aboutsummaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorGreg Lewis <glewis@FreeBSD.org>2015-03-15 21:30:04 +0000
committerGreg Lewis <glewis@FreeBSD.org>2015-03-15 21:30:04 +0000
commit72d2e02134e1c214eb3b66ea6b891ee012ec626c (patch)
tree892453da1e2aaa5ff688fceae18c6640e07d2ac3 /java
parentb7346ae0e6adace4c1baf0d03d4a53223dde90b7 (diff)
downloadports-72d2e02134e1c214eb3b66ea6b891ee012ec626c.tar.gz
ports-72d2e02134e1c214eb3b66ea6b891ee012ec626c.zip
Notes
Diffstat (limited to 'java')
-rw-r--r--java/openjdk8/Makefile31
-rw-r--r--java/openjdk8/files/patch-8u40-b25343973
-rw-r--r--java/openjdk8/files/patch-bsd1385
-rw-r--r--java/openjdk8/files/patch-bsd-test468
-rw-r--r--java/openjdk8/files/patch-jdk-src-solaris-native-java-net-bsd_close.c16
5 files changed, 344804 insertions, 1069 deletions
diff --git a/java/openjdk8/Makefile b/java/openjdk8/Makefile
index bf26d17fa68e..1bce99b6b560 100644
--- a/java/openjdk8/Makefile
+++ b/java/openjdk8/Makefile
@@ -2,7 +2,6 @@
PORTNAME= openjdk
PORTVERSION= ${JDK_MAJOR_VERSION}.${JDK_UPDATE_VERSION}.${JDK_BUILD_NUMBER:S/^0//}
-PORTREVISION= 2
CATEGORIES= java devel
MASTER_SITES= http://download.java.net/openjdk/jdk${JDK_MAJOR_VERSION}/promoted/b${DIST_BUILD_NUMBER}/:jdk \
https://adopt-openjdk.ci.cloudbees.com/job/jtreg/${JTREG_JENKINS_BUILD}/artifact/:jtreg \
@@ -37,17 +36,37 @@ BUILD_DEPENDS+= ${UNZIP_CMD}:${PORTSDIR}/archivers/unzip
ONLY_FOR_ARCHS= i386 amd64
WRKSRC= ${WRKDIR}/${PORTNAME}
-DOS2UNIX_FILES= jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties \
- jdk/src/bsd/doc/man/java.1 \
+DOS2UNIX_FILES= jdk/src/bsd/doc/man/java.1 \
jdk/src/bsd/doc/man/javac.1 \
+ jdk/src/bsd/doc/man/javadoc.1 \
jdk/src/bsd/doc/man/javap.1 \
+ jdk/src/bsd/doc/man/jcmd.1 \
+ jdk/src/bsd/doc/man/jjs.1 \
+ jdk/src/bsd/doc/man/jstat.1 \
+ jdk/src/bsd/doc/man/keytool.1 \
+ jdk/src/bsd/doc/man/policytool.1 \
jdk/src/linux/doc/man/java.1 \
jdk/src/linux/doc/man/javac.1 \
+ jdk/src/linux/doc/man/javadoc.1 \
jdk/src/linux/doc/man/javap.1 \
+ jdk/src/linux/doc/man/jcmd.1 \
+ jdk/src/linux/doc/man/jjs.1 \
+ jdk/src/linux/doc/man/jstat.1 \
+ jdk/src/linux/doc/man/keytool.1 \
+ jdk/src/linux/doc/man/policytool.1 \
+ jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties \
jdk/src/solaris/doc/sun/man/man1/java.1 \
jdk/src/solaris/doc/sun/man/man1/javac.1 \
+ jdk/src/solaris/doc/sun/man/man1/javadoc.1 \
jdk/src/solaris/doc/sun/man/man1/javap.1 \
- nashorn/test/script/jfx.js
+ jdk/src/solaris/doc/sun/man/man1/jcmd.1 \
+ jdk/src/solaris/doc/sun/man/man1/jjs.1 \
+ jdk/src/solaris/doc/sun/man/man1/jstat.1 \
+ jdk/src/solaris/doc/sun/man/man1/keytool.1 \
+ jdk/src/solaris/doc/sun/man/man1/policytool.1 \
+ nashorn/test/script/jfx.js \
+ nashorn/test/script/jfx/kaleidoscope.js \
+ nashorn/test/script/jfx/spread.js
SHEBANG_FILES= configure
_MAKE_JOBS= #
@@ -72,8 +91,8 @@ NO_CCACHE= yes
NOPRECIOUSMAKEVARS= yes
JDK_MAJOR_VERSION= 8
-JDK_UPDATE_VERSION= 31
-JDK_BUILD_NUMBER= 13
+JDK_UPDATE_VERSION= 40
+JDK_BUILD_NUMBER= 25
DIST_BUILD_NUMBER= 132
JTREG_VERSION= 4.1
JTREG_BUILD_NUMBER= b08
diff --git a/java/openjdk8/files/patch-8u40-b25 b/java/openjdk8/files/patch-8u40-b25
new file mode 100644
index 000000000000..fbed54b5cf25
--- /dev/null
+++ b/java/openjdk8/files/patch-8u40-b25
@@ -0,0 +1,343973 @@
+--- ./.hgtags Mon Dec 08 12:28:03 2014 -0800
++++ ./.hgtags Wed Feb 04 12:14:35 2015 -0800
+@@ -349,3 +349,29 @@
+ 01a98532348477a84b6e3c322fdd12dfed28d96d jdk8u31-b10
+ ec85d5d0e3c05b0b6d61f4fc3f41313448ed9b05 jdk8u31-b11
+ ca98e3e9727ffdcde2c9980668d0c7f344261938 jdk8u31-b12
++fde671d8b2537b6be61f67e583164b5b8b33ac5b jdk8u31-b13
++0dccc4aca1859b1ff7dca9db214f7f38c4ddbbce jdk8u40-b00
++f8736a40a35df0c8055c8a94b96e5381b381ad33 jdk8u40-b01
++b6a148730f2b14193c308bc9c866c36ee6c08ed3 jdk8u40-b02
++a0224ac4135108efdbcf316c7c4b02f8a93c35fe jdk8u40-b03
++e9473185d77a9278e47fc916a255c4905aa74d98 jdk8u40-b04
++7e286a0c90fb26766b91e3a19467848f39d1f973 jdk8u40-b05
++8881a63f7f00a4a5611800db7715aecc8f6b3601 jdk8u40-b06
++cf9afcfcb7a41b892fc896c1dbf245d5dcc42395 jdk8u40-b07
++515a912fb5a9a61774fa2afa10f4472589be5602 jdk8u40-b08
++0958d0a9f44efcebe30b17b07240abaa42a2112b jdk8u40-b09
++1053aeab6b12d5cd4e063bf9ee37f20811450084 jdk8u40-b10
++2ffefbac794be27e0c60d7e5f2cb598f04ec2411 jdk8u40-b11
++3e6d3c8810ee495ba599443e29b0dc72c0dd53fd jdk8u40-b12
++43ccc2b9d5b7c06baca33162c6aff8900fa76b65 jdk8u40-b13
++df659b8b0bc82214358e2f0ef340612011d5ed3b jdk8u40-b14
++60d2bf063f7d8baa4e0954b6400aa6d30f9064f9 jdk8u40-b15
++64790e9792f88fadd9d25eaf4dcba7e6e96664de jdk8u40-b16
++e1c506c8e1db7356d120dd7d22b2c50276b6bcee jdk8u40-b17
++83d1d42c3df409c87ef7cb0126343a009857ca71 jdk8u40-b18
++ae4980d195b64eec58884b233d7efd312205bac8 jdk8u40-b19
++b31a07adaef50dacba20e376cff6f1096e745092 jdk8u40-b20
++765a17e75fd622f7b892381e23c9b2c531d416f0 jdk8u40-b21
++b6d03a810a61116268fea08517a9632bd66a7363 jdk8u40-b22
++5dd2ad6c7911a1e21f15a28f13ffad662378a3be jdk8u40-b23
++5b37e6757d7c95c9c58b07fb3c9eba234567385a jdk8u40-b24
+--- ./Makefile Mon Dec 08 12:28:03 2014 -0800
++++ ./Makefile Wed Feb 04 12:14:35 2015 -0800
+@@ -66,7 +66,7 @@
+ # First, find out the valid targets
+ # Run the makefile with an arbitrary SPEC using -p -q (quiet dry-run and dump rules) to find
+ # available PHONY targets. Use this list as valid targets to pass on to the repeated calls.
+- all_phony_targets=$(filter-out $(global_targets) bundles bundles-only final-images-only, $(strip $(shell \
++ all_phony_targets=$(filter-out $(global_targets), $(strip $(shell \
+ cd $(root_dir) && $(MAKE) -p -q FRC SPEC=$(firstword $(SPEC)) | \
+ grep ^.PHONY: | head -n 1 | cut -d " " -f 2-)))
+
+@@ -79,10 +79,6 @@
+ endif
+ endif
+
+-# Include this after a potential spec file has been included so that the bundles target
+-# has access to the spec variables.
+-include $(root_dir)/make/Jprt.gmk
+-
+ # Here are "global" targets, i.e. targets that can be executed without specifying a single configuration.
+ # If you addd more global targets, please update the variable global_targets in MakeHelpers.
+
+--- ./THIRD_PARTY_README Mon Dec 08 12:28:03 2014 -0800
++++ ./THIRD_PARTY_README Wed Feb 04 12:14:35 2015 -0800
+@@ -3385,7 +3385,7 @@
+ included with JRE 8, JDK 8, and OpenJDK 8.
+
+ Apache Commons Math 3.2
+- Apache Derby 10.10.1.3
++ Apache Derby 10.11.1.2
+ Apache Jakarta BCEL 5.1
+ Apache Jakarta Regexp 1.4
+ Apache Santuario XML Security for Java 1.5.4
+--- ./common/autoconf/boot-jdk.m4 Mon Dec 08 12:28:03 2014 -0800
++++ ./common/autoconf/boot-jdk.m4 Wed Feb 04 12:14:35 2015 -0800
+@@ -301,35 +301,59 @@
+ [specify JVM arguments to be passed to all invocations of the Boot JDK, overriding the default values,
+ e.g --with-boot-jdk-jvmargs="-Xmx8G -enableassertions"])])
+
+- if test "x$with_boot_jdk_jvmargs" = x; then
+- # Not all JVM:s accept the same arguments on the command line.
+- # OpenJDK specific increase in thread stack for JDK build,
+- # well more specifically, when running javac.
+- if test "x$BUILD_NUM_BITS" = x32; then
+- STACK_SIZE=768
+- else
+- # Running Javac on a JVM on a 64-bit machine, the stack takes more space
+- # since 64-bit pointers are pushed on the stach. Apparently, we need
+- # to increase the stack space when javacing the JDK....
+- STACK_SIZE=1536
+- fi
++ AC_MSG_CHECKING([flags for boot jdk java command] )
+
+- # Minimum amount of heap memory.
+- ADD_JVM_ARG_IF_OK([-Xms64M],boot_jdk_jvmargs,[$JAVA])
+- if test "x$OPENJDK_TARGET_OS" = "xmacosx" || test "x$OPENJDK_TARGET_CPU" = "xppc64" ; then
+- # Why does macosx need more heap? Its the huge JDK batch.
+- ADD_JVM_ARG_IF_OK([-Xmx1600M],boot_jdk_jvmargs,[$JAVA])
+- else
+- ADD_JVM_ARG_IF_OK([-Xmx1100M],boot_jdk_jvmargs,[$JAVA])
+- fi
+- # When is adding -client something that speeds up the JVM?
+- # ADD_JVM_ARG_IF_OK([-client],boot_jdk_jvmargs,[$JAVA])
+- ADD_JVM_ARG_IF_OK([-XX:PermSize=32m],boot_jdk_jvmargs,[$JAVA])
+- ADD_JVM_ARG_IF_OK([-XX:MaxPermSize=160m],boot_jdk_jvmargs,[$JAVA])
+- ADD_JVM_ARG_IF_OK([-XX:ThreadStackSize=$STACK_SIZE],boot_jdk_jvmargs,[$JAVA])
+- # Disable special log output when a debug build is used as Boot JDK...
+- ADD_JVM_ARG_IF_OK([-XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput],boot_jdk_jvmargs,[$JAVA])
++ # Disable special log output when a debug build is used as Boot JDK...
++ ADD_JVM_ARG_IF_OK([-XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput],boot_jdk_jvmargs,[$JAVA])
++
++ # Apply user provided options.
++ ADD_JVM_ARG_IF_OK([$with_boot_jdk_jvmargs],boot_jdk_jvmargs,[$JAVA])
++
++ AC_MSG_RESULT([$boot_jdk_jvmargs])
++
++ # For now, general JAVA_FLAGS are the same as the boot jdk jvmargs
++ JAVA_FLAGS=$boot_jdk_jvmargs
++ AC_SUBST(JAVA_FLAGS)
++
++
++ AC_MSG_CHECKING([flags for boot jdk java command for big workloads])
++
++ # Starting amount of heap memory.
++ ADD_JVM_ARG_IF_OK([-Xms64M],boot_jdk_jvmargs_big,[$JAVA])
++
++ # Maximum amount of heap memory.
++ # Maximum stack size.
++ if test "x$BUILD_NUM_BITS" = x32; then
++ JVM_MAX_HEAP=1100M
++ STACK_SIZE=768
++ else
++ # Running Javac on a JVM on a 64-bit machine, takes more space since 64-bit
++ # pointers are used. Apparently, we need to increase the heap and stack
++ # space for the jvm. More specifically, when running javac to build huge
++ # jdk batch
++ JVM_MAX_HEAP=1600M
++ STACK_SIZE=1536
+ fi
++ ADD_JVM_ARG_IF_OK([-Xmx$JVM_MAX_HEAP],boot_jdk_jvmargs_big,[$JAVA])
++ ADD_JVM_ARG_IF_OK([-XX:ThreadStackSize=$STACK_SIZE],boot_jdk_jvmargs_big,[$JAVA])
++ ADD_JVM_ARG_IF_OK([-XX:PermSize=32m],boot_jdk_jvmargs_big,[$JAVA])
++ ADD_JVM_ARG_IF_OK([-XX:MaxPermSize=160m],boot_jdk_jvmargs_big,[$JAVA])
+
+- AC_SUBST(BOOT_JDK_JVMARGS, $boot_jdk_jvmargs)
++ AC_MSG_RESULT([$boot_jdk_jvmargs_big])
++
++ JAVA_FLAGS_BIG=$boot_jdk_jvmargs_big
++ AC_SUBST(JAVA_FLAGS_BIG)
++
++
++ AC_MSG_CHECKING([flags for boot jdk java command for small workloads])
++
++ # Use serial gc for small short lived tools if possible
++ ADD_JVM_ARG_IF_OK([-XX:+UseSerialGC],boot_jdk_jvmargs_small,[$JAVA])
++ ADD_JVM_ARG_IF_OK([-Xms32M],boot_jdk_jvmargs_small,[$JAVA])
++ ADD_JVM_ARG_IF_OK([-Xmx512M],boot_jdk_jvmargs_small,[$JAVA])
++
++ AC_MSG_RESULT([$boot_jdk_jvmargs_small])
++
++ JAVA_FLAGS_SMALL=$boot_jdk_jvmargs_small
++ AC_SUBST(JAVA_FLAGS_SMALL)
+ ])
+--- ./common/autoconf/generated-configure.sh Mon Dec 08 12:28:03 2014 -0800
++++ ./common/autoconf/generated-configure.sh Wed Feb 04 12:14:35 2015 -0800
+@@ -786,7 +786,9 @@
+ JAXP_TOPDIR
+ CORBA_TOPDIR
+ LANGTOOLS_TOPDIR
+-BOOT_JDK_JVMARGS
++JAVA_FLAGS_SMALL
++JAVA_FLAGS_BIG
++JAVA_FLAGS
+ JAVAC_FLAGS
+ BOOT_JDK_SOURCETARGET
+ BOOT_JDK
+@@ -7928,7 +7930,7 @@
+ fi
+
+ # Replace the commas with AND for use in the build directory name.
+- ANDED_JVM_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/^,//' -e 's/,$//' -e 's/,/AND/'`
++ ANDED_JVM_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/^,//' -e 's/,$//' -e 's/,/AND/g'`
+ COUNT_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/server,/1/' -e 's/client,/1/' -e 's/minimal1,/1/' -e 's/kernel,/1/' -e 's/zero,/1/' -e 's/zeroshark,/1/' -e 's/core,/1/'`
+ if test "x$COUNT_VARIANTS" != "x,1"; then
+ BUILDING_MULTIPLE_JVM_VARIANTS=yes
+@@ -16086,117 +16088,10 @@
+ fi
+
+
+- if test "x$with_boot_jdk_jvmargs" = x; then
+- # Not all JVM:s accept the same arguments on the command line.
+- # OpenJDK specific increase in thread stack for JDK build,
+- # well more specifically, when running javac.
+- if test "x$BUILD_NUM_BITS" = x32; then
+- STACK_SIZE=768
+- else
+- # Running Javac on a JVM on a 64-bit machine, the stack takes more space
+- # since 64-bit pointers are pushed on the stach. Apparently, we need
+- # to increase the stack space when javacing the JDK....
+- STACK_SIZE=1536
+- fi
+-
+- # Minimum amount of heap memory.
+-
+- $ECHO "Check if jvm arg is ok: -Xms64M" >&5
+- $ECHO "Command: $JAVA -Xms64M -version" >&5
+- OUTPUT=`$JAVA -Xms64M -version 2>&1`
+- FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+- FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+- if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+- boot_jdk_jvmargs="$boot_jdk_jvmargs -Xms64M"
+- JVM_ARG_OK=true
+- else
+- $ECHO "Arg failed:" >&5
+- $ECHO "$OUTPUT" >&5
+- JVM_ARG_OK=false
+- fi
+-
+- if test "x$OPENJDK_TARGET_OS" = "xmacosx" || test "x$OPENJDK_TARGET_CPU" = "xppc64" ; then
+- # Why does macosx need more heap? Its the huge JDK batch.
+-
+- $ECHO "Check if jvm arg is ok: -Xmx1600M" >&5
+- $ECHO "Command: $JAVA -Xmx1600M -version" >&5
+- OUTPUT=`$JAVA -Xmx1600M -version 2>&1`
+- FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+- FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+- if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+- boot_jdk_jvmargs="$boot_jdk_jvmargs -Xmx1600M"
+- JVM_ARG_OK=true
+- else
+- $ECHO "Arg failed:" >&5
+- $ECHO "$OUTPUT" >&5
+- JVM_ARG_OK=false
+- fi
+-
+- else
+-
+- $ECHO "Check if jvm arg is ok: -Xmx1100M" >&5
+- $ECHO "Command: $JAVA -Xmx1100M -version" >&5
+- OUTPUT=`$JAVA -Xmx1100M -version 2>&1`
+- FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+- FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+- if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+- boot_jdk_jvmargs="$boot_jdk_jvmargs -Xmx1100M"
+- JVM_ARG_OK=true
+- else
+- $ECHO "Arg failed:" >&5
+- $ECHO "$OUTPUT" >&5
+- JVM_ARG_OK=false
+- fi
+-
+- fi
+- # When is adding -client something that speeds up the JVM?
+- # ADD_JVM_ARG_IF_OK([-client],boot_jdk_jvmargs,[$JAVA])
+-
+- $ECHO "Check if jvm arg is ok: -XX:PermSize=32m" >&5
+- $ECHO "Command: $JAVA -XX:PermSize=32m -version" >&5
+- OUTPUT=`$JAVA -XX:PermSize=32m -version 2>&1`
+- FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+- FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+- if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+- boot_jdk_jvmargs="$boot_jdk_jvmargs -XX:PermSize=32m"
+- JVM_ARG_OK=true
+- else
+- $ECHO "Arg failed:" >&5
+- $ECHO "$OUTPUT" >&5
+- JVM_ARG_OK=false
+- fi
+-
+-
+- $ECHO "Check if jvm arg is ok: -XX:MaxPermSize=160m" >&5
+- $ECHO "Command: $JAVA -XX:MaxPermSize=160m -version" >&5
+- OUTPUT=`$JAVA -XX:MaxPermSize=160m -version 2>&1`
+- FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+- FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+- if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+- boot_jdk_jvmargs="$boot_jdk_jvmargs -XX:MaxPermSize=160m"
+- JVM_ARG_OK=true
+- else
+- $ECHO "Arg failed:" >&5
+- $ECHO "$OUTPUT" >&5
+- JVM_ARG_OK=false
+- fi
+-
+-
+- $ECHO "Check if jvm arg is ok: -XX:ThreadStackSize=$STACK_SIZE" >&5
+- $ECHO "Command: $JAVA -XX:ThreadStackSize=$STACK_SIZE -version" >&5
+- OUTPUT=`$JAVA -XX:ThreadStackSize=$STACK_SIZE -version 2>&1`
+- FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+- FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+- if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+- boot_jdk_jvmargs="$boot_jdk_jvmargs -XX:ThreadStackSize=$STACK_SIZE"
+- JVM_ARG_OK=true
+- else
+- $ECHO "Arg failed:" >&5
+- $ECHO "$OUTPUT" >&5
+- JVM_ARG_OK=false
+- fi
+-
+- # Disable special log output when a debug build is used as Boot JDK...
++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking flags for boot jdk java command " >&5
++$as_echo_n "checking flags for boot jdk java command ... " >&6; }
++
++ # Disable special log output when a debug build is used as Boot JDK...
+
+ $ECHO "Check if jvm arg is ok: -XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput" >&5
+ $ECHO "Command: $JAVA -XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput -version" >&5
+@@ -16212,9 +16107,187 @@
+ JVM_ARG_OK=false
+ fi
+
+- fi
+-
+- BOOT_JDK_JVMARGS=$boot_jdk_jvmargs
++
++ # Apply user provided options.
++
++ $ECHO "Check if jvm arg is ok: $with_boot_jdk_jvmargs" >&5
++ $ECHO "Command: $JAVA $with_boot_jdk_jvmargs -version" >&5
++ OUTPUT=`$JAVA $with_boot_jdk_jvmargs -version 2>&1`
++ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
++ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
++ if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
++ boot_jdk_jvmargs="$boot_jdk_jvmargs $with_boot_jdk_jvmargs"
++ JVM_ARG_OK=true
++ else
++ $ECHO "Arg failed:" >&5
++ $ECHO "$OUTPUT" >&5
++ JVM_ARG_OK=false
++ fi
++
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $boot_jdk_jvmargs" >&5
++$as_echo "$boot_jdk_jvmargs" >&6; }
++
++ # For now, general JAVA_FLAGS are the same as the boot jdk jvmargs
++ JAVA_FLAGS=$boot_jdk_jvmargs
++
++
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking flags for boot jdk java command for big workloads" >&5
++$as_echo_n "checking flags for boot jdk java command for big workloads... " >&6; }
++
++ # Starting amount of heap memory.
++
++ $ECHO "Check if jvm arg is ok: -Xms64M" >&5
++ $ECHO "Command: $JAVA -Xms64M -version" >&5
++ OUTPUT=`$JAVA -Xms64M -version 2>&1`
++ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
++ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
++ if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
++ boot_jdk_jvmargs_big="$boot_jdk_jvmargs_big -Xms64M"
++ JVM_ARG_OK=true
++ else
++ $ECHO "Arg failed:" >&5
++ $ECHO "$OUTPUT" >&5
++ JVM_ARG_OK=false
++ fi
++
++
++ # Maximum amount of heap memory.
++ # Maximum stack size.
++ if test "x$BUILD_NUM_BITS" = x32; then
++ JVM_MAX_HEAP=1100M
++ STACK_SIZE=768
++ else
++ # Running Javac on a JVM on a 64-bit machine, takes more space since 64-bit
++ # pointers are used. Apparently, we need to increase the heap and stack
++ # space for the jvm. More specifically, when running javac to build huge
++ # jdk batch
++ JVM_MAX_HEAP=1600M
++ STACK_SIZE=1536
++ fi
++
++ $ECHO "Check if jvm arg is ok: -Xmx$JVM_MAX_HEAP" >&5
++ $ECHO "Command: $JAVA -Xmx$JVM_MAX_HEAP -version" >&5
++ OUTPUT=`$JAVA -Xmx$JVM_MAX_HEAP -version 2>&1`
++ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
++ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
++ if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
++ boot_jdk_jvmargs_big="$boot_jdk_jvmargs_big -Xmx$JVM_MAX_HEAP"
++ JVM_ARG_OK=true
++ else
++ $ECHO "Arg failed:" >&5
++ $ECHO "$OUTPUT" >&5
++ JVM_ARG_OK=false
++ fi
++
++
++ $ECHO "Check if jvm arg is ok: -XX:ThreadStackSize=$STACK_SIZE" >&5
++ $ECHO "Command: $JAVA -XX:ThreadStackSize=$STACK_SIZE -version" >&5
++ OUTPUT=`$JAVA -XX:ThreadStackSize=$STACK_SIZE -version 2>&1`
++ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
++ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
++ if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
++ boot_jdk_jvmargs_big="$boot_jdk_jvmargs_big -XX:ThreadStackSize=$STACK_SIZE"
++ JVM_ARG_OK=true
++ else
++ $ECHO "Arg failed:" >&5
++ $ECHO "$OUTPUT" >&5
++ JVM_ARG_OK=false
++ fi
++
++
++ $ECHO "Check if jvm arg is ok: -XX:PermSize=32m" >&5
++ $ECHO "Command: $JAVA -XX:PermSize=32m -version" >&5
++ OUTPUT=`$JAVA -XX:PermSize=32m -version 2>&1`
++ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
++ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
++ if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
++ boot_jdk_jvmargs_big="$boot_jdk_jvmargs_big -XX:PermSize=32m"
++ JVM_ARG_OK=true
++ else
++ $ECHO "Arg failed:" >&5
++ $ECHO "$OUTPUT" >&5
++ JVM_ARG_OK=false
++ fi
++
++
++ $ECHO "Check if jvm arg is ok: -XX:MaxPermSize=160m" >&5
++ $ECHO "Command: $JAVA -XX:MaxPermSize=160m -version" >&5
++ OUTPUT=`$JAVA -XX:MaxPermSize=160m -version 2>&1`
++ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
++ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
++ if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
++ boot_jdk_jvmargs_big="$boot_jdk_jvmargs_big -XX:MaxPermSize=160m"
++ JVM_ARG_OK=true
++ else
++ $ECHO "Arg failed:" >&5
++ $ECHO "$OUTPUT" >&5
++ JVM_ARG_OK=false
++ fi
++
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $boot_jdk_jvmargs_big" >&5
++$as_echo "$boot_jdk_jvmargs_big" >&6; }
++
++ JAVA_FLAGS_BIG=$boot_jdk_jvmargs_big
++
++
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking flags for boot jdk java command for small workloads" >&5
++$as_echo_n "checking flags for boot jdk java command for small workloads... " >&6; }
++
++ # Use serial gc for small short lived tools if possible
++
++ $ECHO "Check if jvm arg is ok: -XX:+UseSerialGC" >&5
++ $ECHO "Command: $JAVA -XX:+UseSerialGC -version" >&5
++ OUTPUT=`$JAVA -XX:+UseSerialGC -version 2>&1`
++ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
++ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
++ if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
++ boot_jdk_jvmargs_small="$boot_jdk_jvmargs_small -XX:+UseSerialGC"
++ JVM_ARG_OK=true
++ else
++ $ECHO "Arg failed:" >&5
++ $ECHO "$OUTPUT" >&5
++ JVM_ARG_OK=false
++ fi
++
++
++ $ECHO "Check if jvm arg is ok: -Xms32M" >&5
++ $ECHO "Command: $JAVA -Xms32M -version" >&5
++ OUTPUT=`$JAVA -Xms32M -version 2>&1`
++ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
++ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
++ if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
++ boot_jdk_jvmargs_small="$boot_jdk_jvmargs_small -Xms32M"
++ JVM_ARG_OK=true
++ else
++ $ECHO "Arg failed:" >&5
++ $ECHO "$OUTPUT" >&5
++ JVM_ARG_OK=false
++ fi
++
++
++ $ECHO "Check if jvm arg is ok: -Xmx512M" >&5
++ $ECHO "Command: $JAVA -Xmx512M -version" >&5
++ OUTPUT=`$JAVA -Xmx512M -version 2>&1`
++ FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
++ FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
++ if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
++ boot_jdk_jvmargs_small="$boot_jdk_jvmargs_small -Xmx512M"
++ JVM_ARG_OK=true
++ else
++ $ECHO "Arg failed:" >&5
++ $ECHO "$OUTPUT" >&5
++ JVM_ARG_OK=false
++ fi
++
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $boot_jdk_jvmargs_small" >&5
++$as_echo "$boot_jdk_jvmargs_small" >&6; }
++
++ JAVA_FLAGS_SMALL=$boot_jdk_jvmargs_small
+
+
+
+--- ./common/autoconf/jdk-options.m4 Mon Dec 08 12:28:03 2014 -0800
++++ ./common/autoconf/jdk-options.m4 Wed Feb 04 12:14:35 2015 -0800
+@@ -134,7 +134,7 @@
+ fi
+
+ # Replace the commas with AND for use in the build directory name.
+- ANDED_JVM_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/^,//' -e 's/,$//' -e 's/,/AND/'`
++ ANDED_JVM_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/^,//' -e 's/,$//' -e 's/,/AND/g'`
+ COUNT_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/server,/1/' -e 's/client,/1/' -e 's/minimal1,/1/' -e 's/kernel,/1/' -e 's/zero,/1/' -e 's/zeroshark,/1/' -e 's/core,/1/'`
+ if test "x$COUNT_VARIANTS" != "x,1"; then
+ BUILDING_MULTIPLE_JVM_VARIANTS=yes
+--- ./common/autoconf/spec.gmk.in Mon Dec 08 12:28:03 2014 -0800
++++ ./common/autoconf/spec.gmk.in Wed Feb 04 12:14:35 2015 -0800
+@@ -249,7 +249,6 @@
+
+ # The boot jdk to use
+ BOOT_JDK:=@BOOT_JDK@
+-BOOT_JDK_JVMARGS:=@BOOT_JDK_JVMARGS@
+ BOOT_RTJAR:=@BOOT_RTJAR@
+ BOOT_TOOLSJAR=$(BOOT_JDK)/lib/tools.jar
+
+@@ -436,9 +435,12 @@
+ POST_STRIP_CMD:=@POST_STRIP_CMD@
+ POST_MCS_CMD:=@POST_MCS_CMD@
+
+-JAVA_FLAGS:=@BOOT_JDK_JVMARGS@
++JAVA_FLAGS:=@JAVA_FLAGS@
++JAVA_FLAGS_BIG:=@JAVA_FLAGS_BIG@
++JAVA_FLAGS_SMALL:=@JAVA_FLAGS_SMALL@
+
+-JAVA=@FIXPATH@ $(BOOT_JDK)/bin/java $(JAVA_FLAGS)
++JAVA=@FIXPATH@ $(BOOT_JDK)/bin/java $(JAVA_FLAGS_BIG) $(JAVA_FLAGS)
++JAVA_SMALL=@FIXPATH@ $(BOOT_JDK)/bin/java $(JAVA_FLAGS_SMALL) $(JAVA_FLAGS)
+
+ JAVAC=@FIXPATH@ $(BOOT_JDK)/bin/javac
+ # Hotspot sets this variable before reading the SPEC when compiling sa-jdi.jar. Avoid
+@@ -451,7 +453,7 @@
+
+ RMIC=@FIXPATH@ $(BOOT_JDK)/bin/rmic
+
+-NATIVE2ASCII=@FIXPATH@ $(BOOT_JDK)/bin/native2ascii
++NATIVE2ASCII=@FIXPATH@ $(BOOT_JDK)/bin/native2ascii $(addprefix -J, $(JAVA_FLAGS_SMALL))
+
+ JARSIGNER=@FIXPATH@ $(BOOT_JDK)/bin/jarsigner
+
+--- ./common/bin/hgforest.sh Mon Dec 08 12:28:03 2014 -0800
++++ ./common/bin/hgforest.sh Wed Feb 04 12:14:35 2015 -0800
+@@ -1,7 +1,6 @@
+ #!/bin/sh
+-
+ #
+-# Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -23,165 +22,375 @@
+ # questions.
+ #
+
+-# Shell script for a fast parallel forest command
+-command="$1"
+-pull_extra_base="$2"
++# Shell script for a fast parallel forest/trees command
+
+-if [ "" = "$command" ] ; then
+- echo No command to hg supplied!
+- exit 1
++usage() {
++ echo "usage: $0 [-h|--help] [-q|--quiet] [-v|--verbose] [-s|--sequential] [--] <command> [commands...]" > ${status_output}
++ echo "Environment variables which modify behaviour:"
++ echo " HGFOREST_QUIET : (boolean) If 'true' then standard output is redirected to /dev/null"
++ echo " HGFOREST_VERBOSE : (boolean) If 'true' then Mercurial asked to produce verbose output"
++ echo " HGFOREST_SEQUENTIAL : (boolean) If 'true' then repos are processed sequentially. Disables concurrency"
++ echo " HGFOREST_GLOBALOPTS : (string, must begin with space) Additional Mercurial global options"
++ echo " HGFOREST_REDIRECT : (file path) Redirect standard output to specified file"
++ echo " HGFOREST_FIFOS : (boolean) Default behaviour for FIFO detection. Does not override FIFOs disabled"
++ echo " HGFOREST_CONCURRENCY: (positive integer) Number of repos to process concurrently"
++ echo " HGFOREST_DEBUG : (boolean) If 'true' then temp files are retained"
++ exit 1
++}
++
++global_opts="${HGFOREST_GLOBALOPTS:-}"
++status_output="${HGFOREST_REDIRECT:-/dev/stdout}"
++qflag="${HGFOREST_QUIET:-false}"
++vflag="${HGFOREST_VERBOSE:-false}"
++sflag="${HGFOREST_SEQUENTIAL:-false}"
++while [ $# -gt 0 ]
++do
++ case $1 in
++ -h | --help )
++ usage
++ ;;
++
++ -q | --quiet )
++ qflag="true"
++ ;;
++
++ -v | --verbose )
++ vflag="true"
++ ;;
++
++ -s | --sequential )
++ sflag="true"
++ ;;
++
++ '--' ) # no more options
++ shift; break
++ ;;
++
++ -*) # bad option
++ usage
++ ;;
++
++ * ) # non option
++ break
++ ;;
++ esac
++ shift
++done
++
++# silence standard output?
++if [ ${qflag} = "true" ] ; then
++ global_opts="${global_opts} -q"
++ status_output="/dev/null"
+ fi
+
++# verbose output?
++if [ ${vflag} = "true" ] ; then
++ global_opts="${global_opts} -v"
++fi
++
++# Make sure we have a command.
++if [ $# -lt 1 -o -z "${1:-}" ] ; then
++ echo "ERROR: No command to hg supplied!"
++ usage
++fi
++
++command="$1"; shift
++command_args="${@:-}"
++
+ # Clean out the temporary directory that stores the pid files.
+ tmp=/tmp/forest.$$
+ rm -f -r ${tmp}
+ mkdir -p ${tmp}
+
++
++if [ "${HGFOREST_DEBUG:-false}" = "true" ] ; then
++ echo "DEBUG: temp files are in: ${tmp}"
++fi
++
++# Check if we can use fifos for monitoring sub-process completion.
++echo "1" > ${tmp}/read
++while_subshell=1
++while read line; do
++ while_subshell=0
++ break;
++done < ${tmp}/read
++rm ${tmp}/read
++
++on_windows=`uname -s | egrep -ic -e 'cygwin|msys'`
++
++if [ ${while_subshell} = "1" -o ${on_windows} = "1" ]; then
++ # cygwin has (2014-04-18) broken (single writer only) FIFOs
++ # msys has (2014-04-18) no FIFOs.
++ # older shells create a sub-shell for redirect to while
++ have_fifos="false"
++else
++ have_fifos="${HGFOREST_FIFOS:-true}"
++fi
++
+ safe_interrupt () {
+ if [ -d ${tmp} ]; then
+ if [ "`ls ${tmp}/*.pid`" != "" ]; then
+- echo "Waiting for processes ( `cat ${tmp}/*.pid | tr '\n' ' '`) to terminate nicely!"
++ echo "Waiting for processes ( `cat ${tmp}/.*.pid ${tmp}/*.pid 2> /dev/null | tr '\n' ' '`) to terminate nicely!" > ${status_output}
+ sleep 1
+ # Pipe stderr to dev/null to silence kill, that complains when trying to kill
+ # a subprocess that has already exited.
+ kill -TERM `cat ${tmp}/*.pid | tr '\n' ' '` 2> /dev/null
+ wait
+- echo Interrupt complete!
++ echo "Interrupt complete!" > ${status_output}
+ fi
++ rm -f -r ${tmp}
+ fi
+- rm -f -r ${tmp}
+- exit 1
++ exit 130
+ }
+
+ nice_exit () {
+ if [ -d ${tmp} ]; then
+- if [ "`ls ${tmp}`" != "" ]; then
++ if [ "`ls -A ${tmp} 2> /dev/null`" != "" ]; then
+ wait
+ fi
++ if [ "${HGFOREST_DEBUG:-false}" != "true" ] ; then
++ rm -f -r ${tmp}
++ fi
+ fi
+- rm -f -r ${tmp}
+ }
+
+ trap 'safe_interrupt' INT QUIT
+ trap 'nice_exit' EXIT
+
++subrepos="corba jaxp jaxws langtools jdk hotspot nashorn"
++subrepos_extra="jdk/src/closed jdk/make/closed jdk/test/closed hotspot/make/closed hotspot/src/closed hotspot/test/closed deploy install sponsors pubs"
++
+ # Only look in specific locations for possible forests (avoids long searches)
+ pull_default=""
+ repos=""
+ repos_extra=""
+-if [ "${command}" = "clone" -o "${command}" = "fclone" ] ; then
+- subrepos="corba jaxp jaxws langtools jdk hotspot nashorn"
+- if [ -f .hg/hgrc ] ; then
+- pull_default=`hg paths default`
+- if [ "${pull_default}" = "" ] ; then
+- echo "ERROR: Need initial clone with 'hg paths default' defined"
+- exit 1
+- fi
+- fi
+- if [ "${pull_default}" = "" ] ; then
+- echo "ERROR: Need initial repository to use this script"
++if [ "${command}" = "clone" -o "${command}" = "fclone" -o "${command}" = "tclone" ] ; then
++ # we must be a clone
++ if [ ! -f .hg/hgrc ] ; then
++ echo "ERROR: Need initial repository to use this script" > ${status_output}
+ exit 1
+ fi
++
++ # the clone must know where it came from (have a default pull path).
++ pull_default=`hg paths default`
++ if [ "${pull_default}" = "" ] ; then
++ echo "ERROR: Need initial clone with 'hg paths default' defined" > ${status_output}
++ exit 1
++ fi
++
++ # determine which sub repos need to be cloned.
+ for i in ${subrepos} ; do
+ if [ ! -f ${i}/.hg/hgrc ] ; then
+ repos="${repos} ${i}"
+ fi
+ done
+- if [ "${pull_extra_base}" != "" ] ; then
+- subrepos_extra="jdk/src/closed jdk/make/closed jdk/test/closed hotspot/make/closed hotspot/src/closed hotspot/test/closed deploy install sponsors pubs"
+- pull_default_tail=`echo ${pull_default} | sed -e 's@^.*://[^/]*/\(.*\)@\1@'`
+- pull_extra="${pull_extra_base}/${pull_default_tail}"
++
++ pull_default_tail=`echo ${pull_default} | sed -e 's@^.*://[^/]*/\(.*\)@\1@'`
++
++ if [ -n "${command_args}" ] ; then
++ # if there is an "extra sources" path then reparent "extra" repos to that path
++ if [ "x${pull_default}" = "x${pull_default_tail}" ] ; then
++ echo "ERROR: Need initial clone from non-local source" > ${status_output}
++ exit 1
++ fi
++ pull_extra="${command_args}/${pull_default_tail}"
++
++ # determine which extra subrepos need to be cloned.
+ for i in ${subrepos_extra} ; do
+ if [ ! -f ${i}/.hg/hgrc ] ; then
+ repos_extra="${repos_extra} ${i}"
+ fi
+ done
++ else
++ if [ "x${pull_default}" = "x${pull_default_tail}" ] ; then
++ # local source repo. Clone the "extra" subrepos that exist there.
++ for i in ${subrepos_extra} ; do
++ if [ -f ${pull_default}/${i}/.hg/hgrc -a ! -f ${i}/.hg/hgrc ] ; then
++ # sub-repo there in source but not here
++ repos_extra="${repos_extra} ${i}"
++ fi
++ done
++ fi
+ fi
+- at_a_time=2
++
+ # Any repos to deal with?
+ if [ "${repos}" = "" -a "${repos_extra}" = "" ] ; then
++ echo "No repositories to process." > ${status_output}
+ exit
+ fi
++
++ # Repos to process concurrently. Clone does better with low concurrency.
++ at_a_time="${HGFOREST_CONCURRENCY:-2}"
+ else
+- hgdirs=`ls -d ./.hg ./*/.hg ./*/*/.hg ./*/*/*/.hg ./*/*/*/*/.hg 2>/dev/null`
+- # Derive repository names from the .hg directory locations
+- for i in ${hgdirs} ; do
+- repos="${repos} `echo ${i} | sed -e 's@/.hg$@@'`"
++ # Process command for all of the present repos
++ for i in . ${subrepos} ${subrepos_extra} ; do
++ if [ -d ${i}/.hg ] ; then
++ repos="${repos} ${i}"
++ fi
+ done
++
++ # Any repos to deal with?
++ if [ "${repos}" = "" ] ; then
++ echo "No repositories to process." > ${status_output}
++ exit
++ fi
++
++ # any of the repos locked?
++ locked=""
+ for i in ${repos} ; do
+ if [ -h ${i}/.hg/store/lock -o -f ${i}/.hg/store/lock ] ; then
+ locked="${i} ${locked}"
+ fi
+ done
+- at_a_time=8
+- # Any repos to deal with?
+- if [ "${repos}" = "" ] ; then
+- echo "No repositories to process."
+- exit
++ if [ "${locked}" != "" ] ; then
++ echo "ERROR: These repositories are locked: ${locked}" > ${status_output}
++ exit 1
+ fi
+- if [ "${locked}" != "" ] ; then
+- echo "These repositories are locked: ${locked}"
+- exit
+- fi
++
++ # Repos to process concurrently.
++ at_a_time="${HGFOREST_CONCURRENCY:-8}"
+ fi
+
+ # Echo out what repositories we do a command on.
+-echo "# Repositories: ${repos} ${repos_extra}"
+-echo
++echo "# Repositories: ${repos} ${repos_extra}" > ${status_output}
+
+-# Run the supplied command on all repos in parallel.
+-n=0
+-for i in ${repos} ${repos_extra} ; do
+- n=`expr ${n} '+' 1`
+- repopidfile=`echo ${i} | sed -e 's@./@@' -e 's@/@_@g'`
+- reponame=`echo ${i} | sed -e :a -e 's/^.\{1,20\}$/ &/;ta'`
+- pull_base="${pull_default}"
+- for j in $repos_extra ; do
+- if [ "$i" = "$j" ] ; then
+- pull_base="${pull_extra}"
+- fi
+- done
++if [ "${command}" = "serve" ] ; then
++ # "serve" is run for all the repos as one command.
+ (
+ (
+- if [ "${command}" = "clone" -o "${command}" = "fclone" ] ; then
+- pull_newrepo="`echo ${pull_base}/${i} | sed -e 's@\([^:]/\)//*@\1@g'`"
+- echo hg clone ${pull_newrepo} ${i}
+- path="`dirname ${i}`"
+- if [ "${path}" != "." ] ; then
+- times=0
+- while [ ! -d "${path}" ] ## nested repo, ensure containing dir exists
+- do
+- times=`expr ${times} '+' 1`
+- if [ `expr ${times} '%' 10` -eq 0 ] ; then
+- echo ${path} still not created, waiting...
++ cwd=`pwd`
++ serving=`basename ${cwd}`
++ (
++ echo "[web]"
++ echo "description = ${serving}"
++ echo "allow_push = *"
++ echo "push_ssl = False"
++
++ echo "[paths]"
++ for i in ${repos} ; do
++ if [ "${i}" != "." ] ; then
++ echo "/${serving}/${i} = ${i}"
++ else
++ echo "/${serving} = ${cwd}"
++ fi
++ done
++ ) > ${tmp}/serve.web-conf
++
++ echo "serving root repo ${serving}" > ${status_output}
++
++ echo "hg${global_opts} serve" > ${status_output}
++ (PYTHONUNBUFFERED=true hg${global_opts} serve -A ${status_output} -E ${status_output} --pid-file ${tmp}/serve.pid --web-conf ${tmp}/serve.web-conf; echo "$?" > ${tmp}/serve.pid.rc ) 2>&1 &
++ ) 2>&1 | sed -e "s@^@serve: @" > ${status_output}
++ ) &
++else
++ # Run the supplied command on all repos in parallel.
++
++ # n is the number of subprocess started or which might still be running.
++ n=0
++ if [ ${have_fifos} = "true" ]; then
++ # if we have fifos use them to detect command completion.
++ mkfifo ${tmp}/fifo
++ exec 3<>${tmp}/fifo
++ fi
++
++ # iterate over all of the subrepos.
++ for i in ${repos} ${repos_extra} ; do
++ n=`expr ${n} '+' 1`
++ repopidfile=`echo ${i} | sed -e 's@./@@' -e 's@/@_@g'`
++ reponame=`echo ${i} | sed -e :a -e 's/^.\{1,20\}$/ &/;ta'`
++ pull_base="${pull_default}"
++
++ # regular repo or "extra" repo?
++ for j in ${repos_extra} ; do
++ if [ "${i}" = "${j}" ] ; then
++ # it's an "extra"
++ pull_base="${pull_extra}"
++ fi
++ done
++
++ # remove trailing slash
++ pull_base="`echo ${pull_base} | sed -e 's@[/]*$@@'`"
++
++ # execute the command on the subrepo
++ (
++ (
++ if [ "${command}" = "clone" -o "${command}" = "fclone" -o "${command}" = "tclone" ] ; then
++ # some form of clone
++ clone_newrepo="${pull_base}/${i}"
++ parent_path="`dirname ${i}`"
++ if [ "${parent_path}" != "." ] ; then
++ times=0
++ while [ ! -d "${parent_path}" ] ; do ## nested repo, ensure containing dir exists
++ if [ "${sflag}" = "true" ] ; then
++ # Missing parent is fatal during sequential operation.
++ echo "ERROR: Missing parent path: ${parent_path}" > ${status_output}
++ exit 1
++ fi
++ times=`expr ${times} '+' 1`
++ if [ `expr ${times} '%' 10` -eq 0 ] ; then
++ echo "${parent_path} still not created, waiting..." > ${status_output}
++ fi
++ sleep 5
++ done
++ fi
++ # run the clone command.
++ echo "hg${global_opts} clone ${clone_newrepo} ${i}" > ${status_output}
++ (PYTHONUNBUFFERED=true hg${global_opts} clone ${clone_newrepo} ${i}; echo "$?" > ${tmp}/${repopidfile}.pid.rc ) 2>&1 &
++ else
++ # run the command.
++ echo "cd ${i} && hg${global_opts} ${command} ${command_args}" > ${status_output}
++ cd ${i} && (PYTHONUNBUFFERED=true hg${global_opts} ${command} ${command_args}; echo "$?" > ${tmp}/${repopidfile}.pid.rc ) 2>&1 &
++ fi
++
++ echo $! > ${tmp}/${repopidfile}.pid
++ ) 2>&1 | sed -e "s@^@${reponame}: @" > ${status_output}
++ # tell the fifo waiter that this subprocess is done.
++ if [ ${have_fifos} = "true" ]; then
++ echo "${i}" >&3
++ fi
++ ) &
++
++ if [ "${sflag}" = "true" ] ; then
++ # complete this task before starting another.
++ wait
++ else
++ if [ "${have_fifos}" = "true" ]; then
++ # check on count of running subprocesses and possibly wait for completion
++ if [ ${n} -ge ${at_a_time} ] ; then
++ # read will block until there are completed subprocesses
++ while read repo_done; do
++ n=`expr ${n} '-' 1`
++ if [ ${n} -lt ${at_a_time} ] ; then
++ # we should start more subprocesses
++ break;
+ fi
+- sleep 5
+- done
++ done <&3
+ fi
+- (PYTHONUNBUFFERED=true hg clone ${pull_newrepo} ${i}; echo "$?" > ${tmp}/${repopidfile}.pid.rc )&
+ else
+- echo "cd ${i} && hg $*"
+- cd ${i} && (PYTHONUNBUFFERED=true hg "$@"; echo "$?" > ${tmp}/${repopidfile}.pid.rc )&
++ # Compare completions to starts
++ completed="`(ls -a1 ${tmp}/*.pid.rc 2> /dev/null | wc -l) || echo 0`"
++ while [ `expr ${n} '-' ${completed}` -ge ${at_a_time} ] ; do
++ # sleep a short time to give time for something to complete
++ sleep 1
++ completed="`(ls -a1 ${tmp}/*.pid.rc 2> /dev/null | wc -l) || echo 0`"
++ done
+ fi
+- echo $! > ${tmp}/${repopidfile}.pid
+- ) 2>&1 | sed -e "s@^@${reponame}: @") &
++ fi
++ done
++fi
+
+- if [ `expr ${n} '%' ${at_a_time}` -eq 0 ] ; then
+- sleep 2
+- echo Waiting 5 secs before spawning next background command.
+- sleep 3
+- fi
+-done
+-# Wait for all hg commands to complete
++# Wait for all subprocesses to complete
+ wait
+
+ # Terminate with exit 0 only if all subprocesses were successful
+ ec=0
+ if [ -d ${tmp} ]; then
+- for rc in ${tmp}/*.pid.rc ; do
++ rcfiles="`(ls -a ${tmp}/*.pid.rc 2> /dev/null) || echo ''`"
++ for rc in ${rcfiles} ; do
+ exit_code=`cat ${rc} | tr -d ' \n\r'`
+ if [ "${exit_code}" != "0" ] ; then
+- echo "WARNING: ${rc} exited abnormally."
++ repo="`echo ${rc} | sed -e 's@^'${tmp}'@@' -e 's@/*\([^/]*\)\.pid\.rc$@\1@' -e 's@_@/@g'`"
++ echo "WARNING: ${repo} exited abnormally (${exit_code})" > ${status_output}
+ ec=1
+ fi
+ done
+--- ./get_source.sh Mon Dec 08 12:28:03 2014 -0800
++++ ./get_source.sh Wed Feb 04 12:14:35 2015 -0800
+@@ -1,7 +1,7 @@
+ #!/bin/sh
+
+ #
+-# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -25,9 +25,76 @@
+ # questions.
+ #
+
+-# Get clones of all nested repositories
+-sh ./common/bin/hgforest.sh clone "$@" || exit 1
++to_stderr() {
++ echo "$@" >&2
++}
++
++error() {
++ to_stderr "ERROR: $1"
++ exit ${2:-126}
++}
++
++warning() {
++ to_stderr "WARNING: $1"
++}
++
++version_field() {
++ # rev is typically omitted for minor and major releases
++ field=`echo ${1}.0 | cut -f ${2} -d .`
++ if expr 1 + $field >/dev/null 2> /dev/null; then
++ echo $field
++ else
++ echo -1
++ fi
++}
++
++# Version check
++
++# required
++reqdmajor=1
++reqdminor=4
++reqdrev=0
++
++# requested
++rqstmajor=2
++rqstminor=6
++rqstrev=3
++
++
++# installed
++hgwhere="`command -v hg`"
++if [ "x$hgwhere" = "x" ]; then
++ error "Could not locate Mercurial command"
++fi
++
++hgversion="`hg --version 2> /dev/null | sed -n -e 's@^Mercurial Distributed SCM (version \([^+]*\).*)\$@\1@p'`"
++if [ "x${hgversion}" = "x" ] ; then
++ error "Could not determine Mercurial version of $hgwhere"
++fi
++
++hgmajor="`version_field $hgversion 1`"
++hgminor="`version_field $hgversion 2`"
++hgrev="`version_field $hgversion 3`"
++
++if [ $hgmajor -eq -1 -o $hgminor -eq -1 -o $hgrev -eq -1 ] ; then
++ error "Could not determine Mercurial version of $hgwhere from \"$hgversion\""
++fi
++
++
++# Require
++if [ $hgmajor -lt $reqdmajor -o \( $hgmajor -eq $reqdmajor -a $hgminor -lt $reqdminor \) -o \( $hgmajor -eq $reqdmajor -a $hgminor -eq $reqdminor -a $hgrev -lt $reqdrev \) ] ; then
++ error "Mercurial version $reqdmajor.$reqdminor.$reqdrev or later is required. $hgwhere is version $hgversion"
++fi
++
++
++# Request
++if [ $hgmajor -lt $rqstmajor -o \( $hgmajor -eq $rqstmajor -a $hgminor -lt $rqstminor \) -o \( $hgmajor -eq $rqstmajor -a $hgminor -eq $rqstminor -a $hgrev -lt $rqstrev \) ] ; then
++ warning "Mercurial version $rqstmajor.$rqstminor.$rqstrev or later is recommended. $hgwhere is version $hgversion"
++fi
++
++
++# Get clones of all absent nested repositories (harmless if already exist)
++sh ./common/bin/hgforest.sh clone "$@" || exit $?
+
+ # Update all existing repositories to the latest sources
+ sh ./common/bin/hgforest.sh pull -u
+-
+--- ./make/Javadoc.gmk Mon Dec 08 12:28:03 2014 -0800
++++ ./make/Javadoc.gmk Wed Feb 04 12:14:35 2015 -0800
+@@ -70,6 +70,7 @@
+ SCTPAPI_FIRST_COPYRIGHT_YEAR = 2009
+ TRACING_FIRST_COPYRIGHT_YEAR = 2008
+ TREEAPI_FIRST_COPYRIGHT_YEAR = 2005
++NASHORNAPI_FIRST_COPYRIGHT_YEAR = 2014
+ JNLP_FIRST_COPYRIGHT_YEAR = 1998
+ PLUGIN2_FIRST_COPYRIGHT_YEAR = 2007
+ JDKNET_FIRST_COPYRIGHT_YEAR = 2014
+@@ -113,10 +114,10 @@
+
+ # Url to devdocs page
+ # Was: http://java.sun.com/javase/6/webnotes/devdocs-vs-specs.html
+-DEV_DOCS_URL-7 = http://download.oracle.com/javase/7/docs/index.html
+-DEV_DOCS_URL-8 = http://download.oracle.com/javase/8/docs/index.html
++DEV_DOCS_URL-7 = https://docs.oracle.com/javase/7/docs/index.html
++DEV_DOCS_URL-8 = https://docs.oracle.com/javase/8/docs/index.html
+ DEV_DOCS_URL = $(DEV_DOCS_URL-$(JDK_MINOR_VERSION))
+-DOCS_BASE_URL = http://download.oracle.com/javase/7/docs
++DOCS_BASE_URL = https://docs.oracle.com/javase/7/docs
+
+ # Common Java trademark line
+ JAVA_TRADEMARK_LINE = Java is a trademark or registered trademark of \
+@@ -137,6 +138,7 @@
+ $(JDK_OUTPUTDIR)/gendocsrc_rmic \
+ $(JDK_TOPDIR)/src/solaris/classes \
+ $(JDK_TOPDIR)/src/windows/classes \
++ $(NASHORN_TOPDIR)/src/ \
+ $(JDK_SHARE_SRC)/doc/stub
+
+ # List of directories that actually exist
+@@ -311,6 +313,13 @@
+ #################################################################
+
+ #
++# Load custom Javadoc rules, if present
++#
++-include $(CUSTOM_MAKE_DIR)/Javadoc.gmk
++
++#################################################################
++
++#
+ # Default target is same as docs target, create core api and all others it can
+ #
+
+@@ -1095,6 +1104,60 @@
+
+ #############################################################
+ #
++# nashornapidocs
++#
++
++ALL_OTHER_TARGETS += nashornapidocs
++
++NASHORNAPI_DOCDIR := $(JDK_API_DOCSDIR)/nashorn
++NASHORNAPI2COREAPI := ../$(JDKJRE2COREAPI)
++NASHORNAPI_DOCTITLE := Nashorn API
++NASHORNAPI_WINDOWTITLE := Nashorn API
++NASHORNAPI_HEADER := <strong>Nashorn API</strong>
++NASHORNAPI_BOTTOM := $(call CommonBottom,$(NASHORNAPI_FIRST_COPYRIGHT_YEAR))
++NASHORNAPI_GROUPNAME := Packages
++NASHORNAPI_REGEXP := jdk.nashorn.api.scripting.*
++
++# NASHORNAPI_PKGS is located in NON_CORE_PKGS.gmk
++
++NASHORNAPI_INDEX_HTML = $(NASHORNAPI_DOCDIR)/index.html
++NASHORNAPI_OPTIONS_FILE = $(DOCSTMPDIR)/nashornapi.options
++NASHORNAPI_PACKAGES_FILE = $(DOCSTMPDIR)/nashornapi.packages
++
++nashornapidocs: $(NASHORNAPI_INDEX_HTML)
++
++# Set relative location to core api document root
++$(NASHORNAPI_INDEX_HTML): GET2DOCSDIR=$(NASHORNAPI2COREAPI)/..
++
++# Run javadoc if the index file is out of date or missing
++$(NASHORNAPI_INDEX_HTML): $(NASHORNAPI_OPTIONS_FILE) $(NASHORNAPI_PACKAGES_FILE) coredocs
++ $(prep-javadoc)
++ $(call JavadocSummary,$(NASHORNAPI_OPTIONS_FILE),$(NASHORNAPI_PACKAGES_FILE))
++ $(JAVADOC_CMD) -d $(@D) \
++ @$(NASHORNAPI_OPTIONS_FILE) @$(NASHORNAPI_PACKAGES_FILE)
++
++# Create file with javadoc options in it
++$(NASHORNAPI_OPTIONS_FILE):
++ $(prep-target)
++ @($(call OptionOnly,$(COMMON_JAVADOCFLAGS)) ; \
++ $(call OptionPair,-sourcepath,$(RELEASEDOCS_SOURCEPATH)) ; \
++ $(call OptionPair,-encoding,ascii) ; \
++ $(call OptionPair,-doctitle,$(NASHORNAPI_DOCTITLE)) ; \
++ $(call OptionPair,-windowtitle,$(NASHORNAPI_WINDOWTITLE) $(DRAFT_WINTITLE)); \
++ $(call OptionPair,-header,$(NASHORNAPI_HEADER)$(DRAFT_HEADER)) ; \
++ $(call OptionPair,-tag,$(TAG_JLS)) ; \
++ $(call OptionPair,-bottom,$(NASHORNAPI_BOTTOM)$(DRAFT_BOTTOM)) ; \
++ $(call OptionTrip,-group,$(NASHORNAPI_GROUPNAME),$(NASHORNAPI_REGEXP)); \
++ $(call OptionTrip,-linkoffline,$(NASHORNAPI2COREAPI),$(COREAPI_DOCSDIR)/); \
++ ) >> $@
++
++# Create a file with the package names in it
++$(NASHORNAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(NASHORNAPI_PKGS))
++ $(prep-target)
++ $(call PackageFilter,$(NASHORNAPI_PKGS))
++
++#############################################################
++#
+ # sctpdocs
+ #
+
+--- ./make/Jprt.gmk Mon Dec 08 12:28:03 2014 -0800
++++ ./make/Jprt.gmk Wed Feb 04 12:14:35 2015 -0800
+@@ -23,155 +23,11 @@
+ # questions.
+ #
+
+-# This file is included by the root NewerMakefile and contains targets
+-# and utilities needed by JPRT.
++# This file is contains targets utilities needed by JPRT.
+
+-# Utilities used in this Makefile. Most of this makefile executes without
+-# the context of a spec file from configure.
+-CAT=cat
+-CMP=cmp
+-CP=cp
+-ECHO=echo
+-MKDIR=mkdir
+-PRINTF=printf
+-PWD=pwd
+-# Insure we have a path that looks like it came from pwd
+-# (This is mostly for Windows sake and drive letters)
+-define UnixPath # path
+-$(shell (cd "$1" && $(PWD)))
+-endef
+-
+-BUILD_DIR_ROOT:=$(root_dir)/build
+-
+-ifdef OPENJDK
+- OPEN_BUILD=true
+-else
+- OPEN_BUILD := $(if $(or $(wildcard $(root_dir)/jdk/src/closed), \
+- $(wildcard $(root_dir)/jdk/make/closed), \
+- $(wildcard $(root_dir)/jdk/test/closed), \
+- $(wildcard $(root_dir)/hotspot/src/closed), \
+- $(wildcard $(root_dir)/hotspot/make/closed), \
+- $(wildcard $(root_dir)/hotspot/test/closed)), \
+- false,true)
+-endif
+-
+-HOTSPOT_AVAILABLE := $(if $(wildcard $(root_dir)/hotspot),true,false)
+-
+-###########################################################################
+-# To help in adoption of the new configure&&make build process, a bridge
+-# build will use the old settings to run configure and do the build.
+-
+-# Build with the configure bridge. After running configure, restart make
+-# to parse the new spec file.
+-BRIDGE_TARGETS := all
+-# Add bootcycle-images target if legacy variable is set.
+-ifeq ($(SKIP_BOOT_CYCLE),false)
+- BRIDGE_TARGETS += bootcycle-images
+-endif
+-bridgeBuild: bridge2configure
+- @cd $(root_dir) && $(MAKE) -f Makefile $(BRIDGE_TARGETS)
+-
+-# Bridge from old Makefile ALT settings to configure options
+-bridge2configure: $(BUILD_DIR_ROOT)/.bridge2configureOpts
+- bash ./configure $(strip $(shell $(CAT) $<))
+-
+-# Create a file with configure options created from old Makefile mechanisms.
+-$(BUILD_DIR_ROOT)/.bridge2configureOpts: $(BUILD_DIR_ROOT)/.bridge2configureOptsLatest
+- $(RM) $@
+- $(CP) $< $@
+-
+-# Use this file to only change when obvious things have changed
+-$(BUILD_DIR_ROOT)/.bridge2configureOptsLatest: FRC
+- $(RM) $@.tmp
+- $(MKDIR) -p $(BUILD_DIR_ROOT)
+- @$(ECHO) " --with-debug-level=$(if $(DEBUG_LEVEL),$(DEBUG_LEVEL),release) " >> $@.tmp
+- ifdef ARCH_DATA_MODEL
+- @$(ECHO) " --with-target-bits=$(ARCH_DATA_MODEL) " >> $@.tmp
+- endif
+- ifeq ($(ARCH_DATA_MODEL),32)
+- @$(ECHO) " --with-jvm-variants=client,server " >> $@.tmp
+- endif
+- ifdef ALT_PARALLEL_COMPILE_JOBS
+- @$(ECHO) " --with-num-cores=$(ALT_PARALLEL_COMPILE_JOBS) " >> $@.tmp
+- endif
+- ifdef ALT_BOOTDIR
+- @$(ECHO) " --with-boot-jdk=$(call UnixPath,$(ALT_BOOTDIR)) " >> $@.tmp
+- endif
+- ifdef ALT_CUPS_HEADERS_PATH
+- @$(ECHO) " --with-cups-include=$(call UnixPath,$(ALT_CUPS_HEADERS_PATH)) " >> $@.tmp
+- endif
+- ifdef ALT_FREETYPE_HEADERS_PATH
+- @$(ECHO) " --with-freetype=$(call UnixPath,$(ALT_FREETYPE_HEADERS_PATH)/..) " >> $@.tmp
+- endif
+- ifdef ENABLE_SJAVAC
+- @$(ECHO) " --enable-sjavac" >> $@.tmp
+- endif
+- ifdef JDK_UPDATE_VERSION
+- @$(ECHO) " --with-update-version=$(JDK_UPDATE_VERSION)" >> $@.tmp
+- endif
+- ifeq ($(HOTSPOT_AVAILABLE),false)
+- ifdef ALT_JDK_IMPORT_PATH
+- @$(ECHO) " --with-import-hotspot=$(call UnixPath,$(ALT_JDK_IMPORT_PATH)) " >> $@.tmp
+- endif
+- endif
+- ifeq ($(OPEN_BUILD),true)
+- @$(ECHO) " --enable-openjdk-only " >> $@.tmp
+- else
+-# Todo: move to closed?
+- ifdef ALT_MOZILLA_HEADERS_PATH
+- @$(ECHO) " --with-mozilla-headers=$(call UnixPath,$(ALT_MOZILLA_HEADERS_PATH)) " >> $@.tmp
+- endif
+- ifdef ALT_JUNIT_DIR
+- @$(ECHO) " --with-junit-dir=$(call UnixPath,$(ALT_JUNIT_DIR)) " >> $@.tmp
+- endif
+- ifdef ANT_HOME
+- @$(ECHO) " --with-ant-home=$(call UnixPath,$(ANT_HOME)) " >> $@.tmp
+- endif
+- ifdef ALT_JAVAFX_ZIP_DIR
+- @$(ECHO) " --with-javafx-zip-dir=$(call UnixPath,$(ALT_JAVAFX_ZIP_DIR)) " >> $@.tmp
+- endif
+- ifdef ALT_JMC_ZIP_DIR
+- @$(ECHO) " --with-jmc-zip-dir=$(call UnixPath,$(ALT_JMC_ZIP_DIR)) " >> $@.tmp
+- endif
+- ifdef ALT_WIXDIR
+- @$(ECHO) " --with-wix=$(call UnixPath,$(ALT_WIXDIR)) " >> $@.tmp
+- endif
+- ifdef ALT_INSTALL_LZMA_PATH
+- @$(ECHO) " --with-lzma-path=$(call UnixPath,$(ALT_INSTALL_LZMA_PATH)) " >> $@.tmp
+- endif
+- ifdef ALT_INSTALL_UPX_PATH
+- @$(ECHO) " --with-upx-path=$(call UnixPath,$(ALT_INSTALL_UPX_PATH)) " >> $@.tmp
+- endif
+- ifdef ALT_INSTALL_UPX_FILENAME
+- @$(ECHO) " --with-upx-filename=$(call UnixPath,$(ALT_INSTALL_UPX_FILENAME)) " >> $@.tmp
+- endif
+ ifdef ALT_BSDIFF_DIR
+ @$(ECHO) " --with-bsdiff-dir=$(call UnixPath,$(ALT_BSDIFF_DIR)) " >> $@.tmp
+ endif
+- ifdef ALT_CCSS_SIGNING_DIR
+- @$(ECHO) " --with-ccss-signing=$(call UnixPath,$(ALT_CCSS_SIGNING_DIR)) " >> $@.tmp
+- endif
+- ifdef ALT_SLASH_JAVA
+- @$(ECHO) " --with-java-devtools=$(call UnixPath,$(ALT_SLASH_JAVA)/devtools) " >> $@.tmp
+- endif
+- ifdef ALT_SPARKLE_FRAMEWORK_DIR
+- @$(ECHO) " --with-sparkle-framework=$(call UnixPath,$(ALT_SPARKLE_FRAMEWORK_DIR)) " >> $@.tmp
+- endif
+- endif
+- @if [ -f $@ ] ; then \
+- if ! $(CMP) $@ $@.tmp > /dev/null ; then \
+- $(CP) $@.tmp $@ ; \
+- fi ; \
+- else \
+- $(CP) $@.tmp $@ ; \
+- fi
+- $(RM) $@.tmp
+-
+-PHONY_LIST += bridge2configure bridgeBuild
+-
+-###########################################################################
+-# JPRT targets
+-
+ ifndef JPRT_ARCHIVE_BUNDLE
+ JPRT_ARCHIVE_BUNDLE=/tmp/jprt_bundles/j2sdk-image.zip
+ endif
+@@ -179,22 +35,9 @@
+ JPRT_ARCHIVE_INSTALL_BUNDLE=/tmp/jprt_bundles/product-install.zip
+ endif
+
+-# These targets execute in a SPEC free context, before calling bridgeBuild
+-# to generate the SPEC.
+-jprt_build_product: DEBUG_LEVEL=release
+-jprt_build_product: BUILD_DIRNAME=*-release
+-jprt_build_product: jprt_build_generic
+-
+-jprt_build_fastdebug: DEBUG_LEVEL=fastdebug
+-jprt_build_fastdebug: BUILD_DIRNAME=*-fastdebug
+-jprt_build_fastdebug: jprt_build_generic
+-
+-jprt_build_debug: DEBUG_LEVEL=slowdebug
+-jprt_build_debug: BUILD_DIRNAME=*-debug
+-jprt_build_debug: jprt_build_generic
+-
+-jprt_build_generic: BRIDGE_TARGETS+=jprt_bundle
+-jprt_build_generic: bridgeBuild
++ifeq ($(SKIP_BOOT_CYCLE), false)
++ jprt_bundle: bootcycle-images
++endif
+
+ # This target must be called in the context of a SPEC file
+ jprt_bundle: $(JPRT_ARCHIVE_BUNDLE)
+@@ -241,14 +84,6 @@
+ @$(call TargetExit)
+
+
+-# Keep track of phony targets
+-PHONY_LIST += jprt_build_product jprt_build_fastdebug jprt_build_debug \
+- jprt_build_generic bundles jprt_bundle \
+- final-images final-images-only
+-
+ ###########################################################################
+ # Phony targets
+-.PHONY: $(PHONY_LIST)
+-
+-# Force target
+-FRC:
++.PHONY: jprt_bundle bundles bundles-only final-images final-images-only
+--- ./make/Main.gmk Mon Dec 08 12:28:03 2014 -0800
++++ ./make/Main.gmk Wed Feb 04 12:14:35 2015 -0800
+@@ -242,4 +242,6 @@
+ .PHONY: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-nashorn clean-images clean-docs clean-test clean-overlay-images clean-bootcycle-build
+ .PHONY: profiles profiles-only profiles-oscheck
+
++include $(root_dir)/make/Jprt.gmk
++
+ FRC: # Force target
+--- ./make/MakeHelpers.gmk Mon Dec 08 12:28:03 2014 -0800
++++ ./make/MakeHelpers.gmk Wed Feb 04 12:14:35 2015 -0800
+@@ -50,7 +50,7 @@
+
+ # Global targets are possible to run either with or without a SPEC. The prototypical
+ # global target is "help".
+-global_targets=help jprt% bridgeBuild bridge2configure
++global_targets=help
+
+ ##############################
+ # Functions
+--- ./make/common/NON_CORE_PKGS.gmk Mon Dec 08 12:28:03 2014 -0800
++++ ./make/common/NON_CORE_PKGS.gmk Wed Feb 04 12:14:35 2015 -0800
+@@ -83,6 +83,8 @@
+ com.sun.source.util \
+ jdk
+
++NASHORNAPI_PKGS = jdk.nashorn.api.scripting
++
+ SMARTCARDIO_PKGS = javax.smartcardio
+
+ SCTPAPI_PKGS = com.sun.nio.sctp
+@@ -95,7 +97,8 @@
+ endif
+
+ JDK_PKGS = jdk \
+- jdk.net
++ jdk.net \
++ jdk.management.cmm
+
+ # non-core packages in rt.jar
+ NON_CORE_PKGS = $(DOMAPI_PKGS) \
+--- ./make/jprt.properties Mon Dec 08 12:28:03 2014 -0800
++++ ./make/jprt.properties Wed Feb 04 12:14:35 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -23,132 +23,467 @@
+ # questions.
+ #
+
+-# Properties for jprt
++##############
++#
++# Global settings
++#
+
+ # The current release name
+-my.jdk.update.version=25
++my.jdk.update.version=40
+ jprt.tools.default.release=jdk8u${my.jdk.update.version}
+
+-# Unix toolkit to use for building on windows
+-jprt.windows.jdk8.build.unix.toolkit=cygwin
++# Check if this is the equivalent of a hotspot push job
++# Interpret -testset hotspot to mean exactly that
++my.is.hotspot.job.hotspot=true
++my.is.hotspot.job=${my.is.hotspot.job.${jprt.test.set}}
+
+-# The different build flavors we want, we override here so we just get these 2
+-jprt.build.flavors=product,fastdebug
+-
+-# Standard list of jprt build targets for this source tree
+-jprt.build.targets= \
+- solaris_sparcv9_5.10-{product|fastdebug}, \
+- solaris_x64_5.10-{product|fastdebug}, \
+- linux_i586_2.6-{product|fastdebug}, \
+- linux_x64_2.6-{product|fastdebug}, \
+- macosx_x64_10.7-{product|fastdebug}, \
+- windows_i586_6.1-{product|fastdebug}, \
+- windows_x64_6.1-{product|fastdebug}
+-
+-# User can select the test set with jprt submit "-testset name" option
+-jprt.my.test.set=${jprt.test.set}
+-
+-# Test target list (no fastdebug & limited c2 testing)
+-jprt.my.test.target.set= \
+- solaris_sparcv9_5.10-product-c2-TESTNAME, \
+- solaris_x64_5.10-product-c2-TESTNAME, \
+- linux_i586_2.6-product-{c1|c2}-TESTNAME, \
+- linux_x64_2.6-product-c2-TESTNAME, \
+- macosx_x64_10.7-product-c2-TESTNAME, \
+- windows_i586_6.1-product-c1-TESTNAME, \
+- windows_x64_6.1-product-c2-TESTNAME
+-
+-# Default vm test targets (testset=default)
+-jprt.vm.default.test.targets= \
+- ${jprt.my.test.target.set:TESTNAME=jvm98}, \
+- ${jprt.my.test.target.set:TESTNAME=scimark}
+-
+-# Default jdk test targets (testset=default)
+-jprt.make.rule.default.test.targets= \
+- ${jprt.my.test.target.set:TESTNAME=langtools_jtreg}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_lang}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_math}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_util}
+-
+-
+-# Default vm test targets (testset=core)
+-jprt.vm.core.test.targets=
+-
+-# Core jdk test targets (testset=core)
+-jprt.make.rule.core.test.targets= \
+- ${jprt.my.test.target.set:TESTNAME=jdk_lang}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_math}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_util}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_io}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_net}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_nio}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_security1}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_security2}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_security3}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_rmi}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_text}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_time}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_other}, \
+- ${jprt.my.test.target.set:TESTNAME=core_tools}
+-
+-# Svc vm test targets (testset=svc)
+-jprt.vm.svc.test.targets=
+-
+-# Core jdk test targets (testset=svc)
+-jprt.make.rule.svc.test.targets= \
+- ${jprt.my.test.target.set:TESTNAME=jdk_management}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_instrument}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_jmx}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_jdi}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_jfr}, \
+- ${jprt.my.test.target.set:TESTNAME=svc_tools}
+-
+-# All vm test targets (testset=all)
+-jprt.vm.all.test.targets= \
+- ${jprt.vm.default.test.targets}, \
+- ${jprt.my.test.target.set:TESTNAME=runThese}, \
+- ${jprt.my.test.target.set:TESTNAME=jbb_default}
+-
+-# All jdk test targets (testset=all)
+-jprt.make.rule.all.test.targets= \
+- ${jprt.make.rule.core.test.targets}, \
+- ${jprt.make.rule.svc.test.targets}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_awt}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_beans1}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_beans2}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_beans3}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_sound}, \
+- ${jprt.my.test.target.set:TESTNAME=jdk_swing}
+-
+-# PIT vm test targets (testset=pit)
+-jprt.vm.pit.test.targets= \
+- ${jprt.vm.all.test.targets}
+-
+-# PIT jdk test targets (testset=pit)
+-jprt.make.rule.pit.test.targets= \
+- ${jprt.my.test.target.set:TESTNAME=langtools_jtreg}, \
+- ${jprt.make.rule.core.test.targets}, \
+- ${jprt.make.rule.svc.test.targets}
+-
+-# JCK test targets in test/Makefile (no windows)
+-jprt.my.jck.test.target.set= \
+- solaris_sparcv9_5.10-product-c2-JCK7TESTRULE, \
+- solaris_x64_5.10-product-c2-JCK7TESTRULE, \
+- linux_i586_2.6-product-c1-JCK7TESTRULE, \
+- linux_x64_2.6-product-c2-JCK7TESTRULE
+-
+-# JCK testset targets (e.g. jprt submit -testset jck ... )
+-jprt.make.rule.jck.test.targets= \
+- ${jprt.my.jck.test.target.set:JCK7TESTRULE=jck7devtools}, \
+- ${jprt.my.jck.test.target.set:JCK7TESTRULE=jck7runtime}, \
+- ${jprt.my.jck.test.target.set:JCK7TESTRULE=jck7compiler}
+-
+-# Select list to use (allow for testset to be empty too)
+-jprt.make.rule..test.targets=${jprt.make.rule.default.test.targets}
+-jprt.make.rule.test.targets=${jprt.make.rule.${jprt.my.test.set}.test.targets}
+-jprt.vm..test.targets=${jprt.vm.default.test.targets}
+-jprt.test.targets=${jprt.vm.${jprt.my.test.set}.test.targets}
++# Disable syncing the source after builds and tests are done
++jprt.sync.push=${my.is.hotspot.job ? false : true}
+
+ # Directories to be excluded from the source bundles
+ jprt.bundle.exclude.src.dirs=build dist webrev
+
++# Use configure when building
++jprt.build.use.configure=true
++
++# Set make target to use for different build flavors
++jprt.build.flavor.debugOpen.target=jprt_bundle
++jprt.build.flavor.fastdebug.target=jprt_bundle
++jprt.build.flavor.product.target=jprt_bundle
++jprt.build.flavor.productOpen.target=jprt_bundle
++
++# Use these configure args to define debug level
++jprt.debug.build.configure.args=--with-debug-level=slowdebug
++jprt.fastdebug.build.configure.args=--with-debug-level=fastdebug
++jprt.product.build.configure.args=--with-debug-level=release
++jprt.debugOpen.build.configure.args=${jprt.debug.build.configure.args} --enable-openjdk-only
++jprt.fastdebugOpen.build.configure.args=${jprt.fastdebug.build.configure.args} --enable-openjdk-only
++jprt.productOpen.build.configure.args=${jprt.product.build.configure.args} --enable-openjdk-only
++
++# Select build flavors and build targets
++jprt.build.flavors=${my.is.hotspot.job ? ${my.build.flavors.hotspot} : ${my.build.flavors.default}}
++jprt.build.targets=${my.is.hotspot.job ? ${my.build.targets.hotspot} : ${my.build.targets.default}}
++
++# Select test targets - jprt default for jprt.test.set is "default"
++jprt.test.targets=${my.test.targets.${jprt.test.set}}
++jprt.make.rule.test.targets=${my.make.rule.test.targets.${jprt.test.set}}
++
++# 7155453: Work-around to prevent popups on OSX from blocking test completion
++# but the work-around is added to all platforms to be consistent
++jprt.jbb.options=-Djava.awt.headless=true
++
++########
++#
++# Build options (generic)
++#
++
++# Configure args common to all builds
++# Also allows for additional, testset specific configure arguments to be set
++jprt.build.configure.args= \
++ --with-boot-jdk=$ALT_BOOTDIR \
++ --with-jobs=$ALT_PARALLEL_COMPILE_JOBS \
++ --with-update-version=${my.jdk.update.version} \
++ ${my.additional.build.configure.args.${jprt.test.set}}
++
++# i586 is often cross-compiled from 64-bit machines, so need to set target bits explicitly
++jprt.i586.build.configure.args= \
++ --with-target-bits=32
++
++# i586 platforms have both client and server, but to allow for overriding the exact configuration
++# on a per-build flavor basis the value is set for the individual build flavors
++# All other platforms only build server, which is the default setting from configure
++my.i586.default.build.configure.args= \
++ --with-jvm-variants=client,server
++jprt.i586.debug.build.configure.args= \
++ ${my.i586.default.build.configure.args} \
++ ${jprt.debug.build.configure.args}
++jprt.i586.fastdebug.build.configure.args= \
++ ${my.i586.default.build.configure.args} \
++ ${jprt.fastdebug.build.configure.args}
++jprt.i586.product.build.configure.args= \
++ ${my.i586.default.build.configure.args} \
++ ${jprt.product.build.configure.args}
++jprt.i586.debugOpen.build.configure.args= \
++ ${my.i586.default.build.configure.args} \
++ ${jprt.debugOpen.build.configure.args}
++jprt.i586.fastdebugOpen.build.configure.args= \
++ ${my.i586.default.build.configure.args} \
++ ${jprt.fastdebugOpen.build.configure.args}
++jprt.i586.productOpen.build.configure.args= \
++ ${my.i586.default.build.configure.args} \
++ ${jprt.productOpen.build.configure.args}
++
++########
++#
++# Build targets and options (default/jdk)
++#
++
++# The default build flavors
++my.build.flavors.default=fastdebug,product
++
++# Standard list of jprt build targets for this source tree
++my.build.targets.default= \
++ solaris_sparcv9_5.10-{product|fastdebug}, \
++ solaris_x64_5.10-{product|fastdebug}, \
++ linux_i586_2.6-{product|fastdebug}, \
++ linux_x64_2.6-{product|fastdebug}, \
++ macosx_x64_10.7-{product|fastdebug}, \
++ windows_i586_6.1-{product|fastdebug}, \
++ windows_x64_6.1-{product|fastdebug}
++
++# Test target list (no fastdebug & limited c2 testing)
++my.test.target.set= \
++ solaris_sparcv9_5.10-product-c2-TESTNAME, \
++ solaris_x64_5.10-product-c2-TESTNAME, \
++ linux_i586_2.6-product-{c1|c2}-TESTNAME, \
++ linux_x64_2.6-product-c2-TESTNAME, \
++ macosx_x64_10.7-product-c2-TESTNAME, \
++ windows_i586_6.1-product-c1-TESTNAME, \
++ windows_x64_6.1-product-c2-TESTNAME
++
++# Default vm test targets (testset=default)
++my.test.targets.default= \
++ ${my.test.target.set:TESTNAME=jvm98}, \
++ ${my.test.target.set:TESTNAME=scimark}
++
++# Default jdk test targets (testset=default)
++my.make.rule.test.targets.default= \
++ ${my.test.target.set:TESTNAME=langtools_jtreg}, \
++ ${my.test.target.set:TESTNAME=jdk_lang}, \
++ ${my.test.target.set:TESTNAME=jdk_math}, \
++ ${my.test.target.set:TESTNAME=jdk_util}
++
++# Default vm test targets (testset=core)
++my.test.targets.core=
++
++# Core jdk test targets (testset=core)
++my.make.rule.test.targets.core= \
++ ${my.test.target.set:TESTNAME=jdk_lang}, \
++ ${my.test.target.set:TESTNAME=jdk_math}, \
++ ${my.test.target.set:TESTNAME=jdk_util}, \
++ ${my.test.target.set:TESTNAME=jdk_io}, \
++ ${my.test.target.set:TESTNAME=jdk_net}, \
++ ${my.test.target.set:TESTNAME=jdk_nio}, \
++ ${my.test.target.set:TESTNAME=jdk_security1}, \
++ ${my.test.target.set:TESTNAME=jdk_security2}, \
++ ${my.test.target.set:TESTNAME=jdk_security3}, \
++ ${my.test.target.set:TESTNAME=jdk_security4}, \
++ ${my.test.target.set:TESTNAME=jdk_rmi}, \
++ ${my.test.target.set:TESTNAME=jdk_text}, \
++ ${my.test.target.set:TESTNAME=jdk_time}, \
++ ${my.test.target.set:TESTNAME=jdk_other}, \
++ ${my.test.target.set:TESTNAME=core_tools}
++
++# Svc vm test targets (testset=svc)
++my.test.targets.svc=
++
++# Core jdk test targets (testset=svc)
++my.make.rule.test.targets.svc= \
++ ${my.test.target.set:TESTNAME=jdk_management}, \
++ ${my.test.target.set:TESTNAME=jdk_instrument}, \
++ ${my.test.target.set:TESTNAME=jdk_jmx}, \
++ ${my.test.target.set:TESTNAME=jdk_jdi}, \
++ ${my.test.target.set:TESTNAME=jdk_jfr}, \
++ ${my.test.target.set:TESTNAME=jdk_rm}, \
++ ${my.test.target.set:TESTNAME=svc_tools}
++
++# All vm test targets (testset=all)
++my.test.targets.all= \
++ ${my.test.targets.default}, \
++ ${my.test.target.set:TESTNAME=runThese}, \
++ ${my.test.target.set:TESTNAME=jbb_default}
++
++# All jdk test targets (testset=all)
++my.make.rule.test.targets.all= \
++ ${my.make.rule.test.targets.core}, \
++ ${my.make.rule.test.targets.svc}, \
++ ${my.test.target.set:TESTNAME=jdk_awt}, \
++ ${my.test.target.set:TESTNAME=jdk_beans1}, \
++ ${my.test.target.set:TESTNAME=jdk_beans2}, \
++ ${my.test.target.set:TESTNAME=jdk_beans3}, \
++ ${my.test.target.set:TESTNAME=jdk_sound}, \
++ ${my.test.target.set:TESTNAME=jdk_swing}
++
++# PIT vm test targets (testset=pit)
++my.test.targets.pit= \
++ ${my.test.targets.all}
++
++# PIT jdk test targets (testset=pit)
++my.make.rule.test.targets.pit= \
++ ${my.test.target.set:TESTNAME=langtools_jtreg}, \
++ ${my.make.rule.test.targets.core}, \
++ ${my.make.rule.test.targets.svc}
++
++# JCK test targets in test/Makefile (no windows)
++my.test.target.set.jck= \
++ solaris_sparcv9_5.10-product-c2-JCK7TESTRULE, \
++ solaris_x64_5.10-product-c2-JCK7TESTRULE, \
++ linux_i586_2.6-product-c1-JCK7TESTRULE, \
++ linux_x64_2.6-product-c2-JCK7TESTRULE
++
++# JCK testset targets
++my.make.rule.test.targets.jck= \
++ ${my.test.target.set.jck:JCK7TESTRULE=jck7devtools}, \
++ ${my.test.target.set.jck:JCK7TESTRULE=jck7runtime}, \
++ ${my.test.target.set.jck:JCK7TESTRULE=jck7compiler}
++
++
++#############
++#
++# Hotspot related settings (testset=hotspot)
++#
++
++# The hotspot build flavors
++my.build.flavors.hotspot= \
++ debugOpen,fastdebug,product,productOpen, \
++ ${my.additional.build.flavors.hotspot}
++
++# Platforms built for hotspot push jobs
++my.build.targets.hotspot= \
++ solaris_sparcv9_5.10-{product|fastdebug|optimized}, \
++ solaris_x64_5.10-{product|fastdebug}, \
++ linux_i586_2.6-{product|fastdebug}, \
++ linux_x64_2.6-{product|fastdebug|optimized}, \
++ macosx_x64_10.7-{product|fastdebug}, \
++ windows_i586_6.1-{product|fastdebug}, \
++ windows_x64_6.1-{product|fastdebug|optimized}, \
++ solaris_x64_5.10-{debugOpen}, \
++ linux_x64_2.6-{productOpen}, \
++ ${my.additional.build.targets.hotspot}
++
++# Tests to run on the various platforms for hotspot push jobs
++my.test.targets.hotspot.solaris.sparcv9= \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-jvm98, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-jvm98_nontiered, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-scimark, \
++ solaris_sparcv9_5.10-product-c2-runThese, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_SerialGC, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_ParallelGC, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_ParNewGC, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_CMS, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_G1, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_ParOldGC, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_SerialGC, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_ParallelGC, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_ParNewGC, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_CMS, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_G1, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_ParOldGC, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-jbb_default_nontiered, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-jbb_SerialGC, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-jbb_ParallelGC, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-jbb_CMS, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-jbb_G1, \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-jbb_ParOldGC
++
++my.test.targets.hotspot.solaris.x64= \
++ solaris_x64_5.10-{product|fastdebug}-c2-jvm98, \
++ solaris_x64_5.10-{product|fastdebug}-c2-jvm98_nontiered, \
++ solaris_x64_5.10-{product|fastdebug}-c2-scimark, \
++ solaris_x64_5.10-product-c2-runThese, \
++ solaris_x64_5.10-product-c2-runThese_Xcomp, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GCBasher_SerialGC, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GCBasher_ParallelGC, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GCBasher_ParNewGC, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GCBasher_CMS, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GCBasher_G1, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GCBasher_ParOldGC, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GCOld_SerialGC, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GCOld_ParallelGC, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GCOld_ParNewGC, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GCOld_CMS, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GCOld_G1, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GCOld_ParOldGC, \
++ solaris_x64_5.10-{product|fastdebug}-c2-jbb_default_nontiered, \
++ solaris_x64_5.10-{product|fastdebug}-c2-jbb_SerialGC, \
++ solaris_x64_5.10-{product|fastdebug}-c2-jbb_ParallelGC, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GCOld_CMS, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GCOld_G1, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GCOld_ParOldGC
++
++my.test.targets.hotspot.linux.i586= \
++ linux_i586_2.6-{product|fastdebug}-{c1|c2}-jvm98, \
++ linux_i586_2.6-{product|fastdebug}-c2-jvm98_nontiered, \
++ linux_i586_2.6-{product|fastdebug}-{c1|c2}-scimark, \
++ linux_i586_2.6-product-c1-runThese_Xcomp, \
++ linux_i586_2.6-fastdebug-c1-runThese_Xshare, \
++ linux_i586_2.6-fastdebug-c2-runThese_Xcomp, \
++ linux_i586_2.6-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
++ linux_i586_2.6-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
++ linux_i586_2.6-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
++ linux_i586_2.6-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
++ linux_i586_2.6-{product|fastdebug}-{c1|c2}-GCBasher_G1, \
++ linux_i586_2.6-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \
++ linux_i586_2.6-product-{c1|c2}-GCOld_SerialGC, \
++ linux_i586_2.6-product-{c1|c2}-GCOld_ParallelGC, \
++ linux_i586_2.6-product-{c1|c2}-GCOld_ParNewGC, \
++ linux_i586_2.6-product-{c1|c2}-GCOld_CMS, \
++ linux_i586_2.6-product-{c1|c2}-GCOld_G1, \
++ linux_i586_2.6-product-{c1|c2}-GCOld_ParOldGC, \
++ linux_i586_2.6-{product|fastdebug}-c1-jbb_SerialGC, \
++ linux_i586_2.6-{product|fastdebug}-c2-jbb_default_nontiered, \
++ linux_i586_2.6-{product|fastdebug}-c1-jbb_ParallelGC, \
++ linux_i586_2.6-{product|fastdebug}-c1-jbb_CMS, \
++ linux_i586_2.6-{product|fastdebug}-c1-jbb_G1, \
++ linux_i586_2.6-{product|fastdebug}-c1-jbb_ParOldGC
++
++my.test.targets.hotspot.linux.x64= \
++ linux_x64_2.6-{product|fastdebug}-c2-jvm98, \
++ linux_x64_2.6-{product|fastdebug}-c2-jvm98_nontiered, \
++ linux_x64_2.6-{product|fastdebug}-c2-scimark, \
++ linux_x64_2.6-{product|fastdebug}-c2-GCBasher_SerialGC, \
++ linux_x64_2.6-{product|fastdebug}-c2-GCBasher_ParallelGC, \
++ linux_x64_2.6-{product|fastdebug}-c2-GCBasher_ParNewGC, \
++ linux_x64_2.6-{product|fastdebug}-c2-GCBasher_CMS, \
++ linux_x64_2.6-{product|fastdebug}-c2-GCBasher_G1, \
++ linux_x64_2.6-{product|fastdebug}-c2-GCBasher_ParOldGC, \
++ linux_x64_2.6-{product|fastdebug}-c2-GCOld_SerialGC, \
++ linux_x64_2.6-{product|fastdebug}-c2-GCOld_ParallelGC, \
++ linux_x64_2.6-{product|fastdebug}-c2-GCOld_ParNewGC, \
++ linux_x64_2.6-{product|fastdebug}-c2-GCOld_CMS, \
++ linux_x64_2.6-{product|fastdebug}-c2-GCOld_G1, \
++ linux_x64_2.6-{product|fastdebug}-c2-GCOld_ParOldGC, \
++ linux_x64_2.6-{product|fastdebug}-c2-jbb_default_nontiered, \
++ linux_x64_2.6-{product|fastdebug}-c2-jbb_ParallelGC, \
++ linux_x64_2.6-{product|fastdebug}-c2-jbb_G1, \
++ linux_x64_2.6-{product|fastdebug}-c2-jbb_ParOldGC
++
++my.test.targets.hotspot.macosx.x64= \
++ macosx_x64_10.7-{product|fastdebug}-c2-jvm98, \
++ macosx_x64_10.7-{product|fastdebug}-c2-jvm98_nontiered, \
++ macosx_x64_10.7-{product|fastdebug}-c2-scimark, \
++ macosx_x64_10.7-{product|fastdebug}-c2-GCBasher_SerialGC, \
++ macosx_x64_10.7-{product|fastdebug}-c2-GCBasher_ParallelGC, \
++ macosx_x64_10.7-{product|fastdebug}-c2-GCBasher_ParNewGC, \
++ macosx_x64_10.7-{product|fastdebug}-c2-GCBasher_CMS, \
++ macosx_x64_10.7-{product|fastdebug}-c2-GCBasher_G1, \
++ macosx_x64_10.7-{product|fastdebug}-c2-GCBasher_ParOldGC, \
++ macosx_x64_10.7-{product|fastdebug}-c2-GCOld_SerialGC, \
++ macosx_x64_10.7-{product|fastdebug}-c2-GCOld_ParallelGC, \
++ macosx_x64_10.7-{product|fastdebug}-c2-GCOld_ParNewGC, \
++ macosx_x64_10.7-{product|fastdebug}-c2-GCOld_CMS, \
++ macosx_x64_10.7-{product|fastdebug}-c2-GCOld_G1, \
++ macosx_x64_10.7-{product|fastdebug}-c2-GCOld_ParOldGC, \
++ macosx_x64_10.7-{product|fastdebug}-c2-jbb_default_nontiered, \
++ macosx_x64_10.7-{product|fastdebug}-c2-jbb_ParallelGC, \
++ macosx_x64_10.7-{product|fastdebug}-c2-jbb_G1, \
++ macosx_x64_10.7-{product|fastdebug}-c2-jbb_ParOldGC
++
++my.test.targets.hotspot.windows.i586= \
++ windows_i586_6.1-{product|fastdebug}-{c1|c2}-jvm98, \
++ windows_i586_6.1-{product|fastdebug}-c2-jvm98_nontiered, \
++ windows_i586_6.1-{product|fastdebug}-{c1|c2}-scimark, \
++ windows_i586_6.1-product-{c1|c2}-runThese, \
++ windows_i586_6.1-product-{c1|c2}-runThese_Xcomp, \
++ windows_i586_6.1-fastdebug-c1-runThese_Xshare, \
++ windows_i586_6.1-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
++ windows_i586_6.1-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
++ windows_i586_6.1-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
++ windows_i586_6.1-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
++ windows_i586_6.1-{product|fastdebug}-{c1|c2}-GCBasher_G1, \
++ windows_i586_6.1-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \
++ windows_i586_6.1-product-{c1|c2}-GCOld_SerialGC, \
++ windows_i586_6.1-product-{c1|c2}-GCOld_ParallelGC, \
++ windows_i586_6.1-product-{c1|c2}-GCOld_ParNewGC, \
++ windows_i586_6.1-product-{c1|c2}-GCOld_CMS, \
++ windows_i586_6.1-product-{c1|c2}-GCOld_G1, \
++ windows_i586_6.1-product-{c1|c2}-GCOld_ParOldGC, \
++ windows_i586_6.1-{product|fastdebug}-{c1|c2}-jbb_default, \
++ windows_i586_6.1-{product|fastdebug}-c2-jbb_default_nontiered, \
++ windows_i586_6.1-product-{c1|c2}-jbb_ParallelGC, \
++ windows_i586_6.1-product-{c1|c2}-jbb_CMS, \
++ windows_i586_6.1-product-{c1|c2}-jbb_G1, \
++ windows_i586_6.1-product-{c1|c2}-jbb_ParOldGC
++
++my.test.targets.hotspot.windows.x64= \
++ windows_x64_6.1-{product|fastdebug}-c2-jvm98, \
++ windows_x64_6.1-{product|fastdebug}-c2-jvm98_nontiered, \
++ windows_x64_6.1-{product|fastdebug}-c2-scimark, \
++ windows_x64_6.1-product-c2-runThese, \
++ windows_x64_6.1-product-c2-runThese_Xcomp, \
++ windows_x64_6.1-{product|fastdebug}-c2-GCBasher_SerialGC, \
++ windows_x64_6.1-{product|fastdebug}-c2-GCBasher_ParallelGC, \
++ windows_x64_6.1-{product|fastdebug}-c2-GCBasher_ParNewGC, \
++ windows_x64_6.1-{product|fastdebug}-c2-GCBasher_CMS, \
++ windows_x64_6.1-{product|fastdebug}-c2-GCBasher_G1, \
++ windows_x64_6.1-{product|fastdebug}-c2-GCBasher_ParOldGC, \
++ windows_x64_6.1-{product|fastdebug}-c2-GCOld_SerialGC, \
++ windows_x64_6.1-{product|fastdebug}-c2-GCOld_ParallelGC, \
++ windows_x64_6.1-{product|fastdebug}-c2-GCOld_ParNewGC, \
++ windows_x64_6.1-{product|fastdebug}-c2-GCOld_CMS, \
++ windows_x64_6.1-{product|fastdebug}-c2-GCOld_G1, \
++ windows_x64_6.1-{product|fastdebug}-c2-GCOld_ParOldGC, \
++ windows_x64_6.1-{product|fastdebug}-c2-jbb_default, \
++ windows_x64_6.1-{product|fastdebug}-c2-jbb_default_nontiered, \
++ windows_x64_6.1-product-c2-jbb_CMS, \
++ windows_x64_6.1-product-c2-jbb_ParallelGC, \
++ windows_x64_6.1-product-c2-jbb_G1, \
++ windows_x64_6.1-product-c2-jbb_ParOldGC
++
++# Some basic "smoke" tests for OpenJDK builds
++my.test.targets.hotspot.open= \
++ solaris_x64_5.10-{productOpen|fastdebugOpen}-c2-jvm98, \
++ linux_x64_2.6-{productOpen|fastdebugOpen}-c2-jvm98
++
++# The complete list of test targets for jprt
++my.test.targets.hotspot= \
++ ${my.test.targets.hotspot.open}, \
++ ${my.test.targets.hotspot.solaris.sparcv9}, \
++ ${my.test.targets.hotspot.solaris.x64}, \
++ ${my.test.targets.hotspot.linux.i586}, \
++ ${my.test.targets.hotspot.linux.x64}, \
++ ${my.test.targets.hotspot.macosx.x64}, \
++ ${my.test.targets.hotspot.windows.i586}, \
++ ${my.test.targets.hotspot.windows.x64}, \
++ ${my.test.targets.hotspot.solaris.sparcv9}, \
++ ${my.test.targets.hotspot.solaris.x64}, \
++ ${my.test.targets.hotspot.linux.x64}, \
++ ${my.test.targets.hotspot.windows.i586}, \
++ ${my.test.targets.hotspot.windows.x64}, \
++ ${my.additional.test.targets.hotspot}
++
++
++# Make file based test targets
++
++my.make.rule.test.targets.hotspot.clienttests= \
++ linux_i586_2.6-*-c1-hotspot_clienttest, \
++ windows_i586_6.1-*-c1-hotspot_clienttest
++
++my.make.rule.test.targets.hotspot.servertests= \
++ solaris_sparcv9_5.10-*-c2-hotspot_servertest, \
++ solaris_x64_5.10-*-c2-hotspot_servertest, \
++ linux_i586_2.6-*-c2-hotspot_servertest, \
++ linux_x64_2.6-*-c2-hotspot_servertest, \
++ macosx_x64_10.7-*-c2-hotspot_servertest, \
++ windows_i586_6.1-*-c2-hotspot_servertest, \
++ windows_x64_6.1-*-c2-hotspot_servertest
++
++my.make.rule.test.targets.hotspot.internalvmtests= \
++ solaris_sparcv9_5.10-fastdebug-c2-hotspot_internalvmtests, \
++ solaris_x64_5.10-fastdebug-c2-hotspot_internalvmtests, \
++ linux_i586_2.6-fastdebug-c2-hotspot_internalvmtests, \
++ linux_x64_2.6-fastdebug-c2-hotspot_internalvmtests, \
++ macosx_x64_10.7-fastdebug-c2-hotspot_internalvmtests, \
++ windows_i586_6.1-fastdebug-c2-hotspot_internalvmtests, \
++ windows_x64_6.1-fastdebug-c2-hotspot_internalvmtests
++
++my.make.rule.test.targets.hotspot.reg.group= \
++ solaris_sparcv9_5.10-{product|fastdebug}-c2-GROUP, \
++ solaris_x64_5.10-{product|fastdebug}-c2-GROUP, \
++ linux_i586_2.6-{product|fastdebug}-c2-GROUP, \
++ linux_x64_2.6-{product|fastdebug}-c2-GROUP, \
++ windows_i586_6.1-{product|fastdebug}-c2-GROUP, \
++ windows_x64_6.1-{product|fastdebug}-c2-GROUP, \
++ linux_i586_2.6-{product|fastdebug}-c1-GROUP, \
++ windows_i586_6.1-{product|fastdebug}-c1-GROUP
++
++my.make.rule.test.targets.hotspot= \
++ ${my.make.rule.test.targets.hotspot.clienttests}, \
++ ${my.make.rule.test.targets.hotspot.servertests}, \
++ ${my.make.rule.test.targets.hotspot.internalvmtests}, \
++ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_wbapitest}, \
++ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_compiler}, \
++ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_gc}, \
++ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_runtime}, \
++ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_serviceability}, \
++ ${my.additional.make.rule.test.targets.hotspot}
+--- ./test/Makefile Mon Dec 08 12:28:03 2014 -0800
++++ ./test/Makefile Wed Feb 04 12:14:35 2015 -0800
+@@ -33,6 +33,7 @@
+ # This makefile depends on the availability of sibling directories.
+ LANGTOOLS_DIR=$(TOPDIR)/langtools
+ JDK_DIR=$(TOPDIR)/jdk
++HOTSPOT_DIR=$(TOPDIR)/hotspot
+
+ # Macro to run a test target in a subdir
+ define SUBDIR_TEST # subdirectory target
+@@ -62,6 +63,9 @@
+ jdk_% core_%s svc_%:
+ @$(NO_STOPPING)$(call SUBDIR_TEST, $(JDK_DIR), TEST="$@" $@)
+
++hotspot_%:
++ @$(NO_STOPPING)$(call SUBDIR_TEST, $(HOTSPOT_DIR), TEST="$@" $@)
++
+ ################################################################
+
+ # Phony targets (e.g. these are not filenames)
+--- ./corba/.hgtags Mon Dec 08 12:28:12 2014 -0800
++++ ./corba/.hgtags Wed Feb 04 12:14:39 2015 -0800
+@@ -347,3 +347,29 @@
+ 474bf60980443dfae2fe6e121fef0caea4e014b3 jdk8u31-b10
+ 7e2056eba0b62247407e065f3f88a89358fc26a6 jdk8u31-b11
+ 285b0e589c50e46ca7ad3434221335901a547d66 jdk8u31-b12
++f89b454638d89ee5f44422b7a5b8e5651260e68f jdk8u31-b13
++7d1e0f0b63f1d66c77924d8b2a1accdf8f7480db jdk8u40-b00
++c5d9822a3c18cd9e274dfe99e91c33e02bd8f8f4 jdk8u40-b01
++504b4455570e14b7fc0a837a09c6401c603516d9 jdk8u40-b02
++91cd0ecdbe08eadf09ee89e64bf45360da8f2413 jdk8u40-b03
++f3969243c71a0f1c90f312ac755faad1deff3412 jdk8u40-b04
++740fea207f7045ab8ccc790867657d5c03a99eec jdk8u40-b05
++ced787f7545f26c3b1fdd35119ff41aa79fe6e03 jdk8u40-b06
++0d09cb188d39b5abb759977b9020ef957a0374ed jdk8u40-b07
++8d4971881c6661c51276ddb84b8e314b37d8d742 jdk8u40-b08
++bf87d71911661f583b9300795c9472179b4b3506 jdk8u40-b09
++a6d92ff8b962af32e2a9d66e956ff885d4c574b1 jdk8u40-b10
++a6dd66098734f58bc0bf847e2ca6f9b335689b9c jdk8u40-b11
++f5c47f0074b4822486c97709503b8885078c80f0 jdk8u40-b12
++7f8454e2f02fc296661a083dd4373d582980a86f jdk8u40-b13
++d36513f2cf934eb2f6f665a259cbbf2af82930c0 jdk8u40-b14
++46bf2b74baf4fc2f27b4c9238f8da94b7fcb8fe5 jdk8u40-b15
++0d3a452720a58bc203869ad606a4ea346c14c291 jdk8u40-b16
++bff1a326ac97c543b9c271adebc9deeda974edb1 jdk8u40-b17
++a1e2c13de84e00f2aedf4c40e96347306ede84f3 jdk8u40-b18
++8bbc2bb414b7e9331c2014c230553d72c9d161c5 jdk8u40-b19
++445eceffc829e205037098115c26e38e85ea5f7c jdk8u40-b20
++9c54cc92c0beb29179abbce272d3f5c8ba4ffd0e jdk8u40-b21
++4c7421f74674ebefb8e91eba59ab2a2db8c1abd7 jdk8u40-b22
++62f7faef5ed956cd481cae6216b22fdb4b6e3e46 jdk8u40-b23
++472aa5bae0e78614e873d56bcc31e7caba49963c jdk8u40-b24
+--- ./corba/THIRD_PARTY_README Mon Dec 08 12:28:12 2014 -0800
++++ ./corba/THIRD_PARTY_README Wed Feb 04 12:14:39 2015 -0800
+@@ -3385,7 +3385,7 @@
+ included with JRE 8, JDK 8, and OpenJDK 8.
+
+ Apache Commons Math 3.2
+- Apache Derby 10.10.1.3
++ Apache Derby 10.11.1.2
+ Apache Jakarta BCEL 5.1
+ Apache Jakarta Regexp 1.4
+ Apache Santuario XML Security for Java 1.5.4
+--- ./corba/src/share/classes/com/sun/corba/se/impl/io/OutputStreamHook.java Mon Dec 08 12:28:12 2014 -0800
++++ ./corba/src/share/classes/com/sun/corba/se/impl/io/OutputStreamHook.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -35,7 +35,8 @@
+ import java.io.OutputStream;
+ import java.io.ObjectOutputStream;
+ import java.io.ObjectOutput;
+-import java.util.Hashtable;
++import java.util.Map;
++import java.util.HashMap;
+
+ import org.omg.CORBA.INTERNAL;
+
+@@ -49,7 +50,7 @@
+ */
+ private class HookPutFields extends ObjectOutputStream.PutField
+ {
+- private Hashtable fields = new Hashtable();
++ private Map<String,Object> fields = new HashMap<>();
+
+ /**
+ * Put the value of the named boolean field into the persistent field.
+@@ -140,7 +141,6 @@
+ public OutputStreamHook()
+ throws java.io.IOException {
+ super();
+-
+ }
+
+ public void defaultWriteObject() throws IOException {
+--- ./hotspot/.hgtags Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/.hgtags Wed Feb 04 12:14:39 2015 -0800
+@@ -503,6 +503,30 @@
+ eaa4074a7e3975cd33ec55e6b584586e2ac681bd jdk8u20-b26
+ 7c9925f21c2529a88eb64b8039cc080f60b85e01 jdk8u20-b31
+ 7edb04063a423e278fe34a0006d25fee198f495e jdk8u20-b32
++4828415ebbf11e205dcc08e97ad5ae7dd03522f9 jdk8u40-b00
++d952af8cf67dd1e7ab5fec9a299c6c6dafd1863e hs25.40-b01
++f0afba33c928ddaa2d5f003b90d683c143f78ea3 hs25.40-b02
++e2976043eac37c8036f6a6dfa454787f64fa3f56 hs25.40-b03
++cb95655ef06fece507bbc2792474411ab2e899ab hs25.40-b04
++dc06b830ea95ed953cac02e9e67a75ab682edb97 jdk8u40-b01
++897333c7e5874625bd26d09fdaf242196024e9c2 hs25.40-b05
++f52cb91647590fe4a12af295a8a87e2cb761b044 jdk8u40-b02
++fbc31318922c31488c0464ccd864d2cd1d9e21a7 hs25.40-b06
++38539608359a6dfc5740abb66f878af643757c3b jdk8u40-b03
++c3990b8c710e4c1996b5cd579681645d9f0408c1 hs25.40-b07
++3f1b3f2dd1cb224747a11a6788e58b5cb7683d57 hs25.40-b08
++fd4dbaff30027832dd21bcc7171ddb466ca2924f jdk8u40-b04
++c9635cad4a5d794a96b4a26d3e7ad1d783133add hs25.40-b09
++232b50b20797424c64da115ca48db131b1489ac1 jdk8u40-b05
++47ec483b936ee8cd2b26752e0aba3d5e6caab393 hs25.40-b10
++3702eb6ec7086186211ab7763a44c68fc7a898eb jdk8u40-b06
++4489ac5b084aae8e2a80b71ff98d8e8acc3bf290 hs25.40-b11
++b63d0e8bfc0738bba21ae67779780f59118a95f7 jdk8u40-b07
++5c1b5be2c69bcae610a790e9438da446c61d3361 hs25.40-b12
++905a16825d2931345a7d6dba9e427f98eb51761a jdk8u40-b08
++d96716f6cbba9f000dfb1da39d2b81264f4cdea7 hs25.40-b13
++7ff8d51e0d8fc71f3ad31fd15817083341416ca8 jdk8u40-b09
++e193bbae24effeaf476f688d8d840787db53d74e hs25.40-b14
+ a4d44dfb7d30eea54bc172e4429a655454ae0bbf jdk8u25-b00
+ 9a2152fbd929b0d8b2f5c326a5526214ae71731a jdk8u25-b01
+ d3d5604ea0dea3812e87ba76ac199d0a8be6f49f jdk8u25-b02
+@@ -536,3 +560,30 @@
+ d7b6bdd51abe68b16411d5b292fb830a43c5bc09 jdk8u31-b10
+ 9906d432d6dbd2cda242e3f3cfde7cf6c90245bf jdk8u31-b11
+ e13839545238d1ecf17f0489bb6fb765de46719a jdk8u31-b12
++4206e725d584be942c25ff46ff23d8e299ca4a4c jdk8u31-b13
++1b3abbeee961dee49780c0e4af5337feb918c555 jdk8u40-b10
++f10fe402dfb1543723b4b117a7cba3ea3d4159f1 hs25.40-b15
++99372b2fee0eb8b3452f47230e84aa6e97003184 jdk8u40-b11
++8b9ec2da541a74ac698560b6a2bc45fccb789919 hs25.40-b16
++6b93bf9ea3ea57ed0fe53cfedb2f9ab912c324e5 jdk8u40-b12
++521e269ae1daa9df1cb0835b97aa76bdf340fcb2 hs25.40-b17
++86307d47790785398d0695acc361bccaefe25f94 jdk8u40-b13
++4d5dc0d0f8799fafa1135d51d85edd4edd566501 hs25.40-b18
++b8ca8ec1daea70f7c0d519e866f9f147ec247055 jdk8u40-b14
++eb16b24e2eba9bdf04a9b377bebc2db9f713ff5e jdk8u40-b15
++3a8a0fd171c5876023112941b1c7254262f9adfc hs25.40-b19
++aa2442f89230dc46147c721812f3b3bd4c612e83 hs25.40-b20
++5ea68fb91139081304357f9b937f32c5fdfeca6d jdk8u40-b16
++6bf89bfe8185747a57193efb6cec1f17ccc80414 hs25.40-b21
++fc1f9b67fd8c5d5cd94ecc03569d93e7ce7fb574 jdk8u40-b17
++bc5a90a4db47f1c497d7894434c42325f595cd02 hs25.40-b22
++31d3306aad29e39929418ed43f28212a5f5306a3 jdk8u40-b18
++f8fc5cbe082ce0fb0c6c1dcd39493a16ed916353 hs25.40-b23
++d9349fa8822336e0244da0a8448f3e6b2d62741d jdk8u40-b19
++c3933f52eeb33f70ee562464edddfe9f01d944fd jdk8u40-b20
++d2e9a6bec4f2eec8506eed16f7324992a85d8480 hs25.40-b24
++25ec4a67433744bbe3406e5069e7fd1876ebbf2f jdk8u40-b21
++0f0cb4eeab2d871274f4ffdcd6017d2fdfa89238 hs25.40-b25
++0ee548a1cda08c884eccd563e2d5fdb6ee769b5a jdk8u40-b22
++0e67683b700174eab71ea205d1cfa4f1cf4523ba jdk8u40-b23
++fa4e797f61e6dda1a60e06944018213bff2a1b76 jdk8u40-b24
+--- ./hotspot/THIRD_PARTY_README Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/THIRD_PARTY_README Wed Feb 04 12:14:39 2015 -0800
+@@ -3385,7 +3385,7 @@
+ included with JRE 8, JDK 8, and OpenJDK 8.
+
+ Apache Commons Math 3.2
+- Apache Derby 10.10.1.3
++ Apache Derby 10.11.1.2
+ Apache Jakarta BCEL 5.1
+ Apache Jakarta Regexp 1.4
+ Apache Santuario XML Security for Java 1.5.4
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1Allocator.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,40 @@
++package sun.jvm.hotspot.gc_implementation.g1;
++
++import java.util.Observable;
++import java.util.Observer;
++
++import sun.jvm.hotspot.debugger.Address;
++import sun.jvm.hotspot.runtime.VM;
++import sun.jvm.hotspot.runtime.VMObject;
++import sun.jvm.hotspot.types.CIntegerField;
++import sun.jvm.hotspot.types.Type;
++import sun.jvm.hotspot.types.TypeDataBase;
++
++public class G1Allocator extends VMObject {
++
++ //size_t _summary_bytes_used;
++ static private CIntegerField summaryBytesUsedField;
++
++ static {
++ VM.registerVMInitializedObserver(new Observer() {
++ public void update(Observable o, Object data) {
++ initialize(VM.getVM().getTypeDataBase());
++ }
++ });
++ }
++
++ static private synchronized void initialize(TypeDataBase db) {
++ Type type = db.lookupType("G1Allocator");
++
++ summaryBytesUsedField = type.getCIntegerField("_summary_bytes_used");
++ }
++
++ public long getSummaryBytes() {
++ return summaryBytesUsedField.getValue(addr);
++ }
++
++ public G1Allocator(Address addr) {
++ super(addr);
++
++ }
++}
+--- ./hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1CollectedHeap.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1CollectedHeap.java Wed Feb 04 12:14:39 2015 -0800
+@@ -36,19 +36,18 @@
+ import sun.jvm.hotspot.runtime.VM;
+ import sun.jvm.hotspot.runtime.VMObjectFactory;
+ import sun.jvm.hotspot.types.AddressField;
+-import sun.jvm.hotspot.types.CIntegerField;
+ import sun.jvm.hotspot.types.Type;
+ import sun.jvm.hotspot.types.TypeDataBase;
+
+ // Mirror class for G1CollectedHeap.
+
+ public class G1CollectedHeap extends SharedHeap {
+- // HeapRegionSeq _seq;
+- static private long hrsFieldOffset;
+- // MemRegion _g1_committed;
+- static private long g1CommittedFieldOffset;
+- // size_t _summary_bytes_used;
+- static private CIntegerField summaryBytesUsedField;
++ // HeapRegionManager _hrm;
++ static private long hrmFieldOffset;
++ // MemRegion _g1_reserved;
++ static private long g1ReservedFieldOffset;
++ // G1Allocator* _allocator
++ static private AddressField g1Allocator;
+ // G1MonitoringSupport* _g1mm;
+ static private AddressField g1mmField;
+ // HeapRegionSet _old_set;
+@@ -67,32 +66,29 @@
+ static private synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("G1CollectedHeap");
+
+- hrsFieldOffset = type.getField("_hrs").getOffset();
+- g1CommittedFieldOffset = type.getField("_g1_committed").getOffset();
+- summaryBytesUsedField = type.getCIntegerField("_summary_bytes_used");
++ hrmFieldOffset = type.getField("_hrm").getOffset();
++ g1Allocator = type.getAddressField("_allocator");
+ g1mmField = type.getAddressField("_g1mm");
+ oldSetFieldOffset = type.getField("_old_set").getOffset();
+ humongousSetFieldOffset = type.getField("_humongous_set").getOffset();
+ }
+
+ public long capacity() {
+- Address g1CommittedAddr = addr.addOffsetTo(g1CommittedFieldOffset);
+- MemRegion g1Committed = new MemRegion(g1CommittedAddr);
+- return g1Committed.byteSize();
++ return hrm().capacity();
+ }
+
+ public long used() {
+- return summaryBytesUsedField.getValue(addr);
++ return allocator().getSummaryBytes();
+ }
+
+ public long n_regions() {
+- return hrs().length();
++ return hrm().length();
+ }
+
+- private HeapRegionSeq hrs() {
+- Address hrsAddr = addr.addOffsetTo(hrsFieldOffset);
+- return (HeapRegionSeq) VMObjectFactory.newObject(HeapRegionSeq.class,
+- hrsAddr);
++ private HeapRegionManager hrm() {
++ Address hrmAddr = addr.addOffsetTo(hrmFieldOffset);
++ return (HeapRegionManager) VMObjectFactory.newObject(HeapRegionManager.class,
++ hrmAddr);
+ }
+
+ public G1MonitoringSupport g1mm() {
+@@ -100,6 +96,11 @@
+ return (G1MonitoringSupport) VMObjectFactory.newObject(G1MonitoringSupport.class, g1mmAddr);
+ }
+
++ public G1Allocator allocator() {
++ Address g1AllocatorAddr = g1Allocator.getValue(addr);
++ return (G1Allocator) VMObjectFactory.newObject(G1Allocator.class, g1AllocatorAddr);
++ }
++
+ public HeapRegionSetBase oldSet() {
+ Address oldSetAddr = addr.addOffsetTo(oldSetFieldOffset);
+ return (HeapRegionSetBase) VMObjectFactory.newObject(HeapRegionSetBase.class,
+@@ -113,7 +114,7 @@
+ }
+
+ private Iterator<HeapRegion> heapRegionIterator() {
+- return hrs().heapRegionIterator();
++ return hrm().heapRegionIterator();
+ }
+
+ public void heapRegionIterate(SpaceClosure scl) {
+--- ./hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1HeapRegionTable.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1HeapRegionTable.java Wed Feb 04 12:14:39 2015 -0800
+@@ -93,19 +93,35 @@
+ private class HeapRegionIterator implements Iterator<HeapRegion> {
+ private long index;
+ private long length;
++ private HeapRegion next;
++
++ public HeapRegion positionToNext() {
++ HeapRegion result = next;
++ while (index < length && at(index) == null) {
++ index++;
++ }
++ if (index < length) {
++ next = at(index);
++ index++; // restart search at next element
++ } else {
++ next = null;
++ }
++ return result;
++ }
+
+ @Override
+- public boolean hasNext() { return index < length; }
++ public boolean hasNext() { return next != null; }
+
+ @Override
+- public HeapRegion next() { return at(index++); }
++ public HeapRegion next() { return positionToNext(); }
+
+ @Override
+- public void remove() { /* not supported */ }
++ public void remove() { /* not supported */ }
+
+- HeapRegionIterator(long committedLength) {
++ HeapRegionIterator(long totalLength) {
+ index = 0;
+- length = committedLength;
++ length = totalLength;
++ positionToNext();
+ }
+ }
+
+--- ./hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegion.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegion.java Wed Feb 04 12:14:39 2015 -0800
+@@ -24,23 +24,26 @@
+
+ package sun.jvm.hotspot.gc_implementation.g1;
+
++import java.util.ArrayList;
++import java.util.List;
+ import java.util.Observable;
+ import java.util.Observer;
+-
+ import sun.jvm.hotspot.debugger.Address;
+-import sun.jvm.hotspot.memory.ContiguousSpace;
++import sun.jvm.hotspot.memory.CompactibleSpace;
++import sun.jvm.hotspot.memory.MemRegion;
+ import sun.jvm.hotspot.runtime.VM;
++import sun.jvm.hotspot.types.AddressField;
+ import sun.jvm.hotspot.types.CIntegerField;
+ import sun.jvm.hotspot.types.Type;
+ import sun.jvm.hotspot.types.TypeDataBase;
+
+ // Mirror class for HeapRegion. Currently we don't actually include
+-// any of its fields but only iterate over it (which we get "for free"
+-// as HeapRegion ultimately inherits from ContiguousSpace).
++// any of its fields but only iterate over it.
+
+-public class HeapRegion extends ContiguousSpace {
++public class HeapRegion extends CompactibleSpace {
+ // static int GrainBytes;
+ static private CIntegerField grainBytesField;
++ static private AddressField topField;
+
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+@@ -54,6 +57,8 @@
+ Type type = db.lookupType("HeapRegion");
+
+ grainBytesField = type.getCIntegerField("GrainBytes");
++ topField = type.getAddressField("_top");
++
+ }
+
+ static public long grainBytes() {
+@@ -63,4 +68,25 @@
+ public HeapRegion(Address addr) {
+ super(addr);
+ }
++
++ public Address top() {
++ return topField.getValue(addr);
++ }
++
++ @Override
++ public List getLiveRegions() {
++ List res = new ArrayList();
++ res.add(new MemRegion(bottom(), top()));
++ return res;
++ }
++
++ @Override
++ public long used() {
++ return top().minus(bottom());
++ }
++
++ @Override
++ public long free() {
++ return end().minus(top());
++ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionManager.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,88 @@
++/*
++ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.gc_implementation.g1;
++
++import java.util.Iterator;
++import java.util.Observable;
++import java.util.Observer;
++
++import sun.jvm.hotspot.debugger.Address;
++import sun.jvm.hotspot.runtime.VM;
++import sun.jvm.hotspot.runtime.VMObject;
++import sun.jvm.hotspot.runtime.VMObjectFactory;
++import sun.jvm.hotspot.types.AddressField;
++import sun.jvm.hotspot.types.CIntegerField;
++import sun.jvm.hotspot.types.Type;
++import sun.jvm.hotspot.types.TypeDataBase;
++
++// Mirror class for HeapRegionManager.
++
++public class HeapRegionManager extends VMObject {
++ // G1HeapRegionTable _regions
++ static private long regionsFieldOffset;
++ // uint _committed_length
++ static private CIntegerField numCommittedField;
++
++ static {
++ VM.registerVMInitializedObserver(new Observer() {
++ public void update(Observable o, Object data) {
++ initialize(VM.getVM().getTypeDataBase());
++ }
++ });
++ }
++
++ static private synchronized void initialize(TypeDataBase db) {
++ Type type = db.lookupType("HeapRegionManager");
++
++ regionsFieldOffset = type.getField("_regions").getOffset();
++ numCommittedField = type.getCIntegerField("_num_committed");
++ }
++
++ private G1HeapRegionTable regions() {
++ Address regionsAddr = addr.addOffsetTo(regionsFieldOffset);
++ return (G1HeapRegionTable) VMObjectFactory.newObject(G1HeapRegionTable.class,
++ regionsAddr);
++ }
++
++ public long capacity() {
++ return length() * HeapRegion.grainBytes();
++ }
++
++ public long length() {
++ return regions().length();
++ }
++
++ public long committedLength() {
++ return numCommittedField.getValue(addr);
++ }
++
++ public Iterator<HeapRegion> heapRegionIterator() {
++ return regions().heapRegionIterator(length());
++ }
++
++ public HeapRegionManager(Address addr) {
++ super(addr);
++ }
++}
+--- ./hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,84 +0,0 @@
+-/*
+- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- *
+- */
+-
+-package sun.jvm.hotspot.gc_implementation.g1;
+-
+-import java.util.Iterator;
+-import java.util.Observable;
+-import java.util.Observer;
+-
+-import sun.jvm.hotspot.debugger.Address;
+-import sun.jvm.hotspot.runtime.VM;
+-import sun.jvm.hotspot.runtime.VMObject;
+-import sun.jvm.hotspot.runtime.VMObjectFactory;
+-import sun.jvm.hotspot.types.AddressField;
+-import sun.jvm.hotspot.types.CIntegerField;
+-import sun.jvm.hotspot.types.Type;
+-import sun.jvm.hotspot.types.TypeDataBase;
+-
+-// Mirror class for HeapRegionSeq. It essentially encapsulates the G1HeapRegionTable.
+-
+-public class HeapRegionSeq extends VMObject {
+- // G1HeapRegionTable _regions
+- static private long regionsFieldOffset;
+- // uint _committed_length
+- static private CIntegerField committedLengthField;
+-
+- static {
+- VM.registerVMInitializedObserver(new Observer() {
+- public void update(Observable o, Object data) {
+- initialize(VM.getVM().getTypeDataBase());
+- }
+- });
+- }
+-
+- static private synchronized void initialize(TypeDataBase db) {
+- Type type = db.lookupType("HeapRegionSeq");
+-
+- regionsFieldOffset = type.getField("_regions").getOffset();
+- committedLengthField = type.getCIntegerField("_committed_length");
+- }
+-
+- private G1HeapRegionTable regions() {
+- Address regionsAddr = addr.addOffsetTo(regionsFieldOffset);
+- return (G1HeapRegionTable) VMObjectFactory.newObject(G1HeapRegionTable.class,
+- regionsAddr);
+- }
+-
+- public long length() {
+- return regions().length();
+- }
+-
+- public long committedLength() {
+- return committedLengthField.getValue(addr);
+- }
+-
+- public Iterator<HeapRegion> heapRegionIterator() {
+- return regions().heapRegionIterator(committedLength());
+- }
+-
+- public HeapRegionSeq(Address addr) {
+- super(addr);
+- }
+-}
+--- ./hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Wed Feb 04 12:14:39 2015 -0800
+@@ -152,7 +152,7 @@
+
+ private long indexOffset(long index) {
+ if (Assert.ASSERTS_ENABLED) {
+- Assert.that(index > 0 && index < getLength(), "invalid cp index " + index + " " + getLength());
++ Assert.that(index >= 0 && index < getLength(), "invalid cp index " + index + " " + getLength());
+ }
+ return (index * getElementSize()) + headerSize;
+ }
+--- ./hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java Wed Feb 04 12:14:39 2015 -0800
+@@ -98,11 +98,14 @@
+ break;
+ default: throw new IllegalArgumentException();
+ }
++
+ if (cpCache == null) {
+ return (short) cpCacheIndex;
+ } else if (fmt.indexOf("JJJJ") >= 0) {
+- // change byte-ordering and go via secondary cache entry
+- throw new InternalError("unimplemented");
++ // Invokedynamic require special handling
++ cpCacheIndex = ~cpCacheIndex;
++ cpCacheIndex = bytes.swapInt(cpCacheIndex);
++ return (short) cpCache.getEntryAt(cpCacheIndex).getConstantPoolIndex();
+ } else if (fmt.indexOf("JJ") >= 0) {
+ // change byte-ordering and go via cache
+ return (short) cpCache.getEntryAt((int) (0xFFFF & bytes.swapShort((short)cpCacheIndex))).getConstantPoolIndex();
+--- ./hotspot/make/Makefile Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/Makefile Wed Feb 04 12:14:39 2015 -0800
+@@ -95,6 +95,7 @@
+ COMMON_VM_PRODUCT_TARGETS=product product1 docs export_product
+ COMMON_VM_FASTDEBUG_TARGETS=fastdebug fastdebug1 docs export_fastdebug
+ COMMON_VM_DEBUG_TARGETS=debug debug1 docs export_debug
++COMMON_VM_OPTIMIZED_TARGETS=optimized optimized1 docs export_optimized
+
+ # JDK directory list
+ JDK_DIRS=bin include jre lib demo
+@@ -111,20 +112,21 @@
+ all_product: product1 docs export_product
+ all_fastdebug: fastdebug1 docs export_fastdebug
+ all_debug: debug1 docs export_debug
++all_optimized: optimized1 docs export_optimized
+ else
+ ifeq ($(MACOSX_UNIVERSAL),true)
+ all_product: universal_product
+ all_fastdebug: universal_fastdebug
+ all_debug: universal_debug
++all_optimized: universal_optimized
+ else
+ all_product: $(COMMON_VM_PRODUCT_TARGETS)
+ all_fastdebug: $(COMMON_VM_FASTDEBUG_TARGETS)
+ all_debug: $(COMMON_VM_DEBUG_TARGETS)
++all_optimized: $(COMMON_VM_OPTIMIZED_TARGETS)
+ endif
+ endif
+
+-all_optimized: optimized optimized1 docs export_optimized
+-
+ allzero: all_productzero all_fastdebugzero
+ all_productzero: productzero docs export_product
+ all_fastdebugzero: fastdebugzero docs export_fastdebug
+@@ -302,7 +304,7 @@
+ export_product_jdk::
+ $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) generic_export
+ export_optimized_jdk::
+- $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) generic_export
++ $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) generic_export
+ export_fastdebug_jdk::
+ $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR)/$(@:export_%_jdk=%) generic_export
+ export_debug_jdk::
+@@ -686,6 +688,19 @@
+ ($(CD) $(JDK_IMAGE_DIR)/debug && $(TAR) -xf -) ; \
+ fi
+
++copy_optimized_jdk::
++ $(RM) -r $(JDK_IMAGE_DIR)/optimized
++ $(MKDIR) -p $(JDK_IMAGE_DIR)/optimized
++ if [ -d $(JDK_IMPORT_PATH)/optimized ] ; then \
++ ($(CD) $(JDK_IMPORT_PATH)/optimized && \
++ $(TAR) -cf - $(JDK_DIRS)) | \
++ ($(CD) $(JDK_IMAGE_DIR)/optimized && $(TAR) -xf -) ; \
++ else \
++ ($(CD) $(JDK_IMPORT_PATH) && \
++ $(TAR) -cf - $(JDK_DIRS)) | \
++ ($(CD) $(JDK_IMAGE_DIR)/optimized && $(TAR) -xf -) ; \
++ fi
++
+ #
+ # Check target
+ #
+--- ./hotspot/make/aix/makefiles/adjust-mflags.sh Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/aix/makefiles/adjust-mflags.sh Wed Feb 04 12:14:39 2015 -0800
+@@ -1,6 +1,6 @@
+ #! /bin/sh
+ #
+-# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -64,7 +64,7 @@
+ echo "$MFLAGS" \
+ | sed '
+ s/^-/ -/
+- s/ -\([^ ][^ ]*\)j/ -\1 -j/
++ s/ -\([^ I][^ I]*\)j/ -\1 -j/
+ s/ -j[0-9][0-9]*/ -j/
+ s/ -j\([^ ]\)/ -j -\1/
+ s/ -j/ -j'${HOTSPOT_BUILD_JOBS:-${default_build_jobs}}'/
+--- ./hotspot/make/aix/makefiles/fastdebug.make Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/aix/makefiles/fastdebug.make Wed Feb 04 12:14:39 2015 -0800
+@@ -67,7 +67,6 @@
+ # not justified.
+ LFLAGS_QIPA=
+
+-G_SUFFIX = _g
+ VERSION = optimized
+ SYSDEFS += -DASSERT -DFASTDEBUG
+ PICFLAGS = DEFAULT
+--- ./hotspot/make/aix/makefiles/xlc.make Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/aix/makefiles/xlc.make Wed Feb 04 12:14:39 2015 -0800
+@@ -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)
+--- ./hotspot/make/bsd/makefiles/adjust-mflags.sh Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/bsd/makefiles/adjust-mflags.sh Wed Feb 04 12:14:39 2015 -0800
+@@ -64,7 +64,7 @@
+ echo "$MFLAGS" \
+ | sed '
+ s/^-/ -/
+- s/ -\([^ ][^ ]*\)j/ -\1 -j/
++ s/ -\([^ I][^ I]*\)j/ -\1 -j/
+ s/ -j[0-9][0-9]*/ -j/
+ s/ -j\([^ ]\)/ -j -\1/
+ s/ -j/ -j'${HOTSPOT_BUILD_JOBS:-${default_build_jobs}}'/
+--- ./hotspot/make/bsd/makefiles/mapfile-vers-debug Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/bsd/makefiles/mapfile-vers-debug Wed Feb 04 12:14:39 2015 -0800
+@@ -187,6 +187,9 @@
+ _JVM_IsSupportedJNIVersion
+ _JVM_IsThreadAlive
+ _JVM_IsVMGeneratedMethodIx
++ _JVM_KnownToNotExist
++ _JVM_GetResourceLookupCacheURLs
++ _JVM_GetResourceLookupCache
+ _JVM_LatestUserDefinedLoader
+ _JVM_Listen
+ _JVM_LoadClass0
+--- ./hotspot/make/bsd/makefiles/mapfile-vers-product Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/bsd/makefiles/mapfile-vers-product Wed Feb 04 12:14:39 2015 -0800
+@@ -187,6 +187,9 @@
+ _JVM_IsSupportedJNIVersion
+ _JVM_IsThreadAlive
+ _JVM_IsVMGeneratedMethodIx
++ _JVM_KnownToNotExist
++ _JVM_GetResourceLookupCacheURLs
++ _JVM_GetResourceLookupCache
+ _JVM_LatestUserDefinedLoader
+ _JVM_Listen
+ _JVM_LoadClass0
+--- ./hotspot/make/bsd/makefiles/universal.gmk Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/bsd/makefiles/universal.gmk Wed Feb 04 12:14:39 2015 -0800
+@@ -25,6 +25,8 @@
+ # macosx universal builds
+ universal_product:
+ $(MAKE) MACOSX_UNIVERSAL=true all_product_universal
++universal_optimized:
++ $(MAKE) MACOSX_UNIVERSAL=true all_optimized_universal
+ universal_fastdebug:
+ $(MAKE) MACOSX_UNIVERSAL=true all_fastdebug_universal
+ universal_debug:
+@@ -36,6 +38,10 @@
+ # $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 $(COMMON_VM_PRODUCT_TARGETS)
+ $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 $(COMMON_VM_PRODUCT_TARGETS)
+ $(QUIETLY) $(MAKE) BUILD_FLAVOR=product EXPORT_SUBDIR= universalize
++all_optimized_universal:
++# $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 $(COMMON_VM_OPTIMIZED_TARGETS)
++ $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 $(COMMON_VM_OPTIMIZED_TARGETS)
++ $(QUIETLY) $(MAKE) BUILD_FLAVOR=optimized EXPORT_SUBDIR=/optimized universalize
+ all_fastdebug_universal:
+ # $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 $(COMMON_VM_FASTDEBUG_TARGETS)
+ $(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 $(COMMON_VM_FASTDEBUG_TARGETS)
+@@ -98,13 +104,15 @@
+ export_product_jdk::
+ $(MAKE) EXPORT_SUBDIR= export_universal
+ export_optimized_jdk::
+- $(MAKE) EXPORT_SUBDIR= export_universal
++ $(MAKE) EXPORT_SUBDIR=/optimized export_universal
+ export_fastdebug_jdk::
+ $(MAKE) EXPORT_SUBDIR=/fastdebug export_universal
+ export_debug_jdk::
+ $(MAKE) EXPORT_SUBDIR=/debug export_universal
+ copy_product_jdk::
+ $(MAKE) COPY_SUBDIR= copy_universal
++copy_optimized_jdk::
++ $(MAKE) COPY_SUBDIR=/optimized copy_universal
+ copy_fastdebug_jdk::
+ $(MAKE) COPY_SUBDIR=/fastdebug copy_universal
+ copy_debug_jdk::
+@@ -112,5 +120,6 @@
+
+ .PHONY: universal_product universal_fastdebug universal_debug \
+ all_product_universal all_fastdebug_universal all_debug_universal \
++ universal_optimized all_optimized_universal \
+ universalize export_universal copy_universal \
+ $(UNIVERSAL_LIPO_LIST) $(UNIVERSAL_COPY_LIST)
+--- ./hotspot/make/bsd/makefiles/vm.make Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/bsd/makefiles/vm.make Wed Feb 04 12:14:39 2015 -0800
+@@ -243,10 +243,10 @@
+
+ vm_version.o: $(filter-out vm_version.o,$(JVM_OBJ_FILES))
+
+-mapfile : $(MAPFILE) vm.def
++mapfile : $(MAPFILE) vm.def mapfile_ext
+ rm -f $@
+ awk '{ if ($$0 ~ "INSERT VTABLE SYMBOLS HERE") \
+- { system ("cat vm.def"); } \
++ { system ("cat mapfile_ext"); system ("cat vm.def"); } \
+ else \
+ { print $$0 } \
+ }' > $@ < $(MAPFILE)
+@@ -258,6 +258,13 @@
+ vm.def: $(Res_Files) $(Obj_Files)
+ sh $(GAMMADIR)/make/bsd/makefiles/build_vm_def.sh *.o > $@
+
++mapfile_ext:
++ rm -f $@
++ touch $@
++ if [ -f $(HS_ALT_MAKE)/bsd/makefiles/mapfile-ext ]; then \
++ cat $(HS_ALT_MAKE)/bsd/makefiles/mapfile-ext > $@; \
++ fi
++
+ STATIC_CXX = false
+
+ ifeq ($(LINK_INTO),AOUT)
+--- ./hotspot/make/excludeSrc.make Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/excludeSrc.make Wed Feb 04 12:14:39 2015 -0800
+@@ -21,6 +21,9 @@
+ # questions.
+ #
+ #
++
++include $(GAMMADIR)/make/altsrc.make
++
+ ifeq ($(INCLUDE_JVMTI), false)
+ CXXFLAGS += -DINCLUDE_JVMTI=0
+ CFLAGS += -DINCLUDE_JVMTI=0
+@@ -70,37 +73,49 @@
+ CXXFLAGS += -DINCLUDE_CDS=0
+ CFLAGS += -DINCLUDE_CDS=0
+
+- Src_Files_EXCLUDE += filemap.cpp metaspaceShared.cpp
++ Src_Files_EXCLUDE += filemap.cpp metaspaceShared*.cpp sharedPathsMiscInfo.cpp \
++ systemDictionaryShared.cpp classLoaderExt.cpp sharedClassUtil.cpp
+ endif
+
+ ifeq ($(INCLUDE_ALL_GCS), false)
+ CXXFLAGS += -DINCLUDE_ALL_GCS=0
+ CFLAGS += -DINCLUDE_ALL_GCS=0
+
+- Src_Files_EXCLUDE += \
+- cmsAdaptiveSizePolicy.cpp cmsCollectorPolicy.cpp \
+- cmsGCAdaptivePolicyCounters.cpp cmsLockVerifier.cpp compactibleFreeListSpace.cpp \
+- concurrentMarkSweepGeneration.cpp concurrentMarkSweepThread.cpp \
+- freeChunk.cpp adaptiveFreeList.cpp promotionInfo.cpp vmCMSOperations.cpp \
+- collectionSetChooser.cpp concurrentG1Refine.cpp concurrentG1RefineThread.cpp \
+- concurrentMark.cpp concurrentMarkThread.cpp dirtyCardQueue.cpp g1AllocRegion.cpp \
+- g1BlockOffsetTable.cpp g1CardCounts.cpp g1CollectedHeap.cpp g1CollectorPolicy.cpp \
+- g1ErgoVerbose.cpp g1GCPhaseTimes.cpp g1HRPrinter.cpp g1HotCardCache.cpp g1Log.cpp \
+- g1MMUTracker.cpp g1MarkSweep.cpp g1MemoryPool.cpp g1MonitoringSupport.cpp g1OopClosures.cpp \
+- g1RemSet.cpp g1RemSetSummary.cpp g1SATBCardTableModRefBS.cpp g1StringDedup.cpp g1StringDedupStat.cpp \
+- g1StringDedupTable.cpp g1StringDedupThread.cpp g1StringDedupQueue.cpp g1_globals.cpp heapRegion.cpp \
+- g1BiasedArray.cpp heapRegionRemSet.cpp heapRegionSeq.cpp heapRegionSet.cpp heapRegionSets.cpp \
+- ptrQueue.cpp satbQueue.cpp sparsePRT.cpp survRateGroup.cpp vm_operations_g1.cpp g1CodeCacheRemSet.cpp \
+- adjoiningGenerations.cpp adjoiningVirtualSpaces.cpp asPSOldGen.cpp asPSYoungGen.cpp \
+- cardTableExtension.cpp gcTaskManager.cpp gcTaskThread.cpp objectStartArray.cpp \
+- parallelScavengeHeap.cpp parMarkBitMap.cpp pcTasks.cpp psAdaptiveSizePolicy.cpp \
+- psCompactionManager.cpp psGCAdaptivePolicyCounters.cpp psGenerationCounters.cpp \
+- psMarkSweep.cpp psMarkSweepDecorator.cpp psMemoryPool.cpp psOldGen.cpp \
+- psParallelCompact.cpp psPromotionLAB.cpp psPromotionManager.cpp psScavenge.cpp \
+- psTasks.cpp psVirtualspace.cpp psYoungGen.cpp vmPSOperations.cpp asParNewGeneration.cpp \
+- parCardTableModRefBS.cpp parGCAllocBuffer.cpp parNewGeneration.cpp mutableSpace.cpp \
+- gSpaceCounters.cpp allocationStats.cpp spaceCounters.cpp gcAdaptivePolicyCounters.cpp \
+- mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp hSpaceCounters.cpp
++ gc_impl := $(HS_COMMON_SRC)/share/vm/gc_implementation
++ gc_impl_alt := $(HS_ALT_SRC)/share/vm/gc_implementation
++ gc_subdirs := concurrentMarkSweep g1 parallelScavenge parNew
++ gc_exclude := $(foreach gc,$(gc_subdirs), \
++ $(notdir $(wildcard $(gc_impl)/$(gc)/*.cpp)) \
++ $(notdir $(wildcard $(gc_impl_alt)/$(gc)/*.cpp)))
++ Src_Files_EXCLUDE += $(gc_exclude)
++
++ # Exclude everything in $(gc_impl)/shared except the files listed
++ # in $(gc_shared_keep).
++ gc_shared_all := $(notdir $(wildcard $(gc_impl)/shared/*.cpp))
++ gc_shared_keep := \
++ adaptiveSizePolicy.cpp \
++ ageTable.cpp \
++ collectorCounters.cpp \
++ cSpaceCounters.cpp \
++ gcId.cpp \
++ gcPolicyCounters.cpp \
++ gcStats.cpp \
++ gcTimer.cpp \
++ gcTrace.cpp \
++ gcTraceSend.cpp \
++ gcTraceTime.cpp \
++ gcUtil.cpp \
++ generationCounters.cpp \
++ markSweep.cpp \
++ objectCountEventSender.cpp \
++ spaceDecorator.cpp \
++ vmGCOperations.cpp
++ Src_Files_EXCLUDE += $(filter-out $(gc_shared_keep),$(gc_shared_all))
++
++ # src/share/vm/services
++ Src_Files_EXCLUDE += \
++ g1MemoryPool.cpp \
++ psMemoryPool.cpp
+ endif
+
+ ifeq ($(INCLUDE_NMT), false)
+@@ -108,8 +123,8 @@
+ CFLAGS += -DINCLUDE_NMT=0
+
+ Src_Files_EXCLUDE += \
+- memBaseline.cpp memPtr.cpp memRecorder.cpp memReporter.cpp memSnapshot.cpp memTrackWorker.cpp \
+- memTracker.cpp nmtDCmd.cpp
++ memBaseline.cpp memReporter.cpp mallocTracker.cpp virtualMemoryTracker.cpp nmtCommon.cpp \
++ memTracker.cpp nmtDCmd.cpp mallocSiteTable.cpp
+ endif
+
+ -include $(HS_ALT_MAKE)/excludeSrc.make
+--- ./hotspot/make/hotspot_version Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/hotspot_version Wed Feb 04 12:14:39 2015 -0800
+@@ -34,8 +34,8 @@
+ HOTSPOT_VM_COPYRIGHT=Copyright 2015
+
+ HS_MAJOR_VER=25
+-HS_MINOR_VER=31
+-HS_BUILD_NUMBER=07
++HS_MINOR_VER=40
++HS_BUILD_NUMBER=25
+
+ JDK_MAJOR_VER=1
+ JDK_MINOR_VER=8
+--- ./hotspot/make/jprt.gmk Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/jprt.gmk Wed Feb 04 12:14:39 2015 -0800
+@@ -42,6 +42,9 @@
+ jprt_build_fastdebugEmb:
+ $(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_fastdebug
+
++jprt_build_optimizedEmb:
++ $(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_optimized
++
+ jprt_build_productOpen:
+ $(MAKE) OPENJDK=true jprt_build_product
+
+@@ -51,6 +54,9 @@
+ jprt_build_fastdebugOpen:
+ $(MAKE) OPENJDK=true jprt_build_fastdebug
+
++jprt_build_optimizedOpen:
++ $(MAKE) OPENJDK=true jprt_build_optimized
++
+ jprt_build_product: all_product copy_product_jdk export_product_jdk
+ ( $(CD) $(JDK_IMAGE_DIR) && \
+ $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
+@@ -63,5 +69,9 @@
+ ( $(CD) $(JDK_IMAGE_DIR)/debug && \
+ $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
+
+-.PHONY: jprt_build_product jprt_build_fastdebug jprt_build_debug
++jprt_build_optimized: all_optimized copy_optimized_jdk export_optimized_jdk
++ ( $(CD) $(JDK_IMAGE_DIR)/optimized && \
++ $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
+
++.PHONY: jprt_build_product jprt_build_fastdebug jprt_build_debug jprt_build_optimized
++
+--- ./hotspot/make/jprt.properties Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,403 +0,0 @@
+-#
+-# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-#
+-# This code is free software; you can redistribute it and/or modify it
+-# under the terms of the GNU General Public License version 2 only, as
+-# published by the Free Software Foundation.
+-#
+-# This code is distributed in the hope that it will be useful, but WITHOUT
+-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-# version 2 for more details (a copy is included in the LICENSE file that
+-# accompanied this code).
+-#
+-# You should have received a copy of the GNU General Public License version
+-# 2 along with this work; if not, write to the Free Software Foundation,
+-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-#
+-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-# or visit www.oracle.com if you need additional information or have any
+-# questions.
+-#
+-#
+-
+-# Properties for jprt
+-
+-# All build result bundles are full jdks.
+-jprt.need.sibling.build=false
+-
+-# At submit time, the release supplied will be in jprt.submit.release
+-# and will be one of the official release names defined in jprt.
+-# jprt supports property value expansion using ${property.name} syntax.
+-
+-# This tells jprt what default release we want to build
+-
+-jprt.hotspot.default.release=jdk8u20
+-
+-jprt.tools.default.release=${jprt.submit.option.release?${jprt.submit.option.release}:${jprt.hotspot.default.release}}
+-
+-# Disable syncing the source after builds and tests are done.
+-
+-jprt.sync.push=false
+-
+-# Note: we want both embedded releases and regular releases to build and test
+-# all platforms so that regressions are not introduced (eg. change to
+-# common code by SE breaks PPC/ARM; change to common code by SE-E breaks
+-# sparc etc.
+-
+-# Define the Solaris platforms we want for the various releases
+-jprt.my.solaris.sparcv9.jdk8u20=solaris_sparcv9_5.10
+-jprt.my.solaris.sparcv9.jdk7=solaris_sparcv9_5.10
+-jprt.my.solaris.sparcv9.jdk7u8=${jprt.my.solaris.sparcv9.jdk7}
+-jprt.my.solaris.sparcv9=${jprt.my.solaris.sparcv9.${jprt.tools.default.release}}
+-
+-jprt.my.solaris.x64.jdk8u20=solaris_x64_5.10
+-jprt.my.solaris.x64.jdk7=solaris_x64_5.10
+-jprt.my.solaris.x64.jdk7u8=${jprt.my.solaris.x64.jdk7}
+-jprt.my.solaris.x64=${jprt.my.solaris.x64.${jprt.tools.default.release}}
+-
+-jprt.my.linux.i586.jdk8u20=linux_i586_2.6
+-jprt.my.linux.i586.jdk7=linux_i586_2.6
+-jprt.my.linux.i586.jdk7u8=${jprt.my.linux.i586.jdk7}
+-jprt.my.linux.i586=${jprt.my.linux.i586.${jprt.tools.default.release}}
+-
+-jprt.my.linux.x64.jdk8u20=linux_x64_2.6
+-jprt.my.linux.x64.jdk7=linux_x64_2.6
+-jprt.my.linux.x64.jdk7u8=${jprt.my.linux.x64.jdk7}
+-jprt.my.linux.x64=${jprt.my.linux.x64.${jprt.tools.default.release}}
+-
+-jprt.my.linux.ppc.jdk8u20=linux_ppc_2.6
+-jprt.my.linux.ppc.jdk7=linux_ppc_2.6
+-jprt.my.linux.ppc.jdk7u8=${jprt.my.linux.ppc.jdk7}
+-jprt.my.linux.ppc=${jprt.my.linux.ppc.${jprt.tools.default.release}}
+-
+-jprt.my.linux.ppcv2.jdk8u20=linux_ppcv2_2.6
+-jprt.my.linux.ppcv2.jdk7=linux_ppcv2_2.6
+-jprt.my.linux.ppcv2.jdk7u8=${jprt.my.linux.ppcv2.jdk7}
+-jprt.my.linux.ppcv2=${jprt.my.linux.ppcv2.${jprt.tools.default.release}}
+-
+-jprt.my.linux.armvfpsflt.jdk8u20=linux_armvfpsflt_2.6
+-jprt.my.linux.armvfpsflt=${jprt.my.linux.armvfpsflt.${jprt.tools.default.release}}
+-
+-jprt.my.linux.armvfphflt.jdk8u20=linux_armvfphflt_2.6
+-jprt.my.linux.armvfphflt=${jprt.my.linux.armvfphflt.${jprt.tools.default.release}}
+-
+-# The ARM GP vfp-sflt build is not currently supported
+-#jprt.my.linux.armvs.jdk8u20=linux_armvs_2.6
+-#jprt.my.linux.armvs=${jprt.my.linux.armvs.${jprt.tools.default.release}}
+-
+-jprt.my.linux.armvh.jdk8u20=linux_armvh_2.6
+-jprt.my.linux.armvh=${jprt.my.linux.armvh.${jprt.tools.default.release}}
+-
+-jprt.my.linux.armsflt.jdk8u20=linux_armsflt_2.6
+-jprt.my.linux.armsflt.jdk7=linux_armsflt_2.6
+-jprt.my.linux.armsflt.jdk7u8=${jprt.my.linux.armsflt.jdk7}
+-jprt.my.linux.armsflt=${jprt.my.linux.armsflt.${jprt.tools.default.release}}
+-
+-jprt.my.macosx.x64.jdk8u20=macosx_x64_10.7
+-jprt.my.macosx.x64.jdk7=macosx_x64_10.7
+-jprt.my.macosx.x64.jdk7u8=${jprt.my.macosx.x64.jdk7}
+-jprt.my.macosx.x64=${jprt.my.macosx.x64.${jprt.tools.default.release}}
+-
+-jprt.my.windows.i586.jdk8u20=windows_i586_6.1
+-jprt.my.windows.i586.jdk7=windows_i586_6.1
+-jprt.my.windows.i586.jdk7u8=${jprt.my.windows.i586.jdk7}
+-jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
+-
+-jprt.my.windows.x64.jdk8u20=windows_x64_6.1
+-jprt.my.windows.x64.jdk7=windows_x64_6.1
+-jprt.my.windows.x64.jdk7u8=${jprt.my.windows.x64.jdk7}
+-jprt.my.windows.x64=${jprt.my.windows.x64.${jprt.tools.default.release}}
+-
+-# Standard list of jprt build targets for this source tree
+-
+-jprt.build.targets.standard= \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug|optimized}, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}, \
+- ${jprt.my.linux.i586}-{product|fastdebug}, \
+- ${jprt.my.linux.x64}-{product|fastdebug|optimized}, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}, \
+- ${jprt.my.windows.i586}-{product|fastdebug}, \
+- ${jprt.my.windows.x64}-{product|fastdebug|optimized}, \
+- ${jprt.my.linux.armvh}-{product|fastdebug}
+-
+-jprt.build.targets.open= \
+- ${jprt.my.solaris.x64}-{debugOpen}, \
+- ${jprt.my.linux.x64}-{productOpen}
+-
+-jprt.build.targets.embedded= \
+- ${jprt.my.linux.i586}-{productEmb|fastdebugEmb}, \
+- ${jprt.my.linux.ppc}-{productEmb|fastdebugEmb}, \
+- ${jprt.my.linux.ppcv2}-{productEmb|fastdebugEmb}, \
+- ${jprt.my.linux.armvfpsflt}-{productEmb|fastdebugEmb}, \
+- ${jprt.my.linux.armvfphflt}-{productEmb|fastdebugEmb}, \
+- ${jprt.my.linux.armsflt}-{productEmb|fastdebugEmb}
+-
+-jprt.build.targets.all=${jprt.build.targets.standard}, \
+- ${jprt.build.targets.embedded}, ${jprt.build.targets.open}
+-
+-jprt.build.targets.jdk8u20=${jprt.build.targets.all}
+-jprt.build.targets.jdk7=${jprt.build.targets.all}
+-jprt.build.targets.jdk7u8=${jprt.build.targets.all}
+-jprt.build.targets=${jprt.build.targets.${jprt.tools.default.release}}
+-
+-# Subset lists of test targets for this source tree
+-
+-jprt.my.solaris.sparcv9.test.targets= \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jvm98, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jvm98_nontiered, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-scimark, \
+- ${jprt.my.solaris.sparcv9}-product-c2-runThese, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_SerialGC, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_CMS, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_G1, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParOldGC, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_SerialGC, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParallelGC, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParNewGC, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_CMS, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_G1, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParOldGC, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_default_nontiered, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_SerialGC, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_ParallelGC, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_CMS, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_G1, \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_ParOldGC
+-
+-jprt.my.solaris.x64.test.targets= \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jvm98, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jvm98_nontiered, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-scimark, \
+- ${jprt.my.solaris.x64}-product-c2-runThese, \
+- ${jprt.my.solaris.x64}-product-c2-runThese_Xcomp, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_G1, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_CMS, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_G1, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_default_nontiered, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_SerialGC, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_CMS, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_G1, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParOldGC
+-
+-jprt.my.linux.i586.test.targets = \
+- ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-c2-jvm98_nontiered, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-scimark, \
+- ${jprt.my.linux.i586}-product-c1-runThese_Xcomp, \
+- ${jprt.my.linux.i586}-fastdebug-c1-runThese_Xshare, \
+- ${jprt.my.linux.i586}-fastdebug-c2-runThese_Xcomp, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_G1, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \
+- ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_SerialGC, \
+- ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParallelGC, \
+- ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParNewGC, \
+- ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_CMS, \
+- ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_G1, \
+- ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParOldGC, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_SerialGC, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-c2-jbb_default_nontiered, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_ParallelGC, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_CMS, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_G1, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_ParOldGC
+-
+-jprt.my.linux.x64.test.targets = \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-jvm98, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-jvm98_nontiered, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-scimark, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_G1, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_CMS, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_G1, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_default_nontiered, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_G1, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_ParOldGC
+-
+-jprt.my.macosx.x64.test.targets = \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jvm98, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jvm98_nontiered, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-scimark, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_G1, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_CMS, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_G1, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jbb_default_nontiered, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jbb_G1, \
+- ${jprt.my.macosx.x64}-{product|fastdebug}-c2-jbb_ParOldGC
+-
+-jprt.my.windows.i586.test.targets = \
+- ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
+- ${jprt.my.windows.i586}-{product|fastdebug}-c2-jvm98_nontiered, \
+- ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-scimark, \
+- ${jprt.my.windows.i586}-product-{c1|c2}-runThese, \
+- ${jprt.my.windows.i586}-product-{c1|c2}-runThese_Xcomp, \
+- ${jprt.my.windows.i586}-fastdebug-c1-runThese_Xshare, \
+- ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
+- ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
+- ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
+- ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
+- ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_G1, \
+- ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \
+- ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_SerialGC, \
+- ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParallelGC, \
+- ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParNewGC, \
+- ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_CMS, \
+- ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_G1, \
+- ${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParOldGC, \
+- ${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-jbb_default, \
+- ${jprt.my.windows.i586}-{product|fastdebug}-c2-jbb_default_nontiered, \
+- ${jprt.my.windows.i586}-product-{c1|c2}-jbb_ParallelGC, \
+- ${jprt.my.windows.i586}-product-{c1|c2}-jbb_CMS, \
+- ${jprt.my.windows.i586}-product-{c1|c2}-jbb_G1, \
+- ${jprt.my.windows.i586}-product-{c1|c2}-jbb_ParOldGC
+-
+-jprt.my.windows.x64.test.targets = \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-jvm98, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-jvm98_nontiered, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-scimark, \
+- ${jprt.my.windows.x64}-product-c2-runThese, \
+- ${jprt.my.windows.x64}-product-c2-runThese_Xcomp, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_G1, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParOldGC, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_CMS, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_G1, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParOldGC, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-jbb_default, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-jbb_default_nontiered, \
+- ${jprt.my.windows.x64}-product-c2-jbb_CMS, \
+- ${jprt.my.windows.x64}-product-c2-jbb_ParallelGC, \
+- ${jprt.my.windows.x64}-product-c2-jbb_G1, \
+- ${jprt.my.windows.x64}-product-c2-jbb_ParOldGC
+-
+-# Some basic "smoke" tests for OpenJDK builds
+-jprt.test.targets.open = \
+- ${jprt.my.solaris.x64}-{productOpen|fastdebugOpen}-c2-jvm98, \
+- ${jprt.my.linux.x64}-{productOpen|fastdebugOpen}-c2-jvm98
+-
+-# Testing for actual embedded builds is different to standard
+-jprt.my.linux.i586.test.targets.embedded = \
+- linux_i586_2.6-product-c1-scimark
+-
+-# The complete list of test targets for jprt
+-# Note: no PPC or ARM tests at this stage
+-
+-jprt.test.targets.standard = \
+- ${jprt.my.linux.i586.test.targets.embedded}, \
+- ${jprt.my.solaris.sparcv9.test.targets}, \
+- ${jprt.my.solaris.x64.test.targets}, \
+- ${jprt.my.linux.i586.test.targets}, \
+- ${jprt.my.linux.x64.test.targets}, \
+- ${jprt.my.macosx.x64.test.targets}, \
+- ${jprt.my.windows.i586.test.targets}, \
+- ${jprt.my.windows.x64.test.targets}, \
+- ${jprt.test.targets.open}
+-
+-jprt.test.targets.embedded= \
+- ${jprt.my.linux.i586.test.targets.embedded}, \
+- ${jprt.my.solaris.sparcv9.test.targets}, \
+- ${jprt.my.solaris.x64.test.targets}, \
+- ${jprt.my.linux.x64.test.targets}, \
+- ${jprt.my.windows.i586.test.targets}, \
+- ${jprt.my.windows.x64.test.targets}
+-
+-jprt.test.targets.jdk8u20=${jprt.test.targets.standard}
+-jprt.test.targets.jdk7=${jprt.test.targets.standard}
+-jprt.test.targets.jdk7u8=${jprt.test.targets.jdk7}
+-jprt.test.targets=${jprt.test.targets.${jprt.tools.default.release}}
+-
+-# The default test/Makefile targets that should be run
+-
+-#jprt.make.rule.test.targets=*-product-*-packtest
+-
+-jprt.make.rule.test.targets.standard.client = \
+- ${jprt.my.linux.i586}-*-c1-clienttest, \
+- ${jprt.my.windows.i586}-*-c1-clienttest
+-
+-jprt.make.rule.test.targets.standard.server = \
+- ${jprt.my.solaris.sparcv9}-*-c2-servertest, \
+- ${jprt.my.solaris.x64}-*-c2-servertest, \
+- ${jprt.my.linux.i586}-*-c2-servertest, \
+- ${jprt.my.linux.x64}-*-c2-servertest, \
+- ${jprt.my.macosx.x64}-*-c2-servertest, \
+- ${jprt.my.windows.i586}-*-c2-servertest, \
+- ${jprt.my.windows.x64}-*-c2-servertest
+-
+-jprt.make.rule.test.targets.standard.internalvmtests = \
+- ${jprt.my.solaris.sparcv9}-fastdebug-c2-internalvmtests, \
+- ${jprt.my.solaris.x64}-fastdebug-c2-internalvmtests, \
+- ${jprt.my.linux.i586}-fastdebug-c2-internalvmtests, \
+- ${jprt.my.linux.x64}-fastdebug-c2-internalvmtests, \
+- ${jprt.my.macosx.x64}-fastdebug-c2-internalvmtests, \
+- ${jprt.my.windows.i586}-fastdebug-c2-internalvmtests, \
+- ${jprt.my.windows.x64}-fastdebug-c2-internalvmtests
+-
+-jprt.make.rule.test.targets.standard.wbapi = \
+- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-wbapitest, \
+- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-wbapitest, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-c2-wbapitest, \
+- ${jprt.my.linux.x64}-{product|fastdebug}-c2-wbapitest, \
+- ${jprt.my.windows.i586}-{product|fastdebug}-c2-wbapitest, \
+- ${jprt.my.windows.x64}-{product|fastdebug}-c2-wbapitest, \
+- ${jprt.my.linux.i586}-{product|fastdebug}-c1-wbapitest, \
+- ${jprt.my.windows.i586}-{product|fastdebug}-c1-wbapitest
+-
+-jprt.make.rule.test.targets.standard = \
+- ${jprt.make.rule.test.targets.standard.client}, \
+- ${jprt.make.rule.test.targets.standard.server}, \
+- ${jprt.make.rule.test.targets.standard.internalvmtests}, \
+- ${jprt.make.rule.test.targets.standard.wbapi}
+-
+-jprt.make.rule.test.targets.embedded = \
+- ${jprt.make.rule.test.targets.standard.client}
+-
+-jprt.make.rule.test.targets.jdk8u20=${jprt.make.rule.test.targets.standard}
+-jprt.make.rule.test.targets.jdk7=${jprt.make.rule.test.targets.standard}
+-jprt.make.rule.test.targets.jdk7u8=${jprt.make.rule.test.targets.jdk7}
+-jprt.make.rule.test.targets=${jprt.make.rule.test.targets.${jprt.tools.default.release}}
+-
+-# 7155453: Work-around to prevent popups on OSX from blocking test completion
+-# but the work-around is added to all platforms to be consistent
+-jprt.jbb.options=-Djava.awt.headless=true
+--- ./hotspot/make/linux/makefiles/adjust-mflags.sh Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/linux/makefiles/adjust-mflags.sh Wed Feb 04 12:14:39 2015 -0800
+@@ -64,7 +64,7 @@
+ echo "$MFLAGS" \
+ | sed '
+ s/^-/ -/
+- s/ -\([^ ][^ ]*\)j/ -\1 -j/
++ s/ -\([^ I][^ I]*\)j/ -\1 -j/
+ s/ -j[0-9][0-9]*/ -j/
+ s/ -j\([^ ]\)/ -j -\1/
+ s/ -j/ -j'${HOTSPOT_BUILD_JOBS:-${default_build_jobs}}'/
+--- ./hotspot/make/linux/makefiles/mapfile-vers-debug Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/linux/makefiles/mapfile-vers-debug Wed Feb 04 12:14:39 2015 -0800
+@@ -217,6 +217,9 @@
+ JVM_RegisterSignal;
+ JVM_ReleaseUTF;
+ JVM_ResolveClass;
++ JVM_KnownToNotExist;
++ JVM_GetResourceLookupCacheURLs;
++ JVM_GetResourceLookupCache;
+ JVM_ResumeThread;
+ JVM_Send;
+ JVM_SendTo;
+--- ./hotspot/make/linux/makefiles/mapfile-vers-product Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/linux/makefiles/mapfile-vers-product Wed Feb 04 12:14:39 2015 -0800
+@@ -217,6 +217,9 @@
+ JVM_RegisterSignal;
+ JVM_ReleaseUTF;
+ JVM_ResolveClass;
++ JVM_KnownToNotExist;
++ JVM_GetResourceLookupCacheURLs;
++ JVM_GetResourceLookupCache;
+ JVM_ResumeThread;
+ JVM_Send;
+ JVM_SendTo;
+--- ./hotspot/make/linux/makefiles/vm.make Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/linux/makefiles/vm.make Wed Feb 04 12:14:39 2015 -0800
+@@ -233,10 +233,10 @@
+
+ vm_version.o: $(filter-out vm_version.o,$(JVM_OBJ_FILES))
+
+-mapfile : $(MAPFILE) vm.def
++mapfile : $(MAPFILE) vm.def mapfile_ext
+ rm -f $@
+ awk '{ if ($$0 ~ "INSERT VTABLE SYMBOLS HERE") \
+- { system ("cat vm.def"); } \
++ { system ("cat mapfile_ext"); system ("cat vm.def"); } \
+ else \
+ { print $$0 } \
+ }' > $@ < $(MAPFILE)
+@@ -248,6 +248,13 @@
+ vm.def: $(Res_Files) $(Obj_Files)
+ sh $(GAMMADIR)/make/linux/makefiles/build_vm_def.sh *.o > $@
+
++mapfile_ext:
++ rm -f $@
++ touch $@
++ if [ -f $(HS_ALT_MAKE)/linux/makefiles/mapfile-ext ]; then \
++ cat $(HS_ALT_MAKE)/linux/makefiles/mapfile-ext > $@; \
++ fi
++
+ ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+ STATIC_CXX = false
+ else
+--- ./hotspot/make/solaris/Makefile Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/solaris/Makefile Wed Feb 04 12:14:39 2015 -0800
+@@ -159,6 +159,7 @@
+ BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) ARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH)
+ BUILDTREE_VARS += HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION) HOTSPOT_BUILD_VERSION=$(HOTSPOT_BUILD_VERSION) JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION)
+ BUILDTREE_VARS += ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS) OBJCOPY=$(OBJCOPY) STRIP_POLICY=$(STRIP_POLICY) ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES) ZIPEXE=$(ZIPEXE)
++BUILDTREE_VARS += HS_ALT_MAKE=$(HS_ALT_MAKE)
+
+ BUILDTREE = $(MAKE) -f $(BUILDTREE_MAKE) $(BUILDTREE_VARS)
+
+--- ./hotspot/make/solaris/makefiles/add_gnu_debuglink.make Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,54 +0,0 @@
+-#
+-# Copyright (c) 2012, 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.
+-#
+-#
+-
+-# Rules to build add_gnu_debuglink, used by vm.make on Solaris
+-
+-# Allow $(ADD_GNU_DEBUGLINK) to be called from any directory.
+-# We don't set or use the GENERATED macro to avoid affecting
+-# other HotSpot Makefiles.
+-TOPDIR = $(shell echo `pwd`)
+-ADD_GNU_DEBUGLINK = $(TOPDIR)/../generated/add_gnu_debuglink
+-
+-ADD_GNU_DEBUGLINK_DIR = $(GAMMADIR)/src/os/solaris/add_gnu_debuglink
+-ADD_GNU_DEBUGLINK_SRC = $(ADD_GNU_DEBUGLINK_DIR)/add_gnu_debuglink.c
+-ADD_GNU_DEBUGLINK_FLAGS =
+-LIBS_ADD_GNU_DEBUGLINK += -lelf
+-
+-ifeq ("${Platform_compiler}", "sparcWorks")
+-# Enable the following ADD_GNU_DEBUGLINK_FLAGS addition if you need to
+-# compare the built ELF objects.
+-#
+-# The -g option makes static data global and the "-W0,-noglobal"
+-# option tells the compiler to not globalize static data using a unique
+-# globalization prefix. Instead force the use of a static globalization
+-# prefix based on the source filepath so the objects from two identical
+-# compilations are the same.
+-#
+-# Note: The blog says to use "-W0,-xglobalstatic", but that doesn't
+-# seem to work. I got "-W0,-noglobal" from Kelly and that works.
+-#ADD_GNU_DEBUGLINK_FLAGS += -W0,-noglobal
+-endif # Platform_compiler == sparcWorks
+-
+-$(ADD_GNU_DEBUGLINK): $(ADD_GNU_DEBUGLINK_SRC)
+- $(CC) -g -o $@ $< $(ADD_GNU_DEBUGLINK_FLAGS) $(LIBS_ADD_GNU_DEBUGLINK)
+--- ./hotspot/make/solaris/makefiles/adjust-mflags.sh Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/solaris/makefiles/adjust-mflags.sh Wed Feb 04 12:14:39 2015 -0800
+@@ -64,7 +64,7 @@
+ echo "$MFLAGS" \
+ | sed '
+ s/^-/ -/
+- s/ -\([^ ][^ ]*\)j/ -\1 -j/
++ s/ -\([^ I][^ I]*\)j/ -\1 -j/
+ s/ -j[0-9][0-9]*/ -j/
+ s/ -j\([^ ]\)/ -j -\1/
+ s/ -j/ -j'${HOTSPOT_BUILD_JOBS:-${default_build_jobs}}'/
+--- ./hotspot/make/solaris/makefiles/buildtree.make Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/solaris/makefiles/buildtree.make Wed Feb 04 12:14:39 2015 -0800
+@@ -258,6 +258,8 @@
+ echo && echo "ZIP_DEBUGINFO_FILES = $(ZIP_DEBUGINFO_FILES)"; \
+ [ -n "$(ZIPEXE)" ] && \
+ echo && echo "ZIPEXE = $(ZIPEXE)"; \
++ [ -n "$(HS_ALT_MAKE)" ] && \
++ echo && echo "HS_ALT_MAKE = $(HS_ALT_MAKE)"; \
+ [ -n "$(HOTSPOT_EXTRA_SYSDEFS)" ] && \
+ echo && \
+ echo "HOTSPOT_EXTRA_SYSDEFS\$$(HOTSPOT_EXTRA_SYSDEFS) = $(HOTSPOT_EXTRA_SYSDEFS)" && \
+--- ./hotspot/make/solaris/makefiles/defs.make Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/solaris/makefiles/defs.make Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -133,6 +133,55 @@
+ OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
+ endif
+
++ ifneq ($(OBJCOPY),)
++ # OBJCOPY version check:
++ # - version number is last blank separate word on first line
++ # - version number formats that have been seen:
++ # - <major>.<minor>
++ # - <major>.<minor>.<micro>
++ #
++ # Full Debug Symbols on Solaris needs version 2.21.1 or newer.
++ #
++ OBJCOPY_VERS_CHK := $(shell \
++ $(OBJCOPY) --version \
++ | sed -n \
++ -e 's/.* //' \
++ -e '/^[01]\./b bad' \
++ -e '/^2\./{' \
++ -e ' s/^2\.//' \
++ -e ' /^[0-9]$$/b bad' \
++ -e ' /^[0-9]\./b bad' \
++ -e ' /^1[0-9]$$/b bad' \
++ -e ' /^1[0-9]\./b bad' \
++ -e ' /^20\./b bad' \
++ -e ' /^21\.0$$/b bad' \
++ -e ' /^21\.0\./b bad' \
++ -e '}' \
++ -e ':good' \
++ -e 's/.*/VALID_VERSION/p' \
++ -e 'q' \
++ -e ':bad' \
++ -e 's/.*/BAD_VERSION/p' \
++ -e 'q' \
++ )
++ ifeq ($(OBJCOPY_VERS_CHK),BAD_VERSION)
++ _JUNK_ := $(shell \
++ echo >&2 "WARNING: $(OBJCOPY) --version info:"; \
++ $(OBJCOPY) --version | sed -n -e 's/^/WARNING: /p' -e 'q' >&2; \
++ echo >&2 "WARNING: an objcopy version of 2.21.1 or newer" \
++ "is needed to create valid .debuginfo files."; \
++ echo >&2 "WARNING: ignoring above objcopy command."; \
++ echo >&2 "WARNING: patch 149063-01 or newer contains the" \
++ "correct Solaris 10 SPARC version."; \
++ echo >&2 "WARNING: patch 149064-01 or newer contains the" \
++ "correct Solaris 10 X86 version."; \
++ echo >&2 "WARNING: Solaris 11 Update 1 contains the" \
++ "correct version."; \
++ )
++ OBJCOPY=
++ endif
++ endif
++
+ ifeq ($(OBJCOPY),)
+ _JUNK_ := $(shell \
+ echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.")
+--- ./hotspot/make/solaris/makefiles/dtrace.make Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/solaris/makefiles/dtrace.make Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -96,25 +96,16 @@
+ XLIBJVM_DTRACE_DEBUGINFO = $(XLIBJVM_DIR)/$(LIBJVM_DTRACE_DEBUGINFO)
+ XLIBJVM_DTRACE_DIZ = $(XLIBJVM_DIR)/$(LIBJVM_DTRACE_DIZ)
+
+-$(XLIBJVM_DB): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
++$(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
+ @echo Making $@
+ $(QUIETLY) mkdir -p $(XLIBJVM_DIR) ; \
+ $(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. -I$(GENERATED) \
+ $(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
+ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+-# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
+-# Clear the SHF_ALLOC flag (if set) from empty section headers.
+-# An empty section header has sh_addr == 0 and sh_size == 0.
+-# This problem has only been seen on Solaris X64, but we call this tool
+-# on all Solaris builds just in case.
+- $(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
+ $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(XLIBJVM_DB_DEBUGINFO)
+-# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
+-# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
+-# $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $(LIBJVM_DB) ;
+ # Do this part in the $(XLIBJVM_DIR) subdir so $(XLIBJVM_DIR) is not
+ # in the link name:
+- ( cd $(XLIBJVM_DIR) && $(ADD_GNU_DEBUGLINK) $(LIBJVM_DB_DEBUGINFO) $(LIBJVM_DB) )
++ ( cd $(XLIBJVM_DIR) && $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $(LIBJVM_DB) )
+ ifeq ($(STRIP_POLICY),all_strip)
+ $(QUIETLY) $(STRIP) $@
+ else
+@@ -131,20 +122,16 @@
+ endif
+ endif
+
+-$(XLIBJVM_DTRACE): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
++$(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
+ @echo Making $@
+ $(QUIETLY) mkdir -p $(XLIBJVM_DIR) ; \
+ $(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \
+ $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
+ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+-# Clear the SHF_ALLOC flag (if set) from empty section headers.
+- $(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
+ $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(XLIBJVM_DTRACE_DEBUGINFO)
+-# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
+-# $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $(LIBJVM_DTRACE) ;
+ # Do this part in the $(XLIBJVM_DIR) subdir so $(XLIBJVM_DIR) is not
+ # in the link name:
+- ( cd $(XLIBJVM_DIR) && $(ADD_GNU_DEBUGLINK) $(LIBJVM_DTRACE_DEBUGINFO) $(LIBJVM_DTRACE) )
++ ( cd $(XLIBJVM_DIR) && $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $(LIBJVM_DTRACE) )
+ ifeq ($(STRIP_POLICY),all_strip)
+ $(QUIETLY) $(STRIP) $@
+ else
+@@ -201,17 +188,13 @@
+ $(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp
+ $(QUIETLY) $(CXX) -c -I. -o $@ $(ARCHFLAG) -D$(TYPE) $(JVMOFFS).cpp
+
+-$(LIBJVM_DB): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_DB_MAPFILE)
++$(LIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_DB_MAPFILE)
+ @echo Making $@
+ $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. -I$(GENERATED) \
+ $(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
+ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+-# Clear the SHF_ALLOC flag (if set) from empty section headers.
+- $(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
+ $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DB_DEBUGINFO)
+-# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
+-# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $@
+- $(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJVM_DB_DEBUGINFO) $@
++ $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DB_DEBUGINFO) $@
+ ifeq ($(STRIP_POLICY),all_strip)
+ $(QUIETLY) $(STRIP) $@
+ else
+@@ -226,17 +209,13 @@
+ endif
+ endif
+
+-$(LIBJVM_DTRACE): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
++$(LIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
+ @echo Making $@
+ $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. \
+ $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
+ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+-# Clear the SHF_ALLOC flag (if set) from empty section headers.
+- $(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
+ $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DTRACE_DEBUGINFO)
+-# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
+-# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $@
+- $(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJVM_DTRACE_DEBUGINFO) $@
++ $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $@
+ ifeq ($(STRIP_POLICY),all_strip)
+ $(QUIETLY) $(STRIP) $@
+ else
+--- ./hotspot/make/solaris/makefiles/fix_empty_sec_hdr_flags.make Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,54 +0,0 @@
+-#
+-# Copyright (c) 2012, 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.
+-#
+-#
+-
+-# Rules to build fix_empty_sec_hdr_flags, used by vm.make on Solaris
+-
+-# Allow $(FIX_EMPTY_SEC_HDR_FLAGS) to be called from any directory.
+-# We don't set or use the GENERATED macro to avoid affecting
+-# other HotSpot Makefiles.
+-TOPDIR = $(shell echo `pwd`)
+-FIX_EMPTY_SEC_HDR_FLAGS = $(TOPDIR)/../generated/fix_empty_sec_hdr_flags
+-
+-FIX_EMPTY_SEC_HDR_FLAGS_DIR = $(GAMMADIR)/src/os/solaris/fix_empty_sec_hdr_flags
+-FIX_EMPTY_SEC_HDR_FLAGS_SRC = $(FIX_EMPTY_SEC_HDR_FLAGS_DIR)/fix_empty_sec_hdr_flags.c
+-FIX_EMPTY_SEC_HDR_FLAGS_FLAGS =
+-LIBS_FIX_EMPTY_SEC_HDR_FLAGS += -lelf
+-
+-ifeq ("${Platform_compiler}", "sparcWorks")
+-# Enable the following FIX_EMPTY_SEC_HDR_FLAGS_FLAGS addition if you need to
+-# compare the built ELF objects.
+-#
+-# The -g option makes static data global and the "-W0,-noglobal"
+-# option tells the compiler to not globalize static data using a unique
+-# globalization prefix. Instead force the use of a static globalization
+-# prefix based on the source filepath so the objects from two identical
+-# compilations are the same.
+-#
+-# Note: The blog says to use "-W0,-xglobalstatic", but that doesn't
+-# seem to work. I got "-W0,-noglobal" from Kelly and that works.
+-#FIX_EMPTY_SEC_HDR_FLAGS_FLAGS += -W0,-noglobal
+-endif # Platform_compiler == sparcWorks
+-
+-$(FIX_EMPTY_SEC_HDR_FLAGS): $(FIX_EMPTY_SEC_HDR_FLAGS_SRC)
+- $(CC) -g -o $@ $< $(FIX_EMPTY_SEC_HDR_FLAGS_FLAGS) $(LIBS_FIX_EMPTY_SEC_HDR_FLAGS)
+--- ./hotspot/make/solaris/makefiles/jsig.make Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/solaris/makefiles/jsig.make Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -47,22 +47,13 @@
+ LFLAGS_JSIG += -mt -xnolib
+ endif
+
+-$(LIBJSIG): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
++$(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
+ @echo Making signal interposition lib...
+ $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
+ $(LFLAGS_JSIG) -o $@ $(JSIGSRCDIR)/jsig.c -ldl
+ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+-# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
+-# Clear the SHF_ALLOC flag (if set) from empty section headers.
+-# An empty section header has sh_addr == 0 and sh_size == 0.
+-# This problem has only been seen on Solaris X64, but we call this tool
+-# on all Solaris builds just in case.
+- $(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
+ $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJSIG_DEBUGINFO)
+-# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
+-# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
+-# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@
+- $(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJSIG_DEBUGINFO) $@
++ $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@
+ ifeq ($(STRIP_POLICY),all_strip)
+ $(QUIETLY) $(STRIP) $@
+ else
+--- ./hotspot/make/solaris/makefiles/mapfile-vers Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/solaris/makefiles/mapfile-vers Wed Feb 04 12:14:39 2015 -0800
+@@ -189,6 +189,9 @@
+ JVM_IsSupportedJNIVersion;
+ JVM_IsThreadAlive;
+ JVM_IsVMGeneratedMethodIx;
++ JVM_KnownToNotExist;
++ JVM_GetResourceLookupCacheURLs;
++ JVM_GetResourceLookupCache;
+ JVM_LatestUserDefinedLoader;
+ JVM_Listen;
+ JVM_LoadClass0;
+--- ./hotspot/make/solaris/makefiles/saproc.make Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/solaris/makefiles/saproc.make Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -90,7 +90,7 @@
+ #SOLARIS_11_B159_OR_LATER=-DSOLARIS_11_B159_OR_LATER
+
+
+-$(LIBSAPROC): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(SASRCFILES) $(SADISOBJ) $(SAMAPFILE)
++$(LIBSAPROC): $(SASRCFILES) $(SADISOBJ) $(SAMAPFILE)
+ $(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
+ echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \
+ exit 1; \
+@@ -121,17 +121,8 @@
+ -c -o $(SADISOBJ)
+
+ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+-# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
+-# Clear the SHF_ALLOC flag (if set) from empty section headers.
+-# An empty section header has sh_addr == 0 and sh_size == 0.
+-# This problem has only been seen on Solaris X64, but we call this tool
+-# on all Solaris builds just in case.
+- $(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
+ $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBSAPROC_DEBUGINFO)
+-# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
+-# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
+-# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@
+- $(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBSAPROC_DEBUGINFO) $@
++ $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@
+ ifeq ($(STRIP_POLICY),all_strip)
+ $(QUIETLY) $(STRIP) $@
+ else
+--- ./hotspot/make/solaris/makefiles/vm.make Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/solaris/makefiles/vm.make Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -153,14 +153,6 @@
+ include $(MAKEFILES_DIR)/dtrace.make
+
+ #----------------------------------------------------------------------
+-# add_gnu_debuglink tool
+-include $(MAKEFILES_DIR)/add_gnu_debuglink.make
+-
+-#----------------------------------------------------------------------
+-# fix_empty_sec_hdr_flags tool
+-include $(MAKEFILES_DIR)/fix_empty_sec_hdr_flags.make
+-
+-#----------------------------------------------------------------------
+ # JVM
+
+ JVM = jvm
+@@ -247,11 +239,12 @@
+
+ vm_version.o: $(filter-out vm_version.o,$(JVM_OBJ_FILES))
+
+-mapfile : $(MAPFILE) $(MAPFILE_DTRACE_OPT) vm.def
++mapfile : $(MAPFILE) $(MAPFILE_DTRACE_OPT) vm.def mapfile_ext
+ rm -f $@
+ cat $(MAPFILE) $(MAPFILE_DTRACE_OPT) \
+ | $(NAWK) '{ \
+ if ($$0 ~ "INSERT VTABLE SYMBOLS HERE") { \
++ system ("cat mapfile_ext"); \
+ system ("cat vm.def"); \
+ } else { \
+ print $$0; \
+@@ -265,6 +258,13 @@
+ vm.def: $(Obj_Files)
+ sh $(GAMMADIR)/make/solaris/makefiles/build_vm_def.sh *.o > $@
+
++mapfile_ext:
++ rm -f $@
++ touch $@
++ if [ -f $(HS_ALT_MAKE)/solaris/makefiles/mapfile-ext ]; then \
++ cat $(HS_ALT_MAKE)/solaris/makefiles/mapfile-ext > $@; \
++ fi
++
+ ifeq ($(LINK_INTO),AOUT)
+ LIBJVM.o =
+ LIBJVM_MAPFILE =
+@@ -291,7 +291,7 @@
+ LINK_VM = $(LINK_LIB.CXX)
+ endif
+ # making the library:
+-$(LIBJVM): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(LIBJVM.o) $(LIBJVM_MAPFILE)
++$(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE)
+ ifeq ($(filter -sbfast -xsbfast, $(CFLAGS_BROWSE)),)
+ @echo Linking vm...
+ $(QUIETLY) $(LINK_LIB.CXX/PRE_HOOK)
+@@ -299,17 +299,8 @@
+ $(QUIETLY) $(LINK_LIB.CXX/POST_HOOK)
+ $(QUIETLY) rm -f $@.1 && ln -s $@ $@.1
+ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+-# gobjcopy crashes on "empty" section headers with the SHF_ALLOC flag set.
+-# Clear the SHF_ALLOC flag (if set) from empty section headers.
+-# An empty section header has sh_addr == 0 and sh_size == 0.
+-# This problem has only been seen on Solaris X64, but we call this tool
+-# on all Solaris builds just in case.
+- $(QUIETLY) $(FIX_EMPTY_SEC_HDR_FLAGS) $@
+ $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DEBUGINFO)
+-# $(OBJCOPY) --add-gnu-debuglink=... corrupts SUNW_* sections.
+-# Use $(ADD_GNU_DEBUGLINK) until a fixed $(OBJCOPY) is available.
+-# $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DEBUGINFO) $@
+- $(QUIETLY) $(ADD_GNU_DEBUGLINK) $(LIBJVM_DEBUGINFO) $@
++ $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DEBUGINFO) $@
+ ifeq ($(STRIP_POLICY),all_strip)
+ $(QUIETLY) $(STRIP) $@
+ else
+--- ./hotspot/make/windows/makefiles/compile.make Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/windows/makefiles/compile.make Wed Feb 04 12:14:39 2015 -0800
+@@ -268,7 +268,7 @@
+ !endif
+ LD_FLAGS= $(LD_FLAGS) kernel32.lib user32.lib gdi32.lib winspool.lib \
+ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \
+- uuid.lib Wsock32.lib winmm.lib /nologo /machine:$(MACHINE) /opt:REF \
++ uuid.lib Wsock32.lib winmm.lib version.lib /nologo /machine:$(MACHINE) /opt:REF \
+ /opt:ICF,8
+ !if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1"
+ LD_FLAGS= $(LD_FLAGS) /map /debug
+--- ./hotspot/make/windows/makefiles/projectcreator.make Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/windows/makefiles/projectcreator.make Wed Feb 04 12:14:39 2015 -0800
+@@ -72,6 +72,7 @@
+ -ignorePath arm \
+ -ignorePath ppc \
+ -ignorePath zero \
++ -ignorePath aix \
+ -hidePath .hg
+
+
+--- ./hotspot/make/windows/makefiles/sa.make Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/make/windows/makefiles/sa.make Wed Feb 04 12:14:39 2015 -0800
+@@ -111,7 +111,7 @@
+ SA_LFLAGS = $(SA_LFLAGS) -map -debug
+ !endif
+ !if "$(BUILDARCH)" == "i486"
+-SA_LFLAGS = $(SAFESEH_FLAG) $(SA_LFLAGS)
++SA_LFLAGS = /SAFESEH $(SA_LFLAGS)
+ !endif
+
+ SA_CFLAGS = $(SA_CFLAGS) $(MP_FLAG)
+--- ./hotspot/src/cpu/ppc/vm/assembler_ppc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/assembler_ppc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+@@ -693,7 +693,7 @@
+ // PPC 1, section 4.6.7 Floating-Point Compare Instructions
+ fcmpu( CCR7, F24, F25);
+
+- tty->print_cr("\ntest_asm disassembly (0x%lx 0x%lx):", code()->insts_begin(), code()->insts_end());
++ tty->print_cr("\ntest_asm disassembly (0x%lx 0x%lx):", p2i(code()->insts_begin()), p2i(code()->insts_end()));
+ code()->decode();
+ }
+
+--- ./hotspot/src/cpu/ppc/vm/assembler_ppc.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/assembler_ppc.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -268,8 +268,35 @@
+
+ ISEL_OPCODE = (31u << OPCODE_SHIFT | 15u << 1),
+
+- MTLR_OPCODE = (31u << OPCODE_SHIFT | 467u << 1 | 8 << SPR_0_4_SHIFT),
+- MFLR_OPCODE = (31u << OPCODE_SHIFT | 339u << 1 | 8 << SPR_0_4_SHIFT),
++ // Special purpose registers
++ MTSPR_OPCODE = (31u << OPCODE_SHIFT | 467u << 1),
++ MFSPR_OPCODE = (31u << OPCODE_SHIFT | 339u << 1),
++
++ MTXER_OPCODE = (MTSPR_OPCODE | 1 << SPR_0_4_SHIFT),
++ MFXER_OPCODE = (MFSPR_OPCODE | 1 << SPR_0_4_SHIFT),
++
++ MTDSCR_OPCODE = (MTSPR_OPCODE | 3 << SPR_0_4_SHIFT),
++ MFDSCR_OPCODE = (MFSPR_OPCODE | 3 << SPR_0_4_SHIFT),
++
++ MTLR_OPCODE = (MTSPR_OPCODE | 8 << SPR_0_4_SHIFT),
++ MFLR_OPCODE = (MFSPR_OPCODE | 8 << SPR_0_4_SHIFT),
++
++ MTCTR_OPCODE = (MTSPR_OPCODE | 9 << SPR_0_4_SHIFT),
++ MFCTR_OPCODE = (MFSPR_OPCODE | 9 << SPR_0_4_SHIFT),
++
++ MTTFHAR_OPCODE = (MTSPR_OPCODE | 128 << SPR_0_4_SHIFT),
++ MFTFHAR_OPCODE = (MFSPR_OPCODE | 128 << SPR_0_4_SHIFT),
++ MTTFIAR_OPCODE = (MTSPR_OPCODE | 129 << SPR_0_4_SHIFT),
++ MFTFIAR_OPCODE = (MFSPR_OPCODE | 129 << SPR_0_4_SHIFT),
++ MTTEXASR_OPCODE = (MTSPR_OPCODE | 130 << SPR_0_4_SHIFT),
++ MFTEXASR_OPCODE = (MFSPR_OPCODE | 130 << SPR_0_4_SHIFT),
++ MTTEXASRU_OPCODE = (MTSPR_OPCODE | 131 << SPR_0_4_SHIFT),
++ MFTEXASRU_OPCODE = (MFSPR_OPCODE | 131 << SPR_0_4_SHIFT),
++
++ MTVRSAVE_OPCODE = (MTSPR_OPCODE | 256 << SPR_0_4_SHIFT),
++ MFVRSAVE_OPCODE = (MFSPR_OPCODE | 256 << SPR_0_4_SHIFT),
++
++ MFTB_OPCODE = (MFSPR_OPCODE | 268 << SPR_0_4_SHIFT),
+
+ MTCRF_OPCODE = (31u << OPCODE_SHIFT | 144u << 1),
+ MFCR_OPCODE = (31u << OPCODE_SHIFT | 19u << 1),
+@@ -291,13 +318,11 @@
+
+ // CTR-related opcodes
+ BCCTR_OPCODE = (19u << OPCODE_SHIFT | 528u << 1),
+- MTCTR_OPCODE = (31u << OPCODE_SHIFT | 467u << 1 | 9 << SPR_0_4_SHIFT),
+- MFCTR_OPCODE = (31u << OPCODE_SHIFT | 339u << 1 | 9 << SPR_0_4_SHIFT),
+-
+
+ LWZ_OPCODE = (32u << OPCODE_SHIFT),
+ LWZX_OPCODE = (31u << OPCODE_SHIFT | 23u << 1),
+ LWZU_OPCODE = (33u << OPCODE_SHIFT),
++ LWBRX_OPCODE = (31u << OPCODE_SHIFT | 534 << 1),
+
+ LHA_OPCODE = (42u << OPCODE_SHIFT),
+ LHAX_OPCODE = (31u << OPCODE_SHIFT | 343u << 1),
+@@ -306,6 +331,7 @@
+ LHZ_OPCODE = (40u << OPCODE_SHIFT),
+ LHZX_OPCODE = (31u << OPCODE_SHIFT | 279u << 1),
+ LHZU_OPCODE = (41u << OPCODE_SHIFT),
++ LHBRX_OPCODE = (31u << OPCODE_SHIFT | 790 << 1),
+
+ LBZ_OPCODE = (34u << OPCODE_SHIFT),
+ LBZX_OPCODE = (31u << OPCODE_SHIFT | 87u << 1),
+@@ -583,6 +609,37 @@
+ MTVSCR_OPCODE = (4u << OPCODE_SHIFT | 1604u ),
+ MFVSCR_OPCODE = (4u << OPCODE_SHIFT | 1540u ),
+
++ // AES (introduced with Power 8)
++ VCIPHER_OPCODE = (4u << OPCODE_SHIFT | 1288u),
++ VCIPHERLAST_OPCODE = (4u << OPCODE_SHIFT | 1289u),
++ VNCIPHER_OPCODE = (4u << OPCODE_SHIFT | 1352u),
++ VNCIPHERLAST_OPCODE = (4u << OPCODE_SHIFT | 1353u),
++ VSBOX_OPCODE = (4u << OPCODE_SHIFT | 1480u),
++
++ // SHA (introduced with Power 8)
++ VSHASIGMAD_OPCODE = (4u << OPCODE_SHIFT | 1730u),
++ VSHASIGMAW_OPCODE = (4u << OPCODE_SHIFT | 1666u),
++
++ // Vector Binary Polynomial Multiplication (introduced with Power 8)
++ VPMSUMB_OPCODE = (4u << OPCODE_SHIFT | 1032u),
++ VPMSUMD_OPCODE = (4u << OPCODE_SHIFT | 1224u),
++ VPMSUMH_OPCODE = (4u << OPCODE_SHIFT | 1096u),
++ VPMSUMW_OPCODE = (4u << OPCODE_SHIFT | 1160u),
++
++ // Vector Permute and Xor (introduced with Power 8)
++ VPERMXOR_OPCODE = (4u << OPCODE_SHIFT | 45u),
++
++ // Transactional Memory instructions (introduced with Power 8)
++ TBEGIN_OPCODE = (31u << OPCODE_SHIFT | 654u << 1),
++ TEND_OPCODE = (31u << OPCODE_SHIFT | 686u << 1),
++ TABORT_OPCODE = (31u << OPCODE_SHIFT | 910u << 1),
++ TABORTWC_OPCODE = (31u << OPCODE_SHIFT | 782u << 1),
++ TABORTWCI_OPCODE = (31u << OPCODE_SHIFT | 846u << 1),
++ TABORTDC_OPCODE = (31u << OPCODE_SHIFT | 814u << 1),
++ TABORTDCI_OPCODE = (31u << OPCODE_SHIFT | 878u << 1),
++ TSR_OPCODE = (31u << OPCODE_SHIFT | 750u << 1),
++ TCHECK_OPCODE = (31u << OPCODE_SHIFT | 718u << 1),
++
+ // Icache and dcache related instructions
+ DCBA_OPCODE = (31u << OPCODE_SHIFT | 758u << 1),
+ DCBZ_OPCODE = (31u << OPCODE_SHIFT | 1014u << 1),
+@@ -1364,11 +1421,17 @@
+ inline void lwax( Register d, Register s1, Register s2);
+ inline void lwa( Register d, int si16, Register s1);
+
++ // 4 bytes reversed
++ inline void lwbrx( Register d, Register s1, Register s2);
++
+ // 2 bytes
+ inline void lhzx( Register d, Register s1, Register s2);
+ inline void lhz( Register d, int si16, Register s1);
+ inline void lhzu( Register d, int si16, Register s1);
+
++ // 2 bytes reversed
++ inline void lhbrx( Register d, Register s1, Register s2);
++
+ // 2 bytes
+ inline void lhax( Register d, Register s1, Register s2);
+ inline void lha( Register d, int si16, Register s1);
+@@ -1412,6 +1475,25 @@
+ inline void mcrf( ConditionRegister crd, ConditionRegister cra);
+ inline void mtcr( Register s);
+
++ // Special purpose registers
++ // Exception Register
++ inline void mtxer(Register s1);
++ inline void mfxer(Register d);
++ // Vector Register Save Register
++ inline void mtvrsave(Register s1);
++ inline void mfvrsave(Register d);
++ // Timebase
++ inline void mftb(Register d);
++ // Introduced with Power 8:
++ // Data Stream Control Register
++ inline void mtdscr(Register s1);
++ inline void mfdscr(Register d );
++ // Transactional Memory Registers
++ inline void mftfhar(Register d);
++ inline void mftfiar(Register d);
++ inline void mftexasr(Register d);
++ inline void mftexasru(Register d);
++
+ // PPC 1, section 2.4.1 Branch Instructions
+ inline void b( address a, relocInfo::relocType rt = relocInfo::none);
+ inline void b( Label& L);
+@@ -1852,16 +1934,51 @@
+ inline void mtvscr( VectorRegister b);
+ inline void mfvscr( VectorRegister d);
+
++ // AES (introduced with Power 8)
++ inline void vcipher( VectorRegister d, VectorRegister a, VectorRegister b);
++ inline void vcipherlast( VectorRegister d, VectorRegister a, VectorRegister b);
++ inline void vncipher( VectorRegister d, VectorRegister a, VectorRegister b);
++ inline void vncipherlast(VectorRegister d, VectorRegister a, VectorRegister b);
++ inline void vsbox( VectorRegister d, VectorRegister a);
++
++ // SHA (introduced with Power 8)
++ // Not yet implemented.
++
++ // Vector Binary Polynomial Multiplication (introduced with Power 8)
++ inline void vpmsumb( VectorRegister d, VectorRegister a, VectorRegister b);
++ inline void vpmsumd( VectorRegister d, VectorRegister a, VectorRegister b);
++ inline void vpmsumh( VectorRegister d, VectorRegister a, VectorRegister b);
++ inline void vpmsumw( VectorRegister d, VectorRegister a, VectorRegister b);
++
++ // Vector Permute and Xor (introduced with Power 8)
++ inline void vpermxor( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c);
++
++ // Transactional Memory instructions (introduced with Power 8)
++ inline void tbegin_(); // R=0
++ inline void tbeginrot_(); // R=1 Rollback-Only Transaction
++ inline void tend_(); // A=0
++ inline void tendall_(); // A=1
++ inline void tabort_(Register a);
++ inline void tabortwc_(int t, Register a, Register b);
++ inline void tabortwci_(int t, Register a, int si);
++ inline void tabortdc_(int t, Register a, Register b);
++ inline void tabortdci_(int t, Register a, int si);
++ inline void tsuspend_(); // tsr with L=0
++ inline void tresume_(); // tsr with L=1
++ inline void tcheck(int f);
++
+ // The following encoders use r0 as second operand. These instructions
+ // read r0 as '0'.
+ inline void lwzx( Register d, Register s2);
+ inline void lwz( Register d, int si16);
+ inline void lwax( Register d, Register s2);
+ inline void lwa( Register d, int si16);
++ inline void lwbrx(Register d, Register s2);
+ inline void lhzx( Register d, Register s2);
+ inline void lhz( Register d, int si16);
+ inline void lhax( Register d, Register s2);
+ inline void lha( Register d, int si16);
++ inline void lhbrx(Register d, Register s2);
+ inline void lbzx( Register d, Register s2);
+ inline void lbz( Register d, int si16);
+ inline void ldx( Register d, Register s2);
+--- ./hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -263,10 +263,14 @@
+ inline void Assembler::lwax( Register d, Register s1, Register s2) { emit_int32(LWAX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));}
+ inline void Assembler::lwa( Register d, int si16, Register s1) { emit_int32(LWA_OPCODE | rt(d) | ds(si16) | ra0mem(s1));}
+
++inline void Assembler::lwbrx( Register d, Register s1, Register s2) { emit_int32(LWBRX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));}
++
+ inline void Assembler::lhzx( Register d, Register s1, Register s2) { emit_int32(LHZX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));}
+ inline void Assembler::lhz( Register d, int si16, Register s1) { emit_int32(LHZ_OPCODE | rt(d) | d1(si16) | ra0mem(s1));}
+ inline void Assembler::lhzu( Register d, int si16, Register s1) { assert(d != s1, "according to ibm manual"); emit_int32(LHZU_OPCODE | rt(d) | d1(si16) | rta0mem(s1));}
+
++inline void Assembler::lhbrx( Register d, Register s1, Register s2) { emit_int32(LHBRX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));}
++
+ inline void Assembler::lhax( Register d, Register s1, Register s2) { emit_int32(LHAX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));}
+ inline void Assembler::lha( Register d, int si16, Register s1) { emit_int32(LHA_OPCODE | rt(d) | d1(si16) | ra0mem(s1));}
+ inline void Assembler::lhau( Register d, int si16, Register s1) { assert(d != s1, "according to ibm manual"); emit_int32(LHAU_OPCODE | rt(d) | d1(si16) | rta0mem(s1));}
+@@ -308,6 +312,25 @@
+ { emit_int32(MCRF_OPCODE | bf(crd) | bfa(cra)); }
+ inline void Assembler::mtcr( Register s) { Assembler::mtcrf(0xff, s); }
+
++// Special purpose registers
++// Exception Register
++inline void Assembler::mtxer(Register s1) { emit_int32(MTXER_OPCODE | rs(s1)); }
++inline void Assembler::mfxer(Register d ) { emit_int32(MFXER_OPCODE | rt(d)); }
++// Vector Register Save Register
++inline void Assembler::mtvrsave(Register s1) { emit_int32(MTVRSAVE_OPCODE | rs(s1)); }
++inline void Assembler::mfvrsave(Register d ) { emit_int32(MFVRSAVE_OPCODE | rt(d)); }
++// Timebase
++inline void Assembler::mftb(Register d ) { emit_int32(MFTB_OPCODE | rt(d)); }
++// Introduced with Power 8:
++// Data Stream Control Register
++inline void Assembler::mtdscr(Register s1) { emit_int32(MTDSCR_OPCODE | rs(s1)); }
++inline void Assembler::mfdscr(Register d ) { emit_int32(MFDSCR_OPCODE | rt(d)); }
++// Transactional Memory Registers
++inline void Assembler::mftfhar(Register d ) { emit_int32(MFTFHAR_OPCODE | rt(d)); }
++inline void Assembler::mftfiar(Register d ) { emit_int32(MFTFIAR_OPCODE | rt(d)); }
++inline void Assembler::mftexasr(Register d ) { emit_int32(MFTEXASR_OPCODE | rt(d)); }
++inline void Assembler::mftexasru(Register d ) { emit_int32(MFTEXASRU_OPCODE | rt(d)); }
++
+ // SAP JVM 2006-02-13 PPC branch instruction.
+ // PPC 1, section 2.4.1 Branch Instructions
+ inline void Assembler::b( address a, relocInfo::relocType rt) { emit_data(BXX_OPCODE| li(disp( intptr_t(a), intptr_t(pc()))) |aa(0)|lk(0), rt); }
+@@ -731,15 +754,50 @@
+ inline void Assembler::mtvscr( VectorRegister b) { emit_int32( MTVSCR_OPCODE | vrb(b)); }
+ inline void Assembler::mfvscr( VectorRegister d) { emit_int32( MFVSCR_OPCODE | vrt(d)); }
+
++// AES (introduced with Power 8)
++inline void Assembler::vcipher( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VCIPHER_OPCODE | vrt(d) | vra(a) | vrb(b)); }
++inline void Assembler::vcipherlast( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VCIPHERLAST_OPCODE | vrt(d) | vra(a) | vrb(b)); }
++inline void Assembler::vncipher( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VNCIPHER_OPCODE | vrt(d) | vra(a) | vrb(b)); }
++inline void Assembler::vncipherlast(VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VNCIPHERLAST_OPCODE | vrt(d) | vra(a) | vrb(b)); }
++inline void Assembler::vsbox( VectorRegister d, VectorRegister a) { emit_int32( VSBOX_OPCODE | vrt(d) | vra(a) ); }
++
++// SHA (introduced with Power 8)
++// Not yet implemented.
++
++// Vector Binary Polynomial Multiplication (introduced with Power 8)
++inline void Assembler::vpmsumb( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPMSUMB_OPCODE | vrt(d) | vra(a) | vrb(b)); }
++inline void Assembler::vpmsumd( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPMSUMD_OPCODE | vrt(d) | vra(a) | vrb(b)); }
++inline void Assembler::vpmsumh( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPMSUMH_OPCODE | vrt(d) | vra(a) | vrb(b)); }
++inline void Assembler::vpmsumw( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPMSUMW_OPCODE | vrt(d) | vra(a) | vrb(b)); }
++
++// Vector Permute and Xor (introduced with Power 8)
++inline void Assembler::vpermxor( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c) { emit_int32( VPMSUMW_OPCODE | vrt(d) | vra(a) | vrb(b) | vrc(c)); }
++
++// Transactional Memory instructions (introduced with Power 8)
++inline void Assembler::tbegin_() { emit_int32( TBEGIN_OPCODE | rc(1)); }
++inline void Assembler::tbeginrot_() { emit_int32( TBEGIN_OPCODE | /*R=1*/ 1u << (31-10) | rc(1)); }
++inline void Assembler::tend_() { emit_int32( TEND_OPCODE | rc(1)); }
++inline void Assembler::tendall_() { emit_int32( TEND_OPCODE | /*A=1*/ 1u << (31-6) | rc(1)); }
++inline void Assembler::tabort_(Register a) { emit_int32( TABORT_OPCODE | ra(a) | rc(1)); }
++inline void Assembler::tabortwc_(int t, Register a, Register b) { emit_int32( TABORTWC_OPCODE | to(t) | ra(a) | rb(b) | rc(1)); }
++inline void Assembler::tabortwci_(int t, Register a, int si) { emit_int32( TABORTWCI_OPCODE | to(t) | ra(a) | sh1620(si) | rc(1)); }
++inline void Assembler::tabortdc_(int t, Register a, Register b) { emit_int32( TABORTDC_OPCODE | to(t) | ra(a) | rb(b) | rc(1)); }
++inline void Assembler::tabortdci_(int t, Register a, int si) { emit_int32( TABORTDCI_OPCODE | to(t) | ra(a) | sh1620(si) | rc(1)); }
++inline void Assembler::tsuspend_() { emit_int32( TSR_OPCODE | rc(1)); }
++inline void Assembler::tresume_() { emit_int32( TSR_OPCODE | /*L=1*/ 1u << (31-10) | rc(1)); }
++inline void Assembler::tcheck(int f) { emit_int32( TCHECK_OPCODE | bf(f)); }
++
+ // ra0 version
+ inline void Assembler::lwzx( Register d, Register s2) { emit_int32( LWZX_OPCODE | rt(d) | rb(s2));}
+ inline void Assembler::lwz( Register d, int si16 ) { emit_int32( LWZ_OPCODE | rt(d) | d1(si16));}
+ inline void Assembler::lwax( Register d, Register s2) { emit_int32( LWAX_OPCODE | rt(d) | rb(s2));}
+ inline void Assembler::lwa( Register d, int si16 ) { emit_int32( LWA_OPCODE | rt(d) | ds(si16));}
++inline void Assembler::lwbrx(Register d, Register s2) { emit_int32( LWBRX_OPCODE| rt(d) | rb(s2));}
+ inline void Assembler::lhzx( Register d, Register s2) { emit_int32( LHZX_OPCODE | rt(d) | rb(s2));}
+ inline void Assembler::lhz( Register d, int si16 ) { emit_int32( LHZ_OPCODE | rt(d) | d1(si16));}
+ inline void Assembler::lhax( Register d, Register s2) { emit_int32( LHAX_OPCODE | rt(d) | rb(s2));}
+ inline void Assembler::lha( Register d, int si16 ) { emit_int32( LHA_OPCODE | rt(d) | d1(si16));}
++inline void Assembler::lhbrx(Register d, Register s2) { emit_int32( LHBRX_OPCODE| rt(d) | rb(s2));}
+ inline void Assembler::lbzx( Register d, Register s2) { emit_int32( LBZX_OPCODE | rt(d) | rb(s2));}
+ inline void Assembler::lbz( Register d, int si16 ) { emit_int32( LBZ_OPCODE | rt(d) | d1(si16));}
+ inline void Assembler::ld( Register d, int si16 ) { emit_int32( LD_OPCODE | rt(d) | ds(si16));}
+--- ./hotspot/src/cpu/ppc/vm/compiledIC_ppc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/compiledIC_ppc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -50,34 +50,6 @@
+ return is_icholder_entry(call->destination());
+ }
+
+-//-----------------------------------------------------------------------------
+-// High-level access to an inline cache. Guaranteed to be MT-safe.
+-
+-CompiledIC::CompiledIC(nmethod* nm, NativeCall* call)
+- : _ic_call(call)
+-{
+- address ic_call = call->instruction_address();
+-
+- assert(ic_call != NULL, "ic_call address must be set");
+- assert(nm != NULL, "must pass nmethod");
+- assert(nm->contains(ic_call), "must be in nmethod");
+-
+- // Search for the ic_call at the given address.
+- RelocIterator iter(nm, ic_call, ic_call+1);
+- bool ret = iter.next();
+- assert(ret == true, "relocInfo must exist at this address");
+- assert(iter.addr() == ic_call, "must find ic_call");
+- if (iter.type() == relocInfo::virtual_call_type) {
+- virtual_call_Relocation* r = iter.virtual_call_reloc();
+- _is_optimized = false;
+- _value = nativeMovConstReg_at(r->cached_value());
+- } else {
+- assert(iter.type() == relocInfo::opt_virtual_call_type, "must be a virtual call");
+- _is_optimized = true;
+- _value = NULL;
+- }
+-}
+-
+ // ----------------------------------------------------------------------------
+
+ // A PPC CompiledStaticCall looks like this:
+@@ -203,7 +175,7 @@
+ if (TraceICs) {
+ ResourceMark rm;
+ tty->print_cr("CompiledStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
+- instruction_address(),
++ p2i(instruction_address()),
+ callee->name_and_sig_as_C_string());
+ }
+
+--- ./hotspot/src/cpu/ppc/vm/frame_ppc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/frame_ppc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+@@ -140,7 +140,7 @@
+ void frame::patch_pc(Thread* thread, address pc) {
+ if (TracePcPatching) {
+ tty->print_cr("patch_pc at address " PTR_FORMAT " [" PTR_FORMAT " -> " PTR_FORMAT "]",
+- &((address*) _sp)[-1], ((address*) _sp)[-1], pc);
++ p2i(&((address*) _sp)[-1]), p2i(((address*) _sp)[-1]), p2i(pc));
+ }
+ own_abi()->lr = (uint64_t)pc;
+ _cb = CodeCache::find_blob(pc);
+--- ./hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -37,6 +37,8 @@
+ // signatures accordingly.
+ const bool CCallingConventionRequiresIntsAsLongs = true;
+
++#define SUPPORTS_NATIVE_CX8
++
+ // The PPC CPUs are NOT multiple-copy-atomic.
+ #define CPU_NOT_MULTIPLE_COPY_ATOMIC
+
+--- ./hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,7 +25,6 @@
+
+
+ #include "precompiled.hpp"
+-#include "asm/assembler.hpp"
+ #include "asm/macroAssembler.inline.hpp"
+ #include "interp_masm_ppc_64.hpp"
+ #include "interpreter/interpreterRuntime.hpp"
+@@ -119,9 +118,15 @@
+ // Call the Interpreter::remove_activation_preserving_args_entry()
+ // func to get the address of the same-named entrypoint in the
+ // generated interpreter code.
++#if defined(ABI_ELFv2)
++ call_c(CAST_FROM_FN_PTR(address,
++ Interpreter::remove_activation_preserving_args_entry),
++ relocInfo::none);
++#else
+ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*,
+ Interpreter::remove_activation_preserving_args_entry),
+ relocInfo::none);
++#endif
+
+ // Jump to Interpreter::_remove_activation_preserving_args_entry.
+ mtctr(R3_RET);
+@@ -331,29 +336,40 @@
+ void InterpreterMacroAssembler::get_2_byte_integer_at_bcp(int bcp_offset,
+ Register Rdst,
+ signedOrNot is_signed) {
++#if defined(VM_LITTLE_ENDIAN)
++ if (bcp_offset) {
++ load_const_optimized(Rdst, bcp_offset);
++ lhbrx(Rdst, R14_bcp, Rdst);
++ } else {
++ lhbrx(Rdst, R14_bcp);
++ }
++ if (is_signed == Signed) {
++ extsh(Rdst, Rdst);
++ }
++#else
+ // Read Java big endian format.
+ if (is_signed == Signed) {
+ lha(Rdst, bcp_offset, R14_bcp);
+ } else {
+ lhz(Rdst, bcp_offset, R14_bcp);
+ }
+-#if 0
+- assert(Rtmp != Rdst, "need separate temp register");
+- Register Rfirst = Rtmp;
+- lbz(Rfirst, bcp_offset, R14_bcp); // first byte
+- lbz(Rdst, bcp_offset+1, R14_bcp); // second byte
+-
+- // Rdst = ((Rfirst<<8) & 0xFF00) | (Rdst &~ 0xFF00)
+- rldimi(/*RA=*/Rdst, /*RS=*/Rfirst, /*sh=*/8, /*mb=*/48);
+- if (is_signed == Signed) {
+- extsh(Rdst, Rdst);
+- }
+ #endif
+ }
+
+ void InterpreterMacroAssembler::get_4_byte_integer_at_bcp(int bcp_offset,
+ Register Rdst,
+ signedOrNot is_signed) {
++#if defined(VM_LITTLE_ENDIAN)
++ if (bcp_offset) {
++ load_const_optimized(Rdst, bcp_offset);
++ lwbrx(Rdst, R14_bcp, Rdst);
++ } else {
++ lwbrx(Rdst, R14_bcp);
++ }
++ if (is_signed == Signed) {
++ extsw(Rdst, Rdst);
++ }
++#else
+ // Read Java big endian format.
+ if (bcp_offset & 3) { // Offset unaligned?
+ load_const_optimized(Rdst, bcp_offset);
+@@ -369,19 +385,27 @@
+ lwz(Rdst, bcp_offset, R14_bcp);
+ }
+ }
++#endif
+ }
+
++
+ // Load the constant pool cache index from the bytecode stream.
+ //
+ // Kills / writes:
+ // - Rdst, Rscratch
+ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register Rdst, int bcp_offset, size_t index_size) {
+ assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
++ // Cache index is always in the native format, courtesy of Rewriter.
+ if (index_size == sizeof(u2)) {
+- get_2_byte_integer_at_bcp(bcp_offset, Rdst, Unsigned);
++ lhz(Rdst, bcp_offset, R14_bcp);
+ } else if (index_size == sizeof(u4)) {
+ assert(EnableInvokeDynamic, "giant index used only for JSR 292");
+- get_4_byte_integer_at_bcp(bcp_offset, Rdst, Signed);
++ if (bcp_offset & 3) {
++ load_const_optimized(Rdst, bcp_offset);
++ lwax(Rdst, R14_bcp, Rdst);
++ } else {
++ lwa(Rdst, bcp_offset, R14_bcp);
++ }
+ assert(ConstantPool::decode_invokedynamic_index(~123) == 123, "else change next line");
+ nand(Rdst, Rdst, Rdst); // convert to plain index
+ } else if (index_size == sizeof(u1)) {
+@@ -398,6 +422,29 @@
+ add(cache, R27_constPoolCache, cache);
+ }
+
++// Load 4-byte signed or unsigned integer in Java format (that is, big-endian format)
++// from (Rsrc)+offset.
++void InterpreterMacroAssembler::get_u4(Register Rdst, Register Rsrc, int offset,
++ signedOrNot is_signed) {
++#if defined(VM_LITTLE_ENDIAN)
++ if (offset) {
++ load_const_optimized(Rdst, offset);
++ lwbrx(Rdst, Rdst, Rsrc);
++ } else {
++ lwbrx(Rdst, Rsrc);
++ }
++ if (is_signed == Signed) {
++ extsw(Rdst, Rdst);
++ }
++#else
++ if (is_signed == Signed) {
++ lwa(Rdst, offset, Rsrc);
++ } else {
++ lwz(Rdst, offset, Rsrc);
++ }
++#endif
++}
++
+ // Load object from cpool->resolved_references(index).
+ void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result, Register index) {
+ assert_different_registers(result, index);
+@@ -498,6 +545,9 @@
+ cmplw(CCR0, Rindex, Rlength);
+ sldi(RsxtIndex, RsxtIndex, index_shift);
+ blt(CCR0, LnotOOR);
++ // Index should be in R17_tos, array should be in R4_ARG2.
++ mr(R17_tos, Rindex);
++ mr(R4_ARG2, Rarray);
+ load_dispatch_table(Rtmp, (address*)Interpreter::_throw_ArrayIndexOutOfBoundsException_entry);
+ mtctr(Rtmp);
+ bctr();
+@@ -1632,6 +1682,228 @@
+ }
+ }
+
++// Argument and return type profilig.
++// kills: tmp, tmp2, R0, CR0, CR1
++void InterpreterMacroAssembler::profile_obj_type(Register obj, Register mdo_addr_base,
++ RegisterOrConstant mdo_addr_offs, Register tmp, Register tmp2) {
++ Label do_nothing, do_update;
++
++ // tmp2 = obj is allowed
++ assert_different_registers(obj, mdo_addr_base, tmp, R0);
++ assert_different_registers(tmp2, mdo_addr_base, tmp, R0);
++ const Register klass = tmp2;
++
++ verify_oop(obj);
++
++ ld(tmp, mdo_addr_offs, mdo_addr_base);
++
++ // Set null_seen if obj is 0.
++ cmpdi(CCR0, obj, 0);
++ ori(R0, tmp, TypeEntries::null_seen);
++ beq(CCR0, do_update);
++
++ load_klass(klass, obj);
++
++ clrrdi(R0, tmp, exact_log2(-TypeEntries::type_klass_mask));
++ // Basically same as andi(R0, tmp, TypeEntries::type_klass_mask);
++ cmpd(CCR1, R0, klass);
++ // Klass seen before, nothing to do (regardless of unknown bit).
++ //beq(CCR1, do_nothing);
++
++ andi_(R0, klass, TypeEntries::type_unknown);
++ // Already unknown. Nothing to do anymore.
++ //bne(CCR0, do_nothing);
++ crorc(/*CCR0 eq*/2, /*CCR1 eq*/4+2, /*CCR0 eq*/2); // cr0 eq = cr1 eq or cr0 ne
++ beq(CCR0, do_nothing);
++
++ clrrdi_(R0, tmp, exact_log2(-TypeEntries::type_mask));
++ orr(R0, klass, tmp); // Combine klass and null_seen bit (only used if (tmp & type_mask)==0).
++ beq(CCR0, do_update); // First time here. Set profile type.
++
++ // Different than before. Cannot keep accurate profile.
++ ori(R0, tmp, TypeEntries::type_unknown);
++
++ bind(do_update);
++ // update profile
++ std(R0, mdo_addr_offs, mdo_addr_base);
++
++ align(32, 12);
++ bind(do_nothing);
++}
++
++void InterpreterMacroAssembler::profile_arguments_type(Register callee, Register tmp1, Register tmp2, bool is_virtual) {
++ if (!ProfileInterpreter) {
++ return;
++ }
++
++ assert_different_registers(callee, tmp1, tmp2, R28_mdx);
++
++ if (MethodData::profile_arguments() || MethodData::profile_return()) {
++ Label profile_continue;
++
++ test_method_data_pointer(profile_continue);
++
++ int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size());
++
++ lbz(tmp1, in_bytes(DataLayout::tag_offset()) - off_to_start, R28_mdx);
++ cmpwi(CCR0, tmp1, is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag);
++ bne(CCR0, profile_continue);
++
++ if (MethodData::profile_arguments()) {
++ Label done;
++ int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset());
++ add(R28_mdx, off_to_args, R28_mdx);
++
++ for (int i = 0; i < TypeProfileArgsLimit; i++) {
++ if (i > 0 || MethodData::profile_return()) {
++ // If return value type is profiled we may have no argument to profile.
++ ld(tmp1, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args, R28_mdx);
++ cmpdi(CCR0, tmp1, (i+1)*TypeStackSlotEntries::per_arg_count());
++ addi(tmp1, tmp1, -i*TypeStackSlotEntries::per_arg_count());
++ blt(CCR0, done);
++ }
++ ld(tmp1, in_bytes(Method::const_offset()), callee);
++ lhz(tmp1, in_bytes(ConstMethod::size_of_parameters_offset()), tmp1);
++ // Stack offset o (zero based) from the start of the argument
++ // list, for n arguments translates into offset n - o - 1 from
++ // the end of the argument list. But there's an extra slot at
++ // the top of the stack. So the offset is n - o from Lesp.
++ ld(tmp2, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args, R28_mdx);
++ subf(tmp1, tmp2, tmp1);
++
++ sldi(tmp1, tmp1, Interpreter::logStackElementSize);
++ ldx(tmp1, tmp1, R15_esp);
++
++ profile_obj_type(tmp1, R28_mdx, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args, tmp2, tmp1);
++
++ int to_add = in_bytes(TypeStackSlotEntries::per_arg_size());
++ addi(R28_mdx, R28_mdx, to_add);
++ off_to_args += to_add;
++ }
++
++ if (MethodData::profile_return()) {
++ ld(tmp1, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args, R28_mdx);
++ addi(tmp1, tmp1, -TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count());
++ }
++
++ bind(done);
++
++ if (MethodData::profile_return()) {
++ // We're right after the type profile for the last
++ // argument. tmp1 is the number of cells left in the
++ // CallTypeData/VirtualCallTypeData to reach its end. Non null
++ // if there's a return to profile.
++ assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type");
++ sldi(tmp1, tmp1, exact_log2(DataLayout::cell_size));
++ add(R28_mdx, tmp1, R28_mdx);
++ }
++ } else {
++ assert(MethodData::profile_return(), "either profile call args or call ret");
++ update_mdp_by_constant(in_bytes(TypeEntriesAtCall::return_only_size()));
++ }
++
++ // Mdp points right after the end of the
++ // CallTypeData/VirtualCallTypeData, right after the cells for the
++ // return value type if there's one.
++ align(32, 12);
++ bind(profile_continue);
++ }
++}
++
++void InterpreterMacroAssembler::profile_return_type(Register ret, Register tmp1, Register tmp2) {
++ assert_different_registers(ret, tmp1, tmp2);
++ if (ProfileInterpreter && MethodData::profile_return()) {
++ Label profile_continue;
++
++ test_method_data_pointer(profile_continue);
++
++ if (MethodData::profile_return_jsr292_only()) {
++ // If we don't profile all invoke bytecodes we must make sure
++ // it's a bytecode we indeed profile. We can't go back to the
++ // begining of the ProfileData we intend to update to check its
++ // type because we're right after it and we don't known its
++ // length.
++ lbz(tmp1, 0, R14_bcp);
++ lbz(tmp2, Method::intrinsic_id_offset_in_bytes(), R19_method);
++ cmpwi(CCR0, tmp1, Bytecodes::_invokedynamic);
++ cmpwi(CCR1, tmp1, Bytecodes::_invokehandle);
++ cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2);
++ cmpwi(CCR1, tmp2, vmIntrinsics::_compiledLambdaForm);
++ cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2);
++ bne(CCR0, profile_continue);
++ }
++
++ profile_obj_type(ret, R28_mdx, -in_bytes(ReturnTypeEntry::size()), tmp1, tmp2);
++
++ align(32, 12);
++ bind(profile_continue);
++ }
++}
++
++void InterpreterMacroAssembler::profile_parameters_type(Register tmp1, Register tmp2, Register tmp3, Register tmp4) {
++ if (ProfileInterpreter && MethodData::profile_parameters()) {
++ Label profile_continue, done;
++
++ test_method_data_pointer(profile_continue);
++
++ // Load the offset of the area within the MDO used for
++ // parameters. If it's negative we're not profiling any parameters.
++ lwz(tmp1, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset()), R28_mdx);
++ cmpwi(CCR0, tmp1, 0);
++ blt(CCR0, profile_continue);
++
++ // Compute a pointer to the area for parameters from the offset
++ // and move the pointer to the slot for the last
++ // parameters. Collect profiling from last parameter down.
++ // mdo start + parameters offset + array length - 1
++
++ // Pointer to the parameter area in the MDO.
++ const Register mdp = tmp1;
++ add(mdp, tmp1, R28_mdx);
++
++ // Pffset of the current profile entry to update.
++ const Register entry_offset = tmp2;
++ // entry_offset = array len in number of cells
++ ld(entry_offset, in_bytes(ArrayData::array_len_offset()), mdp);
++
++ int off_base = in_bytes(ParametersTypeData::stack_slot_offset(0));
++ assert(off_base % DataLayout::cell_size == 0, "should be a number of cells");
++
++ // entry_offset (number of cells) = array len - size of 1 entry + offset of the stack slot field
++ addi(entry_offset, entry_offset, -TypeStackSlotEntries::per_arg_count() + (off_base / DataLayout::cell_size));
++ // entry_offset in bytes
++ sldi(entry_offset, entry_offset, exact_log2(DataLayout::cell_size));
++
++ Label loop;
++ align(32, 12);
++ bind(loop);
++
++ // Load offset on the stack from the slot for this parameter.
++ ld(tmp3, entry_offset, mdp);
++ sldi(tmp3, tmp3, Interpreter::logStackElementSize);
++ neg(tmp3, tmp3);
++ // Read the parameter from the local area.
++ ldx(tmp3, tmp3, R18_locals);
++
++ // Make entry_offset now point to the type field for this parameter.
++ int type_base = in_bytes(ParametersTypeData::type_offset(0));
++ assert(type_base > off_base, "unexpected");
++ addi(entry_offset, entry_offset, type_base - off_base);
++
++ // Profile the parameter.
++ profile_obj_type(tmp3, mdp, entry_offset, tmp4, tmp3);
++
++ // Go to next parameter.
++ int delta = TypeStackSlotEntries::per_arg_count() * DataLayout::cell_size + (type_base - off_base);
++ cmpdi(CCR0, entry_offset, off_base + delta);
++ addi(entry_offset, entry_offset, -delta);
++ bge(CCR0, loop);
++
++ align(32, 12);
++ bind(profile_continue);
++ }
++}
++
+ // Add a InterpMonitorElem to stack (see frame_sparc.hpp).
+ void InterpreterMacroAssembler::add_monitor_to_stack(bool stack_is_empty, Register Rtemp1, Register Rtemp2) {
+
+@@ -1993,20 +2265,19 @@
+ bne(CCR0, test);
+
+ address fd = CAST_FROM_FN_PTR(address, verify_return_address);
+- unsigned int nbytes_save = 10*8; // 10 volatile gprs
+-
+- save_LR_CR(Rtmp);
++ const int nbytes_save = 11*8; // volatile gprs except R0
++ save_volatile_gprs(R1_SP, -nbytes_save); // except R0
++ save_LR_CR(Rtmp); // Save in old frame.
+ push_frame_reg_args(nbytes_save, Rtmp);
+- save_volatile_gprs(R1_SP, 112); // except R0
+
+ load_const_optimized(Rtmp, fd, R0);
+ mr_if_needed(R4_ARG2, reg);
+ mr(R3_ARG1, R19_method);
+ call_c(Rtmp); // call C
+
+- restore_volatile_gprs(R1_SP, 112); // except R0
+ pop_frame();
+ restore_LR_CR(Rtmp);
++ restore_volatile_gprs(R1_SP, -nbytes_save); // except R0
+ b(skip);
+
+ // Perform a more elaborate out-of-line call.
+--- ./hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -130,6 +130,7 @@
+
+ void get_cache_and_index_at_bcp(Register cache, int bcp_offset, size_t index_size = sizeof(u2));
+
++ void get_u4(Register Rdst, Register Rsrc, int offset, signedOrNot is_signed);
+
+ // common code
+
+@@ -254,6 +255,12 @@
+ void record_klass_in_profile(Register receiver, Register scratch1, Register scratch2, bool is_virtual_call);
+ void record_klass_in_profile_helper(Register receiver, Register scratch1, Register scratch2, int start_row, Label& done, bool is_virtual_call);
+
++ // Argument and return type profiling.
++ void profile_obj_type(Register obj, Register mdo_addr_base, RegisterOrConstant mdo_addr_offs, Register tmp, Register tmp2);
++ void profile_arguments_type(Register callee, Register tmp1, Register tmp2, bool is_virtual);
++ void profile_return_type(Register ret, Register tmp1, Register tmp2);
++ void profile_parameters_type(Register tmp1, Register tmp2, Register tmp3, Register tmp4);
++
+ #endif // !CC_INTERP
+
+ // Debugging
+--- ./hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -24,7 +24,6 @@
+ */
+
+ #include "precompiled.hpp"
+-#include "asm/assembler.hpp"
+ #include "asm/macroAssembler.inline.hpp"
+ #include "interpreter/bytecodeHistogram.hpp"
+ #include "interpreter/interpreter.hpp"
+--- ./hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+@@ -806,6 +806,7 @@
+
+ // For verify_oops.
+ void MacroAssembler::save_volatile_gprs(Register dst, int offset) {
++ std(R2, offset, dst); offset += 8;
+ std(R3, offset, dst); offset += 8;
+ std(R4, offset, dst); offset += 8;
+ std(R5, offset, dst); offset += 8;
+@@ -820,6 +821,7 @@
+
+ // For verify_oops.
+ void MacroAssembler::restore_volatile_gprs(Register src, int offset) {
++ ld(R2, offset, src); offset += 8;
+ ld(R3, offset, src); offset += 8;
+ ld(R4, offset, src); offset += 8;
+ ld(R5, offset, src); offset += 8;
+@@ -1186,6 +1188,16 @@
+ call_VM(oop_result, entry_point, check_exceptions);
+ }
+
++void MacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg_3,
++ bool check_exceptions) {
++ // R3_ARG1 is reserved for the thread
++ mr_if_needed(R4_ARG2, arg_1);
++ assert(arg_2 != R4_ARG2, "smashed argument");
++ mr_if_needed(R5_ARG3, arg_2);
++ mr_if_needed(R6_ARG4, arg_3);
++ call_VM(oop_result, entry_point, check_exceptions);
++}
++
+ void MacroAssembler::call_VM_leaf(address entry_point) {
+ call_VM_leaf_base(entry_point);
+ }
+@@ -2365,7 +2377,7 @@
+ #endif // INCLUDE_ALL_GCS
+
+ // Values for last_Java_pc, and last_Java_sp must comply to the rules
+-// in frame_ppc64.hpp.
++// in frame_ppc.hpp.
+ void MacroAssembler::set_last_Java_frame(Register last_Java_sp, Register last_Java_pc) {
+ // Always set last_Java_pc and flags first because once last_Java_sp
+ // is visible has_last_Java_frame is true and users will look at the
+@@ -2492,6 +2504,7 @@
+ }
+
+ void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
++ assert(dst != R0, "Dst reg may not be R0, as R0 is used here.");
+ if (src == noreg) src = dst;
+ Register shifted_src = src;
+ if (Universe::narrow_klass_shift() != 0 ||
+@@ -2526,14 +2539,11 @@
+
+ void MacroAssembler::reinit_heapbase(Register d, Register tmp) {
+ if (Universe::heap() != NULL) {
+- if (Universe::narrow_oop_base() == NULL) {
+- Assembler::xorr(R30, R30, R30);
+- } else {
+- load_const(R30, Universe::narrow_ptrs_base(), tmp);
+- }
++ load_const_optimized(R30, Universe::narrow_ptrs_base(), tmp);
+ } else {
+- load_const(R30, Universe::narrow_ptrs_base_addr(), tmp);
+- ld(R30, 0, R30);
++ // Heap not yet allocated. Load indirectly.
++ int simm16_offset = load_const_optimized(R30, Universe::narrow_ptrs_base_addr(), tmp, true);
++ ld(R30, simm16_offset, R30);
+ }
+ }
+
+@@ -3060,35 +3070,27 @@
+ if (!VerifyOops) {
+ return;
+ }
+- // Will be preserved.
+- Register tmp = R11;
+- assert(oop != tmp, "precondition");
+- unsigned int nbytes_save = 10*8; // 10 volatile gprs
++
+ address/* FunctionDescriptor** */fd = StubRoutines::verify_oop_subroutine_entry_address();
+- // save tmp
+- mr(R0, tmp);
+- // kill tmp
+- save_LR_CR(tmp);
++ 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
++
++ if (oop == tmp) mr(R4_ARG2, oop);
++ save_LR_CR(tmp); // save in old frame
+ push_frame_reg_args(nbytes_save, tmp);
+- // restore tmp
+- mr(tmp, R0);
+- save_volatile_gprs(R1_SP, 112); // except R0
+ // load FunctionDescriptor** / entry_address *
+- load_const(tmp, fd);
++ load_const_optimized(tmp, fd, R0);
+ // load FunctionDescriptor* / entry_address
+ ld(tmp, 0, tmp);
+- mr(R4_ARG2, oop);
+- load_const(R3_ARG1, (address)msg);
+- // call destination for its side effect
++ if (oop != tmp) mr_if_needed(R4_ARG2, oop);
++ load_const_optimized(R3_ARG1, (address)msg, R0);
++ // Call destination for its side effect.
+ call_c(tmp);
+- restore_volatile_gprs(R1_SP, 112); // except R0
++
+ pop_frame();
+- // save tmp
+- mr(R0, tmp);
+- // kill tmp
+ restore_LR_CR(tmp);
+- // restore tmp
+- mr(tmp, R0);
++ restore_volatile_gprs(R1_SP, -nbytes_save); // except R0
+ }
+
+ const char* stop_types[] = {
+@@ -3099,7 +3101,7 @@
+ };
+
+ static void stop_on_request(int tp, const char* msg) {
+- tty->print("PPC assembly code requires stop: (%s) %s\n", (void *)stop_types[tp%/*stop_end*/4], msg);
++ tty->print("PPC assembly code requires stop: (%s) %s\n", stop_types[tp%/*stop_end*/4], msg);
+ guarantee(false, err_msg("PPC assembly code requires stop: %s", msg));
+ }
+
+--- ./hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -368,6 +368,7 @@
+ void call_VM(Register oop_result, address entry_point, bool check_exceptions = true);
+ void call_VM(Register oop_result, address entry_point, Register arg_1, bool check_exceptions = true);
+ void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true);
++ void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg3, bool check_exceptions = true);
+ void call_VM_leaf(address entry_point);
+ void call_VM_leaf(address entry_point, Register arg_1);
+ void call_VM_leaf(address entry_point, Register arg_1, Register arg_2);
+--- ./hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+@@ -464,7 +464,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, entry_sp);
++ adaptername, mh_reg_name, (intptr_t) mh, (intptr_t) entry_sp);
+
+ if (Verbose) {
+ tty->print_cr("Registers:");
+--- ./hotspot/src/cpu/ppc/vm/nativeInst_ppc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/nativeInst_ppc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,6 +1,6 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+- * Copyright 2012, 2013 SAP AG. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -100,10 +100,7 @@
+ MacroAssembler* a = new MacroAssembler(&cb);
+
+ // Patch the call.
+- if (ReoptimizeCallSequences &&
+- a->is_within_range_of_b(dest, addr_call)) {
+- a->bl(dest);
+- } else {
++ if (!ReoptimizeCallSequences || !a->is_within_range_of_b(dest, addr_call)) {
+ address trampoline_stub_addr = get_trampoline();
+
+ // We did not find a trampoline stub because the current codeblob
+@@ -115,9 +112,12 @@
+
+ // Patch the constant in the call's trampoline stub.
+ NativeCallTrampolineStub_at(trampoline_stub_addr)->set_destination(dest);
++ dest = trampoline_stub_addr;
++ }
+
+- a->bl(trampoline_stub_addr);
+- }
++ OrderAccess::release();
++ a->bl(dest);
++
+ ICache::ppc64_flush_icache_bytes(addr_call, code_size);
+ }
+
+@@ -147,9 +147,9 @@
+ address addr = addr_at(0);
+
+ if (!NativeCall::is_call_at(addr)) {
+- tty->print_cr("not a NativeCall at " PTR_FORMAT, addr);
++ tty->print_cr("not a NativeCall at " PTR_FORMAT, p2i(addr));
+ // TODO: PPC port: Disassembler::decode(addr - 20, addr + 20, tty);
+- fatal(err_msg("not a NativeCall at " PTR_FORMAT, addr));
++ fatal(err_msg("not a NativeCall at " PTR_FORMAT, p2i(addr)));
+ }
+ }
+ #endif // ASSERT
+@@ -160,9 +160,9 @@
+
+ NativeInstruction::verify();
+ if (!NativeFarCall::is_far_call_at(addr)) {
+- tty->print_cr("not a NativeFarCall at " PTR_FORMAT, addr);
++ tty->print_cr("not a NativeFarCall at " PTR_FORMAT, p2i(addr));
+ // TODO: PPC port: Disassembler::decode(addr, 20, 20, tty);
+- fatal(err_msg("not a NativeFarCall at " PTR_FORMAT, addr));
++ fatal(err_msg("not a NativeFarCall at " PTR_FORMAT, p2i(addr)));
+ }
+ }
+ #endif // ASSERT
+@@ -306,9 +306,9 @@
+ if (! (cb != NULL && MacroAssembler::is_calculate_address_from_global_toc_at(addr, cb->content_begin())) &&
+ ! (cb != NULL && MacroAssembler::is_set_narrow_oop(addr, cb->content_begin())) &&
+ ! MacroAssembler::is_bl(*((int*) addr))) {
+- tty->print_cr("not a NativeMovConstReg at " PTR_FORMAT, addr);
++ tty->print_cr("not a NativeMovConstReg at " PTR_FORMAT, p2i(addr));
+ // TODO: PPC port: Disassembler::decode(addr, 20, 20, tty);
+- fatal(err_msg("not a NativeMovConstReg at " PTR_FORMAT, addr));
++ fatal(err_msg("not a NativeMovConstReg at " PTR_FORMAT, p2i(addr)));
+ }
+ }
+ }
+@@ -344,9 +344,9 @@
+
+ NativeInstruction::verify();
+ if (!NativeJump::is_jump_at(addr)) {
+- tty->print_cr("not a NativeJump at " PTR_FORMAT, addr);
++ tty->print_cr("not a NativeJump at " PTR_FORMAT, p2i(addr));
+ // TODO: PPC port: Disassembler::decode(addr, 20, 20, tty);
+- fatal(err_msg("not a NativeJump at " PTR_FORMAT, addr));
++ fatal(err_msg("not a NativeJump at " PTR_FORMAT, p2i(addr)));
+ }
+ }
+ #endif // ASSERT
+--- ./hotspot/src/cpu/ppc/vm/ppc.ad Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/ppc.ad Wed Feb 04 12:14:39 2015 -0800
+@@ -1249,6 +1249,7 @@
+
+ // Emit the trampoline stub which will be related to the branch-and-link below.
+ CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset);
++ if (Compile::current()->env()->failing()) { return offsets; } // Code cache may be full.
+ __ relocate(rtype);
+ }
+
+@@ -1329,7 +1330,7 @@
+
+ if (!false /* TODO: PPC port C->is_frameless_method()*/) {
+ st->print("save return pc\n\t");
+- st->print("push frame %d\n\t", -framesize);
++ st->print("push frame %ld\n\t", -framesize);
+ }
+ }
+ #endif
+@@ -1412,7 +1413,7 @@
+ while (bang_offset <= bang_end) {
+ // Need at least one stack bang at end of shadow zone.
+
+- // Again I had to copy code, this time from assembler_ppc64.cpp,
++ // Again I had to copy code, this time from assembler_ppc.cpp,
+ // bang_stack_with_offset - see there for comments.
+
+ // Stack grows down, caller passes positive offset.
+@@ -1937,8 +1938,9 @@
+ // --------------------------------------------------------------------
+ // Check for hi bits still needing moving. Only happens for misaligned
+ // arguments to native calls.
+- if (src_hi == dst_hi)
++ if (src_hi == dst_hi) {
+ return ppc64Opcode_none; // Self copy; no move.
++ }
+
+ ShouldNotReachHere();
+ return ppc64Opcode_undefined;
+@@ -1960,14 +1962,15 @@
+ }
+
+ uint MachNopNode::size(PhaseRegAlloc *ra_) const {
+- return _count * 4;
++ return _count * 4;
+ }
+
+ #ifndef PRODUCT
+ void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
+ int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
+- int reg = ra_->get_reg_first(this);
+- st->print("ADDI %s, SP, %d \t// box node", Matcher::regName[reg], offset);
++ char reg_str[128];
++ ra_->dump_register(this, reg_str);
++ st->print("ADDI %s, SP, %d \t// box node", reg_str, offset);
+ }
+ #endif
+
+@@ -2002,7 +2005,7 @@
+
+ // Inline_cache contains a klass.
+ Register ic_klass = as_Register(Matcher::inline_cache_reg_encode());
+- Register receiver_klass = R0; // tmp
++ Register receiver_klass = R12_scratch2; // tmp
+
+ assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1);
+ assert(R11_scratch1 == R11, "need prologue scratch register");
+@@ -3486,6 +3489,7 @@
+
+ // Emit the trampoline stub which will be related to the branch-and-link below.
+ CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset);
++ if (Compile::current()->env()->failing()) { return; } // Code cache may be full.
+ __ relocate(_optimized_virtual ?
+ relocInfo::opt_virtual_call_type : relocInfo::static_call_type);
+ }
+@@ -3529,6 +3533,7 @@
+
+ // Emit the trampoline stub which will be related to the branch-and-link below.
+ CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset);
++ if (ra_->C->env()->failing()) { return; } // Code cache may be full.
+ assert(_optimized_virtual, "methodHandle call should be a virtual call");
+ __ relocate(relocInfo::opt_virtual_call_type);
+ }
+@@ -3579,9 +3584,7 @@
+ const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none);
+ const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const);
+ CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset());
+-
+- if (ra_->C->env()->failing())
+- return;
++ if (ra_->C->env()->failing()) { return; } // Code cache may be full.
+
+ // Build relocation at call site with ic position as data.
+ assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) ||
+@@ -5640,19 +5643,6 @@
+ ins_pipe(pipe_class_memory);
+ %}
+
+-//// Load compressed klass and decode it if narrow_klass_shift == 0.
+-//// TODO: will narrow_klass_shift ever be 0?
+-//instruct decodeNKlass2Klass(iRegPdst dst, memory mem) %{
+-// match(Set dst (DecodeNKlass (LoadNKlass mem)));
+-// predicate(false /* TODO: PPC port Universe::narrow_klass_shift() == 0*);
+-// ins_cost(MEMORY_REF_COST);
+-//
+-// format %{ "LWZ $dst, $mem \t// DecodeNKlass (unscaled)" %}
+-// size(4);
+-// ins_encode( enc_lwz(dst, mem) );
+-// ins_pipe(pipe_class_memory);
+-//%}
+-
+ // Load Klass Pointer
+ instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{
+ match(Set dst (LoadKlass mem));
+@@ -6072,11 +6062,15 @@
+ %}
+ %}
+
+-instruct loadConNKlass_hi(iRegNdst dst, immNKlass src) %{
++// We have seen a safepoint between the hi and lo parts, and this node was handled
++// as an oop. Therefore this needs a match rule so that build_oop_map knows this is
++// not a narrow oop.
++instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{
++ match(Set dst src);
+ effect(DEF dst, USE src);
+ ins_cost(DEFAULT_COST);
+
+- format %{ "LIS $dst, $src \t// narrow oop hi" %}
++ format %{ "LIS $dst, $src \t// narrow klass hi" %}
+ size(4);
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_addis);
+@@ -6086,6 +6080,21 @@
+ ins_pipe(pipe_class_default);
+ %}
+
++// As loadConNKlass_hi this must be recognized as narrow klass, not oop!
++instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
++ match(Set dst src1);
++ effect(TEMP src2);
++ ins_cost(DEFAULT_COST);
++
++ format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask
++ size(4);
++ ins_encode %{
++ // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
++ __ clrldi($dst$$Register, $src2$$Register, 0x20);
++ %}
++ ins_pipe(pipe_class_default);
++%}
++
+ // This needs a match rule so that build_oop_map knows this is
+ // not a narrow oop.
+ instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
+@@ -6093,10 +6102,10 @@
+ effect(TEMP src2);
+ ins_cost(DEFAULT_COST);
+
+- format %{ "ADDI $dst, $src1, $src2 \t// narrow oop lo" %}
+- size(4);
+- ins_encode %{
+- // TODO: PPC port $archOpcode(ppc64Opcode_addi);
++ format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %}
++ size(4);
++ ins_encode %{
++ // TODO: PPC port $archOpcode(ppc64Opcode_ori);
+ intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant);
+ assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder");
+ int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant);
+@@ -6127,10 +6136,11 @@
+ MachNode *m2 = m1;
+ if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) {
+ // Value might be 1-extended. Mask out these bits.
+- m2 = new (C) clearMs32bNode();
++ m2 = new (C) loadConNKlass_maskNode();
+ m2->add_req(NULL, m1);
+ m2->_opnds[0] = op_dst;
+- m2->_opnds[1] = op_dst;
++ m2->_opnds[1] = op_src;
++ m2->_opnds[2] = op_dst;
+ ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
+ nodes->push(m2);
+ }
+@@ -6975,7 +6985,7 @@
+ size(4);
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
+- __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32);
++ __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32);
+ %}
+ ins_pipe(pipe_class_default);
+ %}
+--- ./hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -24,7 +24,6 @@
+ */
+
+ #include "precompiled.hpp"
+-#include "asm/assembler.hpp"
+ #include "asm/macroAssembler.inline.hpp"
+ #include "interpreter/interpreter.hpp"
+ #include "nativeInst_ppc.hpp"
+@@ -39,9 +38,6 @@
+ #include "runtime/stubCodeGenerator.hpp"
+ #include "runtime/stubRoutines.hpp"
+ #include "utilities/top.hpp"
+-#ifdef COMPILER2
+-#include "opto/runtime.hpp"
+-#endif
+ #include "runtime/thread.inline.hpp"
+
+ #define __ _masm->
+@@ -216,7 +212,7 @@
+ {
+ BLOCK_COMMENT("Call frame manager or native entry.");
+ // Call frame manager or native entry.
+- Register r_new_arg_entry = R14; // PPC_state;
++ Register r_new_arg_entry = R14;
+ assert_different_registers(r_new_arg_entry, r_top_of_arguments_addr,
+ r_arg_method, r_arg_thread);
+
+--- ./hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -90,7 +90,7 @@
+
+ // Thread will be loaded to R3_ARG1.
+ // Target class oop is in register R5_ARG3 by convention!
+- __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ClassCastException_verbose, R17_tos, R5_ARG3));
++ __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ClassCastException_verbose), R17_tos, R5_ARG3);
+ // Above call must not return here since exception pending.
+ DEBUG_ONLY(__ should_not_reach_here();)
+ return entry;
+@@ -171,12 +171,20 @@
+ // Compiled code destroys templateTableBase, reload.
+ __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R12_scratch2);
+
++ if (state == atos) {
++ __ profile_return_type(R3_RET, R11_scratch1, R12_scratch2);
++ }
++
+ const Register cache = R11_scratch1;
+ const Register size = R12_scratch2;
+ __ get_cache_and_index_at_bcp(cache, 1, index_size);
+
+- // Big Endian (get least significant byte of 64 bit value):
++ // Get least significant byte of 64 bit value:
++#if defined(VM_LITTLE_ENDIAN)
++ __ lbz(size, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()), cache);
++#else
+ __ lbz(size, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()) + 7, cache);
++#endif
+ __ sldi(size, size, Interpreter::logStackElementSize);
+ __ add(R15_esp, R15_esp, size);
+ __ dispatch_next(state, step);
+@@ -857,7 +865,9 @@
+ // Our signature handlers copy required arguments to the C stack
+ // (outgoing C args), R3_ARG1 to R10_ARG8, and FARG1 to FARG13.
+ __ mr(R3_ARG1, R18_locals);
++#if !defined(ABI_ELFv2)
+ __ ld(signature_handler_fd, 0, signature_handler_fd);
++#endif
+
+ __ call_stub(signature_handler_fd);
+
+@@ -1019,8 +1029,13 @@
+ // native result across the call. No oop is present.
+
+ __ mr(R3_ARG1, R16_thread);
++#if defined(ABI_ELFv2)
++ __ call_c(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans),
++ relocInfo::none);
++#else
+ __ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, JavaThread::check_special_condition_for_native_trans),
+ relocInfo::none);
++#endif
+
+ __ bind(sync_check_done);
+
+@@ -1219,6 +1234,10 @@
+ __ li(R0, 1);
+ __ stb(R0, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread);
+ }
++
++ // Argument and return type profiling.
++ __ profile_parameters_type(R3_ARG1, R4_ARG2, R5_ARG3, R6_ARG4);
++
+ // Increment invocation counter and check for overflow.
+ if (inc_counter) {
+ generate_counter_incr(&invocation_counter_overflow, &profile_method, &profile_method_continue);
+@@ -1538,6 +1557,8 @@
+ __ resize_frame_absolute(R12_scratch2, R11_scratch1, R0);
+ if (ProfileInterpreter) {
+ __ set_method_data_pointer_for_bcp();
++ __ ld(R11_scratch1, 0, R1_SP);
++ __ std(R28_mdx, _ijava_state_neg(mdx), R11_scratch1);
+ }
+ #if INCLUDE_JVMTI
+ Label L_done;
+@@ -1549,13 +1570,11 @@
+ // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call.
+ // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL.
+ __ ld(R4_ARG2, 0, R18_locals);
+- __ call_VM(R11_scratch1, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null),
+- R4_ARG2, R19_method, R14_bcp);
+-
+- __ cmpdi(CCR0, R11_scratch1, 0);
++ __ MacroAssembler::call_VM(R4_ARG2, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), R4_ARG2, R19_method, R14_bcp, false);
++ __ restore_interpreter_state(R11_scratch1, /*bcp_and_mdx_only*/ true);
++ __ cmpdi(CCR0, R4_ARG2, 0);
+ __ beq(CCR0, L_done);
+-
+- __ std(R11_scratch1, wordSize, R15_esp);
++ __ std(R4_ARG2, wordSize, R15_esp);
+ __ bind(L_done);
+ #endif // INCLUDE_JVMTI
+ __ dispatch_next(vtos);
+--- ./hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -188,8 +188,12 @@
+ assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
+ assert(load_bc_into_bc_reg, "we use bc_reg as temp");
+ __ get_cache_and_index_at_bcp(Rtemp /* dst = cache */, 1);
+- // Big Endian: ((*(cache+indices))>>((1+byte_no)*8))&0xFF
++ // ((*(cache+indices))>>((1+byte_no)*8))&0xFF:
++#if defined(VM_LITTLE_ENDIAN)
++ __ lbz(Rnew_bc, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + 1 + byte_no, Rtemp);
++#else
+ __ lbz(Rnew_bc, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + 7 - (1 + byte_no), Rtemp);
++#endif
+ __ cmpwi(CCR0, Rnew_bc, 0);
+ __ li(Rnew_bc, (unsigned int)(unsigned char)new_bc);
+ __ beq(CCR0, L_patch_done);
+@@ -348,7 +352,6 @@
+ __ sldi(Rscratch1, Rscratch1, LogBytesPerWord);
+ __ cmpdi(CCR0, Rscratch2, JVM_CONSTANT_Integer);
+ __ bne(CCR0, notInt);
+- __ isync(); // Order load of constant wrt. tags.
+ __ lwax(R17_tos, Rcpool, Rscratch1);
+ __ push(itos);
+ __ b(exit);
+@@ -360,7 +363,6 @@
+ __ cmpdi(CCR0, Rscratch2, JVM_CONSTANT_Float);
+ __ asm_assert_eq("unexpected type", 0x8765);
+ #endif
+- __ isync(); // Order load of constant wrt. tags.
+ __ lfsx(F15_ftos, Rcpool, Rscratch1);
+ __ push(ftos);
+
+@@ -419,13 +421,11 @@
+ // Check out Conversions.java for an example.
+ // Also ConstantPool::header_size() is 20, which makes it very difficult
+ // to double-align double on the constant pool. SG, 11/7/97
+- __ isync(); // Order load of constant wrt. tags.
+ __ lfdx(F15_ftos, Rcpool, Rindex);
+ __ push(dtos);
+ __ b(Lexit);
+
+ __ bind(Llong);
+- __ isync(); // Order load of constant wrt. tags.
+ __ ldx(R17_tos, Rcpool, Rindex);
+ __ push(ltos);
+
+@@ -1838,8 +1838,8 @@
+ __ clrrdi(Rdef_offset_addr, Rdef_offset_addr, log2_long((jlong)BytesPerInt));
+
+ // Load lo & hi.
+- __ lwz(Rlow_byte, BytesPerInt, Rdef_offset_addr);
+- __ lwz(Rhigh_byte, BytesPerInt * 2, Rdef_offset_addr);
++ __ get_u4(Rlow_byte, Rdef_offset_addr, BytesPerInt, InterpreterMacroAssembler::Unsigned);
++ __ get_u4(Rhigh_byte, Rdef_offset_addr, 2 *BytesPerInt, InterpreterMacroAssembler::Unsigned);
+
+ // Check for default case (=index outside [low,high]).
+ __ cmpw(CCR0, R17_tos, Rlow_byte);
+@@ -1853,12 +1853,17 @@
+ __ profile_switch_case(Rindex, Rhigh_byte /* scratch */, Rscratch1, Rscratch2);
+ __ sldi(Rindex, Rindex, LogBytesPerInt);
+ __ addi(Rindex, Rindex, 3 * BytesPerInt);
++#if defined(VM_LITTLE_ENDIAN)
++ __ lwbrx(Roffset, Rdef_offset_addr, Rindex);
++ __ extsw(Roffset, Roffset);
++#else
+ __ lwax(Roffset, Rdef_offset_addr, Rindex);
++#endif
+ __ b(Ldispatch);
+
+ __ bind(Ldefault_case);
+ __ profile_switch_default(Rhigh_byte, Rscratch1);
+- __ lwa(Roffset, 0, Rdef_offset_addr);
++ __ get_u4(Roffset, Rdef_offset_addr, 0, InterpreterMacroAssembler::Signed);
+
+ __ bind(Ldispatch);
+
+@@ -1874,12 +1879,11 @@
+ // Table switch using linear search through cases.
+ // Bytecode stream format:
+ // Bytecode (1) | 4-byte padding | default offset (4) | count (4) | value/offset pair1 (8) | value/offset pair2 (8) | ...
+-// Note: Everything is big-endian format here. So on little endian machines, we have to revers offset and count and cmp value.
++// Note: Everything is big-endian format here.
+ void TemplateTable::fast_linearswitch() {
+ transition(itos, vtos);
+
+- Label Lloop_entry, Lsearch_loop, Lfound, Lcontinue_execution, Ldefault_case;
+-
++ Label Lloop_entry, Lsearch_loop, Lcontinue_execution, Ldefault_case;
+ Register Rcount = R3_ARG1,
+ Rcurrent_pair = R4_ARG2,
+ Rdef_offset_addr = R5_ARG3, // Is going to contain address of default offset.
+@@ -1893,47 +1897,40 @@
+ __ clrrdi(Rdef_offset_addr, Rdef_offset_addr, log2_long((jlong)BytesPerInt));
+
+ // Setup loop counter and limit.
+- __ lwz(Rcount, BytesPerInt, Rdef_offset_addr); // Load count.
++ __ get_u4(Rcount, Rdef_offset_addr, BytesPerInt, InterpreterMacroAssembler::Unsigned);
+ __ addi(Rcurrent_pair, Rdef_offset_addr, 2 * BytesPerInt); // Rcurrent_pair now points to first pair.
+
+- // Set up search loop.
++ __ mtctr(Rcount);
+ __ cmpwi(CCR0, Rcount, 0);
+- __ beq(CCR0, Ldefault_case);
+-
+- __ mtctr(Rcount);
+-
+- // linear table search
+- __ bind(Lsearch_loop);
+-
+- __ lwz(Rvalue, 0, Rcurrent_pair);
+- __ lwa(Roffset, 1 * BytesPerInt, Rcurrent_pair);
+-
+- __ cmpw(CCR0, Rvalue, Rcmp_value);
+- __ beq(CCR0, Lfound);
+-
+- __ addi(Rcurrent_pair, Rcurrent_pair, 2 * BytesPerInt);
+- __ bdnz(Lsearch_loop);
+-
+- // default case
++ __ bne(CCR0, Lloop_entry);
++
++ // Default case
+ __ bind(Ldefault_case);
+-
+- __ lwa(Roffset, 0, Rdef_offset_addr);
++ __ get_u4(Roffset, Rdef_offset_addr, 0, InterpreterMacroAssembler::Signed);
+ if (ProfileInterpreter) {
+ __ profile_switch_default(Rdef_offset_addr, Rcount/* scratch */);
+- __ b(Lcontinue_execution);
+ }
+-
+- // Entry found, skip Roffset bytecodes and continue.
+- __ bind(Lfound);
++ __ b(Lcontinue_execution);
++
++ // Next iteration
++ __ bind(Lsearch_loop);
++ __ bdz(Ldefault_case);
++ __ addi(Rcurrent_pair, Rcurrent_pair, 2 * BytesPerInt);
++ __ bind(Lloop_entry);
++ __ get_u4(Rvalue, Rcurrent_pair, 0, InterpreterMacroAssembler::Unsigned);
++ __ cmpw(CCR0, Rvalue, Rcmp_value);
++ __ bne(CCR0, Lsearch_loop);
++
++ // Found, load offset.
++ __ get_u4(Roffset, Rcurrent_pair, BytesPerInt, InterpreterMacroAssembler::Signed);
++ // Calculate case index and profile
++ __ mfctr(Rcurrent_pair);
+ if (ProfileInterpreter) {
+- // Calc the num of the pair we hit. Careful, Rcurrent_pair points 2 ints
+- // beyond the actual current pair due to the auto update load above!
+- __ sub(Rcurrent_pair, Rcurrent_pair, Rdef_offset_addr);
+- __ addi(Rcurrent_pair, Rcurrent_pair, - 2 * BytesPerInt);
+- __ srdi(Rcurrent_pair, Rcurrent_pair, LogBytesPerInt + 1);
++ __ sub(Rcurrent_pair, Rcount, Rcurrent_pair);
+ __ profile_switch_case(Rcurrent_pair, Rcount /*scratch*/, Rdef_offset_addr/*scratch*/, Rscratch);
+- __ bind(Lcontinue_execution);
+ }
++
++ __ bind(Lcontinue_execution);
+ __ add(R14_bcp, Roffset, R14_bcp);
+ __ dispatch_next(vtos);
+ }
+@@ -1989,7 +1986,7 @@
+
+ // initialize i & j
+ __ li(Ri,0);
+- __ lwz(Rj, -BytesPerInt, Rarray);
++ __ get_u4(Rj, Rarray, -BytesPerInt, InterpreterMacroAssembler::Unsigned);
+
+ // and start.
+ Label entry;
+@@ -2006,7 +2003,11 @@
+ // i = h;
+ // }
+ __ sldi(Rscratch, Rh, log_entry_size);
++#if defined(VM_LITTLE_ENDIAN)
++ __ lwbrx(Rscratch, Rscratch, Rarray);
++#else
+ __ lwzx(Rscratch, Rscratch, Rarray);
++#endif
+
+ // if (key < current value)
+ // Rh = Rj
+@@ -2038,20 +2039,20 @@
+ // Ri = value offset
+ __ sldi(Ri, Ri, log_entry_size);
+ __ add(Ri, Ri, Rarray);
+- __ lwz(Rscratch, 0, Ri);
++ __ get_u4(Rscratch, Ri, 0, InterpreterMacroAssembler::Unsigned);
+
+ Label not_found;
+ // Ri = offset offset
+ __ cmpw(CCR0, Rkey, Rscratch);
+ __ beq(CCR0, not_found);
+ // entry not found -> j = default offset
+- __ lwz(Rj, -2 * BytesPerInt, Rarray);
++ __ get_u4(Rj, Rarray, -2 * BytesPerInt, InterpreterMacroAssembler::Unsigned);
+ __ b(default_case);
+
+ __ bind(not_found);
+ // entry found -> j = offset
+ __ profile_switch_case(Rh, Rj, Rscratch, Rkey);
+- __ lwz(Rj, BytesPerInt, Ri);
++ __ get_u4(Rj, Ri, BytesPerInt, InterpreterMacroAssembler::Unsigned);
+
+ if (ProfileInterpreter) {
+ __ b(continue_execution);
+@@ -2146,8 +2147,11 @@
+
+ assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
+ // We are resolved if the indices offset contains the current bytecode.
+- // Big Endian:
++#if defined(VM_LITTLE_ENDIAN)
++ __ lbz(Rscratch, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + byte_no + 1, Rcache);
++#else
+ __ lbz(Rscratch, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + 7 - (byte_no + 1), Rcache);
++#endif
+ // Acquire by cmp-br-isync (see below).
+ __ cmpdi(CCR0, Rscratch, (int)bytecode());
+ __ beq(CCR0, Lresolved);
+@@ -3230,6 +3234,8 @@
+ // Load target.
+ __ addi(Rrecv_klass, Rrecv_klass, base + vtableEntry::method_offset_in_bytes());
+ __ ldx(Rtarget_method, Rindex, Rrecv_klass);
++ // Argument and return type profiling.
++ __ profile_arguments_type(Rtarget_method, Rrecv_klass /* scratch1 */, Rtemp /* scratch2 */, true);
+ __ call_from_interpreter(Rtarget_method, Rret, Rrecv_klass /* scratch1 */, Rtemp /* scratch2 */);
+ }
+
+@@ -3313,6 +3319,8 @@
+ __ null_check_throw(Rrecv, -1, Rscratch1);
+
+ __ profile_final_call(Rrecv, Rscratch1);
++ // Argument and return type profiling.
++ __ profile_arguments_type(Rmethod, Rscratch1, Rscratch2, true);
+
+ // Do the call.
+ __ call_from_interpreter(Rmethod, Rret_addr, Rscratch1, Rscratch2);
+@@ -3334,6 +3342,8 @@
+ __ null_check_throw(Rreceiver, -1, R11_scratch1);
+
+ __ profile_call(R11_scratch1, R12_scratch2);
++ // Argument and return type profiling.
++ __ profile_arguments_type(Rmethod, R11_scratch1, R12_scratch2, false);
+ __ call_from_interpreter(Rmethod, Rret_addr, R11_scratch1, R12_scratch2);
+ }
+
+@@ -3348,6 +3358,8 @@
+ prepare_invoke(byte_no, R19_method, Rret_addr, noreg, noreg, Rflags, R11_scratch1);
+
+ __ profile_call(R11_scratch1, R12_scratch2);
++ // Argument and return type profiling.
++ __ profile_arguments_type(R19_method, R11_scratch1, R12_scratch2, false);
+ __ call_from_interpreter(R19_method, Rret_addr, R11_scratch1, R12_scratch2);
+ }
+
+@@ -3369,6 +3381,8 @@
+
+ // Final call case.
+ __ profile_final_call(Rtemp1, Rscratch);
++ // Argument and return type profiling.
++ __ profile_arguments_type(Rindex, Rscratch, Rrecv_klass /* scratch */, true);
+ // Do the final call - the index (f2) contains the method.
+ __ call_from_interpreter(Rindex, Rret, Rscratch, Rrecv_klass /* scratch */);
+
+@@ -3420,6 +3434,8 @@
+ __ cmpdi(CCR0, Rindex, 0);
+ __ beq(CCR0, Lthrow_ame);
+ // Found entry. Jump off!
++ // Argument and return type profiling.
++ __ profile_arguments_type(Rindex, Rscratch1, Rscratch2, true);
+ __ call_from_interpreter(Rindex, Rret_addr, Rscratch1, Rscratch2);
+
+ // Vtable entry was NULL => Throw abstract method error.
+@@ -3473,6 +3489,8 @@
+ // to be the callsite object the bootstrap method returned. This is passed to a
+ // "link" method which does the dispatch (Most likely just grabs the MH stored
+ // inside the callsite and does an invokehandle).
++ // Argument and return type profiling.
++ __ profile_arguments_type(Rmethod, Rscratch1, Rscratch2, false);
+ __ call_from_interpreter(Rmethod, Rret_addr, Rscratch1 /* scratch1 */, Rscratch2 /* scratch2 */);
+ }
+
+@@ -3499,6 +3517,8 @@
+ __ profile_final_call(Rrecv, Rscratch1);
+
+ // Still no call from handle => We call the method handle interpreter here.
++ // Argument and return type profiling.
++ __ profile_arguments_type(Rmethod, Rscratch1, Rscratch2, true);
+ __ call_from_interpreter(Rmethod, Rret_addr, Rscratch1 /* scratch1 */, Rscratch2 /* scratch2 */);
+ }
+
+--- ./hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -139,13 +139,44 @@
+ }
+
+ assert(AllocatePrefetchLines > 0, "invalid value");
+- if (AllocatePrefetchLines < 1) // Set valid value in product VM.
++ if (AllocatePrefetchLines < 1) { // Set valid value in product VM.
+ AllocatePrefetchLines = 1; // Conservative value.
++ }
+
+- if (AllocatePrefetchStyle == 3 && AllocatePrefetchDistance < cache_line_size)
++ if (AllocatePrefetchStyle == 3 && AllocatePrefetchDistance < cache_line_size) {
+ AllocatePrefetchStyle = 1; // Fall back if inappropriate.
++ }
+
+ assert(AllocatePrefetchStyle >= 0, "AllocatePrefetchStyle should be positive");
++
++ if (UseCRC32Intrinsics) {
++ if (!FLAG_IS_DEFAULT(UseCRC32Intrinsics))
++ warning("CRC32 intrinsics are not available on this CPU");
++ FLAG_SET_DEFAULT(UseCRC32Intrinsics, false);
++ }
++
++ // The AES intrinsic stubs require AES instruction support.
++ if (UseAES) {
++ warning("AES instructions are not available on this CPU");
++ FLAG_SET_DEFAULT(UseAES, false);
++ }
++ if (UseAESIntrinsics) {
++ if (!FLAG_IS_DEFAULT(UseAESIntrinsics))
++ warning("AES intrinsics are not available on this CPU");
++ FLAG_SET_DEFAULT(UseAESIntrinsics, false);
++ }
++
++ if (UseSHA) {
++ warning("SHA instructions are not available on this CPU");
++ FLAG_SET_DEFAULT(UseSHA, false);
++ }
++ if (UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics) {
++ warning("SHA intrinsics are not available on this CPU");
++ FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
++ FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
++ FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
++ }
++
+ }
+
+ void VM_Version::print_features() {
+@@ -352,7 +383,7 @@
+
+ if (PrintAssembly) {
+ ttyLocker ttyl;
+- tty->print_cr("Decoding section size detection stub at " INTPTR_FORMAT " before execution:", code);
++ tty->print_cr("Decoding section size detection stub at " INTPTR_FORMAT " before execution:", p2i(code));
+ Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
+ tty->print_cr("Time loop1 :%f", loop1_seconds);
+ tty->print_cr("Time loop2 :%f", loop2_seconds);
+@@ -435,7 +466,7 @@
+ // Print the detection code.
+ if (PrintAssembly) {
+ ttyLocker ttyl;
+- tty->print_cr("Decoding cpu-feature detection stub at " INTPTR_FORMAT " before execution:", code);
++ tty->print_cr("Decoding cpu-feature detection stub at " INTPTR_FORMAT " before execution:", p2i(code));
+ Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
+ }
+
+@@ -468,7 +499,7 @@
+ // Print the detection code.
+ if (PrintAssembly) {
+ ttyLocker ttyl;
+- tty->print_cr("Decoding cpu-feature detection stub at " INTPTR_FORMAT " after execution:", code);
++ tty->print_cr("Decoding cpu-feature detection stub at " INTPTR_FORMAT " after execution:", p2i(code));
+ Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
+ }
+
+--- ./hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -123,6 +123,7 @@
+ fpop2_op3 = 0x35,
+ impdep1_op3 = 0x36,
+ aes3_op3 = 0x36,
++ sha_op3 = 0x36,
+ alignaddr_op3 = 0x36,
+ faligndata_op3 = 0x36,
+ flog3_op3 = 0x36,
+@@ -223,7 +224,11 @@
+ mwtos_opf = 0x119,
+
+ aes_kexpand0_opf = 0x130,
+- aes_kexpand2_opf = 0x131
++ aes_kexpand2_opf = 0x131,
++
++ sha1_opf = 0x141,
++ sha256_opf = 0x142,
++ sha512_opf = 0x143
+ };
+
+ enum op5s {
+@@ -595,6 +600,11 @@
+ // AES crypto instructions supported only on certain processors
+ static void aes_only() { assert( VM_Version::has_aes(), "This instruction only works on SPARC with AES instructions support"); }
+
++ // SHA crypto instructions supported only on certain processors
++ static void sha1_only() { assert( VM_Version::has_sha1(), "This instruction only works on SPARC with SHA1"); }
++ static void sha256_only() { assert( VM_Version::has_sha256(), "This instruction only works on SPARC with SHA256"); }
++ static void sha512_only() { assert( VM_Version::has_sha512(), "This instruction only works on SPARC with SHA512"); }
++
+ // instruction only in VIS1
+ static void vis1_only() { assert( VM_Version::has_vis1(), "This instruction only works on SPARC with VIS1"); }
+
+@@ -1179,7 +1189,6 @@
+ u_field(3, 29, 25) | immed(true) | simm(simm13a, 13)); }
+ inline void wrfprs( Register d) { v9_only(); emit_int32( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(6, 29, 25)); }
+
+-
+ // VIS1 instructions
+
+ void alignaddr( Register s1, Register s2, Register d ) { vis1_only(); emit_int32( op(arith_op) | rd(d) | op3(alignaddr_op3) | rs1(s1) | opf(alignaddr_opf) | rs2(s2)); }
+@@ -1203,6 +1212,12 @@
+ void movwtos( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(mftoi_op3) | opf(mwtos_opf) | rs2(s)); }
+ void movxtod( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(mftoi_op3) | opf(mxtod_opf) | rs2(s)); }
+
++ // Crypto SHA instructions
++
++ void sha1() { sha1_only(); emit_int32( op(arith_op) | op3(sha_op3) | opf(sha1_opf)); }
++ void sha256() { sha256_only(); emit_int32( op(arith_op) | op3(sha_op3) | opf(sha256_opf)); }
++ void sha512() { sha512_only(); emit_int32( op(arith_op) | op3(sha_op3) | opf(sha512_opf)); }
++
+ // Creation
+ Assembler(CodeBuffer* code) : AbstractAssembler(code) {
+ #ifdef CHECK_DELAY
+--- ./hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -872,21 +872,19 @@
+
+
+ void LIRGenerator::do_NewInstance(NewInstance* x) {
++ print_if_not_loaded(x);
++
+ // This instruction can be deoptimized in the slow path : use
+ // O0 as result register.
+ const LIR_Opr reg = result_register_for(x->type());
+-#ifndef PRODUCT
+- if (PrintNotLoaded && !x->klass()->is_loaded()) {
+- tty->print_cr(" ###class not loaded at new bci %d", x->printable_bci());
+- }
+-#endif
++
+ CodeEmitInfo* info = state_for(x, x->state());
+ LIR_Opr tmp1 = FrameMap::G1_oop_opr;
+ LIR_Opr tmp2 = FrameMap::G3_oop_opr;
+ LIR_Opr tmp3 = FrameMap::G4_oop_opr;
+ LIR_Opr tmp4 = FrameMap::O1_oop_opr;
+ LIR_Opr klass_reg = FrameMap::G5_metadata_opr;
+- new_instance(reg, x->klass(), tmp1, tmp2, tmp3, tmp4, klass_reg, info);
++ new_instance(reg, x->klass(), x->is_unresolved(), tmp1, tmp2, tmp3, tmp4, klass_reg, info);
+ LIR_Opr result = rlock_result(x);
+ __ move(reg, result);
+ }
+--- ./hotspot/src/cpu/sparc/vm/compiledIC_sparc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/sparc/vm/compiledIC_sparc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -50,34 +50,6 @@
+ return is_icholder_entry(call->destination());
+ }
+
+-//-----------------------------------------------------------------------------
+-// High-level access to an inline cache. Guaranteed to be MT-safe.
+-
+-CompiledIC::CompiledIC(nmethod* nm, NativeCall* call)
+- : _ic_call(call)
+-{
+- address ic_call = call->instruction_address();
+-
+- assert(ic_call != NULL, "ic_call address must be set");
+- assert(nm != NULL, "must pass nmethod");
+- assert(nm->contains(ic_call), "must be in nmethod");
+-
+- // Search for the ic_call at the given address.
+- RelocIterator iter(nm, ic_call, ic_call+1);
+- bool ret = iter.next();
+- assert(ret == true, "relocInfo must exist at this address");
+- assert(iter.addr() == ic_call, "must find ic_call");
+- if (iter.type() == relocInfo::virtual_call_type) {
+- virtual_call_Relocation* r = iter.virtual_call_reloc();
+- _is_optimized = false;
+- _value = nativeMovConstReg_at(r->cached_value());
+- } else {
+- assert(iter.type() == relocInfo::opt_virtual_call_type, "must be a virtual call");
+- _is_optimized = true;
+- _value = NULL;
+- }
+-}
+-
+ // ----------------------------------------------------------------------------
+
+ #define __ _masm.
+--- ./hotspot/src/cpu/sparc/vm/sparc.ad Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/sparc/vm/sparc.ad Wed Feb 04 12:14:39 2015 -0800
+@@ -6184,7 +6184,11 @@
+ ins_cost(DEFAULT_COST * 3/2);
+ format %{ "SET $con,$dst\t! non-oop ptr" %}
+ ins_encode %{
+- __ set($con$$constant, $dst$$Register);
++ if (_opnds[1]->constant_reloc() == relocInfo::metadata_type) {
++ __ set_metadata_constant((Metadata*)$con$$constant, $dst$$Register);
++ } else {
++ __ set($con$$constant, $dst$$Register);
++ }
+ %}
+ ins_pipe(loadConP);
+ %}
+--- ./hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -4575,6 +4575,219 @@
+ return start;
+ }
+
++ address generate_sha1_implCompress(bool multi_block, const char *name) {
++ __ align(CodeEntryAlignment);
++ StubCodeMark mark(this, "StubRoutines", name);
++ address start = __ pc();
++
++ Label L_sha1_loop, L_sha1_unaligned_input, L_sha1_unaligned_input_loop;
++ int i;
++
++ Register buf = O0; // byte[] source+offset
++ Register state = O1; // int[] SHA.state
++ Register ofs = O2; // int offset
++ Register limit = O3; // int limit
++
++ // load state into F0-F4
++ for (i = 0; i < 5; i++) {
++ __ ldf(FloatRegisterImpl::S, state, i*4, as_FloatRegister(i));
++ }
++
++ __ andcc(buf, 7, G0);
++ __ br(Assembler::notZero, false, Assembler::pn, L_sha1_unaligned_input);
++ __ delayed()->nop();
++
++ __ BIND(L_sha1_loop);
++ // load buf into F8-F22
++ for (i = 0; i < 8; i++) {
++ __ ldf(FloatRegisterImpl::D, buf, i*8, as_FloatRegister(i*2 + 8));
++ }
++ __ sha1();
++ if (multi_block) {
++ __ add(ofs, 64, ofs);
++ __ add(buf, 64, buf);
++ __ cmp_and_brx_short(ofs, limit, Assembler::lessEqual, Assembler::pt, L_sha1_loop);
++ __ mov(ofs, O0); // to be returned
++ }
++
++ // store F0-F4 into state and return
++ for (i = 0; i < 4; i++) {
++ __ stf(FloatRegisterImpl::S, as_FloatRegister(i), state, i*4);
++ }
++ __ retl();
++ __ delayed()->stf(FloatRegisterImpl::S, F4, state, 0x10);
++
++ __ BIND(L_sha1_unaligned_input);
++ __ alignaddr(buf, G0, buf);
++
++ __ BIND(L_sha1_unaligned_input_loop);
++ // load buf into F8-F22
++ for (i = 0; i < 9; i++) {
++ __ ldf(FloatRegisterImpl::D, buf, i*8, as_FloatRegister(i*2 + 8));
++ }
++ for (i = 0; i < 8; i++) {
++ __ faligndata(as_FloatRegister(i*2 + 8), as_FloatRegister(i*2 + 10), as_FloatRegister(i*2 + 8));
++ }
++ __ sha1();
++ if (multi_block) {
++ __ add(ofs, 64, ofs);
++ __ add(buf, 64, buf);
++ __ cmp_and_brx_short(ofs, limit, Assembler::lessEqual, Assembler::pt, L_sha1_unaligned_input_loop);
++ __ mov(ofs, O0); // to be returned
++ }
++
++ // store F0-F4 into state and return
++ for (i = 0; i < 4; i++) {
++ __ stf(FloatRegisterImpl::S, as_FloatRegister(i), state, i*4);
++ }
++ __ retl();
++ __ delayed()->stf(FloatRegisterImpl::S, F4, state, 0x10);
++
++ return start;
++ }
++
++ address generate_sha256_implCompress(bool multi_block, const char *name) {
++ __ align(CodeEntryAlignment);
++ StubCodeMark mark(this, "StubRoutines", name);
++ address start = __ pc();
++
++ Label L_sha256_loop, L_sha256_unaligned_input, L_sha256_unaligned_input_loop;
++ int i;
++
++ Register buf = O0; // byte[] source+offset
++ Register state = O1; // int[] SHA2.state
++ Register ofs = O2; // int offset
++ Register limit = O3; // int limit
++
++ // load state into F0-F7
++ for (i = 0; i < 8; i++) {
++ __ ldf(FloatRegisterImpl::S, state, i*4, as_FloatRegister(i));
++ }
++
++ __ andcc(buf, 7, G0);
++ __ br(Assembler::notZero, false, Assembler::pn, L_sha256_unaligned_input);
++ __ delayed()->nop();
++
++ __ BIND(L_sha256_loop);
++ // load buf into F8-F22
++ for (i = 0; i < 8; i++) {
++ __ ldf(FloatRegisterImpl::D, buf, i*8, as_FloatRegister(i*2 + 8));
++ }
++ __ sha256();
++ if (multi_block) {
++ __ add(ofs, 64, ofs);
++ __ add(buf, 64, buf);
++ __ cmp_and_brx_short(ofs, limit, Assembler::lessEqual, Assembler::pt, L_sha256_loop);
++ __ mov(ofs, O0); // to be returned
++ }
++
++ // store F0-F7 into state and return
++ for (i = 0; i < 7; i++) {
++ __ stf(FloatRegisterImpl::S, as_FloatRegister(i), state, i*4);
++ }
++ __ retl();
++ __ delayed()->stf(FloatRegisterImpl::S, F7, state, 0x1c);
++
++ __ BIND(L_sha256_unaligned_input);
++ __ alignaddr(buf, G0, buf);
++
++ __ BIND(L_sha256_unaligned_input_loop);
++ // load buf into F8-F22
++ for (i = 0; i < 9; i++) {
++ __ ldf(FloatRegisterImpl::D, buf, i*8, as_FloatRegister(i*2 + 8));
++ }
++ for (i = 0; i < 8; i++) {
++ __ faligndata(as_FloatRegister(i*2 + 8), as_FloatRegister(i*2 + 10), as_FloatRegister(i*2 + 8));
++ }
++ __ sha256();
++ if (multi_block) {
++ __ add(ofs, 64, ofs);
++ __ add(buf, 64, buf);
++ __ cmp_and_brx_short(ofs, limit, Assembler::lessEqual, Assembler::pt, L_sha256_unaligned_input_loop);
++ __ mov(ofs, O0); // to be returned
++ }
++
++ // store F0-F7 into state and return
++ for (i = 0; i < 7; i++) {
++ __ stf(FloatRegisterImpl::S, as_FloatRegister(i), state, i*4);
++ }
++ __ retl();
++ __ delayed()->stf(FloatRegisterImpl::S, F7, state, 0x1c);
++
++ return start;
++ }
++
++ address generate_sha512_implCompress(bool multi_block, const char *name) {
++ __ align(CodeEntryAlignment);
++ StubCodeMark mark(this, "StubRoutines", name);
++ address start = __ pc();
++
++ Label L_sha512_loop, L_sha512_unaligned_input, L_sha512_unaligned_input_loop;
++ int i;
++
++ Register buf = O0; // byte[] source+offset
++ Register state = O1; // long[] SHA5.state
++ Register ofs = O2; // int offset
++ Register limit = O3; // int limit
++
++ // load state into F0-F14
++ for (i = 0; i < 8; i++) {
++ __ ldf(FloatRegisterImpl::D, state, i*8, as_FloatRegister(i*2));
++ }
++
++ __ andcc(buf, 7, G0);
++ __ br(Assembler::notZero, false, Assembler::pn, L_sha512_unaligned_input);
++ __ delayed()->nop();
++
++ __ BIND(L_sha512_loop);
++ // load buf into F16-F46
++ for (i = 0; i < 16; i++) {
++ __ ldf(FloatRegisterImpl::D, buf, i*8, as_FloatRegister(i*2 + 16));
++ }
++ __ sha512();
++ if (multi_block) {
++ __ add(ofs, 128, ofs);
++ __ add(buf, 128, buf);
++ __ cmp_and_brx_short(ofs, limit, Assembler::lessEqual, Assembler::pt, L_sha512_loop);
++ __ mov(ofs, O0); // to be returned
++ }
++
++ // store F0-F14 into state and return
++ for (i = 0; i < 7; i++) {
++ __ stf(FloatRegisterImpl::D, as_FloatRegister(i*2), state, i*8);
++ }
++ __ retl();
++ __ delayed()->stf(FloatRegisterImpl::D, F14, state, 0x38);
++
++ __ BIND(L_sha512_unaligned_input);
++ __ alignaddr(buf, G0, buf);
++
++ __ BIND(L_sha512_unaligned_input_loop);
++ // load buf into F16-F46
++ for (i = 0; i < 17; i++) {
++ __ ldf(FloatRegisterImpl::D, buf, i*8, as_FloatRegister(i*2 + 16));
++ }
++ for (i = 0; i < 16; i++) {
++ __ faligndata(as_FloatRegister(i*2 + 16), as_FloatRegister(i*2 + 18), as_FloatRegister(i*2 + 16));
++ }
++ __ sha512();
++ if (multi_block) {
++ __ add(ofs, 128, ofs);
++ __ add(buf, 128, buf);
++ __ cmp_and_brx_short(ofs, limit, Assembler::lessEqual, Assembler::pt, L_sha512_unaligned_input_loop);
++ __ mov(ofs, O0); // to be returned
++ }
++
++ // store F0-F14 into state and return
++ for (i = 0; i < 7; i++) {
++ __ stf(FloatRegisterImpl::D, as_FloatRegister(i*2), state, i*8);
++ }
++ __ retl();
++ __ delayed()->stf(FloatRegisterImpl::D, F14, state, 0x38);
++
++ return start;
++ }
++
+ void generate_initial() {
+ // Generates all stubs and initializes the entry points
+
+@@ -4647,6 +4860,20 @@
+ StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt();
+ StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel();
+ }
++
++ // generate SHA1/SHA256/SHA512 intrinsics code
++ if (UseSHA1Intrinsics) {
++ StubRoutines::_sha1_implCompress = generate_sha1_implCompress(false, "sha1_implCompress");
++ StubRoutines::_sha1_implCompressMB = generate_sha1_implCompress(true, "sha1_implCompressMB");
++ }
++ if (UseSHA256Intrinsics) {
++ StubRoutines::_sha256_implCompress = generate_sha256_implCompress(false, "sha256_implCompress");
++ StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(true, "sha256_implCompressMB");
++ }
++ if (UseSHA512Intrinsics) {
++ StubRoutines::_sha512_implCompress = generate_sha512_implCompress(false, "sha512_implCompress");
++ StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(true, "sha512_implCompressMB");
++ }
+ }
+
+
+--- ./hotspot/src/cpu/sparc/vm/stubRoutines_sparc.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/sparc/vm/stubRoutines_sparc.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -41,7 +41,7 @@
+ enum /* platform_dependent_constants */ {
+ // %%%%%%%% May be able to shrink this a lot
+ code_size1 = 20000, // simply increase if too small (assembler will crash if too small)
+- code_size2 = 22000 // simply increase if too small (assembler will crash if too small)
++ code_size2 = 23000 // simply increase if too small (assembler will crash if too small)
+ };
+
+ class Sparc {
+--- ./hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -37,6 +37,7 @@
+
+ int VM_Version::_features = VM_Version::unknown_m;
+ const char* VM_Version::_features_str = "";
++unsigned int VM_Version::_L2_cache_line_size = 0;
+
+ void VM_Version::initialize() {
+ _features = determine_features();
+@@ -197,7 +198,7 @@
+ }
+
+ assert(BlockZeroingLowLimit > 0, "invalid value");
+- if (has_block_zeroing()) {
++ if (has_block_zeroing() && cache_line_size > 0) {
+ if (FLAG_IS_DEFAULT(UseBlockZeroing)) {
+ FLAG_SET_DEFAULT(UseBlockZeroing, true);
+ }
+@@ -207,7 +208,7 @@
+ }
+
+ assert(BlockCopyLowLimit > 0, "invalid value");
+- if (has_block_zeroing()) { // has_blk_init() && is_T4(): core's local L2 cache
++ if (has_block_zeroing() && cache_line_size > 0) { // has_blk_init() && is_T4(): core's local L2 cache
+ if (FLAG_IS_DEFAULT(UseBlockCopy)) {
+ FLAG_SET_DEFAULT(UseBlockCopy, true);
+ }
+@@ -234,7 +235,7 @@
+ assert((OptoLoopAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size");
+
+ char buf[512];
+- jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
++ jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ (has_v9() ? ", v9" : (has_v8() ? ", v8" : "")),
+ (has_hardware_popc() ? ", popc" : ""),
+ (has_vis1() ? ", vis1" : ""),
+@@ -243,6 +244,9 @@
+ (has_blk_init() ? ", blk_init" : ""),
+ (has_cbcond() ? ", cbcond" : ""),
+ (has_aes() ? ", aes" : ""),
++ (has_sha1() ? ", sha1" : ""),
++ (has_sha256() ? ", sha256" : ""),
++ (has_sha512() ? ", sha512" : ""),
+ (is_ultra3() ? ", ultra3" : ""),
+ (is_sun4v() ? ", sun4v" : ""),
+ (is_niagara_plus() ? ", niagara_plus" : (is_niagara() ? ", niagara" : "")),
+@@ -301,12 +305,65 @@
+ }
+ }
+
++ // SHA1, SHA256, and SHA512 instructions were added to SPARC T-series at different times
++ if (has_sha1() || has_sha256() || has_sha512()) {
++ if (UseVIS > 0) { // SHA intrinsics use VIS1 instructions
++ if (FLAG_IS_DEFAULT(UseSHA)) {
++ FLAG_SET_DEFAULT(UseSHA, true);
++ }
++ } else {
++ if (UseSHA) {
++ warning("SPARC SHA intrinsics require VIS1 instruction support. Intrinsics will be disabled.");
++ FLAG_SET_DEFAULT(UseSHA, false);
++ }
++ }
++ } else if (UseSHA) {
++ warning("SHA instructions are not available on this CPU");
++ FLAG_SET_DEFAULT(UseSHA, false);
++ }
++
++ if (!UseSHA) {
++ FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
++ FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
++ FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
++ } else {
++ if (has_sha1()) {
++ if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
++ FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
++ }
++ } else if (UseSHA1Intrinsics) {
++ warning("SHA1 instruction is not available on this CPU.");
++ FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
++ }
++ if (has_sha256()) {
++ if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
++ FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
++ }
++ } else if (UseSHA256Intrinsics) {
++ warning("SHA256 instruction (for SHA-224 and SHA-256) is not available on this CPU.");
++ FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
++ }
++
++ if (has_sha512()) {
++ if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
++ FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
++ }
++ } else if (UseSHA512Intrinsics) {
++ warning("SHA512 instruction (for SHA-384 and SHA-512) is not available on this CPU.");
++ FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
++ }
++ if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) {
++ FLAG_SET_DEFAULT(UseSHA, false);
++ }
++ }
++
+ if (FLAG_IS_DEFAULT(ContendedPaddingWidth) &&
+ (cache_line_size > ContendedPaddingWidth))
+ ContendedPaddingWidth = cache_line_size;
+
+ #ifndef PRODUCT
+ if (PrintMiscellaneous && Verbose) {
++ tty->print_cr("L2 cache line size: %u", L2_cache_line_size());
+ tty->print("Allocation");
+ if (AllocatePrefetchStyle <= 0) {
+ tty->print_cr(": no prefetching");
+--- ./hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -50,7 +50,10 @@
+ T_family = 16,
+ T1_model = 17,
+ sparc5_instructions = 18,
+- aes_instructions = 19
++ aes_instructions = 19,
++ sha1_instruction = 20,
++ sha256_instruction = 21,
++ sha512_instruction = 22
+ };
+
+ enum Feature_Flag_Set {
+@@ -77,6 +80,9 @@
+ T1_model_m = 1 << T1_model,
+ sparc5_instructions_m = 1 << sparc5_instructions,
+ aes_instructions_m = 1 << aes_instructions,
++ sha1_instruction_m = 1 << sha1_instruction,
++ sha256_instruction_m = 1 << sha256_instruction,
++ sha512_instruction_m = 1 << sha512_instruction,
+
+ generic_v8_m = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m,
+ generic_v9_m = generic_v8_m | v9_instructions_m,
+@@ -90,6 +96,9 @@
+ static int _features;
+ static const char* _features_str;
+
++ static unsigned int _L2_cache_line_size;
++ static unsigned int L2_cache_line_size() { return _L2_cache_line_size; }
++
+ static void print_features();
+ static int determine_features();
+ static int platform_features(int features);
+@@ -129,6 +138,9 @@
+ static bool has_cbcond() { return (_features & cbcond_instructions_m) != 0; }
+ static bool has_sparc5_instr() { return (_features & sparc5_instructions_m) != 0; }
+ static bool has_aes() { return (_features & aes_instructions_m) != 0; }
++ static bool has_sha1() { return (_features & sha1_instruction_m) != 0; }
++ static bool has_sha256() { return (_features & sha256_instruction_m) != 0; }
++ static bool has_sha512() { return (_features & sha512_instruction_m) != 0; }
+
+ static bool supports_compare_and_exchange()
+ { return has_v9(); }
+@@ -158,9 +170,8 @@
+
+ static const char* cpu_features() { return _features_str; }
+
+- static intx prefetch_data_size() {
+- return is_T4() && !is_T7() ? 32 : 64; // default prefetch block size on sparc
+- }
++ // default prefetch block size on sparc
++ static intx prefetch_data_size() { return L2_cache_line_size(); }
+
+ // Prefetch
+ static intx prefetch_copy_interval_in_bytes() {
+--- ./hotspot/src/cpu/x86/vm/assembler_x86.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -3854,6 +3854,15 @@
+ }
+
+ // Carry-Less Multiplication Quadword
++void Assembler::pclmulqdq(XMMRegister dst, XMMRegister src, int mask) {
++ assert(VM_Version::supports_clmul(), "");
++ int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A);
++ emit_int8(0x44);
++ emit_int8((unsigned char)(0xC0 | encode));
++ emit_int8((unsigned char)mask);
++}
++
++// Carry-Less Multiplication Quadword
+ void Assembler::vpclmulqdq(XMMRegister dst, XMMRegister nds, XMMRegister src, int mask) {
+ assert(VM_Version::supports_avx() && VM_Version::supports_clmul(), "");
+ bool vector256 = false;
+@@ -4928,6 +4937,26 @@
+ emit_arith(0x03, 0xC0, dst, src);
+ }
+
++void Assembler::adcxq(Register dst, Register src) {
++ //assert(VM_Version::supports_adx(), "adx instructions not supported");
++ emit_int8((unsigned char)0x66);
++ int encode = prefixq_and_encode(dst->encoding(), src->encoding());
++ emit_int8(0x0F);
++ emit_int8(0x38);
++ emit_int8((unsigned char)0xF6);
++ emit_int8((unsigned char)(0xC0 | encode));
++}
++
++void Assembler::adoxq(Register dst, Register src) {
++ //assert(VM_Version::supports_adx(), "adx instructions not supported");
++ emit_int8((unsigned char)0xF3);
++ int encode = prefixq_and_encode(dst->encoding(), src->encoding());
++ emit_int8(0x0F);
++ emit_int8(0x38);
++ emit_int8((unsigned char)0xF6);
++ emit_int8((unsigned char)(0xC0 | encode));
++}
++
+ void Assembler::andq(Address dst, int32_t imm32) {
+ InstructionMark im(this);
+ prefixq(dst);
+@@ -5435,6 +5464,26 @@
+ emit_int8((unsigned char)(0xC0 | encode));
+ }
+
++void Assembler::mulq(Address src) {
++ InstructionMark im(this);
++ prefixq(src);
++ emit_int8((unsigned char)0xF7);
++ emit_operand(rsp, src);
++}
++
++void Assembler::mulq(Register src) {
++ int encode = prefixq_and_encode(src->encoding());
++ emit_int8((unsigned char)0xF7);
++ emit_int8((unsigned char)(0xE0 | encode));
++}
++
++void Assembler::mulxq(Register dst1, Register dst2, Register src) {
++ assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
++ int encode = vex_prefix_and_encode(dst1->encoding(), dst2->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38, true, false);
++ emit_int8((unsigned char)0xF6);
++ emit_int8((unsigned char)(0xC0 | encode));
++}
++
+ void Assembler::negq(Register dst) {
+ int encode = prefixq_and_encode(dst->encoding());
+ emit_int8((unsigned char)0xF7);
+@@ -5563,6 +5612,28 @@
+ emit_int8(imm8);
+ }
+ }
++
++void Assembler::rorq(Register dst, int imm8) {
++ assert(isShiftCount(imm8 >> 1), "illegal shift count");
++ int encode = prefixq_and_encode(dst->encoding());
++ if (imm8 == 1) {
++ emit_int8((unsigned char)0xD1);
++ emit_int8((unsigned char)(0xC8 | encode));
++ } else {
++ emit_int8((unsigned char)0xC1);
++ emit_int8((unsigned char)(0xc8 | encode));
++ emit_int8(imm8);
++ }
++}
++
++void Assembler::rorxq(Register dst, Register src, int imm8) {
++ assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
++ int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_3A, true, false);
++ emit_int8((unsigned char)0xF0);
++ emit_int8((unsigned char)(0xC0 | encode));
++ emit_int8(imm8);
++}
++
+ void Assembler::sarq(Register dst, int imm8) {
+ assert(isShiftCount(imm8 >> 1), "illegal shift count");
+ int encode = prefixq_and_encode(dst->encoding());
+--- ./hotspot/src/cpu/x86/vm/assembler_x86.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/x86/vm/assembler_x86.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -888,6 +888,14 @@
+ void addq(Register dst, Address src);
+ void addq(Register dst, Register src);
+
++#ifdef _LP64
++ //Add Unsigned Integers with Carry Flag
++ void adcxq(Register dst, Register src);
++
++ //Add Unsigned Integers with Overflow Flag
++ void adoxq(Register dst, Register src);
++#endif
++
+ void addr_nop_4();
+ void addr_nop_5();
+ void addr_nop_7();
+@@ -1204,19 +1212,20 @@
+ void idivl(Register src);
+ void divl(Register src); // Unsigned division
+
++#ifdef _LP64
+ void idivq(Register src);
++#endif
+
+ void imull(Register dst, Register src);
+ void imull(Register dst, Register src, int value);
+ void imull(Register dst, Address src);
+
++#ifdef _LP64
+ void imulq(Register dst, Register src);
+ void imulq(Register dst, Register src, int value);
+-#ifdef _LP64
+ void imulq(Register dst, Address src);
+ #endif
+
+-
+ // jcc is the generic conditional branch generator to run-
+ // time routines, jcc is used for branches to labels. jcc
+ // takes a branch opcode (cc) and a label (L) and generates
+@@ -1408,9 +1417,16 @@
+ void movzwq(Register dst, Register src);
+ #endif
+
++ // Unsigned multiply with RAX destination register
+ void mull(Address src);
+ void mull(Register src);
+
++#ifdef _LP64
++ void mulq(Address src);
++ void mulq(Register src);
++ void mulxq(Register dst1, Register dst2, Register src);
++#endif
++
+ // Multiply Scalar Double-Precision Floating-Point Values
+ void mulsd(XMMRegister dst, Address src);
+ void mulsd(XMMRegister dst, XMMRegister src);
+@@ -1541,6 +1557,11 @@
+
+ void ret(int imm16);
+
++#ifdef _LP64
++ void rorq(Register dst, int imm8);
++ void rorxq(Register dst, Register src, int imm8);
++#endif
++
+ void sahf();
+
+ void sarl(Register dst, int imm8);
+@@ -1837,6 +1858,7 @@
+ void vpbroadcastd(XMMRegister dst, XMMRegister src);
+
+ // Carry-Less Multiplication Quadword
++ void pclmulqdq(XMMRegister dst, XMMRegister src, int mask);
+ void vpclmulqdq(XMMRegister dst, XMMRegister nds, XMMRegister src, int mask);
+
+ // AVX instruction which is used to clear upper 128 bits of YMM registers and
+--- ./hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1085,14 +1085,11 @@
+
+
+ void LIRGenerator::do_NewInstance(NewInstance* x) {
+-#ifndef PRODUCT
+- if (PrintNotLoaded && !x->klass()->is_loaded()) {
+- tty->print_cr(" ###class not loaded at new bci %d", x->printable_bci());
+- }
+-#endif
++ print_if_not_loaded(x);
++
+ CodeEmitInfo* info = state_for(x, x->state());
+ LIR_Opr reg = result_register_for(x->type());
+- new_instance(reg, x->klass(),
++ new_instance(reg, x->klass(), x->is_unresolved(),
+ FrameMap::rcx_oop_opr,
+ FrameMap::rdi_oop_opr,
+ FrameMap::rsi_oop_opr,
+--- ./hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -675,7 +675,7 @@
+ case handle_exception_nofpu_id:
+ case handle_exception_id:
+ // At this point all registers MAY be live.
+- oop_map = save_live_registers(sasm, 1 /*thread*/, id == handle_exception_nofpu_id);
++ oop_map = save_live_registers(sasm, 1 /*thread*/, id != handle_exception_nofpu_id);
+ break;
+ case handle_exception_from_callee_id: {
+ // At this point all registers except exception oop (RAX) and
+@@ -748,7 +748,7 @@
+ case handle_exception_nofpu_id:
+ case handle_exception_id:
+ // Restore the registers that were saved at the beginning.
+- restore_live_registers(sasm, id == handle_exception_nofpu_id);
++ restore_live_registers(sasm, id != handle_exception_nofpu_id);
+ break;
+ case handle_exception_from_callee_id:
+ // WIN64_ONLY: No need to add frame::arg_reg_save_area_bytes to SP
+--- ./hotspot/src/cpu/x86/vm/compiledIC_x86.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/x86/vm/compiledIC_x86.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -47,34 +47,6 @@
+ return is_icholder_entry(call->destination());
+ }
+
+-//-----------------------------------------------------------------------------
+-// High-level access to an inline cache. Guaranteed to be MT-safe.
+-
+-CompiledIC::CompiledIC(nmethod* nm, NativeCall* call)
+- : _ic_call(call)
+-{
+- address ic_call = call->instruction_address();
+-
+- assert(ic_call != NULL, "ic_call address must be set");
+- assert(nm != NULL, "must pass nmethod");
+- assert(nm->contains(ic_call), "must be in nmethod");
+-
+- // Search for the ic_call at the given address.
+- RelocIterator iter(nm, ic_call, ic_call+1);
+- bool ret = iter.next();
+- assert(ret == true, "relocInfo must exist at this address");
+- assert(iter.addr() == ic_call, "must find ic_call");
+- if (iter.type() == relocInfo::virtual_call_type) {
+- virtual_call_Relocation* r = iter.virtual_call_reloc();
+- _is_optimized = false;
+- _value = nativeMovConstReg_at(r->cached_value());
+- } else {
+- assert(iter.type() == relocInfo::opt_virtual_call_type, "must be a virtual call");
+- _is_optimized = true;
+- _value = NULL;
+- }
+-}
+-
+ // ----------------------------------------------------------------------------
+
+ #define __ _masm.
+--- ./hotspot/src/cpu/x86/vm/globals_x86.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/x86/vm/globals_x86.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -130,16 +130,16 @@
+ "Use fast-string operation for zeroing: rep stosb") \
+ \
+ /* Use Restricted Transactional Memory for lock eliding */ \
+- experimental(bool, UseRTMLocking, false, \
++ product(bool, UseRTMLocking, false, \
+ "Enable RTM lock eliding for inflated locks in compiled code") \
+ \
+ experimental(bool, UseRTMForStackLocks, false, \
+ "Enable RTM lock eliding for stack locks in compiled code") \
+ \
+- experimental(bool, UseRTMDeopt, false, \
++ product(bool, UseRTMDeopt, false, \
+ "Perform deopt and recompilation based on RTM abort ratio") \
+ \
+- experimental(uintx, RTMRetryCount, 5, \
++ product(uintx, RTMRetryCount, 5, \
+ "Number of RTM retries on lock abort or busy") \
+ \
+ experimental(intx, RTMSpinLoopCount, 100, \
+@@ -176,6 +176,8 @@
+ "Use count trailing zeros instruction") \
+ \
+ product(bool, UseBMI1Instructions, false, \
+- "Use BMI instructions")
+-
++ "Use BMI1 instructions") \
++ \
++ product(bool, UseBMI2Instructions, false, \
++ "Use BMI2 instructions")
+ #endif // CPU_X86_VM_GLOBALS_X86_HPP
+--- ./hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1769,7 +1769,7 @@
+ // at [FETCH], below, will never observe a biased encoding (*101b).
+ // If this invariant is not held we risk exclusion (safety) failure.
+ if (UseBiasedLocking && !UseOptoBiasInlining) {
+- biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, counters);
++ biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, counters);
+ }
+
+ #if INCLUDE_RTM_OPT
+@@ -7293,6 +7293,467 @@
+ bind(L_done);
+ }
+
++#ifdef _LP64
++/**
++ * Helper for multiply_to_len().
++ */
++void MacroAssembler::add2_with_carry(Register dest_hi, Register dest_lo, Register src1, Register src2) {
++ addq(dest_lo, src1);
++ adcq(dest_hi, 0);
++ addq(dest_lo, src2);
++ adcq(dest_hi, 0);
++}
++
++/**
++ * Multiply 64 bit by 64 bit first loop.
++ */
++void MacroAssembler::multiply_64_x_64_loop(Register x, Register xstart, Register x_xstart,
++ Register y, Register y_idx, Register z,
++ Register carry, Register product,
++ Register idx, Register kdx) {
++ //
++ // jlong carry, x[], y[], z[];
++ // for (int idx=ystart, kdx=ystart+1+xstart; idx >= 0; idx-, kdx--) {
++ // huge_128 product = y[idx] * x[xstart] + carry;
++ // z[kdx] = (jlong)product;
++ // carry = (jlong)(product >>> 64);
++ // }
++ // z[xstart] = carry;
++ //
++
++ Label L_first_loop, L_first_loop_exit;
++ Label L_one_x, L_one_y, L_multiply;
++
++ decrementl(xstart);
++ jcc(Assembler::negative, L_one_x);
++
++ movq(x_xstart, Address(x, xstart, Address::times_4, 0));
++ rorq(x_xstart, 32); // convert big-endian to little-endian
++
++ bind(L_first_loop);
++ decrementl(idx);
++ jcc(Assembler::negative, L_first_loop_exit);
++ decrementl(idx);
++ jcc(Assembler::negative, L_one_y);
++ movq(y_idx, Address(y, idx, Address::times_4, 0));
++ rorq(y_idx, 32); // convert big-endian to little-endian
++ bind(L_multiply);
++ movq(product, x_xstart);
++ mulq(y_idx); // product(rax) * y_idx -> rdx:rax
++ addq(product, carry);
++ adcq(rdx, 0);
++ subl(kdx, 2);
++ movl(Address(z, kdx, Address::times_4, 4), product);
++ shrq(product, 32);
++ movl(Address(z, kdx, Address::times_4, 0), product);
++ movq(carry, rdx);
++ jmp(L_first_loop);
++
++ bind(L_one_y);
++ movl(y_idx, Address(y, 0));
++ jmp(L_multiply);
++
++ bind(L_one_x);
++ movl(x_xstart, Address(x, 0));
++ jmp(L_first_loop);
++
++ bind(L_first_loop_exit);
++}
++
++/**
++ * Multiply 64 bit by 64 bit and add 128 bit.
++ */
++void MacroAssembler::multiply_add_128_x_128(Register x_xstart, Register y, Register z,
++ Register yz_idx, Register idx,
++ Register carry, Register product, int offset) {
++ // huge_128 product = (y[idx] * x_xstart) + z[kdx] + carry;
++ // z[kdx] = (jlong)product;
++
++ movq(yz_idx, Address(y, idx, Address::times_4, offset));
++ rorq(yz_idx, 32); // convert big-endian to little-endian
++ movq(product, x_xstart);
++ mulq(yz_idx); // product(rax) * yz_idx -> rdx:product(rax)
++ movq(yz_idx, Address(z, idx, Address::times_4, offset));
++ rorq(yz_idx, 32); // convert big-endian to little-endian
++
++ add2_with_carry(rdx, product, carry, yz_idx);
++
++ movl(Address(z, idx, Address::times_4, offset+4), product);
++ shrq(product, 32);
++ movl(Address(z, idx, Address::times_4, offset), product);
++
++}
++
++/**
++ * Multiply 128 bit by 128 bit. Unrolled inner loop.
++ */
++void MacroAssembler::multiply_128_x_128_loop(Register x_xstart, Register y, Register z,
++ Register yz_idx, Register idx, Register jdx,
++ Register carry, Register product,
++ Register carry2) {
++ // jlong carry, x[], y[], z[];
++ // int kdx = ystart+1;
++ // for (int idx=ystart-2; idx >= 0; idx -= 2) { // Third loop
++ // huge_128 product = (y[idx+1] * x_xstart) + z[kdx+idx+1] + carry;
++ // z[kdx+idx+1] = (jlong)product;
++ // jlong carry2 = (jlong)(product >>> 64);
++ // product = (y[idx] * x_xstart) + z[kdx+idx] + carry2;
++ // z[kdx+idx] = (jlong)product;
++ // carry = (jlong)(product >>> 64);
++ // }
++ // idx += 2;
++ // if (idx > 0) {
++ // product = (y[idx] * x_xstart) + z[kdx+idx] + carry;
++ // z[kdx+idx] = (jlong)product;
++ // carry = (jlong)(product >>> 64);
++ // }
++ //
++
++ Label L_third_loop, L_third_loop_exit, L_post_third_loop_done;
++
++ movl(jdx, idx);
++ andl(jdx, 0xFFFFFFFC);
++ shrl(jdx, 2);
++
++ bind(L_third_loop);
++ subl(jdx, 1);
++ jcc(Assembler::negative, L_third_loop_exit);
++ subl(idx, 4);
++
++ multiply_add_128_x_128(x_xstart, y, z, yz_idx, idx, carry, product, 8);
++ movq(carry2, rdx);
++
++ multiply_add_128_x_128(x_xstart, y, z, yz_idx, idx, carry2, product, 0);
++ movq(carry, rdx);
++ jmp(L_third_loop);
++
++ bind (L_third_loop_exit);
++
++ andl (idx, 0x3);
++ jcc(Assembler::zero, L_post_third_loop_done);
++
++ Label L_check_1;
++ subl(idx, 2);
++ jcc(Assembler::negative, L_check_1);
++
++ multiply_add_128_x_128(x_xstart, y, z, yz_idx, idx, carry, product, 0);
++ movq(carry, rdx);
++
++ bind (L_check_1);
++ addl (idx, 0x2);
++ andl (idx, 0x1);
++ subl(idx, 1);
++ jcc(Assembler::negative, L_post_third_loop_done);
++
++ movl(yz_idx, Address(y, idx, Address::times_4, 0));
++ movq(product, x_xstart);
++ mulq(yz_idx); // product(rax) * yz_idx -> rdx:product(rax)
++ movl(yz_idx, Address(z, idx, Address::times_4, 0));
++
++ add2_with_carry(rdx, product, yz_idx, carry);
++
++ movl(Address(z, idx, Address::times_4, 0), product);
++ shrq(product, 32);
++
++ shlq(rdx, 32);
++ orq(product, rdx);
++ movq(carry, product);
++
++ bind(L_post_third_loop_done);
++}
++
++/**
++ * Multiply 128 bit by 128 bit using BMI2. Unrolled inner loop.
++ *
++ */
++void MacroAssembler::multiply_128_x_128_bmi2_loop(Register y, Register z,
++ Register carry, Register carry2,
++ Register idx, Register jdx,
++ Register yz_idx1, Register yz_idx2,
++ Register tmp, Register tmp3, Register tmp4) {
++ assert(UseBMI2Instructions, "should be used only when BMI2 is available");
++
++ // jlong carry, x[], y[], z[];
++ // int kdx = ystart+1;
++ // for (int idx=ystart-2; idx >= 0; idx -= 2) { // Third loop
++ // huge_128 tmp3 = (y[idx+1] * rdx) + z[kdx+idx+1] + carry;
++ // jlong carry2 = (jlong)(tmp3 >>> 64);
++ // huge_128 tmp4 = (y[idx] * rdx) + z[kdx+idx] + carry2;
++ // carry = (jlong)(tmp4 >>> 64);
++ // z[kdx+idx+1] = (jlong)tmp3;
++ // z[kdx+idx] = (jlong)tmp4;
++ // }
++ // idx += 2;
++ // if (idx > 0) {
++ // yz_idx1 = (y[idx] * rdx) + z[kdx+idx] + carry;
++ // z[kdx+idx] = (jlong)yz_idx1;
++ // carry = (jlong)(yz_idx1 >>> 64);
++ // }
++ //
++
++ Label L_third_loop, L_third_loop_exit, L_post_third_loop_done;
++
++ movl(jdx, idx);
++ andl(jdx, 0xFFFFFFFC);
++ shrl(jdx, 2);
++
++ bind(L_third_loop);
++ subl(jdx, 1);
++ jcc(Assembler::negative, L_third_loop_exit);
++ subl(idx, 4);
++
++ movq(yz_idx1, Address(y, idx, Address::times_4, 8));
++ rorxq(yz_idx1, yz_idx1, 32); // convert big-endian to little-endian
++ movq(yz_idx2, Address(y, idx, Address::times_4, 0));
++ rorxq(yz_idx2, yz_idx2, 32);
++
++ mulxq(tmp4, tmp3, yz_idx1); // yz_idx1 * rdx -> tmp4:tmp3
++ mulxq(carry2, tmp, yz_idx2); // yz_idx2 * rdx -> carry2:tmp
++
++ movq(yz_idx1, Address(z, idx, Address::times_4, 8));
++ rorxq(yz_idx1, yz_idx1, 32);
++ movq(yz_idx2, Address(z, idx, Address::times_4, 0));
++ rorxq(yz_idx2, yz_idx2, 32);
++
++ if (VM_Version::supports_adx()) {
++ adcxq(tmp3, carry);
++ adoxq(tmp3, yz_idx1);
++
++ adcxq(tmp4, tmp);
++ adoxq(tmp4, yz_idx2);
++
++ movl(carry, 0); // does not affect flags
++ adcxq(carry2, carry);
++ adoxq(carry2, carry);
++ } else {
++ add2_with_carry(tmp4, tmp3, carry, yz_idx1);
++ add2_with_carry(carry2, tmp4, tmp, yz_idx2);
++ }
++ movq(carry, carry2);
++
++ movl(Address(z, idx, Address::times_4, 12), tmp3);
++ shrq(tmp3, 32);
++ movl(Address(z, idx, Address::times_4, 8), tmp3);
++
++ movl(Address(z, idx, Address::times_4, 4), tmp4);
++ shrq(tmp4, 32);
++ movl(Address(z, idx, Address::times_4, 0), tmp4);
++
++ jmp(L_third_loop);
++
++ bind (L_third_loop_exit);
++
++ andl (idx, 0x3);
++ jcc(Assembler::zero, L_post_third_loop_done);
++
++ Label L_check_1;
++ subl(idx, 2);
++ jcc(Assembler::negative, L_check_1);
++
++ movq(yz_idx1, Address(y, idx, Address::times_4, 0));
++ rorxq(yz_idx1, yz_idx1, 32);
++ mulxq(tmp4, tmp3, yz_idx1); // yz_idx1 * rdx -> tmp4:tmp3
++ movq(yz_idx2, Address(z, idx, Address::times_4, 0));
++ rorxq(yz_idx2, yz_idx2, 32);
++
++ add2_with_carry(tmp4, tmp3, carry, yz_idx2);
++
++ movl(Address(z, idx, Address::times_4, 4), tmp3);
++ shrq(tmp3, 32);
++ movl(Address(z, idx, Address::times_4, 0), tmp3);
++ movq(carry, tmp4);
++
++ bind (L_check_1);
++ addl (idx, 0x2);
++ andl (idx, 0x1);
++ subl(idx, 1);
++ jcc(Assembler::negative, L_post_third_loop_done);
++ movl(tmp4, Address(y, idx, Address::times_4, 0));
++ mulxq(carry2, tmp3, tmp4); // tmp4 * rdx -> carry2:tmp3
++ movl(tmp4, Address(z, idx, Address::times_4, 0));
++
++ add2_with_carry(carry2, tmp3, tmp4, carry);
++
++ movl(Address(z, idx, Address::times_4, 0), tmp3);
++ shrq(tmp3, 32);
++
++ shlq(carry2, 32);
++ orq(tmp3, carry2);
++ movq(carry, tmp3);
++
++ bind(L_post_third_loop_done);
++}
++
++/**
++ * Code for BigInteger::multiplyToLen() instrinsic.
++ *
++ * rdi: x
++ * rax: xlen
++ * rsi: y
++ * rcx: ylen
++ * r8: z
++ * r11: zlen
++ * r12: tmp1
++ * r13: tmp2
++ * r14: tmp3
++ * r15: tmp4
++ * rbx: tmp5
++ *
++ */
++void MacroAssembler::multiply_to_len(Register x, Register xlen, Register y, Register ylen, Register z, Register zlen,
++ Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5) {
++ ShortBranchVerifier sbv(this);
++ assert_different_registers(x, xlen, y, ylen, z, zlen, tmp1, tmp2, tmp3, tmp4, tmp5, rdx);
++
++ push(tmp1);
++ push(tmp2);
++ push(tmp3);
++ push(tmp4);
++ push(tmp5);
++
++ push(xlen);
++ push(zlen);
++
++ const Register idx = tmp1;
++ const Register kdx = tmp2;
++ const Register xstart = tmp3;
++
++ const Register y_idx = tmp4;
++ const Register carry = tmp5;
++ const Register product = xlen;
++ const Register x_xstart = zlen; // reuse register
++
++ // First Loop.
++ //
++ // final static long LONG_MASK = 0xffffffffL;
++ // int xstart = xlen - 1;
++ // int ystart = ylen - 1;
++ // long carry = 0;
++ // for (int idx=ystart, kdx=ystart+1+xstart; idx >= 0; idx-, kdx--) {
++ // long product = (y[idx] & LONG_MASK) * (x[xstart] & LONG_MASK) + carry;
++ // z[kdx] = (int)product;
++ // carry = product >>> 32;
++ // }
++ // z[xstart] = (int)carry;
++ //
++
++ movl(idx, ylen); // idx = ylen;
++ movl(kdx, zlen); // kdx = xlen+ylen;
++ xorq(carry, carry); // carry = 0;
++
++ Label L_done;
++
++ movl(xstart, xlen);
++ decrementl(xstart);
++ jcc(Assembler::negative, L_done);
++
++ multiply_64_x_64_loop(x, xstart, x_xstart, y, y_idx, z, carry, product, idx, kdx);
++
++ Label L_second_loop;
++ testl(kdx, kdx);
++ jcc(Assembler::zero, L_second_loop);
++
++ Label L_carry;
++ subl(kdx, 1);
++ jcc(Assembler::zero, L_carry);
++
++ movl(Address(z, kdx, Address::times_4, 0), carry);
++ shrq(carry, 32);
++ subl(kdx, 1);
++
++ bind(L_carry);
++ movl(Address(z, kdx, Address::times_4, 0), carry);
++
++ // Second and third (nested) loops.
++ //
++ // for (int i = xstart-1; i >= 0; i--) { // Second loop
++ // carry = 0;
++ // for (int jdx=ystart, k=ystart+1+i; jdx >= 0; jdx--, k--) { // Third loop
++ // long product = (y[jdx] & LONG_MASK) * (x[i] & LONG_MASK) +
++ // (z[k] & LONG_MASK) + carry;
++ // z[k] = (int)product;
++ // carry = product >>> 32;
++ // }
++ // z[i] = (int)carry;
++ // }
++ //
++ // i = xlen, j = tmp1, k = tmp2, carry = tmp5, x[i] = rdx
++
++ const Register jdx = tmp1;
++
++ bind(L_second_loop);
++ xorl(carry, carry); // carry = 0;
++ movl(jdx, ylen); // j = ystart+1
++
++ subl(xstart, 1); // i = xstart-1;
++ jcc(Assembler::negative, L_done);
++
++ push (z);
++
++ Label L_last_x;
++ lea(z, Address(z, xstart, Address::times_4, 4)); // z = z + k - j
++ subl(xstart, 1); // i = xstart-1;
++ jcc(Assembler::negative, L_last_x);
++
++ if (UseBMI2Instructions) {
++ movq(rdx, Address(x, xstart, Address::times_4, 0));
++ rorxq(rdx, rdx, 32); // convert big-endian to little-endian
++ } else {
++ movq(x_xstart, Address(x, xstart, Address::times_4, 0));
++ rorq(x_xstart, 32); // convert big-endian to little-endian
++ }
++
++ Label L_third_loop_prologue;
++ bind(L_third_loop_prologue);
++
++ push (x);
++ push (xstart);
++ push (ylen);
++
++
++ if (UseBMI2Instructions) {
++ multiply_128_x_128_bmi2_loop(y, z, carry, x, jdx, ylen, product, tmp2, x_xstart, tmp3, tmp4);
++ } else { // !UseBMI2Instructions
++ multiply_128_x_128_loop(x_xstart, y, z, y_idx, jdx, ylen, carry, product, x);
++ }
++
++ pop(ylen);
++ pop(xlen);
++ pop(x);
++ pop(z);
++
++ movl(tmp3, xlen);
++ addl(tmp3, 1);
++ movl(Address(z, tmp3, Address::times_4, 0), carry);
++ subl(tmp3, 1);
++ jccb(Assembler::negative, L_done);
++
++ shrq(carry, 32);
++ movl(Address(z, tmp3, Address::times_4, 0), carry);
++ jmp(L_second_loop);
++
++ // Next infrequent code is moved outside loops.
++ bind(L_last_x);
++ if (UseBMI2Instructions) {
++ movl(rdx, Address(x, 0));
++ } else {
++ movl(x_xstart, Address(x, 0));
++ }
++ jmp(L_third_loop_prologue);
++
++ bind(L_done);
++
++ pop(zlen);
++ pop(xlen);
++
++ pop(tmp5);
++ pop(tmp4);
++ pop(tmp3);
++ pop(tmp2);
++ pop(tmp1);
++}
++#endif
++
+ /**
+ * Emits code to update CRC-32 with a byte value according to constants in table
+ *
+@@ -7316,17 +7777,34 @@
+ * Fold 128-bit data chunk
+ */
+ void MacroAssembler::fold_128bit_crc32(XMMRegister xcrc, XMMRegister xK, XMMRegister xtmp, Register buf, int offset) {
+- vpclmulhdq(xtmp, xK, xcrc); // [123:64]
+- vpclmulldq(xcrc, xK, xcrc); // [63:0]
+- vpxor(xcrc, xcrc, Address(buf, offset), false /* vector256 */);
+- pxor(xcrc, xtmp);
++ if (UseAVX > 0) {
++ vpclmulhdq(xtmp, xK, xcrc); // [123:64]
++ vpclmulldq(xcrc, xK, xcrc); // [63:0]
++ vpxor(xcrc, xcrc, Address(buf, offset), false /* vector256 */);
++ pxor(xcrc, xtmp);
++ } else {
++ movdqa(xtmp, xcrc);
++ pclmulhdq(xtmp, xK); // [123:64]
++ pclmulldq(xcrc, xK); // [63:0]
++ pxor(xcrc, xtmp);
++ movdqu(xtmp, Address(buf, offset));
++ pxor(xcrc, xtmp);
++ }
+ }
+
+ void MacroAssembler::fold_128bit_crc32(XMMRegister xcrc, XMMRegister xK, XMMRegister xtmp, XMMRegister xbuf) {
+- vpclmulhdq(xtmp, xK, xcrc);
+- vpclmulldq(xcrc, xK, xcrc);
+- pxor(xcrc, xbuf);
+- pxor(xcrc, xtmp);
++ if (UseAVX > 0) {
++ vpclmulhdq(xtmp, xK, xcrc);
++ vpclmulldq(xcrc, xK, xcrc);
++ pxor(xcrc, xbuf);
++ pxor(xcrc, xtmp);
++ } else {
++ movdqa(xtmp, xcrc);
++ pclmulhdq(xtmp, xK);
++ pclmulldq(xcrc, xK);
++ pxor(xcrc, xbuf);
++ pxor(xcrc, xtmp);
++ }
+ }
+
+ /**
+@@ -7444,9 +7922,17 @@
+ // Fold 128 bits in xmm1 down into 32 bits in crc register.
+ BIND(L_fold_128b);
+ movdqu(xmm0, ExternalAddress(StubRoutines::x86::crc_by128_masks_addr()));
+- vpclmulqdq(xmm2, xmm0, xmm1, 0x1);
+- vpand(xmm3, xmm0, xmm2, false /* vector256 */);
+- vpclmulqdq(xmm0, xmm0, xmm3, 0x1);
++ if (UseAVX > 0) {
++ vpclmulqdq(xmm2, xmm0, xmm1, 0x1);
++ vpand(xmm3, xmm0, xmm2, false /* vector256 */);
++ vpclmulqdq(xmm0, xmm0, xmm3, 0x1);
++ } else {
++ movdqa(xmm2, xmm0);
++ pclmulqdq(xmm2, xmm1, 0x1);
++ movdqa(xmm3, xmm0);
++ pand(xmm3, xmm2);
++ pclmulqdq(xmm0, xmm3, 0x1);
++ }
+ psrldq(xmm1, 8);
+ psrldq(xmm2, 4);
+ pxor(xmm0, xmm1);
+--- ./hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -966,6 +966,16 @@
+ void mulss(XMMRegister dst, Address src) { Assembler::mulss(dst, src); }
+ void mulss(XMMRegister dst, AddressLiteral src);
+
++ // Carry-Less Multiplication Quadword
++ void pclmulldq(XMMRegister dst, XMMRegister src) {
++ // 0x00 - multiply lower 64 bits [0:63]
++ Assembler::pclmulqdq(dst, src, 0x00);
++ }
++ void pclmulhdq(XMMRegister dst, XMMRegister src) {
++ // 0x11 - multiply upper 64 bits [64:127]
++ Assembler::pclmulqdq(dst, src, 0x11);
++ }
++
+ void sqrtsd(XMMRegister dst, XMMRegister src) { Assembler::sqrtsd(dst, src); }
+ void sqrtsd(XMMRegister dst, Address src) { Assembler::sqrtsd(dst, src); }
+ void sqrtsd(XMMRegister dst, AddressLiteral src);
+@@ -1211,6 +1221,28 @@
+ XMMRegister tmp1, XMMRegister tmp2, XMMRegister tmp3,
+ XMMRegister tmp4, Register tmp5, Register result);
+
++#ifdef _LP64
++ void add2_with_carry(Register dest_hi, Register dest_lo, Register src1, Register src2);
++ void multiply_64_x_64_loop(Register x, Register xstart, Register x_xstart,
++ Register y, Register y_idx, Register z,
++ Register carry, Register product,
++ Register idx, Register kdx);
++ void multiply_add_128_x_128(Register x_xstart, Register y, Register z,
++ Register yz_idx, Register idx,
++ Register carry, Register product, int offset);
++ void multiply_128_x_128_bmi2_loop(Register y, Register z,
++ Register carry, Register carry2,
++ Register idx, Register jdx,
++ Register yz_idx1, Register yz_idx2,
++ Register tmp, Register tmp3, Register tmp4);
++ void multiply_128_x_128_loop(Register x_xstart, Register y, Register z,
++ Register yz_idx, Register idx, Register jdx,
++ Register carry, Register product,
++ Register carry2);
++ void multiply_to_len(Register x, Register xlen, Register y, Register ylen, Register z, Register zlen,
++ Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5);
++#endif
++
+ // CRC32 code for java.util.zip.CRC32::updateBytes() instrinsic.
+ void update_byte_crc32(Register crc, Register val, Register table);
+ void kernel_crc32(Register crc, Register buf, Register len, Register table, Register tmp);
+--- ./hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -3677,6 +3677,70 @@
+ return start;
+ }
+
++
++ /**
++ * Arguments:
++ *
++ * Input:
++ * c_rarg0 - x address
++ * c_rarg1 - x length
++ * c_rarg2 - y address
++ * c_rarg3 - y lenth
++ * not Win64
++ * c_rarg4 - z address
++ * c_rarg5 - z length
++ * Win64
++ * rsp+40 - z address
++ * rsp+48 - z length
++ */
++ address generate_multiplyToLen() {
++ __ align(CodeEntryAlignment);
++ StubCodeMark mark(this, "StubRoutines", "multiplyToLen");
++
++ address start = __ pc();
++ // Win64: rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...)
++ // Unix: rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...)
++ const Register x = rdi;
++ const Register xlen = rax;
++ const Register y = rsi;
++ const Register ylen = rcx;
++ const Register z = r8;
++ const Register zlen = r11;
++
++ // Next registers will be saved on stack in multiply_to_len().
++ const Register tmp1 = r12;
++ const Register tmp2 = r13;
++ const Register tmp3 = r14;
++ const Register tmp4 = r15;
++ const Register tmp5 = rbx;
++
++ BLOCK_COMMENT("Entry:");
++ __ enter(); // required for proper stackwalking of RuntimeStub frame
++
++#ifndef _WIN64
++ __ movptr(zlen, r9); // Save r9 in r11 - zlen
++#endif
++ setup_arg_regs(4); // x => rdi, xlen => rsi, y => rdx
++ // ylen => rcx, z => r8, zlen => r11
++ // r9 and r10 may be used to save non-volatile registers
++#ifdef _WIN64
++ // last 2 arguments (#4, #5) are on stack on Win64
++ __ movptr(z, Address(rsp, 6 * wordSize));
++ __ movptr(zlen, Address(rsp, 7 * wordSize));
++#endif
++
++ __ movptr(xlen, rsi);
++ __ movptr(y, rdx);
++ __ multiply_to_len(x, xlen, y, ylen, z, zlen, tmp1, tmp2, tmp3, tmp4, tmp5);
++
++ restore_arg_regs();
++
++ __ leave(); // required for proper stackwalking of RuntimeStub frame
++ __ ret(0);
++
++ return start;
++ }
++
+ #undef __
+ #define __ masm->
+
+@@ -3917,6 +3981,11 @@
+ generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry,
+ &StubRoutines::_safefetchN_fault_pc,
+ &StubRoutines::_safefetchN_continuation_pc);
++#ifdef COMPILER2
++ if (UseMultiplyToLenIntrinsic) {
++ StubRoutines::_multiplyToLen = generate_multiplyToLen();
++ }
++#endif
+ }
+
+ public:
+--- ./hotspot/src/cpu/x86/vm/vm_version_x86.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/x86/vm/vm_version_x86.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -493,7 +493,7 @@
+ }
+
+ char buf[256];
+- jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
++ jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ cores_per_cpu(), threads_per_core(),
+ cpu_family(), _model, _stepping,
+ (supports_cmov() ? ", cmov" : ""),
+@@ -522,7 +522,8 @@
+ (supports_tscinv_bit() ? ", tscinvbit": ""),
+ (supports_tscinv() ? ", tscinv": ""),
+ (supports_bmi1() ? ", bmi1" : ""),
+- (supports_bmi2() ? ", bmi2" : ""));
++ (supports_bmi2() ? ", bmi2" : ""),
++ (supports_adx() ? ", adx" : ""));
+ _features_str = strdup(buf);
+
+ // UseSSE is set to the smaller of what hardware supports and what
+@@ -568,13 +569,13 @@
+ FLAG_SET_DEFAULT(UseCLMUL, false);
+ }
+
+- if (UseCLMUL && (UseAVX > 0) && (UseSSE > 2)) {
++ if (UseCLMUL && (UseSSE > 2)) {
+ if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) {
+ UseCRC32Intrinsics = true;
+ }
+ } else if (UseCRC32Intrinsics) {
+ if (!FLAG_IS_DEFAULT(UseCRC32Intrinsics))
+- warning("CRC32 Intrinsics requires AVX and CLMUL instructions (not available on this CPU)");
++ warning("CRC32 Intrinsics requires CLMUL instructions (not available on this CPU)");
+ FLAG_SET_DEFAULT(UseCRC32Intrinsics, false);
+ }
+
+@@ -590,6 +591,17 @@
+ FLAG_SET_DEFAULT(UseAESIntrinsics, false);
+ }
+
++ if (UseSHA) {
++ warning("SHA instructions are not available on this CPU");
++ FLAG_SET_DEFAULT(UseSHA, false);
++ }
++ if (UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics) {
++ warning("SHA intrinsics are not available on this CPU");
++ FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
++ FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
++ FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
++ }
++
+ // Adjust RTM (Restricted Transactional Memory) flags
+ if (!supports_rtm() && UseRTMLocking) {
+ // Can't continue because UseRTMLocking affects UseBiasedLocking flag
+@@ -601,6 +613,17 @@
+
+ #if INCLUDE_RTM_OPT
+ if (UseRTMLocking) {
++ if (is_intel_family_core()) {
++ if ((_model == CPU_MODEL_HASWELL_E3) ||
++ (_model == CPU_MODEL_HASWELL_E7 && _stepping < 3) ||
++ (_model == CPU_MODEL_BROADWELL && _stepping < 4)) {
++ if (!UnlockExperimentalVMOptions) {
++ vm_exit_during_initialization("UseRTMLocking is only available as experimental option on this platform. It must be enabled via -XX:+UnlockExperimentalVMOptions flag.");
++ } else {
++ warning("UseRTMLocking is only available as experimental option on this platform.");
++ }
++ }
++ }
+ if (!FLAG_IS_CMDLINE(UseRTMLocking)) {
+ // RTM locking should be used only for applications with
+ // high lock contention. For now we do not use it by default.
+@@ -675,7 +698,20 @@
+ }
+ #endif
+ }
++
++#ifdef _LP64
++ if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
++ UseMultiplyToLenIntrinsic = true;
++ }
++#else
++ if (UseMultiplyToLenIntrinsic) {
++ if (!FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
++ warning("multiplyToLen intrinsic is not available in 32-bit VM");
++ }
++ FLAG_SET_DEFAULT(UseMultiplyToLenIntrinsic, false);
++ }
+ #endif
++#endif // COMPILER2
+
+ // On new cpus instructions which update whole XMM register should be used
+ // to prevent partial register stall due to dependencies on high half.
+@@ -803,6 +839,24 @@
+ }
+ }
+ }
++ if ((cpu_family() == 0x06) &&
++ ((extended_cpu_model() == 0x36) || // Centerton
++ (extended_cpu_model() == 0x37) || // Silvermont
++ (extended_cpu_model() == 0x4D))) {
++#ifdef COMPILER2
++ if (FLAG_IS_DEFAULT(OptoScheduling)) {
++ OptoScheduling = true;
++ }
++#endif
++ if (supports_sse4_2()) { // Silvermont
++ if (FLAG_IS_DEFAULT(UseUnalignedLoadStores)) {
++ UseUnalignedLoadStores = true; // use movdqu on newest Intel cpus
++ }
++ }
++ }
++ if(FLAG_IS_DEFAULT(AllocatePrefetchInstr) && supports_3dnow_prefetch()) {
++ AllocatePrefetchInstr = 3;
++ }
+ }
+
+ // Use count leading zeros count instruction if available.
+@@ -815,23 +869,40 @@
+ FLAG_SET_DEFAULT(UseCountLeadingZerosInstruction, false);
+ }
+
++ // Use count trailing zeros instruction if available
+ if (supports_bmi1()) {
++ // tzcnt does not require VEX prefix
++ if (FLAG_IS_DEFAULT(UseCountTrailingZerosInstruction)) {
++ if (!UseBMI1Instructions && !FLAG_IS_DEFAULT(UseBMI1Instructions)) {
++ // Don't use tzcnt if BMI1 is switched off on command line.
++ UseCountTrailingZerosInstruction = false;
++ } else {
++ UseCountTrailingZerosInstruction = true;
++ }
++ }
++ } else if (UseCountTrailingZerosInstruction) {
++ warning("tzcnt instruction is not available on this CPU");
++ FLAG_SET_DEFAULT(UseCountTrailingZerosInstruction, false);
++ }
++
++ // BMI instructions (except tzcnt) use an encoding with VEX prefix.
++ // VEX prefix is generated only when AVX > 0.
++ if (supports_bmi1() && supports_avx()) {
+ if (FLAG_IS_DEFAULT(UseBMI1Instructions)) {
+ UseBMI1Instructions = true;
+ }
+ } else if (UseBMI1Instructions) {
+- warning("BMI1 instructions are not available on this CPU");
++ warning("BMI1 instructions are not available on this CPU (AVX is also required)");
+ FLAG_SET_DEFAULT(UseBMI1Instructions, false);
+ }
+
+- // Use count trailing zeros instruction if available
+- if (supports_bmi1()) {
+- if (FLAG_IS_DEFAULT(UseCountTrailingZerosInstruction)) {
+- UseCountTrailingZerosInstruction = UseBMI1Instructions;
++ if (supports_bmi2() && supports_avx()) {
++ if (FLAG_IS_DEFAULT(UseBMI2Instructions)) {
++ UseBMI2Instructions = true;
+ }
+- } else if (UseCountTrailingZerosInstruction) {
+- warning("tzcnt instruction is not available on this CPU");
+- FLAG_SET_DEFAULT(UseCountTrailingZerosInstruction, false);
++ } else if (UseBMI2Instructions) {
++ warning("BMI2 instructions are not available on this CPU (AVX is also required)");
++ FLAG_SET_DEFAULT(UseBMI2Instructions, false);
+ }
+
+ // Use population count instruction if available.
+@@ -890,23 +961,25 @@
+ AllocatePrefetchDistance = allocate_prefetch_distance();
+ AllocatePrefetchStyle = allocate_prefetch_style();
+
+- if( is_intel() && cpu_family() == 6 && supports_sse3() ) {
+- if( AllocatePrefetchStyle == 2 ) { // watermark prefetching on Core
++ if (is_intel() && cpu_family() == 6 && supports_sse3()) {
++ if (AllocatePrefetchStyle == 2) { // watermark prefetching on Core
+ #ifdef _LP64
+ AllocatePrefetchDistance = 384;
+ #else
+ AllocatePrefetchDistance = 320;
+ #endif
+ }
+- if( supports_sse4_2() && supports_ht() ) { // Nehalem based cpus
++ if (supports_sse4_2() && supports_ht()) { // Nehalem based cpus
+ AllocatePrefetchDistance = 192;
+ AllocatePrefetchLines = 4;
++ }
+ #ifdef COMPILER2
+- if (AggressiveOpts && FLAG_IS_DEFAULT(UseFPUForSpilling)) {
++ if (supports_sse4_2()) {
++ if (FLAG_IS_DEFAULT(UseFPUForSpilling)) {
+ FLAG_SET_DEFAULT(UseFPUForSpilling, true);
+ }
++ }
+ #endif
+- }
+ }
+ assert(AllocatePrefetchDistance % AllocatePrefetchStepSize == 0, "invalid value");
+
+--- ./hotspot/src/cpu/x86/vm/vm_version_x86.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/x86/vm/vm_version_x86.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -209,7 +209,9 @@
+ erms : 1,
+ : 1,
+ rtm : 1,
+- : 20;
++ : 7,
++ adx : 1,
++ : 12;
+ } bits;
+ };
+
+@@ -260,7 +262,8 @@
+ CPU_CLMUL = (1 << 21), // carryless multiply for CRC
+ CPU_BMI1 = (1 << 22),
+ CPU_BMI2 = (1 << 23),
+- CPU_RTM = (1 << 24) // Restricted Transactional Memory instructions
++ CPU_RTM = (1 << 24), // Restricted Transactional Memory instructions
++ CPU_ADX = (1 << 25)
+ } cpuFeatureFlags;
+
+ enum {
+@@ -276,7 +279,10 @@
+ CPU_MODEL_WESTMERE_EX = 0x2f,
+ CPU_MODEL_SANDYBRIDGE = 0x2a,
+ CPU_MODEL_SANDYBRIDGE_EP = 0x2d,
+- CPU_MODEL_IVYBRIDGE_EP = 0x3a
++ CPU_MODEL_IVYBRIDGE_EP = 0x3a,
++ CPU_MODEL_HASWELL_E3 = 0x3c,
++ CPU_MODEL_HASWELL_E7 = 0x3f,
++ CPU_MODEL_BROADWELL = 0x3d
+ } cpuExtendedFamily;
+
+ // cpuid information block. All info derived from executing cpuid with
+@@ -462,10 +468,16 @@
+ }
+ // Intel features.
+ if(is_intel()) {
++ if(_cpuid_info.sef_cpuid7_ebx.bits.adx != 0)
++ result |= CPU_ADX;
+ if(_cpuid_info.sef_cpuid7_ebx.bits.bmi2 != 0)
+ result |= CPU_BMI2;
+ if(_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0)
+ result |= CPU_LZCNT;
++ // for Intel, ecx.bits.misalignsse bit (bit 8) indicates support for prefetchw
++ if (_cpuid_info.ext_cpuid1_ecx.bits.misalignsse != 0) {
++ result |= CPU_3DNOW_PREFETCH;
++ }
+ }
+
+ return result;
+@@ -618,6 +630,7 @@
+ static bool supports_rtm() { return (_cpuFeatures & CPU_RTM) != 0; }
+ static bool supports_bmi1() { return (_cpuFeatures & CPU_BMI1) != 0; }
+ static bool supports_bmi2() { return (_cpuFeatures & CPU_BMI2) != 0; }
++ static bool supports_adx() { return (_cpuFeatures & CPU_ADX) != 0; }
+ // Intel features
+ static bool is_intel_family_core() { return is_intel() &&
+ extended_cpu_family() == CPU_FAMILY_INTEL_CORE; }
+--- ./hotspot/src/cpu/zero/vm/compiledIC_zero.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/zero/vm/compiledIC_zero.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -58,34 +58,6 @@
+ return is_icholder_entry(call->destination());
+ }
+
+-//-----------------------------------------------------------------------------
+-// High-level access to an inline cache. Guaranteed to be MT-safe.
+-
+-CompiledIC::CompiledIC(nmethod* nm, NativeCall* call)
+- : _ic_call(call)
+-{
+- address ic_call = call->instruction_address();
+-
+- assert(ic_call != NULL, "ic_call address must be set");
+- assert(nm != NULL, "must pass nmethod");
+- assert(nm->contains(ic_call), "must be in nmethod");
+-
+- // Search for the ic_call at the given address.
+- RelocIterator iter(nm, ic_call, ic_call+1);
+- bool ret = iter.next();
+- assert(ret == true, "relocInfo must exist at this address");
+- assert(iter.addr() == ic_call, "must find ic_call");
+- if (iter.type() == relocInfo::virtual_call_type) {
+- virtual_call_Relocation* r = iter.virtual_call_reloc();
+- _is_optimized = false;
+- _value = nativeMovConstReg_at(r->cached_value());
+- } else {
+- assert(iter.type() == relocInfo::opt_virtual_call_type, "must be a virtual call");
+- _is_optimized = true;
+- _value = NULL;
+- }
+-}
+-
+ // ----------------------------------------------------------------------------
+
+ void CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf) {
+--- ./hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -40,6 +40,7 @@
+ #include "runtime/deoptimization.hpp"
+ #include "runtime/frame.inline.hpp"
+ #include "runtime/interfaceSupport.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/sharedRuntime.hpp"
+ #include "runtime/stubRoutines.hpp"
+ #include "runtime/synchronizer.hpp"
+--- ./hotspot/src/os/aix/vm/os_aix.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/aix/vm/os_aix.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -55,6 +55,7 @@
+ #include "runtime/javaCalls.hpp"
+ #include "runtime/mutexLocker.hpp"
+ #include "runtime/objectMonitor.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/osThread.hpp"
+ #include "runtime/perfMemory.hpp"
+ #include "runtime/sharedRuntime.hpp"
+@@ -113,12 +114,6 @@
+ }
+ #endif
+
+-// Excerpts from systemcfg.h definitions newer than AIX 5.3
+-#ifndef PV_7
+-# define PV_7 0x200000 // Power PC 7
+-# define PV_7_Compat 0x208000 // Power PC 7
+-#endif
+-
+ #define MAX_PATH (2 * K)
+
+ // for timer info max values which include all bits
+@@ -129,17 +124,40 @@
+ #define ERROR_MP_VMGETINFO_FAILED 102
+ #define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103
+
+-// the semantics in this file are thus that codeptr_t is a *real code ptr*
++// The semantics in this file are thus that codeptr_t is a *real code ptr*.
+ // This means that any function taking codeptr_t as arguments will assume
+ // a real codeptr and won't handle function descriptors (eg getFuncName),
+ // whereas functions taking address as args will deal with function
+-// descriptors (eg os::dll_address_to_library_name)
++// descriptors (eg os::dll_address_to_library_name).
+ typedef unsigned int* codeptr_t;
+
+-// typedefs for stackslots, stack pointers, pointers to op codes
++// Typedefs for stackslots, stack pointers, pointers to op codes.
+ typedef unsigned long stackslot_t;
+ typedef stackslot_t* stackptr_t;
+
++// Excerpts from systemcfg.h definitions newer than AIX 5.3.
++#ifndef PV_7
++#define PV_7 0x200000 /* Power PC 7 */
++#define PV_7_Compat 0x208000 /* Power PC 7 */
++#endif
++#ifndef PV_8
++#define PV_8 0x300000 /* Power PC 8 */
++#define PV_8_Compat 0x308000 /* Power PC 8 */
++#endif
++
++#define trcVerbose(fmt, ...) { /* PPC port */ \
++ if (Verbose) { \
++ fprintf(stderr, fmt, ##__VA_ARGS__); \
++ fputc('\n', stderr); fflush(stderr); \
++ } \
++}
++#define trc(fmt, ...) /* PPC port */
++
++#define ERRBYE(s) { \
++ trcVerbose(s); \
++ return -1; \
++}
++
+ // query dimensions of the stack of the calling thread
+ static void query_stack_dimensions(address* p_stack_base, size_t* p_stack_size);
+
+@@ -171,12 +189,12 @@
+ return true;
+ }
+
+-// macro to check a given stack pointer against given stack limits and to die if test fails
++// Macro to check a given stack pointer against given stack limits and to die if test fails.
+ #define CHECK_STACK_PTR(sp, stack_base, stack_size) { \
+ guarantee(is_valid_stackpointer((stackptr_t)(sp), (stackptr_t)(stack_base), stack_size), "Stack Pointer Invalid"); \
+ }
+
+-// macro to check the current stack pointer against given stacklimits
++// Macro to check the current stack pointer against given stacklimits.
+ #define CHECK_CURRENT_STACK_PTR(stack_base, stack_size) { \
+ address sp; \
+ sp = os::current_stack_pointer(); \
+@@ -210,7 +228,7 @@
+ static pid_t _initial_pid = 0;
+ static int SR_signum = SIGUSR2; // Signal used to suspend/resume a thread (must be > SIGSEGV, see 4355769)
+ static sigset_t SR_sigset;
+-static pthread_mutex_t dl_mutex; // Used to protect dlsym() calls */
++static pthread_mutex_t dl_mutex; // Used to protect dlsym() calls.
+
+ julong os::available_memory() {
+ return Aix::available_memory();
+@@ -242,7 +260,6 @@
+ return false;
+ }
+
+-
+ // Return true if user is running as root.
+
+ bool os::have_special_privileges() {
+@@ -273,8 +290,7 @@
+
+ for (int i = 0; i < numFullDisclaimsNeeded; i ++) {
+ if (::disclaim(p, maxDisclaimSize, DISCLAIM_ZEROMEM) != 0) {
+- //if (Verbose)
+- fprintf(stderr, "Cannot disclaim %p - %p (errno %d)\n", p, p + maxDisclaimSize, errno);
++ trc("Cannot disclaim %p - %p (errno %d)\n", p, p + maxDisclaimSize, errno);
+ return false;
+ }
+ p += maxDisclaimSize;
+@@ -282,8 +298,7 @@
+
+ if (lastDisclaimSize > 0) {
+ if (::disclaim(p, lastDisclaimSize, DISCLAIM_ZEROMEM) != 0) {
+- //if (Verbose)
+- fprintf(stderr, "Cannot disclaim %p - %p (errno %d)\n", p, p + lastDisclaimSize, errno);
++ trc("Cannot disclaim %p - %p (errno %d)\n", p, p + lastDisclaimSize, errno);
+ return false;
+ }
+ }
+@@ -323,11 +338,11 @@
+
+ void os::Aix::initialize_system_info() {
+
+- // get the number of online(logical) cpus instead of configured
++ // Get the number of online(logical) cpus instead of configured.
+ os::_processor_count = sysconf(_SC_NPROCESSORS_ONLN);
+ assert(_processor_count > 0, "_processor_count must be > 0");
+
+- // retrieve total physical storage
++ // Retrieve total physical storage.
+ os::Aix::meminfo_t mi;
+ if (!os::Aix::get_meminfo(&mi)) {
+ fprintf(stderr, "os::Aix::get_meminfo failed.\n"); fflush(stderr);
+@@ -502,7 +517,6 @@
+
+ } // end os::Aix::query_multipage_support()
+
+-// The code for this method was initially derived from the version in os_linux.cpp.
+ void os::init_system_properties_values() {
+
+ #define DEFAULT_LIBPATH "/usr/lib:/lib"
+@@ -599,10 +613,11 @@
+ sigaction(sig, (struct sigaction*)NULL, &oact);
+ void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction)
+ : CAST_FROM_FN_PTR(void*, oact.sa_handler);
+- if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN))
++ if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN)) {
+ return true;
+- else
++ } else {
+ return false;
++ }
+ }
+
+ void os::Aix::signal_sets_init() {
+@@ -776,6 +791,9 @@
+
+ // get the processor version from _system_configuration
+ switch (_system_configuration.version) {
++ case PV_8:
++ strcpy(pci->version, "Power PC 8");
++ break;
+ case PV_7:
+ strcpy(pci->version, "Power PC 7");
+ break;
+@@ -803,6 +821,9 @@
+ case PV_7_Compat:
+ strcpy(pci->version, "PV_7_Compat");
+ break;
++ case PV_8_Compat:
++ strcpy(pci->version, "PV_8_Compat");
++ break;
+ default:
+ strcpy(pci->version, "unknown");
+ }
+@@ -938,7 +959,9 @@
+
+ pthread_attr_destroy(&attr);
+
+- if (ret != 0) {
++ if (ret == 0) {
++ // PPC port traceOsMisc(("Created New Thread : pthread-id %u", tid));
++ } else {
+ if (PrintMiscellaneous && (Verbose || WizardMode)) {
+ perror("pthread_create()");
+ }
+@@ -1095,8 +1118,7 @@
+ if (os::Aix::on_pase()) {
+ Unimplemented();
+ return 0;
+- }
+- else {
++ } else {
+ // On AIX use the precision of processors real time clock
+ // or time base registers.
+ timebasestruct_t time;
+@@ -1149,7 +1171,6 @@
+ }
+ }
+
+-
+ char * os::local_time_string(char *buf, size_t buflen) {
+ struct tm t;
+ time_t long_time;
+@@ -1187,7 +1208,6 @@
+ if (abort_hook != NULL) {
+ abort_hook();
+ }
+-
+ }
+
+ // Note: os::abort() might be called very early during initialization, or
+@@ -1219,8 +1239,7 @@
+ // from src/solaris/hpi/src/system_md.c
+
+ size_t os::lasterror(char *buf, size_t len) {
+-
+- if (errno == 0) return 0;
++ if (errno == 0) return 0;
+
+ const char *s = ::strerror(errno);
+ size_t n = ::strlen(s);
+@@ -1233,6 +1252,7 @@
+ }
+
+ intx os::current_thread_id() { return (intx)pthread_self(); }
++
+ int os::current_process_id() {
+
+ // This implementation returns a unique pid, the pid of the
+@@ -1369,9 +1389,9 @@
+ if (offset) {
+ *offset = -1;
+ }
+- if (buf) {
+- buf[0] = '\0';
+- }
++ // Buf is not optional, but offset is optional.
++ assert(buf != NULL, "sanity check");
++ buf[0] = '\0';
+
+ // Resolve function ptr literals first.
+ addr = resolve_function_descriptor_to_code_pointer(addr);
+@@ -1404,12 +1424,9 @@
+ return 0;
+ }
+
+- if (Verbose) {
+- fprintf(stderr, "pc outside any module");
+- }
++ trcVerbose("pc outside any module");
+
+ return -1;
+-
+ }
+
+ bool os::dll_address_to_library_name(address addr, char* buf,
+@@ -1417,9 +1434,9 @@
+ if (offset) {
+ *offset = -1;
+ }
+- if (buf) {
+- buf[0] = '\0';
+- }
++ // Buf is not optional, but offset is optional.
++ assert(buf != NULL, "sanity check");
++ buf[0] = '\0';
+
+ // Resolve function ptr literals first.
+ addr = resolve_function_descriptor_to_code_pointer(addr);
+@@ -1434,7 +1451,7 @@
+ }
+
+ // Loads .dll/.so and in case of error it checks if .dll/.so was built
+-// for the same architecture as Hotspot is running on
++// for the same architecture as Hotspot is running on.
+ void *os::dll_load(const char *filename, char *ebuf, int ebuflen) {
+
+ if (ebuf && ebuflen > 0) {
+@@ -1597,7 +1614,6 @@
+ st->cr();
+ }
+
+-
+ static void print_signal_handler(outputStream* st, int sig,
+ char* buf, size_t buflen);
+
+@@ -1621,7 +1637,7 @@
+
+ static char saved_jvm_path[MAXPATHLEN] = {0};
+
+-// Find the full path to the current module, libjvm.so or libjvm_g.so
++// Find the full path to the current module, libjvm.so.
+ void os::jvm_path(char *buf, jint buflen) {
+ // Error checking.
+ if (buflen < MAXPATHLEN) {
+@@ -1691,7 +1707,7 @@
+ // Do not block out synchronous signals in the signal handler.
+ // Blocking synchronous signals only makes sense if you can really
+ // be sure that those signals won't happen during signal handling,
+- // when the blocking applies. Normal signal handlers are lean and
++ // when the blocking applies. Normal signal handlers are lean and
+ // do not cause signals. But our signal handlers tend to be "risky"
+ // - secondary SIGSEGV, SIGILL, SIGBUS' may and do happen.
+ // On AIX, PASE there was a case where a SIGSEGV happened, followed
+@@ -2966,13 +2982,9 @@
+ param.sched_priority = newpri;
+ int ret = pthread_setschedparam(thr, policy, &param);
+
+- if (Verbose) {
+- if (ret == 0) {
+- fprintf(stderr, "changed priority of thread %d to %d\n", (int)thr, newpri);
+- } else {
+- fprintf(stderr, "Could not changed priority for thread %d to %d (error %d, %s)\n",
+- (int)thr, newpri, ret, strerror(ret));
+- }
++ if (ret != 0) {
++ trcVerbose("Could not change priority for thread %d to %d (error %d, %s)",
++ (int)thr, newpri, ret, strerror(ret));
+ }
+ return (ret == 0) ? OS_OK : OS_ERR;
+ }
+@@ -3093,7 +3105,6 @@
+ errno = old_errno;
+ }
+
+-
+ static int SR_initialize() {
+ struct sigaction act;
+ char *s;
+@@ -3336,7 +3347,6 @@
+ JVM_handle_aix_signal(sig, info, uc, true);
+ }
+
+-
+ // This boolean allows users to forward their own non-matching signals
+ // to JVM_handle_aix_signal, harmlessly.
+ bool os::Aix::signal_handlers_are_installed = false;
+@@ -3530,7 +3540,7 @@
+ set_signal_handler(SIGDANGER, true);
+
+ if (libjsig_is_loaded) {
+- // Tell libjsig jvm finishes setting signal handlers
++ // Tell libjsig jvm finishes setting signal handlers.
+ (*end_signal_setting)();
+ }
+
+@@ -3546,7 +3556,7 @@
+ tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled");
+ check_signals = false;
+ }
+- // need to initialize check_signal_done
++ // Need to initialize check_signal_done.
+ ::sigemptyset(&check_signal_done);
+ }
+ }
+@@ -3620,7 +3630,6 @@
+ st->cr();
+ }
+
+-
+ #define DO_SIGNAL_CHECK(sig) \
+ if (!sigismember(&check_signal_done, sig)) \
+ os::Aix::check_signal_handler(sig)
+@@ -3681,7 +3690,6 @@
+ ? CAST_FROM_FN_PTR(address, act.sa_sigaction)
+ : CAST_FROM_FN_PTR(address, act.sa_handler);
+
+-
+ switch(sig) {
+ case SIGSEGV:
+ case SIGBUS:
+@@ -3829,15 +3837,13 @@
+ pthread_mutex_init(&dl_mutex, NULL);
+ }
+
+-// this is called _after_ the global arguments have been parsed
++// This is called _after_ the global arguments have been parsed.
+ jint os::init_2(void) {
+
+- if (Verbose) {
+- fprintf(stderr, "processor count: %d\n", os::_processor_count);
+- fprintf(stderr, "physical memory: %lu\n", Aix::_physical_memory);
+- }
+-
+- // initially build up the loaded dll map
++ trcVerbose("processor count: %d", os::_processor_count);
++ trcVerbose("physical memory: %lu", Aix::_physical_memory);
++
++ // Initially build up the loaded dll map.
+ LoadedLibraries::reload();
+
+ const int page_size = Aix::page_size();
+@@ -3887,7 +3893,7 @@
+ }
+
+ if (map_address != (address) MAP_FAILED) {
+- // map succeeded, but polling_page is not at wished address, unmap and continue.
++ // Map succeeded, but polling_page is not at wished address, unmap and continue.
+ ::munmap(map_address, map_size);
+ map_address = (address) MAP_FAILED;
+ }
+@@ -3941,7 +3947,7 @@
+
+ // Make the stack size a multiple of the page size so that
+ // the yellow/red zones can be guarded.
+- // note that this can be 0, if no default stacksize was set
++ // Note that this can be 0, if no default stacksize was set.
+ JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, vm_page_size()));
+
+ Aix::libpthread_init();
+@@ -4254,7 +4260,6 @@
+ return fd;
+ }
+
+-
+ // create binary file, rewriting existing file if required
+ int os::create_binary_file(const char* path, bool rewrite_existing) {
+ int oflags = O_WRONLY | O_CREAT;
+@@ -4323,7 +4328,6 @@
+ return NULL;
+ }
+
+-
+ // Remap a block of memory.
+ char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,
+ char *addr, size_t bytes, bool read_only,
+@@ -4371,14 +4375,14 @@
+ jlong sys_time = 0;
+ jlong user_time = 0;
+
+- // reimplemented using getthrds64().
++ // Reimplemented using getthrds64().
+ //
+- // goes like this:
++ // Works like this:
+ // For the thread in question, get the kernel thread id. Then get the
+ // kernel thread statistics using that id.
+ //
+ // This only works of course when no pthread scheduling is used,
+- // ie there is a 1:1 relationship to kernel threads.
++ // i.e. there is a 1:1 relationship to kernel threads.
+ // On AIX, see AIXTHREAD_SCOPE variable.
+
+ pthread_t pthtid = thread->osthread()->pthread_id();
+@@ -4525,14 +4529,12 @@
+ memset(&uts, 0, sizeof(uts));
+ strcpy(uts.sysname, "?");
+ if (::uname(&uts) == -1) {
+- fprintf(stderr, "uname failed (%d)\n", errno);
++ trc("uname failed (%d)", errno);
+ guarantee(0, "Could not determine whether we run on AIX or PASE");
+ } else {
+- if (Verbose) {
+- fprintf(stderr,"uname says: sysname \"%s\" version \"%s\" release \"%s\" "
+- "node \"%s\" machine \"%s\"\n",
+- uts.sysname, uts.version, uts.release, uts.nodename, uts.machine);
+- }
++ trcVerbose("uname says: sysname \"%s\" version \"%s\" release \"%s\" "
++ "node \"%s\" machine \"%s\"\n",
++ uts.sysname, uts.version, uts.release, uts.nodename, uts.machine);
+ const int major = atoi(uts.version);
+ assert(major > 0, "invalid OS version");
+ const int minor = atoi(uts.release);
+@@ -4544,12 +4546,10 @@
+ // We run on AIX. We do not support versions older than AIX 5.3.
+ _on_pase = 0;
+ if (_os_version < 0x0503) {
+- fprintf(stderr, "AIX release older than AIX 5.3 not supported.\n");
++ trc("AIX release older than AIX 5.3 not supported.");
+ assert(false, "AIX release too old.");
+ } else {
+- if (Verbose) {
+- fprintf(stderr, "We run on AIX %d.%d\n", major, minor);
+- }
++ trcVerbose("We run on AIX %d.%d\n", major, minor);
+ }
+ } else {
+ assert(false, "unknown OS");
+@@ -4557,7 +4557,6 @@
+ }
+
+ guarantee(_on_pase != -1 && _os_version, "Could not determine AIX/OS400 release");
+-
+ } // end: os::Aix::initialize_os_info()
+
+ // Scan environment for important settings which might effect the VM.
+@@ -4595,12 +4594,10 @@
+ // Note: Setting XPG_SUS_ENV in the process is too late. Must be set earlier (before
+ // exec() ? before loading the libjvm ? ....)
+ p = ::getenv("XPG_SUS_ENV");
+- if (Verbose) {
+- fprintf(stderr, "XPG_SUS_ENV=%s.\n", p ? p : "<unset>");
+- }
++ trcVerbose("XPG_SUS_ENV=%s.", p ? p : "<unset>");
+ if (p && strcmp(p, "ON") == 0) {
+ _xpg_sus_mode = 1;
+- fprintf(stderr, "Unsupported setting: XPG_SUS_ENV=ON\n");
++ trc("Unsupported setting: XPG_SUS_ENV=ON");
+ // This is not supported. Worst of all, it changes behaviour of mmap MAP_FIXED to
+ // clobber address ranges. If we ever want to support that, we have to do some
+ // testing first.
+@@ -4612,10 +4609,7 @@
+ // Switch off AIX internal (pthread) guard pages. This has
+ // immediate effect for any pthread_create calls which follow.
+ p = ::getenv("AIXTHREAD_GUARDPAGES");
+- if (Verbose) {
+- fprintf(stderr, "AIXTHREAD_GUARDPAGES=%s.\n", p ? p : "<unset>");
+- fprintf(stderr, "setting AIXTHREAD_GUARDPAGES=0.\n");
+- }
++ trcVerbose("AIXTHREAD_GUARDPAGES=%s.", p ? p : "<unset>");
+ rc = ::putenv("AIXTHREAD_GUARDPAGES=0");
+ guarantee(rc == 0, "");
+
+@@ -4633,7 +4627,7 @@
+ assert(os::Aix::on_aix(), "AIX only");
+
+ if (!libperfstat::init()) {
+- fprintf(stderr, "libperfstat initialization failed.\n");
++ trc("libperfstat initialization failed.");
+ assert(false, "libperfstat initialization failed");
+ } else {
+ if (Verbose) {
+@@ -4805,7 +4799,6 @@
+ return abstime;
+ }
+
+-
+ // Test-and-clear _Event, always leaves _Event set to 0, returns immediately.
+ // Conceptually TryPark() should be equivalent to park(0).
+
+@@ -4888,7 +4881,7 @@
+ while (_Event < 0) {
+ status = pthread_cond_timedwait(_cond, _mutex, &abst);
+ assert_status(status == 0 || status == ETIMEDOUT,
+- status, "cond_timedwait");
++ status, "cond_timedwait");
+ if (!FilterSpuriousWakeups) break; // previous semantics
+ if (status == ETIMEDOUT) break;
+ // We consume and ignore EINTR and spurious wakeups.
+@@ -5022,9 +5015,9 @@
+ // Optional fast-path check:
+ // Return immediately if a permit is available.
+ if (_counter > 0) {
+- _counter = 0;
+- OrderAccess::fence();
+- return;
++ _counter = 0;
++ OrderAccess::fence();
++ return;
+ }
+
+ Thread* thread = Thread::current();
+@@ -5046,7 +5039,6 @@
+ unpackTime(&absTime, isAbsolute, time);
+ }
+
+-
+ // Enter safepoint region
+ // Beware of deadlocks such as 6317397.
+ // The per-thread Parker:: mutex is a classic leaf-lock.
+@@ -5134,7 +5126,6 @@
+ }
+ }
+
+-
+ extern char** environ;
+
+ // Run the specified command in a separate process. Return its exit value,
+@@ -5153,44 +5144,43 @@
+ } else if (pid == 0) {
+ // child process
+
+- // try to be consistent with system(), which uses "/usr/bin/sh" on AIX
++ // Try to be consistent with system(), which uses "/usr/bin/sh" on AIX.
+ execve("/usr/bin/sh", argv, environ);
+
+ // execve failed
+ _exit(-1);
+
+- } else {
++ } else {
+ // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't
+ // care about the actual exit code, for now.
+
+ int status;
+
+- // Wait for the child process to exit. This returns immediately if
++ // Wait for the child process to exit. This returns immediately if
+ // the child has already exited. */
+ while (waitpid(pid, &status, 0) < 0) {
+- switch (errno) {
++ switch (errno) {
+ case ECHILD: return 0;
+ case EINTR: break;
+ default: return -1;
+- }
++ }
+ }
+
+ if (WIFEXITED(status)) {
+- // The child exited normally; get its exit code.
+- return WEXITSTATUS(status);
++ // The child exited normally; get its exit code.
++ return WEXITSTATUS(status);
+ } else if (WIFSIGNALED(status)) {
+- // The child exited because of a signal
+- // The best value to return is 0x80 + signal number,
+- // because that is what all Unix shells do, and because
+- // it allows callers to distinguish between process exit and
+- // process death by signal.
+- return 0x80 + WTERMSIG(status);
++ // The child exited because of a signal.
++ // The best value to return is 0x80 + signal number,
++ // because that is what all Unix shells do, and because
++ // it allows callers to distinguish between process exit and
++ // process death by signal.
++ return 0x80 + WTERMSIG(status);
+ } else {
+- // Unknown exit code; pass it through
+- return status;
++ // Unknown exit code; pass it through.
++ return status;
+ }
+ }
+- // Remove warning.
+ return -1;
+ }
+
+@@ -5205,7 +5195,7 @@
+ struct stat statbuf;
+ char buf[MAXPATHLEN];
+ char libmawtpath[MAXPATHLEN];
+- const char *xawtstr = "/xawt/libmawt.so";
++ const char *xawtstr = "/xawt/libmawt.so";
+ const char *new_xawtstr = "/libawt_xawt.so";
+
+ char *p;
+--- ./hotspot/src/os/aix/vm/os_aix.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/aix/vm/os_aix.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -209,7 +209,7 @@
+ return _can_use_16M_pages == 1 ? true : false;
+ }
+
+- static address ucontext_get_pc(ucontext_t* uc);
++ static address ucontext_get_pc(const ucontext_t* uc);
+ static intptr_t* ucontext_get_sp(ucontext_t* uc);
+ static intptr_t* ucontext_get_fp(ucontext_t* uc);
+ // Set PC into context. Needed for continuation after signal.
+--- ./hotspot/src/os/aix/vm/os_aix.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/aix/vm/os_aix.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,12 +26,9 @@
+ #ifndef OS_AIX_VM_OS_AIX_INLINE_HPP
+ #define OS_AIX_VM_OS_AIX_INLINE_HPP
+
+-#include "runtime/atomic.hpp"
++#include "runtime/atomic.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/os.hpp"
+-#ifdef TARGET_OS_ARCH_aix_ppc
+-# include "atomic_aix_ppc.inline.hpp"
+-# include "orderAccess_aix_ppc.inline.hpp"
+-#endif
+
+ // System includes
+
+--- ./hotspot/src/os/aix/vm/perfMemory_aix.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/aix/vm/perfMemory_aix.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -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, mtInternal);
+@@ -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, mtInternal);
+-}
+-
+-
+-// 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,32 +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
+- 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) {
+
+@@ -528,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);
++
++ // 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);
+ }
+@@ -613,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) {
+@@ -647,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(),
+@@ -661,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
+@@ -694,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, mtInternal);
+ FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+@@ -732,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;
+ }
+
+@@ -806,7 +1112,7 @@
+ char* mapAddress;
+ int result;
+ int fd;
+- size_t size;
++ size_t size = 0;
+ const char* luser = NULL;
+
+ int mmap_prot;
+@@ -818,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,6 +1165,9 @@
+ //
+ if (!is_directory_secure(dirname)) {
+ FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
++ if (luser != user) {
++ FREE_C_HEAP_ARRAY(char, luser, mtInternal);
++ }
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Process not found");
+ }
+@@ -897,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;
+
+--- ./hotspot/src/os/aix/vm/thread_aix.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/aix/vm/thread_aix.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,15 +26,9 @@
+ #ifndef OS_AIX_VM_THREAD_AIX_INLINE_HPP
+ #define OS_AIX_VM_THREAD_AIX_INLINE_HPP
+
+-#include "runtime/atomic.hpp"
+-#include "runtime/prefetch.hpp"
+ #include "runtime/thread.hpp"
+ #include "runtime/threadLocalStorage.hpp"
+
+-#include "atomic_aix_ppc.inline.hpp"
+-#include "orderAccess_aix_ppc.inline.hpp"
+-#include "prefetch_aix_ppc.inline.hpp"
+-
+ // Contains inlined functions for class Thread and ThreadLocalStorage
+
+ inline void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do
+--- ./hotspot/src/os/bsd/dtrace/libjvm_db.c Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/bsd/dtrace/libjvm_db.c Wed Feb 04 12:14:39 2015 -0800
+@@ -260,6 +260,9 @@
+ uint64_t base;
+ int err;
+
++ /* Clear *vmp now in case we jump to fail: */
++ memset(vmp, 0, sizeof(VMStructEntry));
++
+ err = ps_pglobal_lookup(J->P, LIBJVM_SO, "gHotSpotVMStructs", &sym_addr);
+ CHECK_FAIL(err);
+ err = read_pointer(J, sym_addr, &gHotSpotVMStructs);
+--- ./hotspot/src/os/bsd/vm/os_bsd.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/bsd/vm/os_bsd.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -48,6 +48,7 @@
+ #include "runtime/javaCalls.hpp"
+ #include "runtime/mutexLocker.hpp"
+ #include "runtime/objectMonitor.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/osThread.hpp"
+ #include "runtime/perfMemory.hpp"
+ #include "runtime/sharedRuntime.hpp"
+@@ -2433,23 +2434,25 @@
+ }
+
+ // The memory is committed
+- MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, mtNone, CALLER_PC);
++ MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, CALLER_PC);
+
+ return addr;
+ }
+
+ bool os::release_memory_special(char* base, size_t bytes) {
+- MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
+- // detaching the SHM segment will also delete it, see reserve_memory_special()
+- int rslt = shmdt(base);
+- if (rslt == 0) {
+- tkr.record((address)base, bytes);
+- return true;
++ if (MemTracker::tracking_level() > NMT_minimal) {
++ Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
++ // detaching the SHM segment will also delete it, see reserve_memory_special()
++ int rslt = shmdt(base);
++ if (rslt == 0) {
++ tkr.record((address)base, bytes);
++ return true;
++ } else {
++ return false;
++ }
+ } else {
+- tkr.discard();
+- return false;
++ return shmdt(base) == 0;
+ }
+-
+ }
+
+ size_t os::large_page_size() {
+--- ./hotspot/src/os/bsd/vm/os_bsd.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/bsd/vm/os_bsd.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,15 +26,9 @@
+ #define OS_BSD_VM_OS_BSD_INLINE_HPP
+
+ #include "runtime/atomic.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/os.hpp"
+
+-#ifdef TARGET_OS_ARCH_bsd_x86
+-# include "orderAccess_bsd_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_bsd_zero
+-# include "orderAccess_bsd_zero.inline.hpp"
+-#endif
+-
+ // System includes
+
+ #include <unistd.h>
+--- ./hotspot/src/os/bsd/vm/perfMemory_bsd.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/bsd/vm/perfMemory_bsd.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -962,7 +962,7 @@
+ (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, mtInternal, CURRENT_PC);
++ MemTracker::record_virtual_memory_reserve_and_commit((address)mapAddress, size, CURRENT_PC, mtInternal);
+
+ return mapAddress;
+ }
+@@ -1127,7 +1127,7 @@
+ }
+
+ // it does not go through os api, the operation has to record from here
+- MemTracker::record_virtual_memory_reserve((address)mapAddress, size, mtInternal, CURRENT_PC);
++ MemTracker::record_virtual_memory_reserve_and_commit((address)mapAddress, size, CURRENT_PC, mtInternal);
+
+ *addr = mapAddress;
+ *sizep = size;
+--- ./hotspot/src/os/bsd/vm/thread_bsd.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/bsd/vm/thread_bsd.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -29,20 +29,8 @@
+ #error "This file should only be included from thread.inline.hpp"
+ #endif
+
+-#include "runtime/atomic.hpp"
+-#include "runtime/prefetch.hpp"
+ #include "runtime/thread.hpp"
+ #include "runtime/threadLocalStorage.hpp"
+-#ifdef TARGET_OS_ARCH_bsd_x86
+-# include "atomic_bsd_x86.inline.hpp"
+-# include "orderAccess_bsd_x86.inline.hpp"
+-# include "prefetch_bsd_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_bsd_zero
+-# include "atomic_bsd_zero.inline.hpp"
+-# include "orderAccess_bsd_zero.inline.hpp"
+-# include "prefetch_bsd_zero.inline.hpp"
+-#endif
+
+ // Contains inlined functions for class Thread and ThreadLocalStorage
+
+--- ./hotspot/src/os/linux/vm/os_linux.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/linux/vm/os_linux.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -49,6 +49,7 @@
+ #include "runtime/javaCalls.hpp"
+ #include "runtime/mutexLocker.hpp"
+ #include "runtime/objectMonitor.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/osThread.hpp"
+ #include "runtime/perfMemory.hpp"
+ #include "runtime/sharedRuntime.hpp"
+@@ -2243,7 +2244,7 @@
+ const siginfo_t* si = (const siginfo_t*)siginfo;
+
+ os::Posix::print_siginfo_brief(st, si);
+-
++#if INCLUDE_CDS
+ if (si && (si->si_signo == SIGBUS || si->si_signo == SIGSEGV) &&
+ UseSharedSpaces) {
+ FileMapInfo* mapinfo = FileMapInfo::current_info();
+@@ -2253,6 +2254,7 @@
+ " possible disk/network problem.");
+ }
+ }
++#endif
+ st->cr();
+ }
+
+@@ -3500,9 +3502,12 @@
+
+ assert(is_ptr_aligned(start, alignment), "Must be");
+
+- // os::reserve_memory_special will record this memory area.
+- // Need to release it here to prevent overlapping reservations.
+- MemTracker::record_virtual_memory_release((address)start, bytes);
++ if (MemTracker::tracking_level() > NMT_minimal) {
++ // os::reserve_memory_special will record this memory area.
++ // Need to release it here to prevent overlapping reservations.
++ Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
++ tkr.record((address)start, bytes);
++ }
+
+ char* end = start + bytes;
+
+@@ -3597,7 +3602,7 @@
+ }
+
+ // The memory is committed
+- MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, mtNone, CALLER_PC);
++ MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, CALLER_PC);
+ }
+
+ return addr;
+@@ -3613,24 +3618,30 @@
+ }
+
+ bool os::release_memory_special(char* base, size_t bytes) {
++ bool res;
++ if (MemTracker::tracking_level() > NMT_minimal) {
++ Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
++ res = os::Linux::release_memory_special_impl(base, bytes);
++ if (res) {
++ tkr.record((address)base, bytes);
++ }
++
++ } else {
++ res = os::Linux::release_memory_special_impl(base, bytes);
++ }
++ return res;
++}
++
++bool os::Linux::release_memory_special_impl(char* base, size_t bytes) {
+ assert(UseLargePages, "only for large pages");
+-
+- MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
+-
+ bool res;
++
+ if (UseSHM) {
+ res = os::Linux::release_memory_special_shm(base, bytes);
+ } else {
+ assert(UseHugeTLBFS, "must be");
+ res = os::Linux::release_memory_special_huge_tlbfs(base, bytes);
+ }
+-
+- if (res) {
+- tkr.record((address)base, bytes);
+- } else {
+- tkr.discard();
+- }
+-
+ return res;
+ }
+
+--- ./hotspot/src/os/linux/vm/os_linux.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/linux/vm/os_linux.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -108,6 +108,7 @@
+ static char* reserve_memory_special_huge_tlbfs_only(size_t bytes, char* req_addr, bool exec);
+ static char* reserve_memory_special_huge_tlbfs_mixed(size_t bytes, size_t alignment, char* req_addr, bool exec);
+
++ static bool release_memory_special_impl(char* base, size_t bytes);
+ static bool release_memory_special_shm(char* base, size_t bytes);
+ static bool release_memory_special_huge_tlbfs(char* base, size_t bytes);
+
+--- ./hotspot/src/os/linux/vm/os_linux.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/linux/vm/os_linux.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,24 +26,9 @@
+ #define OS_LINUX_VM_OS_LINUX_INLINE_HPP
+
+ #include "runtime/atomic.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/os.hpp"
+
+-#ifdef TARGET_OS_ARCH_linux_x86
+-# include "orderAccess_linux_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_sparc
+-# include "orderAccess_linux_sparc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_zero
+-# include "orderAccess_linux_zero.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_arm
+-# include "orderAccess_linux_arm.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_ppc
+-# include "orderAccess_linux_ppc.inline.hpp"
+-#endif
+-
+ // System includes
+
+ #include <unistd.h>
+--- ./hotspot/src/os/linux/vm/perfMemory_linux.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/linux/vm/perfMemory_linux.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -971,7 +971,7 @@
+ (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, mtInternal, CURRENT_PC);
++ MemTracker::record_virtual_memory_reserve_and_commit((address)mapAddress, size, CURRENT_PC, mtInternal);
+
+ return mapAddress;
+ }
+@@ -1142,7 +1142,7 @@
+ }
+
+ // it does not go through os api, the operation has to record from here
+- MemTracker::record_virtual_memory_reserve((address)mapAddress, size, mtInternal, CURRENT_PC);
++ MemTracker::record_virtual_memory_reserve_and_commit((address)mapAddress, size, CURRENT_PC, mtInternal);
+
+ *addr = mapAddress;
+ *sizep = size;
+--- ./hotspot/src/os/linux/vm/thread_linux.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/linux/vm/thread_linux.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -29,35 +29,8 @@
+ #error "This file should only be included from thread.inline.hpp"
+ #endif
+
+-#include "runtime/atomic.hpp"
+-#include "runtime/prefetch.hpp"
+ #include "runtime/thread.hpp"
+ #include "runtime/threadLocalStorage.hpp"
+-#ifdef TARGET_OS_ARCH_linux_x86
+-# include "atomic_linux_x86.inline.hpp"
+-# include "orderAccess_linux_x86.inline.hpp"
+-# include "prefetch_linux_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_sparc
+-# include "atomic_linux_sparc.inline.hpp"
+-# include "orderAccess_linux_sparc.inline.hpp"
+-# include "prefetch_linux_sparc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_zero
+-# include "atomic_linux_zero.inline.hpp"
+-# include "orderAccess_linux_zero.inline.hpp"
+-# include "prefetch_linux_zero.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_arm
+-# include "atomic_linux_arm.inline.hpp"
+-# include "orderAccess_linux_arm.inline.hpp"
+-# include "prefetch_linux_arm.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_ppc
+-# include "atomic_linux_ppc.inline.hpp"
+-# include "orderAccess_linux_ppc.inline.hpp"
+-# include "prefetch_linux_ppc.inline.hpp"
+-#endif
+
+ // Contains inlined functions for class Thread and ThreadLocalStorage
+
+--- ./hotspot/src/os/posix/vm/os_posix.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/posix/vm/os_posix.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -74,21 +74,41 @@
+ VMError::report_coredump_status(buffer, success);
+ }
+
+-address os::get_caller_pc(int n) {
++int os::get_native_stack(address* stack, int frames, int toSkip) {
+ #ifdef _NMT_NOINLINE_
+- n ++;
++ toSkip++;
+ #endif
++
++ int frame_idx = 0;
++ int num_of_frames; // number of frames captured
+ frame fr = os::current_frame();
+- while (n > 0 && fr.pc() &&
+- !os::is_first_C_frame(&fr) && fr.sender_pc()) {
+- fr = os::get_sender_for_C_frame(&fr);
+- n --;
++ while (fr.pc() && frame_idx < frames) {
++ if (toSkip > 0) {
++ toSkip --;
++ } else {
++ stack[frame_idx ++] = fr.pc();
++ }
++ if (fr.fp() == NULL || os::is_first_C_frame(&fr)
++ ||fr.sender_pc() == NULL || fr.cb() != NULL) break;
++
++ if (fr.sender_pc() && !os::is_first_C_frame(&fr)) {
++ fr = os::get_sender_for_C_frame(&fr);
++ } else {
++ break;
++ }
+ }
+- if (n == 0) {
+- return fr.pc();
+- } else {
+- return NULL;
++ num_of_frames = frame_idx;
++ for (; frame_idx < frames; frame_idx ++) {
++ stack[frame_idx] = NULL;
+ }
++
++ return num_of_frames;
++}
++
++
++bool os::unsetenv(const char* name) {
++ assert(name != NULL, "Null pointer");
++ return (::unsetenv(name) == 0);
+ }
+
+ int os::get_last_error() {
+--- ./hotspot/src/os/solaris/add_gnu_debuglink/add_gnu_debuglink.c Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,285 +0,0 @@
+-/*
+- * Copyright (c) 2012, 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.
+- *
+- */
+-
+-/*
+- * Name: add_gnu_debuglink.c
+- *
+- * Description: Add a ".gnu_debuglink" section that refers to the specified
+- * debug_info_path to the specified ELF object.
+- *
+- * This program is adapted from the example program shown on the
+- * elf(3elf) man page and from code from the Solaris compiler
+- * driver.
+- */
+-
+-/*
+- * needed to define SHF_EXCLUDE
+- */
+-#define ELF_TARGET_ALL
+-
+-#include <fcntl.h>
+-#include <stdio.h>
+-#include <libelf.h>
+-#include <stdlib.h>
+-#include <string.h>
+-#include <unistd.h>
+-
+-static void failure(void);
+-static unsigned int gnu_debuglink_crc32(unsigned int crc, unsigned char *buf,
+- size_t len);
+-
+-void
+-main(int argc, char ** argv) {
+- /* new ELF section name */
+- static char SEC_NAME[] = ".gnu_debuglink";
+-
+- unsigned char buffer[8 * 1024]; /* I/O buffer */
+- int buffer_len; /* buffer length */
+- char * debug_info_path; /* debug info path */
+- void * ehdr; /* ELF header */
+- Elf * elf; /* ELF descriptor */
+- char * elf_ident; /* ELF identity string */
+- char * elf_obj; /* elf_obj file */
+- int fd; /* descriptor for files */
+- unsigned int file_crc = 0; /* CRC for debug info file */
+- int is_elfclass64; /* is an ELFCLASS64 file? */
+- Elf_Data * link_dat; /* ELF data for new debug info link */
+- Elf_Data * name_dat; /* ELF data for new section name */
+- Elf_Scn * new_scn; /* new ELF section descriptor */
+- void * new_shdr; /* new ELF section header */
+- Elf_Scn * scn; /* ELF section descriptor */
+- void * shdr; /* ELF section header */
+-
+- if (argc != 3) {
+- (void) fprintf(stderr, "Usage: %s debug_info_path elf_obj\n", argv[0]);
+- exit(2);
+- }
+-
+- debug_info_path = argv[1]; /* save for later */
+- if ((fd = open(debug_info_path, O_RDONLY)) == -1) {
+- (void) fprintf(stderr, "%s: cannot open file.\n", debug_info_path);
+- exit(3);
+- }
+-
+- (void) printf("Computing CRC for '%s'\n", debug_info_path);
+- (void) fflush(stdout);
+- /* compute CRC for the debug info file */
+- for (;;) {
+- int len = read(fd, buffer, sizeof buffer);
+- if (len <= 0) {
+- break;
+- }
+- file_crc = gnu_debuglink_crc32(file_crc, buffer, len);
+- }
+- (void) close(fd);
+-
+- /* open the elf_obj */
+- elf_obj = argv[2];
+- if ((fd = open(elf_obj, O_RDWR)) == -1) {
+- (void) fprintf(stderr, "%s: cannot open file.\n", elf_obj);
+- exit(4);
+- }
+-
+- (void) printf("Opening '%s' for update\n", elf_obj);
+- (void) fflush(stdout);
+- (void) elf_version(EV_CURRENT); /* coordinate ELF versions */
+-
+- /* obtain the ELF descriptors from the input file */
+- if ((elf = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL) {
+- failure();
+- }
+-
+- /* determine if ELFCLASS64 or not? */
+- elf_ident = elf_getident(elf, NULL);
+- is_elfclass64 = (elf_ident[EI_CLASS] == ELFCLASS64);
+-
+- /* get the ELF header */
+- if (is_elfclass64) {
+- ehdr = elf64_getehdr(elf);
+- } else {
+- ehdr = elf32_getehdr(elf);
+- }
+- if (ehdr == NULL) {
+- failure();
+- }
+-
+- /* get the ELF section descriptor */
+- if (is_elfclass64) {
+- scn = elf_getscn(elf, ((Elf64_Ehdr *) ehdr)->e_shstrndx);
+- } else {
+- scn = elf_getscn(elf, ((Elf32_Ehdr *) ehdr)->e_shstrndx);
+- }
+- if (scn == NULL) {
+- failure();
+- }
+-
+- /* get the section header */
+- if (is_elfclass64) {
+- shdr = elf64_getshdr(scn);
+- } else {
+- shdr = elf32_getshdr(scn);
+- }
+- if (shdr == NULL) {
+- failure();
+- }
+-
+- (void) printf("Adding ELF data for new section name\n");
+- (void) fflush(stdout);
+- name_dat = elf_newdata(scn);
+- name_dat->d_buf = (void *) SEC_NAME;
+- if (is_elfclass64) {
+- name_dat->d_off = ((Elf64_Shdr *) shdr)->sh_size + 1;
+- } else {
+- name_dat->d_off = ((Elf32_Shdr *) shdr)->sh_size + 1;
+- }
+- name_dat->d_align = 1;
+- name_dat->d_size = strlen(SEC_NAME) + 1;
+-
+- new_scn = elf_newscn(elf);
+-
+- if (is_elfclass64) {
+- new_shdr = elf64_getshdr(new_scn);
+- ((Elf64_Shdr *) new_shdr)->sh_flags = SHF_EXCLUDE;
+- ((Elf64_Shdr *) new_shdr)->sh_type = SHT_PROGBITS;
+- ((Elf64_Shdr *) new_shdr)->sh_name = ((Elf64_Shdr *) shdr)->sh_size;
+- ((Elf64_Shdr *) new_shdr)->sh_addralign = 1;
+- ((Elf64_Shdr *) shdr)->sh_size += (strlen(SEC_NAME) + 1);
+- } else {
+- new_shdr = elf32_getshdr(new_scn);
+- ((Elf32_Shdr *) new_shdr)->sh_flags = SHF_EXCLUDE;
+- ((Elf32_Shdr *) new_shdr)->sh_type = SHT_PROGBITS;
+- ((Elf32_Shdr *) new_shdr)->sh_name = ((Elf32_Shdr *) shdr)->sh_size;
+- ((Elf32_Shdr *) new_shdr)->sh_addralign = 1;
+- ((Elf32_Shdr *) shdr)->sh_size += (strlen(SEC_NAME) + 1);
+- }
+-
+- (void) printf("Adding ELF data for debug_info_path value\n");
+- (void) fflush(stdout);
+- (void) memset(buffer, 0, sizeof buffer);
+- buffer_len = strlen(debug_info_path) + 1; /* +1 for NUL */
+- (void) strncpy((char *) buffer, debug_info_path, buffer_len);
+- if (buffer_len % 4 != 0) {
+- /* not on a 4 byte boundary so pad to the next one */
+- buffer_len += (4 - buffer_len % 4);
+- }
+- /* save the CRC */
+- (void) memcpy(&buffer[buffer_len], &file_crc, sizeof file_crc);
+- buffer_len += sizeof file_crc;
+-
+- link_dat = elf_newdata(new_scn);
+- link_dat->d_type = ELF_T_BYTE;
+- link_dat->d_size = buffer_len;
+- link_dat->d_buf = buffer;
+- link_dat->d_align = 1;
+-
+- (void) printf("Saving updates to '%s'\n", elf_obj);
+- (void) fflush(stdout);
+- (void) elf_update(elf, ELF_C_NULL); /* recalc ELF memory structures */
+- (void) elf_update(elf, ELF_C_WRITE); /* write out changes to ELF obj */
+- (void) elf_end(elf); /* done with ELF obj */
+- (void) close(fd);
+-
+- (void) printf("Done updating '%s'\n", elf_obj);
+- (void) fflush(stdout);
+- exit(0);
+-} /* end main */
+-
+-
+-static void
+-failure() {
+- (void) fprintf(stderr, "%s\n", elf_errmsg(elf_errno()));
+- exit(5);
+-}
+-
+-
+-/*
+- * The CRC used in gnu_debuglink, retrieved from
+- * http://sourceware.org/gdb/current/onlinedocs/gdb/Separate-Debug-Files.html#Separate-Debug-Files.
+- */
+-
+-static unsigned int
+-gnu_debuglink_crc32(unsigned int crc, unsigned char *buf, size_t len) {
+- static const unsigned int crc32_table[256] = {
+- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+- 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+- 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+- 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+- 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+- 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+- 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+- 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+- 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+- 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+- 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+- 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+- 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+- 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+- 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+- 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+- 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+- 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+- 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+- 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+- 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+- 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+- 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+- 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+- 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+- 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+- 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+- 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+- 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+- 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+- 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+- 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+- 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+- 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+- 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+- 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+- 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+- 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+- 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+- 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+- 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+- 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+- 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+- 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+- 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+- 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+- 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+- 0x2d02ef8d
+- };
+-
+- unsigned char *end;
+-
+- crc = ~crc & 0xffffffff;
+- for (end = buf + len; buf < end; ++buf) {
+- crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+- }
+- return ~crc & 0xffffffff;
+-}
+--- ./hotspot/src/os/solaris/dtrace/libjvm_db.c Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/solaris/dtrace/libjvm_db.c Wed Feb 04 12:14:39 2015 -0800
+@@ -260,6 +260,9 @@
+ uint64_t base;
+ int err;
+
++ /* Clear *vmp now in case we jump to fail: */
++ memset(vmp, 0, sizeof(VMStructEntry));
++
+ err = ps_pglobal_lookup(J->P, LIBJVM_SO, "gHotSpotVMStructs", &sym_addr);
+ CHECK_FAIL(err);
+ err = read_pointer(J, sym_addr, &gHotSpotVMStructs);
+--- ./hotspot/src/os/solaris/fix_empty_sec_hdr_flags/fix_empty_sec_hdr_flags.c Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,181 +0,0 @@
+-/*
+- * Copyright (c) 2012, 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.
+- *
+- */
+-
+-/*
+- * Name: fix_empty_sec_hdr_flags.c
+- *
+- * Description: Remove the SHF_ALLOC flag from "empty" section headers.
+- * An "empty" section header has sh_addr == 0 and sh_size == 0.
+- *
+- * This program is adapted from the example program shown on the
+- * elf(3elf) man page and from code from the Solaris compiler
+- * driver.
+- */
+-
+-#include <fcntl.h>
+-#include <stdio.h>
+-#include <libelf.h>
+-#include <stdlib.h>
+-#include <string.h>
+-#include <unistd.h>
+-
+-static void failure(void);
+-
+-void
+-main(int argc, char ** argv) {
+- void * ehdr; /* ELF header */
+- unsigned int i; /* section counter */
+- int fd; /* descriptor for file */
+- Elf * elf; /* ELF descriptor */
+- char * elf_ident; /* ELF identity string */
+- char * elf_obj; /* elf_obj file */
+- int fix_count; /* number of flags fixed */
+- int is_elfclass64; /* is an ELFCLASS64 file? */
+- Elf_Scn * scn; /* ELF section descriptor */
+- void * shdr; /* ELF section header */
+- Elf_Data * shstrtab; /* ELF section header string table */
+-
+- if (argc != 2) {
+- (void) fprintf(stderr, "Usage: %s elf_obj\n", argv[0]);
+- exit(2);
+- }
+-
+- /* open the elf_obj */
+- elf_obj = argv[1];
+- if ((fd = open(elf_obj, O_RDWR)) == -1) {
+- (void) fprintf(stderr, "%s: cannot open file.\n", elf_obj);
+- exit(3);
+- }
+-
+- (void) printf("Opening '%s' for update\n", elf_obj);
+- (void) fflush(stdout);
+- (void) elf_version(EV_CURRENT); /* coordinate ELF versions */
+-
+- /* obtain the ELF descriptors from the input file */
+- if ((elf = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL) {
+- failure();
+- }
+-
+- /* determine if ELFCLASS64 or not? */
+- elf_ident = elf_getident(elf, NULL);
+- is_elfclass64 = (elf_ident[EI_CLASS] == ELFCLASS64);
+-
+- /* get the ELF header */
+- if (is_elfclass64) {
+- ehdr = elf64_getehdr(elf);
+- } else {
+- ehdr = elf32_getehdr(elf);
+- }
+- if (ehdr == NULL) {
+- failure();
+- }
+-
+- /* get the ELF section descriptor */
+- if (is_elfclass64) {
+- scn = elf_getscn(elf, ((Elf64_Ehdr *) ehdr)->e_shstrndx);
+- } else {
+- scn = elf_getscn(elf, ((Elf32_Ehdr *) ehdr)->e_shstrndx);
+- }
+- if (scn == NULL) {
+- failure();
+- }
+-
+- /* get the section header string table */
+- shstrtab = elf_getdata(scn, NULL);
+- if (shstrtab == NULL) {
+- failure();
+- }
+-
+- fix_count = 0;
+-
+- /* traverse the sections of the input file */
+- for (i = 1, scn = NULL; scn = elf_nextscn(elf, scn); i++) {
+- int has_flag_set; /* is SHF_ALLOC flag set? */
+- int is_empty; /* is section empty? */
+- char * name; /* short hand pointer */
+-
+- /* get the section header */
+- if (is_elfclass64) {
+- shdr = elf64_getshdr(scn);
+- } else {
+- shdr = elf32_getshdr(scn);
+- }
+- if (shdr == NULL) {
+- failure();
+- }
+-
+- if (is_elfclass64) {
+- name = (char *)shstrtab->d_buf + ((Elf64_Shdr *) shdr)->sh_name;
+- } else {
+- name = (char *)shstrtab->d_buf + ((Elf32_Shdr *) shdr)->sh_name;
+- }
+-
+- if (is_elfclass64) {
+- has_flag_set = ((Elf64_Shdr *) shdr)->sh_flags & SHF_ALLOC;
+- is_empty = ((Elf64_Shdr *) shdr)->sh_addr == 0 &&
+- ((Elf64_Shdr *) shdr)->sh_size == 0;
+- } else {
+- has_flag_set = ((Elf32_Shdr *) shdr)->sh_flags & SHF_ALLOC;
+- is_empty = ((Elf32_Shdr *) shdr)->sh_addr == 0 &&
+- ((Elf32_Shdr *) shdr)->sh_size == 0;
+- }
+-
+- if (is_empty && has_flag_set) {
+- (void) printf("section[%u] '%s' is empty, "
+- "but SHF_ALLOC flag is set.\n", i, name);
+- (void) printf("Clearing the SHF_ALLOC flag.\n");
+-
+- if (is_elfclass64) {
+- ((Elf64_Shdr *) shdr)->sh_flags &= ~SHF_ALLOC;
+- } else {
+- ((Elf32_Shdr *) shdr)->sh_flags &= ~SHF_ALLOC;
+- }
+- fix_count++;
+- }
+- } /* end for each ELF section */
+-
+- if (fix_count > 0) {
+- (void) printf("Saving %d updates to '%s'\n", fix_count, elf_obj);
+- (void) fflush(stdout);
+- (void) elf_update(elf, ELF_C_NULL); /* recalc ELF memory structures */
+- (void) elf_update(elf, ELF_C_WRITE); /* write out changes to ELF obj */
+- } else {
+- (void) printf("No SHF_ALLOC flags needed to be cleared.\n");
+- }
+-
+- (void) elf_end(elf); /* done with ELF obj */
+- (void) close(fd);
+-
+- (void) printf("Done %s '%s'\n",
+- (fix_count > 0) ? "updating" : "with", elf_obj);
+- (void) fflush(stdout);
+- exit(0);
+-} /* end main */
+-
+-
+-static void
+-failure() {
+- (void) fprintf(stderr, "%s\n", elf_errmsg(elf_errno()));
+- exit(6);
+-}
+--- ./hotspot/src/os/solaris/vm/os_solaris.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/solaris/vm/os_solaris.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -48,6 +48,7 @@
+ #include "runtime/javaCalls.hpp"
+ #include "runtime/mutexLocker.hpp"
+ #include "runtime/objectMonitor.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/osThread.hpp"
+ #include "runtime/perfMemory.hpp"
+ #include "runtime/sharedRuntime.hpp"
+--- ./hotspot/src/os/solaris/vm/os_solaris.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/solaris/vm/os_solaris.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,15 +26,9 @@
+ #define OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP
+
+ #include "runtime/atomic.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/os.hpp"
+
+-#ifdef TARGET_OS_ARCH_solaris_x86
+-# include "orderAccess_solaris_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_solaris_sparc
+-# include "orderAccess_solaris_sparc.inline.hpp"
+-#endif
+-
+ // System includes
+ #include <sys/param.h>
+ #include <dlfcn.h>
+--- ./hotspot/src/os/solaris/vm/perfMemory_solaris.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/solaris/vm/perfMemory_solaris.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -991,7 +991,8 @@
+ (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, mtInternal, CURRENT_PC);
++ MemTracker::record_virtual_memory_reserve_and_commit((address)mapAddress,
++ size, CURRENT_PC, mtInternal);
+
+ return mapAddress;
+ }
+@@ -1162,7 +1163,8 @@
+ }
+
+ // it does not go through os api, the operation has to record from here
+- MemTracker::record_virtual_memory_reserve((address)mapAddress, size, mtInternal, CURRENT_PC);
++ MemTracker::record_virtual_memory_reserve_and_commit((address)mapAddress,
++ size, CURRENT_PC, mtInternal);
+
+ *addr = mapAddress;
+ *sizep = size;
+--- ./hotspot/src/os/solaris/vm/thread_solaris.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/solaris/vm/thread_solaris.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -29,20 +29,9 @@
+ #error "This file should only be included from thread.inline.hpp"
+ #endif
+
+-#include "runtime/atomic.hpp"
+-#include "runtime/prefetch.hpp"
++#include "runtime/atomic.inline.hpp"
+ #include "runtime/thread.hpp"
+ #include "runtime/threadLocalStorage.hpp"
+-#ifdef TARGET_OS_ARCH_solaris_x86
+-# include "atomic_solaris_x86.inline.hpp"
+-# include "orderAccess_solaris_x86.inline.hpp"
+-# include "prefetch_solaris_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_solaris_sparc
+-# include "atomic_solaris_sparc.inline.hpp"
+-# include "orderAccess_solaris_sparc.inline.hpp"
+-# include "prefetch_solaris_sparc.inline.hpp"
+-#endif
+
+ // Thread::current is "hot" it's called > 128K times in the 1st 500 msecs of
+ // startup.
+--- ./hotspot/src/os/windows/vm/os_windows.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/windows/vm/os_windows.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -51,6 +51,7 @@
+ #include "runtime/javaCalls.hpp"
+ #include "runtime/mutexLocker.hpp"
+ #include "runtime/objectMonitor.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/osThread.hpp"
+ #include "runtime/perfMemory.hpp"
+ #include "runtime/sharedRuntime.hpp"
+@@ -130,6 +131,7 @@
+ case DLL_PROCESS_DETACH:
+ if(ForceTimeHighResolution)
+ timeEndPeriod(1L);
++
+ break;
+ default:
+ break;
+@@ -152,6 +154,10 @@
+ return result > 0 && result < len;
+ }
+
++bool os::unsetenv(const char* name) {
++ assert(name != NULL, "Null pointer");
++ return (SetEnvironmentVariable(name, NULL) == TRUE);
++}
+
+ // No setuid programs under Windows.
+ bool os::have_special_privileges() {
+@@ -310,15 +316,17 @@
+ * So far, this method is only used by Native Memory Tracking, which is
+ * only supported on Windows XP or later.
+ */
+-address os::get_caller_pc(int n) {
++
++int os::get_native_stack(address* stack, int frames, int toSkip) {
+ #ifdef _NMT_NOINLINE_
+- n ++;
++ toSkip ++;
+ #endif
+- address pc;
+- if (os::Kernel32Dll::RtlCaptureStackBackTrace(n + 1, 1, (PVOID*)&pc, NULL) == 1) {
+- return pc;
+- }
+- return NULL;
++ int captured = Kernel32Dll::RtlCaptureStackBackTrace(toSkip + 1, frames,
++ (PVOID*)stack, NULL);
++ for (int index = captured; index < frames; index ++) {
++ stack[index] = NULL;
++ }
++ return captured;
+ }
+
+
+@@ -1642,96 +1650,123 @@
+
+ void os::win32::print_windows_version(outputStream* st) {
+ OSVERSIONINFOEX osvi;
+- SYSTEM_INFO si;
+-
++ VS_FIXEDFILEINFO *file_info;
++ TCHAR kernel32_path[MAX_PATH];
++ UINT len, ret;
++
++ // Use the GetVersionEx information to see if we're on a server or
++ // workstation edition of Windows. Starting with Windows 8.1 we can't
++ // trust the OS version information returned by this API.
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+-
+ if (!GetVersionEx((OSVERSIONINFO *)&osvi)) {
+- st->print_cr("N/A");
++ st->print_cr("Call to GetVersionEx failed");
+ return;
+ }
+-
+- int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion;
+-
++ bool is_workstation = (osvi.wProductType == VER_NT_WORKSTATION);
++
++ // Get the full path to \Windows\System32\kernel32.dll and use that for
++ // determining what version of Windows we're running on.
++ len = MAX_PATH - (UINT)strlen("\\kernel32.dll") - 1;
++ ret = GetSystemDirectory(kernel32_path, len);
++ if (ret == 0 || ret > len) {
++ st->print_cr("Call to GetSystemDirectory failed");
++ return;
++ }
++ strncat(kernel32_path, "\\kernel32.dll", MAX_PATH - ret);
++
++ DWORD version_size = GetFileVersionInfoSize(kernel32_path, NULL);
++ if (version_size == 0) {
++ st->print_cr("Call to GetFileVersionInfoSize failed");
++ return;
++ }
++
++ LPTSTR version_info = (LPTSTR)os::malloc(version_size, mtInternal);
++ if (version_info == NULL) {
++ st->print_cr("Failed to allocate version_info");
++ return;
++ }
++
++ if (!GetFileVersionInfo(kernel32_path, NULL, version_size, version_info)) {
++ os::free(version_info);
++ st->print_cr("Call to GetFileVersionInfo failed");
++ return;
++ }
++
++ if (!VerQueryValue(version_info, TEXT("\\"), (LPVOID*)&file_info, &len)) {
++ os::free(version_info);
++ st->print_cr("Call to VerQueryValue failed");
++ return;
++ }
++
++ int major_version = HIWORD(file_info->dwProductVersionMS);
++ int minor_version = LOWORD(file_info->dwProductVersionMS);
++ int build_number = HIWORD(file_info->dwProductVersionLS);
++ int build_minor = LOWORD(file_info->dwProductVersionLS);
++ int os_vers = major_version * 1000 + minor_version;
++ os::free(version_info);
++
++ st->print(" Windows ");
++ switch (os_vers) {
++
++ case 6000:
++ if (is_workstation) {
++ st->print("Vista");
++ } else {
++ st->print("Server 2008");
++ }
++ break;
++
++ case 6001:
++ if (is_workstation) {
++ st->print("7");
++ } else {
++ st->print("Server 2008 R2");
++ }
++ break;
++
++ case 6002:
++ if (is_workstation) {
++ st->print("8");
++ } else {
++ st->print("Server 2012");
++ }
++ break;
++
++ case 6003:
++ if (is_workstation) {
++ st->print("8.1");
++ } else {
++ st->print("Server 2012 R2");
++ }
++ break;
++
++ case 6004:
++ if (is_workstation) {
++ st->print("10");
++ } else {
++ // The server version name of Windows 10 is not known at this time
++ st->print("%d.%d", major_version, minor_version);
++ }
++ break;
++
++ default:
++ // Unrecognized windows, print out its major and minor versions
++ st->print("%d.%d", major_version, minor_version);
++ break;
++ }
++
++ // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
++ // find out whether we are running on 64 bit processor or not
++ SYSTEM_INFO si;
+ ZeroMemory(&si, sizeof(SYSTEM_INFO));
+- if (os_vers >= 5002) {
+- // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
+- // find out whether we are running on 64 bit processor or not.
+- if (os::Kernel32Dll::GetNativeSystemInfoAvailable()) {
+- os::Kernel32Dll::GetNativeSystemInfo(&si);
+- } else {
+- GetSystemInfo(&si);
+- }
+- }
+-
+- if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+- switch (os_vers) {
+- case 3051: st->print(" Windows NT 3.51"); break;
+- case 4000: st->print(" Windows NT 4.0"); break;
+- case 5000: st->print(" Windows 2000"); break;
+- case 5001: st->print(" Windows XP"); break;
+- case 5002:
+- if (osvi.wProductType == VER_NT_WORKSTATION &&
+- si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
+- st->print(" Windows XP x64 Edition");
+- } else {
+- st->print(" Windows Server 2003 family");
+- }
+- break;
+-
+- case 6000:
+- if (osvi.wProductType == VER_NT_WORKSTATION) {
+- st->print(" Windows Vista");
+- } else {
+- st->print(" Windows Server 2008");
+- }
+- break;
+-
+- case 6001:
+- if (osvi.wProductType == VER_NT_WORKSTATION) {
+- st->print(" Windows 7");
+- } else {
+- st->print(" Windows Server 2008 R2");
+- }
+- break;
+-
+- case 6002:
+- if (osvi.wProductType == VER_NT_WORKSTATION) {
+- st->print(" Windows 8");
+- } else {
+- st->print(" Windows Server 2012");
+- }
+- break;
+-
+- case 6003:
+- if (osvi.wProductType == VER_NT_WORKSTATION) {
+- st->print(" Windows 8.1");
+- } else {
+- st->print(" Windows Server 2012 R2");
+- }
+- break;
+-
+- default: // future os
+- // Unrecognized windows, print out its major and minor versions
+- st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
+- }
+- } else {
+- switch (os_vers) {
+- case 4000: st->print(" Windows 95"); break;
+- case 4010: st->print(" Windows 98"); break;
+- case 4090: st->print(" Windows Me"); break;
+- default: // future windows, print out its major and minor versions
+- st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
+- }
+- }
+-
+- if (os_vers >= 6000 && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
++ os::Kernel32Dll::GetNativeSystemInfo(&si);
++ if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
+ st->print(" , 64 bit");
+ }
+
+- st->print(" Build %d", osvi.dwBuildNumber);
+- st->print(" %s", osvi.szCSDVersion); // service pack
++ st->print(" Build %d", build_number);
++ st->print(" (%d.%d.%d.%d)", major_version, minor_version, build_number, build_minor);
+ st->cr();
+ }
+
+@@ -2903,7 +2938,7 @@
+ PAGE_READWRITE);
+ // If reservation failed, return NULL
+ if (p_buf == NULL) return NULL;
+- MemTracker::record_virtual_memory_reserve((address)p_buf, size_of_reserve, mtNone, CALLER_PC);
++ MemTracker::record_virtual_memory_reserve((address)p_buf, size_of_reserve, CALLER_PC);
+ os::release_memory(p_buf, bytes + chunk_size);
+
+ // we still need to round up to a page boundary (in case we are using large pages)
+@@ -2969,7 +3004,7 @@
+ // need to create a dummy 'reserve' record to match
+ // the release.
+ MemTracker::record_virtual_memory_reserve((address)p_buf,
+- bytes_to_release, mtNone, CALLER_PC);
++ bytes_to_release, CALLER_PC);
+ os::release_memory(p_buf, bytes_to_release);
+ }
+ #ifdef ASSERT
+@@ -2988,11 +3023,10 @@
+ }
+ // Although the memory is allocated individually, it is returned as one.
+ // NMT records it as one block.
+- address pc = CALLER_PC;
+ if ((flags & MEM_COMMIT) != 0) {
+- MemTracker::record_virtual_memory_reserve_and_commit((address)p_buf, bytes, mtNone, pc);
++ MemTracker::record_virtual_memory_reserve_and_commit((address)p_buf, bytes, CALLER_PC);
+ } else {
+- MemTracker::record_virtual_memory_reserve((address)p_buf, bytes, mtNone, pc);
++ MemTracker::record_virtual_memory_reserve((address)p_buf, bytes, CALLER_PC);
+ }
+
+ // made it this far, success
+@@ -3190,8 +3224,7 @@
+ DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
+ char * res = (char *)VirtualAlloc(addr, bytes, flag, prot);
+ if (res != NULL) {
+- address pc = CALLER_PC;
+- MemTracker::record_virtual_memory_reserve_and_commit((address)res, bytes, mtNone, pc);
++ MemTracker::record_virtual_memory_reserve_and_commit((address)res, bytes, CALLER_PC);
+ }
+
+ return res;
+@@ -5344,11 +5377,6 @@
+ return ::Module32Next(hSnapshot, lpme);
+ }
+
+-
+-inline BOOL os::Kernel32Dll::GetNativeSystemInfoAvailable() {
+- return true;
+-}
+-
+ inline void os::Kernel32Dll::GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) {
+ ::GetNativeSystemInfo(lpSystemInfo);
+ }
+--- ./hotspot/src/os/windows/vm/os_windows.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/windows/vm/os_windows.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -192,7 +192,6 @@
+ static BOOL Module32First(HANDLE,LPMODULEENTRY32);
+ static BOOL Module32Next(HANDLE,LPMODULEENTRY32);
+
+- static BOOL GetNativeSystemInfoAvailable();
+ static void GetNativeSystemInfo(LPSYSTEM_INFO);
+
+ // NUMA calls
+--- ./hotspot/src/os/windows/vm/os_windows.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/windows/vm/os_windows.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,12 +26,9 @@
+ #define OS_WINDOWS_VM_OS_WINDOWS_INLINE_HPP
+
+ #include "runtime/atomic.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/os.hpp"
+
+-#ifdef TARGET_OS_ARCH_windows_x86
+-# include "orderAccess_windows_x86.inline.hpp"
+-#endif
+-
+ inline const char* os::file_separator() { return "\\"; }
+ inline const char* os::line_separator() { return "\r\n"; }
+ inline const char* os::path_separator() { return ";"; }
+--- ./hotspot/src/os/windows/vm/perfMemory_windows.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/windows/vm/perfMemory_windows.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -1498,7 +1498,8 @@
+ (void)memset(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, mtInternal, CURRENT_PC);
++ MemTracker::record_virtual_memory_reserve_and_commit((address)mapAddress,
++ size, CURRENT_PC, mtInternal);
+
+ return (char*) mapAddress;
+ }
+@@ -1680,7 +1681,8 @@
+ }
+
+ // it does not go through os api, the operation has to record from here
+- MemTracker::record_virtual_memory_reserve((address)mapAddress, size, mtInternal, CURRENT_PC);
++ MemTracker::record_virtual_memory_reserve_and_commit((address)mapAddress, size,
++ CURRENT_PC, mtInternal);
+
+
+ *addrp = (char*)mapAddress;
+@@ -1834,10 +1836,14 @@
+ return;
+ }
+
+- MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
+- remove_file_mapping(addr);
+- // it does not go through os api, the operation has to record from here
+- tkr.record((address)addr, bytes);
++ if (MemTracker::tracking_level() > NMT_minimal) {
++ // it does not go through os api, the operation has to record from here
++ Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
++ remove_file_mapping(addr);
++ tkr.record((address)addr, bytes);
++ } else {
++ remove_file_mapping(addr);
++ }
+ }
+
+ char* PerfMemory::backing_store_filename() {
+--- ./hotspot/src/os/windows/vm/thread_windows.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os/windows/vm/thread_windows.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -29,15 +29,8 @@
+ #error "This file should only be included from thread.inline.hpp"
+ #endif
+
+-#include "runtime/atomic.hpp"
+-#include "runtime/prefetch.hpp"
+ #include "runtime/thread.hpp"
+ #include "runtime/threadLocalStorage.hpp"
+-#ifdef TARGET_OS_ARCH_windows_x86
+-# include "atomic_windows_x86.inline.hpp"
+-# include "orderAccess_windows_x86.inline.hpp"
+-# include "prefetch_windows_x86.inline.hpp"
+-#endif
+
+ // Contains inlined functions for class Thread and ThreadLocalStorage
+
+--- ./hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,7 +26,6 @@
+ #ifndef OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_INLINE_HPP
+ #define OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_INLINE_HPP
+
+-#include "orderAccess_aix_ppc.inline.hpp"
+ #include "runtime/atomic.hpp"
+ #include "runtime/os.hpp"
+ #include "vm_version_ppc.hpp"
+--- ./hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -91,8 +91,9 @@
+
+ // Frame information (pc, sp, fp) retrieved via ucontext
+ // always looks like a C-frame according to the frame
+-// conventions in frame_ppc64.hpp.
+-address os::Aix::ucontext_get_pc(ucontext_t * uc) {
++// conventions in frame_ppc.hpp.
++
++address os::Aix::ucontext_get_pc(const ucontext_t * uc) {
+ return (address)uc->uc_mcontext.jmp_context.iar;
+ }
+
+@@ -486,7 +487,7 @@
+ ////////////////////////////////////////////////////////////////////////////////
+ // thread stack
+
+-size_t os::Aix::min_stack_allowed = 768*K;
++size_t os::Aix::min_stack_allowed = 128*K;
+
+ // Aix is always in floating stack mode. The stack size for a new
+ // thread can be set via pthread_attr_setstacksize().
+@@ -499,7 +500,7 @@
+ // because of the strange 'fallback logic' in os::create_thread().
+ // Better set CompilerThreadStackSize in globals_<os_cpu>.hpp if you want to
+ // specify a different stack size for compiler threads!
+- size_t s = (thr_type == os::compiler_thread ? 4 * M : 1024 * K);
++ size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
+ return s;
+ }
+
+--- ./hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -23,8 +23,8 @@
+ *
+ */
+
+-#ifndef OS_CPU_AIX_OJDKPPC_VM_OS_AIX_PPC_HPP
+-#define OS_CPU_AIX_OJDKPPC_VM_OS_AIX_PPC_HPP
++#ifndef OS_CPU_AIX_PPC_VM_OS_AIX_PPC_HPP
++#define OS_CPU_AIX_PPC_VM_OS_AIX_PPC_HPP
+
+ static void setup_fpu() {}
+
+@@ -32,4 +32,4 @@
+ // Note: Currently only used in 64 bit Windows implementations
+ static bool register_code_area(char *low, char *high) { return true; }
+
+-#endif // OS_CPU_AIX_OJDKPPC_VM_OS_AIX_PPC_HPP
++#endif // OS_CPU_AIX_PPC_VM_OS_AIX_PPC_HPP
+--- ./hotspot/src/os_cpu/aix_ppc/vm/prefetch_aix_ppc.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os_cpu/aix_ppc/vm/prefetch_aix_ppc.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -23,8 +23,8 @@
+ *
+ */
+
+-#ifndef OS_CPU_AIX_PPC_64_VM_PREFETCH_AIX_PPC_64_INLINE_HPP
+-#define OS_CPU_AIX_PPC_64_VM_PREFETCH_AIX_PPC_64_INLINE_HPP
++#ifndef OS_CPU_AIX_PPC_VM_PREFETCH_AIX_PPC_INLINE_HPP
++#define OS_CPU_AIX_PPC_VM_PREFETCH_AIX_PPC_INLINE_HPP
+
+ #include "runtime/prefetch.hpp"
+
+@@ -55,4 +55,4 @@
+ #endif
+ }
+
+-#endif // OS_CPU_AIX_PPC_64_VM_PREFETCH_AIX_PPC_64_INLINE_HPP
++#endif // OS_CPU_AIX_PPC_VM_PREFETCH_AIX_PPC_INLINE_HPP
+--- ./hotspot/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -23,8 +23,8 @@
+ *
+ */
+
+-#ifndef OS_CPU_AIX_OJDKPPC_VM_THREADLS_AIX_PPC_HPP
+-#define OS_CPU_AIX_OJDKPPC_VM_THREADLS_AIX_PPC_HPP
++#ifndef OS_CPU_AIX_PPC_VM_THREADLS_AIX_PPC_HPP
++#define OS_CPU_AIX_PPC_VM_THREADLS_AIX_PPC_HPP
+
+ // Processor dependent parts of ThreadLocalStorage
+
+@@ -33,4 +33,4 @@
+ return (Thread *) os::thread_local_storage_at(thread_index());
+ }
+
+-#endif // OS_CPU_AIX_OJDKPPC_VM_THREADLS_AIX_PPC_HPP
++#endif // OS_CPU_AIX_PPC_VM_THREADLS_AIX_PPC_HPP
+--- ./hotspot/src/os_cpu/aix_ppc/vm/thread_aix_ppc.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os_cpu/aix_ppc/vm/thread_aix_ppc.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -23,8 +23,8 @@
+ *
+ */
+
+-#ifndef OS_CPU_AIX_OJDKPPC_VM_THREAD_AIX_PPC_HPP
+-#define OS_CPU_AIX_OJDKPPC_VM_THREAD_AIX_PPC_HPP
++#ifndef OS_CPU_AIX_PPC_VM_THREAD_AIX_PPC_HPP
++#define OS_CPU_AIX_PPC_VM_THREAD_AIX_PPC_HPP
+
+ private:
+ void pd_initialize() {
+@@ -76,4 +76,4 @@
+
+ intptr_t* last_interpreter_fp() { return _last_interpreter_fp; }
+
+-#endif // OS_CPU_AIX_OJDKPPC_VM_THREAD_AIX_PPC_HPP
++#endif // OS_CPU_AIX_PPC_VM_THREAD_AIX_PPC_HPP
+--- ./hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,7 +26,6 @@
+ #ifndef OS_CPU_LINUX_PPC_VM_ATOMIC_LINUX_PPC_INLINE_HPP
+ #define OS_CPU_LINUX_PPC_VM_ATOMIC_LINUX_PPC_INLINE_HPP
+
+-#include "orderAccess_linux_ppc.inline.hpp"
+ #include "runtime/atomic.hpp"
+ #include "runtime/os.hpp"
+ #include "vm_version_ppc.hpp"
+--- ./hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,6 +1,6 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+- * Copyright 2012, 2013 SAP AG. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -307,7 +307,7 @@
+ // doesn't work for us. We use:
+ ((NativeInstruction*)pc)->is_safepoint_poll()) {
+ if (TraceTraps) {
+- tty->print_cr("trap: safepoint_poll at " INTPTR_FORMAT " (SIGSEGV)", pc);
++ tty->print_cr("trap: safepoint_poll at " INTPTR_FORMAT " (SIGSEGV)", p2i(pc));
+ }
+ stub = SharedRuntime::get_poll_stub(pc);
+ }
+@@ -316,7 +316,7 @@
+ else if (sig == SIGTRAP && TrapBasedICMissChecks &&
+ nativeInstruction_at(pc)->is_sigtrap_ic_miss_check()) {
+ if (TraceTraps) {
+- tty->print_cr("trap: ic_miss_check at " INTPTR_FORMAT " (SIGTRAP)", pc);
++ tty->print_cr("trap: ic_miss_check at " INTPTR_FORMAT " (SIGTRAP)", p2i(pc));
+ }
+ stub = SharedRuntime::get_ic_miss_stub();
+ }
+@@ -325,7 +325,7 @@
+ else if (sig == SIGTRAP && TrapBasedNullChecks &&
+ nativeInstruction_at(pc)->is_sigtrap_null_check()) {
+ if (TraceTraps) {
+- tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGTRAP)", pc);
++ tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGTRAP)", p2i(pc));
+ }
+ stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
+ }
+@@ -335,7 +335,7 @@
+ CodeCache::contains((void*) pc) &&
+ !MacroAssembler::needs_explicit_null_check((intptr_t) info->si_addr)) {
+ if (TraceTraps) {
+- tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGSEGV)", pc);
++ tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGSEGV)", p2i(pc));
+ }
+ stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
+ }
+@@ -345,7 +345,7 @@
+ else if (sig == SIGTRAP && TrapBasedRangeChecks &&
+ nativeInstruction_at(pc)->is_sigtrap_range_check()) {
+ if (TraceTraps) {
+- tty->print_cr("trap: range_check at " INTPTR_FORMAT " (SIGTRAP)", pc);
++ tty->print_cr("trap: range_check at " INTPTR_FORMAT " (SIGTRAP)", p2i(pc));
+ }
+ stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
+ }
+@@ -453,7 +453,7 @@
+ ////////////////////////////////////////////////////////////////////////////////
+ // thread stack
+
+-size_t os::Linux::min_stack_allowed = 768*K;
++size_t os::Linux::min_stack_allowed = 128*K;
+
+ bool os::Linux::supports_variable_stack_size() { return true; }
+
+@@ -572,7 +572,7 @@
+ st->cr();
+
+ intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc);
+- st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp);
++ st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", p2i(sp));
+ print_hex_dump(st, (address)sp, (address)(sp + 128), sizeof(intptr_t));
+ st->cr();
+
+@@ -580,7 +580,7 @@
+ // point to garbage if entry point in an nmethod is corrupted. Leave
+ // this at the end, and hope for the best.
+ address pc = os::Linux::ucontext_get_pc(uc);
+- st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
++ st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc));
+ print_hex_dump(st, pc - 64, pc + 64, /*instrsize=*/4);
+ st->cr();
+ }
+--- ./hotspot/src/os_cpu/linux_ppc/vm/prefetch_linux_ppc.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os_cpu/linux_ppc/vm/prefetch_linux_ppc.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -47,4 +47,4 @@
+ );
+ }
+
+-#endif // OS_CPU_LINUX_PPC_VM_PREFETCH_LINUX_OJDKPPC_HPP
++#endif // OS_CPU_LINUX_PPC_VM_PREFETCH_LINUX_PPC_INLINE_HPP
+--- ./hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -118,7 +118,7 @@
+ *ret_sp = os::Linux::ucontext_get_sp(uc);
+ }
+ if (ret_fp) {
+- *ret_fp = os::Linux::ucontext_get_fp(uc);
++ *ret_fp = (intptr_t*)NULL;
+ }
+ } else {
+ // construct empty ExtendedPC for return value checking
+@@ -136,18 +136,15 @@
+
+ frame os::fetch_frame_from_context(void* ucVoid) {
+ intptr_t* sp;
+- intptr_t* fp;
+- ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
+- return frame(sp, fp, epc.pc());
++ ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, NULL);
++ return frame(sp, frame::unpatchable, epc.pc());
+ }
+
+ frame os::get_sender_for_C_frame(frame* fr) {
+- return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
++ return frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc());
+ }
+
+ frame os::current_frame() {
+- fprintf(stderr, "current_frame()");
+-
+ intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()();
+ frame myframe(sp, frame::unpatchable,
+ CAST_FROM_FN_PTR(address, os::current_frame));
+--- ./hotspot/src/os_cpu/linux_sparc/vm/vm_version_linux_sparc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os_cpu/linux_sparc/vm/vm_version_linux_sparc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -55,7 +55,7 @@
+
+ if (detect_niagara()) {
+ NOT_PRODUCT(if (PrintMiscellaneous && Verbose) tty->print_cr("Detected Linux on Niagara");)
+- features = niagara1_m;
++ features = niagara1_m | T_family_m;
+ }
+
+ return features;
+--- ./hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -26,10 +26,216 @@
+ #include "runtime/os.hpp"
+ #include "vm_version_sparc.hpp"
+
+-# include <sys/auxv.h>
+-# include <sys/auxv_SPARC.h>
+-# include <sys/systeminfo.h>
+-# include <kstat.h>
++#include <sys/auxv.h>
++#include <sys/auxv_SPARC.h>
++#include <sys/systeminfo.h>
++#include <kstat.h>
++#include <picl.h>
++#include <dlfcn.h>
++#include <link.h>
++
++extern "C" static int PICL_get_l1_data_cache_line_size_helper(picl_nodehdl_t nodeh, void *result);
++extern "C" static int PICL_get_l2_cache_line_size_helper(picl_nodehdl_t nodeh, void *result);
++
++// Functions from the library we need (signatures should match those in picl.h)
++extern "C" {
++ typedef int (*picl_initialize_func_t)(void);
++ typedef int (*picl_shutdown_func_t)(void);
++ typedef int (*picl_get_root_func_t)(picl_nodehdl_t *nodehandle);
++ typedef int (*picl_walk_tree_by_class_func_t)(picl_nodehdl_t rooth,
++ const char *classname, void *c_args,
++ int (*callback_fn)(picl_nodehdl_t hdl, void *args));
++ typedef int (*picl_get_prop_by_name_func_t)(picl_nodehdl_t nodeh, const char *nm,
++ picl_prophdl_t *ph);
++ typedef int (*picl_get_propval_func_t)(picl_prophdl_t proph, void *valbuf, size_t sz);
++ typedef int (*picl_get_propinfo_func_t)(picl_prophdl_t proph, picl_propinfo_t *pi);
++}
++
++class PICL {
++ // Pointers to functions in the library
++ picl_initialize_func_t _picl_initialize;
++ picl_shutdown_func_t _picl_shutdown;
++ picl_get_root_func_t _picl_get_root;
++ picl_walk_tree_by_class_func_t _picl_walk_tree_by_class;
++ picl_get_prop_by_name_func_t _picl_get_prop_by_name;
++ picl_get_propval_func_t _picl_get_propval;
++ picl_get_propinfo_func_t _picl_get_propinfo;
++ // Handle to the library that is returned by dlopen
++ void *_dl_handle;
++
++ bool open_library();
++ void close_library();
++
++ template<typename FuncType> bool bind(FuncType& func, const char* name);
++ bool bind_library_functions();
++
++ // Get a value of the integer property. The value in the tree can be either 32 or 64 bit
++ // depending on the platform. The result is converted to int.
++ int get_int_property(picl_nodehdl_t nodeh, const char* name, int* result) {
++ picl_propinfo_t pinfo;
++ picl_prophdl_t proph;
++ if (_picl_get_prop_by_name(nodeh, name, &proph) != PICL_SUCCESS ||
++ _picl_get_propinfo(proph, &pinfo) != PICL_SUCCESS) {
++ return PICL_FAILURE;
++ }
++
++ if (pinfo.type != PICL_PTYPE_INT && pinfo.type != PICL_PTYPE_UNSIGNED_INT) {
++ assert(false, "Invalid property type");
++ return PICL_FAILURE;
++ }
++ if (pinfo.size == sizeof(int64_t)) {
++ int64_t val;
++ if (_picl_get_propval(proph, &val, sizeof(int64_t)) != PICL_SUCCESS) {
++ return PICL_FAILURE;
++ }
++ *result = static_cast<int>(val);
++ } else if (pinfo.size == sizeof(int32_t)) {
++ int32_t val;
++ if (_picl_get_propval(proph, &val, sizeof(int32_t)) != PICL_SUCCESS) {
++ return PICL_FAILURE;
++ }
++ *result = static_cast<int>(val);
++ } else {
++ assert(false, "Unexpected integer property size");
++ return PICL_FAILURE;
++ }
++ return PICL_SUCCESS;
++ }
++
++ // Visitor and a state machine that visits integer properties and verifies that the
++ // values are the same. Stores the unique value observed.
++ class UniqueValueVisitor {
++ PICL *_picl;
++ enum {
++ INITIAL, // Start state, no assignments happened
++ ASSIGNED, // Assigned a value
++ INCONSISTENT // Inconsistent value seen
++ } _state;
++ int _value;
++ public:
++ UniqueValueVisitor(PICL* picl) : _picl(picl), _state(INITIAL) { }
++ int value() {
++ assert(_state == ASSIGNED, "Precondition");
++ return _value;
++ }
++ void set_value(int value) {
++ assert(_state == INITIAL, "Precondition");
++ _value = value;
++ _state = ASSIGNED;
++ }
++ bool is_initial() { return _state == INITIAL; }
++ bool is_assigned() { return _state == ASSIGNED; }
++ bool is_inconsistent() { return _state == INCONSISTENT; }
++ void set_inconsistent() { _state = INCONSISTENT; }
++
++ static int visit(picl_nodehdl_t nodeh, const char* name, void *arg) {
++ UniqueValueVisitor *state = static_cast<UniqueValueVisitor*>(arg);
++ PICL* picl = state->_picl;
++ assert(!state->is_inconsistent(), "Precondition");
++ int curr;
++ if (picl->get_int_property(nodeh, name, &curr) == PICL_SUCCESS) {
++ if (!state->is_assigned()) { // first iteration
++ state->set_value(curr);
++ } else if (curr != state->value()) { // following iterations
++ state->set_inconsistent();
++ }
++ }
++ if (state->is_inconsistent()) {
++ return PICL_WALK_TERMINATE;
++ }
++ return PICL_WALK_CONTINUE;
++ }
++ };
++
++ int _L1_data_cache_line_size;
++ int _L2_cache_line_size;
++public:
++ static int get_l1_data_cache_line_size(picl_nodehdl_t nodeh, void *state) {
++ return UniqueValueVisitor::visit(nodeh, "l1-dcache-line-size", state);
++ }
++ static int get_l2_cache_line_size(picl_nodehdl_t nodeh, void *state) {
++ return UniqueValueVisitor::visit(nodeh, "l2-cache-line-size", state);
++ }
++
++ PICL() : _L1_data_cache_line_size(0), _L2_cache_line_size(0), _dl_handle(NULL) {
++ if (!open_library()) {
++ return;
++ }
++ if (_picl_initialize() == PICL_SUCCESS) {
++ picl_nodehdl_t rooth;
++ if (_picl_get_root(&rooth) == PICL_SUCCESS) {
++ UniqueValueVisitor L1_state(this);
++ // Visit all "cpu" class instances
++ _picl_walk_tree_by_class(rooth, "cpu", &L1_state, PICL_get_l1_data_cache_line_size_helper);
++ if (L1_state.is_initial()) { // Still initial, iteration found no values
++ // Try walk all "core" class instances, it might be a Fujitsu machine
++ _picl_walk_tree_by_class(rooth, "core", &L1_state, PICL_get_l1_data_cache_line_size_helper);
++ }
++ if (L1_state.is_assigned()) { // Is there a value?
++ _L1_data_cache_line_size = L1_state.value();
++ }
++
++ UniqueValueVisitor L2_state(this);
++ _picl_walk_tree_by_class(rooth, "cpu", &L2_state, PICL_get_l2_cache_line_size_helper);
++ if (L2_state.is_initial()) {
++ _picl_walk_tree_by_class(rooth, "core", &L2_state, PICL_get_l2_cache_line_size_helper);
++ }
++ if (L2_state.is_assigned()) {
++ _L2_cache_line_size = L2_state.value();
++ }
++ }
++ _picl_shutdown();
++ }
++ close_library();
++ }
++
++ unsigned int L1_data_cache_line_size() const { return _L1_data_cache_line_size; }
++ unsigned int L2_cache_line_size() const { return _L2_cache_line_size; }
++};
++
++extern "C" static int PICL_get_l1_data_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) {
++ return PICL::get_l1_data_cache_line_size(nodeh, result);
++}
++extern "C" static int PICL_get_l2_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) {
++ return PICL::get_l2_cache_line_size(nodeh, result);
++}
++
++template<typename FuncType>
++bool PICL::bind(FuncType& func, const char* name) {
++ func = reinterpret_cast<FuncType>(dlsym(_dl_handle, name));
++ return func != NULL;
++}
++
++bool PICL::bind_library_functions() {
++ assert(_dl_handle != NULL, "library should be open");
++ return bind(_picl_initialize, "picl_initialize" ) &&
++ bind(_picl_shutdown, "picl_shutdown" ) &&
++ bind(_picl_get_root, "picl_get_root" ) &&
++ bind(_picl_walk_tree_by_class, "picl_walk_tree_by_class") &&
++ bind(_picl_get_prop_by_name, "picl_get_prop_by_name" ) &&
++ bind(_picl_get_propval, "picl_get_propval" ) &&
++ bind(_picl_get_propinfo, "picl_get_propinfo" );
++}
++
++bool PICL::open_library() {
++ _dl_handle = dlopen("libpicl.so.1", RTLD_LAZY);
++ if (_dl_handle == NULL) {
++ warning("PICL (libpicl.so.1) is missing. Performance will not be optimal.");
++ return false;
++ }
++ if (!bind_library_functions()) {
++ assert(false, "unexpected PICL API change");
++ close_library();
++ return false;
++ }
++ return true;
++}
++
++void PICL::close_library() {
++ assert(_dl_handle != NULL, "library should be open");
++ dlclose(_dl_handle);
++ _dl_handle = NULL;
++}
+
+ // We need to keep these here as long as we have to build on Solaris
+ // versions before 10.
+@@ -137,6 +343,21 @@
+ #endif
+ if (av & AV_SPARC_AES) features |= aes_instructions_m;
+
++#ifndef AV_SPARC_SHA1
++#define AV_SPARC_SHA1 0x00400000 /* sha1 instruction supported */
++#endif
++ if (av & AV_SPARC_SHA1) features |= sha1_instruction_m;
++
++#ifndef AV_SPARC_SHA256
++#define AV_SPARC_SHA256 0x00800000 /* sha256 instruction supported */
++#endif
++ if (av & AV_SPARC_SHA256) features |= sha256_instruction_m;
++
++#ifndef AV_SPARC_SHA512
++#define AV_SPARC_SHA512 0x01000000 /* sha512 instruction supported */
++#endif
++ if (av & AV_SPARC_SHA512) features |= sha512_instruction_m;
++
+ } else {
+ // getisax(2) failed, use the old legacy code.
+ #ifndef PRODUCT
+@@ -248,5 +469,9 @@
+ kstat_close(kc);
+ }
+
++ // Figure out cache line sizes using PICL
++ PICL picl;
++ _L2_cache_line_size = picl.L2_cache_line_size();
++
+ return features;
+ }
+--- ./hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -635,7 +635,11 @@
+ #ifndef PRODUCT
+ void os::verify_stack_alignment() {
+ #ifdef AMD64
+- assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
++ // The current_stack_pointer() calls generated get_previous_sp stub routine.
++ // Only enable the assert after the routine becomes available.
++ if (StubRoutines::code1() != NULL) {
++ assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
++ }
+ #endif
+ }
+ #endif
+--- ./hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Wed Feb 04 12:14:39 2015 -0800
+@@ -406,9 +406,17 @@
+ } else if (scopes.peek().getCalls().size() > 2 && m == scopes.peek().last(-2).getMethod()) {
+ scopes.push(scopes.peek().last(-2));
+ } else {
+- System.out.println(site.getMethod());
+- System.out.println(m);
+- throw new InternalError("call site and parse don't match");
++ // C1 prints multiple method tags during inlining when it narrows method being inlinied.
++ // Example:
++ // ...
++ // <method id="813" holder="694" name="toString" return="695" flags="1" bytes="36" iicount="1"/>
++ // <call method="813" instr="invokevirtual"/>
++ // <inline_success reason="receiver is statically known"/>
++ // <method id="814" holder="792" name="toString" return="695" flags="1" bytes="5" iicount="3"/>
++ // <parse method="814">
++ // ...
++ site.setMethod(m);
++ scopes.push(site);
+ }
+ }
+ } else if (qname.equals("parse_done")) {
+--- ./hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java Wed Feb 04 12:14:39 2015 -0800
+@@ -398,7 +398,7 @@
+ "/export:JVM_GetThreadStateNames "+
+ "/export:JVM_GetThreadStateValues "+
+ "/export:JVM_InitAgentProperties");
+- addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib;psapi.lib");
++ addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib;psapi.lib;version.lib");
+ addAttr(rv, "OutputFile", outDll);
+ addAttr(rv, "SuppressStartupBanner", "true");
+ addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def");
+--- ./hotspot/src/share/vm/asm/codeBuffer.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/asm/codeBuffer.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -133,6 +133,10 @@
+ // free any overflow storage
+ delete _overflow_arena;
+
++ // Claim is that stack allocation ensures resources are cleaned up.
++ // This is resource clean up, let's hope that all were properly copied out.
++ free_strings();
++
+ #ifdef ASSERT
+ // Save allocation type to execute assert in ~ResourceObj()
+ // which is called after this destructor.
+@@ -268,7 +272,7 @@
+
+ GrowableArray<int>* CodeBuffer::create_patch_overflow() {
+ if (_overflow_arena == NULL) {
+- _overflow_arena = new (mtCode) Arena();
++ _overflow_arena = new (mtCode) Arena(mtCode);
+ }
+ return new (_overflow_arena) GrowableArray<int>(_overflow_arena, 8, 0, 0);
+ }
+@@ -704,7 +708,7 @@
+ relocate_code_to(&dest);
+
+ // transfer strings and comments from buffer to blob
+- dest_blob->set_strings(_strings);
++ dest_blob->set_strings(_code_strings);
+
+ // Done moving code bytes; were they the right size?
+ assert(round_to(dest.total_content_size(), oopSize) == dest_blob->content_size(), "sanity");
+@@ -1003,11 +1007,11 @@
+
+
+ void CodeBuffer::block_comment(intptr_t offset, const char * comment) {
+- _strings.add_comment(offset, comment);
++ _code_strings.add_comment(offset, comment);
+ }
+
+ const char* CodeBuffer::code_string(const char* str) {
+- return _strings.add_string(str);
++ return _code_strings.add_string(str);
+ }
+
+ class CodeString: public CHeapObj<mtCode> {
+@@ -1073,6 +1077,7 @@
+ }
+
+ void CodeStrings::add_comment(intptr_t offset, const char * comment) {
++ check_valid();
+ CodeString* c = new CodeString(comment, offset);
+ CodeString* inspos = (_strings == NULL) ? NULL : find_last(offset);
+
+@@ -1088,11 +1093,32 @@
+ }
+
+ void CodeStrings::assign(CodeStrings& other) {
++ other.check_valid();
++ // Cannot do following because CodeStrings constructor is not alway run!
++ assert(is_null(), "Cannot assign onto non-empty CodeStrings");
+ _strings = other._strings;
++ other.set_null_and_invalidate();
++}
++
++// Deep copy of CodeStrings for consistent memory management.
++// Only used for actual disassembly so this is cheaper than reference counting
++// for the "normal" fastdebug case.
++void CodeStrings::copy(CodeStrings& other) {
++ other.check_valid();
++ check_valid();
++ assert(is_null(), "Cannot copy onto non-empty CodeStrings");
++ CodeString* n = other._strings;
++ CodeString** ps = &_strings;
++ while (n != NULL) {
++ *ps = new CodeString(n->string(),n->offset());
++ ps = &((*ps)->_next);
++ n = n->next();
++ }
+ }
+
+ void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const {
+- if (_strings != NULL) {
++ check_valid();
++ if (_strings != NULL) {
+ CodeString* c = find(offset);
+ while (c && c->offset() == offset) {
+ stream->bol();
+@@ -1103,7 +1129,7 @@
+ }
+ }
+
+-
++// Also sets isNull()
+ void CodeStrings::free() {
+ CodeString* n = _strings;
+ while (n) {
+@@ -1113,10 +1139,11 @@
+ delete n;
+ n = p;
+ }
+- _strings = NULL;
++ set_null_and_invalidate();
+ }
+
+ const char* CodeStrings::add_string(const char * string) {
++ check_valid();
+ CodeString* s = new CodeString(string);
+ s->set_next(_strings);
+ _strings = s;
+--- ./hotspot/src/share/vm/asm/codeBuffer.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/asm/codeBuffer.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -27,6 +27,7 @@
+
+ #include "code/oopRecorder.hpp"
+ #include "code/relocInfo.hpp"
++#include "utilities/debug.hpp"
+
+ class CodeStrings;
+ class PhaseCFG;
+@@ -245,15 +246,39 @@
+ private:
+ #ifndef PRODUCT
+ CodeString* _strings;
++#ifdef ASSERT
++ // Becomes true after copy-out, forbids further use.
++ bool _defunct; // Zero bit pattern is "valid", see memset call in decode_env::decode_env
++#endif
+ #endif
+
+ CodeString* find(intptr_t offset) const;
+ CodeString* find_last(intptr_t offset) const;
+
++ void set_null_and_invalidate() {
++#ifndef PRODUCT
++ _strings = NULL;
++#ifdef ASSERT
++ _defunct = true;
++#endif
++#endif
++ }
++
+ public:
+ CodeStrings() {
+ #ifndef PRODUCT
+ _strings = NULL;
++#ifdef ASSERT
++ _defunct = false;
++#endif
++#endif
++ }
++
++ bool is_null() {
++#ifdef ASSERT
++ return _strings == NULL;
++#else
++ return true;
+ #endif
+ }
+
+@@ -261,8 +286,17 @@
+
+ void add_comment(intptr_t offset, const char * comment) PRODUCT_RETURN;
+ void print_block_comment(outputStream* stream, intptr_t offset) const PRODUCT_RETURN;
++ // MOVE strings from other to this; invalidate other.
+ void assign(CodeStrings& other) PRODUCT_RETURN;
++ // COPY strings from other to this; leave other valid.
++ void copy(CodeStrings& other) PRODUCT_RETURN;
+ void free() PRODUCT_RETURN;
++ // Guarantee that _strings are used at most once; assign invalidates a buffer.
++ inline void check_valid() const {
++#ifdef ASSERT
++ assert(!_defunct, "Use of invalid CodeStrings");
++#endif
++ }
+ };
+
+ // A CodeBuffer describes a memory space into which assembly
+@@ -330,7 +364,7 @@
+ csize_t _total_size; // size in bytes of combined memory buffer
+
+ OopRecorder* _oop_recorder;
+- CodeStrings _strings;
++ CodeStrings _code_strings;
+ OopRecorder _default_oop_recorder; // override with initialize_oop_recorder
+ Arena* _overflow_arena;
+
+@@ -531,7 +565,13 @@
+ void initialize_oop_recorder(OopRecorder* r);
+
+ OopRecorder* oop_recorder() const { return _oop_recorder; }
+- CodeStrings& strings() { return _strings; }
++ CodeStrings& strings() { return _code_strings; }
++
++ void free_strings() {
++ if (!_code_strings.is_null()) {
++ _code_strings.free(); // sets _strings Null as a side-effect.
++ }
++ }
+
+ // Code generation
+ void relocate(address at, RelocationHolder const& rspec, int format = 0) {
+--- ./hotspot/src/share/vm/asm/register.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/asm/register.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -275,4 +275,101 @@
+ );
+ }
+
++inline void assert_different_registers(
++ AbstractRegister a,
++ AbstractRegister b,
++ AbstractRegister c,
++ AbstractRegister d,
++ AbstractRegister e,
++ AbstractRegister f,
++ AbstractRegister g,
++ AbstractRegister h,
++ AbstractRegister i,
++ AbstractRegister j
++) {
++ assert(
++ a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j
++ && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j
++ && c != d && c != e && c != f && c != g && c != h && c != i && c != j
++ && d != e && d != f && d != g && d != h && d != i && d != j
++ && e != f && e != g && e != h && e != i && e != j
++ && f != g && f != h && f != i && f != j
++ && g != h && g != i && g != j
++ && h != i && h != j
++ && i != j,
++ err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
++ ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
++ ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
++ ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT "",
++ p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j))
++ );
++}
++
++inline void assert_different_registers(
++ AbstractRegister a,
++ AbstractRegister b,
++ AbstractRegister c,
++ AbstractRegister d,
++ AbstractRegister e,
++ AbstractRegister f,
++ AbstractRegister g,
++ AbstractRegister h,
++ AbstractRegister i,
++ AbstractRegister j,
++ AbstractRegister k
++) {
++ assert(
++ a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k
++ && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k
++ && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k
++ && d != e && d != f && d != g && d != h && d != i && d != j && d !=k
++ && e != f && e != g && e != h && e != i && e != j && e !=k
++ && f != g && f != h && f != i && f != j && f !=k
++ && g != h && g != i && g != j && g !=k
++ && h != i && h != j && h !=k
++ && i != j && i !=k
++ && j !=k,
++ err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
++ ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
++ ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
++ ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT "",
++ p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k))
++ );
++}
++
++inline void assert_different_registers(
++ AbstractRegister a,
++ AbstractRegister b,
++ AbstractRegister c,
++ AbstractRegister d,
++ AbstractRegister e,
++ AbstractRegister f,
++ AbstractRegister g,
++ AbstractRegister h,
++ AbstractRegister i,
++ AbstractRegister j,
++ AbstractRegister k,
++ AbstractRegister l
++) {
++ assert(
++ a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k && a !=l
++ && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k && b !=l
++ && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k && c !=l
++ && d != e && d != f && d != g && d != h && d != i && d != j && d !=k && d !=l
++ && e != f && e != g && e != h && e != i && e != j && e !=k && e !=l
++ && f != g && f != h && f != i && f != j && f !=k && f !=l
++ && g != h && g != i && g != j && g !=k && g !=l
++ && h != i && h != j && h !=k && h !=l
++ && i != j && i !=k && i !=l
++ && j !=k && j !=l
++ && k !=l,
++ err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
++ ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
++ ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
++ ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT
++ ", l=" INTPTR_FORMAT "",
++ p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k), p2i(l))
++ );
++}
++
+ #endif // SHARE_VM_ASM_REGISTER_HPP
+--- ./hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -327,7 +327,7 @@
+ if (t2->is_constant()) {
+ switch (t2->tag()) {
+ case intTag : if (t2->as_IntConstant()->value() == 0) set_canonical(x->x()); return;
+- case longTag : if (t2->as_IntConstant()->value() == 0) set_canonical(x->x()); return;
++ case longTag : if (t2->as_LongConstant()->value() == (jlong)0) set_canonical(x->x()); return;
+ default : ShouldNotReachHere();
+ }
+ }
+@@ -808,28 +808,41 @@
+
+ static bool match_index_and_scale(Instruction* instr,
+ Instruction** index,
+- int* log2_scale,
+- Instruction** instr_to_unpin) {
+- *instr_to_unpin = NULL;
+-
+- // Skip conversion ops
++ int* log2_scale) {
++ // Skip conversion ops. This works only on 32bit because of the implicit l2i that the
++ // unsafe performs.
++#ifndef _LP64
+ Convert* convert = instr->as_Convert();
+- if (convert != NULL) {
++ if (convert != NULL && convert->op() == Bytecodes::_i2l) {
++ assert(convert->value()->type() == intType, "invalid input type");
+ instr = convert->value();
+ }
++#endif
+
+ ShiftOp* shift = instr->as_ShiftOp();
+ if (shift != NULL) {
+- if (shift->is_pinned()) {
+- *instr_to_unpin = shift;
++ if (shift->op() == Bytecodes::_lshl) {
++ assert(shift->x()->type() == longType, "invalid input type");
++ } else {
++#ifndef _LP64
++ if (shift->op() == Bytecodes::_ishl) {
++ assert(shift->x()->type() == intType, "invalid input type");
++ } else {
++ return false;
++ }
++#else
++ return false;
++#endif
+ }
++
++
+ // Constant shift value?
+ Constant* con = shift->y()->as_Constant();
+ if (con == NULL) return false;
+ // Well-known type and value?
+ IntConstant* val = con->type()->as_IntConstant();
+- if (val == NULL) return false;
+- if (shift->x()->type() != intType) return false;
++ assert(val != NULL, "Should be an int constant");
++
+ *index = shift->x();
+ int tmp_scale = val->value();
+ if (tmp_scale >= 0 && tmp_scale < 4) {
+@@ -842,31 +855,42 @@
+
+ ArithmeticOp* arith = instr->as_ArithmeticOp();
+ if (arith != NULL) {
+- if (arith->is_pinned()) {
+- *instr_to_unpin = arith;
++ // See if either arg is a known constant
++ Constant* con = arith->x()->as_Constant();
++ if (con != NULL) {
++ *index = arith->y();
++ } else {
++ con = arith->y()->as_Constant();
++ if (con == NULL) return false;
++ *index = arith->x();
+ }
++ long const_value;
+ // Check for integer multiply
+- if (arith->op() == Bytecodes::_imul) {
+- // See if either arg is a known constant
+- Constant* con = arith->x()->as_Constant();
+- if (con != NULL) {
+- *index = arith->y();
++ if (arith->op() == Bytecodes::_lmul) {
++ assert((*index)->type() == longType, "invalid input type");
++ LongConstant* val = con->type()->as_LongConstant();
++ assert(val != NULL, "expecting a long constant");
++ const_value = val->value();
++ } else {
++#ifndef _LP64
++ if (arith->op() == Bytecodes::_imul) {
++ assert((*index)->type() == intType, "invalid input type");
++ IntConstant* val = con->type()->as_IntConstant();
++ assert(val != NULL, "expecting an int constant");
++ const_value = val->value();
+ } else {
+- con = arith->y()->as_Constant();
+- if (con == NULL) return false;
+- *index = arith->x();
++ return false;
+ }
+- if ((*index)->type() != intType) return false;
+- // Well-known type and value?
+- IntConstant* val = con->type()->as_IntConstant();
+- if (val == NULL) return false;
+- switch (val->value()) {
+- case 1: *log2_scale = 0; return true;
+- case 2: *log2_scale = 1; return true;
+- case 4: *log2_scale = 2; return true;
+- case 8: *log2_scale = 3; return true;
+- default: return false;
+- }
++#else
++ return false;
++#endif
++ }
++ switch (const_value) {
++ case 1: *log2_scale = 0; return true;
++ case 2: *log2_scale = 1; return true;
++ case 4: *log2_scale = 2; return true;
++ case 8: *log2_scale = 3; return true;
++ default: return false;
+ }
+ }
+
+@@ -879,29 +903,37 @@
+ Instruction** base,
+ Instruction** index,
+ int* log2_scale) {
+- Instruction* instr_to_unpin = NULL;
+ ArithmeticOp* root = x->base()->as_ArithmeticOp();
+ if (root == NULL) return false;
+ // Limit ourselves to addition for now
+ if (root->op() != Bytecodes::_ladd) return false;
++
++ bool match_found = false;
+ // Try to find shift or scale op
+- if (match_index_and_scale(root->y(), index, log2_scale, &instr_to_unpin)) {
++ if (match_index_and_scale(root->y(), index, log2_scale)) {
+ *base = root->x();
+- } else if (match_index_and_scale(root->x(), index, log2_scale, &instr_to_unpin)) {
++ match_found = true;
++ } else if (match_index_and_scale(root->x(), index, log2_scale)) {
+ *base = root->y();
+- } else if (root->y()->as_Convert() != NULL) {
++ match_found = true;
++ } else if (NOT_LP64(root->y()->as_Convert() != NULL) LP64_ONLY(false)) {
++ // Skipping i2l works only on 32bit because of the implicit l2i that the unsafe performs.
++ // 64bit needs a real sign-extending conversion.
+ Convert* convert = root->y()->as_Convert();
+- if (convert->op() == Bytecodes::_i2l && convert->value()->type() == intType) {
++ if (convert->op() == Bytecodes::_i2l) {
++ assert(convert->value()->type() == intType, "should be an int");
+ // pick base and index, setting scale at 1
+ *base = root->x();
+ *index = convert->value();
+ *log2_scale = 0;
+- } else {
+- return false;
++ match_found = true;
+ }
+- } else {
+- // doesn't match any expected sequences
+- return false;
++ }
++ // The default solution
++ if (!match_found) {
++ *base = root->x();
++ *index = root->y();
++ *log2_scale = 0;
+ }
+
+ // If the value is pinned then it will be always be computed so
+--- ./hotspot/src/share/vm/c1/c1_Compiler.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/c1/c1_Compiler.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -47,7 +47,7 @@
+
+ void Compiler::init_c1_runtime() {
+ BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob();
+- Arena* arena = new (mtCompiler) Arena();
++ Arena* arena = new (mtCompiler) Arena(mtCompiler);
+ Runtime1::initialize(buffer_blob);
+ FrameMap::initialize();
+ // initialize data structures
+--- ./hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -2061,7 +2061,7 @@
+ bool will_link;
+ ciKlass* klass = stream()->get_klass(will_link);
+ assert(klass->is_instance_klass(), "must be an instance klass");
+- NewInstance* new_instance = new NewInstance(klass->as_instance_klass(), state_before);
++ NewInstance* new_instance = new NewInstance(klass->as_instance_klass(), state_before, stream()->is_unresolved_klass());
+ _memory->new_instance(new_instance);
+ apush(append_split(new_instance));
+ }
+@@ -3960,10 +3960,15 @@
+ // Clear out bytecode stream
+ scope_data()->set_stream(NULL);
+
++ CompileLog* log = compilation()->log();
++ if (log != NULL) log->head("parse method='%d'", log->identify(callee));
++
+ // Ready to resume parsing in callee (either in the same block we
+ // were in before or in the callee's start block)
+ iterate_all_blocks(callee_start_block == NULL);
+
++ if (log != NULL) log->done("parse");
++
+ // If we bailed out during parsing, return immediately (this is bad news)
+ if (bailed_out())
+ return false;
+--- ./hotspot/src/share/vm/c1/c1_Instruction.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/c1/c1_Instruction.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1291,16 +1291,18 @@
+ LEAF(NewInstance, StateSplit)
+ private:
+ ciInstanceKlass* _klass;
++ bool _is_unresolved;
+
+ public:
+ // creation
+- NewInstance(ciInstanceKlass* klass, ValueStack* state_before)
++ NewInstance(ciInstanceKlass* klass, ValueStack* state_before, bool is_unresolved)
+ : StateSplit(instanceType, state_before)
+- , _klass(klass)
++ , _klass(klass), _is_unresolved(is_unresolved)
+ {}
+
+ // accessors
+ ciInstanceKlass* klass() const { return _klass; }
++ bool is_unresolved() const { return _is_unresolved; }
+
+ virtual bool needs_exception_state() const { return false; }
+
+--- ./hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -466,8 +466,11 @@
+ }
+
+
+-void LIRGenerator::klass2reg_with_patching(LIR_Opr r, ciMetadata* obj, CodeEmitInfo* info) {
+- if (!obj->is_loaded() || PatchALot) {
++void LIRGenerator::klass2reg_with_patching(LIR_Opr r, ciMetadata* obj, CodeEmitInfo* info, bool need_resolve) {
++ /* C2 relies on constant pool entries being resolved (ciTypeFlow), so if TieredCompilation
++ * is active and the class hasn't yet been resolved we need to emit a patch that resolves
++ * the class. */
++ if ((TieredCompilation && need_resolve) || !obj->is_loaded() || PatchALot) {
+ assert(info != NULL, "info must be set if class is not loaded");
+ __ klass2reg_patch(NULL, r, info);
+ } else {
+@@ -660,9 +663,18 @@
+ __ unlock_object(hdr, object, lock, scratch, slow_path);
+ }
+
+-
+-void LIRGenerator::new_instance(LIR_Opr dst, ciInstanceKlass* klass, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr klass_reg, CodeEmitInfo* info) {
+- klass2reg_with_patching(klass_reg, klass, info);
++#ifndef PRODUCT
++void LIRGenerator::print_if_not_loaded(const NewInstance* new_instance) {
++ if (PrintNotLoaded && !new_instance->klass()->is_loaded()) {
++ tty->print_cr(" ###class not loaded at new bci %d", new_instance->printable_bci());
++ } else if (PrintNotLoaded && (TieredCompilation && new_instance->is_unresolved())) {
++ tty->print_cr(" ###class not resolved at new bci %d", new_instance->printable_bci());
++ }
++}
++#endif
++
++void LIRGenerator::new_instance(LIR_Opr dst, ciInstanceKlass* klass, bool is_unresolved, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr klass_reg, CodeEmitInfo* info) {
++ klass2reg_with_patching(klass_reg, klass, info, is_unresolved);
+ // If klass is not loaded we do not know if the klass has finalizers:
+ if (UseFastNewInstance && klass->is_loaded()
+ && !Klass::layout_helper_needs_slow_path(klass->layout_helper())) {
+@@ -2030,6 +2042,8 @@
+ }
+ }
+
++// Here UnsafeGetRaw may have x->base() and x->index() be int or long
++// on both 64 and 32 bits. Expecting x->base() to be always long on 64bit.
+ void LIRGenerator::do_UnsafeGetRaw(UnsafeGetRaw* x) {
+ LIRItem base(x->base(), this);
+ LIRItem idx(this);
+@@ -2044,50 +2058,73 @@
+
+ int log2_scale = 0;
+ if (x->has_index()) {
+- assert(x->index()->type()->tag() == intTag, "should not find non-int index");
+ log2_scale = x->log2_scale();
+ }
+
+ assert(!x->has_index() || idx.value() == x->index(), "should match");
+
+ LIR_Opr base_op = base.result();
++ LIR_Opr index_op = idx.result();
+ #ifndef _LP64
+- if (x->base()->type()->tag() == longTag) {
++ if (base_op->type() == T_LONG) {
+ base_op = new_register(T_INT);
+ __ convert(Bytecodes::_l2i, base.result(), base_op);
+- } else {
+- assert(x->base()->type()->tag() == intTag, "must be");
+ }
++ if (x->has_index()) {
++ if (index_op->type() == T_LONG) {
++ LIR_Opr long_index_op = index_op;
++ if (index_op->is_constant()) {
++ long_index_op = new_register(T_LONG);
++ __ move(index_op, long_index_op);
++ }
++ index_op = new_register(T_INT);
++ __ convert(Bytecodes::_l2i, long_index_op, index_op);
++ } else {
++ assert(x->index()->type()->tag() == intTag, "must be");
++ }
++ }
++ // At this point base and index should be all ints.
++ assert(base_op->type() == T_INT && !base_op->is_constant(), "base should be an non-constant int");
++ assert(!x->has_index() || index_op->type() == T_INT, "index should be an int");
++#else
++ if (x->has_index()) {
++ if (index_op->type() == T_INT) {
++ if (!index_op->is_constant()) {
++ index_op = new_register(T_LONG);
++ __ convert(Bytecodes::_i2l, idx.result(), index_op);
++ }
++ } else {
++ assert(index_op->type() == T_LONG, "must be");
++ if (index_op->is_constant()) {
++ index_op = new_register(T_LONG);
++ __ move(idx.result(), index_op);
++ }
++ }
++ }
++ // At this point base is a long non-constant
++ // Index is a long register or a int constant.
++ // We allow the constant to stay an int because that would allow us a more compact encoding by
++ // embedding an immediate offset in the address expression. If we have a long constant, we have to
++ // move it into a register first.
++ assert(base_op->type() == T_LONG && !base_op->is_constant(), "base must be a long non-constant");
++ assert(!x->has_index() || (index_op->type() == T_INT && index_op->is_constant()) ||
++ (index_op->type() == T_LONG && !index_op->is_constant()), "unexpected index type");
+ #endif
+
+ BasicType dst_type = x->basic_type();
+- LIR_Opr index_op = idx.result();
+
+ LIR_Address* addr;
+ if (index_op->is_constant()) {
+ assert(log2_scale == 0, "must not have a scale");
++ assert(index_op->type() == T_INT, "only int constants supported");
+ addr = new LIR_Address(base_op, index_op->as_jint(), dst_type);
+ } else {
+ #ifdef X86
+-#ifdef _LP64
+- if (!index_op->is_illegal() && index_op->type() == T_INT) {
+- LIR_Opr tmp = new_pointer_register();
+- __ convert(Bytecodes::_i2l, index_op, tmp);
+- index_op = tmp;
+- }
+-#endif
+ addr = new LIR_Address(base_op, index_op, LIR_Address::Scale(log2_scale), 0, dst_type);
+ #elif defined(ARM)
+ addr = generate_address(base_op, index_op, log2_scale, 0, dst_type);
+ #else
+ if (index_op->is_illegal() || log2_scale == 0) {
+-#ifdef _LP64
+- if (!index_op->is_illegal() && index_op->type() == T_INT) {
+- LIR_Opr tmp = new_pointer_register();
+- __ convert(Bytecodes::_i2l, index_op, tmp);
+- index_op = tmp;
+- }
+-#endif
+ addr = new LIR_Address(base_op, index_op, dst_type);
+ } else {
+ LIR_Opr tmp = new_pointer_register();
+@@ -2114,7 +2151,6 @@
+ BasicType type = x->basic_type();
+
+ if (x->has_index()) {
+- assert(x->index()->type()->tag() == intTag, "should not find non-int index");
+ log2_scale = x->log2_scale();
+ }
+
+@@ -2137,38 +2173,39 @@
+ set_no_result(x);
+
+ LIR_Opr base_op = base.result();
++ LIR_Opr index_op = idx.result();
++
+ #ifndef _LP64
+- if (x->base()->type()->tag() == longTag) {
++ if (base_op->type() == T_LONG) {
+ base_op = new_register(T_INT);
+ __ convert(Bytecodes::_l2i, base.result(), base_op);
+- } else {
+- assert(x->base()->type()->tag() == intTag, "must be");
+ }
++ if (x->has_index()) {
++ if (index_op->type() == T_LONG) {
++ index_op = new_register(T_INT);
++ __ convert(Bytecodes::_l2i, idx.result(), index_op);
++ }
++ }
++ // At this point base and index should be all ints and not constants
++ assert(base_op->type() == T_INT && !base_op->is_constant(), "base should be an non-constant int");
++ assert(!x->has_index() || (index_op->type() == T_INT && !index_op->is_constant()), "index should be an non-constant int");
++#else
++ if (x->has_index()) {
++ if (index_op->type() == T_INT) {
++ index_op = new_register(T_LONG);
++ __ convert(Bytecodes::_i2l, idx.result(), index_op);
++ }
++ }
++ // At this point base and index are long and non-constant
++ assert(base_op->type() == T_LONG && !base_op->is_constant(), "base must be a non-constant long");
++ assert(!x->has_index() || (index_op->type() == T_LONG && !index_op->is_constant()), "index must be a non-constant long");
+ #endif
+
+- LIR_Opr index_op = idx.result();
+ if (log2_scale != 0) {
+ // temporary fix (platform dependent code without shift on Intel would be better)
+- index_op = new_pointer_register();
+-#ifdef _LP64
+- if(idx.result()->type() == T_INT) {
+- __ convert(Bytecodes::_i2l, idx.result(), index_op);
+- } else {
+-#endif
+- // TODO: ARM also allows embedded shift in the address
+- __ move(idx.result(), index_op);
+-#ifdef _LP64
+- }
+-#endif
++ // TODO: ARM also allows embedded shift in the address
+ __ shift_left(index_op, log2_scale, index_op);
+ }
+-#ifdef _LP64
+- else if(!index_op->is_illegal() && index_op->type() == T_INT) {
+- LIR_Opr tmp = new_pointer_register();
+- __ convert(Bytecodes::_i2l, index_op, tmp);
+- index_op = tmp;
+- }
+-#endif
+
+ LIR_Address* addr = new LIR_Address(base_op, index_op, x->basic_type());
+ __ move(value.result(), addr);
+--- ./hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -169,6 +169,8 @@
+ return this;
+ }
+
++ void print_if_not_loaded(const NewInstance* new_instance) PRODUCT_RETURN;
++
+ #ifdef ASSERT
+ LIR_List* lir(const char * file, int line) const {
+ _lir->set_file_and_line(file, line);
+@@ -307,7 +309,7 @@
+
+ void store_stack_parameter (LIR_Opr opr, ByteSize offset_from_sp_in_bytes);
+
+- void klass2reg_with_patching(LIR_Opr r, ciMetadata* obj, CodeEmitInfo* info);
++ void klass2reg_with_patching(LIR_Opr r, ciMetadata* obj, CodeEmitInfo* info, bool need_resolve = false);
+
+ // this loads the length and compares against the index
+ void array_range_check (LIR_Opr array, LIR_Opr index, CodeEmitInfo* null_check_info, CodeEmitInfo* range_check_info);
+@@ -325,7 +327,7 @@
+ void monitor_enter (LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, LIR_Opr scratch, int monitor_no, CodeEmitInfo* info_for_exception, CodeEmitInfo* info);
+ void monitor_exit (LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, LIR_Opr scratch, int monitor_no);
+
+- void new_instance (LIR_Opr dst, ciInstanceKlass* klass, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr klass_reg, CodeEmitInfo* info);
++ void new_instance (LIR_Opr dst, ciInstanceKlass* klass, bool is_unresolved, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr klass_reg, CodeEmitInfo* info);
+
+ // machine dependent
+ void cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info);
+--- ./hotspot/src/share/vm/c1/c1_LinearScan.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/c1/c1_LinearScan.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1628,25 +1628,22 @@
+ Interval* precolored_cpu_intervals, *not_precolored_cpu_intervals;
+ Interval* precolored_fpu_intervals, *not_precolored_fpu_intervals;
+
+- create_unhandled_lists(&precolored_cpu_intervals, &not_precolored_cpu_intervals, is_precolored_cpu_interval, is_virtual_cpu_interval);
+- if (has_fpu_registers()) {
+- create_unhandled_lists(&precolored_fpu_intervals, &not_precolored_fpu_intervals, is_precolored_fpu_interval, is_virtual_fpu_interval);
+-#ifdef ASSERT
+- } else {
+- // fpu register allocation is omitted because no virtual fpu registers are present
+- // just check this again...
+- create_unhandled_lists(&precolored_fpu_intervals, &not_precolored_fpu_intervals, is_precolored_fpu_interval, is_virtual_fpu_interval);
+- assert(not_precolored_fpu_intervals == Interval::end(), "missed an uncolored fpu interval");
+-#endif
+- }
+-
+ // allocate cpu registers
++ create_unhandled_lists(&precolored_cpu_intervals, &not_precolored_cpu_intervals,
++ is_precolored_cpu_interval, is_virtual_cpu_interval);
++
++ // allocate fpu registers
++ create_unhandled_lists(&precolored_fpu_intervals, &not_precolored_fpu_intervals,
++ is_precolored_fpu_interval, is_virtual_fpu_interval);
++
++ // the fpu interval allocation cannot be moved down below with the fpu section as
++ // the cpu_lsw.walk() changes interval positions.
++
+ LinearScanWalker cpu_lsw(this, precolored_cpu_intervals, not_precolored_cpu_intervals);
+ cpu_lsw.walk();
+ cpu_lsw.finish_allocation();
+
+ if (has_fpu_registers()) {
+- // allocate fpu registers
+ LinearScanWalker fpu_lsw(this, precolored_fpu_intervals, not_precolored_fpu_intervals);
+ fpu_lsw.walk();
+ fpu_lsw.finish_allocation();
+--- ./hotspot/src/share/vm/c1/c1_Runtime1.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/c1/c1_Runtime1.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -544,13 +544,18 @@
+ // normal bytecode execution.
+ thread->clear_exception_oop_and_pc();
+
++ Handle original_exception(thread, exception());
++
+ continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false);
+ // If an exception was thrown during exception dispatch, the exception oop may have changed
+ thread->set_exception_oop(exception());
+ thread->set_exception_pc(pc);
+
+ // the exception cache is used only by non-implicit exceptions
+- if (continuation != NULL) {
++ // Update the exception cache only when there didn't happen
++ // another exception during the computation of the compiled
++ // exception handler.
++ if (continuation != NULL && original_exception() == exception()) {
+ nm->add_handler_for_exception_and_pc(exception, pc, continuation);
+ }
+ }
+@@ -1018,6 +1023,7 @@
+ n_copy->set_data((intx) (load_klass()));
+ } else {
+ assert(mirror() != NULL, "klass not set");
++ // Don't need a G1 pre-barrier here since we assert above that data isn't an oop.
+ n_copy->set_data(cast_from_oop<intx>(mirror()));
+ }
+
+--- ./hotspot/src/share/vm/c1/c1_globals.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/c1/c1_globals.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -287,9 +287,6 @@
+ develop(bool, InstallMethods, true, \
+ "Install methods at the end of successful compilations") \
+ \
+- product(intx, CompilationRepeat, 0, \
+- "Number of times to recompile method before returning result") \
+- \
+ develop(intx, NMethodSizeLimit, (64*K)*wordSize, \
+ "Maximum size of a compiled method.") \
+ \
+--- ./hotspot/src/share/vm/ci/ciEnv.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/ci/ciEnv.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -51,6 +51,7 @@
+ #include "runtime/init.hpp"
+ #include "runtime/reflection.hpp"
+ #include "runtime/sharedRuntime.hpp"
++#include "runtime/thread.inline.hpp"
+ #include "utilities/dtrace.hpp"
+ #include "utilities/macros.hpp"
+ #ifdef COMPILER1
+@@ -85,7 +86,8 @@
+
+ // ------------------------------------------------------------------
+ // ciEnv::ciEnv
+-ciEnv::ciEnv(CompileTask* task, int system_dictionary_modification_counter) {
++ciEnv::ciEnv(CompileTask* task, int system_dictionary_modification_counter)
++ : _ciEnv_arena(mtCompiler) {
+ VM_ENTRY_MARK;
+
+ // Set up ciEnv::current immediately, for the sake of ciObjectFactory, etc.
+@@ -138,7 +140,7 @@
+ _the_min_jint_string = NULL;
+ }
+
+-ciEnv::ciEnv(Arena* arena) {
++ciEnv::ciEnv(Arena* arena) : _ciEnv_arena(mtCompiler) {
+ ASSERT_IN_VM;
+
+ // Set up ciEnv::current immediately, for the sake of ciObjectFactory, etc.
+@@ -557,7 +559,12 @@
+ oop obj = cpool->resolved_references()->obj_at(cache_index);
+ if (obj != NULL) {
+ ciObject* ciobj = get_object(obj);
+- return ciConstant(T_OBJECT, ciobj);
++ if (ciobj->is_array()) {
++ return ciConstant(T_ARRAY, ciobj);
++ } else {
++ assert(ciobj->is_instance(), "should be an instance");
++ return ciConstant(T_OBJECT, ciobj);
++ }
+ }
+ index = cpool->object_to_cp_index(cache_index);
+ }
+@@ -584,8 +591,12 @@
+ }
+ }
+ ciObject* constant = get_object(string);
+- assert (constant->is_instance(), "must be an instance, or not? ");
+- return ciConstant(T_OBJECT, constant);
++ if (constant->is_array()) {
++ return ciConstant(T_ARRAY, constant);
++ } else {
++ assert (constant->is_instance(), "must be an instance, or not? ");
++ return ciConstant(T_OBJECT, constant);
++ }
+ } else if (tag.is_klass() || tag.is_unresolved_klass()) {
+ // 4881222: allow ldc to take a class type
+ ciKlass* klass = get_klass_by_index_impl(cpool, index, ignore_will_link, accessor);
+@@ -1110,9 +1121,6 @@
+ // ------------------------------------------------------------------
+ // ciEnv::record_failure()
+ void ciEnv::record_failure(const char* reason) {
+- if (log() != NULL) {
+- log()->elem("failure reason='%s'", reason);
+- }
+ if (_failure_reason == NULL) {
+ // Record the first failure reason.
+ _failure_reason = reason;
+--- ./hotspot/src/share/vm/ci/ciEnv.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/ci/ciEnv.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -184,6 +184,10 @@
+ }
+ }
+
++ void ensure_metadata_alive(ciMetadata* m) {
++ _factory->ensure_metadata_alive(m);
++ }
++
+ ciInstance* get_instance(oop o) {
+ if (o == NULL) return NULL;
+ return get_object(o)->as_instance();
+--- ./hotspot/src/share/vm/ci/ciKlass.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/ci/ciKlass.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -43,6 +43,7 @@
+ friend class ciMethod;
+ friend class ciMethodData;
+ friend class ciObjArrayKlass;
++ friend class ciReceiverTypeData;
+
+ private:
+ ciSymbol* _name;
+--- ./hotspot/src/share/vm/ci/ciMethod.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/ci/ciMethod.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -68,7 +68,10 @@
+ // ciMethod::ciMethod
+ //
+ // Loaded method.
+-ciMethod::ciMethod(methodHandle h_m) : ciMetadata(h_m()) {
++ciMethod::ciMethod(methodHandle h_m, ciInstanceKlass* holder) :
++ ciMetadata(h_m()),
++ _holder(holder)
++{
+ assert(h_m() != NULL, "no null method");
+
+ // These fields are always filled in in loaded methods.
+@@ -124,7 +127,6 @@
+ // generating _signature may allow GC and therefore move m.
+ // These fields are always filled in.
+ _name = env->get_symbol(h_m()->name());
+- _holder = env->get_instance_klass(h_m()->method_holder());
+ ciSymbol* sig_symbol = env->get_symbol(h_m()->signature());
+ constantPoolHandle cpool = h_m()->constants();
+ _signature = new (env->arena()) ciSignature(_holder, cpool, sig_symbol);
+@@ -1106,6 +1108,22 @@
+ }
+
+ // ------------------------------------------------------------------
++// ciMethod::has_option_value
++//
++template<typename T>
++bool ciMethod::has_option_value(const char* option, T& value) {
++ check_is_loaded();
++ VM_ENTRY_MARK;
++ methodHandle mh(THREAD, get_Method());
++ return CompilerOracle::has_option_value(mh, option, value);
++}
++// Explicit instantiation for all OptionTypes supported.
++template bool ciMethod::has_option_value<intx>(const char* option, intx& value);
++template bool ciMethod::has_option_value<uintx>(const char* option, uintx& value);
++template bool ciMethod::has_option_value<bool>(const char* option, bool& value);
++template bool ciMethod::has_option_value<ccstr>(const char* option, ccstr& value);
++
++// ------------------------------------------------------------------
+ // ciMethod::can_be_compiled
+ //
+ // Have previous compilations of this method succeeded?
+--- ./hotspot/src/share/vm/ci/ciMethod.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/ci/ciMethod.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -90,7 +90,7 @@
+ BCEscapeAnalyzer* _bcea;
+ #endif
+
+- ciMethod(methodHandle h_m);
++ ciMethod(methodHandle h_m, ciInstanceKlass* holder);
+ ciMethod(ciInstanceKlass* holder, ciSymbol* name, ciSymbol* signature, ciInstanceKlass* accessor);
+
+ Method* get_Method() const {
+@@ -264,6 +264,8 @@
+ bool should_print_assembly();
+ bool break_at_execute();
+ bool has_option(const char *option);
++ template<typename T>
++ bool has_option_value(const char* option, T& value);
+ bool can_be_compiled();
+ bool can_be_osr_compiled(int entry_bci);
+ void set_not_compilable(const char* reason = NULL);
+--- ./hotspot/src/share/vm/ci/ciMethodData.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/ci/ciMethodData.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -170,6 +170,7 @@
+ Klass* k = data->as_ReceiverTypeData()->receiver(row);
+ if (k != NULL) {
+ ciKlass* klass = CURRENT_ENV->get_klass(k);
++ CURRENT_ENV->ensure_metadata_alive(klass);
+ set_receiver(row, klass);
+ }
+ }
+@@ -191,6 +192,7 @@
+ void ciSpeculativeTrapData::translate_from(const ProfileData* data) {
+ Method* m = data->as_SpeculativeTrapData()->method();
+ ciMethod* ci_m = CURRENT_ENV->get_method(m);
++ CURRENT_ENV->ensure_metadata_alive(ci_m);
+ set_method(ci_m);
+ }
+
+--- ./hotspot/src/share/vm/ci/ciMethodData.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/ci/ciMethodData.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -70,6 +70,7 @@
+ Klass* v = TypeEntries::valid_klass(k);
+ if (v != NULL) {
+ ciKlass* klass = CURRENT_ENV->get_klass(v);
++ CURRENT_ENV->ensure_metadata_alive(klass);
+ return with_status(klass, k);
+ }
+ return with_status(NULL, k);
+--- ./hotspot/src/share/vm/ci/ciObjectFactory.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/ci/ciObjectFactory.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -46,6 +46,9 @@
+ #include "oops/oop.inline.hpp"
+ #include "oops/oop.inline2.hpp"
+ #include "runtime/fieldType.hpp"
++#if INCLUDE_ALL_GCS
++# include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
++#endif
+
+ // ciObjectFactory
+ //
+@@ -109,7 +112,7 @@
+ // This Arena is long lived and exists in the resource mark of the
+ // compiler thread that initializes the initial ciObjectFactory which
+ // creates the shared ciObjects that all later ciObjectFactories use.
+- Arena* arena = new (mtCompiler) Arena();
++ Arena* arena = new (mtCompiler) Arena(mtCompiler);
+ ciEnv initial(arena);
+ ciEnv* env = ciEnv::current();
+ env->_factory->init_shared_objects();
+@@ -236,7 +239,7 @@
+ ciObject* ciObjectFactory::get(oop key) {
+ ASSERT_IN_VM;
+
+- assert(key == NULL || Universe::heap()->is_in_reserved(key), "must be");
++ assert(Universe::heap()->is_in_reserved(key), "must be");
+
+ NonPermObject* &bucket = find_non_perm(key);
+ if (bucket != NULL) {
+@@ -257,10 +260,10 @@
+ }
+
+ // ------------------------------------------------------------------
+-// ciObjectFactory::get
++// ciObjectFactory::get_metadata
+ //
+-// Get the ciObject corresponding to some oop. If the ciObject has
+-// already been created, it is returned. Otherwise, a new ciObject
++// Get the ciMetadata corresponding to some Metadata. If the ciMetadata has
++// already been created, it is returned. Otherwise, a new ciMetadata
+ // is created.
+ ciMetadata* ciObjectFactory::get_metadata(Metadata* key) {
+ ASSERT_IN_VM;
+@@ -287,9 +290,9 @@
+ }
+ #endif
+ if (!is_found_at(index, key, _ci_metadata)) {
+- // The ciObject does not yet exist. Create it and insert it
++ // The ciMetadata does not yet exist. Create it and insert it
+ // into the cache.
+- ciMetadata* new_object = create_new_object(key);
++ ciMetadata* new_object = create_new_metadata(key);
+ init_ident_of(new_object);
+ assert(new_object->is_metadata(), "must be");
+
+@@ -341,15 +344,28 @@
+ }
+
+ // ------------------------------------------------------------------
+-// ciObjectFactory::create_new_object
++// ciObjectFactory::create_new_metadata
+ //
+-// Create a new ciObject from a Metadata*.
++// Create a new ciMetadata from a Metadata*.
+ //
+-// Implementation note: this functionality could be virtual behavior
+-// of the oop itself. For now, we explicitly marshal the object.
+-ciMetadata* ciObjectFactory::create_new_object(Metadata* o) {
++// Implementation note: in order to keep Metadata live, an auxiliary ciObject
++// is used, which points to it's holder.
++ciMetadata* ciObjectFactory::create_new_metadata(Metadata* o) {
+ EXCEPTION_CONTEXT;
+
++ // Hold metadata from unloading by keeping it's holder alive.
++ if (_initialized && o->is_klass()) {
++ Klass* holder = ((Klass*)o);
++ if (holder->oop_is_instance() && InstanceKlass::cast(holder)->is_anonymous()) {
++ // Though ciInstanceKlass records class loader oop, it's not enough to keep
++ // VM anonymous classes alive (loader == NULL). Klass holder should be used instead.
++ // It is enough to record a ciObject, since cached elements are never removed
++ // during ciObjectFactory lifetime. ciObjectFactory itself is created for
++ // every compilation and lives for the whole duration of the compilation.
++ ciObject* h = get(holder->klass_holder());
++ }
++ }
++
+ if (o->is_klass()) {
+ KlassHandle h_k(THREAD, (Klass*)o);
+ Klass* k = (Klass*)o;
+@@ -362,18 +378,51 @@
+ }
+ } else if (o->is_method()) {
+ methodHandle h_m(THREAD, (Method*)o);
+- return new (arena()) ciMethod(h_m);
++ ciEnv *env = CURRENT_THREAD_ENV;
++ ciInstanceKlass* holder = env->get_instance_klass(h_m()->method_holder());
++ return new (arena()) ciMethod(h_m, holder);
+ } else if (o->is_methodData()) {
+ // Hold methodHandle alive - might not be necessary ???
+ methodHandle h_m(THREAD, ((MethodData*)o)->method());
+ return new (arena()) ciMethodData((MethodData*)o);
+ }
+
+- // The oop is of some type not supported by the compiler interface.
++ // The Metadata* is of some type not supported by the compiler interface.
+ ShouldNotReachHere();
+ return NULL;
+ }
+
++// ------------------------------------------------------------------
++// ciObjectFactory::ensure_metadata_alive
++//
++// Ensure that the metadata wrapped by the ciMetadata is kept alive by GC.
++// This is primarily useful for metadata which is considered as weak roots
++// by the GC but need to be strong roots if reachable from a current compilation.
++//
++void ciObjectFactory::ensure_metadata_alive(ciMetadata* m) {
++ ASSERT_IN_VM; // We're handling raw oops here.
++
++#if INCLUDE_ALL_GCS
++ if (!UseG1GC) {
++ return;
++ }
++ Klass* metadata_owner_klass;
++ if (m->is_klass()) {
++ metadata_owner_klass = m->as_klass()->get_Klass();
++ } else if (m->is_method()) {
++ metadata_owner_klass = m->as_method()->get_Method()->constants()->pool_holder();
++ } else {
++ fatal("Not implemented for other types of metadata");
++ }
++
++ oop metadata_holder = metadata_owner_klass->klass_holder();
++ if (metadata_holder != NULL) {
++ G1SATBCardTableModRefBS::enqueue(metadata_holder);
++ }
++
++#endif
++}
++
+ //------------------------------------------------------------------
+ // ciObjectFactory::get_unloaded_method
+ //
+@@ -667,7 +716,7 @@
+ // If there is no entry in the cache corresponding to this oop, return
+ // the null tail of the bucket into which the oop should be inserted.
+ ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) {
+- assert(Universe::heap()->is_in_reserved_or_null(key), "must be");
++ assert(Universe::heap()->is_in_reserved(key), "must be");
+ ciMetadata* klass = get_metadata(key->klass());
+ NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS];
+ for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) {
+--- ./hotspot/src/share/vm/ci/ciObjectFactory.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/ci/ciObjectFactory.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -73,7 +73,9 @@
+ void insert(int index, ciMetadata* obj, GrowableArray<ciMetadata*>* objects);
+
+ ciObject* create_new_object(oop o);
+- ciMetadata* create_new_object(Metadata* o);
++ ciMetadata* create_new_metadata(Metadata* o);
++
++ void ensure_metadata_alive(ciMetadata* m);
+
+ static bool is_equal(NonPermObject* p, oop key) {
+ return p->object()->get_oop() == key;
+--- ./hotspot/src/share/vm/ci/ciTypeFlow.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/ci/ciTypeFlow.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -35,6 +35,7 @@
+ #include "interpreter/bytecode.hpp"
+ #include "interpreter/bytecodes.hpp"
+ #include "memory/allocation.inline.hpp"
++#include "opto/compile.hpp"
+ #include "runtime/deoptimization.hpp"
+ #include "utilities/growableArray.hpp"
+
+@@ -730,7 +731,7 @@
+ if (obj->is_null_object()) {
+ push_null();
+ } else {
+- assert(obj->is_instance(), "must be java_mirror of klass");
++ assert(obj->is_instance() || obj->is_array(), "must be java_mirror of klass");
+ push_object(obj->klass());
+ }
+ } else {
+@@ -2646,7 +2647,7 @@
+ assert (!blk->has_pre_order(), "");
+ blk->set_next_pre_order();
+
+- if (_next_pre_order >= MaxNodeLimit / 2) {
++ if (_next_pre_order >= (int)Compile::current()->max_node_limit() / 2) {
+ // Too many basic blocks. Bail out.
+ // This can happen when try/finally constructs are nested to depth N,
+ // and there is O(2**N) cloning of jsr bodies. See bug 4697245!
+--- ./hotspot/src/share/vm/classfile/classFileParser.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/classFileParser.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -31,6 +31,9 @@
+ #include "classfile/javaClasses.hpp"
+ #include "classfile/symbolTable.hpp"
+ #include "classfile/systemDictionary.hpp"
++#if INCLUDE_CDS
++#include "classfile/systemDictionaryShared.hpp"
++#endif
+ #include "classfile/verificationType.hpp"
+ #include "classfile/verifier.hpp"
+ #include "classfile/vmSymbols.hpp"
+@@ -60,6 +63,7 @@
+ #include "services/threadService.hpp"
+ #include "utilities/array.hpp"
+ #include "utilities/globalDefinitions.hpp"
++#include "utilities/ostream.hpp"
+
+ // We generally try to create the oops directly when parsing, rather than
+ // allocating temporary data structures and copying the bytes twice. A
+@@ -2525,7 +2529,7 @@
+ Array<Method*>* ClassFileParser::parse_methods(bool is_interface,
+ AccessFlags* promoted_flags,
+ bool* has_final_method,
+- bool* has_default_methods,
++ bool* declares_default_methods,
+ TRAPS) {
+ ClassFileStream* cfs = stream();
+ cfs->guarantee_more(2, CHECK_NULL); // length
+@@ -2544,11 +2548,11 @@
+ if (method->is_final()) {
+ *has_final_method = true;
+ }
+- if (is_interface && !(*has_default_methods)
+- && !method->is_abstract() && !method->is_static()
+- && !method->is_private()) {
+- // default method
+- *has_default_methods = true;
++ // declares_default_methods: declares concrete instance methods, any access flags
++ // used for interface initialization, and default method inheritance analysis
++ if (is_interface && !(*declares_default_methods)
++ && !method->is_abstract() && !method->is_static()) {
++ *declares_default_methods = true;
+ }
+ _methods->at_put(index, method());
+ }
+@@ -2780,19 +2784,19 @@
+ ClassFileStream* cfs = stream();
+ u1* current_start = cfs->current();
+
+- cfs->guarantee_more(attribute_byte_length, CHECK);
+-
+- int attribute_array_length = cfs->get_u2_fast();
+-
+- guarantee_property(_max_bootstrap_specifier_index < attribute_array_length,
+- "Short length on BootstrapMethods in class file %s",
+- CHECK);
+-
+ guarantee_property(attribute_byte_length >= sizeof(u2),
+ "Invalid BootstrapMethods attribute length %u in class file %s",
+ attribute_byte_length,
+ CHECK);
+
++ cfs->guarantee_more(attribute_byte_length, CHECK);
++
++ int attribute_array_length = cfs->get_u2_fast();
++
++ guarantee_property(_max_bootstrap_specifier_index < attribute_array_length,
++ "Short length on BootstrapMethods in class file %s",
++ CHECK);
++
+ // The attribute contains a counted array of counted tuples of shorts,
+ // represending bootstrap specifiers:
+ // length*{bootstrap_method_index, argument_count*{argument_index}}
+@@ -3054,21 +3058,39 @@
+ }
+ }
+
+-// Transfer ownership of metadata allocated to the InstanceKlass.
+-void ClassFileParser::apply_parsed_class_metadata(
+- instanceKlassHandle this_klass,
+- int java_fields_count, TRAPS) {
+- // Assign annotations if needed
+- if (_annotations != NULL || _type_annotations != NULL ||
+- _fields_annotations != NULL || _fields_type_annotations != NULL) {
++// Create the Annotations object that will
++// hold the annotations array for the Klass.
++void ClassFileParser::create_combined_annotations(TRAPS) {
++ if (_annotations == NULL &&
++ _type_annotations == NULL &&
++ _fields_annotations == NULL &&
++ _fields_type_annotations == NULL) {
++ // Don't create the Annotations object unnecessarily.
++ return;
++ }
++
+ Annotations* annotations = Annotations::allocate(_loader_data, CHECK);
+ annotations->set_class_annotations(_annotations);
+ annotations->set_class_type_annotations(_type_annotations);
+ annotations->set_fields_annotations(_fields_annotations);
+ annotations->set_fields_type_annotations(_fields_type_annotations);
+- this_klass->set_annotations(annotations);
+- }
+-
++
++ // This is the Annotations object that will be
++ // assigned to InstanceKlass being constructed.
++ _combined_annotations = annotations;
++
++ // The annotations arrays below has been transfered the
++ // _combined_annotations so these fields can now be cleared.
++ _annotations = NULL;
++ _type_annotations = NULL;
++ _fields_annotations = NULL;
++ _fields_type_annotations = NULL;
++}
++
++// Transfer ownership of metadata allocated to the InstanceKlass.
++void ClassFileParser::apply_parsed_class_metadata(
++ instanceKlassHandle this_klass,
++ int java_fields_count, TRAPS) {
+ _cp->set_pool_holder(this_klass());
+ this_klass->set_constants(_cp);
+ this_klass->set_fields(_fields, java_fields_count);
+@@ -3076,6 +3098,7 @@
+ this_klass->set_inner_classes(_inner_classes);
+ this_klass->set_local_interfaces(_local_interfaces);
+ this_klass->set_transitive_interfaces(_transitive_interfaces);
++ this_klass->set_annotations(_combined_annotations);
+
+ // Clear out these fields so they don't get deallocated by the destructor
+ clear_class_metadata();
+@@ -3687,6 +3710,7 @@
+ JvmtiCachedClassFileData *cached_class_file = NULL;
+ Handle class_loader(THREAD, loader_data->class_loader());
+ bool has_default_methods = false;
++ bool declares_default_methods = false;
+ ResourceMark rm(THREAD);
+
+ ClassFileStream* cfs = stream();
+@@ -3741,7 +3765,15 @@
+ instanceKlassHandle nullHandle;
+
+ // Figure out whether we can skip format checking (matching classic VM behavior)
+- _need_verify = Verifier::should_verify_for(class_loader(), verify);
++ if (DumpSharedSpaces) {
++ // verify == true means it's a 'remote' class (i.e., non-boot class)
++ // Verification decision is based on BytecodeVerificationRemote flag
++ // for those classes.
++ _need_verify = (verify) ? BytecodeVerificationRemote :
++ BytecodeVerificationLocal;
++ } else {
++ _need_verify = Verifier::should_verify_for(class_loader(), verify);
++ }
+
+ // Set the verify flag in stream
+ cfs->set_verify(_need_verify);
+@@ -3760,6 +3792,18 @@
+ u2 minor_version = cfs->get_u2_fast();
+ u2 major_version = cfs->get_u2_fast();
+
++ if (DumpSharedSpaces && major_version < JAVA_1_5_VERSION) {
++ ResourceMark rm;
++ warning("Pre JDK 1.5 class not supported by CDS: %u.%u %s",
++ major_version, minor_version, name->as_C_string());
++ Exceptions::fthrow(
++ THREAD_AND_LOCATION,
++ vmSymbols::java_lang_UnsupportedClassVersionError(),
++ "Unsupported major.minor version for dump time %u.%u",
++ major_version,
++ minor_version);
++ }
++
+ // Check version numbers - we check this even with verifier off
+ if (!is_supported_version(major_version, minor_version)) {
+ if (name == NULL) {
+@@ -3867,6 +3911,18 @@
+ if (cfs->source() != NULL) tty->print(" from %s", cfs->source());
+ tty->print_cr("]");
+ }
++#if INCLUDE_CDS
++ if (DumpLoadedClassList != NULL && cfs->source() != NULL && classlist_file->is_open()) {
++ // Only dump the classes that can be stored into CDS archive
++ if (SystemDictionaryShared::is_sharing_possible(loader_data)) {
++ if (name != NULL) {
++ ResourceMark rm(THREAD);
++ classlist_file->print_cr("%s", name->as_C_string());
++ classlist_file->flush();
++ }
++ }
++ }
++#endif
+
+ u2 super_class_index = cfs->get_u2_fast();
+ instanceKlassHandle super_klass = parse_super_class(super_class_index,
+@@ -3892,13 +3948,20 @@
+ Array<Method*>* methods = parse_methods(access_flags.is_interface(),
+ &promoted_flags,
+ &has_final_method,
+- &has_default_methods,
++ &declares_default_methods,
+ CHECK_(nullHandle));
++ if (declares_default_methods) {
++ has_default_methods = true;
++ }
+
+ // Additional attributes
+ ClassAnnotationCollector parsed_annotations;
+ parse_classfile_attributes(&parsed_annotations, CHECK_(nullHandle));
+
++ // Finalize the Annotations metadata object,
++ // now that all annotation arrays have been created.
++ create_combined_annotations(CHECK_(nullHandle));
++
+ // Make sure this is the end of class file stream
+ guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle));
+
+@@ -4036,6 +4099,7 @@
+ this_klass->set_minor_version(minor_version);
+ this_klass->set_major_version(major_version);
+ this_klass->set_has_default_methods(has_default_methods);
++ this_klass->set_declares_default_methods(declares_default_methods);
+
+ if (!host_klass.is_null()) {
+ assert (this_klass->is_anonymous(), "should be the same");
+@@ -4106,8 +4170,8 @@
+ }
+
+ // Allocate mirror and initialize static fields
+- java_lang_Class::create_mirror(this_klass, protection_domain, CHECK_(nullHandle));
+-
++ java_lang_Class::create_mirror(this_klass, class_loader, protection_domain,
++ CHECK_(nullHandle));
+
+ // Generate any default methods - default methods are interface methods
+ // that have a default implementation. This is new with Lambda project.
+@@ -4129,8 +4193,12 @@
+ tty->print("[Loaded %s from %s]\n", this_klass->external_name(),
+ cfs->source());
+ } else if (class_loader.is_null()) {
+- if (THREAD->is_Java_thread()) {
+- Klass* caller = ((JavaThread*)THREAD)->security_get_caller_class(1);
++ Klass* caller =
++ THREAD->is_Java_thread()
++ ? ((JavaThread*)THREAD)->security_get_caller_class(1)
++ : NULL;
++ // caller can be NULL, for example, during a JVMTI VM_Init hook
++ if (caller != NULL) {
+ tty->print("[Loaded %s by instance of %s]\n",
+ this_klass->external_name(),
+ InstanceKlass::cast(caller)->external_name());
+@@ -4194,10 +4262,27 @@
+ InstanceKlass::deallocate_interfaces(_loader_data, _super_klass(),
+ _local_interfaces, _transitive_interfaces);
+
+- MetadataFactory::free_array<u1>(_loader_data, _annotations);
+- MetadataFactory::free_array<u1>(_loader_data, _type_annotations);
+- Annotations::free_contents(_loader_data, _fields_annotations);
+- Annotations::free_contents(_loader_data, _fields_type_annotations);
++ if (_combined_annotations != NULL) {
++ // After all annotations arrays have been created, they are installed into the
++ // Annotations object that will be assigned to the InstanceKlass being created.
++
++ // Deallocate the Annotations object and the installed annotations arrays.
++ _combined_annotations->deallocate_contents(_loader_data);
++
++ // If the _combined_annotations pointer is non-NULL,
++ // then the other annotations fields should have been cleared.
++ assert(_annotations == NULL, "Should have been cleared");
++ assert(_type_annotations == NULL, "Should have been cleared");
++ assert(_fields_annotations == NULL, "Should have been cleared");
++ assert(_fields_type_annotations == NULL, "Should have been cleared");
++ } else {
++ // If the annotations arrays were not installed into the Annotations object,
++ // then they have to be deallocated explicitly.
++ MetadataFactory::free_array<u1>(_loader_data, _annotations);
++ MetadataFactory::free_array<u1>(_loader_data, _type_annotations);
++ Annotations::free_contents(_loader_data, _fields_annotations);
++ Annotations::free_contents(_loader_data, _fields_type_annotations);
++ }
+
+ clear_class_metadata();
+
+--- ./hotspot/src/share/vm/classfile/classFileParser.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/classFileParser.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -75,6 +75,7 @@
+ Array<u2>* _inner_classes;
+ Array<Klass*>* _local_interfaces;
+ Array<Klass*>* _transitive_interfaces;
++ Annotations* _combined_annotations;
+ AnnotationArray* _annotations;
+ AnnotationArray* _type_annotations;
+ Array<AnnotationArray*>* _fields_annotations;
+@@ -86,6 +87,8 @@
+ void set_class_generic_signature_index(u2 x) { _generic_signature_index = x; }
+ void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; }
+
++ void create_combined_annotations(TRAPS);
++
+ void init_parsed_class_attributes(ClassLoaderData* loader_data) {
+ _loader_data = loader_data;
+ _synthetic_flag = false;
+@@ -110,6 +113,7 @@
+ _inner_classes = NULL;
+ _local_interfaces = NULL;
+ _transitive_interfaces = NULL;
++ _combined_annotations = NULL;
+ _annotations = _type_annotations = NULL;
+ _fields_annotations = _fields_type_annotations = NULL;
+ }
+@@ -247,7 +251,7 @@
+ Array<Method*>* parse_methods(bool is_interface,
+ AccessFlags* promoted_flags,
+ bool* has_final_method,
+- bool* has_default_method,
++ bool* declares_default_methods,
+ TRAPS);
+ intArray* sort_methods(Array<Method*>* methods);
+
+--- ./hotspot/src/share/vm/classfile/classFileStream.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/classFileStream.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -30,7 +30,7 @@
+ THROW_MSG(vmSymbols::java_lang_ClassFormatError(), "Truncated class file");
+ }
+
+-ClassFileStream::ClassFileStream(u1* buffer, int length, char* source) {
++ClassFileStream::ClassFileStream(u1* buffer, int length, const char* source) {
+ _buffer_start = buffer;
+ _buffer_end = buffer + length;
+ _current = buffer;
+--- ./hotspot/src/share/vm/classfile/classFileStream.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/classFileStream.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -53,20 +53,20 @@
+ u1* _buffer_start; // Buffer bottom
+ u1* _buffer_end; // Buffer top (one past last element)
+ u1* _current; // Current buffer position
+- char* _source; // Source of stream (directory name, ZIP/JAR archive name)
++ const char* _source; // Source of stream (directory name, ZIP/JAR archive name)
+ bool _need_verify; // True if verification is on for the class file
+
+ void truncated_file_error(TRAPS);
+ public:
+ // Constructor
+- ClassFileStream(u1* buffer, int length, char* source);
++ ClassFileStream(u1* buffer, int length, const char* source);
+
+ // Buffer access
+ u1* buffer() const { return _buffer_start; }
+ int length() const { return _buffer_end - _buffer_start; }
+ u1* current() const { return _current; }
+ void set_current(u1* pos) { _current = pos; }
+- char* source() const { return _source; }
++ const char* source() const { return _source; }
+ void set_verify(bool flag) { _need_verify = flag; }
+
+ void check_truncated_file(bool b, TRAPS) {
+--- ./hotspot/src/share/vm/classfile/classLoader.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/classLoader.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,8 +26,13 @@
+ #include "classfile/classFileParser.hpp"
+ #include "classfile/classFileStream.hpp"
+ #include "classfile/classLoader.hpp"
++#include "classfile/classLoaderExt.hpp"
+ #include "classfile/classLoaderData.inline.hpp"
+ #include "classfile/javaClasses.hpp"
++#if INCLUDE_CDS
++#include "classfile/sharedPathsMiscInfo.hpp"
++#include "classfile/sharedClassUtil.hpp"
++#endif
+ #include "classfile/systemDictionary.hpp"
+ #include "classfile/vmSymbols.hpp"
+ #include "compiler/compileBroker.hpp"
+@@ -35,6 +40,7 @@
+ #include "interpreter/bytecodeStream.hpp"
+ #include "interpreter/oopMapCache.hpp"
+ #include "memory/allocation.inline.hpp"
++#include "memory/filemap.hpp"
+ #include "memory/generation.hpp"
+ #include "memory/oopFactory.hpp"
+ #include "memory/universe.inline.hpp"
+@@ -131,8 +137,12 @@
+
+ ClassPathEntry* ClassLoader::_first_entry = NULL;
+ ClassPathEntry* ClassLoader::_last_entry = NULL;
++int ClassLoader::_num_entries = 0;
+ PackageHashtable* ClassLoader::_package_hash_table = NULL;
+
++#if INCLUDE_CDS
++SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL;
++#endif
+ // helper routines
+ bool string_starts_with(const char* str, const char* str_to_find) {
+ size_t str_len = strlen(str);
+@@ -196,9 +206,10 @@
+ return false;
+ }
+
+-ClassPathDirEntry::ClassPathDirEntry(char* dir) : ClassPathEntry() {
+- _dir = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass);
+- strcpy(_dir, dir);
++ClassPathDirEntry::ClassPathDirEntry(const char* dir) : ClassPathEntry() {
++ char* copy = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass);
++ strcpy(copy, dir);
++ _dir = copy;
+ }
+
+
+@@ -211,6 +222,14 @@
+ // check if file exists
+ struct stat st;
+ if (os::stat(path, &st) == 0) {
++#if INCLUDE_CDS
++ if (DumpSharedSpaces) {
++ // We have already check in ClassLoader::check_shared_classpath() that the directory is empty, so
++ // we should never find a file underneath it -- unless user has added a new file while we are running
++ // the dump, in which case let's quit!
++ ShouldNotReachHere();
++ }
++#endif
+ // found file, open it
+ int file_handle = os::open(path, 0, 0);
+ if (file_handle != -1) {
+@@ -234,8 +253,9 @@
+
+ ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name) : ClassPathEntry() {
+ _zip = zip;
+- _zip_name = NEW_C_HEAP_ARRAY(char, strlen(zip_name)+1, mtClass);
+- strcpy(_zip_name, zip_name);
++ char *copy = NEW_C_HEAP_ARRAY(char, strlen(zip_name)+1, mtClass);
++ strcpy(copy, zip_name);
++ _zip_name = copy;
+ }
+
+ ClassPathZipEntry::~ClassPathZipEntry() {
+@@ -245,13 +265,13 @@
+ FREE_C_HEAP_ARRAY(char, _zip_name, mtClass);
+ }
+
+-ClassFileStream* ClassPathZipEntry::open_stream(const char* name, TRAPS) {
+- // enable call to C land
++u1* ClassPathZipEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) {
++ // enable call to C land
+ JavaThread* thread = JavaThread::current();
+ ThreadToNativeFromVM ttn(thread);
+ // check whether zip archive contains name
+- jint filesize, name_len;
+- jzentry* entry = (*FindEntry)(_zip, name, &filesize, &name_len);
++ jint name_len;
++ jzentry* entry = (*FindEntry)(_zip, name, filesize, &name_len);
+ if (entry == NULL) return NULL;
+ u1* buffer;
+ char name_buf[128];
+@@ -262,19 +282,33 @@
+ filename = NEW_RESOURCE_ARRAY(char, name_len + 1);
+ }
+
+- // file found, get pointer to class in mmaped jar file.
++ // file found, get pointer to the entry in mmapped jar file.
+ if (ReadMappedEntry == NULL ||
+ !(*ReadMappedEntry)(_zip, entry, &buffer, filename)) {
+- // mmaped access not available, perhaps due to compression,
++ // mmapped access not available, perhaps due to compression,
+ // read contents into resource array
+- buffer = NEW_RESOURCE_ARRAY(u1, filesize);
++ int size = (*filesize) + ((nul_terminate) ? 1 : 0);
++ buffer = NEW_RESOURCE_ARRAY(u1, size);
+ if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL;
+ }
++
++ // return result
++ if (nul_terminate) {
++ buffer[*filesize] = 0;
++ }
++ return buffer;
++}
++
++ClassFileStream* ClassPathZipEntry::open_stream(const char* name, TRAPS) {
++ jint filesize;
++ u1* buffer = open_entry(name, &filesize, false, CHECK_NULL);
++ if (buffer == NULL) {
++ return NULL;
++ }
+ if (UsePerfData) {
+ ClassLoader::perf_sys_classfile_bytes_read()->inc(filesize);
+ }
+- // return result
+- return new ClassFileStream(buffer, filesize, _zip_name); // Resource allocated
++ return new ClassFileStream(buffer, filesize, _zip_name); // Resource allocated
+ }
+
+ // invoke function for each entry in the zip file
+@@ -289,12 +323,13 @@
+ }
+ }
+
+-LazyClassPathEntry::LazyClassPathEntry(char* path, const struct stat* st) : ClassPathEntry() {
++LazyClassPathEntry::LazyClassPathEntry(const char* path, const struct stat* st, bool throw_exception) : ClassPathEntry() {
+ _path = strdup(path);
+ _st = *st;
+ _meta_index = NULL;
+ _resolved_entry = NULL;
+ _has_error = false;
++ _throw_exception = throw_exception;
+ }
+
+ bool LazyClassPathEntry::is_jar_file() {
+@@ -306,7 +341,11 @@
+ return (ClassPathEntry*) _resolved_entry;
+ }
+ ClassPathEntry* new_entry = NULL;
+- new_entry = ClassLoader::create_class_path_entry(_path, &_st, false, CHECK_NULL);
++ new_entry = ClassLoader::create_class_path_entry(_path, &_st, false, _throw_exception, CHECK_NULL);
++ if (!_throw_exception && new_entry == NULL) {
++ assert(!HAS_PENDING_EXCEPTION, "must be");
++ return NULL;
++ }
+ {
+ ThreadCritical tc;
+ if (_resolved_entry == NULL) {
+@@ -340,6 +379,23 @@
+ return true;
+ }
+
++u1* LazyClassPathEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) {
++ if (_has_error) {
++ return NULL;
++ }
++ ClassPathEntry* cpe = resolve_entry(THREAD);
++ if (cpe == NULL) {
++ _has_error = true;
++ return NULL;
++ } else if (cpe->is_jar_file()) {
++ return ((ClassPathZipEntry*)cpe)->open_entry(name, filesize, nul_terminate,THREAD);
++ } else {
++ ShouldNotReachHere();
++ *filesize = 0;
++ return NULL;
++ }
++}
++
+ static void print_meta_index(LazyClassPathEntry* entry,
+ GrowableArray<char*>& meta_packages) {
+ tty->print("[Meta index for %s=", entry->name());
+@@ -350,15 +406,62 @@
+ tty->print_cr("]");
+ }
+
++#if INCLUDE_CDS
++void ClassLoader::exit_with_path_failure(const char* error, const char* message) {
++ assert(DumpSharedSpaces, "only called at dump time");
++ tty->print_cr("Hint: enable -XX:+TraceClassPaths to diagnose the failure");
++ vm_exit_during_initialization(error, message);
++}
++#endif
+
+-void ClassLoader::setup_meta_index() {
++void ClassLoader::trace_class_path(const char* msg, const char* name) {
++ if (!TraceClassPaths) {
++ return;
++ }
++
++ if (msg) {
++ tty->print("%s", msg);
++ }
++ if (name) {
++ if (strlen(name) < 256) {
++ tty->print("%s", name);
++ } else {
++ // For very long paths, we need to print each character separately,
++ // as print_cr() has a length limit
++ while (name[0] != '\0') {
++ tty->print("%c", name[0]);
++ name++;
++ }
++ }
++ }
++ if (msg && msg[0] == '[') {
++ tty->print_cr("]");
++ } else {
++ tty->cr();
++ }
++}
++
++void ClassLoader::setup_bootstrap_meta_index() {
+ // Set up meta index which allows us to open boot jars lazily if
+ // class data sharing is enabled
++ const char* meta_index_path = Arguments::get_meta_index_path();
++ const char* meta_index_dir = Arguments::get_meta_index_dir();
++ setup_meta_index(meta_index_path, meta_index_dir, 0);
++}
++
++void ClassLoader::setup_meta_index(const char* meta_index_path, const char* meta_index_dir, int start_index) {
+ const char* known_version = "% VERSION 2";
+- char* meta_index_path = Arguments::get_meta_index_path();
+- char* meta_index_dir = Arguments::get_meta_index_dir();
+ FILE* file = fopen(meta_index_path, "r");
+ int line_no = 0;
++#if INCLUDE_CDS
++ if (DumpSharedSpaces) {
++ if (file != NULL) {
++ _shared_paths_misc_info->add_required_file(meta_index_path);
++ } else {
++ _shared_paths_misc_info->add_nonexist_path(meta_index_path);
++ }
++ }
++#endif
+ if (file != NULL) {
+ ResourceMark rm;
+ LazyClassPathEntry* cur_entry = NULL;
+@@ -393,7 +496,7 @@
+ // Hand off current packages to current lazy entry (if any)
+ if ((cur_entry != NULL) &&
+ (boot_class_path_packages.length() > 0)) {
+- if (TraceClassLoading && Verbose) {
++ if ((TraceClassLoading || TraceClassPaths) && Verbose) {
+ print_meta_index(cur_entry, boot_class_path_packages);
+ }
+ MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0),
+@@ -404,8 +507,10 @@
+ boot_class_path_packages.clear();
+
+ // Find lazy entry corresponding to this jar file
+- for (ClassPathEntry* entry = _first_entry; entry != NULL; entry = entry->next()) {
+- if (entry->is_lazy() &&
++ int count = 0;
++ for (ClassPathEntry* entry = _first_entry; entry != NULL; entry = entry->next(), count++) {
++ if (count >= start_index &&
++ entry->is_lazy() &&
+ string_starts_with(entry->name(), meta_index_dir) &&
+ string_ends_with(entry->name(), &package_name[2])) {
+ cur_entry = (LazyClassPathEntry*) entry;
+@@ -442,7 +547,7 @@
+ // Hand off current packages to current lazy entry (if any)
+ if ((cur_entry != NULL) &&
+ (boot_class_path_packages.length() > 0)) {
+- if (TraceClassLoading && Verbose) {
++ if ((TraceClassLoading || TraceClassPaths) && Verbose) {
+ print_meta_index(cur_entry, boot_class_path_packages);
+ }
+ MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0),
+@@ -453,36 +558,96 @@
+ }
+ }
+
++#if INCLUDE_CDS
++void ClassLoader::check_shared_classpath(const char *path) {
++ if (strcmp(path, "") == 0) {
++ exit_with_path_failure("Cannot have empty path in archived classpaths", NULL);
++ }
++
++ struct stat st;
++ if (os::stat(path, &st) == 0) {
++ if ((st.st_mode & S_IFREG) != S_IFREG) { // is directory
++ if (!os::dir_is_empty(path)) {
++ tty->print_cr("Error: non-empty directory '%s'", path);
++ exit_with_path_failure("CDS allows only empty directories in archived classpaths", NULL);
++ }
++ }
++ }
++}
++#endif
++
+ void ClassLoader::setup_bootstrap_search_path() {
+ assert(_first_entry == NULL, "should not setup bootstrap class search path twice");
+- char* sys_class_path = os::strdup(Arguments::get_sysclasspath());
+- if (TraceClassLoading && Verbose) {
+- tty->print_cr("[Bootstrap loader class path=%s]", sys_class_path);
++ const char* sys_class_path = Arguments::get_sysclasspath();
++ if (PrintSharedArchiveAndExit) {
++ // Don't print sys_class_path - this is the bootcp of this current VM process, not necessarily
++ // the same as the bootcp of the shared archive.
++ } else {
++ trace_class_path("[Bootstrap loader class path=", sys_class_path);
+ }
++#if INCLUDE_CDS
++ if (DumpSharedSpaces) {
++ _shared_paths_misc_info->add_boot_classpath(sys_class_path);
++ }
++#endif
++ setup_search_path(sys_class_path);
++}
+
+- int len = (int)strlen(sys_class_path);
++#if INCLUDE_CDS
++int ClassLoader::get_shared_paths_misc_info_size() {
++ return _shared_paths_misc_info->get_used_bytes();
++}
++
++void* ClassLoader::get_shared_paths_misc_info() {
++ return _shared_paths_misc_info->buffer();
++}
++
++bool ClassLoader::check_shared_paths_misc_info(void *buf, int size) {
++ SharedPathsMiscInfo* checker = SharedClassUtil::allocate_shared_paths_misc_info((char*)buf, size);
++ bool result = checker->check();
++ delete checker;
++ return result;
++}
++#endif
++
++void ClassLoader::setup_search_path(const char *class_path, bool canonicalize) {
++ int offset = 0;
++ int len = (int)strlen(class_path);
+ int end = 0;
+
+ // Iterate over class path entries
+ for (int start = 0; start < len; start = end) {
+- while (sys_class_path[end] && sys_class_path[end] != os::path_separator()[0]) {
++ while (class_path[end] && class_path[end] != os::path_separator()[0]) {
+ end++;
+ }
+- char* path = NEW_C_HEAP_ARRAY(char, end-start+1, mtClass);
+- strncpy(path, &sys_class_path[start], end-start);
+- path[end-start] = '\0';
+- update_class_path_entry_list(path, false);
+- FREE_C_HEAP_ARRAY(char, path, mtClass);
+- while (sys_class_path[end] == os::path_separator()[0]) {
++ EXCEPTION_MARK;
++ ResourceMark rm(THREAD);
++ char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
++ strncpy(path, &class_path[start], end - start);
++ path[end - start] = '\0';
++ if (canonicalize) {
++ char* canonical_path = NEW_RESOURCE_ARRAY(char, JVM_MAXPATHLEN + 1);
++ if (get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) {
++ path = canonical_path;
++ }
++ }
++ update_class_path_entry_list(path, /*check_for_duplicates=*/canonicalize);
++#if INCLUDE_CDS
++ if (DumpSharedSpaces) {
++ check_shared_classpath(path);
++ }
++#endif
++ while (class_path[end] == os::path_separator()[0]) {
+ end++;
+ }
+ }
+ }
+
+-ClassPathEntry* ClassLoader::create_class_path_entry(char *path, const struct stat* st, bool lazy, TRAPS) {
++ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const struct stat* st,
++ bool lazy, bool throw_exception, TRAPS) {
+ JavaThread* thread = JavaThread::current();
+ if (lazy) {
+- return new LazyClassPathEntry(path, st);
++ return new LazyClassPathEntry(path, st, throw_exception);
+ }
+ ClassPathEntry* new_entry = NULL;
+ if ((st->st_mode & S_IFREG) == S_IFREG) {
+@@ -491,7 +656,11 @@
+ char canonical_path[JVM_MAXPATHLEN];
+ if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) {
+ // This matches the classic VM
+- THROW_MSG_(vmSymbols::java_io_IOException(), "Bad pathname", NULL);
++ if (throw_exception) {
++ THROW_MSG_(vmSymbols::java_io_IOException(), "Bad pathname", NULL);
++ } else {
++ return NULL;
++ }
+ }
+ char* error_msg = NULL;
+ jzfile* zip;
+@@ -503,7 +672,7 @@
+ }
+ if (zip != NULL && error_msg == NULL) {
+ new_entry = new ClassPathZipEntry(zip, path);
+- if (TraceClassLoading) {
++ if (TraceClassLoading || TraceClassPaths) {
+ tty->print_cr("[Opened %s]", path);
+ }
+ } else {
+@@ -517,12 +686,16 @@
+ msg = NEW_RESOURCE_ARRAY(char, len); ;
+ jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path);
+ }
+- THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL);
++ if (throw_exception) {
++ THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL);
++ } else {
++ return NULL;
++ }
+ }
+ } else {
+ // Directory
+ new_entry = new ClassPathDirEntry(path);
+- if (TraceClassLoading) {
++ if (TraceClassLoading || TraceClassPaths) {
+ tty->print_cr("[Path %s]", path);
+ }
+ }
+@@ -537,11 +710,8 @@
+ struct stat st;
+ if (os::stat(path, &st) == 0) {
+ if ((st.st_mode & S_IFREG) == S_IFREG) {
+- char orig_path[JVM_MAXPATHLEN];
+ char canonical_path[JVM_MAXPATHLEN];
+-
+- strcpy(orig_path, path);
+- if (get_canonical_path(orig_path, canonical_path, JVM_MAXPATHLEN)) {
++ if (get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) {
+ char* error_msg = NULL;
+ jzfile* zip;
+ {
+@@ -583,23 +753,37 @@
+ _last_entry = new_entry;
+ }
+ }
++ _num_entries ++;
+ }
+
+-void ClassLoader::update_class_path_entry_list(char *path,
+- bool check_for_duplicates) {
++// Returns true IFF the file/dir exists and the entry was successfully created.
++bool ClassLoader::update_class_path_entry_list(const char *path,
++ bool check_for_duplicates,
++ bool throw_exception) {
+ struct stat st;
+ if (os::stat(path, &st) == 0) {
+ // File or directory found
+ ClassPathEntry* new_entry = NULL;
+ Thread* THREAD = Thread::current();
+- new_entry = create_class_path_entry(path, &st, LazyBootClassLoader, CHECK);
++ new_entry = create_class_path_entry(path, &st, LazyBootClassLoader, throw_exception, CHECK_(false));
++ if (new_entry == NULL) {
++ return false;
++ }
+ // The kernel VM adds dynamically to the end of the classloader path and
+ // doesn't reorder the bootclasspath which would break java.lang.Package
+ // (see PackageInfo).
+ // Add new entry to linked list
+ if (!check_for_duplicates || !contains_entry(new_entry)) {
+- add_to_list(new_entry);
++ ClassLoaderExt::add_class_path_entry(path, check_for_duplicates, new_entry);
+ }
++ return true;
++ } else {
++#if INCLUDE_CDS
++ if (DumpSharedSpaces) {
++ _shared_paths_misc_info->add_nonexist_path(path);
++ }
++#endif
++ return false;
+ }
+ }
+
+@@ -758,10 +942,10 @@
+ assert(n == number_of_entries(), "just checking");
+ }
+
+- void copy_table(char** top, char* end, PackageHashtable* table);
++ CDS_ONLY(void copy_table(char** top, char* end, PackageHashtable* table);)
+ };
+
+-
++#if INCLUDE_CDS
+ void PackageHashtable::copy_table(char** top, char* end,
+ PackageHashtable* table) {
+ // Copy (relocate) the table to the shared space.
+@@ -769,33 +953,30 @@
+
+ // Calculate the space needed for the package name strings.
+ int i;
+- int n = 0;
+- for (i = 0; i < table_size(); ++i) {
+- for (PackageInfo* pp = table->bucket(i);
+- pp != NULL;
+- pp = pp->next()) {
+- n += (int)(strlen(pp->pkgname()) + 1);
+- }
+- }
+- if (*top + n + sizeof(intptr_t) >= end) {
+- report_out_of_shared_space(SharedMiscData);
+- }
+-
+- // Copy the table data (the strings) to the shared space.
+- n = align_size_up(n, sizeof(HeapWord));
+- *(intptr_t*)(*top) = n;
+- *top += sizeof(intptr_t);
++ intptr_t* tableSize = (intptr_t*)(*top);
++ *top += sizeof(intptr_t); // For table size
++ char* tableStart = *top;
+
+ for (i = 0; i < table_size(); ++i) {
+ for (PackageInfo* pp = table->bucket(i);
+ pp != NULL;
+ pp = pp->next()) {
+ int n1 = (int)(strlen(pp->pkgname()) + 1);
++ if (*top + n1 >= end) {
++ report_out_of_shared_space(SharedMiscData);
++ }
+ pp->set_pkgname((char*)memcpy(*top, pp->pkgname(), n1));
+ *top += n1;
+ }
+ }
+ *top = (char*)align_size_up((intptr_t)*top, sizeof(HeapWord));
++ if (*top >= end) {
++ report_out_of_shared_space(SharedMiscData);
++ }
++
++ // Write table size
++ intptr_t len = *top - (char*)tableStart;
++ *tableSize = len;
+ }
+
+
+@@ -806,7 +987,7 @@
+ void ClassLoader::copy_package_info_table(char** top, char* end) {
+ _package_hash_table->copy_table(top, end, _package_hash_table);
+ }
+-
++#endif
+
+ PackageInfo* ClassLoader::lookup_package(const char *pkgname) {
+ const char *cp = strrchr(pkgname, '/');
+@@ -899,7 +1080,8 @@
+
+ instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) {
+ ResourceMark rm(THREAD);
+- EventMark m("loading class %s", h_name->as_C_string());
++ const char* class_name = h_name->as_C_string();
++ EventMark m("loading class %s", class_name);
+ ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);
+
+ stringStream st;
+@@ -907,18 +1089,24 @@
+ // st.print("%s.class", h_name->as_utf8());
+ st.print_raw(h_name->as_utf8());
+ st.print_raw(".class");
+- char* name = st.as_string();
++ const char* file_name = st.as_string();
++ ClassLoaderExt::Context context(class_name, file_name, THREAD);
+
+ // Lookup stream for parsing .class file
+ ClassFileStream* stream = NULL;
+ int classpath_index = 0;
++ ClassPathEntry* e = NULL;
++ instanceKlassHandle h;
+ {
+ PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
+ ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
+ PerfClassTraceTime::CLASS_LOAD);
+- ClassPathEntry* e = _first_entry;
++ e = _first_entry;
+ while (e != NULL) {
+- stream = e->open_stream(name, CHECK_NULL);
++ stream = e->open_stream(file_name, CHECK_NULL);
++ if (!context.check(stream, classpath_index)) {
++ return h; // NULL
++ }
+ if (stream != NULL) {
+ break;
+ }
+@@ -927,9 +1115,7 @@
+ }
+ }
+
+- instanceKlassHandle h;
+ if (stream != NULL) {
+-
+ // class file found, parse it
+ ClassFileParser parser(stream);
+ ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
+@@ -939,12 +1125,19 @@
+ loader_data,
+ protection_domain,
+ parsed_name,
+- false,
+- CHECK_(h));
+-
+- // add to package table
+- if (add_package(name, classpath_index, THREAD)) {
+- h = result;
++ context.should_verify(classpath_index),
++ THREAD);
++ if (HAS_PENDING_EXCEPTION) {
++ ResourceMark rm;
++ if (DumpSharedSpaces) {
++ tty->print_cr("Preload Error: Failed to load %s", class_name);
++ }
++ return h;
++ }
++ h = context.record_result(classpath_index, e, result, THREAD);
++ } else {
++ if (DumpSharedSpaces) {
++ tty->print_cr("Preload Warning: Cannot find %s", class_name);
+ }
+ }
+
+@@ -1039,14 +1232,27 @@
+
+ // lookup zip library entry points
+ load_zip_library();
++#if INCLUDE_CDS
+ // initialize search path
++ if (DumpSharedSpaces) {
++ _shared_paths_misc_info = SharedClassUtil::allocate_shared_paths_misc_info();
++ }
++#endif
+ setup_bootstrap_search_path();
+ if (LazyBootClassLoader) {
+ // set up meta index which makes boot classpath initialization lazier
+- setup_meta_index();
++ setup_bootstrap_meta_index();
+ }
+ }
+
++#if INCLUDE_CDS
++void ClassLoader::initialize_shared_path() {
++ if (DumpSharedSpaces) {
++ ClassLoaderExt::setup_search_paths();
++ _shared_paths_misc_info->write_jint(0); // see comments in SharedPathsMiscInfo::check()
++ }
++}
++#endif
+
+ jlong ClassLoader::classloader_time_ms() {
+ return UsePerfData ?
+@@ -1090,11 +1296,17 @@
+ }
+
+
+-bool ClassLoader::get_canonical_path(char* orig, char* out, int len) {
++bool ClassLoader::get_canonical_path(const char* orig, char* out, int len) {
+ assert(orig != NULL && out != NULL && len > 0, "bad arguments");
+ if (CanonicalizeEntry != NULL) {
+- JNIEnv* env = JavaThread::current()->jni_environment();
+- if ((CanonicalizeEntry)(env, os::native_path(orig), out, len) < 0) {
++ JavaThread* THREAD = JavaThread::current();
++ JNIEnv* env = THREAD->jni_environment();
++ ResourceMark rm(THREAD);
++
++ // os::native_path writes into orig_copy
++ char* orig_copy = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, strlen(orig)+1);
++ strcpy(orig_copy, orig);
++ if ((CanonicalizeEntry)(env, os::native_path(orig_copy), out, len) < 0) {
+ return false;
+ }
+ } else {
+@@ -1412,7 +1624,7 @@
+ if (TieredCompilation && TieredStopAtLevel >= CompLevel_full_optimization) {
+ // Clobber the first compile and force second tier compilation
+ nmethod* nm = m->code();
+- if (nm != NULL) {
++ if (nm != NULL && !m->is_method_handle_intrinsic()) {
+ // Throw out the code so that the code cache doesn't fill up
+ nm->make_not_entrant();
+ m->clear_code();
+@@ -1431,7 +1643,7 @@
+ }
+
+ nmethod* nm = m->code();
+- if (nm != NULL) {
++ if (nm != NULL && !m->is_method_handle_intrinsic()) {
+ // Throw out the code so that the code cache doesn't fill up
+ nm->make_not_entrant();
+ m->clear_code();
+--- ./hotspot/src/share/vm/classfile/classLoader.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/classLoader.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -72,11 +72,11 @@
+
+ class ClassPathDirEntry: public ClassPathEntry {
+ private:
+- char* _dir; // Name of directory
++ const char* _dir; // Name of directory
+ public:
+ bool is_jar_file() { return false; }
+ const char* name() { return _dir; }
+- ClassPathDirEntry(char* dir);
++ ClassPathDirEntry(const char* dir);
+ ClassFileStream* open_stream(const char* name, TRAPS);
+ // Debugging
+ NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
+@@ -100,13 +100,14 @@
+
+ class ClassPathZipEntry: public ClassPathEntry {
+ private:
+- jzfile* _zip; // The zip archive
+- char* _zip_name; // Name of zip archive
++ jzfile* _zip; // The zip archive
++ const char* _zip_name; // Name of zip archive
+ public:
+ bool is_jar_file() { return true; }
+ const char* name() { return _zip_name; }
+ ClassPathZipEntry(jzfile* zip, const char* zip_name);
+ ~ClassPathZipEntry();
++ u1* open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS);
+ ClassFileStream* open_stream(const char* name, TRAPS);
+ void contents_do(void f(const char* name, void* context), void* context);
+ // Debugging
+@@ -122,16 +123,18 @@
+ // For lazier loading of boot class path entries
+ class LazyClassPathEntry: public ClassPathEntry {
+ private:
+- char* _path; // dir or file
++ const char* _path; // dir or file
+ struct stat _st;
+ MetaIndex* _meta_index;
+ bool _has_error;
++ bool _throw_exception;
+ volatile ClassPathEntry* _resolved_entry;
++ public:
+ ClassPathEntry* resolve_entry(TRAPS);
+- public:
+ bool is_jar_file();
+ const char* name() { return _path; }
+- LazyClassPathEntry(char* path, const struct stat* st);
++ LazyClassPathEntry(const char* path, const struct stat* st, bool throw_exception);
++ u1* open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS);
+ ClassFileStream* open_stream(const char* name, TRAPS);
+ void set_meta_index(MetaIndex* meta_index) { _meta_index = meta_index; }
+ virtual bool is_lazy();
+@@ -142,6 +145,7 @@
+
+ class PackageHashtable;
+ class PackageInfo;
++class SharedPathsMiscInfo;
+ template <MEMFLAGS F> class HashtableBucket;
+
+ class ClassLoader: AllStatic {
+@@ -149,7 +153,7 @@
+ enum SomeConstants {
+ package_hash_table_size = 31 // Number of buckets
+ };
+- private:
++ protected:
+ friend class LazyClassPathEntry;
+
+ // Performance counters
+@@ -191,10 +195,15 @@
+ static ClassPathEntry* _first_entry;
+ // Last entry in linked list of ClassPathEntry instances
+ static ClassPathEntry* _last_entry;
++ static int _num_entries;
++
+ // Hash table used to keep track of loaded packages
+ static PackageHashtable* _package_hash_table;
+ static const char* _shared_archive;
+
++ // Info used by CDS
++ CDS_ONLY(static SharedPathsMiscInfo * _shared_paths_misc_info;)
++
+ // Hash function
+ static unsigned int hash(const char *s, int n);
+ // Returns the package file name corresponding to the specified package
+@@ -205,20 +214,24 @@
+ static bool add_package(const char *pkgname, int classpath_index, TRAPS);
+
+ // Initialization
+- static void setup_meta_index();
++ static void setup_bootstrap_meta_index();
++ static void setup_meta_index(const char* meta_index_path, const char* meta_index_dir,
++ int start_index);
+ static void setup_bootstrap_search_path();
++ static void setup_search_path(const char *class_path, bool canonicalize=false);
++
+ static void load_zip_library();
+- static ClassPathEntry* create_class_path_entry(char *path, const struct stat* st,
+- bool lazy, TRAPS);
++ static ClassPathEntry* create_class_path_entry(const char *path, const struct stat* st,
++ bool lazy, bool throw_exception, TRAPS);
+
+ // Canonicalizes path names, so strcmp will work properly. This is mainly
+ // to avoid confusing the zip library
+- static bool get_canonical_path(char* orig, char* out, int len);
++ static bool get_canonical_path(const char* orig, char* out, int len);
+ public:
+ static int crc32(int crc, const char* buf, int len);
+- // Used by the kernel jvm.
+- static void update_class_path_entry_list(char *path,
+- bool check_for_duplicates);
++ static bool update_class_path_entry_list(const char *path,
++ bool check_for_duplicates,
++ bool throw_exception=true);
+ static void print_bootclasspath();
+
+ // Timing
+@@ -301,6 +314,7 @@
+
+ // Initialization
+ static void initialize();
++ CDS_ONLY(static void initialize_shared_path();)
+ static void create_package_info_table();
+ static void create_package_info_table(HashtableBucket<mtClass> *t, int length,
+ int number_of_entries);
+@@ -315,10 +329,25 @@
+ return e;
+ }
+
++ static int num_classpath_entries() {
++ return _num_entries;
++ }
++
++#if INCLUDE_CDS
+ // Sharing dump and restore
+ static void copy_package_info_buckets(char** top, char* end);
+ static void copy_package_info_table(char** top, char* end);
+
++ static void check_shared_classpath(const char *path);
++ static void finalize_shared_paths_misc_info();
++ static int get_shared_paths_misc_info_size();
++ static void* get_shared_paths_misc_info();
++ static bool check_shared_paths_misc_info(void* info, int size);
++ static void exit_with_path_failure(const char* error, const char* message);
++#endif
++
++ static void trace_class_path(const char* msg, const char* name = NULL);
++
+ // VM monitoring and management support
+ static jlong classloader_time_ms();
+ static jlong class_method_total_size();
+@@ -342,7 +371,7 @@
+
+ // Force compilation of all methods in all classes in bootstrap class path (stress test)
+ #ifndef PRODUCT
+- private:
++ protected:
+ static int _compile_the_world_class_counter;
+ static int _compile_the_world_method_counter;
+ public:
+--- ./hotspot/src/share/vm/classfile/classLoaderData.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/classLoaderData.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -64,16 +64,19 @@
+ #include "utilities/growableArray.hpp"
+ #include "utilities/macros.hpp"
+ #include "utilities/ostream.hpp"
+-
+ #if INCLUDE_TRACE
+- #include "trace/tracing.hpp"
++#include "trace/tracing.hpp"
+ #endif
+
+ ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
+
+ ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) :
+ _class_loader(h_class_loader()),
+- _is_anonymous(is_anonymous), _keep_alive(is_anonymous), // initially
++ _is_anonymous(is_anonymous),
++ // An anonymous class loader data doesn't have anything to keep
++ // it from being unloaded during parsing of the anonymous class.
++ // The null-class-loader should always be kept alive.
++ _keep_alive(is_anonymous || h_class_loader.is_null()),
+ _metaspace(NULL), _unloading(false), _klasses(NULL),
+ _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
+ _next(NULL), _dependencies(dependencies),
+@@ -317,12 +320,45 @@
+ }
+ }
+
++#ifdef ASSERT
++class AllAliveClosure : public OopClosure {
++ BoolObjectClosure* _is_alive_closure;
++ bool _found_dead;
++ public:
++ AllAliveClosure(BoolObjectClosure* is_alive_closure) : _is_alive_closure(is_alive_closure), _found_dead(false) {}
++ template <typename T> void do_oop_work(T* p) {
++ T heap_oop = oopDesc::load_heap_oop(p);
++ if (!oopDesc::is_null(heap_oop)) {
++ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
++ if (!_is_alive_closure->do_object_b(obj)) {
++ _found_dead = true;
++ }
++ }
++ }
++ void do_oop(oop* p) { do_oop_work<oop>(p); }
++ void do_oop(narrowOop* p) { do_oop_work<narrowOop>(p); }
++ bool found_dead() { return _found_dead; }
++};
++#endif
++
++oop ClassLoaderData::keep_alive_object() const {
++ assert(!keep_alive(), "Don't use with CLDs that are artificially kept alive");
++ return is_anonymous() ? _klasses->java_mirror() : class_loader();
++}
++
+ bool ClassLoaderData::is_alive(BoolObjectClosure* is_alive_closure) const {
+- bool alive =
+- is_anonymous() ?
+- is_alive_closure->do_object_b(_klasses->java_mirror()) :
+- class_loader() == NULL || is_alive_closure->do_object_b(class_loader());
+- assert(!alive || claimed(), "must be claimed");
++ bool alive = keep_alive() // null class loader and incomplete anonymous klasses.
++ || is_alive_closure->do_object_b(keep_alive_object());
++
++#ifdef ASSERT
++ if (alive) {
++ AllAliveClosure all_alive_closure(is_alive_closure);
++ KlassToOopClosure klass_closure(&all_alive_closure);
++ const_cast<ClassLoaderData*>(this)->oops_do(&all_alive_closure, &klass_closure, false);
++ assert(!all_alive_closure.found_dead(), err_msg("Found dead oop in alive cld: " PTR_FORMAT, p2i(this)));
++ }
++#endif
++
+ return alive;
+ }
+
+@@ -601,11 +637,36 @@
+
+ void ClassLoaderDataGraph::always_strong_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
+ if (ClassUnloading) {
+- ClassLoaderData::the_null_class_loader_data()->oops_do(f, klass_closure, must_claim);
+- // keep any special CLDs alive.
+- ClassLoaderDataGraph::keep_alive_oops_do(f, klass_closure, must_claim);
++ keep_alive_oops_do(f, klass_closure, must_claim);
+ } else {
+- ClassLoaderDataGraph::oops_do(f, klass_closure, must_claim);
++ oops_do(f, klass_closure, must_claim);
++ }
++}
++
++void ClassLoaderDataGraph::cld_do(CLDClosure* cl) {
++ for (ClassLoaderData* cld = _head; cl != NULL && cld != NULL; cld = cld->next()) {
++ cl->do_cld(cld);
++ }
++}
++
++void ClassLoaderDataGraph::roots_cld_do(CLDClosure* strong, CLDClosure* weak) {
++ for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->_next) {
++ CLDClosure* closure = cld->keep_alive() ? strong : weak;
++ if (closure != NULL) {
++ closure->do_cld(cld);
++ }
++ }
++}
++
++void ClassLoaderDataGraph::keep_alive_cld_do(CLDClosure* cl) {
++ roots_cld_do(cl, NULL);
++}
++
++void ClassLoaderDataGraph::always_strong_cld_do(CLDClosure* cl) {
++ if (ClassUnloading) {
++ keep_alive_cld_do(cl);
++ } else {
++ cld_do(cl);
+ }
+ }
+
+@@ -660,6 +721,16 @@
+ return array;
+ }
+
++bool ClassLoaderDataGraph::unload_list_contains(const void* x) {
++ assert(SafepointSynchronize::is_at_safepoint(), "only safe to call at safepoint");
++ for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) {
++ if (cld->metaspace_or_null() != NULL && cld->metaspace_or_null()->contains(x)) {
++ return true;
++ }
++ }
++ return false;
++}
++
+ #ifndef PRODUCT
+ bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) {
+ for (ClassLoaderData* data = _head; data != NULL; data = data->next()) {
+@@ -675,7 +746,7 @@
+
+ // Move class loader data from main list to the unloaded list for unloading
+ // and deallocation later.
+-bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) {
++bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure, bool clean_alive) {
+ ClassLoaderData* data = _head;
+ ClassLoaderData* prev = NULL;
+ bool seen_dead_loader = false;
+@@ -684,16 +755,8 @@
+ // purging and we don't want to rewalk the previously unloaded class loader data.
+ _saved_unloading = _unloading;
+
+- // mark metadata seen on the stack and code cache so we can delete
+- // unneeded entries.
+- bool has_redefined_a_class = JvmtiExport::has_redefined_a_class();
+- MetadataOnStackMark md_on_stack;
+ while (data != NULL) {
+- if (data->keep_alive() || data->is_alive(is_alive_closure)) {
+- if (has_redefined_a_class) {
+- data->classes_do(InstanceKlass::purge_previous_versions);
+- }
+- data->free_deallocate_list();
++ if (data->is_alive(is_alive_closure)) {
+ prev = data;
+ data = data->next();
+ continue;
+@@ -715,6 +778,11 @@
+ _unloading = dead;
+ }
+
++ if (clean_alive) {
++ // Clean previous versions and the deallocate list.
++ ClassLoaderDataGraph::clean_metaspaces();
++ }
++
+ if (seen_dead_loader) {
+ post_class_unload_events();
+ }
+@@ -722,6 +790,26 @@
+ return seen_dead_loader;
+ }
+
++void ClassLoaderDataGraph::clean_metaspaces() {
++ // mark metadata seen on the stack and code cache so we can delete unneeded entries.
++ bool has_redefined_a_class = JvmtiExport::has_redefined_a_class();
++ MetadataOnStackMark md_on_stack(has_redefined_a_class);
++
++ if (has_redefined_a_class) {
++ // purge_previous_versions also cleans weak method links. Because
++ // one method's MDO can reference another method from another
++ // class loader, we need to first clean weak method links for all
++ // class loaders here. Below, we can then free redefined methods
++ // for all class loaders.
++ for (ClassLoaderData* data = _head; data != NULL; data = data->next()) {
++ data->classes_do(InstanceKlass::purge_previous_versions);
++ }
++ }
++
++ // Need to purge the previous version before deallocating.
++ free_deallocate_lists();
++}
++
+ void ClassLoaderDataGraph::purge() {
+ assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
+ ClassLoaderData* list = _unloading;
+@@ -749,6 +837,14 @@
+ #endif
+ }
+
++void ClassLoaderDataGraph::free_deallocate_lists() {
++ for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
++ // We need to keep this data until InstanceKlass::purge_previous_version has been
++ // called on all alive classes. See the comment in ClassLoaderDataGraph::clean_metaspaces.
++ cld->free_deallocate_list();
++ }
++}
++
+ // CDS support
+
+ // Global metaspaces for writing information to the shared archive. When
+@@ -780,6 +876,60 @@
+ return _rw_metaspace;
+ }
+
++ClassLoaderDataGraphKlassIteratorAtomic::ClassLoaderDataGraphKlassIteratorAtomic()
++ : _next_klass(NULL) {
++ ClassLoaderData* cld = ClassLoaderDataGraph::_head;
++ Klass* klass = NULL;
++
++ // Find the first klass in the CLDG.
++ while (cld != NULL) {
++ klass = cld->_klasses;
++ if (klass != NULL) {
++ _next_klass = klass;
++ return;
++ }
++ cld = cld->next();
++ }
++}
++
++Klass* ClassLoaderDataGraphKlassIteratorAtomic::next_klass_in_cldg(Klass* klass) {
++ Klass* next = klass->next_link();
++ if (next != NULL) {
++ return next;
++ }
++
++ // No more klasses in the current CLD. Time to find a new CLD.
++ ClassLoaderData* cld = klass->class_loader_data();
++ while (next == NULL) {
++ cld = cld->next();
++ if (cld == NULL) {
++ break;
++ }
++ next = cld->_klasses;
++ }
++
++ return next;
++}
++
++Klass* ClassLoaderDataGraphKlassIteratorAtomic::next_klass() {
++ Klass* head = (Klass*)_next_klass;
++
++ while (head != NULL) {
++ Klass* next = next_klass_in_cldg(head);
++
++ Klass* old_head = (Klass*)Atomic::cmpxchg_ptr(next, &_next_klass, head);
++
++ if (old_head == head) {
++ return head; // Won the CAS.
++ }
++
++ head = old_head;
++ }
++
++ // Nothing more for the iterator to hand out.
++ assert(head == NULL, err_msg("head is " PTR_FORMAT ", expected not null:", p2i(head)));
++ return NULL;
++}
+
+ ClassLoaderDataGraphMetaspaceIterator::ClassLoaderDataGraphMetaspaceIterator() {
+ _data = ClassLoaderDataGraph::_head;
+@@ -833,4 +983,4 @@
+ event.commit();
+ }
+
+-#endif /* INCLUDE_TRACE */
++#endif // INCLUDE_TRACE
+--- ./hotspot/src/share/vm/classfile/classLoaderData.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/classLoaderData.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -31,9 +31,9 @@
+ #include "memory/metaspaceCounters.hpp"
+ #include "runtime/mutex.hpp"
+ #include "utilities/growableArray.hpp"
+-
++#include "utilities/macros.hpp"
+ #if INCLUDE_TRACE
+-# include "utilities/ticks.hpp"
++#include "utilities/ticks.hpp"
+ #endif
+
+ //
+@@ -59,6 +59,7 @@
+ class ClassLoaderDataGraph : public AllStatic {
+ friend class ClassLoaderData;
+ friend class ClassLoaderDataGraphMetaspaceIterator;
++ friend class ClassLoaderDataGraphKlassIteratorAtomic;
+ friend class VMStructs;
+ private:
+ // All CLDs (except the null CLD) can be reached by walking _head->_next->...
+@@ -71,18 +72,26 @@
+
+ static ClassLoaderData* add(Handle class_loader, bool anonymous, TRAPS);
+ static void post_class_unload_events(void);
++ static void clean_metaspaces();
+ public:
+ static ClassLoaderData* find_or_create(Handle class_loader, TRAPS);
+ static void purge();
+ static void clear_claimed_marks();
++ // oops do
+ static void oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim);
++ static void keep_alive_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
+ static void always_strong_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
+- static void keep_alive_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
++ // cld do
++ static void cld_do(CLDClosure* cl);
++ static void roots_cld_do(CLDClosure* strong, CLDClosure* weak);
++ static void keep_alive_cld_do(CLDClosure* cl);
++ static void always_strong_cld_do(CLDClosure* cl);
++ // klass do
+ static void classes_do(KlassClosure* klass_closure);
+ static void classes_do(void f(Klass* const));
+ static void loaded_classes_do(KlassClosure* klass_closure);
+ static void classes_unloading_do(void f(Klass* const));
+- static bool do_unloading(BoolObjectClosure* is_alive);
++ static bool do_unloading(BoolObjectClosure* is_alive, bool clean_alive);
+
+ // CMS support.
+ static void remember_new_clds(bool remember) { _saved_head = (remember ? _head : NULL); }
+@@ -98,10 +107,13 @@
+ }
+ }
+
++ static void free_deallocate_lists();
++
+ static void dump_on(outputStream * const out) PRODUCT_RETURN;
+ static void dump() { dump_on(tty); }
+ static void verify();
+
++ static bool unload_list_contains(const void* x);
+ #ifndef PRODUCT
+ static bool contains_loader_data(ClassLoaderData* loader_data);
+ #endif
+@@ -134,6 +146,7 @@
+ };
+
+ friend class ClassLoaderDataGraph;
++ friend class ClassLoaderDataGraphKlassIteratorAtomic;
+ friend class ClassLoaderDataGraphMetaspaceIterator;
+ friend class MetaDataFactory;
+ friend class Method;
+@@ -149,7 +162,7 @@
+ // classes in the class loader are allocated.
+ Mutex* _metaspace_lock; // Locks the metaspace for allocations and setup.
+ bool _unloading; // true if this class loader goes away
+- bool _keep_alive; // if this CLD can be unloaded for anonymous loaders
++ bool _keep_alive; // if this CLD is kept alive without a keep_alive_object().
+ bool _is_anonymous; // if this CLD is for an anonymous class
+ volatile int _claimed; // true if claimed, for example during GC traces.
+ // To avoid applying oop closure more than once.
+@@ -195,7 +208,6 @@
+
+ void unload();
+ bool keep_alive() const { return _keep_alive; }
+- bool is_alive(BoolObjectClosure* is_alive_closure) const;
+ void classes_do(void f(Klass*));
+ void loaded_classes_do(KlassClosure* klass_closure);
+ void classes_do(void f(InstanceKlass*));
+@@ -207,6 +219,9 @@
+ MetaWord* allocate(size_t size);
+
+ public:
++
++ bool is_alive(BoolObjectClosure* is_alive_closure) const;
++
+ // Accessors
+ Metaspace* metaspace_or_null() const { return _metaspace; }
+
+@@ -240,13 +255,16 @@
+
+ oop class_loader() const { return _class_loader; }
+
++ // The object the GC is using to keep this ClassLoaderData alive.
++ oop keep_alive_object() const;
++
+ // Returns true if this class loader data is for a loader going away.
+ bool is_unloading() const {
+ assert(!(is_the_null_class_loader_data() && _unloading), "The null class loader can never be unloaded");
+ return _unloading;
+ }
+- // Anonymous class loader data doesn't have anything to keep them from
+- // being unloaded during parsing the anonymous class.
++
++ // Used to make sure that this CLD is not unloaded.
+ void set_keep_alive(bool value) { _keep_alive = value; }
+
+ unsigned int identity_hash() {
+@@ -287,6 +305,16 @@
+ void initialize_shared_metaspaces();
+ };
+
++// An iterator that distributes Klasses to parallel worker threads.
++class ClassLoaderDataGraphKlassIteratorAtomic : public StackObj {
++ volatile Klass* _next_klass;
++ public:
++ ClassLoaderDataGraphKlassIteratorAtomic();
++ Klass* next_klass();
++ private:
++ static Klass* next_klass_in_cldg(Klass* klass);
++};
++
+ class ClassLoaderDataGraphMetaspaceIterator : public StackObj {
+ ClassLoaderData* _data;
+ public:
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/classfile/classLoaderExt.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,81 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP
++#define SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP
++
++#include "classfile/classLoader.hpp"
++
++class ClassLoaderExt: public ClassLoader { // AllStatic
++public:
++
++ class Context {
++ const char* _file_name;
++ public:
++ Context(const char* class_name, const char* file_name, TRAPS) {
++ _file_name = file_name;
++ }
++
++ bool check(ClassFileStream* stream, const int classpath_index) {
++ return true;
++ }
++
++ bool should_verify(int classpath_index) {
++ return false;
++ }
++
++ instanceKlassHandle record_result(const int classpath_index,
++ ClassPathEntry* e, instanceKlassHandle result, TRAPS) {
++ if (ClassLoader::add_package(_file_name, classpath_index, THREAD)) {
++ if (DumpSharedSpaces) {
++ result->set_shared_classpath_index(classpath_index);
++ }
++ return result;
++ } else {
++ return instanceKlassHandle(); // NULL
++ }
++ }
++ };
++
++
++ static void add_class_path_entry(const char* path, bool check_for_duplicates,
++ ClassPathEntry* new_entry) {
++ ClassLoader::add_to_list(new_entry);
++ }
++ static void append_boot_classpath(ClassPathEntry* new_entry) {
++ ClassLoader::add_to_list(new_entry);
++ }
++ static void setup_search_paths() {}
++
++ static void init_lookup_cache(TRAPS) {}
++ static void copy_lookup_cache_to_archive(char** top, char* end) {}
++ static char* restore_lookup_cache_from_archive(char* buffer) {return buffer;}
++ static inline bool is_lookup_cache_enabled() {return false;}
++
++ static bool known_to_not_exist(JNIEnv *env, jobject loader, const char *classname, TRAPS) {return false;}
++ static jobjectArray get_lookup_cache_urls(JNIEnv *env, jobject loader, TRAPS) {return NULL;}
++ static jintArray get_lookup_cache(JNIEnv *env, jobject loader, const char *pkgname, TRAPS) {return NULL;}
++};
++
++#endif // SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP
+--- ./hotspot/src/share/vm/classfile/dictionary.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/dictionary.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,6 +28,7 @@
+ #include "memory/iterator.hpp"
+ #include "oops/oop.inline.hpp"
+ #include "prims/jvmtiRedefineClassesTrace.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "utilities/hashtable.inline.hpp"
+
+ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+@@ -129,15 +130,13 @@
+ }
+
+
+-bool Dictionary::do_unloading() {
++void Dictionary::do_unloading() {
+ assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
+- bool class_was_unloaded = false;
+- int index = 0; // Defined here for portability! Do not move
+
+ // Remove unloadable entries and classes from system dictionary
+ // The placeholder array has been handled in always_strong_oops_do.
+ DictionaryEntry* probe = NULL;
+- for (index = 0; index < table_size(); index++) {
++ for (int index = 0; index < table_size(); index++) {
+ for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) {
+ probe = *p;
+ Klass* e = probe->klass();
+@@ -157,16 +156,8 @@
+ // Do we need to delete this system dictionary entry?
+ if (loader_data->is_unloading()) {
+ // If the loader is not live this entry should always be
+- // removed (will never be looked up again). Note that this is
+- // not the same as unloading the referred class.
+- if (k_def_class_loader_data == loader_data) {
+- // This is the defining entry, so the referred class is about
+- // to be unloaded.
+- class_was_unloaded = true;
+- }
+- // Also remove this system dictionary entry.
++ // removed (will never be looked up again).
+ purge_entry = true;
+-
+ } else {
+ // The loader in this entry is alive. If the klass is dead,
+ // (determined by checking the defining class loader)
+@@ -195,9 +186,51 @@
+ p = probe->next_addr();
+ }
+ }
+- return class_was_unloaded;
+ }
+
++void Dictionary::roots_oops_do(OopClosure* strong, OopClosure* weak) {
++ // Skip the strong roots probe marking if the closures are the same.
++ if (strong == weak) {
++ oops_do(strong);
++ return;
++ }
++
++ for (int index = 0; index < table_size(); index++) {
++ for (DictionaryEntry *probe = bucket(index);
++ probe != NULL;
++ probe = probe->next()) {
++ Klass* e = probe->klass();
++ ClassLoaderData* loader_data = probe->loader_data();
++ if (is_strongly_reachable(loader_data, e)) {
++ probe->set_strongly_reachable();
++ }
++ }
++ }
++ _pd_cache_table->roots_oops_do(strong, weak);
++}
++
++void Dictionary::remove_classes_in_error_state() {
++ assert(DumpSharedSpaces, "supported only when dumping");
++ DictionaryEntry* probe = NULL;
++ for (int index = 0; index < table_size(); index++) {
++ for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) {
++ probe = *p;
++ InstanceKlass* ik = InstanceKlass::cast(probe->klass());
++ if (ik->is_in_error_state()) { // purge this entry
++ *p = probe->next();
++ if (probe == _current_class_entry) {
++ _current_class_entry = NULL;
++ }
++ free_entry(probe);
++ ResourceMark rm;
++ tty->print_cr("Preload Warning: Removed error class: %s", ik->external_name());
++ continue;
++ }
++
++ p = probe->next_addr();
++ }
++ }
++}
+
+ void Dictionary::always_strong_oops_do(OopClosure* blk) {
+ // Follow all system classes and temporary placeholders in dictionary; only
+@@ -489,6 +522,23 @@
+ }
+ }
+
++void ProtectionDomainCacheTable::roots_oops_do(OopClosure* strong, OopClosure* weak) {
++ for (int index = 0; index < table_size(); index++) {
++ for (ProtectionDomainCacheEntry* probe = bucket(index);
++ probe != NULL;
++ probe = probe->next()) {
++ if (probe->is_strongly_reachable()) {
++ probe->reset_strongly_reachable();
++ probe->oops_do(strong);
++ } else {
++ if (weak != NULL) {
++ probe->oops_do(weak);
++ }
++ }
++ }
++ }
++}
++
+ uint ProtectionDomainCacheTable::bucket_size() {
+ return sizeof(ProtectionDomainCacheEntry);
+ }
+@@ -655,16 +705,17 @@
+
+
+ // ----------------------------------------------------------------------------
+-#ifndef PRODUCT
+
+-void Dictionary::print() {
++void Dictionary::print(bool details) {
+ ResourceMark rm;
+ HandleMark hm;
+
+- tty->print_cr("Java system dictionary (table_size=%d, classes=%d)",
+- table_size(), number_of_entries());
+- tty->print_cr("^ indicates that initiating loader is different from "
+- "defining loader");
++ if (details) {
++ tty->print_cr("Java system dictionary (table_size=%d, classes=%d)",
++ table_size(), number_of_entries());
++ tty->print_cr("^ indicates that initiating loader is different from "
++ "defining loader");
++ }
+
+ for (int index = 0; index < table_size(); index++) {
+ for (DictionaryEntry* probe = bucket(index);
+@@ -675,21 +726,28 @@
+ ClassLoaderData* loader_data = probe->loader_data();
+ bool is_defining_class =
+ (loader_data == InstanceKlass::cast(e)->class_loader_data());
+- tty->print("%s%s", is_defining_class ? " " : "^",
++ tty->print("%s%s", ((!details) || is_defining_class) ? " " : "^",
+ e->external_name());
+
++ if (details) {
+ tty->print(", loader ");
+- loader_data->print_value();
++ if (loader_data != NULL) {
++ loader_data->print_value();
++ } else {
++ tty->print("NULL");
++ }
++ }
+ tty->cr();
+ }
+ }
+- tty->cr();
+- _pd_cache_table->print();
++
++ if (details) {
++ tty->cr();
++ _pd_cache_table->print();
++ }
+ tty->cr();
+ }
+
+-#endif
+-
+ void Dictionary::verify() {
+ guarantee(number_of_entries() >= 0, "Verify of system dictionary failed");
+
+--- ./hotspot/src/share/vm/classfile/dictionary.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/dictionary.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -89,6 +89,7 @@
+ // GC support
+ void oops_do(OopClosure* f);
+ void always_strong_oops_do(OopClosure* blk);
++ void roots_oops_do(OopClosure* strong, OopClosure* weak);
+
+ void always_strong_classes_do(KlassClosure* closure);
+
+@@ -99,6 +100,7 @@
+ void methods_do(void f(Method*));
+
+ void unlink(BoolObjectClosure* is_alive);
++ void remove_classes_in_error_state();
+
+ // Classes loaded by the bootstrap loader are always strongly reachable.
+ // If we're not doing class unloading, all classes are strongly reachable.
+@@ -107,9 +109,8 @@
+ return (loader_data->is_the_null_class_loader_data() || !ClassUnloading);
+ }
+
+- // Unload (that is, break root links to) all unmarked classes and
+- // loaders. Returns "true" iff something was unloaded.
+- bool do_unloading();
++ // Unload (that is, break root links to) all unmarked classes and loaders.
++ void do_unloading();
+
+ // Protection domains
+ Klass* find(int index, unsigned int hash, Symbol* name,
+@@ -126,9 +127,7 @@
+
+ ProtectionDomainCacheEntry* cache_get(oop protection_domain);
+
+-#ifndef PRODUCT
+- void print();
+-#endif
++ void print(bool details = true);
+ void verify();
+ };
+
+@@ -218,6 +217,7 @@
+ // GC support
+ void oops_do(OopClosure* f);
+ void always_strong_oops_do(OopClosure* f);
++ void roots_oops_do(OopClosure* strong, OopClosure* weak);
+
+ static uint bucket_size();
+
+--- ./hotspot/src/share/vm/classfile/javaClasses.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/javaClasses.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -41,6 +41,7 @@
+ #include "oops/method.hpp"
+ #include "oops/symbol.hpp"
+ #include "oops/typeArrayOop.hpp"
++#include "prims/jvmtiRedefineClassesTrace.hpp"
+ #include "runtime/fieldDescriptor.hpp"
+ #include "runtime/handles.inline.hpp"
+ #include "runtime/interfaceSupport.hpp"
+@@ -463,12 +464,11 @@
+ return true;
+ }
+
+-void java_lang_String::print(Handle java_string, outputStream* st) {
+- oop obj = java_string();
+- assert(obj->klass() == SystemDictionary::String_klass(), "must be java_string");
+- typeArrayOop value = java_lang_String::value(obj);
+- int offset = java_lang_String::offset(obj);
+- int length = java_lang_String::length(obj);
++void java_lang_String::print(oop java_string, outputStream* st) {
++ assert(java_string->klass() == SystemDictionary::String_klass(), "must be java_string");
++ typeArrayOop value = java_lang_String::value(java_string);
++ int offset = java_lang_String::offset(java_string);
++ int length = java_lang_String::length(java_string);
+
+ int end = MIN2(length, 100);
+ if (value == NULL) {
+@@ -549,7 +549,7 @@
+ }
+ }
+ }
+- create_mirror(k, Handle(NULL), CHECK);
++ create_mirror(k, Handle(NULL), Handle(NULL), CHECK);
+ }
+
+ void java_lang_Class::initialize_mirror_fields(KlassHandle k,
+@@ -569,7 +569,8 @@
+ InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, mirror, CHECK);
+ }
+
+-void java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) {
++void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
++ Handle protection_domain, TRAPS) {
+ assert(k->java_mirror() == NULL, "should only assign mirror once");
+ // Use this moment of initialization to cache modifier_flags also,
+ // to support Class.getModifiers(). Instance classes recalculate
+@@ -624,6 +625,10 @@
+ }
+ }
+
++ // set the classLoader field in the java_lang_Class instance
++ assert(class_loader() == k->class_loader(), "should be same");
++ set_class_loader(mirror(), class_loader());
++
+ // Setup indirection from klass->mirror last
+ // after any exceptions can happen during allocations.
+ if (!k.is_null()) {
+@@ -685,6 +690,18 @@
+ }
+
+
++void java_lang_Class::set_class_loader(oop java_class, oop loader) {
++ // jdk7 runs Queens in bootstrapping and jdk8-9 has no coordinated pushes yet.
++ if (_class_loader_offset != 0) {
++ java_class->obj_field_put(_class_loader_offset, loader);
++ }
++}
++
++oop java_lang_Class::class_loader(oop java_class) {
++ assert(_class_loader_offset != 0, "must be set");
++ return java_class->obj_field(_class_loader_offset);
++}
++
+ oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
+ // This should be improved by adding a field at the Java level or by
+ // introducing a new VM klass (see comment in ClassFileParser)
+@@ -844,6 +861,12 @@
+ compute_optional_offset(classRedefinedCount_offset,
+ klass_oop, vmSymbols::classRedefinedCount_name(), vmSymbols::int_signature());
+
++ // Needs to be optional because the old build runs Queens during bootstrapping
++ // and jdk8-9 doesn't have coordinated pushes yet.
++ compute_optional_offset(_class_loader_offset,
++ klass_oop, vmSymbols::classLoader_name(),
++ vmSymbols::classloader_signature());
++
+ CLASS_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
+ }
+
+@@ -2753,12 +2776,35 @@
+ return (Metadata*)mname->address_field(_vmtarget_offset);
+ }
+
++bool java_lang_invoke_MemberName::is_method(oop mname) {
++ assert(is_instance(mname), "must be MemberName");
++ return (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0;
++}
++
+ #if INCLUDE_JVMTI
+ // Can be executed on VM thread only
+-void java_lang_invoke_MemberName::adjust_vmtarget(oop mname, Metadata* ref) {
+- assert((is_instance(mname) && (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0), "wrong type");
++void java_lang_invoke_MemberName::adjust_vmtarget(oop mname, Method* old_method,
++ Method* new_method, bool* trace_name_printed) {
++ assert(is_method(mname), "wrong type");
+ assert(Thread::current()->is_VM_thread(), "not VM thread");
+- mname->address_field_put(_vmtarget_offset, (address)ref);
++
++ Method* target = (Method*)mname->address_field(_vmtarget_offset);
++ if (target == old_method) {
++ mname->address_field_put(_vmtarget_offset, (address)new_method);
++
++ if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
++ if (!(*trace_name_printed)) {
++ // RC_TRACE_MESG macro has an embedded ResourceMark
++ RC_TRACE_MESG(("adjust: name=%s",
++ old_method->method_holder()->external_name()));
++ *trace_name_printed = true;
++ }
++ // RC_TRACE macro has an embedded ResourceMark
++ RC_TRACE(0x00400000, ("MemberName method update: %s(%s)",
++ new_method->name()->as_C_string(),
++ new_method->signature()->as_C_string()));
++ }
++ }
+ }
+ #endif // INCLUDE_JVMTI
+
+@@ -3083,6 +3129,7 @@
+ int java_lang_Class::_array_klass_offset;
+ int java_lang_Class::_oop_size_offset;
+ int java_lang_Class::_static_oop_field_count_offset;
++int java_lang_Class::_class_loader_offset;
+ int java_lang_Class::_protection_domain_offset;
+ int java_lang_Class::_init_lock_offset;
+ int java_lang_Class::_signers_offset;
+--- ./hotspot/src/share/vm/classfile/javaClasses.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/javaClasses.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -208,7 +208,7 @@
+ }
+
+ // Debugging
+- static void print(Handle java_string, outputStream* st);
++ static void print(oop java_string, outputStream* st);
+ friend class JavaClasses;
+ };
+
+@@ -239,19 +239,23 @@
+ static int _protection_domain_offset;
+ static int _init_lock_offset;
+ static int _signers_offset;
++ static int _class_loader_offset;
+
+ static bool offsets_computed;
+ static int classRedefinedCount_offset;
++
+ static GrowableArray<Klass*>* _fixup_mirror_list;
+
+ static void set_init_lock(oop java_class, oop init_lock);
+ static void set_protection_domain(oop java_class, oop protection_domain);
++ static void set_class_loader(oop java_class, oop class_loader);
+ static void initialize_mirror_fields(KlassHandle k, Handle mirror, Handle protection_domain, TRAPS);
+ public:
+ static void compute_offsets();
+
+ // Instance creation
+- static void create_mirror(KlassHandle k, Handle protection_domain, TRAPS);
++ static void create_mirror(KlassHandle k, Handle class_loader,
++ Handle protection_domain, TRAPS);
+ static void fixup_mirror(KlassHandle k, TRAPS);
+ static oop create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
+ // Conversion
+@@ -289,6 +293,8 @@
+ static objArrayOop signers(oop java_class);
+ static void set_signers(oop java_class, objArrayOop signers);
+
++ static oop class_loader(oop java_class);
++
+ static int oop_size(oop java_class);
+ static void set_oop_size(oop java_class, int size);
+ static int static_oop_field_count(oop java_class);
+@@ -1090,7 +1096,8 @@
+ static Metadata* vmtarget(oop mname);
+ static void set_vmtarget(oop mname, Metadata* target);
+ #if INCLUDE_JVMTI
+- static void adjust_vmtarget(oop mname, Metadata* target);
++ static void adjust_vmtarget(oop mname, Method* old_method, Method* new_method,
++ bool* trace_name_printed);
+ #endif // INCLUDE_JVMTI
+
+ static intptr_t vmindex(oop mname);
+@@ -1104,6 +1111,8 @@
+ return obj != NULL && is_subclass(obj->klass());
+ }
+
++ static bool is_method(oop obj);
++
+ // Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants):
+ enum {
+ MN_IS_METHOD = 0x00010000, // method (not constructor)
+--- ./hotspot/src/share/vm/classfile/metadataOnStackMark.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/metadataOnStackMark.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -31,24 +31,25 @@
+ #include "runtime/synchronizer.hpp"
+ #include "runtime/thread.hpp"
+ #include "services/threadService.hpp"
+-#include "utilities/growableArray.hpp"
++#include "utilities/chunkedList.hpp"
+
++volatile MetadataOnStackBuffer* MetadataOnStackMark::_used_buffers = NULL;
++volatile MetadataOnStackBuffer* MetadataOnStackMark::_free_buffers = NULL;
+
+-// Keep track of marked on-stack metadata so it can be cleared.
+-GrowableArray<Metadata*>* _marked_objects = NULL;
+ NOT_PRODUCT(bool MetadataOnStackMark::_is_active = false;)
+
+ // Walk metadata on the stack and mark it so that redefinition doesn't delete
+ // it. Class unloading also walks the previous versions and might try to
+ // delete it, so this class is used by class unloading also.
+-MetadataOnStackMark::MetadataOnStackMark() {
++MetadataOnStackMark::MetadataOnStackMark(bool visit_code_cache) {
+ assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
++ assert(_used_buffers == NULL, "sanity check");
+ NOT_PRODUCT(_is_active = true;)
+- if (_marked_objects == NULL) {
+- _marked_objects = new (ResourceObj::C_HEAP, mtClass) GrowableArray<Metadata*>(1000, true);
++
++ Threads::metadata_do(Metadata::mark_on_stack);
++ if (visit_code_cache) {
++ CodeCache::alive_nmethods_do(nmethod::mark_on_stack);
+ }
+- Threads::metadata_do(Metadata::mark_on_stack);
+- CodeCache::alive_nmethods_do(nmethod::mark_on_stack);
+ CompileBroker::mark_on_stack();
+ JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack);
+ ThreadService::metadata_do(Metadata::mark_on_stack);
+@@ -59,15 +60,93 @@
+ // Unmark everything that was marked. Can't do the same walk because
+ // redefine classes messes up the code cache so the set of methods
+ // might not be the same.
+- for (int i = 0; i< _marked_objects->length(); i++) {
+- _marked_objects->at(i)->set_on_stack(false);
++
++ retire_buffer_for_thread(Thread::current());
++
++ MetadataOnStackBuffer* buffer = const_cast<MetadataOnStackBuffer* >(_used_buffers);
++ while (buffer != NULL) {
++ // Clear on stack state for all metadata.
++ size_t size = buffer->size();
++ for (size_t i = 0; i < size; i++) {
++ Metadata* md = buffer->at(i);
++ md->set_on_stack(false);
++ }
++
++ MetadataOnStackBuffer* next = buffer->next_used();
++
++ // Move the buffer to the free list.
++ buffer->clear();
++ buffer->set_next_used(NULL);
++ buffer->set_next_free(const_cast<MetadataOnStackBuffer*>(_free_buffers));
++ _free_buffers = buffer;
++
++ // Step to next used buffer.
++ buffer = next;
+ }
+- _marked_objects->clear(); // reuse growable array for next time.
++
++ _used_buffers = NULL;
++
+ NOT_PRODUCT(_is_active = false;)
+ }
+
++void MetadataOnStackMark::retire_buffer(MetadataOnStackBuffer* buffer) {
++ if (buffer == NULL) {
++ return;
++ }
++
++ MetadataOnStackBuffer* old_head;
++
++ do {
++ old_head = const_cast<MetadataOnStackBuffer*>(_used_buffers);
++ buffer->set_next_used(old_head);
++ } while (Atomic::cmpxchg_ptr(buffer, &_used_buffers, old_head) != old_head);
++}
++
++void MetadataOnStackMark::retire_buffer_for_thread(Thread* thread) {
++ retire_buffer(thread->metadata_on_stack_buffer());
++ thread->set_metadata_on_stack_buffer(NULL);
++}
++
++bool MetadataOnStackMark::has_buffer_for_thread(Thread* thread) {
++ return thread->metadata_on_stack_buffer() != NULL;
++}
++
++MetadataOnStackBuffer* MetadataOnStackMark::allocate_buffer() {
++ MetadataOnStackBuffer* allocated;
++ MetadataOnStackBuffer* new_head;
++
++ do {
++ allocated = const_cast<MetadataOnStackBuffer*>(_free_buffers);
++ if (allocated == NULL) {
++ break;
++ }
++ new_head = allocated->next_free();
++ } while (Atomic::cmpxchg_ptr(new_head, &_free_buffers, allocated) != allocated);
++
++ if (allocated == NULL) {
++ allocated = new MetadataOnStackBuffer();
++ }
++
++ assert(!allocated->is_full(), err_msg("Should not be full: " PTR_FORMAT, p2i(allocated)));
++
++ return allocated;
++}
++
+ // Record which objects are marked so we can unmark the same objects.
+-void MetadataOnStackMark::record(Metadata* m) {
++void MetadataOnStackMark::record(Metadata* m, Thread* thread) {
+ assert(_is_active, "metadata on stack marking is active");
+- _marked_objects->push(m);
++
++ MetadataOnStackBuffer* buffer = thread->metadata_on_stack_buffer();
++
++ if (buffer != NULL && buffer->is_full()) {
++ retire_buffer(buffer);
++ buffer = NULL;
++ }
++
++ if (buffer == NULL) {
++ buffer = allocate_buffer();
++ thread->set_metadata_on_stack_buffer(buffer);
++ }
++
++ buffer->push(m);
+ }
+--- ./hotspot/src/share/vm/classfile/metadataOnStackMark.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/metadataOnStackMark.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,9 +26,12 @@
+ #define SHARE_VM_CLASSFILE_METADATAONSTACKMARK_HPP
+
+ #include "memory/allocation.hpp"
++#include "utilities/chunkedList.hpp"
+
+ class Metadata;
+
++typedef ChunkedList<Metadata*, mtInternal> MetadataOnStackBuffer;
++
+ // Helper class to mark and unmark metadata used on the stack as either handles
+ // or executing methods, so that it can't be deleted during class redefinition
+ // and class unloading.
+@@ -36,10 +39,20 @@
+ // metadata during parsing, relocated methods, and methods in backtraces.
+ class MetadataOnStackMark : public StackObj {
+ NOT_PRODUCT(static bool _is_active;)
++
++ static volatile MetadataOnStackBuffer* _used_buffers;
++ static volatile MetadataOnStackBuffer* _free_buffers;
++
++ static MetadataOnStackBuffer* allocate_buffer();
++ static void retire_buffer(MetadataOnStackBuffer* buffer);
++
+ public:
+- MetadataOnStackMark();
+- ~MetadataOnStackMark();
+- static void record(Metadata* m);
++ MetadataOnStackMark(bool visit_code_cache);
++ ~MetadataOnStackMark();
++
++ static void record(Metadata* m, Thread* thread);
++ static void retire_buffer_for_thread(Thread* thread);
++ static bool has_buffer_for_thread(Thread* thread);
+ };
+
+ #endif // SHARE_VM_CLASSFILE_METADATAONSTACKMARK_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/classfile/sharedClassUtil.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
++#define SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
++
++#include "classfile/sharedPathsMiscInfo.hpp"
++#include "memory/filemap.hpp"
++
++class SharedClassUtil : AllStatic {
++public:
++
++ static SharedPathsMiscInfo* allocate_shared_paths_misc_info() {
++ return new SharedPathsMiscInfo();
++ }
++
++ static SharedPathsMiscInfo* allocate_shared_paths_misc_info(char* buf, int size) {
++ return new SharedPathsMiscInfo(buf, size);
++ }
++
++ static FileMapInfo::FileMapHeader* allocate_file_map_header() {
++ return new FileMapInfo::FileMapHeader();
++ }
++
++ static size_t file_map_header_size() {
++ return sizeof(FileMapInfo::FileMapHeader);
++ }
++
++ static size_t shared_class_path_entry_size() {
++ return sizeof(SharedClassPathEntry);
++ }
++
++ static void update_shared_classpath(ClassPathEntry *cpe,
++ SharedClassPathEntry* ent,
++ time_t timestamp,
++ long filesize, TRAPS) {
++ ent->_timestamp = timestamp;
++ ent->_filesize = filesize;
++ }
++
++ static void initialize(TRAPS) {}
++
++ inline static bool is_shared_boot_class(Klass* klass) {
++ return (klass->_shared_class_path_index >= 0);
++ }
++};
++
++#endif // SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/classfile/sharedPathsMiscInfo.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,154 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "classfile/classLoader.hpp"
++#include "classfile/classLoaderData.inline.hpp"
++#include "classfile/sharedPathsMiscInfo.hpp"
++#include "memory/allocation.inline.hpp"
++#include "memory/metaspaceShared.hpp"
++#include "runtime/arguments.hpp"
++
++void SharedPathsMiscInfo::add_path(const char* path, int type) {
++ if (TraceClassPaths) {
++ tty->print("[type=%s] ", type_name(type));
++ trace_class_path("[Add misc shared path ", path);
++ }
++ write(path, strlen(path) + 1);
++ write_jint(jint(type));
++}
++
++void SharedPathsMiscInfo::ensure_size(size_t needed_bytes) {
++ assert(_allocated, "cannot modify buffer during validation.");
++ int used = get_used_bytes();
++ int target = used + int(needed_bytes);
++ if (target > _buf_size) {
++ _buf_size = _buf_size * 2 + (int)needed_bytes;
++ _buf_start = REALLOC_C_HEAP_ARRAY(char, _buf_start, _buf_size, mtClass);
++ _cur_ptr = _buf_start + used;
++ _end_ptr = _buf_start + _buf_size;
++ }
++}
++
++void SharedPathsMiscInfo::write(const void* ptr, size_t size) {
++ ensure_size(size);
++ memcpy(_cur_ptr, ptr, size);
++ _cur_ptr += size;
++}
++
++bool SharedPathsMiscInfo::read(void* ptr, size_t size) {
++ if (_cur_ptr + size <= _end_ptr) {
++ memcpy(ptr, _cur_ptr, size);
++ _cur_ptr += size;
++ return true;
++ }
++ return false;
++}
++
++bool SharedPathsMiscInfo::fail(const char* msg, const char* name) {
++ ClassLoader::trace_class_path(msg, name);
++ MetaspaceShared::set_archive_loading_failed();
++ return false;
++}
++
++bool SharedPathsMiscInfo::check() {
++ // The whole buffer must be 0 terminated so that we can use strlen and strcmp
++ // without fear.
++ _end_ptr -= sizeof(jint);
++ if (_cur_ptr >= _end_ptr) {
++ return fail("Truncated archive file header");
++ }
++ if (*_end_ptr != 0) {
++ return fail("Corrupted archive file header");
++ }
++
++ while (_cur_ptr < _end_ptr) {
++ jint type;
++ const char* path = _cur_ptr;
++ _cur_ptr += strlen(path) + 1;
++ if (!read_jint(&type)) {
++ return fail("Corrupted archive file header");
++ }
++ if (TraceClassPaths) {
++ tty->print("[type=%s ", type_name(type));
++ print_path(tty, type, path);
++ tty->print_cr("]");
++ }
++ if (!check(type, path)) {
++ if (!PrintSharedArchiveAndExit) {
++ return false;
++ }
++ } else {
++ trace_class_path("[ok");
++ }
++ }
++
++ return true;
++}
++
++bool SharedPathsMiscInfo::check(jint type, const char* path) {
++ switch (type) {
++ case BOOT:
++ if (strcmp(path, Arguments::get_sysclasspath()) != 0) {
++ return fail("[BOOT classpath mismatch, actual: -Dsun.boot.class.path=", Arguments::get_sysclasspath());
++ }
++ break;
++ case NON_EXIST: // fall-through
++ case REQUIRED:
++ {
++ struct stat st;
++ if (os::stat(path, &st) != 0) {
++ // The file does not actually exist
++ if (type == REQUIRED) {
++ // but we require it to exist -> fail
++ return fail("Required file doesn't exist");
++ }
++ } else {
++ // The file actually exists
++ if (type == NON_EXIST) {
++ // But we want it to not exist -> fail
++ return fail("File must not exist");
++ }
++ time_t timestamp;
++ long filesize;
++
++ if (!read_time(&timestamp) || !read_long(&filesize)) {
++ return fail("Corrupted archive file header");
++ }
++ if (timestamp != st.st_mtime) {
++ return fail("Timestamp mismatch");
++ }
++ if (filesize != st.st_size) {
++ return fail("File size mismatch");
++ }
++ }
++ }
++ break;
++
++ default:
++ return fail("Corrupted archive file header");
++ }
++
++ return true;
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/classfile/sharedPathsMiscInfo.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,187 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
++#define SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
++
++#include "runtime/os.hpp"
++
++// During dumping time, when processing class paths, we build up the dump-time
++// classpath. The JAR files that exist are stored in the list ClassLoader::_first_entry.
++// However, we need to store other "misc" information for run-time checking, such as
++//
++// + The values of Arguments::get_sysclasspath() used during dumping.
++//
++// + The meta-index file(s) used during dumping (incl modification time and size)
++//
++// + The class path elements specified during dumping but did not exist --
++// these elements must also be specified at run time, and they also must not
++// exist at run time.
++//
++// These misc items are stored in a linear buffer in SharedPathsMiscInfo.
++// The storage format is stream oriented to minimize its size.
++//
++// When writing the information to the archive file, SharedPathsMiscInfo is stored in
++// the archive file header. At run-time, this information is used only during initialization
++// (accessed using read() instead of mmap()), and is deallocated afterwards to save space.
++//
++// The SharedPathsMiscInfo class is used for both creating the the information (during
++// dumping time) and validation (at run time). Different constructors are used in the
++// two situations. See below.
++
++class SharedPathsMiscInfo : public CHeapObj<mtClass> {
++protected:
++ char* _buf_start;
++ char* _cur_ptr;
++ char* _end_ptr;
++ int _buf_size;
++ bool _allocated; // was _buf_start allocated by me?
++ void ensure_size(size_t needed_bytes);
++ void add_path(const char* path, int type);
++
++ void write(const void* ptr, size_t size);
++ bool read(void* ptr, size_t size);
++
++ static void trace_class_path(const char* msg, const char* name = NULL) {
++ ClassLoader::trace_class_path(msg, name);
++ }
++protected:
++ static bool fail(const char* msg, const char* name = NULL);
++ virtual bool check(jint type, const char* path);
++
++public:
++ enum {
++ INITIAL_BUF_SIZE = 128
++ };
++ // This constructor is used when creating the misc information (during dump)
++ SharedPathsMiscInfo() {
++ _buf_size = INITIAL_BUF_SIZE;
++ _cur_ptr = _buf_start = NEW_C_HEAP_ARRAY(char, _buf_size, mtClass);
++ _allocated = true;
++ }
++ // This constructor is used when validating the misc info (during run time)
++ SharedPathsMiscInfo(char *buff, int size) {
++ _cur_ptr = _buf_start = buff;
++ _end_ptr = _buf_start + size;
++ _buf_size = size;
++ _allocated = false;
++ }
++ ~SharedPathsMiscInfo() {
++ if (_allocated) {
++ FREE_C_HEAP_ARRAY(char, _buf_start, mtClass);
++ }
++ }
++ int get_used_bytes() {
++ return _cur_ptr - _buf_start;
++ }
++ void* buffer() {
++ return _buf_start;
++ }
++
++ // writing --
++
++ // The path must not exist at run-time
++ void add_nonexist_path(const char* path) {
++ add_path(path, NON_EXIST);
++ }
++
++ // The path must exist and have required size and modification time
++ void add_required_file(const char* path) {
++ add_path(path, REQUIRED);
++
++ struct stat st;
++ if (os::stat(path, &st) != 0) {
++ assert(0, "sanity");
++ ClassLoader::exit_with_path_failure("failed to os::stat(%s)", path); // should not happen
++ }
++ write_time(st.st_mtime);
++ write_long(st.st_size);
++ }
++
++ // The path must exist, and must contain exactly <num_entries> files/dirs
++ void add_boot_classpath(const char* path) {
++ add_path(path, BOOT);
++ }
++ int write_jint(jint num) {
++ write(&num, sizeof(num));
++ return 0;
++ }
++ void write_time(time_t t) {
++ write(&t, sizeof(t));
++ }
++ void write_long(long l) {
++ write(&l, sizeof(l));
++ }
++
++ bool dump_to_file(int fd) {
++ int n = get_used_bytes();
++ return (os::write(fd, _buf_start, n) == (size_t)n);
++ }
++
++ // reading --
++
++ enum {
++ BOOT = 1,
++ NON_EXIST = 2,
++ REQUIRED = 3
++ };
++
++ virtual const char* type_name(int type) {
++ switch (type) {
++ case BOOT: return "BOOT";
++ case NON_EXIST: return "NON_EXIST";
++ case REQUIRED: return "REQUIRED";
++ default: ShouldNotReachHere(); return "?";
++ }
++ }
++
++ virtual void print_path(outputStream* out, int type, const char* path) {
++ switch (type) {
++ case BOOT:
++ out->print("Expecting -Dsun.boot.class.path=%s", path);
++ break;
++ case NON_EXIST:
++ out->print("Expecting that %s does not exist", path);
++ break;
++ case REQUIRED:
++ out->print("Expecting that file %s must exist and is not altered", path);
++ break;
++ default:
++ ShouldNotReachHere();
++ }
++ }
++
++ bool check();
++ bool read_jint(jint *ptr) {
++ return read(ptr, sizeof(jint));
++ }
++ bool read_long(long *ptr) {
++ return read(ptr, sizeof(long));
++ }
++ bool read_time(time_t *ptr) {
++ return read(ptr, sizeof(time_t));
++ }
++};
++
++#endif // SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
+--- ./hotspot/src/share/vm/classfile/symbolTable.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/symbolTable.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -36,6 +36,7 @@
+ #include "runtime/mutexLocker.hpp"
+ #include "utilities/hashtable.inline.hpp"
+ #if INCLUDE_ALL_GCS
++#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
+ #include "gc_implementation/g1/g1StringDedup.hpp"
+ #endif
+
+@@ -73,9 +74,9 @@
+ void SymbolTable::initialize_symbols(int arena_alloc_size) {
+ // Initialize the arena for global symbols, size passed in depends on CDS.
+ if (arena_alloc_size == 0) {
+- _arena = new (mtSymbol) Arena();
++ _arena = new (mtSymbol) Arena(mtSymbol);
+ } else {
+- _arena = new (mtSymbol) Arena(arena_alloc_size);
++ _arena = new (mtSymbol) Arena(mtSymbol, arena_alloc_size);
+ }
+ }
+
+@@ -204,7 +205,7 @@
+ }
+ }
+ // If the bucket size is too deep check if this hash code is insufficient.
+- if (count >= BasicHashtable<mtSymbol>::rehash_count && !needs_rehashing()) {
++ if (count >= rehash_count && !needs_rehashing()) {
+ _needs_rehashing = check_rehash_table(count);
+ }
+ return NULL;
+@@ -655,7 +656,7 @@
+ }
+ }
+ // If the bucket size is too deep check if this hash code is insufficient.
+- if (count >= BasicHashtable<mtSymbol>::rehash_count && !needs_rehashing()) {
++ if (count >= rehash_count && !needs_rehashing()) {
+ _needs_rehashing = check_rehash_table(count);
+ }
+ return NULL;
+@@ -704,11 +705,26 @@
+ return lookup(chars, length);
+ }
+
++// Tell the GC that this string was looked up in the StringTable.
++static void ensure_string_alive(oop string) {
++ // A lookup in the StringTable could return an object that was previously
++ // considered dead. The SATB part of G1 needs to get notified about this
++ // potential resurrection, otherwise the marking might not find the object.
++#if INCLUDE_ALL_GCS
++ if (UseG1GC && string != NULL) {
++ G1SATBCardTableModRefBS::enqueue(string);
++ }
++#endif
++}
+
+ oop StringTable::lookup(jchar* name, int len) {
+ unsigned int hash = hash_string(name, len);
+ int index = the_table()->hash_to_index(hash);
+- return the_table()->lookup(index, name, len, hash);
++ oop string = the_table()->lookup(index, name, len, hash);
++
++ ensure_string_alive(string);
++
++ return string;
+ }
+
+
+@@ -719,7 +735,10 @@
+ oop found_string = the_table()->lookup(index, name, len, hashValue);
+
+ // Found
+- if (found_string != NULL) return found_string;
++ if (found_string != NULL) {
++ ensure_string_alive(found_string);
++ return found_string;
++ }
+
+ debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
+ assert(!Universe::heap()->is_in_reserved(name),
+@@ -744,11 +763,17 @@
+
+ // Grab the StringTable_lock before getting the_table() because it could
+ // change at safepoint.
+- MutexLocker ml(StringTable_lock, THREAD);
++ oop added_or_found;
++ {
++ MutexLocker ml(StringTable_lock, THREAD);
++ // Otherwise, add to symbol to table
++ added_or_found = the_table()->basic_add(index, string, name, len,
++ hashValue, CHECK_NULL);
++ }
+
+- // Otherwise, add to symbol to table
+- return the_table()->basic_add(index, string, name, len,
+- hashValue, CHECK_NULL);
++ ensure_string_alive(added_or_found);
++
++ return added_or_found;
+ }
+
+ oop StringTable::intern(Symbol* symbol, TRAPS) {
+--- ./hotspot/src/share/vm/classfile/symbolTable.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/symbolTable.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -74,7 +74,7 @@
+ operator Symbol*() { return _temp; }
+ };
+
+-class SymbolTable : public Hashtable<Symbol*, mtSymbol> {
++class SymbolTable : public RehashableHashtable<Symbol*, mtSymbol> {
+ friend class VMStructs;
+ friend class ClassFileParser;
+
+@@ -110,10 +110,10 @@
+ Symbol* lookup(int index, const char* name, int len, unsigned int hash);
+
+ SymbolTable()
+- : Hashtable<Symbol*, mtSymbol>(SymbolTableSize, sizeof (HashtableEntry<Symbol*, mtSymbol>)) {}
++ : RehashableHashtable<Symbol*, mtSymbol>(SymbolTableSize, sizeof (HashtableEntry<Symbol*, mtSymbol>)) {}
+
+ SymbolTable(HashtableBucket<mtSymbol>* t, int number_of_entries)
+- : Hashtable<Symbol*, mtSymbol>(SymbolTableSize, sizeof (HashtableEntry<Symbol*, mtSymbol>), t,
++ : RehashableHashtable<Symbol*, mtSymbol>(SymbolTableSize, sizeof (HashtableEntry<Symbol*, mtSymbol>), t,
+ number_of_entries) {}
+
+ // Arena for permanent symbols (null class loader) that are never unloaded
+@@ -252,7 +252,7 @@
+ static int parallel_claimed_index() { return _parallel_claimed_idx; }
+ };
+
+-class StringTable : public Hashtable<oop, mtSymbol> {
++class StringTable : public RehashableHashtable<oop, mtSymbol> {
+ friend class VMStructs;
+
+ private:
+@@ -278,11 +278,11 @@
+ // in the range [start_idx, end_idx).
+ static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed);
+
+- StringTable() : Hashtable<oop, mtSymbol>((int)StringTableSize,
++ StringTable() : RehashableHashtable<oop, mtSymbol>((int)StringTableSize,
+ sizeof (HashtableEntry<oop, mtSymbol>)) {}
+
+ StringTable(HashtableBucket<mtSymbol>* t, int number_of_entries)
+- : Hashtable<oop, mtSymbol>((int)StringTableSize, sizeof (HashtableEntry<oop, mtSymbol>), t,
++ : RehashableHashtable<oop, mtSymbol>((int)StringTableSize, sizeof (HashtableEntry<oop, mtSymbol>), t,
+ number_of_entries) {}
+ public:
+ // The string table
+--- ./hotspot/src/share/vm/classfile/systemDictionary.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -30,10 +30,15 @@
+ #include "classfile/placeholders.hpp"
+ #include "classfile/resolutionErrors.hpp"
+ #include "classfile/systemDictionary.hpp"
++#if INCLUDE_CDS
++#include "classfile/sharedClassUtil.hpp"
++#include "classfile/systemDictionaryShared.hpp"
++#endif
+ #include "classfile/vmSymbols.hpp"
+ #include "compiler/compileBroker.hpp"
+ #include "interpreter/bytecodeStream.hpp"
+ #include "interpreter/interpreter.hpp"
++#include "memory/filemap.hpp"
+ #include "memory/gcLocker.hpp"
+ #include "memory/oopFactory.hpp"
+ #include "oops/instanceKlass.hpp"
+@@ -46,20 +51,21 @@
+ #include "oops/typeArrayKlass.hpp"
+ #include "prims/jvmtiEnvBase.hpp"
+ #include "prims/methodHandles.hpp"
++#include "runtime/arguments.hpp"
+ #include "runtime/biasedLocking.hpp"
+ #include "runtime/fieldType.hpp"
+ #include "runtime/handles.inline.hpp"
+ #include "runtime/java.hpp"
+ #include "runtime/javaCalls.hpp"
+ #include "runtime/mutexLocker.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/signature.hpp"
+ #include "services/classLoadingService.hpp"
+ #include "services/threadService.hpp"
+ #include "utilities/macros.hpp"
+ #include "utilities/ticks.hpp"
+-
+ #if INCLUDE_TRACE
+- #include "trace/tracing.hpp"
++#include "trace/tracing.hpp"
+ #endif
+
+ Dictionary* SystemDictionary::_dictionary = NULL;
+@@ -108,6 +114,8 @@
+ CHECK);
+
+ _java_system_loader = (oop)result.get_jobject();
++
++ CDS_ONLY(SystemDictionaryShared::initialize(CHECK);)
+ }
+
+
+@@ -973,6 +981,7 @@
+ // as the host_klass
+ assert(EnableInvokeDynamic, "");
+ guarantee(host_klass->class_loader() == class_loader(), "should be the same");
++ guarantee(!DumpSharedSpaces, "must not create anonymous classes when dumping");
+ loader_data = ClassLoaderData::anonymous_class_loader_data(class_loader(), CHECK_NULL);
+ loader_data->record_dependency(host_klass(), CHECK_NULL);
+ } else {
+@@ -1134,7 +1143,7 @@
+ return k();
+ }
+
+-
++#if INCLUDE_CDS
+ void SystemDictionary::set_shared_dictionary(HashtableBucket<mtClass>* t, int length,
+ int number_of_entries) {
+ assert(length == _nof_buckets * sizeof(HashtableBucket<mtClass>),
+@@ -1167,15 +1176,21 @@
+ instanceKlassHandle SystemDictionary::load_shared_class(
+ Symbol* class_name, Handle class_loader, TRAPS) {
+ instanceKlassHandle ik (THREAD, find_shared_class(class_name));
+- return load_shared_class(ik, class_loader, THREAD);
++ // Make sure we only return the boot class for the NULL classloader.
++ if (ik.not_null() &&
++ SharedClassUtil::is_shared_boot_class(ik()) && class_loader.is_null()) {
++ Handle protection_domain;
++ return load_shared_class(ik, class_loader, protection_domain, THREAD);
++ }
++ return instanceKlassHandle();
+ }
+
+-instanceKlassHandle SystemDictionary::load_shared_class(
+- instanceKlassHandle ik, Handle class_loader, TRAPS) {
+- assert(class_loader.is_null(), "non-null classloader for shared class?");
++instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik,
++ Handle class_loader,
++ Handle protection_domain, TRAPS) {
+ if (ik.not_null()) {
+ instanceKlassHandle nh = instanceKlassHandle(); // null Handle
+- Symbol* class_name = ik->name();
++ Symbol* class_name = ik->name();
+
+ // Found the class, now load the superclass and interfaces. If they
+ // are shared, add them to the main system dictionary and reset
+@@ -1184,7 +1199,7 @@
+ if (ik->super() != NULL) {
+ Symbol* cn = ik->super()->name();
+ resolve_super_or_fail(class_name, cn,
+- class_loader, Handle(), true, CHECK_(nh));
++ class_loader, protection_domain, true, CHECK_(nh));
+ }
+
+ Array<Klass*>* interfaces = ik->local_interfaces();
+@@ -1197,7 +1212,7 @@
+ // reinitialized yet (they will be once the interface classes
+ // are loaded)
+ Symbol* name = k->name();
+- resolve_super_or_fail(class_name, name, class_loader, Handle(), false, CHECK_(nh));
++ resolve_super_or_fail(class_name, name, class_loader, protection_domain, false, CHECK_(nh));
+ }
+
+ // Adjust methods to recover missing data. They need addresses for
+@@ -1206,30 +1221,45 @@
+
+ // Updating methods must be done under a lock so multiple
+ // threads don't update these in parallel
+- // Shared classes are all currently loaded by the bootstrap
+- // classloader, so this will never cause a deadlock on
+- // a custom class loader lock.
++ //
++ // Shared classes are all currently loaded by either the bootstrap or
++ // internal parallel class loaders, so this will never cause a deadlock
++ // on a custom class loader lock.
+
++ ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
+ {
+ Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
+ check_loader_lock_contention(lockObject, THREAD);
+ ObjectLocker ol(lockObject, THREAD, true);
+- ik->restore_unshareable_info(CHECK_(nh));
++ ik->restore_unshareable_info(loader_data, protection_domain, CHECK_(nh));
+ }
+
+ if (TraceClassLoading) {
+ ResourceMark rm;
+ tty->print("[Loaded %s", ik->external_name());
+ tty->print(" from shared objects file");
++ if (class_loader.not_null()) {
++ tty->print(" by %s", loader_data->loader_name());
++ }
+ tty->print_cr("]");
+ }
++
++ if (DumpLoadedClassList != NULL && classlist_file->is_open()) {
++ // Only dump the classes that can be stored into CDS archive
++ if (SystemDictionaryShared::is_sharing_possible(loader_data)) {
++ ResourceMark rm(THREAD);
++ classlist_file->print_cr("%s", ik->name()->as_C_string());
++ classlist_file->flush();
++ }
++ }
++
+ // notify a class loaded from shared object
+ ClassLoadingService::notify_class_loaded(InstanceKlass::cast(ik()),
+ true /* shared class */);
+ }
+ return ik;
+ }
+-
++#endif // INCLUDE_CDS
+
+ instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) {
+ instanceKlassHandle nh = instanceKlassHandle(); // null Handle
+@@ -1239,8 +1269,10 @@
+ // shared spaces.
+ instanceKlassHandle k;
+ {
++#if INCLUDE_CDS
+ PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time());
+ k = load_shared_class(class_name, class_loader, THREAD);
++#endif
+ }
+
+ if (k.is_null()) {
+@@ -1599,7 +1631,6 @@
+ Universe::flush_dependents_on(k);
+ }
+
+-
+ // ----------------------------------------------------------------------------
+ // GC support
+
+@@ -1612,13 +1643,7 @@
+ // system dictionary and follows the remaining classes' contents.
+
+ void SystemDictionary::always_strong_oops_do(OopClosure* blk) {
+- blk->do_oop(&_java_system_loader);
+- blk->do_oop(&_system_loader_lock_obj);
+-
+- dictionary()->always_strong_oops_do(blk);
+-
+- // Visit extra methods
+- invoke_method_table()->oops_do(blk);
++ roots_oops_do(blk, NULL);
+ }
+
+ void SystemDictionary::always_strong_classes_do(KlassClosure* closure) {
+@@ -1665,12 +1690,11 @@
+
+ // Assumes classes in the SystemDictionary are only unloaded at a safepoint
+ // Note: anonymous classes are not in the SD.
+-bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive) {
++bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive, bool clean_alive) {
+ // First, mark for unload all ClassLoaderData referencing a dead class loader.
+- bool has_dead_loaders = ClassLoaderDataGraph::do_unloading(is_alive);
+- bool unloading_occurred = false;
+- if (has_dead_loaders) {
+- unloading_occurred = dictionary()->do_unloading();
++ bool unloading_occurred = ClassLoaderDataGraph::do_unloading(is_alive, clean_alive);
++ if (unloading_occurred) {
++ dictionary()->do_unloading();
+ constraints()->purge_loader_constraints();
+ resolution_errors()->purge_resolution_errors();
+ }
+@@ -1685,9 +1709,22 @@
+ return unloading_occurred;
+ }
+
++void SystemDictionary::roots_oops_do(OopClosure* strong, OopClosure* weak) {
++ strong->do_oop(&_java_system_loader);
++ strong->do_oop(&_system_loader_lock_obj);
++ CDS_ONLY(SystemDictionaryShared::roots_oops_do(strong);)
++
++ // Adjust dictionary
++ dictionary()->roots_oops_do(strong, weak);
++
++ // Visit extra methods
++ invoke_method_table()->oops_do(strong);
++}
++
+ void SystemDictionary::oops_do(OopClosure* f) {
+ f->do_oop(&_java_system_loader);
+ f->do_oop(&_system_loader_lock_obj);
++ CDS_ONLY(SystemDictionaryShared::oops_do(f);)
+
+ // Adjust dictionary
+ dictionary()->oops_do(f);
+@@ -1749,6 +1786,10 @@
+ invoke_method_table()->methods_do(f);
+ }
+
++void SystemDictionary::remove_classes_in_error_state() {
++ dictionary()->remove_classes_in_error_state();
++}
++
+ // ----------------------------------------------------------------------------
+ // Lazily load klasses
+
+@@ -2235,9 +2276,15 @@
+ spe = NULL;
+ // Must create lots of stuff here, but outside of the SystemDictionary lock.
+ m = Method::make_method_handle_intrinsic(iid, signature, CHECK_(empty));
+- CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_highest_tier,
+- methodHandle(), CompileThreshold, "MH", CHECK_(empty));
+-
++ if (!Arguments::is_interpreter_only()) {
++ // Generate a compiled form of the MH intrinsic.
++ AdapterHandlerLibrary::create_native_wrapper(m);
++ // Check if have the compiled code.
++ if (!m->has_compiled_code()) {
++ THROW_MSG_(vmSymbols::java_lang_VirtualMachineError(),
++ "out of space in CodeCache for method handle intrinsic", empty);
++ }
++ }
+ // Now grab the lock. We might have to throw away the new method,
+ // if a racing thread has managed to install one at the same time.
+ {
+@@ -2251,6 +2298,9 @@
+ }
+
+ assert(spe != NULL && spe->method() != NULL, "");
++ assert(Arguments::is_interpreter_only() || (spe->method()->has_compiled_code() &&
++ spe->method()->code()->entry_point() == spe->method()->from_compiled_entry()),
++ "MH intrinsic invariant");
+ return spe->method();
+ }
+
+@@ -2562,10 +2612,12 @@
+
+
+ // ----------------------------------------------------------------------------
+-#ifndef PRODUCT
++void SystemDictionary::print_shared(bool details) {
++ shared_dictionary()->print(details);
++}
+
+-void SystemDictionary::print() {
+- dictionary()->print();
++void SystemDictionary::print(bool details) {
++ dictionary()->print(details);
+
+ // Placeholders
+ GCMutexLocker mu(SystemDictionary_lock);
+@@ -2575,7 +2627,6 @@
+ constraints()->print();
+ }
+
+-#endif
+
+ void SystemDictionary::verify() {
+ guarantee(dictionary() != NULL, "Verify of system dictionary failed");
+@@ -2613,7 +2664,7 @@
+ class_loader->klass() : (Klass*)NULL);
+ event.commit();
+ }
+-#endif /* INCLUDE_TRACE */
++#endif // INCLUDE_TRACE
+ }
+
+ #ifndef PRODUCT
+--- ./hotspot/src/share/vm/classfile/systemDictionary.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/systemDictionary.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -111,6 +111,7 @@
+ do_klass(SecurityManager_klass, java_lang_SecurityManager, Pre ) \
+ do_klass(ProtectionDomain_klass, java_security_ProtectionDomain, Pre ) \
+ do_klass(AccessControlContext_klass, java_security_AccessControlContext, Pre ) \
++ do_klass(SecureClassLoader_klass, java_security_SecureClassLoader, Pre ) \
+ do_klass(ClassNotFoundException_klass, java_lang_ClassNotFoundException, Pre ) \
+ do_klass(NoClassDefFoundError_klass, java_lang_NoClassDefFoundError, Pre ) \
+ do_klass(LinkageError_klass, java_lang_LinkageError, Pre ) \
+@@ -168,6 +169,17 @@
+ do_klass(StringBuilder_klass, java_lang_StringBuilder, Pre ) \
+ do_klass(misc_Unsafe_klass, sun_misc_Unsafe, Pre ) \
+ \
++ /* support for CDS */ \
++ do_klass(ByteArrayInputStream_klass, java_io_ByteArrayInputStream, Pre ) \
++ do_klass(File_klass, java_io_File, Pre ) \
++ do_klass(URLClassLoader_klass, java_net_URLClassLoader, Pre ) \
++ do_klass(URL_klass, java_net_URL, Pre ) \
++ do_klass(Jar_Manifest_klass, java_util_jar_Manifest, Pre ) \
++ do_klass(sun_misc_Launcher_klass, sun_misc_Launcher, Pre ) \
++ do_klass(sun_misc_Launcher_AppClassLoader_klass, sun_misc_Launcher_AppClassLoader, Pre ) \
++ do_klass(sun_misc_Launcher_ExtClassLoader_klass, sun_misc_Launcher_ExtClassLoader, Pre ) \
++ do_klass(CodeSource_klass, java_security_CodeSource, Pre ) \
++ \
+ /* It's NULL in non-1.4 JDKs. */ \
+ do_klass(StackTraceElement_klass, java_lang_StackTraceElement, Opt ) \
+ /* Universe::is_gte_jdk14x_version() is not set up by this point. */ \
+@@ -227,7 +239,7 @@
+ static Klass* resolve_or_fail(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, TRAPS);
+ // Convenient call for null loader and protection domain.
+ static Klass* resolve_or_fail(Symbol* class_name, bool throw_error, TRAPS);
+-private:
++protected:
+ // handle error translation for resolve_or_null results
+ static Klass* handle_resolution_exception(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, KlassHandle klass_h, TRAPS);
+
+@@ -330,17 +342,21 @@
+
+ // Unload (that is, break root links to) all unmarked classes and
+ // loaders. Returns "true" iff something was unloaded.
+- static bool do_unloading(BoolObjectClosure* is_alive);
++ static bool do_unloading(BoolObjectClosure* is_alive, bool clean_alive = true);
++
++ // Used by DumpSharedSpaces only to remove classes that failed verification
++ static void remove_classes_in_error_state();
+
+ static int calculate_systemdictionary_size(int loadedclasses);
+
+ // Applies "f->do_oop" to all root oops in the system dictionary.
+ static void oops_do(OopClosure* f);
++ static void roots_oops_do(OopClosure* strong, OopClosure* weak);
+
+ // System loader lock
+ static oop system_loader_lock() { return _system_loader_lock_obj; }
+
+-private:
++protected:
+ // Extended Redefine classes support (tbi)
+ static void preloaded_classes_do(KlassClosure* f);
+ static void lazily_loaded_classes_do(KlassClosure* f);
+@@ -353,7 +369,8 @@
+ static void set_shared_dictionary(HashtableBucket<mtClass>* t, int length,
+ int number_of_entries);
+ // Printing
+- static void print() PRODUCT_RETURN;
++ static void print(bool details = true);
++ static void print_shared(bool details = true);
+ static void print_class_statistics() PRODUCT_RETURN;
+ static void print_method_statistics() PRODUCT_RETURN;
+
+@@ -439,7 +456,7 @@
+
+ static void load_abstract_ownable_synchronizer_klass(TRAPS);
+
+-private:
++protected:
+ // Tells whether ClassLoader.loadClassInternal is present
+ static bool has_loadClassInternal() { return _has_loadClassInternal; }
+
+@@ -467,7 +484,7 @@
+
+ // Register a new class loader
+ static ClassLoaderData* register_loader(Handle class_loader, TRAPS);
+-private:
++protected:
+ // Mirrors for primitive classes (created eagerly)
+ static oop check_mirror(oop m) {
+ assert(m != NULL, "mirror not initialized");
+@@ -536,7 +553,7 @@
+ static void delete_resolution_error(ConstantPool* pool);
+ static Symbol* find_resolution_error(constantPoolHandle pool, int which);
+
+- private:
++ protected:
+
+ enum Constants {
+ _loader_constraint_size = 107, // number of entries in constraint table
+@@ -587,7 +604,7 @@
+ friend class CounterDecay;
+ static Klass* try_get_next_class();
+
+-private:
++protected:
+ static void validate_protection_domain(instanceKlassHandle klass,
+ Handle class_loader,
+ Handle protection_domain, TRAPS);
+@@ -614,10 +631,10 @@
+ static instanceKlassHandle find_or_define_instance_class(Symbol* class_name,
+ Handle class_loader,
+ instanceKlassHandle k, TRAPS);
+- static instanceKlassHandle load_shared_class(Symbol* class_name,
+- Handle class_loader, TRAPS);
+ static instanceKlassHandle load_shared_class(instanceKlassHandle ik,
+- Handle class_loader, TRAPS);
++ Handle class_loader,
++ Handle protection_domain,
++ TRAPS);
+ static instanceKlassHandle load_instance_class(Symbol* class_name, Handle class_loader, TRAPS);
+ static Handle compute_loader_lock_object(Handle class_loader, TRAPS);
+ static void check_loader_lock_contention(Handle loader_lock, TRAPS);
+@@ -625,9 +642,12 @@
+ static bool is_parallelDefine(Handle class_loader);
+
+ public:
++ static instanceKlassHandle load_shared_class(Symbol* class_name,
++ Handle class_loader,
++ TRAPS);
+ static bool is_ext_class_loader(Handle class_loader);
+
+-private:
++protected:
+ static Klass* find_shared_class(Symbol* class_name);
+
+ // Setup link to hierarchy
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/classfile/systemDictionaryShared.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++
++#ifndef SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
++#define SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
++
++#include "classfile/systemDictionary.hpp"
++
++class SystemDictionaryShared: public SystemDictionary {
++public:
++ static void initialize(TRAPS) {}
++ static instanceKlassHandle find_or_load_shared_class(Symbol* class_name,
++ Handle class_loader,
++ TRAPS) {
++ return instanceKlassHandle();
++ }
++ static void roots_oops_do(OopClosure* blk) {}
++ static void oops_do(OopClosure* f) {}
++ static bool is_sharing_possible(ClassLoaderData* loader_data) {
++ oop class_loader = loader_data->class_loader();
++ return (class_loader == NULL);
++ }
++};
++
++#endif // SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
+--- ./hotspot/src/share/vm/classfile/verifier.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/verifier.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -43,7 +43,7 @@
+ #include "runtime/handles.inline.hpp"
+ #include "runtime/interfaceSupport.hpp"
+ #include "runtime/javaCalls.hpp"
+-#include "runtime/orderAccess.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/os.hpp"
+ #ifdef TARGET_ARCH_x86
+ # include "bytes_x86.hpp"
+--- ./hotspot/src/share/vm/classfile/vmSymbols.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -92,11 +92,17 @@
+ template(java_lang_CharSequence, "java/lang/CharSequence") \
+ template(java_lang_SecurityManager, "java/lang/SecurityManager") \
+ template(java_security_AccessControlContext, "java/security/AccessControlContext") \
++ template(java_security_CodeSource, "java/security/CodeSource") \
+ template(java_security_ProtectionDomain, "java/security/ProtectionDomain") \
++ template(java_security_SecureClassLoader, "java/security/SecureClassLoader") \
++ template(java_net_URLClassLoader, "java/net/URLClassLoader") \
++ template(java_net_URL, "java/net/URL") \
++ template(java_util_jar_Manifest, "java/util/jar/Manifest") \
+ template(impliesCreateAccessControlContext_name, "impliesCreateAccessControlContext") \
+ template(java_io_OutputStream, "java/io/OutputStream") \
+ template(java_io_Reader, "java/io/Reader") \
+ template(java_io_BufferedReader, "java/io/BufferedReader") \
++ template(java_io_File, "java/io/File") \
+ template(java_io_FileInputStream, "java/io/FileInputStream") \
+ template(java_io_ByteArrayInputStream, "java/io/ByteArrayInputStream") \
+ template(java_io_Serializable, "java/io/Serializable") \
+@@ -107,9 +113,11 @@
+ template(java_util_Hashtable, "java/util/Hashtable") \
+ template(java_lang_Compiler, "java/lang/Compiler") \
+ template(sun_misc_Signal, "sun/misc/Signal") \
++ template(sun_misc_Launcher, "sun/misc/Launcher") \
+ template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \
+ template(getBootClassPathEntryForClass_name, "getBootClassPathEntryForClass") \
+ template(sun_misc_PostVMInitHook, "sun/misc/PostVMInitHook") \
++ template(sun_misc_Launcher_AppClassLoader, "sun/misc/Launcher$AppClassLoader") \
+ template(sun_misc_Launcher_ExtClassLoader, "sun/misc/Launcher$ExtClassLoader") \
+ \
+ /* Java runtime version access */ \
+@@ -398,6 +406,14 @@
+ template(signers_name, "signers_name") \
+ template(loader_data_name, "loader_data") \
+ template(dependencies_name, "dependencies") \
++ template(input_stream_void_signature, "(Ljava/io/InputStream;)V") \
++ template(getFileURL_name, "getFileURL") \
++ template(getFileURL_signature, "(Ljava/io/File;)Ljava/net/URL;") \
++ template(definePackageInternal_name, "definePackageInternal") \
++ template(definePackageInternal_signature, "(Ljava/lang/String;Ljava/util/jar/Manifest;Ljava/net/URL;)V") \
++ template(getProtectionDomain_name, "getProtectionDomain") \
++ template(getProtectionDomain_signature, "(Ljava/security/CodeSource;)Ljava/security/ProtectionDomain;") \
++ template(url_code_signer_array_void_signature, "(Ljava/net/URL;[Ljava/security/CodeSigner;)V") \
+ \
+ /* non-intrinsic name/signature pairs: */ \
+ template(register_method_name, "register") \
+@@ -573,6 +589,7 @@
+ template(serializePropertiesToByteArray_signature, "()[B") \
+ template(serializeAgentPropertiesToByteArray_name, "serializeAgentPropertiesToByteArray") \
+ template(classRedefinedCount_name, "classRedefinedCount") \
++ template(classLoader_name, "classLoader") \
+ \
+ /* trace signatures */ \
+ TRACE_TEMPLATES(template) \
+@@ -772,6 +789,11 @@
+ do_name( encodeISOArray_name, "encodeISOArray") \
+ do_signature(encodeISOArray_signature, "([CI[BII)I") \
+ \
++ do_class(java_math_BigInteger, "java/math/BigInteger") \
++ do_intrinsic(_multiplyToLen, java_math_BigInteger, multiplyToLen_name, multiplyToLen_signature, F_R) \
++ do_name( multiplyToLen_name, "multiplyToLen") \
++ do_signature(multiplyToLen_signature, "([II[II[I)[I") \
++ \
+ /* java/lang/ref/Reference */ \
+ do_intrinsic(_Reference_get, java_lang_ref_Reference, get_name, void_object_signature, F_R) \
+ \
+@@ -790,6 +812,26 @@
+ do_name( decrypt_name, "decrypt") \
+ do_signature(byteArray_int_int_byteArray_int_signature, "([BII[BI)I") \
+ \
++ /* support for sun.security.provider.SHA */ \
++ do_class(sun_security_provider_sha, "sun/security/provider/SHA") \
++ do_intrinsic(_sha_implCompress, sun_security_provider_sha, implCompress_name, implCompress_signature, F_R) \
++ do_name( implCompress_name, "implCompress") \
++ do_signature(implCompress_signature, "([BI)V") \
++ \
++ /* support for sun.security.provider.SHA2 */ \
++ do_class(sun_security_provider_sha2, "sun/security/provider/SHA2") \
++ do_intrinsic(_sha2_implCompress, sun_security_provider_sha2, implCompress_name, implCompress_signature, F_R) \
++ \
++ /* support for sun.security.provider.SHA5 */ \
++ do_class(sun_security_provider_sha5, "sun/security/provider/SHA5") \
++ do_intrinsic(_sha5_implCompress, sun_security_provider_sha5, implCompress_name, implCompress_signature, F_R) \
++ \
++ /* support for sun.security.provider.DigestBase */ \
++ do_class(sun_security_provider_digestbase, "sun/security/provider/DigestBase") \
++ do_intrinsic(_digestBase_implCompressMB, sun_security_provider_digestbase, implCompressMB_name, implCompressMB_signature, F_R) \
++ do_name( implCompressMB_name, "implCompressMultiBlock") \
++ do_signature(implCompressMB_signature, "([BII)I") \
++ \
+ /* support for java.util.zip */ \
+ do_class(java_util_zip_CRC32, "java/util/zip/CRC32") \
+ do_intrinsic(_updateCRC32, java_util_zip_CRC32, update_name, int2_int_signature, F_SN) \
+--- ./hotspot/src/share/vm/code/codeBlob.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/code/codeBlob.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -253,6 +253,7 @@
+
+ void BufferBlob::free( BufferBlob *blob ) {
+ ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
++ blob->flush();
+ {
+ MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ CodeCache::free((CodeBlob*)blob);
+--- ./hotspot/src/share/vm/code/codeCache.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/code/codeCache.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -337,6 +337,11 @@
+ // Walk the list of methods which might contain non-perm oops.
+ void CodeCache::scavenge_root_nmethods_do(CodeBlobClosure* f) {
+ assert_locked_or_safepoint(CodeCache_lock);
++
++ if (UseG1GC) {
++ return;
++ }
++
+ debug_only(mark_scavenge_root_nmethods());
+
+ for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) {
+@@ -362,6 +367,11 @@
+
+ void CodeCache::add_scavenge_root_nmethod(nmethod* nm) {
+ assert_locked_or_safepoint(CodeCache_lock);
++
++ if (UseG1GC) {
++ return;
++ }
++
+ nm->set_on_scavenge_root_list();
+ nm->set_scavenge_root_link(_scavenge_root_nmethods);
+ set_scavenge_root_nmethods(nm);
+@@ -370,6 +380,11 @@
+
+ void CodeCache::drop_scavenge_root_nmethod(nmethod* nm) {
+ assert_locked_or_safepoint(CodeCache_lock);
++
++ if (UseG1GC) {
++ return;
++ }
++
+ print_trace("drop_scavenge_root", nm);
+ nmethod* last = NULL;
+ nmethod* cur = scavenge_root_nmethods();
+@@ -391,6 +406,11 @@
+
+ void CodeCache::prune_scavenge_root_nmethods() {
+ assert_locked_or_safepoint(CodeCache_lock);
++
++ if (UseG1GC) {
++ return;
++ }
++
+ debug_only(mark_scavenge_root_nmethods());
+
+ nmethod* last = NULL;
+@@ -423,6 +443,10 @@
+
+ #ifndef PRODUCT
+ void CodeCache::asserted_non_scavengable_nmethods_do(CodeBlobClosure* f) {
++ if (UseG1GC) {
++ return;
++ }
++
+ // While we are here, verify the integrity of the list.
+ mark_scavenge_root_nmethods();
+ for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) {
+@@ -463,9 +487,36 @@
+ }
+ #endif //PRODUCT
+
++void CodeCache::verify_clean_inline_caches() {
++#ifdef ASSERT
++ FOR_ALL_ALIVE_BLOBS(cb) {
++ if (cb->is_nmethod()) {
++ nmethod* nm = (nmethod*)cb;
++ assert(!nm->is_unloaded(), "Tautology");
++ nm->verify_clean_inline_caches();
++ nm->verify();
++ }
++ }
++#endif
++}
++
++void CodeCache::verify_icholder_relocations() {
++#ifdef ASSERT
++ // make sure that we aren't leaking icholders
++ int count = 0;
++ FOR_ALL_BLOBS(cb) {
++ if (cb->is_nmethod()) {
++ nmethod* nm = (nmethod*)cb;
++ count += nm->verify_icholder_relocations();
++ }
++ }
++
++ assert(count + InlineCacheBuffer::pending_icholder_count() + CompiledICHolder::live_not_claimed_count() ==
++ CompiledICHolder::live_count(), "must agree");
++#endif
++}
+
+ void CodeCache::gc_prologue() {
+- assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called");
+ }
+
+ void CodeCache::gc_epilogue() {
+@@ -478,41 +529,15 @@
+ nm->cleanup_inline_caches();
+ }
+ DEBUG_ONLY(nm->verify());
+- nm->fix_oop_relocations();
++ DEBUG_ONLY(nm->verify_oop_relocations());
+ }
+ }
+ set_needs_cache_clean(false);
+ prune_scavenge_root_nmethods();
+- assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called");
+
+-#ifdef ASSERT
+- // make sure that we aren't leaking icholders
+- int count = 0;
+- FOR_ALL_BLOBS(cb) {
+- if (cb->is_nmethod()) {
+- RelocIterator iter((nmethod*)cb);
+- while(iter.next()) {
+- if (iter.type() == relocInfo::virtual_call_type) {
+- if (CompiledIC::is_icholder_call_site(iter.virtual_call_reloc())) {
+- CompiledIC *ic = CompiledIC_at(iter.reloc());
+- if (TraceCompiledIC) {
+- tty->print("noticed icholder " INTPTR_FORMAT " ", p2i(ic->cached_icholder()));
+- ic->print();
+- }
+- assert(ic->cached_icholder() != NULL, "must be non-NULL");
+- count++;
+- }
+- }
+- }
+- }
+- }
+-
+- assert(count + InlineCacheBuffer::pending_icholder_count() + CompiledICHolder::live_not_claimed_count() ==
+- CompiledICHolder::live_count(), "must agree");
+-#endif
++ verify_icholder_relocations();
+ }
+
+-
+ void CodeCache::verify_oops() {
+ MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ VerifyOopClosure voc;
+@@ -687,7 +712,9 @@
+ void CodeCache::mark_all_nmethods_for_deoptimization() {
+ MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ FOR_ALL_ALIVE_NMETHODS(nm) {
+- nm->mark_for_deoptimization();
++ if (!nm->method()->is_method_handle_intrinsic()) {
++ nm->mark_for_deoptimization();
++ }
+ }
+ }
+
+--- ./hotspot/src/share/vm/code/codeCache.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/code/codeCache.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -134,10 +134,6 @@
+ // to) any unmarked codeBlobs in the cache. Sets "marked_for_unloading"
+ // to "true" iff some code got unloaded.
+ static void do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred);
+- static void oops_do(OopClosure* f) {
+- CodeBlobToOopClosure oopc(f, /*do_marking=*/ false);
+- blobs_do(&oopc);
+- }
+ static void asserted_non_scavengable_nmethods_do(CodeBlobClosure* f = NULL) PRODUCT_RETURN;
+ static void scavenge_root_nmethods_do(CodeBlobClosure* f);
+
+@@ -172,6 +168,9 @@
+ static void set_needs_cache_clean(bool v) { _needs_cache_clean = v; }
+ static void clear_inline_caches(); // clear all inline caches
+
++ static void verify_clean_inline_caches();
++ static void verify_icholder_relocations();
++
+ // Deoptimization
+ static int mark_for_deoptimization(DepChange& changes);
+ #ifdef HOTSWAP
+--- ./hotspot/src/share/vm/code/compiledIC.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/code/compiledIC.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -99,13 +99,13 @@
+ }
+
+ {
+- MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
++ MutexLockerEx pl(SafepointSynchronize::is_at_safepoint() ? NULL : Patching_lock, Mutex::_no_safepoint_check_flag);
+ #ifdef ASSERT
+- CodeBlob* cb = CodeCache::find_blob_unsafe(_ic_call);
+- assert(cb != NULL && cb->is_nmethod(), "must be nmethod");
++ CodeBlob* cb = CodeCache::find_blob_unsafe(_ic_call);
++ assert(cb != NULL && cb->is_nmethod(), "must be nmethod");
+ #endif
+- _ic_call->set_destination_mt_safe(entry_point);
+-}
++ _ic_call->set_destination_mt_safe(entry_point);
++ }
+
+ if (is_optimized() || is_icstub) {
+ // Optimized call sites don't have a cache value and ICStub call
+@@ -159,6 +159,50 @@
+ //-----------------------------------------------------------------------------
+ // High-level access to an inline cache. Guaranteed to be MT-safe.
+
++void CompiledIC::initialize_from_iter(RelocIterator* iter) {
++ assert(iter->addr() == _ic_call->instruction_address(), "must find ic_call");
++
++ if (iter->type() == relocInfo::virtual_call_type) {
++ virtual_call_Relocation* r = iter->virtual_call_reloc();
++ _is_optimized = false;
++ _value = nativeMovConstReg_at(r->cached_value());
++ } else {
++ assert(iter->type() == relocInfo::opt_virtual_call_type, "must be a virtual call");
++ _is_optimized = true;
++ _value = NULL;
++ }
++}
++
++CompiledIC::CompiledIC(nmethod* nm, NativeCall* call)
++ : _ic_call(call)
++{
++ address ic_call = _ic_call->instruction_address();
++
++ assert(ic_call != NULL, "ic_call address must be set");
++ assert(nm != NULL, "must pass nmethod");
++ assert(nm->contains(ic_call), "must be in nmethod");
++
++ // Search for the ic_call at the given address.
++ RelocIterator iter(nm, ic_call, ic_call+1);
++ bool ret = iter.next();
++ assert(ret == true, "relocInfo must exist at this address");
++ assert(iter.addr() == ic_call, "must find ic_call");
++
++ initialize_from_iter(&iter);
++}
++
++CompiledIC::CompiledIC(RelocIterator* iter)
++ : _ic_call(nativeCall_at(iter->addr()))
++{
++ address ic_call = _ic_call->instruction_address();
++
++ nmethod* nm = iter->code();
++ assert(ic_call != NULL, "ic_call address must be set");
++ assert(nm != NULL, "must pass nmethod");
++ assert(nm->contains(ic_call), "must be in nmethod");
++
++ initialize_from_iter(iter);
++}
+
+ bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) {
+ assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "");
+@@ -485,7 +529,7 @@
+ void CompiledStaticCall::set_to_clean() {
+ assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "mt unsafe call");
+ // Reset call site
+- MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
++ MutexLockerEx pl(SafepointSynchronize::is_at_safepoint() ? NULL : Patching_lock, Mutex::_no_safepoint_check_flag);
+ #ifdef ASSERT
+ CodeBlob* cb = CodeCache::find_blob_unsafe(this);
+ assert(cb != NULL && cb->is_nmethod(), "must be nmethod");
+@@ -551,6 +595,7 @@
+ } else {
+ // Callee is interpreted code. In any case entering the interpreter
+ // puts a converter-frame on the stack to save arguments.
++ assert(!m->is_method_handle_intrinsic(), "Compiled code should never call interpreter MH intrinsics");
+ info._to_interpreter = true;
+ info._entry = m()->get_c2i_entry();
+ }
+--- ./hotspot/src/share/vm/code/compiledIC.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/code/compiledIC.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -150,6 +150,9 @@
+ bool _is_optimized; // an optimized virtual call (i.e., no compiled IC)
+
+ CompiledIC(nmethod* nm, NativeCall* ic_call);
++ CompiledIC(RelocIterator* iter);
++
++ void initialize_from_iter(RelocIterator* iter);
+
+ static bool is_icholder_entry(address entry);
+
+@@ -183,6 +186,7 @@
+ friend CompiledIC* CompiledIC_before(nmethod* nm, address return_addr);
+ friend CompiledIC* CompiledIC_at(nmethod* nm, address call_site);
+ friend CompiledIC* CompiledIC_at(Relocation* call_site);
++ friend CompiledIC* CompiledIC_at(RelocIterator* reloc_iter);
+
+ // This is used to release CompiledICHolder*s from nmethods that
+ // are about to be freed. The callsite might contain other stale
+@@ -263,6 +267,13 @@
+ return c_ic;
+ }
+
++inline CompiledIC* CompiledIC_at(RelocIterator* reloc_iter) {
++ assert(reloc_iter->type() == relocInfo::virtual_call_type ||
++ reloc_iter->type() == relocInfo::opt_virtual_call_type, "wrong reloc. info");
++ CompiledIC* c_ic = new CompiledIC(reloc_iter);
++ c_ic->verify();
++ return c_ic;
++}
+
+ //-----------------------------------------------------------------------------
+ // The CompiledStaticCall represents a call to a static method in the compiled
+--- ./hotspot/src/share/vm/code/dependencies.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/code/dependencies.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -32,6 +32,7 @@
+ #include "oops/oop.inline.hpp"
+ #include "runtime/handles.hpp"
+ #include "runtime/handles.inline.hpp"
++#include "runtime/thread.inline.hpp"
+ #include "utilities/copy.hpp"
+
+
+@@ -406,56 +407,66 @@
+ // for the sake of the compiler log, print out current dependencies:
+ void Dependencies::log_all_dependencies() {
+ if (log() == NULL) return;
+- ciBaseObject* args[max_arg_count];
++ ResourceMark rm;
+ for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
+ DepType dept = (DepType)deptv;
+ GrowableArray<ciBaseObject*>* deps = _deps[dept];
+- if (deps->length() == 0) continue;
++ int deplen = deps->length();
++ if (deplen == 0) {
++ continue;
++ }
+ int stride = dep_args(dept);
++ GrowableArray<ciBaseObject*>* ciargs = new GrowableArray<ciBaseObject*>(stride);
+ for (int i = 0; i < deps->length(); i += stride) {
+ for (int j = 0; j < stride; j++) {
+ // flush out the identities before printing
+- args[j] = deps->at(i+j);
++ ciargs->push(deps->at(i+j));
+ }
+- write_dependency_to(log(), dept, stride, args);
++ write_dependency_to(log(), dept, ciargs);
++ ciargs->clear();
+ }
++ guarantee(deplen == deps->length(), "deps array cannot grow inside nested ResoureMark scope");
+ }
+ }
+
+ void Dependencies::write_dependency_to(CompileLog* log,
+ DepType dept,
+- int nargs, DepArgument args[],
++ GrowableArray<DepArgument>* args,
+ Klass* witness) {
+ if (log == NULL) {
+ return;
+ }
++ ResourceMark rm;
+ ciEnv* env = ciEnv::current();
+- ciBaseObject* ciargs[max_arg_count];
+- assert(nargs <= max_arg_count, "oob");
+- for (int j = 0; j < nargs; j++) {
+- if (args[j].is_oop()) {
+- ciargs[j] = env->get_object(args[j].oop_value());
++ GrowableArray<ciBaseObject*>* ciargs = new GrowableArray<ciBaseObject*>(args->length());
++ for (GrowableArrayIterator<DepArgument> it = args->begin(); it != args->end(); ++it) {
++ DepArgument arg = *it;
++ if (arg.is_oop()) {
++ ciargs->push(env->get_object(arg.oop_value()));
+ } else {
+- ciargs[j] = env->get_metadata(args[j].metadata_value());
++ ciargs->push(env->get_metadata(arg.metadata_value()));
+ }
+ }
+- Dependencies::write_dependency_to(log, dept, nargs, ciargs, witness);
++ int argslen = ciargs->length();
++ Dependencies::write_dependency_to(log, dept, ciargs, witness);
++ guarantee(argslen == ciargs->length(), "ciargs array cannot grow inside nested ResoureMark scope");
+ }
+
+ void Dependencies::write_dependency_to(CompileLog* log,
+ DepType dept,
+- int nargs, ciBaseObject* args[],
++ GrowableArray<ciBaseObject*>* args,
+ Klass* witness) {
+- if (log == NULL) return;
+- assert(nargs <= max_arg_count, "oob");
+- int argids[max_arg_count];
+- int ctxkj = dep_context_arg(dept); // -1 if no context arg
+- int j;
+- for (j = 0; j < nargs; j++) {
+- if (args[j]->is_object()) {
+- argids[j] = log->identify(args[j]->as_object());
++ if (log == NULL) {
++ return;
++ }
++ ResourceMark rm;
++ GrowableArray<int>* argids = new GrowableArray<int>(args->length());
++ for (GrowableArrayIterator<ciBaseObject*> it = args->begin(); it != args->end(); ++it) {
++ ciBaseObject* obj = *it;
++ if (obj->is_object()) {
++ argids->push(log->identify(obj->as_object()));
+ } else {
+- argids[j] = log->identify(args[j]->as_metadata());
++ argids->push(log->identify(obj->as_metadata()));
+ }
+ }
+ if (witness != NULL) {
+@@ -464,16 +475,17 @@
+ log->begin_elem("dependency");
+ }
+ log->print(" type='%s'", dep_name(dept));
+- if (ctxkj >= 0) {
+- log->print(" ctxk='%d'", argids[ctxkj]);
++ const int ctxkj = dep_context_arg(dept); // -1 if no context arg
++ if (ctxkj >= 0 && ctxkj < argids->length()) {
++ log->print(" ctxk='%d'", argids->at(ctxkj));
+ }
+ // write remaining arguments, if any.
+- for (j = 0; j < nargs; j++) {
++ for (int j = 0; j < argids->length(); j++) {
+ if (j == ctxkj) continue; // already logged
+ if (j == 1) {
+- log->print( " x='%d'", argids[j]);
++ log->print( " x='%d'", argids->at(j));
+ } else {
+- log->print(" x%d='%d'", j, argids[j]);
++ log->print(" x%d='%d'", j, argids->at(j));
+ }
+ }
+ if (witness != NULL) {
+@@ -485,9 +497,12 @@
+
+ void Dependencies::write_dependency_to(xmlStream* xtty,
+ DepType dept,
+- int nargs, DepArgument args[],
++ GrowableArray<DepArgument>* args,
+ Klass* witness) {
+- if (xtty == NULL) return;
++ if (xtty == NULL) {
++ return;
++ }
++ ResourceMark rm;
+ ttyLocker ttyl;
+ int ctxkj = dep_context_arg(dept); // -1 if no context arg
+ if (witness != NULL) {
+@@ -497,23 +512,24 @@
+ }
+ xtty->print(" type='%s'", dep_name(dept));
+ if (ctxkj >= 0) {
+- xtty->object("ctxk", args[ctxkj].metadata_value());
++ xtty->object("ctxk", args->at(ctxkj).metadata_value());
+ }
+ // write remaining arguments, if any.
+- for (int j = 0; j < nargs; j++) {
++ for (int j = 0; j < args->length(); j++) {
+ if (j == ctxkj) continue; // already logged
++ DepArgument arg = args->at(j);
+ if (j == 1) {
+- if (args[j].is_oop()) {
+- xtty->object("x", args[j].oop_value());
++ if (arg.is_oop()) {
++ xtty->object("x", arg.oop_value());
+ } else {
+- xtty->object("x", args[j].metadata_value());
++ xtty->object("x", arg.metadata_value());
+ }
+ } else {
+ char xn[10]; sprintf(xn, "x%d", j);
+- if (args[j].is_oop()) {
+- xtty->object(xn, args[j].oop_value());
++ if (arg.is_oop()) {
++ xtty->object(xn, arg.oop_value());
+ } else {
+- xtty->object(xn, args[j].metadata_value());
++ xtty->object(xn, arg.metadata_value());
+ }
+ }
+ }
+@@ -524,7 +540,7 @@
+ xtty->end_elem();
+ }
+
+-void Dependencies::print_dependency(DepType dept, int nargs, DepArgument args[],
++void Dependencies::print_dependency(DepType dept, GrowableArray<DepArgument>* args,
+ Klass* witness) {
+ ResourceMark rm;
+ ttyLocker ttyl; // keep the following output all in one block
+@@ -533,8 +549,8 @@
+ dep_name(dept));
+ // print arguments
+ int ctxkj = dep_context_arg(dept); // -1 if no context arg
+- for (int j = 0; j < nargs; j++) {
+- DepArgument arg = args[j];
++ for (int j = 0; j < args->length(); j++) {
++ DepArgument arg = args->at(j);
+ bool put_star = false;
+ if (arg.is_null()) continue;
+ const char* what;
+@@ -570,31 +586,33 @@
+ void Dependencies::DepStream::log_dependency(Klass* witness) {
+ if (_deps == NULL && xtty == NULL) return; // fast cutout for runtime
+ ResourceMark rm;
+- int nargs = argument_count();
+- DepArgument args[max_arg_count];
++ const int nargs = argument_count();
++ GrowableArray<DepArgument>* args = new GrowableArray<DepArgument>(nargs);
+ for (int j = 0; j < nargs; j++) {
+ if (type() == call_site_target_value) {
+- args[j] = argument_oop(j);
++ args->push(argument_oop(j));
+ } else {
+- args[j] = argument(j);
++ args->push(argument(j));
+ }
+ }
++ int argslen = args->length();
+ if (_deps != NULL && _deps->log() != NULL) {
+- Dependencies::write_dependency_to(_deps->log(),
+- type(), nargs, args, witness);
++ Dependencies::write_dependency_to(_deps->log(), type(), args, witness);
+ } else {
+- Dependencies::write_dependency_to(xtty,
+- type(), nargs, args, witness);
++ Dependencies::write_dependency_to(xtty, type(), args, witness);
+ }
++ guarantee(argslen == args->length(), "args array cannot grow inside nested ResoureMark scope");
+ }
+
+ void Dependencies::DepStream::print_dependency(Klass* witness, bool verbose) {
++ ResourceMark rm;
+ int nargs = argument_count();
+- DepArgument args[max_arg_count];
++ GrowableArray<DepArgument>* args = new GrowableArray<DepArgument>(nargs);
+ for (int j = 0; j < nargs; j++) {
+- args[j] = argument(j);
++ args->push(argument(j));
+ }
+- Dependencies::print_dependency(type(), nargs, args, witness);
++ int argslen = args->length();
++ Dependencies::print_dependency(type(), args, witness);
+ if (verbose) {
+ if (_code != NULL) {
+ tty->print(" code: ");
+@@ -602,6 +620,7 @@
+ tty->cr();
+ }
+ }
++ guarantee(argslen == args->length(), "args array cannot grow inside nested ResoureMark scope");
+ }
+
+
+@@ -860,6 +879,8 @@
+ bool is_witness(Klass* k) {
+ if (doing_subtype_search()) {
+ return Dependencies::is_concrete_klass(k);
++ } else if (!k->oop_is_instance()) {
++ return false; // no methods to find in an array type
+ } else {
+ // Search class hierarchy first.
+ Method* m = InstanceKlass::cast(k)->find_instance_method(_name, _signature);
+@@ -1075,7 +1096,7 @@
+ Klass* chain; // scratch variable
+ #define ADD_SUBCLASS_CHAIN(k) { \
+ assert(chaini < CHAINMAX, "oob"); \
+- chain = InstanceKlass::cast(k)->subklass(); \
++ chain = k->subklass(); \
+ if (chain != NULL) chains[chaini++] = chain; }
+
+ // Look for non-abstract subclasses.
+@@ -1086,35 +1107,37 @@
+ // (Their subclasses are additional indirect implementors.
+ // See InstanceKlass::add_implementor.)
+ // (Note: nof_implementors is always zero for non-interfaces.)
+- int nof_impls = InstanceKlass::cast(context_type)->nof_implementors();
+- if (nof_impls > 1) {
+- // Avoid this case: *I.m > { A.m, C }; B.m > C
+- // Here, I.m has 2 concrete implementations, but m appears unique
+- // as A.m, because the search misses B.m when checking C.
+- // The inherited method B.m was getting missed by the walker
+- // when interface 'I' was the starting point.
+- // %%% Until this is fixed more systematically, bail out.
+- // (Old CHA had the same limitation.)
+- return context_type;
+- }
+- if (nof_impls > 0) {
+- Klass* impl = InstanceKlass::cast(context_type)->implementor();
+- assert(impl != NULL, "just checking");
+- // If impl is the same as the context_type, then more than one
+- // implementor has seen. No exact info in this case.
+- if (impl == context_type) {
+- return context_type; // report an inexact witness to this sad affair
++ if (top_level_call) {
++ int nof_impls = InstanceKlass::cast(context_type)->nof_implementors();
++ if (nof_impls > 1) {
++ // Avoid this case: *I.m > { A.m, C }; B.m > C
++ // Here, I.m has 2 concrete implementations, but m appears unique
++ // as A.m, because the search misses B.m when checking C.
++ // The inherited method B.m was getting missed by the walker
++ // when interface 'I' was the starting point.
++ // %%% Until this is fixed more systematically, bail out.
++ // (Old CHA had the same limitation.)
++ return context_type;
+ }
+- if (do_counts)
+- { NOT_PRODUCT(deps_find_witness_steps++); }
+- if (is_participant(impl)) {
+- if (!participants_hide_witnesses) {
++ if (nof_impls > 0) {
++ Klass* impl = InstanceKlass::cast(context_type)->implementor();
++ assert(impl != NULL, "just checking");
++ // If impl is the same as the context_type, then more than one
++ // implementor has seen. No exact info in this case.
++ if (impl == context_type) {
++ return context_type; // report an inexact witness to this sad affair
++ }
++ if (do_counts)
++ { NOT_PRODUCT(deps_find_witness_steps++); }
++ if (is_participant(impl)) {
++ if (!participants_hide_witnesses) {
++ ADD_SUBCLASS_CHAIN(impl);
++ }
++ } else if (is_witness(impl) && !ignore_witness(impl)) {
++ return impl;
++ } else {
+ ADD_SUBCLASS_CHAIN(impl);
+ }
+- } else if (is_witness(impl) && !ignore_witness(impl)) {
+- return impl;
+- } else {
+- ADD_SUBCLASS_CHAIN(impl);
+ }
+ }
+
+--- ./hotspot/src/share/vm/code/dependencies.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/code/dependencies.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -366,20 +366,36 @@
+ void copy_to(nmethod* nm);
+
+ void log_all_dependencies();
+- void log_dependency(DepType dept, int nargs, ciBaseObject* args[]) {
+- write_dependency_to(log(), dept, nargs, args);
++
++ void log_dependency(DepType dept, GrowableArray<ciBaseObject*>* args) {
++ ResourceMark rm;
++ int argslen = args->length();
++ write_dependency_to(log(), dept, args);
++ guarantee(argslen == args->length(),
++ "args array cannot grow inside nested ResoureMark scope");
+ }
++
+ void log_dependency(DepType dept,
+ ciBaseObject* x0,
+ ciBaseObject* x1 = NULL,
+ ciBaseObject* x2 = NULL) {
+- if (log() == NULL) return;
+- ciBaseObject* args[max_arg_count];
+- args[0] = x0;
+- args[1] = x1;
+- args[2] = x2;
+- assert(2 < max_arg_count, "");
+- log_dependency(dept, dep_args(dept), args);
++ if (log() == NULL) {
++ return;
++ }
++ ResourceMark rm;
++ GrowableArray<ciBaseObject*>* ciargs =
++ new GrowableArray<ciBaseObject*>(dep_args(dept));
++ assert (x0 != NULL, "no log x0");
++ ciargs->push(x0);
++
++ if (x1 != NULL) {
++ ciargs->push(x1);
++ }
++ if (x2 != NULL) {
++ ciargs->push(x2);
++ }
++ assert(ciargs->length() == dep_args(dept), "");
++ log_dependency(dept, ciargs);
+ }
+
+ class DepArgument : public ResourceObj {
+@@ -402,20 +418,8 @@
+ Metadata* metadata_value() const { assert(!_is_oop && _valid, "must be"); return (Metadata*) _value; }
+ };
+
+- static void write_dependency_to(CompileLog* log,
+- DepType dept,
+- int nargs, ciBaseObject* args[],
+- Klass* witness = NULL);
+- static void write_dependency_to(CompileLog* log,
+- DepType dept,
+- int nargs, DepArgument args[],
+- Klass* witness = NULL);
+- static void write_dependency_to(xmlStream* xtty,
+- DepType dept,
+- int nargs, DepArgument args[],
+- Klass* witness = NULL);
+ static void print_dependency(DepType dept,
+- int nargs, DepArgument args[],
++ GrowableArray<DepArgument>* args,
+ Klass* witness = NULL);
+
+ private:
+@@ -424,6 +428,18 @@
+
+ static Klass* ctxk_encoded_as_null(DepType dept, Metadata* x);
+
++ static void write_dependency_to(CompileLog* log,
++ DepType dept,
++ GrowableArray<ciBaseObject*>* args,
++ Klass* witness = NULL);
++ static void write_dependency_to(CompileLog* log,
++ DepType dept,
++ GrowableArray<DepArgument>* args,
++ Klass* witness = NULL);
++ static void write_dependency_to(xmlStream* xtty,
++ DepType dept,
++ GrowableArray<DepArgument>* args,
++ Klass* witness = NULL);
+ public:
+ // Use this to iterate over an nmethod's dependency set.
+ // Works on new and old dependency sets.
+--- ./hotspot/src/share/vm/code/nmethod.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/code/nmethod.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -37,6 +37,7 @@
+ #include "oops/methodData.hpp"
+ #include "prims/jvmtiRedefineClassesTrace.hpp"
+ #include "prims/jvmtiImpl.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/sharedRuntime.hpp"
+ #include "runtime/sweeper.hpp"
+ #include "utilities/dtrace.hpp"
+@@ -48,6 +49,8 @@
+
+ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+
++unsigned char nmethod::_global_unloading_clock = 0;
++
+ #ifdef DTRACE_ENABLED
+
+ // Only bother with this argument setup if dtrace is available
+@@ -383,27 +386,30 @@
+ set_exception_cache(new_entry);
+ }
+
+-void nmethod::remove_from_exception_cache(ExceptionCache* ec) {
++void nmethod::clean_exception_cache(BoolObjectClosure* is_alive) {
+ ExceptionCache* prev = NULL;
+ ExceptionCache* curr = exception_cache();
+- assert(curr != NULL, "nothing to remove");
+- // find the previous and next entry of ec
+- while (curr != ec) {
+- prev = curr;
+- curr = curr->next();
+- assert(curr != NULL, "ExceptionCache not found");
++
++ while (curr != NULL) {
++ ExceptionCache* next = curr->next();
++
++ Klass* ex_klass = curr->exception_type();
++ if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) {
++ if (prev == NULL) {
++ set_exception_cache(next);
++ } else {
++ prev->set_next(next);
++ }
++ delete curr;
++ // prev stays the same.
++ } else {
++ prev = curr;
++ }
++
++ curr = next;
+ }
+- // now: curr == ec
+- ExceptionCache* next = curr->next();
+- if (prev == NULL) {
+- set_exception_cache(next);
+- } else {
+- prev->set_next(next);
+- }
+- delete curr;
+ }
+
+-
+ // public method for accessing the exception cache
+ // These are the public access methods.
+ address nmethod::handler_for_exception_and_pc(Handle exception, address pc) {
+@@ -462,6 +468,7 @@
+ // Fill in default values for various flag fields
+ void nmethod::init_defaults() {
+ _state = in_use;
++ _unloading_clock = 0;
+ _marked_for_reclamation = 0;
+ _has_flushed_dependencies = 0;
+ _has_unsafe_access = 0;
+@@ -480,7 +487,11 @@
+ _oops_do_mark_link = NULL;
+ _jmethod_id = NULL;
+ _osr_link = NULL;
+- _scavenge_root_link = NULL;
++ if (UseG1GC) {
++ _unloading_next = NULL;
++ } else {
++ _scavenge_root_link = NULL;
++ }
+ _scavenge_root_state = 0;
+ _compiler = NULL;
+ #if INCLUDE_RTM_OPT
+@@ -688,8 +699,10 @@
+ _hotness_counter = NMethodSweeper::hotness_counter_reset_val();
+
+ code_buffer->copy_values_to(this);
+- if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
+- CodeCache::add_scavenge_root_nmethod(this);
++ if (ScavengeRootsInCode) {
++ if (detect_scavenge_root_oops()) {
++ CodeCache::add_scavenge_root_nmethod(this);
++ }
+ Universe::heap()->register_nmethod(this);
+ }
+ debug_only(verify_scavenge_root_oops());
+@@ -773,8 +786,10 @@
+ _hotness_counter = NMethodSweeper::hotness_counter_reset_val();
+
+ code_buffer->copy_values_to(this);
+- if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
+- CodeCache::add_scavenge_root_nmethod(this);
++ if (ScavengeRootsInCode) {
++ if (detect_scavenge_root_oops()) {
++ CodeCache::add_scavenge_root_nmethod(this);
++ }
+ Universe::heap()->register_nmethod(this);
+ }
+ DEBUG_ONLY(verify_scavenge_root_oops();)
+@@ -889,8 +904,10 @@
+ code_buffer->copy_values_to(this);
+ debug_info->copy_to(this);
+ dependencies->copy_to(this);
+- if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
+- CodeCache::add_scavenge_root_nmethod(this);
++ if (ScavengeRootsInCode) {
++ if (detect_scavenge_root_oops()) {
++ CodeCache::add_scavenge_root_nmethod(this);
++ }
+ Universe::heap()->register_nmethod(this);
+ }
+ debug_only(verify_scavenge_root_oops());
+@@ -1156,7 +1173,7 @@
+ switch(iter.type()) {
+ case relocInfo::virtual_call_type:
+ case relocInfo::opt_virtual_call_type: {
+- CompiledIC *ic = CompiledIC_at(iter.reloc());
++ CompiledIC *ic = CompiledIC_at(&iter);
+ // Ok, to lookup references to zombies here
+ CodeBlob *cb = CodeCache::find_blob_unsafe(ic->ic_destination());
+ if( cb != NULL && cb->is_nmethod() ) {
+@@ -1180,6 +1197,77 @@
+ }
+ }
+
++void nmethod::verify_clean_inline_caches() {
++ assert_locked_or_safepoint(CompiledIC_lock);
++
++ // If the method is not entrant or zombie then a JMP is plastered over the
++ // first few bytes. If an oop in the old code was there, that oop
++ // should not get GC'd. Skip the first few bytes of oops on
++ // not-entrant methods.
++ address low_boundary = verified_entry_point();
++ if (!is_in_use()) {
++ low_boundary += NativeJump::instruction_size;
++ // %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump.
++ // This means that the low_boundary is going to be a little too high.
++ // This shouldn't matter, since oops of non-entrant methods are never used.
++ // In fact, why are we bothering to look at oops in a non-entrant method??
++ }
++
++ ResourceMark rm;
++ RelocIterator iter(this, low_boundary);
++ while(iter.next()) {
++ switch(iter.type()) {
++ case relocInfo::virtual_call_type:
++ case relocInfo::opt_virtual_call_type: {
++ CompiledIC *ic = CompiledIC_at(&iter);
++ // Ok, to lookup references to zombies here
++ CodeBlob *cb = CodeCache::find_blob_unsafe(ic->ic_destination());
++ if( cb != NULL && cb->is_nmethod() ) {
++ nmethod* nm = (nmethod*)cb;
++ // Verify that inline caches pointing to both zombie and not_entrant methods are clean
++ if (!nm->is_in_use() || (nm->method()->code() != nm)) {
++ assert(ic->is_clean(), "IC should be clean");
++ }
++ }
++ break;
++ }
++ case relocInfo::static_call_type: {
++ CompiledStaticCall *csc = compiledStaticCall_at(iter.reloc());
++ CodeBlob *cb = CodeCache::find_blob_unsafe(csc->destination());
++ if( cb != NULL && cb->is_nmethod() ) {
++ nmethod* nm = (nmethod*)cb;
++ // Verify that inline caches pointing to both zombie and not_entrant methods are clean
++ if (!nm->is_in_use() || (nm->method()->code() != nm)) {
++ assert(csc->is_clean(), "IC should be clean");
++ }
++ }
++ break;
++ }
++ }
++ }
++}
++
++int nmethod::verify_icholder_relocations() {
++ int count = 0;
++
++ RelocIterator iter(this);
++ while(iter.next()) {
++ if (iter.type() == relocInfo::virtual_call_type) {
++ if (CompiledIC::is_icholder_call_site(iter.virtual_call_reloc())) {
++ CompiledIC *ic = CompiledIC_at(&iter);
++ if (TraceCompiledIC) {
++ tty->print("noticed icholder " INTPTR_FORMAT " ", p2i(ic->cached_icholder()));
++ ic->print();
++ }
++ assert(ic->cached_icholder() != NULL, "must be non-NULL");
++ count++;
++ }
++ }
++ }
++
++ return count;
++}
++
+ // This is a private interface with the sweeper.
+ void nmethod::mark_as_seen_on_stack() {
+ assert(is_alive(), "Must be an alive method");
+@@ -1212,6 +1300,23 @@
+ mdo->inc_decompile_count();
+ }
+
++void nmethod::increase_unloading_clock() {
++ _global_unloading_clock++;
++ if (_global_unloading_clock == 0) {
++ // _nmethods are allocated with _unloading_clock == 0,
++ // so 0 is never used as a clock value.
++ _global_unloading_clock = 1;
++ }
++}
++
++void nmethod::set_unloading_clock(unsigned char unloading_clock) {
++ OrderAccess::release_store((volatile jubyte*)&_unloading_clock, unloading_clock);
++}
++
++unsigned char nmethod::unloading_clock() {
++ return (unsigned char)OrderAccess::load_acquire((volatile jubyte*)&_unloading_clock);
++}
++
+ void nmethod::make_unloaded(BoolObjectClosure* is_alive, oop cause) {
+
+ post_compiled_method_unload();
+@@ -1257,6 +1362,10 @@
+ // for later on.
+ CodeCache::set_needs_cache_clean(true);
+ }
++
++ // Unregister must be done before the state change
++ Universe::heap()->unregister_nmethod(this);
++
+ _state = unloaded;
+
+ // Log the unloading.
+@@ -1611,6 +1720,45 @@
+ set_unload_reported();
+ }
+
++void static clean_ic_if_metadata_is_dead(CompiledIC *ic, BoolObjectClosure *is_alive, bool mark_on_stack) {
++ if (ic->is_icholder_call()) {
++ // The only exception is compiledICHolder oops which may
++ // yet be marked below. (We check this further below).
++ CompiledICHolder* cichk_oop = ic->cached_icholder();
++
++ if (mark_on_stack) {
++ Metadata::mark_on_stack(cichk_oop->holder_method());
++ Metadata::mark_on_stack(cichk_oop->holder_klass());
++ }
++
++ if (cichk_oop->holder_method()->method_holder()->is_loader_alive(is_alive) &&
++ cichk_oop->holder_klass()->is_loader_alive(is_alive)) {
++ return;
++ }
++ } else {
++ Metadata* ic_oop = ic->cached_metadata();
++ if (ic_oop != NULL) {
++ if (mark_on_stack) {
++ Metadata::mark_on_stack(ic_oop);
++ }
++
++ if (ic_oop->is_klass()) {
++ if (((Klass*)ic_oop)->is_loader_alive(is_alive)) {
++ return;
++ }
++ } else if (ic_oop->is_method()) {
++ if (((Method*)ic_oop)->method_holder()->is_loader_alive(is_alive)) {
++ return;
++ }
++ } else {
++ ShouldNotReachHere();
++ }
++ }
++ }
++
++ ic->set_to_clean();
++}
++
+ // This is called at the end of the strong tracing/marking phase of a
+ // GC to unload an nmethod if it contains otherwise unreachable
+ // oops.
+@@ -1643,15 +1791,7 @@
+ }
+
+ // Exception cache
+- ExceptionCache* ec = exception_cache();
+- while (ec != NULL) {
+- Klass* ex_klass = ec->exception_type();
+- ExceptionCache* next_ec = ec->next();
+- if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) {
+- remove_from_exception_cache(ec);
+- }
+- ec = next_ec;
+- }
++ clean_exception_cache(is_alive);
+
+ // If class unloading occurred we first iterate over all inline caches and
+ // clear ICs where the cached oop is referring to an unloaded klass or method.
+@@ -1661,32 +1801,8 @@
+ RelocIterator iter(this, low_boundary);
+ while(iter.next()) {
+ if (iter.type() == relocInfo::virtual_call_type) {
+- CompiledIC *ic = CompiledIC_at(iter.reloc());
+- if (ic->is_icholder_call()) {
+- // The only exception is compiledICHolder oops which may
+- // yet be marked below. (We check this further below).
+- CompiledICHolder* cichk_oop = ic->cached_icholder();
+- if (cichk_oop->holder_method()->method_holder()->is_loader_alive(is_alive) &&
+- cichk_oop->holder_klass()->is_loader_alive(is_alive)) {
+- continue;
+- }
+- } else {
+- Metadata* ic_oop = ic->cached_metadata();
+- if (ic_oop != NULL) {
+- if (ic_oop->is_klass()) {
+- if (((Klass*)ic_oop)->is_loader_alive(is_alive)) {
+- continue;
+- }
+- } else if (ic_oop->is_method()) {
+- if (((Method*)ic_oop)->method_holder()->is_loader_alive(is_alive)) {
+- continue;
+- }
+- } else {
+- ShouldNotReachHere();
+- }
+- }
+- }
+- ic->set_to_clean();
++ CompiledIC *ic = CompiledIC_at(&iter);
++ clean_ic_if_metadata_is_dead(ic, is_alive, false);
+ }
+ }
+ }
+@@ -1724,6 +1840,224 @@
+ verify_metadata_loaders(low_boundary, is_alive);
+ }
+
++template <class CompiledICorStaticCall>
++static bool clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address addr, BoolObjectClosure *is_alive, nmethod* from) {
++ // Ok, to lookup references to zombies here
++ CodeBlob *cb = CodeCache::find_blob_unsafe(addr);
++ if (cb != NULL && cb->is_nmethod()) {
++ nmethod* nm = (nmethod*)cb;
++
++ if (nm->unloading_clock() != nmethod::global_unloading_clock()) {
++ // The nmethod has not been processed yet.
++ return true;
++ }
++
++ // Clean inline caches pointing to both zombie and not_entrant methods
++ if (!nm->is_in_use() || (nm->method()->code() != nm)) {
++ ic->set_to_clean();
++ assert(ic->is_clean(), err_msg("nmethod " PTR_FORMAT "not clean %s", from, from->method()->name_and_sig_as_C_string()));
++ }
++ }
++
++ return false;
++}
++
++static bool clean_if_nmethod_is_unloaded(CompiledIC *ic, BoolObjectClosure *is_alive, nmethod* from) {
++ return clean_if_nmethod_is_unloaded(ic, ic->ic_destination(), is_alive, from);
++}
++
++static bool clean_if_nmethod_is_unloaded(CompiledStaticCall *csc, BoolObjectClosure *is_alive, nmethod* from) {
++ return clean_if_nmethod_is_unloaded(csc, csc->destination(), is_alive, from);
++}
++
++bool nmethod::unload_if_dead_at(RelocIterator* iter_at_oop, BoolObjectClosure *is_alive, bool unloading_occurred) {
++ assert(iter_at_oop->type() == relocInfo::oop_type, "Wrong relocation type");
++
++ oop_Relocation* r = iter_at_oop->oop_reloc();
++ // Traverse those oops directly embedded in the code.
++ // Other oops (oop_index>0) are seen as part of scopes_oops.
++ assert(1 == (r->oop_is_immediate()) +
++ (r->oop_addr() >= oops_begin() && r->oop_addr() < oops_end()),
++ "oop must be found in exactly one place");
++ if (r->oop_is_immediate() && r->oop_value() != NULL) {
++ // Unload this nmethod if the oop is dead.
++ if (can_unload(is_alive, r->oop_addr(), unloading_occurred)) {
++ return true;;
++ }
++ }
++
++ return false;
++}
++
++void nmethod::mark_metadata_on_stack_at(RelocIterator* iter_at_metadata) {
++ assert(iter_at_metadata->type() == relocInfo::metadata_type, "Wrong relocation type");
++
++ metadata_Relocation* r = iter_at_metadata->metadata_reloc();
++ // In this metadata, we must only follow those metadatas directly embedded in
++ // the code. Other metadatas (oop_index>0) are seen as part of
++ // the metadata section below.
++ assert(1 == (r->metadata_is_immediate()) +
++ (r->metadata_addr() >= metadata_begin() && r->metadata_addr() < metadata_end()),
++ "metadata must be found in exactly one place");
++ if (r->metadata_is_immediate() && r->metadata_value() != NULL) {
++ Metadata* md = r->metadata_value();
++ if (md != _method) Metadata::mark_on_stack(md);
++ }
++}
++
++void nmethod::mark_metadata_on_stack_non_relocs() {
++ // Visit the metadata section
++ for (Metadata** p = metadata_begin(); p < metadata_end(); p++) {
++ if (*p == Universe::non_oop_word() || *p == NULL) continue; // skip non-oops
++ Metadata* md = *p;
++ Metadata::mark_on_stack(md);
++ }
++
++ // Visit metadata not embedded in the other places.
++ if (_method != NULL) Metadata::mark_on_stack(_method);
++}
++
++bool nmethod::do_unloading_parallel(BoolObjectClosure* is_alive, bool unloading_occurred) {
++ ResourceMark rm;
++
++ // Make sure the oop's ready to receive visitors
++ assert(!is_zombie() && !is_unloaded(),
++ "should not call follow on zombie or unloaded nmethod");
++
++ // If the method is not entrant then a JMP is plastered over the
++ // first few bytes. If an oop in the old code was there, that oop
++ // should not get GC'd. Skip the first few bytes of oops on
++ // not-entrant methods.
++ address low_boundary = verified_entry_point();
++ if (is_not_entrant()) {
++ low_boundary += NativeJump::instruction_size;
++ // %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump.
++ // (See comment above.)
++ }
++
++ // The RedefineClasses() API can cause the class unloading invariant
++ // to no longer be true. See jvmtiExport.hpp for details.
++ // Also, leave a debugging breadcrumb in local flag.
++ bool a_class_was_redefined = JvmtiExport::has_redefined_a_class();
++ if (a_class_was_redefined) {
++ // This set of the unloading_occurred flag is done before the
++ // call to post_compiled_method_unload() so that the unloading
++ // of this nmethod is reported.
++ unloading_occurred = true;
++ }
++
++ // When class redefinition is used all metadata in the CodeCache has to be recorded,
++ // so that unused "previous versions" can be purged. Since walking the CodeCache can
++ // be expensive, the "mark on stack" is piggy-backed on this parallel unloading code.
++ bool mark_metadata_on_stack = a_class_was_redefined;
++
++ // Exception cache
++ clean_exception_cache(is_alive);
++
++ bool is_unloaded = false;
++ bool postponed = false;
++
++ RelocIterator iter(this, low_boundary);
++ while(iter.next()) {
++
++ switch (iter.type()) {
++
++ case relocInfo::virtual_call_type:
++ if (unloading_occurred) {
++ // If class unloading occurred we first iterate over all inline caches and
++ // clear ICs where the cached oop is referring to an unloaded klass or method.
++ clean_ic_if_metadata_is_dead(CompiledIC_at(&iter), is_alive, mark_metadata_on_stack);
++ }
++
++ postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this);
++ break;
++
++ case relocInfo::opt_virtual_call_type:
++ postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this);
++ break;
++
++ case relocInfo::static_call_type:
++ postponed |= clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), is_alive, this);
++ break;
++
++ case relocInfo::oop_type:
++ if (!is_unloaded) {
++ is_unloaded = unload_if_dead_at(&iter, is_alive, unloading_occurred);
++ }
++ break;
++
++ case relocInfo::metadata_type:
++ if (mark_metadata_on_stack) {
++ mark_metadata_on_stack_at(&iter);
++ }
++ }
++ }
++
++ if (mark_metadata_on_stack) {
++ mark_metadata_on_stack_non_relocs();
++ }
++
++ if (is_unloaded) {
++ return postponed;
++ }
++
++ // Scopes
++ for (oop* p = oops_begin(); p < oops_end(); p++) {
++ if (*p == Universe::non_oop_word()) continue; // skip non-oops
++ if (can_unload(is_alive, p, unloading_occurred)) {
++ is_unloaded = true;
++ break;
++ }
++ }
++
++ if (is_unloaded) {
++ return postponed;
++ }
++
++ // Ensure that all metadata is still alive
++ verify_metadata_loaders(low_boundary, is_alive);
++
++ return postponed;
++}
++
++void nmethod::do_unloading_parallel_postponed(BoolObjectClosure* is_alive, bool unloading_occurred) {
++ ResourceMark rm;
++
++ // Make sure the oop's ready to receive visitors
++ assert(!is_zombie(),
++ "should not call follow on zombie nmethod");
++
++ // If the method is not entrant then a JMP is plastered over the
++ // first few bytes. If an oop in the old code was there, that oop
++ // should not get GC'd. Skip the first few bytes of oops on
++ // not-entrant methods.
++ address low_boundary = verified_entry_point();
++ if (is_not_entrant()) {
++ low_boundary += NativeJump::instruction_size;
++ // %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump.
++ // (See comment above.)
++ }
++
++ RelocIterator iter(this, low_boundary);
++ while(iter.next()) {
++
++ switch (iter.type()) {
++
++ case relocInfo::virtual_call_type:
++ clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this);
++ break;
++
++ case relocInfo::opt_virtual_call_type:
++ clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this);
++ break;
++
++ case relocInfo::static_call_type:
++ clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), is_alive, this);
++ break;
++ }
++ }
++}
++
+ #ifdef ASSERT
+
+ class CheckClass : AllStatic {
+@@ -1770,7 +2104,7 @@
+ // compiled code is maintaining a link to dead metadata.
+ address static_call_addr = NULL;
+ if (iter.type() == relocInfo::opt_virtual_call_type) {
+- CompiledIC* cic = CompiledIC_at(iter.reloc());
++ CompiledIC* cic = CompiledIC_at(&iter);
+ if (!cic->is_call_to_interpreted()) {
+ static_call_addr = iter.addr();
+ }
+@@ -1810,7 +2144,7 @@
+ while (iter.next()) {
+ if (iter.type() == relocInfo::metadata_type ) {
+ metadata_Relocation* r = iter.metadata_reloc();
+- // In this lmetadata, we must only follow those metadatas directly embedded in
++ // In this metadata, we must only follow those metadatas directly embedded in
+ // the code. Other metadatas (oop_index>0) are seen as part of
+ // the metadata section below.
+ assert(1 == (r->metadata_is_immediate()) +
+@@ -1822,7 +2156,7 @@
+ }
+ } else if (iter.type() == relocInfo::virtual_call_type) {
+ // Check compiledIC holders associated with this nmethod
+- CompiledIC *ic = CompiledIC_at(iter.reloc());
++ CompiledIC *ic = CompiledIC_at(&iter);
+ if (ic->is_icholder_call()) {
+ CompiledICHolder* cichk = ic->cached_icholder();
+ f(cichk->holder_method());
+@@ -1844,7 +2178,7 @@
+ f(md);
+ }
+
+- // Call function Method*, not embedded in these other places.
++ // Visit metadata not embedded in the other places.
+ if (_method != NULL) f(_method);
+ }
+
+@@ -1940,7 +2274,7 @@
+ assert(cur != NULL, "not NULL-terminated");
+ nmethod* next = cur->_oops_do_mark_link;
+ cur->_oops_do_mark_link = NULL;
+- cur->fix_oop_relocations();
++ cur->verify_oop_relocations();
+ NOT_PRODUCT(if (TraceScavenge) cur->print_on(tty, "oops_do, unmark"));
+ cur = next;
+ }
+@@ -2482,6 +2816,10 @@
+ };
+
+ void nmethod::verify_scavenge_root_oops() {
++ if (UseG1GC) {
++ return;
++ }
++
+ if (!on_scavenge_root_list()) {
+ // Actually look inside, to verify the claim that it's clean.
+ DebugScavengeRoot debug_scavenge_root(this);
+@@ -2925,7 +3263,7 @@
+ case relocInfo::virtual_call_type:
+ case relocInfo::opt_virtual_call_type: {
+ VerifyMutexLocker mc(CompiledIC_lock);
+- CompiledIC_at(iter.reloc())->print();
++ CompiledIC_at(&iter)->print();
+ break;
+ }
+ case relocInfo::static_call_type:
+--- ./hotspot/src/share/vm/code/nmethod.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/code/nmethod.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -69,7 +69,12 @@
+ friend class VMStructs;
+ private:
+ enum { cache_size = 4 };
+- PcDesc* _pc_descs[cache_size]; // last cache_size pc_descs found
++ // The array elements MUST be volatile! Several threads may modify
++ // and read from the cache concurrently. find_pc_desc_internal has
++ // returned wrong results. C++ compiler (namely xlC12) may duplicate
++ // C++ field accesses if the elements are not volatile.
++ typedef PcDesc* PcDescPtr;
++ volatile PcDescPtr _pc_descs[cache_size]; // last cache_size pc_descs found
+ public:
+ PcDescCache() { debug_only(_pc_descs[0] = NULL); }
+ void reset_to(PcDesc* initial_pc_desc);
+@@ -111,6 +116,11 @@
+ friend class NMethodSweeper;
+ friend class CodeCache; // scavengable oops
+ private:
++
++ // GC support to help figure out if an nmethod has been
++ // cleaned/unloaded by the current GC.
++ static unsigned char _global_unloading_clock;
++
+ // Shared fields for all nmethod's
+ Method* _method;
+ int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method
+@@ -118,7 +128,13 @@
+
+ // To support simple linked-list chaining of nmethods:
+ nmethod* _osr_link; // from InstanceKlass::osr_nmethods_head
+- nmethod* _scavenge_root_link; // from CodeCache::scavenge_root_nmethods
++
++ union {
++ // Used by G1 to chain nmethods.
++ nmethod* _unloading_next;
++ // Used by non-G1 GCs to chain nmethods.
++ nmethod* _scavenge_root_link; // from CodeCache::scavenge_root_nmethods
++ };
+
+ static nmethod* volatile _oops_do_mark_nmethods;
+ nmethod* volatile _oops_do_mark_link;
+@@ -180,6 +196,8 @@
+ // Protected by Patching_lock
+ volatile unsigned char _state; // {alive, not_entrant, zombie, unloaded}
+
++ volatile unsigned char _unloading_clock; // Incremented after GC unloaded/cleaned the nmethod
++
+ #ifdef ASSERT
+ bool _oops_are_stale; // indicates that it's no longer safe to access oops section
+ #endif
+@@ -430,13 +448,25 @@
+ // alive. It is used when an uncommon trap happens. Returns true
+ // if this thread changed the state of the nmethod or false if
+ // another thread performed the transition.
+- bool make_not_entrant() { return make_not_entrant_or_zombie(not_entrant); }
++ bool make_not_entrant() {
++ assert(!method()->is_method_handle_intrinsic(), "Cannot make MH intrinsic not entrant");
++ return make_not_entrant_or_zombie(not_entrant);
++ }
+ bool make_zombie() { return make_not_entrant_or_zombie(zombie); }
+
+ // used by jvmti to track if the unload event has been reported
+ bool unload_reported() { return _unload_reported; }
+ void set_unload_reported() { _unload_reported = true; }
+
++ void set_unloading_next(nmethod* next) { _unloading_next = next; }
++ nmethod* unloading_next() { return _unloading_next; }
++
++ static unsigned char global_unloading_clock() { return _global_unloading_clock; }
++ static void increase_unloading_clock();
++
++ void set_unloading_clock(unsigned char unloading_clock);
++ unsigned char unloading_clock();
++
+ bool is_marked_for_deoptimization() const { return _marked_for_deoptimization; }
+ void mark_for_deoptimization() { _marked_for_deoptimization = true; }
+
+@@ -529,7 +559,7 @@
+ void set_exception_cache(ExceptionCache *ec) { _exception_cache = ec; }
+ address handler_for_exception_and_pc(Handle exception, address pc);
+ void add_handler_for_exception_and_pc(Handle exception, address pc, address handler);
+- void remove_from_exception_cache(ExceptionCache* ec);
++ void clean_exception_cache(BoolObjectClosure* is_alive);
+
+ // implicit exceptions support
+ address continuation_for_implicit_exception(address pc);
+@@ -552,6 +582,10 @@
+ return (addr >= code_begin() && addr < verified_entry_point());
+ }
+
++ // Verify calls to dead methods have been cleaned.
++ void verify_clean_inline_caches();
++ // Verify and count cached icholder relocations.
++ int verify_icholder_relocations();
+ // Check that all metadata is still alive
+ void verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive);
+
+@@ -577,8 +611,19 @@
+
+ // GC support
+ void do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred);
++ // The parallel versions are used by G1.
++ bool do_unloading_parallel(BoolObjectClosure* is_alive, bool unloading_occurred);
++ void do_unloading_parallel_postponed(BoolObjectClosure* is_alive, bool unloading_occurred);
++
++ private:
++ // Unload a nmethod if the *root object is dead.
+ bool can_unload(BoolObjectClosure* is_alive, oop* root, bool unloading_occurred);
++ bool unload_if_dead_at(RelocIterator *iter_at_oop, BoolObjectClosure* is_alive, bool unloading_occurred);
+
++ void mark_metadata_on_stack_at(RelocIterator* iter_at_metadata);
++ void mark_metadata_on_stack_non_relocs();
++
++ public:
+ void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map,
+ OopClosure* f);
+ void oops_do(OopClosure* f) { oops_do(f, false); }
+--- ./hotspot/src/share/vm/code/relocInfo.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/code/relocInfo.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -877,11 +877,7 @@
+ void internal_word_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
+ address target = _target;
+ if (target == NULL) {
+- if (addr_in_const()) {
+- target = new_addr_for(*(address*)addr(), src, dest);
+- } else {
+- target = new_addr_for(pd_get_address_from_code(), src, dest);
+- }
++ target = new_addr_for(this->target(), src, dest);
+ }
+ set_value(target);
+ }
+@@ -890,7 +886,11 @@
+ address internal_word_Relocation::target() {
+ address target = _target;
+ if (target == NULL) {
+- target = pd_get_address_from_code();
++ if (addr_in_const()) {
++ target = *(address*)addr();
++ } else {
++ target = pd_get_address_from_code();
++ }
+ }
+ return target;
+ }
+--- ./hotspot/src/share/vm/compiler/compileBroker.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/compiler/compileBroker.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -183,9 +183,8 @@
+
+ long CompileBroker::_peak_compilation_time = 0;
+
+-CompileQueue* CompileBroker::_c2_method_queue = NULL;
+-CompileQueue* CompileBroker::_c1_method_queue = NULL;
+-CompileTask* CompileBroker::_task_free_list = NULL;
++CompileQueue* CompileBroker::_c2_compile_queue = NULL;
++CompileQueue* CompileBroker::_c1_compile_queue = NULL;
+
+ GrowableArray<CompilerThread*>* CompileBroker::_compiler_threads = NULL;
+
+@@ -253,13 +252,56 @@
+
+ // By convention, the compiling thread is responsible for
+ // recycling a non-blocking CompileTask.
+- CompileBroker::free_task(task);
++ CompileTask::free(task);
+ }
+ }
+
+
+-// ------------------------------------------------------------------
+-// CompileTask::initialize
++CompileTask* CompileTask::_task_free_list = NULL;
++#ifdef ASSERT
++int CompileTask::_num_allocated_tasks = 0;
++#endif
++/**
++ * Allocate a CompileTask, from the free list if possible.
++ */
++CompileTask* CompileTask::allocate() {
++ MutexLocker locker(CompileTaskAlloc_lock);
++ CompileTask* task = NULL;
++
++ if (_task_free_list != NULL) {
++ task = _task_free_list;
++ _task_free_list = task->next();
++ task->set_next(NULL);
++ } else {
++ task = new CompileTask();
++ DEBUG_ONLY(_num_allocated_tasks++;)
++ assert (_num_allocated_tasks < 10000, "Leaking compilation tasks?");
++ task->set_next(NULL);
++ task->set_is_free(true);
++ }
++ assert(task->is_free(), "Task must be free.");
++ task->set_is_free(false);
++ return task;
++}
++
++
++/**
++ * Add a task to the free list.
++ */
++void CompileTask::free(CompileTask* task) {
++ MutexLocker locker(CompileTaskAlloc_lock);
++ if (!task->is_free()) {
++ task->set_code(NULL);
++ assert(!task->lock()->is_locked(), "Should not be locked when freed");
++ JNIHandles::destroy_global(task->_method_holder);
++ JNIHandles::destroy_global(task->_hot_method_holder);
++
++ task->set_is_free(true);
++ task->set_next(_task_free_list);
++ _task_free_list = task;
++ }
++}
++
+ void CompileTask::initialize(int compile_id,
+ methodHandle method,
+ int osr_bci,
+@@ -287,6 +329,7 @@
+ _hot_count = hot_count;
+ _time_queued = 0; // tidy
+ _comment = comment;
++ _failure_reason = NULL;
+
+ if (LogCompilation) {
+ _time_queued = os::elapsed_counter();
+@@ -317,15 +360,6 @@
+ if (nm == NULL) _code_handle = NULL; // drop the handle also
+ }
+
+-// ------------------------------------------------------------------
+-// CompileTask::free
+-void CompileTask::free() {
+- set_code(NULL);
+- assert(!_lock->is_locked(), "Should not be locked when freed");
+- JNIHandles::destroy_global(_method_holder);
+- JNIHandles::destroy_global(_hot_method_holder);
+-}
+-
+
+ void CompileTask::mark_on_stack() {
+ // Mark these methods as something redefine classes cannot remove.
+@@ -565,6 +599,11 @@
+ methodHandle method(thread, this->method());
+ ResourceMark rm(thread);
+
++ if (!_is_success) {
++ const char* reason = _failure_reason != NULL ? _failure_reason : "unknown";
++ log->elem("failure reason='%s'", reason);
++ }
++
+ // <task_done ... stamp='1.234'> </task>
+ nmethod* nm = code();
+ log->begin_elem("task_done success='%d' nmsize='%d' count='%d'",
+@@ -588,9 +627,12 @@
+
+
+
+-// Add a CompileTask to a CompileQueue
++/**
++ * Add a CompileTask to a CompileQueue
++ */
+ void CompileQueue::add(CompileTask* task) {
+ assert(lock()->owned_by_self(), "must own lock");
++ assert(!CompileBroker::is_compilation_disabled_forever(), "Do not add task if compilation is turned off forever");
+
+ task->set_next(NULL);
+ task->set_prev(NULL);
+@@ -612,9 +654,7 @@
+ // Mark the method as being in the compile queue.
+ task->method()->set_queued_for_compilation();
+
+- if (CIPrintCompileQueue) {
+- print();
+- }
++ NOT_PRODUCT(print();)
+
+ if (LogCompilation && xtty != NULL) {
+ task->log_task_queued();
+@@ -624,14 +664,32 @@
+ lock()->notify_all();
+ }
+
+-void CompileQueue::delete_all() {
+- assert(lock()->owned_by_self(), "must own lock");
+- if (_first != NULL) {
+- for (CompileTask* task = _first; task != NULL; task = task->next()) {
+- delete task;
++/**
++ * Empties compilation queue by putting all compilation tasks onto
++ * a freelist. Furthermore, the method wakes up all threads that are
++ * waiting on a compilation task to finish. This can happen if background
++ * compilation is disabled.
++ */
++void CompileQueue::free_all() {
++ MutexLocker mu(lock());
++ CompileTask* next = _first;
++
++ // Iterate over all tasks in the compile queue
++ while (next != NULL) {
++ CompileTask* current = next;
++ next = current->next();
++ {
++ // Wake up thread that blocks on the compile task.
++ MutexLocker ct_lock(current->lock());
++ current->lock()->notify();
+ }
+- _first = NULL;
++ // Put the task back on the freelist.
++ CompileTask::free(current);
+ }
++ _first = NULL;
++
++ // Wake up all threads that block on the queue.
++ lock()->notify_all();
+ }
+
+ // ------------------------------------------------------------------
+@@ -688,13 +746,40 @@
+ return NULL;
+ }
+
+- CompileTask* task = CompilationPolicy::policy()->select_task(this);
++ CompileTask* task;
++ {
++ No_Safepoint_Verifier nsv;
++ task = CompilationPolicy::policy()->select_task(this);
++ }
+ remove(task);
++ purge_stale_tasks(); // may temporarily release MCQ lock
+ return task;
+ }
+
+-void CompileQueue::remove(CompileTask* task)
+-{
++// Clean & deallocate stale compile tasks.
++// Temporarily releases MethodCompileQueue lock.
++void CompileQueue::purge_stale_tasks() {
++ assert(lock()->owned_by_self(), "must own lock");
++ if (_first_stale != NULL) {
++ // Stale tasks are purged when MCQ lock is released,
++ // but _first_stale updates are protected by MCQ lock.
++ // Once task processing starts and MCQ lock is released,
++ // other compiler threads can reuse _first_stale.
++ CompileTask* head = _first_stale;
++ _first_stale = NULL;
++ {
++ MutexUnlocker ul(lock());
++ for (CompileTask* task = head; task != NULL; ) {
++ CompileTask* next_task = task->next();
++ CompileTaskWrapper ctw(task); // Frees the task
++ task->set_failure_reason("stale task");
++ task = next_task;
++ }
++ }
++ }
++}
++
++void CompileQueue::remove(CompileTask* task) {
+ assert(lock()->owned_by_self(), "must own lock");
+ if (task->prev() != NULL) {
+ task->prev()->set_next(task->next());
+@@ -714,6 +799,16 @@
+ --_size;
+ }
+
++void CompileQueue::remove_and_mark_stale(CompileTask* task) {
++ assert(lock()->owned_by_self(), "must own lock");
++ remove(task);
++
++ // Enqueue the task for reclamation (should be done outside MCQ lock)
++ task->set_next(_first_stale);
++ task->set_prev(NULL);
++ _first_stale = task;
++}
++
+ // methods in the compile queue need to be marked as used on the stack
+ // so that they don't get reclaimed by Redefine Classes
+ void CompileQueue::mark_on_stack() {
+@@ -724,18 +819,24 @@
+ }
+ }
+
+-// ------------------------------------------------------------------
+-// CompileQueue::print
++#ifndef PRODUCT
++/**
++ * Print entire compilation queue.
++ */
+ void CompileQueue::print() {
+- tty->print_cr("Contents of %s", name());
+- tty->print_cr("----------------------");
+- CompileTask* task = _first;
+- while (task != NULL) {
+- task->print_line();
+- task = task->next();
++ if (CIPrintCompileQueue) {
++ ttyLocker ttyl;
++ tty->print_cr("Contents of %s", name());
++ tty->print_cr("----------------------");
++ CompileTask* task = _first;
++ while (task != NULL) {
++ task->print_line();
++ task = task->next();
++ }
++ tty->print_cr("----------------------");
+ }
+- tty->print_cr("----------------------");
+ }
++#endif // PRODUCT
+
+ CompilerCounters::CompilerCounters(const char* thread_name, int instance, TRAPS) {
+
+@@ -808,9 +909,6 @@
+ _compilers[1] = new SharkCompiler();
+ #endif // SHARK
+
+- // Initialize the CompileTask free list
+- _task_free_list = NULL;
+-
+ // Start the CompilerThreads
+ init_compiler_threads(c1_count, c2_count);
+ // totalTime performance counter is always created as it is required
+@@ -1003,11 +1101,11 @@
+ #endif // !ZERO && !SHARK
+ // Initialize the compilation queue
+ if (c2_compiler_count > 0) {
+- _c2_method_queue = new CompileQueue("C2MethodQueue", MethodCompileQueue_lock);
++ _c2_compile_queue = new CompileQueue("C2 CompileQueue", MethodCompileQueue_lock);
+ _compilers[1]->set_num_compiler_threads(c2_compiler_count);
+ }
+ if (c1_compiler_count > 0) {
+- _c1_method_queue = new CompileQueue("C1MethodQueue", MethodCompileQueue_lock);
++ _c1_compile_queue = new CompileQueue("C1 CompileQueue", MethodCompileQueue_lock);
+ _compilers[0]->set_num_compiler_threads(c1_compiler_count);
+ }
+
+@@ -1022,7 +1120,7 @@
+ sprintf(name_buffer, "C2 CompilerThread%d", i);
+ CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK);
+ // Shark and C2
+- CompilerThread* new_thread = make_compiler_thread(name_buffer, _c2_method_queue, counters, _compilers[1], CHECK);
++ CompilerThread* new_thread = make_compiler_thread(name_buffer, _c2_compile_queue, counters, _compilers[1], CHECK);
+ _compiler_threads->append(new_thread);
+ }
+
+@@ -1031,7 +1129,7 @@
+ sprintf(name_buffer, "C1 CompilerThread%d", i);
+ CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK);
+ // C1
+- CompilerThread* new_thread = make_compiler_thread(name_buffer, _c1_method_queue, counters, _compilers[0], CHECK);
++ CompilerThread* new_thread = make_compiler_thread(name_buffer, _c1_compile_queue, counters, _compilers[0], CHECK);
+ _compiler_threads->append(new_thread);
+ }
+
+@@ -1041,14 +1139,19 @@
+ }
+
+
+-// Set the methods on the stack as on_stack so that redefine classes doesn't
+-// reclaim them
++/**
++ * Set the methods on the stack as on_stack so that redefine classes doesn't
++ * reclaim them. This method is executed at a safepoint.
++ */
+ void CompileBroker::mark_on_stack() {
+- if (_c2_method_queue != NULL) {
+- _c2_method_queue->mark_on_stack();
++ assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
++ // Since we are at a safepoint, we do not need a lock to access
++ // the compile queues.
++ if (_c2_compile_queue != NULL) {
++ _c2_compile_queue->mark_on_stack();
+ }
+- if (_c1_method_queue != NULL) {
+- _c1_method_queue->mark_on_stack();
++ if (_c1_compile_queue != NULL) {
++ _c1_compile_queue->mark_on_stack();
+ }
+ }
+
+@@ -1064,7 +1167,7 @@
+ const char* comment,
+ Thread* thread) {
+ // do nothing if compiler thread(s) is not available
+- if (!_initialized ) {
++ if (!_initialized) {
+ return;
+ }
+
+@@ -1111,7 +1214,7 @@
+
+ // If this method is already in the compile queue, then
+ // we do not block the current thread.
+- if (compilation_is_in_queue(method, osr_bci)) {
++ if (compilation_is_in_queue(method)) {
+ // We may want to decay our counter a bit here to prevent
+ // multiple denied requests for compilation. This is an
+ // open compilation policy issue. Note: The other possibility,
+@@ -1132,6 +1235,12 @@
+ return;
+ }
+
++ if (TieredCompilation) {
++ // Tiered policy requires MethodCounters to exist before adding a method to
++ // the queue. Create if we don't have them yet.
++ method->get_method_counters(thread);
++ }
++
+ // Outputs from the following MutexLocker block:
+ CompileTask* task = NULL;
+ bool blocking = false;
+@@ -1144,7 +1253,7 @@
+ // Make sure the method has not slipped into the queues since
+ // last we checked; note that those checks were "fast bail-outs".
+ // Here we need to be more careful, see 14012000 below.
+- if (compilation_is_in_queue(method, osr_bci)) {
++ if (compilation_is_in_queue(method)) {
+ return;
+ }
+
+@@ -1165,7 +1274,7 @@
+ }
+
+ // Should this thread wait for completion of the compile?
+- blocking = is_compile_blocking(method, osr_bci);
++ blocking = is_compile_blocking();
+
+ // We will enter the compilation in the queue.
+ // 14012000: Note that this sets the queued_for_compile bits in
+@@ -1357,19 +1466,17 @@
+ }
+
+
+-// ------------------------------------------------------------------
+-// CompileBroker::compilation_is_in_queue
+-//
+-// See if this compilation is already requested.
+-//
+-// Implementation note: there is only a single "is in queue" bit
+-// for each method. This means that the check below is overly
+-// conservative in the sense that an osr compilation in the queue
+-// will block a normal compilation from entering the queue (and vice
+-// versa). This can be remedied by a full queue search to disambiguate
+-// cases. If it is deemed profitible, this may be done.
+-bool CompileBroker::compilation_is_in_queue(methodHandle method,
+- int osr_bci) {
++/**
++ * See if this compilation is already requested.
++ *
++ * Implementation note: there is only a single "is in queue" bit
++ * for each method. This means that the check below is overly
++ * conservative in the sense that an osr compilation in the queue
++ * will block a normal compilation from entering the queue (and vice
++ * versa). This can be remedied by a full queue search to disambiguate
++ * cases. If it is deemed profitable, this may be done.
++ */
++bool CompileBroker::compilation_is_in_queue(methodHandle method) {
+ return method->queued_for_compilation();
+ }
+
+@@ -1449,13 +1556,11 @@
+ #endif
+ }
+
+-
+-// ------------------------------------------------------------------
+-// CompileBroker::is_compile_blocking
+-//
+-// Should the current thread be blocked until this compilation request
+-// has been fulfilled?
+-bool CompileBroker::is_compile_blocking(methodHandle method, int osr_bci) {
++/**
++ * Should the current thread block until this compilation request
++ * has been fulfilled?
++ */
++bool CompileBroker::is_compile_blocking() {
+ assert(!InstanceRefKlass::owns_pending_list_lock(JavaThread::current()), "possible deadlock");
+ return !BackgroundCompilation;
+ }
+@@ -1483,7 +1588,7 @@
+ int hot_count,
+ const char* comment,
+ bool blocking) {
+- CompileTask* new_task = allocate_task();
++ CompileTask* new_task = CompileTask::allocate();
+ new_task->initialize(compile_id, method, osr_bci, comp_level,
+ hot_method, hot_count, comment,
+ blocking);
+@@ -1492,75 +1597,52 @@
+ }
+
+
+-// ------------------------------------------------------------------
+-// CompileBroker::allocate_task
+-//
+-// Allocate a CompileTask, from the free list if possible.
+-CompileTask* CompileBroker::allocate_task() {
+- MutexLocker locker(CompileTaskAlloc_lock);
+- CompileTask* task = NULL;
+- if (_task_free_list != NULL) {
+- task = _task_free_list;
+- _task_free_list = task->next();
+- task->set_next(NULL);
+- } else {
+- task = new CompileTask();
+- task->set_next(NULL);
+- }
+- return task;
+-}
+-
+-
+-// ------------------------------------------------------------------
+-// CompileBroker::free_task
+-//
+-// Add a task to the free list.
+-void CompileBroker::free_task(CompileTask* task) {
+- MutexLocker locker(CompileTaskAlloc_lock);
+- task->free();
+- task->set_next(_task_free_list);
+- _task_free_list = task;
+-}
+-
+-
+-// ------------------------------------------------------------------
+-// CompileBroker::wait_for_completion
+-//
+-// Wait for the given method CompileTask to complete.
++/**
++ * Wait for the compilation task to complete.
++ */
+ void CompileBroker::wait_for_completion(CompileTask* task) {
+ if (CIPrintCompileQueue) {
++ ttyLocker ttyl;
+ tty->print_cr("BLOCKING FOR COMPILE");
+ }
+
+ assert(task->is_blocking(), "can only wait on blocking task");
+
+- JavaThread *thread = JavaThread::current();
++ JavaThread* thread = JavaThread::current();
+ thread->set_blocked_on_compilation(true);
+
+ methodHandle method(thread, task->method());
+ {
+ MutexLocker waiter(task->lock(), thread);
+
+- while (!task->is_complete())
++ while (!task->is_complete() && !is_compilation_disabled_forever()) {
+ task->lock()->wait();
++ }
+ }
++
++ thread->set_blocked_on_compilation(false);
++ if (is_compilation_disabled_forever()) {
++ CompileTask::free(task);
++ return;
++ }
++
+ // It is harmless to check this status without the lock, because
+ // completion is a stable property (until the task object is recycled).
+ assert(task->is_complete(), "Compilation should have completed");
+ assert(task->code_handle() == NULL, "must be reset");
+
+- thread->set_blocked_on_compilation(false);
+-
+ // By convention, the waiter is responsible for recycling a
+ // blocking CompileTask. Since there is only one waiter ever
+ // waiting on a CompileTask, we know that no one else will
+ // be using this CompileTask; we can free it.
+- free_task(task);
++ CompileTask::free(task);
+ }
+
+-// Initialize compiler thread(s) + compiler object(s). The postcondition
+-// of this function is that the compiler runtimes are initialized and that
+-//compiler threads can start compiling.
++/**
++ * Initialize compiler thread(s) + compiler object(s). The postcondition
++ * of this function is that the compiler runtimes are initialized and that
++ * compiler threads can start compiling.
++ */
+ bool CompileBroker::init_compiler_runtime() {
+ CompilerThread* thread = CompilerThread::current();
+ AbstractCompiler* comp = thread->compiler();
+@@ -1597,7 +1679,6 @@
+ disable_compilation_forever();
+ // If compiler initialization failed, no compiler thread that is specific to a
+ // particular compiler runtime will ever start to compile methods.
+-
+ shutdown_compiler_runtime(comp, thread);
+ return false;
+ }
+@@ -1611,9 +1692,11 @@
+ return true;
+ }
+
+-// If C1 and/or C2 initialization failed, we shut down all compilation.
+-// We do this to keep things simple. This can be changed if it ever turns out to be
+-// a problem.
++/**
++ * If C1 and/or C2 initialization failed, we shut down all compilation.
++ * We do this to keep things simple. This can be changed if it ever turns
++ * out to be a problem.
++ */
+ void CompileBroker::shutdown_compiler_runtime(AbstractCompiler* comp, CompilerThread* thread) {
+ // Free buffer blob, if allocated
+ if (thread->get_buffer_blob() != NULL) {
+@@ -1625,28 +1708,25 @@
+ // There are two reasons for shutting down the compiler
+ // 1) compiler runtime initialization failed
+ // 2) The code cache is full and the following flag is set: -XX:-UseCodeCacheFlushing
+- warning("Shutting down compiler %s (no space to run compilers)", comp->name());
++ warning("%s initialization failed. Shutting down all compilers", comp->name());
+
+ // Only one thread per compiler runtime object enters here
+ // Set state to shut down
+ comp->set_shut_down();
+
+- MutexLocker mu(MethodCompileQueue_lock, thread);
+- CompileQueue* queue;
+- if (_c1_method_queue != NULL) {
+- _c1_method_queue->delete_all();
+- queue = _c1_method_queue;
+- _c1_method_queue = NULL;
+- delete _c1_method_queue;
++ // Delete all queued compilation tasks to make compiler threads exit faster.
++ if (_c1_compile_queue != NULL) {
++ _c1_compile_queue->free_all();
+ }
+
+- if (_c2_method_queue != NULL) {
+- _c2_method_queue->delete_all();
+- queue = _c2_method_queue;
+- _c2_method_queue = NULL;
+- delete _c2_method_queue;
++ if (_c2_compile_queue != NULL) {
++ _c2_compile_queue->free_all();
+ }
+
++ // Set flags so that we continue execution with using interpreter only.
++ UseCompiler = false;
++ UseInterpreter = true;
++
+ // We could delete compiler runtimes also. However, there are references to
+ // the compiler runtime(s) (e.g., nmethod::is_compiled_by_c1()) which then
+ // fail. This can be done later if necessary.
+@@ -1732,26 +1812,11 @@
+ if (method()->number_of_breakpoints() == 0) {
+ // Compile the method.
+ if ((UseCompiler || AlwaysCompileLoopMethods) && CompileBroker::should_compile_new_jobs()) {
+-#ifdef COMPILER1
+- // Allow repeating compilations for the purpose of benchmarking
+- // compile speed. This is not useful for customers.
+- if (CompilationRepeat != 0) {
+- int compile_count = CompilationRepeat;
+- while (compile_count > 0) {
+- invoke_compiler_on_method(task);
+- nmethod* nm = method->code();
+- if (nm != NULL) {
+- nm->make_zombie();
+- method->clear_code();
+- }
+- compile_count--;
+- }
+- }
+-#endif /* COMPILER1 */
+ invoke_compiler_on_method(task);
+ } else {
+ // After compilation is disabled, remove remaining methods from queue
+ method->clear_queued_for_compilation();
++ task->set_failure_reason("compilation is disabled");
+ }
+ }
+ }
+@@ -1780,7 +1845,7 @@
+ os::file_separator(), thread_id, os::current_process_id());
+ }
+
+- fp = fopen(file_name, "at");
++ fp = fopen(file_name, "wt");
+ if (fp != NULL) {
+ if (LogCompilation && Verbose) {
+ tty->print_cr("Opening compilation log %s", file_name);
+@@ -1939,6 +2004,7 @@
+ compilable = ci_env.compilable();
+
+ if (ci_env.failing()) {
++ task->set_failure_reason(ci_env.failure_reason());
+ const char* retry_message = ci_env.retry_message();
+ if (_compilation_log != NULL) {
+ _compilation_log->log_failure(thread, task, ci_env.failure_reason(), retry_message);
+@@ -2011,7 +2077,7 @@
+
+ // Note that the queued_for_compilation bits are cleared without
+ // protection of a mutex. [They were set by the requester thread,
+- // when adding the task to the complie queue -- at which time the
++ // when adding the task to the compile queue -- at which time the
+ // compile queue lock was held. Subsequently, we acquired the compile
+ // queue lock to get this task off the compile queue; thus (to belabour
+ // the point somewhat) our clearing of the bits must be occurring
+--- ./hotspot/src/share/vm/compiler/compileBroker.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/compiler/compileBroker.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -40,6 +40,11 @@
+ friend class VMStructs;
+
+ private:
++ static CompileTask* _task_free_list;
++#ifdef ASSERT
++ static int _num_allocated_tasks;
++#endif
++
+ Monitor* _lock;
+ uint _compile_id;
+ Method* _method;
+@@ -52,13 +57,14 @@
+ int _num_inlined_bytecodes;
+ nmethodLocker* _code_handle; // holder of eventual result
+ CompileTask* _next, *_prev;
+-
++ bool _is_free;
+ // Fields used for logging why the compilation was initiated:
+ jlong _time_queued; // in units of os::elapsed_counter()
+ Method* _hot_method; // which method actually triggered this task
+ jobject _hot_method_holder;
+ int _hot_count; // information about its invocation counter
+ const char* _comment; // more info about the task
++ const char* _failure_reason;
+
+ public:
+ CompileTask() {
+@@ -69,7 +75,8 @@
+ methodHandle hot_method, int hot_count, const char* comment,
+ bool is_blocking);
+
+- void free();
++ static CompileTask* allocate();
++ static void free(CompileTask* task);
+
+ int compile_id() const { return _compile_id; }
+ Method* method() const { return _method; }
+@@ -98,6 +105,8 @@
+ void set_next(CompileTask* next) { _next = next; }
+ CompileTask* prev() const { return _prev; }
+ void set_prev(CompileTask* prev) { _prev = prev; }
++ bool is_free() const { return _is_free; }
++ void set_is_free(bool val) { _is_free = val; }
+
+ private:
+ static void print_compilation_impl(outputStream* st, Method* method, int compile_id, int comp_level,
+@@ -130,6 +139,10 @@
+ void log_task_queued();
+ void log_task_start(CompileLog* log);
+ void log_task_done(CompileLog* log);
++
++ void set_failure_reason(const char* reason) {
++ _failure_reason = reason;
++ }
+ };
+
+ // CompilerCounters
+@@ -188,7 +201,11 @@
+ CompileTask* _first;
+ CompileTask* _last;
+
++ CompileTask* _first_stale;
++
+ int _size;
++
++ void purge_stale_tasks();
+ public:
+ CompileQueue(const char* name, Monitor* lock) {
+ _name = name;
+@@ -196,6 +213,7 @@
+ _first = NULL;
+ _last = NULL;
+ _size = 0;
++ _first_stale = NULL;
+ }
+
+ const char* name() const { return _name; }
+@@ -203,6 +221,7 @@
+
+ void add(CompileTask* task);
+ void remove(CompileTask* task);
++ void remove_and_mark_stale(CompileTask* task);
+ CompileTask* first() { return _first; }
+ CompileTask* last() { return _last; }
+
+@@ -211,10 +230,11 @@
+ bool is_empty() const { return _first == NULL; }
+ int size() const { return _size; }
+
++
+ // Redefine Classes support
+ void mark_on_stack();
+- void delete_all();
+- void print();
++ void free_all();
++ NOT_PRODUCT (void print();)
+
+ ~CompileQueue() {
+ assert (is_empty(), " Compile Queue must be empty");
+@@ -267,9 +287,8 @@
+ static int _last_compile_level;
+ static char _last_method_compiled[name_buffer_length];
+
+- static CompileQueue* _c2_method_queue;
+- static CompileQueue* _c1_method_queue;
+- static CompileTask* _task_free_list;
++ static CompileQueue* _c2_compile_queue;
++ static CompileQueue* _c1_compile_queue;
+
+ static GrowableArray<CompilerThread*>* _compiler_threads;
+
+@@ -322,7 +341,7 @@
+ static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count);
+ static bool compilation_is_complete (methodHandle method, int osr_bci, int comp_level);
+ static bool compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level);
+- static bool is_compile_blocking (methodHandle method, int osr_bci);
++ static bool is_compile_blocking ();
+ static void preload_classes (methodHandle method, TRAPS);
+
+ static CompileTask* create_compile_task(CompileQueue* queue,
+@@ -334,8 +353,6 @@
+ int hot_count,
+ const char* comment,
+ bool blocking);
+- static CompileTask* allocate_task();
+- static void free_task(CompileTask* task);
+ static void wait_for_completion(CompileTask* task);
+
+ static void invoke_compiler_on_method(CompileTask* task);
+@@ -353,8 +370,8 @@
+ const char* comment,
+ Thread* thread);
+ static CompileQueue* compile_queue(int comp_level) {
+- if (is_c2_compile(comp_level)) return _c2_method_queue;
+- if (is_c1_compile(comp_level)) return _c1_method_queue;
++ if (is_c2_compile(comp_level)) return _c2_compile_queue;
++ if (is_c1_compile(comp_level)) return _c1_compile_queue;
+ return NULL;
+ }
+ static bool init_compiler_runtime();
+@@ -372,7 +389,7 @@
+ return NULL;
+ }
+
+- static bool compilation_is_in_queue(methodHandle method, int osr_bci);
++ static bool compilation_is_in_queue(methodHandle method);
+ static int queue_size(int comp_level) {
+ CompileQueue *q = compile_queue(comp_level);
+ return q != NULL ? q->size() : 0;
+--- ./hotspot/src/share/vm/compiler/compileLog.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/compiler/compileLog.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -55,8 +55,10 @@
+ }
+
+ CompileLog::~CompileLog() {
+- delete _out;
++ delete _out; // Close fd in fileStream::~fileStream()
+ _out = NULL;
++ // Remove partial file after merging in CompileLog::finish_log_on_error
++ unlink(_file);
+ FREE_C_HEAP_ARRAY(char, _identities, mtCompiler);
+ FREE_C_HEAP_ARRAY(char, _file, mtCompiler);
+ }
+@@ -268,10 +270,9 @@
+ }
+ file->print_raw_cr("</compilation_log>");
+ close(partial_fd);
+- unlink(partial_file);
+ }
+ CompileLog* next_log = log->_next;
+- delete log;
++ delete log; // Removes partial file
+ log = next_log;
+ }
+ _first = NULL;
+--- ./hotspot/src/share/vm/compiler/compilerOracle.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/compiler/compilerOracle.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -167,44 +167,134 @@
+ }
+ }
+
++enum OptionType {
++ IntxType,
++ UintxType,
++ BoolType,
++ CcstrType,
++ UnknownType
++};
+
+-class MethodOptionMatcher: public MethodMatcher {
+- const char * option;
+- public:
+- MethodOptionMatcher(Symbol* class_name, Mode class_mode,
+- Symbol* method_name, Mode method_mode,
+- Symbol* signature, const char * opt, MethodMatcher* next):
+- MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next) {
+- option = opt;
++/* Methods to map real type names to OptionType */
++template<typename T>
++static OptionType get_type_for() {
++ return UnknownType;
++};
++
++template<> OptionType get_type_for<intx>() {
++ return IntxType;
++}
++
++template<> OptionType get_type_for<uintx>() {
++ return UintxType;
++}
++
++template<> OptionType get_type_for<bool>() {
++ return BoolType;
++}
++
++template<> OptionType get_type_for<ccstr>() {
++ return CcstrType;
++}
++
++template<typename T>
++static const T copy_value(const T value) {
++ return value;
++}
++
++template<> const ccstr copy_value<ccstr>(const ccstr value) {
++ return (const ccstr)strdup(value);
++}
++
++template <typename T>
++class TypedMethodOptionMatcher : public MethodMatcher {
++ const char* _option;
++ OptionType _type;
++ const T _value;
++
++public:
++ TypedMethodOptionMatcher(Symbol* class_name, Mode class_mode,
++ Symbol* method_name, Mode method_mode,
++ Symbol* signature, const char* opt,
++ const T value, MethodMatcher* next) :
++ MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next),
++ _type(get_type_for<T>()), _value(copy_value<T>(value)) {
++ _option = strdup(opt);
+ }
+
+- bool match(methodHandle method, const char* opt) {
+- MethodOptionMatcher* current = this;
++ ~TypedMethodOptionMatcher() {
++ free((void*)_option);
++ }
++
++ TypedMethodOptionMatcher* match(methodHandle method, const char* opt) {
++ TypedMethodOptionMatcher* current = this;
+ while (current != NULL) {
+- current = (MethodOptionMatcher*)current->find(method);
++ current = (TypedMethodOptionMatcher*)current->find(method);
+ if (current == NULL) {
+- return false;
++ return NULL;
+ }
+- if (strcmp(current->option, opt) == 0) {
+- return true;
++ if (strcmp(current->_option, opt) == 0) {
++ return current;
+ }
+ current = current->next();
+ }
+- return false;
++ return NULL;
+ }
+
+- MethodOptionMatcher* next() {
+- return (MethodOptionMatcher*)_next;
++ TypedMethodOptionMatcher* next() {
++ return (TypedMethodOptionMatcher*)_next;
+ }
+
+- virtual void print() {
++ OptionType get_type(void) {
++ return _type;
++ };
++
++ T value() { return _value; }
++
++ void print() {
++ ttyLocker ttyl;
+ print_base();
+- tty->print(" %s", option);
++ tty->print(" %s", _option);
++ tty->print(" <unknown option type>");
+ tty->cr();
+ }
+ };
+
++template<>
++void TypedMethodOptionMatcher<intx>::print() {
++ ttyLocker ttyl;
++ print_base();
++ tty->print(" intx %s", _option);
++ tty->print(" = " INTX_FORMAT, _value);
++ tty->cr();
++};
+
++template<>
++void TypedMethodOptionMatcher<uintx>::print() {
++ ttyLocker ttyl;
++ print_base();
++ tty->print(" uintx %s", _option);
++ tty->print(" = " UINTX_FORMAT, _value);
++ tty->cr();
++};
++
++template<>
++void TypedMethodOptionMatcher<bool>::print() {
++ ttyLocker ttyl;
++ print_base();
++ tty->print(" bool %s", _option);
++ tty->print(" = %s", _value ? "true" : "false");
++ tty->cr();
++};
++
++template<>
++void TypedMethodOptionMatcher<ccstr>::print() {
++ ttyLocker ttyl;
++ print_base();
++ tty->print(" const char* %s", _option);
++ tty->print(" = '%s'", _value);
++ tty->cr();
++};
+
+ // this must parallel the command_names below
+ enum OracleCommand {
+@@ -259,23 +349,46 @@
+ return lists[command];
+ }
+
+-
+-
++template<typename T>
+ static MethodMatcher* add_option_string(Symbol* class_name, MethodMatcher::Mode c_mode,
+ Symbol* method_name, MethodMatcher::Mode m_mode,
+ Symbol* signature,
+- const char* option) {
+- lists[OptionCommand] = new MethodOptionMatcher(class_name, c_mode, method_name, m_mode,
+- signature, option, lists[OptionCommand]);
++ const char* option,
++ T value) {
++ lists[OptionCommand] = new TypedMethodOptionMatcher<T>(class_name, c_mode, method_name, m_mode,
++ signature, option, value, lists[OptionCommand]);
+ return lists[OptionCommand];
+ }
+
++template<typename T>
++static bool get_option_value(methodHandle method, const char* option, T& value) {
++ TypedMethodOptionMatcher<T>* m;
++ if (lists[OptionCommand] != NULL
++ && (m = ((TypedMethodOptionMatcher<T>*)lists[OptionCommand])->match(method, option)) != NULL
++ && m->get_type() == get_type_for<T>()) {
++ value = m->value();
++ return true;
++ } else {
++ return false;
++ }
++}
+
+ bool CompilerOracle::has_option_string(methodHandle method, const char* option) {
+- return lists[OptionCommand] != NULL &&
+- ((MethodOptionMatcher*)lists[OptionCommand])->match(method, option);
++ bool value = false;
++ get_option_value(method, option, value);
++ return value;
+ }
+
++template<typename T>
++bool CompilerOracle::has_option_value(methodHandle method, const char* option, T& value) {
++ return ::get_option_value(method, option, value);
++}
++
++// Explicit instantiation for all OptionTypes supported.
++template bool CompilerOracle::has_option_value<intx>(methodHandle method, const char* option, intx& value);
++template bool CompilerOracle::has_option_value<uintx>(methodHandle method, const char* option, uintx& value);
++template bool CompilerOracle::has_option_value<bool>(methodHandle method, const char* option, bool& value);
++template bool CompilerOracle::has_option_value<ccstr>(methodHandle method, const char* option, ccstr& value);
+
+ bool CompilerOracle::should_exclude(methodHandle method, bool& quietly) {
+ quietly = true;
+@@ -433,6 +546,94 @@
+
+
+
++// Scan next flag and value in line, return MethodMatcher object on success, NULL on failure.
++// On failure, error_msg contains description for the first error.
++// For future extensions: set error_msg on first error.
++static MethodMatcher* scan_flag_and_value(const char* type, const char* line, int& total_bytes_read,
++ Symbol* c_name, MethodMatcher::Mode c_match,
++ Symbol* m_name, MethodMatcher::Mode m_match,
++ Symbol* signature,
++ char* errorbuf, const int buf_size) {
++ total_bytes_read = 0;
++ int bytes_read = 0;
++ char flag[256];
++
++ // Read flag name.
++ if (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", flag, &bytes_read) == 1) {
++ line += bytes_read;
++ total_bytes_read += bytes_read;
++
++ // Read value.
++ if (strcmp(type, "intx") == 0) {
++ intx value;
++ if (sscanf(line, "%*[ \t]" INTX_FORMAT "%n", &value, &bytes_read) == 1) {
++ total_bytes_read += bytes_read;
++ return add_option_string(c_name, c_match, m_name, m_match, signature, flag, value);
++ } else {
++ jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s ", flag, type);
++ }
++ } else if (strcmp(type, "uintx") == 0) {
++ uintx value;
++ if (sscanf(line, "%*[ \t]" UINTX_FORMAT "%n", &value, &bytes_read) == 1) {
++ total_bytes_read += bytes_read;
++ return add_option_string(c_name, c_match, m_name, m_match, signature, flag, value);
++ } else {
++ jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type);
++ }
++ } else if (strcmp(type, "ccstr") == 0) {
++ ResourceMark rm;
++ char* value = NEW_RESOURCE_ARRAY(char, strlen(line) + 1);
++ if (sscanf(line, "%*[ \t]%255[_a-zA-Z0-9]%n", value, &bytes_read) == 1) {
++ total_bytes_read += bytes_read;
++ return add_option_string(c_name, c_match, m_name, m_match, signature, flag, (ccstr)value);
++ } else {
++ jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type);
++ }
++ } else if (strcmp(type, "ccstrlist") == 0) {
++ // Accumulates several strings into one. The internal type is ccstr.
++ ResourceMark rm;
++ char* value = NEW_RESOURCE_ARRAY(char, strlen(line) + 1);
++ char* next_value = value;
++ if (sscanf(line, "%*[ \t]%255[_a-zA-Z0-9]%n", next_value, &bytes_read) == 1) {
++ total_bytes_read += bytes_read;
++ line += bytes_read;
++ next_value += bytes_read;
++ char* end_value = next_value-1;
++ while (sscanf(line, "%*[ \t]%255[_a-zA-Z0-9]%n", next_value, &bytes_read) == 1) {
++ total_bytes_read += bytes_read;
++ line += bytes_read;
++ *end_value = ' '; // override '\0'
++ next_value += bytes_read;
++ end_value = next_value-1;
++ }
++ return add_option_string(c_name, c_match, m_name, m_match, signature, flag, (ccstr)value);
++ } else {
++ jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type);
++ }
++ } else if (strcmp(type, "bool") == 0) {
++ char value[256];
++ if (sscanf(line, "%*[ \t]%255[a-zA-Z]%n", value, &bytes_read) == 1) {
++ if (strcmp(value, "true") == 0) {
++ total_bytes_read += bytes_read;
++ return add_option_string(c_name, c_match, m_name, m_match, signature, flag, true);
++ } else if (strcmp(value, "false") == 0) {
++ total_bytes_read += bytes_read;
++ return add_option_string(c_name, c_match, m_name, m_match, signature, flag, false);
++ } else {
++ jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type);
++ }
++ } else {
++ jio_snprintf(errorbuf, sizeof(errorbuf), " Value cannot be read for flag %s of type %s", flag, type);
++ }
++ } else {
++ jio_snprintf(errorbuf, sizeof(errorbuf), " Type %s not supported ", type);
++ }
++ } else {
++ jio_snprintf(errorbuf, sizeof(errorbuf), " Flag name for type %s should be alphanumeric ", type);
++ }
++ return NULL;
++}
++
+ void CompilerOracle::parse_from_line(char* line) {
+ if (line[0] == '\0') return;
+ if (line[0] == '#') return;
+@@ -462,8 +663,10 @@
+ int bytes_read;
+ OracleCommand command = parse_command_name(line, &bytes_read);
+ line += bytes_read;
++ ResourceMark rm;
+
+ if (command == UnknownCommand) {
++ ttyLocker ttyl;
+ tty->print_cr("CompilerOracle: unrecognized line");
+ tty->print_cr(" \"%s\"", original_line);
+ return;
+@@ -485,7 +688,7 @@
+ char method_name[256];
+ char sig[1024];
+ char errorbuf[1024];
+- const char* error_msg = NULL;
++ const char* error_msg = NULL; // description of first error that appears
+ MethodMatcher* match = NULL;
+
+ if (scan_line(line, class_name, &c_match, method_name, &m_match, &bytes_read, error_msg)) {
+@@ -504,43 +707,77 @@
+ }
+
+ if (command == OptionCommand) {
+- // Look for trailing options to support
+- // ciMethod::has_option("string") to control features in the
+- // compiler. Multiple options may follow the method name.
+- char option[256];
++ // Look for trailing options.
++ //
++ // Two types of trailing options are
++ // supported:
++ //
++ // (1) CompileCommand=option,Klass::method,flag
++ // (2) CompileCommand=option,Klass::method,type,flag,value
++ //
++ // Type (1) is used to support ciMethod::has_option("someflag")
++ // (i.e., to check if a flag "someflag" is enabled for a method).
++ //
++ // Type (2) is used to support options with a value. Values can have the
++ // the following types: intx, uintx, bool, ccstr, and ccstrlist.
++ //
++ // For future extensions: extend scan_flag_and_value()
++ char option[256]; // stores flag for Type (1) and type of Type (2)
+ while (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) {
+ if (match != NULL && !_quiet) {
+ // Print out the last match added
++ ttyLocker ttyl;
+ tty->print("CompilerOracle: %s ", command_names[command]);
+ match->print();
+ }
+- match = add_option_string(c_name, c_match, m_name, m_match, signature, strdup(option));
+ line += bytes_read;
+- }
++
++ if (strcmp(option, "intx") == 0
++ || strcmp(option, "uintx") == 0
++ || strcmp(option, "bool") == 0
++ || strcmp(option, "ccstr") == 0
++ || strcmp(option, "ccstrlist") == 0
++ ) {
++
++ // Type (2) option: parse flag name and value.
++ match = scan_flag_and_value(option, line, bytes_read,
++ c_name, c_match, m_name, m_match, signature,
++ errorbuf, sizeof(errorbuf));
++ if (match == NULL) {
++ error_msg = errorbuf;
++ break;
++ }
++ line += bytes_read;
++ } else {
++ // Type (1) option
++ match = add_option_string(c_name, c_match, m_name, m_match, signature, option, true);
++ }
++ } // while(
+ } else {
+- bytes_read = 0;
+- sscanf(line, "%*[ \t]%n", &bytes_read);
+- if (line[bytes_read] != '\0') {
+- jio_snprintf(errorbuf, sizeof(errorbuf), " Unrecognized text after command: %s", line);
+- error_msg = errorbuf;
+- } else {
+- match = add_predicate(command, c_name, c_match, m_name, m_match, signature);
+- }
++ match = add_predicate(command, c_name, c_match, m_name, m_match, signature);
+ }
+ }
+
+- if (match != NULL) {
+- if (!_quiet) {
+- ResourceMark rm;
+- tty->print("CompilerOracle: %s ", command_names[command]);
+- match->print();
+- }
+- } else {
++ ttyLocker ttyl;
++ if (error_msg != NULL) {
++ // an error has happened
+ tty->print_cr("CompilerOracle: unrecognized line");
+ tty->print_cr(" \"%s\"", original_line);
+ if (error_msg != NULL) {
+ tty->print_cr("%s", error_msg);
+ }
++ } else {
++ // check for remaining characters
++ bytes_read = 0;
++ sscanf(line, "%*[ \t]%n", &bytes_read);
++ if (line[bytes_read] != '\0') {
++ tty->print_cr("CompilerOracle: unrecognized line");
++ tty->print_cr(" \"%s\"", original_line);
++ tty->print_cr(" Unrecognized text %s after command ", line);
++ } else if (match != NULL && !_quiet) {
++ tty->print("CompilerOracle: %s ", command_names[command]);
++ match->print();
++ }
+ }
+ }
+
+--- ./hotspot/src/share/vm/compiler/compilerOracle.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/compiler/compilerOracle.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -64,6 +64,11 @@
+ // Check to see if this method has option set for it
+ static bool has_option_string(methodHandle method, const char * option);
+
++ // Check if method has option and value set. If yes, overwrite value and return true,
++ // otherwise leave value unchanged and return false.
++ template<typename T>
++ static bool has_option_value(methodHandle method, const char* option, T& value);
++
+ // Reads from string instead of file
+ static void parse_from_string(const char* command_string, void (*parser)(char*));
+
+--- ./hotspot/src/share/vm/compiler/disassembler.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/compiler/disassembler.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -245,12 +245,12 @@
+ };
+
+ decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) {
+- memset(this, 0, sizeof(*this));
++ memset(this, 0, sizeof(*this)); // Beware, this zeroes bits of fields.
+ _output = output ? output : tty;
+ _code = code;
+ if (code != NULL && code->is_nmethod())
+ _nm = (nmethod*) code;
+- _strings.assign(c);
++ _strings.copy(c);
+
+ // by default, output pc but not bytes:
+ _print_pc = true;
+--- ./hotspot/src/share/vm/compiler/methodLiveness.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/compiler/methodLiveness.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -475,7 +475,7 @@
+ bci = 0;
+ }
+
+- MethodLivenessResult answer((uintptr_t*)NULL,0);
++ MethodLivenessResult answer((BitMap::bm_word_t*)NULL,0);
+
+ if (_block_count > 0) {
+ if (TimeLivenessAnalysis) _time_total.start();
+@@ -1000,7 +1000,7 @@
+ }
+
+ MethodLivenessResult MethodLiveness::BasicBlock::get_liveness_at(ciMethod* method, int bci) {
+- MethodLivenessResult answer(NEW_RESOURCE_ARRAY(uintptr_t, _analyzer->bit_map_size_words()),
++ MethodLivenessResult answer(NEW_RESOURCE_ARRAY(BitMap::bm_word_t, _analyzer->bit_map_size_words()),
+ _analyzer->bit_map_size_bits());
+ answer.set_is_valid();
+
+--- ./hotspot/src/share/vm/compiler/oopMap.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/compiler/oopMap.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -467,7 +467,6 @@
+ assert(cb != NULL, "no codeblob");
+
+ // Any reg might be saved by a safepoint handler (see generate_handler_blob).
+- const int max_saved_on_entry_reg_count = ConcreteRegisterImpl::number_of_registers;
+ assert( reg_map->_update_for_id == NULL || fr->is_older(reg_map->_update_for_id),
+ "already updated this map; do not 'update' it twice!" );
+ debug_only(reg_map->_update_for_id = fr->id());
+@@ -477,27 +476,20 @@
+ !cb->caller_must_gc_arguments(reg_map->thread())),
+ "include_argument_oops should already be set");
+
+- int nof_callee = 0;
+- oop* locs[2*max_saved_on_entry_reg_count+1];
+- VMReg regs[2*max_saved_on_entry_reg_count+1];
+- // ("+1" because max_saved_on_entry_reg_count might be zero)
+-
+ // Scan through oopmap and find location of all callee-saved registers
+ // (we do not do update in place, since info could be overwritten)
+
+ address pc = fr->pc();
++ OopMap* map = cb->oop_map_for_return_address(pc);
++ assert(map != NULL, "no ptr map found");
++ DEBUG_ONLY(int nof_callee = 0;)
+
+- OopMap* map = cb->oop_map_for_return_address(pc);
+-
+- assert(map != NULL, " no ptr map found");
+-
+- OopMapValue omv;
+- for(OopMapStream oms(map,OopMapValue::callee_saved_value); !oms.is_done(); oms.next()) {
+- omv = oms.current();
+- assert(nof_callee < 2*max_saved_on_entry_reg_count, "overflow");
+- regs[nof_callee] = omv.content_reg();
+- locs[nof_callee] = fr->oopmapreg_to_location(omv.reg(),reg_map);
+- nof_callee++;
++ for (OopMapStream oms(map, OopMapValue::callee_saved_value); !oms.is_done(); oms.next()) {
++ OopMapValue omv = oms.current();
++ VMReg reg = omv.content_reg();
++ oop* loc = fr->oopmapreg_to_location(omv.reg(), reg_map);
++ reg_map->set_location(reg, (address) loc);
++ DEBUG_ONLY(nof_callee++;)
+ }
+
+ // Check that runtime stubs save all callee-saved registers
+@@ -506,11 +498,6 @@
+ (nof_callee >= SAVED_ON_ENTRY_REG_COUNT || nof_callee >= C_SAVED_ON_ENTRY_REG_COUNT),
+ "must save all");
+ #endif // COMPILER2
+-
+- // Copy found callee-saved register to reg_map
+- for(int i = 0; i < nof_callee; i++) {
+- reg_map->set_location(regs[i], (address)locs[i]);
+- }
+ }
+
+ //=============================================================================
+--- ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -158,7 +158,7 @@
+ " coal_deaths(" SIZE_FORMAT ")"
+ " + count(" SSIZE_FORMAT ")",
+ p2i(this), size(), _allocation_stats.prev_sweep(), _allocation_stats.split_births(),
+- _allocation_stats.split_births(), _allocation_stats.split_deaths(),
++ _allocation_stats.coal_births(), _allocation_stats.split_deaths(),
+ _allocation_stats.coal_deaths(), count()));
+ }
+ #endif
+--- ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -53,7 +53,8 @@
+ }
+
+ void ConcurrentMarkSweepPolicy::initialize_generations() {
+- _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC, 0, AllocFailStrategy::RETURN_NULL);
++ _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC,
++ CURRENT_PC, AllocFailStrategy::RETURN_NULL);
+ if (_generations == NULL)
+ vm_exit_during_initialization("Unable to allocate gen spec");
+
+--- ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,6 +26,7 @@
+ #define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CMSOOPCLOSURES_HPP
+
+ #include "memory/genOopClosures.hpp"
++#include "memory/iterator.hpp"
+
+ /////////////////////////////////////////////////////////////////
+ // Closures used by ConcurrentMarkSweepGeneration's collector
+@@ -48,33 +49,13 @@
+ } \
+ }
+
+-// Applies the given oop closure to all oops in all klasses visited.
+-class CMKlassClosure : public KlassClosure {
+- friend class CMSOopClosure;
+- friend class CMSOopsInGenClosure;
+-
+- OopClosure* _oop_closure;
+-
+- // Used when _oop_closure couldn't be set in an initialization list.
+- void initialize(OopClosure* oop_closure) {
+- assert(_oop_closure == NULL, "Should only be called once");
+- _oop_closure = oop_closure;
+- }
++// TODO: This duplication of the MetadataAwareOopClosure class is only needed
++// because some CMS OopClosures derive from OopsInGenClosure. It would be
++// good to get rid of them completely.
++class MetadataAwareOopsInGenClosure: public OopsInGenClosure {
++ KlassToOopClosure _klass_closure;
+ public:
+- CMKlassClosure(OopClosure* oop_closure = NULL) : _oop_closure(oop_closure) { }
+-
+- void do_klass(Klass* k);
+-};
+-
+-// The base class for all CMS marking closures.
+-// It's used to proxy through the metadata to the oops defined in them.
+-class CMSOopClosure: public ExtendedOopClosure {
+- CMKlassClosure _klass_closure;
+- public:
+- CMSOopClosure() : ExtendedOopClosure() {
+- _klass_closure.initialize(this);
+- }
+- CMSOopClosure(ReferenceProcessor* rp) : ExtendedOopClosure(rp) {
++ MetadataAwareOopsInGenClosure() {
+ _klass_closure.initialize(this);
+ }
+
+@@ -87,26 +68,7 @@
+ virtual void do_class_loader_data(ClassLoaderData* cld);
+ };
+
+-// TODO: This duplication of the CMSOopClosure class is only needed because
+-// some CMS OopClosures derive from OopsInGenClosure. It would be good
+-// to get rid of them completely.
+-class CMSOopsInGenClosure: public OopsInGenClosure {
+- CMKlassClosure _klass_closure;
+- public:
+- CMSOopsInGenClosure() {
+- _klass_closure.initialize(this);
+- }
+-
+- virtual bool do_metadata() { return do_metadata_nv(); }
+- inline bool do_metadata_nv() { return true; }
+-
+- virtual void do_klass(Klass* k);
+- void do_klass_nv(Klass* k);
+-
+- virtual void do_class_loader_data(ClassLoaderData* cld);
+-};
+-
+-class MarkRefsIntoClosure: public CMSOopsInGenClosure {
++class MarkRefsIntoClosure: public MetadataAwareOopsInGenClosure {
+ private:
+ const MemRegion _span;
+ CMSBitMap* _bitMap;
+@@ -122,7 +84,7 @@
+ }
+ };
+
+-class Par_MarkRefsIntoClosure: public CMSOopsInGenClosure {
++class Par_MarkRefsIntoClosure: public MetadataAwareOopsInGenClosure {
+ private:
+ const MemRegion _span;
+ CMSBitMap* _bitMap;
+@@ -140,7 +102,7 @@
+
+ // A variant of the above used in certain kinds of CMS
+ // marking verification.
+-class MarkRefsIntoVerifyClosure: public CMSOopsInGenClosure {
++class MarkRefsIntoVerifyClosure: public MetadataAwareOopsInGenClosure {
+ private:
+ const MemRegion _span;
+ CMSBitMap* _verification_bm;
+@@ -159,7 +121,7 @@
+ };
+
+ // The non-parallel version (the parallel version appears further below).
+-class PushAndMarkClosure: public CMSOopClosure {
++class PushAndMarkClosure: public MetadataAwareOopClosure {
+ private:
+ CMSCollector* _collector;
+ MemRegion _span;
+@@ -193,7 +155,7 @@
+ // synchronization (for instance, via CAS). The marking stack
+ // used in the non-parallel case above is here replaced with
+ // an OopTaskQueue structure to allow efficient work stealing.
+-class Par_PushAndMarkClosure: public CMSOopClosure {
++class Par_PushAndMarkClosure: public MetadataAwareOopClosure {
+ private:
+ CMSCollector* _collector;
+ MemRegion _span;
+@@ -218,7 +180,7 @@
+ };
+
+ // The non-parallel version (the parallel version appears further below).
+-class MarkRefsIntoAndScanClosure: public CMSOopsInGenClosure {
++class MarkRefsIntoAndScanClosure: public MetadataAwareOopsInGenClosure {
+ private:
+ MemRegion _span;
+ CMSBitMap* _bit_map;
+@@ -262,7 +224,7 @@
+ // stack and the bitMap are shared, so access needs to be suitably
+ // sycnhronized. An OopTaskQueue structure, supporting efficient
+ // workstealing, replaces a CMSMarkStack for storing grey objects.
+-class Par_MarkRefsIntoAndScanClosure: public CMSOopsInGenClosure {
++class Par_MarkRefsIntoAndScanClosure: public MetadataAwareOopsInGenClosure {
+ private:
+ MemRegion _span;
+ CMSBitMap* _bit_map;
+@@ -291,7 +253,7 @@
+ // This closure is used during the concurrent marking phase
+ // following the first checkpoint. Its use is buried in
+ // the closure MarkFromRootsClosure.
+-class PushOrMarkClosure: public CMSOopClosure {
++class PushOrMarkClosure: public MetadataAwareOopClosure {
+ private:
+ CMSCollector* _collector;
+ MemRegion _span;
+@@ -324,7 +286,7 @@
+ // This closure is used during the concurrent marking phase
+ // following the first checkpoint. Its use is buried in
+ // the closure Par_MarkFromRootsClosure.
+-class Par_PushOrMarkClosure: public CMSOopClosure {
++class Par_PushOrMarkClosure: public MetadataAwareOopClosure {
+ private:
+ CMSCollector* _collector;
+ MemRegion _whole_span;
+@@ -364,7 +326,7 @@
+ // processing phase of the CMS final checkpoint step, as
+ // well as during the concurrent precleaning of the discovered
+ // reference lists.
+-class CMSKeepAliveClosure: public CMSOopClosure {
++class CMSKeepAliveClosure: public MetadataAwareOopClosure {
+ private:
+ CMSCollector* _collector;
+ const MemRegion _span;
+@@ -384,7 +346,7 @@
+ inline void do_oop_nv(narrowOop* p) { CMSKeepAliveClosure::do_oop_work(p); }
+ };
+
+-class CMSInnerParMarkAndPushClosure: public CMSOopClosure {
++class CMSInnerParMarkAndPushClosure: public MetadataAwareOopClosure {
+ private:
+ CMSCollector* _collector;
+ MemRegion _span;
+@@ -405,7 +367,7 @@
+ // A parallel (MT) version of the above, used when
+ // reference processing is parallel; the only difference
+ // is in the do_oop method.
+-class CMSParKeepAliveClosure: public CMSOopClosure {
++class CMSParKeepAliveClosure: public MetadataAwareOopClosure {
+ private:
+ MemRegion _span;
+ OopTaskQueue* _work_queue;
+--- ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -44,33 +44,20 @@
+ }
+ }
+
+-// CMSOopClosure and CMSoopsInGenClosure are duplicated,
++// MetadataAwareOopClosure and MetadataAwareOopsInGenClosure are duplicated,
+ // until we get rid of OopsInGenClosure.
+
+-inline void CMSOopClosure::do_klass(Klass* k) { do_klass_nv(k); }
+-inline void CMSOopsInGenClosure::do_klass(Klass* k) { do_klass_nv(k); }
+-
+-inline void CMSOopClosure::do_klass_nv(Klass* k) {
++inline void MetadataAwareOopsInGenClosure::do_klass_nv(Klass* k) {
+ ClassLoaderData* cld = k->class_loader_data();
+ do_class_loader_data(cld);
+ }
+-inline void CMSOopsInGenClosure::do_klass_nv(Klass* k) {
+- ClassLoaderData* cld = k->class_loader_data();
+- do_class_loader_data(cld);
+-}
++inline void MetadataAwareOopsInGenClosure::do_klass(Klass* k) { do_klass_nv(k); }
+
+-inline void CMSOopClosure::do_class_loader_data(ClassLoaderData* cld) {
+- assert(_klass_closure._oop_closure == this, "Must be");
+-
+- bool claim = true; // Must claim the class loader data before processing.
+- cld->oops_do(_klass_closure._oop_closure, &_klass_closure, claim);
+-}
+-inline void CMSOopsInGenClosure::do_class_loader_data(ClassLoaderData* cld) {
++inline void MetadataAwareOopsInGenClosure::do_class_loader_data(ClassLoaderData* cld) {
+ assert(_klass_closure._oop_closure == this, "Must be");
+
+ bool claim = true; // Must claim the class loader data before processing.
+ cld->oops_do(_klass_closure._oop_closure, &_klass_closure, claim);
+ }
+
+-
+ #endif // SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CMSOOPCLOSURES_INLINE_HPP
+--- ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -33,12 +33,14 @@
+ #include "memory/allocation.inline.hpp"
+ #include "memory/blockOffsetTable.inline.hpp"
+ #include "memory/resourceArea.hpp"
++#include "memory/space.inline.hpp"
+ #include "memory/universe.inline.hpp"
+ #include "oops/oop.inline.hpp"
+ #include "runtime/globals.hpp"
+ #include "runtime/handles.inline.hpp"
+ #include "runtime/init.hpp"
+ #include "runtime/java.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/vmThread.hpp"
+ #include "utilities/copy.hpp"
+
+@@ -793,53 +795,6 @@
+ }
+ }
+
+-// Apply the given closure to each oop in the space \intersect memory region.
+-void CompactibleFreeListSpace::oop_iterate(MemRegion mr, ExtendedOopClosure* cl) {
+- assert_lock_strong(freelistLock());
+- if (is_empty()) {
+- return;
+- }
+- MemRegion cur = MemRegion(bottom(), end());
+- mr = mr.intersection(cur);
+- if (mr.is_empty()) {
+- return;
+- }
+- if (mr.equals(cur)) {
+- oop_iterate(cl);
+- return;
+- }
+- assert(mr.end() <= end(), "just took an intersection above");
+- HeapWord* obj_addr = block_start(mr.start());
+- HeapWord* t = mr.end();
+-
+- SpaceMemRegionOopsIterClosure smr_blk(cl, mr);
+- if (block_is_obj(obj_addr)) {
+- // Handle first object specially.
+- oop obj = oop(obj_addr);
+- obj_addr += adjustObjectSize(obj->oop_iterate(&smr_blk));
+- } else {
+- FreeChunk* fc = (FreeChunk*)obj_addr;
+- obj_addr += fc->size();
+- }
+- while (obj_addr < t) {
+- HeapWord* obj = obj_addr;
+- obj_addr += block_size(obj_addr);
+- // If "obj_addr" is not greater than top, then the
+- // entire object "obj" is within the region.
+- if (obj_addr <= t) {
+- if (block_is_obj(obj)) {
+- oop(obj)->oop_iterate(cl);
+- }
+- } else {
+- // "obj" extends beyond end of region
+- if (block_is_obj(obj)) {
+- oop(obj)->oop_iterate(&smr_blk);
+- }
+- break;
+- }
+- }
+-}
+-
+ // NOTE: In the following methods, in order to safely be able to
+ // apply the closure to an object, we need to be sure that the
+ // object has been initialized. We are guaranteed that an object
+@@ -898,42 +853,60 @@
+ UpwardsObjectClosure* cl) {
+ assert_locked(freelistLock());
+ NOT_PRODUCT(verify_objects_initialized());
+- Space::object_iterate_mem(mr, cl);
++ assert(!mr.is_empty(), "Should be non-empty");
++ // We use MemRegion(bottom(), end()) rather than used_region() below
++ // because the two are not necessarily equal for some kinds of
++ // spaces, in particular, certain kinds of free list spaces.
++ // We could use the more complicated but more precise:
++ // MemRegion(used_region().start(), round_to(used_region().end(), CardSize))
++ // but the slight imprecision seems acceptable in the assertion check.
++ assert(MemRegion(bottom(), end()).contains(mr),
++ "Should be within used space");
++ HeapWord* prev = cl->previous(); // max address from last time
++ if (prev >= mr.end()) { // nothing to do
++ return;
++ }
++ // This assert will not work when we go from cms space to perm
++ // space, and use same closure. Easy fix deferred for later. XXX YSR
++ // assert(prev == NULL || contains(prev), "Should be within space");
++
++ bool last_was_obj_array = false;
++ HeapWord *blk_start_addr, *region_start_addr;
++ if (prev > mr.start()) {
++ region_start_addr = prev;
++ blk_start_addr = prev;
++ // The previous invocation may have pushed "prev" beyond the
++ // last allocated block yet there may be still be blocks
++ // in this region due to a particular coalescing policy.
++ // Relax the assertion so that the case where the unallocated
++ // block is maintained and "prev" is beyond the unallocated
++ // block does not cause the assertion to fire.
++ assert((BlockOffsetArrayUseUnallocatedBlock &&
++ (!is_in(prev))) ||
++ (blk_start_addr == block_start(region_start_addr)), "invariant");
++ } else {
++ region_start_addr = mr.start();
++ blk_start_addr = block_start(region_start_addr);
++ }
++ HeapWord* region_end_addr = mr.end();
++ MemRegion derived_mr(region_start_addr, region_end_addr);
++ while (blk_start_addr < region_end_addr) {
++ const size_t size = block_size(blk_start_addr);
++ if (block_is_obj(blk_start_addr)) {
++ last_was_obj_array = cl->do_object_bm(oop(blk_start_addr), derived_mr);
++ } else {
++ last_was_obj_array = false;
++ }
++ blk_start_addr += size;
++ }
++ if (!last_was_obj_array) {
++ assert((bottom() <= blk_start_addr) && (blk_start_addr <= end()),
++ "Should be within (closed) used space");
++ assert(blk_start_addr > prev, "Invariant");
++ cl->set_previous(blk_start_addr); // min address for next time
++ }
+ }
+
+-// Callers of this iterator beware: The closure application should
+-// be robust in the face of uninitialized objects and should (always)
+-// return a correct size so that the next addr + size below gives us a
+-// valid block boundary. [See for instance,
+-// ScanMarkedObjectsAgainCarefullyClosure::do_object_careful()
+-// in ConcurrentMarkSweepGeneration.cpp.]
+-HeapWord*
+-CompactibleFreeListSpace::object_iterate_careful(ObjectClosureCareful* cl) {
+- assert_lock_strong(freelistLock());
+- HeapWord *addr, *last;
+- size_t size;
+- for (addr = bottom(), last = end();
+- addr < last; addr += size) {
+- FreeChunk* fc = (FreeChunk*)addr;
+- if (fc->is_free()) {
+- // Since we hold the free list lock, which protects direct
+- // allocation in this generation by mutators, a free object
+- // will remain free throughout this iteration code.
+- size = fc->size();
+- } else {
+- // Note that the object need not necessarily be initialized,
+- // because (for instance) the free list lock does NOT protect
+- // object initialization. The closure application below must
+- // therefore be correct in the face of uninitialized objects.
+- size = cl->do_object_careful(oop(addr));
+- if (size == 0) {
+- // An unparsable object found. Signal early termination.
+- return addr;
+- }
+- }
+- }
+- return NULL;
+-}
+
+ // Callers of this iterator beware: The closure application should
+ // be robust in the face of uninitialized objects and should (always)
+@@ -2668,7 +2641,7 @@
+ // Get the #blocks we want to claim
+ size_t n_blks = (size_t)_blocks_to_claim[word_sz].average();
+ assert(n_blks > 0, "Error");
+- assert(ResizePLAB || n_blks == OldPLABSize, "Error");
++ assert(ResizeOldPLAB || n_blks == OldPLABSize, "Error");
+ // In some cases, when the application has a phase change,
+ // there may be a sudden and sharp shift in the object survival
+ // profile, and updating the counts at the end of a scavenge
+--- ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -351,10 +351,6 @@
+ unallocated_block() : end());
+ }
+
+- bool is_in(const void* p) const {
+- return used_region().contains(p);
+- }
+-
+ virtual bool is_free_block(const HeapWord* p) const;
+
+ // Resizing support
+@@ -364,7 +360,6 @@
+ Mutex* freelistLock() const { return &_freelistLock; }
+
+ // Iteration support
+- void oop_iterate(MemRegion mr, ExtendedOopClosure* cl);
+ void oop_iterate(ExtendedOopClosure* cl);
+
+ void object_iterate(ObjectClosure* blk);
+@@ -377,6 +372,12 @@
+ // obj_is_alive() to determine whether it is safe to iterate of
+ // an object.
+ void safe_object_iterate(ObjectClosure* blk);
++
++ // Iterate over all objects that intersect with mr, calling "cl->do_object"
++ // on each. There is an exception to this: if this closure has already
++ // been invoked on an object, it may skip such objects in some cases. This is
++ // Most likely to happen in an "upwards" (ascending address) iteration of
++ // MemRegions.
+ void object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl);
+
+ // Requires that "mr" be entirely within the space.
+@@ -385,11 +386,8 @@
+ // terminate the iteration and return the address of the start of the
+ // subregion that isn't done. Return of "NULL" indicates that the
+ // interation completed.
+- virtual HeapWord*
+- object_iterate_careful_m(MemRegion mr,
+- ObjectClosureCareful* cl);
+- virtual HeapWord*
+- object_iterate_careful(ObjectClosureCareful* cl);
++ HeapWord* object_iterate_careful_m(MemRegion mr,
++ ObjectClosureCareful* cl);
+
+ // Override: provides a DCTO_CL specific to this kind of space.
+ DirtyCardToOopClosure* new_dcto_cl(ExtendedOopClosure* cl,
+--- ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -49,7 +49,7 @@
+ #include "memory/genCollectedHeap.hpp"
+ #include "memory/genMarkSweep.hpp"
+ #include "memory/genOopClosures.inline.hpp"
+-#include "memory/iterator.hpp"
++#include "memory/iterator.inline.hpp"
+ #include "memory/padded.hpp"
+ #include "memory/referencePolicy.hpp"
+ #include "memory/resourceArea.hpp"
+@@ -59,6 +59,7 @@
+ #include "runtime/globals_extension.hpp"
+ #include "runtime/handles.inline.hpp"
+ #include "runtime/java.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/vmThread.hpp"
+ #include "services/memoryService.hpp"
+ #include "services/runtimeService.hpp"
+@@ -1519,6 +1520,8 @@
+ gclog_or_tty->print_cr("cms_allocation_rate=%g", stats().cms_allocation_rate());
+ gclog_or_tty->print_cr("occupancy=%3.7f", _cmsGen->occupancy());
+ gclog_or_tty->print_cr("initiatingOccupancy=%3.7f", _cmsGen->initiating_occupancy());
++ gclog_or_tty->print_cr("cms_time_since_begin=%3.7f", stats().cms_time_since_begin());
++ gclog_or_tty->print_cr("cms_time_since_end=%3.7f", stats().cms_time_since_end());
+ gclog_or_tty->print_cr("metadata initialized %d",
+ MetaspaceGC::should_concurrent_collect());
+ }
+@@ -1575,11 +1578,33 @@
+ }
+
+ if (MetaspaceGC::should_concurrent_collect()) {
++ if (Verbose && PrintGCDetails) {
++ gclog_or_tty->print("CMSCollector: collect for metadata allocation ");
++ }
++ return true;
++ }
++
++ // CMSTriggerInterval starts a CMS cycle if enough time has passed.
++ if (CMSTriggerInterval >= 0) {
++ if (CMSTriggerInterval == 0) {
++ // Trigger always
++ return true;
++ }
++
++ // Check the CMS time since begin (we do not check the stats validity
++ // as we want to be able to trigger the first CMS cycle as well)
++ if (stats().cms_time_since_begin() >= (CMSTriggerInterval / ((double) MILLIUNITS))) {
+ if (Verbose && PrintGCDetails) {
+- gclog_or_tty->print("CMSCollector: collect for metadata allocation ");
++ if (stats().valid()) {
++ gclog_or_tty->print_cr("CMSCollector: collect because of trigger interval (time since last begin %3.7f secs)",
++ stats().cms_time_since_begin());
++ } else {
++ gclog_or_tty->print_cr("CMSCollector: collect because of trigger interval (first collection)");
++ }
+ }
+ return true;
+ }
++ }
+
+ return false;
+ }
+@@ -2005,7 +2030,7 @@
+ SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer();
+ gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start());
+
+- GCTraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, NULL);
++ GCTraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, NULL, gc_tracer->gc_id());
+ if (PrintGC && Verbose && !(GCCause::is_user_requested_gc(gch->gc_cause()))) {
+ gclog_or_tty->print_cr("Compact ConcurrentMarkSweepGeneration after %d "
+ "collections passed to foreground collector", _full_gcs_since_conc_gc);
+@@ -2515,8 +2540,10 @@
+ assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
+ "VM thread should have CMS token");
+
++ // The gc id is created in register_foreground_gc_start if this collection is synchronous
++ const GCId gc_id = _collectorState == InitialMarking ? GCId::peek() : _gc_tracer_cm->gc_id();
+ NOT_PRODUCT(GCTraceTime t("CMS:MS (foreground) ", PrintGCDetails && Verbose,
+- true, NULL);)
++ true, NULL, gc_id);)
+ if (UseAdaptiveSizePolicy) {
+ size_policy()->ms_collection_begin();
+ }
+@@ -3031,22 +3058,21 @@
+ HandleMark hm;
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+
+- // Get a clear set of claim bits for the strong roots processing to work with.
++ // Get a clear set of claim bits for the roots processing to work with.
+ ClassLoaderDataGraph::clear_claimed_marks();
+
+ // Mark from roots one level into CMS
+ MarkRefsIntoClosure notOlder(_span, verification_mark_bm());
+ gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
+
+- gch->gen_process_strong_roots(_cmsGen->level(),
+- true, // younger gens are roots
+- true, // activate StrongRootsScope
+- false, // not scavenging
+- SharedHeap::ScanningOption(roots_scanning_options()),
+- &notOlder,
+- true, // walk code active on stacks
+- NULL,
+- NULL); // SSS: Provide correct closure
++ gch->gen_process_roots(_cmsGen->level(),
++ true, // younger gens are roots
++ true, // activate StrongRootsScope
++ SharedHeap::ScanningOption(roots_scanning_options()),
++ should_unload_classes(),
++ &notOlder,
++ NULL,
++ NULL); // SSS: Provide correct closure
+
+ // Now mark from the roots
+ MarkFromRootsClosure markFromRootsClosure(this, _span,
+@@ -3097,24 +3123,24 @@
+ HandleMark hm;
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+
+- // Get a clear set of claim bits for the strong roots processing to work with.
++ // Get a clear set of claim bits for the roots processing to work with.
+ ClassLoaderDataGraph::clear_claimed_marks();
+
+ // Mark from roots one level into CMS
+ MarkRefsIntoVerifyClosure notOlder(_span, verification_mark_bm(),
+ markBitMap());
+- CMKlassClosure klass_closure(&notOlder);
++ CLDToOopClosure cld_closure(&notOlder, true);
+
+ gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
+- gch->gen_process_strong_roots(_cmsGen->level(),
+- true, // younger gens are roots
+- true, // activate StrongRootsScope
+- false, // not scavenging
+- SharedHeap::ScanningOption(roots_scanning_options()),
+- &notOlder,
+- true, // walk code active on stacks
+- NULL,
+- &klass_closure);
++
++ gch->gen_process_roots(_cmsGen->level(),
++ true, // younger gens are roots
++ true, // activate StrongRootsScope
++ SharedHeap::ScanningOption(roots_scanning_options()),
++ should_unload_classes(),
++ &notOlder,
++ NULL,
++ &cld_closure);
+
+ // Now mark from the roots
+ MarkFromRootsVerifyClosure markFromRootsClosure(this, _span,
+@@ -3175,16 +3201,6 @@
+ }
+
+ void
+-ConcurrentMarkSweepGeneration::oop_iterate(MemRegion mr, ExtendedOopClosure* cl) {
+- if (freelistLock()->owned_by_self()) {
+- Generation::oop_iterate(mr, cl);
+- } else {
+- MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
+- Generation::oop_iterate(mr, cl);
+- }
+-}
+-
+-void
+ ConcurrentMarkSweepGeneration::oop_iterate(ExtendedOopClosure* cl) {
+ if (freelistLock()->owned_by_self()) {
+ Generation::oop_iterate(cl);
+@@ -3311,12 +3327,10 @@
+ void CMSCollector::setup_cms_unloading_and_verification_state() {
+ const bool should_verify = VerifyBeforeGC || VerifyAfterGC || VerifyDuringGC
+ || VerifyBeforeExit;
+- const int rso = SharedHeap::SO_Strings | SharedHeap::SO_CodeCache;
++ const int rso = SharedHeap::SO_AllCodeCache;
+
+ // We set the proper root for this CMS cycle here.
+ if (should_unload_classes()) { // Should unload classes this cycle
+- remove_root_scanning_option(SharedHeap::SO_AllClasses);
+- add_root_scanning_option(SharedHeap::SO_SystemClasses);
+ remove_root_scanning_option(rso); // Shrink the root set appropriately
+ set_verifying(should_verify); // Set verification state for this cycle
+ return; // Nothing else needs to be done at this time
+@@ -3324,8 +3338,6 @@
+
+ // Not unloading classes this cycle
+ assert(!should_unload_classes(), "Inconsitency!");
+- remove_root_scanning_option(SharedHeap::SO_SystemClasses);
+- add_root_scanning_option(SharedHeap::SO_AllClasses);
+
+ if ((!verifying() || unloaded_classes_last_cycle()) && should_verify) {
+ // Include symbols, strings and code cache elements to prevent their resurrection.
+@@ -3533,6 +3545,7 @@
+ public:
+ CMSPhaseAccounting(CMSCollector *collector,
+ const char *phase,
++ const GCId gc_id,
+ bool print_cr = true);
+ ~CMSPhaseAccounting();
+
+@@ -3541,6 +3554,7 @@
+ const char *_phase;
+ elapsedTimer _wallclock;
+ bool _print_cr;
++ const GCId _gc_id;
+
+ public:
+ // Not MT-safe; so do not pass around these StackObj's
+@@ -3556,15 +3570,15 @@
+
+ CMSPhaseAccounting::CMSPhaseAccounting(CMSCollector *collector,
+ const char *phase,
++ const GCId gc_id,
+ bool print_cr) :
+- _collector(collector), _phase(phase), _print_cr(print_cr) {
++ _collector(collector), _phase(phase), _print_cr(print_cr), _gc_id(gc_id) {
+
+ if (PrintCMSStatistics != 0) {
+ _collector->resetYields();
+ }
+ if (PrintGCDetails) {
+- gclog_or_tty->date_stamp(PrintGCDateStamps);
+- gclog_or_tty->stamp(PrintGCTimeStamps);
++ gclog_or_tty->gclog_stamp(_gc_id);
+ gclog_or_tty->print_cr("[%s-concurrent-%s-start]",
+ _collector->cmsGen()->short_name(), _phase);
+ }
+@@ -3578,8 +3592,7 @@
+ _collector->stopTimer();
+ _wallclock.stop();
+ if (PrintGCDetails) {
+- gclog_or_tty->date_stamp(PrintGCDateStamps);
+- gclog_or_tty->stamp(PrintGCTimeStamps);
++ gclog_or_tty->gclog_stamp(_gc_id);
+ gclog_or_tty->print("[%s-concurrent-%s: %3.3f/%3.3f secs]",
+ _collector->cmsGen()->short_name(),
+ _phase, _collector->timerValue(), _wallclock.seconds());
+@@ -3677,7 +3690,7 @@
+ setup_cms_unloading_and_verification_state();
+
+ NOT_PRODUCT(GCTraceTime t("\ncheckpointRootsInitialWork",
+- PrintGCDetails && Verbose, true, _gc_timer_cm);)
++ PrintGCDetails && Verbose, true, _gc_timer_cm, _gc_tracer_cm->gc_id());)
+ if (UseAdaptiveSizePolicy) {
+ size_policy()->checkpoint_roots_initial_begin();
+ }
+@@ -3690,12 +3703,6 @@
+ ResourceMark rm;
+ HandleMark hm;
+
+- FalseClosure falseClosure;
+- // In the case of a synchronous collection, we will elide the
+- // remark step, so it's important to catch all the nmethod oops
+- // in this step.
+- // The final 'true' flag to gen_process_strong_roots will ensure this.
+- // If 'async' is true, we can relax the nmethod tracing.
+ MarkRefsIntoClosure notOlder(_span, &_markBitMap);
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+
+@@ -3741,17 +3748,16 @@
+ gch->set_par_threads(0);
+ } else {
+ // The serial version.
+- CMKlassClosure klass_closure(&notOlder);
++ CLDToOopClosure cld_closure(&notOlder, true);
+ gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
+- gch->gen_process_strong_roots(_cmsGen->level(),
+- true, // younger gens are roots
+- true, // activate StrongRootsScope
+- false, // not scavenging
+- SharedHeap::ScanningOption(roots_scanning_options()),
+- &notOlder,
+- true, // walk all of code cache if (so & SO_CodeCache)
+- NULL,
+- &klass_closure);
++ gch->gen_process_roots(_cmsGen->level(),
++ true, // younger gens are roots
++ true, // activate StrongRootsScope
++ SharedHeap::ScanningOption(roots_scanning_options()),
++ should_unload_classes(),
++ &notOlder,
++ NULL,
++ &cld_closure);
+ }
+ }
+
+@@ -3802,7 +3808,7 @@
+
+ CMSTokenSyncWithLocks ts(true, bitMapLock());
+ TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
+- CMSPhaseAccounting pa(this, "mark", !PrintGCDetails);
++ CMSPhaseAccounting pa(this, "mark", _gc_tracer_cm->gc_id(), !PrintGCDetails);
+ res = markFromRootsWork(asynch);
+ if (res) {
+ _collectorState = Precleaning;
+@@ -4205,7 +4211,7 @@
+ pst->all_tasks_completed();
+ }
+
+-class Par_ConcMarkingClosure: public CMSOopClosure {
++class Par_ConcMarkingClosure: public MetadataAwareOopClosure {
+ private:
+ CMSCollector* _collector;
+ CMSConcMarkingTask* _task;
+@@ -4218,7 +4224,7 @@
+ public:
+ Par_ConcMarkingClosure(CMSCollector* collector, CMSConcMarkingTask* task, OopTaskQueue* work_queue,
+ CMSBitMap* bit_map, CMSMarkStack* overflow_stack):
+- CMSOopClosure(collector->ref_processor()),
++ MetadataAwareOopClosure(collector->ref_processor()),
+ _collector(collector),
+ _task(task),
+ _span(collector->_span),
+@@ -4525,7 +4531,7 @@
+ _start_sampling = false;
+ }
+ TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
+- CMSPhaseAccounting pa(this, "preclean", !PrintGCDetails);
++ CMSPhaseAccounting pa(this, "preclean", _gc_tracer_cm->gc_id(), !PrintGCDetails);
+ preclean_work(CMSPrecleanRefLists1, CMSPrecleanSurvivors1);
+ }
+ CMSTokenSync x(true); // is cms thread
+@@ -4554,7 +4560,7 @@
+ // we will never do an actual abortable preclean cycle.
+ if (get_eden_used() > CMSScheduleRemarkEdenSizeThreshold) {
+ TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
+- CMSPhaseAccounting pa(this, "abortable-preclean", !PrintGCDetails);
++ CMSPhaseAccounting pa(this, "abortable-preclean", _gc_tracer_cm->gc_id(), !PrintGCDetails);
+ // We need more smarts in the abortable preclean
+ // loop below to deal with cases where allocation
+ // in young gen is very very slow, and our precleaning
+@@ -4699,7 +4705,7 @@
+ GCTimer *gc_timer = NULL; // Currently not tracing concurrent phases
+ rp->preclean_discovered_references(
+ rp->is_alive_non_header(), &keep_alive, &complete_trace, &yield_cl,
+- gc_timer);
++ gc_timer, _gc_tracer_cm->gc_id());
+ }
+
+ if (clean_survivor) { // preclean the active survivor space(s)
+@@ -4989,7 +4995,7 @@
+ }
+
+ class PrecleanKlassClosure : public KlassClosure {
+- CMKlassClosure _cm_klass_closure;
++ KlassToOopClosure _cm_klass_closure;
+ public:
+ PrecleanKlassClosure(OopClosure* oop_closure) : _cm_klass_closure(oop_closure) {}
+ void do_klass(Klass* k) {
+@@ -5042,7 +5048,7 @@
+ // expect it to be false and set to true
+ FlagSetting fl(gch->_is_gc_active, false);
+ NOT_PRODUCT(GCTraceTime t("Scavenge-Before-Remark",
+- PrintGCDetails && Verbose, true, _gc_timer_cm);)
++ PrintGCDetails && Verbose, true, _gc_timer_cm, _gc_tracer_cm->gc_id());)
+ int level = _cmsGen->level() - 1;
+ if (level >= 0) {
+ gch->do_collection(true, // full (i.e. force, see below)
+@@ -5071,7 +5077,7 @@
+ void CMSCollector::checkpointRootsFinalWork(bool asynch,
+ bool clear_all_soft_refs, bool init_mark_was_synchronous) {
+
+- NOT_PRODUCT(GCTraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, _gc_timer_cm);)
++ NOT_PRODUCT(GCTraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());)
+
+ assert(haveFreelistLocks(), "must have free list locks");
+ assert_lock_strong(bitMapLock());
+@@ -5126,11 +5132,11 @@
+ // the most recent young generation GC, minus those cleaned up by the
+ // concurrent precleaning.
+ if (CMSParallelRemarkEnabled && CollectedHeap::use_parallel_gc_threads()) {
+- GCTraceTime t("Rescan (parallel) ", PrintGCDetails, false, _gc_timer_cm);
++ GCTraceTime t("Rescan (parallel) ", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+ do_remark_parallel();
+ } else {
+ GCTraceTime t("Rescan (non-parallel) ", PrintGCDetails, false,
+- _gc_timer_cm);
++ _gc_timer_cm, _gc_tracer_cm->gc_id());
+ do_remark_non_parallel();
+ }
+ }
+@@ -5143,7 +5149,7 @@
+ verify_overflow_empty();
+
+ {
+- NOT_PRODUCT(GCTraceTime ts("refProcessingWork", PrintGCDetails, false, _gc_timer_cm);)
++ NOT_PRODUCT(GCTraceTime ts("refProcessingWork", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());)
+ refProcessingWork(asynch, clear_all_soft_refs);
+ }
+ verify_work_stacks_empty();
+@@ -5227,7 +5233,6 @@
+ _timer.start();
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+ Par_MarkRefsIntoClosure par_mri_cl(_collector->_span, &(_collector->_markBitMap));
+- CMKlassClosure klass_closure(&par_mri_cl);
+
+ // ---------- young gen roots --------------
+ {
+@@ -5243,17 +5248,19 @@
+ // ---------- remaining roots --------------
+ _timer.reset();
+ _timer.start();
+- gch->gen_process_strong_roots(_collector->_cmsGen->level(),
+- false, // yg was scanned above
+- false, // this is parallel code
+- false, // not scavenging
+- SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
+- &par_mri_cl,
+- true, // walk all of code cache if (so & SO_CodeCache)
+- NULL,
+- &klass_closure);
++
++ CLDToOopClosure cld_closure(&par_mri_cl, true);
++
++ gch->gen_process_roots(_collector->_cmsGen->level(),
++ false, // yg was scanned above
++ false, // this is parallel code
++ SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
++ _collector->should_unload_classes(),
++ &par_mri_cl,
++ NULL,
++ &cld_closure);
+ assert(_collector->should_unload_classes()
+- || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_CodeCache),
++ || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_AllCodeCache),
+ "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
+ _timer.stop();
+ if (PrintCMSStatistics != 0) {
+@@ -5303,7 +5310,7 @@
+ };
+
+ class RemarkKlassClosure : public KlassClosure {
+- CMKlassClosure _cm_klass_closure;
++ KlassToOopClosure _cm_klass_closure;
+ public:
+ RemarkKlassClosure(OopClosure* oop_closure) : _cm_klass_closure(oop_closure) {}
+ void do_klass(Klass* k) {
+@@ -5380,17 +5387,17 @@
+ // ---------- remaining roots --------------
+ _timer.reset();
+ _timer.start();
+- gch->gen_process_strong_roots(_collector->_cmsGen->level(),
+- false, // yg was scanned above
+- false, // this is parallel code
+- false, // not scavenging
+- SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
+- &par_mrias_cl,
+- true, // walk all of code cache if (so & SO_CodeCache)
+- NULL,
+- NULL); // The dirty klasses will be handled below
++ gch->gen_process_roots(_collector->_cmsGen->level(),
++ false, // yg was scanned above
++ false, // this is parallel code
++ SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
++ _collector->should_unload_classes(),
++ &par_mrias_cl,
++ NULL,
++ NULL); // The dirty klasses will be handled below
++
+ assert(_collector->should_unload_classes()
+- || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_CodeCache),
++ || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_AllCodeCache),
+ "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
+ _timer.stop();
+ if (PrintCMSStatistics != 0) {
+@@ -5443,7 +5450,7 @@
+ // We might have added oops to ClassLoaderData::_handles during the
+ // concurrent marking phase. These oops point to newly allocated objects
+ // that are guaranteed to be kept alive. Either by the direct allocation
+- // code, or when the young collector processes the strong roots. Hence,
++ // code, or when the young collector processes the roots. Hence,
+ // we don't have to revisit the _handles block during the remark phase.
+
+ // ---------- rescan dirty cards ------------
+@@ -5865,7 +5872,7 @@
+ cms_space,
+ n_workers, workers, task_queues());
+
+- // Set up for parallel process_strong_roots work.
++ // Set up for parallel process_roots work.
+ gch->set_par_threads(n_workers);
+ // We won't be iterating over the cards in the card table updating
+ // the younger_gen cards, so we shouldn't call the following else
+@@ -5874,7 +5881,7 @@
+ // gch->rem_set()->prepare_for_younger_refs_iterate(true); // parallel
+
+ // The young gen rescan work will not be done as part of
+- // process_strong_roots (which currently doesn't knw how to
++ // process_roots (which currently doesn't know how to
+ // parallelize such a scan), but rather will be broken up into
+ // a set of parallel tasks (via the sampling that the [abortable]
+ // preclean phase did of EdenSpace, plus the [two] tasks of
+@@ -5928,7 +5935,7 @@
+ NULL, // space is set further below
+ &_markBitMap, &_markStack, &mrias_cl);
+ {
+- GCTraceTime t("grey object rescan", PrintGCDetails, false, _gc_timer_cm);
++ GCTraceTime t("grey object rescan", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+ // Iterate over the dirty cards, setting the corresponding bits in the
+ // mod union table.
+ {
+@@ -5965,29 +5972,29 @@
+ Universe::verify();
+ }
+ {
+- GCTraceTime t("root rescan", PrintGCDetails, false, _gc_timer_cm);
++ GCTraceTime t("root rescan", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+
+ verify_work_stacks_empty();
+
+ gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
+ GenCollectedHeap::StrongRootsScope srs(gch);
+- gch->gen_process_strong_roots(_cmsGen->level(),
+- true, // younger gens as roots
+- false, // use the local StrongRootsScope
+- false, // not scavenging
+- SharedHeap::ScanningOption(roots_scanning_options()),
+- &mrias_cl,
+- true, // walk code active on stacks
+- NULL,
+- NULL); // The dirty klasses will be handled below
++
++ gch->gen_process_roots(_cmsGen->level(),
++ true, // younger gens as roots
++ false, // use the local StrongRootsScope
++ SharedHeap::ScanningOption(roots_scanning_options()),
++ should_unload_classes(),
++ &mrias_cl,
++ NULL,
++ NULL); // The dirty klasses will be handled below
+
+ assert(should_unload_classes()
+- || (roots_scanning_options() & SharedHeap::SO_CodeCache),
++ || (roots_scanning_options() & SharedHeap::SO_AllCodeCache),
+ "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
+ }
+
+ {
+- GCTraceTime t("visit unhandled CLDs", PrintGCDetails, false, _gc_timer_cm);
++ GCTraceTime t("visit unhandled CLDs", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+
+ verify_work_stacks_empty();
+
+@@ -6006,7 +6013,7 @@
+ }
+
+ {
+- GCTraceTime t("dirty klass scan", PrintGCDetails, false, _gc_timer_cm);
++ GCTraceTime t("dirty klass scan", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+
+ verify_work_stacks_empty();
+
+@@ -6019,7 +6026,7 @@
+ // We might have added oops to ClassLoaderData::_handles during the
+ // concurrent marking phase. These oops point to newly allocated objects
+ // that are guaranteed to be kept alive. Either by the direct allocation
+- // code, or when the young collector processes the strong roots. Hence,
++ // code, or when the young collector processes the roots. Hence,
+ // we don't have to revisit the _handles block during the remark phase.
+
+ verify_work_stacks_empty();
+@@ -6074,6 +6081,8 @@
+ };
+
+ void CMSRefProcTaskProxy::work(uint worker_id) {
++ ResourceMark rm;
++ HandleMark hm;
+ assert(_collector->_span.equals(_span), "Inconsistency in _span");
+ CMSParKeepAliveClosure par_keep_alive(_collector, _span,
+ _mark_bit_map,
+@@ -6208,7 +6217,7 @@
+ _span, &_markBitMap, &_markStack,
+ &cmsKeepAliveClosure, false /* !preclean */);
+ {
+- GCTraceTime t("weak refs processing", PrintGCDetails, false, _gc_timer_cm);
++ GCTraceTime t("weak refs processing", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+
+ ReferenceProcessorStats stats;
+ if (rp->processing_is_mt()) {
+@@ -6233,13 +6242,15 @@
+ &cmsKeepAliveClosure,
+ &cmsDrainMarkingStackClosure,
+ &task_executor,
+- _gc_timer_cm);
++ _gc_timer_cm,
++ _gc_tracer_cm->gc_id());
+ } else {
+ stats = rp->process_discovered_references(&_is_alive_closure,
+ &cmsKeepAliveClosure,
+ &cmsDrainMarkingStackClosure,
+ NULL,
+- _gc_timer_cm);
++ _gc_timer_cm,
++ _gc_tracer_cm->gc_id());
+ }
+ _gc_tracer_cm->report_gc_reference_stats(stats);
+
+@@ -6250,7 +6261,7 @@
+
+ if (should_unload_classes()) {
+ {
+- GCTraceTime t("class unloading", PrintGCDetails, false, _gc_timer_cm);
++ GCTraceTime t("class unloading", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+
+ // Unload classes and purge the SystemDictionary.
+ bool purged_class = SystemDictionary::do_unloading(&_is_alive_closure);
+@@ -6263,19 +6274,18 @@
+ }
+
+ {
+- GCTraceTime t("scrub symbol table", PrintGCDetails, false, _gc_timer_cm);
++ GCTraceTime t("scrub symbol table", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
+ // Clean up unreferenced symbols in symbol table.
+ SymbolTable::unlink();
+ }
+- }
+-
+- // CMS doesn't use the StringTable as hard roots when class unloading is turned off.
+- // Need to check if we really scanned the StringTable.
+- if ((roots_scanning_options() & SharedHeap::SO_Strings) == 0) {
+- GCTraceTime t("scrub string table", PrintGCDetails, false, _gc_timer_cm);
+- // Delete entries for dead interned strings.
+- StringTable::unlink(&_is_alive_closure);
+- }
++
++ {
++ GCTraceTime t("scrub string table", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());
++ // Delete entries for dead interned strings.
++ StringTable::unlink(&_is_alive_closure);
++ }
++ }
++
+
+ // Restore any preserved marks as a result of mark stack or
+ // work queue overflow
+@@ -6339,7 +6349,7 @@
+ _intra_sweep_timer.start();
+ if (asynch) {
+ TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
+- CMSPhaseAccounting pa(this, "sweep", !PrintGCDetails);
++ CMSPhaseAccounting pa(this, "sweep", _gc_tracer_cm->gc_id(), !PrintGCDetails);
+ // First sweep the old gen
+ {
+ CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(),
+@@ -6560,7 +6570,7 @@
+ // Clear the mark bitmap (no grey objects to start with)
+ // for the next cycle.
+ TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
+- CMSPhaseAccounting cmspa(this, "reset", !PrintGCDetails);
++ CMSPhaseAccounting cmspa(this, "reset", _gc_tracer_cm->gc_id(), !PrintGCDetails);
+
+ HeapWord* curAddr = _markBitMap.startWord();
+ while (curAddr < _markBitMap.endWord()) {
+@@ -6626,7 +6636,7 @@
+ void CMSCollector::do_CMS_operation(CMS_op_type op, GCCause::Cause gc_cause) {
+ gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
+ TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
+- GCTraceTime t(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
++ GCTraceTime t(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer_cm->gc_id());
+ TraceCollectorStats tcs(counters());
+
+ switch (op) {
+@@ -7744,7 +7754,7 @@
+ CMSCollector* collector, MemRegion span,
+ CMSBitMap* verification_bm, CMSBitMap* cms_bm,
+ CMSMarkStack* mark_stack):
+- CMSOopClosure(collector->ref_processor()),
++ MetadataAwareOopClosure(collector->ref_processor()),
+ _collector(collector),
+ _span(span),
+ _verification_bm(verification_bm),
+@@ -7797,7 +7807,7 @@
+ MemRegion span,
+ CMSBitMap* bitMap, CMSMarkStack* markStack,
+ HeapWord* finger, MarkFromRootsClosure* parent) :
+- CMSOopClosure(collector->ref_processor()),
++ MetadataAwareOopClosure(collector->ref_processor()),
+ _collector(collector),
+ _span(span),
+ _bitMap(bitMap),
+@@ -7814,7 +7824,7 @@
+ HeapWord* finger,
+ HeapWord** global_finger_addr,
+ Par_MarkFromRootsClosure* parent) :
+- CMSOopClosure(collector->ref_processor()),
++ MetadataAwareOopClosure(collector->ref_processor()),
+ _collector(collector),
+ _whole_span(collector->_span),
+ _span(span),
+@@ -7863,11 +7873,6 @@
+ _overflow_stack->expand(); // expand the stack if possible
+ }
+
+-void CMKlassClosure::do_klass(Klass* k) {
+- assert(_oop_closure != NULL, "Not initialized?");
+- k->oops_do(_oop_closure);
+-}
+-
+ void PushOrMarkClosure::do_oop(oop obj) {
+ // Ignore mark word because we are running concurrent with mutators.
+ assert(obj->is_oop_or_null(true), "expected an oop or NULL");
+@@ -7965,7 +7970,7 @@
+ CMSBitMap* mod_union_table,
+ CMSMarkStack* mark_stack,
+ bool concurrent_precleaning):
+- CMSOopClosure(rp),
++ MetadataAwareOopClosure(rp),
+ _collector(collector),
+ _span(span),
+ _bit_map(bit_map),
+@@ -8038,7 +8043,7 @@
+ ReferenceProcessor* rp,
+ CMSBitMap* bit_map,
+ OopTaskQueue* work_queue):
+- CMSOopClosure(rp),
++ MetadataAwareOopClosure(rp),
+ _collector(collector),
+ _span(span),
+ _bit_map(bit_map),
+--- ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -32,6 +32,7 @@
+ #include "gc_implementation/shared/generationCounters.hpp"
+ #include "memory/freeBlockDictionary.hpp"
+ #include "memory/generation.hpp"
++#include "memory/iterator.hpp"
+ #include "runtime/mutexLocker.hpp"
+ #include "runtime/virtualspace.hpp"
+ #include "services/memoryService.hpp"
+@@ -1289,7 +1290,6 @@
+ void save_sweep_limit();
+
+ // More iteration support
+- virtual void oop_iterate(MemRegion mr, ExtendedOopClosure* cl);
+ virtual void oop_iterate(ExtendedOopClosure* cl);
+ virtual void safe_object_iterate(ObjectClosure* cl);
+ virtual void object_iterate(ObjectClosure* cl);
+@@ -1387,13 +1387,6 @@
+ // Closures of various sorts used by CMS to accomplish its work
+ //
+
+-// This closure is used to check that a certain set of oops is empty.
+-class FalseClosure: public OopClosure {
+- public:
+- void do_oop(oop* p) { guarantee(false, "Should be an empty set"); }
+- void do_oop(narrowOop* p) { guarantee(false, "Should be an empty set"); }
+-};
+-
+ // This closure is used to do concurrent marking from the roots
+ // following the first checkpoint.
+ class MarkFromRootsClosure: public BitMapClosure {
+@@ -1458,7 +1451,7 @@
+
+ // The following closures are used to do certain kinds of verification of
+ // CMS marking.
+-class PushAndMarkVerifyClosure: public CMSOopClosure {
++class PushAndMarkVerifyClosure: public MetadataAwareOopClosure {
+ CMSCollector* _collector;
+ MemRegion _span;
+ CMSBitMap* _verification_bm;
+@@ -1511,6 +1504,19 @@
+ }
+ };
+
++// A version of ObjectClosure with "memory" (see _previous_address below)
++class UpwardsObjectClosure: public BoolObjectClosure {
++ HeapWord* _previous_address;
++ public:
++ UpwardsObjectClosure() : _previous_address(NULL) { }
++ void set_previous(HeapWord* addr) { _previous_address = addr; }
++ HeapWord* previous() { return _previous_address; }
++ // A return value of "true" can be used by the caller to decide
++ // if this object's end should *NOT* be recorded in
++ // _previous_address above.
++ virtual bool do_object_bm(oop obj, MemRegion mr) = 0;
++};
++
+ // This closure is used during the second checkpointing phase
+ // to rescan the marked objects on the dirty cards in the mod
+ // union table and the card table proper. It's invoked via
+--- ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -50,8 +50,12 @@
+ void VM_CMS_Operation::acquire_pending_list_lock() {
+ // The caller may block while communicating
+ // with the SLT thread in order to acquire/release the PLL.
+- ConcurrentMarkSweepThread::slt()->
+- manipulatePLL(SurrogateLockerThread::acquirePLL);
++ SurrogateLockerThread* slt = ConcurrentMarkSweepThread::slt();
++ if (slt != NULL) {
++ slt->manipulatePLL(SurrogateLockerThread::acquirePLL);
++ } else {
++ SurrogateLockerThread::report_missing_slt();
++ }
+ }
+
+ void VM_CMS_Operation::release_and_notify_pending_list_lock() {
+@@ -64,7 +68,7 @@
+ void VM_CMS_Operation::verify_before_gc() {
+ if (VerifyBeforeGC &&
+ GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
+- GCTraceTime tm("Verify Before", false, false, _collector->_gc_timer_cm);
++ GCTraceTime tm("Verify Before", false, false, _collector->_gc_timer_cm, _collector->_gc_tracer_cm->gc_id());
+ HandleMark hm;
+ FreelistLocker x(_collector);
+ MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
+@@ -76,7 +80,7 @@
+ void VM_CMS_Operation::verify_after_gc() {
+ if (VerifyAfterGC &&
+ GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
+- GCTraceTime tm("Verify After", false, false, _collector->_gc_timer_cm);
++ GCTraceTime tm("Verify After", false, false, _collector->_gc_timer_cm, _collector->_gc_tracer_cm->gc_id());
+ HandleMark hm;
+ FreelistLocker x(_collector);
+ MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/bufferingOopClosure.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,271 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "gc_implementation/g1/bufferingOopClosure.hpp"
++#include "memory/iterator.hpp"
++#include "utilities/debug.hpp"
++
++/////////////// Unit tests ///////////////
++
++#ifndef PRODUCT
++
++class TestBufferingOopClosure {
++
++ // Helper class to fake a set of oop*s and narrowOop*s.
++ class FakeRoots {
++ public:
++ // Used for sanity checking of the values passed to the do_oops functions in the test.
++ static const uintptr_t NarrowOopMarker = uintptr_t(1) << (BitsPerWord -1);
++
++ int _num_narrow;
++ int _num_full;
++ void** _narrow;
++ void** _full;
++
++ FakeRoots(int num_narrow, int num_full) :
++ _num_narrow(num_narrow),
++ _num_full(num_full),
++ _narrow((void**)::malloc(sizeof(void*) * num_narrow)),
++ _full((void**)::malloc(sizeof(void*) * num_full)) {
++
++ for (int i = 0; i < num_narrow; i++) {
++ _narrow[i] = (void*)(NarrowOopMarker + (uintptr_t)i);
++ }
++ for (int i = 0; i < num_full; i++) {
++ _full[i] = (void*)(uintptr_t)i;
++ }
++ }
++
++ ~FakeRoots() {
++ ::free(_narrow);
++ ::free(_full);
++ }
++
++ void oops_do_narrow_then_full(OopClosure* cl) {
++ for (int i = 0; i < _num_narrow; i++) {
++ cl->do_oop((narrowOop*)_narrow[i]);
++ }
++ for (int i = 0; i < _num_full; i++) {
++ cl->do_oop((oop*)_full[i]);
++ }
++ }
++
++ void oops_do_full_then_narrow(OopClosure* cl) {
++ for (int i = 0; i < _num_full; i++) {
++ cl->do_oop((oop*)_full[i]);
++ }
++ for (int i = 0; i < _num_narrow; i++) {
++ cl->do_oop((narrowOop*)_narrow[i]);
++ }
++ }
++
++ void oops_do_mixed(OopClosure* cl) {
++ int i;
++ for (i = 0; i < _num_full && i < _num_narrow; i++) {
++ cl->do_oop((oop*)_full[i]);
++ cl->do_oop((narrowOop*)_narrow[i]);
++ }
++ for (int j = i; j < _num_full; j++) {
++ cl->do_oop((oop*)_full[i]);
++ }
++ for (int j = i; j < _num_narrow; j++) {
++ cl->do_oop((narrowOop*)_narrow[i]);
++ }
++ }
++
++ static const int MaxOrder = 2;
++
++ void oops_do(OopClosure* cl, int do_oop_order) {
++ switch(do_oop_order) {
++ case 0:
++ oops_do_narrow_then_full(cl);
++ break;
++ case 1:
++ oops_do_full_then_narrow(cl);
++ break;
++ case 2:
++ oops_do_mixed(cl);
++ break;
++ default:
++ oops_do_narrow_then_full(cl);
++ break;
++ }
++ }
++ };
++
++ class CountOopClosure : public OopClosure {
++ int _narrow_oop_count;
++ int _full_oop_count;
++ public:
++ CountOopClosure() : _narrow_oop_count(0), _full_oop_count(0) {}
++ void do_oop(narrowOop* p) {
++ assert((uintptr_t(p) & FakeRoots::NarrowOopMarker) != 0,
++ "The narrowOop was unexpectedly not marked with the NarrowOopMarker");
++ _narrow_oop_count++;
++ }
++
++ void do_oop(oop* p){
++ assert((uintptr_t(p) & FakeRoots::NarrowOopMarker) == 0,
++ "The oop was unexpectedly marked with the NarrowOopMarker");
++ _full_oop_count++;
++ }
++
++ int narrow_oop_count() { return _narrow_oop_count; }
++ int full_oop_count() { return _full_oop_count; }
++ int all_oop_count() { return _narrow_oop_count + _full_oop_count; }
++ };
++
++ class DoNothingOopClosure : public OopClosure {
++ public:
++ void do_oop(narrowOop* p) {}
++ void do_oop(oop* p) {}
++ };
++
++ static void testCount(int num_narrow, int num_full, int do_oop_order) {
++ FakeRoots fr(num_narrow, num_full);
++
++ CountOopClosure coc;
++ BufferingOopClosure boc(&coc);
++
++ fr.oops_do(&boc, do_oop_order);
++
++ boc.done();
++
++ #define assert_testCount(got, expected) \
++ assert((got) == (expected), \
++ err_msg("Expected: %d, got: %d, when running testCount(%d, %d, %d)", \
++ (got), (expected), num_narrow, num_full, do_oop_order))
++
++ assert_testCount(num_narrow, coc.narrow_oop_count());
++ assert_testCount(num_full, coc.full_oop_count());
++ assert_testCount(num_narrow + num_full, coc.all_oop_count());
++ }
++
++ static void testCount() {
++ int buffer_length = BufferingOopClosure::BufferLength;
++
++ for (int order = 0; order < FakeRoots::MaxOrder; order++) {
++ testCount(0, 0, order);
++ testCount(10, 0, order);
++ testCount(0, 10, order);
++ testCount(10, 10, order);
++ testCount(buffer_length, 10, order);
++ testCount(10, buffer_length, order);
++ testCount(buffer_length, buffer_length, order);
++ testCount(buffer_length + 1, 10, order);
++ testCount(10, buffer_length + 1, order);
++ testCount(buffer_length + 1, buffer_length, order);
++ testCount(buffer_length, buffer_length + 1, order);
++ testCount(buffer_length + 1, buffer_length + 1, order);
++ }
++ }
++
++ static void testIsBufferEmptyOrFull(int num_narrow, int num_full, bool expect_empty, bool expect_full) {
++ FakeRoots fr(num_narrow, num_full);
++
++ DoNothingOopClosure cl;
++ BufferingOopClosure boc(&cl);
++
++ fr.oops_do(&boc, 0);
++
++ #define assert_testIsBufferEmptyOrFull(got, expected) \
++ assert((got) == (expected), \
++ err_msg("Expected: %d, got: %d. testIsBufferEmptyOrFull(%d, %d, %s, %s)", \
++ (got), (expected), num_narrow, num_full, \
++ BOOL_TO_STR(expect_empty), BOOL_TO_STR(expect_full)))
++
++ assert_testIsBufferEmptyOrFull(expect_empty, boc.is_buffer_empty());
++ assert_testIsBufferEmptyOrFull(expect_full, boc.is_buffer_full());
++ }
++
++ static void testIsBufferEmptyOrFull() {
++ int bl = BufferingOopClosure::BufferLength;
++
++ testIsBufferEmptyOrFull(0, 0, true, false);
++ testIsBufferEmptyOrFull(1, 0, false, false);
++ testIsBufferEmptyOrFull(0, 1, false, false);
++ testIsBufferEmptyOrFull(1, 1, false, false);
++ testIsBufferEmptyOrFull(10, 0, false, false);
++ testIsBufferEmptyOrFull(0, 10, false, false);
++ testIsBufferEmptyOrFull(10, 10, false, false);
++ testIsBufferEmptyOrFull(0, bl, false, true);
++ testIsBufferEmptyOrFull(bl, 0, false, true);
++ testIsBufferEmptyOrFull(bl/2, bl/2, false, true);
++ testIsBufferEmptyOrFull(bl-1, 1, false, true);
++ testIsBufferEmptyOrFull(1, bl-1, false, true);
++ // Processed
++ testIsBufferEmptyOrFull(bl+1, 0, false, false);
++ testIsBufferEmptyOrFull(bl*2, 0, false, true);
++ }
++
++ static void testEmptyAfterDone(int num_narrow, int num_full) {
++ FakeRoots fr(num_narrow, num_full);
++
++ DoNothingOopClosure cl;
++ BufferingOopClosure boc(&cl);
++
++ fr.oops_do(&boc, 0);
++
++ // Make sure all get processed.
++ boc.done();
++
++ assert(boc.is_buffer_empty(),
++ err_msg("Should be empty after call to done(). testEmptyAfterDone(%d, %d)",
++ num_narrow, num_full));
++ }
++
++ static void testEmptyAfterDone() {
++ int bl = BufferingOopClosure::BufferLength;
++
++ testEmptyAfterDone(0, 0);
++ testEmptyAfterDone(1, 0);
++ testEmptyAfterDone(0, 1);
++ testEmptyAfterDone(1, 1);
++ testEmptyAfterDone(10, 0);
++ testEmptyAfterDone(0, 10);
++ testEmptyAfterDone(10, 10);
++ testEmptyAfterDone(0, bl);
++ testEmptyAfterDone(bl, 0);
++ testEmptyAfterDone(bl/2, bl/2);
++ testEmptyAfterDone(bl-1, 1);
++ testEmptyAfterDone(1, bl-1);
++ // Processed
++ testEmptyAfterDone(bl+1, 0);
++ testEmptyAfterDone(bl*2, 0);
++ }
++
++ public:
++ static void test() {
++ testCount();
++ testIsBufferEmptyOrFull();
++ testEmptyAfterDone();
++ }
++};
++
++void TestBufferingOopClosure_test() {
++ TestBufferingOopClosure::test();
++}
++
++#endif
+--- ./hotspot/src/share/vm/gc_implementation/g1/bufferingOopClosure.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/bufferingOopClosure.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -25,10 +25,10 @@
+ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP
+
+-#include "memory/genOopClosures.hpp"
+-#include "memory/generation.hpp"
++#include "memory/iterator.hpp"
++#include "oops/oopsHierarchy.hpp"
+ #include "runtime/os.hpp"
+-#include "utilities/taskqueue.hpp"
++#include "utilities/debug.hpp"
+
+ // A BufferingOops closure tries to separate out the cost of finding roots
+ // from the cost of applying closures to them. It maintains an array of
+@@ -41,60 +41,103 @@
+ // The caller must be sure to call "done" to process any unprocessed
+ // buffered entriess.
+
+-class Generation;
+-class HeapRegion;
++class BufferingOopClosure: public OopClosure {
++ friend class TestBufferingOopClosure;
++protected:
++ static const size_t BufferLength = 1024;
+
+-class BufferingOopClosure: public OopClosure {
+-protected:
+- enum PrivateConstants {
+- BufferLength = 1024
+- };
+-
+- StarTask _buffer[BufferLength];
+- StarTask* _buffer_top;
+- StarTask* _buffer_curr;
++ // We need to know if the buffered addresses contain oops or narrowOops.
++ // We can't tag the addresses the way StarTask does, because we need to
++ // be able to handle unaligned addresses coming from oops embedded in code.
++ //
++ // The addresses for the full-sized oops are filled in from the bottom,
++ // while the addresses for the narrowOops are filled in from the top.
++ OopOrNarrowOopStar _buffer[BufferLength];
++ OopOrNarrowOopStar* _oop_top;
++ OopOrNarrowOopStar* _narrowOop_bottom;
+
+ OopClosure* _oc;
+ double _closure_app_seconds;
+
+- void process_buffer () {
++
++ bool is_buffer_empty() {
++ return _oop_top == _buffer && _narrowOop_bottom == (_buffer + BufferLength - 1);
++ }
++
++ bool is_buffer_full() {
++ return _narrowOop_bottom < _oop_top;
++ }
++
++ // Process addresses containing full-sized oops.
++ void process_oops() {
++ for (OopOrNarrowOopStar* curr = _buffer; curr < _oop_top; ++curr) {
++ _oc->do_oop((oop*)(*curr));
++ }
++ _oop_top = _buffer;
++ }
++
++ // Process addresses containing narrow oops.
++ void process_narrowOops() {
++ for (OopOrNarrowOopStar* curr = _buffer + BufferLength - 1; curr > _narrowOop_bottom; --curr) {
++ _oc->do_oop((narrowOop*)(*curr));
++ }
++ _narrowOop_bottom = _buffer + BufferLength - 1;
++ }
++
++ // Apply the closure to all oops and clear the buffer.
++ // Accumulate the time it took.
++ void process_buffer() {
+ double start = os::elapsedTime();
+- for (StarTask* curr = _buffer; curr < _buffer_curr; ++curr) {
+- if (curr->is_narrow()) {
+- assert(UseCompressedOops, "Error");
+- _oc->do_oop((narrowOop*)(*curr));
+- } else {
+- _oc->do_oop((oop*)(*curr));
+- }
+- }
+- _buffer_curr = _buffer;
++
++ process_oops();
++ process_narrowOops();
++
+ _closure_app_seconds += (os::elapsedTime() - start);
+ }
+
+- template <class T> inline void do_oop_work(T* p) {
+- if (_buffer_curr == _buffer_top) {
++ void process_buffer_if_full() {
++ if (is_buffer_full()) {
+ process_buffer();
+ }
+- StarTask new_ref(p);
+- *_buffer_curr = new_ref;
+- ++_buffer_curr;
++ }
++
++ void add_narrowOop(narrowOop* p) {
++ assert(!is_buffer_full(), "Buffer should not be full");
++ *_narrowOop_bottom = (OopOrNarrowOopStar)p;
++ _narrowOop_bottom--;
++ }
++
++ void add_oop(oop* p) {
++ assert(!is_buffer_full(), "Buffer should not be full");
++ *_oop_top = (OopOrNarrowOopStar)p;
++ _oop_top++;
+ }
+
+ public:
+- virtual void do_oop(narrowOop* p) { do_oop_work(p); }
+- virtual void do_oop(oop* p) { do_oop_work(p); }
++ virtual void do_oop(narrowOop* p) {
++ process_buffer_if_full();
++ add_narrowOop(p);
++ }
+
+- void done () {
+- if (_buffer_curr > _buffer) {
++ virtual void do_oop(oop* p) {
++ process_buffer_if_full();
++ add_oop(p);
++ }
++
++ void done() {
++ if (!is_buffer_empty()) {
+ process_buffer();
+ }
+ }
+- double closure_app_seconds () {
++
++ double closure_app_seconds() {
+ return _closure_app_seconds;
+ }
+- BufferingOopClosure (OopClosure *oc) :
++
++ BufferingOopClosure(OopClosure *oc) :
+ _oc(oc),
+- _buffer_curr(_buffer), _buffer_top(_buffer + BufferLength),
++ _oop_top(_buffer),
++ _narrowOop_bottom(_buffer + BufferLength - 1),
+ _closure_app_seconds(0.0) { }
+ };
+
+--- ./hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -29,7 +29,7 @@
+ #include "gc_implementation/g1/g1HotCardCache.hpp"
+ #include "runtime/java.hpp"
+
+-ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h) :
++ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h, CardTableEntryClosure* refine_closure) :
+ _threads(NULL), _n_threads(0),
+ _hot_card_cache(g1h)
+ {
+@@ -61,7 +61,7 @@
+
+ ConcurrentG1RefineThread *next = NULL;
+ for (uint i = _n_threads - 1; i != UINT_MAX; i--) {
+- ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, worker_id_offset, i);
++ ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, refine_closure, worker_id_offset, i);
+ assert(t != NULL, "Conc refine should have been created");
+ if (t->osthread() == NULL) {
+ vm_shutdown_during_initialization("Could not create ConcurrentG1RefineThread");
+@@ -81,8 +81,8 @@
+ }
+ }
+
+-void ConcurrentG1Refine::init() {
+- _hot_card_cache.initialize();
++void ConcurrentG1Refine::init(G1RegionToSpaceMapper* card_counts_storage) {
++ _hot_card_cache.initialize(card_counts_storage);
+ }
+
+ void ConcurrentG1Refine::stop() {
+@@ -128,9 +128,7 @@
+ }
+
+ uint ConcurrentG1Refine::thread_num() {
+- uint n_threads = (G1ConcRefinementThreads > 0) ? G1ConcRefinementThreads
+- : ParallelGCThreads;
+- return MAX2<uint>(n_threads, 1);
++ return G1ConcRefinementThreads;
+ }
+
+ void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const {
+--- ./hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -34,6 +34,7 @@
+ class ConcurrentG1RefineThread;
+ class G1CollectedHeap;
+ class G1HotCardCache;
++class G1RegionToSpaceMapper;
+ class G1RemSet;
+ class DirtyCardQueue;
+
+@@ -71,10 +72,10 @@
+ void reset_threshold_step();
+
+ public:
+- ConcurrentG1Refine(G1CollectedHeap* g1h);
++ ConcurrentG1Refine(G1CollectedHeap* g1h, CardTableEntryClosure* refine_closure);
+ ~ConcurrentG1Refine();
+
+- void init(); // Accomplish some initialization that has to wait.
++ void init(G1RegionToSpaceMapper* card_counts_storage);
+ void stop();
+
+ void reinitialize_threads();
+--- ./hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -33,8 +33,10 @@
+
+ ConcurrentG1RefineThread::
+ ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *next,
++ CardTableEntryClosure* refine_closure,
+ uint worker_id_offset, uint worker_id) :
+ ConcurrentGCThread(),
++ _refine_closure(refine_closure),
+ _worker_id_offset(worker_id_offset),
+ _worker_id(worker_id),
+ _active(false),
+@@ -71,6 +73,7 @@
+ }
+
+ void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
++ SuspendibleThreadSetJoiner sts;
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ G1CollectorPolicy* g1p = g1h->g1_policy();
+ if (g1p->adaptive_young_list_length()) {
+@@ -82,8 +85,8 @@
+
+ // we try to yield every time we visit 10 regions
+ if (regions_visited == 10) {
+- if (_sts.should_yield()) {
+- _sts.yield("G1 refine");
++ if (sts.should_yield()) {
++ sts.yield();
+ // we just abandon the iteration
+ break;
+ }
+@@ -99,9 +102,7 @@
+ DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+ _vtime_start = os::elapsedVTime();
+ while(!_should_terminate) {
+- _sts.join();
+ sample_young_list_rs_lengths();
+- _sts.leave();
+
+ if (os::supports_vtime()) {
+ _vtime_accum = (os::elapsedVTime() - _vtime_start);
+@@ -182,37 +183,37 @@
+ break;
+ }
+
+- _sts.join();
++ {
++ SuspendibleThreadSetJoiner sts;
+
+- do {
+- int curr_buffer_num = (int)dcqs.completed_buffers_num();
+- // If the number of the buffers falls down into the yellow zone,
+- // that means that the transition period after the evacuation pause has ended.
+- if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cg1r()->yellow_zone()) {
+- dcqs.set_completed_queue_padding(0);
++ do {
++ int curr_buffer_num = (int)dcqs.completed_buffers_num();
++ // If the number of the buffers falls down into the yellow zone,
++ // that means that the transition period after the evacuation pause has ended.
++ if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cg1r()->yellow_zone()) {
++ dcqs.set_completed_queue_padding(0);
++ }
++
++ if (_worker_id > 0 && curr_buffer_num <= _deactivation_threshold) {
++ // If the number of the buffer has fallen below our threshold
++ // we should deactivate. The predecessor will reactivate this
++ // thread should the number of the buffers cross the threshold again.
++ deactivate();
++ break;
++ }
++
++ // Check if we need to activate the next thread.
++ if (_next != NULL && !_next->is_active() && curr_buffer_num > _next->_threshold) {
++ _next->activate();
++ }
++ } while (dcqs.apply_closure_to_completed_buffer(_refine_closure, _worker_id + _worker_id_offset, cg1r()->green_zone()));
++
++ // We can exit the loop above while being active if there was a yield request.
++ if (is_active()) {
++ deactivate();
+ }
+-
+- if (_worker_id > 0 && curr_buffer_num <= _deactivation_threshold) {
+- // If the number of the buffer has fallen below our threshold
+- // we should deactivate. The predecessor will reactivate this
+- // thread should the number of the buffers cross the threshold again.
+- deactivate();
+- break;
+- }
+-
+- // Check if we need to activate the next thread.
+- if (_next != NULL && !_next->is_active() && curr_buffer_num > _next->_threshold) {
+- _next->activate();
+- }
+- } while (dcqs.apply_closure_to_completed_buffer(_worker_id + _worker_id_offset, cg1r()->green_zone()));
+-
+- // We can exit the loop above while being active if there was a yield request.
+- if (is_active()) {
+- deactivate();
+ }
+
+- _sts.leave();
+-
+ if (os::supports_vtime()) {
+ _vtime_accum = (os::elapsedVTime() - _vtime_start);
+ } else {
+@@ -223,17 +224,6 @@
+ terminate();
+ }
+
+-
+-void ConcurrentG1RefineThread::yield() {
+- if (G1TraceConcRefinement) {
+- gclog_or_tty->print_cr("G1-Refine-yield");
+- }
+- _sts.yield("G1 refine");
+- if (G1TraceConcRefinement) {
+- gclog_or_tty->print_cr("G1-Refine-yield-end");
+- }
+-}
+-
+ void ConcurrentG1RefineThread::stop() {
+ // it is ok to take late safepoints here, if needed
+ {
+--- ./hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,6 +28,7 @@
+ #include "gc_implementation/shared/concurrentGCThread.hpp"
+
+ // Forward Decl.
++class CardTableEntryClosure;
+ class ConcurrentG1Refine;
+
+ // The G1 Concurrent Refinement Thread (could be several in the future).
+@@ -49,6 +50,9 @@
+ Monitor* _monitor;
+ ConcurrentG1Refine* _cg1r;
+
++ // The closure applied to completed log buffers.
++ CardTableEntryClosure* _refine_closure;
++
+ int _thread_threshold_step;
+ // This thread activation threshold
+ int _threshold;
+@@ -64,13 +68,11 @@
+ void activate();
+ void deactivate();
+
+- // For use by G1CollectedHeap, which is a friend.
+- static SuspendibleThreadSet* sts() { return &_sts; }
+-
+ public:
+ virtual void run();
+ // Constructor
+ ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread* next,
++ CardTableEntryClosure* refine_closure,
+ uint worker_id_offset, uint worker_id);
+
+ void initialize();
+@@ -84,8 +86,6 @@
+
+ ConcurrentG1Refine* cg1r() { return _cg1r; }
+
+- // Yield for GC
+- void yield();
+ // shutdown
+ void stop();
+ };
+--- ./hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -23,7 +23,9 @@
+ */
+
+ #include "precompiled.hpp"
++#include "classfile/metadataOnStackMark.hpp"
+ #include "classfile/symbolTable.hpp"
++#include "code/codeCache.hpp"
+ #include "gc_implementation/g1/concurrentMark.inline.hpp"
+ #include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
+ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+@@ -33,18 +35,21 @@
+ #include "gc_implementation/g1/g1OopClosures.inline.hpp"
+ #include "gc_implementation/g1/g1RemSet.hpp"
+ #include "gc_implementation/g1/heapRegion.inline.hpp"
++#include "gc_implementation/g1/heapRegionManager.inline.hpp"
+ #include "gc_implementation/g1/heapRegionRemSet.hpp"
+-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
++#include "gc_implementation/g1/heapRegionSet.inline.hpp"
+ #include "gc_implementation/shared/vmGCOperations.hpp"
+ #include "gc_implementation/shared/gcTimer.hpp"
+ #include "gc_implementation/shared/gcTrace.hpp"
+ #include "gc_implementation/shared/gcTraceTime.hpp"
++#include "memory/allocation.hpp"
+ #include "memory/genOopClosures.inline.hpp"
+ #include "memory/referencePolicy.hpp"
+ #include "memory/resourceArea.hpp"
+ #include "oops/oop.inline.hpp"
+ #include "runtime/handles.inline.hpp"
+ #include "runtime/java.hpp"
++#include "runtime/prefetch.inline.hpp"
+ #include "services/memTracker.hpp"
+
+ // Concurrent marking bit map wrapper
+@@ -56,8 +61,8 @@
+ _bmWordSize = 0;
+ }
+
+-HeapWord* CMBitMapRO::getNextMarkedWordAddress(HeapWord* addr,
+- HeapWord* limit) const {
++HeapWord* CMBitMapRO::getNextMarkedWordAddress(const HeapWord* addr,
++ const HeapWord* limit) const {
+ // First we must round addr *up* to a possible object boundary.
+ addr = (HeapWord*)align_size_up((intptr_t)addr,
+ HeapWordSize << _shifter);
+@@ -74,8 +79,8 @@
+ return nextAddr;
+ }
+
+-HeapWord* CMBitMapRO::getNextUnmarkedWordAddress(HeapWord* addr,
+- HeapWord* limit) const {
++HeapWord* CMBitMapRO::getNextUnmarkedWordAddress(const HeapWord* addr,
++ const HeapWord* limit) const {
+ size_t addrOffset = heapWordToOffset(addr);
+ if (limit == NULL) {
+ limit = _bmStartWord + _bmWordSize;
+@@ -95,12 +100,12 @@
+ }
+
+ #ifndef PRODUCT
+-bool CMBitMapRO::covers(ReservedSpace heap_rs) const {
++bool CMBitMapRO::covers(MemRegion heap_rs) const {
+ // assert(_bm.map() == _virtual_space.low(), "map inconsistency");
+ assert(((size_t)_bm.size() * ((size_t)1 << _shifter)) == _bmWordSize,
+ "size inconsistency");
+- return _bmStartWord == (HeapWord*)(heap_rs.base()) &&
+- _bmWordSize == heap_rs.size()>>LogHeapWordSize;
++ return _bmStartWord == (HeapWord*)(heap_rs.start()) &&
++ _bmWordSize == heap_rs.word_size();
+ }
+ #endif
+
+@@ -108,33 +113,76 @@
+ _bm.print_on_error(st, prefix);
+ }
+
+-bool CMBitMap::allocate(ReservedSpace heap_rs) {
+- _bmStartWord = (HeapWord*)(heap_rs.base());
+- _bmWordSize = heap_rs.size()/HeapWordSize; // heap_rs.size() is in bytes
+- ReservedSpace brs(ReservedSpace::allocation_align_size_up(
+- (_bmWordSize >> (_shifter + LogBitsPerByte)) + 1));
+- if (!brs.is_reserved()) {
+- warning("ConcurrentMark marking bit map allocation failure");
++size_t CMBitMap::compute_size(size_t heap_size) {
++ return heap_size / mark_distance();
++}
++
++size_t CMBitMap::mark_distance() {
++ return MinObjAlignmentInBytes * BitsPerByte;
++}
++
++void CMBitMap::initialize(MemRegion heap, G1RegionToSpaceMapper* storage) {
++ _bmStartWord = heap.start();
++ _bmWordSize = heap.word_size();
++
++ _bm.set_map((BitMap::bm_word_t*) storage->reserved().start());
++ _bm.set_size(_bmWordSize >> _shifter);
++
++ storage->set_mapping_changed_listener(&_listener);
++}
++
++void CMBitMapMappingChangedListener::on_commit(uint start_region, size_t num_regions, bool zero_filled) {
++ if (zero_filled) {
++ return;
++ }
++ // We need to clear the bitmap on commit, removing any existing information.
++ MemRegion mr(G1CollectedHeap::heap()->bottom_addr_for_region(start_region), num_regions * HeapRegion::GrainWords);
++ _bm->clearRange(mr);
++}
++
++// Closure used for clearing the given mark bitmap.
++class ClearBitmapHRClosure : public HeapRegionClosure {
++ private:
++ ConcurrentMark* _cm;
++ CMBitMap* _bitmap;
++ bool _may_yield; // The closure may yield during iteration. If yielded, abort the iteration.
++ public:
++ ClearBitmapHRClosure(ConcurrentMark* cm, CMBitMap* bitmap, bool may_yield) : HeapRegionClosure(), _cm(cm), _bitmap(bitmap), _may_yield(may_yield) {
++ assert(!may_yield || cm != NULL, "CM must be non-NULL if this closure is expected to yield.");
++ }
++
++ virtual bool doHeapRegion(HeapRegion* r) {
++ size_t const chunk_size_in_words = M / HeapWordSize;
++
++ HeapWord* cur = r->bottom();
++ HeapWord* const end = r->end();
++
++ while (cur < end) {
++ MemRegion mr(cur, MIN2(cur + chunk_size_in_words, end));
++ _bitmap->clearRange(mr);
++
++ cur += chunk_size_in_words;
++
++ // Abort iteration if after yielding the marking has been aborted.
++ if (_may_yield && _cm->do_yield_check() && _cm->has_aborted()) {
++ return true;
++ }
++ // Repeat the asserts from before the start of the closure. We will do them
++ // as asserts here to minimize their overhead on the product. However, we
++ // will have them as guarantees at the beginning / end of the bitmap
++ // clearing to get some checking in the product.
++ assert(!_may_yield || _cm->cmThread()->during_cycle(), "invariant");
++ assert(!_may_yield || !G1CollectedHeap::heap()->mark_in_progress(), "invariant");
++ }
++
+ return false;
+ }
+- MemTracker::record_virtual_memory_type((address)brs.base(), mtGC);
+- // For now we'll just commit all of the bit map up front.
+- // Later on we'll try to be more parsimonious with swap.
+- if (!_virtual_space.initialize(brs, brs.size())) {
+- warning("ConcurrentMark marking bit map backing store failure");
+- return false;
+- }
+- assert(_virtual_space.committed_size() == brs.size(),
+- "didn't reserve backing store for all of concurrent marking bit map?");
+- _bm.set_map((uintptr_t*)_virtual_space.low());
+- assert(_virtual_space.committed_size() << (_shifter + LogBitsPerByte) >=
+- _bmWordSize, "inconsistency in bit map sizing");
+- _bm.set_size(_bmWordSize >> _shifter);
+- return true;
+-}
++};
+
+ void CMBitMap::clearAll() {
+- _bm.clear();
++ ClearBitmapHRClosure cl(NULL, this, false /* may_yield */);
++ G1CollectedHeap::heap()->heap_region_iterate(&cl);
++ guarantee(cl.complete(), "Must have completed iteration.");
+ return;
+ }
+
+@@ -389,10 +437,6 @@
+ }
+ }
+
+-bool ConcurrentMark::not_yet_marked(oop obj) const {
+- return _g1h->is_obj_ill(obj);
+-}
+-
+ CMRootRegions::CMRootRegions() :
+ _young_list(NULL), _cm(NULL), _scan_in_progress(false),
+ _should_abort(false), _next_survivor(NULL) { }
+@@ -479,10 +523,10 @@
+ return MAX2((n_par_threads + 2) / 4, 1U);
+ }
+
+-ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) :
++ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, G1RegionToSpaceMapper* prev_bitmap_storage, G1RegionToSpaceMapper* next_bitmap_storage) :
+ _g1h(g1h),
+- _markBitMap1(log2_intptr(MinObjAlignment)),
+- _markBitMap2(log2_intptr(MinObjAlignment)),
++ _markBitMap1(),
++ _markBitMap2(),
+ _parallel_marking_threads(0),
+ _max_parallel_marking_threads(0),
+ _sleep_factor(0.0),
+@@ -491,7 +535,7 @@
+ _cleanup_task_overhead(1.0),
+ _cleanup_list("Cleanup List"),
+ _region_bm((BitMap::idx_t)(g1h->max_regions()), false /* in_resource_area*/),
+- _card_bm((heap_rs.size() + CardTableModRefBS::card_size - 1) >>
++ _card_bm((g1h->reserved_region().byte_size() + CardTableModRefBS::card_size - 1) >>
+ CardTableModRefBS::card_shift,
+ false /* in_resource_area*/),
+
+@@ -510,6 +554,7 @@
+ _has_overflown(false),
+ _concurrent(false),
+ _has_aborted(false),
++ _aborted_gc_id(GCId::undefined()),
+ _restart_for_overflow(false),
+ _concurrent_marking_in_progress(false),
+
+@@ -540,14 +585,8 @@
+ "heap end = " INTPTR_FORMAT, p2i(_heap_start), p2i(_heap_end));
+ }
+
+- if (!_markBitMap1.allocate(heap_rs)) {
+- warning("Failed to allocate first CM bit map");
+- return;
+- }
+- if (!_markBitMap2.allocate(heap_rs)) {
+- warning("Failed to allocate second CM bit map");
+- return;
+- }
++ _markBitMap1.initialize(g1h->reserved_region(), prev_bitmap_storage);
++ _markBitMap2.initialize(g1h->reserved_region(), next_bitmap_storage);
+
+ // Create & start a ConcurrentMark thread.
+ _cmThread = new ConcurrentMarkThread(this);
+@@ -558,8 +597,8 @@
+ }
+
+ assert(CGC_lock != NULL, "Where's the CGC_lock?");
+- assert(_markBitMap1.covers(heap_rs), "_markBitMap1 inconsistency");
+- assert(_markBitMap2.covers(heap_rs), "_markBitMap2 inconsistency");
++ assert(_markBitMap1.covers(g1h->reserved_region()), "_markBitMap1 inconsistency");
++ assert(_markBitMap2.covers(g1h->reserved_region()), "_markBitMap2 inconsistency");
+
+ SATBMarkQueueSet& satb_qs = JavaThread::satb_mark_queue_set();
+ satb_qs.set_buffer_size(G1SATBBufferSize);
+@@ -719,38 +758,17 @@
+ clear_all_count_data();
+
+ // so that the call below can read a sensible value
+- _heap_start = (HeapWord*) heap_rs.base();
++ _heap_start = g1h->reserved_region().start();
+ set_non_marking_state();
+ _completed_initialization = true;
+ }
+
+-void ConcurrentMark::update_g1_committed(bool force) {
+- // If concurrent marking is not in progress, then we do not need to
+- // update _heap_end.
+- if (!concurrent_marking_in_progress() && !force) return;
+-
+- MemRegion committed = _g1h->g1_committed();
+- assert(committed.start() == _heap_start, "start shouldn't change");
+- HeapWord* new_end = committed.end();
+- if (new_end > _heap_end) {
+- // The heap has been expanded.
+-
+- _heap_end = new_end;
+- }
+- // Notice that the heap can also shrink. However, this only happens
+- // during a Full GC (at least currently) and the entire marking
+- // phase will bail out and the task will not be restarted. So, let's
+- // do nothing.
+-}
+-
+ void ConcurrentMark::reset() {
+ // Starting values for these two. This should be called in a STW
+- // phase. CM will be notified of any future g1_committed expansions
+- // will be at the end of evacuation pauses, when tasks are
+- // inactive.
+- MemRegion committed = _g1h->g1_committed();
+- _heap_start = committed.start();
+- _heap_end = committed.end();
++ // phase.
++ MemRegion reserved = _g1h->g1_reserved();
++ _heap_start = reserved.start();
++ _heap_end = reserved.end();
+
+ // Separated the asserts so that we know which one fires.
+ assert(_heap_start != NULL, "heap bounds should look ok");
+@@ -822,7 +840,6 @@
+ assert(out_of_regions(),
+ err_msg("only way to get here: _finger: "PTR_FORMAT", _heap_end: "PTR_FORMAT,
+ p2i(_finger), p2i(_heap_end)));
+- update_g1_committed(true);
+ }
+ }
+
+@@ -841,7 +858,6 @@
+
+ void ConcurrentMark::clearNextBitmap() {
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+- G1CollectorPolicy* g1p = g1h->g1_policy();
+
+ // Make sure that the concurrent mark thread looks to still be in
+ // the current cycle.
+@@ -853,39 +869,47 @@
+ // is the case.
+ guarantee(!g1h->mark_in_progress(), "invariant");
+
+- // clear the mark bitmap (no grey objects to start with).
+- // We need to do this in chunks and offer to yield in between
+- // each chunk.
+- HeapWord* start = _nextMarkBitMap->startWord();
+- HeapWord* end = _nextMarkBitMap->endWord();
+- HeapWord* cur = start;
+- size_t chunkSize = M;
+- while (cur < end) {
+- HeapWord* next = cur + chunkSize;
+- if (next > end) {
+- next = end;
+- }
+- MemRegion mr(cur,next);
+- _nextMarkBitMap->clearRange(mr);
+- cur = next;
+- do_yield_check();
+-
+- // Repeat the asserts from above. We'll do them as asserts here to
+- // minimize their overhead on the product. However, we'll have
+- // them as guarantees at the beginning / end of the bitmap
+- // clearing to get some checking in the product.
+- assert(cmThread()->during_cycle(), "invariant");
+- assert(!g1h->mark_in_progress(), "invariant");
++ ClearBitmapHRClosure cl(this, _nextMarkBitMap, true /* may_yield */);
++ g1h->heap_region_iterate(&cl);
++
++ // Clear the liveness counting data. If the marking has been aborted, the abort()
++ // call already did that.
++ if (cl.complete()) {
++ clear_all_count_data();
+ }
+
+- // Clear the liveness counting data
+- clear_all_count_data();
+-
+ // Repeat the asserts from above.
+ guarantee(cmThread()->during_cycle(), "invariant");
+ guarantee(!g1h->mark_in_progress(), "invariant");
+ }
+
++class CheckBitmapClearHRClosure : public HeapRegionClosure {
++ CMBitMap* _bitmap;
++ bool _error;
++ public:
++ CheckBitmapClearHRClosure(CMBitMap* bitmap) : _bitmap(bitmap) {
++ }
++
++ virtual bool doHeapRegion(HeapRegion* r) {
++ // This closure can be called concurrently to the mutator, so we must make sure
++ // that the result of the getNextMarkedWordAddress() call is compared to the
++ // value passed to it as limit to detect any found bits.
++ // We can use the region's orig_end() for the limit and the comparison value
++ // as it always contains the "real" end of the region that never changes and
++ // has no side effects.
++ // Due to the latter, there can also be no problem with the compiler generating
++ // reloads of the orig_end() call.
++ HeapWord* end = r->orig_end();
++ return _bitmap->getNextMarkedWordAddress(r->bottom(), end) != end;
++ }
++};
++
++bool ConcurrentMark::nextMarkBitmapIsClear() {
++ CheckBitmapClearHRClosure cl(_nextMarkBitMap);
++ _g1h->heap_region_iterate(&cl);
++ return cl.complete();
++}
++
+ class NoteStartOfMarkHRClosure: public HeapRegionClosure {
+ public:
+ bool doHeapRegion(HeapRegion* r) {
+@@ -976,13 +1000,13 @@
+ }
+
+ if (concurrent()) {
+- ConcurrentGCThread::stsLeave();
++ SuspendibleThreadSet::leave();
+ }
+
+ bool barrier_aborted = !_first_overflow_barrier_sync.enter();
+
+ if (concurrent()) {
+- ConcurrentGCThread::stsJoin();
++ SuspendibleThreadSet::join();
+ }
+ // at this point everyone should have synced up and not be doing any
+ // more work
+@@ -1019,8 +1043,7 @@
+ force_overflow()->update();
+
+ if (G1Log::fine()) {
+- gclog_or_tty->date_stamp(PrintGCDateStamps);
+- gclog_or_tty->stamp(PrintGCTimeStamps);
++ gclog_or_tty->gclog_stamp(concurrent_gc_id());
+ gclog_or_tty->print_cr("[GC concurrent-mark-reset-for-overflow]");
+ }
+ }
+@@ -1036,13 +1059,13 @@
+ }
+
+ if (concurrent()) {
+- ConcurrentGCThread::stsLeave();
++ SuspendibleThreadSet::leave();
+ }
+
+ bool barrier_aborted = !_second_overflow_barrier_sync.enter();
+
+ if (concurrent()) {
+- ConcurrentGCThread::stsJoin();
++ SuspendibleThreadSet::join();
+ }
+ // at this point everything should be re-initialized and ready to go
+
+@@ -1094,7 +1117,7 @@
+
+ double start_vtime = os::elapsedVTime();
+
+- ConcurrentGCThread::stsJoin();
++ SuspendibleThreadSet::join();
+
+ assert(worker_id < _cm->active_tasks(), "invariant");
+ CMTask* the_task = _cm->task(worker_id);
+@@ -1102,46 +1125,32 @@
+ if (!_cm->has_aborted()) {
+ do {
+ double start_vtime_sec = os::elapsedVTime();
+- double start_time_sec = os::elapsedTime();
+ double mark_step_duration_ms = G1ConcMarkStepDurationMillis;
+
+ the_task->do_marking_step(mark_step_duration_ms,
+ true /* do_termination */,
+ false /* is_serial*/);
+
+- double end_time_sec = os::elapsedTime();
+ double end_vtime_sec = os::elapsedVTime();
+ double elapsed_vtime_sec = end_vtime_sec - start_vtime_sec;
+- double elapsed_time_sec = end_time_sec - start_time_sec;
+ _cm->clear_has_overflown();
+
+- bool ret = _cm->do_yield_check(worker_id);
++ _cm->do_yield_check(worker_id);
+
+ jlong sleep_time_ms;
+ if (!_cm->has_aborted() && the_task->has_aborted()) {
+ sleep_time_ms =
+ (jlong) (elapsed_vtime_sec * _cm->sleep_factor() * 1000.0);
+- ConcurrentGCThread::stsLeave();
++ SuspendibleThreadSet::leave();
+ os::sleep(Thread::current(), sleep_time_ms, false);
+- ConcurrentGCThread::stsJoin();
++ SuspendibleThreadSet::join();
+ }
+- double end_time2_sec = os::elapsedTime();
+- double elapsed_time2_sec = end_time2_sec - start_time_sec;
+-
+-#if 0
+- gclog_or_tty->print_cr("CM: elapsed %1.4lf ms, sleep %1.4lf ms, "
+- "overhead %1.4lf",
+- elapsed_vtime_sec * 1000.0, (double) sleep_time_ms,
+- the_task->conc_overhead(os::elapsedTime()) * 8.0);
+- gclog_or_tty->print_cr("elapsed time %1.4lf ms, time 2: %1.4lf ms",
+- elapsed_time_sec * 1000.0, elapsed_time2_sec * 1000.0);
+-#endif
+ } while (!_cm->has_aborted() && the_task->has_aborted());
+ }
+ the_task->record_end_time();
+ guarantee(!the_task->has_aborted() || _cm->has_aborted(), "invariant");
+
+- ConcurrentGCThread::stsLeave();
++ SuspendibleThreadSet::leave();
+
+ double end_vtime = os::elapsedVTime();
+ _cm->update_accum_task_vtime(worker_id, end_vtime - start_vtime);
+@@ -1221,6 +1230,9 @@
+ };
+
+ void ConcurrentMark::scanRootRegions() {
++ // Start of concurrent marking.
++ ClassLoaderDataGraph::clear_claimed_marks();
++
+ // scan_in_progress() will have been set to true only if there was
+ // at least one root region to scan. So, if it's false, we
+ // should not attempt to do any further work.
+@@ -1269,7 +1281,7 @@
+ CMConcurrentMarkingTask markingTask(this, cmThread());
+ if (use_parallel_marking_threads()) {
+ _parallel_workers->set_active_workers((int)active_workers);
+- // Don't set _n_par_threads because it affects MT in proceess_strong_roots()
++ // Don't set _n_par_threads because it affects MT in process_roots()
+ // and the decisions on that MT processing is made elsewhere.
+ assert(_parallel_workers->active_workers() > 0, "Should have been set");
+ _parallel_workers->run_task(&markingTask);
+@@ -1300,6 +1312,7 @@
+ Universe::verify(VerifyOption_G1UsePrevMarking,
+ " VerifyDuringGC:(before)");
+ }
++ g1h->check_bitmaps("Remark Start");
+
+ G1CollectorPolicy* g1p = g1h->g1_policy();
+ g1p->record_concurrent_mark_remark_start();
+@@ -1348,6 +1361,7 @@
+ Universe::verify(VerifyOption_G1UseNextMarking,
+ " VerifyDuringGC:(after)");
+ }
++ g1h->check_bitmaps("Remark End");
+ assert(!restart_for_overflow(), "sanity");
+ // Completely reset the marking state since marking completed
+ set_non_marking_state();
+@@ -1389,7 +1403,7 @@
+ void set_bit_for_region(HeapRegion* hr) {
+ assert(!hr->continuesHumongous(), "should have filtered those out");
+
+- BitMap::idx_t index = (BitMap::idx_t) hr->hrs_index();
++ BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index();
+ if (!hr->startsHumongous()) {
+ // Normal (non-humongous) case: just set the bit.
+ _region_bm->par_at_put(index, true);
+@@ -1577,7 +1591,7 @@
+ if (_verbose) {
+ gclog_or_tty->print_cr("Region %u: marked bytes mismatch: "
+ "expected: " SIZE_FORMAT ", actual: " SIZE_FORMAT,
+- hr->hrs_index(), exp_marked_bytes, act_marked_bytes);
++ hr->hrm_index(), exp_marked_bytes, act_marked_bytes);
+ }
+ failures += 1;
+ }
+@@ -1586,7 +1600,7 @@
+ // (which was just calculated) region bit maps.
+ // We're not OK if the bit in the calculated expected region
+ // bitmap is set and the bit in the actual region bitmap is not.
+- BitMap::idx_t index = (BitMap::idx_t) hr->hrs_index();
++ BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index();
+
+ bool expected = _exp_region_bm->at(index);
+ bool actual = _region_bm->at(index);
+@@ -1594,7 +1608,7 @@
+ if (_verbose) {
+ gclog_or_tty->print_cr("Region %u: region bitmap mismatch: "
+ "expected: %s, actual: %s",
+- hr->hrs_index(),
++ hr->hrm_index(),
+ BOOL_TO_STR(expected), BOOL_TO_STR(actual));
+ }
+ failures += 1;
+@@ -1615,7 +1629,7 @@
+ if (_verbose) {
+ gclog_or_tty->print_cr("Region %u: card bitmap mismatch at " SIZE_FORMAT ": "
+ "expected: %s, actual: %s",
+- hr->hrs_index(), i,
++ hr->hrm_index(), i,
+ BOOL_TO_STR(expected), BOOL_TO_STR(actual));
+ }
+ failures += 1;
+@@ -1997,6 +2011,7 @@
+ Universe::verify(VerifyOption_G1UsePrevMarking,
+ " VerifyDuringGC:(before)");
+ }
++ g1h->check_bitmaps("Cleanup Start");
+
+ G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy();
+ g1p->record_concurrent_mark_cleanup_start();
+@@ -2034,8 +2049,8 @@
+ // that calculated by walking the marking bitmap.
+
+ // Bitmaps to hold expected values
+- BitMap expected_region_bm(_region_bm.size(), false);
+- BitMap expected_card_bm(_card_bm.size(), false);
++ BitMap expected_region_bm(_region_bm.size(), true);
++ BitMap expected_card_bm(_card_bm.size(), true);
+
+ G1ParVerifyFinalCountTask g1_par_verify_task(g1h,
+ &_region_bm,
+@@ -2137,22 +2152,31 @@
+ // Update the soft reference policy with the new heap occupancy.
+ Universe::update_heap_info_at_gc();
+
+- // We need to make this be a "collection" so any collection pause that
+- // races with it goes around and waits for completeCleanup to finish.
+- g1h->increment_total_collections();
+-
+- // We reclaimed old regions so we should calculate the sizes to make
+- // sure we update the old gen/space data.
+- g1h->g1mm()->update_sizes();
+-
+ if (VerifyDuringGC) {
+ HandleMark hm; // handle scope
+ Universe::heap()->prepare_for_verify();
+ Universe::verify(VerifyOption_G1UsePrevMarking,
+ " VerifyDuringGC:(after)");
+ }
++ g1h->check_bitmaps("Cleanup End");
+
+ g1h->verify_region_sets_optional();
++
++ // We need to make this be a "collection" so any collection pause that
++ // races with it goes around and waits for completeCleanup to finish.
++ g1h->increment_total_collections();
++
++ // Clean out dead classes and update Metaspace sizes.
++ if (ClassUnloadingWithConcurrentMark) {
++ ClassLoaderDataGraph::purge();
++ }
++ MetaspaceGC::compute_new_size();
++
++ // We reclaimed old regions so we should calculate the sizes to make
++ // sure we update the old gen/space data.
++ g1h->g1mm()->update_sizes();
++ g1h->allocation_context_stats().update_after_mark();
++
+ g1h->trace_heap_after_concurrent_cycle();
+ }
+
+@@ -2170,10 +2194,10 @@
+ _cleanup_list.length());
+ }
+
+- // Noone else should be accessing the _cleanup_list at this point,
+- // so it's not necessary to take any locks
++ // No one else should be accessing the _cleanup_list at this point,
++ // so it is not necessary to take any locks
+ while (!_cleanup_list.is_empty()) {
+- HeapRegion* hr = _cleanup_list.remove_head();
++ HeapRegion* hr = _cleanup_list.remove_region(true /* from_head */);
+ assert(hr != NULL, "Got NULL from a non-empty list");
+ hr->par_clear();
+ tmp_free_list.add_ordered(hr);
+@@ -2382,6 +2406,8 @@
+ }
+
+ virtual void work(uint worker_id) {
++ ResourceMark rm;
++ HandleMark hm;
+ CMTask* task = _cm->task(worker_id);
+ G1CMIsAliveClosure g1_is_alive(_g1h);
+ G1CMKeepAliveAndDrainClosure g1_par_keep_alive(_cm, task, false /* is_serial */);
+@@ -2439,6 +2465,26 @@
+ _g1h->set_par_threads(0);
+ }
+
++void ConcurrentMark::weakRefsWorkParallelPart(BoolObjectClosure* is_alive, bool purged_classes) {
++ G1CollectedHeap::heap()->parallel_cleaning(is_alive, true, true, purged_classes);
++}
++
++// Helper class to get rid of some boilerplate code.
++class G1RemarkGCTraceTime : public GCTraceTime {
++ static bool doit_and_prepend(bool doit) {
++ if (doit) {
++ gclog_or_tty->put(' ');
++ }
++ return doit;
++ }
++
++ public:
++ G1RemarkGCTraceTime(const char* title, bool doit)
++ : GCTraceTime(title, doit_and_prepend(doit), false, G1CollectedHeap::heap()->gc_timer_cm(),
++ G1CollectedHeap::heap()->concurrent_mark()->concurrent_gc_id()) {
++ }
++};
++
+ void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
+ if (has_overflown()) {
+ // Skip processing the discovered references if we have
+@@ -2464,7 +2510,7 @@
+ if (G1Log::finer()) {
+ gclog_or_tty->put(' ');
+ }
+- GCTraceTime t("GC ref-proc", G1Log::finer(), false, g1h->gc_timer_cm());
++ GCTraceTime t("GC ref-proc", G1Log::finer(), false, g1h->gc_timer_cm(), concurrent_gc_id());
+
+ ReferenceProcessor* rp = g1h->ref_processor_cm();
+
+@@ -2521,7 +2567,8 @@
+ &g1_keep_alive,
+ &g1_drain_mark_stack,
+ executor,
+- g1h->gc_timer_cm());
++ g1h->gc_timer_cm(),
++ concurrent_gc_id());
+ g1h->gc_tracer_cm()->report_gc_reference_stats(stats);
+
+ // The do_oop work routines of the keep_alive and drain_marking_stack
+@@ -2550,9 +2597,41 @@
+ return;
+ }
+
+- g1h->unlink_string_and_symbol_table(&g1_is_alive,
+- /* process_strings */ false, // currently strings are always roots
+- /* process_symbols */ true);
++ assert(_markStack.isEmpty(), "Marking should have completed");
++
++ // Unload Klasses, String, Symbols, Code Cache, etc.
++ {
++ G1RemarkGCTraceTime trace("Unloading", G1Log::finer());
++
++ if (ClassUnloadingWithConcurrentMark) {
++ // Cleaning of klasses depends on correct information from MetadataMarkOnStack. The CodeCache::mark_on_stack
++ // part is too slow to be done serially, so it is handled during the weakRefsWorkParallelPart phase.
++ // Defer the cleaning until we have complete on_stack data.
++ MetadataOnStackMark md_on_stack(false /* Don't visit the code cache at this point */);
++
++ bool purged_classes;
++
++ {
++ G1RemarkGCTraceTime trace("System Dictionary Unloading", G1Log::finest());
++ purged_classes = SystemDictionary::do_unloading(&g1_is_alive, false /* Defer klass cleaning */);
++ }
++
++ {
++ G1RemarkGCTraceTime trace("Parallel Unloading", G1Log::finest());
++ weakRefsWorkParallelPart(&g1_is_alive, purged_classes);
++ }
++
++ {
++ G1RemarkGCTraceTime trace("Deallocate Metadata", G1Log::finest());
++ ClassLoaderDataGraph::free_deallocate_lists();
++ }
++ }
++
++ if (G1StringDedup::is_enabled()) {
++ G1RemarkGCTraceTime trace("String Deduplication Unlink", G1Log::finest());
++ G1StringDedup::unlink(&g1_is_alive);
++ }
++ }
+ }
+
+ void ConcurrentMark::swapMarkBitMaps() {
+@@ -2561,6 +2640,57 @@
+ _nextMarkBitMap = (CMBitMap*) temp;
+ }
+
++class CMObjectClosure;
++
++// Closure for iterating over objects, currently only used for
++// processing SATB buffers.
++class CMObjectClosure : public ObjectClosure {
++private:
++ CMTask* _task;
++
++public:
++ void do_object(oop obj) {
++ _task->deal_with_reference(obj);
++ }
++
++ CMObjectClosure(CMTask* task) : _task(task) { }
++};
++
++class G1RemarkThreadsClosure : public ThreadClosure {
++ CMObjectClosure _cm_obj;
++ G1CMOopClosure _cm_cl;
++ MarkingCodeBlobClosure _code_cl;
++ int _thread_parity;
++ bool _is_par;
++
++ public:
++ G1RemarkThreadsClosure(G1CollectedHeap* g1h, CMTask* task, bool is_par) :
++ _cm_obj(task), _cm_cl(g1h, g1h->concurrent_mark(), task), _code_cl(&_cm_cl, !CodeBlobToOopClosure::FixRelocations),
++ _thread_parity(SharedHeap::heap()->strong_roots_parity()), _is_par(is_par) {}
++
++ void do_thread(Thread* thread) {
++ if (thread->is_Java_thread()) {
++ if (thread->claim_oops_do(_is_par, _thread_parity)) {
++ JavaThread* jt = (JavaThread*)thread;
++
++ // In theory it should not be neccessary to explicitly walk the nmethods to find roots for concurrent marking
++ // however the liveness of oops reachable from nmethods have very complex lifecycles:
++ // * Alive if on the stack of an executing method
++ // * Weakly reachable otherwise
++ // Some objects reachable from nmethods, such as the class loader (or klass_holder) of the receiver should be
++ // live by the SATB invariant but other oops recorded in nmethods may behave differently.
++ jt->nmethods_do(&_code_cl);
++
++ jt->satb_mark_queue().apply_closure_and_empty(&_cm_obj);
++ }
++ } else if (thread->is_VM_thread()) {
++ if (thread->claim_oops_do(_is_par, _thread_parity)) {
++ JavaThread::satb_mark_queue_set().shared_satb_queue()->apply_closure_and_empty(&_cm_obj);
++ }
++ }
++ }
++};
++
+ class CMRemarkTask: public AbstractGangTask {
+ private:
+ ConcurrentMark* _cm;
+@@ -2572,6 +2702,14 @@
+ if (worker_id < _cm->active_tasks()) {
+ CMTask* task = _cm->task(worker_id);
+ task->record_start_time();
++ {
++ ResourceMark rm;
++ HandleMark hm;
++
++ G1RemarkThreadsClosure threads_f(G1CollectedHeap::heap(), task, !_is_serial);
++ Threads::threads_do(&threads_f);
++ }
++
+ do {
+ task->do_marking_step(1000000000.0 /* something very large */,
+ true /* do_termination */,
+@@ -2594,6 +2732,8 @@
+ HandleMark hm;
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+
++ G1RemarkGCTraceTime trace("Finalize Marking", G1Log::finer());
++
+ g1h->ensure_parsability(false);
+
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+@@ -2673,7 +2813,6 @@
+ str = " O";
+ } else {
+ HeapRegion* hr = _g1h->heap_region_containing(obj);
+- guarantee(hr != NULL, "invariant");
+ bool over_tams = _g1h->allocated_since_marking(obj, hr, _vo);
+ bool marked = _g1h->is_marked(obj, _vo);
+
+@@ -2814,11 +2953,6 @@
+ _nextMarkBitMap->clearRange(mr);
+ }
+
+-void ConcurrentMark::clearRangeBothBitmaps(MemRegion mr) {
+- clearRangePrevBitmap(mr);
+- clearRangeNextBitmap(mr);
+-}
+-
+ HeapRegion*
+ ConcurrentMark::claim_region(uint worker_id) {
+ // "checkpoint" the finger
+@@ -2852,22 +2986,25 @@
+ // claim_region() and a humongous object allocation might force us
+ // to do a bit of unnecessary work (due to some unnecessary bitmap
+ // iterations) but it should not introduce and correctness issues.
+- HeapRegion* curr_region = _g1h->heap_region_containing_raw(finger);
+- HeapWord* bottom = curr_region->bottom();
+- HeapWord* end = curr_region->end();
+- HeapWord* limit = curr_region->next_top_at_mark_start();
+-
+- if (verbose_low()) {
+- gclog_or_tty->print_cr("[%u] curr_region = "PTR_FORMAT" "
+- "["PTR_FORMAT", "PTR_FORMAT"), "
+- "limit = "PTR_FORMAT,
+- worker_id, p2i(curr_region), p2i(bottom), p2i(end), p2i(limit));
+- }
++ HeapRegion* curr_region = _g1h->heap_region_containing_raw(finger);
++
++ // Above heap_region_containing_raw may return NULL as we always scan claim
++ // until the end of the heap. In this case, just jump to the next region.
++ HeapWord* end = curr_region != NULL ? curr_region->end() : finger + HeapRegion::GrainWords;
+
+ // Is the gap between reading the finger and doing the CAS too long?
+ HeapWord* res = (HeapWord*) Atomic::cmpxchg_ptr(end, &_finger, finger);
+- if (res == finger) {
++ if (res == finger && curr_region != NULL) {
+ // we succeeded
++ HeapWord* bottom = curr_region->bottom();
++ HeapWord* limit = curr_region->next_top_at_mark_start();
++
++ if (verbose_low()) {
++ gclog_or_tty->print_cr("[%u] curr_region = "PTR_FORMAT" "
++ "["PTR_FORMAT", "PTR_FORMAT"), "
++ "limit = "PTR_FORMAT,
++ worker_id, p2i(curr_region), p2i(bottom), p2i(end), p2i(limit));
++ }
+
+ // notice that _finger == end cannot be guaranteed here since,
+ // someone else might have moved the finger even further
+@@ -2898,10 +3035,17 @@
+ } else {
+ assert(_finger > finger, "the finger should have moved forward");
+ if (verbose_low()) {
+- gclog_or_tty->print_cr("[%u] somebody else moved the finger, "
+- "global finger = "PTR_FORMAT", "
+- "our finger = "PTR_FORMAT,
+- worker_id, p2i(_finger), p2i(finger));
++ if (curr_region == NULL) {
++ gclog_or_tty->print_cr("[%u] found uncommitted region, moving finger, "
++ "global finger = "PTR_FORMAT", "
++ "our finger = "PTR_FORMAT,
++ worker_id, p2i(_finger), p2i(finger));
++ } else {
++ gclog_or_tty->print_cr("[%u] somebody else moved the finger, "
++ "global finger = "PTR_FORMAT", "
++ "our finger = "PTR_FORMAT,
++ worker_id, p2i(_finger), p2i(finger));
++ }
+ }
+
+ // read it again
+@@ -3016,8 +3160,10 @@
+ // happens, heap_region_containing() will return the bottom of the
+ // corresponding starts humongous region and the check below will
+ // not hold any more.
++ // Since we always iterate over all regions, we might get a NULL HeapRegion
++ // here.
+ HeapRegion* global_hr = _g1h->heap_region_containing_raw(global_finger);
+- guarantee(global_finger == global_hr->bottom(),
++ guarantee(global_hr == NULL || global_finger == global_hr->bottom(),
+ err_msg("global finger: "PTR_FORMAT" region: "HR_FORMAT,
+ p2i(global_finger), HR_FORMAT_PARAMS(global_hr)));
+ }
+@@ -3030,7 +3176,7 @@
+ if (task_finger != NULL && task_finger < _heap_end) {
+ // See above note on the global finger verification.
+ HeapRegion* task_hr = _g1h->heap_region_containing_raw(task_finger);
+- guarantee(task_finger == task_hr->bottom() ||
++ guarantee(task_hr == NULL || task_finger == task_hr->bottom() ||
+ !task_hr->in_collection_set(),
+ err_msg("task finger: "PTR_FORMAT" region: "HR_FORMAT,
+ p2i(task_finger), HR_FORMAT_PARAMS(task_hr)));
+@@ -3109,7 +3255,7 @@
+ assert(limit_idx <= end_idx, "or else use atomics");
+
+ // Aggregate the "stripe" in the count data associated with hr.
+- uint hrs_index = hr->hrs_index();
++ uint hrm_index = hr->hrm_index();
+ size_t marked_bytes = 0;
+
+ for (uint i = 0; i < _max_worker_id; i += 1) {
+@@ -3118,7 +3264,7 @@
+
+ // Fetch the marked_bytes in this region for task i and
+ // add it to the running total for this region.
+- marked_bytes += marked_bytes_array[hrs_index];
++ marked_bytes += marked_bytes_array[hrm_index];
+
+ // Now union the bitmaps[0,max_worker_id)[start_idx..limit_idx)
+ // into the global card bitmap.
+@@ -3241,8 +3387,14 @@
+
+ // abandon current marking iteration due to a Full GC
+ void ConcurrentMark::abort() {
+- // Clear all marks to force marking thread to do nothing
++ // Clear all marks in the next bitmap for the next marking cycle. This will allow us to skip the next
++ // concurrent bitmap clearing.
+ _nextMarkBitMap->clearAll();
++
++ // Note we cannot clear the previous marking bitmap here
++ // since VerifyDuringGC verifies the objects marked during
++ // a full GC against the previous bitmap.
++
+ // Clear the liveness counting data
+ clear_all_count_data();
+ // Empty mark stack
+@@ -3252,6 +3404,12 @@
+ }
+ _first_overflow_barrier_sync.abort();
+ _second_overflow_barrier_sync.abort();
++ const GCId& gc_id = _g1h->gc_tracer_cm()->gc_id();
++ if (!gc_id.is_undefined()) {
++ // We can do multiple full GCs before ConcurrentMarkThread::run() gets a chance
++ // to detect that it was aborted. Only keep track of the first GC id that we aborted.
++ _aborted_gc_id = gc_id;
++ }
+ _has_aborted = true;
+
+ SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
+@@ -3266,6 +3424,13 @@
+ _g1h->register_concurrent_cycle_end();
+ }
+
++const GCId& ConcurrentMark::concurrent_gc_id() {
++ if (has_aborted()) {
++ return _aborted_gc_id;
++ }
++ return _g1h->gc_tracer_cm()->gc_id();
++}
++
+ static void print_ms_time_info(const char* prefix, const char* name,
+ NumberSeq& ns) {
+ gclog_or_tty->print_cr("%s%5d %12s: total time = %8.2f s (avg = %8.2f ms).",
+@@ -3322,32 +3487,17 @@
+
+ // We take a break if someone is trying to stop the world.
+ bool ConcurrentMark::do_yield_check(uint worker_id) {
+- if (should_yield()) {
++ if (SuspendibleThreadSet::should_yield()) {
+ if (worker_id == 0) {
+ _g1h->g1_policy()->record_concurrent_pause();
+ }
+- cmThread()->yield();
++ SuspendibleThreadSet::yield();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+-bool ConcurrentMark::should_yield() {
+- return cmThread()->should_yield();
+-}
+-
+-bool ConcurrentMark::containing_card_is_marked(void* p) {
+- size_t offset = pointer_delta(p, _g1h->reserved_region().start(), 1);
+- return _card_bm.at(offset >> CardTableModRefBS::card_shift);
+-}
+-
+-bool ConcurrentMark::containing_cards_are_marked(void* start,
+- void* last) {
+- return containing_card_is_marked(start) &&
+- containing_card_is_marked(last);
+-}
+-
+ #ifndef PRODUCT
+ // for debugging purposes
+ void ConcurrentMark::print_finger() {
+@@ -3410,20 +3560,6 @@
+ }
+ };
+
+-// Closure for iterating over objects, currently only used for
+-// processing SATB buffers.
+-class CMObjectClosure : public ObjectClosure {
+-private:
+- CMTask* _task;
+-
+-public:
+- void do_object(oop obj) {
+- _task->deal_with_reference(obj);
+- }
+-
+- CMObjectClosure(CMTask* task) : _task(task) { }
+-};
+-
+ G1CMOopClosure::G1CMOopClosure(G1CollectedHeap* g1h,
+ ConcurrentMark* cm,
+ CMTask* task)
+@@ -3437,9 +3573,8 @@
+ }
+
+ void CMTask::setup_for_region(HeapRegion* hr) {
+- // Separated the asserts so that we know which one fires.
+ assert(hr != NULL,
+- "claim_region() should have filtered out continues humongous regions");
++ "claim_region() should have filtered out NULL regions");
+ assert(!hr->continuesHumongous(),
+ "claim_region() should have filtered out continues humongous regions");
+
+@@ -3615,7 +3750,7 @@
+
+ if (_cm->verbose_medium()) {
+ gclog_or_tty->print_cr("[%u] regular clock, interval = %1.2lfms, "
+- "scanned = %d%s, refs reached = %d%s",
++ "scanned = "SIZE_FORMAT"%s, refs reached = "SIZE_FORMAT"%s",
+ _worker_id, last_interval_ms,
+ _words_scanned,
+ (_words_scanned >= _words_scanned_limit) ? " (*)" : "",
+@@ -3625,7 +3760,7 @@
+ #endif // _MARKING_STATS_
+
+ // (4) We check whether we should yield. If we have to, then we abort.
+- if (_cm->should_yield()) {
++ if (SuspendibleThreadSet::should_yield()) {
+ // We should yield. To do this we abort the task. The caller is
+ // responsible for yielding.
+ set_has_aborted();
+@@ -3889,15 +4024,6 @@
+ }
+ }
+
+- if (!concurrent() && !has_aborted()) {
+- // We should only do this during remark.
+- if (G1CollectedHeap::use_parallel_gc_threads()) {
+- satb_mq_set.par_iterate_closure_all_threads(_worker_id);
+- } else {
+- satb_mq_set.iterate_closure_all_threads();
+- }
+- }
+-
+ _draining_satb_buffers = false;
+
+ assert(has_aborted() ||
+@@ -4555,7 +4681,6 @@
+ _hum_prev_live_bytes(0), _hum_next_live_bytes(0),
+ _total_remset_bytes(0), _total_strong_code_roots_bytes(0) {
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+- MemRegion g1_committed = g1h->g1_committed();
+ MemRegion g1_reserved = g1h->g1_reserved();
+ double now = os::elapsedTime();
+
+@@ -4563,10 +4688,8 @@
+ _out->cr();
+ _out->print_cr(G1PPRL_LINE_PREFIX" PHASE %s @ %1.3f", phase_name, now);
+ _out->print_cr(G1PPRL_LINE_PREFIX" HEAP"
+- G1PPRL_SUM_ADDR_FORMAT("committed")
+ G1PPRL_SUM_ADDR_FORMAT("reserved")
+ G1PPRL_SUM_BYTE_FORMAT("region-size"),
+- p2i(g1_committed.start()), p2i(g1_committed.end()),
+ p2i(g1_reserved.start()), p2i(g1_reserved.end()),
+ HeapRegion::GrainBytes);
+ _out->print_cr(G1PPRL_LINE_PREFIX);
+@@ -4627,7 +4750,7 @@
+ }
+
+ bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) {
+- const char* type = "";
++ const char* type = r->get_type_str();
+ HeapWord* bottom = r->bottom();
+ HeapWord* end = r->end();
+ size_t capacity_bytes = r->capacity();
+@@ -4638,15 +4761,7 @@
+ size_t remset_bytes = r->rem_set()->mem_size();
+ size_t strong_code_roots_bytes = r->rem_set()->strong_code_roots_mem_size();
+
+- if (r->used() == 0) {
+- type = "FREE";
+- } else if (r->is_survivor()) {
+- type = "SURV";
+- } else if (r->is_young()) {
+- type = "EDEN";
+- } else if (r->startsHumongous()) {
+- type = "HUMS";
+-
++ if (r->startsHumongous()) {
+ assert(_hum_used_bytes == 0 && _hum_capacity_bytes == 0 &&
+ _hum_prev_live_bytes == 0 && _hum_next_live_bytes == 0,
+ "they should have been zeroed after the last time we used them");
+@@ -4659,12 +4774,9 @@
+ &prev_live_bytes, &next_live_bytes);
+ end = bottom + HeapRegion::GrainWords;
+ } else if (r->continuesHumongous()) {
+- type = "HUMC";
+ get_hum_bytes(&used_bytes, &capacity_bytes,
+ &prev_live_bytes, &next_live_bytes);
+ assert(end == bottom + HeapRegion::GrainWords, "invariant");
+- } else {
+- type = "OLD";
+ }
+
+ _total_used_bytes += used_bytes;
+--- ./hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,10 +25,14 @@
+ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_HPP
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_HPP
+
++#include "classfile/javaClasses.hpp"
+ #include "gc_implementation/g1/heapRegionSet.hpp"
++#include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
++#include "gc_implementation/shared/gcId.hpp"
+ #include "utilities/taskqueue.hpp"
+
+ class G1CollectedHeap;
++class CMBitMap;
+ class CMTask;
+ typedef GenericTaskQueue<oop, mtGC> CMTaskQueue;
+ typedef GenericTaskQueueSet<CMTaskQueue, mtGC> CMTaskQueueSet;
+@@ -55,7 +59,6 @@
+ HeapWord* _bmStartWord; // base address of range covered by map
+ size_t _bmWordSize; // map size (in #HeapWords covered)
+ const int _shifter; // map to char or bit
+- VirtualSpace _virtual_space; // underlying the bit map
+ BitMap _bm; // the bit map itself
+
+ public:
+@@ -85,19 +88,19 @@
+ // Return the address corresponding to the next marked bit at or after
+ // "addr", and before "limit", if "limit" is non-NULL. If there is no
+ // such bit, returns "limit" if that is non-NULL, or else "endWord()".
+- HeapWord* getNextMarkedWordAddress(HeapWord* addr,
+- HeapWord* limit = NULL) const;
++ HeapWord* getNextMarkedWordAddress(const HeapWord* addr,
++ const HeapWord* limit = NULL) const;
+ // Return the address corresponding to the next unmarked bit at or after
+ // "addr", and before "limit", if "limit" is non-NULL. If there is no
+ // such bit, returns "limit" if that is non-NULL, or else "endWord()".
+- HeapWord* getNextUnmarkedWordAddress(HeapWord* addr,
+- HeapWord* limit = NULL) const;
++ HeapWord* getNextUnmarkedWordAddress(const HeapWord* addr,
++ const HeapWord* limit = NULL) const;
+
+ // conversion utilities
+ HeapWord* offsetToHeapWord(size_t offset) const {
+ return _bmStartWord + (offset << _shifter);
+ }
+- size_t heapWordToOffset(HeapWord* addr) const {
++ size_t heapWordToOffset(const HeapWord* addr) const {
+ return pointer_delta(addr, _bmStartWord) >> _shifter;
+ }
+ int heapWordDiffToOffsetDiff(size_t diff) const;
+@@ -113,42 +116,41 @@
+ void print_on_error(outputStream* st, const char* prefix) const;
+
+ // debugging
+- NOT_PRODUCT(bool covers(ReservedSpace rs) const;)
++ NOT_PRODUCT(bool covers(MemRegion rs) const;)
++};
++
++class CMBitMapMappingChangedListener : public G1MappingChangedListener {
++ private:
++ CMBitMap* _bm;
++ public:
++ CMBitMapMappingChangedListener() : _bm(NULL) {}
++
++ void set_bitmap(CMBitMap* bm) { _bm = bm; }
++
++ virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled);
+ };
+
+ class CMBitMap : public CMBitMapRO {
++ private:
++ CMBitMapMappingChangedListener _listener;
+
+ public:
+- // constructor
+- CMBitMap(int shifter) :
+- CMBitMapRO(shifter) {}
++ static size_t compute_size(size_t heap_size);
++ // Returns the amount of bytes on the heap between two marks in the bitmap.
++ static size_t mark_distance();
+
+- // Allocates the back store for the marking bitmap
+- bool allocate(ReservedSpace heap_rs);
++ CMBitMap() : CMBitMapRO(LogMinObjAlignment), _listener() { _listener.set_bitmap(this); }
+
+- // write marks
+- void mark(HeapWord* addr) {
+- assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize),
+- "outside underlying space?");
+- _bm.set_bit(heapWordToOffset(addr));
+- }
+- void clear(HeapWord* addr) {
+- assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize),
+- "outside underlying space?");
+- _bm.clear_bit(heapWordToOffset(addr));
+- }
+- bool parMark(HeapWord* addr) {
+- assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize),
+- "outside underlying space?");
+- return _bm.par_set_bit(heapWordToOffset(addr));
+- }
+- bool parClear(HeapWord* addr) {
+- assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize),
+- "outside underlying space?");
+- return _bm.par_clear_bit(heapWordToOffset(addr));
+- }
++ // Initializes the underlying BitMap to cover the given area.
++ void initialize(MemRegion heap, G1RegionToSpaceMapper* storage);
++
++ // Write marks.
++ inline void mark(HeapWord* addr);
++ inline void clear(HeapWord* addr);
++ inline bool parMark(HeapWord* addr);
++ inline bool parClear(HeapWord* addr);
++
+ void markRange(MemRegion mr);
+- void clearAll();
+ void clearRange(MemRegion mr);
+
+ // Starting at the bit corresponding to "addr" (inclusive), find the next
+@@ -159,6 +161,9 @@
+ // the run. If there is no "1" bit at or after "addr", return an empty
+ // MemRegion.
+ MemRegion getAndClearMarkedRegion(HeapWord* addr, HeapWord* end_addr);
++
++ // Clear the whole mark bitmap.
++ void clearAll();
+ };
+
+ // Represents a marking stack used by ConcurrentMarking in the G1 collector.
+@@ -444,6 +449,7 @@
+ volatile bool _concurrent;
+ // set at the end of a Full GC so that marking aborts
+ volatile bool _has_aborted;
++ GCId _aborted_gc_id;
+
+ // used when remark aborts due to an overflow to indicate that
+ // another concurrent marking phase should start
+@@ -474,6 +480,7 @@
+ ForceOverflowSettings _force_overflow_conc;
+ ForceOverflowSettings _force_overflow_stw;
+
++ void weakRefsWorkParallelPart(BoolObjectClosure* is_alive, bool purged_classes);
+ void weakRefsWork(bool clear_all_soft_refs);
+
+ void swapMarkBitMaps();
+@@ -676,7 +683,9 @@
+ return _task_queues->steal(worker_id, hash_seed, obj);
+ }
+
+- ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs);
++ ConcurrentMark(G1CollectedHeap* g1h,
++ G1RegionToSpaceMapper* prev_bitmap_storage,
++ G1RegionToSpaceMapper* next_bitmap_storage);
+ ~ConcurrentMark();
+
+ ConcurrentMarkThread* cmThread() { return _cmThread; }
+@@ -705,8 +714,10 @@
+ // inconsistent) and always passing the size. hr is the region that
+ // contains the object and it's passed optionally from callers who
+ // might already have it (no point in recalculating it).
+- inline void grayRoot(oop obj, size_t word_size,
+- uint worker_id, HeapRegion* hr = NULL);
++ inline void grayRoot(oop obj,
++ size_t word_size,
++ uint worker_id,
++ HeapRegion* hr = NULL);
+
+ // It iterates over the heap and for each object it comes across it
+ // will dump the contents of its reference fields, as well as
+@@ -727,11 +738,16 @@
+ // AND MARKED : indicates that an object is both explicitly and
+ // implicitly live (it should be one or the other, not both)
+ void print_reachable(const char* str,
+- VerifyOption vo, bool all) PRODUCT_RETURN;
++ VerifyOption vo,
++ bool all) PRODUCT_RETURN;
+
+ // Clear the next marking bitmap (will be called concurrently).
+ void clearNextBitmap();
+
++ // Return whether the next mark bitmap has no marks set. To be used for assertions
++ // only. Will not yield to pause requests.
++ bool nextMarkBitmapIsClear();
++
+ // These two do the work that needs to be done before and after the
+ // initial root checkpoint. Since this checkpoint can be done at two
+ // different points (i.e. an explicit pause or piggy-backed on a
+@@ -760,12 +776,11 @@
+ // this carefully!
+ inline void markPrev(oop p);
+
+- // Clears marks for all objects in the given range, for the prev,
+- // next, or both bitmaps. NB: the previous bitmap is usually
++ // Clears marks for all objects in the given range, for the prev or
++ // next bitmaps. NB: the previous bitmap is usually
+ // read-only, so use this carefully!
+ void clearRangePrevBitmap(MemRegion mr);
+ void clearRangeNextBitmap(MemRegion mr);
+- void clearRangeBothBitmaps(MemRegion mr);
+
+ // Notify data structures that a GC has started.
+ void note_start_of_gc() {
+@@ -787,27 +802,6 @@
+ bool verify_thread_buffers,
+ bool verify_fingers) PRODUCT_RETURN;
+
+- // It is called at the end of an evacuation pause during marking so
+- // that CM is notified of where the new end of the heap is. It
+- // doesn't do anything if concurrent_marking_in_progress() is false,
+- // unless the force parameter is true.
+- void update_g1_committed(bool force = false);
+-
+- bool isMarked(oop p) const {
+- assert(p != NULL && p->is_oop(), "expected an oop");
+- HeapWord* addr = (HeapWord*)p;
+- assert(addr >= _nextMarkBitMap->startWord() ||
+- addr < _nextMarkBitMap->endWord(), "in a region");
+-
+- return _nextMarkBitMap->isMarked(addr);
+- }
+-
+- inline bool not_yet_marked(oop p) const;
+-
+- // XXX Debug code
+- bool containing_card_is_marked(void* p);
+- bool containing_cards_are_marked(void* start, void* last);
+-
+ bool isPrevMarked(oop p) const {
+ assert(p != NULL && p->is_oop(), "expected an oop");
+ HeapWord* addr = (HeapWord*)p;
+@@ -818,13 +812,14 @@
+ }
+
+ inline bool do_yield_check(uint worker_i = 0);
+- inline bool should_yield();
+
+ // Called to abort the marking cycle after a Full GC takes palce.
+ void abort();
+
+ bool has_aborted() { return _has_aborted; }
+
++ const GCId& concurrent_gc_id();
++
+ // This prints the global/local fingers. It is used for debugging.
+ NOT_PRODUCT(void print_finger();)
+
+@@ -892,7 +887,8 @@
+ // marked_bytes array slot for the given HeapRegion.
+ // Sets the bits in the given card bitmap that are associated with the
+ // cards that are spanned by the memory region.
+- inline void count_region(MemRegion mr, HeapRegion* hr,
++ inline void count_region(MemRegion mr,
++ HeapRegion* hr,
+ size_t* marked_bytes_array,
+ BitMap* task_card_bm);
+
+@@ -900,56 +896,27 @@
+ // data structures for the given worker id.
+ inline void count_region(MemRegion mr, HeapRegion* hr, uint worker_id);
+
+- // Counts the given memory region in the task/worker counting
+- // data structures for the given worker id.
+- inline void count_region(MemRegion mr, uint worker_id);
+-
+ // Counts the given object in the given task/worker counting
+ // data structures.
+- inline void count_object(oop obj, HeapRegion* hr,
++ inline void count_object(oop obj,
++ HeapRegion* hr,
+ size_t* marked_bytes_array,
+ BitMap* task_card_bm);
+
+- // Counts the given object in the task/worker counting data
+- // structures for the given worker id.
+- inline void count_object(oop obj, HeapRegion* hr, uint worker_id);
+-
+ // Attempts to mark the given object and, if successful, counts
+ // the object in the given task/worker counting structures.
+- inline bool par_mark_and_count(oop obj, HeapRegion* hr,
++ inline bool par_mark_and_count(oop obj,
++ HeapRegion* hr,
+ size_t* marked_bytes_array,
+ BitMap* task_card_bm);
+
+ // Attempts to mark the given object and, if successful, counts
+ // the object in the task/worker counting structures for the
+ // given worker id.
+- inline bool par_mark_and_count(oop obj, size_t word_size,
+- HeapRegion* hr, uint worker_id);
+-
+- // Attempts to mark the given object and, if successful, counts
+- // the object in the task/worker counting structures for the
+- // given worker id.
+- inline bool par_mark_and_count(oop obj, HeapRegion* hr, uint worker_id);
+-
+- // Similar to the above routine but we don't know the heap region that
+- // contains the object to be marked/counted, which this routine looks up.
+- inline bool par_mark_and_count(oop obj, uint worker_id);
+-
+- // Similar to the above routine but there are times when we cannot
+- // safely calculate the size of obj due to races and we, therefore,
+- // pass the size in as a parameter. It is the caller's reponsibility
+- // to ensure that the size passed in for obj is valid.
+- inline bool par_mark_and_count(oop obj, size_t word_size, uint worker_id);
+-
+- // Unconditionally mark the given object, and unconditinally count
+- // the object in the counting structures for worker id 0.
+- // Should *not* be called from parallel code.
+- inline bool mark_and_count(oop obj, HeapRegion* hr);
+-
+- // Similar to the above routine but we don't know the heap region that
+- // contains the object to be marked/counted, which this routine looks up.
+- // Should *not* be called from parallel code.
+- inline bool mark_and_count(oop obj);
++ inline bool par_mark_and_count(oop obj,
++ size_t word_size,
++ HeapRegion* hr,
++ uint worker_id);
+
+ // Returns true if initialization was successfully completed.
+ bool completed_initialization() const {
+@@ -1221,9 +1188,12 @@
+ _finger = new_finger;
+ }
+
+- CMTask(uint worker_id, ConcurrentMark *cm,
+- size_t* marked_bytes, BitMap* card_bm,
+- CMTaskQueue* task_queue, CMTaskQueueSet* task_queues);
++ CMTask(uint worker_id,
++ ConcurrentMark *cm,
++ size_t* marked_bytes,
++ BitMap* card_bm,
++ CMTaskQueue* task_queue,
++ CMTaskQueueSet* task_queues);
+
+ // it prints statistics associated with this task
+ void print_stats();
+--- ./hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -86,7 +86,7 @@
+ HeapWord* start = mr.start();
+ HeapWord* end = mr.end();
+ size_t region_size_bytes = mr.byte_size();
+- uint index = hr->hrs_index();
++ uint index = hr->hrm_index();
+
+ assert(!hr->continuesHumongous(), "should not be HC region");
+ assert(hr == g1h->heap_region_containing(start), "sanity");
+@@ -125,14 +125,6 @@
+ count_region(mr, hr, marked_bytes_array, task_card_bm);
+ }
+
+-// Counts the given memory region, which may be a single object, in the
+-// task/worker counting data structures for the given worker id.
+-inline void ConcurrentMark::count_region(MemRegion mr, uint worker_id) {
+- HeapWord* addr = mr.start();
+- HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
+- count_region(mr, hr, worker_id);
+-}
+-
+ // Counts the given object in the given task/worker counting data structures.
+ inline void ConcurrentMark::count_object(oop obj,
+ HeapRegion* hr,
+@@ -142,17 +134,6 @@
+ count_region(mr, hr, marked_bytes_array, task_card_bm);
+ }
+
+-// Counts the given object in the task/worker counting data
+-// structures for the given worker id.
+-inline void ConcurrentMark::count_object(oop obj,
+- HeapRegion* hr,
+- uint worker_id) {
+- size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
+- BitMap* task_card_bm = count_card_bitmap_for(worker_id);
+- HeapWord* addr = (HeapWord*) obj;
+- count_object(obj, hr, marked_bytes_array, task_card_bm);
+-}
+-
+ // Attempts to mark the given object and, if successful, counts
+ // the object in the given task/worker counting structures.
+ inline bool ConcurrentMark::par_mark_and_count(oop obj,
+@@ -184,63 +165,6 @@
+ return false;
+ }
+
+-// Attempts to mark the given object and, if successful, counts
+-// the object in the task/worker counting structures for the
+-// given worker id.
+-inline bool ConcurrentMark::par_mark_and_count(oop obj,
+- HeapRegion* hr,
+- uint worker_id) {
+- HeapWord* addr = (HeapWord*)obj;
+- if (_nextMarkBitMap->parMark(addr)) {
+- // Update the task specific count data for the object.
+- count_object(obj, hr, worker_id);
+- return true;
+- }
+- return false;
+-}
+-
+-// As above - but we don't know the heap region containing the
+-// object and so have to supply it.
+-inline bool ConcurrentMark::par_mark_and_count(oop obj, uint worker_id) {
+- HeapWord* addr = (HeapWord*)obj;
+- HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
+- return par_mark_and_count(obj, hr, worker_id);
+-}
+-
+-// Similar to the above routine but we already know the size, in words, of
+-// the object that we wish to mark/count
+-inline bool ConcurrentMark::par_mark_and_count(oop obj,
+- size_t word_size,
+- uint worker_id) {
+- HeapWord* addr = (HeapWord*)obj;
+- if (_nextMarkBitMap->parMark(addr)) {
+- // Update the task specific count data for the object.
+- MemRegion mr(addr, word_size);
+- count_region(mr, worker_id);
+- return true;
+- }
+- return false;
+-}
+-
+-// Unconditionally mark the given object, and unconditinally count
+-// the object in the counting structures for worker id 0.
+-// Should *not* be called from parallel code.
+-inline bool ConcurrentMark::mark_and_count(oop obj, HeapRegion* hr) {
+- HeapWord* addr = (HeapWord*)obj;
+- _nextMarkBitMap->mark(addr);
+- // Update the task specific count data for the object.
+- count_object(obj, hr, 0 /* worker_id */);
+- return true;
+-}
+-
+-// As above - but we don't have the heap region containing the
+-// object, so we have to supply it.
+-inline bool ConcurrentMark::mark_and_count(oop obj) {
+- HeapWord* addr = (HeapWord*)obj;
+- HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
+- return mark_and_count(obj, hr);
+-}
+-
+ inline bool CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
+ HeapWord* start_addr = MAX2(startWord(), mr.start());
+ HeapWord* end_addr = MIN2(endWord(), mr.end());
+@@ -268,6 +192,36 @@
+ return iterate(cl, mr);
+ }
+
++#define check_mark(addr) \
++ assert(_bmStartWord <= (addr) && (addr) < (_bmStartWord + _bmWordSize), \
++ "outside underlying space?"); \
++ assert(G1CollectedHeap::heap()->is_in_exact(addr), \
++ err_msg("Trying to access not available bitmap "PTR_FORMAT \
++ " corresponding to "PTR_FORMAT" (%u)", \
++ p2i(this), p2i(addr), G1CollectedHeap::heap()->addr_to_region(addr)));
++
++inline void CMBitMap::mark(HeapWord* addr) {
++ check_mark(addr);
++ _bm.set_bit(heapWordToOffset(addr));
++}
++
++inline void CMBitMap::clear(HeapWord* addr) {
++ check_mark(addr);
++ _bm.clear_bit(heapWordToOffset(addr));
++}
++
++inline bool CMBitMap::parMark(HeapWord* addr) {
++ check_mark(addr);
++ return _bm.par_set_bit(heapWordToOffset(addr));
++}
++
++inline bool CMBitMap::parClear(HeapWord* addr) {
++ check_mark(addr);
++ return _bm.par_clear_bit(heapWordToOffset(addr));
++}
++
++#undef check_mark
++
+ inline void CMTask::push(oop obj) {
+ HeapWord* objAddr = (HeapWord*) obj;
+ assert(_g1h->is_in_g1_reserved(objAddr), "invariant");
+--- ./hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,4 +1,4 @@
+-/*
++ /*
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+@@ -29,6 +29,7 @@
+ #include "gc_implementation/g1/g1Log.hpp"
+ #include "gc_implementation/g1/g1MMUTracker.hpp"
+ #include "gc_implementation/g1/vm_operations_g1.hpp"
++#include "gc_implementation/shared/gcTrace.hpp"
+ #include "memory/resourceArea.hpp"
+ #include "runtime/vmThread.hpp"
+
+@@ -109,8 +110,7 @@
+ double scan_start = os::elapsedTime();
+ if (!cm()->has_aborted()) {
+ if (G1Log::fine()) {
+- gclog_or_tty->date_stamp(PrintGCDateStamps);
+- gclog_or_tty->stamp(PrintGCTimeStamps);
++ gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id());
+ gclog_or_tty->print_cr("[GC concurrent-root-region-scan-start]");
+ }
+
+@@ -118,8 +118,7 @@
+
+ double scan_end = os::elapsedTime();
+ if (G1Log::fine()) {
+- gclog_or_tty->date_stamp(PrintGCDateStamps);
+- gclog_or_tty->stamp(PrintGCTimeStamps);
++ gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id());
+ gclog_or_tty->print_cr("[GC concurrent-root-region-scan-end, %1.7lf secs]",
+ scan_end - scan_start);
+ }
+@@ -127,8 +126,7 @@
+
+ double mark_start_sec = os::elapsedTime();
+ if (G1Log::fine()) {
+- gclog_or_tty->date_stamp(PrintGCDateStamps);
+- gclog_or_tty->stamp(PrintGCTimeStamps);
++ gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id());
+ gclog_or_tty->print_cr("[GC concurrent-mark-start]");
+ }
+
+@@ -151,8 +149,7 @@
+ }
+
+ if (G1Log::fine()) {
+- gclog_or_tty->date_stamp(PrintGCDateStamps);
+- gclog_or_tty->stamp(PrintGCTimeStamps);
++ gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id());
+ gclog_or_tty->print_cr("[GC concurrent-mark-end, %1.7lf secs]",
+ mark_end_sec - mark_start_sec);
+ }
+@@ -167,8 +164,7 @@
+ "in remark (restart #%d).", iter);
+ }
+ if (G1Log::fine()) {
+- gclog_or_tty->date_stamp(PrintGCDateStamps);
+- gclog_or_tty->stamp(PrintGCTimeStamps);
++ gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id());
+ gclog_or_tty->print_cr("[GC concurrent-mark-restart-for-overflow]");
+ }
+ }
+@@ -194,9 +190,8 @@
+ } else {
+ // We don't want to update the marking status if a GC pause
+ // is already underway.
+- _sts.join();
++ SuspendibleThreadSetJoiner sts;
+ g1h->set_marking_complete();
+- _sts.leave();
+ }
+
+ // Check if cleanup set the free_regions_coming flag. If it
+@@ -212,8 +207,7 @@
+
+ double cleanup_start_sec = os::elapsedTime();
+ if (G1Log::fine()) {
+- gclog_or_tty->date_stamp(PrintGCDateStamps);
+- gclog_or_tty->stamp(PrintGCTimeStamps);
++ gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id());
+ gclog_or_tty->print_cr("[GC concurrent-cleanup-start]");
+ }
+
+@@ -233,8 +227,7 @@
+
+ double cleanup_end_sec = os::elapsedTime();
+ if (G1Log::fine()) {
+- gclog_or_tty->date_stamp(PrintGCDateStamps);
+- gclog_or_tty->stamp(PrintGCTimeStamps);
++ gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id());
+ gclog_or_tty->print_cr("[GC concurrent-cleanup-end, %1.7lf secs]",
+ cleanup_end_sec - cleanup_start_sec);
+ }
+@@ -266,46 +259,47 @@
+ // record_concurrent_mark_cleanup_completed() (and, in fact, it's
+ // not needed any more as the concurrent mark state has been
+ // already reset).
+- _sts.join();
+- if (!cm()->has_aborted()) {
+- g1_policy->record_concurrent_mark_cleanup_completed();
++ {
++ SuspendibleThreadSetJoiner sts;
++ if (!cm()->has_aborted()) {
++ g1_policy->record_concurrent_mark_cleanup_completed();
++ }
+ }
+- _sts.leave();
+
+ if (cm()->has_aborted()) {
+ if (G1Log::fine()) {
+- gclog_or_tty->date_stamp(PrintGCDateStamps);
+- gclog_or_tty->stamp(PrintGCTimeStamps);
++ gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id());
+ gclog_or_tty->print_cr("[GC concurrent-mark-abort]");
+ }
+ }
+
+ // We now want to allow clearing of the marking bitmap to be
+ // suspended by a collection pause.
+- _sts.join();
+- _cm->clearNextBitmap();
+- _sts.leave();
++ // We may have aborted just before the remark. Do not bother clearing the
++ // bitmap then, as it has been done during mark abort.
++ if (!cm()->has_aborted()) {
++ SuspendibleThreadSetJoiner sts;
++ _cm->clearNextBitmap();
++ } else {
++ assert(!G1VerifyBitmaps || _cm->nextMarkBitmapIsClear(), "Next mark bitmap must be clear");
++ }
+ }
+
+ // Update the number of full collections that have been
+ // completed. This will also notify the FullGCCount_lock in case a
+ // Java thread is waiting for a full GC to happen (e.g., it
+ // called System.gc() with +ExplicitGCInvokesConcurrent).
+- _sts.join();
+- g1h->increment_old_marking_cycles_completed(true /* concurrent */);
+- g1h->register_concurrent_cycle_end();
+- _sts.leave();
++ {
++ SuspendibleThreadSetJoiner sts;
++ g1h->increment_old_marking_cycles_completed(true /* concurrent */);
++ g1h->register_concurrent_cycle_end();
++ }
+ }
+ assert(_should_terminate, "just checking");
+
+ terminate();
+ }
+
+-
+-void ConcurrentMarkThread::yield() {
+- _sts.yield("Concurrent Mark");
+-}
+-
+ void ConcurrentMarkThread::stop() {
+ {
+ MutexLockerEx ml(Terminator_lock);
+--- ./hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -89,9 +89,6 @@
+ // that started() is set and set in_progress().
+ bool during_cycle() { return started() || in_progress(); }
+
+- // Yield for GC
+- void yield();
+-
+ // shutdown
+ void stop();
+ };
+--- ./hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -70,7 +70,7 @@
+
+ DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
+ PtrQueueSet(notify_when_complete),
+- _closure(NULL),
++ _mut_process_closure(NULL),
+ _shared_dirty_card_queue(this, true /*perm*/),
+ _free_ids(NULL),
+ _processed_buffers_mut(0), _processed_buffers_rs_thread(0)
+@@ -83,10 +83,11 @@
+ return (uint)os::processor_count();
+ }
+
+-void DirtyCardQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
++void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock,
+ int process_completed_threshold,
+ int max_completed_queue,
+ Mutex* lock, PtrQueueSet* fl_owner) {
++ _mut_process_closure = cl;
+ PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold,
+ max_completed_queue, fl_owner);
+ set_buffer_size(G1UpdateBufferSize);
+@@ -98,18 +99,15 @@
+ t->dirty_card_queue().handle_zero_index();
+ }
+
+-void DirtyCardQueueSet::set_closure(CardTableEntryClosure* closure) {
+- _closure = closure;
+-}
+-
+-void DirtyCardQueueSet::iterate_closure_all_threads(bool consume,
++void DirtyCardQueueSet::iterate_closure_all_threads(CardTableEntryClosure* cl,
++ bool consume,
+ uint worker_i) {
+ assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
+ for(JavaThread* t = Threads::first(); t; t = t->next()) {
+- bool b = t->dirty_card_queue().apply_closure(_closure, consume);
++ bool b = t->dirty_card_queue().apply_closure(cl, consume);
+ guarantee(b, "Should not be interrupted.");
+ }
+- bool b = shared_dirty_card_queue()->apply_closure(_closure,
++ bool b = shared_dirty_card_queue()->apply_closure(cl,
+ consume,
+ worker_i);
+ guarantee(b, "Should not be interrupted.");
+@@ -143,7 +141,7 @@
+
+ bool b = false;
+ if (worker_i != UINT_MAX) {
+- b = DirtyCardQueue::apply_closure_to_buffer(_closure, buf, 0,
++ b = DirtyCardQueue::apply_closure_to_buffer(_mut_process_closure, buf, 0,
+ _sz, true, worker_i);
+ if (b) Atomic::inc(&_processed_buffers_mut);
+
+@@ -218,18 +216,11 @@
+ return res;
+ }
+
+-bool DirtyCardQueueSet::apply_closure_to_completed_buffer(uint worker_i,
+- int stop_at,
+- bool during_pause) {
+- return apply_closure_to_completed_buffer(_closure, worker_i,
+- stop_at, during_pause);
+-}
+-
+-void DirtyCardQueueSet::apply_closure_to_all_completed_buffers() {
++void DirtyCardQueueSet::apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl) {
+ BufferNode* nd = _completed_buffers_head;
+ while (nd != NULL) {
+ bool b =
+- DirtyCardQueue::apply_closure_to_buffer(_closure,
++ DirtyCardQueue::apply_closure_to_buffer(cl,
+ BufferNode::make_buffer_from_node(nd),
+ 0, _sz, false);
+ guarantee(b, "Should not stop early.");
+@@ -237,6 +228,24 @@
+ }
+ }
+
++void DirtyCardQueueSet::par_apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl) {
++ BufferNode* nd = _cur_par_buffer_node;
++ while (nd != NULL) {
++ BufferNode* next = (BufferNode*)nd->next();
++ BufferNode* actual = (BufferNode*)Atomic::cmpxchg_ptr((void*)next, (volatile void*)&_cur_par_buffer_node, (void*)nd);
++ if (actual == nd) {
++ bool b =
++ DirtyCardQueue::apply_closure_to_buffer(cl,
++ BufferNode::make_buffer_from_node(actual),
++ 0, _sz, false);
++ guarantee(b, "Should not stop early.");
++ nd = next;
++ } else {
++ nd = actual;
++ }
++ }
++}
++
+ // Deallocates any completed log buffers
+ void DirtyCardQueueSet::clear() {
+ BufferNode* buffers_to_delete = NULL;
+--- ./hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -80,7 +80,8 @@
+
+
+ class DirtyCardQueueSet: public PtrQueueSet {
+- CardTableEntryClosure* _closure;
++ // The closure used in mut_process_buffer().
++ CardTableEntryClosure* _mut_process_closure;
+
+ DirtyCardQueue _shared_dirty_card_queue;
+
+@@ -95,10 +96,12 @@
+ jint _processed_buffers_mut;
+ jint _processed_buffers_rs_thread;
+
++ // Current buffer node used for parallel iteration.
++ BufferNode* volatile _cur_par_buffer_node;
+ public:
+ DirtyCardQueueSet(bool notify_when_complete = true);
+
+- void initialize(Monitor* cbl_mon, Mutex* fl_lock,
++ void initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock,
+ int process_completed_threshold,
+ int max_completed_queue,
+ Mutex* lock, PtrQueueSet* fl_owner = NULL);
+@@ -109,33 +112,15 @@
+
+ static void handle_zero_index_for_thread(JavaThread* t);
+
+- // Register "blk" as "the closure" for all queues. Only one such closure
+- // is allowed. The "apply_closure_to_completed_buffer" method will apply
+- // this closure to a completed buffer, and "iterate_closure_all_threads"
+- // applies it to partially-filled buffers (the latter should only be done
+- // with the world stopped).
+- void set_closure(CardTableEntryClosure* closure);
+-
+- // If there is a registered closure for buffers, apply it to all entries
+- // in all currently-active buffers. This should only be applied at a
+- // safepoint. (Currently must not be called in parallel; this should
+- // change in the future.) If "consume" is true, processed entries are
+- // discarded.
+- void iterate_closure_all_threads(bool consume = true,
++ // Apply the given closure to all entries in all currently-active buffers.
++ // This should only be applied at a safepoint. (Currently must not be called
++ // in parallel; this should change in the future.) If "consume" is true,
++ // processed entries are discarded.
++ void iterate_closure_all_threads(CardTableEntryClosure* cl,
++ bool consume = true,
+ uint worker_i = 0);
+
+ // If there exists some completed buffer, pop it, then apply the
+- // registered closure to all its elements, nulling out those elements
+- // processed. If all elements are processed, returns "true". If no
+- // completed buffers exist, returns false. If a completed buffer exists,
+- // but is only partially completed before a "yield" happens, the
+- // partially completed buffer (with its processed elements set to NULL)
+- // is returned to the completed buffer set, and this call returns false.
+- bool apply_closure_to_completed_buffer(uint worker_i = 0,
+- int stop_at = 0,
+- bool during_pause = false);
+-
+- // If there exists some completed buffer, pop it, then apply the
+ // specified closure to all its elements, nulling out those elements
+ // processed. If all elements are processed, returns "true". If no
+ // completed buffers exist, returns false. If a completed buffer exists,
+@@ -156,7 +141,12 @@
+
+ // Applies the current closure to all completed buffers,
+ // non-consumptively.
+- void apply_closure_to_all_completed_buffers();
++ void apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl);
++
++ void reset_for_par_iteration() { _cur_par_buffer_node = _completed_buffers_head; }
++ // Applies the current closure to all completed buffers, non-consumptively.
++ // Parallel version.
++ void par_apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl);
+
+ DirtyCardQueue* shared_dirty_card_queue() {
+ return &_shared_dirty_card_queue;
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,6 +25,7 @@
+ #include "precompiled.hpp"
+ #include "gc_implementation/g1/g1AllocRegion.inline.hpp"
+ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+
+ G1CollectedHeap* G1AllocRegion::_g1h = NULL;
+ HeapRegion* G1AllocRegion::_dummy_region = NULL;
+@@ -128,8 +129,7 @@
+ // Note that we first perform the allocation and then we store the
+ // region in _alloc_region. This is the reason why an active region
+ // can never be empty.
+- _alloc_region = new_alloc_region;
+- _count += 1;
++ update_alloc_region(new_alloc_region);
+ trace("region allocation successful");
+ return result;
+ } else {
+@@ -171,6 +171,19 @@
+ trace("set");
+ }
+
++void G1AllocRegion::update_alloc_region(HeapRegion* alloc_region) {
++ trace("update");
++ // We explicitly check that the region is not empty to make sure we
++ // maintain the "the alloc region cannot be empty" invariant.
++ assert(alloc_region != NULL && !alloc_region->is_empty(),
++ ar_ext_msg(this, "pre-condition"));
++
++ _alloc_region = alloc_region;
++ _alloc_region->set_allocation_context(allocation_context());
++ _count += 1;
++ trace("updated");
++}
++
+ HeapRegion* G1AllocRegion::release() {
+ trace("releasing");
+ HeapRegion* alloc_region = _alloc_region;
+@@ -224,5 +237,70 @@
+ G1AllocRegion::G1AllocRegion(const char* name,
+ bool bot_updates)
+ : _name(name), _bot_updates(bot_updates),
+- _alloc_region(NULL), _count(0), _used_bytes_before(0) { }
++ _alloc_region(NULL), _count(0), _used_bytes_before(0),
++ _allocation_context(AllocationContext::system()) { }
+
++
++HeapRegion* MutatorAllocRegion::allocate_new_region(size_t word_size,
++ bool force) {
++ return _g1h->new_mutator_alloc_region(word_size, force);
++}
++
++void MutatorAllocRegion::retire_region(HeapRegion* alloc_region,
++ size_t allocated_bytes) {
++ _g1h->retire_mutator_alloc_region(alloc_region, allocated_bytes);
++}
++
++HeapRegion* SurvivorGCAllocRegion::allocate_new_region(size_t word_size,
++ bool force) {
++ assert(!force, "not supported for GC alloc regions");
++ return _g1h->new_gc_alloc_region(word_size, count(), GCAllocForSurvived);
++}
++
++void SurvivorGCAllocRegion::retire_region(HeapRegion* alloc_region,
++ size_t allocated_bytes) {
++ _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes,
++ GCAllocForSurvived);
++}
++
++HeapRegion* OldGCAllocRegion::allocate_new_region(size_t word_size,
++ bool force) {
++ assert(!force, "not supported for GC alloc regions");
++ return _g1h->new_gc_alloc_region(word_size, count(), GCAllocForTenured);
++}
++
++void OldGCAllocRegion::retire_region(HeapRegion* alloc_region,
++ size_t allocated_bytes) {
++ _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes,
++ GCAllocForTenured);
++}
++
++HeapRegion* OldGCAllocRegion::release() {
++ HeapRegion* cur = get();
++ if (cur != NULL) {
++ // Determine how far we are from the next card boundary. If it is smaller than
++ // the minimum object size we can allocate into, expand into the next card.
++ HeapWord* top = cur->top();
++ HeapWord* aligned_top = (HeapWord*)align_ptr_up(top, G1BlockOffsetSharedArray::N_bytes);
++
++ size_t to_allocate_words = pointer_delta(aligned_top, top, HeapWordSize);
++
++ if (to_allocate_words != 0) {
++ // We are not at a card boundary. Fill up, possibly into the next, taking the
++ // end of the region and the minimum object size into account.
++ to_allocate_words = MIN2(pointer_delta(cur->end(), cur->top(), HeapWordSize),
++ MAX2(to_allocate_words, G1CollectedHeap::min_fill_size()));
++
++ // Skip allocation if there is not enough space to allocate even the smallest
++ // possible object. In this case this region will not be retained, so the
++ // original problem cannot occur.
++ if (to_allocate_words >= G1CollectedHeap::min_fill_size()) {
++ HeapWord* dummy = attempt_allocation(to_allocate_words, true /* bot_updates */);
++ CollectedHeap::fill_with_object(dummy, to_allocate_words);
++ }
++ }
++ }
++ return G1AllocRegion::release();
++}
++
++
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -57,6 +57,9 @@
+ // correct use of init() and release()).
+ HeapRegion* volatile _alloc_region;
+
++ // Allocation context associated with this alloc region.
++ AllocationContext_t _allocation_context;
++
+ // It keeps track of the distinct number of regions that are used
+ // for allocation in the active interval of this object, i.e.,
+ // between a call to init() and a call to release(). The count
+@@ -110,6 +113,10 @@
+ // else can allocate out of it.
+ void retire(bool fill_up);
+
++ // After a region is allocated by alloc_new_region, this
++ // method is used to set it as the active alloc_region
++ void update_alloc_region(HeapRegion* alloc_region);
++
+ // Allocate a new active region and use it to perform a word_size
+ // allocation. The force parameter will be passed on to
+ // G1CollectedHeap::allocate_new_alloc_region() and tells it to try
+@@ -137,6 +144,9 @@
+ return (hr == _dummy_region) ? NULL : hr;
+ }
+
++ void set_allocation_context(AllocationContext_t context) { _allocation_context = context; }
++ AllocationContext_t allocation_context() { return _allocation_context; }
++
+ uint count() { return _count; }
+
+ // The following two are the building blocks for the allocation method.
+@@ -182,6 +192,40 @@
+ #endif // G1_ALLOC_REGION_TRACING
+ };
+
++class MutatorAllocRegion : public G1AllocRegion {
++protected:
++ virtual HeapRegion* allocate_new_region(size_t word_size, bool force);
++ virtual void retire_region(HeapRegion* alloc_region, size_t allocated_bytes);
++public:
++ MutatorAllocRegion()
++ : G1AllocRegion("Mutator Alloc Region", false /* bot_updates */) { }
++};
++
++class SurvivorGCAllocRegion : public G1AllocRegion {
++protected:
++ virtual HeapRegion* allocate_new_region(size_t word_size, bool force);
++ virtual void retire_region(HeapRegion* alloc_region, size_t allocated_bytes);
++public:
++ SurvivorGCAllocRegion()
++ : G1AllocRegion("Survivor GC Alloc Region", false /* bot_updates */) { }
++};
++
++class OldGCAllocRegion : public G1AllocRegion {
++protected:
++ virtual HeapRegion* allocate_new_region(size_t word_size, bool force);
++ virtual void retire_region(HeapRegion* alloc_region, size_t allocated_bytes);
++public:
++ OldGCAllocRegion()
++ : G1AllocRegion("Old GC Alloc Region", true /* bot_updates */) { }
++
++ // This specialization of release() makes sure that the last card that has
++ // been allocated into has been completely filled by a dummy object. This
++ // avoids races when remembered set scanning wants to update the BOT of the
++ // last card in the retained old gc alloc region, and allocation threads
++ // allocating into that card at the same time.
++ virtual HeapRegion* release();
++};
++
+ class ar_ext_msg : public err_msg {
+ public:
+ ar_ext_msg(G1AllocRegion* alloc_region, const char *message) : err_msg("%s", "") {
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,6 +26,7 @@
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCREGION_INLINE_HPP
+
+ #include "gc_implementation/g1/g1AllocRegion.hpp"
++#include "gc_implementation/g1/heapRegion.inline.hpp"
+
+ inline HeapWord* G1AllocRegion::allocate(HeapRegion* alloc_region,
+ size_t word_size,
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1AllocationContext.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCATIONCONTEXT_HPP
++#define SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCATIONCONTEXT_HPP
++
++#include "memory/allocation.hpp"
++
++typedef unsigned char AllocationContext_t;
++
++class AllocationContext : AllStatic {
++public:
++ // Currently used context
++ static AllocationContext_t current() {
++ return 0;
++ }
++ // System wide default context
++ static AllocationContext_t system() {
++ return 0;
++ }
++};
++
++class AllocationContextStats: public StackObj {
++public:
++ inline void clear() { }
++ inline void update(bool full_gc) { }
++ inline void update_after_mark() { }
++ inline bool available() { return false; }
++};
++
++#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCATIONCONTEXT_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,155 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "gc_implementation/g1/g1Allocator.hpp"
++#include "gc_implementation/g1/g1CollectedHeap.hpp"
++#include "gc_implementation/g1/g1CollectorPolicy.hpp"
++#include "gc_implementation/g1/heapRegion.inline.hpp"
++#include "gc_implementation/g1/heapRegionSet.inline.hpp"
++
++void G1DefaultAllocator::init_mutator_alloc_region() {
++ assert(_mutator_alloc_region.get() == NULL, "pre-condition");
++ _mutator_alloc_region.init();
++}
++
++void G1DefaultAllocator::release_mutator_alloc_region() {
++ _mutator_alloc_region.release();
++ assert(_mutator_alloc_region.get() == NULL, "post-condition");
++}
++
++void G1Allocator::reuse_retained_old_region(EvacuationInfo& evacuation_info,
++ OldGCAllocRegion* old,
++ HeapRegion** retained_old) {
++ HeapRegion* retained_region = *retained_old;
++ *retained_old = NULL;
++
++ // We will discard the current GC alloc region if:
++ // a) it's in the collection set (it can happen!),
++ // b) it's already full (no point in using it),
++ // c) it's empty (this means that it was emptied during
++ // a cleanup and it should be on the free list now), or
++ // d) it's humongous (this means that it was emptied
++ // during a cleanup and was added to the free list, but
++ // has been subsequently used to allocate a humongous
++ // object that may be less than the region size).
++ if (retained_region != NULL &&
++ !retained_region->in_collection_set() &&
++ !(retained_region->top() == retained_region->end()) &&
++ !retained_region->is_empty() &&
++ !retained_region->isHumongous()) {
++ retained_region->record_top_and_timestamp();
++ // The retained region was added to the old region set when it was
++ // retired. We have to remove it now, since we don't allow regions
++ // we allocate to in the region sets. We'll re-add it later, when
++ // it's retired again.
++ _g1h->_old_set.remove(retained_region);
++ bool during_im = _g1h->g1_policy()->during_initial_mark_pause();
++ retained_region->note_start_of_copying(during_im);
++ old->set(retained_region);
++ _g1h->_hr_printer.reuse(retained_region);
++ evacuation_info.set_alloc_regions_used_before(retained_region->used());
++ }
++}
++
++void G1DefaultAllocator::init_gc_alloc_regions(EvacuationInfo& evacuation_info) {
++ assert_at_safepoint(true /* should_be_vm_thread */);
++
++ _survivor_gc_alloc_region.init();
++ _old_gc_alloc_region.init();
++ reuse_retained_old_region(evacuation_info,
++ &_old_gc_alloc_region,
++ &_retained_old_gc_alloc_region);
++}
++
++void G1DefaultAllocator::release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info) {
++ AllocationContext_t context = AllocationContext::current();
++ evacuation_info.set_allocation_regions(survivor_gc_alloc_region(context)->count() +
++ old_gc_alloc_region(context)->count());
++ survivor_gc_alloc_region(context)->release();
++ // If we have an old GC alloc region to release, we'll save it in
++ // _retained_old_gc_alloc_region. If we don't
++ // _retained_old_gc_alloc_region will become NULL. This is what we
++ // want either way so no reason to check explicitly for either
++ // condition.
++ _retained_old_gc_alloc_region = old_gc_alloc_region(context)->release();
++
++ if (ResizePLAB) {
++ _g1h->_survivor_plab_stats.adjust_desired_plab_sz(no_of_gc_workers);
++ _g1h->_old_plab_stats.adjust_desired_plab_sz(no_of_gc_workers);
++ }
++}
++
++void G1DefaultAllocator::abandon_gc_alloc_regions() {
++ assert(survivor_gc_alloc_region(AllocationContext::current())->get() == NULL, "pre-condition");
++ assert(old_gc_alloc_region(AllocationContext::current())->get() == NULL, "pre-condition");
++ _retained_old_gc_alloc_region = NULL;
++}
++
++G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) :
++ ParGCAllocBuffer(gclab_word_size), _retired(true) { }
++
++HeapWord* G1ParGCAllocator::allocate_slow(GCAllocPurpose purpose, size_t word_sz, AllocationContext_t context) {
++ HeapWord* obj = NULL;
++ size_t gclab_word_size = _g1h->desired_plab_sz(purpose);
++ if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
++ G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose, context);
++ add_to_alloc_buffer_waste(alloc_buf->words_remaining());
++ alloc_buf->retire(false /* end_of_gc */, false /* retain */);
++
++ HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size, context);
++ if (buf == NULL) {
++ return NULL; // Let caller handle allocation failure.
++ }
++ // Otherwise.
++ alloc_buf->set_word_size(gclab_word_size);
++ alloc_buf->set_buf(buf);
++
++ obj = alloc_buf->allocate(word_sz);
++ assert(obj != NULL, "buffer was definitely big enough...");
++ } else {
++ obj = _g1h->par_allocate_during_gc(purpose, word_sz, context);
++ }
++ return obj;
++}
++
++G1DefaultParGCAllocator::G1DefaultParGCAllocator(G1CollectedHeap* g1h) :
++ G1ParGCAllocator(g1h),
++ _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)),
++ _tenured_alloc_buffer(g1h->desired_plab_sz(GCAllocForTenured)) {
++
++ _alloc_buffers[GCAllocForSurvived] = &_surviving_alloc_buffer;
++ _alloc_buffers[GCAllocForTenured] = &_tenured_alloc_buffer;
++
++}
++
++void G1DefaultParGCAllocator::retire_alloc_buffers() {
++ for (int ap = 0; ap < GCAllocPurposeCount; ++ap) {
++ size_t waste = _alloc_buffers[ap]->words_remaining();
++ add_to_alloc_buffer_waste(waste);
++ _alloc_buffers[ap]->flush_stats_and_retire(_g1h->stats_for_purpose((GCAllocPurpose)ap),
++ true /* end_of_gc */,
++ false /* retain */);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,242 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCATOR_HPP
++#define SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCATOR_HPP
++
++#include "gc_implementation/g1/g1AllocationContext.hpp"
++#include "gc_implementation/g1/g1AllocRegion.hpp"
++#include "gc_implementation/shared/parGCAllocBuffer.hpp"
++
++enum GCAllocPurpose {
++ GCAllocForTenured,
++ GCAllocForSurvived,
++ GCAllocPurposeCount
++};
++
++// Base class for G1 allocators.
++class G1Allocator : public CHeapObj<mtGC> {
++ friend class VMStructs;
++protected:
++ G1CollectedHeap* _g1h;
++
++ // Outside of GC pauses, the number of bytes used in all regions other
++ // than the current allocation region.
++ size_t _summary_bytes_used;
++
++public:
++ G1Allocator(G1CollectedHeap* heap) :
++ _g1h(heap), _summary_bytes_used(0) { }
++
++ static G1Allocator* create_allocator(G1CollectedHeap* g1h);
++
++ virtual void init_mutator_alloc_region() = 0;
++ virtual void release_mutator_alloc_region() = 0;
++
++ virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0;
++ virtual void release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info) = 0;
++ virtual void abandon_gc_alloc_regions() = 0;
++
++ virtual MutatorAllocRegion* mutator_alloc_region(AllocationContext_t context) = 0;
++ virtual SurvivorGCAllocRegion* survivor_gc_alloc_region(AllocationContext_t context) = 0;
++ virtual OldGCAllocRegion* old_gc_alloc_region(AllocationContext_t context) = 0;
++ virtual size_t used() = 0;
++ virtual bool is_retained_old_region(HeapRegion* hr) = 0;
++
++ void reuse_retained_old_region(EvacuationInfo& evacuation_info,
++ OldGCAllocRegion* old,
++ HeapRegion** retained);
++
++ size_t used_unlocked() const {
++ return _summary_bytes_used;
++ }
++
++ void increase_used(size_t bytes) {
++ _summary_bytes_used += bytes;
++ }
++
++ void decrease_used(size_t bytes) {
++ assert(_summary_bytes_used >= bytes,
++ err_msg("invariant: _summary_bytes_used: "SIZE_FORMAT" should be >= bytes: "SIZE_FORMAT,
++ _summary_bytes_used, bytes));
++ _summary_bytes_used -= bytes;
++ }
++
++ void set_used(size_t bytes) {
++ _summary_bytes_used = bytes;
++ }
++
++ virtual HeapRegion* new_heap_region(uint hrs_index,
++ G1BlockOffsetSharedArray* sharedOffsetArray,
++ MemRegion mr) {
++ return new HeapRegion(hrs_index, sharedOffsetArray, mr);
++ }
++};
++
++// The default allocator for G1.
++class G1DefaultAllocator : public G1Allocator {
++protected:
++ // Alloc region used to satisfy mutator allocation requests.
++ MutatorAllocRegion _mutator_alloc_region;
++
++ // Alloc region used to satisfy allocation requests by the GC for
++ // survivor objects.
++ SurvivorGCAllocRegion _survivor_gc_alloc_region;
++
++ // Alloc region used to satisfy allocation requests by the GC for
++ // old objects.
++ OldGCAllocRegion _old_gc_alloc_region;
++
++ HeapRegion* _retained_old_gc_alloc_region;
++public:
++ G1DefaultAllocator(G1CollectedHeap* heap) : G1Allocator(heap), _retained_old_gc_alloc_region(NULL) { }
++
++ virtual void init_mutator_alloc_region();
++ virtual void release_mutator_alloc_region();
++
++ virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info);
++ virtual void release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info);
++ virtual void abandon_gc_alloc_regions();
++
++ virtual bool is_retained_old_region(HeapRegion* hr) {
++ return _retained_old_gc_alloc_region == hr;
++ }
++
++ virtual MutatorAllocRegion* mutator_alloc_region(AllocationContext_t context) {
++ return &_mutator_alloc_region;
++ }
++
++ virtual SurvivorGCAllocRegion* survivor_gc_alloc_region(AllocationContext_t context) {
++ return &_survivor_gc_alloc_region;
++ }
++
++ virtual OldGCAllocRegion* old_gc_alloc_region(AllocationContext_t context) {
++ return &_old_gc_alloc_region;
++ }
++
++ virtual size_t used() {
++ assert(Heap_lock->owner() != NULL,
++ "Should be owned on this thread's behalf.");
++ size_t result = _summary_bytes_used;
++
++ // Read only once in case it is set to NULL concurrently
++ HeapRegion* hr = mutator_alloc_region(AllocationContext::current())->get();
++ if (hr != NULL) {
++ result += hr->used();
++ }
++ return result;
++ }
++};
++
++class G1ParGCAllocBuffer: public ParGCAllocBuffer {
++private:
++ bool _retired;
++
++public:
++ G1ParGCAllocBuffer(size_t gclab_word_size);
++ virtual ~G1ParGCAllocBuffer() {
++ guarantee(_retired, "Allocation buffer has not been retired");
++ }
++
++ virtual void set_buf(HeapWord* buf) {
++ ParGCAllocBuffer::set_buf(buf);
++ _retired = false;
++ }
++
++ virtual void retire(bool end_of_gc, bool retain) {
++ if (_retired) {
++ return;
++ }
++ ParGCAllocBuffer::retire(end_of_gc, retain);
++ _retired = true;
++ }
++};
++
++class G1ParGCAllocator : public CHeapObj<mtGC> {
++ friend class G1ParScanThreadState;
++protected:
++ G1CollectedHeap* _g1h;
++
++ size_t _alloc_buffer_waste;
++ size_t _undo_waste;
++
++ void add_to_alloc_buffer_waste(size_t waste) { _alloc_buffer_waste += waste; }
++ void add_to_undo_waste(size_t waste) { _undo_waste += waste; }
++
++ HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz, AllocationContext_t context);
++
++ virtual void retire_alloc_buffers() = 0;
++ virtual G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose, AllocationContext_t context) = 0;
++
++public:
++ G1ParGCAllocator(G1CollectedHeap* g1h) :
++ _g1h(g1h), _alloc_buffer_waste(0), _undo_waste(0) {
++ }
++
++ static G1ParGCAllocator* create_allocator(G1CollectedHeap* g1h);
++
++ size_t alloc_buffer_waste() { return _alloc_buffer_waste; }
++ size_t undo_waste() {return _undo_waste; }
++
++ HeapWord* allocate(GCAllocPurpose purpose, size_t word_sz, AllocationContext_t context) {
++ HeapWord* obj = NULL;
++ if (purpose == GCAllocForSurvived) {
++ obj = alloc_buffer(purpose, context)->allocate_aligned(word_sz, SurvivorAlignmentInBytes);
++ } else {
++ obj = alloc_buffer(purpose, context)->allocate(word_sz);
++ }
++ if (obj != NULL) {
++ return obj;
++ }
++ return allocate_slow(purpose, word_sz, context);
++ }
++
++ void undo_allocation(GCAllocPurpose purpose, HeapWord* obj, size_t word_sz, AllocationContext_t context) {
++ if (alloc_buffer(purpose, context)->contains(obj)) {
++ assert(alloc_buffer(purpose, context)->contains(obj + word_sz - 1),
++ "should contain whole object");
++ alloc_buffer(purpose, context)->undo_allocation(obj, word_sz);
++ } else {
++ CollectedHeap::fill_with_object(obj, word_sz);
++ add_to_undo_waste(word_sz);
++ }
++ }
++};
++
++class G1DefaultParGCAllocator : public G1ParGCAllocator {
++ G1ParGCAllocBuffer _surviving_alloc_buffer;
++ G1ParGCAllocBuffer _tenured_alloc_buffer;
++ G1ParGCAllocBuffer* _alloc_buffers[GCAllocPurposeCount];
++
++public:
++ G1DefaultParGCAllocator(G1CollectedHeap* g1h);
++
++ virtual G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose, AllocationContext_t context) {
++ return _alloc_buffers[purpose];
++ }
++
++ virtual void retire_alloc_buffers() ;
++};
++
++#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCATOR_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1Allocator_ext.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "gc_implementation/g1/g1Allocator.hpp"
++#include "gc_implementation/g1/g1CollectedHeap.hpp"
++
++G1Allocator* G1Allocator::create_allocator(G1CollectedHeap* g1h) {
++ return new G1DefaultAllocator(g1h);
++}
++
++G1ParGCAllocator* G1ParGCAllocator::create_allocator(G1CollectedHeap* g1h) {
++ return new G1DefaultParGCAllocator(g1h);
++}
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -24,6 +24,7 @@
+
+ #include "precompiled.hpp"
+ #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
++#include "gc_implementation/g1/heapRegion.hpp"
+ #include "memory/space.hpp"
+ #include "oops/oop.inline.hpp"
+ #include "runtime/java.hpp"
+@@ -35,60 +36,26 @@
+ // G1BlockOffsetSharedArray
+ //////////////////////////////////////////////////////////////////////
+
+-G1BlockOffsetSharedArray::G1BlockOffsetSharedArray(MemRegion reserved,
+- size_t init_word_size) :
+- _reserved(reserved), _end(NULL)
+-{
+- size_t size = compute_size(reserved.word_size());
+- ReservedSpace rs(ReservedSpace::allocation_align_size_up(size));
+- if (!rs.is_reserved()) {
+- vm_exit_during_initialization("Could not reserve enough space for heap offset array");
+- }
+- if (!_vs.initialize(rs, 0)) {
+- vm_exit_during_initialization("Could not reserve enough space for heap offset array");
+- }
++G1BlockOffsetSharedArray::G1BlockOffsetSharedArray(MemRegion heap, G1RegionToSpaceMapper* storage) :
++ _reserved(), _end(NULL), _listener(), _offset_array(NULL) {
+
+- MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
++ _reserved = heap;
++ _end = NULL;
+
+- _offset_array = (u_char*)_vs.low_boundary();
+- resize(init_word_size);
++ MemRegion bot_reserved = storage->reserved();
++
++ _offset_array = (u_char*)bot_reserved.start();
++ _end = _reserved.end();
++
++ storage->set_mapping_changed_listener(&_listener);
++
+ if (TraceBlockOffsetTable) {
+ gclog_or_tty->print_cr("G1BlockOffsetSharedArray::G1BlockOffsetSharedArray: ");
+ gclog_or_tty->print_cr(" "
+ " rs.base(): " INTPTR_FORMAT
+ " rs.size(): " INTPTR_FORMAT
+ " rs end(): " INTPTR_FORMAT,
+- rs.base(), rs.size(), rs.base() + rs.size());
+- gclog_or_tty->print_cr(" "
+- " _vs.low_boundary(): " INTPTR_FORMAT
+- " _vs.high_boundary(): " INTPTR_FORMAT,
+- _vs.low_boundary(),
+- _vs.high_boundary());
+- }
+-}
+-
+-void G1BlockOffsetSharedArray::resize(size_t new_word_size) {
+- assert(new_word_size <= _reserved.word_size(), "Resize larger than reserved");
+- size_t new_size = compute_size(new_word_size);
+- size_t old_size = _vs.committed_size();
+- size_t delta;
+- char* high = _vs.high();
+- _end = _reserved.start() + new_word_size;
+- if (new_size > old_size) {
+- delta = ReservedSpace::page_align_size_up(new_size - old_size);
+- assert(delta > 0, "just checking");
+- if (!_vs.expand_by(delta)) {
+- // Do better than this for Merlin
+- vm_exit_out_of_memory(delta, OOM_MMAP_ERROR, "offset table expansion");
+- }
+- assert(_vs.high() == high + delta, "invalid expansion");
+- // Initialization of the contents is left to the
+- // G1BlockOffsetArray that uses it.
+- } else {
+- delta = ReservedSpace::page_align_size_down(old_size - new_size);
+- if (delta == 0) return;
+- _vs.shrink_by(delta);
+- assert(_vs.high() == high - delta, "invalid expansion");
++ bot_reserved.start(), bot_reserved.byte_size(), bot_reserved.end());
+ }
+ }
+
+@@ -98,28 +65,20 @@
+ return (delta & right_n_bits(LogN_words)) == (size_t)NoBits;
+ }
+
+-
+ //////////////////////////////////////////////////////////////////////
+ // G1BlockOffsetArray
+ //////////////////////////////////////////////////////////////////////
+
+ G1BlockOffsetArray::G1BlockOffsetArray(G1BlockOffsetSharedArray* array,
+- MemRegion mr, bool init_to_zero) :
++ MemRegion mr) :
+ G1BlockOffsetTable(mr.start(), mr.end()),
+ _unallocated_block(_bottom),
+- _array(array), _csp(NULL),
+- _init_to_zero(init_to_zero) {
++ _array(array), _gsp(NULL) {
+ assert(_bottom <= _end, "arguments out of order");
+- if (!_init_to_zero) {
+- // initialize cards to point back to mr.start()
+- set_remainder_to_point_to_start(mr.start() + N_words, mr.end());
+- _array->set_offset_array(0, 0); // set first card to 0
+- }
+ }
+
+-void G1BlockOffsetArray::set_space(Space* sp) {
+- _sp = sp;
+- _csp = sp->toContiguousSpace();
++void G1BlockOffsetArray::set_space(G1OffsetTableContigSpace* sp) {
++ _gsp = sp;
+ }
+
+ // The arguments follow the normal convention of denoting
+@@ -205,93 +164,6 @@
+ DEBUG_ONLY(check_all_cards(start_card, end_card);)
+ }
+
+-// The block [blk_start, blk_end) has been allocated;
+-// adjust the block offset table to represent this information;
+-// right-open interval: [blk_start, blk_end)
+-void
+-G1BlockOffsetArray::alloc_block(HeapWord* blk_start, HeapWord* blk_end) {
+- mark_block(blk_start, blk_end);
+- allocated(blk_start, blk_end);
+-}
+-
+-// Adjust BOT to show that a previously whole block has been split
+-// into two.
+-void G1BlockOffsetArray::split_block(HeapWord* blk, size_t blk_size,
+- size_t left_blk_size) {
+- // Verify that the BOT shows [blk, blk + blk_size) to be one block.
+- verify_single_block(blk, blk_size);
+- // Update the BOT to indicate that [blk + left_blk_size, blk + blk_size)
+- // is one single block.
+- mark_block(blk + left_blk_size, blk + blk_size);
+-}
+-
+-
+-// Action_mark - update the BOT for the block [blk_start, blk_end).
+-// Current typical use is for splitting a block.
+-// Action_single - update the BOT for an allocation.
+-// Action_verify - BOT verification.
+-void G1BlockOffsetArray::do_block_internal(HeapWord* blk_start,
+- HeapWord* blk_end,
+- Action action) {
+- assert(Universe::heap()->is_in_reserved(blk_start),
+- "reference must be into the heap");
+- assert(Universe::heap()->is_in_reserved(blk_end-1),
+- "limit must be within the heap");
+- // This is optimized to make the test fast, assuming we only rarely
+- // cross boundaries.
+- uintptr_t end_ui = (uintptr_t)(blk_end - 1);
+- uintptr_t start_ui = (uintptr_t)blk_start;
+- // Calculate the last card boundary preceding end of blk
+- intptr_t boundary_before_end = (intptr_t)end_ui;
+- clear_bits(boundary_before_end, right_n_bits(LogN));
+- if (start_ui <= (uintptr_t)boundary_before_end) {
+- // blk starts at or crosses a boundary
+- // Calculate index of card on which blk begins
+- size_t start_index = _array->index_for(blk_start);
+- // Index of card on which blk ends
+- size_t end_index = _array->index_for(blk_end - 1);
+- // Start address of card on which blk begins
+- HeapWord* boundary = _array->address_for_index(start_index);
+- assert(boundary <= blk_start, "blk should start at or after boundary");
+- if (blk_start != boundary) {
+- // blk starts strictly after boundary
+- // adjust card boundary and start_index forward to next card
+- boundary += N_words;
+- start_index++;
+- }
+- assert(start_index <= end_index, "monotonicity of index_for()");
+- assert(boundary <= (HeapWord*)boundary_before_end, "tautology");
+- switch (action) {
+- case Action_mark: {
+- if (init_to_zero()) {
+- _array->set_offset_array(start_index, boundary, blk_start);
+- break;
+- } // Else fall through to the next case
+- }
+- case Action_single: {
+- _array->set_offset_array(start_index, boundary, blk_start);
+- // We have finished marking the "offset card". We need to now
+- // mark the subsequent cards that this blk spans.
+- if (start_index < end_index) {
+- HeapWord* rem_st = _array->address_for_index(start_index) + N_words;
+- HeapWord* rem_end = _array->address_for_index(end_index) + N_words;
+- set_remainder_to_point_to_start(rem_st, rem_end);
+- }
+- break;
+- }
+- case Action_check: {
+- _array->check_offset_array(start_index, boundary, blk_start);
+- // We have finished checking the "offset card". We need to now
+- // check the subsequent cards that this blk spans.
+- check_all_cards(start_index + 1, end_index);
+- break;
+- }
+- default:
+- ShouldNotReachHere();
+- }
+- }
+-}
+-
+ // The card-interval [start_card, end_card] is a closed interval; this
+ // is an expensive check -- use with care and only under protection of
+ // suitable flag.
+@@ -330,25 +202,6 @@
+ }
+ }
+
+-// The range [blk_start, blk_end) represents a single contiguous block
+-// of storage; modify the block offset table to represent this
+-// information; Right-open interval: [blk_start, blk_end)
+-// NOTE: this method does _not_ adjust _unallocated_block.
+-void
+-G1BlockOffsetArray::single_block(HeapWord* blk_start, HeapWord* blk_end) {
+- do_block_internal(blk_start, blk_end, Action_single);
+-}
+-
+-// Mark the BOT such that if [blk_start, blk_end) straddles a card
+-// boundary, the card following the first such boundary is marked
+-// with the appropriate offset.
+-// NOTE: this method does _not_ adjust _unallocated_block or
+-// any cards subsequent to the first one.
+-void
+-G1BlockOffsetArray::mark_block(HeapWord* blk_start, HeapWord* blk_end) {
+- do_block_internal(blk_start, blk_end, Action_mark);
+-}
+-
+ HeapWord* G1BlockOffsetArray::block_start_unsafe(const void* addr) {
+ assert(_bottom <= addr && addr < _end,
+ "addr must be covered by this Array");
+@@ -378,7 +231,7 @@
+ }
+ // Otherwise, find the block start using the table.
+ HeapWord* q = block_at_or_preceding(addr, false, 0);
+- HeapWord* n = q + _sp->block_size(q);
++ HeapWord* n = q + block_size(q);
+ return forward_to_block_containing_addr_const(q, n, addr);
+ }
+
+@@ -406,86 +259,28 @@
+ err_msg("next_boundary is beyond the end of the covered region "
+ " next_boundary " PTR_FORMAT " _array->_end " PTR_FORMAT,
+ next_boundary, _array->_end));
+- if (csp() != NULL) {
+- if (addr >= csp()->top()) return csp()->top();
+- while (next_boundary < addr) {
+- while (n <= next_boundary) {
+- q = n;
+- oop obj = oop(q);
+- if (obj->klass_or_null() == NULL) return q;
+- n += obj->size();
+- }
+- assert(q <= next_boundary && n > next_boundary, "Consequence of loop");
+- // [q, n) is the block that crosses the boundary.
+- alloc_block_work2(&next_boundary, &next_index, q, n);
++ if (addr >= gsp()->top()) return gsp()->top();
++ while (next_boundary < addr) {
++ while (n <= next_boundary) {
++ q = n;
++ oop obj = oop(q);
++ if (obj->klass_or_null() == NULL) return q;
++ n += block_size(q);
+ }
+- } else {
+- while (next_boundary < addr) {
+- while (n <= next_boundary) {
+- q = n;
+- oop obj = oop(q);
+- if (obj->klass_or_null() == NULL) return q;
+- n += _sp->block_size(q);
+- }
+- assert(q <= next_boundary && n > next_boundary, "Consequence of loop");
+- // [q, n) is the block that crosses the boundary.
+- alloc_block_work2(&next_boundary, &next_index, q, n);
+- }
++ assert(q <= next_boundary && n > next_boundary, "Consequence of loop");
++ // [q, n) is the block that crosses the boundary.
++ alloc_block_work2(&next_boundary, &next_index, q, n);
+ }
+ return forward_to_block_containing_addr_const(q, n, addr);
+ }
+
+-HeapWord* G1BlockOffsetArray::block_start_careful(const void* addr) const {
+- assert(_array->offset_array(0) == 0, "objects can't cross covered areas");
+-
+- assert(_bottom <= addr && addr < _end,
+- "addr must be covered by this Array");
+- // Must read this exactly once because it can be modified by parallel
+- // allocation.
+- HeapWord* ub = _unallocated_block;
+- if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) {
+- assert(ub < _end, "tautology (see above)");
+- return ub;
+- }
+-
+- // Otherwise, find the block start using the table, but taking
+- // care (cf block_start_unsafe() above) not to parse any objects/blocks
+- // on the cards themsleves.
+- size_t index = _array->index_for(addr);
+- assert(_array->address_for_index(index) == addr,
+- "arg should be start of card");
+-
+- HeapWord* q = (HeapWord*)addr;
+- uint offset;
+- do {
+- offset = _array->offset_array(index--);
+- q -= offset;
+- } while (offset == N_words);
+- assert(q <= addr, "block start should be to left of arg");
+- return q;
+-}
+-
+ // Note that the committed size of the covered space may have changed,
+ // so the table size might also wish to change.
+ void G1BlockOffsetArray::resize(size_t new_word_size) {
+ HeapWord* new_end = _bottom + new_word_size;
+- if (_end < new_end && !init_to_zero()) {
+- // verify that the old and new boundaries are also card boundaries
+- assert(_array->is_card_boundary(_end),
+- "_end not a card boundary");
+- assert(_array->is_card_boundary(new_end),
+- "new _end would not be a card boundary");
+- // set all the newly added cards
+- _array->set_offset_array(_end, new_end, N_words);
+- }
+ _end = new_end; // update _end
+ }
+
+-void G1BlockOffsetArray::set_region(MemRegion mr) {
+- _bottom = mr.start();
+- _end = mr.end();
+-}
+-
+ //
+ // threshold_
+ // | _index_
+@@ -638,19 +433,38 @@
+ assert(_bottom <= addr && addr < _end,
+ "addr must be covered by this Array");
+ HeapWord* q = block_at_or_preceding(addr, true, _next_offset_index-1);
+- HeapWord* n = q + _sp->block_size(q);
++ HeapWord* n = q + block_size(q);
+ return forward_to_block_containing_addr_const(q, n, addr);
+ }
+
+ G1BlockOffsetArrayContigSpace::
+ G1BlockOffsetArrayContigSpace(G1BlockOffsetSharedArray* array,
+ MemRegion mr) :
+- G1BlockOffsetArray(array, mr, true)
++ G1BlockOffsetArray(array, mr)
+ {
+ _next_offset_threshold = NULL;
+ _next_offset_index = 0;
+ }
+
++HeapWord* G1BlockOffsetArrayContigSpace::initialize_threshold_raw() {
++ assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
++ "just checking");
++ _next_offset_index = _array->index_for_raw(_bottom);
++ _next_offset_index++;
++ _next_offset_threshold =
++ _array->address_for_index_raw(_next_offset_index);
++ return _next_offset_threshold;
++}
++
++void G1BlockOffsetArrayContigSpace::zero_bottom_entry_raw() {
++ assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
++ "just checking");
++ size_t bottom_index = _array->index_for_raw(_bottom);
++ assert(_array->address_for_index_raw(bottom_index) == _bottom,
++ "Precondition of call");
++ _array->set_offset_array_raw(bottom_index, 0);
++}
++
+ HeapWord* G1BlockOffsetArrayContigSpace::initialize_threshold() {
+ assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
+ "just checking");
+@@ -661,22 +475,12 @@
+ return _next_offset_threshold;
+ }
+
+-void G1BlockOffsetArrayContigSpace::zero_bottom_entry() {
+- assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
+- "just checking");
+- size_t bottom_index = _array->index_for(_bottom);
+- assert(_array->address_for_index(bottom_index) == _bottom,
+- "Precondition of call");
+- _array->set_offset_array(bottom_index, 0);
+-}
+-
+ void
+ G1BlockOffsetArrayContigSpace::set_for_starts_humongous(HeapWord* new_top) {
+ assert(new_top <= _end, "_end should have already been updated");
+
+ // The first BOT entry should have offset 0.
+- zero_bottom_entry();
+- initialize_threshold();
++ reset_bot();
+ alloc_block(_bottom, new_top);
+ }
+
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,6 +25,7 @@
+ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_HPP
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_HPP
+
++#include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
+ #include "memory/memRegion.hpp"
+ #include "runtime/virtualspace.hpp"
+ #include "utilities/globalDefinitions.hpp"
+@@ -52,8 +53,8 @@
+ // consolidation.
+
+ // Forward declarations
+-class ContiguousSpace;
+ class G1BlockOffsetSharedArray;
++class G1OffsetTableContigSpace;
+
+ class G1BlockOffsetTable VALUE_OBJ_CLASS_SPEC {
+ friend class VMStructs;
+@@ -106,6 +107,16 @@
+ inline HeapWord* block_start_const(const void* addr) const;
+ };
+
++class G1BlockOffsetSharedArrayMappingChangedListener : public G1MappingChangedListener {
++ public:
++ virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
++ // Nothing to do. The BOT is hard-wired to be part of the HeapRegion, and we cannot
++ // retrieve it here since this would cause firing of several asserts. The code
++ // executed after commit of a region already needs to do some re-initialization of
++ // the HeapRegion, so we combine that.
++ }
++};
++
+ // This implementation of "G1BlockOffsetTable" divides the covered region
+ // into "N"-word subregions (where "N" = 2^"LogN". An array with an entry
+ // for each such subregion indicates how far back one must go to find the
+@@ -125,6 +136,7 @@
+ friend class VMStructs;
+
+ private:
++ G1BlockOffsetSharedArrayMappingChangedListener _listener;
+ // The reserved region covered by the shared array.
+ MemRegion _reserved;
+
+@@ -133,16 +145,8 @@
+
+ // Array for keeping offsets for retrieving object start fast given an
+ // address.
+- VirtualSpace _vs;
+ u_char* _offset_array; // byte array keeping backwards offsets
+
+- void check_index(size_t index, const char* msg) const {
+- assert(index < _vs.committed_size(),
+- err_msg("%s - "
+- "index: " SIZE_FORMAT ", _vs.committed_size: " SIZE_FORMAT,
+- msg, index, _vs.committed_size()));
+- }
+-
+ void check_offset(size_t offset, const char* msg) const {
+ assert(offset <= N_words,
+ err_msg("%s - "
+@@ -152,76 +156,29 @@
+
+ // Bounds checking accessors:
+ // For performance these have to devolve to array accesses in product builds.
+- u_char offset_array(size_t index) const {
+- check_index(index, "index out of range");
+- return _offset_array[index];
+- }
++ inline u_char offset_array(size_t index) const;
+
+- void set_offset_array(size_t index, u_char offset) {
+- check_index(index, "index out of range");
+- check_offset(offset, "offset too large");
++ void set_offset_array_raw(size_t index, u_char offset) {
+ _offset_array[index] = offset;
+ }
+
+- void set_offset_array(size_t index, HeapWord* high, HeapWord* low) {
+- check_index(index, "index out of range");
+- assert(high >= low, "addresses out of order");
+- check_offset(pointer_delta(high, low), "offset too large");
+- _offset_array[index] = (u_char) pointer_delta(high, low);
+- }
++ inline void set_offset_array(size_t index, u_char offset);
+
+- void set_offset_array(HeapWord* left, HeapWord* right, u_char offset) {
+- check_index(index_for(right - 1), "right address out of range");
+- assert(left < right, "Heap addresses out of order");
+- size_t num_cards = pointer_delta(right, left) >> LogN_words;
+- if (UseMemSetInBOT) {
+- memset(&_offset_array[index_for(left)], offset, num_cards);
+- } else {
+- size_t i = index_for(left);
+- const size_t end = i + num_cards;
+- for (; i < end; i++) {
+- _offset_array[i] = offset;
+- }
+- }
+- }
++ inline void set_offset_array(size_t index, HeapWord* high, HeapWord* low);
+
+- void set_offset_array(size_t left, size_t right, u_char offset) {
+- check_index(right, "right index out of range");
+- assert(left <= right, "indexes out of order");
+- size_t num_cards = right - left + 1;
+- if (UseMemSetInBOT) {
+- memset(&_offset_array[left], offset, num_cards);
+- } else {
+- size_t i = left;
+- const size_t end = i + num_cards;
+- for (; i < end; i++) {
+- _offset_array[i] = offset;
+- }
+- }
+- }
+-
+- void check_offset_array(size_t index, HeapWord* high, HeapWord* low) const {
+- check_index(index, "index out of range");
+- assert(high >= low, "addresses out of order");
+- check_offset(pointer_delta(high, low), "offset too large");
+- assert(_offset_array[index] == pointer_delta(high, low), "Wrong offset");
+- }
++ inline void set_offset_array(size_t left, size_t right, u_char offset);
+
+ bool is_card_boundary(HeapWord* p) const;
+
++public:
++
+ // Return the number of slots needed for an offset array
+ // that covers mem_region_words words.
+- // We always add an extra slot because if an object
+- // ends on a card boundary we put a 0 in the next
+- // offset array slot, so we want that slot always
+- // to be reserved.
+-
+- size_t compute_size(size_t mem_region_words) {
+- size_t number_of_slots = (mem_region_words / N_words) + 1;
+- return ReservedSpace::page_align_size_up(number_of_slots);
++ static size_t compute_size(size_t mem_region_words) {
++ size_t number_of_slots = (mem_region_words / N_words);
++ return ReservedSpace::allocation_align_size_up(number_of_slots);
+ }
+
+-public:
+ enum SomePublicConstants {
+ LogN = 9,
+ LogN_words = LogN - LogHeapWordSize,
+@@ -235,25 +192,19 @@
+ // least "init_word_size".) The contents of the initial table are
+ // undefined; it is the responsibility of the constituent
+ // G1BlockOffsetTable(s) to initialize cards.
+- G1BlockOffsetSharedArray(MemRegion reserved, size_t init_word_size);
+-
+- // Notes a change in the committed size of the region covered by the
+- // table. The "new_word_size" may not be larger than the size of the
+- // reserved region this table covers.
+- void resize(size_t new_word_size);
+-
+- void set_bottom(HeapWord* new_bottom);
+-
+- // Updates all the BlockOffsetArray's sharing this shared array to
+- // reflect the current "top"'s of their spaces.
+- void update_offset_arrays();
++ G1BlockOffsetSharedArray(MemRegion heap, G1RegionToSpaceMapper* storage);
+
+ // Return the appropriate index into "_offset_array" for "p".
+ inline size_t index_for(const void* p) const;
++ inline size_t index_for_raw(const void* p) const;
+
+ // Return the address indicating the start of the region corresponding to
+ // "index" in "_offset_array".
+ inline HeapWord* address_for_index(size_t index) const;
++ // Variant of address_for_index that does not check the index for validity.
++ inline HeapWord* address_for_index_raw(size_t index) const {
++ return _reserved.start() + (index << LogN_words);
++ }
+ };
+
+ // And here is the G1BlockOffsetTable subtype that uses the array.
+@@ -268,28 +219,12 @@
+ LogN = G1BlockOffsetSharedArray::LogN
+ };
+
+- // The following enums are used by do_block_helper
+- enum Action {
+- Action_single, // BOT records a single block (see single_block())
+- Action_mark, // BOT marks the start of a block (see mark_block())
+- Action_check // Check that BOT records block correctly
+- // (see verify_single_block()).
+- };
+-
+ // This is the array, which can be shared by several BlockOffsetArray's
+ // servicing different
+ G1BlockOffsetSharedArray* _array;
+
+ // The space that owns this subregion.
+- Space* _sp;
+-
+- // If "_sp" is a contiguous space, the field below is the view of "_sp"
+- // as a contiguous space, else NULL.
+- ContiguousSpace* _csp;
+-
+- // If true, array entries are initialized to 0; otherwise, they are
+- // initialized to point backwards to the beginning of the covered region.
+- bool _init_to_zero;
++ G1OffsetTableContigSpace* _gsp;
+
+ // The portion [_unallocated_block, _sp.end()) of the space that
+ // is a single block known not to contain any objects.
+@@ -305,12 +240,11 @@
+ // that is closed: [start_index, end_index]
+ void set_remainder_to_point_to_start_incl(size_t start, size_t end);
+
+- // A helper function for BOT adjustment/verification work
+- void do_block_internal(HeapWord* blk_start, HeapWord* blk_end, Action action);
+-
+ protected:
+
+- ContiguousSpace* csp() const { return _csp; }
++ G1OffsetTableContigSpace* gsp() const { return _gsp; }
++
++ inline size_t block_size(const HeapWord* p) const;
+
+ // Returns the address of a block whose start is at most "addr".
+ // If "has_max_index" is true, "assumes "max_index" is the last valid one
+@@ -353,126 +287,29 @@
+
+ public:
+ // The space may not have it's bottom and top set yet, which is why the
+- // region is passed as a parameter. If "init_to_zero" is true, the
+- // elements of the array are initialized to zero. Otherwise, they are
+- // initialized to point backwards to the beginning.
+- G1BlockOffsetArray(G1BlockOffsetSharedArray* array, MemRegion mr,
+- bool init_to_zero);
++ // region is passed as a parameter. The elements of the array are
++ // initialized to zero.
++ G1BlockOffsetArray(G1BlockOffsetSharedArray* array, MemRegion mr);
+
+ // Note: this ought to be part of the constructor, but that would require
+ // "this" to be passed as a parameter to a member constructor for
+ // the containing concrete subtype of Space.
+ // This would be legal C++, but MS VC++ doesn't allow it.
+- void set_space(Space* sp);
+-
+- // Resets the covered region to the given "mr".
+- void set_region(MemRegion mr);
++ void set_space(G1OffsetTableContigSpace* sp);
+
+ // Resets the covered region to one with the same _bottom as before but
+ // the "new_word_size".
+ void resize(size_t new_word_size);
+
+- // These must be guaranteed to work properly (i.e., do nothing)
+- // when "blk_start" ("blk" for second version) is "NULL".
+- virtual void alloc_block(HeapWord* blk_start, HeapWord* blk_end);
+- virtual void alloc_block(HeapWord* blk, size_t size) {
+- alloc_block(blk, blk + size);
+- }
+-
+- // The following methods are useful and optimized for a
+- // general, non-contiguous space.
+-
+- // Given a block [blk_start, blk_start + full_blk_size), and
+- // a left_blk_size < full_blk_size, adjust the BOT to show two
+- // blocks [blk_start, blk_start + left_blk_size) and
+- // [blk_start + left_blk_size, blk_start + full_blk_size).
+- // It is assumed (and verified in the non-product VM) that the
+- // BOT was correct for the original block.
+- void split_block(HeapWord* blk_start, size_t full_blk_size,
+- size_t left_blk_size);
+-
+- // Adjust the BOT to show that it has a single block in the
+- // range [blk_start, blk_start + size). All necessary BOT
+- // cards are adjusted, but _unallocated_block isn't.
+- void single_block(HeapWord* blk_start, HeapWord* blk_end);
+- void single_block(HeapWord* blk, size_t size) {
+- single_block(blk, blk + size);
+- }
+-
+- // Adjust BOT to show that it has a block in the range
+- // [blk_start, blk_start + size). Only the first card
+- // of BOT is touched. It is assumed (and verified in the
+- // non-product VM) that the remaining cards of the block
+- // are correct.
+- void mark_block(HeapWord* blk_start, HeapWord* blk_end);
+- void mark_block(HeapWord* blk, size_t size) {
+- mark_block(blk, blk + size);
+- }
+-
+- // Adjust _unallocated_block to indicate that a particular
+- // block has been newly allocated or freed. It is assumed (and
+- // verified in the non-product VM) that the BOT is correct for
+- // the given block.
+- inline void allocated(HeapWord* blk_start, HeapWord* blk_end) {
+- // Verify that the BOT shows [blk, blk + blk_size) to be one block.
+- verify_single_block(blk_start, blk_end);
+- if (BlockOffsetArrayUseUnallocatedBlock) {
+- _unallocated_block = MAX2(_unallocated_block, blk_end);
+- }
+- }
+-
+- inline void allocated(HeapWord* blk, size_t size) {
+- allocated(blk, blk + size);
+- }
+-
+- inline void freed(HeapWord* blk_start, HeapWord* blk_end);
+-
+- inline void freed(HeapWord* blk, size_t size);
+-
+ virtual HeapWord* block_start_unsafe(const void* addr);
+ virtual HeapWord* block_start_unsafe_const(const void* addr) const;
+
+- // Requires "addr" to be the start of a card and returns the
+- // start of the block that contains the given address.
+- HeapWord* block_start_careful(const void* addr) const;
+-
+- // If true, initialize array slots with no allocated blocks to zero.
+- // Otherwise, make them point back to the front.
+- bool init_to_zero() { return _init_to_zero; }
+-
+- // Verification & debugging - ensure that the offset table reflects the fact
+- // that the block [blk_start, blk_end) or [blk, blk + size) is a
+- // single block of storage. NOTE: can;t const this because of
+- // call to non-const do_block_internal() below.
+- inline void verify_single_block(HeapWord* blk_start, HeapWord* blk_end) {
+- if (VerifyBlockOffsetArray) {
+- do_block_internal(blk_start, blk_end, Action_check);
+- }
+- }
+-
+- inline void verify_single_block(HeapWord* blk, size_t size) {
+- verify_single_block(blk, blk + size);
+- }
+-
+ // Used by region verification. Checks that the contents of the
+ // BOT reflect that there's a single object that spans the address
+ // range [obj_start, obj_start + word_size); returns true if this is
+ // the case, returns false if it's not.
+ bool verify_for_object(HeapWord* obj_start, size_t word_size) const;
+
+- // Verify that the given block is before _unallocated_block
+- inline void verify_not_unallocated(HeapWord* blk_start,
+- HeapWord* blk_end) const {
+- if (BlockOffsetArrayUseUnallocatedBlock) {
+- assert(blk_start < blk_end, "Block inconsistency?");
+- assert(blk_end <= _unallocated_block, "_unallocated_block problem");
+- }
+- }
+-
+- inline void verify_not_unallocated(HeapWord* blk, size_t size) const {
+- verify_not_unallocated(blk, blk + size);
+- }
+-
+ void check_all_cards(size_t left_card, size_t right_card) const;
+
+ virtual void print_on(outputStream* out) PRODUCT_RETURN;
+@@ -495,6 +332,12 @@
+ blk_start, blk_end);
+ }
+
++ // Zero out the entry for _bottom (offset will be zero). Does not check for availability of the
++ // memory first.
++ void zero_bottom_entry_raw();
++ // Variant of initialize_threshold that does not check for availability of the
++ // memory first.
++ HeapWord* initialize_threshold_raw();
+ public:
+ G1BlockOffsetArrayContigSpace(G1BlockOffsetSharedArray* array, MemRegion mr);
+
+@@ -502,8 +345,10 @@
+ // bottom of the covered region.
+ HeapWord* initialize_threshold();
+
+- // Zero out the entry for _bottom (offset will be zero).
+- void zero_bottom_entry();
++ void reset_bot() {
++ zero_bottom_entry_raw();
++ initialize_threshold_raw();
++ }
+
+ // Return the next threshold, the point at which the table should be
+ // updated.
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,6 +26,8 @@
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_INLINE_HPP
+
+ #include "gc_implementation/g1/g1BlockOffsetTable.hpp"
++#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
++#include "gc_implementation/g1/heapRegion.inline.hpp"
+ #include "memory/space.hpp"
+
+ inline HeapWord* G1BlockOffsetTable::block_start(const void* addr) {
+@@ -45,14 +47,62 @@
+ }
+ }
+
++#define check_index(index, msg) \
++ assert((index) < (_reserved.word_size() >> LogN_words), \
++ err_msg("%s - index: "SIZE_FORMAT", _vs.committed_size: "SIZE_FORMAT, \
++ msg, (index), (_reserved.word_size() >> LogN_words))); \
++ assert(G1CollectedHeap::heap()->is_in_exact(address_for_index_raw(index)), \
++ err_msg("Index "SIZE_FORMAT" corresponding to "PTR_FORMAT \
++ " (%u) is not in committed area.", \
++ (index), \
++ p2i(address_for_index_raw(index)), \
++ G1CollectedHeap::heap()->addr_to_region(address_for_index_raw(index))));
++
++u_char G1BlockOffsetSharedArray::offset_array(size_t index) const {
++ check_index(index, "index out of range");
++ return _offset_array[index];
++}
++
++void G1BlockOffsetSharedArray::set_offset_array(size_t index, u_char offset) {
++ check_index(index, "index out of range");
++ set_offset_array_raw(index, offset);
++}
++
++void G1BlockOffsetSharedArray::set_offset_array(size_t index, HeapWord* high, HeapWord* low) {
++ check_index(index, "index out of range");
++ assert(high >= low, "addresses out of order");
++ size_t offset = pointer_delta(high, low);
++ check_offset(offset, "offset too large");
++ set_offset_array(index, (u_char)offset);
++}
++
++void G1BlockOffsetSharedArray::set_offset_array(size_t left, size_t right, u_char offset) {
++ check_index(right, "right index out of range");
++ assert(left <= right, "indexes out of order");
++ size_t num_cards = right - left + 1;
++ if (UseMemSetInBOT) {
++ memset(&_offset_array[left], offset, num_cards);
++ } else {
++ size_t i = left;
++ const size_t end = i + num_cards;
++ for (; i < end; i++) {
++ _offset_array[i] = offset;
++ }
++ }
++}
++
++// Variant of index_for that does not check the index for validity.
++inline size_t G1BlockOffsetSharedArray::index_for_raw(const void* p) const {
++ return pointer_delta((char*)p, _reserved.start(), sizeof(char)) >> LogN;
++}
++
+ inline size_t G1BlockOffsetSharedArray::index_for(const void* p) const {
+ char* pc = (char*)p;
+ assert(pc >= (char*)_reserved.start() &&
+ pc < (char*)_reserved.end(),
+ err_msg("p (" PTR_FORMAT ") not in reserved [" PTR_FORMAT ", " PTR_FORMAT ")",
+ p2i(p), p2i(_reserved.start()), p2i(_reserved.end())));
+- size_t delta = pointer_delta(pc, _reserved.start(), sizeof(char));
+- size_t result = delta >> LogN;
++ size_t result = index_for_raw(p);
+ check_index(result, "bad index from address");
+ return result;
+ }
+@@ -60,7 +110,7 @@
+ inline HeapWord*
+ G1BlockOffsetSharedArray::address_for_index(size_t index) const {
+ check_index(index, "index out of range");
+- HeapWord* result = _reserved.start() + (index << LogN_words);
++ HeapWord* result = address_for_index_raw(index);
+ assert(result >= _reserved.start() && result < _reserved.end(),
+ err_msg("bad address from index result " PTR_FORMAT
+ " _reserved.start() " PTR_FORMAT " _reserved.end() "
+@@ -69,6 +119,13 @@
+ return result;
+ }
+
++#undef check_index
++
++inline size_t
++G1BlockOffsetArray::block_size(const HeapWord* p) const {
++ return gsp()->block_size(p);
++}
++
+ inline HeapWord*
+ G1BlockOffsetArray::block_at_or_preceding(const void* addr,
+ bool has_max_index,
+@@ -88,7 +145,7 @@
+ // to go back by.
+ size_t n_cards_back = BlockOffsetArray::entry_to_cards_back(offset);
+ q -= (N_words * n_cards_back);
+- assert(q >= _sp->bottom(), "Went below bottom!");
++ assert(q >= gsp()->bottom(), "Went below bottom!");
+ index -= n_cards_back;
+ offset = _array->offset_array(index);
+ }
+@@ -101,21 +158,12 @@
+ G1BlockOffsetArray::
+ forward_to_block_containing_addr_const(HeapWord* q, HeapWord* n,
+ const void* addr) const {
+- if (csp() != NULL) {
+- if (addr >= csp()->top()) return csp()->top();
+- while (n <= addr) {
+- q = n;
+- oop obj = oop(q);
+- if (obj->klass_or_null() == NULL) return q;
+- n += obj->size();
+- }
+- } else {
+- while (n <= addr) {
+- q = n;
+- oop obj = oop(q);
+- if (obj->klass_or_null() == NULL) return q;
+- n += _sp->block_size(q);
+- }
++ if (addr >= gsp()->top()) return gsp()->top();
++ while (n <= addr) {
++ q = n;
++ oop obj = oop(q);
++ if (obj->klass_or_null() == NULL) return q;
++ n += block_size(q);
+ }
+ assert(q <= n, "wrong order for q and addr");
+ assert(addr < n, "wrong order for addr and n");
+@@ -126,7 +174,7 @@
+ G1BlockOffsetArray::forward_to_block_containing_addr(HeapWord* q,
+ const void* addr) {
+ if (oop(q)->klass_or_null() == NULL) return q;
+- HeapWord* n = q + _sp->block_size(q);
++ HeapWord* n = q + block_size(q);
+ // In the normal case, where the query "addr" is a card boundary, and the
+ // offset table chunks are the same size as cards, the block starting at
+ // "q" will contain addr, so the test below will fail, and we'll fall
+@@ -138,28 +186,4 @@
+ return q;
+ }
+
+-//////////////////////////////////////////////////////////////////////////
+-// BlockOffsetArrayNonContigSpace inlines
+-//////////////////////////////////////////////////////////////////////////
+-inline void G1BlockOffsetArray::freed(HeapWord* blk_start, HeapWord* blk_end) {
+- // Verify that the BOT shows [blk_start, blk_end) to be one block.
+- verify_single_block(blk_start, blk_end);
+- // adjust _unallocated_block upward or downward
+- // as appropriate
+- if (BlockOffsetArrayUseUnallocatedBlock) {
+- assert(_unallocated_block <= _end,
+- "Inconsistent value for _unallocated_block");
+- if (blk_end >= _unallocated_block && blk_start <= _unallocated_block) {
+- // CMS-specific note: a block abutting _unallocated_block to
+- // its left is being freed, a new block is being added or
+- // we are resetting following a compaction
+- _unallocated_block = blk_start;
+- }
+- }
+-}
+-
+-inline void G1BlockOffsetArray::freed(HeapWord* blk, size_t size) {
+- freed(blk, blk + size);
+-}
+-
+ #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_INLINE_HPP
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -33,31 +33,29 @@
+
+ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+
++void G1CardCountsMappingChangedListener::on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
++ if (zero_filled) {
++ return;
++ }
++ MemRegion mr(G1CollectedHeap::heap()->bottom_addr_for_region(start_idx), num_regions * HeapRegion::GrainWords);
++ _counts->clear_range(mr);
++}
++
+ void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) {
+ if (has_count_table()) {
+- assert(from_card_num >= 0 && from_card_num < _committed_max_card_num,
+- err_msg("from card num out of range: "SIZE_FORMAT, from_card_num));
+ assert(from_card_num < to_card_num,
+ err_msg("Wrong order? from: " SIZE_FORMAT ", to: "SIZE_FORMAT,
+ from_card_num, to_card_num));
+- assert(to_card_num <= _committed_max_card_num,
+- err_msg("to card num out of range: "
+- "to: "SIZE_FORMAT ", "
+- "max: "SIZE_FORMAT,
+- to_card_num, _committed_max_card_num));
+-
+- to_card_num = MIN2(_committed_max_card_num, to_card_num);
+-
+ Copy::fill_to_bytes(&_card_counts[from_card_num], (to_card_num - from_card_num));
+ }
+ }
+
+ G1CardCounts::G1CardCounts(G1CollectedHeap *g1h):
+- _g1h(g1h), _card_counts(NULL),
+- _reserved_max_card_num(0), _committed_max_card_num(0),
+- _committed_size(0) {}
++ _listener(), _g1h(g1h), _card_counts(NULL), _reserved_max_card_num(0) {
++ _listener.set_cardcounts(this);
++}
+
+-void G1CardCounts::initialize() {
++void G1CardCounts::initialize(G1RegionToSpaceMapper* mapper) {
+ assert(_g1h->max_capacity() > 0, "initialization order");
+ assert(_g1h->capacity() == 0, "initialization order");
+
+@@ -70,70 +68,9 @@
+ _ct_bs = _g1h->g1_barrier_set();
+ _ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start());
+
+- // Allocate/Reserve the counts table
+- size_t reserved_bytes = _g1h->max_capacity();
+- _reserved_max_card_num = reserved_bytes >> CardTableModRefBS::card_shift;
+-
+- size_t reserved_size = _reserved_max_card_num * sizeof(jbyte);
+- ReservedSpace rs(ReservedSpace::allocation_align_size_up(reserved_size));
+- if (!rs.is_reserved()) {
+- warning("Could not reserve enough space for the card counts table");
+- guarantee(!has_reserved_count_table(), "should be NULL");
+- return;
+- }
+-
+- MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
+-
+- _card_counts_storage.initialize(rs, 0);
+- _card_counts = (jubyte*) _card_counts_storage.low();
+- }
+-}
+-
+-void G1CardCounts::resize(size_t heap_capacity) {
+- // Expand the card counts table to handle a heap with the given capacity.
+-
+- if (!has_reserved_count_table()) {
+- // Don't expand if we failed to reserve the card counts table.
+- return;
+- }
+-
+- assert(_committed_size ==
+- ReservedSpace::allocation_align_size_up(_committed_size),
+- err_msg("Unaligned? committed_size: " SIZE_FORMAT, _committed_size));
+-
+- // Verify that the committed space for the card counts matches our
+- // committed max card num. Note for some allocation alignments, the
+- // amount of space actually committed for the counts table will be able
+- // to span more cards than the number spanned by the maximum heap.
+- size_t prev_committed_size = _committed_size;
+- size_t prev_committed_card_num = committed_to_card_num(prev_committed_size);
+-
+- assert(prev_committed_card_num == _committed_max_card_num,
+- err_msg("Card mismatch: "
+- "prev: " SIZE_FORMAT ", "
+- "committed: "SIZE_FORMAT", "
+- "reserved: "SIZE_FORMAT,
+- prev_committed_card_num, _committed_max_card_num, _reserved_max_card_num));
+-
+- size_t new_size = (heap_capacity >> CardTableModRefBS::card_shift) * sizeof(jbyte);
+- size_t new_committed_size = ReservedSpace::allocation_align_size_up(new_size);
+- size_t new_committed_card_num = committed_to_card_num(new_committed_size);
+-
+- if (_committed_max_card_num < new_committed_card_num) {
+- // we need to expand the backing store for the card counts
+- size_t expand_size = new_committed_size - prev_committed_size;
+-
+- if (!_card_counts_storage.expand_by(expand_size)) {
+- warning("Card counts table backing store commit failure");
+- return;
+- }
+- assert(_card_counts_storage.committed_size() == new_committed_size,
+- "expansion commit failure");
+-
+- _committed_size = new_committed_size;
+- _committed_max_card_num = new_committed_card_num;
+-
+- clear_range(prev_committed_card_num, _committed_max_card_num);
++ _card_counts = (jubyte*) mapper->reserved().start();
++ _reserved_max_card_num = mapper->reserved().byte_size();
++ mapper->set_mapping_changed_listener(&_listener);
+ }
+ }
+
+@@ -149,12 +86,13 @@
+ uint count = 0;
+ if (has_count_table()) {
+ size_t card_num = ptr_2_card_num(card_ptr);
+- if (card_num < _committed_max_card_num) {
+- count = (uint) _card_counts[card_num];
+- if (count < G1ConcRSHotCardLimit) {
+- _card_counts[card_num] =
+- (jubyte)(MIN2((uintx)(_card_counts[card_num] + 1), G1ConcRSHotCardLimit));
+- }
++ assert(card_num < _reserved_max_card_num,
++ err_msg("Card "SIZE_FORMAT" outside of card counts table (max size "SIZE_FORMAT")",
++ card_num, _reserved_max_card_num));
++ count = (uint) _card_counts[card_num];
++ if (count < G1ConcRSHotCardLimit) {
++ _card_counts[card_num] =
++ (jubyte)(MIN2((uintx)(_card_counts[card_num] + 1), G1ConcRSHotCardLimit));
+ }
+ }
+ return count;
+@@ -165,31 +103,23 @@
+ }
+
+ void G1CardCounts::clear_region(HeapRegion* hr) {
+- assert(!hr->isHumongous(), "Should have been cleared");
++ MemRegion mr(hr->bottom(), hr->end());
++ clear_range(mr);
++}
++
++void G1CardCounts::clear_range(MemRegion mr) {
+ if (has_count_table()) {
+- HeapWord* bottom = hr->bottom();
+-
+- // We use the last address in hr as hr could be the
+- // last region in the heap. In which case trying to find
+- // the card for hr->end() will be an OOB accesss to the
+- // card table.
+- HeapWord* last = hr->end() - 1;
+- assert(_g1h->g1_committed().contains(last),
+- err_msg("last not in committed: "
+- "last: " PTR_FORMAT ", "
+- "committed: [" PTR_FORMAT ", " PTR_FORMAT ")",
+- last,
+- _g1h->g1_committed().start(),
+- _g1h->g1_committed().end()));
+-
+- const jbyte* from_card_ptr = _ct_bs->byte_for_const(bottom);
+- const jbyte* last_card_ptr = _ct_bs->byte_for_const(last);
++ const jbyte* from_card_ptr = _ct_bs->byte_for_const(mr.start());
++ // We use the last address in the range as the range could represent the
++ // last region in the heap. In which case trying to find the card will be an
++ // OOB access to the card table.
++ const jbyte* last_card_ptr = _ct_bs->byte_for_const(mr.last());
+
+ #ifdef ASSERT
+ HeapWord* start_addr = _ct_bs->addr_for(from_card_ptr);
+- assert(start_addr == hr->bottom(), "alignment");
++ assert(start_addr == mr.start(), "MemRegion start must be aligned to a card.");
+ HeapWord* last_addr = _ct_bs->addr_for(last_card_ptr);
+- assert((last_addr + CardTableModRefBS::card_size_in_words) == hr->end(), "alignment");
++ assert((last_addr + CardTableModRefBS::card_size_in_words) == mr.end(), "MemRegion end must be aligned to a card.");
+ #endif // ASSERT
+
+ // Clear the counts for the (exclusive) card range.
+@@ -199,14 +129,22 @@
+ }
+ }
+
++class G1CardCountsClearClosure : public HeapRegionClosure {
++ private:
++ G1CardCounts* _card_counts;
++ public:
++ G1CardCountsClearClosure(G1CardCounts* card_counts) :
++ HeapRegionClosure(), _card_counts(card_counts) { }
++
++
++ virtual bool doHeapRegion(HeapRegion* r) {
++ _card_counts->clear_region(r);
++ return false;
++ }
++};
++
+ void G1CardCounts::clear_all() {
+ assert(SafepointSynchronize::is_at_safepoint(), "don't call this otherwise");
+- clear_range((size_t)0, _committed_max_card_num);
++ G1CardCountsClearClosure cl(this);
++ _g1h->heap_region_iterate(&cl);
+ }
+-
+-G1CardCounts::~G1CardCounts() {
+- if (has_reserved_count_table()) {
+- _card_counts_storage.release();
+- }
+-}
+-
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,14 +25,26 @@
+ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1CARDCOUNTS_HPP
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_G1CARDCOUNTS_HPP
+
++#include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
+ #include "memory/allocation.hpp"
+ #include "runtime/virtualspace.hpp"
+ #include "utilities/globalDefinitions.hpp"
+
+ class CardTableModRefBS;
++class G1CardCounts;
+ class G1CollectedHeap;
++class G1RegionToSpaceMapper;
+ class HeapRegion;
+
++class G1CardCountsMappingChangedListener : public G1MappingChangedListener {
++ private:
++ G1CardCounts* _counts;
++ public:
++ void set_cardcounts(G1CardCounts* counts) { _counts = counts; }
++
++ virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled);
++};
++
+ // Table to track the number of times a card has been refined. Once
+ // a card has been refined a certain number of times, it is
+ // considered 'hot' and its refinement is delayed by inserting the
+@@ -41,6 +53,8 @@
+ // is 'drained' during the next evacuation pause.
+
+ class G1CardCounts: public CHeapObj<mtGC> {
++ G1CardCountsMappingChangedListener _listener;
++
+ G1CollectedHeap* _g1h;
+
+ // The table of counts
+@@ -49,27 +63,18 @@
+ // Max capacity of the reserved space for the counts table
+ size_t _reserved_max_card_num;
+
+- // Max capacity of the committed space for the counts table
+- size_t _committed_max_card_num;
+-
+- // Size of committed space for the counts table
+- size_t _committed_size;
+-
+ // CardTable bottom.
+ const jbyte* _ct_bot;
+
+ // Barrier set
+ CardTableModRefBS* _ct_bs;
+
+- // The virtual memory backing the counts table
+- VirtualSpace _card_counts_storage;
+-
+ // Returns true if the card counts table has been reserved.
+ bool has_reserved_count_table() { return _card_counts != NULL; }
+
+ // Returns true if the card counts table has been reserved and committed.
+ bool has_count_table() {
+- return has_reserved_count_table() && _committed_max_card_num > 0;
++ return has_reserved_count_table();
+ }
+
+ size_t ptr_2_card_num(const jbyte* card_ptr) {
+@@ -79,37 +84,24 @@
+ "_ct_bot: " PTR_FORMAT,
+ p2i(card_ptr), p2i(_ct_bot)));
+ size_t card_num = pointer_delta(card_ptr, _ct_bot, sizeof(jbyte));
+- assert(card_num >= 0 && card_num < _committed_max_card_num,
++ assert(card_num >= 0 && card_num < _reserved_max_card_num,
+ err_msg("card pointer out of range: " PTR_FORMAT, p2i(card_ptr)));
+ return card_num;
+ }
+
+ jbyte* card_num_2_ptr(size_t card_num) {
+- assert(card_num >= 0 && card_num < _committed_max_card_num,
++ assert(card_num >= 0 && card_num < _reserved_max_card_num,
+ err_msg("card num out of range: "SIZE_FORMAT, card_num));
+ return (jbyte*) (_ct_bot + card_num);
+ }
+
+- // Helper routine.
+- // Returns the number of cards that can be counted by the given committed
+- // table size, with a maximum of the number of cards spanned by the max
+- // capacity of the heap.
+- size_t committed_to_card_num(size_t committed_size) {
+- return MIN2(_reserved_max_card_num, committed_size / sizeof(jbyte));
+- }
+-
+ // Clear the counts table for the given (exclusive) index range.
+ void clear_range(size_t from_card_num, size_t to_card_num);
+
+ public:
+ G1CardCounts(G1CollectedHeap* g1h);
+- ~G1CardCounts();
+
+- void initialize();
+-
+- // Resize the committed space for the card counts table in
+- // response to a resize of the committed space for the heap.
+- void resize(size_t heap_capacity);
++ void initialize(G1RegionToSpaceMapper* mapper);
+
+ // Increments the refinement count for the given card.
+ // Returns the pre-increment count value.
+@@ -122,8 +114,10 @@
+ // Clears the card counts for the cards spanned by the region
+ void clear_region(HeapRegion* hr);
+
++ // Clears the card counts for the cards spanned by the MemRegion
++ void clear_range(MemRegion mr);
++
+ // Clear the entire card counts table during GC.
+- // Updates the policy stats with the duration.
+ void clear_all();
+ };
+
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -22,298 +22,386 @@
+ *
+ */
+
+-
+ #include "precompiled.hpp"
++#include "code/codeCache.hpp"
+ #include "code/nmethod.hpp"
+ #include "gc_implementation/g1/g1CodeCacheRemSet.hpp"
++#include "gc_implementation/g1/heapRegion.hpp"
++#include "memory/heap.hpp"
+ #include "memory/iterator.hpp"
++#include "oops/oop.inline.hpp"
++#include "utilities/hashtable.inline.hpp"
++#include "utilities/stack.inline.hpp"
+
+ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+
+-G1CodeRootChunk::G1CodeRootChunk() : _top(NULL), _next(NULL), _prev(NULL) {
+- _top = bottom();
++class CodeRootSetTable : public Hashtable<nmethod*, mtGC> {
++ friend class G1CodeRootSetTest;
++ typedef HashtableEntry<nmethod*, mtGC> Entry;
++
++ static CodeRootSetTable* volatile _purge_list;
++
++ CodeRootSetTable* _purge_next;
++
++ unsigned int compute_hash(nmethod* nm) {
++ uintptr_t hash = (uintptr_t)nm;
++ return hash ^ (hash >> 7); // code heap blocks are 128byte aligned
++ }
++
++ void remove_entry(Entry* e, Entry* previous);
++ Entry* new_entry(nmethod* nm);
++
++ public:
++ CodeRootSetTable(int size) : Hashtable<nmethod*, mtGC>(size, sizeof(Entry)), _purge_next(NULL) {}
++ ~CodeRootSetTable();
++
++ // Needs to be protected locks
++ bool add(nmethod* nm);
++ bool remove(nmethod* nm);
++
++ // Can be called without locking
++ bool contains(nmethod* nm);
++
++ int entry_size() const { return BasicHashtable<mtGC>::entry_size(); }
++
++ void copy_to(CodeRootSetTable* new_table);
++ void nmethods_do(CodeBlobClosure* blk);
++
++ template<typename CB>
++ int remove_if(CB& should_remove);
++
++ static void purge_list_append(CodeRootSetTable* tbl);
++ static void purge();
++
++ static size_t static_mem_size() {
++ return sizeof(_purge_list);
++ }
++};
++
++CodeRootSetTable* volatile CodeRootSetTable::_purge_list = NULL;
++
++CodeRootSetTable::Entry* CodeRootSetTable::new_entry(nmethod* nm) {
++ unsigned int hash = compute_hash(nm);
++ Entry* entry = (Entry*) new_entry_free_list();
++ if (entry == NULL) {
++ entry = (Entry*) NEW_C_HEAP_ARRAY2(char, entry_size(), mtGC, CURRENT_PC);
++ }
++ entry->set_next(NULL);
++ entry->set_hash(hash);
++ entry->set_literal(nm);
++ return entry;
+ }
+
+-void G1CodeRootChunk::reset() {
+- _next = _prev = NULL;
+- _top = bottom();
++void CodeRootSetTable::remove_entry(Entry* e, Entry* previous) {
++ int index = hash_to_index(e->hash());
++ assert((e == bucket(index)) == (previous == NULL), "if e is the first entry then previous should be null");
++
++ if (previous == NULL) {
++ set_entry(index, e->next());
++ } else {
++ previous->set_next(e->next());
++ }
++ free_entry(e);
+ }
+
+-void G1CodeRootChunk::nmethods_do(CodeBlobClosure* cl) {
+- nmethod** cur = bottom();
+- while (cur != _top) {
+- cl->do_code_blob(*cur);
+- cur++;
++CodeRootSetTable::~CodeRootSetTable() {
++ for (int index = 0; index < table_size(); ++index) {
++ for (Entry* e = bucket(index); e != NULL; ) {
++ Entry* to_remove = e;
++ // read next before freeing.
++ e = e->next();
++ unlink_entry(to_remove);
++ FREE_C_HEAP_ARRAY(char, to_remove, mtGC);
++ }
++ }
++ assert(number_of_entries() == 0, "should have removed all entries");
++ free_buckets();
++ for (BasicHashtableEntry<mtGC>* e = new_entry_free_list(); e != NULL; e = new_entry_free_list()) {
++ FREE_C_HEAP_ARRAY(char, e, mtGC);
+ }
+ }
+
+-FreeList<G1CodeRootChunk> G1CodeRootSet::_free_list;
+-size_t G1CodeRootSet::_num_chunks_handed_out = 0;
+-
+-G1CodeRootChunk* G1CodeRootSet::new_chunk() {
+- G1CodeRootChunk* result = _free_list.get_chunk_at_head();
+- if (result == NULL) {
+- result = new G1CodeRootChunk();
++bool CodeRootSetTable::add(nmethod* nm) {
++ if (!contains(nm)) {
++ Entry* e = new_entry(nm);
++ int index = hash_to_index(e->hash());
++ add_entry(index, e);
++ return true;
+ }
+- G1CodeRootSet::_num_chunks_handed_out++;
+- result->reset();
+- return result;
++ return false;
+ }
+
+-void G1CodeRootSet::free_chunk(G1CodeRootChunk* chunk) {
+- _free_list.return_chunk_at_head(chunk);
+- G1CodeRootSet::_num_chunks_handed_out--;
++bool CodeRootSetTable::contains(nmethod* nm) {
++ int index = hash_to_index(compute_hash(nm));
++ for (Entry* e = bucket(index); e != NULL; e = e->next()) {
++ if (e->literal() == nm) {
++ return true;
++ }
++ }
++ return false;
+ }
+
+-void G1CodeRootSet::free_all_chunks(FreeList<G1CodeRootChunk>* list) {
+- G1CodeRootSet::_num_chunks_handed_out -= list->count();
+- _free_list.prepend(list);
++bool CodeRootSetTable::remove(nmethod* nm) {
++ int index = hash_to_index(compute_hash(nm));
++ Entry* previous = NULL;
++ for (Entry* e = bucket(index); e != NULL; previous = e, e = e->next()) {
++ if (e->literal() == nm) {
++ remove_entry(e, previous);
++ return true;
++ }
++ }
++ return false;
+ }
+
+-void G1CodeRootSet::purge_chunks(size_t keep_ratio) {
+- size_t keep = G1CodeRootSet::_num_chunks_handed_out * keep_ratio / 100;
++void CodeRootSetTable::copy_to(CodeRootSetTable* new_table) {
++ for (int index = 0; index < table_size(); ++index) {
++ for (Entry* e = bucket(index); e != NULL; e = e->next()) {
++ new_table->add(e->literal());
++ }
++ }
++ new_table->copy_freelist(this);
++}
+
+- if (keep >= (size_t)_free_list.count()) {
+- return;
+- }
+-
+- FreeList<G1CodeRootChunk> temp;
+- temp.initialize();
+- temp.set_size(G1CodeRootChunk::word_size());
+-
+- _free_list.getFirstNChunksFromList((size_t)_free_list.count() - keep, &temp);
+-
+- G1CodeRootChunk* cur = temp.get_chunk_at_head();
+- while (cur != NULL) {
+- delete cur;
+- cur = temp.get_chunk_at_head();
++void CodeRootSetTable::nmethods_do(CodeBlobClosure* blk) {
++ for (int index = 0; index < table_size(); ++index) {
++ for (Entry* e = bucket(index); e != NULL; e = e->next()) {
++ blk->do_code_blob(e->literal());
++ }
+ }
+ }
+
+-size_t G1CodeRootSet::static_mem_size() {
+- return sizeof(_free_list) + sizeof(_num_chunks_handed_out);
+-}
+-
+-size_t G1CodeRootSet::fl_mem_size() {
+- return _free_list.count() * _free_list.size();
+-}
+-
+-void G1CodeRootSet::initialize() {
+- _free_list.initialize();
+- _free_list.set_size(G1CodeRootChunk::word_size());
+-}
+-
+-G1CodeRootSet::G1CodeRootSet() : _list(), _length(0) {
+- _list.initialize();
+- _list.set_size(G1CodeRootChunk::word_size());
++template<typename CB>
++int CodeRootSetTable::remove_if(CB& should_remove) {
++ int num_removed = 0;
++ for (int index = 0; index < table_size(); ++index) {
++ Entry* previous = NULL;
++ Entry* e = bucket(index);
++ while (e != NULL) {
++ Entry* next = e->next();
++ if (should_remove(e->literal())) {
++ remove_entry(e, previous);
++ ++num_removed;
++ } else {
++ previous = e;
++ }
++ e = next;
++ }
++ }
++ return num_removed;
+ }
+
+ G1CodeRootSet::~G1CodeRootSet() {
+- clear();
++ delete _table;
++}
++
++CodeRootSetTable* G1CodeRootSet::load_acquire_table() {
++ return (CodeRootSetTable*) OrderAccess::load_ptr_acquire(&_table);
++}
++
++void G1CodeRootSet::allocate_small_table() {
++ _table = new CodeRootSetTable(SmallSize);
++}
++
++void CodeRootSetTable::purge_list_append(CodeRootSetTable* table) {
++ for (;;) {
++ table->_purge_next = _purge_list;
++ CodeRootSetTable* old = (CodeRootSetTable*) Atomic::cmpxchg_ptr(table, &_purge_list, table->_purge_next);
++ if (old == table->_purge_next) {
++ break;
++ }
++ }
++}
++
++void CodeRootSetTable::purge() {
++ CodeRootSetTable* table = _purge_list;
++ _purge_list = NULL;
++ while (table != NULL) {
++ CodeRootSetTable* to_purge = table;
++ table = table->_purge_next;
++ delete to_purge;
++ }
++}
++
++void G1CodeRootSet::move_to_large() {
++ CodeRootSetTable* temp = new CodeRootSetTable(LargeSize);
++
++ _table->copy_to(temp);
++
++ CodeRootSetTable::purge_list_append(_table);
++
++ OrderAccess::release_store_ptr(&_table, temp);
++}
++
++
++void G1CodeRootSet::purge() {
++ CodeRootSetTable::purge();
++}
++
++size_t G1CodeRootSet::static_mem_size() {
++ return CodeRootSetTable::static_mem_size();
+ }
+
+ void G1CodeRootSet::add(nmethod* method) {
+- if (!contains(method)) {
+- // Try to add the nmethod. If there is not enough space, get a new chunk.
+- if (_list.head() == NULL || _list.head()->is_full()) {
+- G1CodeRootChunk* cur = new_chunk();
+- _list.return_chunk_at_head(cur);
+- }
+- bool result = _list.head()->add(method);
+- guarantee(result, err_msg("Not able to add nmethod "PTR_FORMAT" to newly allocated chunk.", method));
+- _length++;
++ bool added = false;
++ if (is_empty()) {
++ allocate_small_table();
++ }
++ added = _table->add(method);
++ if (_length == Threshold) {
++ move_to_large();
++ }
++ if (added) {
++ ++_length;
+ }
+ }
+
+-void G1CodeRootSet::remove(nmethod* method) {
+- G1CodeRootChunk* found = find(method);
+- if (found != NULL) {
+- bool result = found->remove(method);
+- guarantee(result, err_msg("could not find nmethod "PTR_FORMAT" during removal although we previously found it", method));
+- // eventually free completely emptied chunk
+- if (found->is_empty()) {
+- _list.remove_chunk(found);
+- free(found);
++bool G1CodeRootSet::remove(nmethod* method) {
++ bool removed = false;
++ if (_table != NULL) {
++ removed = _table->remove(method);
++ }
++ if (removed) {
++ _length--;
++ if (_length == 0) {
++ clear();
+ }
+- _length--;
+ }
+- assert(!contains(method), err_msg(PTR_FORMAT" still contains nmethod "PTR_FORMAT, this, method));
+-}
+-
+-nmethod* G1CodeRootSet::pop() {
+- do {
+- G1CodeRootChunk* cur = _list.head();
+- if (cur == NULL) {
+- assert(_length == 0, "when there are no chunks, there should be no elements");
+- return NULL;
+- }
+- nmethod* result = cur->pop();
+- if (result != NULL) {
+- _length--;
+- return result;
+- } else {
+- free(_list.get_chunk_at_head());
+- }
+- } while (true);
+-}
+-
+-G1CodeRootChunk* G1CodeRootSet::find(nmethod* method) {
+- G1CodeRootChunk* cur = _list.head();
+- while (cur != NULL) {
+- if (cur->contains(method)) {
+- return cur;
+- }
+- cur = (G1CodeRootChunk*)cur->next();
+- }
+- return NULL;
+-}
+-
+-void G1CodeRootSet::free(G1CodeRootChunk* chunk) {
+- free_chunk(chunk);
++ return removed;
+ }
+
+ bool G1CodeRootSet::contains(nmethod* method) {
+- return find(method) != NULL;
++ CodeRootSetTable* table = load_acquire_table();
++ if (table != NULL) {
++ return table->contains(method);
++ }
++ return false;
+ }
+
+ void G1CodeRootSet::clear() {
+- free_all_chunks(&_list);
++ delete _table;
++ _table = NULL;
+ _length = 0;
+ }
+
++size_t G1CodeRootSet::mem_size() {
++ return sizeof(*this) +
++ (_table != NULL ? sizeof(CodeRootSetTable) + _table->entry_size() * _length : 0);
++}
++
+ void G1CodeRootSet::nmethods_do(CodeBlobClosure* blk) const {
+- G1CodeRootChunk* cur = _list.head();
+- while (cur != NULL) {
+- cur->nmethods_do(blk);
+- cur = (G1CodeRootChunk*)cur->next();
++ if (_table != NULL) {
++ _table->nmethods_do(blk);
+ }
+ }
+
+-size_t G1CodeRootSet::mem_size() {
+- return sizeof(this) + _list.count() * _list.size();
++class CleanCallback : public StackObj {
++ class PointsIntoHRDetectionClosure : public OopClosure {
++ HeapRegion* _hr;
++ public:
++ bool _points_into;
++ PointsIntoHRDetectionClosure(HeapRegion* hr) : _hr(hr), _points_into(false) {}
++
++ void do_oop(narrowOop* o) {
++ do_oop_work(o);
++ }
++
++ void do_oop(oop* o) {
++ do_oop_work(o);
++ }
++
++ template <typename T>
++ void do_oop_work(T* p) {
++ if (_hr->is_in(oopDesc::load_decode_heap_oop(p))) {
++ _points_into = true;
++ }
++ }
++ };
++
++ PointsIntoHRDetectionClosure _detector;
++ CodeBlobToOopClosure _blobs;
++
++ public:
++ CleanCallback(HeapRegion* hr) : _detector(hr), _blobs(&_detector, !CodeBlobToOopClosure::FixRelocations) {}
++
++ bool operator() (nmethod* nm) {
++ _detector._points_into = false;
++ _blobs.do_code_blob(nm);
++ return !_detector._points_into;
++ }
++};
++
++void G1CodeRootSet::clean(HeapRegion* owner) {
++ CleanCallback should_clean(owner);
++ if (_table != NULL) {
++ int removed = _table->remove_if(should_clean);
++ assert((size_t)removed <= _length, "impossible");
++ _length -= removed;
++ }
++ if (_length == 0) {
++ clear();
++ }
+ }
+
+ #ifndef PRODUCT
+
+-void G1CodeRootSet::test() {
+- initialize();
++class G1CodeRootSetTest {
++ public:
++ static void test() {
++ {
++ G1CodeRootSet set1;
++ assert(set1.is_empty(), "Code root set must be initially empty but is not.");
+
+- assert(_free_list.count() == 0, "Free List must be empty");
+- assert(_num_chunks_handed_out == 0, "No elements must have been handed out yet");
++ assert(G1CodeRootSet::static_mem_size() == sizeof(void*),
++ err_msg("The code root set's static memory usage is incorrect, "SIZE_FORMAT" bytes", G1CodeRootSet::static_mem_size()));
+
+- // The number of chunks that we allocate for purge testing.
+- size_t const num_chunks = 10;
+- {
+- G1CodeRootSet set1;
+- assert(set1.is_empty(), "Code root set must be initially empty but is not.");
++ set1.add((nmethod*)1);
++ assert(set1.length() == 1, err_msg("Added exactly one element, but set contains "
++ SIZE_FORMAT" elements", set1.length()));
+
+- set1.add((nmethod*)1);
+- assert(_num_chunks_handed_out == 1,
+- err_msg("Must have allocated and handed out one chunk, but handed out "
+- SIZE_FORMAT" chunks", _num_chunks_handed_out));
+- assert(set1.length() == 1, err_msg("Added exactly one element, but set contains "
+- SIZE_FORMAT" elements", set1.length()));
++ const size_t num_to_add = (size_t)G1CodeRootSet::Threshold + 1;
+
+- // G1CodeRootChunk::word_size() is larger than G1CodeRootChunk::num_entries which
+- // we cannot access.
+- for (uint i = 0; i < G1CodeRootChunk::word_size() + 1; i++) {
+- set1.add((nmethod*)1);
+- }
+- assert(_num_chunks_handed_out == 1,
+- err_msg("Duplicate detection must have prevented allocation of further "
+- "chunks but contains "SIZE_FORMAT, _num_chunks_handed_out));
+- assert(set1.length() == 1,
+- err_msg("Duplicate detection should not have increased the set size but "
+- "is "SIZE_FORMAT, set1.length()));
++ for (size_t i = 1; i <= num_to_add; i++) {
++ set1.add((nmethod*)1);
++ }
++ assert(set1.length() == 1,
++ err_msg("Duplicate detection should not have increased the set size but "
++ "is "SIZE_FORMAT, set1.length()));
+
+- size_t num_total_after_add = G1CodeRootChunk::word_size() + 1;
+- for (size_t i = 0; i < num_total_after_add - 1; i++) {
+- set1.add((nmethod*)(2 + i));
+- }
+- assert(_num_chunks_handed_out > 1,
+- "After adding more code roots, more than one chunks should have been handed out");
+- assert(set1.length() == num_total_after_add,
+- err_msg("After adding in total "SIZE_FORMAT" distinct code roots, they "
+- "need to be in the set, but there are only "SIZE_FORMAT,
+- num_total_after_add, set1.length()));
++ for (size_t i = 2; i <= num_to_add; i++) {
++ set1.add((nmethod*)(uintptr_t)(i));
++ }
++ assert(set1.length() == num_to_add,
++ err_msg("After adding in total "SIZE_FORMAT" distinct code roots, they "
++ "need to be in the set, but there are only "SIZE_FORMAT,
++ num_to_add, set1.length()));
+
+- size_t num_popped = 0;
+- while (set1.pop() != NULL) {
+- num_popped++;
+- }
+- assert(num_popped == num_total_after_add,
+- err_msg("Managed to pop "SIZE_FORMAT" code roots, but only "SIZE_FORMAT" "
+- "were added", num_popped, num_total_after_add));
+- assert(_num_chunks_handed_out == 0,
+- err_msg("After popping all elements, all chunks must have been returned "
+- "but are still "SIZE_FORMAT, _num_chunks_handed_out));
++ assert(CodeRootSetTable::_purge_list != NULL, "should have grown to large hashtable");
+
+- purge_chunks(0);
+- assert(_free_list.count() == 0,
+- err_msg("After purging everything, the free list must be empty but still "
+- "contains "SIZE_FORMAT" chunks", _free_list.count()));
++ size_t num_popped = 0;
++ for (size_t i = 1; i <= num_to_add; i++) {
++ bool removed = set1.remove((nmethod*)i);
++ if (removed) {
++ num_popped += 1;
++ } else {
++ break;
++ }
++ }
++ assert(num_popped == num_to_add,
++ err_msg("Managed to pop "SIZE_FORMAT" code roots, but only "SIZE_FORMAT" "
++ "were added", num_popped, num_to_add));
++ assert(CodeRootSetTable::_purge_list != NULL, "should have grown to large hashtable");
+
+- // Add some more handed out chunks.
+- size_t i = 0;
+- while (_num_chunks_handed_out < num_chunks) {
+- set1.add((nmethod*)i);
+- i++;
++ G1CodeRootSet::purge();
++
++ assert(CodeRootSetTable::_purge_list == NULL, "should have purged old small tables");
++
+ }
+
+- {
+- // Generate chunks on the free list.
+- G1CodeRootSet set2;
+- size_t i = 0;
+- while (_num_chunks_handed_out < num_chunks * 2) {
+- set2.add((nmethod*)i);
+- i++;
+- }
+- // Exit of the scope of the set2 object will call the destructor that generates
+- // num_chunks elements on the free list.
+- }
++ }
++};
+
+- assert(_num_chunks_handed_out == num_chunks,
+- err_msg("Deletion of the second set must have resulted in giving back "
+- "those, but there is still "SIZE_FORMAT" handed out, expecting "
+- SIZE_FORMAT, _num_chunks_handed_out, num_chunks));
+- assert((size_t)_free_list.count() == num_chunks,
+- err_msg("After freeing "SIZE_FORMAT" chunks, they must be on the free list "
+- "but there are only "SIZE_FORMAT, num_chunks, _free_list.count()));
+-
+- size_t const test_percentage = 50;
+- purge_chunks(test_percentage);
+- assert(_num_chunks_handed_out == num_chunks,
+- err_msg("Purging must not hand out chunks but there are "SIZE_FORMAT,
+- _num_chunks_handed_out));
+- assert((size_t)_free_list.count() == (ssize_t)(num_chunks * test_percentage / 100),
+- err_msg("Must have purged "SIZE_FORMAT" percent of "SIZE_FORMAT" chunks"
+- "but there are "SSIZE_FORMAT, test_percentage, num_chunks,
+- _free_list.count()));
+- // Purge the remainder of the chunks on the free list.
+- purge_chunks(0);
+- assert(_free_list.count() == 0, "Free List must be empty");
+- assert(_num_chunks_handed_out == num_chunks,
+- err_msg("Expected to be "SIZE_FORMAT" chunks handed out from the first set "
+- "but there are "SIZE_FORMAT, num_chunks, _num_chunks_handed_out));
+-
+- // Exit of the scope of the set1 object will call the destructor that generates
+- // num_chunks additional elements on the free list.
+- }
+-
+- assert(_num_chunks_handed_out == 0,
+- err_msg("Deletion of the only set must have resulted in no chunks handed "
+- "out, but there is still "SIZE_FORMAT" handed out", _num_chunks_handed_out));
+- assert((size_t)_free_list.count() == num_chunks,
+- err_msg("After freeing "SIZE_FORMAT" chunks, they must be on the free list "
+- "but there are only "SSIZE_FORMAT, num_chunks, _free_list.count()));
+-
+- // Restore initial state.
+- purge_chunks(0);
+- assert(_free_list.count() == 0, "Free List must be empty");
+- assert(_num_chunks_handed_out == 0, "No elements must have been handed out yet");
++void TestCodeCacheRemSet_test() {
++ G1CodeRootSetTest::test();
+ }
+
+-void TestCodeCacheRemSet_test() {
+- G1CodeRootSet::test();
+-}
+ #endif
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,155 +26,57 @@
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_G1CODECACHEREMSET_HPP
+
+ #include "memory/allocation.hpp"
+-#include "memory/freeList.hpp"
+-#include "runtime/globals.hpp"
+
+ class CodeBlobClosure;
+-
+-class G1CodeRootChunk : public CHeapObj<mtGC> {
+- private:
+- static const int NUM_ENTRIES = 32;
+- public:
+- G1CodeRootChunk* _next;
+- G1CodeRootChunk* _prev;
+-
+- nmethod** _top;
+-
+- nmethod* _data[NUM_ENTRIES];
+-
+- nmethod** bottom() const {
+- return (nmethod**) &(_data[0]);
+- }
+-
+- nmethod** end() const {
+- return (nmethod**) &(_data[NUM_ENTRIES]);
+- }
+-
+- public:
+- G1CodeRootChunk();
+- ~G1CodeRootChunk() {}
+-
+- static size_t word_size() { return (size_t)(align_size_up_(sizeof(G1CodeRootChunk), HeapWordSize) / HeapWordSize); }
+-
+- // FreeList "interface" methods
+-
+- G1CodeRootChunk* next() const { return _next; }
+- G1CodeRootChunk* prev() const { return _prev; }
+- void set_next(G1CodeRootChunk* v) { _next = v; assert(v != this, "Boom");}
+- void set_prev(G1CodeRootChunk* v) { _prev = v; assert(v != this, "Boom");}
+- void clear_next() { set_next(NULL); }
+- void clear_prev() { set_prev(NULL); }
+-
+- size_t size() const { return word_size(); }
+-
+- void link_next(G1CodeRootChunk* ptr) { set_next(ptr); }
+- void link_prev(G1CodeRootChunk* ptr) { set_prev(ptr); }
+- void link_after(G1CodeRootChunk* ptr) {
+- link_next(ptr);
+- if (ptr != NULL) ptr->link_prev((G1CodeRootChunk*)this);
+- }
+-
+- bool is_free() { return true; }
+-
+- // New G1CodeRootChunk routines
+-
+- void reset();
+-
+- bool is_empty() const {
+- return _top == bottom();
+- }
+-
+- bool is_full() const {
+- return _top == (nmethod**)end();
+- }
+-
+- bool contains(nmethod* method) {
+- nmethod** cur = bottom();
+- while (cur != _top) {
+- if (*cur == method) return true;
+- cur++;
+- }
+- return false;
+- }
+-
+- bool add(nmethod* method) {
+- if (is_full()) return false;
+- *_top = method;
+- _top++;
+- return true;
+- }
+-
+- bool remove(nmethod* method) {
+- nmethod** cur = bottom();
+- while (cur != _top) {
+- if (*cur == method) {
+- memmove(cur, cur + 1, (_top - (cur + 1)) * sizeof(nmethod**));
+- _top--;
+- return true;
+- }
+- cur++;
+- }
+- return false;
+- }
+-
+- void nmethods_do(CodeBlobClosure* blk);
+-
+- nmethod* pop() {
+- if (is_empty()) {
+- return NULL;
+- }
+- _top--;
+- return *_top;
+- }
+-};
++class CodeRootSetTable;
++class HeapRegion;
++class nmethod;
+
+ // Implements storage for a set of code roots.
+ // All methods that modify the set are not thread-safe except if otherwise noted.
+ class G1CodeRootSet VALUE_OBJ_CLASS_SPEC {
++ friend class G1CodeRootSetTest;
+ private:
+- // Global free chunk list management
+- static FreeList<G1CodeRootChunk> _free_list;
+- // Total number of chunks handed out
+- static size_t _num_chunks_handed_out;
+
+- static G1CodeRootChunk* new_chunk();
+- static void free_chunk(G1CodeRootChunk* chunk);
+- // Free all elements of the given list.
+- static void free_all_chunks(FreeList<G1CodeRootChunk>* list);
++ const static size_t SmallSize = 32;
++ const static size_t Threshold = 24;
++ const static size_t LargeSize = 512;
+
+- // Return the chunk that contains the given nmethod, NULL otherwise.
+- // Scans the list of chunks backwards, as this method is used to add new
+- // entries, which are typically added in bulk for a single nmethod.
+- G1CodeRootChunk* find(nmethod* method);
+- void free(G1CodeRootChunk* chunk);
++ CodeRootSetTable* _table;
++ CodeRootSetTable* load_acquire_table();
+
+ size_t _length;
+- FreeList<G1CodeRootChunk> _list;
++
++ void move_to_large();
++ void allocate_small_table();
+
+ public:
+- G1CodeRootSet();
++ G1CodeRootSet() : _table(NULL), _length(0) {}
+ ~G1CodeRootSet();
+
+- static void initialize();
+- static void purge_chunks(size_t keep_ratio);
++ static void purge();
+
+ static size_t static_mem_size();
+- static size_t fl_mem_size();
+
+- // Search for the code blob from the recently allocated ones to find duplicates more quickly, as this
+- // method is likely to be repeatedly called with the same nmethod.
+ void add(nmethod* method);
+
+- void remove(nmethod* method);
+- nmethod* pop();
++ bool remove(nmethod* method);
+
++ // Safe to call without synchronization, but may return false negatives.
+ bool contains(nmethod* method);
+
+ void clear();
+
+ void nmethods_do(CodeBlobClosure* blk) const;
+
+- bool is_empty() { return length() == 0; }
++ // Remove all nmethods which no longer contain pointers into our "owner" region
++ void clean(HeapRegion* owner);
++
++ bool is_empty() {
++ bool empty = length() == 0;
++ assert(empty == (_table == NULL), "is empty only if table is deallocated");
++ return empty;
++ }
+
+ // Length in elements
+ size_t length() const { return _length; }
+@@ -182,7 +84,6 @@
+ // Memory size in bytes taken by this set.
+ size_t mem_size();
+
+- static void test() PRODUCT_RETURN;
+ };
+
+ #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1CODECACHEREMSET_HPP
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -27,6 +27,7 @@
+ #endif
+
+ #include "precompiled.hpp"
++#include "classfile/metadataOnStackMark.hpp"
+ #include "code/codeCache.hpp"
+ #include "code/icBuffer.hpp"
+ #include "gc_implementation/g1/bufferingOopClosure.hpp"
+@@ -42,26 +43,29 @@
+ #include "gc_implementation/g1/g1Log.hpp"
+ #include "gc_implementation/g1/g1MarkSweep.hpp"
+ #include "gc_implementation/g1/g1OopClosures.inline.hpp"
++#include "gc_implementation/g1/g1ParScanThreadState.inline.hpp"
++#include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
+ #include "gc_implementation/g1/g1RemSet.inline.hpp"
+ #include "gc_implementation/g1/g1StringDedup.hpp"
+ #include "gc_implementation/g1/g1YCTypes.hpp"
+ #include "gc_implementation/g1/heapRegion.inline.hpp"
+ #include "gc_implementation/g1/heapRegionRemSet.hpp"
+-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
++#include "gc_implementation/g1/heapRegionSet.inline.hpp"
+ #include "gc_implementation/g1/vm_operations_g1.hpp"
+ #include "gc_implementation/shared/gcHeapSummary.hpp"
+ #include "gc_implementation/shared/gcTimer.hpp"
+ #include "gc_implementation/shared/gcTrace.hpp"
+ #include "gc_implementation/shared/gcTraceTime.hpp"
+ #include "gc_implementation/shared/isGCActiveMark.hpp"
++#include "memory/allocation.hpp"
+ #include "memory/gcLocker.inline.hpp"
+ #include "memory/generationSpec.hpp"
+ #include "memory/iterator.hpp"
+ #include "memory/referenceProcessor.hpp"
+ #include "oops/oop.inline.hpp"
+ #include "oops/oop.pcgc.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/vmThread.hpp"
+-#include "utilities/ticks.hpp"
+
+ size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0;
+
+@@ -86,66 +90,64 @@
+ // G1ParVerifyTask uses heap_region_par_iterate_chunked() for parallelism.
+ // The number of GC workers is passed to heap_region_par_iterate_chunked().
+ // It does use run_task() which sets _n_workers in the task.
+-// G1ParTask executes g1_process_strong_roots() ->
+-// SharedHeap::process_strong_roots() which calls eventually to
++// G1ParTask executes g1_process_roots() ->
++// SharedHeap::process_roots() which calls eventually to
+ // CardTableModRefBS::par_non_clean_card_iterate_work() which uses
+-// SequentialSubTasksDone. SharedHeap::process_strong_roots() also
++// SequentialSubTasksDone. SharedHeap::process_roots() also
+ // directly uses SubTasksDone (_process_strong_tasks field in SharedHeap).
+ //
+
+ // Local to this file.
+
+ class RefineCardTableEntryClosure: public CardTableEntryClosure {
+- SuspendibleThreadSet* _sts;
+- G1RemSet* _g1rs;
+- ConcurrentG1Refine* _cg1r;
+ bool _concurrent;
+ public:
+- RefineCardTableEntryClosure(SuspendibleThreadSet* sts,
+- G1RemSet* g1rs,
+- ConcurrentG1Refine* cg1r) :
+- _sts(sts), _g1rs(g1rs), _cg1r(cg1r), _concurrent(true)
+- {}
++ RefineCardTableEntryClosure() : _concurrent(true) { }
++
+ bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
+- bool oops_into_cset = _g1rs->refine_card(card_ptr, worker_i, false);
++ bool oops_into_cset = G1CollectedHeap::heap()->g1_rem_set()->refine_card(card_ptr, worker_i, false);
+ // This path is executed by the concurrent refine or mutator threads,
+ // concurrently, and so we do not care if card_ptr contains references
+ // that point into the collection set.
+ assert(!oops_into_cset, "should be");
+
+- if (_concurrent && _sts->should_yield()) {
++ if (_concurrent && SuspendibleThreadSet::should_yield()) {
+ // Caller will actually yield.
+ return false;
+ }
+ // Otherwise, we finished successfully; return true.
+ return true;
+ }
++
+ void set_concurrent(bool b) { _concurrent = b; }
+ };
+
+
+ class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure {
+- int _calls;
+- G1CollectedHeap* _g1h;
++ size_t _num_processed;
+ CardTableModRefBS* _ctbs;
+ int _histo[256];
+-public:
++
++ public:
+ ClearLoggedCardTableEntryClosure() :
+- _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set())
++ _num_processed(0), _ctbs(G1CollectedHeap::heap()->g1_barrier_set())
+ {
+ for (int i = 0; i < 256; i++) _histo[i] = 0;
+ }
++
+ bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
+- if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) {
+- _calls++;
+- unsigned char* ujb = (unsigned char*)card_ptr;
+- int ind = (int)(*ujb);
+- _histo[ind]++;
+- *card_ptr = -1;
+- }
++ unsigned char* ujb = (unsigned char*)card_ptr;
++ int ind = (int)(*ujb);
++ _histo[ind]++;
++
++ *card_ptr = (jbyte)CardTableModRefBS::clean_card_val();
++ _num_processed++;
++
+ return true;
+ }
+- int calls() { return _calls; }
++
++ size_t num_processed() { return _num_processed; }
++
+ void print_histo() {
+ gclog_or_tty->print_cr("Card table value histogram:");
+ for (int i = 0; i < 256; i++) {
+@@ -156,22 +158,20 @@
+ }
+ };
+
+-class RedirtyLoggedCardTableEntryClosure: public CardTableEntryClosure {
+- int _calls;
+- G1CollectedHeap* _g1h;
+- CardTableModRefBS* _ctbs;
+-public:
+- RedirtyLoggedCardTableEntryClosure() :
+- _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) {}
++class RedirtyLoggedCardTableEntryClosure : public CardTableEntryClosure {
++ private:
++ size_t _num_processed;
++
++ public:
++ RedirtyLoggedCardTableEntryClosure() : CardTableEntryClosure(), _num_processed(0) { }
+
+ bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
+- if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) {
+- _calls++;
+- *card_ptr = 0;
+- }
++ *card_ptr = CardTableModRefBS::dirty_card_val();
++ _num_processed++;
+ return true;
+ }
+- int calls() { return _calls; }
++
++ size_t num_processed() const { return _num_processed; }
+ };
+
+ YoungList::YoungList(G1CollectedHeap* g1h) :
+@@ -208,7 +208,10 @@
+ HeapRegion* next = list->get_next_young_region();
+ list->set_next_young_region(NULL);
+ list->uninstall_surv_rate_group();
+- list->set_not_young();
++ // This is called before a Full GC and all the non-empty /
++ // non-humongous regions at the end of the Full GC will end up as
++ // old anyway.
++ list->set_old();
+ list = next;
+ }
+ }
+@@ -367,7 +370,7 @@
+ if (curr == NULL)
+ gclog_or_tty->print_cr(" empty");
+ while (curr != NULL) {
+- gclog_or_tty->print_cr(" "HR_FORMAT", P: "PTR_FORMAT "N: "PTR_FORMAT", age: %4d",
++ gclog_or_tty->print_cr(" "HR_FORMAT", P: "PTR_FORMAT ", N: "PTR_FORMAT", age: %4d",
+ HR_FORMAT_PARAMS(curr),
+ curr->prev_top_at_mark_start(),
+ curr->next_top_at_mark_start(),
+@@ -379,6 +382,16 @@
+ gclog_or_tty->cr();
+ }
+
++void G1RegionMappingChangedListener::reset_from_card_cache(uint start_idx, size_t num_regions) {
++ OtherRegionsTable::invalidate(start_idx, num_regions);
++}
++
++void G1RegionMappingChangedListener::on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
++ // The from card cache is not the memory that is actually committed. So we cannot
++ // take advantage of the zero_filled parameter.
++ reset_from_card_cache(start_idx, num_regions);
++}
++
+ void G1CollectedHeap::push_dirty_cards_region(HeapRegion* hr)
+ {
+ // Claim the right to put the region on the dirty cards region list
+@@ -444,24 +457,18 @@
+ // implementation of is_scavengable() for G1 will indicate that
+ // all nmethods must be scanned during a partial collection.
+ bool G1CollectedHeap::is_in_partial_collection(const void* p) {
+- HeapRegion* hr = heap_region_containing(p);
+- return hr != NULL && hr->in_collection_set();
++ if (p == NULL) {
++ return false;
++ }
++ return heap_region_containing(p)->in_collection_set();
+ }
+ #endif
+
+ // Returns true if the reference points to an object that
+ // can move in an incremental collection.
+ bool G1CollectedHeap::is_scavengable(const void* p) {
+- G1CollectedHeap* g1h = G1CollectedHeap::heap();
+- G1CollectorPolicy* g1p = g1h->g1_policy();
+ HeapRegion* hr = heap_region_containing(p);
+- if (hr == NULL) {
+- // null
+- assert(p == NULL, err_msg("Not NULL " PTR_FORMAT ,p));
+- return false;
+- } else {
+- return !hr->isHumongous();
+- }
++ return !hr->isHumongous();
+ }
+
+ void G1CollectedHeap::check_ct_logs_at_safepoint() {
+@@ -475,9 +482,8 @@
+
+ // First clear the logged cards.
+ ClearLoggedCardTableEntryClosure clear;
+- dcqs.set_closure(&clear);
+- dcqs.apply_closure_to_all_completed_buffers();
+- dcqs.iterate_closure_all_threads(false);
++ dcqs.apply_closure_to_all_completed_buffers(&clear);
++ dcqs.iterate_closure_all_threads(&clear, false);
+ clear.print_histo();
+
+ // Now ensure that there's no dirty cards.
+@@ -490,13 +496,13 @@
+ guarantee(count2.n() == 0, "Card table should be clean.");
+
+ RedirtyLoggedCardTableEntryClosure redirty;
+- JavaThread::dirty_card_queue_set().set_closure(&redirty);
+- dcqs.apply_closure_to_all_completed_buffers();
+- dcqs.iterate_closure_all_threads(false);
++ dcqs.apply_closure_to_all_completed_buffers(&redirty);
++ dcqs.iterate_closure_all_threads(&redirty, false);
+ gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.",
+- clear.calls(), orig_count);
+- guarantee(redirty.calls() == clear.calls(),
+- "Or else mechanism is broken.");
++ clear.num_processed(), orig_count);
++ guarantee(redirty.num_processed() == clear.num_processed(),
++ err_msg("Redirtied "SIZE_FORMAT" cards, bug cleared "SIZE_FORMAT,
++ redirty.num_processed(), clear.num_processed()));
+
+ CountNonCleanMemRegionClosure count3(this);
+ ct_bs->mod_card_iterate(&count3);
+@@ -505,8 +511,6 @@
+ orig_count, count3.n());
+ guarantee(count3.n() >= orig_count, "Should have restored them all.");
+ }
+-
+- JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl);
+ }
+
+ // Private class members.
+@@ -530,9 +534,9 @@
+ // again to allocate from it.
+ append_secondary_free_list();
+
+- assert(!_free_list.is_empty(), "if the secondary_free_list was not "
++ assert(_hrm.num_free_regions() > 0, "if the secondary_free_list was not "
+ "empty we should have moved at least one entry to the free_list");
+- HeapRegion* res = _free_list.remove_region(is_old);
++ HeapRegion* res = _hrm.allocate_free_region(is_old);
+ if (G1ConcRegionFreeingVerbose) {
+ gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
+ "allocated "HR_FORMAT" from secondary_free_list",
+@@ -573,7 +577,7 @@
+ }
+ }
+
+- res = _free_list.remove_region(is_old);
++ res = _hrm.allocate_free_region(is_old);
+
+ if (res == NULL) {
+ if (G1ConcRegionFreeingVerbose) {
+@@ -598,8 +602,8 @@
+ // Given that expand() succeeded in expanding the heap, and we
+ // always expand the heap by an amount aligned to the heap
+ // region size, the free list should in theory not be empty.
+- // In either case remove_region() will check for NULL.
+- res = _free_list.remove_region(is_old);
++ // In either case allocate_free_region() will check for NULL.
++ res = _hrm.allocate_free_region(is_old);
+ } else {
+ _expand_heap_after_alloc_failure = false;
+ }
+@@ -607,55 +611,12 @@
+ return res;
+ }
+
+-uint G1CollectedHeap::humongous_obj_allocate_find_first(uint num_regions,
+- size_t word_size) {
+- assert(isHumongous(word_size), "word_size should be humongous");
+- assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition");
+-
+- uint first = G1_NULL_HRS_INDEX;
+- if (num_regions == 1) {
+- // Only one region to allocate, no need to go through the slower
+- // path. The caller will attempt the expansion if this fails, so
+- // let's not try to expand here too.
+- HeapRegion* hr = new_region(word_size, true /* is_old */, false /* do_expand */);
+- if (hr != NULL) {
+- first = hr->hrs_index();
+- } else {
+- first = G1_NULL_HRS_INDEX;
+- }
+- } else {
+- // We can't allocate humongous regions while cleanupComplete() is
+- // running, since some of the regions we find to be empty might not
+- // yet be added to the free list and it is not straightforward to
+- // know which list they are on so that we can remove them. Note
+- // that we only need to do this if we need to allocate more than
+- // one region to satisfy the current humongous allocation
+- // request. If we are only allocating one region we use the common
+- // region allocation code (see above).
+- wait_while_free_regions_coming();
+- append_secondary_free_list_if_not_empty_with_lock();
+-
+- if (free_regions() >= num_regions) {
+- first = _hrs.find_contiguous(num_regions);
+- if (first != G1_NULL_HRS_INDEX) {
+- for (uint i = first; i < first + num_regions; ++i) {
+- HeapRegion* hr = region_at(i);
+- assert(hr->is_empty(), "sanity");
+- assert(is_on_master_free_list(hr), "sanity");
+- hr->set_pending_removal(true);
+- }
+- _free_list.remove_all_pending(num_regions);
+- }
+- }
+- }
+- return first;
+-}
+-
+ HeapWord*
+ G1CollectedHeap::humongous_obj_allocate_initialize_regions(uint first,
+ uint num_regions,
+- size_t word_size) {
+- assert(first != G1_NULL_HRS_INDEX, "pre-condition");
++ size_t word_size,
++ AllocationContext_t context) {
++ assert(first != G1_NO_HRM_INDEX, "pre-condition");
+ assert(isHumongous(word_size), "word_size should be humongous");
+ assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition");
+
+@@ -706,13 +667,14 @@
+ // that there is a single object that starts at the bottom of the
+ // first region.
+ first_hr->set_startsHumongous(new_top, new_end);
+-
++ first_hr->set_allocation_context(context);
+ // Then, if there are any, we will set up the "continues
+ // humongous" regions.
+ HeapRegion* hr = NULL;
+ for (uint i = first + 1; i < last; ++i) {
+ hr = region_at(i);
+ hr->set_continuesHumongous(first_hr);
++ hr->set_allocation_context(context);
+ }
+ // If we have "continues humongous" regions (hr != NULL), then the
+ // end of the last one should match new_end.
+@@ -776,9 +738,10 @@
+ // match new_top.
+ assert(hr == NULL ||
+ (hr->end() == new_end && hr->top() == new_top), "sanity");
++ check_bitmaps("Humongous Region Allocation", first_hr);
+
+ assert(first_hr->used() == word_size * HeapWordSize, "invariant");
+- _summary_bytes_used += first_hr->used();
++ _allocator->increase_used(first_hr->used());
+ _humongous_set.add(first_hr);
+
+ return new_obj;
+@@ -787,47 +750,77 @@
+ // If could fit into free regions w/o expansion, try.
+ // Otherwise, if can expand, do so.
+ // Otherwise, if using ex regions might help, try with ex given back.
+-HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size) {
++HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size, AllocationContext_t context) {
+ assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
+
+ verify_region_sets_optional();
+
+- size_t word_size_rounded = round_to(word_size, HeapRegion::GrainWords);
+- uint num_regions = (uint) (word_size_rounded / HeapRegion::GrainWords);
+- uint x_num = expansion_regions();
+- uint fs = _hrs.free_suffix();
+- uint first = humongous_obj_allocate_find_first(num_regions, word_size);
+- if (first == G1_NULL_HRS_INDEX) {
+- // The only thing we can do now is attempt expansion.
+- if (fs + x_num >= num_regions) {
+- // If the number of regions we're trying to allocate for this
+- // object is at most the number of regions in the free suffix,
+- // then the call to humongous_obj_allocate_find_first() above
+- // should have succeeded and we wouldn't be here.
+- //
+- // We should only be trying to expand when the free suffix is
+- // not sufficient for the object _and_ we have some expansion
+- // room available.
+- assert(num_regions > fs, "earlier allocation should have succeeded");
+-
++ uint first = G1_NO_HRM_INDEX;
++ uint obj_regions = (uint)(align_size_up_(word_size, HeapRegion::GrainWords) / HeapRegion::GrainWords);
++
++ if (obj_regions == 1) {
++ // Only one region to allocate, try to use a fast path by directly allocating
++ // from the free lists. Do not try to expand here, we will potentially do that
++ // later.
++ HeapRegion* hr = new_region(word_size, true /* is_old */, false /* do_expand */);
++ if (hr != NULL) {
++ first = hr->hrm_index();
++ }
++ } else {
++ // We can't allocate humongous regions spanning more than one region while
++ // cleanupComplete() is running, since some of the regions we find to be
++ // empty might not yet be added to the free list. It is not straightforward
++ // to know in which list they are on so that we can remove them. We only
++ // need to do this if we need to allocate more than one region to satisfy the
++ // current humongous allocation request. If we are only allocating one region
++ // we use the one-region region allocation code (see above), that already
++ // potentially waits for regions from the secondary free list.
++ wait_while_free_regions_coming();
++ append_secondary_free_list_if_not_empty_with_lock();
++
++ // Policy: Try only empty regions (i.e. already committed first). Maybe we
++ // are lucky enough to find some.
++ first = _hrm.find_contiguous_only_empty(obj_regions);
++ if (first != G1_NO_HRM_INDEX) {
++ _hrm.allocate_free_regions_starting_at(first, obj_regions);
++ }
++ }
++
++ if (first == G1_NO_HRM_INDEX) {
++ // Policy: We could not find enough regions for the humongous object in the
++ // free list. Look through the heap to find a mix of free and uncommitted regions.
++ // If so, try expansion.
++ first = _hrm.find_contiguous_empty_or_unavailable(obj_regions);
++ if (first != G1_NO_HRM_INDEX) {
++ // We found something. Make sure these regions are committed, i.e. expand
++ // the heap. Alternatively we could do a defragmentation GC.
+ ergo_verbose1(ErgoHeapSizing,
+ "attempt heap expansion",
+ ergo_format_reason("humongous allocation request failed")
+ ergo_format_byte("allocation request"),
+ word_size * HeapWordSize);
+- if (expand((num_regions - fs) * HeapRegion::GrainBytes)) {
+- // Even though the heap was expanded, it might not have
+- // reached the desired size. So, we cannot assume that the
+- // allocation will succeed.
+- first = humongous_obj_allocate_find_first(num_regions, word_size);
++
++ _hrm.expand_at(first, obj_regions);
++ g1_policy()->record_new_heap_size(num_regions());
++
++#ifdef ASSERT
++ for (uint i = first; i < first + obj_regions; ++i) {
++ HeapRegion* hr = region_at(i);
++ assert(hr->is_free(), "sanity");
++ assert(hr->is_empty(), "sanity");
++ assert(is_on_master_free_list(hr), "sanity");
+ }
++#endif
++ _hrm.allocate_free_regions_starting_at(first, obj_regions);
++ } else {
++ // Policy: Potentially trigger a defragmentation GC.
+ }
+ }
+
+ HeapWord* result = NULL;
+- if (first != G1_NULL_HRS_INDEX) {
+- result =
+- humongous_obj_allocate_initialize_regions(first, num_regions, word_size);
++ if (first != G1_NO_HRM_INDEX) {
++ result = humongous_obj_allocate_initialize_regions(first, obj_regions,
++ word_size, context);
+ assert(result != NULL, "it should always return a valid result");
+
+ // A successful humongous object allocation changes the used space
+@@ -871,6 +864,8 @@
+
+ // Create the garbage collection operation...
+ VM_G1CollectForAllocation op(gc_count_before, word_size);
++ op.set_allocation_context(AllocationContext::current());
++
+ // ...and get the VM thread to execute it.
+ VMThread::execute(&op);
+
+@@ -906,8 +901,9 @@
+ }
+
+ HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size,
+- unsigned int *gc_count_before_ret,
+- int* gclocker_retry_count_ret) {
++ AllocationContext_t context,
++ unsigned int *gc_count_before_ret,
++ int* gclocker_retry_count_ret) {
+ // Make sure you read the note in attempt_allocation_humongous().
+
+ assert_heap_not_locked_and_not_at_safepoint();
+@@ -928,23 +924,22 @@
+
+ {
+ MutexLockerEx x(Heap_lock);
+-
+- result = _mutator_alloc_region.attempt_allocation_locked(word_size,
+- false /* bot_updates */);
++ result = _allocator->mutator_alloc_region(context)->attempt_allocation_locked(word_size,
++ false /* bot_updates */);
+ if (result != NULL) {
+ return result;
+ }
+
+ // If we reach here, attempt_allocation_locked() above failed to
+ // allocate a new region. So the mutator alloc region should be NULL.
+- assert(_mutator_alloc_region.get() == NULL, "only way to get here");
++ assert(_allocator->mutator_alloc_region(context)->get() == NULL, "only way to get here");
+
+ if (GC_locker::is_active_and_needs_gc()) {
+ if (g1_policy()->can_expand_young_list()) {
+ // No need for an ergo verbose message here,
+ // can_expand_young_list() does this when it returns true.
+- result = _mutator_alloc_region.attempt_allocation_force(word_size,
+- false /* bot_updates */);
++ result = _allocator->mutator_alloc_region(context)->attempt_allocation_force(word_size,
++ false /* bot_updates */);
+ if (result != NULL) {
+ return result;
+ }
+@@ -1004,8 +999,8 @@
+ // first attempt (without holding the Heap_lock) here and the
+ // follow-on attempt will be at the start of the next loop
+ // iteration (after taking the Heap_lock).
+- result = _mutator_alloc_region.attempt_allocation(word_size,
+- false /* bot_updates */);
++ result = _allocator->mutator_alloc_region(context)->attempt_allocation(word_size,
++ false /* bot_updates */);
+ if (result != NULL) {
+ return result;
+ }
+@@ -1023,8 +1018,8 @@
+ }
+
+ HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size,
+- unsigned int * gc_count_before_ret,
+- int* gclocker_retry_count_ret) {
++ unsigned int * gc_count_before_ret,
++ int* gclocker_retry_count_ret) {
+ // The structure of this method has a lot of similarities to
+ // attempt_allocation_slow(). The reason these two were not merged
+ // into a single one is that such a method would require several "if
+@@ -1065,7 +1060,7 @@
+ // Given that humongous objects are not allocated in young
+ // regions, we'll first try to do the allocation without doing a
+ // collection hoping that there's enough space in the heap.
+- result = humongous_obj_allocate(word_size);
++ result = humongous_obj_allocate(word_size, AllocationContext::current());
+ if (result != NULL) {
+ return result;
+ }
+@@ -1141,17 +1136,18 @@
+ }
+
+ HeapWord* G1CollectedHeap::attempt_allocation_at_safepoint(size_t word_size,
+- bool expect_null_mutator_alloc_region) {
++ AllocationContext_t context,
++ bool expect_null_mutator_alloc_region) {
+ assert_at_safepoint(true /* should_be_vm_thread */);
+- assert(_mutator_alloc_region.get() == NULL ||
++ assert(_allocator->mutator_alloc_region(context)->get() == NULL ||
+ !expect_null_mutator_alloc_region,
+ "the current alloc region was unexpectedly found to be non-NULL");
+
+ if (!isHumongous(word_size)) {
+- return _mutator_alloc_region.attempt_allocation_locked(word_size,
++ return _allocator->mutator_alloc_region(context)->attempt_allocation_locked(word_size,
+ false /* bot_updates */);
+ } else {
+- HeapWord* result = humongous_obj_allocate(word_size);
++ HeapWord* result = humongous_obj_allocate(word_size, context);
+ if (result != NULL && g1_policy()->need_to_start_conc_mark("STW humongous allocation")) {
+ g1_policy()->set_initiate_conc_mark_if_possible();
+ }
+@@ -1238,21 +1234,21 @@
+ public:
+ bool doHeapRegion(HeapRegion* hr) {
+ assert(!hr->is_young(), "not expecting to find young regions");
+- // We only generate output for non-empty regions.
+- if (!hr->is_empty()) {
+- if (!hr->isHumongous()) {
+- _hr_printer->post_compaction(hr, G1HRPrinter::Old);
+- } else if (hr->startsHumongous()) {
+- if (hr->region_num() == 1) {
+- // single humongous region
+- _hr_printer->post_compaction(hr, G1HRPrinter::SingleHumongous);
+- } else {
+- _hr_printer->post_compaction(hr, G1HRPrinter::StartsHumongous);
+- }
++ if (hr->is_free()) {
++ // We only generate output for non-empty regions.
++ } else if (hr->startsHumongous()) {
++ if (hr->region_num() == 1) {
++ // single humongous region
++ _hr_printer->post_compaction(hr, G1HRPrinter::SingleHumongous);
+ } else {
+- assert(hr->continuesHumongous(), "only way to get here");
+- _hr_printer->post_compaction(hr, G1HRPrinter::ContinuesHumongous);
++ _hr_printer->post_compaction(hr, G1HRPrinter::StartsHumongous);
+ }
++ } else if (hr->continuesHumongous()) {
++ _hr_printer->post_compaction(hr, G1HRPrinter::ContinuesHumongous);
++ } else if (hr->is_old()) {
++ _hr_printer->post_compaction(hr, G1HRPrinter::Old);
++ } else {
++ ShouldNotReachHere();
+ }
+ return false;
+ }
+@@ -1261,7 +1257,7 @@
+ : _hr_printer(hr_printer) { }
+ };
+
+-void G1CollectedHeap::print_hrs_post_compaction() {
++void G1CollectedHeap::print_hrm_post_compaction() {
+ PostCompactionPrinterClosure cl(hr_printer());
+ heap_region_iterate(&cl);
+ }
+@@ -1305,7 +1301,7 @@
+ TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
+
+ {
+- GCTraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, NULL);
++ GCTraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, NULL, gc_tracer->gc_id());
+ TraceCollectorStats tcs(g1mm()->full_collection_counters());
+ TraceMemoryManagerStats tms(true /* fullGC */, gc_cause());
+
+@@ -1334,6 +1330,7 @@
+
+ verify_before_gc();
+
++ check_bitmaps("Full GC Start");
+ pre_full_gc_dump(gc_timer);
+
+ COMPILER2_PRESENT(DerivedPointerTable::clear());
+@@ -1350,8 +1347,8 @@
+ concurrent_mark()->abort();
+
+ // Make sure we'll choose a new allocation region afterwards.
+- release_mutator_alloc_region();
+- abandon_gc_alloc_regions();
++ _allocator->release_mutator_alloc_region();
++ _allocator->abandon_gc_alloc_regions();
+ g1_rem_set()->cleanupHRRS();
+
+ // We should call this after we retire any currently active alloc
+@@ -1389,7 +1386,7 @@
+ G1MarkSweep::invoke_at_safepoint(ref_processor_stw(), do_clear_all_soft_refs);
+ }
+
+- assert(free_regions() == 0, "we should not have added any free regions");
++ assert(num_free_regions() == 0, "we should not have added any free regions");
+ rebuild_region_sets(false /* free_list_only */);
+
+ // Enqueue any discovered reference objects that have
+@@ -1429,7 +1426,7 @@
+ // that all the COMMIT / UNCOMMIT events are generated before
+ // the end GC event.
+
+- print_hrs_post_compaction();
++ print_hrm_post_compaction();
+ _hr_printer.end_gc(true /* full */, (size_t) total_collections());
+ }
+
+@@ -1489,9 +1486,7 @@
+
+ // Discard all rset updates
+ JavaThread::dirty_card_queue_set().abandon_logs();
+- assert(!G1DeferredRSUpdate
+- || (G1DeferredRSUpdate &&
+- (dirty_card_queue_set().completed_buffers_num() == 0)), "Should not be any");
++ assert(dirty_card_queue_set().completed_buffers_num() == 0, "DCQS should be empty");
+
+ _young_list->reset_sampled_info();
+ // At this point there should be no regions in the
+@@ -1502,21 +1497,30 @@
+ // Update the number of full collections that have been completed.
+ increment_old_marking_cycles_completed(false /* concurrent */);
+
+- _hrs.verify_optional();
++ _hrm.verify_optional();
+ verify_region_sets_optional();
+
+ verify_after_gc();
+
++ // Clear the previous marking bitmap, if needed for bitmap verification.
++ // Note we cannot do this when we clear the next marking bitmap in
++ // ConcurrentMark::abort() above since VerifyDuringGC verifies the
++ // objects marked during a full GC against the previous bitmap.
++ // But we need to clear it before calling check_bitmaps below since
++ // the full GC has compacted objects and updated TAMS but not updated
++ // the prev bitmap.
++ if (G1VerifyBitmaps) {
++ ((CMBitMap*) concurrent_mark()->prevMarkBitMap())->clearAll();
++ }
++ check_bitmaps("Full GC End");
++
+ // Start a new incremental collection set for the next pause
+ assert(g1_policy()->collection_set() == NULL, "must be");
+ g1_policy()->start_incremental_cset_building();
+
+- // Clear the _cset_fast_test bitmap in anticipation of adding
+- // regions to the incremental collection set for the next
+- // evacuation pause.
+ clear_cset_fast_test();
+
+- init_mutator_alloc_region();
++ _allocator->init_mutator_alloc_region();
+
+ double end = os::elapsedTime();
+ g1_policy()->record_full_collection_end();
+@@ -1652,6 +1656,7 @@
+
+ HeapWord*
+ G1CollectedHeap::satisfy_failed_allocation(size_t word_size,
++ AllocationContext_t context,
+ bool* succeeded) {
+ assert_at_safepoint(true /* should_be_vm_thread */);
+
+@@ -1659,7 +1664,8 @@
+ // Let's attempt the allocation first.
+ HeapWord* result =
+ attempt_allocation_at_safepoint(word_size,
+- false /* expect_null_mutator_alloc_region */);
++ context,
++ false /* expect_null_mutator_alloc_region */);
+ if (result != NULL) {
+ assert(*succeeded, "sanity");
+ return result;
+@@ -1669,7 +1675,7 @@
+ // incremental pauses. Therefore, at least for now, we'll favor
+ // expansion over collection. (This might change in the future if we can
+ // do something smarter than full collection to satisfy a failed alloc.)
+- result = expand_and_allocate(word_size);
++ result = expand_and_allocate(word_size, context);
+ if (result != NULL) {
+ assert(*succeeded, "sanity");
+ return result;
+@@ -1686,7 +1692,8 @@
+
+ // Retry the allocation
+ result = attempt_allocation_at_safepoint(word_size,
+- true /* expect_null_mutator_alloc_region */);
++ context,
++ true /* expect_null_mutator_alloc_region */);
+ if (result != NULL) {
+ assert(*succeeded, "sanity");
+ return result;
+@@ -1703,7 +1710,8 @@
+
+ // Retry the allocation once more
+ result = attempt_allocation_at_safepoint(word_size,
+- true /* expect_null_mutator_alloc_region */);
++ context,
++ true /* expect_null_mutator_alloc_region */);
+ if (result != NULL) {
+ assert(*succeeded, "sanity");
+ return result;
+@@ -1725,7 +1733,7 @@
+ // successful, perform the allocation and return the address of the
+ // allocated block, or else "NULL".
+
+-HeapWord* G1CollectedHeap::expand_and_allocate(size_t word_size) {
++HeapWord* G1CollectedHeap::expand_and_allocate(size_t word_size, AllocationContext_t context) {
+ assert_at_safepoint(true /* should_be_vm_thread */);
+
+ verify_region_sets_optional();
+@@ -1737,29 +1745,15 @@
+ ergo_format_byte("allocation request"),
+ word_size * HeapWordSize);
+ if (expand(expand_bytes)) {
+- _hrs.verify_optional();
++ _hrm.verify_optional();
+ verify_region_sets_optional();
+ return attempt_allocation_at_safepoint(word_size,
+- false /* expect_null_mutator_alloc_region */);
++ context,
++ false /* expect_null_mutator_alloc_region */);
+ }
+ return NULL;
+ }
+
+-void G1CollectedHeap::update_committed_space(HeapWord* old_end,
+- HeapWord* new_end) {
+- assert(old_end != new_end, "don't call this otherwise");
+- assert((HeapWord*) _g1_storage.high() == new_end, "invariant");
+-
+- // Update the committed mem region.
+- _g1_committed.set_end(new_end);
+- // Tell the card table about the update.
+- Universe::heap()->barrier_set()->resize_covered_region(_g1_committed);
+- // Tell the BOT about the update.
+- _bot_shared->resize(_g1_committed.word_size());
+- // Tell the hot card cache about the update
+- _cg1r->hot_card_cache()->resize_card_counts(capacity());
+-}
+-
+ bool G1CollectedHeap::expand(size_t expand_bytes) {
+ size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
+ aligned_expand_bytes = align_size_up(aligned_expand_bytes,
+@@ -1770,55 +1764,22 @@
+ ergo_format_byte("attempted expansion amount"),
+ expand_bytes, aligned_expand_bytes);
+
+- if (_g1_storage.uncommitted_size() == 0) {
++ if (is_maximal_no_gc()) {
+ ergo_verbose0(ErgoHeapSizing,
+ "did not expand the heap",
+ ergo_format_reason("heap already fully expanded"));
+ return false;
+ }
+
+- // First commit the memory.
+- HeapWord* old_end = (HeapWord*) _g1_storage.high();
+- bool successful = _g1_storage.expand_by(aligned_expand_bytes);
+- if (successful) {
+- // Then propagate this update to the necessary data structures.
+- HeapWord* new_end = (HeapWord*) _g1_storage.high();
+- update_committed_space(old_end, new_end);
+-
+- FreeRegionList expansion_list("Local Expansion List");
+- MemRegion mr = _hrs.expand_by(old_end, new_end, &expansion_list);
+- assert(mr.start() == old_end, "post-condition");
+- // mr might be a smaller region than what was requested if
+- // expand_by() was unable to allocate the HeapRegion instances
+- assert(mr.end() <= new_end, "post-condition");
+-
+- size_t actual_expand_bytes = mr.byte_size();
++ uint regions_to_expand = (uint)(aligned_expand_bytes / HeapRegion::GrainBytes);
++ assert(regions_to_expand > 0, "Must expand by at least one region");
++
++ uint expanded_by = _hrm.expand_by(regions_to_expand);
++
++ if (expanded_by > 0) {
++ size_t actual_expand_bytes = expanded_by * HeapRegion::GrainBytes;
+ assert(actual_expand_bytes <= aligned_expand_bytes, "post-condition");
+- assert(actual_expand_bytes == expansion_list.total_capacity_bytes(),
+- "post-condition");
+- if (actual_expand_bytes < aligned_expand_bytes) {
+- // We could not expand _hrs to the desired size. In this case we
+- // need to shrink the committed space accordingly.
+- assert(mr.end() < new_end, "invariant");
+-
+- size_t diff_bytes = aligned_expand_bytes - actual_expand_bytes;
+- // First uncommit the memory.
+- _g1_storage.shrink_by(diff_bytes);
+- // Then propagate this update to the necessary data structures.
+- update_committed_space(new_end, mr.end());
+- }
+- _free_list.add_as_tail(&expansion_list);
+-
+- if (_hr_printer.is_active()) {
+- HeapWord* curr = mr.start();
+- while (curr < mr.end()) {
+- HeapWord* curr_end = curr + HeapRegion::GrainWords;
+- _hr_printer.commit(curr, curr_end);
+- curr = curr_end;
+- }
+- assert(curr == mr.end(), "post-condition");
+- }
+- g1_policy()->record_new_heap_size(n_regions());
++ g1_policy()->record_new_heap_size(num_regions());
+ } else {
+ ergo_verbose0(ErgoHeapSizing,
+ "did not expand the heap",
+@@ -1826,12 +1787,12 @@
+ // The expansion of the virtual storage space was unsuccessful.
+ // Let's see if it was because we ran out of swap.
+ if (G1ExitOnExpansionFailure &&
+- _g1_storage.uncommitted_size() >= aligned_expand_bytes) {
++ _hrm.available() >= regions_to_expand) {
+ // We had head room...
+ vm_exit_out_of_memory(aligned_expand_bytes, OOM_MMAP_ERROR, "G1 heap expansion");
+ }
+ }
+- return successful;
++ return regions_to_expand > 0;
+ }
+
+ void G1CollectedHeap::shrink_helper(size_t shrink_bytes) {
+@@ -1841,8 +1802,7 @@
+ HeapRegion::GrainBytes);
+ uint num_regions_to_remove = (uint)(shrink_bytes / HeapRegion::GrainBytes);
+
+- uint num_regions_removed = _hrs.shrink_by(num_regions_to_remove);
+- HeapWord* old_end = (HeapWord*) _g1_storage.high();
++ uint num_regions_removed = _hrm.shrink_by(num_regions_to_remove);
+ size_t shrunk_bytes = num_regions_removed * HeapRegion::GrainBytes;
+
+ ergo_verbose3(ErgoHeapSizing,
+@@ -1852,22 +1812,7 @@
+ ergo_format_byte("attempted shrinking amount"),
+ shrink_bytes, aligned_shrink_bytes, shrunk_bytes);
+ if (num_regions_removed > 0) {
+- _g1_storage.shrink_by(shrunk_bytes);
+- HeapWord* new_end = (HeapWord*) _g1_storage.high();
+-
+- if (_hr_printer.is_active()) {
+- HeapWord* curr = old_end;
+- while (curr > new_end) {
+- HeapWord* curr_end = curr;
+- curr -= HeapRegion::GrainWords;
+- _hr_printer.uncommit(curr, curr_end);
+- }
+- }
+-
+- _expansion_regions += num_regions_removed;
+- update_committed_space(old_end, new_end);
+- HeapRegionRemSet::shrink_heap(n_regions());
+- g1_policy()->record_new_heap_size(n_regions());
++ g1_policy()->record_new_heap_size(num_regions());
+ } else {
+ ergo_verbose0(ErgoHeapSizing,
+ "did not shrink the heap",
+@@ -1881,7 +1826,7 @@
+ // We should only reach here at the end of a Full GC which means we
+ // should not not be holding to any GC alloc regions. The method
+ // below will make sure of that and do any remaining clean up.
+- abandon_gc_alloc_regions();
++ _allocator->abandon_gc_alloc_regions();
+
+ // Instead of tearing down / rebuilding the free lists here, we
+ // could instead use the remove_all_pending() method on free_list to
+@@ -1890,7 +1835,7 @@
+ shrink_helper(shrink_bytes);
+ rebuild_region_sets(true /* free_list_only */);
+
+- _hrs.verify_optional();
++ _hrm.verify_optional();
+ verify_region_sets_optional();
+ }
+
+@@ -1914,18 +1859,18 @@
+ _bot_shared(NULL),
+ _evac_failure_scan_stack(NULL),
+ _mark_in_progress(false),
+- _cg1r(NULL), _summary_bytes_used(0),
++ _cg1r(NULL),
+ _g1mm(NULL),
+ _refine_cte_cl(NULL),
+ _full_collection(false),
+- _free_list("Master Free List", new MasterFreeRegionListMtSafeChecker()),
+ _secondary_free_list("Secondary Free List", new SecondaryFreeRegionListMtSafeChecker()),
+ _old_set("Old Set", false /* humongous */, new OldRegionSetMtSafeChecker()),
+ _humongous_set("Master Humongous Set", true /* humongous */, new HumongousRegionSetMtSafeChecker()),
++ _humongous_is_live(),
++ _has_humongous_reclaim_candidates(false),
+ _free_regions_coming(false),
+ _young_list(new YoungList(this)),
+ _gc_time_stamp(0),
+- _retained_old_gc_alloc_region(NULL),
+ _survivor_plab_stats(YoungPLABSize, PLABWeight),
+ _old_plab_stats(OldPLABSize, PLABWeight),
+ _expand_heap_after_alloc_failure(true),
+@@ -1933,8 +1878,7 @@
+ _old_marking_cycles_started(0),
+ _old_marking_cycles_completed(0),
+ _concurrent_cycle_started(false),
+- _in_cset_fast_test(NULL),
+- _in_cset_fast_test_base(NULL),
++ _in_cset_fast_test(),
+ _dirty_cards_region_list(NULL),
+ _worker_cset_start_region(NULL),
+ _worker_cset_start_region_time_stamp(NULL),
+@@ -1948,6 +1892,7 @@
+ vm_exit_during_initialization("Failed necessary allocation.");
+ }
+
++ _allocator = G1Allocator::create_allocator(_g1h);
+ _humongous_object_threshold_in_words = HeapRegion::GrainWords / 2;
+
+ int n_queues = MAX2((int)ParallelGCThreads, 1);
+@@ -2004,7 +1949,9 @@
+ Universe::check_alignment(max_byte_size, HeapRegion::GrainBytes, "g1 heap");
+ Universe::check_alignment(max_byte_size, heap_alignment, "g1 heap");
+
+- _cg1r = new ConcurrentG1Refine(this);
++ _refine_cte_cl = new RefineCardTableEntryClosure();
++
++ _cg1r = new ConcurrentG1Refine(this, _refine_cte_cl);
+
+ // Reserve the maximum.
+
+@@ -2029,8 +1976,6 @@
+ _reserved.set_start((HeapWord*)heap_rs.base());
+ _reserved.set_end((HeapWord*)(heap_rs.base() + heap_rs.size()));
+
+- _expansion_regions = (uint) (max_byte_size / HeapRegion::GrainBytes);
+-
+ // Create the gen rem set (and barrier set) for the entire reserved region.
+ _rem_set = collector_policy()->create_rem_set(_reserved, 2);
+ set_barrier_set(rem_set()->bs());
+@@ -2044,20 +1989,65 @@
+
+ // Carve out the G1 part of the heap.
+
+- ReservedSpace g1_rs = heap_rs.first_part(max_byte_size);
+- _g1_reserved = MemRegion((HeapWord*)g1_rs.base(),
+- g1_rs.size()/HeapWordSize);
+-
+- _g1_storage.initialize(g1_rs, 0);
+- _g1_committed = MemRegion((HeapWord*)_g1_storage.low(), (size_t) 0);
+- _hrs.initialize((HeapWord*) _g1_reserved.start(),
+- (HeapWord*) _g1_reserved.end());
+- assert(_hrs.max_length() == _expansion_regions,
+- err_msg("max length: %u expansion regions: %u",
+- _hrs.max_length(), _expansion_regions));
+-
+- // Do later initialization work for concurrent refinement.
+- _cg1r->init();
++ ReservedSpace g1_rs = heap_rs.first_part(max_byte_size);
++ G1RegionToSpaceMapper* heap_storage =
++ G1RegionToSpaceMapper::create_mapper(g1_rs,
++ UseLargePages ? os::large_page_size() : os::vm_page_size(),
++ HeapRegion::GrainBytes,
++ 1,
++ mtJavaHeap);
++ heap_storage->set_mapping_changed_listener(&_listener);
++
++ // Reserve space for the block offset table. We do not support automatic uncommit
++ // for the card table at this time. BOT only.
++ ReservedSpace bot_rs(G1BlockOffsetSharedArray::compute_size(g1_rs.size() / HeapWordSize));
++ G1RegionToSpaceMapper* bot_storage =
++ G1RegionToSpaceMapper::create_mapper(bot_rs,
++ os::vm_page_size(),
++ HeapRegion::GrainBytes,
++ G1BlockOffsetSharedArray::N_bytes,
++ mtGC);
++
++ ReservedSpace cardtable_rs(G1SATBCardTableLoggingModRefBS::compute_size(g1_rs.size() / HeapWordSize));
++ G1RegionToSpaceMapper* cardtable_storage =
++ G1RegionToSpaceMapper::create_mapper(cardtable_rs,
++ os::vm_page_size(),
++ HeapRegion::GrainBytes,
++ G1BlockOffsetSharedArray::N_bytes,
++ mtGC);
++
++ // Reserve space for the card counts table.
++ ReservedSpace card_counts_rs(G1BlockOffsetSharedArray::compute_size(g1_rs.size() / HeapWordSize));
++ G1RegionToSpaceMapper* card_counts_storage =
++ G1RegionToSpaceMapper::create_mapper(card_counts_rs,
++ os::vm_page_size(),
++ HeapRegion::GrainBytes,
++ G1BlockOffsetSharedArray::N_bytes,
++ mtGC);
++
++ // Reserve space for prev and next bitmap.
++ size_t bitmap_size = CMBitMap::compute_size(g1_rs.size());
++
++ ReservedSpace prev_bitmap_rs(ReservedSpace::allocation_align_size_up(bitmap_size));
++ G1RegionToSpaceMapper* prev_bitmap_storage =
++ G1RegionToSpaceMapper::create_mapper(prev_bitmap_rs,
++ os::vm_page_size(),
++ HeapRegion::GrainBytes,
++ CMBitMap::mark_distance(),
++ mtGC);
++
++ ReservedSpace next_bitmap_rs(ReservedSpace::allocation_align_size_up(bitmap_size));
++ G1RegionToSpaceMapper* next_bitmap_storage =
++ G1RegionToSpaceMapper::create_mapper(next_bitmap_rs,
++ os::vm_page_size(),
++ HeapRegion::GrainBytes,
++ CMBitMap::mark_distance(),
++ mtGC);
++
++ _hrm.initialize(heap_storage, prev_bitmap_storage, next_bitmap_storage, bot_storage, cardtable_storage, card_counts_storage);
++ g1_barrier_set()->initialize(cardtable_storage);
++ // Do later initialization work for concurrent refinement.
++ _cg1r->init(card_counts_storage);
+
+ // 6843694 - ensure that the maximum region index can fit
+ // in the remembered set structures.
+@@ -2071,29 +2061,16 @@
+
+ FreeRegionList::set_unrealistically_long_length(max_regions() + 1);
+
+- _bot_shared = new G1BlockOffsetSharedArray(_reserved,
+- heap_word_size(init_byte_size));
++ _bot_shared = new G1BlockOffsetSharedArray(_reserved, bot_storage);
+
+ _g1h = this;
+
+- _in_cset_fast_test_length = max_regions();
+- _in_cset_fast_test_base =
+- NEW_C_HEAP_ARRAY(bool, (size_t) _in_cset_fast_test_length, mtGC);
+-
+- // We're biasing _in_cset_fast_test to avoid subtracting the
+- // beginning of the heap every time we want to index; basically
+- // it's the same with what we do with the card table.
+- _in_cset_fast_test = _in_cset_fast_test_base -
+- ((uintx) _g1_reserved.start() >> HeapRegion::LogOfHRGrainBytes);
+-
+- // Clear the _cset_fast_test bitmap in anticipation of adding
+- // regions to the incremental collection set for the first
+- // evacuation pause.
+- clear_cset_fast_test();
++ _in_cset_fast_test.initialize(_hrm.reserved().start(), _hrm.reserved().end(), HeapRegion::GrainBytes);
++ _humongous_is_live.initialize(_hrm.reserved().start(), _hrm.reserved().end(), HeapRegion::GrainBytes);
+
+ // Create the ConcurrentMark data structure and thread.
+ // (Must do this late, so that "max_regions" is defined.)
+- _cm = new ConcurrentMark(this, heap_rs);
++ _cm = new ConcurrentMark(this, prev_bitmap_storage, next_bitmap_storage);
+ if (_cm == NULL || !_cm->completed_initialization()) {
+ vm_shutdown_during_initialization("Could not create/initialize ConcurrentMark");
+ return JNI_ENOMEM;
+@@ -2112,35 +2089,30 @@
+ // Perform any initialization actions delegated to the policy.
+ g1_policy()->init();
+
+- _refine_cte_cl =
+- new RefineCardTableEntryClosure(ConcurrentG1RefineThread::sts(),
+- g1_rem_set(),
+- concurrent_g1_refine());
+- JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl);
+-
+ JavaThread::satb_mark_queue_set().initialize(SATB_Q_CBL_mon,
+ SATB_Q_FL_lock,
+ G1SATBProcessCompletedThreshold,
+ Shared_SATB_Q_lock);
+
+- JavaThread::dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
++ JavaThread::dirty_card_queue_set().initialize(_refine_cte_cl,
++ DirtyCardQ_CBL_mon,
+ DirtyCardQ_FL_lock,
+ concurrent_g1_refine()->yellow_zone(),
+ concurrent_g1_refine()->red_zone(),
+ Shared_DirtyCardQ_lock);
+
+- if (G1DeferredRSUpdate) {
+- dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
+- DirtyCardQ_FL_lock,
+- -1, // never trigger processing
+- -1, // no limit on length
+- Shared_DirtyCardQ_lock,
+- &JavaThread::dirty_card_queue_set());
+- }
++ dirty_card_queue_set().initialize(NULL, // Should never be called by the Java code
++ DirtyCardQ_CBL_mon,
++ DirtyCardQ_FL_lock,
++ -1, // never trigger processing
++ -1, // no limit on length
++ Shared_DirtyCardQ_lock,
++ &JavaThread::dirty_card_queue_set());
+
+ // Initialize the card queue set used to hold cards containing
+ // references into the collection set.
+- _into_cset_dirty_card_queue_set.initialize(DirtyCardQ_CBL_mon,
++ _into_cset_dirty_card_queue_set.initialize(NULL, // Should never be called by the Java code
++ DirtyCardQ_CBL_mon,
+ DirtyCardQ_FL_lock,
+ -1, // never trigger processing
+ -1, // no limit on length
+@@ -2151,22 +2123,20 @@
+ // counts and that mechanism.
+ SpecializationStats::clear();
+
+- // Here we allocate the dummy full region that is required by the
+- // G1AllocRegion class. If we don't pass an address in the reserved
+- // space here, lots of asserts fire.
+-
+- HeapRegion* dummy_region = new_heap_region(0 /* index of bottom region */,
+- _g1_reserved.start());
++ // Here we allocate the dummy HeapRegion that is required by the
++ // G1AllocRegion class.
++ HeapRegion* dummy_region = _hrm.get_dummy_region();
++
+ // We'll re-use the same region whether the alloc region will
+ // require BOT updates or not and, if it doesn't, then a non-young
+ // region will complain that it cannot support allocations without
+- // BOT updates. So we'll tag the dummy region as young to avoid that.
+- dummy_region->set_young();
++ // BOT updates. So we'll tag the dummy region as eden to avoid that.
++ dummy_region->set_eden();
+ // Make sure it's full.
+ dummy_region->set_top(dummy_region->end());
+ G1AllocRegion::setup(this, dummy_region);
+
+- init_mutator_alloc_region();
++ _allocator->init_mutator_alloc_region();
+
+ // Do create of the monitoring and management support so that
+ // values in the heap have been properly initialized.
+@@ -2188,6 +2158,11 @@
+ }
+ }
+
++void G1CollectedHeap::clear_humongous_is_live_table() {
++ guarantee(G1ReclaimDeadHumongousObjectsAtYoungGC, "Should only be called if true");
++ _humongous_is_live.clear();
++}
++
+ size_t G1CollectedHeap::conservative_max_heap_alignment() {
+ return HeapRegion::max_region_size();
+ }
+@@ -2267,14 +2242,14 @@
+ }
+
+ size_t G1CollectedHeap::capacity() const {
+- return _g1_committed.byte_size();
++ return _hrm.length() * HeapRegion::GrainBytes;
+ }
+
+ void G1CollectedHeap::reset_gc_time_stamps(HeapRegion* hr) {
+ assert(!hr->continuesHumongous(), "pre-condition");
+ hr->reset_gc_time_stamp();
+ if (hr->startsHumongous()) {
+- uint first_index = hr->hrs_index() + 1;
++ uint first_index = hr->hrm_index() + 1;
+ uint last_index = hr->last_hc_index();
+ for (uint i = first_index; i < last_index; i += 1) {
+ HeapRegion* chr = region_at(i);
+@@ -2335,21 +2310,12 @@
+
+
+ // Computes the sum of the storage used by the various regions.
+-
+ size_t G1CollectedHeap::used() const {
+- assert(Heap_lock->owner() != NULL,
+- "Should be owned on this thread's behalf.");
+- size_t result = _summary_bytes_used;
+- // Read only once in case it is set to NULL concurrently
+- HeapRegion* hr = _mutator_alloc_region.get();
+- if (hr != NULL)
+- result += hr->used();
+- return result;
++ return _allocator->used();
+ }
+
+ size_t G1CollectedHeap::used_unlocked() const {
+- size_t result = _summary_bytes_used;
+- return result;
++ return _allocator->used_unlocked();
+ }
+
+ class SumUsedClosure: public HeapRegionClosure {
+@@ -2375,30 +2341,12 @@
+ return blk.result();
+ }
+
+-size_t G1CollectedHeap::unsafe_max_alloc() {
+- if (free_regions() > 0) return HeapRegion::GrainBytes;
+- // otherwise, is there space in the current allocation region?
+-
+- // We need to store the current allocation region in a local variable
+- // here. The problem is that this method doesn't take any locks and
+- // there may be other threads which overwrite the current allocation
+- // region field. attempt_allocation(), for example, sets it to NULL
+- // and this can happen *after* the NULL check here but before the call
+- // to free(), resulting in a SIGSEGV. Note that this doesn't appear
+- // to be a problem in the optimized build, since the two loads of the
+- // current allocation region field are optimized away.
+- HeapRegion* hr = _mutator_alloc_region.get();
+- if (hr == NULL) {
+- return 0;
+- }
+- return hr->free();
+-}
+-
+ bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) {
+ switch (cause) {
+ case GCCause::_gc_locker: return GCLockerInvokesConcurrent;
+ case GCCause::_java_lang_system_gc: return ExplicitGCInvokesConcurrent;
+ case GCCause::_g1_humongous_allocation: return true;
++ case GCCause::_update_allocation_context_stats_inc: return true;
+ default: return false;
+ }
+ }
+@@ -2412,7 +2360,8 @@
+
+ for (uintx i = 0; i < G1DummyRegionsPerGC; ++i) {
+ // Let's use the existing mechanism for the allocation
+- HeapWord* dummy_obj = humongous_obj_allocate(word_size);
++ HeapWord* dummy_obj = humongous_obj_allocate(word_size,
++ AllocationContext::system());
+ if (dummy_obj != NULL) {
+ MemRegion mr(dummy_obj, word_size);
+ CollectedHeap::fill_with_object(mr);
+@@ -2530,6 +2479,7 @@
+
+ unsigned int gc_count_before;
+ unsigned int old_marking_count_before;
++ unsigned int full_gc_count_before;
+ bool retry_gc;
+
+ do {
+@@ -2540,6 +2490,7 @@
+
+ // Read the GC count while holding the Heap_lock
+ gc_count_before = total_collections();
++ full_gc_count_before = total_full_collections();
+ old_marking_count_before = _old_marking_cycles_started;
+ }
+
+@@ -2552,6 +2503,7 @@
+ true, /* should_initiate_conc_mark */
+ g1_policy()->max_pause_time_ms(),
+ cause);
++ op.set_allocation_context(AllocationContext::current());
+
+ VMThread::execute(&op);
+ if (!op.pause_succeeded()) {
+@@ -2570,7 +2522,7 @@
+ }
+ }
+ } else {
+- if (cause == GCCause::_gc_locker
++ if (cause == GCCause::_gc_locker || cause == GCCause::_wb_young_gc
+ DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) {
+
+ // Schedule a standard evacuation pause. We're setting word_size
+@@ -2583,7 +2535,7 @@
+ VMThread::execute(&op);
+ } else {
+ // Schedule a Full GC.
+- VM_G1CollectFull op(gc_count_before, old_marking_count_before, cause);
++ VM_G1CollectFull op(gc_count_before, full_gc_count_before, cause);
+ VMThread::execute(&op);
+ }
+ }
+@@ -2591,8 +2543,8 @@
+ }
+
+ bool G1CollectedHeap::is_in(const void* p) const {
+- if (_g1_committed.contains(p)) {
+- // Given that we know that p is in the committed space,
++ if (_hrm.reserved().contains(p)) {
++ // Given that we know that p is in the reserved space,
+ // heap_region_containing_raw() should successfully
+ // return the containing region.
+ HeapRegion* hr = heap_region_containing_raw(p);
+@@ -2602,17 +2554,26 @@
+ }
+ }
+
++#ifdef ASSERT
++bool G1CollectedHeap::is_in_exact(const void* p) const {
++ bool contains = reserved_region().contains(p);
++ bool available = _hrm.is_available(addr_to_region((HeapWord*)p));
++ if (contains && available) {
++ return true;
++ } else {
++ return false;
++ }
++}
++#endif
++
+ // Iteration functions.
+
+-// Iterates an OopClosure over all ref-containing fields of objects
+-// within a HeapRegion.
++// Applies an ExtendedOopClosure onto all references of objects within a HeapRegion.
+
+ class IterateOopClosureRegionClosure: public HeapRegionClosure {
+- MemRegion _mr;
+ ExtendedOopClosure* _cl;
+ public:
+- IterateOopClosureRegionClosure(MemRegion mr, ExtendedOopClosure* cl)
+- : _mr(mr), _cl(cl) {}
++ IterateOopClosureRegionClosure(ExtendedOopClosure* cl) : _cl(cl) {}
+ bool doHeapRegion(HeapRegion* r) {
+ if (!r->continuesHumongous()) {
+ r->oop_iterate(_cl);
+@@ -2622,12 +2583,7 @@
+ };
+
+ void G1CollectedHeap::oop_iterate(ExtendedOopClosure* cl) {
+- IterateOopClosureRegionClosure blk(_g1_committed, cl);
+- heap_region_iterate(&blk);
+-}
+-
+-void G1CollectedHeap::oop_iterate(MemRegion mr, ExtendedOopClosure* cl) {
+- IterateOopClosureRegionClosure blk(mr, cl);
++ IterateOopClosureRegionClosure blk(cl);
+ heap_region_iterate(&blk);
+ }
+
+@@ -2668,89 +2624,15 @@
+ }
+
+ void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const {
+- _hrs.iterate(cl);
++ _hrm.iterate(cl);
+ }
+
+ void
+ G1CollectedHeap::heap_region_par_iterate_chunked(HeapRegionClosure* cl,
+ uint worker_id,
+- uint no_of_par_workers,
+- jint claim_value) {
+- const uint regions = n_regions();
+- const uint max_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
+- no_of_par_workers :
+- 1);
+- assert(UseDynamicNumberOfGCThreads ||
+- no_of_par_workers == workers()->total_workers(),
+- "Non dynamic should use fixed number of workers");
+- // try to spread out the starting points of the workers
+- const HeapRegion* start_hr =
+- start_region_for_worker(worker_id, no_of_par_workers);
+- const uint start_index = start_hr->hrs_index();
+-
+- // each worker will actually look at all regions
+- for (uint count = 0; count < regions; ++count) {
+- const uint index = (start_index + count) % regions;
+- assert(0 <= index && index < regions, "sanity");
+- HeapRegion* r = region_at(index);
+- // we'll ignore "continues humongous" regions (we'll process them
+- // when we come across their corresponding "start humongous"
+- // region) and regions already claimed
+- if (r->claim_value() == claim_value || r->continuesHumongous()) {
+- continue;
+- }
+- // OK, try to claim it
+- if (r->claimHeapRegion(claim_value)) {
+- // success!
+- assert(!r->continuesHumongous(), "sanity");
+- if (r->startsHumongous()) {
+- // If the region is "starts humongous" we'll iterate over its
+- // "continues humongous" first; in fact we'll do them
+- // first. The order is important. In on case, calling the
+- // closure on the "starts humongous" region might de-allocate
+- // and clear all its "continues humongous" regions and, as a
+- // result, we might end up processing them twice. So, we'll do
+- // them first (notice: most closures will ignore them anyway) and
+- // then we'll do the "starts humongous" region.
+- for (uint ch_index = index + 1; ch_index < regions; ++ch_index) {
+- HeapRegion* chr = region_at(ch_index);
+-
+- // if the region has already been claimed or it's not
+- // "continues humongous" we're done
+- if (chr->claim_value() == claim_value ||
+- !chr->continuesHumongous()) {
+- break;
+- }
+-
+- // No one should have claimed it directly. We can given
+- // that we claimed its "starts humongous" region.
+- assert(chr->claim_value() != claim_value, "sanity");
+- assert(chr->humongous_start_region() == r, "sanity");
+-
+- if (chr->claimHeapRegion(claim_value)) {
+- // we should always be able to claim it; no one else should
+- // be trying to claim this region
+-
+- bool res2 = cl->doHeapRegion(chr);
+- assert(!res2, "Should not abort");
+-
+- // Right now, this holds (i.e., no closure that actually
+- // does something with "continues humongous" regions
+- // clears them). We might have to weaken it in the future,
+- // but let's leave these two asserts here for extra safety.
+- assert(chr->continuesHumongous(), "should still be the case");
+- assert(chr->humongous_start_region() == r, "sanity");
+- } else {
+- guarantee(false, "we should not reach here");
+- }
+- }
+- }
+-
+- assert(!r->continuesHumongous(), "sanity");
+- bool res = cl->doHeapRegion(r);
+- assert(!res, "Should not abort");
+- }
+- }
++ uint num_workers,
++ jint claim_value) const {
++ _hrm.par_iterate(cl, worker_id, num_workers, claim_value);
+ }
+
+ class ResetClaimValuesClosure: public HeapRegionClosure {
+@@ -2928,17 +2810,6 @@
+ return result;
+ }
+
+-HeapRegion* G1CollectedHeap::start_region_for_worker(uint worker_i,
+- uint no_of_par_workers) {
+- uint worker_num =
+- G1CollectedHeap::use_parallel_gc_threads() ? no_of_par_workers : 1U;
+- assert(UseDynamicNumberOfGCThreads ||
+- no_of_par_workers == workers()->total_workers(),
+- "Non dynamic should use fixed number of workers");
+- const uint start_index = n_regions() * worker_i / worker_num;
+- return region_at(start_index);
+-}
+-
+ void G1CollectedHeap::collection_set_iterate(HeapRegionClosure* cl) {
+ HeapRegion* r = g1_policy()->collection_set();
+ while (r != NULL) {
+@@ -2980,27 +2851,25 @@
+ }
+ }
+
+-CompactibleSpace* G1CollectedHeap::first_compactible_space() {
+- return n_regions() > 0 ? region_at(0) : NULL;
+-}
+-
++HeapRegion* G1CollectedHeap::next_compaction_region(const HeapRegion* from) const {
++ HeapRegion* result = _hrm.next_region_in_heap(from);
++ while (result != NULL && result->isHumongous()) {
++ result = _hrm.next_region_in_heap(result);
++ }
++ return result;
++}
+
+ Space* G1CollectedHeap::space_containing(const void* addr) const {
+- Space* res = heap_region_containing(addr);
+- return res;
++ return heap_region_containing(addr);
+ }
+
+ HeapWord* G1CollectedHeap::block_start(const void* addr) const {
+ Space* sp = space_containing(addr);
+- if (sp != NULL) {
+- return sp->block_start(addr);
+- }
+- return NULL;
++ return sp->block_start(addr);
+ }
+
+ size_t G1CollectedHeap::block_size(const HeapWord* addr) const {
+ Space* sp = space_containing(addr);
+- assert(sp != NULL, "block_size of address outside of heap");
+ return sp->block_size(addr);
+ }
+
+@@ -3035,7 +2904,7 @@
+ // since we can't allow tlabs to grow big enough to accommodate
+ // humongous objects.
+
+- HeapRegion* hr = _mutator_alloc_region.get();
++ HeapRegion* hr = _allocator->mutator_alloc_region(AllocationContext::current())->get();
+ size_t max_tlab = max_tlab_size() * wordSize;
+ if (hr == NULL) {
+ return max_tlab;
+@@ -3045,7 +2914,7 @@
+ }
+
+ size_t G1CollectedHeap::max_capacity() const {
+- return _g1_reserved.byte_size();
++ return _hrm.reserved().byte_size();
+ }
+
+ jlong G1CollectedHeap::millis_since_last_gc() {
+@@ -3414,25 +3283,20 @@
+
+ if (!silent) { gclog_or_tty->print("Roots "); }
+ VerifyRootsClosure rootsCl(vo);
++ VerifyKlassClosure klassCl(this, &rootsCl);
++ CLDToKlassAndOopClosure cldCl(&klassCl, &rootsCl, false);
++
++ // We apply the relevant closures to all the oops in the
++ // system dictionary, class loader data graph, the string table
++ // and the nmethods in the code cache.
+ G1VerifyCodeRootOopClosure codeRootsCl(this, &rootsCl, vo);
+ G1VerifyCodeRootBlobClosure blobsCl(&codeRootsCl);
+- VerifyKlassClosure klassCl(this, &rootsCl);
+-
+- // We apply the relevant closures to all the oops in the
+- // system dictionary, the string table and the code cache.
+- const int so = SO_AllClasses | SO_Strings | SO_CodeCache;
+-
+- // Need cleared claim bits for the strong roots processing
+- ClassLoaderDataGraph::clear_claimed_marks();
+-
+- process_strong_roots(true, // activate StrongRootsScope
+- false, // we set "is scavenging" to false,
+- // so we don't reset the dirty cards.
+- ScanningOption(so), // roots scanning options
+- &rootsCl,
+- &blobsCl,
+- &klassCl
+- );
++
++ process_all_roots(true, // activate StrongRootsScope
++ SO_AllCodeCache, // roots scanning options
++ &rootsCl,
++ &cldCl,
++ &blobsCl);
+
+ bool failures = rootsCl.failures() || codeRootsCl.failures();
+
+@@ -3579,9 +3443,9 @@
+ st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
+ capacity()/K, used_unlocked()/K);
+ st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")",
+- _g1_storage.low_boundary(),
+- _g1_storage.high(),
+- _g1_storage.high_boundary());
++ _hrm.reserved().start(),
++ _hrm.reserved().start() + _hrm.length() + HeapRegion::GrainWords,
++ _hrm.reserved().end());
+ st->cr();
+ st->print(" region size " SIZE_FORMAT "K, ", HeapRegion::GrainBytes / K);
+ uint young_regions = _young_list->length();
+@@ -3727,7 +3591,7 @@
+ }
+ }
+
+-void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) {
++void G1CollectedHeap::gc_epilogue(bool full) {
+
+ if (G1SummarizeRSetStats &&
+ (G1SummarizeRSetStatsPeriod > 0) &&
+@@ -3744,6 +3608,7 @@
+ // always_do_update_barrier = true;
+
+ resize_all_tlabs();
++ allocation_context_stats().update(full);
+
+ // We have just completed a GC. Update the soft reference
+ // policy with the new heap occupancy
+@@ -3761,6 +3626,8 @@
+ false, /* should_initiate_conc_mark */
+ g1_policy()->max_pause_time_ms(),
+ gc_cause);
++
++ op.set_allocation_context(AllocationContext::current());
+ VMThread::execute(&op);
+
+ HeapWord* result = op.result();
+@@ -3804,6 +3671,61 @@
+ return g1_rem_set()->cardsScanned();
+ }
+
++bool G1CollectedHeap::humongous_region_is_always_live(uint index) {
++ HeapRegion* region = region_at(index);
++ assert(region->startsHumongous(), "Must start a humongous object");
++ return oop(region->bottom())->is_objArray() || !region->rem_set()->is_empty();
++}
++
++class RegisterHumongousWithInCSetFastTestClosure : public HeapRegionClosure {
++ private:
++ size_t _total_humongous;
++ size_t _candidate_humongous;
++ public:
++ RegisterHumongousWithInCSetFastTestClosure() : _total_humongous(0), _candidate_humongous(0) {
++ }
++
++ virtual bool doHeapRegion(HeapRegion* r) {
++ if (!r->startsHumongous()) {
++ return false;
++ }
++ G1CollectedHeap* g1h = G1CollectedHeap::heap();
++
++ uint region_idx = r->hrm_index();
++ bool is_candidate = !g1h->humongous_region_is_always_live(region_idx);
++ // Is_candidate already filters out humongous regions with some remembered set.
++ // This will not lead to humongous object that we mistakenly keep alive because
++ // during young collection the remembered sets will only be added to.
++ if (is_candidate) {
++ g1h->register_humongous_region_with_in_cset_fast_test(region_idx);
++ _candidate_humongous++;
++ }
++ _total_humongous++;
++
++ return false;
++ }
++
++ size_t total_humongous() const { return _total_humongous; }
++ size_t candidate_humongous() const { return _candidate_humongous; }
++};
++
++void G1CollectedHeap::register_humongous_regions_with_in_cset_fast_test() {
++ if (!G1ReclaimDeadHumongousObjectsAtYoungGC) {
++ g1_policy()->phase_times()->record_fast_reclaim_humongous_stats(0, 0);
++ return;
++ }
++
++ RegisterHumongousWithInCSetFastTestClosure cl;
++ heap_region_iterate(&cl);
++ g1_policy()->phase_times()->record_fast_reclaim_humongous_stats(cl.total_humongous(),
++ cl.candidate_humongous());
++ _has_humongous_reclaim_candidates = cl.candidate_humongous() > 0;
++
++ if (_has_humongous_reclaim_candidates) {
++ clear_humongous_is_live_table();
++ }
++}
++
+ void
+ G1CollectedHeap::setup_surviving_young_words() {
+ assert(_surviving_young_words == NULL, "pre-condition");
+@@ -3893,8 +3815,7 @@
+ return;
+ }
+
+- gclog_or_tty->date_stamp(PrintGCDateStamps);
+- gclog_or_tty->stamp(PrintGCTimeStamps);
++ gclog_or_tty->gclog_stamp(_gc_tracer_stw->gc_id());
+
+ GCCauseString gc_cause_str = GCCauseString("GC pause", gc_cause())
+ .append(g1_policy()->gcs_are_young() ? "(young)" : "(mixed)")
+@@ -4015,6 +3936,7 @@
+ increment_gc_time_stamp();
+
+ verify_before_gc();
++ check_bitmaps("GC Start");
+
+ COMPILER2_PRESENT(DerivedPointerTable::clear());
+
+@@ -4035,7 +3957,7 @@
+
+ // Forget the current alloc region (we might even choose it to be part
+ // of the collection set!).
+- release_mutator_alloc_region();
++ _allocator->release_mutator_alloc_region();
+
+ // We should call this after we retire the mutator alloc
+ // region(s) so that all the ALLOC / RETIRE events are generated
+@@ -4090,6 +4012,8 @@
+
+ g1_policy()->finalize_cset(target_pause_time_ms, evacuation_info);
+
++ register_humongous_regions_with_in_cset_fast_test();
++
+ _cm->note_start_of_gc();
+ // We should not verify the per-thread SATB buffers given that
+ // we have not filtered them yet (we'll do so during the
+@@ -4103,14 +4027,6 @@
+ if (_hr_printer.is_active()) {
+ HeapRegion* hr = g1_policy()->collection_set();
+ while (hr != NULL) {
+- G1HRPrinter::RegionType type;
+- if (!hr->is_young()) {
+- type = G1HRPrinter::Old;
+- } else if (hr->is_survivor()) {
+- type = G1HRPrinter::Survivor;
+- } else {
+- type = G1HRPrinter::Eden;
+- }
+ _hr_printer.cset(hr);
+ hr = hr->next_in_collection_set();
+ }
+@@ -4124,7 +4040,7 @@
+ setup_surviving_young_words();
+
+ // Initialize the GC alloc regions.
+- init_gc_alloc_regions(evacuation_info);
++ _allocator->init_gc_alloc_regions(evacuation_info);
+
+ // Actually do the work...
+ evacuate_collection_set(evacuation_info);
+@@ -4140,6 +4056,9 @@
+ true /* verify_fingers */);
+
+ free_collection_set(g1_policy()->collection_set(), evacuation_info);
++
++ eagerly_reclaim_humongous_regions();
++
+ g1_policy()->clear_collection_set();
+
+ cleanup_surviving_young_words();
+@@ -4147,9 +4066,6 @@
+ // Start a new incremental collection set for the next pause.
+ g1_policy()->start_incremental_cset_building();
+
+- // Clear the _cset_fast_test bitmap in anticipation of adding
+- // regions to the incremental collection set for the next
+- // evacuation pause.
+ clear_cset_fast_test();
+
+ _young_list->reset_sampled_info();
+@@ -4173,7 +4089,7 @@
+ _young_list->reset_auxilary_lists();
+
+ if (evacuation_failed()) {
+- _summary_bytes_used = recalculate_used();
++ _allocator->set_used(recalculate_used());
+ uint n_queues = MAX2((int)ParallelGCThreads, 1);
+ for (uint i = 0; i < n_queues; i++) {
+ if (_evacuation_failed_info_array[i].has_failed()) {
+@@ -4183,7 +4099,7 @@
+ } else {
+ // The "used" of the the collection set have already been subtracted
+ // when they were freed. Add in the bytes evacuated.
+- _summary_bytes_used += g1_policy()->bytes_copied_during_gc();
++ _allocator->increase_used(g1_policy()->bytes_copied_during_gc());
+ }
+
+ if (g1_policy()->during_initial_mark_pause()) {
+@@ -4205,7 +4121,7 @@
+ g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty);
+ #endif // YOUNG_LIST_VERBOSE
+
+- init_mutator_alloc_region();
++ _allocator->init_mutator_alloc_region();
+
+ {
+ size_t expand_bytes = g1_policy()->expansion_amount();
+@@ -4214,10 +4130,7 @@
+ // No need for an ergo verbose message here,
+ // expansion_amount() does this when it returns a value > 0.
+ if (!expand(expand_bytes)) {
+- // We failed to expand the heap so let's verify that
+- // committed/uncommitted amount match the backing store
+- assert(capacity() == _g1_storage.committed_size(), "committed size mismatch");
+- assert(max_capacity() == _g1_storage.reserved_size(), "reserved size mismatch");
++ // We failed to expand the heap. Cannot do anything about it.
+ }
+ }
+ }
+@@ -4263,6 +4176,7 @@
+ increment_gc_time_stamp();
+
+ verify_after_gc();
++ check_bitmaps("GC End");
+
+ assert(!ref_processor_stw()->discovery_enabled(), "Postcondition");
+ ref_processor_stw()->verify_no_references_recorded();
+@@ -4276,10 +4190,6 @@
+ // RETIRE events are generated before the end GC event.
+ _hr_printer.end_gc(false /* full */, (size_t) total_collections());
+
+- if (mark_in_progress()) {
+- concurrent_mark()->update_g1_committed();
+- }
+-
+ #ifdef TRACESPINNING
+ ParallelTaskTerminator::print_termination_counts();
+ #endif
+@@ -4295,7 +4205,7 @@
+ // output from the concurrent mark thread interfering with this
+ // logging output either.
+
+- _hrs.verify_optional();
++ _hrm.verify_optional();
+ verify_region_sets_optional();
+
+ TASKQUEUE_STATS_ONLY(if (ParallelGCVerbose) print_taskqueue_stats());
+@@ -4326,7 +4236,7 @@
+ // this point does not assume that we are the only GC thread
+ // running. Note: of course, the actual marking work will
+ // not start until the safepoint itself is released in
+- // ConcurrentGCThread::safepoint_desynchronize().
++ // SuspendibleThreadSet::desynchronize().
+ doConcurrentMark();
+ }
+
+@@ -4356,75 +4266,6 @@
+ return MIN2(_humongous_object_threshold_in_words, gclab_word_size);
+ }
+
+-void G1CollectedHeap::init_mutator_alloc_region() {
+- assert(_mutator_alloc_region.get() == NULL, "pre-condition");
+- _mutator_alloc_region.init();
+-}
+-
+-void G1CollectedHeap::release_mutator_alloc_region() {
+- _mutator_alloc_region.release();
+- assert(_mutator_alloc_region.get() == NULL, "post-condition");
+-}
+-
+-void G1CollectedHeap::init_gc_alloc_regions(EvacuationInfo& evacuation_info) {
+- assert_at_safepoint(true /* should_be_vm_thread */);
+-
+- _survivor_gc_alloc_region.init();
+- _old_gc_alloc_region.init();
+- HeapRegion* retained_region = _retained_old_gc_alloc_region;
+- _retained_old_gc_alloc_region = NULL;
+-
+- // We will discard the current GC alloc region if:
+- // a) it's in the collection set (it can happen!),
+- // b) it's already full (no point in using it),
+- // c) it's empty (this means that it was emptied during
+- // a cleanup and it should be on the free list now), or
+- // d) it's humongous (this means that it was emptied
+- // during a cleanup and was added to the free list, but
+- // has been subsequently used to allocate a humongous
+- // object that may be less than the region size).
+- if (retained_region != NULL &&
+- !retained_region->in_collection_set() &&
+- !(retained_region->top() == retained_region->end()) &&
+- !retained_region->is_empty() &&
+- !retained_region->isHumongous()) {
+- retained_region->set_saved_mark();
+- // The retained region was added to the old region set when it was
+- // retired. We have to remove it now, since we don't allow regions
+- // we allocate to in the region sets. We'll re-add it later, when
+- // it's retired again.
+- _old_set.remove(retained_region);
+- bool during_im = g1_policy()->during_initial_mark_pause();
+- retained_region->note_start_of_copying(during_im);
+- _old_gc_alloc_region.set(retained_region);
+- _hr_printer.reuse(retained_region);
+- evacuation_info.set_alloc_regions_used_before(retained_region->used());
+- }
+-}
+-
+-void G1CollectedHeap::release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info) {
+- evacuation_info.set_allocation_regions(_survivor_gc_alloc_region.count() +
+- _old_gc_alloc_region.count());
+- _survivor_gc_alloc_region.release();
+- // If we have an old GC alloc region to release, we'll save it in
+- // _retained_old_gc_alloc_region. If we don't
+- // _retained_old_gc_alloc_region will become NULL. This is what we
+- // want either way so no reason to check explicitly for either
+- // condition.
+- _retained_old_gc_alloc_region = _old_gc_alloc_region.release();
+-
+- if (ResizePLAB) {
+- _survivor_plab_stats.adjust_desired_plab_sz(no_of_gc_workers);
+- _old_plab_stats.adjust_desired_plab_sz(no_of_gc_workers);
+- }
+-}
+-
+-void G1CollectedHeap::abandon_gc_alloc_regions() {
+- assert(_survivor_gc_alloc_region.get() == NULL, "pre-condition");
+- assert(_old_gc_alloc_region.get() == NULL, "pre-condition");
+- _retained_old_gc_alloc_region = NULL;
+-}
+-
+ void G1CollectedHeap::init_for_evac_failure(OopsInHeapRegionClosure* cl) {
+ _drain_in_progress = false;
+ set_evac_failure_closure(cl);
+@@ -4565,25 +4406,26 @@
+ }
+
+ HeapWord* G1CollectedHeap::par_allocate_during_gc(GCAllocPurpose purpose,
+- size_t word_size) {
++ size_t word_size,
++ AllocationContext_t context) {
+ if (purpose == GCAllocForSurvived) {
+- HeapWord* result = survivor_attempt_allocation(word_size);
++ HeapWord* result = survivor_attempt_allocation(word_size, context);
+ if (result != NULL) {
+ return result;
+ } else {
+ // Let's try to allocate in the old gen in case we can fit the
+ // object there.
+- return old_attempt_allocation(word_size);
++ return old_attempt_allocation(word_size, context);
+ }
+ } else {
+ assert(purpose == GCAllocForTenured, "sanity");
+- HeapWord* result = old_attempt_allocation(word_size);
++ HeapWord* result = old_attempt_allocation(word_size, context);
+ if (result != NULL) {
+ return result;
+ } else {
+ // Let's try to allocate in the survivors in case we can fit the
+ // object there.
+- return survivor_attempt_allocation(word_size);
++ return survivor_attempt_allocation(word_size, context);
+ }
+ }
+
+@@ -4592,154 +4434,20 @@
+ return NULL;
+ }
+
+-G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) :
+- ParGCAllocBuffer(gclab_word_size), _retired(false) { }
+-
+-G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp)
+- : _g1h(g1h),
+- _refs(g1h->task_queue(queue_num)),
+- _dcq(&g1h->dirty_card_queue_set()),
+- _ct_bs(g1h->g1_barrier_set()),
+- _g1_rem(g1h->g1_rem_set()),
+- _hash_seed(17), _queue_num(queue_num),
+- _term_attempts(0),
+- _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)),
+- _tenured_alloc_buffer(g1h->desired_plab_sz(GCAllocForTenured)),
+- _age_table(false), _scanner(g1h, this, rp),
+- _strong_roots_time(0), _term_time(0),
+- _alloc_buffer_waste(0), _undo_waste(0) {
+- // we allocate G1YoungSurvRateNumRegions plus one entries, since
+- // we "sacrifice" entry 0 to keep track of surviving bytes for
+- // non-young regions (where the age is -1)
+- // We also add a few elements at the beginning and at the end in
+- // an attempt to eliminate cache contention
+- uint real_length = 1 + _g1h->g1_policy()->young_cset_region_length();
+- uint array_length = PADDING_ELEM_NUM +
+- real_length +
+- PADDING_ELEM_NUM;
+- _surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length, mtGC);
+- if (_surviving_young_words_base == NULL)
+- vm_exit_out_of_memory(array_length * sizeof(size_t), OOM_MALLOC_ERROR,
+- "Not enough space for young surv histo.");
+- _surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM;
+- memset(_surviving_young_words, 0, (size_t) real_length * sizeof(size_t));
+-
+- _alloc_buffers[GCAllocForSurvived] = &_surviving_alloc_buffer;
+- _alloc_buffers[GCAllocForTenured] = &_tenured_alloc_buffer;
+-
+- _start = os::elapsedTime();
+-}
+-
+-void
+-G1ParScanThreadState::print_termination_stats_hdr(outputStream* const st)
+-{
+- st->print_raw_cr("GC Termination Stats");
+- st->print_raw_cr(" elapsed --strong roots-- -------termination-------"
+- " ------waste (KiB)------");
+- st->print_raw_cr("thr ms ms % ms % attempts"
+- " total alloc undo");
+- st->print_raw_cr("--- --------- --------- ------ --------- ------ --------"
+- " ------- ------- -------");
+-}
+-
+-void
+-G1ParScanThreadState::print_termination_stats(int i,
+- outputStream* const st) const
+-{
+- const double elapsed_ms = elapsed_time() * 1000.0;
+- const double s_roots_ms = strong_roots_time() * 1000.0;
+- const double term_ms = term_time() * 1000.0;
+- st->print_cr("%3d %9.2f %9.2f %6.2f "
+- "%9.2f %6.2f " SIZE_FORMAT_W(8) " "
+- SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7),
+- i, elapsed_ms, s_roots_ms, s_roots_ms * 100 / elapsed_ms,
+- term_ms, term_ms * 100 / elapsed_ms, term_attempts(),
+- (alloc_buffer_waste() + undo_waste()) * HeapWordSize / K,
+- alloc_buffer_waste() * HeapWordSize / K,
+- undo_waste() * HeapWordSize / K);
+-}
+-
+-#ifdef ASSERT
+-bool G1ParScanThreadState::verify_ref(narrowOop* ref) const {
+- assert(ref != NULL, "invariant");
+- assert(UseCompressedOops, "sanity");
+- assert(!has_partial_array_mask(ref), err_msg("ref=" PTR_FORMAT, ref));
+- oop p = oopDesc::load_decode_heap_oop(ref);
+- assert(_g1h->is_in_g1_reserved(p),
+- err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, (void *)p));
+- return true;
+-}
+-
+-bool G1ParScanThreadState::verify_ref(oop* ref) const {
+- assert(ref != NULL, "invariant");
+- if (has_partial_array_mask(ref)) {
+- // Must be in the collection set--it's already been copied.
+- oop p = clear_partial_array_mask(ref);
+- assert(_g1h->obj_in_cs(p),
+- err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, (void *)p));
+- } else {
+- oop p = oopDesc::load_decode_heap_oop(ref);
+- assert(_g1h->is_in_g1_reserved(p),
+- err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, (void *)p));
+- }
+- return true;
+-}
+-
+-bool G1ParScanThreadState::verify_task(StarTask ref) const {
+- if (ref.is_narrow()) {
+- return verify_ref((narrowOop*) ref);
+- } else {
+- return verify_ref((oop*) ref);
+- }
+-}
+-#endif // ASSERT
+-
+-void G1ParScanThreadState::trim_queue() {
+- assert(_evac_failure_cl != NULL, "not set");
+-
+- StarTask ref;
+- do {
+- // Drain the overflow stack first, so other threads can steal.
+- while (refs()->pop_overflow(ref)) {
+- deal_with_reference(ref);
+- }
+-
+- while (refs()->pop_local(ref)) {
+- deal_with_reference(ref);
+- }
+- } while (!refs()->is_empty());
+-}
+-
+-G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1,
+- G1ParScanThreadState* par_scan_state) :
+- _g1(g1), _par_scan_state(par_scan_state),
+- _worker_id(par_scan_state->queue_num()) { }
+-
+ void G1ParCopyHelper::mark_object(oop obj) {
+-#ifdef ASSERT
+- HeapRegion* hr = _g1->heap_region_containing(obj);
+- assert(hr != NULL, "sanity");
+- assert(!hr->in_collection_set(), "should not mark objects in the CSet");
+-#endif // ASSERT
++ assert(!_g1->heap_region_containing(obj)->in_collection_set(), "should not mark objects in the CSet");
+
+ // We know that the object is not moving so it's safe to read its size.
+ _cm->grayRoot(obj, (size_t) obj->size(), _worker_id);
+ }
+
+ void G1ParCopyHelper::mark_forwarded_object(oop from_obj, oop to_obj) {
+-#ifdef ASSERT
+ assert(from_obj->is_forwarded(), "from obj should be forwarded");
+ assert(from_obj->forwardee() == to_obj, "to obj should be the forwardee");
+ assert(from_obj != to_obj, "should not be self-forwarded");
+
+- HeapRegion* from_hr = _g1->heap_region_containing(from_obj);
+- assert(from_hr != NULL, "sanity");
+- assert(from_hr->in_collection_set(), "from obj should be in the CSet");
+-
+- HeapRegion* to_hr = _g1->heap_region_containing(to_obj);
+- assert(to_hr != NULL, "sanity");
+- assert(!to_hr->in_collection_set(), "should not mark objects in the CSet");
+-#endif // ASSERT
++ assert(_g1->heap_region_containing(from_obj)->in_collection_set(), "from obj should be in the CSet");
++ assert(!_g1->heap_region_containing(to_obj)->in_collection_set(), "should not mark objects in the CSet");
+
+ // The object might be in the process of being copied by another
+ // worker so we cannot trust that its to-space image is
+@@ -4748,107 +4456,6 @@
+ _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id);
+ }
+
+-oop G1ParScanThreadState::copy_to_survivor_space(oop const old) {
+- size_t word_sz = old->size();
+- HeapRegion* from_region = _g1h->heap_region_containing_raw(old);
+- // +1 to make the -1 indexes valid...
+- int young_index = from_region->young_index_in_cset()+1;
+- assert( (from_region->is_young() && young_index > 0) ||
+- (!from_region->is_young() && young_index == 0), "invariant" );
+- G1CollectorPolicy* g1p = _g1h->g1_policy();
+- markOop m = old->mark();
+- int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age()
+- : m->age();
+- GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age,
+- word_sz);
+- HeapWord* obj_ptr = allocate(alloc_purpose, word_sz);
+-#ifndef PRODUCT
+- // Should this evacuation fail?
+- if (_g1h->evacuation_should_fail()) {
+- if (obj_ptr != NULL) {
+- undo_allocation(alloc_purpose, obj_ptr, word_sz);
+- obj_ptr = NULL;
+- }
+- }
+-#endif // !PRODUCT
+-
+- if (obj_ptr == NULL) {
+- // This will either forward-to-self, or detect that someone else has
+- // installed a forwarding pointer.
+- return _g1h->handle_evacuation_failure_par(this, old);
+- }
+-
+- oop obj = oop(obj_ptr);
+-
+- // We're going to allocate linearly, so might as well prefetch ahead.
+- Prefetch::write(obj_ptr, PrefetchCopyIntervalInBytes);
+-
+- oop forward_ptr = old->forward_to_atomic(obj);
+- if (forward_ptr == NULL) {
+- Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz);
+-
+- // alloc_purpose is just a hint to allocate() above, recheck the type of region
+- // we actually allocated from and update alloc_purpose accordingly
+- HeapRegion* to_region = _g1h->heap_region_containing_raw(obj_ptr);
+- alloc_purpose = to_region->is_young() ? GCAllocForSurvived : GCAllocForTenured;
+-
+- if (g1p->track_object_age(alloc_purpose)) {
+- // We could simply do obj->incr_age(). However, this causes a
+- // performance issue. obj->incr_age() will first check whether
+- // the object has a displaced mark by checking its mark word;
+- // getting the mark word from the new location of the object
+- // stalls. So, given that we already have the mark word and we
+- // are about to install it anyway, it's better to increase the
+- // age on the mark word, when the object does not have a
+- // displaced mark word. We're not expecting many objects to have
+- // a displaced marked word, so that case is not optimized
+- // further (it could be...) and we simply call obj->incr_age().
+-
+- if (m->has_displaced_mark_helper()) {
+- // in this case, we have to install the mark word first,
+- // otherwise obj looks to be forwarded (the old mark word,
+- // which contains the forward pointer, was copied)
+- obj->set_mark(m);
+- obj->incr_age();
+- } else {
+- m = m->incr_age();
+- obj->set_mark(m);
+- }
+- age_table()->add(obj, word_sz);
+- } else {
+- obj->set_mark(m);
+- }
+-
+- if (G1StringDedup::is_enabled()) {
+- G1StringDedup::enqueue_from_evacuation(from_region->is_young(),
+- to_region->is_young(),
+- queue_num(),
+- obj);
+- }
+-
+- size_t* surv_young_words = surviving_young_words();
+- surv_young_words[young_index] += word_sz;
+-
+- if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) {
+- // We keep track of the next start index in the length field of
+- // the to-space object. The actual length can be found in the
+- // length field of the from-space object.
+- arrayOop(obj)->set_length(0);
+- oop* old_p = set_partial_array_mask(old);
+- push_on_queue(old_p);
+- } else {
+- // No point in using the slower heap_region_containing() method,
+- // given that we know obj is in the heap.
+- _scanner.set_region(_g1h->heap_region_containing_raw(obj));
+- obj->oop_iterate_backwards(&_scanner);
+- }
+- } else {
+- undo_allocation(alloc_purpose, obj_ptr, word_sz);
+- obj = forward_ptr;
+- }
+- return obj;
+-}
+-
+ template <class T>
+ void G1ParCopyHelper::do_klass_barrier(T* p, oop new_obj) {
+ if (_g1->heap_region_containing_raw(new_obj)->is_young()) {
+@@ -4856,7 +4463,7 @@
+ }
+ }
+
+-template <G1Barrier barrier, bool do_mark_object>
++template <G1Barrier barrier, G1Mark do_mark_object>
+ template <class T>
+ void G1ParCopyClosure<barrier, do_mark_object>::do_oop_work(T* p) {
+ T heap_oop = oopDesc::load_heap_oop(p);
+@@ -4869,7 +4476,9 @@
+
+ assert(_worker_id == _par_scan_state->queue_num(), "sanity");
+
+- if (_g1->in_cset_fast_test(obj)) {
++ G1CollectedHeap::in_cset_state_t state = _g1->in_cset_state(obj);
++
++ if (state == G1CollectedHeap::InCSet) {
+ oop forwardee;
+ if (obj->is_forwarded()) {
+ forwardee = obj->forwardee();
+@@ -4878,7 +4487,7 @@
+ }
+ assert(forwardee != NULL, "forwardee should not be NULL");
+ oopDesc::encode_store_heap_oop(p, forwardee);
+- if (do_mark_object && forwardee != obj) {
++ if (do_mark_object != G1MarkNone && forwardee != obj) {
+ // If the object is self-forwarded we don't need to explicitly
+ // mark it, the evacuation failure protocol will do so.
+ mark_forwarded_object(obj, forwardee);
+@@ -4888,10 +4497,12 @@
+ do_klass_barrier(p, forwardee);
+ }
+ } else {
++ if (state == G1CollectedHeap::IsHumongous) {
++ _g1->set_humongous_is_live(obj);
++ }
+ // The object is not in collection set. If we're a root scanning
+- // closure during an initial mark pause (i.e. do_mark_object will
+- // be true) then attempt to mark the object.
+- if (do_mark_object) {
++ // closure during an initial mark pause then attempt to mark the object.
++ if (do_mark_object == G1MarkFromRoot) {
+ mark_object(obj);
+ }
+ }
+@@ -4901,8 +4512,8 @@
+ }
+ }
+
+-template void G1ParCopyClosure<G1BarrierEvac, false>::do_oop_work(oop* p);
+-template void G1ParCopyClosure<G1BarrierEvac, false>::do_oop_work(narrowOop* p);
++template void G1ParCopyClosure<G1BarrierEvac, G1MarkNone>::do_oop_work(oop* p);
++template void G1ParCopyClosure<G1BarrierEvac, G1MarkNone>::do_oop_work(narrowOop* p);
+
+ class G1ParEvacuateFollowersClosure : public VoidClosure {
+ protected:
+@@ -4938,27 +4549,11 @@
+ }
+
+ void G1ParEvacuateFollowersClosure::do_void() {
+- StarTask stolen_task;
+ G1ParScanThreadState* const pss = par_scan_state();
+ pss->trim_queue();
+-
+ do {
+- while (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) {
+- assert(pss->verify_task(stolen_task), "sanity");
+- if (stolen_task.is_narrow()) {
+- pss->deal_with_reference((narrowOop*) stolen_task);
+- } else {
+- pss->deal_with_reference((oop*) stolen_task);
+- }
+-
+- // We've just processed a reference and we might have made
+- // available new entries on the queues. So we have to make sure
+- // we drain the queues as necessary.
+- pss->trim_queue();
+- }
++ pss->steal_and_trim_queue(queues());
+ } while (!offer_termination());
+-
+- pss->retire_alloc_buffers();
+ }
+
+ class G1KlassScanClosure : public KlassClosure {
+@@ -4987,6 +4582,56 @@
+ }
+ };
+
++class G1CodeBlobClosure : public CodeBlobClosure {
++ class HeapRegionGatheringOopClosure : public OopClosure {
++ G1CollectedHeap* _g1h;
++ OopClosure* _work;
++ nmethod* _nm;
++
++ template <typename T>
++ void do_oop_work(T* p) {
++ _work->do_oop(p);
++ T oop_or_narrowoop = oopDesc::load_heap_oop(p);
++ if (!oopDesc::is_null(oop_or_narrowoop)) {
++ oop o = oopDesc::decode_heap_oop_not_null(oop_or_narrowoop);
++ HeapRegion* hr = _g1h->heap_region_containing_raw(o);
++ assert(!_g1h->obj_in_cs(o) || hr->rem_set()->strong_code_roots_list_contains(_nm), "if o still in CS then evacuation failed and nm must already be in the remset");
++ hr->add_strong_code_root(_nm);
++ }
++ }
++
++ public:
++ HeapRegionGatheringOopClosure(OopClosure* oc) : _g1h(G1CollectedHeap::heap()), _work(oc), _nm(NULL) {}
++
++ void do_oop(oop* o) {
++ do_oop_work(o);
++ }
++
++ void do_oop(narrowOop* o) {
++ do_oop_work(o);
++ }
++
++ void set_nm(nmethod* nm) {
++ _nm = nm;
++ }
++ };
++
++ HeapRegionGatheringOopClosure _oc;
++public:
++ G1CodeBlobClosure(OopClosure* oc) : _oc(oc) {}
++
++ void do_code_blob(CodeBlob* cb) {
++ nmethod* nm = cb->as_nmethod_or_null();
++ if (nm != NULL) {
++ if (!nm->test_set_oops_do_mark()) {
++ _oc.set_nm(nm);
++ nm->oops_do(&_oc);
++ nm->fix_oop_relocations();
++ }
++ }
++ }
++};
++
+ class G1ParTask : public AbstractGangTask {
+ protected:
+ G1CollectedHeap* _g1h;
+@@ -4997,14 +4642,8 @@
+ Mutex _stats_lock;
+ Mutex* stats_lock() { return &_stats_lock; }
+
+- size_t getNCards() {
+- return (_g1h->capacity() + G1BlockOffsetSharedArray::N_bytes - 1)
+- / G1BlockOffsetSharedArray::N_bytes;
+- }
+-
+ public:
+- G1ParTask(G1CollectedHeap* g1h,
+- RefToScanQueueSet *task_queues)
++ G1ParTask(G1CollectedHeap* g1h, RefToScanQueueSet *task_queues)
+ : AbstractGangTask("G1 collection"),
+ _g1h(g1h),
+ _queues(task_queues),
+@@ -5032,6 +4671,35 @@
+ _n_workers = active_workers;
+ }
+
++ // Helps out with CLD processing.
++ //
++ // During InitialMark we need to:
++ // 1) Scavenge all CLDs for the young GC.
++ // 2) Mark all objects directly reachable from strong CLDs.
++ template <G1Mark do_mark_object>
++ class G1CLDClosure : public CLDClosure {
++ G1ParCopyClosure<G1BarrierNone, do_mark_object>* _oop_closure;
++ G1ParCopyClosure<G1BarrierKlass, do_mark_object> _oop_in_klass_closure;
++ G1KlassScanClosure _klass_in_cld_closure;
++ bool _claim;
++
++ public:
++ G1CLDClosure(G1ParCopyClosure<G1BarrierNone, do_mark_object>* oop_closure,
++ bool only_young, bool claim)
++ : _oop_closure(oop_closure),
++ _oop_in_klass_closure(oop_closure->g1(),
++ oop_closure->pss(),
++ oop_closure->rp()),
++ _klass_in_cld_closure(&_oop_in_klass_closure, only_young),
++ _claim(claim) {
++
++ }
++
++ void do_cld(ClassLoaderData* cld) {
++ cld->oops_do(_oop_closure, &_klass_in_cld_closure, _claim);
++ }
++ };
++
+ void work(uint worker_id) {
+ if (worker_id >= _n_workers) return; // no work needed this round
+
+@@ -5049,40 +4717,67 @@
+
+ pss.set_evac_failure_closure(&evac_failure_cl);
+
+- G1ParScanExtRootClosure only_scan_root_cl(_g1h, &pss, rp);
+- G1ParScanMetadataClosure only_scan_metadata_cl(_g1h, &pss, rp);
+-
+- G1ParScanAndMarkExtRootClosure scan_mark_root_cl(_g1h, &pss, rp);
+- G1ParScanAndMarkMetadataClosure scan_mark_metadata_cl(_g1h, &pss, rp);
+-
+- bool only_young = _g1h->g1_policy()->gcs_are_young();
+- G1KlassScanClosure scan_mark_klasses_cl_s(&scan_mark_metadata_cl, false);
+- G1KlassScanClosure only_scan_klasses_cl_s(&only_scan_metadata_cl, only_young);
+-
+- OopClosure* scan_root_cl = &only_scan_root_cl;
+- G1KlassScanClosure* scan_klasses_cl = &only_scan_klasses_cl_s;
++ bool only_young = _g1h->g1_policy()->gcs_are_young();
++
++ // Non-IM young GC.
++ G1ParCopyClosure<G1BarrierNone, G1MarkNone> scan_only_root_cl(_g1h, &pss, rp);
++ G1CLDClosure<G1MarkNone> scan_only_cld_cl(&scan_only_root_cl,
++ only_young, // Only process dirty klasses.
++ false); // No need to claim CLDs.
++ // IM young GC.
++ // Strong roots closures.
++ G1ParCopyClosure<G1BarrierNone, G1MarkFromRoot> scan_mark_root_cl(_g1h, &pss, rp);
++ G1CLDClosure<G1MarkFromRoot> scan_mark_cld_cl(&scan_mark_root_cl,
++ false, // Process all klasses.
++ true); // Need to claim CLDs.
++ // Weak roots closures.
++ G1ParCopyClosure<G1BarrierNone, G1MarkPromotedFromRoot> scan_mark_weak_root_cl(_g1h, &pss, rp);
++ G1CLDClosure<G1MarkPromotedFromRoot> scan_mark_weak_cld_cl(&scan_mark_weak_root_cl,
++ false, // Process all klasses.
++ true); // Need to claim CLDs.
++
++ G1CodeBlobClosure scan_only_code_cl(&scan_only_root_cl);
++ G1CodeBlobClosure scan_mark_code_cl(&scan_mark_root_cl);
++ // IM Weak code roots are handled later.
++
++ OopClosure* strong_root_cl;
++ OopClosure* weak_root_cl;
++ CLDClosure* strong_cld_cl;
++ CLDClosure* weak_cld_cl;
++ CodeBlobClosure* strong_code_cl;
+
+ if (_g1h->g1_policy()->during_initial_mark_pause()) {
+ // We also need to mark copied objects.
+- scan_root_cl = &scan_mark_root_cl;
+- scan_klasses_cl = &scan_mark_klasses_cl_s;
++ strong_root_cl = &scan_mark_root_cl;
++ strong_cld_cl = &scan_mark_cld_cl;
++ strong_code_cl = &scan_mark_code_cl;
++ if (ClassUnloadingWithConcurrentMark) {
++ weak_root_cl = &scan_mark_weak_root_cl;
++ weak_cld_cl = &scan_mark_weak_cld_cl;
++ } else {
++ weak_root_cl = &scan_mark_root_cl;
++ weak_cld_cl = &scan_mark_cld_cl;
++ }
++ } else {
++ strong_root_cl = &scan_only_root_cl;
++ weak_root_cl = &scan_only_root_cl;
++ strong_cld_cl = &scan_only_cld_cl;
++ weak_cld_cl = &scan_only_cld_cl;
++ strong_code_cl = &scan_only_code_cl;
+ }
+
+- G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, &pss);
+-
+- // Don't scan the scavengable methods in the code cache as part
+- // of strong root scanning. The code roots that point into a
+- // region in the collection set are scanned when we scan the
+- // region's RSet.
+- int so = SharedHeap::SO_AllClasses | SharedHeap::SO_Strings;
++
++ G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, &pss);
+
+ pss.start_strong_roots();
+- _g1h->g1_process_strong_roots(/* is scavenging */ true,
+- SharedHeap::ScanningOption(so),
+- scan_root_cl,
+- &push_heap_rs_cl,
+- scan_klasses_cl,
+- worker_id);
++ _g1h->g1_process_roots(strong_root_cl,
++ weak_root_cl,
++ &push_heap_rs_cl,
++ strong_cld_cl,
++ weak_cld_cl,
++ strong_code_cl,
++ worker_id);
++
+ pss.end_strong_roots();
+
+ {
+@@ -5102,7 +4797,7 @@
+ pss.print_termination_stats(worker_id);
+ }
+
+- assert(pss.refs()->is_empty(), "should be empty");
++ assert(pss.queue_is_empty(), "should be empty");
+
+ // Close the inner scope so that the ResourceMark and HandleMark
+ // destructors are executed here and are included as part of the
+@@ -5120,30 +4815,32 @@
+
+ void
+ G1CollectedHeap::
+-g1_process_strong_roots(bool is_scavenging,
+- ScanningOption so,
+- OopClosure* scan_non_heap_roots,
+- OopsInHeapRegionClosure* scan_rs,
+- G1KlassScanClosure* scan_klasses,
+- uint worker_i) {
+-
+- // First scan the strong roots
++g1_process_roots(OopClosure* scan_non_heap_roots,
++ OopClosure* scan_non_heap_weak_roots,
++ OopsInHeapRegionClosure* scan_rs,
++ CLDClosure* scan_strong_clds,
++ CLDClosure* scan_weak_clds,
++ CodeBlobClosure* scan_strong_code,
++ uint worker_i) {
++
++ // First scan the shared roots.
+ double ext_roots_start = os::elapsedTime();
+ double closure_app_time_sec = 0.0;
+
++ bool during_im = _g1h->g1_policy()->during_initial_mark_pause();
++ bool trace_metadata = during_im && ClassUnloadingWithConcurrentMark;
++
+ BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots);
+-
+- assert(so & SO_CodeCache || scan_rs != NULL, "must scan code roots somehow");
+- // Walk the code cache/strong code roots w/o buffering, because StarTask
+- // cannot handle unaligned oop locations.
+- CodeBlobToOopClosure eager_scan_code_roots(scan_non_heap_roots, true /* do_marking */);
+-
+- process_strong_roots(false, // no scoping; this is parallel code
+- is_scavenging, so,
+- &buf_scan_non_heap_roots,
+- &eager_scan_code_roots,
+- scan_klasses
+- );
++ BufferingOopClosure buf_scan_non_heap_weak_roots(scan_non_heap_weak_roots);
++
++ process_roots(false, // no scoping; this is parallel code
++ SharedHeap::SO_None,
++ &buf_scan_non_heap_roots,
++ &buf_scan_non_heap_weak_roots,
++ scan_strong_clds,
++ // Unloading Initial Marks handle the weak CLDs separately.
++ (trace_metadata ? NULL : scan_weak_clds),
++ scan_strong_code);
+
+ // Now the CM ref_processor roots.
+ if (!_process_strong_tasks->is_task_claimed(G1H_PS_refProcessor_oops_do)) {
+@@ -5154,10 +4851,21 @@
+ ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots);
+ }
+
++ if (trace_metadata) {
++ // Barrier to make sure all workers passed
++ // the strong CLD and strong nmethods phases.
++ active_strong_roots_scope()->wait_until_all_workers_done_with_threads(n_par_threads());
++
++ // Now take the complement of the strong CLDs.
++ ClassLoaderDataGraph::roots_cld_do(NULL, scan_weak_clds);
++ }
++
+ // Finish up any enqueued closure apps (attributed as object copy time).
+ buf_scan_non_heap_roots.done();
+-
+- double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds();
++ buf_scan_non_heap_weak_roots.done();
++
++ double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds()
++ + buf_scan_non_heap_weak_roots.closure_app_seconds();
+
+ g1_policy()->phase_times()->record_obj_copy_time(worker_i, obj_copy_time_sec * 1000.0);
+
+@@ -5181,32 +4889,14 @@
+ }
+ g1_policy()->phase_times()->record_satb_filtering_time(worker_i, satb_filtering_ms);
+
+- // If this is an initial mark pause, and we're not scanning
+- // the entire code cache, we need to mark the oops in the
+- // strong code root lists for the regions that are not in
+- // the collection set.
+- // Note all threads participate in this set of root tasks.
+- double mark_strong_code_roots_ms = 0.0;
+- if (g1_policy()->during_initial_mark_pause() && !(so & SO_CodeCache)) {
+- double mark_strong_roots_start = os::elapsedTime();
+- mark_strong_code_roots(worker_i);
+- mark_strong_code_roots_ms = (os::elapsedTime() - mark_strong_roots_start) * 1000.0;
+- }
+- g1_policy()->phase_times()->record_strong_code_root_mark_time(worker_i, mark_strong_code_roots_ms);
+-
+ // Now scan the complement of the collection set.
+- if (scan_rs != NULL) {
+- g1_rem_set()->oops_into_collection_set_do(scan_rs, &eager_scan_code_roots, worker_i);
+- }
++ G1CodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots);
++
++ g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i);
++
+ _process_strong_tasks->all_tasks_completed();
+ }
+
+-void
+-G1CollectedHeap::g1_process_weak_roots(OopClosure* root_closure) {
+- CodeBlobToOopClosure roots_in_blobs(root_closure, /*do_marking=*/ false);
+- SharedHeap::process_weak_roots(root_closure, &roots_in_blobs);
+-}
+-
+ class G1StringSymbolTableUnlinkTask : public AbstractGangTask {
+ private:
+ BoolObjectClosure* _is_alive;
+@@ -5224,7 +4914,8 @@
+ bool _do_in_parallel;
+ public:
+ G1StringSymbolTableUnlinkTask(BoolObjectClosure* is_alive, bool process_strings, bool process_symbols) :
+- AbstractGangTask("Par String/Symbol table unlink"), _is_alive(is_alive),
++ AbstractGangTask("String/Symbol Unlinking"),
++ _is_alive(is_alive),
+ _do_in_parallel(G1CollectedHeap::use_parallel_gc_threads()),
+ _process_strings(process_strings), _strings_processed(0), _strings_removed(0),
+ _process_symbols(process_symbols), _symbols_processed(0), _symbols_removed(0) {
+@@ -5246,6 +4937,14 @@
+ guarantee(!_process_symbols || !_do_in_parallel || SymbolTable::parallel_claimed_index() >= _initial_symbol_table_size,
+ err_msg("claim value "INT32_FORMAT" after unlink less than initial symbol table size "INT32_FORMAT,
+ SymbolTable::parallel_claimed_index(), _initial_symbol_table_size));
++
++ if (G1TraceStringSymbolTableScrubbing) {
++ gclog_or_tty->print_cr("Cleaned string and symbol table, "
++ "strings: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed, "
++ "symbols: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed",
++ strings_processed(), strings_removed(),
++ symbols_processed(), symbols_removed());
++ }
+ }
+
+ void work(uint worker_id) {
+@@ -5281,12 +4980,300 @@
+ size_t symbols_removed() const { return (size_t)_symbols_removed; }
+ };
+
+-void G1CollectedHeap::unlink_string_and_symbol_table(BoolObjectClosure* is_alive,
+- bool process_strings, bool process_symbols) {
++class G1CodeCacheUnloadingTask VALUE_OBJ_CLASS_SPEC {
++private:
++ static Monitor* _lock;
++
++ BoolObjectClosure* const _is_alive;
++ const bool _unloading_occurred;
++ const uint _num_workers;
++
++ // Variables used to claim nmethods.
++ nmethod* _first_nmethod;
++ volatile nmethod* _claimed_nmethod;
++
++ // The list of nmethods that need to be processed by the second pass.
++ volatile nmethod* _postponed_list;
++ volatile uint _num_entered_barrier;
++
++ public:
++ G1CodeCacheUnloadingTask(uint num_workers, BoolObjectClosure* is_alive, bool unloading_occurred) :
++ _is_alive(is_alive),
++ _unloading_occurred(unloading_occurred),
++ _num_workers(num_workers),
++ _first_nmethod(NULL),
++ _claimed_nmethod(NULL),
++ _postponed_list(NULL),
++ _num_entered_barrier(0)
++ {
++ nmethod::increase_unloading_clock();
++ _first_nmethod = CodeCache::alive_nmethod(CodeCache::first());
++ _claimed_nmethod = (volatile nmethod*)_first_nmethod;
++ }
++
++ ~G1CodeCacheUnloadingTask() {
++ CodeCache::verify_clean_inline_caches();
++
++ CodeCache::set_needs_cache_clean(false);
++ guarantee(CodeCache::scavenge_root_nmethods() == NULL, "Must be");
++
++ CodeCache::verify_icholder_relocations();
++ }
++
++ private:
++ void add_to_postponed_list(nmethod* nm) {
++ nmethod* old;
++ do {
++ old = (nmethod*)_postponed_list;
++ nm->set_unloading_next(old);
++ } while ((nmethod*)Atomic::cmpxchg_ptr(nm, &_postponed_list, old) != old);
++ }
++
++ void clean_nmethod(nmethod* nm) {
++ bool postponed = nm->do_unloading_parallel(_is_alive, _unloading_occurred);
++
++ if (postponed) {
++ // This nmethod referred to an nmethod that has not been cleaned/unloaded yet.
++ add_to_postponed_list(nm);
++ }
++
++ // Mark that this thread has been cleaned/unloaded.
++ // After this call, it will be safe to ask if this nmethod was unloaded or not.
++ nm->set_unloading_clock(nmethod::global_unloading_clock());
++ }
++
++ void clean_nmethod_postponed(nmethod* nm) {
++ nm->do_unloading_parallel_postponed(_is_alive, _unloading_occurred);
++ }
++
++ static const int MaxClaimNmethods = 16;
++
++ void claim_nmethods(nmethod** claimed_nmethods, int *num_claimed_nmethods) {
++ nmethod* first;
++ nmethod* last;
++
++ do {
++ *num_claimed_nmethods = 0;
++
++ first = last = (nmethod*)_claimed_nmethod;
++
++ if (first != NULL) {
++ for (int i = 0; i < MaxClaimNmethods; i++) {
++ last = CodeCache::alive_nmethod(CodeCache::next(last));
++
++ if (last == NULL) {
++ break;
++ }
++
++ claimed_nmethods[i] = last;
++ (*num_claimed_nmethods)++;
++ }
++ }
++
++ } while ((nmethod*)Atomic::cmpxchg_ptr(last, &_claimed_nmethod, first) != first);
++ }
++
++ nmethod* claim_postponed_nmethod() {
++ nmethod* claim;
++ nmethod* next;
++
++ do {
++ claim = (nmethod*)_postponed_list;
++ if (claim == NULL) {
++ return NULL;
++ }
++
++ next = claim->unloading_next();
++
++ } while ((nmethod*)Atomic::cmpxchg_ptr(next, &_postponed_list, claim) != claim);
++
++ return claim;
++ }
++
++ public:
++ // Mark that we're done with the first pass of nmethod cleaning.
++ void barrier_mark(uint worker_id) {
++ MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag);
++ _num_entered_barrier++;
++ if (_num_entered_barrier == _num_workers) {
++ ml.notify_all();
++ }
++ }
++
++ // See if we have to wait for the other workers to
++ // finish their first-pass nmethod cleaning work.
++ void barrier_wait(uint worker_id) {
++ if (_num_entered_barrier < _num_workers) {
++ MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag);
++ while (_num_entered_barrier < _num_workers) {
++ ml.wait(Mutex::_no_safepoint_check_flag, 0, false);
++ }
++ }
++ }
++
++ // Cleaning and unloading of nmethods. Some work has to be postponed
++ // to the second pass, when we know which nmethods survive.
++ void work_first_pass(uint worker_id) {
++ // The first nmethods is claimed by the first worker.
++ if (worker_id == 0 && _first_nmethod != NULL) {
++ clean_nmethod(_first_nmethod);
++ _first_nmethod = NULL;
++ }
++
++ int num_claimed_nmethods;
++ nmethod* claimed_nmethods[MaxClaimNmethods];
++
++ while (true) {
++ claim_nmethods(claimed_nmethods, &num_claimed_nmethods);
++
++ if (num_claimed_nmethods == 0) {
++ break;
++ }
++
++ for (int i = 0; i < num_claimed_nmethods; i++) {
++ clean_nmethod(claimed_nmethods[i]);
++ }
++ }
++
++ // The nmethod cleaning helps out and does the CodeCache part of MetadataOnStackMark.
++ // Need to retire the buffers now that this thread has stopped cleaning nmethods.
++ MetadataOnStackMark::retire_buffer_for_thread(Thread::current());
++ }
++
++ void work_second_pass(uint worker_id) {
++ nmethod* nm;
++ // Take care of postponed nmethods.
++ while ((nm = claim_postponed_nmethod()) != NULL) {
++ clean_nmethod_postponed(nm);
++ }
++ }
++};
++
++Monitor* G1CodeCacheUnloadingTask::_lock = new Monitor(Mutex::leaf, "Code Cache Unload lock");
++
++class G1KlassCleaningTask : public StackObj {
++ BoolObjectClosure* _is_alive;
++ volatile jint _clean_klass_tree_claimed;
++ ClassLoaderDataGraphKlassIteratorAtomic _klass_iterator;
++
++ public:
++ G1KlassCleaningTask(BoolObjectClosure* is_alive) :
++ _is_alive(is_alive),
++ _clean_klass_tree_claimed(0),
++ _klass_iterator() {
++ }
++
++ private:
++ bool claim_clean_klass_tree_task() {
++ if (_clean_klass_tree_claimed) {
++ return false;
++ }
++
++ return Atomic::cmpxchg(1, (jint*)&_clean_klass_tree_claimed, 0) == 0;
++ }
++
++ InstanceKlass* claim_next_klass() {
++ Klass* klass;
++ do {
++ klass =_klass_iterator.next_klass();
++ } while (klass != NULL && !klass->oop_is_instance());
++
++ return (InstanceKlass*)klass;
++ }
++
++public:
++
++ void clean_klass(InstanceKlass* ik) {
++ ik->clean_implementors_list(_is_alive);
++ ik->clean_method_data(_is_alive);
++
++ // G1 specific cleanup work that has
++ // been moved here to be done in parallel.
++ ik->clean_dependent_nmethods();
++ if (JvmtiExport::has_redefined_a_class()) {
++ InstanceKlass::purge_previous_versions(ik);
++ }
++ }
++
++ void work() {
++ ResourceMark rm;
++
++ // One worker will clean the subklass/sibling klass tree.
++ if (claim_clean_klass_tree_task()) {
++ Klass::clean_subklass_tree(_is_alive);
++ }
++
++ // All workers will help cleaning the classes,
++ InstanceKlass* klass;
++ while ((klass = claim_next_klass()) != NULL) {
++ clean_klass(klass);
++ }
++ }
++};
++
++// To minimize the remark pause times, the tasks below are done in parallel.
++class G1ParallelCleaningTask : public AbstractGangTask {
++private:
++ G1StringSymbolTableUnlinkTask _string_symbol_task;
++ G1CodeCacheUnloadingTask _code_cache_task;
++ G1KlassCleaningTask _klass_cleaning_task;
++
++public:
++ // The constructor is run in the VMThread.
++ G1ParallelCleaningTask(BoolObjectClosure* is_alive, bool process_strings, bool process_symbols, uint num_workers, bool unloading_occurred) :
++ AbstractGangTask("Parallel Cleaning"),
++ _string_symbol_task(is_alive, process_strings, process_symbols),
++ _code_cache_task(num_workers, is_alive, unloading_occurred),
++ _klass_cleaning_task(is_alive) {
++ }
++
++ void pre_work_verification() {
++ // The VM Thread will have registered Metadata during the single-threaded phase of MetadataStackOnMark.
++ assert(Thread::current()->is_VM_thread()
++ || !MetadataOnStackMark::has_buffer_for_thread(Thread::current()), "Should be empty");
++ }
++
++ void post_work_verification() {
++ assert(!MetadataOnStackMark::has_buffer_for_thread(Thread::current()), "Should be empty");
++ }
++
++ // The parallel work done by all worker threads.
++ void work(uint worker_id) {
++ pre_work_verification();
++
++ // Do first pass of code cache cleaning.
++ _code_cache_task.work_first_pass(worker_id);
++
++ // Let the threads mark that the first pass is done.
++ _code_cache_task.barrier_mark(worker_id);
++
++ // Clean the Strings and Symbols.
++ _string_symbol_task.work(worker_id);
++
++ // Wait for all workers to finish the first code cache cleaning pass.
++ _code_cache_task.barrier_wait(worker_id);
++
++ // Do the second code cache cleaning work, which realize on
++ // the liveness information gathered during the first pass.
++ _code_cache_task.work_second_pass(worker_id);
++
++ // Clean all klasses that were not unloaded.
++ _klass_cleaning_task.work();
++
++ post_work_verification();
++ }
++};
++
++
++void G1CollectedHeap::parallel_cleaning(BoolObjectClosure* is_alive,
++ bool process_strings,
++ bool process_symbols,
++ bool class_unloading_occurred) {
+ uint n_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
+- _g1h->workers()->active_workers() : 1);
+-
+- G1StringSymbolTableUnlinkTask g1_unlink_task(is_alive, process_strings, process_symbols);
++ workers()->active_workers() : 1);
++
++ G1ParallelCleaningTask g1_unlink_task(is_alive, process_strings, process_symbols,
++ n_workers, class_unloading_occurred);
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ set_par_threads(n_workers);
+ workers()->run_task(&g1_unlink_task);
+@@ -5294,12 +5281,21 @@
+ } else {
+ g1_unlink_task.work(0);
+ }
+- if (G1TraceStringSymbolTableScrubbing) {
+- gclog_or_tty->print_cr("Cleaned string and symbol table, "
+- "strings: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed, "
+- "symbols: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed",
+- g1_unlink_task.strings_processed(), g1_unlink_task.strings_removed(),
+- g1_unlink_task.symbols_processed(), g1_unlink_task.symbols_removed());
++}
++
++void G1CollectedHeap::unlink_string_and_symbol_table(BoolObjectClosure* is_alive,
++ bool process_strings, bool process_symbols) {
++ {
++ uint n_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
++ _g1h->workers()->active_workers() : 1);
++ G1StringSymbolTableUnlinkTask g1_unlink_task(is_alive, process_strings, process_symbols);
++ if (G1CollectedHeap::use_parallel_gc_threads()) {
++ set_par_threads(n_workers);
++ workers()->run_task(&g1_unlink_task);
++ set_par_threads(0);
++ } else {
++ g1_unlink_task.work(0);
++ }
+ }
+
+ if (G1StringDedup::is_enabled()) {
+@@ -5307,21 +5303,43 @@
+ }
+ }
+
+-class RedirtyLoggedCardTableEntryFastClosure : public CardTableEntryClosure {
+-public:
+- bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
+- *card_ptr = CardTableModRefBS::dirty_card_val();
+- return true;
++class G1RedirtyLoggedCardsTask : public AbstractGangTask {
++ private:
++ DirtyCardQueueSet* _queue;
++ public:
++ G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue) : AbstractGangTask("Redirty Cards"), _queue(queue) { }
++
++ virtual void work(uint worker_id) {
++ double start_time = os::elapsedTime();
++
++ RedirtyLoggedCardTableEntryClosure cl;
++ if (G1CollectedHeap::heap()->use_parallel_gc_threads()) {
++ _queue->par_apply_closure_to_all_completed_buffers(&cl);
++ } else {
++ _queue->apply_closure_to_all_completed_buffers(&cl);
++ }
++
++ G1GCPhaseTimes* timer = G1CollectedHeap::heap()->g1_policy()->phase_times();
++ timer->record_redirty_logged_cards_time_ms(worker_id, (os::elapsedTime() - start_time) * 1000.0);
++ timer->record_redirty_logged_cards_processed_cards(worker_id, cl.num_processed());
+ }
+ };
+
+ void G1CollectedHeap::redirty_logged_cards() {
+- guarantee(G1DeferredRSUpdate, "Must only be called when using deferred RS updates.");
+ double redirty_logged_cards_start = os::elapsedTime();
+
+- RedirtyLoggedCardTableEntryFastClosure redirty;
+- dirty_card_queue_set().set_closure(&redirty);
+- dirty_card_queue_set().apply_closure_to_all_completed_buffers();
++ uint n_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
++ _g1h->workers()->active_workers() : 1);
++
++ G1RedirtyLoggedCardsTask redirty_task(&dirty_card_queue_set());
++ dirty_card_queue_set().reset_for_par_iteration();
++ if (use_parallel_gc_threads()) {
++ set_par_threads(n_workers);
++ workers()->run_task(&redirty_task);
++ set_par_threads(0);
++ } else {
++ redirty_task.work(0);
++ }
+
+ DirtyCardQueueSet& dcq = JavaThread::dirty_card_queue_set();
+ dcq.merge_bufferlists(&dirty_card_queue_set());
+@@ -5360,12 +5378,22 @@
+ public:
+ G1KeepAliveClosure(G1CollectedHeap* g1) : _g1(g1) {}
+ void do_oop(narrowOop* p) { guarantee(false, "Not needed"); }
+- void do_oop( oop* p) {
++ void do_oop(oop* p) {
+ oop obj = *p;
+-
+- if (_g1->obj_in_cs(obj)) {
++ assert(obj != NULL, "the caller should have filtered out NULL values");
++
++ G1CollectedHeap::in_cset_state_t cset_state = _g1->in_cset_state(obj);
++ if (cset_state == G1CollectedHeap::InNeither) {
++ return;
++ }
++ if (cset_state == G1CollectedHeap::InCSet) {
+ assert( obj->is_forwarded(), "invariant" );
+ *p = obj->forwardee();
++ } else {
++ assert(!obj->is_forwarded(), "invariant" );
++ assert(cset_state == G1CollectedHeap::IsHumongous,
++ err_msg("Only allowed InCSet state is IsHumongous, but is %d", cset_state));
++ _g1->set_humongous_is_live(obj);
+ }
+ }
+ };
+@@ -5378,17 +5406,14 @@
+ class G1CopyingKeepAliveClosure: public OopClosure {
+ G1CollectedHeap* _g1h;
+ OopClosure* _copy_non_heap_obj_cl;
+- OopsInHeapRegionClosure* _copy_metadata_obj_cl;
+ G1ParScanThreadState* _par_scan_state;
+
+ public:
+ G1CopyingKeepAliveClosure(G1CollectedHeap* g1h,
+ OopClosure* non_heap_obj_cl,
+- OopsInHeapRegionClosure* metadata_obj_cl,
+ G1ParScanThreadState* pss):
+ _g1h(g1h),
+ _copy_non_heap_obj_cl(non_heap_obj_cl),
+- _copy_metadata_obj_cl(metadata_obj_cl),
+ _par_scan_state(pss)
+ {}
+
+@@ -5398,7 +5423,7 @@
+ template <class T> void do_oop_work(T* p) {
+ oop obj = oopDesc::load_decode_heap_oop(p);
+
+- if (_g1h->obj_in_cs(obj)) {
++ if (_g1h->is_in_cset_or_humongous(obj)) {
+ // If the referent object has been forwarded (either copied
+ // to a new location or to itself in the event of an
+ // evacuation failure) then we need to update the reference
+@@ -5421,12 +5446,12 @@
+ _par_scan_state->push_on_queue(p);
+ } else {
+ assert(!Metaspace::contains((const void*)p),
+- err_msg("Otherwise need to call _copy_metadata_obj_cl->do_oop(p) "
++ err_msg("Unexpectedly found a pointer from metadata: "
+ PTR_FORMAT, p));
+- _copy_non_heap_obj_cl->do_oop(p);
+- }
++ _copy_non_heap_obj_cl->do_oop(p);
+ }
+ }
++ }
+ };
+
+ // Serial drain queue closure. Called as the 'complete_gc'
+@@ -5516,22 +5541,18 @@
+ pss.set_evac_failure_closure(&evac_failure_cl);
+
+ G1ParScanExtRootClosure only_copy_non_heap_cl(_g1h, &pss, NULL);
+- G1ParScanMetadataClosure only_copy_metadata_cl(_g1h, &pss, NULL);
+
+ G1ParScanAndMarkExtRootClosure copy_mark_non_heap_cl(_g1h, &pss, NULL);
+- G1ParScanAndMarkMetadataClosure copy_mark_metadata_cl(_g1h, &pss, NULL);
+
+ OopClosure* copy_non_heap_cl = &only_copy_non_heap_cl;
+- OopsInHeapRegionClosure* copy_metadata_cl = &only_copy_metadata_cl;
+
+ if (_g1h->g1_policy()->during_initial_mark_pause()) {
+ // We also need to mark copied objects.
+ copy_non_heap_cl = &copy_mark_non_heap_cl;
+- copy_metadata_cl = &copy_mark_metadata_cl;
+ }
+
+ // Keep alive closure.
+- G1CopyingKeepAliveClosure keep_alive(_g1h, copy_non_heap_cl, copy_metadata_cl, &pss);
++ G1CopyingKeepAliveClosure keep_alive(_g1h, copy_non_heap_cl, &pss);
+
+ // Complete GC closure
+ G1ParEvacuateFollowersClosure drain_queue(_g1h, &pss, _task_queues, _terminator);
+@@ -5622,22 +5643,17 @@
+
+ pss.set_evac_failure_closure(&evac_failure_cl);
+
+- assert(pss.refs()->is_empty(), "both queue and overflow should be empty");
+-
++ assert(pss.queue_is_empty(), "both queue and overflow should be empty");
+
+ G1ParScanExtRootClosure only_copy_non_heap_cl(_g1h, &pss, NULL);
+- G1ParScanMetadataClosure only_copy_metadata_cl(_g1h, &pss, NULL);
+
+ G1ParScanAndMarkExtRootClosure copy_mark_non_heap_cl(_g1h, &pss, NULL);
+- G1ParScanAndMarkMetadataClosure copy_mark_metadata_cl(_g1h, &pss, NULL);
+
+ OopClosure* copy_non_heap_cl = &only_copy_non_heap_cl;
+- OopsInHeapRegionClosure* copy_metadata_cl = &only_copy_metadata_cl;
+
+ if (_g1h->g1_policy()->during_initial_mark_pause()) {
+ // We also need to mark copied objects.
+ copy_non_heap_cl = &copy_mark_non_heap_cl;
+- copy_metadata_cl = &copy_mark_metadata_cl;
+ }
+
+ // Is alive closure
+@@ -5645,7 +5661,7 @@
+
+ // Copying keep alive closure. Applied to referent objects that need
+ // to be copied.
+- G1CopyingKeepAliveClosure keep_alive(_g1h, copy_non_heap_cl, copy_metadata_cl, &pss);
++ G1CopyingKeepAliveClosure keep_alive(_g1h, copy_non_heap_cl, &pss);
+
+ ReferenceProcessor* rp = _g1h->ref_processor_cm();
+
+@@ -5681,7 +5697,7 @@
+ G1ParEvacuateFollowersClosure drain_queue(_g1h, &pss, _queues, &_terminator);
+ drain_queue.do_void();
+ // Allocation buffers were retired at the end of G1ParEvacuateFollowersClosure
+- assert(pss.refs()->is_empty(), "should be");
++ assert(pss.queue_is_empty(), "should be");
+ }
+ };
+
+@@ -5748,25 +5764,21 @@
+
+ pss.set_evac_failure_closure(&evac_failure_cl);
+
+- assert(pss.refs()->is_empty(), "pre-condition");
++ assert(pss.queue_is_empty(), "pre-condition");
+
+ G1ParScanExtRootClosure only_copy_non_heap_cl(this, &pss, NULL);
+- G1ParScanMetadataClosure only_copy_metadata_cl(this, &pss, NULL);
+
+ G1ParScanAndMarkExtRootClosure copy_mark_non_heap_cl(this, &pss, NULL);
+- G1ParScanAndMarkMetadataClosure copy_mark_metadata_cl(this, &pss, NULL);
+
+ OopClosure* copy_non_heap_cl = &only_copy_non_heap_cl;
+- OopsInHeapRegionClosure* copy_metadata_cl = &only_copy_metadata_cl;
+
+ if (_g1h->g1_policy()->during_initial_mark_pause()) {
+ // We also need to mark copied objects.
+ copy_non_heap_cl = &copy_mark_non_heap_cl;
+- copy_metadata_cl = &copy_mark_metadata_cl;
+ }
+
+ // Keep alive closure.
+- G1CopyingKeepAliveClosure keep_alive(this, copy_non_heap_cl, copy_metadata_cl, &pss);
++ G1CopyingKeepAliveClosure keep_alive(this, copy_non_heap_cl, &pss);
+
+ // Serial Complete GC closure
+ G1STWDrainQueueClosure drain_queue(this, &pss);
+@@ -5781,7 +5793,8 @@
+ &keep_alive,
+ &drain_queue,
+ NULL,
+- _gc_timer_stw);
++ _gc_timer_stw,
++ _gc_tracer_stw->gc_id());
+ } else {
+ // Parallel reference processing
+ assert(rp->num_q() == no_of_gc_workers, "sanity");
+@@ -5792,15 +5805,14 @@
+ &keep_alive,
+ &drain_queue,
+ &par_task_executor,
+- _gc_timer_stw);
++ _gc_timer_stw,
++ _gc_tracer_stw->gc_id());
+ }
+
+ _gc_tracer_stw->report_gc_reference_stats(stats);
+- // We have completed copying any necessary live referent objects
+- // (that were not copied during the actual pause) so we can
+- // retire any active alloc buffers
+- pss.retire_alloc_buffers();
+- assert(pss.refs()->is_empty(), "both queue and overflow should be empty");
++
++ // We have completed copying any necessary live referent objects.
++ assert(pss.queue_is_empty(), "both queue and overflow should be empty");
+
+ double ref_proc_time = os::elapsedTime() - ref_proc_start;
+ g1_policy()->phase_times()->record_ref_proc_time(ref_proc_time * 1000.0);
+@@ -5885,6 +5897,10 @@
+
+ {
+ StrongRootsScope srs(this);
++ // InitialMark needs claim bits to keep track of the marked-through CLDs.
++ if (g1_policy()->during_initial_mark_pause()) {
++ ClassLoaderDataGraph::clear_claimed_marks();
++ }
+
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ // The individual threads will set their evac-failure closures.
+@@ -5933,7 +5949,7 @@
+ }
+ }
+
+- release_gc_alloc_regions(n_workers, evacuation_info);
++ _allocator->release_gc_alloc_regions(n_workers, evacuation_info);
+ g1_rem_set()->cleanup_after_oops_into_collection_set_do();
+
+ // Reset and re-enable the hot card cache.
+@@ -5942,12 +5958,6 @@
+ hot_card_cache->reset_hot_cache();
+ hot_card_cache->set_use_cache(true);
+
+- // Migrate the strong code roots attached to each region in
+- // the collection set. Ideally we would like to do this
+- // after we have finished the scanning/evacuation of the
+- // strong code roots for a particular heap region.
+- migrate_strong_code_roots();
+-
+ purge_code_root_memory();
+
+ if (g1_policy()->during_initial_mark_pause()) {
+@@ -5975,9 +5985,7 @@
+ // RSets.
+ enqueue_discovered_references(n_workers);
+
+- if (G1DeferredRSUpdate) {
+- redirty_logged_cards();
+- }
++ redirty_logged_cards();
+ COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
+ }
+
+@@ -5985,10 +5993,16 @@
+ FreeRegionList* free_list,
+ bool par,
+ bool locked) {
+- assert(!hr->isHumongous(), "this is only for non-humongous regions");
++ assert(!hr->is_free(), "the region should not be free");
+ assert(!hr->is_empty(), "the region should not be empty");
++ assert(_hrm.is_available(hr->hrm_index()), "region should be committed");
+ assert(free_list != NULL, "pre-condition");
+
++ if (G1VerifyBitmaps) {
++ MemRegion mr(hr->bottom(), hr->end());
++ concurrent_mark()->clearRangePrevBitmap(mr);
++ }
++
+ // Clear the card counts for this region.
+ // Note: we only need to do this if the region is not young
+ // (since we don't refine cards in young regions).
+@@ -6009,14 +6023,14 @@
+ // We need to read this before we make the region non-humongous,
+ // otherwise the information will be gone.
+ uint last_index = hr->last_hc_index();
+- hr->set_notHumongous();
++ hr->clear_humongous();
+ free_region(hr, free_list, par);
+
+- uint i = hr->hrs_index() + 1;
++ uint i = hr->hrm_index() + 1;
+ while (i < last_index) {
+ HeapRegion* curr_hr = region_at(i);
+ assert(curr_hr->continuesHumongous(), "invariant");
+- curr_hr->set_notHumongous();
++ curr_hr->clear_humongous();
+ free_region(curr_hr, free_list, par);
+ i += 1;
+ }
+@@ -6036,15 +6050,12 @@
+ assert(list != NULL, "list can't be null");
+ if (!list->is_empty()) {
+ MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
+- _free_list.add_ordered(list);
++ _hrm.insert_list_into_free_list(list);
+ }
+ }
+
+ void G1CollectedHeap::decrement_summary_bytes(size_t bytes) {
+- assert(_summary_bytes_used >= bytes,
+- err_msg("invariant: _summary_bytes_used: "SIZE_FORMAT" should be >= bytes: "SIZE_FORMAT,
+- _summary_bytes_used, bytes));
+- _summary_bytes_used -= bytes;
++ _allocator->decrease_used(bytes);
+ }
+
+ class G1ParCleanupCTTask : public AbstractGangTask {
+@@ -6123,7 +6134,87 @@
+ void G1CollectedHeap::verify_dirty_young_regions() {
+ verify_dirty_young_list(_young_list->first_region());
+ }
+-#endif
++
++bool G1CollectedHeap::verify_no_bits_over_tams(const char* bitmap_name, CMBitMapRO* bitmap,
++ HeapWord* tams, HeapWord* end) {
++ guarantee(tams <= end,
++ err_msg("tams: "PTR_FORMAT" end: "PTR_FORMAT, tams, end));
++ HeapWord* result = bitmap->getNextMarkedWordAddress(tams, end);
++ if (result < end) {
++ gclog_or_tty->cr();
++ gclog_or_tty->print_cr("## wrong marked address on %s bitmap: "PTR_FORMAT,
++ bitmap_name, result);
++ gclog_or_tty->print_cr("## %s tams: "PTR_FORMAT" end: "PTR_FORMAT,
++ bitmap_name, tams, end);
++ return false;
++ }
++ return true;
++}
++
++bool G1CollectedHeap::verify_bitmaps(const char* caller, HeapRegion* hr) {
++ CMBitMapRO* prev_bitmap = concurrent_mark()->prevMarkBitMap();
++ CMBitMapRO* next_bitmap = (CMBitMapRO*) concurrent_mark()->nextMarkBitMap();
++
++ HeapWord* bottom = hr->bottom();
++ HeapWord* ptams = hr->prev_top_at_mark_start();
++ HeapWord* ntams = hr->next_top_at_mark_start();
++ HeapWord* end = hr->end();
++
++ bool res_p = verify_no_bits_over_tams("prev", prev_bitmap, ptams, end);
++
++ bool res_n = true;
++ // We reset mark_in_progress() before we reset _cmThread->in_progress() and in this window
++ // we do the clearing of the next bitmap concurrently. Thus, we can not verify the bitmap
++ // if we happen to be in that state.
++ if (mark_in_progress() || !_cmThread->in_progress()) {
++ res_n = verify_no_bits_over_tams("next", next_bitmap, ntams, end);
++ }
++ if (!res_p || !res_n) {
++ gclog_or_tty->print_cr("#### Bitmap verification failed for "HR_FORMAT,
++ HR_FORMAT_PARAMS(hr));
++ gclog_or_tty->print_cr("#### Caller: %s", caller);
++ return false;
++ }
++ return true;
++}
++
++void G1CollectedHeap::check_bitmaps(const char* caller, HeapRegion* hr) {
++ if (!G1VerifyBitmaps) return;
++
++ guarantee(verify_bitmaps(caller, hr), "bitmap verification");
++}
++
++class G1VerifyBitmapClosure : public HeapRegionClosure {
++private:
++ const char* _caller;
++ G1CollectedHeap* _g1h;
++ bool _failures;
++
++public:
++ G1VerifyBitmapClosure(const char* caller, G1CollectedHeap* g1h) :
++ _caller(caller), _g1h(g1h), _failures(false) { }
++
++ bool failures() { return _failures; }
++
++ virtual bool doHeapRegion(HeapRegion* hr) {
++ if (hr->continuesHumongous()) return false;
++
++ bool result = _g1h->verify_bitmaps(_caller, hr);
++ if (!result) {
++ _failures = true;
++ }
++ return false;
++ }
++};
++
++void G1CollectedHeap::check_bitmaps(const char* caller) {
++ if (!G1VerifyBitmaps) return;
++
++ G1VerifyBitmapClosure cl(caller, this);
++ heap_region_iterate(&cl);
++ guarantee(!cl.failures(), "bitmap verification");
++}
++#endif // PRODUCT
+
+ void G1CollectedHeap::cleanUpCardTable() {
+ G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
+@@ -6244,9 +6335,9 @@
+ if (cur->is_young()) {
+ cur->set_young_index_in_cset(-1);
+ }
+- cur->set_not_young();
+ cur->set_evacuation_failed(false);
+ // The region is now considered to be old.
++ cur->set_old();
+ _old_set.add(cur);
+ evacuation_info.increment_collectionset_used_after(cur->used());
+ }
+@@ -6272,6 +6363,154 @@
+ policy->phase_times()->record_non_young_free_cset_time_ms(non_young_time_ms);
+ }
+
++class G1FreeHumongousRegionClosure : public HeapRegionClosure {
++ private:
++ FreeRegionList* _free_region_list;
++ HeapRegionSet* _proxy_set;
++ HeapRegionSetCount _humongous_regions_removed;
++ size_t _freed_bytes;
++ public:
++
++ G1FreeHumongousRegionClosure(FreeRegionList* free_region_list) :
++ _free_region_list(free_region_list), _humongous_regions_removed(), _freed_bytes(0) {
++ }
++
++ virtual bool doHeapRegion(HeapRegion* r) {
++ if (!r->startsHumongous()) {
++ return false;
++ }
++
++ G1CollectedHeap* g1h = G1CollectedHeap::heap();
++
++ oop obj = (oop)r->bottom();
++ CMBitMap* next_bitmap = g1h->concurrent_mark()->nextMarkBitMap();
++
++ // The following checks whether the humongous object is live are sufficient.
++ // The main additional check (in addition to having a reference from the roots
++ // or the young gen) is whether the humongous object has a remembered set entry.
++ //
++ // A humongous object cannot be live if there is no remembered set for it
++ // because:
++ // - there can be no references from within humongous starts regions referencing
++ // the object because we never allocate other objects into them.
++ // (I.e. there are no intra-region references that may be missed by the
++ // remembered set)
++ // - as soon there is a remembered set entry to the humongous starts region
++ // (i.e. it has "escaped" to an old object) this remembered set entry will stay
++ // until the end of a concurrent mark.
++ //
++ // It is not required to check whether the object has been found dead by marking
++ // or not, in fact it would prevent reclamation within a concurrent cycle, as
++ // all objects allocated during that time are considered live.
++ // SATB marking is even more conservative than the remembered set.
++ // So if at this point in the collection there is no remembered set entry,
++ // nobody has a reference to it.
++ // At the start of collection we flush all refinement logs, and remembered sets
++ // are completely up-to-date wrt to references to the humongous object.
++ //
++ // Other implementation considerations:
++ // - never consider object arrays: while they are a valid target, they have not
++ // been observed to be used as temporary objects.
++ // - they would also pose considerable effort for cleaning up the the remembered
++ // sets.
++ // While this cleanup is not strictly necessary to be done (or done instantly),
++ // given that their occurrence is very low, this saves us this additional
++ // complexity.
++ uint region_idx = r->hrm_index();
++ if (g1h->humongous_is_live(region_idx) ||
++ g1h->humongous_region_is_always_live(region_idx)) {
++
++ if (G1TraceReclaimDeadHumongousObjectsAtYoungGC) {
++ gclog_or_tty->print_cr("Live humongous %d region %d with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d live-other %d obj array %d",
++ r->isHumongous(),
++ region_idx,
++ r->rem_set()->occupied(),
++ r->rem_set()->strong_code_roots_list_length(),
++ next_bitmap->isMarked(r->bottom()),
++ g1h->humongous_is_live(region_idx),
++ obj->is_objArray()
++ );
++ }
++
++ return false;
++ }
++
++ guarantee(!obj->is_objArray(),
++ err_msg("Eagerly reclaiming object arrays is not supported, but the object "PTR_FORMAT" is.",
++ r->bottom()));
++
++ if (G1TraceReclaimDeadHumongousObjectsAtYoungGC) {
++ gclog_or_tty->print_cr("Reclaim humongous region %d start "PTR_FORMAT" region %d length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d live-other %d obj array %d",
++ r->isHumongous(),
++ r->bottom(),
++ region_idx,
++ r->region_num(),
++ r->rem_set()->occupied(),
++ r->rem_set()->strong_code_roots_list_length(),
++ next_bitmap->isMarked(r->bottom()),
++ g1h->humongous_is_live(region_idx),
++ obj->is_objArray()
++ );
++ }
++ // Need to clear mark bit of the humongous object if already set.
++ if (next_bitmap->isMarked(r->bottom())) {
++ next_bitmap->clear(r->bottom());
++ }
++ _freed_bytes += r->used();
++ r->set_containing_set(NULL);
++ _humongous_regions_removed.increment(1u, r->capacity());
++ g1h->free_humongous_region(r, _free_region_list, false);
++
++ return false;
++ }
++
++ HeapRegionSetCount& humongous_free_count() {
++ return _humongous_regions_removed;
++ }
++
++ size_t bytes_freed() const {
++ return _freed_bytes;
++ }
++
++ size_t humongous_reclaimed() const {
++ return _humongous_regions_removed.length();
++ }
++};
++
++void G1CollectedHeap::eagerly_reclaim_humongous_regions() {
++ assert_at_safepoint(true);
++
++ if (!G1ReclaimDeadHumongousObjectsAtYoungGC || !_has_humongous_reclaim_candidates) {
++ g1_policy()->phase_times()->record_fast_reclaim_humongous_time_ms(0.0, 0);
++ return;
++ }
++
++ double start_time = os::elapsedTime();
++
++ FreeRegionList local_cleanup_list("Local Humongous Cleanup List");
++
++ G1FreeHumongousRegionClosure cl(&local_cleanup_list);
++ heap_region_iterate(&cl);
++
++ HeapRegionSetCount empty_set;
++ remove_from_old_sets(empty_set, cl.humongous_free_count());
++
++ G1HRPrinter* hr_printer = _g1h->hr_printer();
++ if (hr_printer->is_active()) {
++ FreeRegionListIterator iter(&local_cleanup_list);
++ while (iter.more_available()) {
++ HeapRegion* hr = iter.get_next();
++ hr_printer->cleanup(hr);
++ }
++ }
++
++ prepend_to_freelist(&local_cleanup_list);
++ decrement_summary_bytes(cl.bytes_freed());
++
++ g1_policy()->phase_times()->record_fast_reclaim_humongous_time_ms((os::elapsedTime() - start_time) * 1000.0,
++ cl.humongous_reclaimed());
++}
++
+ // This routine is similar to the above but does not record
+ // any policy statistics or update free lists; we are abandoning
+ // the current incremental collection set in preparation of a
+@@ -6385,16 +6624,15 @@
+ TearDownRegionSetsClosure(HeapRegionSet* old_set) : _old_set(old_set) { }
+
+ bool doHeapRegion(HeapRegion* r) {
+- if (r->is_empty()) {
+- // We ignore empty regions, we'll empty the free list afterwards
+- } else if (r->is_young()) {
+- // We ignore young regions, we'll empty the young list afterwards
+- } else if (r->isHumongous()) {
++ if (r->is_old()) {
++ _old_set->remove(r);
++ } else {
++ // We ignore free regions, we'll empty the free list afterwards.
++ // We ignore young regions, we'll empty the young list afterwards.
+ // We ignore humongous regions, we're not tearing down the
+- // humongous region set
+- } else {
+- // The rest should be old
+- _old_set->remove(r);
++ // humongous regions set.
++ assert(r->is_free() || r->is_young() || r->isHumongous(),
++ "it cannot be another type");
+ }
+ return false;
+ }
+@@ -6416,22 +6654,22 @@
+ // this is that during a full GC string deduplication needs to know if
+ // a collected region was young or old when the full GC was initiated.
+ }
+- _free_list.remove_all();
++ _hrm.remove_all_free_regions();
+ }
+
+ class RebuildRegionSetsClosure : public HeapRegionClosure {
+ private:
+ bool _free_list_only;
+ HeapRegionSet* _old_set;
+- FreeRegionList* _free_list;
++ HeapRegionManager* _hrm;
+ size_t _total_used;
+
+ public:
+ RebuildRegionSetsClosure(bool free_list_only,
+- HeapRegionSet* old_set, FreeRegionList* free_list) :
++ HeapRegionSet* old_set, HeapRegionManager* hrm) :
+ _free_list_only(free_list_only),
+- _old_set(old_set), _free_list(free_list), _total_used(0) {
+- assert(_free_list->is_empty(), "pre-condition");
++ _old_set(old_set), _hrm(hrm), _total_used(0) {
++ assert(_hrm->num_free_regions() == 0, "pre-condition");
+ if (!free_list_only) {
+ assert(_old_set->is_empty(), "pre-condition");
+ }
+@@ -6444,14 +6682,20 @@
+
+ if (r->is_empty()) {
+ // Add free regions to the free list
+- _free_list->add_as_tail(r);
++ r->set_free();
++ r->set_allocation_context(AllocationContext::system());
++ _hrm->insert_into_free_list(r);
+ } else if (!_free_list_only) {
+ assert(!r->is_young(), "we should not come across young regions");
+
+ if (r->isHumongous()) {
+ // We ignore humongous regions, we left the humongous set unchanged
+ } else {
+- // The rest should be old, add them to the old set
++ // Objects that were compacted would have ended up on regions
++ // that were previously old or free.
++ assert(r->is_free() || r->is_old(), "invariant");
++ // We now consider them old, so register as such.
++ r->set_old();
+ _old_set->add(r);
+ }
+ _total_used += r->used();
+@@ -6472,16 +6716,16 @@
+ _young_list->empty_list();
+ }
+
+- RebuildRegionSetsClosure cl(free_list_only, &_old_set, &_free_list);
++ RebuildRegionSetsClosure cl(free_list_only, &_old_set, &_hrm);
+ heap_region_iterate(&cl);
+
+ if (!free_list_only) {
+- _summary_bytes_used = cl.total_used();
+- }
+- assert(_summary_bytes_used == recalculate_used(),
+- err_msg("inconsistent _summary_bytes_used, "
++ _allocator->set_used(cl.total_used());
++ }
++ assert(_allocator->used_unlocked() == recalculate_used(),
++ err_msg("inconsistent _allocator->used_unlocked(), "
+ "value: "SIZE_FORMAT" recalculated: "SIZE_FORMAT,
+- _summary_bytes_used, recalculate_used()));
++ _allocator->used_unlocked(), recalculate_used()));
+ }
+
+ void G1CollectedHeap::set_refine_cte_cl_concurrency(bool concurrent) {
+@@ -6490,11 +6734,7 @@
+
+ bool G1CollectedHeap::is_in_closed_subset(const void* p) const {
+ HeapRegion* hr = heap_region_containing(p);
+- if (hr == NULL) {
+- return false;
+- } else {
+- return hr->is_in(p);
+- }
++ return hr->is_in(p);
+ }
+
+ // Methods for the mutator alloc region
+@@ -6512,6 +6752,7 @@
+ if (new_alloc_region != NULL) {
+ set_region_short_lived_locked(new_alloc_region);
+ _hr_printer.alloc(new_alloc_region, G1HRPrinter::Eden, young_list_full);
++ check_bitmaps("Mutator Region Allocation", new_alloc_region);
+ return new_alloc_region;
+ }
+ }
+@@ -6521,10 +6762,10 @@
+ void G1CollectedHeap::retire_mutator_alloc_region(HeapRegion* alloc_region,
+ size_t allocated_bytes) {
+ assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
+- assert(alloc_region->is_young(), "all mutator alloc regions should be young");
++ assert(alloc_region->is_eden(), "all mutator alloc regions should be eden");
+
+ g1_policy()->add_region_to_incremental_cset_lhs(alloc_region);
+- _summary_bytes_used += allocated_bytes;
++ _allocator->increase_used(allocated_bytes);
+ _hr_printer.retire(alloc_region);
+ // We update the eden sizes here, when the region is retired,
+ // instead of when it's allocated, since this is the point that its
+@@ -6532,11 +6773,6 @@
+ g1mm()->update_eden_size();
+ }
+
+-HeapRegion* MutatorAllocRegion::allocate_new_region(size_t word_size,
+- bool force) {
+- return _g1h->new_mutator_alloc_region(word_size, force);
+-}
+-
+ void G1CollectedHeap::set_par_threads() {
+ // Don't change the number of workers. Use the value previously set
+ // in the workgroup.
+@@ -6553,11 +6789,6 @@
+ set_par_threads(n_workers);
+ }
+
+-void MutatorAllocRegion::retire_region(HeapRegion* alloc_region,
+- size_t allocated_bytes) {
+- _g1h->retire_mutator_alloc_region(alloc_region, allocated_bytes);
+-}
+-
+ // Methods for the GC alloc regions
+
+ HeapRegion* G1CollectedHeap::new_gc_alloc_region(size_t word_size,
+@@ -6574,12 +6805,15 @@
+ // We really only need to do this for old regions given that we
+ // should never scan survivors. But it doesn't hurt to do it
+ // for survivors too.
+- new_alloc_region->set_saved_mark();
++ new_alloc_region->record_top_and_timestamp();
+ if (survivor) {
+ new_alloc_region->set_survivor();
+ _hr_printer.alloc(new_alloc_region, G1HRPrinter::Survivor);
++ check_bitmaps("Survivor Region Allocation", new_alloc_region);
+ } else {
++ new_alloc_region->set_old();
+ _hr_printer.alloc(new_alloc_region, G1HRPrinter::Old);
++ check_bitmaps("Old Region Allocation", new_alloc_region);
+ }
+ bool during_im = g1_policy()->during_initial_mark_pause();
+ new_alloc_region->note_start_of_copying(during_im);
+@@ -6605,65 +6839,13 @@
+ _hr_printer.retire(alloc_region);
+ }
+
+-HeapRegion* SurvivorGCAllocRegion::allocate_new_region(size_t word_size,
+- bool force) {
+- assert(!force, "not supported for GC alloc regions");
+- return _g1h->new_gc_alloc_region(word_size, count(), GCAllocForSurvived);
+-}
+-
+-void SurvivorGCAllocRegion::retire_region(HeapRegion* alloc_region,
+- size_t allocated_bytes) {
+- _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes,
+- GCAllocForSurvived);
+-}
+-
+-HeapRegion* OldGCAllocRegion::allocate_new_region(size_t word_size,
+- bool force) {
+- assert(!force, "not supported for GC alloc regions");
+- return _g1h->new_gc_alloc_region(word_size, count(), GCAllocForTenured);
+-}
+-
+-void OldGCAllocRegion::retire_region(HeapRegion* alloc_region,
+- size_t allocated_bytes) {
+- _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes,
+- GCAllocForTenured);
+-}
+-
+-HeapRegion* OldGCAllocRegion::release() {
+- HeapRegion* cur = get();
+- if (cur != NULL) {
+- // Determine how far we are from the next card boundary. If it is smaller than
+- // the minimum object size we can allocate into, expand into the next card.
+- HeapWord* top = cur->top();
+- HeapWord* aligned_top = (HeapWord*)align_ptr_up(top, G1BlockOffsetSharedArray::N_bytes);
+-
+- size_t to_allocate_words = pointer_delta(aligned_top, top, HeapWordSize);
+-
+- if (to_allocate_words != 0) {
+- // We are not at a card boundary. Fill up, possibly into the next, taking the
+- // end of the region and the minimum object size into account.
+- to_allocate_words = MIN2(pointer_delta(cur->end(), cur->top(), HeapWordSize),
+- MAX2(to_allocate_words, G1CollectedHeap::min_fill_size()));
+-
+- // Skip allocation if there is not enough space to allocate even the smallest
+- // possible object. In this case this region will not be retained, so the
+- // original problem cannot occur.
+- if (to_allocate_words >= G1CollectedHeap::min_fill_size()) {
+- HeapWord* dummy = attempt_allocation(to_allocate_words, true /* bot_updates */);
+- CollectedHeap::fill_with_object(dummy, to_allocate_words);
+- }
+- }
+- }
+- return G1AllocRegion::release();
+-}
+-
+ // Heap region set verification
+
+ class VerifyRegionListsClosure : public HeapRegionClosure {
+ private:
+ HeapRegionSet* _old_set;
+ HeapRegionSet* _humongous_set;
+- FreeRegionList* _free_list;
++ HeapRegionManager* _hrm;
+
+ public:
+ HeapRegionSetCount _old_count;
+@@ -6672,8 +6854,8 @@
+
+ VerifyRegionListsClosure(HeapRegionSet* old_set,
+ HeapRegionSet* humongous_set,
+- FreeRegionList* free_list) :
+- _old_set(old_set), _humongous_set(humongous_set), _free_list(free_list),
++ HeapRegionManager* hrm) :
++ _old_set(old_set), _humongous_set(humongous_set), _hrm(hrm),
+ _old_count(), _humongous_count(), _free_count(){ }
+
+ bool doHeapRegion(HeapRegion* hr) {
+@@ -6684,19 +6866,21 @@
+ if (hr->is_young()) {
+ // TODO
+ } else if (hr->startsHumongous()) {
+- assert(hr->containing_set() == _humongous_set, err_msg("Heap region %u is starts humongous but not in humongous set.", hr->region_num()));
++ assert(hr->containing_set() == _humongous_set, err_msg("Heap region %u is starts humongous but not in humongous set.", hr->hrm_index()));
+ _humongous_count.increment(1u, hr->capacity());
+ } else if (hr->is_empty()) {
+- assert(hr->containing_set() == _free_list, err_msg("Heap region %u is empty but not on the free list.", hr->region_num()));
++ assert(_hrm->is_free(hr), err_msg("Heap region %u is empty but not on the free list.", hr->hrm_index()));
+ _free_count.increment(1u, hr->capacity());
++ } else if (hr->is_old()) {
++ assert(hr->containing_set() == _old_set, err_msg("Heap region %u is old but not in the old set.", hr->hrm_index()));
++ _old_count.increment(1u, hr->capacity());
+ } else {
+- assert(hr->containing_set() == _old_set, err_msg("Heap region %u is old but not in the old set.", hr->region_num()));
+- _old_count.increment(1u, hr->capacity());
++ ShouldNotReachHere();
+ }
+ return false;
+ }
+
+- void verify_counts(HeapRegionSet* old_set, HeapRegionSet* humongous_set, FreeRegionList* free_list) {
++ void verify_counts(HeapRegionSet* old_set, HeapRegionSet* humongous_set, HeapRegionManager* free_list) {
+ guarantee(old_set->length() == _old_count.length(), err_msg("Old set count mismatch. Expected %u, actual %u.", old_set->length(), _old_count.length()));
+ guarantee(old_set->total_capacity_bytes() == _old_count.capacity(), err_msg("Old set capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
+ old_set->total_capacity_bytes(), _old_count.capacity()));
+@@ -6705,26 +6889,17 @@
+ guarantee(humongous_set->total_capacity_bytes() == _humongous_count.capacity(), err_msg("Hum set capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
+ humongous_set->total_capacity_bytes(), _humongous_count.capacity()));
+
+- guarantee(free_list->length() == _free_count.length(), err_msg("Free list count mismatch. Expected %u, actual %u.", free_list->length(), _free_count.length()));
++ guarantee(free_list->num_free_regions() == _free_count.length(), err_msg("Free list count mismatch. Expected %u, actual %u.", free_list->num_free_regions(), _free_count.length()));
+ guarantee(free_list->total_capacity_bytes() == _free_count.capacity(), err_msg("Free list capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
+ free_list->total_capacity_bytes(), _free_count.capacity()));
+ }
+ };
+
+-HeapRegion* G1CollectedHeap::new_heap_region(uint hrs_index,
+- HeapWord* bottom) {
+- HeapWord* end = bottom + HeapRegion::GrainWords;
+- MemRegion mr(bottom, end);
+- assert(_g1_reserved.contains(mr), "invariant");
+- // This might return NULL if the allocation fails
+- return new HeapRegion(hrs_index, _bot_shared, mr);
+-}
+-
+ void G1CollectedHeap::verify_region_sets() {
+ assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
+
+ // First, check the explicit lists.
+- _free_list.verify_list();
++ _hrm.verify();
+ {
+ // Given that a concurrent operation might be adding regions to
+ // the secondary free list we have to take the lock before
+@@ -6755,9 +6930,9 @@
+ // Finally, make sure that the region accounting in the lists is
+ // consistent with what we see in the heap.
+
+- VerifyRegionListsClosure cl(&_old_set, &_humongous_set, &_free_list);
++ VerifyRegionListsClosure cl(&_old_set, &_humongous_set, &_hrm);
+ heap_region_iterate(&cl);
+- cl.verify_counts(&_old_set, &_humongous_set, &_free_list);
++ cl.verify_counts(&_old_set, &_humongous_set, &_hrm);
+ }
+
+ // Optimized nmethod scanning
+@@ -6776,13 +6951,8 @@
+ " starting at "HR_FORMAT,
+ _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
+
+- // HeapRegion::add_strong_code_root() avoids adding duplicate
+- // entries but having duplicates is OK since we "mark" nmethods
+- // as visited when we scan the strong code root lists during the GC.
+- hr->add_strong_code_root(_nm);
+- assert(hr->rem_set()->strong_code_roots_list_contains(_nm),
+- err_msg("failed to add code root "PTR_FORMAT" to remembered set of region "HR_FORMAT,
+- _nm, HR_FORMAT_PARAMS(hr)));
++ // HeapRegion::add_strong_code_root_locked() avoids adding duplicate entries.
++ hr->add_strong_code_root_locked(_nm);
+ }
+ }
+
+@@ -6809,9 +6979,6 @@
+ _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
+
+ hr->remove_strong_code_root(_nm);
+- assert(!hr->rem_set()->strong_code_roots_list_contains(_nm),
+- err_msg("failed to remove code root "PTR_FORMAT" of region "HR_FORMAT,
+- _nm, HR_FORMAT_PARAMS(hr)));
+ }
+ }
+
+@@ -6839,132 +7006,13 @@
+ nm->oops_do(&reg_cl, true);
+ }
+
+-class MigrateCodeRootsHeapRegionClosure: public HeapRegionClosure {
+-public:
+- bool doHeapRegion(HeapRegion *hr) {
+- assert(!hr->isHumongous(),
+- err_msg("humongous region "HR_FORMAT" should not have been added to collection set",
+- HR_FORMAT_PARAMS(hr)));
+- hr->migrate_strong_code_roots();
+- return false;
+- }
+-};
+-
+-void G1CollectedHeap::migrate_strong_code_roots() {
+- MigrateCodeRootsHeapRegionClosure cl;
+- double migrate_start = os::elapsedTime();
+- collection_set_iterate(&cl);
+- double migration_time_ms = (os::elapsedTime() - migrate_start) * 1000.0;
+- g1_policy()->phase_times()->record_strong_code_root_migration_time(migration_time_ms);
+-}
+-
+ void G1CollectedHeap::purge_code_root_memory() {
+ double purge_start = os::elapsedTime();
+- G1CodeRootSet::purge_chunks(G1CodeRootsChunkCacheKeepPercent);
++ G1CodeRootSet::purge();
+ double purge_time_ms = (os::elapsedTime() - purge_start) * 1000.0;
+ g1_policy()->phase_times()->record_strong_code_root_purge_time(purge_time_ms);
+ }
+
+-// Mark all the code roots that point into regions *not* in the
+-// collection set.
+-//
+-// Note we do not want to use a "marking" CodeBlobToOopClosure while
+-// walking the the code roots lists of regions not in the collection
+-// set. Suppose we have an nmethod (M) that points to objects in two
+-// separate regions - one in the collection set (R1) and one not (R2).
+-// Using a "marking" CodeBlobToOopClosure here would result in "marking"
+-// nmethod M when walking the code roots for R1. When we come to scan
+-// the code roots for R2, we would see that M is already marked and it
+-// would be skipped and the objects in R2 that are referenced from M
+-// would not be evacuated.
+-
+-class MarkStrongCodeRootCodeBlobClosure: public CodeBlobClosure {
+-
+- class MarkStrongCodeRootOopClosure: public OopClosure {
+- ConcurrentMark* _cm;
+- HeapRegion* _hr;
+- uint _worker_id;
+-
+- template <class T> void do_oop_work(T* p) {
+- T heap_oop = oopDesc::load_heap_oop(p);
+- if (!oopDesc::is_null(heap_oop)) {
+- oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+- // Only mark objects in the region (which is assumed
+- // to be not in the collection set).
+- if (_hr->is_in(obj)) {
+- _cm->grayRoot(obj, (size_t) obj->size(), _worker_id);
+- }
+- }
+- }
+-
+- public:
+- MarkStrongCodeRootOopClosure(ConcurrentMark* cm, HeapRegion* hr, uint worker_id) :
+- _cm(cm), _hr(hr), _worker_id(worker_id) {
+- assert(!_hr->in_collection_set(), "sanity");
+- }
+-
+- void do_oop(narrowOop* p) { do_oop_work(p); }
+- void do_oop(oop* p) { do_oop_work(p); }
+- };
+-
+- MarkStrongCodeRootOopClosure _oop_cl;
+-
+-public:
+- MarkStrongCodeRootCodeBlobClosure(ConcurrentMark* cm, HeapRegion* hr, uint worker_id):
+- _oop_cl(cm, hr, worker_id) {}
+-
+- void do_code_blob(CodeBlob* cb) {
+- nmethod* nm = (cb == NULL) ? NULL : cb->as_nmethod_or_null();
+- if (nm != NULL) {
+- nm->oops_do(&_oop_cl);
+- }
+- }
+-};
+-
+-class MarkStrongCodeRootsHRClosure: public HeapRegionClosure {
+- G1CollectedHeap* _g1h;
+- uint _worker_id;
+-
+-public:
+- MarkStrongCodeRootsHRClosure(G1CollectedHeap* g1h, uint worker_id) :
+- _g1h(g1h), _worker_id(worker_id) {}
+-
+- bool doHeapRegion(HeapRegion *hr) {
+- HeapRegionRemSet* hrrs = hr->rem_set();
+- if (hr->continuesHumongous()) {
+- // Code roots should never be attached to a continuation of a humongous region
+- assert(hrrs->strong_code_roots_list_length() == 0,
+- err_msg("code roots should never be attached to continuations of humongous region "HR_FORMAT
+- " starting at "HR_FORMAT", but has "SIZE_FORMAT,
+- HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()),
+- hrrs->strong_code_roots_list_length()));
+- return false;
+- }
+-
+- if (hr->in_collection_set()) {
+- // Don't mark code roots into regions in the collection set here.
+- // They will be marked when we scan them.
+- return false;
+- }
+-
+- MarkStrongCodeRootCodeBlobClosure cb_cl(_g1h->concurrent_mark(), hr, _worker_id);
+- hr->strong_code_roots_do(&cb_cl);
+- return false;
+- }
+-};
+-
+-void G1CollectedHeap::mark_strong_code_roots(uint worker_id) {
+- MarkStrongCodeRootsHRClosure cl(this, worker_id);
+- if (G1CollectedHeap::use_parallel_gc_threads()) {
+- heap_region_par_iterate_chunked(&cl,
+- worker_id,
+- workers()->active_workers(),
+- HeapRegion::ParMarkRootClaimValue);
+- } else {
+- heap_region_iterate(&cl);
+- }
+-}
+-
+ class RebuildStrongCodeRootClosure: public CodeBlobClosure {
+ G1CollectedHeap* _g1h;
+
+@@ -6978,7 +7026,7 @@
+ return;
+ }
+
+- if (ScavengeRootsInCode && nm->detect_scavenge_root_oops()) {
++ if (ScavengeRootsInCode) {
+ _g1h->register_nmethod(nm);
+ }
+ }
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,4 +1,4 @@
+-/*
++ /*
+ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+@@ -25,15 +25,17 @@
+ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP
+
++#include "gc_implementation/g1/g1AllocationContext.hpp"
++#include "gc_implementation/g1/g1Allocator.hpp"
+ #include "gc_implementation/g1/concurrentMark.hpp"
+ #include "gc_implementation/g1/evacuationInfo.hpp"
+ #include "gc_implementation/g1/g1AllocRegion.hpp"
++#include "gc_implementation/g1/g1BiasedArray.hpp"
+ #include "gc_implementation/g1/g1HRPrinter.hpp"
+ #include "gc_implementation/g1/g1MonitoringSupport.hpp"
+-#include "gc_implementation/g1/g1RemSet.hpp"
+ #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
+ #include "gc_implementation/g1/g1YCTypes.hpp"
+-#include "gc_implementation/g1/heapRegionSeq.hpp"
++#include "gc_implementation/g1/heapRegionManager.hpp"
+ #include "gc_implementation/g1/heapRegionSet.hpp"
+ #include "gc_implementation/shared/hSpaceCounters.hpp"
+ #include "gc_implementation/shared/parGCAllocBuffer.hpp"
+@@ -80,12 +82,6 @@
+ typedef int RegionIdx_t; // needs to hold [ 0..max_regions() )
+ typedef int CardIdx_t; // needs to hold [ 0..CardsPerRegion )
+
+-enum GCAllocPurpose {
+- GCAllocForTenured,
+- GCAllocForSurvived,
+- GCAllocPurposeCount
+-};
+-
+ class YoungList : public CHeapObj<mtGC> {
+ private:
+ G1CollectedHeap* _g1h;
+@@ -158,40 +154,6 @@
+ void print();
+ };
+
+-class MutatorAllocRegion : public G1AllocRegion {
+-protected:
+- virtual HeapRegion* allocate_new_region(size_t word_size, bool force);
+- virtual void retire_region(HeapRegion* alloc_region, size_t allocated_bytes);
+-public:
+- MutatorAllocRegion()
+- : G1AllocRegion("Mutator Alloc Region", false /* bot_updates */) { }
+-};
+-
+-class SurvivorGCAllocRegion : public G1AllocRegion {
+-protected:
+- virtual HeapRegion* allocate_new_region(size_t word_size, bool force);
+- virtual void retire_region(HeapRegion* alloc_region, size_t allocated_bytes);
+-public:
+- SurvivorGCAllocRegion()
+- : G1AllocRegion("Survivor GC Alloc Region", false /* bot_updates */) { }
+-};
+-
+-class OldGCAllocRegion : public G1AllocRegion {
+-protected:
+- virtual HeapRegion* allocate_new_region(size_t word_size, bool force);
+- virtual void retire_region(HeapRegion* alloc_region, size_t allocated_bytes);
+-public:
+- OldGCAllocRegion()
+- : G1AllocRegion("Old GC Alloc Region", true /* bot_updates */) { }
+-
+- // This specialization of release() makes sure that the last card that has been
+- // allocated into has been completely filled by a dummy object.
+- // This avoids races when remembered set scanning wants to update the BOT of the
+- // last card in the retained old gc alloc region, and allocation threads
+- // allocating into that card at the same time.
+- virtual HeapRegion* release();
+-};
+-
+ // The G1 STW is alive closure.
+ // An instance is embedded into the G1CH and used as the
+ // (optional) _is_alive_non_header closure in the STW
+@@ -206,7 +168,15 @@
+
+ class RefineCardTableEntryClosure;
+
++class G1RegionMappingChangedListener : public G1MappingChangedListener {
++ private:
++ void reset_from_card_cache(uint start_idx, size_t num_regions);
++ public:
++ virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled);
++};
++
+ class G1CollectedHeap : public SharedHeap {
++ friend class VM_CollectForMetadataAllocation;
+ friend class VM_G1CollectForAllocation;
+ friend class VM_G1CollectFull;
+ friend class VM_G1IncCollectionPause;
+@@ -214,9 +184,12 @@
+ friend class MutatorAllocRegion;
+ friend class SurvivorGCAllocRegion;
+ friend class OldGCAllocRegion;
++ friend class G1Allocator;
++ friend class G1DefaultAllocator;
++ friend class G1ResManAllocator;
+
+ // Closures used in implementation.
+- template <G1Barrier barrier, bool do_mark_object>
++ template <G1Barrier barrier, G1Mark do_mark_object>
+ friend class G1ParCopyClosure;
+ friend class G1IsAliveClosure;
+ friend class G1EvacuateFollowersClosure;
+@@ -224,6 +197,8 @@
+ friend class G1ParScanClosureSuper;
+ friend class G1ParEvacuateFollowersClosure;
+ friend class G1ParTask;
++ friend class G1ParGCAllocator;
++ friend class G1DefaultParGCAllocator;
+ friend class G1FreeGarbageRegionClosure;
+ friend class RefineCardTableEntryClosure;
+ friend class G1PrepareCompactClosure;
+@@ -233,6 +208,7 @@
+ friend class EvacPopObjClosure;
+ friend class G1ParCleanupCTTask;
+
++ friend class G1FreeHumongousRegionClosure;
+ // Other related classes.
+ friend class G1MarkSweep;
+
+@@ -242,19 +218,9 @@
+
+ static size_t _humongous_object_threshold_in_words;
+
+- // Storage for the G1 heap.
+- VirtualSpace _g1_storage;
+- MemRegion _g1_reserved;
+-
+- // The part of _g1_storage that is currently committed.
+- MemRegion _g1_committed;
+-
+- // The master free list. It will satisfy all new region allocations.
+- FreeRegionList _free_list;
+-
+ // The secondary free list which contains regions that have been
+- // freed up during the cleanup process. This will be appended to the
+- // master free list when appropriate.
++ // freed up during the cleanup process. This will be appended to
++ // the master free list when appropriate.
+ FreeRegionList _secondary_free_list;
+
+ // It keeps track of the old regions.
+@@ -263,6 +229,9 @@
+ // It keeps track of the humongous regions.
+ HeapRegionSet _humongous_set;
+
++ void clear_humongous_is_live_table();
++ void eagerly_reclaim_humongous_regions();
++
+ // The number of regions we could create by expansion.
+ uint _expansion_regions;
+
+@@ -285,47 +254,24 @@
+ // after heap shrinking (free_list_only == true).
+ void rebuild_region_sets(bool free_list_only);
+
++ // Callback for region mapping changed events.
++ G1RegionMappingChangedListener _listener;
++
+ // The sequence of all heap regions in the heap.
+- HeapRegionSeq _hrs;
++ HeapRegionManager _hrm;
+
+- // Alloc region used to satisfy mutator allocation requests.
+- MutatorAllocRegion _mutator_alloc_region;
++ // Class that handles the different kinds of allocations.
++ G1Allocator* _allocator;
+
+- // Alloc region used to satisfy allocation requests by the GC for
+- // survivor objects.
+- SurvivorGCAllocRegion _survivor_gc_alloc_region;
++ // Statistics for each allocation context
++ AllocationContextStats _allocation_context_stats;
+
+ // PLAB sizing policy for survivors.
+ PLABStats _survivor_plab_stats;
+
+- // Alloc region used to satisfy allocation requests by the GC for
+- // old objects.
+- OldGCAllocRegion _old_gc_alloc_region;
+-
+ // PLAB sizing policy for tenured objects.
+ PLABStats _old_plab_stats;
+
+- PLABStats* stats_for_purpose(GCAllocPurpose purpose) {
+- PLABStats* stats = NULL;
+-
+- switch (purpose) {
+- case GCAllocForSurvived:
+- stats = &_survivor_plab_stats;
+- break;
+- case GCAllocForTenured:
+- stats = &_old_plab_stats;
+- break;
+- default:
+- assert(false, "unrecognized GCAllocPurpose");
+- }
+-
+- return stats;
+- }
+-
+- // The last old region we allocated to during the last GC.
+- // Typically, it is not full so we should re-use it during the next GC.
+- HeapRegion* _retained_old_gc_alloc_region;
+-
+ // It specifies whether we should attempt to expand the heap after a
+ // region allocation failure. If heap expansion fails we set this to
+ // false so that we don't re-attempt the heap expansion (it's likely
+@@ -353,33 +299,25 @@
+ // Helper for monitoring and management support.
+ G1MonitoringSupport* _g1mm;
+
+- // Determines PLAB size for a particular allocation purpose.
+- size_t desired_plab_sz(GCAllocPurpose purpose);
++ // Records whether the region at the given index is kept live by roots or
++ // references from the young generation.
++ class HumongousIsLiveBiasedMappedArray : public G1BiasedMappedArray<bool> {
++ protected:
++ bool default_value() const { return false; }
++ public:
++ void clear() { G1BiasedMappedArray<bool>::clear(); }
++ void set_live(uint region) {
++ set_by_index(region, true);
++ }
++ bool is_live(uint region) {
++ return get_by_index(region);
++ }
++ };
+
+- // Outside of GC pauses, the number of bytes used in all regions other
+- // than the current allocation region.
+- size_t _summary_bytes_used;
+-
+- // This is used for a quick test on whether a reference points into
+- // the collection set or not. Basically, we have an array, with one
+- // byte per region, and that byte denotes whether the corresponding
+- // region is in the collection set or not. The entry corresponding
+- // the bottom of the heap, i.e., region 0, is pointed to by
+- // _in_cset_fast_test_base. The _in_cset_fast_test field has been
+- // biased so that it actually points to address 0 of the address
+- // space, to make the test as fast as possible (we can simply shift
+- // the address to address into it, instead of having to subtract the
+- // bottom of the heap from the address before shifting it; basically
+- // it works in the same way the card table works).
+- bool* _in_cset_fast_test;
+-
+- // The allocated array used for the fast test on whether a reference
+- // points into the collection set or not. This field is also used to
+- // free the array.
+- bool* _in_cset_fast_test_base;
+-
+- // The length of the _in_cset_fast_test_base array.
+- uint _in_cset_fast_test_length;
++ HumongousIsLiveBiasedMappedArray _humongous_is_live;
++ // Stores whether during humongous object registration we found candidate regions.
++ // If not, we can skip a few steps.
++ bool _has_humongous_reclaim_candidates;
+
+ volatile unsigned _gc_time_stamp;
+
+@@ -422,7 +360,7 @@
+
+ // If the HR printer is active, dump the state of the regions in the
+ // heap after a compaction.
+- void print_hrs_post_compaction();
++ void print_hrm_post_compaction();
+
+ double verify(bool guard, const char* msg);
+ void verify_before_gc();
+@@ -513,24 +451,17 @@
+ // humongous object, set is_old to true. If not, to false.
+ HeapRegion* new_region(size_t word_size, bool is_old, bool do_expand);
+
+- // Attempt to satisfy a humongous allocation request of the given
+- // size by finding a contiguous set of free regions of num_regions
+- // length and remove them from the master free list. Return the
+- // index of the first region or G1_NULL_HRS_INDEX if the search
+- // was unsuccessful.
+- uint humongous_obj_allocate_find_first(uint num_regions,
+- size_t word_size);
+-
+ // Initialize a contiguous set of free regions of length num_regions
+ // and starting at index first so that they appear as a single
+ // humongous region.
+ HeapWord* humongous_obj_allocate_initialize_regions(uint first,
+ uint num_regions,
+- size_t word_size);
++ size_t word_size,
++ AllocationContext_t context);
+
+ // Attempt to allocate a humongous object of the given size. Return
+ // NULL if unsuccessful.
+- HeapWord* humongous_obj_allocate(size_t word_size);
++ HeapWord* humongous_obj_allocate(size_t word_size, AllocationContext_t context);
+
+ // The following two methods, allocate_new_tlab() and
+ // mem_allocate(), are the two main entry points from the runtime
+@@ -586,6 +517,7 @@
+ // retry the allocation attempt, potentially scheduling a GC
+ // pause. This should only be used for non-humongous allocations.
+ HeapWord* attempt_allocation_slow(size_t word_size,
++ AllocationContext_t context,
+ unsigned int* gc_count_before_ret,
+ int* gclocker_retry_count_ret);
+
+@@ -600,7 +532,8 @@
+ // specifies whether the mutator alloc region is expected to be NULL
+ // or not.
+ HeapWord* attempt_allocation_at_safepoint(size_t word_size,
+- bool expect_null_mutator_alloc_region);
++ AllocationContext_t context,
++ bool expect_null_mutator_alloc_region);
+
+ // It dirties the cards that cover the block so that so that the post
+ // write barrier never queues anything when updating objects on this
+@@ -612,7 +545,9 @@
+ // allocation region, either by picking one or expanding the
+ // heap, and then allocate a block of the given size. The block
+ // may not be a humongous - it must fit into a single heap region.
+- HeapWord* par_allocate_during_gc(GCAllocPurpose purpose, size_t word_size);
++ HeapWord* par_allocate_during_gc(GCAllocPurpose purpose,
++ size_t word_size,
++ AllocationContext_t context);
+
+ HeapWord* allocate_during_gc_slow(GCAllocPurpose purpose,
+ HeapRegion* alloc_region,
+@@ -624,10 +559,12 @@
+ void par_allocate_remaining_space(HeapRegion* r);
+
+ // Allocation attempt during GC for a survivor object / PLAB.
+- inline HeapWord* survivor_attempt_allocation(size_t word_size);
++ inline HeapWord* survivor_attempt_allocation(size_t word_size,
++ AllocationContext_t context);
+
+ // Allocation attempt during GC for an old object / PLAB.
+- inline HeapWord* old_attempt_allocation(size_t word_size);
++ inline HeapWord* old_attempt_allocation(size_t word_size,
++ AllocationContext_t context);
+
+ // These methods are the "callbacks" from the G1AllocRegion class.
+
+@@ -666,13 +603,15 @@
+ // Callback from VM_G1CollectForAllocation operation.
+ // This function does everything necessary/possible to satisfy a
+ // failed allocation request (including collection, expansion, etc.)
+- HeapWord* satisfy_failed_allocation(size_t word_size, bool* succeeded);
++ HeapWord* satisfy_failed_allocation(size_t word_size,
++ AllocationContext_t context,
++ bool* succeeded);
+
+ // Attempting to expand the heap sufficiently
+ // to support an allocation of the given "word_size". If
+ // successful, perform the allocation and return the address of the
+ // allocated block, or else "NULL".
+- HeapWord* expand_and_allocate(size_t word_size);
++ HeapWord* expand_and_allocate(size_t word_size, AllocationContext_t context);
+
+ // Process any reference objects discovered during
+ // an incremental evacuation pause.
+@@ -684,6 +623,10 @@
+
+ public:
+
++ G1Allocator* allocator() {
++ return _allocator;
++ }
++
+ G1MonitoringSupport* g1mm() {
+ assert(_g1mm != NULL, "should have been initialized");
+ return _g1mm;
+@@ -695,19 +638,51 @@
+ // (Rounds up to a HeapRegion boundary.)
+ bool expand(size_t expand_bytes);
+
++ // Returns the PLAB statistics given a purpose.
++ PLABStats* stats_for_purpose(GCAllocPurpose purpose) {
++ PLABStats* stats = NULL;
++
++ switch (purpose) {
++ case GCAllocForSurvived:
++ stats = &_survivor_plab_stats;
++ break;
++ case GCAllocForTenured:
++ stats = &_old_plab_stats;
++ break;
++ default:
++ assert(false, "unrecognized GCAllocPurpose");
++ }
++
++ return stats;
++ }
++
++ // Determines PLAB size for a particular allocation purpose.
++ size_t desired_plab_sz(GCAllocPurpose purpose);
++
++ inline AllocationContextStats& allocation_context_stats();
++
+ // Do anything common to GC's.
+ virtual void gc_prologue(bool full);
+ virtual void gc_epilogue(bool full);
+
++ inline void set_humongous_is_live(oop obj);
++
++ bool humongous_is_live(uint region) {
++ return _humongous_is_live.is_live(region);
++ }
++
++ // Returns whether the given region (which must be a humongous (start) region)
++ // is to be considered conservatively live regardless of any other conditions.
++ bool humongous_region_is_always_live(uint index);
++ // Register the given region to be part of the collection set.
++ inline void register_humongous_region_with_in_cset_fast_test(uint index);
++ // Register regions with humongous objects (actually on the start region) in
++ // the in_cset_fast_test table.
++ void register_humongous_regions_with_in_cset_fast_test();
+ // We register a region with the fast "in collection set" test. We
+ // simply set to true the array slot corresponding to this region.
+ void register_region_with_in_cset_fast_test(HeapRegion* r) {
+- assert(_in_cset_fast_test_base != NULL, "sanity");
+- assert(r->in_collection_set(), "invariant");
+- uint index = r->hrs_index();
+- assert(index < _in_cset_fast_test_length, "invariant");
+- assert(!_in_cset_fast_test_base[index], "invariant");
+- _in_cset_fast_test_base[index] = true;
++ _in_cset_fast_test.set_in_cset(r->hrm_index());
+ }
+
+ // This is a fast test on whether a reference points into the
+@@ -716,9 +691,7 @@
+ inline bool in_cset_fast_test(oop obj);
+
+ void clear_cset_fast_test() {
+- assert(_in_cset_fast_test_base != NULL, "sanity");
+- memset(_in_cset_fast_test_base, false,
+- (size_t) _in_cset_fast_test_length * sizeof(bool));
++ _in_cset_fast_test.clear();
+ }
+
+ // This is called at the start of either a concurrent cycle or a Full
+@@ -847,22 +820,13 @@
+ // param is for use with parallel roots processing, and should be
+ // the "i" of the calling parallel worker thread's work(i) function.
+ // In the sequential case this param will be ignored.
+- void g1_process_strong_roots(bool is_scavenging,
+- ScanningOption so,
+- OopClosure* scan_non_heap_roots,
+- OopsInHeapRegionClosure* scan_rs,
+- G1KlassScanClosure* scan_klasses,
+- uint worker_i);
+-
+- // Apply "blk" to all the weak roots of the system. These include
+- // JNI weak roots, the code cache, system dictionary, symbol table,
+- // string table, and referents of reachable weak refs.
+- void g1_process_weak_roots(OopClosure* root_closure);
+-
+- // Notifies all the necessary spaces that the committed space has
+- // been updated (either expanded or shrunk). It should be called
+- // after _g1_storage is updated.
+- void update_committed_space(HeapWord* old_end, HeapWord* new_end);
++ void g1_process_roots(OopClosure* scan_non_heap_roots,
++ OopClosure* scan_non_heap_weak_roots,
++ OopsInHeapRegionClosure* scan_rs,
++ CLDClosure* scan_strong_clds,
++ CLDClosure* scan_weak_clds,
++ CodeBlobClosure* scan_strong_code,
++ uint worker_i);
+
+ // The concurrent marker (and the thread it runs in.)
+ ConcurrentMark* _cm;
+@@ -1050,7 +1014,7 @@
+ // of G1CollectedHeap::_gc_time_stamp.
+ unsigned int* _worker_cset_start_region_time_stamp;
+
+- enum G1H_process_strong_roots_tasks {
++ enum G1H_process_roots_tasks {
+ G1H_PS_filter_satb_buffers,
+ G1H_PS_refProcessor_oops_do,
+ // Leave this one last.
+@@ -1131,20 +1095,11 @@
+ return _gc_time_stamp;
+ }
+
+- void reset_gc_time_stamp() {
+- _gc_time_stamp = 0;
+- OrderAccess::fence();
+- // Clear the cached CSet starting regions and time stamps.
+- // Their validity is dependent on the GC timestamp.
+- clear_cset_start_regions();
+- }
++ inline void reset_gc_time_stamp();
+
+ void check_gc_time_stamps() PRODUCT_RETURN;
+
+- void increment_gc_time_stamp() {
+- ++_gc_time_stamp;
+- OrderAccess::fence();
+- }
++ inline void increment_gc_time_stamp();
+
+ // Reset the given region's GC timestamp. If it's starts humongous,
+ // also reset the GC timestamp of its corresponding
+@@ -1182,43 +1137,51 @@
+ // end fields defining the extent of the contiguous allocation region.)
+ // But G1CollectedHeap doesn't yet support this.
+
+- // Return an estimate of the maximum allocation that could be performed
+- // without triggering any collection or expansion activity. In a
+- // generational collector, for example, this is probably the largest
+- // allocation that could be supported (without expansion) in the youngest
+- // generation. It is "unsafe" because no locks are taken; the result
+- // should be treated as an approximation, not a guarantee, for use in
+- // heuristic resizing decisions.
+- virtual size_t unsafe_max_alloc();
+-
+ virtual bool is_maximal_no_gc() const {
+- return _g1_storage.uncommitted_size() == 0;
++ return _hrm.available() == 0;
+ }
+
+- // The total number of regions in the heap.
+- uint n_regions() { return _hrs.length(); }
++ // The current number of regions in the heap.
++ uint num_regions() const { return _hrm.length(); }
+
+ // The max number of regions in the heap.
+- uint max_regions() { return _hrs.max_length(); }
++ uint max_regions() const { return _hrm.max_length(); }
+
+ // The number of regions that are completely free.
+- uint free_regions() { return _free_list.length(); }
++ uint num_free_regions() const { return _hrm.num_free_regions(); }
+
+ // The number of regions that are not completely free.
+- uint used_regions() { return n_regions() - free_regions(); }
+-
+- // The number of regions available for "regular" expansion.
+- uint expansion_regions() { return _expansion_regions; }
+-
+- // Factory method for HeapRegion instances. It will return NULL if
+- // the allocation fails.
+- HeapRegion* new_heap_region(uint hrs_index, HeapWord* bottom);
++ uint num_used_regions() const { return num_regions() - num_free_regions(); }
+
+ void verify_not_dirty_region(HeapRegion* hr) PRODUCT_RETURN;
+ void verify_dirty_region(HeapRegion* hr) PRODUCT_RETURN;
+ void verify_dirty_young_list(HeapRegion* head) PRODUCT_RETURN;
+ void verify_dirty_young_regions() PRODUCT_RETURN;
+
++#ifndef PRODUCT
++ // Make sure that the given bitmap has no marked objects in the
++ // range [from,limit). If it does, print an error message and return
++ // false. Otherwise, just return true. bitmap_name should be "prev"
++ // or "next".
++ bool verify_no_bits_over_tams(const char* bitmap_name, CMBitMapRO* bitmap,
++ HeapWord* from, HeapWord* limit);
++
++ // Verify that the prev / next bitmap range [tams,end) for the given
++ // region has no marks. Return true if all is well, false if errors
++ // are detected.
++ bool verify_bitmaps(const char* caller, HeapRegion* hr);
++#endif // PRODUCT
++
++ // If G1VerifyBitmaps is set, verify that the marking bitmaps for
++ // the given region do not have any spurious marks. If errors are
++ // detected, print appropriate error messages and crash.
++ void check_bitmaps(const char* caller, HeapRegion* hr) PRODUCT_RETURN;
++
++ // If G1VerifyBitmaps is set, verify that the marking bitmaps do not
++ // have any spurious marks. If errors are detected, print
++ // appropriate error messages and crash.
++ void check_bitmaps(const char* caller) PRODUCT_RETURN;
++
+ // verify_region_sets() performs verification over the region
+ // lists. It will be compiled in the product code to be used when
+ // necessary (i.e., during heap verification).
+@@ -1237,7 +1200,7 @@
+
+ #ifdef ASSERT
+ bool is_on_master_free_list(HeapRegion* hr) {
+- return hr->containing_set() == &_free_list;
++ return _hrm.is_free(hr);
+ }
+ #endif // ASSERT
+
+@@ -1249,7 +1212,7 @@
+ }
+
+ void append_secondary_free_list() {
+- _free_list.add_ordered(&_secondary_free_list);
++ _hrm.insert_list_into_free_list(&_secondary_free_list);
+ }
+
+ void append_secondary_free_list_if_not_empty_with_lock() {
+@@ -1275,7 +1238,7 @@
+ // Determine whether the given region is one that we are using as an
+ // old GC alloc region.
+ bool is_old_gc_alloc_region(HeapRegion* hr) {
+- return hr == _retained_old_gc_alloc_region;
++ return _allocator->is_retained_old_region(hr);
+ }
+
+ // Perform a collection of the heap; intended for use in implementing
+@@ -1286,6 +1249,11 @@
+ // The same as above but assume that the caller holds the Heap_lock.
+ void collect_locked(GCCause::Cause cause);
+
++ virtual bool copy_allocation_context_stats(const jint* contexts,
++ jlong* totals,
++ jbyte* accuracy,
++ jint len);
++
+ // True iff an evacuation has failed in the most-recent collection.
+ bool evacuation_failed() { return _evacuation_failed; }
+
+@@ -1295,33 +1263,84 @@
+
+ // Returns "TRUE" iff "p" points into the committed areas of the heap.
+ virtual bool is_in(const void* p) const;
++#ifdef ASSERT
++ // Returns whether p is in one of the available areas of the heap. Slow but
++ // extensive version.
++ bool is_in_exact(const void* p) const;
++#endif
+
+ // Return "TRUE" iff the given object address is within the collection
+- // set.
++ // set. Slow implementation.
+ inline bool obj_in_cs(oop obj);
+
++ inline bool is_in_cset(oop obj);
++
++ inline bool is_in_cset_or_humongous(const oop obj);
++
++ enum in_cset_state_t {
++ InNeither, // neither in collection set nor humongous
++ InCSet, // region is in collection set only
++ IsHumongous // region is a humongous start region
++ };
++ private:
++ // Instances of this class are used for quick tests on whether a reference points
++ // into the collection set or is a humongous object (points into a humongous
++ // object).
++ // Each of the array's elements denotes whether the corresponding region is in
++ // the collection set or a humongous region.
++ // We use this to quickly reclaim humongous objects: by making a humongous region
++ // succeed this test, we sort-of add it to the collection set. During the reference
++ // iteration closures, when we see a humongous region, we simply mark it as
++ // referenced, i.e. live.
++ class G1FastCSetBiasedMappedArray : public G1BiasedMappedArray<char> {
++ protected:
++ char default_value() const { return G1CollectedHeap::InNeither; }
++ public:
++ void set_humongous(uintptr_t index) {
++ assert(get_by_index(index) != InCSet, "Should not overwrite InCSet values");
++ set_by_index(index, G1CollectedHeap::IsHumongous);
++ }
++
++ void clear_humongous(uintptr_t index) {
++ set_by_index(index, G1CollectedHeap::InNeither);
++ }
++
++ void set_in_cset(uintptr_t index) {
++ assert(get_by_index(index) != G1CollectedHeap::IsHumongous, "Should not overwrite IsHumongous value");
++ set_by_index(index, G1CollectedHeap::InCSet);
++ }
++
++ bool is_in_cset_or_humongous(HeapWord* addr) const { return get_by_address(addr) != G1CollectedHeap::InNeither; }
++ bool is_in_cset(HeapWord* addr) const { return get_by_address(addr) == G1CollectedHeap::InCSet; }
++ G1CollectedHeap::in_cset_state_t at(HeapWord* addr) const { return (G1CollectedHeap::in_cset_state_t)get_by_address(addr); }
++ void clear() { G1BiasedMappedArray<char>::clear(); }
++ };
++
++ // This array is used for a quick test on whether a reference points into
++ // the collection set or not. Each of the array's elements denotes whether the
++ // corresponding region is in the collection set or not.
++ G1FastCSetBiasedMappedArray _in_cset_fast_test;
++
++ public:
++
++ inline in_cset_state_t in_cset_state(const oop obj);
++
+ // Return "TRUE" iff the given object address is in the reserved
+ // region of g1.
+ bool is_in_g1_reserved(const void* p) const {
+- return _g1_reserved.contains(p);
++ return _hrm.reserved().contains(p);
+ }
+
+ // Returns a MemRegion that corresponds to the space that has been
+ // reserved for the heap
+- MemRegion g1_reserved() {
+- return _g1_reserved;
+- }
+-
+- // Returns a MemRegion that corresponds to the space that has been
+- // committed in the heap
+- MemRegion g1_committed() {
+- return _g1_committed;
++ MemRegion g1_reserved() const {
++ return _hrm.reserved();
+ }
+
+ virtual bool is_in_closed_subset(const void* p) const;
+
+- G1SATBCardTableModRefBS* g1_barrier_set() {
+- return (G1SATBCardTableModRefBS*) barrier_set();
++ G1SATBCardTableLoggingModRefBS* g1_barrier_set() {
++ return (G1SATBCardTableLoggingModRefBS*) barrier_set();
+ }
+
+ // This resets the card table to all zeros. It is used after
+@@ -1334,9 +1353,6 @@
+ // "cl.do_oop" on each.
+ virtual void oop_iterate(ExtendedOopClosure* cl);
+
+- // Same as above, restricted to a memory region.
+- void oop_iterate(MemRegion mr, ExtendedOopClosure* cl);
+-
+ // Iterate over all objects, calling "cl.do_object" on each.
+ virtual void object_iterate(ObjectClosure* cl);
+
+@@ -1354,6 +1370,12 @@
+ // Return the region with the given index. It assumes the index is valid.
+ inline HeapRegion* region_at(uint index) const;
+
++ // Calculate the region index of the given address. Given address must be
++ // within the heap.
++ inline uint addr_to_region(HeapWord* addr) const;
++
++ inline HeapWord* bottom_addr_for_region(uint index) const;
++
+ // Divide the heap region sequence into "chunks" of some size (the number
+ // of regions divided by the number of parallel threads times some
+ // overpartition factor, currently 4). Assumes that this will be called
+@@ -1367,10 +1389,10 @@
+ // setting the claim value of the second and subsequent regions of the
+ // chunk.) For now requires that "doHeapRegion" always returns "false",
+ // i.e., that a closure never attempt to abort a traversal.
+- void heap_region_par_iterate_chunked(HeapRegionClosure* blk,
+- uint worker,
+- uint no_of_par_workers,
+- jint claim_value);
++ void heap_region_par_iterate_chunked(HeapRegionClosure* cl,
++ uint worker_id,
++ uint num_workers,
++ jint claim_value) const;
+
+ // It resets all the region claim values to the default.
+ void reset_heap_region_claim_values();
+@@ -1395,35 +1417,27 @@
+ // starting region for iterating over the current collection set.
+ HeapRegion* start_cset_region_for_worker(uint worker_i);
+
+- // This is a convenience method that is used by the
+- // HeapRegionIterator classes to calculate the starting region for
+- // each worker so that they do not all start from the same region.
+- HeapRegion* start_region_for_worker(uint worker_i, uint no_of_par_workers);
+-
+ // Iterate over the regions (if any) in the current collection set.
+ void collection_set_iterate(HeapRegionClosure* blk);
+
+ // As above but starting from region r
+ void collection_set_iterate_from(HeapRegion* r, HeapRegionClosure *blk);
+
+- // Returns the first (lowest address) compactible space in the heap.
+- virtual CompactibleSpace* first_compactible_space();
++ HeapRegion* next_compaction_region(const HeapRegion* from) const;
+
+ // A CollectedHeap will contain some number of spaces. This finds the
+ // space containing a given address, or else returns NULL.
+ virtual Space* space_containing(const void* addr) const;
+
+- // A G1CollectedHeap will contain some number of heap regions. This
+- // finds the region containing a given address, or else returns NULL.
++ // Returns the HeapRegion that contains addr. addr must not be NULL.
++ template <class T>
++ inline HeapRegion* heap_region_containing_raw(const T addr) const;
++
++ // Returns the HeapRegion that contains addr. addr must not be NULL.
++ // If addr is within a humongous continues region, it returns its humongous start region.
+ template <class T>
+ inline HeapRegion* heap_region_containing(const T addr) const;
+
+- // Like the above, but requires "addr" to be in the heap (to avoid a
+- // null-check), and unlike the above, may return an continuing humongous
+- // region.
+- template <class T>
+- inline HeapRegion* heap_region_containing_raw(const T addr) const;
+-
+ // A CollectedHeap is divided into a dense sequence of "blocks"; that is,
+ // each address in the (reserved) heap is a member of exactly
+ // one block. The defining characteristic of a block is that it is
+@@ -1565,7 +1579,6 @@
+ // the region to which the object belongs. An object is dead
+ // iff a) it was not allocated since the last mark and b) it
+ // is not marked.
+-
+ bool is_obj_dead(const oop obj, const HeapRegion* hr) const {
+ return
+ !hr->obj_allocated_since_prev_marking(obj) &&
+@@ -1575,7 +1588,6 @@
+ // This function returns true when an object has been
+ // around since the previous marking and hasn't yet
+ // been marked during this marking.
+-
+ bool is_obj_ill(const oop obj, const HeapRegion* hr) const {
+ return
+ !hr->obj_allocated_since_next_marking(obj) &&
+@@ -1621,19 +1633,9 @@
+ // Unregister the given nmethod from the G1 heap
+ virtual void unregister_nmethod(nmethod* nm);
+
+- // Migrate the nmethods in the code root lists of the regions
+- // in the collection set to regions in to-space. In the event
+- // of an evacuation failure, nmethods that reference objects
+- // that were not successfullly evacuated are not migrated.
+- void migrate_strong_code_roots();
+-
+ // Free up superfluous code root memory.
+ void purge_code_root_memory();
+
+- // During an initial mark pause, mark all the code roots that
+- // point into regions *not* in the collection set.
+- void mark_strong_code_roots(uint worker_id);
+-
+ // Rebuild the stong code root lists for each region
+ // after a full GC
+ void rebuild_strong_code_roots();
+@@ -1642,6 +1644,9 @@
+ // in symbol table, possibly in parallel.
+ void unlink_string_and_symbol_table(BoolObjectClosure* is_alive, bool unlink_strings = true, bool unlink_symbols = true);
+
++ // Parallel phase of unloading/cleaning after G1 concurrent mark.
++ void parallel_cleaning(BoolObjectClosure* is_alive, bool process_strings, bool process_symbols, bool class_unloading_occurred);
++
+ // Redirty logged cards in the refinement queue.
+ void redirty_logged_cards();
+ // Verification
+@@ -1713,274 +1718,4 @@
+ size_t _max_heap_capacity;
+ };
+
+-class G1ParGCAllocBuffer: public ParGCAllocBuffer {
+-private:
+- bool _retired;
+-
+-public:
+- G1ParGCAllocBuffer(size_t gclab_word_size);
+-
+- void set_buf(HeapWord* buf) {
+- ParGCAllocBuffer::set_buf(buf);
+- _retired = false;
+- }
+-
+- void retire(bool end_of_gc, bool retain) {
+- if (_retired)
+- return;
+- ParGCAllocBuffer::retire(end_of_gc, retain);
+- _retired = true;
+- }
+-};
+-
+-class G1ParScanThreadState : public StackObj {
+-protected:
+- G1CollectedHeap* _g1h;
+- RefToScanQueue* _refs;
+- DirtyCardQueue _dcq;
+- G1SATBCardTableModRefBS* _ct_bs;
+- G1RemSet* _g1_rem;
+-
+- G1ParGCAllocBuffer _surviving_alloc_buffer;
+- G1ParGCAllocBuffer _tenured_alloc_buffer;
+- G1ParGCAllocBuffer* _alloc_buffers[GCAllocPurposeCount];
+- ageTable _age_table;
+-
+- G1ParScanClosure _scanner;
+-
+- size_t _alloc_buffer_waste;
+- size_t _undo_waste;
+-
+- OopsInHeapRegionClosure* _evac_failure_cl;
+-
+- int _hash_seed;
+- uint _queue_num;
+-
+- size_t _term_attempts;
+-
+- double _start;
+- double _start_strong_roots;
+- double _strong_roots_time;
+- double _start_term;
+- double _term_time;
+-
+- // Map from young-age-index (0 == not young, 1 is youngest) to
+- // surviving words. base is what we get back from the malloc call
+- size_t* _surviving_young_words_base;
+- // this points into the array, as we use the first few entries for padding
+- size_t* _surviving_young_words;
+-
+-#define PADDING_ELEM_NUM (DEFAULT_CACHE_LINE_SIZE / sizeof(size_t))
+-
+- void add_to_alloc_buffer_waste(size_t waste) { _alloc_buffer_waste += waste; }
+-
+- void add_to_undo_waste(size_t waste) { _undo_waste += waste; }
+-
+- DirtyCardQueue& dirty_card_queue() { return _dcq; }
+- G1SATBCardTableModRefBS* ctbs() { return _ct_bs; }
+-
+- template <class T> inline void immediate_rs_update(HeapRegion* from, T* p, int tid);
+-
+- template <class T> void deferred_rs_update(HeapRegion* from, T* p, int tid) {
+- // If the new value of the field points to the same region or
+- // is the to-space, we don't need to include it in the Rset updates.
+- if (!from->is_in_reserved(oopDesc::load_decode_heap_oop(p)) && !from->is_survivor()) {
+- size_t card_index = ctbs()->index_for(p);
+- // If the card hasn't been added to the buffer, do it.
+- if (ctbs()->mark_card_deferred(card_index)) {
+- dirty_card_queue().enqueue((jbyte*)ctbs()->byte_for_index(card_index));
+- }
+- }
+- }
+-
+-public:
+- G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp);
+-
+- ~G1ParScanThreadState() {
+- FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC);
+- }
+-
+- RefToScanQueue* refs() { return _refs; }
+- ageTable* age_table() { return &_age_table; }
+-
+- G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose) {
+- return _alloc_buffers[purpose];
+- }
+-
+- size_t alloc_buffer_waste() const { return _alloc_buffer_waste; }
+- size_t undo_waste() const { return _undo_waste; }
+-
+-#ifdef ASSERT
+- bool verify_ref(narrowOop* ref) const;
+- bool verify_ref(oop* ref) const;
+- bool verify_task(StarTask ref) const;
+-#endif // ASSERT
+-
+- template <class T> void push_on_queue(T* ref) {
+- assert(verify_ref(ref), "sanity");
+- refs()->push(ref);
+- }
+-
+- template <class T> inline void update_rs(HeapRegion* from, T* p, int tid);
+-
+- HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz) {
+- HeapWord* obj = NULL;
+- size_t gclab_word_size = _g1h->desired_plab_sz(purpose);
+- if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
+- G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose);
+- add_to_alloc_buffer_waste(alloc_buf->words_remaining());
+- alloc_buf->retire(false /* end_of_gc */, false /* retain */);
+-
+- HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size);
+- if (buf == NULL) return NULL; // Let caller handle allocation failure.
+- // Otherwise.
+- alloc_buf->set_word_size(gclab_word_size);
+- alloc_buf->set_buf(buf);
+-
+- obj = alloc_buf->allocate(word_sz);
+- assert(obj != NULL, "buffer was definitely big enough...");
+- } else {
+- obj = _g1h->par_allocate_during_gc(purpose, word_sz);
+- }
+- return obj;
+- }
+-
+- HeapWord* allocate(GCAllocPurpose purpose, size_t word_sz) {
+- HeapWord* obj = alloc_buffer(purpose)->allocate(word_sz);
+- if (obj != NULL) return obj;
+- return allocate_slow(purpose, word_sz);
+- }
+-
+- void undo_allocation(GCAllocPurpose purpose, HeapWord* obj, size_t word_sz) {
+- if (alloc_buffer(purpose)->contains(obj)) {
+- assert(alloc_buffer(purpose)->contains(obj + word_sz - 1),
+- "should contain whole object");
+- alloc_buffer(purpose)->undo_allocation(obj, word_sz);
+- } else {
+- CollectedHeap::fill_with_object(obj, word_sz);
+- add_to_undo_waste(word_sz);
+- }
+- }
+-
+- void set_evac_failure_closure(OopsInHeapRegionClosure* evac_failure_cl) {
+- _evac_failure_cl = evac_failure_cl;
+- }
+- OopsInHeapRegionClosure* evac_failure_closure() {
+- return _evac_failure_cl;
+- }
+-
+- int* hash_seed() { return &_hash_seed; }
+- uint queue_num() { return _queue_num; }
+-
+- size_t term_attempts() const { return _term_attempts; }
+- void note_term_attempt() { _term_attempts++; }
+-
+- void start_strong_roots() {
+- _start_strong_roots = os::elapsedTime();
+- }
+- void end_strong_roots() {
+- _strong_roots_time += (os::elapsedTime() - _start_strong_roots);
+- }
+- double strong_roots_time() const { return _strong_roots_time; }
+-
+- void start_term_time() {
+- note_term_attempt();
+- _start_term = os::elapsedTime();
+- }
+- void end_term_time() {
+- _term_time += (os::elapsedTime() - _start_term);
+- }
+- double term_time() const { return _term_time; }
+-
+- double elapsed_time() const {
+- return os::elapsedTime() - _start;
+- }
+-
+- static void
+- print_termination_stats_hdr(outputStream* const st = gclog_or_tty);
+- void
+- print_termination_stats(int i, outputStream* const st = gclog_or_tty) const;
+-
+- size_t* surviving_young_words() {
+- // We add on to hide entry 0 which accumulates surviving words for
+- // age -1 regions (i.e. non-young ones)
+- return _surviving_young_words;
+- }
+-
+- void retire_alloc_buffers() {
+- for (int ap = 0; ap < GCAllocPurposeCount; ++ap) {
+- size_t waste = _alloc_buffers[ap]->words_remaining();
+- add_to_alloc_buffer_waste(waste);
+- _alloc_buffers[ap]->flush_stats_and_retire(_g1h->stats_for_purpose((GCAllocPurpose)ap),
+- true /* end_of_gc */,
+- false /* retain */);
+- }
+- }
+-private:
+- #define G1_PARTIAL_ARRAY_MASK 0x2
+-
+- inline bool has_partial_array_mask(oop* ref) const {
+- return ((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) == G1_PARTIAL_ARRAY_MASK;
+- }
+-
+- // We never encode partial array oops as narrowOop*, so return false immediately.
+- // This allows the compiler to create optimized code when popping references from
+- // the work queue.
+- inline bool has_partial_array_mask(narrowOop* ref) const {
+- assert(((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) != G1_PARTIAL_ARRAY_MASK, "Partial array oop reference encoded as narrowOop*");
+- return false;
+- }
+-
+- // Only implement set_partial_array_mask() for regular oops, not for narrowOops.
+- // We always encode partial arrays as regular oop, to allow the
+- // specialization for has_partial_array_mask() for narrowOops above.
+- // This means that unintentional use of this method with narrowOops are caught
+- // by the compiler.
+- inline oop* set_partial_array_mask(oop obj) const {
+- assert(((uintptr_t)(void *)obj & G1_PARTIAL_ARRAY_MASK) == 0, "Information loss!");
+- return (oop*) ((uintptr_t)(void *)obj | G1_PARTIAL_ARRAY_MASK);
+- }
+-
+- inline oop clear_partial_array_mask(oop* ref) const {
+- return cast_to_oop((intptr_t)ref & ~G1_PARTIAL_ARRAY_MASK);
+- }
+-
+- inline void do_oop_partial_array(oop* p);
+-
+- // This method is applied to the fields of the objects that have just been copied.
+- template <class T> void do_oop_evac(T* p, HeapRegion* from) {
+- assert(!oopDesc::is_null(oopDesc::load_decode_heap_oop(p)),
+- "Reference should not be NULL here as such are never pushed to the task queue.");
+- oop obj = oopDesc::load_decode_heap_oop_not_null(p);
+-
+- // Although we never intentionally push references outside of the collection
+- // set, due to (benign) races in the claim mechanism during RSet scanning more
+- // than one thread might claim the same card. So the same card may be
+- // processed multiple times. So redo this check.
+- if (_g1h->in_cset_fast_test(obj)) {
+- oop forwardee;
+- if (obj->is_forwarded()) {
+- forwardee = obj->forwardee();
+- } else {
+- forwardee = copy_to_survivor_space(obj);
+- }
+- assert(forwardee != NULL, "forwardee should not be NULL");
+- oopDesc::encode_store_heap_oop(p, forwardee);
+- }
+-
+- assert(obj != NULL, "Must be");
+- update_rs(from, p, queue_num());
+- }
+-public:
+-
+- oop copy_to_survivor_space(oop const obj);
+-
+- template <class T> inline void deal_with_reference(T* ref_to_scan);
+-
+- inline void deal_with_reference(StarTask ref);
+-
+-public:
+- void trim_queue();
+-};
+-
+ #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -29,34 +29,61 @@
+ #include "gc_implementation/g1/g1CollectedHeap.hpp"
+ #include "gc_implementation/g1/g1AllocRegion.inline.hpp"
+ #include "gc_implementation/g1/g1CollectorPolicy.hpp"
+-#include "gc_implementation/g1/g1RemSet.inline.hpp"
+ #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
++#include "gc_implementation/g1/heapRegionManager.inline.hpp"
+ #include "gc_implementation/g1/heapRegionSet.inline.hpp"
+-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "utilities/taskqueue.hpp"
+
+ // Inline functions for G1CollectedHeap
+
++inline AllocationContextStats& G1CollectedHeap::allocation_context_stats() {
++ return _allocation_context_stats;
++}
++
+ // Return the region with the given index. It assumes the index is valid.
+-inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrs.at(index); }
++inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrm.at(index); }
++
++inline uint G1CollectedHeap::addr_to_region(HeapWord* addr) const {
++ assert(is_in_reserved(addr),
++ err_msg("Cannot calculate region index for address "PTR_FORMAT" that is outside of the heap ["PTR_FORMAT", "PTR_FORMAT")",
++ p2i(addr), p2i(_reserved.start()), p2i(_reserved.end())));
++ return (uint)(pointer_delta(addr, _reserved.start(), sizeof(uint8_t)) >> HeapRegion::LogOfHRGrainBytes);
++}
++
++inline HeapWord* G1CollectedHeap::bottom_addr_for_region(uint index) const {
++ return _hrm.reserved().start() + index * HeapRegion::GrainWords;
++}
+
+ template <class T>
+-inline HeapRegion*
+-G1CollectedHeap::heap_region_containing(const T addr) const {
+- HeapRegion* hr = _hrs.addr_to_region((HeapWord*) addr);
+- // hr can be null if addr in perm_gen
+- if (hr != NULL && hr->continuesHumongous()) {
+- hr = hr->humongous_start_region();
++inline HeapRegion* G1CollectedHeap::heap_region_containing_raw(const T addr) const {
++ assert(addr != NULL, "invariant");
++ assert(is_in_g1_reserved((const void*) addr),
++ err_msg("Address "PTR_FORMAT" is outside of the heap ranging from ["PTR_FORMAT" to "PTR_FORMAT")",
++ p2i((void*)addr), p2i(g1_reserved().start()), p2i(g1_reserved().end())));
++ return _hrm.addr_to_region((HeapWord*) addr);
++}
++
++template <class T>
++inline HeapRegion* G1CollectedHeap::heap_region_containing(const T addr) const {
++ HeapRegion* hr = heap_region_containing_raw(addr);
++ if (hr->continuesHumongous()) {
++ return hr->humongous_start_region();
+ }
+ return hr;
+ }
+
+-template <class T>
+-inline HeapRegion*
+-G1CollectedHeap::heap_region_containing_raw(const T addr) const {
+- assert(_g1_reserved.contains((const void*) addr), "invariant");
+- HeapRegion* res = _hrs.addr_to_region_unsafe((HeapWord*) addr);
+- return res;
++inline void G1CollectedHeap::reset_gc_time_stamp() {
++ _gc_time_stamp = 0;
++ OrderAccess::fence();
++ // Clear the cached CSet starting regions and time stamps.
++ // Their validity is dependent on the GC timestamp.
++ clear_cset_start_regions();
++}
++
++inline void G1CollectedHeap::increment_gc_time_stamp() {
++ ++_gc_time_stamp;
++ OrderAccess::fence();
+ }
+
+ inline void G1CollectedHeap::old_set_remove(HeapRegion* hr) {
+@@ -64,22 +91,23 @@
+ }
+
+ inline bool G1CollectedHeap::obj_in_cs(oop obj) {
+- HeapRegion* r = _hrs.addr_to_region((HeapWord*) obj);
++ HeapRegion* r = _hrm.addr_to_region((HeapWord*) obj);
+ return r != NULL && r->in_collection_set();
+ }
+
+-inline HeapWord*
+-G1CollectedHeap::attempt_allocation(size_t word_size,
+- unsigned int* gc_count_before_ret,
+- int* gclocker_retry_count_ret) {
++inline HeapWord* G1CollectedHeap::attempt_allocation(size_t word_size,
++ unsigned int* gc_count_before_ret,
++ int* gclocker_retry_count_ret) {
+ assert_heap_not_locked_and_not_at_safepoint();
+ assert(!isHumongous(word_size), "attempt_allocation() should not "
+ "be called for humongous allocation requests");
+
+- HeapWord* result = _mutator_alloc_region.attempt_allocation(word_size,
+- false /* bot_updates */);
++ AllocationContext_t context = AllocationContext::current();
++ HeapWord* result = _allocator->mutator_alloc_region(context)->attempt_allocation(word_size,
++ false /* bot_updates */);
+ if (result == NULL) {
+ result = attempt_allocation_slow(word_size,
++ context,
+ gc_count_before_ret,
+ gclocker_retry_count_ret);
+ }
+@@ -90,17 +118,17 @@
+ return result;
+ }
+
+-inline HeapWord* G1CollectedHeap::survivor_attempt_allocation(size_t
+- word_size) {
++inline HeapWord* G1CollectedHeap::survivor_attempt_allocation(size_t word_size,
++ AllocationContext_t context) {
+ assert(!isHumongous(word_size),
+ "we should not be seeing humongous-size allocations in this path");
+
+- HeapWord* result = _survivor_gc_alloc_region.attempt_allocation(word_size,
+- false /* bot_updates */);
++ HeapWord* result = _allocator->survivor_gc_alloc_region(context)->attempt_allocation(word_size,
++ false /* bot_updates */);
+ if (result == NULL) {
+ MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
+- result = _survivor_gc_alloc_region.attempt_allocation_locked(word_size,
+- false /* bot_updates */);
++ result = _allocator->survivor_gc_alloc_region(context)->attempt_allocation_locked(word_size,
++ false /* bot_updates */);
+ }
+ if (result != NULL) {
+ dirty_young_block(result, word_size);
+@@ -108,16 +136,17 @@
+ return result;
+ }
+
+-inline HeapWord* G1CollectedHeap::old_attempt_allocation(size_t word_size) {
++inline HeapWord* G1CollectedHeap::old_attempt_allocation(size_t word_size,
++ AllocationContext_t context) {
+ assert(!isHumongous(word_size),
+ "we should not be seeing humongous-size allocations in this path");
+
+- HeapWord* result = _old_gc_alloc_region.attempt_allocation(word_size,
+- true /* bot_updates */);
++ HeapWord* result = _allocator->old_gc_alloc_region(context)->attempt_allocation(word_size,
++ true /* bot_updates */);
+ if (result == NULL) {
+ MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
+- result = _old_gc_alloc_region.attempt_allocation_locked(word_size,
+- true /* bot_updates */);
++ result = _allocator->old_gc_alloc_region(context)->attempt_allocation_locked(word_size,
++ true /* bot_updates */);
+ }
+ return result;
+ }
+@@ -134,8 +163,7 @@
+ // have to keep calling heap_region_containing_raw() in the
+ // asserts below.
+ DEBUG_ONLY(HeapRegion* containing_hr = heap_region_containing_raw(start);)
+- assert(containing_hr != NULL && start != NULL && word_size > 0,
+- "pre-condition");
++ assert(word_size > 0, "pre-condition");
+ assert(containing_hr->is_in(start), "it should contain start");
+ assert(containing_hr->is_young(), "it should be young");
+ assert(!containing_hr->isHumongous(), "it should not be humongous");
+@@ -159,17 +187,11 @@
+ return _cm->nextMarkBitMap()->isMarked((HeapWord *)obj);
+ }
+
+-
+ // This is a fast test on whether a reference points into the
+ // collection set or not. Assume that the reference
+ // points into the heap.
+-inline bool G1CollectedHeap::in_cset_fast_test(oop obj) {
+- assert(_in_cset_fast_test != NULL, "sanity");
+- assert(_g1_committed.contains((HeapWord*) obj), err_msg("Given reference outside of heap, is "PTR_FORMAT, p2i((HeapWord*)obj)));
+- // no need to subtract the bottom of the heap from obj,
+- // _in_cset_fast_test is biased
+- uintx index = cast_from_oop<uintx>(obj) >> HeapRegion::LogOfHRGrainBytes;
+- bool ret = _in_cset_fast_test[index];
++inline bool G1CollectedHeap::is_in_cset(oop obj) {
++ bool ret = _in_cset_fast_test.is_in_cset((HeapWord*)obj);
+ // let's make sure the result is consistent with what the slower
+ // test returns
+ assert( ret || !obj_in_cs(obj), "sanity");
+@@ -177,6 +199,18 @@
+ return ret;
+ }
+
++bool G1CollectedHeap::is_in_cset_or_humongous(const oop obj) {
++ return _in_cset_fast_test.is_in_cset_or_humongous((HeapWord*)obj);
++}
++
++G1CollectedHeap::in_cset_state_t G1CollectedHeap::in_cset_state(const oop obj) {
++ return _in_cset_fast_test.at((HeapWord*)obj);
++}
++
++void G1CollectedHeap::register_humongous_region_with_in_cset_fast_test(uint index) {
++ _in_cset_fast_test.set_humongous(index);
++}
++
+ #ifndef PRODUCT
+ // Support for G1EvacuationFailureALot
+
+@@ -226,8 +260,7 @@
+ }
+ }
+
+-inline bool
+-G1CollectedHeap::evacuation_should_fail() {
++inline bool G1CollectedHeap::evacuation_should_fail() {
+ if (!G1EvacuationFailureALot || !_evacuation_failure_alot_for_current_gc) {
+ return false;
+ }
+@@ -251,8 +284,10 @@
+ #endif // #ifndef PRODUCT
+
+ inline bool G1CollectedHeap::is_in_young(const oop obj) {
+- HeapRegion* hr = heap_region_containing(obj);
+- return hr != NULL && hr->is_young();
++ if (obj == NULL) {
++ return false;
++ }
++ return heap_region_containing(obj)->is_young();
+ }
+
+ // We don't need barriers for initializing stores to objects
+@@ -265,105 +300,34 @@
+ }
+
+ inline bool G1CollectedHeap::is_obj_dead(const oop obj) const {
+- const HeapRegion* hr = heap_region_containing(obj);
+- if (hr == NULL) {
+- if (obj == NULL) return false;
+- else return true;
++ if (obj == NULL) {
++ return false;
+ }
+- else return is_obj_dead(obj, hr);
++ return is_obj_dead(obj, heap_region_containing(obj));
+ }
+
+ inline bool G1CollectedHeap::is_obj_ill(const oop obj) const {
+- const HeapRegion* hr = heap_region_containing(obj);
+- if (hr == NULL) {
+- if (obj == NULL) return false;
+- else return true;
++ if (obj == NULL) {
++ return false;
+ }
+- else return is_obj_ill(obj, hr);
++ return is_obj_ill(obj, heap_region_containing(obj));
+ }
+
+-template <class T> inline void G1ParScanThreadState::immediate_rs_update(HeapRegion* from, T* p, int tid) {
+- if (!from->is_survivor()) {
+- _g1_rem->par_write_ref(from, p, tid);
+- }
+-}
+-
+-template <class T> void G1ParScanThreadState::update_rs(HeapRegion* from, T* p, int tid) {
+- if (G1DeferredRSUpdate) {
+- deferred_rs_update(from, p, tid);
+- } else {
+- immediate_rs_update(from, p, tid);
+- }
+-}
+-
+-
+-inline void G1ParScanThreadState::do_oop_partial_array(oop* p) {
+- assert(has_partial_array_mask(p), "invariant");
+- oop from_obj = clear_partial_array_mask(p);
+-
+- assert(Universe::heap()->is_in_reserved(from_obj), "must be in heap.");
+- assert(from_obj->is_objArray(), "must be obj array");
+- objArrayOop from_obj_array = objArrayOop(from_obj);
+- // The from-space object contains the real length.
+- int length = from_obj_array->length();
+-
+- assert(from_obj->is_forwarded(), "must be forwarded");
+- oop to_obj = from_obj->forwardee();
+- assert(from_obj != to_obj, "should not be chunking self-forwarded objects");
+- objArrayOop to_obj_array = objArrayOop(to_obj);
+- // We keep track of the next start index in the length field of the
+- // to-space object.
+- int next_index = to_obj_array->length();
+- assert(0 <= next_index && next_index < length,
+- err_msg("invariant, next index: %d, length: %d", next_index, length));
+-
+- int start = next_index;
+- int end = length;
+- int remainder = end - start;
+- // We'll try not to push a range that's smaller than ParGCArrayScanChunk.
+- if (remainder > 2 * ParGCArrayScanChunk) {
+- end = start + ParGCArrayScanChunk;
+- to_obj_array->set_length(end);
+- // Push the remainder before we process the range in case another
+- // worker has run out of things to do and can steal it.
+- oop* from_obj_p = set_partial_array_mask(from_obj);
+- push_on_queue(from_obj_p);
+- } else {
+- assert(length == end, "sanity");
+- // We'll process the final range for this object. Restore the length
+- // so that the heap remains parsable in case of evacuation failure.
+- to_obj_array->set_length(end);
+- }
+- _scanner.set_region(_g1h->heap_region_containing_raw(to_obj));
+- // Process indexes [start,end). It will also process the header
+- // along with the first chunk (i.e., the chunk with start == 0).
+- // Note that at this point the length field of to_obj_array is not
+- // correct given that we are using it to keep track of the next
+- // start index. oop_iterate_range() (thankfully!) ignores the length
+- // field and only relies on the start / end parameters. It does
+- // however return the size of the object which will be incorrect. So
+- // we have to ignore it even if we wanted to use it.
+- to_obj_array->oop_iterate_range(&_scanner, start, end);
+-}
+-
+-template <class T> inline void G1ParScanThreadState::deal_with_reference(T* ref_to_scan) {
+- if (!has_partial_array_mask(ref_to_scan)) {
+- // Note: we can use "raw" versions of "region_containing" because
+- // "obj_to_scan" is definitely in the heap, and is not in a
+- // humongous region.
+- HeapRegion* r = _g1h->heap_region_containing_raw(ref_to_scan);
+- do_oop_evac(ref_to_scan, r);
+- } else {
+- do_oop_partial_array((oop*)ref_to_scan);
+- }
+-}
+-
+-inline void G1ParScanThreadState::deal_with_reference(StarTask ref) {
+- assert(verify_task(ref), "sanity");
+- if (ref.is_narrow()) {
+- deal_with_reference((narrowOop*)ref);
+- } else {
+- deal_with_reference((oop*)ref);
++inline void G1CollectedHeap::set_humongous_is_live(oop obj) {
++ uint region = addr_to_region((HeapWord*)obj);
++ // We not only set the "live" flag in the humongous_is_live table, but also
++ // reset the entry in the _in_cset_fast_test table so that subsequent references
++ // to the same humongous object do not go into the slow path again.
++ // This is racy, as multiple threads may at the same time enter here, but this
++ // is benign.
++ // During collection we only ever set the "live" flag, and only ever clear the
++ // entry in the in_cset_fast_table.
++ // We only ever evaluate the contents of these tables (in the VM thread) after
++ // having synchronized the worker threads with the VM thread, or in the same
++ // thread (i.e. within the VM thread).
++ if (!_humongous_is_live.is_live(region)) {
++ _humongous_is_live.set_live(region);
++ _in_cset_fast_test.clear_humongous(region);
+ }
+ }
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap_ext.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "gc_implementation/g1/g1CollectedHeap.hpp"
++
++bool G1CollectedHeap::copy_allocation_context_stats(const jint* contexts,
++ jlong* totals,
++ jbyte* accuracy,
++ jint len) {
++ return false;
++}
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -455,7 +455,7 @@
+ } else {
+ _young_list_fixed_length = _young_gen_sizer->min_desired_young_length();
+ }
+- _free_regions_at_end_of_collection = _g1->free_regions();
++ _free_regions_at_end_of_collection = _g1->num_free_regions();
+ update_young_list_target_length();
+
+ // We may immediately start allocating regions and placing them on the
+@@ -828,7 +828,7 @@
+
+ record_survivor_regions(0, NULL, NULL);
+
+- _free_regions_at_end_of_collection = _g1->free_regions();
++ _free_regions_at_end_of_collection = _g1->num_free_regions();
+ // Reset survivors SurvRateGroup.
+ _survivor_surv_rate_group->reset();
+ update_young_list_target_length();
+@@ -1046,7 +1046,7 @@
+
+ bool new_in_marking_window = _in_marking_window;
+ bool new_in_marking_window_im = false;
+- if (during_initial_mark_pause()) {
++ if (last_pause_included_initial_mark) {
+ new_in_marking_window = true;
+ new_in_marking_window_im = true;
+ }
+@@ -1180,7 +1180,7 @@
+
+ _in_marking_window = new_in_marking_window;
+ _in_marking_window_im = new_in_marking_window_im;
+- _free_regions_at_end_of_collection = _g1->free_regions();
++ _free_regions_at_end_of_collection = _g1->num_free_regions();
+ update_young_list_target_length();
+
+ // Note that _mmu_tracker->max_gc_time() returns the time in seconds.
+@@ -1202,7 +1202,7 @@
+ _survivor_used_bytes_before_gc = young_list->survivor_used_bytes();
+ _heap_capacity_bytes_before_gc = _g1->capacity();
+ _heap_used_bytes_before_gc = _g1->used();
+- _cur_collection_pause_used_regions_at_start = _g1->used_regions();
++ _cur_collection_pause_used_regions_at_start = _g1->num_used_regions();
+
+ _eden_capacity_bytes_before_gc =
+ (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_used_bytes_before_gc;
+@@ -1425,6 +1425,18 @@
+ #endif // PRODUCT
+ }
+
++bool G1CollectorPolicy::is_young_list_full() {
++ uint young_list_length = _g1->young_list()->length();
++ uint young_list_target_length = _young_list_target_length;
++ return young_list_length >= young_list_target_length;
++}
++
++bool G1CollectorPolicy::can_expand_young_list() {
++ uint young_list_length = _g1->young_list()->length();
++ uint young_list_max_length = _young_list_max_length;
++ return young_list_length < young_list_max_length;
++}
++
+ uint G1CollectorPolicy::max_regions(int purpose) {
+ switch (purpose) {
+ case GCAllocForSurvived:
+@@ -1617,7 +1629,7 @@
+ G1CollectorPolicy::record_concurrent_mark_cleanup_end(int no_of_gc_threads) {
+ _collectionSetChooser->clear();
+
+- uint region_num = _g1->n_regions();
++ uint region_num = _g1->num_regions();
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ const uint OverpartitionFactor = 4;
+ uint WorkUnit;
+@@ -1638,7 +1650,7 @@
+ MAX2(region_num / (uint) (ParallelGCThreads * OverpartitionFactor),
+ MinWorkUnit);
+ }
+- _collectionSetChooser->prepare_for_par_region_addition(_g1->n_regions(),
++ _collectionSetChooser->prepare_for_par_region_addition(_g1->num_regions(),
+ WorkUnit);
+ ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser,
+ (int) WorkUnit);
+@@ -1664,7 +1676,7 @@
+ // Add the heap region at the head of the non-incremental collection set
+ void G1CollectorPolicy::add_old_region_to_cset(HeapRegion* hr) {
+ assert(_inc_cset_build_state == Active, "Precondition");
+- assert(!hr->is_young(), "non-incremental add of young region");
++ assert(hr->is_old(), "the region should be old");
+
+ assert(!hr->in_collection_set(), "should not already be in the CSet");
+ hr->set_in_collection_set(true);
+@@ -1810,7 +1822,7 @@
+ // Add the region at the RHS of the incremental cset
+ void G1CollectorPolicy::add_region_to_incremental_cset_rhs(HeapRegion* hr) {
+ // We should only ever be appending survivors at the end of a pause
+- assert( hr->is_survivor(), "Logic");
++ assert(hr->is_survivor(), "Logic");
+
+ // Do the 'common' stuff
+ add_region_to_incremental_cset_common(hr);
+@@ -1828,7 +1840,7 @@
+ // Add the region to the LHS of the incremental cset
+ void G1CollectorPolicy::add_region_to_incremental_cset_lhs(HeapRegion* hr) {
+ // Survivors should be added to the RHS at the end of a pause
+- assert(!hr->is_survivor(), "Logic");
++ assert(hr->is_eden(), "Logic");
+
+ // Do the 'common' stuff
+ add_region_to_incremental_cset_common(hr);
+@@ -1935,7 +1947,7 @@
+ // of them are available.
+
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+- const size_t region_num = g1h->n_regions();
++ const size_t region_num = g1h->num_regions();
+ const size_t perc = (size_t) G1OldCSetRegionThresholdPercent;
+ size_t result = region_num * perc / 100;
+ // emulate ceiling
+@@ -1988,7 +2000,11 @@
+ HeapRegion* hr = young_list->first_survivor_region();
+ while (hr != NULL) {
+ assert(hr->is_survivor(), "badly formed young list");
+- hr->set_young();
++ // There is a convention that all the young regions in the CSet
++ // are tagged as "eden", so we do this for the survivors here. We
++ // use the special set_eden_pre_gc() as it doesn't check that the
++ // region is free (which is not the case here).
++ hr->set_eden_pre_gc();
+ hr = hr->get_next_young_region();
+ }
+
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,6 +26,7 @@
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTORPOLICY_HPP
+
+ #include "gc_implementation/g1/collectionSetChooser.hpp"
++#include "gc_implementation/g1/g1Allocator.hpp"
+ #include "gc_implementation/g1/g1MMUTracker.hpp"
+ #include "memory/collectorPolicy.hpp"
+
+@@ -299,13 +300,13 @@
+ // Accessors
+
+ void set_region_eden(HeapRegion* hr, int young_index_in_cset) {
+- hr->set_young();
++ hr->set_eden();
+ hr->install_surv_rate_group(_short_lived_surv_rate_group);
+ hr->set_young_index_in_cset(young_index_in_cset);
+ }
+
+ void set_region_survivor(HeapRegion* hr, int young_index_in_cset) {
+- assert(hr->is_young() && hr->is_survivor(), "pre-condition");
++ assert(hr->is_survivor(), "pre-condition");
+ hr->install_surv_rate_group(_survivor_surv_rate_group);
+ hr->set_young_index_in_cset(young_index_in_cset);
+ }
+@@ -803,7 +804,7 @@
+
+ // If an expansion would be appropriate, because recent GC overhead had
+ // exceeded the desired limit, return an amount to expand by.
+- size_t expansion_amount();
++ virtual size_t expansion_amount();
+
+ // Print tracing information.
+ void print_tracing_info() const;
+@@ -822,17 +823,9 @@
+
+ size_t young_list_target_length() const { return _young_list_target_length; }
+
+- bool is_young_list_full() {
+- uint young_list_length = _g1->young_list()->length();
+- uint young_list_target_length = _young_list_target_length;
+- return young_list_length >= young_list_target_length;
+- }
++ bool is_young_list_full();
+
+- bool can_expand_young_list() {
+- uint young_list_length = _g1->young_list()->length();
+- uint young_list_max_length = _young_list_max_length;
+- return young_list_length < young_list_max_length;
+- }
++ bool can_expand_young_list();
+
+ uint young_list_max_length() {
+ return _young_list_max_length;
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy_ext.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTORPOLICY_EXT_HPP
++#define SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTORPOLICY_EXT_HPP
++
++#include "gc_implementation/g1/g1CollectorPolicy.hpp"
++
++class G1CollectorPolicyExt : public G1CollectorPolicy { };
++
++#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTORPOLICY_EXT_HPP
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -71,6 +71,9 @@
+ bool _during_initial_mark;
+ bool _during_conc_mark;
+ uint _worker_id;
++ HeapWord* _end_of_last_gap;
++ HeapWord* _last_gap_threshold;
++ HeapWord* _last_obj_threshold;
+
+ public:
+ RemoveSelfForwardPtrObjClosure(G1CollectedHeap* g1, ConcurrentMark* cm,
+@@ -83,7 +86,10 @@
+ _update_rset_cl(update_rset_cl),
+ _during_initial_mark(during_initial_mark),
+ _during_conc_mark(during_conc_mark),
+- _worker_id(worker_id) { }
++ _worker_id(worker_id),
++ _end_of_last_gap(hr->bottom()),
++ _last_gap_threshold(hr->bottom()),
++ _last_obj_threshold(hr->bottom()) { }
+
+ size_t marked_bytes() { return _marked_bytes; }
+
+@@ -107,7 +113,12 @@
+ HeapWord* obj_addr = (HeapWord*) obj;
+ assert(_hr->is_in(obj_addr), "sanity");
+ size_t obj_size = obj->size();
+- _hr->update_bot_for_object(obj_addr, obj_size);
++ HeapWord* obj_end = obj_addr + obj_size;
++
++ if (_end_of_last_gap != obj_addr) {
++ // there was a gap before obj_addr
++ _last_gap_threshold = _hr->cross_threshold(_end_of_last_gap, obj_addr);
++ }
+
+ if (obj->is_forwarded() && obj->forwardee() == obj) {
+ // The object failed to move.
+@@ -115,7 +126,9 @@
+ // We consider all objects that we find self-forwarded to be
+ // live. What we'll do is that we'll update the prev marking
+ // info so that they are all under PTAMS and explicitly marked.
+- _cm->markPrev(obj);
++ if (!_cm->isPrevMarked(obj)) {
++ _cm->markPrev(obj);
++ }
+ if (_during_initial_mark) {
+ // For the next marking info we'll only mark the
+ // self-forwarded objects explicitly if we are during
+@@ -145,28 +158,35 @@
+ // remembered set entries missing given that we skipped cards on
+ // the collection set. So, we'll recreate such entries now.
+ obj->oop_iterate(_update_rset_cl);
+- assert(_cm->isPrevMarked(obj), "Should be marked!");
+ } else {
++
+ // The object has been either evacuated or is dead. Fill it with a
+ // dummy object.
+- MemRegion mr((HeapWord*) obj, obj_size);
++ MemRegion mr(obj_addr, obj_size);
+ CollectedHeap::fill_with_object(mr);
++
++ // must nuke all dead objects which we skipped when iterating over the region
++ _cm->clearRangePrevBitmap(MemRegion(_end_of_last_gap, obj_end));
+ }
++ _end_of_last_gap = obj_end;
++ _last_obj_threshold = _hr->cross_threshold(obj_addr, obj_end);
+ }
+ };
+
+ class RemoveSelfForwardPtrHRClosure: public HeapRegionClosure {
+ G1CollectedHeap* _g1h;
+ ConcurrentMark* _cm;
+- OopsInHeapRegionClosure *_update_rset_cl;
+ uint _worker_id;
+
++ DirtyCardQueue _dcq;
++ UpdateRSetDeferred _update_rset_cl;
++
+ public:
+ RemoveSelfForwardPtrHRClosure(G1CollectedHeap* g1h,
+- OopsInHeapRegionClosure* update_rset_cl,
+ uint worker_id) :
+- _g1h(g1h), _update_rset_cl(update_rset_cl),
+- _worker_id(worker_id), _cm(_g1h->concurrent_mark()) { }
++ _g1h(g1h), _dcq(&g1h->dirty_card_queue_set()), _update_rset_cl(g1h, &_dcq),
++ _worker_id(worker_id), _cm(_g1h->concurrent_mark()) {
++ }
+
+ bool doHeapRegion(HeapRegion *hr) {
+ bool during_initial_mark = _g1h->g1_policy()->during_initial_mark_pause();
+@@ -177,20 +197,14 @@
+
+ if (hr->claimHeapRegion(HeapRegion::ParEvacFailureClaimValue)) {
+ if (hr->evacuation_failed()) {
+- RemoveSelfForwardPtrObjClosure rspc(_g1h, _cm, hr, _update_rset_cl,
++ RemoveSelfForwardPtrObjClosure rspc(_g1h, _cm, hr, &_update_rset_cl,
+ during_initial_mark,
+ during_conc_mark,
+ _worker_id);
+
+- MemRegion mr(hr->bottom(), hr->end());
+- // We'll recreate the prev marking info so we'll first clear
+- // the prev bitmap range for this region. We never mark any
+- // CSet objects explicitly so the next bitmap range should be
+- // cleared anyway.
+- _cm->clearRangePrevBitmap(mr);
+-
+ hr->note_self_forwarding_removal_start(during_initial_mark,
+ during_conc_mark);
++ _g1h->check_bitmaps("Self-Forwarding Ptr Removal", hr);
+
+ // In the common case (i.e. when there is no evacuation
+ // failure) we make sure that the following is done when
+@@ -202,9 +216,11 @@
+ // whenever this might be required in the future.
+ hr->rem_set()->reset_for_par_iteration();
+ hr->reset_bot();
+- _update_rset_cl->set_region(hr);
++ _update_rset_cl.set_region(hr);
+ hr->object_iterate(&rspc);
+
++ hr->rem_set()->clean_strong_code_roots(hr);
++
+ hr->note_self_forwarding_removal_end(during_initial_mark,
+ during_conc_mark,
+ rspc.marked_bytes());
+@@ -224,16 +240,7 @@
+ _g1h(g1h) { }
+
+ void work(uint worker_id) {
+- UpdateRSetImmediate immediate_update(_g1h->g1_rem_set());
+- DirtyCardQueue dcq(&_g1h->dirty_card_queue_set());
+- UpdateRSetDeferred deferred_update(_g1h, &dcq);
+-
+- OopsInHeapRegionClosure *update_rset_cl = &deferred_update;
+- if (!G1DeferredRSUpdate) {
+- update_rset_cl = &immediate_update;
+- }
+-
+- RemoveSelfForwardPtrHRClosure rsfp_cl(_g1h, update_rset_cl, worker_id);
++ RemoveSelfForwardPtrHRClosure rsfp_cl(_g1h, worker_id);
+
+ HeapRegion* hr = _g1h->start_cset_region_for_worker(worker_id);
+ _g1h->collection_set_iterate_from(hr, &rsfp_cl);
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -166,13 +166,14 @@
+ _last_update_rs_processed_buffers(_max_gc_threads, "%d"),
+ _last_scan_rs_times_ms(_max_gc_threads, "%.1lf"),
+ _last_strong_code_root_scan_times_ms(_max_gc_threads, "%.1lf"),
+- _last_strong_code_root_mark_times_ms(_max_gc_threads, "%.1lf"),
+ _last_obj_copy_times_ms(_max_gc_threads, "%.1lf"),
+ _last_termination_times_ms(_max_gc_threads, "%.1lf"),
+ _last_termination_attempts(_max_gc_threads, SIZE_FORMAT),
+ _last_gc_worker_end_times_ms(_max_gc_threads, "%.1lf", false),
+ _last_gc_worker_times_ms(_max_gc_threads, "%.1lf"),
+ _last_gc_worker_other_times_ms(_max_gc_threads, "%.1lf"),
++ _last_redirty_logged_cards_time_ms(_max_gc_threads, "%.1lf"),
++ _last_redirty_logged_cards_processed_cards(_max_gc_threads, SIZE_FORMAT),
+ _cur_string_dedup_queue_fixup_worker_times_ms(_max_gc_threads, "%.1lf"),
+ _cur_string_dedup_table_fixup_worker_times_ms(_max_gc_threads, "%.1lf")
+ {
+@@ -191,13 +192,16 @@
+ _last_update_rs_processed_buffers.reset();
+ _last_scan_rs_times_ms.reset();
+ _last_strong_code_root_scan_times_ms.reset();
+- _last_strong_code_root_mark_times_ms.reset();
+ _last_obj_copy_times_ms.reset();
+ _last_termination_times_ms.reset();
+ _last_termination_attempts.reset();
+ _last_gc_worker_end_times_ms.reset();
+ _last_gc_worker_times_ms.reset();
+ _last_gc_worker_other_times_ms.reset();
++
++ _last_redirty_logged_cards_time_ms.reset();
++ _last_redirty_logged_cards_processed_cards.reset();
++
+ }
+
+ void G1GCPhaseTimes::note_gc_end() {
+@@ -208,7 +212,6 @@
+ _last_update_rs_processed_buffers.verify();
+ _last_scan_rs_times_ms.verify();
+ _last_strong_code_root_scan_times_ms.verify();
+- _last_strong_code_root_mark_times_ms.verify();
+ _last_obj_copy_times_ms.verify();
+ _last_termination_times_ms.verify();
+ _last_termination_attempts.verify();
+@@ -223,7 +226,6 @@
+ _last_update_rs_times_ms.get(i) +
+ _last_scan_rs_times_ms.get(i) +
+ _last_strong_code_root_scan_times_ms.get(i) +
+- _last_strong_code_root_mark_times_ms.get(i) +
+ _last_obj_copy_times_ms.get(i) +
+ _last_termination_times_ms.get(i);
+
+@@ -233,6 +235,9 @@
+
+ _last_gc_worker_times_ms.verify();
+ _last_gc_worker_other_times_ms.verify();
++
++ _last_redirty_logged_cards_time_ms.verify();
++ _last_redirty_logged_cards_processed_cards.verify();
+ }
+
+ void G1GCPhaseTimes::note_string_dedup_fixup_start() {
+@@ -249,6 +254,10 @@
+ LineBuffer(level).append_and_print_cr("[%s: %.1lf ms]", str, value);
+ }
+
++void G1GCPhaseTimes::print_stats(int level, const char* str, size_t value) {
++ LineBuffer(level).append_and_print_cr("[%s: "SIZE_FORMAT"]", str, value);
++}
++
+ void G1GCPhaseTimes::print_stats(int level, const char* str, double value, uint workers) {
+ LineBuffer(level).append_and_print_cr("[%s: %.1lf ms, GC Workers: " UINT32_FORMAT "]", str, value, workers);
+ }
+@@ -263,9 +272,6 @@
+ // Now subtract the time taken to fix up roots in generated code
+ misc_time_ms += _cur_collection_code_root_fixup_time_ms;
+
+- // Strong code root migration time
+- misc_time_ms += _cur_strong_code_root_migration_time_ms;
+-
+ // Strong code root purge time
+ misc_time_ms += _cur_strong_code_root_purge_time_ms;
+
+@@ -292,9 +298,6 @@
+ if (_last_satb_filtering_times_ms.sum() > 0.0) {
+ _last_satb_filtering_times_ms.print(2, "SATB Filtering (ms)");
+ }
+- if (_last_strong_code_root_mark_times_ms.sum() > 0.0) {
+- _last_strong_code_root_mark_times_ms.print(2, "Code Root Marking (ms)");
+- }
+ _last_update_rs_times_ms.print(2, "Update RS (ms)");
+ _last_update_rs_processed_buffers.print(3, "Processed Buffers");
+ _last_scan_rs_times_ms.print(2, "Scan RS (ms)");
+@@ -312,9 +315,6 @@
+ if (_last_satb_filtering_times_ms.sum() > 0.0) {
+ _last_satb_filtering_times_ms.print(1, "SATB Filtering (ms)");
+ }
+- if (_last_strong_code_root_mark_times_ms.sum() > 0.0) {
+- _last_strong_code_root_mark_times_ms.print(1, "Code Root Marking (ms)");
+- }
+ _last_update_rs_times_ms.print(1, "Update RS (ms)");
+ _last_update_rs_processed_buffers.print(2, "Processed Buffers");
+ _last_scan_rs_times_ms.print(1, "Scan RS (ms)");
+@@ -322,7 +322,6 @@
+ _last_obj_copy_times_ms.print(1, "Object Copy (ms)");
+ }
+ print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
+- print_stats(1, "Code Root Migration", _cur_strong_code_root_migration_time_ms);
+ print_stats(1, "Code Root Purge", _cur_strong_code_root_purge_time_ms);
+ if (G1StringDedup::is_enabled()) {
+ print_stats(1, "String Dedup Fixup", _cur_string_dedup_fixup_time_ms, _active_gc_threads);
+@@ -350,8 +349,18 @@
+ _recorded_non_young_cset_choice_time_ms));
+ print_stats(2, "Ref Proc", _cur_ref_proc_time_ms);
+ print_stats(2, "Ref Enq", _cur_ref_enq_time_ms);
+- if (G1DeferredRSUpdate) {
+- print_stats(2, "Redirty Cards", _recorded_redirty_logged_cards_time_ms);
++ print_stats(2, "Redirty Cards", _recorded_redirty_logged_cards_time_ms);
++ if (G1Log::finest()) {
++ _last_redirty_logged_cards_time_ms.print(3, "Parallel Redirty");
++ _last_redirty_logged_cards_processed_cards.print(3, "Redirtied Cards");
++ }
++ if (G1ReclaimDeadHumongousObjectsAtYoungGC) {
++ print_stats(2, "Humongous Reclaim", _cur_fast_reclaim_humongous_time_ms);
++ if (G1Log::finest()) {
++ print_stats(3, "Humongous Total", _cur_fast_reclaim_humongous_total);
++ print_stats(3, "Humongous Candidate", _cur_fast_reclaim_humongous_candidates);
++ print_stats(3, "Humongous Reclaimed", _cur_fast_reclaim_humongous_reclaimed);
++ }
+ }
+ print_stats(2, "Free CSet",
+ (_recorded_young_free_cset_time_ms +
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -120,7 +120,6 @@
+ WorkerDataArray<int> _last_update_rs_processed_buffers;
+ WorkerDataArray<double> _last_scan_rs_times_ms;
+ WorkerDataArray<double> _last_strong_code_root_scan_times_ms;
+- WorkerDataArray<double> _last_strong_code_root_mark_times_ms;
+ WorkerDataArray<double> _last_obj_copy_times_ms;
+ WorkerDataArray<double> _last_termination_times_ms;
+ WorkerDataArray<size_t> _last_termination_attempts;
+@@ -130,7 +129,6 @@
+
+ double _cur_collection_par_time_ms;
+ double _cur_collection_code_root_fixup_time_ms;
+- double _cur_strong_code_root_migration_time_ms;
+ double _cur_strong_code_root_purge_time_ms;
+
+ double _cur_evac_fail_recalc_used;
+@@ -151,16 +149,24 @@
+ double _recorded_young_cset_choice_time_ms;
+ double _recorded_non_young_cset_choice_time_ms;
+
++ WorkerDataArray<double> _last_redirty_logged_cards_time_ms;
++ WorkerDataArray<size_t> _last_redirty_logged_cards_processed_cards;
+ double _recorded_redirty_logged_cards_time_ms;
+
+ double _recorded_young_free_cset_time_ms;
+ double _recorded_non_young_free_cset_time_ms;
+
++ double _cur_fast_reclaim_humongous_time_ms;
++ size_t _cur_fast_reclaim_humongous_total;
++ size_t _cur_fast_reclaim_humongous_candidates;
++ size_t _cur_fast_reclaim_humongous_reclaimed;
++
+ double _cur_verify_before_time_ms;
+ double _cur_verify_after_time_ms;
+
+ // Helper methods for detailed logging
+ void print_stats(int level, const char* str, double value);
++ void print_stats(int level, const char* str, size_t value);
+ void print_stats(int level, const char* str, double value, uint workers);
+
+ public:
+@@ -197,10 +203,6 @@
+ _last_strong_code_root_scan_times_ms.set(worker_i, ms);
+ }
+
+- void record_strong_code_root_mark_time(uint worker_i, double ms) {
+- _last_strong_code_root_mark_times_ms.set(worker_i, ms);
+- }
+-
+ void record_obj_copy_time(uint worker_i, double ms) {
+ _last_obj_copy_times_ms.set(worker_i, ms);
+ }
+@@ -230,10 +232,6 @@
+ _cur_collection_code_root_fixup_time_ms = ms;
+ }
+
+- void record_strong_code_root_migration_time(double ms) {
+- _cur_strong_code_root_migration_time_ms = ms;
+- }
+-
+ void record_strong_code_root_purge_time(double ms) {
+ _cur_strong_code_root_purge_time_ms = ms;
+ }
+@@ -285,6 +283,16 @@
+ _recorded_non_young_free_cset_time_ms = time_ms;
+ }
+
++ void record_fast_reclaim_humongous_stats(size_t total, size_t candidates) {
++ _cur_fast_reclaim_humongous_total = total;
++ _cur_fast_reclaim_humongous_candidates = candidates;
++ }
++
++ void record_fast_reclaim_humongous_time_ms(double value, size_t reclaimed) {
++ _cur_fast_reclaim_humongous_time_ms = value;
++ _cur_fast_reclaim_humongous_reclaimed = reclaimed;
++ }
++
+ void record_young_cset_choice_time_ms(double time_ms) {
+ _recorded_young_cset_choice_time_ms = time_ms;
+ }
+@@ -293,6 +301,14 @@
+ _recorded_non_young_cset_choice_time_ms = time_ms;
+ }
+
++ void record_redirty_logged_cards_time_ms(uint worker_i, double time_ms) {
++ _last_redirty_logged_cards_time_ms.set(worker_i, time_ms);
++ }
++
++ void record_redirty_logged_cards_processed_cards(uint worker_i, size_t processed_buffers) {
++ _last_redirty_logged_cards_processed_cards.set(worker_i, processed_buffers);
++ }
++
+ void record_redirty_logged_cards_time_ms(double time_ms) {
+ _recorded_redirty_logged_cards_time_ms = time_ms;
+ }
+@@ -343,6 +359,10 @@
+ return _recorded_non_young_free_cset_time_ms;
+ }
+
++ double fast_reclaim_humongous_time_ms() {
++ return _cur_fast_reclaim_humongous_time_ms;
++ }
++
+ double average_last_update_rs_time() {
+ return _last_update_rs_times_ms.average();
+ }
+@@ -359,10 +379,6 @@
+ return _last_strong_code_root_scan_times_ms.average();
+ }
+
+- double average_last_strong_code_root_mark_time(){
+- return _last_strong_code_root_mark_times_ms.average();
+- }
+-
+ double average_last_obj_copy_time() {
+ return _last_obj_copy_times_ms.average();
+ }
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -27,13 +27,12 @@
+ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+ #include "gc_implementation/g1/g1HotCardCache.hpp"
+ #include "gc_implementation/g1/g1RemSet.hpp"
+-#include "gc_implementation/g1/heapRegion.hpp"
+ #include "runtime/atomic.hpp"
+
+ G1HotCardCache::G1HotCardCache(G1CollectedHeap *g1h):
+ _g1h(g1h), _hot_cache(NULL), _use_cache(false), _card_counts(g1h) {}
+
+-void G1HotCardCache::initialize() {
++void G1HotCardCache::initialize(G1RegionToSpaceMapper* card_counts_storage) {
+ if (default_use_cache()) {
+ _use_cache = true;
+
+@@ -49,7 +48,7 @@
+ _hot_cache_par_chunk_size = MAX2(1, _hot_cache_size / (int)n_workers);
+ _hot_cache_par_claimed_idx = 0;
+
+- _card_counts.initialize();
++ _card_counts.initialize(card_counts_storage);
+ }
+ }
+
+@@ -135,10 +134,6 @@
+ // above, are discarded prior to re-enabling the cache near the end of the GC.
+ }
+
+-void G1HotCardCache::resize_card_counts(size_t heap_capacity) {
+- _card_counts.resize(heap_capacity);
+-}
+-
+ void G1HotCardCache::reset_card_counts(HeapRegion* hr) {
+ _card_counts.clear_region(hr);
+ }
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -78,7 +78,7 @@
+ G1HotCardCache(G1CollectedHeap* g1h);
+ ~G1HotCardCache();
+
+- void initialize();
++ void initialize(G1RegionToSpaceMapper* card_counts_storage);
+
+ bool use_cache() { return _use_cache; }
+
+@@ -115,9 +115,6 @@
+
+ bool hot_cache_is_empty() { return _n_hot == 0; }
+
+- // Resizes the card counts table to match the given capacity
+- void resize_card_counts(size_t heap_capacity);
+-
+ // Zeros the values in the card counts table for entire committed heap
+ void reset_card_counts();
+
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -123,20 +123,20 @@
+ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
+ bool clear_all_softrefs) {
+ // Recursively traverse all live objects and mark them
+- GCTraceTime tm("phase 1", G1Log::fine() && Verbose, true, gc_timer());
++ GCTraceTime tm("phase 1", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
+ GenMarkSweep::trace(" 1");
+
+ SharedHeap* sh = SharedHeap::heap();
+
+- // Need cleared claim bits for the strong roots processing
++ // Need cleared claim bits for the roots processing
+ ClassLoaderDataGraph::clear_claimed_marks();
+
+- sh->process_strong_roots(true, // activate StrongRootsScope
+- false, // not scavenging.
+- SharedHeap::SO_SystemClasses,
++ MarkingCodeBlobClosure follow_code_closure(&GenMarkSweep::follow_root_closure, !CodeBlobToOopClosure::FixRelocations);
++ sh->process_strong_roots(true, // activate StrongRootsScope
++ SharedHeap::SO_None,
+ &GenMarkSweep::follow_root_closure,
+- &GenMarkSweep::follow_code_root_closure,
+- &GenMarkSweep::follow_klass_closure);
++ &GenMarkSweep::follow_cld_closure,
++ &follow_code_closure);
+
+ // Process reference objects found during marking
+ ReferenceProcessor* rp = GenMarkSweep::ref_processor();
+@@ -148,7 +148,8 @@
+ &GenMarkSweep::keep_alive,
+ &GenMarkSweep::follow_stack_closure,
+ NULL,
+- gc_timer());
++ gc_timer(),
++ gc_tracer()->gc_id());
+ gc_tracer()->report_gc_reference_stats(stats);
+
+
+@@ -193,65 +194,6 @@
+ gc_tracer()->report_object_count_after_gc(&GenMarkSweep::is_alive);
+ }
+
+-class G1PrepareCompactClosure: public HeapRegionClosure {
+- G1CollectedHeap* _g1h;
+- ModRefBarrierSet* _mrbs;
+- CompactPoint _cp;
+- HeapRegionSetCount _humongous_regions_removed;
+-
+- void free_humongous_region(HeapRegion* hr) {
+- HeapWord* end = hr->end();
+- FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep");
+-
+- assert(hr->startsHumongous(),
+- "Only the start of a humongous region should be freed.");
+-
+- hr->set_containing_set(NULL);
+- _humongous_regions_removed.increment(1u, hr->capacity());
+-
+- _g1h->free_humongous_region(hr, &dummy_free_list, false /* par */);
+- hr->prepare_for_compaction(&_cp);
+- // Also clear the part of the card table that will be unused after
+- // compaction.
+- _mrbs->clear(MemRegion(hr->compaction_top(), end));
+- dummy_free_list.remove_all();
+- }
+-
+-public:
+- G1PrepareCompactClosure(CompactibleSpace* cs)
+- : _g1h(G1CollectedHeap::heap()),
+- _mrbs(_g1h->g1_barrier_set()),
+- _cp(NULL, cs, cs->initialize_threshold()),
+- _humongous_regions_removed() { }
+-
+- void update_sets() {
+- // We'll recalculate total used bytes and recreate the free list
+- // at the end of the GC, so no point in updating those values here.
+- HeapRegionSetCount empty_set;
+- _g1h->remove_from_old_sets(empty_set, _humongous_regions_removed);
+- }
+-
+- bool doHeapRegion(HeapRegion* hr) {
+- if (hr->isHumongous()) {
+- if (hr->startsHumongous()) {
+- oop obj = oop(hr->bottom());
+- if (obj->is_gc_marked()) {
+- obj->forward_to(obj);
+- } else {
+- free_humongous_region(hr);
+- }
+- } else {
+- assert(hr->continuesHumongous(), "Invalid humongous.");
+- }
+- } else {
+- hr->prepare_for_compaction(&_cp);
+- // Also clear the part of the card table that will be unused after
+- // compaction.
+- _mrbs->clear(MemRegion(hr->compaction_top(), hr->end()));
+- }
+- return false;
+- }
+-};
+
+ void G1MarkSweep::mark_sweep_phase2() {
+ // Now all live objects are marked, compute the new object addresses.
+@@ -260,21 +202,10 @@
+ // phase2, phase3 and phase4, but the ValidateMarkSweep live oops
+ // tracking expects us to do so. See comment under phase4.
+
+- G1CollectedHeap* g1h = G1CollectedHeap::heap();
+-
+- GCTraceTime tm("phase 2", G1Log::fine() && Verbose, true, gc_timer());
++ GCTraceTime tm("phase 2", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
+ GenMarkSweep::trace("2");
+
+- // find the first region
+- HeapRegion* r = g1h->region_at(0);
+- CompactibleSpace* sp = r;
+- if (r->isHumongous() && oop(r->bottom())->is_gc_marked()) {
+- sp = r->next_compaction_space();
+- }
+-
+- G1PrepareCompactClosure blk(sp);
+- g1h->heap_region_iterate(&blk);
+- blk.update_sets();
++ prepare_compaction();
+ }
+
+ class G1AdjustPointersClosure: public HeapRegionClosure {
+@@ -299,27 +230,27 @@
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+
+ // Adjust the pointers to reflect the new locations
+- GCTraceTime tm("phase 3", G1Log::fine() && Verbose, true, gc_timer());
++ GCTraceTime tm("phase 3", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
+ GenMarkSweep::trace("3");
+
+ SharedHeap* sh = SharedHeap::heap();
+
+- // Need cleared claim bits for the strong roots processing
++ // Need cleared claim bits for the roots processing
+ ClassLoaderDataGraph::clear_claimed_marks();
+
+- sh->process_strong_roots(true, // activate StrongRootsScope
+- false, // not scavenging.
+- SharedHeap::SO_AllClasses,
+- &GenMarkSweep::adjust_pointer_closure,
+- NULL, // do not touch code cache here
+- &GenMarkSweep::adjust_klass_closure);
++ CodeBlobToOopClosure adjust_code_closure(&GenMarkSweep::adjust_pointer_closure, CodeBlobToOopClosure::FixRelocations);
++ sh->process_all_roots(true, // activate StrongRootsScope
++ SharedHeap::SO_AllCodeCache,
++ &GenMarkSweep::adjust_pointer_closure,
++ &GenMarkSweep::adjust_cld_closure,
++ &adjust_code_closure);
+
+ assert(GenMarkSweep::ref_processor() == g1h->ref_processor_stw(), "Sanity");
+ g1h->ref_processor_stw()->weak_oops_do(&GenMarkSweep::adjust_pointer_closure);
+
+ // Now adjust pointers in remaining weak roots. (All of which should
+ // have been cleared if they pointed to non-surviving objects.)
+- g1h->g1_process_weak_roots(&GenMarkSweep::adjust_pointer_closure);
++ sh->process_weak_roots(&GenMarkSweep::adjust_pointer_closure);
+
+ if (G1StringDedup::is_enabled()) {
+ G1StringDedup::oops_do(&GenMarkSweep::adjust_pointer_closure);
+@@ -362,10 +293,75 @@
+ // to use a higher index (saved from phase2) when verifying perm_gen.
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+
+- GCTraceTime tm("phase 4", G1Log::fine() && Verbose, true, gc_timer());
++ GCTraceTime tm("phase 4", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
+ GenMarkSweep::trace("4");
+
+ G1SpaceCompactClosure blk;
+ g1h->heap_region_iterate(&blk);
+
+ }
++
++void G1MarkSweep::prepare_compaction_work(G1PrepareCompactClosure* blk) {
++ G1CollectedHeap* g1h = G1CollectedHeap::heap();
++ g1h->heap_region_iterate(blk);
++ blk->update_sets();
++}
++
++void G1PrepareCompactClosure::free_humongous_region(HeapRegion* hr) {
++ HeapWord* end = hr->end();
++ FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep");
++
++ assert(hr->startsHumongous(),
++ "Only the start of a humongous region should be freed.");
++
++ hr->set_containing_set(NULL);
++ _humongous_regions_removed.increment(1u, hr->capacity());
++
++ _g1h->free_humongous_region(hr, &dummy_free_list, false /* par */);
++ prepare_for_compaction(hr, end);
++ dummy_free_list.remove_all();
++}
++
++void G1PrepareCompactClosure::prepare_for_compaction(HeapRegion* hr, HeapWord* end) {
++ // If this is the first live region that we came across which we can compact,
++ // initialize the CompactPoint.
++ if (!is_cp_initialized()) {
++ _cp.space = hr;
++ _cp.threshold = hr->initialize_threshold();
++ }
++ prepare_for_compaction_work(&_cp, hr, end);
++}
++
++void G1PrepareCompactClosure::prepare_for_compaction_work(CompactPoint* cp,
++ HeapRegion* hr,
++ HeapWord* end) {
++ hr->prepare_for_compaction(cp);
++ // Also clear the part of the card table that will be unused after
++ // compaction.
++ _mrbs->clear(MemRegion(hr->compaction_top(), end));
++}
++
++void G1PrepareCompactClosure::update_sets() {
++ // We'll recalculate total used bytes and recreate the free list
++ // at the end of the GC, so no point in updating those values here.
++ HeapRegionSetCount empty_set;
++ _g1h->remove_from_old_sets(empty_set, _humongous_regions_removed);
++}
++
++bool G1PrepareCompactClosure::doHeapRegion(HeapRegion* hr) {
++ if (hr->isHumongous()) {
++ if (hr->startsHumongous()) {
++ oop obj = oop(hr->bottom());
++ if (obj->is_gc_marked()) {
++ obj->forward_to(obj);
++ } else {
++ free_humongous_region(hr);
++ }
++ } else {
++ assert(hr->continuesHumongous(), "Invalid humongous.");
++ }
++ } else {
++ prepare_for_compaction(hr, hr->end());
++ }
++ return false;
++}
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -43,7 +43,7 @@
+ // compaction.
+ //
+ // Class unloading will only occur when a full gc is invoked.
+-
++class G1PrepareCompactClosure;
+
+ class G1MarkSweep : AllStatic {
+ friend class VM_G1MarkSweep;
+@@ -70,6 +70,30 @@
+ static void mark_sweep_phase4();
+
+ static void allocate_stacks();
++ static void prepare_compaction();
++ static void prepare_compaction_work(G1PrepareCompactClosure* blk);
++};
++
++class G1PrepareCompactClosure : public HeapRegionClosure {
++ protected:
++ G1CollectedHeap* _g1h;
++ ModRefBarrierSet* _mrbs;
++ CompactPoint _cp;
++ HeapRegionSetCount _humongous_regions_removed;
++
++ virtual void prepare_for_compaction(HeapRegion* hr, HeapWord* end);
++ void prepare_for_compaction_work(CompactPoint* cp, HeapRegion* hr, HeapWord* end);
++ void free_humongous_region(HeapRegion* hr);
++ bool is_cp_initialized() const { return _cp.space != NULL; }
++
++ public:
++ G1PrepareCompactClosure() :
++ _g1h(G1CollectedHeap::heap()),
++ _mrbs(_g1h->g1_barrier_set()),
++ _humongous_regions_removed() { }
++
++ void update_sets();
++ bool doHeapRegion(HeapRegion* hr);
+ };
+
+ #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1MARKSWEEP_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep_ext.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "gc_implementation/g1/g1MarkSweep.hpp"
++
++void G1MarkSweep::prepare_compaction() {
++ G1PrepareCompactClosure blk;
++ G1MarkSweep::prepare_compaction_work(&blk);
++}
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,7 +25,28 @@
+ #include "precompiled.hpp"
+ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+ #include "gc_implementation/g1/g1OopClosures.inline.hpp"
++#include "gc_implementation/g1/g1ParScanThreadState.hpp"
+
+ G1ParCopyHelper::G1ParCopyHelper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) :
+ G1ParClosureSuper(g1, par_scan_state), _scanned_klass(NULL),
+ _cm(_g1->concurrent_mark()) {}
++
++G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1) :
++ _g1(g1), _par_scan_state(NULL), _worker_id(UINT_MAX) { }
++
++G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) :
++ _g1(g1), _par_scan_state(NULL),
++ _worker_id(UINT_MAX) {
++ set_par_scan_thread_state(par_scan_state);
++}
++
++void G1ParClosureSuper::set_par_scan_thread_state(G1ParScanThreadState* par_scan_state) {
++ assert(_par_scan_state == NULL, "_par_scan_state must only be set once");
++ assert(par_scan_state != NULL, "Must set par_scan_state to non-NULL.");
++
++ _par_scan_state = par_scan_state;
++ _worker_id = par_scan_state->queue_num();
++
++ assert(_worker_id < MAX2((uint)ParallelGCThreads, 1u),
++ err_msg("The given worker id %u must be less than the number of threads %u", _worker_id, MAX2((uint)ParallelGCThreads, 1u)));
++}
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,6 +25,8 @@
+ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_HPP
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_HPP
+
++#include "memory/iterator.hpp"
++
+ class HeapRegion;
+ class G1CollectedHeap;
+ class G1RemSet;
+@@ -51,8 +53,13 @@
+ G1ParScanThreadState* _par_scan_state;
+ uint _worker_id;
+ public:
++ // Initializes the instance, leaving _par_scan_state uninitialized. Must be done
++ // later using the set_par_scan_thread_state() method.
++ G1ParClosureSuper(G1CollectedHeap* g1);
+ G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state);
+ bool apply_to_weak_ref_discovered_field() { return true; }
++
++ void set_par_scan_thread_state(G1ParScanThreadState* par_scan_state);
+ };
+
+ class G1ParPushHeapRSClosure : public G1ParClosureSuper {
+@@ -68,9 +75,8 @@
+
+ class G1ParScanClosure : public G1ParClosureSuper {
+ public:
+- G1ParScanClosure(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state, ReferenceProcessor* rp) :
+- G1ParClosureSuper(g1, par_scan_state)
+- {
++ G1ParScanClosure(G1CollectedHeap* g1, ReferenceProcessor* rp) :
++ G1ParClosureSuper(g1) {
+ assert(_ref_processor == NULL, "sanity");
+ _ref_processor = rp;
+ }
+@@ -102,7 +108,7 @@
+ template <class T> void do_klass_barrier(T* p, oop new_obj);
+ };
+
+-template <G1Barrier barrier, bool do_mark_object>
++template <G1Barrier barrier, G1Mark do_mark_object>
+ class G1ParCopyClosure : public G1ParCopyHelper {
+ private:
+ template <class T> void do_oop_work(T* p);
+@@ -117,19 +123,19 @@
+ template <class T> void do_oop_nv(T* p) { do_oop_work(p); }
+ virtual void do_oop(oop* p) { do_oop_nv(p); }
+ virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
++
++ G1CollectedHeap* g1() { return _g1; };
++ G1ParScanThreadState* pss() { return _par_scan_state; }
++ ReferenceProcessor* rp() { return _ref_processor; };
+ };
+
+-typedef G1ParCopyClosure<G1BarrierNone, false> G1ParScanExtRootClosure;
+-typedef G1ParCopyClosure<G1BarrierKlass, false> G1ParScanMetadataClosure;
+-
+-
+-typedef G1ParCopyClosure<G1BarrierNone, true> G1ParScanAndMarkExtRootClosure;
+-typedef G1ParCopyClosure<G1BarrierKlass, true> G1ParScanAndMarkMetadataClosure;
+-
++typedef G1ParCopyClosure<G1BarrierNone, G1MarkNone> G1ParScanExtRootClosure;
++typedef G1ParCopyClosure<G1BarrierNone, G1MarkFromRoot> G1ParScanAndMarkExtRootClosure;
++typedef G1ParCopyClosure<G1BarrierNone, G1MarkPromotedFromRoot> G1ParScanAndMarkWeakExtRootClosure;
+ // We use a separate closure to handle references during evacuation
+ // failure processing.
+
+-typedef G1ParCopyClosure<G1BarrierEvac, false> G1ParScanHeapEvacFailureClosure;
++typedef G1ParCopyClosure<G1BarrierEvac, G1MarkNone> G1ParScanHeapEvacFailureClosure;
+
+ class FilterIntoCSClosure: public ExtendedOopClosure {
+ G1CollectedHeap* _g1;
+@@ -160,10 +166,11 @@
+ };
+
+ // Closure for iterating over object fields during concurrent marking
+-class G1CMOopClosure : public ExtendedOopClosure {
++class G1CMOopClosure : public MetadataAwareOopClosure {
++protected:
++ ConcurrentMark* _cm;
+ private:
+ G1CollectedHeap* _g1h;
+- ConcurrentMark* _cm;
+ CMTask* _task;
+ public:
+ G1CMOopClosure(G1CollectedHeap* g1h, ConcurrentMark* cm, CMTask* task);
+@@ -173,7 +180,7 @@
+ };
+
+ // Closure to scan the root regions during concurrent marking
+-class G1RootRegionScanClosure : public ExtendedOopClosure {
++class G1RootRegionScanClosure : public MetadataAwareOopClosure {
+ private:
+ G1CollectedHeap* _g1h;
+ ConcurrentMark* _cm;
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,9 +28,12 @@
+ #include "gc_implementation/g1/concurrentMark.inline.hpp"
+ #include "gc_implementation/g1/g1CollectedHeap.hpp"
+ #include "gc_implementation/g1/g1OopClosures.hpp"
++#include "gc_implementation/g1/g1ParScanThreadState.inline.hpp"
+ #include "gc_implementation/g1/g1RemSet.hpp"
+ #include "gc_implementation/g1/g1RemSet.inline.hpp"
+ #include "gc_implementation/g1/heapRegionRemSet.hpp"
++#include "memory/iterator.inline.hpp"
++#include "runtime/prefetch.inline.hpp"
+
+ /*
+ * This really ought to be an inline function, but apparently the C++
+@@ -41,7 +44,7 @@
+ inline void FilterIntoCSClosure::do_oop_nv(T* p) {
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop) &&
+- _g1->obj_in_cs(oopDesc::decode_heap_oop_not_null(heap_oop))) {
++ _g1->is_in_cset_or_humongous(oopDesc::decode_heap_oop_not_null(heap_oop))) {
+ _oc->do_oop(p);
+ }
+ }
+@@ -64,7 +67,8 @@
+
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+- if (_g1->in_cset_fast_test(obj)) {
++ G1CollectedHeap::in_cset_state_t state = _g1->in_cset_state(obj);
++ if (state == G1CollectedHeap::InCSet) {
+ // We're not going to even bother checking whether the object is
+ // already forwarded or not, as this usually causes an immediate
+ // stall. We'll try to prefetch the object (for write, given that
+@@ -83,6 +87,9 @@
+
+ _par_scan_state->push_on_queue(p);
+ } else {
++ if (state == G1CollectedHeap::IsHumongous) {
++ _g1->set_humongous_is_live(obj);
++ }
+ _par_scan_state->update_rs(_from, p, _worker_id);
+ }
+ }
+@@ -94,22 +101,20 @@
+
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+- if (_g1->in_cset_fast_test(obj)) {
++ if (_g1->is_in_cset_or_humongous(obj)) {
+ Prefetch::write(obj->mark_addr(), 0);
+ Prefetch::read(obj->mark_addr(), (HeapWordSize*2));
+
+ // Place on the references queue
+ _par_scan_state->push_on_queue(p);
++ } else {
++ assert(!_g1->obj_in_cs(obj), "checking");
+ }
+ }
+ }
+
+ template <class T>
+ inline void G1CMOopClosure::do_oop_nv(T* p) {
+- assert(_g1h->is_in_g1_reserved((HeapWord*) p), "invariant");
+- assert(!_g1h->is_on_master_free_list(
+- _g1h->heap_region_containing((HeapWord*) p)), "invariant");
+-
+ oop obj = oopDesc::load_decode_heap_oop(p);
+ if (_cm->verbose_high()) {
+ gclog_or_tty->print_cr("[%u] we're looking at location "
+@@ -125,9 +130,7 @@
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+ HeapRegion* hr = _g1h->heap_region_containing((HeapWord*) obj);
+- if (hr != NULL) {
+- _cm->grayRoot(obj, obj->size(), _worker_id, hr);
+- }
++ _cm->grayRoot(obj, obj->size(), _worker_id, hr);
+ }
+ }
+
+@@ -154,57 +157,61 @@
+ template <class T>
+ inline void G1UpdateRSOrPushRefOopClosure::do_oop_nv(T* p) {
+ oop obj = oopDesc::load_decode_heap_oop(p);
++ if (obj == NULL) {
++ return;
++ }
+ #ifdef ASSERT
+ // can't do because of races
+ // assert(obj == NULL || obj->is_oop(), "expected an oop");
+
+ // Do the safe subset of is_oop
+- if (obj != NULL) {
+ #ifdef CHECK_UNHANDLED_OOPS
+- oopDesc* o = obj.obj();
++ oopDesc* o = obj.obj();
+ #else
+- oopDesc* o = obj;
++ oopDesc* o = obj;
+ #endif // CHECK_UNHANDLED_OOPS
+- assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned");
+- assert(Universe::heap()->is_in_reserved(obj), "must be in heap");
+- }
++ assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned");
++ assert(Universe::heap()->is_in_reserved(obj), "must be in heap");
+ #endif // ASSERT
+
+ assert(_from != NULL, "from region must be non-NULL");
+ assert(_from->is_in_reserved(p), "p is not in from");
+
+ HeapRegion* to = _g1->heap_region_containing(obj);
+- if (to != NULL && _from != to) {
+- // The _record_refs_into_cset flag is true during the RSet
+- // updating part of an evacuation pause. It is false at all
+- // other times:
+- // * rebuilding the rembered sets after a full GC
+- // * during concurrent refinement.
+- // * updating the remembered sets of regions in the collection
+- // set in the event of an evacuation failure (when deferred
+- // updates are enabled).
++ if (_from == to) {
++ // Normally this closure should only be called with cross-region references.
++ // But since Java threads are manipulating the references concurrently and we
++ // reload the values things may have changed.
++ return;
++ }
++ // The _record_refs_into_cset flag is true during the RSet
++ // updating part of an evacuation pause. It is false at all
++ // other times:
++ // * rebuilding the remembered sets after a full GC
++ // * during concurrent refinement.
++ // * updating the remembered sets of regions in the collection
++ // set in the event of an evacuation failure (when deferred
++ // updates are enabled).
+
+- if (_record_refs_into_cset && to->in_collection_set()) {
+- // We are recording references that point into the collection
+- // set and this particular reference does exactly that...
+- // If the referenced object has already been forwarded
+- // to itself, we are handling an evacuation failure and
+- // we have already visited/tried to copy this object
+- // there is no need to retry.
+- if (!self_forwarded(obj)) {
+- assert(_push_ref_cl != NULL, "should not be null");
+- // Push the reference in the refs queue of the G1ParScanThreadState
+- // instance for this worker thread.
+- _push_ref_cl->do_oop(p);
+- }
++ if (_record_refs_into_cset && to->in_collection_set()) {
++ // We are recording references that point into the collection
++ // set and this particular reference does exactly that...
++ // If the referenced object has already been forwarded
++ // to itself, we are handling an evacuation failure and
++ // we have already visited/tried to copy this object
++ // there is no need to retry.
++ if (!self_forwarded(obj)) {
++ assert(_push_ref_cl != NULL, "should not be null");
++ // Push the reference in the refs queue of the G1ParScanThreadState
++ // instance for this worker thread.
++ _push_ref_cl->do_oop(p);
++ }
+
+- // Deferred updates to the CSet are either discarded (in the normal case),
+- // or processed (if an evacuation failure occurs) at the end
+- // of the collection.
+- // See G1RemSet::cleanup_after_oops_into_collection_set_do().
+- return;
+- }
+-
++ // Deferred updates to the CSet are either discarded (in the normal case),
++ // or processed (if an evacuation failure occurs) at the end
++ // of the collection.
++ // See G1RemSet::cleanup_after_oops_into_collection_set_do().
++ } else {
+ // We either don't care about pushing references that point into the
+ // collection set (i.e. we're not during an evacuation pause) _or_
+ // the reference doesn't point into the collection set. Either way
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,181 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "gc_implementation/g1/g1PageBasedVirtualSpace.hpp"
++#include "oops/markOop.hpp"
++#include "oops/oop.inline.hpp"
++#include "services/memTracker.hpp"
++#ifdef TARGET_OS_FAMILY_linux
++# include "os_linux.inline.hpp"
++#endif
++#ifdef TARGET_OS_FAMILY_solaris
++# include "os_solaris.inline.hpp"
++#endif
++#ifdef TARGET_OS_FAMILY_windows
++# include "os_windows.inline.hpp"
++#endif
++#ifdef TARGET_OS_FAMILY_aix
++# include "os_aix.inline.hpp"
++#endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
++#include "utilities/bitMap.inline.hpp"
++
++G1PageBasedVirtualSpace::G1PageBasedVirtualSpace() : _low_boundary(NULL),
++ _high_boundary(NULL), _committed(), _page_size(0), _special(false),
++ _dirty(), _executable(false) {
++}
++
++bool G1PageBasedVirtualSpace::initialize_with_granularity(ReservedSpace rs, size_t page_size) {
++ if (!rs.is_reserved()) {
++ return false; // Allocation failed.
++ }
++ assert(_low_boundary == NULL, "VirtualSpace already initialized");
++ assert(page_size > 0, "Granularity must be non-zero.");
++
++ _low_boundary = rs.base();
++ _high_boundary = _low_boundary + rs.size();
++
++ _special = rs.special();
++ _executable = rs.executable();
++
++ _page_size = page_size;
++
++ assert(_committed.size() == 0, "virtual space initialized more than once");
++ uintx size_in_bits = rs.size() / page_size;
++ _committed.resize(size_in_bits, /* in_resource_area */ false);
++ if (_special) {
++ _dirty.resize(size_in_bits, /* in_resource_area */ false);
++ }
++
++ return true;
++}
++
++
++G1PageBasedVirtualSpace::~G1PageBasedVirtualSpace() {
++ release();
++}
++
++void G1PageBasedVirtualSpace::release() {
++ // This does not release memory it never reserved.
++ // Caller must release via rs.release();
++ _low_boundary = NULL;
++ _high_boundary = NULL;
++ _special = false;
++ _executable = false;
++ _page_size = 0;
++ _committed.resize(0, false);
++ _dirty.resize(0, false);
++}
++
++size_t G1PageBasedVirtualSpace::committed_size() const {
++ return _committed.count_one_bits() * _page_size;
++}
++
++size_t G1PageBasedVirtualSpace::reserved_size() const {
++ return pointer_delta(_high_boundary, _low_boundary, sizeof(char));
++}
++
++size_t G1PageBasedVirtualSpace::uncommitted_size() const {
++ return reserved_size() - committed_size();
++}
++
++uintptr_t G1PageBasedVirtualSpace::addr_to_page_index(char* addr) const {
++ return (addr - _low_boundary) / _page_size;
++}
++
++bool G1PageBasedVirtualSpace::is_area_committed(uintptr_t start, size_t size_in_pages) const {
++ uintptr_t end = start + size_in_pages;
++ return _committed.get_next_zero_offset(start, end) >= end;
++}
++
++bool G1PageBasedVirtualSpace::is_area_uncommitted(uintptr_t start, size_t size_in_pages) const {
++ uintptr_t end = start + size_in_pages;
++ return _committed.get_next_one_offset(start, end) >= end;
++}
++
++char* G1PageBasedVirtualSpace::page_start(uintptr_t index) {
++ return _low_boundary + index * _page_size;
++}
++
++size_t G1PageBasedVirtualSpace::byte_size_for_pages(size_t num) {
++ return num * _page_size;
++}
++
++bool G1PageBasedVirtualSpace::commit(uintptr_t start, size_t size_in_pages) {
++ // We need to make sure to commit all pages covered by the given area.
++ guarantee(is_area_uncommitted(start, size_in_pages), "Specified area is not uncommitted");
++
++ bool zero_filled = true;
++ uintptr_t end = start + size_in_pages;
++
++ if (_special) {
++ // Check for dirty pages and update zero_filled if any found.
++ if (_dirty.get_next_one_offset(start,end) < end) {
++ zero_filled = false;
++ _dirty.clear_range(start, end);
++ }
++ } else {
++ os::commit_memory_or_exit(page_start(start), byte_size_for_pages(size_in_pages), _executable,
++ err_msg("Failed to commit pages from "SIZE_FORMAT" of length "SIZE_FORMAT, start, size_in_pages));
++ }
++ _committed.set_range(start, end);
++
++ return zero_filled;
++}
++
++void G1PageBasedVirtualSpace::uncommit(uintptr_t start, size_t size_in_pages) {
++ guarantee(is_area_committed(start, size_in_pages), "checking");
++
++ if (_special) {
++ // Mark that memory is dirty. If committed again the memory might
++ // need to be cleared explicitly.
++ _dirty.set_range(start, start + size_in_pages);
++ } else {
++ os::uncommit_memory(page_start(start), byte_size_for_pages(size_in_pages));
++ }
++
++ _committed.clear_range(start, start + size_in_pages);
++}
++
++bool G1PageBasedVirtualSpace::contains(const void* p) const {
++ return _low_boundary <= (const char*) p && (const char*) p < _high_boundary;
++}
++
++#ifndef PRODUCT
++void G1PageBasedVirtualSpace::print_on(outputStream* out) {
++ out->print ("Virtual space:");
++ if (_special) out->print(" (pinned in memory)");
++ out->cr();
++ out->print_cr(" - committed: " SIZE_FORMAT, committed_size());
++ out->print_cr(" - reserved: " SIZE_FORMAT, reserved_size());
++ out->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", p2i(_low_boundary), p2i(_high_boundary));
++}
++
++void G1PageBasedVirtualSpace::print() {
++ print_on(tty);
++}
++#endif
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,116 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1PAGEBASEDVIRTUALSPACE_HPP
++#define SHARE_VM_GC_IMPLEMENTATION_G1_G1PAGEBASEDVIRTUALSPACE_HPP
++
++#include "memory/allocation.hpp"
++#include "memory/memRegion.hpp"
++#include "runtime/virtualspace.hpp"
++#include "utilities/bitMap.hpp"
++
++// Virtual space management helper for a virtual space with an OS page allocation
++// granularity.
++// (De-)Allocation requests are always OS page aligned by passing a page index
++// and multiples of pages.
++// The implementation gives an error when trying to commit or uncommit pages that
++// have already been committed or uncommitted.
++class G1PageBasedVirtualSpace VALUE_OBJ_CLASS_SPEC {
++ friend class VMStructs;
++ private:
++ // Reserved area addresses.
++ char* _low_boundary;
++ char* _high_boundary;
++
++ // The commit/uncommit granularity in bytes.
++ size_t _page_size;
++
++ // Bitmap used for verification of commit/uncommit operations.
++ BitMap _committed;
++
++ // Bitmap used to keep track of which pages are dirty or not for _special
++ // spaces. This is needed because for those spaces the underlying memory
++ // will only be zero filled the first time it is committed. Calls to commit
++ // will use this bitmap and return whether or not the memory is zero filled.
++ BitMap _dirty;
++
++ // Indicates that the entire space has been committed and pinned in memory,
++ // os::commit_memory() or os::uncommit_memory() have no function.
++ bool _special;
++
++ // Indicates whether the committed space should be executable.
++ bool _executable;
++
++ // Returns the index of the page which contains the given address.
++ uintptr_t addr_to_page_index(char* addr) const;
++ // Returns the address of the given page index.
++ char* page_start(uintptr_t index);
++ // Returns the byte size of the given number of pages.
++ size_t byte_size_for_pages(size_t num);
++
++ // Returns true if the entire area is backed by committed memory.
++ bool is_area_committed(uintptr_t start, size_t size_in_pages) const;
++ // Returns true if the entire area is not backed by committed memory.
++ bool is_area_uncommitted(uintptr_t start, size_t size_in_pages) const;
++
++ public:
++
++ // Commit the given area of pages starting at start being size_in_pages large.
++ // Returns true if the given area is zero filled upon completion.
++ bool commit(uintptr_t start, size_t size_in_pages);
++
++ // Uncommit the given area of pages starting at start being size_in_pages large.
++ void uncommit(uintptr_t start, size_t size_in_pages);
++
++ // Initialization
++ G1PageBasedVirtualSpace();
++ bool initialize_with_granularity(ReservedSpace rs, size_t page_size);
++
++ // Destruction
++ ~G1PageBasedVirtualSpace();
++
++ // Amount of reserved memory.
++ size_t reserved_size() const;
++ // Memory used in this virtual space.
++ size_t committed_size() const;
++ // Memory left to use/expand in this virtual space.
++ size_t uncommitted_size() const;
++
++ bool contains(const void* p) const;
++
++ MemRegion reserved() {
++ MemRegion x((HeapWord*)_low_boundary, reserved_size() / HeapWordSize);
++ return x;
++ }
++
++ void release();
++
++ void check_for_contiguity() PRODUCT_RETURN;
++
++ // Debugging
++ void print_on(outputStream* out) PRODUCT_RETURN;
++ void print();
++};
++
++#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1PAGEBASEDVIRTUALSPACE_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,253 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
++#include "gc_implementation/g1/g1OopClosures.inline.hpp"
++#include "gc_implementation/g1/g1ParScanThreadState.inline.hpp"
++#include "oops/oop.inline.hpp"
++#include "oops/oop.pcgc.inline.hpp"
++#include "runtime/prefetch.inline.hpp"
++
++G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp)
++ : _g1h(g1h),
++ _refs(g1h->task_queue(queue_num)),
++ _dcq(&g1h->dirty_card_queue_set()),
++ _ct_bs(g1h->g1_barrier_set()),
++ _g1_rem(g1h->g1_rem_set()),
++ _hash_seed(17), _queue_num(queue_num),
++ _term_attempts(0),
++ _age_table(false), _scanner(g1h, rp),
++ _strong_roots_time(0), _term_time(0) {
++ _scanner.set_par_scan_thread_state(this);
++ // we allocate G1YoungSurvRateNumRegions plus one entries, since
++ // we "sacrifice" entry 0 to keep track of surviving bytes for
++ // non-young regions (where the age is -1)
++ // We also add a few elements at the beginning and at the end in
++ // an attempt to eliminate cache contention
++ uint real_length = 1 + _g1h->g1_policy()->young_cset_region_length();
++ uint array_length = PADDING_ELEM_NUM +
++ real_length +
++ PADDING_ELEM_NUM;
++ _surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length, mtGC);
++ if (_surviving_young_words_base == NULL)
++ vm_exit_out_of_memory(array_length * sizeof(size_t), OOM_MALLOC_ERROR,
++ "Not enough space for young surv histo.");
++ _surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM;
++ memset(_surviving_young_words, 0, (size_t) real_length * sizeof(size_t));
++
++ _g1_par_allocator = G1ParGCAllocator::create_allocator(_g1h);
++
++ _start = os::elapsedTime();
++}
++
++G1ParScanThreadState::~G1ParScanThreadState() {
++ _g1_par_allocator->retire_alloc_buffers();
++ delete _g1_par_allocator;
++ FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC);
++}
++
++void
++G1ParScanThreadState::print_termination_stats_hdr(outputStream* const st)
++{
++ st->print_raw_cr("GC Termination Stats");
++ st->print_raw_cr(" elapsed --strong roots-- -------termination-------"
++ " ------waste (KiB)------");
++ st->print_raw_cr("thr ms ms % ms % attempts"
++ " total alloc undo");
++ st->print_raw_cr("--- --------- --------- ------ --------- ------ --------"
++ " ------- ------- -------");
++}
++
++void
++G1ParScanThreadState::print_termination_stats(int i,
++ outputStream* const st) const
++{
++ const double elapsed_ms = elapsed_time() * 1000.0;
++ const double s_roots_ms = strong_roots_time() * 1000.0;
++ const double term_ms = term_time() * 1000.0;
++ const size_t alloc_buffer_waste = _g1_par_allocator->alloc_buffer_waste();
++ const size_t undo_waste = _g1_par_allocator->undo_waste();
++ st->print_cr("%3d %9.2f %9.2f %6.2f "
++ "%9.2f %6.2f " SIZE_FORMAT_W(8) " "
++ SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7),
++ i, elapsed_ms, s_roots_ms, s_roots_ms * 100 / elapsed_ms,
++ term_ms, term_ms * 100 / elapsed_ms, term_attempts(),
++ (alloc_buffer_waste + undo_waste) * HeapWordSize / K,
++ alloc_buffer_waste * HeapWordSize / K,
++ undo_waste * HeapWordSize / K);
++}
++
++#ifdef ASSERT
++bool G1ParScanThreadState::verify_ref(narrowOop* ref) const {
++ assert(ref != NULL, "invariant");
++ assert(UseCompressedOops, "sanity");
++ assert(!has_partial_array_mask(ref), err_msg("ref=" PTR_FORMAT, p2i(ref)));
++ oop p = oopDesc::load_decode_heap_oop(ref);
++ assert(_g1h->is_in_g1_reserved(p),
++ err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, p2i(ref), p2i(p)));
++ return true;
++}
++
++bool G1ParScanThreadState::verify_ref(oop* ref) const {
++ assert(ref != NULL, "invariant");
++ if (has_partial_array_mask(ref)) {
++ // Must be in the collection set--it's already been copied.
++ oop p = clear_partial_array_mask(ref);
++ assert(_g1h->obj_in_cs(p),
++ err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, p2i(ref), p2i(p)));
++ } else {
++ oop p = oopDesc::load_decode_heap_oop(ref);
++ assert(_g1h->is_in_g1_reserved(p),
++ err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, p2i(ref), p2i(p)));
++ }
++ return true;
++}
++
++bool G1ParScanThreadState::verify_task(StarTask ref) const {
++ if (ref.is_narrow()) {
++ return verify_ref((narrowOop*) ref);
++ } else {
++ return verify_ref((oop*) ref);
++ }
++}
++#endif // ASSERT
++
++void G1ParScanThreadState::trim_queue() {
++ assert(_evac_failure_cl != NULL, "not set");
++
++ StarTask ref;
++ do {
++ // Drain the overflow stack first, so other threads can steal.
++ while (_refs->pop_overflow(ref)) {
++ dispatch_reference(ref);
++ }
++
++ while (_refs->pop_local(ref)) {
++ dispatch_reference(ref);
++ }
++ } while (!_refs->is_empty());
++}
++
++oop G1ParScanThreadState::copy_to_survivor_space(oop const old) {
++ size_t word_sz = old->size();
++ HeapRegion* from_region = _g1h->heap_region_containing_raw(old);
++ // +1 to make the -1 indexes valid...
++ int young_index = from_region->young_index_in_cset()+1;
++ assert( (from_region->is_young() && young_index > 0) ||
++ (!from_region->is_young() && young_index == 0), "invariant" );
++ G1CollectorPolicy* g1p = _g1h->g1_policy();
++ markOop m = old->mark();
++ int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age()
++ : m->age();
++ GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age,
++ word_sz);
++ AllocationContext_t context = from_region->allocation_context();
++ HeapWord* obj_ptr = _g1_par_allocator->allocate(alloc_purpose, word_sz, context);
++#ifndef PRODUCT
++ // Should this evacuation fail?
++ if (_g1h->evacuation_should_fail()) {
++ if (obj_ptr != NULL) {
++ _g1_par_allocator->undo_allocation(alloc_purpose, obj_ptr, word_sz, context);
++ obj_ptr = NULL;
++ }
++ }
++#endif // !PRODUCT
++
++ if (obj_ptr == NULL) {
++ // This will either forward-to-self, or detect that someone else has
++ // installed a forwarding pointer.
++ return _g1h->handle_evacuation_failure_par(this, old);
++ }
++
++ oop obj = oop(obj_ptr);
++
++ // We're going to allocate linearly, so might as well prefetch ahead.
++ Prefetch::write(obj_ptr, PrefetchCopyIntervalInBytes);
++
++ oop forward_ptr = old->forward_to_atomic(obj);
++ if (forward_ptr == NULL) {
++ Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz);
++
++ // alloc_purpose is just a hint to allocate() above, recheck the type of region
++ // we actually allocated from and update alloc_purpose accordingly
++ HeapRegion* to_region = _g1h->heap_region_containing_raw(obj_ptr);
++ alloc_purpose = to_region->is_young() ? GCAllocForSurvived : GCAllocForTenured;
++
++ if (g1p->track_object_age(alloc_purpose)) {
++ // We could simply do obj->incr_age(). However, this causes a
++ // performance issue. obj->incr_age() will first check whether
++ // the object has a displaced mark by checking its mark word;
++ // getting the mark word from the new location of the object
++ // stalls. So, given that we already have the mark word and we
++ // are about to install it anyway, it's better to increase the
++ // age on the mark word, when the object does not have a
++ // displaced mark word. We're not expecting many objects to have
++ // a displaced marked word, so that case is not optimized
++ // further (it could be...) and we simply call obj->incr_age().
++
++ if (m->has_displaced_mark_helper()) {
++ // in this case, we have to install the mark word first,
++ // otherwise obj looks to be forwarded (the old mark word,
++ // which contains the forward pointer, was copied)
++ obj->set_mark(m);
++ obj->incr_age();
++ } else {
++ m = m->incr_age();
++ obj->set_mark(m);
++ }
++ age_table()->add(obj, word_sz);
++ } else {
++ obj->set_mark(m);
++ }
++
++ if (G1StringDedup::is_enabled()) {
++ G1StringDedup::enqueue_from_evacuation(from_region->is_young(),
++ to_region->is_young(),
++ queue_num(),
++ obj);
++ }
++
++ size_t* surv_young_words = surviving_young_words();
++ surv_young_words[young_index] += word_sz;
++
++ if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) {
++ // We keep track of the next start index in the length field of
++ // the to-space object. The actual length can be found in the
++ // length field of the from-space object.
++ arrayOop(obj)->set_length(0);
++ oop* old_p = set_partial_array_mask(old);
++ push_on_queue(old_p);
++ } else {
++ // No point in using the slower heap_region_containing() method,
++ // given that we know obj is in the heap.
++ _scanner.set_region(_g1h->heap_region_containing_raw(obj));
++ obj->oop_iterate_backwards(&_scanner);
++ }
++ } else {
++ _g1_par_allocator->undo_allocation(alloc_purpose, obj_ptr, word_sz, context);
++ obj = forward_ptr;
++ }
++ return obj;
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,205 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1PARSCANTHREADSTATE_HPP
++#define SHARE_VM_GC_IMPLEMENTATION_G1_G1PARSCANTHREADSTATE_HPP
++
++#include "gc_implementation/g1/dirtyCardQueue.hpp"
++#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
++#include "gc_implementation/g1/g1CollectedHeap.hpp"
++#include "gc_implementation/g1/g1CollectorPolicy.hpp"
++#include "gc_implementation/g1/g1OopClosures.hpp"
++#include "gc_implementation/g1/g1RemSet.hpp"
++#include "gc_implementation/shared/ageTable.hpp"
++#include "memory/allocation.hpp"
++#include "oops/oop.hpp"
++
++class HeapRegion;
++class outputStream;
++
++class G1ParScanThreadState : public StackObj {
++ private:
++ G1CollectedHeap* _g1h;
++ RefToScanQueue* _refs;
++ DirtyCardQueue _dcq;
++ G1SATBCardTableModRefBS* _ct_bs;
++ G1RemSet* _g1_rem;
++
++ G1ParGCAllocator* _g1_par_allocator;
++
++ ageTable _age_table;
++
++ G1ParScanClosure _scanner;
++
++ size_t _alloc_buffer_waste;
++ size_t _undo_waste;
++
++ OopsInHeapRegionClosure* _evac_failure_cl;
++
++ int _hash_seed;
++ uint _queue_num;
++
++ size_t _term_attempts;
++
++ double _start;
++ double _start_strong_roots;
++ double _strong_roots_time;
++ double _start_term;
++ double _term_time;
++
++ // Map from young-age-index (0 == not young, 1 is youngest) to
++ // surviving words. base is what we get back from the malloc call
++ size_t* _surviving_young_words_base;
++ // this points into the array, as we use the first few entries for padding
++ size_t* _surviving_young_words;
++
++#define PADDING_ELEM_NUM (DEFAULT_CACHE_LINE_SIZE / sizeof(size_t))
++
++ void add_to_alloc_buffer_waste(size_t waste) { _alloc_buffer_waste += waste; }
++ void add_to_undo_waste(size_t waste) { _undo_waste += waste; }
++
++ DirtyCardQueue& dirty_card_queue() { return _dcq; }
++ G1SATBCardTableModRefBS* ctbs() { return _ct_bs; }
++
++ public:
++ G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp);
++ ~G1ParScanThreadState();
++
++ ageTable* age_table() { return &_age_table; }
++
++#ifdef ASSERT
++ bool queue_is_empty() const { return _refs->is_empty(); }
++
++ bool verify_ref(narrowOop* ref) const;
++ bool verify_ref(oop* ref) const;
++ bool verify_task(StarTask ref) const;
++#endif // ASSERT
++
++ template <class T> void push_on_queue(T* ref) {
++ assert(verify_ref(ref), "sanity");
++ _refs->push(ref);
++ }
++
++ template <class T> void update_rs(HeapRegion* from, T* p, int tid) {
++ // If the new value of the field points to the same region or
++ // is the to-space, we don't need to include it in the Rset updates.
++ if (!from->is_in_reserved(oopDesc::load_decode_heap_oop(p)) && !from->is_survivor()) {
++ size_t card_index = ctbs()->index_for(p);
++ // If the card hasn't been added to the buffer, do it.
++ if (ctbs()->mark_card_deferred(card_index)) {
++ dirty_card_queue().enqueue((jbyte*)ctbs()->byte_for_index(card_index));
++ }
++ }
++ }
++ public:
++
++ void set_evac_failure_closure(OopsInHeapRegionClosure* evac_failure_cl) {
++ _evac_failure_cl = evac_failure_cl;
++ }
++
++ OopsInHeapRegionClosure* evac_failure_closure() { return _evac_failure_cl; }
++
++ int* hash_seed() { return &_hash_seed; }
++ uint queue_num() { return _queue_num; }
++
++ size_t term_attempts() const { return _term_attempts; }
++ void note_term_attempt() { _term_attempts++; }
++
++ void start_strong_roots() {
++ _start_strong_roots = os::elapsedTime();
++ }
++ void end_strong_roots() {
++ _strong_roots_time += (os::elapsedTime() - _start_strong_roots);
++ }
++ double strong_roots_time() const { return _strong_roots_time; }
++
++ void start_term_time() {
++ note_term_attempt();
++ _start_term = os::elapsedTime();
++ }
++ void end_term_time() {
++ _term_time += (os::elapsedTime() - _start_term);
++ }
++ double term_time() const { return _term_time; }
++
++ double elapsed_time() const {
++ return os::elapsedTime() - _start;
++ }
++
++ static void print_termination_stats_hdr(outputStream* const st = gclog_or_tty);
++ void print_termination_stats(int i, outputStream* const st = gclog_or_tty) const;
++
++ size_t* surviving_young_words() {
++ // We add on to hide entry 0 which accumulates surviving words for
++ // age -1 regions (i.e. non-young ones)
++ return _surviving_young_words;
++ }
++
++ private:
++ #define G1_PARTIAL_ARRAY_MASK 0x2
++
++ inline bool has_partial_array_mask(oop* ref) const {
++ return ((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) == G1_PARTIAL_ARRAY_MASK;
++ }
++
++ // We never encode partial array oops as narrowOop*, so return false immediately.
++ // This allows the compiler to create optimized code when popping references from
++ // the work queue.
++ inline bool has_partial_array_mask(narrowOop* ref) const {
++ assert(((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) != G1_PARTIAL_ARRAY_MASK, "Partial array oop reference encoded as narrowOop*");
++ return false;
++ }
++
++ // Only implement set_partial_array_mask() for regular oops, not for narrowOops.
++ // We always encode partial arrays as regular oop, to allow the
++ // specialization for has_partial_array_mask() for narrowOops above.
++ // This means that unintentional use of this method with narrowOops are caught
++ // by the compiler.
++ inline oop* set_partial_array_mask(oop obj) const {
++ assert(((uintptr_t)(void *)obj & G1_PARTIAL_ARRAY_MASK) == 0, "Information loss!");
++ return (oop*) ((uintptr_t)(void *)obj | G1_PARTIAL_ARRAY_MASK);
++ }
++
++ inline oop clear_partial_array_mask(oop* ref) const {
++ return cast_to_oop((intptr_t)ref & ~G1_PARTIAL_ARRAY_MASK);
++ }
++
++ inline void do_oop_partial_array(oop* p);
++
++ // This method is applied to the fields of the objects that have just been copied.
++ template <class T> inline void do_oop_evac(T* p, HeapRegion* from);
++
++ template <class T> inline void deal_with_reference(T* ref_to_scan);
++
++ inline void dispatch_reference(StarTask ref);
++ public:
++
++ oop copy_to_survivor_space(oop const obj);
++
++ void trim_queue();
++
++ inline void steal_and_trim_queue(RefToScanQueueSet *task_queues);
++};
++
++#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1PARSCANTHREADSTATE_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,145 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1PARSCANTHREADSTATE_INLINE_HPP
++#define SHARE_VM_GC_IMPLEMENTATION_G1_G1PARSCANTHREADSTATE_INLINE_HPP
++
++#include "gc_implementation/g1/g1ParScanThreadState.hpp"
++#include "gc_implementation/g1/g1RemSet.inline.hpp"
++#include "oops/oop.inline.hpp"
++
++template <class T> void G1ParScanThreadState::do_oop_evac(T* p, HeapRegion* from) {
++ assert(!oopDesc::is_null(oopDesc::load_decode_heap_oop(p)),
++ "Reference should not be NULL here as such are never pushed to the task queue.");
++ oop obj = oopDesc::load_decode_heap_oop_not_null(p);
++
++ // Although we never intentionally push references outside of the collection
++ // set, due to (benign) races in the claim mechanism during RSet scanning more
++ // than one thread might claim the same card. So the same card may be
++ // processed multiple times. So redo this check.
++ G1CollectedHeap::in_cset_state_t in_cset_state = _g1h->in_cset_state(obj);
++ if (in_cset_state == G1CollectedHeap::InCSet) {
++ oop forwardee;
++ if (obj->is_forwarded()) {
++ forwardee = obj->forwardee();
++ } else {
++ forwardee = copy_to_survivor_space(obj);
++ }
++ oopDesc::encode_store_heap_oop(p, forwardee);
++ } else if (in_cset_state == G1CollectedHeap::IsHumongous) {
++ _g1h->set_humongous_is_live(obj);
++ } else {
++ assert(in_cset_state == G1CollectedHeap::InNeither,
++ err_msg("In_cset_state must be InNeither here, but is %d", in_cset_state));
++ }
++
++ assert(obj != NULL, "Must be");
++ update_rs(from, p, queue_num());
++}
++
++inline void G1ParScanThreadState::do_oop_partial_array(oop* p) {
++ assert(has_partial_array_mask(p), "invariant");
++ oop from_obj = clear_partial_array_mask(p);
++
++ assert(Universe::heap()->is_in_reserved(from_obj), "must be in heap.");
++ assert(from_obj->is_objArray(), "must be obj array");
++ objArrayOop from_obj_array = objArrayOop(from_obj);
++ // The from-space object contains the real length.
++ int length = from_obj_array->length();
++
++ assert(from_obj->is_forwarded(), "must be forwarded");
++ oop to_obj = from_obj->forwardee();
++ assert(from_obj != to_obj, "should not be chunking self-forwarded objects");
++ objArrayOop to_obj_array = objArrayOop(to_obj);
++ // We keep track of the next start index in the length field of the
++ // to-space object.
++ int next_index = to_obj_array->length();
++ assert(0 <= next_index && next_index < length,
++ err_msg("invariant, next index: %d, length: %d", next_index, length));
++
++ int start = next_index;
++ int end = length;
++ int remainder = end - start;
++ // We'll try not to push a range that's smaller than ParGCArrayScanChunk.
++ if (remainder > 2 * ParGCArrayScanChunk) {
++ end = start + ParGCArrayScanChunk;
++ to_obj_array->set_length(end);
++ // Push the remainder before we process the range in case another
++ // worker has run out of things to do and can steal it.
++ oop* from_obj_p = set_partial_array_mask(from_obj);
++ push_on_queue(from_obj_p);
++ } else {
++ assert(length == end, "sanity");
++ // We'll process the final range for this object. Restore the length
++ // so that the heap remains parsable in case of evacuation failure.
++ to_obj_array->set_length(end);
++ }
++ _scanner.set_region(_g1h->heap_region_containing_raw(to_obj));
++ // Process indexes [start,end). It will also process the header
++ // along with the first chunk (i.e., the chunk with start == 0).
++ // Note that at this point the length field of to_obj_array is not
++ // correct given that we are using it to keep track of the next
++ // start index. oop_iterate_range() (thankfully!) ignores the length
++ // field and only relies on the start / end parameters. It does
++ // however return the size of the object which will be incorrect. So
++ // we have to ignore it even if we wanted to use it.
++ to_obj_array->oop_iterate_range(&_scanner, start, end);
++}
++
++template <class T> inline void G1ParScanThreadState::deal_with_reference(T* ref_to_scan) {
++ if (!has_partial_array_mask(ref_to_scan)) {
++ // Note: we can use "raw" versions of "region_containing" because
++ // "obj_to_scan" is definitely in the heap, and is not in a
++ // humongous region.
++ HeapRegion* r = _g1h->heap_region_containing_raw(ref_to_scan);
++ do_oop_evac(ref_to_scan, r);
++ } else {
++ do_oop_partial_array((oop*)ref_to_scan);
++ }
++}
++
++inline void G1ParScanThreadState::dispatch_reference(StarTask ref) {
++ assert(verify_task(ref), "sanity");
++ if (ref.is_narrow()) {
++ deal_with_reference((narrowOop*)ref);
++ } else {
++ deal_with_reference((oop*)ref);
++ }
++}
++
++void G1ParScanThreadState::steal_and_trim_queue(RefToScanQueueSet *task_queues) {
++ StarTask stolen_task;
++ while (task_queues->steal(queue_num(), hash_seed(), stolen_task)) {
++ assert(verify_task(stolen_task), "sanity");
++ dispatch_reference(stolen_task);
++
++ // We've just processed a reference and we might have made
++ // available new entries on the queues. So we have to make sure
++ // we drain the queues as necessary.
++ trim_queue();
++ }
++}
++
++#endif /* SHARE_VM_GC_IMPLEMENTATION_G1_G1PARSCANTHREADSTATE_INLINE_HPP */
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,160 @@
++/*
++ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "gc_implementation/g1/g1BiasedArray.hpp"
++#include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
++#include "memory/allocation.inline.hpp"
++#include "runtime/virtualspace.hpp"
++#include "services/memTracker.hpp"
++#include "utilities/bitMap.inline.hpp"
++
++G1RegionToSpaceMapper::G1RegionToSpaceMapper(ReservedSpace rs,
++ size_t commit_granularity,
++ size_t region_granularity,
++ MemoryType type) :
++ _storage(),
++ _commit_granularity(commit_granularity),
++ _region_granularity(region_granularity),
++ _listener(NULL),
++ _commit_map() {
++ guarantee(is_power_of_2(commit_granularity), "must be");
++ guarantee(is_power_of_2(region_granularity), "must be");
++ _storage.initialize_with_granularity(rs, commit_granularity);
++
++ MemTracker::record_virtual_memory_type((address)rs.base(), type);
++}
++
++// G1RegionToSpaceMapper implementation where the region granularity is larger than
++// or the same as the commit granularity.
++// Basically, the space corresponding to one region region spans several OS pages.
++class G1RegionsLargerThanCommitSizeMapper : public G1RegionToSpaceMapper {
++ private:
++ size_t _pages_per_region;
++
++ public:
++ G1RegionsLargerThanCommitSizeMapper(ReservedSpace rs,
++ size_t os_commit_granularity,
++ size_t alloc_granularity,
++ size_t commit_factor,
++ MemoryType type) :
++ G1RegionToSpaceMapper(rs, os_commit_granularity, alloc_granularity, type),
++ _pages_per_region(alloc_granularity / (os_commit_granularity * commit_factor)) {
++
++ guarantee(alloc_granularity >= os_commit_granularity, "allocation granularity smaller than commit granularity");
++ _commit_map.resize(rs.size() * commit_factor / alloc_granularity, /* in_resource_area */ false);
++ }
++
++ virtual void commit_regions(uintptr_t start_idx, size_t num_regions) {
++ bool zero_filled = _storage.commit(start_idx * _pages_per_region, num_regions * _pages_per_region);
++ _commit_map.set_range(start_idx, start_idx + num_regions);
++ fire_on_commit(start_idx, num_regions, zero_filled);
++ }
++
++ virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) {
++ _storage.uncommit(start_idx * _pages_per_region, num_regions * _pages_per_region);
++ _commit_map.clear_range(start_idx, start_idx + num_regions);
++ }
++};
++
++// G1RegionToSpaceMapper implementation where the region granularity is smaller
++// than the commit granularity.
++// Basically, the contents of one OS page span several regions.
++class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper {
++ private:
++ class CommitRefcountArray : public G1BiasedMappedArray<uint> {
++ protected:
++ virtual uint default_value() const { return 0; }
++ };
++
++ size_t _regions_per_page;
++
++ CommitRefcountArray _refcounts;
++
++ uintptr_t region_idx_to_page_idx(uint region) const {
++ return region / _regions_per_page;
++ }
++
++ public:
++ G1RegionsSmallerThanCommitSizeMapper(ReservedSpace rs,
++ size_t os_commit_granularity,
++ size_t alloc_granularity,
++ size_t commit_factor,
++ MemoryType type) :
++ G1RegionToSpaceMapper(rs, os_commit_granularity, alloc_granularity, type),
++ _regions_per_page((os_commit_granularity * commit_factor) / alloc_granularity), _refcounts() {
++
++ guarantee((os_commit_granularity * commit_factor) >= alloc_granularity, "allocation granularity smaller than commit granularity");
++ _refcounts.initialize((HeapWord*)rs.base(), (HeapWord*)(rs.base() + rs.size()), os_commit_granularity);
++ _commit_map.resize(rs.size() * commit_factor / alloc_granularity, /* in_resource_area */ false);
++ }
++
++ virtual void commit_regions(uintptr_t start_idx, size_t num_regions) {
++ for (uintptr_t i = start_idx; i < start_idx + num_regions; i++) {
++ assert(!_commit_map.at(i), err_msg("Trying to commit storage at region "INTPTR_FORMAT" that is already committed", i));
++ uintptr_t idx = region_idx_to_page_idx(i);
++ uint old_refcount = _refcounts.get_by_index(idx);
++ bool zero_filled = false;
++ if (old_refcount == 0) {
++ zero_filled = _storage.commit(idx, 1);
++ }
++ _refcounts.set_by_index(idx, old_refcount + 1);
++ _commit_map.set_bit(i);
++ fire_on_commit(i, 1, zero_filled);
++ }
++ }
++
++ virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) {
++ for (uintptr_t i = start_idx; i < start_idx + num_regions; i++) {
++ assert(_commit_map.at(i), err_msg("Trying to uncommit storage at region "INTPTR_FORMAT" that is not committed", i));
++ uintptr_t idx = region_idx_to_page_idx(i);
++ uint old_refcount = _refcounts.get_by_index(idx);
++ assert(old_refcount > 0, "must be");
++ if (old_refcount == 1) {
++ _storage.uncommit(idx, 1);
++ }
++ _refcounts.set_by_index(idx, old_refcount - 1);
++ _commit_map.clear_bit(i);
++ }
++ }
++};
++
++void G1RegionToSpaceMapper::fire_on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
++ if (_listener != NULL) {
++ _listener->on_commit(start_idx, num_regions, zero_filled);
++ }
++}
++
++G1RegionToSpaceMapper* G1RegionToSpaceMapper::create_mapper(ReservedSpace rs,
++ size_t os_commit_granularity,
++ size_t region_granularity,
++ size_t commit_factor,
++ MemoryType type) {
++
++ if (region_granularity >= (os_commit_granularity * commit_factor)) {
++ return new G1RegionsLargerThanCommitSizeMapper(rs, os_commit_granularity, region_granularity, commit_factor, type);
++ } else {
++ return new G1RegionsSmallerThanCommitSizeMapper(rs, os_commit_granularity, region_granularity, commit_factor, type);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,85 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1REGIONTOSPACEMAPPER_HPP
++#define SHARE_VM_GC_IMPLEMENTATION_G1_G1REGIONTOSPACEMAPPER_HPP
++
++#include "gc_implementation/g1/g1PageBasedVirtualSpace.hpp"
++#include "memory/allocation.hpp"
++#include "utilities/debug.hpp"
++
++class G1MappingChangedListener VALUE_OBJ_CLASS_SPEC {
++ public:
++ // Fired after commit of the memory, i.e. the memory this listener is registered
++ // for can be accessed.
++ // Zero_filled indicates that the memory can be considered as filled with zero bytes
++ // when called.
++ virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled) = 0;
++};
++
++// Maps region based commit/uncommit requests to the underlying page sized virtual
++// space.
++class G1RegionToSpaceMapper : public CHeapObj<mtGC> {
++ private:
++ G1MappingChangedListener* _listener;
++ protected:
++ // Backing storage.
++ G1PageBasedVirtualSpace _storage;
++ size_t _commit_granularity;
++ size_t _region_granularity;
++ // Mapping management
++ BitMap _commit_map;
++
++ G1RegionToSpaceMapper(ReservedSpace rs, size_t commit_granularity, size_t region_granularity, MemoryType type);
++
++ void fire_on_commit(uint start_idx, size_t num_regions, bool zero_filled);
++ public:
++ MemRegion reserved() { return _storage.reserved(); }
++
++ void set_mapping_changed_listener(G1MappingChangedListener* listener) { _listener = listener; }
++
++ virtual ~G1RegionToSpaceMapper() {
++ _commit_map.resize(0, /* in_resource_area */ false);
++ }
++
++ bool is_committed(uintptr_t idx) const {
++ return _commit_map.at(idx);
++ }
++
++ virtual void commit_regions(uintptr_t start_idx, size_t num_regions = 1) = 0;
++ virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions = 1) = 0;
++
++ // Creates an appropriate G1RegionToSpaceMapper for the given parameters.
++ // The byte_translation_factor defines how many bytes in a region correspond to
++ // a single byte in the data structure this mapper is for.
++ // Eg. in the card table, this value corresponds to the size a single card
++ // table entry corresponds to.
++ static G1RegionToSpaceMapper* create_mapper(ReservedSpace rs,
++ size_t os_commit_granularity,
++ size_t region_granularity,
++ size_t byte_translation_factor,
++ MemoryType type);
++};
++
++#endif /* SHARE_VM_GC_IMPLEMENTATION_G1_G1REGIONTOSPACEMAPPER_HPP */
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -23,7 +23,6 @@
+ */
+
+ #include "precompiled.hpp"
+-#include "gc_implementation/g1/bufferingOopClosure.hpp"
+ #include "gc_implementation/g1/concurrentG1Refine.hpp"
+ #include "gc_implementation/g1/concurrentG1RefineThread.hpp"
+ #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
+@@ -33,7 +32,7 @@
+ #include "gc_implementation/g1/g1GCPhaseTimes.hpp"
+ #include "gc_implementation/g1/g1OopClosures.inline.hpp"
+ #include "gc_implementation/g1/g1RemSet.inline.hpp"
+-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
++#include "gc_implementation/g1/heapRegionManager.inline.hpp"
+ #include "gc_implementation/g1/heapRegionRemSet.hpp"
+ #include "memory/iterator.hpp"
+ #include "oops/oop.inline.hpp"
+@@ -110,7 +109,7 @@
+ G1CollectedHeap* _g1h;
+
+ OopsInHeapRegionClosure* _oc;
+- CodeBlobToOopClosure* _code_root_cl;
++ CodeBlobClosure* _code_root_cl;
+
+ G1BlockOffsetSharedArray* _bot_shared;
+ G1SATBCardTableModRefBS *_ct_bs;
+@@ -122,7 +121,7 @@
+
+ public:
+ ScanRSClosure(OopsInHeapRegionClosure* oc,
+- CodeBlobToOopClosure* code_root_cl,
++ CodeBlobClosure* code_root_cl,
+ uint worker_i) :
+ _oc(oc),
+ _code_root_cl(code_root_cl),
+@@ -212,7 +211,6 @@
+ #endif
+
+ HeapRegion* card_region = _g1h->heap_region_containing(card_start);
+- assert(card_region != NULL, "Yielding cards not in the heap?");
+ _cards++;
+
+ if (!card_region->is_on_dirty_cards_region_list()) {
+@@ -243,7 +241,7 @@
+ };
+
+ void G1RemSet::scanRS(OopsInHeapRegionClosure* oc,
+- CodeBlobToOopClosure* code_root_cl,
++ CodeBlobClosure* code_root_cl,
+ uint worker_i) {
+ double rs_time_start = os::elapsedTime();
+ HeapRegion *startRegion = _g1->start_cset_region_for_worker(worker_i);
+@@ -322,7 +320,7 @@
+ }
+
+ void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
+- CodeBlobToOopClosure* code_root_cl,
++ CodeBlobClosure* code_root_cl,
+ uint worker_i) {
+ #if CARD_REPEAT_HISTO
+ ct_freq_update_histo_and_reset();
+@@ -340,12 +338,8 @@
+ // are just discarded (there's no need to update the RSets of regions
+ // that were in the collection set - after the pause these regions
+ // are wholly 'free' of live objects. In the event of an evacuation
+- // failure the cards/buffers in this queue set are:
+- // * passed to the DirtyCardQueueSet that is used to manage deferred
+- // RSet updates, or
+- // * scanned for references that point into the collection set
+- // and the RSet of the corresponding region in the collection set
+- // is updated immediately.
++ // failure the cards/buffers in this queue set are passed to the
++ // DirtyCardQueueSet that is used to manage RSet updates
+ DirtyCardQueue into_cset_dcq(&_g1->into_cset_dirty_card_queue_set());
+
+ assert((ParallelGCThreads > 0) || worker_i == 0, "invariant");
+@@ -374,7 +368,6 @@
+
+ void G1RemSet::prepare_for_oops_into_collection_set_do() {
+ cleanupHRRS();
+- ConcurrentG1Refine* cg1r = _g1->concurrent_g1_refine();
+ _g1->set_refine_cte_cl_concurrency(false);
+ DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+ dcqs.concatenate_logs();
+@@ -387,67 +380,6 @@
+ _total_cards_scanned = 0;
+ }
+
+-
+-// This closure, applied to a DirtyCardQueueSet, is used to immediately
+-// update the RSets for the regions in the CSet. For each card it iterates
+-// through the oops which coincide with that card. It scans the reference
+-// fields in each oop; when it finds an oop that points into the collection
+-// set, the RSet for the region containing the referenced object is updated.
+-class UpdateRSetCardTableEntryIntoCSetClosure: public CardTableEntryClosure {
+- G1CollectedHeap* _g1;
+- CardTableModRefBS* _ct_bs;
+-public:
+- UpdateRSetCardTableEntryIntoCSetClosure(G1CollectedHeap* g1,
+- CardTableModRefBS* bs):
+- _g1(g1), _ct_bs(bs)
+- { }
+-
+- bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
+- // Construct the region representing the card.
+- HeapWord* start = _ct_bs->addr_for(card_ptr);
+- // And find the region containing it.
+- HeapRegion* r = _g1->heap_region_containing(start);
+- assert(r != NULL, "unexpected null");
+-
+- // Scan oops in the card looking for references into the collection set
+- // Don't use addr_for(card_ptr + 1) which can ask for
+- // a card beyond the heap. This is not safe without a perm
+- // gen.
+- HeapWord* end = start + CardTableModRefBS::card_size_in_words;
+- MemRegion scanRegion(start, end);
+-
+- UpdateRSetImmediate update_rs_cl(_g1->g1_rem_set());
+- FilterIntoCSClosure update_rs_cset_oop_cl(NULL, _g1, &update_rs_cl);
+- FilterOutOfRegionClosure filter_then_update_rs_cset_oop_cl(r, &update_rs_cset_oop_cl);
+-
+- // We can pass false as the "filter_young" parameter here as:
+- // * we should be in a STW pause,
+- // * the DCQS to which this closure is applied is used to hold
+- // references that point into the collection set from the prior
+- // RSet updating,
+- // * the post-write barrier shouldn't be logging updates to young
+- // regions (but there is a situation where this can happen - see
+- // the comment in G1RemSet::refine_card() below -
+- // that should not be applicable here), and
+- // * during actual RSet updating, the filtering of cards in young
+- // regions in HeapRegion::oops_on_card_seq_iterate_careful is
+- // employed.
+- // As a result, when this closure is applied to "refs into cset"
+- // DCQS, we shouldn't see any cards in young regions.
+- update_rs_cl.set_region(r);
+- HeapWord* stop_point =
+- r->oops_on_card_seq_iterate_careful(scanRegion,
+- &filter_then_update_rs_cset_oop_cl,
+- false /* filter_young */,
+- NULL /* card_ptr */);
+-
+- // Since this is performed in the event of an evacuation failure, we
+- // we shouldn't see a non-null stop point
+- assert(stop_point == NULL, "saw an unallocated region");
+- return true;
+- }
+-};
+-
+ void G1RemSet::cleanup_after_oops_into_collection_set_do() {
+ guarantee( _cards_scanned != NULL, "invariant" );
+ _total_cards_scanned = 0;
+@@ -468,25 +400,10 @@
+ double restore_remembered_set_start = os::elapsedTime();
+
+ // Restore remembered sets for the regions pointing into the collection set.
+- if (G1DeferredRSUpdate) {
+- // If deferred RS updates are enabled then we just need to transfer
+- // the completed buffers from (a) the DirtyCardQueueSet used to hold
+- // cards that contain references that point into the collection set
+- // to (b) the DCQS used to hold the deferred RS updates
+- _g1->dirty_card_queue_set().merge_bufferlists(&into_cset_dcqs);
+- } else {
+-
+- CardTableModRefBS* bs = (CardTableModRefBS*)_g1->barrier_set();
+- UpdateRSetCardTableEntryIntoCSetClosure update_rs_cset_immediate(_g1, bs);
+-
+- int n_completed_buffers = 0;
+- while (into_cset_dcqs.apply_closure_to_completed_buffer(&update_rs_cset_immediate,
+- 0, 0, true)) {
+- n_completed_buffers++;
+- }
+- assert(n_completed_buffers == into_cset_n_buffers, "missed some buffers");
+- }
+-
++ // We just need to transfer the completed buffers from the DirtyCardQueueSet
++ // used to hold cards that contain references that point into the collection set
++ // to the DCQS used to hold the deferred RS updates.
++ _g1->dirty_card_queue_set().merge_bufferlists(&into_cset_dcqs);
+ _g1->g1_policy()->phase_times()->record_evac_fail_restore_remsets((os::elapsedTime() - restore_remembered_set_start) * 1000.0);
+ }
+
+@@ -557,6 +474,12 @@
+
+ bool G1RemSet::refine_card(jbyte* card_ptr, uint worker_i,
+ bool check_for_refs_into_cset) {
++ assert(_g1->is_in_exact(_ct_bs->addr_for(card_ptr)),
++ err_msg("Card at "PTR_FORMAT" index "SIZE_FORMAT" representing heap at "PTR_FORMAT" (%u) must be in committed heap",
++ p2i(card_ptr),
++ _ct_bs->index_for(_ct_bs->addr_for(card_ptr)),
++ _ct_bs->addr_for(card_ptr),
++ _g1->addr_to_region(_ct_bs->addr_for(card_ptr))));
+
+ // If the card is no longer dirty, nothing to do.
+ if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
+@@ -569,11 +492,6 @@
+ HeapWord* start = _ct_bs->addr_for(card_ptr);
+ // And find the region containing it.
+ HeapRegion* r = _g1->heap_region_containing(start);
+- if (r == NULL) {
+- // Again no need to return that this card contains refs that
+- // point into the collection set.
+- return false; // Not in the G1 heap (might be in perm, for example.)
+- }
+
+ // Why do we have to check here whether a card is on a young region,
+ // given that we dirty young regions and, as a result, the
+@@ -626,10 +544,6 @@
+
+ start = _ct_bs->addr_for(card_ptr);
+ r = _g1->heap_region_containing(start);
+- if (r == NULL) {
+- // Not in the G1 heap
+- return false;
+- }
+
+ // Checking whether the region we got back from the cache
+ // is young here is inappropriate. The region could have been
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -96,7 +96,7 @@
+ // the "i" passed to the calling thread's work(i) function.
+ // In the sequential case this param will be ignored.
+ void oops_into_collection_set_do(OopsInHeapRegionClosure* blk,
+- CodeBlobToOopClosure* code_root_cl,
++ CodeBlobClosure* code_root_cl,
+ uint worker_i);
+
+ // Prepare for and cleanup after an oops_into_collection_set_do
+@@ -108,7 +108,7 @@
+ void cleanup_after_oops_into_collection_set_do();
+
+ void scanRS(OopsInHeapRegionClosure* oc,
+- CodeBlobToOopClosure* code_root_cl,
++ CodeBlobClosure* code_root_cl,
+ uint worker_i);
+
+ void updateRS(DirtyCardQueue* into_cset_dcq, uint worker_i);
+@@ -193,18 +193,4 @@
+ bool apply_to_weak_ref_discovered_field() { return true; }
+ };
+
+-class UpdateRSetImmediate: public OopsInHeapRegionClosure {
+-private:
+- G1RemSet* _g1_rem_set;
+-
+- template <class T> void do_oop_work(T* p);
+-public:
+- UpdateRSetImmediate(G1RemSet* rs) :
+- _g1_rem_set(rs) {}
+-
+- virtual void do_oop(narrowOop* p) { do_oop_work(p); }
+- virtual void do_oop( oop* p) { do_oop_work(p); }
+-};
+-
+-
+ #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_HPP
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,6 +26,7 @@
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_INLINE_HPP
+
+ #include "gc_implementation/g1/g1RemSet.hpp"
++#include "gc_implementation/g1/heapRegion.hpp"
+ #include "gc_implementation/g1/heapRegionRemSet.hpp"
+ #include "oops/oop.inline.hpp"
+
+@@ -45,26 +46,28 @@
+ template <class T>
+ inline void G1RemSet::par_write_ref(HeapRegion* from, T* p, int tid) {
+ oop obj = oopDesc::load_decode_heap_oop(p);
++ if (obj == NULL) {
++ return;
++ }
++
+ #ifdef ASSERT
+ // can't do because of races
+ // assert(obj == NULL || obj->is_oop(), "expected an oop");
+
+ // Do the safe subset of is_oop
+- if (obj != NULL) {
+ #ifdef CHECK_UNHANDLED_OOPS
+- oopDesc* o = obj.obj();
++ oopDesc* o = obj.obj();
+ #else
+- oopDesc* o = obj;
++ oopDesc* o = obj;
+ #endif // CHECK_UNHANDLED_OOPS
+- assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned");
+- assert(Universe::heap()->is_in_reserved(obj), "must be in heap");
+- }
++ assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned");
++ assert(Universe::heap()->is_in_reserved(obj), "must be in heap");
+ #endif // ASSERT
+
+ assert(from == NULL || from->is_in_reserved(p), "p is not in from");
+
+ HeapRegion* to = _g1->heap_region_containing(obj);
+- if (to != NULL && from != to) {
++ if (from != to) {
+ assert(to->rem_set() != NULL, "Need per-region 'into' remsets.");
+ to->rem_set()->add_reference(p, tid);
+ }
+@@ -76,13 +79,4 @@
+ _rs->par_write_ref(_from, p, _worker_i);
+ }
+
+-template <class T>
+-inline void UpdateRSetImmediate::do_oop_work(T* p) {
+- assert(_from->is_in_reserved(p), "paranoia");
+- T heap_oop = oopDesc::load_heap_oop(p);
+- if (!oopDesc::is_null(heap_oop) && !_from->is_survivor()) {
+- _g1_rem_set->par_write_ref(_from, p, 0);
+- }
+-}
+-
+ #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_INLINE_HPP
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -253,19 +253,22 @@
+ size_t occupied_cards = hrrs->occupied();
+ size_t code_root_mem_sz = hrrs->strong_code_roots_mem_size();
+ if (code_root_mem_sz > max_code_root_mem_sz()) {
++ _max_code_root_mem_sz = code_root_mem_sz;
+ _max_code_root_mem_sz_region = r;
+ }
+ size_t code_root_elems = hrrs->strong_code_roots_list_length();
+
+ RegionTypeCounter* current = NULL;
+- if (r->is_young()) {
++ if (r->is_free()) {
++ current = &_free;
++ } else if (r->is_young()) {
+ current = &_young;
+ } else if (r->isHumongous()) {
+ current = &_humonguous;
+- } else if (r->is_empty()) {
+- current = &_free;
++ } else if (r->is_old()) {
++ current = &_old;
+ } else {
+- current = &_old;
++ ShouldNotReachHere();
+ }
+ current->add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems);
+ _all.add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems);
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -23,10 +23,12 @@
+ */
+
+ #include "precompiled.hpp"
++#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+ #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
+ #include "gc_implementation/g1/heapRegion.hpp"
+ #include "gc_implementation/g1/satbQueue.hpp"
+ #include "runtime/mutexLocker.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/thread.inline.hpp"
+
+ G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap,
+@@ -36,7 +38,6 @@
+ _kind = G1SATBCT;
+ }
+
+-
+ void G1SATBCardTableModRefBS::enqueue(oop pre_val) {
+ // Nulls should have been already filtered.
+ assert(pre_val->is_oop(true), "Error");
+@@ -64,6 +65,17 @@
+ }
+ }
+
++void G1SATBCardTableModRefBS::write_ref_array_pre(oop* dst, int count, bool dest_uninitialized) {
++ if (!dest_uninitialized) {
++ write_ref_array_pre_work(dst, count);
++ }
++}
++void G1SATBCardTableModRefBS::write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized) {
++ if (!dest_uninitialized) {
++ write_ref_array_pre_work(dst, count);
++ }
++}
++
+ bool G1SATBCardTableModRefBS::mark_card_deferred(size_t card_index) {
+ jbyte val = _byte_map[card_index];
+ // It's already processed
+@@ -112,13 +124,53 @@
+ }
+ #endif
+
++void G1SATBCardTableLoggingModRefBSChangedListener::on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
++ // Default value for a clean card on the card table is -1. So we cannot take advantage of the zero_filled parameter.
++ MemRegion mr(G1CollectedHeap::heap()->bottom_addr_for_region(start_idx), num_regions * HeapRegion::GrainWords);
++ _card_table->clear(mr);
++}
++
+ G1SATBCardTableLoggingModRefBS::
+ G1SATBCardTableLoggingModRefBS(MemRegion whole_heap,
+ int max_covered_regions) :
+ G1SATBCardTableModRefBS(whole_heap, max_covered_regions),
+- _dcqs(JavaThread::dirty_card_queue_set())
++ _dcqs(JavaThread::dirty_card_queue_set()),
++ _listener()
+ {
+ _kind = G1SATBCTLogging;
++ _listener.set_card_table(this);
++}
++
++void G1SATBCardTableLoggingModRefBS::initialize(G1RegionToSpaceMapper* mapper) {
++ mapper->set_mapping_changed_listener(&_listener);
++
++ _byte_map_size = mapper->reserved().byte_size();
++
++ _guard_index = cards_required(_whole_heap.word_size()) - 1;
++ _last_valid_index = _guard_index - 1;
++
++ HeapWord* low_bound = _whole_heap.start();
++ HeapWord* high_bound = _whole_heap.end();
++
++ _cur_covered_regions = 1;
++ _covered[0] = _whole_heap;
++
++ _byte_map = (jbyte*) mapper->reserved().start();
++ byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift);
++ assert(byte_for(low_bound) == &_byte_map[0], "Checking start of map");
++ assert(byte_for(high_bound-1) <= &_byte_map[_last_valid_index], "Checking end of map");
++
++ if (TraceCardTableModRefBS) {
++ gclog_or_tty->print_cr("G1SATBCardTableModRefBS::G1SATBCardTableModRefBS: ");
++ gclog_or_tty->print_cr(" "
++ " &_byte_map[0]: " INTPTR_FORMAT
++ " &_byte_map[_last_valid_index]: " INTPTR_FORMAT,
++ p2i(&_byte_map[0]),
++ p2i(&_byte_map[_last_valid_index]));
++ gclog_or_tty->print_cr(" "
++ " byte_map_base: " INTPTR_FORMAT,
++ p2i(byte_map_base));
++ }
+ }
+
+ void
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,14 +25,14 @@
+ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1SATBCARDTABLEMODREFBS_HPP
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_G1SATBCARDTABLEMODREFBS_HPP
+
++#include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
+ #include "memory/cardTableModRefBS.hpp"
+ #include "memory/memRegion.hpp"
+ #include "oops/oop.inline.hpp"
+ #include "utilities/macros.hpp"
+
+-#if INCLUDE_ALL_GCS
+-
+ class DirtyCardQueueSet;
++class G1SATBCardTableLoggingModRefBS;
+
+ // This barrier is specialized to use a logging barrier to support
+ // snapshot-at-the-beginning marking.
+@@ -86,16 +86,8 @@
+ }
+
+ template <class T> void write_ref_array_pre_work(T* dst, int count);
+- virtual void write_ref_array_pre(oop* dst, int count, bool dest_uninitialized) {
+- if (!dest_uninitialized) {
+- write_ref_array_pre_work(dst, count);
+- }
+- }
+- virtual void write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized) {
+- if (!dest_uninitialized) {
+- write_ref_array_pre_work(dst, count);
+- }
+- }
++ virtual void write_ref_array_pre(oop* dst, int count, bool dest_uninitialized);
++ virtual void write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized);
+
+ /*
+ Claimed and deferred bits are used together in G1 during the evacuation
+@@ -134,18 +126,40 @@
+ jbyte val = _byte_map[card_index];
+ return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
+ }
++};
+
++class G1SATBCardTableLoggingModRefBSChangedListener : public G1MappingChangedListener {
++ private:
++ G1SATBCardTableLoggingModRefBS* _card_table;
++ public:
++ G1SATBCardTableLoggingModRefBSChangedListener() : _card_table(NULL) { }
++
++ void set_card_table(G1SATBCardTableLoggingModRefBS* card_table) { _card_table = card_table; }
++
++ virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled);
+ };
+
+ // Adds card-table logging to the post-barrier.
+ // Usual invariant: all dirty cards are logged in the DirtyCardQueueSet.
+ class G1SATBCardTableLoggingModRefBS: public G1SATBCardTableModRefBS {
++ friend class G1SATBCardTableLoggingModRefBSChangedListener;
+ private:
++ G1SATBCardTableLoggingModRefBSChangedListener _listener;
+ DirtyCardQueueSet& _dcqs;
+ public:
++ static size_t compute_size(size_t mem_region_size_in_words) {
++ size_t number_of_slots = (mem_region_size_in_words / card_size_in_words);
++ return ReservedSpace::allocation_align_size_up(number_of_slots);
++ }
++
+ G1SATBCardTableLoggingModRefBS(MemRegion whole_heap,
+ int max_covered_regions);
+
++ virtual void initialize() { }
++ virtual void initialize(G1RegionToSpaceMapper* mapper);
++
++ virtual void resize_covered_region(MemRegion new_region) { ShouldNotReachHere(); }
++
+ bool is_a(BarrierSet::Name bsn) {
+ return bsn == BarrierSet::G1SATBCTLogging ||
+ G1SATBCardTableModRefBS::is_a(bsn);
+@@ -162,11 +176,6 @@
+
+ void write_region_work(MemRegion mr) { invalidate(mr); }
+ void write_ref_array_work(MemRegion mr) { invalidate(mr); }
+-
+-
+ };
+
+-
+-#endif // INCLUDE_ALL_GCS
+-
+ #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1SATBCARDTABLEMODREFBS_HPP
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -77,38 +77,37 @@
+ break;
+ }
+
+- // Include this thread in safepoints
+- stsJoin();
++ {
++ // Include thread in safepoints
++ SuspendibleThreadSetJoiner sts;
+
+- stat.mark_exec();
++ stat.mark_exec();
+
+- // Process the queue
+- for (;;) {
+- oop java_string = G1StringDedupQueue::pop();
+- if (java_string == NULL) {
+- break;
++ // Process the queue
++ for (;;) {
++ oop java_string = G1StringDedupQueue::pop();
++ if (java_string == NULL) {
++ break;
++ }
++
++ G1StringDedupTable::deduplicate(java_string, stat);
++
++ // Safepoint this thread if needed
++ if (sts.should_yield()) {
++ stat.mark_block();
++ sts.yield();
++ stat.mark_unblock();
++ }
+ }
+
+- G1StringDedupTable::deduplicate(java_string, stat);
++ G1StringDedupTable::trim_entry_cache();
+
+- // Safepoint this thread if needed
+- if (stsShouldYield()) {
+- stat.mark_block();
+- stsYield(NULL);
+- stat.mark_unblock();
+- }
++ stat.mark_done();
++
++ // Print statistics
++ total_stat.add(stat);
++ print(gclog_or_tty, stat, total_stat);
+ }
+-
+- G1StringDedupTable::trim_entry_cache();
+-
+- stat.mark_done();
+-
+- // Print statistics
+- total_stat.add(stat);
+- print(gclog_or_tty, stat, total_stat);
+-
+- // Exclude this thread from safepoints
+- stsLeave();
+ }
+
+ terminate();
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -108,9 +108,6 @@
+ develop(bool, G1RSBarrierRegionFilter, true, \
+ "If true, generate region filtering code in RS barrier") \
+ \
+- develop(bool, G1DeferredRSUpdate, true, \
+- "If true, use deferred RS updates") \
+- \
+ develop(bool, G1RSLogCheckCardTable, false, \
+ "If true, verify that no dirty cards remain after RS log " \
+ "processing.") \
+@@ -273,21 +270,24 @@
+ "Percentage (0-100) of the heap size to use as default " \
+ " maximum young gen size.") \
+ \
+- experimental(uintx, G1MixedGCLiveThresholdPercent, 65, \
++ experimental(uintx, G1MixedGCLiveThresholdPercent, 85, \
+ "Threshold for regions to be considered for inclusion in the " \
+ "collection set of mixed GCs. " \
+ "Regions with live bytes exceeding this will not be collected.") \
+ \
+- product(uintx, G1HeapWastePercent, 10, \
++ product(uintx, G1HeapWastePercent, 5, \
+ "Amount of space, expressed as a percentage of the heap size, " \
+ "that G1 is willing not to collect to avoid expensive GCs.") \
+ \
+ product(uintx, G1MixedGCCountTarget, 8, \
+ "The target number of mixed GCs after a marking cycle.") \
+ \
+- experimental(uintx, G1CodeRootsChunkCacheKeepPercent, 10, \
+- "The amount of code root chunks that should be kept at most " \
+- "as percentage of already allocated.") \
++ experimental(bool, G1ReclaimDeadHumongousObjectsAtYoungGC, true, \
++ "Try to reclaim dead large objects at every young GC.") \
++ \
++ experimental(bool, G1TraceReclaimDeadHumongousObjectsAtYoungGC, false, \
++ "Print some information about large object liveness " \
++ "at every young GC.") \
+ \
+ experimental(uintx, G1OldCSetRegionThresholdPercent, 10, \
+ "An upper bound for the number of old CSet regions expressed " \
+@@ -325,11 +325,14 @@
+ "evacuation pauses") \
+ \
+ diagnostic(bool, G1VerifyRSetsDuringFullGC, false, \
+- "If true, perform verification of each heap region's " \
+- "remembered set when verifying the heap during a full GC.") \
++ "If true, perform verification of each heap region's " \
++ "remembered set when verifying the heap during a full GC.") \
+ \
+ diagnostic(bool, G1VerifyHeapRegionCodeRoots, false, \
+- "Verify the code root lists attached to each heap region.")
++ "Verify the code root lists attached to each heap region.") \
++ \
++ develop(bool, G1VerifyBitmaps, false, \
++ "Verifies the consistency of the marking bitmaps")
+
+ G1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG)
+
+--- ./hotspot/src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -30,14 +30,21 @@
+ // non-virtually, using a mechanism defined in this file. Extend these
+ // macros in the obvious way to add specializations for new closures.
+
+-// Forward declarations.
+ enum G1Barrier {
+ G1BarrierNone,
+ G1BarrierEvac,
+ G1BarrierKlass
+ };
+
+-template<G1Barrier barrier, bool do_mark_object>
++enum G1Mark {
++ G1MarkNone,
++ G1MarkFromRoot,
++ G1MarkPromotedFromRoot
++};
++
++// Forward declarations.
++
++template<G1Barrier barrier, G1Mark do_mark_object>
+ class G1ParCopyClosure;
+
+ class G1ParScanClosure;
+--- ./hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,11 +28,15 @@
+ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+ #include "gc_implementation/g1/g1OopClosures.inline.hpp"
+ #include "gc_implementation/g1/heapRegion.inline.hpp"
++#include "gc_implementation/g1/heapRegionBounds.inline.hpp"
+ #include "gc_implementation/g1/heapRegionRemSet.hpp"
+-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
++#include "gc_implementation/g1/heapRegionManager.inline.hpp"
++#include "gc_implementation/shared/liveRange.hpp"
+ #include "memory/genOopClosures.inline.hpp"
+ #include "memory/iterator.hpp"
++#include "memory/space.inline.hpp"
+ #include "oops/oop.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+
+ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+
+@@ -46,7 +50,7 @@
+ HeapRegion* hr, ExtendedOopClosure* cl,
+ CardTableModRefBS::PrecisionStyle precision,
+ FilterKind fk) :
+- ContiguousSpaceDCTOC(hr, cl, precision, NULL),
++ DirtyCardToOopClosure(hr, cl, precision, NULL),
+ _hr(hr), _fk(fk), _g1(g1) { }
+
+ FilterOutOfRegionClosure::FilterOutOfRegionClosure(HeapRegion* r,
+@@ -58,7 +62,7 @@
+ HeapRegion* hr,
+ HeapWord* cur, HeapWord* top) {
+ oop cur_oop = oop(cur);
+- int oop_size = cur_oop->size();
++ size_t oop_size = hr->block_size(cur);
+ HeapWord* next_obj = cur + oop_size;
+ while (next_obj < top) {
+ // Keep filtering the remembered set.
+@@ -69,25 +73,24 @@
+ }
+ cur = next_obj;
+ cur_oop = oop(cur);
+- oop_size = cur_oop->size();
++ oop_size = hr->block_size(cur);
+ next_obj = cur + oop_size;
+ }
+ return cur;
+ }
+
+-void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr,
+- HeapWord* bottom,
+- HeapWord* top,
+- ExtendedOopClosure* cl) {
++void HeapRegionDCTOC::walk_mem_region(MemRegion mr,
++ HeapWord* bottom,
++ HeapWord* top) {
+ G1CollectedHeap* g1h = _g1;
+- int oop_size;
++ size_t oop_size;
+ ExtendedOopClosure* cl2 = NULL;
+
+- FilterIntoCSClosure intoCSFilt(this, g1h, cl);
+- FilterOutOfRegionClosure outOfRegionFilt(_hr, cl);
++ FilterIntoCSClosure intoCSFilt(this, g1h, _cl);
++ FilterOutOfRegionClosure outOfRegionFilt(_hr, _cl);
+
+ switch (_fk) {
+- case NoFilterKind: cl2 = cl; break;
++ case NoFilterKind: cl2 = _cl; break;
+ case IntoCSFilterKind: cl2 = &intoCSFilt; break;
+ case OutOfRegionFilterKind: cl2 = &outOfRegionFilt; break;
+ default: ShouldNotReachHere();
+@@ -100,7 +103,7 @@
+ if (!g1h->is_obj_dead(oop(bottom), _hr)) {
+ oop_size = oop(bottom)->oop_iterate(cl2, mr);
+ } else {
+- oop_size = oop(bottom)->size();
++ oop_size = _hr->block_size(bottom);
+ }
+
+ bottom += oop_size;
+@@ -109,17 +112,17 @@
+ // We replicate the loop below for several kinds of possible filters.
+ switch (_fk) {
+ case NoFilterKind:
+- bottom = walk_mem_region_loop(cl, g1h, _hr, bottom, top);
++ bottom = walk_mem_region_loop(_cl, g1h, _hr, bottom, top);
+ break;
+
+ case IntoCSFilterKind: {
+- FilterIntoCSClosure filt(this, g1h, cl);
++ FilterIntoCSClosure filt(this, g1h, _cl);
+ bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top);
+ break;
+ }
+
+ case OutOfRegionFilterKind: {
+- FilterOutOfRegionClosure filt(_hr, cl);
++ FilterOutOfRegionClosure filt(_hr, _cl);
+ bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top);
+ break;
+ }
+@@ -135,32 +138,16 @@
+ }
+ }
+
+-// Minimum region size; we won't go lower than that.
+-// We might want to decrease this in the future, to deal with small
+-// heaps a bit more efficiently.
+-#define MIN_REGION_SIZE ( 1024 * 1024 )
+-
+-// Maximum region size; we don't go higher than that. There's a good
+-// reason for having an upper bound. We don't want regions to get too
+-// large, otherwise cleanup's effectiveness would decrease as there
+-// will be fewer opportunities to find totally empty regions after
+-// marking.
+-#define MAX_REGION_SIZE ( 32 * 1024 * 1024 )
+-
+-// The automatic region size calculation will try to have around this
+-// many regions in the heap (based on the min heap size).
+-#define TARGET_REGION_NUMBER 2048
+-
+ size_t HeapRegion::max_region_size() {
+- return (size_t)MAX_REGION_SIZE;
++ return HeapRegionBounds::max_size();
+ }
+
+ void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) {
+ uintx region_size = G1HeapRegionSize;
+ if (FLAG_IS_DEFAULT(G1HeapRegionSize)) {
+ size_t average_heap_size = (initial_heap_size + max_heap_size) / 2;
+- region_size = MAX2(average_heap_size / TARGET_REGION_NUMBER,
+- (uintx) MIN_REGION_SIZE);
++ region_size = MAX2(average_heap_size / HeapRegionBounds::target_number(),
++ (uintx) HeapRegionBounds::min_size());
+ }
+
+ int region_size_log = log2_long((jlong) region_size);
+@@ -170,10 +157,10 @@
+ region_size = ((uintx)1 << region_size_log);
+
+ // Now make sure that we don't go over or under our limits.
+- if (region_size < MIN_REGION_SIZE) {
+- region_size = MIN_REGION_SIZE;
+- } else if (region_size > MAX_REGION_SIZE) {
+- region_size = MAX_REGION_SIZE;
++ if (region_size < HeapRegionBounds::min_size()) {
++ region_size = HeapRegionBounds::min_size();
++ } else if (region_size > HeapRegionBounds::max_size()) {
++ region_size = HeapRegionBounds::max_size();
+ }
+
+ // And recalculate the log.
+@@ -208,8 +195,6 @@
+ }
+
+ void HeapRegion::hr_clear(bool par, bool clear_space, bool locked) {
+- assert(_humongous_type == NotHumongous,
+- "we should have already filtered out humongous regions");
+ assert(_humongous_start_region == NULL,
+ "we should have already filtered out humongous regions");
+ assert(_end == _orig_end,
+@@ -217,9 +202,10 @@
+
+ _in_collection_set = false;
+
++ set_allocation_context(AllocationContext::system());
+ set_young_index_in_cset(-1);
+ uninstall_surv_rate_group();
+- set_young_type(NotYoung);
++ set_free();
+ reset_pre_dummy_top();
+
+ if (!par) {
+@@ -270,7 +256,7 @@
+ assert(top() == bottom(), "should be empty");
+ assert(bottom() <= new_top && new_top <= new_end, "pre-condition");
+
+- _humongous_type = StartsHumongous;
++ _type.set_starts_humongous();
+ _humongous_start_region = this;
+
+ set_end(new_end);
+@@ -284,11 +270,11 @@
+ assert(top() == bottom(), "should be empty");
+ assert(first_hr->startsHumongous(), "pre-condition");
+
+- _humongous_type = ContinuesHumongous;
++ _type.set_continues_humongous();
+ _humongous_start_region = first_hr;
+ }
+
+-void HeapRegion::set_notHumongous() {
++void HeapRegion::clear_humongous() {
+ assert(isHumongous(), "pre-condition");
+
+ if (startsHumongous()) {
+@@ -304,7 +290,6 @@
+ }
+
+ assert(capacity() == HeapRegion::GrainBytes, "pre-condition");
+- _humongous_type = NotHumongous;
+ _humongous_start_region = NULL;
+ }
+
+@@ -319,46 +304,19 @@
+ return false;
+ }
+
+-HeapWord* HeapRegion::next_block_start_careful(HeapWord* addr) {
+- HeapWord* low = addr;
+- HeapWord* high = end();
+- while (low < high) {
+- size_t diff = pointer_delta(high, low);
+- // Must add one below to bias toward the high amount. Otherwise, if
+- // "high" were at the desired value, and "low" were one less, we
+- // would not converge on "high". This is not symmetric, because
+- // we set "high" to a block start, which might be the right one,
+- // which we don't do for "low".
+- HeapWord* middle = low + (diff+1)/2;
+- if (middle == high) return high;
+- HeapWord* mid_bs = block_start_careful(middle);
+- if (mid_bs < addr) {
+- low = middle;
+- } else {
+- high = mid_bs;
+- }
+- }
+- assert(low == high && low >= addr, "Didn't work.");
+- return low;
+-}
+-
+-#ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
+-#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
+-#endif // _MSC_VER
+-
+-
+-HeapRegion::HeapRegion(uint hrs_index,
++HeapRegion::HeapRegion(uint hrm_index,
+ G1BlockOffsetSharedArray* sharedOffsetArray,
+ MemRegion mr) :
+ G1OffsetTableContigSpace(sharedOffsetArray, mr),
+- _hrs_index(hrs_index),
+- _humongous_type(NotHumongous), _humongous_start_region(NULL),
++ _hrm_index(hrm_index),
++ _allocation_context(AllocationContext::system()),
++ _humongous_start_region(NULL),
+ _in_collection_set(false),
+ _next_in_special_set(NULL), _orig_end(NULL),
+ _claimed(InitialClaimValue), _evacuation_failed(false),
+ _prev_marked_bytes(0), _next_marked_bytes(0), _gc_efficiency(0.0),
+- _young_type(NotYoung), _next_young_region(NULL),
+- _next_dirty_cards_region(NULL), _next(NULL), _prev(NULL), _pending_removal(false),
++ _next_young_region(NULL),
++ _next_dirty_cards_region(NULL), _next(NULL), _prev(NULL),
+ #ifdef ASSERT
+ _containing_set(NULL),
+ #endif // ASSERT
+@@ -367,55 +325,24 @@
+ _predicted_bytes_to_copy(0)
+ {
+ _rem_set = new HeapRegionRemSet(sharedOffsetArray, this);
++ assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant.");
++
++ initialize(mr);
++}
++
++void HeapRegion::initialize(MemRegion mr, bool clear_space, bool mangle_space) {
++ assert(_rem_set->is_empty(), "Remembered set must be empty");
++
++ G1OffsetTableContigSpace::initialize(mr, clear_space, mangle_space);
++
+ _orig_end = mr.end();
+- // Note that initialize() will set the start of the unmarked area of the
+- // region.
+ hr_clear(false /*par*/, false /*clear_space*/);
+ set_top(bottom());
+- set_saved_mark();
+-
+- assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant.");
++ record_top_and_timestamp();
+ }
+
+ CompactibleSpace* HeapRegion::next_compaction_space() const {
+- // We're not using an iterator given that it will wrap around when
+- // it reaches the last region and this is not what we want here.
+- G1CollectedHeap* g1h = G1CollectedHeap::heap();
+- uint index = hrs_index() + 1;
+- while (index < g1h->n_regions()) {
+- HeapRegion* hr = g1h->region_at(index);
+- if (!hr->isHumongous()) {
+- return hr;
+- }
+- index += 1;
+- }
+- return NULL;
+-}
+-
+-void HeapRegion::save_marks() {
+- set_saved_mark();
+-}
+-
+-void HeapRegion::oops_in_mr_iterate(MemRegion mr, ExtendedOopClosure* cl) {
+- HeapWord* p = mr.start();
+- HeapWord* e = mr.end();
+- oop obj;
+- while (p < e) {
+- obj = oop(p);
+- p += obj->oop_iterate(cl);
+- }
+- assert(p == e, "bad memregion: doesn't end on obj boundary");
+-}
+-
+-#define HeapRegion_OOP_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix) \
+-void HeapRegion::oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl) { \
+- ContiguousSpace::oop_since_save_marks_iterate##nv_suffix(cl); \
+-}
+-SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(HeapRegion_OOP_SINCE_SAVE_MARKS_DEFN)
+-
+-
+-void HeapRegion::oop_before_save_marks_iterate(ExtendedOopClosure* cl) {
+- oops_in_mr_iterate(MemRegion(bottom(), saved_mark_word()), cl);
++ return G1CollectedHeap::heap()->next_compaction_region(this);
+ }
+
+ void HeapRegion::note_self_forwarding_removal_start(bool during_initial_mark,
+@@ -423,7 +350,6 @@
+ // We always recreate the prev marking info and we'll explicitly
+ // mark all objects we find to be self-forwarded on the prev
+ // bitmap. So all objects need to be below PTAMS.
+- _prev_top_at_mark_start = top();
+ _prev_marked_bytes = 0;
+
+ if (during_initial_mark) {
+@@ -447,6 +373,7 @@
+ assert(0 <= marked_bytes && marked_bytes <= used(),
+ err_msg("marked: "SIZE_FORMAT" used: "SIZE_FORMAT,
+ marked_bytes, used()));
++ _prev_top_at_mark_start = top();
+ _prev_marked_bytes = marked_bytes;
+ }
+
+@@ -477,7 +404,7 @@
+ if (cl->abort()) return cur;
+ // The check above must occur before the operation below, since an
+ // abort might invalidate the "size" operation.
+- cur += obj->size();
++ cur += block_size(cur);
+ }
+ return NULL;
+ }
+@@ -549,7 +476,7 @@
+ return cur;
+ }
+ // Otherwise...
+- next = (cur + obj->size());
++ next = cur + block_size(cur);
+ }
+
+ // If we finish the above loop...We have a parseable object that
+@@ -557,10 +484,9 @@
+ // inside or spans the entire region.
+
+ assert(obj == oop(cur), "sanity");
+- assert(cur <= start &&
+- obj->klass_or_null() != NULL &&
+- (cur + obj->size()) > start,
+- "Loop postcondition");
++ assert(cur <= start, "Loop postcondition");
++ assert(obj->klass_or_null() != NULL, "Loop postcondition");
++ assert((cur + block_size(cur)) > start, "Loop postcondition");
+
+ if (!g1h->is_obj_dead(obj)) {
+ obj->oop_iterate(cl, mr);
+@@ -574,7 +500,7 @@
+ };
+
+ // Otherwise:
+- next = (cur + obj->size());
++ next = cur + block_size(cur);
+
+ if (!g1h->is_obj_dead(obj)) {
+ if (next < end || !obj->is_objArray()) {
+@@ -600,21 +526,17 @@
+ hrrs->add_strong_code_root(nm);
+ }
+
++void HeapRegion::add_strong_code_root_locked(nmethod* nm) {
++ assert_locked_or_safepoint(CodeCache_lock);
++ HeapRegionRemSet* hrrs = rem_set();
++ hrrs->add_strong_code_root_locked(nm);
++}
++
+ void HeapRegion::remove_strong_code_root(nmethod* nm) {
+ HeapRegionRemSet* hrrs = rem_set();
+ hrrs->remove_strong_code_root(nm);
+ }
+
+-void HeapRegion::migrate_strong_code_roots() {
+- assert(in_collection_set(), "only collection set regions");
+- assert(!isHumongous(),
+- err_msg("humongous region "HR_FORMAT" should not have been added to collection set",
+- HR_FORMAT_PARAMS(this)));
+-
+- HeapRegionRemSet* hrrs = rem_set();
+- hrrs->migrate_strong_code_roots();
+-}
+-
+ void HeapRegion::strong_code_roots_do(CodeBlobClosure* blk) const {
+ HeapRegionRemSet* hrrs = rem_set();
+ hrrs->strong_code_roots_do(blk);
+@@ -750,26 +672,12 @@
+
+ void HeapRegion::print() const { print_on(gclog_or_tty); }
+ void HeapRegion::print_on(outputStream* st) const {
+- if (isHumongous()) {
+- if (startsHumongous())
+- st->print(" HS");
+- else
+- st->print(" HC");
+- } else {
+- st->print(" ");
+- }
++ st->print("AC%4u", allocation_context());
++ st->print(" %2s", get_short_type_str());
+ if (in_collection_set())
+ st->print(" CS");
+ else
+ st->print(" ");
+- if (is_young())
+- st->print(is_survivor() ? " SU" : " Y ");
+- else
+- st->print(" ");
+- if (is_empty())
+- st->print(" F");
+- else
+- st->print(" ");
+ st->print(" TS %5d", _gc_time_stamp);
+ st->print(" PTAMS "PTR_FORMAT" NTAMS "PTR_FORMAT,
+ prev_top_at_mark_start(), next_top_at_mark_start());
+@@ -929,10 +837,11 @@
+ size_t object_num = 0;
+ while (p < top()) {
+ oop obj = oop(p);
+- size_t obj_size = obj->size();
++ size_t obj_size = block_size(p);
+ object_num += 1;
+
+- if (is_humongous != g1->isHumongous(obj_size)) {
++ if (is_humongous != g1->isHumongous(obj_size) &&
++ !g1->is_obj_dead(obj, this)) { // Dead objects may have bigger block_size since they span several objects.
+ gclog_or_tty->print_cr("obj "PTR_FORMAT" is of %shumongous size ("
+ SIZE_FORMAT" words) in a %shumongous region",
+ p, g1->isHumongous(obj_size) ? "" : "non-",
+@@ -942,8 +851,10 @@
+ }
+
+ // If it returns false, verify_for_object() will output the
+- // appropriate messasge.
+- if (do_bot_verify && !_offsets.verify_for_object(p, obj_size)) {
++ // appropriate message.
++ if (do_bot_verify &&
++ !g1->is_obj_dead(obj, this) &&
++ !_offsets.verify_for_object(p, obj_size)) {
+ *failures = true;
+ return;
+ }
+@@ -951,7 +862,10 @@
+ if (!g1->is_obj_dead_cond(obj, this, vo)) {
+ if (obj->is_oop()) {
+ Klass* klass = obj->klass();
+- if (!klass->is_metaspace_object()) {
++ bool is_metaspace_object = Metaspace::contains(klass) ||
++ (vo == VerifyOption_G1UsePrevMarking &&
++ ClassLoaderDataGraph::unload_list_contains(klass));
++ if (!is_metaspace_object) {
+ gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
+ "not metadata", klass, (void *)obj);
+ *failures = true;
+@@ -1065,9 +979,10 @@
+ // away eventually.
+
+ void G1OffsetTableContigSpace::clear(bool mangle_space) {
+- ContiguousSpace::clear(mangle_space);
+- _offsets.zero_bottom_entry();
+- _offsets.initialize_threshold();
++ set_top(bottom());
++ set_saved_mark_word(bottom());
++ CompactibleSpace::clear(mangle_space);
++ reset_bot();
+ }
+
+ void G1OffsetTableContigSpace::set_bottom(HeapWord* new_bottom) {
+@@ -1100,13 +1015,16 @@
+ HeapWord* G1OffsetTableContigSpace::saved_mark_word() const {
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ assert( _gc_time_stamp <= g1h->get_gc_time_stamp(), "invariant" );
+- if (_gc_time_stamp < g1h->get_gc_time_stamp())
+- return top();
+- else
+- return ContiguousSpace::saved_mark_word();
++ HeapWord* local_top = top();
++ OrderAccess::loadload();
++ if (_gc_time_stamp < g1h->get_gc_time_stamp()) {
++ return local_top;
++ } else {
++ return Space::saved_mark_word();
++ }
+ }
+
+-void G1OffsetTableContigSpace::set_saved_mark() {
++void G1OffsetTableContigSpace::record_top_and_timestamp() {
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ unsigned curr_gc_time_stamp = g1h->get_gc_time_stamp();
+
+@@ -1118,7 +1036,7 @@
+ // of region. If it does so after _gc_time_stamp = ..., then it
+ // will pick up the right saved_mark_word() as the high water mark
+ // of the region. Either way, the behaviour will be correct.
+- ContiguousSpace::set_saved_mark();
++ Space::set_saved_mark_word(top());
+ OrderAccess::storestore();
+ _gc_time_stamp = curr_gc_time_stamp;
+ // No need to do another barrier to flush the writes above. If
+@@ -1129,6 +1047,26 @@
+ }
+ }
+
++void G1OffsetTableContigSpace::safe_object_iterate(ObjectClosure* blk) {
++ object_iterate(blk);
++}
++
++void G1OffsetTableContigSpace::object_iterate(ObjectClosure* blk) {
++ HeapWord* p = bottom();
++ while (p < top()) {
++ if (block_is_obj(p)) {
++ blk->do_object(oop(p));
++ }
++ p += block_size(p);
++ }
++}
++
++#define block_is_always_obj(q) true
++void G1OffsetTableContigSpace::prepare_for_compaction(CompactPoint* cp) {
++ SCAN_AND_FORWARD(cp, top, block_is_always_obj, block_size);
++}
++#undef block_is_always_obj
++
+ G1OffsetTableContigSpace::
+ G1OffsetTableContigSpace(G1BlockOffsetSharedArray* sharedOffsetArray,
+ MemRegion mr) :
+@@ -1137,8 +1075,11 @@
+ _gc_time_stamp(0)
+ {
+ _offsets.set_space(this);
+- // false ==> we'll do the clearing if there's clearing to be done.
+- ContiguousSpace::initialize(mr, false, SpaceDecorator::Mangle);
+- _offsets.zero_bottom_entry();
+- _offsets.initialize_threshold();
+ }
++
++void G1OffsetTableContigSpace::initialize(MemRegion mr, bool clear_space, bool mangle_space) {
++ CompactibleSpace::initialize(mr, clear_space, mangle_space);
++ _top = bottom();
++ reset_bot();
++}
++
+--- ./hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,8 +25,10 @@
+ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_HPP
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_HPP
+
+-#include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
++#include "gc_implementation/g1/g1AllocationContext.hpp"
++#include "gc_implementation/g1/g1BlockOffsetTable.hpp"
+ #include "gc_implementation/g1/g1_specialized_oop_closures.hpp"
++#include "gc_implementation/g1/heapRegionType.hpp"
+ #include "gc_implementation/g1/survRateGroup.hpp"
+ #include "gc_implementation/shared/ageTable.hpp"
+ #include "gc_implementation/shared/spaceDecorator.hpp"
+@@ -34,8 +36,6 @@
+ #include "memory/watermark.hpp"
+ #include "utilities/macros.hpp"
+
+-#if INCLUDE_ALL_GCS
+-
+ // A HeapRegion is the smallest piece of a G1CollectedHeap that
+ // can be collected independently.
+
+@@ -46,8 +46,6 @@
+ // The solution is to remove this method from the definition
+ // of a Space.
+
+-class CompactibleSpace;
+-class ContiguousSpace;
+ class HeapRegionRemSet;
+ class HeapRegionRemSetIterator;
+ class HeapRegion;
+@@ -56,22 +54,19 @@
+
+ #define HR_FORMAT "%u:(%s)["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
+ #define HR_FORMAT_PARAMS(_hr_) \
+- (_hr_)->hrs_index(), \
+- (_hr_)->is_survivor() ? "S" : (_hr_)->is_young() ? "E" : \
+- (_hr_)->startsHumongous() ? "HS" : \
+- (_hr_)->continuesHumongous() ? "HC" : \
+- !(_hr_)->is_empty() ? "O" : "F", \
++ (_hr_)->hrm_index(), \
++ (_hr_)->get_short_type_str(), \
+ p2i((_hr_)->bottom()), p2i((_hr_)->top()), p2i((_hr_)->end())
+
+-// sentinel value for hrs_index
+-#define G1_NULL_HRS_INDEX ((uint) -1)
++// sentinel value for hrm_index
++#define G1_NO_HRM_INDEX ((uint) -1)
+
+ // A dirty card to oop closure for heap regions. It
+ // knows how to get the G1 heap and how to use the bitmap
+ // in the concurrent marker used by G1 to filter remembered
+ // sets.
+
+-class HeapRegionDCTOC : public ContiguousSpaceDCTOC {
++class HeapRegionDCTOC : public DirtyCardToOopClosure {
+ public:
+ // Specification of possible DirtyCardToOopClosure filtering.
+ enum FilterKind {
+@@ -85,39 +80,13 @@
+ FilterKind _fk;
+ G1CollectedHeap* _g1;
+
+- void walk_mem_region_with_cl(MemRegion mr,
+- HeapWord* bottom, HeapWord* top,
+- ExtendedOopClosure* cl);
+-
+- // We don't specialize this for FilteringClosure; filtering is handled by
+- // the "FilterKind" mechanism. But we provide this to avoid a compiler
+- // warning.
+- void walk_mem_region_with_cl(MemRegion mr,
+- HeapWord* bottom, HeapWord* top,
+- FilteringClosure* cl) {
+- HeapRegionDCTOC::walk_mem_region_with_cl(mr, bottom, top,
+- (ExtendedOopClosure*)cl);
+- }
+-
+- // Get the actual top of the area on which the closure will
+- // operate, given where the top is assumed to be (the end of the
+- // memory region passed to do_MemRegion) and where the object
+- // at the top is assumed to start. For example, an object may
+- // start at the top but actually extend past the assumed top,
+- // in which case the top becomes the end of the object.
+- HeapWord* get_actual_top(HeapWord* top, HeapWord* top_obj) {
+- return ContiguousSpaceDCTOC::get_actual_top(top, top_obj);
+- }
+-
+ // Walk the given memory region from bottom to (actual) top
+ // looking for objects and applying the oop closure (_cl) to
+ // them. The base implementation of this treats the area as
+ // blocks, where a block may or may not be an object. Sub-
+ // classes should override this to provide more accurate
+ // or possibly more efficient walking.
+- void walk_mem_region(MemRegion mr, HeapWord* bottom, HeapWord* top) {
+- Filtering_DCTOC::walk_mem_region(mr, bottom, top);
+- }
++ void walk_mem_region(MemRegion mr, HeapWord* bottom, HeapWord* top);
+
+ public:
+ HeapRegionDCTOC(G1CollectedHeap* g1,
+@@ -151,9 +120,9 @@
+ // the regions anyway) and at the end of a Full GC. The current scheme
+ // that uses sequential unsigned ints will fail only if we have 4b
+ // evacuation pauses between two cleanups, which is _highly_ unlikely.
+-
+-class G1OffsetTableContigSpace: public ContiguousSpace {
++class G1OffsetTableContigSpace: public CompactibleSpace {
+ friend class VMStructs;
++ HeapWord* _top;
+ protected:
+ G1BlockOffsetArrayContigSpace _offsets;
+ Mutex _par_alloc_lock;
+@@ -170,11 +139,35 @@
+ G1OffsetTableContigSpace(G1BlockOffsetSharedArray* sharedOffsetArray,
+ MemRegion mr);
+
++ void set_top(HeapWord* value) { _top = value; }
++ HeapWord* top() const { return _top; }
++
++ protected:
++ // Reset the G1OffsetTableContigSpace.
++ virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space);
++
++ HeapWord** top_addr() { return &_top; }
++ // Allocation helpers (return NULL if full).
++ inline HeapWord* allocate_impl(size_t word_size, HeapWord* end_value);
++ inline HeapWord* par_allocate_impl(size_t word_size, HeapWord* end_value);
++
++ public:
++ void reset_after_compaction() { set_top(compaction_top()); }
++
++ size_t used() const { return byte_size(bottom(), top()); }
++ size_t free() const { return byte_size(top(), end()); }
++ bool is_free_block(const HeapWord* p) const { return p >= top(); }
++
++ MemRegion used_region() const { return MemRegion(bottom(), top()); }
++
++ void object_iterate(ObjectClosure* blk);
++ void safe_object_iterate(ObjectClosure* blk);
++
+ void set_bottom(HeapWord* value);
+ void set_end(HeapWord* value);
+
+ virtual HeapWord* saved_mark_word() const;
+- virtual void set_saved_mark();
++ void record_top_and_timestamp();
+ void reset_gc_time_stamp() { _gc_time_stamp = 0; }
+ unsigned get_gc_time_stamp() { return _gc_time_stamp; }
+
+@@ -194,6 +187,8 @@
+ HeapWord* block_start(const void* p);
+ HeapWord* block_start_const(const void* p) const;
+
++ void prepare_for_compaction(CompactPoint* cp);
++
+ // Add offset table update.
+ virtual HeapWord* allocate(size_t word_size);
+ HeapWord* par_allocate(size_t word_size);
+@@ -205,12 +200,7 @@
+ virtual void print() const;
+
+ void reset_bot() {
+- _offsets.zero_bottom_entry();
+- _offsets.initialize_threshold();
+- }
+-
+- void update_bot_for_object(HeapWord* start, size_t word_size) {
+- _offsets.alloc_block(start, word_size);
++ _offsets.reset_bot();
+ }
+
+ void print_bot_on(outputStream* out) {
+@@ -222,16 +212,6 @@
+ friend class VMStructs;
+ private:
+
+- enum HumongousType {
+- NotHumongous = 0,
+- StartsHumongous,
+- ContinuesHumongous
+- };
+-
+- // Requires that the region "mr" be dense with objects, and begin and end
+- // with an object.
+- void oops_in_mr_iterate(MemRegion mr, ExtendedOopClosure* cl);
+-
+ // The remembered set for this region.
+ // (Might want to make this "inline" later, to avoid some alloc failure
+ // issues.)
+@@ -241,9 +221,12 @@
+
+ protected:
+ // The index of this region in the heap region sequence.
+- uint _hrs_index;
++ uint _hrm_index;
+
+- HumongousType _humongous_type;
++ AllocationContext_t _allocation_context;
++
++ HeapRegionType _type;
++
+ // For a humongous region, region in which it starts.
+ HeapRegion* _humongous_start_region;
+ // For the start region of a humongous sequence, it's original end().
+@@ -256,11 +239,9 @@
+ bool _evacuation_failed;
+
+ // A heap region may be a member one of a number of special subsets, each
+- // represented as linked lists through the field below. Currently, these
+- // sets include:
++ // represented as linked lists through the field below. Currently, there
++ // is only one set:
+ // The collection set.
+- // The set of allocation regions used in a collection pause.
+- // Spaces that may contain gray objects.
+ HeapRegion* _next_in_special_set;
+
+ // next region in the young "generation" region set
+@@ -275,7 +256,6 @@
+ #ifdef ASSERT
+ HeapRegionSetBase* _containing_set;
+ #endif // ASSERT
+- bool _pending_removal;
+
+ // For parallel heapRegion traversal.
+ jint _claimed;
+@@ -288,13 +268,6 @@
+ // The calculated GC efficiency of the region.
+ double _gc_efficiency;
+
+- enum YoungType {
+- NotYoung, // a region is not young
+- Young, // a region is young
+- Survivor // a region is young and it contains survivors
+- };
+-
+- volatile YoungType _young_type;
+ int _young_index_in_cset;
+ SurvRateGroup* _surv_rate_group;
+ int _age_index;
+@@ -319,12 +292,6 @@
+ _next_top_at_mark_start = bot;
+ }
+
+- void set_young_type(YoungType new_type) {
+- //assert(_young_type != new_type, "setting the same type" );
+- // TODO: add more assertions here
+- _young_type = new_type;
+- }
+-
+ // Cached attributes used in the collection set policy information
+
+ // The RSet length that was added to the total value
+@@ -340,10 +307,16 @@
+ size_t _predicted_bytes_to_copy;
+
+ public:
+- HeapRegion(uint hrs_index,
++ HeapRegion(uint hrm_index,
+ G1BlockOffsetSharedArray* sharedOffsetArray,
+ MemRegion mr);
+
++ // Initializing the HeapRegion not only resets the data structure, but also
++ // resets the BOT for that heap region.
++ // The default values for clear_space means that we will do the clearing if
++ // there's clearing to be done ourselves. We also always mangle the space.
++ virtual void initialize(MemRegion mr, bool clear_space = false, bool mangle_space = SpaceDecorator::Mangle);
++
+ static int LogOfHRGrainBytes;
+ static int LogOfHRGrainWords;
+
+@@ -379,18 +352,19 @@
+ ParMarkRootClaimValue = 9
+ };
+
+- inline HeapWord* par_allocate_no_bot_updates(size_t word_size) {
+- assert(is_young(), "we can only skip BOT updates on young regions");
+- return ContiguousSpace::par_allocate(word_size);
+- }
+- inline HeapWord* allocate_no_bot_updates(size_t word_size) {
+- assert(is_young(), "we can only skip BOT updates on young regions");
+- return ContiguousSpace::allocate(word_size);
+- }
++ // All allocated blocks are occupied by objects in a HeapRegion
++ bool block_is_obj(const HeapWord* p) const;
+
+- // If this region is a member of a HeapRegionSeq, the index in that
++ // Returns the object size for all valid block starts
++ // and the amount of unallocated words if called on top()
++ size_t block_size(const HeapWord* p) const;
++
++ inline HeapWord* par_allocate_no_bot_updates(size_t word_size);
++ inline HeapWord* allocate_no_bot_updates(size_t word_size);
++
++ // If this region is a member of a HeapRegionManager, the index in that
+ // sequence, otherwise -1.
+- uint hrs_index() const { return _hrs_index; }
++ uint hrm_index() const { return _hrm_index; }
+
+ // The number of bytes marked live in the region in the last marking phase.
+ size_t marked_bytes() { return _prev_marked_bytes; }
+@@ -437,9 +411,21 @@
+ _prev_marked_bytes = _next_marked_bytes = 0;
+ }
+
+- bool isHumongous() const { return _humongous_type != NotHumongous; }
+- bool startsHumongous() const { return _humongous_type == StartsHumongous; }
+- bool continuesHumongous() const { return _humongous_type == ContinuesHumongous; }
++ const char* get_type_str() const { return _type.get_str(); }
++ const char* get_short_type_str() const { return _type.get_short_str(); }
++
++ bool is_free() const { return _type.is_free(); }
++
++ bool is_young() const { return _type.is_young(); }
++ bool is_eden() const { return _type.is_eden(); }
++ bool is_survivor() const { return _type.is_survivor(); }
++
++ bool isHumongous() const { return _type.is_humongous(); }
++ bool startsHumongous() const { return _type.is_starts_humongous(); }
++ bool continuesHumongous() const { return _type.is_continues_humongous(); }
++
++ bool is_old() const { return _type.is_old(); }
++
+ // For a humongous region, region in which it starts.
+ HeapRegion* humongous_start_region() const {
+ return _humongous_start_region;
+@@ -461,7 +447,7 @@
+ // with this HS region.
+ uint last_hc_index() const {
+ assert(startsHumongous(), "don't call this otherwise");
+- return hrs_index() + region_num();
++ return hrm_index() + region_num();
+ }
+
+ // Same as Space::is_in_reserved, but will use the original size of the region.
+@@ -503,7 +489,7 @@
+ void set_continuesHumongous(HeapRegion* first_hr);
+
+ // Unsets the humongous-related fields on the region.
+- void set_notHumongous();
++ void clear_humongous();
+
+ // If the region has a remembered set, return a pointer to it.
+ HeapRegionRemSet* rem_set() const {
+@@ -530,6 +516,14 @@
+ _next_in_special_set = r;
+ }
+
++ void set_allocation_context(AllocationContext_t context) {
++ _allocation_context = context;
++ }
++
++ AllocationContext_t allocation_context() const {
++ return _allocation_context;
++ }
++
+ // Methods used by the HeapRegionSetBase class and subclasses.
+
+ // Getter and setter for the next and prev fields used to link regions into
+@@ -563,26 +557,6 @@
+ // to provide a dummy version of it.
+ #endif // ASSERT
+
+- // If we want to remove regions from a list in bulk we can simply tag
+- // them with the pending_removal tag and call the
+- // remove_all_pending() method on the list.
+-
+- bool pending_removal() { return _pending_removal; }
+-
+- void set_pending_removal(bool pending_removal) {
+- if (pending_removal) {
+- assert(!_pending_removal && containing_set() != NULL,
+- "can only set pending removal to true if it's false and "
+- "the region belongs to a region set");
+- } else {
+- assert( _pending_removal && containing_set() == NULL,
+- "can only set pending removal to false if it's true and "
+- "the region does not belong to a region set");
+- }
+-
+- _pending_removal = pending_removal;
+- }
+-
+ HeapRegion* get_next_young_region() { return _next_young_region; }
+ void set_next_young_region(HeapRegion* hr) {
+ _next_young_region = hr;
+@@ -593,10 +567,7 @@
+ void set_next_dirty_cards_region(HeapRegion* hr) { _next_dirty_cards_region = hr; }
+ bool is_on_dirty_cards_region_list() const { return get_next_dirty_cards_region() != NULL; }
+
+- HeapWord* orig_end() { return _orig_end; }
+-
+- // Allows logical separation between objects allocated before and after.
+- void save_marks();
++ HeapWord* orig_end() const { return _orig_end; }
+
+ // Reset HR stuff to default values.
+ void hr_clear(bool par, bool clear_space, bool locked = false);
+@@ -606,10 +577,6 @@
+ HeapWord* prev_top_at_mark_start() const { return _prev_top_at_mark_start; }
+ HeapWord* next_top_at_mark_start() const { return _next_top_at_mark_start; }
+
+- // Apply "cl->do_oop" to (the addresses of) all reference fields in objects
+- // allocated in the current region before the last call to "save_mark".
+- void oop_before_save_marks_iterate(ExtendedOopClosure* cl);
+-
+ // Note the start or end of marking. This tells the heap region
+ // that the collector is about to start or has finished (concurrently)
+ // marking the heap.
+@@ -657,9 +624,6 @@
+ void calc_gc_efficiency(void);
+ double gc_efficiency() { return _gc_efficiency;}
+
+- bool is_young() const { return _young_type != NotYoung; }
+- bool is_survivor() const { return _young_type == Survivor; }
+-
+ int young_index_in_cset() const { return _young_index_in_cset; }
+ void set_young_index_in_cset(int index) {
+ assert( (index == -1) || is_young(), "pre-condition" );
+@@ -711,11 +675,13 @@
+ }
+ }
+
+- void set_young() { set_young_type(Young); }
++ void set_free() { _type.set_free(); }
+
+- void set_survivor() { set_young_type(Survivor); }
++ void set_eden() { _type.set_eden(); }
++ void set_eden_pre_gc() { _type.set_eden_pre_gc(); }
++ void set_survivor() { _type.set_survivor(); }
+
+- void set_not_young() { set_young_type(NotYoung); }
++ void set_old() { _type.set_old(); }
+
+ // Determine if an object has been allocated since the last
+ // mark performed by the collector. This returns true iff the object
+@@ -767,18 +733,6 @@
+ bool filter_young,
+ jbyte* card_ptr);
+
+- // A version of block start that is guaranteed to find *some* block
+- // boundary at or before "p", but does not object iteration, and may
+- // therefore be used safely when the heap is unparseable.
+- HeapWord* block_start_careful(const void* p) const {
+- return _offsets.block_start_careful(p);
+- }
+-
+- // Requires that "addr" is within the region. Returns the start of the
+- // first ("careful") block that starts at or after "addr", or else the
+- // "end" of the region if there is no such block.
+- HeapWord* next_block_start_careful(HeapWord* addr);
+-
+ size_t recorded_rs_length() const { return _recorded_rs_length; }
+ double predicted_elapsed_time_ms() const { return _predicted_elapsed_time_ms; }
+ size_t predicted_bytes_to_copy() const { return _predicted_bytes_to_copy; }
+@@ -795,10 +749,6 @@
+ _predicted_bytes_to_copy = bytes;
+ }
+
+-#define HeapRegion_OOP_SINCE_SAVE_MARKS_DECL(OopClosureType, nv_suffix) \
+- virtual void oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl);
+- SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(HeapRegion_OOP_SINCE_SAVE_MARKS_DECL)
+-
+ virtual CompactibleSpace* next_compaction_space() const;
+
+ virtual void reset_after_compaction();
+@@ -806,14 +756,9 @@
+ // Routines for managing a list of code roots (attached to the
+ // this region's RSet) that point into this heap region.
+ void add_strong_code_root(nmethod* nm);
++ void add_strong_code_root_locked(nmethod* nm);
+ void remove_strong_code_root(nmethod* nm);
+
+- // During a collection, migrate the successfully evacuated
+- // strong code roots that referenced into this region to the
+- // new regions that they now point into. Unsuccessfully
+- // evacuated code roots are not migrated.
+- void migrate_strong_code_roots();
+-
+ // Applies blk->do_code_blob() to each of the entries in
+ // the strong code roots list for this region
+ void strong_code_roots_do(CodeBlobClosure* blk) const;
+@@ -847,7 +792,7 @@
+ // HeapRegionClosure is used for iterating over regions.
+ // Terminates the iteration when the "doHeapRegion" method returns "true".
+ class HeapRegionClosure : public StackObj {
+- friend class HeapRegionSeq;
++ friend class HeapRegionManager;
+ friend class G1CollectedHeap;
+
+ bool _complete;
+@@ -864,6 +809,4 @@
+ bool complete() { return _complete; }
+ };
+
+-#endif // INCLUDE_ALL_GCS
+-
+ #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_HPP
+--- ./hotspot/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,8 +25,49 @@
+ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_INLINE_HPP
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_INLINE_HPP
+
++#include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
++#include "gc_implementation/g1/g1CollectedHeap.hpp"
++#include "gc_implementation/g1/heapRegion.hpp"
++#include "memory/space.hpp"
++#include "runtime/atomic.inline.hpp"
++
++// This version requires locking.
++inline HeapWord* G1OffsetTableContigSpace::allocate_impl(size_t size,
++ HeapWord* const end_value) {
++ HeapWord* obj = top();
++ if (pointer_delta(end_value, obj) >= size) {
++ HeapWord* new_top = obj + size;
++ set_top(new_top);
++ assert(is_aligned(obj) && is_aligned(new_top), "checking alignment");
++ return obj;
++ } else {
++ return NULL;
++ }
++}
++
++// This version is lock-free.
++inline HeapWord* G1OffsetTableContigSpace::par_allocate_impl(size_t size,
++ HeapWord* const end_value) {
++ do {
++ HeapWord* obj = top();
++ if (pointer_delta(end_value, obj) >= size) {
++ HeapWord* new_top = obj + size;
++ HeapWord* result = (HeapWord*)Atomic::cmpxchg_ptr(new_top, top_addr(), obj);
++ // result can be one of two:
++ // the old top value: the exchange succeeded
++ // otherwise: the new value of the top is returned.
++ if (result == obj) {
++ assert(is_aligned(obj) && is_aligned(new_top), "checking alignment");
++ return obj;
++ }
++ } else {
++ return NULL;
++ }
++ } while (true);
++}
++
+ inline HeapWord* G1OffsetTableContigSpace::allocate(size_t size) {
+- HeapWord* res = ContiguousSpace::allocate(size);
++ HeapWord* res = allocate_impl(size, end());
+ if (res != NULL) {
+ _offsets.alloc_block(res, size);
+ }
+@@ -38,12 +79,7 @@
+ // this is used for larger LAB allocations only.
+ inline HeapWord* G1OffsetTableContigSpace::par_allocate(size_t size) {
+ MutexLocker x(&_par_alloc_lock);
+- // Given that we take the lock no need to use par_allocate() here.
+- HeapWord* res = ContiguousSpace::allocate(size);
+- if (res != NULL) {
+- _offsets.alloc_block(res, size);
+- }
+- return res;
++ return allocate(size);
+ }
+
+ inline HeapWord* G1OffsetTableContigSpace::block_start(const void* p) {
+@@ -55,6 +91,52 @@
+ return _offsets.block_start_const(p);
+ }
+
++inline bool
++HeapRegion::block_is_obj(const HeapWord* p) const {
++ G1CollectedHeap* g1h = G1CollectedHeap::heap();
++ if (ClassUnloadingWithConcurrentMark) {
++ return !g1h->is_obj_dead(oop(p), this);
++ }
++ return p < top();
++}
++
++inline size_t
++HeapRegion::block_size(const HeapWord *addr) const {
++ if (addr == top()) {
++ return pointer_delta(end(), addr);
++ }
++
++ if (block_is_obj(addr)) {
++ return oop(addr)->size();
++ }
++
++ assert(ClassUnloadingWithConcurrentMark,
++ err_msg("All blocks should be objects if G1 Class Unloading isn't used. "
++ "HR: ["PTR_FORMAT", "PTR_FORMAT", "PTR_FORMAT") "
++ "addr: " PTR_FORMAT,
++ p2i(bottom()), p2i(top()), p2i(end()), p2i(addr)));
++
++ // Old regions' dead objects may have dead classes
++ // We need to find the next live object in some other
++ // manner than getting the oop size
++ G1CollectedHeap* g1h = G1CollectedHeap::heap();
++ HeapWord* next = g1h->concurrent_mark()->prevMarkBitMap()->
++ getNextMarkedWordAddress(addr, prev_top_at_mark_start());
++
++ assert(next > addr, "must get the next live object");
++ return pointer_delta(next, addr);
++}
++
++inline HeapWord* HeapRegion::par_allocate_no_bot_updates(size_t word_size) {
++ assert(is_young(), "we can only skip BOT updates on young regions");
++ return par_allocate_impl(word_size, end());
++}
++
++inline HeapWord* HeapRegion::allocate_no_bot_updates(size_t word_size) {
++ assert(is_young(), "we can only skip BOT updates on young regions");
++ return allocate_impl(word_size, end());
++}
++
+ inline void HeapRegion::note_start_of_marking() {
+ _next_marked_bytes = 0;
+ _next_top_at_mark_start = top();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/heapRegionBounds.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONBOUNDS_HPP
++#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONBOUNDS_HPP
++
++class HeapRegionBounds : public AllStatic {
++private:
++ // Minimum region size; we won't go lower than that.
++ // We might want to decrease this in the future, to deal with small
++ // heaps a bit more efficiently.
++ static const size_t MIN_REGION_SIZE = 1024 * 1024;
++
++ // Maximum region size; we don't go higher than that. There's a good
++ // reason for having an upper bound. We don't want regions to get too
++ // large, otherwise cleanup's effectiveness would decrease as there
++ // will be fewer opportunities to find totally empty regions after
++ // marking.
++ static const size_t MAX_REGION_SIZE = 32 * 1024 * 1024;
++
++ // The automatic region size calculation will try to have around this
++ // many regions in the heap (based on the min heap size).
++ static const size_t TARGET_REGION_NUMBER = 2048;
++
++public:
++ static inline size_t min_size();
++ static inline size_t max_size();
++ static inline size_t target_number();
++};
++
++#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONBOUNDS_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/heapRegionBounds.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "gc_implementation/g1/heapRegionBounds.hpp"
++
++size_t HeapRegionBounds::min_size() {
++ return MIN_REGION_SIZE;
++}
++
++size_t HeapRegionBounds::max_size() {
++ return MAX_REGION_SIZE;
++}
++
++size_t HeapRegionBounds::target_number() {
++ return TARGET_REGION_NUMBER;
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,447 @@
++/*
++ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "gc_implementation/g1/heapRegion.hpp"
++#include "gc_implementation/g1/heapRegionManager.inline.hpp"
++#include "gc_implementation/g1/heapRegionSet.inline.hpp"
++#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
++#include "gc_implementation/g1/concurrentG1Refine.hpp"
++#include "memory/allocation.hpp"
++
++void HeapRegionManager::initialize(G1RegionToSpaceMapper* heap_storage,
++ G1RegionToSpaceMapper* prev_bitmap,
++ G1RegionToSpaceMapper* next_bitmap,
++ G1RegionToSpaceMapper* bot,
++ G1RegionToSpaceMapper* cardtable,
++ G1RegionToSpaceMapper* card_counts) {
++ _allocated_heapregions_length = 0;
++
++ _heap_mapper = heap_storage;
++
++ _prev_bitmap_mapper = prev_bitmap;
++ _next_bitmap_mapper = next_bitmap;
++
++ _bot_mapper = bot;
++ _cardtable_mapper = cardtable;
++
++ _card_counts_mapper = card_counts;
++
++ MemRegion reserved = heap_storage->reserved();
++ _regions.initialize(reserved.start(), reserved.end(), HeapRegion::GrainBytes);
++
++ _available_map.resize(_regions.length(), false);
++ _available_map.clear();
++}
++
++bool HeapRegionManager::is_available(uint region) const {
++ return _available_map.at(region);
++}
++
++#ifdef ASSERT
++bool HeapRegionManager::is_free(HeapRegion* hr) const {
++ return _free_list.contains(hr);
++}
++#endif
++
++HeapRegion* HeapRegionManager::new_heap_region(uint hrm_index) {
++ G1CollectedHeap* g1h = G1CollectedHeap::heap();
++ HeapWord* bottom = g1h->bottom_addr_for_region(hrm_index);
++ MemRegion mr(bottom, bottom + HeapRegion::GrainWords);
++ assert(reserved().contains(mr), "invariant");
++ return g1h->allocator()->new_heap_region(hrm_index, g1h->bot_shared(), mr);
++}
++
++void HeapRegionManager::commit_regions(uint index, size_t num_regions) {
++ guarantee(num_regions > 0, "Must commit more than zero regions");
++ guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions");
++
++ _num_committed += (uint)num_regions;
++
++ _heap_mapper->commit_regions(index, num_regions);
++
++ // Also commit auxiliary data
++ _prev_bitmap_mapper->commit_regions(index, num_regions);
++ _next_bitmap_mapper->commit_regions(index, num_regions);
++
++ _bot_mapper->commit_regions(index, num_regions);
++ _cardtable_mapper->commit_regions(index, num_regions);
++
++ _card_counts_mapper->commit_regions(index, num_regions);
++}
++
++void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) {
++ guarantee(num_regions >= 1, err_msg("Need to specify at least one region to uncommit, tried to uncommit zero regions at %u", start));
++ guarantee(_num_committed >= num_regions, "pre-condition");
++
++ // Print before uncommitting.
++ if (G1CollectedHeap::heap()->hr_printer()->is_active()) {
++ for (uint i = start; i < start + num_regions; i++) {
++ HeapRegion* hr = at(i);
++ G1CollectedHeap::heap()->hr_printer()->uncommit(hr->bottom(), hr->end());
++ }
++ }
++
++ _num_committed -= (uint)num_regions;
++
++ _available_map.par_clear_range(start, start + num_regions, BitMap::unknown_range);
++ _heap_mapper->uncommit_regions(start, num_regions);
++
++ // Also uncommit auxiliary data
++ _prev_bitmap_mapper->uncommit_regions(start, num_regions);
++ _next_bitmap_mapper->uncommit_regions(start, num_regions);
++
++ _bot_mapper->uncommit_regions(start, num_regions);
++ _cardtable_mapper->uncommit_regions(start, num_regions);
++
++ _card_counts_mapper->uncommit_regions(start, num_regions);
++}
++
++void HeapRegionManager::make_regions_available(uint start, uint num_regions) {
++ guarantee(num_regions > 0, "No point in calling this for zero regions");
++ commit_regions(start, num_regions);
++ for (uint i = start; i < start + num_regions; i++) {
++ if (_regions.get_by_index(i) == NULL) {
++ HeapRegion* new_hr = new_heap_region(i);
++ _regions.set_by_index(i, new_hr);
++ _allocated_heapregions_length = MAX2(_allocated_heapregions_length, i + 1);
++ }
++ }
++
++ _available_map.par_set_range(start, start + num_regions, BitMap::unknown_range);
++
++ for (uint i = start; i < start + num_regions; i++) {
++ assert(is_available(i), err_msg("Just made region %u available but is apparently not.", i));
++ HeapRegion* hr = at(i);
++ if (G1CollectedHeap::heap()->hr_printer()->is_active()) {
++ G1CollectedHeap::heap()->hr_printer()->commit(hr->bottom(), hr->end());
++ }
++ HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(i);
++ MemRegion mr(bottom, bottom + HeapRegion::GrainWords);
++
++ hr->initialize(mr);
++ insert_into_free_list(at(i));
++ }
++}
++
++uint HeapRegionManager::expand_by(uint num_regions) {
++ return expand_at(0, num_regions);
++}
++
++uint HeapRegionManager::expand_at(uint start, uint num_regions) {
++ if (num_regions == 0) {
++ return 0;
++ }
++
++ uint cur = start;
++ uint idx_last_found = 0;
++ uint num_last_found = 0;
++
++ uint expanded = 0;
++
++ while (expanded < num_regions &&
++ (num_last_found = find_unavailable_from_idx(cur, &idx_last_found)) > 0) {
++ uint to_expand = MIN2(num_regions - expanded, num_last_found);
++ make_regions_available(idx_last_found, to_expand);
++ expanded += to_expand;
++ cur = idx_last_found + num_last_found + 1;
++ }
++
++ verify_optional();
++ return expanded;
++}
++
++uint HeapRegionManager::find_contiguous(size_t num, bool empty_only) {
++ uint found = 0;
++ size_t length_found = 0;
++ uint cur = 0;
++
++ while (length_found < num && cur < max_length()) {
++ HeapRegion* hr = _regions.get_by_index(cur);
++ if ((!empty_only && !is_available(cur)) || (is_available(cur) && hr != NULL && hr->is_empty())) {
++ // This region is a potential candidate for allocation into.
++ length_found++;
++ } else {
++ // This region is not a candidate. The next region is the next possible one.
++ found = cur + 1;
++ length_found = 0;
++ }
++ cur++;
++ }
++
++ if (length_found == num) {
++ for (uint i = found; i < (found + num); i++) {
++ HeapRegion* hr = _regions.get_by_index(i);
++ // sanity check
++ guarantee((!empty_only && !is_available(i)) || (is_available(i) && hr != NULL && hr->is_empty()),
++ err_msg("Found region sequence starting at " UINT32_FORMAT ", length " SIZE_FORMAT
++ " that is not empty at " UINT32_FORMAT ". Hr is " PTR_FORMAT, found, num, i, p2i(hr)));
++ }
++ return found;
++ } else {
++ return G1_NO_HRM_INDEX;
++ }
++}
++
++HeapRegion* HeapRegionManager::next_region_in_heap(const HeapRegion* r) const {
++ guarantee(r != NULL, "Start region must be a valid region");
++ guarantee(is_available(r->hrm_index()), err_msg("Trying to iterate starting from region %u which is not in the heap", r->hrm_index()));
++ for (uint i = r->hrm_index() + 1; i < _allocated_heapregions_length; i++) {
++ HeapRegion* hr = _regions.get_by_index(i);
++ if (is_available(i)) {
++ return hr;
++ }
++ }
++ return NULL;
++}
++
++void HeapRegionManager::iterate(HeapRegionClosure* blk) const {
++ uint len = max_length();
++
++ for (uint i = 0; i < len; i++) {
++ if (!is_available(i)) {
++ continue;
++ }
++ guarantee(at(i) != NULL, err_msg("Tried to access region %u that has a NULL HeapRegion*", i));
++ bool res = blk->doHeapRegion(at(i));
++ if (res) {
++ blk->incomplete();
++ return;
++ }
++ }
++}
++
++uint HeapRegionManager::find_unavailable_from_idx(uint start_idx, uint* res_idx) const {
++ guarantee(res_idx != NULL, "checking");
++ guarantee(start_idx <= (max_length() + 1), "checking");
++
++ uint num_regions = 0;
++
++ uint cur = start_idx;
++ while (cur < max_length() && is_available(cur)) {
++ cur++;
++ }
++ if (cur == max_length()) {
++ return num_regions;
++ }
++ *res_idx = cur;
++ while (cur < max_length() && !is_available(cur)) {
++ cur++;
++ }
++ num_regions = cur - *res_idx;
++#ifdef ASSERT
++ for (uint i = *res_idx; i < (*res_idx + num_regions); i++) {
++ assert(!is_available(i), "just checking");
++ }
++ assert(cur == max_length() || num_regions == 0 || is_available(cur),
++ err_msg("The region at the current position %u must be available or at the end of the heap.", cur));
++#endif
++ return num_regions;
++}
++
++uint HeapRegionManager::start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const {
++ return num_regions * worker_i / num_workers;
++}
++
++void HeapRegionManager::par_iterate(HeapRegionClosure* blk, uint worker_id, uint num_workers, jint claim_value) const {
++ const uint start_index = start_region_for_worker(worker_id, num_workers, _allocated_heapregions_length);
++
++ // Every worker will actually look at all regions, skipping over regions that
++ // are currently not committed.
++ // This also (potentially) iterates over regions newly allocated during GC. This
++ // is no problem except for some extra work.
++ for (uint count = 0; count < _allocated_heapregions_length; count++) {
++ const uint index = (start_index + count) % _allocated_heapregions_length;
++ assert(0 <= index && index < _allocated_heapregions_length, "sanity");
++ // Skip over unavailable regions
++ if (!is_available(index)) {
++ continue;
++ }
++ HeapRegion* r = _regions.get_by_index(index);
++ // We'll ignore "continues humongous" regions (we'll process them
++ // when we come across their corresponding "start humongous"
++ // region) and regions already claimed.
++ if (r->claim_value() == claim_value || r->continuesHumongous()) {
++ continue;
++ }
++ // OK, try to claim it
++ if (!r->claimHeapRegion(claim_value)) {
++ continue;
++ }
++ // Success!
++ if (r->startsHumongous()) {
++ // If the region is "starts humongous" we'll iterate over its
++ // "continues humongous" first; in fact we'll do them
++ // first. The order is important. In one case, calling the
++ // closure on the "starts humongous" region might de-allocate
++ // and clear all its "continues humongous" regions and, as a
++ // result, we might end up processing them twice. So, we'll do
++ // them first (note: most closures will ignore them anyway) and
++ // then we'll do the "starts humongous" region.
++ for (uint ch_index = index + 1; ch_index < index + r->region_num(); ch_index++) {
++ HeapRegion* chr = _regions.get_by_index(ch_index);
++
++ assert(chr->continuesHumongous(), "Must be humongous region");
++ assert(chr->humongous_start_region() == r,
++ err_msg("Must work on humongous continuation of the original start region "
++ PTR_FORMAT ", but is " PTR_FORMAT, p2i(r), p2i(chr)));
++ assert(chr->claim_value() != claim_value,
++ "Must not have been claimed yet because claiming of humongous continuation first claims the start region");
++
++ bool claim_result = chr->claimHeapRegion(claim_value);
++ // We should always be able to claim it; no one else should
++ // be trying to claim this region.
++ guarantee(claim_result, "We should always be able to claim the continuesHumongous part of the humongous object");
++
++ bool res2 = blk->doHeapRegion(chr);
++ if (res2) {
++ return;
++ }
++
++ // Right now, this holds (i.e., no closure that actually
++ // does something with "continues humongous" regions
++ // clears them). We might have to weaken it in the future,
++ // but let's leave these two asserts here for extra safety.
++ assert(chr->continuesHumongous(), "should still be the case");
++ assert(chr->humongous_start_region() == r, "sanity");
++ }
++ }
++
++ bool res = blk->doHeapRegion(r);
++ if (res) {
++ return;
++ }
++ }
++}
++
++uint HeapRegionManager::shrink_by(uint num_regions_to_remove) {
++ assert(length() > 0, "the region sequence should not be empty");
++ assert(length() <= _allocated_heapregions_length, "invariant");
++ assert(_allocated_heapregions_length > 0, "we should have at least one region committed");
++ assert(num_regions_to_remove < length(), "We should never remove all regions");
++
++ if (num_regions_to_remove == 0) {
++ return 0;
++ }
++
++ uint removed = 0;
++ uint cur = _allocated_heapregions_length - 1;
++ uint idx_last_found = 0;
++ uint num_last_found = 0;
++
++ while ((removed < num_regions_to_remove) &&
++ (num_last_found = find_empty_from_idx_reverse(cur, &idx_last_found)) > 0) {
++ uint to_remove = MIN2(num_regions_to_remove - removed, num_last_found);
++
++ uncommit_regions(idx_last_found + num_last_found - to_remove, to_remove);
++
++ cur -= num_last_found;
++ removed += to_remove;
++ }
++
++ verify_optional();
++
++ return removed;
++}
++
++uint HeapRegionManager::find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const {
++ guarantee(start_idx < _allocated_heapregions_length, "checking");
++ guarantee(res_idx != NULL, "checking");
++
++ uint num_regions_found = 0;
++
++ jlong cur = start_idx;
++ while (cur != -1 && !(is_available(cur) && at(cur)->is_empty())) {
++ cur--;
++ }
++ if (cur == -1) {
++ return num_regions_found;
++ }
++ jlong old_cur = cur;
++ // cur indexes the first empty region
++ while (cur != -1 && is_available(cur) && at(cur)->is_empty()) {
++ cur--;
++ }
++ *res_idx = cur + 1;
++ num_regions_found = old_cur - cur;
++
++#ifdef ASSERT
++ for (uint i = *res_idx; i < (*res_idx + num_regions_found); i++) {
++ assert(at(i)->is_empty(), "just checking");
++ }
++#endif
++ return num_regions_found;
++}
++
++void HeapRegionManager::verify() {
++ guarantee(length() <= _allocated_heapregions_length,
++ err_msg("invariant: _length: %u _allocated_length: %u",
++ length(), _allocated_heapregions_length));
++ guarantee(_allocated_heapregions_length <= max_length(),
++ err_msg("invariant: _allocated_length: %u _max_length: %u",
++ _allocated_heapregions_length, max_length()));
++
++ bool prev_committed = true;
++ uint num_committed = 0;
++ HeapWord* prev_end = heap_bottom();
++ for (uint i = 0; i < _allocated_heapregions_length; i++) {
++ if (!is_available(i)) {
++ prev_committed = false;
++ continue;
++ }
++ num_committed++;
++ HeapRegion* hr = _regions.get_by_index(i);
++ guarantee(hr != NULL, err_msg("invariant: i: %u", i));
++ guarantee(!prev_committed || hr->bottom() == prev_end,
++ err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT,
++ i, HR_FORMAT_PARAMS(hr), p2i(prev_end)));
++ guarantee(hr->hrm_index() == i,
++ err_msg("invariant: i: %u hrm_index(): %u", i, hr->hrm_index()));
++ // Asserts will fire if i is >= _length
++ HeapWord* addr = hr->bottom();
++ guarantee(addr_to_region(addr) == hr, "sanity");
++ // We cannot check whether the region is part of a particular set: at the time
++ // this method may be called, we have only completed allocation of the regions,
++ // but not put into a region set.
++ prev_committed = true;
++ if (hr->startsHumongous()) {
++ prev_end = hr->orig_end();
++ } else {
++ prev_end = hr->end();
++ }
++ }
++ for (uint i = _allocated_heapregions_length; i < max_length(); i++) {
++ guarantee(_regions.get_by_index(i) == NULL, err_msg("invariant i: %u", i));
++ }
++
++ guarantee(num_committed == _num_committed, err_msg("Found %u committed regions, but should be %u", num_committed, _num_committed));
++ _free_list.verify();
++}
++
++#ifndef PRODUCT
++void HeapRegionManager::verify_optional() {
++ verify();
++}
++#endif // PRODUCT
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,238 @@
++/*
++ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP
++#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP
++
++#include "gc_implementation/g1/g1BiasedArray.hpp"
++#include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
++#include "gc_implementation/g1/heapRegionSet.hpp"
++
++class HeapRegion;
++class HeapRegionClosure;
++class FreeRegionList;
++
++class G1HeapRegionTable : public G1BiasedMappedArray<HeapRegion*> {
++ protected:
++ virtual HeapRegion* default_value() const { return NULL; }
++};
++
++// This class keeps track of the actual heap memory, auxiliary data
++// and its metadata (i.e., HeapRegion instances) and the list of free regions.
++//
++// This allows maximum flexibility for deciding what to commit or uncommit given
++// a request from outside.
++//
++// HeapRegions are kept in the _regions array in address order. A region's
++// index in the array corresponds to its index in the heap (i.e., 0 is the
++// region at the bottom of the heap, 1 is the one after it, etc.). Two
++// regions that are consecutive in the array should also be adjacent in the
++// address space (i.e., region(i).end() == region(i+1).bottom().
++//
++// We create a HeapRegion when we commit the region's address space
++// for the first time. When we uncommit the address space of a
++// region we retain the HeapRegion to be able to re-use it in the
++// future (in case we recommit it).
++//
++// We keep track of three lengths:
++//
++// * _num_committed (returned by length()) is the number of currently
++// committed regions. These may not be contiguous.
++// * _allocated_heapregions_length (not exposed outside this class) is the
++// number of regions+1 for which we have HeapRegions.
++// * max_length() returns the maximum number of regions the heap can have.
++//
++
++class HeapRegionManager: public CHeapObj<mtGC> {
++ friend class VMStructs;
++
++ G1HeapRegionTable _regions;
++
++ G1RegionToSpaceMapper* _heap_mapper;
++ G1RegionToSpaceMapper* _prev_bitmap_mapper;
++ G1RegionToSpaceMapper* _next_bitmap_mapper;
++ G1RegionToSpaceMapper* _bot_mapper;
++ G1RegionToSpaceMapper* _cardtable_mapper;
++ G1RegionToSpaceMapper* _card_counts_mapper;
++
++ FreeRegionList _free_list;
++
++ // Each bit in this bitmap indicates that the corresponding region is available
++ // for allocation.
++ BitMap _available_map;
++
++ // The number of regions committed in the heap.
++ uint _num_committed;
++
++ // Internal only. The highest heap region +1 we allocated a HeapRegion instance for.
++ uint _allocated_heapregions_length;
++
++ HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); }
++ HeapWord* heap_end() const {return _regions.end_address_mapped(); }
++
++ void make_regions_available(uint index, uint num_regions = 1);
++
++ // Pass down commit calls to the VirtualSpace.
++ void commit_regions(uint index, size_t num_regions = 1);
++ void uncommit_regions(uint index, size_t num_regions = 1);
++
++ // Notify other data structures about change in the heap layout.
++ void update_committed_space(HeapWord* old_end, HeapWord* new_end);
++ // Calculate the starting region for each worker during parallel iteration so
++ // that they do not all start from the same region.
++ uint start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const;
++
++ // Find a contiguous set of empty or uncommitted regions of length num and return
++ // the index of the first region or G1_NO_HRM_INDEX if the search was unsuccessful.
++ // If only_empty is true, only empty regions are considered.
++ // Searches from bottom to top of the heap, doing a first-fit.
++ uint find_contiguous(size_t num, bool only_empty);
++ // Finds the next sequence of unavailable regions starting from start_idx. Returns the
++ // length of the sequence found. If this result is zero, no such sequence could be found,
++ // otherwise res_idx indicates the start index of these regions.
++ uint find_unavailable_from_idx(uint start_idx, uint* res_idx) const;
++ // Finds the next sequence of empty regions starting from start_idx, going backwards in
++ // the heap. Returns the length of the sequence found. If this value is zero, no
++ // sequence could be found, otherwise res_idx contains the start index of this range.
++ uint find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const;
++ // Allocate a new HeapRegion for the given index.
++ HeapRegion* new_heap_region(uint hrm_index);
++#ifdef ASSERT
++public:
++ bool is_free(HeapRegion* hr) const;
++#endif
++ // Returns whether the given region is available for allocation.
++ bool is_available(uint region) const;
++
++ public:
++ // Empty constructor, we'll initialize it with the initialize() method.
++ HeapRegionManager() : _regions(), _heap_mapper(NULL), _num_committed(0),
++ _next_bitmap_mapper(NULL), _prev_bitmap_mapper(NULL), _bot_mapper(NULL),
++ _allocated_heapregions_length(0), _available_map(),
++ _free_list("Free list", new MasterFreeRegionListMtSafeChecker())
++ { }
++
++ void initialize(G1RegionToSpaceMapper* heap_storage,
++ G1RegionToSpaceMapper* prev_bitmap,
++ G1RegionToSpaceMapper* next_bitmap,
++ G1RegionToSpaceMapper* bot,
++ G1RegionToSpaceMapper* cardtable,
++ G1RegionToSpaceMapper* card_counts);
++
++ // Return the "dummy" region used for G1AllocRegion. This is currently a hardwired
++ // new HeapRegion that owns HeapRegion at index 0. Since at the moment we commit
++ // the heap from the lowest address, this region (and its associated data
++ // structures) are available and we do not need to check further.
++ HeapRegion* get_dummy_region() { return new_heap_region(0); }
++
++ // Return the HeapRegion at the given index. Assume that the index
++ // is valid.
++ inline HeapRegion* at(uint index) const;
++
++ // If addr is within the committed space return its corresponding
++ // HeapRegion, otherwise return NULL.
++ inline HeapRegion* addr_to_region(HeapWord* addr) const;
++
++ // Insert the given region into the free region list.
++ inline void insert_into_free_list(HeapRegion* hr);
++
++ // Insert the given region list into the global free region list.
++ void insert_list_into_free_list(FreeRegionList* list) {
++ _free_list.add_ordered(list);
++ }
++
++ HeapRegion* allocate_free_region(bool is_old) {
++ HeapRegion* hr = _free_list.remove_region(is_old);
++
++ if (hr != NULL) {
++ assert(hr->next() == NULL, "Single region should not have next");
++ assert(is_available(hr->hrm_index()), "Must be committed");
++ }
++ return hr;
++ }
++
++ inline void allocate_free_regions_starting_at(uint first, uint num_regions);
++
++ // Remove all regions from the free list.
++ void remove_all_free_regions() {
++ _free_list.remove_all();
++ }
++
++ // Return the number of committed free regions in the heap.
++ uint num_free_regions() const {
++ return _free_list.length();
++ }
++
++ size_t total_capacity_bytes() const {
++ return num_free_regions() * HeapRegion::GrainBytes;
++ }
++
++ // Return the number of available (uncommitted) regions.
++ uint available() const { return max_length() - length(); }
++
++ // Return the number of regions that have been committed in the heap.
++ uint length() const { return _num_committed; }
++
++ // Return the maximum number of regions in the heap.
++ uint max_length() const { return (uint)_regions.length(); }
++
++ MemRegion reserved() const { return MemRegion(heap_bottom(), heap_end()); }
++
++ // Expand the sequence to reflect that the heap has grown. Either create new
++ // HeapRegions, or re-use existing ones. Returns the number of regions the
++ // sequence was expanded by. If a HeapRegion allocation fails, the resulting
++ // number of regions might be smaller than what's desired.
++ uint expand_by(uint num_regions);
++
++ // Makes sure that the regions from start to start+num_regions-1 are available
++ // for allocation. Returns the number of regions that were committed to achieve
++ // this.
++ uint expand_at(uint start, uint num_regions);
++
++ // Find a contiguous set of empty regions of length num. Returns the start index of
++ // that set, or G1_NO_HRM_INDEX.
++ uint find_contiguous_only_empty(size_t num) { return find_contiguous(num, true); }
++ // Find a contiguous set of empty or unavailable regions of length num. Returns the
++ // start index of that set, or G1_NO_HRM_INDEX.
++ uint find_contiguous_empty_or_unavailable(size_t num) { return find_contiguous(num, false); }
++
++ HeapRegion* next_region_in_heap(const HeapRegion* r) const;
++
++ // Apply blk->doHeapRegion() on all committed regions in address order,
++ // terminating the iteration early if doHeapRegion() returns true.
++ void iterate(HeapRegionClosure* blk) const;
++
++ void par_iterate(HeapRegionClosure* blk, uint worker_id, uint no_of_par_workers, jint claim_value) const;
++
++ // Uncommit up to num_regions_to_remove regions that are completely free.
++ // Return the actual number of uncommitted regions.
++ uint shrink_by(uint num_regions_to_remove);
++
++ void verify();
++
++ // Do some sanity checking.
++ void verify_optional() PRODUCT_RETURN;
++};
++
++#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,58 @@
++/*
++ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_INLINE_HPP
++#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_INLINE_HPP
++
++#include "gc_implementation/g1/heapRegion.hpp"
++#include "gc_implementation/g1/heapRegionManager.hpp"
++#include "gc_implementation/g1/heapRegionSet.inline.hpp"
++
++inline HeapRegion* HeapRegionManager::addr_to_region(HeapWord* addr) const {
++ assert(addr < heap_end(),
++ err_msg("addr: "PTR_FORMAT" end: "PTR_FORMAT, p2i(addr), p2i(heap_end())));
++ assert(addr >= heap_bottom(),
++ err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, p2i(addr), p2i(heap_bottom())));
++
++ HeapRegion* hr = _regions.get_by_address(addr);
++ return hr;
++}
++
++inline HeapRegion* HeapRegionManager::at(uint index) const {
++ assert(is_available(index), "pre-condition");
++ HeapRegion* hr = _regions.get_by_index(index);
++ assert(hr != NULL, "sanity");
++ assert(hr->hrm_index() == index, "sanity");
++ return hr;
++}
++
++inline void HeapRegionManager::insert_into_free_list(HeapRegion* hr) {
++ _free_list.add_ordered(hr);
++}
++
++inline void HeapRegionManager::allocate_free_regions_starting_at(uint first, uint num_regions) {
++ _free_list.remove_starting_at(at(first), num_regions);
++}
++
++#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_INLINE_HPP
+--- ./hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -27,7 +27,7 @@
+ #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
+ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+ #include "gc_implementation/g1/heapRegionRemSet.hpp"
+-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
++#include "gc_implementation/g1/heapRegionManager.inline.hpp"
+ #include "memory/allocation.hpp"
+ #include "memory/padded.inline.hpp"
+ #include "memory/space.inline.hpp"
+@@ -169,7 +169,7 @@
+
+ // Mem size in bytes.
+ size_t mem_size() const {
+- return sizeof(this) + _bm.size_in_words() * HeapWordSize;
++ return sizeof(PerRegionTable) + _bm.size_in_words() * HeapWordSize;
+ }
+
+ // Requires "from" to be in "hr()".
+@@ -288,7 +288,7 @@
+ }
+
+ _fine_grain_regions = NEW_C_HEAP_ARRAY3(PerRegionTablePtr, _max_fine_entries,
+- mtGC, 0, AllocFailStrategy::RETURN_NULL);
++ mtGC, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
+
+ if (_fine_grain_regions == NULL) {
+ vm_exit_out_of_memory(sizeof(void*)*_max_fine_entries, OOM_MALLOC_ERROR,
+@@ -372,17 +372,17 @@
+ _max_regions,
+ &_static_mem_size);
+
+- for (uint i = 0; i < n_par_rs; i++) {
+- for (uint j = 0; j < _max_regions; j++) {
+- set(i, j, InvalidCard);
+- }
+- }
++ invalidate(0, _max_regions);
+ }
+
+-void FromCardCache::shrink(uint new_num_regions) {
++void FromCardCache::invalidate(uint start_idx, size_t new_num_regions) {
++ guarantee((size_t)start_idx + new_num_regions <= max_uintx,
++ err_msg("Trying to invalidate beyond maximum region, from %u size "SIZE_FORMAT,
++ start_idx, new_num_regions));
+ for (uint i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
+- assert(new_num_regions <= _max_regions, "Must be within max.");
+- for (uint j = new_num_regions; j < _max_regions; j++) {
++ uint end_idx = (start_idx + (uint)new_num_regions);
++ assert(end_idx <= _max_regions, "Must be within max.");
++ for (uint j = start_idx; j < end_idx; j++) {
+ set(i, j, InvalidCard);
+ }
+ }
+@@ -406,12 +406,12 @@
+ }
+ }
+
+-void OtherRegionsTable::init_from_card_cache(uint max_regions) {
++void OtherRegionsTable::initialize(uint max_regions) {
+ FromCardCache::initialize(HeapRegionRemSet::num_par_rem_sets(), max_regions);
+ }
+
+-void OtherRegionsTable::shrink_from_card_cache(uint new_num_regions) {
+- FromCardCache::shrink(new_num_regions);
++void OtherRegionsTable::invalidate(uint start_idx, size_t num_regions) {
++ FromCardCache::invalidate(start_idx, num_regions);
+ }
+
+ void OtherRegionsTable::print_from_card_cache() {
+@@ -419,7 +419,7 @@
+ }
+
+ void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) {
+- uint cur_hrs_ind = hr()->hrs_index();
++ uint cur_hrm_ind = hr()->hrm_index();
+
+ if (G1TraceHeapRegionRememberedSet) {
+ gclog_or_tty->print_cr("ORT::add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").",
+@@ -434,10 +434,10 @@
+ if (G1TraceHeapRegionRememberedSet) {
+ gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = "INT32_FORMAT")",
+ hr()->bottom(), from_card,
+- FromCardCache::at((uint)tid, cur_hrs_ind));
++ FromCardCache::at((uint)tid, cur_hrm_ind));
+ }
+
+- if (FromCardCache::contains_or_replace((uint)tid, cur_hrs_ind, from_card)) {
++ if (FromCardCache::contains_or_replace((uint)tid, cur_hrm_ind, from_card)) {
+ if (G1TraceHeapRegionRememberedSet) {
+ gclog_or_tty->print_cr(" from-card cache hit.");
+ }
+@@ -447,10 +447,10 @@
+
+ // Note that this may be a continued H region.
+ HeapRegion* from_hr = _g1h->heap_region_containing_raw(from);
+- RegionIdx_t from_hrs_ind = (RegionIdx_t) from_hr->hrs_index();
++ RegionIdx_t from_hrm_ind = (RegionIdx_t) from_hr->hrm_index();
+
+ // If the region is already coarsened, return.
+- if (_coarse_map.at(from_hrs_ind)) {
++ if (_coarse_map.at(from_hrm_ind)) {
+ if (G1TraceHeapRegionRememberedSet) {
+ gclog_or_tty->print_cr(" coarse map hit.");
+ }
+@@ -459,7 +459,7 @@
+ }
+
+ // Otherwise find a per-region table to add it to.
+- size_t ind = from_hrs_ind & _mod_max_fine_entries_mask;
++ size_t ind = from_hrm_ind & _mod_max_fine_entries_mask;
+ PerRegionTable* prt = find_region_table(ind, from_hr);
+ if (prt == NULL) {
+ MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
+@@ -474,7 +474,7 @@
+ assert(0 <= card_index && (size_t)card_index < HeapRegion::CardsPerRegion,
+ "Must be in range.");
+ if (G1HRRSUseSparseTable &&
+- _sparse_table.add_card(from_hrs_ind, card_index)) {
++ _sparse_table.add_card(from_hrm_ind, card_index)) {
+ if (G1RecordHRRSOops) {
+ HeapRegionRemSet::record(hr(), from);
+ if (G1TraceHeapRegionRememberedSet) {
+@@ -493,8 +493,8 @@
+ } else {
+ if (G1TraceHeapRegionRememberedSet) {
+ gclog_or_tty->print_cr(" [tid %d] sparse table entry "
+- "overflow(f: %d, t: %d)",
+- tid, from_hrs_ind, cur_hrs_ind);
++ "overflow(f: %d, t: %u)",
++ tid, from_hrm_ind, cur_hrm_ind);
+ }
+ }
+
+@@ -515,7 +515,7 @@
+
+ if (G1HRRSUseSparseTable) {
+ // Transfer from sparse to fine-grain.
+- SparsePRTEntry *sprt_entry = _sparse_table.get_entry(from_hrs_ind);
++ SparsePRTEntry *sprt_entry = _sparse_table.get_entry(from_hrm_ind);
+ assert(sprt_entry != NULL, "There should have been an entry");
+ for (int i = 0; i < SparsePRTEntry::cards_num(); i++) {
+ CardIdx_t c = sprt_entry->card(i);
+@@ -524,7 +524,7 @@
+ }
+ }
+ // Now we can delete the sparse entry.
+- bool res = _sparse_table.delete_entry(from_hrs_ind);
++ bool res = _sparse_table.delete_entry(from_hrm_ind);
+ assert(res, "It should have been there.");
+ }
+ }
+@@ -606,9 +606,9 @@
+ guarantee(max != NULL, "Since _n_fine_entries > 0");
+
+ // Set the corresponding coarse bit.
+- size_t max_hrs_index = (size_t) max->hr()->hrs_index();
+- if (!_coarse_map.at(max_hrs_index)) {
+- _coarse_map.at_put(max_hrs_index, true);
++ size_t max_hrm_index = (size_t) max->hr()->hrm_index();
++ if (!_coarse_map.at(max_hrm_index)) {
++ _coarse_map.at_put(max_hrm_index, true);
+ _n_coarse_entries++;
+ if (G1TraceHeapRegionRememberedSet) {
+ gclog_or_tty->print("Coarsened entry in region [" PTR_FORMAT "...] "
+@@ -632,7 +632,7 @@
+ BitMap* region_bm, BitMap* card_bm) {
+ // First eliminated garbage regions from the coarse map.
+ if (G1RSScrubVerbose) {
+- gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrs_index());
++ gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrm_index());
+ }
+
+ assert(_coarse_map.size() == region_bm->size(), "Precondition");
+@@ -655,9 +655,9 @@
+ // If the entire region is dead, eliminate.
+ if (G1RSScrubVerbose) {
+ gclog_or_tty->print_cr(" For other region %u:",
+- cur->hr()->hrs_index());
++ cur->hr()->hrm_index());
+ }
+- if (!region_bm->at((size_t) cur->hr()->hrs_index())) {
++ if (!region_bm->at((size_t) cur->hr()->hrm_index())) {
+ *prev = nxt;
+ cur->set_collision_list_next(NULL);
+ _n_fine_entries--;
+@@ -694,6 +694,9 @@
+ clear_fcc();
+ }
+
++bool OtherRegionsTable::is_empty() const {
++ return occ_sparse() == 0 && occ_coarse() == 0 && _first_all_fine_prts == NULL;
++}
+
+ size_t OtherRegionsTable::occupied() const {
+ size_t sum = occ_fine();
+@@ -735,7 +738,7 @@
+ sum += (sizeof(PerRegionTable*) * _max_fine_entries);
+ sum += (_coarse_map.size_in_words() * HeapWordSize);
+ sum += (_sparse_table.mem_size());
+- sum += sizeof(*this) - sizeof(_sparse_table); // Avoid double counting above.
++ sum += sizeof(OtherRegionsTable) - sizeof(_sparse_table); // Avoid double counting above.
+ return sum;
+ }
+
+@@ -748,7 +751,7 @@
+ }
+
+ void OtherRegionsTable::clear_fcc() {
+- FromCardCache::clear(hr()->hrs_index());
++ FromCardCache::clear(hr()->hrm_index());
+ }
+
+ void OtherRegionsTable::clear() {
+@@ -770,30 +773,6 @@
+ clear_fcc();
+ }
+
+-void OtherRegionsTable::clear_incoming_entry(HeapRegion* from_hr) {
+- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
+- size_t hrs_ind = (size_t) from_hr->hrs_index();
+- size_t ind = hrs_ind & _mod_max_fine_entries_mask;
+- if (del_single_region_table(ind, from_hr)) {
+- assert(!_coarse_map.at(hrs_ind), "Inv");
+- } else {
+- _coarse_map.par_at_put(hrs_ind, 0);
+- }
+- // Check to see if any of the fcc entries come from here.
+- uint hr_ind = hr()->hrs_index();
+- for (uint tid = 0; tid < HeapRegionRemSet::num_par_rem_sets(); tid++) {
+- int fcc_ent = FromCardCache::at(tid, hr_ind);
+- if (fcc_ent != FromCardCache::InvalidCard) {
+- HeapWord* card_addr = (HeapWord*)
+- (uintptr_t(fcc_ent) << CardTableModRefBS::card_shift);
+- if (hr()->is_in_reserved(card_addr)) {
+- // Clear the from card cache.
+- FromCardCache::set(tid, hr_ind, FromCardCache::InvalidCard);
+- }
+- }
+- }
+-}
+-
+ bool OtherRegionsTable::del_single_region_table(size_t ind,
+ HeapRegion* hr) {
+ assert(0 <= ind && ind < _max_fine_entries, "Preconditions.");
+@@ -823,8 +802,7 @@
+
+ bool OtherRegionsTable::contains_reference_locked(OopOrNarrowOopStar from) const {
+ HeapRegion* hr = _g1h->heap_region_containing_raw(from);
+- if (hr == NULL) return false;
+- RegionIdx_t hr_ind = (RegionIdx_t) hr->hrs_index();
++ RegionIdx_t hr_ind = (RegionIdx_t) hr->hrm_index();
+ // Is this region in the coarse map?
+ if (_coarse_map.at(hr_ind)) return true;
+
+@@ -861,8 +839,8 @@
+ HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa,
+ HeapRegion* hr)
+ : _bosa(bosa),
+- _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #"UINT32_FORMAT, hr->hrs_index()), true),
+- _code_roots(), _other_regions(hr, &_m) {
++ _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrm_index()), true),
++ _code_roots(), _other_regions(hr, &_m), _iter_state(Unclaimed), _iter_claimed(0) {
+ reset_for_par_iteration();
+ }
+
+@@ -945,123 +923,61 @@
+ }
+
+ // Code roots support
++//
++// The code root set is protected by two separate locking schemes
++// When at safepoint the per-hrrs lock must be held during modifications
++// except when doing a full gc.
++// When not at safepoint the CodeCache_lock must be held during modifications.
++// When concurrent readers access the contains() function
++// (during the evacuation phase) no removals are allowed.
+
+ void HeapRegionRemSet::add_strong_code_root(nmethod* nm) {
+ assert(nm != NULL, "sanity");
++ // Optimistic unlocked contains-check
++ if (!_code_roots.contains(nm)) {
++ MutexLockerEx ml(&_m, Mutex::_no_safepoint_check_flag);
++ add_strong_code_root_locked(nm);
++ }
++}
++
++void HeapRegionRemSet::add_strong_code_root_locked(nmethod* nm) {
++ assert(nm != NULL, "sanity");
+ _code_roots.add(nm);
+ }
+
+ void HeapRegionRemSet::remove_strong_code_root(nmethod* nm) {
+ assert(nm != NULL, "sanity");
++ assert_locked_or_safepoint(CodeCache_lock);
++
++ MutexLockerEx ml(CodeCache_lock->owned_by_self() ? NULL : &_m, Mutex::_no_safepoint_check_flag);
+ _code_roots.remove(nm);
++
+ // Check that there were no duplicates
+ guarantee(!_code_roots.contains(nm), "duplicate entry found");
+ }
+
+-class NMethodMigrationOopClosure : public OopClosure {
+- G1CollectedHeap* _g1h;
+- HeapRegion* _from;
+- nmethod* _nm;
+-
+- uint _num_self_forwarded;
+-
+- template <class T> void do_oop_work(T* p) {
+- T heap_oop = oopDesc::load_heap_oop(p);
+- if (!oopDesc::is_null(heap_oop)) {
+- oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+- if (_from->is_in(obj)) {
+- // Reference still points into the source region.
+- // Since roots are immediately evacuated this means that
+- // we must have self forwarded the object
+- assert(obj->is_forwarded(),
+- err_msg("code roots should be immediately evacuated. "
+- "Ref: "PTR_FORMAT", "
+- "Obj: "PTR_FORMAT", "
+- "Region: "HR_FORMAT,
+- p, (void*) obj, HR_FORMAT_PARAMS(_from)));
+- assert(obj->forwardee() == obj,
+- err_msg("not self forwarded? obj = "PTR_FORMAT, (void*)obj));
+-
+- // The object has been self forwarded.
+- // Note, if we're during an initial mark pause, there is
+- // no need to explicitly mark object. It will be marked
+- // during the regular evacuation failure handling code.
+- _num_self_forwarded++;
+- } else {
+- // The reference points into a promotion or to-space region
+- HeapRegion* to = _g1h->heap_region_containing(obj);
+- to->rem_set()->add_strong_code_root(_nm);
+- }
+- }
+- }
+-
+-public:
+- NMethodMigrationOopClosure(G1CollectedHeap* g1h, HeapRegion* from, nmethod* nm):
+- _g1h(g1h), _from(from), _nm(nm), _num_self_forwarded(0) {}
+-
+- void do_oop(narrowOop* p) { do_oop_work(p); }
+- void do_oop(oop* p) { do_oop_work(p); }
+-
+- uint retain() { return _num_self_forwarded > 0; }
+-};
+-
+-void HeapRegionRemSet::migrate_strong_code_roots() {
+- assert(hr()->in_collection_set(), "only collection set regions");
+- assert(!hr()->isHumongous(),
+- err_msg("humongous region "HR_FORMAT" should not have been added to the collection set",
+- HR_FORMAT_PARAMS(hr())));
+-
+- ResourceMark rm;
+-
+- // List of code blobs to retain for this region
+- GrowableArray<nmethod*> to_be_retained(10);
+- G1CollectedHeap* g1h = G1CollectedHeap::heap();
+-
+- while (!_code_roots.is_empty()) {
+- nmethod *nm = _code_roots.pop();
+- if (nm != NULL) {
+- NMethodMigrationOopClosure oop_cl(g1h, hr(), nm);
+- nm->oops_do(&oop_cl);
+- if (oop_cl.retain()) {
+- to_be_retained.push(nm);
+- }
+- }
+- }
+-
+- // Now push any code roots we need to retain
+- assert(to_be_retained.is_empty() || hr()->evacuation_failed(),
+- "Retained nmethod list must be empty or "
+- "evacuation of this region failed");
+-
+- while (to_be_retained.is_nonempty()) {
+- nmethod* nm = to_be_retained.pop();
+- assert(nm != NULL, "sanity");
+- add_strong_code_root(nm);
+- }
+-}
+-
+ void HeapRegionRemSet::strong_code_roots_do(CodeBlobClosure* blk) const {
+ _code_roots.nmethods_do(blk);
+ }
+
++void HeapRegionRemSet::clean_strong_code_roots(HeapRegion* hr) {
++ _code_roots.clean(hr);
++}
++
+ size_t HeapRegionRemSet::strong_code_roots_mem_size() {
+ return _code_roots.mem_size();
+ }
+
+-//-------------------- Iteration --------------------
+-
+ HeapRegionRemSetIterator:: HeapRegionRemSetIterator(HeapRegionRemSet* hrrs) :
+ _hrrs(hrrs),
+ _g1h(G1CollectedHeap::heap()),
+ _coarse_map(&hrrs->_other_regions._coarse_map),
+- _fine_grain_regions(hrrs->_other_regions._fine_grain_regions),
+ _bosa(hrrs->bosa()),
+ _is(Sparse),
+ // Set these values so that we increment to the first region.
+ _coarse_cur_region_index(-1),
+ _coarse_cur_region_cur_card(HeapRegion::CardsPerRegion-1),
+- _cur_region_cur_card(0),
+- _fine_array_index(-1),
++ _cur_card_in_prt(HeapRegion::CardsPerRegion),
+ _fine_cur_prt(NULL),
+ _n_yielded_coarse(0),
+ _n_yielded_fine(0),
+@@ -1093,58 +1009,59 @@
+ return true;
+ }
+
+-void HeapRegionRemSetIterator::fine_find_next_non_null_prt() {
+- // Otherwise, find the next bucket list in the array.
+- _fine_array_index++;
+- while (_fine_array_index < (int) OtherRegionsTable::_max_fine_entries) {
+- _fine_cur_prt = _fine_grain_regions[_fine_array_index];
+- if (_fine_cur_prt != NULL) return;
+- else _fine_array_index++;
+- }
+- assert(_fine_cur_prt == NULL, "Loop post");
+-}
+-
+ bool HeapRegionRemSetIterator::fine_has_next(size_t& card_index) {
+ if (fine_has_next()) {
+- _cur_region_cur_card =
+- _fine_cur_prt->_bm.get_next_one_offset(_cur_region_cur_card + 1);
++ _cur_card_in_prt =
++ _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1);
+ }
+- while (!fine_has_next()) {
+- if (_cur_region_cur_card == (size_t) HeapRegion::CardsPerRegion) {
+- _cur_region_cur_card = 0;
+- _fine_cur_prt = _fine_cur_prt->collision_list_next();
++ if (_cur_card_in_prt == HeapRegion::CardsPerRegion) {
++ // _fine_cur_prt may still be NULL in case if there are not PRTs at all for
++ // the remembered set.
++ if (_fine_cur_prt == NULL || _fine_cur_prt->next() == NULL) {
++ return false;
+ }
+- if (_fine_cur_prt == NULL) {
+- fine_find_next_non_null_prt();
+- if (_fine_cur_prt == NULL) return false;
+- }
+- assert(_fine_cur_prt != NULL && _cur_region_cur_card == 0,
+- "inv.");
+- HeapWord* r_bot =
+- _fine_cur_prt->hr()->bottom();
+- _cur_region_card_offset = _bosa->index_for(r_bot);
+- _cur_region_cur_card = _fine_cur_prt->_bm.get_next_one_offset(0);
++ PerRegionTable* next_prt = _fine_cur_prt->next();
++ switch_to_prt(next_prt);
++ _cur_card_in_prt = _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1);
+ }
+- assert(fine_has_next(), "Or else we exited the loop via the return.");
+- card_index = _cur_region_card_offset + _cur_region_cur_card;
++
++ card_index = _cur_region_card_offset + _cur_card_in_prt;
++ guarantee(_cur_card_in_prt < HeapRegion::CardsPerRegion,
++ err_msg("Card index "SIZE_FORMAT" must be within the region", _cur_card_in_prt));
+ return true;
+ }
+
+ bool HeapRegionRemSetIterator::fine_has_next() {
+- return
+- _fine_cur_prt != NULL &&
+- _cur_region_cur_card < HeapRegion::CardsPerRegion;
++ return _cur_card_in_prt != HeapRegion::CardsPerRegion;
++}
++
++void HeapRegionRemSetIterator::switch_to_prt(PerRegionTable* prt) {
++ assert(prt != NULL, "Cannot switch to NULL prt");
++ _fine_cur_prt = prt;
++
++ HeapWord* r_bot = _fine_cur_prt->hr()->bottom();
++ _cur_region_card_offset = _bosa->index_for(r_bot);
++
++ // The bitmap scan for the PRT always scans from _cur_region_cur_card + 1.
++ // To avoid special-casing this start case, and not miss the first bitmap
++ // entry, initialize _cur_region_cur_card with -1 instead of 0.
++ _cur_card_in_prt = (size_t)-1;
+ }
+
+ bool HeapRegionRemSetIterator::has_next(size_t& card_index) {
+ switch (_is) {
+- case Sparse:
++ case Sparse: {
+ if (_sparse_iter.has_next(card_index)) {
+ _n_yielded_sparse++;
+ return true;
+ }
+ // Otherwise, deliberate fall-through
+ _is = Fine;
++ PerRegionTable* initial_fine_prt = _hrrs->_other_regions._first_all_fine_prts;
++ if (initial_fine_prt != NULL) {
++ switch_to_prt(_hrrs->_other_regions._first_all_fine_prts);
++ }
++ }
+ case Fine:
+ if (fine_has_next(card_index)) {
+ _n_yielded_fine++;
+@@ -1276,6 +1193,11 @@
+ #ifndef PRODUCT
+ void PerRegionTable::test_fl_mem_size() {
+ PerRegionTable* dummy = alloc(NULL);
++
++ size_t min_prt_size = sizeof(void*) + dummy->bm()->size_in_words() * HeapWordSize;
++ assert(dummy->mem_size() > min_prt_size,
++ err_msg("PerRegionTable memory usage is suspiciously small, only has "SIZE_FORMAT" bytes. "
++ "Should be at least "SIZE_FORMAT" bytes.", dummy->mem_size(), min_prt_size));
+ free(dummy);
+ guarantee(dummy->mem_size() == fl_mem_size(), "fl_mem_size() does not return the correct element size");
+ // try to reset the state
+--- ./hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -84,7 +84,7 @@
+
+ static void initialize(uint n_par_rs, uint max_num_regions);
+
+- static void shrink(uint new_num_regions);
++ static void invalidate(uint start_idx, size_t num_regions);
+
+ static void print(outputStream* out = gclog_or_tty) PRODUCT_RETURN;
+
+@@ -185,6 +185,9 @@
+ // objects.
+ void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm);
+
++ // Returns whether this remembered set (and all sub-sets) contain no entries.
++ bool is_empty() const;
++
+ size_t occupied() const;
+ size_t occ_fine() const;
+ size_t occ_coarse() const;
+@@ -206,18 +209,15 @@
+ // Specifically clear the from_card_cache.
+ void clear_fcc();
+
+- // "from_hr" is being cleared; remove any entries from it.
+- void clear_incoming_entry(HeapRegion* from_hr);
+-
+ void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task);
+
+ // Declare the heap size (in # of regions) to the OtherRegionsTable.
+ // (Uses it to initialize from_card_cache).
+- static void init_from_card_cache(uint max_regions);
++ static void initialize(uint max_regions);
+
+- // Declares that only regions i s.t. 0 <= i < new_n_regs are in use.
+- // Make sure any entries for higher regions are invalid.
+- static void shrink_from_card_cache(uint new_num_regions);
++ // Declares that regions between start_idx <= i < start_idx + num_regions are
++ // not in use. Make sure that any entries for these regions are invalid.
++ static void invalidate(uint start_idx, size_t num_regions);
+
+ static void print_from_card_cache();
+ };
+@@ -272,6 +272,10 @@
+ return _other_regions.hr();
+ }
+
++ bool is_empty() const {
++ return (strong_code_roots_list_length() == 0) && _other_regions.is_empty();
++ }
++
+ size_t occupied() {
+ MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
+ return occupied_locked();
+@@ -342,7 +346,7 @@
+ return _other_regions.mem_size()
+ // This correction is necessary because the above includes the second
+ // part.
+- + (sizeof(this) - sizeof(OtherRegionsTable))
++ + (sizeof(HeapRegionRemSet) - sizeof(OtherRegionsTable))
+ + strong_code_roots_mem_size();
+ }
+
+@@ -355,7 +359,7 @@
+ // Returns the memory occupancy of all free_list data structures associated
+ // with remembered sets.
+ static size_t fl_mem_size() {
+- return OtherRegionsTable::fl_mem_size() + G1CodeRootSet::fl_mem_size();
++ return OtherRegionsTable::fl_mem_size();
+ }
+
+ bool contains_reference(OopOrNarrowOopStar from) const {
+@@ -365,20 +369,17 @@
+ // Routines for managing the list of code roots that point into
+ // the heap region that owns this RSet.
+ void add_strong_code_root(nmethod* nm);
++ void add_strong_code_root_locked(nmethod* nm);
+ void remove_strong_code_root(nmethod* nm);
+
+- // During a collection, migrate the successfully evacuated strong
+- // code roots that referenced into the region that owns this RSet
+- // to the RSets of the new regions that they now point into.
+- // Unsuccessfully evacuated code roots are not migrated.
+- void migrate_strong_code_roots();
+-
+ // Applies blk->do_code_blob() to each of the entries in
+ // the strong code roots list
+ void strong_code_roots_do(CodeBlobClosure* blk) const;
+
++ void clean_strong_code_roots(HeapRegion* hr);
++
+ // Returns the number of elements in the strong code roots list
+- size_t strong_code_roots_list_length() {
++ size_t strong_code_roots_list_length() const {
+ return _code_roots.length();
+ }
+
+@@ -400,13 +401,11 @@
+ // Declare the heap size (in # of regions) to the HeapRegionRemSet(s).
+ // (Uses it to initialize from_card_cache).
+ static void init_heap(uint max_regions) {
+- G1CodeRootSet::initialize();
+- OtherRegionsTable::init_from_card_cache(max_regions);
++ OtherRegionsTable::initialize(max_regions);
+ }
+
+- // Declares that only regions i s.t. 0 <= i < new_n_regs are in use.
+- static void shrink_heap(uint new_n_regs) {
+- OtherRegionsTable::shrink_from_card_cache(new_n_regs);
++ static void invalidate(uint start_idx, uint num_regions) {
++ OtherRegionsTable::invalidate(start_idx, num_regions);
+ }
+
+ #ifndef PRODUCT
+@@ -433,26 +432,24 @@
+ };
+
+ class HeapRegionRemSetIterator : public StackObj {
+-
+- // The region RSet over which we're iterating.
++ private:
++ // The region RSet over which we are iterating.
+ HeapRegionRemSet* _hrrs;
+
+ // Local caching of HRRS fields.
+ const BitMap* _coarse_map;
+- PerRegionTable** _fine_grain_regions;
+
+ G1BlockOffsetSharedArray* _bosa;
+ G1CollectedHeap* _g1h;
+
+- // The number yielded since initialization.
++ // The number of cards yielded since initialization.
+ size_t _n_yielded_fine;
+ size_t _n_yielded_coarse;
+ size_t _n_yielded_sparse;
+
+- // Indicates what granularity of table that we're currently iterating over.
++ // Indicates what granularity of table that we are currently iterating over.
+ // We start iterating over the sparse table, progress to the fine grain
+ // table, and then finish with the coarse table.
+- // See HeapRegionRemSetIterator::has_next().
+ enum IterState {
+ Sparse,
+ Fine,
+@@ -460,38 +457,30 @@
+ };
+ IterState _is;
+
+- // In both kinds of iteration, heap offset of first card of current
+- // region.
++ // For both Coarse and Fine remembered set iteration this contains the
++ // first card number of the heap region we currently iterate over.
+ size_t _cur_region_card_offset;
+- // Card offset within cur region.
+- size_t _cur_region_cur_card;
+
+- // Coarse table iteration fields:
+-
+- // Current region index;
++ // Current region index for the Coarse remembered set iteration.
+ int _coarse_cur_region_index;
+ size_t _coarse_cur_region_cur_card;
+
+ bool coarse_has_next(size_t& card_index);
+
+- // Fine table iteration fields:
++ // The PRT we are currently iterating over.
++ PerRegionTable* _fine_cur_prt;
++ // Card offset within the current PRT.
++ size_t _cur_card_in_prt;
+
+- // Index of bucket-list we're working on.
+- int _fine_array_index;
+-
+- // Per Region Table we're doing within current bucket list.
+- PerRegionTable* _fine_cur_prt;
+-
+- /* SparsePRT::*/ SparsePRTIter _sparse_iter;
+-
+- void fine_find_next_non_null_prt();
+-
++ // Update internal variables when switching to the given PRT.
++ void switch_to_prt(PerRegionTable* prt);
+ bool fine_has_next();
+ bool fine_has_next(size_t& card_index);
+
+-public:
+- // We require an iterator to be initialized before use, so the
+- // constructor does little.
++ // The Sparse remembered set iterator.
++ SparsePRTIter _sparse_iter;
++
++ public:
+ HeapRegionRemSetIterator(HeapRegionRemSet* hrrs);
+
+ // If there remains one or more cards to be yielded, returns true and
+--- ./hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,261 +0,0 @@
+-/*
+- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- *
+- */
+-
+-#include "precompiled.hpp"
+-#include "gc_implementation/g1/heapRegion.hpp"
+-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
+-#include "gc_implementation/g1/heapRegionSet.hpp"
+-#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+-#include "memory/allocation.hpp"
+-
+-// Private
+-
+-uint HeapRegionSeq::find_contiguous_from(uint from, uint num) {
+- uint len = length();
+- assert(num > 1, "use this only for sequences of length 2 or greater");
+- assert(from <= len,
+- err_msg("from: %u should be valid and <= than %u", from, len));
+-
+- uint curr = from;
+- uint first = G1_NULL_HRS_INDEX;
+- uint num_so_far = 0;
+- while (curr < len && num_so_far < num) {
+- if (at(curr)->is_empty()) {
+- if (first == G1_NULL_HRS_INDEX) {
+- first = curr;
+- num_so_far = 1;
+- } else {
+- num_so_far += 1;
+- }
+- } else {
+- first = G1_NULL_HRS_INDEX;
+- num_so_far = 0;
+- }
+- curr += 1;
+- }
+- assert(num_so_far <= num, "post-condition");
+- if (num_so_far == num) {
+- // we found enough space for the humongous object
+- assert(from <= first && first < len, "post-condition");
+- assert(first < curr && (curr - first) == num, "post-condition");
+- for (uint i = first; i < first + num; ++i) {
+- assert(at(i)->is_empty(), "post-condition");
+- }
+- return first;
+- } else {
+- // we failed to find enough space for the humongous object
+- return G1_NULL_HRS_INDEX;
+- }
+-}
+-
+-// Public
+-
+-void HeapRegionSeq::initialize(HeapWord* bottom, HeapWord* end) {
+- assert((uintptr_t) bottom % HeapRegion::GrainBytes == 0,
+- "bottom should be heap region aligned");
+- assert((uintptr_t) end % HeapRegion::GrainBytes == 0,
+- "end should be heap region aligned");
+-
+- _next_search_index = 0;
+- _allocated_length = 0;
+-
+- _regions.initialize(bottom, end, HeapRegion::GrainBytes);
+-}
+-
+-MemRegion HeapRegionSeq::expand_by(HeapWord* old_end,
+- HeapWord* new_end,
+- FreeRegionList* list) {
+- assert(old_end < new_end, "don't call it otherwise");
+- G1CollectedHeap* g1h = G1CollectedHeap::heap();
+-
+- HeapWord* next_bottom = old_end;
+- assert(heap_bottom() <= next_bottom, "invariant");
+- while (next_bottom < new_end) {
+- assert(next_bottom < heap_end(), "invariant");
+- uint index = length();
+-
+- assert(index < max_length(), "otherwise we cannot expand further");
+- if (index == 0) {
+- // We have not allocated any regions so far
+- assert(next_bottom == heap_bottom(), "invariant");
+- } else {
+- // next_bottom should match the end of the last/previous region
+- assert(next_bottom == at(index - 1)->end(), "invariant");
+- }
+-
+- if (index == _allocated_length) {
+- // We have to allocate a new HeapRegion.
+- HeapRegion* new_hr = g1h->new_heap_region(index, next_bottom);
+- if (new_hr == NULL) {
+- // allocation failed, we bail out and return what we have done so far
+- return MemRegion(old_end, next_bottom);
+- }
+- assert(_regions.get_by_index(index) == NULL, "invariant");
+- _regions.set_by_index(index, new_hr);
+- increment_allocated_length();
+- }
+- // Have to increment the length first, otherwise we will get an
+- // assert failure at(index) below.
+- increment_length();
+- HeapRegion* hr = at(index);
+- list->add_as_tail(hr);
+-
+- next_bottom = hr->end();
+- }
+- assert(next_bottom == new_end, "post-condition");
+- return MemRegion(old_end, next_bottom);
+-}
+-
+-uint HeapRegionSeq::free_suffix() {
+- uint res = 0;
+- uint index = length();
+- while (index > 0) {
+- index -= 1;
+- if (!at(index)->is_empty()) {
+- break;
+- }
+- res += 1;
+- }
+- return res;
+-}
+-
+-uint HeapRegionSeq::find_contiguous(uint num) {
+- assert(num > 1, "use this only for sequences of length 2 or greater");
+- assert(_next_search_index <= length(),
+- err_msg("_next_search_index: %u should be valid and <= than %u",
+- _next_search_index, length()));
+-
+- uint start = _next_search_index;
+- uint res = find_contiguous_from(start, num);
+- if (res == G1_NULL_HRS_INDEX && start > 0) {
+- // Try starting from the beginning. If _next_search_index was 0,
+- // no point in doing this again.
+- res = find_contiguous_from(0, num);
+- }
+- if (res != G1_NULL_HRS_INDEX) {
+- assert(res < length(), err_msg("res: %u should be valid", res));
+- _next_search_index = res + num;
+- assert(_next_search_index <= length(),
+- err_msg("_next_search_index: %u should be valid and <= than %u",
+- _next_search_index, length()));
+- }
+- return res;
+-}
+-
+-void HeapRegionSeq::iterate(HeapRegionClosure* blk) const {
+- iterate_from((HeapRegion*) NULL, blk);
+-}
+-
+-void HeapRegionSeq::iterate_from(HeapRegion* hr, HeapRegionClosure* blk) const {
+- uint hr_index = 0;
+- if (hr != NULL) {
+- hr_index = hr->hrs_index();
+- }
+-
+- uint len = length();
+- for (uint i = hr_index; i < len; i += 1) {
+- bool res = blk->doHeapRegion(at(i));
+- if (res) {
+- blk->incomplete();
+- return;
+- }
+- }
+- for (uint i = 0; i < hr_index; i += 1) {
+- bool res = blk->doHeapRegion(at(i));
+- if (res) {
+- blk->incomplete();
+- return;
+- }
+- }
+-}
+-
+-uint HeapRegionSeq::shrink_by(uint num_regions_to_remove) {
+- // Reset this in case it's currently pointing into the regions that
+- // we just removed.
+- _next_search_index = 0;
+-
+- assert(length() > 0, "the region sequence should not be empty");
+- assert(length() <= _allocated_length, "invariant");
+- assert(_allocated_length > 0, "we should have at least one region committed");
+- assert(num_regions_to_remove < length(), "We should never remove all regions");
+-
+- uint i = 0;
+- for (; i < num_regions_to_remove; i++) {
+- HeapRegion* cur = at(length() - 1);
+-
+- if (!cur->is_empty()) {
+- // We have to give up if the region can not be moved
+- break;
+- }
+- assert(!cur->isHumongous(), "Humongous regions should not be empty");
+-
+- decrement_length();
+- }
+- return i;
+-}
+-
+-#ifndef PRODUCT
+-void HeapRegionSeq::verify_optional() {
+- guarantee(length() <= _allocated_length,
+- err_msg("invariant: _length: %u _allocated_length: %u",
+- length(), _allocated_length));
+- guarantee(_allocated_length <= max_length(),
+- err_msg("invariant: _allocated_length: %u _max_length: %u",
+- _allocated_length, max_length()));
+- guarantee(_next_search_index <= length(),
+- err_msg("invariant: _next_search_index: %u _length: %u",
+- _next_search_index, length()));
+-
+- HeapWord* prev_end = heap_bottom();
+- for (uint i = 0; i < _allocated_length; i += 1) {
+- HeapRegion* hr = _regions.get_by_index(i);
+- guarantee(hr != NULL, err_msg("invariant: i: %u", i));
+- guarantee(hr->bottom() == prev_end,
+- err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT,
+- i, HR_FORMAT_PARAMS(hr), p2i(prev_end)));
+- guarantee(hr->hrs_index() == i,
+- err_msg("invariant: i: %u hrs_index(): %u", i, hr->hrs_index()));
+- if (i < length()) {
+- // Asserts will fire if i is >= _length
+- HeapWord* addr = hr->bottom();
+- guarantee(addr_to_region(addr) == hr, "sanity");
+- guarantee(addr_to_region_unsafe(addr) == hr, "sanity");
+- } else {
+- guarantee(hr->is_empty(), "sanity");
+- guarantee(!hr->isHumongous(), "sanity");
+- // using assert instead of guarantee here since containing_set()
+- // is only available in non-product builds.
+- assert(hr->containing_set() == NULL, "sanity");
+- }
+- if (hr->startsHumongous()) {
+- prev_end = hr->orig_end();
+- } else {
+- prev_end = hr->end();
+- }
+- }
+- for (uint i = _allocated_length; i < max_length(); i += 1) {
+- guarantee(_regions.get_by_index(i) == NULL, err_msg("invariant i: %u", i));
+- }
+-}
+-#endif // PRODUCT
+--- ./hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,158 +0,0 @@
+-/*
+- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- *
+- */
+-
+-#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP
+-#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP
+-
+-#include "gc_implementation/g1/g1BiasedArray.hpp"
+-
+-class HeapRegion;
+-class HeapRegionClosure;
+-class FreeRegionList;
+-
+-class G1HeapRegionTable : public G1BiasedMappedArray<HeapRegion*> {
+- protected:
+- virtual HeapRegion* default_value() const { return NULL; }
+-};
+-
+-// This class keeps track of the region metadata (i.e., HeapRegion
+-// instances). They are kept in the _regions array in address
+-// order. A region's index in the array corresponds to its index in
+-// the heap (i.e., 0 is the region at the bottom of the heap, 1 is
+-// the one after it, etc.). Two regions that are consecutive in the
+-// array should also be adjacent in the address space (i.e.,
+-// region(i).end() == region(i+1).bottom().
+-//
+-// We create a HeapRegion when we commit the region's address space
+-// for the first time. When we uncommit the address space of a
+-// region we retain the HeapRegion to be able to re-use it in the
+-// future (in case we recommit it).
+-//
+-// We keep track of three lengths:
+-//
+-// * _committed_length (returned by length()) is the number of currently
+-// committed regions.
+-// * _allocated_length (not exposed outside this class) is the
+-// number of regions for which we have HeapRegions.
+-// * max_length() returns the maximum number of regions the heap can have.
+-//
+-// and maintain that: _committed_length <= _allocated_length <= max_length()
+-
+-class HeapRegionSeq: public CHeapObj<mtGC> {
+- friend class VMStructs;
+-
+- G1HeapRegionTable _regions;
+-
+- // The number of regions committed in the heap.
+- uint _committed_length;
+-
+- // A hint for which index to start searching from for humongous
+- // allocations.
+- uint _next_search_index;
+-
+- // The number of regions for which we have allocated HeapRegions for.
+- uint _allocated_length;
+-
+- // Find a contiguous set of empty regions of length num, starting
+- // from the given index.
+- uint find_contiguous_from(uint from, uint num);
+-
+- void increment_allocated_length() {
+- assert(_allocated_length < max_length(), "pre-condition");
+- _allocated_length++;
+- }
+-
+- void increment_length() {
+- assert(length() < max_length(), "pre-condition");
+- _committed_length++;
+- }
+-
+- void decrement_length() {
+- assert(length() > 0, "pre-condition");
+- _committed_length--;
+- }
+-
+- HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); }
+- HeapWord* heap_end() const {return _regions.end_address_mapped(); }
+-
+- public:
+- // Empty contructor, we'll initialize it with the initialize() method.
+- HeapRegionSeq() : _regions(), _committed_length(0), _next_search_index(0), _allocated_length(0) { }
+-
+- void initialize(HeapWord* bottom, HeapWord* end);
+-
+- // Return the HeapRegion at the given index. Assume that the index
+- // is valid.
+- inline HeapRegion* at(uint index) const;
+-
+- // If addr is within the committed space return its corresponding
+- // HeapRegion, otherwise return NULL.
+- inline HeapRegion* addr_to_region(HeapWord* addr) const;
+-
+- // Return the HeapRegion that corresponds to the given
+- // address. Assume the address is valid.
+- inline HeapRegion* addr_to_region_unsafe(HeapWord* addr) const;
+-
+- // Return the number of regions that have been committed in the heap.
+- uint length() const { return _committed_length; }
+-
+- // Return the maximum number of regions in the heap.
+- uint max_length() const { return (uint)_regions.length(); }
+-
+- // Expand the sequence to reflect that the heap has grown from
+- // old_end to new_end. Either create new HeapRegions, or re-use
+- // existing ones, and return them in the given list. Returns the
+- // memory region that covers the newly-created regions. If a
+- // HeapRegion allocation fails, the result memory region might be
+- // smaller than the desired one.
+- MemRegion expand_by(HeapWord* old_end, HeapWord* new_end,
+- FreeRegionList* list);
+-
+- // Return the number of contiguous regions at the end of the sequence
+- // that are available for allocation.
+- uint free_suffix();
+-
+- // Find a contiguous set of empty regions of length num and return
+- // the index of the first region or G1_NULL_HRS_INDEX if the
+- // search was unsuccessful.
+- uint find_contiguous(uint num);
+-
+- // Apply blk->doHeapRegion() on all committed regions in address order,
+- // terminating the iteration early if doHeapRegion() returns true.
+- void iterate(HeapRegionClosure* blk) const;
+-
+- // As above, but start the iteration from hr and loop around. If hr
+- // is NULL, we start from the first region in the heap.
+- void iterate_from(HeapRegion* hr, HeapRegionClosure* blk) const;
+-
+- // Tag as uncommitted as many regions that are completely free as
+- // possible, up to num_regions_to_remove, from the suffix of the committed
+- // sequence. Return the actual number of removed regions.
+- uint shrink_by(uint num_regions_to_remove);
+-
+- // Do some sanity checking.
+- void verify_optional() PRODUCT_RETURN;
+-};
+-
+-#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP
+--- ./hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,54 +0,0 @@
+-/*
+- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- *
+- */
+-
+-#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_INLINE_HPP
+-#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_INLINE_HPP
+-
+-#include "gc_implementation/g1/heapRegion.hpp"
+-#include "gc_implementation/g1/heapRegionSeq.hpp"
+-
+-inline HeapRegion* HeapRegionSeq::addr_to_region_unsafe(HeapWord* addr) const {
+- HeapRegion* hr = _regions.get_by_address(addr);
+- assert(hr != NULL, "invariant");
+- return hr;
+-}
+-
+-inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const {
+- if (addr != NULL && addr < heap_end()) {
+- assert(addr >= heap_bottom(),
+- err_msg("addr: " PTR_FORMAT " bottom: " PTR_FORMAT, p2i(addr), p2i(heap_bottom())));
+- return addr_to_region_unsafe(addr);
+- }
+- return NULL;
+-}
+-
+-inline HeapRegion* HeapRegionSeq::at(uint index) const {
+- assert(index < length(), "pre-condition");
+- HeapRegion* hr = _regions.get_by_index(index);
+- assert(hr != NULL, "sanity");
+- assert(hr->hrs_index() == index, "sanity");
+- return hr;
+-}
+-
+-#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_INLINE_HPP
+--- ./hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -23,6 +23,7 @@
+ */
+
+ #include "precompiled.hpp"
++#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+ #include "gc_implementation/g1/heapRegionRemSet.hpp"
+ #include "gc_implementation/g1/heapRegionSet.inline.hpp"
+
+@@ -38,11 +39,13 @@
+
+ #ifndef PRODUCT
+ void HeapRegionSetBase::verify_region(HeapRegion* hr) {
+- assert(hr->containing_set() == this, err_msg("Inconsistent containing set for %u", hr->hrs_index()));
+- assert(!hr->is_young(), err_msg("Adding young region %u", hr->hrs_index())); // currently we don't use these sets for young regions
+- assert(hr->isHumongous() == regions_humongous(), err_msg("Wrong humongous state for region %u and set %s", hr->hrs_index(), name()));
+- assert(hr->is_empty() == regions_empty(), err_msg("Wrong empty state for region %u and set %s", hr->hrs_index(), name()));
+- assert(hr->rem_set()->verify_ready_for_par_iteration(), err_msg("Wrong iteration state %u", hr->hrs_index()));
++ assert(hr->containing_set() == this, err_msg("Inconsistent containing set for %u", hr->hrm_index()));
++ assert(!hr->is_young(), err_msg("Adding young region %u", hr->hrm_index())); // currently we don't use these sets for young regions
++ assert(hr->isHumongous() == regions_humongous(), err_msg("Wrong humongous state for region %u and set %s", hr->hrm_index(), name()));
++ assert(hr->is_free() == regions_free(), err_msg("Wrong free state for region %u and set %s", hr->hrm_index(), name()));
++ assert(!hr->is_free() || hr->is_empty(), err_msg("Free region %u is not empty for set %s", hr->hrm_index(), name()));
++ assert(!hr->is_empty() || hr->is_free(), err_msg("Empty region %u is not free for set %s", hr->hrm_index(), name()));
++ assert(hr->rem_set()->verify_ready_for_par_iteration(), err_msg("Wrong iteration state %u", hr->hrm_index()));
+ }
+ #endif
+
+@@ -67,7 +70,7 @@
+ // Do the basic verification first before we do the checks over the regions.
+ HeapRegionSetBase::verify();
+
+- _verify_in_progress = true;
++ _verify_in_progress = true;
+ }
+
+ void HeapRegionSetBase::verify_end() {
+@@ -84,16 +87,16 @@
+ out->print_cr("Set: %s ("PTR_FORMAT")", name(), this);
+ out->print_cr(" Region Assumptions");
+ out->print_cr(" humongous : %s", BOOL_TO_STR(regions_humongous()));
+- out->print_cr(" empty : %s", BOOL_TO_STR(regions_empty()));
++ out->print_cr(" free : %s", BOOL_TO_STR(regions_free()));
+ out->print_cr(" Attributes");
+ out->print_cr(" length : %14u", length());
+ out->print_cr(" total capacity : "SIZE_FORMAT_W(14)" bytes",
+ total_capacity_bytes());
+ }
+
+-HeapRegionSetBase::HeapRegionSetBase(const char* name, bool humongous, bool empty, HRSMtSafeChecker* mt_safety_checker)
++HeapRegionSetBase::HeapRegionSetBase(const char* name, bool humongous, bool free, HRSMtSafeChecker* mt_safety_checker)
+ : _name(name), _verify_in_progress(false),
+- _is_humongous(humongous), _is_empty(empty), _mt_safety_checker(mt_safety_checker),
++ _is_humongous(humongous), _is_free(free), _mt_safety_checker(mt_safety_checker),
+ _count()
+ { }
+
+@@ -103,62 +106,7 @@
+ }
+
+ void FreeRegionList::fill_in_ext_msg_extra(hrs_ext_msg* msg) {
+- msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, head(), tail());
+-}
+-
+-void FreeRegionList::add_as_head_or_tail(FreeRegionList* from_list, bool as_head) {
+- check_mt_safety();
+- from_list->check_mt_safety();
+-
+- verify_optional();
+- from_list->verify_optional();
+-
+- if (from_list->is_empty()) {
+- return;
+- }
+-
+-#ifdef ASSERT
+- FreeRegionListIterator iter(from_list);
+- while (iter.more_available()) {
+- HeapRegion* hr = iter.get_next();
+- // In set_containing_set() we check that we either set the value
+- // from NULL to non-NULL or vice versa to catch bugs. So, we have
+- // to NULL it first before setting it to the value.
+- hr->set_containing_set(NULL);
+- hr->set_containing_set(this);
+- }
+-#endif // ASSERT
+-
+- if (_head == NULL) {
+- assert(length() == 0 && _tail == NULL, hrs_ext_msg(this, "invariant"));
+- _head = from_list->_head;
+- _tail = from_list->_tail;
+- } else {
+- assert(length() > 0 && _tail != NULL, hrs_ext_msg(this, "invariant"));
+- if (as_head) {
+- from_list->_tail->set_next(_head);
+- _head->set_prev(from_list->_tail);
+- _head = from_list->_head;
+- } else {
+- _tail->set_next(from_list->_head);
+- from_list->_head->set_prev(_tail);
+- _tail = from_list->_tail;
+- }
+- }
+-
+- _count.increment(from_list->length(), from_list->total_capacity_bytes());
+- from_list->clear();
+-
+- verify_optional();
+- from_list->verify_optional();
+-}
+-
+-void FreeRegionList::add_as_head(FreeRegionList* from_list) {
+- add_as_head_or_tail(from_list, true /* as_head */);
+-}
+-
+-void FreeRegionList::add_as_tail(FreeRegionList* from_list) {
+- add_as_head_or_tail(from_list, false /* as_head */);
++ msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, _head, _tail);
+ }
+
+ void FreeRegionList::remove_all() {
+@@ -191,11 +139,6 @@
+ return;
+ }
+
+- if (is_empty()) {
+- add_as_head(from_list);
+- return;
+- }
+-
+ #ifdef ASSERT
+ FreeRegionListIterator iter(from_list);
+ while (iter.more_available()) {
+@@ -208,39 +151,45 @@
+ }
+ #endif // ASSERT
+
+- HeapRegion* curr_to = _head;
+- HeapRegion* curr_from = from_list->_head;
++ if (is_empty()) {
++ assert(length() == 0 && _tail == NULL, hrs_ext_msg(this, "invariant"));
++ _head = from_list->_head;
++ _tail = from_list->_tail;
++ } else {
++ HeapRegion* curr_to = _head;
++ HeapRegion* curr_from = from_list->_head;
+
+- while (curr_from != NULL) {
+- while (curr_to != NULL && curr_to->hrs_index() < curr_from->hrs_index()) {
+- curr_to = curr_to->next();
++ while (curr_from != NULL) {
++ while (curr_to != NULL && curr_to->hrm_index() < curr_from->hrm_index()) {
++ curr_to = curr_to->next();
++ }
++
++ if (curr_to == NULL) {
++ // The rest of the from list should be added as tail
++ _tail->set_next(curr_from);
++ curr_from->set_prev(_tail);
++ curr_from = NULL;
++ } else {
++ HeapRegion* next_from = curr_from->next();
++
++ curr_from->set_next(curr_to);
++ curr_from->set_prev(curr_to->prev());
++ if (curr_to->prev() == NULL) {
++ _head = curr_from;
++ } else {
++ curr_to->prev()->set_next(curr_from);
++ }
++ curr_to->set_prev(curr_from);
++
++ curr_from = next_from;
++ }
+ }
+
+- if (curr_to == NULL) {
+- // The rest of the from list should be added as tail
+- _tail->set_next(curr_from);
+- curr_from->set_prev(_tail);
+- curr_from = NULL;
+- } else {
+- HeapRegion* next_from = curr_from->next();
+-
+- curr_from->set_next(curr_to);
+- curr_from->set_prev(curr_to->prev());
+- if (curr_to->prev() == NULL) {
+- _head = curr_from;
+- } else {
+- curr_to->prev()->set_next(curr_from);
+- }
+- curr_to->set_prev(curr_from);
+-
+- curr_from = next_from;
++ if (_tail->hrm_index() < from_list->_tail->hrm_index()) {
++ _tail = from_list->_tail;
+ }
+ }
+
+- if (_tail->hrs_index() < from_list->_tail->hrs_index()) {
+- _tail = from_list->_tail;
+- }
+-
+ _count.increment(from_list->length(), from_list->total_capacity_bytes());
+ from_list->clear();
+
+@@ -248,68 +197,59 @@
+ from_list->verify_optional();
+ }
+
+-void FreeRegionList::remove_all_pending(uint target_count) {
++void FreeRegionList::remove_starting_at(HeapRegion* first, uint num_regions) {
+ check_mt_safety();
+- assert(target_count > 1, hrs_ext_msg(this, "pre-condition"));
++ assert(num_regions >= 1, hrs_ext_msg(this, "pre-condition"));
+ assert(!is_empty(), hrs_ext_msg(this, "pre-condition"));
+
+ verify_optional();
+ DEBUG_ONLY(uint old_length = length();)
+
+- HeapRegion* curr = _head;
++ HeapRegion* curr = first;
+ uint count = 0;
+- while (curr != NULL) {
++ while (count < num_regions) {
+ verify_region(curr);
+ HeapRegion* next = curr->next();
+ HeapRegion* prev = curr->prev();
+
+- if (curr->pending_removal()) {
+- assert(count < target_count,
+- hrs_err_msg("[%s] should not come across more regions "
+- "pending for removal than target_count: %u",
+- name(), target_count));
++ assert(count < num_regions,
++ hrs_err_msg("[%s] should not come across more regions "
++ "pending for removal than num_regions: %u",
++ name(), num_regions));
+
+- if (prev == NULL) {
+- assert(_head == curr, hrs_ext_msg(this, "invariant"));
+- _head = next;
+- } else {
+- assert(_head != curr, hrs_ext_msg(this, "invariant"));
+- prev->set_next(next);
+- }
+- if (next == NULL) {
+- assert(_tail == curr, hrs_ext_msg(this, "invariant"));
+- _tail = prev;
+- } else {
+- assert(_tail != curr, hrs_ext_msg(this, "invariant"));
+- next->set_prev(prev);
+- }
+- if (_last = curr) {
+- _last = NULL;
+- }
++ if (prev == NULL) {
++ assert(_head == curr, hrs_ext_msg(this, "invariant"));
++ _head = next;
++ } else {
++ assert(_head != curr, hrs_ext_msg(this, "invariant"));
++ prev->set_next(next);
++ }
++ if (next == NULL) {
++ assert(_tail == curr, hrs_ext_msg(this, "invariant"));
++ _tail = prev;
++ } else {
++ assert(_tail != curr, hrs_ext_msg(this, "invariant"));
++ next->set_prev(prev);
++ }
++ if (_last = curr) {
++ _last = NULL;
++ }
+
+- curr->set_next(NULL);
+- curr->set_prev(NULL);
+- remove(curr);
+- curr->set_pending_removal(false);
++ curr->set_next(NULL);
++ curr->set_prev(NULL);
++ remove(curr);
+
+- count += 1;
+-
+- // If we have come across the target number of regions we can
+- // just bail out. However, for debugging purposes, we can just
+- // carry on iterating to make sure there are not more regions
+- // tagged with pending removal.
+- DEBUG_ONLY(if (count == target_count) break;)
+- }
++ count++;
+ curr = next;
+ }
+
+- assert(count == target_count,
+- hrs_err_msg("[%s] count: %u should be == target_count: %u",
+- name(), count, target_count));
+- assert(length() + target_count == old_length,
++ assert(count == num_regions,
++ hrs_err_msg("[%s] count: %u should be == num_regions: %u",
++ name(), count, num_regions));
++ assert(length() + num_regions == old_length,
+ hrs_err_msg("[%s] new length should be consistent "
+- "new length: %u old length: %u target_count: %u",
+- name(), length(), old_length, target_count));
++ "new length: %u old length: %u num_regions: %u",
++ name(), length(), old_length, num_regions));
+
+ verify_optional();
+ }
+@@ -348,10 +288,12 @@
+ hr->print_on(out);
+ }
+ }
++
++ out->cr();
+ }
+
+ void FreeRegionList::verify_list() {
+- HeapRegion* curr = head();
++ HeapRegion* curr = _head;
+ HeapRegion* prev1 = NULL;
+ HeapRegion* prev0 = NULL;
+ uint count = 0;
+@@ -369,8 +311,8 @@
+ if (curr->next() != NULL) {
+ guarantee(curr->next()->prev() == curr, "Next or prev pointers messed up");
+ }
+- guarantee(curr->hrs_index() == 0 || curr->hrs_index() > last_index, "List should be sorted");
+- last_index = curr->hrs_index();
++ guarantee(curr->hrm_index() == 0 || curr->hrm_index() > last_index, "List should be sorted");
++ last_index = curr->hrm_index();
+
+ capacity += curr->capacity();
+
+@@ -379,7 +321,7 @@
+ curr = curr->next();
+ }
+
+- guarantee(tail() == prev0, err_msg("Expected %s to end with %u but it ended with %u.", name(), tail()->hrs_index(), prev0->hrs_index()));
++ guarantee(_tail == prev0, err_msg("Expected %s to end with %u but it ended with %u.", name(), _tail->hrm_index(), prev0->hrm_index()));
+ guarantee(_tail == NULL || _tail->next() == NULL, "_tail should not have a next");
+ guarantee(length() == count, err_msg("%s count mismatch. Expected %u, actual %u.", name(), length(), count));
+ guarantee(total_capacity_bytes() == capacity, err_msg("%s capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
+@@ -463,3 +405,41 @@
+ "master humongous set MT safety protocol outside a safepoint");
+ }
+ }
++
++void FreeRegionList_test() {
++ FreeRegionList l("test");
++
++ const uint num_regions_in_test = 5;
++ // Create a fake heap. It does not need to be valid, as the HeapRegion constructor
++ // does not access it.
++ MemRegion heap(NULL, num_regions_in_test * HeapRegion::GrainWords);
++ // Allocate a fake BOT because the HeapRegion constructor initializes
++ // the BOT.
++ size_t bot_size = G1BlockOffsetSharedArray::compute_size(heap.word_size());
++ HeapWord* bot_data = NEW_C_HEAP_ARRAY(HeapWord, bot_size, mtGC);
++ ReservedSpace bot_rs(G1BlockOffsetSharedArray::compute_size(heap.word_size()));
++ G1RegionToSpaceMapper* bot_storage =
++ G1RegionToSpaceMapper::create_mapper(bot_rs,
++ os::vm_page_size(),
++ HeapRegion::GrainBytes,
++ G1BlockOffsetSharedArray::N_bytes,
++ mtGC);
++ G1BlockOffsetSharedArray oa(heap, bot_storage);
++ bot_storage->commit_regions(0, num_regions_in_test);
++ HeapRegion hr0(0, &oa, heap);
++ HeapRegion hr1(1, &oa, heap);
++ HeapRegion hr2(2, &oa, heap);
++ HeapRegion hr3(3, &oa, heap);
++ HeapRegion hr4(4, &oa, heap);
++ l.add_ordered(&hr1);
++ l.add_ordered(&hr0);
++ l.add_ordered(&hr3);
++ l.add_ordered(&hr4);
++ l.add_ordered(&hr2);
++ assert(l.length() == num_regions_in_test, "wrong length");
++ l.verify_list();
++
++ bot_storage->uncommit_regions(0, num_regions_in_test);
++ delete bot_storage;
++ FREE_C_HEAP_ARRAY(HeapWord, bot_data, mtGC);
++}
+--- ./hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -81,7 +81,7 @@
+ friend class VMStructs;
+ private:
+ bool _is_humongous;
+- bool _is_empty;
++ bool _is_free;
+ HRSMtSafeChecker* _mt_safety_checker;
+
+ protected:
+@@ -102,9 +102,9 @@
+ // not. Only used during verification.
+ bool regions_humongous() { return _is_humongous; }
+
+- // Indicates whether all regions in the set should be empty or
++ // Indicates whether all regions in the set should be free or
+ // not. Only used during verification.
+- bool regions_empty() { return _is_empty; }
++ bool regions_free() { return _is_free; }
+
+ void check_mt_safety() {
+ if (_mt_safety_checker != NULL) {
+@@ -114,12 +114,12 @@
+
+ virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg) { }
+
+- HeapRegionSetBase(const char* name, bool humongous, bool empty, HRSMtSafeChecker* mt_safety_checker);
++ HeapRegionSetBase(const char* name, bool humongous, bool free, HRSMtSafeChecker* mt_safety_checker);
+
+ public:
+ const char* name() { return _name; }
+
+- uint length() { return _count.length(); }
++ uint length() const { return _count.length(); }
+
+ bool is_empty() { return _count.length() == 0; }
+
+@@ -162,7 +162,7 @@
+ // diagnosing failures.
+ class hrs_ext_msg : public hrs_err_msg {
+ public:
+- hrs_ext_msg(HeapRegionSetBase* set, const char* message) : hrs_err_msg("%s","") {
++ hrs_ext_msg(HeapRegionSetBase* set, const char* message) : hrs_err_msg("%s", "") {
+ set->fill_in_ext_msg(this, message);
+ }
+ };
+@@ -171,7 +171,7 @@
+ do { \
+ assert(((_set1_)->regions_humongous() == \
+ (_set2_)->regions_humongous()) && \
+- ((_set1_)->regions_empty() == (_set2_)->regions_empty()), \
++ ((_set1_)->regions_free() == (_set2_)->regions_free()), \
+ hrs_err_msg("the contents of set %s and set %s should match", \
+ (_set1_)->name(), (_set2_)->name())); \
+ } while (0)
+@@ -184,7 +184,7 @@
+ class HeapRegionSet : public HeapRegionSetBase {
+ public:
+ HeapRegionSet(const char* name, bool humongous, HRSMtSafeChecker* mt_safety_checker):
+- HeapRegionSetBase(name, humongous, false /* empty */, mt_safety_checker) { }
++ HeapRegionSetBase(name, humongous, false /* free */, mt_safety_checker) { }
+
+ void bulk_remove(const HeapRegionSetCount& removed) {
+ _count.decrement(removed.length(), removed.capacity());
+@@ -192,13 +192,9 @@
+ };
+
+ // A set that links all the regions added to it in a doubly-linked
+-// list. We should try to avoid doing operations that iterate over
++// sorted list. We should try to avoid doing operations that iterate over
+ // such lists in performance critical paths. Typically we should
+-// add / remove one region at a time or concatenate two lists. There are
+-// two ways to treat your lists, ordered and un-ordered. All un-ordered
+-// operations are done in constant time. To keep a list ordered only use
+-// add_ordered() to add elements to the list. If a list is not ordered
+-// from start, there is no way to sort it later.
++// add / remove one region at a time or concatenate two lists.
+
+ class FreeRegionListIterator;
+
+@@ -210,13 +206,13 @@
+ HeapRegion* _tail;
+
+ // _last is used to keep track of where we added an element the last
+- // time in ordered lists. It helps to improve performance when adding
+- // several ordered items in a row.
++ // time. It helps to improve performance when adding several ordered items in a row.
+ HeapRegion* _last;
+
+ static uint _unrealistically_long_length;
+
+- void add_as_head_or_tail(FreeRegionList* from_list, bool as_head);
++ inline HeapRegion* remove_from_head_impl();
++ inline HeapRegion* remove_from_tail_impl();
+
+ protected:
+ virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg);
+@@ -232,65 +228,33 @@
+
+ void verify_list();
+
+- HeapRegion* head() { return _head; }
+- HeapRegion* tail() { return _tail; }
++#ifdef ASSERT
++ bool contains(HeapRegion* hr) const {
++ return hr->containing_set() == this;
++ }
++#endif
+
+ static void set_unrealistically_long_length(uint len);
+
+ // Add hr to the list. The region should not be a member of another set.
+ // Assumes that the list is ordered and will preserve that order. The order
+- // is determined by hrs_index.
++ // is determined by hrm_index.
+ inline void add_ordered(HeapRegion* hr);
+
+- // It adds hr to the list as the new head. The region should not be
+- // a member of another set.
+- inline void add_as_head(HeapRegion* hr);
+-
+- // It adds hr to the list as the new tail. The region should not be
+- // a member of another set.
+- inline void add_as_tail(HeapRegion* hr);
+-
+- // It removes and returns the head of the list. It assumes that the
+- // list is not empty so it will return a non-NULL value.
+- inline HeapRegion* remove_head();
+-
+- // Convenience method.
+- inline HeapRegion* remove_head_or_null();
+-
+- // Removes and returns the last element (_tail) of the list. It assumes
+- // that the list isn't empty so that it can return a non-NULL value.
+- inline HeapRegion* remove_tail();
+-
+- // Convenience method
+- inline HeapRegion* remove_tail_or_null();
+-
+ // Removes from head or tail based on the given argument.
+- inline HeapRegion* remove_region(bool from_head);
++ HeapRegion* remove_region(bool from_head);
+
+ // Merge two ordered lists. The result is also ordered. The order is
+- // determined by hrs_index.
++ // determined by hrm_index.
+ void add_ordered(FreeRegionList* from_list);
+
+- // It moves the regions from from_list to this list and empties
+- // from_list. The new regions will appear in the same order as they
+- // were in from_list and be linked in the beginning of this list.
+- void add_as_head(FreeRegionList* from_list);
+-
+- // It moves the regions from from_list to this list and empties
+- // from_list. The new regions will appear in the same order as they
+- // were in from_list and be linked in the end of this list.
+- void add_as_tail(FreeRegionList* from_list);
+-
+ // It empties the list by removing all regions from it.
+ void remove_all();
+
+- // It removes all regions in the list that are pending for removal
+- // (i.e., they have been tagged with "pending_removal"). The list
+- // must not be empty, target_count should reflect the exact number
+- // of regions that are pending for removal in the list, and
+- // target_count should be > 1 (currently, we never need to remove a
+- // single region using this).
+- void remove_all_pending(uint target_count);
++ // Remove all (contiguous) regions from first to first + num_regions -1 from
++ // this list.
++ // Num_regions must be > 1.
++ void remove_starting_at(HeapRegion* first, uint num_regions);
+
+ virtual void verify();
+
+@@ -298,7 +262,7 @@
+ };
+
+ // Iterator class that provides a convenient way to iterate over the
+-// regions of a HeapRegionLinkedList instance.
++// regions of a FreeRegionList.
+
+ class FreeRegionListIterator : public StackObj {
+ private:
+@@ -324,7 +288,7 @@
+ }
+
+ FreeRegionListIterator(FreeRegionList* list) : _curr(NULL), _list(list) {
+- _curr = list->head();
++ _curr = list->_head;
+ }
+ };
+
+--- ./hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -30,7 +30,8 @@
+ inline void HeapRegionSetBase::add(HeapRegion* hr) {
+ check_mt_safety();
+ assert(hr->containing_set() == NULL, hrs_ext_msg(this, "should not already have a containing set %u"));
+- assert(hr->next() == NULL && hr->prev() == NULL, hrs_ext_msg(this, "should not already be linked"));
++ assert(hr->next() == NULL, hrs_ext_msg(this, "should not already be linked"));
++ assert(hr->prev() == NULL, hrs_ext_msg(this, "should not already be linked"));
+
+ _count.increment(1u, hr->capacity());
+ hr->set_containing_set(this);
+@@ -40,7 +41,8 @@
+ inline void HeapRegionSetBase::remove(HeapRegion* hr) {
+ check_mt_safety();
+ verify_region(hr);
+- assert(hr->next() == NULL && hr->prev() == NULL, hrs_ext_msg(this, "should already be unlinked"));
++ assert(hr->next() == NULL, hrs_ext_msg(this, "should already be unlinked"));
++ assert(hr->prev() == NULL, hrs_ext_msg(this, "should already be unlinked"));
+
+ hr->set_containing_set(NULL);
+ assert(_count.length() > 0, hrs_ext_msg(this, "pre-condition"));
+@@ -48,8 +50,7 @@
+ }
+
+ inline void FreeRegionList::add_ordered(HeapRegion* hr) {
+- check_mt_safety();
+- assert((length() == 0 && _head == NULL && _tail == NULL) ||
++ assert((length() == 0 && _head == NULL && _tail == NULL && _last == NULL) ||
+ (length() > 0 && _head != NULL && _tail != NULL),
+ hrs_ext_msg(this, "invariant"));
+ // add() will verify the region and check mt safety.
+@@ -59,14 +60,14 @@
+ if (_head != NULL) {
+ HeapRegion* curr;
+
+- if (_last != NULL && _last->hrs_index() < hr->hrs_index()) {
++ if (_last != NULL && _last->hrm_index() < hr->hrm_index()) {
+ curr = _last;
+ } else {
+ curr = _head;
+ }
+
+ // Find first entry with a Region Index larger than entry to insert.
+- while (curr != NULL && curr->hrs_index() < hr->hrs_index()) {
++ while (curr != NULL && curr->hrm_index() < hr->hrm_index()) {
+ curr = curr->next();
+ }
+
+@@ -95,55 +96,48 @@
+ _last = hr;
+ }
+
+-inline void FreeRegionList::add_as_head(HeapRegion* hr) {
+- assert((length() == 0 && _head == NULL && _tail == NULL) ||
+- (length() > 0 && _head != NULL && _tail != NULL),
+- hrs_ext_msg(this, "invariant"));
+- // add() will verify the region and check mt safety.
+- add(hr);
+-
+- // Now link the region.
+- if (_head != NULL) {
+- hr->set_next(_head);
+- _head->set_prev(hr);
+- } else {
+- _tail = hr;
+- }
+- _head = hr;
+-}
+-
+-inline void FreeRegionList::add_as_tail(HeapRegion* hr) {
+- check_mt_safety();
+- assert((length() == 0 && _head == NULL && _tail == NULL) ||
+- (length() > 0 && _head != NULL && _tail != NULL),
+- hrs_ext_msg(this, "invariant"));
+- // add() will verify the region and check mt safety.
+- add(hr);
+-
+- // Now link the region.
+- if (_tail != NULL) {
+- _tail->set_next(hr);
+- hr->set_prev(_tail);
+- } else {
+- _head = hr;
+- }
+- _tail = hr;
+-}
+-
+-inline HeapRegion* FreeRegionList::remove_head() {
+- assert(!is_empty(), hrs_ext_msg(this, "the list should not be empty"));
+- assert(length() > 0 && _head != NULL && _tail != NULL,
+- hrs_ext_msg(this, "invariant"));
+-
+- // We need to unlink it first.
+- HeapRegion* hr = _head;
+- _head = hr->next();
++inline HeapRegion* FreeRegionList::remove_from_head_impl() {
++ HeapRegion* result = _head;
++ _head = result->next();
+ if (_head == NULL) {
+ _tail = NULL;
+ } else {
+ _head->set_prev(NULL);
+ }
+- hr->set_next(NULL);
++ result->set_next(NULL);
++ return result;
++}
++
++inline HeapRegion* FreeRegionList::remove_from_tail_impl() {
++ HeapRegion* result = _tail;
++
++ _tail = result->prev();
++ if (_tail == NULL) {
++ _head = NULL;
++ } else {
++ _tail->set_next(NULL);
++ }
++ result->set_prev(NULL);
++ return result;
++}
++
++inline HeapRegion* FreeRegionList::remove_region(bool from_head) {
++ check_mt_safety();
++ verify_optional();
++
++ if (is_empty()) {
++ return NULL;
++ }
++ assert(length() > 0 && _head != NULL && _tail != NULL,
++ hrs_ext_msg(this, "invariant"));
++
++ HeapRegion* hr;
++
++ if (from_head) {
++ hr = remove_from_head_impl();
++ } else {
++ hr = remove_from_tail_impl();
++ }
+
+ if (_last == hr) {
+ _last = NULL;
+@@ -154,56 +148,5 @@
+ return hr;
+ }
+
+-inline HeapRegion* FreeRegionList::remove_head_or_null() {
+- check_mt_safety();
+- if (!is_empty()) {
+- return remove_head();
+- } else {
+- return NULL;
+- }
+-}
++#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_INLINE_HPP
+
+-inline HeapRegion* FreeRegionList::remove_tail() {
+- assert(!is_empty(), hrs_ext_msg(this, "The list should not be empty"));
+- assert(length() > 0 && _head != NULL && _tail != NULL,
+- hrs_ext_msg(this, "invariant"));
+-
+- // We need to unlink it first
+- HeapRegion* hr = _tail;
+-
+- _tail = hr->prev();
+- if (_tail == NULL) {
+- _head = NULL;
+- } else {
+- _tail->set_next(NULL);
+- }
+- hr->set_prev(NULL);
+-
+- if (_last == hr) {
+- _last = NULL;
+- }
+-
+- // remove() will verify the region and check mt safety.
+- remove(hr);
+- return hr;
+-}
+-
+-inline HeapRegion* FreeRegionList::remove_tail_or_null() {
+- check_mt_safety();
+-
+- if (!is_empty()) {
+- return remove_tail();
+- } else {
+- return NULL;
+- }
+-}
+-
+-inline HeapRegion* FreeRegionList::remove_region(bool from_head) {
+- if (from_head) {
+- return remove_head_or_null();
+- } else {
+- return remove_tail_or_null();
+- }
+-}
+-
+-#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_INLINE_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/heapRegionType.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "gc_implementation/g1/heapRegionType.hpp"
++
++bool HeapRegionType::is_valid(Tag tag) {
++ switch (tag) {
++ case FreeTag:
++ case EdenTag:
++ case SurvTag:
++ case HumStartsTag:
++ case HumContTag:
++ case OldTag:
++ return true;
++ }
++ return false;
++}
++
++const char* HeapRegionType::get_str() const {
++ hrt_assert_is_valid(_tag);
++ switch (_tag) {
++ case FreeTag: return "FREE";
++ case EdenTag: return "EDEN";
++ case SurvTag: return "SURV";
++ case HumStartsTag: return "HUMS";
++ case HumContTag: return "HUMC";
++ case OldTag: return "OLD";
++ }
++ ShouldNotReachHere();
++ // keep some compilers happy
++ return NULL;
++}
++
++const char* HeapRegionType::get_short_str() const {
++ hrt_assert_is_valid(_tag);
++ switch (_tag) {
++ case FreeTag: return "F";
++ case EdenTag: return "E";
++ case SurvTag: return "S";
++ case HumStartsTag: return "HS";
++ case HumContTag: return "HC";
++ case OldTag: return "O";
++ }
++ ShouldNotReachHere();
++ // keep some compilers happy
++ return NULL;
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/g1/heapRegionType.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,134 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONTYPE_HPP
++#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONTYPE_HPP
++
++#include "memory/allocation.hpp"
++
++#define hrt_assert_is_valid(tag) \
++ assert(is_valid((tag)), err_msg("invalid HR type: %u", (uint) (tag)))
++
++class HeapRegionType VALUE_OBJ_CLASS_SPEC {
++private:
++ // We encode the value of the heap region type so the generation can be
++ // determined quickly. The tag is split into two parts:
++ //
++ // major type (young, humongous) : top N-1 bits
++ // minor type (eden / survivor, starts / cont hum, etc.) : bottom 1 bit
++ //
++ // If there's need to increase the number of minor types in the
++ // future, we'll have to increase the size of the latter and hence
++ // decrease the size of the former.
++ //
++ // 0000 0 [ 0] Free
++ //
++ // 0001 0 Young Mask
++ // 0001 0 [ 2] Eden
++ // 0001 1 [ 3] Survivor
++ //
++ // 0010 0 Humongous Mask
++ // 0010 0 [ 4] Humongous Starts
++ // 0010 1 [ 5] Humongous Continues
++ //
++ // 01000 [ 8] Old
++ typedef enum {
++ FreeTag = 0,
++
++ YoungMask = 2,
++ EdenTag = YoungMask,
++ SurvTag = YoungMask + 1,
++
++ HumMask = 4,
++ HumStartsTag = HumMask,
++ HumContTag = HumMask + 1,
++
++ OldTag = 8
++ } Tag;
++
++ volatile Tag _tag;
++
++ static bool is_valid(Tag tag);
++
++ Tag get() const {
++ hrt_assert_is_valid(_tag);
++ return _tag;
++ }
++
++ // Sets the type to 'tag'.
++ void set(Tag tag) {
++ hrt_assert_is_valid(tag);
++ hrt_assert_is_valid(_tag);
++ _tag = tag;
++ }
++
++ // Sets the type to 'tag', expecting the type to be 'before'. This
++ // is available for when we want to add sanity checking to the type
++ // transition.
++ void set_from(Tag tag, Tag before) {
++ hrt_assert_is_valid(tag);
++ hrt_assert_is_valid(before);
++ hrt_assert_is_valid(_tag);
++ assert(_tag == before,
++ err_msg("HR tag: %u, expected: %u new tag; %u", _tag, before, tag));
++ _tag = tag;
++ }
++
++public:
++ // Queries
++
++ bool is_free() const { return get() == FreeTag; }
++
++ bool is_young() const { return (get() & YoungMask) != 0; }
++ bool is_eden() const { return get() == EdenTag; }
++ bool is_survivor() const { return get() == SurvTag; }
++
++ bool is_humongous() const { return (get() & HumMask) != 0; }
++ bool is_starts_humongous() const { return get() == HumStartsTag; }
++ bool is_continues_humongous() const { return get() == HumContTag; }
++
++ bool is_old() const { return get() == OldTag; }
++
++ // Setters
++
++ void set_free() { set(FreeTag); }
++
++ void set_eden() { set_from(EdenTag, FreeTag); }
++ void set_eden_pre_gc() { set_from(EdenTag, SurvTag); }
++ void set_survivor() { set_from(SurvTag, FreeTag); }
++
++ void set_starts_humongous() { set_from(HumStartsTag, FreeTag); }
++ void set_continues_humongous() { set_from(HumContTag, FreeTag); }
++
++ void set_old() { set(OldTag); }
++
++ // Misc
++
++ const char* get_str() const;
++ const char* get_short_str() const;
++
++ HeapRegionType() : _tag(FreeTag) { hrt_assert_is_valid(_tag); }
++};
++
++#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONTYPE_HPP
+--- ./hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -285,37 +285,6 @@
+ _par_closures[i] = par_closure;
+ }
+
+-void SATBMarkQueueSet::iterate_closure_all_threads() {
+- for(JavaThread* t = Threads::first(); t; t = t->next()) {
+- t->satb_mark_queue().apply_closure_and_empty(_closure);
+- }
+- shared_satb_queue()->apply_closure_and_empty(_closure);
+-}
+-
+-void SATBMarkQueueSet::par_iterate_closure_all_threads(uint worker) {
+- SharedHeap* sh = SharedHeap::heap();
+- int parity = sh->strong_roots_parity();
+-
+- for(JavaThread* t = Threads::first(); t; t = t->next()) {
+- if (t->claim_oops_do(true, parity)) {
+- t->satb_mark_queue().apply_closure_and_empty(_par_closures[worker]);
+- }
+- }
+-
+- // We also need to claim the VMThread so that its parity is updated
+- // otherwise the next call to Thread::possibly_parallel_oops_do inside
+- // a StrongRootsScope might skip the VMThread because it has a stale
+- // parity that matches the parity set by the StrongRootsScope
+- //
+- // Whichever worker succeeds in claiming the VMThread gets to do
+- // the shared queue.
+-
+- VMThread* vmt = VMThread::vm_thread();
+- if (vmt->claim_oops_do(true, parity)) {
+- shared_satb_queue()->apply_closure_and_empty(_par_closures[worker]);
+- }
+-}
+-
+ bool SATBMarkQueueSet::apply_closure_to_completed_buffer_work(bool par,
+ uint worker) {
+ BufferNode* nd = NULL;
+--- ./hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -33,7 +33,9 @@
+
+ // A ptrQueue whose elements are "oops", pointers to object heads.
+ class ObjPtrQueue: public PtrQueue {
++ friend class Threads;
+ friend class SATBMarkQueueSet;
++ friend class G1RemarkThreadsClosure;
+
+ private:
+ // Filter out unwanted entries from the buffer.
+@@ -118,13 +120,6 @@
+ // closures, one for each parallel GC thread.
+ void set_par_closure(int i, ObjectClosure* closure);
+
+- // Apply the registered closure to all entries on each
+- // currently-active buffer and then empty the buffer. It should only
+- // be called serially and at a safepoint.
+- void iterate_closure_all_threads();
+- // Parallel version of the above.
+- void par_iterate_closure_all_threads(uint worker);
+-
+ // If there exists some completed buffer, pop it, then apply the
+ // registered closure to all its elements, and return true. If no
+ // completed buffers exist, return false.
+--- ./hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -370,7 +370,7 @@
+ }
+
+ size_t RSHashTable::mem_size() const {
+- return sizeof(this) +
++ return sizeof(RSHashTable) +
+ capacity() * (SparsePRTEntry::size() + sizeof(int));
+ }
+
+@@ -472,13 +472,13 @@
+ size_t SparsePRT::mem_size() const {
+ // We ignore "_cur" here, because it either = _next, or else it is
+ // on the deleted list.
+- return sizeof(this) + _next->mem_size();
++ return sizeof(SparsePRT) + _next->mem_size();
+ }
+
+ bool SparsePRT::add_card(RegionIdx_t region_id, CardIdx_t card_index) {
+ #if SPARSE_PRT_VERBOSE
+ gclog_or_tty->print_cr(" Adding card %d from region %d to region %u sparse.",
+- card_index, region_id, _hr->hrs_index());
++ card_index, region_id, _hr->hrm_index());
+ #endif
+ if (_next->occupied_entries() * 2 > _next->capacity()) {
+ expand();
+@@ -530,7 +530,7 @@
+
+ #if SPARSE_PRT_VERBOSE
+ gclog_or_tty->print_cr(" Expanded sparse table for %u to %d.",
+- _hr->hrs_index(), _next->capacity());
++ _hr->hrm_index(), _next->capacity());
+ #endif
+ for (size_t i = 0; i < last->capacity(); i++) {
+ SparsePRTEntry* e = last->entry((int)i);
+--- ./hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,7 +26,7 @@
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_VMSTRUCTS_G1_HPP
+
+ #include "gc_implementation/g1/heapRegion.hpp"
+-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
++#include "gc_implementation/g1/heapRegionManager.inline.hpp"
+ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+
+ #define VM_STRUCTS_G1(nonstatic_field, static_field) \
+@@ -34,21 +34,24 @@
+ static_field(HeapRegion, GrainBytes, size_t) \
+ static_field(HeapRegion, LogOfHRGrainBytes, int) \
+ \
++ nonstatic_field(G1OffsetTableContigSpace, _top, HeapWord*) \
++ \
+ nonstatic_field(G1HeapRegionTable, _base, address) \
+ nonstatic_field(G1HeapRegionTable, _length, size_t) \
+ nonstatic_field(G1HeapRegionTable, _biased_base, address) \
+ nonstatic_field(G1HeapRegionTable, _bias, size_t) \
+ nonstatic_field(G1HeapRegionTable, _shift_by, uint) \
+ \
+- nonstatic_field(HeapRegionSeq, _regions, G1HeapRegionTable) \
+- nonstatic_field(HeapRegionSeq, _committed_length, uint) \
++ nonstatic_field(HeapRegionManager, _regions, G1HeapRegionTable) \
++ nonstatic_field(HeapRegionManager, _num_committed, uint) \
+ \
+- nonstatic_field(G1CollectedHeap, _hrs, HeapRegionSeq) \
+- nonstatic_field(G1CollectedHeap, _g1_committed, MemRegion) \
+- nonstatic_field(G1CollectedHeap, _summary_bytes_used, size_t) \
++ nonstatic_field(G1Allocator, _summary_bytes_used, size_t) \
++ \
++ nonstatic_field(G1CollectedHeap, _hrm, HeapRegionManager) \
+ nonstatic_field(G1CollectedHeap, _g1mm, G1MonitoringSupport*) \
+ nonstatic_field(G1CollectedHeap, _old_set, HeapRegionSetBase) \
+ nonstatic_field(G1CollectedHeap, _humongous_set, HeapRegionSetBase) \
++ nonstatic_field(G1CollectedHeap, _allocator, G1Allocator*) \
+ \
+ nonstatic_field(G1MonitoringSupport, _eden_committed, size_t) \
+ nonstatic_field(G1MonitoringSupport, _eden_used, size_t) \
+@@ -69,15 +72,18 @@
+ \
+ declare_type(G1CollectedHeap, SharedHeap) \
+ \
+- declare_type(HeapRegion, ContiguousSpace) \
+- declare_toplevel_type(HeapRegionSeq) \
++ declare_type(G1OffsetTableContigSpace, CompactibleSpace) \
++ declare_type(HeapRegion, G1OffsetTableContigSpace) \
++ declare_toplevel_type(HeapRegionManager) \
+ declare_toplevel_type(HeapRegionSetBase) \
+ declare_toplevel_type(HeapRegionSetCount) \
+ declare_toplevel_type(G1MonitoringSupport) \
++ declare_toplevel_type(G1Allocator) \
+ \
+ declare_toplevel_type(G1CollectedHeap*) \
+ declare_toplevel_type(HeapRegion*) \
+ declare_toplevel_type(G1MonitoringSupport*) \
++ declare_toplevel_type(G1Allocator*) \
+
+
+ #endif // SHARE_VM_GC_IMPLEMENTATION_G1_VMSTRUCTS_G1_HPP
+--- ./hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -45,7 +45,8 @@
+ void VM_G1CollectForAllocation::doit() {
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ GCCauseSetter x(g1h, _gc_cause);
+- _result = g1h->satisfy_failed_allocation(_word_size, &_pause_succeeded);
++
++ _result = g1h->satisfy_failed_allocation(_word_size, allocation_context(), &_pause_succeeded);
+ assert(_result == NULL || _pause_succeeded,
+ "if we get back a result, the pause should have succeeded");
+ }
+@@ -94,12 +95,13 @@
+ assert(!_should_initiate_conc_mark ||
+ ((_gc_cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) ||
+ (_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent) ||
+- _gc_cause == GCCause::_g1_humongous_allocation),
+- "only a GC locker, a System.gc() or a hum allocation induced GC should start a cycle");
++ _gc_cause == GCCause::_g1_humongous_allocation ||
++ _gc_cause == GCCause::_update_allocation_context_stats_inc),
++ "only a GC locker, a System.gc(), stats update or a hum allocation induced GC should start a cycle");
+
+ if (_word_size > 0) {
+ // An allocation has been requested. So, try to do that first.
+- _result = g1h->attempt_allocation_at_safepoint(_word_size,
++ _result = g1h->attempt_allocation_at_safepoint(_word_size, allocation_context(),
+ false /* expect_null_cur_alloc_region */);
+ if (_result != NULL) {
+ // If we can successfully allocate before we actually do the
+@@ -152,7 +154,7 @@
+ g1h->do_collection_pause_at_safepoint(_target_pause_time_ms);
+ if (_pause_succeeded && _word_size > 0) {
+ // An allocation had been requested.
+- _result = g1h->attempt_allocation_at_safepoint(_word_size,
++ _result = g1h->attempt_allocation_at_safepoint(_word_size, allocation_context(),
+ true /* expect_null_cur_alloc_region */);
+ } else {
+ assert(_result == NULL, "invariant");
+@@ -211,8 +213,12 @@
+ assert(_needs_pll, "don't call this otherwise");
+ // The caller may block while communicating
+ // with the SLT thread in order to acquire/release the PLL.
+- ConcurrentMarkThread::slt()->
+- manipulatePLL(SurrogateLockerThread::acquirePLL);
++ SurrogateLockerThread* slt = ConcurrentMarkThread::slt();
++ if (slt != NULL) {
++ slt->manipulatePLL(SurrogateLockerThread::acquirePLL);
++ } else {
++ SurrogateLockerThread::report_missing_slt();
++ }
+ }
+
+ void VM_CGC_Operation::release_and_notify_pending_list_lock() {
+@@ -226,7 +232,7 @@
+ void VM_CGC_Operation::doit() {
+ gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps);
+ TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
+- GCTraceTime t(_printGCMessage, G1Log::fine(), true, G1CollectedHeap::heap()->gc_timer_cm());
++ GCTraceTime t(_printGCMessage, G1Log::fine(), true, G1CollectedHeap::heap()->gc_timer_cm(), G1CollectedHeap::heap()->concurrent_mark()->concurrent_gc_id());
+ SharedHeap* sh = SharedHeap::heap();
+ // This could go away if CollectedHeap gave access to _gc_is_active...
+ if (sh != NULL) {
+--- ./hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,6 +25,7 @@
+ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_VM_OPERATIONS_G1_HPP
+ #define SHARE_VM_GC_IMPLEMENTATION_G1_VM_OPERATIONS_G1_HPP
+
++#include "gc_implementation/g1/g1AllocationContext.hpp"
+ #include "gc_implementation/shared/vmGCOperations.hpp"
+
+ // VM_operations for the G1 collector.
+@@ -40,6 +41,7 @@
+ size_t _word_size;
+ HeapWord* _result;
+ bool _pause_succeeded;
++ AllocationContext_t _allocation_context;
+
+ public:
+ VM_G1OperationWithAllocRequest(unsigned int gc_count_before,
+@@ -49,6 +51,8 @@
+ _word_size(word_size), _result(NULL), _pause_succeeded(false) { }
+ HeapWord* result() { return _result; }
+ bool pause_succeeded() { return _pause_succeeded; }
++ void set_allocation_context(AllocationContext_t context) { _allocation_context = context; }
++ AllocationContext_t allocation_context() { return _allocation_context; }
+ };
+
+ class VM_G1CollectFull: public VM_GC_Operation {
+@@ -56,7 +60,7 @@
+ VM_G1CollectFull(unsigned int gc_count_before,
+ unsigned int full_gc_count_before,
+ GCCause::Cause cause)
+- : VM_GC_Operation(gc_count_before, cause, full_gc_count_before) { }
++ : VM_GC_Operation(gc_count_before, cause, full_gc_count_before, true) { }
+ virtual VMOp_Type type() const { return VMOp_G1CollectFull; }
+ virtual void doit();
+ virtual const char* name() const {
+--- ./hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -32,6 +32,7 @@
+ #include "oops/oop.inline.hpp"
+ #include "runtime/java.hpp"
+ #include "runtime/mutexLocker.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/virtualspace.hpp"
+ #include "runtime/vmThread.hpp"
+
+--- ./hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,12 +28,12 @@
+ #include "gc_implementation/parNew/parOopClosures.inline.hpp"
+ #include "gc_implementation/shared/adaptiveSizePolicy.hpp"
+ #include "gc_implementation/shared/ageTable.hpp"
+-#include "gc_implementation/shared/parGCAllocBuffer.hpp"
++#include "gc_implementation/shared/copyFailedInfo.hpp"
+ #include "gc_implementation/shared/gcHeapSummary.hpp"
+ #include "gc_implementation/shared/gcTimer.hpp"
+ #include "gc_implementation/shared/gcTrace.hpp"
+ #include "gc_implementation/shared/gcTraceTime.hpp"
+-#include "gc_implementation/shared/copyFailedInfo.hpp"
++#include "gc_implementation/shared/parGCAllocBuffer.inline.hpp"
+ #include "gc_implementation/shared/spaceDecorator.hpp"
+ #include "memory/defNewGeneration.inline.hpp"
+ #include "memory/genCollectedHeap.hpp"
+@@ -50,7 +50,7 @@
+ #include "runtime/handles.hpp"
+ #include "runtime/handles.inline.hpp"
+ #include "runtime/java.hpp"
+-#include "runtime/thread.hpp"
++#include "runtime/thread.inline.hpp"
+ #include "utilities/copy.hpp"
+ #include "utilities/globalDefinitions.hpp"
+ #include "utilities/workgroup.hpp"
+@@ -251,7 +251,7 @@
+ plab->set_word_size(buf_size);
+ plab->set_buf(buf_space);
+ record_survivor_plab(buf_space, buf_size);
+- obj = plab->allocate(word_sz);
++ obj = plab->allocate_aligned(word_sz, SurvivorAlignmentInBytes);
+ // Note that we cannot compare buf_size < word_sz below
+ // because of AlignmentReserve (see ParGCAllocBuffer::allocate()).
+ assert(obj != NULL || plab->words_remaining() < word_sz,
+@@ -613,20 +613,21 @@
+
+ KlassScanClosure klass_scan_closure(&par_scan_state.to_space_root_closure(),
+ gch->rem_set()->klass_rem_set());
+-
+- int so = SharedHeap::SO_AllClasses | SharedHeap::SO_Strings | SharedHeap::SO_CodeCache;
++ CLDToKlassAndOopClosure cld_scan_closure(&klass_scan_closure,
++ &par_scan_state.to_space_root_closure(),
++ false);
+
+ par_scan_state.start_strong_roots();
+- gch->gen_process_strong_roots(_gen->level(),
+- true, // Process younger gens, if any,
+- // as strong roots.
+- false, // no scope; this is parallel code
+- true, // is scavenging
+- SharedHeap::ScanningOption(so),
+- &par_scan_state.to_space_root_closure(),
+- true, // walk *all* scavengable nmethods
+- &par_scan_state.older_gen_closure(),
+- &klass_scan_closure);
++ gch->gen_process_roots(_gen->level(),
++ true, // Process younger gens, if any,
++ // as strong roots.
++ false, // no scope; this is parallel code
++ SharedHeap::SO_ScavengeCodeCache,
++ GenCollectedHeap::StrongAndWeakRoots,
++ &par_scan_state.to_space_root_closure(),
++ &par_scan_state.older_gen_closure(),
++ &cld_scan_closure);
++
+ par_scan_state.end_strong_roots();
+
+ // "evacuate followers".
+@@ -957,7 +958,7 @@
+ size_policy->minor_collection_begin();
+ }
+
+- GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL);
++ GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL, gc_tracer.gc_id());
+ // Capture heap used before collection (for printing).
+ size_t gch_prev_used = gch->used();
+
+@@ -1015,14 +1016,14 @@
+ ParNewRefProcTaskExecutor task_executor(*this, thread_state_set);
+ stats = rp->process_discovered_references(&is_alive, &keep_alive,
+ &evacuate_followers, &task_executor,
+- _gc_timer);
++ _gc_timer, gc_tracer.gc_id());
+ } else {
+ thread_state_set.flush();
+ gch->set_par_threads(0); // 0 ==> non-parallel.
+ gch->save_marks();
+ stats = rp->process_discovered_references(&is_alive, &keep_alive,
+ &evacuate_followers, NULL,
+- _gc_timer);
++ _gc_timer, gc_tracer.gc_id());
+ }
+ gc_tracer.report_gc_reference_stats(stats);
+ if (!promotion_failed()) {
+--- ./hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -69,7 +69,7 @@
+ ParScanWithoutBarrierClosure _to_space_closure; // scan_without_gc_barrier
+ ParScanWithBarrierClosure _old_gen_closure; // scan_with_gc_barrier
+ ParRootScanWithoutBarrierClosure _to_space_root_closure; // scan_root_without_gc_barrier
+- // One of these two will be passed to process_strong_roots, which will
++ // One of these two will be passed to process_roots, which will
+ // set its generation. The first is for two-gen configs where the
+ // old gen collects the perm gen; the second is for arbitrary configs.
+ // The second isn't used right now (it used to be used for the train, an
+@@ -168,7 +168,7 @@
+ HeapWord* alloc_in_to_space_slow(size_t word_sz);
+
+ HeapWord* alloc_in_to_space(size_t word_sz) {
+- HeapWord* obj = to_space_alloc_buffer()->allocate(word_sz);
++ HeapWord* obj = to_space_alloc_buffer()->allocate_aligned(word_sz, SurvivorAlignmentInBytes);
+ if (obj != NULL) return obj;
+ else return alloc_in_to_space_slow(word_sz);
+ }
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -30,6 +30,7 @@
+ #include "gc_implementation/parallelScavenge/psYoungGen.hpp"
+ #include "oops/oop.inline.hpp"
+ #include "oops/oop.psgc.inline.hpp"
++#include "runtime/prefetch.inline.hpp"
+
+ // Checks an individual oop for missing precise marks. Mark
+ // may be either dirty or newgen.
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -30,6 +30,7 @@
+ #include "memory/allocation.inline.hpp"
+ #include "runtime/mutex.hpp"
+ #include "runtime/mutexLocker.hpp"
++#include "runtime/orderAccess.inline.hpp"
+
+ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -71,7 +71,7 @@
+ if (_virtual_space != NULL && _virtual_space->expand_by(_reserved_byte_size)) {
+ _region_start = covered_region.start();
+ _region_size = covered_region.word_size();
+- idx_t* map = (idx_t*)_virtual_space->reserved_low_addr();
++ BitMap::bm_word_t* map = (BitMap::bm_word_t*)_virtual_space->reserved_low_addr();
+ _beg_bits.set_map(map);
+ _beg_bits.set_size(bits / 2);
+ _end_bits.set_map(map + words / 2);
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -78,6 +78,7 @@
+ (HeapWord*)(heap_rs.base() + heap_rs.size()));
+
+ CardTableExtension* const barrier_set = new CardTableExtension(_reserved, 3);
++ barrier_set->initialize();
+ _barrier_set = barrier_set;
+ oopDesc::set_bs(_barrier_set);
+ if (_barrier_set == NULL) {
+@@ -484,10 +485,6 @@
+ young_gen()->eden_space()->ensure_parsability();
+ }
+
+-size_t ParallelScavengeHeap::unsafe_max_alloc() {
+- return young_gen()->eden_space()->free_in_bytes();
+-}
+-
+ size_t ParallelScavengeHeap::tlab_capacity(Thread* thr) const {
+ return young_gen()->eden_space()->tlab_capacity(thr);
+ }
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -184,8 +184,6 @@
+ void accumulate_statistics_all_tlabs();
+ void resize_all_tlabs();
+
+- size_t unsafe_max_alloc();
+-
+ bool supports_tlab_allocation() const { return true; }
+
+ size_t tlab_capacity(Thread* thr) const;
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -53,13 +53,13 @@
+ ResourceMark rm;
+
+ NOT_PRODUCT(GCTraceTime tm("ThreadRootsMarkingTask",
+- PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
++ PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
+ ParCompactionManager* cm =
+ ParCompactionManager::gc_thread_compaction_manager(which);
+
+ PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
+ CLDToOopClosure mark_and_push_from_clds(&mark_and_push_closure, true);
+- CodeBlobToOopClosure mark_and_push_in_blobs(&mark_and_push_closure, /*do_marking=*/ true);
++ MarkingCodeBlobClosure mark_and_push_in_blobs(&mark_and_push_closure, !CodeBlobToOopClosure::FixRelocations);
+
+ if (_java_thread != NULL)
+ _java_thread->oops_do(
+@@ -82,7 +82,7 @@
+ assert(Universe::heap()->is_gc_active(), "called outside gc");
+
+ NOT_PRODUCT(GCTraceTime tm("MarkFromRootsTask",
+- PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
++ PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
+ ParCompactionManager* cm =
+ ParCompactionManager::gc_thread_compaction_manager(which);
+ PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
+@@ -100,7 +100,7 @@
+ case threads:
+ {
+ ResourceMark rm;
+- CodeBlobToOopClosure each_active_code_blob(&mark_and_push_closure, /*do_marking=*/ true);
++ MarkingCodeBlobClosure each_active_code_blob(&mark_and_push_closure, !CodeBlobToOopClosure::FixRelocations);
+ CLDToOopClosure mark_and_push_from_cld(&mark_and_push_closure);
+ Threads::oops_do(&mark_and_push_closure, &mark_and_push_from_cld, &each_active_code_blob);
+ }
+@@ -153,7 +153,7 @@
+ assert(Universe::heap()->is_gc_active(), "called outside gc");
+
+ NOT_PRODUCT(GCTraceTime tm("RefProcTask",
+- PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
++ PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
+ ParCompactionManager* cm =
+ ParCompactionManager::gc_thread_compaction_manager(which);
+ PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
+@@ -209,7 +209,7 @@
+ assert(Universe::heap()->is_gc_active(), "called outside gc");
+
+ NOT_PRODUCT(GCTraceTime tm("StealMarkingTask",
+- PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
++ PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
+
+ ParCompactionManager* cm =
+ ParCompactionManager::gc_thread_compaction_manager(which);
+@@ -242,7 +242,7 @@
+ assert(Universe::heap()->is_gc_active(), "called outside gc");
+
+ NOT_PRODUCT(GCTraceTime tm("StealRegionCompactionTask",
+- PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
++ PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
+
+ ParCompactionManager* cm =
+ ParCompactionManager::gc_thread_compaction_manager(which);
+@@ -309,7 +309,7 @@
+ void UpdateDensePrefixTask::do_it(GCTaskManager* manager, uint which) {
+
+ NOT_PRODUCT(GCTraceTime tm("UpdateDensePrefixTask",
+- PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
++ PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
+
+ ParCompactionManager* cm =
+ ParCompactionManager::gc_thread_compaction_manager(which);
+@@ -324,7 +324,7 @@
+ assert(Universe::heap()->is_gc_active(), "called outside gc");
+
+ NOT_PRODUCT(GCTraceTime tm("DrainStacksCompactionTask",
+- PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
++ PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
+
+ ParCompactionManager* cm =
+ ParCompactionManager::gc_thread_compaction_manager(which);
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -169,7 +169,7 @@
+
+ gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
+ TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
+- GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
++ GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer->gc_id());
+ TraceCollectorStats tcs(counters());
+ TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
+
+@@ -513,7 +513,7 @@
+
+ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
+ // Recursively traverse all live objects and mark them
+- GCTraceTime tm("phase 1", PrintGCDetails && Verbose, true, _gc_timer);
++ GCTraceTime tm("phase 1", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+ trace(" 1");
+
+ ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+@@ -528,14 +528,14 @@
+ Universe::oops_do(mark_and_push_closure());
+ JNIHandles::oops_do(mark_and_push_closure()); // Global (strong) JNI handles
+ CLDToOopClosure mark_and_push_from_cld(mark_and_push_closure());
+- CodeBlobToOopClosure each_active_code_blob(mark_and_push_closure(), /*do_marking=*/ true);
++ MarkingCodeBlobClosure each_active_code_blob(mark_and_push_closure(), !CodeBlobToOopClosure::FixRelocations);
+ Threads::oops_do(mark_and_push_closure(), &mark_and_push_from_cld, &each_active_code_blob);
+ ObjectSynchronizer::oops_do(mark_and_push_closure());
+ FlatProfiler::oops_do(mark_and_push_closure());
+ Management::oops_do(mark_and_push_closure());
+ JvmtiExport::oops_do(mark_and_push_closure());
+ SystemDictionary::always_strong_oops_do(mark_and_push_closure());
+- ClassLoaderDataGraph::always_strong_oops_do(mark_and_push_closure(), follow_klass_closure(), true);
++ ClassLoaderDataGraph::always_strong_cld_do(follow_cld_closure());
+ // Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
+ //CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure()));
+ }
+@@ -548,7 +548,7 @@
+ ref_processor()->setup_policy(clear_all_softrefs);
+ const ReferenceProcessorStats& stats =
+ ref_processor()->process_discovered_references(
+- is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL, _gc_timer);
++ is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL, _gc_timer, _gc_tracer->gc_id());
+ gc_tracer()->report_gc_reference_stats(stats);
+ }
+
+@@ -574,7 +574,7 @@
+
+
+ void PSMarkSweep::mark_sweep_phase2() {
+- GCTraceTime tm("phase 2", PrintGCDetails && Verbose, true, _gc_timer);
++ GCTraceTime tm("phase 2", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+ trace("2");
+
+ // Now all live objects are marked, compute the new object addresses.
+@@ -604,7 +604,7 @@
+
+ void PSMarkSweep::mark_sweep_phase3() {
+ // Adjust the pointers to reflect the new locations
+- GCTraceTime tm("phase 3", PrintGCDetails && Verbose, true, _gc_timer);
++ GCTraceTime tm("phase 3", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+ trace("3");
+
+ ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+@@ -625,16 +625,16 @@
+ FlatProfiler::oops_do(adjust_pointer_closure());
+ Management::oops_do(adjust_pointer_closure());
+ JvmtiExport::oops_do(adjust_pointer_closure());
+- // SO_AllClasses
+ SystemDictionary::oops_do(adjust_pointer_closure());
+- ClassLoaderDataGraph::oops_do(adjust_pointer_closure(), adjust_klass_closure(), true);
++ ClassLoaderDataGraph::cld_do(adjust_cld_closure());
+
+ // Now adjust pointers in remaining weak roots. (All of which should
+ // have been cleared if they pointed to non-surviving objects.)
+ // Global (weak) JNI handles
+ JNIHandles::weak_oops_do(&always_true, adjust_pointer_closure());
+
+- CodeCache::oops_do(adjust_pointer_closure());
++ CodeBlobToOopClosure adjust_from_blobs(adjust_pointer_closure(), CodeBlobToOopClosure::FixRelocations);
++ CodeCache::blobs_do(&adjust_from_blobs);
+ StringTable::oops_do(adjust_pointer_closure());
+ ref_processor()->weak_oops_do(adjust_pointer_closure());
+ PSScavenge::reference_processor()->weak_oops_do(adjust_pointer_closure());
+@@ -647,7 +647,7 @@
+
+ void PSMarkSweep::mark_sweep_phase4() {
+ EventMark m("4 compact heap");
+- GCTraceTime tm("phase 4", PrintGCDetails && Verbose, true, _gc_timer);
++ GCTraceTime tm("phase 4", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+ trace("4");
+
+ // All pointers are now adjusted, move objects accordingly
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -40,11 +40,11 @@
+ static CollectorCounters* _counters;
+
+ // Closure accessors
+- static OopClosure* mark_and_push_closure() { return &MarkSweep::mark_and_push_closure; }
+- static KlassClosure* follow_klass_closure() { return &MarkSweep::follow_klass_closure; }
+- static VoidClosure* follow_stack_closure() { return (VoidClosure*)&MarkSweep::follow_stack_closure; }
+- static OopClosure* adjust_pointer_closure() { return (OopClosure*)&MarkSweep::adjust_pointer_closure; }
+- static KlassClosure* adjust_klass_closure() { return &MarkSweep::adjust_klass_closure; }
++ static OopClosure* mark_and_push_closure() { return &MarkSweep::mark_and_push_closure; }
++ static VoidClosure* follow_stack_closure() { return (VoidClosure*)&MarkSweep::follow_stack_closure; }
++ static CLDClosure* follow_cld_closure() { return &MarkSweep::follow_cld_closure; }
++ static OopClosure* adjust_pointer_closure() { return (OopClosure*)&MarkSweep::adjust_pointer_closure; }
++ static CLDClosure* adjust_cld_closure() { return &MarkSweep::adjust_cld_closure; }
+ static BoolObjectClosure* is_alive_closure() { return (BoolObjectClosure*)&MarkSweep::is_alive; }
+
+ debug_only(public:) // Used for PSParallelCompact debugging
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -32,6 +32,7 @@
+ #include "gc_implementation/shared/markSweep.inline.hpp"
+ #include "gc_implementation/shared/spaceDecorator.hpp"
+ #include "oops/oop.inline.hpp"
++#include "runtime/prefetch.inline.hpp"
+
+ PSMarkSweepDecorator* PSMarkSweepDecorator::_destination_decorator = NULL;
+
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -978,7 +978,7 @@
+ // at each young gen gc. Do the update unconditionally (even though a
+ // promotion failure does not swap spaces) because an unknown number of minor
+ // collections will have swapped the spaces an unknown number of times.
+- GCTraceTime tm("pre compact", print_phases(), true, &_gc_timer);
++ GCTraceTime tm("pre compact", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+ ParallelScavengeHeap* heap = gc_heap();
+ _space_info[from_space_id].set_space(heap->young_gen()->from_space());
+ _space_info[to_space_id].set_space(heap->young_gen()->to_space());
+@@ -1021,7 +1021,7 @@
+
+ void PSParallelCompact::post_compact()
+ {
+- GCTraceTime tm("post compact", print_phases(), true, &_gc_timer);
++ GCTraceTime tm("post compact", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+
+ for (unsigned int id = old_space_id; id < last_space_id; ++id) {
+ // Clear the marking bitmap, summary data and split info.
+@@ -1847,7 +1847,7 @@
+ void PSParallelCompact::summary_phase(ParCompactionManager* cm,
+ bool maximum_compaction)
+ {
+- GCTraceTime tm("summary phase", print_phases(), true, &_gc_timer);
++ GCTraceTime tm("summary phase", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+ // trace("2");
+
+ #ifdef ASSERT
+@@ -2056,7 +2056,7 @@
+
+ gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
+ TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
+- GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
++ GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer.gc_id());
+ TraceCollectorStats tcs(counters());
+ TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
+
+@@ -2351,7 +2351,7 @@
+ bool maximum_heap_compaction,
+ ParallelOldTracer *gc_tracer) {
+ // Recursively traverse all live objects and mark them
+- GCTraceTime tm("marking phase", print_phases(), true, &_gc_timer);
++ GCTraceTime tm("marking phase", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+
+ ParallelScavengeHeap* heap = gc_heap();
+ uint parallel_gc_threads = heap->gc_task_manager()->workers();
+@@ -2366,7 +2366,7 @@
+ ClassLoaderDataGraph::clear_claimed_marks();
+
+ {
+- GCTraceTime tm_m("par mark", print_phases(), true, &_gc_timer);
++ GCTraceTime tm_m("par mark", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+
+ ParallelScavengeHeap::ParStrongRootsScope psrs;
+
+@@ -2395,24 +2395,24 @@
+
+ // Process reference objects found during marking
+ {
+- GCTraceTime tm_r("reference processing", print_phases(), true, &_gc_timer);
++ GCTraceTime tm_r("reference processing", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+
+ ReferenceProcessorStats stats;
+ if (ref_processor()->processing_is_mt()) {
+ RefProcTaskExecutor task_executor;
+ stats = ref_processor()->process_discovered_references(
+ is_alive_closure(), &mark_and_push_closure, &follow_stack_closure,
+- &task_executor, &_gc_timer);
++ &task_executor, &_gc_timer, _gc_tracer.gc_id());
+ } else {
+ stats = ref_processor()->process_discovered_references(
+ is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, NULL,
+- &_gc_timer);
++ &_gc_timer, _gc_tracer.gc_id());
+ }
+
+ gc_tracer->report_gc_reference_stats(stats);
+ }
+
+- GCTraceTime tm_c("class unloading", print_phases(), true, &_gc_timer);
++ GCTraceTime tm_c("class unloading", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+
+ // This is the point where the entire marking should have completed.
+ assert(cm->marking_stacks_empty(), "Marking should have completed");
+@@ -2451,7 +2451,7 @@
+
+ void PSParallelCompact::adjust_roots() {
+ // Adjust the pointers to reflect the new locations
+- GCTraceTime tm("adjust roots", print_phases(), true, &_gc_timer);
++ GCTraceTime tm("adjust roots", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+
+ // Need new claim bits when tracing through and adjusting pointers.
+ ClassLoaderDataGraph::clear_claimed_marks();
+@@ -2465,7 +2465,6 @@
+ FlatProfiler::oops_do(adjust_pointer_closure());
+ Management::oops_do(adjust_pointer_closure());
+ JvmtiExport::oops_do(adjust_pointer_closure());
+- // SO_AllClasses
+ SystemDictionary::oops_do(adjust_pointer_closure());
+ ClassLoaderDataGraph::oops_do(adjust_pointer_closure(), adjust_klass_closure(), true);
+
+@@ -2474,7 +2473,8 @@
+ // Global (weak) JNI handles
+ JNIHandles::weak_oops_do(&always_true, adjust_pointer_closure());
+
+- CodeCache::oops_do(adjust_pointer_closure());
++ CodeBlobToOopClosure adjust_from_blobs(adjust_pointer_closure(), CodeBlobToOopClosure::FixRelocations);
++ CodeCache::blobs_do(&adjust_from_blobs);
+ StringTable::oops_do(adjust_pointer_closure());
+ ref_processor()->weak_oops_do(adjust_pointer_closure());
+ // Roots were visited so references into the young gen in roots
+@@ -2487,7 +2487,7 @@
+ void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q,
+ uint parallel_gc_threads)
+ {
+- GCTraceTime tm("drain task setup", print_phases(), true, &_gc_timer);
++ GCTraceTime tm("drain task setup", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+
+ // Find the threads that are active
+ unsigned int which = 0;
+@@ -2561,7 +2561,7 @@
+
+ void PSParallelCompact::enqueue_dense_prefix_tasks(GCTaskQueue* q,
+ uint parallel_gc_threads) {
+- GCTraceTime tm("dense prefix task setup", print_phases(), true, &_gc_timer);
++ GCTraceTime tm("dense prefix task setup", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+
+ ParallelCompactData& sd = PSParallelCompact::summary_data();
+
+@@ -2643,7 +2643,7 @@
+ GCTaskQueue* q,
+ ParallelTaskTerminator* terminator_ptr,
+ uint parallel_gc_threads) {
+- GCTraceTime tm("steal task setup", print_phases(), true, &_gc_timer);
++ GCTraceTime tm("steal task setup", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+
+ // Once a thread has drained it's stack, it should try to steal regions from
+ // other threads.
+@@ -2691,7 +2691,7 @@
+
+ void PSParallelCompact::compact() {
+ // trace("5");
+- GCTraceTime tm("compaction phase", print_phases(), true, &_gc_timer);
++ GCTraceTime tm("compaction phase", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+
+ ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
+ assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+@@ -2708,7 +2708,7 @@
+ enqueue_region_stealing_tasks(q, &terminator, active_gc_threads);
+
+ {
+- GCTraceTime tm_pc("par compact", print_phases(), true, &_gc_timer);
++ GCTraceTime tm_pc("par compact", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+
+ gc_task_manager()->execute_and_wait(q);
+
+@@ -2722,7 +2722,7 @@
+
+ {
+ // Update the deferred objects, if any. Any compaction manager can be used.
+- GCTraceTime tm_du("deferred updates", print_phases(), true, &_gc_timer);
++ GCTraceTime tm_du("deferred updates", print_phases(), true, &_gc_timer, _gc_tracer.gc_id());
+ ParCompactionManager* cm = ParCompactionManager::manager_array(0);
+ for (unsigned int id = old_space_id; id < last_space_id; ++id) {
+ update_deferred_objects(cm, SpaceId(id));
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1004,6 +1004,10 @@
+ static bool _dwl_initialized;
+ #endif // #ifdef ASSERT
+
++
++ public:
++ static ParallelOldTracer* gc_tracer() { return &_gc_tracer; }
++
+ private:
+
+ static void initialize_space_info();
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,6 +26,7 @@
+ #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONLAB_HPP
+
+ #include "gc_implementation/parallelScavenge/objectStartArray.hpp"
++#include "gc_interface/collectedHeap.inline.hpp"
+ #include "memory/allocation.hpp"
+
+ //
+@@ -94,23 +95,9 @@
+ PSYoungPromotionLAB() { }
+
+ // Not MT safe
+- HeapWord* allocate(size_t size) {
+- // Can't assert this, when young fills, we keep the LAB around, but flushed.
+- // assert(_state != flushed, "Sanity");
+- HeapWord* obj = top();
+- HeapWord* new_top = obj + size;
+- // The 'new_top>obj' check is needed to detect overflow of obj+size.
+- if (new_top > obj && new_top <= end()) {
+- set_top(new_top);
+- assert(is_object_aligned((intptr_t)obj) && is_object_aligned((intptr_t)new_top),
+- "checking alignment");
+- return obj;
+- }
++ inline HeapWord* allocate(size_t size);
+
+- return NULL;
+- }
+-
+- debug_only(virtual bool lab_is_valid(MemRegion lab));
++ debug_only(virtual bool lab_is_valid(MemRegion lab);)
+ };
+
+ class PSOldPromotionLAB : public PSPromotionLAB {
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONLAB_INLINE_HPP
++#define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONLAB_INLINE_HPP
++
++#include "gc_implementation/parallelScavenge/psPromotionLAB.hpp"
++#include "gc_interface/collectedHeap.inline.hpp"
++
++HeapWord* PSYoungPromotionLAB::allocate(size_t size) {
++ // Can't assert this, when young fills, we keep the LAB around, but flushed.
++ // assert(_state != flushed, "Sanity");
++ HeapWord* obj = CollectedHeap::align_allocation_or_fail(top(), end(), SurvivorAlignmentInBytes);
++ if (obj == NULL) {
++ return NULL;
++ }
++
++ HeapWord* new_top = obj + size;
++ // The 'new_top>obj' check is needed to detect overflow of obj+size.
++ if (new_top > obj && new_top <= end()) {
++ set_top(new_top);
++ assert(is_ptr_aligned(obj, SurvivorAlignmentInBytes) && is_object_aligned((intptr_t)new_top),
++ "checking alignment");
++ return obj;
++ } else {
++ set_top(obj);
++ return NULL;
++ }
++}
++
++#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONLAB_INLINE_HPP
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -27,6 +27,7 @@
+
+ #include "gc_implementation/parallelScavenge/psOldGen.hpp"
+ #include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
++#include "gc_implementation/parallelScavenge/psPromotionLAB.inline.hpp"
+ #include "gc_implementation/parallelScavenge/psScavenge.hpp"
+ #include "oops/oop.psgc.inline.hpp"
+
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -331,7 +331,7 @@
+
+ gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
+ TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
+- GCTraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
++ GCTraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer.gc_id());
+ TraceCollectorStats tcs(counters());
+ TraceMemoryManagerStats tms(false /* not full GC */,gc_cause);
+
+@@ -397,7 +397,7 @@
+ // We'll use the promotion manager again later.
+ PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager();
+ {
+- GCTraceTime tm("Scavenge", false, false, &_gc_timer);
++ GCTraceTime tm("Scavenge", false, false, &_gc_timer, _gc_tracer.gc_id());
+ ParallelScavengeHeap::ParStrongRootsScope psrs;
+
+ GCTaskQueue* q = GCTaskQueue::create();
+@@ -439,7 +439,7 @@
+
+ // Process reference objects discovered during scavenge
+ {
+- GCTraceTime tm("References", false, false, &_gc_timer);
++ GCTraceTime tm("References", false, false, &_gc_timer, _gc_tracer.gc_id());
+
+ reference_processor()->setup_policy(false); // not always_clear
+ reference_processor()->set_active_mt_degree(active_workers);
+@@ -450,10 +450,10 @@
+ PSRefProcTaskExecutor task_executor;
+ stats = reference_processor()->process_discovered_references(
+ &_is_alive_closure, &keep_alive, &evac_followers, &task_executor,
+- &_gc_timer);
++ &_gc_timer, _gc_tracer.gc_id());
+ } else {
+ stats = reference_processor()->process_discovered_references(
+- &_is_alive_closure, &keep_alive, &evac_followers, NULL, &_gc_timer);
++ &_is_alive_closure, &keep_alive, &evac_followers, NULL, &_gc_timer, _gc_tracer.gc_id());
+ }
+
+ _gc_tracer.report_gc_reference_stats(stats);
+@@ -468,7 +468,7 @@
+ }
+
+ {
+- GCTraceTime tm("StringTable", false, false, &_gc_timer);
++ GCTraceTime tm("StringTable", false, false, &_gc_timer, _gc_tracer.gc_id());
+ // Unlink any dead interned Strings and process the remaining live ones.
+ PSScavengeRootsClosure root_closure(promotion_manager);
+ StringTable::unlink_or_oops_do(&_is_alive_closure, &root_closure);
+@@ -638,7 +638,7 @@
+ NOT_PRODUCT(reference_processor()->verify_no_references_recorded());
+
+ {
+- GCTraceTime tm("Prune Scavenge Root Methods", false, false, &_gc_timer);
++ GCTraceTime tm("Prune Scavenge Root Methods", false, false, &_gc_timer, _gc_tracer.gc_id());
+
+ CodeCache::prune_scavenge_root_nmethods();
+ }
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -65,7 +65,7 @@
+ case threads:
+ {
+ ResourceMark rm;
+- CLDToOopClosure* cld_closure = NULL; // Not needed. All CLDs are already visited.
++ CLDClosure* cld_closure = NULL; // Not needed. All CLDs are already visited.
+ Threads::oops_do(&roots_closure, cld_closure, NULL);
+ }
+ break;
+@@ -100,7 +100,7 @@
+
+ case code_cache:
+ {
+- CodeBlobToOopClosure each_scavengable_code_blob(&roots_to_old_closure, /*do_marking=*/ true);
++ MarkingCodeBlobClosure each_scavengable_code_blob(&roots_to_old_closure, CodeBlobToOopClosure::FixRelocations);
+ CodeCache::scavenge_root_nmethods_do(&each_scavengable_code_blob);
+ }
+ break;
+@@ -122,8 +122,8 @@
+
+ PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
+ PSScavengeRootsClosure roots_closure(pm);
+- CLDToOopClosure* roots_from_clds = NULL; // Not needed. All CLDs are already visited.
+- CodeBlobToOopClosure roots_in_blobs(&roots_closure, /*do_marking=*/ true);
++ CLDClosure* roots_from_clds = NULL; // Not needed. All CLDs are already visited.
++ MarkingCodeBlobClosure roots_in_blobs(&roots_closure, CodeBlobToOopClosure::FixRelocations);
+
+ if (_java_thread != NULL)
+ _java_thread->oops_do(&roots_closure, roots_from_clds, &roots_in_blobs);
+--- ./hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -70,7 +70,7 @@
+ "must be a ParallelScavengeHeap");
+
+ GCCauseSetter gccs(heap, _gc_cause);
+- if (_gc_cause == GCCause::_gc_locker
++ if (_gc_cause == GCCause::_gc_locker || _gc_cause == GCCause::_wb_young_gc
+ DEBUG_ONLY(|| _gc_cause == GCCause::_scavenge_alot)) {
+ // If (and only if) the scavenge fails, this will invoke a full gc.
+ heap->invoke_scavenge();
+--- ./hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -36,21 +36,10 @@
+
+ int ConcurrentGCThread::_CGC_flag = CGC_nil;
+
+-SuspendibleThreadSet ConcurrentGCThread::_sts;
+-
+ ConcurrentGCThread::ConcurrentGCThread() :
+ _should_terminate(false), _has_terminated(false) {
+- _sts.initialize();
+ };
+
+-void ConcurrentGCThread::safepoint_synchronize() {
+- _sts.suspend_all();
+-}
+-
+-void ConcurrentGCThread::safepoint_desynchronize() {
+- _sts.resume_all();
+-}
+-
+ void ConcurrentGCThread::create_and_start() {
+ if (os::create_thread(this, os::cgc_thread)) {
+ // XXX: need to set this to low priority
+@@ -91,78 +80,6 @@
+ ThreadLocalStorage::set_thread(NULL);
+ }
+
+-
+-void SuspendibleThreadSet::initialize_work() {
+- MutexLocker x(STS_init_lock);
+- if (!_initialized) {
+- _m = new Monitor(Mutex::leaf,
+- "SuspendibleThreadSetLock", true);
+- _async = 0;
+- _async_stop = false;
+- _async_stopped = 0;
+- _initialized = true;
+- }
+-}
+-
+-void SuspendibleThreadSet::join() {
+- initialize();
+- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
+- while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag);
+- _async++;
+- assert(_async > 0, "Huh.");
+-}
+-
+-void SuspendibleThreadSet::leave() {
+- assert(_initialized, "Must be initialized.");
+- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
+- _async--;
+- assert(_async >= 0, "Huh.");
+- if (_async_stop) _m->notify_all();
+-}
+-
+-void SuspendibleThreadSet::yield(const char* id) {
+- assert(_initialized, "Must be initialized.");
+- if (_async_stop) {
+- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
+- if (_async_stop) {
+- _async_stopped++;
+- assert(_async_stopped > 0, "Huh.");
+- if (_async_stopped == _async) {
+- if (ConcGCYieldTimeout > 0) {
+- double now = os::elapsedTime();
+- guarantee((now - _suspend_all_start) * 1000.0 <
+- (double)ConcGCYieldTimeout,
+- "Long delay; whodunit?");
+- }
+- }
+- _m->notify_all();
+- while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag);
+- _async_stopped--;
+- assert(_async >= 0, "Huh");
+- _m->notify_all();
+- }
+- }
+-}
+-
+-void SuspendibleThreadSet::suspend_all() {
+- initialize(); // If necessary.
+- if (ConcGCYieldTimeout > 0) {
+- _suspend_all_start = os::elapsedTime();
+- }
+- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
+- assert(!_async_stop, "Only one at a time.");
+- _async_stop = true;
+- while (_async_stopped < _async) _m->wait(Mutex::_no_safepoint_check_flag);
+-}
+-
+-void SuspendibleThreadSet::resume_all() {
+- assert(_initialized, "Must be initialized.");
+- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
+- assert(_async_stopped == _async, "Huh.");
+- _async_stop = false;
+- _m->notify_all();
+-}
+-
+ static void _sltLoop(JavaThread* thread, TRAPS) {
+ SurrogateLockerThread* slt = (SurrogateLockerThread*)thread;
+ slt->loop();
+@@ -220,6 +137,13 @@
+ return res;
+ }
+
++void SurrogateLockerThread::report_missing_slt() {
++ vm_exit_during_initialization(
++ "GC before GC support fully initialized: "
++ "SLT is needed but has not yet been created.");
++ ShouldNotReachHere();
++}
++
+ void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) {
+ MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
+ assert(_buffer == empty, "Should be empty");
+@@ -282,30 +206,3 @@
+ }
+ assert(!_monitor.owned_by_self(), "Should unlock before exit.");
+ }
+-
+-
+-// ===== STS Access From Outside CGCT =====
+-
+-void ConcurrentGCThread::stsYield(const char* id) {
+- assert( Thread::current()->is_ConcurrentGC_thread(),
+- "only a conc GC thread can call this" );
+- _sts.yield(id);
+-}
+-
+-bool ConcurrentGCThread::stsShouldYield() {
+- assert( Thread::current()->is_ConcurrentGC_thread(),
+- "only a conc GC thread can call this" );
+- return _sts.should_yield();
+-}
+-
+-void ConcurrentGCThread::stsJoin() {
+- assert( Thread::current()->is_ConcurrentGC_thread(),
+- "only a conc GC thread can call this" );
+- _sts.join();
+-}
+-
+-void ConcurrentGCThread::stsLeave() {
+- assert( Thread::current()->is_ConcurrentGC_thread(),
+- "only a conc GC thread can call this" );
+- _sts.leave();
+-}
+--- ./hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,55 +26,8 @@
+ #define SHARE_VM_GC_IMPLEMENTATION_SHARED_CONCURRENTGCTHREAD_HPP
+
+ #include "utilities/macros.hpp"
+-#if INCLUDE_ALL_GCS
++#include "gc_implementation/shared/suspendibleThreadSet.hpp"
+ #include "runtime/thread.hpp"
+-#endif // INCLUDE_ALL_GCS
+-
+-class VoidClosure;
+-
+-// A SuspendibleThreadSet is (obviously) a set of threads that can be
+-// suspended. A thread can join and later leave the set, and periodically
+-// yield. If some thread (not in the set) requests, via suspend_all, that
+-// the threads be suspended, then the requesting thread is blocked until
+-// all the threads in the set have yielded or left the set. (Threads may
+-// not enter the set when an attempted suspension is in progress.) The
+-// suspending thread later calls resume_all, allowing the suspended threads
+-// to continue.
+-
+-class SuspendibleThreadSet {
+- Monitor* _m;
+- int _async;
+- bool _async_stop;
+- int _async_stopped;
+- bool _initialized;
+- double _suspend_all_start;
+-
+- void initialize_work();
+-
+- public:
+- SuspendibleThreadSet() : _initialized(false) {}
+-
+- // Add the current thread to the set. May block if a suspension
+- // is in progress.
+- void join();
+- // Removes the current thread from the set.
+- void leave();
+- // Returns "true" iff an suspension is in progress.
+- bool should_yield() { return _async_stop; }
+- // Suspends the current thread if a suspension is in progress (for
+- // the duration of the suspension.)
+- void yield(const char* id);
+- // Return when all threads in the set are suspended.
+- void suspend_all();
+- // Allow suspended threads to resume.
+- void resume_all();
+- // Redundant initializations okay.
+- void initialize() {
+- // Double-check dirty read idiom.
+- if (!_initialized) initialize_work();
+- }
+-};
+-
+
+ class ConcurrentGCThread: public NamedThread {
+ friend class VMStructs;
+@@ -96,9 +49,6 @@
+ static int set_CGC_flag(int b) { return _CGC_flag |= b; }
+ static int reset_CGC_flag(int b) { return _CGC_flag &= ~b; }
+
+- // All instances share this one set.
+- static SuspendibleThreadSet _sts;
+-
+ // Create and start the thread (setting it's priority high.)
+ void create_and_start();
+
+@@ -121,25 +71,6 @@
+
+ // Tester
+ bool is_ConcurrentGC_thread() const { return true; }
+-
+- static void safepoint_synchronize();
+- static void safepoint_desynchronize();
+-
+- // All overridings should probably do _sts::yield, but we allow
+- // overriding for distinguished debugging messages. Default is to do
+- // nothing.
+- virtual void yield() {}
+-
+- bool should_yield() { return _sts.should_yield(); }
+-
+- // they are prefixed by sts since there are already yield() and
+- // should_yield() (non-static) methods in this class and it was an
+- // easy way to differentiate them.
+- static void stsYield(const char* id);
+- static bool stsShouldYield();
+- static void stsJoin();
+- static void stsLeave();
+-
+ };
+
+ // The SurrogateLockerThread is used by concurrent GC threads for
+@@ -162,6 +93,9 @@
+ public:
+ static SurrogateLockerThread* make(TRAPS);
+
++ // Terminate VM with error message that SLT needed but not yet created.
++ static void report_missing_slt();
++
+ SurrogateLockerThread();
+
+ bool is_hidden_from_external_view() const { return true; }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/shared/gcId.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "gc_implementation/shared/gcId.hpp"
++#include "runtime/safepoint.hpp"
++
++uint GCId::_next_id = 0;
++
++const GCId GCId::create() {
++ return GCId(_next_id++);
++}
++const GCId GCId::peek() {
++ return GCId(_next_id);
++}
++const GCId GCId::undefined() {
++ return GCId(UNDEFINED);
++}
++bool GCId::is_undefined() const {
++ return _id == UNDEFINED;
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/shared/gcId.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,51 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GCID_HPP
++#define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCID_HPP
++
++#include "memory/allocation.hpp"
++
++class GCId VALUE_OBJ_CLASS_SPEC {
++ private:
++ uint _id;
++ GCId(uint id) : _id(id) {}
++ GCId() { } // Unused
++
++ static uint _next_id;
++ static const uint UNDEFINED = (uint)-1;
++
++ public:
++ uint id() const {
++ assert(_id != UNDEFINED, "Using undefined GC ID");
++ return _id;
++ }
++ bool is_undefined() const;
++
++ static const GCId create();
++ static const GCId peek();
++ static const GCId undefined();
++};
++
++#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_GCID_HPP
+--- ./hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,6 +25,7 @@
+ #include "precompiled.hpp"
+ #include "gc_implementation/shared/copyFailedInfo.hpp"
+ #include "gc_implementation/shared/gcHeapSummary.hpp"
++#include "gc_implementation/shared/gcId.hpp"
+ #include "gc_implementation/shared/gcTimer.hpp"
+ #include "gc_implementation/shared/gcTrace.hpp"
+ #include "gc_implementation/shared/objectCountEventSender.hpp"
+@@ -38,19 +39,14 @@
+ #include "gc_implementation/g1/evacuationInfo.hpp"
+ #endif
+
+-#define assert_unset_gc_id() assert(_shared_gc_info.id() == SharedGCInfo::UNSET_GCID, "GC already started?")
+-#define assert_set_gc_id() assert(_shared_gc_info.id() != SharedGCInfo::UNSET_GCID, "GC not started?")
+-
+-static GCId GCTracer_next_gc_id = 0;
+-static GCId create_new_gc_id() {
+- return GCTracer_next_gc_id++;
+-}
++#define assert_unset_gc_id() assert(_shared_gc_info.gc_id().is_undefined(), "GC already started?")
++#define assert_set_gc_id() assert(!_shared_gc_info.gc_id().is_undefined(), "GC not started?")
+
+ void GCTracer::report_gc_start_impl(GCCause::Cause cause, const Ticks& timestamp) {
+ assert_unset_gc_id();
+
+- GCId gc_id = create_new_gc_id();
+- _shared_gc_info.set_id(gc_id);
++ GCId gc_id = GCId::create();
++ _shared_gc_info.set_gc_id(gc_id);
+ _shared_gc_info.set_cause(cause);
+ _shared_gc_info.set_start_timestamp(timestamp);
+ }
+@@ -62,7 +58,7 @@
+ }
+
+ bool GCTracer::has_reported_gc_start() const {
+- return _shared_gc_info.id() != SharedGCInfo::UNSET_GCID;
++ return !_shared_gc_info.gc_id().is_undefined();
+ }
+
+ void GCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) {
+@@ -81,7 +77,7 @@
+
+ report_gc_end_impl(timestamp, time_partitions);
+
+- _shared_gc_info.set_id(SharedGCInfo::UNSET_GCID);
++ _shared_gc_info.set_gc_id(GCId::undefined());
+ }
+
+ void GCTracer::report_gc_reference_stats(const ReferenceProcessorStats& rps) const {
+@@ -132,7 +128,7 @@
+ if (!cit.allocation_failed()) {
+ HeapInspection hi(false, false, false, NULL);
+ hi.populate_table(&cit, is_alive_cl);
+- ObjectCountEventSenderClosure event_sender(_shared_gc_info.id(), cit.size_of_instances_in_words(), Ticks::now());
++ ObjectCountEventSenderClosure event_sender(_shared_gc_info.gc_id(), cit.size_of_instances_in_words(), Ticks::now());
+ cit.iterate(&event_sender);
+ }
+ }
+--- ./hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -27,6 +27,7 @@
+
+ #include "gc_interface/gcCause.hpp"
+ #include "gc_interface/gcName.hpp"
++#include "gc_implementation/shared/gcId.hpp"
+ #include "gc_implementation/shared/gcWhen.hpp"
+ #include "gc_implementation/shared/copyFailedInfo.hpp"
+ #include "memory/allocation.hpp"
+@@ -38,7 +39,6 @@
+ #include "utilities/macros.hpp"
+ #include "utilities/ticks.hpp"
+
+-typedef uint GCId;
+
+ class EvacuationInfo;
+ class GCHeapSummary;
+@@ -50,11 +50,8 @@
+ class BoolObjectClosure;
+
+ class SharedGCInfo VALUE_OBJ_CLASS_SPEC {
+- public:
+- static const GCId UNSET_GCID = (GCId)-1;
+-
+ private:
+- GCId _id;
++ GCId _gc_id;
+ GCName _name;
+ GCCause::Cause _cause;
+ Ticks _start_timestamp;
+@@ -64,7 +61,7 @@
+
+ public:
+ SharedGCInfo(GCName name) :
+- _id(UNSET_GCID),
++ _gc_id(GCId::undefined()),
+ _name(name),
+ _cause(GCCause::_last_gc_cause),
+ _start_timestamp(),
+@@ -73,8 +70,8 @@
+ _longest_pause() {
+ }
+
+- void set_id(GCId id) { _id = id; }
+- GCId id() const { return _id; }
++ void set_gc_id(GCId gc_id) { _gc_id = gc_id; }
++ const GCId& gc_id() const { return _gc_id; }
+
+ void set_start_timestamp(const Ticks& timestamp) { _start_timestamp = timestamp; }
+ const Ticks start_timestamp() const { return _start_timestamp; }
+@@ -131,10 +128,11 @@
+ void report_gc_reference_stats(const ReferenceProcessorStats& rp) const;
+ void report_object_count_after_gc(BoolObjectClosure* object_filter) NOT_SERVICES_RETURN;
+ bool has_reported_gc_start() const;
++ const GCId& gc_id() { return _shared_gc_info.gc_id(); }
+
+ protected:
+ GCTracer(GCName name) : _shared_gc_info(name) {}
+- virtual void report_gc_start_impl(GCCause::Cause cause, const Ticks& timestamp);
++ void report_gc_start_impl(GCCause::Cause cause, const Ticks& timestamp);
+ virtual void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions);
+
+ private:
+--- ./hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -43,7 +43,7 @@
+ void GCTracer::send_garbage_collection_event() const {
+ EventGCGarbageCollection event(UNTIMED);
+ if (event.should_commit()) {
+- event.set_gcId(_shared_gc_info.id());
++ event.set_gcId(_shared_gc_info.gc_id().id());
+ event.set_name(_shared_gc_info.name());
+ event.set_cause((u2) _shared_gc_info.cause());
+ event.set_sumOfPauses(_shared_gc_info.sum_of_pauses());
+@@ -57,7 +57,7 @@
+ void GCTracer::send_reference_stats_event(ReferenceType type, size_t count) const {
+ EventGCReferenceStatistics e;
+ if (e.should_commit()) {
+- e.set_gcId(_shared_gc_info.id());
++ e.set_gcId(_shared_gc_info.gc_id().id());
+ e.set_type((u1)type);
+ e.set_count(count);
+ e.commit();
+@@ -68,7 +68,7 @@
+ const MetaspaceChunkFreeListSummary& summary) const {
+ EventMetaspaceChunkFreeListSummary e;
+ if (e.should_commit()) {
+- e.set_gcId(_shared_gc_info.id());
++ e.set_gcId(_shared_gc_info.gc_id().id());
+ e.set_when(when);
+ e.set_metadataType(mdtype);
+
+@@ -91,7 +91,7 @@
+ void ParallelOldTracer::send_parallel_old_event() const {
+ EventGCParallelOld e(UNTIMED);
+ if (e.should_commit()) {
+- e.set_gcId(_shared_gc_info.id());
++ e.set_gcId(_shared_gc_info.gc_id().id());
+ e.set_densePrefix((TraceAddress)_parallel_old_gc_info.dense_prefix());
+ e.set_starttime(_shared_gc_info.start_timestamp());
+ e.set_endtime(_shared_gc_info.end_timestamp());
+@@ -102,7 +102,7 @@
+ void YoungGCTracer::send_young_gc_event() const {
+ EventGCYoungGarbageCollection e(UNTIMED);
+ if (e.should_commit()) {
+- e.set_gcId(_shared_gc_info.id());
++ e.set_gcId(_shared_gc_info.gc_id().id());
+ e.set_tenuringThreshold(_tenuring_threshold);
+ e.set_starttime(_shared_gc_info.start_timestamp());
+ e.set_endtime(_shared_gc_info.end_timestamp());
+@@ -113,7 +113,7 @@
+ void OldGCTracer::send_old_gc_event() const {
+ EventGCOldGarbageCollection e(UNTIMED);
+ if (e.should_commit()) {
+- e.set_gcId(_shared_gc_info.id());
++ e.set_gcId(_shared_gc_info.gc_id().id());
+ e.set_starttime(_shared_gc_info.start_timestamp());
+ e.set_endtime(_shared_gc_info.end_timestamp());
+ e.commit();
+@@ -132,7 +132,7 @@
+ void YoungGCTracer::send_promotion_failed_event(const PromotionFailedInfo& pf_info) const {
+ EventPromotionFailed e;
+ if (e.should_commit()) {
+- e.set_gcId(_shared_gc_info.id());
++ e.set_gcId(_shared_gc_info.gc_id().id());
+ e.set_data(to_trace_struct(pf_info));
+ e.set_thread(pf_info.thread()->thread_id());
+ e.commit();
+@@ -143,7 +143,7 @@
+ void OldGCTracer::send_concurrent_mode_failure_event() {
+ EventConcurrentModeFailure e;
+ if (e.should_commit()) {
+- e.set_gcId(_shared_gc_info.id());
++ e.set_gcId(_shared_gc_info.gc_id().id());
+ e.commit();
+ }
+ }
+@@ -152,7 +152,7 @@
+ void G1NewTracer::send_g1_young_gc_event() {
+ EventGCG1GarbageCollection e(UNTIMED);
+ if (e.should_commit()) {
+- e.set_gcId(_shared_gc_info.id());
++ e.set_gcId(_shared_gc_info.gc_id().id());
+ e.set_type(_g1_young_gc_info.type());
+ e.set_starttime(_shared_gc_info.start_timestamp());
+ e.set_endtime(_shared_gc_info.end_timestamp());
+@@ -163,7 +163,7 @@
+ void G1NewTracer::send_evacuation_info_event(EvacuationInfo* info) {
+ EventEvacuationInfo e;
+ if (e.should_commit()) {
+- e.set_gcId(_shared_gc_info.id());
++ e.set_gcId(_shared_gc_info.gc_id().id());
+ e.set_cSetRegions(info->collectionset_regions());
+ e.set_cSetUsedBefore(info->collectionset_used_before());
+ e.set_cSetUsedAfter(info->collectionset_used_after());
+@@ -179,7 +179,7 @@
+ void G1NewTracer::send_evacuation_failed_event(const EvacuationFailedInfo& ef_info) const {
+ EventEvacuationFailed e;
+ if (e.should_commit()) {
+- e.set_gcId(_shared_gc_info.id());
++ e.set_gcId(_shared_gc_info.gc_id().id());
+ e.set_data(to_trace_struct(ef_info));
+ e.commit();
+ }
+@@ -206,17 +206,17 @@
+ }
+
+ class GCHeapSummaryEventSender : public GCHeapSummaryVisitor {
+- GCId _id;
++ GCId _gc_id;
+ GCWhen::Type _when;
+ public:
+- GCHeapSummaryEventSender(GCId id, GCWhen::Type when) : _id(id), _when(when) {}
++ GCHeapSummaryEventSender(GCId gc_id, GCWhen::Type when) : _gc_id(gc_id), _when(when) {}
+
+ void visit(const GCHeapSummary* heap_summary) const {
+ const VirtualSpaceSummary& heap_space = heap_summary->heap();
+
+ EventGCHeapSummary e;
+ if (e.should_commit()) {
+- e.set_gcId(_id);
++ e.set_gcId(_gc_id.id());
+ e.set_when((u1)_when);
+ e.set_heapSpace(to_trace_struct(heap_space));
+ e.set_heapUsed(heap_summary->used());
+@@ -236,7 +236,7 @@
+
+ EventPSHeapSummary e;
+ if (e.should_commit()) {
+- e.set_gcId(_id);
++ e.set_gcId(_gc_id.id());
+ e.set_when((u1)_when);
+
+ e.set_oldSpace(to_trace_struct(ps_heap_summary->old()));
+@@ -251,7 +251,7 @@
+ };
+
+ void GCTracer::send_gc_heap_summary_event(GCWhen::Type when, const GCHeapSummary& heap_summary) const {
+- GCHeapSummaryEventSender visitor(_shared_gc_info.id(), when);
++ GCHeapSummaryEventSender visitor(_shared_gc_info.gc_id(), when);
+ heap_summary.accept(&visitor);
+ }
+
+@@ -268,7 +268,7 @@
+ void GCTracer::send_meta_space_summary_event(GCWhen::Type when, const MetaspaceSummary& meta_space_summary) const {
+ EventMetaspaceSummary e;
+ if (e.should_commit()) {
+- e.set_gcId(_shared_gc_info.id());
++ e.set_gcId(_shared_gc_info.gc_id().id());
+ e.set_when((u1) when);
+ e.set_gcThreshold(meta_space_summary.capacity_until_GC());
+ e.set_metaspace(to_trace_struct(meta_space_summary.meta_space()));
+@@ -287,7 +287,7 @@
+ void send_phase(PausePhase* pause) {
+ T event(UNTIMED);
+ if (event.should_commit()) {
+- event.set_gcId(_gc_id);
++ event.set_gcId(_gc_id.id());
+ event.set_name(pause->name());
+ event.set_starttime(pause->start());
+ event.set_endtime(pause->end());
+@@ -311,7 +311,7 @@
+ };
+
+ void GCTracer::send_phase_events(TimePartitions* time_partitions) const {
+- PhaseSender phase_reporter(_shared_gc_info.id());
++ PhaseSender phase_reporter(_shared_gc_info.gc_id());
+
+ TimePartitionPhasesIterator iter(time_partitions);
+ while (iter.has_next()) {
+--- ./hotspot/src/share/vm/gc_implementation/shared/gcTraceTime.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/shared/gcTraceTime.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -24,6 +24,7 @@
+
+ #include "precompiled.hpp"
+ #include "gc_implementation/shared/gcTimer.hpp"
++#include "gc_implementation/shared/gcTrace.hpp"
+ #include "gc_implementation/shared/gcTraceTime.hpp"
+ #include "runtime/globals.hpp"
+ #include "runtime/os.hpp"
+@@ -34,7 +35,7 @@
+ #include "utilities/ticks.inline.hpp"
+
+
+-GCTraceTime::GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer) :
++GCTraceTime::GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer, GCId gc_id) :
+ _title(title), _doit(doit), _print_cr(print_cr), _timer(timer), _start_counter() {
+ if (_doit || _timer != NULL) {
+ _start_counter.stamp();
+@@ -52,6 +53,9 @@
+ gclog_or_tty->stamp();
+ gclog_or_tty->print(": ");
+ }
++ if (PrintGCID) {
++ gclog_or_tty->print("#%u: ", gc_id.id());
++ }
+ gclog_or_tty->print("[%s", title);
+ gclog_or_tty->flush();
+ }
+--- ./hotspot/src/share/vm/gc_implementation/shared/gcTraceTime.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/shared/gcTraceTime.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,6 +25,7 @@
+ #ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACETIME_HPP
+ #define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACETIME_HPP
+
++#include "gc_implementation/shared/gcTrace.hpp"
+ #include "prims/jni_md.h"
+ #include "utilities/ticks.hpp"
+
+@@ -38,7 +39,7 @@
+ Ticks _start_counter;
+
+ public:
+- GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer);
++ GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer, GCId gc_id);
+ ~GCTraceTime();
+ };
+
+--- ./hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -49,27 +49,19 @@
+ SerialOldTracer* MarkSweep::_gc_tracer = NULL;
+
+ MarkSweep::FollowRootClosure MarkSweep::follow_root_closure;
+-CodeBlobToOopClosure MarkSweep::follow_code_root_closure(&MarkSweep::follow_root_closure, /*do_marking=*/ true);
+
+ void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); }
+ void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); }
+
+ MarkSweep::MarkAndPushClosure MarkSweep::mark_and_push_closure;
+-MarkSweep::FollowKlassClosure MarkSweep::follow_klass_closure;
+-MarkSweep::AdjustKlassClosure MarkSweep::adjust_klass_closure;
++CLDToOopClosure MarkSweep::follow_cld_closure(&mark_and_push_closure);
++CLDToOopClosure MarkSweep::adjust_cld_closure(&adjust_pointer_closure);
+
+ void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(p); }
+ void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); }
+
+-void MarkSweep::FollowKlassClosure::do_klass(Klass* klass) {
+- klass->oops_do(&MarkSweep::mark_and_push_closure);
+-}
+-void MarkSweep::AdjustKlassClosure::do_klass(Klass* klass) {
+- klass->oops_do(&MarkSweep::adjust_pointer_closure);
+-}
+-
+ void MarkSweep::follow_class_loader(ClassLoaderData* cld) {
+- cld->oops_do(&MarkSweep::mark_and_push_closure, &MarkSweep::follow_klass_closure, true);
++ MarkSweep::follow_cld_closure.do_cld(cld);
+ }
+
+ void MarkSweep::follow_stack() {
+--- ./hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -65,17 +65,6 @@
+ virtual void do_oop(narrowOop* p);
+ };
+
+- // The one and only place to start following the classes.
+- // Should only be applied to the ClassLoaderData klasses list.
+- class FollowKlassClosure : public KlassClosure {
+- public:
+- void do_klass(Klass* klass);
+- };
+- class AdjustKlassClosure : public KlassClosure {
+- public:
+- void do_klass(Klass* klass);
+- };
+-
+ class FollowStackClosure: public VoidClosure {
+ public:
+ virtual void do_void();
+@@ -143,12 +132,11 @@
+ // Public closures
+ static IsAliveClosure is_alive;
+ static FollowRootClosure follow_root_closure;
+- static CodeBlobToOopClosure follow_code_root_closure; // => follow_root_closure
+ static MarkAndPushClosure mark_and_push_closure;
+- static FollowKlassClosure follow_klass_closure;
+ static FollowStackClosure follow_stack_closure;
++ static CLDToOopClosure follow_cld_closure;
+ static AdjustPointerClosure adjust_pointer_closure;
+- static AdjustKlassClosure adjust_klass_closure;
++ static CLDToOopClosure adjust_cld_closure;
+
+ // Accessors
+ static uint total_invocations() { return _total_invocations; }
+--- ./hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -24,12 +24,13 @@
+
+
+ #include "precompiled.hpp"
++#include "gc_implementation/shared/gcId.hpp"
+ #include "gc_implementation/shared/objectCountEventSender.hpp"
+ #include "memory/heapInspection.hpp"
+ #include "trace/tracing.hpp"
+ #include "utilities/globalDefinitions.hpp"
++#include "utilities/macros.hpp"
+ #include "utilities/ticks.hpp"
+-
+ #if INCLUDE_SERVICES
+
+ void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, const Ticks& timestamp) {
+@@ -38,7 +39,7 @@
+ "Only call this method if the event is enabled");
+
+ EventObjectCountAfterGC event(UNTIMED);
+- event.set_gcId(gc_id);
++ event.set_gcId(gc_id.id());
+ event.set_class(entry->klass());
+ event.set_count(entry->count());
+ event.set_totalSize(entry->words() * BytesPerWord);
+--- ./hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -24,7 +24,7 @@
+
+ #ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
+ #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
+-
++#include "gc_interface/collectedHeap.hpp"
+ #include "memory/allocation.hpp"
+ #include "memory/blockOffsetTable.hpp"
+ #include "memory/threadLocalAllocBuffer.hpp"
+@@ -60,6 +60,7 @@
+ // Initializes the buffer to be empty, but with the given "word_sz".
+ // Must get initialized with "set_buf" for an allocation to succeed.
+ ParGCAllocBuffer(size_t word_sz);
++ virtual ~ParGCAllocBuffer() {}
+
+ static const size_t min_size() {
+ // Make sure that we return something that is larger than AlignmentReserve
+@@ -84,6 +85,9 @@
+ }
+ }
+
++ // Allocate the object aligned to "alignment_in_bytes".
++ HeapWord* allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes);
++
+ // Undo the last allocation in the buffer, which is required to be of the
+ // "obj" of the given "word_sz".
+ void undo_allocation(HeapWord* obj, size_t word_sz) {
+@@ -114,7 +118,7 @@
+ }
+
+ // Sets the space of the buffer to be [buf, space+word_sz()).
+- void set_buf(HeapWord* buf) {
++ virtual void set_buf(HeapWord* buf) {
+ _bottom = buf;
+ _top = _bottom;
+ _hard_end = _bottom + word_sz();
+@@ -159,7 +163,7 @@
+ // Fills in the unallocated portion of the buffer with a garbage object.
+ // If "end_of_gc" is TRUE, is after the last use in the GC. IF "retain"
+ // is true, attempt to re-use the unused portion in the next GC.
+- void retire(bool end_of_gc, bool retain);
++ virtual void retire(bool end_of_gc, bool retain);
+
+ void print() PRODUCT_RETURN;
+ };
+@@ -239,14 +243,14 @@
+
+ void undo_allocation(HeapWord* obj, size_t word_sz);
+
+- void set_buf(HeapWord* buf_start) {
++ virtual void set_buf(HeapWord* buf_start) {
+ ParGCAllocBuffer::set_buf(buf_start);
+ _true_end = _hard_end;
+ _bt.set_region(MemRegion(buf_start, word_sz()));
+ _bt.initialize_threshold();
+ }
+
+- void retire(bool end_of_gc, bool retain);
++ virtual void retire(bool end_of_gc, bool retain);
+
+ MemRegion range() {
+ return MemRegion(_top, _true_end);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,44 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_PARGCALLOCBUFFER_INLINE_HPP
++#define SHARE_VM_GC_IMPLEMENTATION_SHARED_PARGCALLOCBUFFER_INLINE_HPP
++
++#include "gc_implementation/shared/parGCAllocBuffer.hpp"
++#include "gc_interface/collectedHeap.inline.hpp"
++
++HeapWord* ParGCAllocBuffer::allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes) {
++
++ HeapWord* res = CollectedHeap::align_allocation_or_fail(_top, _end, alignment_in_bytes);
++ if (res == NULL) {
++ return NULL;
++ }
++
++ // Set _top so that allocate(), which expects _top to be correctly set,
++ // can be used below.
++ _top = res;
++ return allocate(word_sz);
++}
++
++#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_PARGCALLOCBUFFER_INLINE_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/shared/suspendibleThreadSet.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,93 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "gc_implementation/shared/suspendibleThreadSet.hpp"
++#include "runtime/mutexLocker.hpp"
++#include "runtime/thread.inline.hpp"
++
++uint SuspendibleThreadSet::_nthreads = 0;
++uint SuspendibleThreadSet::_nthreads_stopped = 0;
++bool SuspendibleThreadSet::_suspend_all = false;
++double SuspendibleThreadSet::_suspend_all_start = 0.0;
++
++void SuspendibleThreadSet::join() {
++ MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
++ while (_suspend_all) {
++ ml.wait(Mutex::_no_safepoint_check_flag);
++ }
++ _nthreads++;
++}
++
++void SuspendibleThreadSet::leave() {
++ MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
++ assert(_nthreads > 0, "Invalid");
++ _nthreads--;
++ if (_suspend_all) {
++ ml.notify_all();
++ }
++}
++
++void SuspendibleThreadSet::yield() {
++ if (_suspend_all) {
++ MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
++ if (_suspend_all) {
++ _nthreads_stopped++;
++ if (_nthreads_stopped == _nthreads) {
++ if (ConcGCYieldTimeout > 0) {
++ double now = os::elapsedTime();
++ guarantee((now - _suspend_all_start) * 1000.0 < (double)ConcGCYieldTimeout, "Long delay");
++ }
++ }
++ ml.notify_all();
++ while (_suspend_all) {
++ ml.wait(Mutex::_no_safepoint_check_flag);
++ }
++ assert(_nthreads_stopped > 0, "Invalid");
++ _nthreads_stopped--;
++ ml.notify_all();
++ }
++ }
++}
++
++void SuspendibleThreadSet::synchronize() {
++ assert(Thread::current()->is_VM_thread(), "Must be the VM thread");
++ if (ConcGCYieldTimeout > 0) {
++ _suspend_all_start = os::elapsedTime();
++ }
++ MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
++ assert(!_suspend_all, "Only one at a time");
++ _suspend_all = true;
++ while (_nthreads_stopped < _nthreads) {
++ ml.wait(Mutex::_no_safepoint_check_flag);
++ }
++}
++
++void SuspendibleThreadSet::desynchronize() {
++ assert(Thread::current()->is_VM_thread(), "Must be the VM thread");
++ MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
++ assert(_nthreads_stopped == _nthreads, "Invalid");
++ _suspend_all = false;
++ ml.notify_all();
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/gc_implementation/shared/suspendibleThreadSet.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,84 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_SUSPENDIBLETHREADSET_HPP
++#define SHARE_VM_GC_IMPLEMENTATION_SHARED_SUSPENDIBLETHREADSET_HPP
++
++#include "memory/allocation.hpp"
++
++// A SuspendibleThreadSet is a set of threads that can be suspended.
++// A thread can join and later leave the set, and periodically yield.
++// If some thread (not in the set) requests, via synchronize(), that
++// the threads be suspended, then the requesting thread is blocked
++// until all the threads in the set have yielded or left the set. Threads
++// may not enter the set when an attempted suspension is in progress. The
++// suspending thread later calls desynchronize(), allowing the suspended
++// threads to continue.
++class SuspendibleThreadSet : public AllStatic {
++private:
++ static uint _nthreads;
++ static uint _nthreads_stopped;
++ static bool _suspend_all;
++ static double _suspend_all_start;
++
++public:
++ // Add the current thread to the set. May block if a suspension is in progress.
++ static void join();
++
++ // Removes the current thread from the set.
++ static void leave();
++
++ // Returns true if an suspension is in progress.
++ static bool should_yield() { return _suspend_all; }
++
++ // Suspends the current thread if a suspension is in progress.
++ static void yield();
++
++ // Returns when all threads in the set are suspended.
++ static void synchronize();
++
++ // Resumes all suspended threads in the set.
++ static void desynchronize();
++};
++
++class SuspendibleThreadSetJoiner : public StackObj {
++public:
++ SuspendibleThreadSetJoiner() {
++ SuspendibleThreadSet::join();
++ }
++
++ ~SuspendibleThreadSetJoiner() {
++ SuspendibleThreadSet::leave();
++ }
++
++ bool should_yield() {
++ return SuspendibleThreadSet::should_yield();
++ }
++
++ void yield() {
++ SuspendibleThreadSet::yield();
++ }
++};
++
++#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_SUSPENDIBLETHREADSET_HPP
+--- ./hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -209,6 +209,45 @@
+ gch->do_full_collection(gch->must_clear_all_soft_refs(), _max_level);
+ }
+
++// Returns true iff concurrent GCs unloads metadata.
++bool VM_CollectForMetadataAllocation::initiate_concurrent_GC() {
++#if INCLUDE_ALL_GCS
++ if (UseConcMarkSweepGC && CMSClassUnloadingEnabled) {
++ MetaspaceGC::set_should_concurrent_collect(true);
++ return true;
++ }
++
++ if (UseG1GC && ClassUnloadingWithConcurrentMark) {
++ G1CollectedHeap* g1h = G1CollectedHeap::heap();
++ g1h->g1_policy()->set_initiate_conc_mark_if_possible();
++
++ GCCauseSetter x(g1h, _gc_cause);
++
++ // At this point we are supposed to start a concurrent cycle. We
++ // will do so if one is not already in progress.
++ bool should_start = g1h->g1_policy()->force_initial_mark_if_outside_cycle(_gc_cause);
++
++ if (should_start) {
++ double pause_target = g1h->g1_policy()->max_pause_time_ms();
++ g1h->do_collection_pause_at_safepoint(pause_target);
++ }
++ return true;
++ }
++#endif
++
++ return false;
++}
++
++static void log_metaspace_alloc_failure_for_concurrent_GC() {
++ if (Verbose && PrintGCDetails) {
++ if (UseConcMarkSweepGC) {
++ gclog_or_tty->print_cr("\nCMS full GC for Metaspace");
++ } else if (UseG1GC) {
++ gclog_or_tty->print_cr("\nG1 full GC for Metaspace");
++ }
++ }
++}
++
+ void VM_CollectForMetadataAllocation::doit() {
+ SvcGCMarker sgcm(SvcGCMarker::FULL);
+
+@@ -220,54 +259,57 @@
+ // a GC that freed space for the allocation.
+ if (!MetadataAllocationFailALot) {
+ _result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype);
+- }
+-
+- if (_result == NULL) {
+- if (UseConcMarkSweepGC) {
+- if (CMSClassUnloadingEnabled) {
+- MetaspaceGC::set_should_concurrent_collect(true);
+- }
+- // For CMS expand since the collection is going to be concurrent.
+- _result =
+- _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype);
+- }
+- if (_result == NULL) {
+- // Don't clear the soft refs yet.
+- if (Verbose && PrintGCDetails && UseConcMarkSweepGC) {
+- gclog_or_tty->print_cr("\nCMS full GC for Metaspace");
+- }
+- heap->collect_as_vm_thread(GCCause::_metadata_GC_threshold);
+- // After a GC try to allocate without expanding. Could fail
+- // and expansion will be tried below.
+- _result =
+- _loader_data->metaspace_non_null()->allocate(_size, _mdtype);
+- }
+- if (_result == NULL) {
+- // If still failing, allow the Metaspace to expand.
+- // See delta_capacity_until_GC() for explanation of the
+- // amount of the expansion.
+- // This should work unless there really is no more space
+- // or a MaxMetaspaceSize has been specified on the command line.
+- _result =
+- _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype);
+- if (_result == NULL) {
+- // If expansion failed, do a last-ditch collection and try allocating
+- // again. A last-ditch collection will clear softrefs. This
+- // behavior is similar to the last-ditch collection done for perm
+- // gen when it was full and a collection for failed allocation
+- // did not free perm gen space.
+- heap->collect_as_vm_thread(GCCause::_last_ditch_collection);
+- _result =
+- _loader_data->metaspace_non_null()->allocate(_size, _mdtype);
+- }
+- }
+- if (Verbose && PrintGCDetails && _result == NULL) {
+- gclog_or_tty->print_cr("\nAfter Metaspace GC failed to allocate size "
+- SIZE_FORMAT, _size);
++ if (_result != NULL) {
++ return;
+ }
+ }
+
+- if (_result == NULL && GC_locker::is_active_and_needs_gc()) {
++ if (initiate_concurrent_GC()) {
++ // For CMS and G1 expand since the collection is going to be concurrent.
++ _result = _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype);
++ if (_result != NULL) {
++ return;
++ }
++
++ log_metaspace_alloc_failure_for_concurrent_GC();
++ }
++
++ // Don't clear the soft refs yet.
++ heap->collect_as_vm_thread(GCCause::_metadata_GC_threshold);
++ // After a GC try to allocate without expanding. Could fail
++ // and expansion will be tried below.
++ _result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype);
++ if (_result != NULL) {
++ return;
++ }
++
++ // If still failing, allow the Metaspace to expand.
++ // See delta_capacity_until_GC() for explanation of the
++ // amount of the expansion.
++ // This should work unless there really is no more space
++ // or a MaxMetaspaceSize has been specified on the command line.
++ _result = _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype);
++ if (_result != NULL) {
++ return;
++ }
++
++ // If expansion failed, do a last-ditch collection and try allocating
++ // again. A last-ditch collection will clear softrefs. This
++ // behavior is similar to the last-ditch collection done for perm
++ // gen when it was full and a collection for failed allocation
++ // did not free perm gen space.
++ heap->collect_as_vm_thread(GCCause::_last_ditch_collection);
++ _result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype);
++ if (_result != NULL) {
++ return;
++ }
++
++ if (Verbose && PrintGCDetails) {
++ gclog_or_tty->print_cr("\nAfter Metaspace GC failed to allocate size "
++ SIZE_FORMAT, _size);
++ }
++
++ if (GC_locker::is_active_and_needs_gc()) {
+ set_gc_locked();
+ }
+ }
+--- ./hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -217,6 +217,8 @@
+ virtual VMOp_Type type() const { return VMOp_CollectForMetadataAllocation; }
+ virtual void doit();
+ MetaWord* result() const { return _result; }
++
++ bool initiate_concurrent_GC();
+ };
+
+ class SvcGCMarker : public StackObj {
+--- ./hotspot/src/share/vm/gc_interface/collectedHeap.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_interface/collectedHeap.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -558,13 +558,13 @@
+
+ void CollectedHeap::pre_full_gc_dump(GCTimer* timer) {
+ if (HeapDumpBeforeFullGC) {
+- GCTraceTime tt("Heap Dump (before full gc): ", PrintGCDetails, false, timer);
++ GCTraceTime tt("Heap Dump (before full gc): ", PrintGCDetails, false, timer, GCId::create());
+ // We are doing a "major" collection and a heap dump before
+ // major collection has been requested.
+ HeapDumper::dump_heap();
+ }
+ if (PrintClassHistogramBeforeFullGC) {
+- GCTraceTime tt("Class Histogram (before full gc): ", PrintGCDetails, true, timer);
++ GCTraceTime tt("Class Histogram (before full gc): ", PrintGCDetails, true, timer, GCId::create());
+ VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */);
+ inspector.doit();
+ }
+@@ -572,11 +572,11 @@
+
+ void CollectedHeap::post_full_gc_dump(GCTimer* timer) {
+ if (HeapDumpAfterFullGC) {
+- GCTraceTime tt("Heap Dump (after full gc): ", PrintGCDetails, false, timer);
++ GCTraceTime tt("Heap Dump (after full gc): ", PrintGCDetails, false, timer, GCId::create());
+ HeapDumper::dump_heap();
+ }
+ if (PrintClassHistogramAfterFullGC) {
+- GCTraceTime tt("Class Histogram (after full gc): ", PrintGCDetails, true, timer);
++ GCTraceTime tt("Class Histogram (after full gc): ", PrintGCDetails, true, timer, GCId::create());
+ VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */);
+ inspector.doit();
+ }
+--- ./hotspot/src/share/vm/gc_interface/collectedHeap.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_interface/collectedHeap.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -351,6 +351,12 @@
+ fill_with_object(start, pointer_delta(end, start), zap);
+ }
+
++ // Return the address "addr" aligned by "alignment_in_bytes" if such
++ // an address is below "end". Return NULL otherwise.
++ inline static HeapWord* align_allocation_or_fail(HeapWord* addr,
++ HeapWord* end,
++ unsigned short alignment_in_bytes);
++
+ // Some heaps may offer a contiguous region for shared non-blocking
+ // allocation, via inlined code (by exporting the address of the top and
+ // end fields defining the extent of the contiguous allocation region.)
+@@ -389,15 +395,6 @@
+ // allocation from them and necessitating allocation of new TLABs.
+ virtual void ensure_parsability(bool retire_tlabs);
+
+- // Return an estimate of the maximum allocation that could be performed
+- // without triggering any collection or expansion activity. In a
+- // generational collector, for example, this is probably the largest
+- // allocation that could be supported (without expansion) in the youngest
+- // generation. It is "unsafe" because no locks are taken; the result
+- // should be treated as an approximation, not a guarantee, for use in
+- // heuristic resizing decisions.
+- virtual size_t unsafe_max_alloc() = 0;
+-
+ // Section on thread-local allocation buffers (TLABs)
+ // If the heap supports thread-local allocation buffers, it should override
+ // the following methods:
+@@ -640,6 +637,18 @@
+ // actual number may be germane.
+ static bool use_parallel_gc_threads() { return ParallelGCThreads > 0; }
+
++ // Copy the current allocation context statistics for the specified contexts.
++ // For each context in contexts, set the corresponding entries in the totals
++ // and accuracy arrays to the current values held by the statistics. Each
++ // array should be of length len.
++ // Returns true if there are more stats available.
++ virtual bool copy_allocation_context_stats(const jint* contexts,
++ jlong* totals,
++ jbyte* accuracy,
++ jint len) {
++ return false;
++ }
++
+ /////////////// Unit tests ///////////////
+
+ NOT_PRODUCT(static void test_is_in();)
+--- ./hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -241,6 +241,44 @@
+ oop_iterate(&no_header_cl);
+ }
+
++
++inline HeapWord* CollectedHeap::align_allocation_or_fail(HeapWord* addr,
++ HeapWord* end,
++ unsigned short alignment_in_bytes) {
++ if (alignment_in_bytes <= ObjectAlignmentInBytes) {
++ return addr;
++ }
++
++ assert(is_ptr_aligned(addr, HeapWordSize),
++ err_msg("Address " PTR_FORMAT " is not properly aligned.", p2i(addr)));
++ assert(is_size_aligned(alignment_in_bytes, HeapWordSize),
++ err_msg("Alignment size %u is incorrect.", alignment_in_bytes));
++
++ HeapWord* new_addr = (HeapWord*) align_pointer_up(addr, alignment_in_bytes);
++ size_t padding = pointer_delta(new_addr, addr);
++
++ if (padding == 0) {
++ return addr;
++ }
++
++ if (padding < CollectedHeap::min_fill_size()) {
++ padding += alignment_in_bytes / HeapWordSize;
++ assert(padding >= CollectedHeap::min_fill_size(),
++ err_msg("alignment_in_bytes %u is expect to be larger "
++ "than the minimum object size", alignment_in_bytes));
++ new_addr = addr + padding;
++ }
++
++ assert(new_addr > addr, err_msg("Unexpected arithmetic overflow "
++ PTR_FORMAT " not greater than " PTR_FORMAT, p2i(new_addr), p2i(addr)));
++ if(new_addr < end) {
++ CollectedHeap::fill_with_object(addr, padding);
++ return new_addr;
++ } else {
++ return NULL;
++ }
++}
++
+ #ifndef PRODUCT
+
+ inline bool
+--- ./hotspot/src/share/vm/gc_interface/gcCause.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_interface/gcCause.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -51,6 +51,13 @@
+ case _heap_dump:
+ return "Heap Dump Initiated GC";
+
++ case _wb_young_gc:
++ return "WhiteBox Initiated Young GC";
++
++ case _update_allocation_context_stats_inc:
++ case _update_allocation_context_stats_full:
++ return "Update Allocation Context Stats";
++
+ case _no_gc:
+ return "No GC";
+
+--- ./hotspot/src/share/vm/gc_interface/gcCause.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/gc_interface/gcCause.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -46,6 +46,9 @@
+ _gc_locker,
+ _heap_inspection,
+ _heap_dump,
++ _wb_young_gc,
++ _update_allocation_context_stats_inc,
++ _update_allocation_context_stats_full,
+
+ /* implementation independent, but reserved for GC use */
+ _no_gc,
+--- ./hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -41,43 +41,10 @@
+ #include "runtime/frame.inline.hpp"
+ #include "runtime/handles.inline.hpp"
+ #include "runtime/interfaceSupport.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/sharedRuntime.hpp"
+ #include "runtime/threadCritical.hpp"
+ #include "utilities/exceptions.hpp"
+-#ifdef TARGET_OS_ARCH_linux_x86
+-# include "orderAccess_linux_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_sparc
+-# include "orderAccess_linux_sparc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_zero
+-# include "orderAccess_linux_zero.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_solaris_x86
+-# include "orderAccess_solaris_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_solaris_sparc
+-# include "orderAccess_solaris_sparc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_windows_x86
+-# include "orderAccess_windows_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_arm
+-# include "orderAccess_linux_arm.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_ppc
+-# include "orderAccess_linux_ppc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_aix_ppc
+-# include "orderAccess_aix_ppc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_bsd_x86
+-# include "orderAccess_bsd_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_bsd_zero
+-# include "orderAccess_bsd_zero.inline.hpp"
+-#endif
+-
+
+ // no precompiled headers
+ #ifdef CC_INTERP
+@@ -2846,11 +2813,11 @@
+ if (TraceExceptions) {
+ ttyLocker ttyl;
+ ResourceMark rm;
+- tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), (void*)except_oop());
++ tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), p2i(except_oop()));
+ tty->print_cr(" thrown in interpreter method <%s>", METHOD->print_value_string());
+ tty->print_cr(" at bci %d, continuing at %d for thread " INTPTR_FORMAT,
+- istate->bcp() - (intptr_t)METHOD->code_base(),
+- continuation_bci, THREAD);
++ (int)(istate->bcp() - METHOD->code_base()),
++ (int)continuation_bci, p2i(THREAD));
+ }
+ // for AbortVMOnException flag
+ NOT_PRODUCT(Exceptions::debug_check_abort(except_oop));
+@@ -2862,11 +2829,11 @@
+ if (TraceExceptions) {
+ ttyLocker ttyl;
+ ResourceMark rm;
+- tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), (void*)except_oop());
++ tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), p2i(except_oop()));
+ tty->print_cr(" thrown in interpreter method <%s>", METHOD->print_value_string());
+ tty->print_cr(" at bci %d, unwinding for thread " INTPTR_FORMAT,
+- istate->bcp() - (intptr_t)METHOD->code_base(),
+- THREAD);
++ (int)(istate->bcp() - METHOD->code_base()),
++ p2i(THREAD));
+ }
+ // for AbortVMOnException flag
+ NOT_PRODUCT(Exceptions::debug_check_abort(except_oop));
+@@ -3465,7 +3432,7 @@
+ tty->print_cr("osr._osr_buf: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_buf);
+ tty->print_cr("osr._osr_entry: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_entry);
+ tty->print_cr("prev_link: " INTPTR_FORMAT, (uintptr_t) this->_prev_link);
+- tty->print_cr("native_mirror: " INTPTR_FORMAT, (void*) this->_oop_temp);
++ tty->print_cr("native_mirror: " INTPTR_FORMAT, (uintptr_t) this->_oop_temp);
+ tty->print_cr("stack_base: " INTPTR_FORMAT, (uintptr_t) this->_stack_base);
+ tty->print_cr("stack_limit: " INTPTR_FORMAT, (uintptr_t) this->_stack_limit);
+ tty->print_cr("monitor_base: " INTPTR_FORMAT, (uintptr_t) this->_monitor_base);
+--- ./hotspot/src/share/vm/interpreter/bytecodeInterpreterProfiling.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/interpreter/bytecodeInterpreterProfiling.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,6 +1,6 @@
+ /*
+- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+- * Copyright 2012, 2013 SAP AG. All rights reserved.
++ * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -86,11 +86,11 @@
+ " \t-> " PTR_FORMAT "(%d)", \
+ (int) THREAD->osthread()->thread_id(), \
+ BCI(), \
+- MDX(), \
++ p2i(MDX()), \
+ (MDX() == NULL \
+ ? 0 \
+ : istate->method()->method_data()->dp_to_di((address)MDX())), \
+- mdx, \
++ p2i(mdx), \
+ istate->method()->method_data()->dp_to_di((address)mdx) \
+ ); \
+ }; \
+@@ -107,7 +107,7 @@
+ MethodData *md = istate->method()->method_data(); \
+ tty->cr(); \
+ tty->print("method data at mdx " PTR_FORMAT "(0) for", \
+- md->data_layout_at(md->bci_to_di(0))); \
++ p2i(md->data_layout_at(md->bci_to_di(0)))); \
+ istate->method()->print_short_name(tty); \
+ tty->cr(); \
+ if (md != NULL) { \
+@@ -115,7 +115,7 @@
+ address mdx = (address) MDX(); \
+ if (mdx != NULL) { \
+ tty->print_cr("current mdx " PTR_FORMAT "(%d)", \
+- mdx, \
++ p2i(mdx), \
+ istate->method()->method_data()->dp_to_di(mdx)); \
+ } \
+ } else { \
+--- ./hotspot/src/share/vm/interpreter/bytecodes.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/interpreter/bytecodes.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -420,8 +420,10 @@
+ static bool is_astore (Code code) { return (code == _astore || code == _astore_0 || code == _astore_1
+ || code == _astore_2 || code == _astore_3); }
+
++ static bool is_const (Code code) { return (_aconst_null <= code && code <= _ldc2_w); }
+ static bool is_zero_const (Code code) { return (code == _aconst_null || code == _iconst_0
+ || code == _fconst_0 || code == _dconst_0); }
++ static bool is_return (Code code) { return (_ireturn <= code && code <= _return); }
+ static bool is_invoke (Code code) { return (_invokevirtual <= code && code <= _invokedynamic); }
+ static bool has_receiver (Code code) { assert(is_invoke(code), ""); return code == _invokevirtual ||
+ code == _invokespecial ||
+--- ./hotspot/src/share/vm/interpreter/interpreter.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/interpreter/interpreter.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -53,7 +53,9 @@
+ public:
+ // Initialization/finalization
+ void initialize(int size,
+- CodeStrings& strings) { _size = size; DEBUG_ONLY(_strings.assign(strings);) }
++ CodeStrings& strings) { _size = size;
++ DEBUG_ONLY(::new(&_strings) CodeStrings();)
++ DEBUG_ONLY(_strings.assign(strings);) }
+ void finalize() { ShouldNotCallThis(); }
+
+ // General info/converters
+--- ./hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -398,6 +398,18 @@
+ int handler_bci;
+ int current_bci = bci(thread);
+
++ if (thread->frames_to_pop_failed_realloc() > 0) {
++ // Allocation of scalar replaced object used in this frame
++ // failed. Unconditionally pop the frame.
++ thread->dec_frames_to_pop_failed_realloc();
++ thread->set_vm_result(h_exception());
++ // If the method is synchronized we already unlocked the monitor
++ // during deoptimization so the interpreter needs to skip it when
++ // the frame is popped.
++ thread->set_do_not_unlock_if_synchronized(true);
++ return Interpreter::remove_activation_entry();
++ }
++
+ // Need to do this check first since when _do_not_unlock_if_synchronized
+ // is set, we don't want to trigger any classloading which may make calls
+ // into java, or surprisingly find a matching exception handler for bci 0
+@@ -1269,8 +1281,10 @@
+ // This is a support of the JVMTI PopFrame interface.
+ // Make sure it is an invokestatic of a polymorphic intrinsic that has a member_name argument
+ // and return it as a vm_result so that it can be reloaded in the list of invokestatic parameters.
+-// The dmh argument is a reference to a DirectMethoHandle that has a member name field.
+-IRT_ENTRY(void, InterpreterRuntime::member_name_arg_or_null(JavaThread* thread, address dmh,
++// The member_name argument is a saved reference (in local#0) to the member_name.
++// For backward compatibility with some JDK versions (7, 8) it can also be a direct method handle.
++// FIXME: remove DMH case after j.l.i.InvokerBytecodeGenerator code shape is updated.
++IRT_ENTRY(void, InterpreterRuntime::member_name_arg_or_null(JavaThread* thread, address member_name,
+ Method* method, address bcp))
+ Bytecodes::Code code = Bytecodes::code_at(method, bcp);
+ if (code != Bytecodes::_invokestatic) {
+@@ -1282,8 +1296,12 @@
+ Symbol* mname = cpool->name_ref_at(cp_index);
+
+ if (MethodHandles::has_member_arg(cname, mname)) {
+- oop member_name = java_lang_invoke_DirectMethodHandle::member((oop)dmh);
+- thread->set_vm_result(member_name);
++ oop member_name_oop = (oop) member_name;
++ if (java_lang_invoke_DirectMethodHandle::is_instance(member_name_oop)) {
++ // FIXME: remove after j.l.i.InvokerBytecodeGenerator code shape is updated.
++ member_name_oop = java_lang_invoke_DirectMethodHandle::member(member_name_oop);
++ }
++ thread->set_vm_result(member_name_oop);
+ }
+ IRT_END
+ #endif // INCLUDE_JVMTI
+--- ./hotspot/src/share/vm/interpreter/oopMapCache.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/interpreter/oopMapCache.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -180,7 +180,7 @@
+ }
+ }
+
+-bool InterpreterOopMap::is_empty() {
++bool InterpreterOopMap::is_empty() const {
+ bool result = _method == NULL;
+ assert(_method != NULL || (_bci == 0 &&
+ (_mask_size == 0 || _mask_size == USHRT_MAX) &&
+@@ -196,7 +196,7 @@
+ for (int i = 0; i < N; i++) _bit_mask[i] = 0;
+ }
+
+-void InterpreterOopMap::iterate_oop(OffsetClosure* oop_closure) {
++void InterpreterOopMap::iterate_oop(OffsetClosure* oop_closure) const {
+ int n = number_of_entries();
+ int word_index = 0;
+ uintptr_t value = 0;
+@@ -238,7 +238,7 @@
+ #endif
+
+
+-void InterpreterOopMap::print() {
++void InterpreterOopMap::print() const {
+ int n = number_of_entries();
+ tty->print("oop map for ");
+ method()->print_value();
+@@ -469,7 +469,7 @@
+ }
+ }
+
+-inline unsigned int OopMapCache::hash_value_for(methodHandle method, int bci) {
++inline unsigned int OopMapCache::hash_value_for(methodHandle method, int bci) const {
+ // We use method->code_size() rather than method->identity_hash() below since
+ // the mark may not be present if a pointer to the method is already reversed.
+ return ((unsigned int) bci)
+@@ -522,7 +522,7 @@
+
+ void OopMapCache::lookup(methodHandle method,
+ int bci,
+- InterpreterOopMap* entry_for) {
++ InterpreterOopMap* entry_for) const {
+ MutexLocker x(&_mut);
+
+ OopMapCacheEntry* entry = NULL;
+--- ./hotspot/src/share/vm/interpreter/oopMapCache.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/interpreter/oopMapCache.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -101,32 +101,31 @@
+
+ // access methods
+ Method* method() const { return _method; }
+- void set_method(Method* v) { _method = v; }
++ void set_method(Method* v) { _method = v; }
+ int bci() const { return _bci; }
+ void set_bci(int v) { _bci = v; }
+ int mask_size() const { return _mask_size; }
+ void set_mask_size(int v) { _mask_size = v; }
+- int number_of_entries() const { return mask_size() / bits_per_entry; }
+ // Test bit mask size and return either the in-line bit mask or allocated
+ // bit mask.
+- uintptr_t* bit_mask() { return (uintptr_t*)(mask_size() <= small_mask_limit ? (intptr_t)_bit_mask : _bit_mask[0]); }
++ uintptr_t* bit_mask() const { return (uintptr_t*)(mask_size() <= small_mask_limit ? (intptr_t)_bit_mask : _bit_mask[0]); }
+
+ // return the word size of_bit_mask. mask_size() <= 4 * MAX_USHORT
+- size_t mask_word_size() {
++ size_t mask_word_size() const {
+ return (mask_size() + BitsPerWord - 1) / BitsPerWord;
+ }
+
+- uintptr_t entry_at(int offset) { int i = offset * bits_per_entry; return bit_mask()[i / BitsPerWord] >> (i % BitsPerWord); }
++ uintptr_t entry_at(int offset) const { int i = offset * bits_per_entry; return bit_mask()[i / BitsPerWord] >> (i % BitsPerWord); }
+
+- void set_expression_stack_size(int sz) { _expression_stack_size = sz; }
++ void set_expression_stack_size(int sz) { _expression_stack_size = sz; }
+
+ #ifdef ENABLE_ZAP_DEAD_LOCALS
+- bool is_dead(int offset) { return (entry_at(offset) & (1 << dead_bit_number)) != 0; }
++ bool is_dead(int offset) const { return (entry_at(offset) & (1 << dead_bit_number)) != 0; }
+ #endif
+
+ // Lookup
+- bool match(methodHandle method, int bci) { return _method == method() && _bci == bci; }
+- bool is_empty();
++ bool match(methodHandle method, int bci) const { return _method == method() && _bci == bci; }
++ bool is_empty() const;
+
+ // Initialization
+ void initialize();
+@@ -141,12 +140,13 @@
+ // in-line), allocate the space from a Resource area.
+ void resource_copy(OopMapCacheEntry* from);
+
+- void iterate_oop(OffsetClosure* oop_closure);
+- void print();
++ void iterate_oop(OffsetClosure* oop_closure) const;
++ void print() const;
+
+- bool is_oop (int offset) { return (entry_at(offset) & (1 << oop_bit_number )) != 0; }
++ int number_of_entries() const { return mask_size() / bits_per_entry; }
++ bool is_oop (int offset) const { return (entry_at(offset) & (1 << oop_bit_number )) != 0; }
+
+- int expression_stack_size() { return _expression_stack_size; }
++ int expression_stack_size() const { return _expression_stack_size; }
+
+ #ifdef ENABLE_ZAP_DEAD_LOCALS
+ void iterate_all(OffsetClosure* oop_closure, OffsetClosure* value_closure, OffsetClosure* dead_closure);
+@@ -161,10 +161,10 @@
+
+ OopMapCacheEntry* _array;
+
+- unsigned int hash_value_for(methodHandle method, int bci);
++ unsigned int hash_value_for(methodHandle method, int bci) const;
+ OopMapCacheEntry* entry_at(int i) const;
+
+- Mutex _mut;
++ mutable Mutex _mut;
+
+ void flush();
+
+@@ -177,7 +177,7 @@
+
+ // Returns the oopMap for (method, bci) in parameter "entry".
+ // Returns false if an oop map was not found.
+- void lookup(methodHandle method, int bci, InterpreterOopMap* entry);
++ void lookup(methodHandle method, int bci, InterpreterOopMap* entry) const;
+
+ // Compute an oop map without updating the cache or grabbing any locks (for debugging)
+ static void compute_one_oop_map(methodHandle method, int bci, InterpreterOopMap* entry);
+--- ./hotspot/src/share/vm/memory/allocation.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/allocation.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -438,24 +438,22 @@
+ }
+
+ //------------------------------Arena------------------------------------------
+-NOT_PRODUCT(volatile jint Arena::_instance_count = 0;)
+-
+-Arena::Arena(size_t init_size) {
++Arena::Arena(MEMFLAGS flag, size_t init_size) : _flags(flag), _size_in_bytes(0) {
+ size_t round_size = (sizeof (char *)) - 1;
+ init_size = (init_size+round_size) & ~round_size;
+ _first = _chunk = new (AllocFailStrategy::EXIT_OOM, init_size) Chunk(init_size);
+ _hwm = _chunk->bottom(); // Save the cached hwm, max
+ _max = _chunk->top();
++ MemTracker::record_new_arena(flag);
+ set_size_in_bytes(init_size);
+- NOT_PRODUCT(Atomic::inc(&_instance_count);)
+ }
+
+-Arena::Arena() {
++Arena::Arena(MEMFLAGS flag) : _flags(flag), _size_in_bytes(0) {
+ _first = _chunk = new (AllocFailStrategy::EXIT_OOM, Chunk::init_size) Chunk(Chunk::init_size);
+ _hwm = _chunk->bottom(); // Save the cached hwm, max
+ _max = _chunk->top();
++ MemTracker::record_new_arena(flag);
+ set_size_in_bytes(Chunk::init_size);
+- NOT_PRODUCT(Atomic::inc(&_instance_count);)
+ }
+
+ Arena *Arena::move_contents(Arena *copy) {
+@@ -477,7 +475,7 @@
+
+ Arena::~Arena() {
+ destruct_contents();
+- NOT_PRODUCT(Atomic::dec(&_instance_count);)
++ MemTracker::record_arena_free(_flags);
+ }
+
+ void* Arena::operator new(size_t size) throw() {
+@@ -493,21 +491,21 @@
+ // dynamic memory type binding
+ void* Arena::operator new(size_t size, MEMFLAGS flags) throw() {
+ #ifdef ASSERT
+- void* p = (void*)AllocateHeap(size, flags|otArena, CALLER_PC);
++ void* p = (void*)AllocateHeap(size, flags, CALLER_PC);
+ if (PrintMallocFree) trace_heap_malloc(size, "Arena-new", p);
+ return p;
+ #else
+- return (void *) AllocateHeap(size, flags|otArena, CALLER_PC);
++ return (void *) AllocateHeap(size, flags, CALLER_PC);
+ #endif
+ }
+
+ void* Arena::operator new(size_t size, const std::nothrow_t& nothrow_constant, MEMFLAGS flags) throw() {
+ #ifdef ASSERT
+- void* p = os::malloc(size, flags|otArena, CALLER_PC);
++ void* p = os::malloc(size, flags, CALLER_PC);
+ if (PrintMallocFree) trace_heap_malloc(size, "Arena-new", p);
+ return p;
+ #else
+- return os::malloc(size, flags|otArena, CALLER_PC);
++ return os::malloc(size, flags, CALLER_PC);
+ #endif
+ }
+
+@@ -532,8 +530,9 @@
+ // change the size
+ void Arena::set_size_in_bytes(size_t size) {
+ if (_size_in_bytes != size) {
++ long delta = (long)(size - size_in_bytes());
+ _size_in_bytes = size;
+- MemTracker::record_arena_size((address)this, size);
++ MemTracker::record_arena_size_change(delta, _flags);
+ }
+ }
+
+--- ./hotspot/src/share/vm/memory/allocation.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/allocation.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -133,51 +133,34 @@
+
+
+ /*
+- * MemoryType bitmap layout:
+- * | 16 15 14 13 12 11 10 09 | 08 07 06 05 | 04 03 02 01 |
+- * | memory type | object | reserved |
+- * | | type | |
++ * Memory types
+ */
+ enum MemoryType {
+ // Memory type by sub systems. It occupies lower byte.
+- mtNone = 0x0000, // undefined
+- mtClass = 0x0100, // memory class for Java classes
+- mtThread = 0x0200, // memory for thread objects
+- mtThreadStack = 0x0300,
+- mtCode = 0x0400, // memory for generated code
+- mtGC = 0x0500, // memory for GC
+- mtCompiler = 0x0600, // memory for compiler
+- mtInternal = 0x0700, // memory used by VM, but does not belong to
++ mtJavaHeap = 0x00, // Java heap
++ mtClass = 0x01, // memory class for Java classes
++ mtThread = 0x02, // memory for thread objects
++ mtThreadStack = 0x03,
++ mtCode = 0x04, // memory for generated code
++ mtGC = 0x05, // memory for GC
++ mtCompiler = 0x06, // memory for compiler
++ mtInternal = 0x07, // memory used by VM, but does not belong to
+ // any of above categories, and not used for
+ // native memory tracking
+- mtOther = 0x0800, // memory not used by VM
+- mtSymbol = 0x0900, // symbol
+- mtNMT = 0x0A00, // memory used by native memory tracking
+- mtChunk = 0x0B00, // chunk that holds content of arenas
+- mtJavaHeap = 0x0C00, // Java heap
+- mtClassShared = 0x0D00, // class data sharing
+- mtTest = 0x0E00, // Test type for verifying NMT
+- mtTracing = 0x0F00, // memory used for Tracing
+- mt_number_of_types = 0x000F, // number of memory types (mtDontTrack
++ mtOther = 0x08, // memory not used by VM
++ mtSymbol = 0x09, // symbol
++ mtNMT = 0x0A, // memory used by native memory tracking
++ mtClassShared = 0x0B, // class data sharing
++ mtChunk = 0x0C, // chunk that holds content of arenas
++ mtTest = 0x0D, // Test type for verifying NMT
++ mtTracing = 0x0E, // memory used for Tracing
++ mtNone = 0x0F, // undefined
++ mt_number_of_types = 0x10 // number of memory types (mtDontTrack
+ // is not included as validate type)
+- mtDontTrack = 0x0F00, // memory we do not or cannot track
+- mt_masks = 0x7F00,
+-
+- // object type mask
+- otArena = 0x0010, // an arena object
+- otNMTRecorder = 0x0020, // memory recorder object
+- ot_masks = 0x00F0
+ };
+
+-#define IS_MEMORY_TYPE(flags, type) ((flags & mt_masks) == type)
+-#define HAS_VALID_MEMORY_TYPE(flags)((flags & mt_masks) != mtNone)
+-#define FLAGS_TO_MEMORY_TYPE(flags) (flags & mt_masks)
++typedef MemoryType MEMFLAGS;
+
+-#define IS_ARENA_OBJ(flags) ((flags & ot_masks) == otArena)
+-#define IS_NMT_RECORDER(flags) ((flags & ot_masks) == otNMTRecorder)
+-#define NMT_CAN_TRACK(flags) (!IS_NMT_RECORDER(flags) && !(IS_MEMORY_TYPE(flags, mtDontTrack)))
+-
+-typedef unsigned short MEMFLAGS;
+
+ #if INCLUDE_NMT
+
+@@ -189,27 +172,23 @@
+
+ #endif // INCLUDE_NMT
+
+-// debug build does not inline
+-#if defined(_NMT_NOINLINE_)
+- #define CURRENT_PC (NMT_track_callsite ? os::get_caller_pc(1) : 0)
+- #define CALLER_PC (NMT_track_callsite ? os::get_caller_pc(2) : 0)
+- #define CALLER_CALLER_PC (NMT_track_callsite ? os::get_caller_pc(3) : 0)
+-#else
+- #define CURRENT_PC (NMT_track_callsite? os::get_caller_pc(0) : 0)
+- #define CALLER_PC (NMT_track_callsite ? os::get_caller_pc(1) : 0)
+- #define CALLER_CALLER_PC (NMT_track_callsite ? os::get_caller_pc(2) : 0)
+-#endif
+-
++class NativeCallStack;
+
+
+ template <MEMFLAGS F> class CHeapObj ALLOCATION_SUPER_CLASS_SPEC {
+ public:
+- _NOINLINE_ void* operator new(size_t size, address caller_pc = 0) throw();
++ _NOINLINE_ void* operator new(size_t size, const NativeCallStack& stack) throw();
++ _NOINLINE_ void* operator new(size_t size) throw();
+ _NOINLINE_ void* operator new (size_t size, const std::nothrow_t& nothrow_constant,
+- address caller_pc = 0) throw();
+- _NOINLINE_ void* operator new [](size_t size, address caller_pc = 0) throw();
++ const NativeCallStack& stack) throw();
++ _NOINLINE_ void* operator new (size_t size, const std::nothrow_t& nothrow_constant)
++ throw();
++ _NOINLINE_ void* operator new [](size_t size, const NativeCallStack& stack) throw();
++ _NOINLINE_ void* operator new [](size_t size) throw();
+ _NOINLINE_ void* operator new [](size_t size, const std::nothrow_t& nothrow_constant,
+- address caller_pc = 0) throw();
++ const NativeCallStack& stack) throw();
++ _NOINLINE_ void* operator new [](size_t size, const std::nothrow_t& nothrow_constant)
++ throw();
+ void operator delete(void* p);
+ void operator delete [] (void* p);
+ };
+@@ -286,7 +265,8 @@
+ f(ConstantPool) \
+ f(ConstantPoolCache) \
+ f(Annotation) \
+- f(MethodCounters)
++ f(MethodCounters) \
++ f(Deallocated)
+
+ #define METASPACE_OBJ_TYPE_DECLARE(name) name ## Type,
+ #define METASPACE_OBJ_TYPE_NAME_CASE(name) case name ## Type: return #name;
+@@ -384,13 +364,15 @@
+
+ //------------------------------Arena------------------------------------------
+ // Fast allocation of memory
+-class Arena : public CHeapObj<mtNone|otArena> {
++class Arena : public CHeapObj<mtNone> {
+ protected:
+ friend class ResourceMark;
+ friend class HandleMark;
+ friend class NoHandleMark;
+ friend class VMStructs;
+
++ MEMFLAGS _flags; // Memory tracking flags
++
+ Chunk *_first; // First chunk
+ Chunk *_chunk; // current chunk
+ char *_hwm, *_max; // High water mark and max in current chunk
+@@ -418,8 +400,8 @@
+ }
+
+ public:
+- Arena();
+- Arena(size_t init_size);
++ Arena(MEMFLAGS memflag);
++ Arena(MEMFLAGS memflag, size_t init_size);
+ ~Arena();
+ void destruct_contents();
+ char* hwm() const { return _hwm; }
+@@ -518,8 +500,6 @@
+ static void free_malloced_objects(Chunk* chunk, char* hwm, char* max, char* hwm2) PRODUCT_RETURN;
+ static void free_all(char** start, char** end) PRODUCT_RETURN;
+
+- // how many arena instances
+- NOT_PRODUCT(static volatile jint _instance_count;)
+ private:
+ // Reset this Arena to empty, access will trigger grow if necessary
+ void reset(void) {
+@@ -681,7 +661,7 @@
+ NEW_C_HEAP_ARRAY3(type, (size), memflags, pc, AllocFailStrategy::RETURN_NULL)
+
+ #define NEW_C_HEAP_ARRAY_RETURN_NULL(type, size, memflags)\
+- NEW_C_HEAP_ARRAY3(type, (size), memflags, (address)0, AllocFailStrategy::RETURN_NULL)
++ NEW_C_HEAP_ARRAY3(type, (size), memflags, CURRENT_PC, AllocFailStrategy::RETURN_NULL)
+
+ #define REALLOC_C_HEAP_ARRAY(type, old, size, memflags)\
+ (type*) (ReallocateHeap((char*)(old), (size) * sizeof(type), memflags))
+--- ./hotspot/src/share/vm/memory/allocation.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/allocation.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -27,6 +27,7 @@
+
+ #include "runtime/atomic.inline.hpp"
+ #include "runtime/os.hpp"
++#include "services/memTracker.hpp"
+
+ // Explicit C-heap memory management
+
+@@ -49,12 +50,10 @@
+ #endif
+
+ // allocate using malloc; will fail if no memory available
+-inline char* AllocateHeap(size_t size, MEMFLAGS flags, address pc = 0,
++inline char* AllocateHeap(size_t size, MEMFLAGS flags,
++ const NativeCallStack& stack,
+ AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
+- if (pc == 0) {
+- pc = CURRENT_PC;
+- }
+- char* p = (char*) os::malloc(size, flags, pc);
++ char* p = (char*) os::malloc(size, flags, stack);
+ #ifdef ASSERT
+ if (PrintMallocFree) trace_heap_malloc(size, "AllocateHeap", p);
+ #endif
+@@ -63,10 +62,14 @@
+ }
+ return p;
+ }
++inline char* AllocateHeap(size_t size, MEMFLAGS flags,
++ AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
++ return AllocateHeap(size, flags, CURRENT_PC, alloc_failmode);
++}
+
+-inline char* ReallocateHeap(char *old, size_t size, MEMFLAGS flags,
++inline char* ReallocateHeap(char *old, size_t size, MEMFLAGS flag,
+ AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
+- char* p = (char*) os::realloc(old, size, flags, CURRENT_PC);
++ char* p = (char*) os::realloc(old, size, flag, CURRENT_PC);
+ #ifdef ASSERT
+ if (PrintMallocFree) trace_heap_malloc(size, "ReallocateHeap", p);
+ #endif
+@@ -85,8 +88,22 @@
+
+
+ template <MEMFLAGS F> void* CHeapObj<F>::operator new(size_t size,
+- address caller_pc) throw() {
+- void* p = (void*)AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
++ const NativeCallStack& stack) throw() {
++ void* p = (void*)AllocateHeap(size, F, stack);
++#ifdef ASSERT
++ if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
++#endif
++ return p;
++}
++
++template <MEMFLAGS F> void* CHeapObj<F>::operator new(size_t size) throw() {
++ return CHeapObj<F>::operator new(size, CALLER_PC);
++}
++
++template <MEMFLAGS F> void* CHeapObj<F>::operator new (size_t size,
++ const std::nothrow_t& nothrow_constant, const NativeCallStack& stack) throw() {
++ void* p = (void*)AllocateHeap(size, F, stack,
++ AllocFailStrategy::RETURN_NULL);
+ #ifdef ASSERT
+ if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
+ #endif
+@@ -94,23 +111,28 @@
+ }
+
+ template <MEMFLAGS F> void* CHeapObj<F>::operator new (size_t size,
+- const std::nothrow_t& nothrow_constant, address caller_pc) throw() {
+- void* p = (void*)AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC),
+- AllocFailStrategy::RETURN_NULL);
+-#ifdef ASSERT
+- if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
+-#endif
+- return p;
++ const std::nothrow_t& nothrow_constant) throw() {
++ return CHeapObj<F>::operator new(size, nothrow_constant, CALLER_PC);
+ }
+
+ template <MEMFLAGS F> void* CHeapObj<F>::operator new [](size_t size,
+- address caller_pc) throw() {
+- return CHeapObj<F>::operator new(size, caller_pc);
++ const NativeCallStack& stack) throw() {
++ return CHeapObj<F>::operator new(size, stack);
++}
++
++template <MEMFLAGS F> void* CHeapObj<F>::operator new [](size_t size)
++ throw() {
++ return CHeapObj<F>::operator new(size, CALLER_PC);
+ }
+
+ template <MEMFLAGS F> void* CHeapObj<F>::operator new [](size_t size,
+- const std::nothrow_t& nothrow_constant, address caller_pc) throw() {
+- return CHeapObj<F>::operator new(size, nothrow_constant, caller_pc);
++ const std::nothrow_t& nothrow_constant, const NativeCallStack& stack) throw() {
++ return CHeapObj<F>::operator new(size, nothrow_constant, stack);
++}
++
++template <MEMFLAGS F> void* CHeapObj<F>::operator new [](size_t size,
++ const std::nothrow_t& nothrow_constant) throw() {
++ return CHeapObj<F>::operator new(size, nothrow_constant, CALLER_PC);
+ }
+
+ template <MEMFLAGS F> void CHeapObj<F>::operator delete(void* p){
+--- ./hotspot/src/share/vm/memory/cardTableModRefBS.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/cardTableModRefBS.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -44,13 +44,6 @@
+ // enumerate ref fields that have been modified (since the last
+ // enumeration.)
+
+-size_t CardTableModRefBS::cards_required(size_t covered_words)
+-{
+- // Add one for a guard card, used to detect errors.
+- const size_t words = align_size_up(covered_words, card_size_in_words);
+- return words / card_size_in_words + 1;
+-}
+-
+ size_t CardTableModRefBS::compute_byte_map_size()
+ {
+ assert(_guard_index == cards_required(_whole_heap.word_size()) - 1,
+@@ -64,27 +57,50 @@
+ int max_covered_regions):
+ ModRefBarrierSet(max_covered_regions),
+ _whole_heap(whole_heap),
+- _guard_index(cards_required(whole_heap.word_size()) - 1),
+- _last_valid_index(_guard_index - 1),
++ _guard_index(0),
++ _guard_region(),
++ _last_valid_index(0),
+ _page_size(os::vm_page_size()),
+- _byte_map_size(compute_byte_map_size())
++ _byte_map_size(0),
++ _covered(NULL),
++ _committed(NULL),
++ _cur_covered_regions(0),
++ _byte_map(NULL),
++ byte_map_base(NULL),
++ // LNC functionality
++ _lowest_non_clean(NULL),
++ _lowest_non_clean_chunk_size(NULL),
++ _lowest_non_clean_base_chunk_index(NULL),
++ _last_LNC_resizing_collection(NULL)
+ {
+ _kind = BarrierSet::CardTableModRef;
+
+- HeapWord* low_bound = _whole_heap.start();
+- HeapWord* high_bound = _whole_heap.end();
+- assert((uintptr_t(low_bound) & (card_size - 1)) == 0, "heap must start at card boundary");
+- assert((uintptr_t(high_bound) & (card_size - 1)) == 0, "heap must end at card boundary");
++ assert((uintptr_t(_whole_heap.start()) & (card_size - 1)) == 0, "heap must start at card boundary");
++ assert((uintptr_t(_whole_heap.end()) & (card_size - 1)) == 0, "heap must end at card boundary");
+
+ assert(card_size <= 512, "card_size must be less than 512"); // why?
+
+- _covered = new MemRegion[max_covered_regions];
+- _committed = new MemRegion[max_covered_regions];
+- if (_covered == NULL || _committed == NULL) {
+- vm_exit_during_initialization("couldn't alloc card table covered region set.");
++ _covered = new MemRegion[_max_covered_regions];
++ if (_covered == NULL) {
++ vm_exit_during_initialization("Could not allocate card table covered region set.");
++ }
++}
++
++void CardTableModRefBS::initialize() {
++ _guard_index = cards_required(_whole_heap.word_size()) - 1;
++ _last_valid_index = _guard_index - 1;
++
++ _byte_map_size = compute_byte_map_size();
++
++ HeapWord* low_bound = _whole_heap.start();
++ HeapWord* high_bound = _whole_heap.end();
++
++ _cur_covered_regions = 0;
++ _committed = new MemRegion[_max_covered_regions];
++ if (_committed == NULL) {
++ vm_exit_during_initialization("Could not allocate card table committed region set.");
+ }
+
+- _cur_covered_regions = 0;
+ const size_t rs_align = _page_size == (size_t) os::vm_page_size() ? 0 :
+ MAX2(_page_size, (size_t) os::vm_allocation_granularity());
+ ReservedSpace heap_rs(_byte_map_size, rs_align, false);
+@@ -114,20 +130,20 @@
+ !ExecMem, "card table last card");
+ *guard_card = last_card;
+
+- _lowest_non_clean =
+- NEW_C_HEAP_ARRAY(CardArr, max_covered_regions, mtGC);
++ _lowest_non_clean =
++ NEW_C_HEAP_ARRAY(CardArr, _max_covered_regions, mtGC);
+ _lowest_non_clean_chunk_size =
+- NEW_C_HEAP_ARRAY(size_t, max_covered_regions, mtGC);
++ NEW_C_HEAP_ARRAY(size_t, _max_covered_regions, mtGC);
+ _lowest_non_clean_base_chunk_index =
+- NEW_C_HEAP_ARRAY(uintptr_t, max_covered_regions, mtGC);
++ NEW_C_HEAP_ARRAY(uintptr_t, _max_covered_regions, mtGC);
+ _last_LNC_resizing_collection =
+- NEW_C_HEAP_ARRAY(int, max_covered_regions, mtGC);
++ NEW_C_HEAP_ARRAY(int, _max_covered_regions, mtGC);
+ if (_lowest_non_clean == NULL
+ || _lowest_non_clean_chunk_size == NULL
+ || _lowest_non_clean_base_chunk_index == NULL
+ || _last_LNC_resizing_collection == NULL)
+ vm_exit_during_initialization("couldn't allocate an LNC array.");
+- for (int i = 0; i < max_covered_regions; i++) {
++ for (int i = 0; i < _max_covered_regions; i++) {
+ _lowest_non_clean[i] = NULL;
+ _lowest_non_clean_chunk_size[i] = 0;
+ _last_LNC_resizing_collection[i] = -1;
+@@ -429,7 +445,7 @@
+ OopsInGenClosure* cl,
+ CardTableRS* ct) {
+ if (!mr.is_empty()) {
+- // Caller (process_strong_roots()) claims that all GC threads
++ // Caller (process_roots()) claims that all GC threads
+ // execute this call. With UseDynamicNumberOfGCThreads now all
+ // active GC threads execute this call. The number of active GC
+ // threads needs to be passed to par_non_clean_card_iterate_work()
+@@ -438,7 +454,7 @@
+ // This is an example of where n_par_threads() is used instead
+ // of workers()->active_workers(). n_par_threads can be set to 0 to
+ // turn off parallelism. For example when this code is called as
+- // part of verification and SharedHeap::process_strong_roots() is being
++ // part of verification and SharedHeap::process_roots() is being
+ // used, then n_par_threads() may have been set to 0. active_workers
+ // is not overloaded with the meaning that it is a switch to disable
+ // parallelism and so keeps the meaning of the number of
+@@ -650,7 +666,7 @@
+ jbyte val, bool val_equals) {
+ jbyte* start = byte_for(mr.start());
+ jbyte* end = byte_for(mr.last());
+- bool failures = false;
++ bool failures = false;
+ for (jbyte* curr = start; curr <= end; ++curr) {
+ jbyte curr_val = *curr;
+ bool failed = (val_equals) ? (curr_val != val) : (curr_val == val);
+--- ./hotspot/src/share/vm/memory/cardTableModRefBS.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/cardTableModRefBS.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -96,12 +96,12 @@
+ // The declaration order of these const fields is important; see the
+ // constructor before changing.
+ const MemRegion _whole_heap; // the region covered by the card table
+- const size_t _guard_index; // index of very last element in the card
++ size_t _guard_index; // index of very last element in the card
+ // table; it is set to a guard value
+ // (last_card) and should never be modified
+- const size_t _last_valid_index; // index of the last valid element
++ size_t _last_valid_index; // index of the last valid element
+ const size_t _page_size; // page size used when mapping _byte_map
+- const size_t _byte_map_size; // in bytes
++ size_t _byte_map_size; // in bytes
+ jbyte* _byte_map; // the card marking array
+
+ int _cur_covered_regions;
+@@ -123,7 +123,12 @@
+ protected:
+ // Initialization utilities; covered_words is the size of the covered region
+ // in, um, words.
+- inline size_t cards_required(size_t covered_words);
++ inline size_t cards_required(size_t covered_words) {
++ // Add one for a guard card, used to detect errors.
++ const size_t words = align_size_up(covered_words, card_size_in_words);
++ return words / card_size_in_words + 1;
++ }
++
+ inline size_t compute_byte_map_size();
+
+ // Finds and return the index of the region, if any, to which the given
+@@ -137,7 +142,7 @@
+ int find_covering_region_containing(HeapWord* addr);
+
+ // Resize one of the regions covered by the remembered set.
+- void resize_covered_region(MemRegion new_region);
++ virtual void resize_covered_region(MemRegion new_region);
+
+ // Returns the leftmost end of a committed region corresponding to a
+ // covered region before covered region "ind", or else "NULL" if "ind" is
+@@ -282,6 +287,8 @@
+ CardTableModRefBS(MemRegion whole_heap, int max_covered_regions);
+ ~CardTableModRefBS();
+
++ virtual void initialize();
++
+ // *** Barrier set functions.
+
+ bool has_write_ref_pre_barrier() { return false; }
+--- ./hotspot/src/share/vm/memory/cardTableRS.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/cardTableRS.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -53,9 +53,10 @@
+ #else
+ _ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions);
+ #endif
++ _ct_bs->initialize();
+ set_bs(_ct_bs);
+ _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, GenCollectedHeap::max_gens + 1,
+- mtGC, 0, AllocFailStrategy::RETURN_NULL);
++ mtGC, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
+ if (_last_cur_val_in_gen == NULL) {
+ vm_exit_during_initialization("Could not create last_cur_val_in_gen array.");
+ }
+--- ./hotspot/src/share/vm/memory/collectorPolicy.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/collectorPolicy.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -183,13 +183,9 @@
+ // Requirements of any new remembered set implementations must be added here.
+ size_t alignment = GenRemSet::max_alignment_constraint(GenRemSet::CardTable);
+
+- // Parallel GC does its own alignment of the generations to avoid requiring a
+- // large page (256M on some platforms) for the permanent generation. The
+- // other collectors should also be updated to do their own alignment and then
+- // this use of lcm() should be removed.
+- if (UseLargePages && !UseParallelGC) {
+- // in presence of large pages we have to make sure that our
+- // alignment is large page aware
++ if (UseLargePages) {
++ // In presence of large pages we have to make sure that our
++ // alignment is large page aware.
+ alignment = lcm(os::large_page_size(), alignment);
+ }
+
+@@ -969,7 +965,8 @@
+ }
+
+ void MarkSweepPolicy::initialize_generations() {
+- _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC, 0, AllocFailStrategy::RETURN_NULL);
++ _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC, CURRENT_PC,
++ AllocFailStrategy::RETURN_NULL);
+ if (_generations == NULL) {
+ vm_exit_during_initialization("Unable to allocate gen spec");
+ }
+--- ./hotspot/src/share/vm/memory/defNewGeneration.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/defNewGeneration.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -42,6 +42,7 @@
+ #include "oops/instanceRefKlass.hpp"
+ #include "oops/oop.inline.hpp"
+ #include "runtime/java.hpp"
++#include "runtime/prefetch.inline.hpp"
+ #include "runtime/thread.inline.hpp"
+ #include "utilities/copy.hpp"
+ #include "utilities/stack.inline.hpp"
+@@ -584,7 +585,7 @@
+
+ init_assuming_no_promotion_failure();
+
+- GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL);
++ GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL, gc_tracer.gc_id());
+ // Capture heap used before collection (for printing).
+ size_t gch_prev_used = gch->used();
+
+@@ -612,6 +613,9 @@
+
+ KlassScanClosure klass_scan_closure(&fsc_with_no_gc_barrier,
+ gch->rem_set()->klass_rem_set());
++ CLDToKlassAndOopClosure cld_scan_closure(&klass_scan_closure,
++ &fsc_with_no_gc_barrier,
++ false);
+
+ set_promo_failure_scan_stack_closure(&fsc_with_no_gc_barrier);
+ FastEvacuateFollowersClosure evacuate_followers(gch, _level, this,
+@@ -621,18 +625,15 @@
+ assert(gch->no_allocs_since_save_marks(0),
+ "save marks have not been newly set.");
+
+- int so = SharedHeap::SO_AllClasses | SharedHeap::SO_Strings | SharedHeap::SO_CodeCache;
+-
+- gch->gen_process_strong_roots(_level,
+- true, // Process younger gens, if any,
+- // as strong roots.
+- true, // activate StrongRootsScope
+- true, // is scavenging
+- SharedHeap::ScanningOption(so),
+- &fsc_with_no_gc_barrier,
+- true, // walk *all* scavengable nmethods
+- &fsc_with_gc_barrier,
+- &klass_scan_closure);
++ gch->gen_process_roots(_level,
++ true, // Process younger gens, if any,
++ // as strong roots.
++ true, // activate StrongRootsScope
++ SharedHeap::SO_ScavengeCodeCache,
++ GenCollectedHeap::StrongAndWeakRoots,
++ &fsc_with_no_gc_barrier,
++ &fsc_with_gc_barrier,
++ &cld_scan_closure);
+
+ // "evacuate followers".
+ evacuate_followers.do_void();
+@@ -642,7 +643,7 @@
+ rp->setup_policy(clear_all_soft_refs);
+ const ReferenceProcessorStats& stats =
+ rp->process_discovered_references(&is_alive, &keep_alive, &evacuate_followers,
+- NULL, _gc_timer);
++ NULL, _gc_timer, gc_tracer.gc_id());
+ gc_tracer.report_gc_reference_stats(stats);
+
+ if (!_promotion_failed) {
+@@ -788,7 +789,7 @@
+
+ // Try allocating obj in to-space (unless too old)
+ if (old->age() < tenuring_threshold()) {
+- obj = (oop) to()->allocate(s);
++ obj = (oop) to()->allocate_aligned(s);
+ }
+
+ // Otherwise try allocating obj tenured
+--- ./hotspot/src/share/vm/memory/filemap.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/filemap.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -24,9 +24,14 @@
+
+ #include "precompiled.hpp"
+ #include "classfile/classLoader.hpp"
++#include "classfile/sharedClassUtil.hpp"
+ #include "classfile/symbolTable.hpp"
++#include "classfile/systemDictionaryShared.hpp"
+ #include "classfile/altHashing.hpp"
+ #include "memory/filemap.hpp"
++#include "memory/metadataFactory.hpp"
++#include "memory/oopFactory.hpp"
++#include "oops/objArrayOop.hpp"
+ #include "runtime/arguments.hpp"
+ #include "runtime/java.hpp"
+ #include "runtime/os.hpp"
+@@ -41,7 +46,6 @@
+ #endif
+
+ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+-
+ extern address JVM_FunctionAtStart();
+ extern address JVM_FunctionAtEnd();
+
+@@ -77,12 +81,27 @@
+ void FileMapInfo::fail_continue(const char *msg, ...) {
+ va_list ap;
+ va_start(ap, msg);
+- if (RequireSharedSpaces) {
+- fail(msg, ap);
++ MetaspaceShared::set_archive_loading_failed();
++ if (PrintSharedArchiveAndExit && _validating_classpath_entry_table) {
++ // If we are doing PrintSharedArchiveAndExit and some of the classpath entries
++ // do not validate, we can still continue "limping" to validate the remaining
++ // entries. No need to quit.
++ tty->print("[");
++ tty->vprint(msg, ap);
++ tty->print_cr("]");
++ } else {
++ if (RequireSharedSpaces) {
++ fail(msg, ap);
++ } else {
++ if (PrintSharedSpaces) {
++ tty->print_cr("UseSharedSpaces: %s", msg);
++ }
++ }
++ UseSharedSpaces = false;
++ assert(current_info() != NULL, "singleton must be registered");
++ current_info()->close();
+ }
+ va_end(ap);
+- UseSharedSpaces = false;
+- close();
+ }
+
+ // Fill in the fileMapInfo structure with data about this VM instance.
+@@ -117,74 +136,208 @@
+ }
+ }
+
++FileMapInfo::FileMapInfo() {
++ assert(_current_info == NULL, "must be singleton"); // not thread safe
++ _current_info = this;
++ memset(this, 0, sizeof(FileMapInfo));
++ _file_offset = 0;
++ _file_open = false;
++ _header = SharedClassUtil::allocate_file_map_header();
++ _header->_version = _invalid_version;
++}
++
++FileMapInfo::~FileMapInfo() {
++ assert(_current_info == this, "must be singleton"); // not thread safe
++ _current_info = NULL;
++}
++
+ void FileMapInfo::populate_header(size_t alignment) {
+- _header._magic = 0xf00baba2;
+- _header._version = _current_version;
+- _header._alignment = alignment;
+- _header._obj_alignment = ObjectAlignmentInBytes;
++ _header->populate(this, alignment);
++}
++
++size_t FileMapInfo::FileMapHeader::data_size() {
++ return SharedClassUtil::file_map_header_size() - sizeof(FileMapInfo::FileMapHeaderBase);
++}
++
++void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) {
++ _magic = 0xf00baba2;
++ _version = _current_version;
++ _alignment = alignment;
++ _obj_alignment = ObjectAlignmentInBytes;
++ _classpath_entry_table_size = mapinfo->_classpath_entry_table_size;
++ _classpath_entry_table = mapinfo->_classpath_entry_table;
++ _classpath_entry_size = mapinfo->_classpath_entry_size;
+
+ // The following fields are for sanity checks for whether this archive
+ // will function correctly with this JVM and the bootclasspath it's
+ // invoked with.
+
+ // JVM version string ... changes on each build.
+- get_header_version(_header._jvm_ident);
++ get_header_version(_jvm_ident);
++}
+
+- // Build checks on classpath and jar files
+- _header._num_jars = 0;
+- ClassPathEntry *cpe = ClassLoader::classpath_entry(0);
+- for ( ; cpe != NULL; cpe = cpe->next()) {
++void FileMapInfo::allocate_classpath_entry_table() {
++ int bytes = 0;
++ int count = 0;
++ char* strptr = NULL;
++ char* strptr_max = NULL;
++ Thread* THREAD = Thread::current();
+
+- if (cpe->is_jar_file()) {
+- if (_header._num_jars >= JVM_SHARED_JARS_MAX) {
+- fail_stop("Too many jar files to share.", NULL);
++ ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
++ size_t entry_size = SharedClassUtil::shared_class_path_entry_size();
++
++ for (int pass=0; pass<2; pass++) {
++ ClassPathEntry *cpe = ClassLoader::classpath_entry(0);
++
++ for (int cur_entry = 0 ; cpe != NULL; cpe = cpe->next(), cur_entry++) {
++ const char *name = cpe->name();
++ int name_bytes = (int)(strlen(name) + 1);
++
++ if (pass == 0) {
++ count ++;
++ bytes += (int)entry_size;
++ bytes += name_bytes;
++ if (TraceClassPaths || (TraceClassLoading && Verbose)) {
++ tty->print_cr("[Add main shared path (%s) %s]", (cpe->is_jar_file() ? "jar" : "dir"), name);
++ }
++ } else {
++ SharedClassPathEntry* ent = shared_classpath(cur_entry);
++ if (cpe->is_jar_file()) {
++ struct stat st;
++ if (os::stat(name, &st) != 0) {
++ // The file/dir must exist, or it would not have been added
++ // into ClassLoader::classpath_entry().
++ //
++ // If we can't access a jar file in the boot path, then we can't
++ // make assumptions about where classes get loaded from.
++ FileMapInfo::fail_stop("Unable to open jar file %s.", name);
++ }
++
++ EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
++ SharedClassUtil::update_shared_classpath(cpe, ent, st.st_mtime, st.st_size, THREAD);
++ } else {
++ ent->_filesize = -1;
++ if (!os::dir_is_empty(name)) {
++ ClassLoader::exit_with_path_failure("Cannot have non-empty directory in archived classpaths", name);
++ }
++ }
++ ent->_name = strptr;
++ if (strptr + name_bytes <= strptr_max) {
++ strncpy(strptr, name, (size_t)name_bytes); // name_bytes includes trailing 0.
++ strptr += name_bytes;
++ } else {
++ assert(0, "miscalculated buffer size");
++ }
+ }
++ }
+
+- // Jar file - record timestamp and file size.
+- struct stat st;
+- const char *path = cpe->name();
+- if (os::stat(path, &st) != 0) {
+- // If we can't access a jar file in the boot path, then we can't
+- // make assumptions about where classes get loaded from.
+- fail_stop("Unable to open jar file %s.", path);
+- }
+- _header._jar[_header._num_jars]._timestamp = st.st_mtime;
+- _header._jar[_header._num_jars]._filesize = st.st_size;
+- _header._num_jars++;
+- } else {
++ if (pass == 0) {
++ EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
++ Array<u8>* arr = MetadataFactory::new_array<u8>(loader_data, (bytes + 7)/8, THREAD);
++ strptr = (char*)(arr->data());
++ strptr_max = strptr + bytes;
++ SharedClassPathEntry* table = (SharedClassPathEntry*)strptr;
++ strptr += entry_size * count;
+
+- // If directories appear in boot classpath, they must be empty to
+- // avoid having to verify each individual class file.
+- const char* name = ((ClassPathDirEntry*)cpe)->name();
+- if (!os::dir_is_empty(name)) {
+- fail_stop("Boot classpath directory %s is not empty.", name);
+- }
++ _classpath_entry_table_size = count;
++ _classpath_entry_table = table;
++ _classpath_entry_size = entry_size;
+ }
+ }
+ }
+
++bool FileMapInfo::validate_classpath_entry_table() {
++ _validating_classpath_entry_table = true;
++
++ int count = _header->_classpath_entry_table_size;
++
++ _classpath_entry_table = _header->_classpath_entry_table;
++ _classpath_entry_size = _header->_classpath_entry_size;
++
++ for (int i=0; i<count; i++) {
++ SharedClassPathEntry* ent = shared_classpath(i);
++ struct stat st;
++ const char* name = ent->_name;
++ bool ok = true;
++ if (TraceClassPaths || (TraceClassLoading && Verbose)) {
++ tty->print_cr("[Checking shared classpath entry: %s]", name);
++ }
++ if (os::stat(name, &st) != 0) {
++ fail_continue("Required classpath entry does not exist: %s", name);
++ ok = false;
++ } else if (ent->is_dir()) {
++ if (!os::dir_is_empty(name)) {
++ fail_continue("directory is not empty: %s", name);
++ ok = false;
++ }
++ } else {
++ if (ent->_timestamp != st.st_mtime ||
++ ent->_filesize != st.st_size) {
++ ok = false;
++ if (PrintSharedArchiveAndExit) {
++ fail_continue(ent->_timestamp != st.st_mtime ?
++ "Timestamp mismatch" :
++ "File size mismatch");
++ } else {
++ fail_continue("A jar file is not the one used while building"
++ " the shared archive file: %s", name);
++ }
++ }
++ }
++ if (ok) {
++ if (TraceClassPaths || (TraceClassLoading && Verbose)) {
++ tty->print_cr("[ok]");
++ }
++ } else if (!PrintSharedArchiveAndExit) {
++ _validating_classpath_entry_table = false;
++ return false;
++ }
++ }
++
++ _classpath_entry_table_size = _header->_classpath_entry_table_size;
++ _validating_classpath_entry_table = false;
++ return true;
++}
++
+
+ // Read the FileMapInfo information from the file.
+
+ bool FileMapInfo::init_from_file(int fd) {
+-
+- size_t n = read(fd, &_header, sizeof(struct FileMapHeader));
+- if (n != sizeof(struct FileMapHeader)) {
++ size_t sz = _header->data_size();
++ char* addr = _header->data();
++ size_t n = os::read(fd, addr, (unsigned int)sz);
++ if (n != sz) {
+ fail_continue("Unable to read the file header.");
+ return false;
+ }
+- if (_header._version != current_version()) {
++ if (_header->_version != current_version()) {
+ fail_continue("The shared archive file has the wrong version.");
+ return false;
+ }
++
++ size_t info_size = _header->_paths_misc_info_size;
++ _paths_misc_info = NEW_C_HEAP_ARRAY_RETURN_NULL(char, info_size, mtClass);
++ if (_paths_misc_info == NULL) {
++ fail_continue("Unable to read the file header.");
++ return false;
++ }
++ n = os::read(fd, _paths_misc_info, (unsigned int)info_size);
++ if (n != info_size) {
++ fail_continue("Unable to read the shared path info header.");
++ FREE_C_HEAP_ARRAY(char, _paths_misc_info, mtClass);
++ _paths_misc_info = NULL;
++ return false;
++ }
++
+ size_t len = lseek(fd, 0, SEEK_END);
+ struct FileMapInfo::FileMapHeader::space_info* si =
+- &_header._space[MetaspaceShared::mc];
++ &_header->_space[MetaspaceShared::mc];
+ if (si->_file_offset >= len || len - si->_file_offset < si->_used) {
+ fail_continue("The shared archive file has been truncated.");
+ return false;
+ }
+- _file_offset = n;
++
++ _file_offset += (long)n;
+ return true;
+ }
+
+@@ -239,7 +392,16 @@
+ // Write the header to the file, seek to the next allocation boundary.
+
+ void FileMapInfo::write_header() {
+- write_bytes_aligned(&_header, sizeof(FileMapHeader));
++ int info_size = ClassLoader::get_shared_paths_misc_info_size();
++
++ _header->_paths_misc_info_size = info_size;
++
++ align_file_position();
++ size_t sz = _header->data_size();
++ char* addr = _header->data();
++ write_bytes(addr, (int)sz); // skip the C++ vtable
++ write_bytes(ClassLoader::get_shared_paths_misc_info(), info_size);
++ align_file_position();
+ }
+
+
+@@ -249,7 +411,7 @@
+ align_file_position();
+ size_t used = space->used_bytes_slow(Metaspace::NonClassType);
+ size_t capacity = space->capacity_bytes_slow(Metaspace::NonClassType);
+- struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
++ struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
+ write_region(i, (char*)space->bottom(), used, capacity, read_only, false);
+ }
+
+@@ -259,7 +421,7 @@
+ void FileMapInfo::write_region(int region, char* base, size_t size,
+ size_t capacity, bool read_only,
+ bool allow_exec) {
+- struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[region];
++ struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[region];
+
+ if (_file_open) {
+ guarantee(si->_file_offset == _file_offset, "file offset mismatch.");
+@@ -343,7 +505,7 @@
+ // JVM/TI RedefineClasses() support:
+ // Remap the shared readonly space to shared readwrite, private.
+ bool FileMapInfo::remap_shared_readonly_as_readwrite() {
+- struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0];
++ struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[0];
+ if (!si->_read_only) {
+ // the space is already readwrite so we are done
+ return true;
+@@ -371,7 +533,7 @@
+
+ // Map the whole region at once, assumed to be allocated contiguously.
+ ReservedSpace FileMapInfo::reserve_shared_memory() {
+- struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0];
++ struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[0];
+ char* requested_addr = si->_base;
+
+ size_t size = FileMapInfo::shared_spaces_size();
+@@ -393,7 +555,7 @@
+ static const char* shared_region_name[] = { "ReadOnly", "ReadWrite", "MiscData", "MiscCode"};
+
+ char* FileMapInfo::map_region(int i) {
+- struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
++ struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
+ size_t used = si->_used;
+ size_t alignment = os::vm_allocation_granularity();
+ size_t size = align_size_up(used, alignment);
+@@ -419,10 +581,10 @@
+ if (!VerifySharedSpaces) {
+ return true;
+ }
+- const char* buf = _header._space[i]._base;
+- size_t sz = _header._space[i]._used;
++ const char* buf = _header->_space[i]._base;
++ size_t sz = _header->_space[i]._used;
+ int crc = ClassLoader::crc32(0, buf, (jint)sz);
+- if (crc != _header._space[i]._crc) {
++ if (crc != _header->_space[i]._crc) {
+ fail_continue("Checksum verification failed.");
+ return false;
+ }
+@@ -432,7 +594,7 @@
+ // Unmap a memory region in the address space.
+
+ void FileMapInfo::unmap_region(int i) {
+- struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
++ struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
+ size_t used = si->_used;
+ size_t size = align_size_up(used, os::vm_allocation_granularity());
+ if (!os::unmap_memory(si->_base, size)) {
+@@ -449,12 +611,21 @@
+
+
+ FileMapInfo* FileMapInfo::_current_info = NULL;
+-
++SharedClassPathEntry* FileMapInfo::_classpath_entry_table = NULL;
++int FileMapInfo::_classpath_entry_table_size = 0;
++size_t FileMapInfo::_classpath_entry_size = 0x1234baad;
++bool FileMapInfo::_validating_classpath_entry_table = false;
+
+ // Open the shared archive file, read and validate the header
+ // information (version, boot classpath, etc.). If initialization
+ // fails, shared spaces are disabled and the file is closed. [See
+ // fail_continue.]
++//
++// Validation of the archive is done in two steps:
++//
++// [1] validate_header() - done here. This checks the header, including _paths_misc_info.
++// [2] validate_classpath_entry_table - this is done later, because the table is in the RW
++// region of the archive, which is not mapped yet.
+ bool FileMapInfo::initialize() {
+ assert(UseSharedSpaces, "UseSharedSpaces expected.");
+
+@@ -468,104 +639,84 @@
+ }
+
+ init_from_file(_fd);
+- if (!validate()) {
++ if (!validate_header()) {
+ return false;
+ }
+
+- SharedReadOnlySize = _header._space[0]._capacity;
+- SharedReadWriteSize = _header._space[1]._capacity;
+- SharedMiscDataSize = _header._space[2]._capacity;
+- SharedMiscCodeSize = _header._space[3]._capacity;
++ SharedReadOnlySize = _header->_space[0]._capacity;
++ SharedReadWriteSize = _header->_space[1]._capacity;
++ SharedMiscDataSize = _header->_space[2]._capacity;
++ SharedMiscCodeSize = _header->_space[3]._capacity;
+ return true;
+ }
+
+-int FileMapInfo::compute_header_crc() {
+- char* header = (char*)&_header;
++int FileMapInfo::FileMapHeader::compute_crc() {
++ char* header = data();
+ // start computing from the field after _crc
+- char* buf = (char*)&_header._crc + sizeof(int);
+- size_t sz = sizeof(FileMapInfo::FileMapHeader) - (buf - header);
++ char* buf = (char*)&_crc + sizeof(int);
++ size_t sz = data_size() - (buf - header);
+ int crc = ClassLoader::crc32(0, buf, (jint)sz);
+ return crc;
+ }
+
+-bool FileMapInfo::validate() {
+- if (VerifySharedSpaces && compute_header_crc() != _header._crc) {
++int FileMapInfo::compute_header_crc() {
++ return _header->compute_crc();
++}
++
++bool FileMapInfo::FileMapHeader::validate() {
++ if (_magic != (int)0xf00baba2) {
++ FileMapInfo::fail_continue("The shared archive file has a bad magic number.");
++ return false;
++ }
++ if (VerifySharedSpaces && compute_crc() != _crc) {
+ fail_continue("Header checksum verification failed.");
+ return false;
+ }
+- if (_header._version != current_version()) {
+- fail_continue("The shared archive file is the wrong version.");
+- return false;
+- }
+- if (_header._magic != (int)0xf00baba2) {
+- fail_continue("The shared archive file has a bad magic number.");
++ if (_version != current_version()) {
++ FileMapInfo::fail_continue("The shared archive file is the wrong version.");
++
+ return false;
+ }
+ char header_version[JVM_IDENT_MAX];
+ get_header_version(header_version);
+- if (strncmp(_header._jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
+- fail_continue("The shared archive file was created by a different"
+- " version or build of HotSpot.");
++ if (strncmp(_jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
++ if (TraceClassPaths) {
++ tty->print_cr("Expected: %s", header_version);
++ tty->print_cr("Actual: %s", _jvm_ident);
++ }
++ FileMapInfo::fail_continue("The shared archive file was created by a different"
++ " version or build of HotSpot");
+ return false;
+ }
+- if (_header._obj_alignment != ObjectAlignmentInBytes) {
+- fail_continue("The shared archive file's ObjectAlignmentInBytes of %d"
++ if (_obj_alignment != ObjectAlignmentInBytes) {
++ FileMapInfo::fail_continue("The shared archive file's ObjectAlignmentInBytes of %d"
+ " does not equal the current ObjectAlignmentInBytes of %d.",
+- _header._obj_alignment, ObjectAlignmentInBytes);
+- return false;
+- }
+-
+- // Cannot verify interpreter yet, as it can only be created after the GC
+- // heap has been initialized.
+-
+- if (_header._num_jars >= JVM_SHARED_JARS_MAX) {
+- fail_continue("Too many jar files to share.");
+- return false;
+- }
+-
+- // Build checks on classpath and jar files
+- int num_jars_now = 0;
+- ClassPathEntry *cpe = ClassLoader::classpath_entry(0);
+- for ( ; cpe != NULL; cpe = cpe->next()) {
+-
+- if (cpe->is_jar_file()) {
+- if (num_jars_now < _header._num_jars) {
+-
+- // Jar file - verify timestamp and file size.
+- struct stat st;
+- const char *path = cpe->name();
+- if (os::stat(path, &st) != 0) {
+- fail_continue("Unable to open jar file %s.", path);
+- return false;
+- }
+- if (_header._jar[num_jars_now]._timestamp != st.st_mtime ||
+- _header._jar[num_jars_now]._filesize != st.st_size) {
+- fail_continue("A jar file is not the one used while building"
+- " the shared archive file.");
+- return false;
+- }
+- }
+- ++num_jars_now;
+- } else {
+-
+- // If directories appear in boot classpath, they must be empty to
+- // avoid having to verify each individual class file.
+- const char* name = ((ClassPathDirEntry*)cpe)->name();
+- if (!os::dir_is_empty(name)) {
+- fail_continue("Boot classpath directory %s is not empty.", name);
+- return false;
+- }
+- }
+- }
+- if (num_jars_now < _header._num_jars) {
+- fail_continue("The number of jar files in the boot classpath is"
+- " less than the number the shared archive was created with.");
++ _obj_alignment, ObjectAlignmentInBytes);
+ return false;
+ }
+
+ return true;
+ }
+
++bool FileMapInfo::validate_header() {
++ bool status = _header->validate();
++
++ if (status) {
++ if (!ClassLoader::check_shared_paths_misc_info(_paths_misc_info, _header->_paths_misc_info_size)) {
++ if (!PrintSharedArchiveAndExit) {
++ fail_continue("shared class paths mismatch (hint: enable -XX:+TraceClassPaths to diagnose the failure)");
++ status = false;
++ }
++ }
++ }
++
++ if (_paths_misc_info != NULL) {
++ FREE_C_HEAP_ARRAY(char, _paths_misc_info, mtClass);
++ _paths_misc_info = NULL;
++ }
++ return status;
++}
++
+ // The following method is provided to see whether a given pointer
+ // falls in the mapped shared space.
+ // Param:
+@@ -574,8 +725,8 @@
+ // True if the p is within the mapped shared space, otherwise, false.
+ bool FileMapInfo::is_in_shared_space(const void* p) {
+ for (int i = 0; i < MetaspaceShared::n_regions; i++) {
+- if (p >= _header._space[i]._base &&
+- p < _header._space[i]._base + _header._space[i]._used) {
++ if (p >= _header->_space[i]._base &&
++ p < _header->_space[i]._base + _header->_space[i]._used) {
+ return true;
+ }
+ }
+@@ -586,7 +737,7 @@
+ void FileMapInfo::print_shared_spaces() {
+ gclog_or_tty->print_cr("Shared Spaces:");
+ for (int i = 0; i < MetaspaceShared::n_regions; i++) {
+- struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
++ struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
+ gclog_or_tty->print(" %s " INTPTR_FORMAT "-" INTPTR_FORMAT,
+ shared_region_name[i],
+ si->_base, si->_base + si->_used);
+@@ -599,9 +750,9 @@
+ if (map_info) {
+ map_info->fail_continue(msg);
+ for (int i = 0; i < MetaspaceShared::n_regions; i++) {
+- if (map_info->_header._space[i]._base != NULL) {
++ if (map_info->_header->_space[i]._base != NULL) {
+ map_info->unmap_region(i);
+- map_info->_header._space[i]._base = NULL;
++ map_info->_header->_space[i]._base = NULL;
+ }
+ }
+ } else if (DumpSharedSpaces) {
+--- ./hotspot/src/share/vm/memory/filemap.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/filemap.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -37,30 +37,55 @@
+ // misc data (block offset table, string table, symbols, dictionary, etc.)
+ // tag(666)
+
+-static const int JVM_SHARED_JARS_MAX = 128;
+-static const int JVM_SPACENAME_MAX = 128;
+ static const int JVM_IDENT_MAX = 256;
+-static const int JVM_ARCH_MAX = 12;
+-
+
+ class Metaspace;
+
++class SharedClassPathEntry VALUE_OBJ_CLASS_SPEC {
++public:
++ const char *_name;
++ time_t _timestamp; // jar timestamp, 0 if is directory
++ long _filesize; // jar file size, -1 if is directory
++ bool is_dir() {
++ return _filesize == -1;
++ }
++};
++
+ class FileMapInfo : public CHeapObj<mtInternal> {
+ private:
++ friend class ManifestStream;
+ enum {
+ _invalid_version = -1,
+- _current_version = 1
++ _current_version = 2
+ };
+
+ bool _file_open;
+ int _fd;
+ size_t _file_offset;
+
++private:
++ static SharedClassPathEntry* _classpath_entry_table;
++ static int _classpath_entry_table_size;
++ static size_t _classpath_entry_size;
++ static bool _validating_classpath_entry_table;
++
+ // FileMapHeader describes the shared space data in the file to be
+ // mapped. This structure gets written to a file. It is not a class, so
+ // that the compilers don't add any compiler-private data to it.
+
+- struct FileMapHeader {
++public:
++ struct FileMapHeaderBase : public CHeapObj<mtClass> {
++ virtual bool validate() = 0;
++ virtual void populate(FileMapInfo* info, size_t alignment) = 0;
++ };
++ struct FileMapHeader : FileMapHeaderBase {
++ // Use data() and data_size() to memcopy to/from the FileMapHeader. We need to
++ // avoid read/writing the C++ vtable pointer.
++ static size_t data_size();
++ char* data() {
++ return ((char*)this) + sizeof(FileMapHeaderBase);
++ }
++
+ int _magic; // identify file type.
+ int _crc; // header crc checksum.
+ int _version; // (from enum, above.)
+@@ -80,46 +105,67 @@
+ // The following fields are all sanity checks for whether this archive
+ // will function correctly with this JVM and the bootclasspath it's
+ // invoked with.
+- char _arch[JVM_ARCH_MAX]; // architecture
+ char _jvm_ident[JVM_IDENT_MAX]; // identifier for jvm
+- int _num_jars; // Number of jars in bootclasspath
+
+- // Per jar file data: timestamp, size.
++ // The _paths_misc_info is a variable-size structure that records "miscellaneous"
++ // information during dumping. It is generated and validated by the
++ // SharedPathsMiscInfo class. See SharedPathsMiscInfo.hpp and sharedClassUtil.hpp for
++ // detailed description.
++ //
++ // The _paths_misc_info data is stored as a byte array in the archive file header,
++ // immediately after the _header field. This information is used only when
++ // checking the validity of the archive and is deallocated after the archive is loaded.
++ //
++ // Note that the _paths_misc_info does NOT include information for JAR files
++ // that existed during dump time. Their information is stored in _classpath_entry_table.
++ int _paths_misc_info_size;
+
+- struct {
+- time_t _timestamp; // jar timestamp.
+- long _filesize; // jar file size.
+- } _jar[JVM_SHARED_JARS_MAX];
+- } _header;
++ // The following is a table of all the class path entries that were used
++ // during dumping. At run time, we require these files to exist and have the same
++ // size/modification time, or else the archive will refuse to load.
++ //
++ // All of these entries must be JAR files. The dumping process would fail if a non-empty
++ // directory was specified in the classpaths. If an empty directory was specified
++ // it is checked by the _paths_misc_info as described above.
++ //
++ // FIXME -- if JAR files in the tail of the list were specified but not used during dumping,
++ // they should be removed from this table, to save space and to avoid spurious
++ // loading failures during runtime.
++ int _classpath_entry_table_size;
++ size_t _classpath_entry_size;
++ SharedClassPathEntry* _classpath_entry_table;
++
++ virtual bool validate();
++ virtual void populate(FileMapInfo* info, size_t alignment);
++ int compute_crc();
++ };
++
++ FileMapHeader * _header;
++
+ const char* _full_path;
++ char* _paths_misc_info;
+
+ static FileMapInfo* _current_info;
+
+ bool init_from_file(int fd);
+ void align_file_position();
++ bool validate_header_impl();
+
+ public:
+- FileMapInfo() {
+- _file_offset = 0;
+- _file_open = false;
+- _header._version = _invalid_version;
+- }
++ FileMapInfo();
++ ~FileMapInfo();
+
+ static int current_version() { return _current_version; }
+ int compute_header_crc();
+- void set_header_crc(int crc) { _header._crc = crc; }
++ void set_header_crc(int crc) { _header->_crc = crc; }
+ void populate_header(size_t alignment);
+- bool validate();
++ bool validate_header();
+ void invalidate();
+- int version() { return _header._version; }
+- size_t alignment() { return _header._alignment; }
+- size_t space_capacity(int i) { return _header._space[i]._capacity; }
+- char* region_base(int i) { return _header._space[i]._base; }
+- struct FileMapHeader* header() { return &_header; }
+-
+- static void set_current_info(FileMapInfo* info) {
+- CDS_ONLY(_current_info = info;)
+- }
++ int version() { return _header->_version; }
++ size_t alignment() { return _header->_alignment; }
++ size_t space_capacity(int i) { return _header->_space[i]._capacity; }
++ char* region_base(int i) { return _header->_space[i]._base; }
++ struct FileMapHeader* header() { return _header; }
+
+ static FileMapInfo* current_info() {
+ CDS_ONLY(return _current_info;)
+@@ -151,7 +197,7 @@
+
+ // Errors.
+ static void fail_stop(const char *msg, ...);
+- void fail_continue(const char *msg, ...);
++ static void fail_continue(const char *msg, ...);
+
+ // Return true if given address is in the mapped shared space.
+ bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);
+@@ -165,6 +211,22 @@
+
+ // Stop CDS sharing and unmap CDS regions.
+ static void stop_sharing_and_unmap(const char* msg);
++
++ static void allocate_classpath_entry_table();
++ bool validate_classpath_entry_table();
++
++ static SharedClassPathEntry* shared_classpath(int index) {
++ char* p = (char*)_classpath_entry_table;
++ p += _classpath_entry_size * index;
++ return (SharedClassPathEntry*)p;
++ }
++ static const char* shared_classpath_name(int index) {
++ return shared_classpath(index)->_name;
++ }
++
++ static int get_number_of_share_classpaths() {
++ return _classpath_entry_table_size;
++ }
+ };
+
+ #endif // SHARE_VM_MEMORY_FILEMAP_HPP
+--- ./hotspot/src/share/vm/memory/freeList.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/freeList.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -34,7 +34,6 @@
+
+ #if INCLUDE_ALL_GCS
+ #include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
+-#include "gc_implementation/g1/g1CodeCacheRemSet.hpp"
+ #endif // INCLUDE_ALL_GCS
+
+ // Free list. A FreeList is used to access a linked list of chunks
+@@ -333,5 +332,4 @@
+ template class FreeList<Metachunk>;
+ #if INCLUDE_ALL_GCS
+ template class FreeList<FreeChunk>;
+-template class FreeList<G1CodeRootChunk>;
+ #endif // INCLUDE_ALL_GCS
+--- ./hotspot/src/share/vm/memory/gcLocker.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/gcLocker.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,6 +26,7 @@
+ #include "memory/gcLocker.inline.hpp"
+ #include "memory/resourceArea.hpp"
+ #include "memory/sharedHeap.hpp"
++#include "runtime/thread.inline.hpp"
+
+ volatile jint GC_locker::_jni_lock_count = 0;
+ volatile bool GC_locker::_needs_gc = false;
+--- ./hotspot/src/share/vm/memory/genCollectedHeap.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/genCollectedHeap.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,6 +28,7 @@
+ #include "classfile/vmSymbols.hpp"
+ #include "code/icBuffer.hpp"
+ #include "gc_implementation/shared/collectorCounters.hpp"
++#include "gc_implementation/shared/gcTrace.hpp"
+ #include "gc_implementation/shared/gcTraceTime.hpp"
+ #include "gc_implementation/shared/vmGCOperations.hpp"
+ #include "gc_interface/collectedHeap.inline.hpp"
+@@ -60,8 +61,8 @@
+ GenCollectedHeap* GenCollectedHeap::_gch;
+ NOT_PRODUCT(size_t GenCollectedHeap::_skip_header_HeapWords = 0;)
+
+-// The set of potentially parallel tasks in strong root scanning.
+-enum GCH_process_strong_roots_tasks {
++// The set of potentially parallel tasks in root scanning.
++enum GCH_strong_roots_tasks {
+ // We probably want to parallelize both of these internally, but for now...
+ GCH_PS_younger_gens,
+ // Leave this one last.
+@@ -71,11 +72,11 @@
+ GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy) :
+ SharedHeap(policy),
+ _gen_policy(policy),
+- _gen_process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)),
++ _gen_process_roots_tasks(new SubTasksDone(GCH_PS_NumElements)),
+ _full_collections_completed(0)
+ {
+- if (_gen_process_strong_tasks == NULL ||
+- !_gen_process_strong_tasks->valid()) {
++ if (_gen_process_roots_tasks == NULL ||
++ !_gen_process_roots_tasks->valid()) {
+ vm_exit_during_initialization("Failed necessary allocation.");
+ }
+ assert(policy != NULL, "Sanity check");
+@@ -385,7 +386,9 @@
+ const char* gc_cause_prefix = complete ? "Full GC" : "GC";
+ gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
+ TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
+- GCTraceTime t(GCCauseString(gc_cause_prefix, gc_cause()), PrintGCDetails, false, NULL);
++ // The PrintGCDetails logging starts before we have incremented the GC id. We will do that later
++ // so we can assume here that the next GC id is what we want.
++ GCTraceTime t(GCCauseString(gc_cause_prefix, gc_cause()), PrintGCDetails, false, NULL, GCId::peek());
+
+ gc_prologue(complete);
+ increment_total_collections(complete);
+@@ -418,7 +421,9 @@
+ }
+ // Timer for individual generations. Last argument is false: no CR
+ // FIXME: We should try to start the timing earlier to cover more of the GC pause
+- GCTraceTime t1(_gens[i]->short_name(), PrintGCDetails, false, NULL);
++ // The PrintGCDetails logging starts before we have incremented the GC id. We will do that later
++ // so we can assume here that the next GC id is what we want.
++ GCTraceTime t1(_gens[i]->short_name(), PrintGCDetails, false, NULL, GCId::peek());
+ TraceCollectorStats tcs(_gens[i]->counters());
+ TraceMemoryManagerStats tmms(_gens[i]->kind(),gc_cause());
+
+@@ -585,33 +590,29 @@
+
+ void GenCollectedHeap::set_par_threads(uint t) {
+ SharedHeap::set_par_threads(t);
+- _gen_process_strong_tasks->set_n_threads(t);
++ _gen_process_roots_tasks->set_n_threads(t);
+ }
+
+ void GenCollectedHeap::
+-gen_process_strong_roots(int level,
+- bool younger_gens_as_roots,
+- bool activate_scope,
+- bool is_scavenging,
+- SharedHeap::ScanningOption so,
+- OopsInGenClosure* not_older_gens,
+- bool do_code_roots,
+- OopsInGenClosure* older_gens,
+- KlassClosure* klass_closure) {
+- // General strong roots.
++gen_process_roots(int level,
++ bool younger_gens_as_roots,
++ bool activate_scope,
++ SharedHeap::ScanningOption so,
++ OopsInGenClosure* not_older_gens,
++ OopsInGenClosure* weak_roots,
++ OopsInGenClosure* older_gens,
++ CLDClosure* cld_closure,
++ CLDClosure* weak_cld_closure,
++ CodeBlobClosure* code_closure) {
+
+- if (!do_code_roots) {
+- SharedHeap::process_strong_roots(activate_scope, is_scavenging, so,
+- not_older_gens, NULL, klass_closure);
+- } else {
+- bool do_code_marking = (activate_scope || nmethod::oops_do_marking_is_active());
+- CodeBlobToOopClosure code_roots(not_older_gens, /*do_marking=*/ do_code_marking);
+- SharedHeap::process_strong_roots(activate_scope, is_scavenging, so,
+- not_older_gens, &code_roots, klass_closure);
+- }
++ // General roots.
++ SharedHeap::process_roots(activate_scope, so,
++ not_older_gens, weak_roots,
++ cld_closure, weak_cld_closure,
++ code_closure);
+
+ if (younger_gens_as_roots) {
+- if (!_gen_process_strong_tasks->is_task_claimed(GCH_PS_younger_gens)) {
++ if (!_gen_process_roots_tasks->is_task_claimed(GCH_PS_younger_gens)) {
+ for (int i = 0; i < level; i++) {
+ not_older_gens->set_generation(_gens[i]);
+ _gens[i]->oop_iterate(not_older_gens);
+@@ -627,12 +628,42 @@
+ older_gens->reset_generation();
+ }
+
+- _gen_process_strong_tasks->all_tasks_completed();
++ _gen_process_roots_tasks->all_tasks_completed();
+ }
+
+-void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure,
+- CodeBlobClosure* code_roots) {
+- SharedHeap::process_weak_roots(root_closure, code_roots);
++void GenCollectedHeap::
++gen_process_roots(int level,
++ bool younger_gens_as_roots,
++ bool activate_scope,
++ SharedHeap::ScanningOption so,
++ bool only_strong_roots,
++ OopsInGenClosure* not_older_gens,
++ OopsInGenClosure* older_gens,
++ CLDClosure* cld_closure) {
++
++ const bool is_adjust_phase = !only_strong_roots && !younger_gens_as_roots;
++
++ bool is_moving_collection = false;
++ if (level == 0 || is_adjust_phase) {
++ // young collections are always moving
++ is_moving_collection = true;
++ }
++
++ MarkingCodeBlobClosure mark_code_closure(not_older_gens, is_moving_collection);
++ CodeBlobClosure* code_closure = &mark_code_closure;
++
++ gen_process_roots(level,
++ younger_gens_as_roots,
++ activate_scope, so,
++ not_older_gens, only_strong_roots ? NULL : not_older_gens,
++ older_gens,
++ cld_closure, only_strong_roots ? NULL : cld_closure,
++ code_closure);
++
++}
++
++void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure) {
++ SharedHeap::process_weak_roots(root_closure);
+ // "Local" "weak" refs
+ for (int i = 0; i < _n_gens; i++) {
+ _gens[i]->ref_processor()->weak_oops_do(root_closure);
+@@ -673,10 +704,6 @@
+ return _gens[0]->end_addr();
+ }
+
+-size_t GenCollectedHeap::unsafe_max_alloc() {
+- return _gens[0]->unsafe_max_alloc_nogc();
+-}
+-
+ // public collection interfaces
+
+ void GenCollectedHeap::collect(GCCause::Cause cause) {
+@@ -687,15 +714,18 @@
+ #else // INCLUDE_ALL_GCS
+ ShouldNotReachHere();
+ #endif // INCLUDE_ALL_GCS
++ } else if (cause == GCCause::_wb_young_gc) {
++ // minor collection for WhiteBox API
++ collect(cause, 0);
+ } else {
+ #ifdef ASSERT
+- if (cause == GCCause::_scavenge_alot) {
+- // minor collection only
+- collect(cause, 0);
+- } else {
+- // Stop-the-world full collection
+- collect(cause, n_gens() - 1);
+- }
++ if (cause == GCCause::_scavenge_alot) {
++ // minor collection only
++ collect(cause, 0);
++ } else {
++ // Stop-the-world full collection
++ collect(cause, n_gens() - 1);
++ }
+ #else
+ // Stop-the-world full collection
+ collect(cause, n_gens() - 1);
+@@ -851,12 +881,6 @@
+ }
+ }
+
+-void GenCollectedHeap::oop_iterate(MemRegion mr, ExtendedOopClosure* cl) {
+- for (int i = 0; i < _n_gens; i++) {
+- _gens[i]->oop_iterate(mr, cl);
+- }
+-}
+-
+ void GenCollectedHeap::object_iterate(ObjectClosure* cl) {
+ for (int i = 0; i < _n_gens; i++) {
+ _gens[i]->object_iterate(cl);
+@@ -1074,7 +1098,7 @@
+ guarantee(_n_gens = 2, "Wrong number of generations");
+ Generation* old_gen = _gens[1];
+ // Start by compacting into same gen.
+- CompactPoint cp(old_gen, NULL, NULL);
++ CompactPoint cp(old_gen);
+ old_gen->prepare_for_compaction(&cp);
+ Generation* young_gen = _gens[0];
+ young_gen->prepare_for_compaction(&cp);
+--- ./hotspot/src/share/vm/memory/genCollectedHeap.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/genCollectedHeap.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -78,9 +78,9 @@
+ unsigned int _full_collections_completed;
+
+ // Data structure for claiming the (potentially) parallel tasks in
+- // (gen-specific) strong roots processing.
+- SubTasksDone* _gen_process_strong_tasks;
+- SubTasksDone* gen_process_strong_tasks() { return _gen_process_strong_tasks; }
++ // (gen-specific) roots processing.
++ SubTasksDone* _gen_process_roots_tasks;
++ SubTasksDone* gen_process_roots_tasks() { return _gen_process_roots_tasks; }
+
+ // In block contents verification, the number of header words to skip
+ NOT_PRODUCT(static size_t _skip_header_HeapWords;)
+@@ -166,14 +166,6 @@
+ HeapWord** top_addr() const;
+ HeapWord** end_addr() const;
+
+- // Return an estimate of the maximum allocation that could be performed
+- // without triggering any collection activity. In a generational
+- // collector, for example, this is probably the largest allocation that
+- // could be supported in the youngest generation. It is "unsafe" because
+- // no locks are taken; the result should be treated as an approximation,
+- // not a guarantee.
+- size_t unsafe_max_alloc();
+-
+ // Does this heap support heap inspection? (+PrintClassHistogram)
+ virtual bool supports_heap_inspection() const { return true; }
+
+@@ -220,7 +212,6 @@
+
+ // Iteration functions.
+ void oop_iterate(ExtendedOopClosure* cl);
+- void oop_iterate(MemRegion mr, ExtendedOopClosure* cl);
+ void object_iterate(ObjectClosure* cl);
+ void safe_object_iterate(ObjectClosure* cl);
+ Space* space_containing(const void* addr) const;
+@@ -412,26 +403,35 @@
+ // The "so" argument determines which of the roots
+ // the closure is applied to:
+ // "SO_None" does none;
+- // "SO_AllClasses" applies the closure to all entries in the SystemDictionary;
+- // "SO_SystemClasses" to all the "system" classes and loaders;
+- // "SO_Strings" applies the closure to all entries in the StringTable.
+- void gen_process_strong_roots(int level,
+- bool younger_gens_as_roots,
+- // The remaining arguments are in an order
+- // consistent with SharedHeap::process_strong_roots:
+- bool activate_scope,
+- bool is_scavenging,
+- SharedHeap::ScanningOption so,
+- OopsInGenClosure* not_older_gens,
+- bool do_code_roots,
+- OopsInGenClosure* older_gens,
+- KlassClosure* klass_closure);
++ private:
++ void gen_process_roots(int level,
++ bool younger_gens_as_roots,
++ bool activate_scope,
++ SharedHeap::ScanningOption so,
++ OopsInGenClosure* not_older_gens,
++ OopsInGenClosure* weak_roots,
++ OopsInGenClosure* older_gens,
++ CLDClosure* cld_closure,
++ CLDClosure* weak_cld_closure,
++ CodeBlobClosure* code_closure);
+
+- // Apply "blk" to all the weak roots of the system. These include
+- // JNI weak roots, the code cache, system dictionary, symbol table,
+- // string table, and referents of reachable weak refs.
+- void gen_process_weak_roots(OopClosure* root_closure,
+- CodeBlobClosure* code_roots);
++ public:
++ static const bool StrongAndWeakRoots = false;
++ static const bool StrongRootsOnly = true;
++
++ void gen_process_roots(int level,
++ bool younger_gens_as_roots,
++ bool activate_scope,
++ SharedHeap::ScanningOption so,
++ bool only_strong_roots,
++ OopsInGenClosure* not_older_gens,
++ OopsInGenClosure* older_gens,
++ CLDClosure* cld_closure);
++
++ // Apply "root_closure" to all the weak roots of the system.
++ // These include JNI weak roots, string table,
++ // and referents of reachable weak refs.
++ void gen_process_weak_roots(OopClosure* root_closure);
+
+ // Set the saved marks of generations, if that makes sense.
+ // In particular, if any generation might iterate over the oops
+--- ./hotspot/src/share/vm/memory/genMarkSweep.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/genMarkSweep.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -69,7 +69,7 @@
+ _ref_processor = rp;
+ rp->setup_policy(clear_all_softrefs);
+
+- GCTraceTime t1(GCCauseString("Full GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL);
++ GCTraceTime t1(GCCauseString("Full GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL, _gc_tracer->gc_id());
+
+ gch->trace_heap_before_gc(_gc_tracer);
+
+@@ -193,7 +193,7 @@
+ void GenMarkSweep::mark_sweep_phase1(int level,
+ bool clear_all_softrefs) {
+ // Recursively traverse all live objects and mark them
+- GCTraceTime tm("phase 1", PrintGC && Verbose, true, _gc_timer);
++ GCTraceTime tm("phase 1", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+ trace(" 1");
+
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+@@ -207,22 +207,21 @@
+ // Need new claim bits before marking starts.
+ ClassLoaderDataGraph::clear_claimed_marks();
+
+- gch->gen_process_strong_roots(level,
+- false, // Younger gens are not roots.
+- true, // activate StrongRootsScope
+- false, // not scavenging
+- SharedHeap::SO_SystemClasses,
+- &follow_root_closure,
+- true, // walk code active on stacks
+- &follow_root_closure,
+- &follow_klass_closure);
++ gch->gen_process_roots(level,
++ false, // Younger gens are not roots.
++ true, // activate StrongRootsScope
++ SharedHeap::SO_None,
++ GenCollectedHeap::StrongRootsOnly,
++ &follow_root_closure,
++ &follow_root_closure,
++ &follow_cld_closure);
+
+ // Process reference objects found during marking
+ {
+ ref_processor()->setup_policy(clear_all_softrefs);
+ const ReferenceProcessorStats& stats =
+ ref_processor()->process_discovered_references(
+- &is_alive, &keep_alive, &follow_stack_closure, NULL, _gc_timer);
++ &is_alive, &keep_alive, &follow_stack_closure, NULL, _gc_timer, _gc_tracer->gc_id());
+ gc_tracer()->report_gc_reference_stats(stats);
+ }
+
+@@ -264,7 +263,7 @@
+
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+
+- GCTraceTime tm("phase 2", PrintGC && Verbose, true, _gc_timer);
++ GCTraceTime tm("phase 2", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+ trace("2");
+
+ gch->prepare_for_compaction();
+@@ -281,7 +280,7 @@
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+
+ // Adjust the pointers to reflect the new locations
+- GCTraceTime tm("phase 3", PrintGC && Verbose, true, _gc_timer);
++ GCTraceTime tm("phase 3", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+ trace("3");
+
+ // Need new claim bits for the pointer adjustment tracing.
+@@ -293,22 +292,16 @@
+ // are run.
+ adjust_pointer_closure.set_orig_generation(gch->get_gen(level));
+
+- gch->gen_process_strong_roots(level,
+- false, // Younger gens are not roots.
+- true, // activate StrongRootsScope
+- false, // not scavenging
+- SharedHeap::SO_AllClasses,
+- &adjust_pointer_closure,
+- false, // do not walk code
+- &adjust_pointer_closure,
+- &adjust_klass_closure);
++ gch->gen_process_roots(level,
++ false, // Younger gens are not roots.
++ true, // activate StrongRootsScope
++ SharedHeap::SO_AllCodeCache,
++ GenCollectedHeap::StrongAndWeakRoots,
++ &adjust_pointer_closure,
++ &adjust_pointer_closure,
++ &adjust_cld_closure);
+
+- // Now adjust pointers in remaining weak roots. (All of which should
+- // have been cleared if they pointed to non-surviving objects.)
+- CodeBlobToOopClosure adjust_code_pointer_closure(&adjust_pointer_closure,
+- /*do_marking=*/ false);
+- gch->gen_process_weak_roots(&adjust_pointer_closure,
+- &adjust_code_pointer_closure);
++ gch->gen_process_weak_roots(&adjust_pointer_closure);
+
+ adjust_marks();
+ GenAdjustPointersClosure blk;
+@@ -336,7 +329,7 @@
+ // to use a higher index (saved from phase2) when verifying perm_gen.
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+
+- GCTraceTime tm("phase 4", PrintGC && Verbose, true, _gc_timer);
++ GCTraceTime tm("phase 4", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
+ trace("4");
+
+ GenCompactClosure blk;
+--- ./hotspot/src/share/vm/memory/generation.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/generation.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -297,22 +297,16 @@
+
+ class GenerationOopIterateClosure : public SpaceClosure {
+ public:
+- ExtendedOopClosure* cl;
+- MemRegion mr;
++ ExtendedOopClosure* _cl;
+ virtual void do_space(Space* s) {
+- s->oop_iterate(mr, cl);
++ s->oop_iterate(_cl);
+ }
+- GenerationOopIterateClosure(ExtendedOopClosure* _cl, MemRegion _mr) :
+- cl(_cl), mr(_mr) {}
++ GenerationOopIterateClosure(ExtendedOopClosure* cl) :
++ _cl(cl) {}
+ };
+
+ void Generation::oop_iterate(ExtendedOopClosure* cl) {
+- GenerationOopIterateClosure blk(cl, _reserved);
+- space_iterate(&blk);
+-}
+-
+-void Generation::oop_iterate(MemRegion mr, ExtendedOopClosure* cl) {
+- GenerationOopIterateClosure blk(cl, mr);
++ GenerationOopIterateClosure blk(cl);
+ space_iterate(&blk);
+ }
+
+--- ./hotspot/src/share/vm/memory/generation.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/generation.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -543,10 +543,6 @@
+ // generation, calling "cl.do_oop" on each.
+ virtual void oop_iterate(ExtendedOopClosure* cl);
+
+- // Same as above, restricted to the intersection of a memory region and
+- // the generation.
+- virtual void oop_iterate(MemRegion mr, ExtendedOopClosure* cl);
+-
+ // Iterate over all objects in the generation, calling "cl.do_object" on
+ // each.
+ virtual void object_iterate(ObjectClosure* cl);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/memory/guardedMemory.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,161 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++#include "precompiled.hpp"
++#include "memory/allocation.hpp"
++#include "memory/allocation.inline.hpp"
++#include "memory/guardedMemory.hpp"
++#include "runtime/os.hpp"
++
++void* GuardedMemory::wrap_copy(const void* ptr, const size_t len, const void* tag) {
++ size_t total_sz = GuardedMemory::get_total_size(len);
++ void* outerp = os::malloc(total_sz, mtInternal);
++ if (outerp != NULL) {
++ GuardedMemory guarded(outerp, len, tag);
++ void* innerp = guarded.get_user_ptr();
++ memcpy(innerp, ptr, len);
++ return innerp;
++ }
++ return NULL; // OOM
++}
++
++bool GuardedMemory::free_copy(void* p) {
++ if (p == NULL) {
++ return true;
++ }
++ GuardedMemory guarded((u_char*)p);
++ bool verify_ok = guarded.verify_guards();
++
++ /* always attempt to free, pass problem on to any nested memchecker */
++ os::free(guarded.release_for_freeing());
++
++ return verify_ok;
++}
++
++void GuardedMemory::print_on(outputStream* st) const {
++ if (_base_addr == NULL) {
++ st->print_cr("GuardedMemory(" PTR_FORMAT ") not associated to any memory", p2i(this));
++ return;
++ }
++ st->print_cr("GuardedMemory(" PTR_FORMAT ") base_addr=" PTR_FORMAT
++ " tag=" PTR_FORMAT " user_size=" SIZE_FORMAT " user_data=" PTR_FORMAT,
++ p2i(this), p2i(_base_addr), p2i(get_tag()), get_user_size(), p2i(get_user_ptr()));
++
++ Guard* guard = get_head_guard();
++ st->print_cr(" Header guard @" PTR_FORMAT " is %s", p2i(guard), (guard->verify() ? "OK" : "BROKEN"));
++ guard = get_tail_guard();
++ st->print_cr(" Trailer guard @" PTR_FORMAT " is %s", p2i(guard), (guard->verify() ? "OK" : "BROKEN"));
++
++ u_char udata = *get_user_ptr();
++ switch (udata) {
++ case uninitBlockPad:
++ st->print_cr(" User data appears unused");
++ break;
++ case freeBlockPad:
++ st->print_cr(" User data appears to have been freed");
++ break;
++ default:
++ st->print_cr(" User data appears to be in use");
++ break;
++ }
++}
++
++// test code...
++
++#ifndef PRODUCT
++
++static void guarded_memory_test_check(void* p, size_t sz, void* tag) {
++ assert(p != NULL, "NULL pointer given to check");
++ u_char* c = (u_char*) p;
++ GuardedMemory guarded(c);
++ assert(guarded.get_tag() == tag, "Tag is not the same as supplied");
++ assert(guarded.get_user_ptr() == c, "User pointer is not the same as supplied");
++ assert(guarded.get_user_size() == sz, "User size is not the same as supplied");
++ assert(guarded.verify_guards(), "Guard broken");
++}
++
++void GuardedMemory::test_guarded_memory() {
++ // Test the basic characteristics...
++ size_t total_sz = GuardedMemory::get_total_size(1);
++ assert(total_sz > 1 && total_sz >= (sizeof(GuardHeader) + 1 + sizeof(Guard)), "Unexpected size");
++ u_char* basep = (u_char*) os::malloc(total_sz, mtInternal);
++
++ GuardedMemory guarded(basep, 1, (void*)0xf000f000);
++
++ assert(*basep == badResourceValue, "Expected guard in the form of badResourceValue");
++ u_char* userp = guarded.get_user_ptr();
++ assert(*userp == uninitBlockPad, "Expected uninitialized data in the form of uninitBlockPad");
++ guarded_memory_test_check(userp, 1, (void*)0xf000f000);
++
++ void* freep = guarded.release_for_freeing();
++ assert((u_char*)freep == basep, "Expected the same pointer guard was ");
++ assert(*userp == freeBlockPad, "Expected user data to be free block padded");
++ assert(!guarded.verify_guards(), "Expected failed");
++ os::free(freep);
++
++ // Test a number of odd sizes...
++ size_t sz = 0;
++ do {
++ void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
++ void* up = guarded.wrap_with_guards(p, sz, (void*)1);
++ memset(up, 0, sz);
++ guarded_memory_test_check(up, sz, (void*)1);
++ os::free(guarded.release_for_freeing());
++ sz = (sz << 4) + 1;
++ } while (sz < (256 * 1024));
++
++ // Test buffer overrun into head...
++ basep = (u_char*) os::malloc(GuardedMemory::get_total_size(1), mtInternal);
++ guarded.wrap_with_guards(basep, 1);
++ *basep = 0;
++ assert(!guarded.verify_guards(), "Expected failure");
++ os::free(basep);
++
++ // Test buffer overrun into tail with a number of odd sizes...
++ sz = 1;
++ do {
++ void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
++ void* up = guarded.wrap_with_guards(p, sz, (void*)1);
++ memset(up, 0, sz + 1); // Buffer-overwrite (within guard)
++ assert(!guarded.verify_guards(), "Guard was not broken as expected");
++ os::free(guarded.release_for_freeing());
++ sz = (sz << 4) + 1;
++ } while (sz < (256 * 1024));
++
++ // Test wrap_copy/wrap_free...
++ assert(GuardedMemory::free_copy(NULL), "Expected free NULL to be OK");
++
++ const char* str = "Check my bounds out";
++ size_t str_sz = strlen(str) + 1;
++ char* str_copy = (char*) GuardedMemory::wrap_copy(str, str_sz);
++ guarded_memory_test_check(str_copy, str_sz, NULL);
++ assert(strcmp(str, str_copy) == 0, "Not identical copy");
++ assert(GuardedMemory::free_copy(str_copy), "Free copy failed to verify");
++
++ void* no_data = NULL;
++ void* no_data_copy = GuardedMemory::wrap_copy(no_data, 0);
++ assert(GuardedMemory::free_copy(no_data_copy), "Expected valid guards even for no data copy");
++}
++
++#endif // !PRODUCT
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/memory/guardedMemory.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,326 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_MEMORY_GUARDED_MEMORY_HPP
++#define SHARE_VM_MEMORY_GUARDED_MEMORY_HPP
++
++#include "memory/allocation.hpp"
++#include "utilities/globalDefinitions.hpp"
++
++/**
++ * Guarded memory for detecting buffer overrun.
++ *
++ * Allows allocations to be wrapped with padded bytes of a known byte pattern,
++ * that is a "guard". Guard patterns may be verified to detect buffer overruns.
++ *
++ * Primarily used by "debug malloc" and "checked JNI".
++ *
++ * Memory layout:
++ *
++ * |Offset | Content | Description |
++ * |------------------------------------------------------------
++ * |base_addr | 0xABABABABABABABAB | Head guard |
++ * |+16 | <size_t:user_size> | User data size |
++ * |+sizeof(uintptr_t) | <tag> | Tag word |
++ * |+sizeof(void*) | 0xF1 <user_data> ( | User data |
++ * |+user_size | 0xABABABABABABABAB | Tail guard |
++ * -------------------------------------------------------------
++ *
++ * Where:
++ * - guard padding uses "badResourceValue" (0xAB)
++ * - tag word is general purpose
++ * - user data
++ * -- initially padded with "uninitBlockPad" (0xF1),
++ * -- to "freeBlockPad" (0xBA), when freed
++ *
++ * Usage:
++ *
++ * * Allocations: one may wrap allocations with guard memory:
++ * <code>
++ * Thing* alloc_thing() {
++ * void* mem = user_alloc_fn(GuardedMemory::get_total_size(sizeof(thing)));
++ * GuardedMemory guarded(mem, sizeof(thing));
++ * return (Thing*) guarded.get_user_ptr();
++ * }
++ * </code>
++ * * Verify: memory guards are still in tact
++ * <code>
++ * bool verify_thing(Thing* thing) {
++ * GuardedMemory guarded((void*)thing);
++ * return guarded.verify_guards();
++ * }
++ * </code>
++ * * Free: one may mark bytes as freed (further debugging support)
++ * <code>
++ * void free_thing(Thing* thing) {
++ * GuardedMemory guarded((void*)thing);
++ * assert(guarded.verify_guards(), "Corrupt thing");
++ * user_free_fn(guards.release_for_freeing();
++ * }
++ * </code>
++ */
++class GuardedMemory : StackObj { // Wrapper on stack
++
++ // Private inner classes for memory layout...
++
++protected:
++
++ /**
++ * Guard class for header and trailer known pattern to test for overwrites.
++ */
++ class Guard { // Class for raw memory (no vtbl allowed)
++ friend class GuardedMemory;
++ protected:
++ enum {
++ GUARD_SIZE = 16
++ };
++
++ u_char _guard[GUARD_SIZE];
++
++ public:
++
++ void build() {
++ u_char* c = _guard; // Possibly unaligned if tail guard
++ u_char* end = c + GUARD_SIZE;
++ while (c < end) {
++ *c = badResourceValue;
++ c++;
++ }
++ }
++
++ bool verify() const {
++ u_char* c = (u_char*) _guard;
++ u_char* end = c + GUARD_SIZE;
++ while (c < end) {
++ if (*c != badResourceValue) {
++ return false;
++ }
++ c++;
++ }
++ return true;
++ }
++
++ }; // GuardedMemory::Guard
++
++ /**
++ * Header guard and size
++ */
++ class GuardHeader : Guard {
++ friend class GuardedMemory;
++ protected:
++ // Take care in modifying fields here, will effect alignment
++ // e.g. x86 ABI 16 byte stack alignment
++ union {
++ uintptr_t __unused_full_word1;
++ size_t _user_size;
++ };
++ void* _tag;
++ public:
++ void set_user_size(const size_t usz) { _user_size = usz; }
++ size_t get_user_size() const { return _user_size; }
++
++ void set_tag(const void* tag) { _tag = (void*) tag; }
++ void* get_tag() const { return _tag; }
++
++ }; // GuardedMemory::GuardHeader
++
++ // Guarded Memory...
++
++ protected:
++ u_char* _base_addr;
++
++ public:
++
++ /**
++ * Create new guarded memory.
++ *
++ * Wraps, starting at the given "base_ptr" with guards. Use "get_user_ptr()"
++ * to return a pointer suitable for user data.
++ *
++ * @param base_ptr allocation wishing to be wrapped, must be at least "GuardedMemory::get_total_size()" bytes.
++ * @param user_size the size of the user data to be wrapped.
++ * @param tag optional general purpose tag.
++ */
++ GuardedMemory(void* base_ptr, const size_t user_size, const void* tag = NULL) {
++ wrap_with_guards(base_ptr, user_size, tag);
++ }
++
++ /**
++ * Wrap existing guarded memory.
++ *
++ * To use this constructor, one must have created guarded memory with
++ * "GuardedMemory(void*, size_t, void*)" (or indirectly via helper, e.g. "wrap_copy()").
++ *
++ * @param user_p existing wrapped memory.
++ */
++ GuardedMemory(void* userp) {
++ u_char* user_ptr = (u_char*) userp;
++ assert((uintptr_t)user_ptr > (sizeof(GuardHeader) + 0x1000), "Invalid pointer");
++ _base_addr = (user_ptr - sizeof(GuardHeader));
++ }
++
++ /**
++ * Create new guarded memory.
++ *
++ * Wraps, starting at the given "base_ptr" with guards. Allows reuse of stack allocated helper.
++ *
++ * @param base_ptr allocation wishing to be wrapped, must be at least "GuardedMemory::get_total_size()" bytes.
++ * @param user_size the size of the user data to be wrapped.
++ * @param tag optional general purpose tag.
++ *
++ * @return user data pointer (inner pointer to supplied "base_ptr").
++ */
++ void* wrap_with_guards(void* base_ptr, size_t user_size, const void* tag = NULL) {
++ assert(base_ptr != NULL, "Attempt to wrap NULL with memory guard");
++ _base_addr = (u_char*)base_ptr;
++ get_head_guard()->build();
++ get_head_guard()->set_user_size(user_size);
++ get_tail_guard()->build();
++ set_tag(tag);
++ set_user_bytes(uninitBlockPad);
++ assert(verify_guards(), "Expected valid memory guards");
++ return get_user_ptr();
++ }
++
++ /**
++ * Verify head and tail guards.
++ *
++ * @return true if guards are intact, false would indicate a buffer overrun.
++ */
++ bool verify_guards() const {
++ if (_base_addr != NULL) {
++ return (get_head_guard()->verify() && get_tail_guard()->verify());
++ }
++ return false;
++ }
++
++ /**
++ * Set the general purpose tag.
++ *
++ * @param tag general purpose tag.
++ */
++ void set_tag(const void* tag) { get_head_guard()->set_tag(tag); }
++
++ /**
++ * Return the general purpose tag.
++ *
++ * @return the general purpose tag, defaults to NULL.
++ */
++ void* get_tag() const { return get_head_guard()->get_tag(); }
++
++ /**
++ * Return the size of the user data.
++ *
++ * @return the size of the user data.
++ */
++ size_t get_user_size() const {
++ assert(_base_addr, "Not wrapping any memory");
++ return get_head_guard()->get_user_size();
++ }
++
++ /**
++ * Return the user data pointer.
++ *
++ * @return the user data pointer.
++ */
++ u_char* get_user_ptr() const {
++ assert(_base_addr, "Not wrapping any memory");
++ return _base_addr + sizeof(GuardHeader);
++ }
++
++ /**
++ * Release the wrapped pointer for resource freeing.
++ *
++ * Pads the user data with "freeBlockPad", and dis-associates the helper.
++ *
++ * @return the original base pointer used to wrap the data.
++ */
++ void* release_for_freeing() {
++ set_user_bytes(freeBlockPad);
++ return release();
++ }
++
++ /**
++ * Dis-associate the help from the original base address.
++ *
++ * @return the original base pointer used to wrap the data.
++ */
++ void* release() {
++ void* p = (void*) _base_addr;
++ _base_addr = NULL;
++ return p;
++ }
++
++ virtual void print_on(outputStream* st) const;
++
++ protected:
++ GuardHeader* get_head_guard() const { return (GuardHeader*) _base_addr; }
++ Guard* get_tail_guard() const { return (Guard*) (get_user_ptr() + get_user_size()); };
++ void set_user_bytes(u_char ch) {
++ memset(get_user_ptr(), ch, get_user_size());
++ }
++
++public:
++ /**
++ * Return the total size required for wrapping the given user size.
++ *
++ * @return the total size required for wrapping the given user size.
++ */
++ static size_t get_total_size(size_t user_size) {
++ size_t total_size = sizeof(GuardHeader) + user_size + sizeof(Guard);
++ assert(total_size > user_size, "Unexpected wrap-around");
++ return total_size;
++ }
++
++ // Helper functions...
++
++ /**
++ * Wrap a copy of size "len" of "ptr".
++ *
++ * @param ptr the memory to be copied
++ * @param len the length of the copy
++ * @param tag optional general purpose tag (see GuardedMemory::get_tag())
++ *
++ * @return guarded wrapped memory pointer to the user area, or NULL if OOM.
++ */
++ static void* wrap_copy(const void* p, const size_t len, const void* tag = NULL);
++
++ /**
++ * Free wrapped copy.
++ *
++ * Frees memory copied with "wrap_copy()".
++ *
++ * @param p memory returned by "wrap_copy()".
++ *
++ * @return true if guards were verified as intact. false indicates a buffer overrun.
++ */
++ static bool free_copy(void* p);
++
++ // Testing...
++#ifndef PRODUCT
++ static void test_guarded_memory(void);
++#endif
++}; // GuardedMemory
++
++#endif // SHARE_VM_MEMORY_GUARDED_MEMORY_HPP
+--- ./hotspot/src/share/vm/memory/heapInspection.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/heapInspection.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -135,7 +135,7 @@
+ _ref = (HeapWord*) Universe::boolArrayKlassObj();
+ _buckets =
+ (KlassInfoBucket*) AllocateHeap(sizeof(KlassInfoBucket) * _num_buckets,
+- mtInternal, 0, AllocFailStrategy::RETURN_NULL);
++ mtInternal, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
+ if (_buckets != NULL) {
+ _size = _num_buckets;
+ for (int index = 0; index < _size; index++) {
+--- ./hotspot/src/share/vm/memory/iterator.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/iterator.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -27,6 +27,7 @@
+ #include "oops/oop.inline.hpp"
+
+ void KlassToOopClosure::do_klass(Klass* k) {
++ assert(_oop_closure != NULL, "Not initialized?");
+ k->oops_do(_oop_closure);
+ }
+
+@@ -34,6 +35,10 @@
+ cld->oops_do(_oop_closure, &_klass_closure, _must_claim_cld);
+ }
+
++void CLDToKlassAndOopClosure::do_cld(ClassLoaderData* cld) {
++ cld->oops_do(_oop_closure, _klass_closure, _must_claim_cld);
++}
++
+ void ObjectToOopClosure::do_object(oop obj) {
+ obj->oop_iterate(_cl);
+ }
+@@ -42,6 +47,20 @@
+ ShouldNotCallThis();
+ }
+
++void CodeBlobToOopClosure::do_nmethod(nmethod* nm) {
++ nm->oops_do(_cl);
++ if (_fix_relocations) {
++ nm->fix_oop_relocations();
++ }
++}
++
++void CodeBlobToOopClosure::do_code_blob(CodeBlob* cb) {
++ nmethod* nm = cb->as_nmethod_or_null();
++ if (nm != NULL) {
++ do_nmethod(nm);
++ }
++}
++
+ MarkingCodeBlobClosure::MarkScope::MarkScope(bool activate)
+ : _active(activate)
+ {
+@@ -54,32 +73,7 @@
+
+ void MarkingCodeBlobClosure::do_code_blob(CodeBlob* cb) {
+ nmethod* nm = cb->as_nmethod_or_null();
+- if (nm == NULL) return;
+- if (!nm->test_set_oops_do_mark()) {
+- NOT_PRODUCT(if (TraceScavenge) nm->print_on(tty, "oops_do, 1st visit\n"));
+- do_newly_marked_nmethod(nm);
+- } else {
+- NOT_PRODUCT(if (TraceScavenge) nm->print_on(tty, "oops_do, skipped on 2nd visit\n"));
++ if (nm != NULL && !nm->test_set_oops_do_mark()) {
++ do_nmethod(nm);
+ }
+ }
+-
+-void CodeBlobToOopClosure::do_newly_marked_nmethod(nmethod* nm) {
+- nm->oops_do(_cl, /*allow_zombie=*/ false);
+-}
+-
+-void CodeBlobToOopClosure::do_code_blob(CodeBlob* cb) {
+- if (!_do_marking) {
+- nmethod* nm = cb->as_nmethod_or_null();
+- NOT_PRODUCT(if (TraceScavenge && Verbose && nm != NULL) nm->print_on(tty, "oops_do, unmarked visit\n"));
+- // This assert won't work, since there are lots of mini-passes
+- // (mostly in debug mode) that co-exist with marking phases.
+- //assert(!(cb->is_nmethod() && ((nmethod*)cb)->test_oops_do_mark()), "found marked nmethod during mark-free phase");
+- if (nm != NULL) {
+- nm->oops_do(_cl);
+- }
+- } else {
+- MarkingCodeBlobClosure::do_code_blob(cb);
+- }
+-}
+-
+-
+--- ./hotspot/src/share/vm/memory/iterator.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/iterator.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -84,8 +84,8 @@
+ //
+ // Providing default implementations of the _nv functions unfortunately
+ // removes the compile-time safeness, but reduces the clutter for the
+- // ExtendedOopClosures that don't need to walk the metadata. Currently,
+- // only CMS needs these.
++ // ExtendedOopClosures that don't need to walk the metadata.
++ // Currently, only CMS and G1 need these.
+
+ virtual bool do_metadata() { return do_metadata_nv(); }
+ bool do_metadata_v() { return do_metadata(); }
+@@ -128,17 +128,33 @@
+ virtual void do_klass(Klass* k) = 0;
+ };
+
++class CLDClosure : public Closure {
++ public:
++ virtual void do_cld(ClassLoaderData* cld) = 0;
++};
++
+ class KlassToOopClosure : public KlassClosure {
++ friend class MetadataAwareOopClosure;
++ friend class MetadataAwareOopsInGenClosure;
++
+ OopClosure* _oop_closure;
++
++ // Used when _oop_closure couldn't be set in an initialization list.
++ void initialize(OopClosure* oop_closure) {
++ assert(_oop_closure == NULL, "Should only be called once");
++ _oop_closure = oop_closure;
++ }
++
+ public:
+- KlassToOopClosure(OopClosure* oop_closure) : _oop_closure(oop_closure) {}
++ KlassToOopClosure(OopClosure* oop_closure = NULL) : _oop_closure(oop_closure) {}
++
+ virtual void do_klass(Klass* k);
+ };
+
+-class CLDToOopClosure {
+- OopClosure* _oop_closure;
++class CLDToOopClosure : public CLDClosure {
++ OopClosure* _oop_closure;
+ KlassToOopClosure _klass_closure;
+- bool _must_claim_cld;
++ bool _must_claim_cld;
+
+ public:
+ CLDToOopClosure(OopClosure* oop_closure, bool must_claim_cld = true) :
+@@ -149,6 +165,46 @@
+ void do_cld(ClassLoaderData* cld);
+ };
+
++class CLDToKlassAndOopClosure : public CLDClosure {
++ friend class SharedHeap;
++ friend class G1CollectedHeap;
++ protected:
++ OopClosure* _oop_closure;
++ KlassClosure* _klass_closure;
++ bool _must_claim_cld;
++ public:
++ CLDToKlassAndOopClosure(KlassClosure* klass_closure,
++ OopClosure* oop_closure,
++ bool must_claim_cld) :
++ _oop_closure(oop_closure),
++ _klass_closure(klass_closure),
++ _must_claim_cld(must_claim_cld) {}
++ void do_cld(ClassLoaderData* cld);
++};
++
++// The base class for all concurrent marking closures,
++// that participates in class unloading.
++// It's used to proxy through the metadata to the oops defined in them.
++class MetadataAwareOopClosure: public ExtendedOopClosure {
++ KlassToOopClosure _klass_closure;
++
++ public:
++ MetadataAwareOopClosure() : ExtendedOopClosure() {
++ _klass_closure.initialize(this);
++ }
++ MetadataAwareOopClosure(ReferenceProcessor* rp) : ExtendedOopClosure(rp) {
++ _klass_closure.initialize(this);
++ }
++
++ virtual bool do_metadata() { return do_metadata_nv(); }
++ inline bool do_metadata_nv() { return true; }
++
++ virtual void do_klass(Klass* k);
++ void do_klass_nv(Klass* k);
++
++ virtual void do_class_loader_data(ClassLoaderData* cld);
++};
++
+ // ObjectClosure is used for iterating through an object space
+
+ class ObjectClosure : public Closure {
+@@ -172,19 +228,6 @@
+ ObjectToOopClosure(ExtendedOopClosure* cl) : _cl(cl) {}
+ };
+
+-// A version of ObjectClosure with "memory" (see _previous_address below)
+-class UpwardsObjectClosure: public BoolObjectClosure {
+- HeapWord* _previous_address;
+- public:
+- UpwardsObjectClosure() : _previous_address(NULL) { }
+- void set_previous(HeapWord* addr) { _previous_address = addr; }
+- HeapWord* previous() { return _previous_address; }
+- // A return value of "true" can be used by the caller to decide
+- // if this object's end should *NOT* be recorded in
+- // _previous_address above.
+- virtual bool do_object_bm(oop obj, MemRegion mr) = 0;
+-};
+-
+ // A version of ObjectClosure that is expected to be robust
+ // in the face of possibly uninitialized objects.
+ class ObjectClosureCareful : public ObjectClosure {
+@@ -240,14 +283,26 @@
+ virtual void do_code_blob(CodeBlob* cb) = 0;
+ };
+
++// Applies an oop closure to all ref fields in code blobs
++// iterated over in an object iteration.
++class CodeBlobToOopClosure : public CodeBlobClosure {
++ OopClosure* _cl;
++ bool _fix_relocations;
++ protected:
++ void do_nmethod(nmethod* nm);
++ public:
++ CodeBlobToOopClosure(OopClosure* cl, bool fix_relocations) : _cl(cl), _fix_relocations(fix_relocations) {}
++ virtual void do_code_blob(CodeBlob* cb);
+
+-class MarkingCodeBlobClosure : public CodeBlobClosure {
++ const static bool FixRelocations = true;
++};
++
++class MarkingCodeBlobClosure : public CodeBlobToOopClosure {
+ public:
++ MarkingCodeBlobClosure(OopClosure* cl, bool fix_relocations) : CodeBlobToOopClosure(cl, fix_relocations) {}
+ // Called for each code blob, but at most once per unique blob.
+- virtual void do_newly_marked_nmethod(nmethod* nm) = 0;
+
+ virtual void do_code_blob(CodeBlob* cb);
+- // = { if (!nmethod(cb)->test_set_oops_do_mark()) do_newly_marked_nmethod(cb); }
+
+ class MarkScope : public StackObj {
+ protected:
+@@ -260,23 +315,6 @@
+ };
+ };
+
+-
+-// Applies an oop closure to all ref fields in code blobs
+-// iterated over in an object iteration.
+-class CodeBlobToOopClosure: public MarkingCodeBlobClosure {
+- OopClosure* _cl;
+- bool _do_marking;
+-public:
+- virtual void do_newly_marked_nmethod(nmethod* cb);
+- // = { cb->oops_do(_cl); }
+- virtual void do_code_blob(CodeBlob* cb);
+- // = { if (_do_marking) super::do_code_blob(cb); else cb->oops_do(_cl); }
+- CodeBlobToOopClosure(OopClosure* cl, bool do_marking)
+- : _cl(cl), _do_marking(do_marking) {}
+-};
+-
+-
+-
+ // MonitorClosure is used for iterating over monitors in the monitors cache
+
+ class ObjectMonitor;
+@@ -345,4 +383,16 @@
+ }
+ };
+
++
++// Helper defines for ExtendOopClosure
++
++#define if_do_metadata_checked(closure, nv_suffix) \
++ /* Make sure the non-virtual and the virtual versions match. */ \
++ assert(closure->do_metadata##nv_suffix() == closure->do_metadata(), \
++ "Inconsistency in do_metadata"); \
++ if (closure->do_metadata##nv_suffix())
++
++#define assert_should_ignore_metadata(closure, nv_suffix) \
++ assert(!closure->do_metadata##nv_suffix(), "Code to handle metadata is not implemented")
++
+ #endif // SHARE_VM_MEMORY_ITERATOR_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/memory/iterator.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_MEMORY_ITERATOR_INLINE_HPP
++#define SHARE_VM_MEMORY_ITERATOR_INLINE_HPP
++
++#include "classfile/classLoaderData.hpp"
++#include "memory/iterator.hpp"
++#include "oops/klass.hpp"
++#include "utilities/debug.hpp"
++
++inline void MetadataAwareOopClosure::do_class_loader_data(ClassLoaderData* cld) {
++ assert(_klass_closure._oop_closure == this, "Must be");
++
++ bool claim = true; // Must claim the class loader data before processing.
++ cld->oops_do(_klass_closure._oop_closure, &_klass_closure, claim);
++}
++
++inline void MetadataAwareOopClosure::do_klass_nv(Klass* k) {
++ ClassLoaderData* cld = k->class_loader_data();
++ do_class_loader_data(cld);
++}
++
++inline void MetadataAwareOopClosure::do_klass(Klass* k) { do_klass_nv(k); }
++
++#endif // SHARE_VM_MEMORY_ITERATOR_INLINE_HPP
+--- ./hotspot/src/share/vm/memory/memRegion.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/memRegion.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -103,11 +103,13 @@
+ }
+
+ void* MemRegion::operator new(size_t size) throw() {
+- return (address)AllocateHeap(size, mtGC, 0, AllocFailStrategy::RETURN_NULL);
++ return (address)AllocateHeap(size, mtGC, CURRENT_PC,
++ AllocFailStrategy::RETURN_NULL);
+ }
+
+ void* MemRegion::operator new [](size_t size) throw() {
+- return (address)AllocateHeap(size, mtGC, 0, AllocFailStrategy::RETURN_NULL);
++ return (address)AllocateHeap(size, mtGC, CURRENT_PC,
++ AllocFailStrategy::RETURN_NULL);
+ }
+ void MemRegion::operator delete(void* p) {
+ FreeHeap(p, mtGC);
+--- ./hotspot/src/share/vm/memory/metadataFactory.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/metadataFactory.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,6 +25,7 @@
+ #ifndef SHARE_VM_MEMORY_METADATAFACTORY_HPP
+ #define SHARE_VM_MEMORY_METADATAFACTORY_HPP
+
++#include "classfile/classLoaderData.hpp"
+ #include "utilities/array.hpp"
+ #include "utilities/exceptions.hpp"
+ #include "utilities/globalDefinitions.hpp"
+@@ -63,6 +64,12 @@
+
+ template <typename T>
+ static void free_array(ClassLoaderData* loader_data, Array<T>* data) {
++ if (DumpSharedSpaces) {
++ // FIXME: the freeing code is buggy, especially when PrintSharedSpaces is enabled.
++ // Disable for now -- this means if you specify bad classes in your classlist you
++ // may have wasted space inside the archive.
++ return;
++ }
+ if (data != NULL) {
+ assert(loader_data != NULL, "shouldn't pass null");
+ assert(!data->is_shared(), "cannot deallocate array in shared spaces");
+@@ -78,6 +85,12 @@
+ // Deallocation method for metadata
+ template <class T>
+ static void free_metadata(ClassLoaderData* loader_data, T md) {
++ if (DumpSharedSpaces) {
++ // FIXME: the freeing code is buggy, especially when PrintSharedSpaces is enabled.
++ // Disable for now -- this means if you specify bad classes in your classlist you
++ // may have wasted space inside the archive.
++ return;
++ }
+ if (md != NULL) {
+ assert(loader_data != NULL, "shouldn't pass null");
+ int size = md->size();
+--- ./hotspot/src/share/vm/memory/metaspace.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/metaspace.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -42,7 +42,7 @@
+ #include "runtime/init.hpp"
+ #include "runtime/java.hpp"
+ #include "runtime/mutex.hpp"
+-#include "runtime/orderAccess.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "services/memTracker.hpp"
+ #include "services/memoryService.hpp"
+ #include "utilities/copy.hpp"
+@@ -413,6 +413,7 @@
+ VirtualSpaceNode::VirtualSpaceNode(size_t bytes) : _top(NULL), _next(NULL), _rs(), _container_count(0) {
+ assert_is_size_aligned(bytes, Metaspace::reserve_alignment());
+
++#if INCLUDE_CDS
+ // This allocates memory with mmap. For DumpSharedspaces, try to reserve
+ // configurable address, generally at the top of the Java heap so other
+ // memory addresses don't conflict.
+@@ -428,7 +429,9 @@
+ _rs = ReservedSpace(bytes, Metaspace::reserve_alignment(), large_pages);
+ }
+ MetaspaceShared::set_shared_rs(&_rs);
+- } else {
++ } else
++#endif
++ {
+ bool large_pages = should_commit_large_pages_when_reserving(bytes);
+
+ _rs = ReservedSpace(bytes, Metaspace::reserve_alignment(), large_pages);
+@@ -1411,10 +1414,31 @@
+ return value;
+ }
+
+-size_t MetaspaceGC::inc_capacity_until_GC(size_t v) {
++bool MetaspaceGC::inc_capacity_until_GC(size_t v, size_t* new_cap_until_GC, size_t* old_cap_until_GC) {
+ assert_is_size_aligned(v, Metaspace::commit_alignment());
+
+- return (size_t)Atomic::add_ptr(v, &_capacity_until_GC);
++ size_t capacity_until_GC = (size_t) _capacity_until_GC;
++ size_t new_value = capacity_until_GC + v;
++
++ if (new_value < capacity_until_GC) {
++ // The addition wrapped around, set new_value to aligned max value.
++ new_value = align_size_down(max_uintx, Metaspace::commit_alignment());
++ }
++
++ intptr_t expected = (intptr_t) capacity_until_GC;
++ intptr_t actual = Atomic::cmpxchg_ptr((intptr_t) new_value, &_capacity_until_GC, expected);
++
++ if (expected != actual) {
++ return false;
++ }
++
++ if (new_cap_until_GC != NULL) {
++ *new_cap_until_GC = new_value;
++ }
++ if (old_cap_until_GC != NULL) {
++ *old_cap_until_GC = capacity_until_GC;
++ }
++ return true;
+ }
+
+ size_t MetaspaceGC::dec_capacity_until_GC(size_t v) {
+@@ -1514,7 +1538,10 @@
+ expand_bytes = align_size_up(expand_bytes, Metaspace::commit_alignment());
+ // Don't expand unless it's significant
+ if (expand_bytes >= MinMetaspaceExpansion) {
+- size_t new_capacity_until_GC = MetaspaceGC::inc_capacity_until_GC(expand_bytes);
++ size_t new_capacity_until_GC = 0;
++ bool succeeded = MetaspaceGC::inc_capacity_until_GC(expand_bytes, &new_capacity_until_GC);
++ assert(succeeded, "Should always succesfully increment HWM when at safepoint");
++
+ Metaspace::tracer()->report_gc_threshold(capacity_until_GC,
+ new_capacity_until_GC,
+ MetaspaceGCThresholdUpdater::ComputeNewSize);
+@@ -2937,11 +2964,14 @@
+ // between the lower base and higher address.
+ address lower_base;
+ address higher_address;
++#if INCLUDE_CDS
+ if (UseSharedSpaces) {
+ higher_address = MAX2((address)(cds_base + FileMapInfo::shared_spaces_size()),
+ (address)(metaspace_base + compressed_class_space_size()));
+ lower_base = MIN2(metaspace_base, cds_base);
+- } else {
++ } else
++#endif
++ {
+ higher_address = metaspace_base + compressed_class_space_size();
+ lower_base = metaspace_base;
+
+@@ -2962,6 +2992,7 @@
+ }
+ }
+
++#if INCLUDE_CDS
+ // Return TRUE if the specified metaspace_base and cds_base are close enough
+ // to work with compressed klass pointers.
+ bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base) {
+@@ -2972,6 +3003,7 @@
+ (address)(metaspace_base + compressed_class_space_size()));
+ return ((uint64_t)(higher_address - lower_base) <= UnscaledClassSpaceMax);
+ }
++#endif
+
+ // Try to allocate the metaspace at the requested addr.
+ void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base) {
+@@ -2991,6 +3023,7 @@
+ large_pages,
+ requested_addr, 0);
+ if (!metaspace_rs.is_reserved()) {
++#if INCLUDE_CDS
+ if (UseSharedSpaces) {
+ size_t increment = align_size_up(1*G, _reserve_alignment);
+
+@@ -3005,7 +3038,7 @@
+ _reserve_alignment, large_pages, addr, 0);
+ }
+ }
+-
++#endif
+ // If no successful allocation then try to allocate the space anywhere. If
+ // that fails then OOM doom. At this point we cannot try allocating the
+ // metaspace as if UseCompressedClassPointers is off because too much
+@@ -3024,12 +3057,13 @@
+ // If we got here then the metaspace got allocated.
+ MemTracker::record_virtual_memory_type((address)metaspace_rs.base(), mtClass);
+
++#if INCLUDE_CDS
+ // Verify that we can use shared spaces. Otherwise, turn off CDS.
+ if (UseSharedSpaces && !can_use_cds_with_metaspace_addr(metaspace_rs.base(), cds_base)) {
+ FileMapInfo::stop_sharing_and_unmap(
+ "Could not allocate metaspace at a compatible address");
+ }
+-
++#endif
+ set_narrow_klass_base_and_shift((address)metaspace_rs.base(),
+ UseSharedSpaces ? (address)cds_base : 0);
+
+@@ -3107,17 +3141,30 @@
+ MetaspaceGC::initialize();
+
+ // Initialize the alignment for shared spaces.
+- int max_alignment = os::vm_page_size();
++ int max_alignment = os::vm_allocation_granularity();
+ size_t cds_total = 0;
+
+ MetaspaceShared::set_max_alignment(max_alignment);
+
+ if (DumpSharedSpaces) {
++#if INCLUDE_CDS
++ MetaspaceShared::estimate_regions_size();
++
+ SharedReadOnlySize = align_size_up(SharedReadOnlySize, max_alignment);
+ SharedReadWriteSize = align_size_up(SharedReadWriteSize, max_alignment);
+ SharedMiscDataSize = align_size_up(SharedMiscDataSize, max_alignment);
+ SharedMiscCodeSize = align_size_up(SharedMiscCodeSize, max_alignment);
+
++ // the min_misc_code_size estimate is based on MetaspaceShared::generate_vtable_methods()
++ uintx min_misc_code_size = align_size_up(
++ (MetaspaceShared::num_virtuals * MetaspaceShared::vtbl_list_size) *
++ (sizeof(void*) + MetaspaceShared::vtbl_method_size) + MetaspaceShared::vtbl_common_code_size,
++ max_alignment);
++
++ if (SharedMiscCodeSize < min_misc_code_size) {
++ report_out_of_shared_space(SharedMiscCode);
++ }
++
+ // Initialize with the sum of the shared space sizes. The read-only
+ // and read write metaspace chunks will be allocated out of this and the
+ // remainder is the misc code and data chunks.
+@@ -3150,23 +3197,22 @@
+ }
+
+ Universe::set_narrow_klass_shift(0);
+-#endif
+-
++#endif // _LP64
++#endif // INCLUDE_CDS
+ } else {
++#if INCLUDE_CDS
+ // If using shared space, open the file that contains the shared space
+ // and map in the memory before initializing the rest of metaspace (so
+ // the addresses don't conflict)
+ address cds_address = NULL;
+ if (UseSharedSpaces) {
+ FileMapInfo* mapinfo = new FileMapInfo();
+- memset(mapinfo, 0, sizeof(FileMapInfo));
+
+ // Open the shared archive file, read and validate the header. If
+ // initialization fails, shared spaces [UseSharedSpaces] are
+ // disabled and the file is closed.
+ // Map in spaces now also
+ if (mapinfo->initialize() && MetaspaceShared::map_shared_spaces(mapinfo)) {
+- FileMapInfo::set_current_info(mapinfo);
+ cds_total = FileMapInfo::shared_spaces_size();
+ cds_address = (address)mapinfo->region_base(0);
+ } else {
+@@ -3174,21 +3220,23 @@
+ "archive file not closed or shared spaces not disabled.");
+ }
+ }
+-
++#endif // INCLUDE_CDS
+ #ifdef _LP64
+ // If UseCompressedClassPointers is set then allocate the metaspace area
+ // above the heap and above the CDS area (if it exists).
+ if (using_class_space()) {
+ if (UseSharedSpaces) {
++#if INCLUDE_CDS
+ char* cds_end = (char*)(cds_address + cds_total);
+ cds_end = (char *)align_ptr_up(cds_end, _reserve_alignment);
+ allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address);
++#endif
+ } else {
+ char* base = (char*)align_ptr_up(Universe::heap()->reserved_region().end(), _reserve_alignment);
+ allocate_metaspace_compressed_klass_ptrs(base, 0);
+ }
+ }
+-#endif
++#endif // _LP64
+
+ // Initialize these before initializing the VirtualSpaceList
+ _first_chunk_word_size = InitialBootClassLoaderMetaspaceSize / BytesPerWord;
+@@ -3305,19 +3353,29 @@
+ size_t delta_bytes = MetaspaceGC::delta_capacity_until_GC(word_size * BytesPerWord);
+ assert(delta_bytes > 0, "Must be");
+
+- size_t after_inc = MetaspaceGC::inc_capacity_until_GC(delta_bytes);
+-
+- // capacity_until_GC might be updated concurrently, must calculate previous value.
+- size_t before_inc = after_inc - delta_bytes;
+-
+- tracer()->report_gc_threshold(before_inc, after_inc,
+- MetaspaceGCThresholdUpdater::ExpandAndAllocate);
+- if (PrintGCDetails && Verbose) {
+- gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT
+- " to " SIZE_FORMAT, before_inc, after_inc);
++ size_t before = 0;
++ size_t after = 0;
++ MetaWord* res;
++ bool incremented;
++
++ // Each thread increments the HWM at most once. Even if the thread fails to increment
++ // the HWM, an allocation is still attempted. This is because another thread must then
++ // have incremented the HWM and therefore the allocation might still succeed.
++ do {
++ incremented = MetaspaceGC::inc_capacity_until_GC(delta_bytes, &after, &before);
++ res = allocate(word_size, mdtype);
++ } while (!incremented && res == NULL);
++
++ if (incremented) {
++ tracer()->report_gc_threshold(before, after,
++ MetaspaceGCThresholdUpdater::ExpandAndAllocate);
++ if (PrintGCDetails && Verbose) {
++ gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT
++ " to " SIZE_FORMAT, before, after);
++ }
+ }
+
+- return allocate(word_size, mdtype);
++ return res;
+ }
+
+ // Space allocated in the Metaspace. This may
+@@ -3366,6 +3424,10 @@
+
+ void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
+ if (SafepointSynchronize::is_at_safepoint()) {
++ if (DumpSharedSpaces && PrintSharedSpaces) {
++ record_deallocation(ptr, vsm()->get_raw_word_size(word_size));
++ }
++
+ assert(Thread::current()->is_VM_thread(), "should be the VM thread");
+ // Don't take Heap_lock
+ MutexLockerEx ml(vsm()->lock(), Mutex::_no_safepoint_check_flag);
+@@ -3420,8 +3482,9 @@
+ if (result == NULL) {
+ report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite);
+ }
+-
+- space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size));
++ if (PrintSharedSpaces) {
++ space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size));
++ }
+
+ // Zero initialize.
+ Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0);
+@@ -3520,15 +3583,55 @@
+ void Metaspace::record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size) {
+ assert(DumpSharedSpaces, "sanity");
+
+- AllocRecord *rec = new AllocRecord((address)ptr, type, (int)word_size * HeapWordSize);
++ int byte_size = (int)word_size * HeapWordSize;
++ AllocRecord *rec = new AllocRecord((address)ptr, type, byte_size);
++
+ if (_alloc_record_head == NULL) {
+ _alloc_record_head = _alloc_record_tail = rec;
+- } else {
++ } else if (_alloc_record_tail->_ptr + _alloc_record_tail->_byte_size == (address)ptr) {
+ _alloc_record_tail->_next = rec;
+ _alloc_record_tail = rec;
++ } else {
++ // slow linear search, but this doesn't happen that often, and only when dumping
++ for (AllocRecord *old = _alloc_record_head; old; old = old->_next) {
++ if (old->_ptr == ptr) {
++ assert(old->_type == MetaspaceObj::DeallocatedType, "sanity");
++ int remain_bytes = old->_byte_size - byte_size;
++ assert(remain_bytes >= 0, "sanity");
++ old->_type = type;
++
++ if (remain_bytes == 0) {
++ delete(rec);
++ } else {
++ address remain_ptr = address(ptr) + byte_size;
++ rec->_ptr = remain_ptr;
++ rec->_byte_size = remain_bytes;
++ rec->_type = MetaspaceObj::DeallocatedType;
++ rec->_next = old->_next;
++ old->_byte_size = byte_size;
++ old->_next = rec;
++ }
++ return;
++ }
++ }
++ assert(0, "reallocating a freed pointer that was not recorded");
+ }
+ }
+
++void Metaspace::record_deallocation(void* ptr, size_t word_size) {
++ assert(DumpSharedSpaces, "sanity");
++
++ for (AllocRecord *rec = _alloc_record_head; rec; rec = rec->_next) {
++ if (rec->_ptr == ptr) {
++ assert(rec->_byte_size == (int)word_size * HeapWordSize, "sanity");
++ rec->_type = MetaspaceObj::DeallocatedType;
++ return;
++ }
++ }
++
++ assert(0, "deallocating a pointer that was not recorded");
++}
++
+ void Metaspace::iterate(Metaspace::AllocRecordClosure *closure) {
+ assert(DumpSharedSpaces, "unimplemented for !DumpSharedSpaces");
+
+--- ./hotspot/src/share/vm/memory/metaspace.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/metaspace.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -171,9 +171,10 @@
+ static const MetaspaceTracer* tracer() { return _tracer; }
+
+ private:
+- // This is used by DumpSharedSpaces only, where only _vsm is used. So we will
++ // These 2 methods are used by DumpSharedSpaces only, where only _vsm is used. So we will
+ // maintain a single list for now.
+ void record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size);
++ void record_deallocation(void* ptr, size_t word_size);
+
+ #ifdef _LP64
+ static void set_narrow_klass_base_and_shift(address metaspace_base, address cds_base);
+@@ -403,7 +404,9 @@
+ static void post_initialize();
+
+ static size_t capacity_until_GC();
+- static size_t inc_capacity_until_GC(size_t v);
++ static bool inc_capacity_until_GC(size_t v,
++ size_t* new_cap_until_GC = NULL,
++ size_t* old_cap_until_GC = NULL);
+ static size_t dec_capacity_until_GC(size_t v);
+
+ static bool should_concurrent_collect() { return _should_concurrent_collect; }
+--- ./hotspot/src/share/vm/memory/metaspaceShared.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/metaspaceShared.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -24,8 +24,10 @@
+
+ #include "precompiled.hpp"
+ #include "classfile/dictionary.hpp"
++#include "classfile/classLoaderExt.hpp"
+ #include "classfile/loaderConstraints.hpp"
+ #include "classfile/placeholders.hpp"
++#include "classfile/sharedClassUtil.hpp"
+ #include "classfile/symbolTable.hpp"
+ #include "classfile/systemDictionary.hpp"
+ #include "code/codeCache.hpp"
+@@ -38,6 +40,7 @@
+ #include "runtime/signature.hpp"
+ #include "runtime/vm_operations.hpp"
+ #include "runtime/vmThread.hpp"
++#include "utilities/hashtable.hpp"
+ #include "utilities/hashtable.inline.hpp"
+
+ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+@@ -46,6 +49,10 @@
+
+ ReservedSpace* MetaspaceShared::_shared_rs = NULL;
+
++bool MetaspaceShared::_link_classes_made_progress;
++bool MetaspaceShared::_check_classes_made_progress;
++bool MetaspaceShared::_has_error_classes;
++bool MetaspaceShared::_archive_loading_failed = false;
+ // Read/write a data stream for restoring/preserving metadata pointers and
+ // miscellaneous data from/to the shared archive file.
+
+@@ -445,6 +452,23 @@
+ SystemDictionary::classes_do(collect_classes);
+
+ tty->print_cr("Number of classes %d", _global_klass_objects->length());
++ {
++ int num_type_array = 0, num_obj_array = 0, num_inst = 0;
++ for (int i = 0; i < _global_klass_objects->length(); i++) {
++ Klass* k = _global_klass_objects->at(i);
++ if (k->oop_is_instance()) {
++ num_inst ++;
++ } else if (k->oop_is_objArray()) {
++ num_obj_array ++;
++ } else {
++ assert(k->oop_is_typeArray(), "sanity");
++ num_type_array ++;
++ }
++ }
++ tty->print_cr(" instance classes = %5d", num_inst);
++ tty->print_cr(" obj array classes = %5d", num_obj_array);
++ tty->print_cr(" type array classes = %5d", num_type_array);
++ }
+
+ // Update all the fingerprints in the shared methods.
+ tty->print("Calculating fingerprints ... ");
+@@ -511,6 +535,8 @@
+ ClassLoader::copy_package_info_table(&md_top, md_end);
+ ClassLoader::verify();
+
++ ClassLoaderExt::copy_lookup_cache_to_archive(&md_top, md_end);
++
+ // Write the other data to the output array.
+ WriteClosure wc(md_top, md_end);
+ MetaspaceShared::serialize(&wc);
+@@ -611,38 +637,58 @@
+ #undef fmt_space
+ }
+
+-static void link_shared_classes(Klass* obj, TRAPS) {
++
++void MetaspaceShared::link_one_shared_class(Klass* obj, TRAPS) {
+ Klass* k = obj;
+ if (k->oop_is_instance()) {
+ InstanceKlass* ik = (InstanceKlass*) k;
+ // Link the class to cause the bytecodes to be rewritten and the
+- // cpcache to be created.
+- if (ik->init_state() < InstanceKlass::linked) {
+- ik->link_class(THREAD);
+- guarantee(!HAS_PENDING_EXCEPTION, "exception in class rewriting");
++ // cpcache to be created. Class verification is done according
++ // to -Xverify setting.
++ _link_classes_made_progress |= try_link_class(ik, THREAD);
++ guarantee(!HAS_PENDING_EXCEPTION, "exception in link_class");
++ }
++}
++
++void MetaspaceShared::check_one_shared_class(Klass* k) {
++ if (k->oop_is_instance() && InstanceKlass::cast(k)->check_sharing_error_state()) {
++ _check_classes_made_progress = true;
++ }
++}
++
++void MetaspaceShared::link_and_cleanup_shared_classes(TRAPS) {
++ // We need to iterate because verification may cause additional classes
++ // to be loaded.
++ do {
++ _link_classes_made_progress = false;
++ SystemDictionary::classes_do(link_one_shared_class, THREAD);
++ guarantee(!HAS_PENDING_EXCEPTION, "exception in link_class");
++ } while (_link_classes_made_progress);
++
++ if (_has_error_classes) {
++ // Mark all classes whose super class or interfaces failed verification.
++ do {
++ // Not completely sure if we need to do this iteratively. Anyway,
++ // we should come here only if there are unverifiable classes, which
++ // shouldn't happen in normal cases. So better safe than sorry.
++ _check_classes_made_progress = false;
++ SystemDictionary::classes_do(check_one_shared_class);
++ } while (_check_classes_made_progress);
++
++ if (IgnoreUnverifiableClassesDuringDump) {
++ // This is useful when running JCK or SQE tests. You should not
++ // enable this when running real apps.
++ SystemDictionary::remove_classes_in_error_state();
++ } else {
++ tty->print_cr("Please remove the unverifiable classes from your class list and try again");
++ exit(1);
+ }
+ }
+ }
+
+-
+-// Support for a simple checksum of the contents of the class list
+-// file to prevent trivial tampering. The algorithm matches that in
+-// the MakeClassList program used by the J2SE build process.
+-#define JSUM_SEED ((jlong)CONST64(0xcafebabebabecafe))
+-static jlong
+-jsum(jlong start, const char *buf, const int len)
+-{
+- jlong h = start;
+- char *p = (char *)buf, *e = p + len;
+- while (p < e) {
+- char c = *p++;
+- if (c <= ' ') {
+- /* Skip spaces and control characters */
+- continue;
+- }
+- h = 31 * h + c;
+- }
+- return h;
++void MetaspaceShared::prepare_for_dumping() {
++ ClassLoader::initialize_shared_path();
++ FileMapInfo::allocate_classpath_entry_table();
+ }
+
+ // Preload classes from a list, populate the shared spaces and dump to a
+@@ -651,72 +697,114 @@
+ TraceTime timer("Dump Shared Spaces", TraceStartupTime);
+ ResourceMark rm;
+
++ tty->print_cr("Allocated shared space: %d bytes at " PTR_FORMAT,
++ MetaspaceShared::shared_rs()->size(),
++ MetaspaceShared::shared_rs()->base());
++
+ // Preload classes to be shared.
+ // Should use some os:: method rather than fopen() here. aB.
+- // Construct the path to the class list (in jre/lib)
+- // Walk up two directories from the location of the VM and
+- // optionally tack on "lib" (depending on platform)
+- char class_list_path[JVM_MAXPATHLEN];
+- os::jvm_path(class_list_path, sizeof(class_list_path));
+- for (int i = 0; i < 3; i++) {
+- char *end = strrchr(class_list_path, *os::file_separator());
+- if (end != NULL) *end = '\0';
++ const char* class_list_path;
++ if (SharedClassListFile == NULL) {
++ // Construct the path to the class list (in jre/lib)
++ // Walk up two directories from the location of the VM and
++ // optionally tack on "lib" (depending on platform)
++ char class_list_path_str[JVM_MAXPATHLEN];
++ os::jvm_path(class_list_path_str, sizeof(class_list_path_str));
++ for (int i = 0; i < 3; i++) {
++ char *end = strrchr(class_list_path_str, *os::file_separator());
++ if (end != NULL) *end = '\0';
++ }
++ int class_list_path_len = (int)strlen(class_list_path_str);
++ if (class_list_path_len >= 3) {
++ if (strcmp(class_list_path_str + class_list_path_len - 3, "lib") != 0) {
++ strcat(class_list_path_str, os::file_separator());
++ strcat(class_list_path_str, "lib");
++ }
++ }
++ strcat(class_list_path_str, os::file_separator());
++ strcat(class_list_path_str, "classlist");
++ class_list_path = class_list_path_str;
++ } else {
++ class_list_path = SharedClassListFile;
+ }
+- int class_list_path_len = (int)strlen(class_list_path);
+- if (class_list_path_len >= 3) {
+- if (strcmp(class_list_path + class_list_path_len - 3, "lib") != 0) {
+- strcat(class_list_path, os::file_separator());
+- strcat(class_list_path, "lib");
+- }
++
++ int class_count = 0;
++ GrowableArray<Klass*>* class_promote_order = new GrowableArray<Klass*>();
++
++ // sun.io.Converters
++ static const char obj_array_sig[] = "[[Ljava/lang/Object;";
++ SymbolTable::new_permanent_symbol(obj_array_sig, THREAD);
++
++ // java.util.HashMap
++ static const char map_entry_array_sig[] = "[Ljava/util/Map$Entry;";
++ SymbolTable::new_permanent_symbol(map_entry_array_sig, THREAD);
++
++ tty->print_cr("Loading classes to share ...");
++ _has_error_classes = false;
++ class_count += preload_and_dump(class_list_path, class_promote_order,
++ THREAD);
++ if (ExtraSharedClassListFile) {
++ class_count += preload_and_dump(ExtraSharedClassListFile, class_promote_order,
++ THREAD);
+ }
+- strcat(class_list_path, os::file_separator());
+- strcat(class_list_path, "classlist");
++ tty->print_cr("Loading classes to share: done.");
+
++ ClassLoaderExt::init_lookup_cache(THREAD);
++
++ if (PrintSharedSpaces) {
++ tty->print_cr("Shared spaces: preloaded %d classes", class_count);
++ }
++
++ // Rewrite and link classes
++ tty->print_cr("Rewriting and linking classes ...");
++
++ // Link any classes which got missed. This would happen if we have loaded classes that
++ // were not explicitly specified in the classlist. E.g., if an interface implemented by class K
++ // fails verification, all other interfaces that were not specified in the classlist but
++ // are implemented by K are not verified.
++ link_and_cleanup_shared_classes(CATCH);
++ tty->print_cr("Rewriting and linking classes: done");
++
++ // Create and dump the shared spaces. Everything so far is loaded
++ // with the null class loader.
++ ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
++ VM_PopulateDumpSharedSpace op(loader_data, class_promote_order);
++ VMThread::execute(&op);
++
++ // Since various initialization steps have been undone by this process,
++ // it is not reasonable to continue running a java process.
++ exit(0);
++}
++
++int MetaspaceShared::preload_and_dump(const char * class_list_path,
++ GrowableArray<Klass*>* class_promote_order,
++ TRAPS) {
+ FILE* file = fopen(class_list_path, "r");
++ char class_name[256];
++ int class_count = 0;
++
+ if (file != NULL) {
+- jlong computed_jsum = JSUM_SEED;
+- jlong file_jsum = 0;
+-
+- char class_name[256];
+- int class_count = 0;
+- GrowableArray<Klass*>* class_promote_order = new GrowableArray<Klass*>();
+-
+- // sun.io.Converters
+- static const char obj_array_sig[] = "[[Ljava/lang/Object;";
+- SymbolTable::new_permanent_symbol(obj_array_sig, THREAD);
+-
+- // java.util.HashMap
+- static const char map_entry_array_sig[] = "[Ljava/util/Map$Entry;";
+- SymbolTable::new_permanent_symbol(map_entry_array_sig, THREAD);
+-
+- tty->print("Loading classes to share ... ");
+ while ((fgets(class_name, sizeof class_name, file)) != NULL) {
+- if (*class_name == '#') {
+- jint fsh, fsl;
+- if (sscanf(class_name, "# %8x%8x\n", &fsh, &fsl) == 2) {
+- file_jsum = ((jlong)(fsh) << 32) | (fsl & 0xffffffff);
+- }
+-
++ if (*class_name == '#') { // comment
+ continue;
+ }
+ // Remove trailing newline
+ size_t name_len = strlen(class_name);
+- class_name[name_len-1] = '\0';
+-
+- computed_jsum = jsum(computed_jsum, class_name, (const int)name_len - 1);
++ if (class_name[name_len-1] == '\n') {
++ class_name[name_len-1] = '\0';
++ }
+
+ // Got a class name - load it.
+ TempNewSymbol class_name_symbol = SymbolTable::new_permanent_symbol(class_name, THREAD);
+ guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol.");
+ Klass* klass = SystemDictionary::resolve_or_null(class_name_symbol,
+ THREAD);
+- guarantee(!HAS_PENDING_EXCEPTION, "Exception resolving a class.");
++ CLEAR_PENDING_EXCEPTION;
+ if (klass != NULL) {
+ if (PrintSharedSpaces && Verbose && WizardMode) {
+ tty->print_cr("Shared spaces preloaded: %s", class_name);
+ }
+
+-
+ InstanceKlass* ik = InstanceKlass::cast(klass);
+
+ // Should be class load order as per -XX:+TraceClassLoadingPreorder
+@@ -726,52 +814,15 @@
+ // cpcache to be created. The linking is done as soon as classes
+ // are loaded in order that the related data structures (klass and
+ // cpCache) are located together.
+-
+- if (ik->init_state() < InstanceKlass::linked) {
+- ik->link_class(THREAD);
+- guarantee(!(HAS_PENDING_EXCEPTION), "exception in class rewriting");
+- }
+-
+- // TODO: Resolve klasses in constant pool
+- ik->constants()->resolve_class_constants(THREAD);
++ try_link_class(ik, THREAD);
++ guarantee(!HAS_PENDING_EXCEPTION, "exception in link_class");
+
+ class_count++;
+ } else {
+- if (PrintSharedSpaces && Verbose && WizardMode) {
+- tty->cr();
+- tty->print_cr(" Preload failed: %s", class_name);
+- }
++ //tty->print_cr("Preload failed: %s", class_name);
+ }
+- file_jsum = 0; // Checksum must be on last line of file
+ }
+- if (computed_jsum != file_jsum) {
+- tty->cr();
+- tty->print_cr("Preload failed: checksum of class list was incorrect.");
+- exit(1);
+- }
+-
+- tty->print_cr("done. ");
+-
+- if (PrintSharedSpaces) {
+- tty->print_cr("Shared spaces: preloaded %d classes", class_count);
+- }
+-
+- // Rewrite and unlink classes.
+- tty->print("Rewriting and linking classes ... ");
+-
+- // Link any classes which got missed. (It's not quite clear why
+- // they got missed.) This iteration would be unsafe if we weren't
+- // single-threaded at this point; however we can't do it on the VM
+- // thread because it requires object allocation.
+- SystemDictionary::classes_do(link_shared_classes, CATCH);
+- tty->print_cr("done. ");
+-
+- // Create and dump the shared spaces. Everything so far is loaded
+- // with the null class loader.
+- ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
+- VM_PopulateDumpSharedSpace op(loader_data, class_promote_order);
+- VMThread::execute(&op);
+-
++ fclose(file);
+ } else {
+ char errmsg[JVM_MAXPATHLEN];
+ os::lasterror(errmsg, JVM_MAXPATHLEN);
+@@ -779,11 +830,39 @@
+ exit(1);
+ }
+
+- // Since various initialization steps have been undone by this process,
+- // it is not reasonable to continue running a java process.
+- exit(0);
++ return class_count;
+ }
+
++// Returns true if the class's status has changed
++bool MetaspaceShared::try_link_class(InstanceKlass* ik, TRAPS) {
++ assert(DumpSharedSpaces, "should only be called during dumping");
++ if (ik->init_state() < InstanceKlass::linked) {
++ bool saved = BytecodeVerificationLocal;
++ if (!SharedClassUtil::is_shared_boot_class(ik)) {
++ // The verification decision is based on BytecodeVerificationRemote
++ // for non-system classes. Since we are using the NULL classloader
++ // to load non-system classes during dumping, we need to temporarily
++ // change BytecodeVerificationLocal to be the same as
++ // BytecodeVerificationRemote. Note this can cause the parent system
++ // classes also being verified. The extra overhead is acceptable during
++ // dumping.
++ BytecodeVerificationLocal = BytecodeVerificationRemote;
++ }
++ ik->link_class(THREAD);
++ if (HAS_PENDING_EXCEPTION) {
++ ResourceMark rm;
++ tty->print_cr("Preload Warning: Verification failed for %s",
++ ik->external_name());
++ CLEAR_PENDING_EXCEPTION;
++ ik->set_in_error_state();
++ _has_error_classes = true;
++ }
++ BytecodeVerificationLocal = saved;
++ return true;
++ } else {
++ return false;
++ }
++}
+
+ // Closure for serializing initialization data in from a data area
+ // (ptr_array) read from the shared file.
+@@ -871,7 +950,8 @@
+ mapinfo->verify_region_checksum(md) &&
+ (_mc_base = mapinfo->map_region(mc)) != NULL &&
+ mapinfo->verify_region_checksum(mc) &&
+- (image_alignment == (size_t)max_alignment())) {
++ (image_alignment == (size_t)max_alignment()) &&
++ mapinfo->validate_classpath_entry_table()) {
+ // Success (no need to do anything)
+ return true;
+ } else {
+@@ -887,8 +967,8 @@
+ #endif
+ // If -Xshare:on is specified, print out the error message and exit VM,
+ // otherwise, set UseSharedSpaces to false and continue.
+- if (RequireSharedSpaces) {
+- vm_exit_during_initialization("Unable to use shared archive.", NULL);
++ if (RequireSharedSpaces || PrintSharedArchiveAndExit) {
++ vm_exit_during_initialization("Unable to use shared archive.", "Failed map_region for using -Xshare:on.");
+ } else {
+ FLAG_SET_DEFAULT(UseSharedSpaces, false);
+ }
+@@ -982,12 +1062,28 @@
+ buffer += sizeof(intptr_t);
+ buffer += len;
+
++ buffer = ClassLoaderExt::restore_lookup_cache_from_archive(buffer);
++
+ intptr_t* array = (intptr_t*)buffer;
+ ReadClosure rc(&array);
+ serialize(&rc);
+
+ // Close the mapinfo file
+ mapinfo->close();
++
++ if (PrintSharedArchiveAndExit) {
++ if (PrintSharedDictionary) {
++ tty->print_cr("\nShared classes:\n");
++ SystemDictionary::print_shared(false);
++ }
++ if (_archive_loading_failed) {
++ tty->print_cr("archive is invalid");
++ vm_exit(1);
++ } else {
++ tty->print_cr("archive is valid");
++ vm_exit(0);
++ }
++ }
+ }
+
+ // JVM/TI RedefineClasses() support:
+@@ -1003,3 +1099,49 @@
+ }
+ return true;
+ }
++
++int MetaspaceShared::count_class(const char* classlist_file) {
++ if (classlist_file == NULL) {
++ return 0;
++ }
++ char class_name[256];
++ int class_count = 0;
++ FILE* file = fopen(classlist_file, "r");
++ if (file != NULL) {
++ while ((fgets(class_name, sizeof class_name, file)) != NULL) {
++ if (*class_name == '#') { // comment
++ continue;
++ }
++ class_count++;
++ }
++ fclose(file);
++ } else {
++ char errmsg[JVM_MAXPATHLEN];
++ os::lasterror(errmsg, JVM_MAXPATHLEN);
++ tty->print_cr("Loading classlist failed: %s", errmsg);
++ exit(1);
++ }
++
++ return class_count;
++}
++
++// the sizes are good for typical large applications that have a lot of shared
++// classes
++void MetaspaceShared::estimate_regions_size() {
++ int class_count = count_class(SharedClassListFile);
++ class_count += count_class(ExtraSharedClassListFile);
++
++ if (class_count > LargeThresholdClassCount) {
++ if (class_count < HugeThresholdClassCount) {
++ SET_ESTIMATED_SIZE(Large, ReadOnly);
++ SET_ESTIMATED_SIZE(Large, ReadWrite);
++ SET_ESTIMATED_SIZE(Large, MiscData);
++ SET_ESTIMATED_SIZE(Large, MiscCode);
++ } else {
++ SET_ESTIMATED_SIZE(Huge, ReadOnly);
++ SET_ESTIMATED_SIZE(Huge, ReadWrite);
++ SET_ESTIMATED_SIZE(Huge, MiscData);
++ SET_ESTIMATED_SIZE(Huge, MiscCode);
++ }
++ }
++}
+--- ./hotspot/src/share/vm/memory/metaspaceShared.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/metaspaceShared.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -30,6 +30,19 @@
+ #include "utilities/exceptions.hpp"
+ #include "utilities/macros.hpp"
+
++#define LargeSharedArchiveSize (300*M)
++#define HugeSharedArchiveSize (800*M)
++#define ReadOnlyRegionPercentage 0.39
++#define ReadWriteRegionPercentage 0.50
++#define MiscDataRegionPercentage 0.09
++#define MiscCodeRegionPercentage 0.02
++#define LargeThresholdClassCount 5000
++#define HugeThresholdClassCount 40000
++
++#define SET_ESTIMATED_SIZE(type, region) \
++ Shared ##region## Size = FLAG_IS_DEFAULT(Shared ##region## Size) ? \
++ (uintx)(type ## SharedArchiveSize * region ## RegionPercentage) : Shared ## region ## Size
++
+ class FileMapInfo;
+
+ // Class Data Sharing Support
+@@ -38,14 +51,22 @@
+ // CDS support
+ static ReservedSpace* _shared_rs;
+ static int _max_alignment;
+-
++ static bool _link_classes_made_progress;
++ static bool _check_classes_made_progress;
++ static bool _has_error_classes;
++ static bool _archive_loading_failed;
+ public:
+ enum {
+- vtbl_list_size = 17, // number of entries in the shared space vtable list.
+- num_virtuals = 200 // maximum number of virtual functions
+- // If virtual functions are added to Metadata,
+- // this number needs to be increased. Also,
+- // SharedMiscCodeSize will need to be increased.
++ vtbl_list_size = 17, // number of entries in the shared space vtable list.
++ num_virtuals = 200, // maximum number of virtual functions
++ // If virtual functions are added to Metadata,
++ // this number needs to be increased. Also,
++ // SharedMiscCodeSize will need to be increased.
++ // The following 2 sizes were based on
++ // MetaspaceShared::generate_vtable_methods()
++ vtbl_method_size = 16, // conservative size of the mov1 and jmp instructions
++ // for the x64 platform
++ vtbl_common_code_size = (1*K) // conservative size of the "common_code" for the x64 platform
+ };
+
+ enum {
+@@ -67,7 +88,11 @@
+ NOT_CDS(return 0);
+ }
+
++ static void prepare_for_dumping() NOT_CDS_RETURN;
+ static void preload_and_dump(TRAPS) NOT_CDS_RETURN;
++ static int preload_and_dump(const char * class_list_path,
++ GrowableArray<Klass*>* class_promote_order,
++ TRAPS) NOT_CDS_RETURN;
+
+ static ReservedSpace* shared_rs() {
+ CDS_ONLY(return _shared_rs);
+@@ -78,6 +103,9 @@
+ CDS_ONLY(_shared_rs = rs;)
+ }
+
++ static void set_archive_loading_failed() {
++ _archive_loading_failed = true;
++ }
+ static bool map_shared_spaces(FileMapInfo* mapinfo) NOT_CDS_RETURN_(false);
+ static void initialize_shared_spaces() NOT_CDS_RETURN;
+
+@@ -97,5 +125,13 @@
+ static bool remap_shared_readonly_as_readwrite() NOT_CDS_RETURN_(true);
+
+ static void print_shared_spaces();
++
++ static bool try_link_class(InstanceKlass* ik, TRAPS);
++ static void link_one_shared_class(Klass* obj, TRAPS);
++ static void check_one_shared_class(Klass* obj);
++ static void link_and_cleanup_shared_classes(TRAPS);
++
++ static int count_class(const char* classlist_file);
++ static void estimate_regions_size() NOT_CDS_RETURN;
+ };
+ #endif // SHARE_VM_MEMORY_METASPACE_SHARED_HPP
+--- ./hotspot/src/share/vm/memory/referenceProcessor.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/referenceProcessor.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -191,7 +191,8 @@
+ OopClosure* keep_alive,
+ VoidClosure* complete_gc,
+ AbstractRefProcTaskExecutor* task_executor,
+- GCTimer* gc_timer) {
++ GCTimer* gc_timer,
++ GCId gc_id) {
+ NOT_PRODUCT(verify_ok_to_handle_reflists());
+
+ assert(!enqueuing_is_done(), "If here enqueuing should not be complete");
+@@ -213,7 +214,7 @@
+ // Soft references
+ size_t soft_count = 0;
+ {
+- GCTraceTime tt("SoftReference", trace_time, false, gc_timer);
++ GCTraceTime tt("SoftReference", trace_time, false, gc_timer, gc_id);
+ soft_count =
+ process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
+ is_alive, keep_alive, complete_gc, task_executor);
+@@ -224,7 +225,7 @@
+ // Weak references
+ size_t weak_count = 0;
+ {
+- GCTraceTime tt("WeakReference", trace_time, false, gc_timer);
++ GCTraceTime tt("WeakReference", trace_time, false, gc_timer, gc_id);
+ weak_count =
+ process_discovered_reflist(_discoveredWeakRefs, NULL, true,
+ is_alive, keep_alive, complete_gc, task_executor);
+@@ -233,7 +234,7 @@
+ // Final references
+ size_t final_count = 0;
+ {
+- GCTraceTime tt("FinalReference", trace_time, false, gc_timer);
++ GCTraceTime tt("FinalReference", trace_time, false, gc_timer, gc_id);
+ final_count =
+ process_discovered_reflist(_discoveredFinalRefs, NULL, false,
+ is_alive, keep_alive, complete_gc, task_executor);
+@@ -242,7 +243,7 @@
+ // Phantom references
+ size_t phantom_count = 0;
+ {
+- GCTraceTime tt("PhantomReference", trace_time, false, gc_timer);
++ GCTraceTime tt("PhantomReference", trace_time, false, gc_timer, gc_id);
+ phantom_count =
+ process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
+ is_alive, keep_alive, complete_gc, task_executor);
+@@ -261,7 +262,7 @@
+ // thus use JNI weak references to circumvent the phantom references and
+ // resurrect a "post-mortem" object.
+ {
+- GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer);
++ GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer, gc_id);
+ if (task_executor != NULL) {
+ task_executor->set_single_threaded_mode();
+ }
+@@ -1263,14 +1264,15 @@
+ OopClosure* keep_alive,
+ VoidClosure* complete_gc,
+ YieldClosure* yield,
+- GCTimer* gc_timer) {
++ GCTimer* gc_timer,
++ GCId gc_id) {
+
+ NOT_PRODUCT(verify_ok_to_handle_reflists());
+
+ // Soft references
+ {
+ GCTraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
+- false, gc_timer);
++ false, gc_timer, gc_id);
+ for (uint i = 0; i < _max_num_q; i++) {
+ if (yield->should_return()) {
+ return;
+@@ -1283,7 +1285,7 @@
+ // Weak references
+ {
+ GCTraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
+- false, gc_timer);
++ false, gc_timer, gc_id);
+ for (uint i = 0; i < _max_num_q; i++) {
+ if (yield->should_return()) {
+ return;
+@@ -1296,7 +1298,7 @@
+ // Final references
+ {
+ GCTraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
+- false, gc_timer);
++ false, gc_timer, gc_id);
+ for (uint i = 0; i < _max_num_q; i++) {
+ if (yield->should_return()) {
+ return;
+@@ -1309,7 +1311,7 @@
+ // Phantom references
+ {
+ GCTraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
+- false, gc_timer);
++ false, gc_timer, gc_id);
+ for (uint i = 0; i < _max_num_q; i++) {
+ if (yield->should_return()) {
+ return;
+--- ./hotspot/src/share/vm/memory/referenceProcessor.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/referenceProcessor.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,6 +25,7 @@
+ #ifndef SHARE_VM_MEMORY_REFERENCEPROCESSOR_HPP
+ #define SHARE_VM_MEMORY_REFERENCEPROCESSOR_HPP
+
++#include "gc_implementation/shared/gcTrace.hpp"
+ #include "memory/referencePolicy.hpp"
+ #include "memory/referenceProcessorStats.hpp"
+ #include "memory/referenceType.hpp"
+@@ -350,7 +351,8 @@
+ OopClosure* keep_alive,
+ VoidClosure* complete_gc,
+ YieldClosure* yield,
+- GCTimer* gc_timer);
++ GCTimer* gc_timer,
++ GCId gc_id);
+
+ // Delete entries in the discovered lists that have
+ // either a null referent or are not active. Such
+@@ -481,7 +483,8 @@
+ OopClosure* keep_alive,
+ VoidClosure* complete_gc,
+ AbstractRefProcTaskExecutor* task_executor,
+- GCTimer *gc_timer);
++ GCTimer *gc_timer,
++ GCId gc_id);
+
+ // Enqueue references at end of GC (called by the garbage collector)
+ bool enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor = NULL);
+--- ./hotspot/src/share/vm/memory/resourceArea.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/resourceArea.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -49,11 +49,11 @@
+ debug_only(static int _warned;) // to suppress multiple warnings
+
+ public:
+- ResourceArea() {
++ ResourceArea() : Arena(mtThread) {
+ debug_only(_nesting = 0;)
+ }
+
+- ResourceArea(size_t init_size) : Arena(init_size) {
++ ResourceArea(size_t init_size) : Arena(mtThread, init_size) {
+ debug_only(_nesting = 0;);
+ }
+
+@@ -64,7 +64,7 @@
+ if (UseMallocOnly) {
+ // use malloc, but save pointer in res. area for later freeing
+ char** save = (char**)internal_malloc_4(sizeof(char*));
+- return (*save = (char*)os::malloc(size, mtThread));
++ return (*save = (char*)os::malloc(size, mtThread, CURRENT_PC));
+ }
+ #endif
+ return (char*)Amalloc(size, alloc_failmode);
+--- ./hotspot/src/share/vm/memory/sharedHeap.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/sharedHeap.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -29,6 +29,7 @@
+ #include "gc_interface/collectedHeap.inline.hpp"
+ #include "memory/sharedHeap.hpp"
+ #include "oops/oop.inline.hpp"
++#include "runtime/atomic.inline.hpp"
+ #include "runtime/fprofiler.hpp"
+ #include "runtime/java.hpp"
+ #include "services/management.hpp"
+@@ -39,8 +40,8 @@
+
+ SharedHeap* SharedHeap::_sh;
+
+-// The set of potentially parallel tasks in strong root scanning.
+-enum SH_process_strong_roots_tasks {
++// The set of potentially parallel tasks in root scanning.
++enum SH_process_roots_tasks {
+ SH_PS_Universe_oops_do,
+ SH_PS_JNIHandles_oops_do,
+ SH_PS_ObjectSynchronizer_oops_do,
+@@ -58,6 +59,7 @@
+ CollectedHeap(),
+ _collector_policy(policy_),
+ _rem_set(NULL),
++ _strong_roots_scope(NULL),
+ _strong_roots_parity(0),
+ _process_strong_tasks(new SubTasksDone(SH_PS_NumElements)),
+ _workers(NULL)
+@@ -114,6 +116,19 @@
+ static AssertNonScavengableClosure assert_is_non_scavengable_closure;
+ #endif
+
++SharedHeap::StrongRootsScope* SharedHeap::active_strong_roots_scope() const {
++ return _strong_roots_scope;
++}
++void SharedHeap::register_strong_roots_scope(SharedHeap::StrongRootsScope* scope) {
++ assert(_strong_roots_scope == NULL, "Should only have one StrongRootsScope active");
++ assert(scope != NULL, "Illegal argument");
++ _strong_roots_scope = scope;
++}
++void SharedHeap::unregister_strong_roots_scope(SharedHeap::StrongRootsScope* scope) {
++ assert(_strong_roots_scope == scope, "Wrong scope unregistered");
++ _strong_roots_scope = NULL;
++}
++
+ void SharedHeap::change_strong_roots_parity() {
+ // Also set the new collection parity.
+ assert(_strong_roots_parity >= 0 && _strong_roots_parity <= 2,
+@@ -124,122 +139,173 @@
+ "Not in range.");
+ }
+
+-SharedHeap::StrongRootsScope::StrongRootsScope(SharedHeap* outer, bool activate)
+- : MarkScope(activate)
++SharedHeap::StrongRootsScope::StrongRootsScope(SharedHeap* heap, bool activate)
++ : MarkScope(activate), _sh(heap), _n_workers_done_with_threads(0)
+ {
+ if (_active) {
+- outer->change_strong_roots_parity();
++ _sh->register_strong_roots_scope(this);
++ _sh->change_strong_roots_parity();
+ // Zero the claimed high water mark in the StringTable
+ StringTable::clear_parallel_claimed_index();
+ }
+ }
+
+ SharedHeap::StrongRootsScope::~StrongRootsScope() {
+- // nothing particular
++ if (_active) {
++ _sh->unregister_strong_roots_scope(this);
++ }
+ }
+
+-void SharedHeap::process_strong_roots(bool activate_scope,
+- bool is_scavenging,
+- ScanningOption so,
+- OopClosure* roots,
+- CodeBlobClosure* code_roots,
+- KlassClosure* klass_closure) {
++Monitor* SharedHeap::StrongRootsScope::_lock = new Monitor(Mutex::leaf, "StrongRootsScope lock", false);
++
++void SharedHeap::StrongRootsScope::mark_worker_done_with_threads(uint n_workers) {
++ // The Thread work barrier is only needed by G1 Class Unloading.
++ // No need to use the barrier if this is single-threaded code.
++ if (UseG1GC && ClassUnloadingWithConcurrentMark && n_workers > 0) {
++ uint new_value = (uint)Atomic::add(1, &_n_workers_done_with_threads);
++ if (new_value == n_workers) {
++ // This thread is last. Notify the others.
++ MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag);
++ _lock->notify_all();
++ }
++ }
++}
++
++void SharedHeap::StrongRootsScope::wait_until_all_workers_done_with_threads(uint n_workers) {
++ assert(UseG1GC, "Currently only used by G1");
++ assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
++
++ // No need to use the barrier if this is single-threaded code.
++ if (n_workers > 0 && (uint)_n_workers_done_with_threads != n_workers) {
++ MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag);
++ while ((uint)_n_workers_done_with_threads != n_workers) {
++ _lock->wait(Mutex::_no_safepoint_check_flag, 0, false);
++ }
++ }
++}
++
++void SharedHeap::process_roots(bool activate_scope,
++ ScanningOption so,
++ OopClosure* strong_roots,
++ OopClosure* weak_roots,
++ CLDClosure* strong_cld_closure,
++ CLDClosure* weak_cld_closure,
++ CodeBlobClosure* code_roots) {
+ StrongRootsScope srs(this, activate_scope);
+
+- // General strong roots.
++ // General roots.
+ assert(_strong_roots_parity != 0, "must have called prologue code");
++ assert(code_roots != NULL, "code root closure should always be set");
+ // _n_termination for _process_strong_tasks should be set up stream
+ // in a method not running in a GC worker. Otherwise the GC worker
+ // could be trying to change the termination condition while the task
+ // is executing in another GC worker.
++
++ // Iterating over the CLDG and the Threads are done early to allow G1 to
++ // first process the strong CLDs and nmethods and then, after a barrier,
++ // let the thread process the weak CLDs and nmethods.
++
++ if (!_process_strong_tasks->is_task_claimed(SH_PS_ClassLoaderDataGraph_oops_do)) {
++ ClassLoaderDataGraph::roots_cld_do(strong_cld_closure, weak_cld_closure);
++ }
++
++ // Some CLDs contained in the thread frames should be considered strong.
++ // Don't process them if they will be processed during the ClassLoaderDataGraph phase.
++ CLDClosure* roots_from_clds_p = (strong_cld_closure != weak_cld_closure) ? strong_cld_closure : NULL;
++ // Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway
++ CodeBlobClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots;
++
++ Threads::possibly_parallel_oops_do(strong_roots, roots_from_clds_p, roots_from_code_p);
++
++ // This is the point where this worker thread will not find more strong CLDs/nmethods.
++ // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing.
++ active_strong_roots_scope()->mark_worker_done_with_threads(n_par_threads());
++
+ if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) {
+- Universe::oops_do(roots);
++ Universe::oops_do(strong_roots);
+ }
+ // Global (strong) JNI handles
+ if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do))
+- JNIHandles::oops_do(roots);
+-
+- // All threads execute this; the individual threads are task groups.
+- CLDToOopClosure roots_from_clds(roots);
+- CLDToOopClosure* roots_from_clds_p = (is_scavenging ? NULL : &roots_from_clds);
+- if (CollectedHeap::use_parallel_gc_threads()) {
+- Threads::possibly_parallel_oops_do(roots, roots_from_clds_p, code_roots);
+- } else {
+- Threads::oops_do(roots, roots_from_clds_p, code_roots);
+- }
++ JNIHandles::oops_do(strong_roots);
+
+ if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do))
+- ObjectSynchronizer::oops_do(roots);
++ ObjectSynchronizer::oops_do(strong_roots);
+ if (!_process_strong_tasks->is_task_claimed(SH_PS_FlatProfiler_oops_do))
+- FlatProfiler::oops_do(roots);
++ FlatProfiler::oops_do(strong_roots);
+ if (!_process_strong_tasks->is_task_claimed(SH_PS_Management_oops_do))
+- Management::oops_do(roots);
++ Management::oops_do(strong_roots);
+ if (!_process_strong_tasks->is_task_claimed(SH_PS_jvmti_oops_do))
+- JvmtiExport::oops_do(roots);
++ JvmtiExport::oops_do(strong_roots);
+
+ if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) {
+- if (so & SO_AllClasses) {
+- SystemDictionary::oops_do(roots);
+- } else if (so & SO_SystemClasses) {
+- SystemDictionary::always_strong_oops_do(roots);
+- } else {
+- fatal("We should always have selected either SO_AllClasses or SO_SystemClasses");
+- }
+- }
+-
+- if (!_process_strong_tasks->is_task_claimed(SH_PS_ClassLoaderDataGraph_oops_do)) {
+- if (so & SO_AllClasses) {
+- ClassLoaderDataGraph::oops_do(roots, klass_closure, !is_scavenging);
+- } else if (so & SO_SystemClasses) {
+- ClassLoaderDataGraph::always_strong_oops_do(roots, klass_closure, !is_scavenging);
+- }
++ SystemDictionary::roots_oops_do(strong_roots, weak_roots);
+ }
+
+ // All threads execute the following. A specific chunk of buckets
+ // from the StringTable are the individual tasks.
+- if (so & SO_Strings) {
++ if (weak_roots != NULL) {
+ if (CollectedHeap::use_parallel_gc_threads()) {
+- StringTable::possibly_parallel_oops_do(roots);
++ StringTable::possibly_parallel_oops_do(weak_roots);
+ } else {
+- StringTable::oops_do(roots);
++ StringTable::oops_do(weak_roots);
+ }
+ }
+
+ if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) {
+- if (so & SO_CodeCache) {
++ if (so & SO_ScavengeCodeCache) {
+ assert(code_roots != NULL, "must supply closure for code cache");
+
+- if (is_scavenging) {
+- // We only visit parts of the CodeCache when scavenging.
+- CodeCache::scavenge_root_nmethods_do(code_roots);
+- } else {
+- // CMSCollector uses this to do intermediate-strength collections.
+- // We scan the entire code cache, since CodeCache::do_unloading is not called.
+- CodeCache::blobs_do(code_roots);
+- }
++ // We only visit parts of the CodeCache when scavenging.
++ CodeCache::scavenge_root_nmethods_do(code_roots);
++ }
++ if (so & SO_AllCodeCache) {
++ assert(code_roots != NULL, "must supply closure for code cache");
++
++ // CMSCollector uses this to do intermediate-strength collections.
++ // We scan the entire code cache, since CodeCache::do_unloading is not called.
++ CodeCache::blobs_do(code_roots);
+ }
+ // Verify that the code cache contents are not subject to
+ // movement by a scavenging collection.
+- DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, /*do_marking=*/ false));
++ DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, !CodeBlobToOopClosure::FixRelocations));
+ DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable));
+ }
+
+ _process_strong_tasks->all_tasks_completed();
+ }
+
++void SharedHeap::process_all_roots(bool activate_scope,
++ ScanningOption so,
++ OopClosure* roots,
++ CLDClosure* cld_closure,
++ CodeBlobClosure* code_closure) {
++ process_roots(activate_scope, so,
++ roots, roots,
++ cld_closure, cld_closure,
++ code_closure);
++}
++
++void SharedHeap::process_strong_roots(bool activate_scope,
++ ScanningOption so,
++ OopClosure* roots,
++ CLDClosure* cld_closure,
++ CodeBlobClosure* code_closure) {
++ process_roots(activate_scope, so,
++ roots, NULL,
++ cld_closure, NULL,
++ code_closure);
++}
++
++
+ class AlwaysTrueClosure: public BoolObjectClosure {
+ public:
+ bool do_object_b(oop p) { return true; }
+ };
+ static AlwaysTrueClosure always_true;
+
+-void SharedHeap::process_weak_roots(OopClosure* root_closure,
+- CodeBlobClosure* code_roots) {
++void SharedHeap::process_weak_roots(OopClosure* root_closure) {
+ // Global (weak) JNI handles
+ JNIHandles::weak_oops_do(&always_true, root_closure);
+-
+- CodeCache::blobs_do(code_roots);
+- StringTable::oops_do(root_closure);
+ }
+
+ void SharedHeap::set_barrier_set(BarrierSet* bs) {
+--- ./hotspot/src/share/vm/memory/sharedHeap.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/sharedHeap.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -69,14 +69,10 @@
+ // number of active GC workers. CompactibleFreeListSpace and Space
+ // have SequentialSubTasksDone's.
+ // Example of using SubTasksDone and SequentialSubTasksDone
+-// G1CollectedHeap::g1_process_strong_roots() calls
+-// process_strong_roots(false, // no scoping; this is parallel code
+-// is_scavenging, so,
+-// &buf_scan_non_heap_roots,
+-// &eager_scan_code_roots);
+-// which delegates to SharedHeap::process_strong_roots() and uses
++// G1CollectedHeap::g1_process_roots()
++// to SharedHeap::process_roots() and uses
+ // SubTasksDone* _process_strong_tasks to claim tasks.
+-// process_strong_roots() calls
++// process_roots() calls
+ // rem_set()->younger_refs_iterate()
+ // to scan the card table and which eventually calls down into
+ // CardTableModRefBS::par_non_clean_card_iterate_work(). This method
+@@ -163,9 +159,6 @@
+ // Iteration functions.
+ void oop_iterate(ExtendedOopClosure* cl) = 0;
+
+- // Same as above, restricted to a memory region.
+- virtual void oop_iterate(MemRegion mr, ExtendedOopClosure* cl) = 0;
+-
+ // Iterate over all spaces in use in the heap, in an undefined order.
+ virtual void space_iterate(SpaceClosure* cl) = 0;
+
+@@ -185,12 +178,12 @@
+ // task. (This also means that a parallel thread may only call
+ // process_strong_roots once.)
+ //
+- // For calls to process_strong_roots by sequential code, the parity is
++ // For calls to process_roots by sequential code, the parity is
+ // updated automatically.
+ //
+ // The idea is that objects representing fine-grained tasks, such as
+ // threads, will contain a "parity" field. A task will is claimed in the
+- // current "process_strong_roots" call only if its parity field is the
++ // current "process_roots" call only if its parity field is the
+ // same as the "strong_roots_parity"; task claiming is accomplished by
+ // updating the parity field to the strong_roots_parity with a CAS.
+ //
+@@ -201,27 +194,45 @@
+ // c) to never return a distinguished value (zero) with which such
+ // task-claiming variables may be initialized, to indicate "never
+ // claimed".
+- private:
+- void change_strong_roots_parity();
+ public:
+ int strong_roots_parity() { return _strong_roots_parity; }
+
+- // Call these in sequential code around process_strong_roots.
++ // Call these in sequential code around process_roots.
+ // strong_roots_prologue calls change_strong_roots_parity, if
+ // parallel tasks are enabled.
+ class StrongRootsScope : public MarkingCodeBlobClosure::MarkScope {
+- public:
+- StrongRootsScope(SharedHeap* outer, bool activate = true);
++ // Used to implement the Thread work barrier.
++ static Monitor* _lock;
++
++ SharedHeap* _sh;
++ volatile jint _n_workers_done_with_threads;
++
++ public:
++ StrongRootsScope(SharedHeap* heap, bool activate = true);
+ ~StrongRootsScope();
++
++ // Mark that this thread is done with the Threads work.
++ void mark_worker_done_with_threads(uint n_workers);
++ // Wait until all n_workers are done with the Threads work.
++ void wait_until_all_workers_done_with_threads(uint n_workers);
+ };
+ friend class StrongRootsScope;
+
++ // The current active StrongRootScope
++ StrongRootsScope* _strong_roots_scope;
++
++ StrongRootsScope* active_strong_roots_scope() const;
++
++ private:
++ void register_strong_roots_scope(StrongRootsScope* scope);
++ void unregister_strong_roots_scope(StrongRootsScope* scope);
++ void change_strong_roots_parity();
++
++ public:
+ enum ScanningOption {
+- SO_None = 0x0,
+- SO_AllClasses = 0x1,
+- SO_SystemClasses = 0x2,
+- SO_Strings = 0x4,
+- SO_CodeCache = 0x8
++ SO_None = 0x0,
++ SO_AllCodeCache = 0x8,
++ SO_ScavengeCodeCache = 0x10
+ };
+
+ FlexibleWorkGang* workers() const { return _workers; }
+@@ -229,22 +240,29 @@
+ // Invoke the "do_oop" method the closure "roots" on all root locations.
+ // The "so" argument determines which roots the closure is applied to:
+ // "SO_None" does none;
+- // "SO_AllClasses" applies the closure to all entries in the SystemDictionary;
+- // "SO_SystemClasses" to all the "system" classes and loaders;
+- // "SO_Strings" applies the closure to all entries in StringTable;
+- // "SO_CodeCache" applies the closure to all elements of the CodeCache.
++ // "SO_AllCodeCache" applies the closure to all elements of the CodeCache.
++ // "SO_ScavengeCodeCache" applies the closure to elements on the scavenge root list in the CodeCache.
++ void process_roots(bool activate_scope,
++ ScanningOption so,
++ OopClosure* strong_roots,
++ OopClosure* weak_roots,
++ CLDClosure* strong_cld_closure,
++ CLDClosure* weak_cld_closure,
++ CodeBlobClosure* code_roots);
++ void process_all_roots(bool activate_scope,
++ ScanningOption so,
++ OopClosure* roots,
++ CLDClosure* cld_closure,
++ CodeBlobClosure* code_roots);
+ void process_strong_roots(bool activate_scope,
+- bool is_scavenging,
+ ScanningOption so,
+ OopClosure* roots,
+- CodeBlobClosure* code_roots,
+- KlassClosure* klass_closure);
++ CLDClosure* cld_closure,
++ CodeBlobClosure* code_roots);
+
+- // Apply "blk" to all the weak roots of the system. These include
+- // JNI weak roots, the code cache, system dictionary, symbol table,
+- // string table.
+- void process_weak_roots(OopClosure* root_closure,
+- CodeBlobClosure* code_roots);
++
++ // Apply "root_closure" to the JNI weak roots..
++ void process_weak_roots(OopClosure* root_closure);
+
+ // The functions below are helper functions that a subclass of
+ // "SharedHeap" can use in the implementation of its virtual
+@@ -257,7 +275,7 @@
+ virtual void gc_epilogue(bool full) = 0;
+
+ // Sets the number of parallel threads that will be doing tasks
+- // (such as process strong roots) subsequently.
++ // (such as process roots) subsequently.
+ virtual void set_par_threads(uint t);
+
+ int n_termination();
+@@ -274,4 +292,8 @@
+ size_t capacity);
+ };
+
++inline SharedHeap::ScanningOption operator|(SharedHeap::ScanningOption so0, SharedHeap::ScanningOption so1) {
++ return static_cast<SharedHeap::ScanningOption>(static_cast<int>(so0) | static_cast<int>(so1));
++}
++
+ #endif // SHARE_VM_MEMORY_SHAREDHEAP_HPP
+--- ./hotspot/src/share/vm/memory/space.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/space.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,6 +28,7 @@
+ #include "gc_implementation/shared/liveRange.hpp"
+ #include "gc_implementation/shared/markSweep.hpp"
+ #include "gc_implementation/shared/spaceDecorator.hpp"
++#include "gc_interface/collectedHeap.inline.hpp"
+ #include "memory/blockOffsetTable.inline.hpp"
+ #include "memory/defNewGeneration.hpp"
+ #include "memory/genCollectedHeap.hpp"
+@@ -37,14 +38,13 @@
+ #include "oops/oop.inline.hpp"
+ #include "oops/oop.inline2.hpp"
+ #include "runtime/java.hpp"
++#include "runtime/prefetch.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/safepoint.hpp"
+ #include "utilities/copy.hpp"
+ #include "utilities/globalDefinitions.hpp"
+ #include "utilities/macros.hpp"
+
+-void SpaceMemRegionOopsIterClosure::do_oop(oop* p) { SpaceMemRegionOopsIterClosure::do_oop_work(p); }
+-void SpaceMemRegionOopsIterClosure::do_oop(narrowOop* p) { SpaceMemRegionOopsIterClosure::do_oop_work(p); }
+-
+ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+
+ HeapWord* DirtyCardToOopClosure::get_actual_top(HeapWord* top,
+@@ -307,10 +307,6 @@
+ CompactibleSpace::clear(mangle_space);
+ }
+
+-bool ContiguousSpace::is_in(const void* p) const {
+- return _bottom <= p && p < _top;
+-}
+-
+ bool ContiguousSpace::is_free_block(const HeapWord* p) const {
+ return p >= _top;
+ }
+@@ -552,115 +548,11 @@
+ object_iterate(&blk2);
+ }
+
+-HeapWord* Space::object_iterate_careful(ObjectClosureCareful* cl) {
+- guarantee(false, "NYI");
+- return bottom();
+-}
+-
+-HeapWord* Space::object_iterate_careful_m(MemRegion mr,
+- ObjectClosureCareful* cl) {
+- guarantee(false, "NYI");
+- return bottom();
+-}
+-
+-
+-void Space::object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl) {
+- assert(!mr.is_empty(), "Should be non-empty");
+- // We use MemRegion(bottom(), end()) rather than used_region() below
+- // because the two are not necessarily equal for some kinds of
+- // spaces, in particular, certain kinds of free list spaces.
+- // We could use the more complicated but more precise:
+- // MemRegion(used_region().start(), round_to(used_region().end(), CardSize))
+- // but the slight imprecision seems acceptable in the assertion check.
+- assert(MemRegion(bottom(), end()).contains(mr),
+- "Should be within used space");
+- HeapWord* prev = cl->previous(); // max address from last time
+- if (prev >= mr.end()) { // nothing to do
+- return;
+- }
+- // This assert will not work when we go from cms space to perm
+- // space, and use same closure. Easy fix deferred for later. XXX YSR
+- // assert(prev == NULL || contains(prev), "Should be within space");
+-
+- bool last_was_obj_array = false;
+- HeapWord *blk_start_addr, *region_start_addr;
+- if (prev > mr.start()) {
+- region_start_addr = prev;
+- blk_start_addr = prev;
+- // The previous invocation may have pushed "prev" beyond the
+- // last allocated block yet there may be still be blocks
+- // in this region due to a particular coalescing policy.
+- // Relax the assertion so that the case where the unallocated
+- // block is maintained and "prev" is beyond the unallocated
+- // block does not cause the assertion to fire.
+- assert((BlockOffsetArrayUseUnallocatedBlock &&
+- (!is_in(prev))) ||
+- (blk_start_addr == block_start(region_start_addr)), "invariant");
+- } else {
+- region_start_addr = mr.start();
+- blk_start_addr = block_start(region_start_addr);
+- }
+- HeapWord* region_end_addr = mr.end();
+- MemRegion derived_mr(region_start_addr, region_end_addr);
+- while (blk_start_addr < region_end_addr) {
+- const size_t size = block_size(blk_start_addr);
+- if (block_is_obj(blk_start_addr)) {
+- last_was_obj_array = cl->do_object_bm(oop(blk_start_addr), derived_mr);
+- } else {
+- last_was_obj_array = false;
+- }
+- blk_start_addr += size;
+- }
+- if (!last_was_obj_array) {
+- assert((bottom() <= blk_start_addr) && (blk_start_addr <= end()),
+- "Should be within (closed) used space");
+- assert(blk_start_addr > prev, "Invariant");
+- cl->set_previous(blk_start_addr); // min address for next time
+- }
+-}
+-
+ bool Space::obj_is_alive(const HeapWord* p) const {
+ assert (block_is_obj(p), "The address should point to an object");
+ return true;
+ }
+
+-void ContiguousSpace::object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl) {
+- assert(!mr.is_empty(), "Should be non-empty");
+- assert(used_region().contains(mr), "Should be within used space");
+- HeapWord* prev = cl->previous(); // max address from last time
+- if (prev >= mr.end()) { // nothing to do
+- return;
+- }
+- // See comment above (in more general method above) in case you
+- // happen to use this method.
+- assert(prev == NULL || is_in_reserved(prev), "Should be within space");
+-
+- bool last_was_obj_array = false;
+- HeapWord *obj_start_addr, *region_start_addr;
+- if (prev > mr.start()) {
+- region_start_addr = prev;
+- obj_start_addr = prev;
+- assert(obj_start_addr == block_start(region_start_addr), "invariant");
+- } else {
+- region_start_addr = mr.start();
+- obj_start_addr = block_start(region_start_addr);
+- }
+- HeapWord* region_end_addr = mr.end();
+- MemRegion derived_mr(region_start_addr, region_end_addr);
+- while (obj_start_addr < region_end_addr) {
+- oop obj = oop(obj_start_addr);
+- const size_t size = obj->size();
+- last_was_obj_array = cl->do_object_bm(obj, derived_mr);
+- obj_start_addr += size;
+- }
+- if (!last_was_obj_array) {
+- assert((bottom() <= obj_start_addr) && (obj_start_addr <= end()),
+- "Should be within (closed) used space");
+- assert(obj_start_addr > prev, "Invariant");
+- cl->set_previous(obj_start_addr); // min address for next time
+- }
+-}
+-
+ #if INCLUDE_ALL_GCS
+ #define ContigSpace_PAR_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \
+ \
+@@ -688,43 +580,6 @@
+ }
+ }
+
+-void ContiguousSpace::oop_iterate(MemRegion mr, ExtendedOopClosure* blk) {
+- if (is_empty()) {
+- return;
+- }
+- MemRegion cur = MemRegion(bottom(), top());
+- mr = mr.intersection(cur);
+- if (mr.is_empty()) {
+- return;
+- }
+- if (mr.equals(cur)) {
+- oop_iterate(blk);
+- return;
+- }
+- assert(mr.end() <= top(), "just took an intersection above");
+- HeapWord* obj_addr = block_start(mr.start());
+- HeapWord* t = mr.end();
+-
+- // Handle first object specially.
+- oop obj = oop(obj_addr);
+- SpaceMemRegionOopsIterClosure smr_blk(blk, mr);
+- obj_addr += obj->oop_iterate(&smr_blk);
+- while (obj_addr < t) {
+- oop obj = oop(obj_addr);
+- assert(obj->is_oop(), "expected an oop");
+- obj_addr += obj->size();
+- // If "obj_addr" is not greater than top, then the
+- // entire object "obj" is within the region.
+- if (obj_addr <= t) {
+- obj->oop_iterate(blk);
+- } else {
+- // "obj" extends beyond end of region
+- obj->oop_iterate(&smr_blk);
+- break;
+- }
+- };
+-}
+-
+ void ContiguousSpace::object_iterate(ObjectClosure* blk) {
+ if (is_empty()) return;
+ WaterMark bm = bottom_mark();
+@@ -830,14 +685,8 @@
+ // This version requires locking.
+ inline HeapWord* ContiguousSpace::allocate_impl(size_t size,
+ HeapWord* const end_value) {
+- // In G1 there are places where a GC worker can allocates into a
+- // region using this serial allocation code without being prone to a
+- // race with other GC workers (we ensure that no other GC worker can
+- // access the same region at the same time). So the assert below is
+- // too strong in the case of G1.
+ assert(Heap_lock->owned_by_self() ||
+- (SafepointSynchronize::is_at_safepoint() &&
+- (Thread::current()->is_VM_thread() || UseG1GC)),
++ (SafepointSynchronize::is_at_safepoint() && Thread::current()->is_VM_thread()),
+ "not locked");
+ HeapWord* obj = top();
+ if (pointer_delta(end_value, obj) >= size) {
+@@ -871,6 +720,27 @@
+ } while (true);
+ }
+
++HeapWord* ContiguousSpace::allocate_aligned(size_t size) {
++ assert(Heap_lock->owned_by_self() || (SafepointSynchronize::is_at_safepoint() && Thread::current()->is_VM_thread()), "not locked");
++ HeapWord* end_value = end();
++
++ HeapWord* obj = CollectedHeap::align_allocation_or_fail(top(), end_value, SurvivorAlignmentInBytes);
++ if (obj == NULL) {
++ return NULL;
++ }
++
++ if (pointer_delta(end_value, obj) >= size) {
++ HeapWord* new_top = obj + size;
++ set_top(new_top);
++ assert(is_ptr_aligned(obj, SurvivorAlignmentInBytes) && is_aligned(new_top),
++ "checking alignment");
++ return obj;
++ } else {
++ set_top(obj);
++ return NULL;
++ }
++}
++
+ // Requires locking.
+ HeapWord* ContiguousSpace::allocate(size_t size) {
+ return allocate_impl(size, end());
+--- ./hotspot/src/share/vm/memory/space.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/space.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -33,24 +33,8 @@
+ #include "memory/watermark.hpp"
+ #include "oops/markOop.hpp"
+ #include "runtime/mutexLocker.hpp"
+-#include "runtime/prefetch.hpp"
+ #include "utilities/macros.hpp"
+ #include "utilities/workgroup.hpp"
+-#ifdef TARGET_OS_FAMILY_linux
+-# include "os_linux.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_FAMILY_solaris
+-# include "os_solaris.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_FAMILY_windows
+-# include "os_windows.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_FAMILY_aix
+-# include "os_aix.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_FAMILY_bsd
+-# include "os_bsd.inline.hpp"
+-#endif
+
+ // A space is an abstraction for the "storage units" backing
+ // up the generation abstraction. It includes specific
+@@ -81,31 +65,6 @@
+ class CardTableRS;
+ class DirtyCardToOopClosure;
+
+-// An oop closure that is circumscribed by a filtering memory region.
+-class SpaceMemRegionOopsIterClosure: public ExtendedOopClosure {
+- private:
+- ExtendedOopClosure* _cl;
+- MemRegion _mr;
+- protected:
+- template <class T> void do_oop_work(T* p) {
+- if (_mr.contains(p)) {
+- _cl->do_oop(p);
+- }
+- }
+- public:
+- SpaceMemRegionOopsIterClosure(ExtendedOopClosure* cl, MemRegion mr):
+- _cl(cl), _mr(mr) {}
+- virtual void do_oop(oop* p);
+- virtual void do_oop(narrowOop* p);
+- virtual bool do_metadata() {
+- // _cl is of type ExtendedOopClosure instead of OopClosure, so that we can check this.
+- assert(!_cl->do_metadata(), "I've checked all call paths, this shouldn't happen.");
+- return false;
+- }
+- virtual void do_klass(Klass* k) { ShouldNotReachHere(); }
+- virtual void do_class_loader_data(ClassLoaderData* cld) { ShouldNotReachHere(); }
+-};
+-
+ // A Space describes a heap area. Class Space is an abstract
+ // base class.
+ //
+@@ -145,6 +104,12 @@
+
+ void set_saved_mark_word(HeapWord* p) { _saved_mark_word = p; }
+
++ // Returns true if this object has been allocated since a
++ // generation's "save_marks" call.
++ virtual bool obj_allocated_since_save_marks(const oop obj) const {
++ return (HeapWord*)obj >= saved_mark_word();
++ }
++
+ MemRegionClosure* preconsumptionDirtyCardClosure() const {
+ return _preconsumptionDirtyCardClosure;
+ }
+@@ -152,9 +117,9 @@
+ _preconsumptionDirtyCardClosure = cl;
+ }
+
+- // Returns a subregion of the space containing all the objects in
++ // Returns a subregion of the space containing only the allocated objects in
+ // the space.
+- virtual MemRegion used_region() const { return MemRegion(bottom(), end()); }
++ virtual MemRegion used_region() const = 0;
+
+ // Returns a region that is guaranteed to contain (at least) all objects
+ // allocated at the time of the last call to "save_marks". If the space
+@@ -164,7 +129,7 @@
+ // saved mark. Otherwise, the "obj_allocated_since_save_marks" method of
+ // the space must distiguish between objects in the region allocated before
+ // and after the call to save marks.
+- virtual MemRegion used_region_at_save_marks() const {
++ MemRegion used_region_at_save_marks() const {
+ return MemRegion(bottom(), saved_mark_word());
+ }
+
+@@ -197,7 +162,9 @@
+ // expensive operation. To prevent performance problems
+ // on account of its inadvertent use in product jvm's,
+ // we restrict its use to assertion checks only.
+- virtual bool is_in(const void* p) const = 0;
++ bool is_in(const void* p) const {
++ return used_region().contains(p);
++ }
+
+ // Returns true iff the given reserved memory of the space contains the
+ // given address.
+@@ -221,11 +188,6 @@
+ // applications of the closure are not included in the iteration.
+ virtual void oop_iterate(ExtendedOopClosure* cl);
+
+- // Same as above, restricted to the intersection of a memory region and
+- // the space. Fields in objects allocated by applications of the closure
+- // are not included in the iteration.
+- virtual void oop_iterate(MemRegion mr, ExtendedOopClosure* cl) = 0;
+-
+ // Iterate over all objects in the space, calling "cl.do_object" on
+ // each. Objects allocated by applications of the closure are not
+ // included in the iteration.
+@@ -234,24 +196,6 @@
+ // objects whose internal references point to objects in the space.
+ virtual void safe_object_iterate(ObjectClosure* blk) = 0;
+
+- // Iterate over all objects that intersect with mr, calling "cl->do_object"
+- // on each. There is an exception to this: if this closure has already
+- // been invoked on an object, it may skip such objects in some cases. This is
+- // Most likely to happen in an "upwards" (ascending address) iteration of
+- // MemRegions.
+- virtual void object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl);
+-
+- // Iterate over as many initialized objects in the space as possible,
+- // calling "cl.do_object_careful" on each. Return NULL if all objects
+- // in the space (at the start of the iteration) were iterated over.
+- // Return an address indicating the extent of the iteration in the
+- // event that the iteration had to return because of finding an
+- // uninitialized object in the space, or if the closure "cl"
+- // signalled early termination.
+- virtual HeapWord* object_iterate_careful(ObjectClosureCareful* cl);
+- virtual HeapWord* object_iterate_careful_m(MemRegion mr,
+- ObjectClosureCareful* cl);
+-
+ // Create and return a new dirty card to oop closure. Can be
+ // overriden to return the appropriate type of closure
+ // depending on the type of space in which the closure will
+@@ -292,10 +236,6 @@
+ // Allocation (return NULL if full). Enforces mutual exclusion internally.
+ virtual HeapWord* par_allocate(size_t word_size) = 0;
+
+- // Returns true if this object has been allocated since a
+- // generation's "save_marks" call.
+- virtual bool obj_allocated_since_save_marks(const oop obj) const = 0;
+-
+ // Mark-sweep-compact support: all spaces can update pointers to objects
+ // moving as a part of compaction.
+ virtual void adjust_pointers();
+@@ -390,12 +330,11 @@
+ Generation* gen;
+ CompactibleSpace* space;
+ HeapWord* threshold;
+- CompactPoint(Generation* _gen, CompactibleSpace* _space,
+- HeapWord* _threshold) :
+- gen(_gen), space(_space), threshold(_threshold) {}
++
++ CompactPoint(Generation* g = NULL) :
++ gen(g), space(NULL), threshold(0) {}
+ };
+
+-
+ // A space that supports compaction operations. This is usually, but not
+ // necessarily, a space that is normally contiguous. But, for example, a
+ // free-list-based space whose normal collection is a mark-sweep without
+@@ -427,7 +366,7 @@
+
+ // Perform operations on the space needed after a compaction
+ // has been performed.
+- virtual void reset_after_compaction() {}
++ virtual void reset_after_compaction() = 0;
+
+ // Returns the next space (in the current generation) to be compacted in
+ // the global compaction order. Also is used to select the next
+@@ -492,7 +431,7 @@
+ HeapWord* _end_of_live;
+
+ // Minimum size of a free block.
+- virtual size_t minimum_free_block_size() const = 0;
++ virtual size_t minimum_free_block_size() const { return 0; }
+
+ // This the function is invoked when an allocation of an object covering
+ // "start" to "end occurs crosses the threshold; returns the next
+@@ -512,272 +451,6 @@
+ size_t word_len);
+ };
+
+-#define SCAN_AND_FORWARD(cp,scan_limit,block_is_obj,block_size) { \
+- /* Compute the new addresses for the live objects and store it in the mark \
+- * Used by universe::mark_sweep_phase2() \
+- */ \
+- HeapWord* compact_top; /* This is where we are currently compacting to. */ \
+- \
+- /* We're sure to be here before any objects are compacted into this \
+- * space, so this is a good time to initialize this: \
+- */ \
+- set_compaction_top(bottom()); \
+- \
+- if (cp->space == NULL) { \
+- assert(cp->gen != NULL, "need a generation"); \
+- assert(cp->threshold == NULL, "just checking"); \
+- assert(cp->gen->first_compaction_space() == this, "just checking"); \
+- cp->space = cp->gen->first_compaction_space(); \
+- compact_top = cp->space->bottom(); \
+- cp->space->set_compaction_top(compact_top); \
+- cp->threshold = cp->space->initialize_threshold(); \
+- } else { \
+- compact_top = cp->space->compaction_top(); \
+- } \
+- \
+- /* We allow some amount of garbage towards the bottom of the space, so \
+- * we don't start compacting before there is a significant gain to be made.\
+- * Occasionally, we want to ensure a full compaction, which is determined \
+- * by the MarkSweepAlwaysCompactCount parameter. \
+- */ \
+- uint invocations = MarkSweep::total_invocations(); \
+- bool skip_dead = ((invocations % MarkSweepAlwaysCompactCount) != 0); \
+- \
+- size_t allowed_deadspace = 0; \
+- if (skip_dead) { \
+- const size_t ratio = allowed_dead_ratio(); \
+- allowed_deadspace = (capacity() * ratio / 100) / HeapWordSize; \
+- } \
+- \
+- HeapWord* q = bottom(); \
+- HeapWord* t = scan_limit(); \
+- \
+- HeapWord* end_of_live= q; /* One byte beyond the last byte of the last \
+- live object. */ \
+- HeapWord* first_dead = end();/* The first dead object. */ \
+- LiveRange* liveRange = NULL; /* The current live range, recorded in the \
+- first header of preceding free area. */ \
+- _first_dead = first_dead; \
+- \
+- const intx interval = PrefetchScanIntervalInBytes; \
+- \
+- while (q < t) { \
+- assert(!block_is_obj(q) || \
+- oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() || \
+- oop(q)->mark()->has_bias_pattern(), \
+- "these are the only valid states during a mark sweep"); \
+- if (block_is_obj(q) && oop(q)->is_gc_marked()) { \
+- /* prefetch beyond q */ \
+- Prefetch::write(q, interval); \
+- size_t size = block_size(q); \
+- compact_top = cp->space->forward(oop(q), size, cp, compact_top); \
+- q += size; \
+- end_of_live = q; \
+- } else { \
+- /* run over all the contiguous dead objects */ \
+- HeapWord* end = q; \
+- do { \
+- /* prefetch beyond end */ \
+- Prefetch::write(end, interval); \
+- end += block_size(end); \
+- } while (end < t && (!block_is_obj(end) || !oop(end)->is_gc_marked()));\
+- \
+- /* see if we might want to pretend this object is alive so that \
+- * we don't have to compact quite as often. \
+- */ \
+- if (allowed_deadspace > 0 && q == compact_top) { \
+- size_t sz = pointer_delta(end, q); \
+- if (insert_deadspace(allowed_deadspace, q, sz)) { \
+- compact_top = cp->space->forward(oop(q), sz, cp, compact_top); \
+- q = end; \
+- end_of_live = end; \
+- continue; \
+- } \
+- } \
+- \
+- /* otherwise, it really is a free region. */ \
+- \
+- /* for the previous LiveRange, record the end of the live objects. */ \
+- if (liveRange) { \
+- liveRange->set_end(q); \
+- } \
+- \
+- /* record the current LiveRange object. \
+- * liveRange->start() is overlaid on the mark word. \
+- */ \
+- liveRange = (LiveRange*)q; \
+- liveRange->set_start(end); \
+- liveRange->set_end(end); \
+- \
+- /* see if this is the first dead region. */ \
+- if (q < first_dead) { \
+- first_dead = q; \
+- } \
+- \
+- /* move on to the next object */ \
+- q = end; \
+- } \
+- } \
+- \
+- assert(q == t, "just checking"); \
+- if (liveRange != NULL) { \
+- liveRange->set_end(q); \
+- } \
+- _end_of_live = end_of_live; \
+- if (end_of_live < first_dead) { \
+- first_dead = end_of_live; \
+- } \
+- _first_dead = first_dead; \
+- \
+- /* save the compaction_top of the compaction space. */ \
+- cp->space->set_compaction_top(compact_top); \
+-}
+-
+-#define SCAN_AND_ADJUST_POINTERS(adjust_obj_size) { \
+- /* adjust all the interior pointers to point at the new locations of objects \
+- * Used by MarkSweep::mark_sweep_phase3() */ \
+- \
+- HeapWord* q = bottom(); \
+- HeapWord* t = _end_of_live; /* Established by "prepare_for_compaction". */ \
+- \
+- assert(_first_dead <= _end_of_live, "Stands to reason, no?"); \
+- \
+- if (q < t && _first_dead > q && \
+- !oop(q)->is_gc_marked()) { \
+- /* we have a chunk of the space which hasn't moved and we've \
+- * reinitialized the mark word during the previous pass, so we can't \
+- * use is_gc_marked for the traversal. */ \
+- HeapWord* end = _first_dead; \
+- \
+- while (q < end) { \
+- /* I originally tried to conjoin "block_start(q) == q" to the \
+- * assertion below, but that doesn't work, because you can't \
+- * accurately traverse previous objects to get to the current one \
+- * after their pointers have been \
+- * updated, until the actual compaction is done. dld, 4/00 */ \
+- assert(block_is_obj(q), \
+- "should be at block boundaries, and should be looking at objs"); \
+- \
+- /* point all the oops to the new location */ \
+- size_t size = oop(q)->adjust_pointers(); \
+- size = adjust_obj_size(size); \
+- \
+- q += size; \
+- } \
+- \
+- if (_first_dead == t) { \
+- q = t; \
+- } else { \
+- /* $$$ This is funky. Using this to read the previously written \
+- * LiveRange. See also use below. */ \
+- q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer(); \
+- } \
+- } \
+- \
+- const intx interval = PrefetchScanIntervalInBytes; \
+- \
+- debug_only(HeapWord* prev_q = NULL); \
+- while (q < t) { \
+- /* prefetch beyond q */ \
+- Prefetch::write(q, interval); \
+- if (oop(q)->is_gc_marked()) { \
+- /* q is alive */ \
+- /* point all the oops to the new location */ \
+- size_t size = oop(q)->adjust_pointers(); \
+- size = adjust_obj_size(size); \
+- debug_only(prev_q = q); \
+- q += size; \
+- } else { \
+- /* q is not a live object, so its mark should point at the next \
+- * live object */ \
+- debug_only(prev_q = q); \
+- q = (HeapWord*) oop(q)->mark()->decode_pointer(); \
+- assert(q > prev_q, "we should be moving forward through memory"); \
+- } \
+- } \
+- \
+- assert(q == t, "just checking"); \
+-}
+-
+-#define SCAN_AND_COMPACT(obj_size) { \
+- /* Copy all live objects to their new location \
+- * Used by MarkSweep::mark_sweep_phase4() */ \
+- \
+- HeapWord* q = bottom(); \
+- HeapWord* const t = _end_of_live; \
+- debug_only(HeapWord* prev_q = NULL); \
+- \
+- if (q < t && _first_dead > q && \
+- !oop(q)->is_gc_marked()) { \
+- debug_only( \
+- /* we have a chunk of the space which hasn't moved and we've reinitialized \
+- * the mark word during the previous pass, so we can't use is_gc_marked for \
+- * the traversal. */ \
+- HeapWord* const end = _first_dead; \
+- \
+- while (q < end) { \
+- size_t size = obj_size(q); \
+- assert(!oop(q)->is_gc_marked(), \
+- "should be unmarked (special dense prefix handling)"); \
+- debug_only(prev_q = q); \
+- q += size; \
+- } \
+- ) /* debug_only */ \
+- \
+- if (_first_dead == t) { \
+- q = t; \
+- } else { \
+- /* $$$ Funky */ \
+- q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer(); \
+- } \
+- } \
+- \
+- const intx scan_interval = PrefetchScanIntervalInBytes; \
+- const intx copy_interval = PrefetchCopyIntervalInBytes; \
+- while (q < t) { \
+- if (!oop(q)->is_gc_marked()) { \
+- /* mark is pointer to next marked oop */ \
+- debug_only(prev_q = q); \
+- q = (HeapWord*) oop(q)->mark()->decode_pointer(); \
+- assert(q > prev_q, "we should be moving forward through memory"); \
+- } else { \
+- /* prefetch beyond q */ \
+- Prefetch::read(q, scan_interval); \
+- \
+- /* size and destination */ \
+- size_t size = obj_size(q); \
+- HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee(); \
+- \
+- /* prefetch beyond compaction_top */ \
+- Prefetch::write(compaction_top, copy_interval); \
+- \
+- /* copy object and reinit its mark */ \
+- assert(q != compaction_top, "everything in this pass should be moving"); \
+- Copy::aligned_conjoint_words(q, compaction_top, size); \
+- oop(compaction_top)->init_mark(); \
+- assert(oop(compaction_top)->klass() != NULL, "should have a class"); \
+- \
+- debug_only(prev_q = q); \
+- q += size; \
+- } \
+- } \
+- \
+- /* Let's remember if we were empty before we did the compaction. */ \
+- bool was_empty = used_region().is_empty(); \
+- /* Reset space after compaction is complete */ \
+- reset_after_compaction(); \
+- /* We do this clear, below, since it has overloaded meanings for some */ \
+- /* space subtypes. For example, OffsetTableContigSpace's that were */ \
+- /* compacted into will have had their offset table thresholds updated */ \
+- /* continuously, but those that weren't need to have their thresholds */ \
+- /* re-initialized. Also mangles unused area for debugging. */ \
+- if (used_region().is_empty()) { \
+- if (!was_empty) clear(SpaceDecorator::Mangle); \
+- } else { \
+- if (ZapUnusedHeapArea) mangle_unused_area(); \
+- } \
+-}
+-
+ class GenSpaceMangler;
+
+ // A space in which the free area is contiguous. It therefore supports
+@@ -808,7 +481,7 @@
+ HeapWord* top() const { return _top; }
+ void set_top(HeapWord* value) { _top = value; }
+
+- virtual void set_saved_mark() { _saved_mark_word = top(); }
++ void set_saved_mark() { _saved_mark_word = top(); }
+ void reset_saved_mark() { _saved_mark_word = bottom(); }
+
+ WaterMark bottom_mark() { return WaterMark(this, bottom()); }
+@@ -843,36 +516,31 @@
+ size_t used() const { return byte_size(bottom(), top()); }
+ size_t free() const { return byte_size(top(), end()); }
+
+- // Override from space.
+- bool is_in(const void* p) const;
+-
+ virtual bool is_free_block(const HeapWord* p) const;
+
+ // In a contiguous space we have a more obvious bound on what parts
+ // contain objects.
+ MemRegion used_region() const { return MemRegion(bottom(), top()); }
+
+- MemRegion used_region_at_save_marks() const {
+- return MemRegion(bottom(), saved_mark_word());
+- }
+-
+ // Allocation (return NULL if full)
+ virtual HeapWord* allocate(size_t word_size);
+ virtual HeapWord* par_allocate(size_t word_size);
+-
+- virtual bool obj_allocated_since_save_marks(const oop obj) const {
+- return (HeapWord*)obj >= saved_mark_word();
+- }
++ HeapWord* allocate_aligned(size_t word_size);
+
+ // Iteration
+ void oop_iterate(ExtendedOopClosure* cl);
+- void oop_iterate(MemRegion mr, ExtendedOopClosure* cl);
+ void object_iterate(ObjectClosure* blk);
+ // For contiguous spaces this method will iterate safely over objects
+ // in the space (i.e., between bottom and top) when at a safepoint.
+ void safe_object_iterate(ObjectClosure* blk);
+- void object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl);
+- // iterates on objects up to the safe limit
++
++ // Iterate over as many initialized objects in the space as possible,
++ // calling "cl.do_object_careful" on each. Return NULL if all objects
++ // in the space (at the start of the iteration) were iterated over.
++ // Return an address indicating the extent of the iteration in the
++ // event that the iteration had to return because of finding an
++ // uninitialized object in the space, or if the closure "cl"
++ // signaled early termination.
+ HeapWord* object_iterate_careful(ObjectClosureCareful* cl);
+ HeapWord* concurrent_iteration_safe_limit() {
+ assert(_concurrent_iteration_safe_limit <= top(),
+@@ -903,7 +571,6 @@
+ // set new iteration safe limit
+ set_concurrent_iteration_safe_limit(compaction_top());
+ }
+- virtual size_t minimum_free_block_size() const { return 0; }
+
+ // Override.
+ DirtyCardToOopClosure* new_dcto_cl(ExtendedOopClosure* cl,
+--- ./hotspot/src/share/vm/memory/space.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/space.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,12 +28,279 @@
+ #include "gc_interface/collectedHeap.hpp"
+ #include "memory/space.hpp"
+ #include "memory/universe.hpp"
++#include "runtime/prefetch.inline.hpp"
+ #include "runtime/safepoint.hpp"
+
+ inline HeapWord* Space::block_start(const void* p) {
+ return block_start_const(p);
+ }
+
++#define SCAN_AND_FORWARD(cp,scan_limit,block_is_obj,block_size) { \
++ /* Compute the new addresses for the live objects and store it in the mark \
++ * Used by universe::mark_sweep_phase2() \
++ */ \
++ HeapWord* compact_top; /* This is where we are currently compacting to. */ \
++ \
++ /* We're sure to be here before any objects are compacted into this \
++ * space, so this is a good time to initialize this: \
++ */ \
++ set_compaction_top(bottom()); \
++ \
++ if (cp->space == NULL) { \
++ assert(cp->gen != NULL, "need a generation"); \
++ assert(cp->threshold == NULL, "just checking"); \
++ assert(cp->gen->first_compaction_space() == this, "just checking"); \
++ cp->space = cp->gen->first_compaction_space(); \
++ compact_top = cp->space->bottom(); \
++ cp->space->set_compaction_top(compact_top); \
++ cp->threshold = cp->space->initialize_threshold(); \
++ } else { \
++ compact_top = cp->space->compaction_top(); \
++ } \
++ \
++ /* We allow some amount of garbage towards the bottom of the space, so \
++ * we don't start compacting before there is a significant gain to be made.\
++ * Occasionally, we want to ensure a full compaction, which is determined \
++ * by the MarkSweepAlwaysCompactCount parameter. \
++ */ \
++ uint invocations = MarkSweep::total_invocations(); \
++ bool skip_dead = ((invocations % MarkSweepAlwaysCompactCount) != 0); \
++ \
++ size_t allowed_deadspace = 0; \
++ if (skip_dead) { \
++ const size_t ratio = allowed_dead_ratio(); \
++ allowed_deadspace = (capacity() * ratio / 100) / HeapWordSize; \
++ } \
++ \
++ HeapWord* q = bottom(); \
++ HeapWord* t = scan_limit(); \
++ \
++ HeapWord* end_of_live= q; /* One byte beyond the last byte of the last \
++ live object. */ \
++ HeapWord* first_dead = end();/* The first dead object. */ \
++ LiveRange* liveRange = NULL; /* The current live range, recorded in the \
++ first header of preceding free area. */ \
++ _first_dead = first_dead; \
++ \
++ const intx interval = PrefetchScanIntervalInBytes; \
++ \
++ while (q < t) { \
++ assert(!block_is_obj(q) || \
++ oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() || \
++ oop(q)->mark()->has_bias_pattern(), \
++ "these are the only valid states during a mark sweep"); \
++ if (block_is_obj(q) && oop(q)->is_gc_marked()) { \
++ /* prefetch beyond q */ \
++ Prefetch::write(q, interval); \
++ size_t size = block_size(q); \
++ compact_top = cp->space->forward(oop(q), size, cp, compact_top); \
++ q += size; \
++ end_of_live = q; \
++ } else { \
++ /* run over all the contiguous dead objects */ \
++ HeapWord* end = q; \
++ do { \
++ /* prefetch beyond end */ \
++ Prefetch::write(end, interval); \
++ end += block_size(end); \
++ } while (end < t && (!block_is_obj(end) || !oop(end)->is_gc_marked()));\
++ \
++ /* see if we might want to pretend this object is alive so that \
++ * we don't have to compact quite as often. \
++ */ \
++ if (allowed_deadspace > 0 && q == compact_top) { \
++ size_t sz = pointer_delta(end, q); \
++ if (insert_deadspace(allowed_deadspace, q, sz)) { \
++ compact_top = cp->space->forward(oop(q), sz, cp, compact_top); \
++ q = end; \
++ end_of_live = end; \
++ continue; \
++ } \
++ } \
++ \
++ /* otherwise, it really is a free region. */ \
++ \
++ /* for the previous LiveRange, record the end of the live objects. */ \
++ if (liveRange) { \
++ liveRange->set_end(q); \
++ } \
++ \
++ /* record the current LiveRange object. \
++ * liveRange->start() is overlaid on the mark word. \
++ */ \
++ liveRange = (LiveRange*)q; \
++ liveRange->set_start(end); \
++ liveRange->set_end(end); \
++ \
++ /* see if this is the first dead region. */ \
++ if (q < first_dead) { \
++ first_dead = q; \
++ } \
++ \
++ /* move on to the next object */ \
++ q = end; \
++ } \
++ } \
++ \
++ assert(q == t, "just checking"); \
++ if (liveRange != NULL) { \
++ liveRange->set_end(q); \
++ } \
++ _end_of_live = end_of_live; \
++ if (end_of_live < first_dead) { \
++ first_dead = end_of_live; \
++ } \
++ _first_dead = first_dead; \
++ \
++ /* save the compaction_top of the compaction space. */ \
++ cp->space->set_compaction_top(compact_top); \
++}
++
++#define SCAN_AND_ADJUST_POINTERS(adjust_obj_size) { \
++ /* adjust all the interior pointers to point at the new locations of objects \
++ * Used by MarkSweep::mark_sweep_phase3() */ \
++ \
++ HeapWord* q = bottom(); \
++ HeapWord* t = _end_of_live; /* Established by "prepare_for_compaction". */ \
++ \
++ assert(_first_dead <= _end_of_live, "Stands to reason, no?"); \
++ \
++ if (q < t && _first_dead > q && \
++ !oop(q)->is_gc_marked()) { \
++ /* we have a chunk of the space which hasn't moved and we've \
++ * reinitialized the mark word during the previous pass, so we can't \
++ * use is_gc_marked for the traversal. */ \
++ HeapWord* end = _first_dead; \
++ \
++ while (q < end) { \
++ /* I originally tried to conjoin "block_start(q) == q" to the \
++ * assertion below, but that doesn't work, because you can't \
++ * accurately traverse previous objects to get to the current one \
++ * after their pointers have been \
++ * updated, until the actual compaction is done. dld, 4/00 */ \
++ assert(block_is_obj(q), \
++ "should be at block boundaries, and should be looking at objs"); \
++ \
++ /* point all the oops to the new location */ \
++ size_t size = oop(q)->adjust_pointers(); \
++ size = adjust_obj_size(size); \
++ \
++ q += size; \
++ } \
++ \
++ if (_first_dead == t) { \
++ q = t; \
++ } else { \
++ /* $$$ This is funky. Using this to read the previously written \
++ * LiveRange. See also use below. */ \
++ q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer(); \
++ } \
++ } \
++ \
++ const intx interval = PrefetchScanIntervalInBytes; \
++ \
++ debug_only(HeapWord* prev_q = NULL); \
++ while (q < t) { \
++ /* prefetch beyond q */ \
++ Prefetch::write(q, interval); \
++ if (oop(q)->is_gc_marked()) { \
++ /* q is alive */ \
++ /* point all the oops to the new location */ \
++ size_t size = oop(q)->adjust_pointers(); \
++ size = adjust_obj_size(size); \
++ debug_only(prev_q = q); \
++ q += size; \
++ } else { \
++ /* q is not a live object, so its mark should point at the next \
++ * live object */ \
++ debug_only(prev_q = q); \
++ q = (HeapWord*) oop(q)->mark()->decode_pointer(); \
++ assert(q > prev_q, "we should be moving forward through memory"); \
++ } \
++ } \
++ \
++ assert(q == t, "just checking"); \
++}
++
++#define SCAN_AND_COMPACT(obj_size) { \
++ /* Copy all live objects to their new location \
++ * Used by MarkSweep::mark_sweep_phase4() */ \
++ \
++ HeapWord* q = bottom(); \
++ HeapWord* const t = _end_of_live; \
++ debug_only(HeapWord* prev_q = NULL); \
++ \
++ if (q < t && _first_dead > q && \
++ !oop(q)->is_gc_marked()) { \
++ debug_only( \
++ /* we have a chunk of the space which hasn't moved and we've reinitialized \
++ * the mark word during the previous pass, so we can't use is_gc_marked for \
++ * the traversal. */ \
++ HeapWord* const end = _first_dead; \
++ \
++ while (q < end) { \
++ size_t size = obj_size(q); \
++ assert(!oop(q)->is_gc_marked(), \
++ "should be unmarked (special dense prefix handling)"); \
++ debug_only(prev_q = q); \
++ q += size; \
++ } \
++ ) /* debug_only */ \
++ \
++ if (_first_dead == t) { \
++ q = t; \
++ } else { \
++ /* $$$ Funky */ \
++ q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer(); \
++ } \
++ } \
++ \
++ const intx scan_interval = PrefetchScanIntervalInBytes; \
++ const intx copy_interval = PrefetchCopyIntervalInBytes; \
++ while (q < t) { \
++ if (!oop(q)->is_gc_marked()) { \
++ /* mark is pointer to next marked oop */ \
++ debug_only(prev_q = q); \
++ q = (HeapWord*) oop(q)->mark()->decode_pointer(); \
++ assert(q > prev_q, "we should be moving forward through memory"); \
++ } else { \
++ /* prefetch beyond q */ \
++ Prefetch::read(q, scan_interval); \
++ \
++ /* size and destination */ \
++ size_t size = obj_size(q); \
++ HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee(); \
++ \
++ /* prefetch beyond compaction_top */ \
++ Prefetch::write(compaction_top, copy_interval); \
++ \
++ /* copy object and reinit its mark */ \
++ assert(q != compaction_top, "everything in this pass should be moving"); \
++ Copy::aligned_conjoint_words(q, compaction_top, size); \
++ oop(compaction_top)->init_mark(); \
++ assert(oop(compaction_top)->klass() != NULL, "should have a class"); \
++ \
++ debug_only(prev_q = q); \
++ q += size; \
++ } \
++ } \
++ \
++ /* Let's remember if we were empty before we did the compaction. */ \
++ bool was_empty = used_region().is_empty(); \
++ /* Reset space after compaction is complete */ \
++ reset_after_compaction(); \
++ /* We do this clear, below, since it has overloaded meanings for some */ \
++ /* space subtypes. For example, OffsetTableContigSpace's that were */ \
++ /* compacted into will have had their offset table thresholds updated */ \
++ /* continuously, but those that weren't need to have their thresholds */ \
++ /* re-initialized. Also mangles unused area for debugging. */ \
++ if (used_region().is_empty()) { \
++ if (!was_empty) clear(SpaceDecorator::Mangle); \
++ } else { \
++ if (ZapUnusedHeapArea) mangle_unused_area(); \
++ } \
++}
++
+ inline HeapWord* OffsetTableContigSpace::allocate(size_t size) {
+ HeapWord* res = ContiguousSpace::allocate(size);
+ if (res != NULL) {
+--- ./hotspot/src/share/vm/memory/universe.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/universe.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,6 +26,9 @@
+ #include "classfile/classLoader.hpp"
+ #include "classfile/classLoaderData.hpp"
+ #include "classfile/javaClasses.hpp"
++#if INCLUDE_CDS
++#include "classfile/sharedClassUtil.hpp"
++#endif
+ #include "classfile/symbolTable.hpp"
+ #include "classfile/systemDictionary.hpp"
+ #include "classfile/vmSymbols.hpp"
+@@ -34,6 +37,7 @@
+ #include "gc_interface/collectedHeap.inline.hpp"
+ #include "interpreter/interpreter.hpp"
+ #include "memory/cardTableModRefBS.hpp"
++#include "memory/filemap.hpp"
+ #include "memory/gcLocker.inline.hpp"
+ #include "memory/genCollectedHeap.hpp"
+ #include "memory/genRemSet.hpp"
+@@ -74,7 +78,7 @@
+ #include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp"
+ #include "gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp"
+ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+-#include "gc_implementation/g1/g1CollectorPolicy.hpp"
++#include "gc_implementation/g1/g1CollectorPolicy_ext.hpp"
+ #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
+ #endif // INCLUDE_ALL_GCS
+
+@@ -115,6 +119,7 @@
+ oop Universe::_out_of_memory_error_class_metaspace = NULL;
+ oop Universe::_out_of_memory_error_array_size = NULL;
+ oop Universe::_out_of_memory_error_gc_overhead_limit = NULL;
++oop Universe::_out_of_memory_error_realloc_objects = NULL;
+ objArrayOop Universe::_preallocated_out_of_memory_error_array = NULL;
+ volatile jint Universe::_preallocated_out_of_memory_error_avail_count = 0;
+ bool Universe::_verify_in_progress = false;
+@@ -122,6 +127,8 @@
+ oop Universe::_arithmetic_exception_instance = NULL;
+ oop Universe::_virtual_machine_error_instance = NULL;
+ oop Universe::_vm_exception = NULL;
++oop Universe::_allocation_context_notification_obj = NULL;
++
+ Method* Universe::_throw_illegal_access_error = NULL;
+ Array<int>* Universe::_the_empty_int_array = NULL;
+ Array<u2>* Universe::_the_empty_short_array = NULL;
+@@ -184,6 +191,7 @@
+ f->do_oop((oop*)&_out_of_memory_error_class_metaspace);
+ f->do_oop((oop*)&_out_of_memory_error_array_size);
+ f->do_oop((oop*)&_out_of_memory_error_gc_overhead_limit);
++ f->do_oop((oop*)&_out_of_memory_error_realloc_objects);
+ f->do_oop((oop*)&_preallocated_out_of_memory_error_array);
+ f->do_oop((oop*)&_null_ptr_exception_instance);
+ f->do_oop((oop*)&_arithmetic_exception_instance);
+@@ -191,6 +199,7 @@
+ f->do_oop((oop*)&_main_thread_group);
+ f->do_oop((oop*)&_system_thread_group);
+ f->do_oop((oop*)&_vm_exception);
++ f->do_oop((oop*)&_allocation_context_notification_obj);
+ debug_only(f->do_oop((oop*)&_fullgc_alot_dummy_array);)
+ }
+
+@@ -238,8 +247,9 @@
+ void initialize_basic_type_klass(Klass* k, TRAPS) {
+ Klass* ok = SystemDictionary::Object_klass();
+ if (UseSharedSpaces) {
++ ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
+ assert(k->super() == ok, "u3");
+- k->restore_unshareable_info(CHECK);
++ k->restore_unshareable_info(loader_data, Handle(), CHECK);
+ } else {
+ k->initialize_supers(ok, CHECK);
+ }
+@@ -566,7 +576,8 @@
+ (throwable() != Universe::_out_of_memory_error_metaspace) &&
+ (throwable() != Universe::_out_of_memory_error_class_metaspace) &&
+ (throwable() != Universe::_out_of_memory_error_array_size) &&
+- (throwable() != Universe::_out_of_memory_error_gc_overhead_limit));
++ (throwable() != Universe::_out_of_memory_error_gc_overhead_limit) &&
++ (throwable() != Universe::_out_of_memory_error_realloc_objects));
+ }
+
+
+@@ -665,6 +676,10 @@
+ SymbolTable::create_table();
+ StringTable::create_table();
+ ClassLoader::create_package_info_table();
++
++ if (DumpSharedSpaces) {
++ MetaspaceShared::prepare_for_dumping();
++ }
+ }
+
+ return JNI_OK;
+@@ -786,7 +801,7 @@
+
+ } else if (UseG1GC) {
+ #if INCLUDE_ALL_GCS
+- G1CollectorPolicy* g1p = new G1CollectorPolicy();
++ G1CollectorPolicyExt* g1p = new G1CollectorPolicyExt();
+ g1p->initialize_all();
+ G1CollectedHeap* g1h = new G1CollectedHeap(g1p);
+ Universe::_collectedHeap = g1h;
+@@ -1032,6 +1047,7 @@
+ Universe::_out_of_memory_error_array_size = k_h->allocate_instance(CHECK_false);
+ Universe::_out_of_memory_error_gc_overhead_limit =
+ k_h->allocate_instance(CHECK_false);
++ Universe::_out_of_memory_error_realloc_objects = k_h->allocate_instance(CHECK_false);
+
+ // Setup preallocated NullPointerException
+ // (this is currently used for a cheap & dirty solution in compiler exception handling)
+@@ -1071,6 +1087,9 @@
+ msg = java_lang_String::create_from_str("GC overhead limit exceeded", CHECK_false);
+ java_lang_Throwable::set_message(Universe::_out_of_memory_error_gc_overhead_limit, msg());
+
++ msg = java_lang_String::create_from_str("Java heap space: failed reallocation of scalar replaced objects", CHECK_false);
++ java_lang_Throwable::set_message(Universe::_out_of_memory_error_realloc_objects, msg());
++
+ msg = java_lang_String::create_from_str("/ by zero", CHECK_false);
+ java_lang_Throwable::set_message(Universe::_arithmetic_exception_instance, msg());
+
+@@ -1166,6 +1185,11 @@
+ MemoryService::add_metaspace_memory_pools();
+
+ MemoryService::set_universe_heap(Universe::_collectedHeap);
++#if INCLUDE_CDS
++ if (UseSharedSpaces) {
++ SharedClassUtil::initialize(CHECK_false);
++ }
++#endif
+ return true;
+ }
+
+--- ./hotspot/src/share/vm/memory/universe.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/universe.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -157,6 +157,7 @@
+ static oop _out_of_memory_error_class_metaspace;
+ static oop _out_of_memory_error_array_size;
+ static oop _out_of_memory_error_gc_overhead_limit;
++ static oop _out_of_memory_error_realloc_objects;
+
+ static Array<int>* _the_empty_int_array; // Canonicalized int array
+ static Array<u2>* _the_empty_short_array; // Canonicalized short array
+@@ -178,6 +179,8 @@
+ // the vm thread.
+ static oop _vm_exception;
+
++ static oop _allocation_context_notification_obj;
++
+ // The particular choice of collected heap.
+ static CollectedHeap* _collectedHeap;
+
+@@ -307,6 +310,10 @@
+ static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; }
+ static oop virtual_machine_error_instance() { return _virtual_machine_error_instance; }
+ static oop vm_exception() { return _vm_exception; }
++
++ static inline oop allocation_context_notification_obj();
++ static inline void set_allocation_context_notification_obj(oop obj);
++
+ static Method* throw_illegal_access_error() { return _throw_illegal_access_error; }
+
+ static Array<int>* the_empty_int_array() { return _the_empty_int_array; }
+@@ -322,6 +329,7 @@
+ static oop out_of_memory_error_class_metaspace() { return gen_out_of_memory_error(_out_of_memory_error_class_metaspace); }
+ static oop out_of_memory_error_array_size() { return gen_out_of_memory_error(_out_of_memory_error_array_size); }
+ static oop out_of_memory_error_gc_overhead_limit() { return gen_out_of_memory_error(_out_of_memory_error_gc_overhead_limit); }
++ static oop out_of_memory_error_realloc_objects() { return gen_out_of_memory_error(_out_of_memory_error_realloc_objects); }
+
+ // Accessors needed for fast allocation
+ static Klass** boolArrayKlassObj_addr() { return &_boolArrayKlassObj; }
+--- ./hotspot/src/share/vm/memory/universe.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/memory/universe.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -41,4 +41,12 @@
+ return type == T_DOUBLE || type == T_LONG;
+ }
+
++inline oop Universe::allocation_context_notification_obj() {
++ return _allocation_context_notification_obj;
++}
++
++inline void Universe::set_allocation_context_notification_obj(oop obj) {
++ _allocation_context_notification_obj = obj;
++}
++
+ #endif // SHARE_VM_MEMORY_UNIVERSE_INLINE_HPP
+--- ./hotspot/src/share/vm/oops/arrayKlass.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/arrayKlass.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -100,7 +100,7 @@
+ ResourceMark rm(THREAD);
+ k->initialize_supers(super_klass(), CHECK);
+ k->vtable()->initialize_vtable(false, CHECK);
+- java_lang_Class::create_mirror(k, Handle(NULL), CHECK);
++ java_lang_Class::create_mirror(k, Handle(THREAD, k->class_loader()), Handle(NULL), CHECK);
+ }
+
+ GrowableArray<Klass*>* ArrayKlass::compute_secondary_supers(int num_extra_slots) {
+@@ -193,8 +193,9 @@
+ set_component_mirror(NULL);
+ }
+
+-void ArrayKlass::restore_unshareable_info(TRAPS) {
+- Klass::restore_unshareable_info(CHECK);
++void ArrayKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
++ assert(loader_data == ClassLoaderData::the_null_class_loader_data(), "array classes belong to null loader");
++ Klass::restore_unshareable_info(loader_data, protection_domain, CHECK);
+ // Klass recreates the component mirror also
+ }
+
+--- ./hotspot/src/share/vm/oops/arrayKlass.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/arrayKlass.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -141,7 +141,7 @@
+
+ // CDS support - remove and restore oops from metadata. Oops are not shared.
+ virtual void remove_unshareable_info();
+- virtual void restore_unshareable_info(TRAPS);
++ virtual void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
+
+ // Printing
+ void print_on(outputStream* st) const;
+--- ./hotspot/src/share/vm/oops/constantPool.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/constantPool.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1817,11 +1817,22 @@
+
+ void ConstantPool::set_on_stack(const bool value) {
+ if (value) {
+- _flags |= _on_stack;
++ int old_flags = *const_cast<volatile int *>(&_flags);
++ while ((old_flags & _on_stack) == 0) {
++ int new_flags = old_flags | _on_stack;
++ int result = Atomic::cmpxchg(new_flags, &_flags, old_flags);
++
++ if (result == old_flags) {
++ // Succeeded.
++ MetadataOnStackMark::record(this, Thread::current());
++ return;
++ }
++ old_flags = result;
++ }
+ } else {
++ // Clearing is done single-threadedly.
+ _flags &= ~_on_stack;
+ }
+- if (value) MetadataOnStackMark::record(this);
+ }
+
+ // JSR 292 support for patching constant pool oops after the class is linked and
+--- ./hotspot/src/share/vm/oops/cpCache.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/cpCache.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -33,6 +33,7 @@
+ #include "prims/jvmtiRedefineClassesTrace.hpp"
+ #include "prims/methodHandles.hpp"
+ #include "runtime/handles.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "utilities/macros.hpp"
+ #if INCLUDE_ALL_GCS
+ # include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
+--- ./hotspot/src/share/vm/oops/cpCache.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/cpCache.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -27,6 +27,7 @@
+
+ #include "interpreter/bytecodes.hpp"
+ #include "memory/allocation.hpp"
++#include "runtime/orderAccess.hpp"
+ #include "utilities/array.hpp"
+
+ class PSPromotionManager;
+--- ./hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,6 +28,7 @@
+ #include "gc_implementation/shared/markSweep.inline.hpp"
+ #include "gc_interface/collectedHeap.inline.hpp"
+ #include "memory/genOopClosures.inline.hpp"
++#include "memory/iterator.inline.hpp"
+ #include "memory/oopFactory.hpp"
+ #include "oops/instanceKlass.hpp"
+ #include "oops/instanceClassLoaderKlass.hpp"
+@@ -44,12 +45,6 @@
+ #include "oops/oop.pcgc.inline.hpp"
+ #endif // INCLUDE_ALL_GCS
+
+-#define if_do_metadata_checked(closure, nv_suffix) \
+- /* Make sure the non-virtual and the virtual versions match. */ \
+- assert(closure->do_metadata##nv_suffix() == closure->do_metadata(), \
+- "Inconsistency in do_metadata"); \
+- if (closure->do_metadata##nv_suffix())
+-
+ // Macro to define InstanceClassLoaderKlass::oop_oop_iterate for virtual/nonvirtual for
+ // all closures. Macros calling macros above for each oop size.
+ // Since ClassLoader objects have only a pointer to the loader_data, they are not
+--- ./hotspot/src/share/vm/oops/instanceKlass.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/instanceKlass.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -35,6 +35,7 @@
+ #include "jvmtifiles/jvmti.h"
+ #include "memory/genOopClosures.inline.hpp"
+ #include "memory/heapInspection.hpp"
++#include "memory/iterator.inline.hpp"
+ #include "memory/metadataFactory.hpp"
+ #include "memory/oopFactory.hpp"
+ #include "oops/fieldStreams.hpp"
+@@ -54,6 +55,7 @@
+ #include "runtime/handles.inline.hpp"
+ #include "runtime/javaCalls.hpp"
+ #include "runtime/mutexLocker.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/thread.inline.hpp"
+ #include "services/classLoadingService.hpp"
+ #include "services/threadService.hpp"
+@@ -64,7 +66,7 @@
+ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+ #include "gc_implementation/g1/g1OopClosures.inline.hpp"
+ #include "gc_implementation/g1/g1RemSet.inline.hpp"
+-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
++#include "gc_implementation/g1/heapRegionManager.inline.hpp"
+ #include "gc_implementation/parNew/parOopClosures.inline.hpp"
+ #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
+ #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
+@@ -287,6 +289,7 @@
+ set_static_oop_field_count(0);
+ set_nonstatic_field_size(0);
+ set_is_marked_dependent(false);
++ set_has_unloaded_dependent(false);
+ set_init_state(InstanceKlass::allocated);
+ set_init_thread(NULL);
+ set_reference_type(rt);
+@@ -501,6 +504,8 @@
+ oop InstanceKlass::init_lock() const {
+ // return the init lock from the mirror
+ oop lock = java_lang_Class::init_lock(java_mirror());
++ // Prevent reordering with any access of initialization state
++ OrderAccess::loadload();
+ assert((oop)lock != NULL || !is_not_initialized(), // initialized or in_error state
+ "only fully initialized state can have a null lock");
+ return lock;
+@@ -775,6 +780,41 @@
+ }
+ }
+
++// Eagerly initialize superinterfaces that declare default methods (concrete instance: any access)
++void InstanceKlass::initialize_super_interfaces(instanceKlassHandle this_oop, TRAPS) {
++ if (this_oop->has_default_methods()) {
++ for (int i = 0; i < this_oop->local_interfaces()->length(); ++i) {
++ Klass* iface = this_oop->local_interfaces()->at(i);
++ InstanceKlass* ik = InstanceKlass::cast(iface);
++ if (ik->should_be_initialized()) {
++ if (ik->has_default_methods()) {
++ ik->initialize_super_interfaces(ik, THREAD);
++ }
++ // Only initialize() interfaces that "declare" concrete methods.
++ // has_default_methods drives searching superinterfaces since it
++ // means has_default_methods in its superinterface hierarchy
++ if (!HAS_PENDING_EXCEPTION && ik->declares_default_methods()) {
++ ik->initialize(THREAD);
++ }
++ if (HAS_PENDING_EXCEPTION) {
++ Handle e(THREAD, PENDING_EXCEPTION);
++ CLEAR_PENDING_EXCEPTION;
++ {
++ EXCEPTION_MARK;
++ // Locks object, set state, and notify all waiting threads
++ this_oop->set_initialization_state_and_notify(
++ initialization_error, THREAD);
++
++ // ignore any exception thrown, superclass initialization error is
++ // thrown below
++ CLEAR_PENDING_EXCEPTION;
++ }
++ THROW_OOP(e());
++ }
++ }
++ }
++ }
++}
+
+ void InstanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) {
+ // Make sure klass is linked (verified) before initialization
+@@ -854,33 +894,11 @@
+ }
+ }
+
++ // Recursively initialize any superinterfaces that declare default methods
++ // Only need to recurse if has_default_methods which includes declaring and
++ // inheriting default methods
+ if (this_oop->has_default_methods()) {
+- // Step 7.5: initialize any interfaces which have default methods
+- for (int i = 0; i < this_oop->local_interfaces()->length(); ++i) {
+- Klass* iface = this_oop->local_interfaces()->at(i);
+- InstanceKlass* ik = InstanceKlass::cast(iface);
+- if (ik->has_default_methods() && ik->should_be_initialized()) {
+- ik->initialize(THREAD);
+-
+- if (HAS_PENDING_EXCEPTION) {
+- Handle e(THREAD, PENDING_EXCEPTION);
+- CLEAR_PENDING_EXCEPTION;
+- {
+- EXCEPTION_MARK;
+- // Locks object, set state, and notify all waiting threads
+- this_oop->set_initialization_state_and_notify(
+- initialization_error, THREAD);
+-
+- // ignore any exception thrown, superclass initialization error is
+- // thrown below
+- CLEAR_PENDING_EXCEPTION;
+- }
+- DTRACE_CLASSINIT_PROBE_WAIT(
+- super__failed, InstanceKlass::cast(this_oop()), -1, wait);
+- THROW_OOP(e());
+- }
+- }
+- }
++ this_oop->initialize_super_interfaces(this_oop, CHECK);
+ }
+
+ // Step 8
+@@ -1827,6 +1845,9 @@
+ return id;
+ }
+
++int nmethodBucket::decrement() {
++ return Atomic::add(-1, (volatile int *)&_count);
++}
+
+ //
+ // Walk the list of dependent nmethods searching for nmethods which
+@@ -1841,7 +1862,7 @@
+ nmethod* nm = b->get_nmethod();
+ // since dependencies aren't removed until an nmethod becomes a zombie,
+ // the dependency list may contain nmethods which aren't alive.
+- if (nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) {
++ if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) {
+ if (TraceDependencies) {
+ ResourceMark rm;
+ tty->print_cr("Marked for deoptimization");
+@@ -1858,6 +1879,43 @@
+ return found;
+ }
+
++void InstanceKlass::clean_dependent_nmethods() {
++ assert_locked_or_safepoint(CodeCache_lock);
++
++ if (has_unloaded_dependent()) {
++ nmethodBucket* b = _dependencies;
++ nmethodBucket* last = NULL;
++ while (b != NULL) {
++ assert(b->count() >= 0, err_msg("bucket count: %d", b->count()));
++
++ nmethodBucket* next = b->next();
++
++ if (b->count() == 0) {
++ if (last == NULL) {
++ _dependencies = next;
++ } else {
++ last->set_next(next);
++ }
++ delete b;
++ // last stays the same.
++ } else {
++ last = b;
++ }
++
++ b = next;
++ }
++ set_has_unloaded_dependent(false);
++ }
++#ifdef ASSERT
++ else {
++ // Verification
++ for (nmethodBucket* b = _dependencies; b != NULL; b = b->next()) {
++ assert(b->count() >= 0, err_msg("bucket count: %d", b->count()));
++ assert(b->count() != 0, "empty buckets need to be cleaned");
++ }
++ }
++#endif
++}
+
+ //
+ // Add an nmethodBucket to the list of dependencies for this nmethod.
+@@ -1892,13 +1950,10 @@
+ nmethodBucket* last = NULL;
+ while (b != NULL) {
+ if (nm == b->get_nmethod()) {
+- if (b->decrement() == 0) {
+- if (last == NULL) {
+- _dependencies = b->next();
+- } else {
+- last->set_next(b->next());
+- }
+- delete b;
++ int val = b->decrement();
++ guarantee(val >= 0, err_msg("Underflow: %d", val));
++ if (val == 0) {
++ set_has_unloaded_dependent(true);
+ }
+ return;
+ }
+@@ -1937,6 +1992,10 @@
+ nmethodBucket* b = _dependencies;
+ while (b != NULL) {
+ if (nm == b->get_nmethod()) {
++#ifdef ASSERT
++ int count = b->count();
++ assert(count >= 0, err_msg("count shouldn't be negative: %d", count));
++#endif
+ return true;
+ }
+ b = b->next();
+@@ -2141,12 +2200,6 @@
+ // closure's do_metadata() method dictates whether the given closure should be
+ // applied to the klass ptr in the object header.
+
+-#define if_do_metadata_checked(closure, nv_suffix) \
+- /* Make sure the non-virtual and the virtual versions match. */ \
+- assert(closure->do_metadata##nv_suffix() == closure->do_metadata(), \
+- "Inconsistency in do_metadata"); \
+- if (closure->do_metadata##nv_suffix())
+-
+ #define InstanceKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \
+ \
+ int InstanceKlass::oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \
+@@ -2170,10 +2223,9 @@
+ int InstanceKlass::oop_oop_iterate_backwards##nv_suffix(oop obj, \
+ OopClosureType* closure) { \
+ SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik); \
+- /* header */ \
+- if_do_metadata_checked(closure, nv_suffix) { \
+- closure->do_klass##nv_suffix(obj->klass()); \
+- } \
++ \
++ assert_should_ignore_metadata(closure, nv_suffix); \
++ \
+ /* instance variables */ \
+ InstanceKlass_OOP_MAP_REVERSE_ITERATE( \
+ obj, \
+@@ -2242,7 +2294,7 @@
+ #endif // INCLUDE_ALL_GCS
+
+ void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) {
+- assert(is_loader_alive(is_alive), "this klass should be live");
++ assert(class_loader_data()->is_alive(is_alive), "this klass should be live");
+ if (is_interface()) {
+ if (ClassUnloading) {
+ Klass* impl = implementor();
+@@ -2294,12 +2346,14 @@
+ array_klasses_do(remove_unshareable_in_class);
+ }
+
+-void restore_unshareable_in_class(Klass* k, TRAPS) {
+- k->restore_unshareable_info(CHECK);
++static void restore_unshareable_in_class(Klass* k, TRAPS) {
++ // Array classes have null protection domain.
++ // --> see ArrayKlass::complete_create_array_klass()
++ k->restore_unshareable_info(ClassLoaderData::the_null_class_loader_data(), Handle(), CHECK);
+ }
+
+-void InstanceKlass::restore_unshareable_info(TRAPS) {
+- Klass::restore_unshareable_info(CHECK);
++void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
++ Klass::restore_unshareable_info(loader_data, protection_domain, CHECK);
+ instanceKlassHandle ik(THREAD, this);
+
+ Array<Method*>* methods = ik->methods();
+@@ -2325,6 +2379,38 @@
+ ik->array_klasses_do(restore_unshareable_in_class, CHECK);
+ }
+
++// returns true IFF is_in_error_state() has been changed as a result of this call.
++bool InstanceKlass::check_sharing_error_state() {
++ assert(DumpSharedSpaces, "should only be called during dumping");
++ bool old_state = is_in_error_state();
++
++ if (!is_in_error_state()) {
++ bool bad = false;
++ for (InstanceKlass* sup = java_super(); sup; sup = sup->java_super()) {
++ if (sup->is_in_error_state()) {
++ bad = true;
++ break;
++ }
++ }
++ if (!bad) {
++ Array<Klass*>* interfaces = transitive_interfaces();
++ for (int i = 0; i < interfaces->length(); i++) {
++ Klass* iface = interfaces->at(i);
++ if (InstanceKlass::cast(iface)->is_in_error_state()) {
++ bad = true;
++ break;
++ }
++ }
++ }
++
++ if (bad) {
++ set_in_error_state();
++ }
++ }
++
++ return (old_state != is_in_error_state());
++}
++
+ static void clear_all_breakpoints(Method* m) {
+ m->clear_all_breakpoints();
+ }
+@@ -2814,6 +2900,22 @@
+ OsrList_lock->unlock();
+ }
+
++int InstanceKlass::mark_osr_nmethods(const Method* m) {
++ // This is a short non-blocking critical region, so the no safepoint check is ok.
++ MutexLockerEx ml(OsrList_lock, Mutex::_no_safepoint_check_flag);
++ nmethod* osr = osr_nmethods_head();
++ int found = 0;
++ while (osr != NULL) {
++ assert(osr->is_osr_method(), "wrong kind of nmethod found in chain");
++ if (osr->method() == m) {
++ osr->mark_for_deoptimization();
++ found++;
++ }
++ osr = osr->osr_link();
++ }
++ return found;
++}
++
+ nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_level, bool match_level) const {
+ // This is a short non-blocking critical region, so the no safepoint check is ok.
+ OsrList_lock->lock_without_safepoint_check();
+@@ -2855,28 +2957,27 @@
+ return NULL;
+ }
+
+-void InstanceKlass::add_member_name(int index, Handle mem_name) {
++bool InstanceKlass::add_member_name(Handle mem_name) {
+ jweak mem_name_wref = JNIHandles::make_weak_global(mem_name);
+ MutexLocker ml(MemberNameTable_lock);
+- assert(0 <= index && index < idnum_allocated_count(), "index is out of bounds");
+ DEBUG_ONLY(No_Safepoint_Verifier nsv);
+
++ // Check if method has been redefined while taking out MemberNameTable_lock, if so
++ // return false. We cannot cache obsolete methods. They will crash when the function
++ // is called!
++ Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mem_name());
++ if (method->is_obsolete()) {
++ return false;
++ } else if (method->is_old()) {
++ // Replace method with redefined version
++ java_lang_invoke_MemberName::set_vmtarget(mem_name(), method_with_idnum(method->method_idnum()));
++ }
++
+ if (_member_names == NULL) {
+ _member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable(idnum_allocated_count());
+ }
+- _member_names->add_member_name(index, mem_name_wref);
+-}
+-
+-oop InstanceKlass::get_member_name(int index) {
+- MutexLocker ml(MemberNameTable_lock);
+- assert(0 <= index && index < idnum_allocated_count(), "index is out of bounds");
+- DEBUG_ONLY(No_Safepoint_Verifier nsv);
+-
+- if (_member_names == NULL) {
+- return NULL;
+- }
+- oop mem_name =_member_names->get_member_name(index);
+- return mem_name;
++ _member_names->add_member_name(mem_name_wref);
++ return true;
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+@@ -3051,8 +3152,7 @@
+ offset <= (juint) value->length() &&
+ offset + length <= (juint) value->length()) {
+ st->print(BULLET"string: ");
+- Handle h_obj(obj);
+- java_lang_String::print(h_obj, st);
++ java_lang_String::print(obj, st);
+ st->cr();
+ if (!WizardMode) return; // that is enough
+ }
+--- ./hotspot/src/share/vm/oops/instanceKlass.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/instanceKlass.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -226,14 +226,16 @@
+ // _is_marked_dependent can be set concurrently, thus cannot be part of the
+ // _misc_flags.
+ bool _is_marked_dependent; // used for marking during flushing and deoptimization
++ bool _has_unloaded_dependent;
+
+ enum {
+- _misc_rewritten = 1 << 0, // methods rewritten.
+- _misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops
+- _misc_should_verify_class = 1 << 2, // allow caching of preverification
+- _misc_is_anonymous = 1 << 3, // has embedded _host_klass field
+- _misc_is_contended = 1 << 4, // marked with contended annotation
+- _misc_has_default_methods = 1 << 5 // class/superclass/implemented interfaces has default methods
++ _misc_rewritten = 1 << 0, // methods rewritten.
++ _misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops
++ _misc_should_verify_class = 1 << 2, // allow caching of preverification
++ _misc_is_anonymous = 1 << 3, // has embedded _host_klass field
++ _misc_is_contended = 1 << 4, // marked with contended annotation
++ _misc_has_default_methods = 1 << 5, // class/superclass/implemented interfaces has default methods
++ _misc_declares_default_methods = 1 << 6 // directly declares default methods (any access)
+ };
+ u2 _misc_flags;
+ u2 _minor_version; // minor version number of class file
+@@ -473,6 +475,9 @@
+ bool is_marked_dependent() const { return _is_marked_dependent; }
+ void set_is_marked_dependent(bool value) { _is_marked_dependent = value; }
+
++ bool has_unloaded_dependent() const { return _has_unloaded_dependent; }
++ void set_has_unloaded_dependent(bool value) { _has_unloaded_dependent = value; }
++
+ // initialization (virtuals from Klass)
+ bool should_be_initialized() const; // means that initialize should be called
+ void initialize(TRAPS);
+@@ -682,6 +687,17 @@
+ }
+ }
+
++ bool declares_default_methods() const {
++ return (_misc_flags & _misc_declares_default_methods) != 0;
++ }
++ void set_declares_default_methods(bool b) {
++ if (b) {
++ _misc_flags |= _misc_declares_default_methods;
++ } else {
++ _misc_flags &= ~_misc_declares_default_methods;
++ }
++ }
++
+ // for adding methods, ConstMethod::UNSET_IDNUM means no more ids available
+ inline u2 next_method_idnum();
+ void set_initial_method_idnum(u2 value) { _idnum_allocated_count = value; }
+@@ -773,6 +789,7 @@
+ void set_osr_nmethods_head(nmethod* h) { _osr_nmethods_head = h; };
+ void add_osr_nmethod(nmethod* n);
+ void remove_osr_nmethod(nmethod* n);
++ int mark_osr_nmethods(const Method* m);
+ nmethod* lookup_osr_nmethod(const Method* m, int bci, int level, bool match_level) const;
+
+ // Breakpoint support (see methods on Method* for details)
+@@ -952,6 +969,7 @@
+
+ void clean_implementors_list(BoolObjectClosure* is_alive);
+ void clean_method_data(BoolObjectClosure* is_alive);
++ void clean_dependent_nmethods();
+
+ // Explicit metaspace deallocation of fields
+ // For RedefineClasses and class file parsing errors, we need to deallocate
+@@ -1005,6 +1023,13 @@
+
+ u2 idnum_allocated_count() const { return _idnum_allocated_count; }
+
++public:
++ void set_in_error_state() {
++ assert(DumpSharedSpaces, "only call this when dumping archive");
++ _init_state = initialization_error;
++ }
++ bool check_sharing_error_state();
++
+ private:
+ // initialization state
+ #ifdef ASSERT
+@@ -1040,6 +1065,7 @@
+ static bool link_class_impl (instanceKlassHandle this_oop, bool throw_verifyerror, TRAPS);
+ static bool verify_code (instanceKlassHandle this_oop, bool throw_verifyerror, TRAPS);
+ static void initialize_impl (instanceKlassHandle this_oop, TRAPS);
++ static void initialize_super_interfaces (instanceKlassHandle this_oop, TRAPS);
+ static void eager_initialize_impl (instanceKlassHandle this_oop);
+ static void set_initialization_state_and_notify_impl (instanceKlassHandle this_oop, ClassState state, TRAPS);
+ static void call_class_initializer_impl (instanceKlassHandle this_oop, TRAPS);
+@@ -1063,7 +1089,7 @@
+ public:
+ // CDS support - remove and restore oops from metadata. Oops are not shared.
+ virtual void remove_unshareable_info();
+- virtual void restore_unshareable_info(TRAPS);
++ virtual void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
+
+ // jvm support
+ jint compute_modifier_flags(TRAPS) const;
+@@ -1071,8 +1097,7 @@
+ // JSR-292 support
+ MemberNameTable* member_names() { return _member_names; }
+ void set_member_names(MemberNameTable* member_names) { _member_names = member_names; }
+- void add_member_name(int index, Handle member_name);
+- oop get_member_name(int index);
++ bool add_member_name(Handle member_name);
+
+ public:
+ // JVMTI support
+@@ -1240,7 +1265,7 @@
+ }
+ int count() { return _count; }
+ int increment() { _count += 1; return _count; }
+- int decrement() { _count -= 1; assert(_count >= 0, "don't underflow"); return _count; }
++ int decrement();
+ nmethodBucket* next() { return _next; }
+ void set_next(nmethodBucket* b) { _next = b; }
+ nmethod* get_nmethod() { return _nmethod; }
+--- ./hotspot/src/share/vm/oops/instanceMirrorKlass.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/instanceMirrorKlass.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,6 +28,7 @@
+ #include "gc_implementation/shared/markSweep.inline.hpp"
+ #include "gc_interface/collectedHeap.inline.hpp"
+ #include "memory/genOopClosures.inline.hpp"
++#include "memory/iterator.inline.hpp"
+ #include "memory/oopFactory.hpp"
+ #include "oops/instanceKlass.hpp"
+ #include "oops/instanceMirrorKlass.hpp"
+@@ -41,7 +42,7 @@
+ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+ #include "gc_implementation/g1/g1OopClosures.inline.hpp"
+ #include "gc_implementation/g1/g1RemSet.inline.hpp"
+-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
++#include "gc_implementation/g1/heapRegionManager.inline.hpp"
+ #include "gc_implementation/parNew/parOopClosures.inline.hpp"
+ #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
+ #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
+@@ -241,12 +242,6 @@
+ return oop_size(obj); \
+
+
+-#define if_do_metadata_checked(closure, nv_suffix) \
+- /* Make sure the non-virtual and the virtual versions match. */ \
+- assert(closure->do_metadata##nv_suffix() == closure->do_metadata(), \
+- "Inconsistency in do_metadata"); \
+- if (closure->do_metadata##nv_suffix())
+-
+ // Macro to define InstanceMirrorKlass::oop_oop_iterate for virtual/nonvirtual for
+ // all closures. Macros calling macros above for each oop size.
+
+--- ./hotspot/src/share/vm/oops/instanceRefKlass.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/instanceRefKlass.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -38,7 +38,7 @@
+ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+ #include "gc_implementation/g1/g1OopClosures.inline.hpp"
+ #include "gc_implementation/g1/g1RemSet.inline.hpp"
+-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
++#include "gc_implementation/g1/heapRegionManager.inline.hpp"
+ #include "gc_implementation/parNew/parOopClosures.inline.hpp"
+ #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
+ #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
+--- ./hotspot/src/share/vm/oops/klass.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/klass.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -36,11 +36,13 @@
+ #include "oops/instanceKlass.hpp"
+ #include "oops/klass.inline.hpp"
+ #include "oops/oop.inline2.hpp"
+-#include "runtime/atomic.hpp"
++#include "runtime/atomic.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "trace/traceMacros.hpp"
+ #include "utilities/stack.hpp"
+ #include "utilities/macros.hpp"
+ #if INCLUDE_ALL_GCS
++#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
+ #include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
+ #include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
+ #include "gc_implementation/parallelScavenge/psScavenge.hpp"
+@@ -167,7 +169,12 @@
+ _primary_supers[0] = k;
+ set_super_check_offset(in_bytes(primary_supers_offset()));
+
+- set_java_mirror(NULL);
++ // The constructor is used from init_self_patching_vtbl_list,
++ // which doesn't zero out the memory before calling the constructor.
++ // Need to set the field explicitly to not hit an assert that the field
++ // should be NULL before setting it.
++ _java_mirror = NULL;
++
+ set_modifier_flags(0);
+ set_layout_helper(Klass::_lh_neutral_value);
+ set_name(NULL);
+@@ -186,6 +193,7 @@
+ // The klass doesn't have any references at this point.
+ clear_modified_oops();
+ clear_accumulated_modified_oops();
++ _shared_class_path_index = -1;
+ }
+
+ jint Klass::array_layout_helper(BasicType etype) {
+@@ -399,7 +407,7 @@
+ return mirror_alive;
+ }
+
+-void Klass::clean_weak_klass_links(BoolObjectClosure* is_alive) {
++void Klass::clean_weak_klass_links(BoolObjectClosure* is_alive, bool clean_alive_klasses) {
+ if (!ClassUnloading) {
+ return;
+ }
+@@ -444,7 +452,7 @@
+ }
+
+ // Clean the implementors list and method data.
+- if (current->oop_is_instance()) {
++ if (clean_alive_klasses && current->oop_is_instance()) {
+ InstanceKlass* ik = InstanceKlass::cast(current);
+ ik->clean_implementors_list(is_alive);
+ ik->clean_method_data(is_alive);
+@@ -456,12 +464,18 @@
+ record_modified_oops();
+ }
+
+-void Klass::klass_update_barrier_set_pre(void* p, oop v) {
+- // This barrier used by G1, where it's used remember the old oop values,
+- // so that we don't forget any objects that were live at the snapshot at
+- // the beginning. This function is only used when we write oops into
+- // Klasses. Since the Klasses are used as roots in G1, we don't have to
+- // do anything here.
++// This barrier is used by G1 to remember the old oop values, so
++// that we don't forget any objects that were live at the snapshot at
++// the beginning. This function is only used when we write oops into Klasses.
++void Klass::klass_update_barrier_set_pre(oop* p, oop v) {
++#if INCLUDE_ALL_GCS
++ if (UseG1GC) {
++ oop obj = *p;
++ if (obj != NULL) {
++ G1SATBCardTableModRefBS::enqueue(obj);
++ }
++ }
++#endif
+ }
+
+ void Klass::klass_oop_store(oop* p, oop v) {
+@@ -472,7 +486,7 @@
+ if (always_do_update_barrier) {
+ klass_oop_store((volatile oop*)p, v);
+ } else {
+- klass_update_barrier_set_pre((void*)p, v);
++ klass_update_barrier_set_pre(p, v);
+ *p = v;
+ klass_update_barrier_set(v);
+ }
+@@ -482,7 +496,7 @@
+ assert(!Universe::heap()->is_in_reserved((void*)p), "Should store pointer into metadata");
+ assert(v == NULL || Universe::heap()->is_in_reserved((void*)v), "Should store pointer to an object");
+
+- klass_update_barrier_set_pre((void*)p, v);
++ klass_update_barrier_set_pre((oop*)p, v); // Cast away volatile.
+ OrderAccess::release_store_ptr(p, v);
+ klass_update_barrier_set(v);
+ }
+@@ -504,27 +518,25 @@
+ set_class_loader_data(NULL);
+ }
+
+-void Klass::restore_unshareable_info(TRAPS) {
++void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
+ TRACE_INIT_ID(this);
+ // If an exception happened during CDS restore, some of these fields may already be
+ // set. We leave the class on the CLD list, even if incomplete so that we don't
+ // modify the CLD list outside a safepoint.
+ if (class_loader_data() == NULL) {
+- ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
+- // Restore class_loader_data to the null class loader data
++ // Restore class_loader_data
+ set_class_loader_data(loader_data);
+
+- // Add to null class loader list first before creating the mirror
++ // Add to class loader list first before creating the mirror
+ // (same order as class file parsing)
+ loader_data->add_class(this);
+ }
+
+- // Recreate the class mirror. The protection_domain is always null for
+- // boot loader, for now.
++ // Recreate the class mirror.
+ // Only recreate it if not present. A previous attempt to restore may have
+ // gotten an OOM later but keep the mirror if it was created.
+ if (java_mirror() == NULL) {
+- java_lang_Class::create_mirror(this, Handle(NULL), CHECK);
++ java_lang_Class::create_mirror(this, class_loader(), protection_domain, CHECK);
+ }
+ }
+
+@@ -707,3 +719,21 @@
+ }
+
+ #endif
++
++/////////////// Unit tests ///////////////
++
++#ifndef PRODUCT
++
++class TestKlass {
++ public:
++ static void test_oop_is_instanceClassLoader() {
++ assert(SystemDictionary::ClassLoader_klass()->oop_is_instanceClassLoader(), "assert");
++ assert(!SystemDictionary::String_klass()->oop_is_instanceClassLoader(), "assert");
++ }
++};
++
++void TestKlass_test() {
++ TestKlass::test_oop_is_instanceClassLoader();
++}
++
++#endif
+--- ./hotspot/src/share/vm/oops/klass.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/klass.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -32,7 +32,6 @@
+ #include "oops/klassPS.hpp"
+ #include "oops/metadata.hpp"
+ #include "oops/oop.hpp"
+-#include "runtime/orderAccess.hpp"
+ #include "trace/traceMacros.hpp"
+ #include "utilities/accessFlags.hpp"
+ #include "utilities/macros.hpp"
+@@ -177,6 +176,16 @@
+ jbyte _modified_oops; // Card Table Equivalent (YC/CMS support)
+ jbyte _accumulated_modified_oops; // Mod Union Equivalent (CMS support)
+
++private:
++ // This is an index into FileMapHeader::_classpath_entry_table[], to
++ // associate this class with the JAR file where it's loaded from during
++ // dump time. If a class is not loaded from the shared archive, this field is
++ // -1.
++ jshort _shared_class_path_index;
++
++ friend class SharedClassUtil;
++protected:
++
+ // Constructor
+ Klass();
+
+@@ -283,6 +292,15 @@
+ void clear_accumulated_modified_oops() { _accumulated_modified_oops = 0; }
+ bool has_accumulated_modified_oops() { return _accumulated_modified_oops == 1; }
+
++ int shared_classpath_index() const {
++ return _shared_class_path_index;
++ };
++
++ void set_shared_classpath_index(int index) {
++ _shared_class_path_index = index;
++ };
++
++
+ protected: // internal accessors
+ Klass* subklass_oop() const { return _subklass; }
+ Klass* next_sibling_oop() const { return _next_sibling; }
+@@ -455,7 +473,7 @@
+ public:
+ // CDS support - remove and restore oops from metadata. Oops are not shared.
+ virtual void remove_unshareable_info();
+- virtual void restore_unshareable_info(TRAPS);
++ virtual void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
+
+ protected:
+ // computes the subtype relationship
+@@ -502,6 +520,7 @@
+ virtual bool oop_is_objArray_slow() const { return false; }
+ virtual bool oop_is_typeArray_slow() const { return false; }
+ public:
++ virtual bool oop_is_instanceClassLoader() const { return false; }
+ virtual bool oop_is_instanceMirror() const { return false; }
+ virtual bool oop_is_instanceRef() const { return false; }
+
+@@ -585,36 +604,9 @@
+ // The is_alive closure passed in depends on the Garbage Collector used.
+ bool is_loader_alive(BoolObjectClosure* is_alive);
+
+- static void clean_weak_klass_links(BoolObjectClosure* is_alive);
+-
+- // Prefetch within oop iterators. This is a macro because we
+- // can't guarantee that the compiler will inline it. In 64-bit
+- // it generally doesn't. Signature is
+- //
+- // static void prefetch_beyond(oop* const start,
+- // oop* const end,
+- // const intx foffset,
+- // const Prefetch::style pstyle);
+-#define prefetch_beyond(start, end, foffset, pstyle) { \
+- const intx foffset_ = (foffset); \
+- const Prefetch::style pstyle_ = (pstyle); \
+- assert(foffset_ > 0, "prefetch beyond, not behind"); \
+- if (pstyle_ != Prefetch::do_none) { \
+- oop* ref = (start); \
+- if (ref < (end)) { \
+- switch (pstyle_) { \
+- case Prefetch::do_read: \
+- Prefetch::read(*ref, foffset_); \
+- break; \
+- case Prefetch::do_write: \
+- Prefetch::write(*ref, foffset_); \
+- break; \
+- default: \
+- ShouldNotReachHere(); \
+- break; \
+- } \
+- } \
+- } \
++ static void clean_weak_klass_links(BoolObjectClosure* is_alive, bool clean_alive_klasses = true);
++ static void clean_subklass_tree(BoolObjectClosure* is_alive) {
++ clean_weak_klass_links(is_alive, false /* clean_alive_klasses */);
+ }
+
+ // iterators
+@@ -722,7 +714,7 @@
+ private:
+ // barriers used by klass_oop_store
+ void klass_update_barrier_set(oop v);
+- void klass_update_barrier_set_pre(void* p, oop v);
++ void klass_update_barrier_set_pre(oop* p, oop v);
+ };
+
+ #endif // SHARE_VM_OOPS_KLASS_HPP
+--- ./hotspot/src/share/vm/oops/method.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/method.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -49,6 +49,7 @@
+ #include "runtime/compilationPolicy.hpp"
+ #include "runtime/frame.inline.hpp"
+ #include "runtime/handles.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/relocator.hpp"
+ #include "runtime/sharedRuntime.hpp"
+ #include "runtime/signature.hpp"
+@@ -92,7 +93,7 @@
+ set_hidden(false);
+ set_dont_inline(false);
+ set_method_data(NULL);
+- set_method_counters(NULL);
++ clear_method_counters();
+ set_vtable_index(Method::garbage_vtable_index);
+
+ // Fix and bury in Method*
+@@ -116,7 +117,7 @@
+ MetadataFactory::free_metadata(loader_data, method_data());
+ set_method_data(NULL);
+ MetadataFactory::free_metadata(loader_data, method_counters());
+- set_method_counters(NULL);
++ clear_method_counters();
+ // The nmethod will be gone when we get here.
+ if (code() != NULL) _code = NULL;
+ }
+@@ -387,9 +388,7 @@
+ methodHandle mh(m);
+ ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
+ MethodCounters* counters = MethodCounters::allocate(loader_data, CHECK_NULL);
+- if (mh->method_counters() == NULL) {
+- mh->set_method_counters(counters);
+- } else {
++ if (!mh->init_method_counters(counters)) {
+ MetadataFactory::free_metadata(loader_data, counters);
+ }
+ return mh->method_counters();
+@@ -559,6 +558,15 @@
+ return true;
+ }
+
++bool Method::is_constant_getter() const {
++ int last_index = code_size() - 1;
++ // Check if the first 1-3 bytecodes are a constant push
++ // and the last bytecode is a return.
++ return (2 <= code_size() && code_size() <= 4 &&
++ Bytecodes::is_const(java_code_at(0)) &&
++ Bytecodes::length_for(java_code_at(0)) == last_index &&
++ Bytecodes::is_return(java_code_at(last_index)));
++}
+
+ bool Method::is_initializer() const {
+ return name() == vmSymbols::object_initializer_name() || is_static_initializer();
+@@ -730,8 +738,8 @@
+ }
+ if ((TraceDeoptimization || LogCompilation) && (xtty != NULL)) {
+ ttyLocker ttyl;
+- xtty->begin_elem("make_not_%scompilable thread='" UINTX_FORMAT "'",
+- is_osr ? "osr_" : "", os::current_thread_id());
++ xtty->begin_elem("make_not_compilable thread='" UINTX_FORMAT "' osr='%d' level='%d'",
++ os::current_thread_id(), is_osr, comp_level);
+ if (reason != NULL) {
+ xtty->print(" reason=\'%s\'", reason);
+ }
+@@ -851,7 +859,7 @@
+ assert(!DumpSharedSpaces || _method_data == NULL, "unexpected method data?");
+
+ set_method_data(NULL);
+- set_method_counters(NULL);
++ clear_method_counters();
+ }
+
+ // Called when the method_holder is getting linked. Setup entrypoints so the method
+@@ -1635,34 +1643,34 @@
+ }
+
+ int Method::highest_comp_level() const {
+- const MethodData* mdo = method_data();
+- if (mdo != NULL) {
+- return mdo->highest_comp_level();
++ const MethodCounters* mcs = method_counters();
++ if (mcs != NULL) {
++ return mcs->highest_comp_level();
+ } else {
+ return CompLevel_none;
+ }
+ }
+
+ int Method::highest_osr_comp_level() const {
+- const MethodData* mdo = method_data();
+- if (mdo != NULL) {
+- return mdo->highest_osr_comp_level();
++ const MethodCounters* mcs = method_counters();
++ if (mcs != NULL) {
++ return mcs->highest_osr_comp_level();
+ } else {
+ return CompLevel_none;
+ }
+ }
+
+ void Method::set_highest_comp_level(int level) {
+- MethodData* mdo = method_data();
+- if (mdo != NULL) {
+- mdo->set_highest_comp_level(level);
++ MethodCounters* mcs = method_counters();
++ if (mcs != NULL) {
++ mcs->set_highest_comp_level(level);
+ }
+ }
+
+ void Method::set_highest_osr_comp_level(int level) {
+- MethodData* mdo = method_data();
+- if (mdo != NULL) {
+- mdo->set_highest_osr_comp_level(level);
++ MethodCounters* mcs = method_counters();
++ if (mcs != NULL) {
++ mcs->set_highest_osr_comp_level(level);
+ }
+ }
+
+@@ -1864,9 +1872,12 @@
+ void Method::set_on_stack(const bool value) {
+ // Set both the method itself and its constant pool. The constant pool
+ // on stack means some method referring to it is also on the stack.
+- _access_flags.set_on_stack(value);
+ constants()->set_on_stack(value);
+- if (value) MetadataOnStackMark::record(this);
++
++ bool succeeded = _access_flags.set_on_stack(value);
++ if (value && succeeded) {
++ MetadataOnStackMark::record(this, Thread::current());
++ }
+ }
+
+ // Called when the class loader is unloaded to make all methods weak.
+--- ./hotspot/src/share/vm/oops/method.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/method.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -233,10 +233,11 @@
+ // Tracking number of breakpoints, for fullspeed debugging.
+ // Only mutated by VM thread.
+ u2 number_of_breakpoints() const {
+- if (method_counters() == NULL) {
++ MethodCounters* mcs = method_counters();
++ if (mcs == NULL) {
+ return 0;
+ } else {
+- return method_counters()->number_of_breakpoints();
++ return mcs->number_of_breakpoints();
+ }
+ }
+ void incr_number_of_breakpoints(TRAPS) {
+@@ -253,8 +254,9 @@
+ }
+ // Initialization only
+ void clear_number_of_breakpoints() {
+- if (method_counters() != NULL) {
+- method_counters()->clear_number_of_breakpoints();
++ MethodCounters* mcs = method_counters();
++ if (mcs != NULL) {
++ mcs->clear_number_of_breakpoints();
+ }
+ }
+
+@@ -301,10 +303,11 @@
+ }
+
+ int interpreter_throwout_count() const {
+- if (method_counters() == NULL) {
++ MethodCounters* mcs = method_counters();
++ if (mcs == NULL) {
+ return 0;
+ } else {
+- return method_counters()->interpreter_throwout_count();
++ return mcs->interpreter_throwout_count();
+ }
+ }
+
+@@ -362,11 +365,13 @@
+ return _method_counters;
+ }
+
+- void set_method_counters(MethodCounters* counters) {
+- // The store into method must be released. On platforms without
+- // total store order (TSO) the reference may become visible before
+- // the initialization of data otherwise.
+- OrderAccess::release_store_ptr((volatile void *)&_method_counters, counters);
++ void clear_method_counters() {
++ _method_counters = NULL;
++ }
++
++ bool init_method_counters(MethodCounters* counters) {
++ // Try to install a pointer to MethodCounters, return true on success.
++ return Atomic::cmpxchg_ptr(counters, (volatile void*)&_method_counters, NULL) == NULL;
+ }
+
+ #ifdef TIERED
+@@ -379,26 +384,28 @@
+ return method_counters()->interpreter_invocation_count();
+ }
+ }
+- void set_prev_event_count(int count, TRAPS) {
+- MethodCounters* mcs = get_method_counters(CHECK);
++ void set_prev_event_count(int count) {
++ MethodCounters* mcs = method_counters();
+ if (mcs != NULL) {
+ mcs->set_interpreter_invocation_count(count);
+ }
+ }
+ jlong prev_time() const {
+- return method_counters() == NULL ? 0 : method_counters()->prev_time();
++ MethodCounters* mcs = method_counters();
++ return mcs == NULL ? 0 : mcs->prev_time();
+ }
+- void set_prev_time(jlong time, TRAPS) {
+- MethodCounters* mcs = get_method_counters(CHECK);
++ void set_prev_time(jlong time) {
++ MethodCounters* mcs = method_counters();
+ if (mcs != NULL) {
+ mcs->set_prev_time(time);
+ }
+ }
+ float rate() const {
+- return method_counters() == NULL ? 0 : method_counters()->rate();
++ MethodCounters* mcs = method_counters();
++ return mcs == NULL ? 0 : mcs->rate();
+ }
+- void set_rate(float rate, TRAPS) {
+- MethodCounters* mcs = get_method_counters(CHECK);
++ void set_rate(float rate) {
++ MethodCounters* mcs = method_counters();
+ if (mcs != NULL) {
+ mcs->set_rate(rate);
+ }
+@@ -416,9 +423,12 @@
+ static MethodCounters* build_method_counters(Method* m, TRAPS);
+
+ int interpreter_invocation_count() {
+- if (TieredCompilation) return invocation_count();
+- else return (method_counters() == NULL) ? 0 :
+- method_counters()->interpreter_invocation_count();
++ if (TieredCompilation) {
++ return invocation_count();
++ } else {
++ MethodCounters* mcs = method_counters();
++ return (mcs == NULL) ? 0 : mcs->interpreter_invocation_count();
++ }
+ }
+ int increment_interpreter_invocation_count(TRAPS) {
+ if (TieredCompilation) ShouldNotReachHere();
+@@ -609,6 +619,9 @@
+ // returns true if the method is an accessor function (setter/getter).
+ bool is_accessor() const;
+
++ // returns true if the method does nothing but return a constant of primitive type
++ bool is_constant_getter() const;
++
+ // returns true if the method is an initializer (<init> or <clinit>).
+ bool is_initializer() const;
+
+@@ -783,6 +796,10 @@
+ return method_holder()->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL;
+ }
+
++ int mark_osr_nmethods() {
++ return method_holder()->mark_osr_nmethods(this);
++ }
++
+ nmethod* lookup_osr_nmethod_for(int bci, int level, bool match_level) {
+ return method_holder()->lookup_osr_nmethod(this, bci, level, match_level);
+ }
+--- ./hotspot/src/share/vm/oops/methodCounters.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/methodCounters.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -34,4 +34,40 @@
+ backedge_counter()->reset();
+ set_interpreter_throwout_count(0);
+ set_interpreter_invocation_count(0);
++#ifdef TIERED
++ set_prev_time(0);
++ set_rate(0);
++ set_highest_comp_level(0);
++ set_highest_osr_comp_level(0);
++#endif
+ }
++
++
++int MethodCounters::highest_comp_level() const {
++#ifdef TIERED
++ return _highest_comp_level;
++#else
++ return CompLevel_none;
++#endif
++}
++
++void MethodCounters::set_highest_comp_level(int level) {
++#ifdef TIERED
++ _highest_comp_level = level;
++#endif
++}
++
++int MethodCounters::highest_osr_comp_level() const {
++#ifdef TIERED
++ return _highest_osr_comp_level;
++#else
++ return CompLevel_none;
++#endif
++}
++
++void MethodCounters::set_highest_osr_comp_level(int level) {
++#ifdef TIERED
++ _highest_osr_comp_level = level;
++#endif
++}
++
+--- ./hotspot/src/share/vm/oops/methodCounters.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/methodCounters.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -39,6 +39,8 @@
+
+ #ifdef TIERED
+ float _rate; // Events (invocation and backedge counter increments) per millisecond
++ u1 _highest_comp_level; // Highest compile level this method has ever seen.
++ u1 _highest_osr_comp_level; // Same for OSR level
+ jlong _prev_time; // Previous time the rate was acquired
+ #endif
+
+@@ -47,6 +49,8 @@
+ _number_of_breakpoints(0)
+ #ifdef TIERED
+ , _rate(0),
++ _highest_comp_level(0),
++ _highest_osr_comp_level(0),
+ _prev_time(0)
+ #endif
+ {
+@@ -100,6 +104,11 @@
+ void set_rate(float rate) { _rate = rate; }
+ #endif
+
++ int highest_comp_level() const;
++ void set_highest_comp_level(int level);
++ int highest_osr_comp_level() const;
++ void set_highest_osr_comp_level(int level);
++
+ // invocation counter
+ InvocationCounter* invocation_counter() { return &_invocation_counter; }
+ InvocationCounter* backedge_counter() { return &_backedge_counter; }
+--- ./hotspot/src/share/vm/oops/methodData.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/methodData.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -34,6 +34,7 @@
+ #include "runtime/compilationPolicy.hpp"
+ #include "runtime/deoptimization.hpp"
+ #include "runtime/handles.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+
+ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+
+@@ -1152,9 +1153,7 @@
+ _backedge_counter_start = 0;
+ _num_loops = 0;
+ _num_blocks = 0;
+- _highest_comp_level = 0;
+- _highest_osr_comp_level = 0;
+- _would_profile = true;
++ _would_profile = unknown;
+
+ #if INCLUDE_RTM_OPT
+ _rtm_state = NoRTM; // No RTM lock eliding by default
+--- ./hotspot/src/share/vm/oops/methodData.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/methodData.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -2057,7 +2057,7 @@
+
+ // Whole-method sticky bits and flags
+ enum {
+- _trap_hist_limit = 19, // decoupled from Deoptimization::Reason_LIMIT
++ _trap_hist_limit = 20, // decoupled from Deoptimization::Reason_LIMIT
+ _trap_hist_mask = max_jubyte,
+ _extra_data_count = 4 // extra DataLayout headers, for trap history
+ }; // Public flag values
+@@ -2098,12 +2098,9 @@
+ // time with C1. It is used to determine if method is trivial.
+ short _num_loops;
+ short _num_blocks;
+- // Highest compile level this method has ever seen.
+- u1 _highest_comp_level;
+- // Same for OSR level
+- u1 _highest_osr_comp_level;
+ // Does this method contain anything worth profiling?
+- bool _would_profile;
++ enum WouldProfile {unknown, no_profile, profile};
++ WouldProfile _would_profile;
+
+ // Size of _data array in bytes. (Excludes header and extra_data fields.)
+ int _data_size;
+@@ -2272,13 +2269,8 @@
+ }
+ #endif
+
+- void set_would_profile(bool p) { _would_profile = p; }
+- bool would_profile() const { return _would_profile; }
+-
+- int highest_comp_level() const { return _highest_comp_level; }
+- void set_highest_comp_level(int level) { _highest_comp_level = level; }
+- int highest_osr_comp_level() const { return _highest_osr_comp_level; }
+- void set_highest_osr_comp_level(int level) { _highest_osr_comp_level = level; }
++ void set_would_profile(bool p) { _would_profile = p ? profile : no_profile; }
++ bool would_profile() const { return _would_profile != no_profile; }
+
+ int num_loops() const { return _num_loops; }
+ void set_num_loops(int n) { _num_loops = n; }
+--- ./hotspot/src/share/vm/oops/objArrayKlass.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/objArrayKlass.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -29,6 +29,7 @@
+ #include "gc_implementation/shared/markSweep.inline.hpp"
+ #include "gc_interface/collectedHeap.inline.hpp"
+ #include "memory/genOopClosures.inline.hpp"
++#include "memory/iterator.inline.hpp"
+ #include "memory/metadataFactory.hpp"
+ #include "memory/resourceArea.hpp"
+ #include "memory/universe.inline.hpp"
+@@ -42,6 +43,7 @@
+ #include "oops/symbol.hpp"
+ #include "runtime/handles.inline.hpp"
+ #include "runtime/mutexLocker.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "utilities/copy.hpp"
+ #include "utilities/macros.hpp"
+ #if INCLUDE_ALL_GCS
+@@ -49,7 +51,7 @@
+ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+ #include "gc_implementation/g1/g1OopClosures.inline.hpp"
+ #include "gc_implementation/g1/g1RemSet.inline.hpp"
+-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
++#include "gc_implementation/g1/heapRegionManager.inline.hpp"
+ #include "gc_implementation/parNew/parOopClosures.inline.hpp"
+ #include "gc_implementation/parallelScavenge/psCompactionManager.hpp"
+ #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
+@@ -475,12 +477,6 @@
+ }
+ #endif // INCLUDE_ALL_GCS
+
+-#define if_do_metadata_checked(closure, nv_suffix) \
+- /* Make sure the non-virtual and the virtual versions match. */ \
+- assert(closure->do_metadata##nv_suffix() == closure->do_metadata(), \
+- "Inconsistency in do_metadata"); \
+- if (closure->do_metadata##nv_suffix())
+-
+ #define ObjArrayKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \
+ \
+ int ObjArrayKlass::oop_oop_iterate##nv_suffix(oop obj, \
+--- ./hotspot/src/share/vm/oops/objArrayOop.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/objArrayOop.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -45,9 +45,10 @@
+ private:
+ // Give size of objArrayOop in HeapWords minus the header
+ static int array_size(int length) {
+- const int OopsPerHeapWord = HeapWordSize/heapOopSize;
++ const uint OopsPerHeapWord = HeapWordSize/heapOopSize;
+ assert(OopsPerHeapWord >= 1 && (HeapWordSize % heapOopSize == 0),
+ "Else the following (new) computation would be in error");
++ uint res = ((uint)length + OopsPerHeapWord - 1)/OopsPerHeapWord;
+ #ifdef ASSERT
+ // The old code is left in for sanity-checking; it'll
+ // go away pretty soon. XXX
+@@ -55,16 +56,15 @@
+ // oop->length() * HeapWordsPerOop;
+ // With narrowOops, HeapWordsPerOop is 1/2 or equal 0 as an integer.
+ // The oop elements are aligned up to wordSize
+- const int HeapWordsPerOop = heapOopSize/HeapWordSize;
+- int old_res;
++ const uint HeapWordsPerOop = heapOopSize/HeapWordSize;
++ uint old_res;
+ if (HeapWordsPerOop > 0) {
+ old_res = length * HeapWordsPerOop;
+ } else {
+- old_res = align_size_up(length, OopsPerHeapWord)/OopsPerHeapWord;
++ old_res = align_size_up((uint)length, OopsPerHeapWord)/OopsPerHeapWord;
+ }
++ assert(res == old_res, "Inconsistency between old and new.");
+ #endif // ASSERT
+- int res = ((uint)length + OopsPerHeapWord - 1)/OopsPerHeapWord;
+- assert(res == old_res, "Inconsistency between old and new.");
+ return res;
+ }
+
+--- ./hotspot/src/share/vm/oops/oop.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/oop.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -109,12 +109,13 @@
+ int size_given_klass(Klass* klass);
+
+ // type test operations (inlined in oop.inline.h)
+- bool is_instance() const;
+- bool is_instanceMirror() const;
+- bool is_instanceRef() const;
+- bool is_array() const;
+- bool is_objArray() const;
+- bool is_typeArray() const;
++ bool is_instance() const;
++ bool is_instanceMirror() const;
++ bool is_instanceClassLoader() const;
++ bool is_instanceRef() const;
++ bool is_array() const;
++ bool is_objArray() const;
++ bool is_typeArray() const;
+
+ private:
+ // field addresses in oop
+--- ./hotspot/src/share/vm/oops/oop.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/oop.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -38,7 +38,8 @@
+ #include "oops/klass.inline.hpp"
+ #include "oops/markOop.inline.hpp"
+ #include "oops/oop.hpp"
+-#include "runtime/atomic.hpp"
++#include "runtime/atomic.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/os.hpp"
+ #include "utilities/macros.hpp"
+ #ifdef TARGET_ARCH_x86
+@@ -147,12 +148,13 @@
+
+ inline bool oopDesc::is_a(Klass* k) const { return klass()->is_subtype_of(k); }
+
+-inline bool oopDesc::is_instance() const { return klass()->oop_is_instance(); }
+-inline bool oopDesc::is_instanceMirror() const { return klass()->oop_is_instanceMirror(); }
+-inline bool oopDesc::is_instanceRef() const { return klass()->oop_is_instanceRef(); }
+-inline bool oopDesc::is_array() const { return klass()->oop_is_array(); }
+-inline bool oopDesc::is_objArray() const { return klass()->oop_is_objArray(); }
+-inline bool oopDesc::is_typeArray() const { return klass()->oop_is_typeArray(); }
++inline bool oopDesc::is_instance() const { return klass()->oop_is_instance(); }
++inline bool oopDesc::is_instanceClassLoader() const { return klass()->oop_is_instanceClassLoader(); }
++inline bool oopDesc::is_instanceMirror() const { return klass()->oop_is_instanceMirror(); }
++inline bool oopDesc::is_instanceRef() const { return klass()->oop_is_instanceRef(); }
++inline bool oopDesc::is_array() const { return klass()->oop_is_array(); }
++inline bool oopDesc::is_objArray() const { return klass()->oop_is_objArray(); }
++inline bool oopDesc::is_typeArray() const { return klass()->oop_is_typeArray(); }
+
+ inline void* oopDesc::field_base(int offset) const { return (void*)&((char*)this)[offset]; }
+
+--- ./hotspot/src/share/vm/oops/oop.pcgc.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/oop.pcgc.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -54,8 +54,6 @@
+ klass()->oop_follow_contents(cm, this);
+ }
+
+-// Used by parallel old GC.
+-
+ inline oop oopDesc::forward_to_atomic(oop p) {
+ assert(ParNewGeneration::is_legal_forward_ptr(p),
+ "illegal forwarding pointer value.");
+--- ./hotspot/src/share/vm/oops/typeArrayKlass.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/typeArrayKlass.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -39,6 +39,7 @@
+ #include "oops/typeArrayKlass.hpp"
+ #include "oops/typeArrayOop.hpp"
+ #include "runtime/handles.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "utilities/macros.hpp"
+
+ bool TypeArrayKlass::compute_is_subtype_of(Klass* k) {
+--- ./hotspot/src/share/vm/oops/typeArrayOop.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/oops/typeArrayOop.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -27,39 +27,7 @@
+
+ #include "oops/arrayOop.hpp"
+ #include "oops/typeArrayKlass.hpp"
+-#ifdef TARGET_OS_ARCH_linux_x86
+-# include "orderAccess_linux_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_sparc
+-# include "orderAccess_linux_sparc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_zero
+-# include "orderAccess_linux_zero.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_solaris_x86
+-# include "orderAccess_solaris_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_solaris_sparc
+-# include "orderAccess_solaris_sparc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_windows_x86
+-# include "orderAccess_windows_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_arm
+-# include "orderAccess_linux_arm.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_ppc
+-# include "orderAccess_linux_ppc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_aix_ppc
+-# include "orderAccess_aix_ppc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_bsd_x86
+-# include "orderAccess_bsd_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_bsd_zero
+-# include "orderAccess_bsd_zero.inline.hpp"
+-#endif
++#include "runtime/orderAccess.inline.hpp"
+
+ // A typeArrayOop is an array containing basic types (non oop elements).
+ // It is used for arrays of {characters, singles, doubles, bytes, shorts, integers, longs}
+@@ -182,7 +150,7 @@
+ DEBUG_ONLY(BasicType etype = Klass::layout_helper_element_type(lh));
+ assert(length <= arrayOopDesc::max_array_length(etype), "no overflow");
+
+- julong size_in_bytes = length;
++ julong size_in_bytes = (juint)length;
+ size_in_bytes <<= element_shift;
+ size_in_bytes += instance_header_size;
+ julong size_in_words = ((size_in_bytes + (HeapWordSize-1)) >> LogHeapWordSize);
+--- ./hotspot/src/share/vm/opto/bytecodeInfo.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/bytecodeInfo.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -107,7 +107,7 @@
+ int caller_bci, ciCallProfile& profile,
+ WarmCallInfo* wci_result) {
+ // Allows targeted inlining
+- if(callee_method->should_inline()) {
++ if (callee_method->should_inline()) {
+ *wci_result = *(WarmCallInfo::always_hot());
+ if (C->print_inlining() && Verbose) {
+ CompileTask::print_inline_indent(inline_level());
+@@ -118,6 +118,12 @@
+ return true;
+ }
+
++ if (callee_method->force_inline()) {
++ set_msg("force inline by annotation");
++ _forced_inline = true;
++ return true;
++ }
++
+ #ifndef PRODUCT
+ int inline_depth = inline_level()+1;
+ if (ciReplay::should_inline(C->replay_inline_data(), callee_method, caller_bci, inline_depth)) {
+@@ -244,6 +250,11 @@
+ }
+ #endif
+
++ if (callee_method->force_inline()) {
++ set_msg("force inline by annotation");
++ return false;
++ }
++
+ // Now perform checks which are heuristic
+
+ if (is_unboxing_method(callee_method, C)) {
+@@ -251,12 +262,10 @@
+ return false;
+ }
+
+- if (!callee_method->force_inline()) {
+- if (callee_method->has_compiled_code() &&
+- callee_method->instructions_size() > InlineSmallCode) {
+- set_msg("already compiled into a big method");
+- return true;
+- }
++ if (callee_method->has_compiled_code() &&
++ callee_method->instructions_size() > InlineSmallCode) {
++ set_msg("already compiled into a big method");
++ return true;
+ }
+
+ // don't inline exception code unless the top method belongs to an
+@@ -349,7 +358,7 @@
+ // Escape Analysis stress testing when running Xcomp or CTW:
+ // inline constructors even if they are not reached.
+ } else if (forced_inline()) {
+- // Inlining was forced by CompilerOracle or ciReplay
++ // Inlining was forced by CompilerOracle, ciReplay or annotation
+ } else if (profile.count() == 0) {
+ // don't inline unreached call sites
+ set_msg("call site not reached");
+--- ./hotspot/src/share/vm/opto/c2_globals.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/c2_globals.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -473,6 +473,9 @@
+ product(bool, DoEscapeAnalysis, true, \
+ "Perform escape analysis") \
+ \
++ product(double, EscapeAnalysisTimeout, 20. DEBUG_ONLY(+40.), \
++ "Abort EA when it reaches time limit (in sec)") \
++ \
+ develop(bool, ExitEscapeAnalysisOnTimeout, true, \
+ "Exit or throw assert in EA when it reaches time limit") \
+ \
+@@ -644,7 +647,7 @@
+ develop(bool, AlwaysIncrementalInline, false, \
+ "do all inlining incrementally") \
+ \
+- product(intx, LiveNodeCountInliningCutoff, 20000, \
++ product(intx, LiveNodeCountInliningCutoff, 40000, \
+ "max number of live nodes in a method") \
+ \
+ diagnostic(bool, OptimizeExpensiveOps, true, \
+@@ -653,8 +656,8 @@
+ product(bool, UseMathExactIntrinsics, true, \
+ "Enables intrinsification of various java.lang.Math functions") \
+ \
+- experimental(bool, ReplaceInParentMaps, false, \
+- "Propagate type improvements in callers of inlinee if possible") \
++ product(bool, UseMultiplyToLenIntrinsic, false, \
++ "Enables intrinsification of BigInteger.multiplyToLen()") \
+ \
+ product(bool, UseTypeSpeculation, true, \
+ "Speculatively propagate types from profiles") \
+--- ./hotspot/src/share/vm/opto/callGenerator.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/callGenerator.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -63,12 +63,12 @@
+ }
+
+ virtual bool is_parse() const { return true; }
+- virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
++ virtual JVMState* generate(JVMState* jvms);
+ int is_osr() { return _is_osr; }
+
+ };
+
+-JVMState* ParseGenerator::generate(JVMState* jvms, Parse* parent_parser) {
++JVMState* ParseGenerator::generate(JVMState* jvms) {
+ Compile* C = Compile::current();
+
+ if (is_osr()) {
+@@ -80,7 +80,7 @@
+ return NULL; // bailing out of the compile; do not try to parse
+ }
+
+- Parse parser(jvms, method(), _expected_uses, parent_parser);
++ Parse parser(jvms, method(), _expected_uses);
+ // Grab signature for matching/allocation
+ #ifdef ASSERT
+ if (parser.tf() != (parser.depth() == 1 ? C->tf() : tf())) {
+@@ -119,12 +119,12 @@
+ _separate_io_proj(separate_io_proj)
+ {
+ }
+- virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
++ virtual JVMState* generate(JVMState* jvms);
+
+ CallStaticJavaNode* call_node() const { return _call_node; }
+ };
+
+-JVMState* DirectCallGenerator::generate(JVMState* jvms, Parse* parent_parser) {
++JVMState* DirectCallGenerator::generate(JVMState* jvms) {
+ GraphKit kit(jvms);
+ bool is_static = method()->is_static();
+ address target = is_static ? SharedRuntime::get_resolve_static_call_stub()
+@@ -171,10 +171,10 @@
+ vtable_index >= 0, "either invalid or usable");
+ }
+ virtual bool is_virtual() const { return true; }
+- virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
++ virtual JVMState* generate(JVMState* jvms);
+ };
+
+-JVMState* VirtualCallGenerator::generate(JVMState* jvms, Parse* parent_parser) {
++JVMState* VirtualCallGenerator::generate(JVMState* jvms) {
+ GraphKit kit(jvms);
+ Node* receiver = kit.argument(0);
+
+@@ -276,7 +276,7 @@
+ // Convert the CallStaticJava into an inline
+ virtual void do_late_inline();
+
+- virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
++ virtual JVMState* generate(JVMState* jvms) {
+ Compile *C = Compile::current();
+ C->print_inlining_skip(this);
+
+@@ -290,7 +290,7 @@
+ // that the late inlining logic can distinguish between fall
+ // through and exceptional uses of the memory and io projections
+ // as is done for allocations and macro expansion.
+- return DirectCallGenerator::generate(jvms, parent_parser);
++ return DirectCallGenerator::generate(jvms);
+ }
+
+ virtual void print_inlining_late(const char* msg) {
+@@ -389,7 +389,7 @@
+ }
+
+ // Now perform the inling using the synthesized JVMState
+- JVMState* new_jvms = _inline_cg->generate(jvms, NULL);
++ JVMState* new_jvms = _inline_cg->generate(jvms);
+ if (new_jvms == NULL) return; // no change
+ if (C->failing()) return;
+
+@@ -407,7 +407,7 @@
+ C->env()->notice_inlined_method(_inline_cg->method());
+ C->set_inlining_progress(true);
+
+- kit.replace_call(call, result);
++ kit.replace_call(call, result, true);
+ }
+
+
+@@ -429,8 +429,8 @@
+
+ virtual bool is_mh_late_inline() const { return true; }
+
+- virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
+- JVMState* new_jvms = LateInlineCallGenerator::generate(jvms, parent_parser);
++ virtual JVMState* generate(JVMState* jvms) {
++ JVMState* new_jvms = LateInlineCallGenerator::generate(jvms);
+ if (_input_not_const) {
+ // inlining won't be possible so no need to enqueue right now.
+ call_node()->set_generator(this);
+@@ -477,13 +477,13 @@
+ LateInlineStringCallGenerator(ciMethod* method, CallGenerator* inline_cg) :
+ LateInlineCallGenerator(method, inline_cg) {}
+
+- virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
++ virtual JVMState* generate(JVMState* jvms) {
+ Compile *C = Compile::current();
+ C->print_inlining_skip(this);
+
+ C->add_string_late_inline(this);
+
+- JVMState* new_jvms = DirectCallGenerator::generate(jvms, parent_parser);
++ JVMState* new_jvms = DirectCallGenerator::generate(jvms);
+ return new_jvms;
+ }
+
+@@ -500,13 +500,13 @@
+ LateInlineBoxingCallGenerator(ciMethod* method, CallGenerator* inline_cg) :
+ LateInlineCallGenerator(method, inline_cg) {}
+
+- virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
++ virtual JVMState* generate(JVMState* jvms) {
+ Compile *C = Compile::current();
+ C->print_inlining_skip(this);
+
+ C->add_boxing_late_inline(this);
+
+- JVMState* new_jvms = DirectCallGenerator::generate(jvms, parent_parser);
++ JVMState* new_jvms = DirectCallGenerator::generate(jvms);
+ return new_jvms;
+ }
+ };
+@@ -542,7 +542,7 @@
+ virtual bool is_virtual() const { return _is_virtual; }
+ virtual bool is_deferred() const { return true; }
+
+- virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
++ virtual JVMState* generate(JVMState* jvms);
+ };
+
+
+@@ -552,12 +552,12 @@
+ return new WarmCallGenerator(ci, if_cold, if_hot);
+ }
+
+-JVMState* WarmCallGenerator::generate(JVMState* jvms, Parse* parent_parser) {
++JVMState* WarmCallGenerator::generate(JVMState* jvms) {
+ Compile* C = Compile::current();
+ if (C->log() != NULL) {
+ C->log()->elem("warm_call bci='%d'", jvms->bci());
+ }
+- jvms = _if_cold->generate(jvms, parent_parser);
++ jvms = _if_cold->generate(jvms);
+ if (jvms != NULL) {
+ Node* m = jvms->map()->control();
+ if (m->is_CatchProj()) m = m->in(0); else m = C->top();
+@@ -618,7 +618,7 @@
+ virtual bool is_inline() const { return _if_hit->is_inline(); }
+ virtual bool is_deferred() const { return _if_hit->is_deferred(); }
+
+- virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
++ virtual JVMState* generate(JVMState* jvms);
+ };
+
+
+@@ -630,7 +630,7 @@
+ }
+
+
+-JVMState* PredictedCallGenerator::generate(JVMState* jvms, Parse* parent_parser) {
++JVMState* PredictedCallGenerator::generate(JVMState* jvms) {
+ GraphKit kit(jvms);
+ PhaseGVN& gvn = kit.gvn();
+ // We need an explicit receiver null_check before checking its type.
+@@ -648,6 +648,10 @@
+ return kit.transfer_exceptions_into_jvms();
+ }
+
++ // Make a copy of the replaced nodes in case we need to restore them
++ ReplacedNodes replaced_nodes = kit.map()->replaced_nodes();
++ replaced_nodes.clone();
++
+ Node* exact_receiver = receiver; // will get updated in place...
+ Node* slow_ctl = kit.type_check_receiver(receiver,
+ _predicted_receiver, _hit_prob,
+@@ -658,7 +662,7 @@
+ { PreserveJVMState pjvms(&kit);
+ kit.set_control(slow_ctl);
+ if (!kit.stopped()) {
+- slow_jvms = _if_missed->generate(kit.sync_jvms(), parent_parser);
++ slow_jvms = _if_missed->generate(kit.sync_jvms());
+ if (kit.failing())
+ return NULL; // might happen because of NodeCountInliningCutoff
+ assert(slow_jvms != NULL, "must be");
+@@ -679,12 +683,12 @@
+ kit.replace_in_map(receiver, exact_receiver);
+
+ // Make the hot call:
+- JVMState* new_jvms = _if_hit->generate(kit.sync_jvms(), parent_parser);
++ JVMState* new_jvms = _if_hit->generate(kit.sync_jvms());
+ if (new_jvms == NULL) {
+ // Inline failed, so make a direct call.
+ assert(_if_hit->is_inline(), "must have been a failed inline");
+ CallGenerator* cg = CallGenerator::for_direct_call(_if_hit->method());
+- new_jvms = cg->generate(kit.sync_jvms(), parent_parser);
++ new_jvms = cg->generate(kit.sync_jvms());
+ }
+ kit.add_exception_states_from(new_jvms);
+ kit.set_jvms(new_jvms);
+@@ -701,6 +705,11 @@
+ return kit.transfer_exceptions_into_jvms();
+ }
+
++ // There are 2 branches and the replaced nodes are only valid on
++ // one: restore the replaced nodes to what they were before the
++ // branch.
++ kit.map()->set_replaced_nodes(replaced_nodes);
++
+ // Finish the diamond.
+ kit.C->set_has_split_ifs(true); // Has chance for split-if optimization
+ RegionNode* region = new (kit.C) RegionNode(3);
+@@ -710,7 +719,15 @@
+ Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO);
+ iophi->set_req(2, slow_map->i_o());
+ kit.set_i_o(gvn.transform(iophi));
++ // Merge memory
+ kit.merge_memory(slow_map->merged_memory(), region, 2);
++ // Transform new memory Phis.
++ for (MergeMemStream mms(kit.merged_memory()); mms.next_non_empty();) {
++ Node* phi = mms.memory();
++ if (phi->is_Phi() && phi->in(0) == region) {
++ mms.set_memory(gvn.transform(phi));
++ }
++ }
+ uint tos = kit.jvms()->stkoff() + kit.sp();
+ uint limit = slow_map->req();
+ for (uint i = TypeFunc::Parms; i < limit; i++) {
+@@ -845,7 +862,7 @@
+ call_does_dispatch, vtable_index); // out-parameters
+ // We lack profiling at this call but type speculation may
+ // provide us with a type
+- speculative_receiver_type = receiver_type->speculative_type();
++ speculative_receiver_type = (receiver_type != NULL) ? receiver_type->speculative_type() : NULL;
+ }
+
+ CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, true, PROB_ALWAYS, speculative_receiver_type, true, true);
+@@ -864,15 +881,15 @@
+ }
+
+
+-//------------------------PredictedIntrinsicGenerator------------------------------
+-// Internal class which handles all predicted Intrinsic calls.
+-class PredictedIntrinsicGenerator : public CallGenerator {
++//------------------------PredicatedIntrinsicGenerator------------------------------
++// Internal class which handles all predicated Intrinsic calls.
++class PredicatedIntrinsicGenerator : public CallGenerator {
+ CallGenerator* _intrinsic;
+ CallGenerator* _cg;
+
+ public:
+- PredictedIntrinsicGenerator(CallGenerator* intrinsic,
+- CallGenerator* cg)
++ PredicatedIntrinsicGenerator(CallGenerator* intrinsic,
++ CallGenerator* cg)
+ : CallGenerator(cg->method())
+ {
+ _intrinsic = intrinsic;
+@@ -883,107 +900,186 @@
+ virtual bool is_inlined() const { return true; }
+ virtual bool is_intrinsic() const { return true; }
+
+- virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
++ virtual JVMState* generate(JVMState* jvms);
+ };
+
+
+-CallGenerator* CallGenerator::for_predicted_intrinsic(CallGenerator* intrinsic,
+- CallGenerator* cg) {
+- return new PredictedIntrinsicGenerator(intrinsic, cg);
++CallGenerator* CallGenerator::for_predicated_intrinsic(CallGenerator* intrinsic,
++ CallGenerator* cg) {
++ return new PredicatedIntrinsicGenerator(intrinsic, cg);
+ }
+
+
+-JVMState* PredictedIntrinsicGenerator::generate(JVMState* jvms, Parse* parent_parser) {
++JVMState* PredicatedIntrinsicGenerator::generate(JVMState* jvms) {
++ // The code we want to generate here is:
++ // if (receiver == NULL)
++ // uncommon_Trap
++ // if (predicate(0))
++ // do_intrinsic(0)
++ // else
++ // if (predicate(1))
++ // do_intrinsic(1)
++ // ...
++ // else
++ // do_java_comp
++
+ GraphKit kit(jvms);
+ PhaseGVN& gvn = kit.gvn();
+
+ CompileLog* log = kit.C->log();
+ if (log != NULL) {
+- log->elem("predicted_intrinsic bci='%d' method='%d'",
++ log->elem("predicated_intrinsic bci='%d' method='%d'",
+ jvms->bci(), log->identify(method()));
+ }
+
+- Node* slow_ctl = _intrinsic->generate_predicate(kit.sync_jvms());
+- if (kit.failing())
+- return NULL; // might happen because of NodeCountInliningCutoff
+-
+- SafePointNode* slow_map = NULL;
+- JVMState* slow_jvms;
+- if (slow_ctl != NULL) {
+- PreserveJVMState pjvms(&kit);
+- kit.set_control(slow_ctl);
+- if (!kit.stopped()) {
+- slow_jvms = _cg->generate(kit.sync_jvms(), parent_parser);
+- if (kit.failing())
+- return NULL; // might happen because of NodeCountInliningCutoff
+- assert(slow_jvms != NULL, "must be");
+- kit.add_exception_states_from(slow_jvms);
+- kit.set_map(slow_jvms->map());
+- if (!kit.stopped())
+- slow_map = kit.stop();
++ if (!method()->is_static()) {
++ // We need an explicit receiver null_check before checking its type in predicate.
++ // We share a map with the caller, so his JVMS gets adjusted.
++ Node* receiver = kit.null_check_receiver_before_call(method());
++ if (kit.stopped()) {
++ return kit.transfer_exceptions_into_jvms();
+ }
+ }
+
+- if (kit.stopped()) {
+- // Predicate is always false.
+- kit.set_jvms(slow_jvms);
++ int n_predicates = _intrinsic->predicates_count();
++ assert(n_predicates > 0, "sanity");
++
++ JVMState** result_jvms = NEW_RESOURCE_ARRAY(JVMState*, (n_predicates+1));
++
++ // Region for normal compilation code if intrinsic failed.
++ Node* slow_region = new (kit.C) RegionNode(1);
++
++ int results = 0;
++ for (int predicate = 0; (predicate < n_predicates) && !kit.stopped(); predicate++) {
++#ifdef ASSERT
++ JVMState* old_jvms = kit.jvms();
++ SafePointNode* old_map = kit.map();
++ Node* old_io = old_map->i_o();
++ Node* old_mem = old_map->memory();
++ Node* old_exc = old_map->next_exception();
++#endif
++ Node* else_ctrl = _intrinsic->generate_predicate(kit.sync_jvms(), predicate);
++#ifdef ASSERT
++ // Assert(no_new_memory && no_new_io && no_new_exceptions) after generate_predicate.
++ assert(old_jvms == kit.jvms(), "generate_predicate should not change jvm state");
++ SafePointNode* new_map = kit.map();
++ assert(old_io == new_map->i_o(), "generate_predicate should not change i_o");
++ assert(old_mem == new_map->memory(), "generate_predicate should not change memory");
++ assert(old_exc == new_map->next_exception(), "generate_predicate should not add exceptions");
++#endif
++ if (!kit.stopped()) {
++ PreserveJVMState pjvms(&kit);
++ // Generate intrinsic code:
++ JVMState* new_jvms = _intrinsic->generate(kit.sync_jvms());
++ if (new_jvms == NULL) {
++ // Intrinsic failed, use normal compilation path for this predicate.
++ slow_region->add_req(kit.control());
++ } else {
++ kit.add_exception_states_from(new_jvms);
++ kit.set_jvms(new_jvms);
++ if (!kit.stopped()) {
++ result_jvms[results++] = kit.jvms();
++ }
++ }
++ }
++ if (else_ctrl == NULL) {
++ else_ctrl = kit.C->top();
++ }
++ kit.set_control(else_ctrl);
++ }
++ if (!kit.stopped()) {
++ // Final 'else' after predicates.
++ slow_region->add_req(kit.control());
++ }
++ if (slow_region->req() > 1) {
++ PreserveJVMState pjvms(&kit);
++ // Generate normal compilation code:
++ kit.set_control(gvn.transform(slow_region));
++ JVMState* new_jvms = _cg->generate(kit.sync_jvms());
++ if (kit.failing())
++ return NULL; // might happen because of NodeCountInliningCutoff
++ assert(new_jvms != NULL, "must be");
++ kit.add_exception_states_from(new_jvms);
++ kit.set_jvms(new_jvms);
++ if (!kit.stopped()) {
++ result_jvms[results++] = kit.jvms();
++ }
++ }
++
++ if (results == 0) {
++ // All paths ended in uncommon traps.
++ (void) kit.stop();
+ return kit.transfer_exceptions_into_jvms();
+ }
+
+- // Generate intrinsic code:
+- JVMState* new_jvms = _intrinsic->generate(kit.sync_jvms(), parent_parser);
+- if (new_jvms == NULL) {
+- // Intrinsic failed, so use slow code or make a direct call.
+- if (slow_map == NULL) {
+- CallGenerator* cg = CallGenerator::for_direct_call(method());
+- new_jvms = cg->generate(kit.sync_jvms(), parent_parser);
+- } else {
+- kit.set_jvms(slow_jvms);
+- return kit.transfer_exceptions_into_jvms();
+- }
+- }
+- kit.add_exception_states_from(new_jvms);
+- kit.set_jvms(new_jvms);
+-
+- // Need to merge slow and fast?
+- if (slow_map == NULL) {
+- // The fast path is the only path remaining.
++ if (results == 1) { // Only one path
++ kit.set_jvms(result_jvms[0]);
+ return kit.transfer_exceptions_into_jvms();
+ }
+
+- if (kit.stopped()) {
+- // Intrinsic method threw an exception, so it's just the slow path after all.
+- kit.set_jvms(slow_jvms);
+- return kit.transfer_exceptions_into_jvms();
++ // Merge all paths.
++ kit.C->set_has_split_ifs(true); // Has chance for split-if optimization
++ RegionNode* region = new (kit.C) RegionNode(results + 1);
++ Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO);
++ for (int i = 0; i < results; i++) {
++ JVMState* jvms = result_jvms[i];
++ int path = i + 1;
++ SafePointNode* map = jvms->map();
++ region->init_req(path, map->control());
++ iophi->set_req(path, map->i_o());
++ if (i == 0) {
++ kit.set_jvms(jvms);
++ } else {
++ kit.merge_memory(map->merged_memory(), region, path);
++ }
++ }
++ kit.set_control(gvn.transform(region));
++ kit.set_i_o(gvn.transform(iophi));
++ // Transform new memory Phis.
++ for (MergeMemStream mms(kit.merged_memory()); mms.next_non_empty();) {
++ Node* phi = mms.memory();
++ if (phi->is_Phi() && phi->in(0) == region) {
++ mms.set_memory(gvn.transform(phi));
++ }
+ }
+
+- // Finish the diamond.
+- kit.C->set_has_split_ifs(true); // Has chance for split-if optimization
+- RegionNode* region = new (kit.C) RegionNode(3);
+- region->init_req(1, kit.control());
+- region->init_req(2, slow_map->control());
+- kit.set_control(gvn.transform(region));
+- Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO);
+- iophi->set_req(2, slow_map->i_o());
+- kit.set_i_o(gvn.transform(iophi));
+- kit.merge_memory(slow_map->merged_memory(), region, 2);
++ // Merge debug info.
++ Node** ins = NEW_RESOURCE_ARRAY(Node*, results);
+ uint tos = kit.jvms()->stkoff() + kit.sp();
+- uint limit = slow_map->req();
++ Node* map = kit.map();
++ uint limit = map->req();
+ for (uint i = TypeFunc::Parms; i < limit; i++) {
+ // Skip unused stack slots; fast forward to monoff();
+ if (i == tos) {
+ i = kit.jvms()->monoff();
+ if( i >= limit ) break;
+ }
+- Node* m = kit.map()->in(i);
+- Node* n = slow_map->in(i);
+- if (m != n) {
+- const Type* t = gvn.type(m)->meet_speculative(gvn.type(n));
+- Node* phi = PhiNode::make(region, m, t);
+- phi->set_req(2, n);
+- kit.map()->set_req(i, gvn.transform(phi));
++ Node* n = map->in(i);
++ ins[0] = n;
++ const Type* t = gvn.type(n);
++ bool needs_phi = false;
++ for (int j = 1; j < results; j++) {
++ JVMState* jvms = result_jvms[j];
++ Node* jmap = jvms->map();
++ Node* m = NULL;
++ if (jmap->req() > i) {
++ m = jmap->in(i);
++ if (m != n) {
++ needs_phi = true;
++ t = t->meet_speculative(gvn.type(m));
++ }
++ }
++ ins[j] = m;
++ }
++ if (needs_phi) {
++ Node* phi = PhiNode::make(region, n, t);
++ for (int j = 1; j < results; j++) {
++ phi->set_req(j + 1, ins[j]);
++ }
++ map->set_req(i, gvn.transform(phi));
+ }
+ }
++
+ return kit.transfer_exceptions_into_jvms();
+ }
+
+@@ -1006,7 +1102,7 @@
+ virtual bool is_virtual() const { ShouldNotReachHere(); return false; }
+ virtual bool is_trap() const { return true; }
+
+- virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
++ virtual JVMState* generate(JVMState* jvms);
+ };
+
+
+@@ -1018,7 +1114,7 @@
+ }
+
+
+-JVMState* UncommonTrapCallGenerator::generate(JVMState* jvms, Parse* parent_parser) {
++JVMState* UncommonTrapCallGenerator::generate(JVMState* jvms) {
+ GraphKit kit(jvms);
+ // Take the trap with arguments pushed on the stack. (Cf. null_check_receiver).
+ int nargs = method()->arg_size();
+--- ./hotspot/src/share/vm/opto/callGenerator.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/callGenerator.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -31,8 +31,6 @@
+ #include "opto/type.hpp"
+ #include "runtime/deoptimization.hpp"
+
+-class Parse;
+-
+ //---------------------------CallGenerator-------------------------------------
+ // The subclasses of this class handle generation of ideal nodes for
+ // call sites and method entry points.
+@@ -63,8 +61,9 @@
+ virtual bool is_virtual() const { return false; }
+ // is_deferred: The decision whether to inline or not is deferred.
+ virtual bool is_deferred() const { return false; }
+- // is_predicted: Uses an explicit check against a predicted type.
+- virtual bool is_predicted() const { return false; }
++ // is_predicated: Uses an explicit check (predicate).
++ virtual bool is_predicated() const { return false; }
++ virtual int predicates_count() const { return 0; }
+ // is_trap: Does not return to the caller. (E.g., uncommon trap.)
+ virtual bool is_trap() const { return false; }
+ // does_virtual_dispatch: Should try inlining as normal method first.
+@@ -111,7 +110,7 @@
+ //
+ // If the result is NULL, it means that this CallGenerator was unable
+ // to handle the given call, and another CallGenerator should be consulted.
+- virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) = 0;
++ virtual JVMState* generate(JVMState* jvms) = 0;
+
+ // How to generate a call site that is inlined:
+ static CallGenerator* for_inline(ciMethod* m, float expected_uses = -1);
+@@ -157,9 +156,9 @@
+ // Registry for intrinsics:
+ static CallGenerator* for_intrinsic(ciMethod* m);
+ static void register_intrinsic(ciMethod* m, CallGenerator* cg);
+- static CallGenerator* for_predicted_intrinsic(CallGenerator* intrinsic,
+- CallGenerator* cg);
+- virtual Node* generate_predicate(JVMState* jvms) { return NULL; };
++ static CallGenerator* for_predicated_intrinsic(CallGenerator* intrinsic,
++ CallGenerator* cg);
++ virtual Node* generate_predicate(JVMState* jvms, int predicate) { return NULL; };
+
+ virtual void print_inlining_late(const char* msg) { ShouldNotReachHere(); }
+
+--- ./hotspot/src/share/vm/opto/callnode.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/callnode.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -777,7 +777,7 @@
+ }
+
+ // Returns the unique CheckCastPP of a call
+-// or 'this' if there are several CheckCastPP
++// or 'this' if there are several CheckCastPP or unexpected uses
+ // or returns NULL if there is no one.
+ Node *CallNode::result_cast() {
+ Node *cast = NULL;
+@@ -793,6 +793,13 @@
+ return this; // more than 1 CheckCastPP
+ }
+ cast = use;
++ } else if (!use->is_Initialize() &&
++ !use->is_AddP()) {
++ // Expected uses are restricted to a CheckCastPP, an Initialize
++ // node, and AddP nodes. If we encounter any other use (a Phi
++ // node can be seen in rare cases) return this to prevent
++ // incorrect optimizations.
++ return this;
+ }
+ }
+ return cast;
+@@ -1089,6 +1096,7 @@
+ #ifndef PRODUCT
+ void SafePointNode::dump_spec(outputStream *st) const {
+ st->print(" SafePoint ");
++ _replaced_nodes.dump(st);
+ }
+ #endif
+
+--- ./hotspot/src/share/vm/opto/callnode.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/callnode.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -30,6 +30,7 @@
+ #include "opto/multnode.hpp"
+ #include "opto/opcodes.hpp"
+ #include "opto/phaseX.hpp"
++#include "opto/replacednodes.hpp"
+ #include "opto/type.hpp"
+
+ // Portions of code courtesy of Clifford Click
+@@ -335,6 +336,7 @@
+ OopMap* _oop_map; // Array of OopMap info (8-bit char) for GC
+ JVMState* const _jvms; // Pointer to list of JVM State objects
+ const TypePtr* _adr_type; // What type of memory does this node produce?
++ ReplacedNodes _replaced_nodes; // During parsing: list of pair of nodes from calls to GraphKit::replace_in_map()
+
+ // Many calls take *all* of memory as input,
+ // but some produce a limited subset of that memory as output.
+@@ -426,6 +428,37 @@
+ void set_next_exception(SafePointNode* n);
+ bool has_exceptions() const { return next_exception() != NULL; }
+
++ // Helper methods to operate on replaced nodes
++ ReplacedNodes replaced_nodes() const {
++ return _replaced_nodes;
++ }
++
++ void set_replaced_nodes(ReplacedNodes replaced_nodes) {
++ _replaced_nodes = replaced_nodes;
++ }
++
++ void clone_replaced_nodes() {
++ _replaced_nodes.clone();
++ }
++ void record_replaced_node(Node* initial, Node* improved) {
++ _replaced_nodes.record(initial, improved);
++ }
++ void transfer_replaced_nodes_from(SafePointNode* sfpt, uint idx = 0) {
++ _replaced_nodes.transfer_from(sfpt->_replaced_nodes, idx);
++ }
++ void delete_replaced_nodes() {
++ _replaced_nodes.reset();
++ }
++ void apply_replaced_nodes() {
++ _replaced_nodes.apply(this);
++ }
++ void merge_replaced_nodes_with(SafePointNode* sfpt) {
++ _replaced_nodes.merge_with(sfpt->_replaced_nodes);
++ }
++ bool has_replaced_nodes() const {
++ return !_replaced_nodes.is_empty();
++ }
++
+ // Standard Node stuff
+ virtual int Opcode() const;
+ virtual bool pinned() const { return true; }
+--- ./hotspot/src/share/vm/opto/coalesce.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/coalesce.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -281,9 +281,11 @@
+ Block *pred = _phc._cfg.get_block_for_node(b->pred(j));
+ Node *copy;
+ assert(!m->is_Con() || m->is_Mach(), "all Con must be Mach");
+- // Rematerialize constants instead of copying them
+- if( m->is_Mach() && m->as_Mach()->is_Con() &&
+- m->as_Mach()->rematerialize() ) {
++ // Rematerialize constants instead of copying them.
++ // We do this only for immediate constants, we avoid constant table loads
++ // because that will unsafely extend the live range of the constant table base.
++ if (m->is_Mach() && m->as_Mach()->is_Con() && !m->as_Mach()->is_MachConstant() &&
++ m->as_Mach()->rematerialize()) {
+ copy = m->clone();
+ // Insert the copy in the predecessor basic block
+ pred->add_inst(copy);
+@@ -317,8 +319,8 @@
+ assert(!m->is_Con() || m->is_Mach(), "all Con must be Mach");
+ // At this point it is unsafe to extend live ranges (6550579).
+ // Rematerialize only constants as we do for Phi above.
+- if(m->is_Mach() && m->as_Mach()->is_Con() &&
+- m->as_Mach()->rematerialize()) {
++ if (m->is_Mach() && m->as_Mach()->is_Con() && !m->as_Mach()->is_MachConstant() &&
++ m->as_Mach()->rematerialize()) {
+ copy = m->clone();
+ // Insert the copy in the basic block, just before us
+ b->insert_node(copy, l++);
+--- ./hotspot/src/share/vm/opto/compile.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/compile.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -391,6 +391,11 @@
+ uint next = 0;
+ while (next < useful.size()) {
+ Node *n = useful.at(next++);
++ if (n->is_SafePoint()) {
++ // We're done with a parsing phase. Replaced nodes are not valid
++ // beyond that point.
++ n->as_SafePoint()->delete_replaced_nodes();
++ }
+ // Use raw traversal of out edges since this code removes out edges
+ int max = n->outcnt();
+ for (int j = 0; j < max; ++j) {
+@@ -660,6 +665,10 @@
+ _printer(IdealGraphPrinter::printer()),
+ #endif
+ _congraph(NULL),
++ _comp_arena(mtCompiler),
++ _node_arena(mtCompiler),
++ _old_arena(mtCompiler),
++ _Compile_types(mtCompiler),
+ _replay_inline_data(NULL),
+ _late_inlines(comp_arena(), 2, 0, NULL),
+ _string_late_inlines(comp_arena(), 2, 0, NULL),
+@@ -670,8 +679,8 @@
+ _inlining_incrementally(false),
+ _print_inlining_list(NULL),
+ _print_inlining_idx(0),
+- _preserve_jvm_state(0),
+- _interpreter_frame_size(0) {
++ _interpreter_frame_size(0),
++ _max_node_limit(MaxNodeLimit) {
+ C = this;
+
+ CompileWrapper cw(this);
+@@ -782,7 +791,7 @@
+ return;
+ }
+ JVMState* jvms = build_start_state(start(), tf());
+- if ((jvms = cg->generate(jvms, NULL)) == NULL) {
++ if ((jvms = cg->generate(jvms)) == NULL) {
+ record_method_not_compilable("method parse failed");
+ return;
+ }
+@@ -968,6 +977,10 @@
+ _in_dump_cnt(0),
+ _printer(NULL),
+ #endif
++ _comp_arena(mtCompiler),
++ _node_arena(mtCompiler),
++ _old_arena(mtCompiler),
++ _Compile_types(mtCompiler),
+ _dead_node_list(comp_arena()),
+ _dead_node_count(0),
+ _congraph(NULL),
+@@ -977,9 +990,9 @@
+ _inlining_incrementally(false),
+ _print_inlining_list(NULL),
+ _print_inlining_idx(0),
+- _preserve_jvm_state(0),
+ _allowed_reasons(0),
+- _interpreter_frame_size(0) {
++ _interpreter_frame_size(0),
++ _max_node_limit(MaxNodeLimit) {
+ C = this;
+
+ #ifndef PRODUCT
+@@ -1089,6 +1102,7 @@
+ set_do_count_invocations(false);
+ set_do_method_data_update(false);
+ set_rtm_state(NoRTM); // No RTM lock eliding by default
++ method_has_option_value("MaxNodeLimit", _max_node_limit);
+ #if INCLUDE_RTM_OPT
+ if (UseRTMLocking && has_method() && (method()->method_data_or_null() != NULL)) {
+ int rtm_state = method()->method_data()->rtm_state();
+@@ -1910,6 +1924,8 @@
+ for_igvn()->clear();
+ gvn->replace_with(&igvn);
+
++ _late_inlines_pos = _late_inlines.length();
++
+ while (_boxing_late_inlines.length() > 0) {
+ CallGenerator* cg = _boxing_late_inlines.pop();
+ cg->do_late_inline();
+@@ -1973,8 +1989,8 @@
+ if (live_nodes() > (uint)LiveNodeCountInliningCutoff) {
+ if (low_live_nodes < (uint)LiveNodeCountInliningCutoff * 8 / 10) {
+ // PhaseIdealLoop is expensive so we only try it once we are
+- // out of loop and we only try it again if the previous helped
+- // got the number of nodes down significantly
++ // out of live nodes and we only try it again if the previous
++ // helped got the number of nodes down significantly
+ PhaseIdealLoop ideal_loop( igvn, false, true );
+ if (failing()) return;
+ low_live_nodes = live_nodes();
+@@ -2066,6 +2082,10 @@
+ // Inline valueOf() methods now.
+ inline_boxing_calls(igvn);
+
++ if (AlwaysIncrementalInline) {
++ inline_incrementally(igvn);
++ }
++
+ print_method(PHASE_INCREMENTAL_BOXING_INLINE, 2);
+
+ if (failing()) return;
+--- ./hotspot/src/share/vm/opto/compile.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/compile.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -290,6 +290,7 @@
+ int _freq_inline_size; // Max hot method inline size for this compilation
+ int _fixed_slots; // count of frame slots not allocated by the register
+ // allocator i.e. locks, original deopt pc, etc.
++ uintx _max_node_limit; // Max unique node count during a single compilation.
+ // For deopt
+ int _orig_pc_slot;
+ int _orig_pc_slot_offset_in_bytes;
+@@ -429,9 +430,6 @@
+ // Remove the speculative part of types and clean up the graph
+ void remove_speculative_types(PhaseIterGVN &igvn);
+
+- // Are we within a PreserveJVMState block?
+- int _preserve_jvm_state;
+-
+ void* _replay_inline_data; // Pointer to data loaded from file
+
+ public:
+@@ -597,10 +595,17 @@
+ void set_rtm_state(RTMState s) { _rtm_state = s; }
+ bool use_rtm() const { return (_rtm_state & NoRTM) == 0; }
+ bool profile_rtm() const { return _rtm_state == ProfileRTM; }
++ uint max_node_limit() const { return (uint)_max_node_limit; }
++ void set_max_node_limit(uint n) { _max_node_limit = n; }
++
+ // check the CompilerOracle for special behaviours for this compile
+ bool method_has_option(const char * option) {
+ return method() != NULL && method()->has_option(option);
+ }
++ template<typename T>
++ bool method_has_option_value(const char * option, T& value) {
++ return method() != NULL && method()->has_option_value(option, value);
++ }
+ #ifndef PRODUCT
+ bool trace_opto_output() const { return _trace_opto_output; }
+ bool parsed_irreducible_loop() const { return _parsed_irreducible_loop; }
+@@ -722,7 +727,7 @@
+ record_method_not_compilable(reason, true);
+ }
+ bool check_node_count(uint margin, const char* reason) {
+- if (live_nodes() + margin > (uint)MaxNodeLimit) {
++ if (live_nodes() + margin > max_node_limit()) {
+ record_method_not_compilable(reason);
+ return true;
+ } else {
+@@ -1196,21 +1201,6 @@
+
+ // Auxiliary method for randomized fuzzing/stressing
+ static bool randomized_select(int count);
+-
+- // enter a PreserveJVMState block
+- void inc_preserve_jvm_state() {
+- _preserve_jvm_state++;
+- }
+-
+- // exit a PreserveJVMState block
+- void dec_preserve_jvm_state() {
+- _preserve_jvm_state--;
+- assert(_preserve_jvm_state >= 0, "_preserve_jvm_state shouldn't be negative");
+- }
+-
+- bool has_preserve_jvm_state() const {
+- return _preserve_jvm_state > 0;
+- }
+ };
+
+ #endif // SHARE_VM_OPTO_COMPILE_HPP
+--- ./hotspot/src/share/vm/opto/connode.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/connode.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -441,6 +441,102 @@
+ return this;
+ }
+
++uint CastIINode::size_of() const {
++ return sizeof(*this);
++}
++
++uint CastIINode::cmp(const Node &n) const {
++ return TypeNode::cmp(n) && ((CastIINode&)n)._carry_dependency == _carry_dependency;
++}
++
++Node *CastIINode::Identity(PhaseTransform *phase) {
++ if (_carry_dependency) {
++ return this;
++ }
++ return ConstraintCastNode::Identity(phase);
++}
++
++const Type *CastIINode::Value(PhaseTransform *phase) const {
++ const Type *res = ConstraintCastNode::Value(phase);
++
++ // Try to improve the type of the CastII if we recognize a CmpI/If
++ // pattern.
++ if (_carry_dependency) {
++ if (in(0) != NULL && in(0)->in(0) != NULL && in(0)->in(0)->is_If()) {
++ assert(in(0)->is_IfFalse() || in(0)->is_IfTrue(), "should be If proj");
++ Node* proj = in(0);
++ if (proj->in(0)->in(1)->is_Bool()) {
++ Node* b = proj->in(0)->in(1);
++ if (b->in(1)->Opcode() == Op_CmpI) {
++ Node* cmp = b->in(1);
++ if (cmp->in(1) == in(1) && phase->type(cmp->in(2))->isa_int()) {
++ const TypeInt* in2_t = phase->type(cmp->in(2))->is_int();
++ const Type* t = TypeInt::INT;
++ BoolTest test = b->as_Bool()->_test;
++ if (proj->is_IfFalse()) {
++ test = test.negate();
++ }
++ BoolTest::mask m = test._test;
++ jlong lo_long = min_jint;
++ jlong hi_long = max_jint;
++ if (m == BoolTest::le || m == BoolTest::lt) {
++ hi_long = in2_t->_hi;
++ if (m == BoolTest::lt) {
++ hi_long -= 1;
++ }
++ } else if (m == BoolTest::ge || m == BoolTest::gt) {
++ lo_long = in2_t->_lo;
++ if (m == BoolTest::gt) {
++ lo_long += 1;
++ }
++ } else if (m == BoolTest::eq) {
++ lo_long = in2_t->_lo;
++ hi_long = in2_t->_hi;
++ } else if (m == BoolTest::ne) {
++ // can't do any better
++ } else {
++ stringStream ss;
++ test.dump_on(&ss);
++ fatal(err_msg_res("unexpected comparison %s", ss.as_string()));
++ }
++ int lo_int = (int)lo_long;
++ int hi_int = (int)hi_long;
++
++ if (lo_long != (jlong)lo_int) {
++ lo_int = min_jint;
++ }
++ if (hi_long != (jlong)hi_int) {
++ hi_int = max_jint;
++ }
++
++ t = TypeInt::make(lo_int, hi_int, Type::WidenMax);
++
++ res = res->filter_speculative(t);
++
++ return res;
++ }
++ }
++ }
++ }
++ }
++ return res;
++}
++
++Node *CastIINode::Ideal_DU_postCCP(PhaseCCP *ccp) {
++ if (_carry_dependency) {
++ return NULL;
++ }
++ return ConstraintCastNode::Ideal_DU_postCCP(ccp);
++}
++
++#ifndef PRODUCT
++void CastIINode::dump_spec(outputStream *st) const {
++ TypeNode::dump_spec(st);
++ if (_carry_dependency) {
++ st->print(" carry dependency");
++ }
++}
++#endif
+
+ //=============================================================================
+
+--- ./hotspot/src/share/vm/opto/connode.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/connode.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -241,10 +241,25 @@
+ //------------------------------CastIINode-------------------------------------
+ // cast integer to integer (different range)
+ class CastIINode: public ConstraintCastNode {
++ private:
++ // Can this node be removed post CCP or does it carry a required dependency?
++ const bool _carry_dependency;
++
++ protected:
++ virtual uint cmp( const Node &n ) const;
++ virtual uint size_of() const;
++
+ public:
+- CastIINode (Node *n, const Type *t ): ConstraintCastNode(n,t) {}
++ CastIINode(Node *n, const Type *t, bool carry_dependency = false)
++ : ConstraintCastNode(n,t), _carry_dependency(carry_dependency) {}
+ virtual int Opcode() const;
+ virtual uint ideal_reg() const { return Op_RegI; }
++ virtual Node *Identity( PhaseTransform *phase );
++ virtual const Type *Value( PhaseTransform *phase ) const;
++ virtual Node *Ideal_DU_postCCP( PhaseCCP * );
++#ifndef PRODUCT
++ virtual void dump_spec(outputStream *st) const;
++#endif
+ };
+
+ //------------------------------CastPPNode-------------------------------------
+--- ./hotspot/src/share/vm/opto/doCall.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/doCall.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -115,12 +115,12 @@
+ if (allow_inline && allow_intrinsics) {
+ CallGenerator* cg = find_intrinsic(callee, call_does_dispatch);
+ if (cg != NULL) {
+- if (cg->is_predicted()) {
++ if (cg->is_predicated()) {
+ // Code without intrinsic but, hopefully, inlined.
+ CallGenerator* inline_cg = this->call_generator(callee,
+ vtable_index, call_does_dispatch, jvms, allow_inline, prof_factor, speculative_receiver_type, false);
+ if (inline_cg != NULL) {
+- cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg);
++ cg = CallGenerator::for_predicated_intrinsic(cg, inline_cg);
+ }
+ }
+
+@@ -410,6 +410,11 @@
+ ciInstanceKlass* klass = ciEnv::get_instance_klass_for_declared_method_holder(holder);
+ assert(declared_signature != NULL, "cannot be null");
+
++ // Bump max node limit for JSR292 users
++ if (bc() == Bytecodes::_invokedynamic || orig_callee->is_method_handle_intrinsic()) {
++ C->set_max_node_limit(3*MaxNodeLimit);
++ }
++
+ // uncommon-trap when callee is unloaded, uninitialized or will not link
+ // bailout when too many arguments for register representation
+ if (!will_link || can_not_compile_call_site(orig_callee, klass)) {
+@@ -523,7 +528,7 @@
+ // because exceptions don't return to the call site.)
+ profile_call(receiver);
+
+- JVMState* new_jvms = cg->generate(jvms, this);
++ JVMState* new_jvms = cg->generate(jvms);
+ if (new_jvms == NULL) {
+ // When inlining attempt fails (e.g., too many arguments),
+ // it may contaminate the current compile state, making it
+@@ -537,7 +542,7 @@
+ // intrinsic was expecting to optimize. Should always be possible to
+ // get a normal java call that may inline in that case
+ cg = C->call_generator(cg->method(), vtable_index, call_does_dispatch, jvms, try_inline, prof_factor(), speculative_receiver_type, /* allow_intrinsics= */ false);
+- if ((new_jvms = cg->generate(jvms, this)) == NULL) {
++ if ((new_jvms = cg->generate(jvms)) == NULL) {
+ guarantee(failing(), "call failed to generate: calls should work");
+ return;
+ }
+@@ -791,7 +796,7 @@
+ Node* ex_klass_node = NULL;
+ if (has_ex_handler() && !ex_type->klass_is_exact()) {
+ Node* p = basic_plus_adr( ex_node, ex_node, oopDesc::klass_offset_in_bytes());
+- ex_klass_node = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) );
++ ex_klass_node = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT));
+
+ // Compute the exception klass a little more cleverly.
+ // Obvious solution is to simple do a LoadKlass from the 'ex_node'.
+@@ -799,11 +804,17 @@
+ // each arm of the Phi. If I know something clever about the exceptions
+ // I'm loading the class from, I can replace the LoadKlass with the
+ // klass constant for the exception oop.
+- if( ex_node->is_Phi() ) {
+- ex_klass_node = new (C) PhiNode( ex_node->in(0), TypeKlassPtr::OBJECT );
+- for( uint i = 1; i < ex_node->req(); i++ ) {
+- Node* p = basic_plus_adr( ex_node->in(i), ex_node->in(i), oopDesc::klass_offset_in_bytes() );
+- Node* k = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) );
++ if (ex_node->is_Phi()) {
++ ex_klass_node = new (C) PhiNode(ex_node->in(0), TypeKlassPtr::OBJECT);
++ for (uint i = 1; i < ex_node->req(); i++) {
++ Node* ex_in = ex_node->in(i);
++ if (ex_in == top() || ex_in == NULL) {
++ // This path was not taken.
++ ex_klass_node->init_req(i, top());
++ continue;
++ }
++ Node* p = basic_plus_adr(ex_in, ex_in, oopDesc::klass_offset_in_bytes());
++ Node* k = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT));
+ ex_klass_node->init_req( i, k );
+ }
+ _gvn.set_type(ex_klass_node, TypeKlassPtr::OBJECT);
+--- ./hotspot/src/share/vm/opto/escape.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/escape.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -37,6 +37,8 @@
+
+ ConnectionGraph::ConnectionGraph(Compile * C, PhaseIterGVN *igvn) :
+ _nodes(C->comp_arena(), C->unique(), C->unique(), NULL),
++ _in_worklist(C->comp_arena()),
++ _next_pidx(0),
+ _collecting(true),
+ _verify(false),
+ _compile(C),
+@@ -124,13 +126,19 @@
+ if (C->root() != NULL) {
+ ideal_nodes.push(C->root());
+ }
++ // Processed ideal nodes are unique on ideal_nodes list
++ // but several ideal nodes are mapped to the phantom_obj.
++ // To avoid duplicated entries on the following worklists
++ // add the phantom_obj only once to them.
++ ptnodes_worklist.append(phantom_obj);
++ java_objects_worklist.append(phantom_obj);
+ for( uint next = 0; next < ideal_nodes.size(); ++next ) {
+ Node* n = ideal_nodes.at(next);
+ // Create PointsTo nodes and add them to Connection Graph. Called
+ // only once per ideal node since ideal_nodes is Unique_Node list.
+ add_node_to_connection_graph(n, &delayed_worklist);
+ PointsToNode* ptn = ptnode_adr(n->_idx);
+- if (ptn != NULL) {
++ if (ptn != NULL && ptn != phantom_obj) {
+ ptnodes_worklist.append(ptn);
+ if (ptn->is_JavaObject()) {
+ java_objects_worklist.append(ptn->as_JavaObject());
+@@ -414,7 +422,7 @@
+ }
+ case Op_CreateEx: {
+ // assume that all exception objects globally escape
+- add_java_object(n, PointsToNode::GlobalEscape);
++ map_ideal_node(n, phantom_obj);
+ break;
+ }
+ case Op_LoadKlass:
+@@ -938,7 +946,14 @@
+ strcmp(call->as_CallLeaf()->_name, "aescrypt_encryptBlock") == 0 ||
+ strcmp(call->as_CallLeaf()->_name, "aescrypt_decryptBlock") == 0 ||
+ strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_encryptAESCrypt") == 0 ||
+- strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_decryptAESCrypt") == 0)
++ strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_decryptAESCrypt") == 0 ||
++ strcmp(call->as_CallLeaf()->_name, "sha1_implCompress") == 0 ||
++ strcmp(call->as_CallLeaf()->_name, "sha1_implCompressMB") == 0 ||
++ strcmp(call->as_CallLeaf()->_name, "sha256_implCompress") == 0 ||
++ strcmp(call->as_CallLeaf()->_name, "sha256_implCompressMB") == 0 ||
++ strcmp(call->as_CallLeaf()->_name, "sha512_implCompress") == 0 ||
++ strcmp(call->as_CallLeaf()->_name, "sha512_implCompressMB") == 0 ||
++ strcmp(call->as_CallLeaf()->_name, "multiplyToLen") == 0)
+ ))) {
+ call->dump();
+ fatal(err_msg_res("EA unexpected CallLeaf %s", call->as_CallLeaf()->_name));
+@@ -1058,13 +1073,8 @@
+ // on graph complexity. Observed 8 passes in jvm2008 compiler.compiler.
+ // Set limit to 20 to catch situation when something did go wrong and
+ // bailout Escape Analysis.
+- // Also limit build time to 30 sec (60 in debug VM).
++ // Also limit build time to 20 sec (60 in debug VM), EscapeAnalysisTimeout flag.
+ #define CG_BUILD_ITER_LIMIT 20
+-#ifdef ASSERT
+-#define CG_BUILD_TIME_LIMIT 60.0
+-#else
+-#define CG_BUILD_TIME_LIMIT 30.0
+-#endif
+
+ // Propagate GlobalEscape and ArgEscape escape states and check that
+ // we still have non-escaping objects. The method pushs on _worklist
+@@ -1075,12 +1085,13 @@
+ // Now propagate references to all JavaObject nodes.
+ int java_objects_length = java_objects_worklist.length();
+ elapsedTimer time;
++ bool timeout = false;
+ int new_edges = 1;
+ int iterations = 0;
+ do {
+ while ((new_edges > 0) &&
+- (iterations++ < CG_BUILD_ITER_LIMIT) &&
+- (time.seconds() < CG_BUILD_TIME_LIMIT)) {
++ (iterations++ < CG_BUILD_ITER_LIMIT)) {
++ double start_time = time.seconds();
+ time.start();
+ new_edges = 0;
+ // Propagate references to phantom_object for nodes pushed on _worklist
+@@ -1089,7 +1100,29 @@
+ for (int next = 0; next < java_objects_length; ++next) {
+ JavaObjectNode* ptn = java_objects_worklist.at(next);
+ new_edges += add_java_object_edges(ptn, true);
++
++#define SAMPLE_SIZE 4
++ if ((next % SAMPLE_SIZE) == 0) {
++ // Each 4 iterations calculate how much time it will take
++ // to complete graph construction.
++ time.stop();
++ // Poll for requests from shutdown mechanism to quiesce compiler
++ // because Connection graph construction may take long time.
++ CompileBroker::maybe_block();
++ double stop_time = time.seconds();
++ double time_per_iter = (stop_time - start_time) / (double)SAMPLE_SIZE;
++ double time_until_end = time_per_iter * (double)(java_objects_length - next);
++ if ((start_time + time_until_end) >= EscapeAnalysisTimeout) {
++ timeout = true;
++ break; // Timeout
++ }
++ start_time = stop_time;
++ time.start();
++ }
++#undef SAMPLE_SIZE
++
+ }
++ if (timeout) break;
+ if (new_edges > 0) {
+ // Update escape states on each iteration if graph was updated.
+ if (!find_non_escaped_objects(ptnodes_worklist, non_escaped_worklist)) {
+@@ -1097,9 +1130,12 @@
+ }
+ }
+ time.stop();
++ if (time.seconds() >= EscapeAnalysisTimeout) {
++ timeout = true;
++ break;
++ }
+ }
+- if ((iterations < CG_BUILD_ITER_LIMIT) &&
+- (time.seconds() < CG_BUILD_TIME_LIMIT)) {
++ if ((iterations < CG_BUILD_ITER_LIMIT) && !timeout) {
+ time.start();
+ // Find fields which have unknown value.
+ int fields_length = oop_fields_worklist.length();
+@@ -1112,18 +1148,21 @@
+ }
+ }
+ time.stop();
++ if (time.seconds() >= EscapeAnalysisTimeout) {
++ timeout = true;
++ break;
++ }
+ } else {
+ new_edges = 0; // Bailout
+ }
+ } while (new_edges > 0);
+
+ // Bailout if passed limits.
+- if ((iterations >= CG_BUILD_ITER_LIMIT) ||
+- (time.seconds() >= CG_BUILD_TIME_LIMIT)) {
++ if ((iterations >= CG_BUILD_ITER_LIMIT) || timeout) {
+ Compile* C = _compile;
+ if (C->log() != NULL) {
+ C->log()->begin_elem("connectionGraph_bailout reason='reached ");
+- C->log()->text("%s", (iterations >= CG_BUILD_ITER_LIMIT) ? "iterations" : "time");
++ C->log()->text("%s", timeout ? "time" : "iterations");
+ C->log()->end_elem(" limit'");
+ }
+ assert(ExitEscapeAnalysisOnTimeout, err_msg_res("infinite EA connection graph build (%f sec, %d iterations) with %d nodes and worklist size %d",
+@@ -1140,7 +1179,6 @@
+ #endif
+
+ #undef CG_BUILD_ITER_LIMIT
+-#undef CG_BUILD_TIME_LIMIT
+
+ // Find fields initialized by NULL for non-escaping Allocations.
+ int non_escaped_length = non_escaped_worklist.length();
+@@ -1264,8 +1302,8 @@
+ }
+ }
+ }
+- while(_worklist.length() > 0) {
+- PointsToNode* use = _worklist.pop();
++ for (int l = 0; l < _worklist.length(); l++) {
++ PointsToNode* use = _worklist.at(l);
+ if (PointsToNode::is_base_use(use)) {
+ // Add reference from jobj to field and from field to jobj (field's base).
+ use = PointsToNode::get_use_node(use)->as_Field();
+@@ -1312,6 +1350,8 @@
+ add_field_uses_to_worklist(use->as_Field());
+ }
+ }
++ _worklist.clear();
++ _in_worklist.Reset();
+ return new_edges;
+ }
+
+@@ -1891,7 +1931,7 @@
+ return;
+ }
+ Compile* C = _compile;
+- ptadr = new (C->comp_arena()) LocalVarNode(C, n, es);
++ ptadr = new (C->comp_arena()) LocalVarNode(this, n, es);
+ _nodes.at_put(n->_idx, ptadr);
+ }
+
+@@ -1902,7 +1942,7 @@
+ return;
+ }
+ Compile* C = _compile;
+- ptadr = new (C->comp_arena()) JavaObjectNode(C, n, es);
++ ptadr = new (C->comp_arena()) JavaObjectNode(this, n, es);
+ _nodes.at_put(n->_idx, ptadr);
+ }
+
+@@ -1918,7 +1958,7 @@
+ es = PointsToNode::GlobalEscape;
+ }
+ Compile* C = _compile;
+- FieldNode* field = new (C->comp_arena()) FieldNode(C, n, es, offset, is_oop);
++ FieldNode* field = new (C->comp_arena()) FieldNode(this, n, es, offset, is_oop);
+ _nodes.at_put(n->_idx, field);
+ }
+
+@@ -1932,7 +1972,7 @@
+ return;
+ }
+ Compile* C = _compile;
+- ptadr = new (C->comp_arena()) ArraycopyNode(C, n, es);
++ ptadr = new (C->comp_arena()) ArraycopyNode(this, n, es);
+ _nodes.at_put(n->_idx, ptadr);
+ // Add edge from arraycopy node to source object.
+ (void)add_edge(ptadr, src);
+@@ -2372,7 +2412,7 @@
+ }
+ }
+ }
+- if ((int) (C->live_nodes() + 2*NodeLimitFudgeFactor) > MaxNodeLimit) {
++ if (C->live_nodes() + 2*NodeLimitFudgeFactor > C->max_node_limit()) {
+ if (C->do_escape_analysis() == true && !C->failing()) {
+ // Retry compilation without escape analysis.
+ // If this is the first failure, the sentinel string will "stick"
+@@ -2832,6 +2872,13 @@
+ continue;
+ }
+ }
++
++ const TypeOopPtr *t = igvn->type(n)->isa_oopptr();
++ if (t == NULL)
++ continue; // not a TypeOopPtr
++ if (!t->klass_is_exact())
++ continue; // not an unique type
++
+ if (alloc->is_Allocate()) {
+ // Set the scalar_replaceable flag for allocation
+ // so it could be eliminated.
+@@ -2850,10 +2897,7 @@
+ // - not determined to be ineligible by escape analysis
+ set_map(alloc, n);
+ set_map(n, alloc);
+- const TypeOopPtr *t = igvn->type(n)->isa_oopptr();
+- if (t == NULL)
+- continue; // not a TypeOopPtr
+- const TypeOopPtr* tinst = t->cast_to_exactness(true)->is_oopptr()->cast_to_instance_id(ni);
++ const TypeOopPtr* tinst = t->cast_to_instance_id(ni);
+ igvn->hash_delete(n);
+ igvn->set_type(n, tinst);
+ n->raise_bottom_type(tinst);
+--- ./hotspot/src/share/vm/opto/escape.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/escape.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -125,6 +125,8 @@
+ class FieldNode;
+ class ArraycopyNode;
+
++class ConnectionGraph;
++
+ // ConnectionGraph nodes
+ class PointsToNode : public ResourceObj {
+ GrowableArray<PointsToNode*> _edges; // List of nodes this node points to
+@@ -137,6 +139,7 @@
+
+ Node* const _node; // Ideal node corresponding to this PointsTo node.
+ const int _idx; // Cached ideal node's _idx
++ const uint _pidx; // Index of this node
+
+ public:
+ typedef enum {
+@@ -165,17 +168,9 @@
+ } NodeFlags;
+
+
+- PointsToNode(Compile *C, Node* n, EscapeState es, NodeType type):
+- _edges(C->comp_arena(), 2, 0, NULL),
+- _uses (C->comp_arena(), 2, 0, NULL),
+- _node(n),
+- _idx(n->_idx),
+- _type((u1)type),
+- _escape((u1)es),
+- _fields_escape((u1)es),
+- _flags(ScalarReplaceable) {
+- assert(n != NULL && es != UnknownEscape, "sanity");
+- }
++ inline PointsToNode(ConnectionGraph* CG, Node* n, EscapeState es, NodeType type);
++
++ uint pidx() const { return _pidx; }
+
+ Node* ideal_node() const { return _node; }
+ int idx() const { return _idx; }
+@@ -243,14 +238,14 @@
+
+ class LocalVarNode: public PointsToNode {
+ public:
+- LocalVarNode(Compile *C, Node* n, EscapeState es):
+- PointsToNode(C, n, es, LocalVar) {}
++ LocalVarNode(ConnectionGraph *CG, Node* n, EscapeState es):
++ PointsToNode(CG, n, es, LocalVar) {}
+ };
+
+ class JavaObjectNode: public PointsToNode {
+ public:
+- JavaObjectNode(Compile *C, Node* n, EscapeState es):
+- PointsToNode(C, n, es, JavaObject) {
++ JavaObjectNode(ConnectionGraph *CG, Node* n, EscapeState es):
++ PointsToNode(CG, n, es, JavaObject) {
+ if (es > NoEscape)
+ set_scalar_replaceable(false);
+ }
+@@ -262,8 +257,8 @@
+ const bool _is_oop; // Field points to object
+ bool _has_unknown_base; // Has phantom_object base
+ public:
+- FieldNode(Compile *C, Node* n, EscapeState es, int offs, bool is_oop):
+- PointsToNode(C, n, es, Field),
++ FieldNode(ConnectionGraph *CG, Node* n, EscapeState es, int offs, bool is_oop):
++ PointsToNode(CG, n, es, Field),
+ _offset(offs), _is_oop(is_oop),
+ _has_unknown_base(false) {}
+
+@@ -284,8 +279,8 @@
+
+ class ArraycopyNode: public PointsToNode {
+ public:
+- ArraycopyNode(Compile *C, Node* n, EscapeState es):
+- PointsToNode(C, n, es, Arraycopy) {}
++ ArraycopyNode(ConnectionGraph *CG, Node* n, EscapeState es):
++ PointsToNode(CG, n, es, Arraycopy) {}
+ };
+
+ // Iterators for PointsTo node's edges:
+@@ -323,11 +318,14 @@
+
+
+ class ConnectionGraph: public ResourceObj {
++ friend class PointsToNode;
+ private:
+ GrowableArray<PointsToNode*> _nodes; // Map from ideal nodes to
+ // ConnectionGraph nodes.
+
+ GrowableArray<PointsToNode*> _worklist; // Nodes to be processed
++ VectorSet _in_worklist;
++ uint _next_pidx;
+
+ bool _collecting; // Indicates whether escape information
+ // is still being collected. If false,
+@@ -353,6 +351,8 @@
+ }
+ uint nodes_size() const { return _nodes.length(); }
+
++ uint next_pidx() { return _next_pidx++; }
++
+ // Add nodes to ConnectionGraph.
+ void add_local_var(Node* n, PointsToNode::EscapeState es);
+ void add_java_object(Node* n, PointsToNode::EscapeState es);
+@@ -396,15 +396,26 @@
+ int add_java_object_edges(JavaObjectNode* jobj, bool populate_worklist);
+
+ // Put node on worklist if it is (or was) not there.
+- void add_to_worklist(PointsToNode* pt) {
+- _worklist.push(pt);
+- return;
++ inline void add_to_worklist(PointsToNode* pt) {
++ PointsToNode* ptf = pt;
++ uint pidx_bias = 0;
++ if (PointsToNode::is_base_use(pt)) {
++ // Create a separate entry in _in_worklist for a marked base edge
++ // because _worklist may have an entry for a normal edge pointing
++ // to the same node. To separate them use _next_pidx as bias.
++ ptf = PointsToNode::get_use_node(pt)->as_Field();
++ pidx_bias = _next_pidx;
++ }
++ if (!_in_worklist.test_set(ptf->pidx() + pidx_bias)) {
++ _worklist.append(pt);
++ }
+ }
+
+ // Put on worklist all uses of this node.
+- void add_uses_to_worklist(PointsToNode* pt) {
+- for (UseIterator i(pt); i.has_next(); i.next())
+- _worklist.push(i.get());
++ inline void add_uses_to_worklist(PointsToNode* pt) {
++ for (UseIterator i(pt); i.has_next(); i.next()) {
++ add_to_worklist(i.get());
++ }
+ }
+
+ // Put on worklist all field's uses and related field nodes.
+@@ -517,8 +528,8 @@
+ }
+ // Helper functions
+ bool is_oop_field(Node* n, int offset, bool* unsafe);
+- static Node* get_addp_base(Node *addp);
+- static Node* find_second_addp(Node* addp, Node* n);
++ static Node* get_addp_base(Node *addp);
++ static Node* find_second_addp(Node* addp, Node* n);
+ // offset of a field reference
+ int address_offset(Node* adr, PhaseTransform *phase);
+
+@@ -587,4 +598,17 @@
+ #endif
+ };
+
++inline PointsToNode::PointsToNode(ConnectionGraph *CG, Node* n, EscapeState es, NodeType type):
++ _edges(CG->_compile->comp_arena(), 2, 0, NULL),
++ _uses (CG->_compile->comp_arena(), 2, 0, NULL),
++ _node(n),
++ _idx(n->_idx),
++ _pidx(CG->next_pidx()),
++ _type((u1)type),
++ _escape((u1)es),
++ _fields_escape((u1)es),
++ _flags(ScalarReplaceable) {
++ assert(n != NULL && es != UnknownEscape, "sanity");
++}
++
+ #endif // SHARE_VM_OPTO_ESCAPE_HPP
+--- ./hotspot/src/share/vm/opto/graphKit.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/graphKit.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -428,6 +428,7 @@
+ }
+ }
+ }
++ phi_map->merge_replaced_nodes_with(ex_map);
+ }
+
+ //--------------------------use_exception_state--------------------------------
+@@ -641,7 +642,6 @@
+ _map = kit->map(); // preserve the map
+ _sp = kit->sp();
+ kit->set_map(clone_map ? kit->clone_map() : NULL);
+- Compile::current()->inc_preserve_jvm_state();
+ #ifdef ASSERT
+ _bci = kit->bci();
+ Parse* parser = kit->is_Parse();
+@@ -659,7 +659,6 @@
+ #endif
+ kit->set_map(_map);
+ kit->set_sp(_sp);
+- Compile::current()->dec_preserve_jvm_state();
+ }
+
+
+@@ -1151,7 +1150,7 @@
+ Node* akls = AllocateNode::Ideal_klass(obj, &_gvn);
+ if (akls != NULL) return akls;
+ Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
+- return _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), k_adr, TypeInstPtr::KLASS) );
++ return _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), k_adr, TypeInstPtr::KLASS));
+ }
+
+ //-------------------------load_array_length-----------------------------------
+@@ -1398,60 +1397,17 @@
+ // on the map. This includes locals, stack, and monitors
+ // of the current (innermost) JVM state.
+
+- if (!ReplaceInParentMaps) {
++ // don't let inconsistent types from profiling escape this
++ // method
++
++ const Type* told = _gvn.type(old);
++ const Type* tnew = _gvn.type(neww);
++
++ if (!tnew->higher_equal(told)) {
+ return;
+ }
+
+- // PreserveJVMState doesn't do a deep copy so we can't modify
+- // parents
+- if (Compile::current()->has_preserve_jvm_state()) {
+- return;
+- }
+-
+- Parse* parser = is_Parse();
+- bool progress = true;
+- Node* ctrl = map()->in(0);
+- // Follow the chain of parsers and see whether the update can be
+- // done in the map of callers. We can do the replace for a caller if
+- // the current control post dominates the control of a caller.
+- while (parser != NULL && parser->caller() != NULL && progress) {
+- progress = false;
+- Node* parent_map = parser->caller()->map();
+- assert(parser->exits().map()->jvms()->depth() == parser->caller()->depth(), "map mismatch");
+-
+- Node* parent_ctrl = parent_map->in(0);
+-
+- while (parent_ctrl->is_Region()) {
+- Node* n = parent_ctrl->as_Region()->is_copy();
+- if (n == NULL) {
+- break;
+- }
+- parent_ctrl = n;
+- }
+-
+- for (;;) {
+- if (ctrl == parent_ctrl) {
+- // update the map of the exits which is the one that will be
+- // used when compilation resume after inlining
+- parser->exits().map()->replace_edge(old, neww);
+- progress = true;
+- break;
+- }
+- if (ctrl->is_Proj() && ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none)) {
+- ctrl = ctrl->in(0)->in(0);
+- } else if (ctrl->is_Region()) {
+- Node* n = ctrl->as_Region()->is_copy();
+- if (n == NULL) {
+- break;
+- }
+- ctrl = n;
+- } else {
+- break;
+- }
+- }
+-
+- parser = parser->parent_parser();
+- }
++ map()->record_replaced_node(old, neww);
+ }
+
+
+@@ -1855,12 +1811,16 @@
+
+
+ // Replace the call with the current state of the kit.
+-void GraphKit::replace_call(CallNode* call, Node* result) {
++void GraphKit::replace_call(CallNode* call, Node* result, bool do_replaced_nodes) {
+ JVMState* ejvms = NULL;
+ if (has_exceptions()) {
+ ejvms = transfer_exceptions_into_jvms();
+ }
+
++ ReplacedNodes replaced_nodes = map()->replaced_nodes();
++ ReplacedNodes replaced_nodes_exception;
++ Node* ex_ctl = top();
++
+ SafePointNode* final_state = stop();
+
+ // Find all the needed outputs of this call
+@@ -1877,6 +1837,10 @@
+ C->gvn_replace_by(callprojs.fallthrough_catchproj, final_ctl);
+ }
+ if (callprojs.fallthrough_memproj != NULL) {
++ if (final_mem->is_MergeMem()) {
++ // Parser's exits MergeMem was not transformed but may be optimized
++ final_mem = _gvn.transform(final_mem);
++ }
+ C->gvn_replace_by(callprojs.fallthrough_memproj, final_mem);
+ }
+ if (callprojs.fallthrough_ioproj != NULL) {
+@@ -1908,10 +1872,13 @@
+
+ // Load my combined exception state into the kit, with all phis transformed:
+ SafePointNode* ex_map = ekit.combine_and_pop_all_exception_states();
++ replaced_nodes_exception = ex_map->replaced_nodes();
+
+ Node* ex_oop = ekit.use_exception_state(ex_map);
++
+ if (callprojs.catchall_catchproj != NULL) {
+ C->gvn_replace_by(callprojs.catchall_catchproj, ekit.control());
++ ex_ctl = ekit.control();
+ }
+ if (callprojs.catchall_memproj != NULL) {
+ C->gvn_replace_by(callprojs.catchall_memproj, ekit.reset_memory());
+@@ -1944,6 +1911,13 @@
+ _gvn.transform(wl.pop());
+ }
+ }
++
++ if (callprojs.fallthrough_catchproj != NULL && !final_ctl->is_top() && do_replaced_nodes) {
++ replaced_nodes.apply(C, final_ctl);
++ }
++ if (!ex_ctl->is_top() && do_replaced_nodes) {
++ replaced_nodes_exception.apply(C, ex_ctl);
++ }
+ }
+
+
+@@ -2435,23 +2409,24 @@
+ Node* new_slice = mms.memory2();
+ if (old_slice != new_slice) {
+ PhiNode* phi;
+- if (new_slice->is_Phi() && new_slice->as_Phi()->region() == region) {
+- phi = new_slice->as_Phi();
+- #ifdef ASSERT
+- if (old_slice->is_Phi() && old_slice->as_Phi()->region() == region)
+- old_slice = old_slice->in(new_path);
+- // Caller is responsible for ensuring that any pre-existing
+- // phis are already aware of old memory.
+- int old_path = (new_path > 1) ? 1 : 2; // choose old_path != new_path
+- assert(phi->in(old_path) == old_slice, "pre-existing phis OK");
+- #endif
+- mms.set_memory(phi);
++ if (old_slice->is_Phi() && old_slice->as_Phi()->region() == region) {
++ if (mms.is_empty()) {
++ // clone base memory Phi's inputs for this memory slice
++ assert(old_slice == mms.base_memory(), "sanity");
++ phi = PhiNode::make(region, NULL, Type::MEMORY, mms.adr_type(C));
++ _gvn.set_type(phi, Type::MEMORY);
++ for (uint i = 1; i < phi->req(); i++) {
++ phi->init_req(i, old_slice->in(i));
++ }
++ } else {
++ phi = old_slice->as_Phi(); // Phi was generated already
++ }
+ } else {
+ phi = PhiNode::make(region, old_slice, Type::MEMORY, mms.adr_type(C));
+ _gvn.set_type(phi, Type::MEMORY);
+- phi->set_req(new_path, new_slice);
+- mms.set_memory(_gvn.transform(phi)); // assume it is complete
+ }
++ phi->set_req(new_path, new_slice);
++ mms.set_memory(phi);
+ }
+ }
+ }
+@@ -2567,7 +2542,7 @@
+ // cache which is mutable so can't use immutable memory. Other
+ // types load from the super-class display table which is immutable.
+ Node *kmem = might_be_cache ? memory(p2) : immutable_memory();
+- Node *nkls = _gvn.transform( LoadKlassNode::make( _gvn, kmem, p2, _gvn.type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL ) );
++ Node* nkls = _gvn.transform(LoadKlassNode::make(_gvn, NULL, kmem, p2, _gvn.type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL));
+
+ // Compile speed common case: ARE a subtype and we canNOT fail
+ if( superklass == nkls )
+--- ./hotspot/src/share/vm/opto/graphKit.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/graphKit.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -685,7 +685,7 @@
+ // Replace the call with the current state of the kit. Requires
+ // that the call was generated with separate io_projs so that
+ // exceptional control flow can be handled properly.
+- void replace_call(CallNode* call, Node* result);
++ void replace_call(CallNode* call, Node* result, bool do_replaced_nodes = false);
+
+ // helper functions for statistics
+ void increment_counter(address counter_addr); // increment a debug counter
+--- ./hotspot/src/share/vm/opto/ifg.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/ifg.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -541,17 +541,37 @@
+ if( !n->is_Proj() ||
+ // Could also be a flags-projection of a dead ADD or such.
+ (_lrg_map.live_range_id(def) && !liveout.member(_lrg_map.live_range_id(def)))) {
+- block->remove_node(j - 1);
+- if (lrgs(r)._def == n) {
+- lrgs(r)._def = 0;
++ bool remove = true;
++ if (n->is_MachProj()) {
++ // Don't remove KILL projections if their "defining" nodes have
++ // memory effects (have SCMemProj projection node) -
++ // they are not dead even when their result is not used.
++ // For example, compareAndSwapL (and other CAS) and EncodeISOArray nodes.
++ // 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) {
++ remove = false;
++ break;
++ }
++ }
+ }
+- n->disconnect_inputs(NULL, C);
+- _cfg.unmap_node_from_block(n);
+- n->replace_by(C->top());
+- // Since yanking a Node from block, high pressure moves up one
+- hrp_index[0]--;
+- hrp_index[1]--;
+- continue;
++ if (remove) {
++ block->remove_node(j - 1);
++ if (lrgs(r)._def == n) {
++ lrgs(r)._def = 0;
++ }
++ n->disconnect_inputs(NULL, C);
++ _cfg.unmap_node_from_block(n);
++ n->replace_by(C->top());
++ // Since yanking a Node from block, high pressure moves up one
++ hrp_index[0]--;
++ hrp_index[1]--;
++ continue;
++ }
+ }
+
+ // Fat-projections kill many registers which cannot be used to
+--- ./hotspot/src/share/vm/opto/ifnode.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/ifnode.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -820,6 +820,11 @@
+
+ static IfNode* idealize_test(PhaseGVN* phase, IfNode* iff);
+
++struct RangeCheck {
++ Node* ctl;
++ jint off;
++};
++
+ //------------------------------Ideal------------------------------------------
+ // Return a node which is more "ideal" than the current node. Strip out
+ // control copies
+@@ -861,83 +866,141 @@
+ jint offset1;
+ int flip1 = is_range_check(range1, index1, offset1);
+ if( flip1 ) {
+- Node *first_prev_dom = NULL;
+-
+ // Try to remove extra range checks. All 'up_one_dom' gives up at merges
+ // so all checks we inspect post-dominate the top-most check we find.
+ // If we are going to fail the current check and we reach the top check
+ // then we are guaranteed to fail, so just start interpreting there.
+- // We 'expand' the top 2 range checks to include all post-dominating
++ // We 'expand' the top 3 range checks to include all post-dominating
+ // checks.
+
+- // The top 2 range checks seen
+- Node *prev_chk1 = NULL;
+- Node *prev_chk2 = NULL;
++ // The top 3 range checks seen
++ const int NRC =3;
++ RangeCheck prev_checks[NRC];
++ int nb_checks = 0;
++
+ // Low and high offsets seen so far
+ jint off_lo = offset1;
+ jint off_hi = offset1;
+
+- // Scan for the top 2 checks and collect range of offsets
+- for( int dist = 0; dist < 999; dist++ ) { // Range-Check scan limit
+- if( dom->Opcode() == Op_If && // Not same opcode?
+- prev_dom->in(0) == dom ) { // One path of test does dominate?
+- if( dom == this ) return NULL; // dead loop
++ bool found_immediate_dominator = false;
++
++ // Scan for the top checks and collect range of offsets
++ for (int dist = 0; dist < 999; dist++) { // Range-Check scan limit
++ if (dom->Opcode() == Op_If && // Not same opcode?
++ prev_dom->in(0) == dom) { // One path of test does dominate?
++ if (dom == this) return NULL; // dead loop
+ // See if this is a range check
+ Node *index2, *range2;
+ jint offset2;
+ int flip2 = dom->as_If()->is_range_check(range2, index2, offset2);
+ // See if this is a _matching_ range check, checking against
+ // the same array bounds.
+- if( flip2 == flip1 && range2 == range1 && index2 == index1 &&
+- dom->outcnt() == 2 ) {
++ if (flip2 == flip1 && range2 == range1 && index2 == index1 &&
++ dom->outcnt() == 2) {
++ if (nb_checks == 0 && dom->in(1) == in(1)) {
++ // Found an immediately dominating test at the same offset.
++ // This kind of back-to-back test can be eliminated locally,
++ // and there is no need to search further for dominating tests.
++ assert(offset2 == offset1, "Same test but different offsets");
++ found_immediate_dominator = true;
++ break;
++ }
+ // Gather expanded bounds
+ off_lo = MIN2(off_lo,offset2);
+ off_hi = MAX2(off_hi,offset2);
+- // Record top 2 range checks
+- prev_chk2 = prev_chk1;
+- prev_chk1 = prev_dom;
+- // If we match the test exactly, then the top test covers
+- // both our lower and upper bounds.
+- if( dom->in(1) == in(1) )
+- prev_chk2 = prev_chk1;
++ // Record top NRC range checks
++ prev_checks[nb_checks%NRC].ctl = prev_dom;
++ prev_checks[nb_checks%NRC].off = offset2;
++ nb_checks++;
+ }
+ }
+ prev_dom = dom;
+- dom = up_one_dom( dom );
+- if( !dom ) break;
++ dom = up_one_dom(dom);
++ if (!dom) break;
+ }
+
++ if (!found_immediate_dominator) {
++ // Attempt to widen the dominating range check to cover some later
++ // ones. Since range checks "fail" by uncommon-trapping to the
++ // interpreter, widening a check can make us speculatively enter
++ // the interpreter. If we see range-check deopt's, do not widen!
++ if (!phase->C->allow_range_check_smearing()) return NULL;
+
+- // Attempt to widen the dominating range check to cover some later
+- // ones. Since range checks "fail" by uncommon-trapping to the
+- // interpreter, widening a check can make us speculative enter the
+- // interpreter. If we see range-check deopt's, do not widen!
+- if (!phase->C->allow_range_check_smearing()) return NULL;
+-
+- // Constant indices only need to check the upper bound.
+- // Non-constance indices must check both low and high.
+- if( index1 ) {
+- // Didn't find 2 prior covering checks, so cannot remove anything.
+- if( !prev_chk2 ) return NULL;
+- // 'Widen' the offsets of the 1st and 2nd covering check
+- adjust_check( prev_chk1, range1, index1, flip1, off_lo, igvn );
+- // Do not call adjust_check twice on the same projection
+- // as the first call may have transformed the BoolNode to a ConI
+- if( prev_chk1 != prev_chk2 ) {
+- adjust_check( prev_chk2, range1, index1, flip1, off_hi, igvn );
++ // Didn't find prior covering check, so cannot remove anything.
++ if (nb_checks == 0) {
++ return NULL;
+ }
+- // Test is now covered by prior checks, dominate it out
+- prev_dom = prev_chk2;
+- } else {
+- // Didn't find prior covering check, so cannot remove anything.
+- if( !prev_chk1 ) return NULL;
+- // 'Widen' the offset of the 1st and only covering check
+- adjust_check( prev_chk1, range1, index1, flip1, off_hi, igvn );
+- // Test is now covered by prior checks, dominate it out
+- prev_dom = prev_chk1;
++ // Constant indices only need to check the upper bound.
++ // Non-constant indices must check both low and high.
++ int chk0 = (nb_checks - 1) % NRC;
++ if (index1) {
++ if (nb_checks == 1) {
++ return NULL;
++ } else {
++ // If the top range check's constant is the min or max of
++ // all constants we widen the next one to cover the whole
++ // range of constants.
++ RangeCheck rc0 = prev_checks[chk0];
++ int chk1 = (nb_checks - 2) % NRC;
++ RangeCheck rc1 = prev_checks[chk1];
++ if (rc0.off == off_lo) {
++ adjust_check(rc1.ctl, range1, index1, flip1, off_hi, igvn);
++ prev_dom = rc1.ctl;
++ } else if (rc0.off == off_hi) {
++ adjust_check(rc1.ctl, range1, index1, flip1, off_lo, igvn);
++ prev_dom = rc1.ctl;
++ } else {
++ // If the top test's constant is not the min or max of all
++ // constants, we need 3 range checks. We must leave the
++ // top test unchanged because widening it would allow the
++ // accesses it protects to successfully read/write out of
++ // bounds.
++ if (nb_checks == 2) {
++ return NULL;
++ }
++ int chk2 = (nb_checks - 3) % NRC;
++ RangeCheck rc2 = prev_checks[chk2];
++ // The top range check a+i covers interval: -a <= i < length-a
++ // The second range check b+i covers interval: -b <= i < length-b
++ if (rc1.off <= rc0.off) {
++ // if b <= a, we change the second range check to:
++ // -min_of_all_constants <= i < length-min_of_all_constants
++ // Together top and second range checks now cover:
++ // -min_of_all_constants <= i < length-a
++ // which is more restrictive than -b <= i < length-b:
++ // -b <= -min_of_all_constants <= i < length-a <= length-b
++ // The third check is then changed to:
++ // -max_of_all_constants <= i < length-max_of_all_constants
++ // so 2nd and 3rd checks restrict allowed values of i to:
++ // -min_of_all_constants <= i < length-max_of_all_constants
++ adjust_check(rc1.ctl, range1, index1, flip1, off_lo, igvn);
++ adjust_check(rc2.ctl, range1, index1, flip1, off_hi, igvn);
++ } else {
++ // if b > a, we change the second range check to:
++ // -max_of_all_constants <= i < length-max_of_all_constants
++ // Together top and second range checks now cover:
++ // -a <= i < length-max_of_all_constants
++ // which is more restrictive than -b <= i < length-b:
++ // -b < -a <= i < length-max_of_all_constants <= length-b
++ // The third check is then changed to:
++ // -max_of_all_constants <= i < length-max_of_all_constants
++ // so 2nd and 3rd checks restrict allowed values of i to:
++ // -min_of_all_constants <= i < length-max_of_all_constants
++ adjust_check(rc1.ctl, range1, index1, flip1, off_hi, igvn);
++ adjust_check(rc2.ctl, range1, index1, flip1, off_lo, igvn);
++ }
++ prev_dom = rc2.ctl;
++ }
++ }
++ } else {
++ RangeCheck rc0 = prev_checks[chk0];
++ // 'Widen' the offset of the 1st and only covering check
++ adjust_check(rc0.ctl, range1, index1, flip1, off_hi, igvn);
++ // Test is now covered by prior checks, dominate it out
++ prev_dom = rc0.ctl;
++ }
+ }
+
+-
+ } else { // Scan for an equivalent test
+
+ Node *cmp;
+@@ -1019,7 +1082,7 @@
+ // for lower and upper bounds.
+ ProjNode* unc_proj = proj_out(1 - prev_dom->as_Proj()->_con)->as_Proj();
+ if (unc_proj->is_uncommon_trap_proj(Deoptimization::Reason_predicate))
+- prev_dom = idom;
++ prev_dom = idom;
+
+ // Now walk the current IfNode's projections.
+ // Loop ends when 'this' has no more uses.
+--- ./hotspot/src/share/vm/opto/library_call.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/library_call.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -46,25 +46,28 @@
+ public:
+ private:
+ bool _is_virtual;
+- bool _is_predicted;
+ bool _does_virtual_dispatch;
++ int8_t _predicates_count; // Intrinsic is predicated by several conditions
++ int8_t _last_predicate; // Last generated predicate
+ vmIntrinsics::ID _intrinsic_id;
+
+ public:
+- LibraryIntrinsic(ciMethod* m, bool is_virtual, bool is_predicted, bool does_virtual_dispatch, vmIntrinsics::ID id)
++ LibraryIntrinsic(ciMethod* m, bool is_virtual, int predicates_count, bool does_virtual_dispatch, vmIntrinsics::ID id)
+ : InlineCallGenerator(m),
+ _is_virtual(is_virtual),
+- _is_predicted(is_predicted),
+ _does_virtual_dispatch(does_virtual_dispatch),
++ _predicates_count((int8_t)predicates_count),
++ _last_predicate((int8_t)-1),
+ _intrinsic_id(id)
+ {
+ }
+ virtual bool is_intrinsic() const { return true; }
+ virtual bool is_virtual() const { return _is_virtual; }
+- virtual bool is_predicted() const { return _is_predicted; }
++ virtual bool is_predicated() const { return _predicates_count > 0; }
++ virtual int predicates_count() const { return _predicates_count; }
+ virtual bool does_virtual_dispatch() const { return _does_virtual_dispatch; }
+- virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
+- virtual Node* generate_predicate(JVMState* jvms);
++ virtual JVMState* generate(JVMState* jvms);
++ virtual Node* generate_predicate(JVMState* jvms, int predicate);
+ vmIntrinsics::ID intrinsic_id() const { return _intrinsic_id; }
+ };
+
+@@ -107,8 +110,8 @@
+ vmIntrinsics::ID intrinsic_id() const { return _intrinsic->intrinsic_id(); }
+ ciMethod* callee() const { return _intrinsic->method(); }
+
+- bool try_to_inline();
+- Node* try_to_predicate();
++ bool try_to_inline(int predicate);
++ Node* try_to_predicate(int predicate);
+
+ void push_result() {
+ // Push the result onto the stack.
+@@ -307,10 +310,19 @@
+ Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
+ Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
+ Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
++ bool inline_sha_implCompress(vmIntrinsics::ID id);
++ bool inline_digestBase_implCompressMB(int predicate);
++ bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA,
++ bool long_state, address stubAddr, const char *stubName,
++ Node* src_start, Node* ofs, Node* limit);
++ Node* get_state_from_sha_object(Node *sha_object);
++ Node* get_state_from_sha5_object(Node *sha_object);
++ Node* inline_digestBase_implCompressMB_predicate(int predicate);
+ bool inline_encodeISOArray();
+ bool inline_updateCRC32();
+ bool inline_updateBytesCRC32();
+ bool inline_updateByteBufferCRC32();
++ bool inline_multiplyToLen();
+ };
+
+
+@@ -319,8 +331,12 @@
+ vmIntrinsics::ID id = m->intrinsic_id();
+ assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
+
+- if (DisableIntrinsic[0] != '\0'
+- && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) {
++ ccstr disable_intr = NULL;
++
++ if ((DisableIntrinsic[0] != '\0'
++ && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) ||
++ (method_has_option_value("DisableIntrinsic", disable_intr)
++ && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) {
+ // disabled by a user request on the command line:
+ // example: -XX:DisableIntrinsic=_hashCode,_getClass
+ return NULL;
+@@ -367,7 +383,7 @@
+ }
+ }
+
+- bool is_predicted = false;
++ int predicates = 0;
+ bool does_virtual_dispatch = false;
+
+ switch (id) {
+@@ -504,11 +520,32 @@
+ if (!UseAESIntrinsics) return NULL;
+ break;
+
++ case vmIntrinsics::_multiplyToLen:
++ if (!UseMultiplyToLenIntrinsic) return NULL;
++ break;
++
+ case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
+ case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
+ if (!UseAESIntrinsics) return NULL;
+ // these two require the predicated logic
+- is_predicted = true;
++ predicates = 1;
++ break;
++
++ case vmIntrinsics::_sha_implCompress:
++ if (!UseSHA1Intrinsics) return NULL;
++ break;
++
++ case vmIntrinsics::_sha2_implCompress:
++ if (!UseSHA256Intrinsics) return NULL;
++ break;
++
++ case vmIntrinsics::_sha5_implCompress:
++ if (!UseSHA512Intrinsics) return NULL;
++ break;
++
++ case vmIntrinsics::_digestBase_implCompressMB:
++ if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) return NULL;
++ predicates = 3;
+ break;
+
+ case vmIntrinsics::_updateCRC32:
+@@ -577,7 +614,7 @@
+ if (!InlineUnsafeOps) return NULL;
+ }
+
+- return new LibraryIntrinsic(m, is_virtual, is_predicted, does_virtual_dispatch, (vmIntrinsics::ID) id);
++ return new LibraryIntrinsic(m, is_virtual, predicates, does_virtual_dispatch, (vmIntrinsics::ID) id);
+ }
+
+ //----------------------register_library_intrinsics-----------------------
+@@ -586,7 +623,7 @@
+ // Nothing to do here.
+ }
+
+-JVMState* LibraryIntrinsic::generate(JVMState* jvms, Parse* parent_parser) {
++JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
+ LibraryCallKit kit(jvms, this);
+ Compile* C = kit.C;
+ int nodes = C->unique();
+@@ -601,7 +638,7 @@
+ const int bci = kit.bci();
+
+ // Try to inline the intrinsic.
+- if (kit.try_to_inline()) {
++ if (kit.try_to_inline(_last_predicate)) {
+ if (C->print_intrinsics() || C->print_inlining()) {
+ C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)");
+ }
+@@ -634,12 +671,13 @@
+ return NULL;
+ }
+
+-Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) {
++Node* LibraryIntrinsic::generate_predicate(JVMState* jvms, int predicate) {
+ LibraryCallKit kit(jvms, this);
+ Compile* C = kit.C;
+ int nodes = C->unique();
++ _last_predicate = predicate;
+ #ifndef PRODUCT
+- assert(is_predicted(), "sanity");
++ assert(is_predicated() && predicate < predicates_count(), "sanity");
+ if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
+ char buf[1000];
+ const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf));
+@@ -649,10 +687,10 @@
+ ciMethod* callee = kit.callee();
+ const int bci = kit.bci();
+
+- Node* slow_ctl = kit.try_to_predicate();
++ Node* slow_ctl = kit.try_to_predicate(predicate);
+ if (!kit.failing()) {
+ if (C->print_intrinsics() || C->print_inlining()) {
+- C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)");
++ C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual, predicate)" : "(intrinsic, predicate)");
+ }
+ C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked);
+ if (C->log()) {
+@@ -681,7 +719,7 @@
+ return NULL;
+ }
+
+-bool LibraryCallKit::try_to_inline() {
++bool LibraryCallKit::try_to_inline(int predicate) {
+ // Handle symbolic names for otherwise undistinguished boolean switches:
+ const bool is_store = true;
+ const bool is_native_ptr = true;
+@@ -875,6 +913,17 @@
+ case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
+ return inline_cipherBlockChaining_AESCrypt(intrinsic_id());
+
++ case vmIntrinsics::_sha_implCompress:
++ case vmIntrinsics::_sha2_implCompress:
++ case vmIntrinsics::_sha5_implCompress:
++ return inline_sha_implCompress(intrinsic_id());
++
++ case vmIntrinsics::_digestBase_implCompressMB:
++ return inline_digestBase_implCompressMB(predicate);
++
++ case vmIntrinsics::_multiplyToLen:
++ return inline_multiplyToLen();
++
+ case vmIntrinsics::_encodeISOArray:
+ return inline_encodeISOArray();
+
+@@ -898,7 +947,7 @@
+ }
+ }
+
+-Node* LibraryCallKit::try_to_predicate() {
++Node* LibraryCallKit::try_to_predicate(int predicate) {
+ if (!jvms()->has_method()) {
+ // Root JVMState has a null method.
+ assert(map()->memory()->Opcode() == Op_Parm, "");
+@@ -912,6 +961,8 @@
+ return inline_cipherBlockChaining_AESCrypt_predicate(false);
+ case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
+ return inline_cipherBlockChaining_AESCrypt_predicate(true);
++ case vmIntrinsics::_digestBase_implCompressMB:
++ return inline_digestBase_implCompressMB_predicate(predicate);
+
+ default:
+ // If you get here, it may be that someone has added a new intrinsic
+@@ -2611,7 +2662,8 @@
+ if (need_mem_bar) insert_mem_bar(Op_MemBarCPUOrder);
+
+ if (!is_store) {
+- Node* p = make_load(control(), adr, value_type, type, adr_type, MemNode::unordered, is_volatile);
++ MemNode::MemOrd mo = is_volatile ? MemNode::acquire : MemNode::unordered;
++ Node* p = make_load(control(), adr, value_type, type, adr_type, mo, is_volatile);
+ // load value
+ switch (type) {
+ case T_BOOLEAN:
+@@ -3346,7 +3398,7 @@
+ if (region == NULL) never_see_null = true;
+ Node* p = basic_plus_adr(mirror, offset);
+ const TypeKlassPtr* kls_type = TypeKlassPtr::OBJECT_OR_NULL;
+- Node* kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type));
++ Node* kls = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type));
+ Node* null_ctl = top();
+ kls = null_check_oop(kls, &null_ctl, never_see_null);
+ if (region != NULL) {
+@@ -3522,7 +3574,7 @@
+ phi->add_req(makecon(TypeInstPtr::make(env()->Object_klass()->java_mirror())));
+ // If we fall through, it's a plain class. Get its _super.
+ p = basic_plus_adr(kls, in_bytes(Klass::super_offset()));
+- kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeKlassPtr::OBJECT_OR_NULL));
++ kls = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeKlassPtr::OBJECT_OR_NULL));
+ null_ctl = top();
+ kls = null_check_oop(kls, &null_ctl);
+ if (null_ctl != top()) {
+@@ -3604,7 +3656,7 @@
+ args[which_arg] = arg;
+
+ Node* p = basic_plus_adr(arg, class_klass_offset);
+- Node* kls = LoadKlassNode::make(_gvn, immutable_memory(), p, adr_type, kls_type);
++ Node* kls = LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, adr_type, kls_type);
+ klasses[which_arg] = _gvn.transform(kls);
+ }
+
+@@ -5120,7 +5172,7 @@
+ // (At this point we can assume disjoint_bases, since types differ.)
+ int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset());
+ Node* p1 = basic_plus_adr(dest_klass, ek_offset);
+- Node* n1 = LoadKlassNode::make(_gvn, immutable_memory(), p1, TypeRawPtr::BOTTOM);
++ Node* n1 = LoadKlassNode::make(_gvn, NULL, immutable_memory(), p1, TypeRawPtr::BOTTOM);
+ Node* dest_elem_klass = _gvn.transform(n1);
+ Node* cv = generate_checkcast_arraycopy(adr_type,
+ dest_elem_klass,
+@@ -5695,6 +5747,108 @@
+ return true;
+ }
+
++//-------------inline_multiplyToLen-----------------------------------
++bool LibraryCallKit::inline_multiplyToLen() {
++ assert(UseMultiplyToLenIntrinsic, "not implementated on this platform");
++
++ address stubAddr = StubRoutines::multiplyToLen();
++ if (stubAddr == NULL) {
++ return false; // Intrinsic's stub is not implemented on this platform
++ }
++ const char* stubName = "multiplyToLen";
++
++ assert(callee()->signature()->size() == 5, "multiplyToLen has 5 parameters");
++
++ Node* x = argument(1);
++ Node* xlen = argument(2);
++ Node* y = argument(3);
++ Node* ylen = argument(4);
++ Node* z = argument(5);
++
++ const Type* x_type = x->Value(&_gvn);
++ const Type* y_type = y->Value(&_gvn);
++ const TypeAryPtr* top_x = x_type->isa_aryptr();
++ const TypeAryPtr* top_y = y_type->isa_aryptr();
++ if (top_x == NULL || top_x->klass() == NULL ||
++ top_y == NULL || top_y->klass() == NULL) {
++ // failed array check
++ return false;
++ }
++
++ BasicType x_elem = x_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
++ BasicType y_elem = y_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
++ if (x_elem != T_INT || y_elem != T_INT) {
++ return false;
++ }
++
++ // Set the original stack and the reexecute bit for the interpreter to reexecute
++ // the bytecode that invokes BigInteger.multiplyToLen() if deoptimization happens
++ // on the return from z array allocation in runtime.
++ { PreserveReexecuteState preexecs(this);
++ jvms()->set_should_reexecute(true);
++
++ Node* x_start = array_element_address(x, intcon(0), x_elem);
++ Node* y_start = array_element_address(y, intcon(0), y_elem);
++ // 'x_start' points to x array + scaled xlen
++ // 'y_start' points to y array + scaled ylen
++
++ // Allocate the result array
++ Node* zlen = _gvn.transform(new(C) AddINode(xlen, ylen));
++ ciKlass* klass = ciTypeArrayKlass::make(T_INT);
++ Node* klass_node = makecon(TypeKlassPtr::make(klass));
++
++ IdealKit ideal(this);
++
++#define __ ideal.
++ Node* one = __ ConI(1);
++ Node* zero = __ ConI(0);
++ IdealVariable need_alloc(ideal), z_alloc(ideal); __ declarations_done();
++ __ set(need_alloc, zero);
++ __ set(z_alloc, z);
++ __ if_then(z, BoolTest::eq, null()); {
++ __ increment (need_alloc, one);
++ } __ else_(); {
++ // Update graphKit memory and control from IdealKit.
++ sync_kit(ideal);
++ Node* zlen_arg = load_array_length(z);
++ // Update IdealKit memory and control from graphKit.
++ __ sync_kit(this);
++ __ if_then(zlen_arg, BoolTest::lt, zlen); {
++ __ increment (need_alloc, one);
++ } __ end_if();
++ } __ end_if();
++
++ __ if_then(__ value(need_alloc), BoolTest::ne, zero); {
++ // Update graphKit memory and control from IdealKit.
++ sync_kit(ideal);
++ Node * narr = new_array(klass_node, zlen, 1);
++ // Update IdealKit memory and control from graphKit.
++ __ sync_kit(this);
++ __ set(z_alloc, narr);
++ } __ end_if();
++
++ sync_kit(ideal);
++ z = __ value(z_alloc);
++ // Can't use TypeAryPtr::INTS which uses Bottom offset.
++ _gvn.set_type(z, TypeOopPtr::make_from_klass(klass));
++ // Final sync IdealKit and GraphKit.
++ final_sync(ideal);
++#undef __
++
++ Node* z_start = array_element_address(z, intcon(0), T_INT);
++
++ Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
++ OptoRuntime::multiplyToLen_Type(),
++ stubAddr, stubName, TypePtr::BOTTOM,
++ x_start, xlen, y_start, ylen, z_start, zlen);
++ } // original reexecute is set back here
++
++ C->set_has_split_ifs(true); // Has chance for split-if optimization
++ set_result(z);
++ return true;
++}
++
++
+ /**
+ * Calculate CRC32 for byte.
+ * int java.util.zip.CRC32.update(int crc, int b)
+@@ -5866,10 +6020,26 @@
+ BasicType bt = field->layout_type();
+
+ // Build the resultant type of the load
+- const Type *type = TypeOopPtr::make_from_klass(field_klass->as_klass());
+-
++ const Type *type;
++ if (bt == T_OBJECT) {
++ type = TypeOopPtr::make_from_klass(field_klass->as_klass());
++ } else {
++ type = Type::get_const_basic_type(bt);
++ }
++
++ if (support_IRIW_for_not_multiple_copy_atomic_cpu && is_vol) {
++ insert_mem_bar(Op_MemBarVolatile); // StoreLoad barrier
++ }
+ // Build the load.
+- Node* loadedField = make_load(NULL, adr, type, bt, adr_type, MemNode::unordered, is_vol);
++ MemNode::MemOrd mo = is_vol ? MemNode::acquire : MemNode::unordered;
++ Node* loadedField = make_load(NULL, adr, type, bt, adr_type, mo, is_vol);
++ // If reference is volatile, prevent following memory ops from
++ // floating up past the volatile read. Also prevents commoning
++ // another volatile read.
++ if (is_vol) {
++ // Memory barrier includes bogus read of value to force load BEFORE membar
++ insert_mem_bar(Op_MemBarAcquire, loadedField);
++ }
+ return loadedField;
+ }
+
+@@ -5996,7 +6166,7 @@
+ assert(tinst != NULL, "CBC obj is null");
+ assert(tinst->klass()->is_loaded(), "CBC obj is not loaded");
+ ciKlass* klass_AESCrypt = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make("com/sun/crypto/provider/AESCrypt"));
+- if (!klass_AESCrypt->is_loaded()) return false;
++ assert(klass_AESCrypt->is_loaded(), "predicate checks that this class is loaded");
+
+ ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass();
+ const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_AESCrypt);
+@@ -6071,11 +6241,8 @@
+ // note cipher==plain is more conservative than the original java code but that's OK
+ //
+ Node* LibraryCallKit::inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting) {
+- // First, check receiver for NULL since it is virtual method.
++ // The receiver was checked for NULL already.
+ Node* objCBC = argument(0);
+- objCBC = null_check(objCBC);
+-
+- if (stopped()) return NULL; // Always NULL
+
+ // Load embeddedCipher field of CipherBlockChaining object.
+ Node* embeddedCipherObj = load_field_from_object(objCBC, "embeddedCipher", "Lcom/sun/crypto/provider/SymmetricCipher;", /*is_exact*/ false);
+@@ -6122,3 +6289,258 @@
+ record_for_igvn(region);
+ return _gvn.transform(region);
+ }
++
++//------------------------------inline_sha_implCompress-----------------------
++//
++// Calculate SHA (i.e., SHA-1) for single-block byte[] array.
++// void com.sun.security.provider.SHA.implCompress(byte[] buf, int ofs)
++//
++// Calculate SHA2 (i.e., SHA-244 or SHA-256) for single-block byte[] array.
++// void com.sun.security.provider.SHA2.implCompress(byte[] buf, int ofs)
++//
++// Calculate SHA5 (i.e., SHA-384 or SHA-512) for single-block byte[] array.
++// void com.sun.security.provider.SHA5.implCompress(byte[] buf, int ofs)
++//
++bool LibraryCallKit::inline_sha_implCompress(vmIntrinsics::ID id) {
++ assert(callee()->signature()->size() == 2, "sha_implCompress has 2 parameters");
++
++ Node* sha_obj = argument(0);
++ Node* src = argument(1); // type oop
++ Node* ofs = argument(2); // type int
++
++ const Type* src_type = src->Value(&_gvn);
++ const TypeAryPtr* top_src = src_type->isa_aryptr();
++ if (top_src == NULL || top_src->klass() == NULL) {
++ // failed array check
++ return false;
++ }
++ // Figure out the size and type of the elements we will be copying.
++ BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
++ if (src_elem != T_BYTE) {
++ return false;
++ }
++ // 'src_start' points to src array + offset
++ Node* src_start = array_element_address(src, ofs, src_elem);
++ Node* state = NULL;
++ address stubAddr;
++ const char *stubName;
++
++ switch(id) {
++ case vmIntrinsics::_sha_implCompress:
++ assert(UseSHA1Intrinsics, "need SHA1 instruction support");
++ state = get_state_from_sha_object(sha_obj);
++ stubAddr = StubRoutines::sha1_implCompress();
++ stubName = "sha1_implCompress";
++ break;
++ case vmIntrinsics::_sha2_implCompress:
++ assert(UseSHA256Intrinsics, "need SHA256 instruction support");
++ state = get_state_from_sha_object(sha_obj);
++ stubAddr = StubRoutines::sha256_implCompress();
++ stubName = "sha256_implCompress";
++ break;
++ case vmIntrinsics::_sha5_implCompress:
++ assert(UseSHA512Intrinsics, "need SHA512 instruction support");
++ state = get_state_from_sha5_object(sha_obj);
++ stubAddr = StubRoutines::sha512_implCompress();
++ stubName = "sha512_implCompress";
++ break;
++ default:
++ fatal_unexpected_iid(id);
++ return false;
++ }
++ if (state == NULL) return false;
++
++ // Call the stub.
++ Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::sha_implCompress_Type(),
++ stubAddr, stubName, TypePtr::BOTTOM,
++ src_start, state);
++
++ return true;
++}
++
++//------------------------------inline_digestBase_implCompressMB-----------------------
++//
++// Calculate SHA/SHA2/SHA5 for multi-block byte[] array.
++// int com.sun.security.provider.DigestBase.implCompressMultiBlock(byte[] b, int ofs, int limit)
++//
++bool LibraryCallKit::inline_digestBase_implCompressMB(int predicate) {
++ assert(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics,
++ "need SHA1/SHA256/SHA512 instruction support");
++ assert((uint)predicate < 3, "sanity");
++ assert(callee()->signature()->size() == 3, "digestBase_implCompressMB has 3 parameters");
++
++ Node* digestBase_obj = argument(0); // The receiver was checked for NULL already.
++ Node* src = argument(1); // byte[] array
++ Node* ofs = argument(2); // type int
++ Node* limit = argument(3); // type int
++
++ const Type* src_type = src->Value(&_gvn);
++ const TypeAryPtr* top_src = src_type->isa_aryptr();
++ if (top_src == NULL || top_src->klass() == NULL) {
++ // failed array check
++ return false;
++ }
++ // Figure out the size and type of the elements we will be copying.
++ BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
++ if (src_elem != T_BYTE) {
++ return false;
++ }
++ // 'src_start' points to src array + offset
++ Node* src_start = array_element_address(src, ofs, src_elem);
++
++ const char* klass_SHA_name = NULL;
++ const char* stub_name = NULL;
++ address stub_addr = NULL;
++ bool long_state = false;
++
++ switch (predicate) {
++ case 0:
++ if (UseSHA1Intrinsics) {
++ klass_SHA_name = "sun/security/provider/SHA";
++ stub_name = "sha1_implCompressMB";
++ stub_addr = StubRoutines::sha1_implCompressMB();
++ }
++ break;
++ case 1:
++ if (UseSHA256Intrinsics) {
++ klass_SHA_name = "sun/security/provider/SHA2";
++ stub_name = "sha256_implCompressMB";
++ stub_addr = StubRoutines::sha256_implCompressMB();
++ }
++ break;
++ case 2:
++ if (UseSHA512Intrinsics) {
++ klass_SHA_name = "sun/security/provider/SHA5";
++ stub_name = "sha512_implCompressMB";
++ stub_addr = StubRoutines::sha512_implCompressMB();
++ long_state = true;
++ }
++ break;
++ default:
++ fatal(err_msg_res("unknown SHA intrinsic predicate: %d", predicate));
++ }
++ if (klass_SHA_name != NULL) {
++ // get DigestBase klass to lookup for SHA klass
++ const TypeInstPtr* tinst = _gvn.type(digestBase_obj)->isa_instptr();
++ assert(tinst != NULL, "digestBase_obj is not instance???");
++ assert(tinst->klass()->is_loaded(), "DigestBase is not loaded");
++
++ ciKlass* klass_SHA = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_SHA_name));
++ assert(klass_SHA->is_loaded(), "predicate checks that this class is loaded");
++ ciInstanceKlass* instklass_SHA = klass_SHA->as_instance_klass();
++ return inline_sha_implCompressMB(digestBase_obj, instklass_SHA, long_state, stub_addr, stub_name, src_start, ofs, limit);
++ }
++ return false;
++}
++//------------------------------inline_sha_implCompressMB-----------------------
++bool LibraryCallKit::inline_sha_implCompressMB(Node* digestBase_obj, ciInstanceKlass* instklass_SHA,
++ bool long_state, address stubAddr, const char *stubName,
++ Node* src_start, Node* ofs, Node* limit) {
++ const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_SHA);
++ const TypeOopPtr* xtype = aklass->as_instance_type();
++ Node* sha_obj = new (C) CheckCastPPNode(control(), digestBase_obj, xtype);
++ sha_obj = _gvn.transform(sha_obj);
++
++ Node* state;
++ if (long_state) {
++ state = get_state_from_sha5_object(sha_obj);
++ } else {
++ state = get_state_from_sha_object(sha_obj);
++ }
++ if (state == NULL) return false;
++
++ // Call the stub.
++ Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
++ OptoRuntime::digestBase_implCompressMB_Type(),
++ stubAddr, stubName, TypePtr::BOTTOM,
++ src_start, state, ofs, limit);
++ // return ofs (int)
++ Node* result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms));
++ set_result(result);
++
++ return true;
++}
++
++//------------------------------get_state_from_sha_object-----------------------
++Node * LibraryCallKit::get_state_from_sha_object(Node *sha_object) {
++ Node* sha_state = load_field_from_object(sha_object, "state", "[I", /*is_exact*/ false);
++ assert (sha_state != NULL, "wrong version of sun.security.provider.SHA/SHA2");
++ if (sha_state == NULL) return (Node *) NULL;
++
++ // now have the array, need to get the start address of the state array
++ Node* state = array_element_address(sha_state, intcon(0), T_INT);
++ return state;
++}
++
++//------------------------------get_state_from_sha5_object-----------------------
++Node * LibraryCallKit::get_state_from_sha5_object(Node *sha_object) {
++ Node* sha_state = load_field_from_object(sha_object, "state", "[J", /*is_exact*/ false);
++ assert (sha_state != NULL, "wrong version of sun.security.provider.SHA5");
++ if (sha_state == NULL) return (Node *) NULL;
++
++ // now have the array, need to get the start address of the state array
++ Node* state = array_element_address(sha_state, intcon(0), T_LONG);
++ return state;
++}
++
++//----------------------------inline_digestBase_implCompressMB_predicate----------------------------
++// Return node representing slow path of predicate check.
++// the pseudo code we want to emulate with this predicate is:
++// if (digestBaseObj instanceof SHA/SHA2/SHA5) do_intrinsic, else do_javapath
++//
++Node* LibraryCallKit::inline_digestBase_implCompressMB_predicate(int predicate) {
++ assert(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics,
++ "need SHA1/SHA256/SHA512 instruction support");
++ assert((uint)predicate < 3, "sanity");
++
++ // The receiver was checked for NULL already.
++ Node* digestBaseObj = argument(0);
++
++ // get DigestBase klass for instanceOf check
++ const TypeInstPtr* tinst = _gvn.type(digestBaseObj)->isa_instptr();
++ assert(tinst != NULL, "digestBaseObj is null");
++ assert(tinst->klass()->is_loaded(), "DigestBase is not loaded");
++
++ const char* klass_SHA_name = NULL;
++ switch (predicate) {
++ case 0:
++ if (UseSHA1Intrinsics) {
++ // we want to do an instanceof comparison against the SHA class
++ klass_SHA_name = "sun/security/provider/SHA";
++ }
++ break;
++ case 1:
++ if (UseSHA256Intrinsics) {
++ // we want to do an instanceof comparison against the SHA2 class
++ klass_SHA_name = "sun/security/provider/SHA2";
++ }
++ break;
++ case 2:
++ if (UseSHA512Intrinsics) {
++ // we want to do an instanceof comparison against the SHA5 class
++ klass_SHA_name = "sun/security/provider/SHA5";
++ }
++ break;
++ default:
++ fatal(err_msg_res("unknown SHA intrinsic predicate: %d", predicate));
++ }
++
++ ciKlass* klass_SHA = NULL;
++ if (klass_SHA_name != NULL) {
++ klass_SHA = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_SHA_name));
++ }
++ if ((klass_SHA == NULL) || !klass_SHA->is_loaded()) {
++ // if none of SHA/SHA2/SHA5 is loaded, we never take the intrinsic fast path
++ Node* ctrl = control();
++ set_control(top()); // no intrinsic path
++ return ctrl;
++ }
++ ciInstanceKlass* instklass_SHA = klass_SHA->as_instance_klass();
++
++ Node* instofSHA = gen_instanceof(digestBaseObj, makecon(TypeKlassPtr::make(instklass_SHA)));
++ Node* cmp_instof = _gvn.transform(new (C) CmpINode(instofSHA, intcon(1)));
++ Node* bool_instof = _gvn.transform(new (C) BoolNode(cmp_instof, BoolTest::ne));
++ Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN);
++
++ return instof_false; // even if it is NULL
++}
+--- ./hotspot/src/share/vm/opto/loopTransform.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/loopTransform.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -269,10 +269,9 @@
+ bool IdealLoopTree::policy_peeling( PhaseIdealLoop *phase ) const {
+ Node *test = ((IdealLoopTree*)this)->tail();
+ int body_size = ((IdealLoopTree*)this)->_body.size();
+- int live_node_count = phase->C->live_nodes();
+ // Peeling does loop cloning which can result in O(N^2) node construction
+ if( body_size > 255 /* Prevent overflow for large body_size */
+- || (body_size * body_size + live_node_count > MaxNodeLimit) ) {
++ || (body_size * body_size + phase->C->live_nodes()) > phase->C->max_node_limit() ) {
+ return false; // too large to safely clone
+ }
+ while( test != _head ) { // Scan till run off top of loop
+@@ -601,7 +600,7 @@
+ return false;
+ if (new_body_size > unroll_limit ||
+ // Unrolling can result in a large amount of node construction
+- new_body_size >= MaxNodeLimit - (uint) phase->C->live_nodes()) {
++ new_body_size >= phase->C->max_node_limit() - phase->C->live_nodes()) {
+ return false;
+ }
+
+@@ -882,6 +881,20 @@
+ return n;
+ }
+
++bool PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop) {
++ Node* castii = new (C) CastIINode(incr, TypeInt::INT, true);
++ castii->set_req(0, ctrl);
++ register_new_node(castii, ctrl);
++ for (DUIterator_Fast imax, i = incr->fast_outs(imax); i < imax; i++) {
++ Node* n = incr->fast_out(i);
++ if (n->is_Phi() && n->in(0) == loop) {
++ int nrep = n->replace_edge(incr, castii);
++ return true;
++ }
++ }
++ return false;
++}
++
+ //------------------------------insert_pre_post_loops--------------------------
+ // Insert pre and post loops. If peel_only is set, the pre-loop can not have
+ // more iterations added. It acts as a 'peel' only, no lower-bound RCE, no
+@@ -1080,6 +1093,24 @@
+ }
+ }
+
++ // Nodes inside the loop may be control dependent on a predicate
++ // that was moved before the preloop. If the back branch of the main
++ // or post loops becomes dead, those nodes won't be dependent on the
++ // test that guards that loop nest anymore which could lead to an
++ // incorrect array access because it executes independently of the
++ // test that was guarding the loop nest. We add a special CastII on
++ // the if branch that enters the loop, between the input induction
++ // variable value and the induction variable Phi to preserve correct
++ // dependencies.
++
++ // CastII for the post loop:
++ bool inserted = cast_incr_before_loop(zer_opaq->in(1), zer_taken, post_head);
++ assert(inserted, "no castII inserted");
++
++ // CastII for the main loop:
++ inserted = cast_incr_before_loop(pre_incr, min_taken, main_head);
++ assert(inserted, "no castII inserted");
++
+ // Step B4: Shorten the pre-loop to run only 1 iteration (for now).
+ // RCE and alignment may change this later.
+ Node *cmp_end = pre_end->cmp_node();
+@@ -2287,8 +2318,8 @@
+
+ // Skip next optimizations if running low on nodes. Note that
+ // policy_unswitching and policy_maximally_unroll have this check.
+- uint nodes_left = MaxNodeLimit - (uint) phase->C->live_nodes();
+- if ((2 * _body.size()) > nodes_left) {
++ int nodes_left = phase->C->max_node_limit() - phase->C->live_nodes();
++ if ((int)(2 * _body.size()) > nodes_left) {
+ return true;
+ }
+
+--- ./hotspot/src/share/vm/opto/loopUnswitch.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/loopUnswitch.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -59,8 +59,8 @@
+ if (!_head->is_Loop()) {
+ return false;
+ }
+- uint nodes_left = MaxNodeLimit - phase->C->live_nodes();
+- if (2 * _body.size() > nodes_left) {
++ int nodes_left = phase->C->max_node_limit() - phase->C->live_nodes();
++ if ((int)(2 * _body.size()) > nodes_left) {
+ return false; // Too speculative if running low on nodes.
+ }
+ LoopNode* head = _head->as_Loop();
+--- ./hotspot/src/share/vm/opto/loopnode.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/loopnode.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -602,6 +602,8 @@
+ return ctrl;
+ }
+
++ bool cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop);
++
+ public:
+ bool has_node( Node* n ) const {
+ guarantee(n != NULL, "No Node.");
+--- ./hotspot/src/share/vm/opto/loopopts.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/loopopts.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -239,8 +239,13 @@
+ ProjNode* dp_proj = dp->as_Proj();
+ ProjNode* unc_proj = iff->as_If()->proj_out(1 - dp_proj->_con)->as_Proj();
+ if (exclude_loop_predicate &&
+- unc_proj->is_uncommon_trap_proj(Deoptimization::Reason_predicate))
++ (unc_proj->is_uncommon_trap_proj(Deoptimization::Reason_predicate) ||
++ unc_proj->is_uncommon_trap_proj(Deoptimization::Reason_range_check))) {
++ // If this is a range check (IfNode::is_range_check), do not
++ // reorder because Compile::allow_range_check_smearing might have
++ // changed the check.
+ return; // Let IGVN transformation change control dependence.
++ }
+
+ IdealLoopTree *old_loop = get_loop(dp);
+
+@@ -734,7 +739,7 @@
+ for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
+ weight += region->fast_out(i)->outcnt();
+ }
+- int nodes_left = MaxNodeLimit - C->live_nodes();
++ int nodes_left = C->max_node_limit() - C->live_nodes();
+ if (weight * 8 > nodes_left) {
+ #ifndef PRODUCT
+ if (PrintOpto)
+@@ -896,23 +901,23 @@
+ int n_op = n->Opcode();
+
+ // Check for an IF being dominated by another IF same test
+- if( n_op == Op_If ) {
++ if (n_op == Op_If) {
+ Node *bol = n->in(1);
+ uint max = bol->outcnt();
+ // Check for same test used more than once?
+- if( n_op == Op_If && max > 1 && bol->is_Bool() ) {
++ if (max > 1 && bol->is_Bool()) {
+ // Search up IDOMs to see if this IF is dominated.
+ Node *cutoff = get_ctrl(bol);
+
+ // Now search up IDOMs till cutoff, looking for a dominating test
+ Node *prevdom = n;
+ Node *dom = idom(prevdom);
+- while( dom != cutoff ) {
+- if( dom->req() > 1 && dom->in(1) == bol && prevdom->in(0) == dom ) {
++ while (dom != cutoff) {
++ if (dom->req() > 1 && dom->in(1) == bol && prevdom->in(0) == dom) {
+ // Replace the dominated test with an obvious true or false.
+ // Place it on the IGVN worklist for later cleanup.
+ C->set_major_progress();
+- dominated_by( prevdom, n, false, true );
++ dominated_by(prevdom, n, false, true);
+ #ifndef PRODUCT
+ if( VerifyLoopOptimizations ) verify();
+ #endif
+--- ./hotspot/src/share/vm/opto/machnode.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/machnode.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -639,7 +639,6 @@
+ }
+ #endif
+
+-
+ bool MachCallNode::return_value_is_used() const {
+ if (tf()->range()->cnt() == TypeFunc::Parms) {
+ // void return
+@@ -657,6 +656,14 @@
+ return false;
+ }
+
++// Similar to cousin class CallNode::returns_pointer
++// Because this is used in deoptimization, we want the type info, not the data
++// flow info; the interpreter will "use" things that are dead to the optimizer.
++bool MachCallNode::returns_pointer() const {
++ const TypeTuple *r = tf()->range();
++ return (r->cnt() > TypeFunc::Parms &&
++ r->field_at(TypeFunc::Parms)->isa_ptr());
++}
+
+ //------------------------------Registers--------------------------------------
+ const RegMask &MachCallNode::in_RegMask(uint idx) const {
+--- ./hotspot/src/share/vm/opto/machnode.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/machnode.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -784,6 +784,10 @@
+
+ bool returns_long() const { return tf()->return_type() == T_LONG; }
+ bool return_value_is_used() const;
++
++ // Similar to cousin class CallNode::returns_pointer
++ bool returns_pointer() const;
++
+ #ifndef PRODUCT
+ virtual void dump_spec(outputStream *st) const;
+ #endif
+--- ./hotspot/src/share/vm/opto/macro.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/macro.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -699,6 +699,7 @@
+ ciType* elem_type;
+
+ Node* res = alloc->result_cast();
++ assert(res == NULL || res->is_CheckCastPP(), "unexpected AllocateNode result");
+ const TypeOopPtr* res_type = NULL;
+ if (res != NULL) { // Could be NULL when there are no users
+ res_type = _igvn.type(res)->isa_oopptr();
+@@ -963,7 +964,11 @@
+ }
+
+ bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) {
+- if (!EliminateAllocations || !alloc->_is_non_escaping) {
++ // Don't do scalar replacement if the frame can be popped by JVMTI:
++ // if reallocation fails during deoptimization we'll pop all
++ // interpreter frames for this compiled frame and that won't play
++ // nice with JVMTI popframe.
++ if (!EliminateAllocations || JvmtiExport::can_pop_frame() || !alloc->_is_non_escaping) {
+ return false;
+ }
+ Node* klass = alloc->in(AllocateNode::KlassNode);
+@@ -1031,6 +1036,8 @@
+ return false;
+ }
+
++ assert(boxing->result_cast() == NULL, "unexpected boxing node result");
++
+ extract_call_projections(boxing);
+
+ const TypeTuple* r = boxing->tf()->range();
+@@ -2191,7 +2198,7 @@
+ Node* klass_node = AllocateNode::Ideal_klass(obj, &_igvn);
+ if (klass_node == NULL) {
+ Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
+- klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) );
++ klass_node = transform_later(LoadKlassNode::make(_igvn, NULL, mem, k_adr, _igvn.type(k_adr)->is_ptr()));
+ #ifdef _LP64
+ if (UseCompressedClassPointers && klass_node->is_DecodeNKlass()) {
+ assert(klass_node->in(1)->Opcode() == Op_LoadNKlass, "sanity");
+--- ./hotspot/src/share/vm/opto/memnode.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/memnode.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -859,6 +859,10 @@
+
+
+ //=============================================================================
++// Should LoadNode::Ideal() attempt to remove control edges?
++bool LoadNode::can_remove_control() const {
++ return true;
++}
+ uint LoadNode::size_of() const { return sizeof(*this); }
+ uint LoadNode::cmp( const Node &n ) const
+ { return !Type::cmp( _type, ((LoadNode&)n)._type ); }
+@@ -1251,6 +1255,16 @@
+ result = new (phase->C) ConvI2LNode(phase->transform(result));
+ }
+ #endif
++ // Boxing/unboxing can be done from signed & unsigned loads (e.g. LoadUB -> ... -> LoadB pair).
++ // Need to preserve unboxing load type if it is unsigned.
++ switch(this->Opcode()) {
++ case Op_LoadUB:
++ result = new (phase->C) AndINode(phase->transform(result), phase->intcon(0xFF));
++ break;
++ case Op_LoadUS:
++ result = new (phase->C) AndINode(phase->transform(result), phase->intcon(0xFFFF));
++ break;
++ }
+ return result;
+ }
+ }
+@@ -1455,7 +1469,7 @@
+ }
+
+ //------------------------------Ideal------------------------------------------
+-// If the load is from Field memory and the pointer is non-null, we can
++// If the load is from Field memory and the pointer is non-null, it might be possible to
+ // zero out the control input.
+ // If the offset is constant and the base is an object allocation,
+ // try to hook me up to the exact initializing store.
+@@ -1480,6 +1494,7 @@
+ && phase->C->get_alias_index(phase->type(address)->is_ptr()) != Compile::AliasIdxRaw) {
+ // Check for useless control edge in some common special cases
+ if (in(MemNode::Control) != NULL
++ && can_remove_control()
+ && phase->type(base)->higher_equal(TypePtr::NOTNULL)
+ && all_controls_dominate(base, phase->C->start())) {
+ // A method-invariant, non-null address (constant or 'this' argument).
+@@ -2007,9 +2022,8 @@
+ //=============================================================================
+ //----------------------------LoadKlassNode::make------------------------------
+ // Polymorphic factory method:
+-Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at, const TypeKlassPtr *tk ) {
++Node* LoadKlassNode::make(PhaseGVN& gvn, Node* ctl, Node *mem, Node *adr, const TypePtr* at, const TypeKlassPtr *tk) {
+ Compile* C = gvn.C;
+- Node *ctl = NULL;
+ // sanity check the alias category against the created node type
+ const TypePtr *adr_type = adr->bottom_type()->isa_ptr();
+ assert(adr_type != NULL, "expecting TypeKlassPtr");
+@@ -2029,6 +2043,12 @@
+ return klass_value_common(phase);
+ }
+
++// In most cases, LoadKlassNode does not have the control input set. If the control
++// input is set, it must not be removed (by LoadNode::Ideal()).
++bool LoadKlassNode::can_remove_control() const {
++ return false;
++}
++
+ const Type *LoadNode::klass_value_common( PhaseTransform *phase ) const {
+ // Either input is TOP ==> the result is TOP
+ const Type *t1 = phase->type( in(MemNode::Memory) );
+--- ./hotspot/src/share/vm/opto/memnode.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/memnode.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -148,6 +148,8 @@
+ protected:
+ virtual uint cmp(const Node &n) const;
+ virtual uint size_of() const; // Size is bigger
++ // Should LoadNode::Ideal() attempt to remove control edges?
++ virtual bool can_remove_control() const;
+ const Type* const _type; // What kind of value is loaded?
+ public:
+
+@@ -171,8 +173,10 @@
+ // we are equivalent to. We look for Load of a Store.
+ virtual Node *Identity( PhaseTransform *phase );
+
+- // If the load is from Field memory and the pointer is non-null, we can
++ // If the load is from Field memory and the pointer is non-null, it might be possible to
+ // zero out the control input.
++ // If the offset is constant and the base is an object allocation,
++ // try to hook me up to the exact initializing store.
+ virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
+
+ // Split instance field load through Phi.
+@@ -413,6 +417,10 @@
+ //------------------------------LoadKlassNode----------------------------------
+ // Load a Klass from an object
+ class LoadKlassNode : public LoadPNode {
++protected:
++ // In most cases, LoadKlassNode does not have the control input set. If the control
++ // input is set, it must not be removed (by LoadNode::Ideal()).
++ virtual bool can_remove_control() const;
+ public:
+ LoadKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk, MemOrd mo)
+ : LoadPNode(c, mem, adr, at, tk, mo) {}
+@@ -422,8 +430,8 @@
+ virtual bool depends_only_on_test() const { return true; }
+
+ // Polymorphic factory method:
+- static Node* make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at,
+- const TypeKlassPtr *tk = TypeKlassPtr::OBJECT );
++ static Node* make(PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* at,
++ const TypeKlassPtr* tk = TypeKlassPtr::OBJECT);
+ };
+
+ //------------------------------LoadNKlassNode---------------------------------
+--- ./hotspot/src/share/vm/opto/multnode.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/multnode.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -194,7 +194,9 @@
+ }
+ }
+
+- ProjNode* other_proj = iff->proj_out(1-_con)->as_Proj();
++ ProjNode* other_proj = iff->proj_out(1-_con);
++ if (other_proj == NULL) // Should never happen, but make Parfait happy.
++ return false;
+ if (other_proj->is_uncommon_trap_proj(reason)) {
+ assert(reason == Deoptimization::Reason_none ||
+ Compile::current()->is_predicate_opaq(iff->in(1)->in(1)), "should be on the list");
+--- ./hotspot/src/share/vm/opto/node.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/node.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -69,7 +69,7 @@
+ Compile::set_debug_idx(new_debug_idx);
+ set_debug_idx( new_debug_idx );
+ assert(Compile::current()->unique() < (INT_MAX - 1), "Node limit exceeded INT_MAX");
+- assert(Compile::current()->live_nodes() < (uint)MaxNodeLimit, "Live Node limit exceeded limit");
++ assert(Compile::current()->live_nodes() < Compile::current()->max_node_limit(), "Live Node limit exceeded limit");
+ if (BreakAtNode != 0 && (_debug_idx == BreakAtNode || (int)_idx == BreakAtNode)) {
+ tty->print_cr("BreakAtNode: _idx=%d _debug_idx=%d", _idx, _debug_idx);
+ BREAKPOINT;
+@@ -326,7 +326,7 @@
+ Node::Node(uint req)
+ : _idx(IDX_INIT(req))
+ {
+- assert( req < (uint)(MaxNodeLimit - NodeLimitFudgeFactor), "Input limit exceeded" );
++ assert( req < Compile::current()->max_node_limit() - NodeLimitFudgeFactor, "Input limit exceeded" );
+ debug_only( verify_construction() );
+ NOT_PRODUCT(nodes_created++);
+ if (req == 0) {
+@@ -527,6 +527,9 @@
+ if (n->is_Call()) {
+ n->as_Call()->clone_jvms(C);
+ }
++ if (n->is_SafePoint()) {
++ n->as_SafePoint()->clone_replaced_nodes();
++ }
+ return n; // Return the clone
+ }
+
+@@ -622,6 +625,9 @@
+ if (is_expensive()) {
+ compile->remove_expensive_node(this);
+ }
++ if (is_SafePoint()) {
++ as_SafePoint()->delete_replaced_nodes();
++ }
+ #ifdef ASSERT
+ // We will not actually delete the storage, but we'll make the node unusable.
+ *(address*)this = badAddress; // smash the C++ vtbl, probably
+@@ -1087,6 +1093,9 @@
+ if( this->is_Store() ) {
+ // Condition for back-to-back stores folding.
+ return n->Opcode() == op && n->in(MemNode::Memory) == this;
++ } else if (this->is_Load()) {
++ // Condition for removing an unused LoadNode from the MemBarAcquire precedence input
++ return n->Opcode() == Op_MemBarAcquire;
+ } else if( op == Op_AddL ) {
+ // Condition for convL2I(addL(x,y)) ==> addI(convL2I(x),convL2I(y))
+ return n->Opcode() == Op_ConvL2I && n->in(1) == this;
+--- ./hotspot/src/share/vm/opto/output.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/output.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -783,9 +783,10 @@
+ // grow downwards in all implementations.
+ // (If, on some machine, the interpreter's Java locals or stack
+ // were to grow upwards, the embedded doubles would be word-swapped.)
+- jint *dp = (jint*)&d;
+- array->append(new ConstantIntValue(dp[1]));
+- array->append(new ConstantIntValue(dp[0]));
++ jlong_accessor acc;
++ acc.long_value = jlong_cast(d);
++ array->append(new ConstantIntValue(acc.words[1]));
++ array->append(new ConstantIntValue(acc.words[0]));
+ #endif
+ break;
+ }
+@@ -802,9 +803,10 @@
+ // grow downwards in all implementations.
+ // (If, on some machine, the interpreter's Java locals or stack
+ // were to grow upwards, the embedded doubles would be word-swapped.)
+- jint *dp = (jint*)&d;
+- array->append(new ConstantIntValue(dp[1]));
+- array->append(new ConstantIntValue(dp[0]));
++ jlong_accessor acc;
++ acc.long_value = d;
++ array->append(new ConstantIntValue(acc.words[1]));
++ array->append(new ConstantIntValue(acc.words[0]));
+ #endif
+ break;
+ }
+@@ -854,8 +856,7 @@
+ }
+
+ // Check if a call returns an object.
+- if (mcall->return_value_is_used() &&
+- mcall->tf()->range()->field_at(TypeFunc::Parms)->isa_ptr()) {
++ if (mcall->returns_pointer()) {
+ return_oop = true;
+ }
+ safepoint_pc_offset += mcall->ret_addr_offset();
+--- ./hotspot/src/share/vm/opto/parse.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/parse.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -142,7 +142,7 @@
+
+ void print_value_on(outputStream* st) const PRODUCT_RETURN;
+
+- bool _forced_inline; // Inlining was forced by CompilerOracle or ciReplay
++ bool _forced_inline; // Inlining was forced by CompilerOracle, ciReplay or annotation
+ bool forced_inline() const { return _forced_inline; }
+ // Count number of nodes in this subtree
+ int count() const;
+@@ -357,12 +357,13 @@
+ int _est_switch_depth; // Debugging SwitchRanges.
+ #endif
+
+- // parser for the caller of the method of this object
+- Parse* const _parent;
++ bool _first_return; // true if return is the first to be parsed
++ bool _replaced_nodes_for_exceptions; // needs processing of replaced nodes in exception paths?
++ uint _new_idx; // any node with _idx above were new during this parsing. Used to trim the replaced nodes list.
+
+ public:
+ // Constructor
+- Parse(JVMState* caller, ciMethod* parse_method, float expected_uses, Parse* parent);
++ Parse(JVMState* caller, ciMethod* parse_method, float expected_uses);
+
+ virtual Parse* is_Parse() const { return (Parse*)this; }
+
+@@ -419,8 +420,6 @@
+ return block()->successor_for_bci(bci);
+ }
+
+- Parse* parent_parser() const { return _parent; }
+-
+ private:
+ // Create a JVMS & map for the initial state of this method.
+ SafePointNode* create_entry_map();
+@@ -552,8 +551,9 @@
+
+ float dynamic_branch_prediction(float &cnt);
+ float branch_prediction(float &cnt, BoolTest::mask btest, int target_bci);
+- bool seems_never_taken(float prob);
+- bool seems_stable_comparison(BoolTest::mask btest, Node* c);
++ bool seems_never_taken(float prob) const;
++ bool path_is_suitable_for_uncommon_trap(float prob) const;
++ bool seems_stable_comparison() const;
+
+ void do_ifnull(BoolTest::mask btest, Node* c);
+ void do_if(BoolTest::mask btest, Node* c);
+--- ./hotspot/src/share/vm/opto/parse1.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/parse1.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -381,8 +381,8 @@
+
+ //------------------------------Parse------------------------------------------
+ // Main parser constructor.
+-Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses, Parse* parent)
+- : _exits(caller), _parent(parent)
++Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses)
++ : _exits(caller)
+ {
+ // Init some variables
+ _caller = caller;
+@@ -395,6 +395,9 @@
+ _entry_bci = InvocationEntryBci;
+ _tf = NULL;
+ _block = NULL;
++ _first_return = true;
++ _replaced_nodes_for_exceptions = false;
++ _new_idx = C->unique();
+ debug_only(_block_count = -1);
+ debug_only(_blocks = (Block*)-1);
+ #ifndef PRODUCT
+@@ -565,12 +568,13 @@
+ set_map(entry_map);
+ do_method_entry();
+ }
+- if (depth() == 1) {
++
++ if (depth() == 1 && !failing()) {
+ // Add check to deoptimize the nmethod if RTM state was changed
+ rtm_deopt();
+ }
+
+- // Check for bailouts during method entry.
++ // Check for bailouts during method entry or RTM state check setup.
+ if (failing()) {
+ if (log) log->done("parse");
+ C->set_default_node_notes(caller_nn);
+@@ -894,6 +898,10 @@
+ for (uint i = 0; i < TypeFunc::Parms; i++) {
+ caller.map()->set_req(i, ex_map->in(i));
+ }
++ if (ex_map->has_replaced_nodes()) {
++ _replaced_nodes_for_exceptions = true;
++ }
++ caller.map()->transfer_replaced_nodes_from(ex_map, _new_idx);
+ // ...and the exception:
+ Node* ex_oop = saved_ex_oop(ex_map);
+ SafePointNode* caller_ex_map = caller.make_exception_state(ex_oop);
+@@ -962,7 +970,7 @@
+ bool do_synch = method()->is_synchronized() && GenerateSynchronizationCode;
+
+ // record exit from a method if compiled while Dtrace is turned on.
+- if (do_synch || C->env()->dtrace_method_probes()) {
++ if (do_synch || C->env()->dtrace_method_probes() || _replaced_nodes_for_exceptions) {
+ // First move the exception list out of _exits:
+ GraphKit kit(_exits.transfer_exceptions_into_jvms());
+ SafePointNode* normal_map = kit.map(); // keep this guy safe
+@@ -987,6 +995,9 @@
+ if (C->env()->dtrace_method_probes()) {
+ kit.make_dtrace_method_exit(method());
+ }
++ if (_replaced_nodes_for_exceptions) {
++ kit.map()->apply_replaced_nodes();
++ }
+ // Done with exception-path processing.
+ ex_map = kit.make_exception_state(ex_oop);
+ assert(ex_jvms->same_calls_as(ex_map->jvms()), "sanity");
+@@ -1006,6 +1017,7 @@
+ _exits.add_exception_state(ex_map);
+ }
+ }
++ _exits.map()->apply_replaced_nodes();
+ }
+
+ //-----------------------------create_entry_map-------------------------------
+@@ -1020,6 +1032,9 @@
+ return NULL;
+ }
+
++ // clear current replaced nodes that are of no use from here on (map was cloned in build_exits).
++ _caller->map()->delete_replaced_nodes();
++
+ // If this is an inlined method, we may have to do a receiver null check.
+ if (_caller->has_method() && is_normal_parse() && !method()->is_static()) {
+ GraphKit kit(_caller);
+@@ -1043,6 +1058,8 @@
+
+ SafePointNode* inmap = _caller->map();
+ assert(inmap != NULL, "must have inmap");
++ // In case of null check on receiver above
++ map()->transfer_replaced_nodes_from(inmap, _new_idx);
+
+ uint i;
+
+@@ -1672,6 +1689,8 @@
+ set_control(r->nonnull_req());
+ }
+
++ map()->merge_replaced_nodes_with(newin);
++
+ // newin has been subsumed into the lazy merge, and is now dead.
+ set_block(save_block);
+
+@@ -1939,7 +1958,7 @@
+ // finalization. In general this will fold up since the concrete
+ // class is often visible so the access flags are constant.
+ Node* klass_addr = basic_plus_adr( receiver, receiver, oopDesc::klass_offset_in_bytes() );
+- Node* klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), klass_addr, TypeInstPtr::KLASS) );
++ Node* klass = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), klass_addr, TypeInstPtr::KLASS));
+
+ Node* access_flags_addr = basic_plus_adr(klass, klass, in_bytes(Klass::access_flags_offset()));
+ Node* access_flags = make_load(NULL, access_flags_addr, TypeInt::INT, T_INT, MemNode::unordered);
+@@ -2076,6 +2095,13 @@
+ phi->add_req(value);
+ }
+
++ if (_first_return) {
++ _exits.map()->transfer_replaced_nodes_from(map(), _new_idx);
++ _first_return = false;
++ } else {
++ _exits.map()->merge_replaced_nodes_with(map());
++ }
++
+ stop_and_kill_map(); // This CFG path dies here
+ }
+
+--- ./hotspot/src/share/vm/opto/parse2.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/parse2.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -884,7 +884,7 @@
+ // some branches (e.g., _213_javac.Assembler.eliminate) validly produce
+ // very small but nonzero probabilities, which if confused with zero
+ // counts would keep the program recompiling indefinitely.
+-bool Parse::seems_never_taken(float prob) {
++bool Parse::seems_never_taken(float prob) const {
+ return prob < PROB_MIN;
+ }
+
+@@ -895,53 +895,12 @@
+ // if a path is never taken, its controlling comparison is
+ // already acting in a stable fashion. If the comparison
+ // seems stable, we will put an expensive uncommon trap
+-// on the untaken path. To be conservative, and to allow
+-// partially executed counted loops to be compiled fully,
+-// we will plant uncommon traps only after pointer comparisons.
+-bool Parse::seems_stable_comparison(BoolTest::mask btest, Node* cmp) {
+- for (int depth = 4; depth > 0; depth--) {
+- // The following switch can find CmpP here over half the time for
+- // dynamic language code rich with type tests.
+- // Code using counted loops or array manipulations (typical
+- // of benchmarks) will have many (>80%) CmpI instructions.
+- switch (cmp->Opcode()) {
+- case Op_CmpP:
+- // A never-taken null check looks like CmpP/BoolTest::eq.
+- // These certainly should be closed off as uncommon traps.
+- if (btest == BoolTest::eq)
+- return true;
+- // A never-failed type check looks like CmpP/BoolTest::ne.
+- // Let's put traps on those, too, so that we don't have to compile
+- // unused paths with indeterminate dynamic type information.
+- if (ProfileDynamicTypes)
+- return true;
+- return false;
+-
+- case Op_CmpI:
+- // A small minority (< 10%) of CmpP are masked as CmpI,
+- // as if by boolean conversion ((p == q? 1: 0) != 0).
+- // Detect that here, even if it hasn't optimized away yet.
+- // Specifically, this covers the 'instanceof' operator.
+- if (btest == BoolTest::ne || btest == BoolTest::eq) {
+- if (_gvn.type(cmp->in(2))->singleton() &&
+- cmp->in(1)->is_Phi()) {
+- PhiNode* phi = cmp->in(1)->as_Phi();
+- int true_path = phi->is_diamond_phi();
+- if (true_path > 0 &&
+- _gvn.type(phi->in(1))->singleton() &&
+- _gvn.type(phi->in(2))->singleton()) {
+- // phi->region->if_proj->ifnode->bool->cmp
+- BoolNode* bol = phi->in(0)->in(1)->in(0)->in(1)->as_Bool();
+- btest = bol->_test._test;
+- cmp = bol->in(1);
+- continue;
+- }
+- }
+- }
+- return false;
+- }
++// on the untaken path.
++bool Parse::seems_stable_comparison() const {
++ if (C->too_many_traps(method(), bci(), Deoptimization::Reason_unstable_if)) {
++ return false;
+ }
+- return false;
++ return true;
+ }
+
+ //-------------------------------repush_if_args--------------------------------
+@@ -1166,6 +1125,14 @@
+ }
+ }
+
++bool Parse::path_is_suitable_for_uncommon_trap(float prob) const {
++ // Don't want to speculate on uncommon traps when running with -Xcomp
++ if (!UseInterpreter) {
++ return false;
++ }
++ return (seems_never_taken(prob) && seems_stable_comparison());
++}
++
+ //----------------------------adjust_map_after_if------------------------------
+ // Adjust the JVM state to reflect the result of taking this path.
+ // Basically, it means inspecting the CmpNode controlling this
+@@ -1179,33 +1146,9 @@
+
+ bool is_fallthrough = (path == successor_for_bci(iter().next_bci()));
+
+- if (seems_never_taken(prob) && seems_stable_comparison(btest, c)) {
+- // If this might possibly turn into an implicit null check,
+- // and the null has never yet been seen, we need to generate
+- // an uncommon trap, so as to recompile instead of suffering
+- // with very slow branches. (We'll get the slow branches if
+- // the program ever changes phase and starts seeing nulls here.)
+- //
+- // We do not inspect for a null constant, since a node may
+- // optimize to 'null' later on.
+- //
+- // Null checks, and other tests which expect inequality,
+- // show btest == BoolTest::eq along the non-taken branch.
+- // On the other hand, type tests, must-be-null tests,
+- // and other tests which expect pointer equality,
+- // show btest == BoolTest::ne along the non-taken branch.
+- // We prune both types of branches if they look unused.
++ if (path_is_suitable_for_uncommon_trap(prob)) {
+ repush_if_args();
+- // We need to mark this branch as taken so that if we recompile we will
+- // see that it is possible. In the tiered system the interpreter doesn't
+- // do profiling and by the time we get to the lower tier from the interpreter
+- // the path may be cold again. Make sure it doesn't look untaken
+- if (is_fallthrough) {
+- profile_not_taken_branch(!ProfileInterpreter);
+- } else {
+- profile_taken_branch(iter().get_dest(), !ProfileInterpreter);
+- }
+- uncommon_trap(Deoptimization::Reason_unreached,
++ uncommon_trap(Deoptimization::Reason_unstable_if,
+ Deoptimization::Action_reinterpret,
+ NULL,
+ (is_fallthrough ? "taken always" : "taken never"));
+--- ./hotspot/src/share/vm/opto/parseHelper.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/parseHelper.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -156,22 +156,43 @@
+ int klass_offset = oopDesc::klass_offset_in_bytes();
+ Node* p = basic_plus_adr( ary, ary, klass_offset );
+ // p's type is array-of-OOPS plus klass_offset
+- Node* array_klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS) );
++ Node* array_klass = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeInstPtr::KLASS));
+ // Get the array klass
+ const TypeKlassPtr *tak = _gvn.type(array_klass)->is_klassptr();
+
+- // array_klass's type is generally INexact array-of-oop. Heroically
+- // cast the array klass to EXACT array and uncommon-trap if the cast
+- // fails.
++ // The type of array_klass is usually INexact array-of-oop. Heroically
++ // cast array_klass to EXACT array and uncommon-trap if the cast fails.
++ // Make constant out of the inexact array klass, but use it only if the cast
++ // succeeds.
+ bool always_see_exact_class = false;
+ if (MonomorphicArrayCheck
+- && !too_many_traps(Deoptimization::Reason_array_check)) {
++ && !too_many_traps(Deoptimization::Reason_array_check)
++ && !tak->klass_is_exact()
++ && tak != TypeKlassPtr::OBJECT) {
++ // Regarding the fourth condition in the if-statement from above:
++ //
++ // If the compiler has determined that the type of array 'ary' (represented
++ // by 'array_klass') is java/lang/Object, the compiler must not assume that
++ // the array 'ary' is monomorphic.
++ //
++ // If 'ary' were of type java/lang/Object, this arraystore would have to fail,
++ // because it is not possible to perform a arraystore into an object that is not
++ // a "proper" array.
++ //
++ // Therefore, let's obtain at runtime the type of 'ary' and check if we can still
++ // successfully perform the store.
++ //
++ // The implementation reasons for the condition are the following:
++ //
++ // java/lang/Object is the superclass of all arrays, but it is represented by the VM
++ // as an InstanceKlass. The checks generated by gen_checkcast() (see below) expect
++ // 'array_klass' to be ObjArrayKlass, which can result in invalid memory accesses.
++ //
++ // See issue JDK-8057622 for details.
++
+ always_see_exact_class = true;
+ // (If no MDO at all, hope for the best, until a trap actually occurs.)
+- }
+
+- // Is the array klass is exactly its defined type?
+- if (always_see_exact_class && !tak->klass_is_exact()) {
+ // Make a constant out of the inexact array klass
+ const TypeKlassPtr *extak = tak->cast_to_exactness(true)->is_klassptr();
+ Node* con = makecon(extak);
+@@ -202,11 +223,15 @@
+ // Extract the array element class
+ int element_klass_offset = in_bytes(ObjArrayKlass::element_klass_offset());
+ Node *p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset);
+- Node *a_e_klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p2, tak) );
++ // We are allowed to use the constant type only if cast succeeded. If always_see_exact_class is true,
++ // we must set a control edge from the IfTrue node created by the uncommon_trap above to the
++ // LoadKlassNode.
++ Node* a_e_klass = _gvn.transform(LoadKlassNode::make(_gvn, always_see_exact_class ? control() : NULL,
++ immutable_memory(), p2, tak));
+
+ // Check (the hard way) and throw if not a subklass.
+ // Result is ignored, we just need the CFG effects.
+- gen_checkcast( obj, a_e_klass );
++ gen_checkcast(obj, a_e_klass);
+ }
+
+
+--- ./hotspot/src/share/vm/opto/phaseX.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/phaseX.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1340,15 +1340,27 @@
+ }
+ }
+
+- if( use->is_Cmp() ) { // Enable CMP/BOOL optimization
++ uint use_op = use->Opcode();
++ if(use->is_Cmp()) { // Enable CMP/BOOL optimization
+ add_users_to_worklist(use); // Put Bool on worklist
+- // Look for the 'is_x2logic' pattern: "x ? : 0 : 1" and put the
+- // phi merging either 0 or 1 onto the worklist
+ if (use->outcnt() > 0) {
+ Node* bol = use->raw_out(0);
+ if (bol->outcnt() > 0) {
+ Node* iff = bol->raw_out(0);
+- if (iff->outcnt() == 2) {
++ if (use_op == Op_CmpI &&
++ iff->is_CountedLoopEnd()) {
++ CountedLoopEndNode* cle = iff->as_CountedLoopEnd();
++ if (cle->limit() == n && cle->phi() != NULL) {
++ // If an opaque node feeds into the limit condition of a
++ // CountedLoop, we need to process the Phi node for the
++ // induction variable when the opaque node is removed:
++ // the range of values taken by the Phi is now known and
++ // so its type is also known.
++ _worklist.push(cle->phi());
++ }
++ } else if (iff->outcnt() == 2) {
++ // Look for the 'is_x2logic' pattern: "x ? : 0 : 1" and put the
++ // phi merging either 0 or 1 onto the worklist
+ Node* ifproj0 = iff->raw_out(0);
+ Node* ifproj1 = iff->raw_out(1);
+ if (ifproj0->outcnt() > 0 && ifproj1->outcnt() > 0) {
+@@ -1360,9 +1372,26 @@
+ }
+ }
+ }
++ if (use_op == Op_CmpI) {
++ Node* in1 = use->in(1);
++ for (uint i = 0; i < in1->outcnt(); i++) {
++ if (in1->raw_out(i)->Opcode() == Op_CastII) {
++ Node* castii = in1->raw_out(i);
++ if (castii->in(0) != NULL && castii->in(0)->in(0) != NULL && castii->in(0)->in(0)->is_If()) {
++ Node* ifnode = castii->in(0)->in(0);
++ if (ifnode->in(1) != NULL && ifnode->in(1)->is_Bool() && ifnode->in(1)->in(1) == use) {
++ // Reprocess a CastII node that may depend on an
++ // opaque node value when the opaque node is
++ // removed. In case it carries a dependency we can do
++ // a better job of computing its type.
++ _worklist.push(castii);
++ }
++ }
++ }
++ }
++ }
+ }
+
+- uint use_op = use->Opcode();
+ // If changed Cast input, check Phi users for simple cycles
+ if( use->is_ConstraintCast() || use->is_CheckCastPP() ) {
+ for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) {
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/opto/replacednodes.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,219 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "opto/cfgnode.hpp"
++#include "opto/phaseX.hpp"
++#include "opto/replacednodes.hpp"
++
++void ReplacedNodes::allocate_if_necessary() {
++ if (_replaced_nodes == NULL) {
++ _replaced_nodes = new GrowableArray<ReplacedNode>();
++ }
++}
++
++bool ReplacedNodes::is_empty() const {
++ return _replaced_nodes == NULL || _replaced_nodes->length() == 0;
++}
++
++bool ReplacedNodes::has_node(const ReplacedNode& r) const {
++ return _replaced_nodes->find(r) != -1;
++}
++
++bool ReplacedNodes::has_target_node(Node* n) const {
++ for (int i = 0; i < _replaced_nodes->length(); i++) {
++ if (_replaced_nodes->at(i).improved() == n) {
++ return true;
++ }
++ }
++ return false;
++}
++
++// Record replaced node if not seen before
++void ReplacedNodes::record(Node* initial, Node* improved) {
++ allocate_if_necessary();
++ ReplacedNode r(initial, improved);
++ if (!has_node(r)) {
++ _replaced_nodes->push(r);
++ }
++}
++
++// Copy replaced nodes from one map to another. idx is used to
++// identify nodes that are too new to be of interest in the target
++// node list.
++void ReplacedNodes::transfer_from(const ReplacedNodes& other, uint idx) {
++ if (other.is_empty()) {
++ return;
++ }
++ allocate_if_necessary();
++ for (int i = 0; i < other._replaced_nodes->length(); i++) {
++ ReplacedNode replaced = other._replaced_nodes->at(i);
++ // Only transfer the nodes that can actually be useful
++ if (!has_node(replaced) && (replaced.initial()->_idx < idx || has_target_node(replaced.initial()))) {
++ _replaced_nodes->push(replaced);
++ }
++ }
++}
++
++void ReplacedNodes::clone() {
++ if (_replaced_nodes != NULL) {
++ GrowableArray<ReplacedNode>* replaced_nodes_clone = new GrowableArray<ReplacedNode>();
++ replaced_nodes_clone->appendAll(_replaced_nodes);
++ _replaced_nodes = replaced_nodes_clone;
++ }
++}
++
++void ReplacedNodes::reset() {
++ if (_replaced_nodes != NULL) {
++ _replaced_nodes->clear();
++ }
++}
++
++// Perfom node replacement (used when returning to caller)
++void ReplacedNodes::apply(Node* n) {
++ if (is_empty()) {
++ return;
++ }
++ for (int i = 0; i < _replaced_nodes->length(); i++) {
++ ReplacedNode replaced = _replaced_nodes->at(i);
++ n->replace_edge(replaced.initial(), replaced.improved());
++ }
++}
++
++static void enqueue_use(Node* n, Node* use, Unique_Node_List& work) {
++ if (use->is_Phi()) {
++ Node* r = use->in(0);
++ assert(r->is_Region(), "Phi should have Region");
++ for (uint i = 1; i < use->req(); i++) {
++ if (use->in(i) == n) {
++ work.push(r->in(i));
++ }
++ }
++ } else {
++ work.push(use);
++ }
++}
++
++// Perfom node replacement following late inlining
++void ReplacedNodes::apply(Compile* C, Node* ctl) {
++ // ctl is the control on exit of the method that was late inlined
++ if (is_empty()) {
++ return;
++ }
++ for (int i = 0; i < _replaced_nodes->length(); i++) {
++ ReplacedNode replaced = _replaced_nodes->at(i);
++ Node* initial = replaced.initial();
++ Node* improved = replaced.improved();
++ assert (ctl != NULL && !ctl->is_top(), "replaced node should have actual control");
++
++ ResourceMark rm;
++ Unique_Node_List work;
++ // Go over all the uses of the node that is considered for replacement...
++ for (DUIterator j = initial->outs(); initial->has_out(j); j++) {
++ Node* use = initial->out(j);
++
++ if (use == improved || use->outcnt() == 0) {
++ continue;
++ }
++ work.clear();
++ enqueue_use(initial, use, work);
++ bool replace = true;
++ // Check that this use is dominated by ctl. Go ahead with the
++ // replacement if it is.
++ while (work.size() != 0 && replace) {
++ Node* n = work.pop();
++ if (use->outcnt() == 0) {
++ continue;
++ }
++ if (n->is_CFG() || (n->in(0) != NULL && !n->in(0)->is_top())) {
++ int depth = 0;
++ Node *m = n;
++ if (!n->is_CFG()) {
++ n = n->in(0);
++ }
++ assert(n->is_CFG(), "should be CFG now");
++ while(n != ctl) {
++ n = IfNode::up_one_dom(n);
++ depth++;
++ // limit search depth
++ if (depth >= 100 || n == NULL) {
++ replace = false;
++ break;
++ }
++ }
++ } else {
++ for (DUIterator k = n->outs(); n->has_out(k); k++) {
++ enqueue_use(n, n->out(k), work);
++ }
++ }
++ }
++ if (replace) {
++ bool is_in_table = C->initial_gvn()->hash_delete(use);
++ int replaced = use->replace_edge(initial, improved);
++ if (is_in_table) {
++ C->initial_gvn()->hash_find_insert(use);
++ }
++ C->record_for_igvn(use);
++
++ assert(replaced > 0, "inconsistent");
++ --j;
++ }
++ }
++ }
++}
++
++void ReplacedNodes::dump(outputStream *st) const {
++ if (!is_empty()) {
++ st->print("replaced nodes: ");
++ for (int i = 0; i < _replaced_nodes->length(); i++) {
++ st->print("%d->%d", _replaced_nodes->at(i).initial()->_idx, _replaced_nodes->at(i).improved()->_idx);
++ if (i < _replaced_nodes->length()-1) {
++ st->print(",");
++ }
++ }
++ }
++}
++
++// Merge 2 list of replaced node at a point where control flow paths merge
++void ReplacedNodes::merge_with(const ReplacedNodes& other) {
++ if (is_empty()) {
++ return;
++ }
++ if (other.is_empty()) {
++ reset();
++ return;
++ }
++ int shift = 0;
++ int len = _replaced_nodes->length();
++ for (int i = 0; i < len; i++) {
++ if (!other.has_node(_replaced_nodes->at(i))) {
++ shift++;
++ } else if (shift > 0) {
++ _replaced_nodes->at_put(i-shift, _replaced_nodes->at(i));
++ }
++ }
++ if (shift > 0) {
++ _replaced_nodes->trunc_to(len - shift);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/opto/replacednodes.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,81 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_OPTO_REPLACEDNODES_HPP
++#define SHARE_VM_OPTO_REPLACEDNODES_HPP
++
++#include "opto/connode.hpp"
++
++// During parsing, when a node is "improved",
++// GraphKit::replace_in_map() is called to update the current map so
++// that the improved node is used from that point
++// on. GraphKit::replace_in_map() doesn't operate on the callers maps
++// and so some optimization opportunities may be lost. The
++// ReplacedNodes class addresses that problem.
++//
++// A ReplacedNodes object is a list of pair of nodes. Every
++// SafePointNode carries a ReplacedNodes object. Every time
++// GraphKit::replace_in_map() is called, a new pair of nodes is pushed
++// on the list of replaced nodes. When control flow paths merge, their
++// replaced nodes are also merged. When parsing exits a method to
++// return to a caller, the replaced nodes on the exit path are used to
++// update the caller's map.
++class ReplacedNodes VALUE_OBJ_CLASS_SPEC {
++ private:
++ class ReplacedNode VALUE_OBJ_CLASS_SPEC {
++ private:
++ Node* _initial;
++ Node* _improved;
++ public:
++ ReplacedNode() : _initial(NULL), _improved(NULL) {}
++ ReplacedNode(Node* initial, Node* improved) : _initial(initial), _improved(improved) {}
++ Node* initial() const { return _initial; }
++ Node* improved() const { return _improved; }
++
++ bool operator==(const ReplacedNode& other) {
++ return _initial == other._initial && _improved == other._improved;
++ }
++ };
++ GrowableArray<ReplacedNode>* _replaced_nodes;
++
++ void allocate_if_necessary();
++ bool has_node(const ReplacedNode& r) const;
++ bool has_target_node(Node* n) const;
++
++ public:
++ ReplacedNodes()
++ : _replaced_nodes(NULL) {}
++
++ void clone();
++ void record(Node* initial, Node* improved);
++ void transfer_from(const ReplacedNodes& other, uint idx);
++ void reset();
++ void apply(Node* n);
++ void merge_with(const ReplacedNodes& other);
++ bool is_empty() const;
++ void dump(outputStream *st) const;
++ void apply(Compile* C, Node* ctl);
++};
++
++#endif // SHARE_VM_OPTO_REPLACEDNODES_HPP
+--- ./hotspot/src/share/vm/opto/runtime.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/runtime.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -898,6 +898,74 @@
+ return TypeFunc::make(domain, range);
+ }
+
++/*
++ * void implCompress(byte[] buf, int ofs)
++ */
++const TypeFunc* OptoRuntime::sha_implCompress_Type() {
++ // create input type (domain)
++ int num_args = 2;
++ int argcnt = num_args;
++ const Type** fields = TypeTuple::fields(argcnt);
++ int argp = TypeFunc::Parms;
++ fields[argp++] = TypePtr::NOTNULL; // buf
++ fields[argp++] = TypePtr::NOTNULL; // state
++ assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
++ const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
++
++ // no result type needed
++ fields = TypeTuple::fields(1);
++ fields[TypeFunc::Parms+0] = NULL; // void
++ const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
++ return TypeFunc::make(domain, range);
++}
++
++/*
++ * int implCompressMultiBlock(byte[] b, int ofs, int limit)
++ */
++const TypeFunc* OptoRuntime::digestBase_implCompressMB_Type() {
++ // create input type (domain)
++ int num_args = 4;
++ int argcnt = num_args;
++ const Type** fields = TypeTuple::fields(argcnt);
++ int argp = TypeFunc::Parms;
++ fields[argp++] = TypePtr::NOTNULL; // buf
++ fields[argp++] = TypePtr::NOTNULL; // state
++ fields[argp++] = TypeInt::INT; // ofs
++ fields[argp++] = TypeInt::INT; // limit
++ assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
++ const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
++
++ // returning ofs (int)
++ fields = TypeTuple::fields(1);
++ fields[TypeFunc::Parms+0] = TypeInt::INT; // ofs
++ const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
++ return TypeFunc::make(domain, range);
++}
++
++const TypeFunc* OptoRuntime::multiplyToLen_Type() {
++ // create input type (domain)
++ int num_args = 6;
++ int argcnt = num_args;
++ const Type** fields = TypeTuple::fields(argcnt);
++ int argp = TypeFunc::Parms;
++ fields[argp++] = TypePtr::NOTNULL; // x
++ fields[argp++] = TypeInt::INT; // xlen
++ fields[argp++] = TypePtr::NOTNULL; // y
++ fields[argp++] = TypeInt::INT; // ylen
++ fields[argp++] = TypePtr::NOTNULL; // z
++ fields[argp++] = TypeInt::INT; // zlen
++ assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
++ const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
++
++ // no result type needed
++ fields = TypeTuple::fields(1);
++ fields[TypeFunc::Parms+0] = NULL;
++ const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
++ return TypeFunc::make(domain, range);
++}
++
++
++
+ //------------- Interpreter state access for on stack replacement
+ const TypeFunc* OptoRuntime::osr_end_Type() {
+ // create input type (domain)
+--- ./hotspot/src/share/vm/opto/runtime.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/runtime.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -300,6 +300,11 @@
+ static const TypeFunc* aescrypt_block_Type();
+ static const TypeFunc* cipherBlockChaining_aescrypt_Type();
+
++ static const TypeFunc* sha_implCompress_Type();
++ static const TypeFunc* digestBase_implCompressMB_Type();
++
++ static const TypeFunc* multiplyToLen_Type();
++
+ static const TypeFunc* updateBytesCRC32_Type();
+
+ // leaf on stack replacement interpreter accessor types
+--- ./hotspot/src/share/vm/opto/subnode.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/subnode.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1147,12 +1147,10 @@
+
+ //------------------------------dump_spec-------------------------------------
+ // Print special per-node info
+-#ifndef PRODUCT
+ void BoolTest::dump_on(outputStream *st) const {
+ const char *msg[] = {"eq","gt","of","lt","ne","le","nof","ge"};
+ st->print("%s", msg[_test]);
+ }
+-#endif
+
+ //=============================================================================
+ uint BoolNode::hash() const { return (Node::hash() << 3)|(_test._test+1); }
+--- ./hotspot/src/share/vm/opto/subnode.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/subnode.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -275,9 +275,7 @@
+ mask commute( ) const { return mask("032147658"[_test]-'0'); }
+ mask negate( ) const { return mask(_test^4); }
+ bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le || _test == BoolTest::overflow); }
+-#ifndef PRODUCT
+ void dump_on(outputStream *st) const;
+-#endif
+ };
+
+ //------------------------------BoolNode---------------------------------------
+--- ./hotspot/src/share/vm/opto/superword.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/superword.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1374,6 +1374,20 @@
+ if (n->is_Load()) {
+ Node* ctl = n->in(MemNode::Control);
+ Node* mem = first->in(MemNode::Memory);
++ SWPointer p1(n->as_Mem(), this);
++ // Identify the memory dependency for the new loadVector node by
++ // walking up through memory chain.
++ // This is done to give flexibility to the new loadVector node so that
++ // it can move above independent storeVector nodes.
++ while (mem->is_StoreVector()) {
++ SWPointer p2(mem->as_Mem(), this);
++ int cmp = p1.cmp(p2);
++ if (SWPointer::not_equal(cmp) || !SWPointer::comparable(cmp)) {
++ mem = mem->in(MemNode::Memory);
++ } else {
++ break; // dependent memory
++ }
++ }
+ Node* adr = low_adr->in(MemNode::Address);
+ const TypePtr* atyp = n->adr_type();
+ vn = LoadVectorNode::make(C, opc, ctl, mem, adr, atyp, vlen, velt_basic_type(n));
+--- ./hotspot/src/share/vm/opto/type.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/opto/type.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -265,7 +265,7 @@
+ // locking.
+
+ Arena* save = current->type_arena();
+- Arena* shared_type_arena = new (mtCompiler)Arena();
++ Arena* shared_type_arena = new (mtCompiler)Arena(mtCompiler);
+
+ current->set_type_arena(shared_type_arena);
+ _shared_type_dict =
+--- ./hotspot/src/share/vm/precompiled/precompiled.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/precompiled/precompiled.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -193,11 +193,13 @@
+ # include "runtime/mutexLocker.hpp"
+ # include "runtime/objectMonitor.hpp"
+ # include "runtime/orderAccess.hpp"
++# include "runtime/orderAccess.inline.hpp"
+ # include "runtime/os.hpp"
+ # include "runtime/osThread.hpp"
+ # include "runtime/perfData.hpp"
+ # include "runtime/perfMemory.hpp"
+ # include "runtime/prefetch.hpp"
++# include "runtime/prefetch.inline.hpp"
+ # include "runtime/reflection.hpp"
+ # include "runtime/reflectionUtils.hpp"
+ # include "runtime/registerMap.hpp"
+@@ -218,10 +220,17 @@
+ # include "runtime/vmThread.hpp"
+ # include "runtime/vm_operations.hpp"
+ # include "runtime/vm_version.hpp"
++# include "services/allocationSite.hpp"
+ # include "services/lowMemoryDetector.hpp"
++# include "services/mallocTracker.hpp"
++# include "services/memBaseline.hpp"
+ # include "services/memoryPool.hpp"
+ # include "services/memoryService.hpp"
+ # include "services/memoryUsage.hpp"
++# include "services/memReporter.hpp"
++# include "services/memTracker.hpp"
++# include "services/nmtCommon.hpp"
++# include "services/virtualMemoryTracker.hpp"
+ # include "utilities/accessFlags.hpp"
+ # include "utilities/array.hpp"
+ # include "utilities/bitMap.hpp"
+@@ -235,6 +244,7 @@
+ # include "utilities/hashtable.hpp"
+ # include "utilities/histogram.hpp"
+ # include "utilities/macros.hpp"
++# include "utilities/nativeCallStack.hpp"
+ # include "utilities/numberSeq.hpp"
+ # include "utilities/ostream.hpp"
+ # include "utilities/preserveException.hpp"
+--- ./hotspot/src/share/vm/prims/forte.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/forte.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -32,7 +32,7 @@
+ #include "oops/oop.inline2.hpp"
+ #include "prims/forte.hpp"
+ #include "runtime/javaCalls.hpp"
+-#include "runtime/thread.hpp"
++#include "runtime/thread.inline.hpp"
+ #include "runtime/vframe.hpp"
+ #include "runtime/vframeArray.hpp"
+
+--- ./hotspot/src/share/vm/prims/jni.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/jni.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -67,11 +67,13 @@
+ #include "runtime/java.hpp"
+ #include "runtime/javaCalls.hpp"
+ #include "runtime/jfieldIDWorkaround.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/reflection.hpp"
+ #include "runtime/sharedRuntime.hpp"
+ #include "runtime/signature.hpp"
+ #include "runtime/thread.inline.hpp"
+ #include "runtime/vm_operations.hpp"
++#include "services/memTracker.hpp"
+ #include "services/runtimeService.hpp"
+ #include "trace/tracing.hpp"
+ #include "utilities/defaultStream.hpp"
+@@ -291,15 +293,6 @@
+ "Bug in native code: jfieldID offset must address interior of object");
+ }
+
+-// Pick a reasonable higher bound for local capacity requested
+-// for EnsureLocalCapacity and PushLocalFrame. We don't want it too
+-// high because a test (or very unusual application) may try to allocate
+-// that many handles and run out of swap space. An implementation is
+-// permitted to allocate more handles than the ensured capacity, so this
+-// value is set high enough to prevent compatibility problems.
+-const int MAX_REASONABLE_LOCAL_CAPACITY = 4*K;
+-
+-
+ // Wrapper to trace JNI functions
+
+ #ifdef ASSERT
+@@ -879,7 +872,8 @@
+ env, capacity);
+ #endif /* USDT2 */
+ //%note jni_11
+- if (capacity < 0 || capacity > MAX_REASONABLE_LOCAL_CAPACITY) {
++ if (capacity < 0 ||
++ ((MaxJNILocalCapacity > 0) && (capacity > MaxJNILocalCapacity))) {
+ #ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, JNI_ERR);
+ #else /* USDT2 */
+@@ -1038,7 +1032,8 @@
+ env, capacity);
+ #endif /* USDT2 */
+ jint ret;
+- if (capacity >= 0 && capacity <= MAX_REASONABLE_LOCAL_CAPACITY) {
++ if (capacity >= 0 &&
++ ((MaxJNILocalCapacity <= 0) || (capacity <= MaxJNILocalCapacity))) {
+ ret = JNI_OK;
+ } else {
+ ret = JNI_ERR;
+@@ -3588,6 +3583,7 @@
+ if (bad_address != NULL) {
+ os::protect_memory(bad_address, size, os::MEM_PROT_READ,
+ /*is_committed*/false);
++ MemTracker::record_virtual_memory_type((void*)bad_address, mtInternal);
+ }
+ }
+ return bad_address;
+@@ -5063,6 +5059,7 @@
+ #if INCLUDE_ALL_GCS
+ #include "gc_implementation/g1/heapRegionRemSet.hpp"
+ #endif
++#include "memory/guardedMemory.hpp"
+ #include "utilities/quickSort.hpp"
+ #include "utilities/ostream.hpp"
+ #if INCLUDE_VM_STRUCTS
+@@ -5081,10 +5078,15 @@
+ void TestMetachunk_test();
+ void TestVirtualSpaceNode_test();
+ void TestNewSize_test();
++void TestKlass_test();
++void Test_linked_list();
++void TestChunkedList_test();
+ #if INCLUDE_ALL_GCS
+ void TestOldFreeSpaceCalculation_test();
+ void TestG1BiasedArray_test();
++void TestBufferingOopClosure_test();
+ void TestCodeCacheRemSet_test();
++void FreeRegionList_test();
+ #endif
+
+ void execute_internal_vm_tests() {
+@@ -5101,9 +5103,13 @@
+ run_unit_test(arrayOopDesc::test_max_array_length());
+ run_unit_test(CollectedHeap::test_is_in());
+ run_unit_test(QuickSort::test_quick_sort());
++ run_unit_test(GuardedMemory::test_guarded_memory());
+ run_unit_test(AltHashing::test_alt_hash());
+ run_unit_test(test_loggc_filename());
+ run_unit_test(TestNewSize_test());
++ run_unit_test(TestKlass_test());
++ run_unit_test(Test_linked_list());
++ run_unit_test(TestChunkedList_test());
+ #if INCLUDE_VM_STRUCTS
+ run_unit_test(VMStructs::test());
+ #endif
+@@ -5111,7 +5117,11 @@
+ run_unit_test(TestOldFreeSpaceCalculation_test());
+ run_unit_test(TestG1BiasedArray_test());
+ run_unit_test(HeapRegionRemSet::test_prt());
++ run_unit_test(TestBufferingOopClosure_test());
+ run_unit_test(TestCodeCacheRemSet_test());
++ if (UseG1GC) {
++ run_unit_test(FreeRegionList_test());
++ }
+ #endif
+ tty->print_cr("All internal VM tests passed");
+ }
+--- ./hotspot/src/share/vm/prims/jniCheck.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/jniCheck.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,6 +25,7 @@
+ #include "precompiled.hpp"
+ #include "classfile/systemDictionary.hpp"
+ #include "classfile/vmSymbols.hpp"
++#include "memory/guardedMemory.hpp"
+ #include "oops/instanceKlass.hpp"
+ #include "oops/oop.inline.hpp"
+ #include "oops/symbol.hpp"
+@@ -35,7 +36,7 @@
+ #include "runtime/handles.hpp"
+ #include "runtime/interfaceSupport.hpp"
+ #include "runtime/jfieldIDWorkaround.hpp"
+-#include "runtime/thread.hpp"
++#include "runtime/thread.inline.hpp"
+ #ifdef TARGET_ARCH_x86
+ # include "jniTypes_x86.hpp"
+ #endif
+@@ -323,6 +324,74 @@
+ }
+ }
+
++/*
++ * Copy and wrap array elements for bounds checking.
++ * Remember the original elements (GuardedMemory::get_tag())
++ */
++static void* check_jni_wrap_copy_array(JavaThread* thr, jarray array,
++ void* orig_elements) {
++ void* result;
++ IN_VM(
++ oop a = JNIHandles::resolve_non_null(array);
++ size_t len = arrayOop(a)->length() <<
++ TypeArrayKlass::cast(a->klass())->log2_element_size();
++ result = GuardedMemory::wrap_copy(orig_elements, len, orig_elements);
++ )
++ return result;
++}
++
++static void* check_wrapped_array(JavaThread* thr, const char* fn_name,
++ void* obj, void* carray, size_t* rsz) {
++ if (carray == NULL) {
++ tty->print_cr("%s: elements vector NULL" PTR_FORMAT, fn_name, p2i(obj));
++ NativeReportJNIFatalError(thr, "Elements vector NULL");
++ }
++ GuardedMemory guarded(carray);
++ void* orig_result = guarded.get_tag();
++ if (!guarded.verify_guards()) {
++ tty->print_cr("ReleasePrimitiveArrayCritical: release array failed bounds "
++ "check, incorrect pointer returned ? array: " PTR_FORMAT " carray: "
++ PTR_FORMAT, p2i(obj), p2i(carray));
++ guarded.print_on(tty);
++ NativeReportJNIFatalError(thr, "ReleasePrimitiveArrayCritical: "
++ "failed bounds check");
++ }
++ if (orig_result == NULL) {
++ tty->print_cr("ReleasePrimitiveArrayCritical: unrecognized elements. array: "
++ PTR_FORMAT " carray: " PTR_FORMAT, p2i(obj), p2i(carray));
++ guarded.print_on(tty);
++ NativeReportJNIFatalError(thr, "ReleasePrimitiveArrayCritical: "
++ "unrecognized elements");
++ }
++ if (rsz != NULL) {
++ *rsz = guarded.get_user_size();
++ }
++ return orig_result;
++}
++
++static void* check_wrapped_array_release(JavaThread* thr, const char* fn_name,
++ void* obj, void* carray, jint mode) {
++ size_t sz;
++ void* orig_result = check_wrapped_array(thr, fn_name, obj, carray, &sz);
++ switch (mode) {
++ case 0:
++ memcpy(orig_result, carray, sz);
++ GuardedMemory::free_copy(carray);
++ break;
++ case JNI_COMMIT:
++ memcpy(orig_result, carray, sz);
++ break;
++ case JNI_ABORT:
++ GuardedMemory::free_copy(carray);
++ break;
++ default:
++ tty->print_cr("%s: Unrecognized mode %i releasing array "
++ PTR_FORMAT " elements " PTR_FORMAT, fn_name, mode, p2i(obj), p2i(carray));
++ NativeReportJNIFatalError(thr, "Unrecognized array release mode");
++ }
++ return orig_result;
++}
++
+ oop jniCheck::validate_handle(JavaThread* thr, jobject obj) {
+ if (JNIHandles::is_frame_handle(thr, obj) ||
+ JNIHandles::is_local_handle(thr, obj) ||
+@@ -1314,7 +1383,7 @@
+ JNI_END
+
+ // Arbitrary (but well-known) tag
+-const jint STRING_TAG = 0x47114711;
++const void* STRING_TAG = (void*)0x47114711;
+
+ JNI_ENTRY_CHECKED(const jchar *,
+ checked_jni_GetStringChars(JNIEnv *env,
+@@ -1324,21 +1393,22 @@
+ IN_VM(
+ checkString(thr, str);
+ )
+- jchar* newResult = NULL;
++ jchar* new_result = NULL;
+ const jchar *result = UNCHECKED()->GetStringChars(env,str,isCopy);
+ assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringChars didn't return a copy as expected");
+ if (result != NULL) {
+ size_t len = UNCHECKED()->GetStringLength(env,str) + 1; // + 1 for NULL termination
+- jint* tagLocation = (jint*) AllocateHeap(len * sizeof(jchar) + sizeof(jint), mtInternal);
+- *tagLocation = STRING_TAG;
+- newResult = (jchar*) (tagLocation + 1);
+- memcpy(newResult, result, len * sizeof(jchar));
++ len *= sizeof(jchar);
++ new_result = (jchar*) GuardedMemory::wrap_copy(result, len, STRING_TAG);
++ if (new_result == NULL) {
++ vm_exit_out_of_memory(len, OOM_MALLOC_ERROR, "checked_jni_GetStringChars");
++ }
+ // Avoiding call to UNCHECKED()->ReleaseStringChars() since that will fire unexpected dtrace probes
+ // Note that the dtrace arguments for the allocated memory will not match up with this solution.
+ FreeHeap((char*)result);
+ }
+ functionExit(env);
+- return newResult;
++ return new_result;
+ JNI_END
+
+ JNI_ENTRY_CHECKED(void,
+@@ -1354,11 +1424,23 @@
+ UNCHECKED()->ReleaseStringChars(env,str,chars);
+ }
+ else {
+- jint* tagLocation = ((jint*) chars) - 1;
+- if (*tagLocation != STRING_TAG) {
+- NativeReportJNIFatalError(thr, "ReleaseStringChars called on something not allocated by GetStringChars");
+- }
+- UNCHECKED()->ReleaseStringChars(env,str,(const jchar*)tagLocation);
++ GuardedMemory guarded((void*)chars);
++ if (!guarded.verify_guards()) {
++ tty->print_cr("ReleaseStringChars: release chars failed bounds check. "
++ "string: " PTR_FORMAT " chars: " PTR_FORMAT, p2i(str), p2i(chars));
++ guarded.print_on(tty);
++ NativeReportJNIFatalError(thr, "ReleaseStringChars: "
++ "release chars failed bounds check.");
++ }
++ if (guarded.get_tag() != STRING_TAG) {
++ tty->print_cr("ReleaseStringChars: called on something not allocated "
++ "by GetStringChars. string: " PTR_FORMAT " chars: " PTR_FORMAT,
++ p2i(str), p2i(chars));
++ NativeReportJNIFatalError(thr, "ReleaseStringChars called on something "
++ "not allocated by GetStringChars");
++ }
++ UNCHECKED()->ReleaseStringChars(env, str,
++ (const jchar*) guarded.release_for_freeing());
+ }
+ functionExit(env);
+ JNI_END
+@@ -1385,7 +1467,7 @@
+ JNI_END
+
+ // Arbitrary (but well-known) tag - different than GetStringChars
+-const jint STRING_UTF_TAG = 0x48124812;
++const void* STRING_UTF_TAG = (void*) 0x48124812;
+
+ JNI_ENTRY_CHECKED(const char *,
+ checked_jni_GetStringUTFChars(JNIEnv *env,
+@@ -1395,21 +1477,21 @@
+ IN_VM(
+ checkString(thr, str);
+ )
+- char* newResult = NULL;
++ char* new_result = NULL;
+ const char *result = UNCHECKED()->GetStringUTFChars(env,str,isCopy);
+ assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringUTFChars didn't return a copy as expected");
+ if (result != NULL) {
+ size_t len = strlen(result) + 1; // + 1 for NULL termination
+- jint* tagLocation = (jint*) AllocateHeap(len + sizeof(jint), mtInternal);
+- *tagLocation = STRING_UTF_TAG;
+- newResult = (char*) (tagLocation + 1);
+- strcpy(newResult, result);
++ new_result = (char*) GuardedMemory::wrap_copy(result, len, STRING_UTF_TAG);
++ if (new_result == NULL) {
++ vm_exit_out_of_memory(len, OOM_MALLOC_ERROR, "checked_jni_GetStringUTFChars");
++ }
+ // Avoiding call to UNCHECKED()->ReleaseStringUTFChars() since that will fire unexpected dtrace probes
+ // Note that the dtrace arguments for the allocated memory will not match up with this solution.
+ FreeHeap((char*)result, mtInternal);
+ }
+ functionExit(env);
+- return newResult;
++ return new_result;
+ JNI_END
+
+ JNI_ENTRY_CHECKED(void,
+@@ -1425,11 +1507,23 @@
+ UNCHECKED()->ReleaseStringUTFChars(env,str,chars);
+ }
+ else {
+- jint* tagLocation = ((jint*) chars) - 1;
+- if (*tagLocation != STRING_UTF_TAG) {
+- NativeReportJNIFatalError(thr, "ReleaseStringUTFChars called on something not allocated by GetStringUTFChars");
+- }
+- UNCHECKED()->ReleaseStringUTFChars(env,str,(const char*)tagLocation);
++ GuardedMemory guarded((void*)chars);
++ if (!guarded.verify_guards()) {
++ tty->print_cr("ReleaseStringUTFChars: release chars failed bounds check. "
++ "string: " PTR_FORMAT " chars: " PTR_FORMAT, p2i(str), p2i(chars));
++ guarded.print_on(tty);
++ NativeReportJNIFatalError(thr, "ReleaseStringUTFChars: "
++ "release chars failed bounds check.");
++ }
++ if (guarded.get_tag() != STRING_UTF_TAG) {
++ tty->print_cr("ReleaseStringUTFChars: called on something not "
++ "allocated by GetStringUTFChars. string: " PTR_FORMAT " chars: "
++ PTR_FORMAT, p2i(str), p2i(chars));
++ NativeReportJNIFatalError(thr, "ReleaseStringUTFChars "
++ "called on something not allocated by GetStringUTFChars");
++ }
++ UNCHECKED()->ReleaseStringUTFChars(env, str,
++ (const char*) guarded.release_for_freeing());
+ }
+ functionExit(env);
+ JNI_END
+@@ -1514,6 +1608,9 @@
+ ElementType *result = UNCHECKED()->Get##Result##ArrayElements(env, \
+ array, \
+ isCopy); \
++ if (result != NULL) { \
++ result = (ElementType *) check_jni_wrap_copy_array(thr, array, result); \
++ } \
+ functionExit(env); \
+ return result; \
+ JNI_END
+@@ -1538,12 +1635,10 @@
+ check_primitive_array_type(thr, array, ElementTag); \
+ ASSERT_OOPS_ALLOWED; \
+ typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
+- /* cannot check validity of copy, unless every request is logged by
+- * checking code. Implementation of this check is deferred until a
+- * subsequent release.
+- */ \
+ ) \
+- UNCHECKED()->Release##Result##ArrayElements(env,array,elems,mode); \
++ ElementType* orig_result = (ElementType *) check_wrapped_array_release( \
++ thr, "checked_jni_Release"#Result"ArrayElements", array, elems, mode); \
++ UNCHECKED()->Release##Result##ArrayElements(env, array, orig_result, mode); \
+ functionExit(env); \
+ JNI_END
+
+@@ -1694,6 +1789,9 @@
+ check_is_primitive_array(thr, array);
+ )
+ void *result = UNCHECKED()->GetPrimitiveArrayCritical(env, array, isCopy);
++ if (result != NULL) {
++ result = check_jni_wrap_copy_array(thr, array, result);
++ }
+ functionExit(env);
+ return result;
+ JNI_END
+@@ -1707,10 +1805,9 @@
+ IN_VM(
+ check_is_primitive_array(thr, array);
+ )
+- /* The Hotspot JNI code does not use the parameters, so just check the
+- * array parameter as a minor sanity check
+- */
+- UNCHECKED()->ReleasePrimitiveArrayCritical(env, array, carray, mode);
++ // Check the element array...
++ void* orig_result = check_wrapped_array_release(thr, "ReleasePrimitiveArrayCritical", array, carray, mode);
++ UNCHECKED()->ReleasePrimitiveArrayCritical(env, array, orig_result, mode);
+ functionExit(env);
+ JNI_END
+
+--- ./hotspot/src/share/vm/prims/jvm.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/jvm.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -24,10 +24,15 @@
+
+ #include "precompiled.hpp"
+ #include "classfile/classLoader.hpp"
++#include "classfile/classLoaderExt.hpp"
+ #include "classfile/javaAssertions.hpp"
+ #include "classfile/javaClasses.hpp"
+ #include "classfile/symbolTable.hpp"
+ #include "classfile/systemDictionary.hpp"
++#if INCLUDE_CDS
++#include "classfile/sharedClassUtil.hpp"
++#include "classfile/systemDictionaryShared.hpp"
++#endif
+ #include "classfile/vmSymbols.hpp"
+ #include "gc_interface/collectedHeap.inline.hpp"
+ #include "interpreter/bytecode.hpp"
+@@ -51,6 +56,7 @@
+ #include "runtime/java.hpp"
+ #include "runtime/javaCalls.hpp"
+ #include "runtime/jfieldIDWorkaround.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/os.hpp"
+ #include "runtime/perfData.hpp"
+ #include "runtime/reflection.hpp"
+@@ -388,6 +394,14 @@
+ }
+ }
+
++ const char* enableSharedLookupCache = "false";
++#if INCLUDE_CDS
++ if (ClassLoaderExt::is_lookup_cache_enabled()) {
++ enableSharedLookupCache = "true";
++ }
++#endif
++ PUTPROP(props, "sun.cds.enableSharedLookupCache", enableSharedLookupCache);
++
+ return properties;
+ JVM_END
+
+@@ -589,13 +603,14 @@
+
+ // Make shallow object copy
+ const int size = obj->size();
+- oop new_obj = NULL;
++ oop new_obj_oop = NULL;
+ if (obj->is_array()) {
+ const int length = ((arrayOop)obj())->length();
+- new_obj = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL);
++ new_obj_oop = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL);
+ } else {
+- new_obj = CollectedHeap::obj_allocate(klass, size, CHECK_NULL);
++ new_obj_oop = CollectedHeap::obj_allocate(klass, size, CHECK_NULL);
+ }
++
+ // 4839641 (4840070): We must do an oop-atomic copy, because if another thread
+ // is modifying a reference field in the clonee, a non-oop-atomic copy might
+ // be suspended in the middle of copying the pointer and end up with parts
+@@ -606,24 +621,41 @@
+ // The same is true of StubRoutines::object_copy and the various oop_copy
+ // variants, and of the code generated by the inline_native_clone intrinsic.
+ assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned");
+- Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj,
++ Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj_oop,
+ (size_t)align_object_size(size) / HeapWordsPerLong);
+ // Clear the header
+- new_obj->init_mark();
++ new_obj_oop->init_mark();
+
+ // Store check (mark entire object and let gc sort it out)
+ BarrierSet* bs = Universe::heap()->barrier_set();
+ assert(bs->has_write_region_opt(), "Barrier set does not have write_region");
+- bs->write_region(MemRegion((HeapWord*)new_obj, size));
++ bs->write_region(MemRegion((HeapWord*)new_obj_oop, size));
++
++ Handle new_obj(THREAD, new_obj_oop);
++ // Special handling for MemberNames. Since they contain Method* metadata, they
++ // must be registered so that RedefineClasses can fix metadata contained in them.
++ if (java_lang_invoke_MemberName::is_instance(new_obj()) &&
++ java_lang_invoke_MemberName::is_method(new_obj())) {
++ Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(new_obj());
++ // MemberName may be unresolved, so doesn't need registration until resolved.
++ if (method != NULL) {
++ methodHandle m(THREAD, method);
++ // This can safepoint and redefine method, so need both new_obj and method
++ // in a handle, for two different reasons. new_obj can move, method can be
++ // deleted if nothing is using it on the stack.
++ m->method_holder()->add_member_name(new_obj());
++ }
++ }
+
+ // Caution: this involves a java upcall, so the clone should be
+ // "gc-robust" by this stage.
+ if (klass->has_finalizer()) {
+ assert(obj->is_instance(), "should be instanceOop");
+- new_obj = InstanceKlass::register_finalizer(instanceOop(new_obj), CHECK_NULL);
++ new_obj_oop = InstanceKlass::register_finalizer(instanceOop(new_obj()), CHECK_NULL);
++ new_obj = Handle(THREAD, new_obj_oop);
+ }
+
+- return JNIHandles::make_local(env, oop(new_obj));
++ return JNIHandles::make_local(env, new_obj());
+ JVM_END
+
+ // java.lang.Compiler ////////////////////////////////////////////////////
+@@ -761,6 +793,36 @@
+ JVM_END
+
+
++JVM_ENTRY(jboolean, JVM_KnownToNotExist(JNIEnv *env, jobject loader, const char *classname))
++ JVMWrapper("JVM_KnownToNotExist");
++#if INCLUDE_CDS
++ return ClassLoaderExt::known_to_not_exist(env, loader, classname, CHECK_(false));
++#else
++ return false;
++#endif
++JVM_END
++
++
++JVM_ENTRY(jobjectArray, JVM_GetResourceLookupCacheURLs(JNIEnv *env, jobject loader))
++ JVMWrapper("JVM_GetResourceLookupCacheURLs");
++#if INCLUDE_CDS
++ return ClassLoaderExt::get_lookup_cache_urls(env, loader, CHECK_NULL);
++#else
++ return NULL;
++#endif
++JVM_END
++
++
++JVM_ENTRY(jintArray, JVM_GetResourceLookupCache(JNIEnv *env, jobject loader, const char *resource_name))
++ JVMWrapper("JVM_GetResourceLookupCache");
++#if INCLUDE_CDS
++ return ClassLoaderExt::get_lookup_cache(env, loader, resource_name, CHECK_NULL);
++#else
++ return NULL;
++#endif
++JVM_END
++
++
+ // Returns a class loaded by the bootstrap class loader; or null
+ // if not found. ClassNotFoundException is not thrown.
+ //
+@@ -1032,7 +1094,15 @@
+ h_loader,
+ Handle(),
+ CHECK_NULL);
+-
++#if INCLUDE_CDS
++ if (k == NULL) {
++ // If the class is not already loaded, try to see if it's in the shared
++ // archive for the current classloader (h_loader).
++ instanceKlassHandle ik = SystemDictionaryShared::find_or_load_shared_class(
++ klass_name, h_loader, CHECK_NULL);
++ k = ik();
++ }
++#endif
+ return (k == NULL) ? NULL :
+ (jclass) JNIHandles::make_local(env, k->java_mirror());
+ JVM_END
+@@ -4474,7 +4544,7 @@
+
+ JVM_ENTRY(void, JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size))
+ {
+- memset(info, 0, sizeof(info_size));
++ memset(info, 0, info_size);
+
+ info->jvm_version = Abstract_VM_Version::jvm_version();
+ info->update_version = 0; /* 0 in HotSpot Express VM */
+--- ./hotspot/src/share/vm/prims/jvm.h Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/jvm.h Wed Feb 04 12:14:39 2015 -0800
+@@ -1548,6 +1548,31 @@
+ JNIEXPORT jobjectArray JNICALL
+ JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArray values);
+
++/*
++ * Returns true if the JVM's lookup cache indicates that this class is
++ * known to NOT exist for the given loader.
++ */
++JNIEXPORT jboolean JNICALL
++JVM_KnownToNotExist(JNIEnv *env, jobject loader, const char *classname);
++
++/*
++ * Returns an array of all URLs that are stored in the JVM's lookup cache
++ * for the given loader. NULL if the lookup cache is unavailable.
++ */
++JNIEXPORT jobjectArray JNICALL
++JVM_GetResourceLookupCacheURLs(JNIEnv *env, jobject loader);
++
++/*
++ * Returns an array of all URLs that *may* contain the resource_name for the
++ * given loader. This function returns an integer array, each element
++ * of which can be used to index into the array returned by
++ * JVM_GetResourceLookupCacheURLs of the same loader to determine the
++ * URLs.
++ */
++JNIEXPORT jintArray JNICALL
++JVM_GetResourceLookupCache(JNIEnv *env, jobject loader, const char *resource_name);
++
++
+ /* =========================================================================
+ * The following defines a private JVM interface that the JDK can query
+ * for the JVM version and capabilities. sun.misc.Version defines
+--- ./hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -54,6 +54,7 @@
+ void JvmtiClassFileReconstituter::write_field_infos() {
+ HandleMark hm(thread());
+ Array<AnnotationArray*>* fields_anno = ikh()->fields_annotations();
++ Array<AnnotationArray*>* fields_type_anno = ikh()->fields_type_annotations();
+
+ // Compute the real number of Java fields
+ int java_fields = ikh()->java_fields_count();
+@@ -68,6 +69,7 @@
+ // int offset = ikh()->field_offset( index );
+ int generic_signature_index = fs.generic_signature_index();
+ AnnotationArray* anno = fields_anno == NULL ? NULL : fields_anno->at(fs.index());
++ AnnotationArray* type_anno = fields_type_anno == NULL ? NULL : fields_type_anno->at(fs.index());
+
+ // JVMSpec| field_info {
+ // JVMSpec| u2 access_flags;
+@@ -93,6 +95,9 @@
+ if (anno != NULL) {
+ ++attr_count; // has RuntimeVisibleAnnotations attribute
+ }
++ if (type_anno != NULL) {
++ ++attr_count; // has RuntimeVisibleTypeAnnotations attribute
++ }
+
+ write_u2(attr_count);
+
+@@ -110,6 +115,9 @@
+ if (anno != NULL) {
+ write_annotations_attribute("RuntimeVisibleAnnotations", anno);
+ }
++ if (type_anno != NULL) {
++ write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
++ }
+ }
+ }
+
+@@ -550,6 +558,7 @@
+ AnnotationArray* anno = method->annotations();
+ AnnotationArray* param_anno = method->parameter_annotations();
+ AnnotationArray* default_anno = method->annotation_default();
++ AnnotationArray* type_anno = method->type_annotations();
+
+ // skip generated default interface methods
+ if (method->is_overpass()) {
+@@ -585,6 +594,9 @@
+ if (param_anno != NULL) {
+ ++attr_count; // has RuntimeVisibleParameterAnnotations attribute
+ }
++ if (type_anno != NULL) {
++ ++attr_count; // has RuntimeVisibleTypeAnnotations attribute
++ }
+
+ write_u2(attr_count);
+ if (const_method->code_size() > 0) {
+@@ -609,6 +621,9 @@
+ if (param_anno != NULL) {
+ write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno);
+ }
++ if (type_anno != NULL) {
++ write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
++ }
+ }
+
+ // Write the class attributes portion of ClassFile structure
+@@ -618,6 +633,7 @@
+ u2 inner_classes_length = inner_classes_attribute_length();
+ Symbol* generic_signature = ikh()->generic_signature();
+ AnnotationArray* anno = ikh()->class_annotations();
++ AnnotationArray* type_anno = ikh()->class_type_annotations();
+
+ int attr_count = 0;
+ if (generic_signature != NULL) {
+@@ -635,6 +651,9 @@
+ if (anno != NULL) {
+ ++attr_count; // has RuntimeVisibleAnnotations attribute
+ }
++ if (type_anno != NULL) {
++ ++attr_count; // has RuntimeVisibleTypeAnnotations attribute
++ }
+ if (cpool()->operands() != NULL) {
+ ++attr_count;
+ }
+@@ -656,6 +675,9 @@
+ if (anno != NULL) {
+ write_annotations_attribute("RuntimeVisibleAnnotations", anno);
+ }
++ if (type_anno != NULL) {
++ write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
++ }
+ if (cpool()->operands() != NULL) {
+ write_bootstrapmethod_attribute();
+ }
+--- ./hotspot/src/share/vm/prims/jvmtiEnv.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/jvmtiEnv.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -23,6 +23,7 @@
+ */
+
+ #include "precompiled.hpp"
++#include "classfile/classLoaderExt.hpp"
+ #include "classfile/systemDictionary.hpp"
+ #include "classfile/vmSymbols.hpp"
+ #include "interpreter/bytecodeStream.hpp"
+@@ -475,7 +476,7 @@
+ if (TraceClassLoading) {
+ tty->print_cr("[Opened %s]", zip_entry->name());
+ }
+- ClassLoader::add_to_list(zip_entry);
++ ClassLoaderExt::append_boot_classpath(zip_entry);
+ return JVMTI_ERROR_NONE;
+ } else {
+ return JVMTI_ERROR_WRONG_PHASE;
+--- ./hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -41,6 +41,7 @@
+ #include "runtime/objectMonitor.hpp"
+ #include "runtime/objectMonitor.inline.hpp"
+ #include "runtime/signature.hpp"
++#include "runtime/thread.inline.hpp"
+ #include "runtime/vframe.hpp"
+ #include "runtime/vframe_hp.hpp"
+ #include "runtime/vmThread.hpp"
+--- ./hotspot/src/share/vm/prims/jvmtiExport.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/jvmtiExport.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -47,7 +47,7 @@
+ #include "runtime/interfaceSupport.hpp"
+ #include "runtime/objectMonitor.hpp"
+ #include "runtime/objectMonitor.inline.hpp"
+-#include "runtime/thread.hpp"
++#include "runtime/thread.inline.hpp"
+ #include "runtime/vframe.hpp"
+ #include "services/attachListener.hpp"
+ #include "services/serviceUtil.hpp"
+--- ./hotspot/src/share/vm/prims/jvmtiRawMonitor.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/jvmtiRawMonitor.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,7 +25,8 @@
+ #include "precompiled.hpp"
+ #include "prims/jvmtiRawMonitor.hpp"
+ #include "runtime/interfaceSupport.hpp"
+-#include "runtime/thread.hpp"
++#include "runtime/orderAccess.inline.hpp"
++#include "runtime/thread.inline.hpp"
+
+ GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiRawMonitor*>(1,true);
+
+--- ./hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -135,7 +135,7 @@
+
+ // Mark methods seen on stack and everywhere else so old methods are not
+ // cleaned up if they're on the stack.
+- MetadataOnStackMark md_on_stack;
++ MetadataOnStackMark md_on_stack(true);
+ HandleMark hm(thread); // make sure any handles created are deleted
+ // before the stack walk again.
+
+@@ -1569,6 +1569,29 @@
+ return false;
+ }
+
++ // rewrite constant pool references in the class_type_annotations:
++ if (!rewrite_cp_refs_in_class_type_annotations(scratch_class, THREAD)) {
++ // propagate failure back to caller
++ return false;
++ }
++
++ // rewrite constant pool references in the fields_type_annotations:
++ if (!rewrite_cp_refs_in_fields_type_annotations(scratch_class, THREAD)) {
++ // propagate failure back to caller
++ return false;
++ }
++
++ // rewrite constant pool references in the methods_type_annotations:
++ if (!rewrite_cp_refs_in_methods_type_annotations(scratch_class, THREAD)) {
++ // propagate failure back to caller
++ return false;
++ }
++
++ // There can be type annotations in the Code part of a method_info attribute.
++ // These annotations are not accessible, even by reflection.
++ // Currently they are not even parsed by the ClassFileParser.
++ // If runtime access is added they will also need to be rewritten.
++
+ // rewrite source file name index:
+ u2 source_file_name_idx = scratch_class->source_file_name_index();
+ if (source_file_name_idx != 0) {
+@@ -2239,6 +2262,588 @@
+ } // end rewrite_cp_refs_in_methods_default_annotations()
+
+
++// Rewrite constant pool references in a class_type_annotations field.
++bool VM_RedefineClasses::rewrite_cp_refs_in_class_type_annotations(
++ instanceKlassHandle scratch_class, TRAPS) {
++
++ AnnotationArray* class_type_annotations = scratch_class->class_type_annotations();
++ if (class_type_annotations == NULL || class_type_annotations->length() == 0) {
++ // no class_type_annotations so nothing to do
++ return true;
++ }
++
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("class_type_annotations length=%d", class_type_annotations->length()));
++
++ int byte_i = 0; // byte index into class_type_annotations
++ return rewrite_cp_refs_in_type_annotations_typeArray(class_type_annotations,
++ byte_i, "ClassFile", THREAD);
++} // end rewrite_cp_refs_in_class_type_annotations()
++
++
++// Rewrite constant pool references in a fields_type_annotations field.
++bool VM_RedefineClasses::rewrite_cp_refs_in_fields_type_annotations(
++ instanceKlassHandle scratch_class, TRAPS) {
++
++ Array<AnnotationArray*>* fields_type_annotations = scratch_class->fields_type_annotations();
++ if (fields_type_annotations == NULL || fields_type_annotations->length() == 0) {
++ // no fields_type_annotations so nothing to do
++ return true;
++ }
++
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("fields_type_annotations length=%d", fields_type_annotations->length()));
++
++ for (int i = 0; i < fields_type_annotations->length(); i++) {
++ AnnotationArray* field_type_annotations = fields_type_annotations->at(i);
++ if (field_type_annotations == NULL || field_type_annotations->length() == 0) {
++ // this field does not have any annotations so skip it
++ continue;
++ }
++
++ int byte_i = 0; // byte index into field_type_annotations
++ if (!rewrite_cp_refs_in_type_annotations_typeArray(field_type_annotations,
++ byte_i, "field_info", THREAD)) {
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("bad field_type_annotations at %d", i));
++ // propagate failure back to caller
++ return false;
++ }
++ }
++
++ return true;
++} // end rewrite_cp_refs_in_fields_type_annotations()
++
++
++// Rewrite constant pool references in a methods_type_annotations field.
++bool VM_RedefineClasses::rewrite_cp_refs_in_methods_type_annotations(
++ instanceKlassHandle scratch_class, TRAPS) {
++
++ for (int i = 0; i < scratch_class->methods()->length(); i++) {
++ Method* m = scratch_class->methods()->at(i);
++ AnnotationArray* method_type_annotations = m->constMethod()->type_annotations();
++
++ if (method_type_annotations == NULL || method_type_annotations->length() == 0) {
++ // this method does not have any annotations so skip it
++ continue;
++ }
++
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("methods type_annotations length=%d", method_type_annotations->length()));
++
++ int byte_i = 0; // byte index into method_type_annotations
++ if (!rewrite_cp_refs_in_type_annotations_typeArray(method_type_annotations,
++ byte_i, "method_info", THREAD)) {
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("bad method_type_annotations at %d", i));
++ // propagate failure back to caller
++ return false;
++ }
++ }
++
++ return true;
++} // end rewrite_cp_refs_in_methods_type_annotations()
++
++
++// Rewrite constant pool references in a type_annotations
++// field. This "structure" is adapted from the
++// RuntimeVisibleTypeAnnotations_attribute described in
++// section 4.7.20 of the Java SE 8 Edition of the VM spec:
++//
++// type_annotations_typeArray {
++// u2 num_annotations;
++// type_annotation annotations[num_annotations];
++// }
++//
++bool VM_RedefineClasses::rewrite_cp_refs_in_type_annotations_typeArray(
++ AnnotationArray* type_annotations_typeArray, int &byte_i_ref,
++ const char * location_mesg, TRAPS) {
++
++ if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
++ // not enough room for num_annotations field
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("length() is too small for num_annotations field"));
++ return false;
++ }
++
++ u2 num_annotations = Bytes::get_Java_u2((address)
++ type_annotations_typeArray->adr_at(byte_i_ref));
++ byte_i_ref += 2;
++
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("num_type_annotations=%d", num_annotations));
++
++ int calc_num_annotations = 0;
++ for (; calc_num_annotations < num_annotations; calc_num_annotations++) {
++ if (!rewrite_cp_refs_in_type_annotation_struct(type_annotations_typeArray,
++ byte_i_ref, location_mesg, THREAD)) {
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("bad type_annotation_struct at %d", calc_num_annotations));
++ // propagate failure back to caller
++ return false;
++ }
++ }
++ assert(num_annotations == calc_num_annotations, "sanity check");
++
++ if (byte_i_ref != type_annotations_typeArray->length()) {
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("read wrong amount of bytes at end of processing "
++ "type_annotations_typeArray (%d of %d bytes were read)",
++ byte_i_ref, type_annotations_typeArray->length()));
++ return false;
++ }
++
++ return true;
++} // end rewrite_cp_refs_in_type_annotations_typeArray()
++
++
++// Rewrite constant pool references in a type_annotation
++// field. This "structure" is adapted from the
++// RuntimeVisibleTypeAnnotations_attribute described in
++// section 4.7.20 of the Java SE 8 Edition of the VM spec:
++//
++// type_annotation {
++// u1 target_type;
++// union {
++// type_parameter_target;
++// supertype_target;
++// type_parameter_bound_target;
++// empty_target;
++// method_formal_parameter_target;
++// throws_target;
++// localvar_target;
++// catch_target;
++// offset_target;
++// type_argument_target;
++// } target_info;
++// type_path target_path;
++// annotation anno;
++// }
++//
++bool VM_RedefineClasses::rewrite_cp_refs_in_type_annotation_struct(
++ AnnotationArray* type_annotations_typeArray, int &byte_i_ref,
++ const char * location_mesg, TRAPS) {
++
++ if (!skip_type_annotation_target(type_annotations_typeArray,
++ byte_i_ref, location_mesg, THREAD)) {
++ return false;
++ }
++
++ if (!skip_type_annotation_type_path(type_annotations_typeArray,
++ byte_i_ref, THREAD)) {
++ return false;
++ }
++
++ if (!rewrite_cp_refs_in_annotation_struct(type_annotations_typeArray,
++ byte_i_ref, THREAD)) {
++ return false;
++ }
++
++ return true;
++} // end rewrite_cp_refs_in_type_annotation_struct()
++
++
++// Read, verify and skip over the target_type and target_info part
++// so that rewriting can continue in the later parts of the struct.
++//
++// u1 target_type;
++// union {
++// type_parameter_target;
++// supertype_target;
++// type_parameter_bound_target;
++// empty_target;
++// method_formal_parameter_target;
++// throws_target;
++// localvar_target;
++// catch_target;
++// offset_target;
++// type_argument_target;
++// } target_info;
++//
++bool VM_RedefineClasses::skip_type_annotation_target(
++ AnnotationArray* type_annotations_typeArray, int &byte_i_ref,
++ const char * location_mesg, TRAPS) {
++
++ if ((byte_i_ref + 1) > type_annotations_typeArray->length()) {
++ // not enough room for a target_type let alone the rest of a type_annotation
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("length() is too small for a target_type"));
++ return false;
++ }
++
++ u1 target_type = type_annotations_typeArray->at(byte_i_ref);
++ byte_i_ref += 1;
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("target_type=0x%.2x", target_type));
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("location=%s", location_mesg));
++
++ // Skip over target_info
++ switch (target_type) {
++ case 0x00:
++ // kind: type parameter declaration of generic class or interface
++ // location: ClassFile
++ case 0x01:
++ // kind: type parameter declaration of generic method or constructor
++ // location: method_info
++
++ {
++ // struct:
++ // type_parameter_target {
++ // u1 type_parameter_index;
++ // }
++ //
++ if ((byte_i_ref + 1) > type_annotations_typeArray->length()) {
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("length() is too small for a type_parameter_target"));
++ return false;
++ }
++
++ u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref);
++ byte_i_ref += 1;
++
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("type_parameter_target: type_parameter_index=%d",
++ type_parameter_index));
++ } break;
++
++ case 0x10:
++ // kind: type in extends clause of class or interface declaration
++ // (including the direct superclass of an anonymous class declaration),
++ // or in implements clause of interface declaration
++ // location: ClassFile
++
++ {
++ // struct:
++ // supertype_target {
++ // u2 supertype_index;
++ // }
++ //
++ if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("length() is too small for a supertype_target"));
++ return false;
++ }
++
++ u2 supertype_index = Bytes::get_Java_u2((address)
++ type_annotations_typeArray->adr_at(byte_i_ref));
++ byte_i_ref += 2;
++
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("supertype_target: supertype_index=%d", supertype_index));
++ } break;
++
++ case 0x11:
++ // kind: type in bound of type parameter declaration of generic class or interface
++ // location: ClassFile
++ case 0x12:
++ // kind: type in bound of type parameter declaration of generic method or constructor
++ // location: method_info
++
++ {
++ // struct:
++ // type_parameter_bound_target {
++ // u1 type_parameter_index;
++ // u1 bound_index;
++ // }
++ //
++ if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("length() is too small for a type_parameter_bound_target"));
++ return false;
++ }
++
++ u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref);
++ byte_i_ref += 1;
++ u1 bound_index = type_annotations_typeArray->at(byte_i_ref);
++ byte_i_ref += 1;
++
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("type_parameter_bound_target: type_parameter_index=%d, bound_index=%d",
++ type_parameter_index, bound_index));
++ } break;
++
++ case 0x13:
++ // kind: type in field declaration
++ // location: field_info
++ case 0x14:
++ // kind: return type of method, or type of newly constructed object
++ // location: method_info
++ case 0x15:
++ // kind: receiver type of method or constructor
++ // location: method_info
++
++ {
++ // struct:
++ // empty_target {
++ // }
++ //
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("empty_target"));
++ } break;
++
++ case 0x16:
++ // kind: type in formal parameter declaration of method, constructor, or lambda expression
++ // location: method_info
++
++ {
++ // struct:
++ // formal_parameter_target {
++ // u1 formal_parameter_index;
++ // }
++ //
++ if ((byte_i_ref + 1) > type_annotations_typeArray->length()) {
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("length() is too small for a formal_parameter_target"));
++ return false;
++ }
++
++ u1 formal_parameter_index = type_annotations_typeArray->at(byte_i_ref);
++ byte_i_ref += 1;
++
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("formal_parameter_target: formal_parameter_index=%d",
++ formal_parameter_index));
++ } break;
++
++ case 0x17:
++ // kind: type in throws clause of method or constructor
++ // location: method_info
++
++ {
++ // struct:
++ // throws_target {
++ // u2 throws_type_index
++ // }
++ //
++ if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("length() is too small for a throws_target"));
++ return false;
++ }
++
++ u2 throws_type_index = Bytes::get_Java_u2((address)
++ type_annotations_typeArray->adr_at(byte_i_ref));
++ byte_i_ref += 2;
++
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("throws_target: throws_type_index=%d", throws_type_index));
++ } break;
++
++ case 0x40:
++ // kind: type in local variable declaration
++ // location: Code
++ case 0x41:
++ // kind: type in resource variable declaration
++ // location: Code
++
++ {
++ // struct:
++ // localvar_target {
++ // u2 table_length;
++ // struct {
++ // u2 start_pc;
++ // u2 length;
++ // u2 index;
++ // } table[table_length];
++ // }
++ //
++ if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
++ // not enough room for a table_length let alone the rest of a localvar_target
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("length() is too small for a localvar_target table_length"));
++ return false;
++ }
++
++ u2 table_length = Bytes::get_Java_u2((address)
++ type_annotations_typeArray->adr_at(byte_i_ref));
++ byte_i_ref += 2;
++
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("localvar_target: table_length=%d", table_length));
++
++ int table_struct_size = 2 + 2 + 2; // 3 u2 variables per table entry
++ int table_size = table_length * table_struct_size;
++
++ if ((byte_i_ref + table_size) > type_annotations_typeArray->length()) {
++ // not enough room for a table
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("length() is too small for a table array of length %d", table_length));
++ return false;
++ }
++
++ // Skip over table
++ byte_i_ref += table_size;
++ } break;
++
++ case 0x42:
++ // kind: type in exception parameter declaration
++ // location: Code
++
++ {
++ // struct:
++ // catch_target {
++ // u2 exception_table_index;
++ // }
++ //
++ if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("length() is too small for a catch_target"));
++ return false;
++ }
++
++ u2 exception_table_index = Bytes::get_Java_u2((address)
++ type_annotations_typeArray->adr_at(byte_i_ref));
++ byte_i_ref += 2;
++
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("catch_target: exception_table_index=%d", exception_table_index));
++ } break;
++
++ case 0x43:
++ // kind: type in instanceof expression
++ // location: Code
++ case 0x44:
++ // kind: type in new expression
++ // location: Code
++ case 0x45:
++ // kind: type in method reference expression using ::new
++ // location: Code
++ case 0x46:
++ // kind: type in method reference expression using ::Identifier
++ // location: Code
++
++ {
++ // struct:
++ // offset_target {
++ // u2 offset;
++ // }
++ //
++ if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("length() is too small for a offset_target"));
++ return false;
++ }
++
++ u2 offset = Bytes::get_Java_u2((address)
++ type_annotations_typeArray->adr_at(byte_i_ref));
++ byte_i_ref += 2;
++
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("offset_target: offset=%d", offset));
++ } break;
++
++ case 0x47:
++ // kind: type in cast expression
++ // location: Code
++ case 0x48:
++ // kind: type argument for generic constructor in new expression or
++ // explicit constructor invocation statement
++ // location: Code
++ case 0x49:
++ // kind: type argument for generic method in method invocation expression
++ // location: Code
++ case 0x4A:
++ // kind: type argument for generic constructor in method reference expression using ::new
++ // location: Code
++ case 0x4B:
++ // kind: type argument for generic method in method reference expression using ::Identifier
++ // location: Code
++
++ {
++ // struct:
++ // type_argument_target {
++ // u2 offset;
++ // u1 type_argument_index;
++ // }
++ //
++ if ((byte_i_ref + 3) > type_annotations_typeArray->length()) {
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("length() is too small for a type_argument_target"));
++ return false;
++ }
++
++ u2 offset = Bytes::get_Java_u2((address)
++ type_annotations_typeArray->adr_at(byte_i_ref));
++ byte_i_ref += 2;
++ u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref);
++ byte_i_ref += 1;
++
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("type_argument_target: offset=%d, type_argument_index=%d",
++ offset, type_argument_index));
++ } break;
++
++ default:
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("unknown target_type"));
++#ifdef ASSERT
++ ShouldNotReachHere();
++#endif
++ return false;
++ }
++
++ return true;
++} // end skip_type_annotation_target()
++
++
++// Read, verify and skip over the type_path part so that rewriting
++// can continue in the later parts of the struct.
++//
++// type_path {
++// u1 path_length;
++// {
++// u1 type_path_kind;
++// u1 type_argument_index;
++// } path[path_length];
++// }
++//
++bool VM_RedefineClasses::skip_type_annotation_type_path(
++ AnnotationArray* type_annotations_typeArray, int &byte_i_ref, TRAPS) {
++
++ if ((byte_i_ref + 1) > type_annotations_typeArray->length()) {
++ // not enough room for a path_length let alone the rest of the type_path
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("length() is too small for a type_path"));
++ return false;
++ }
++
++ u1 path_length = type_annotations_typeArray->at(byte_i_ref);
++ byte_i_ref += 1;
++
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("type_path: path_length=%d", path_length));
++
++ int calc_path_length = 0;
++ for (; calc_path_length < path_length; calc_path_length++) {
++ if ((byte_i_ref + 1 + 1) > type_annotations_typeArray->length()) {
++ // not enough room for a path
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("length() is too small for path entry %d of %d",
++ calc_path_length, path_length));
++ return false;
++ }
++
++ u1 type_path_kind = type_annotations_typeArray->at(byte_i_ref);
++ byte_i_ref += 1;
++ u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref);
++ byte_i_ref += 1;
++
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("type_path: path[%d]: type_path_kind=%d, type_argument_index=%d",
++ calc_path_length, type_path_kind, type_argument_index));
++
++ if (type_path_kind > 3 || (type_path_kind != 3 && type_argument_index != 0)) {
++ // not enough room for a path
++ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
++ ("inconsistent type_path values"));
++ return false;
++ }
++ }
++ assert(path_length == calc_path_length, "sanity check");
++
++ return true;
++} // end skip_type_annotation_type_path()
++
++
+ // Rewrite constant pool references in the method's stackmap table.
+ // These "structures" are adapted from the StackMapTable_attribute that
+ // is described in section 4.8.4 of the 6.0 version of the VM spec
+@@ -3223,23 +3828,6 @@
+
+ void VM_RedefineClasses::swap_annotations(instanceKlassHandle the_class,
+ instanceKlassHandle scratch_class) {
+- // Since there is currently no rewriting of type annotations indexes
+- // into the CP, we null out type annotations on scratch_class before
+- // we swap annotations with the_class rather than facing the
+- // possibility of shipping annotations with broken indexes to
+- // Java-land.
+- ClassLoaderData* loader_data = scratch_class->class_loader_data();
+- AnnotationArray* new_class_type_annotations = scratch_class->class_type_annotations();
+- if (new_class_type_annotations != NULL) {
+- MetadataFactory::free_array<u1>(loader_data, new_class_type_annotations);
+- scratch_class->annotations()->set_class_type_annotations(NULL);
+- }
+- Array<AnnotationArray*>* new_field_type_annotations = scratch_class->fields_type_annotations();
+- if (new_field_type_annotations != NULL) {
+- Annotations::free_contents(loader_data, new_field_type_annotations);
+- scratch_class->annotations()->set_fields_type_annotations(NULL);
+- }
+-
+ // Swap annotation fields values
+ Annotations* old_annotations = the_class->annotations();
+ the_class->set_annotations(scratch_class->annotations());
+--- ./hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -457,6 +457,17 @@
+ instanceKlassHandle scratch_class, TRAPS);
+ bool rewrite_cp_refs_in_element_value(
+ AnnotationArray* class_annotations, int &byte_i_ref, TRAPS);
++ bool rewrite_cp_refs_in_type_annotations_typeArray(
++ AnnotationArray* type_annotations_typeArray, int &byte_i_ref,
++ const char * location_mesg, TRAPS);
++ bool rewrite_cp_refs_in_type_annotation_struct(
++ AnnotationArray* type_annotations_typeArray, int &byte_i_ref,
++ const char * location_mesg, TRAPS);
++ bool skip_type_annotation_target(
++ AnnotationArray* type_annotations_typeArray, int &byte_i_ref,
++ const char * location_mesg, TRAPS);
++ bool skip_type_annotation_type_path(
++ AnnotationArray* type_annotations_typeArray, int &byte_i_ref, TRAPS);
+ bool rewrite_cp_refs_in_fields_annotations(
+ instanceKlassHandle scratch_class, TRAPS);
+ void rewrite_cp_refs_in_method(methodHandle method,
+@@ -468,6 +479,12 @@
+ instanceKlassHandle scratch_class, TRAPS);
+ bool rewrite_cp_refs_in_methods_parameter_annotations(
+ instanceKlassHandle scratch_class, TRAPS);
++ bool rewrite_cp_refs_in_class_type_annotations(
++ instanceKlassHandle scratch_class, TRAPS);
++ bool rewrite_cp_refs_in_fields_type_annotations(
++ instanceKlassHandle scratch_class, TRAPS);
++ bool rewrite_cp_refs_in_methods_type_annotations(
++ instanceKlassHandle scratch_class, TRAPS);
+ void rewrite_cp_refs_in_stack_map_table(methodHandle method, TRAPS);
+ void rewrite_cp_refs_in_verification_type_info(
+ address& stackmap_addr_ref, address stackmap_end, u2 frame_i,
+--- ./hotspot/src/share/vm/prims/jvmtiTagMap.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/jvmtiTagMap.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -3017,7 +3017,7 @@
+
+ // If there are any non-perm roots in the code cache, visit them.
+ blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
+- CodeBlobToOopClosure look_in_blobs(&blk, false);
++ CodeBlobToOopClosure look_in_blobs(&blk, !CodeBlobToOopClosure::FixRelocations);
+ CodeCache::scavenge_root_nmethods_do(&look_in_blobs);
+
+ return true;
+--- ./hotspot/src/share/vm/prims/jvmtiThreadState.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/jvmtiThreadState.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -27,6 +27,7 @@
+
+ #include "prims/jvmtiEnvThreadState.hpp"
+ #include "prims/jvmtiThreadState.hpp"
++#include "runtime/thread.inline.hpp"
+
+ // JvmtiEnvThreadStateIterator implementation
+
+--- ./hotspot/src/share/vm/prims/methodHandles.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/methodHandles.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -29,7 +29,6 @@
+ #include "interpreter/oopMapCache.hpp"
+ #include "memory/allocation.inline.hpp"
+ #include "memory/oopFactory.hpp"
+-#include "prims/jvmtiRedefineClassesTrace.hpp"
+ #include "prims/methodHandles.hpp"
+ #include "runtime/compilationPolicy.hpp"
+ #include "runtime/javaCalls.hpp"
+@@ -271,9 +270,12 @@
+ // This is done eagerly, since it is readily available without
+ // constructing any new objects.
+ // TO DO: maybe intern mname_oop
+- m->method_holder()->add_member_name(m->method_idnum(), mname);
+-
+- return mname();
++ if (m->method_holder()->add_member_name(mname)) {
++ return mname();
++ } else {
++ // Redefinition caused this to fail. Return NULL (and an exception?)
++ return NULL;
++ }
+ }
+
+ oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) {
+@@ -946,63 +948,27 @@
+ }
+ }
+
+-void MemberNameTable::add_member_name(int index, jweak mem_name_wref) {
++void MemberNameTable::add_member_name(jweak mem_name_wref) {
+ assert_locked_or_safepoint(MemberNameTable_lock);
+- this->at_put_grow(index, mem_name_wref);
+-}
+-
+-// Return a member name oop or NULL.
+-oop MemberNameTable::get_member_name(int index) {
+- assert_locked_or_safepoint(MemberNameTable_lock);
+-
+- jweak ref = this->at(index);
+- oop mem_name = JNIHandles::resolve(ref);
+- return mem_name;
++ this->push(mem_name_wref);
+ }
+
+ #if INCLUDE_JVMTI
+-oop MemberNameTable::find_member_name_by_method(Method* old_method) {
+- assert_locked_or_safepoint(MemberNameTable_lock);
+- oop found = NULL;
+- int len = this->length();
+-
+- for (int idx = 0; idx < len; idx++) {
+- oop mem_name = JNIHandles::resolve(this->at(idx));
+- if (mem_name == NULL) {
+- continue;
+- }
+- Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mem_name);
+- if (method == old_method) {
+- found = mem_name;
+- break;
+- }
+- }
+- return found;
+-}
+-
+-// It is called at safepoint only
++// It is called at safepoint only for RedefineClasses
+ void MemberNameTable::adjust_method_entries(Method** old_methods, Method** new_methods,
+ int methods_length, bool *trace_name_printed) {
+ assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
+- // search the MemberNameTable for uses of either obsolete or EMCP methods
++ // For each redefined method
+ for (int j = 0; j < methods_length; j++) {
+ Method* old_method = old_methods[j];
+ Method* new_method = new_methods[j];
+- oop mem_name = find_member_name_by_method(old_method);
+- if (mem_name != NULL) {
+- java_lang_invoke_MemberName::adjust_vmtarget(mem_name, new_method);
+
+- if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
+- if (!(*trace_name_printed)) {
+- // RC_TRACE_MESG macro has an embedded ResourceMark
+- RC_TRACE_MESG(("adjust: name=%s",
+- old_method->method_holder()->external_name()));
+- *trace_name_printed = true;
+- }
+- // RC_TRACE macro has an embedded ResourceMark
+- RC_TRACE(0x00400000, ("MemberName method update: %s(%s)",
+- new_method->name()->as_C_string(),
+- new_method->signature()->as_C_string()));
++ // search the MemberNameTable for uses of either obsolete or EMCP methods
++ for (int idx = 0; idx < length(); idx++) {
++ oop mem_name = JNIHandles::resolve(this->at(idx));
++ if (mem_name != NULL) {
++ java_lang_invoke_MemberName::adjust_vmtarget(mem_name, old_method, new_method,
++ trace_name_printed);
+ }
+ }
+ }
+--- ./hotspot/src/share/vm/prims/methodHandles.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/methodHandles.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -236,18 +236,14 @@
+ public:
+ MemberNameTable(int methods_cnt);
+ ~MemberNameTable();
+- void add_member_name(int index, jweak mem_name_ref);
+- oop get_member_name(int index);
++ void add_member_name(jweak mem_name_ref);
+
+ #if INCLUDE_JVMTI
+- public:
+ // RedefineClasses() API support:
+ // If a MemberName refers to old_method then update it
+ // to refer to new_method.
+ void adjust_method_entries(Method** old_methods, Method** new_methods,
+ int methods_length, bool *trace_name_printed);
+- private:
+- oop find_member_name_by_method(Method* old_method);
+ #endif // INCLUDE_JVMTI
+ };
+
+--- ./hotspot/src/share/vm/prims/unsafe.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/unsafe.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -33,6 +33,8 @@
+ #include "prims/jvm.h"
+ #include "runtime/globals.hpp"
+ #include "runtime/interfaceSupport.hpp"
++#include "runtime/prefetch.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/reflection.hpp"
+ #include "runtime/synchronizer.hpp"
+ #include "services/threadService.hpp"
+@@ -951,6 +953,14 @@
+ }
+ UNSAFE_END
+
++static jobject get_class_loader(JNIEnv* env, jclass cls) {
++ if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {
++ return NULL;
++ }
++ Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
++ oop loader = k->class_loader();
++ return JNIHandles::make_local(env, loader);
++}
+
+ UNSAFE_ENTRY(jclass, Unsafe_DefineClass0(JNIEnv *env, jobject unsafe, jstring name, jbyteArray data, int offset, int length))
+ UnsafeWrapper("Unsafe_DefineClass");
+@@ -959,7 +969,7 @@
+
+ int depthFromDefineClass0 = 1;
+ jclass caller = JVM_GetCallerClass(env, depthFromDefineClass0);
+- jobject loader = (caller == NULL) ? NULL : JVM_GetClassLoader(env, caller);
++ jobject loader = (caller == NULL) ? NULL : get_class_loader(env, caller);
+ jobject pd = (caller == NULL) ? NULL : JVM_GetProtectionDomain(env, caller);
+
+ return Unsafe_DefineClass_impl(env, name, data, offset, length, loader, pd);
+--- ./hotspot/src/share/vm/prims/whitebox.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/whitebox.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -24,6 +24,7 @@
+
+ #include "precompiled.hpp"
+
++#include "memory/metadataFactory.hpp"
+ #include "memory/universe.hpp"
+ #include "oops/oop.inline.hpp"
+
+@@ -36,21 +37,26 @@
+ #include "runtime/arguments.hpp"
+ #include "runtime/interfaceSupport.hpp"
+ #include "runtime/os.hpp"
++#include "utilities/array.hpp"
+ #include "utilities/debug.hpp"
+ #include "utilities/macros.hpp"
+ #include "utilities/exceptions.hpp"
+
+ #if INCLUDE_ALL_GCS
++#include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
+ #include "gc_implementation/g1/concurrentMark.hpp"
+ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+ #include "gc_implementation/g1/heapRegionRemSet.hpp"
+ #endif // INCLUDE_ALL_GCS
+
+-#ifdef INCLUDE_NMT
++#if INCLUDE_NMT
++#include "services/mallocSiteTable.hpp"
+ #include "services/memTracker.hpp"
++#include "utilities/nativeCallStack.hpp"
+ #endif // INCLUDE_NMT
+
+ #include "compiler/compileBroker.hpp"
++#include "jvmtifiles/jvmtiEnv.hpp"
+ #include "runtime/compilationPolicy.hpp"
+
+ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+@@ -99,6 +105,51 @@
+ return closure.found();
+ WB_END
+
++WB_ENTRY(jboolean, WB_ClassKnownToNotExist(JNIEnv* env, jobject o, jobject loader, jstring name))
++ ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
++ const char* class_name = env->GetStringUTFChars(name, NULL);
++ jboolean result = JVM_KnownToNotExist(env, loader, class_name);
++ env->ReleaseStringUTFChars(name, class_name);
++ return result;
++WB_END
++
++WB_ENTRY(jobjectArray, WB_GetLookupCacheURLs(JNIEnv* env, jobject o, jobject loader))
++ ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
++ return JVM_GetResourceLookupCacheURLs(env, loader);
++WB_END
++
++WB_ENTRY(jintArray, WB_GetLookupCacheMatches(JNIEnv* env, jobject o, jobject loader, jstring name))
++ ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
++ const char* resource_name = env->GetStringUTFChars(name, NULL);
++ jintArray result = JVM_GetResourceLookupCache(env, loader, resource_name);
++
++ env->ReleaseStringUTFChars(name, resource_name);
++ return result;
++WB_END
++
++WB_ENTRY(void, WB_AddToBootstrapClassLoaderSearch(JNIEnv* env, jobject o, jstring segment)) {
++#if INCLUDE_JVMTI
++ ResourceMark rm;
++ const char* seg = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(segment));
++ JvmtiEnv* jvmti_env = JvmtiEnv::create_a_jvmti(JVMTI_VERSION);
++ jvmtiError err = jvmti_env->AddToBootstrapClassLoaderSearch(seg);
++ assert(err == JVMTI_ERROR_NONE, "must not fail");
++#endif
++}
++WB_END
++
++WB_ENTRY(void, WB_AddToSystemClassLoaderSearch(JNIEnv* env, jobject o, jstring segment)) {
++#if INCLUDE_JVMTI
++ ResourceMark rm;
++ const char* seg = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(segment));
++ JvmtiEnv* jvmti_env = JvmtiEnv::create_a_jvmti(JVMTI_VERSION);
++ jvmtiError err = jvmti_env->AddToSystemClassLoaderSearch(seg);
++ assert(err == JVMTI_ERROR_NONE, "must not fail");
++#endif
++}
++WB_END
++
++
+ WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) {
+ return (jlong)Arguments::max_heap_for_compressed_oops();
+ }
+@@ -219,6 +270,30 @@
+ (size_t) magnitude, (size_t) iterations);
+ WB_END
+
++WB_ENTRY(jboolean, WB_isObjectInOldGen(JNIEnv* env, jobject o, jobject obj))
++ oop p = JNIHandles::resolve(obj);
++#if INCLUDE_ALL_GCS
++ if (UseG1GC) {
++ G1CollectedHeap* g1 = G1CollectedHeap::heap();
++ const HeapRegion* hr = g1->heap_region_containing(p);
++ if (hr == NULL) {
++ return false;
++ }
++ return !(hr->is_young());
++ } else if (UseParallelGC) {
++ ParallelScavengeHeap* psh = ParallelScavengeHeap::heap();
++ return !psh->is_in_young(p);
++ }
++#endif // INCLUDE_ALL_GCS
++ GenCollectedHeap* gch = GenCollectedHeap::heap();
++ return !gch->is_in_young(p);
++WB_END
++
++WB_ENTRY(jlong, WB_GetObjectSize(JNIEnv* env, jobject o, jobject obj))
++ oop p = JNIHandles::resolve(obj);
++ return p->size() * HeapWordSize;
++WB_END
++
+ #if INCLUDE_ALL_GCS
+ WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj))
+ G1CollectedHeap* g1 = G1CollectedHeap::heap();
+@@ -229,7 +304,7 @@
+
+ WB_ENTRY(jlong, WB_G1NumFreeRegions(JNIEnv* env, jobject o))
+ G1CollectedHeap* g1 = G1CollectedHeap::heap();
+- size_t nr = g1->free_regions();
++ size_t nr = g1->num_free_regions();
+ return (jlong)nr;
+ WB_END
+
+@@ -249,12 +324,16 @@
+ // NMT picks it up correctly
+ WB_ENTRY(jlong, WB_NMTMalloc(JNIEnv* env, jobject o, jlong size))
+ jlong addr = 0;
++ addr = (jlong)(uintptr_t)os::malloc(size, mtTest);
++ return addr;
++WB_END
+
+- if (MemTracker::is_on() && !MemTracker::shutdown_in_progress()) {
+- addr = (jlong)(uintptr_t)os::malloc(size, mtTest);
+- }
+-
+- return addr;
++// Alloc memory with pseudo call stack. The test can create psudo malloc
++// allocation site to stress the malloc tracking.
++WB_ENTRY(jlong, WB_NMTMallocWithPseudoStack(JNIEnv* env, jobject o, jlong size, jint pseudo_stack))
++ address pc = (address)(size_t)pseudo_stack;
++ NativeCallStack stack(&pc, 1);
++ return (jlong)(uintptr_t)os::malloc(size, mtTest, stack);
+ WB_END
+
+ // Free the memory allocated by NMTAllocTest
+@@ -265,10 +344,8 @@
+ WB_ENTRY(jlong, WB_NMTReserveMemory(JNIEnv* env, jobject o, jlong size))
+ jlong addr = 0;
+
+- if (MemTracker::is_on() && !MemTracker::shutdown_in_progress()) {
+ addr = (jlong)(uintptr_t)os::reserve_memory(size);
+ MemTracker::record_virtual_memory_type((address)addr, mtTest);
+- }
+
+ return addr;
+ WB_END
+@@ -287,20 +364,46 @@
+ os::release_memory((char *)(uintptr_t)addr, size);
+ WB_END
+
+-// Block until the current generation of NMT data to be merged, used to reliably test the NMT feature
+-WB_ENTRY(jboolean, WB_NMTWaitForDataMerge(JNIEnv* env))
+-
+- if (!MemTracker::is_on() || MemTracker::shutdown_in_progress()) {
+- return false;
+- }
+-
+- return MemTracker::wbtest_wait_for_data_merge();
++WB_ENTRY(jboolean, WB_NMTIsDetailSupported(JNIEnv* env))
++ return MemTracker::tracking_level() == NMT_detail;
+ WB_END
+
+-WB_ENTRY(jboolean, WB_NMTIsDetailSupported(JNIEnv* env))
+- return MemTracker::tracking_level() == MemTracker::NMT_detail;
++WB_ENTRY(jboolean, WB_NMTChangeTrackingLevel(JNIEnv* env))
++ // Test that we can downgrade NMT levels but not upgrade them.
++ if (MemTracker::tracking_level() == NMT_off) {
++ MemTracker::transition_to(NMT_off);
++ return MemTracker::tracking_level() == NMT_off;
++ } else {
++ assert(MemTracker::tracking_level() == NMT_detail, "Should start out as detail tracking");
++ MemTracker::transition_to(NMT_summary);
++ assert(MemTracker::tracking_level() == NMT_summary, "Should be summary now");
++
++ // Can't go to detail once NMT is set to summary.
++ MemTracker::transition_to(NMT_detail);
++ assert(MemTracker::tracking_level() == NMT_summary, "Should still be summary now");
++
++ // Shutdown sets tracking level to minimal.
++ MemTracker::shutdown();
++ assert(MemTracker::tracking_level() == NMT_minimal, "Should be minimal now");
++
++ // Once the tracking level is minimal, we cannot increase to summary.
++ // The code ignores this request instead of asserting because if the malloc site
++ // table overflows in another thread, it tries to change the code to summary.
++ MemTracker::transition_to(NMT_summary);
++ assert(MemTracker::tracking_level() == NMT_minimal, "Should still be minimal now");
++
++ // Really can never go up to detail, verify that the code would never do this.
++ MemTracker::transition_to(NMT_detail);
++ assert(MemTracker::tracking_level() == NMT_minimal, "Should still be minimal now");
++ return MemTracker::tracking_level() == NMT_minimal;
++ }
+ WB_END
+
++WB_ENTRY(jint, WB_NMTGetHashSize(JNIEnv* env, jobject o))
++ int hash_size = MallocSiteTable::hash_buckets();
++ assert(hash_size > 0, "NMT hash_size should be > 0");
++ return (jint)hash_size;
++WB_END
+ #endif // INCLUDE_NMT
+
+ static jmethodID reflected_method_to_jmid(JavaThread* thread, JNIEnv* env, jobject method) {
+@@ -322,19 +425,10 @@
+ CHECK_JNI_EXCEPTION_(env, result);
+ MutexLockerEx mu(Compile_lock);
+ methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
+- nmethod* code;
+ if (is_osr) {
+- int bci = InvocationEntryBci;
+- while ((code = mh->lookup_osr_nmethod_for(bci, CompLevel_none, false)) != NULL) {
+- code->mark_for_deoptimization();
+- ++result;
+- bci = code->osr_entry_bci() + 1;
+- }
+- } else {
+- code = mh->code();
+- }
+- if (code != NULL) {
+- code->mark_for_deoptimization();
++ result += mh->mark_osr_nmethods();
++ } else if (mh->code() != NULL) {
++ mh->code()->mark_for_deoptimization();
+ ++result;
+ }
+ result += CodeCache::mark_for_deoptimization(mh());
+@@ -495,12 +589,165 @@
+
+ #ifdef TIERED
+ mcs->set_rate(0.0F);
+- mh->set_prev_event_count(0, THREAD);
+- mh->set_prev_time(0, THREAD);
++ mh->set_prev_event_count(0);
++ mh->set_prev_time(0);
+ #endif
+ }
+ WB_END
+
++template <typename T>
++static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAt)(const char*, T*)) {
++ if (name == NULL) {
++ return false;
++ }
++ ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
++ const char* flag_name = env->GetStringUTFChars(name, NULL);
++ bool result = (*TAt)(flag_name, value);
++ env->ReleaseStringUTFChars(name, flag_name);
++ return result;
++}
++
++template <typename T>
++static bool SetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAtPut)(const char*, T*, Flag::Flags)) {
++ if (name == NULL) {
++ return false;
++ }
++ ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
++ const char* flag_name = env->GetStringUTFChars(name, NULL);
++ bool result = (*TAtPut)(flag_name, value, Flag::INTERNAL);
++ env->ReleaseStringUTFChars(name, flag_name);
++ return result;
++}
++
++template <typename T>
++static jobject box(JavaThread* thread, JNIEnv* env, Symbol* name, Symbol* sig, T value) {
++ ResourceMark rm(thread);
++ jclass clazz = env->FindClass(name->as_C_string());
++ CHECK_JNI_EXCEPTION_(env, NULL);
++ jmethodID methodID = env->GetStaticMethodID(clazz,
++ vmSymbols::valueOf_name()->as_C_string(),
++ sig->as_C_string());
++ CHECK_JNI_EXCEPTION_(env, NULL);
++ jobject result = env->CallStaticObjectMethod(clazz, methodID, value);
++ CHECK_JNI_EXCEPTION_(env, NULL);
++ return result;
++}
++
++static jobject booleanBox(JavaThread* thread, JNIEnv* env, jboolean value) {
++ return box(thread, env, vmSymbols::java_lang_Boolean(), vmSymbols::Boolean_valueOf_signature(), value);
++}
++static jobject integerBox(JavaThread* thread, JNIEnv* env, jint value) {
++ return box(thread, env, vmSymbols::java_lang_Integer(), vmSymbols::Integer_valueOf_signature(), value);
++}
++static jobject longBox(JavaThread* thread, JNIEnv* env, jlong value) {
++ return box(thread, env, vmSymbols::java_lang_Long(), vmSymbols::Long_valueOf_signature(), value);
++}
++/* static jobject floatBox(JavaThread* thread, JNIEnv* env, jfloat value) {
++ return box(thread, env, vmSymbols::java_lang_Float(), vmSymbols::Float_valueOf_signature(), value);
++}*/
++static jobject doubleBox(JavaThread* thread, JNIEnv* env, jdouble value) {
++ return box(thread, env, vmSymbols::java_lang_Double(), vmSymbols::Double_valueOf_signature(), value);
++}
++
++WB_ENTRY(jobject, WB_GetBooleanVMFlag(JNIEnv* env, jobject o, jstring name))
++ bool result;
++ if (GetVMFlag <bool> (thread, env, name, &result, &CommandLineFlags::boolAt)) {
++ ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
++ return booleanBox(thread, env, result);
++ }
++ return NULL;
++WB_END
++
++WB_ENTRY(jobject, WB_GetIntxVMFlag(JNIEnv* env, jobject o, jstring name))
++ intx result;
++ if (GetVMFlag <intx> (thread, env, name, &result, &CommandLineFlags::intxAt)) {
++ ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
++ return longBox(thread, env, result);
++ }
++ return NULL;
++WB_END
++
++WB_ENTRY(jobject, WB_GetUintxVMFlag(JNIEnv* env, jobject o, jstring name))
++ uintx result;
++ if (GetVMFlag <uintx> (thread, env, name, &result, &CommandLineFlags::uintxAt)) {
++ ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
++ return longBox(thread, env, result);
++ }
++ return NULL;
++WB_END
++
++WB_ENTRY(jobject, WB_GetUint64VMFlag(JNIEnv* env, jobject o, jstring name))
++ uint64_t result;
++ if (GetVMFlag <uint64_t> (thread, env, name, &result, &CommandLineFlags::uint64_tAt)) {
++ ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
++ return longBox(thread, env, result);
++ }
++ return NULL;
++WB_END
++
++WB_ENTRY(jobject, WB_GetDoubleVMFlag(JNIEnv* env, jobject o, jstring name))
++ double result;
++ if (GetVMFlag <double> (thread, env, name, &result, &CommandLineFlags::doubleAt)) {
++ ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
++ return doubleBox(thread, env, result);
++ }
++ return NULL;
++WB_END
++
++WB_ENTRY(jstring, WB_GetStringVMFlag(JNIEnv* env, jobject o, jstring name))
++ ccstr ccstrResult;
++ if (GetVMFlag <ccstr> (thread, env, name, &ccstrResult, &CommandLineFlags::ccstrAt)) {
++ ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
++ jstring result = env->NewStringUTF(ccstrResult);
++ CHECK_JNI_EXCEPTION_(env, NULL);
++ return result;
++ }
++ return NULL;
++WB_END
++
++WB_ENTRY(void, WB_SetBooleanVMFlag(JNIEnv* env, jobject o, jstring name, jboolean value))
++ bool result = value == JNI_TRUE ? true : false;
++ SetVMFlag <bool> (thread, env, name, &result, &CommandLineFlags::boolAtPut);
++WB_END
++
++WB_ENTRY(void, WB_SetIntxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
++ intx result = value;
++ SetVMFlag <intx> (thread, env, name, &result, &CommandLineFlags::intxAtPut);
++WB_END
++
++WB_ENTRY(void, WB_SetUintxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
++ uintx result = value;
++ SetVMFlag <uintx> (thread, env, name, &result, &CommandLineFlags::uintxAtPut);
++WB_END
++
++WB_ENTRY(void, WB_SetUint64VMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
++ uint64_t result = value;
++ SetVMFlag <uint64_t> (thread, env, name, &result, &CommandLineFlags::uint64_tAtPut);
++WB_END
++
++WB_ENTRY(void, WB_SetDoubleVMFlag(JNIEnv* env, jobject o, jstring name, jdouble value))
++ double result = value;
++ SetVMFlag <double> (thread, env, name, &result, &CommandLineFlags::doubleAtPut);
++WB_END
++
++WB_ENTRY(void, WB_SetStringVMFlag(JNIEnv* env, jobject o, jstring name, jstring value))
++ ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
++ const char* ccstrValue = (value == NULL) ? NULL : env->GetStringUTFChars(value, NULL);
++ ccstr ccstrResult = ccstrValue;
++ bool needFree;
++ {
++ ThreadInVMfromNative ttvfn(thread); // back to VM
++ needFree = SetVMFlag <ccstr> (thread, env, name, &ccstrResult, &CommandLineFlags::ccstrAtPut);
++ }
++ if (value != NULL) {
++ env->ReleaseStringUTFChars(value, ccstrValue);
++ }
++ if (needFree) {
++ FREE_C_HEAP_ARRAY(char, ccstrResult, mtInternal);
++ }
++WB_END
++
++
+ WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString))
+ ResourceMark rm(THREAD);
+ int len;
+@@ -511,8 +758,17 @@
+ WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o))
+ Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(true);
+ Universe::heap()->collect(GCCause::_last_ditch_collection);
++#if INCLUDE_ALL_GCS
++ if (UseG1GC) {
++ // Needs to be cleared explicitly for G1
++ Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(false);
++ }
++#endif // INCLUDE_ALL_GCS
+ WB_END
+
++WB_ENTRY(void, WB_YoungGC(JNIEnv* env, jobject o))
++ Universe::heap()->collect(GCCause::_wb_young_gc);
++WB_END
+
+ WB_ENTRY(void, WB_ReadReservedMemory(JNIEnv* env, jobject o))
+ // static+volatile in order to force the read to happen
+@@ -559,11 +815,7 @@
+ return result;
+ }
+
+- clazz = env->FindClass(vmSymbols::java_lang_Integer()->as_C_string());
+- CHECK_JNI_EXCEPTION_(env, NULL);
+- jmethodID constructor = env->GetMethodID(clazz, vmSymbols::object_initializer_name()->as_C_string(), vmSymbols::int_void_signature()->as_C_string());
+- CHECK_JNI_EXCEPTION_(env, NULL);
+- jobject obj = env->NewObject(clazz, constructor, code->comp_level());
++ jobject obj = integerBox(thread, env, code->comp_level());
+ CHECK_JNI_EXCEPTION_(env, NULL);
+ env->SetObjectArrayElement(result, 0, obj);
+
+@@ -576,6 +828,62 @@
+ WB_END
+
+
++int WhiteBox::array_bytes_to_length(size_t bytes) {
++ return Array<u1>::bytes_to_length(bytes);
++}
++
++WB_ENTRY(jlong, WB_AllocateMetaspace(JNIEnv* env, jobject wb, jobject class_loader, jlong size))
++ if (size < 0) {
++ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
++ err_msg("WB_AllocateMetaspace: size is negative: " JLONG_FORMAT, size));
++ }
++
++ oop class_loader_oop = JNIHandles::resolve(class_loader);
++ ClassLoaderData* cld = class_loader_oop != NULL
++ ? java_lang_ClassLoader::loader_data(class_loader_oop)
++ : ClassLoaderData::the_null_class_loader_data();
++
++ void* metadata = MetadataFactory::new_writeable_array<u1>(cld, WhiteBox::array_bytes_to_length((size_t)size), thread);
++
++ return (jlong)(uintptr_t)metadata;
++WB_END
++
++WB_ENTRY(void, WB_FreeMetaspace(JNIEnv* env, jobject wb, jobject class_loader, jlong addr, jlong size))
++ oop class_loader_oop = JNIHandles::resolve(class_loader);
++ ClassLoaderData* cld = class_loader_oop != NULL
++ ? java_lang_ClassLoader::loader_data(class_loader_oop)
++ : ClassLoaderData::the_null_class_loader_data();
++
++ MetadataFactory::free_array(cld, (Array<u1>*)(uintptr_t)addr);
++WB_END
++
++WB_ENTRY(jlong, WB_IncMetaspaceCapacityUntilGC(JNIEnv* env, jobject wb, jlong inc))
++ if (inc < 0) {
++ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
++ err_msg("WB_IncMetaspaceCapacityUntilGC: inc is negative: " JLONG_FORMAT, inc));
++ }
++
++ jlong max_size_t = (jlong) ((size_t) -1);
++ if (inc > max_size_t) {
++ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
++ err_msg("WB_IncMetaspaceCapacityUntilGC: inc does not fit in size_t: " JLONG_FORMAT, inc));
++ }
++
++ size_t new_cap_until_GC = 0;
++ size_t aligned_inc = align_size_down((size_t) inc, Metaspace::commit_alignment());
++ bool success = MetaspaceGC::inc_capacity_until_GC(aligned_inc, &new_cap_until_GC);
++ if (!success) {
++ THROW_MSG_0(vmSymbols::java_lang_IllegalStateException(),
++ "WB_IncMetaspaceCapacityUntilGC: could not increase capacity until GC "
++ "due to contention with another thread");
++ }
++ return (jlong) new_cap_until_GC;
++WB_END
++
++WB_ENTRY(jlong, WB_MetaspaceCapacityUntilGC(JNIEnv* env, jobject wb))
++ return (jlong) MetaspaceGC::capacity_until_GC();
++WB_END
++
+ //Some convenience methods to deal with objects from java
+ int WhiteBox::offset_for_field(const char* field_name, oop object,
+ Symbol* signature_symbol) {
+@@ -626,17 +934,58 @@
+ return ret;
+ }
+
++void WhiteBox::register_methods(JNIEnv* env, jclass wbclass, JavaThread* thread, JNINativeMethod* method_array, int method_count) {
++ ResourceMark rm;
++ ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
++
++ // one by one registration natives for exception catching
++ jclass no_such_method_error_klass = env->FindClass(vmSymbols::java_lang_NoSuchMethodError()->as_C_string());
++ CHECK_JNI_EXCEPTION(env);
++ for (int i = 0, n = method_count; i < n; ++i) {
++ // Skip dummy entries
++ if (method_array[i].fnPtr == NULL) continue;
++ if (env->RegisterNatives(wbclass, &method_array[i], 1) != 0) {
++ jthrowable throwable_obj = env->ExceptionOccurred();
++ if (throwable_obj != NULL) {
++ env->ExceptionClear();
++ if (env->IsInstanceOf(throwable_obj, no_such_method_error_klass)) {
++ // NoSuchMethodError is thrown when a method can't be found or a method is not native.
++ // Ignoring the exception since it is not preventing use of other WhiteBox methods.
++ tty->print_cr("Warning: 'NoSuchMethodError' on register of sun.hotspot.WhiteBox::%s%s",
++ method_array[i].name, method_array[i].signature);
++ }
++ } else {
++ // Registration failed unexpectedly.
++ tty->print_cr("Warning: unexpected error on register of sun.hotspot.WhiteBox::%s%s. All methods will be unregistered",
++ method_array[i].name, method_array[i].signature);
++ env->UnregisterNatives(wbclass);
++ break;
++ }
++ }
++ }
++}
+
+ #define CC (char*)
+
+ static JNINativeMethod methods[] = {
+ {CC"getObjectAddress", CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectAddress },
++ {CC"getObjectSize", CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectSize },
++ {CC"isObjectInOldGen", CC"(Ljava/lang/Object;)Z", (void*)&WB_isObjectInOldGen },
+ {CC"getHeapOopSize", CC"()I", (void*)&WB_GetHeapOopSize },
+ {CC"isClassAlive0", CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive },
++ {CC"classKnownToNotExist",
++ CC"(Ljava/lang/ClassLoader;Ljava/lang/String;)Z",(void*)&WB_ClassKnownToNotExist},
++ {CC"getLookupCacheURLs", CC"(Ljava/lang/ClassLoader;)[Ljava/net/URL;", (void*)&WB_GetLookupCacheURLs},
++ {CC"getLookupCacheMatches", CC"(Ljava/lang/ClassLoader;Ljava/lang/String;)[I",
++ (void*)&WB_GetLookupCacheMatches},
+ {CC"parseCommandLine",
+ CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
+ (void*) &WB_ParseCommandLine
+ },
++ {CC"addToBootstrapClassLoaderSearch", CC"(Ljava/lang/String;)V",
++ (void*)&WB_AddToBootstrapClassLoaderSearch},
++ {CC"addToSystemClassLoaderSearch", CC"(Ljava/lang/String;)V",
++ (void*)&WB_AddToSystemClassLoaderSearch},
+ {CC"getCompressedOopsMaxHeapSize", CC"()J",
+ (void*)&WB_GetCompressedOopsMaxHeapSize},
+ {CC"printHeapSizes", CC"()V", (void*)&WB_PrintHeapSizes },
+@@ -651,13 +1000,15 @@
+ #endif // INCLUDE_ALL_GCS
+ #if INCLUDE_NMT
+ {CC"NMTMalloc", CC"(J)J", (void*)&WB_NMTMalloc },
++ {CC"NMTMallocWithPseudoStack", CC"(JI)J", (void*)&WB_NMTMallocWithPseudoStack},
+ {CC"NMTFree", CC"(J)V", (void*)&WB_NMTFree },
+ {CC"NMTReserveMemory", CC"(J)J", (void*)&WB_NMTReserveMemory },
+ {CC"NMTCommitMemory", CC"(JJ)V", (void*)&WB_NMTCommitMemory },
+ {CC"NMTUncommitMemory", CC"(JJ)V", (void*)&WB_NMTUncommitMemory },
+ {CC"NMTReleaseMemory", CC"(JJ)V", (void*)&WB_NMTReleaseMemory },
+- {CC"NMTWaitForDataMerge", CC"()Z", (void*)&WB_NMTWaitForDataMerge},
+ {CC"NMTIsDetailSupported",CC"()Z", (void*)&WB_NMTIsDetailSupported},
++ {CC"NMTChangeTrackingLevel", CC"()Z", (void*)&WB_NMTChangeTrackingLevel},
++ {CC"NMTGetHashSize", CC"()I", (void*)&WB_NMTGetHashSize },
+ #endif // INCLUDE_NMT
+ {CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll },
+ {CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;Z)I",
+@@ -684,9 +1035,35 @@
+ CC"(Ljava/lang/reflect/Executable;II)Z", (void*)&WB_EnqueueMethodForCompilation},
+ {CC"clearMethodState",
+ CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState},
+- {CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable },
++ {CC"setBooleanVMFlag", CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag},
++ {CC"setIntxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetIntxVMFlag},
++ {CC"setUintxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUintxVMFlag},
++ {CC"setUint64VMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUint64VMFlag},
++ {CC"setDoubleVMFlag", CC"(Ljava/lang/String;D)V",(void*)&WB_SetDoubleVMFlag},
++ {CC"setStringVMFlag", CC"(Ljava/lang/String;Ljava/lang/String;)V",
++ (void*)&WB_SetStringVMFlag},
++ {CC"getBooleanVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Boolean;",
++ (void*)&WB_GetBooleanVMFlag},
++ {CC"getIntxVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;",
++ (void*)&WB_GetIntxVMFlag},
++ {CC"getUintxVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;",
++ (void*)&WB_GetUintxVMFlag},
++ {CC"getUint64VMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;",
++ (void*)&WB_GetUint64VMFlag},
++ {CC"getDoubleVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Double;",
++ (void*)&WB_GetDoubleVMFlag},
++ {CC"getStringVMFlag", CC"(Ljava/lang/String;)Ljava/lang/String;",
++ (void*)&WB_GetStringVMFlag},
++ {CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable },
+ {CC"fullGC", CC"()V", (void*)&WB_FullGC },
++ {CC"youngGC", CC"()V", (void*)&WB_YoungGC },
+ {CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory },
++ {CC"allocateMetaspace",
++ CC"(Ljava/lang/ClassLoader;J)J", (void*)&WB_AllocateMetaspace },
++ {CC"freeMetaspace",
++ CC"(Ljava/lang/ClassLoader;JJ)V", (void*)&WB_FreeMetaspace },
++ {CC"incMetaspaceCapacityUntilGC", CC"(J)J", (void*)&WB_IncMetaspaceCapacityUntilGC },
++ {CC"metaspaceCapacityUntilGC", CC"()J", (void*)&WB_MetaspaceCapacityUntilGC },
+ {CC"getCPUFeatures", CC"()Ljava/lang/String;", (void*)&WB_GetCPUFeatures },
+ {CC"getNMethod", CC"(Ljava/lang/reflect/Executable;Z)[Ljava/lang/Object;",
+ (void*)&WB_GetNMethod },
+@@ -701,35 +1078,9 @@
+ instanceKlassHandle ikh = instanceKlassHandle(JNIHandles::resolve(wbclass)->klass());
+ Handle loader(ikh->class_loader());
+ if (loader.is_null()) {
+- ResourceMark rm;
+- ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
+- bool result = true;
+- // one by one registration natives for exception catching
+- jclass exceptionKlass = env->FindClass(vmSymbols::java_lang_NoSuchMethodError()->as_C_string());
+- CHECK_JNI_EXCEPTION(env);
+- for (int i = 0, n = sizeof(methods) / sizeof(methods[0]); i < n; ++i) {
+- if (env->RegisterNatives(wbclass, methods + i, 1) != 0) {
+- result = false;
+- jthrowable throwable_obj = env->ExceptionOccurred();
+- if (throwable_obj != NULL) {
+- env->ExceptionClear();
+- if (env->IsInstanceOf(throwable_obj, exceptionKlass)) {
+- // j.l.NoSuchMethodError is thrown when a method can't be found or a method is not native
+- // ignoring the exception
+- tty->print_cr("Warning: 'NoSuchMethodError' on register of sun.hotspot.WhiteBox::%s%s", methods[i].name, methods[i].signature);
+- }
+- } else {
+- // register is failed w/o exception or w/ unexpected exception
+- tty->print_cr("Warning: unexpected error on register of sun.hotspot.WhiteBox::%s%s. All methods will be unregistered", methods[i].name, methods[i].signature);
+- env->UnregisterNatives(wbclass);
+- break;
+- }
+- }
+- }
+-
+- if (result) {
+- WhiteBox::set_used();
+- }
++ WhiteBox::register_methods(env, wbclass, thread, methods, sizeof(methods) / sizeof(methods[0]));
++ WhiteBox::register_extended(env, wbclass, thread);
++ WhiteBox::set_used();
+ }
+ }
+ }
+--- ./hotspot/src/share/vm/prims/whitebox.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/prims/whitebox.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -29,6 +29,8 @@
+
+ #include "memory/allocation.hpp"
+ #include "oops/oopsHierarchy.hpp"
++#include "oops/symbol.hpp"
++#include "runtime/interfaceSupport.hpp"
+
+ // Entry macro to transition from JNI to VM state.
+
+@@ -62,6 +64,11 @@
+ Symbol* signature_symbol);
+ static const char* lookup_jstring(const char* field_name, oop object);
+ static bool lookup_bool(const char* field_name, oop object);
++
++ static int array_bytes_to_length(size_t bytes);
++ static void register_methods(JNIEnv* env, jclass wbclass, JavaThread* thread,
++ JNINativeMethod* method_array, int method_count);
++ static void register_extended(JNIEnv* env, jclass wbclass, JavaThread* thread);
+ };
+
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/prims/whitebox_ext.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,29 @@
++/*
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++
++#include "prims/whitebox.hpp"
++
++void WhiteBox::register_extended(JNIEnv* env, jclass wbclass, JavaThread* thread) { }
+--- ./hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -75,11 +75,14 @@
+
+ // update_rate() is called from select_task() while holding a compile queue lock.
+ void AdvancedThresholdPolicy::update_rate(jlong t, Method* m) {
+- JavaThread* THREAD = JavaThread::current();
++ // Skip update if counters are absent.
++ // Can't allocate them since we are holding compile queue lock.
++ if (m->method_counters() == NULL) return;
++
+ if (is_old(m)) {
+ // We don't remove old methods from the queue,
+ // so we can just zero the rate.
+- m->set_rate(0, THREAD);
++ m->set_rate(0);
+ return;
+ }
+
+@@ -95,14 +98,15 @@
+ if (delta_s >= TieredRateUpdateMinTime) {
+ // And we must've taken the previous point at least 1ms before.
+ if (delta_t >= TieredRateUpdateMinTime && delta_e > 0) {
+- m->set_prev_time(t, THREAD);
+- m->set_prev_event_count(event_count, THREAD);
+- m->set_rate((float)delta_e / (float)delta_t, THREAD); // Rate is events per millisecond
+- } else
++ m->set_prev_time(t);
++ m->set_prev_event_count(event_count);
++ m->set_rate((float)delta_e / (float)delta_t); // Rate is events per millisecond
++ } else {
+ if (delta_t > TieredRateUpdateMaxTime && delta_e == 0) {
+ // If nothing happened for 25ms, zero the rate. Don't modify prev values.
+- m->set_rate(0, THREAD);
++ m->set_rate(0);
+ }
++ }
+ }
+ }
+
+@@ -164,7 +168,6 @@
+ for (CompileTask* task = compile_queue->first(); task != NULL;) {
+ CompileTask* next_task = task->next();
+ Method* method = task->method();
+- MethodData* mdo = method->method_data();
+ update_rate(t, method);
+ if (max_task == NULL) {
+ max_task = task;
+@@ -175,8 +178,7 @@
+ if (PrintTieredEvents) {
+ print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level());
+ }
+- CompileTaskWrapper ctw(task); // Frees the task
+- compile_queue->remove(task);
++ compile_queue->remove_and_mark_stale(task);
+ method->clear_queued_for_compilation();
+ task = next_task;
+ continue;
+@@ -314,8 +316,8 @@
+ * c. 0 -> (3->2) -> 4.
+ * In this case we enqueue a method for compilation at level 3, but the C1 queue is long enough
+ * to enable the profiling to fully occur at level 0. In this case we change the compilation level
+- * of the method to 2, because it'll allow it to run much faster without full profiling while c2
+- * is compiling.
++ * of the method to 2 while the request is still in-queue, because it'll allow it to run much faster
++ * without full profiling while c2 is compiling.
+ *
+ * d. 0 -> 3 -> 1 or 0 -> 2 -> 1.
+ * After a method was once compiled with C1 it can be identified as trivial and be compiled to
+@@ -449,7 +451,7 @@
+ if (should_create_mdo(mh(), level)) {
+ create_mdo(mh, thread);
+ }
+- if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) {
++ if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh)) {
+ CompLevel next_level = call_event(mh(), level);
+ if (next_level != level) {
+ compile(mh, InvocationEntryBci, next_level, thread);
+@@ -473,7 +475,7 @@
+ CompLevel next_osr_level = loop_event(imh(), level);
+ CompLevel max_osr_level = (CompLevel)imh->highest_osr_comp_level();
+ // At the very least compile the OSR version
+- if (!CompileBroker::compilation_is_in_queue(imh, bci) && next_osr_level != level) {
++ if (!CompileBroker::compilation_is_in_queue(imh) && (next_osr_level != level)) {
+ compile(imh, bci, next_osr_level, thread);
+ }
+
+@@ -507,7 +509,7 @@
+ nm->make_not_entrant();
+ }
+ }
+- if (!CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) {
++ if (!CompileBroker::compilation_is_in_queue(mh)) {
+ // Fix up next_level if necessary to avoid deopts
+ if (next_level == CompLevel_limited_profile && max_osr_level == CompLevel_full_profile) {
+ next_level = CompLevel_full_profile;
+@@ -519,7 +521,7 @@
+ } else {
+ cur_level = comp_level(imh());
+ next_level = call_event(imh(), cur_level);
+- if (!CompileBroker::compilation_is_in_queue(imh, bci) && next_level != cur_level) {
++ if (!CompileBroker::compilation_is_in_queue(imh) && (next_level != cur_level)) {
+ compile(imh, InvocationEntryBci, next_level, thread);
+ }
+ }
+--- ./hotspot/src/share/vm/runtime/arguments.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/arguments.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -23,6 +23,7 @@
+ */
+
+ #include "precompiled.hpp"
++#include "classfile/classLoader.hpp"
+ #include "classfile/javaAssertions.hpp"
+ #include "classfile/symbolTable.hpp"
+ #include "compiler/compilerOracle.hpp"
+@@ -34,12 +35,14 @@
+ #include "oops/oop.inline.hpp"
+ #include "prims/jvmtiExport.hpp"
+ #include "runtime/arguments.hpp"
++#include "runtime/arguments_ext.hpp"
+ #include "runtime/globals_extension.hpp"
+ #include "runtime/java.hpp"
+ #include "services/management.hpp"
+ #include "services/memTracker.hpp"
+ #include "utilities/defaultStream.hpp"
+ #include "utilities/macros.hpp"
++#include "utilities/stringUtils.hpp"
+ #include "utilities/taskqueue.hpp"
+ #ifdef TARGET_OS_FAMILY_linux
+ # include "os_linux.inline.hpp"
+@@ -98,6 +101,8 @@
+ bool Arguments::_has_profile = false;
+ size_t Arguments::_conservative_max_heap_alignment = 0;
+ uintx Arguments::_min_heap_size = 0;
++uintx Arguments::_min_heap_free_ratio = 0;
++uintx Arguments::_max_heap_free_ratio = 0;
+ Arguments::Mode Arguments::_mode = _mixed;
+ bool Arguments::_java_compiler = false;
+ bool Arguments::_xdebug_mode = false;
+@@ -294,6 +299,8 @@
+ { "UseMPSS", JDK_Version::jdk(8), JDK_Version::jdk(9) },
+ { "UseStringCache", JDK_Version::jdk(8), JDK_Version::jdk(9) },
+ { "UseOldInlining", JDK_Version::jdk(9), JDK_Version::jdk(10) },
++ { "AutoShutdownNMT", JDK_Version::jdk(9), JDK_Version::jdk(10) },
++ { "CompilationRepeat", JDK_Version::jdk(8), JDK_Version::jdk(9) },
+ #ifdef PRODUCT
+ { "DesiredMethodLimit",
+ JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) },
+@@ -1108,11 +1115,11 @@
+ // Conflict: required to use shared spaces (-Xshare:on), but
+ // incompatible command line options were chosen.
+
+-static void no_shared_spaces() {
++static void no_shared_spaces(const char* message) {
+ if (RequireSharedSpaces) {
+ jio_fprintf(defaultStream::error_stream(),
+ "Class data sharing is inconsistent with other specified options.\n");
+- vm_exit_during_initialization("Unable to use shared archive.", NULL);
++ vm_exit_during_initialization("Unable to use shared archive.", message);
+ } else {
+ FLAG_SET_DEFAULT(UseSharedSpaces, false);
+ }
+@@ -1138,6 +1145,32 @@
+ }
+ }
+
++/**
++ * Returns the minimum number of compiler threads needed to run the JVM. The following
++ * configurations are possible.
++ *
++ * 1) The JVM is build using an interpreter only. As a result, the minimum number of
++ * compiler threads is 0.
++ * 2) The JVM is build using the compiler(s) and tiered compilation is disabled. As
++ * a result, either C1 or C2 is used, so the minimum number of compiler threads is 1.
++ * 3) The JVM is build using the compiler(s) and tiered compilation is enabled. However,
++ * the option "TieredStopAtLevel < CompLevel_full_optimization". As a result, only
++ * C1 can be used, so the minimum number of compiler threads is 1.
++ * 4) The JVM is build using the compilers and tiered compilation is enabled. The option
++ * 'TieredStopAtLevel = CompLevel_full_optimization' (the default value). As a result,
++ * the minimum number of compiler threads is 2.
++ */
++int Arguments::get_min_number_of_compiler_threads() {
++#if !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK)
++ return 0; // case 1
++#else
++ if (!TieredCompilation || (TieredStopAtLevel < CompLevel_full_optimization)) {
++ return 1; // case 2 or case 3
++ }
++ return 2; // case 4 (tiered)
++#endif
++}
++
+ #if INCLUDE_ALL_GCS
+ static void disable_adaptive_size_policy(const char* collector_name) {
+ if (UseAdaptiveSizePolicy) {
+@@ -1398,10 +1431,26 @@
+ (int)ObjectAlignmentInBytes, os::vm_page_size());
+ return false;
+ }
++ if(SurvivorAlignmentInBytes == 0) {
++ SurvivorAlignmentInBytes = ObjectAlignmentInBytes;
++ } else {
++ if (!is_power_of_2(SurvivorAlignmentInBytes)) {
++ jio_fprintf(defaultStream::error_stream(),
++ "error: SurvivorAlignmentInBytes=%d must be power of 2\n",
++ (int)SurvivorAlignmentInBytes);
++ return false;
++ }
++ if (SurvivorAlignmentInBytes < ObjectAlignmentInBytes) {
++ jio_fprintf(defaultStream::error_stream(),
++ "error: SurvivorAlignmentInBytes=%d must be greater than ObjectAlignmentInBytes=%d \n",
++ (int)SurvivorAlignmentInBytes, (int)ObjectAlignmentInBytes);
++ return false;
++ }
++ }
+ return true;
+ }
+
+-uintx Arguments::max_heap_for_compressed_oops() {
++size_t Arguments::max_heap_for_compressed_oops() {
+ // Avoid sign flip.
+ assert(OopEncodingHeapMax > (uint64_t)os::vm_page_size(), "Unusual page size");
+ // We need to fit both the NULL page and the heap into the memory budget, while
+@@ -1505,28 +1554,31 @@
+ heap_alignment = G1CollectedHeap::conservative_max_heap_alignment();
+ }
+ #endif // INCLUDE_ALL_GCS
+- _conservative_max_heap_alignment = MAX3(heap_alignment, os::max_page_size(),
+- CollectorPolicy::compute_heap_alignment());
++ _conservative_max_heap_alignment = MAX4(heap_alignment,
++ (size_t)os::vm_allocation_granularity(),
++ os::max_page_size(),
++ CollectorPolicy::compute_heap_alignment());
+ }
+
+-void Arguments::set_ergonomics_flags() {
+-
++void Arguments::select_gc_ergonomically() {
+ if (os::is_server_class_machine()) {
+- // If no other collector is requested explicitly,
+- // let the VM select the collector based on
+- // machine class and automatic selection policy.
+- if (!UseSerialGC &&
+- !UseConcMarkSweepGC &&
+- !UseG1GC &&
+- !UseParNewGC &&
+- FLAG_IS_DEFAULT(UseParallelGC)) {
+- if (should_auto_select_low_pause_collector()) {
+- FLAG_SET_ERGO(bool, UseConcMarkSweepGC, true);
+- } else {
+- FLAG_SET_ERGO(bool, UseParallelGC, true);
+- }
++ if (should_auto_select_low_pause_collector()) {
++ FLAG_SET_ERGO(bool, UseConcMarkSweepGC, true);
++ } else {
++ FLAG_SET_ERGO(bool, UseParallelGC, true);
+ }
+ }
++}
++
++void Arguments::select_gc() {
++ if (!gc_selected()) {
++ ArgumentsExt::select_gc_ergonomically();
++ }
++}
++
++void Arguments::set_ergonomics_flags() {
++ select_gc();
++
+ #ifdef COMPILER2
+ // Shared spaces work fine with other GCs but causes bytecode rewriting
+ // to be disabled, which hurts interpreter performance and decreases
+@@ -1535,7 +1587,7 @@
+ // at link time, or rewrite bytecodes in non-shared methods.
+ if (!DumpSharedSpaces && !RequireSharedSpaces &&
+ (FLAG_IS_DEFAULT(UseSharedSpaces) || !UseSharedSpaces)) {
+- no_shared_spaces();
++ no_shared_spaces("COMPILER2 default: -Xshare:auto | off, have to manually setup to on.");
+ }
+ #endif
+
+@@ -1578,9 +1630,11 @@
+ // unless the user actually sets these flags.
+ if (FLAG_IS_DEFAULT(MinHeapFreeRatio)) {
+ FLAG_SET_DEFAULT(MinHeapFreeRatio, 0);
++ _min_heap_free_ratio = MinHeapFreeRatio;
+ }
+ if (FLAG_IS_DEFAULT(MaxHeapFreeRatio)) {
+ FLAG_SET_DEFAULT(MaxHeapFreeRatio, 100);
++ _max_heap_free_ratio = MaxHeapFreeRatio;
+ }
+ }
+
+@@ -1619,6 +1673,12 @@
+ Abstract_VM_Version::parallel_worker_threads());
+ }
+
++#if INCLUDE_ALL_GCS
++ if (G1ConcRefinementThreads == 0) {
++ FLAG_SET_DEFAULT(G1ConcRefinementThreads, ParallelGCThreads);
++ }
++#endif
++
+ // MarkStackSize will be set (if it hasn't been set by the user)
+ // when concurrent marking is initialized.
+ // Its value will be based upon the number of parallel marking threads.
+@@ -1644,6 +1704,46 @@
+ }
+ }
+
++#if !INCLUDE_ALL_GCS
++#ifdef ASSERT
++static bool verify_serial_gc_flags() {
++ return (UseSerialGC &&
++ !(UseParNewGC || (UseConcMarkSweepGC || CMSIncrementalMode) || UseG1GC ||
++ UseParallelGC || UseParallelOldGC));
++}
++#endif // ASSERT
++#endif // INCLUDE_ALL_GCS
++
++void Arguments::set_gc_specific_flags() {
++#if INCLUDE_ALL_GCS
++ // Set per-collector flags
++ if (UseParallelGC || UseParallelOldGC) {
++ set_parallel_gc_flags();
++ } else if (UseConcMarkSweepGC) { // Should be done before ParNew check below
++ set_cms_and_parnew_gc_flags();
++ } else if (UseParNewGC) { // Skipped if CMS is set above
++ set_parnew_gc_flags();
++ } else if (UseG1GC) {
++ set_g1_gc_flags();
++ }
++ check_deprecated_gcs();
++ check_deprecated_gc_flags();
++ if (AssumeMP && !UseSerialGC) {
++ if (FLAG_IS_DEFAULT(ParallelGCThreads) && ParallelGCThreads == 1) {
++ warning("If the number of processors is expected to increase from one, then"
++ " you should configure the number of parallel GC threads appropriately"
++ " using -XX:ParallelGCThreads=N");
++ }
++ }
++ if (MinHeapFreeRatio == 100) {
++ // Keeping the heap 100% free is hard ;-) so limit it to 99%.
++ FLAG_SET_ERGO(uintx, MinHeapFreeRatio, 99);
++ }
++#else // INCLUDE_ALL_GCS
++ assert(verify_serial_gc_flags(), "SerialGC unset");
++#endif // INCLUDE_ALL_GCS
++}
++
+ julong Arguments::limit_by_allocatable_memory(julong limit) {
+ julong max_allocatable;
+ julong result = limit;
+@@ -1867,16 +1967,6 @@
+ return false;
+ }
+
+-#if !INCLUDE_ALL_GCS
+-#ifdef ASSERT
+-static bool verify_serial_gc_flags() {
+- return (UseSerialGC &&
+- !(UseParNewGC || (UseConcMarkSweepGC || CMSIncrementalMode) || UseG1GC ||
+- UseParallelGC || UseParallelOldGC));
+-}
+-#endif // ASSERT
+-#endif // INCLUDE_ALL_GCS
+-
+ // check if do gclog rotation
+ // +UseGCLogFileRotation is a must,
+ // no gc log rotation when log file not supplied or
+@@ -1955,6 +2045,8 @@
+ MaxHeapFreeRatio);
+ return false;
+ }
++ // This does not set the flag itself, but stores the value in a safe place for later usage.
++ _min_heap_free_ratio = min_heap_free_ratio;
+ return true;
+ }
+
+@@ -1969,11 +2061,13 @@
+ MinHeapFreeRatio);
+ return false;
+ }
++ // This does not set the flag itself, but stores the value in a safe place for later usage.
++ _max_heap_free_ratio = max_heap_free_ratio;
+ return true;
+ }
+
+ // Check consistency of GC selection
+-bool Arguments::check_gc_consistency() {
++bool Arguments::check_gc_consistency_user() {
+ check_gclog_consistency();
+ bool status = true;
+ // Ensure that the user has not selected conflicting sets
+@@ -2139,7 +2233,7 @@
+ FLAG_SET_DEFAULT(UseGCOverheadLimit, false);
+ }
+
+- status = status && check_gc_consistency();
++ status = status && check_gc_consistency_user();
+ status = status && check_stack_pages();
+
+ if (CMSIncrementalMode) {
+@@ -2322,10 +2416,13 @@
+ status = status && verify_percentage(MarkSweepDeadRatio, "MarkSweepDeadRatio");
+
+ status = status && verify_min_value(MarkSweepAlwaysCompactCount, 1, "MarkSweepAlwaysCompactCount");
++#ifdef COMPILER1
++ status = status && verify_min_value(ValueMapInitialSize, 1, "ValueMapInitialSize");
++#endif
+
+ if (PrintNMTStatistics) {
+ #if INCLUDE_NMT
+- if (MemTracker::tracking_level() == MemTracker::NMT_off) {
++ if (MemTracker::tracking_level() == NMT_off) {
+ #endif // INCLUDE_NMT
+ warning("PrintNMTStatistics is disabled, because native memory tracking is not enabled");
+ PrintNMTStatistics = false;
+@@ -2391,6 +2488,12 @@
+ status &= verify_interval(SafepointPollOffset, 0, os::vm_page_size() - BytesPerWord, "SafepointPollOffset");
+ #endif
+
++ int min_number_of_compiler_threads = get_min_number_of_compiler_threads();
++ // The default CICompilerCount's value is CI_COMPILER_COUNT.
++ assert(min_number_of_compiler_threads <= CI_COMPILER_COUNT, "minimum should be less or equal default number");
++ // Check the minimum number of compiler threads
++ status &=verify_min_value(CICompilerCount, min_number_of_compiler_threads, "CICompilerCount");
++
+ return status;
+ }
+
+@@ -2859,6 +2962,23 @@
+ #endif
+ // -D
+ } else if (match_option(option, "-D", &tail)) {
++ if (CheckEndorsedAndExtDirs) {
++ if (match_option(option, "-Djava.endorsed.dirs=", &tail)) {
++ // abort if -Djava.endorsed.dirs is set
++ jio_fprintf(defaultStream::output_stream(),
++ "-Djava.endorsed.dirs will not be supported in a future release.\n"
++ "Refer to JEP 220 for details (http://openjdk.java.net/jeps/220).\n");
++ return JNI_EINVAL;
++ }
++ if (match_option(option, "-Djava.ext.dirs=", &tail)) {
++ // abort if -Djava.ext.dirs is set
++ jio_fprintf(defaultStream::output_stream(),
++ "-Djava.ext.dirs will not be supported in a future release.\n"
++ "Refer to JEP 220 for details (http://openjdk.java.net/jeps/220).\n");
++ return JNI_EINVAL;
++ }
++ }
++
+ if (!add_property(tail)) {
+ return JNI_ENOMEM;
+ }
+@@ -3226,6 +3346,15 @@
+ }
+ }
+
++ // PrintSharedArchiveAndExit will turn on
++ // -Xshare:on
++ // -XX:+TraceClassPaths
++ if (PrintSharedArchiveAndExit) {
++ FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
++ FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true);
++ FLAG_SET_CMDLINE(bool, TraceClassPaths, true);
++ }
++
+ // Change the default value for flags which have different default values
+ // when working with older JDKs.
+ #ifdef LINUX
+@@ -3234,9 +3363,195 @@
+ FLAG_SET_DEFAULT(UseLinuxPosixThreadCPUClocks, false);
+ }
+ #endif // LINUX
++ fix_appclasspath();
+ return JNI_OK;
+ }
+
++// Remove all empty paths from the app classpath (if IgnoreEmptyClassPaths is enabled)
++//
++// This is necessary because some apps like to specify classpath like -cp foo.jar:${XYZ}:bar.jar
++// in their start-up scripts. If XYZ is empty, the classpath will look like "-cp foo.jar::bar.jar".
++// Java treats such empty paths as if the user specified "-cp foo.jar:.:bar.jar". I.e., an empty
++// path is treated as the current directory.
++//
++// This causes problems with CDS, which requires that all directories specified in the classpath
++// must be empty. In most cases, applications do NOT want to load classes from the current
++// directory anyway. Adding -XX:+IgnoreEmptyClassPaths will make these applications' start-up
++// scripts compatible with CDS.
++void Arguments::fix_appclasspath() {
++ if (IgnoreEmptyClassPaths) {
++ const char separator = *os::path_separator();
++ const char* src = _java_class_path->value();
++
++ // skip over all the leading empty paths
++ while (*src == separator) {
++ src ++;
++ }
++
++ char* copy = AllocateHeap(strlen(src) + 1, mtInternal);
++ strncpy(copy, src, strlen(src) + 1);
++
++ // trim all trailing empty paths
++ for (char* tail = copy + strlen(copy) - 1; tail >= copy && *tail == separator; tail--) {
++ *tail = '\0';
++ }
++
++ char from[3] = {separator, separator, '\0'};
++ char to [2] = {separator, '\0'};
++ while (StringUtils::replace_no_expand(copy, from, to) > 0) {
++ // Keep replacing "::" -> ":" until we have no more "::" (non-windows)
++ // Keep replacing ";;" -> ";" until we have no more ";;" (windows)
++ }
++
++ _java_class_path->set_value(copy);
++ FreeHeap(copy); // a copy was made by set_value, so don't need this anymore
++ }
++
++ if (!PrintSharedArchiveAndExit) {
++ ClassLoader::trace_class_path("[classpath: ", _java_class_path->value());
++ }
++}
++
++static bool has_jar_files(const char* directory) {
++ DIR* dir = os::opendir(directory);
++ if (dir == NULL) return false;
++
++ struct dirent *entry;
++ char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtInternal);
++ bool hasJarFile = false;
++ while (!hasJarFile && (entry = os::readdir(dir, (dirent *) dbuf)) != NULL) {
++ const char* name = entry->d_name;
++ const char* ext = name + strlen(name) - 4;
++ hasJarFile = ext > name && (os::file_name_strcmp(ext, ".jar") == 0);
++ }
++ FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
++ os::closedir(dir);
++ return hasJarFile ;
++}
++
++// returns the number of directories in the given path containing JAR files
++// If the skip argument is not NULL, it will skip that directory
++static int check_non_empty_dirs(const char* path, const char* type, const char* skip) {
++ const char separator = *os::path_separator();
++ const char* const end = path + strlen(path);
++ int nonEmptyDirs = 0;
++ while (path < end) {
++ const char* tmp_end = strchr(path, separator);
++ if (tmp_end == NULL) {
++ if ((skip == NULL || strcmp(path, skip) != 0) && has_jar_files(path)) {
++ nonEmptyDirs++;
++ jio_fprintf(defaultStream::output_stream(),
++ "Non-empty %s directory: %s\n", type, path);
++ }
++ path = end;
++ } else {
++ char* dirpath = NEW_C_HEAP_ARRAY(char, tmp_end - path + 1, mtInternal);
++ memcpy(dirpath, path, tmp_end - path);
++ dirpath[tmp_end - path] = '\0';
++ if ((skip == NULL || strcmp(dirpath, skip) != 0) && has_jar_files(dirpath)) {
++ nonEmptyDirs++;
++ jio_fprintf(defaultStream::output_stream(),
++ "Non-empty %s directory: %s\n", type, dirpath);
++ }
++ FREE_C_HEAP_ARRAY(char, dirpath, mtInternal);
++ path = tmp_end + 1;
++ }
++ }
++ return nonEmptyDirs;
++}
++
++// Returns true if endorsed standards override mechanism and extension mechanism
++// are not used.
++static bool check_endorsed_and_ext_dirs() {
++ if (!CheckEndorsedAndExtDirs)
++ return true;
++
++ char endorsedDir[JVM_MAXPATHLEN];
++ char extDir[JVM_MAXPATHLEN];
++ const char* fileSep = os::file_separator();
++ jio_snprintf(endorsedDir, sizeof(endorsedDir), "%s%slib%sendorsed",
++ Arguments::get_java_home(), fileSep, fileSep);
++ jio_snprintf(extDir, sizeof(extDir), "%s%slib%sext",
++ Arguments::get_java_home(), fileSep, fileSep);
++
++ // check endorsed directory
++ int nonEmptyDirs = check_non_empty_dirs(Arguments::get_endorsed_dir(), "endorsed", NULL);
++
++ // check the extension directories but skip the default lib/ext directory
++ nonEmptyDirs += check_non_empty_dirs(Arguments::get_ext_dirs(), "extension", extDir);
++
++ // List of JAR files installed in the default lib/ext directory.
++ // -XX:+CheckEndorsedAndExtDirs checks if any non-JDK file installed
++ static const char* jdk_ext_jars[] = {
++ "access-bridge-32.jar",
++ "access-bridge-64.jar",
++ "access-bridge.jar",
++ "cldrdata.jar",
++ "dnsns.jar",
++ "jaccess.jar",
++ "jfxrt.jar",
++ "localedata.jar",
++ "nashorn.jar",
++ "sunec.jar",
++ "sunjce_provider.jar",
++ "sunmscapi.jar",
++ "sunpkcs11.jar",
++ "ucrypto.jar",
++ "zipfs.jar",
++ NULL
++ };
++
++ // check if the default lib/ext directory has any non-JDK jar files; if so, error
++ DIR* dir = os::opendir(extDir);
++ if (dir != NULL) {
++ int num_ext_jars = 0;
++ struct dirent *entry;
++ char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(extDir), mtInternal);
++ while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL) {
++ const char* name = entry->d_name;
++ const char* ext = name + strlen(name) - 4;
++ if (ext > name && (os::file_name_strcmp(ext, ".jar") == 0)) {
++ bool is_jdk_jar = false;
++ const char* jarfile = NULL;
++ for (int i=0; (jarfile = jdk_ext_jars[i]) != NULL; i++) {
++ if (os::file_name_strcmp(name, jarfile) == 0) {
++ is_jdk_jar = true;
++ break;
++ }
++ }
++ if (!is_jdk_jar) {
++ jio_fprintf(defaultStream::output_stream(),
++ "%s installed in <JAVA_HOME>/lib/ext\n", name);
++ num_ext_jars++;
++ }
++ }
++ }
++ FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
++ os::closedir(dir);
++ if (num_ext_jars > 0) {
++ nonEmptyDirs += 1;
++ }
++ }
++
++ // check if the default lib/endorsed directory exists; if so, error
++ dir = os::opendir(endorsedDir);
++ if (dir != NULL) {
++ jio_fprintf(defaultStream::output_stream(), "<JAVA_HOME>/lib/endorsed exists\n");
++ os::closedir(dir);
++ nonEmptyDirs += 1;
++ }
++
++ if (nonEmptyDirs > 0) {
++ jio_fprintf(defaultStream::output_stream(),
++ "Endorsed standards override mechanism and extension mechanism "
++ "will not be supported in a future release.\n"
++ "Refer to JEP 220 for details (http://openjdk.java.net/jeps/220).\n");
++ return false;
++ }
++
++ return true;
++}
++
+ jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_required) {
+ // This must be done after all -D arguments have been processed.
+ scp_p->expand_endorsed();
+@@ -3246,6 +3561,10 @@
+ Arguments::set_sysclasspath(scp_p->combined_path());
+ }
+
++ if (!check_endorsed_and_ext_dirs()) {
++ return JNI_ERR;
++ }
++
+ // This must be done after all arguments have been processed.
+ // java_compiler() true means set to "NONE" or empty.
+ if (java_compiler() && !xdebug_mode()) {
+@@ -3407,9 +3726,8 @@
+ "Cannot dump shared archive when UseCompressedOops or UseCompressedClassPointers is off.", NULL);
+ }
+ } else {
+- // UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces.
+ if (!UseCompressedOops || !UseCompressedClassPointers) {
+- no_shared_spaces();
++ no_shared_spaces("UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces.");
+ }
+ #endif
+ }
+@@ -3493,6 +3811,8 @@
+ bool settings_file_specified = false;
+ bool needs_hotspotrc_warning = false;
+
++ ArgumentsExt::process_options(args);
++
+ const char* flags_file;
+ int index;
+ for (index = 0; index < args->nOptions; index++) {
+@@ -3517,15 +3837,24 @@
+ CommandLineFlags::printFlags(tty, false);
+ vm_exit(0);
+ }
++#if INCLUDE_NMT
+ if (match_option(option, "-XX:NativeMemoryTracking", &tail)) {
+-#if INCLUDE_NMT
+- MemTracker::init_tracking_options(tail);
+-#else
+- jio_fprintf(defaultStream::error_stream(),
+- "Native Memory Tracking is not supported in this VM\n");
+- return JNI_ERR;
++ // The launcher did not setup nmt environment variable properly.
++ if (!MemTracker::check_launcher_nmt_support(tail)) {
++ warning("Native Memory Tracking did not setup properly, using wrong launcher?");
++ }
++
++ // Verify if nmt option is valid.
++ if (MemTracker::verify_nmt_option()) {
++ // Late initialization, still in single-threaded mode.
++ if (MemTracker::tracking_level() >= NMT_summary) {
++ MemTracker::init();
++ }
++ } else {
++ vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL);
++ }
++ }
+ #endif
+- }
+
+
+ #ifndef PRODUCT
+@@ -3663,7 +3992,7 @@
+ FLAG_SET_DEFAULT(UseSharedSpaces, false);
+ FLAG_SET_DEFAULT(PrintSharedSpaces, false);
+ }
+- no_shared_spaces();
++ no_shared_spaces("CDS Disabled");
+ #endif // INCLUDE_CDS
+
+ return JNI_OK;
+@@ -3677,7 +4006,7 @@
+ set_shared_spaces_flags();
+
+ // Check the GC selections again.
+- if (!check_gc_consistency()) {
++ if (!ArgumentsExt::check_gc_consistency_ergo()) {
+ return JNI_EINVAL;
+ }
+
+@@ -3699,33 +4028,7 @@
+ // Set heap size based on available physical memory
+ set_heap_size();
+
+-#if INCLUDE_ALL_GCS
+- // Set per-collector flags
+- if (UseParallelGC || UseParallelOldGC) {
+- set_parallel_gc_flags();
+- } else if (UseConcMarkSweepGC) { // Should be done before ParNew check below
+- set_cms_and_parnew_gc_flags();
+- } else if (UseParNewGC) { // Skipped if CMS is set above
+- set_parnew_gc_flags();
+- } else if (UseG1GC) {
+- set_g1_gc_flags();
+- }
+- check_deprecated_gcs();
+- check_deprecated_gc_flags();
+- if (AssumeMP && !UseSerialGC) {
+- if (FLAG_IS_DEFAULT(ParallelGCThreads) && ParallelGCThreads == 1) {
+- warning("If the number of processors is expected to increase from one, then"
+- " you should configure the number of parallel GC threads appropriately"
+- " using -XX:ParallelGCThreads=N");
+- }
+- }
+- if (MinHeapFreeRatio == 100) {
+- // Keeping the heap 100% free is hard ;-) so limit it to 99%.
+- FLAG_SET_ERGO(uintx, MinHeapFreeRatio, 99);
+- }
+-#else // INCLUDE_ALL_GCS
+- assert(verify_serial_gc_flags(), "SerialGC unset");
+-#endif // INCLUDE_ALL_GCS
++ ArgumentsExt::set_gc_specific_flags();
+
+ // Initialize Metaspace flags and alignments.
+ Metaspace::ergo_initialize();
+@@ -3781,10 +4084,6 @@
+ // nothing to use the profiling, turn if off
+ FLAG_SET_DEFAULT(TypeProfileLevel, 0);
+ }
+- if (UseTypeSpeculation && FLAG_IS_DEFAULT(ReplaceInParentMaps)) {
+- // Doing the replace in parent maps helps speculation
+- FLAG_SET_DEFAULT(ReplaceInParentMaps, true);
+- }
+ #endif
+
+ if (PrintAssembly && FLAG_IS_DEFAULT(DebugNonSafepoints)) {
+@@ -3842,18 +4141,24 @@
+ }
+
+ jint Arguments::adjust_after_os() {
+-#if INCLUDE_ALL_GCS
+- if (UseParallelGC || UseParallelOldGC) {
+- if (UseNUMA) {
++ if (UseNUMA) {
++ if (UseParallelGC || UseParallelOldGC) {
+ if (FLAG_IS_DEFAULT(MinHeapDeltaBytes)) {
+- FLAG_SET_DEFAULT(MinHeapDeltaBytes, 64*M);
++ FLAG_SET_DEFAULT(MinHeapDeltaBytes, 64*M);
+ }
+- // For those collectors or operating systems (eg, Windows) that do
+- // not support full UseNUMA, we will map to UseNUMAInterleaving for now
+- UseNUMAInterleaving = true;
++ }
++ // UseNUMAInterleaving is set to ON for all collectors and
++ // platforms when UseNUMA is set to ON. NUMA-aware collectors
++ // such as the parallel collector for Linux and Solaris will
++ // interleave old gen and survivor spaces on top of NUMA
++ // allocation policy for the eden space.
++ // Non NUMA-aware collectors such as CMS, G1 and Serial-GC on
++ // all platforms and ParallelGC on Windows will interleave all
++ // of the heap spaces across NUMA nodes.
++ if (FLAG_IS_DEFAULT(UseNUMAInterleaving)) {
++ FLAG_SET_ERGO(bool, UseNUMAInterleaving, true);
+ }
+ }
+-#endif // INCLUDE_ALL_GCS
+ return JNI_OK;
+ }
+
+--- ./hotspot/src/share/vm/runtime/arguments.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/arguments.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -284,7 +284,11 @@
+ // Value of the conservative maximum heap alignment needed
+ static size_t _conservative_max_heap_alignment;
+
+- static uintx _min_heap_size;
++ static uintx _min_heap_size;
++
++ // Used to store original flag values
++ static uintx _min_heap_free_ratio;
++ static uintx _max_heap_free_ratio;
+
+ // -Xrun arguments
+ static AgentLibraryList _libraryList;
+@@ -323,6 +327,7 @@
+
+ // Tiered
+ static void set_tiered_flags();
++ static int get_min_number_of_compiler_threads();
+ // CMS/ParNew garbage collectors
+ static void set_parnew_gc_flags();
+ static void set_cms_and_parnew_gc_flags();
+@@ -334,6 +339,7 @@
+ static void set_conservative_max_heap_alignment();
+ static void set_use_compressed_oops();
+ static void set_use_compressed_klass_ptrs();
++ static void select_gc();
+ static void set_ergonomics_flags();
+ static void set_shared_spaces_flags();
+ // limits the given memory size by the maximum amount of memory this process is
+@@ -447,6 +453,10 @@
+ // Adjusts the arguments after the OS have adjusted the arguments
+ static jint adjust_after_os();
+
++ static void set_gc_specific_flags();
++ static inline bool gc_selected(); // whether a gc has been selected
++ static void select_gc_ergonomically();
++
+ // Verifies that the given value will fit as a MinHeapFreeRatio. If not, an error
+ // message is returned in the provided buffer.
+ static bool verify_MinHeapFreeRatio(FormatBuffer<80>& err_msg, uintx min_heap_free_ratio);
+@@ -456,7 +466,8 @@
+ static bool verify_MaxHeapFreeRatio(FormatBuffer<80>& err_msg, uintx max_heap_free_ratio);
+
+ // Check for consistency in the selection of the garbage collector.
+- static bool check_gc_consistency();
++ static bool check_gc_consistency_user(); // Check user-selected gc
++ static inline bool check_gc_consistency_ergo(); // Check ergonomic-selected gc
+ static void check_deprecated_gcs();
+ static void check_deprecated_gc_flags();
+ // Check consistecy or otherwise of VM argument settings
+@@ -513,6 +524,10 @@
+ static uintx min_heap_size() { return _min_heap_size; }
+ static void set_min_heap_size(uintx v) { _min_heap_size = v; }
+
++ // Returns the original values of -XX:MinHeapFreeRatio and -XX:MaxHeapFreeRatio
++ static uintx min_heap_free_ratio() { return _min_heap_free_ratio; }
++ static uintx max_heap_free_ratio() { return _max_heap_free_ratio; }
++
+ // -Xrun
+ static AgentLibrary* libraries() { return _libraryList.first(); }
+ static bool init_libraries_at_startup() { return !_libraryList.is_empty(); }
+@@ -576,18 +591,32 @@
+ _meta_index_dir = meta_index_dir;
+ }
+
+- static char *get_java_home() { return _java_home->value(); }
+- static char *get_dll_dir() { return _sun_boot_library_path->value(); }
+- static char *get_endorsed_dir() { return _java_endorsed_dirs->value(); }
+- static char *get_sysclasspath() { return _sun_boot_class_path->value(); }
++ static char* get_java_home() { return _java_home->value(); }
++ static char* get_dll_dir() { return _sun_boot_library_path->value(); }
++ static char* get_endorsed_dir() { return _java_endorsed_dirs->value(); }
++ static char* get_sysclasspath() { return _sun_boot_class_path->value(); }
+ static char* get_meta_index_path() { return _meta_index_path; }
+ static char* get_meta_index_dir() { return _meta_index_dir; }
++ static char* get_ext_dirs() { return _java_ext_dirs->value(); }
++ static char* get_appclasspath() { return _java_class_path->value(); }
++ static void fix_appclasspath();
+
+ // Operation modi
+- static Mode mode() { return _mode; }
++ static Mode mode() { return _mode; }
++ static bool is_interpreter_only() { return mode() == _int; }
++
+
+ // Utility: copies src into buf, replacing "%%" with "%" and "%p" with pid.
+ static bool copy_expand_pid(const char* src, size_t srclen, char* buf, size_t buflen);
+ };
+
++bool Arguments::gc_selected() {
++ return UseConcMarkSweepGC || UseG1GC || UseParallelGC || UseParallelOldGC ||
++ UseParNewGC || UseSerialGC;
++}
++
++bool Arguments::check_gc_consistency_ergo() {
++ return check_gc_consistency_user();
++}
++
+ #endif // SHARE_VM_RUNTIME_ARGUMENTS_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/runtime/arguments_ext.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,51 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_RUNTIME_ARGUMENTS_EXT_HPP
++#define SHARE_VM_RUNTIME_ARGUMENTS_EXT_HPP
++
++#include "memory/allocation.hpp"
++#include "runtime/arguments.hpp"
++
++class ArgumentsExt: AllStatic {
++public:
++ static inline void select_gc_ergonomically();
++ static inline void set_gc_specific_flags();
++ static inline bool check_gc_consistency_ergo();
++ static void process_options(const JavaVMInitArgs* args) {}
++};
++
++void ArgumentsExt::select_gc_ergonomically() {
++ Arguments::select_gc_ergonomically();
++}
++
++void ArgumentsExt::set_gc_specific_flags() {
++ Arguments::set_gc_specific_flags();
++}
++
++bool ArgumentsExt::check_gc_consistency_ergo() {
++ return Arguments::check_gc_consistency_ergo();
++}
++
++#endif // SHARE_VM_RUNTIME_ARGUMENTS_EXT_HPP
+--- ./hotspot/src/share/vm/runtime/deoptimization.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/deoptimization.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -213,6 +213,8 @@
+ assert(vf->is_compiled_frame(), "Wrong frame type");
+ chunk->push(compiledVFrame::cast(vf));
+
++ bool realloc_failures = false;
++
+ #ifdef COMPILER2
+ // Reallocate the non-escaping objects and restore their fields. Then
+ // relock objects if synchronization on them was eliminated.
+@@ -228,7 +230,8 @@
+ // It is not guaranteed that we can get such information here only
+ // by analyzing bytecode in deoptimized frames. This is why this flag
+ // is set during method compilation (see Compile::Process_OopMap_Node()).
+- bool save_oop_result = chunk->at(0)->scope()->return_oop();
++ // If the previous frame was popped, we don't have a result.
++ bool save_oop_result = chunk->at(0)->scope()->return_oop() && !thread->popframe_forcing_deopt_reexecution();
+ Handle return_value;
+ if (save_oop_result) {
+ // Reallocation may trigger GC. If deoptimization happened on return from
+@@ -242,19 +245,16 @@
+ tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, (void *)result, thread);
+ }
+ }
+- bool reallocated = false;
+ if (objects != NULL) {
+ JRT_BLOCK
+- reallocated = realloc_objects(thread, &deoptee, objects, THREAD);
++ realloc_failures = realloc_objects(thread, &deoptee, objects, THREAD);
+ JRT_END
+- }
+- if (reallocated) {
+- reassign_fields(&deoptee, &map, objects);
++ reassign_fields(&deoptee, &map, objects, realloc_failures);
+ #ifndef PRODUCT
+ if (TraceDeoptimization) {
+ ttyLocker ttyl;
+ tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread);
+- print_objects(objects);
++ print_objects(objects, realloc_failures);
+ }
+ #endif
+ }
+@@ -272,7 +272,7 @@
+ assert (cvf->scope() != NULL,"expect only compiled java frames");
+ GrowableArray<MonitorInfo*>* monitors = cvf->monitors();
+ if (monitors->is_nonempty()) {
+- relock_objects(monitors, thread);
++ relock_objects(monitors, thread, realloc_failures);
+ #ifndef PRODUCT
+ if (TraceDeoptimization) {
+ ttyLocker ttyl;
+@@ -283,7 +283,12 @@
+ first = false;
+ tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread);
+ }
+- tty->print_cr(" object <" INTPTR_FORMAT "> locked", (void *)mi->owner());
++ if (mi->owner_is_scalar_replaced()) {
++ Klass* k = java_lang_Class::as_Klass(mi->owner_klass());
++ tty->print_cr(" failed reallocation for klass %s", k->external_name());
++ } else {
++ tty->print_cr(" object <" INTPTR_FORMAT "> locked", (void *)mi->owner());
++ }
+ }
+ }
+ }
+@@ -298,9 +303,14 @@
+ // out the java state residing in the vframeArray will be missed.
+ No_Safepoint_Verifier no_safepoint;
+
+- vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk);
++ vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk, realloc_failures);
++#ifdef COMPILER2
++ if (realloc_failures) {
++ pop_frames_failed_reallocs(thread, array);
++ }
++#endif
+
+- assert(thread->vframe_array_head() == NULL, "Pending deopt!");;
++ assert(thread->vframe_array_head() == NULL, "Pending deopt!");
+ thread->set_vframe_array_head(array);
+
+ // Now that the vframeArray has been created if we have any deferred local writes
+@@ -698,7 +708,7 @@
+ (iframe->interpreter_frame_expression_stack_size() == (next_mask_expression_stack_size -
+ top_frame_expression_stack_adjustment))) ||
+ (is_top_frame && (exec_mode == Unpack_exception) && iframe->interpreter_frame_expression_stack_size() == 0) ||
+- (is_top_frame && (exec_mode == Unpack_uncommon_trap || exec_mode == Unpack_reexecute) &&
++ (is_top_frame && (exec_mode == Unpack_uncommon_trap || exec_mode == Unpack_reexecute || el->should_reexecute()) &&
+ (iframe->interpreter_frame_expression_stack_size() == mask.expression_stack_size() + cur_invoke_parameter_size))
+ )) {
+ ttyLocker ttyl;
+@@ -752,6 +762,8 @@
+ int exception_line = thread->exception_line();
+ thread->clear_pending_exception();
+
++ bool failures = false;
++
+ for (int i = 0; i < objects->length(); i++) {
+ assert(objects->at(i)->is_object(), "invalid debug information");
+ ObjectValue* sv = (ObjectValue*) objects->at(i);
+@@ -761,27 +773,34 @@
+
+ if (k->oop_is_instance()) {
+ InstanceKlass* ik = InstanceKlass::cast(k());
+- obj = ik->allocate_instance(CHECK_(false));
++ obj = ik->allocate_instance(THREAD);
+ } else if (k->oop_is_typeArray()) {
+ TypeArrayKlass* ak = TypeArrayKlass::cast(k());
+ assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length");
+ int len = sv->field_size() / type2size[ak->element_type()];
+- obj = ak->allocate(len, CHECK_(false));
++ obj = ak->allocate(len, THREAD);
+ } else if (k->oop_is_objArray()) {
+ ObjArrayKlass* ak = ObjArrayKlass::cast(k());
+- obj = ak->allocate(sv->field_size(), CHECK_(false));
++ obj = ak->allocate(sv->field_size(), THREAD);
+ }
+
+- assert(obj != NULL, "allocation failed");
++ if (obj == NULL) {
++ failures = true;
++ }
++
+ assert(sv->value().is_null(), "redundant reallocation");
++ assert(obj != NULL || HAS_PENDING_EXCEPTION, "allocation should succeed or we should get an exception");
++ CLEAR_PENDING_EXCEPTION;
+ sv->set_value(obj);
+ }
+
+- if (pending_exception.not_null()) {
++ if (failures) {
++ THROW_OOP_(Universe::out_of_memory_error_realloc_objects(), failures);
++ } else if (pending_exception.not_null()) {
+ thread->set_pending_exception(pending_exception(), exception_file, exception_line);
+ }
+
+- return true;
++ return failures;
+ }
+
+ // This assumes that the fields are stored in ObjectValue in the same order
+@@ -919,12 +938,15 @@
+
+
+ // restore fields of all eliminated objects and arrays
+-void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects) {
++void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures) {
+ for (int i = 0; i < objects->length(); i++) {
+ ObjectValue* sv = (ObjectValue*) objects->at(i);
+ KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()()));
+ Handle obj = sv->value();
+- assert(obj.not_null(), "reallocation was missed");
++ assert(obj.not_null() || realloc_failures, "reallocation was missed");
++ if (obj.is_null()) {
++ continue;
++ }
+
+ if (k->oop_is_instance()) {
+ InstanceKlass* ik = InstanceKlass::cast(k());
+@@ -941,34 +963,36 @@
+
+
+ // relock objects for which synchronization was eliminated
+-void Deoptimization::relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread) {
++void Deoptimization::relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread, bool realloc_failures) {
+ for (int i = 0; i < monitors->length(); i++) {
+ MonitorInfo* mon_info = monitors->at(i);
+ if (mon_info->eliminated()) {
+- assert(mon_info->owner() != NULL, "reallocation was missed");
+- Handle obj = Handle(mon_info->owner());
+- markOop mark = obj->mark();
+- if (UseBiasedLocking && mark->has_bias_pattern()) {
+- // New allocated objects may have the mark set to anonymously biased.
+- // Also the deoptimized method may called methods with synchronization
+- // where the thread-local object is bias locked to the current thread.
+- assert(mark->is_biased_anonymously() ||
+- mark->biased_locker() == thread, "should be locked to current thread");
+- // Reset mark word to unbiased prototype.
+- markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
+- obj->set_mark(unbiased_prototype);
++ assert(!mon_info->owner_is_scalar_replaced() || realloc_failures, "reallocation was missed");
++ if (!mon_info->owner_is_scalar_replaced()) {
++ Handle obj = Handle(mon_info->owner());
++ markOop mark = obj->mark();
++ if (UseBiasedLocking && mark->has_bias_pattern()) {
++ // New allocated objects may have the mark set to anonymously biased.
++ // Also the deoptimized method may called methods with synchronization
++ // where the thread-local object is bias locked to the current thread.
++ assert(mark->is_biased_anonymously() ||
++ mark->biased_locker() == thread, "should be locked to current thread");
++ // Reset mark word to unbiased prototype.
++ markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
++ obj->set_mark(unbiased_prototype);
++ }
++ BasicLock* lock = mon_info->lock();
++ ObjectSynchronizer::slow_enter(obj, lock, thread);
++ assert(mon_info->owner()->is_locked(), "object must be locked now");
+ }
+- BasicLock* lock = mon_info->lock();
+- ObjectSynchronizer::slow_enter(obj, lock, thread);
+ }
+- assert(mon_info->owner()->is_locked(), "object must be locked now");
+ }
+ }
+
+
+ #ifndef PRODUCT
+ // print information about reallocated objects
+-void Deoptimization::print_objects(GrowableArray<ScopeValue*>* objects) {
++void Deoptimization::print_objects(GrowableArray<ScopeValue*>* objects, bool realloc_failures) {
+ fieldDescriptor fd;
+
+ for (int i = 0; i < objects->length(); i++) {
+@@ -978,10 +1002,15 @@
+
+ tty->print(" object <" INTPTR_FORMAT "> of type ", (void *)sv->value()());
+ k->print_value();
+- tty->print(" allocated (%d bytes)", obj->size() * HeapWordSize);
++ assert(obj.not_null() || realloc_failures, "reallocation was missed");
++ if (obj.is_null()) {
++ tty->print(" allocation failed");
++ } else {
++ tty->print(" allocated (%d bytes)", obj->size() * HeapWordSize);
++ }
+ tty->cr();
+
+- if (Verbose) {
++ if (Verbose && !obj.is_null()) {
+ k->oop_print_on(obj(), tty);
+ }
+ }
+@@ -989,7 +1018,7 @@
+ #endif
+ #endif // COMPILER2
+
+-vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk) {
++vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures) {
+ Events::log(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, fr.pc(), fr.sp());
+
+ #ifndef PRODUCT
+@@ -1032,7 +1061,7 @@
+ // Since the Java thread being deoptimized will eventually adjust it's own stack,
+ // the vframeArray containing the unpacking information is allocated in the C heap.
+ // For Compiler1, the caller of the deoptimized frame is saved for use by unpack_frames().
+- vframeArray* array = vframeArray::allocate(thread, frame_size, chunk, reg_map, sender, caller, fr);
++ vframeArray* array = vframeArray::allocate(thread, frame_size, chunk, reg_map, sender, caller, fr, realloc_failures);
+
+ // Compare the vframeArray to the collected vframes
+ assert(array->structural_compare(thread, chunk), "just checking");
+@@ -1047,6 +1076,33 @@
+ return array;
+ }
+
++#ifdef COMPILER2
++void Deoptimization::pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array) {
++ // Reallocation of some scalar replaced objects failed. Record
++ // that we need to pop all the interpreter frames for the
++ // deoptimized compiled frame.
++ assert(thread->frames_to_pop_failed_realloc() == 0, "missed frames to pop?");
++ thread->set_frames_to_pop_failed_realloc(array->frames());
++ // Unlock all monitors here otherwise the interpreter will see a
++ // mix of locked and unlocked monitors (because of failed
++ // reallocations of synchronized objects) and be confused.
++ for (int i = 0; i < array->frames(); i++) {
++ MonitorChunk* monitors = array->element(i)->monitors();
++ if (monitors != NULL) {
++ for (int j = 0; j < monitors->number_of_monitors(); j++) {
++ BasicObjectLock* src = monitors->at(j);
++ if (src->obj() != NULL) {
++ ObjectSynchronizer::fast_exit(src->obj(), src->lock(), thread);
++ }
++ }
++ array->element(i)->free_monitors(thread);
++#ifdef ASSERT
++ array->element(i)->set_removed_monitors();
++#endif
++ }
++ }
++}
++#endif
+
+ static void collect_monitors(compiledVFrame* cvf, GrowableArray<Handle>* objects_to_revoke) {
+ GrowableArray<MonitorInfo*>* monitors = cvf->monitors();
+@@ -1835,7 +1891,8 @@
+ "predicate",
+ "loop_limit_check",
+ "speculate_class_check",
+- "rtm_state_change"
++ "rtm_state_change",
++ "unstable_if"
+ };
+ const char* Deoptimization::_trap_action_name[Action_LIMIT] = {
+ // Note: Keep this in sync. with enum DeoptAction.
+--- ./hotspot/src/share/vm/runtime/deoptimization.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/deoptimization.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -61,6 +61,7 @@
+ Reason_loop_limit_check, // compiler generated loop limits check failed
+ Reason_speculate_class_check, // saw unexpected object class from type speculation
+ Reason_rtm_state_change, // rtm state change detected
++ Reason_unstable_if, // a branch predicted always false was taken
+ Reason_LIMIT,
+ // Note: Keep this enum in sync. with _trap_reason_name.
+ Reason_RECORDED_LIMIT = Reason_bimorphic // some are not recorded per bc
+@@ -119,13 +120,14 @@
+ static bool realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS);
+ static void reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type);
+ static void reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj);
+- static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects);
+- static void relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread);
+- NOT_PRODUCT(static void print_objects(GrowableArray<ScopeValue*>* objects);)
++ static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures);
++ static void relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread, bool realloc_failures);
++ static void pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array);
++ NOT_PRODUCT(static void print_objects(GrowableArray<ScopeValue*>* objects, bool realloc_failures);)
+ #endif // COMPILER2
+
+ public:
+- static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk);
++ static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures);
+
+ // Interface used for unpacking deoptimized frames
+
+@@ -315,6 +317,8 @@
+ return Reason_null_check; // recorded per BCI as a null check
+ else if (reason == Reason_speculate_class_check)
+ return Reason_class_check;
++ else if (reason == Reason_unstable_if)
++ return Reason_intrinsic;
+ else
+ return Reason_none;
+ }
+--- ./hotspot/src/share/vm/runtime/fprofiler.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/fprofiler.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -38,6 +38,7 @@
+ #include "runtime/stubCodeGenerator.hpp"
+ #include "runtime/stubRoutines.hpp"
+ #include "runtime/task.hpp"
++#include "runtime/thread.inline.hpp"
+ #include "runtime/vframe.hpp"
+ #include "utilities/macros.hpp"
+
+--- ./hotspot/src/share/vm/runtime/frame.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/frame.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -900,7 +900,7 @@
+ }
+
+
+-void frame::oops_interpreted_do(OopClosure* f, CLDToOopClosure* cld_f,
++void frame::oops_interpreted_do(OopClosure* f, CLDClosure* cld_f,
+ const RegisterMap* map, bool query_oop_map_cache) {
+ assert(is_interpreted_frame(), "Not an interpreted frame");
+ assert(map != NULL, "map must be set");
+@@ -1140,7 +1140,7 @@
+ }
+
+
+-void frame::oops_do_internal(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache) {
++void frame::oops_do_internal(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache) {
+ #ifndef PRODUCT
+ // simulate GC crash here to dump java thread in error report
+ if (CrashGCForDumpingJavaThread) {
+--- ./hotspot/src/share/vm/runtime/frame.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/frame.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -419,19 +419,19 @@
+
+ // Oops-do's
+ void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, const RegisterMap* reg_map, OopClosure* f);
+- void oops_interpreted_do(OopClosure* f, CLDToOopClosure* cld_f, const RegisterMap* map, bool query_oop_map_cache = true);
++ void oops_interpreted_do(OopClosure* f, CLDClosure* cld_f, const RegisterMap* map, bool query_oop_map_cache = true);
+
+ private:
+ void oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f);
+
+ // Iteration of oops
+- void oops_do_internal(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache);
++ void oops_do_internal(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache);
+ void oops_entry_do(OopClosure* f, const RegisterMap* map);
+ void oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map);
+ int adjust_offset(Method* method, int index); // helper for above fn
+ public:
+ // Memory management
+- void oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf, RegisterMap* map) { oops_do_internal(f, cld_f, cf, map, true); }
++ void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf, RegisterMap* map) { oops_do_internal(f, cld_f, cf, map, true); }
+ void nmethods_do(CodeBlobClosure* cf);
+
+ // RedefineClasses support for finding live interpreted methods on the stack
+--- ./hotspot/src/share/vm/runtime/globals.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/globals.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -243,6 +243,11 @@
+ return is_unlocked_ext();
+ }
+
++void Flag::unlock_diagnostic() {
++ assert(is_diagnostic(), "sanity");
++ _flags = Flags(_flags & ~KIND_DIAGNOSTIC);
++}
++
+ // Get custom message for this locked flag, or return NULL if
+ // none is available.
+ void Flag::get_locked_message(char* buf, int buflen) const {
+@@ -611,7 +616,7 @@
+ e.commit();
+ }
+
+-bool CommandLineFlags::boolAt(char* name, size_t len, bool* value) {
++bool CommandLineFlags::boolAt(const char* name, size_t len, bool* value) {
+ Flag* result = Flag::find_flag(name, len);
+ if (result == NULL) return false;
+ if (!result->is_bool()) return false;
+@@ -619,7 +624,7 @@
+ return true;
+ }
+
+-bool CommandLineFlags::boolAtPut(char* name, size_t len, bool* value, Flag::Flags origin) {
++bool CommandLineFlags::boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin) {
+ Flag* result = Flag::find_flag(name, len);
+ if (result == NULL) return false;
+ if (!result->is_bool()) return false;
+@@ -639,7 +644,7 @@
+ faddr->set_origin(origin);
+ }
+
+-bool CommandLineFlags::intxAt(char* name, size_t len, intx* value) {
++bool CommandLineFlags::intxAt(const char* name, size_t len, intx* value) {
+ Flag* result = Flag::find_flag(name, len);
+ if (result == NULL) return false;
+ if (!result->is_intx()) return false;
+@@ -647,7 +652,7 @@
+ return true;
+ }
+
+-bool CommandLineFlags::intxAtPut(char* name, size_t len, intx* value, Flag::Flags origin) {
++bool CommandLineFlags::intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin) {
+ Flag* result = Flag::find_flag(name, len);
+ if (result == NULL) return false;
+ if (!result->is_intx()) return false;
+@@ -667,7 +672,7 @@
+ faddr->set_origin(origin);
+ }
+
+-bool CommandLineFlags::uintxAt(char* name, size_t len, uintx* value) {
++bool CommandLineFlags::uintxAt(const char* name, size_t len, uintx* value) {
+ Flag* result = Flag::find_flag(name, len);
+ if (result == NULL) return false;
+ if (!result->is_uintx()) return false;
+@@ -675,7 +680,7 @@
+ return true;
+ }
+
+-bool CommandLineFlags::uintxAtPut(char* name, size_t len, uintx* value, Flag::Flags origin) {
++bool CommandLineFlags::uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin) {
+ Flag* result = Flag::find_flag(name, len);
+ if (result == NULL) return false;
+ if (!result->is_uintx()) return false;
+@@ -695,7 +700,7 @@
+ faddr->set_origin(origin);
+ }
+
+-bool CommandLineFlags::uint64_tAt(char* name, size_t len, uint64_t* value) {
++bool CommandLineFlags::uint64_tAt(const char* name, size_t len, uint64_t* value) {
+ Flag* result = Flag::find_flag(name, len);
+ if (result == NULL) return false;
+ if (!result->is_uint64_t()) return false;
+@@ -703,7 +708,7 @@
+ return true;
+ }
+
+-bool CommandLineFlags::uint64_tAtPut(char* name, size_t len, uint64_t* value, Flag::Flags origin) {
++bool CommandLineFlags::uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin) {
+ Flag* result = Flag::find_flag(name, len);
+ if (result == NULL) return false;
+ if (!result->is_uint64_t()) return false;
+@@ -723,7 +728,7 @@
+ faddr->set_origin(origin);
+ }
+
+-bool CommandLineFlags::doubleAt(char* name, size_t len, double* value) {
++bool CommandLineFlags::doubleAt(const char* name, size_t len, double* value) {
+ Flag* result = Flag::find_flag(name, len);
+ if (result == NULL) return false;
+ if (!result->is_double()) return false;
+@@ -731,7 +736,7 @@
+ return true;
+ }
+
+-bool CommandLineFlags::doubleAtPut(char* name, size_t len, double* value, Flag::Flags origin) {
++bool CommandLineFlags::doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin) {
+ Flag* result = Flag::find_flag(name, len);
+ if (result == NULL) return false;
+ if (!result->is_double()) return false;
+@@ -751,7 +756,7 @@
+ faddr->set_origin(origin);
+ }
+
+-bool CommandLineFlags::ccstrAt(char* name, size_t len, ccstr* value) {
++bool CommandLineFlags::ccstrAt(const char* name, size_t len, ccstr* value) {
+ Flag* result = Flag::find_flag(name, len);
+ if (result == NULL) return false;
+ if (!result->is_ccstr()) return false;
+@@ -759,9 +764,7 @@
+ return true;
+ }
+
+-// Contract: Flag will make private copy of the incoming value.
+-// Outgoing value is always malloc-ed, and caller MUST call free.
+-bool CommandLineFlags::ccstrAtPut(char* name, size_t len, ccstr* value, Flag::Flags origin) {
++bool CommandLineFlags::ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin) {
+ Flag* result = Flag::find_flag(name, len);
+ if (result == NULL) return false;
+ if (!result->is_ccstr()) return false;
+@@ -784,7 +787,6 @@
+ return true;
+ }
+
+-// Contract: Flag will make private copy of the incoming value.
+ void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) {
+ Flag* faddr = address_of_flag(flag);
+ guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
+--- ./hotspot/src/share/vm/runtime/globals.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/globals.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -313,6 +313,8 @@
+ bool is_writeable_ext() const;
+ bool is_external_ext() const;
+
++ void unlock_diagnostic();
++
+ void get_locked_message(char*, int) const;
+ void get_locked_message_ext(char*, int) const;
+
+@@ -363,35 +365,37 @@
+
+ class CommandLineFlags {
+ public:
+- static bool boolAt(char* name, size_t len, bool* value);
+- static bool boolAt(char* name, bool* value) { return boolAt(name, strlen(name), value); }
+- static bool boolAtPut(char* name, size_t len, bool* value, Flag::Flags origin);
+- static bool boolAtPut(char* name, bool* value, Flag::Flags origin) { return boolAtPut(name, strlen(name), value, origin); }
++ static bool boolAt(const char* name, size_t len, bool* value);
++ static bool boolAt(const char* name, bool* value) { return boolAt(name, strlen(name), value); }
++ static bool boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin);
++ static bool boolAtPut(const char* name, bool* value, Flag::Flags origin) { return boolAtPut(name, strlen(name), value, origin); }
+
+- static bool intxAt(char* name, size_t len, intx* value);
+- static bool intxAt(char* name, intx* value) { return intxAt(name, strlen(name), value); }
+- static bool intxAtPut(char* name, size_t len, intx* value, Flag::Flags origin);
+- static bool intxAtPut(char* name, intx* value, Flag::Flags origin) { return intxAtPut(name, strlen(name), value, origin); }
++ static bool intxAt(const char* name, size_t len, intx* value);
++ static bool intxAt(const char* name, intx* value) { return intxAt(name, strlen(name), value); }
++ static bool intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin);
++ static bool intxAtPut(const char* name, intx* value, Flag::Flags origin) { return intxAtPut(name, strlen(name), value, origin); }
+
+- static bool uintxAt(char* name, size_t len, uintx* value);
+- static bool uintxAt(char* name, uintx* value) { return uintxAt(name, strlen(name), value); }
+- static bool uintxAtPut(char* name, size_t len, uintx* value, Flag::Flags origin);
+- static bool uintxAtPut(char* name, uintx* value, Flag::Flags origin) { return uintxAtPut(name, strlen(name), value, origin); }
++ static bool uintxAt(const char* name, size_t len, uintx* value);
++ static bool uintxAt(const char* name, uintx* value) { return uintxAt(name, strlen(name), value); }
++ static bool uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin);
++ static bool uintxAtPut(const char* name, uintx* value, Flag::Flags origin) { return uintxAtPut(name, strlen(name), value, origin); }
+
+- static bool uint64_tAt(char* name, size_t len, uint64_t* value);
+- static bool uint64_tAt(char* name, uint64_t* value) { return uint64_tAt(name, strlen(name), value); }
+- static bool uint64_tAtPut(char* name, size_t len, uint64_t* value, Flag::Flags origin);
+- static bool uint64_tAtPut(char* name, uint64_t* value, Flag::Flags origin) { return uint64_tAtPut(name, strlen(name), value, origin); }
++ static bool uint64_tAt(const char* name, size_t len, uint64_t* value);
++ static bool uint64_tAt(const char* name, uint64_t* value) { return uint64_tAt(name, strlen(name), value); }
++ static bool uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin);
++ static bool uint64_tAtPut(const char* name, uint64_t* value, Flag::Flags origin) { return uint64_tAtPut(name, strlen(name), value, origin); }
+
+- static bool doubleAt(char* name, size_t len, double* value);
+- static bool doubleAt(char* name, double* value) { return doubleAt(name, strlen(name), value); }
+- static bool doubleAtPut(char* name, size_t len, double* value, Flag::Flags origin);
+- static bool doubleAtPut(char* name, double* value, Flag::Flags origin) { return doubleAtPut(name, strlen(name), value, origin); }
++ static bool doubleAt(const char* name, size_t len, double* value);
++ static bool doubleAt(const char* name, double* value) { return doubleAt(name, strlen(name), value); }
++ static bool doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin);
++ static bool doubleAtPut(const char* name, double* value, Flag::Flags origin) { return doubleAtPut(name, strlen(name), value, origin); }
+
+- static bool ccstrAt(char* name, size_t len, ccstr* value);
+- static bool ccstrAt(char* name, ccstr* value) { return ccstrAt(name, strlen(name), value); }
+- static bool ccstrAtPut(char* name, size_t len, ccstr* value, Flag::Flags origin);
+- static bool ccstrAtPut(char* name, ccstr* value, Flag::Flags origin) { return ccstrAtPut(name, strlen(name), value, origin); }
++ static bool ccstrAt(const char* name, size_t len, ccstr* value);
++ static bool ccstrAt(const char* name, ccstr* value) { return ccstrAt(name, strlen(name), value); }
++ // Contract: Flag will make private copy of the incoming value.
++ // Outgoing value is always malloc-ed, and caller MUST call free.
++ static bool ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin);
++ static bool ccstrAtPut(const char* name, ccstr* value, Flag::Flags origin) { return ccstrAtPut(name, strlen(name), value, origin); }
+
+ // Returns false if name is not a command line flag.
+ static bool wasSetOnCmdline(const char* name, bool* value);
+@@ -595,6 +599,9 @@
+ product(bool, UseAES, false, \
+ "Control whether AES instructions can be used on x86/x64") \
+ \
++ product(bool, UseSHA, false, \
++ "Control whether SHA instructions can be used on SPARC") \
++ \
+ product(uintx, LargePageSizeInBytes, 0, \
+ "Large page size (0 to let VM choose the page size)") \
+ \
+@@ -701,6 +708,15 @@
+ product(bool, UseAESIntrinsics, false, \
+ "Use intrinsics for AES versions of crypto") \
+ \
++ product(bool, UseSHA1Intrinsics, false, \
++ "Use intrinsics for SHA-1 crypto hash function") \
++ \
++ product(bool, UseSHA256Intrinsics, false, \
++ "Use intrinsics for SHA-224 and SHA-256 crypto hash functions") \
++ \
++ product(bool, UseSHA512Intrinsics, false, \
++ "Use intrinsics for SHA-384 and SHA-512 crypto hash functions") \
++ \
+ product(bool, UseCRC32Intrinsics, false, \
+ "use intrinsics for java.util.zip.CRC32") \
+ \
+@@ -929,11 +945,6 @@
+ diagnostic(bool, PrintNMTStatistics, false, \
+ "Print native memory tracking summary data if it is on") \
+ \
+- diagnostic(bool, AutoShutdownNMT, true, \
+- "Automatically shutdown native memory tracking under stress " \
+- "situations. When set to false, native memory tracking tries to " \
+- "stay alive at the expense of JVM performance") \
+- \
+ diagnostic(bool, LogCompilation, false, \
+ "Log compilation activity in detail to LogFile") \
+ \
+@@ -1062,6 +1073,9 @@
+ product(bool, ClassUnloading, true, \
+ "Do unloading of classes") \
+ \
++ product(bool, ClassUnloadingWithConcurrentMark, true, \
++ "Do unloading of classes with a concurrent marking cycle") \
++ \
+ develop(bool, DisableStartThread, false, \
+ "Disable starting of additional Java threads " \
+ "(for debugging only)") \
+@@ -1196,9 +1210,17 @@
+ product(bool, CheckJNICalls, false, \
+ "Verify all arguments to JNI calls") \
+ \
++ product(bool, CheckEndorsedAndExtDirs, false, \
++ "Verify the endorsed and extension directories are not used") \
++ \
+ product(bool, UseFastJNIAccessors, true, \
+ "Use optimized versions of Get<Primitive>Field") \
+ \
++ product(intx, MaxJNILocalCapacity, 65536, \
++ "Maximum allowable local JNI handle capacity to " \
++ "EnsureLocalCapacity() and PushLocalFrame(), " \
++ "where <= 0 is unlimited, default: 65536") \
++ \
+ product(bool, EagerXrunInit, false, \
+ "Eagerly initialize -Xrun libraries; allows startup profiling, " \
+ "but not all -Xrun libraries may support the state of the VM " \
+@@ -1923,6 +1945,10 @@
+ "not just one of the generations (e.g., G1). A value of 0 " \
+ "denotes 'do constant GC cycles'.") \
+ \
++ manageable(intx, CMSTriggerInterval, -1, \
++ "Commence a CMS collection cycle (at least) every so many " \
++ "milliseconds (0 permanently, -1 disabled)") \
++ \
+ product(bool, UseCMSInitiatingOccupancyOnly, false, \
+ "Only use occupancy as a criterion for starting a CMS collection")\
+ \
+@@ -2287,6 +2313,9 @@
+ manageable(bool, PrintGCTimeStamps, false, \
+ "Print timestamps at garbage collection") \
+ \
++ manageable(bool, PrintGCID, false, \
++ "Print an identifier for each garbage collection") \
++ \
+ product(bool, PrintGCTaskTimeStamps, false, \
+ "Print timestamps for individual gc worker thread tasks") \
+ \
+@@ -2310,6 +2339,12 @@
+ notproduct(bool, TraceScavenge, false, \
+ "Trace scavenge") \
+ \
++ product(bool, IgnoreEmptyClassPaths, false, \
++ "Ignore empty path elements in -classpath") \
++ \
++ product(bool, TraceClassPaths, false, \
++ "Trace processing of class paths") \
++ \
+ product_rw(bool, TraceClassLoading, false, \
+ "Trace all classes loaded") \
+ \
+@@ -3760,6 +3795,13 @@
+ product(bool, PrintSharedSpaces, false, \
+ "Print usage of shared spaces") \
+ \
++ product(bool, PrintSharedArchiveAndExit, false, \
++ "Print shared archive file contents") \
++ \
++ product(bool, PrintSharedDictionary, false, \
++ "If PrintSharedArchiveAndExit is true, also print the shared " \
++ "dictionary") \
++ \
+ product(uintx, SharedReadWriteSize, NOT_LP64(12*M) LP64_ONLY(16*M), \
+ "Size of read-write space for metadata (in bytes)") \
+ \
+@@ -3780,6 +3822,10 @@
+ "support JSR 292 (method handles, invokedynamic, " \
+ "anonymous classes") \
+ \
++ diagnostic(bool, IgnoreUnverifiableClassesDuringDump, false, \
++ "Do not quit -Xshare:dump even if we encounter unverifiable " \
++ "classes. Just exclude them from the shared dictionary.") \
++ \
+ diagnostic(bool, PrintMethodHandleStubs, false, \
+ "Print generated stub code for method handles") \
+ \
+@@ -3869,12 +3915,25 @@
+ product(bool, PrintGCCause, true, \
+ "Include GC cause in GC logging") \
+ \
++ experimental(intx, SurvivorAlignmentInBytes, 0, \
++ "Default survivor space alignment in bytes") \
++ \
+ product(bool , AllowNonVirtualCalls, false, \
+ "Obey the ACC_SUPER flag and allow invokenonvirtual calls") \
+ \
++ product(ccstr, DumpLoadedClassList, NULL, \
++ "Dump the names all loaded classes, that could be stored into " \
++ "the CDS archive, in the specified file") \
++ \
++ product(ccstr, SharedClassListFile, NULL, \
++ "Override the default CDS class list") \
++ \
+ diagnostic(ccstr, SharedArchiveFile, NULL, \
+ "Override the default location of the CDS archive file") \
+ \
++ product(ccstr, ExtraSharedClassListFile, NULL, \
++ "Extra classlist for building the CDS archive file") \
++ \
+ experimental(uintx, ArrayAllocatorMallocLimit, \
+ SOLARIS_ONLY(64*K) NOT_SOLARIS(max_uintx), \
+ "Allocation less than this value will be allocated " \
+--- ./hotspot/src/share/vm/runtime/globals_extension.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/globals_extension.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -201,6 +201,7 @@
+ static void uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin);
+ static void uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin);
+ static void doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin);
++ // Contract: Flag will make private copy of the incoming value
+ static void ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin);
+
+ static bool is_default(CommandLineFlag flag);
+--- ./hotspot/src/share/vm/runtime/handles.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/handles.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -227,7 +227,7 @@
+ HandleArea* _prev; // link to outer (older) area
+ public:
+ // Constructor
+- HandleArea(HandleArea* prev) : Arena(Chunk::tiny_size) {
++ HandleArea(HandleArea* prev) : Arena(mtThread, Chunk::tiny_size) {
+ debug_only(_handle_mark_nesting = 0);
+ debug_only(_no_handle_mark_nesting = 0);
+ _prev = prev;
+--- ./hotspot/src/share/vm/runtime/init.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/init.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -34,8 +34,10 @@
+ #include "runtime/init.hpp"
+ #include "runtime/safepoint.hpp"
+ #include "runtime/sharedRuntime.hpp"
++#include "services/memTracker.hpp"
+ #include "utilities/macros.hpp"
+
++
+ // Initialization done by VM thread in vm_init_globals()
+ void check_ThreadShadow();
+ void eventlog_init();
+@@ -131,6 +133,12 @@
+ javaClasses_init(); // must happen after vtable initialization
+ stubRoutines_init2(); // note: StubRoutines need 2-phase init
+
++#if INCLUDE_NMT
++ // Solaris stack is walkable only after stubRoutines are set up.
++ // On Other platforms, the stack is always walkable.
++ NMT_stack_walkable = true;
++#endif // INCLUDE_NMT
++
+ // All the flags that get adjusted by VM_Version_init and os::init_2
+ // have been set so dump the flags now.
+ if (PrintFlagsFinal) {
+--- ./hotspot/src/share/vm/runtime/interfaceSupport.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/interfaceSupport.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -30,6 +30,7 @@
+ #include "memory/resourceArea.hpp"
+ #include "runtime/init.hpp"
+ #include "runtime/interfaceSupport.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/threadLocalStorage.hpp"
+ #include "runtime/vframe.hpp"
+ #include "utilities/preserveException.hpp"
+@@ -84,7 +85,7 @@
+ // Short-circuit any possible re-entrant gc-a-lot attempt
+ if (thread->skip_gcalot()) return;
+
+- if (is_init_completed()) {
++ if (Threads::is_vm_complete()) {
+
+ if (++_fullgc_alot_invocation < FullGCALotStart) {
+ return;
+--- ./hotspot/src/share/vm/runtime/java.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/java.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -57,7 +57,6 @@
+ #include "runtime/thread.inline.hpp"
+ #include "runtime/timer.hpp"
+ #include "runtime/vm_operations.hpp"
+-#include "services/memReporter.hpp"
+ #include "services/memTracker.hpp"
+ #include "trace/tracing.hpp"
+ #include "utilities/dtrace.hpp"
+@@ -364,12 +363,7 @@
+ #endif // ENABLE_ZAP_DEAD_LOCALS
+ // Native memory tracking data
+ if (PrintNMTStatistics) {
+- if (MemTracker::is_on()) {
+- BaselineTTYOutputer outputer(tty);
+- MemTracker::print_memory_usage(outputer, K, false);
+- } else {
+- tty->print_cr("%s", MemTracker::reason());
+- }
++ MemTracker::final_report(tty);
+ }
+ }
+
+@@ -401,12 +395,7 @@
+
+ // Native memory tracking data
+ if (PrintNMTStatistics) {
+- if (MemTracker::is_on()) {
+- BaselineTTYOutputer outputer(tty);
+- MemTracker::print_memory_usage(outputer, K, false);
+- } else {
+- tty->print_cr("%s", MemTracker::reason());
+- }
++ MemTracker::final_report(tty);
+ }
+ }
+
+@@ -555,10 +544,6 @@
+ BeforeExit_lock->notify_all();
+ }
+
+- // Shutdown NMT before exit. Otherwise,
+- // it will run into trouble when system destroys static variables.
+- MemTracker::shutdown(MemTracker::NMT_normal);
+-
+ if (VerifyStringTableAtExit) {
+ int fail_cnt = 0;
+ {
+--- ./hotspot/src/share/vm/runtime/javaCalls.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/javaCalls.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -308,6 +308,10 @@
+ }
+
+ void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArguments* args, TRAPS) {
++ // During dumping, Java execution environment is not fully initialized. Also, Java execution
++ // may cause undesirable side-effects in the class metadata.
++ assert(!DumpSharedSpaces, "must not execute Java bytecodes when dumping");
++
+ methodHandle method = *m;
+ JavaThread* thread = (JavaThread*)THREAD;
+ assert(thread->is_Java_thread(), "must be called by a java thread");
+--- ./hotspot/src/share/vm/runtime/javaFrameAnchor.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/javaFrameAnchor.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,39 +26,7 @@
+ #define SHARE_VM_RUNTIME_JAVAFRAMEANCHOR_HPP
+
+ #include "utilities/globalDefinitions.hpp"
+-#ifdef TARGET_OS_ARCH_linux_x86
+-# include "orderAccess_linux_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_sparc
+-# include "orderAccess_linux_sparc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_zero
+-# include "orderAccess_linux_zero.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_solaris_x86
+-# include "orderAccess_solaris_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_solaris_sparc
+-# include "orderAccess_solaris_sparc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_windows_x86
+-# include "orderAccess_windows_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_arm
+-# include "orderAccess_linux_arm.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_ppc
+-# include "orderAccess_linux_ppc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_aix_ppc
+-# include "orderAccess_aix_ppc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_bsd_x86
+-# include "orderAccess_bsd_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_bsd_zero
+-# include "orderAccess_bsd_zero.inline.hpp"
+-#endif
++#include "runtime/orderAccess.inline.hpp"
+
+ //
+ // An object for encapsulating the machine/os dependent part of a JavaThread frame state
+--- ./hotspot/src/share/vm/runtime/mutex.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/mutex.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,6 +25,7 @@
+
+ #include "precompiled.hpp"
+ #include "runtime/mutex.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/osThread.hpp"
+ #include "runtime/thread.inline.hpp"
+ #include "utilities/events.hpp"
+--- ./hotspot/src/share/vm/runtime/mutexLocker.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/mutexLocker.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -69,7 +69,7 @@
+ Monitor* SerializePage_lock = NULL;
+ Monitor* Threads_lock = NULL;
+ Monitor* CGC_lock = NULL;
+-Mutex* STS_init_lock = NULL;
++Monitor* STS_lock = NULL;
+ Monitor* SLT_lock = NULL;
+ Monitor* iCMS_lock = NULL;
+ Monitor* FullGCCount_lock = NULL;
+@@ -173,7 +173,7 @@
+ def(tty_lock , Mutex , event, true ); // allow to lock in VM
+
+ def(CGC_lock , Monitor, special, true ); // coordinate between fore- and background GC
+- def(STS_init_lock , Mutex, leaf, true );
++ def(STS_lock , Monitor, leaf, true );
+ if (UseConcMarkSweepGC) {
+ def(iCMS_lock , Monitor, special, true ); // CMS incremental mode start/stop notification
+ }
+--- ./hotspot/src/share/vm/runtime/mutexLocker.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/mutexLocker.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -79,7 +79,7 @@
+ // (also used by Safepoints too to block threads creation/destruction)
+ extern Monitor* CGC_lock; // used for coordination between
+ // fore- & background GC threads.
+-extern Mutex* STS_init_lock; // coordinate initialization of SuspendibleThreadSets.
++extern Monitor* STS_lock; // used for joining/leaving SuspendibleThreadSet.
+ extern Monitor* SLT_lock; // used in CMS GC for acquiring PLL
+ extern Monitor* iCMS_lock; // CMS incremental mode start/stop notification
+ extern Monitor* FullGCCount_lock; // in support of "concurrent" full gc
+--- ./hotspot/src/share/vm/runtime/objectMonitor.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/objectMonitor.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -32,6 +32,7 @@
+ #include "runtime/mutexLocker.hpp"
+ #include "runtime/objectMonitor.hpp"
+ #include "runtime/objectMonitor.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/osThread.hpp"
+ #include "runtime/stubRoutines.hpp"
+ #include "runtime/thread.inline.hpp"
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/runtime/orderAccess.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,74 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2014 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.
++ *
++ */
++
++#ifndef SHARE_VM_RUNTIME_ORDERACCESS_INLINE_HPP
++#define SHARE_VM_RUNTIME_ORDERACCESS_INLINE_HPP
++
++#include "runtime/orderAccess.hpp"
++
++// Linux
++#ifdef TARGET_OS_ARCH_linux_x86
++# include "orderAccess_linux_x86.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_linux_sparc
++# include "orderAccess_linux_sparc.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_linux_zero
++# include "orderAccess_linux_zero.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_linux_arm
++# include "orderAccess_linux_arm.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_linux_ppc
++# include "orderAccess_linux_ppc.inline.hpp"
++#endif
++
++// Solaris
++#ifdef TARGET_OS_ARCH_solaris_x86
++# include "orderAccess_solaris_x86.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_solaris_sparc
++# include "orderAccess_solaris_sparc.inline.hpp"
++#endif
++
++// Windows
++#ifdef TARGET_OS_ARCH_windows_x86
++# include "orderAccess_windows_x86.inline.hpp"
++#endif
++
++// AIX
++#ifdef TARGET_OS_ARCH_aix_ppc
++# include "orderAccess_aix_ppc.inline.hpp"
++#endif
++
++// BSD
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "orderAccess_bsd_x86.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_bsd_zero
++# include "orderAccess_bsd_zero.inline.hpp"
++#endif
++
++#endif // SHARE_VM_RUNTIME_ORDERACCESS_INLINE_HPP
+--- ./hotspot/src/share/vm/runtime/os.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/os.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -32,6 +32,9 @@
+ #include "gc_implementation/shared/vmGCOperations.hpp"
+ #include "interpreter/interpreter.hpp"
+ #include "memory/allocation.inline.hpp"
++#ifdef ASSERT
++#include "memory/guardedMemory.hpp"
++#endif
+ #include "oops/oop.inline.hpp"
+ #include "prims/jvm.h"
+ #include "prims/jvm_misc.hpp"
+@@ -46,6 +49,8 @@
+ #include "runtime/stubRoutines.hpp"
+ #include "runtime/thread.inline.hpp"
+ #include "services/attachListener.hpp"
++#include "services/nmtCommon.hpp"
++#include "services/mallocTracker.hpp"
+ #include "services/memTracker.hpp"
+ #include "services/threadService.hpp"
+ #include "utilities/defaultStream.hpp"
+@@ -524,118 +529,16 @@
+
+
+
+-#ifdef ASSERT
+-#define space_before (MallocCushion + sizeof(double))
+-#define space_after MallocCushion
+-#define size_addr_from_base(p) (size_t*)(p + space_before - sizeof(size_t))
+-#define size_addr_from_obj(p) ((size_t*)p - 1)
+-// MallocCushion: size of extra cushion allocated around objects with +UseMallocOnly
+-// NB: cannot be debug variable, because these aren't set from the command line until
+-// *after* the first few allocs already happened
+-#define MallocCushion 16
+-#else
+-#define space_before 0
+-#define space_after 0
+-#define size_addr_from_base(p) should not use w/o ASSERT
+-#define size_addr_from_obj(p) should not use w/o ASSERT
+-#define MallocCushion 0
+-#endif
+ #define paranoid 0 /* only set to 1 if you suspect checking code has bug */
+
+ #ifdef ASSERT
+-inline size_t get_size(void* obj) {
+- size_t size = *size_addr_from_obj(obj);
+- if (size < 0) {
+- fatal(err_msg("free: size field of object #" PTR_FORMAT " was overwritten ("
+- SIZE_FORMAT ")", obj, size));
+- }
+- return size;
+-}
+-
+-u_char* find_cushion_backwards(u_char* start) {
+- u_char* p = start;
+- while (p[ 0] != badResourceValue || p[-1] != badResourceValue ||
+- p[-2] != badResourceValue || p[-3] != badResourceValue) p--;
+- // ok, we have four consecutive marker bytes; find start
+- u_char* q = p - 4;
+- while (*q == badResourceValue) q--;
+- return q + 1;
+-}
+-
+-u_char* find_cushion_forwards(u_char* start) {
+- u_char* p = start;
+- while (p[0] != badResourceValue || p[1] != badResourceValue ||
+- p[2] != badResourceValue || p[3] != badResourceValue) p++;
+- // ok, we have four consecutive marker bytes; find end of cushion
+- u_char* q = p + 4;
+- while (*q == badResourceValue) q++;
+- return q - MallocCushion;
+-}
+-
+-void print_neighbor_blocks(void* ptr) {
+- // find block allocated before ptr (not entirely crash-proof)
+- if (MallocCushion < 4) {
+- tty->print_cr("### cannot find previous block (MallocCushion < 4)");
+- return;
+- }
+- u_char* start_of_this_block = (u_char*)ptr - space_before;
+- u_char* end_of_prev_block_data = start_of_this_block - space_after -1;
+- // look for cushion in front of prev. block
+- u_char* start_of_prev_block = find_cushion_backwards(end_of_prev_block_data);
+- ptrdiff_t size = *size_addr_from_base(start_of_prev_block);
+- u_char* obj = start_of_prev_block + space_before;
+- if (size <= 0 ) {
+- // start is bad; mayhave been confused by OS data inbetween objects
+- // search one more backwards
+- start_of_prev_block = find_cushion_backwards(start_of_prev_block);
+- size = *size_addr_from_base(start_of_prev_block);
+- obj = start_of_prev_block + space_before;
+- }
+-
+- if (start_of_prev_block + space_before + size + space_after == start_of_this_block) {
+- tty->print_cr("### previous object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size);
+- } else {
+- tty->print_cr("### previous object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size);
+- }
+-
+- // now find successor block
+- u_char* start_of_next_block = (u_char*)ptr + *size_addr_from_obj(ptr) + space_after;
+- start_of_next_block = find_cushion_forwards(start_of_next_block);
+- u_char* next_obj = start_of_next_block + space_before;
+- ptrdiff_t next_size = *size_addr_from_base(start_of_next_block);
+- if (start_of_next_block[0] == badResourceValue &&
+- start_of_next_block[1] == badResourceValue &&
+- start_of_next_block[2] == badResourceValue &&
+- start_of_next_block[3] == badResourceValue) {
+- tty->print_cr("### next object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size);
+- } else {
+- tty->print_cr("### next object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size);
+- }
+-}
+-
+-
+-void report_heap_error(void* memblock, void* bad, const char* where) {
+- tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees);
+- tty->print_cr("## memory stomp: byte at " PTR_FORMAT " %s object " PTR_FORMAT, bad, where, memblock);
+- print_neighbor_blocks(memblock);
+- fatal("memory stomping error");
+-}
+-
+-void verify_block(void* memblock) {
+- size_t size = get_size(memblock);
+- if (MallocCushion) {
+- u_char* ptr = (u_char*)memblock - space_before;
+- for (int i = 0; i < MallocCushion; i++) {
+- if (ptr[i] != badResourceValue) {
+- report_heap_error(memblock, ptr+i, "in front of");
+- }
+- }
+- u_char* end = (u_char*)memblock + size + space_after;
+- for (int j = -MallocCushion; j < 0; j++) {
+- if (end[j] != badResourceValue) {
+- report_heap_error(memblock, end+j, "after");
+- }
+- }
++static void verify_memory(void* ptr) {
++ GuardedMemory guarded(ptr);
++ if (!guarded.verify_guards()) {
++ tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees);
++ tty->print_cr("## memory stomp:");
++ guarded.print_on(tty);
++ fatal("memory stomping error");
+ }
+ }
+ #endif
+@@ -660,7 +563,11 @@
+ return ptr;
+ }
+
+-void* os::malloc(size_t size, MEMFLAGS memflags, address caller) {
++void* os::malloc(size_t size, MEMFLAGS flags) {
++ return os::malloc(size, flags, CALLER_PC);
++}
++
++void* os::malloc(size_t size, MEMFLAGS memflags, const NativeCallStack& stack) {
+ NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
+ NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
+
+@@ -686,16 +593,22 @@
+ size = 1;
+ }
+
+- const size_t alloc_size = size + space_before + space_after;
++ // NMT support
++ NMT_TrackingLevel level = MemTracker::tracking_level();
++ size_t nmt_header_size = MemTracker::malloc_header_size(level);
+
+- if (size > alloc_size) { // Check for rollover.
++#ifndef ASSERT
++ const size_t alloc_size = size + nmt_header_size;
++#else
++ const size_t alloc_size = GuardedMemory::get_total_size(size + nmt_header_size);
++ if (size + nmt_header_size > alloc_size) { // Check for rollover.
+ return NULL;
+ }
++#endif
+
+ NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
+
+ u_char* ptr;
+-
+ if (MallocMaxTestWords > 0) {
+ ptr = testMalloc(alloc_size);
+ } else {
+@@ -703,67 +616,73 @@
+ }
+
+ #ifdef ASSERT
+- if (ptr == NULL) return NULL;
+- if (MallocCushion) {
+- for (u_char* p = ptr; p < ptr + MallocCushion; p++) *p = (u_char)badResourceValue;
+- u_char* end = ptr + space_before + size;
+- for (u_char* pq = ptr+MallocCushion; pq < end; pq++) *pq = (u_char)uninitBlockPad;
+- for (u_char* q = end; q < end + MallocCushion; q++) *q = (u_char)badResourceValue;
++ if (ptr == NULL) {
++ return NULL;
+ }
+- // put size just before data
+- *size_addr_from_base(ptr) = size;
++ // Wrap memory with guard
++ GuardedMemory guarded(ptr, size + nmt_header_size);
++ ptr = guarded.get_user_ptr();
+ #endif
+- u_char* memblock = ptr + space_before;
+- if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
+- tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
++ if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
++ tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
+ breakpoint();
+ }
+- debug_only(if (paranoid) verify_block(memblock));
+- if (PrintMalloc && tty != NULL) tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
++ debug_only(if (paranoid) verify_memory(ptr));
++ if (PrintMalloc && tty != NULL) {
++ tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
++ }
+
+- // we do not track MallocCushion memory
+- MemTracker::record_malloc((address)memblock, size, memflags, caller == 0 ? CALLER_PC : caller);
+-
+- return memblock;
++ // we do not track guard memory
++ return MemTracker::record_malloc((address)ptr, size, memflags, stack, level);
+ }
+
++void* os::realloc(void *memblock, size_t size, MEMFLAGS flags) {
++ return os::realloc(memblock, size, flags, CALLER_PC);
++}
+
+-void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, address caller) {
++void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, const NativeCallStack& stack) {
++
+ #ifndef ASSERT
+ NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
+ NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
+- MemTracker::Tracker tkr = MemTracker::get_realloc_tracker();
+- void* ptr = ::realloc(memblock, size);
+- if (ptr != NULL) {
+- tkr.record((address)memblock, (address)ptr, size, memflags,
+- caller == 0 ? CALLER_PC : caller);
+- } else {
+- tkr.discard();
+- }
+- return ptr;
++ // NMT support
++ void* membase = MemTracker::record_free(memblock);
++ NMT_TrackingLevel level = MemTracker::tracking_level();
++ size_t nmt_header_size = MemTracker::malloc_header_size(level);
++ void* ptr = ::realloc(membase, size + nmt_header_size);
++ return MemTracker::record_malloc(ptr, size, memflags, stack, level);
+ #else
+ if (memblock == NULL) {
+- return malloc(size, memflags, (caller == 0 ? CALLER_PC : caller));
++ return os::malloc(size, memflags, stack);
+ }
+ if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
+ tty->print_cr("os::realloc caught " PTR_FORMAT, memblock);
+ breakpoint();
+ }
+- verify_block(memblock);
++ // NMT support
++ void* membase = MemTracker::malloc_base(memblock);
++ verify_memory(membase);
+ NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
+- if (size == 0) return NULL;
++ if (size == 0) {
++ return NULL;
++ }
+ // always move the block
+- void* ptr = malloc(size, memflags, caller == 0 ? CALLER_PC : caller);
+- if (PrintMalloc) tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
++ void* ptr = os::malloc(size, memflags, stack);
++ if (PrintMalloc) {
++ tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
++ }
+ // Copy to new memory if malloc didn't fail
+ if ( ptr != NULL ) {
+- memcpy(ptr, memblock, MIN2(size, get_size(memblock)));
+- if (paranoid) verify_block(ptr);
++ GuardedMemory guarded(MemTracker::malloc_base(memblock));
++ // Guard's user data contains NMT header
++ size_t memblock_size = guarded.get_user_size() - MemTracker::malloc_header_size(memblock);
++ memcpy(ptr, memblock, MIN2(size, memblock_size));
++ if (paranoid) verify_memory(MemTracker::malloc_base(ptr));
+ if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
+ tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
+ breakpoint();
+ }
+- free(memblock);
++ os::free(memblock);
+ }
+ return ptr;
+ #endif
+@@ -778,34 +697,22 @@
+ if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock);
+ breakpoint();
+ }
+- verify_block(memblock);
++ void* membase = MemTracker::record_free(memblock);
++ verify_memory(membase);
+ NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
+- // Added by detlefs.
+- if (MallocCushion) {
+- u_char* ptr = (u_char*)memblock - space_before;
+- for (u_char* p = ptr; p < ptr + MallocCushion; p++) {
+- guarantee(*p == badResourceValue,
+- "Thing freed should be malloc result.");
+- *p = (u_char)freeBlockPad;
+- }
+- size_t size = get_size(memblock);
+- inc_stat_counter(&free_bytes, size);
+- u_char* end = ptr + space_before + size;
+- for (u_char* q = end; q < end + MallocCushion; q++) {
+- guarantee(*q == badResourceValue,
+- "Thing freed should be malloc result.");
+- *q = (u_char)freeBlockPad;
+- }
+- if (PrintMalloc && tty != NULL)
+- fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, (uintptr_t)memblock);
+- } else if (PrintMalloc && tty != NULL) {
+- // tty->print_cr("os::free %p", memblock);
+- fprintf(stderr, "os::free " PTR_FORMAT "\n", (uintptr_t)memblock);
++
++ GuardedMemory guarded(membase);
++ size_t size = guarded.get_user_size();
++ inc_stat_counter(&free_bytes, size);
++ membase = guarded.release_for_freeing();
++ if (PrintMalloc && tty != NULL) {
++ fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, (uintptr_t)membase);
+ }
++ ::free(membase);
++#else
++ void* membase = MemTracker::record_free(memblock);
++ ::free(membase);
+ #endif
+- MemTracker::record_free((address)memblock, memflags);
+-
+- ::free((char*)memblock - space_before);
+ }
+
+ void os::init_random(long initval) {
+@@ -1519,7 +1426,7 @@
+ char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
+ char* result = pd_reserve_memory(bytes, addr, alignment_hint);
+ if (result != NULL) {
+- MemTracker::record_virtual_memory_reserve((address)result, bytes, mtNone, CALLER_PC);
++ MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
+ }
+
+ return result;
+@@ -1529,7 +1436,7 @@
+ MEMFLAGS flags) {
+ char* result = pd_reserve_memory(bytes, addr, alignment_hint);
+ if (result != NULL) {
+- MemTracker::record_virtual_memory_reserve((address)result, bytes, mtNone, CALLER_PC);
++ MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
+ MemTracker::record_virtual_memory_type((address)result, flags);
+ }
+
+@@ -1539,7 +1446,7 @@
+ char* os::attempt_reserve_memory_at(size_t bytes, char* addr) {
+ char* result = pd_attempt_reserve_memory_at(bytes, addr);
+ if (result != NULL) {
+- MemTracker::record_virtual_memory_reserve((address)result, bytes, mtNone, CALLER_PC);
++ MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
+ }
+ return result;
+ }
+@@ -1579,23 +1486,29 @@
+ }
+
+ bool os::uncommit_memory(char* addr, size_t bytes) {
+- MemTracker::Tracker tkr = MemTracker::get_virtual_memory_uncommit_tracker();
+- bool res = pd_uncommit_memory(addr, bytes);
+- if (res) {
+- tkr.record((address)addr, bytes);
++ bool res;
++ if (MemTracker::tracking_level() > NMT_minimal) {
++ Tracker tkr = MemTracker::get_virtual_memory_uncommit_tracker();
++ res = pd_uncommit_memory(addr, bytes);
++ if (res) {
++ tkr.record((address)addr, bytes);
++ }
+ } else {
+- tkr.discard();
++ res = pd_uncommit_memory(addr, bytes);
+ }
+ return res;
+ }
+
+ bool os::release_memory(char* addr, size_t bytes) {
+- MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
+- bool res = pd_release_memory(addr, bytes);
+- if (res) {
+- tkr.record((address)addr, bytes);
++ bool res;
++ if (MemTracker::tracking_level() > NMT_minimal) {
++ Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
++ res = pd_release_memory(addr, bytes);
++ if (res) {
++ tkr.record((address)addr, bytes);
++ }
+ } else {
+- tkr.discard();
++ res = pd_release_memory(addr, bytes);
+ }
+ return res;
+ }
+@@ -1606,7 +1519,7 @@
+ bool allow_exec) {
+ char* result = pd_map_memory(fd, file_name, file_offset, addr, bytes, read_only, allow_exec);
+ if (result != NULL) {
+- MemTracker::record_virtual_memory_reserve_and_commit((address)result, bytes, mtNone, CALLER_PC);
++ MemTracker::record_virtual_memory_reserve_and_commit((address)result, bytes, CALLER_PC);
+ }
+ return result;
+ }
+@@ -1619,12 +1532,15 @@
+ }
+
+ bool os::unmap_memory(char *addr, size_t bytes) {
+- MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
+- bool result = pd_unmap_memory(addr, bytes);
+- if (result) {
+- tkr.record((address)addr, bytes);
++ bool result;
++ if (MemTracker::tracking_level() > NMT_minimal) {
++ Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
++ result = pd_unmap_memory(addr, bytes);
++ if (result) {
++ tkr.record((address)addr, bytes);
++ }
+ } else {
+- tkr.discard();
++ result = pd_unmap_memory(addr, bytes);
+ }
+ return result;
+ }
+--- ./hotspot/src/share/vm/runtime/os.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/os.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -66,6 +66,8 @@
+ class Event;
+ class DLL;
+ class FileHandle;
++class NativeCallStack;
++
+ template<class E> class GrowableArray;
+
+ // %%%%% Moved ThreadState, START_FN, OSThread to new osThread.hpp. -- Rose
+@@ -97,9 +99,11 @@
+ // Typedef for structured exception handling support
+ typedef void (*java_call_t)(JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread);
+
++class MallocTracker;
++
+ class os: AllStatic {
+ friend class VMStructs;
+-
++ friend class MallocTracker;
+ public:
+ enum { page_sizes_max = 9 }; // Size of _page_sizes array (8 plus a sentinel)
+
+@@ -161,7 +165,10 @@
+ // Override me as needed
+ static int file_name_strcmp(const char* s1, const char* s2);
+
++ // get/unset environment variable
+ static bool getenv(const char* name, char* buffer, int len);
++ static bool unsetenv(const char* name);
++
+ static bool have_special_privileges();
+
+ static jlong javaTimeMillis();
+@@ -207,8 +214,14 @@
+
+ // Interface for detecting multiprocessor system
+ static inline bool is_MP() {
+- assert(_processor_count > 0, "invalid processor count");
+- return _processor_count > 1 || AssumeMP;
++ // During bootstrap if _processor_count is not yet initialized
++ // we claim to be MP as that is safest. If any platform has a
++ // stub generator that might be triggered in this phase and for
++ // which being declared MP when in fact not, is a problem - then
++ // the bootstrap routine for the stub generator needs to check
++ // the processor count directly and leave the bootstrap routine
++ // in place until called after initialization has ocurred.
++ return (_processor_count != 1) || AssumeMP;
+ }
+ static julong available_memory();
+ static julong physical_memory();
+@@ -651,12 +664,20 @@
+ static void* thread_local_storage_at(int index);
+ static void free_thread_local_storage(int index);
+
+- // Stack walk
+- static address get_caller_pc(int n = 0);
++ // Retrieve native stack frames.
++ // Parameter:
++ // stack: an array to storage stack pointers.
++ // frames: size of above array.
++ // toSkip: number of stack frames to skip at the beginning.
++ // Return: number of stack frames captured.
++ static int get_native_stack(address* stack, int size, int toSkip = 0);
+
+ // General allocation (must be MT-safe)
+- static void* malloc (size_t size, MEMFLAGS flags, address caller_pc = 0);
+- static void* realloc (void *memblock, size_t size, MEMFLAGS flags, address caller_pc = 0);
++ static void* malloc (size_t size, MEMFLAGS flags, const NativeCallStack& stack);
++ static void* malloc (size_t size, MEMFLAGS flags);
++ static void* realloc (void *memblock, size_t size, MEMFLAGS flag, const NativeCallStack& stack);
++ static void* realloc (void *memblock, size_t size, MEMFLAGS flag);
++
+ static void free (void *memblock, MEMFLAGS flags = mtNone);
+ static bool check_heap(bool force = false); // verify C heap integrity
+ static char* strdup(const char *, MEMFLAGS flags = mtInternal); // Like strdup
+--- ./hotspot/src/share/vm/runtime/perfMemory.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/perfMemory.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,6 +28,7 @@
+ #include "runtime/java.hpp"
+ #include "runtime/mutex.hpp"
+ #include "runtime/mutexLocker.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/os.hpp"
+ #include "runtime/perfData.hpp"
+ #include "runtime/perfMemory.hpp"
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/runtime/prefetch.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,73 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_RUNTIME_PREFETCH_INLINE_HPP
++#define SHARE_VM_RUNTIME_PREFETCH_INLINE_HPP
++
++#include "runtime/prefetch.hpp"
++
++// Linux
++#ifdef TARGET_OS_ARCH_linux_x86
++# include "prefetch_linux_x86.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_linux_sparc
++# include "prefetch_linux_sparc.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_linux_zero
++# include "prefetch_linux_zero.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_linux_arm
++# include "prefetch_linux_arm.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_linux_ppc
++# include "prefetch_linux_ppc.inline.hpp"
++#endif
++
++// Solaris
++#ifdef TARGET_OS_ARCH_solaris_x86
++# include "prefetch_solaris_x86.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_solaris_sparc
++# include "prefetch_solaris_sparc.inline.hpp"
++#endif
++
++// Windows
++#ifdef TARGET_OS_ARCH_windows_x86
++# include "prefetch_windows_x86.inline.hpp"
++#endif
++
++// AIX
++#ifdef TARGET_OS_ARCH_aix_ppc
++# include "prefetch_aix_ppc.inline.hpp"
++#endif
++
++// BSD
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "prefetch_bsd_x86.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_bsd_zero
++# include "prefetch_bsd_zero.inline.hpp"
++#endif
++
++#endif // SHARE_VM_RUNTIME_PREFETCH_INLINE_HPP
+--- ./hotspot/src/share/vm/runtime/safepoint.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/safepoint.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -41,6 +41,7 @@
+ #include "runtime/frame.inline.hpp"
+ #include "runtime/interfaceSupport.hpp"
+ #include "runtime/mutexLocker.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/osThread.hpp"
+ #include "runtime/safepoint.hpp"
+ #include "runtime/signature.hpp"
+@@ -49,7 +50,6 @@
+ #include "runtime/sweeper.hpp"
+ #include "runtime/synchronizer.hpp"
+ #include "runtime/thread.inline.hpp"
+-#include "services/memTracker.hpp"
+ #include "services/runtimeService.hpp"
+ #include "utilities/events.hpp"
+ #include "utilities/macros.hpp"
+@@ -75,7 +75,7 @@
+ #endif
+ #if INCLUDE_ALL_GCS
+ #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
+-#include "gc_implementation/shared/concurrentGCThread.hpp"
++#include "gc_implementation/shared/suspendibleThreadSet.hpp"
+ #endif // INCLUDE_ALL_GCS
+ #ifdef COMPILER1
+ #include "c1/c1_globals.hpp"
+@@ -112,7 +112,7 @@
+ // more-general mechanism below. DLD (01/05).
+ ConcurrentMarkSweepThread::synchronize(false);
+ } else if (UseG1GC) {
+- ConcurrentGCThread::safepoint_synchronize();
++ SuspendibleThreadSet::synchronize();
+ }
+ #endif // INCLUDE_ALL_GCS
+
+@@ -488,7 +488,7 @@
+ if (UseConcMarkSweepGC) {
+ ConcurrentMarkSweepThread::desynchronize(false);
+ } else if (UseG1GC) {
+- ConcurrentGCThread::safepoint_desynchronize();
++ SuspendibleThreadSet::desynchronize();
+ }
+ #endif // INCLUDE_ALL_GCS
+ // record this time so VMThread can keep track how much time has elasped
+@@ -546,10 +546,6 @@
+ TraceTime t7("purging class loader data graph", TraceSafepointCleanupTime);
+ ClassLoaderDataGraph::purge_if_needed();
+ }
+-
+- if (MemTracker::is_on()) {
+- MemTracker::sync();
+- }
+ }
+
+
+--- ./hotspot/src/share/vm/runtime/serviceThread.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/serviceThread.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,6 +28,7 @@
+ #include "runtime/serviceThread.hpp"
+ #include "runtime/mutexLocker.hpp"
+ #include "prims/jvmtiImpl.hpp"
++#include "services/allocationContextService.hpp"
+ #include "services/gcNotifier.hpp"
+ #include "services/diagnosticArgument.hpp"
+ #include "services/diagnosticFramework.hpp"
+@@ -86,6 +87,7 @@
+ bool has_jvmti_events = false;
+ bool has_gc_notification_event = false;
+ bool has_dcmd_notification_event = false;
++ bool acs_notify = false;
+ JvmtiDeferredEvent jvmti_event;
+ {
+ // Need state transition ThreadBlockInVM so that this thread
+@@ -102,7 +104,8 @@
+ while (!(sensors_changed = LowMemoryDetector::has_pending_requests()) &&
+ !(has_jvmti_events = JvmtiDeferredEventQueue::has_events()) &&
+ !(has_gc_notification_event = GCNotifier::has_event()) &&
+- !(has_dcmd_notification_event = DCmdFactory::has_pending_jmx_notification())) {
++ !(has_dcmd_notification_event = DCmdFactory::has_pending_jmx_notification()) &&
++ !(acs_notify = AllocationContextService::should_notify())) {
+ // wait until one of the sensors has pending requests, or there is a
+ // pending JVMTI event or JMX GC notification to post
+ Service_lock->wait(Mutex::_no_safepoint_check_flag);
+@@ -128,6 +131,10 @@
+ if(has_dcmd_notification_event) {
+ DCmdFactory::send_notification(CHECK);
+ }
++
++ if (acs_notify) {
++ AllocationContextService::notify(CHECK);
++ }
+ }
+ }
+
+--- ./hotspot/src/share/vm/runtime/sharedRuntime.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/sharedRuntime.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -482,6 +482,7 @@
+
+ address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* thread, address return_address) {
+ assert(frame::verify_return_pc(return_address), err_msg("must be a return address: " INTPTR_FORMAT, return_address));
++ assert(thread->frames_to_pop_failed_realloc() == 0 || Interpreter::contains(return_address), "missed frames to pop?");
+
+ // Reset method handle flag.
+ thread->set_is_method_handle_return(false);
+@@ -1209,10 +1210,7 @@
+ (!is_virtual && invoke_code == Bytecodes::_invokedynamic) ||
+ ( is_virtual && invoke_code != Bytecodes::_invokestatic ), "inconsistent bytecode");
+
+- // We do not patch the call site if the caller nmethod has been made non-entrant.
+- if (!caller_nm->is_in_use()) {
+- return callee_method;
+- }
++ assert(caller_nm->is_alive(), "It should be alive");
+
+ #ifndef PRODUCT
+ // tracing/debugging/statistics
+@@ -1282,13 +1280,11 @@
+
+ // Now that we are ready to patch if the Method* was redefined then
+ // don't update call site and let the caller retry.
+- // Don't update call site if caller nmethod has been made non-entrant
+- // as it is a waste of time.
+ // Don't update call site if callee nmethod was unloaded or deoptimized.
+ // Don't update call site if callee nmethod was replaced by an other nmethod
+ // which may happen when multiply alive nmethod (tiered compilation)
+ // will be supported.
+- if (!callee_method->is_old() && caller_nm->is_in_use() &&
++ if (!callee_method->is_old() &&
+ (callee_nm == NULL || callee_nm->is_in_use() && (callee_method->code() == callee_nm))) {
+ #ifdef ASSERT
+ // We must not try to patch to jump to an already unloaded method.
+@@ -1489,14 +1485,12 @@
+ // out of scope.
+ JvmtiDynamicCodeEventCollector event_collector;
+
+- // Update inline cache to megamorphic. Skip update if caller has been
+- // made non-entrant or we are called from interpreted.
++ // Update inline cache to megamorphic. Skip update if we are called from interpreted.
+ { MutexLocker ml_patch (CompiledIC_lock);
+ RegisterMap reg_map(thread, false);
+ frame caller_frame = thread->last_frame().sender(&reg_map);
+ CodeBlob* cb = caller_frame.cb();
+- if (cb->is_nmethod() && ((nmethod*)cb)->is_in_use()) {
+- // Not a non-entrant nmethod, so find inline_cache
++ if (cb->is_nmethod()) {
+ CompiledIC* inline_cache = CompiledIC_before(((nmethod*)cb), caller_frame.pc());
+ bool should_be_mono = false;
+ if (inline_cache->is_optimized()) {
+@@ -1639,19 +1633,13 @@
+ // resolve is only done once.
+
+ MutexLocker ml(CompiledIC_lock);
+- //
+- // We do not patch the call site if the nmethod has been made non-entrant
+- // as it is a waste of time
+- //
+- if (caller_nm->is_in_use()) {
+- if (is_static_call) {
+- CompiledStaticCall* ssc= compiledStaticCall_at(call_addr);
+- ssc->set_to_clean();
+- } else {
+- // compiled, dispatched call (which used to call an interpreted method)
+- CompiledIC* inline_cache = CompiledIC_at(caller_nm, call_addr);
+- inline_cache->set_to_clean();
+- }
++ if (is_static_call) {
++ CompiledStaticCall* ssc= compiledStaticCall_at(call_addr);
++ ssc->set_to_clean();
++ } else {
++ // compiled, dispatched call (which used to call an interpreted method)
++ CompiledIC* inline_cache = CompiledIC_at(caller_nm, call_addr);
++ inline_cache->set_to_clean();
+ }
+ }
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/runtime/sharedRuntimeMath.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,130 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_RUNTIME_SHAREDRUNTIMEMATH_HPP
++#define SHARE_VM_RUNTIME_SHAREDRUNTIMEMATH_HPP
++
++#include <math.h>
++
++// Used to access the lower/higher 32 bits of a double
++typedef union {
++ double d;
++ struct {
++#ifdef VM_LITTLE_ENDIAN
++ int lo;
++ int hi;
++#else
++ int hi;
++ int lo;
++#endif
++ } split;
++} DoubleIntConv;
++
++static inline int high(double d) {
++ DoubleIntConv x;
++ x.d = d;
++ return x.split.hi;
++}
++
++static inline int low(double d) {
++ DoubleIntConv x;
++ x.d = d;
++ return x.split.lo;
++}
++
++static inline void set_high(double* d, int high) {
++ DoubleIntConv conv;
++ conv.d = *d;
++ conv.split.hi = high;
++ *d = conv.d;
++}
++
++static inline void set_low(double* d, int low) {
++ DoubleIntConv conv;
++ conv.d = *d;
++ conv.split.lo = low;
++ *d = conv.d;
++}
++
++static double copysignA(double x, double y) {
++ DoubleIntConv convX;
++ convX.d = x;
++ convX.split.hi = (convX.split.hi & 0x7fffffff) | (high(y) & 0x80000000);
++ return convX.d;
++}
++
++/*
++ * ====================================================
++ * Copyright (c) 1998 Oracle and/or its affiliates. All rights reserved.
++ *
++ * Developed at SunSoft, a Sun Microsystems, Inc. business.
++ * Permission to use, copy, modify, and distribute this
++ * software is freely granted, provided that this notice
++ * is preserved.
++ * ====================================================
++ */
++
++/*
++ * scalbn (double x, int n)
++ * scalbn(x,n) returns x* 2**n computed by exponent
++ * manipulation rather than by actually performing an
++ * exponentiation or a multiplication.
++ */
++
++static const double
++two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
++twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
++hugeX = 1.0e+300,
++tiny = 1.0e-300;
++
++static double scalbnA(double x, int n) {
++ int k,hx,lx;
++ hx = high(x);
++ lx = low(x);
++ k = (hx&0x7ff00000)>>20; /* extract exponent */
++ if (k==0) { /* 0 or subnormal x */
++ if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
++ x *= two54;
++ hx = high(x);
++ k = ((hx&0x7ff00000)>>20) - 54;
++ if (n< -50000) return tiny*x; /*underflow*/
++ }
++ if (k==0x7ff) return x+x; /* NaN or Inf */
++ k = k+n;
++ if (k > 0x7fe) return hugeX*copysignA(hugeX,x); /* overflow */
++ if (k > 0) { /* normal result */
++ set_high(&x, (hx&0x800fffff)|(k<<20));
++ return x;
++ }
++ if (k <= -54) {
++ if (n > 50000) /* in case integer overflow in n+k */
++ return hugeX*copysignA(hugeX,x); /*overflow*/
++ else return tiny*copysignA(tiny,x); /*underflow*/
++ }
++ k += 54; /* subnormal result */
++ set_high(&x, (hx&0x800fffff)|(k<<20));
++ return x*twom54;
++}
++
++#endif // SHARE_VM_RUNTIME_SHAREDRUNTIMEMATH_HPP
+--- ./hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -40,81 +40,11 @@
+ // generated; can not figure out how to turn down optimization for one
+ // file in the IDE on Windows
+ #ifdef WIN32
++# pragma warning( disable: 4748 ) // /GS can not protect parameters and local variables from local buffer overrun because optimizations are disabled in function
+ # pragma optimize ( "", off )
+ #endif
+
+-#include <math.h>
+-
+-// VM_LITTLE_ENDIAN is #defined appropriately in the Makefiles
+-// [jk] this is not 100% correct because the float word order may different
+-// from the byte order (e.g. on ARM)
+-#ifdef VM_LITTLE_ENDIAN
+-# define __HI(x) *(1+(int*)&x)
+-# define __LO(x) *(int*)&x
+-#else
+-# define __HI(x) *(int*)&x
+-# define __LO(x) *(1+(int*)&x)
+-#endif
+-
+-#if !defined(AIX)
+-double copysign(double x, double y) {
+- __HI(x) = (__HI(x)&0x7fffffff)|(__HI(y)&0x80000000);
+- return x;
+-}
+-#endif
+-
+-/*
+- * ====================================================
+- * Copyright (c) 1998 Oracle and/or its affiliates. All rights reserved.
+- *
+- * Developed at SunSoft, a Sun Microsystems, Inc. business.
+- * Permission to use, copy, modify, and distribute this
+- * software is freely granted, provided that this notice
+- * is preserved.
+- * ====================================================
+- */
+-
+-/*
+- * scalbn (double x, int n)
+- * scalbn(x,n) returns x* 2**n computed by exponent
+- * manipulation rather than by actually performing an
+- * exponentiation or a multiplication.
+- */
+-
+-static const double
+-two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+- twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
+- hugeX = 1.0e+300,
+- tiny = 1.0e-300;
+-
+-#if !defined(AIX)
+-double scalbn (double x, int n) {
+- int k,hx,lx;
+- hx = __HI(x);
+- lx = __LO(x);
+- k = (hx&0x7ff00000)>>20; /* extract exponent */
+- if (k==0) { /* 0 or subnormal x */
+- if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
+- x *= two54;
+- hx = __HI(x);
+- k = ((hx&0x7ff00000)>>20) - 54;
+- if (n< -50000) return tiny*x; /*underflow*/
+- }
+- if (k==0x7ff) return x+x; /* NaN or Inf */
+- k = k+n;
+- if (k > 0x7fe) return hugeX*copysign(hugeX,x); /* overflow */
+- if (k > 0) /* normal result */
+- {__HI(x) = (hx&0x800fffff)|(k<<20); return x;}
+- if (k <= -54) {
+- if (n > 50000) /* in case integer overflow in n+k */
+- return hugeX*copysign(hugeX,x); /*overflow*/
+- else return tiny*copysign(tiny,x); /*underflow*/
+- }
+- k += 54; /* subnormal result */
+- __HI(x) = (hx&0x800fffff)|(k<<20);
+- return x*twom54;
+-}
+-#endif
++#include "runtime/sharedRuntimeMath.hpp"
+
+ /* __ieee754_log(x)
+ * Return the logrithm of x
+@@ -185,8 +115,8 @@
+ int k,hx,i,j;
+ unsigned lx;
+
+- hx = __HI(x); /* high word of x */
+- lx = __LO(x); /* low word of x */
++ hx = high(x); /* high word of x */
++ lx = low(x); /* low word of x */
+
+ k=0;
+ if (hx < 0x00100000) { /* x < 2**-1022 */
+@@ -194,13 +124,13 @@
+ return -two54/zero; /* log(+-0)=-inf */
+ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
+ k -= 54; x *= two54; /* subnormal number, scale up x */
+- hx = __HI(x); /* high word of x */
++ hx = high(x); /* high word of x */
+ }
+ if (hx >= 0x7ff00000) return x+x;
+ k += (hx>>20)-1023;
+ hx &= 0x000fffff;
+ i = (hx+0x95f64)&0x100000;
+- __HI(x) = hx|(i^0x3ff00000); /* normalize x or x/2 */
++ set_high(&x, hx|(i^0x3ff00000)); /* normalize x or x/2 */
+ k += (i>>20);
+ f = x-1.0;
+ if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */
+@@ -279,8 +209,8 @@
+ int i,k,hx;
+ unsigned lx;
+
+- hx = __HI(x); /* high word of x */
+- lx = __LO(x); /* low word of x */
++ hx = high(x); /* high word of x */
++ lx = low(x); /* low word of x */
+
+ k=0;
+ if (hx < 0x00100000) { /* x < 2**-1022 */
+@@ -288,14 +218,14 @@
+ return -two54/zero; /* log(+-0)=-inf */
+ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
+ k -= 54; x *= two54; /* subnormal number, scale up x */
+- hx = __HI(x); /* high word of x */
++ hx = high(x); /* high word of x */
+ }
+ if (hx >= 0x7ff00000) return x+x;
+ k += (hx>>20)-1023;
+ i = ((unsigned)k&0x80000000)>>31;
+ hx = (hx&0x000fffff)|((0x3ff-i)<<20);
+ y = (double)(k+i);
+- __HI(x) = hx;
++ set_high(&x, hx);
+ z = y*log10_2lo + ivln10*__ieee754_log(x);
+ return z+y*log10_2hi;
+ }
+@@ -390,14 +320,14 @@
+ int k=0,xsb;
+ unsigned hx;
+
+- hx = __HI(x); /* high word of x */
++ hx = high(x); /* high word of x */
+ xsb = (hx>>31)&1; /* sign bit of x */
+ hx &= 0x7fffffff; /* high word of |x| */
+
+ /* filter out non-finite argument */
+ if(hx >= 0x40862E42) { /* if |x|>=709.78... */
+ if(hx>=0x7ff00000) {
+- if(((hx&0xfffff)|__LO(x))!=0)
++ if(((hx&0xfffff)|low(x))!=0)
+ return x+x; /* NaN */
+ else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */
+ }
+@@ -428,10 +358,10 @@
+ if(k==0) return one-((x*c)/(c-2.0)-x);
+ else y = one-((lo-(x*c)/(2.0-c))-hi);
+ if(k >= -1021) {
+- __HI(y) += (k<<20); /* add k to y's exponent */
++ set_high(&y, high(y) + (k<<20)); /* add k to y's exponent */
+ return y;
+ } else {
+- __HI(y) += ((k+1000)<<20);/* add k to y's exponent */
++ set_high(&y, high(y) + ((k+1000)<<20)); /* add k to y's exponent */
+ return y*twom1000;
+ }
+ }
+@@ -518,8 +448,8 @@
+ unsigned lx,ly;
+
+ i0 = ((*(int*)&one)>>29)^1; i1=1-i0;
+- hx = __HI(x); lx = __LO(x);
+- hy = __HI(y); ly = __LO(y);
++ hx = high(x); lx = low(x);
++ hy = high(y); ly = low(y);
+ ix = hx&0x7fffffff; iy = hy&0x7fffffff;
+
+ /* y==zero: x**0 = 1 */
+@@ -619,14 +549,14 @@
+ u = ivln2_h*t; /* ivln2_h has 21 sig. bits */
+ v = t*ivln2_l-w*ivln2;
+ t1 = u+v;
+- __LO(t1) = 0;
++ set_low(&t1, 0);
+ t2 = v-(t1-u);
+ } else {
+ double ss,s2,s_h,s_l,t_h,t_l;
+ n = 0;
+ /* take care subnormal number */
+ if(ix<0x00100000)
+- {ax *= two53; n -= 53; ix = __HI(ax); }
++ {ax *= two53; n -= 53; ix = high(ax); }
+ n += ((ix)>>20)-0x3ff;
+ j = ix&0x000fffff;
+ /* determine interval */
+@@ -634,17 +564,17 @@
+ if(j<=0x3988E) k=0; /* |x|<sqrt(3/2) */
+ else if(j<0xBB67A) k=1; /* |x|<sqrt(3) */
+ else {k=0;n+=1;ix -= 0x00100000;}
+- __HI(ax) = ix;
++ set_high(&ax, ix);
+
+ /* compute ss = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+ u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
+ v = one/(ax+bp[k]);
+ ss = u*v;
+ s_h = ss;
+- __LO(s_h) = 0;
++ set_low(&s_h, 0);
+ /* t_h=ax+bp[k] High */
+ t_h = zeroX;
+- __HI(t_h)=((ix>>1)|0x20000000)+0x00080000+(k<<18);
++ set_high(&t_h, ((ix>>1)|0x20000000)+0x00080000+(k<<18));
+ t_l = ax - (t_h-bp[k]);
+ s_l = v*((u-s_h*t_h)-s_h*t_l);
+ /* compute log(ax) */
+@@ -653,32 +583,32 @@
+ r += s_l*(s_h+ss);
+ s2 = s_h*s_h;
+ t_h = 3.0+s2+r;
+- __LO(t_h) = 0;
++ set_low(&t_h, 0);
+ t_l = r-((t_h-3.0)-s2);
+ /* u+v = ss*(1+...) */
+ u = s_h*t_h;
+ v = s_l*t_h+t_l*ss;
+ /* 2/(3log2)*(ss+...) */
+ p_h = u+v;
+- __LO(p_h) = 0;
++ set_low(&p_h, 0);
+ p_l = v-(p_h-u);
+ z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
+ z_l = cp_l*p_h+p_l*cp+dp_l[k];
+ /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+ t = (double)n;
+ t1 = (((z_h+z_l)+dp_h[k])+t);
+- __LO(t1) = 0;
++ set_low(&t1, 0);
+ t2 = z_l-(((t1-t)-dp_h[k])-z_h);
+ }
+
+ /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+ y1 = y;
+- __LO(y1) = 0;
++ set_low(&y1, 0);
+ p_l = (y-y1)*t1+y*t2;
+ p_h = y1*t1;
+ z = p_l+p_h;
+- j = __HI(z);
+- i = __LO(z);
++ j = high(z);
++ i = low(z);
+ if (j>=0x40900000) { /* z >= 1024 */
+ if(((j-0x40900000)|i)!=0) /* if z > 1024 */
+ return s*hugeX*hugeX; /* overflow */
+@@ -702,13 +632,13 @@
+ n = j+(0x00100000>>(k+1));
+ k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */
+ t = zeroX;
+- __HI(t) = (n&~(0x000fffff>>k));
++ set_high(&t, (n&~(0x000fffff>>k)));
+ n = ((n&0x000fffff)|0x00100000)>>(20-k);
+ if(j<0) n = -n;
+ p_h -= t;
+ }
+ t = p_l+p_h;
+- __LO(t) = 0;
++ set_low(&t, 0);
+ u = t*lg2_h;
+ v = (p_l-(t-p_h))*lg2+t*lg2_l;
+ z = u+v;
+@@ -717,10 +647,10 @@
+ t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+ r = (z*t1)/(t1-two)-(w+z*w);
+ z = one-(r-z);
+- j = __HI(z);
++ j = high(z);
+ j += (n<<20);
+- if((j>>20)<=0) z = scalbn(z,n); /* subnormal output */
+- else __HI(z) += (n<<20);
++ if((j>>20)<=0) z = scalbnA(z,n); /* subnormal output */
++ else set_high(&z, high(z) + (n<<20));
+ return s*z;
+ }
+
+--- ./hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -63,63 +63,7 @@
+ #define SAFEBUF
+ #endif
+
+-#include <math.h>
+-
+-// VM_LITTLE_ENDIAN is #defined appropriately in the Makefiles
+-// [jk] this is not 100% correct because the float word order may different
+-// from the byte order (e.g. on ARM)
+-#ifdef VM_LITTLE_ENDIAN
+-# define __HI(x) *(1+(int*)&x)
+-# define __LO(x) *(int*)&x
+-#else
+-# define __HI(x) *(int*)&x
+-# define __LO(x) *(1+(int*)&x)
+-#endif
+-
+-static double copysignA(double x, double y) {
+- __HI(x) = (__HI(x)&0x7fffffff)|(__HI(y)&0x80000000);
+- return x;
+-}
+-
+-/*
+- * scalbn (double x, int n)
+- * scalbn(x,n) returns x* 2**n computed by exponent
+- * manipulation rather than by actually performing an
+- * exponentiation or a multiplication.
+- */
+-
+-static const double
+-two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+-twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
+-hugeX = 1.0e+300,
+-tiny = 1.0e-300;
+-
+-static double scalbnA (double x, int n) {
+- int k,hx,lx;
+- hx = __HI(x);
+- lx = __LO(x);
+- k = (hx&0x7ff00000)>>20; /* extract exponent */
+- if (k==0) { /* 0 or subnormal x */
+- if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
+- x *= two54;
+- hx = __HI(x);
+- k = ((hx&0x7ff00000)>>20) - 54;
+- if (n< -50000) return tiny*x; /*underflow*/
+- }
+- if (k==0x7ff) return x+x; /* NaN or Inf */
+- k = k+n;
+- if (k > 0x7fe) return hugeX*copysignA(hugeX,x); /* overflow */
+- if (k > 0) /* normal result */
+- {__HI(x) = (hx&0x800fffff)|(k<<20); return x;}
+- if (k <= -54) {
+- if (n > 50000) /* in case integer overflow in n+k */
+- return hugeX*copysignA(hugeX,x); /*overflow*/
+- else return tiny*copysignA(tiny,x); /*underflow*/
+- }
+- k += 54; /* subnormal result */
+- __HI(x) = (hx&0x800fffff)|(k<<20);
+- return x*twom54;
+-}
++#include "runtime/sharedRuntimeMath.hpp"
+
+ /*
+ * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
+@@ -603,7 +547,7 @@
+ {
+ double z,r,v;
+ int ix;
+- ix = __HI(x)&0x7fffffff; /* high word of x */
++ ix = high(x)&0x7fffffff; /* high word of x */
+ if(ix<0x3e400000) /* |x| < 2**-27 */
+ {if((int)x==0) return x;} /* generate inexact */
+ z = x*x;
+@@ -658,9 +602,9 @@
+
+ static double __kernel_cos(double x, double y)
+ {
+- double a,h,z,r,qx;
++ double a,h,z,r,qx=0;
+ int ix;
+- ix = __HI(x)&0x7fffffff; /* ix = |x|'s high word*/
++ ix = high(x)&0x7fffffff; /* ix = |x|'s high word*/
+ if(ix<0x3e400000) { /* if x < 2**27 */
+ if(((int)x)==0) return one; /* generate inexact */
+ }
+@@ -672,8 +616,8 @@
+ if(ix > 0x3fe90000) { /* x > 0.78125 */
+ qx = 0.28125;
+ } else {
+- __HI(qx) = ix-0x00200000; /* x/4 */
+- __LO(qx) = 0;
++ set_high(&qx, ix-0x00200000); /* x/4 */
++ set_low(&qx, 0);
+ }
+ h = 0.5*z-qx;
+ a = one-qx;
+@@ -738,11 +682,11 @@
+ {
+ double z,r,v,w,s;
+ int ix,hx;
+- hx = __HI(x); /* high word of x */
++ hx = high(x); /* high word of x */
+ ix = hx&0x7fffffff; /* high word of |x| */
+ if(ix<0x3e300000) { /* x < 2**-28 */
+ if((int)x==0) { /* generate inexact */
+- if (((ix | __LO(x)) | (iy + 1)) == 0)
++ if (((ix | low(x)) | (iy + 1)) == 0)
+ return one / fabsd(x);
+ else {
+ if (iy == 1)
+@@ -751,10 +695,10 @@
+ double a, t;
+
+ z = w = x + y;
+- __LO(z) = 0;
++ set_low(&z, 0);
+ v = y - (z - x);
+ t = a = -one / w;
+- __LO(t) = 0;
++ set_low(&t, 0);
+ s = one + t * z;
+ return t + a * (s + t * v);
+ }
+@@ -789,10 +733,10 @@
+ /* compute -1.0/(x+r) accurately */
+ double a,t;
+ z = w;
+- __LO(z) = 0;
++ set_low(&z, 0);
+ v = r-(z - x); /* z+v = r+x */
+ t = a = -1.0/w; /* a = -1.0/w */
+- __LO(t) = 0;
++ set_low(&t, 0);
+ s = 1.0+t*z;
+ return t+a*(s+t*v);
+ }
+@@ -841,7 +785,7 @@
+ int n, ix;
+
+ /* High word of x. */
+- ix = __HI(x);
++ ix = high(x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+@@ -899,7 +843,7 @@
+ int n, ix;
+
+ /* High word of x. */
+- ix = __HI(x);
++ ix = high(x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+@@ -956,7 +900,7 @@
+ int n, ix;
+
+ /* High word of x. */
+- ix = __HI(x);
++ ix = high(x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+--- ./hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -196,7 +196,6 @@
+ // Don't trigger other compiles in testing mode
+ return NULL;
+ }
+- nmethod *osr_nm = NULL;
+
+ handle_counter_overflow(method());
+ if (method() != inlinee()) {
+@@ -210,14 +209,16 @@
+ if (bci == InvocationEntryBci) {
+ method_invocation_event(method, inlinee, comp_level, nm, thread);
+ } else {
++ // method == inlinee if the event originated in the main method
+ method_back_branch_event(method, inlinee, bci, comp_level, nm, thread);
+- // method == inlinee if the event originated in the main method
+- int highest_level = inlinee->highest_osr_comp_level();
+- if (highest_level > comp_level) {
+- osr_nm = inlinee->lookup_osr_nmethod_for(bci, highest_level, false);
++ // Check if event led to a higher level OSR compilation
++ nmethod* osr_nm = inlinee->lookup_osr_nmethod_for(bci, comp_level, false);
++ if (osr_nm != NULL && osr_nm->comp_level() > comp_level) {
++ // Perform OSR with new nmethod
++ return osr_nm;
+ }
+ }
+- return osr_nm;
++ return NULL;
+ }
+
+ // Check if the method can be compiled, change level if necessary
+@@ -239,7 +240,7 @@
+ if (bci != InvocationEntryBci && mh->is_not_osr_compilable(level)) {
+ return;
+ }
+- if (!CompileBroker::compilation_is_in_queue(mh, bci)) {
++ if (!CompileBroker::compilation_is_in_queue(mh)) {
+ if (PrintTieredEvents) {
+ print_event(COMPILE, mh, mh, bci, level);
+ }
+@@ -378,7 +379,7 @@
+ // Handle the invocation event.
+ void SimpleThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh,
+ CompLevel level, nmethod* nm, JavaThread* thread) {
+- if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) {
++ if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh)) {
+ CompLevel next_level = call_event(mh(), level);
+ if (next_level != level) {
+ compile(mh, InvocationEntryBci, next_level, thread);
+@@ -391,8 +392,8 @@
+ void SimpleThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh,
+ int bci, CompLevel level, nmethod* nm, JavaThread* thread) {
+ // If the method is already compiling, quickly bail out.
+- if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, bci)) {
+- // Use loop event as an opportinity to also check there's been
++ if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh)) {
++ // Use loop event as an opportunity to also check there's been
+ // enough calls.
+ CompLevel cur_level = comp_level(mh());
+ CompLevel next_level = call_event(mh(), cur_level);
+--- ./hotspot/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -54,13 +54,17 @@
+ // Simple methods are as good being compiled with C1 as C2.
+ // Determine if a given method is such a case.
+ bool SimpleThresholdPolicy::is_trivial(Method* method) {
+- if (method->is_accessor()) return true;
+- if (method->code() != NULL) {
+- MethodData* mdo = method->method_data();
+- if (mdo != NULL && mdo->num_loops() == 0 &&
+- (method->code_size() < 5 || (mdo->num_blocks() < 4) && (method->code_size() < 15))) {
+- return !mdo->would_profile();
+- }
++ if (method->is_accessor() ||
++ method->is_constant_getter()) {
++ return true;
++ }
++ if (method->has_loops() || method->code_size() >= 15) {
++ return false;
++ }
++ MethodData* mdo = method->method_data();
++ if (mdo != NULL && !mdo->would_profile() &&
++ (method->code_size() < 5 || (mdo->num_blocks() < 4))) {
++ return true;
+ }
+ return false;
+ }
+--- ./hotspot/src/share/vm/runtime/stubRoutines.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/stubRoutines.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -125,9 +125,18 @@
+ address StubRoutines::_cipherBlockChaining_encryptAESCrypt = NULL;
+ address StubRoutines::_cipherBlockChaining_decryptAESCrypt = NULL;
+
++address StubRoutines::_sha1_implCompress = NULL;
++address StubRoutines::_sha1_implCompressMB = NULL;
++address StubRoutines::_sha256_implCompress = NULL;
++address StubRoutines::_sha256_implCompressMB = NULL;
++address StubRoutines::_sha512_implCompress = NULL;
++address StubRoutines::_sha512_implCompressMB = NULL;
++
+ address StubRoutines::_updateBytesCRC32 = NULL;
+ address StubRoutines::_crc_table_adr = NULL;
+
++address StubRoutines::_multiplyToLen = NULL;
++
+ double (* StubRoutines::_intrinsic_log )(double) = NULL;
+ double (* StubRoutines::_intrinsic_log10 )(double) = NULL;
+ double (* StubRoutines::_intrinsic_exp )(double) = NULL;
+--- ./hotspot/src/share/vm/runtime/stubRoutines.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/stubRoutines.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -207,9 +207,18 @@
+ static address _cipherBlockChaining_encryptAESCrypt;
+ static address _cipherBlockChaining_decryptAESCrypt;
+
++ static address _sha1_implCompress;
++ static address _sha1_implCompressMB;
++ static address _sha256_implCompress;
++ static address _sha256_implCompressMB;
++ static address _sha512_implCompress;
++ static address _sha512_implCompressMB;
++
+ static address _updateBytesCRC32;
+ static address _crc_table_adr;
+
++ static address _multiplyToLen;
++
+ // These are versions of the java.lang.Math methods which perform
+ // the same operations as the intrinsic version. They are used for
+ // constant folding in the compiler to ensure equivalence. If the
+@@ -356,9 +365,18 @@
+ static address cipherBlockChaining_encryptAESCrypt() { return _cipherBlockChaining_encryptAESCrypt; }
+ static address cipherBlockChaining_decryptAESCrypt() { return _cipherBlockChaining_decryptAESCrypt; }
+
++ static address sha1_implCompress() { return _sha1_implCompress; }
++ static address sha1_implCompressMB() { return _sha1_implCompressMB; }
++ static address sha256_implCompress() { return _sha256_implCompress; }
++ static address sha256_implCompressMB() { return _sha256_implCompressMB; }
++ static address sha512_implCompress() { return _sha512_implCompress; }
++ static address sha512_implCompressMB() { return _sha512_implCompressMB; }
++
+ static address updateBytesCRC32() { return _updateBytesCRC32; }
+ static address crc_table_addr() { return _crc_table_adr; }
+
++ static address multiplyToLen() {return _multiplyToLen; }
++
+ static address select_fill_function(BasicType t, bool aligned, const char* &name);
+
+ static address zero_aligned_words() { return _zero_aligned_words; }
+--- ./hotspot/src/share/vm/runtime/sweeper.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/sweeper.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -33,8 +33,10 @@
+ #include "runtime/atomic.hpp"
+ #include "runtime/compilationPolicy.hpp"
+ #include "runtime/mutexLocker.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/os.hpp"
+ #include "runtime/sweeper.hpp"
++#include "runtime/thread.inline.hpp"
+ #include "runtime/vm_operations.hpp"
+ #include "trace/tracing.hpp"
+ #include "utilities/events.hpp"
+--- ./hotspot/src/share/vm/runtime/thread.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/thread.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -58,6 +58,7 @@
+ #include "runtime/memprofiler.hpp"
+ #include "runtime/mutexLocker.hpp"
+ #include "runtime/objectMonitor.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "runtime/osThread.hpp"
+ #include "runtime/safepoint.hpp"
+ #include "runtime/sharedRuntime.hpp"
+@@ -233,6 +234,8 @@
+ // This initial value ==> never claimed.
+ _oops_do_parity = 0;
+
++ _metadata_on_stack_buffer = NULL;
++
+ // the handle mark links itself to last_handle_mark
+ new HandleMark(this);
+
+@@ -330,8 +333,7 @@
+ #if INCLUDE_NMT
+ // record thread's native stack, stack grows downward
+ address stack_low_addr = stack_base() - stack_size();
+- MemTracker::record_thread_stack(stack_low_addr, stack_size(), this,
+- CURRENT_PC);
++ MemTracker::record_thread_stack(stack_low_addr, stack_size());
+ #endif // INCLUDE_NMT
+ }
+
+@@ -349,7 +351,7 @@
+ #if INCLUDE_NMT
+ if (_stack_base != NULL) {
+ address low_stack_addr = stack_base() - stack_size();
+- MemTracker::release_thread_stack(low_stack_addr, stack_size(), this);
++ MemTracker::release_thread_stack(low_stack_addr, stack_size());
+ #ifdef ASSERT
+ set_stack_base(NULL);
+ #endif
+@@ -833,7 +835,7 @@
+ return false;
+ }
+
+-void Thread::oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf) {
++void Thread::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
+ active_handles()->oops_do(f);
+ // Do oop for ThreadShadow
+ f->do_oop((oop*)&_pending_exception);
+@@ -860,6 +862,7 @@
+ st->print("os_prio=%d ", os_prio);
+ }
+ st->print("tid=" INTPTR_FORMAT " ", this);
++ ext().print_on(st);
+ osthread()->print_on(st);
+ }
+ debug_only(if (WizardMode) print_owned_locks_on(st);)
+@@ -939,7 +942,7 @@
+ cur != VMOperationRequest_lock &&
+ cur != VMOperationQueue_lock) ||
+ cur->rank() == Mutex::special) {
+- warning("Thread holding lock at safepoint that vm can block on: %s", cur->name());
++ fatal(err_msg("Thread holding lock at safepoint that vm can block on: %s", cur->name()));
+ }
+ }
+ }
+@@ -1441,9 +1444,6 @@
+ set_monitor_chunks(NULL);
+ set_next(NULL);
+ set_thread_state(_thread_new);
+-#if INCLUDE_NMT
+- set_recorder(NULL);
+-#endif
+ _terminated = _not_terminated;
+ _privileged_stack_top = NULL;
+ _array_for_gc = NULL;
+@@ -1495,6 +1495,7 @@
+ _popframe_condition = popframe_inactive;
+ _popframe_preserved_args = NULL;
+ _popframe_preserved_args_size = 0;
++ _frames_to_pop_failed_realloc = 0;
+
+ pd_initialize();
+ }
+@@ -1518,7 +1519,6 @@
+ _jni_attach_state = _not_attaching_via_jni;
+ }
+ assert(deferred_card_mark().is_empty(), "Default MemRegion ctor");
+- _safepoint_visible = false;
+ }
+
+ bool JavaThread::reguard_stack(address cur_sp) {
+@@ -1581,7 +1581,6 @@
+ thr_type = entry_point == &compiler_thread_entry ? os::compiler_thread :
+ os::java_thread;
+ os::create_thread(this, thr_type, stack_sz);
+- _safepoint_visible = false;
+ // The _osthread may be NULL here because we ran out of memory (too many threads active).
+ // We need to throw and OutOfMemoryError - however we cannot do this here because the caller
+ // may hold a lock and all locks must be unlocked before throwing the exception (throwing
+@@ -1599,13 +1598,6 @@
+ tty->print_cr("terminate thread %p", this);
+ }
+
+- // By now, this thread should already be invisible to safepoint,
+- // and its per-thread recorder also collected.
+- assert(!is_safepoint_visible(), "wrong state");
+-#if INCLUDE_NMT
+- assert(get_recorder() == NULL, "Already collected");
+-#endif // INCLUDE_NMT
+-
+ // JSR166 -- return the parker to the free list
+ Parker::Release(_parker);
+ _parker = NULL ;
+@@ -2729,7 +2721,7 @@
+ }
+ };
+
+-void JavaThread::oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf) {
++void JavaThread::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
+ // Verify that the deferred card marks have been flushed.
+ assert(deferred_card_mark().is_empty(), "Should be empty during GC");
+
+@@ -3033,6 +3025,8 @@
+ // Push the Java priority down to the native thread; needs Threads_lock
+ Thread::set_priority(this, prio);
+
++ prepare_ext();
++
+ // Add the new thread to the Threads list and set it in motion.
+ // We must have threads lock in order to call Threads::add.
+ // It is crucial that we do not block before the thread is
+@@ -3252,7 +3246,7 @@
+ #endif
+ }
+
+-void CompilerThread::oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf) {
++void CompilerThread::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
+ JavaThread::oops_do(f, cld_f, cf);
+ if (_scanned_nmethod != NULL && cf != NULL) {
+ // Safepoints can occur when the sweeper is scanning an nmethod so
+@@ -3369,11 +3363,6 @@
+ // intialize TLS
+ ThreadLocalStorage::init();
+
+- // Bootstrap native memory tracking, so it can start recording memory
+- // activities before worker thread is started. This is the first phase
+- // of bootstrapping, VM is currently running in single-thread mode.
+- MemTracker::bootstrap_single_thread();
+-
+ // Initialize output stream logging
+ ostream_init_log();
+
+@@ -3424,9 +3413,6 @@
+ // Initialize Java-Level synchronization subsystem
+ ObjectMonitor::Initialize() ;
+
+- // Second phase of bootstrapping, VM is about entering multi-thread mode
+- MemTracker::bootstrap_multi_thread();
+-
+ // Initialize global modules
+ jint status = init_globals();
+ if (status != JNI_OK) {
+@@ -3448,9 +3434,6 @@
+ // real raw monitor. VM is setup enough here for raw monitor enter.
+ JvmtiExport::transition_pending_onload_raw_monitors();
+
+- // Fully start NMT
+- MemTracker::start();
+-
+ // Create the VMThread
+ { TraceTime timer("Start VMThread", TraceStartupTime);
+ VMThread::create();
+@@ -3898,6 +3881,24 @@
+ }
+ }
+
++JavaThread* Threads::find_java_thread_from_java_tid(jlong java_tid) {
++ assert(Threads_lock->owned_by_self(), "Must hold Threads_lock");
++
++ JavaThread* java_thread = NULL;
++ // Sequential search for now. Need to do better optimization later.
++ for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) {
++ oop tobj = thread->threadObj();
++ if (!thread->is_exiting() &&
++ tobj != NULL &&
++ java_tid == java_lang_Thread::thread_id(tobj)) {
++ java_thread = thread;
++ break;
++ }
++ }
++ return java_thread;
++}
++
++
+ // Last thread running calls java.lang.Shutdown.shutdown()
+ void JavaThread::invoke_shutdown_hooks() {
+ HandleMark hm(this);
+@@ -4088,8 +4089,6 @@
+ daemon = false;
+ }
+
+- p->set_safepoint_visible(true);
+-
+ ThreadService::add_thread(p, daemon);
+
+ // Possible GC point.
+@@ -4135,13 +4134,6 @@
+ // to do callbacks into the safepoint code. However, the safepoint code is not aware
+ // of this thread since it is removed from the queue.
+ p->set_terminated_value();
+-
+- // Now, this thread is not visible to safepoint
+- p->set_safepoint_visible(false);
+- // once the thread becomes safepoint invisible, we can not use its per-thread
+- // recorder. And Threads::do_threads() no longer walks this thread, so we have
+- // to release its per-thread recorder here.
+- MemTracker::thread_exiting(p);
+ } // unlock Threads_lock
+
+ // Since Events::log uses a lock, we grab it outside the Threads_lock
+@@ -4166,22 +4158,22 @@
+ // uses the Threads_lock to gurantee this property. It also makes sure that
+ // all threads gets blocked when exiting or starting).
+
+-void Threads::oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf) {
++void Threads::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
+ ALL_JAVA_THREADS(p) {
+ p->oops_do(f, cld_f, cf);
+ }
+ VMThread::vm_thread()->oops_do(f, cld_f, cf);
+ }
+
+-void Threads::possibly_parallel_oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf) {
++void Threads::possibly_parallel_oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
+ // Introduce a mechanism allowing parallel threads to claim threads as
+ // root groups. Overhead should be small enough to use all the time,
+ // even in sequential code.
+ SharedHeap* sh = SharedHeap::heap();
+ // Cannot yet substitute active_workers for n_par_threads
+ // because of G1CollectedHeap::verify() use of
+- // SharedHeap::process_strong_roots(). n_par_threads == 0 will
+- // turn off parallelism in process_strong_roots while active_workers
++ // SharedHeap::process_roots(). n_par_threads == 0 will
++ // turn off parallelism in process_roots while active_workers
+ // is being used for parallelism elsewhere.
+ bool is_par = sh->n_par_threads() > 0;
+ assert(!is_par ||
+--- ./hotspot/src/share/vm/runtime/thread.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/thread.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -40,16 +40,12 @@
+ #include "runtime/safepoint.hpp"
+ #include "runtime/stubRoutines.hpp"
+ #include "runtime/threadLocalStorage.hpp"
++#include "runtime/thread_ext.hpp"
+ #include "runtime/unhandledOops.hpp"
+-#include "utilities/macros.hpp"
+-
+-#if INCLUDE_NMT
+-#include "services/memRecorder.hpp"
+-#endif // INCLUDE_NMT
+-
+ #include "trace/traceBackend.hpp"
+ #include "trace/traceMacros.hpp"
+ #include "utilities/exceptions.hpp"
++#include "utilities/macros.hpp"
+ #include "utilities/top.hpp"
+ #if INCLUDE_ALL_GCS
+ #include "gc_implementation/g1/dirtyCardQueue.hpp"
+@@ -86,6 +82,10 @@
+ class ThreadClosure;
+ class IdealGraphPrinter;
+
++class Metadata;
++template <class T, MEMFLAGS F> class ChunkedList;
++typedef ChunkedList<Metadata*, mtInternal> MetadataOnStackBuffer;
++
+ DEBUG_ONLY(class ResourceMark;)
+
+ class WorkerThread;
+@@ -259,8 +259,13 @@
+ jlong _allocated_bytes; // Cumulative number of bytes allocated on
+ // the Java heap
+
++ // Thread-local buffer used by MetadataOnStackMark.
++ MetadataOnStackBuffer* _metadata_on_stack_buffer;
++
+ TRACE_DATA _trace_data; // Thread-local data for tracing
+
++ ThreadExt _ext;
++
+ int _vm_operation_started_count; // VM_Operation support
+ int _vm_operation_completed_count; // VM_Operation support
+
+@@ -436,21 +441,13 @@
+ jlong allocated_bytes() { return _allocated_bytes; }
+ void set_allocated_bytes(jlong value) { _allocated_bytes = value; }
+ void incr_allocated_bytes(jlong size) { _allocated_bytes += size; }
+- jlong cooked_allocated_bytes() {
+- jlong allocated_bytes = OrderAccess::load_acquire(&_allocated_bytes);
+- if (UseTLAB) {
+- size_t used_bytes = tlab().used_bytes();
+- if ((ssize_t)used_bytes > 0) {
+- // More-or-less valid tlab. The load_acquire above should ensure
+- // that the result of the add is <= the instantaneous value
+- return allocated_bytes + used_bytes;
+- }
+- }
+- return allocated_bytes;
+- }
++ inline jlong cooked_allocated_bytes();
+
+ TRACE_DATA* trace_data() { return &_trace_data; }
+
++ const ThreadExt& ext() const { return _ext; }
++ ThreadExt& ext() { return _ext; }
++
+ // VM operation support
+ int vm_operation_ticket() { return ++_vm_operation_started_count; }
+ int vm_operation_completed_count() { return _vm_operation_completed_count; }
+@@ -483,13 +480,13 @@
+ // Apply "cld_f->do_cld" to CLDs that are otherwise not kept alive.
+ // Used by JavaThread::oops_do.
+ // Apply "cf->do_code_blob" (if !NULL) to all code blobs active in frames
+- virtual void oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf);
++ virtual void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
+
+ // Handles the parallel case for the method below.
+ private:
+ bool claim_oops_do_par_case(int collection_parity);
+ public:
+- // Requires that "collection_parity" is that of the current strong roots
++ // Requires that "collection_parity" is that of the current roots
+ // iteration. If "is_par" is false, sets the parity of "this" to
+ // "collection_parity", and returns "true". If "is_par" is true,
+ // uses an atomic instruction to set the current threads parity to
+@@ -526,7 +523,10 @@
+ // creation fails due to lack of memory, too many threads etc.
+ bool set_as_starting_thread();
+
+- protected:
++ void set_metadata_on_stack_buffer(MetadataOnStackBuffer* buffer) { _metadata_on_stack_buffer = buffer; }
++ MetadataOnStackBuffer* metadata_on_stack_buffer() const { return _metadata_on_stack_buffer; }
++
++protected:
+ // OS data associated with the thread
+ OSThread* _osthread; // Platform-specific thread information
+
+@@ -933,6 +933,12 @@
+ // This is set to popframe_pending to signal that top Java frame should be popped immediately
+ int _popframe_condition;
+
++ // If reallocation of scalar replaced objects fails, we throw OOM
++ // and during exception propagation, pop the top
++ // _frames_to_pop_failed_realloc frames, the ones that reference
++ // failed reallocations.
++ int _frames_to_pop_failed_realloc;
++
+ #ifndef PRODUCT
+ int _jmp_ring_index;
+ struct {
+@@ -1017,6 +1023,7 @@
+ // not specified, use the priority of the thread object. Threads_lock
+ // must be held while this function is called.
+ void prepare(jobject jni_thread, ThreadPriority prio=NoPriority);
++ void prepare_ext();
+
+ void set_saved_exception_pc(address pc) { _saved_exception_pc = pc; }
+ address saved_exception_pc() { return _saved_exception_pc; }
+@@ -1046,12 +1053,8 @@
+ #else
+ // Use membars when accessing volatile _thread_state. See
+ // Threads::create_vm() for size checks.
+- JavaThreadState thread_state() const {
+- return (JavaThreadState) OrderAccess::load_acquire((volatile jint*)&_thread_state);
+- }
+- void set_thread_state(JavaThreadState s) {
+- OrderAccess::release_store((volatile jint*)&_thread_state, (jint)s);
+- }
++ inline JavaThreadState thread_state() const;
++ inline void set_thread_state(JavaThreadState s);
+ #endif
+ ThreadSafepointState *safepoint_state() const { return _safepoint_state; }
+ void set_safepoint_state(ThreadSafepointState *state) { _safepoint_state = state; }
+@@ -1074,16 +1077,6 @@
+ bool do_not_unlock_if_synchronized() { return _do_not_unlock_if_synchronized; }
+ void set_do_not_unlock_if_synchronized(bool val) { _do_not_unlock_if_synchronized = val; }
+
+-#if INCLUDE_NMT
+- // native memory tracking
+- inline MemRecorder* get_recorder() const { return (MemRecorder*)_recorder; }
+- inline void set_recorder(MemRecorder* rc) { _recorder = rc; }
+-
+- private:
+- // per-thread memory recorder
+- MemRecorder* volatile _recorder;
+-#endif // INCLUDE_NMT
+-
+ // Suspend/resume support for JavaThread
+ private:
+ void set_ext_suspended() { set_suspend_flag (_ext_suspended); }
+@@ -1444,7 +1437,7 @@
+ void frames_do(void f(frame*, const RegisterMap*));
+
+ // Memory operations
+- void oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf);
++ void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
+
+ // Sweeper operations
+ void nmethods_do(CodeBlobClosure* cf);
+@@ -1526,19 +1519,6 @@
+ return result;
+ }
+
+- // NMT (Native memory tracking) support.
+- // This flag helps NMT to determine if this JavaThread will be blocked
+- // at safepoint. If not, ThreadCritical is needed for writing memory records.
+- // JavaThread is only safepoint visible when it is in Threads' thread list,
+- // it is not visible until it is added to the list and becomes invisible
+- // once it is removed from the list.
+- public:
+- bool is_safepoint_visible() const { return _safepoint_visible; }
+- void set_safepoint_visible(bool visible) { _safepoint_visible = visible; }
+- private:
+- bool _safepoint_visible;
+-
+- // Static operations
+ public:
+ // Returns the running thread as a JavaThread
+ static inline JavaThread* current();
+@@ -1611,6 +1591,10 @@
+ void clr_pop_frame_in_process(void) { _popframe_condition &= ~popframe_processing_bit; }
+ #endif
+
++ int frames_to_pop_failed_realloc() const { return _frames_to_pop_failed_realloc; }
++ void set_frames_to_pop_failed_realloc(int nb) { _frames_to_pop_failed_realloc = nb; }
++ void dec_frames_to_pop_failed_realloc() { _frames_to_pop_failed_realloc--; }
++
+ private:
+ // Saved incoming arguments to popped frame.
+ // Used only when popped interpreted frame returns to deoptimized frame.
+@@ -1775,7 +1759,7 @@
+ // clearing/querying jni attach status
+ bool is_attaching_via_jni() const { return _jni_attach_state == _attaching_via_jni; }
+ bool has_attached_via_jni() const { return is_attaching_via_jni() || _jni_attach_state == _attached_via_jni; }
+- void set_done_attaching_via_jni() { _jni_attach_state = _attached_via_jni; OrderAccess::fence(); }
++ inline void set_done_attaching_via_jni();
+ private:
+ // This field is used to determine if a thread has claimed
+ // a par_id: it is UINT_MAX if the thread has not claimed a par_id;
+@@ -1875,7 +1859,7 @@
+ // GC support
+ // Apply "f->do_oop" to all root oops in "this".
+ // Apply "cf->do_code_blob" (if !NULL) to all code blobs active in frames
+- void oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf);
++ void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
+
+ #ifndef PRODUCT
+ private:
+@@ -1942,9 +1926,9 @@
+
+ // Apply "f->do_oop" to all root oops in all threads.
+ // This version may only be called by sequential code.
+- static void oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf);
++ static void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
+ // This version may be called by sequential or parallel code.
+- static void possibly_parallel_oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf);
++ static void possibly_parallel_oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
+ // This creates a list of GCTasks, one per thread.
+ static void create_thread_roots_tasks(GCTaskQueue* q);
+ // This creates a list of GCTasks, one per thread, for marking objects.
+@@ -1998,6 +1982,8 @@
+ // Deoptimizes all frames tied to marked nmethods
+ static void deoptimized_wrt_marked_nmethods();
+
++ static JavaThread* find_java_thread_from_java_tid(jlong java_tid);
++
+ };
+
+
+--- ./hotspot/src/share/vm/runtime/thread.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/thread.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -46,4 +46,32 @@
+
+ #undef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
+
++inline jlong Thread::cooked_allocated_bytes() {
++ jlong allocated_bytes = OrderAccess::load_acquire(&_allocated_bytes);
++ if (UseTLAB) {
++ size_t used_bytes = tlab().used_bytes();
++ if ((ssize_t)used_bytes > 0) {
++ // More-or-less valid tlab. The load_acquire above should ensure
++ // that the result of the add is <= the instantaneous value.
++ return allocated_bytes + used_bytes;
++ }
++ }
++ return allocated_bytes;
++}
++
++#ifdef PPC64
++inline JavaThreadState JavaThread::thread_state() const {
++ return (JavaThreadState) OrderAccess::load_acquire((volatile jint*)&_thread_state);
++}
++
++inline void JavaThread::set_thread_state(JavaThreadState s) {
++ OrderAccess::release_store((volatile jint*)&_thread_state, (jint)s);
++}
++#endif
++
++inline void JavaThread::set_done_attaching_via_jni() {
++ _jni_attach_state = _attached_via_jni;
++ OrderAccess::fence();
++}
++
+ #endif // SHARE_VM_RUNTIME_THREAD_INLINE_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/runtime/thread_ext.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "runtime/thread.hpp"
++#include "runtime/thread_ext.hpp"
++
++void JavaThread::prepare_ext() {
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/runtime/thread_ext.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_RUNTIME_THREAD_EXT_HPP
++#define SHARE_VM_RUNTIME_THREAD_EXT_HPP
++
++#include "memory/allocation.hpp"
++
++class ThreadExt VALUE_OBJ_CLASS_SPEC {
++public:
++ void print_on(outputStream* st) const {};
++};
++
++#endif // SHARE_VM_RUNTIME_THREAD_EXT_HPP
+--- ./hotspot/src/share/vm/runtime/vframe.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/vframe.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -260,65 +260,156 @@
+ return fr().interpreter_frame_method();
+ }
+
+-StackValueCollection* interpretedVFrame::locals() const {
+- int length = method()->max_locals();
++static StackValue* create_stack_value_from_oop_map(const InterpreterOopMap& oop_mask,
++ int index,
++ const intptr_t* const addr) {
+
+- if (method()->is_native()) {
+- // If the method is native, max_locals is not telling the truth.
+- // maxlocals then equals the size of parameters
+- length = method()->size_of_parameters();
++ assert(index >= 0 &&
++ index < oop_mask.number_of_entries(), "invariant");
++
++ // categorize using oop_mask
++ if (oop_mask.is_oop(index)) {
++ // reference (oop) "r"
++ Handle h(addr != NULL ? (*(oop*)addr) : (oop)NULL);
++ return new StackValue(h);
++ }
++ // value (integer) "v"
++ return new StackValue(addr != NULL ? *addr : 0);
++}
++
++static bool is_in_expression_stack(const frame& fr, const intptr_t* const addr) {
++ assert(addr != NULL, "invariant");
++
++ // Ensure to be 'inside' the expresion stack (i.e., addr >= sp for Intel).
++ // In case of exceptions, the expression stack is invalid and the sp
++ // will be reset to express this condition.
++ if (frame::interpreter_frame_expression_stack_direction() > 0) {
++ return addr <= fr.interpreter_frame_tos_address();
+ }
+
+- StackValueCollection* result = new StackValueCollection(length);
++ return addr >= fr.interpreter_frame_tos_address();
++}
+
+- // Get oopmap describing oops and int for current bci
++static void stack_locals(StackValueCollection* result,
++ int length,
++ const InterpreterOopMap& oop_mask,
++ const frame& fr) {
++
++ assert(result != NULL, "invariant");
++
++ for (int i = 0; i < length; ++i) {
++ const intptr_t* const addr = fr.interpreter_frame_local_at(i);
++ assert(addr != NULL, "invariant");
++ assert(addr >= fr.sp(), "must be inside the frame");
++
++ StackValue* const sv = create_stack_value_from_oop_map(oop_mask, i, addr);
++ assert(sv != NULL, "sanity check");
++
++ result->add(sv);
++ }
++}
++
++static void stack_expressions(StackValueCollection* result,
++ int length,
++ int max_locals,
++ const InterpreterOopMap& oop_mask,
++ const frame& fr) {
++
++ assert(result != NULL, "invariant");
++
++ for (int i = 0; i < length; ++i) {
++ const intptr_t* addr = fr.interpreter_frame_expression_stack_at(i);
++ assert(addr != NULL, "invariant");
++ if (!is_in_expression_stack(fr, addr)) {
++ // Need to ensure no bogus escapes.
++ addr = NULL;
++ }
++
++ StackValue* const sv = create_stack_value_from_oop_map(oop_mask,
++ i + max_locals,
++ addr);
++ assert(sv != NULL, "sanity check");
++
++ result->add(sv);
++ }
++}
++
++StackValueCollection* interpretedVFrame::locals() const {
++ return stack_data(false);
++}
++
++StackValueCollection* interpretedVFrame::expressions() const {
++ return stack_data(true);
++}
++
++/*
++ * Worker routine for fetching references and/or values
++ * for a particular bci in the interpretedVFrame.
++ *
++ * Returns data for either "locals" or "expressions",
++ * using bci relative oop_map (oop_mask) information.
++ *
++ * @param expressions bool switch controlling what data to return
++ (false == locals / true == expressions)
++ *
++ */
++StackValueCollection* interpretedVFrame::stack_data(bool expressions) const {
++
+ InterpreterOopMap oop_mask;
++ // oopmap for current bci
+ if (TraceDeoptimization && Verbose) {
+- methodHandle m_h(thread(), method());
++ methodHandle m_h(Thread::current(), method());
+ OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask);
+ } else {
+ method()->mask_for(bci(), &oop_mask);
+ }
+- // handle locals
+- for(int i=0; i < length; i++) {
+- // Find stack location
+- intptr_t *addr = locals_addr_at(i);
+
+- // Depending on oop/int put it in the right package
+- StackValue *sv;
+- if (oop_mask.is_oop(i)) {
+- // oop value
+- Handle h(*(oop *)addr);
+- sv = new StackValue(h);
+- } else {
+- // integer
+- sv = new StackValue(*addr);
+- }
+- assert(sv != NULL, "sanity check");
+- result->add(sv);
++ const int mask_len = oop_mask.number_of_entries();
++
++ // If the method is native, method()->max_locals() is not telling the truth.
++ // For our purposes, max locals instead equals the size of parameters.
++ const int max_locals = method()->is_native() ?
++ method()->size_of_parameters() : method()->max_locals();
++
++ assert(mask_len >= max_locals, "invariant");
++
++ const int length = expressions ? mask_len - max_locals : max_locals;
++ assert(length >= 0, "invariant");
++
++ StackValueCollection* const result = new StackValueCollection(length);
++
++ if (0 == length) {
++ return result;
+ }
++
++ if (expressions) {
++ stack_expressions(result, length, max_locals, oop_mask, fr());
++ } else {
++ stack_locals(result, length, oop_mask, fr());
++ }
++
++ assert(length == result->size(), "invariant");
++
+ return result;
+ }
+
+ void interpretedVFrame::set_locals(StackValueCollection* values) const {
+ if (values == NULL || values->size() == 0) return;
+
+- int length = method()->max_locals();
+- if (method()->is_native()) {
+- // If the method is native, max_locals is not telling the truth.
+- // maxlocals then equals the size of parameters
+- length = method()->size_of_parameters();
+- }
++ // If the method is native, max_locals is not telling the truth.
++ // maxlocals then equals the size of parameters
++ const int max_locals = method()->is_native() ?
++ method()->size_of_parameters() : method()->max_locals();
+
+- assert(length == values->size(), "Mismatch between actual stack format and supplied data");
++ assert(max_locals == values->size(), "Mismatch between actual stack format and supplied data");
+
+ // handle locals
+- for (int i = 0; i < length; i++) {
++ for (int i = 0; i < max_locals; i++) {
+ // Find stack location
+ intptr_t *addr = locals_addr_at(i);
+
+ // Depending on oop/int put it in the right package
+- StackValue *sv = values->at(i);
++ const StackValue* const sv = values->at(i);
+ assert(sv != NULL, "sanity check");
+ if (sv->type() == T_OBJECT) {
+ *(oop *) addr = (sv->get_obj())();
+@@ -328,46 +419,6 @@
+ }
+ }
+
+-StackValueCollection* interpretedVFrame::expressions() const {
+- int length = fr().interpreter_frame_expression_stack_size();
+- if (method()->is_native()) {
+- // If the method is native, there is no expression stack
+- length = 0;
+- }
+-
+- int nof_locals = method()->max_locals();
+- StackValueCollection* result = new StackValueCollection(length);
+-
+- InterpreterOopMap oop_mask;
+- // Get oopmap describing oops and int for current bci
+- if (TraceDeoptimization && Verbose) {
+- methodHandle m_h(method());
+- OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask);
+- } else {
+- method()->mask_for(bci(), &oop_mask);
+- }
+- // handle expressions
+- for(int i=0; i < length; i++) {
+- // Find stack location
+- intptr_t *addr = fr().interpreter_frame_expression_stack_at(i);
+-
+- // Depending on oop/int put it in the right package
+- StackValue *sv;
+- if (oop_mask.is_oop(i + nof_locals)) {
+- // oop value
+- Handle h(*(oop *)addr);
+- sv = new StackValue(h);
+- } else {
+- // integer
+- sv = new StackValue(*addr);
+- }
+- assert(sv != NULL, "sanity check");
+- result->add(sv);
+- }
+- return result;
+-}
+-
+-
+ // ------------- cChunk --------------
+
+ entryVFrame::entryVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread)
+--- ./hotspot/src/share/vm/runtime/vframe.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/vframe.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -186,7 +186,7 @@
+ private:
+ static const int bcp_offset;
+ intptr_t* locals_addr_at(int offset) const;
+-
++ StackValueCollection* stack_data(bool expressions) const;
+ // returns where the parameters starts relative to the frame pointer
+ int start_of_parameters() const;
+
+--- ./hotspot/src/share/vm/runtime/vframeArray.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/vframeArray.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -56,7 +56,7 @@
+ }
+ }
+
+-void vframeArrayElement::fill_in(compiledVFrame* vf) {
++void vframeArrayElement::fill_in(compiledVFrame* vf, bool realloc_failures) {
+
+ // Copy the information from the compiled vframe to the
+ // interpreter frame we will be creating to replace vf
+@@ -64,6 +64,9 @@
+ _method = vf->method();
+ _bci = vf->raw_bci();
+ _reexecute = vf->should_reexecute();
++#ifdef ASSERT
++ _removed_monitors = false;
++#endif
+
+ int index;
+
+@@ -81,11 +84,15 @@
+ // Migrate the BasicLocks from the stack to the monitor chunk
+ for (index = 0; index < list->length(); index++) {
+ MonitorInfo* monitor = list->at(index);
+- assert(!monitor->owner_is_scalar_replaced(), "object should be reallocated already");
+- assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased");
++ assert(!monitor->owner_is_scalar_replaced() || realloc_failures, "object should be reallocated already");
+ BasicObjectLock* dest = _monitors->at(index);
+- dest->set_obj(monitor->owner());
+- monitor->lock()->move_to(monitor->owner(), dest->lock());
++ if (monitor->owner_is_scalar_replaced()) {
++ dest->set_obj(NULL);
++ } else {
++ assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased");
++ dest->set_obj(monitor->owner());
++ monitor->lock()->move_to(monitor->owner(), dest->lock());
++ }
+ }
+ }
+
+@@ -110,7 +117,7 @@
+ StackValue* value = locs->at(index);
+ switch(value->type()) {
+ case T_OBJECT:
+- assert(!value->obj_is_scalar_replaced(), "object should be reallocated already");
++ assert(!value->obj_is_scalar_replaced() || realloc_failures, "object should be reallocated already");
+ // preserve object type
+ _locals->add( new StackValue(cast_from_oop<intptr_t>((value->get_obj()())), T_OBJECT ));
+ break;
+@@ -135,7 +142,7 @@
+ StackValue* value = exprs->at(index);
+ switch(value->type()) {
+ case T_OBJECT:
+- assert(!value->obj_is_scalar_replaced(), "object should be reallocated already");
++ assert(!value->obj_is_scalar_replaced() || realloc_failures, "object should be reallocated already");
+ // preserve object type
+ _expressions->add( new StackValue(cast_from_oop<intptr_t>((value->get_obj()())), T_OBJECT ));
+ break;
+@@ -286,7 +293,7 @@
+
+ _frame.patch_pc(thread, pc);
+
+- assert (!method()->is_synchronized() || locks > 0, "synchronized methods must have monitors");
++ assert (!method()->is_synchronized() || locks > 0 || _removed_monitors, "synchronized methods must have monitors");
+
+ BasicObjectLock* top = iframe()->interpreter_frame_monitor_begin();
+ for (int index = 0; index < locks; index++) {
+@@ -438,7 +445,8 @@
+
+
+ vframeArray* vframeArray::allocate(JavaThread* thread, int frame_size, GrowableArray<compiledVFrame*>* chunk,
+- RegisterMap *reg_map, frame sender, frame caller, frame self) {
++ RegisterMap *reg_map, frame sender, frame caller, frame self,
++ bool realloc_failures) {
+
+ // Allocate the vframeArray
+ vframeArray * result = (vframeArray*) AllocateHeap(sizeof(vframeArray) + // fixed part
+@@ -450,19 +458,20 @@
+ result->_caller = caller;
+ result->_original = self;
+ result->set_unroll_block(NULL); // initialize it
+- result->fill_in(thread, frame_size, chunk, reg_map);
++ result->fill_in(thread, frame_size, chunk, reg_map, realloc_failures);
+ return result;
+ }
+
+ void vframeArray::fill_in(JavaThread* thread,
+ int frame_size,
+ GrowableArray<compiledVFrame*>* chunk,
+- const RegisterMap *reg_map) {
++ const RegisterMap *reg_map,
++ bool realloc_failures) {
+ // Set owner first, it is used when adding monitor chunks
+
+ _frame_size = frame_size;
+ for(int i = 0; i < chunk->length(); i++) {
+- element(i)->fill_in(chunk->at(i));
++ element(i)->fill_in(chunk->at(i), realloc_failures);
+ }
+
+ // Copy registers for callee-saved registers
+--- ./hotspot/src/share/vm/runtime/vframeArray.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/vframeArray.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -58,6 +58,9 @@
+ MonitorChunk* _monitors; // active monitors for this vframe
+ StackValueCollection* _locals;
+ StackValueCollection* _expressions;
++#ifdef ASSERT
++ bool _removed_monitors;
++#endif
+
+ public:
+
+@@ -78,7 +81,7 @@
+
+ StackValueCollection* expressions(void) const { return _expressions; }
+
+- void fill_in(compiledVFrame* vf);
++ void fill_in(compiledVFrame* vf, bool realloc_failures);
+
+ // Formerly part of deoptimizedVFrame
+
+@@ -99,6 +102,12 @@
+ bool is_bottom_frame,
+ int exec_mode);
+
++#ifdef ASSERT
++ void set_removed_monitors() {
++ _removed_monitors = true;
++ }
++#endif
++
+ #ifndef PRODUCT
+ void print(outputStream* st);
+ #endif /* PRODUCT */
+@@ -160,13 +169,14 @@
+ int frames() const { return _frames; }
+
+ static vframeArray* allocate(JavaThread* thread, int frame_size, GrowableArray<compiledVFrame*>* chunk,
+- RegisterMap* reg_map, frame sender, frame caller, frame self);
++ RegisterMap* reg_map, frame sender, frame caller, frame self,
++ bool realloc_failures);
+
+
+ vframeArrayElement* element(int index) { assert(is_within_bounds(index), "Bad index"); return &_elements[index]; }
+
+ // Allocates a new vframe in the array and fills the array with vframe information in chunk
+- void fill_in(JavaThread* thread, int frame_size, GrowableArray<compiledVFrame*>* chunk, const RegisterMap *reg_map);
++ void fill_in(JavaThread* thread, int frame_size, GrowableArray<compiledVFrame*>* chunk, const RegisterMap *reg_map, bool realloc_failures);
+
+ // Returns the owner of this vframeArray
+ JavaThread* owner_thread() const { return _owner_thread; }
+--- ./hotspot/src/share/vm/runtime/vmStructs.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/vmStructs.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -320,7 +320,7 @@
+ nonstatic_field(InstanceKlass, _jni_ids, JNIid*) \
+ nonstatic_field(InstanceKlass, _osr_nmethods_head, nmethod*) \
+ nonstatic_field(InstanceKlass, _breakpoints, BreakpointInfo*) \
+- nonstatic_field(InstanceKlass, _generic_signature_index, u2) \
++ nonstatic_field(InstanceKlass, _generic_signature_index, u2) \
+ nonstatic_field(InstanceKlass, _methods_jmethod_ids, jmethodID*) \
+ volatile_nonstatic_field(InstanceKlass, _idnum_allocated_count, u2) \
+ nonstatic_field(InstanceKlass, _annotations, Annotations*) \
+@@ -665,6 +665,7 @@
+ static_field(SystemDictionary, WK_KLASS(StackOverflowError_klass), Klass*) \
+ static_field(SystemDictionary, WK_KLASS(ProtectionDomain_klass), Klass*) \
+ static_field(SystemDictionary, WK_KLASS(AccessControlContext_klass), Klass*) \
++ static_field(SystemDictionary, WK_KLASS(SecureClassLoader_klass), Klass*) \
+ static_field(SystemDictionary, WK_KLASS(Reference_klass), Klass*) \
+ static_field(SystemDictionary, WK_KLASS(SoftReference_klass), Klass*) \
+ static_field(SystemDictionary, WK_KLASS(WeakReference_klass), Klass*) \
+@@ -814,6 +815,7 @@
+ static_field(StubRoutines, _cipherBlockChaining_decryptAESCrypt, address) \
+ static_field(StubRoutines, _updateBytesCRC32, address) \
+ static_field(StubRoutines, _crc_table_adr, address) \
++ static_field(StubRoutines, _multiplyToLen, address) \
+ \
+ /*****************/ \
+ /* SharedRuntime */ \
+@@ -2495,6 +2497,7 @@
+ declare_constant(Deoptimization::Reason_age) \
+ declare_constant(Deoptimization::Reason_predicate) \
+ declare_constant(Deoptimization::Reason_loop_limit_check) \
++ declare_constant(Deoptimization::Reason_unstable_if) \
+ declare_constant(Deoptimization::Reason_LIMIT) \
+ declare_constant(Deoptimization::Reason_RECORDED_LIMIT) \
+ \
+--- ./hotspot/src/share/vm/runtime/vmThread.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/vmThread.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -682,7 +682,7 @@
+ }
+
+
+-void VMThread::oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf) {
++void VMThread::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
+ Thread::oops_do(f, cld_f, cf);
+ _vm_queue->oops_do(f);
+ }
+--- ./hotspot/src/share/vm/runtime/vmThread.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/vmThread.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -126,7 +126,7 @@
+ static VMThread* vm_thread() { return _vm_thread; }
+
+ // GC support
+- void oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf);
++ void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
+
+ // Debugging
+ void print_on(outputStream* st) const;
+--- ./hotspot/src/share/vm/runtime/vm_operations.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/runtime/vm_operations.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -68,6 +68,7 @@
+ template(G1CollectFull) \
+ template(G1CollectForAllocation) \
+ template(G1IncCollectionPause) \
++ template(DestroyAllocationContext) \
+ template(EnableBiasedLocking) \
+ template(RevokeBias) \
+ template(BulkRevokeBias) \
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/services/allocationContextService.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,39 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_SERVICES_ALLOCATION_CONTEXT_SERVICE_HPP
++#define SHARE_VM_SERVICES_ALLOCATION_CONTEXT_SERVICE_HPP
++
++#include "utilities/exceptions.hpp"
++
++class AllocationContextService: public AllStatic {
++public:
++ static inline bool should_notify();
++ static inline void notify(TRAPS);
++};
++
++bool AllocationContextService::should_notify() { return false; }
++void AllocationContextService::notify(TRAPS) { }
++
++#endif // SHARE_VM_SERVICES_ALLOCATION_CONTEXT_SERVICE_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/services/allocationSite.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,57 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_SERVICES_ALLOCATION_SITE_HPP
++#define SHARE_VM_SERVICES_ALLOCATION_SITE_HPP
++
++#include "memory/allocation.hpp"
++#include "utilities/nativeCallStack.hpp"
++
++// Allocation site represents a code path that makes a memory
++// allocation
++template <class E> class AllocationSite VALUE_OBJ_CLASS_SPEC {
++ private:
++ NativeCallStack _call_stack;
++ E e;
++ public:
++ AllocationSite(const NativeCallStack& stack) : _call_stack(stack) { }
++ int hash() const { return _call_stack.hash(); }
++ bool equals(const NativeCallStack& stack) const {
++ return _call_stack.equals(stack);
++ }
++
++ bool equals(const AllocationSite<E>& other) const {
++ return other.equals(_call_stack);
++ }
++
++ const NativeCallStack* call_stack() const {
++ return &_call_stack;
++ }
++
++ // Information regarding this allocation
++ E* data() { return &e; }
++ const E* peek() const { return &e; }
++};
++
++#endif // SHARE_VM_SERVICES_ALLOCATION_SITE_HPP
+--- ./hotspot/src/share/vm/services/attachListener.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/services/attachListener.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -162,10 +162,7 @@
+ java_lang_Throwable::print(PENDING_EXCEPTION, out);
+ out->cr();
+ CLEAR_PENDING_EXCEPTION;
+- // The exception has been printed on the output stream
+- // If the JVM returns JNI_ERR, the attachAPI throws a generic I/O
+- // exception and the content of the output stream is not processed.
+- // By returning JNI_OK, the exception will be displayed on the client side
++ return JNI_ERR;
+ }
+ return JNI_OK;
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/services/mallocSiteTable.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,261 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++#include "precompiled.hpp"
++
++
++#include "memory/allocation.inline.hpp"
++#include "runtime/atomic.hpp"
++#include "services/mallocSiteTable.hpp"
++
++/*
++ * Early os::malloc() calls come from initializations of static variables, long before entering any
++ * VM code. Upon the arrival of the first os::malloc() call, malloc site hashtable has to be
++ * initialized, along with the allocation site for the hashtable entries.
++ * To ensure that malloc site hashtable can be initialized without triggering any additional os::malloc()
++ * call, the hashtable bucket array and hashtable entry allocation site have to be static.
++ * It is not a problem for hashtable bucket, since it is an array of pointer type, C runtime just
++ * allocates a block memory and zero the memory for it.
++ * But for hashtable entry allocation site object, things get tricky. C runtime not only allocates
++ * memory for it, but also calls its constructor at some later time. If we initialize the allocation site
++ * at the first os::malloc() call, the object will be reinitialized when its constructor is called
++ * by C runtime.
++ * To workaround above issue, we declare a static size_t array with the size of the CallsiteHashtableEntry,
++ * the memory is used to instantiate CallsiteHashtableEntry for the hashtable entry allocation site.
++ * Given it is a primitive type array, C runtime will do nothing other than assign the memory block for the variable,
++ * which is exactly what we want.
++ * The same trick is also applied to create NativeCallStack object for CallsiteHashtableEntry memory allocation.
++ *
++ * Note: C++ object usually aligns to particular alignment, depends on compiler implementation, we declare
++ * the memory as size_t arrays, to ensure the memory is aligned to native machine word alignment.
++ */
++
++// Reserve enough memory for NativeCallStack and MallocSiteHashtableEntry objects
++size_t MallocSiteTable::_hash_entry_allocation_stack[CALC_OBJ_SIZE_IN_TYPE(NativeCallStack, size_t)];
++size_t MallocSiteTable::_hash_entry_allocation_site[CALC_OBJ_SIZE_IN_TYPE(MallocSiteHashtableEntry, size_t)];
++
++// Malloc site hashtable buckets
++MallocSiteHashtableEntry* MallocSiteTable::_table[MallocSiteTable::table_size];
++
++// concurrent access counter
++volatile int MallocSiteTable::_access_count = 0;
++
++// Tracking hashtable contention
++NOT_PRODUCT(int MallocSiteTable::_peak_count = 0;)
++
++
++/*
++ * Initialize malloc site table.
++ * Hashtable entry is malloc'd, so it can cause infinite recursion.
++ * To avoid above problem, we pre-initialize a hash entry for
++ * this allocation site.
++ * The method is called during C runtime static variable initialization
++ * time, it is in single-threaded mode from JVM perspective.
++ */
++bool MallocSiteTable::initialize() {
++ assert(sizeof(_hash_entry_allocation_stack) >= sizeof(NativeCallStack), "Sanity Check");
++ assert(sizeof(_hash_entry_allocation_site) >= sizeof(MallocSiteHashtableEntry),
++ "Sanity Check");
++ assert((size_t)table_size <= MAX_MALLOCSITE_TABLE_SIZE, "Hashtable overflow");
++
++ // Fake the call stack for hashtable entry allocation
++ assert(NMT_TrackingStackDepth > 1, "At least one tracking stack");
++
++ // Create pseudo call stack for hashtable entry allocation
++ address pc[3];
++ if (NMT_TrackingStackDepth >= 3) {
++ pc[2] = (address)MallocSiteTable::allocation_at;
++ }
++ if (NMT_TrackingStackDepth >= 2) {
++ pc[1] = (address)MallocSiteTable::lookup_or_add;
++ }
++ pc[0] = (address)MallocSiteTable::new_entry;
++
++ // Instantiate NativeCallStack object, have to use placement new operator. (see comments above)
++ NativeCallStack* stack = ::new ((void*)_hash_entry_allocation_stack)
++ NativeCallStack(pc, MIN2(((int)(sizeof(pc) / sizeof(address))), ((int)NMT_TrackingStackDepth)));
++
++ // Instantiate hash entry for hashtable entry allocation callsite
++ MallocSiteHashtableEntry* entry = ::new ((void*)_hash_entry_allocation_site)
++ MallocSiteHashtableEntry(*stack);
++
++ // Add the allocation site to hashtable.
++ int index = hash_to_index(stack->hash());
++ _table[index] = entry;
++
++ return true;
++}
++
++// Walks entries in the hashtable.
++// It stops walk if the walker returns false.
++bool MallocSiteTable::walk(MallocSiteWalker* walker) {
++ MallocSiteHashtableEntry* head;
++ for (int index = 0; index < table_size; index ++) {
++ head = _table[index];
++ while (head != NULL) {
++ if (!walker->do_malloc_site(head->peek())) {
++ return false;
++ }
++ head = (MallocSiteHashtableEntry*)head->next();
++ }
++ }
++ return true;
++}
++
++/*
++ * The hashtable does not have deletion policy on individual entry,
++ * and each linked list node is inserted via compare-and-swap,
++ * so each linked list is stable, the contention only happens
++ * at the end of linked list.
++ * This method should not return NULL under normal circumstance.
++ * If NULL is returned, it indicates:
++ * 1. Out of memory, it cannot allocate new hash entry.
++ * 2. Overflow hash bucket.
++ * Under any of above circumstances, caller should handle the situation.
++ */
++MallocSite* MallocSiteTable::lookup_or_add(const NativeCallStack& key, size_t* bucket_idx,
++ size_t* pos_idx) {
++ int index = hash_to_index(key.hash());
++ assert(index >= 0, "Negative index");
++ *bucket_idx = (size_t)index;
++ *pos_idx = 0;
++
++ // First entry for this hash bucket
++ if (_table[index] == NULL) {
++ MallocSiteHashtableEntry* entry = new_entry(key);
++ // OOM check
++ if (entry == NULL) return NULL;
++
++ // swap in the head
++ if (Atomic::cmpxchg_ptr((void*)entry, (volatile void *)&_table[index], NULL) == NULL) {
++ return entry->data();
++ }
++
++ delete entry;
++ }
++
++ MallocSiteHashtableEntry* head = _table[index];
++ while (head != NULL && (*pos_idx) <= MAX_BUCKET_LENGTH) {
++ MallocSite* site = head->data();
++ if (site->equals(key)) {
++ // found matched entry
++ return head->data();
++ }
++
++ if (head->next() == NULL && (*pos_idx) < MAX_BUCKET_LENGTH) {
++ MallocSiteHashtableEntry* entry = new_entry(key);
++ // OOM check
++ if (entry == NULL) return NULL;
++ if (head->atomic_insert(entry)) {
++ (*pos_idx) ++;
++ return entry->data();
++ }
++ // contended, other thread won
++ delete entry;
++ }
++ head = (MallocSiteHashtableEntry*)head->next();
++ (*pos_idx) ++;
++ }
++ return NULL;
++}
++
++// Access malloc site
++MallocSite* MallocSiteTable::malloc_site(size_t bucket_idx, size_t pos_idx) {
++ assert(bucket_idx < table_size, "Invalid bucket index");
++ MallocSiteHashtableEntry* head = _table[bucket_idx];
++ for (size_t index = 0; index < pos_idx && head != NULL;
++ index ++, head = (MallocSiteHashtableEntry*)head->next());
++ assert(head != NULL, "Invalid position index");
++ return head->data();
++}
++
++// Allocates MallocSiteHashtableEntry object. Special call stack
++// (pre-installed allocation site) has to be used to avoid infinite
++// recursion.
++MallocSiteHashtableEntry* MallocSiteTable::new_entry(const NativeCallStack& key) {
++ void* p = AllocateHeap(sizeof(MallocSiteHashtableEntry), mtNMT,
++ *hash_entry_allocation_stack(), AllocFailStrategy::RETURN_NULL);
++ return ::new (p) MallocSiteHashtableEntry(key);
++}
++
++void MallocSiteTable::reset() {
++ for (int index = 0; index < table_size; index ++) {
++ MallocSiteHashtableEntry* head = _table[index];
++ _table[index] = NULL;
++ delete_linked_list(head);
++ }
++}
++
++void MallocSiteTable::delete_linked_list(MallocSiteHashtableEntry* head) {
++ MallocSiteHashtableEntry* p;
++ while (head != NULL) {
++ p = head;
++ head = (MallocSiteHashtableEntry*)head->next();
++ if (p != (MallocSiteHashtableEntry*)_hash_entry_allocation_site) {
++ delete p;
++ }
++ }
++}
++
++void MallocSiteTable::shutdown() {
++ AccessLock locker(&_access_count);
++ locker.exclusiveLock();
++ reset();
++}
++
++bool MallocSiteTable::walk_malloc_site(MallocSiteWalker* walker) {
++ assert(walker != NULL, "NuLL walker");
++ AccessLock locker(&_access_count);
++ if (locker.sharedLock()) {
++ NOT_PRODUCT(_peak_count = MAX2(_peak_count, _access_count);)
++ return walk(walker);
++ }
++ return false;
++}
++
++
++void MallocSiteTable::AccessLock::exclusiveLock() {
++ jint target;
++ jint val;
++
++ assert(_lock_state != ExclusiveLock, "Can only call once");
++ assert(*_lock >= 0, "Can not content exclusive lock");
++
++ // make counter negative to block out shared locks
++ do {
++ val = *_lock;
++ target = _MAGIC_ + *_lock;
++ } while (Atomic::cmpxchg(target, _lock, val) != val);
++
++ // wait for all readers to exit
++ while (*_lock != _MAGIC_) {
++#ifdef _WINDOWS
++ os::naked_short_sleep(1);
++#else
++ os::NakedYield();
++#endif
++ }
++ _lock_state = ExclusiveLock;
++}
++
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/services/mallocSiteTable.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,269 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_SERVICES_MALLOC_SITE_TABLE_HPP
++#define SHARE_VM_SERVICES_MALLOC_SITE_TABLE_HPP
++
++#if INCLUDE_NMT
++
++#include "memory/allocation.hpp"
++#include "runtime/atomic.hpp"
++#include "services/allocationSite.hpp"
++#include "services/mallocTracker.hpp"
++#include "services/nmtCommon.hpp"
++#include "utilities/nativeCallStack.hpp"
++
++// MallocSite represents a code path that eventually calls
++// os::malloc() to allocate memory
++class MallocSite : public AllocationSite<MemoryCounter> {
++ public:
++ MallocSite() :
++ AllocationSite<MemoryCounter>(NativeCallStack::EMPTY_STACK) { }
++
++ MallocSite(const NativeCallStack& stack) :
++ AllocationSite<MemoryCounter>(stack) { }
++
++ void allocate(size_t size) { data()->allocate(size); }
++ void deallocate(size_t size) { data()->deallocate(size); }
++
++ // Memory allocated from this code path
++ size_t size() const { return peek()->size(); }
++ // The number of calls were made
++ size_t count() const { return peek()->count(); }
++};
++
++// Malloc site hashtable entry
++class MallocSiteHashtableEntry : public CHeapObj<mtNMT> {
++ private:
++ MallocSite _malloc_site;
++ MallocSiteHashtableEntry* _next;
++
++ public:
++ MallocSiteHashtableEntry() : _next(NULL) { }
++
++ MallocSiteHashtableEntry(NativeCallStack stack):
++ _malloc_site(stack), _next(NULL) { }
++
++ inline const MallocSiteHashtableEntry* next() const {
++ return _next;
++ }
++
++ // Insert an entry atomically.
++ // Return true if the entry is inserted successfully.
++ // The operation can be failed due to contention from other thread.
++ bool atomic_insert(const MallocSiteHashtableEntry* entry) {
++ return (Atomic::cmpxchg_ptr((void*)entry, (volatile void*)&_next,
++ NULL) == NULL);
++ }
++
++ void set_callsite(const MallocSite& site) {
++ _malloc_site = site;
++ }
++
++ inline const MallocSite* peek() const { return &_malloc_site; }
++ inline MallocSite* data() { return &_malloc_site; }
++
++ inline long hash() const { return _malloc_site.hash(); }
++ inline bool equals(const NativeCallStack& stack) const {
++ return _malloc_site.equals(stack);
++ }
++ // Allocation/deallocation on this allocation site
++ inline void allocate(size_t size) { _malloc_site.allocate(size); }
++ inline void deallocate(size_t size) { _malloc_site.deallocate(size); }
++ // Memory counters
++ inline size_t size() const { return _malloc_site.size(); }
++ inline size_t count() const { return _malloc_site.count(); }
++};
++
++// The walker walks every entry on MallocSiteTable
++class MallocSiteWalker : public StackObj {
++ public:
++ virtual bool do_malloc_site(const MallocSite* e) { return false; }
++};
++
++/*
++ * Native memory tracking call site table.
++ * The table is only needed when detail tracking is enabled.
++ */
++class MallocSiteTable : AllStatic {
++ private:
++ // The number of hash bucket in this hashtable. The number should
++ // be tuned if malloc activities changed significantly.
++ // The statistics data can be obtained via Jcmd
++ // jcmd <pid> VM.native_memory statistics.
++
++ // Currently, (number of buckets / number of entires) ratio is
++ // about 1 / 6
++ enum {
++ table_base_size = 128, // The base size is calculated from statistics to give
++ // table ratio around 1:6
++ table_size = (table_base_size * NMT_TrackingStackDepth - 1)
++ };
++
++
++ // This is a very special lock, that allows multiple shared accesses (sharedLock), but
++ // once exclusive access (exclusiveLock) is requested, all shared accesses are
++ // rejected forever.
++ class AccessLock : public StackObj {
++ enum LockState {
++ NoLock,
++ SharedLock,
++ ExclusiveLock
++ };
++
++ private:
++ // A very large negative number. The only possibility to "overflow"
++ // this number is when there are more than -min_jint threads in
++ // this process, which is not going to happen in foreseeable future.
++ const static int _MAGIC_ = min_jint;
++
++ LockState _lock_state;
++ volatile int* _lock;
++ public:
++ AccessLock(volatile int* lock) :
++ _lock(lock), _lock_state(NoLock) {
++ }
++
++ ~AccessLock() {
++ if (_lock_state == SharedLock) {
++ Atomic::dec((volatile jint*)_lock);
++ }
++ }
++ // Acquire shared lock.
++ // Return true if shared access is granted.
++ inline bool sharedLock() {
++ jint res = Atomic::add(1, _lock);
++ if (res < 0) {
++ Atomic::add(-1, _lock);
++ return false;
++ }
++ _lock_state = SharedLock;
++ return true;
++ }
++ // Acquire exclusive lock
++ void exclusiveLock();
++ };
++
++ public:
++ static bool initialize();
++ static void shutdown();
++
++ NOT_PRODUCT(static int access_peak_count() { return _peak_count; })
++
++ // Number of hash buckets
++ static inline int hash_buckets() { return (int)table_size; }
++
++ // Access and copy a call stack from this table. Shared lock should be
++ // acquired before access the entry.
++ static inline bool access_stack(NativeCallStack& stack, size_t bucket_idx,
++ size_t pos_idx) {
++ AccessLock locker(&_access_count);
++ if (locker.sharedLock()) {
++ NOT_PRODUCT(_peak_count = MAX2(_peak_count, _access_count);)
++ MallocSite* site = malloc_site(bucket_idx, pos_idx);
++ if (site != NULL) {
++ stack = *site->call_stack();
++ return true;
++ }
++ }
++ return false;
++ }
++
++ // Record a new allocation from specified call path.
++ // Return true if the allocation is recorded successfully, bucket_idx
++ // and pos_idx are also updated to indicate the entry where the allocation
++ // information was recorded.
++ // Return false only occurs under rare scenarios:
++ // 1. out of memory
++ // 2. overflow hash bucket
++ static inline bool allocation_at(const NativeCallStack& stack, size_t size,
++ size_t* bucket_idx, size_t* pos_idx) {
++ AccessLock locker(&_access_count);
++ if (locker.sharedLock()) {
++ NOT_PRODUCT(_peak_count = MAX2(_peak_count, _access_count);)
++ MallocSite* site = lookup_or_add(stack, bucket_idx, pos_idx);
++ if (site != NULL) site->allocate(size);
++ return site != NULL;
++ }
++ return false;
++ }
++
++ // Record memory deallocation. bucket_idx and pos_idx indicate where the allocation
++ // information was recorded.
++ static inline bool deallocation_at(size_t size, size_t bucket_idx, size_t pos_idx) {
++ AccessLock locker(&_access_count);
++ if (locker.sharedLock()) {
++ NOT_PRODUCT(_peak_count = MAX2(_peak_count, _access_count);)
++ MallocSite* site = malloc_site(bucket_idx, pos_idx);
++ if (site != NULL) {
++ site->deallocate(size);
++ return true;
++ }
++ }
++ return false;
++ }
++
++ // Walk this table.
++ static bool walk_malloc_site(MallocSiteWalker* walker);
++
++ private:
++ static MallocSiteHashtableEntry* new_entry(const NativeCallStack& key);
++ static void reset();
++
++ // Delete a bucket linked list
++ static void delete_linked_list(MallocSiteHashtableEntry* head);
++
++ static MallocSite* lookup_or_add(const NativeCallStack& key, size_t* bucket_idx, size_t* pos_idx);
++ static MallocSite* malloc_site(size_t bucket_idx, size_t pos_idx);
++ static bool walk(MallocSiteWalker* walker);
++
++ static inline int hash_to_index(int hash) {
++ hash = (hash > 0) ? hash : (-hash);
++ return (hash % table_size);
++ }
++
++ static inline const NativeCallStack* hash_entry_allocation_stack() {
++ return (NativeCallStack*)_hash_entry_allocation_stack;
++ }
++
++ private:
++ // Counter for counting concurrent access
++ static volatile int _access_count;
++
++ // The callsite hashtable. It has to be a static table,
++ // since malloc call can come from C runtime linker.
++ static MallocSiteHashtableEntry* _table[table_size];
++
++
++ // Reserve enough memory for placing the objects
++
++ // The memory for hashtable entry allocation stack object
++ static size_t _hash_entry_allocation_stack[CALC_OBJ_SIZE_IN_TYPE(NativeCallStack, size_t)];
++ // The memory for hashtable entry allocation callsite object
++ static size_t _hash_entry_allocation_site[CALC_OBJ_SIZE_IN_TYPE(MallocSiteHashtableEntry, size_t)];
++ NOT_PRODUCT(static int _peak_count;)
++};
++
++#endif // INCLUDE_NMT
++#endif // SHARE_VM_SERVICES_MALLOC_SITE_TABLE_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/services/mallocTracker.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,166 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++#include "precompiled.hpp"
++
++#include "runtime/atomic.hpp"
++#include "runtime/atomic.inline.hpp"
++#include "services/mallocSiteTable.hpp"
++#include "services/mallocTracker.hpp"
++#include "services/mallocTracker.inline.hpp"
++#include "services/memTracker.hpp"
++
++size_t MallocMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(MallocMemorySnapshot, size_t)];
++
++// Total malloc'd memory amount
++size_t MallocMemorySnapshot::total() const {
++ size_t amount = 0;
++ for (int index = 0; index < mt_number_of_types; index ++) {
++ amount += _malloc[index].malloc_size();
++ }
++ amount += _tracking_header.size() + total_arena();
++ return amount;
++}
++
++// Total malloc'd memory used by arenas
++size_t MallocMemorySnapshot::total_arena() const {
++ size_t amount = 0;
++ for (int index = 0; index < mt_number_of_types; index ++) {
++ amount += _malloc[index].arena_size();
++ }
++ return amount;
++}
++
++// Make adjustment by subtracting chunks used by arenas
++// from total chunks to get total free chunck size
++void MallocMemorySnapshot::make_adjustment() {
++ size_t arena_size = total_arena();
++ int chunk_idx = NMTUtil::flag_to_index(mtChunk);
++ _malloc[chunk_idx].record_free(arena_size);
++}
++
++
++void MallocMemorySummary::initialize() {
++ assert(sizeof(_snapshot) >= sizeof(MallocMemorySnapshot), "Sanity Check");
++ // Uses placement new operator to initialize static area.
++ ::new ((void*)_snapshot)MallocMemorySnapshot();
++}
++
++void MallocHeader::release() const {
++ // Tracking already shutdown, no housekeeping is needed anymore
++ if (MemTracker::tracking_level() <= NMT_minimal) return;
++
++ MallocMemorySummary::record_free(size(), flags());
++ MallocMemorySummary::record_free_malloc_header(sizeof(MallocHeader));
++ if (MemTracker::tracking_level() == NMT_detail) {
++ MallocSiteTable::deallocation_at(size(), _bucket_idx, _pos_idx);
++ }
++}
++
++bool MallocHeader::record_malloc_site(const NativeCallStack& stack, size_t size,
++ size_t* bucket_idx, size_t* pos_idx) const {
++ bool ret = MallocSiteTable::allocation_at(stack, size, bucket_idx, pos_idx);
++
++ // Something went wrong, could be OOM or overflow malloc site table.
++ // We want to keep tracking data under OOM circumstance, so transition to
++ // summary tracking.
++ if (!ret) {
++ MemTracker::transition_to(NMT_summary);
++ }
++ return ret;
++}
++
++bool MallocHeader::get_stack(NativeCallStack& stack) const {
++ return MallocSiteTable::access_stack(stack, _bucket_idx, _pos_idx);
++}
++
++bool MallocTracker::initialize(NMT_TrackingLevel level) {
++ if (level >= NMT_summary) {
++ MallocMemorySummary::initialize();
++ }
++
++ if (level == NMT_detail) {
++ return MallocSiteTable::initialize();
++ }
++ return true;
++}
++
++bool MallocTracker::transition(NMT_TrackingLevel from, NMT_TrackingLevel to) {
++ assert(from != NMT_off, "Can not transition from off state");
++ assert(to != NMT_off, "Can not transition to off state");
++ assert (from != NMT_minimal, "cannot transition from minimal state");
++
++ if (from == NMT_detail) {
++ assert(to == NMT_minimal || to == NMT_summary, "Just check");
++ MallocSiteTable::shutdown();
++ }
++ return true;
++}
++
++// Record a malloc memory allocation
++void* MallocTracker::record_malloc(void* malloc_base, size_t size, MEMFLAGS flags,
++ const NativeCallStack& stack, NMT_TrackingLevel level) {
++ void* memblock; // the address for user data
++ MallocHeader* header = NULL;
++
++ if (malloc_base == NULL) {
++ return NULL;
++ }
++
++ // Uses placement global new operator to initialize malloc header
++
++ if (level == NMT_off) {
++ return malloc_base;
++ }
++
++ header = ::new (malloc_base)MallocHeader(size, flags, stack, level);
++ memblock = (void*)((char*)malloc_base + sizeof(MallocHeader));
++
++ // The alignment check: 8 bytes alignment for 32 bit systems.
++ // 16 bytes alignment for 64-bit systems.
++ assert(((size_t)memblock & (sizeof(size_t) * 2 - 1)) == 0, "Alignment check");
++
++#ifdef ASSERT
++ if (level > NMT_minimal) {
++ // Read back
++ assert(get_size(memblock) == size, "Wrong size");
++ assert(get_flags(memblock) == flags, "Wrong flags");
++ }
++#endif
++
++ return memblock;
++}
++
++void* MallocTracker::record_free(void* memblock) {
++ // Never turned on
++ if (MemTracker::tracking_level() == NMT_off ||
++ memblock == NULL) {
++ return memblock;
++ }
++ MallocHeader* header = malloc_header(memblock);
++ header->release();
++
++ return (void*)header;
++}
++
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/services/mallocTracker.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,373 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_SERVICES_MALLOC_TRACKER_HPP
++#define SHARE_VM_SERVICES_MALLOC_TRACKER_HPP
++
++#if INCLUDE_NMT
++
++#include "memory/allocation.hpp"
++#include "runtime/atomic.hpp"
++#include "services/nmtCommon.hpp"
++#include "utilities/nativeCallStack.hpp"
++
++/*
++ * This counter class counts memory allocation and deallocation,
++ * records total memory allocation size and number of allocations.
++ * The counters are updated atomically.
++ */
++class MemoryCounter VALUE_OBJ_CLASS_SPEC {
++ private:
++ size_t _count;
++ size_t _size;
++
++ DEBUG_ONLY(size_t _peak_count;)
++ DEBUG_ONLY(size_t _peak_size; )
++
++ public:
++ MemoryCounter() : _count(0), _size(0) {
++ DEBUG_ONLY(_peak_count = 0;)
++ DEBUG_ONLY(_peak_size = 0;)
++ }
++
++ inline void allocate(size_t sz) {
++ Atomic::add(1, (volatile MemoryCounterType*)&_count);
++ if (sz > 0) {
++ Atomic::add((MemoryCounterType)sz, (volatile MemoryCounterType*)&_size);
++ DEBUG_ONLY(_peak_size = MAX2(_peak_size, _size));
++ }
++ DEBUG_ONLY(_peak_count = MAX2(_peak_count, _count);)
++ }
++
++ inline void deallocate(size_t sz) {
++ assert(_count > 0, "Negative counter");
++ assert(_size >= sz, "Negative size");
++ Atomic::add(-1, (volatile MemoryCounterType*)&_count);
++ if (sz > 0) {
++ Atomic::add(-(MemoryCounterType)sz, (volatile MemoryCounterType*)&_size);
++ }
++ }
++
++ inline void resize(long sz) {
++ if (sz != 0) {
++ Atomic::add((MemoryCounterType)sz, (volatile MemoryCounterType*)&_size);
++ DEBUG_ONLY(_peak_size = MAX2(_size, _peak_size);)
++ }
++ }
++
++ inline size_t count() const { return _count; }
++ inline size_t size() const { return _size; }
++ DEBUG_ONLY(inline size_t peak_count() const { return _peak_count; })
++ DEBUG_ONLY(inline size_t peak_size() const { return _peak_size; })
++
++};
++
++/*
++ * Malloc memory used by a particular subsystem.
++ * It includes the memory acquired through os::malloc()
++ * call and arena's backing memory.
++ */
++class MallocMemory VALUE_OBJ_CLASS_SPEC {
++ private:
++ MemoryCounter _malloc;
++ MemoryCounter _arena;
++
++ public:
++ MallocMemory() { }
++
++ inline void record_malloc(size_t sz) {
++ _malloc.allocate(sz);
++ }
++
++ inline void record_free(size_t sz) {
++ _malloc.deallocate(sz);
++ }
++
++ inline void record_new_arena() {
++ _arena.allocate(0);
++ }
++
++ inline void record_arena_free() {
++ _arena.deallocate(0);
++ }
++
++ inline void record_arena_size_change(long sz) {
++ _arena.resize(sz);
++ }
++
++ inline size_t malloc_size() const { return _malloc.size(); }
++ inline size_t malloc_count() const { return _malloc.count();}
++ inline size_t arena_size() const { return _arena.size(); }
++ inline size_t arena_count() const { return _arena.count(); }
++
++ DEBUG_ONLY(inline const MemoryCounter& malloc_counter() const { return _malloc; })
++ DEBUG_ONLY(inline const MemoryCounter& arena_counter() const { return _arena; })
++};
++
++class MallocMemorySummary;
++
++// A snapshot of malloc'd memory, includes malloc memory
++// usage by types and memory used by tracking itself.
++class MallocMemorySnapshot : public ResourceObj {
++ friend class MallocMemorySummary;
++
++ private:
++ MallocMemory _malloc[mt_number_of_types];
++ MemoryCounter _tracking_header;
++
++
++ public:
++ inline MallocMemory* by_type(MEMFLAGS flags) {
++ int index = NMTUtil::flag_to_index(flags);
++ return &_malloc[index];
++ }
++
++ inline MallocMemory* by_index(int index) {
++ assert(index >= 0, "Index out of bound");
++ assert(index < mt_number_of_types, "Index out of bound");
++ return &_malloc[index];
++ }
++
++ inline MemoryCounter* malloc_overhead() {
++ return &_tracking_header;
++ }
++
++ // Total malloc'd memory amount
++ size_t total() const;
++ // Total malloc'd memory used by arenas
++ size_t total_arena() const;
++
++ inline size_t thread_count() const {
++ MallocMemorySnapshot* s = const_cast<MallocMemorySnapshot*>(this);
++ return s->by_type(mtThreadStack)->malloc_count();
++ }
++
++ void copy_to(MallocMemorySnapshot* s) {
++ s->_tracking_header = _tracking_header;
++ for (int index = 0; index < mt_number_of_types; index ++) {
++ s->_malloc[index] = _malloc[index];
++ }
++ }
++
++ // Make adjustment by subtracting chunks used by arenas
++ // from total chunks to get total free chunk size
++ void make_adjustment();
++};
++
++/*
++ * This class is for collecting malloc statistics at summary level
++ */
++class MallocMemorySummary : AllStatic {
++ private:
++ // Reserve memory for placement of MallocMemorySnapshot object
++ static size_t _snapshot[CALC_OBJ_SIZE_IN_TYPE(MallocMemorySnapshot, size_t)];
++
++ public:
++ static void initialize();
++
++ static inline void record_malloc(size_t size, MEMFLAGS flag) {
++ as_snapshot()->by_type(flag)->record_malloc(size);
++ }
++
++ static inline void record_free(size_t size, MEMFLAGS flag) {
++ as_snapshot()->by_type(flag)->record_free(size);
++ }
++
++ static inline void record_new_arena(MEMFLAGS flag) {
++ as_snapshot()->by_type(flag)->record_new_arena();
++ }
++
++ static inline void record_arena_free(MEMFLAGS flag) {
++ as_snapshot()->by_type(flag)->record_arena_free();
++ }
++
++ static inline void record_arena_size_change(long size, MEMFLAGS flag) {
++ as_snapshot()->by_type(flag)->record_arena_size_change(size);
++ }
++
++ static void snapshot(MallocMemorySnapshot* s) {
++ as_snapshot()->copy_to(s);
++ s->make_adjustment();
++ }
++
++ // Record memory used by malloc tracking header
++ static inline void record_new_malloc_header(size_t sz) {
++ as_snapshot()->malloc_overhead()->allocate(sz);
++ }
++
++ static inline void record_free_malloc_header(size_t sz) {
++ as_snapshot()->malloc_overhead()->deallocate(sz);
++ }
++
++ // The memory used by malloc tracking headers
++ static inline size_t tracking_overhead() {
++ return as_snapshot()->malloc_overhead()->size();
++ }
++
++ static MallocMemorySnapshot* as_snapshot() {
++ return (MallocMemorySnapshot*)_snapshot;
++ }
++};
++
++
++/*
++ * Malloc tracking header.
++ * To satisfy malloc alignment requirement, NMT uses 2 machine words for tracking purpose,
++ * which ensures 8-bytes alignment on 32-bit systems and 16-bytes on 64-bit systems (Product build).
++ */
++
++class MallocHeader VALUE_OBJ_CLASS_SPEC {
++#ifdef _LP64
++ size_t _size : 64;
++ size_t _flags : 8;
++ size_t _pos_idx : 16;
++ size_t _bucket_idx: 40;
++#define MAX_MALLOCSITE_TABLE_SIZE right_n_bits(40)
++#define MAX_BUCKET_LENGTH right_n_bits(16)
++#else
++ size_t _size : 32;
++ size_t _flags : 8;
++ size_t _pos_idx : 8;
++ size_t _bucket_idx: 16;
++#define MAX_MALLOCSITE_TABLE_SIZE right_n_bits(16)
++#define MAX_BUCKET_LENGTH right_n_bits(8)
++#endif // _LP64
++
++ public:
++ MallocHeader(size_t size, MEMFLAGS flags, const NativeCallStack& stack, NMT_TrackingLevel level) {
++ assert(sizeof(MallocHeader) == sizeof(void*) * 2,
++ "Wrong header size");
++
++ if (level == NMT_minimal) {
++ return;
++ }
++
++ _flags = flags;
++ set_size(size);
++ if (level == NMT_detail) {
++ size_t bucket_idx;
++ size_t pos_idx;
++ if (record_malloc_site(stack, size, &bucket_idx, &pos_idx)) {
++ assert(bucket_idx <= MAX_MALLOCSITE_TABLE_SIZE, "Overflow bucket index");
++ assert(pos_idx <= MAX_BUCKET_LENGTH, "Overflow bucket position index");
++ _bucket_idx = bucket_idx;
++ _pos_idx = pos_idx;
++ }
++ }
++
++ MallocMemorySummary::record_malloc(size, flags);
++ MallocMemorySummary::record_new_malloc_header(sizeof(MallocHeader));
++ }
++
++ inline size_t size() const { return _size; }
++ inline MEMFLAGS flags() const { return (MEMFLAGS)_flags; }
++ bool get_stack(NativeCallStack& stack) const;
++
++ // Cleanup tracking information before the memory is released.
++ void release() const;
++
++ private:
++ inline void set_size(size_t size) {
++ _size = size;
++ }
++ bool record_malloc_site(const NativeCallStack& stack, size_t size,
++ size_t* bucket_idx, size_t* pos_idx) const;
++};
++
++
++// Main class called from MemTracker to track malloc activities
++class MallocTracker : AllStatic {
++ public:
++ // Initialize malloc tracker for specific tracking level
++ static bool initialize(NMT_TrackingLevel level);
++
++ static bool transition(NMT_TrackingLevel from, NMT_TrackingLevel to);
++
++ // malloc tracking header size for specific tracking level
++ static inline size_t malloc_header_size(NMT_TrackingLevel level) {
++ return (level == NMT_off) ? 0 : sizeof(MallocHeader);
++ }
++
++ // Parameter name convention:
++ // memblock : the beginning address for user data
++ // malloc_base: the beginning address that includes malloc tracking header
++ //
++ // The relationship:
++ // memblock = (char*)malloc_base + sizeof(nmt header)
++ //
++
++ // Record malloc on specified memory block
++ static void* record_malloc(void* malloc_base, size_t size, MEMFLAGS flags,
++ const NativeCallStack& stack, NMT_TrackingLevel level);
++
++ // Record free on specified memory block
++ static void* record_free(void* memblock);
++
++ // Offset memory address to header address
++ static inline void* get_base(void* memblock);
++ static inline void* get_base(void* memblock, NMT_TrackingLevel level) {
++ if (memblock == NULL || level == NMT_off) return memblock;
++ return (char*)memblock - malloc_header_size(level);
++ }
++
++ // Get memory size
++ static inline size_t get_size(void* memblock) {
++ MallocHeader* header = malloc_header(memblock);
++ return header->size();
++ }
++
++ // Get memory type
++ static inline MEMFLAGS get_flags(void* memblock) {
++ MallocHeader* header = malloc_header(memblock);
++ return header->flags();
++ }
++
++ // Get header size
++ static inline size_t get_header_size(void* memblock) {
++ return (memblock == NULL) ? 0 : sizeof(MallocHeader);
++ }
++
++ static inline void record_new_arena(MEMFLAGS flags) {
++ MallocMemorySummary::record_new_arena(flags);
++ }
++
++ static inline void record_arena_free(MEMFLAGS flags) {
++ MallocMemorySummary::record_arena_free(flags);
++ }
++
++ static inline void record_arena_size_change(int size, MEMFLAGS flags) {
++ MallocMemorySummary::record_arena_size_change(size, flags);
++ }
++ private:
++ static inline MallocHeader* malloc_header(void *memblock) {
++ assert(memblock != NULL, "NULL pointer");
++ MallocHeader* header = (MallocHeader*)((char*)memblock - sizeof(MallocHeader));
++ return header;
++ }
++};
++
++#endif // INCLUDE_NMT
++
++
++#endif //SHARE_VM_SERVICES_MALLOC_TRACKER_HPP
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/services/mallocTracker.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_SERVICES_MALLOC_TRACKER_INLINE_HPP
++#define SHARE_VM_SERVICES_MALLOC_TRACKER_INLINE_HPP
++
++#include "services/mallocTracker.hpp"
++#include "services/memTracker.hpp"
++
++inline void* MallocTracker::get_base(void* memblock){
++ return get_base(memblock, MemTracker::tracking_level());
++}
++
++#endif // SHARE_VM_SERVICES_MALLOC_TRACKER_INLINE_HPP
++
+--- ./hotspot/src/share/vm/services/management.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/services/management.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -39,6 +39,7 @@
+ #include "runtime/jniHandles.hpp"
+ #include "runtime/os.hpp"
+ #include "runtime/serviceThread.hpp"
++#include "runtime/thread.inline.hpp"
+ #include "services/classLoadingService.hpp"
+ #include "services/diagnosticCommand.hpp"
+ #include "services/diagnosticFramework.hpp"
+@@ -388,23 +389,6 @@
+ return (instanceOop) element();
+ }
+
+-// Helper functions
+-static JavaThread* find_java_thread_from_id(jlong thread_id) {
+- assert(Threads_lock->owned_by_self(), "Must hold Threads_lock");
+-
+- JavaThread* java_thread = NULL;
+- // Sequential search for now. Need to do better optimization later.
+- for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) {
+- oop tobj = thread->threadObj();
+- if (!thread->is_exiting() &&
+- tobj != NULL &&
+- thread_id == java_lang_Thread::thread_id(tobj)) {
+- java_thread = thread;
+- break;
+- }
+- }
+- return java_thread;
+-}
+
+ static GCMemoryManager* get_gc_memory_manager_from_jobject(jobject mgr, TRAPS) {
+ if (mgr == NULL) {
+@@ -441,6 +425,8 @@
+ return MemoryService::get_memory_pool(ph);
+ }
+
++#endif // INCLUDE_MANAGEMENT
++
+ static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {
+ int num_threads = ids_ah->length();
+
+@@ -456,6 +442,8 @@
+ }
+ }
+
++#if INCLUDE_MANAGEMENT
++
+ static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) {
+ // check if the element of infoArray is of type ThreadInfo class
+ Klass* threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK);
+@@ -819,45 +807,6 @@
+ return prev;
+ JVM_END
+
+-// Gets an array containing the amount of memory allocated on the Java
+-// heap for a set of threads (in bytes). Each element of the array is
+-// the amount of memory allocated for the thread ID specified in the
+-// corresponding entry in the given array of thread IDs; or -1 if the
+-// thread does not exist or has terminated.
+-JVM_ENTRY(void, jmm_GetThreadAllocatedMemory(JNIEnv *env, jlongArray ids,
+- jlongArray sizeArray))
+- // Check if threads is null
+- if (ids == NULL || sizeArray == NULL) {
+- THROW(vmSymbols::java_lang_NullPointerException());
+- }
+-
+- ResourceMark rm(THREAD);
+- typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
+- typeArrayHandle ids_ah(THREAD, ta);
+-
+- typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray));
+- typeArrayHandle sizeArray_h(THREAD, sa);
+-
+- // validate the thread id array
+- validate_thread_id_array(ids_ah, CHECK);
+-
+- // sizeArray must be of the same length as the given array of thread IDs
+- int num_threads = ids_ah->length();
+- if (num_threads != sizeArray_h->length()) {
+- THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+- "The length of the given long array does not match the length of "
+- "the given array of thread IDs");
+- }
+-
+- MutexLockerEx ml(Threads_lock);
+- for (int i = 0; i < num_threads; i++) {
+- JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i));
+- if (java_thread != NULL) {
+- sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes());
+- }
+- }
+-JVM_END
+-
+ // Returns a java/lang/management/MemoryUsage object representing
+ // the memory usage for the heap or non-heap memory.
+ JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap))
+@@ -1163,7 +1112,7 @@
+ MutexLockerEx ml(Threads_lock);
+ for (int i = 0; i < num_threads; i++) {
+ jlong tid = ids_ah->long_at(i);
+- JavaThread* jt = find_java_thread_from_id(tid);
++ JavaThread* jt = Threads::find_java_thread_from_java_tid(tid);
+ oop thread_obj = (jt != NULL ? jt->threadObj() : (oop)NULL);
+ instanceHandle threadObj_h(THREAD, (instanceOop) thread_obj);
+ thread_handle_array->append(threadObj_h);
+@@ -1242,7 +1191,7 @@
+ MutexLockerEx ml(Threads_lock);
+ for (int i = 0; i < num_threads; i++) {
+ jlong tid = ids_ah->long_at(i);
+- JavaThread* jt = find_java_thread_from_id(tid);
++ JavaThread* jt = Threads::find_java_thread_from_java_tid(tid);
+ ThreadSnapshot* ts;
+ if (jt == NULL) {
+ // if the thread does not exist or now it is terminated,
+@@ -1488,7 +1437,7 @@
+ }
+ } else {
+ // reset contention statistics for a given thread
+- JavaThread* java_thread = find_java_thread_from_id(tid);
++ JavaThread* java_thread = Threads::find_java_thread_from_java_tid(tid);
+ if (java_thread == NULL) {
+ return false;
+ }
+@@ -1557,7 +1506,7 @@
+ return os::current_thread_cpu_time();
+ } else {
+ MutexLockerEx ml(Threads_lock);
+- java_thread = find_java_thread_from_id(thread_id);
++ java_thread = Threads::find_java_thread_from_java_tid(thread_id);
+ if (java_thread != NULL) {
+ return os::thread_cpu_time((Thread*) java_thread);
+ }
+@@ -1565,78 +1514,6 @@
+ return -1;
+ JVM_END
+
+-// Returns the CPU time consumed by a given thread (in nanoseconds).
+-// If thread_id == 0, CPU time for the current thread is returned.
+-// If user_sys_cpu_time = true, user level and system CPU time of
+-// a given thread is returned; otherwise, only user level CPU time
+-// is returned.
+-JVM_ENTRY(jlong, jmm_GetThreadCpuTimeWithKind(JNIEnv *env, jlong thread_id, jboolean user_sys_cpu_time))
+- if (!os::is_thread_cpu_time_supported()) {
+- return -1;
+- }
+-
+- if (thread_id < 0) {
+- THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
+- "Invalid thread ID", -1);
+- }
+-
+- JavaThread* java_thread = NULL;
+- if (thread_id == 0) {
+- // current thread
+- return os::current_thread_cpu_time(user_sys_cpu_time != 0);
+- } else {
+- MutexLockerEx ml(Threads_lock);
+- java_thread = find_java_thread_from_id(thread_id);
+- if (java_thread != NULL) {
+- return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0);
+- }
+- }
+- return -1;
+-JVM_END
+-
+-// Gets an array containing the CPU times consumed by a set of threads
+-// (in nanoseconds). Each element of the array is the CPU time for the
+-// thread ID specified in the corresponding entry in the given array
+-// of thread IDs; or -1 if the thread does not exist or has terminated.
+-// If user_sys_cpu_time = true, the sum of user level and system CPU time
+-// for the given thread is returned; otherwise, only user level CPU time
+-// is returned.
+-JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids,
+- jlongArray timeArray,
+- jboolean user_sys_cpu_time))
+- // Check if threads is null
+- if (ids == NULL || timeArray == NULL) {
+- THROW(vmSymbols::java_lang_NullPointerException());
+- }
+-
+- ResourceMark rm(THREAD);
+- typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
+- typeArrayHandle ids_ah(THREAD, ta);
+-
+- typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray));
+- typeArrayHandle timeArray_h(THREAD, tia);
+-
+- // validate the thread id array
+- validate_thread_id_array(ids_ah, CHECK);
+-
+- // timeArray must be of the same length as the given array of thread IDs
+- int num_threads = ids_ah->length();
+- if (num_threads != timeArray_h->length()) {
+- THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+- "The length of the given long array does not match the length of "
+- "the given array of thread IDs");
+- }
+-
+- MutexLockerEx ml(Threads_lock);
+- for (int i = 0; i < num_threads; i++) {
+- JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i));
+- if (java_thread != NULL) {
+- timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread,
+- user_sys_cpu_time != 0));
+- }
+- }
+-JVM_END
+-
+ // Returns a String array of all VM global flag names
+ JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
+ // last flag entry is always NULL, so subtract 1
+@@ -1823,7 +1700,7 @@
+ "This flag is not writeable.");
+ }
+
+- bool succeed;
++ bool succeed = false;
+ if (flag->is_bool()) {
+ bool bvalue = (new_value.z == JNI_TRUE ? true : false);
+ succeed = CommandLineFlags::boolAtPut(name, &bvalue, Flag::MANAGEMENT);
+@@ -1855,6 +1732,9 @@
+ }
+ ccstr svalue = java_lang_String::as_utf8_string(str);
+ succeed = CommandLineFlags::ccstrAtPut(name, &svalue, Flag::MANAGEMENT);
++ if (succeed) {
++ FREE_C_HEAP_ARRAY(char, svalue, mtInternal);
++ }
+ }
+ assert(succeed, "Setting flag should succeed");
+ JVM_END
+@@ -2319,7 +2199,122 @@
+ return (jlong)(((double)ticks / (double)os::elapsed_frequency())
+ * (double)1000.0);
+ }
++#endif // INCLUDE_MANAGEMENT
+
++// Gets an array containing the amount of memory allocated on the Java
++// heap for a set of threads (in bytes). Each element of the array is
++// the amount of memory allocated for the thread ID specified in the
++// corresponding entry in the given array of thread IDs; or -1 if the
++// thread does not exist or has terminated.
++JVM_ENTRY(void, jmm_GetThreadAllocatedMemory(JNIEnv *env, jlongArray ids,
++ jlongArray sizeArray))
++ // Check if threads is null
++ if (ids == NULL || sizeArray == NULL) {
++ THROW(vmSymbols::java_lang_NullPointerException());
++ }
++
++ ResourceMark rm(THREAD);
++ typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
++ typeArrayHandle ids_ah(THREAD, ta);
++
++ typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray));
++ typeArrayHandle sizeArray_h(THREAD, sa);
++
++ // validate the thread id array
++ validate_thread_id_array(ids_ah, CHECK);
++
++ // sizeArray must be of the same length as the given array of thread IDs
++ int num_threads = ids_ah->length();
++ if (num_threads != sizeArray_h->length()) {
++ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
++ "The length of the given long array does not match the length of "
++ "the given array of thread IDs");
++ }
++
++ MutexLockerEx ml(Threads_lock);
++ for (int i = 0; i < num_threads; i++) {
++ JavaThread* java_thread = Threads::find_java_thread_from_java_tid(ids_ah->long_at(i));
++ if (java_thread != NULL) {
++ sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes());
++ }
++ }
++JVM_END
++
++// Returns the CPU time consumed by a given thread (in nanoseconds).
++// If thread_id == 0, CPU time for the current thread is returned.
++// If user_sys_cpu_time = true, user level and system CPU time of
++// a given thread is returned; otherwise, only user level CPU time
++// is returned.
++JVM_ENTRY(jlong, jmm_GetThreadCpuTimeWithKind(JNIEnv *env, jlong thread_id, jboolean user_sys_cpu_time))
++ if (!os::is_thread_cpu_time_supported()) {
++ return -1;
++ }
++
++ if (thread_id < 0) {
++ THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
++ "Invalid thread ID", -1);
++ }
++
++ JavaThread* java_thread = NULL;
++ if (thread_id == 0) {
++ // current thread
++ return os::current_thread_cpu_time(user_sys_cpu_time != 0);
++ } else {
++ MutexLockerEx ml(Threads_lock);
++ java_thread = Threads::find_java_thread_from_java_tid(thread_id);
++ if (java_thread != NULL) {
++ return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0);
++ }
++ }
++ return -1;
++JVM_END
++
++// Gets an array containing the CPU times consumed by a set of threads
++// (in nanoseconds). Each element of the array is the CPU time for the
++// thread ID specified in the corresponding entry in the given array
++// of thread IDs; or -1 if the thread does not exist or has terminated.
++// If user_sys_cpu_time = true, the sum of user level and system CPU time
++// for the given thread is returned; otherwise, only user level CPU time
++// is returned.
++JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids,
++ jlongArray timeArray,
++ jboolean user_sys_cpu_time))
++ // Check if threads is null
++ if (ids == NULL || timeArray == NULL) {
++ THROW(vmSymbols::java_lang_NullPointerException());
++ }
++
++ ResourceMark rm(THREAD);
++ typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
++ typeArrayHandle ids_ah(THREAD, ta);
++
++ typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray));
++ typeArrayHandle timeArray_h(THREAD, tia);
++
++ // validate the thread id array
++ validate_thread_id_array(ids_ah, CHECK);
++
++ // timeArray must be of the same length as the given array of thread IDs
++ int num_threads = ids_ah->length();
++ if (num_threads != timeArray_h->length()) {
++ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
++ "The length of the given long array does not match the length of "
++ "the given array of thread IDs");
++ }
++
++ MutexLockerEx ml(Threads_lock);
++ for (int i = 0; i < num_threads; i++) {
++ JavaThread* java_thread = Threads::find_java_thread_from_java_tid(ids_ah->long_at(i));
++ if (java_thread != NULL) {
++ timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread,
++ user_sys_cpu_time != 0));
++ }
++ }
++JVM_END
++
++
++
++#if INCLUDE_MANAGEMENT
+ const struct jmmInterface_1_ jmm_interface = {
+ NULL,
+ NULL,
+--- ./hotspot/src/share/vm/services/memBaseline.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/services/memBaseline.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -22,471 +22,279 @@
+ *
+ */
+ #include "precompiled.hpp"
++
+ #include "memory/allocation.hpp"
+ #include "runtime/safepoint.hpp"
+ #include "runtime/thread.inline.hpp"
+ #include "services/memBaseline.hpp"
+ #include "services/memTracker.hpp"
+
+-
+-MemType2Name MemBaseline::MemType2NameMap[NUMBER_OF_MEMORY_TYPE] = {
+- {mtJavaHeap, "Java Heap"},
+- {mtClass, "Class"},
+- {mtThreadStack,"Thread Stack"},
+- {mtThread, "Thread"},
+- {mtCode, "Code"},
+- {mtGC, "GC"},
+- {mtCompiler, "Compiler"},
+- {mtInternal, "Internal"},
+- {mtOther, "Other"},
+- {mtSymbol, "Symbol"},
+- {mtNMT, "Memory Tracking"},
+- {mtTracing, "Tracing"},
+- {mtChunk, "Pooled Free Chunks"},
+- {mtClassShared,"Shared spaces for classes"},
+- {mtTest, "Test"},
+- {mtNone, "Unknown"} // It can happen when type tagging records are lagging
+- // behind
+-};
+-
+-MemBaseline::MemBaseline() {
+- _baselined = false;
+-
+- for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
+- _malloc_data[index].set_type(MemType2NameMap[index]._flag);
+- _vm_data[index].set_type(MemType2NameMap[index]._flag);
+- _arena_data[index].set_type(MemType2NameMap[index]._flag);
+- }
+-
+- _malloc_cs = NULL;
+- _vm_cs = NULL;
+- _vm_map = NULL;
+-
+- _number_of_classes = 0;
+- _number_of_threads = 0;
+-}
+-
+-
+-void MemBaseline::clear() {
+- if (_malloc_cs != NULL) {
+- delete _malloc_cs;
+- _malloc_cs = NULL;
+- }
+-
+- if (_vm_cs != NULL) {
+- delete _vm_cs;
+- _vm_cs = NULL;
+- }
+-
+- if (_vm_map != NULL) {
+- delete _vm_map;
+- _vm_map = NULL;
+- }
+-
+- reset();
+-}
+-
+-
+-void MemBaseline::reset() {
+- _baselined = false;
+- _total_vm_reserved = 0;
+- _total_vm_committed = 0;
+- _total_malloced = 0;
+- _number_of_classes = 0;
+-
+- if (_malloc_cs != NULL) _malloc_cs->clear();
+- if (_vm_cs != NULL) _vm_cs->clear();
+- if (_vm_map != NULL) _vm_map->clear();
+-
+- for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
+- _malloc_data[index].clear();
+- _vm_data[index].clear();
+- _arena_data[index].clear();
++/*
++ * Sizes are sorted in descenting order for reporting
++ */
++int compare_malloc_size(const MallocSite& s1, const MallocSite& s2) {
++ if (s1.size() == s2.size()) {
++ return 0;
++ } else if (s1.size() > s2.size()) {
++ return -1;
++ } else {
++ return 1;
+ }
+ }
+
+-MemBaseline::~MemBaseline() {
+- clear();
++
++int compare_virtual_memory_size(const VirtualMemoryAllocationSite& s1,
++ const VirtualMemoryAllocationSite& s2) {
++ if (s1.reserved() == s2.reserved()) {
++ return 0;
++ } else if (s1.reserved() > s2.reserved()) {
++ return -1;
++ } else {
++ return 1;
++ }
+ }
+
+-// baseline malloc'd memory records, generate overall summary and summaries by
+-// memory types
+-bool MemBaseline::baseline_malloc_summary(const MemPointerArray* malloc_records) {
+- MemPointerArrayIteratorImpl malloc_itr((MemPointerArray*)malloc_records);
+- MemPointerRecord* malloc_ptr = (MemPointerRecord*)malloc_itr.current();
+- size_t used_arena_size = 0;
+- int index;
+- while (malloc_ptr != NULL) {
+- index = flag2index(FLAGS_TO_MEMORY_TYPE(malloc_ptr->flags()));
+- size_t size = malloc_ptr->size();
+- if (malloc_ptr->is_arena_memory_record()) {
+- // We do have anonymous arenas, they are either used as value objects,
+- // which are embedded inside other objects, or used as stack objects.
+- _arena_data[index].inc(size);
+- used_arena_size += size;
++// Sort into allocation site addresses order for baseline comparison
++int compare_malloc_site(const MallocSite& s1, const MallocSite& s2) {
++ return s1.call_stack()->compare(*s2.call_stack());
++}
++
++
++int compare_virtual_memory_site(const VirtualMemoryAllocationSite& s1,
++ const VirtualMemoryAllocationSite& s2) {
++ return s1.call_stack()->compare(*s2.call_stack());
++}
++
++/*
++ * Walker to walk malloc allocation site table
++ */
++class MallocAllocationSiteWalker : public MallocSiteWalker {
++ private:
++ SortedLinkedList<MallocSite, compare_malloc_size> _malloc_sites;
++ size_t _count;
++
++ // Entries in MallocSiteTable with size = 0 and count = 0,
++ // when the malloc site is not longer there.
++ public:
++ MallocAllocationSiteWalker() : _count(0) { }
++
++ inline size_t count() const { return _count; }
++
++ LinkedList<MallocSite>* malloc_sites() {
++ return &_malloc_sites;
++ }
++
++ bool do_malloc_site(const MallocSite* site) {
++ if (site->size() >= MemBaseline::SIZE_THRESHOLD) {
++ if (_malloc_sites.add(*site) != NULL) {
++ _count++;
++ return true;
++ } else {
++ return false; // OOM
++ }
+ } else {
+- _total_malloced += size;
+- _malloc_data[index].inc(size);
+- if (malloc_ptr->is_arena_record()) {
+- // see if arena memory record present
+- MemPointerRecord* next_malloc_ptr = (MemPointerRecordEx*)malloc_itr.peek_next();
+- if (next_malloc_ptr != NULL && next_malloc_ptr->is_arena_memory_record()) {
+- assert(next_malloc_ptr->is_memory_record_of_arena(malloc_ptr),
+- "Arena records do not match");
+- size = next_malloc_ptr->size();
+- _arena_data[index].inc(size);
+- used_arena_size += size;
+- malloc_itr.next();
+- }
++ // malloc site does not meet threshold, ignore and continue
++ return true;
++ }
++ }
++};
++
++// Compare virtual memory region's base address
++int compare_virtual_memory_base(const ReservedMemoryRegion& r1, const ReservedMemoryRegion& r2) {
++ return r1.compare(r2);
++}
++
++// Walk all virtual memory regions for baselining
++class VirtualMemoryAllocationWalker : public VirtualMemoryWalker {
++ private:
++ SortedLinkedList<ReservedMemoryRegion, compare_virtual_memory_base>
++ _virtual_memory_regions;
++ size_t _count;
++
++ public:
++ VirtualMemoryAllocationWalker() : _count(0) { }
++
++ bool do_allocation_site(const ReservedMemoryRegion* rgn) {
++ if (rgn->size() >= MemBaseline::SIZE_THRESHOLD) {
++ if (_virtual_memory_regions.add(*rgn) != NULL) {
++ _count ++;
++ return true;
++ } else {
++ return false;
+ }
+ }
+- malloc_ptr = (MemPointerRecordEx*)malloc_itr.next();
++ return true;
+ }
+
+- // substract used arena size to get size of arena chunk in free list
+- index = flag2index(mtChunk);
+- _malloc_data[index].reduce(used_arena_size);
+- // we really don't know how many chunks in free list, so just set to
+- // 0
+- _malloc_data[index].overwrite_counter(0);
++ LinkedList<ReservedMemoryRegion>* virtual_memory_allocations() {
++ return &_virtual_memory_regions;
++ }
++};
++
++
++bool MemBaseline::baseline_summary() {
++ MallocMemorySummary::snapshot(&_malloc_memory_snapshot);
++ VirtualMemorySummary::snapshot(&_virtual_memory_snapshot);
++ return true;
++}
++
++bool MemBaseline::baseline_allocation_sites() {
++ // Malloc allocation sites
++ MallocAllocationSiteWalker malloc_walker;
++ if (!MallocSiteTable::walk_malloc_site(&malloc_walker)) {
++ return false;
++ }
++
++ _malloc_sites.move(malloc_walker.malloc_sites());
++ // The malloc sites are collected in size order
++ _malloc_sites_order = by_size;
++
++ // Virtual memory allocation sites
++ VirtualMemoryAllocationWalker virtual_memory_walker;
++ if (!VirtualMemoryTracker::walk_virtual_memory(&virtual_memory_walker)) {
++ return false;
++ }
++
++ // Virtual memory allocations are collected in call stack order
++ _virtual_memory_allocations.move(virtual_memory_walker.virtual_memory_allocations());
++
++ if (!aggregate_virtual_memory_allocation_sites()) {
++ return false;
++ }
++ // Virtual memory allocation sites are aggregrated in call stack order
++ _virtual_memory_sites_order = by_address;
+
+ return true;
+ }
+
+-// check if there is a safepoint in progress, if so, block the thread
+-// for the safepoint
+-void MemBaseline::check_safepoint(JavaThread* thr) {
+- if (SafepointSynchronize::is_synchronizing()) {
+- // grab and drop the SR_lock to honor the safepoint protocol
+- MutexLocker ml(thr->SR_lock());
+- }
+-}
++bool MemBaseline::baseline(bool summaryOnly) {
++ reset();
+
+-// baseline mmap'd memory records, generate overall summary and summaries by
+-// memory types
+-bool MemBaseline::baseline_vm_summary(const MemPointerArray* vm_records) {
+- MemPointerArrayIteratorImpl vm_itr((MemPointerArray*)vm_records);
+- VMMemRegion* vm_ptr = (VMMemRegion*)vm_itr.current();
+- int index;
+- while (vm_ptr != NULL) {
+- if (vm_ptr->is_reserved_region()) {
+- index = flag2index(FLAGS_TO_MEMORY_TYPE(vm_ptr->flags()));
+- // we use the number of thread stack to count threads
+- if (IS_MEMORY_TYPE(vm_ptr->flags(), mtThreadStack)) {
+- _number_of_threads ++;
+- }
+- _total_vm_reserved += vm_ptr->size();
+- _vm_data[index].inc(vm_ptr->size(), 0);
+- } else {
+- _total_vm_committed += vm_ptr->size();
+- _vm_data[index].inc(0, vm_ptr->size());
+- }
+- vm_ptr = (VMMemRegion*)vm_itr.next();
+- }
+- return true;
+-}
++ _class_count = InstanceKlass::number_of_instance_classes();
+
+-// baseline malloc'd memory by callsites, but only the callsites with memory allocation
+-// over 1KB are stored.
+-bool MemBaseline::baseline_malloc_details(const MemPointerArray* malloc_records) {
+- assert(MemTracker::track_callsite(), "detail tracking is off");
+-
+- MemPointerArrayIteratorImpl malloc_itr(const_cast<MemPointerArray*>(malloc_records));
+- MemPointerRecordEx* malloc_ptr = (MemPointerRecordEx*)malloc_itr.current();
+- MallocCallsitePointer malloc_callsite;
+-
+- // initailize malloc callsite array
+- if (_malloc_cs == NULL) {
+- _malloc_cs = new (std::nothrow) MemPointerArrayImpl<MallocCallsitePointer>(64);
+- // out of native memory
+- if (_malloc_cs == NULL || _malloc_cs->out_of_memory()) {
+- return false;
+- }
+- } else {
+- _malloc_cs->clear();
+- }
+-
+- MemPointerArray* malloc_data = const_cast<MemPointerArray*>(malloc_records);
+-
+- // sort into callsite pc order. Details are aggregated by callsites
+- malloc_data->sort((FN_SORT)malloc_sort_by_pc);
+- bool ret = true;
+-
+- // baseline memory that is totaled over 1 KB
+- while (malloc_ptr != NULL) {
+- if (!MemPointerRecord::is_arena_memory_record(malloc_ptr->flags())) {
+- // skip thread stacks
+- if (!IS_MEMORY_TYPE(malloc_ptr->flags(), mtThreadStack)) {
+- if (malloc_callsite.addr() != malloc_ptr->pc()) {
+- if ((malloc_callsite.amount()/K) > 0) {
+- if (!_malloc_cs->append(&malloc_callsite)) {
+- ret = false;
+- break;
+- }
+- }
+- malloc_callsite = MallocCallsitePointer(malloc_ptr->pc());
+- }
+- malloc_callsite.inc(malloc_ptr->size());
+- }
+- }
+- malloc_ptr = (MemPointerRecordEx*)malloc_itr.next();
+- }
+-
+- // restore to address order. Snapshot malloc data is maintained in memory
+- // address order.
+- malloc_data->sort((FN_SORT)malloc_sort_by_addr);
+-
+- if (!ret) {
+- return false;
+- }
+- // deal with last record
+- if (malloc_callsite.addr() != 0 && (malloc_callsite.amount()/K) > 0) {
+- if (!_malloc_cs->append(&malloc_callsite)) {
+- return false;
+- }
+- }
+- return true;
+-}
+-
+-// baseline mmap'd memory by callsites
+-bool MemBaseline::baseline_vm_details(const MemPointerArray* vm_records) {
+- assert(MemTracker::track_callsite(), "detail tracking is off");
+-
+- VMCallsitePointer vm_callsite;
+- VMCallsitePointer* cur_callsite = NULL;
+- MemPointerArrayIteratorImpl vm_itr((MemPointerArray*)vm_records);
+- VMMemRegionEx* vm_ptr = (VMMemRegionEx*)vm_itr.current();
+-
+- // initialize virtual memory map array
+- if (_vm_map == NULL) {
+- _vm_map = new (std::nothrow) MemPointerArrayImpl<VMMemRegionEx>(vm_records->length());
+- if (_vm_map == NULL || _vm_map->out_of_memory()) {
+- return false;
+- }
+- } else {
+- _vm_map->clear();
+- }
+-
+- // initialize virtual memory callsite array
+- if (_vm_cs == NULL) {
+- _vm_cs = new (std::nothrow) MemPointerArrayImpl<VMCallsitePointer>(64);
+- if (_vm_cs == NULL || _vm_cs->out_of_memory()) {
+- return false;
+- }
+- } else {
+- _vm_cs->clear();
+- }
+-
+- // consolidate virtual memory data
+- VMMemRegionEx* reserved_rec = NULL;
+- VMMemRegionEx* committed_rec = NULL;
+-
+- // vm_ptr is coming in increasing base address order
+- while (vm_ptr != NULL) {
+- if (vm_ptr->is_reserved_region()) {
+- // consolidate reserved memory regions for virtual memory map.
+- // The criteria for consolidation is:
+- // 1. two adjacent reserved memory regions
+- // 2. belong to the same memory type
+- // 3. reserved from the same callsite
+- if (reserved_rec == NULL ||
+- reserved_rec->base() + reserved_rec->size() != vm_ptr->addr() ||
+- FLAGS_TO_MEMORY_TYPE(reserved_rec->flags()) != FLAGS_TO_MEMORY_TYPE(vm_ptr->flags()) ||
+- reserved_rec->pc() != vm_ptr->pc()) {
+- if (!_vm_map->append(vm_ptr)) {
+- return false;
+- }
+- // inserted reserved region, we need the pointer to the element in virtual
+- // memory map array.
+- reserved_rec = (VMMemRegionEx*)_vm_map->at(_vm_map->length() - 1);
+- } else {
+- reserved_rec->expand_region(vm_ptr->addr(), vm_ptr->size());
+- }
+-
+- if (cur_callsite != NULL && !_vm_cs->append(cur_callsite)) {
+- return false;
+- }
+- vm_callsite = VMCallsitePointer(vm_ptr->pc());
+- cur_callsite = &vm_callsite;
+- vm_callsite.inc(vm_ptr->size(), 0);
+- } else {
+- // consolidate committed memory regions for virtual memory map
+- // The criterial is:
+- // 1. two adjacent committed memory regions
+- // 2. committed from the same callsite
+- if (committed_rec == NULL ||
+- committed_rec->base() + committed_rec->size() != vm_ptr->addr() ||
+- committed_rec->pc() != vm_ptr->pc()) {
+- if (!_vm_map->append(vm_ptr)) {
+- return false;
+- }
+- committed_rec = (VMMemRegionEx*)_vm_map->at(_vm_map->length() - 1);
+- } else {
+- committed_rec->expand_region(vm_ptr->addr(), vm_ptr->size());
+- }
+- vm_callsite.inc(0, vm_ptr->size());
+- }
+- vm_ptr = (VMMemRegionEx*)vm_itr.next();
+- }
+- // deal with last record
+- if (cur_callsite != NULL && !_vm_cs->append(cur_callsite)) {
++ if (!baseline_summary()) {
+ return false;
+ }
+
+- // sort it into callsite pc order. Details are aggregated by callsites
+- _vm_cs->sort((FN_SORT)bl_vm_sort_by_pc);
++ _baseline_type = Summary_baselined;
+
+- // walk the array to consolidate record by pc
+- MemPointerArrayIteratorImpl itr(_vm_cs);
+- VMCallsitePointer* callsite_rec = (VMCallsitePointer*)itr.current();
+- VMCallsitePointer* next_rec = (VMCallsitePointer*)itr.next();
+- while (next_rec != NULL) {
+- assert(callsite_rec != NULL, "Sanity check");
+- if (next_rec->addr() == callsite_rec->addr()) {
+- callsite_rec->inc(next_rec->reserved_amount(), next_rec->committed_amount());
+- itr.remove();
+- next_rec = (VMCallsitePointer*)itr.current();
+- } else {
+- callsite_rec = next_rec;
+- next_rec = (VMCallsitePointer*)itr.next();
+- }
++ // baseline details
++ if (!summaryOnly &&
++ MemTracker::tracking_level() == NMT_detail) {
++ baseline_allocation_sites();
++ _baseline_type = Detail_baselined;
+ }
+
+ return true;
+ }
+
+-// baseline a snapshot. If summary_only = false, memory usages aggregated by
+-// callsites are also baselined.
+-// The method call can be lengthy, especially when detail tracking info is
+-// requested. So the method checks for safepoint explicitly.
+-bool MemBaseline::baseline(MemSnapshot& snapshot, bool summary_only) {
+- Thread* THREAD = Thread::current();
+- assert(THREAD->is_Java_thread(), "must be a JavaThread");
+- MutexLocker snapshot_locker(snapshot._lock);
+- reset();
+- _baselined = baseline_malloc_summary(snapshot._alloc_ptrs);
+- if (_baselined) {
+- check_safepoint((JavaThread*)THREAD);
+- _baselined = baseline_vm_summary(snapshot._vm_ptrs);
+- }
+- _number_of_classes = snapshot.number_of_classes();
+-
+- if (!summary_only && MemTracker::track_callsite() && _baselined) {
+- check_safepoint((JavaThread*)THREAD);
+- _baselined = baseline_malloc_details(snapshot._alloc_ptrs);
+- if (_baselined) {
+- check_safepoint((JavaThread*)THREAD);
+- _baselined = baseline_vm_details(snapshot._vm_ptrs);
+- }
+- }
+- return _baselined;
++int compare_allocation_site(const VirtualMemoryAllocationSite& s1,
++ const VirtualMemoryAllocationSite& s2) {
++ return s1.call_stack()->compare(*s2.call_stack());
+ }
+
++bool MemBaseline::aggregate_virtual_memory_allocation_sites() {
++ SortedLinkedList<VirtualMemoryAllocationSite, compare_allocation_site> allocation_sites;
+
+-int MemBaseline::flag2index(MEMFLAGS flag) const {
+- for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
+- if (MemType2NameMap[index]._flag == flag) {
+- return index;
++ VirtualMemoryAllocationIterator itr = virtual_memory_allocations();
++ const ReservedMemoryRegion* rgn;
++ VirtualMemoryAllocationSite* site;
++ while ((rgn = itr.next()) != NULL) {
++ VirtualMemoryAllocationSite tmp(*rgn->call_stack());
++ site = allocation_sites.find(tmp);
++ if (site == NULL) {
++ LinkedListNode<VirtualMemoryAllocationSite>* node =
++ allocation_sites.add(tmp);
++ if (node == NULL) return false;
++ site = node->data();
+ }
++ site->reserve_memory(rgn->size());
++ site->commit_memory(rgn->committed_size());
+ }
+- assert(false, "no type");
+- return -1;
++
++ _virtual_memory_sites.move(&allocation_sites);
++ return true;
+ }
+
+-const char* MemBaseline::type2name(MEMFLAGS type) {
+- for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
+- if (MemType2NameMap[index]._flag == type) {
+- return MemType2NameMap[index]._name;
+- }
++MallocSiteIterator MemBaseline::malloc_sites(SortingOrder order) {
++ assert(!_malloc_sites.is_empty(), "Not detail baseline");
++ switch(order) {
++ case by_size:
++ malloc_sites_to_size_order();
++ break;
++ case by_site:
++ malloc_sites_to_allocation_site_order();
++ break;
++ case by_address:
++ default:
++ ShouldNotReachHere();
+ }
+- assert(false, err_msg("bad type %x", type));
+- return NULL;
++ return MallocSiteIterator(_malloc_sites.head());
+ }
+
+-
+-MemBaseline& MemBaseline::operator=(const MemBaseline& other) {
+- _total_malloced = other._total_malloced;
+- _total_vm_reserved = other._total_vm_reserved;
+- _total_vm_committed = other._total_vm_committed;
+-
+- _baselined = other._baselined;
+- _number_of_classes = other._number_of_classes;
+-
+- for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
+- _malloc_data[index] = other._malloc_data[index];
+- _vm_data[index] = other._vm_data[index];
+- _arena_data[index] = other._arena_data[index];
++VirtualMemorySiteIterator MemBaseline::virtual_memory_sites(SortingOrder order) {
++ assert(!_virtual_memory_sites.is_empty(), "Not detail baseline");
++ switch(order) {
++ case by_size:
++ virtual_memory_sites_to_size_order();
++ break;
++ case by_site:
++ virtual_memory_sites_to_reservation_site_order();
++ break;
++ case by_address:
++ default:
++ ShouldNotReachHere();
+ }
+-
+- if (MemTracker::track_callsite()) {
+- assert(_malloc_cs != NULL && _vm_cs != NULL, "out of memory");
+- assert(other._malloc_cs != NULL && other._vm_cs != NULL,
+- "not properly baselined");
+- _malloc_cs->clear();
+- _vm_cs->clear();
+- int index;
+- for (index = 0; index < other._malloc_cs->length(); index ++) {
+- _malloc_cs->append(other._malloc_cs->at(index));
+- }
+-
+- for (index = 0; index < other._vm_cs->length(); index ++) {
+- _vm_cs->append(other._vm_cs->at(index));
+- }
+- }
+- return *this;
++ return VirtualMemorySiteIterator(_virtual_memory_sites.head());
+ }
+
+-/* compare functions for sorting */
+
+-// sort snapshot malloc'd records in callsite pc order
+-int MemBaseline::malloc_sort_by_pc(const void* p1, const void* p2) {
+- assert(MemTracker::track_callsite(),"Just check");
+- const MemPointerRecordEx* mp1 = (const MemPointerRecordEx*)p1;
+- const MemPointerRecordEx* mp2 = (const MemPointerRecordEx*)p2;
+- return UNSIGNED_COMPARE(mp1->pc(), mp2->pc());
++// Sorting allocations sites in different orders
++void MemBaseline::malloc_sites_to_size_order() {
++ if (_malloc_sites_order != by_size) {
++ SortedLinkedList<MallocSite, compare_malloc_size> tmp;
++
++ // Add malloc sites to sorted linked list to sort into size order
++ tmp.move(&_malloc_sites);
++ _malloc_sites.set_head(tmp.head());
++ tmp.set_head(NULL);
++ _malloc_sites_order = by_size;
++ }
+ }
+
+-// sort baselined malloc'd records in size order
+-int MemBaseline::bl_malloc_sort_by_size(const void* p1, const void* p2) {
+- assert(MemTracker::is_on(), "Just check");
+- const MallocCallsitePointer* mp1 = (const MallocCallsitePointer*)p1;
+- const MallocCallsitePointer* mp2 = (const MallocCallsitePointer*)p2;
+- return UNSIGNED_COMPARE(mp2->amount(), mp1->amount());
++void MemBaseline::malloc_sites_to_allocation_site_order() {
++ if (_malloc_sites_order != by_site) {
++ SortedLinkedList<MallocSite, compare_malloc_site> tmp;
++ // Add malloc sites to sorted linked list to sort into site (address) order
++ tmp.move(&_malloc_sites);
++ _malloc_sites.set_head(tmp.head());
++ tmp.set_head(NULL);
++ _malloc_sites_order = by_site;
++ }
+ }
+
+-// sort baselined malloc'd records in callsite pc order
+-int MemBaseline::bl_malloc_sort_by_pc(const void* p1, const void* p2) {
+- assert(MemTracker::is_on(), "Just check");
+- const MallocCallsitePointer* mp1 = (const MallocCallsitePointer*)p1;
+- const MallocCallsitePointer* mp2 = (const MallocCallsitePointer*)p2;
+- return UNSIGNED_COMPARE(mp1->addr(), mp2->addr());
++void MemBaseline::virtual_memory_sites_to_size_order() {
++ if (_virtual_memory_sites_order != by_size) {
++ SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size> tmp;
++
++ tmp.move(&_virtual_memory_sites);
++
++ _virtual_memory_sites.set_head(tmp.head());
++ tmp.set_head(NULL);
++ _virtual_memory_sites_order = by_size;
++ }
+ }
+
++void MemBaseline::virtual_memory_sites_to_reservation_site_order() {
++ if (_virtual_memory_sites_order != by_size) {
++ SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_site> tmp;
+
+-// sort baselined mmap'd records in size (reserved size) order
+-int MemBaseline::bl_vm_sort_by_size(const void* p1, const void* p2) {
+- assert(MemTracker::is_on(), "Just check");
+- const VMCallsitePointer* mp1 = (const VMCallsitePointer*)p1;
+- const VMCallsitePointer* mp2 = (const VMCallsitePointer*)p2;
+- return UNSIGNED_COMPARE(mp2->reserved_amount(), mp1->reserved_amount());
++ tmp.move(&_virtual_memory_sites);
++
++ _virtual_memory_sites.set_head(tmp.head());
++ tmp.set_head(NULL);
++
++ _virtual_memory_sites_order = by_size;
++ }
+ }
+
+-// sort baselined mmap'd records in callsite pc order
+-int MemBaseline::bl_vm_sort_by_pc(const void* p1, const void* p2) {
+- assert(MemTracker::is_on(), "Just check");
+- const VMCallsitePointer* mp1 = (const VMCallsitePointer*)p1;
+- const VMCallsitePointer* mp2 = (const VMCallsitePointer*)p2;
+- return UNSIGNED_COMPARE(mp1->addr(), mp2->addr());
+-}
+-
+-
+-// sort snapshot malloc'd records in memory block address order
+-int MemBaseline::malloc_sort_by_addr(const void* p1, const void* p2) {
+- assert(MemTracker::is_on(), "Just check");
+- const MemPointerRecord* mp1 = (const MemPointerRecord*)p1;
+- const MemPointerRecord* mp2 = (const MemPointerRecord*)p2;
+- int delta = UNSIGNED_COMPARE(mp1->addr(), mp2->addr());
+- assert(p1 == p2 || delta != 0, "dup pointer");
+- return delta;
+-}
+-
+--- ./hotspot/src/share/vm/services/memBaseline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/services/memBaseline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -25,425 +25,176 @@
+ #ifndef SHARE_VM_SERVICES_MEM_BASELINE_HPP
+ #define SHARE_VM_SERVICES_MEM_BASELINE_HPP
+
++#if INCLUDE_NMT
++
+ #include "memory/allocation.hpp"
+ #include "runtime/mutex.hpp"
+-#include "services/memPtr.hpp"
+-#include "services/memSnapshot.hpp"
++#include "services/mallocSiteTable.hpp"
++#include "services/mallocTracker.hpp"
++#include "services/nmtCommon.hpp"
++#include "services/virtualMemoryTracker.hpp"
++#include "utilities/linkedlist.hpp"
+
+-// compare unsigned number
+-#define UNSIGNED_COMPARE(a, b) ((a > b) ? 1 : ((a == b) ? 0 : -1))
++typedef LinkedListIterator<MallocSite> MallocSiteIterator;
++typedef LinkedListIterator<VirtualMemoryAllocationSite> VirtualMemorySiteIterator;
++typedef LinkedListIterator<ReservedMemoryRegion> VirtualMemoryAllocationIterator;
+
+ /*
+- * MallocCallsitePointer and VMCallsitePointer are used
+- * to baseline memory blocks with their callsite information.
+- * They are only available when detail tracking is turned
+- * on.
++ * Baseline a memory snapshot
+ */
+-
+-/* baselined malloc record aggregated by callsite */
+-class MallocCallsitePointer : public MemPointer {
+- private:
+- size_t _count; // number of malloc invocation from this callsite
+- size_t _amount; // total amount of memory malloc-ed from this callsite
+-
++class MemBaseline VALUE_OBJ_CLASS_SPEC {
+ public:
+- MallocCallsitePointer() {
+- _count = 0;
+- _amount = 0;
+- }
+-
+- MallocCallsitePointer(address pc) : MemPointer(pc) {
+- _count = 0;
+- _amount = 0;
+- }
+-
+- MallocCallsitePointer& operator=(const MallocCallsitePointer& p) {
+- MemPointer::operator=(p);
+- _count = p.count();
+- _amount = p.amount();
+- return *this;
+- }
+-
+- inline void inc(size_t size) {
+- _count ++;
+- _amount += size;
++ enum BaselineThreshold {
++ SIZE_THRESHOLD = K // Only allocation size over this threshold will be baselined.
+ };
+
+- inline size_t count() const {
+- return _count;
+- }
++ enum BaselineType {
++ Not_baselined,
++ Summary_baselined,
++ Detail_baselined
++ };
+
+- inline size_t amount() const {
+- return _amount;
+- }
+-};
+-
+-// baselined virtual memory record aggregated by callsite
+-class VMCallsitePointer : public MemPointer {
+- private:
+- size_t _count; // number of invocation from this callsite
+- size_t _reserved_amount; // total reserved amount
+- size_t _committed_amount; // total committed amount
+-
+- public:
+- VMCallsitePointer() {
+- _count = 0;
+- _reserved_amount = 0;
+- _committed_amount = 0;
+- }
+-
+- VMCallsitePointer(address pc) : MemPointer(pc) {
+- _count = 0;
+- _reserved_amount = 0;
+- _committed_amount = 0;
+- }
+-
+- VMCallsitePointer& operator=(const VMCallsitePointer& p) {
+- MemPointer::operator=(p);
+- _count = p.count();
+- _reserved_amount = p.reserved_amount();
+- _committed_amount = p.committed_amount();
+- return *this;
+- }
+-
+- inline void inc(size_t reserved, size_t committed) {
+- _count ++;
+- _reserved_amount += reserved;
+- _committed_amount += committed;
+- }
+-
+- inline size_t count() const {
+- return _count;
+- }
+-
+- inline size_t reserved_amount() const {
+- return _reserved_amount;
+- }
+-
+- inline size_t committed_amount() const {
+- return _committed_amount;
+- }
+-};
+-
+-// maps a memory type flag to readable name
+-typedef struct _memType2Name {
+- MEMFLAGS _flag;
+- const char* _name;
+-} MemType2Name;
+-
+-
+-// This class aggregates malloc'd records by memory type
+-class MallocMem VALUE_OBJ_CLASS_SPEC {
+- private:
+- MEMFLAGS _type;
+-
+- size_t _count;
+- size_t _amount;
+-
+- public:
+- MallocMem() {
+- _type = mtNone;
+- _count = 0;
+- _amount = 0;
+- }
+-
+- MallocMem(MEMFLAGS flags) {
+- assert(HAS_VALID_MEMORY_TYPE(flags), "no type");
+- _type = FLAGS_TO_MEMORY_TYPE(flags);
+- _count = 0;
+- _amount = 0;
+- }
+-
+- inline void set_type(MEMFLAGS flag) {
+- _type = flag;
+- }
+-
+- inline void clear() {
+- _count = 0;
+- _amount = 0;
+- _type = mtNone;
+- }
+-
+- MallocMem& operator=(const MallocMem& m) {
+- assert(_type == m.type(), "different type");
+- _count = m.count();
+- _amount = m.amount();
+- return *this;
+- }
+-
+- inline void inc(size_t amt) {
+- _amount += amt;
+- _count ++;
+- }
+-
+- inline void reduce(size_t amt) {
+- assert(_amount >= amt, "Just check");
+- _amount -= amt;
+- }
+-
+- inline void overwrite_counter(size_t count) {
+- _count = count;
+- }
+-
+- inline MEMFLAGS type() const {
+- return _type;
+- }
+-
+- inline bool is_type(MEMFLAGS flags) const {
+- return FLAGS_TO_MEMORY_TYPE(flags) == _type;
+- }
+-
+- inline size_t count() const {
+- return _count;
+- }
+-
+- inline size_t amount() const {
+- return _amount;
+- }
+-};
+-
+-// This class records live arena's memory usage
+-class ArenaMem : public MallocMem {
+- public:
+- ArenaMem(MEMFLAGS typeflag): MallocMem(typeflag) {
+- }
+- ArenaMem() { }
+-};
+-
+-// This class aggregates virtual memory by its memory type
+-class VMMem VALUE_OBJ_CLASS_SPEC {
+- private:
+- MEMFLAGS _type;
+-
+- size_t _count;
+- size_t _reserved_amount;
+- size_t _committed_amount;
+-
+- public:
+- VMMem() {
+- _type = mtNone;
+- _count = 0;
+- _reserved_amount = 0;
+- _committed_amount = 0;
+- }
+-
+- VMMem(MEMFLAGS flags) {
+- assert(HAS_VALID_MEMORY_TYPE(flags), "no type");
+- _type = FLAGS_TO_MEMORY_TYPE(flags);
+- _count = 0;
+- _reserved_amount = 0;
+- _committed_amount = 0;
+- }
+-
+- inline void clear() {
+- _type = mtNone;
+- _count = 0;
+- _reserved_amount = 0;
+- _committed_amount = 0;
+- }
+-
+- inline void set_type(MEMFLAGS flags) {
+- _type = FLAGS_TO_MEMORY_TYPE(flags);
+- }
+-
+- VMMem& operator=(const VMMem& m) {
+- assert(_type == m.type(), "different type");
+-
+- _count = m.count();
+- _reserved_amount = m.reserved_amount();
+- _committed_amount = m.committed_amount();
+- return *this;
+- }
+-
+-
+- inline MEMFLAGS type() const {
+- return _type;
+- }
+-
+- inline bool is_type(MEMFLAGS flags) const {
+- return FLAGS_TO_MEMORY_TYPE(flags) == _type;
+- }
+-
+- inline void inc(size_t reserved_amt, size_t committed_amt) {
+- _reserved_amount += reserved_amt;
+- _committed_amount += committed_amt;
+- _count ++;
+- }
+-
+- inline size_t count() const {
+- return _count;
+- }
+-
+- inline size_t reserved_amount() const {
+- return _reserved_amount;
+- }
+-
+- inline size_t committed_amount() const {
+- return _committed_amount;
+- }
+-};
+-
+-
+-
+-#define NUMBER_OF_MEMORY_TYPE (mt_number_of_types + 1)
+-
+-class BaselineReporter;
+-class BaselineComparisonReporter;
+-
+-/*
+- * This class baselines current memory snapshot.
+- * A memory baseline summarizes memory usage by memory type,
+- * aggregates memory usage by callsites when detail tracking
+- * is on.
+- */
+-class MemBaseline VALUE_OBJ_CLASS_SPEC {
+- friend class BaselineReporter;
+- friend class BaselineComparisonReporter;
++ enum SortingOrder {
++ by_address, // by memory address
++ by_size, // by memory size
++ by_site // by call site where the memory is allocated from
++ };
+
+ private:
+- // overall summaries
+- size_t _total_malloced;
+- size_t _total_vm_reserved;
+- size_t _total_vm_committed;
+- size_t _number_of_classes;
+- size_t _number_of_threads;
++ // Summary information
++ MallocMemorySnapshot _malloc_memory_snapshot;
++ VirtualMemorySnapshot _virtual_memory_snapshot;
+
+- // if it has properly baselined
+- bool _baselined;
++ size_t _class_count;
+
+- // we categorize memory into three categories within the memory type
+- MallocMem _malloc_data[NUMBER_OF_MEMORY_TYPE];
+- VMMem _vm_data[NUMBER_OF_MEMORY_TYPE];
+- ArenaMem _arena_data[NUMBER_OF_MEMORY_TYPE];
++ // Allocation sites information
++ // Malloc allocation sites
++ LinkedListImpl<MallocSite> _malloc_sites;
+
+- // memory records that aggregate memory usage by callsites.
+- // only available when detail tracking is on.
+- MemPointerArray* _malloc_cs;
+- MemPointerArray* _vm_cs;
+- // virtual memory map
+- MemPointerArray* _vm_map;
++ // All virtual memory allocations
++ LinkedListImpl<ReservedMemoryRegion> _virtual_memory_allocations;
+
+- private:
+- static MemType2Name MemType2NameMap[NUMBER_OF_MEMORY_TYPE];
++ // Virtual memory allocations by allocation sites, always in by_address
++ // order
++ LinkedListImpl<VirtualMemoryAllocationSite> _virtual_memory_sites;
+
+- private:
+- // should not use copy constructor
+- MemBaseline(MemBaseline& copy) { ShouldNotReachHere(); }
++ SortingOrder _malloc_sites_order;
++ SortingOrder _virtual_memory_sites_order;
+
+- // check and block at a safepoint
+- static inline void check_safepoint(JavaThread* thr);
++ BaselineType _baseline_type;
+
+ public:
+ // create a memory baseline
+- MemBaseline();
+-
+- ~MemBaseline();
+-
+- inline bool baselined() const {
+- return _baselined;
++ MemBaseline():
++ _baseline_type(Not_baselined),
++ _class_count(0) {
+ }
+
+- MemBaseline& operator=(const MemBaseline& other);
++ bool baseline(bool summaryOnly = true);
++
++ BaselineType baseline_type() const { return _baseline_type; }
++
++ MallocMemorySnapshot* malloc_memory_snapshot() {
++ return &_malloc_memory_snapshot;
++ }
++
++ VirtualMemorySnapshot* virtual_memory_snapshot() {
++ return &_virtual_memory_snapshot;
++ }
++
++ MallocSiteIterator malloc_sites(SortingOrder order);
++ VirtualMemorySiteIterator virtual_memory_sites(SortingOrder order);
++
++ // Virtual memory allocation iterator always returns in virtual memory
++ // base address order.
++ VirtualMemoryAllocationIterator virtual_memory_allocations() {
++ assert(!_virtual_memory_allocations.is_empty(), "Not detail baseline");
++ return VirtualMemoryAllocationIterator(_virtual_memory_allocations.head());
++ }
++
++ // Total reserved memory = total malloc'd memory + total reserved virtual
++ // memory
++ size_t total_reserved_memory() const {
++ assert(baseline_type() != Not_baselined, "Not yet baselined");
++ size_t amount = _malloc_memory_snapshot.total() +
++ _virtual_memory_snapshot.total_reserved();
++ return amount;
++ }
++
++ // Total committed memory = total malloc'd memory + total committed
++ // virtual memory
++ size_t total_committed_memory() const {
++ assert(baseline_type() != Not_baselined, "Not yet baselined");
++ size_t amount = _malloc_memory_snapshot.total() +
++ _virtual_memory_snapshot.total_committed();
++ return amount;
++ }
++
++ size_t total_arena_memory() const {
++ assert(baseline_type() != Not_baselined, "Not yet baselined");
++ return _malloc_memory_snapshot.total_arena();
++ }
++
++ size_t malloc_tracking_overhead() const {
++ assert(baseline_type() != Not_baselined, "Not yet baselined");
++ MemBaseline* bl = const_cast<MemBaseline*>(this);
++ return bl->_malloc_memory_snapshot.malloc_overhead()->size();
++ }
++
++ MallocMemory* malloc_memory(MEMFLAGS flag) {
++ assert(baseline_type() != Not_baselined, "Not yet baselined");
++ return _malloc_memory_snapshot.by_type(flag);
++ }
++
++ VirtualMemory* virtual_memory(MEMFLAGS flag) {
++ assert(baseline_type() != Not_baselined, "Not yet baselined");
++ return _virtual_memory_snapshot.by_type(flag);
++ }
++
++
++ size_t class_count() const {
++ assert(baseline_type() != Not_baselined, "Not yet baselined");
++ return _class_count;
++ }
++
++ size_t thread_count() const {
++ assert(baseline_type() != Not_baselined, "Not yet baselined");
++ return _malloc_memory_snapshot.thread_count();
++ }
+
+ // reset the baseline for reuse
+- void clear();
++ void reset() {
++ _baseline_type = Not_baselined;
++ // _malloc_memory_snapshot and _virtual_memory_snapshot are copied over.
++ _class_count = 0;
+
+- // baseline the snapshot
+- bool baseline(MemSnapshot& snapshot, bool summary_only = true);
+-
+- bool baseline(const MemPointerArray* malloc_records,
+- const MemPointerArray* vm_records,
+- bool summary_only = true);
+-
+- // total malloc'd memory of specified memory type
+- inline size_t malloc_amount(MEMFLAGS flag) const {
+- return _malloc_data[flag2index(flag)].amount();
+- }
+- // number of malloc'd memory blocks of specified memory type
+- inline size_t malloc_count(MEMFLAGS flag) const {
+- return _malloc_data[flag2index(flag)].count();
+- }
+- // total memory used by arenas of specified memory type
+- inline size_t arena_amount(MEMFLAGS flag) const {
+- return _arena_data[flag2index(flag)].amount();
+- }
+- // number of arenas of specified memory type
+- inline size_t arena_count(MEMFLAGS flag) const {
+- return _arena_data[flag2index(flag)].count();
+- }
+- // total reserved memory of specified memory type
+- inline size_t reserved_amount(MEMFLAGS flag) const {
+- return _vm_data[flag2index(flag)].reserved_amount();
+- }
+- // total committed memory of specified memory type
+- inline size_t committed_amount(MEMFLAGS flag) const {
+- return _vm_data[flag2index(flag)].committed_amount();
+- }
+- // total memory (malloc'd + mmap'd + arena) of specified
+- // memory type
+- inline size_t total_amount(MEMFLAGS flag) const {
+- int index = flag2index(flag);
+- return _malloc_data[index].amount() +
+- _vm_data[index].reserved_amount() +
+- _arena_data[index].amount();
++ _malloc_sites.clear();
++ _virtual_memory_sites.clear();
++ _virtual_memory_allocations.clear();
+ }
+
+- /* overall summaries */
++ private:
++ // Baseline summary information
++ bool baseline_summary();
+
+- // total malloc'd memory in snapshot
+- inline size_t total_malloc_amount() const {
+- return _total_malloced;
+- }
+- // total mmap'd memory in snapshot
+- inline size_t total_reserved_amount() const {
+- return _total_vm_reserved;
+- }
+- // total committed memory in snapshot
+- inline size_t total_committed_amount() const {
+- return _total_vm_committed;
+- }
+- // number of loaded classes
+- inline size_t number_of_classes() const {
+- return _number_of_classes;
+- }
+- // number of running threads
+- inline size_t number_of_threads() const {
+- return _number_of_threads;
+- }
+- // lookup human readable name of a memory type
+- static const char* type2name(MEMFLAGS type);
++ // Baseline allocation sites (detail tracking only)
++ bool baseline_allocation_sites();
+
+- private:
+- // convert memory flag to the index to mapping table
+- int flag2index(MEMFLAGS flag) const;
++ // Aggregate virtual memory allocation by allocation sites
++ bool aggregate_virtual_memory_allocation_sites();
+
+- // reset baseline values
+- void reset();
++ // Sorting allocation sites in different orders
++ // Sort allocation sites in size order
++ void malloc_sites_to_size_order();
++ // Sort allocation sites in call site address order
++ void malloc_sites_to_allocation_site_order();
+
+- // summarize the records in global snapshot
+- bool baseline_malloc_summary(const MemPointerArray* malloc_records);
+- bool baseline_vm_summary(const MemPointerArray* vm_records);
+- bool baseline_malloc_details(const MemPointerArray* malloc_records);
+- bool baseline_vm_details(const MemPointerArray* vm_records);
+-
+- // print a line of malloc'd memory aggregated by callsite
+- void print_malloc_callsite(outputStream* st, address pc, size_t size,
+- size_t count, int diff_amt, int diff_count) const;
+- // print a line of mmap'd memory aggregated by callsite
+- void print_vm_callsite(outputStream* st, address pc, size_t rsz,
+- size_t csz, int diff_rsz, int diff_csz) const;
+-
+- // sorting functions for raw records
+- static int malloc_sort_by_pc(const void* p1, const void* p2);
+- static int malloc_sort_by_addr(const void* p1, const void* p2);
+-
+- private:
+- // sorting functions for baselined records
+- static int bl_malloc_sort_by_size(const void* p1, const void* p2);
+- static int bl_vm_sort_by_size(const void* p1, const void* p2);
+- static int bl_malloc_sort_by_pc(const void* p1, const void* p2);
+- static int bl_vm_sort_by_pc(const void* p1, const void* p2);
++ // Sort allocation sites in reserved size order
++ void virtual_memory_sites_to_size_order();
++ // Sort allocation sites in call site address order
++ void virtual_memory_sites_to_reservation_site_order();
+ };
+
++#endif // INCLUDE_NMT
+
+ #endif // SHARE_VM_SERVICES_MEM_BASELINE_HPP
+--- ./hotspot/src/share/vm/services/memPtr.cpp Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,42 +0,0 @@
+-/*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- *
+- */
+-
+-#include "precompiled.hpp"
+-#include "services/memPtr.hpp"
+-#include "services/memTracker.hpp"
+-
+-volatile jint SequenceGenerator::_seq_number = 1;
+-volatile unsigned long SequenceGenerator::_generation = 1;
+-NOT_PRODUCT(jint SequenceGenerator::_max_seq_number = 1;)
+-
+-jint SequenceGenerator::next() {
+- jint seq = Atomic::add(1, &_seq_number);
+- if (seq < 0) {
+- MemTracker::shutdown(MemTracker::NMT_sequence_overflow);
+- } else {
+- NOT_PRODUCT(_max_seq_number = (seq > _max_seq_number) ? seq : _max_seq_number;)
+- }
+- return seq;
+-}
+-
+--- ./hotspot/src/share/vm/services/memPtr.hpp Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,510 +0,0 @@
+-/*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- *
+- */
+-
+-#ifndef SHARE_VM_SERVICES_MEM_PTR_HPP
+-#define SHARE_VM_SERVICES_MEM_PTR_HPP
+-
+-#include "memory/allocation.hpp"
+-#include "runtime/atomic.hpp"
+-#include "runtime/os.hpp"
+-#include "runtime/safepoint.hpp"
+-
+-/*
+- * global sequence generator that generates sequence numbers to serialize
+- * memory records.
+- */
+-class SequenceGenerator : AllStatic {
+- public:
+- static jint next();
+-
+- // peek last sequence number
+- static jint peek() {
+- return _seq_number;
+- }
+-
+- // reset sequence number
+- static void reset() {
+- assert(SafepointSynchronize::is_at_safepoint(), "Safepoint required");
+- _seq_number = 1;
+- _generation ++;
+- };
+-
+- static unsigned long current_generation() { return _generation; }
+- NOT_PRODUCT(static jint max_seq_num() { return _max_seq_number; })
+-
+- private:
+- static volatile jint _seq_number;
+- static volatile unsigned long _generation;
+- NOT_PRODUCT(static jint _max_seq_number; )
+-};
+-
+-/*
+- * followings are the classes that are used to hold memory activity records in different stages.
+- * MemPointer
+- * |--------MemPointerRecord
+- * |
+- * |----MemPointerRecordEx
+- * | |
+- * | |-------SeqMemPointerRecordEx
+- * |
+- * |----SeqMemPointerRecord
+- * |
+- * |----VMMemRegion
+- * |
+- * |-----VMMemRegionEx
+- *
+- *
+- * prefix 'Seq' - sequenced, the record contains a sequence number
+- * surfix 'Ex' - extension, the record contains a caller's pc
+- *
+- * per-thread recorder : SeqMemPointerRecord(Ex)
+- * snapshot staging : SeqMemPointerRecord(Ex)
+- * snapshot : MemPointerRecord(Ex) and VMMemRegion(Ex)
+- *
+- */
+-
+-/*
+- * class that wraps an address to a memory block,
+- * the memory pointer either points to a malloc'd
+- * memory block, or a mmap'd memory block
+- */
+-class MemPointer VALUE_OBJ_CLASS_SPEC {
+- public:
+- MemPointer(): _addr(0) { }
+- MemPointer(address addr): _addr(addr) { }
+-
+- MemPointer(const MemPointer& copy_from) {
+- _addr = copy_from.addr();
+- }
+-
+- inline address addr() const {
+- return _addr;
+- }
+-
+- inline operator address() const {
+- return addr();
+- }
+-
+- inline bool operator == (const MemPointer& other) const {
+- return addr() == other.addr();
+- }
+-
+- inline MemPointer& operator = (const MemPointer& other) {
+- _addr = other.addr();
+- return *this;
+- }
+-
+- protected:
+- inline void set_addr(address addr) { _addr = addr; }
+-
+- protected:
+- // memory address
+- address _addr;
+-};
+-
+-/* MemPointerRecord records an activityand associated
+- * attributes on a memory block.
+- */
+-class MemPointerRecord : public MemPointer {
+- private:
+- MEMFLAGS _flags;
+- size_t _size;
+-
+-public:
+- /* extension of MemoryType enum
+- * see share/vm/memory/allocation.hpp for details.
+- *
+- * The tag values are associated to sorting orders, so be
+- * careful if changes are needed.
+- * The allocation records should be sorted ahead of tagging
+- * records, which in turn ahead of deallocation records
+- */
+- enum MemPointerTags {
+- tag_alloc = 0x0001, // malloc or reserve record
+- tag_commit = 0x0002, // commit record
+- tag_type = 0x0003, // tag virtual memory to a memory type
+- tag_uncommit = 0x0004, // uncommit record
+- tag_release = 0x0005, // free or release record
+- tag_size = 0x0006, // arena size
+- tag_masks = 0x0007, // all tag bits
+- vmBit = 0x0008
+- };
+-
+- /* helper functions to interpret the tagging flags */
+-
+- inline static bool is_allocation_record(MEMFLAGS flags) {
+- return (flags & tag_masks) == tag_alloc;
+- }
+-
+- inline static bool is_deallocation_record(MEMFLAGS flags) {
+- return (flags & tag_masks) == tag_release;
+- }
+-
+- inline static bool is_arena_record(MEMFLAGS flags) {
+- return (flags & (otArena | tag_size)) == otArena;
+- }
+-
+- inline static bool is_arena_memory_record(MEMFLAGS flags) {
+- return (flags & (otArena | tag_size)) == (otArena | tag_size);
+- }
+-
+- inline static bool is_virtual_memory_record(MEMFLAGS flags) {
+- return (flags & vmBit) != 0;
+- }
+-
+- inline static bool is_virtual_memory_reserve_record(MEMFLAGS flags) {
+- return (flags & 0x0F) == (tag_alloc | vmBit);
+- }
+-
+- inline static bool is_virtual_memory_commit_record(MEMFLAGS flags) {
+- return (flags & 0x0F) == (tag_commit | vmBit);
+- }
+-
+- inline static bool is_virtual_memory_uncommit_record(MEMFLAGS flags) {
+- return (flags & 0x0F) == (tag_uncommit | vmBit);
+- }
+-
+- inline static bool is_virtual_memory_release_record(MEMFLAGS flags) {
+- return (flags & 0x0F) == (tag_release | vmBit);
+- }
+-
+- inline static bool is_virtual_memory_type_record(MEMFLAGS flags) {
+- return (flags & 0x0F) == (tag_type | vmBit);
+- }
+-
+- /* tagging flags */
+- inline static MEMFLAGS malloc_tag() { return tag_alloc; }
+- inline static MEMFLAGS free_tag() { return tag_release; }
+- inline static MEMFLAGS arena_size_tag() { return tag_size | otArena; }
+- inline static MEMFLAGS virtual_memory_tag() { return vmBit; }
+- inline static MEMFLAGS virtual_memory_reserve_tag() { return (tag_alloc | vmBit); }
+- inline static MEMFLAGS virtual_memory_commit_tag() { return (tag_commit | vmBit); }
+- inline static MEMFLAGS virtual_memory_uncommit_tag(){ return (tag_uncommit | vmBit); }
+- inline static MEMFLAGS virtual_memory_release_tag() { return (tag_release | vmBit); }
+- inline static MEMFLAGS virtual_memory_type_tag() { return (tag_type | vmBit); }
+-
+- public:
+- MemPointerRecord(): _size(0), _flags(mtNone) { }
+-
+- MemPointerRecord(address addr, MEMFLAGS memflags, size_t size = 0):
+- MemPointer(addr), _flags(memflags), _size(size) { }
+-
+- MemPointerRecord(const MemPointerRecord& copy_from):
+- MemPointer(copy_from), _flags(copy_from.flags()),
+- _size(copy_from.size()) {
+- }
+-
+- /* MemPointerRecord is not sequenced, it always return
+- * 0 to indicate non-sequenced
+- */
+- virtual jint seq() const { return 0; }
+-
+- inline size_t size() const { return _size; }
+- inline void set_size(size_t size) { _size = size; }
+-
+- inline MEMFLAGS flags() const { return _flags; }
+- inline void set_flags(MEMFLAGS flags) { _flags = flags; }
+-
+- MemPointerRecord& operator= (const MemPointerRecord& ptr) {
+- MemPointer::operator=(ptr);
+- _flags = ptr.flags();
+-#ifdef ASSERT
+- if (IS_ARENA_OBJ(_flags)) {
+- assert(!is_vm_pointer(), "wrong flags");
+- assert((_flags & ot_masks) == otArena, "wrong flags");
+- }
+-#endif
+- _size = ptr.size();
+- return *this;
+- }
+-
+- // if the pointer represents a malloc-ed memory address
+- inline bool is_malloced_pointer() const {
+- return !is_vm_pointer();
+- }
+-
+- // if the pointer represents a virtual memory address
+- inline bool is_vm_pointer() const {
+- return is_virtual_memory_record(_flags);
+- }
+-
+- // if this record records a 'malloc' or virtual memory
+- // 'reserve' call
+- inline bool is_allocation_record() const {
+- return is_allocation_record(_flags);
+- }
+-
+- // if this record records a size information of an arena
+- inline bool is_arena_memory_record() const {
+- return is_arena_memory_record(_flags);
+- }
+-
+- // if this pointer represents an address to an arena object
+- inline bool is_arena_record() const {
+- return is_arena_record(_flags);
+- }
+-
+- // if this record represents a size information of specific arena
+- inline bool is_memory_record_of_arena(const MemPointerRecord* arena_rc) {
+- assert(is_arena_memory_record(), "not size record");
+- assert(arena_rc->is_arena_record(), "not arena record");
+- return (arena_rc->addr() + sizeof(void*)) == addr();
+- }
+-
+- // if this record records a 'free' or virtual memory 'free' call
+- inline bool is_deallocation_record() const {
+- return is_deallocation_record(_flags);
+- }
+-
+- // if this record records a virtual memory 'commit' call
+- inline bool is_commit_record() const {
+- return is_virtual_memory_commit_record(_flags);
+- }
+-
+- // if this record records a virtual memory 'uncommit' call
+- inline bool is_uncommit_record() const {
+- return is_virtual_memory_uncommit_record(_flags);
+- }
+-
+- // if this record is a tagging record of a virtual memory block
+- inline bool is_type_tagging_record() const {
+- return is_virtual_memory_type_record(_flags);
+- }
+-
+- // if the two memory pointer records actually represent the same
+- // memory block
+- inline bool is_same_region(const MemPointerRecord* other) const {
+- return (addr() == other->addr() && size() == other->size());
+- }
+-
+- // if this memory region fully contains another one
+- inline bool contains_region(const MemPointerRecord* other) const {
+- return contains_region(other->addr(), other->size());
+- }
+-
+- // if this memory region fully contains specified memory range
+- inline bool contains_region(address add, size_t sz) const {
+- return (addr() <= add && addr() + size() >= add + sz);
+- }
+-
+- inline bool contains_address(address add) const {
+- return (addr() <= add && addr() + size() > add);
+- }
+-
+- // if this memory region overlaps another region
+- inline bool overlaps_region(const MemPointerRecord* other) const {
+- assert(other != NULL, "Just check");
+- assert(size() > 0 && other->size() > 0, "empty range");
+- return contains_address(other->addr()) ||
+- contains_address(other->addr() + other->size() - 1) || // exclude end address
+- other->contains_address(addr()) ||
+- other->contains_address(addr() + size() - 1); // exclude end address
+- }
+-
+-};
+-
+-// MemPointerRecordEx also records callsite pc, from where
+-// the memory block is allocated
+-class MemPointerRecordEx : public MemPointerRecord {
+- private:
+- address _pc; // callsite pc
+-
+- public:
+- MemPointerRecordEx(): _pc(0) { }
+-
+- MemPointerRecordEx(address addr, MEMFLAGS memflags, size_t size = 0, address pc = 0):
+- MemPointerRecord(addr, memflags, size), _pc(pc) {}
+-
+- MemPointerRecordEx(const MemPointerRecordEx& copy_from):
+- MemPointerRecord(copy_from), _pc(copy_from.pc()) {}
+-
+- inline address pc() const { return _pc; }
+-
+- void init(const MemPointerRecordEx* mpe) {
+- MemPointerRecord::operator=(*mpe);
+- _pc = mpe->pc();
+- }
+-
+- void init(const MemPointerRecord* mp) {
+- MemPointerRecord::operator=(*mp);
+- _pc = 0;
+- }
+-};
+-
+-// a virtual memory region. The region can represent a reserved
+-// virtual memory region or a committed memory region
+-class VMMemRegion : public MemPointerRecord {
+-public:
+- VMMemRegion() { }
+-
+- void init(const MemPointerRecord* mp) {
+- assert(mp->is_vm_pointer(), "Sanity check");
+- _addr = mp->addr();
+- set_size(mp->size());
+- set_flags(mp->flags());
+- }
+-
+- VMMemRegion& operator=(const VMMemRegion& other) {
+- MemPointerRecord::operator=(other);
+- return *this;
+- }
+-
+- inline bool is_reserved_region() const {
+- return is_allocation_record();
+- }
+-
+- inline bool is_committed_region() const {
+- return is_commit_record();
+- }
+-
+- /* base address of this virtual memory range */
+- inline address base() const {
+- return addr();
+- }
+-
+- /* tag this virtual memory range to the specified memory type */
+- inline void tag(MEMFLAGS f) {
+- set_flags(flags() | (f & mt_masks));
+- }
+-
+- // expand this region to also cover specified range.
+- // The range has to be on either end of the memory region.
+- void expand_region(address addr, size_t sz) {
+- if (addr < base()) {
+- assert(addr + sz == base(), "Sanity check");
+- _addr = addr;
+- set_size(size() + sz);
+- } else {
+- assert(base() + size() == addr, "Sanity check");
+- set_size(size() + sz);
+- }
+- }
+-
+- // exclude the specified address range from this region.
+- // The excluded memory range has to be on either end of this memory
+- // region.
+- inline void exclude_region(address add, size_t sz) {
+- assert(is_reserved_region() || is_committed_region(), "Sanity check");
+- assert(addr() != NULL && size() != 0, "Sanity check");
+- assert(add >= addr() && add < addr() + size(), "Sanity check");
+- assert(add == addr() || (add + sz) == (addr() + size()),
+- "exclude in the middle");
+- if (add == addr()) {
+- set_addr(add + sz);
+- set_size(size() - sz);
+- } else {
+- set_size(size() - sz);
+- }
+- }
+-};
+-
+-class VMMemRegionEx : public VMMemRegion {
+- private:
+- jint _seq; // sequence number
+-
+- public:
+- VMMemRegionEx(): _pc(0) { }
+-
+- void init(const MemPointerRecordEx* mpe) {
+- VMMemRegion::init(mpe);
+- _pc = mpe->pc();
+- }
+-
+- void init(const MemPointerRecord* mpe) {
+- VMMemRegion::init(mpe);
+- _pc = 0;
+- }
+-
+- VMMemRegionEx& operator=(const VMMemRegionEx& other) {
+- VMMemRegion::operator=(other);
+- _pc = other.pc();
+- return *this;
+- }
+-
+- inline address pc() const { return _pc; }
+- private:
+- address _pc;
+-};
+-
+-/*
+- * Sequenced memory record
+- */
+-class SeqMemPointerRecord : public MemPointerRecord {
+- private:
+- jint _seq; // sequence number
+-
+- public:
+- SeqMemPointerRecord(): _seq(0){ }
+-
+- SeqMemPointerRecord(address addr, MEMFLAGS flags, size_t size, jint seq)
+- : MemPointerRecord(addr, flags, size), _seq(seq) {
+- }
+-
+- SeqMemPointerRecord(const SeqMemPointerRecord& copy_from)
+- : MemPointerRecord(copy_from) {
+- _seq = copy_from.seq();
+- }
+-
+- SeqMemPointerRecord& operator= (const SeqMemPointerRecord& ptr) {
+- MemPointerRecord::operator=(ptr);
+- _seq = ptr.seq();
+- return *this;
+- }
+-
+- inline jint seq() const {
+- return _seq;
+- }
+-};
+-
+-
+-
+-class SeqMemPointerRecordEx : public MemPointerRecordEx {
+- private:
+- jint _seq; // sequence number
+-
+- public:
+- SeqMemPointerRecordEx(): _seq(0) { }
+-
+- SeqMemPointerRecordEx(address addr, MEMFLAGS flags, size_t size,
+- jint seq, address pc):
+- MemPointerRecordEx(addr, flags, size, pc), _seq(seq) {
+- }
+-
+- SeqMemPointerRecordEx(const SeqMemPointerRecordEx& copy_from)
+- : MemPointerRecordEx(copy_from) {
+- _seq = copy_from.seq();
+- }
+-
+- SeqMemPointerRecordEx& operator= (const SeqMemPointerRecordEx& ptr) {
+- MemPointerRecordEx::operator=(ptr);
+- _seq = ptr.seq();
+- return *this;
+- }
+-
+- inline jint seq() const {
+- return _seq;
+- }
+-};
+-
+-#endif // SHARE_VM_SERVICES_MEM_PTR_HPP
+--- ./hotspot/src/share/vm/services/memPtrArray.hpp Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,306 +0,0 @@
+-/*
+- * Copyright (c) 2012, 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.
+- *
+- */
+-#ifndef SHARE_VM_UTILITIES_MEM_PTR_ARRAY_HPP
+-#define SHARE_VM_UTILITIES_MEM_PTR_ARRAY_HPP
+-
+-#include "memory/allocation.hpp"
+-#include "services/memPtr.hpp"
+-
+-class MemPtr;
+-class MemRecorder;
+-class ArenaInfo;
+-class MemSnapshot;
+-
+-extern "C" {
+- typedef int (*FN_SORT)(const void *, const void *);
+-}
+-
+-
+-// Memory pointer array interface. This array is used by NMT to hold
+-// various memory block information.
+-// The memory pointer arrays are usually walked with their iterators.
+-
+-class MemPointerArray : public CHeapObj<mtNMT> {
+- public:
+- virtual ~MemPointerArray() { }
+-
+- // return true if it can not allocate storage for the data
+- virtual bool out_of_memory() const = 0;
+- virtual bool is_empty() const = 0;
+- virtual bool is_full() = 0;
+- virtual int length() const = 0;
+- virtual void clear() = 0;
+- virtual bool append(MemPointer* ptr) = 0;
+- virtual bool insert_at(MemPointer* ptr, int pos) = 0;
+- virtual bool remove_at(int pos) = 0;
+- virtual MemPointer* at(int index) const = 0;
+- virtual void sort(FN_SORT fn) = 0;
+- virtual size_t instance_size() const = 0;
+- virtual bool shrink() = 0;
+-
+- NOT_PRODUCT(virtual int capacity() const = 0;)
+-};
+-
+-// Iterator interface
+-class MemPointerArrayIterator VALUE_OBJ_CLASS_SPEC {
+- public:
+- // return the pointer at current position
+- virtual MemPointer* current() const = 0;
+- // return the next pointer and advance current position
+- virtual MemPointer* next() = 0;
+- // return next pointer without advancing current position
+- virtual MemPointer* peek_next() const = 0;
+- // return previous pointer without changing current position
+- virtual MemPointer* peek_prev() const = 0;
+- // remove the pointer at current position
+- virtual void remove() = 0;
+- // insert the pointer at current position
+- virtual bool insert(MemPointer* ptr) = 0;
+- // insert specified element after current position and
+- // move current position to newly inserted position
+- virtual bool insert_after(MemPointer* ptr) = 0;
+-};
+-
+-// implementation class
+-class MemPointerArrayIteratorImpl : public MemPointerArrayIterator {
+- protected:
+- MemPointerArray* _array;
+- int _pos;
+-
+- public:
+- MemPointerArrayIteratorImpl(MemPointerArray* arr) {
+- assert(arr != NULL, "Parameter check");
+- _array = arr;
+- _pos = 0;
+- }
+-
+- virtual MemPointer* current() const {
+- if (_pos < _array->length()) {
+- return _array->at(_pos);
+- }
+- return NULL;
+- }
+-
+- virtual MemPointer* next() {
+- if (_pos + 1 < _array->length()) {
+- return _array->at(++_pos);
+- }
+- _pos = _array->length();
+- return NULL;
+- }
+-
+- virtual MemPointer* peek_next() const {
+- if (_pos + 1 < _array->length()) {
+- return _array->at(_pos + 1);
+- }
+- return NULL;
+- }
+-
+- virtual MemPointer* peek_prev() const {
+- if (_pos > 0) {
+- return _array->at(_pos - 1);
+- }
+- return NULL;
+- }
+-
+- virtual void remove() {
+- if (_pos < _array->length()) {
+- _array->remove_at(_pos);
+- }
+- }
+-
+- virtual bool insert(MemPointer* ptr) {
+- return _array->insert_at(ptr, _pos);
+- }
+-
+- virtual bool insert_after(MemPointer* ptr) {
+- if (_array->insert_at(ptr, _pos + 1)) {
+- _pos ++;
+- return true;
+- }
+- return false;
+- }
+-};
+-
+-
+-
+-// Memory pointer array implementation.
+-// This implementation implements expandable array
+-#define DEFAULT_PTR_ARRAY_SIZE 1024
+-
+-template <class E> class MemPointerArrayImpl : public MemPointerArray {
+- private:
+- int _max_size;
+- int _size;
+- bool _init_elements;
+- E* _data;
+-
+- public:
+- MemPointerArrayImpl(int initial_size = DEFAULT_PTR_ARRAY_SIZE, bool init_elements = true):
+- _max_size(initial_size), _size(0), _init_elements(init_elements) {
+- _data = (E*)raw_allocate(sizeof(E), initial_size);
+- if (_init_elements) {
+- for (int index = 0; index < _max_size; index ++) {
+- ::new ((void*)&_data[index]) E();
+- }
+- }
+- }
+-
+- virtual ~MemPointerArrayImpl() {
+- if (_data != NULL) {
+- raw_free(_data);
+- }
+- }
+-
+- public:
+- bool out_of_memory() const {
+- return (_data == NULL);
+- }
+-
+- size_t instance_size() const {
+- return sizeof(MemPointerArrayImpl<E>) + _max_size * sizeof(E);
+- }
+-
+- bool is_empty() const {
+- assert(_data != NULL, "Just check");
+- return _size == 0;
+- }
+-
+- bool is_full() {
+- assert(_data != NULL, "Just check");
+- if (_size < _max_size) {
+- return false;
+- } else {
+- return !expand_array();
+- }
+- }
+-
+- int length() const {
+- assert(_data != NULL, "Just check");
+- return _size;
+- }
+-
+- NOT_PRODUCT(int capacity() const { return _max_size; })
+-
+- void clear() {
+- assert(_data != NULL, "Just check");
+- _size = 0;
+- }
+-
+- bool append(MemPointer* ptr) {
+- assert(_data != NULL, "Just check");
+- if (is_full()) {
+- return false;
+- }
+- _data[_size ++] = *(E*)ptr;
+- return true;
+- }
+-
+- bool insert_at(MemPointer* ptr, int pos) {
+- assert(_data != NULL, "Just check");
+- if (is_full()) {
+- return false;
+- }
+- for (int index = _size; index > pos; index --) {
+- _data[index] = _data[index - 1];
+- }
+- _data[pos] = *(E*)ptr;
+- _size ++;
+- return true;
+- }
+-
+- bool remove_at(int pos) {
+- assert(_data != NULL, "Just check");
+- if (_size <= pos && pos >= 0) {
+- return false;
+- }
+- -- _size;
+-
+- for (int index = pos; index < _size; index ++) {
+- _data[index] = _data[index + 1];
+- }
+- return true;
+- }
+-
+- MemPointer* at(int index) const {
+- assert(_data != NULL, "Just check");
+- assert(index >= 0 && index < _size, "illegal index");
+- return &_data[index];
+- }
+-
+- bool shrink() {
+- float used = ((float)_size) / ((float)_max_size);
+- if (used < 0.40) {
+- E* old_ptr = _data;
+- int new_size = ((_max_size) / (2 * DEFAULT_PTR_ARRAY_SIZE) + 1) * DEFAULT_PTR_ARRAY_SIZE;
+- _data = (E*)raw_reallocate(_data, sizeof(E), new_size);
+- if (_data == NULL) {
+- _data = old_ptr;
+- return false;
+- } else {
+- _max_size = new_size;
+- return true;
+- }
+- }
+- return false;
+- }
+-
+- void sort(FN_SORT fn) {
+- assert(_data != NULL, "Just check");
+- qsort((void*)_data, _size, sizeof(E), fn);
+- }
+-
+- private:
+- bool expand_array() {
+- assert(_data != NULL, "Not yet allocated");
+- E* old_ptr = _data;
+- if ((_data = (E*)raw_reallocate((void*)_data, sizeof(E),
+- _max_size + DEFAULT_PTR_ARRAY_SIZE)) == NULL) {
+- _data = old_ptr;
+- return false;
+- } else {
+- _max_size += DEFAULT_PTR_ARRAY_SIZE;
+- if (_init_elements) {
+- for (int index = _size; index < _max_size; index ++) {
+- ::new ((void*)&_data[index]) E();
+- }
+- }
+- return true;
+- }
+- }
+-
+- void* raw_allocate(size_t elementSize, int items) {
+- return os::malloc(elementSize * items, mtNMT);
+- }
+-
+- void* raw_reallocate(void* ptr, size_t elementSize, int items) {
+- return os::realloc(ptr, elementSize * items, mtNMT);
+- }
+-
+- void raw_free(void* ptr) {
+- os::free(ptr, mtNMT);
+- }
+-};
+-
+-#endif // SHARE_VM_UTILITIES_MEM_PTR_ARRAY_HPP
+--- ./hotspot/src/share/vm/services/memRecorder.cpp Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,171 +0,0 @@
+-/*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- *
+- */
+-
+-#include "precompiled.hpp"
+-
+-#include "runtime/atomic.hpp"
+-#include "services/memBaseline.hpp"
+-#include "services/memRecorder.hpp"
+-#include "services/memPtr.hpp"
+-#include "services/memTracker.hpp"
+-
+-MemPointer* SequencedRecordIterator::next_record() {
+- MemPointerRecord* itr_cur = (MemPointerRecord*)_itr.current();
+- if (itr_cur == NULL) {
+- return itr_cur;
+- }
+-
+- MemPointerRecord* itr_next = (MemPointerRecord*)_itr.next();
+-
+- // don't collapse virtual memory records
+- while (itr_next != NULL && !itr_cur->is_vm_pointer() &&
+- !itr_next->is_vm_pointer() &&
+- same_kind(itr_cur, itr_next)) {
+- itr_cur = itr_next;
+- itr_next = (MemPointerRecord*)_itr.next();
+- }
+-
+- return itr_cur;
+-}
+-
+-
+-volatile jint MemRecorder::_instance_count = 0;
+-
+-MemRecorder::MemRecorder() {
+- assert(MemTracker::is_on(), "Native memory tracking is off");
+- Atomic::inc(&_instance_count);
+- set_generation();
+-
+- if (MemTracker::track_callsite()) {
+- _pointer_records = new (std::nothrow)FixedSizeMemPointerArray<SeqMemPointerRecordEx,
+- DEFAULT_RECORDER_PTR_ARRAY_SIZE>();
+- } else {
+- _pointer_records = new (std::nothrow)FixedSizeMemPointerArray<SeqMemPointerRecord,
+- DEFAULT_RECORDER_PTR_ARRAY_SIZE>();
+- }
+- _next = NULL;
+-
+-
+- if (_pointer_records != NULL) {
+- // recode itself
+- address pc = CURRENT_PC;
+- record((address)this, (MemPointerRecord::malloc_tag()|mtNMT|otNMTRecorder),
+- sizeof(MemRecorder), SequenceGenerator::next(), pc);
+- record((address)_pointer_records, (MemPointerRecord::malloc_tag()|mtNMT|otNMTRecorder),
+- _pointer_records->instance_size(), SequenceGenerator::next(), pc);
+- }
+-}
+-
+-MemRecorder::~MemRecorder() {
+- if (_pointer_records != NULL) {
+- if (MemTracker::is_on()) {
+- MemTracker::record_free((address)_pointer_records, mtNMT);
+- MemTracker::record_free((address)this, mtNMT);
+- }
+- delete _pointer_records;
+- }
+- // delete all linked recorders
+- while (_next != NULL) {
+- MemRecorder* tmp = _next;
+- _next = _next->next();
+- tmp->set_next(NULL);
+- delete tmp;
+- }
+- Atomic::dec(&_instance_count);
+-}
+-
+-// Sorting order:
+-// 1. memory block address
+-// 2. mem pointer record tags
+-// 3. sequence number
+-int MemRecorder::sort_record_fn(const void* e1, const void* e2) {
+- const MemPointerRecord* p1 = (const MemPointerRecord*)e1;
+- const MemPointerRecord* p2 = (const MemPointerRecord*)e2;
+- int delta = UNSIGNED_COMPARE(p1->addr(), p2->addr());
+- if (delta == 0) {
+- int df = UNSIGNED_COMPARE((p1->flags() & MemPointerRecord::tag_masks),
+- (p2->flags() & MemPointerRecord::tag_masks));
+- if (df == 0) {
+- assert(p1->seq() != p2->seq(), "dup seq");
+- return p1->seq() - p2->seq();
+- } else {
+- return df;
+- }
+- } else {
+- return delta;
+- }
+-}
+-
+-bool MemRecorder::record(address p, MEMFLAGS flags, size_t size, jint seq, address pc) {
+- assert(seq > 0, "No sequence number");
+-#ifdef ASSERT
+- if (MemPointerRecord::is_virtual_memory_record(flags)) {
+- assert((flags & MemPointerRecord::tag_masks) != 0, "bad virtual memory record");
+- } else {
+- assert((flags & MemPointerRecord::tag_masks) == MemPointerRecord::malloc_tag() ||
+- (flags & MemPointerRecord::tag_masks) == MemPointerRecord::free_tag() ||
+- IS_ARENA_OBJ(flags),
+- "bad malloc record");
+- }
+- // a recorder should only hold records within the same generation
+- unsigned long cur_generation = SequenceGenerator::current_generation();
+- assert(cur_generation == _generation,
+- "this thread did not enter sync point");
+-#endif
+-
+- if (MemTracker::track_callsite()) {
+- SeqMemPointerRecordEx ap(p, flags, size, seq, pc);
+- debug_only(check_dup_seq(ap.seq());)
+- return _pointer_records->append(&ap);
+- } else {
+- SeqMemPointerRecord ap(p, flags, size, seq);
+- debug_only(check_dup_seq(ap.seq());)
+- return _pointer_records->append(&ap);
+- }
+-}
+-
+- // iterator for alloc pointers
+-SequencedRecordIterator MemRecorder::pointer_itr() {
+- assert(_pointer_records != NULL, "just check");
+- _pointer_records->sort((FN_SORT)sort_record_fn);
+- return SequencedRecordIterator(_pointer_records);
+-}
+-
+-
+-void MemRecorder::set_generation() {
+- _generation = SequenceGenerator::current_generation();
+-}
+-
+-#ifdef ASSERT
+-
+-void MemRecorder::check_dup_seq(jint seq) const {
+- MemPointerArrayIteratorImpl itr(_pointer_records);
+- MemPointerRecord* rc = (MemPointerRecord*)itr.current();
+- while (rc != NULL) {
+- assert(rc->seq() != seq, "dup seq");
+- rc = (MemPointerRecord*)itr.next();
+- }
+-}
+-
+-#endif
+--- ./hotspot/src/share/vm/services/memRecorder.hpp Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,271 +0,0 @@
+-/*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- *
+- */
+-
+-#ifndef SHARE_VM_SERVICES_MEM_RECORDER_HPP
+-#define SHARE_VM_SERVICES_MEM_RECORDER_HPP
+-
+-#include "memory/allocation.hpp"
+-#include "runtime/os.hpp"
+-#include "services/memPtrArray.hpp"
+-
+-class MemSnapshot;
+-class MemTracker;
+-class MemTrackWorker;
+-
+-// Fixed size memory pointer array implementation
+-template <class E, int SIZE> class FixedSizeMemPointerArray :
+- public MemPointerArray {
+- // This implementation is for memory recorder only
+- friend class MemRecorder;
+-
+- private:
+- E _data[SIZE];
+- int _size;
+-
+- protected:
+- FixedSizeMemPointerArray(bool init_elements = false):
+- _size(0){
+- if (init_elements) {
+- for (int index = 0; index < SIZE; index ++) {
+- ::new ((void*)&_data[index]) E();
+- }
+- }
+- }
+-
+- void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() {
+- // the instance is part of memRecorder, needs to be tagged with 'otNMTRecorder'
+- // to avoid recursion
+- return os::malloc(size, (mtNMT | otNMTRecorder));
+- }
+-
+- void* operator new(size_t size) throw() {
+- assert(false, "use nothrow version");
+- return NULL;
+- }
+-
+- void operator delete(void* p) {
+- os::free(p, (mtNMT | otNMTRecorder));
+- }
+-
+- // instance size
+- inline size_t instance_size() const {
+- return sizeof(FixedSizeMemPointerArray<E, SIZE>);
+- }
+-
+- NOT_PRODUCT(int capacity() const { return SIZE; })
+-
+- public:
+- // implementation of public interface
+- bool out_of_memory() const { return false; }
+- bool is_empty() const { return _size == 0; }
+- bool is_full() { return length() >= SIZE; }
+- int length() const { return _size; }
+-
+- void clear() {
+- _size = 0;
+- }
+-
+- bool append(MemPointer* ptr) {
+- if (is_full()) return false;
+- _data[_size ++] = *(E*)ptr;
+- return true;
+- }
+-
+- virtual bool insert_at(MemPointer* p, int pos) {
+- assert(false, "append only");
+- return false;
+- }
+-
+- virtual bool remove_at(int pos) {
+- assert(false, "not supported");
+- return false;
+- }
+-
+- MemPointer* at(int index) const {
+- assert(index >= 0 && index < length(),
+- "parameter check");
+- return ((E*)&_data[index]);
+- }
+-
+- void sort(FN_SORT fn) {
+- qsort((void*)_data, _size, sizeof(E), fn);
+- }
+-
+- bool shrink() {
+- return false;
+- }
+-};
+-
+-
+-// This iterator requires pre-sorted MemPointerArray, which is sorted by:
+-// 1. address
+-// 2. allocation type
+-// 3. sequence number
+-// During the array walking, iterator collapses pointers with the same
+-// address and allocation type, and only returns the one with highest
+-// sequence number.
+-//
+-// This is read-only iterator, update methods are asserted.
+-class SequencedRecordIterator : public MemPointerArrayIterator {
+- private:
+- MemPointerArrayIteratorImpl _itr;
+- MemPointer* _cur;
+-
+- public:
+- SequencedRecordIterator(const MemPointerArray* arr):
+- _itr(const_cast<MemPointerArray*>(arr)) {
+- _cur = next_record();
+- }
+-
+- SequencedRecordIterator(const SequencedRecordIterator& itr):
+- _itr(itr._itr) {
+- _cur = next_record();
+- }
+-
+- // return the pointer at current position
+- virtual MemPointer* current() const {
+- return _cur;
+- };
+-
+- // return the next pointer and advance current position
+- virtual MemPointer* next() {
+- _cur = next_record();
+- return _cur;
+- }
+-
+- // return the next pointer without advancing current position
+- virtual MemPointer* peek_next() const {
+- assert(false, "not implemented");
+- return NULL;
+-
+- }
+- // return the previous pointer without changing current position
+- virtual MemPointer* peek_prev() const {
+- assert(false, "not implemented");
+- return NULL;
+- }
+-
+- // remove the pointer at current position
+- virtual void remove() {
+- assert(false, "read-only iterator");
+- };
+- // insert the pointer at current position
+- virtual bool insert(MemPointer* ptr) {
+- assert(false, "read-only iterator");
+- return false;
+- }
+-
+- virtual bool insert_after(MemPointer* ptr) {
+- assert(false, "read-only iterator");
+- return false;
+- }
+- private:
+- // collapse the 'same kind' of records, and return this 'kind' of
+- // record with highest sequence number
+- MemPointer* next_record();
+-
+- // Test if the two records are the same kind: the same memory block and allocation
+- // type.
+- inline bool same_kind(const MemPointerRecord* p1, const MemPointerRecord* p2) const {
+- assert(!p1->is_vm_pointer() && !p2->is_vm_pointer(), "malloc pointer only");
+- return (p1->addr() == p2->addr() &&
+- (p1->flags() &MemPointerRecord::tag_masks) ==
+- (p2->flags() & MemPointerRecord::tag_masks));
+- }
+-};
+-
+-
+-
+-#define DEFAULT_RECORDER_PTR_ARRAY_SIZE 512
+-
+-class MemRecorder : public CHeapObj<mtNMT|otNMTRecorder> {
+- friend class MemSnapshot;
+- friend class MemTracker;
+- friend class MemTrackWorker;
+- friend class GenerationData;
+-
+- protected:
+- // the array that holds memory records
+- MemPointerArray* _pointer_records;
+-
+- private:
+- // used for linked list
+- MemRecorder* _next;
+- // active recorder can only record a certain generation data
+- unsigned long _generation;
+-
+- protected:
+- _NOINLINE_ MemRecorder();
+- ~MemRecorder();
+-
+- // record a memory operation
+- bool record(address addr, MEMFLAGS flags, size_t size, jint seq, address caller_pc = 0);
+-
+- // linked list support
+- inline void set_next(MemRecorder* rec) {
+- _next = rec;
+- }
+-
+- inline MemRecorder* next() const {
+- return _next;
+- }
+-
+- // if the recorder is full
+- inline bool is_full() const {
+- assert(_pointer_records != NULL, "just check");
+- return _pointer_records->is_full();
+- }
+-
+- // if running out of memory when initializing recorder's internal
+- // data
+- inline bool out_of_memory() const {
+- return (_pointer_records == NULL ||
+- _pointer_records->out_of_memory());
+- }
+-
+- inline void clear() {
+- assert(_pointer_records != NULL, "Just check");
+- _pointer_records->clear();
+- }
+-
+- SequencedRecordIterator pointer_itr();
+-
+- // return the generation of this recorder which it belongs to
+- unsigned long get_generation() const { return _generation; }
+- protected:
+- // number of MemRecorder instance
+- static volatile jint _instance_count;
+-
+- private:
+- // sorting function, sort records into following order
+- // 1. memory address
+- // 2. allocation type
+- // 3. sequence number
+- static int sort_record_fn(const void* e1, const void* e2);
+-
+- debug_only(void check_dup_seq(jint seq) const;)
+- void set_generation();
+-};
+-
+-#endif // SHARE_VM_SERVICES_MEM_RECORDER_HPP
+--- ./hotspot/src/share/vm/services/memReporter.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/services/memReporter.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -22,618 +22,595 @@
+ *
+ */
+ #include "precompiled.hpp"
+-#include "classfile/systemDictionary.hpp"
+-#include "runtime/os.hpp"
++
++#include "memory/allocation.hpp"
++#include "services/mallocTracker.hpp"
+ #include "services/memReporter.hpp"
+-#include "services/memPtrArray.hpp"
+-#include "services/memTracker.hpp"
++#include "services/virtualMemoryTracker.hpp"
++#include "utilities/globalDefinitions.hpp"
+
+-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+-
+-const char* BaselineOutputer::memory_unit(size_t scale) {
+- switch(scale) {
+- case K: return "KB";
+- case M: return "MB";
+- case G: return "GB";
+- }
+- ShouldNotReachHere();
+- return NULL;
++size_t MemReporterBase::reserved_total(const MallocMemory* malloc, const VirtualMemory* vm) const {
++ return malloc->malloc_size() + malloc->arena_size() + vm->reserved();
+ }
+
+-
+-void BaselineReporter::report_baseline(const MemBaseline& baseline, bool summary_only) {
+- assert(MemTracker::is_on(), "Native memory tracking is off");
+- _outputer.start(scale());
+- _outputer.total_usage(
+- amount_in_current_scale(baseline.total_malloc_amount() + baseline.total_reserved_amount()),
+- amount_in_current_scale(baseline.total_malloc_amount() + baseline.total_committed_amount()));
+-
+- _outputer.num_of_classes(baseline.number_of_classes());
+- _outputer.num_of_threads(baseline.number_of_threads());
+-
+- report_summaries(baseline);
+- if (!summary_only && MemTracker::track_callsite()) {
+- report_virtual_memory_map(baseline);
+- report_callsites(baseline);
+- }
+- _outputer.done();
++size_t MemReporterBase::committed_total(const MallocMemory* malloc, const VirtualMemory* vm) const {
++ return malloc->malloc_size() + malloc->arena_size() + vm->committed();
+ }
+
+-void BaselineReporter::report_summaries(const MemBaseline& baseline) {
+- _outputer.start_category_summary();
+- MEMFLAGS type;
++void MemReporterBase::print_total(size_t reserved, size_t committed) const {
++ const char* scale = current_scale();
++ output()->print("reserved=" SIZE_FORMAT "%s, committed=" SIZE_FORMAT "%s",
++ amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale);
++}
+
+- for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
+- type = MemBaseline::MemType2NameMap[index]._flag;
+- _outputer.category_summary(type,
+- amount_in_current_scale(baseline.reserved_amount(type)),
+- amount_in_current_scale(baseline.committed_amount(type)),
+- amount_in_current_scale(baseline.malloc_amount(type)),
+- baseline.malloc_count(type),
+- amount_in_current_scale(baseline.arena_amount(type)),
+- baseline.arena_count(type));
++void MemReporterBase::print_malloc(size_t amount, size_t count) const {
++ const char* scale = current_scale();
++ outputStream* out = output();
++ out->print("(malloc=" SIZE_FORMAT "%s",
++ amount_in_current_scale(amount), scale);
++
++ if (count > 0) {
++ out->print(" #" SIZE_FORMAT "", count);
+ }
+
+- _outputer.done_category_summary();
++ out->print(")");
+ }
+
+-void BaselineReporter::report_virtual_memory_map(const MemBaseline& baseline) {
+- _outputer.start_virtual_memory_map();
+- MemBaseline* pBL = const_cast<MemBaseline*>(&baseline);
+- MemPointerArrayIteratorImpl itr = MemPointerArrayIteratorImpl(pBL->_vm_map);
+- VMMemRegionEx* rgn = (VMMemRegionEx*)itr.current();
+- while (rgn != NULL) {
+- if (rgn->is_reserved_region()) {
+- _outputer.reserved_memory_region(FLAGS_TO_MEMORY_TYPE(rgn->flags()),
+- rgn->base(), rgn->base() + rgn->size(), amount_in_current_scale(rgn->size()), rgn->pc());
+- } else {
+- _outputer.committed_memory_region(rgn->base(), rgn->base() + rgn->size(),
+- amount_in_current_scale(rgn->size()), rgn->pc());
+- }
+- rgn = (VMMemRegionEx*)itr.next();
++void MemReporterBase::print_virtual_memory(size_t reserved, size_t committed) const {
++ const char* scale = current_scale();
++ output()->print("(mmap: reserved=" SIZE_FORMAT "%s, committed=" SIZE_FORMAT "%s)",
++ amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale);
++}
++
++void MemReporterBase::print_malloc_line(size_t amount, size_t count) const {
++ output()->print("%28s", " ");
++ print_malloc(amount, count);
++ output()->print_cr(" ");
++}
++
++void MemReporterBase::print_virtual_memory_line(size_t reserved, size_t committed) const {
++ output()->print("%28s", " ");
++ print_virtual_memory(reserved, committed);
++ output()->print_cr(" ");
++}
++
++void MemReporterBase::print_arena_line(size_t amount, size_t count) const {
++ const char* scale = current_scale();
++ output()->print_cr("%27s (arena=" SIZE_FORMAT "%s #" SIZE_FORMAT ")", " ",
++ amount_in_current_scale(amount), scale, count);
++}
++
++void MemReporterBase::print_virtual_memory_region(const char* type, address base, size_t size) const {
++ const char* scale = current_scale();
++ output()->print("[" PTR_FORMAT " - " PTR_FORMAT "] %s " SIZE_FORMAT "%s",
++ p2i(base), p2i(base + size), type, amount_in_current_scale(size), scale);
++}
++
++
++void MemSummaryReporter::report() {
++ const char* scale = current_scale();
++ outputStream* out = output();
++ size_t total_reserved_amount = _malloc_snapshot->total() +
++ _vm_snapshot->total_reserved();
++ size_t total_committed_amount = _malloc_snapshot->total() +
++ _vm_snapshot->total_committed();
++
++ // Overall total
++ out->print_cr("\nNative Memory Tracking:\n");
++ out->print("Total: ");
++ print_total(total_reserved_amount, total_committed_amount);
++ out->print("\n");
++
++ // Summary by memory type
++ for (int index = 0; index < mt_number_of_types; index ++) {
++ MEMFLAGS flag = NMTUtil::index_to_flag(index);
++ // thread stack is reported as part of thread category
++ if (flag == mtThreadStack) continue;
++ MallocMemory* malloc_memory = _malloc_snapshot->by_type(flag);
++ VirtualMemory* virtual_memory = _vm_snapshot->by_type(flag);
++
++ report_summary_of_type(flag, malloc_memory, virtual_memory);
++ }
++}
++
++void MemSummaryReporter::report_summary_of_type(MEMFLAGS flag,
++ MallocMemory* malloc_memory, VirtualMemory* virtual_memory) {
++
++ size_t reserved_amount = reserved_total (malloc_memory, virtual_memory);
++ size_t committed_amount = committed_total(malloc_memory, virtual_memory);
++
++ // Count thread's native stack in "Thread" category
++ if (flag == mtThread) {
++ const VirtualMemory* thread_stack_usage =
++ (const VirtualMemory*)_vm_snapshot->by_type(mtThreadStack);
++ reserved_amount += thread_stack_usage->reserved();
++ committed_amount += thread_stack_usage->committed();
++ } else if (flag == mtNMT) {
++ // Count malloc headers in "NMT" category
++ reserved_amount += _malloc_snapshot->malloc_overhead()->size();
++ committed_amount += _malloc_snapshot->malloc_overhead()->size();
+ }
+
+- _outputer.done_virtual_memory_map();
++ if (amount_in_current_scale(reserved_amount) > 0) {
++ outputStream* out = output();
++ const char* scale = current_scale();
++ out->print("-%26s (", NMTUtil::flag_to_name(flag));
++ print_total(reserved_amount, committed_amount);
++ out->print_cr(")");
++
++ if (flag == mtClass) {
++ // report class count
++ out->print_cr("%27s (classes #" SIZE_FORMAT ")", " ", _class_count);
++ } else if (flag == mtThread) {
++ // report thread count
++ out->print_cr("%27s (thread #" SIZE_FORMAT ")", " ", _malloc_snapshot->thread_count());
++ const VirtualMemory* thread_stack_usage =
++ _vm_snapshot->by_type(mtThreadStack);
++ out->print("%27s (stack: ", " ");
++ print_total(thread_stack_usage->reserved(), thread_stack_usage->committed());
++ out->print_cr(")");
++ }
++
++ // report malloc'd memory
++ if (amount_in_current_scale(malloc_memory->malloc_size()) > 0) {
++ // We don't know how many arena chunks are in used, so don't report the count
++ size_t count = (flag == mtChunk) ? 0 : malloc_memory->malloc_count();
++ print_malloc_line(malloc_memory->malloc_size(), count);
++ }
++
++ if (amount_in_current_scale(virtual_memory->reserved()) > 0) {
++ print_virtual_memory_line(virtual_memory->reserved(), virtual_memory->committed());
++ }
++
++ if (amount_in_current_scale(malloc_memory->arena_size()) > 0) {
++ print_arena_line(malloc_memory->arena_size(), malloc_memory->arena_count());
++ }
++
++ if (flag == mtNMT &&
++ amount_in_current_scale(_malloc_snapshot->malloc_overhead()->size()) > 0) {
++ out->print_cr("%27s (tracking overhead=" SIZE_FORMAT "%s)", " ",
++ amount_in_current_scale(_malloc_snapshot->malloc_overhead()->size()), scale);
++ }
++
++ out->print_cr(" ");
++ }
+ }
+
+-void BaselineReporter::report_callsites(const MemBaseline& baseline) {
+- _outputer.start_callsite();
+- MemBaseline* pBL = const_cast<MemBaseline*>(&baseline);
++void MemDetailReporter::report_detail() {
++ // Start detail report
++ outputStream* out = output();
++ out->print_cr("Details:\n");
+
+- pBL->_malloc_cs->sort((FN_SORT)MemBaseline::bl_malloc_sort_by_size);
+- pBL->_vm_cs->sort((FN_SORT)MemBaseline::bl_vm_sort_by_size);
++ report_malloc_sites();
++ report_virtual_memory_allocation_sites();
++}
+
+- // walk malloc callsites
+- MemPointerArrayIteratorImpl malloc_itr(pBL->_malloc_cs);
+- MallocCallsitePointer* malloc_callsite =
+- (MallocCallsitePointer*)malloc_itr.current();
+- while (malloc_callsite != NULL) {
+- _outputer.malloc_callsite(malloc_callsite->addr(),
+- amount_in_current_scale(malloc_callsite->amount()), malloc_callsite->count());
+- malloc_callsite = (MallocCallsitePointer*)malloc_itr.next();
++void MemDetailReporter::report_malloc_sites() {
++ MallocSiteIterator malloc_itr = _baseline.malloc_sites(MemBaseline::by_size);
++ if (malloc_itr.is_empty()) return;
++
++ outputStream* out = output();
++
++ const MallocSite* malloc_site;
++ while ((malloc_site = malloc_itr.next()) != NULL) {
++ // Don't report if size is too small
++ if (amount_in_current_scale(malloc_site->size()) == 0)
++ continue;
++
++ const NativeCallStack* stack = malloc_site->call_stack();
++ stack->print_on(out);
++ out->print("%29s", " ");
++ print_malloc(malloc_site->size(), malloc_site->count());
++ out->print_cr("\n");
++ }
++}
++
++void MemDetailReporter::report_virtual_memory_allocation_sites() {
++ VirtualMemorySiteIterator virtual_memory_itr =
++ _baseline.virtual_memory_sites(MemBaseline::by_size);
++
++ if (virtual_memory_itr.is_empty()) return;
++
++ outputStream* out = output();
++ const VirtualMemoryAllocationSite* virtual_memory_site;
++
++ while ((virtual_memory_site = virtual_memory_itr.next()) != NULL) {
++ // Don't report if size is too small
++ if (amount_in_current_scale(virtual_memory_site->reserved()) == 0)
++ continue;
++
++ const NativeCallStack* stack = virtual_memory_site->call_stack();
++ stack->print_on(out);
++ out->print("%28s (", " ");
++ print_total(virtual_memory_site->reserved(), virtual_memory_site->committed());
++ out->print_cr(")\n");
++ }
++}
++
++
++void MemDetailReporter::report_virtual_memory_map() {
++ // Virtual memory map always in base address order
++ VirtualMemoryAllocationIterator itr = _baseline.virtual_memory_allocations();
++ const ReservedMemoryRegion* rgn;
++
++ output()->print_cr("Virtual memory map:");
++ while ((rgn = itr.next()) != NULL) {
++ report_virtual_memory_region(rgn);
++ }
++}
++
++void MemDetailReporter::report_virtual_memory_region(const ReservedMemoryRegion* reserved_rgn) {
++ assert(reserved_rgn != NULL, "NULL pointer");
++
++ // Don't report if size is too small
++ if (amount_in_current_scale(reserved_rgn->size()) == 0) return;
++
++ outputStream* out = output();
++ const char* scale = current_scale();
++ const NativeCallStack* stack = reserved_rgn->call_stack();
++ bool all_committed = reserved_rgn->all_committed();
++ const char* region_type = (all_committed ? "reserved and committed" : "reserved");
++ out->print_cr(" ");
++ print_virtual_memory_region(region_type, reserved_rgn->base(), reserved_rgn->size());
++ out->print(" for %s", NMTUtil::flag_to_name(reserved_rgn->flag()));
++ if (stack->is_empty()) {
++ out->print_cr(" ");
++ } else {
++ out->print_cr(" from");
++ stack->print_on(out, 4);
+ }
+
+- // walk virtual memory callsite
+- MemPointerArrayIteratorImpl vm_itr(pBL->_vm_cs);
+- VMCallsitePointer* vm_callsite = (VMCallsitePointer*)vm_itr.current();
+- while (vm_callsite != NULL) {
+- _outputer.virtual_memory_callsite(vm_callsite->addr(),
+- amount_in_current_scale(vm_callsite->reserved_amount()),
+- amount_in_current_scale(vm_callsite->committed_amount()));
+- vm_callsite = (VMCallsitePointer*)vm_itr.next();
+- }
+- pBL->_malloc_cs->sort((FN_SORT)MemBaseline::bl_malloc_sort_by_pc);
+- pBL->_vm_cs->sort((FN_SORT)MemBaseline::bl_vm_sort_by_pc);
+- _outputer.done_callsite();
+-}
++ if (all_committed) return;
+
+-void BaselineReporter::diff_baselines(const MemBaseline& cur, const MemBaseline& prev,
+- bool summary_only) {
+- assert(MemTracker::is_on(), "Native memory tracking is off");
+- _outputer.start(scale());
+- size_t total_reserved = cur.total_malloc_amount() + cur.total_reserved_amount();
+- size_t total_committed = cur.total_malloc_amount() + cur.total_committed_amount();
+-
+- _outputer.diff_total_usage(
+- amount_in_current_scale(total_reserved), amount_in_current_scale(total_committed),
+- diff_in_current_scale(total_reserved, (prev.total_malloc_amount() + prev.total_reserved_amount())),
+- diff_in_current_scale(total_committed, (prev.total_committed_amount() + prev.total_malloc_amount())));
+-
+- _outputer.diff_num_of_classes(cur.number_of_classes(),
+- diff(cur.number_of_classes(), prev.number_of_classes()));
+- _outputer.diff_num_of_threads(cur.number_of_threads(),
+- diff(cur.number_of_threads(), prev.number_of_threads()));
+-
+- diff_summaries(cur, prev);
+- if (!summary_only && MemTracker::track_callsite()) {
+- diff_callsites(cur, prev);
+- }
+- _outputer.done();
+-}
+-
+-void BaselineReporter::diff_summaries(const MemBaseline& cur, const MemBaseline& prev) {
+- _outputer.start_category_summary();
+- MEMFLAGS type;
+-
+- for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
+- type = MemBaseline::MemType2NameMap[index]._flag;
+- _outputer.diff_category_summary(type,
+- amount_in_current_scale(cur.reserved_amount(type)),
+- amount_in_current_scale(cur.committed_amount(type)),
+- amount_in_current_scale(cur.malloc_amount(type)),
+- cur.malloc_count(type),
+- amount_in_current_scale(cur.arena_amount(type)),
+- cur.arena_count(type),
+- diff_in_current_scale(cur.reserved_amount(type), prev.reserved_amount(type)),
+- diff_in_current_scale(cur.committed_amount(type), prev.committed_amount(type)),
+- diff_in_current_scale(cur.malloc_amount(type), prev.malloc_amount(type)),
+- diff(cur.malloc_count(type), prev.malloc_count(type)),
+- diff_in_current_scale(cur.arena_amount(type), prev.arena_amount(type)),
+- diff(cur.arena_count(type), prev.arena_count(type)));
+- }
+-
+- _outputer.done_category_summary();
+-}
+-
+-void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline& prev) {
+- _outputer.start_callsite();
+- MemBaseline* pBL_cur = const_cast<MemBaseline*>(&cur);
+- MemBaseline* pBL_prev = const_cast<MemBaseline*>(&prev);
+-
+- // walk malloc callsites
+- MemPointerArrayIteratorImpl cur_malloc_itr(pBL_cur->_malloc_cs);
+- MemPointerArrayIteratorImpl prev_malloc_itr(pBL_prev->_malloc_cs);
+-
+- MallocCallsitePointer* cur_malloc_callsite =
+- (MallocCallsitePointer*)cur_malloc_itr.current();
+- MallocCallsitePointer* prev_malloc_callsite =
+- (MallocCallsitePointer*)prev_malloc_itr.current();
+-
+- while (cur_malloc_callsite != NULL || prev_malloc_callsite != NULL) {
+- if (prev_malloc_callsite == NULL) {
+- assert(cur_malloc_callsite != NULL, "sanity check");
+- // this is a new callsite
+- _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
+- amount_in_current_scale(cur_malloc_callsite->amount()),
+- cur_malloc_callsite->count(),
+- diff_in_current_scale(cur_malloc_callsite->amount(), 0),
+- diff(cur_malloc_callsite->count(), 0));
+- cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next();
+- } else if (cur_malloc_callsite == NULL) {
+- assert(prev_malloc_callsite != NULL, "Sanity check");
+- // this callsite is already gone
+- _outputer.diff_malloc_callsite(prev_malloc_callsite->addr(),
+- 0, 0,
+- diff_in_current_scale(0, prev_malloc_callsite->amount()),
+- diff(0, prev_malloc_callsite->count()));
+- prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next();
++ CommittedRegionIterator itr = reserved_rgn->iterate_committed_regions();
++ const CommittedMemoryRegion* committed_rgn;
++ while ((committed_rgn = itr.next()) != NULL) {
++ // Don't report if size is too small
++ if (amount_in_current_scale(committed_rgn->size()) == 0) continue;
++ stack = committed_rgn->call_stack();
++ out->print("\n\t");
++ print_virtual_memory_region("committed", committed_rgn->base(), committed_rgn->size());
++ if (stack->is_empty()) {
++ out->print_cr(" ");
+ } else {
+- assert(cur_malloc_callsite != NULL, "Sanity check");
+- assert(prev_malloc_callsite != NULL, "Sanity check");
+- if (cur_malloc_callsite->addr() < prev_malloc_callsite->addr()) {
+- // this is a new callsite
+- _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
+- amount_in_current_scale(cur_malloc_callsite->amount()),
+- cur_malloc_callsite->count(),
+- diff_in_current_scale(cur_malloc_callsite->amount(), 0),
+- diff(cur_malloc_callsite->count(), 0));
+- cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next();
+- } else if (cur_malloc_callsite->addr() > prev_malloc_callsite->addr()) {
+- // this callsite is already gone
+- _outputer.diff_malloc_callsite(prev_malloc_callsite->addr(),
+- 0, 0,
+- diff_in_current_scale(0, prev_malloc_callsite->amount()),
+- diff(0, prev_malloc_callsite->count()));
+- prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next();
+- } else {
+- // the same callsite
+- _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
+- amount_in_current_scale(cur_malloc_callsite->amount()),
+- cur_malloc_callsite->count(),
+- diff_in_current_scale(cur_malloc_callsite->amount(), prev_malloc_callsite->amount()),
+- diff(cur_malloc_callsite->count(), prev_malloc_callsite->count()));
+- cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next();
+- prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next();
+- }
+- }
+- }
+-
+- // walk virtual memory callsite
+- MemPointerArrayIteratorImpl cur_vm_itr(pBL_cur->_vm_cs);
+- MemPointerArrayIteratorImpl prev_vm_itr(pBL_prev->_vm_cs);
+- VMCallsitePointer* cur_vm_callsite = (VMCallsitePointer*)cur_vm_itr.current();
+- VMCallsitePointer* prev_vm_callsite = (VMCallsitePointer*)prev_vm_itr.current();
+- while (cur_vm_callsite != NULL || prev_vm_callsite != NULL) {
+- if (prev_vm_callsite == NULL || cur_vm_callsite->addr() < prev_vm_callsite->addr()) {
+- // this is a new callsite
+- _outputer.diff_virtual_memory_callsite(cur_vm_callsite->addr(),
+- amount_in_current_scale(cur_vm_callsite->reserved_amount()),
+- amount_in_current_scale(cur_vm_callsite->committed_amount()),
+- diff_in_current_scale(cur_vm_callsite->reserved_amount(), 0),
+- diff_in_current_scale(cur_vm_callsite->committed_amount(), 0));
+- cur_vm_callsite = (VMCallsitePointer*)cur_vm_itr.next();
+- } else if (cur_vm_callsite == NULL || cur_vm_callsite->addr() > prev_vm_callsite->addr()) {
+- // this callsite is already gone
+- _outputer.diff_virtual_memory_callsite(prev_vm_callsite->addr(),
+- amount_in_current_scale(0),
+- amount_in_current_scale(0),
+- diff_in_current_scale(0, prev_vm_callsite->reserved_amount()),
+- diff_in_current_scale(0, prev_vm_callsite->committed_amount()));
+- prev_vm_callsite = (VMCallsitePointer*)prev_vm_itr.next();
+- } else { // the same callsite
+- _outputer.diff_virtual_memory_callsite(cur_vm_callsite->addr(),
+- amount_in_current_scale(cur_vm_callsite->reserved_amount()),
+- amount_in_current_scale(cur_vm_callsite->committed_amount()),
+- diff_in_current_scale(cur_vm_callsite->reserved_amount(), prev_vm_callsite->reserved_amount()),
+- diff_in_current_scale(cur_vm_callsite->committed_amount(), prev_vm_callsite->committed_amount()));
+- cur_vm_callsite = (VMCallsitePointer*)cur_vm_itr.next();
+- prev_vm_callsite = (VMCallsitePointer*)prev_vm_itr.next();
+- }
+- }
+-
+- _outputer.done_callsite();
+-}
+-
+-size_t BaselineReporter::amount_in_current_scale(size_t amt) const {
+- return (size_t)(((float)amt/(float)_scale) + 0.5);
+-}
+-
+-int BaselineReporter::diff_in_current_scale(size_t value1, size_t value2) const {
+- return (int)(((float)value1 - (float)value2)/((float)_scale) + 0.5);
+-}
+-
+-int BaselineReporter::diff(size_t value1, size_t value2) const {
+- return ((int)value1 - (int)value2);
+-}
+-
+-void BaselineTTYOutputer::start(size_t scale, bool report_diff) {
+- _scale = scale;
+- _output->print_cr(" ");
+- _output->print_cr("Native Memory Tracking:");
+- _output->print_cr(" ");
+-}
+-
+-void BaselineTTYOutputer::done() {
+-
+-}
+-
+-void BaselineTTYOutputer::total_usage(size_t total_reserved, size_t total_committed) {
+- const char* unit = memory_unit(_scale);
+- _output->print_cr("Total: reserved=%d%s, committed=%d%s",
+- total_reserved, unit, total_committed, unit);
+-}
+-
+-void BaselineTTYOutputer::start_category_summary() {
+- _output->print_cr(" ");
+-}
+-
+-/**
+- * report a summary of memory type
+- */
+-void BaselineTTYOutputer::category_summary(MEMFLAGS type,
+- size_t reserved_amt, size_t committed_amt, size_t malloc_amt,
+- size_t malloc_count, size_t arena_amt, size_t arena_count) {
+-
+- // we report mtThreadStack under mtThread category
+- if (type == mtThreadStack) {
+- assert(malloc_amt == 0 && malloc_count == 0 && arena_amt == 0,
+- "Just check");
+- _thread_stack_reserved = reserved_amt;
+- _thread_stack_committed = committed_amt;
+- } else {
+- const char* unit = memory_unit(_scale);
+- size_t total_reserved = (reserved_amt + malloc_amt + arena_amt);
+- size_t total_committed = (committed_amt + malloc_amt + arena_amt);
+- if (type == mtThread) {
+- total_reserved += _thread_stack_reserved;
+- total_committed += _thread_stack_committed;
+- }
+-
+- if (total_reserved > 0) {
+- _output->print_cr("-%26s (reserved=%d%s, committed=%d%s)",
+- MemBaseline::type2name(type), total_reserved, unit,
+- total_committed, unit);
+-
+- if (type == mtClass) {
+- _output->print_cr("%27s (classes #%d)", " ", _num_of_classes);
+- } else if (type == mtThread) {
+- _output->print_cr("%27s (thread #%d)", " ", _num_of_threads);
+- _output->print_cr("%27s (stack: reserved=%d%s, committed=%d%s)", " ",
+- _thread_stack_reserved, unit, _thread_stack_committed, unit);
+- }
+-
+- if (malloc_amt > 0) {
+- if (type != mtChunk) {
+- _output->print_cr("%27s (malloc=%d%s, #%d)", " ", malloc_amt, unit,
+- malloc_count);
+- } else {
+- _output->print_cr("%27s (malloc=%d%s)", " ", malloc_amt, unit);
+- }
+- }
+-
+- if (reserved_amt > 0) {
+- _output->print_cr("%27s (mmap: reserved=%d%s, committed=%d%s)",
+- " ", reserved_amt, unit, committed_amt, unit);
+- }
+-
+- if (arena_amt > 0) {
+- _output->print_cr("%27s (arena=%d%s, #%d)", " ", arena_amt, unit, arena_count);
+- }
+-
+- _output->print_cr(" ");
++ out->print_cr(" from");
++ stack->print_on(out, 12);
+ }
+ }
+ }
+
+-void BaselineTTYOutputer::done_category_summary() {
+- _output->print_cr(" ");
+-}
++void MemSummaryDiffReporter::report_diff() {
++ const char* scale = current_scale();
++ outputStream* out = output();
++ out->print_cr("\nNative Memory Tracking:\n");
+
++ // Overall diff
++ out->print("Total: ");
++ print_virtual_memory_diff(_current_baseline.total_reserved_memory(),
++ _current_baseline.total_committed_memory(), _early_baseline.total_reserved_memory(),
++ _early_baseline.total_committed_memory());
+
+-void BaselineTTYOutputer::start_virtual_memory_map() {
+- _output->print_cr("Virtual memory map:");
+-}
++ out->print_cr("\n");
+
+-void BaselineTTYOutputer::reserved_memory_region(MEMFLAGS type, address base, address end,
+- size_t size, address pc) {
+- const char* unit = memory_unit(_scale);
+- char buf[128];
+- int offset;
+- _output->print_cr(" ");
+- _output->print_cr("[" PTR_FORMAT " - " PTR_FORMAT "] reserved %d%s for %s", base, end, size, unit,
+- MemBaseline::type2name(type));
+- if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
+- _output->print_cr("\t\tfrom [%s+0x%x]", buf, offset);
++ // Summary diff by memory type
++ for (int index = 0; index < mt_number_of_types; index ++) {
++ MEMFLAGS flag = NMTUtil::index_to_flag(index);
++ // thread stack is reported as part of thread category
++ if (flag == mtThreadStack) continue;
++ diff_summary_of_type(flag, _early_baseline.malloc_memory(flag),
++ _early_baseline.virtual_memory(flag), _current_baseline.malloc_memory(flag),
++ _current_baseline.virtual_memory(flag));
+ }
+ }
+
+-void BaselineTTYOutputer::committed_memory_region(address base, address end, size_t size, address pc) {
+- const char* unit = memory_unit(_scale);
+- char buf[128];
+- int offset;
+- _output->print("\t[" PTR_FORMAT " - " PTR_FORMAT "] committed %d%s", base, end, size, unit);
+- if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
+- _output->print_cr(" from [%s+0x%x]", buf, offset);
++void MemSummaryDiffReporter::print_malloc_diff(size_t current_amount, size_t current_count,
++ size_t early_amount, size_t early_count) const {
++ const char* scale = current_scale();
++ outputStream* out = output();
++
++ out->print("malloc=" SIZE_FORMAT "%s", amount_in_current_scale(current_amount), scale);
++ long amount_diff = diff_in_current_scale(current_amount, early_amount);
++ if (amount_diff != 0) {
++ out->print(" %+ld%s", amount_diff, scale);
++ }
++ if (current_count > 0) {
++ out->print(" #" SIZE_FORMAT "", current_count);
++ if (current_count != early_count) {
++ out->print(" %+d", (int)(current_count - early_count));
++ }
+ }
+ }
+
+-void BaselineTTYOutputer::done_virtual_memory_map() {
+- _output->print_cr(" ");
+-}
++void MemSummaryDiffReporter::print_arena_diff(size_t current_amount, size_t current_count,
++ size_t early_amount, size_t early_count) const {
++ const char* scale = current_scale();
++ outputStream* out = output();
++ out->print("arena=" SIZE_FORMAT "%s", amount_in_current_scale(current_amount), scale);
++ if (diff_in_current_scale(current_amount, early_amount) != 0) {
++ out->print(" %+ld", diff_in_current_scale(current_amount, early_amount));
++ }
+
+-
+-
+-void BaselineTTYOutputer::start_callsite() {
+- _output->print_cr("Details:");
+- _output->print_cr(" ");
+-}
+-
+-void BaselineTTYOutputer::done_callsite() {
+- _output->print_cr(" ");
+-}
+-
+-void BaselineTTYOutputer::malloc_callsite(address pc, size_t malloc_amt,
+- size_t malloc_count) {
+- if (malloc_amt > 0) {
+- const char* unit = memory_unit(_scale);
+- char buf[128];
+- int offset;
+- if (pc == 0) {
+- _output->print("[BOOTSTRAP]%18s", " ");
+- } else if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
+- _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
+- _output->print("%28s", " ");
+- } else {
+- _output->print("[" PTR_FORMAT "]%18s", pc, " ");
+- }
+-
+- _output->print_cr("(malloc=%d%s #%d)", malloc_amt, unit, malloc_count);
+- _output->print_cr(" ");
++ out->print(" #" SIZE_FORMAT "", current_count);
++ if (current_count != early_count) {
++ out->print(" %+d", (int)(current_count - early_count));
+ }
+ }
+
+-void BaselineTTYOutputer::virtual_memory_callsite(address pc, size_t reserved_amt,
+- size_t committed_amt) {
+- if (reserved_amt > 0) {
+- const char* unit = memory_unit(_scale);
+- char buf[128];
+- int offset;
+- if (pc == 0) {
+- _output->print("[BOOTSTRAP]%18s", " ");
+- } else if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
+- _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
+- _output->print("%28s", " ");
+- } else {
+- _output->print("[" PTR_FORMAT "]%18s", pc, " ");
+- }
++void MemSummaryDiffReporter::print_virtual_memory_diff(size_t current_reserved, size_t current_committed,
++ size_t early_reserved, size_t early_committed) const {
++ const char* scale = current_scale();
++ outputStream* out = output();
++ out->print("reserved=" SIZE_FORMAT "%s", amount_in_current_scale(current_reserved), scale);
++ long reserved_diff = diff_in_current_scale(current_reserved, early_reserved);
++ if (reserved_diff != 0) {
++ out->print(" %+ld%s", reserved_diff, scale);
++ }
+
+- _output->print_cr("(mmap: reserved=%d%s, committed=%d%s)",
+- reserved_amt, unit, committed_amt, unit);
+- _output->print_cr(" ");
++ out->print(", committed=" SIZE_FORMAT "%s", amount_in_current_scale(current_committed), scale);
++ long committed_diff = diff_in_current_scale(current_committed, early_committed);
++ if (committed_diff != 0) {
++ out->print(" %+ld%s", committed_diff, scale);
+ }
+ }
+
+-void BaselineTTYOutputer::diff_total_usage(size_t total_reserved,
+- size_t total_committed, int reserved_diff, int committed_diff) {
+- const char* unit = memory_unit(_scale);
+- _output->print_cr("Total: reserved=%d%s %+d%s, committed=%d%s %+d%s",
+- total_reserved, unit, reserved_diff, unit, total_committed, unit,
+- committed_diff, unit);
+-}
+
+-void BaselineTTYOutputer::diff_category_summary(MEMFLAGS type,
+- size_t cur_reserved_amt, size_t cur_committed_amt,
+- size_t cur_malloc_amt, size_t cur_malloc_count,
+- size_t cur_arena_amt, size_t cur_arena_count,
+- int reserved_diff, int committed_diff, int malloc_diff,
+- int malloc_count_diff, int arena_diff, int arena_count_diff) {
++void MemSummaryDiffReporter::diff_summary_of_type(MEMFLAGS flag, const MallocMemory* early_malloc,
++ const VirtualMemory* early_vm, const MallocMemory* current_malloc,
++ const VirtualMemory* current_vm) const {
+
+- if (type == mtThreadStack) {
+- assert(cur_malloc_amt == 0 && cur_malloc_count == 0 &&
+- cur_arena_amt == 0, "Just check");
+- _thread_stack_reserved = cur_reserved_amt;
+- _thread_stack_committed = cur_committed_amt;
+- _thread_stack_reserved_diff = reserved_diff;
+- _thread_stack_committed_diff = committed_diff;
+- } else {
+- const char* unit = memory_unit(_scale);
+- size_t total_reserved = (cur_reserved_amt + cur_malloc_amt + cur_arena_amt);
+- // nothing to report in this category
+- if (total_reserved == 0) {
+- return;
+- }
+- int diff_reserved = (reserved_diff + malloc_diff + arena_diff);
++ outputStream* out = output();
++ const char* scale = current_scale();
+
+- // category summary
+- _output->print("-%26s (reserved=%d%s", MemBaseline::type2name(type),
+- total_reserved, unit);
++ // Total reserved and committed memory in current baseline
++ size_t current_reserved_amount = reserved_total (current_malloc, current_vm);
++ size_t current_committed_amount = committed_total(current_malloc, current_vm);
+
+- if (diff_reserved != 0) {
+- _output->print(" %+d%s", diff_reserved, unit);
++ // Total reserved and committed memory in early baseline
++ size_t early_reserved_amount = reserved_total(early_malloc, early_vm);
++ size_t early_committed_amount = committed_total(early_malloc, early_vm);
++
++ // Adjust virtual memory total
++ if (flag == mtThread) {
++ const VirtualMemory* early_thread_stack_usage =
++ _early_baseline.virtual_memory(mtThreadStack);
++ const VirtualMemory* current_thread_stack_usage =
++ _current_baseline.virtual_memory(mtThreadStack);
++
++ early_reserved_amount += early_thread_stack_usage->reserved();
++ early_committed_amount += early_thread_stack_usage->committed();
++
++ current_reserved_amount += current_thread_stack_usage->reserved();
++ current_committed_amount += current_thread_stack_usage->committed();
++ } else if (flag == mtNMT) {
++ early_reserved_amount += _early_baseline.malloc_tracking_overhead();
++ early_committed_amount += _early_baseline.malloc_tracking_overhead();
++
++ current_reserved_amount += _current_baseline.malloc_tracking_overhead();
++ current_committed_amount += _current_baseline.malloc_tracking_overhead();
++ }
++
++ if (amount_in_current_scale(current_reserved_amount) > 0 ||
++ diff_in_current_scale(current_reserved_amount, early_reserved_amount) != 0) {
++
++ // print summary line
++ out->print("-%26s (", NMTUtil::flag_to_name(flag));
++ print_virtual_memory_diff(current_reserved_amount, current_committed_amount,
++ early_reserved_amount, early_committed_amount);
++ out->print_cr(")");
++
++ // detail lines
++ if (flag == mtClass) {
++ // report class count
++ out->print("%27s (classes #" SIZE_FORMAT "", " ", _current_baseline.class_count());
++ int class_count_diff = (int)(_current_baseline.class_count() -
++ _early_baseline.class_count());
++ if (_current_baseline.class_count() != _early_baseline.class_count()) {
++ out->print(" %+d", (int)(_current_baseline.class_count() - _early_baseline.class_count()));
++ }
++ out->print_cr(")");
++ } else if (flag == mtThread) {
++ // report thread count
++ out->print("%27s (thread #" SIZE_FORMAT "", " ", _current_baseline.thread_count());
++ int thread_count_diff = (int)(_current_baseline.thread_count() -
++ _early_baseline.thread_count());
++ if (thread_count_diff != 0) {
++ out->print(" %+d", thread_count_diff);
++ }
++ out->print_cr(")");
++
++ // report thread stack
++ const VirtualMemory* current_thread_stack =
++ _current_baseline.virtual_memory(mtThreadStack);
++ const VirtualMemory* early_thread_stack =
++ _early_baseline.virtual_memory(mtThreadStack);
++
++ out->print("%27s (stack: ", " ");
++ print_virtual_memory_diff(current_thread_stack->reserved(), current_thread_stack->committed(),
++ early_thread_stack->reserved(), early_thread_stack->committed());
++ out->print_cr(")");
+ }
+
+- size_t total_committed = cur_committed_amt + cur_malloc_amt + cur_arena_amt;
+- _output->print(", committed=%d%s", total_committed, unit);
+-
+- int total_committed_diff = committed_diff + malloc_diff + arena_diff;
+- if (total_committed_diff != 0) {
+- _output->print(" %+d%s", total_committed_diff, unit);
++ // Report malloc'd memory
++ size_t current_malloc_amount = current_malloc->malloc_size();
++ size_t early_malloc_amount = early_malloc->malloc_size();
++ if (amount_in_current_scale(current_malloc_amount) > 0 ||
++ diff_in_current_scale(current_malloc_amount, early_malloc_amount) != 0) {
++ out->print("%28s(", " ");
++ print_malloc_diff(current_malloc_amount, (flag == mtChunk) ? 0 : current_malloc->malloc_count(),
++ early_malloc_amount, early_malloc->malloc_count());
++ out->print_cr(")");
+ }
+
+- _output->print_cr(")");
+-
+- // special cases
+- if (type == mtClass) {
+- _output->print("%27s (classes #%d", " ", _num_of_classes);
+- if (_num_of_classes_diff != 0) {
+- _output->print(" %+d", _num_of_classes_diff);
+- }
+- _output->print_cr(")");
+- } else if (type == mtThread) {
+- // thread count
+- _output->print("%27s (thread #%d", " ", _num_of_threads);
+- if (_num_of_threads_diff != 0) {
+- _output->print_cr(" %+d)", _num_of_threads_diff);
+- } else {
+- _output->print_cr(")");
+- }
+- _output->print("%27s (stack: reserved=%d%s", " ", _thread_stack_reserved, unit);
+- if (_thread_stack_reserved_diff != 0) {
+- _output->print(" %+d%s", _thread_stack_reserved_diff, unit);
+- }
+-
+- _output->print(", committed=%d%s", _thread_stack_committed, unit);
+- if (_thread_stack_committed_diff != 0) {
+- _output->print(" %+d%s",_thread_stack_committed_diff, unit);
+- }
+-
+- _output->print_cr(")");
++ // Report virtual memory
++ if (amount_in_current_scale(current_vm->reserved()) > 0 ||
++ diff_in_current_scale(current_vm->reserved(), early_vm->reserved()) != 0) {
++ out->print("%27s (mmap: ", " ");
++ print_virtual_memory_diff(current_vm->reserved(), current_vm->committed(),
++ early_vm->reserved(), early_vm->committed());
++ out->print_cr(")");
+ }
+
+- // malloc'd memory
+- if (cur_malloc_amt > 0) {
+- _output->print("%27s (malloc=%d%s", " ", cur_malloc_amt, unit);
+- if (malloc_diff != 0) {
+- _output->print(" %+d%s", malloc_diff, unit);
+- }
+- if (type != mtChunk) {
+- _output->print(", #%d", cur_malloc_count);
+- if (malloc_count_diff) {
+- _output->print(" %+d", malloc_count_diff);
+- }
+- }
+- _output->print_cr(")");
++ // Report arena memory
++ if (amount_in_current_scale(current_malloc->arena_size()) > 0 ||
++ diff_in_current_scale(current_malloc->arena_size(), early_malloc->arena_size()) != 0) {
++ out->print("%28s(", " ");
++ print_arena_diff(current_malloc->arena_size(), current_malloc->arena_count(),
++ early_malloc->arena_size(), early_malloc->arena_count());
++ out->print_cr(")");
+ }
+
+- // mmap'd memory
+- if (cur_reserved_amt > 0) {
+- _output->print("%27s (mmap: reserved=%d%s", " ", cur_reserved_amt, unit);
+- if (reserved_diff != 0) {
+- _output->print(" %+d%s", reserved_diff, unit);
++ // Report native memory tracking overhead
++ if (flag == mtNMT) {
++ size_t current_tracking_overhead = amount_in_current_scale(_current_baseline.malloc_tracking_overhead());
++ size_t early_tracking_overhead = amount_in_current_scale(_early_baseline.malloc_tracking_overhead());
++
++ out->print("%27s (tracking overhead=" SIZE_FORMAT "%s", " ",
++ amount_in_current_scale(_current_baseline.malloc_tracking_overhead()), scale);
++
++ long overhead_diff = diff_in_current_scale(_current_baseline.malloc_tracking_overhead(),
++ _early_baseline.malloc_tracking_overhead());
++ if (overhead_diff != 0) {
++ out->print(" %+ld%s", overhead_diff, scale);
+ }
+-
+- _output->print(", committed=%d%s", cur_committed_amt, unit);
+- if (committed_diff != 0) {
+- _output->print(" %+d%s", committed_diff, unit);
+- }
+- _output->print_cr(")");
++ out->print_cr(")");
+ }
+-
+- // arena memory
+- if (cur_arena_amt > 0) {
+- _output->print("%27s (arena=%d%s", " ", cur_arena_amt, unit);
+- if (arena_diff != 0) {
+- _output->print(" %+d%s", arena_diff, unit);
+- }
+- _output->print(", #%d", cur_arena_count);
+- if (arena_count_diff != 0) {
+- _output->print(" %+d", arena_count_diff);
+- }
+- _output->print_cr(")");
+- }
+-
+- _output->print_cr(" ");
++ out->print_cr(" ");
+ }
+ }
+
+-void BaselineTTYOutputer::diff_malloc_callsite(address pc,
+- size_t cur_malloc_amt, size_t cur_malloc_count,
+- int malloc_diff, int malloc_count_diff) {
+- if (malloc_diff != 0) {
+- const char* unit = memory_unit(_scale);
+- char buf[128];
+- int offset;
+- if (pc == 0) {
+- _output->print_cr("[BOOTSTRAP]%18s", " ");
++void MemDetailDiffReporter::report_diff() {
++ MemSummaryDiffReporter::report_diff();
++ diff_malloc_sites();
++ diff_virtual_memory_sites();
++}
++
++void MemDetailDiffReporter::diff_malloc_sites() const {
++ MallocSiteIterator early_itr = _early_baseline.malloc_sites(MemBaseline::by_site);
++ MallocSiteIterator current_itr = _current_baseline.malloc_sites(MemBaseline::by_site);
++
++ const MallocSite* early_site = early_itr.next();
++ const MallocSite* current_site = current_itr.next();
++
++ while (early_site != NULL || current_site != NULL) {
++ if (early_site == NULL) {
++ new_malloc_site(current_site);
++ current_site = current_itr.next();
++ } else if (current_site == NULL) {
++ old_malloc_site(early_site);
++ early_site = early_itr.next();
+ } else {
+- if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
+- _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
+- _output->print("%28s", " ");
++ int compVal = current_site->call_stack()->compare(*early_site->call_stack());
++ if (compVal < 0) {
++ new_malloc_site(current_site);
++ current_site = current_itr.next();
++ } else if (compVal > 0) {
++ old_malloc_site(early_site);
++ early_site = early_itr.next();
+ } else {
+- _output->print("[" PTR_FORMAT "]%18s", pc, " ");
++ diff_malloc_site(early_site, current_site);
++ early_site = early_itr.next();
++ current_site = current_itr.next();
+ }
+ }
+-
+- _output->print("(malloc=%d%s", cur_malloc_amt, unit);
+- if (malloc_diff != 0) {
+- _output->print(" %+d%s", malloc_diff, unit);
+- }
+- _output->print(", #%d", cur_malloc_count);
+- if (malloc_count_diff != 0) {
+- _output->print(" %+d", malloc_count_diff);
+- }
+- _output->print_cr(")");
+- _output->print_cr(" ");
+ }
+ }
+
+-void BaselineTTYOutputer::diff_virtual_memory_callsite(address pc,
+- size_t cur_reserved_amt, size_t cur_committed_amt,
+- int reserved_diff, int committed_diff) {
+- if (reserved_diff != 0 || committed_diff != 0) {
+- const char* unit = memory_unit(_scale);
+- char buf[64];
+- int offset;
+- if (pc == 0) {
+- _output->print_cr("[BOOSTRAP]%18s", " ");
++void MemDetailDiffReporter::diff_virtual_memory_sites() const {
++ VirtualMemorySiteIterator early_itr = _early_baseline.virtual_memory_sites(MemBaseline::by_site);
++ VirtualMemorySiteIterator current_itr = _current_baseline.virtual_memory_sites(MemBaseline::by_site);
++
++ const VirtualMemoryAllocationSite* early_site = early_itr.next();
++ const VirtualMemoryAllocationSite* current_site = current_itr.next();
++
++ while (early_site != NULL || current_site != NULL) {
++ if (early_site == NULL) {
++ new_virtual_memory_site(current_site);
++ current_site = current_itr.next();
++ } else if (current_site == NULL) {
++ old_virtual_memory_site(early_site);
++ early_site = early_itr.next();
+ } else {
+- if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
+- _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
+- _output->print("%28s", " ");
++ int compVal = current_site->call_stack()->compare(*early_site->call_stack());
++ if (compVal < 0) {
++ new_virtual_memory_site(current_site);
++ current_site = current_itr.next();
++ } else if (compVal > 0) {
++ old_virtual_memory_site(early_site);
++ early_site = early_itr.next();
+ } else {
+- _output->print("[" PTR_FORMAT "]%18s", pc, " ");
++ diff_virtual_memory_site(early_site, current_site);
++ early_site = early_itr.next();
++ current_site = current_itr.next();
+ }
+ }
+-
+- _output->print("(mmap: reserved=%d%s", cur_reserved_amt, unit);
+- if (reserved_diff != 0) {
+- _output->print(" %+d%s", reserved_diff, unit);
+- }
+- _output->print(", committed=%d%s", cur_committed_amt, unit);
+- if (committed_diff != 0) {
+- _output->print(" %+d%s", committed_diff, unit);
+- }
+- _output->print_cr(")");
+- _output->print_cr(" ");
+ }
+ }
++
++
++void MemDetailDiffReporter::new_malloc_site(const MallocSite* malloc_site) const {
++ diff_malloc_site(malloc_site->call_stack(), malloc_site->size(), malloc_site->count(),
++ 0, 0);
++}
++
++void MemDetailDiffReporter::old_malloc_site(const MallocSite* malloc_site) const {
++ diff_malloc_site(malloc_site->call_stack(), 0, 0, malloc_site->size(),
++ malloc_site->count());
++}
++
++void MemDetailDiffReporter::diff_malloc_site(const MallocSite* early,
++ const MallocSite* current) const {
++ diff_malloc_site(current->call_stack(), current->size(), current->count(),
++ early->size(), early->count());
++}
++
++void MemDetailDiffReporter::diff_malloc_site(const NativeCallStack* stack, size_t current_size,
++ size_t current_count, size_t early_size, size_t early_count) const {
++ outputStream* out = output();
++
++ assert(stack != NULL, "NULL stack");
++
++ if (diff_in_current_scale(current_size, early_size) == 0) {
++ return;
++ }
++
++ stack->print_on(out);
++ out->print("%28s (", " ");
++ print_malloc_diff(current_size, current_count,
++ early_size, early_count);
++
++ out->print_cr(")\n");
++}
++
++
++void MemDetailDiffReporter::new_virtual_memory_site(const VirtualMemoryAllocationSite* site) const {
++ diff_virtual_memory_site(site->call_stack(), site->reserved(), site->committed(), 0, 0);
++}
++
++void MemDetailDiffReporter::old_virtual_memory_site(const VirtualMemoryAllocationSite* site) const {
++ diff_virtual_memory_site(site->call_stack(), 0, 0, site->reserved(), site->committed());
++}
++
++void MemDetailDiffReporter::diff_virtual_memory_site(const VirtualMemoryAllocationSite* early,
++ const VirtualMemoryAllocationSite* current) const {
++ diff_virtual_memory_site(current->call_stack(), current->reserved(), current->committed(),
++ early->reserved(), early->committed());
++}
++
++void MemDetailDiffReporter::diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved,
++ size_t current_committed, size_t early_reserved, size_t early_committed) const {
++ outputStream* out = output();
++
++ // no change
++ if (diff_in_current_scale(current_reserved, early_reserved) == 0 &&
++ diff_in_current_scale(current_committed, early_committed) == 0) {
++ return;
++ }
++
++ stack->print_on(out);
++ out->print("%28s (mmap: ", " ");
++ print_virtual_memory_diff(current_reserved, current_committed,
++ early_reserved, early_committed);
++
++ out->print_cr(")\n");
++ }
++
+--- ./hotspot/src/share/vm/services/memReporter.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/services/memReporter.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -25,262 +25,203 @@
+ #ifndef SHARE_VM_SERVICES_MEM_REPORTER_HPP
+ #define SHARE_VM_SERVICES_MEM_REPORTER_HPP
+
+-#include "runtime/mutexLocker.hpp"
+-#include "services/memBaseline.hpp"
+-#include "services/memTracker.hpp"
+-#include "utilities/ostream.hpp"
+-#include "utilities/macros.hpp"
+-
+ #if INCLUDE_NMT
+
++#include "oops/instanceKlass.hpp"
++#include "services/memBaseline.hpp"
++#include "services/nmtCommon.hpp"
++#include "services/mallocTracker.hpp"
++#include "services/virtualMemoryTracker.hpp"
++
+ /*
+- * MemBaselineReporter reports data to this outputer class,
+- * ReportOutputer is responsible for format, store and redirect
+- * the data to the final destination.
+- */
+-class BaselineOutputer : public StackObj {
++ * Base class that provides helpers
++*/
++class MemReporterBase : public StackObj {
++ private:
++ size_t _scale; // report in this scale
++ outputStream* _output; // destination
++
+ public:
+- // start to report memory usage in specified scale.
+- // if report_diff = true, the reporter reports baseline comparison
+- // information.
++ MemReporterBase(outputStream* out = NULL, size_t scale = K)
++ : _scale(scale) {
++ _output = (out == NULL) ? tty : out;
++ }
+
+- virtual void start(size_t scale, bool report_diff = false) = 0;
+- // Done reporting
+- virtual void done() = 0;
++ protected:
++ inline outputStream* output() const {
++ return _output;
++ }
++ // Current reporting scale
++ inline const char* current_scale() const {
++ return NMTUtil::scale_name(_scale);
++ }
++ // Convert memory amount in bytes to current reporting scale
++ inline size_t amount_in_current_scale(size_t amount) const {
++ return NMTUtil::amount_in_scale(amount, _scale);
++ }
+
+- /* report baseline summary information */
+- virtual void total_usage(size_t total_reserved,
+- size_t total_committed) = 0;
+- virtual void num_of_classes(size_t classes) = 0;
+- virtual void num_of_threads(size_t threads) = 0;
++ // Convert diff amount in bytes to current reporting scale
++ inline long diff_in_current_scale(size_t s1, size_t s2) const {
++ long amount = (long)(s1 - s2);
++ long scale = (long)_scale;
++ amount = (amount > 0) ? (amount + scale / 2) : (amount - scale / 2);
++ return amount / scale;
++ }
+
+- virtual void thread_info(size_t stack_reserved_amt, size_t stack_committed_amt) = 0;
++ // Helper functions
++ // Calculate total reserved and committed amount
++ size_t reserved_total(const MallocMemory* malloc, const VirtualMemory* vm) const;
++ size_t committed_total(const MallocMemory* malloc, const VirtualMemory* vm) const;
+
+- /* report baseline summary comparison */
+- virtual void diff_total_usage(size_t total_reserved,
+- size_t total_committed,
+- int reserved_diff,
+- int committed_diff) = 0;
+- virtual void diff_num_of_classes(size_t classes, int diff) = 0;
+- virtual void diff_num_of_threads(size_t threads, int diff) = 0;
+
+- virtual void diff_thread_info(size_t stack_reserved, size_t stack_committed,
+- int stack_reserved_diff, int stack_committed_diff) = 0;
++ // Print summary total, malloc and virtual memory
++ void print_total(size_t reserved, size_t committed) const;
++ void print_malloc(size_t amount, size_t count) const;
++ void print_virtual_memory(size_t reserved, size_t committed) const;
+
++ void print_malloc_line(size_t amount, size_t count) const;
++ void print_virtual_memory_line(size_t reserved, size_t committed) const;
++ void print_arena_line(size_t amount, size_t count) const;
+
+- /*
+- * memory summary by memory types.
+- * for each memory type, following summaries are reported:
+- * - reserved amount, committed amount
+- * - malloc'd amount, malloc count
+- * - arena amount, arena count
+- */
+-
+- // start reporting memory summary by memory type
+- virtual void start_category_summary() = 0;
+-
+- virtual void category_summary(MEMFLAGS type, size_t reserved_amt,
+- size_t committed_amt,
+- size_t malloc_amt, size_t malloc_count,
+- size_t arena_amt, size_t arena_count) = 0;
+-
+- virtual void diff_category_summary(MEMFLAGS type, size_t cur_reserved_amt,
+- size_t cur_committed_amt,
+- size_t cur_malloc_amt, size_t cur_malloc_count,
+- size_t cur_arena_amt, size_t cur_arena_count,
+- int reserved_diff, int committed_diff, int malloc_diff,
+- int malloc_count_diff, int arena_diff,
+- int arena_count_diff) = 0;
+-
+- virtual void done_category_summary() = 0;
+-
+- virtual void start_virtual_memory_map() = 0;
+- virtual void reserved_memory_region(MEMFLAGS type, address base, address end, size_t size, address pc) = 0;
+- virtual void committed_memory_region(address base, address end, size_t size, address pc) = 0;
+- virtual void done_virtual_memory_map() = 0;
+-
+- /*
+- * Report callsite information
+- */
+- virtual void start_callsite() = 0;
+- virtual void malloc_callsite(address pc, size_t malloc_amt, size_t malloc_count) = 0;
+- virtual void virtual_memory_callsite(address pc, size_t reserved_amt, size_t committed_amt) = 0;
+-
+- virtual void diff_malloc_callsite(address pc, size_t cur_malloc_amt, size_t cur_malloc_count,
+- int malloc_diff, int malloc_count_diff) = 0;
+- virtual void diff_virtual_memory_callsite(address pc, size_t cur_reserved_amt, size_t cur_committed_amt,
+- int reserved_diff, int committed_diff) = 0;
+-
+- virtual void done_callsite() = 0;
+-
+- // return current scale in "KB", "MB" or "GB"
+- static const char* memory_unit(size_t scale);
++ void print_virtual_memory_region(const char* type, address base, size_t size) const;
+ };
+
+ /*
+- * This class reports processed data from a baseline or
+- * the changes between the two baseline.
++ * The class is for generating summary tracking report.
+ */
+-class BaselineReporter : public StackObj {
++class MemSummaryReporter : public MemReporterBase {
+ private:
+- BaselineOutputer& _outputer;
+- size_t _scale;
++ MallocMemorySnapshot* _malloc_snapshot;
++ VirtualMemorySnapshot* _vm_snapshot;
++ size_t _class_count;
+
+ public:
+- // construct a reporter that reports memory usage
+- // in specified scale
+- BaselineReporter(BaselineOutputer& outputer, size_t scale = K):
+- _outputer(outputer) {
+- _scale = scale;
+- }
+- virtual void report_baseline(const MemBaseline& baseline, bool summary_only = false);
+- virtual void diff_baselines(const MemBaseline& cur, const MemBaseline& prev,
+- bool summary_only = false);
++ // This constructor is for normal reporting from a recent baseline.
++ MemSummaryReporter(MemBaseline& baseline, outputStream* output,
++ size_t scale = K) : MemReporterBase(output, scale),
++ _malloc_snapshot(baseline.malloc_memory_snapshot()),
++ _vm_snapshot(baseline.virtual_memory_snapshot()),
++ _class_count(baseline.class_count()) { }
+
+- void set_scale(size_t scale);
+- size_t scale() const { return _scale; }
+
++ // Generate summary report
++ virtual void report();
+ private:
+- void report_summaries(const MemBaseline& baseline);
+- void report_virtual_memory_map(const MemBaseline& baseline);
+- void report_callsites(const MemBaseline& baseline);
+-
+- void diff_summaries(const MemBaseline& cur, const MemBaseline& prev);
+- void diff_callsites(const MemBaseline& cur, const MemBaseline& prev);
+-
+- // calculate memory size in current memory scale
+- size_t amount_in_current_scale(size_t amt) const;
+- // diff two unsigned values in current memory scale
+- int diff_in_current_scale(size_t value1, size_t value2) const;
+- // diff two unsigned value
+- int diff(size_t value1, size_t value2) const;
++ // Report summary for each memory type
++ void report_summary_of_type(MEMFLAGS type, MallocMemory* malloc_memory,
++ VirtualMemory* virtual_memory);
+ };
+
+ /*
+- * tty output implementation. Native memory tracking
+- * DCmd uses this outputer.
++ * The class is for generating detail tracking report.
+ */
+-class BaselineTTYOutputer : public BaselineOutputer {
++class MemDetailReporter : public MemSummaryReporter {
+ private:
+- size_t _scale;
+-
+- size_t _num_of_classes;
+- size_t _num_of_threads;
+- size_t _thread_stack_reserved;
+- size_t _thread_stack_committed;
+-
+- int _num_of_classes_diff;
+- int _num_of_threads_diff;
+- int _thread_stack_reserved_diff;
+- int _thread_stack_committed_diff;
+-
+- outputStream* _output;
++ MemBaseline& _baseline;
+
+ public:
+- BaselineTTYOutputer(outputStream* st) {
+- _scale = K;
+- _num_of_classes = 0;
+- _num_of_threads = 0;
+- _thread_stack_reserved = 0;
+- _thread_stack_committed = 0;
+- _num_of_classes_diff = 0;
+- _num_of_threads_diff = 0;
+- _thread_stack_reserved_diff = 0;
+- _thread_stack_committed_diff = 0;
+- _output = st;
++ MemDetailReporter(MemBaseline& baseline, outputStream* output, size_t scale = K) :
++ MemSummaryReporter(baseline, output, scale),
++ _baseline(baseline) { }
++
++ // Generate detail report.
++ // The report contains summary and detail sections.
++ virtual void report() {
++ MemSummaryReporter::report();
++ report_virtual_memory_map();
++ report_detail();
+ }
+
+- // begin reporting memory usage in specified scale
+- void start(size_t scale, bool report_diff = false);
+- // done reporting
+- void done();
++ private:
++ // Report detail tracking data.
++ void report_detail();
++ // Report virtual memory map
++ void report_virtual_memory_map();
++ // Report malloc allocation sites
++ void report_malloc_sites();
++ // Report virtual memory reservation sites
++ void report_virtual_memory_allocation_sites();
+
+- // total memory usage
+- void total_usage(size_t total_reserved,
+- size_t total_committed);
+- // report total loaded classes
+- void num_of_classes(size_t classes) {
+- _num_of_classes = classes;
++ // Report a virtual memory region
++ void report_virtual_memory_region(const ReservedMemoryRegion* rgn);
++};
++
++/*
++ * The class is for generating summary comparison report.
++ * It compares current memory baseline against an early baseline.
++ */
++class MemSummaryDiffReporter : public MemReporterBase {
++ protected:
++ MemBaseline& _early_baseline;
++ MemBaseline& _current_baseline;
++
++ public:
++ MemSummaryDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline,
++ outputStream* output, size_t scale = K) : MemReporterBase(output, scale),
++ _early_baseline(early_baseline), _current_baseline(current_baseline) {
++ assert(early_baseline.baseline_type() != MemBaseline::Not_baselined, "Not baselined");
++ assert(current_baseline.baseline_type() != MemBaseline::Not_baselined, "Not baselined");
+ }
+
+- void num_of_threads(size_t threads) {
+- _num_of_threads = threads;
+- }
++ // Generate summary comparison report
++ virtual void report_diff();
+
+- void thread_info(size_t stack_reserved_amt, size_t stack_committed_amt) {
+- _thread_stack_reserved = stack_reserved_amt;
+- _thread_stack_committed = stack_committed_amt;
+- }
++ private:
++ // report the comparison of each memory type
++ void diff_summary_of_type(MEMFLAGS type,
++ const MallocMemory* early_malloc, const VirtualMemory* early_vm,
++ const MallocMemory* current_malloc, const VirtualMemory* current_vm) const;
+
+- void diff_total_usage(size_t total_reserved,
+- size_t total_committed,
+- int reserved_diff,
+- int committed_diff);
+-
+- void diff_num_of_classes(size_t classes, int diff) {
+- _num_of_classes = classes;
+- _num_of_classes_diff = diff;
+- }
+-
+- void diff_num_of_threads(size_t threads, int diff) {
+- _num_of_threads = threads;
+- _num_of_threads_diff = diff;
+- }
+-
+- void diff_thread_info(size_t stack_reserved_amt, size_t stack_committed_amt,
+- int stack_reserved_diff, int stack_committed_diff) {
+- _thread_stack_reserved = stack_reserved_amt;
+- _thread_stack_committed = stack_committed_amt;
+- _thread_stack_reserved_diff = stack_reserved_diff;
+- _thread_stack_committed_diff = stack_committed_diff;
+- }
+-
+- /*
+- * Report memory summary categoriuzed by memory types.
+- * For each memory type, following summaries are reported:
+- * - reserved amount, committed amount
+- * - malloc-ed amount, malloc count
+- * - arena amount, arena count
+- */
+- // start reporting memory summary by memory type
+- void start_category_summary();
+- void category_summary(MEMFLAGS type, size_t reserved_amt, size_t committed_amt,
+- size_t malloc_amt, size_t malloc_count,
+- size_t arena_amt, size_t arena_count);
+-
+- void diff_category_summary(MEMFLAGS type, size_t cur_reserved_amt,
+- size_t cur_committed_amt,
+- size_t cur_malloc_amt, size_t cur_malloc_count,
+- size_t cur_arena_amt, size_t cur_arena_count,
+- int reserved_diff, int committed_diff, int malloc_diff,
+- int malloc_count_diff, int arena_diff,
+- int arena_count_diff);
+-
+- void done_category_summary();
+-
+- // virtual memory map
+- void start_virtual_memory_map();
+- void reserved_memory_region(MEMFLAGS type, address base, address end, size_t size, address pc);
+- void committed_memory_region(address base, address end, size_t size, address pc);
+- void done_virtual_memory_map();
+-
+-
+- /*
+- * Report callsite information
+- */
+- void start_callsite();
+- void malloc_callsite(address pc, size_t malloc_amt, size_t malloc_count);
+- void virtual_memory_callsite(address pc, size_t reserved_amt, size_t committed_amt);
+-
+- void diff_malloc_callsite(address pc, size_t cur_malloc_amt, size_t cur_malloc_count,
+- int malloc_diff, int malloc_count_diff);
+- void diff_virtual_memory_callsite(address pc, size_t cur_reserved_amt, size_t cur_committed_amt,
+- int reserved_diff, int committed_diff);
+-
+- void done_callsite();
++ protected:
++ void print_malloc_diff(size_t current_amount, size_t current_count,
++ size_t early_amount, size_t early_count) const;
++ void print_virtual_memory_diff(size_t current_reserved, size_t current_committed,
++ size_t early_reserved, size_t early_committed) const;
++ void print_arena_diff(size_t current_amount, size_t current_count,
++ size_t early_amount, size_t early_count) const;
+ };
+
++/*
++ * The class is for generating detail comparison report.
++ * It compares current memory baseline against an early baseline,
++ * both baselines have to be detail baseline.
++ */
++class MemDetailDiffReporter : public MemSummaryDiffReporter {
++ public:
++ MemDetailDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline,
++ outputStream* output, size_t scale = K) :
++ MemSummaryDiffReporter(early_baseline, current_baseline, output, scale) { }
++
++ // Generate detail comparison report
++ virtual void report_diff();
++
++ // Malloc allocation site comparison
++ void diff_malloc_sites() const;
++ // Virutal memory reservation site comparison
++ void diff_virtual_memory_sites() const;
++
++ // New malloc allocation site in recent baseline
++ void new_malloc_site (const MallocSite* site) const;
++ // The malloc allocation site is not in recent baseline
++ void old_malloc_site (const MallocSite* site) const;
++ // Compare malloc allocation site, it is in both baselines
++ void diff_malloc_site(const MallocSite* early, const MallocSite* current) const;
++
++ // New virtual memory allocation site in recent baseline
++ void new_virtual_memory_site (const VirtualMemoryAllocationSite* callsite) const;
++ // The virtual memory allocation site is not in recent baseline
++ void old_virtual_memory_site (const VirtualMemoryAllocationSite* callsite) const;
++ // Compare virtual memory allocation site, it is in both baseline
++ void diff_virtual_memory_site(const VirtualMemoryAllocationSite* early,
++ const VirtualMemoryAllocationSite* current) const;
++
++ void diff_malloc_site(const NativeCallStack* stack, size_t current_size,
++ size_t currrent_count, size_t early_size, size_t early_count) const;
++ void diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved,
++ size_t current_committed, size_t early_reserved, size_t early_committed) const;
++};
+
+ #endif // INCLUDE_NMT
+
+-#endif // SHARE_VM_SERVICES_MEM_REPORTER_HPP
++#endif
++
+--- ./hotspot/src/share/vm/services/memSnapshot.cpp Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,748 +0,0 @@
+-/*
+- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- *
+- */
+-
+-#include "precompiled.hpp"
+-#include "runtime/mutexLocker.hpp"
+-#include "utilities/decoder.hpp"
+-#include "services/memBaseline.hpp"
+-#include "services/memPtr.hpp"
+-#include "services/memPtrArray.hpp"
+-#include "services/memSnapshot.hpp"
+-#include "services/memTracker.hpp"
+-
+-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+-
+-#ifdef ASSERT
+-
+-void decode_pointer_record(MemPointerRecord* rec) {
+- tty->print("Pointer: [" PTR_FORMAT " - " PTR_FORMAT "] size = %d bytes", rec->addr(),
+- rec->addr() + rec->size(), (int)rec->size());
+- tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags())));
+- if (rec->is_vm_pointer()) {
+- if (rec->is_allocation_record()) {
+- tty->print_cr(" (reserve)");
+- } else if (rec->is_commit_record()) {
+- tty->print_cr(" (commit)");
+- } else if (rec->is_uncommit_record()) {
+- tty->print_cr(" (uncommit)");
+- } else if (rec->is_deallocation_record()) {
+- tty->print_cr(" (release)");
+- } else {
+- tty->print_cr(" (tag)");
+- }
+- } else {
+- if (rec->is_arena_memory_record()) {
+- tty->print_cr(" (arena size)");
+- } else if (rec->is_allocation_record()) {
+- tty->print_cr(" (malloc)");
+- } else {
+- tty->print_cr(" (free)");
+- }
+- }
+- if (MemTracker::track_callsite()) {
+- char buf[1024];
+- address pc = ((MemPointerRecordEx*)rec)->pc();
+- if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) {
+- tty->print_cr("\tfrom %s", buf);
+- } else {
+- tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc);
+- }
+- }
+-}
+-
+-void decode_vm_region_record(VMMemRegion* rec) {
+- tty->print("VM Region [" PTR_FORMAT " - " PTR_FORMAT "]", rec->addr(),
+- rec->addr() + rec->size());
+- tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags())));
+- if (rec->is_allocation_record()) {
+- tty->print_cr(" (reserved)");
+- } else if (rec->is_commit_record()) {
+- tty->print_cr(" (committed)");
+- } else {
+- ShouldNotReachHere();
+- }
+- if (MemTracker::track_callsite()) {
+- char buf[1024];
+- address pc = ((VMMemRegionEx*)rec)->pc();
+- if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) {
+- tty->print_cr("\tfrom %s", buf);
+- } else {
+- tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc);
+- }
+-
+- }
+-}
+-
+-#endif
+-
+-
+-bool VMMemPointerIterator::insert_record(MemPointerRecord* rec) {
+- VMMemRegionEx new_rec;
+- assert(rec->is_allocation_record() || rec->is_commit_record(),
+- "Sanity check");
+- if (MemTracker::track_callsite()) {
+- new_rec.init((MemPointerRecordEx*)rec);
+- } else {
+- new_rec.init(rec);
+- }
+- return insert(&new_rec);
+-}
+-
+-bool VMMemPointerIterator::insert_record_after(MemPointerRecord* rec) {
+- VMMemRegionEx new_rec;
+- assert(rec->is_allocation_record() || rec->is_commit_record(),
+- "Sanity check");
+- if (MemTracker::track_callsite()) {
+- new_rec.init((MemPointerRecordEx*)rec);
+- } else {
+- new_rec.init(rec);
+- }
+- return insert_after(&new_rec);
+-}
+-
+-// we don't consolidate reserved regions, since they may be categorized
+-// in different types.
+-bool VMMemPointerIterator::add_reserved_region(MemPointerRecord* rec) {
+- assert(rec->is_allocation_record(), "Sanity check");
+- VMMemRegion* reserved_region = (VMMemRegion*)current();
+-
+- // we don't have anything yet
+- if (reserved_region == NULL) {
+- return insert_record(rec);
+- }
+-
+- assert(reserved_region->is_reserved_region(), "Sanity check");
+- // duplicated records
+- if (reserved_region->is_same_region(rec)) {
+- return true;
+- }
+- // Overlapping stack regions indicate that a JNI thread failed to
+- // detach from the VM before exiting. This leaks the JavaThread object.
+- if (CheckJNICalls) {
+- guarantee(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) != mtThreadStack ||
+- !reserved_region->overlaps_region(rec),
+- "Attached JNI thread exited without being detached");
+- }
+- // otherwise, we should not have overlapping reserved regions
+- assert(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) == mtThreadStack ||
+- reserved_region->base() > rec->addr(), "Just check: locate()");
+- assert(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) == mtThreadStack ||
+- !reserved_region->overlaps_region(rec), "overlapping reserved regions");
+-
+- return insert_record(rec);
+-}
+-
+-// we do consolidate committed regions
+-bool VMMemPointerIterator::add_committed_region(MemPointerRecord* rec) {
+- assert(rec->is_commit_record(), "Sanity check");
+- VMMemRegion* reserved_rgn = (VMMemRegion*)current();
+- assert(reserved_rgn->is_reserved_region() && reserved_rgn->contains_region(rec),
+- "Sanity check");
+-
+- // thread's native stack is always marked as "committed", ignore
+- // the "commit" operation for creating stack guard pages
+- if (FLAGS_TO_MEMORY_TYPE(reserved_rgn->flags()) == mtThreadStack &&
+- FLAGS_TO_MEMORY_TYPE(rec->flags()) != mtThreadStack) {
+- return true;
+- }
+-
+- // if the reserved region has any committed regions
+- VMMemRegion* committed_rgn = (VMMemRegion*)next();
+- while (committed_rgn != NULL && committed_rgn->is_committed_region()) {
+- // duplicated commit records
+- if(committed_rgn->contains_region(rec)) {
+- return true;
+- } else if (committed_rgn->overlaps_region(rec)) {
+- // overlaps front part
+- if (rec->addr() < committed_rgn->addr()) {
+- committed_rgn->expand_region(rec->addr(),
+- committed_rgn->addr() - rec->addr());
+- } else {
+- // overlaps tail part
+- address committed_rgn_end = committed_rgn->addr() +
+- committed_rgn->size();
+- assert(committed_rgn_end < rec->addr() + rec->size(),
+- "overlap tail part");
+- committed_rgn->expand_region(committed_rgn_end,
+- (rec->addr() + rec->size()) - committed_rgn_end);
+- }
+- } else if (committed_rgn->base() + committed_rgn->size() == rec->addr()) {
+- // adjunct each other
+- committed_rgn->expand_region(rec->addr(), rec->size());
+- VMMemRegion* next_reg = (VMMemRegion*)next();
+- // see if we can consolidate next committed region
+- if (next_reg != NULL && next_reg->is_committed_region() &&
+- next_reg->base() == committed_rgn->base() + committed_rgn->size()) {
+- committed_rgn->expand_region(next_reg->base(), next_reg->size());
+- // delete merged region
+- remove();
+- }
+- return true;
+- } else if (committed_rgn->base() > rec->addr()) {
+- // found the location, insert this committed region
+- return insert_record(rec);
+- }
+- committed_rgn = (VMMemRegion*)next();
+- }
+- return insert_record(rec);
+-}
+-
+-bool VMMemPointerIterator::remove_uncommitted_region(MemPointerRecord* rec) {
+- assert(rec->is_uncommit_record(), "sanity check");
+- VMMemRegion* cur;
+- cur = (VMMemRegion*)current();
+- assert(cur->is_reserved_region() && cur->contains_region(rec),
+- "Sanity check");
+- // thread's native stack is always marked as "committed", ignore
+- // the "commit" operation for creating stack guard pages
+- if (FLAGS_TO_MEMORY_TYPE(cur->flags()) == mtThreadStack &&
+- FLAGS_TO_MEMORY_TYPE(rec->flags()) != mtThreadStack) {
+- return true;
+- }
+-
+- cur = (VMMemRegion*)next();
+- while (cur != NULL && cur->is_committed_region()) {
+- // region already uncommitted, must be due to duplicated record
+- if (cur->addr() >= rec->addr() + rec->size()) {
+- break;
+- } else if (cur->contains_region(rec)) {
+- // uncommit whole region
+- if (cur->is_same_region(rec)) {
+- remove();
+- break;
+- } else if (rec->addr() == cur->addr() ||
+- rec->addr() + rec->size() == cur->addr() + cur->size()) {
+- // uncommitted from either end of current memory region.
+- cur->exclude_region(rec->addr(), rec->size());
+- break;
+- } else { // split the committed region and release the middle
+- address high_addr = cur->addr() + cur->size();
+- size_t sz = high_addr - rec->addr();
+- cur->exclude_region(rec->addr(), sz);
+- sz = high_addr - (rec->addr() + rec->size());
+- if (MemTracker::track_callsite()) {
+- MemPointerRecordEx tmp(rec->addr() + rec->size(), cur->flags(), sz,
+- ((VMMemRegionEx*)cur)->pc());
+- return insert_record_after(&tmp);
+- } else {
+- MemPointerRecord tmp(rec->addr() + rec->size(), cur->flags(), sz);
+- return insert_record_after(&tmp);
+- }
+- }
+- }
+- cur = (VMMemRegion*)next();
+- }
+-
+- // we may not find committed record due to duplicated records
+- return true;
+-}
+-
+-bool VMMemPointerIterator::remove_released_region(MemPointerRecord* rec) {
+- assert(rec->is_deallocation_record(), "Sanity check");
+- VMMemRegion* cur = (VMMemRegion*)current();
+- assert(cur->is_reserved_region() && cur->contains_region(rec),
+- "Sanity check");
+- if (rec->is_same_region(cur)) {
+-
+- // In snapshot, the virtual memory records are sorted in following orders:
+- // 1. virtual memory's base address
+- // 2. virtual memory reservation record, followed by commit records within this reservation.
+- // The commit records are also in base address order.
+- // When a reserved region is released, we want to remove the reservation record and all
+- // commit records following it.
+-#ifdef ASSERT
+- address low_addr = cur->addr();
+- address high_addr = low_addr + cur->size();
+-#endif
+- // remove virtual memory reservation record
+- remove();
+- // remove committed regions within above reservation
+- VMMemRegion* next_region = (VMMemRegion*)current();
+- while (next_region != NULL && next_region->is_committed_region()) {
+- assert(next_region->addr() >= low_addr &&
+- next_region->addr() + next_region->size() <= high_addr,
+- "Range check");
+- remove();
+- next_region = (VMMemRegion*)current();
+- }
+- } else if (rec->addr() == cur->addr() ||
+- rec->addr() + rec->size() == cur->addr() + cur->size()) {
+- // released region is at either end of this region
+- cur->exclude_region(rec->addr(), rec->size());
+- assert(check_reserved_region(), "Integrity check");
+- } else { // split the reserved region and release the middle
+- address high_addr = cur->addr() + cur->size();
+- size_t sz = high_addr - rec->addr();
+- cur->exclude_region(rec->addr(), sz);
+- sz = high_addr - rec->addr() - rec->size();
+- if (MemTracker::track_callsite()) {
+- MemPointerRecordEx tmp(rec->addr() + rec->size(), cur->flags(), sz,
+- ((VMMemRegionEx*)cur)->pc());
+- bool ret = insert_reserved_region(&tmp);
+- assert(!ret || check_reserved_region(), "Integrity check");
+- return ret;
+- } else {
+- MemPointerRecord tmp(rec->addr() + rec->size(), cur->flags(), sz);
+- bool ret = insert_reserved_region(&tmp);
+- assert(!ret || check_reserved_region(), "Integrity check");
+- return ret;
+- }
+- }
+- return true;
+-}
+-
+-bool VMMemPointerIterator::insert_reserved_region(MemPointerRecord* rec) {
+- // skip all 'commit' records associated with previous reserved region
+- VMMemRegion* p = (VMMemRegion*)next();
+- while (p != NULL && p->is_committed_region() &&
+- p->base() + p->size() < rec->addr()) {
+- p = (VMMemRegion*)next();
+- }
+- return insert_record(rec);
+-}
+-
+-bool VMMemPointerIterator::split_reserved_region(VMMemRegion* rgn, address new_rgn_addr, size_t new_rgn_size) {
+- assert(rgn->contains_region(new_rgn_addr, new_rgn_size), "Not fully contained");
+- address pc = (MemTracker::track_callsite() ? ((VMMemRegionEx*)rgn)->pc() : NULL);
+- if (rgn->base() == new_rgn_addr) { // new region is at the beginning of the region
+- size_t sz = rgn->size() - new_rgn_size;
+- // the original region becomes 'new' region
+- rgn->exclude_region(new_rgn_addr + new_rgn_size, sz);
+- // remaining becomes next region
+- MemPointerRecordEx next_rgn(new_rgn_addr + new_rgn_size, rgn->flags(), sz, pc);
+- return insert_reserved_region(&next_rgn);
+- } else if (rgn->base() + rgn->size() == new_rgn_addr + new_rgn_size) {
+- rgn->exclude_region(new_rgn_addr, new_rgn_size);
+- MemPointerRecordEx next_rgn(new_rgn_addr, rgn->flags(), new_rgn_size, pc);
+- return insert_reserved_region(&next_rgn);
+- } else {
+- // the orginal region will be split into three
+- address rgn_high_addr = rgn->base() + rgn->size();
+- // first region
+- rgn->exclude_region(new_rgn_addr, (rgn_high_addr - new_rgn_addr));
+- // the second region is the new region
+- MemPointerRecordEx new_rgn(new_rgn_addr, rgn->flags(), new_rgn_size, pc);
+- if (!insert_reserved_region(&new_rgn)) return false;
+- // the remaining region
+- MemPointerRecordEx rem_rgn(new_rgn_addr + new_rgn_size, rgn->flags(),
+- rgn_high_addr - (new_rgn_addr + new_rgn_size), pc);
+- return insert_reserved_region(&rem_rgn);
+- }
+-}
+-
+-static int sort_in_seq_order(const void* p1, const void* p2) {
+- assert(p1 != NULL && p2 != NULL, "Sanity check");
+- const MemPointerRecord* mp1 = (MemPointerRecord*)p1;
+- const MemPointerRecord* mp2 = (MemPointerRecord*)p2;
+- return (mp1->seq() - mp2->seq());
+-}
+-
+-bool StagingArea::init() {
+- if (MemTracker::track_callsite()) {
+- _malloc_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecordEx>();
+- _vm_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecordEx>();
+- } else {
+- _malloc_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecord>();
+- _vm_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecord>();
+- }
+-
+- if (_malloc_data != NULL && _vm_data != NULL &&
+- !_malloc_data->out_of_memory() &&
+- !_vm_data->out_of_memory()) {
+- return true;
+- } else {
+- if (_malloc_data != NULL) delete _malloc_data;
+- if (_vm_data != NULL) delete _vm_data;
+- _malloc_data = NULL;
+- _vm_data = NULL;
+- return false;
+- }
+-}
+-
+-
+-VMRecordIterator StagingArea::virtual_memory_record_walker() {
+- MemPointerArray* arr = vm_data();
+- // sort into seq number order
+- arr->sort((FN_SORT)sort_in_seq_order);
+- return VMRecordIterator(arr);
+-}
+-
+-
+-MemSnapshot::MemSnapshot() {
+- if (MemTracker::track_callsite()) {
+- _alloc_ptrs = new (std::nothrow) MemPointerArrayImpl<MemPointerRecordEx>();
+- _vm_ptrs = new (std::nothrow)MemPointerArrayImpl<VMMemRegionEx>(64, true);
+- } else {
+- _alloc_ptrs = new (std::nothrow) MemPointerArrayImpl<MemPointerRecord>();
+- _vm_ptrs = new (std::nothrow)MemPointerArrayImpl<VMMemRegion>(64, true);
+- }
+-
+- _staging_area.init();
+- _lock = new (std::nothrow) Mutex(Monitor::max_nonleaf - 1, "memSnapshotLock");
+- NOT_PRODUCT(_untracked_count = 0;)
+- _number_of_classes = 0;
+-}
+-
+-MemSnapshot::~MemSnapshot() {
+- assert(MemTracker::shutdown_in_progress(), "native memory tracking still on");
+- {
+- MutexLockerEx locker(_lock);
+- if (_alloc_ptrs != NULL) {
+- delete _alloc_ptrs;
+- _alloc_ptrs = NULL;
+- }
+-
+- if (_vm_ptrs != NULL) {
+- delete _vm_ptrs;
+- _vm_ptrs = NULL;
+- }
+- }
+-
+- if (_lock != NULL) {
+- delete _lock;
+- _lock = NULL;
+- }
+-}
+-
+-
+-void MemSnapshot::copy_seq_pointer(MemPointerRecord* dest, const MemPointerRecord* src) {
+- assert(dest != NULL && src != NULL, "Just check");
+- assert(dest->addr() == src->addr(), "Just check");
+- assert(dest->seq() > 0 && src->seq() > 0, "not sequenced");
+-
+- if (MemTracker::track_callsite()) {
+- *(SeqMemPointerRecordEx*)dest = *(SeqMemPointerRecordEx*)src;
+- } else {
+- *(SeqMemPointerRecord*)dest = *(SeqMemPointerRecord*)src;
+- }
+-}
+-
+-void MemSnapshot::assign_pointer(MemPointerRecord*dest, const MemPointerRecord* src) {
+- assert(src != NULL && dest != NULL, "Just check");
+- assert(dest->seq() == 0 && src->seq() >0, "cast away sequence");
+-
+- if (MemTracker::track_callsite()) {
+- *(MemPointerRecordEx*)dest = *(MemPointerRecordEx*)src;
+- } else {
+- *(MemPointerRecord*)dest = *(MemPointerRecord*)src;
+- }
+-}
+-
+-// merge a recorder to the staging area
+-bool MemSnapshot::merge(MemRecorder* rec) {
+- assert(rec != NULL && !rec->out_of_memory(), "Just check");
+-
+- SequencedRecordIterator itr(rec->pointer_itr());
+-
+- MutexLockerEx lock(_lock, true);
+- MemPointerIterator malloc_staging_itr(_staging_area.malloc_data());
+- MemPointerRecord* incoming_rec = (MemPointerRecord*) itr.current();
+- MemPointerRecord* matched_rec;
+-
+- while (incoming_rec != NULL) {
+- if (incoming_rec->is_vm_pointer()) {
+- // we don't do anything with virtual memory records during merge
+- if (!_staging_area.vm_data()->append(incoming_rec)) {
+- return false;
+- }
+- } else {
+- // locate matched record and/or also position the iterator to proper
+- // location for this incoming record.
+- matched_rec = (MemPointerRecord*)malloc_staging_itr.locate(incoming_rec->addr());
+- // we have not seen this memory block in this generation,
+- // so just add to staging area
+- if (matched_rec == NULL) {
+- if (!malloc_staging_itr.insert(incoming_rec)) {
+- return false;
+- }
+- } else if (incoming_rec->addr() == matched_rec->addr()) {
+- // whoever has higher sequence number wins
+- if (incoming_rec->seq() > matched_rec->seq()) {
+- copy_seq_pointer(matched_rec, incoming_rec);
+- }
+- } else if (incoming_rec->addr() < matched_rec->addr()) {
+- if (!malloc_staging_itr.insert(incoming_rec)) {
+- return false;
+- }
+- } else {
+- ShouldNotReachHere();
+- }
+- }
+- incoming_rec = (MemPointerRecord*)itr.next();
+- }
+- NOT_PRODUCT(void check_staging_data();)
+- return true;
+-}
+-
+-
+-// promote data to next generation
+-bool MemSnapshot::promote(int number_of_classes) {
+- assert(_alloc_ptrs != NULL && _vm_ptrs != NULL, "Just check");
+- assert(_staging_area.malloc_data() != NULL && _staging_area.vm_data() != NULL,
+- "Just check");
+- MutexLockerEx lock(_lock, true);
+-
+- MallocRecordIterator malloc_itr = _staging_area.malloc_record_walker();
+- bool promoted = false;
+- if (promote_malloc_records(&malloc_itr)) {
+- VMRecordIterator vm_itr = _staging_area.virtual_memory_record_walker();
+- if (promote_virtual_memory_records(&vm_itr)) {
+- promoted = true;
+- }
+- }
+-
+- NOT_PRODUCT(check_malloc_pointers();)
+- _staging_area.clear();
+- _number_of_classes = number_of_classes;
+- return promoted;
+-}
+-
+-bool MemSnapshot::promote_malloc_records(MemPointerArrayIterator* itr) {
+- MemPointerIterator malloc_snapshot_itr(_alloc_ptrs);
+- MemPointerRecord* new_rec = (MemPointerRecord*)itr->current();
+- MemPointerRecord* matched_rec;
+- while (new_rec != NULL) {
+- matched_rec = (MemPointerRecord*)malloc_snapshot_itr.locate(new_rec->addr());
+- // found matched memory block
+- if (matched_rec != NULL && new_rec->addr() == matched_rec->addr()) {
+- // snapshot already contains 'live' records
+- assert(matched_rec->is_allocation_record() || matched_rec->is_arena_memory_record(),
+- "Sanity check");
+- // update block states
+- if (new_rec->is_allocation_record()) {
+- assign_pointer(matched_rec, new_rec);
+- } else if (new_rec->is_arena_memory_record()) {
+- if (new_rec->size() == 0) {
+- // remove size record once size drops to 0
+- malloc_snapshot_itr.remove();
+- } else {
+- assign_pointer(matched_rec, new_rec);
+- }
+- } else {
+- // a deallocation record
+- assert(new_rec->is_deallocation_record(), "Sanity check");
+- // an arena record can be followed by a size record, we need to remove both
+- if (matched_rec->is_arena_record()) {
+- MemPointerRecord* next = (MemPointerRecord*)malloc_snapshot_itr.peek_next();
+- if (next != NULL && next->is_arena_memory_record() &&
+- next->is_memory_record_of_arena(matched_rec)) {
+- malloc_snapshot_itr.remove();
+- }
+- }
+- // the memory is deallocated, remove related record(s)
+- malloc_snapshot_itr.remove();
+- }
+- } else {
+- // don't insert size 0 record
+- if (new_rec->is_arena_memory_record() && new_rec->size() == 0) {
+- new_rec = NULL;
+- }
+-
+- if (new_rec != NULL) {
+- if (new_rec->is_allocation_record() || new_rec->is_arena_memory_record()) {
+- if (matched_rec != NULL && new_rec->addr() > matched_rec->addr()) {
+- if (!malloc_snapshot_itr.insert_after(new_rec)) {
+- return false;
+- }
+- } else {
+- if (!malloc_snapshot_itr.insert(new_rec)) {
+- return false;
+- }
+- }
+- }
+-#ifndef PRODUCT
+- else if (!has_allocation_record(new_rec->addr())) {
+- // NMT can not track some startup memory, which is allocated before NMT is on
+- _untracked_count ++;
+- }
+-#endif
+- }
+- }
+- new_rec = (MemPointerRecord*)itr->next();
+- }
+- return true;
+-}
+-
+-bool MemSnapshot::promote_virtual_memory_records(MemPointerArrayIterator* itr) {
+- VMMemPointerIterator vm_snapshot_itr(_vm_ptrs);
+- MemPointerRecord* new_rec = (MemPointerRecord*)itr->current();
+- VMMemRegion* reserved_rec;
+- while (new_rec != NULL) {
+- assert(new_rec->is_vm_pointer(), "Sanity check");
+-
+- // locate a reserved region that contains the specified address, or
+- // the nearest reserved region has base address just above the specified
+- // address
+- reserved_rec = (VMMemRegion*)vm_snapshot_itr.locate(new_rec->addr());
+- if (reserved_rec != NULL && reserved_rec->contains_region(new_rec)) {
+- // snapshot can only have 'live' records
+- assert(reserved_rec->is_reserved_region(), "Sanity check");
+- if (new_rec->is_allocation_record()) {
+- if (!reserved_rec->is_same_region(new_rec)) {
+- // only deal with split a bigger reserved region into smaller regions.
+- // So far, CDS is the only use case.
+- if (!vm_snapshot_itr.split_reserved_region(reserved_rec, new_rec->addr(), new_rec->size())) {
+- return false;
+- }
+- }
+- } else if (new_rec->is_uncommit_record()) {
+- if (!vm_snapshot_itr.remove_uncommitted_region(new_rec)) {
+- return false;
+- }
+- } else if (new_rec->is_commit_record()) {
+- // insert or expand existing committed region to cover this
+- // newly committed region
+- if (!vm_snapshot_itr.add_committed_region(new_rec)) {
+- return false;
+- }
+- } else if (new_rec->is_deallocation_record()) {
+- // release part or all memory region
+- if (!vm_snapshot_itr.remove_released_region(new_rec)) {
+- return false;
+- }
+- } else if (new_rec->is_type_tagging_record()) {
+- // tag this reserved virtual memory range to a memory type. Can not re-tag a memory range
+- // to different type.
+- assert(FLAGS_TO_MEMORY_TYPE(reserved_rec->flags()) == mtNone ||
+- FLAGS_TO_MEMORY_TYPE(reserved_rec->flags()) == FLAGS_TO_MEMORY_TYPE(new_rec->flags()),
+- "Sanity check");
+- reserved_rec->tag(new_rec->flags());
+- } else {
+- ShouldNotReachHere();
+- }
+- } else {
+- /*
+- * The assertion failure indicates mis-matched virtual memory records. The likely
+- * scenario is, that some virtual memory operations are not going through os::xxxx_memory()
+- * api, which have to be tracked manually. (perfMemory is an example).
+- */
+- assert(new_rec->is_allocation_record(), "Sanity check");
+- if (!vm_snapshot_itr.add_reserved_region(new_rec)) {
+- return false;
+- }
+- }
+- new_rec = (MemPointerRecord*)itr->next();
+- }
+- return true;
+-}
+-
+-#ifndef PRODUCT
+-void MemSnapshot::print_snapshot_stats(outputStream* st) {
+- st->print_cr("Snapshot:");
+- st->print_cr("\tMalloced: %d/%d [%5.2f%%] %dKB", _alloc_ptrs->length(), _alloc_ptrs->capacity(),
+- (100.0 * (float)_alloc_ptrs->length()) / (float)_alloc_ptrs->capacity(), _alloc_ptrs->instance_size()/K);
+-
+- st->print_cr("\tVM: %d/%d [%5.2f%%] %dKB", _vm_ptrs->length(), _vm_ptrs->capacity(),
+- (100.0 * (float)_vm_ptrs->length()) / (float)_vm_ptrs->capacity(), _vm_ptrs->instance_size()/K);
+-
+- st->print_cr("\tMalloc staging Area: %d/%d [%5.2f%%] %dKB", _staging_area.malloc_data()->length(),
+- _staging_area.malloc_data()->capacity(),
+- (100.0 * (float)_staging_area.malloc_data()->length()) / (float)_staging_area.malloc_data()->capacity(),
+- _staging_area.malloc_data()->instance_size()/K);
+-
+- st->print_cr("\tVirtual memory staging Area: %d/%d [%5.2f%%] %dKB", _staging_area.vm_data()->length(),
+- _staging_area.vm_data()->capacity(),
+- (100.0 * (float)_staging_area.vm_data()->length()) / (float)_staging_area.vm_data()->capacity(),
+- _staging_area.vm_data()->instance_size()/K);
+-
+- st->print_cr("\tUntracked allocation: %d", _untracked_count);
+-}
+-
+-void MemSnapshot::check_malloc_pointers() {
+- MemPointerArrayIteratorImpl mItr(_alloc_ptrs);
+- MemPointerRecord* p = (MemPointerRecord*)mItr.current();
+- MemPointerRecord* prev = NULL;
+- while (p != NULL) {
+- if (prev != NULL) {
+- assert(p->addr() >= prev->addr(), "sorting order");
+- }
+- prev = p;
+- p = (MemPointerRecord*)mItr.next();
+- }
+-}
+-
+-bool MemSnapshot::has_allocation_record(address addr) {
+- MemPointerArrayIteratorImpl itr(_staging_area.malloc_data());
+- MemPointerRecord* cur = (MemPointerRecord*)itr.current();
+- while (cur != NULL) {
+- if (cur->addr() == addr && cur->is_allocation_record()) {
+- return true;
+- }
+- cur = (MemPointerRecord*)itr.next();
+- }
+- return false;
+-}
+-#endif // PRODUCT
+-
+-#ifdef ASSERT
+-void MemSnapshot::check_staging_data() {
+- MemPointerArrayIteratorImpl itr(_staging_area.malloc_data());
+- MemPointerRecord* cur = (MemPointerRecord*)itr.current();
+- MemPointerRecord* next = (MemPointerRecord*)itr.next();
+- while (next != NULL) {
+- assert((next->addr() > cur->addr()) ||
+- ((next->flags() & MemPointerRecord::tag_masks) >
+- (cur->flags() & MemPointerRecord::tag_masks)),
+- "sorting order");
+- cur = next;
+- next = (MemPointerRecord*)itr.next();
+- }
+-
+- MemPointerArrayIteratorImpl vm_itr(_staging_area.vm_data());
+- cur = (MemPointerRecord*)vm_itr.current();
+- while (cur != NULL) {
+- assert(cur->is_vm_pointer(), "virtual memory pointer only");
+- cur = (MemPointerRecord*)vm_itr.next();
+- }
+-}
+-
+-void MemSnapshot::dump_all_vm_pointers() {
+- MemPointerArrayIteratorImpl itr(_vm_ptrs);
+- VMMemRegion* ptr = (VMMemRegion*)itr.current();
+- tty->print_cr("dump virtual memory pointers:");
+- while (ptr != NULL) {
+- if (ptr->is_committed_region()) {
+- tty->print("\t");
+- }
+- tty->print("[" PTR_FORMAT " - " PTR_FORMAT "] [%x]", ptr->addr(),
+- (ptr->addr() + ptr->size()), ptr->flags());
+-
+- if (MemTracker::track_callsite()) {
+- VMMemRegionEx* ex = (VMMemRegionEx*)ptr;
+- if (ex->pc() != NULL) {
+- char buf[1024];
+- if (os::dll_address_to_function_name(ex->pc(), buf, sizeof(buf), NULL)) {
+- tty->print_cr("\t%s", buf);
+- } else {
+- tty->cr();
+- }
+- }
+- }
+-
+- ptr = (VMMemRegion*)itr.next();
+- }
+- tty->flush();
+-}
+-#endif // ASSERT
+-
+--- ./hotspot/src/share/vm/services/memSnapshot.hpp Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,408 +0,0 @@
+-/*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- *
+- */
+-
+-#ifndef SHARE_VM_SERVICES_MEM_SNAPSHOT_HPP
+-#define SHARE_VM_SERVICES_MEM_SNAPSHOT_HPP
+-
+-#include "memory/allocation.hpp"
+-#include "runtime/mutex.hpp"
+-#include "runtime/mutexLocker.hpp"
+-#include "services/memBaseline.hpp"
+-#include "services/memPtrArray.hpp"
+-
+-// Snapshot pointer array iterator
+-
+-// The pointer array contains malloc-ed pointers
+-class MemPointerIterator : public MemPointerArrayIteratorImpl {
+- public:
+- MemPointerIterator(MemPointerArray* arr):
+- MemPointerArrayIteratorImpl(arr) {
+- assert(arr != NULL, "null array");
+- }
+-
+-#ifdef ASSERT
+- virtual bool is_dup_pointer(const MemPointer* ptr1,
+- const MemPointer* ptr2) const {
+- MemPointerRecord* p1 = (MemPointerRecord*)ptr1;
+- MemPointerRecord* p2 = (MemPointerRecord*)ptr2;
+-
+- if (p1->addr() != p2->addr()) return false;
+- if ((p1->flags() & MemPointerRecord::tag_masks) !=
+- (p2->flags() & MemPointerRecord::tag_masks)) {
+- return false;
+- }
+- // we do see multiple commit/uncommit on the same memory, it is ok
+- return (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_alloc ||
+- (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_release;
+- }
+-
+- virtual bool insert(MemPointer* ptr) {
+- if (_pos > 0) {
+- MemPointer* p1 = (MemPointer*)ptr;
+- MemPointer* p2 = (MemPointer*)_array->at(_pos - 1);
+- assert(!is_dup_pointer(p1, p2),
+- err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
+- }
+- if (_pos < _array->length() -1) {
+- MemPointer* p1 = (MemPointer*)ptr;
+- MemPointer* p2 = (MemPointer*)_array->at(_pos + 1);
+- assert(!is_dup_pointer(p1, p2),
+- err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
+- }
+- return _array->insert_at(ptr, _pos);
+- }
+-
+- virtual bool insert_after(MemPointer* ptr) {
+- if (_pos > 0) {
+- MemPointer* p1 = (MemPointer*)ptr;
+- MemPointer* p2 = (MemPointer*)_array->at(_pos - 1);
+- assert(!is_dup_pointer(p1, p2),
+- err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
+- }
+- if (_pos < _array->length() - 1) {
+- MemPointer* p1 = (MemPointer*)ptr;
+- MemPointer* p2 = (MemPointer*)_array->at(_pos + 1);
+-
+- assert(!is_dup_pointer(p1, p2),
+- err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
+- }
+- if (_array->insert_at(ptr, _pos + 1)) {
+- _pos ++;
+- return true;
+- }
+- return false;
+- }
+-#endif
+-
+- virtual MemPointer* locate(address addr) {
+- MemPointer* cur = current();
+- while (cur != NULL && cur->addr() < addr) {
+- cur = next();
+- }
+- return cur;
+- }
+-};
+-
+-class VMMemPointerIterator : public MemPointerIterator {
+- public:
+- VMMemPointerIterator(MemPointerArray* arr):
+- MemPointerIterator(arr) {
+- }
+-
+- // locate an existing reserved memory region that contains specified address,
+- // or the reserved region just above this address, where the incoming
+- // reserved region should be inserted.
+- virtual MemPointer* locate(address addr) {
+- reset();
+- VMMemRegion* reg = (VMMemRegion*)current();
+- while (reg != NULL) {
+- if (reg->is_reserved_region()) {
+- if (reg->contains_address(addr) || addr < reg->base()) {
+- return reg;
+- }
+- }
+- reg = (VMMemRegion*)next();
+- }
+- return NULL;
+- }
+-
+- // following methods update virtual memory in the context
+- // of 'current' position, which is properly positioned by
+- // callers via locate method.
+- bool add_reserved_region(MemPointerRecord* rec);
+- bool add_committed_region(MemPointerRecord* rec);
+- bool remove_uncommitted_region(MemPointerRecord* rec);
+- bool remove_released_region(MemPointerRecord* rec);
+-
+- // split a reserved region to create a new memory region with specified base and size
+- bool split_reserved_region(VMMemRegion* rgn, address new_rgn_addr, size_t new_rgn_size);
+- private:
+- bool insert_record(MemPointerRecord* rec);
+- bool insert_record_after(MemPointerRecord* rec);
+-
+- bool insert_reserved_region(MemPointerRecord* rec);
+-
+- // reset current position
+- inline void reset() { _pos = 0; }
+-#ifdef ASSERT
+- // check integrity of records on current reserved memory region.
+- bool check_reserved_region() {
+- VMMemRegion* reserved_region = (VMMemRegion*)current();
+- assert(reserved_region != NULL && reserved_region->is_reserved_region(),
+- "Sanity check");
+- // all committed regions that follow current reserved region, should all
+- // belong to the reserved region.
+- VMMemRegion* next_region = (VMMemRegion*)next();
+- for (; next_region != NULL && next_region->is_committed_region();
+- next_region = (VMMemRegion*)next() ) {
+- if(!reserved_region->contains_region(next_region)) {
+- return false;
+- }
+- }
+- return true;
+- }
+-
+- virtual bool is_dup_pointer(const MemPointer* ptr1,
+- const MemPointer* ptr2) const {
+- VMMemRegion* p1 = (VMMemRegion*)ptr1;
+- VMMemRegion* p2 = (VMMemRegion*)ptr2;
+-
+- if (p1->addr() != p2->addr()) return false;
+- if ((p1->flags() & MemPointerRecord::tag_masks) !=
+- (p2->flags() & MemPointerRecord::tag_masks)) {
+- return false;
+- }
+- // we do see multiple commit/uncommit on the same memory, it is ok
+- return (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_alloc ||
+- (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_release;
+- }
+-#endif
+-};
+-
+-class MallocRecordIterator : public MemPointerArrayIterator {
+- private:
+- MemPointerArrayIteratorImpl _itr;
+-
+-
+-
+- public:
+- MallocRecordIterator(MemPointerArray* arr) : _itr(arr) {
+- }
+-
+- virtual MemPointer* current() const {
+-#ifdef ASSERT
+- MemPointer* cur_rec = _itr.current();
+- if (cur_rec != NULL) {
+- MemPointer* prev_rec = _itr.peek_prev();
+- MemPointer* next_rec = _itr.peek_next();
+- assert(prev_rec == NULL || prev_rec->addr() < cur_rec->addr(), "Sorting order");
+- assert(next_rec == NULL || next_rec->addr() > cur_rec->addr(), "Sorting order");
+- }
+-#endif
+- return _itr.current();
+- }
+- virtual MemPointer* next() {
+- MemPointerRecord* next_rec = (MemPointerRecord*)_itr.next();
+- // arena memory record is a special case, which we have to compare
+- // sequence number against its associated arena record.
+- if (next_rec != NULL && next_rec->is_arena_memory_record()) {
+- MemPointerRecord* prev_rec = (MemPointerRecord*)_itr.peek_prev();
+- // if there is an associated arena record, it has to be previous
+- // record because of sorting order (by address) - NMT generates a pseudo address
+- // for arena's size record by offsetting arena's address, that guarantees
+- // the order of arena record and it's size record.
+- if (prev_rec != NULL && prev_rec->is_arena_record() &&
+- next_rec->is_memory_record_of_arena(prev_rec)) {
+- if (prev_rec->seq() > next_rec->seq()) {
+- // Skip this arena memory record
+- // Two scenarios:
+- // - if the arena record is an allocation record, this early
+- // size record must be leftover by previous arena,
+- // and the last size record should have size = 0.
+- // - if the arena record is a deallocation record, this
+- // size record should be its cleanup record, which should
+- // also have size = 0. In other world, arena alway reset
+- // its size before gone (see Arena's destructor)
+- assert(next_rec->size() == 0, "size not reset");
+- return _itr.next();
+- } else {
+- assert(prev_rec->is_allocation_record(),
+- "Arena size record ahead of allocation record");
+- }
+- }
+- }
+- return next_rec;
+- }
+-
+- MemPointer* peek_next() const { ShouldNotReachHere(); return NULL; }
+- MemPointer* peek_prev() const { ShouldNotReachHere(); return NULL; }
+- void remove() { ShouldNotReachHere(); }
+- bool insert(MemPointer* ptr) { ShouldNotReachHere(); return false; }
+- bool insert_after(MemPointer* ptr) { ShouldNotReachHere(); return false; }
+-};
+-
+-// collapse duplicated records. Eliminating duplicated records here, is much
+-// cheaper than during promotion phase. However, it does have limitation - it
+-// can only eliminate duplicated records within the generation, there are
+-// still chances seeing duplicated records during promotion.
+-// We want to use the record with higher sequence number, because it has
+-// more accurate callsite pc.
+-class VMRecordIterator : public MemPointerArrayIterator {
+- private:
+- MemPointerArrayIteratorImpl _itr;
+-
+- public:
+- VMRecordIterator(MemPointerArray* arr) : _itr(arr) {
+- MemPointerRecord* cur = (MemPointerRecord*)_itr.current();
+- MemPointerRecord* next = (MemPointerRecord*)_itr.peek_next();
+- while (next != NULL) {
+- assert(cur != NULL, "Sanity check");
+- assert(((SeqMemPointerRecord*)next)->seq() > ((SeqMemPointerRecord*)cur)->seq(),
+- "pre-sort order");
+-
+- if (is_duplicated_record(cur, next)) {
+- _itr.next();
+- next = (MemPointerRecord*)_itr.peek_next();
+- } else {
+- break;
+- }
+- }
+- }
+-
+- virtual MemPointer* current() const {
+- return _itr.current();
+- }
+-
+- // get next record, but skip the duplicated records
+- virtual MemPointer* next() {
+- MemPointerRecord* cur = (MemPointerRecord*)_itr.next();
+- MemPointerRecord* next = (MemPointerRecord*)_itr.peek_next();
+- while (next != NULL) {
+- assert(cur != NULL, "Sanity check");
+- assert(((SeqMemPointerRecord*)next)->seq() > ((SeqMemPointerRecord*)cur)->seq(),
+- "pre-sort order");
+-
+- if (is_duplicated_record(cur, next)) {
+- _itr.next();
+- cur = next;
+- next = (MemPointerRecord*)_itr.peek_next();
+- } else {
+- break;
+- }
+- }
+- return cur;
+- }
+-
+- MemPointer* peek_next() const { ShouldNotReachHere(); return NULL; }
+- MemPointer* peek_prev() const { ShouldNotReachHere(); return NULL; }
+- void remove() { ShouldNotReachHere(); }
+- bool insert(MemPointer* ptr) { ShouldNotReachHere(); return false; }
+- bool insert_after(MemPointer* ptr) { ShouldNotReachHere(); return false; }
+-
+- private:
+- bool is_duplicated_record(MemPointerRecord* p1, MemPointerRecord* p2) const {
+- bool ret = (p1->addr() == p2->addr() && p1->size() == p2->size() && p1->flags() == p2->flags());
+- assert(!(ret && FLAGS_TO_MEMORY_TYPE(p1->flags()) == mtThreadStack), "dup on stack record");
+- return ret;
+- }
+-};
+-
+-class StagingArea VALUE_OBJ_CLASS_SPEC {
+- private:
+- MemPointerArray* _malloc_data;
+- MemPointerArray* _vm_data;
+-
+- public:
+- StagingArea() : _malloc_data(NULL), _vm_data(NULL) {
+- init();
+- }
+-
+- ~StagingArea() {
+- if (_malloc_data != NULL) delete _malloc_data;
+- if (_vm_data != NULL) delete _vm_data;
+- }
+-
+- MallocRecordIterator malloc_record_walker() {
+- return MallocRecordIterator(malloc_data());
+- }
+-
+- VMRecordIterator virtual_memory_record_walker();
+-
+- bool init();
+- void clear() {
+- assert(_malloc_data != NULL && _vm_data != NULL, "Just check");
+- _malloc_data->shrink();
+- _malloc_data->clear();
+- _vm_data->clear();
+- }
+-
+- inline MemPointerArray* malloc_data() { return _malloc_data; }
+- inline MemPointerArray* vm_data() { return _vm_data; }
+-};
+-
+-class MemBaseline;
+-class MemSnapshot : public CHeapObj<mtNMT> {
+- private:
+- // the following two arrays contain records of all known lived memory blocks
+- // live malloc-ed memory pointers
+- MemPointerArray* _alloc_ptrs;
+- // live virtual memory pointers
+- MemPointerArray* _vm_ptrs;
+-
+- StagingArea _staging_area;
+-
+- // the lock to protect this snapshot
+- Monitor* _lock;
+-
+- // the number of instance classes
+- int _number_of_classes;
+-
+- NOT_PRODUCT(size_t _untracked_count;)
+- friend class MemBaseline;
+-
+- public:
+- MemSnapshot();
+- virtual ~MemSnapshot();
+-
+- // if we are running out of native memory
+- bool out_of_memory() {
+- return (_alloc_ptrs == NULL ||
+- _staging_area.malloc_data() == NULL ||
+- _staging_area.vm_data() == NULL ||
+- _vm_ptrs == NULL || _lock == NULL ||
+- _alloc_ptrs->out_of_memory() ||
+- _vm_ptrs->out_of_memory());
+- }
+-
+- // merge a per-thread memory recorder into staging area
+- bool merge(MemRecorder* rec);
+- // promote staged data to snapshot
+- bool promote(int number_of_classes);
+-
+- int number_of_classes() const { return _number_of_classes; }
+-
+- void wait(long timeout) {
+- assert(_lock != NULL, "Just check");
+- MonitorLockerEx locker(_lock);
+- locker.wait(true, timeout);
+- }
+-
+- NOT_PRODUCT(void print_snapshot_stats(outputStream* st);)
+- NOT_PRODUCT(void check_staging_data();)
+- NOT_PRODUCT(void check_malloc_pointers();)
+- NOT_PRODUCT(bool has_allocation_record(address addr);)
+- // dump all virtual memory pointers in snapshot
+- DEBUG_ONLY( void dump_all_vm_pointers();)
+-
+- private:
+- // copy sequenced pointer from src to dest
+- void copy_seq_pointer(MemPointerRecord* dest, const MemPointerRecord* src);
+- // assign a sequenced pointer to non-sequenced pointer
+- void assign_pointer(MemPointerRecord*dest, const MemPointerRecord* src);
+-
+- bool promote_malloc_records(MemPointerArrayIterator* itr);
+- bool promote_virtual_memory_records(MemPointerArrayIterator* itr);
+-};
+-
+-#endif // SHARE_VM_SERVICES_MEM_SNAPSHOT_HPP
+--- ./hotspot/src/share/vm/services/memTrackWorker.cpp Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,212 +0,0 @@
+-/*
+- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- *
+- */
+-
+-#include "precompiled.hpp"
+-#include "runtime/threadCritical.hpp"
+-#include "services/memTracker.hpp"
+-#include "services/memTrackWorker.hpp"
+-#include "utilities/decoder.hpp"
+-#include "utilities/vmError.hpp"
+-
+-
+-void GenerationData::reset() {
+- _number_of_classes = 0;
+- while (_recorder_list != NULL) {
+- MemRecorder* tmp = _recorder_list;
+- _recorder_list = _recorder_list->next();
+- MemTracker::release_thread_recorder(tmp);
+- }
+-}
+-
+-MemTrackWorker::MemTrackWorker(MemSnapshot* snapshot): _snapshot(snapshot) {
+- // create thread uses cgc thread type for now. We should revisit
+- // the option, or create new thread type.
+- _has_error = !os::create_thread(this, os::cgc_thread);
+- set_name("MemTrackWorker");
+-
+- // initial generation circuit buffer
+- if (!has_error()) {
+- _head = _tail = 0;
+- for(int index = 0; index < MAX_GENERATIONS; index ++) {
+- ::new ((void*)&_gen[index]) GenerationData();
+- }
+- }
+- NOT_PRODUCT(_sync_point_count = 0;)
+- NOT_PRODUCT(_merge_count = 0;)
+- NOT_PRODUCT(_last_gen_in_use = 0;)
+-}
+-
+-MemTrackWorker::~MemTrackWorker() {
+- for (int index = 0; index < MAX_GENERATIONS; index ++) {
+- _gen[index].reset();
+- }
+-}
+-
+-void* MemTrackWorker::operator new(size_t size) throw() {
+- assert(false, "use nothrow version");
+- return NULL;
+-}
+-
+-void* MemTrackWorker::operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() {
+- return allocate(size, false, mtNMT);
+-}
+-
+-void MemTrackWorker::start() {
+- os::start_thread(this);
+-}
+-
+-/*
+- * Native memory tracking worker thread loop:
+- * 1. merge one generation of memory recorders to staging area
+- * 2. promote staging data to memory snapshot
+- *
+- * This thread can run through safepoint.
+- */
+-
+-void MemTrackWorker::run() {
+- assert(MemTracker::is_on(), "native memory tracking is off");
+- this->initialize_thread_local_storage();
+- this->record_stack_base_and_size();
+- assert(_snapshot != NULL, "Worker should not be started");
+- MemRecorder* rec;
+- unsigned long processing_generation = 0;
+- bool worker_idle = false;
+-
+- while (!MemTracker::shutdown_in_progress()) {
+- NOT_PRODUCT(_last_gen_in_use = generations_in_use();)
+- {
+- // take a recorder from earliest generation in buffer
+- ThreadCritical tc;
+- rec = _gen[_head].next_recorder();
+- }
+- if (rec != NULL) {
+- if (rec->get_generation() != processing_generation || worker_idle) {
+- processing_generation = rec->get_generation();
+- worker_idle = false;
+- MemTracker::set_current_processing_generation(processing_generation);
+- }
+-
+- // merge the recorder into staging area
+- if (!_snapshot->merge(rec)) {
+- MemTracker::shutdown(MemTracker::NMT_out_of_memory);
+- } else {
+- NOT_PRODUCT(_merge_count ++;)
+- }
+- MemTracker::release_thread_recorder(rec);
+- } else {
+- // no more recorder to merge, promote staging area
+- // to snapshot
+- if (_head != _tail) {
+- long number_of_classes;
+- {
+- ThreadCritical tc;
+- if (_gen[_head].has_more_recorder() || _head == _tail) {
+- continue;
+- }
+- number_of_classes = _gen[_head].number_of_classes();
+- _gen[_head].reset();
+-
+- // done with this generation, increment _head pointer
+- _head = (_head + 1) % MAX_GENERATIONS;
+- }
+- // promote this generation data to snapshot
+- if (!_snapshot->promote(number_of_classes)) {
+- // failed to promote, means out of memory
+- MemTracker::shutdown(MemTracker::NMT_out_of_memory);
+- }
+- } else {
+- // worker thread is idle
+- worker_idle = true;
+- MemTracker::report_worker_idle();
+- _snapshot->wait(1000);
+- ThreadCritical tc;
+- // check if more data arrived
+- if (!_gen[_head].has_more_recorder()) {
+- _gen[_head].add_recorders(MemTracker::get_pending_recorders());
+- }
+- }
+- }
+- }
+- assert(MemTracker::shutdown_in_progress(), "just check");
+-
+- // transits to final shutdown
+- MemTracker::final_shutdown();
+-}
+-
+-// at synchronization point, where 'safepoint visible' Java threads are blocked
+-// at a safepoint, and the rest of threads are blocked on ThreadCritical lock.
+-// The caller MemTracker::sync() already takes ThreadCritical before calling this
+-// method.
+-//
+-// Following tasks are performed:
+-// 1. add all recorders in pending queue to current generation
+-// 2. increase generation
+-
+-void MemTrackWorker::at_sync_point(MemRecorder* rec, int number_of_classes) {
+- NOT_PRODUCT(_sync_point_count ++;)
+- assert(count_recorder(rec) <= MemRecorder::_instance_count,
+- "pending queue has infinite loop");
+-
+- bool out_of_generation_buffer = false;
+- // check shutdown state inside ThreadCritical
+- if (MemTracker::shutdown_in_progress()) return;
+-
+- _gen[_tail].set_number_of_classes(number_of_classes);
+- // append the recorders to the end of the generation
+- _gen[_tail].add_recorders(rec);
+- assert(count_recorder(_gen[_tail].peek()) <= MemRecorder::_instance_count,
+- "after add to current generation has infinite loop");
+- // we have collected all recorders for this generation. If there is data,
+- // we need to increment _tail to start a new generation.
+- if (_gen[_tail].has_more_recorder() || _head == _tail) {
+- _tail = (_tail + 1) % MAX_GENERATIONS;
+- out_of_generation_buffer = (_tail == _head);
+- }
+-
+- if (out_of_generation_buffer) {
+- MemTracker::shutdown(MemTracker::NMT_out_of_generation);
+- }
+-}
+-
+-#ifndef PRODUCT
+-int MemTrackWorker::count_recorder(const MemRecorder* head) {
+- int count = 0;
+- while(head != NULL) {
+- count ++;
+- head = head->next();
+- }
+- return count;
+-}
+-
+-int MemTrackWorker::count_pending_recorders() const {
+- int count = 0;
+- for (int index = 0; index < MAX_GENERATIONS; index ++) {
+- MemRecorder* head = _gen[index].peek();
+- if (head != NULL) {
+- count += count_recorder(head);
+- }
+- }
+- return count;
+-}
+-#endif
+--- ./hotspot/src/share/vm/services/memTrackWorker.hpp Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,118 +0,0 @@
+-/*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- *
+- */
+-
+-#ifndef SHARE_VM_SERVICES_MEM_TRACK_WORKER_HPP
+-#define SHARE_VM_SERVICES_MEM_TRACK_WORKER_HPP
+-
+-#include "memory/allocation.hpp"
+-#include "runtime/thread.hpp"
+-#include "services/memRecorder.hpp"
+-
+-// Maximum MAX_GENERATIONS generation data can be tracked.
+-#define MAX_GENERATIONS 512
+-
+-class GenerationData VALUE_OBJ_CLASS_SPEC {
+- private:
+- int _number_of_classes;
+- MemRecorder* _recorder_list;
+-
+- public:
+- GenerationData(): _number_of_classes(0), _recorder_list(NULL) { }
+-
+- inline int number_of_classes() const { return _number_of_classes; }
+- inline void set_number_of_classes(long num) { _number_of_classes = num; }
+-
+- inline MemRecorder* next_recorder() {
+- if (_recorder_list == NULL) {
+- return NULL;
+- } else {
+- MemRecorder* tmp = _recorder_list;
+- _recorder_list = _recorder_list->next();
+- return tmp;
+- }
+- }
+-
+- inline bool has_more_recorder() const {
+- return (_recorder_list != NULL);
+- }
+-
+- // add recorders to this generation
+- void add_recorders(MemRecorder* head) {
+- if (head != NULL) {
+- if (_recorder_list == NULL) {
+- _recorder_list = head;
+- } else {
+- MemRecorder* tmp = _recorder_list;
+- for (; tmp->next() != NULL; tmp = tmp->next());
+- tmp->set_next(head);
+- }
+- }
+- }
+-
+- void reset();
+-
+- NOT_PRODUCT(MemRecorder* peek() const { return _recorder_list; })
+-};
+-
+-class MemTrackWorker : public NamedThread {
+- private:
+- // circular buffer. This buffer contains generation data to be merged into global
+- // snaphsot.
+- // Each slot holds a generation
+- GenerationData _gen[MAX_GENERATIONS];
+- int _head, _tail; // head and tail pointers to above circular buffer
+-
+- bool _has_error;
+-
+- MemSnapshot* _snapshot;
+-
+- public:
+- MemTrackWorker(MemSnapshot* snapshot);
+- ~MemTrackWorker();
+- _NOINLINE_ void* operator new(size_t size) throw();
+- _NOINLINE_ void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw();
+-
+- void start();
+- void run();
+-
+- inline bool has_error() const { return _has_error; }
+-
+- // task at synchronization point
+- void at_sync_point(MemRecorder* pending_recorders, int number_of_classes);
+-
+- // for debugging purpose, they are not thread safe.
+- NOT_PRODUCT(static int count_recorder(const MemRecorder* head);)
+- NOT_PRODUCT(int count_pending_recorders() const;)
+-
+- NOT_PRODUCT(int _sync_point_count;)
+- NOT_PRODUCT(int _merge_count;)
+- NOT_PRODUCT(int _last_gen_in_use;)
+-
+- // how many generations are queued
+- inline int generations_in_use() const {
+- return (_tail >= _head ? (_tail - _head + 1) : (MAX_GENERATIONS - (_head - _tail) + 1));
+- }
+-};
+-
+-#endif // SHARE_VM_SERVICES_MEM_TRACK_WORKER_HPP
+--- ./hotspot/src/share/vm/services/memTracker.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/services/memTracker.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -23,861 +23,304 @@
+ */
+ #include "precompiled.hpp"
+
+-#include "oops/instanceKlass.hpp"
+-#include "runtime/atomic.hpp"
+-#include "runtime/interfaceSupport.hpp"
+-#include "runtime/mutexLocker.hpp"
+-#include "runtime/safepoint.hpp"
+-#include "runtime/threadCritical.hpp"
+-#include "runtime/vm_operations.hpp"
+-#include "services/memPtr.hpp"
++#include "runtime/mutex.hpp"
++#include "services/memBaseline.hpp"
+ #include "services/memReporter.hpp"
++#include "services/mallocTracker.inline.hpp"
+ #include "services/memTracker.hpp"
+-#include "utilities/decoder.hpp"
+ #include "utilities/defaultStream.hpp"
+-#include "utilities/globalDefinitions.hpp"
+
+-bool NMT_track_callsite = false;
++#ifdef SOLARIS
++ volatile bool NMT_stack_walkable = false;
++#else
++ volatile bool NMT_stack_walkable = true;
++#endif
+
+-// walk all 'known' threads at NMT sync point, and collect their recorders
+-void SyncThreadRecorderClosure::do_thread(Thread* thread) {
+- assert(SafepointSynchronize::is_at_safepoint(), "Safepoint required");
+- if (thread->is_Java_thread()) {
+- JavaThread* javaThread = (JavaThread*)thread;
+- MemRecorder* recorder = javaThread->get_recorder();
+- if (recorder != NULL) {
+- MemTracker::enqueue_pending_recorder(recorder);
+- javaThread->set_recorder(NULL);
++volatile NMT_TrackingLevel MemTracker::_tracking_level = NMT_unknown;
++NMT_TrackingLevel MemTracker::_cmdline_tracking_level = NMT_unknown;
++
++MemBaseline MemTracker::_baseline;
++Mutex* MemTracker::_query_lock = NULL;
++bool MemTracker::_is_nmt_env_valid = true;
++
++
++NMT_TrackingLevel MemTracker::init_tracking_level() {
++ NMT_TrackingLevel level = NMT_off;
++ char buf[64];
++ char nmt_option[64];
++ jio_snprintf(buf, sizeof(buf), "NMT_LEVEL_%d", os::current_process_id());
++ if (os::getenv(buf, nmt_option, sizeof(nmt_option))) {
++ if (strcmp(nmt_option, "summary") == 0) {
++ level = NMT_summary;
++ } else if (strcmp(nmt_option, "detail") == 0) {
++#if PLATFORM_NATIVE_STACK_WALKING_SUPPORTED
++ level = NMT_detail;
++#else
++ level = NMT_summary;
++#endif // PLATFORM_NATIVE_STACK_WALKING_SUPPORTED
++ } else if (strcmp(nmt_option, "off") != 0) {
++ // The option value is invalid
++ _is_nmt_env_valid = false;
+ }
++
++ // Remove the environment variable to avoid leaking to child processes
++ os::unsetenv(buf);
+ }
+- _thread_count ++;
++
++ // Construct NativeCallStack::EMPTY_STACK. It may get constructed twice,
++ // but it is benign, the results are the same.
++ ::new ((void*)&NativeCallStack::EMPTY_STACK) NativeCallStack(0, false);
++
++ if (!MallocTracker::initialize(level) ||
++ !VirtualMemoryTracker::initialize(level)) {
++ level = NMT_off;
++ }
++ return level;
+ }
+
+-
+-MemRecorder* volatile MemTracker::_global_recorder = NULL;
+-MemSnapshot* MemTracker::_snapshot = NULL;
+-MemBaseline MemTracker::_baseline;
+-Mutex* MemTracker::_query_lock = NULL;
+-MemRecorder* volatile MemTracker::_merge_pending_queue = NULL;
+-MemRecorder* volatile MemTracker::_pooled_recorders = NULL;
+-MemTrackWorker* MemTracker::_worker_thread = NULL;
+-int MemTracker::_sync_point_skip_count = 0;
+-MemTracker::NMTLevel MemTracker::_tracking_level = MemTracker::NMT_off;
+-volatile MemTracker::NMTStates MemTracker::_state = NMT_uninited;
+-MemTracker::ShutdownReason MemTracker::_reason = NMT_shutdown_none;
+-int MemTracker::_thread_count = 255;
+-volatile jint MemTracker::_pooled_recorder_count = 0;
+-volatile unsigned long MemTracker::_processing_generation = 0;
+-volatile bool MemTracker::_worker_thread_idle = false;
+-volatile jint MemTracker::_pending_op_count = 0;
+-volatile bool MemTracker::_slowdown_calling_thread = false;
+-debug_only(intx MemTracker::_main_thread_tid = 0;)
+-NOT_PRODUCT(volatile jint MemTracker::_pending_recorder_count = 0;)
+-
+-void MemTracker::init_tracking_options(const char* option_line) {
+- _tracking_level = NMT_off;
+- if (strcmp(option_line, "=summary") == 0) {
+- _tracking_level = NMT_summary;
+- } else if (strcmp(option_line, "=detail") == 0) {
+- // detail relies on a stack-walking ability that may not
+- // be available depending on platform and/or compiler flags
+-#if PLATFORM_NATIVE_STACK_WALKING_SUPPORTED
+- _tracking_level = NMT_detail;
+-#else
+- jio_fprintf(defaultStream::error_stream(),
+- "NMT detail is not supported on this platform. Using NMT summary instead.\n");
+- _tracking_level = NMT_summary;
+-#endif
+- } else if (strcmp(option_line, "=off") != 0) {
+- vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL);
+- }
+-}
+-
+-// first phase of bootstrapping, when VM is still in single-threaded mode.
+-void MemTracker::bootstrap_single_thread() {
+- if (_tracking_level > NMT_off) {
+- assert(_state == NMT_uninited, "wrong state");
+-
+- // NMT is not supported with UseMallocOnly is on. NMT can NOT
+- // handle the amount of malloc data without significantly impacting
+- // runtime performance when this flag is on.
+- if (UseMallocOnly) {
+- shutdown(NMT_use_malloc_only);
++void MemTracker::init() {
++ NMT_TrackingLevel level = tracking_level();
++ if (level >= NMT_summary) {
++ if (!VirtualMemoryTracker::late_initialize(level)) {
++ shutdown();
+ return;
+ }
+-
+ _query_lock = new (std::nothrow) Mutex(Monitor::max_nonleaf, "NMT_queryLock");
++ // Already OOM. It is unlikely, but still have to handle it.
+ if (_query_lock == NULL) {
+- shutdown(NMT_out_of_memory);
+- return;
+- }
+-
+- debug_only(_main_thread_tid = os::current_thread_id();)
+- _state = NMT_bootstrapping_single_thread;
+- NMT_track_callsite = (_tracking_level == NMT_detail && can_walk_stack());
+- }
+-}
+-
+-// second phase of bootstrapping, when VM is about to or already entered multi-theaded mode.
+-void MemTracker::bootstrap_multi_thread() {
+- if (_tracking_level > NMT_off && _state == NMT_bootstrapping_single_thread) {
+- // create nmt lock for multi-thread execution
+- assert(_main_thread_tid == os::current_thread_id(), "wrong thread");
+- _state = NMT_bootstrapping_multi_thread;
+- NMT_track_callsite = (_tracking_level == NMT_detail && can_walk_stack());
+- }
+-}
+-
+-// fully start nmt
+-void MemTracker::start() {
+- // Native memory tracking is off from command line option
+- if (_tracking_level == NMT_off || shutdown_in_progress()) return;
+-
+- assert(_main_thread_tid == os::current_thread_id(), "wrong thread");
+- assert(_state == NMT_bootstrapping_multi_thread, "wrong state");
+-
+- _snapshot = new (std::nothrow)MemSnapshot();
+- if (_snapshot != NULL) {
+- if (!_snapshot->out_of_memory() && start_worker(_snapshot)) {
+- _state = NMT_started;
+- NMT_track_callsite = (_tracking_level == NMT_detail && can_walk_stack());
+- return;
+- }
+-
+- delete _snapshot;
+- _snapshot = NULL;
+- }
+-
+- // fail to start native memory tracking, shut it down
+- shutdown(NMT_initialization);
+-}
+-
+-/**
+- * Shutting down native memory tracking.
+- * We can not shutdown native memory tracking immediately, so we just
+- * setup shutdown pending flag, every native memory tracking component
+- * should orderly shut itself down.
+- *
+- * The shutdown sequences:
+- * 1. MemTracker::shutdown() sets MemTracker to shutdown pending state
+- * 2. Worker thread calls MemTracker::final_shutdown(), which transites
+- * MemTracker to final shutdown state.
+- * 3. At sync point, MemTracker does final cleanup, before sets memory
+- * tracking level to off to complete shutdown.
+- */
+-void MemTracker::shutdown(ShutdownReason reason) {
+- if (_tracking_level == NMT_off) return;
+-
+- if (_state <= NMT_bootstrapping_single_thread) {
+- // we still in single thread mode, there is not contention
+- _state = NMT_shutdown_pending;
+- _reason = reason;
+- } else {
+- // we want to know who initialized shutdown
+- if ((jint)NMT_started == Atomic::cmpxchg((jint)NMT_shutdown_pending,
+- (jint*)&_state, (jint)NMT_started)) {
+- _reason = reason;
++ shutdown();
+ }
+ }
+ }
+
+-// final phase of shutdown
+-void MemTracker::final_shutdown() {
+- // delete all pending recorders and pooled recorders
+- delete_all_pending_recorders();
+- delete_all_pooled_recorders();
+-
+- {
+- // shared baseline and snapshot are the only objects needed to
+- // create query results
+- MutexLockerEx locker(_query_lock, true);
+- // cleanup baseline data and snapshot
+- _baseline.clear();
+- delete _snapshot;
+- _snapshot = NULL;
++bool MemTracker::check_launcher_nmt_support(const char* value) {
++ if (strcmp(value, "=detail") == 0) {
++#if !PLATFORM_NATIVE_STACK_WALKING_SUPPORTED
++ jio_fprintf(defaultStream::error_stream(),
++ "NMT detail is not supported on this platform. Using NMT summary instead.\n");
++ if (MemTracker::tracking_level() != NMT_summary) {
++ return false;
++ }
++#else
++ if (MemTracker::tracking_level() != NMT_detail) {
++ return false;
++ }
++#endif
++ } else if (strcmp(value, "=summary") == 0) {
++ if (MemTracker::tracking_level() != NMT_summary) {
++ return false;
++ }
++ } else if (strcmp(value, "=off") == 0) {
++ if (MemTracker::tracking_level() != NMT_off) {
++ return false;
++ }
++ } else {
++ _is_nmt_env_valid = false;
+ }
+
+- // shutdown shared decoder instance, since it is only
+- // used by native memory tracking so far.
+- Decoder::shutdown();
+-
+- MemTrackWorker* worker = NULL;
+- {
+- ThreadCritical tc;
+- // can not delete worker inside the thread critical
+- if (_worker_thread != NULL && Thread::current() == _worker_thread) {
+- worker = _worker_thread;
+- _worker_thread = NULL;
+- }
+- }
+- if (worker != NULL) {
+- delete worker;
+- }
+- _state = NMT_final_shutdown;
++ return true;
+ }
+
+-// delete all pooled recorders
+-void MemTracker::delete_all_pooled_recorders() {
+- // free all pooled recorders
+- MemRecorder* volatile cur_head = _pooled_recorders;
+- if (cur_head != NULL) {
+- MemRecorder* null_ptr = NULL;
+- while (cur_head != NULL && (void*)cur_head != Atomic::cmpxchg_ptr((void*)null_ptr,
+- (void*)&_pooled_recorders, (void*)cur_head)) {
+- cur_head = _pooled_recorders;
+- }
+- if (cur_head != NULL) {
+- delete cur_head;
+- _pooled_recorder_count = 0;
++bool MemTracker::verify_nmt_option() {
++ return _is_nmt_env_valid;
++}
++
++void* MemTracker::malloc_base(void* memblock) {
++ return MallocTracker::get_base(memblock);
++}
++
++void Tracker::record(address addr, size_t size) {
++ if (MemTracker::tracking_level() < NMT_summary) return;
++ switch(_type) {
++ case uncommit:
++ VirtualMemoryTracker::remove_uncommitted_region(addr, size);
++ break;
++ case release:
++ VirtualMemoryTracker::remove_released_region(addr, size);
++ break;
++ default:
++ ShouldNotReachHere();
++ }
++}
++
++
++// Shutdown can only be issued via JCmd, and NMT JCmd is serialized by lock
++void MemTracker::shutdown() {
++ // We can only shutdown NMT to minimal tracking level if it is ever on.
++ if (tracking_level () > NMT_minimal) {
++ transition_to(NMT_minimal);
++ }
++}
++
++bool MemTracker::transition_to(NMT_TrackingLevel level) {
++ NMT_TrackingLevel current_level = tracking_level();
++
++ assert(level != NMT_off || current_level == NMT_off, "Cannot transition NMT to off");
++
++ if (current_level == level) {
++ return true;
++ } else if (current_level > level) {
++ // Downgrade tracking level, we want to lower the tracking level first
++ _tracking_level = level;
++ // Make _tracking_level visible immediately.
++ OrderAccess::fence();
++ VirtualMemoryTracker::transition(current_level, level);
++ MallocTracker::transition(current_level, level);
++ } else {
++ // Upgrading tracking level is not supported and has never been supported.
++ // Allocating and deallocating malloc tracking structures is not thread safe and
++ // leads to inconsistencies unless a lot coarser locks are added.
++ }
++ return true;
++}
++
++void MemTracker::report(bool summary_only, outputStream* output) {
++ assert(output != NULL, "No output stream");
++ MemBaseline baseline;
++ if (baseline.baseline(summary_only)) {
++ if (summary_only) {
++ MemSummaryReporter rpt(baseline, output);
++ rpt.report();
++ } else {
++ MemDetailReporter rpt(baseline, output);
++ rpt.report();
+ }
+ }
+ }
+
+-// delete all recorders in pending queue
+-void MemTracker::delete_all_pending_recorders() {
+- // free all pending recorders
+- MemRecorder* pending_head = get_pending_recorders();
+- if (pending_head != NULL) {
+- delete pending_head;
+- }
+-}
++// This is a walker to gather malloc site hashtable statistics,
++// the result is used for tuning.
++class StatisticsWalker : public MallocSiteWalker {
++ private:
++ enum Threshold {
++ // aggregates statistics over this threshold into one
++ // line item.
++ report_threshold = 20
++ };
+
+-/*
+- * retrieve per-thread recorder of specified thread.
+- * if thread == NULL, it means global recorder
+- */
+-MemRecorder* MemTracker::get_thread_recorder(JavaThread* thread) {
+- if (shutdown_in_progress()) return NULL;
++ private:
++ // Number of allocation sites that have all memory freed
++ int _empty_entries;
++ // Total number of allocation sites, include empty sites
++ int _total_entries;
++ // Number of captured call stack distribution
++ int _stack_depth_distribution[NMT_TrackingStackDepth];
++ // Hash distribution
++ int _hash_distribution[report_threshold];
++ // Number of hash buckets that have entries over the threshold
++ int _bucket_over_threshold;
+
+- MemRecorder* rc;
+- if (thread == NULL) {
+- rc = _global_recorder;
+- } else {
+- rc = thread->get_recorder();
++ // The hash bucket that walker is currently walking
++ int _current_hash_bucket;
++ // The length of current hash bucket
++ int _current_bucket_length;
++ // Number of hash buckets that are not empty
++ int _used_buckets;
++ // Longest hash bucket length
++ int _longest_bucket_length;
++
++ public:
++ StatisticsWalker() : _empty_entries(0), _total_entries(0) {
++ int index = 0;
++ for (index = 0; index < NMT_TrackingStackDepth; index ++) {
++ _stack_depth_distribution[index] = 0;
++ }
++ for (index = 0; index < report_threshold; index ++) {
++ _hash_distribution[index] = 0;
++ }
++ _bucket_over_threshold = 0;
++ _longest_bucket_length = 0;
++ _current_hash_bucket = -1;
++ _current_bucket_length = 0;
++ _used_buckets = 0;
+ }
+
+- if (rc != NULL && rc->is_full()) {
+- enqueue_pending_recorder(rc);
+- rc = NULL;
++ virtual bool at(const MallocSite* e) {
++ if (e->size() == 0) _empty_entries ++;
++ _total_entries ++;
++
++ // stack depth distrubution
++ int frames = e->call_stack()->frames();
++ _stack_depth_distribution[frames - 1] ++;
++
++ // hash distribution
++ int hash_bucket = e->hash() % MallocSiteTable::hash_buckets();
++ if (_current_hash_bucket == -1) {
++ _current_hash_bucket = hash_bucket;
++ _current_bucket_length = 1;
++ } else if (_current_hash_bucket == hash_bucket) {
++ _current_bucket_length ++;
++ } else {
++ record_bucket_length(_current_bucket_length);
++ _current_hash_bucket = hash_bucket;
++ _current_bucket_length = 1;
++ }
++ return true;
+ }
+
+- if (rc == NULL) {
+- rc = get_new_or_pooled_instance();
+- if (thread == NULL) {
+- _global_recorder = rc;
+- } else {
+- thread->set_recorder(rc);
+- }
+- }
+- return rc;
+-}
+-
+-/*
+- * get a per-thread recorder from pool, or create a new one if
+- * there is not one available.
+- */
+-MemRecorder* MemTracker::get_new_or_pooled_instance() {
+- MemRecorder* cur_head = const_cast<MemRecorder*> (_pooled_recorders);
+- if (cur_head == NULL) {
+- MemRecorder* rec = new (std::nothrow)MemRecorder();
+- if (rec == NULL || rec->out_of_memory()) {
+- shutdown(NMT_out_of_memory);
+- if (rec != NULL) {
+- delete rec;
+- rec = NULL;
+- }
+- }
+- return rec;
+- } else {
+- MemRecorder* next_head = cur_head->next();
+- if ((void*)cur_head != Atomic::cmpxchg_ptr((void*)next_head, (void*)&_pooled_recorders,
+- (void*)cur_head)) {
+- return get_new_or_pooled_instance();
+- }
+- cur_head->set_next(NULL);
+- Atomic::dec(&_pooled_recorder_count);
+- cur_head->set_generation();
+- return cur_head;
+- }
+-}
+-
+-/*
+- * retrieve all recorders in pending queue, and empty the queue
+- */
+-MemRecorder* MemTracker::get_pending_recorders() {
+- MemRecorder* cur_head = const_cast<MemRecorder*>(_merge_pending_queue);
+- MemRecorder* null_ptr = NULL;
+- while ((void*)cur_head != Atomic::cmpxchg_ptr((void*)null_ptr, (void*)&_merge_pending_queue,
+- (void*)cur_head)) {
+- cur_head = const_cast<MemRecorder*>(_merge_pending_queue);
+- }
+- NOT_PRODUCT(Atomic::store(0, &_pending_recorder_count));
+- return cur_head;
+-}
+-
+-/*
+- * release a recorder to recorder pool.
+- */
+-void MemTracker::release_thread_recorder(MemRecorder* rec) {
+- assert(rec != NULL, "null recorder");
+- // we don't want to pool too many recorders
+- rec->set_next(NULL);
+- if (shutdown_in_progress() || _pooled_recorder_count > _thread_count * 2) {
+- delete rec;
+- return;
++ // walk completed
++ void completed() {
++ record_bucket_length(_current_bucket_length);
+ }
+
+- rec->clear();
+- MemRecorder* cur_head = const_cast<MemRecorder*>(_pooled_recorders);
+- rec->set_next(cur_head);
+- while ((void*)cur_head != Atomic::cmpxchg_ptr((void*)rec, (void*)&_pooled_recorders,
+- (void*)cur_head)) {
+- cur_head = const_cast<MemRecorder*>(_pooled_recorders);
+- rec->set_next(cur_head);
+- }
+- Atomic::inc(&_pooled_recorder_count);
+-}
+-
+-// write a record to proper recorder. No lock can be taken from this method
+-// down.
+-void MemTracker::write_tracking_record(address addr, MEMFLAGS flags,
+- size_t size, jint seq, address pc, JavaThread* thread) {
+-
+- MemRecorder* rc = get_thread_recorder(thread);
+- if (rc != NULL) {
+- rc->record(addr, flags, size, seq, pc);
++ void report_statistics(outputStream* out) {
++ int index;
++ out->print_cr("Malloc allocation site table:");
++ out->print_cr("\tTotal entries: %d", _total_entries);
++ out->print_cr("\tEmpty entries: %d (%2.2f%%)", _empty_entries, ((float)_empty_entries * 100) / _total_entries);
++ out->print_cr(" ");
++ out->print_cr("Hash distribution:");
++ if (_used_buckets < MallocSiteTable::hash_buckets()) {
++ out->print_cr("empty bucket: %d", (MallocSiteTable::hash_buckets() - _used_buckets));
+ }
+-}
+-
+-/**
+- * enqueue a recorder to pending queue
+- */
+-void MemTracker::enqueue_pending_recorder(MemRecorder* rec) {
+- assert(rec != NULL, "null recorder");
+-
+- // we are shutting down, so just delete it
+- if (shutdown_in_progress()) {
+- rec->set_next(NULL);
+- delete rec;
+- return;
+- }
+-
+- MemRecorder* cur_head = const_cast<MemRecorder*>(_merge_pending_queue);
+- rec->set_next(cur_head);
+- while ((void*)cur_head != Atomic::cmpxchg_ptr((void*)rec, (void*)&_merge_pending_queue,
+- (void*)cur_head)) {
+- cur_head = const_cast<MemRecorder*>(_merge_pending_queue);
+- rec->set_next(cur_head);
+- }
+- NOT_PRODUCT(Atomic::inc(&_pending_recorder_count);)
+-}
+-
+-/*
+- * The method is called at global safepoint
+- * during it synchronization process.
+- * 1. enqueue all JavaThreads' per-thread recorders
+- * 2. enqueue global recorder
+- * 3. retrieve all pending recorders
+- * 4. reset global sequence number generator
+- * 5. call worker's sync
+- */
+-#define MAX_SAFEPOINTS_TO_SKIP 128
+-#define SAFE_SEQUENCE_THRESHOLD 30
+-#define HIGH_GENERATION_THRESHOLD 60
+-#define MAX_RECORDER_THREAD_RATIO 30
+-#define MAX_RECORDER_PER_THREAD 100
+-
+-void MemTracker::sync() {
+- assert(_tracking_level > NMT_off, "NMT is not enabled");
+- assert(SafepointSynchronize::is_at_safepoint(), "Safepoint required");
+-
+- // Some GC tests hit large number of safepoints in short period of time
+- // without meaningful activities. We should prevent going to
+- // sync point in these cases, which can potentially exhaust generation buffer.
+- // Here is the factots to determine if we should go into sync point:
+- // 1. not to overflow sequence number
+- // 2. if we are in danger to overflow generation buffer
+- // 3. how many safepoints we already skipped sync point
+- if (_state == NMT_started) {
+- // worker thread is not ready, no one can manage generation
+- // buffer, so skip this safepoint
+- if (_worker_thread == NULL) return;
+-
+- if (_sync_point_skip_count < MAX_SAFEPOINTS_TO_SKIP) {
+- int per_seq_in_use = SequenceGenerator::peek() * 100 / max_jint;
+- int per_gen_in_use = _worker_thread->generations_in_use() * 100 / MAX_GENERATIONS;
+- if (per_seq_in_use < SAFE_SEQUENCE_THRESHOLD && per_gen_in_use >= HIGH_GENERATION_THRESHOLD) {
+- _sync_point_skip_count ++;
+- return;
++ for (index = 0; index < report_threshold; index ++) {
++ if (_hash_distribution[index] != 0) {
++ if (index == 0) {
++ out->print_cr(" %d entry: %d", 1, _hash_distribution[0]);
++ } else if (index < 9) { // single digit
++ out->print_cr(" %d entries: %d", (index + 1), _hash_distribution[index]);
++ } else {
++ out->print_cr(" %d entries: %d", (index + 1), _hash_distribution[index]);
++ }
+ }
+ }
+- {
+- // This method is running at safepoint, with ThreadCritical lock,
+- // it should guarantee that NMT is fully sync-ed.
+- ThreadCritical tc;
+-
+- // We can NOT execute NMT sync-point if there are pending tracking ops.
+- if (_pending_op_count == 0) {
+- SequenceGenerator::reset();
+- _sync_point_skip_count = 0;
+-
+- // walk all JavaThreads to collect recorders
+- SyncThreadRecorderClosure stc;
+- Threads::threads_do(&stc);
+-
+- _thread_count = stc.get_thread_count();
+- MemRecorder* pending_recorders = get_pending_recorders();
+-
+- if (_global_recorder != NULL) {
+- _global_recorder->set_next(pending_recorders);
+- pending_recorders = _global_recorder;
+- _global_recorder = NULL;
+- }
+-
+- // see if NMT has too many outstanding recorder instances, it usually
+- // means that worker thread is lagging behind in processing them.
+- if (!AutoShutdownNMT) {
+- _slowdown_calling_thread = (MemRecorder::_instance_count > MAX_RECORDER_THREAD_RATIO * _thread_count);
+- } else {
+- // If auto shutdown is on, enforce MAX_RECORDER_PER_THREAD threshold to prevent OOM
+- if (MemRecorder::_instance_count >= _thread_count * MAX_RECORDER_PER_THREAD) {
+- shutdown(NMT_out_of_memory);
+- }
+- }
+-
+- // check _worker_thread with lock to avoid racing condition
+- if (_worker_thread != NULL) {
+- _worker_thread->at_sync_point(pending_recorders, InstanceKlass::number_of_instance_classes());
+- }
+- assert(SequenceGenerator::peek() == 1, "Should not have memory activities during sync-point");
+- } else {
+- _sync_point_skip_count ++;
++ if (_bucket_over_threshold > 0) {
++ out->print_cr(" >%d entries: %d", report_threshold, _bucket_over_threshold);
++ }
++ out->print_cr("most entries: %d", _longest_bucket_length);
++ out->print_cr(" ");
++ out->print_cr("Call stack depth distribution:");
++ for (index = 0; index < NMT_TrackingStackDepth; index ++) {
++ if (_stack_depth_distribution[index] > 0) {
++ out->print_cr("\t%d: %d", index + 1, _stack_depth_distribution[index]);
+ }
+ }
+ }
+
+- // now, it is the time to shut whole things off
+- if (_state == NMT_final_shutdown) {
+- // walk all JavaThreads to delete all recorders
+- SyncThreadRecorderClosure stc;
+- Threads::threads_do(&stc);
+- // delete global recorder
+- {
+- ThreadCritical tc;
+- if (_global_recorder != NULL) {
+- delete _global_recorder;
+- _global_recorder = NULL;
+- }
++ private:
++ void record_bucket_length(int length) {
++ _used_buckets ++;
++ if (length <= report_threshold) {
++ _hash_distribution[length - 1] ++;
++ } else {
++ _bucket_over_threshold ++;
+ }
+- MemRecorder* pending_recorders = get_pending_recorders();
+- if (pending_recorders != NULL) {
+- delete pending_recorders;
+- }
+- // try at a later sync point to ensure MemRecorder instance drops to zero to
+- // completely shutdown NMT
+- if (MemRecorder::_instance_count == 0) {
+- _state = NMT_shutdown;
+- _tracking_level = NMT_off;
+- }
++ _longest_bucket_length = MAX2(_longest_bucket_length, length);
+ }
++};
++
++
++void MemTracker::tuning_statistics(outputStream* out) {
++ // NMT statistics
++ StatisticsWalker walker;
++ MallocSiteTable::walk_malloc_site(&walker);
++ walker.completed();
++
++ out->print_cr("Native Memory Tracking Statistics:");
++ out->print_cr("Malloc allocation site table size: %d", MallocSiteTable::hash_buckets());
++ out->print_cr(" Tracking stack depth: %d", NMT_TrackingStackDepth);
++ NOT_PRODUCT(out->print_cr("Peak concurrent access: %d", MallocSiteTable::access_peak_count());)
++ out->print_cr(" ");
++ walker.report_statistics(out);
+ }
+
+-/*
+- * Start worker thread.
+- */
+-bool MemTracker::start_worker(MemSnapshot* snapshot) {
+- assert(_worker_thread == NULL && _snapshot != NULL, "Just Check");
+- _worker_thread = new (std::nothrow) MemTrackWorker(snapshot);
+- if (_worker_thread == NULL) {
+- return false;
+- } else if (_worker_thread->has_error()) {
+- delete _worker_thread;
+- _worker_thread = NULL;
+- return false;
+- }
+- _worker_thread->start();
+- return true;
+-}
+-
+-/*
+- * We need to collect a JavaThread's per-thread recorder
+- * before it exits.
+- */
+-void MemTracker::thread_exiting(JavaThread* thread) {
+- if (is_on()) {
+- MemRecorder* rec = thread->get_recorder();
+- if (rec != NULL) {
+- enqueue_pending_recorder(rec);
+- thread->set_recorder(NULL);
+- }
+- }
+-}
+-
+-// baseline current memory snapshot
+-bool MemTracker::baseline() {
+- MutexLocker lock(_query_lock);
+- MemSnapshot* snapshot = get_snapshot();
+- if (snapshot != NULL) {
+- return _baseline.baseline(*snapshot, false);
+- }
+- return false;
+-}
+-
+-// print memory usage from current snapshot
+-bool MemTracker::print_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
+- MemBaseline baseline;
+- MutexLocker lock(_query_lock);
+- MemSnapshot* snapshot = get_snapshot();
+- if (snapshot != NULL && baseline.baseline(*snapshot, summary_only)) {
+- BaselineReporter reporter(out, unit);
+- reporter.report_baseline(baseline, summary_only);
+- return true;
+- }
+- return false;
+-}
+-
+-// Whitebox API for blocking until the current generation of NMT data has been merged
+-bool MemTracker::wbtest_wait_for_data_merge() {
+- // NMT can't be shutdown while we're holding _query_lock
+- MutexLocker lock(_query_lock);
+- assert(_worker_thread != NULL, "Invalid query");
+- // the generation at query time, so NMT will spin till this generation is processed
+- unsigned long generation_at_query_time = SequenceGenerator::current_generation();
+- unsigned long current_processing_generation = _processing_generation;
+- // if generation counter overflown
+- bool generation_overflown = (generation_at_query_time < current_processing_generation);
+- long generations_to_wrap = MAX_UNSIGNED_LONG - current_processing_generation;
+- // spin
+- while (!shutdown_in_progress()) {
+- if (!generation_overflown) {
+- if (current_processing_generation > generation_at_query_time) {
+- return true;
+- }
+- } else {
+- assert(generations_to_wrap >= 0, "Sanity check");
+- long current_generations_to_wrap = MAX_UNSIGNED_LONG - current_processing_generation;
+- assert(current_generations_to_wrap >= 0, "Sanity check");
+- // to overflow an unsigned long should take long time, so to_wrap check should be sufficient
+- if (current_generations_to_wrap > generations_to_wrap &&
+- current_processing_generation > generation_at_query_time) {
+- return true;
+- }
+- }
+-
+- // if worker thread is idle, but generation is not advancing, that means
+- // there is not safepoint to let NMT advance generation, force one.
+- if (_worker_thread_idle) {
+- VM_ForceSafepoint vfs;
+- VMThread::execute(&vfs);
+- }
+- MemSnapshot* snapshot = get_snapshot();
+- if (snapshot == NULL) {
+- return false;
+- }
+- snapshot->wait(1000);
+- current_processing_generation = _processing_generation;
+- }
+- // We end up here if NMT is shutting down before our data has been merged
+- return false;
+-}
+-
+-// compare memory usage between current snapshot and baseline
+-bool MemTracker::compare_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
+- MutexLocker lock(_query_lock);
+- if (_baseline.baselined()) {
+- MemBaseline baseline;
+- MemSnapshot* snapshot = get_snapshot();
+- if (snapshot != NULL && baseline.baseline(*snapshot, summary_only)) {
+- BaselineReporter reporter(out, unit);
+- reporter.diff_baselines(baseline, _baseline, summary_only);
+- return true;
+- }
+- }
+- return false;
+-}
+-
+-#ifndef PRODUCT
+-void MemTracker::walk_stack(int toSkip, char* buf, int len) {
+- int cur_len = 0;
+- char tmp[1024];
+- address pc;
+-
+- while (cur_len < len) {
+- pc = os::get_caller_pc(toSkip + 1);
+- if (pc != NULL && os::dll_address_to_function_name(pc, tmp, sizeof(tmp), NULL)) {
+- jio_snprintf(&buf[cur_len], (len - cur_len), "%s\n", tmp);
+- cur_len = (int)strlen(buf);
+- } else {
+- buf[cur_len] = '\0';
+- break;
+- }
+- toSkip ++;
+- }
+-}
+-
+-void MemTracker::print_tracker_stats(outputStream* st) {
+- st->print_cr("\nMemory Tracker Stats:");
+- st->print_cr("\tMax sequence number = %d", SequenceGenerator::max_seq_num());
+- st->print_cr("\tthead count = %d", _thread_count);
+- st->print_cr("\tArena instance = %d", Arena::_instance_count);
+- st->print_cr("\tpooled recorder count = %d", _pooled_recorder_count);
+- st->print_cr("\tqueued recorder count = %d", _pending_recorder_count);
+- st->print_cr("\tmemory recorder instance count = %d", MemRecorder::_instance_count);
+- if (_worker_thread != NULL) {
+- st->print_cr("\tWorker thread:");
+- st->print_cr("\t\tSync point count = %d", _worker_thread->_sync_point_count);
+- st->print_cr("\t\tpending recorder count = %d", _worker_thread->count_pending_recorders());
+- st->print_cr("\t\tmerge count = %d", _worker_thread->_merge_count);
+- } else {
+- st->print_cr("\tWorker thread is not started");
+- }
+- st->print_cr(" ");
+-
+- if (_snapshot != NULL) {
+- _snapshot->print_snapshot_stats(st);
+- } else {
+- st->print_cr("No snapshot");
+- }
+-}
+-#endif
+-
+-
+-// Tracker Implementation
+-
+-/*
+- * Create a tracker.
+- * This is a fairly complicated constructor, as it has to make two important decisions:
+- * 1) Does it need to take ThreadCritical lock to write tracking record
+- * 2) Does it need to pre-reserve a sequence number for the tracking record
+- *
+- * The rules to determine if ThreadCritical is needed:
+- * 1. When nmt is in single-threaded bootstrapping mode, no lock is needed as VM
+- * still in single thread mode.
+- * 2. For all threads other than JavaThread, ThreadCritical is needed
+- * to write to recorders to global recorder.
+- * 3. For JavaThreads that are no longer visible by safepoint, also
+- * need to take ThreadCritical and records are written to global
+- * recorders, since these threads are NOT walked by Threads.do_thread().
+- * 4. JavaThreads that are running in safepoint-safe states do not stop
+- * for safepoints, ThreadCritical lock should be taken to write
+- * memory records.
+- * 5. JavaThreads that are running in VM state do not need any lock and
+- * records are written to per-thread recorders.
+- * 6. For a thread has yet to attach VM 'Thread', they need to take
+- * ThreadCritical to write to global recorder.
+- *
+- * The memory operations that need pre-reserve sequence numbers:
+- * The memory operations that "release" memory blocks and the
+- * operations can fail, need to pre-reserve sequence number. They
+- * are realloc, uncommit and release.
+- *
+- * The reason for pre-reserve sequence number, is to prevent race condition:
+- * Thread 1 Thread 2
+- * <release>
+- * <allocate>
+- * <write allocate record>
+- * <write release record>
+- * if Thread 2 happens to obtain the memory address Thread 1 just released,
+- * then NMT can mistakenly report the memory is free.
+- *
+- * Noticeably, free() does not need pre-reserve sequence number, because the call
+- * does not fail, so we can alway write "release" record before the memory is actaully
+- * freed.
+- *
+- * For realloc, uncommit and release, following coding pattern should be used:
+- *
+- * MemTracker::Tracker tkr = MemTracker::get_realloc_tracker();
+- * ptr = ::realloc(...);
+- * if (ptr == NULL) {
+- * tkr.record(...)
+- * } else {
+- * tkr.discard();
+- * }
+- *
+- * MemTracker::Tracker tkr = MemTracker::get_virtual_memory_uncommit_tracker();
+- * if (uncommit(...)) {
+- * tkr.record(...);
+- * } else {
+- * tkr.discard();
+- * }
+- *
+- * MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
+- * if (release(...)) {
+- * tkr.record(...);
+- * } else {
+- * tkr.discard();
+- * }
+- *
+- * Since pre-reserved sequence number is only good for the generation that it is acquired,
+- * when there is pending Tracker that reserved sequence number, NMT sync-point has
+- * to be skipped to prevent from advancing generation. This is done by inc and dec
+- * MemTracker::_pending_op_count, when MemTracker::_pending_op_count > 0, NMT sync-point is skipped.
+- * Not all pre-reservation of sequence number will increment pending op count. For JavaThreads
+- * that honor safepoints, safepoint can not occur during the memory operations, so the
+- * pre-reserved sequence number won't cross the generation boundry.
+- */
+-MemTracker::Tracker::Tracker(MemoryOperation op, Thread* thr) {
+- _op = NoOp;
+- _seq = 0;
+- if (MemTracker::is_on()) {
+- _java_thread = NULL;
+- _op = op;
+-
+- // figure out if ThreadCritical lock is needed to write this operation
+- // to MemTracker
+- if (MemTracker::is_single_threaded_bootstrap()) {
+- thr = NULL;
+- } else if (thr == NULL) {
+- // don't use Thread::current(), since it is possible that
+- // the calling thread has yet to attach to VM 'Thread',
+- // which will result assertion failure
+- thr = ThreadLocalStorage::thread();
+- }
+-
+- if (thr != NULL) {
+- // Check NMT load
+- MemTracker::check_NMT_load(thr);
+-
+- if (thr->is_Java_thread() && ((JavaThread*)thr)->is_safepoint_visible()) {
+- _java_thread = (JavaThread*)thr;
+- JavaThreadState state = _java_thread->thread_state();
+- // JavaThreads that are safepoint safe, can run through safepoint,
+- // so ThreadCritical is needed to ensure no threads at safepoint create
+- // new records while the records are being gathered and the sequence number is changing
+- _need_thread_critical_lock =
+- SafepointSynchronize::safepoint_safe(_java_thread, state);
+- } else {
+- _need_thread_critical_lock = true;
+- }
+- } else {
+- _need_thread_critical_lock
+- = !MemTracker::is_single_threaded_bootstrap();
+- }
+-
+- // see if we need to pre-reserve sequence number for this operation
+- if (_op == Realloc || _op == Uncommit || _op == Release) {
+- if (_need_thread_critical_lock) {
+- ThreadCritical tc;
+- MemTracker::inc_pending_op_count();
+- _seq = SequenceGenerator::next();
+- } else {
+- // for the threads that honor safepoints, no safepoint can occur
+- // during the lifespan of tracker, so we don't need to increase
+- // pending op count.
+- _seq = SequenceGenerator::next();
+- }
+- }
+- }
+-}
+-
+-void MemTracker::Tracker::discard() {
+- if (MemTracker::is_on() && _seq != 0) {
+- if (_need_thread_critical_lock) {
+- ThreadCritical tc;
+- MemTracker::dec_pending_op_count();
+- }
+- _seq = 0;
+- }
+-}
+-
+-
+-void MemTracker::Tracker::record(address old_addr, address new_addr, size_t size,
+- MEMFLAGS flags, address pc) {
+- assert(old_addr != NULL && new_addr != NULL, "Sanity check");
+- assert(_op == Realloc || _op == NoOp, "Wrong call");
+- if (MemTracker::is_on() && NMT_CAN_TRACK(flags) && _op != NoOp) {
+- assert(_seq > 0, "Need pre-reserve sequence number");
+- if (_need_thread_critical_lock) {
+- ThreadCritical tc;
+- // free old address, use pre-reserved sequence number
+- MemTracker::write_tracking_record(old_addr, MemPointerRecord::free_tag(),
+- 0, _seq, pc, _java_thread);
+- MemTracker::write_tracking_record(new_addr, flags | MemPointerRecord::malloc_tag(),
+- size, SequenceGenerator::next(), pc, _java_thread);
+- // decrement MemTracker pending_op_count
+- MemTracker::dec_pending_op_count();
+- } else {
+- // free old address, use pre-reserved sequence number
+- MemTracker::write_tracking_record(old_addr, MemPointerRecord::free_tag(),
+- 0, _seq, pc, _java_thread);
+- MemTracker::write_tracking_record(new_addr, flags | MemPointerRecord::malloc_tag(),
+- size, SequenceGenerator::next(), pc, _java_thread);
+- }
+- _seq = 0;
+- }
+-}
+-
+-void MemTracker::Tracker::record(address addr, size_t size, MEMFLAGS flags, address pc) {
+- // OOM already?
+- if (addr == NULL) return;
+-
+- if (MemTracker::is_on() && NMT_CAN_TRACK(flags) && _op != NoOp) {
+- bool pre_reserved_seq = (_seq != 0);
+- address pc = CALLER_CALLER_PC;
+- MEMFLAGS orig_flags = flags;
+-
+- // or the tagging flags
+- switch(_op) {
+- case Malloc:
+- flags |= MemPointerRecord::malloc_tag();
+- break;
+- case Free:
+- flags = MemPointerRecord::free_tag();
+- break;
+- case Realloc:
+- fatal("Use the other Tracker::record()");
+- break;
+- case Reserve:
+- case ReserveAndCommit:
+- flags |= MemPointerRecord::virtual_memory_reserve_tag();
+- break;
+- case Commit:
+- flags = MemPointerRecord::virtual_memory_commit_tag();
+- break;
+- case Type:
+- flags |= MemPointerRecord::virtual_memory_type_tag();
+- break;
+- case Uncommit:
+- assert(pre_reserved_seq, "Need pre-reserve sequence number");
+- flags = MemPointerRecord::virtual_memory_uncommit_tag();
+- break;
+- case Release:
+- assert(pre_reserved_seq, "Need pre-reserve sequence number");
+- flags = MemPointerRecord::virtual_memory_release_tag();
+- break;
+- case ArenaSize:
+- // a bit of hack here, add a small postive offset to arena
+- // address for its size record, so the size record is sorted
+- // right after arena record.
+- flags = MemPointerRecord::arena_size_tag();
+- addr += sizeof(void*);
+- break;
+- case StackRelease:
+- flags = MemPointerRecord::virtual_memory_release_tag();
+- break;
+- default:
+- ShouldNotReachHere();
+- }
+-
+- // write memory tracking record
+- if (_need_thread_critical_lock) {
+- ThreadCritical tc;
+- if (_seq == 0) _seq = SequenceGenerator::next();
+- MemTracker::write_tracking_record(addr, flags, size, _seq, pc, _java_thread);
+- if (_op == ReserveAndCommit) {
+- MemTracker::write_tracking_record(addr, orig_flags | MemPointerRecord::virtual_memory_commit_tag(),
+- size, SequenceGenerator::next(), pc, _java_thread);
+- }
+- if (pre_reserved_seq) MemTracker::dec_pending_op_count();
+- } else {
+- if (_seq == 0) _seq = SequenceGenerator::next();
+- MemTracker::write_tracking_record(addr, flags, size, _seq, pc, _java_thread);
+- if (_op == ReserveAndCommit) {
+- MemTracker::write_tracking_record(addr, orig_flags | MemPointerRecord::virtual_memory_commit_tag(),
+- size, SequenceGenerator::next(), pc, _java_thread);
+- }
+- }
+- _seq = 0;
+- }
+-}
+-
+--- ./hotspot/src/share/vm/services/memTracker.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/services/memTracker.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -25,574 +25,297 @@
+ #ifndef SHARE_VM_SERVICES_MEM_TRACKER_HPP
+ #define SHARE_VM_SERVICES_MEM_TRACKER_HPP
+
+-#include "utilities/macros.hpp"
++#include "services/nmtCommon.hpp"
++#include "utilities/nativeCallStack.hpp"
++
+
+ #if !INCLUDE_NMT
+
+-#include "utilities/ostream.hpp"
++#define CURRENT_PC NativeCallStack::EMPTY_STACK
++#define CALLER_PC NativeCallStack::EMPTY_STACK
+
+-class BaselineOutputer : public StackObj {
+-
+-};
+-
+-class BaselineTTYOutputer : public BaselineOutputer {
+- public:
+- BaselineTTYOutputer(outputStream* st) { }
++class Tracker : public StackObj {
++ public:
++ Tracker() { }
++ void record(address addr, size_t size) { }
+ };
+
+ class MemTracker : AllStatic {
+- public:
+- enum ShutdownReason {
+- NMT_shutdown_none, // no shutdown requested
+- NMT_shutdown_user, // user requested shutdown
+- NMT_normal, // normal shutdown, process exit
+- NMT_out_of_memory, // shutdown due to out of memory
+- NMT_initialization, // shutdown due to initialization failure
+- NMT_use_malloc_only, // can not combine NMT with UseMallocOnly flag
+- NMT_error_reporting, // shutdown by vmError::report_and_die()
+- NMT_out_of_generation, // running out of generation queue
+- NMT_sequence_overflow // overflow the sequence number
+- };
++ public:
++ static inline NMT_TrackingLevel tracking_level() { return NMT_off; }
++ static inline void shutdown() { }
++ static inline void init() { }
++ static bool check_launcher_nmt_support(const char* value) { return true; }
++ static bool verify_nmt_option() { return true; }
+
+- class Tracker {
+- public:
+- void discard() { }
++ static inline void* record_malloc(void* mem_base, size_t size, MEMFLAGS flag,
++ const NativeCallStack& stack, NMT_TrackingLevel level) { return mem_base; }
++ static inline size_t malloc_header_size(NMT_TrackingLevel level) { return 0; }
++ static inline size_t malloc_header_size(void* memblock) { return 0; }
++ static inline void* malloc_base(void* memblock) { return memblock; }
++ static inline void* record_free(void* memblock) { return memblock; }
+
+- void record(address addr, size_t size = 0, MEMFLAGS flags = mtNone, address pc = NULL) { }
+- void record(address old_addr, address new_addr, size_t size,
+- MEMFLAGS flags, address pc = NULL) { }
+- };
++ static inline void record_new_arena(MEMFLAGS flag) { }
++ static inline void record_arena_free(MEMFLAGS flag) { }
++ static inline void record_arena_size_change(int diff, MEMFLAGS flag) { }
++ static inline void record_virtual_memory_reserve(void* addr, size_t size, const NativeCallStack& stack,
++ MEMFLAGS flag = mtNone) { }
++ static inline void record_virtual_memory_reserve_and_commit(void* addr, size_t size,
++ const NativeCallStack& stack, MEMFLAGS flag = mtNone) { }
++ static inline void record_virtual_memory_commit(void* addr, size_t size, const NativeCallStack& stack) { }
++ static inline Tracker get_virtual_memory_uncommit_tracker() { return Tracker(); }
++ static inline Tracker get_virtual_memory_release_tracker() { }
++ static inline void record_virtual_memory_type(void* addr, MEMFLAGS flag) { }
++ static inline void record_thread_stack(void* addr, size_t size) { }
++ static inline void release_thread_stack(void* addr, size_t size) { }
+
+- private:
+- static Tracker _tkr;
+-
+-
+- public:
+- static inline void init_tracking_options(const char* option_line) { }
+- static inline bool is_on() { return false; }
+- static const char* reason() { return "Native memory tracking is not implemented"; }
+- static inline bool can_walk_stack() { return false; }
+-
+- static inline void bootstrap_single_thread() { }
+- static inline void bootstrap_multi_thread() { }
+- static inline void start() { }
+-
+- static inline void record_malloc(address addr, size_t size, MEMFLAGS flags,
+- address pc = 0, Thread* thread = NULL) { }
+- static inline void record_free(address addr, MEMFLAGS flags, Thread* thread = NULL) { }
+- static inline void record_arena_size(address addr, size_t size) { }
+- static inline void record_virtual_memory_reserve(address addr, size_t size,
+- MEMFLAGS flags, address pc = 0, Thread* thread = NULL) { }
+- static inline void record_virtual_memory_reserve_and_commit(address addr, size_t size,
+- MEMFLAGS flags, address pc = 0, Thread* thread = NULL) { }
+- static inline void record_virtual_memory_commit(address addr, size_t size,
+- address pc = 0, Thread* thread = NULL) { }
+- static inline void record_virtual_memory_release(address addr, size_t size,
+- Thread* thread = NULL) { }
+- static inline void record_virtual_memory_type(address base, MEMFLAGS flags,
+- Thread* thread = NULL) { }
+- static inline Tracker get_realloc_tracker() { return _tkr; }
+- static inline Tracker get_virtual_memory_uncommit_tracker() { return _tkr; }
+- static inline Tracker get_virtual_memory_release_tracker() { return _tkr; }
+- static inline bool baseline() { return false; }
+- static inline bool has_baseline() { return false; }
+-
+- static inline void set_autoShutdown(bool value) { }
+- static void shutdown(ShutdownReason reason) { }
+- static inline bool shutdown_in_progress() { return false; }
+- static bool print_memory_usage(BaselineOutputer& out, size_t unit,
+- bool summary_only = true) { return false; }
+- static bool compare_memory_usage(BaselineOutputer& out, size_t unit,
+- bool summary_only = true) { return false; }
+-
+- static bool wbtest_wait_for_data_merge() { return false; }
+-
+- static inline void sync() { }
+- static inline void thread_exiting(JavaThread* thread) { }
++ static void final_report(outputStream*) { }
++ static void error_report(outputStream*) { }
+ };
+
++#else
+
+-#else // !INCLUDE_NMT
++#include "runtime/atomic.hpp"
++#include "runtime/threadCritical.hpp"
++#include "services/mallocTracker.hpp"
++#include "services/virtualMemoryTracker.hpp"
+
+-#include "memory/allocation.hpp"
+-#include "runtime/globals.hpp"
+-#include "runtime/mutex.hpp"
+-#include "runtime/os.hpp"
+-#include "runtime/thread.hpp"
+-#include "services/memPtr.hpp"
+-#include "services/memRecorder.hpp"
+-#include "services/memSnapshot.hpp"
+-#include "services/memTrackWorker.hpp"
++extern volatile bool NMT_stack_walkable;
+
+-extern bool NMT_track_callsite;
++#define CURRENT_PC ((MemTracker::tracking_level() == NMT_detail && NMT_stack_walkable) ? \
++ NativeCallStack(0, true) : NativeCallStack::EMPTY_STACK)
++#define CALLER_PC ((MemTracker::tracking_level() == NMT_detail && NMT_stack_walkable) ? \
++ NativeCallStack(1, true) : NativeCallStack::EMPTY_STACK)
+
+-#ifndef MAX_UNSIGNED_LONG
+-#define MAX_UNSIGNED_LONG (unsigned long)(-1)
+-#endif
++class MemBaseline;
++class Mutex;
+
+-#ifdef ASSERT
+- #define DEBUG_CALLER_PC (NMT_track_callsite ? os::get_caller_pc(2) : 0)
+-#else
+- #define DEBUG_CALLER_PC 0
+-#endif
+-
+-// The thread closure walks threads to collect per-thread
+-// memory recorders at NMT sync point
+-class SyncThreadRecorderClosure : public ThreadClosure {
+- private:
+- int _thread_count;
+-
++// Tracker is used for guarding 'release' semantics of virtual memory operation, to avoid
++// the other thread obtains and records the same region that is just 'released' by current
++// thread but before it can record the operation.
++class Tracker : public StackObj {
+ public:
+- SyncThreadRecorderClosure() {
+- _thread_count =0;
+- }
+-
+- void do_thread(Thread* thread);
+- int get_thread_count() const {
+- return _thread_count;
+- }
+-};
+-
+-class BaselineOutputer;
+-class MemSnapshot;
+-class MemTrackWorker;
+-class Thread;
+-/*
+- * MemTracker is the 'gate' class to native memory tracking runtime.
+- */
+-class MemTracker : AllStatic {
+- friend class GenerationData;
+- friend class MemTrackWorker;
+- friend class MemSnapshot;
+- friend class SyncThreadRecorderClosure;
+-
+- // NMT state
+- enum NMTStates {
+- NMT_uninited, // not yet initialized
+- NMT_bootstrapping_single_thread, // bootstrapping, VM is in single thread mode
+- NMT_bootstrapping_multi_thread, // bootstrapping, VM is about to enter multi-thread mode
+- NMT_started, // NMT fully started
+- NMT_shutdown_pending, // shutdown pending
+- NMT_final_shutdown, // in final phase of shutdown
+- NMT_shutdown // shutdown
++ enum TrackerType {
++ uncommit,
++ release
+ };
+
+ public:
+- class Tracker : public StackObj {
+- friend class MemTracker;
+- public:
+- enum MemoryOperation {
+- NoOp, // no op
+- Malloc, // malloc
+- Realloc, // realloc
+- Free, // free
+- Reserve, // virtual memory reserve
+- Commit, // virtual memory commit
+- ReserveAndCommit, // virtual memory reserve and commit
+- StackAlloc = ReserveAndCommit, // allocate thread stack
+- Type, // assign virtual memory type
+- Uncommit, // virtual memory uncommit
+- Release, // virtual memory release
+- ArenaSize, // set arena size
+- StackRelease // release thread stack
+- };
++ Tracker(enum TrackerType type) : _type(type) { }
++ void record(address addr, size_t size);
++ private:
++ enum TrackerType _type;
++ // Virtual memory tracking data structures are protected by ThreadCritical lock.
++ ThreadCritical _tc;
++};
+
+-
+- protected:
+- Tracker(MemoryOperation op, Thread* thr = NULL);
+-
+- public:
+- void discard();
+-
+- void record(address addr, size_t size = 0, MEMFLAGS flags = mtNone, address pc = NULL);
+- void record(address old_addr, address new_addr, size_t size,
+- MEMFLAGS flags, address pc = NULL);
+-
+- private:
+- bool _need_thread_critical_lock;
+- JavaThread* _java_thread;
+- MemoryOperation _op; // memory operation
+- jint _seq; // reserved sequence number
+- };
+-
+-
++class MemTracker : AllStatic {
+ public:
+- // native memory tracking level
+- enum NMTLevel {
+- NMT_off, // native memory tracking is off
+- NMT_summary, // don't track callsite
+- NMT_detail // track callsite also
+- };
+-
+- enum ShutdownReason {
+- NMT_shutdown_none, // no shutdown requested
+- NMT_shutdown_user, // user requested shutdown
+- NMT_normal, // normal shutdown, process exit
+- NMT_out_of_memory, // shutdown due to out of memory
+- NMT_initialization, // shutdown due to initialization failure
+- NMT_use_malloc_only, // can not combine NMT with UseMallocOnly flag
+- NMT_error_reporting, // shutdown by vmError::report_and_die()
+- NMT_out_of_generation, // running out of generation queue
+- NMT_sequence_overflow // overflow the sequence number
+- };
+-
+- public:
+- // initialize NMT tracking level from command line options, called
+- // from VM command line parsing code
+- static void init_tracking_options(const char* option_line);
+-
+- // if NMT is enabled to record memory activities
+- static inline bool is_on() {
+- return (_tracking_level >= NMT_summary &&
+- _state >= NMT_bootstrapping_single_thread);
+- }
+-
+- static inline enum NMTLevel tracking_level() {
++ static inline NMT_TrackingLevel tracking_level() {
++ if (_tracking_level == NMT_unknown) {
++ // No fencing is needed here, since JVM is in single-threaded
++ // mode.
++ _tracking_level = init_tracking_level();
++ _cmdline_tracking_level = _tracking_level;
++ }
+ return _tracking_level;
+ }
+
+- // user readable reason for shutting down NMT
+- static const char* reason() {
+- switch(_reason) {
+- case NMT_shutdown_none:
+- return "Native memory tracking is not enabled";
+- case NMT_shutdown_user:
+- return "Native memory tracking has been shutdown by user";
+- case NMT_normal:
+- return "Native memory tracking has been shutdown due to process exiting";
+- case NMT_out_of_memory:
+- return "Native memory tracking has been shutdown due to out of native memory";
+- case NMT_initialization:
+- return "Native memory tracking failed to initialize";
+- case NMT_error_reporting:
+- return "Native memory tracking has been shutdown due to error reporting";
+- case NMT_out_of_generation:
+- return "Native memory tracking has been shutdown due to running out of generation buffer";
+- case NMT_sequence_overflow:
+- return "Native memory tracking has been shutdown due to overflow the sequence number";
+- case NMT_use_malloc_only:
+- return "Native memory tracking is not supported when UseMallocOnly is on";
+- default:
+- ShouldNotReachHere();
+- return NULL;
++ // A late initialization, for the stuff(s) can not be
++ // done in init_tracking_level(), which can NOT malloc
++ // any memory.
++ static void init();
++
++ // Shutdown native memory tracking
++ static void shutdown();
++
++ // Verify native memory tracking command line option.
++ // This check allows JVM to detect if compatible launcher
++ // is used.
++ // If an incompatible launcher is used, NMT may not be
++ // able to start, even it is enabled by command line option.
++ // A warning message should be given if it is encountered.
++ static bool check_launcher_nmt_support(const char* value);
++
++ // This method checks native memory tracking environment
++ // variable value passed by launcher.
++ // Launcher only obligates to pass native memory tracking
++ // option value, but not obligates to validate the value,
++ // and launcher has option to discard native memory tracking
++ // option from the command line once it sets up the environment
++ // variable, so NMT has to catch the bad value here.
++ static bool verify_nmt_option();
++
++ // Transition the tracking level to specified level
++ static bool transition_to(NMT_TrackingLevel level);
++
++ static inline void* record_malloc(void* mem_base, size_t size, MEMFLAGS flag,
++ const NativeCallStack& stack, NMT_TrackingLevel level) {
++ return MallocTracker::record_malloc(mem_base, size, flag, stack, level);
++ }
++
++ static inline size_t malloc_header_size(NMT_TrackingLevel level) {
++ return MallocTracker::malloc_header_size(level);
++ }
++
++ static size_t malloc_header_size(void* memblock) {
++ if (tracking_level() != NMT_off) {
++ return MallocTracker::get_header_size(memblock);
++ }
++ return 0;
++ }
++
++ // To malloc base address, which is the starting address
++ // of malloc tracking header if tracking is enabled.
++ // Otherwise, it returns the same address.
++ static void* malloc_base(void* memblock);
++
++ // Record malloc free and return malloc base address
++ static inline void* record_free(void* memblock) {
++ return MallocTracker::record_free(memblock);
++ }
++
++
++ // Record creation of an arena
++ static inline void record_new_arena(MEMFLAGS flag) {
++ if (tracking_level() < NMT_summary) return;
++ MallocTracker::record_new_arena(flag);
++ }
++
++ // Record destruction of an arena
++ static inline void record_arena_free(MEMFLAGS flag) {
++ if (tracking_level() < NMT_summary) return;
++ MallocTracker::record_arena_free(flag);
++ }
++
++ // Record arena size change. Arena size is the size of all arena
++ // chuncks that backing up the arena.
++ static inline void record_arena_size_change(int diff, MEMFLAGS flag) {
++ if (tracking_level() < NMT_summary) return;
++ MallocTracker::record_arena_size_change(diff, flag);
++ }
++
++ static inline void record_virtual_memory_reserve(void* addr, size_t size, const NativeCallStack& stack,
++ MEMFLAGS flag = mtNone) {
++ if (tracking_level() < NMT_summary) return;
++ if (addr != NULL) {
++ ThreadCritical tc;
++ // Recheck to avoid potential racing during NMT shutdown
++ if (tracking_level() < NMT_summary) return;
++ VirtualMemoryTracker::add_reserved_region((address)addr, size, stack, flag);
+ }
+ }
+
+- // test if we can walk native stack
+- static bool can_walk_stack() {
+- // native stack is not walkable during bootstrapping on sparc
+-#if defined(SPARC)
+- return (_state == NMT_started);
+-#else
+- return (_state >= NMT_bootstrapping_single_thread && _state <= NMT_started);
+-#endif
+- }
+-
+- // if native memory tracking tracks callsite
+- static inline bool track_callsite() { return _tracking_level == NMT_detail; }
+-
+- // NMT automatically shuts itself down under extreme situation by default.
+- // When the value is set to false, NMT will try its best to stay alive,
+- // even it has to slow down VM.
+- static inline void set_autoShutdown(bool value) {
+- AutoShutdownNMT = value;
+- if (AutoShutdownNMT && _slowdown_calling_thread) {
+- _slowdown_calling_thread = false;
++ static inline void record_virtual_memory_reserve_and_commit(void* addr, size_t size,
++ const NativeCallStack& stack, MEMFLAGS flag = mtNone) {
++ if (tracking_level() < NMT_summary) return;
++ if (addr != NULL) {
++ ThreadCritical tc;
++ if (tracking_level() < NMT_summary) return;
++ VirtualMemoryTracker::add_reserved_region((address)addr, size,
++ stack, flag, true);
+ }
+ }
+
+- // shutdown native memory tracking capability. Native memory tracking
+- // can be shutdown by VM when it encounters low memory scenarios.
+- // Memory tracker should gracefully shutdown itself, and preserve the
+- // latest memory statistics for post morten diagnosis.
+- static void shutdown(ShutdownReason reason);
+-
+- // if there is shutdown requested
+- static inline bool shutdown_in_progress() {
+- return (_state >= NMT_shutdown_pending);
+- }
+-
+- // bootstrap native memory tracking, so it can start to collect raw data
+- // before worker thread can start
+-
+- // the first phase of bootstrapping, when VM still in single-threaded mode
+- static void bootstrap_single_thread();
+- // the second phase of bootstrapping, VM is about or already in multi-threaded mode
+- static void bootstrap_multi_thread();
+-
+-
+- // start() has to be called when VM still in single thread mode, but after
+- // command line option parsing is done.
+- static void start();
+-
+- // record a 'malloc' call
+- static inline void record_malloc(address addr, size_t size, MEMFLAGS flags,
+- address pc = 0, Thread* thread = NULL) {
+- Tracker tkr(Tracker::Malloc, thread);
+- tkr.record(addr, size, flags, pc);
+- }
+- // record a 'free' call
+- static inline void record_free(address addr, MEMFLAGS flags, Thread* thread = NULL) {
+- Tracker tkr(Tracker::Free, thread);
+- tkr.record(addr, 0, flags, DEBUG_CALLER_PC);
+- }
+-
+- static inline void record_arena_size(address addr, size_t size) {
+- Tracker tkr(Tracker::ArenaSize);
+- tkr.record(addr, size);
+- }
+-
+- // record a virtual memory 'reserve' call
+- static inline void record_virtual_memory_reserve(address addr, size_t size,
+- MEMFLAGS flags, address pc = 0, Thread* thread = NULL) {
+- assert(size > 0, "Sanity check");
+- Tracker tkr(Tracker::Reserve, thread);
+- tkr.record(addr, size, flags, pc);
+- }
+-
+- static inline void record_thread_stack(address addr, size_t size, Thread* thr,
+- address pc = 0) {
+- Tracker tkr(Tracker::StackAlloc, thr);
+- tkr.record(addr, size, mtThreadStack, pc);
+- }
+-
+- static inline void release_thread_stack(address addr, size_t size, Thread* thr) {
+- Tracker tkr(Tracker::StackRelease, thr);
+- tkr.record(addr, size, mtThreadStack, DEBUG_CALLER_PC);
+- }
+-
+- // record a virtual memory 'commit' call
+- static inline void record_virtual_memory_commit(address addr, size_t size,
+- address pc, Thread* thread = NULL) {
+- Tracker tkr(Tracker::Commit, thread);
+- tkr.record(addr, size, mtNone, pc);
+- }
+-
+- static inline void record_virtual_memory_reserve_and_commit(address addr, size_t size,
+- MEMFLAGS flags, address pc, Thread* thread = NULL) {
+- Tracker tkr(Tracker::ReserveAndCommit, thread);
+- tkr.record(addr, size, flags, pc);
+- }
+-
+- static inline void record_virtual_memory_release(address addr, size_t size,
+- Thread* thread = NULL) {
+- if (is_on()) {
+- Tracker tkr(Tracker::Release, thread);
+- tkr.record(addr, size);
++ static inline void record_virtual_memory_commit(void* addr, size_t size,
++ const NativeCallStack& stack) {
++ if (tracking_level() < NMT_summary) return;
++ if (addr != NULL) {
++ ThreadCritical tc;
++ if (tracking_level() < NMT_summary) return;
++ VirtualMemoryTracker::add_committed_region((address)addr, size, stack);
+ }
+ }
+
+- // record memory type on virtual memory base address
+- static inline void record_virtual_memory_type(address base, MEMFLAGS flags,
+- Thread* thread = NULL) {
+- Tracker tkr(Tracker::Type);
+- tkr.record(base, 0, flags);
+- }
+-
+- // Get memory trackers for memory operations that can result race conditions.
+- // The memory tracker has to be obtained before realloc, virtual memory uncommit
+- // and virtual memory release, and call tracker.record() method if operation
+- // succeeded, or tracker.discard() to abort the tracking.
+- static inline Tracker get_realloc_tracker() {
+- return Tracker(Tracker::Realloc);
+- }
+-
+ static inline Tracker get_virtual_memory_uncommit_tracker() {
+- return Tracker(Tracker::Uncommit);
++ assert(tracking_level() >= NMT_summary, "Check by caller");
++ return Tracker(Tracker::uncommit);
+ }
+
+ static inline Tracker get_virtual_memory_release_tracker() {
+- return Tracker(Tracker::Release);
++ assert(tracking_level() >= NMT_summary, "Check by caller");
++ return Tracker(Tracker::release);
+ }
+
+-
+- // create memory baseline of current memory snapshot
+- static bool baseline();
+- // is there a memory baseline
+- static bool has_baseline() {
+- return _baseline.baselined();
+- }
+-
+- // print memory usage from current snapshot
+- static bool print_memory_usage(BaselineOutputer& out, size_t unit,
+- bool summary_only = true);
+- // compare memory usage between current snapshot and baseline
+- static bool compare_memory_usage(BaselineOutputer& out, size_t unit,
+- bool summary_only = true);
+-
+- // the version for whitebox testing support, it ensures that all memory
+- // activities before this method call, are reflected in the snapshot
+- // database.
+- static bool wbtest_wait_for_data_merge();
+-
+- // sync is called within global safepoint to synchronize nmt data
+- static void sync();
+-
+- // called when a thread is about to exit
+- static void thread_exiting(JavaThread* thread);
+-
+- // retrieve global snapshot
+- static MemSnapshot* get_snapshot() {
+- if (shutdown_in_progress()) {
+- return NULL;
+- }
+- return _snapshot;
+- }
+-
+- // print tracker stats
+- NOT_PRODUCT(static void print_tracker_stats(outputStream* st);)
+- NOT_PRODUCT(static void walk_stack(int toSkip, char* buf, int len);)
+-
+- private:
+- // start native memory tracking worker thread
+- static bool start_worker(MemSnapshot* snapshot);
+-
+- // called by worker thread to complete shutdown process
+- static void final_shutdown();
+-
+- protected:
+- // retrieve per-thread recorder of the specified thread.
+- // if the recorder is full, it will be enqueued to overflow
+- // queue, a new recorder is acquired from recorder pool or a
+- // new instance is created.
+- // when thread == NULL, it means global recorder
+- static MemRecorder* get_thread_recorder(JavaThread* thread);
+-
+- // per-thread recorder pool
+- static void release_thread_recorder(MemRecorder* rec);
+- static void delete_all_pooled_recorders();
+-
+- // pending recorder queue. Recorders are queued to pending queue
+- // when they are overflowed or collected at nmt sync point.
+- static void enqueue_pending_recorder(MemRecorder* rec);
+- static MemRecorder* get_pending_recorders();
+- static void delete_all_pending_recorders();
+-
+- // write a memory tracking record in recorder
+- static void write_tracking_record(address addr, MEMFLAGS type,
+- size_t size, jint seq, address pc, JavaThread* thread);
+-
+- static bool is_single_threaded_bootstrap() {
+- return _state == NMT_bootstrapping_single_thread;
+- }
+-
+- static void check_NMT_load(Thread* thr) {
+- assert(thr != NULL, "Sanity check");
+- if (_slowdown_calling_thread && thr != _worker_thread) {
+-#ifdef _WINDOWS
+- // On Windows, os::NakedYield() does not work as well
+- // as os::yield_all()
+- os::yield_all();
+-#else
+- // On Solaris, os::yield_all() depends on os::sleep()
+- // which requires JavaTherad in _thread_in_vm state.
+- // Transits thread to _thread_in_vm state can be dangerous
+- // if caller holds lock, as it may deadlock with Threads_lock.
+- // So use NaKedYield instead.
+- //
+- // Linux and BSD, NakedYield() and yield_all() implementations
+- // are the same.
+- os::NakedYield();
+-#endif
++ static inline void record_virtual_memory_type(void* addr, MEMFLAGS flag) {
++ if (tracking_level() < NMT_summary) return;
++ if (addr != NULL) {
++ ThreadCritical tc;
++ if (tracking_level() < NMT_summary) return;
++ VirtualMemoryTracker::set_reserved_region_type((address)addr, flag);
+ }
+ }
+
+- static void inc_pending_op_count() {
+- Atomic::inc(&_pending_op_count);
++ static inline void record_thread_stack(void* addr, size_t size) {
++ if (tracking_level() < NMT_summary) return;
++ if (addr != NULL) {
++ // uses thread stack malloc slot for book keeping number of threads
++ MallocMemorySummary::record_malloc(0, mtThreadStack);
++ record_virtual_memory_reserve_and_commit(addr, size, CALLER_PC, mtThreadStack);
++ }
+ }
+
+- static void dec_pending_op_count() {
+- Atomic::dec(&_pending_op_count);
+- assert(_pending_op_count >= 0, "Sanity check");
++ static inline void release_thread_stack(void* addr, size_t size) {
++ if (tracking_level() < NMT_summary) return;
++ if (addr != NULL) {
++ // uses thread stack malloc slot for book keeping number of threads
++ MallocMemorySummary::record_free(0, mtThreadStack);
++ ThreadCritical tc;
++ if (tracking_level() < NMT_summary) return;
++ VirtualMemoryTracker::remove_released_region((address)addr, size);
++ }
+ }
+
++ // Query lock is used to synchronize the access to tracking data.
++ // So far, it is only used by JCmd query, but it may be used by
++ // other tools.
++ static inline Mutex* query_lock() { return _query_lock; }
++
++ // Make a final report or report for hs_err file.
++ static void error_report(outputStream* output) {
++ if (tracking_level() >= NMT_summary) {
++ report(true, output); // just print summary for error case.
++ }
++ }
++
++ static void final_report(outputStream* output) {
++ NMT_TrackingLevel level = tracking_level();
++ if (level >= NMT_summary) {
++ report(level == NMT_summary, output);
++ }
++ }
++
++
++ // Stored baseline
++ static inline MemBaseline& get_baseline() {
++ return _baseline;
++ }
++
++ static NMT_TrackingLevel cmdline_tracking_level() {
++ return _cmdline_tracking_level;
++ }
++
++ static void tuning_statistics(outputStream* out);
+
+ private:
+- // retrieve a pooled memory record or create new one if there is not
+- // one available
+- static MemRecorder* get_new_or_pooled_instance();
+- static void create_memory_record(address addr, MEMFLAGS type,
+- size_t size, address pc, Thread* thread);
+- static void create_record_in_recorder(address addr, MEMFLAGS type,
+- size_t size, address pc, JavaThread* thread);
+-
+- static void set_current_processing_generation(unsigned long generation) {
+- _worker_thread_idle = false;
+- _processing_generation = generation;
+- }
+-
+- static void report_worker_idle() {
+- _worker_thread_idle = true;
+- }
++ static NMT_TrackingLevel init_tracking_level();
++ static void report(bool summary_only, outputStream* output);
+
+ private:
+- // global memory snapshot
+- static MemSnapshot* _snapshot;
+-
+- // a memory baseline of snapshot
++ // Tracking level
++ static volatile NMT_TrackingLevel _tracking_level;
++ // If NMT option value passed by launcher through environment
++ // variable is valid
++ static bool _is_nmt_env_valid;
++ // command line tracking level
++ static NMT_TrackingLevel _cmdline_tracking_level;
++ // Stored baseline
+ static MemBaseline _baseline;
+-
+- // query lock
++ // Query lock
+ static Mutex* _query_lock;
+-
+- // a thread can start to allocate memory before it is attached
+- // to VM 'Thread', those memory activities are recorded here.
+- // ThreadCritical is required to guard this global recorder.
+- static MemRecorder* volatile _global_recorder;
+-
+- // main thread id
+- debug_only(static intx _main_thread_tid;)
+-
+- // pending recorders to be merged
+- static MemRecorder* volatile _merge_pending_queue;
+-
+- NOT_PRODUCT(static volatile jint _pending_recorder_count;)
+-
+- // pooled memory recorders
+- static MemRecorder* volatile _pooled_recorders;
+-
+- // memory recorder pool management, uses following
+- // counter to determine if a released memory recorder
+- // should be pooled
+-
+- // latest thread count
+- static int _thread_count;
+- // pooled recorder count
+- static volatile jint _pooled_recorder_count;
+-
+-
+- // worker thread to merge pending recorders into snapshot
+- static MemTrackWorker* _worker_thread;
+-
+- // how many safepoints we skipped without entering sync point
+- static int _sync_point_skip_count;
+-
+- // if the tracker is properly intialized
+- static bool _is_tracker_ready;
+- // tracking level (off, summary and detail)
+- static enum NMTLevel _tracking_level;
+-
+- // current nmt state
+- static volatile enum NMTStates _state;
+- // the reason for shutting down nmt
+- static enum ShutdownReason _reason;
+- // the generation that NMT is processing
+- static volatile unsigned long _processing_generation;
+- // although NMT is still procesing current generation, but
+- // there is not more recorder to process, set idle state
+- static volatile bool _worker_thread_idle;
+-
+- // if NMT should slow down calling thread to allow
+- // worker thread to catch up
+- static volatile bool _slowdown_calling_thread;
+-
+- // pending memory op count.
+- // Certain memory ops need to pre-reserve sequence number
+- // before memory operation can happen to avoid race condition.
+- // See MemTracker::Tracker for detail
+- static volatile jint _pending_op_count;
+ };
+
+-#endif // !INCLUDE_NMT
++#endif // INCLUDE_NMT
+
+ #endif // SHARE_VM_SERVICES_MEM_TRACKER_HPP
++
+--- ./hotspot/src/share/vm/services/memoryManager.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/services/memoryManager.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,6 +28,7 @@
+ #include "oops/oop.inline.hpp"
+ #include "runtime/handles.inline.hpp"
+ #include "runtime/javaCalls.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "services/lowMemoryDetector.hpp"
+ #include "services/management.hpp"
+ #include "services/memoryManager.hpp"
+--- ./hotspot/src/share/vm/services/memoryPool.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/services/memoryPool.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -29,6 +29,7 @@
+ #include "oops/oop.inline.hpp"
+ #include "runtime/handles.inline.hpp"
+ #include "runtime/javaCalls.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "services/lowMemoryDetector.hpp"
+ #include "services/management.hpp"
+ #include "services/memoryManager.hpp"
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/services/nmtCommon.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,73 @@
++/*
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++#include "precompiled.hpp"
++#include "services/nmtCommon.hpp"
++
++const char* NMTUtil::_memory_type_names[] = {
++ "Java Heap",
++ "Class",
++ "Thread",
++ "Thread Stack",
++ "Code",
++ "GC",
++ "Compiler",
++ "Internal",
++ "Other",
++ "Symbol",
++ "Native Memory Tracking",
++ "Shared class space",
++ "Arena Chunk",
++ "Test",
++ "Tracing",
++ "Unknown"
++};
++
++
++const char* NMTUtil::scale_name(size_t scale) {
++ switch(scale) {
++ case K: return "KB";
++ case M: return "MB";
++ case G: return "GB";
++ }
++ ShouldNotReachHere();
++ return NULL;
++}
++
++size_t NMTUtil::scale_from_name(const char* scale) {
++ assert(scale != NULL, "Null pointer check");
++ if (strncmp(scale, "KB", 2) == 0 ||
++ strncmp(scale, "kb", 2) == 0) {
++ return K;
++ } else if (strncmp(scale, "MB", 2) == 0 ||
++ strncmp(scale, "mb", 2) == 0) {
++ return M;
++ } else if (strncmp(scale, "GB", 2) == 0 ||
++ strncmp(scale, "gb", 2) == 0) {
++ return G;
++ } else {
++ return 0; // Invalid value
++ }
++ return K;
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/services/nmtCommon.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,84 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_SERVICES_NMT_COMMON_HPP
++#define SHARE_VM_SERVICES_NMT_COMMON_HPP
++
++#include "memory/allocation.hpp"
++#include "utilities/globalDefinitions.hpp"
++
++#define CALC_OBJ_SIZE_IN_TYPE(obj, type) (align_size_up_(sizeof(obj), sizeof(type))/sizeof(type))
++
++// Data type for memory counters
++#ifdef _LP64
++ typedef jlong MemoryCounterType;
++#else
++ typedef jint MemoryCounterType;
++#endif
++
++// Native memory tracking level
++enum NMT_TrackingLevel {
++ NMT_unknown = 0xFF,
++ NMT_off = 0x00,
++ NMT_minimal = 0x01,
++ NMT_summary = 0x02,
++ NMT_detail = 0x03
++};
++
++// Number of stack frames to capture. This is a
++// build time decision.
++const int NMT_TrackingStackDepth = 4;
++
++// A few common utilities for native memory tracking
++class NMTUtil : AllStatic {
++ public:
++ // Map memory type to index
++ static inline int flag_to_index(MEMFLAGS flag) {
++ return (flag & 0xff);
++ }
++
++ // Map memory type to human readable name
++ static const char* flag_to_name(MEMFLAGS flag) {
++ return _memory_type_names[flag_to_index(flag)];
++ }
++
++ // Map an index to memory type
++ static MEMFLAGS index_to_flag(int index) {
++ return (MEMFLAGS)index;
++ }
++
++ // Memory size scale
++ static const char* scale_name(size_t scale);
++ static size_t scale_from_name(const char* scale);
++
++ // Translate memory size in specified scale
++ static size_t amount_in_scale(size_t amount, size_t scale) {
++ return (amount + scale / 2) / scale;
++ }
++ private:
++ static const char* _memory_type_names[mt_number_of_types];
++};
++
++
++#endif
+--- ./hotspot/src/share/vm/services/nmtDCmd.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/services/nmtDCmd.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -22,6 +22,8 @@
+ *
+ */
+ #include "precompiled.hpp"
++
++#include "runtime/mutexLocker.hpp"
+ #include "services/nmtDCmd.hpp"
+ #include "services/memReporter.hpp"
+ #include "services/memTracker.hpp"
+@@ -49,13 +51,8 @@
+ _shutdown("shutdown", "request runtime to shutdown itself and free the " \
+ "memory used by runtime.",
+ "BOOLEAN", false, "false"),
+- _auto_shutdown("autoShutdown", "automatically shutdown itself under " \
+- "stress situation",
+- "BOOLEAN", true, "true"),
+-#ifndef PRODUCT
+- _debug("debug", "print tracker statistics. Debug only, not thread safe", \
++ _statistics("statistics", "print tracker statistics for tuning purpose.", \
+ "BOOLEAN", false, "false"),
+-#endif
+ _scale("scale", "Memory usage in which scale, KB, MB or GB",
+ "STRING", false, "KB") {
+ _dcmdparser.add_dcmd_option(&_summary);
+@@ -64,25 +61,30 @@
+ _dcmdparser.add_dcmd_option(&_summary_diff);
+ _dcmdparser.add_dcmd_option(&_detail_diff);
+ _dcmdparser.add_dcmd_option(&_shutdown);
+- _dcmdparser.add_dcmd_option(&_auto_shutdown);
+-#ifndef PRODUCT
+- _dcmdparser.add_dcmd_option(&_debug);
+-#endif
++ _dcmdparser.add_dcmd_option(&_statistics);
+ _dcmdparser.add_dcmd_option(&_scale);
+ }
+
++
++size_t NMTDCmd::get_scale(const char* scale) const {
++ if (scale == NULL) return 0;
++ return NMTUtil::scale_from_name(scale);
++}
++
+ void NMTDCmd::execute(DCmdSource source, TRAPS) {
++ // Check NMT state
++ // native memory tracking has to be on
++ if (MemTracker::tracking_level() == NMT_off) {
++ output()->print_cr("Native memory tracking is not enabled");
++ return;
++ } else if (MemTracker::tracking_level() == NMT_minimal) {
++ output()->print_cr("Native memory tracking has been shutdown");
++ return;
++ }
++
+ const char* scale_value = _scale.value();
+- size_t scale_unit;
+- if (strcmp(scale_value, "KB") == 0 || strcmp(scale_value, "kb") == 0) {
+- scale_unit = K;
+- } else if (strcmp(scale_value, "MB") == 0 ||
+- strcmp(scale_value, "mb") == 0) {
+- scale_unit = M;
+- } else if (strcmp(scale_value, "GB") == 0 ||
+- strcmp(scale_value, "gb") == 0) {
+- scale_unit = G;
+- } else {
++ size_t scale_unit = get_scale(scale_value);
++ if (scale_unit == 0) {
+ output()->print_cr("Incorrect scale value: %s", scale_value);
+ return;
+ }
+@@ -94,19 +96,11 @@
+ if (_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
+ if (_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
+ if (_shutdown.is_set() && _shutdown.value()) { ++nopt; }
+- if (_auto_shutdown.is_set()) { ++nopt; }
+-
+-#ifndef PRODUCT
+- if (_debug.is_set() && _debug.value()) { ++nopt; }
+-#endif
++ if (_statistics.is_set() && _statistics.value()) { ++nopt; }
+
+ if (nopt > 1) {
+ output()->print_cr("At most one of the following option can be specified: " \
+- "summary, detail, baseline, summary.diff, detail.diff, shutdown"
+-#ifndef PRODUCT
+- ", debug"
+-#endif
+- );
++ "summary, detail, baseline, summary.diff, detail.diff, shutdown");
+ return;
+ } else if (nopt == 0) {
+ if (_summary.is_set()) {
+@@ -117,53 +111,47 @@
+ }
+ }
+
+-#ifndef PRODUCT
+- if (_debug.value()) {
+- output()->print_cr("debug command is NOT thread-safe, may cause crash");
+- MemTracker::print_tracker_stats(output());
++ // Serialize NMT query
++ MutexLocker locker(MemTracker::query_lock());
++
++ if (_summary.value()) {
++ report(true, scale_unit);
++ } else if (_detail.value()) {
++ if (!check_detail_tracking_level(output())) {
+ return;
+ }
+-#endif
+-
+- // native memory tracking has to be on
+- if (!MemTracker::is_on() || MemTracker::shutdown_in_progress()) {
+- // if it is not on, what's the reason?
+- output()->print_cr("%s", MemTracker::reason());
++ report(false, scale_unit);
++ } else if (_baseline.value()) {
++ MemBaseline& baseline = MemTracker::get_baseline();
++ if (!baseline.baseline(MemTracker::tracking_level() != NMT_detail)) {
++ output()->print_cr("Baseline failed");
++ } else {
++ output()->print_cr("Baseline succeeded");
++ }
++ } else if (_summary_diff.value()) {
++ MemBaseline& baseline = MemTracker::get_baseline();
++ if (baseline.baseline_type() >= MemBaseline::Summary_baselined) {
++ report_diff(true, scale_unit);
++ } else {
++ output()->print_cr("No baseline for comparison");
++ }
++ } else if (_detail_diff.value()) {
++ if (!check_detail_tracking_level(output())) {
+ return;
+ }
+-
+- if (_summary.value()) {
+- BaselineTTYOutputer outputer(output());
+- MemTracker::print_memory_usage(outputer, scale_unit, true);
+- } else if (_detail.value()) {
+- BaselineTTYOutputer outputer(output());
+- MemTracker::print_memory_usage(outputer, scale_unit, false);
+- } else if (_baseline.value()) {
+- if (MemTracker::baseline()) {
+- output()->print_cr("Successfully baselined.");
++ MemBaseline& baseline = MemTracker::get_baseline();
++ if (baseline.baseline_type() == MemBaseline::Detail_baselined) {
++ report_diff(false, scale_unit);
+ } else {
+- output()->print_cr("Baseline failed.");
+- }
+- } else if (_summary_diff.value()) {
+- if (MemTracker::has_baseline()) {
+- BaselineTTYOutputer outputer(output());
+- MemTracker::compare_memory_usage(outputer, scale_unit, true);
+- } else {
+- output()->print_cr("No baseline to compare, run 'baseline' command first");
+- }
+- } else if (_detail_diff.value()) {
+- if (MemTracker::has_baseline()) {
+- BaselineTTYOutputer outputer(output());
+- MemTracker::compare_memory_usage(outputer, scale_unit, false);
+- } else {
+- output()->print_cr("No baseline to compare to, run 'baseline' command first");
++ output()->print_cr("No detail baseline for comparison");
+ }
+ } else if (_shutdown.value()) {
+- MemTracker::shutdown(MemTracker::NMT_shutdown_user);
+- output()->print_cr("Shutdown is in progress, it will take a few moments to " \
+- "completely shutdown");
+- } else if (_auto_shutdown.is_set()) {
+- MemTracker::set_autoShutdown(_auto_shutdown.value());
++ MemTracker::shutdown();
++ output()->print_cr("Native memory tracking has been turned off");
++ } else if (_statistics.value()) {
++ if (check_detail_tracking_level(output())) {
++ MemTracker::tuning_statistics(output());
++ }
+ } else {
+ ShouldNotReachHere();
+ output()->print_cr("Unknown command");
+@@ -181,3 +169,46 @@
+ }
+ }
+
++void NMTDCmd::report(bool summaryOnly, size_t scale_unit) {
++ MemBaseline baseline;
++ if (baseline.baseline(summaryOnly)) {
++ if (summaryOnly) {
++ MemSummaryReporter rpt(baseline, output(), scale_unit);
++ rpt.report();
++ } else {
++ MemDetailReporter rpt(baseline, output(), scale_unit);
++ rpt.report();
++ }
++ }
++}
++
++void NMTDCmd::report_diff(bool summaryOnly, size_t scale_unit) {
++ MemBaseline& early_baseline = MemTracker::get_baseline();
++ assert(early_baseline.baseline_type() != MemBaseline::Not_baselined,
++ "Not yet baselined");
++ assert(summaryOnly || early_baseline.baseline_type() == MemBaseline::Detail_baselined,
++ "Not a detail baseline");
++
++ MemBaseline baseline;
++ if (baseline.baseline(summaryOnly)) {
++ if (summaryOnly) {
++ MemSummaryDiffReporter rpt(early_baseline, baseline, output(), scale_unit);
++ rpt.report_diff();
++ } else {
++ MemDetailDiffReporter rpt(early_baseline, baseline, output(), scale_unit);
++ rpt.report_diff();
++ }
++ }
++}
++
++bool NMTDCmd::check_detail_tracking_level(outputStream* out) {
++ if (MemTracker::tracking_level() == NMT_detail) {
++ return true;
++ } else if (MemTracker::cmdline_tracking_level() == NMT_detail) {
++ out->print_cr("Tracking level has been downgraded due to lack of resources");
++ return false;
++ } else {
++ out->print_cr("Detail tracking is not enabled");
++ return false;
++ }
++}
+--- ./hotspot/src/share/vm/services/nmtDCmd.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/services/nmtDCmd.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -25,8 +25,12 @@
+ #ifndef SHARE_VM_SERVICES_NMT_DCMD_HPP
+ #define SHARE_VM_SERVICES_NMT_DCMD_HPP
+
++#if INCLUDE_NMT
++
+ #include "services/diagnosticArgument.hpp"
+ #include "services/diagnosticFramework.hpp"
++#include "services/memBaseline.hpp"
++#include "services/mallocTracker.hpp"
+
+ /**
+ * Native memory tracking DCmd implementation
+@@ -39,10 +43,7 @@
+ DCmdArgument<bool> _summary_diff;
+ DCmdArgument<bool> _detail_diff;
+ DCmdArgument<bool> _shutdown;
+- DCmdArgument<bool> _auto_shutdown;
+-#ifndef PRODUCT
+- DCmdArgument<bool> _debug;
+-#endif
++ DCmdArgument<bool> _statistics;
+ DCmdArgument<char*> _scale;
+
+ public:
+@@ -61,6 +62,17 @@
+ }
+ static int num_arguments();
+ virtual void execute(DCmdSource source, TRAPS);
++
++ private:
++ void report(bool summaryOnly, size_t scale);
++ void report_diff(bool summaryOnly, size_t scale);
++
++ size_t get_scale(const char* scale) const;
++
++ // check if NMT running at detail tracking level
++ bool check_detail_tracking_level(outputStream* out);
+ };
+
++#endif // INCLUDE_NMT
++
+ #endif // SHARE_VM_SERVICES_NMT_DCMD_HPP
+--- ./hotspot/src/share/vm/services/runtimeService.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/services/runtimeService.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -46,6 +46,7 @@
+ PerfCounter* RuntimeService::_thread_interrupt_signaled_count = NULL;
+ PerfCounter* RuntimeService::_interrupted_before_count = NULL;
+ PerfCounter* RuntimeService::_interrupted_during_count = NULL;
++double RuntimeService::_last_safepoint_sync_time_sec = 0.0;
+
+ void RuntimeService::init() {
+ // Make sure the VM version is initialized
+@@ -128,6 +129,7 @@
+
+ // update the time stamp to begin recording safepoint time
+ _safepoint_timer.update();
++ _last_safepoint_sync_time_sec = 0.0;
+ if (UsePerfData) {
+ _total_safepoints->inc();
+ if (_app_timer.is_updated()) {
+@@ -140,6 +142,9 @@
+ if (UsePerfData) {
+ _sync_time_ticks->inc(_safepoint_timer.ticks_since_update());
+ }
++ if (PrintGCApplicationStoppedTime) {
++ _last_safepoint_sync_time_sec = last_safepoint_time_sec();
++ }
+ }
+
+ void RuntimeService::record_safepoint_end() {
+@@ -155,8 +160,10 @@
+ gclog_or_tty->date_stamp(PrintGCDateStamps);
+ gclog_or_tty->stamp(PrintGCTimeStamps);
+ gclog_or_tty->print_cr("Total time for which application threads "
+- "were stopped: %3.7f seconds",
+- last_safepoint_time_sec());
++ "were stopped: %3.7f seconds, "
++ "Stopping threads took: %3.7f seconds",
++ last_safepoint_time_sec(),
++ _last_safepoint_sync_time_sec);
+ }
+
+ // update the time stamp to begin recording app time
+--- ./hotspot/src/share/vm/services/runtimeService.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/services/runtimeService.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -40,6 +40,7 @@
+
+ static TimeStamp _safepoint_timer;
+ static TimeStamp _app_timer;
++ static double _last_safepoint_sync_time_sec;
+
+ public:
+ static void init();
+--- ./hotspot/src/share/vm/services/threadService.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/services/threadService.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -33,6 +33,7 @@
+ #include "runtime/init.hpp"
+ #include "runtime/thread.hpp"
+ #include "runtime/vframe.hpp"
++#include "runtime/thread.inline.hpp"
+ #include "runtime/vmThread.hpp"
+ #include "runtime/vm_operations.hpp"
+ #include "services/threadService.hpp"
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/services/virtualMemoryTracker.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,477 @@
++/*
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++#include "precompiled.hpp"
++
++#include "runtime/threadCritical.hpp"
++#include "services/virtualMemoryTracker.hpp"
++
++size_t VirtualMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(VirtualMemorySnapshot, size_t)];
++
++void VirtualMemorySummary::initialize() {
++ assert(sizeof(_snapshot) >= sizeof(VirtualMemorySnapshot), "Sanity Check");
++ // Use placement operator new to initialize static data area.
++ ::new ((void*)_snapshot) VirtualMemorySnapshot();
++}
++
++SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>* VirtualMemoryTracker::_reserved_regions;
++
++int compare_committed_region(const CommittedMemoryRegion& r1, const CommittedMemoryRegion& r2) {
++ return r1.compare(r2);
++}
++
++int compare_reserved_region_base(const ReservedMemoryRegion& r1, const ReservedMemoryRegion& r2) {
++ return r1.compare(r2);
++}
++
++bool ReservedMemoryRegion::add_committed_region(address addr, size_t size, const NativeCallStack& stack) {
++ assert(addr != NULL, "Invalid address");
++ assert(size > 0, "Invalid size");
++ assert(contain_region(addr, size), "Not contain this region");
++
++ if (all_committed()) return true;
++
++ CommittedMemoryRegion committed_rgn(addr, size, stack);
++ LinkedListNode<CommittedMemoryRegion>* node = _committed_regions.find_node(committed_rgn);
++ if (node != NULL) {
++ CommittedMemoryRegion* rgn = node->data();
++ if (rgn->same_region(addr, size)) {
++ return true;
++ }
++
++ if (rgn->adjacent_to(addr, size)) {
++ // check if the next region covers this committed region,
++ // the regions may not be merged due to different call stacks
++ LinkedListNode<CommittedMemoryRegion>* next =
++ node->next();
++ if (next != NULL && next->data()->contain_region(addr, size)) {
++ if (next->data()->same_region(addr, size)) {
++ next->data()->set_call_stack(stack);
++ }
++ return true;
++ }
++ if (rgn->call_stack()->equals(stack)) {
++ VirtualMemorySummary::record_uncommitted_memory(rgn->size(), flag());
++ // the two adjacent regions have the same call stack, merge them
++ rgn->expand_region(addr, size);
++ VirtualMemorySummary::record_committed_memory(rgn->size(), flag());
++ return true;
++ }
++ VirtualMemorySummary::record_committed_memory(size, flag());
++ if (rgn->base() > addr) {
++ return _committed_regions.insert_before(committed_rgn, node) != NULL;
++ } else {
++ return _committed_regions.insert_after(committed_rgn, node) != NULL;
++ }
++ }
++ assert(rgn->contain_region(addr, size), "Must cover this region");
++ return true;
++ } else {
++ // New committed region
++ VirtualMemorySummary::record_committed_memory(size, flag());
++ return add_committed_region(committed_rgn);
++ }
++}
++
++void ReservedMemoryRegion::set_all_committed(bool b) {
++ if (all_committed() != b) {
++ _all_committed = b;
++ if (b) {
++ VirtualMemorySummary::record_committed_memory(size(), flag());
++ }
++ }
++}
++
++bool ReservedMemoryRegion::remove_uncommitted_region(LinkedListNode<CommittedMemoryRegion>* node,
++ address addr, size_t size) {
++ assert(addr != NULL, "Invalid address");
++ assert(size > 0, "Invalid size");
++
++ CommittedMemoryRegion* rgn = node->data();
++ assert(rgn->contain_region(addr, size), "Has to be contained");
++ assert(!rgn->same_region(addr, size), "Can not be the same region");
++
++ if (rgn->base() == addr ||
++ rgn->end() == addr + size) {
++ rgn->exclude_region(addr, size);
++ return true;
++ } else {
++ // split this region
++ address top =rgn->end();
++ // use this region for lower part
++ size_t exclude_size = rgn->end() - addr;
++ rgn->exclude_region(addr, exclude_size);
++
++ // higher part
++ address high_base = addr + size;
++ size_t high_size = top - high_base;
++
++ CommittedMemoryRegion high_rgn(high_base, high_size, *rgn->call_stack());
++ LinkedListNode<CommittedMemoryRegion>* high_node = _committed_regions.add(high_rgn);
++ assert(high_node == NULL || node->next() == high_node, "Should be right after");
++ return (high_node != NULL);
++ }
++
++ return false;
++}
++
++bool ReservedMemoryRegion::remove_uncommitted_region(address addr, size_t sz) {
++ // uncommit stack guard pages
++ if (flag() == mtThreadStack && !same_region(addr, sz)) {
++ return true;
++ }
++
++ assert(addr != NULL, "Invalid address");
++ assert(sz > 0, "Invalid size");
++
++ if (all_committed()) {
++ assert(_committed_regions.is_empty(), "Sanity check");
++ assert(contain_region(addr, sz), "Reserved region does not contain this region");
++ set_all_committed(false);
++ VirtualMemorySummary::record_uncommitted_memory(sz, flag());
++ if (same_region(addr, sz)) {
++ return true;
++ } else {
++ CommittedMemoryRegion rgn(base(), size(), *call_stack());
++ if (rgn.base() == addr || rgn.end() == (addr + sz)) {
++ rgn.exclude_region(addr, sz);
++ return add_committed_region(rgn);
++ } else {
++ // split this region
++ // top of the whole region
++ address top =rgn.end();
++ // use this region for lower part
++ size_t exclude_size = rgn.end() - addr;
++ rgn.exclude_region(addr, exclude_size);
++ if (add_committed_region(rgn)) {
++ // higher part
++ address high_base = addr + sz;
++ size_t high_size = top - high_base;
++ CommittedMemoryRegion high_rgn(high_base, high_size, NativeCallStack::EMPTY_STACK);
++ return add_committed_region(high_rgn);
++ } else {
++ return false;
++ }
++ }
++ }
++ } else {
++ // we have to walk whole list to remove the committed regions in
++ // specified range
++ LinkedListNode<CommittedMemoryRegion>* head =
++ _committed_regions.head();
++ LinkedListNode<CommittedMemoryRegion>* prev = NULL;
++ VirtualMemoryRegion uncommitted_rgn(addr, sz);
++
++ while (head != NULL && !uncommitted_rgn.is_empty()) {
++ CommittedMemoryRegion* crgn = head->data();
++ // this committed region overlaps to region to uncommit
++ if (crgn->overlap_region(uncommitted_rgn.base(), uncommitted_rgn.size())) {
++ if (crgn->same_region(uncommitted_rgn.base(), uncommitted_rgn.size())) {
++ // find matched region, remove the node will do
++ VirtualMemorySummary::record_uncommitted_memory(uncommitted_rgn.size(), flag());
++ _committed_regions.remove_after(prev);
++ return true;
++ } else if (crgn->contain_region(uncommitted_rgn.base(), uncommitted_rgn.size())) {
++ // this committed region contains whole uncommitted region
++ VirtualMemorySummary::record_uncommitted_memory(uncommitted_rgn.size(), flag());
++ return remove_uncommitted_region(head, uncommitted_rgn.base(), uncommitted_rgn.size());
++ } else if (uncommitted_rgn.contain_region(crgn->base(), crgn->size())) {
++ // this committed region has been uncommitted
++ size_t exclude_size = crgn->end() - uncommitted_rgn.base();
++ uncommitted_rgn.exclude_region(uncommitted_rgn.base(), exclude_size);
++ VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
++ LinkedListNode<CommittedMemoryRegion>* tmp = head;
++ head = head->next();
++ _committed_regions.remove_after(prev);
++ continue;
++ } else if (crgn->contain_address(uncommitted_rgn.base())) {
++ size_t toUncommitted = crgn->end() - uncommitted_rgn.base();
++ crgn->exclude_region(uncommitted_rgn.base(), toUncommitted);
++ uncommitted_rgn.exclude_region(uncommitted_rgn.base(), toUncommitted);
++ VirtualMemorySummary::record_uncommitted_memory(toUncommitted, flag());
++ } else if (uncommitted_rgn.contain_address(crgn->base())) {
++ size_t toUncommitted = uncommitted_rgn.end() - crgn->base();
++ crgn->exclude_region(crgn->base(), toUncommitted);
++ uncommitted_rgn.exclude_region(uncommitted_rgn.end() - toUncommitted,
++ toUncommitted);
++ VirtualMemorySummary::record_uncommitted_memory(toUncommitted, flag());
++ }
++ }
++ prev = head;
++ head = head->next();
++ }
++ }
++
++ return true;
++}
++
++void ReservedMemoryRegion::move_committed_regions(address addr, ReservedMemoryRegion& rgn) {
++ assert(addr != NULL, "Invalid address");
++
++ // split committed regions
++ LinkedListNode<CommittedMemoryRegion>* head =
++ _committed_regions.head();
++ LinkedListNode<CommittedMemoryRegion>* prev = NULL;
++
++ while (head != NULL) {
++ if (head->data()->base() >= addr) {
++ break;
++ }
++ prev = head;
++ head = head->next();
++ }
++
++ if (head != NULL) {
++ if (prev != NULL) {
++ prev->set_next(head->next());
++ } else {
++ _committed_regions.set_head(NULL);
++ }
++ }
++
++ rgn._committed_regions.set_head(head);
++}
++
++size_t ReservedMemoryRegion::committed_size() const {
++ if (all_committed()) {
++ return size();
++ } else {
++ size_t committed = 0;
++ LinkedListNode<CommittedMemoryRegion>* head =
++ _committed_regions.head();
++ while (head != NULL) {
++ committed += head->data()->size();
++ head = head->next();
++ }
++ return committed;
++ }
++}
++
++void ReservedMemoryRegion::set_flag(MEMFLAGS f) {
++ assert((flag() == mtNone || flag() == f), "Overwrite memory type");
++ if (flag() != f) {
++ VirtualMemorySummary::move_reserved_memory(flag(), f, size());
++ VirtualMemorySummary::move_committed_memory(flag(), f, committed_size());
++ _flag = f;
++ }
++}
++
++bool VirtualMemoryTracker::initialize(NMT_TrackingLevel level) {
++ if (level >= NMT_summary) {
++ VirtualMemorySummary::initialize();
++ }
++ return true;
++}
++
++bool VirtualMemoryTracker::late_initialize(NMT_TrackingLevel level) {
++ if (level >= NMT_summary) {
++ _reserved_regions = new (std::nothrow, ResourceObj::C_HEAP, mtNMT)
++ SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>();
++ return (_reserved_regions != NULL);
++ }
++ return true;
++}
++
++bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size,
++ const NativeCallStack& stack, MEMFLAGS flag, bool all_committed) {
++ assert(base_addr != NULL, "Invalid address");
++ assert(size > 0, "Invalid size");
++ assert(_reserved_regions != NULL, "Sanity check");
++ ReservedMemoryRegion rgn(base_addr, size, stack, flag);
++ ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
++ LinkedListNode<ReservedMemoryRegion>* node;
++ if (reserved_rgn == NULL) {
++ VirtualMemorySummary::record_reserved_memory(size, flag);
++ node = _reserved_regions->add(rgn);
++ if (node != NULL) {
++ node->data()->set_all_committed(all_committed);
++ return true;
++ } else {
++ return false;
++ }
++ } else {
++ if (reserved_rgn->same_region(base_addr, size)) {
++ reserved_rgn->set_call_stack(stack);
++ reserved_rgn->set_flag(flag);
++ return true;
++ } else if (reserved_rgn->adjacent_to(base_addr, size)) {
++ VirtualMemorySummary::record_reserved_memory(size, flag);
++ reserved_rgn->expand_region(base_addr, size);
++ reserved_rgn->set_call_stack(stack);
++ return true;
++ } else {
++ // Overlapped reservation.
++ // It can happen when the regions are thread stacks, as JNI
++ // thread does not detach from VM before exits, and leads to
++ // leak JavaThread object
++ if (reserved_rgn->flag() == mtThreadStack) {
++ guarantee(!CheckJNICalls, "Attached JNI thread exited without being detached");
++ // Overwrite with new region
++
++ // Release old region
++ VirtualMemorySummary::record_uncommitted_memory(reserved_rgn->committed_size(), reserved_rgn->flag());
++ VirtualMemorySummary::record_released_memory(reserved_rgn->size(), reserved_rgn->flag());
++
++ // Add new region
++ VirtualMemorySummary::record_reserved_memory(rgn.size(), flag);
++
++ *reserved_rgn = rgn;
++ return true;
++ }
++
++ // CDS mapping region.
++ // CDS reserves the whole region for mapping CDS archive, then maps each section into the region.
++ // NMT reports CDS as a whole.
++ if (reserved_rgn->flag() == mtClassShared) {
++ assert(reserved_rgn->contain_region(base_addr, size), "Reserved CDS region should contain this mapping region");
++ return true;
++ }
++
++ ShouldNotReachHere();
++ return false;
++ }
++ }
++}
++
++void VirtualMemoryTracker::set_reserved_region_type(address addr, MEMFLAGS flag) {
++ assert(addr != NULL, "Invalid address");
++ assert(_reserved_regions != NULL, "Sanity check");
++
++ ReservedMemoryRegion rgn(addr, 1);
++ ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
++ if (reserved_rgn != NULL) {
++ assert(reserved_rgn->contain_address(addr), "Containment");
++ if (reserved_rgn->flag() != flag) {
++ assert(reserved_rgn->flag() == mtNone, "Overwrite memory type");
++ reserved_rgn->set_flag(flag);
++ }
++ }
++}
++
++bool VirtualMemoryTracker::add_committed_region(address addr, size_t size,
++ const NativeCallStack& stack) {
++ assert(addr != NULL, "Invalid address");
++ assert(size > 0, "Invalid size");
++ assert(_reserved_regions != NULL, "Sanity check");
++
++ ReservedMemoryRegion rgn(addr, size);
++ ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
++
++ assert(reserved_rgn != NULL, "No reserved region");
++ assert(reserved_rgn->contain_region(addr, size), "Not completely contained");
++ return reserved_rgn->add_committed_region(addr, size, stack);
++}
++
++bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size) {
++ assert(addr != NULL, "Invalid address");
++ assert(size > 0, "Invalid size");
++ assert(_reserved_regions != NULL, "Sanity check");
++
++ ReservedMemoryRegion rgn(addr, size);
++ ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
++ assert(reserved_rgn != NULL, "No reserved region");
++ assert(reserved_rgn->contain_region(addr, size), "Not completely contained");
++ return reserved_rgn->remove_uncommitted_region(addr, size);
++}
++
++bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) {
++ assert(addr != NULL, "Invalid address");
++ assert(size > 0, "Invalid size");
++ assert(_reserved_regions != NULL, "Sanity check");
++
++ ReservedMemoryRegion rgn(addr, size);
++ ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
++
++ assert(reserved_rgn != NULL, "No reserved region");
++
++ // uncommit regions within the released region
++ if (!reserved_rgn->remove_uncommitted_region(addr, size)) {
++ return false;
++ }
++
++
++ VirtualMemorySummary::record_released_memory(size, reserved_rgn->flag());
++
++ if (reserved_rgn->same_region(addr, size)) {
++ return _reserved_regions->remove(rgn);
++ } else {
++ assert(reserved_rgn->contain_region(addr, size), "Not completely contained");
++ if (reserved_rgn->base() == addr ||
++ reserved_rgn->end() == addr + size) {
++ reserved_rgn->exclude_region(addr, size);
++ return true;
++ } else {
++ address top = reserved_rgn->end();
++ address high_base = addr + size;
++ ReservedMemoryRegion high_rgn(high_base, top - high_base,
++ *reserved_rgn->call_stack(), reserved_rgn->flag());
++
++ // use original region for lower region
++ reserved_rgn->exclude_region(addr, top - addr);
++ LinkedListNode<ReservedMemoryRegion>* new_rgn = _reserved_regions->add(high_rgn);
++ if (new_rgn == NULL) {
++ return false;
++ } else {
++ reserved_rgn->move_committed_regions(addr, *new_rgn->data());
++ return true;
++ }
++ }
++ }
++}
++
++
++bool VirtualMemoryTracker::walk_virtual_memory(VirtualMemoryWalker* walker) {
++ assert(_reserved_regions != NULL, "Sanity check");
++ ThreadCritical tc;
++ // Check that the _reserved_regions haven't been deleted.
++ if (_reserved_regions != NULL) {
++ LinkedListNode<ReservedMemoryRegion>* head = _reserved_regions->head();
++ while (head != NULL) {
++ const ReservedMemoryRegion* rgn = head->peek();
++ if (!walker->do_allocation_site(rgn)) {
++ return false;
++ }
++ head = head->next();
++ }
++ }
++ return true;
++}
++
++// Transition virtual memory tracking level.
++bool VirtualMemoryTracker::transition(NMT_TrackingLevel from, NMT_TrackingLevel to) {
++ assert (from != NMT_minimal, "cannot convert from the lowest tracking level to anything");
++ if (to == NMT_minimal) {
++ assert(from == NMT_summary || from == NMT_detail, "Just check");
++ // Clean up virtual memory tracking data structures.
++ ThreadCritical tc;
++ // Check for potential race with other thread calling transition
++ if (_reserved_regions != NULL) {
++ delete _reserved_regions;
++ _reserved_regions = NULL;
++ }
++ }
++
++ return true;
++}
++
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/services/virtualMemoryTracker.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,425 @@
++/*
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_SERVICES_VIRTUAL_MEMORY_TRACKER_HPP
++#define SHARE_VM_SERVICES_VIRTUAL_MEMORY_TRACKER_HPP
++
++#if INCLUDE_NMT
++
++#include "memory/allocation.hpp"
++#include "services/allocationSite.hpp"
++#include "services/nmtCommon.hpp"
++#include "utilities/linkedlist.hpp"
++#include "utilities/nativeCallStack.hpp"
++#include "utilities/ostream.hpp"
++
++
++/*
++ * Virtual memory counter
++ */
++class VirtualMemory VALUE_OBJ_CLASS_SPEC {
++ private:
++ size_t _reserved;
++ size_t _committed;
++
++ public:
++ VirtualMemory() : _reserved(0), _committed(0) { }
++
++ inline void reserve_memory(size_t sz) { _reserved += sz; }
++ inline void commit_memory (size_t sz) {
++ _committed += sz;
++ assert(_committed <= _reserved, "Sanity check");
++ }
++
++ inline void release_memory (size_t sz) {
++ assert(_reserved >= sz, "Negative amount");
++ _reserved -= sz;
++ }
++
++ inline void uncommit_memory(size_t sz) {
++ assert(_committed >= sz, "Negative amount");
++ _committed -= sz;
++ }
++
++ inline size_t reserved() const { return _reserved; }
++ inline size_t committed() const { return _committed; }
++};
++
++// Virtual memory allocation site, keeps track where the virtual memory is reserved.
++class VirtualMemoryAllocationSite : public AllocationSite<VirtualMemory> {
++ public:
++ VirtualMemoryAllocationSite(const NativeCallStack& stack) :
++ AllocationSite<VirtualMemory>(stack) { }
++
++ inline void reserve_memory(size_t sz) { data()->reserve_memory(sz); }
++ inline void commit_memory (size_t sz) { data()->commit_memory(sz); }
++ inline void uncommit_memory(size_t sz) { data()->uncommit_memory(sz); }
++ inline void release_memory(size_t sz) { data()->release_memory(sz); }
++ inline size_t reserved() const { return peek()->reserved(); }
++ inline size_t committed() const { return peek()->committed(); }
++};
++
++class VirtualMemorySummary;
++
++// This class represents a snapshot of virtual memory at a given time.
++// The latest snapshot is saved in a static area.
++class VirtualMemorySnapshot : public ResourceObj {
++ friend class VirtualMemorySummary;
++
++ private:
++ VirtualMemory _virtual_memory[mt_number_of_types];
++
++ public:
++ inline VirtualMemory* by_type(MEMFLAGS flag) {
++ int index = NMTUtil::flag_to_index(flag);
++ return &_virtual_memory[index];
++ }
++
++ inline VirtualMemory* by_index(int index) {
++ assert(index >= 0, "Index out of bound");
++ assert(index < mt_number_of_types, "Index out of bound");
++ return &_virtual_memory[index];
++ }
++
++ inline size_t total_reserved() const {
++ size_t amount = 0;
++ for (int index = 0; index < mt_number_of_types; index ++) {
++ amount += _virtual_memory[index].reserved();
++ }
++ return amount;
++ }
++
++ inline size_t total_committed() const {
++ size_t amount = 0;
++ for (int index = 0; index < mt_number_of_types; index ++) {
++ amount += _virtual_memory[index].committed();
++ }
++ return amount;
++ }
++
++ void copy_to(VirtualMemorySnapshot* s) {
++ for (int index = 0; index < mt_number_of_types; index ++) {
++ s->_virtual_memory[index] = _virtual_memory[index];
++ }
++ }
++};
++
++class VirtualMemorySummary : AllStatic {
++ public:
++ static void initialize();
++
++ static inline void record_reserved_memory(size_t size, MEMFLAGS flag) {
++ as_snapshot()->by_type(flag)->reserve_memory(size);
++ }
++
++ static inline void record_committed_memory(size_t size, MEMFLAGS flag) {
++ as_snapshot()->by_type(flag)->commit_memory(size);
++ }
++
++ static inline void record_uncommitted_memory(size_t size, MEMFLAGS flag) {
++ as_snapshot()->by_type(flag)->uncommit_memory(size);
++ }
++
++ static inline void record_released_memory(size_t size, MEMFLAGS flag) {
++ as_snapshot()->by_type(flag)->release_memory(size);
++ }
++
++ // Move virtual memory from one memory type to another.
++ // Virtual memory can be reserved before it is associated with a memory type, and tagged
++ // as 'unknown'. Once the memory is tagged, the virtual memory will be moved from 'unknown'
++ // type to specified memory type.
++ static inline void move_reserved_memory(MEMFLAGS from, MEMFLAGS to, size_t size) {
++ as_snapshot()->by_type(from)->release_memory(size);
++ as_snapshot()->by_type(to)->reserve_memory(size);
++ }
++
++ static inline void move_committed_memory(MEMFLAGS from, MEMFLAGS to, size_t size) {
++ as_snapshot()->by_type(from)->uncommit_memory(size);
++ as_snapshot()->by_type(to)->commit_memory(size);
++ }
++
++ static inline void snapshot(VirtualMemorySnapshot* s) {
++ as_snapshot()->copy_to(s);
++ }
++
++ static VirtualMemorySnapshot* as_snapshot() {
++ return (VirtualMemorySnapshot*)_snapshot;
++ }
++
++ private:
++ static size_t _snapshot[CALC_OBJ_SIZE_IN_TYPE(VirtualMemorySnapshot, size_t)];
++};
++
++
++
++/*
++ * A virtual memory region
++ */
++class VirtualMemoryRegion VALUE_OBJ_CLASS_SPEC {
++ private:
++ address _base_address;
++ size_t _size;
++
++ public:
++ VirtualMemoryRegion(address addr, size_t size) :
++ _base_address(addr), _size(size) {
++ assert(addr != NULL, "Invalid address");
++ assert(size > 0, "Invalid size");
++ }
++
++ inline address base() const { return _base_address; }
++ inline address end() const { return base() + size(); }
++ inline size_t size() const { return _size; }
++
++ inline bool is_empty() const { return size() == 0; }
++
++ inline bool contain_address(address addr) const {
++ return (addr >= base() && addr < end());
++ }
++
++
++ inline bool contain_region(address addr, size_t size) const {
++ return contain_address(addr) && contain_address(addr + size - 1);
++ }
++
++ inline bool same_region(address addr, size_t sz) const {
++ return (addr == base() && sz == size());
++ }
++
++
++ inline bool overlap_region(address addr, size_t sz) const {
++ VirtualMemoryRegion rgn(addr, sz);
++ return contain_address(addr) ||
++ contain_address(addr + sz - 1) ||
++ rgn.contain_address(base()) ||
++ rgn.contain_address(end() - 1);
++ }
++
++ inline bool adjacent_to(address addr, size_t sz) const {
++ return (addr == end() || (addr + sz) == base());
++ }
++
++ void exclude_region(address addr, size_t sz) {
++ assert(contain_region(addr, sz), "Not containment");
++ assert(addr == base() || addr + sz == end(), "Can not exclude from middle");
++ size_t new_size = size() - sz;
++
++ if (addr == base()) {
++ set_base(addr + sz);
++ }
++ set_size(new_size);
++ }
++
++ void expand_region(address addr, size_t sz) {
++ assert(adjacent_to(addr, sz), "Not adjacent regions");
++ if (base() == addr + sz) {
++ set_base(addr);
++ }
++ set_size(size() + sz);
++ }
++
++ protected:
++ void set_base(address base) {
++ assert(base != NULL, "Sanity check");
++ _base_address = base;
++ }
++
++ void set_size(size_t size) {
++ assert(size > 0, "Sanity check");
++ _size = size;
++ }
++};
++
++
++class CommittedMemoryRegion : public VirtualMemoryRegion {
++ private:
++ NativeCallStack _stack;
++
++ public:
++ CommittedMemoryRegion(address addr, size_t size, const NativeCallStack& stack) :
++ VirtualMemoryRegion(addr, size), _stack(stack) { }
++
++ inline int compare(const CommittedMemoryRegion& rgn) const {
++ if (overlap_region(rgn.base(), rgn.size()) ||
++ adjacent_to (rgn.base(), rgn.size())) {
++ return 0;
++ } else {
++ if (base() == rgn.base()) {
++ return 0;
++ } else if (base() > rgn.base()) {
++ return 1;
++ } else {
++ return -1;
++ }
++ }
++ }
++
++ inline bool equals(const CommittedMemoryRegion& rgn) const {
++ return compare(rgn) == 0;
++ }
++
++ inline void set_call_stack(const NativeCallStack& stack) { _stack = stack; }
++ inline const NativeCallStack* call_stack() const { return &_stack; }
++};
++
++
++typedef LinkedListIterator<CommittedMemoryRegion> CommittedRegionIterator;
++
++int compare_committed_region(const CommittedMemoryRegion&, const CommittedMemoryRegion&);
++class ReservedMemoryRegion : public VirtualMemoryRegion {
++ private:
++ SortedLinkedList<CommittedMemoryRegion, compare_committed_region>
++ _committed_regions;
++
++ NativeCallStack _stack;
++ MEMFLAGS _flag;
++
++ bool _all_committed;
++
++ public:
++ ReservedMemoryRegion(address base, size_t size, const NativeCallStack& stack,
++ MEMFLAGS flag = mtNone) :
++ VirtualMemoryRegion(base, size), _stack(stack), _flag(flag),
++ _all_committed(false) { }
++
++
++ ReservedMemoryRegion(address base, size_t size) :
++ VirtualMemoryRegion(base, size), _stack(NativeCallStack::EMPTY_STACK), _flag(mtNone),
++ _all_committed(false) { }
++
++ // Copy constructor
++ ReservedMemoryRegion(const ReservedMemoryRegion& rr) :
++ VirtualMemoryRegion(rr.base(), rr.size()) {
++ *this = rr;
++ }
++
++ inline void set_call_stack(const NativeCallStack& stack) { _stack = stack; }
++ inline const NativeCallStack* call_stack() const { return &_stack; }
++
++ void set_flag(MEMFLAGS flag);
++ inline MEMFLAGS flag() const { return _flag; }
++
++ inline int compare(const ReservedMemoryRegion& rgn) const {
++ if (overlap_region(rgn.base(), rgn.size())) {
++ return 0;
++ } else {
++ if (base() == rgn.base()) {
++ return 0;
++ } else if (base() > rgn.base()) {
++ return 1;
++ } else {
++ return -1;
++ }
++ }
++ }
++
++ inline bool equals(const ReservedMemoryRegion& rgn) const {
++ return compare(rgn) == 0;
++ }
++
++ bool add_committed_region(address addr, size_t size, const NativeCallStack& stack);
++ bool remove_uncommitted_region(address addr, size_t size);
++
++ size_t committed_size() const;
++
++ // move committed regions that higher than specified address to
++ // the new region
++ void move_committed_regions(address addr, ReservedMemoryRegion& rgn);
++
++ inline bool all_committed() const { return _all_committed; }
++ void set_all_committed(bool b);
++
++ CommittedRegionIterator iterate_committed_regions() const {
++ return CommittedRegionIterator(_committed_regions.head());
++ }
++
++ ReservedMemoryRegion& operator= (const ReservedMemoryRegion& other) {
++ set_base(other.base());
++ set_size(other.size());
++
++ _stack = *other.call_stack();
++ _flag = other.flag();
++ _all_committed = other.all_committed();
++ if (other.all_committed()) {
++ set_all_committed(true);
++ } else {
++ CommittedRegionIterator itr = other.iterate_committed_regions();
++ const CommittedMemoryRegion* rgn = itr.next();
++ while (rgn != NULL) {
++ _committed_regions.add(*rgn);
++ rgn = itr.next();
++ }
++ }
++ return *this;
++ }
++
++ private:
++ // The committed region contains the uncommitted region, subtract the uncommitted
++ // region from this committed region
++ bool remove_uncommitted_region(LinkedListNode<CommittedMemoryRegion>* node,
++ address addr, size_t sz);
++
++ bool add_committed_region(const CommittedMemoryRegion& rgn) {
++ assert(rgn.base() != NULL, "Invalid base address");
++ assert(size() > 0, "Invalid size");
++ return _committed_regions.add(rgn) != NULL;
++ }
++};
++
++int compare_reserved_region_base(const ReservedMemoryRegion& r1, const ReservedMemoryRegion& r2);
++
++class VirtualMemoryWalker : public StackObj {
++ public:
++ virtual bool do_allocation_site(const ReservedMemoryRegion* rgn) { return false; }
++};
++
++// Main class called from MemTracker to track virtual memory allocations, commits and releases.
++class VirtualMemoryTracker : AllStatic {
++ public:
++ static bool initialize(NMT_TrackingLevel level);
++
++ // Late phase initialization
++ static bool late_initialize(NMT_TrackingLevel level);
++
++ static bool add_reserved_region (address base_addr, size_t size, const NativeCallStack& stack,
++ MEMFLAGS flag = mtNone, bool all_committed = false);
++
++ static bool add_committed_region (address base_addr, size_t size, const NativeCallStack& stack);
++ static bool remove_uncommitted_region (address base_addr, size_t size);
++ static bool remove_released_region (address base_addr, size_t size);
++ static void set_reserved_region_type (address addr, MEMFLAGS flag);
++
++ // Walk virtual memory data structure for creating baseline, etc.
++ static bool walk_virtual_memory(VirtualMemoryWalker* walker);
++
++ static bool transition(NMT_TrackingLevel from, NMT_TrackingLevel to);
++
++ private:
++ static SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>* _reserved_regions;
++};
++
++
++#endif // INCLUDE_NMT
++
++#endif // SHARE_VM_SERVICES_VIRTUAL_MEMORY_TRACKER_HPP
+--- ./hotspot/src/share/vm/trace/noTraceBackend.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/trace/noTraceBackend.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -41,4 +41,4 @@
+
+ typedef NoTraceBackend Tracing;
+
+-#endif
++#endif // SHARE_VM_TRACE_NOTRACEBACKEND_HPP
+--- ./hotspot/src/share/vm/trace/traceBackend.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/trace/traceBackend.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -25,9 +25,7 @@
+ #define SHARE_VM_TRACE_TRACEBACKEND_HPP
+
+ #include "utilities/macros.hpp"
+-
+ #if INCLUDE_TRACE
+-
+ #include "runtime/globals.hpp"
+ #include "runtime/os.hpp"
+ #include "trace/traceTime.hpp"
+@@ -58,9 +56,7 @@
+
+ typedef TraceBackend Tracing;
+
+-#else /* INCLUDE_TRACE */
+-
++#else // !INCLUDE_TRACE
+ #include "trace/noTraceBackend.hpp"
+-
+-#endif /* INCLUDE_TRACE */
+-#endif /* SHARE_VM_TRACE_TRACEBACKEND_HPP */
++#endif // INCLUDE_TRACE
++#endif // SHARE_VM_TRACE_TRACEBACKEND_HPP
+--- ./hotspot/src/share/vm/trace/traceEvent.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/trace/traceEvent.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -33,7 +33,6 @@
+ };
+
+ #if INCLUDE_TRACE
+-
+ #include "trace/traceBackend.hpp"
+ #include "trace/tracing.hpp"
+ #include "tracefiles/traceEventIds.hpp"
+@@ -154,6 +153,5 @@
+ }
+ };
+
+-#endif /* INCLUDE_TRACE */
+-
+-#endif /* SHARE_VM_TRACE_TRACEEVENT_HPP */
++#endif // INCLUDE_TRACE
++#endif // SHARE_VM_TRACE_TRACEEVENT_HPP
+--- ./hotspot/src/share/vm/trace/traceEventClasses.xsl Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/trace/traceEventClasses.xsl Wed Feb 04 12:14:39 2015 -0800
+@@ -41,17 +41,14 @@
+ #include "trace/traceEvent.hpp"
+ #include "utilities/macros.hpp"
+ #include "utilities/ticks.hpp"
+-
+ #if INCLUDE_TRACE
+-
+-
+ #include "trace/traceStream.hpp"
+ #include "utilities/ostream.hpp"
+
+ <xsl:apply-templates select="trace/events/struct" mode="trace"/>
+ <xsl:apply-templates select="trace/events/event" mode="trace"/>
+
+-#else
++#else // !INCLUDE_TRACE
+
+ class TraceEvent {
+ public:
+@@ -65,9 +62,8 @@
+ <xsl:apply-templates select="trace/events/struct" mode="empty"/>
+ <xsl:apply-templates select="trace/events/event" mode="empty"/>
+
+-#endif
+-
+-#endif
++#endif // INCLUDE_TRACE
++#endif // TRACEFILES_TRACEEVENTCLASSES_HPP
+ </xsl:template>
+
+ <xsl:template match="struct" mode="trace">
+--- ./hotspot/src/share/vm/trace/traceEventIds.xsl Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/trace/traceEventIds.xsl Wed Feb 04 12:14:39 2015 -0800
+@@ -29,13 +29,11 @@
+ <xsl:template match="/">
+ <xsl:call-template name="file-header"/>
+
+-#ifndef TRACEFILES_JFREVENTIDS_HPP
+-#define TRACEFILES_JFREVENTIDS_HPP
++#ifndef TRACEFILES_TRACEEVENTIDS_HPP
++#define TRACEFILES_TRACEEVENTIDS_HPP
+
+ #include "utilities/macros.hpp"
+-
+ #if INCLUDE_TRACE
+-
+ #include "trace/traceDataTypes.hpp"
+
+ /**
+@@ -67,8 +65,8 @@
+ typedef enum TraceEventId TraceEventId;
+ typedef enum TraceStructId TraceStructId;
+
+-#endif
+-#endif
++#endif // INCLUDE_TRACE
++#endif // TRACEFILES_TRACEEVENTIDS_HPP
+ </xsl:template>
+
+ </xsl:stylesheet>
+--- ./hotspot/src/share/vm/trace/traceMacros.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/trace/traceMacros.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -22,8 +22,8 @@
+ *
+ */
+
+-#ifndef SHARE_VM_TRACE_TRACE_MACRO_HPP
+-#define SHARE_VM_TRACE_TRACE_MACRO_HPP
++#ifndef SHARE_VM_TRACE_TRACEMACROS_HPP
++#define SHARE_VM_TRACE_TRACEMACROS_HPP
+
+ #define EVENT_THREAD_EXIT(thread)
+ #define EVENT_THREAD_DESTRUCT(thread)
+@@ -41,4 +41,4 @@
+ #define TRACE_TEMPLATES(template)
+ #define TRACE_INTRINSICS(do_intrinsic, do_class, do_name, do_signature, do_alias)
+
+-#endif
++#endif // SHARE_VM_TRACE_TRACEMACROS_HPP
+--- ./hotspot/src/share/vm/trace/traceStream.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/trace/traceStream.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,9 +26,7 @@
+ #define SHARE_VM_TRACE_TRACESTREAM_HPP
+
+ #include "utilities/macros.hpp"
+-
+ #if INCLUDE_TRACE
+-
+ #include "oops/klass.hpp"
+ #include "oops/method.hpp"
+ #include "oops/symbol.hpp"
+@@ -117,5 +115,5 @@
+ }
+ };
+
+-#endif /* INCLUDE_TRACE */
+-#endif /* SHARE_VM_TRACE_TRACESTREAM_HPP */
++#endif // INCLUDE_TRACE
++#endif // SHARE_VM_TRACE_TRACESTREAM_HPP
+--- ./hotspot/src/share/vm/trace/traceTypes.xsl Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/trace/traceTypes.xsl Wed Feb 04 12:14:39 2015 -0800
+@@ -29,15 +29,14 @@
+ <xsl:template match="/">
+ <xsl:call-template name="file-header"/>
+
+-#ifndef TRACEFILES_JFRTYPES_HPP
+-#define TRACEFILES_JFRTYPES_HPP
++#ifndef TRACEFILES_TRACETYPES_HPP
++#define TRACEFILES_TRACETYPES_HPP
+
+ #include "oops/symbol.hpp"
+ #include "trace/traceDataTypes.hpp"
+ #include "utilities/globalDefinitions.hpp"
+ #include "utilities/ticks.hpp"
+
+-
+ enum JVMContentType {
+ _not_a_content_type = (JVM_CONTENT_TYPES_START - 1),
+
+@@ -58,7 +57,7 @@
+ };
+
+ /**
+- * Create typedefs for the JRA types:
++ * Create typedefs for the TRACE types:
+ * typedef s8 TYPE_LONG;
+ * typedef s4 TYPE_INTEGER;
+ * typedef const char * TYPE_STRING;
+@@ -68,7 +67,7 @@
+ typedef <xsl:value-of select="@type"/> TYPE_<xsl:value-of select="@symbol"/>;
+ </xsl:for-each>
+
+-#endif // JFRFILES_JFRTYPES_HPP
++#endif // TRACEFILES_TRACETYPES_HPP
+ </xsl:template>
+
+ </xsl:stylesheet>
+--- ./hotspot/src/share/vm/trace/tracetypes.xml Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/trace/tracetypes.xml Wed Feb 04 12:14:39 2015 -0800
+@@ -98,6 +98,7 @@
+ <value type="SYMBOL" field="name" label="Name"/>
+ <value type="SYMBOL" field="signature" label="Signature"/>
+ <value type="SHORT" field="modifiers" label="Access modifiers"/>
++ <value type="BOOLEAN" field="hidden" label="Hidden"/>
+ </content_type>
+
+ <content_type id="UTFConstant" hr_name="UTF constant"
+--- ./hotspot/src/share/vm/trace/tracing.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/trace/tracing.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,4 +28,4 @@
+ #include "tracefiles/traceEventClasses.hpp"
+ #include "tracefiles/traceEventIds.hpp"
+
+-#endif
++#endif // SHARE_VM_TRACE_TRACING_HPP
+--- ./hotspot/src/share/vm/utilities/accessFlags.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/accessFlags.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -62,6 +62,21 @@
+ } while(f != old_flags);
+ }
+
++// Returns true iff this thread succeeded setting the bit.
++bool AccessFlags::atomic_set_one_bit(jint bit) {
++ // Atomically update the flags with the bit given
++ jint old_flags, new_flags, f;
++ bool is_setting_bit = false;
++ do {
++ old_flags = _flags;
++ new_flags = old_flags | bit;
++ is_setting_bit = old_flags != new_flags;
++ f = Atomic::cmpxchg(new_flags, &_flags, old_flags);
++ } while(f != old_flags);
++
++ return is_setting_bit;
++}
++
+ #if !defined(PRODUCT) || INCLUDE_JVMTI
+
+ void AccessFlags::print_on(outputStream* st) const {
+--- ./hotspot/src/share/vm/utilities/accessFlags.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/accessFlags.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -170,6 +170,7 @@
+
+ // Atomic update of flags
+ void atomic_set_bits(jint bits);
++ bool atomic_set_one_bit(jint bit);
+ void atomic_clear_bits(jint bits);
+
+ private:
+@@ -230,12 +231,13 @@
+ atomic_set_bits(JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE);
+ }
+
+- void set_on_stack(const bool value)
++ bool set_on_stack(const bool value)
+ {
+ if (value) {
+- atomic_set_bits(JVM_ACC_ON_STACK);
++ return atomic_set_one_bit(JVM_ACC_ON_STACK);
+ } else {
+ atomic_clear_bits(JVM_ACC_ON_STACK);
++ return true; // Ignored
+ }
+ }
+ // Conversion
+--- ./hotspot/src/share/vm/utilities/array.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/array.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,6 +28,7 @@
+ #include "memory/allocation.hpp"
+ #include "memory/allocation.inline.hpp"
+ #include "memory/metaspace.hpp"
++#include "runtime/orderAccess.hpp"
+
+ // correct linkage required to compile w/o warnings
+ // (must be on file level - cannot be local)
+@@ -304,6 +305,7 @@
+ friend class MetadataFactory;
+ friend class VMStructs;
+ friend class MethodHandleCompiler; // special case
++ friend class WhiteBox;
+ protected:
+ int _length; // the number of array elements
+ T _data[1]; // the array memory
+@@ -325,6 +327,31 @@
+
+ static size_t byte_sizeof(int length) { return sizeof(Array<T>) + MAX2(length - 1, 0) * sizeof(T); }
+
++ // WhiteBox API helper.
++ // Can't distinguish between array of length 0 and length 1,
++ // will always return 0 in those cases.
++ static int bytes_to_length(size_t bytes) {
++ assert(is_size_aligned(bytes, BytesPerWord), "Must be, for now");
++
++ if (sizeof(Array<T>) >= bytes) {
++ return 0;
++ }
++
++ size_t left = bytes - sizeof(Array<T>);
++ assert(is_size_aligned(left, sizeof(T)), "Must be");
++
++ size_t elements = left / sizeof(T);
++ assert(elements <= (size_t)INT_MAX, err_msg("number of elements " SIZE_FORMAT "doesn't fit into an int.", elements));
++
++ int length = (int)elements;
++
++ assert((size_t)size(length) * BytesPerWord == bytes,
++ err_msg("Expected: " SIZE_FORMAT " got: " SIZE_FORMAT,
++ bytes, (size_t)size(length) * BytesPerWord));
++
++ return length;
++ }
++
+ explicit Array(int length) : _length(length) {
+ assert(length >= 0, "illegal length");
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/utilities/chunkedList.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,109 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "utilities/chunkedList.hpp"
++#include "utilities/debug.hpp"
++
++/////////////// Unit tests ///////////////
++
++#ifndef PRODUCT
++
++template <typename T>
++class TestChunkedList {
++ typedef ChunkedList<T, mtOther> ChunkedListT;
++
++ public:
++ static void testEmpty() {
++ ChunkedListT buffer;
++ assert(buffer.size() == 0, "assert");
++ }
++
++ static void testFull() {
++ ChunkedListT buffer;
++ for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) {
++ buffer.push((T)i);
++ }
++ assert(buffer.size() == ChunkedListT::BufferSize, "assert");
++ assert(buffer.is_full(), "assert");
++ }
++
++ static void testSize() {
++ ChunkedListT buffer;
++ for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) {
++ assert(buffer.size() == i, "assert");
++ buffer.push((T)i);
++ assert(buffer.size() == i + 1, "assert");
++ }
++ }
++
++ static void testClear() {
++ ChunkedListT buffer;
++
++ buffer.clear();
++ assert(buffer.size() == 0, "assert");
++
++ for (uintptr_t i = 0; i < ChunkedListT::BufferSize / 2; i++) {
++ buffer.push((T)i);
++ }
++ buffer.clear();
++ assert(buffer.size() == 0, "assert");
++
++ for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) {
++ buffer.push((T)i);
++ }
++ buffer.clear();
++ assert(buffer.size() == 0, "assert");
++ }
++
++ static void testAt() {
++ ChunkedListT buffer;
++
++ for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) {
++ buffer.push((T)i);
++ assert(buffer.at(i) == (T)i, "assert");
++ }
++
++ for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) {
++ assert(buffer.at(i) == (T)i, "assert");
++ }
++ }
++
++ static void test() {
++ testEmpty();
++ testFull();
++ testSize();
++ testClear();
++ testAt();
++ }
++};
++
++class Metadata;
++
++void TestChunkedList_test() {
++ TestChunkedList<Metadata*>::test();
++ TestChunkedList<size_t>::test();
++}
++
++#endif
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/utilities/chunkedList.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,81 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_UTILITIES_CHUNKED_LIST_HPP
++#define SHARE_VM_UTILITIES_CHUNKED_LIST_HPP
++
++#include "memory/allocation.hpp"
++#include "utilities/debug.hpp"
++
++template <class T, MEMFLAGS F> class ChunkedList : public CHeapObj<F> {
++ template <class U> friend class TestChunkedList;
++
++ static const size_t BufferSize = 64;
++
++ T _values[BufferSize];
++ T* _top;
++
++ ChunkedList<T, F>* _next_used;
++ ChunkedList<T, F>* _next_free;
++
++ T const * end() const {
++ return &_values[BufferSize];
++ }
++
++ public:
++ ChunkedList<T, F>() : _top(_values), _next_used(NULL), _next_free(NULL) {}
++
++ bool is_full() const {
++ return _top == end();
++ }
++
++ void clear() {
++ _top = _values;
++ // Don't clear the next pointers since that would interfere
++ // with other threads trying to iterate through the lists.
++ }
++
++ void push(T m) {
++ assert(!is_full(), "Buffer is full");
++ *_top = m;
++ _top++;
++ }
++
++ void set_next_used(ChunkedList<T, F>* buffer) { _next_used = buffer; }
++ void set_next_free(ChunkedList<T, F>* buffer) { _next_free = buffer; }
++
++ ChunkedList<T, F>* next_used() const { return _next_used; }
++ ChunkedList<T, F>* next_free() const { return _next_free; }
++
++ size_t size() const {
++ return pointer_delta(_top, _values, sizeof(T));
++ }
++
++ T at(size_t i) {
++ assert(i < size(), err_msg("IOOBE i: " SIZE_FORMAT " size(): " SIZE_FORMAT, i, size()));
++ return _values[i];
++ }
++};
++
++#endif // SHARE_VM_UTILITIES_CHUNKED_LIST_HPP
+--- ./hotspot/src/share/vm/utilities/debug.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/debug.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -266,17 +266,19 @@
+ "native memory for metadata",
+ "shared read only space",
+ "shared read write space",
+- "shared miscellaneous data space"
++ "shared miscellaneous data space",
++ "shared miscellaneous code space"
+ };
+ static const char* flag[] = {
+ "Metaspace",
+ "SharedReadOnlySize",
+ "SharedReadWriteSize",
+- "SharedMiscDataSize"
++ "SharedMiscDataSize",
++ "SharedMiscCodeSize"
+ };
+
+ warning("\nThe %s is not large enough\n"
+- "to preload requested classes. Use -XX:%s=\n"
++ "to preload requested classes. Use -XX:%s=<size>\n"
+ "to increase the initial size of %s.\n",
+ name[shared_space], flag[shared_space], name[shared_space]);
+ exit(2);
+--- ./hotspot/src/share/vm/utilities/debug.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/debug.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -246,7 +246,8 @@
+ SharedPermGen,
+ SharedReadOnly,
+ SharedReadWrite,
+- SharedMiscData
++ SharedMiscData,
++ SharedMiscCode
+ };
+
+ void report_out_of_shared_space(SharedSpaceType space_type);
+--- ./hotspot/src/share/vm/utilities/exceptions.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/exceptions.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -85,9 +85,13 @@
+ #endif // ASSERT
+
+ if (thread->is_VM_thread()
+- || thread->is_Compiler_thread() ) {
++ || thread->is_Compiler_thread()
++ || DumpSharedSpaces ) {
+ // We do not care what kind of exception we get for the vm-thread or a thread which
+ // is compiling. We just install a dummy exception object
++ //
++ // We also cannot throw a proper exception when dumping, because we cannot run
++ // Java bytecodes now. A dummy exception will suffice.
+ thread->set_pending_exception(Universe::vm_exception(), file, line);
+ return true;
+ }
+@@ -108,9 +112,13 @@
+ }
+
+ if (thread->is_VM_thread()
+- || thread->is_Compiler_thread() ) {
++ || thread->is_Compiler_thread()
++ || DumpSharedSpaces ) {
+ // We do not care what kind of exception we get for the vm-thread or a thread which
+ // is compiling. We just install a dummy exception object
++ //
++ // We also cannot throw a proper exception when dumping, because we cannot run
++ // Java bytecodes now. A dummy exception will suffice.
+ thread->set_pending_exception(Universe::vm_exception(), file, line);
+ return true;
+ }
+--- ./hotspot/src/share/vm/utilities/globalDefinitions.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/globalDefinitions.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -558,6 +558,27 @@
+ return fabs(value);
+ }
+
++//----------------------------------------------------------------------------------------------------
++// Special casts
++// Cast floats into same-size integers and vice-versa w/o changing bit-pattern
++typedef union {
++ jfloat f;
++ jint i;
++} FloatIntConv;
++
++typedef union {
++ jdouble d;
++ jlong l;
++ julong ul;
++} DoubleLongConv;
++
++inline jint jint_cast (jfloat x) { return ((FloatIntConv*)&x)->i; }
++inline jfloat jfloat_cast (jint x) { return ((FloatIntConv*)&x)->f; }
++
++inline jlong jlong_cast (jdouble x) { return ((DoubleLongConv*)&x)->l; }
++inline julong julong_cast (jdouble x) { return ((DoubleLongConv*)&x)->ul; }
++inline jdouble jdouble_cast (jlong x) { return ((DoubleLongConv*)&x)->d; }
++
+ inline jint low (jlong value) { return jint(value); }
+ inline jint high(jlong value) { return jint(value >> 32); }
+
+--- ./hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -167,17 +167,6 @@
+ typedef uint32_t juint;
+ typedef uint64_t julong;
+
+-//----------------------------------------------------------------------------------------------------
+-// Special (possibly not-portable) casts
+-// Cast floats into same-size integers and vice-versa w/o changing bit-pattern
+-// %%%%%% These seem like standard C++ to me--how about factoring them out? - Ungar
+-
+-inline jint jint_cast (jfloat x) { return *(jint* )&x; }
+-inline jlong jlong_cast (jdouble x) { return *(jlong* )&x; }
+-inline julong julong_cast (jdouble x) { return *(julong* )&x; }
+-
+-inline jfloat jfloat_cast (jint x) { return *(jfloat* )&x; }
+-inline jdouble jdouble_cast(jlong x) { return *(jdouble*)&x; }
+
+ //----------------------------------------------------------------------------------------------------
+ // Constant for jlong (specifying an long long canstant is C++ compiler specific)
+--- ./hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -183,15 +183,6 @@
+ typedef unsigned int juint;
+ typedef unsigned long long julong;
+
+-//----------------------------------------------------------------------------------------------------
+-// Special (possibly not-portable) casts
+-// Cast floats into same-size integers and vice-versa w/o changing bit-pattern
+-
+-inline jint jint_cast (jfloat x) { return *(jint* )&x; }
+-inline jlong jlong_cast (jdouble x) { return *(jlong* )&x; }
+-
+-inline jfloat jfloat_cast (jint x) { return *(jfloat* )&x; }
+-inline jdouble jdouble_cast(jlong x) { return *(jdouble*)&x; }
+
+ //----------------------------------------------------------------------------------------------------
+ // Constant for jlong (specifying an long long constant is C++ compiler specific)
+--- ./hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -116,16 +116,6 @@
+ typedef unsigned int juint;
+ typedef unsigned __int64 julong;
+
+-//----------------------------------------------------------------------------------------------------
+-// Special (possibly not-portable) casts
+-// Cast floats into same-size integers and vice-versa w/o changing bit-pattern
+-
+-inline jint jint_cast (jfloat x) { return *(jint* )&x; }
+-inline jlong jlong_cast (jdouble x) { return *(jlong* )&x; }
+-
+-inline jfloat jfloat_cast (jint x) { return *(jfloat* )&x; }
+-inline jdouble jdouble_cast(jlong x) { return *(jdouble*)&x; }
+-
+
+ //----------------------------------------------------------------------------------------------------
+ // Non-standard stdlib-like stuff:
+--- ./hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -114,16 +114,6 @@
+ typedef uint32_t juint;
+ typedef uint64_t julong;
+
+-//----------------------------------------------------------------------------------------------------
+-// Special (possibly not-portable) casts
+-// Cast floats into same-size integers and vice-versa w/o changing bit-pattern
+-// %%%%%% These seem like standard C++ to me--how about factoring them out? - Ungar
+-
+-inline jint jint_cast (jfloat x) { return *(jint* )&x; }
+-inline jlong jlong_cast (jdouble x) { return *(jlong* )&x; }
+-
+-inline jfloat jfloat_cast (jint x) { return *(jfloat* )&x; }
+-inline jdouble jdouble_cast(jlong x) { return *(jdouble*)&x; }
+
+ //----------------------------------------------------------------------------------------------------
+ // Constant for jlong (specifying an long long canstant is C++ compiler specific)
+--- ./hotspot/src/share/vm/utilities/growableArray.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/growableArray.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -147,6 +147,9 @@
+ }
+ };
+
++template<class E> class GrowableArrayIterator;
++template<class E, class UnaryPredicate> class GrowableArrayFilterIterator;
++
+ template<class E> class GrowableArray : public GenericGrowableArray {
+ friend class VMStructs;
+
+@@ -243,6 +246,14 @@
+ return _data[_len-1];
+ }
+
++ GrowableArrayIterator<E> begin() const {
++ return GrowableArrayIterator<E>(this, 0);
++ }
++
++ GrowableArrayIterator<E> end() const {
++ return GrowableArrayIterator<E>(this, length());
++ }
++
+ void push(const E& elem) { append(elem); }
+
+ E pop() {
+@@ -338,6 +349,7 @@
+
+ // inserts the given element before the element at index i
+ void insert_before(const int idx, const E& elem) {
++ assert(0 <= idx && idx <= _len, "illegal index");
+ check_nesting();
+ if (_len == _max) grow(_len);
+ for (int j = _len - 1; j >= idx; j--) {
+@@ -349,7 +361,7 @@
+
+ void appendAll(const GrowableArray<E>* l) {
+ for (int i = 0; i < l->_len; i++) {
+- raw_at_put_grow(_len, l->_data[i], 0);
++ raw_at_put_grow(_len, l->_data[i], E());
+ }
+ }
+
+@@ -412,4 +424,83 @@
+ tty->print("}\n");
+ }
+
++// Custom STL-style iterator to iterate over GrowableArrays
++// It is constructed by invoking GrowableArray::begin() and GrowableArray::end()
++template<class E> class GrowableArrayIterator : public StackObj {
++ friend class GrowableArray<E>;
++ template<class F, class UnaryPredicate> friend class GrowableArrayFilterIterator;
++
++ private:
++ const GrowableArray<E>* _array; // GrowableArray we iterate over
++ int _position; // The current position in the GrowableArray
++
++ // Private constructor used in GrowableArray::begin() and GrowableArray::end()
++ GrowableArrayIterator(const GrowableArray<E>* array, int position) : _array(array), _position(position) {
++ assert(0 <= position && position <= _array->length(), "illegal position");
++ }
++
++ public:
++ GrowableArrayIterator<E>& operator++() { ++_position; return *this; }
++ E operator*() { return _array->at(_position); }
++
++ bool operator==(const GrowableArrayIterator<E>& rhs) {
++ assert(_array == rhs._array, "iterator belongs to different array");
++ return _position == rhs._position;
++ }
++
++ bool operator!=(const GrowableArrayIterator<E>& rhs) {
++ assert(_array == rhs._array, "iterator belongs to different array");
++ return _position != rhs._position;
++ }
++};
++
++// Custom STL-style iterator to iterate over elements of a GrowableArray that satisfy a given predicate
++template<class E, class UnaryPredicate> class GrowableArrayFilterIterator : public StackObj {
++ friend class GrowableArray<E>;
++
++ private:
++ const GrowableArray<E>* _array; // GrowableArray we iterate over
++ int _position; // Current position in the GrowableArray
++ UnaryPredicate _predicate; // Unary predicate the elements of the GrowableArray should satisfy
++
++ public:
++ GrowableArrayFilterIterator(const GrowableArrayIterator<E>& begin, UnaryPredicate filter_predicate)
++ : _array(begin._array), _position(begin._position), _predicate(filter_predicate) {
++ // Advance to first element satisfying the predicate
++ while(_position != _array->length() && !_predicate(_array->at(_position))) {
++ ++_position;
++ }
++ }
++
++ GrowableArrayFilterIterator<E, UnaryPredicate>& operator++() {
++ do {
++ // Advance to next element satisfying the predicate
++ ++_position;
++ } while(_position != _array->length() && !_predicate(_array->at(_position)));
++ return *this;
++ }
++
++ E operator*() { return _array->at(_position); }
++
++ bool operator==(const GrowableArrayIterator<E>& rhs) {
++ assert(_array == rhs._array, "iterator belongs to different array");
++ return _position == rhs._position;
++ }
++
++ bool operator!=(const GrowableArrayIterator<E>& rhs) {
++ assert(_array == rhs._array, "iterator belongs to different array");
++ return _position != rhs._position;
++ }
++
++ bool operator==(const GrowableArrayFilterIterator<E, UnaryPredicate>& rhs) {
++ assert(_array == rhs._array, "iterator belongs to different array");
++ return _position == rhs._position;
++ }
++
++ bool operator!=(const GrowableArrayFilterIterator<E, UnaryPredicate>& rhs) {
++ assert(_array == rhs._array, "iterator belongs to different array");
++ return _position != rhs._position;
++ }
++};
++
+ #endif // SHARE_VM_UTILITIES_GROWABLEARRAY_HPP
+--- ./hotspot/src/share/vm/utilities/hashtable.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/hashtable.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -36,21 +36,22 @@
+ #include "utilities/numberSeq.hpp"
+
+
+-// This is a generic hashtable, designed to be used for the symbol
+-// and string tables.
+-//
+-// It is implemented as an open hash table with a fixed number of buckets.
+-//
+-// %note:
+-// - HashtableEntrys are allocated in blocks to reduce the space overhead.
++// This hashtable is implemented as an open hash table with a fixed number of buckets.
+
+-template <MEMFLAGS F> BasicHashtableEntry<F>* BasicHashtable<F>::new_entry(unsigned int hashValue) {
+- BasicHashtableEntry<F>* entry;
+-
+- if (_free_list) {
++template <MEMFLAGS F> BasicHashtableEntry<F>* BasicHashtable<F>::new_entry_free_list() {
++ BasicHashtableEntry<F>* entry = NULL;
++ if (_free_list != NULL) {
+ entry = _free_list;
+ _free_list = _free_list->next();
+- } else {
++ }
++ return entry;
++}
++
++// HashtableEntrys are allocated in blocks to reduce the space overhead.
++template <MEMFLAGS F> BasicHashtableEntry<F>* BasicHashtable<F>::new_entry(unsigned int hashValue) {
++ BasicHashtableEntry<F>* entry = new_entry_free_list();
++
++ if (entry == NULL) {
+ if (_first_free_entry + _entry_size >= _end_block) {
+ int block_size = MIN2(512, MAX2((int)_table_size / 2, (int)_number_of_entries));
+ int len = _entry_size * block_size;
+@@ -83,9 +84,9 @@
+ // This is somewhat an arbitrary heuristic but if one bucket gets to
+ // rehash_count which is currently 100, there's probably something wrong.
+
+-template <MEMFLAGS F> bool BasicHashtable<F>::check_rehash_table(int count) {
+- assert(table_size() != 0, "underflow");
+- if (count > (((double)number_of_entries()/(double)table_size())*rehash_multiple)) {
++template <class T, MEMFLAGS F> bool RehashableHashtable<T, F>::check_rehash_table(int count) {
++ assert(this->table_size() != 0, "underflow");
++ if (count > (((double)this->number_of_entries()/(double)this->table_size())*rehash_multiple)) {
+ // Set a flag for the next safepoint, which should be at some guaranteed
+ // safepoint interval.
+ return true;
+@@ -93,13 +94,13 @@
+ return false;
+ }
+
+-template <class T, MEMFLAGS F> juint Hashtable<T, F>::_seed = 0;
++template <class T, MEMFLAGS F> juint RehashableHashtable<T, F>::_seed = 0;
+
+ // Create a new table and using alternate hash code, populate the new table
+ // with the existing elements. This can be used to change the hash code
+ // and could in the future change the size of the table.
+
+-template <class T, MEMFLAGS F> void Hashtable<T, F>::move_to(Hashtable<T, F>* new_table) {
++template <class T, MEMFLAGS F> void RehashableHashtable<T, F>::move_to(RehashableHashtable<T, F>* new_table) {
+
+ // Initialize the global seed for hashing.
+ _seed = AltHashing::compute_seed();
+@@ -109,7 +110,7 @@
+
+ // Iterate through the table and create a new entry for the new table
+ for (int i = 0; i < new_table->table_size(); ++i) {
+- for (HashtableEntry<T, F>* p = bucket(i); p != NULL; ) {
++ for (HashtableEntry<T, F>* p = this->bucket(i); p != NULL; ) {
+ HashtableEntry<T, F>* next = p->next();
+ T string = p->literal();
+ // Use alternate hashing algorithm on the symbol in the first table
+@@ -238,11 +239,11 @@
+ }
+ }
+
+-template <class T, MEMFLAGS F> int Hashtable<T, F>::literal_size(Symbol *symbol) {
++template <class T, MEMFLAGS F> int RehashableHashtable<T, F>::literal_size(Symbol *symbol) {
+ return symbol->size() * HeapWordSize;
+ }
+
+-template <class T, MEMFLAGS F> int Hashtable<T, F>::literal_size(oop oop) {
++template <class T, MEMFLAGS F> int RehashableHashtable<T, F>::literal_size(oop oop) {
+ // NOTE: this would over-count if (pre-JDK8) java_lang_Class::has_offset_field() is true,
+ // and the String.value array is shared by several Strings. However, starting from JDK8,
+ // the String.value array is not shared anymore.
+@@ -255,12 +256,12 @@
+ // Note: if you create a new subclass of Hashtable<MyNewType, F>, you will need to
+ // add a new function Hashtable<T, F>::literal_size(MyNewType lit)
+
+-template <class T, MEMFLAGS F> void Hashtable<T, F>::dump_table(outputStream* st, const char *table_name) {
++template <class T, MEMFLAGS F> void RehashableHashtable<T, F>::dump_table(outputStream* st, const char *table_name) {
+ NumberSeq summary;
+ int literal_bytes = 0;
+ for (int i = 0; i < this->table_size(); ++i) {
+ int count = 0;
+- for (HashtableEntry<T, F>* e = bucket(i);
++ for (HashtableEntry<T, F>* e = this->bucket(i);
+ e != NULL; e = e->next()) {
+ count++;
+ literal_bytes += literal_size(e->literal());
+@@ -270,7 +271,7 @@
+ double num_buckets = summary.num();
+ double num_entries = summary.sum();
+
+- int bucket_bytes = (int)num_buckets * sizeof(bucket(0));
++ int bucket_bytes = (int)num_buckets * sizeof(HashtableBucket<F>);
+ int entry_bytes = (int)num_entries * sizeof(HashtableEntry<T, F>);
+ int total_bytes = literal_bytes + bucket_bytes + entry_bytes;
+
+@@ -352,12 +353,20 @@
+
+ #endif
+ // Explicitly instantiate these types
++#if INCLUDE_ALL_GCS
++template class Hashtable<nmethod*, mtGC>;
++template class HashtableEntry<nmethod*, mtGC>;
++template class BasicHashtable<mtGC>;
++#endif
+ template class Hashtable<ConstantPool*, mtClass>;
++template class RehashableHashtable<Symbol*, mtSymbol>;
++template class RehashableHashtable<oopDesc*, mtSymbol>;
+ template class Hashtable<Symbol*, mtSymbol>;
+ template class Hashtable<Klass*, mtClass>;
+ template class Hashtable<oop, mtClass>;
+ #if defined(SOLARIS) || defined(CHECK_UNHANDLED_OOPS)
+ template class Hashtable<oop, mtSymbol>;
++template class RehashableHashtable<oop, mtSymbol>;
+ #endif // SOLARIS || CHECK_UNHANDLED_OOPS
+ template class Hashtable<oopDesc*, mtSymbol>;
+ template class Hashtable<Symbol*, mtClass>;
+--- ./hotspot/src/share/vm/utilities/hashtable.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/hashtable.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -178,11 +178,6 @@
+ void verify_lookup_length(double load);
+ #endif
+
+- enum {
+- rehash_count = 100,
+- rehash_multiple = 60
+- };
+-
+ void initialize(int table_size, int entry_size, int number_of_entries);
+
+ // Accessor
+@@ -194,12 +189,12 @@
+ // The following method is not MT-safe and must be done under lock.
+ BasicHashtableEntry<F>** bucket_addr(int i) { return _buckets[i].entry_addr(); }
+
++ // Attempt to get an entry from the free list
++ BasicHashtableEntry<F>* new_entry_free_list();
++
+ // Table entry management
+ BasicHashtableEntry<F>* new_entry(unsigned int hashValue);
+
+- // Check that the table is unbalanced
+- bool check_rehash_table(int count);
+-
+ // Used when moving the entry to another table
+ // Clean up links, but do not add to free_list
+ void unlink_entry(BasicHashtableEntry<F>* entry) {
+@@ -277,8 +272,30 @@
+ return (HashtableEntry<T, F>**)BasicHashtable<F>::bucket_addr(i);
+ }
+
++};
++
++template <class T, MEMFLAGS F> class RehashableHashtable : public Hashtable<T, F> {
++ protected:
++
++ enum {
++ rehash_count = 100,
++ rehash_multiple = 60
++ };
++
++ // Check that the table is unbalanced
++ bool check_rehash_table(int count);
++
++ public:
++ RehashableHashtable(int table_size, int entry_size)
++ : Hashtable<T, F>(table_size, entry_size) { }
++
++ RehashableHashtable(int table_size, int entry_size,
++ HashtableBucket<F>* buckets, int number_of_entries)
++ : Hashtable<T, F>(table_size, entry_size, buckets, number_of_entries) { }
++
++
+ // Function to move these elements into the new table.
+- void move_to(Hashtable<T, F>* new_table);
++ void move_to(RehashableHashtable<T, F>* new_table);
+ static bool use_alternate_hashcode() { return _seed != 0; }
+ static juint seed() { return _seed; }
+
+@@ -292,7 +309,6 @@
+ static int literal_size(ConstantPool *cp) {Unimplemented(); return 0;}
+ static int literal_size(Klass *k) {Unimplemented(); return 0;}
+
+-public:
+ void dump_table(outputStream* st, const char *table_name);
+
+ private:
+--- ./hotspot/src/share/vm/utilities/hashtable.inline.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/hashtable.inline.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -26,6 +26,7 @@
+ #define SHARE_VM_UTILITIES_HASHTABLE_INLINE_HPP
+
+ #include "memory/allocation.inline.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "utilities/hashtable.hpp"
+ #include "utilities/dtrace.hpp"
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/utilities/linkedlist.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,114 @@
++/*
++ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++
++/////////////// Unit tests ///////////////
++
++#ifndef PRODUCT
++
++#include "runtime/os.hpp"
++#include "utilities/linkedlist.hpp"
++#include "memory/allocation.hpp"
++#include "memory/allocation.inline.hpp"
++
++class Integer : public StackObj {
++ private:
++ int _value;
++ public:
++ Integer(int i) : _value(i) { }
++
++ int value() const { return _value; }
++ bool equals(const Integer& i) const {
++ return _value == i.value();
++ }
++};
++
++int compare_Integer(const Integer& i1, const Integer& i2) {
++ return i1.value() - i2.value();
++}
++
++void check_list_values(const int* expected, const LinkedList<Integer>* list) {
++ LinkedListNode<Integer>* head = list->head();
++ int index = 0;
++ while (head != NULL) {
++ assert(head->peek()->value() == expected[index], "Unexpected value");
++ head = head->next();
++ index ++;
++ }
++}
++
++void Test_linked_list() {
++ LinkedListImpl<Integer, ResourceObj::C_HEAP, mtTest> ll;
++
++
++ // Test regular linked list
++ assert(ll.is_empty(), "Start with empty list");
++ Integer one(1), two(2), three(3), four(4), five(5), six(6);
++
++ ll.add(six);
++ assert(!ll.is_empty(), "Should not be empty");
++
++ Integer* i = ll.find(six);
++ assert(i != NULL, "Should find it");
++
++ i = ll.find(three);
++ assert(i == NULL, "Not in the list");
++
++ LinkedListNode<Integer>* node = ll.find_node(six);
++ assert(node != NULL, "6 is in the list");
++
++ ll.insert_after(three, node);
++ ll.insert_before(one, node);
++ int expected[3] = {1, 6, 3};
++ check_list_values(expected, &ll);
++
++ ll.add(two);
++ ll.add(four);
++ ll.add(five);
++
++ // Test sorted linked list
++ SortedLinkedList<Integer, compare_Integer, ResourceObj::C_HEAP, mtTest> sl;
++ assert(sl.is_empty(), "Start with empty list");
++
++ size_t ll_size = ll.size();
++ sl.move(&ll);
++ size_t sl_size = sl.size();
++
++ assert(ll_size == sl_size, "Should be the same size");
++ assert(ll.is_empty(), "No more entires");
++
++ // sorted result
++ int sorted_result[] = {1, 2, 3, 4, 5, 6};
++ check_list_values(sorted_result, &sl);
++
++ node = sl.find_node(four);
++ assert(node != NULL, "4 is in the list");
++ sl.remove_before(node);
++ sl.remove_after(node);
++ int remains[] = {1, 2, 4, 6};
++ check_list_values(remains, &sl);
++}
++#endif // PRODUCT
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/utilities/linkedlist.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,416 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_UTILITIES_LINKED_LIST_HPP
++#define SHARE_VM_UTILITIES_LINKED_LIST_HPP
++
++#include "memory/allocation.hpp"
++
++/*
++ * The implementation of a generic linked list, which uses various
++ * backing storages, such as C heap, arena and resource, etc.
++ */
++
++
++// An entry in a linked list. It should use the same backing storage
++// as the linked list that contains this entry.
++template <class E> class LinkedListNode : public ResourceObj {
++ private:
++ E _data; // embedded content
++ LinkedListNode<E>* _next; // next entry
++
++ protected:
++ LinkedListNode() : _next(NULL) { }
++
++ public:
++ LinkedListNode(const E& e): _data(e), _next(NULL) { }
++
++ inline void set_next(LinkedListNode<E>* node) { _next = node; }
++ inline LinkedListNode<E> * next() const { return _next; }
++
++ E* data() { return &_data; }
++ const E* peek() const { return &_data; }
++};
++
++// A linked list interface. It does not specify
++// any storage type it uses, so all methods involving
++// memory allocation or deallocation are pure virtual
++template <class E> class LinkedList : public ResourceObj {
++ protected:
++ LinkedListNode<E>* _head;
++
++ public:
++ LinkedList() : _head(NULL) { }
++
++ inline void set_head(LinkedListNode<E>* h) { _head = h; }
++ inline LinkedListNode<E>* head() const { return _head; }
++ inline bool is_empty() const { return head() == NULL; }
++
++ inline size_t size() const {
++ LinkedListNode<E>* p;
++ size_t count = 0;
++ for (p = head(); p != NULL; count++, p = p->next());
++ return count;
++ }
++
++ // Move all entries from specified linked list to this one
++ virtual void move(LinkedList<E>* list) = 0;
++
++ // Add an entry to this linked list
++ virtual LinkedListNode<E>* add(const E& e) = 0;
++ // Add all entries from specified linked list to this one,
++ virtual void add(LinkedListNode<E>* node) = 0;
++
++ // Add a linked list to this linked list
++ virtual bool add(const LinkedList<E>* list) = 0;
++
++ // Search entry in the linked list
++ virtual LinkedListNode<E>* find_node(const E& e) = 0;
++ virtual E* find(const E& e) = 0;
++
++ // Insert entry to the linked list
++ virtual LinkedListNode<E>* insert_before(const E& e, LinkedListNode<E>* ref) = 0;
++ virtual LinkedListNode<E>* insert_after (const E& e, LinkedListNode<E>* ref) = 0;
++
++ // Remove entry from the linked list
++ virtual bool remove(const E& e) = 0;
++ virtual bool remove(LinkedListNode<E>* node) = 0;
++ virtual bool remove_before(LinkedListNode<E>* ref) = 0;
++ virtual bool remove_after(LinkedListNode<E>* ref) = 0;
++
++ LinkedListNode<E>* unlink_head() {
++ LinkedListNode<E>* h = this->head();
++ if (h != NULL) {
++ this->set_head(h->next());
++ }
++ return h;
++ }
++
++ DEBUG_ONLY(virtual ResourceObj::allocation_type storage_type() = 0;)
++};
++
++// A linked list implementation.
++// The linked list can be allocated in various type of memory: C heap, arena and resource area, etc.
++template <class E, ResourceObj::allocation_type T = ResourceObj::C_HEAP,
++ MEMFLAGS F = mtNMT, AllocFailType alloc_failmode = AllocFailStrategy::RETURN_NULL>
++ class LinkedListImpl : public LinkedList<E> {
++ protected:
++ Arena* _arena;
++ public:
++ LinkedListImpl() : _arena(NULL) { }
++ LinkedListImpl(Arena* a) : _arena(a) { }
++
++ virtual ~LinkedListImpl() {
++ clear();
++ }
++
++ virtual void clear() {
++ LinkedListNode<E>* p = this->head();
++ this->set_head(NULL);
++ while (p != NULL) {
++ LinkedListNode<E>* to_delete = p;
++ p = p->next();
++ delete_node(to_delete);
++ }
++ }
++
++ // Add an entry to the linked list
++ virtual LinkedListNode<E>* add(const E& e) {
++ LinkedListNode<E>* node = this->new_node(e);
++ if (node != NULL) {
++ this->add(node);
++ }
++
++ return node;
++ }
++
++ virtual void add(LinkedListNode<E>* node) {
++ assert(node != NULL, "NULL pointer");
++ node->set_next(this->head());
++ this->set_head(node);
++ }
++
++ // Move a linked list to this linked list, both have to be allocated on the same
++ // storage type.
++ virtual void move(LinkedList<E>* list) {
++ assert(list->storage_type() == this->storage_type(), "Different storage type");
++ LinkedListNode<E>* node = this->head();
++ while (node != NULL && node->next() != NULL) {
++ node = node->next();
++ }
++ if (node == NULL) {
++ this->set_head(list->head());
++ } else {
++ node->set_next(list->head());
++ }
++ // All entries are moved
++ list->set_head(NULL);
++ }
++
++ virtual bool add(const LinkedList<E>* list) {
++ LinkedListNode<E>* node = list->head();
++ while (node != NULL) {
++ if (this->add(*node->peek()) == NULL) {
++ return false;
++ }
++ node = node->next();
++ }
++ return true;
++ }
++
++
++ virtual LinkedListNode<E>* find_node(const E& e) {
++ LinkedListNode<E>* p = this->head();
++ while (p != NULL && !p->peek()->equals(e)) {
++ p = p->next();
++ }
++ return p;
++ }
++
++ E* find(const E& e) {
++ LinkedListNode<E>* node = find_node(e);
++ return (node == NULL) ? NULL : node->data();
++ }
++
++
++ // Add an entry in front of the reference entry
++ LinkedListNode<E>* insert_before(const E& e, LinkedListNode<E>* ref_node) {
++ LinkedListNode<E>* node = this->new_node(e);
++ if (node == NULL) return NULL;
++ if (ref_node == this->head()) {
++ node->set_next(ref_node);
++ this->set_head(node);
++ } else {
++ LinkedListNode<E>* p = this->head();
++ while (p != NULL && p->next() != ref_node) {
++ p = p->next();
++ }
++ assert(p != NULL, "ref_node not in the list");
++ node->set_next(ref_node);
++ p->set_next(node);
++ }
++ return node;
++ }
++
++ // Add an entry behind the reference entry
++ LinkedListNode<E>* insert_after(const E& e, LinkedListNode<E>* ref_node) {
++ LinkedListNode<E>* node = this->new_node(e);
++ if (node == NULL) return NULL;
++ node->set_next(ref_node->next());
++ ref_node->set_next(node);
++ return node;
++ }
++
++ // Remove an entry from the linked list.
++ // Return true if the entry is successfully removed
++ virtual bool remove(const E& e) {
++ LinkedListNode<E>* tmp = this->head();
++ LinkedListNode<E>* prev = NULL;
++
++ while (tmp != NULL) {
++ if (tmp->peek()->equals(e)) {
++ return remove_after(prev);
++ }
++ prev = tmp;
++ tmp = tmp->next();
++ }
++ return false;
++ }
++
++ // Remove the node after the reference entry
++ virtual bool remove_after(LinkedListNode<E>* prev) {
++ LinkedListNode<E>* to_delete;
++ if (prev == NULL) {
++ to_delete = this->unlink_head();
++ } else {
++ to_delete = prev->next();
++ if (to_delete != NULL) {
++ prev->set_next(to_delete->next());
++ }
++ }
++
++ if (to_delete != NULL) {
++ delete_node(to_delete);
++ return true;
++ }
++ return false;
++ }
++
++ virtual bool remove(LinkedListNode<E>* node) {
++ LinkedListNode<E>* p = this->head();
++ while (p != NULL && p->next() != node) {
++ p = p->next();
++ }
++ if (p != NULL) {
++ p->set_next(node->next());
++ delete_node(node);
++ return true;
++ } else {
++ return false;
++ }
++ }
++
++ virtual bool remove_before(LinkedListNode<E>* ref) {
++ assert(ref != NULL, "NULL pointer");
++ LinkedListNode<E>* p = this->head();
++ LinkedListNode<E>* to_delete = NULL; // to be deleted
++ LinkedListNode<E>* prev = NULL; // node before the node to be deleted
++ while (p != NULL && p != ref) {
++ prev = to_delete;
++ to_delete = p;
++ p = p->next();
++ }
++ if (p == NULL || to_delete == NULL) return false;
++ assert(to_delete->next() == ref, "Wrong node to delete");
++ assert(prev == NULL || prev->next() == to_delete,
++ "Sanity check");
++ if (prev == NULL) {
++ assert(to_delete == this->head(), "Must be head");
++ this->set_head(to_delete->next());
++ } else {
++ prev->set_next(to_delete->next());
++ }
++ delete_node(to_delete);
++ return true;
++ }
++
++ DEBUG_ONLY(ResourceObj::allocation_type storage_type() { return T; })
++ protected:
++ // Create new linked list node object in specified storage
++ LinkedListNode<E>* new_node(const E& e) const {
++ switch(T) {
++ case ResourceObj::ARENA: {
++ assert(_arena != NULL, "Arena not set");
++ return new(_arena) LinkedListNode<E>(e);
++ }
++ case ResourceObj::RESOURCE_AREA:
++ case ResourceObj::C_HEAP: {
++ if (alloc_failmode == AllocFailStrategy::RETURN_NULL) {
++ return new(std::nothrow, T, F) LinkedListNode<E>(e);
++ } else {
++ return new(T, F) LinkedListNode<E>(e);
++ }
++ }
++ default:
++ ShouldNotReachHere();
++ }
++ return NULL;
++ }
++
++ // Delete linked list node object
++ void delete_node(LinkedListNode<E>* node) {
++ if (T == ResourceObj::C_HEAP) {
++ delete node;
++ }
++ }
++};
++
++// Sorted linked list. The linked list maintains sorting order specified by the comparison
++// function
++template <class E, int (*FUNC)(const E&, const E&),
++ ResourceObj::allocation_type T = ResourceObj::C_HEAP,
++ MEMFLAGS F = mtNMT, AllocFailType alloc_failmode = AllocFailStrategy::RETURN_NULL>
++ class SortedLinkedList : public LinkedListImpl<E, T, F, alloc_failmode> {
++ public:
++ SortedLinkedList() { }
++ SortedLinkedList(Arena* a) : LinkedListImpl<E, T, F, alloc_failmode>(a) { }
++
++ virtual LinkedListNode<E>* add(const E& e) {
++ return LinkedListImpl<E, T, F, alloc_failmode>::add(e);
++ }
++
++ virtual void move(LinkedList<E>* list) {
++ assert(list->storage_type() == this->storage_type(), "Different storage type");
++ LinkedListNode<E>* node;
++ while ((node = list->unlink_head()) != NULL) {
++ this->add(node);
++ }
++ assert(list->is_empty(), "All entries are moved");
++ }
++
++ virtual void add(LinkedListNode<E>* node) {
++ assert(node != NULL, "NULL pointer");
++ LinkedListNode<E>* tmp = this->head();
++ LinkedListNode<E>* prev = NULL;
++
++ int cmp_val;
++ while (tmp != NULL) {
++ cmp_val = FUNC(*tmp->peek(), *node->peek());
++ if (cmp_val >= 0) {
++ break;
++ }
++ prev = tmp;
++ tmp = tmp->next();
++ }
++
++ if (prev != NULL) {
++ node->set_next(prev->next());
++ prev->set_next(node);
++ } else {
++ node->set_next(this->head());
++ this->set_head(node);
++ }
++ }
++
++ virtual bool add(const LinkedList<E>* list) {
++ return LinkedListImpl<E, T, F, alloc_failmode>::add(list);
++ }
++
++ virtual LinkedListNode<E>* find_node(const E& e) {
++ LinkedListNode<E>* p = this->head();
++
++ while (p != NULL) {
++ int comp_val = FUNC(*p->peek(), e);
++ if (comp_val == 0) {
++ return p;
++ } else if (comp_val > 0) {
++ return NULL;
++ }
++ p = p->next();
++ }
++ return NULL;
++ }
++};
++
++// Iterates all entries in the list
++template <class E> class LinkedListIterator : public StackObj {
++ private:
++ LinkedListNode<E>* _p;
++ bool _is_empty;
++ public:
++ LinkedListIterator(LinkedListNode<E>* head) : _p(head) {
++ _is_empty = (head == NULL);
++ }
++
++ bool is_empty() const { return _is_empty; }
++
++ const E* next() {
++ if (_p == NULL) return NULL;
++ const E* e = _p->peek();
++ _p = _p->next();
++ return e;
++ }
++};
++
++#endif
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/utilities/nativeCallStack.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,119 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "runtime/os.hpp"
++#include "utilities/globalDefinitions.hpp"
++#include "utilities/nativeCallStack.hpp"
++
++const NativeCallStack NativeCallStack::EMPTY_STACK(0, false);
++
++NativeCallStack::NativeCallStack(int toSkip, bool fillStack) :
++ _hash_value(0) {
++
++#if !PLATFORM_NATIVE_STACK_WALKING_SUPPORTED
++ fillStack = false;
++#endif
++
++ if (fillStack) {
++ os::get_native_stack(_stack, NMT_TrackingStackDepth, toSkip);
++ } else {
++ for (int index = 0; index < NMT_TrackingStackDepth; index ++) {
++ _stack[index] = NULL;
++ }
++ }
++}
++
++NativeCallStack::NativeCallStack(address* pc, int frameCount) {
++ int frameToCopy = (frameCount < NMT_TrackingStackDepth) ?
++ frameCount : NMT_TrackingStackDepth;
++ int index;
++ for (index = 0; index < frameToCopy; index ++) {
++ _stack[index] = pc[index];
++ }
++ for (; index < NMT_TrackingStackDepth; index ++) {
++ _stack[index] = NULL;
++ }
++}
++
++// number of stack frames captured
++int NativeCallStack::frames() const {
++ int index;
++ for (index = 0; index < NMT_TrackingStackDepth; index ++) {
++ if (_stack[index] == NULL) {
++ break;
++ }
++ }
++ return index;
++}
++
++// Hash code. Any better algorithm?
++int NativeCallStack::hash() const {
++ long hash_val = _hash_value;
++ if (hash_val == 0) {
++ long pc;
++ int index;
++ for (index = 0; index < NMT_TrackingStackDepth; index ++) {
++ pc = (long)_stack[index];
++ if (pc == 0) break;
++ hash_val += pc;
++ }
++
++ NativeCallStack* p = const_cast<NativeCallStack*>(this);
++ p->_hash_value = (int)(hash_val & 0xFFFFFFFF);
++ }
++ return _hash_value;
++}
++
++void NativeCallStack::print_on(outputStream* out) const {
++ print_on(out, 0);
++}
++
++// Decode and print this call path
++void NativeCallStack::print_on(outputStream* out, int indent) const {
++ address pc;
++ char buf[1024];
++ int offset;
++ if (is_empty()) {
++ for (int index = 0; index < indent; index ++) out->print(" ");
++#if PLATFORM_NATIVE_STACK_WALKING_SUPPORTED
++ out->print("[BOOTSTRAP]");
++#else
++ out->print("[No stack]");
++#endif
++ } else {
++ for (int frame = 0; frame < NMT_TrackingStackDepth; frame ++) {
++ pc = get_frame(frame);
++ if (pc == NULL) break;
++ // Print indent
++ for (int index = 0; index < indent; index ++) out->print(" ");
++ if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
++ out->print_cr("[" PTR_FORMAT "] %s+0x%x", p2i(pc), buf, offset);
++ } else {
++ out->print_cr("[" PTR_FORMAT "]", p2i(pc));
++ }
++ }
++ }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/utilities/nativeCallStack.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,98 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_UTILITIES_NATIVE_CALL_STACK_HPP
++#define SHARE_VM_UTILITIES_NATIVE_CALL_STACK_HPP
++
++#include "memory/allocation.hpp"
++#include "services/nmtCommon.hpp"
++#include "utilities/ostream.hpp"
++
++/*
++ * This class represents a native call path (does not include Java frame)
++ *
++ * This class is developed in the context of native memory tracking, it can
++ * be an useful tool for debugging purpose.
++ *
++ * For example, following code should print out native call path:
++ *
++ * ....
++ * NativeCallStack here;
++ * here.print_on(tty);
++ * ....
++ *
++ * However, there are a couple of restrictions on this class. If the restrictions are
++ * not strictly followed, it may break native memory tracking badly.
++ *
++ * 1. Number of stack frames to capture, is defined by native memory tracking.
++ * This number has impacts on how much memory to be used by native
++ * memory tracking.
++ * 2. The class is strict stack object, no heap or virtual memory can be allocated
++ * from it.
++ */
++class NativeCallStack : public StackObj {
++ public:
++ static const NativeCallStack EMPTY_STACK;
++
++ private:
++ address _stack[NMT_TrackingStackDepth];
++ int _hash_value;
++
++ public:
++ NativeCallStack(int toSkip = 0, bool fillStack = false);
++ NativeCallStack(address* pc, int frameCount);
++
++
++ // if it is an empty stack
++ inline bool is_empty() const {
++ return _stack[0] == NULL;
++ }
++
++ // number of stack frames captured
++ int frames() const;
++
++ inline int compare(const NativeCallStack& other) const {
++ return memcmp(_stack, other._stack, sizeof(_stack));
++ }
++
++ inline bool equals(const NativeCallStack& other) const {
++ // compare hash values
++ if (hash() != other.hash()) return false;
++ // compare each frame
++ return compare(other) == 0;
++ }
++
++ inline address get_frame(int index) const {
++ assert(index >= 0 && index < NMT_TrackingStackDepth, "Index out of bound");
++ return _stack[index];
++ }
++
++ // Hash code. Any better algorithm?
++ int hash() const;
++
++ void print_on(outputStream* out) const;
++ void print_on(outputStream* out, int indent) const;
++};
++
++#endif
+--- ./hotspot/src/share/vm/utilities/ostream.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/ostream.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -24,6 +24,7 @@
+
+ #include "precompiled.hpp"
+ #include "compiler/compileLog.hpp"
++#include "gc_implementation/shared/gcId.hpp"
+ #include "oops/oop.inline.hpp"
+ #include "runtime/arguments.hpp"
+ #include "utilities/defaultStream.hpp"
+@@ -240,6 +241,14 @@
+ return;
+ }
+
++void outputStream::gclog_stamp(const GCId& gc_id) {
++ date_stamp(PrintGCDateStamps);
++ stamp(PrintGCTimeStamps);
++ if (PrintGCID) {
++ print("#%u: ", gc_id.id());
++ }
++}
++
+ outputStream& outputStream::indent() {
+ while (_position < _indentation) sp();
+ return *this;
+@@ -356,6 +365,7 @@
+ xmlStream* xtty;
+ outputStream* tty;
+ outputStream* gclog_or_tty;
++CDS_ONLY(fileStream* classlist_file;) // Only dump the classes that can be stored into the CDS archive
+ extern Mutex* tty_lock;
+
+ #define EXTRACHARLEN 32
+@@ -470,7 +480,8 @@
+ return buf;
+ }
+
+-// log_name comes from -XX:LogFile=log_name or -Xloggc:log_name
++// log_name comes from -XX:LogFile=log_name, -Xloggc:log_name or
++// -XX:DumpLoadedClassList=<file_name>
+ // in log_name, %p => pid1234 and
+ // %t => YYYY-MM-DD_HH-MM-SS
+ static const char* make_log_name(const char* log_name, const char* force_directory) {
+@@ -1191,6 +1202,16 @@
+ gclog_or_tty = gclog;
+ }
+
++#if INCLUDE_CDS
++ // For -XX:DumpLoadedClassList=<file> option
++ if (DumpLoadedClassList != NULL) {
++ const char* list_name = make_log_name(DumpLoadedClassList, NULL);
++ classlist_file = new(ResourceObj::C_HEAP, mtInternal)
++ fileStream(list_name);
++ FREE_C_HEAP_ARRAY(char, list_name, mtInternal);
++ }
++#endif
++
+ // If we haven't lazily initialized the logfile yet, do it now,
+ // to avoid the possibility of lazy initialization during a VM
+ // crash, which can affect the stability of the fatal error handler.
+@@ -1203,6 +1224,11 @@
+ static bool ostream_exit_called = false;
+ if (ostream_exit_called) return;
+ ostream_exit_called = true;
++#if INCLUDE_CDS
++ if (classlist_file != NULL) {
++ delete classlist_file;
++ }
++#endif
+ if (gclog_or_tty != tty) {
+ delete gclog_or_tty;
+ }
+--- ./hotspot/src/share/vm/utilities/ostream.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/ostream.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,6 +28,7 @@
+ #include "memory/allocation.hpp"
+ #include "runtime/timer.hpp"
+
++class GCId;
+ DEBUG_ONLY(class ResourceMark;)
+
+ // Output streams for printing
+@@ -107,6 +108,7 @@
+ void date_stamp(bool guard) {
+ date_stamp(guard, "", ": ");
+ }
++ void gclog_stamp(const GCId& gc_id);
+
+ // portable printing of 64 bit integers
+ void print_jlong(jlong value);
+@@ -212,6 +214,8 @@
+ void flush();
+ };
+
++CDS_ONLY(extern fileStream* classlist_file;)
++
+ // unlike fileStream, fdStream does unbuffered I/O by calling
+ // open() and write() directly. It is async-safe, but output
+ // from multiple thread may be mixed together. Used by fatal
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/utilities/stringUtils.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "utilities/stringUtils.hpp"
++
++int StringUtils::replace_no_expand(char* string, const char* from, const char* to) {
++ int replace_count = 0;
++ size_t from_len = strlen(from);
++ size_t to_len = strlen(to);
++ assert(from_len >= to_len, "must not expand input");
++
++ for (char* dst = string; *dst && (dst = strstr(dst, from)) != NULL;) {
++ char* left_over = dst + from_len;
++ memmove(dst, to, to_len); // does not copy trailing 0 of <to>
++ dst += to_len; // skip over the replacement.
++ memmove(dst, left_over, strlen(left_over) + 1); // copies the trailing 0 of <left_over>
++ ++ replace_count;
++ }
++
++ return replace_count;
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/src/share/vm/utilities/stringUtils.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++#ifndef SHARE_VM_UTILITIES_STRINGUTILS_HPP
++#define SHARE_VM_UTILITIES_STRINGUTILS_HPP
++
++#include "memory/allocation.hpp"
++
++class StringUtils : AllStatic {
++public:
++ // Replace the substring <from> with another string <to>. <to> must be
++ // no longer than <from>. The input string is modified in-place.
++ //
++ // Replacement is done in a single pass left-to-right. So replace_no_expand("aaa", "aa", "a")
++ // will result in "aa", not "a".
++ //
++ // Returns the count of substrings that have been replaced.
++ static int replace_no_expand(char* string, const char* from, const char* to);
++};
++
++#endif // SHARE_VM_UTILITIES_STRINGUTILS_HPP
+--- ./hotspot/src/share/vm/utilities/taskqueue.hpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/taskqueue.hpp Wed Feb 04 12:14:39 2015 -0800
+@@ -28,40 +28,8 @@
+ #include "memory/allocation.hpp"
+ #include "memory/allocation.inline.hpp"
+ #include "runtime/mutex.hpp"
++#include "runtime/orderAccess.inline.hpp"
+ #include "utilities/stack.hpp"
+-#ifdef TARGET_OS_ARCH_linux_x86
+-# include "orderAccess_linux_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_sparc
+-# include "orderAccess_linux_sparc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_zero
+-# include "orderAccess_linux_zero.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_solaris_x86
+-# include "orderAccess_solaris_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_solaris_sparc
+-# include "orderAccess_solaris_sparc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_windows_x86
+-# include "orderAccess_windows_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_arm
+-# include "orderAccess_linux_arm.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_linux_ppc
+-# include "orderAccess_linux_ppc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_aix_ppc
+-# include "orderAccess_aix_ppc.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_bsd_x86
+-# include "orderAccess_bsd_x86.inline.hpp"
+-#endif
+-#ifdef TARGET_OS_ARCH_bsd_zero
+-# include "orderAccess_bsd_zero.inline.hpp"
+-#endif
+
+ // Simple TaskQueue stats that are collected by default in debug builds.
+
+--- ./hotspot/src/share/vm/utilities/vmError.cpp Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/src/share/vm/utilities/vmError.cpp Wed Feb 04 12:14:39 2015 -0800
+@@ -31,7 +31,7 @@
+ #include "runtime/frame.inline.hpp"
+ #include "runtime/init.hpp"
+ #include "runtime/os.hpp"
+-#include "runtime/thread.hpp"
++#include "runtime/thread.inline.hpp"
+ #include "runtime/vmThread.hpp"
+ #include "runtime/vm_operations.hpp"
+ #include "services/memTracker.hpp"
+@@ -773,6 +773,11 @@
+ st->cr();
+ }
+
++ STEP(228, "(Native Memory Tracking)" )
++ if (_verbose) {
++ MemTracker::error_report(st);
++ }
++
+ STEP(230, "" )
+
+ if (_verbose) {
+@@ -897,9 +902,6 @@
+ static bool log_done = false; // done saving error log
+ static bool transmit_report_done = false; // done error reporting
+
+- // disble NMT to avoid further exception
+- MemTracker::shutdown(MemTracker::NMT_error_reporting);
+-
+ if (SuppressFatalErrorMessage) {
+ os::abort();
+ }
+--- ./hotspot/test/Makefile Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/Makefile Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -23,14 +23,36 @@
+ #
+
+ #
+-# Makefile to run various jdk tests
++# Makefile to run various hotspot tests
+ #
+
+ GETMIXEDPATH=echo
+
+-# Get OS/ARCH specifics
+-OSNAME = $(shell uname -s)
+-ifeq ($(OSNAME), SunOS)
++# Utilities used
++AWK = awk
++CAT = cat
++CD = cd
++CHMOD = chmod
++CP = cp
++CUT = cut
++DIRNAME = dirname
++ECHO = echo
++EGREP = egrep
++EXPAND = expand
++FIND = find
++MKDIR = mkdir
++PWD = pwd
++SED = sed
++SORT = sort
++TEE = tee
++UNAME = uname
++UNIQ = uniq
++WC = wc
++ZIP = zip
++
++# Get OS name from uname (Cygwin inexplicably adds _NT-5.1)
++UNAME_S := $(shell $(UNAME) -s | $(CUT) -f1 -d_)
++ifeq ($(UNAME_S), SunOS)
+ PLATFORM = solaris
+ SLASH_JAVA = /java
+ ARCH = $(shell uname -p)
+@@ -38,7 +60,7 @@
+ ARCH=i586
+ endif
+ endif
+-ifeq ($(OSNAME), Linux)
++ifeq ($(UNAME_S), Linux)
+ PLATFORM = linux
+ SLASH_JAVA = /java
+ ARCH = $(shell uname -m)
+@@ -46,7 +68,7 @@
+ ARCH = i586
+ endif
+ endif
+-ifeq ($(OSNAME), Darwin)
++ifeq ($(UNAME_S), Darwin)
+ PLATFORM = bsd
+ SLASH_JAVA = /java
+ ARCH = $(shell uname -m)
+@@ -54,7 +76,7 @@
+ ARCH = i586
+ endif
+ endif
+-ifeq ($(findstring BSD,$(OSNAME)), BSD)
++ifeq ($(findstring BSD,$(UNAME_S)), BSD)
+ PLATFORM = bsd
+ SLASH_JAVA = /java
+ ARCH = $(shell uname -m)
+@@ -63,12 +85,12 @@
+ endif
+ endif
+ ifeq ($(PLATFORM),)
+- # detect wether we're running in MKS or cygwin
+- ifeq ($(OSNAME), Windows_NT) # MKS
++ # detect whether we're running in MKS or cygwin
++ ifeq ($(UNAME_S), Windows_NT) # MKS
+ GETMIXEDPATH=dosname -s
+ endif
+- ifeq ($(findstring CYGWIN,$(OSNAME)), CYGWIN)
+- GETMIXEDPATH=cygpath -m -s
++ ifeq ($(findstring CYGWIN,$(UNAME_S)), CYGWIN)
++ GETMIXEDPATH=cygpath -m
+ endif
+ PLATFORM = windows
+ SLASH_JAVA = J:
+@@ -92,13 +114,6 @@
+ SLASH_JAVA = $(ALT_SLASH_JAVA)
+ endif
+
+-# Utilities used
+-CD = cd
+-CP = cp
+-ECHO = echo
+-MKDIR = mkdir
+-ZIP = zip
+-
+ # Root of this test area (important to use full paths in some places)
+ TEST_ROOT := $(shell pwd)
+
+@@ -136,17 +151,83 @@
+ endif
+
+ # How to create the test bundle (pass or fail, we want to create this)
+-BUNDLE_UP = ( $(MKDIR) -p `dirname $(ARCHIVE_BUNDLE)` \
+- && $(CD) $(ABS_TEST_OUTPUT_DIR) \
+- && $(ZIP) -q -r $(ARCHIVE_BUNDLE) . )
+-BUNDLE_UP_FAILED = ( exitCode=$$? && $(BUNDLE_UP) && exit $${exitCode} )
++# Follow command with ";$(BUNDLE_UP_AND_EXIT)", so it always gets executed.
++ZIP_UP_RESULTS = ( $(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)` \
++ && $(CD) $(ABS_TEST_OUTPUT_DIR) \
++ && $(CHMOD) -R a+r . \
++ && $(ZIP) -q -r $(ARCHIVE_BUNDLE) . )
++
++# important results files
++SUMMARY_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport/text/summary.txt")
++STATS_TXT_NAME = Stats.txt
++STATS_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/$(STATS_TXT_NAME)")
++RUNLIST = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/runlist.txt")
++PASSLIST = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/passlist.txt")
++FAILLIST = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/faillist.txt")
++EXITCODE = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/exitcode.txt")
++
++TESTEXIT = \
++ if [ ! -s $(EXITCODE) ] ; then \
++ $(ECHO) "ERROR: EXITCODE file not filled in."; \
++ $(ECHO) "1" > $(EXITCODE); \
++ fi ; \
++ testExitCode=`$(CAT) $(EXITCODE)`; \
++ $(ECHO) "EXIT CODE: $${testExitCode}"; \
++ exit $${testExitCode}
++
++BUNDLE_UP_AND_EXIT = \
++( \
++ jtregExitCode=$$? && \
++ _summary="$(SUMMARY_TXT)"; \
++ $(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \
++ $(ECHO) "$${jtregExitCode}" > $(EXITCODE); \
++ if [ -r "$${_summary}" ] ; then \
++ $(ECHO) "Summary: $(UNIQUE_DIR)" > $(STATS_TXT); \
++ $(EXPAND) $${_summary} | $(EGREP) -v ' Not run\.' > $(RUNLIST); \
++ $(EGREP) ' Passed\.' $(RUNLIST) \
++ | $(EGREP) -v ' Error\.' \
++ | $(EGREP) -v ' Failed\.' > $(PASSLIST); \
++ ( $(EGREP) ' Failed\.' $(RUNLIST); \
++ $(EGREP) ' Error\.' $(RUNLIST); \
++ $(EGREP) -v ' Passed\.' $(RUNLIST) ) \
++ | $(SORT) | $(UNIQ) > $(FAILLIST); \
++ if [ $${jtregExitCode} != 0 -o -s $(FAILLIST) ] ; then \
++ $(EXPAND) $(FAILLIST) \
++ | $(CUT) -d' ' -f1 \
++ | $(SED) -e 's@^@FAILED: @' >> $(STATS_TXT); \
++ if [ $${jtregExitCode} = 0 ] ; then \
++ jtregExitCode=1; \
++ fi; \
++ fi; \
++ runc="`$(CAT) $(RUNLIST) | $(WC) -l | $(AWK) '{print $$1;}'`"; \
++ passc="`$(CAT) $(PASSLIST) | $(WC) -l | $(AWK) '{print $$1;}'`"; \
++ failc="`$(CAT) $(FAILLIST) | $(WC) -l | $(AWK) '{print $$1;}'`"; \
++ exclc="FIXME CODETOOLS-7900176"; \
++ $(ECHO) "TEST STATS: name=$(UNIQUE_DIR) run=$${runc} pass=$${passc} fail=$${failc}" \
++ >> $(STATS_TXT); \
++ else \
++ $(ECHO) "Missing file: $${_summary}" >> $(STATS_TXT); \
++ fi; \
++ if [ -f $(STATS_TXT) ] ; then \
++ $(CAT) $(STATS_TXT); \
++ fi; \
++ $(ZIP_UP_RESULTS) ; \
++ $(TESTEXIT) \
++)
+
+ ################################################################
+
+ # Default make rule (runs jtreg_tests)
+-all: jtreg_tests
++all: hotspot_all
+ @$(ECHO) "Testing completed successfully"
+
++# Support "hotspot_" prefixed test make targets (too)
++# The hotspot_% targets are used by the top level Makefile
++# Unless explicitly defined below, hotspot_<x> is interpreted as a jtreg test group name
++hotspot_%:
++ $(ECHO) "Running tests: $@"
++ $(MAKE) -j 1 TEST_SELECTION=":$@" UNIQUE_DIR=$@ jtreg_tests;
++
+ # Prep for output
+ prep: clean
+ @$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR)
+@@ -163,20 +244,37 @@
+
+ # Expect JT_HOME to be set for jtreg tests. (home for jtreg)
+ ifndef JT_HOME
+- JT_HOME = $(SLASH_JAVA)/re/jtreg/4.0/promoted/latest/binaries/jtreg
+-endif
+-ifdef JPRT_JTREG_HOME
+- JT_HOME = $(JPRT_JTREG_HOME)
++ JT_HOME = $(SLASH_JAVA)/re/jtreg/4.1/promoted/latest/binaries/jtreg
++ ifdef JPRT_JTREG_HOME
++ JT_HOME = $(JPRT_JTREG_HOME)
++ endif
+ endif
+
+-# Expect JPRT to set TESTDIRS to the jtreg test dirs
+-JTREG_TESTDIRS = demo/jvmti/gctest demo/jvmti/hprof
++# When called from JPRT the TESTDIRS variable is set to the jtreg tests to run
+ ifdef TESTDIRS
+- JTREG_TESTDIRS = $(TESTDIRS)
++ TEST_SELECTION = $(TESTDIRS)
+ endif
+
+-# Default JTREG to run (win32 script works for everybody)
+-JTREG = $(JT_HOME)/win32/bin/jtreg
++ifdef CONCURRENCY
++ EXTRA_JTREG_OPTIONS += -concurrency:$(CONCURRENCY)
++endif
++
++# Default JTREG to run
++JTREG = $(JT_HOME)/bin/jtreg
++
++# Only run automatic tests
++JTREG_BASIC_OPTIONS += -a
++# Report details on all failed or error tests, times too
++JTREG_BASIC_OPTIONS += -v:fail,error,time
++# Retain all files for failing tests
++JTREG_BASIC_OPTIONS += -retain:fail,error
++# Ignore tests are not run and completely silent about it
++JTREG_IGNORE_OPTION = -ignore:quiet
++JTREG_BASIC_OPTIONS += $(JTREG_IGNORE_OPTION)
++# Add any extra options
++JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS)
++# Set other vm and test options
++JTREG_TEST_OPTIONS = $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_OPTIONS:%=-vmoption:%) $(JAVA_VM_ARGS:%=-vmoption:%)
+
+ # Option to tell jtreg to not run tests marked with "ignore"
+ ifeq ($(PLATFORM), windows)
+@@ -184,20 +282,26 @@
+ else
+ JTREG_KEY_OPTION = -k:\!ignore
+ endif
++JTREG_BASIC_OPTIONS += $(JTREG_KEY_OPTION)
++
++# Make sure jtreg exists
++$(JTREG): $(JT_HOME)
+
+-#EXTRA_JTREG_OPTIONS =
+-
+-jtreg_tests: prep $(JT_HOME) $(PRODUCT_HOME) $(JTREG)
+- $(JTREG) -a -v:fail,error \
+- $(JTREG_KEY_OPTION) \
+- $(EXTRA_JTREG_OPTIONS) \
+- -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/JTreport \
+- -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/JTwork \
+- -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)") \
+- $(JAVA_OPTIONS:%=-vmoption:%) \
+- $(JTREG_TESTDIRS) \
+- || $(BUNDLE_UP_FAILED)
+- $(BUNDLE_UP)
++jtreg_tests: prep $(PRODUCT_HOME) $(JTREG)
++ ( \
++ ( JT_HOME=$(shell $(GETMIXEDPATH) "$(JT_HOME)"); \
++ export JT_HOME; \
++ $(shell $(GETMIXEDPATH) "$(JTREG)") \
++ $(JTREG_BASIC_OPTIONS) \
++ -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport") \
++ -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTwork") \
++ -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)") \
++ $(JTREG_EXCLUSIONS) \
++ $(JTREG_TEST_OPTIONS) \
++ $(TEST_SELECTION) \
++ ) ; \
++ $(BUNDLE_UP_AND_EXIT) \
++ ) 2>&1 | $(TEE) $(ABS_TEST_OUTPUT_DIR)/output.txt ; $(TESTEXIT)
+
+ PHONY_LIST += jtreg_tests
+
+@@ -205,7 +309,7 @@
+
+ # clienttest (make sure various basic java client options work)
+
+-clienttest: prep $(PRODUCT_HOME)
++hotspot_clienttest clienttest: prep $(PRODUCT_HOME)
+ $(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -version
+ $(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -help
+ $(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -X
+@@ -213,73 +317,38 @@
+ $(RM) $(PRODUCT_HOME)/jre/bin/client/classes.jsa
+ $(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -Xshare:dump
+
+-PHONY_LIST += clienttest
++PHONY_LIST += hotspot_clienttest clienttest
++
++################################################################
++
++# minimaltest (make sure various basic java minimal options work)
++
++hotspot_minimaltest minimaltest: prep $(PRODUCT_HOME)
++ $(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -version
++ $(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -help
++ $(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -X
++
++PHONY_LIST += hotspot_minimaltest minimaltest
+
+ ################################################################
+
+ # servertest (make sure various basic java server options work)
+
+-servertest: prep $(PRODUCT_HOME)
++hotspot_servertest servertest: prep $(PRODUCT_HOME)
+ $(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -version
+ $(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -help
+ $(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -X
+
+-PHONY_LIST += servertest
++PHONY_LIST += hotspot_servertest servertest
+
+ ################################################################
+
+ # internalvmtests (run internal unit tests inside the VM)
+
+-internalvmtests: prep $(PRODUCT_HOME)
++hotspot_internalvmtests internalvmtests: prep $(PRODUCT_HOME)
+ $(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -XX:+ExecuteInternalVMTests -version
+
+-PHONY_LIST += internalvmtests
+-
+-################################################################
+-
+-# wbapitest (make sure the whitebox testing api classes work
+-
+-wbapitest: prep $(JT_HOME) $(PRODUCT_HOME) $(JTREG)
+- $(JTREG) -a -v:fail,error \
+- $(JTREG_KEY_OPTION) \
+- $(EXTRA_JTREG_OPTIONS) \
+- -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/JTreport \
+- -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/JTwork \
+- -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)") \
+- $(JAVA_OPTIONS:%=-vmoption:%) \
+- $(shell $(GETMIXEDPATH) "$(TEST_ROOT)")/sanity \
+- || $(BUNDLE_UP_FAILED)
+- $(BUNDLE_UP)
+-
+-PHONY_LIST += wbapitest
+-
+-################################################################
+-
+-# packtest
+-
+-# Expect JPRT to set JPRT_PACKTEST_HOME.
+-PACKTEST_HOME = /net/jprt-web.sfbay.sun.com/jprt/allproducts/packtest
+-ifdef JPRT_PACKTEST_HOME
+- PACKTEST_HOME = $(JPRT_PACKTEST_HOME)
+-endif
+-
+-#EXTRA_PACKTEST_OPTIONS =
+-
+-packtest: prep $(PACKTEST_HOME)/ptest $(PRODUCT_HOME)
+- ( $(CD) $(PACKTEST_HOME) && \
+- $(PACKTEST_HOME)/ptest \
+- -t "$(PRODUCT_HOME)" \
+- $(PACKTEST_STRESS_OPTION) \
+- $(EXTRA_PACKTEST_OPTIONS) \
+- -W $(ABS_TEST_OUTPUT_DIR) \
+- $(JAVA_OPTIONS:%=-J %) \
+- ) || $(BUNDLE_UP_FAILED)
+- $(BUNDLE_UP)
+-
+-packtest_stress: PACKTEST_STRESS_OPTION=-s
+-packtest_stress: packtest
+-
+-PHONY_LIST += packtest packtest_stress
++PHONY_LIST += hotspot_internalvmtests internalvmtests
+
+ ################################################################
+
+@@ -287,4 +356,3 @@
+ .PHONY: all clean prep $(PHONY_LIST)
+
+ ################################################################
+-
+--- ./hotspot/test/TEST.ROOT Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/TEST.ROOT Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -27,6 +27,7 @@
+ # It also contains test-suite configuration information.
+
+ # The list of keywords supported in this test suite
+-keys=cte_test jcmd nmt regression gc
++keys=cte_test jcmd nmt regression gc stress
+
+ groups=TEST.groups [closed/TEST.groups]
++requires.properties=sun.arch.data.model
+--- ./hotspot/test/TEST.groups Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/TEST.groups Wed Feb 04 12:14:39 2015 -0800
+@@ -73,15 +73,24 @@
+ runtime/jsig/Test8017498.sh \
+ runtime/Metaspace/FragmentMetaspace.java \
+ runtime/NMT/BaselineWithParameter.java \
++ runtime/NMT/JcmdBaselineDetail.java \
++ runtime/NMT/JcmdDetailDiff.java \
++ runtime/NMT/JcmdScaleDetail.java \
+ runtime/NMT/JcmdScale.java \
+ runtime/NMT/JcmdWithNMTDisabled.java \
++ runtime/NMT/MallocRoundingReportTest.java \
++ runtime/NMT/MallocSiteHashOverflow.java \
++ runtime/NMT/MallocStressTest.java \
+ runtime/NMT/MallocTestType.java \
++ runtime/NMT/MallocTrackingVerify.java \
+ runtime/NMT/ReleaseCommittedMemory.java \
++ runtime/NMT/ReleaseNoCommit.java \
+ runtime/NMT/ShutdownTwice.java \
+ runtime/NMT/SummaryAfterShutdown.java \
+ runtime/NMT/SummarySanityCheck.java \
+ runtime/NMT/ThreadedMallocTestType.java \
+ runtime/NMT/ThreadedVirtualAllocTestType.java \
++ runtime/NMT/VirtualAllocCommitUncommitRecommit.java \
+ runtime/NMT/VirtualAllocTestType.java \
+ runtime/RedefineObject/TestRedefineObject.java \
+ runtime/Thread/TestThreadDumpMonitorContention.java \
+@@ -115,6 +124,27 @@
+ -:needs_jdk
+
+
++# When called from top level the test suites use the hotspot_ prefix
++hotspot_wbapitest = \
++ sanity/
++
++hotspot_compiler = \
++ sanity/ExecuteInternalVMTests.java
++
++hotspot_gc = \
++ sanity/ExecuteInternalVMTests.java
++
++hotspot_runtime = \
++ sanity/ExecuteInternalVMTests.java
++
++hotspot_serviceability = \
++ sanity/ExecuteInternalVMTests.java
++
++hotspot_all = \
++ :hotspot_compiler \
++ :hotspot_gc \
++ :hotspot_runtime \
++ :hotspot_serviceability
+ # Tests that require compact3 API's
+ #
+ needs_compact3 = \
+@@ -129,10 +159,19 @@
+ gc/6581734/Test6581734.java \
+ gc/7072527/TestFullGCCount.java \
+ gc/g1/TestHumongousAllocInitialMark.java \
++ gc/g1/TestHumongousShrinkHeap.java \
+ gc/arguments/TestG1HeapRegionSize.java \
+ gc/metaspace/TestMetaspaceMemoryPool.java \
+ gc/arguments/TestDynMinHeapFreeRatio.java \
+ gc/arguments/TestDynMaxHeapFreeRatio.java \
++ gc/g1/TestShrinkAuxiliaryData00.java \
++ gc/g1/TestShrinkAuxiliaryData05.java \
++ gc/g1/TestShrinkAuxiliaryData10.java \
++ gc/g1/TestShrinkAuxiliaryData15.java \
++ gc/g1/TestShrinkAuxiliaryData20.java \
++ gc/g1/TestShrinkAuxiliaryData25.java \
++ gc/g1/TestShrinkAuxiliaryData30.java \
++ gc/survivorAlignment \
+ runtime/InternalApi/ThreadCpuTimesDeadlock.java \
+ serviceability/threads/TestFalseDeadLock.java \
+ serviceability/jvmti/GetObjectSizeOverflow.java \
+@@ -169,6 +208,8 @@
+ #
+ needs_full_vm_compact1 = \
+ runtime/NMT \
++ gc/class_unloading/TestCMSClassUnloadingEnabledHWM.java \
++ gc/class_unloading/TestG1ClassUnloadingHWM.java \
+ gc/g1/TestRegionAlignment.java \
+ gc/g1/TestShrinkToOneRegion.java \
+ gc/metaspace/G1AddMetaspaceDependency.java \
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/EliminateAutoBox/UnsignedLoads.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,63 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.
++ */
++
++/*
++ * @test
++ * @library /testlibrary
++ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+EliminateAutoBox
++ * -XX:CompileOnly=::valueOf,::byteValue,::shortValue,::testUnsignedByte,::testUnsignedShort
++ * UnsignedLoads
++ */
++import static com.oracle.java.testlibrary.Asserts.assertEQ;
++
++public class UnsignedLoads {
++ public static int testUnsignedByte() {
++ byte[] bytes = new byte[] {-1};
++ int res = 0;
++ for (int i = 0; i < 100000; i++) {
++ for (Byte b : bytes) {
++ res = b & 0xff;
++ }
++ }
++ return res;
++ }
++
++ public static int testUnsignedShort() {
++ int res = 0;
++ short[] shorts = new short[] {-1};
++ for (int i = 0; i < 100000; i++) {
++ for (Short s : shorts) {
++ res = s & 0xffff;
++ }
++ }
++ return res;
++ }
++
++ public static void main(String[] args) {
++ assertEQ(testUnsignedByte(), 255);
++ assertEQ(testUnsignedShort(), 65535);
++ System.out.println("TEST PASSED");
++ }
++}
+--- ./hotspot/test/compiler/ciReplay/common.sh Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/ciReplay/common.sh Wed Feb 04 12:14:39 2015 -0800
+@@ -213,7 +213,7 @@
+ -XX:VMThreadStackSize=512 \
+ -XX:CompilerThreadStackSize=512 \
+ -XX:ParallelGCThreads=1 \
+- -XX:CICompilerCount=1 \
++ -XX:CICompilerCount=2 \
+ -Xcomp \
+ -XX:CICrashAt=1 \
+ -XX:+CreateMinidumpOnCrash \
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,130 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import sun.hotspot.WhiteBox;
++import sun.misc.Unsafe;
++import sun.misc.IOUtils;
++
++import java.lang.reflect.Method;
++import java.net.URL;
++import java.net.URLConnection;
++
++/*
++ * @test TestAnonymousClassUnloading
++ * @bug 8054402
++ * @summary "Tests unloading of anonymous classes."
++ * @library /testlibrary /testlibrary/whitebox
++ * @compile TestAnonymousClassUnloading.java
++ * @run main ClassFileInstaller TestAnonymousClassUnloading
++ * sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation TestAnonymousClassUnloading
++ */
++public class TestAnonymousClassUnloading {
++ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
++ private static final Unsafe UNSAFE = Unsafe.getUnsafe();
++ private static int COMP_LEVEL_SIMPLE = 1;
++ private static int COMP_LEVEL_FULL_OPTIMIZATION = 4;
++
++ /**
++ * We override hashCode here to be able to access this implementation
++ * via an Object reference (we cannot cast to TestAnonymousClassUnloading).
++ */
++ @Override
++ public int hashCode() {
++ return 42;
++ }
++
++ /**
++ * Does some work by using the anonymousClass.
++ * @param anonymousClass Class performing some work (will be unloaded)
++ */
++ static private void doWork(Class<?> anonymousClass) throws InstantiationException, IllegalAccessException {
++ // Create a new instance
++ Object anon = anonymousClass.newInstance();
++ // We would like to call a method of anonymousClass here but we cannot cast because the class
++ // was loaded by a different class loader. One solution would be to use reflection but since
++ // we want C2 to implement the call as an IC we call Object::hashCode() here which actually
++ // calls anonymousClass::hashCode(). C2 will then implement this call as an IC.
++ if (anon.hashCode() != 42) {
++ new RuntimeException("Work not done");
++ }
++ }
++
++ /**
++ * Makes sure that method is compiled by forcing compilation if not yet compiled.
++ * @param m Method to be checked
++ */
++ static private void makeSureIsCompiled(Method m) {
++ // Make sure background compilation is disabled
++ if (WHITE_BOX.getBooleanVMFlag("BackgroundCompilation")) {
++ throw new RuntimeException("Background compilation enabled");
++ }
++
++ // Check if already compiled
++ if (!WHITE_BOX.isMethodCompiled(m)) {
++ // If not, try to compile it with C2
++ if(!WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION)) {
++ // C2 compiler not available, try to compile with C1
++ WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_SIMPLE);
++ }
++ // Because background compilation is disabled, method should now be compiled
++ if(!WHITE_BOX.isMethodCompiled(m)) {
++ throw new RuntimeException(m + " not compiled");
++ }
++ }
++ }
++
++ /**
++ * This test creates stale Klass* metadata referenced by a compiled IC.
++ *
++ * The following steps are performed:
++ * (1) An anonymous version of TestAnonymousClassUnloading is loaded by a custom class loader
++ * (2) The method doWork that calls a method of the anonymous class is compiled. The call
++ * is implemented as an IC referencing Klass* metadata of the anonymous class.
++ * (3) Unloading of the anonymous class is enforced. The IC now references dead metadata.
++ */
++ static public void main(String[] args) throws Exception {
++ // (1) Load an anonymous version of this class using the corresponding Unsafe method
++ URL classUrl = TestAnonymousClassUnloading.class.getResource("TestAnonymousClassUnloading.class");
++ URLConnection connection = classUrl.openConnection();
++ byte[] classBytes = IOUtils.readFully(connection.getInputStream(), connection.getContentLength(), true);
++ Class<?> anonymousClass = UNSAFE.defineAnonymousClass(TestAnonymousClassUnloading.class, classBytes, null);
++
++ // (2) Make sure all paths of doWork are profiled and compiled
++ for (int i = 0; i < 100000; ++i) {
++ doWork(anonymousClass);
++ }
++
++ // Make sure doWork is compiled now
++ Method doWork = TestAnonymousClassUnloading.class.getDeclaredMethod("doWork", Class.class);
++ makeSureIsCompiled(doWork);
++
++ // (3) Throw away reference to anonymousClass to allow unloading
++ anonymousClass = null;
++
++ // Force garbage collection to trigger unloading of anonymousClass
++ // Dead metadata reference to anonymousClass triggers JDK-8054402
++ WHITE_BOX.fullGC();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/classUnloading/methodUnloading/TestMethodUnloading.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,145 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import sun.hotspot.WhiteBox;
++
++import java.lang.reflect.Method;
++import java.net.URL;
++import java.net.URLClassLoader;
++
++/*
++ * @test MethodUnloadingTest
++ * @bug 8029443
++ * @summary "Tests the unloading of methods to to class unloading"
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestMethodUnloading
++ * @build WorkerClass
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation -XX:-UseCompressedOops -XX:CompileOnly=TestMethodUnloading::doWork TestMethodUnloading
++ */
++public class TestMethodUnloading {
++ private static final String workerClassName = "WorkerClass";
++ private static int work = -1;
++
++ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
++ private static int COMP_LEVEL_SIMPLE = 1;
++ private static int COMP_LEVEL_FULL_OPTIMIZATION = 4;
++
++ /**
++ * Does some work by either using the workerClass or locally producing values.
++ * @param workerClass Class performing some work (will be unloaded)
++ * @param useWorker If true the workerClass is used
++ */
++ static private void doWork(Class<?> workerClass, boolean useWorker) throws InstantiationException, IllegalAccessException {
++ if (useWorker) {
++ // Create a new instance
++ Object worker = workerClass.newInstance();
++ // We would like to call a method of WorkerClass here but we cannot cast to WorkerClass
++ // because the class was loaded by a different class loader. One solution would be to use
++ // reflection but since we want C2 to implement the call as an optimized IC we call
++ // Object::hashCode() here which actually calls WorkerClass::hashCode().
++ // C2 will then implement this call as an optimized IC that points to a to-interpreter stub
++ // referencing the Method* for WorkerClass::hashCode().
++ work = worker.hashCode();
++ if (work != 42) {
++ new RuntimeException("Work not done");
++ }
++ } else {
++ // Do some important work here
++ work = 1;
++ }
++ }
++
++ /**
++ * Makes sure that method is compiled by forcing compilation if not yet compiled.
++ * @param m Method to be checked
++ */
++ static private void makeSureIsCompiled(Method m) {
++ // Make sure background compilation is disabled
++ if (WHITE_BOX.getBooleanVMFlag("BackgroundCompilation")) {
++ throw new RuntimeException("Background compilation enabled");
++ }
++
++ // Check if already compiled
++ if (!WHITE_BOX.isMethodCompiled(m)) {
++ // If not, try to compile it with C2
++ if(!WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION)) {
++ // C2 compiler not available, try to compile with C1
++ WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_SIMPLE);
++ }
++ // Because background compilation is disabled, method should now be compiled
++ if(!WHITE_BOX.isMethodCompiled(m)) {
++ throw new RuntimeException(m + " not compiled");
++ }
++ }
++ }
++
++ /**
++ * This test creates stale Method* metadata in a to-interpreter stub of an optimized IC.
++ *
++ * The following steps are performed:
++ * (1) A workerClass is loaded by a custom class loader
++ * (2) The method doWork that calls a method of the workerClass is compiled. The call
++ * is implemented as an optimized IC calling a to-interpreted stub. The to-interpreter
++ * stub contains a Method* to a workerClass method.
++ * (3) Unloading of the workerClass is enforced. The to-interpreter stub now contains a dead Method*.
++ * (4) Depending on the implementation of the IC, the compiled version of doWork should still be
++ * valid. We call it again without using the workerClass.
++ */
++ static public void main(String[] args) throws Exception {
++ // (1) Create a custom class loader with no parent class loader
++ URL url = TestMethodUnloading.class.getProtectionDomain().getCodeSource().getLocation();
++ URLClassLoader loader = new URLClassLoader(new URL[] {url}, null);
++
++ // Load worker class with custom class loader
++ Class<?> workerClass = Class.forName(workerClassName, true, loader);
++
++ // (2) Make sure all paths of doWork are profiled and compiled
++ for (int i = 0; i < 100000; ++i) {
++ doWork(workerClass, true);
++ doWork(workerClass, false);
++ }
++
++ // Make sure doWork is compiled now
++ Method doWork = TestMethodUnloading.class.getDeclaredMethod("doWork", Class.class, boolean.class);
++ makeSureIsCompiled(doWork);
++
++ // (3) Throw away class loader and reference to workerClass to allow unloading
++ loader.close();
++ loader = null;
++ workerClass = null;
++
++ // Force garbage collection to trigger unloading of workerClass
++ // Dead reference to WorkerClass::hashCode triggers JDK-8029443
++ WHITE_BOX.fullGC();
++
++ // (4) Depending on the implementation of the IC, the compiled version of doWork
++ // may still be valid here. Execute it without a workerClass.
++ doWork(null, false);
++ if (work != 1) {
++ throw new RuntimeException("Work not done");
++ }
++
++ doWork(Object.class, false);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/classUnloading/methodUnloading/WorkerClass.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Worker class that is dynamically loaded/unloaded by TestMethodUnloading.
++ */
++public class WorkerClass {
++ /**
++ * We override hashCode here to be able to access this implementation
++ * via an Object reference (we cannot cast to WorkerClass).
++ */
++ @Override
++ public int hashCode() {
++ return 42;
++ }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/dependencies/MonomorphicObjectCall/TestMonomorphicObjectCall.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,73 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.io.File;
++import java.util.ArrayList;
++import java.util.Collections;
++
++import com.oracle.java.testlibrary.*;
++
++/*
++ * @test
++ * @bug 8050079
++ * @summary Compiles a monomorphic call to finalizeObject() on a modified java.lang.Object to test C1 CHA.
++ * @library /testlibrary
++ * @compile -XDignore.symbol.file java/lang/Object.java TestMonomorphicObjectCall.java
++ * @run main TestMonomorphicObjectCall
++ */
++public class TestMonomorphicObjectCall {
++ final static String testClasses = System.getProperty("test.classes") + File.separator;
++
++ private static void callFinalize(Object object) throws Throwable {
++ // Call modified version of java.lang.Object::finalize() that is
++ // not overridden by any subclass. C1 CHA should mark the call site
++ // as monomorphic and inline the method.
++ object.finalizeObject();
++ }
++
++ public static void main(String[] args) throws Throwable {
++ if (args.length == 0) {
++ // Execute new instance with modified java.lang.Object
++ executeTestJvm();
++ } else {
++ // Trigger compilation of 'callFinalize'
++ callFinalize(new Object());
++ }
++ }
++
++ public static void executeTestJvm() throws Throwable {
++ // Execute test with modified version of java.lang.Object
++ // in -Xbootclasspath.
++ String[] vmOpts = new String[] {
++ "-Xbootclasspath/p:" + testClasses,
++ "-Xcomp",
++ "-XX:-VerifyDependencies",
++ "-XX:CompileOnly=TestMonomorphicObjectCall::callFinalize",
++ "-XX:CompileOnly=Object::finalizeObject",
++ "-XX:TieredStopAtLevel=1",
++ TestMonomorphicObjectCall.class.getName(),
++ "true"};
++ OutputAnalyzer output = ProcessTools.executeTestJvm(vmOpts);
++ output.shouldHaveExitValue(0);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/dependencies/MonomorphicObjectCall/java/lang/Object.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,87 @@
++/*
++ * Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 java.lang;
++
++/**
++ * Slightly modified version of java.lang.Object that replaces
++ * finalize() by finalizeObject() to avoid overriding in subclasses.
++ */
++public class Object {
++
++ private static native void registerNatives();
++ static {
++ registerNatives();
++ }
++
++ public final native Class<?> getClass();
++
++ public native int hashCode();
++
++ public boolean equals(Object obj) {
++ return (this == obj);
++ }
++
++ protected native Object clone() throws CloneNotSupportedException;
++
++ public String toString() {
++ return getClass().getName() + "@" + Integer.toHexString(hashCode());
++ }
++
++ public final native void notify();
++
++ public final native void notifyAll();
++
++ public final native void wait(long timeout) throws InterruptedException;
++
++ public final void wait(long timeout, int nanos) throws InterruptedException {
++ if (timeout < 0) {
++ throw new IllegalArgumentException("timeout value is negative");
++ }
++
++ if (nanos < 0 || nanos > 999999) {
++ throw new IllegalArgumentException(
++ "nanosecond timeout value out of range");
++ }
++
++ if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
++ timeout++;
++ }
++
++ wait(timeout);
++ }
++
++ public final void wait() throws InterruptedException {
++ wait(0);
++ }
++
++ /**
++ * Replaces original finalize() method and is therefore not
++ * overridden by any subclasses of Object.
++ * @throws Throwable
++ */
++ // protected void finalize() throws Throwable { }
++ public void finalizeObject() throws Throwable { }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/exceptions/CatchInlineExceptions.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,81 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8059299
++ * @summary assert(adr_type != NULL) failed: expecting TypeKlassPtr
++ * @run main/othervm -Xbatch CatchInlineExceptions
++ */
++
++class Exception1 extends Exception {};
++class Exception2 extends Exception {};
++
++public class CatchInlineExceptions {
++ private static int counter0;
++ private static int counter1;
++ private static int counter2;
++ private static int counter;
++
++ static void foo(int i) throws Exception {
++ if ((i & 1023) == 2) {
++ counter0++;
++ throw new Exception2();
++ }
++ }
++
++ static void test(int i) throws Exception {
++ try {
++ foo(i);
++ }
++ catch (Exception e) {
++ if (e instanceof Exception1) {
++ counter1++;
++ } else if (e instanceof Exception2) {
++ counter2++;
++ }
++ counter++;
++ throw e;
++ }
++ }
++
++ public static void main(String[] args) throws Throwable {
++ for (int i = 0; i < 15000; i++) {
++ try {
++ test(i);
++ } catch (Exception e) {
++ // expected
++ }
++ }
++ if (counter1 != 0) {
++ throw new RuntimeException("Failed: counter1(" + counter1 + ") != 0");
++ }
++ if (counter2 != counter0) {
++ throw new RuntimeException("Failed: counter2(" + counter2 + ") != counter0(" + counter0 + ")");
++ }
++ if (counter2 != counter) {
++ throw new RuntimeException("Failed: counter2(" + counter2 + ") != counter(" + counter + ")");
++ }
++ System.out.println("TEST PASSED");
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/exceptions/SumTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,86 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8066900
++ * @summary FP registers are not properly restored by C1 when handling exceptions
++ * @run main/othervm -Xbatch SumTest
++ *
++ */
++public class SumTest {
++ private static class Sum {
++
++ double[] sums;
++
++ /**
++ * Construct empty Sum
++ */
++ public Sum() {
++ sums = new double[0];
++ }
++
++ /**
++ * Return the sum of all numbers added to this Sum
++ *
++ * @return the sum
++ */
++ final public double getSum() {
++ double sum = 0;
++ for (final double s : sums) {
++ sum += s;
++ }
++
++ return sum;
++ }
++
++ /**
++ * Add a new number to this Sum
++ *
++ * @param a number to be added.
++ */
++ final public void add(double a) {
++ try {
++ sums[sums.length] = -1; // Cause IndexOutOfBoundsException
++ } catch (final IndexOutOfBoundsException e) {
++ final double[] oldSums = sums;
++ sums = new double[oldSums.length + 1]; // Extend sums
++ System.arraycopy(oldSums, 0, sums, 0, oldSums.length);
++ sums[oldSums.length] = a; // Append a
++ }
++ }
++ }
++
++ public static void main(String[] args) throws Exception {
++ final Sum sum = new Sum();
++ for (int i = 1; i <= 10000; ++i) {
++ sum.add(1);
++ double ii = sum.getSum();
++ if (i != ii) {
++ throw new Exception("Failure: computed = " + ii + ", expected = " + i);
++ }
++ }
++ }
++
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/exceptions/TestRecursiveReplacedException.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,44 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8054224
++ * @summary Recursive method compiled by C1 is unable to catch StackOverflowError
++ * @run main/othervm -Xcomp -XX:CompileOnly=Test.run -XX:+TieredCompilation -XX:TieredStopAtLevel=2 -Xss256K TestRecursiveReplacedException
++ *
++ */
++
++public class TestRecursiveReplacedException {
++
++ public static void main(String args[]) {
++ new TestRecursiveReplacedException().run();
++ }
++
++ public void run() {
++ try {
++ run();
++ } catch (Throwable t) {
++ }
++ }
++}
+--- ./hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactIntTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactIntTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,6 +24,7 @@
+ /*
+ * @test
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox
++ * /compiler/testlibrary
+ * @build AddExactIntTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+@@ -34,7 +35,7 @@
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,MathIntrinsic*::execMathMethod
+ * -XX:LogFile=hs.log -XX:+UseMathExactIntrinsics AddExactIntTest
+- * @run main Verifier hs_neg.log hs.log
++ * @run main intrinsics.Verifier hs_neg.log hs.log
+ */
+
+ public class AddExactIntTest {
+--- ./hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactLongTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactLongTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,6 +24,7 @@
+ /*
+ * @test
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox
++ * /compiler/testlibrary
+ * @build AddExactLongTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+@@ -34,7 +35,7 @@
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,MathIntrinsic*::execMathMethod
+ * -XX:LogFile=hs.log -XX:+UseMathExactIntrinsics AddExactLongTest
+- * @run main Verifier hs_neg.log hs.log
++ * @run main intrinsics.Verifier hs_neg.log hs.log
+ */
+
+ public class AddExactLongTest {
+--- ./hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactIntTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactIntTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,6 +24,7 @@
+ /*
+ * @test
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox
++ * /compiler/testlibrary
+ * @build DecrementExactIntTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+@@ -34,7 +35,7 @@
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,MathIntrinsic*::execMathMethod
+ * -XX:LogFile=hs.log -XX:+UseMathExactIntrinsics DecrementExactIntTest
+- * @run main Verifier hs_neg.log hs.log
++ * @run main intrinsics.Verifier hs_neg.log hs.log
+ */
+
+ public class DecrementExactIntTest {
+--- ./hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactLongTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactLongTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,6 +24,7 @@
+ /*
+ * @test
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox
++ * /compiler/testlibrary
+ * @build DecrementExactLongTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+@@ -34,7 +35,7 @@
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,MathIntrinsic*::execMathMethod
+ * -XX:LogFile=hs.log -XX:+UseMathExactIntrinsics DecrementExactLongTest
+- * @run main Verifier hs_neg.log hs.log
++ * @run main intrinsics.Verifier hs_neg.log hs.log
+ */
+
+ public class DecrementExactLongTest {
+--- ./hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactIntTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactIntTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,6 +24,7 @@
+ /*
+ * @test
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox
++ * /compiler/testlibrary
+ * @build IncrementExactIntTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+@@ -34,7 +35,7 @@
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,MathIntrinsic*::execMathMethod
+ * -XX:LogFile=hs.log -XX:+UseMathExactIntrinsics IncrementExactIntTest
+- * @run main Verifier hs_neg.log hs.log
++ * @run main intrinsics.Verifier hs_neg.log hs.log
+ */
+
+ public class IncrementExactIntTest {
+--- ./hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactLongTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactLongTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,6 +24,7 @@
+ /*
+ * @test
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox
++ * /compiler/testlibrary
+ * @build IncrementExactLongTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+@@ -34,7 +35,7 @@
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,MathIntrinsic*::execMathMethod
+ * -XX:LogFile=hs.log -XX:+UseMathExactIntrinsics IncrementExactLongTest
+- * @run main Verifier hs_neg.log hs.log
++ * @run main intrinsics.Verifier hs_neg.log hs.log
+ */
+
+ public class IncrementExactLongTest {
+--- ./hotspot/test/compiler/intrinsics/mathexact/sanity/IntrinsicBase.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/intrinsics/mathexact/sanity/IntrinsicBase.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -22,6 +22,7 @@
+ */
+
+ import com.oracle.java.testlibrary.Platform;
++import intrinsics.Verifier;
+
+ import java.io.FileOutputStream;
+ import java.lang.reflect.Executable;
+@@ -79,10 +80,10 @@
+
+ System.out.println("Expected intrinsic count is " + expectedIntrinsicCount + " name " + getIntrinsicId());
+
+- final FileOutputStream out = new FileOutputStream(getVMOption("LogFile") + ".verify.properties");
++ final FileOutputStream out = new FileOutputStream(getVMOption("LogFile") + Verifier.PROPERTY_FILE_SUFFIX);
+ Properties expectedProps = new Properties();
+- expectedProps.setProperty("intrinsic.name", getIntrinsicId());
+- expectedProps.setProperty("intrinsic.expectedCount", String.valueOf(expectedIntrinsicCount));
++ expectedProps.setProperty(Verifier.INTRINSIC_NAME_PROPERTY, getIntrinsicId());
++ expectedProps.setProperty(Verifier.INTRINSIC_EXPECTED_COUNT_PROPERTY, String.valueOf(expectedIntrinsicCount));
+ expectedProps.store(out, null);
+
+ out.close();
+--- ./hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactIntTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactIntTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,6 +24,7 @@
+ /*
+ * @test
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox
++ * /compiler/testlibrary
+ * @build MultiplyExactIntTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+@@ -34,7 +35,7 @@
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,MathIntrinsic*::execMathMethod
+ * -XX:LogFile=hs.log -XX:+UseMathExactIntrinsics MultiplyExactIntTest
+- * @run main Verifier hs_neg.log hs.log
++ * @run main intrinsics.Verifier hs_neg.log hs.log
+ */
+
+ public class MultiplyExactIntTest {
+--- ./hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactLongTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactLongTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,6 +24,7 @@
+ /*
+ * @test
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox
++ * /compiler/testlibrary
+ * @build MultiplyExactLongTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+@@ -34,7 +35,7 @@
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,MathIntrinsic*::execMathMethod
+ * -XX:LogFile=hs.log -XX:+UseMathExactIntrinsics MultiplyExactLongTest
+- * @run main Verifier hs_neg.log hs.log
++ * @run main intrinsics.Verifier hs_neg.log hs.log
+ */
+
+ public class MultiplyExactLongTest {
+--- ./hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactIntTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactIntTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,6 +24,7 @@
+ /*
+ * @test
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox
++ * /compiler/testlibrary
+ * @build NegateExactIntTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+@@ -34,7 +35,7 @@
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,MathIntrinsic*::execMathMethod
+ * -XX:LogFile=hs.log -XX:+UseMathExactIntrinsics NegateExactIntTest
+- * @run main Verifier hs_neg.log hs.log
++ * @run main intrinsics.Verifier hs_neg.log hs.log
+ */
+
+ public class NegateExactIntTest {
+--- ./hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactLongTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactLongTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,6 +24,7 @@
+ /*
+ * @test
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox
++ * /compiler/testlibrary
+ * @build NegateExactLongTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+@@ -34,7 +35,7 @@
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,MathIntrinsic*::execMathMethod
+ * -XX:LogFile=hs.log -XX:+UseMathExactIntrinsics NegateExactLongTest
+- * @run main Verifier hs_neg.log hs.log
++ * @run main intrinsics.Verifier hs_neg.log hs.log
+ */
+
+ public class NegateExactLongTest {
+--- ./hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactIntTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactIntTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,6 +24,7 @@
+ /*
+ * @test
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox
++ * /compiler/testlibrary
+ * @build SubtractExactIntTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+@@ -34,7 +35,7 @@
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,MathIntrinsic*::execMathMethod
+ * -XX:LogFile=hs.log -XX:+UseMathExactIntrinsics SubtractExactIntTest
+- * @run main Verifier hs_neg.log hs.log
++ * @run main intrinsics.Verifier hs_neg.log hs.log
+
+ */
+
+--- ./hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactLongTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactLongTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,6 +24,7 @@
+ /*
+ * @test
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox
++ * /compiler/testlibrary
+ * @build SubtractExactLongTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+@@ -34,7 +35,7 @@
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,MathIntrinsic*::execMathMethod
+ * -XX:LogFile=hs.log -XX:+UseMathExactIntrinsics SubtractExactLongTest
+- * @run main Verifier hs_neg.log hs.log
++ * @run main intrinsics.Verifier hs_neg.log hs.log
+ */
+
+ public class SubtractExactLongTest {
+--- ./hotspot/test/compiler/intrinsics/mathexact/sanity/Verifier.java Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,71 +0,0 @@
+-/*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-import java.io.BufferedReader;
+-import java.io.FileReader;
+-import java.util.Properties;
+-
+-public class Verifier {
+-
+- public static void main(String[] args) throws Exception {
+- if (args.length == 0)
+- throw new RuntimeException("Test bug, nothing to verify");
+- for (String hsLogFile : args) {
+- verify(hsLogFile);
+- }
+- }
+-
+- private static void verify(String hsLogFile) throws Exception {
+- System.out.println("Verifying " + hsLogFile);
+-
+- final Properties expectedProperties = new Properties();
+- final FileReader reader = new FileReader(hsLogFile + ".verify.properties");
+- expectedProperties.load(reader);
+- reader.close();
+-
+- int fullMatchCnt = 0;
+- int suspectCnt = 0;
+- final String intrinsicId = expectedProperties.getProperty("intrinsic.name");
+- final String prefix = "<intrinsic id='";
+- final String prefixWithId = prefix + intrinsicId + "'";
+- final int expectedCount = Integer.parseInt(expectedProperties.getProperty("intrinsic.expectedCount"));
+-
+- BufferedReader r = new BufferedReader(new FileReader(hsLogFile));
+- String s;
+- while ((s = r.readLine()) != null) {
+- if (s.startsWith(prefix)) {
+- if (s.startsWith(prefixWithId)) {
+- fullMatchCnt++;
+- } else {
+- suspectCnt++;
+- System.out.println("WARNING: Other intrinsic detected " + s);
+- }
+- }
+- }
+- r.close();
+-
+- System.out.println("Intrinsic " + intrinsicId + " verification, expected: " + expectedCount + ", matched: " + fullMatchCnt + ", suspected: " + suspectCnt);
+- if (expectedCount != fullMatchCnt)
+- throw new RuntimeException("Unexpected count of intrinsic " + prefixWithId + " expected:" + expectedCount + ", matched: " + fullMatchCnt + ", suspected: " + suspectCnt);
+- }
+-}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/multiplytolen/TestMultiplyToLen.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,113 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++/**
++ * @test
++ * @bug 8055494
++ * @summary Add C2 x86 intrinsic for BigInteger::multiplyToLen() method
++ *
++ * @run main/othervm/timeout=600 -XX:-TieredCompilation -Xbatch
++ * -XX:CompileCommand=exclude,TestMultiplyToLen::main
++ * -XX:CompileCommand=option,TestMultiplyToLen::base_multiply,ccstr,DisableIntrinsic,_multiplyToLen
++ * -XX:CompileCommand=option,java.math.BigInteger::multiply,ccstr,DisableIntrinsic,_multiplyToLen
++ * -XX:CompileCommand=inline,java.math.BigInteger::multiply TestMultiplyToLen
++ */
++
++import java.util.Random;
++import java.math.*;
++
++public class TestMultiplyToLen {
++
++ // Avoid intrinsic by preventing inlining multiply() and multiplyToLen().
++ public static BigInteger base_multiply(BigInteger op1, BigInteger op2) {
++ return op1.multiply(op2);
++ }
++
++ // Generate multiplyToLen() intrinsic by inlining multiply().
++ public static BigInteger new_multiply(BigInteger op1, BigInteger op2) {
++ return op1.multiply(op2);
++ }
++
++ public static boolean bytecompare(BigInteger b1, BigInteger b2) {
++ byte[] data1 = b1.toByteArray();
++ byte[] data2 = b2.toByteArray();
++ if (data1.length != data2.length)
++ return false;
++ for (int i = 0; i < data1.length; i++) {
++ if (data1[i] != data2[i])
++ return false;
++ }
++ return true;
++ }
++
++ public static String stringify(BigInteger b) {
++ String strout= "";
++ byte [] data = b.toByteArray();
++ for (int i = 0; i < data.length; i++) {
++ strout += (String.format("%02x",data[i]) + " ");
++ }
++ return strout;
++ }
++
++ public static void main(String args[]) throws Exception {
++
++ BigInteger oldsum = new BigInteger("0");
++ BigInteger newsum = new BigInteger("0");
++
++ BigInteger b1, b2, oldres, newres;
++
++ Random rand = new Random();
++ long seed = System.nanoTime();
++ Random rand1 = new Random();
++ long seed1 = System.nanoTime();
++ rand.setSeed(seed);
++ rand1.setSeed(seed1);
++
++ for (int j = 0; j < 1000000; j++) {
++ int rand_int = rand1.nextInt(3136)+32;
++ int rand_int1 = rand1.nextInt(3136)+32;
++ b1 = new BigInteger(rand_int, rand);
++ b2 = new BigInteger(rand_int1, rand);
++
++ oldres = base_multiply(b1,b2);
++ newres = new_multiply(b1,b2);
++
++ oldsum = oldsum.add(oldres);
++ newsum = newsum.add(newres);
++
++ if (!bytecompare(oldres,newres)) {
++ System.out.print("mismatch for:b1:" + stringify(b1) + " :b2:" + stringify(b2) + " :oldres:" + stringify(oldres) + " :newres:" + stringify(newres));
++ System.out.println(b1);
++ System.out.println(b2);
++ throw new Exception("Failed");
++ }
++ }
++ if (!bytecompare(oldsum,newsum)) {
++ System.out.println("Failure: oldsum:" + stringify(oldsum) + " newsum:" + stringify(newsum));
++ throw new Exception("Failed");
++ } else {
++ System.out.println("Success");
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/TestSHA.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,141 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++/**
++ * @test
++ * @bug 8035968
++ * @summary C2 support for SHA on SPARC
++ *
++ * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-1 TestSHA
++ * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-224 TestSHA
++ * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-256 TestSHA
++ * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-384 TestSHA
++ * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-512 TestSHA
++ *
++ * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-1 -Doffset=1 TestSHA
++ * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-224 -Doffset=1 TestSHA
++ * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-256 -Doffset=1 TestSHA
++ * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-384 -Doffset=1 TestSHA
++ * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-512 -Doffset=1 TestSHA
++ *
++ * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-1 -Dalgorithm2=SHA-256 TestSHA
++ * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-1 -Dalgorithm2=SHA-512 TestSHA
++ * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-256 -Dalgorithm2=SHA-512 TestSHA
++ *
++ * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=SHA-1 -Dalgorithm2=MD5 TestSHA
++ * @run main/othervm/timeout=600 -Xbatch -Dalgorithm=MD5 -Dalgorithm2=SHA-1 TestSHA
++ */
++
++import java.security.MessageDigest;
++import java.util.Arrays;
++
++public class TestSHA {
++ private static final int HASH_LEN = 64; /* up to 512-bit */
++ private static final int ALIGN = 8; /* for different data alignments */
++
++ public static void main(String[] args) throws Exception {
++ String provider = System.getProperty("provider", "SUN");
++ String algorithm = System.getProperty("algorithm", "SHA-1");
++ String algorithm2 = System.getProperty("algorithm2", "");
++ int msgSize = Integer.getInteger("msgSize", 1024);
++ int offset = Integer.getInteger("offset", 0) % ALIGN;
++ int iters = (args.length > 0 ? Integer.valueOf(args[0]) : 100000);
++ int warmupIters = (args.length > 1 ? Integer.valueOf(args[1]) : 20000);
++
++ testSHA(provider, algorithm, msgSize, offset, iters, warmupIters);
++
++ if (algorithm2.equals("") == false) {
++ testSHA(provider, algorithm2, msgSize, offset, iters, warmupIters);
++ }
++ }
++
++ static void testSHA(String provider, String algorithm, int msgSize,
++ int offset, int iters, int warmupIters) throws Exception {
++ System.out.println("provider = " + provider);
++ System.out.println("algorithm = " + algorithm);
++ System.out.println("msgSize = " + msgSize + " bytes");
++ System.out.println("offset = " + offset);
++ System.out.println("iters = " + iters);
++
++ byte[] expectedHash = new byte[HASH_LEN];
++ byte[] hash = new byte[HASH_LEN];
++ byte[] data = new byte[msgSize + offset];
++ for (int i = 0; i < (msgSize + offset); i++) {
++ data[i] = (byte)(i & 0xff);
++ }
++
++ try {
++ MessageDigest sha = MessageDigest.getInstance(algorithm, provider);
++
++ /* do once, which doesn't use intrinsics */
++ sha.reset();
++ sha.update(data, offset, msgSize);
++ expectedHash = sha.digest();
++
++ /* warm up */
++ for (int i = 0; i < warmupIters; i++) {
++ sha.reset();
++ sha.update(data, offset, msgSize);
++ hash = sha.digest();
++ }
++
++ /* check result */
++ if (Arrays.equals(hash, expectedHash) == false) {
++ System.out.println("TestSHA Error: ");
++ showArray(expectedHash, "expectedHash");
++ showArray(hash, "computedHash");
++ //System.exit(1);
++ throw new Exception("TestSHA Error");
++ } else {
++ showArray(hash, "hash");
++ }
++
++ /* measure performance */
++ long start = System.nanoTime();
++ for (int i = 0; i < iters; i++) {
++ sha.reset();
++ sha.update(data, offset, msgSize);
++ hash = sha.digest();
++ }
++ long end = System.nanoTime();
++ double total = (double)(end - start)/1e9; /* in seconds */
++ double thruput = (double)msgSize*iters/1e6/total; /* in MB/s */
++ System.out.println("TestSHA runtime = " + total + " seconds");
++ System.out.println("TestSHA throughput = " + thruput + " MB/s");
++ System.out.println();
++ } catch (Exception e) {
++ System.out.println("Exception: " + e);
++ //System.exit(1);
++ throw new Exception(e);
++ }
++ }
++
++ static void showArray(byte b[], String name) {
++ System.out.format("%s [%d]: ", name, b.length);
++ for (int i = 0; i < Math.min(b.length, HASH_LEN); i++) {
++ System.out.format("%02x ", b[i] & 0xff);
++ }
++ System.out.println();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/SHAOptionsBase.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,169 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import com.oracle.java.testlibrary.Platform;
++import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
++import sha.predicate.IntrinsicPredicates;
++
++import java.util.function.BooleanSupplier;
++
++/**
++ * Base class for all CLI tests on SHA-related options.
++ *
++ * Instead of using huge complex tests for each option, each test is constructed
++ * from several test cases shared among different tests.
++ */
++public class SHAOptionsBase extends CommandLineOptionTest {
++ protected static final String USE_SHA_OPTION = "UseSHA";
++ protected static final String USE_SHA1_INTRINSICS_OPTION
++ = "UseSHA1Intrinsics";
++ protected static final String USE_SHA256_INTRINSICS_OPTION
++ = "UseSHA256Intrinsics";
++ protected static final String USE_SHA512_INTRINSICS_OPTION
++ = "UseSHA512Intrinsics";
++
++ // Note that strings below will be passed to
++ // CommandLineOptionTest.verifySameJVMStartup and thus are regular
++ // expressions, not just a plain strings.
++ protected static final String SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE
++ = "SHA instructions are not available on this CPU";
++ protected static final String SHA1_INSTRUCTION_IS_NOT_AVAILABLE
++ = "SHA1 instruction is not available on this CPU\\.";
++ protected static final String SHA256_INSTRUCTION_IS_NOT_AVAILABLE
++ = "SHA256 instruction \\(for SHA-224 and SHA-256\\) "
++ + "is not available on this CPU\\.";
++ protected static final String SHA512_INSTRUCTION_IS_NOT_AVAILABLE
++ = "SHA512 instruction \\(for SHA-384 and SHA-512\\) "
++ + "is not available on this CPU\\.";
++ protected static final String SHA_INTRINSICS_ARE_NOT_AVAILABLE
++ = "SHA intrinsics are not available on this CPU";
++
++ private final TestCase[] testCases;
++
++ /**
++ * Returns warning message that should occur in VM output if an option with
++ * the name {@code optionName} was turned on and CPU does not support
++ * required instructions.
++ *
++ * @param optionName The name of the option for which warning message should
++ * be returned.
++ * @return A warning message that will be printed out to VM output if CPU
++ * instructions required by the option are not supported.
++ */
++ protected static String getWarningForUnsupportedCPU(String optionName) {
++ if (Platform.isSparc()) {
++ switch (optionName) {
++ case SHAOptionsBase.USE_SHA_OPTION:
++ return SHAOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
++ case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
++ return SHAOptionsBase.SHA1_INSTRUCTION_IS_NOT_AVAILABLE;
++ case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
++ return SHAOptionsBase.SHA256_INSTRUCTION_IS_NOT_AVAILABLE;
++ case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
++ return SHAOptionsBase.SHA512_INSTRUCTION_IS_NOT_AVAILABLE;
++ default:
++ throw new Error("Unexpected option " + optionName);
++ }
++ } else if (Platform.isX64() || Platform.isX86()) {
++ switch (optionName) {
++ case SHAOptionsBase.USE_SHA_OPTION:
++ return SHAOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
++ case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
++ case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
++ case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
++ return SHAOptionsBase.SHA_INTRINSICS_ARE_NOT_AVAILABLE;
++ default:
++ throw new Error("Unexpected option " + optionName);
++ }
++ } else {
++ throw new Error("Support for CPUs other then X86 or SPARC is not "
++ + "implemented.");
++ }
++ }
++
++ /**
++ * Returns the predicate indicating whether or not CPU instructions required
++ * by the option with name {@code optionName} are available.
++ *
++ * @param optionName The name of the option for which a predicate should be
++ * returned.
++ * @return The predicate on availability of CPU instructions required by the
++ * option.
++ */
++ protected static BooleanSupplier getPredicateForOption(String optionName) {
++ switch (optionName) {
++ case SHAOptionsBase.USE_SHA_OPTION:
++ return IntrinsicPredicates.ANY_SHA_INSTRUCTION_AVAILABLE;
++ case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
++ return IntrinsicPredicates.SHA1_INSTRUCTION_AVAILABLE;
++ case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
++ return IntrinsicPredicates.SHA256_INSTRUCTION_AVAILABLE;
++ case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
++ return IntrinsicPredicates.SHA512_INSTRUCTION_AVAILABLE;
++ default:
++ throw new Error("Unexpected option " + optionName);
++ }
++ }
++
++ public SHAOptionsBase(TestCase... testCases) {
++ super(Boolean.TRUE::booleanValue);
++ this.testCases = testCases;
++ }
++
++ @Override
++ protected void runTestCases() throws Throwable {
++ for (TestCase testCase : testCases) {
++ testCase.test();
++ }
++ }
++
++ public static abstract class TestCase {
++ protected final String optionName;
++ private final BooleanSupplier predicate;
++
++ protected TestCase(String optionName, BooleanSupplier predicate) {
++ this.optionName = optionName;
++ this.predicate = predicate;
++ }
++
++ protected final void test() throws Throwable {
++ String testCaseName = this.getClass().getName();
++ if (!predicate.getAsBoolean()) {
++ System.out.println("Skipping " + testCaseName
++ + " due to predicate failure.");
++ return;
++ } else {
++ System.out.println("Running " + testCaseName);
++ }
++
++ verifyWarnings();
++ verifyOptionValues();
++ }
++
++ protected void verifyWarnings() throws Throwable {
++ }
++
++ protected void verifyOptionValues() throws Throwable {
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnSupportedCPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,40 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8035968
++ * @summary Verify UseSHA1Intrinsics option processing on supported CPU,
++ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases
++ * @build TestUseSHA1IntrinsicsOptionOnSupportedCPU
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI TestUseSHA1IntrinsicsOptionOnSupportedCPU
++ */
++public class TestUseSHA1IntrinsicsOptionOnSupportedCPU {
++ public static void main(String args[]) throws Throwable {
++ new SHAOptionsBase(new GenericTestCaseForSupportedSparcCPU(
++ SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION)).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8035968
++ * @summary Verify UseSHA1Intrinsics option processing on unsupported CPU,
++ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases
++ * @build TestUseSHA1IntrinsicsOptionOnUnsupportedCPU
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI
++ * TestUseSHA1IntrinsicsOptionOnUnsupportedCPU
++ */
++public class TestUseSHA1IntrinsicsOptionOnUnsupportedCPU {
++ public static void main(String args[]) throws Throwable {
++ new SHAOptionsBase(
++ new GenericTestCaseForUnsupportedSparcCPU(
++ SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
++ new UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU(
++ SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
++ new GenericTestCaseForUnsupportedX86CPU(
++ SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION),
++ new GenericTestCaseForOtherCPU(
++ SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION)).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnSupportedCPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8035968
++ * @summary Verify UseSHA256Intrinsics option processing on supported CPU,
++ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases
++ * @build TestUseSHA256IntrinsicsOptionOnSupportedCPU
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI
++ * TestUseSHA256IntrinsicsOptionOnSupportedCPU
++ */
++public class TestUseSHA256IntrinsicsOptionOnSupportedCPU {
++ public static void main(String args[]) throws Throwable {
++ new SHAOptionsBase(new GenericTestCaseForSupportedSparcCPU(
++ SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION)).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8035968
++ * @summary Verify UseSHA256Intrinsics option processing on unsupported CPU,
++ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases
++ * @build TestUseSHA256IntrinsicsOptionOnUnsupportedCPU
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI
++ * TestUseSHA256IntrinsicsOptionOnUnsupportedCPU
++ */
++public class TestUseSHA256IntrinsicsOptionOnUnsupportedCPU {
++ public static void main(String args[]) throws Throwable {
++ new SHAOptionsBase(
++ new GenericTestCaseForUnsupportedSparcCPU(
++ SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
++ new UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU(
++ SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
++ new GenericTestCaseForUnsupportedX86CPU(
++ SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION),
++ new GenericTestCaseForOtherCPU(
++ SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION)).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnSupportedCPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8035968
++ * @summary Verify UseSHA512Intrinsics option processing on supported CPU.
++ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases
++ * @build TestUseSHA512IntrinsicsOptionOnSupportedCPU
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI
++ * TestUseSHA512IntrinsicsOptionOnSupportedCPU
++ */
++public class TestUseSHA512IntrinsicsOptionOnSupportedCPU {
++ public static void main(String args[]) throws Throwable {
++ new SHAOptionsBase(new GenericTestCaseForSupportedSparcCPU(
++ SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION)).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8035968
++ * @summary Verify UseSHA512Intrinsics option processing on unsupported CPU,
++ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases
++ * @build TestUseSHA512IntrinsicsOptionOnUnsupportedCPU
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI
++ * TestUseSHA512IntrinsicsOptionOnUnsupportedCPU
++ */
++public class TestUseSHA512IntrinsicsOptionOnUnsupportedCPU {
++ public static void main(String args[]) throws Throwable {
++ new SHAOptionsBase(
++ new GenericTestCaseForUnsupportedSparcCPU(
++ SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
++ new UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU(
++ SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
++ new GenericTestCaseForUnsupportedX86CPU(
++ SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION),
++ new GenericTestCaseForOtherCPU(
++ SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION)).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnSupportedCPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8035968
++ * @summary Verify UseSHA option processing on supported CPU,
++ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases
++ * @build TestUseSHAOptionOnSupportedCPU
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI TestUseSHAOptionOnSupportedCPU
++ */
++public class TestUseSHAOptionOnSupportedCPU {
++ public static void main(String args[]) throws Throwable {
++ new SHAOptionsBase(
++ new GenericTestCaseForSupportedSparcCPU(
++ SHAOptionsBase.USE_SHA_OPTION),
++ new UseSHASpecificTestCaseForSupportedSparcCPU(
++ SHAOptionsBase.USE_SHA_OPTION)).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8035968
++ * @summary Verify UseSHA option processing on unsupported CPU.
++ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases
++ * @build TestUseSHAOptionOnUnsupportedCPU
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI TestUseSHAOptionOnUnsupportedCPU
++ */
++public class TestUseSHAOptionOnUnsupportedCPU {
++ public static void main(String args[]) throws Throwable {
++ new SHAOptionsBase(
++ new GenericTestCaseForUnsupportedSparcCPU(
++ SHAOptionsBase.USE_SHA_OPTION),
++ new UseSHASpecificTestCaseForUnsupportedSparcCPU(
++ SHAOptionsBase.USE_SHA_OPTION),
++ new GenericTestCaseForUnsupportedX86CPU(
++ SHAOptionsBase.USE_SHA_OPTION),
++ new GenericTestCaseForOtherCPU(
++ SHAOptionsBase.USE_SHA_OPTION)).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import com.oracle.java.testlibrary.ExitCode;
++import com.oracle.java.testlibrary.Platform;
++import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
++import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
++import com.oracle.java.testlibrary.cli.predicate.OrPredicate;
++
++/**
++ * Generic test case for SHA-related options targeted to non-x86 and
++ * non-SPARC CPUs.
++ */
++public class GenericTestCaseForOtherCPU extends
++ SHAOptionsBase.TestCase {
++ public GenericTestCaseForOtherCPU(String optionName) {
++ // Execute the test case on any CPU except SPARC and X86
++ super(optionName, new NotPredicate(new OrPredicate(Platform::isSparc,
++ new OrPredicate(Platform::isX64, Platform::isX86))));
++ }
++
++ @Override
++ protected void verifyWarnings() throws Throwable {
++ // Verify that on non-x86 and non-SPARC CPU usage of SHA-related
++ // options will not cause any warnings.
++ CommandLineOptionTest.verifySameJVMStartup(null,
++ new String[] { ".*" + optionName + ".*" }, ExitCode.OK,
++ CommandLineOptionTest.prepareBooleanFlag(optionName, true));
++
++ CommandLineOptionTest.verifySameJVMStartup(null,
++ new String[] { ".*" + optionName + ".*" }, ExitCode.OK,
++ CommandLineOptionTest.prepareBooleanFlag(optionName, false));
++ }
++
++ @Override
++ protected void verifyOptionValues() throws Throwable {
++ // Verify that option is disabled by default.
++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false");
++
++ // Verify that option is disabled even if it was explicitly enabled
++ // using CLI options.
++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
++ CommandLineOptionTest.prepareBooleanFlag(optionName, true));
++
++ // Verify that option is disabled when it explicitly disabled
++ // using CLI options.
++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
++ CommandLineOptionTest.prepareBooleanFlag(optionName, false));
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedSparcCPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,93 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import com.oracle.java.testlibrary.ExitCode;
++import com.oracle.java.testlibrary.Platform;
++import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
++import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
++
++/**
++ * Generic test case for SHA-related options targeted to SPARC CPUs which
++ * support instructions required by the tested option.
++ */
++public class GenericTestCaseForSupportedSparcCPU extends
++ SHAOptionsBase.TestCase {
++ public GenericTestCaseForSupportedSparcCPU(String optionName) {
++ super(optionName, new AndPredicate(Platform::isSparc,
++ SHAOptionsBase.getPredicateForOption(optionName)));
++ }
++
++ @Override
++ protected void verifyWarnings() throws Throwable {
++ // Verify that there are no warning when option is explicitly enabled.
++ CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
++ SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
++ }, ExitCode.OK,
++ CommandLineOptionTest.prepareBooleanFlag(optionName, true));
++
++ // Verify that option could be disabled even if +UseSHA was passed to
++ // JVM.
++ CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
++ SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
++ }, ExitCode.OK,
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA_OPTION, true),
++ CommandLineOptionTest.prepareBooleanFlag(optionName, false));
++
++ // Verify that it is possible to enable the tested option and disable
++ // all SHA intrinsics via -UseSHA without any warnings.
++ CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
++ SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
++ }, ExitCode.OK,
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA_OPTION, false),
++ CommandLineOptionTest.prepareBooleanFlag(optionName, true));
++ }
++
++ @Override
++ protected void verifyOptionValues() throws Throwable {
++ // Verify that on supported CPU option is enabled by default.
++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true");
++
++ // Verify that it is possible to explicitly enable the option.
++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true",
++ CommandLineOptionTest.prepareBooleanFlag(optionName, true));
++
++ // Verify that it is possible to explicitly disable the option.
++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
++ CommandLineOptionTest.prepareBooleanFlag(optionName, false));
++
++ // verify that option is disabled when -UseSHA was passed to JVM.
++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
++ CommandLineOptionTest.prepareBooleanFlag(optionName, true),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA_OPTION, false));
++
++ // Verify that it is possible to explicitly disable the tested option
++ // even if +UseSHA was passed to JVM.
++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA_OPTION, true),
++ CommandLineOptionTest.prepareBooleanFlag(optionName, false));
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedSparcCPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,66 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import com.oracle.java.testlibrary.ExitCode;
++import com.oracle.java.testlibrary.Platform;
++import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
++import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
++import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
++
++/**
++ * Generic test case for SHA-related options targeted to SPARC CPUs which don't
++ * support instruction required by the tested option.
++ */
++public class GenericTestCaseForUnsupportedSparcCPU extends
++ SHAOptionsBase.TestCase {
++ public GenericTestCaseForUnsupportedSparcCPU(String optionName) {
++ super(optionName, new AndPredicate(Platform::isSparc,
++ new NotPredicate(SHAOptionsBase.getPredicateForOption(
++ optionName))));
++ }
++
++ @Override
++ protected void verifyWarnings() throws Throwable {
++ //Verify that option could be disabled without any warnings.
++ CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
++ SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
++ }, ExitCode.OK,
++ CommandLineOptionTest.prepareBooleanFlag(optionName, false));
++ }
++
++ @Override
++ protected void verifyOptionValues() throws Throwable {
++ // Verify that option is disabled by default.
++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false");
++
++ // Verify that option is disabled even if it was explicitly enabled
++ // using CLI options.
++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
++ CommandLineOptionTest.prepareBooleanFlag(optionName, true));
++
++ // Verify that option is disabled when +UseSHA was passed to JVM.
++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA_OPTION, true));
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,71 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import com.oracle.java.testlibrary.ExitCode;
++import com.oracle.java.testlibrary.Platform;
++import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
++import com.oracle.java.testlibrary.cli.predicate.OrPredicate;
++
++/**
++ * Generic test case for SHA-related options targeted to X86 CPUs that don't
++ * support SHA-related instructions.
++ */
++public class GenericTestCaseForUnsupportedX86CPU
++ extends SHAOptionsBase.TestCase {
++ public GenericTestCaseForUnsupportedX86CPU(String optionName) {
++ super(optionName, new OrPredicate(Platform::isX64, Platform::isX86));
++ }
++
++ @Override
++ protected void verifyWarnings() throws Throwable {
++ // Verify that when the tested option is explicitly enabled, then
++ // a warning will occur in VM output.
++ CommandLineOptionTest.verifySameJVMStartup(new String[] {
++ SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
++ }, null, ExitCode.OK,
++ CommandLineOptionTest.prepareBooleanFlag(optionName, true));
++
++ // Verify that the tested option could be explicitly disabled without
++ // a warning.
++ CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
++ SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
++ }, ExitCode.OK,
++ CommandLineOptionTest.prepareBooleanFlag(optionName, false));
++ }
++
++ @Override
++ protected void verifyOptionValues() throws Throwable {
++ // Verify that the tested option is disabled by default.
++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false");
++
++ // Verify that it is not possible to explicitly enable the option.
++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
++ CommandLineOptionTest.prepareBooleanFlag(optionName, true));
++
++ // Verify that the tested option is disabled even if +UseSHA was passed
++ // to JVM.
++ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false",
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA_OPTION, true));
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import com.oracle.java.testlibrary.ExitCode;
++import com.oracle.java.testlibrary.Platform;
++import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
++import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
++import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
++import sha.predicate.IntrinsicPredicates;
++
++/**
++ * Test case specific to UseSHA*Intrinsics options targeted to SPARC CPUs which
++ * don't support required instruction, but support other SHA-related
++ * instructions.
++ *
++ * For example, CPU support sha1 instruction, but don't support sha256 or
++ * sha512.
++ */
++public class UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU
++ extends SHAOptionsBase.TestCase {
++ public UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU(
++ String optionName) {
++ // execute test case on SPARC CPU that support any sha* instructions,
++ // but does not support sha* instruction required by the tested option.
++ super(optionName, new AndPredicate(Platform::isSparc,
++ new AndPredicate(
++ IntrinsicPredicates.ANY_SHA_INSTRUCTION_AVAILABLE,
++ new NotPredicate(SHAOptionsBase.getPredicateForOption(
++ optionName)))));
++ }
++ @Override
++ protected void verifyWarnings() throws Throwable {
++ // Verify that attempt to enable the tested option will cause a warning.
++ CommandLineOptionTest.verifySameJVMStartup(new String[] {
++ SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
++ }, null, ExitCode.OK,
++ CommandLineOptionTest.prepareBooleanFlag(optionName, true));
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForSupportedSparcCPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,101 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import com.oracle.java.testlibrary.Asserts;
++import com.oracle.java.testlibrary.ExitCode;
++import com.oracle.java.testlibrary.Platform;
++import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
++import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
++import sha.predicate.IntrinsicPredicates;
++
++/**
++ * UseSHA specific test case targeted to SPARC CPUs which support any sha*
++ * instruction.
++ */
++public class UseSHASpecificTestCaseForSupportedSparcCPU
++ extends SHAOptionsBase.TestCase {
++ public UseSHASpecificTestCaseForSupportedSparcCPU(String optionName) {
++ super(SHAOptionsBase.USE_SHA_OPTION, new AndPredicate(Platform::isSparc,
++ IntrinsicPredicates.ANY_SHA_INSTRUCTION_AVAILABLE));
++
++ Asserts.assertEQ(optionName, SHAOptionsBase.USE_SHA_OPTION,
++ "Test case should be used for " + SHAOptionsBase.USE_SHA_OPTION
++ + " option only.");
++ }
++
++ @Override
++ protected void verifyWarnings() throws Throwable {
++ // Verify that there will be no warnings when +UseSHA was passed and
++ // all UseSHA*Intrinsics options were disabled.
++ CommandLineOptionTest.verifySameJVMStartup(
++ null, new String[] { ".*UseSHA.*" }, ExitCode.OK,
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA_OPTION, true),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION, false),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION, false),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION, false));
++ }
++
++ @Override
++ protected void verifyOptionValues() throws Throwable {
++ // Verify that UseSHA is disabled when all UseSHA*Intrinscs are
++ // disabled.
++ CommandLineOptionTest.verifyOptionValueForSameVM(
++ SHAOptionsBase.USE_SHA_OPTION, "false",
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION, false),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION, false),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION, false));
++
++ CommandLineOptionTest.verifyOptionValueForSameVM(
++ // Verify that UseSHA is disabled when all UseSHA*Intrinscs are
++ // disabled even if it was explicitly enabled.
++ SHAOptionsBase.USE_SHA_OPTION, "false",
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA_OPTION, true),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION, false),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION, false),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION, false));
++
++ // Verify that explicitly disabled UseSHA option remains disabled even
++ // if all UseSHA*Intrinsics options were enabled.
++ CommandLineOptionTest.verifyOptionValueForSameVM(
++ SHAOptionsBase.USE_SHA_OPTION, "false",
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA_OPTION, false),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION, true),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION, true),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION, true));
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForUnsupportedSparcCPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,83 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import com.oracle.java.testlibrary.Asserts;
++import com.oracle.java.testlibrary.ExitCode;
++import com.oracle.java.testlibrary.Platform;
++import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
++import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
++import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
++import sha.predicate.IntrinsicPredicates;
++
++/**
++ * UseSHA specific test case targeted to SPARC CPUs which don't support all sha*
++ * instructions.
++ */
++public class UseSHASpecificTestCaseForUnsupportedSparcCPU
++ extends SHAOptionsBase.TestCase {
++ public UseSHASpecificTestCaseForUnsupportedSparcCPU(String optionName) {
++ super(SHAOptionsBase.USE_SHA_OPTION, new AndPredicate(Platform::isSparc,
++ new NotPredicate(
++ IntrinsicPredicates.ANY_SHA_INSTRUCTION_AVAILABLE)));
++
++ Asserts.assertEQ(optionName, SHAOptionsBase.USE_SHA_OPTION,
++ "Test case should be used for " + SHAOptionsBase.USE_SHA_OPTION
++ + " option only.");
++ }
++
++ @Override
++ protected void verifyWarnings() throws Throwable {
++ // Verify that attempt to use UseSHA option will cause a warning.
++ CommandLineOptionTest.verifySameJVMStartup(new String[] {
++ SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
++ }, null, ExitCode.OK,
++ CommandLineOptionTest.prepareBooleanFlag(optionName, true));
++ }
++
++ @Override
++ protected void verifyOptionValues() throws Throwable {
++ // Verify that UseSHA option remains disabled even if all
++ // UseSHA*Intrincs options were enabled.
++ CommandLineOptionTest.verifyOptionValueForSameVM(
++ SHAOptionsBase.USE_SHA_OPTION, "false",
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION, true),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION, true),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION, true));
++
++ // Verify that UseSHA option remains disabled even if all
++ // UseSHA*Intrincs options were enabled and UseSHA was enabled as well.
++ CommandLineOptionTest.verifyOptionValueForSameVM(
++ SHAOptionsBase.USE_SHA_OPTION, "false",
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA_OPTION, true),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION, true),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION, true),
++ CommandLineOptionTest.prepareBooleanFlag(
++ SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION, true));
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/sanity/SHASanityTestBase.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,109 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import intrinsics.Verifier;
++import sun.hotspot.WhiteBox;
++
++import java.io.FileOutputStream;
++import java.io.IOException;
++import java.util.Objects;
++import java.util.Properties;
++import java.util.function.BooleanSupplier;
++
++/**
++ * Base class for sanity tests on SHA intrinsics support.
++ */
++public class SHASanityTestBase {
++ protected static final String SHA1_INTRINSIC_ID
++ = "_sha_implCompress";
++ protected static final String SHA256_INTRINSIC_ID
++ = "_sha2_implCompress";
++ protected static final String SHA512_INTRINSIC_ID
++ = "_sha5_implCompress";
++ protected static final String MB_INTRINSIC_ID
++ = "_digestBase_implCompressMB";
++
++ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
++ private static final int MSG_SIZE = 1024;
++ private static final int OFFSET = 0;
++ private static final int ITERATIONS = 10000;
++ private static final int WARMUP_ITERATIONS = 1;
++ private static final String PROVIDER = "SUN";
++
++ private final BooleanSupplier predicate;
++ private final String intrinsicID;
++
++ /**
++ * Construct the new test on intrinsic with ID {@code intrinsicID},
++ * which is expected to be emitted if {@code predicate} is evaluated to
++ * {@code true}.
++ *
++ * @param predicate The predicate indicating if the intrinsic is expected to
++ * be used.
++ * @param intrinsicID The ID of the intrinsic to be tested.
++ */
++ protected SHASanityTestBase(BooleanSupplier predicate, String intrinsicID) {
++ this.predicate = predicate;
++ this.intrinsicID = intrinsicID;
++ }
++
++ /**
++ * Run the test and dump properties to file.
++ *
++ * @throws Exception when something went wrong.
++ */
++ public final void test() throws Exception {
++ String algorithm = Objects.requireNonNull(
++ System.getProperty("algorithm"),
++ "Algorithm name should be specified.");
++
++ dumpProperties();
++
++ TestSHA.testSHA(SHASanityTestBase.PROVIDER, algorithm,
++ SHASanityTestBase.MSG_SIZE, SHASanityTestBase.OFFSET,
++ SHASanityTestBase.ITERATIONS,
++ SHASanityTestBase.WARMUP_ITERATIONS);
++ }
++
++ /**
++ * Dump properties containing information about the tested intrinsic name
++ * and whether or not is should be used to the file
++ * &lt;LogFile value&gt;.verify.properties.
++ *
++ * @throws IOException when something went wrong during dumping to file.
++ */
++ private void dumpProperties() throws IOException {
++ Properties properties = new Properties();
++ properties.setProperty(Verifier.INTRINSIC_NAME_PROPERTY, intrinsicID);
++ properties.setProperty(Verifier.INTRINSIC_IS_EXPECTED_PROPERTY,
++ String.valueOf(predicate.getAsBoolean()));
++
++ String logFileName
++ = SHASanityTestBase.WHITE_BOX.getStringVMFlag("LogFile");
++ FileOutputStream fileOutputStream = new FileOutputStream(logFileName
++ + Verifier.PROPERTY_FILE_SUFFIX);
++
++ properties.store(fileOutputStream, null);
++ fileOutputStream.close();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1Intrinsics.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,58 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8035968
++ * @summary Verify that SHA-1 intrinsic is actually used.
++ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../
++ * @build TestSHA intrinsics.Verifier TestSHA1Intrinsics
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=positive.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:+UseSHA1Intrinsics
++ * -Dalgorithm=SHA-1 TestSHA1Intrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=negative.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:-UseSHA1Intrinsics
++ * -Dalgorithm=SHA-1 TestSHA1Intrinsics
++ * @run main/othervm -DverificationStrategy=VERIFY_INTRINSIC_USAGE
++ * intrinsics.Verifier positive.log negative.log
++ */
++import sha.predicate.IntrinsicPredicates;
++
++public class TestSHA1Intrinsics {
++ public static void main(String args[]) throws Exception {
++ new SHASanityTestBase(IntrinsicPredicates.SHA1_INTRINSICS_AVAILABLE,
++ SHASanityTestBase.SHA1_INTRINSIC_ID).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1MultiBlockIntrinsics.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,67 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import sha.predicate.IntrinsicPredicates;
++
++/**
++ * @test
++ * @bug 8035968
++ * @summary Verify that SHA-1 multi block intrinsic is actually used.
++ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../
++ * @build TestSHA intrinsics.Verifier TestSHA1MultiBlockIntrinsics
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=positive.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:+UseSHA1Intrinsics -XX:-UseSHA256Intrinsics
++ * -XX:-UseSHA512Intrinsics
++ * -Dalgorithm=SHA-1 TestSHA1MultiBlockIntrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=positive_def.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:+UseSHA1Intrinsics -Dalgorithm=SHA-1
++ * TestSHA1MultiBlockIntrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=negative.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA -XX:-UseSHA
++ * -Dalgorithm=SHA-1 TestSHA1MultiBlockIntrinsics
++ * @run main/othervm -DverificationStrategy=VERIFY_INTRINSIC_USAGE
++ * intrinsics.Verifier positive.log positive_def.log
++ * negative.log
++ */
++public class TestSHA1MultiBlockIntrinsics {
++ public static void main(String args[]) throws Exception {
++ new SHASanityTestBase(IntrinsicPredicates.SHA1_INTRINSICS_AVAILABLE,
++ SHASanityTestBase.MB_INTRINSIC_ID).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256Intrinsics.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,75 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import sha.predicate.IntrinsicPredicates;
++
++/**
++ * @test
++ * @bug 8035968
++ * @summary Verify that SHA-256 intrinsic is actually used.
++ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../
++ * @build TestSHA intrinsics.Verifier TestSHA256Intrinsics
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=positive_224.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:+UseSHA256Intrinsics
++ * -Dalgorithm=SHA-224 TestSHA256Intrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=negative_224.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:-UseSHA256Intrinsics
++ * -Dalgorithm=SHA-224 TestSHA256Intrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=positive_256.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:+UseSHA256Intrinsics
++ * -Dalgorithm=SHA-256 TestSHA256Intrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=negative_256.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:-UseSHA256Intrinsics
++ * -Dalgorithm=SHA-256 TestSHA256Intrinsics
++ * @run main/othervm -DverificationStrategy=VERIFY_INTRINSIC_USAGE
++ * intrinsics.Verifier positive_224.log positive_256.log
++ * negative_224.log negative_256.log
++ */
++public class TestSHA256Intrinsics {
++ public static void main(String args[]) throws Exception {
++ new SHASanityTestBase(IntrinsicPredicates.SHA256_INTRINSICS_AVAILABLE,
++ SHASanityTestBase.SHA256_INTRINSIC_ID).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256MultiBlockIntrinsics.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,92 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import sha.predicate.IntrinsicPredicates;
++
++/**
++ * @test
++ * @bug 8035968
++ * @summary Verify that SHA-256 multi block intrinsic is actually used.
++ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../
++ * @build TestSHA intrinsics.Verifier TestSHA256MultiBlockIntrinsics
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=positive_224.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:+UseSHA256Intrinsics -XX:-UseSHA1Intrinsics
++ * -XX:-UseSHA512Intrinsics
++ * -Dalgorithm=SHA-224 TestSHA256MultiBlockIntrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=positive_224_def.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:+UseSHA256Intrinsics -Dalgorithm=SHA-224
++ * TestSHA256MultiBlockIntrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=negative_224.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA -XX:-UseSHA
++ * -Dalgorithm=SHA-224 TestSHA256MultiBlockIntrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=positive_256.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:+UseSHA256Intrinsics -XX:-UseSHA1Intrinsics
++ * -XX:-UseSHA512Intrinsics
++ * -Dalgorithm=SHA-256 TestSHA256MultiBlockIntrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=positive_256_def.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:+UseSHA256Intrinsics -Dalgorithm=SHA-256
++ * TestSHA256MultiBlockIntrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=negative_256.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA -XX:-UseSHA
++ * -Dalgorithm=SHA-256 TestSHA256MultiBlockIntrinsics
++ * @run main/othervm -DverificationStrategy=VERIFY_INTRINSIC_USAGE
++ * intrinsics.Verifier positive_224.log positive_256.log
++ * positive_224_def.log positive_256_def.log negative_224.log
++ * negative_256.log
++ */
++public class TestSHA256MultiBlockIntrinsics {
++ public static void main(String args[]) throws Exception {
++ new SHASanityTestBase(IntrinsicPredicates.SHA256_INTRINSICS_AVAILABLE,
++ SHASanityTestBase.MB_INTRINSIC_ID).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512Intrinsics.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,75 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import sha.predicate.IntrinsicPredicates;
++
++/**
++ * @test
++ * @bug 8035968
++ * @summary Verify that SHA-512 intrinsic is actually used.
++ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../
++ * @build TestSHA intrinsics.Verifier TestSHA512Intrinsics
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=positive_384.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:+UseSHA512Intrinsics
++ * -Dalgorithm=SHA-384 TestSHA512Intrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=negative_384.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:-UseSHA512Intrinsics
++ * -Dalgorithm=SHA-384 TestSHA512Intrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=positive_512.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:+UseSHA512Intrinsics
++ * -Dalgorithm=SHA-512 TestSHA512Intrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=negative_512.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:-UseSHA512Intrinsics
++ * -Dalgorithm=SHA-512 TestSHA512Intrinsics
++ * @run main/othervm -DverificationStrategy=VERIFY_INTRINSIC_USAGE
++ * intrinsics.Verifier positive_384.log positive_512.log
++ * negative_384.log negative_512.log
++ */
++public class TestSHA512Intrinsics {
++ public static void main(String args[]) throws Exception {
++ new SHASanityTestBase(IntrinsicPredicates.SHA512_INTRINSICS_AVAILABLE,
++ SHASanityTestBase.SHA512_INTRINSIC_ID).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512MultiBlockIntrinsics.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,92 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import sha.predicate.IntrinsicPredicates;
++
++/**
++ * @test
++ * @bug 8035968
++ * @summary Verify that SHA-512 multi block intrinsic is actually used.
++ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../
++ * @build TestSHA intrinsics.Verifier TestSHA512MultiBlockIntrinsics
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=positive_384.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:+UseSHA512Intrinsics -XX:-UseSHA1Intrinsics
++ * -XX:-UseSHA256Intrinsics
++ * -Dalgorithm=SHA-384 TestSHA512MultiBlockIntrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=positive_384_def.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:+UseSHA512Intrinsics -Dalgorithm=SHA-384
++ * TestSHA512MultiBlockIntrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=negative_384.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA -XX:-UseSHA
++ * -Dalgorithm=SHA-384 TestSHA1Intrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=positive_512.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:+UseSHA512Intrinsics -XX:-UseSHA1Intrinsics
++ * -XX:-UseSHA256Intrinsics
++ * -Dalgorithm=SHA-512 TestSHA512MultiBlockIntrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=positive_512_def.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA
++ * -XX:+UseSHA512Intrinsics -Dalgorithm=SHA-512
++ * TestSHA512MultiBlockIntrinsics
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500
++ * -XX:Tier4InvocationThreshold=500
++ * -XX:+LogCompilation -XX:LogFile=negative_512.log
++ * -XX:CompileOnly=sun/security/provider/DigestBase
++ * -XX:CompileOnly=sun/security/provider/SHA -XX:-UseSHA
++ * -Dalgorithm=SHA-512 TestSHA512MultiBlockIntrinsics
++ * @run main/othervm -DverificationStrategy=VERIFY_INTRINSIC_USAGE
++ * intrinsics.Verifier positive_384.log positive_512.log
++ * positive_384_def.log positive_512_def.log negative_384.log
++ * negative_512.log
++ */
++public class TestSHA512MultiBlockIntrinsics {
++ public static void main(String args[]) throws Exception {
++ new SHASanityTestBase(IntrinsicPredicates.SHA512_INTRINSICS_AVAILABLE,
++ SHASanityTestBase.MB_INTRINSIC_ID).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/jsr292/NullConstantReceiver.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8059556
++ * @run main/othervm -Xbatch NullConstantReceiver
++ */
++
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.lang.invoke.MethodType;
++
++public class NullConstantReceiver {
++ static final MethodHandle target;
++ static {
++ try {
++ target = MethodHandles.lookup().findVirtual(NullConstantReceiver.class, "test", MethodType.methodType(void.class));
++ } catch (ReflectiveOperationException e) {
++ throw new Error(e);
++ }
++ }
++
++ public void test() {}
++
++ static void run() throws Throwable {
++ target.invokeExact((NullConstantReceiver) null);
++ }
++
++ public static void main(String[] args) throws Throwable {
++ for (int i = 0; i<15000; i++) {
++ try {
++ run();
++ } catch (NullPointerException e) {
++ // expected
++ continue;
++ }
++ throw new AssertionError("NPE wasn't thrown");
++ }
++ System.out.println("TEST PASSED");
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/jsr292/RedefineMethodUsedByMultipleMethodHandles.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,174 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8042235
++ * @summary redefining method used by multiple MethodHandles crashes VM
++ * @compile -XDignore.symbol.file RedefineMethodUsedByMultipleMethodHandles.java
++ * @run main RedefineMethodUsedByMultipleMethodHandles
++ */
++
++import java.io.*;
++import java.lang.instrument.*;
++import java.lang.invoke.*;
++import java.lang.invoke.MethodHandles.Lookup;
++import java.lang.management.*;
++import java.lang.reflect.*;
++import java.nio.file.*;
++import java.security.*;
++import java.util.jar.*;
++
++import javax.tools.*;
++
++import jdk.internal.org.objectweb.asm.*;
++
++public class RedefineMethodUsedByMultipleMethodHandles {
++
++ static class Foo {
++ public static Object getName() {
++ return "foo";
++ }
++ }
++
++ public static void main(String[] args) throws Throwable {
++
++ Lookup lookup = MethodHandles.lookup();
++ Method fooMethod = Foo.class.getDeclaredMethod("getName");
++
++ // fooMH2 displaces fooMH1 from the MemberNamesTable
++ MethodHandle fooMH1 = lookup.unreflect(fooMethod);
++ MethodHandle fooMH2 = lookup.unreflect(fooMethod);
++
++ System.out.println("fooMH1.invoke = " + fooMH1.invokeExact());
++ System.out.println("fooMH2.invoke = " + fooMH2.invokeExact());
++
++ // Redefining Foo.getName() causes vmtarget to be updated
++ // in fooMH2 but not fooMH1
++ redefineFoo();
++
++ // Full GC causes fooMH1.vmtarget to be deallocated
++ System.gc();
++
++ // Calling fooMH1.vmtarget crashes the VM
++ System.out.println("fooMH1.invoke = " + fooMH1.invokeExact());
++ }
++
++ /**
++ * Adds the class file bytes for {@code c} to {@code jar}.
++ */
++ static void add(JarOutputStream jar, Class<?> c) throws IOException {
++ String classAsPath = c.getName().replace('.', '/') + ".class";
++ jar.putNextEntry(new JarEntry(classAsPath));
++ InputStream stream = c.getClassLoader().getResourceAsStream(classAsPath);
++
++ int b;
++ while ((b = stream.read()) != -1) {
++ jar.write(b);
++ }
++ }
++
++ static void redefineFoo() throws Exception {
++ Manifest manifest = new Manifest();
++ manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
++ Attributes mainAttrs = manifest.getMainAttributes();
++ mainAttrs.putValue("Agent-Class", FooAgent.class.getName());
++ mainAttrs.putValue("Can-Redefine-Classes", "true");
++ mainAttrs.putValue("Can-Retransform-Classes", "true");
++
++ Path jar = Files.createTempFile("myagent", ".jar");
++ try {
++ JarOutputStream jarStream = new JarOutputStream(new FileOutputStream(jar.toFile()), manifest);
++ add(jarStream, FooAgent.class);
++ add(jarStream, FooTransformer.class);
++ jarStream.close();
++ runAgent(jar);
++ } finally {
++ Files.deleteIfExists(jar);
++ }
++ }
++
++ public static void runAgent(Path agent) throws Exception {
++ String vmName = ManagementFactory.getRuntimeMXBean().getName();
++ int p = vmName.indexOf('@');
++ assert p != -1 : "VM name not in <pid>@<host> format: " + vmName;
++ String pid = vmName.substring(0, p);
++ ClassLoader cl = ToolProvider.getSystemToolClassLoader();
++ Class<?> c = Class.forName("com.sun.tools.attach.VirtualMachine", true, cl);
++ Method attach = c.getDeclaredMethod("attach", String.class);
++ Method loadAgent = c.getDeclaredMethod("loadAgent", String.class);
++ Method detach = c.getDeclaredMethod("detach");
++ Object vm = attach.invoke(null, pid);
++ loadAgent.invoke(vm, agent.toString());
++ detach.invoke(vm);
++ }
++
++ public static class FooAgent {
++
++ public static void agentmain(@SuppressWarnings("unused") String args, Instrumentation inst) throws Exception {
++ assert inst.isRedefineClassesSupported();
++ assert inst.isRetransformClassesSupported();
++ inst.addTransformer(new FooTransformer(), true);
++ Class<?>[] classes = inst.getAllLoadedClasses();
++ for (int i = 0; i < classes.length; i++) {
++ Class<?> c = classes[i];
++ if (c == Foo.class) {
++ inst.retransformClasses(new Class[]{c});
++ }
++ }
++ }
++ }
++
++ static class FooTransformer implements ClassFileTransformer {
++
++ @Override
++ public byte[] transform(ClassLoader cl, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
++ if (Foo.class.equals(classBeingRedefined)) {
++ System.out.println("redefining " + classBeingRedefined);
++ ClassReader cr = new ClassReader(classfileBuffer);
++ ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES);
++ ClassVisitor adapter = new ClassVisitor(Opcodes.ASM5, cw) {
++ @Override
++ public MethodVisitor visitMethod(int access, String base, String desc, String signature, String[] exceptions) {
++ MethodVisitor mv = cv.visitMethod(access, base, desc, signature, exceptions);
++ if (mv != null) {
++ mv = new MethodVisitor(Opcodes.ASM5, mv) {
++ @Override
++ public void visitLdcInsn(Object cst) {
++ System.out.println("replacing \"" + cst + "\" with \"bar\"");
++ mv.visitLdcInsn("bar");
++ }
++ };
++ }
++ return mv;
++ }
++ };
++
++ cr.accept(adapter, ClassReader.SKIP_FRAMES);
++ cw.visitEnd();
++ return cw.toByteArray();
++ }
++ return classfileBuffer;
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/jsr292/VMAnonymousClasses.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,125 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8058828
++ * @run main/bootclasspath -Xbatch VMAnonymousClasses
++ */
++
++import jdk.internal.org.objectweb.asm.ClassWriter;
++import jdk.internal.org.objectweb.asm.MethodVisitor;
++import jdk.internal.org.objectweb.asm.Opcodes;
++import sun.misc.Unsafe;
++
++import java.lang.invoke.ConstantCallSite;
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.lang.invoke.MethodType;
++import java.lang.invoke.MutableCallSite;
++import java.lang.invoke.VolatileCallSite;
++
++public class VMAnonymousClasses {
++ static final String TEST_METHOD_NAME = "constant";
++
++ static final Unsafe UNSAFE = Unsafe.getUnsafe();
++
++ static int getConstantPoolSize(byte[] classFile) {
++ // The first few bytes:
++ // u4 magic;
++ // u2 minor_version;
++ // u2 major_version;
++ // u2 constant_pool_count;
++ return ((classFile[8] & 0xFF) << 8) | (classFile[9] & 0xFF);
++ }
++
++ static void test(Object value) throws ReflectiveOperationException {
++ System.out.printf("Test: %s", value != null ? value.getClass() : "null");
++
++ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
++ cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, "Test", null, "java/lang/Object", null);
++
++ MethodVisitor mv = cw.visitMethod(Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, TEST_METHOD_NAME, "()Ljava/lang/Object;", null, null);
++
++ String placeholder = "CONSTANT";
++ int index = cw.newConst(placeholder);
++ mv.visitLdcInsn(placeholder);
++ mv.visitInsn(Opcodes.ARETURN);
++
++ mv.visitMaxs(0, 0);
++ mv.visitEnd();
++
++ byte[] classFile = cw.toByteArray();
++
++ Object[] cpPatches = new Object[getConstantPoolSize(classFile)];
++ cpPatches[index] = value;
++
++ Class<?> test = UNSAFE.defineAnonymousClass(VMAnonymousClasses.class, classFile, cpPatches);
++
++ Object expectedResult = (value != null) ? value : placeholder;
++ for (int i = 0; i<15000; i++) {
++ Object result = test.getMethod(TEST_METHOD_NAME).invoke(null);
++ if (result != expectedResult) {
++ throw new AssertionError(String.format("Wrong value returned: %s != %s", value, result));
++ }
++ }
++ System.out.println(" PASSED");
++ }
++
++ public static void main(String[] args) throws ReflectiveOperationException {
++ // Objects
++ test(new Object());
++ test("TEST");
++ test(new VMAnonymousClasses());
++ test(null);
++
++ // Class
++ test(String.class);
++
++ // Arrays
++ test(new boolean[0]);
++ test(new byte[0]);
++ test(new char[0]);
++ test(new short[0]);
++ test(new int[0]);
++ test(new long[0]);
++ test(new float[0]);
++ test(new double[0]);
++ test(new Object[0]);
++
++ // Multi-dimensional arrays
++ test(new byte[0][0]);
++ test(new Object[0][0]);
++
++ // MethodHandle-related
++ MethodType mt = MethodType.methodType(void.class, String[].class);
++ MethodHandle mh = MethodHandles.lookup().findStatic(VMAnonymousClasses.class, "main", mt);
++ test(mt);
++ test(mh);
++ test(new ConstantCallSite(mh));
++ test(new MutableCallSite(MethodType.methodType(void.class)));
++ test(new VolatileCallSite(MethodType.methodType(void.class)));
++
++ System.out.println("TEST PASSED");
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/loopopts/TestDeadBackbranchArrayAccess.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,58 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++/**
++ * @test
++ * @bug 8054478
++ * @summary dead backbranch in main loop results in erroneous array access
++ * @run main/othervm -XX:CompileOnly=TestDeadBackbranchArrayAccess -Xcomp TestDeadBackbranchArrayAccess
++ *
++ */
++
++public class TestDeadBackbranchArrayAccess {
++ static char[] pattern0 = {0};
++ static char[] pattern1 = {1};
++
++ static void test(char[] array) {
++ if (pattern1 == null) return;
++
++ int i = 0;
++ int pos = 0;
++ char c = array[pos];
++
++ while (i >= 0 && (c == pattern0[i] || c == pattern1[i])) {
++ i--;
++ pos--;
++ if (pos != -1) {
++ c = array[pos];
++ }
++ }
++ }
++
++ public static void main(String[] args) {
++ for (int i = 0; i < 1000000; i++) {
++ test(new char[1]);
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/macronodes/TestEliminateAllocationPhi.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,94 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8046698
++ * @summary PhiNode inserted between AllocateNode and Initialization node confuses allocation elimination
++ * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestEliminateAllocationPhi
++ *
++ */
++
++public class TestEliminateAllocationPhi {
++
++ // This will return I when called from m(0 and once optimized will
++ // go away but this will confuse escape analysis in m(): it will
++ // find I as non escaping but non scalar replaceable. In its own
++ // method so that we can make the profile of the if() branch look
++ // like it's taken sometimes.
++ static Integer m2(Integer I, int i) {
++ for (; i < 10; i=(i+2)*(i+2)) {
++ }
++ if (i == 121) {
++ return II;
++ }
++ return I;
++ }
++
++ static Integer II = new Integer(42);
++
++ static int m(int[] integers, boolean flag) {
++ int j = 0;
++ while(true) {
++ try {
++ int k = integers[j++];
++ // A branch that will cause loop unswitching
++ if (flag) {
++ k += 42;
++ }
++ if (k < 1000) {
++ throw new Exception();
++ }
++ // Because of the try/catch the Allocate node for this
++ // new will be in the loop while the Initialization
++ // node will be outside the loop. When loop
++ // unswitching happens, the Allocate node will be
++ // cloned and the results of both will be inputs to a
++ // Phi that will be between the Allocate nodes and the
++ // Initialization nodes.
++ Integer I = new Integer(k);
++
++ I = m2(I, 0);
++
++ int i = I.intValue();
++ return i;
++ } catch(Exception e) {
++ }
++ }
++ }
++
++ static public void main(String[] args) {
++ for (int i = 0; i < 5000; i++) {
++ m2(null, 1);
++ }
++
++ int[] integers = { 2000 };
++ for (int i = 0; i < 6000; i++) {
++ m(integers, (i%2) == 0);
++ }
++ int[] integers2 = { 1, 2, 3, 4, 5, 2000 };
++ for (int i = 0; i < 10000; i++) {
++ m(integers2, (i%2) == 0);
++ }
++ }
++}
+--- ./hotspot/test/compiler/membars/DekkerTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/membars/DekkerTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -25,9 +25,9 @@
+ * @test
+ * @bug 8007898
+ * @summary Incorrect optimization of Memory Barriers in Matcher::post_store_load_barrier().
+- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
+- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
+- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
++ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest
++ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest
++ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @author Martin Doerr martin DOT doerr AT sap DOT com
+ *
+ * Run 3 times since the failure is intermittent.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/membars/TestMemBarAcquire.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,53 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test TestMemBarAcquire
++ * @bug 8048879
++ * @summary "Tests optimization of MemBarAcquireNodes"
++ * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation TestMemBarAcquire
++ */
++public class TestMemBarAcquire {
++ private volatile static Object defaultObj = new Object();
++ private Object obj;
++
++ public TestMemBarAcquire(Object param) {
++ // Volatile load. MemBarAcquireNode is added after the
++ // load to prevent following loads from floating up past.
++ // StoreNode is added to store result of load in 'obj'.
++ this.obj = defaultObj;
++ // Overrides 'obj' and therefore makes previous StoreNode
++ // and the corresponding LoadNode useless. However, the
++ // LoadNode is still connected to the MemBarAcquireNode
++ // that should now release the reference.
++ this.obj = param;
++ }
++
++ public static void main(String[] args) throws Exception {
++ // Make sure TestMemBarAcquire::<init> is compiled
++ for (int i = 0; i < 100000; ++i) {
++ TestMemBarAcquire p = new TestMemBarAcquire(new Object());
++ }
++ }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/osr/TestOSRWithNonEmptyStack.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,127 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.lang.reflect.Constructor;
++import java.lang.reflect.Method;
++
++import jdk.internal.org.objectweb.asm.ClassWriter;
++import jdk.internal.org.objectweb.asm.Label;
++import jdk.internal.org.objectweb.asm.MethodVisitor;
++import static jdk.internal.org.objectweb.asm.Opcodes.*;
++
++/**
++ * @test
++ * @bug 8051344
++ * @summary Force OSR compilation with non-empty stack at the OSR entry point.
++ * @compile -XDignore.symbol.file TestOSRWithNonEmptyStack.java
++ * @run main/othervm -XX:CompileOnly=TestCase.test TestOSRWithNonEmptyStack
++ */
++public class TestOSRWithNonEmptyStack extends ClassLoader {
++ private static final int CLASS_FILE_VERSION = 52;
++ private static final String CLASS_NAME = "TestCase";
++ private static final String METHOD_NAME = "test";
++ private static final int ITERATIONS = 1_000_000;
++
++ private static byte[] generateTestClass() {
++ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
++
++ cw.visit(TestOSRWithNonEmptyStack.CLASS_FILE_VERSION, ACC_PUBLIC,
++ TestOSRWithNonEmptyStack.CLASS_NAME, null, "java/lang/Object",
++ null);
++
++ TestOSRWithNonEmptyStack.generateConstructor(cw);
++ TestOSRWithNonEmptyStack.generateTestMethod(cw);
++
++ cw.visitEnd();
++ return cw.toByteArray();
++ }
++
++ private static void generateConstructor(ClassWriter classWriter) {
++ MethodVisitor mv = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V",
++ null, null);
++
++ mv.visitCode();
++
++ mv.visitVarInsn(ALOAD, 0);
++ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V",
++ false);
++ mv.visitInsn(RETURN);
++
++ mv.visitMaxs(0, 0);
++ mv.visitEnd();
++ }
++
++ private static void generateTestMethod(ClassWriter classWriter) {
++ MethodVisitor mv = classWriter.visitMethod(ACC_PUBLIC,
++ TestOSRWithNonEmptyStack.METHOD_NAME, "()V", null, null);
++ Label osrEntryPoint = new Label();
++
++ mv.visitCode();
++ // Push 'this' into stack before OSR entry point to bail out compilation
++ mv.visitVarInsn(ALOAD, 0);
++ // Setup loop counter
++ mv.visitInsn(ICONST_0);
++ mv.visitVarInsn(ISTORE, 1);
++ // Begin loop
++ mv.visitLabel(osrEntryPoint);
++ // Increment loop counter
++ mv.visitVarInsn(ILOAD, 1);
++ mv.visitInsn(ICONST_1);
++ mv.visitInsn(IADD);
++ // Duplicate it for loop condition check
++ mv.visitInsn(DUP);
++ mv.visitVarInsn(ISTORE, 1);
++ // Check loop condition
++ mv.visitLdcInsn(TestOSRWithNonEmptyStack.ITERATIONS);
++ mv.visitJumpInsn(IF_ICMPLT, osrEntryPoint);
++ // Pop 'this'.
++ mv.visitInsn(POP);
++ mv.visitInsn(RETURN);
++
++ mv.visitMaxs(0, 0);
++ mv.visitEnd();
++ }
++
++ private void run() {
++ byte[] bytecode = TestOSRWithNonEmptyStack.generateTestClass();
++
++ try {
++ Class klass = defineClass(TestOSRWithNonEmptyStack.CLASS_NAME,
++ bytecode, 0, bytecode.length);
++
++ Constructor ctor = klass.getConstructor();
++ Method method = klass.getDeclaredMethod(
++ TestOSRWithNonEmptyStack.METHOD_NAME);
++
++ Object testCase = ctor.newInstance();
++ method.invoke(testCase);
++ } catch (Exception e) {
++ throw new RuntimeException(
++ "Test bug: generated class should be valid.", e);
++ }
++ }
++
++ public static void main(String args[]) {
++ new TestOSRWithNonEmptyStack().run();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/osr/TestRangeCheck.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test TestRangeCheck
++ * @bug 8054883
++ * @summary Tests that range check is not skipped
++ */
++
++public class TestRangeCheck {
++ public static void main(String args[]) {
++ try {
++ test();
++ throw new AssertionError("Expected ArrayIndexOutOfBoundsException was not thrown");
++ } catch (ArrayIndexOutOfBoundsException e) {
++ System.out.println("Expected ArrayIndexOutOfBoundsException was thrown");
++ }
++ }
++
++ private static void test() {
++ int arr[] = new int[1];
++ int result = 1;
++
++ // provoke OSR compilation
++ for (int i = 0; i < Integer.MAX_VALUE; i++) {
++ }
++
++ if (result > 0 && arr[~result] > 0) {
++ arr[~result] = 0;
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/rangechecks/TestRangeCheckSmearing.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,436 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8066103
++ * @summary C2's range check smearing allows out of bound array accesses
++ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox /testlibrary/com/oracle/java/testlibrary
++ * @build TestRangeCheckSmearing
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main ClassFileInstaller com.oracle.java.testlibrary.Platform
++ * @run main/othervm -ea -Xmixed -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
++ * -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestRangeCheckSmearing
++ *
++ */
++
++import java.lang.annotation.*;
++import java.lang.reflect.*;
++import java.util.*;
++import sun.hotspot.WhiteBox;
++import sun.hotspot.code.NMethod;
++import com.oracle.java.testlibrary.Platform;
++
++public class TestRangeCheckSmearing {
++ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
++
++ @Retention(RetentionPolicy.RUNTIME)
++ @interface Args { int[] value(); }
++
++ // first range check is i + max of all constants
++ @Args({0, 8})
++ static int m1(int[] array, int i, boolean allaccesses) {
++ int res = 0;
++ res += array[i+9];
++ if (allaccesses) {
++ res += array[i+8];
++ res += array[i+7];
++ res += array[i+6];
++ res += array[i+5];
++ res += array[i+4];
++ res += array[i+3];
++ res += array[i+2];
++ res += array[i+1];
++ }
++ return res;
++ }
++
++ // first range check is i + min of all constants
++ @Args({0, -9})
++ static int m2(int[] array, int i, boolean allaccesses) {
++ int res = 0;
++ res += array[i+1];
++ if (allaccesses) {
++ res += array[i+2];
++ res += array[i+3];
++ res += array[i+4];
++ res += array[i+5];
++ res += array[i+6];
++ res += array[i+7];
++ res += array[i+8];
++ res += array[i+9];
++ }
++ return res;
++ }
++
++ // first range check is not i + min/max of all constants
++ @Args({0, 8})
++ static int m3(int[] array, int i, boolean allaccesses) {
++ int res = 0;
++ res += array[i+3];
++ if (allaccesses) {
++ res += array[i+2];
++ res += array[i+1];
++ res += array[i+4];
++ res += array[i+5];
++ res += array[i+6];
++ res += array[i+7];
++ res += array[i+8];
++ res += array[i+9];
++ }
++ return res;
++ }
++
++ @Args({0, -9})
++ static int m4(int[] array, int i, boolean allaccesses) {
++ int res = 0;
++ res += array[i+3];
++ if (allaccesses) {
++ res += array[i+4];
++ res += array[i+1];
++ res += array[i+2];
++ res += array[i+5];
++ res += array[i+6];
++ res += array[i+7];
++ res += array[i+8];
++ res += array[i+9];
++ }
++ return res;
++ }
++
++ @Args({0, -3})
++ static int m5(int[] array, int i, boolean allaccesses) {
++ int res = 0;
++ res += array[i+3];
++ res += array[i+2];
++ if (allaccesses) {
++ res += array[i+1];
++ res += array[i+4];
++ res += array[i+5];
++ res += array[i+6];
++ res += array[i+7];
++ res += array[i+8];
++ res += array[i+9];
++ }
++ return res;
++ }
++
++ @Args({0, 6})
++ static int m6(int[] array, int i, boolean allaccesses) {
++ int res = 0;
++ res += array[i+3];
++ res += array[i+4];
++ if (allaccesses) {
++ res += array[i+2];
++ res += array[i+1];
++ res += array[i+5];
++ res += array[i+6];
++ res += array[i+7];
++ res += array[i+8];
++ res += array[i+9];
++ }
++ return res;
++ }
++
++ @Args({0, 6})
++ static int m7(int[] array, int i, boolean allaccesses) {
++ int res = 0;
++ res += array[i+3];
++ res += array[i+2];
++ res += array[i+4];
++ if (allaccesses) {
++ res += array[i+1];
++ res += array[i+5];
++ res += array[i+6];
++ res += array[i+7];
++ res += array[i+8];
++ res += array[i+9];
++ }
++ return res;
++ }
++
++ @Args({0, -3})
++ static int m8(int[] array, int i, boolean allaccesses) {
++ int res = 0;
++ res += array[i+3];
++ res += array[i+4];
++ res += array[i+2];
++ if (allaccesses) {
++ res += array[i+1];
++ res += array[i+5];
++ res += array[i+6];
++ res += array[i+7];
++ res += array[i+8];
++ res += array[i+9];
++ }
++ return res;
++ }
++
++ @Args({6, 15})
++ static int m9(int[] array, int i, boolean allaccesses) {
++ int res = 0;
++ res += array[i+3];
++ if (allaccesses) {
++ res += array[i-2];
++ res += array[i-1];
++ res += array[i-4];
++ res += array[i-5];
++ res += array[i-6];
++ }
++ return res;
++ }
++
++ @Args({3, 12})
++ static int m10(int[] array, int i, boolean allaccesses) {
++ int res = 0;
++ res += array[i+3];
++ if (allaccesses) {
++ res += array[i-2];
++ res += array[i-1];
++ res += array[i-3];
++ res += array[i+4];
++ res += array[i+5];
++ res += array[i+6];
++ }
++ return res;
++ }
++
++ @Args({3, -3})
++ static int m11(int[] array, int i, boolean allaccesses) {
++ int res = 0;
++ res += array[i+3];
++ res += array[i-2];
++ if (allaccesses) {
++ res += array[i+5];
++ res += array[i+6];
++ }
++ return res;
++ }
++
++ @Args({3, 6})
++ static int m12(int[] array, int i, boolean allaccesses) {
++ int res = 0;
++ res += array[i+3];
++ res += array[i+6];
++ if (allaccesses) {
++ res += array[i-2];
++ res += array[i-3];
++ }
++ return res;
++ }
++
++ // check that identical range check is replaced by dominating one
++ // only when correct
++ @Args({0})
++ static int m13(int[] array, int i, boolean ignore) {
++ int res = 0;
++ res += array[i+3];
++ res += array[i+3];
++ return res;
++ }
++
++ @Args({2, 0})
++ static int m14(int[] array, int i, boolean ignore) {
++ int res = 0;
++
++ res += array[i];
++ res += array[i-2];
++ res += array[i]; // If range check below were to be removed first this cannot be considered identical to first range check
++ res += array[i-1]; // range check removed so i-1 array access depends on previous check
++
++ return res;
++ }
++
++ static int[] m15_dummy = new int[10];
++ @Args({2, 0})
++ static int m15(int[] array, int i, boolean ignore) {
++ int res = 0;
++ res += array[i];
++
++ // When the loop is optimized out we don't want the
++ // array[i-1] access which is dependent on array[i]'s
++ // range check to become dependent on the identical range
++ // check above.
++
++ int[] array2 = m15_dummy;
++ int j = 0;
++ for (; j < 10; j++);
++ if (j == 10) {
++ array2 = array;
++ }
++
++ res += array2[i-2];
++ res += array2[i];
++ res += array2[i-1]; // range check removed so i-1 array access depends on previous check
++
++ return res;
++ }
++
++ @Args({2, 0})
++ static int m16(int[] array, int i, boolean ignore) {
++ int res = 0;
++
++ res += array[i];
++ res += array[i-1];
++ res += array[i-1];
++ res += array[i-2];
++
++ return res;
++ }
++
++ @Args({2, 0})
++ static int m17(int[] array, int i, boolean ignore) {
++ int res = 0;
++
++ res += array[i];
++ res += array[i-2];
++ res += array[i-2];
++ res += array[i+2];
++ res += array[i+2];
++ res += array[i-1];
++ res += array[i-1];
++
++ return res;
++ }
++
++ static public void main(String[] args) {
++ if (WHITE_BOX.getBooleanVMFlag("BackgroundCompilation")) {
++ throw new AssertionError("Background compilation enabled");
++ }
++ new TestRangeCheckSmearing().doTests();
++ }
++ boolean success = true;
++ boolean exception = false;
++ final int[] array = new int[10];
++ final HashMap<String,Method> tests = new HashMap<>();
++ {
++ final Class<?> TEST_PARAM_TYPES[] = { int[].class, int.class, boolean.class };
++ for (Method m : this.getClass().getDeclaredMethods()) {
++ if (m.getName().matches("m[0-9]+")) {
++ assert(Modifier.isStatic(m.getModifiers())) : m;
++ assert(m.getReturnType() == int.class) : m;
++ assert(Arrays.equals(m.getParameterTypes(), TEST_PARAM_TYPES)) : m;
++ tests.put(m.getName(), m);
++ }
++ }
++ }
++
++ void invokeTest(Method m, int[] array, int index, boolean z) {
++ try {
++ m.invoke(null, array, index, z);
++ } catch (ReflectiveOperationException roe) {
++ Throwable ex = roe.getCause();
++ if (ex instanceof ArrayIndexOutOfBoundsException)
++ throw (ArrayIndexOutOfBoundsException) ex;
++ throw new AssertionError(roe);
++ }
++ }
++
++ void doTest(String name) {
++ Method m = tests.get(name);
++ tests.remove(name);
++ int[] args = m.getAnnotation(Args.class).value();
++ int index0 = args[0], index1;
++ boolean exceptionRequired = true;
++ if (args.length == 2) {
++ index1 = args[1];
++ } else {
++ // no negative test for this one
++ assert(args.length == 1);
++ assert(name.equals("m13"));
++ exceptionRequired = false;
++ index1 = index0;
++ }
++ // Get the method compiled.
++ if (!WHITE_BOX.isMethodCompiled(m)) {
++ // If not, try to compile it with C2
++ if(!WHITE_BOX.enqueueMethodForCompilation(m, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION)) {
++ // C2 compiler not available, try to compile with C1
++ WHITE_BOX.enqueueMethodForCompilation(m, CompilerWhiteBoxTest.COMP_LEVEL_SIMPLE);
++ }
++ }
++ if (!WHITE_BOX.isMethodCompiled(m)) {
++ throw new RuntimeException(m + " not compiled");
++ }
++
++ // valid access
++ invokeTest(m, array, index0, true);
++
++ if (!WHITE_BOX.isMethodCompiled(m)) {
++ throw new RuntimeException(m + " deoptimized on valid array access");
++ }
++
++ exception = false;
++ boolean test_success = true;
++ try {
++ invokeTest(m, array, index1, false);
++ } catch(ArrayIndexOutOfBoundsException aioob) {
++ exception = true;
++ System.out.println("ArrayIndexOutOfBoundsException thrown in "+name);
++ }
++ if (!exception) {
++ System.out.println("ArrayIndexOutOfBoundsException was not thrown in "+name);
++ }
++
++ if (Platform.isServer()) {
++ if (exceptionRequired == WHITE_BOX.isMethodCompiled(m)) {
++ System.out.println((exceptionRequired?"Didn't deoptimized":"deoptimized") + " in "+name);
++ test_success = false;
++ }
++ }
++
++ if (exception != exceptionRequired) {
++ System.out.println((exceptionRequired?"exception required but not thrown":"not exception required but thrown") + " in "+name);
++ test_success = false;
++ }
++
++ if (!test_success) {
++ success = false;
++ System.out.println("TEST FAILED: "+name);
++ }
++
++ }
++ void doTests() {
++ doTest("m1");
++ doTest("m2");
++ doTest("m3");
++ doTest("m4");
++ doTest("m5");
++ doTest("m6");
++ doTest("m7");
++ doTest("m8");
++ doTest("m9");
++ doTest("m10");
++ doTest("m11");
++ doTest("m12");
++ doTest("m13");
++ doTest("m14");
++ doTest("m15");
++ doTest("m16");
++ doTest("m17");
++ if (!success) {
++ throw new RuntimeException("Some tests failed");
++ }
++ assert(tests.isEmpty()) : tests;
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/rangechecks/TestRangeCheckSmearingLoopOpts.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,76 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8048170
++ * @summary Following range check smearing, range check cannot be replaced by dominating identical test.
++ * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestRangeCheckSmearingLoopOpts
++ *
++ */
++public class TestRangeCheckSmearingLoopOpts {
++
++ static int dummy;
++
++ static int m1(int[] array, int i) {
++ for (;;) {
++ for (;;) {
++ if (array[i] < 0) { // range check (i+0) dominates equivalent check below
++ break;
++ }
++ i++;
++ }
++
++ // A control flow that stops IfNode::up_one_dom()
++ if ((i % 2)== 0) {
++ if ((array[i] % 2) == 0) {
++ dummy = i;
++ }
++ }
++
++ // IfNode::Ideal will rewrite some range checks if Compile::allow_range_check_smearing
++ if (array[i-1] == 9) { // range check (i-1) unchanged
++ int res = array[i-3]; // range check (i-3) unchanged
++ res += array[i]; // range check (i+0) unchanged
++ res += array[i-2]; // removed redundant range check
++ // the previous access might be hoisted by
++ // PhaseIdealLoop::split_if_with_blocks_post because
++ // it appears to have the same guard, but it also
++ // depends on the previous guards
++ return res;
++ }
++ i++;
++ }
++ }
++
++ static public void main(String[] args) {
++ int[] array = { 0, 1, 2, -3, 4, 5, -2, 7, 8, 9, -1 };
++ for (int i = 0; i < 20000; i++) {
++ m1(array, 0);
++ }
++ array[0] = -1;
++ try {
++ m1(array, 0);
++ } catch(ArrayIndexOutOfBoundsException aioobe) {}
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/relocations/TestPrintRelocations.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8044538
++ * @summary assert hit while printing relocations for jump table entries
++ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:+PrintRelocations TestPrintRelocations
++ */
++
++/**
++ * The test compiles all methods (-Xcomp) and prints their relocation
++ * entries (-XX:+PrintRelocations) to make sure the printing works.
++ */
++public class TestPrintRelocations {
++
++ static public void main(String[] args) { }
++}
+--- ./hotspot/test/compiler/rtm/cli/TestRTMRetryCountOption.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/rtm/cli/TestRTMRetryCountOption.java Wed Feb 04 12:14:39 2015 -0800
+@@ -35,7 +35,7 @@
+ private static final String DEFAULT_VALUE = "5";
+
+ private TestRTMRetryCountOption() {
+- super(Boolean.TRUE::booleanValue, "RTMRetryCount", false, true,
++ super(Boolean.TRUE::booleanValue, "RTMRetryCount", false, false,
+ TestRTMRetryCountOption.DEFAULT_VALUE,
+ "0", "10", "100", "1000");
+ }
+--- ./hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java Wed Feb 04 12:14:39 2015 -0800
+@@ -50,25 +50,15 @@
+
+ @Override
+ public void runTestCases() throws Throwable {
+- String experimentalOptionError
+- = CommandLineOptionTest.getExperimentalOptionErrorMessage(
+- "UseRTMDeopt");
+- // verify that option is experimental
++ // verify that option could be turned on
+ CommandLineOptionTest.verifySameJVMStartup(
+- new String[] { experimentalOptionError }, null, ExitCode.FAIL,
+- "-XX:+UseRTMDeopt");
+- // verify that option could be turned on
+- CommandLineOptionTest.verifySameJVMStartup(null, null, ExitCode.OK,
+- CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+- "-XX:+UseRTMDeopt");
++ null, null, ExitCode.OK, "-XX:+UseRTMDeopt");
+ // verify that option could be turned off
+- CommandLineOptionTest.verifySameJVMStartup(null, null, ExitCode.OK,
+- CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+- "-XX:-UseRTMDeopt");
++ CommandLineOptionTest.verifySameJVMStartup(
++ null, null, ExitCode.OK, "-XX:-UseRTMDeopt");
+ // verify default value
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
+- TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE,
+- CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
++ TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE);
+ // verify default value
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
+ TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE,
+--- ./hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java Wed Feb 04 12:14:39 2015 -0800
+@@ -48,7 +48,7 @@
+ private TestUseRTMDeoptOptionOnUnsupportedConfig() {
+ super(new NotPredicate(new AndPredicate(new SupportedCPU(),
+ new SupportedVM())),
+- "UseRTMDeopt", true, true,
++ "UseRTMDeopt", true, false,
+ TestUseRTMDeoptOptionOnUnsupportedConfig.DEFAULT_VALUE, "true");
+ }
+
+@@ -57,14 +57,11 @@
+ super.verifyJVMStartup();
+ // verify default value
+ CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+- defaultValue,
+- CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
++ defaultValue);
+ // verify that until RTMLocking is not used, value
+ // will be set to default false.
+ CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+- defaultValue,
+- CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+- "-XX:+UseRTMDeopt");
++ defaultValue, "-XX:+UseRTMDeopt");
+ }
+
+ public static void main(String args[]) throws Throwable {
+--- ./hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java Wed Feb 04 12:14:39 2015 -0800
+@@ -51,15 +51,8 @@
+ @Override
+ public void runTestCases() throws Throwable {
+ String unrecongnizedOption
+- = CommandLineOptionTest.getUnrecognizedOptionErrorMessage(
++ = CommandLineOptionTest.getUnrecognizedOptionErrorMessage(
+ "UseRTMLocking");
+- String experimentalOptionError
+- = CommandLineOptionTest.getExperimentalOptionErrorMessage(
+- "UseRTMLocking");
+- // verify that options is experimental
+- CommandLineOptionTest.verifySameJVMStartup(
+- new String[] { experimentalOptionError }, null, ExitCode.FAIL,
+- "-XX:+UseRTMLocking");
+ // verify that there are no warning or error in VM output
+ CommandLineOptionTest.verifySameJVMStartup(null,
+ new String[]{
+@@ -67,7 +60,8 @@
+ unrecongnizedOption
+ }, ExitCode.OK,
+ CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+- "-XX:+UseRTMLocking");
++ "-XX:+UseRTMLocking"
++ );
+
+ CommandLineOptionTest.verifySameJVMStartup(null,
+ new String[]{
+@@ -75,7 +69,8 @@
+ unrecongnizedOption
+ }, ExitCode.OK,
+ CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+- "-XX:-UseRTMLocking");
++ "-XX:-UseRTMLocking"
++ );
+ // verify that UseRTMLocking is of by default
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
+ TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE,
+--- ./hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java Wed Feb 04 12:14:39 2015 -0800
+@@ -63,9 +63,7 @@
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { errorMessage },
+ new String[] { unrecongnizedOption },
+- ExitCode.FAIL,
+- CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+- "-XX:+UseRTMLocking");
++ ExitCode.FAIL, "-XX:+UseRTMLocking");
+ // verify that we can pass -UseRTMLocking without
+ // getting any error messages
+ CommandLineOptionTest.verifySameJVMStartup(
+@@ -73,27 +71,20 @@
+ new String[]{
+ errorMessage,
+ unrecongnizedOption
+- }, ExitCode.OK,
+- CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+- "-XX:-UseRTMLocking");
++ }, ExitCode.OK, "-XX:-UseRTMLocking");
+
+ // verify that UseRTMLocking is false by default
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
+- TestUseRTMLockingOptionOnUnsupportedCPU.DEFAULT_VALUE,
+- CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
++ TestUseRTMLockingOptionOnUnsupportedCPU.DEFAULT_VALUE);
+ } else {
+ // verify that on non-x86 CPUs RTMLocking could not be used
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { unrecongnizedOption },
+- null, ExitCode.FAIL,
+- CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+- "-XX:+UseRTMLocking");
++ null, ExitCode.FAIL, "-XX:+UseRTMLocking");
+
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { unrecongnizedOption },
+- null, ExitCode.FAIL,
+- CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+- "-XX:-UseRTMLocking");
++ null, ExitCode.FAIL, "-XX:-UseRTMLocking");
+ }
+ }
+
+--- ./hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java Wed Feb 04 12:14:39 2015 -0800
+@@ -53,27 +53,17 @@
+ public void runTestCases() throws Throwable {
+ String errorMessage
+ = RTMGenericCommandLineOptionTest.RTM_UNSUPPORTED_VM_ERROR;
+- String experimentalOptionError
+- = CommandLineOptionTest.getExperimentalOptionErrorMessage(
+- "UseRTMLocking");
+- // verify that options is experimental
+- CommandLineOptionTest.verifySameJVMStartup(
+- new String[] { experimentalOptionError }, null, ExitCode.FAIL,
+- "-XX:+UseRTMLocking");
+ // verify that we can't use +UseRTMLocking
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { errorMessage }, null, ExitCode.FAIL,
+- CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+ "-XX:+UseRTMLocking");
+ // verify that we can turn it off
+ CommandLineOptionTest.verifySameJVMStartup(null,
+ new String[] { errorMessage }, ExitCode.OK,
+- CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+ "-XX:-UseRTMLocking");
+ // verify that it is off by default
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
+- TestUseRTMLockingOptionOnUnsupportedVM.DEFAULT_VALUE,
+- CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
++ TestUseRTMLockingOptionOnUnsupportedVM.DEFAULT_VALUE);
+ }
+
+ public static void main(String args[]) throws Throwable {
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/startup/NumCompilerThreadsCheck.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,57 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8034775
++ * @summary Ensures correct minimal number of compiler threads (provided by -XX:CICompilerCount=)
++ * @library /testlibrary
++ */
++import com.oracle.java.testlibrary.*;
++
++public class NumCompilerThreadsCheck {
++
++ public static void main(String[] args) throws Exception {
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:CICompilerCount=-1");
++ OutputAnalyzer out = new OutputAnalyzer(pb.start());
++
++ String expectedOutput = "CICompilerCount of -1 is invalid";
++ out.shouldContain(expectedOutput);
++
++ if (isZeroVm()) {
++ String expectedLowWaterMarkText = "must be at least 0";
++ out.shouldContain(expectedLowWaterMarkText);
++ }
++ }
++
++ private static boolean isZeroVm() {
++ String vmName = System.getProperty("java.vm.name");
++ if (vmName == null) {
++ throw new RuntimeException("No VM name");
++ }
++ if (vmName.toLowerCase().contains("zero")) {
++ return true;
++ }
++ return false;
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/testlibrary/intrinsics/Verifier.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,143 @@
++/*
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++package intrinsics;
++
++import java.io.BufferedReader;
++import java.io.FileReader;
++import java.util.Properties;
++
++public class Verifier {
++ enum VerificationStrategy {
++ VERIFY_STRONG_EQUALITY {
++ @Override
++ void verify(Properties expectedProperties, int fullMatchCnt,
++ int suspectCnt) {
++ int expectedCount = Integer.parseInt(
++ expectedProperties.getProperty(
++ Verifier.INTRINSIC_EXPECTED_COUNT_PROPERTY));
++ String intrinsicID = expectedProperties.getProperty(
++ Verifier.INTRINSIC_NAME_PROPERTY);
++
++ System.out.println("Intrinsic " + intrinsicID
++ + " verification, expected: " + expectedCount
++ + ", matched: " + fullMatchCnt
++ + ", suspected: " + suspectCnt);
++ if (expectedCount != fullMatchCnt) {
++ throw new RuntimeException(
++ "Unexpected count of intrinsic "
++ + intrinsicID
++ + " expected:" + expectedCount
++ + ", matched: " + fullMatchCnt
++ + ", suspected: " + suspectCnt);
++ }
++ }
++ },
++
++ VERIFY_INTRINSIC_USAGE {
++ @Override
++ void verify(Properties expectedProperties, int fullMatchCnt,
++ int suspectCnt) {
++ boolean isExpected = Boolean.parseBoolean(
++ expectedProperties.getProperty(
++ Verifier.INTRINSIC_IS_EXPECTED_PROPERTY));
++ String intrinsicID = expectedProperties.getProperty(
++ Verifier.INTRINSIC_NAME_PROPERTY);
++
++ System.out.println("Intrinsic " + intrinsicID
++ + " verification, is expected: " + isExpected
++ + ", matched: " + fullMatchCnt
++ + ", suspected: " + suspectCnt);
++ if ((fullMatchCnt == 0 && isExpected)
++ || (fullMatchCnt > 0 && !isExpected)) {
++ throw new RuntimeException(
++ "Unexpected count of intrinsic "
++ + intrinsicID
++ + " is expected:" + isExpected
++ + ", matched: " + fullMatchCnt
++ + ", suspected: " + suspectCnt);
++ }
++ }
++ };
++
++ void verify(Properties expectedProperties, int fullMathCnt,
++ int suspectCnt) {
++ throw new RuntimeException("Default strategy is not implemented.");
++ }
++ }
++
++ public static final String PROPERTY_FILE_SUFFIX = ".verify.properties";
++ public static final String INTRINSIC_NAME_PROPERTY = "intrinsic.name";
++ public static final String INTRINSIC_IS_EXPECTED_PROPERTY
++ = "intrinsic.expected";
++ public static final String INTRINSIC_EXPECTED_COUNT_PROPERTY
++ = "intrinsic.expectedCount";
++ private static final String DEFAULT_STRATEGY
++ = VerificationStrategy.VERIFY_STRONG_EQUALITY.name();
++
++ public static void main(String[] args) throws Exception {
++ if (args.length == 0) {
++ throw new RuntimeException("Test bug, nothing to verify");
++ }
++ for (String hsLogFile : args) {
++ verify(hsLogFile);
++ }
++ }
++
++ private static void verify(String hsLogFile) throws Exception {
++ System.out.println("Verifying " + hsLogFile);
++
++ Properties expectedProperties = new Properties();
++ FileReader reader = new FileReader(hsLogFile
++ + Verifier.PROPERTY_FILE_SUFFIX);
++ expectedProperties.load(reader);
++ reader.close();
++
++ int fullMatchCnt = 0;
++ int suspectCnt = 0;
++ String intrinsicId = expectedProperties.getProperty(
++ Verifier.INTRINSIC_NAME_PROPERTY);
++ String prefix = "<intrinsic id='";
++ String prefixWithId = prefix + intrinsicId + "'";
++
++ try (BufferedReader compLogReader
++ = new BufferedReader(new FileReader(hsLogFile))) {
++ String logLine;
++ while ((logLine = compLogReader.readLine()) != null) {
++ if (logLine.startsWith(prefix)) {
++ if (logLine.startsWith(prefixWithId)) {
++ fullMatchCnt++;
++ } else {
++ suspectCnt++;
++ System.err.println(
++ "WARNING: Other intrinsic detected " + logLine);
++ }
++ }
++ }
++ }
++
++ VerificationStrategy strategy = VerificationStrategy.valueOf(
++ System.getProperty("verificationStrategy",
++ Verifier.DEFAULT_STRATEGY));
++ strategy.verify(expectedProperties, fullMatchCnt, suspectCnt);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,103 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package sha.predicate;
++
++import com.oracle.java.testlibrary.Platform;
++import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
++import com.oracle.java.testlibrary.cli.predicate.CPUSpecificPredicate;
++import com.oracle.java.testlibrary.cli.predicate.OrPredicate;
++import sun.hotspot.WhiteBox;
++
++import java.util.function.BooleanSupplier;
++
++/**
++ * Helper class aimed to provide predicates on availability of SHA-related
++ * CPU instructions and intrinsics.
++ */
++public class IntrinsicPredicates {
++ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
++ private static final long TIERED_MAX_LEVEL = 4L;
++ /**
++ * Boolean supplier that check if any method could be compiled by C2.
++ * Method potentially could be compiled by C2 if Server VM is used and
++ * either tiered compilation is disabled or TIERED_MAX_LEVEL tier is
++ * reachable.
++ *
++ * Please don't place this definition after SHA*_INTRINSICS_AVAILABLE
++ * definitions. Otherwise its value will be {@code null} at the time when
++ * all dependent fields will be initialized.
++ */
++ private static final BooleanSupplier COMPILABLE_BY_C2 = () -> {
++ boolean isTiered = IntrinsicPredicates.WHITE_BOX.getBooleanVMFlag(
++ "TieredCompilation");
++ long tieredMaxLevel = IntrinsicPredicates.WHITE_BOX.getIntxVMFlag(
++ "TieredStopAtLevel");
++ boolean maxLevelIsReachable = (tieredMaxLevel
++ == IntrinsicPredicates.TIERED_MAX_LEVEL);
++ return Platform.isServer() && (!isTiered || maxLevelIsReachable);
++ };
++
++ public static final BooleanSupplier SHA1_INSTRUCTION_AVAILABLE
++ = new CPUSpecificPredicate("sparc.*", new String[] { "sha1" },
++ null);
++
++ public static final BooleanSupplier SHA256_INSTRUCTION_AVAILABLE
++ = new CPUSpecificPredicate("sparc.*", new String[] { "sha256" },
++ null);
++
++ public static final BooleanSupplier SHA512_INSTRUCTION_AVAILABLE
++ = new CPUSpecificPredicate("sparc.*", new String[] { "sha512" },
++ null);
++
++ public static final BooleanSupplier ANY_SHA_INSTRUCTION_AVAILABLE
++ = new OrPredicate(IntrinsicPredicates.SHA1_INSTRUCTION_AVAILABLE,
++ new OrPredicate(
++ IntrinsicPredicates.SHA256_INSTRUCTION_AVAILABLE,
++ IntrinsicPredicates.SHA512_INSTRUCTION_AVAILABLE));
++
++ public static final BooleanSupplier SHA1_INTRINSICS_AVAILABLE
++ = new AndPredicate(new AndPredicate(
++ IntrinsicPredicates.SHA1_INSTRUCTION_AVAILABLE,
++ IntrinsicPredicates.COMPILABLE_BY_C2),
++ IntrinsicPredicates.booleanOptionValue("UseSHA1Intrinsics"));
++
++ public static final BooleanSupplier SHA256_INTRINSICS_AVAILABLE
++ = new AndPredicate(new AndPredicate(
++ IntrinsicPredicates.SHA256_INSTRUCTION_AVAILABLE,
++ IntrinsicPredicates.COMPILABLE_BY_C2),
++ IntrinsicPredicates.booleanOptionValue("UseSHA256Intrinsics"));
++
++ public static final BooleanSupplier SHA512_INTRINSICS_AVAILABLE
++ = new AndPredicate(new AndPredicate(
++ IntrinsicPredicates.SHA512_INSTRUCTION_AVAILABLE,
++ IntrinsicPredicates.COMPILABLE_BY_C2),
++ IntrinsicPredicates.booleanOptionValue("UseSHA512Intrinsics"));
++
++ private static BooleanSupplier booleanOptionValue(String option) {
++ return () -> IntrinsicPredicates.WHITE_BOX.getBooleanVMFlag(option);
++ }
++
++ private IntrinsicPredicates() {
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/uncommontrap/TestDeoptOOM.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,426 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 6898462
++ * @summary failed reallocations of scalar replaced objects during deoptimization causes crash
++ * @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=exclude,TestDeoptOOM::main -XX:CompileCommand=exclude,TestDeoptOOM::m9_1 -Xmx128M TestDeoptOOM
++ *
++ */
++
++public class TestDeoptOOM {
++
++ long f1;
++ long f2;
++ long f3;
++ long f4;
++ long f5;
++
++ static class LinkedList {
++ LinkedList l;
++ long[] array;
++ LinkedList(LinkedList l, int size) {
++ array = new long[size];
++ this.l = l;
++ }
++ }
++
++ static LinkedList ll;
++
++ static void consume_all_memory() {
++ int size = 128 * 1024 * 1024;
++ while(size > 0) {
++ try {
++ while(true) {
++ ll = new LinkedList(ll, size);
++ }
++ } catch(OutOfMemoryError oom) {
++ }
++ size = size / 2;
++ }
++ }
++
++ static void free_memory() {
++ ll = null;
++ }
++
++ static TestDeoptOOM m1(boolean deopt) {
++ try {
++ TestDeoptOOM tdoom = new TestDeoptOOM();
++ if (deopt) {
++ return tdoom;
++ }
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in m1");
++ }
++ return null;
++ }
++
++ static TestDeoptOOM m2_1(boolean deopt) {
++ try {
++ TestDeoptOOM tdoom = new TestDeoptOOM();
++ if (deopt) {
++ return tdoom;
++ }
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in m2_1");
++ }
++ return null;
++ }
++
++ static TestDeoptOOM m2(boolean deopt) {
++ try {
++ return m2_1(deopt);
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in m2");
++ }
++ return null;
++ }
++
++ static TestDeoptOOM m3_3(boolean deopt) {
++ try {
++ TestDeoptOOM tdoom = new TestDeoptOOM();
++ if (deopt) {
++ return tdoom;
++ }
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in m3_3");
++ }
++ return null;
++ }
++
++ static boolean m3_2(boolean deopt) {
++ try {
++ return m3_3(deopt) != null;
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in m3_2");
++ }
++ return false;
++ }
++
++ static TestDeoptOOM m3_1(boolean deopt) {
++ try {
++ TestDeoptOOM tdoom = new TestDeoptOOM();
++ if (m3_2(deopt)) {
++ return tdoom;
++ }
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in m3_1");
++ }
++ return null;
++ }
++
++ static TestDeoptOOM m3(boolean deopt) {
++ try {
++ return m3_1(deopt);
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in m3");
++ }
++ return null;
++ }
++
++ static TestDeoptOOM m4(boolean deopt) {
++ try {
++ TestDeoptOOM tdoom = new TestDeoptOOM();
++ if (deopt) {
++ tdoom.f1 = 1l;
++ tdoom.f2 = 2l;
++ tdoom.f3 = 3l;
++ return tdoom;
++ }
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in m4");
++ }
++ return null;
++ }
++
++ static TestDeoptOOM m5(boolean deopt) {
++ try {
++ TestDeoptOOM tdoom = new TestDeoptOOM();
++ synchronized(tdoom) {
++ if (deopt) {
++ return tdoom;
++ }
++ }
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in m5");
++ }
++ return null;
++ }
++
++ synchronized TestDeoptOOM m6_1(boolean deopt) {
++ if (deopt) {
++ return this;
++ }
++ return null;
++ }
++
++ static TestDeoptOOM m6(boolean deopt) {
++ try {
++ TestDeoptOOM tdoom = new TestDeoptOOM();
++ return tdoom.m6_1(deopt);
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in m6");
++ }
++ return null;
++ }
++
++ static TestDeoptOOM m7_1(boolean deopt, Object lock) {
++ try {
++ synchronized(lock) {
++ TestDeoptOOM tdoom = new TestDeoptOOM();
++ if (deopt) {
++ return tdoom;
++ }
++ }
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in m7_1");
++ }
++ return null;
++ }
++
++ static TestDeoptOOM m7(boolean deopt, Object lock) {
++ try {
++ return m7_1(deopt, lock);
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in m7");
++ }
++ return null;
++ }
++
++ static class A {
++ long f1;
++ long f2;
++ long f3;
++ long f4;
++ long f5;
++ }
++
++ static class B {
++ long f1;
++ long f2;
++ long f3;
++ long f4;
++ long f5;
++
++ A a;
++ }
++
++ static B m8(boolean deopt) {
++ try {
++ A a = new A();
++ B b = new B();
++ b.a = a;
++ if (deopt) {
++ return b;
++ }
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in m8");
++ }
++ return null;
++ }
++
++ static void m9_1(int i) {
++ if (i > 90000) {
++ consume_all_memory();
++ }
++ }
++
++ static TestDeoptOOM m9() {
++ try {
++ for (int i = 0; i < 100000; i++) {
++ TestDeoptOOM tdoom = new TestDeoptOOM();
++ m9_1(i);
++ if (i > 90000) {
++ return tdoom;
++ }
++ }
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in m1");
++ }
++ return null;
++ }
++
++ public static void main(String[] args) {
++ for (int i = 0; i < 20000; i++) {
++ m1(false);
++ }
++
++ consume_all_memory();
++
++ try {
++ m1(true);
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in main " + oom.getMessage());
++ }
++
++ free_memory();
++
++ for (int i = 0; i < 20000; i++) {
++ m2(false);
++ }
++
++ consume_all_memory();
++
++ try {
++ m2(true);
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in main");
++ }
++
++ free_memory();
++
++ for (int i = 0; i < 20000; i++) {
++ m3(false);
++ }
++
++ consume_all_memory();
++
++ try {
++ m3(true);
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in main");
++ }
++
++ free_memory();
++
++ for (int i = 0; i < 20000; i++) {
++ m4(false);
++ }
++
++ consume_all_memory();
++
++ try {
++ m4(true);
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in main");
++ }
++
++ free_memory();
++
++ for (int i = 0; i < 20000; i++) {
++ m5(false);
++ }
++
++ consume_all_memory();
++
++ try {
++ m5(true);
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in main");
++ }
++
++ free_memory();
++
++ for (int i = 0; i < 20000; i++) {
++ m6(false);
++ }
++
++ consume_all_memory();
++
++ try {
++ m6(true);
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in main");
++ }
++
++ free_memory();
++
++ final Object lock = new Object();
++
++ for (int i = 0; i < 20000; i++) {
++ m7(false, lock);
++ }
++
++ consume_all_memory();
++
++ try {
++ m7(true, lock);
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in main");
++ }
++
++ free_memory();
++
++ Thread thread = new Thread() {
++ public void run() {
++ System.out.println("Acquiring lock");
++ synchronized(lock) {
++ System.out.println("Lock acquired");
++ }
++ System.out.println("Lock released");
++ }
++ };
++ thread.start();
++ try {
++ thread.join();
++ } catch(InterruptedException ie) {
++ }
++
++ for (int i = 0; i < 20000; i++) {
++ m8(false);
++ }
++
++ consume_all_memory();
++
++ try {
++ m8(true);
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in main");
++ }
++
++ free_memory();
++
++ try {
++ m9();
++ } catch(OutOfMemoryError oom) {
++ free_memory();
++ System.out.println("OOM caught in main");
++ }
++
++ free_memory();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/uncommontrap/TraceDeoptimizationNoRealloc.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8067144
++ * @summary -XX:+TraceDeoptimization tries to print realloc'ed objects even when there are none
++ * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:+IgnoreUnrecognizedVMOptions -XX:+TraceDeoptimization TraceDeoptimizationNoRealloc
++ *
++ */
++
++public class TraceDeoptimizationNoRealloc {
++
++ static void m(boolean some_condition) {
++ if (some_condition) {
++ return;
++ }
++ }
++
++
++ static public void main(String[] args) {
++ for (int i = 0; i < 20000; i++) {
++ m(false);
++ }
++ m(true);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/unsafe/UnsafeRaw.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,140 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8058744
++ * @summary Invalid pattern-matching of address computations in raw unsafe
++ * @library /testlibrary
++ * @run main/othervm -Xbatch UnsafeRaw
++ */
++
++import com.oracle.java.testlibrary.Utils;
++import java.util.Random;
++
++public class UnsafeRaw {
++ public static class Tests {
++ public static int int_index(sun.misc.Unsafe unsafe, long base, int index) throws Exception {
++ return unsafe.getInt(base + (index << 2));
++ }
++ public static int long_index(sun.misc.Unsafe unsafe, long base, long index) throws Exception {
++ return unsafe.getInt(base + (index << 2));
++ }
++ public static int int_index_back_ashift(sun.misc.Unsafe unsafe, long base, int index) throws Exception {
++ return unsafe.getInt(base + (index >> 2));
++ }
++ public static int int_index_back_lshift(sun.misc.Unsafe unsafe, long base, int index) throws Exception {
++ return unsafe.getInt(base + (index >>> 2));
++ }
++ public static int long_index_back_ashift(sun.misc.Unsafe unsafe, long base, long index) throws Exception {
++ return unsafe.getInt(base + (index >> 2));
++ }
++ public static int long_index_back_lshift(sun.misc.Unsafe unsafe, long base, long index) throws Exception {
++ return unsafe.getInt(base + (index >>> 2));
++ }
++ public static int int_const_12345678_index(sun.misc.Unsafe unsafe, long base) throws Exception {
++ int idx4 = 0x12345678;
++ return unsafe.getInt(base + idx4);
++ }
++ public static int long_const_1234567890abcdef_index(sun.misc.Unsafe unsafe, long base) throws Exception {
++ long idx5 = 0x1234567890abcdefL;
++ return unsafe.getInt(base + idx5);
++ }
++ public static int int_index_mul(sun.misc.Unsafe unsafe, long base, int index) throws Exception {
++ return unsafe.getInt(base + (index * 4));
++ }
++ public static int long_index_mul(sun.misc.Unsafe unsafe, long base, long index) throws Exception {
++ return unsafe.getInt(base + (index * 4));
++ }
++ public static int int_index_mul_scale_16(sun.misc.Unsafe unsafe, long base, int index) throws Exception {
++ return unsafe.getInt(base + (index * 16));
++ }
++ public static int long_index_mul_scale_16(sun.misc.Unsafe unsafe, long base, long index) throws Exception {
++ return unsafe.getInt(base + (index * 16));
++ }
++ }
++
++ public static void main(String[] args) throws Exception {
++ sun.misc.Unsafe unsafe = Utils.getUnsafe();
++ final int array_size = 128;
++ final int element_size = 4;
++ final int magic = 0x12345678;
++
++ Random rnd = new Random();
++
++ long array = unsafe.allocateMemory(array_size * element_size); // 128 ints
++ long addr = array + array_size * element_size / 2; // something in the middle to work with
++ unsafe.putInt(addr, magic);
++ for (int j = 0; j < 100000; j++) {
++ if (Tests.int_index(unsafe, addr, 0) != magic) throw new Exception();
++ if (Tests.long_index(unsafe, addr, 0) != magic) throw new Exception();
++ if (Tests.int_index_mul(unsafe, addr, 0) != magic) throw new Exception();
++ if (Tests.long_index_mul(unsafe, addr, 0) != magic) throw new Exception();
++ {
++ long idx1 = rnd.nextLong();
++ long addr1 = addr - (idx1 << 2);
++ if (Tests.long_index(unsafe, addr1, idx1) != magic) throw new Exception();
++ }
++ {
++ long idx2 = rnd.nextLong();
++ long addr2 = addr - (idx2 >> 2);
++ if (Tests.long_index_back_ashift(unsafe, addr2, idx2) != magic) throw new Exception();
++ }
++ {
++ long idx3 = rnd.nextLong();
++ long addr3 = addr - (idx3 >>> 2);
++ if (Tests.long_index_back_lshift(unsafe, addr3, idx3) != magic) throw new Exception();
++ }
++ {
++ long idx4 = 0x12345678;
++ long addr4 = addr - idx4;
++ if (Tests.int_const_12345678_index(unsafe, addr4) != magic) throw new Exception();
++ }
++ {
++ long idx5 = 0x1234567890abcdefL;
++ long addr5 = addr - idx5;
++ if (Tests.long_const_1234567890abcdef_index(unsafe, addr5) != magic) throw new Exception();
++ }
++ {
++ int idx6 = rnd.nextInt();
++ long addr6 = addr - (idx6 >> 2);
++ if (Tests.int_index_back_ashift(unsafe, addr6, idx6) != magic) throw new Exception();
++ }
++ {
++ int idx7 = rnd.nextInt();
++ long addr7 = addr - (idx7 >>> 2);
++ if (Tests.int_index_back_lshift(unsafe, addr7, idx7) != magic) throw new Exception();
++ }
++ {
++ int idx8 = rnd.nextInt();
++ long addr8 = addr - (idx8 * 16);
++ if (Tests.int_index_mul_scale_16(unsafe, addr8, idx8) != magic) throw new Exception();
++ }
++ {
++ long idx9 = rnd.nextLong();
++ long addr9 = addr - (idx9 * 16);
++ if (Tests.long_index_mul_scale_16(unsafe, addr9, idx9) != magic) throw new Exception();
++ }
++ }
++ }
++}
+--- ./hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -72,9 +72,9 @@
+ /** Flag for verbose output, true if {@code -Dverbose} specified */
+ protected static final boolean IS_VERBOSE
+ = System.getProperty("verbose") != null;
+- /** count of invocation to triger compilation */
++ /** invocation count to trigger compilation */
+ protected static final int THRESHOLD;
+- /** count of invocation to triger OSR compilation */
++ /** invocation count to trigger OSR compilation */
+ protected static final long BACKEDGE_THRESHOLD;
+ /** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */
+ protected static final String MODE = System.getProperty("java.vm.info");
+@@ -206,7 +206,6 @@
+ * is compiled, or if {@linkplain #method} has zero
+ * compilation level.
+ */
+-
+ protected final void checkNotCompiled(int compLevel) {
+ if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
+ throw new RuntimeException(method + " must not be in queue");
+@@ -227,20 +226,30 @@
+ * compilation level.
+ */
+ protected final void checkNotCompiled() {
++ checkNotCompiled(true);
++ checkNotCompiled(false);
++ }
++
++ /**
++ * Checks, that {@linkplain #method} is not (OSR-)compiled.
++ *
++ * @param isOsr Check for OSR compilation if true
++ * @throws RuntimeException if {@linkplain #method} is in compiler queue or
++ * is compiled, or if {@linkplain #method} has zero
++ * compilation level.
++ */
++ protected final void checkNotCompiled(boolean isOsr) {
++ waitBackgroundCompilation();
+ if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
+ throw new RuntimeException(method + " must not be in queue");
+ }
+- if (WHITE_BOX.isMethodCompiled(method, false)) {
+- throw new RuntimeException(method + " must be not compiled");
++ if (WHITE_BOX.isMethodCompiled(method, isOsr)) {
++ throw new RuntimeException(method + " must not be " +
++ (isOsr ? "osr_" : "") + "compiled");
+ }
+- if (WHITE_BOX.getMethodCompilationLevel(method, false) != 0) {
+- throw new RuntimeException(method + " comp_level must be == 0");
+- }
+- if (WHITE_BOX.isMethodCompiled(method, true)) {
+- throw new RuntimeException(method + " must be not osr_compiled");
+- }
+- if (WHITE_BOX.getMethodCompilationLevel(method, true) != 0) {
+- throw new RuntimeException(method + " osr_comp_level must be == 0");
++ if (WHITE_BOX.getMethodCompilationLevel(method, isOsr) != 0) {
++ throw new RuntimeException(method + (isOsr ? " osr_" : " ") +
++ "comp_level must be == 0");
+ }
+ }
+
+@@ -306,12 +315,21 @@
+ * Waits for completion of background compilation of {@linkplain #method}.
+ */
+ protected final void waitBackgroundCompilation() {
++ waitBackgroundCompilation(method);
++ }
++
++ /**
++ * Waits for completion of background compilation of the given executable.
++ *
++ * @param executable Executable
++ */
++ protected static final void waitBackgroundCompilation(Executable executable) {
+ if (!BACKGROUND_COMPILATION) {
+ return;
+ }
+ final Object obj = new Object();
+ for (int i = 0; i < 10
+- && WHITE_BOX.isMethodQueuedForCompilation(method); ++i) {
++ && WHITE_BOX.isMethodQueuedForCompilation(executable); ++i) {
+ synchronized (obj) {
+ try {
+ obj.wait(1000);
+@@ -425,14 +443,14 @@
+ /** constructor test case */
+ CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false),
+ /** method test case */
+- METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false),
++ METHOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false),
+ /** static method test case */
+ STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false),
+ /** OSR constructor test case */
+ OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR,
+ Helper.OSR_CONSTRUCTOR_CALLABLE, true),
+ /** OSR method test case */
+- OSR_METOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true),
++ OSR_METHOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true),
+ /** OSR static method test case */
+ OSR_STATIC_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true);
+
+@@ -494,7 +512,7 @@
+ = new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+- return new Helper(null).hashCode();
++ return new Helper(null, CompilerWhiteBoxTest.BACKEDGE_THRESHOLD).hashCode();
+ }
+ };
+
+@@ -504,7 +522,7 @@
+
+ @Override
+ public Integer call() throws Exception {
+- return helper.osrMethod();
++ return helper.osrMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
+ }
+ };
+
+@@ -512,7 +530,7 @@
+ = new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+- return osrStaticMethod();
++ return osrStaticMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
+ }
+ };
+
+@@ -532,25 +550,24 @@
+ }
+ try {
+ OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor(
+- Object.class);
++ Object.class, long.class);
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw new RuntimeException(
+- "exception on getting method Helper.<init>(Object)", e);
++ "exception on getting method Helper.<init>(Object, long)", e);
+ }
+ METHOD = getMethod("method");
+ STATIC = getMethod("staticMethod");
+- OSR_METHOD = getMethod("osrMethod");
+- OSR_STATIC = getMethod("osrStaticMethod");
++ OSR_METHOD = getMethod("osrMethod", long.class);
++ OSR_STATIC = getMethod("osrStaticMethod", long.class);
+ }
+
+- private static Method getMethod(String name) {
++ private static Method getMethod(String name, Class<?>... parameterTypes) {
+ try {
+- return Helper.class.getDeclaredMethod(name);
++ return Helper.class.getDeclaredMethod(name, parameterTypes);
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw new RuntimeException(
+ "exception on getting method Helper." + name, e);
+ }
+-
+ }
+
+ private static int staticMethod() {
+@@ -561,17 +578,84 @@
+ return 42;
+ }
+
+- private static int osrStaticMethod() {
++ /**
++ * Deoptimizes all non-osr versions of the given executable after
++ * compilation finished.
++ *
++ * @param e Executable
++ * @throws Exception
++ */
++ private static void waitAndDeoptimize(Executable e) {
++ CompilerWhiteBoxTest.waitBackgroundCompilation(e);
++ if (WhiteBox.getWhiteBox().isMethodQueuedForCompilation(e)) {
++ throw new RuntimeException(e + " must not be in queue");
++ }
++ // Deoptimize non-osr versions of executable
++ WhiteBox.getWhiteBox().deoptimizeMethod(e, false);
++ }
++
++ /**
++ * Executes the method multiple times to make sure we have
++ * enough profiling information before triggering an OSR
++ * compilation. Otherwise the C2 compiler may add uncommon traps.
++ *
++ * @param m Method to be executed
++ * @return Number of times the method was executed
++ * @throws Exception
++ */
++ private static int warmup(Method m) throws Exception {
++ waitAndDeoptimize(m);
++ Helper helper = new Helper();
+ int result = 0;
+- for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) {
++ for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) {
++ result += (int)m.invoke(helper, 1);
++ }
++ // Wait to make sure OSR compilation is not blocked by
++ // non-OSR compilation in the compile queue
++ CompilerWhiteBoxTest.waitBackgroundCompilation(m);
++ return result;
++ }
++
++ /**
++ * Executes the constructor multiple times to make sure we
++ * have enough profiling information before triggering an OSR
++ * compilation. Otherwise the C2 compiler may add uncommon traps.
++ *
++ * @param c Constructor to be executed
++ * @return Number of times the constructor was executed
++ * @throws Exception
++ */
++ private static int warmup(Constructor c) throws Exception {
++ waitAndDeoptimize(c);
++ int result = 0;
++ for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) {
++ result += c.newInstance(null, 1).hashCode();
++ }
++ // Wait to make sure OSR compilation is not blocked by
++ // non-OSR compilation in the compile queue
++ CompilerWhiteBoxTest.waitBackgroundCompilation(c);
++ return result;
++ }
++
++ private static int osrStaticMethod(long limit) throws Exception {
++ int result = 0;
++ if (limit != 1) {
++ result = warmup(OSR_STATIC);
++ }
++ // Trigger osr compilation
++ for (long i = 0; i < limit; ++i) {
+ result += staticMethod();
+ }
+ return result;
+ }
+
+- private int osrMethod() {
++ private int osrMethod(long limit) throws Exception {
+ int result = 0;
+- for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) {
++ if (limit != 1) {
++ result = warmup(OSR_METHOD);
++ }
++ // Trigger osr compilation
++ for (long i = 0; i < limit; ++i) {
+ result += method();
+ }
+ return result;
+@@ -585,9 +669,13 @@
+ }
+
+ // for OSR constructor test case
+- private Helper(Object o) {
++ private Helper(Object o, long limit) throws Exception {
+ int result = 0;
+- for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) {
++ if (limit != 1) {
++ result = warmup(OSR_CONSTRUCTOR);
++ }
++ // Trigger osr compilation
++ for (long i = 0; i < limit; ++i) {
+ result += method();
+ }
+ x = result;
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/compiler/whitebox/DeoptimizeMultipleOSRTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,95 @@
++/*
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import sun.hotspot.WhiteBox;
++import java.lang.reflect.Executable;
++import java.lang.reflect.Method;
++
++/*
++ * @test DeoptimizeMultipleOSRTest
++ * @bug 8061817
++ * @library /testlibrary /testlibrary/whitebox
++ * @build DeoptimizeMultipleOSRTest
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,DeoptimizeMultipleOSRTest::triggerOSR DeoptimizeMultipleOSRTest
++ * @summary testing of WB::deoptimizeMethod()
++ */
++public class DeoptimizeMultipleOSRTest {
++ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
++ private static final long BACKEDGE_THRESHOLD = 150000;
++ private Method method;
++ private int counter = 0;
++
++ public static void main(String[] args) throws Exception {
++ DeoptimizeMultipleOSRTest test = new DeoptimizeMultipleOSRTest();
++ test.test();
++ }
++
++ /**
++ * Triggers two different OSR compilations for the same method and
++ * checks if WhiteBox.deoptimizeMethod() deoptimizes both.
++ *
++ * @throws Exception
++ */
++ public void test() throws Exception {
++ method = DeoptimizeMultipleOSRTest.class.getDeclaredMethod("triggerOSR", boolean.class, long.class);
++ // Trigger two OSR compiled versions
++ triggerOSR(true, BACKEDGE_THRESHOLD);
++ triggerOSR(false, BACKEDGE_THRESHOLD);
++ // Wait for compilation
++ CompilerWhiteBoxTest.waitBackgroundCompilation(method);
++ // Deoptimize
++ WHITE_BOX.deoptimizeMethod(method, true);
++ if (WHITE_BOX.isMethodCompiled(method, true)) {
++ throw new AssertionError("Not all OSR compiled versions were deoptimized");
++ }
++ }
++
++ /**
++ * Triggers OSR compilations by executing loops.
++ *
++ * @param first Determines which loop to execute
++ * @param limit The number of loop iterations
++ */
++ public void triggerOSR(boolean first, long limit) {
++ if (limit != 1) {
++ // Warmup method to avoid uncommon traps
++ for (int i = 0; i < limit; ++i) {
++ triggerOSR(first, 1);
++ }
++ CompilerWhiteBoxTest.waitBackgroundCompilation(method);
++ }
++ if (first) {
++ // Trigger OSR compilation 1
++ for (int i = 0; i < limit; ++i) {
++ counter++;
++ }
++ } else {
++ // Trigger OSR compilation 2
++ for (int i = 0; i < limit; ++i) {
++ counter++;
++ }
++ }
++ }
++}
+--- ./hotspot/test/compiler/whitebox/IsMethodCompilableTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/whitebox/IsMethodCompilableTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -28,7 +28,7 @@
+ * @build IsMethodCompilableTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller com.oracle.java.testlibrary.Platform
+- * @run main/othervm/timeout=2400 -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:PerMethodRecompilationCutoff=3 -XX:CompileCommand=compileonly,SimpleTestCase$Helper::* IsMethodCompilableTest
++ * @run main/othervm/timeout=2400 -Xbootclasspath/a:. -Xmixed -XX:-TieredCompilation -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:PerMethodRecompilationCutoff=3 -XX:CompileCommand=compileonly,SimpleTestCase$Helper::* IsMethodCompilableTest
+ * @summary testing of WB::isMethodCompilable()
+ * @author igor.ignatyev@oracle.com
+ */
+--- ./hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -131,14 +131,15 @@
+ throw new RuntimeException(method
+ + " is not compilable after clearMethodState()");
+ }
+-
++ // Make method not (OSR-)compilable (depending on testCase.isOsr())
+ makeNotCompilable();
+ if (isCompilable()) {
+ throw new RuntimeException(method + " must be not compilable");
+ }
+-
++ // Try to (OSR-)compile method
+ compile();
+- checkNotCompiled();
++ // Method should not be (OSR-)compiled
++ checkNotCompiled(testCase.isOsr());
+ if (isCompilable()) {
+ throw new RuntimeException(method + " must be not compilable");
+ }
+--- ./hotspot/test/gc/arguments/TestDynMaxHeapFreeRatio.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/gc/arguments/TestDynMaxHeapFreeRatio.java Wed Feb 04 12:14:39 2015 -0800
+@@ -21,6 +21,11 @@
+ * questions.
+ */
+
++import static com.oracle.java.testlibrary.Asserts.assertEQ;
++import static com.oracle.java.testlibrary.Asserts.assertFalse;
++import static com.oracle.java.testlibrary.Asserts.assertTrue;
++import com.oracle.java.testlibrary.DynamicVMOption;
++
+ /**
+ * @test TestDynMaxHeapFreeRatio
+ * @bug 8028391
+@@ -33,32 +38,45 @@
+ * @run main/othervm -XX:MinHeapFreeRatio=51 -XX:MaxHeapFreeRatio=52 TestDynMaxHeapFreeRatio
+ * @run main/othervm -XX:MinHeapFreeRatio=75 -XX:MaxHeapFreeRatio=100 TestDynMaxHeapFreeRatio
+ */
+-import com.oracle.java.testlibrary.TestDynamicVMOption;
+-import com.oracle.java.testlibrary.DynamicVMOptionChecker;
+-
+-public class TestDynMaxHeapFreeRatio extends TestDynamicVMOption {
+-
+- public static final String MinFreeRatioFlagName = "MinHeapFreeRatio";
+- public static final String MaxFreeRatioFlagName = "MaxHeapFreeRatio";
+-
+- public TestDynMaxHeapFreeRatio() {
+- super(MaxFreeRatioFlagName);
+- }
+-
+- public void test() {
+-
+- int minHeapFreeValue = DynamicVMOptionChecker.getIntValue(MinFreeRatioFlagName);
+- System.out.println(MinFreeRatioFlagName + " = " + minHeapFreeValue);
+-
+- testPercentageValues();
+-
+- checkInvalidValue(Integer.toString(minHeapFreeValue - 1));
+- checkValidValue(Integer.toString(minHeapFreeValue));
+- checkValidValue("100");
+- }
++public class TestDynMaxHeapFreeRatio {
+
+ public static void main(String args[]) throws Exception {
+- new TestDynMaxHeapFreeRatio().test();
++
++ // low boundary value
++ int minValue = DynamicVMOption.getInt("MinHeapFreeRatio");
++ System.out.println("MinHeapFreeRatio= " + minValue);
++
++ String badValues[] = {
++ null,
++ "",
++ "not a number",
++ "8.5", "-0.01",
++ Integer.toString(Integer.MIN_VALUE),
++ Integer.toString(Integer.MAX_VALUE),
++ Integer.toString(minValue - 1),
++ "-1024", "-1", "101", "1997"
++ };
++
++ String goodValues[] = {
++ Integer.toString(minValue),
++ Integer.toString(minValue + 1),
++ Integer.toString((minValue + 100) / 2),
++ "99", "100"
++ };
++
++ DynamicVMOption option = new DynamicVMOption("MaxHeapFreeRatio");
++
++ assertTrue(option.isWriteable(), "Option " + option.name
++ + " is expected to be writable");
++
++ for (String v : badValues) {
++ assertFalse(option.isValidValue(v),
++ "'" + v + "' is expected to be illegal for flag " + option.name);
++ }
++ for (String v : goodValues) {
++ option.setValue(v);
++ String newValue = option.getValue();
++ assertEQ(v, newValue);
++ }
+ }
+-
+ }
+--- ./hotspot/test/gc/arguments/TestDynMinHeapFreeRatio.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/gc/arguments/TestDynMinHeapFreeRatio.java Wed Feb 04 12:14:39 2015 -0800
+@@ -33,30 +33,52 @@
+ * @run main/othervm -XX:MinHeapFreeRatio=51 -XX:MaxHeapFreeRatio=52 TestDynMinHeapFreeRatio
+ * @run main/othervm -XX:MinHeapFreeRatio=75 -XX:MaxHeapFreeRatio=100 TestDynMinHeapFreeRatio
+ */
+-import com.oracle.java.testlibrary.TestDynamicVMOption;
+-import com.oracle.java.testlibrary.DynamicVMOptionChecker;
++import static com.oracle.java.testlibrary.Asserts.assertEQ;
++import static com.oracle.java.testlibrary.Asserts.assertFalse;
++import static com.oracle.java.testlibrary.Asserts.assertTrue;
++import com.oracle.java.testlibrary.DynamicVMOption;
+
+-public class TestDynMinHeapFreeRatio extends TestDynamicVMOption {
+-
+- public static final String MinFreeRatioFlagName = "MinHeapFreeRatio";
+- public static final String MaxFreeRatioFlagName = "MaxHeapFreeRatio";
+-
+- public TestDynMinHeapFreeRatio() {
+- super(MinFreeRatioFlagName);
+- }
+-
+- public void test() {
+- int maxHeapFreeValue = DynamicVMOptionChecker.getIntValue(MaxFreeRatioFlagName);
+- System.out.println(MaxFreeRatioFlagName + " = " + maxHeapFreeValue);
+-
+- testPercentageValues();
+-
+- checkInvalidValue(Integer.toString(maxHeapFreeValue + 1));
+- checkValidValue(Integer.toString(maxHeapFreeValue));
+- checkValidValue("0");
+- }
++public class TestDynMinHeapFreeRatio {
+
+ public static void main(String args[]) throws Exception {
+- new TestDynMinHeapFreeRatio().test();
++
++ // high boundary value
++ int maxValue = DynamicVMOption.getInt("MaxHeapFreeRatio");
++ System.out.println("MaxHeapFreeRatio= " + maxValue);
++
++ String badValues[] = {
++ null,
++ "",
++ "not a number",
++ "8.5", "-0.01",
++ Integer.toString(Integer.MIN_VALUE),
++ Integer.toString(Integer.MAX_VALUE),
++ Integer.toString(maxValue + 1),
++ "-1024", "-1", "101", "1997"
++ };
++
++ String goodValues[] = {
++ Integer.toString(maxValue),
++ Integer.toString(maxValue - 1),
++ Integer.toString(maxValue / 2),
++ "0", "1"
++ };
++
++ // option under test
++ DynamicVMOption option = new DynamicVMOption("MinHeapFreeRatio");
++
++ assertTrue(option.isWriteable(), "Option " + option.name
++ + " is expected to be writable");
++
++ for (String v : badValues) {
++ assertFalse(option.isValidValue(v),
++ "'" + v + "' is expected to be illegal for flag " + option.name);
++ }
++
++ for (String v : goodValues) {
++ option.setValue(v);
++ String newValue = option.getValue();
++ assertEQ(v, newValue);
++ }
+ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/arguments/TestG1ConcRefinementThreads.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,97 @@
++/*
++* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++*
++* This code is free software; you can redistribute it and/or modify it
++* under the terms of the GNU General Public License version 2 only, as
++* published by the Free Software Foundation.
++*
++* This code is distributed in the hope that it will be useful, but WITHOUT
++* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++* version 2 for more details (a copy is included in the LICENSE file that
++* accompanied this code).
++*
++* You should have received a copy of the GNU General Public License version
++* 2 along with this work; if not, write to the Free Software Foundation,
++* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++*
++* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++* or visit www.oracle.com if you need additional information or have any
++* questions.
++*/
++
++/*
++ * @test TestG1ConcRefinementThreads
++ * @key gc
++ * @bug 8047976
++ * @summary Tests argument processing for G1ConcRefinementThreads
++ * @library /testlibrary
++ */
++
++import com.oracle.java.testlibrary.*;
++import java.util.*;
++import java.util.regex.*;
++
++public class TestG1ConcRefinementThreads {
++
++ static final int AUTO_SELECT_THREADS_COUNT = 0;
++ static final int PASSED_THREADS_COUNT = 11;
++
++ public static void main(String args[]) throws Exception {
++ // default case
++ runG1ConcRefinementThreadsTest(
++ new String[]{}, // automatically selected
++ AUTO_SELECT_THREADS_COUNT /* use default setting */);
++
++ // zero setting case
++ runG1ConcRefinementThreadsTest(
++ new String[]{"-XX:G1ConcRefinementThreads=0"}, // automatically selected
++ AUTO_SELECT_THREADS_COUNT /* set to zero */);
++
++ // non-zero sestting case
++ runG1ConcRefinementThreadsTest(
++ new String[]{"-XX:G1ConcRefinementThreads="+Integer.toString(PASSED_THREADS_COUNT)},
++ PASSED_THREADS_COUNT);
++ }
++
++ private static void runG1ConcRefinementThreadsTest(String[] passedOpts,
++ int expectedValue) throws Exception {
++ List<String> vmOpts = new ArrayList<>();
++ if (passedOpts.length > 0) {
++ Collections.addAll(vmOpts, passedOpts);
++ }
++ Collections.addAll(vmOpts, "-XX:+UseG1GC", "-XX:+PrintFlagsFinal", "-version");
++
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
++ OutputAnalyzer output = new OutputAnalyzer(pb.start());
++
++ output.shouldHaveExitValue(0);
++ String stdout = output.getStdout();
++ checkG1ConcRefinementThreadsConsistency(stdout, expectedValue);
++ }
++
++ private static void checkG1ConcRefinementThreadsConsistency(String output, int expectedValue) {
++ int actualValue = getIntValue("G1ConcRefinementThreads", output);
++
++ if (expectedValue == 0) {
++ // If expectedValue is automatically selected, set it same as ParallelGCThreads.
++ expectedValue = getIntValue("ParallelGCThreads", output);
++ }
++
++ if (expectedValue != actualValue) {
++ throw new RuntimeException(
++ "Actual G1ConcRefinementThreads(" + Integer.toString(actualValue)
++ + ") is not equal to expected value(" + Integer.toString(expectedValue) + ")");
++ }
++ }
++
++ public static int getIntValue(String flag, String where) {
++ Matcher m = Pattern.compile(flag + "\\s+:?=\\s+\\d+").matcher(where);
++ if (!m.find()) {
++ throw new RuntimeException("Could not find value for flag " + flag + " in output string");
++ }
++ String match = m.group();
++ return Integer.parseInt(match.substring(match.lastIndexOf(" ") + 1, match.length()));
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/arguments/TestSurvivorAlignmentInBytesOption.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,107 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import com.oracle.java.testlibrary.ExitCode;
++import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
++
++/**
++ * @test
++ * @bug 8031323
++ * @summary Verify SurvivorAlignmentInBytes option processing.
++ * @library /testlibrary
++ * @requires vm.opt.SurvivorAlignmentInBytes == null
++ * & vm.opt.ObjectAlignmentInBytes == null
++ * & vm.opt.UnlockExperimentalVMOptions == null
++ * & (vm.opt.IgnoreUnrecognizedVMOptions == null
++ * | vm.opt.IgnoreUnrecognizedVMOptions == "false")
++ * @run main TestSurvivorAlignmentInBytesOption
++ */
++public class TestSurvivorAlignmentInBytesOption {
++ public static void main(String args[]) throws Throwable {
++ String optionName = "SurvivorAlignmentInBytes";
++ String unlockExperimentalVMOpts = "UnlockExperimentalVMOptions";
++ String optionIsExperimental
++ = CommandLineOptionTest.getExperimentalOptionErrorMessage(
++ optionName);
++ String valueIsTooSmall= ".*SurvivorAlignmentInBytes=.*must be greater"
++ + " than ObjectAlignmentInBytes.*";
++ String mustBePowerOf2 = ".*SurvivorAlignmentInBytes=.*must be "
++ + "power of 2.*";
++
++ // Verify that without -XX:+UnlockExperimentalVMOptions usage of
++ // SurvivorAlignmentInBytes option will cause JVM startup failure
++ // with the warning message saying that that option is experimental.
++ CommandLineOptionTest.verifyJVMStartup(
++ new String[]{optionIsExperimental}, null, ExitCode.FAIL, false,
++ "-XX:-UnlockExperimentalVMOptions",
++ CommandLineOptionTest.prepareBooleanFlag(
++ unlockExperimentalVMOpts, false),
++ CommandLineOptionTest.prepareNumericFlag(optionName, 64));
++
++ // Verify that with -XX:+UnlockExperimentalVMOptions passed to JVM
++ // usage of SurvivorAlignmentInBytes option won't cause JVM startup
++ // failure.
++ CommandLineOptionTest.verifyJVMStartup(
++ null, new String[]{optionIsExperimental}, ExitCode.OK, false,
++ CommandLineOptionTest.prepareBooleanFlag(
++ unlockExperimentalVMOpts, true),
++ CommandLineOptionTest.prepareNumericFlag(optionName, 64));
++
++ // Verify that if specified SurvivorAlignmentInBytes is lower then
++ // ObjectAlignmentInBytes, then the JVM startup will fail with
++ // appropriate error message.
++ CommandLineOptionTest.verifyJVMStartup(
++ new String[]{valueIsTooSmall}, null, ExitCode.FAIL, false,
++ CommandLineOptionTest.prepareBooleanFlag(
++ unlockExperimentalVMOpts, true),
++ CommandLineOptionTest.prepareNumericFlag(optionName, 2));
++
++ // Verify that if specified SurvivorAlignmentInBytes value is not
++ // a power of 2 then the JVM startup will fail with appropriate error
++ // message.
++ CommandLineOptionTest.verifyJVMStartup(
++ new String[]{mustBePowerOf2}, null, ExitCode.FAIL, false,
++ CommandLineOptionTest.prepareBooleanFlag(
++ unlockExperimentalVMOpts, true),
++ CommandLineOptionTest.prepareNumericFlag(optionName, 127));
++
++ // Verify that if SurvivorAlignmentInBytes has correct value, then
++ // the JVM will be started without errors.
++ CommandLineOptionTest.verifyJVMStartup(
++ null, new String[]{".*SurvivorAlignmentInBytes.*"},
++ ExitCode.OK, false,
++ CommandLineOptionTest.prepareBooleanFlag(
++ unlockExperimentalVMOpts, true),
++ CommandLineOptionTest.prepareNumericFlag(optionName, 128));
++
++ // Verify that we can setup different SurvivorAlignmentInBytes values.
++ for (int alignment = 32; alignment <= 128; alignment *= 2) {
++ CommandLineOptionTest.verifyOptionValue(optionName,
++ Integer.toString(alignment),
++ CommandLineOptionTest.prepareBooleanFlag(
++ unlockExperimentalVMOpts, true),
++ CommandLineOptionTest.prepareNumericFlag(
++ optionName, alignment));
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/class_unloading/TestCMSClassUnloadingEnabledHWM.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,128 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @key gc
++ * @bug 8049831
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestCMSClassUnloadingEnabledHWM
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run driver TestCMSClassUnloadingEnabledHWM
++ * @summary Test that -XX:-CMSClassUnloadingEnabled will trigger a Full GC when more than MetaspaceSize metadata is allocated.
++ */
++
++import com.oracle.java.testlibrary.OutputAnalyzer;
++import com.oracle.java.testlibrary.ProcessTools;
++import java.lang.management.GarbageCollectorMXBean;
++import java.lang.management.ManagementFactory;
++import java.util.ArrayList;
++import java.util.Arrays;
++import sun.hotspot.WhiteBox;
++
++public class TestCMSClassUnloadingEnabledHWM {
++ private static long MetaspaceSize = 32 * 1024 * 1024;
++ private static long YoungGenSize = 32 * 1024 * 1024;
++
++ private static OutputAnalyzer run(boolean enableUnloading) throws Exception {
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
++ "-Xbootclasspath/a:.",
++ "-XX:+UnlockDiagnosticVMOptions",
++ "-XX:+WhiteBoxAPI",
++ "-Xmx128m",
++ "-XX:CMSMaxAbortablePrecleanTime=1",
++ "-XX:CMSWaitDuration=50",
++ "-XX:MetaspaceSize=" + MetaspaceSize,
++ "-Xmn" + YoungGenSize,
++ "-XX:+UseConcMarkSweepGC",
++ "-XX:" + (enableUnloading ? "+" : "-") + "CMSClassUnloadingEnabled",
++ "-XX:+PrintHeapAtGC",
++ "-XX:+PrintGCDetails",
++ "-XX:+PrintGCTimeStamps",
++ TestCMSClassUnloadingEnabledHWM.AllocateBeyondMetaspaceSize.class.getName(),
++ "" + MetaspaceSize);
++ return new OutputAnalyzer(pb.start());
++ }
++
++ public static OutputAnalyzer runWithCMSClassUnloading() throws Exception {
++ return run(true);
++ }
++
++ public static OutputAnalyzer runWithoutCMSClassUnloading() throws Exception {
++ return run(false);
++ }
++
++ public static void testWithoutCMSClassUnloading() throws Exception {
++ // -XX:-CMSClassUnloadingEnabled is used, so we expect a full GC instead of a concurrent cycle.
++ OutputAnalyzer out = runWithoutCMSClassUnloading();
++
++ out.shouldMatch(".*Full GC.*");
++ out.shouldNotMatch(".*CMS Initial Mark.*");
++ }
++
++ public static void testWithCMSClassUnloading() throws Exception {
++ // -XX:+CMSClassUnloadingEnabled is used, so we expect a concurrent cycle instead of a full GC.
++ OutputAnalyzer out = runWithCMSClassUnloading();
++
++ out.shouldMatch(".*CMS Initial Mark.*");
++ out.shouldNotMatch(".*Full GC.*");
++ }
++
++ public static void main(String args[]) throws Exception {
++ testWithCMSClassUnloading();
++ testWithoutCMSClassUnloading();
++ }
++
++ public static class AllocateBeyondMetaspaceSize {
++ public static void main(String [] args) throws Exception {
++ if (args.length != 1) {
++ throw new IllegalArgumentException("Usage: <MetaspaceSize>");
++ }
++
++ WhiteBox wb = WhiteBox.getWhiteBox();
++
++ // Allocate past the MetaspaceSize limit.
++ long metaspaceSize = Long.parseLong(args[0]);
++ long allocationBeyondMetaspaceSize = metaspaceSize * 2;
++ long metaspace = wb.allocateMetaspace(null, allocationBeyondMetaspaceSize);
++
++ // Wait for at least one GC to occur. The caller will parse the log files produced.
++ GarbageCollectorMXBean cmsGCBean = getCMSGCBean();
++ while (cmsGCBean.getCollectionCount() == 0) {
++ Thread.sleep(100);
++ }
++
++ wb.freeMetaspace(null, metaspace, metaspace);
++ }
++
++ private static GarbageCollectorMXBean getCMSGCBean() {
++ for (GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) {
++ if (gcBean.getObjectName().toString().equals("java.lang:type=GarbageCollector,name=ConcurrentMarkSweep")) {
++ return gcBean;
++ }
++ }
++ return null;
++ }
++ }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/class_unloading/TestG1ClassUnloadingHWM.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,122 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @key gc
++ * @bug 8049831
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestG1ClassUnloadingHWM
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run driver TestG1ClassUnloadingHWM
++ * @summary Test that -XX:-ClassUnloadingWithConcurrentMark will trigger a Full GC when more than MetaspaceSize metadata is allocated.
++ */
++
++import com.oracle.java.testlibrary.OutputAnalyzer;
++import com.oracle.java.testlibrary.ProcessTools;
++import java.util.ArrayList;
++import java.util.Arrays;
++import sun.hotspot.WhiteBox;
++
++public class TestG1ClassUnloadingHWM {
++ private static long MetaspaceSize = 32 * 1024 * 1024;
++ private static long YoungGenSize = 32 * 1024 * 1024;
++
++ private static OutputAnalyzer run(boolean enableUnloading) throws Exception {
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
++ "-Xbootclasspath/a:.",
++ "-XX:+UnlockDiagnosticVMOptions",
++ "-XX:+WhiteBoxAPI",
++ "-XX:MetaspaceSize=" + MetaspaceSize,
++ "-Xmn" + YoungGenSize,
++ "-XX:+UseG1GC",
++ "-XX:" + (enableUnloading ? "+" : "-") + "ClassUnloadingWithConcurrentMark",
++ "-XX:+PrintHeapAtGC",
++ "-XX:+PrintGCDetails",
++ TestG1ClassUnloadingHWM.AllocateBeyondMetaspaceSize.class.getName(),
++ "" + MetaspaceSize,
++ "" + YoungGenSize);
++ return new OutputAnalyzer(pb.start());
++ }
++
++ public static OutputAnalyzer runWithG1ClassUnloading() throws Exception {
++ return run(true);
++ }
++
++ public static OutputAnalyzer runWithoutG1ClassUnloading() throws Exception {
++ return run(false);
++ }
++
++ public static void testWithoutG1ClassUnloading() throws Exception {
++ // -XX:-ClassUnloadingWithConcurrentMark is used, so we expect a full GC instead of a concurrent cycle.
++ OutputAnalyzer out = runWithoutG1ClassUnloading();
++
++ out.shouldMatch(".*Full GC.*");
++ out.shouldNotMatch(".*initial-mark.*");
++ }
++
++ public static void testWithG1ClassUnloading() throws Exception {
++ // -XX:+ClassUnloadingWithConcurrentMark is used, so we expect a concurrent cycle instead of a full GC.
++ OutputAnalyzer out = runWithG1ClassUnloading();
++
++ out.shouldMatch(".*initial-mark.*");
++ out.shouldNotMatch(".*Full GC.*");
++ }
++
++ public static void main(String args[]) throws Exception {
++ testWithG1ClassUnloading();
++ testWithoutG1ClassUnloading();
++ }
++
++ public static class AllocateBeyondMetaspaceSize {
++ public static Object dummy;
++
++ public static void main(String [] args) throws Exception {
++ if (args.length != 2) {
++ throw new IllegalArgumentException("Usage: <MetaspaceSize> <YoungGenSize>");
++ }
++
++ WhiteBox wb = WhiteBox.getWhiteBox();
++
++ // Allocate past the MetaspaceSize limit
++ long metaspaceSize = Long.parseLong(args[0]);
++ long allocationBeyondMetaspaceSize = metaspaceSize * 2;
++ long metaspace = wb.allocateMetaspace(null, allocationBeyondMetaspaceSize);
++
++ long youngGenSize = Long.parseLong(args[1]);
++ triggerYoungGCs(youngGenSize);
++
++ wb.freeMetaspace(null, metaspace, metaspace);
++ }
++
++ public static void triggerYoungGCs(long youngGenSize) {
++ long approxAllocSize = 32 * 1024;
++ long numAllocations = 2 * youngGenSize / approxAllocSize;
++
++ for (long i = 0; i < numAllocations; i++) {
++ dummy = new byte[(int)approxAllocSize];
++ }
++ }
++ }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/concurrentMarkSweep/DisableResizePLAB.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,44 @@
++/*
++* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++*
++* This code is free software; you can redistribute it and/or modify it
++* under the terms of the GNU General Public License version 2 only, as
++* published by the Free Software Foundation.
++*
++* This code is distributed in the hope that it will be useful, but WITHOUT
++* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++* version 2 for more details (a copy is included in the LICENSE file that
++* accompanied this code).
++*
++* You should have received a copy of the GNU General Public License version
++* 2 along with this work; if not, write to the Free Software Foundation,
++* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++*
++* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++* or visit www.oracle.com if you need additional information or have any
++* questions.
++*/
++
++/*
++ * @test DisableResizePLAB
++ * @key gc
++ * @bug 8060467
++ * @author filipp.zhinkin@oracle.com, john.coomes@oracle.com
++ * @summary Run CMS with PLAB resizing disabled and a small OldPLABSize
++ * @run main/othervm -XX:+UseConcMarkSweepGC -XX:-ResizePLAB -XX:OldPLABSize=1k -Xmx256m -XX:+PrintGCDetails DisableResizePLAB
++ */
++
++public class DisableResizePLAB {
++ public static void main(String args[]) throws Exception {
++ Object garbage[] = new Object[1_000];
++ for (int i = 0; i < garbage.length; i++) {
++ garbage[i] = new byte[0];
++ }
++ long startTime = System.currentTimeMillis();
++ while (System.currentTimeMillis() - startTime < 10_000) {
++ Object o = new byte[1024];
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/g1/TestEagerReclaimHumongousRegions.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,98 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test TestEagerReclaimHumongousRegions
++ * @bug 8027959
++ * @summary Test to make sure that eager reclaim of humongous objects work. We simply try to fill
++ * up the heap with humongous objects that should be eagerly reclaimable to avoid Full GC.
++ * @key gc
++ * @library /testlibrary
++ */
++
++import java.util.regex.Pattern;
++import java.util.regex.Matcher;
++import java.util.LinkedList;
++
++import com.oracle.java.testlibrary.OutputAnalyzer;
++import com.oracle.java.testlibrary.ProcessTools;
++import com.oracle.java.testlibrary.Asserts;
++
++class ReclaimRegionFast {
++ public static final int M = 1024*1024;
++
++ public static LinkedList<Object> garbageList = new LinkedList<Object>();
++
++ public static void genGarbage() {
++ for (int i = 0; i < 32*1024; i++) {
++ garbageList.add(new int[100]);
++ }
++ garbageList.clear();
++ }
++
++ // A large object referenced by a static.
++ static int[] filler = new int[10 * M];
++
++ public static void main(String[] args) {
++
++ int[] large = new int[M];
++
++ Object ref_from_stack = large;
++
++ for (int i = 0; i < 100; i++) {
++ // A large object that will be reclaimed eagerly.
++ large = new int[6*M];
++ genGarbage();
++ // Make sure that the compiler cannot completely remove
++ // the allocation of the large object until here.
++ System.out.println(large);
++ }
++
++ // Keep the reference to the first object alive.
++ System.out.println(ref_from_stack);
++ }
++}
++
++public class TestEagerReclaimHumongousRegions {
++ public static void main(String[] args) throws Exception {
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:+UseG1GC",
++ "-Xms128M",
++ "-Xmx128M",
++ "-Xmn16M",
++ "-XX:+PrintGC",
++ ReclaimRegionFast.class.getName());
++
++ Pattern p = Pattern.compile("Full GC");
++
++ OutputAnalyzer output = new OutputAnalyzer(pb.start());
++
++ int found = 0;
++ Matcher m = p.matcher(output.getStdout());
++ while (m.find()) { found++; }
++ System.out.println("Issued " + found + " Full GCs");
++ Asserts.assertLT(found, 10, "Found that " + found + " Full GCs were issued. This is larger than the bound. Eager reclaim seems to not work at all");
++
++ output.shouldHaveExitValue(0);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/g1/TestEagerReclaimHumongousRegions2.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,131 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test TestEagerReclaimHumongousRegions2
++ * @bug 8051973
++ * @summary Test to make sure that eager reclaim of humongous objects correctly clears
++ * mark bitmaps at reclaim.
++ * @key gc
++ * @library /testlibrary
++ */
++
++import java.util.ArrayList;
++import java.util.LinkedList;
++import java.util.Random;
++
++import com.oracle.java.testlibrary.OutputAnalyzer;
++import com.oracle.java.testlibrary.ProcessTools;
++
++// An object that has a few references to other instances to slow down marking.
++class ObjectWithSomeRefs {
++ public ObjectWithSomeRefs other1;
++ public ObjectWithSomeRefs other2;
++ public ObjectWithSomeRefs other3;
++ public ObjectWithSomeRefs other4;
++}
++
++class ReclaimRegionFast {
++ public static final long MAX_MILLIS_FOR_RUN = 50 * 1000; // The maximum runtime for the actual test.
++
++ public static final int M = 1024*1024;
++
++ public static LinkedList<Object> garbageList = new LinkedList<Object>();
++
++ public static void genGarbage(Object large) {
++ for (int i = 0; i < 64*1024; i++) {
++ Object[] garbage = new Object[50];
++ garbage[0] = large;
++ garbageList.add(garbage);
++ }
++ garbageList.clear();
++ }
++
++ public static ArrayList<ObjectWithSomeRefs> longList = new ArrayList<ObjectWithSomeRefs>();
++
++ public static void main(String[] args) {
++
++ for (int i = 0; i < 16*1024; i++) {
++ longList.add(new ObjectWithSomeRefs());
++ }
++
++ Random rnd = new Random();
++ for (int i = 0; i < longList.size(); i++) {
++ int len = longList.size();
++ longList.get(i).other1 = longList.get(rnd.nextInt(len));
++ longList.get(i).other2 = longList.get(rnd.nextInt(len));
++ longList.get(i).other3 = longList.get(rnd.nextInt(len));
++ longList.get(i).other4 = longList.get(rnd.nextInt(len));
++ }
++
++ int[] large1 = new int[M];
++ int[] large2 = null;
++ int[] large3 = null;
++ int[] large4 = null;
++
++ Object ref_from_stack = large1;
++
++ long start_millis = System.currentTimeMillis();
++
++ for (int i = 0; i < 20; i++) {
++ long current_millis = System.currentTimeMillis();
++ if ((current_millis - start_millis) > MAX_MILLIS_FOR_RUN) {
++ System.out.println("Finishing test because maximum runtime exceeded");
++ break;
++ }
++ // A set of large objects that will be reclaimed eagerly - and hopefully marked.
++ large1 = new int[M - 20];
++ large2 = new int[M - 20];
++ large3 = new int[M - 20];
++ large4 = new int[M - 20];
++ genGarbage(large1);
++ // Make sure that the compiler cannot completely remove
++ // the allocation of the large object until here.
++ System.out.println(large1 + " " + large2 + " " + large3 + " " + large4);
++ }
++
++ // Keep the reference to the first object alive.
++ System.out.println(ref_from_stack);
++ }
++}
++
++public class TestEagerReclaimHumongousRegions2 {
++ public static void main(String[] args) throws Exception {
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:+UseG1GC",
++ "-Xms128M",
++ "-Xmx128M",
++ "-Xmn2M",
++ "-XX:G1HeapRegionSize=1M",
++ "-XX:InitiatingHeapOccupancyPercent=0", // Want to have as much as possible initial marks.
++ "-XX:+PrintGC",
++ "-XX:+VerifyAfterGC",
++ "-XX:ConcGCThreads=1", // Want to make marking as slow as possible.
++ "-XX:+IgnoreUnrecognizedVMOptions", // G1VerifyBitmaps is develop only.
++ "-XX:+G1VerifyBitmaps",
++ ReclaimRegionFast.class.getName());
++ OutputAnalyzer output = new OutputAnalyzer(pb.start());
++ output.shouldHaveExitValue(0);
++ }
++}
++
+--- ./hotspot/test/gc/g1/TestGCLogMessages.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/gc/g1/TestGCLogMessages.java Wed Feb 04 12:14:39 2015 -0800
+@@ -22,8 +22,8 @@
+ */
+
+ /*
+- * @test TestPrintGCDetails
+- * @bug 8035406 8027295 8035398
++ * @test TestGCLogMessages
++ * @bug 8035406 8027295 8035398 8019342 8027959
+ * @summary Ensure that the PrintGCDetails output for a minor GC with G1
+ * includes the expected necessary messages.
+ * @key gc
+@@ -48,10 +48,13 @@
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+ output.shouldNotContain("[Redirty Cards");
++ output.shouldNotContain("[Parallel Redirty");
++ output.shouldNotContain("[Redirtied Cards");
+ output.shouldNotContain("[Code Root Purge");
+ output.shouldNotContain("[String Dedup Fixup");
+ output.shouldNotContain("[Young Free CSet");
+ output.shouldNotContain("[Non-Young Free CSet");
++ output.shouldNotContain("[Humongous Reclaim");
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
+@@ -63,10 +66,16 @@
+ output = new OutputAnalyzer(pb.start());
+
+ output.shouldContain("[Redirty Cards");
++ output.shouldNotContain("[Parallel Redirty");
++ output.shouldNotContain("[Redirtied Cards");
+ output.shouldContain("[Code Root Purge");
+ output.shouldContain("[String Dedup Fixup");
+ output.shouldNotContain("[Young Free CSet");
+ output.shouldNotContain("[Non-Young Free CSet");
++ output.shouldContain("[Humongous Reclaim");
++ output.shouldNotContain("[Humongous Total");
++ output.shouldNotContain("[Humongous Candidate");
++ output.shouldNotContain("[Humongous Reclaimed");
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
+@@ -80,16 +89,16 @@
+ output = new OutputAnalyzer(pb.start());
+
+ output.shouldContain("[Redirty Cards");
++ output.shouldContain("[Parallel Redirty");
++ output.shouldContain("[Redirtied Cards");
+ output.shouldContain("[Code Root Purge");
+ output.shouldContain("[String Dedup Fixup");
+ output.shouldContain("[Young Free CSet");
+ output.shouldContain("[Non-Young Free CSet");
+-
+- // also check evacuation failure messages once
+- output.shouldNotContain("[Evacuation Failure");
+- output.shouldNotContain("[Recalculate Used");
+- output.shouldNotContain("[Remove Self Forwards");
+- output.shouldNotContain("[Restore RemSet");
++ output.shouldContain("[Humongous Reclaim");
++ output.shouldContain("[Humongous Total");
++ output.shouldContain("[Humongous Candidate");
++ output.shouldContain("[Humongous Reclaimed");
+ output.shouldHaveExitValue(0);
+ }
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/g1/TestHumongousShrinkHeap.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,143 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test TestHumongousShrinkHeap
++ * @bug 8036025 8056043
++ * @summary Verify that heap shrinks after GC in the presence of fragmentation
++ * due to humongous objects
++ * @library /testlibrary
++ * @run main/othervm -XX:-ExplicitGCInvokesConcurrent -XX:MinHeapFreeRatio=10
++ * -XX:MaxHeapFreeRatio=12 -XX:+UseG1GC -XX:G1HeapRegionSize=1M -verbose:gc
++ * TestHumongousShrinkHeap
++ */
++
++import java.lang.management.ManagementFactory;
++import java.lang.management.MemoryUsage;
++import java.util.ArrayList;
++import java.util.List;
++import sun.management.ManagementFactoryHelper;
++import static com.oracle.java.testlibrary.Asserts.*;
++
++public class TestHumongousShrinkHeap {
++
++ public static final String MIN_FREE_RATIO_FLAG_NAME = "MinHeapFreeRatio";
++ public static final String MAX_FREE_RATIO_FLAG_NAME = "MaxHeapFreeRatio";
++
++ private static final List<List<byte[]>> garbage = new ArrayList();
++ private static final int REGION_SIZE = 1024 * 1024; // 1M
++ private static final int LISTS_COUNT = 10;
++ private static final int HUMON_SIZE = Math.round(.9f * REGION_SIZE);
++ private static final long AVAILABLE_MEMORY
++ = Runtime.getRuntime().freeMemory();
++ private static final int HUMON_COUNT
++ = (int) ((AVAILABLE_MEMORY / HUMON_SIZE)
++ / LISTS_COUNT);
++
++
++ public static void main(String[] args) {
++ System.out.format("Running with %s max heap size. "
++ + "Will allocate humongous object of %s size %d times.%n",
++ MemoryUsagePrinter.humanReadableByteCount(AVAILABLE_MEMORY, false),
++ MemoryUsagePrinter.humanReadableByteCount(HUMON_SIZE, false),
++ HUMON_COUNT
++ );
++ new TestHumongousShrinkHeap().test();
++ }
++
++ private final void test() {
++ System.gc();
++ MemoryUsagePrinter.printMemoryUsage("init");
++
++ allocate();
++ MemoryUsagePrinter.printMemoryUsage("allocated");
++ MemoryUsage muFull = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
++
++ free();
++ MemoryUsagePrinter.printMemoryUsage("free");
++ MemoryUsage muFree = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
++
++ assertLessThan(muFree.getCommitted(), muFull.getCommitted(), String.format(
++ "committed free heap size is not less than committed full heap size, heap hasn't been shrunk?%n"
++ + "%s = %s%n%s = %s",
++ MIN_FREE_RATIO_FLAG_NAME,
++ ManagementFactoryHelper.getDiagnosticMXBean().getVMOption(MIN_FREE_RATIO_FLAG_NAME).getValue(),
++ MAX_FREE_RATIO_FLAG_NAME,
++ ManagementFactoryHelper.getDiagnosticMXBean().getVMOption(MAX_FREE_RATIO_FLAG_NAME).getValue()
++ ));
++ }
++
++ private void allocate() {
++
++ for (int i = 0; i < LISTS_COUNT; i++) {
++ List<byte[]> stuff = new ArrayList();
++ allocateList(stuff, HUMON_COUNT, HUMON_SIZE);
++ MemoryUsagePrinter.printMemoryUsage("allocate #" + (i+1));
++ garbage.add(stuff);
++ }
++ }
++
++ private void free() {
++ // do not free last one list
++ garbage.subList(0, garbage.size() - 1).clear();
++
++ // do not free last one element from last list
++ List stuff = garbage.get(garbage.size() - 1);
++ stuff.subList(0, stuff.size() - 1).clear();
++ System.gc();
++ }
++
++ private static void allocateList(List garbage, int count, int size) {
++ for (int i = 0; i < count; i++) {
++ garbage.add(new byte[size]);
++ }
++ }
++}
++
++/**
++ * Prints memory usage to standard output
++ */
++class MemoryUsagePrinter {
++
++ public static String humanReadableByteCount(long bytes, boolean si) {
++ int unit = si ? 1000 : 1024;
++ if (bytes < unit) {
++ return bytes + " B";
++ }
++ int exp = (int) (Math.log(bytes) / Math.log(unit));
++ String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");
++ return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
++ }
++
++ public static void printMemoryUsage(String label) {
++ MemoryUsage memusage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
++ float freeratio = 1f - (float) memusage.getUsed() / memusage.getCommitted();
++ System.out.format("[%-24s] init: %-7s, used: %-7s, comm: %-7s, freeRatio ~= %.1f%%%n",
++ label,
++ humanReadableByteCount(memusage.getInit(), false),
++ humanReadableByteCount(memusage.getUsed(), false),
++ humanReadableByteCount(memusage.getCommitted(), false),
++ freeratio * 100
++ );
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/g1/TestShrinkAuxiliaryData.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,287 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import static com.oracle.java.testlibrary.Asserts.assertLessThanOrEqual;
++import com.oracle.java.testlibrary.OutputAnalyzer;
++import com.oracle.java.testlibrary.Platform;
++import com.oracle.java.testlibrary.ProcessTools;
++import com.oracle.java.testlibrary.Utils;
++import java.io.IOException;
++import java.lang.management.ManagementFactory;
++import java.lang.management.MemoryUsage;
++import java.text.DecimalFormat;
++import java.text.DecimalFormatSymbols;
++import java.util.ArrayList;
++import java.util.Arrays;
++import java.util.Collections;
++import java.util.LinkedList;
++import java.util.List;
++import sun.misc.Unsafe;
++
++public class TestShrinkAuxiliaryData {
++
++ private final static String[] initialOpts = new String[]{
++ "-XX:MinHeapFreeRatio=10",
++ "-XX:MaxHeapFreeRatio=11",
++ "-XX:+UseG1GC",
++ "-XX:G1HeapRegionSize=1m",
++ "-XX:-ExplicitGCInvokesConcurrent",
++ "-XX:+PrintGCDetails"
++ };
++
++ private final int RSetCacheSize;
++
++ protected TestShrinkAuxiliaryData(int RSetCacheSize) {
++ this.RSetCacheSize = RSetCacheSize;
++ }
++
++ protected void test() throws Exception {
++ ArrayList<String> vmOpts = new ArrayList();
++ Collections.addAll(vmOpts, initialOpts);
++
++ int maxCacheSize = Math.max(0, Math.min(31, getMaxCacheSize()));
++ if (maxCacheSize < RSetCacheSize) {
++ System.out.format("Skiping test for %d cache size due max cache size %d",
++ RSetCacheSize, maxCacheSize
++ );
++ return;
++ }
++
++ printTestInfo(maxCacheSize);
++
++ vmOpts.add("-XX:G1ConcRSLogCacheSize=" + RSetCacheSize);
++
++ vmOpts.addAll(Arrays.asList(Utils.getFilteredTestJavaOpts(
++ ShrinkAuxiliaryDataTest.prohibitedVmOptions)));
++
++ // for 32 bits ObjectAlignmentInBytes is not a option
++ if (Platform.is32bit()) {
++ ArrayList<String> vmOptsWithoutAlign = new ArrayList(vmOpts);
++ vmOptsWithoutAlign.add(ShrinkAuxiliaryDataTest.class.getName());
++ performTest(vmOptsWithoutAlign);
++ return;
++ }
++
++ for (int alignment = 3; alignment <= 8; alignment++) {
++ ArrayList<String> vmOptsWithAlign = new ArrayList(vmOpts);
++ vmOptsWithAlign.add("-XX:ObjectAlignmentInBytes="
++ + (int) Math.pow(2, alignment));
++ vmOptsWithAlign.add(ShrinkAuxiliaryDataTest.class.getName());
++
++ performTest(vmOptsWithAlign);
++ }
++ }
++
++ private void performTest(List<String> opts) throws Exception {
++ ProcessBuilder pb
++ = ProcessTools.createJavaProcessBuilder(
++ opts.toArray(new String[opts.size()])
++ );
++
++ OutputAnalyzer output = new OutputAnalyzer(pb.start());
++ output.shouldHaveExitValue(0);
++ }
++
++ private void printTestInfo(int maxCacheSize) {
++
++ DecimalFormat grouped = new DecimalFormat("000,000");
++ DecimalFormatSymbols formatSymbols = grouped.getDecimalFormatSymbols();
++ formatSymbols.setGroupingSeparator(' ');
++ grouped.setDecimalFormatSymbols(formatSymbols);
++
++ System.out.format("Test will use %s bytes of memory of %s available%n"
++ + "Available memory is %s with %d bytes pointer size - can save %s pointers%n"
++ + "Max cache size: 2^%d = %s elements%n",
++ grouped.format(ShrinkAuxiliaryDataTest.getMemoryUsedByTest()),
++ grouped.format(Runtime.getRuntime().freeMemory()),
++ grouped.format(Runtime.getRuntime().freeMemory()
++ - ShrinkAuxiliaryDataTest.getMemoryUsedByTest()),
++ Unsafe.ADDRESS_SIZE,
++ grouped.format((Runtime.getRuntime().freeMemory()
++ - ShrinkAuxiliaryDataTest.getMemoryUsedByTest())
++ / Unsafe.ADDRESS_SIZE),
++ maxCacheSize,
++ grouped.format((int) Math.pow(2, maxCacheSize))
++ );
++ }
++
++ /**
++ * Detects maximum possible size of G1ConcRSLogCacheSize available for
++ * current process based on maximum available process memory size
++ *
++ * @return power of two
++ */
++ private static int getMaxCacheSize() {
++ long availableMemory = Runtime.getRuntime().freeMemory()
++ - ShrinkAuxiliaryDataTest.getMemoryUsedByTest() - 1l;
++ if (availableMemory <= 0) {
++ return 0;
++ }
++ long availablePointersCount = availableMemory / Unsafe.ADDRESS_SIZE;
++ return (63 - (int) Long.numberOfLeadingZeros(availablePointersCount));
++ }
++
++ static class ShrinkAuxiliaryDataTest {
++
++ public static void main(String[] args) throws IOException {
++ int iterateCount = DEFAULT_ITERATION_COUNT;
++
++ if (args.length > 0) {
++ try {
++ iterateCount = Integer.parseInt(args[0]);
++ } catch (NumberFormatException e) {
++ //num_iterate remains default
++ }
++ }
++
++ new ShrinkAuxiliaryDataTest().test(iterateCount);
++ }
++
++ class GarbageObject {
++
++ private final List<byte[]> payload = new ArrayList();
++ private final List<GarbageObject> ref = new LinkedList();
++
++ public GarbageObject(int size) {
++ payload.add(new byte[size]);
++ }
++
++ public void addRef(GarbageObject g) {
++ ref.add(g);
++ }
++
++ public void mutate() {
++ if (!payload.isEmpty() && payload.get(0).length > 0) {
++ payload.get(0)[0] = (byte) (Math.random() * Byte.MAX_VALUE);
++ }
++ }
++ }
++
++ private final List<GarbageObject> garbage = new ArrayList();
++
++ public void test(int num_iterate) throws IOException {
++
++ allocate();
++ link();
++ mutate();
++ deallocate();
++
++ MemoryUsage muBeforeHeap
++ = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
++ MemoryUsage muBeforeNonHeap
++ = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
++
++ for (int i = 0; i < num_iterate; i++) {
++ allocate();
++ link();
++ mutate();
++ deallocate();
++ }
++
++ System.gc();
++ MemoryUsage muAfterHeap
++ = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
++ MemoryUsage muAfterNonHeap
++ = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
++
++ assertLessThanOrEqual(muAfterHeap.getCommitted(), muBeforeHeap.getCommitted(),
++ String.format("heap decommit failed - after > before: %d > %d",
++ muAfterHeap.getCommitted(), muBeforeHeap.getCommitted()
++ )
++ );
++
++ if (muAfterHeap.getCommitted() < muBeforeHeap.getCommitted()) {
++ assertLessThanOrEqual(muAfterNonHeap.getCommitted(), muBeforeNonHeap.getCommitted(),
++ String.format("non-heap decommit failed - after > before: %d > %d",
++ muAfterNonHeap.getCommitted(), muBeforeNonHeap.getCommitted()
++ )
++ );
++ }
++ }
++
++ private void allocate() {
++ for (int r = 0; r < REGIONS_TO_ALLOCATE; r++) {
++ for (int i = 0; i < NUM_OBJECTS_PER_REGION; i++) {
++ GarbageObject g = new GarbageObject(REGION_SIZE
++ / NUM_OBJECTS_PER_REGION);
++ garbage.add(g);
++ }
++ }
++ }
++
++ /**
++ * Iterate through all allocated objects, and link to objects in another
++ * regions
++ */
++ private void link() {
++ for (int ig = 0; ig < garbage.size(); ig++) {
++ int regionNumber = ig / NUM_OBJECTS_PER_REGION;
++
++ for (int i = 0; i < NUM_LINKS; i++) {
++ int regionToLink;
++ do {
++ regionToLink = (int) (Math.random()
++ * REGIONS_TO_ALLOCATE);
++ } while (regionToLink == regionNumber);
++
++ // get random garbage object from random region
++ garbage.get(ig).addRef(garbage.get(regionToLink
++ * NUM_OBJECTS_PER_REGION + (int) (Math.random()
++ * NUM_OBJECTS_PER_REGION)));
++ }
++ }
++ }
++
++ private void mutate() {
++ for (int ig = 0; ig < garbage.size(); ig++) {
++ garbage.get(ig).mutate();
++ }
++ }
++
++ private void deallocate() {
++ garbage.clear();
++ System.gc();
++ }
++
++ static long getMemoryUsedByTest() {
++ return REGIONS_TO_ALLOCATE * REGION_SIZE;
++ }
++
++ private static final int REGION_SIZE = 1024 * 1024;
++ private static final int DEFAULT_ITERATION_COUNT = 1; // iterate main scenario
++ private static final int REGIONS_TO_ALLOCATE = 5;
++ private static final int NUM_OBJECTS_PER_REGION = 10;
++ private static final int NUM_LINKS = 20; // how many links create for each object
++
++ private static final String[] prohibitedVmOptions = {
++ // remove this when @requires option will be on duty
++ "-XX:\\+UseParallelGC",
++ "-XX:\\+UseSerialGC",
++ "-XX:\\+UseConcMarkSweepGC",
++ "-XX:\\+UseParallelOldGC",
++ "-XX:\\+UseParNewGC",
++ "-Xconcgc",
++ "-Xincgc"
++ };
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/g1/TestShrinkAuxiliaryData00.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test TestShrinkAuxiliaryData00
++ * @bug 8038423
++ * @summary Checks that decommitment occurs for JVM with different
++ * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData00
++ * @run driver/timeout=720 TestShrinkAuxiliaryData00
++ */
++public class TestShrinkAuxiliaryData00 {
++
++ public static void main(String[] args) throws Exception {
++ new TestShrinkAuxiliaryData(0).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/g1/TestShrinkAuxiliaryData05.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test TestShrinkAuxiliaryData05
++ * @bug 8038423
++ * @summary Checks that decommitment occurs for JVM with different
++ * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData05
++ * @run driver/timeout=720 TestShrinkAuxiliaryData05
++ */
++public class TestShrinkAuxiliaryData05 {
++
++ public static void main(String[] args) throws Exception {
++ new TestShrinkAuxiliaryData(5).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/g1/TestShrinkAuxiliaryData10.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test TestShrinkAuxiliaryData10
++ * @bug 8038423
++ * @summary Checks that decommitment occurs for JVM with different
++ * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData10
++ * @run driver/timeout=720 TestShrinkAuxiliaryData10
++ */
++public class TestShrinkAuxiliaryData10 {
++
++ public static void main(String[] args) throws Exception {
++ new TestShrinkAuxiliaryData(10).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/g1/TestShrinkAuxiliaryData15.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test TestShrinkAuxiliaryData15
++ * @bug 8038423
++ * @summary Checks that decommitment occurs for JVM with different
++ * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData15
++ * @run driver/timeout=720 TestShrinkAuxiliaryData15
++ */
++public class TestShrinkAuxiliaryData15 {
++
++ public static void main(String[] args) throws Exception {
++ new TestShrinkAuxiliaryData(15).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/g1/TestShrinkAuxiliaryData20.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test TestShrinkAuxiliaryData20
++ * @bug 8038423
++ * @summary Checks that decommitment occurs for JVM with different
++ * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData20
++ * @run driver/timeout=720 TestShrinkAuxiliaryData20
++ */
++public class TestShrinkAuxiliaryData20 {
++
++ public static void main(String[] args) throws Exception {
++ new TestShrinkAuxiliaryData(20).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/g1/TestShrinkAuxiliaryData25.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test TestShrinkAuxiliaryData25
++ * @bug 8038423
++ * @summary Checks that decommitment occurs for JVM with different
++ * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData25
++ * @run driver/timeout=720 TestShrinkAuxiliaryData25
++ */
++public class TestShrinkAuxiliaryData25 {
++
++ public static void main(String[] args) throws Exception {
++ new TestShrinkAuxiliaryData(25).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/g1/TestShrinkAuxiliaryData30.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test TestShrinkAuxiliaryData30
++ * @bug 8038423
++ * @summary Checks that decommitment occurs for JVM with different
++ * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData30
++ * @run driver/timeout=720 TestShrinkAuxiliaryData30
++ */
++public class TestShrinkAuxiliaryData30 {
++
++ public static void main(String[] args) throws Exception {
++ new TestShrinkAuxiliaryData(30).test();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/g1/TestShrinkDefragmentedHeap.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,189 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test TestShrinkDefragmentedHeap
++ * @bug 8038423
++ * @summary Verify that heap shrinks after GC in the presence of fragmentation due to humongous objects
++ * 1. allocate small objects mixed with humongous ones
++ * "ssssHssssHssssHssssHssssHssssHssssH"
++ * 2. release all allocated object except the last humongous one
++ * "..................................H"
++ * 3. invoke gc and check that memory returned to the system (amount of committed memory got down)
++ *
++ * @library /testlibrary
++ */
++import java.lang.management.ManagementFactory;
++import java.lang.management.MemoryUsage;
++import java.util.ArrayList;
++import java.util.List;
++import sun.management.ManagementFactoryHelper;
++import static com.oracle.java.testlibrary.Asserts.*;
++import com.oracle.java.testlibrary.ProcessTools;
++import com.oracle.java.testlibrary.OutputAnalyzer;
++
++public class TestShrinkDefragmentedHeap {
++ // Since we store all the small objects, they become old and old regions are also allocated at the bottom of the heap
++ // together with humongous regions. So if there are a lot of old regions in the lower part of the heap,
++ // the humongous regions will be allocated in the upper part of the heap anyway.
++ // To avoid this the Eden needs to be big enough to fit all the small objects.
++ private static final int INITIAL_HEAP_SIZE = 200 * 1024 * 1024;
++ private static final int MINIMAL_YOUNG_SIZE = 190 * 1024 * 1024;
++ private static final int REGION_SIZE = 1 * 1024 * 1024;
++
++ public static void main(String[] args) throws Exception, Throwable {
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:InitialHeapSize=" + INITIAL_HEAP_SIZE,
++ "-Xmn" + MINIMAL_YOUNG_SIZE,
++ "-XX:MinHeapFreeRatio=10",
++ "-XX:MaxHeapFreeRatio=11",
++ "-XX:+UseG1GC",
++ "-XX:G1HeapRegionSize=" + REGION_SIZE,
++ "-XX:-ExplicitGCInvokesConcurrent",
++ "-verbose:gc",
++ GCTest.class.getName()
++ );
++
++ OutputAnalyzer output = ProcessTools.executeProcess(pb);
++ output.shouldHaveExitValue(0);
++ }
++
++ static class GCTest {
++
++ private static final String MIN_FREE_RATIO_FLAG_NAME = "MinHeapFreeRatio";
++ private static final String MAX_FREE_RATIO_FLAG_NAME = "MaxHeapFreeRatio";
++ private static final String NEW_SIZE_FLAG_NAME = "NewSize";
++
++ private static final ArrayList<ArrayList<byte[]>> garbage = new ArrayList<>();
++
++ private static final int SMALL_OBJS_SIZE = 10 * 1024; // 10kB
++ private static final int SMALL_OBJS_COUNT = MINIMAL_YOUNG_SIZE / (SMALL_OBJS_SIZE-1);
++ private static final int ALLOCATE_COUNT = 3;
++ // try to put all humongous object into gap between min young size and initial heap size
++ // to avoid implicit GCs
++ private static final int HUMONG_OBJS_SIZE = (int) Math.max(
++ (INITIAL_HEAP_SIZE - MINIMAL_YOUNG_SIZE) / ALLOCATE_COUNT / 4,
++ REGION_SIZE * 1.1
++ );
++
++ private static final long initialHeapSize = getHeapMemoryUsage().getUsed();
++
++ public static void main(String[] args) throws InterruptedException {
++ new GCTest().test();
++ }
++
++ private void test() throws InterruptedException {
++ MemoryUsagePrinter.printMemoryUsage("init");
++
++ allocate();
++ System.gc();
++ MemoryUsage muFull = getHeapMemoryUsage();
++ MemoryUsagePrinter.printMemoryUsage("allocated");
++
++ free();
++ //Thread.sleep(1000); // sleep before measures due lags in JMX
++ MemoryUsage muFree = getHeapMemoryUsage();
++ MemoryUsagePrinter.printMemoryUsage("free");
++
++ assertLessThan(muFree.getCommitted(), muFull.getCommitted(), prepareMessageCommittedIsNotLess() );
++ }
++
++ private void allocate() {
++ System.out.format("Will allocate objects of small size = %s and humongous size = %s",
++ MemoryUsagePrinter.humanReadableByteCount(SMALL_OBJS_SIZE, false),
++ MemoryUsagePrinter.humanReadableByteCount(HUMONG_OBJS_SIZE, false)
++ );
++
++ for (int i = 0; i < ALLOCATE_COUNT; i++) {
++ ArrayList<byte[]> stuff = new ArrayList<>();
++ allocateList(stuff, SMALL_OBJS_COUNT / ALLOCATE_COUNT, SMALL_OBJS_SIZE);
++ garbage.add(stuff);
++
++ ArrayList<byte[]> humongousStuff = new ArrayList<>();
++ allocateList(humongousStuff, 4, HUMONG_OBJS_SIZE);
++ garbage.add(humongousStuff);
++ }
++ }
++
++ private void free() {
++ // do not free last one list
++ garbage.subList(0, garbage.size() - 1).clear();
++
++ // do not free last one element from last list
++ ArrayList stuff = garbage.get(garbage.size() - 1);
++ if (stuff.size() > 1) {
++ stuff.subList(0, stuff.size() - 1).clear();
++ }
++ System.gc();
++ }
++
++ private String prepareMessageCommittedIsNotLess() {
++ return String.format(
++ "committed free heap size is not less than committed full heap size, heap hasn't been shrunk?%n"
++ + "%s = %s%n%s = %s",
++ MIN_FREE_RATIO_FLAG_NAME,
++ ManagementFactoryHelper.getDiagnosticMXBean().getVMOption(MIN_FREE_RATIO_FLAG_NAME).getValue(),
++ MAX_FREE_RATIO_FLAG_NAME,
++ ManagementFactoryHelper.getDiagnosticMXBean().getVMOption(MAX_FREE_RATIO_FLAG_NAME).getValue()
++ );
++ }
++
++ private static void allocateList(List garbage, int count, int size) {
++ for (int i = 0; i < count; i++) {
++ garbage.add(new byte[size]);
++ }
++ }
++ }
++
++ static MemoryUsage getHeapMemoryUsage() {
++ return ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
++ }
++
++ /**
++ * Prints memory usage to standard output
++ */
++ static class MemoryUsagePrinter {
++
++ public static String humanReadableByteCount(long bytes, boolean si) {
++ int unit = si ? 1000 : 1024;
++ if (bytes < unit) {
++ return bytes + " B";
++ }
++ int exp = (int) (Math.log(bytes) / Math.log(unit));
++ String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");
++ return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
++ }
++
++ public static void printMemoryUsage(String label) {
++ MemoryUsage memusage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
++ float freeratio = 1f - (float) memusage.getUsed() / memusage.getCommitted();
++ System.out.format("[%-24s] init: %-7s, used: %-7s, comm: %-7s, freeRatio ~= %.1f%%%n",
++ label,
++ humanReadableByteCount(memusage.getInit(), false),
++ humanReadableByteCount(memusage.getUsed(), false),
++ humanReadableByteCount(memusage.getCommitted(), false),
++ freeratio * 100
++ );
++ }
++ }
++}
+--- ./hotspot/test/gc/g1/TestSummarizeRSetStatsThreads.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/gc/g1/TestSummarizeRSetStatsThreads.java Wed Feb 04 12:14:39 2015 -0800
+@@ -53,8 +53,8 @@
+
+ // a zero in refinement thread numbers indicates that the value in ParallelGCThreads should be used.
+ // Additionally use at least one thread.
+- int expectedNumRefinementThreads = refinementThreads == 0 ? workerThreads : refinementThreads;
+- expectedNumRefinementThreads = Math.max(1, expectedNumRefinementThreads);
++ int expectedNumRefinementThreads = refinementThreads;
++
+ // create the pattern made up of n copies of a floating point number pattern
+ String numberPattern = String.format("%0" + expectedNumRefinementThreads + "d", 0)
+ .replace("0", "\\s+\\d+\\.\\d+");
+@@ -73,9 +73,9 @@
+ return;
+ }
+ // different valid combinations of number of refinement and gc worker threads
+- runTest(0, 0);
+- runTest(0, 5);
+- runTest(5, 0);
++ runTest(1, 1);
++ runTest(1, 5);
++ runTest(5, 1);
+ runTest(10, 10);
+ runTest(1, 2);
+ runTest(4, 3);
+--- ./hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java Wed Feb 04 12:14:39 2015 -0800
+@@ -88,7 +88,6 @@
+ ArrayList<String> finalargs = new ArrayList<String>();
+ String[] defaultArgs = new String[] {
+ "-XX:+UseG1GC",
+- "-XX:+UseCompressedOops",
+ "-Xmn4m",
+ "-Xmx20m",
+ "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/logging/TestGCId.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,91 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test TestGCId
++ * @bug 8043607
++ * @summary Ensure that the GCId is logged
++ * @key gc
++ * @library /testlibrary
++ */
++
++import com.oracle.java.testlibrary.ProcessTools;
++import com.oracle.java.testlibrary.OutputAnalyzer;
++
++public class TestGCId {
++ public static void main(String[] args) throws Exception {
++ testGCId("UseParallelGC", "PrintGC");
++ testGCId("UseParallelGC", "PrintGCDetails");
++
++ testGCId("UseG1GC", "PrintGC");
++ testGCId("UseG1GC", "PrintGCDetails");
++
++ testGCId("UseConcMarkSweepGC", "PrintGC");
++ testGCId("UseConcMarkSweepGC", "PrintGCDetails");
++
++ testGCId("UseSerialGC", "PrintGC");
++ testGCId("UseSerialGC", "PrintGCDetails");
++ }
++
++ private static void verifyContainsGCIDs(OutputAnalyzer output) {
++ output.shouldMatch("^#0: \\[");
++ output.shouldMatch("^#1: \\[");
++ output.shouldHaveExitValue(0);
++ }
++
++ private static void verifyContainsNoGCIDs(OutputAnalyzer output) {
++ output.shouldNotMatch("^#[0-9]+: \\[");
++ output.shouldHaveExitValue(0);
++ }
++
++ private static void testGCId(String gcFlag, String logFlag) throws Exception {
++ // GCID logging enabled
++ ProcessBuilder pb_enabled =
++ ProcessTools.createJavaProcessBuilder("-XX:+" + gcFlag, "-XX:+" + logFlag, "-Xmx10M", "-XX:+PrintGCID", GCTest.class.getName());
++ verifyContainsGCIDs(new OutputAnalyzer(pb_enabled.start()));
++
++ // GCID logging disabled
++ ProcessBuilder pb_disabled =
++ ProcessTools.createJavaProcessBuilder("-XX:+" + gcFlag, "-XX:+" + logFlag, "-Xmx10M", "-XX:-PrintGCID", GCTest.class.getName());
++ verifyContainsNoGCIDs(new OutputAnalyzer(pb_disabled.start()));
++
++ // GCID logging default
++ ProcessBuilder pb_default =
++ ProcessTools.createJavaProcessBuilder("-XX:+" + gcFlag, "-XX:+" + logFlag, "-Xmx10M", GCTest.class.getName());
++ verifyContainsNoGCIDs(new OutputAnalyzer(pb_default.start()));
++ }
++
++ static class GCTest {
++ private static byte[] garbage;
++ public static void main(String [] args) {
++ System.out.println("Creating garbage");
++ // create 128MB of garbage. This should result in at least one GC
++ for (int i = 0; i < 1024; i++) {
++ garbage = new byte[128 * 1024];
++ }
++ // do a system gc to get one more gc
++ System.gc();
++ System.out.println("Done");
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/metaspace/TestCapacityUntilGCWrapAround.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @key gc
++ * @bug 8049831
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestCapacityUntilGCWrapAround
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI TestCapacityUntilGCWrapAround
++ */
++
++import sun.hotspot.WhiteBox;
++
++import com.oracle.java.testlibrary.Asserts;
++import com.oracle.java.testlibrary.Platform;
++
++public class TestCapacityUntilGCWrapAround {
++ private static long MB = 1024 * 1024;
++ private static long GB = 1024 * MB;
++ private static long MAX_UINT = 4 * GB - 1; // On 32-bit platforms
++
++ public static void main(String[] args) {
++ if (Platform.is32bit()) {
++ WhiteBox wb = WhiteBox.getWhiteBox();
++
++ long before = wb.metaspaceCapacityUntilGC();
++ // Now force possible overflow of capacity_until_GC.
++ long after = wb.incMetaspaceCapacityUntilGC(MAX_UINT);
++
++ Asserts.assertGTE(after, before,
++ "Increasing with MAX_UINT should not cause wrap around: " + after + " < " + before);
++ Asserts.assertLTE(after, MAX_UINT,
++ "Increasing with MAX_UINT should not cause value larger than MAX_UINT:" + after);
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/survivorAlignment/AlignmentHelper.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,174 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.lang.management.MemoryPoolMXBean;
++import java.util.Optional;
++
++import sun.hotspot.WhiteBox;
++
++/**
++ * Helper class aimed to provide information about alignment of objects in
++ * particular heap space, expected memory usage after objects' allocation so on.
++ */
++public class AlignmentHelper {
++ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
++
++ private static final long OBJECT_ALIGNMENT_IN_BYTES_FOR_32_VM = 8L;
++
++ /**
++ * Max relative allowed actual memory usage deviation from expected memory
++ * usage.
++ */
++ private static final float MAX_RELATIVE_DEVIATION = 0.05f; // 5%
++
++ public static final long OBJECT_ALIGNMENT_IN_BYTES = Optional.ofNullable(
++ AlignmentHelper.WHITE_BOX.getIntxVMFlag("ObjectAlignmentInBytes"))
++ .orElse(AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES_FOR_32_VM);
++
++ public static final long SURVIVOR_ALIGNMENT_IN_BYTES = Optional.ofNullable(
++ AlignmentHelper.WHITE_BOX.getIntxVMFlag("SurvivorAlignmentInBytes"))
++ .orElseThrow(() ->new AssertionError(
++ "Unable to get SurvivorAlignmentInBytes value"));
++ /**
++ * Min amount of memory that will be occupied by an object.
++ */
++ public static final long MIN_OBJECT_SIZE
++ = AlignmentHelper.WHITE_BOX.getObjectSize(new Object());
++ /**
++ * Min amount of memory that will be occupied by an empty byte array.
++ */
++ public static final long MIN_ARRAY_SIZE
++ = AlignmentHelper.WHITE_BOX.getObjectSize(new byte[0]);
++
++ /**
++ * Precision at which actual memory usage in a heap space represented by
++ * this sizing helper could be measured.
++ */
++ private final long memoryUsageMeasurementPrecision;
++ /**
++ * Min amount of memory that will be occupied by an object allocated in a
++ * heap space represented by this sizing helper.
++ */
++ private final long minObjectSizeInThisSpace;
++ /**
++ * Object's alignment in a heap space represented by this sizing helper.
++ */
++ private final long objectAlignmentInThisRegion;
++ /**
++ * MemoryPoolMXBean associated with a heap space represented by this sizing
++ * helper.
++ */
++ private final MemoryPoolMXBean poolMXBean;
++
++ private static long alignUp(long value, long alignment) {
++ return ((value - 1) / alignment + 1) * alignment;
++ }
++
++ protected AlignmentHelper(long memoryUsageMeasurementPrecision,
++ long objectAlignmentInThisRegion, long minObjectSizeInThisSpace,
++ MemoryPoolMXBean poolMXBean) {
++ this.memoryUsageMeasurementPrecision = memoryUsageMeasurementPrecision;
++ this.minObjectSizeInThisSpace = minObjectSizeInThisSpace;
++ this.objectAlignmentInThisRegion = objectAlignmentInThisRegion;
++ this.poolMXBean = poolMXBean;
++ }
++
++ /**
++ * Returns how many objects have to be allocated to fill
++ * {@code memoryToFill} bytes in this heap space using objects of size
++ * {@code objectSize}.
++ */
++ public int getObjectsCount(long memoryToFill, long objectSize) {
++ return (int) (memoryToFill / getObjectSizeInThisSpace(objectSize));
++ }
++
++ /**
++ * Returns amount of memory that {@code objectsCount} of objects with size
++ * {@code objectSize} will occupy this this space after allocation.
++ */
++ public long getExpectedMemoryUsage(long objectSize, int objectsCount) {
++ long correctedObjectSize = getObjectSizeInThisSpace(objectSize);
++ return AlignmentHelper.alignUp(correctedObjectSize * objectsCount,
++ memoryUsageMeasurementPrecision);
++ }
++
++ /**
++ * Returns current memory usage in this heap space.
++ */
++ public long getActualMemoryUsage() {
++ return poolMXBean.getUsage().getUsed();
++ }
++
++ /**
++ * Returns maximum memory usage deviation from {@code expectedMemoryUsage}
++ * given the max allowed relative deviation equal to
++ * {@code relativeDeviation}.
++ *
++ * Note that value returned by this method is aligned according to
++ * memory measurement precision for this heap space.
++ */
++ public long getAllowedMemoryUsageDeviation(long expectedMemoryUsage) {
++ long unalignedDeviation = (long) (expectedMemoryUsage *
++ AlignmentHelper.MAX_RELATIVE_DEVIATION);
++ return AlignmentHelper.alignUp(unalignedDeviation,
++ memoryUsageMeasurementPrecision);
++ }
++
++ /**
++ * Returns amount of memory that will be occupied by an object with size
++ * {@code objectSize} in this heap space.
++ */
++ public long getObjectSizeInThisSpace(long objectSize) {
++ objectSize = Math.max(objectSize, minObjectSizeInThisSpace);
++
++ long alignedObjectSize = AlignmentHelper.alignUp(objectSize,
++ objectAlignmentInThisRegion);
++ long sizeDiff = alignedObjectSize - objectSize;
++
++ // If there is not enough space to fit padding object, then object will
++ // be aligned to {@code 2 * objectAlignmentInThisRegion}.
++ if (sizeDiff >= AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES
++ && sizeDiff < AlignmentHelper.MIN_OBJECT_SIZE) {
++ alignedObjectSize += AlignmentHelper.MIN_OBJECT_SIZE;
++ alignedObjectSize = AlignmentHelper.alignUp(alignedObjectSize,
++ objectAlignmentInThisRegion);
++ }
++
++ return alignedObjectSize;
++ }
++ @Override
++ public String toString() {
++ StringBuilder builder = new StringBuilder();
++
++ builder.append(String.format("AlignmentHelper for memory pool '%s':%n",
++ poolMXBean.getName()));
++ builder.append(String.format("Memory usage measurement precision: %d%n",
++ memoryUsageMeasurementPrecision));
++ builder.append(String.format("Min object size in this space: %d%n",
++ minObjectSizeInThisSpace));
++ builder.append(String.format("Object alignment in this space: %d%n",
++ objectAlignmentInThisRegion));
++
++ return builder.toString();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/survivorAlignment/SurvivorAlignmentTestMain.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,416 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.lang.management.ManagementFactory;
++import java.lang.management.MemoryPoolMXBean;
++import java.util.Objects;
++import java.util.Optional;
++import java.util.regex.Matcher;
++import java.util.regex.Pattern;
++
++import com.oracle.java.testlibrary.Asserts;
++import com.sun.management.ThreadMXBean;
++import sun.hotspot.WhiteBox;
++import sun.misc.Unsafe;
++
++/**
++ * Main class for tests on {@code SurvivorAlignmentInBytes} option.
++ *
++ * Typical usage is to obtain instance using fromArgs method, allocate objects
++ * and verify that actual memory usage in tested heap space is close to
++ * expected.
++ */
++public class SurvivorAlignmentTestMain {
++ enum HeapSpace {
++ EDEN,
++ SURVIVOR,
++ TENURED
++ }
++
++ public static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
++
++ public static final long MAX_TENURING_THRESHOLD = Optional.ofNullable(
++ SurvivorAlignmentTestMain.WHITE_BOX.getIntxVMFlag(
++ "MaxTenuringThreshold")).orElse(15L);
++
++ /**
++ * Regexp used to parse memory size params, like 2G, 34m or 15k.
++ */
++ private static final Pattern SIZE_REGEX
++ = Pattern.compile("(?<size>[0-9]+)(?<multiplier>[GMKgmk])?");
++
++ // Names of different heap spaces.
++ private static final String DEF_NEW_EDEN = "Eden Space";
++ private static final String DEF_NEW_SURVIVOR = "Survivor Space";
++ private static final String PAR_NEW_EDEN = "Par Eden Space";
++ private static final String PAR_NEW_SURVIVOR = "Par Survivor Space";
++ private static final String PS_EDEN = "PS Eden Space";
++ private static final String PS_SURVIVOR = "PS Survivor Space";
++ private static final String G1_EDEN = "G1 Eden Space";
++ private static final String G1_SURVIVOR = "G1 Survivor Space";
++ private static final String SERIAL_TENURED = "Tenured Gen";
++ private static final String CMS_TENURED = "CMS Old Gen";
++ private static final String PS_TENURED = "PS Old Gen";
++ private static final String G1_TENURED = "G1 Old Gen";
++
++ private static final long G1_HEAP_REGION_SIZE = Optional.ofNullable(
++ SurvivorAlignmentTestMain.WHITE_BOX.getUintxVMFlag(
++ "G1HeapRegionSize")).orElse(-1L);
++
++ /**
++ * Min size of free chunk in CMS generation.
++ * An object allocated in CMS generation will at least occupy this amount
++ * of bytes.
++ */
++ private static final long CMS_MIN_FREE_CHUNK_SIZE
++ = 3L * Unsafe.ADDRESS_SIZE;
++
++ private static final AlignmentHelper EDEN_SPACE_HELPER;
++ private static final AlignmentHelper SURVIVOR_SPACE_HELPER;
++ private static final AlignmentHelper TENURED_SPACE_HELPER;
++ /**
++ * Amount of memory that should be filled during a test run.
++ */
++ private final long memoryToFill;
++ /**
++ * The size of an objects that will be allocated during a test run.
++ */
++ private final long objectSize;
++ /**
++ * Amount of memory that will be actually occupied by an object in eden
++ * space.
++ */
++ private final long actualObjectSize;
++ /**
++ * Storage for allocated objects.
++ */
++ private final Object[] garbage;
++ /**
++ * Heap space whose memory usage is a subject of assertions during the test
++ * run.
++ */
++ private final HeapSpace testedSpace;
++
++ private long[] baselinedThreadMemoryUsage = null;
++ private long[] threadIds = null;
++
++ /**
++ * Initialize {@code EDEN_SPACE_HELPER}, {@code SURVIVOR_SPACE_HELPER} and
++ * {@code TENURED_SPACE_HELPER} to represent heap spaces in use.
++ *
++ * Note that regardless to GC object's alignment in survivor space is
++ * expected to be equal to {@code SurvivorAlignmentInBytes} value and
++ * alignment in other spaces is expected to be equal to
++ * {@code ObjectAlignmentInBytes} value.
++ *
++ * In CMS generation we can't allocate less then {@code MinFreeChunk} value,
++ * for other CGs we expect that object of size {@code MIN_OBJECT_SIZE}
++ * could be allocated as it is (of course, its size could be aligned
++ * according to alignment value used in a particular space).
++ *
++ * For G1 GC MXBeans could report memory usage only with region size
++ * precision (if an object allocated in some G1 heap region, then all region
++ * will claimed as used), so for G1's spaces precision is equal to
++ * {@code G1HeapRegionSize} value.
++ */
++ static {
++ AlignmentHelper edenHelper = null;
++ AlignmentHelper survivorHelper = null;
++ AlignmentHelper tenuredHelper = null;
++ for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
++ switch (pool.getName()) {
++ case SurvivorAlignmentTestMain.DEF_NEW_EDEN:
++ case SurvivorAlignmentTestMain.PAR_NEW_EDEN:
++ case SurvivorAlignmentTestMain.PS_EDEN:
++ Asserts.assertNull(edenHelper,
++ "Only one bean for eden space is expected.");
++ edenHelper = new AlignmentHelper(
++ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
++ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
++ AlignmentHelper.MIN_OBJECT_SIZE, pool);
++ break;
++ case SurvivorAlignmentTestMain.G1_EDEN:
++ Asserts.assertNull(edenHelper,
++ "Only one bean for eden space is expected.");
++ edenHelper = new AlignmentHelper(
++ SurvivorAlignmentTestMain.G1_HEAP_REGION_SIZE,
++ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
++ AlignmentHelper.MIN_OBJECT_SIZE, pool);
++ break;
++ case SurvivorAlignmentTestMain.DEF_NEW_SURVIVOR:
++ case SurvivorAlignmentTestMain.PAR_NEW_SURVIVOR:
++ case SurvivorAlignmentTestMain.PS_SURVIVOR:
++ Asserts.assertNull(survivorHelper,
++ "Only one bean for survivor space is expected.");
++ survivorHelper = new AlignmentHelper(
++ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
++ AlignmentHelper.SURVIVOR_ALIGNMENT_IN_BYTES,
++ AlignmentHelper.MIN_OBJECT_SIZE, pool);
++ break;
++ case SurvivorAlignmentTestMain.G1_SURVIVOR:
++ Asserts.assertNull(survivorHelper,
++ "Only one bean for survivor space is expected.");
++ survivorHelper = new AlignmentHelper(
++ SurvivorAlignmentTestMain.G1_HEAP_REGION_SIZE,
++ AlignmentHelper.SURVIVOR_ALIGNMENT_IN_BYTES,
++ AlignmentHelper.MIN_OBJECT_SIZE, pool);
++ break;
++ case SurvivorAlignmentTestMain.SERIAL_TENURED:
++ case SurvivorAlignmentTestMain.PS_TENURED:
++ case SurvivorAlignmentTestMain.G1_TENURED:
++ Asserts.assertNull(tenuredHelper,
++ "Only one bean for tenured space is expected.");
++ tenuredHelper = new AlignmentHelper(
++ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
++ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
++ AlignmentHelper.MIN_OBJECT_SIZE, pool);
++ break;
++ case SurvivorAlignmentTestMain.CMS_TENURED:
++ Asserts.assertNull(tenuredHelper,
++ "Only one bean for tenured space is expected.");
++ tenuredHelper = new AlignmentHelper(
++ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
++ AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES,
++ SurvivorAlignmentTestMain.CMS_MIN_FREE_CHUNK_SIZE,
++ pool);
++ break;
++ }
++ }
++ EDEN_SPACE_HELPER = Objects.requireNonNull(edenHelper,
++ "AlignmentHelper for eden space should be initialized.");
++ SURVIVOR_SPACE_HELPER = Objects.requireNonNull(survivorHelper,
++ "AlignmentHelper for survivor space should be initialized.");
++ TENURED_SPACE_HELPER = Objects.requireNonNull(tenuredHelper,
++ "AlignmentHelper for tenured space should be initialized.");
++ }
++ /**
++ * Returns an SurvivorAlignmentTestMain instance constructed using CLI
++ * options.
++ *
++ * Following options are expected:
++ * <ul>
++ * <li>memoryToFill</li>
++ * <li>objectSize</li>
++ * </ul>
++ *
++ * Both argument may contain multiplier suffix k, m or g.
++ */
++ public static SurvivorAlignmentTestMain fromArgs(String[] args) {
++ Asserts.assertEQ(args.length, 3, "Expected three arguments: "
++ + "memory size, object size and tested heap space name.");
++
++ long memoryToFill = parseSize(args[0]);
++ long objectSize = Math.max(parseSize(args[1]),
++ AlignmentHelper.MIN_ARRAY_SIZE);
++ HeapSpace testedSpace = HeapSpace.valueOf(args[2]);
++
++ return new SurvivorAlignmentTestMain(memoryToFill, objectSize,
++ testedSpace);
++ }
++
++ /**
++ * Returns a value parsed from a string with format
++ * &lt;integer&gt;&lt;multiplier&gt;.
++ */
++ private static long parseSize(String sizeString) {
++ Matcher matcher = SIZE_REGEX.matcher(sizeString);
++ Asserts.assertTrue(matcher.matches(),
++ "sizeString should have following format \"[0-9]+([MBK])?\"");
++ long size = Long.valueOf(matcher.group("size"));
++
++ if (matcher.group("multiplier") != null) {
++ long K = 1024L;
++ // fall through multipliers
++ switch (matcher.group("multiplier").toLowerCase()) {
++ case "g":
++ size *= K;
++ case "m":
++ size *= K;
++ case "k":
++ size *= K;
++ }
++ }
++ return size;
++ }
++
++ private SurvivorAlignmentTestMain(long memoryToFill, long objectSize,
++ HeapSpace testedSpace) {
++ this.objectSize = objectSize;
++ this.memoryToFill = memoryToFill;
++ this.testedSpace = testedSpace;
++
++ AlignmentHelper helper = SurvivorAlignmentTestMain.EDEN_SPACE_HELPER;
++
++ this.actualObjectSize = helper.getObjectSizeInThisSpace(
++ this.objectSize);
++ int arrayLength = helper.getObjectsCount(memoryToFill, this.objectSize);
++ garbage = new Object[arrayLength];
++ }
++
++ /**
++ * Allocate byte arrays to fill {@code memoryToFill} memory.
++ */
++ public void allocate() {
++ int byteArrayLength = Math.max((int) (objectSize
++ - Unsafe.ARRAY_BYTE_BASE_OFFSET), 0);
++
++ for (int i = 0; i < garbage.length; i++) {
++ garbage[i] = new byte[byteArrayLength];
++ }
++ }
++
++ /**
++ * Release memory occupied after {@code allocate} call.
++ */
++ public void release() {
++ for (int i = 0; i < garbage.length; i++) {
++ garbage[i] = null;
++ }
++ }
++
++ /**
++ * Returns expected amount of memory occupied in a {@code heapSpace} by
++ * objects referenced from {@code garbage} array.
++ */
++ public long getExpectedMemoryUsage() {
++ AlignmentHelper alignmentHelper = getAlignmentHelper(testedSpace);
++ return alignmentHelper.getExpectedMemoryUsage(objectSize,
++ garbage.length);
++ }
++
++ /**
++ * Verifies that memory usage in a {@code heapSpace} deviates from
++ * {@code expectedUsage} for no more than {@code MAX_RELATIVE_DEVIATION}.
++ */
++ public void verifyMemoryUsage(long expectedUsage) {
++ AlignmentHelper alignmentHelper = getAlignmentHelper(testedSpace);
++
++ long actualMemoryUsage = alignmentHelper.getActualMemoryUsage();
++ boolean otherThreadsAllocatedMemory = areOtherThreadsAllocatedMemory();
++
++ long memoryUsageDiff = Math.abs(actualMemoryUsage - expectedUsage);
++ long maxAllowedUsageDiff
++ = alignmentHelper.getAllowedMemoryUsageDeviation(expectedUsage);
++
++ System.out.println("Verifying memory usage in space: " + testedSpace);
++ System.out.println("Allocated objects count: " + garbage.length);
++ System.out.println("Desired object size: " + objectSize);
++ System.out.println("Actual object size: " + actualObjectSize);
++ System.out.println("Expected object size in space: "
++ + alignmentHelper.getObjectSizeInThisSpace(objectSize));
++ System.out.println("Expected memory usage: " + expectedUsage);
++ System.out.println("Actual memory usage: " + actualMemoryUsage);
++ System.out.println("Memory usage diff: " + memoryUsageDiff);
++ System.out.println("Max allowed usage diff: " + maxAllowedUsageDiff);
++
++ if (memoryUsageDiff > maxAllowedUsageDiff
++ && otherThreadsAllocatedMemory) {
++ System.out.println("Memory usage diff is incorrect, but it seems "
++ + "like someone else allocated objects");
++ return;
++ }
++
++ Asserts.assertLTE(memoryUsageDiff, maxAllowedUsageDiff,
++ "Actual memory usage should not deviate from expected for " +
++ "more then " + maxAllowedUsageDiff);
++ }
++
++ /**
++ * Baselines amount of memory allocated by each thread.
++ */
++ public void baselineMemoryAllocation() {
++ ThreadMXBean bean = (ThreadMXBean) ManagementFactory.getThreadMXBean();
++ threadIds = bean.getAllThreadIds();
++ baselinedThreadMemoryUsage = bean.getThreadAllocatedBytes(threadIds);
++ }
++
++ /**
++ * Checks if threads other then the current thread were allocating objects
++ * after baselinedThreadMemoryUsage call.
++ *
++ * If baselinedThreadMemoryUsage was not called, then this method will return
++ * {@code false}.
++ */
++ public boolean areOtherThreadsAllocatedMemory() {
++ if (baselinedThreadMemoryUsage == null) {
++ return false;
++ }
++
++ ThreadMXBean bean = (ThreadMXBean) ManagementFactory.getThreadMXBean();
++ long currentMemoryAllocation[]
++ = bean.getThreadAllocatedBytes(threadIds);
++ boolean otherThreadsAllocatedMemory = false;
++
++ System.out.println("Verifying amount of memory allocated by threads:");
++ for (int i = 0; i < threadIds.length; i++) {
++ System.out.format("Thread %d%nbaseline allocation: %d"
++ + "%ncurrent allocation:%d%n", threadIds[i],
++ baselinedThreadMemoryUsage[i], currentMemoryAllocation[i]);
++ System.out.println(bean.getThreadInfo(threadIds[i]));
++
++ long bytesAllocated = Math.abs(currentMemoryAllocation[i]
++ - baselinedThreadMemoryUsage[i]);
++ if (bytesAllocated > 0
++ && threadIds[i] != Thread.currentThread().getId()) {
++ otherThreadsAllocatedMemory = true;
++ }
++ }
++
++ return otherThreadsAllocatedMemory;
++ }
++
++ @Override
++ public String toString() {
++ StringBuilder builder = new StringBuilder();
++
++ builder.append(String.format("SurvivorAlignmentTestMain info:%n"));
++ builder.append(String.format("Desired object size: %d%n", objectSize));
++ builder.append(String.format("Memory to fill: %d%n", memoryToFill));
++ builder.append(String.format("Objects to be allocated: %d%n",
++ garbage.length));
++
++ builder.append(String.format("Alignment helpers to be used: %n"));
++ for (HeapSpace heapSpace: HeapSpace.values()) {
++ builder.append(String.format("For space %s:%n%s%n", heapSpace,
++ getAlignmentHelper(heapSpace)));
++ }
++
++ return builder.toString();
++ }
++
++ /**
++ * Returns {@code AlignmentHelper} for a space {@code heapSpace}.
++ */
++ public static AlignmentHelper getAlignmentHelper(HeapSpace heapSpace) {
++ switch (heapSpace) {
++ case EDEN:
++ return SurvivorAlignmentTestMain.EDEN_SPACE_HELPER;
++ case SURVIVOR:
++ return SurvivorAlignmentTestMain.SURVIVOR_SPACE_HELPER;
++ case TENURED:
++ return SurvivorAlignmentTestMain.TENURED_SPACE_HELPER;
++ default:
++ throw new Error("Unexpected heap space: " + heapSpace);
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/survivorAlignment/TestAllocationInEden.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,90 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8031323
++ * @summary Verify that object's alignment in eden space is not affected by
++ * SurvivorAlignmentInBytes option.
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestAllocationInEden SurvivorAlignmentTestMain AlignmentHelper
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
++ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=32 -XX:-UseTLAB
++ * -XX:OldSize=128m -XX:MaxHeapSize=192m
++ * -XX:-ExplicitGCInvokesConcurrent
++ * TestAllocationInEden 10m 9 EDEN
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
++ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=32 -XX:-UseTLAB
++ * -XX:OldSize=128m -XX:MaxHeapSize=192m
++ * -XX:-ExplicitGCInvokesConcurrent
++ * TestAllocationInEden 10m 47 EDEN
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
++ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=64 -XX:-UseTLAB
++ * -XX:OldSize=128m -XX:MaxHeapSize=192m
++ * -XX:-ExplicitGCInvokesConcurrent
++ * TestAllocationInEden 10m 9 EDEN
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
++ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=64 -XX:-UseTLAB
++ * -XX:OldSize=128m -XX:MaxHeapSize=192m
++ * -XX:-ExplicitGCInvokesConcurrent
++ * TestAllocationInEden 10m 87 EDEN
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
++ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=128 -XX:-UseTLAB
++ * -XX:OldSize=128m -XX:MaxHeapSize=192m
++ * -XX:-ExplicitGCInvokesConcurrent
++ * TestAllocationInEden 10m 9 EDEN
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
++ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=128 -XX:-UseTLAB
++ * -XX:OldSize=128m -XX:MaxHeapSize=192m
++ * -XX:-ExplicitGCInvokesConcurrent
++ * TestAllocationInEden 10m 147 EDEN
++ */
++public class TestAllocationInEden {
++ public static void main(String args[]) {
++ SurvivorAlignmentTestMain test
++ = SurvivorAlignmentTestMain.fromArgs(args);
++ System.out.println(test);
++
++ long expectedMemoryUsage = test.getExpectedMemoryUsage();
++ test.baselineMemoryAllocation();
++ System.gc();
++
++ test.allocate();
++
++ test.verifyMemoryUsage(expectedMemoryUsage);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/survivorAlignment/TestPromotionFromEdenToTenured.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,96 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8031323
++ * @summary Verify that objects promoted from eden space to tenured space during
++ * full GC are not aligned to SurvivorAlignmentInBytes value.
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestPromotionFromEdenToTenured SurvivorAlignmentTestMain
++ * AlignmentHelper
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
++ * -XX:OldSize=32m -XX:MaxHeapSize=96m -XX:SurvivorRatio=1
++ * -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=32
++ * TestPromotionFromEdenToTenured 10m 9 TENURED
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
++ * -XX:OldSize=32m -XX:MaxHeapSize=96m -XX:SurvivorRatio=1
++ * -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=32
++ * TestPromotionFromEdenToTenured 10m 47 TENURED
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
++ * -XX:OldSize=32m -XX:MaxHeapSize=96m
++ * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=64
++ * TestPromotionFromEdenToTenured 10m 9 TENURED
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
++ * -XX:OldSize=32m -XX:MaxHeapSize=128m
++ * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=64
++ * TestPromotionFromEdenToTenured 10m 87 TENURED
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
++ * -XX:OldSize=32M -XX:MaxHeapSize=96m -XX:SurvivorRatio=1
++ * -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=128
++ * TestPromotionFromEdenToTenured 10m 9 TENURED
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m
++ * -XX:OldSize=32m -XX:MaxHeapSize=96m -XX:SurvivorRatio=1
++ * -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=128
++ * TestPromotionFromEdenToTenured 10m 147 TENURED
++ */
++public class TestPromotionFromEdenToTenured {
++ public static void main(String args[]) {
++ SurvivorAlignmentTestMain test
++ = SurvivorAlignmentTestMain.fromArgs(args);
++ System.out.println(test);
++
++ long expectedMemoryUsage = test.getExpectedMemoryUsage();
++ test.baselineMemoryAllocation();
++ System.gc();
++ // increase expected usage by current old gen usage
++ expectedMemoryUsage += SurvivorAlignmentTestMain.getAlignmentHelper(
++ SurvivorAlignmentTestMain.HeapSpace.TENURED)
++ .getActualMemoryUsage();
++
++ test.allocate();
++ System.gc();
++
++ test.verifyMemoryUsage(expectedMemoryUsage);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,101 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8031323
++ * @summary Verify that objects promoted from survivor space to tenured space
++ * during full GC are not aligned to SurvivorAlignmentInBytes value.
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestPromotionFromSurvivorToTenuredAfterFullGC
++ * SurvivorAlignmentTestMain AlignmentHelper
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
++ * -XX:OldSize=32m -XX:MaxHeapSize=160m
++ * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=32
++ * TestPromotionFromSurvivorToTenuredAfterFullGC 10m 9 TENURED
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
++ * -XX:OldSize=32m -XX:MaxHeapSize=160m
++ * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=32
++ * TestPromotionFromSurvivorToTenuredAfterFullGC 20m 47
++ * TENURED
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=200m -XX:MaxNewSize=200m
++ * -XX:OldSize=32m -XX:MaxHeapSize=232m
++ * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=64
++ * TestPromotionFromSurvivorToTenuredAfterFullGC 10m 9 TENURED
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
++ * -XX:OldSize=32m -XX:MaxHeapSize=160m
++ * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=64
++ * TestPromotionFromSurvivorToTenuredAfterFullGC 20m 87
++ * TENURED
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=256m -XX:MaxNewSize=256m
++ * -XX:OldSize=32M -XX:MaxHeapSize=288m
++ * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=128
++ * TestPromotionFromSurvivorToTenuredAfterFullGC 10m 9
++ * TENURED
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
++ * -XX:OldSize=32m -XX:MaxHeapSize=160m
++ * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=128
++ * TestPromotionFromSurvivorToTenuredAfterFullGC 20m 147
++ * TENURED
++ */
++public class TestPromotionFromSurvivorToTenuredAfterFullGC {
++ public static void main(String args[]) {
++ SurvivorAlignmentTestMain test
++ = SurvivorAlignmentTestMain.fromArgs(args);
++ System.out.println(test);
++
++ long expectedMemoryUsage = test.getExpectedMemoryUsage();
++ test.baselineMemoryAllocation();
++ System.gc();
++ // increase expected usage by current old gen usage
++ expectedMemoryUsage += SurvivorAlignmentTestMain.getAlignmentHelper(
++ SurvivorAlignmentTestMain.HeapSpace.TENURED)
++ .getActualMemoryUsage();
++
++ test.allocate();
++ SurvivorAlignmentTestMain.WHITE_BOX.youngGC();
++ System.gc();
++
++ test.verifyMemoryUsage(expectedMemoryUsage);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,106 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8031323
++ * @summary Verify that objects promoted from survivor space to tenured space
++ * when their age exceeded tenuring threshold are not aligned to
++ * SurvivorAlignmentInBytes value.
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestPromotionFromSurvivorToTenuredAfterMinorGC
++ * SurvivorAlignmentTestMain AlignmentHelper
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
++ * -XX:OldSize=32M -XX:MaxHeapSize=160m -XX:SurvivorRatio=1
++ * -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=32
++ * TestPromotionFromSurvivorToTenuredAfterMinorGC 10m 9
++ * TENURED
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
++ * -XX:OldSize=32M -XX:MaxHeapSize=160m -XX:SurvivorRatio=1
++ * -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=32
++ * TestPromotionFromSurvivorToTenuredAfterMinorGC 20m 47
++ * TENURED
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=200m -XX:MaxNewSize=200m
++ * -XX:OldSize=32M -XX:MaxHeapSize=232m -XX:SurvivorRatio=1
++ * -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=64
++ * TestPromotionFromSurvivorToTenuredAfterMinorGC 10m 9
++ * TENURED
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
++ * -XX:OldSize=32M -XX:MaxHeapSize=160m -XX:SurvivorRatio=1
++ * -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=64
++ * TestPromotionFromSurvivorToTenuredAfterMinorGC 20m 87
++ * TENURED
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=256m -XX:MaxNewSize=256m
++ * -XX:OldSize=32M -XX:MaxHeapSize=288m -XX:SurvivorRatio=1
++ * -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=128
++ * TestPromotionFromSurvivorToTenuredAfterMinorGC 10m 9
++ * TENURED
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
++ * -XX:OldSize=32M -XX:MaxHeapSize=160m -XX:SurvivorRatio=1
++ * -XX:-ExplicitGCInvokesConcurrent
++ * -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=128
++ * TestPromotionFromSurvivorToTenuredAfterMinorGC 20m 147
++ * TENURED
++ */
++public class TestPromotionFromSurvivorToTenuredAfterMinorGC {
++ public static void main(String args[]) throws Exception {
++ SurvivorAlignmentTestMain test
++ = SurvivorAlignmentTestMain.fromArgs(args);
++ System.out.println(test);
++
++ long expectedMemoryUsage = test.getExpectedMemoryUsage();
++ test.baselineMemoryAllocation();
++ SurvivorAlignmentTestMain.WHITE_BOX.fullGC();
++ // increase expected usage by current old gen usage
++ expectedMemoryUsage += SurvivorAlignmentTestMain.getAlignmentHelper(
++ SurvivorAlignmentTestMain.HeapSpace.TENURED)
++ .getActualMemoryUsage();
++
++ test.allocate();
++ for (int i = 0; i <= SurvivorAlignmentTestMain.MAX_TENURING_THRESHOLD;
++ i++) {
++ SurvivorAlignmentTestMain.WHITE_BOX.youngGC();
++ }
++
++ test.verifyMemoryUsage(expectedMemoryUsage);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/survivorAlignment/TestPromotionToSurvivor.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,86 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8031323
++ * @summary Verify that objects promoted from eden space to survivor space after
++ * minor GC are aligned to SurvivorAlignmentInBytes.
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestPromotionToSurvivor
++ * SurvivorAlignmentTestMain AlignmentHelper
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
++ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=32 -XX:OldSize=128m
++ * -XX:MaxHeapSize=256m -XX:-ExplicitGCInvokesConcurrent
++ * TestPromotionToSurvivor 10m 9 SURVIVOR
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
++ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=32 -XX:OldSize=128m
++ * -XX:MaxHeapSize=256m -XX:-ExplicitGCInvokesConcurrent
++ * TestPromotionToSurvivor 20m 47 SURVIVOR
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
++ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=64 -XX:OldSize=128m
++ * -XX:MaxHeapSize=256m -XX:-ExplicitGCInvokesConcurrent
++ * TestPromotionToSurvivor 8m 9 SURVIVOR
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
++ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=64 -XX:OldSize=128m
++ * -XX:MaxHeapSize=256m -XX:-ExplicitGCInvokesConcurrent
++ * TestPromotionToSurvivor 20m 87 SURVIVOR
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=256m -XX:MaxNewSize=256m
++ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=128 -XX:OldSize=128m
++ * -XX:MaxHeapSize=384m -XX:-ExplicitGCInvokesConcurrent
++ * TestPromotionToSurvivor 10m 9 SURVIVOR
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
++ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m
++ * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions
++ * -XX:SurvivorAlignmentInBytes=128 -XX:OldSize=128m
++ * -XX:MaxHeapSize=256m -XX:-ExplicitGCInvokesConcurrent
++ * TestPromotionToSurvivor 20m 147 SURVIVOR
++ */
++public class TestPromotionToSurvivor {
++ public static void main(String args[]) {
++ SurvivorAlignmentTestMain test
++ = SurvivorAlignmentTestMain.fromArgs(args);
++ System.out.println(test);
++
++ long expectedUsage = test.getExpectedMemoryUsage();
++ test.baselineMemoryAllocation();
++ SurvivorAlignmentTestMain.WHITE_BOX.fullGC();
++
++ test.allocate();
++ SurvivorAlignmentTestMain.WHITE_BOX.youngGC();
++
++ test.verifyMemoryUsage(expectedUsage);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/gc/whitebox/TestWBGC.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test TestWBGC
++ * @bug 8055098
++ * @summary Test verify that WB methods isObjectInOldGen and youngGC works correctly.
++ * @library /testlibrary /testlibrary/whitebox
++ * @build TestWBGC
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run driver TestWBGC
++ */
++import com.oracle.java.testlibrary.*;
++import sun.hotspot.WhiteBox;
++
++public class TestWBGC {
++
++ public static void main(String args[]) throws Exception {
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
++ true,
++ "-Xbootclasspath/a:.",
++ "-XX:+UnlockDiagnosticVMOptions",
++ "-XX:+WhiteBoxAPI",
++ "-XX:MaxTenuringThreshold=1",
++ "-XX:+PrintGC",
++ GCYoungTest.class.getName());
++
++ OutputAnalyzer output = new OutputAnalyzer(pb.start());
++ System.out.println(output.getStdout());
++ output.shouldHaveExitValue(0);
++ output.shouldContain("WhiteBox Initiated Young GC");
++ output.shouldNotContain("Full");
++ // To be sure that we don't provoke Full GC additionaly to young
++ }
++
++ public static class GCYoungTest {
++ static WhiteBox wb = WhiteBox.getWhiteBox();
++ public static Object obj;
++
++ public static void main(String args[]) {
++ obj = new Object();
++ Asserts.assertFalse(wb.isObjectInOldGen(obj));
++ wb.youngGC();
++ wb.youngGC();
++ // 2 young GC is needed to promote object into OldGen
++ Asserts.assertTrue(wb.isObjectInOldGen(obj));
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/CheckEndorsedAndExtDirs/EndorsedExtDirs.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,93 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8064667
++ * @summary Sanity test for -XX:+CheckEndorsedAndExtDirs
++ * @library /testlibrary
++ * @build com.oracle.java.testlibrary.*
++ * @run main/othervm EndorsedExtDirs
++ */
++
++import com.oracle.java.testlibrary.*;
++import java.io.File;
++import java.io.IOException;
++import java.nio.file.attribute.BasicFileAttributes;
++import java.nio.file.Files;
++import java.nio.file.Path;
++import java.nio.file.Paths;
++import java.util.ArrayList;
++import java.util.List;
++
++public class EndorsedExtDirs {
++ static final String cpath = System.getProperty("test.classes", ".");
++ public static void main(String arg[]) throws Exception {
++ fatalError("-XX:+CheckEndorsedAndExtDirs", "-Djava.endorsed.dirs=foo");
++ fatalError("-XX:+CheckEndorsedAndExtDirs", "-Djava.ext.dirs=bar");
++ testNonEmptySystemExtDirs();
++ }
++
++ static void testNonEmptySystemExtDirs() throws Exception {
++ String home = System.getProperty("java.home");
++ Path ext = Paths.get(home, "lib", "ext");
++ String extDirs = System.getProperty("java.ext.dirs");
++ String[] dirs = extDirs.split(File.pathSeparator);
++ long count = 0;
++ for (String d : dirs) {
++ Path path = Paths.get(d);
++ if (Files.notExists(path) || path.equals(ext)) continue;
++ count += Files.find(path, 1, (Path p, BasicFileAttributes attr)
++ -> p.getFileName().toString().endsWith(".jar"))
++ .count();
++ }
++ if (count > 0) {
++ fatalError("-XX:+CheckEndorsedAndExtDirs");
++ }
++ }
++
++ static ProcessBuilder newProcessBuilder(String... args) {
++ List<String> commands = new ArrayList<>();
++ String java = System.getProperty("java.home") + "/bin/java";
++ commands.add(java);
++ for (String s : args) {
++ commands.add(s);
++ }
++ commands.add("-cp");
++ commands.add(cpath);
++ commands.add("EndorsedExtDirs");
++
++ System.out.println("Process " + commands);
++ return new ProcessBuilder(commands);
++ }
++
++ static void fatalError(String... args) throws Exception {
++ fatalError(newProcessBuilder(args));
++ }
++
++ static void fatalError(ProcessBuilder pb) throws Exception {
++ OutputAnalyzer output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Could not create the Java Virtual Machine");
++ output.shouldHaveExitValue(1);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/LoadClass/ShowClassLoader.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @key regression
++ * @bug 8058927
++ * @summary Make sure array class has the right class loader
++ * @run main ShowClassLoader
++ */
++
++public class ShowClassLoader {
++
++ public static void main(String[] args) {
++ Object[] oa = new Object[0];
++ ShowClassLoader[] sa = new ShowClassLoader[0];
++
++ System.out.println("Classloader for Object[] is " + oa.getClass().getClassLoader());
++ System.out.println("Classloader for SCL[] is " + sa.getClass().getClassLoader() );
++
++ if (sa.getClass().getClassLoader() == null) {
++ throw new RuntimeException("Wrong class loader");
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/NMT/AutoshutdownNMT.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,44 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @key nmt
++ * @summary Test for deprecated message if -XX:-AutoShutdownNMT is specified
++ * @library /testlibrary
++ */
++
++import com.oracle.java.testlibrary.*;
++
++public class AutoshutdownNMT {
++
++ public static void main(String args[]) throws Exception {
++
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:NativeMemoryTracking=detail",
++ "-XX:-AutoShutdownNMT",
++ "-version");
++ OutputAnalyzer output = new OutputAnalyzer(pb.start());
++ output.shouldContain("ignoring option AutoShutdownNMT");
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/NMT/ChangeTrackingLevel.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,51 @@
++/*
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8059100
++ * @summary Test that you can decrease NMT tracking level but not increase it.
++ * @key nmt
++ * @library /testlibrary /testlibrary/whitebox
++ * @build ChangeTrackingLevel
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * sun.hotspot.WhiteBox$WhiteBoxPermission
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail ChangeTrackingLevel
++ */
++
++import com.oracle.java.testlibrary.*;
++import sun.hotspot.WhiteBox;
++
++public class ChangeTrackingLevel {
++
++ public static WhiteBox wb = WhiteBox.getWhiteBox();
++ public static void main(String args[]) throws Exception {
++ boolean testChangeLevel = wb.NMTChangeTrackingLevel();
++ if (testChangeLevel) {
++ System.out.println("NMT level change test passed.");
++ } else {
++ // it also fails if the VM asserts.
++ throw new RuntimeException("NMT level change test failed");
++ }
++ }
++};
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/NMT/JcmdBaselineDetail.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @key nmt jcmd
++ * @summary Verify that jcmd correctly reports that baseline succeeds with NMT enabled with detailed tracking.
++ * @library /testlibrary
++ * @run main/othervm -XX:NativeMemoryTracking=detail JcmdBaselineDetail
++ */
++
++import com.oracle.java.testlibrary.*;
++
++public class JcmdBaselineDetail {
++
++ public static void main(String args[]) throws Exception {
++ // Grab my own PID
++ String pid = Integer.toString(ProcessTools.getProcessId());
++ OutputAnalyzer output;
++
++ ProcessBuilder pb = new ProcessBuilder();
++
++ // Run 'jcmd <pid> VM.native_memory baseline=true'
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "baseline=true"});
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Baseline succeeded");
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/NMT/JcmdDetailDiff.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,84 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @summary run NMT baseline, allocate memory and verify output from detail.diff
++ * @key nmt jcmd
++ * @library /testlibrary /testlibrary/whitebox
++ * @ignore
++ * @build JcmdDetailDiff
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail JcmdDetailDiff
++ */
++
++import com.oracle.java.testlibrary.*;
++
++import sun.hotspot.WhiteBox;
++
++public class JcmdDetailDiff {
++
++ public static WhiteBox wb = WhiteBox.getWhiteBox();
++
++ public static void main(String args[]) throws Exception {
++ ProcessBuilder pb = new ProcessBuilder();
++ OutputAnalyzer output;
++ // Grab my own PID
++ String pid = Integer.toString(ProcessTools.getProcessId());
++
++ long commitSize = 128 * 1024;
++ long reserveSize = 256 * 1024;
++ long addr;
++
++ // Run 'jcmd <pid> VM.native_memory baseline=true'
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "baseline=true"});
++ pb.start().waitFor();
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Baseline succeeded");
++
++ addr = wb.NMTReserveMemory(reserveSize);
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail.diff", "scale=KB"});
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Test (reserved=256KB +256KB, committed=0KB)");
++
++ wb.NMTCommitMemory(addr, commitSize);
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail.diff", "scale=KB"});
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Test (reserved=256KB +256KB, committed=128KB +128KB)");
++
++ wb.NMTUncommitMemory(addr, commitSize);
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail.diff", "scale=KB"});
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Test (reserved=256KB +256KB, committed=0KB)");
++
++ wb.NMTReleaseMemory(addr, reserveSize);
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail.diff", "scale=KB"});
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldNotContain("Test (reserved=");
++ }
++}
+--- ./hotspot/test/runtime/NMT/JcmdScale.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/runtime/NMT/JcmdScale.java Wed Feb 04 12:14:39 2015 -0800
+@@ -41,15 +41,15 @@
+
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "scale=KB"});
+ output = new OutputAnalyzer(pb.start());
+- output.shouldContain("KB, committed=");
++ output.shouldContain("KB, committed=");
+
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "scale=MB"});
+ output = new OutputAnalyzer(pb.start());
+- output.shouldContain("MB, committed=");
++ output.shouldContain("MB, committed=");
+
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "scale=GB"});
+ output = new OutputAnalyzer(pb.start());
+- output.shouldContain("GB, committed=");
++ output.shouldContain("GB, committed=");
+
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "scale=apa"});
+ output = new OutputAnalyzer(pb.start());
+@@ -57,7 +57,7 @@
+
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary", "scale=GB"});
+ output = new OutputAnalyzer(pb.start());
+- output.shouldContain("GB, committed=");
++ output.shouldContain("GB, committed=");
+
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary", "scale=apa"});
+ output = new OutputAnalyzer(pb.start());
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/NMT/JcmdScaleDetail.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,66 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @key nmt jcmd
++ * @summary Test the NMT scale parameter with detail tracking level
++ * @library /testlibrary
++ * @run main/othervm -XX:NativeMemoryTracking=detail JcmdScaleDetail
++ */
++
++import com.oracle.java.testlibrary.*;
++
++public class JcmdScaleDetail {
++
++ public static void main(String args[]) throws Exception {
++ ProcessBuilder pb = new ProcessBuilder();
++ OutputAnalyzer output;
++ // Grab my own PID
++ String pid = Integer.toString(ProcessTools.getProcessId());
++
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "scale=KB"});
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("KB, committed=");
++
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "scale=MB"});
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("MB, committed=");
++
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "scale=GB"});
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("GB, committed=");
++
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "scale=apa"});
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Incorrect scale value: apa");
++
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary", "scale=GB"});
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("GB, committed=");
++
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary", "scale=apa"});
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Incorrect scale value: apa");
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/NMT/JcmdSummaryDiff.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,83 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @summary run NMT baseline, allocate memory and verify output from summary.diff
++ * @key nmt jcmd
++ * @library /testlibrary /testlibrary/whitebox
++ * @build JcmdSummaryDiff
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=summary JcmdSummaryDiff
++ */
++
++import com.oracle.java.testlibrary.*;
++
++import sun.hotspot.WhiteBox;
++
++public class JcmdSummaryDiff {
++
++ public static WhiteBox wb = WhiteBox.getWhiteBox();
++
++ public static void main(String args[]) throws Exception {
++ ProcessBuilder pb = new ProcessBuilder();
++ OutputAnalyzer output;
++ // Grab my own PID
++ String pid = Integer.toString(ProcessTools.getProcessId());
++
++ long commitSize = 128 * 1024;
++ long reserveSize = 256 * 1024;
++ long addr;
++
++ // Run 'jcmd <pid> VM.native_memory baseline=true'
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "baseline=true"});
++ pb.start().waitFor();
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Baseline succeeded");
++
++ addr = wb.NMTReserveMemory(reserveSize);
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary.diff", "scale=KB"});
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Test (reserved=256KB +256KB, committed=0KB)");
++
++ wb.NMTCommitMemory(addr, commitSize);
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary.diff", "scale=KB"});
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Test (reserved=256KB +256KB, committed=128KB +128KB)");
++
++ wb.NMTUncommitMemory(addr, commitSize);
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary.diff", "scale=KB"});
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Test (reserved=256KB +256KB, committed=0KB)");
++
++ wb.NMTReleaseMemory(addr, reserveSize);
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary.diff", "scale=KB"});
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldNotContain("Test (reserved=");
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/NMT/MallocRoundingReportTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,77 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @summary Test consistency of NMT by creating allocations of the Test type with various sizes and verifying visibility with jcmd
++ * @key nmt jcmd
++ * @library /testlibrary /testlibrary/whitebox
++ * @build MallocRoundingReportTest
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocRoundingReportTest
++ *
++ */
++
++import com.oracle.java.testlibrary.*;
++
++import sun.hotspot.WhiteBox;
++
++public class MallocRoundingReportTest {
++ private static long K = 1024;
++
++ public static void main(String args[]) throws Exception {
++ OutputAnalyzer output;
++ WhiteBox wb = WhiteBox.getWhiteBox();
++
++ // Grab my own PID
++ String pid = Integer.toString(ProcessTools.getProcessId());
++ ProcessBuilder pb = new ProcessBuilder();
++
++ long[] additionalBytes = {0, 1, 512, 650};
++ long[] kByteSize = {1024, 2048};
++ long mallocd_total = 0;
++ for ( int i = 0; i < kByteSize.length; i++)
++ {
++ for (int j = 0; j < (additionalBytes.length); j++) {
++ long curKB = kByteSize[i] + additionalBytes[j];
++ // round up/down to the nearest KB to match NMT reporting
++ long numKB = (curKB % kByteSize[i] >= 512) ? ((curKB / K) + 1) : curKB / K;
++ // Use WB API to alloc and free with the mtTest type
++ mallocd_total = wb.NMTMalloc(curKB);
++ // Run 'jcmd <pid> VM.native_memory summary', check for expected output
++ // NMT does not track memory allocations less than 1KB, and rounds to the nearest KB
++ String expectedOut = ("Test (reserved=" + numKB + "KB, committed=" + numKB + "KB)");
++
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary" });
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain(expectedOut);
++
++ wb.NMTFree(mallocd_total);
++ // Run 'jcmd <pid> VM.native_memory summary', check for expected output
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary" });
++ output = new OutputAnalyzer(pb.start());
++ output.shouldNotContain("Test (reserved=");
++ }
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/NMT/MallocSiteHashOverflow.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,78 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @summary Test corner case that overflows malloc site hashtable bucket
++ * @requires sun.arch.data.model == "32"
++ * @key nmt jcmd stress
++ * @library /testlibrary /testlibrary/whitebox
++ * @build MallocSiteHashOverflow
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocSiteHashOverflow
++ */
++
++import com.oracle.java.testlibrary.*;
++import sun.hotspot.WhiteBox;
++
++public class MallocSiteHashOverflow {
++
++ public static void main(String args[]) throws Exception {
++
++ // Size of entries based on malloc tracking header defined in mallocTracker.hpp
++ // For 32-bit systems, create 257 malloc sites with the same hash bucket to overflow a hash bucket
++ long entries = 257;
++
++ OutputAnalyzer output;
++ WhiteBox wb = WhiteBox.getWhiteBox();
++ int MAX_HASH_SIZE = wb.NMTGetHashSize();
++
++ // Grab my own PID
++ String pid = Integer.toString(ProcessTools.getProcessId());
++ ProcessBuilder pb = new ProcessBuilder();
++
++ // Verify that current tracking level is "detail"
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "statistics"});
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Native Memory Tracking Statistics");
++
++ // Attempt to cause NMT to downgrade tracking level by allocating small amounts
++ // of memory with random pseudo call stack
++ int pc = 1;
++ for (int i = 0; i < entries; i++) {
++ long addr = wb.NMTMallocWithPseudoStack(1, pc);
++ if (addr == 0) {
++ throw new RuntimeException("NMTMallocWithPseudoStack: out of memory");
++ }
++ // We free memory here since it doesn't affect pseudo malloc alloc site hash table entries
++ wb.NMTFree(addr);
++ pc += MAX_HASH_SIZE;
++ if (i == entries) {
++ // Verify that tracking has been downgraded
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "statistics"});
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Tracking level has been downgraded due to lack of resources");
++ }
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/NMT/MallocStressTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,265 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @summary Stress test for malloc tracking
++ * @key nmt jcmd stress
++ * @library /testlibrary /testlibrary/whitebox
++ * @build MallocStressTest
++ * @ignore - This test is disabled since it will stress NMT and timeout during normal testing
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocStressTest
++ */
++
++import java.util.concurrent.atomic.AtomicInteger;
++import java.util.ArrayList;
++import java.util.List;
++import java.util.Random;
++import com.oracle.java.testlibrary.*;
++import sun.hotspot.WhiteBox;
++
++public class MallocStressTest {
++ private static int K = 1024;
++
++ // The stress test runs in three phases:
++ // 1. alloc: A lot of malloc with fewer free, which simulates a burst memory allocation
++ // that is usually seen during startup or class loading.
++ // 2. pause: Pause the test to check accuracy of native memory tracking
++ // 3. release: Release all malloc'd memory and check native memory tracking result.
++ public enum TestPhase {
++ alloc,
++ pause,
++ release
++ };
++
++ static TestPhase phase = TestPhase.alloc;
++
++ // malloc'd memory
++ static ArrayList<MallocMemory> mallocd_memory = new ArrayList<MallocMemory>();
++ static long mallocd_total = 0;
++ static WhiteBox whiteBox;
++ static AtomicInteger pause_count = new AtomicInteger();
++
++ static boolean is_64_bit_system;
++
++ private static boolean is_64_bit_system() { return is_64_bit_system; }
++
++ public static void main(String args[]) throws Exception {
++ is_64_bit_system = (Platform.is64bit());
++
++ OutputAnalyzer output;
++ whiteBox = WhiteBox.getWhiteBox();
++
++ // Grab my own PID
++ String pid = Integer.toString(ProcessTools.getProcessId());
++ ProcessBuilder pb = new ProcessBuilder();
++
++ AllocThread[] alloc_threads = new AllocThread[256];
++ ReleaseThread[] release_threads = new ReleaseThread[64];
++
++ int index;
++ // Create many allocation threads
++ for (index = 0; index < alloc_threads.length; index ++) {
++ alloc_threads[index] = new AllocThread();
++ }
++
++ // Fewer release threads
++ for (index = 0; index < release_threads.length; index ++) {
++ release_threads[index] = new ReleaseThread();
++ }
++
++ if (is_64_bit_system()) {
++ sleep_wait(2*60*1000);
++ } else {
++ sleep_wait(60*1000);
++ }
++ // pause the stress test
++ phase = TestPhase.pause;
++ while (pause_count.intValue() < alloc_threads.length + release_threads.length) {
++ sleep_wait(10);
++ }
++
++ long mallocd_total_in_KB = (mallocd_total + K / 2) / K;
++
++ // Now check if the result from NMT matches the total memory allocated.
++ String expected_test_summary = "Test (reserved=" + mallocd_total_in_KB +"KB, committed=" + mallocd_total_in_KB + "KB)";
++ // Run 'jcmd <pid> VM.native_memory summary'
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"});
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain(expected_test_summary);
++
++ // Release all allocated memory
++ phase = TestPhase.release;
++ synchronized(mallocd_memory) {
++ mallocd_memory.notifyAll();
++ }
++
++ // Join all threads
++ for (index = 0; index < alloc_threads.length; index ++) {
++ try {
++ alloc_threads[index].join();
++ } catch (InterruptedException e) {
++ }
++ }
++
++ for (index = 0; index < release_threads.length; index ++) {
++ try {
++ release_threads[index].join();
++ } catch (InterruptedException e) {
++ }
++ }
++
++ // All test memory allocated should be released
++ output = new OutputAnalyzer(pb.start());
++ output.shouldNotContain("Test (reserved=");
++
++ // Verify that tracking level has not been downgraded
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "statistics"});
++ output = new OutputAnalyzer(pb.start());
++ output.shouldNotContain("Tracking level has been downgraded due to lack of resources");
++ }
++
++ private static void sleep_wait(int n) {
++ try {
++ Thread.sleep(n);
++ } catch (InterruptedException e) {
++ }
++ }
++
++
++ static class MallocMemory {
++ private long addr;
++ private int size;
++
++ MallocMemory(long addr, int size) {
++ this.addr = addr;
++ this.size = size;
++ }
++
++ long addr() { return this.addr; }
++ int size() { return this.size; }
++ }
++
++ static class AllocThread extends Thread {
++ AllocThread() {
++ this.setName("MallocThread");
++ this.start();
++ }
++
++ // AllocThread only runs "Alloc" phase
++ public void run() {
++ Random random = new Random();
++ while (MallocStressTest.phase == TestPhase.alloc) {
++ int r = Math.abs(random.nextInt());
++ // Only malloc small amount to avoid OOM
++ int size = r % 32;
++ if (is_64_bit_system()) {
++ r = r % 32 * K;
++ } else {
++ r = r % 64;
++ }
++ if (size == 0) size = 1;
++ long addr = MallocStressTest.whiteBox.NMTMallocWithPseudoStack(size, r);
++ if (addr != 0) {
++ MallocMemory mem = new MallocMemory(addr, size);
++ synchronized(MallocStressTest.mallocd_memory) {
++ MallocStressTest.mallocd_memory.add(mem);
++ MallocStressTest.mallocd_total += size;
++ }
++ } else {
++ System.out.println("Out of malloc memory");
++ break;
++ }
++ }
++ MallocStressTest.pause_count.incrementAndGet();
++ }
++ }
++
++ static class ReleaseThread extends Thread {
++ private Random random = new Random();
++ ReleaseThread() {
++ this.setName("ReleaseThread");
++ this.start();
++ }
++
++ public void run() {
++ while(true) {
++ switch(MallocStressTest.phase) {
++ case alloc:
++ slow_release();
++ break;
++ case pause:
++ enter_pause();
++ break;
++ case release:
++ quick_release();
++ return;
++ }
++ }
++ }
++
++ private void enter_pause() {
++ MallocStressTest.pause_count.incrementAndGet();
++ while (MallocStressTest.phase != MallocStressTest.TestPhase.release) {
++ try {
++ synchronized(MallocStressTest.mallocd_memory) {
++ MallocStressTest.mallocd_memory.wait(10);
++ }
++ } catch (InterruptedException e) {
++ }
++ }
++ }
++
++ private void quick_release() {
++ List<MallocMemory> free_list;
++ while (true) {
++ synchronized(MallocStressTest.mallocd_memory) {
++ if (MallocStressTest.mallocd_memory.isEmpty()) return;
++ int size = Math.min(MallocStressTest.mallocd_memory.size(), 5000);
++ List<MallocMemory> subList = MallocStressTest.mallocd_memory.subList(0, size);
++ free_list = new ArrayList<MallocMemory>(subList);
++ subList.clear();
++ }
++ for (int index = 0; index < free_list.size(); index ++) {
++ MallocMemory mem = free_list.get(index);
++ MallocStressTest.whiteBox.NMTFree(mem.addr());
++ }
++ }
++ }
++
++ private void slow_release() {
++ try {
++ Thread.sleep(10);
++ } catch (InterruptedException e) {
++ }
++ synchronized(MallocStressTest.mallocd_memory) {
++ if (MallocStressTest.mallocd_memory.isEmpty()) return;
++ int n = Math.abs(random.nextInt()) % MallocStressTest.mallocd_memory.size();
++ MallocMemory mem = mallocd_memory.remove(n);
++ MallocStressTest.whiteBox.NMTFree(mem.addr());
++ MallocStressTest.mallocd_total -= mem.size();
++ }
++ }
++ }
++}
+--- ./hotspot/test/runtime/NMT/MallocTestType.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/runtime/NMT/MallocTestType.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -51,11 +51,6 @@
+ long memAlloc1 = wb.NMTMalloc(512 * 1024);
+ wb.NMTFree(memAlloc2);
+
+- // Use WB API to ensure that all data has been merged before we continue
+- if (!wb.NMTWaitForDataMerge()) {
+- throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+- }
+-
+ // Run 'jcmd <pid> VM.native_memory summary'
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"});
+ output = new OutputAnalyzer(pb.start());
+@@ -64,10 +59,6 @@
+ // Free the memory allocated by NMTAllocTest
+ wb.NMTFree(memAlloc1);
+
+- // Use WB API to ensure that all data has been merged before we continue
+- if (!wb.NMTWaitForDataMerge()) {
+- throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+- }
+ output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("Test (reserved=");
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/NMT/MallocTrackingVerify.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,105 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8054836
++ * @summary Test to verify correctness of malloc tracking
++ * @key nmt jcmd
++ * @library /testlibrary /testlibrary/whitebox
++ * @build MallocTrackingVerify
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocTrackingVerify
++ *
++ */
++
++import java.util.ArrayList;
++import java.util.Random;
++
++import com.oracle.java.testlibrary.*;
++
++import sun.hotspot.WhiteBox;
++
++public class MallocTrackingVerify {
++ private static int MAX_ALLOC = 4 * 1024;
++
++ static ArrayList<MallocMemory> mallocd_memory = new ArrayList<MallocMemory>();
++ static long mallocd_total = 0;
++ public static WhiteBox wb = WhiteBox.getWhiteBox();
++
++ public static void main(String args[]) throws Exception {
++ OutputAnalyzer output;
++
++ // Grab my own PID
++ String pid = Integer.toString(ProcessTools.getProcessId());
++ ProcessBuilder pb = new ProcessBuilder();
++
++ Random random = new Random();
++ // Allocate small amounts of memory with random pseudo call stack
++ while (mallocd_total < MAX_ALLOC) {
++ int size = random.nextInt(31) + 1;
++ long addr = wb.NMTMallocWithPseudoStack(size, random.nextInt());
++ if (addr != 0) {
++ MallocMemory mem = new MallocMemory(addr, size);
++ mallocd_memory.add(mem);
++ mallocd_total += size;
++ } else {
++ System.out.println("Out of malloc memory");
++ break;
++ }
++ }
++
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary" });
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Test (reserved=4KB, committed=4KB)");
++
++ // Free
++ for (MallocMemory mem : mallocd_memory) {
++ wb.NMTFree(mem.addr());
++ }
++
++ // Run 'jcmd <pid> VM.native_memory summary', check for expected output
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid,
++ "VM.native_memory", "summary" });
++ output = new OutputAnalyzer(pb.start());
++ output.shouldNotContain("Test (reserved=");
++ }
++
++ static class MallocMemory {
++ private long addr;
++ private int size;
++
++ MallocMemory(long addr, int size) {
++ this.addr = addr;
++ this.size = size;
++ }
++
++ long addr() {
++ return this.addr;
++ }
++
++ int size() {
++ return this.size;
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/NMT/NMTWithCDS.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8055061
++ * @key nmt
++ * @library /testlibrary
++ * @run main NMTWithCDS
++ */
++import com.oracle.java.testlibrary.*;
++
++public class NMTWithCDS {
++
++ public static void main(String[] args) throws Exception {
++ ProcessBuilder pb;
++ pb = ProcessTools.createJavaProcessBuilder("-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
++ OutputAnalyzer output = new OutputAnalyzer(pb.start());
++ try {
++ output.shouldContain("Loading classes to share");
++ output.shouldHaveExitValue(0);
++
++ pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:NativeMemoryTracking=detail", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("sharing");
++ output.shouldHaveExitValue(0);
++
++ } catch (RuntimeException e) {
++ // Report 'passed' if CDS was turned off.
++ output.shouldContain("Unable to use shared archive");
++ output.shouldHaveExitValue(1);
++ }
++ }
++}
+--- ./hotspot/test/runtime/NMT/PrintNMTStatistics.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/runtime/NMT/PrintNMTStatistics.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,46 +24,40 @@
+ /*
+ * @test
+ * @key nmt regression
+- * @bug 8005936
+- * @summary Make sure PrintNMTStatistics works on normal JVM exit
+- * @library /testlibrary /testlibrary/whitebox
+- * @build PrintNMTStatistics
+- * @run main ClassFileInstaller sun.hotspot.WhiteBox
+- * @run main PrintNMTStatistics
++ * @bug 8005936 8058606
++ * @summary Verify PrintNMTStatistics on normal JVM exit for detail and summary tracking level
++ * @library /testlibrary
+ */
+
+ import com.oracle.java.testlibrary.*;
+
+-import java.util.regex.Matcher;
+-import java.util.regex.Pattern;
+-import sun.hotspot.WhiteBox;
+-
+ public class PrintNMTStatistics {
+
+- public static void main(String args[]) throws Exception {
+-
+- // We start a new java process running with an argument and use WB API to ensure
+- // we have data for NMT on VM exit
+- if (args.length > 0) {
+- // Use WB API to ensure that all data has been merged before we continue
+- if (!WhiteBox.getWhiteBox().NMTWaitForDataMerge()) {
+- throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+- }
+- return;
+- }
++ public static void main(String args[]) throws Exception {
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+- "-XX:+UnlockDiagnosticVMOptions",
+- "-Xbootclasspath/a:.",
+- "-XX:+WhiteBoxAPI",
+- "-XX:NativeMemoryTracking=summary",
+- "-XX:+PrintNMTStatistics",
+- "PrintNMTStatistics",
+- "test");
++ "-XX:+UnlockDiagnosticVMOptions",
++ "-XX:+PrintNMTStatistics",
++ "-XX:NativeMemoryTracking=detail",
++ "-version");
+
+- OutputAnalyzer output = new OutputAnalyzer(pb.start());
+- output.shouldContain("Java Heap (reserved=");
+- output.shouldNotContain("error");
+- output.shouldHaveExitValue(0);
+- }
++ OutputAnalyzer output_detail = new OutputAnalyzer(pb.start());
++ output_detail.shouldContain("Virtual memory map:");
++ output_detail.shouldContain("Details:");
++ output_detail.shouldNotContain("error");
++ output_detail.shouldHaveExitValue(0);
++
++ ProcessBuilder pb1 = ProcessTools.createJavaProcessBuilder(
++ "-XX:+UnlockDiagnosticVMOptions",
++ "-XX:+PrintNMTStatistics",
++ "-XX:NativeMemoryTracking=summary",
++ "-version");
++
++ OutputAnalyzer output_summary = new OutputAnalyzer(pb1.start());
++ output_summary.shouldContain("Java Heap (reserved=");
++ output_summary.shouldNotContain("Virtual memory map:");
++ output_summary.shouldNotContain("Details:");
++ output_summary.shouldNotContain("error");
++ output_summary.shouldHaveExitValue(0);
++ }
+ }
+--- ./hotspot/test/runtime/NMT/ReleaseCommittedMemory.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/runtime/NMT/ReleaseCommittedMemory.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -44,7 +44,6 @@
+ addr = wb.NMTReserveMemory(reserveSize);
+ wb.NMTCommitMemory(addr, 128*1024);
+ wb.NMTReleaseMemory(addr, reserveSize);
+- wb.NMTWaitForDataMerge();
+ }
+ }
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/NMT/ReleaseNoCommit.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,64 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @summary Release uncommitted memory and make sure NMT handles it correctly
++ * @key nmt regression
++ * @library /testlibrary /testlibrary/whitebox
++ * @build ReleaseNoCommit
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=summary ReleaseNoCommit
++ */
++
++import com.oracle.java.testlibrary.JDKToolFinder;
++import com.oracle.java.testlibrary.OutputAnalyzer;
++import com.oracle.java.testlibrary.ProcessTools;
++
++import sun.hotspot.WhiteBox;
++
++public class ReleaseNoCommit {
++
++ public static void main(String args[]) throws Exception {
++ WhiteBox wb = WhiteBox.getWhiteBox();
++ long reserveSize = 256 * 1024;
++ long addr;
++
++ ProcessBuilder pb = new ProcessBuilder();
++ OutputAnalyzer output;
++ // Grab my own PID
++ String pid = Integer.toString(ProcessTools.getProcessId());
++
++ addr = wb.NMTReserveMemory(reserveSize);
++ // Check for reserved
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "scale=KB"});
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain(" Test (reserved=256KB, committed=0KB)");
++
++ wb.NMTReleaseMemory(addr, reserveSize);
++
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "scale=KB"});
++ output = new OutputAnalyzer(pb.start());
++ output.shouldNotContain("Test (reserved=");
++ }
++}
+--- ./hotspot/test/runtime/NMT/ShutdownTwice.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/runtime/NMT/ShutdownTwice.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -45,12 +45,12 @@
+ output = new OutputAnalyzer(pb.start());
+
+ // Verify that jcmd reports that NMT is shutting down
+- output.shouldContain("Shutdown is in progress, it will take a few moments to completely shutdown");
++ output.shouldContain("Native memory tracking has been turned off");
+
+ // Run shutdown again
+ output = new OutputAnalyzer(pb.start());
+
+ // Verify that jcmd reports that NMT has been shutdown already
+- output.shouldContain("Native memory tracking has been shutdown by user");
++ output.shouldContain("Native memory tracking has been shutdown");
+ }
+ }
+--- ./hotspot/test/runtime/NMT/SummaryAfterShutdown.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/runtime/NMT/SummaryAfterShutdown.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -44,13 +44,13 @@
+ output = new OutputAnalyzer(pb.start());
+
+ // Verify that jcmd reports that NMT is shutting down
+- output.shouldContain("Shutdown is in progress, it will take a few moments to completely shutdown");
++ output.shouldContain("Native memory tracking has been turned off");
+
+ // Run 'jcmd <pid> VM.native_memory summary'
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"});
+ output = new OutputAnalyzer(pb.start());
+
+ // Verify that jcmd reports that NMT has been shutdown
+- output.shouldContain("Native memory tracking has been shutdown by user");
++ output.shouldContain("Native memory tracking has been shutdown");
+ }
+ }
+--- ./hotspot/test/runtime/NMT/SummarySanityCheck.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/runtime/NMT/SummarySanityCheck.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -44,11 +44,6 @@
+ // Grab my own PID
+ String pid = Integer.toString(ProcessTools.getProcessId());
+
+- // Use WB API to ensure that all data has been merged before we continue
+- if (!WhiteBox.getWhiteBox().NMTWaitForDataMerge()) {
+- throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+- }
+-
+ ProcessBuilder pb = new ProcessBuilder();
+
+ // Run 'jcmd <pid> VM.native_memory summary scale=KB'
+@@ -69,13 +64,13 @@
+ // Match '- <mtType> (reserved=<reserved>KB, committed=<committed>KB)
+ Pattern mtTypePattern = Pattern.compile("-\\s+(?<typename>[\\w\\s]+)\\(reserved=(?<reserved>\\d+)KB,\\scommitted=(?<committed>\\d+)KB\\)");
+ // Match 'Total: reserved=<reserved>KB, committed=<committed>KB'
+- Pattern totalMemoryPattern = Pattern.compile("Total\\:\\s\\sreserved=(?<reserved>\\d+)KB,\\s\\scommitted=(?<committed>\\d+)KB");
++ Pattern totalMemoryPattern = Pattern.compile("Total\\:\\sreserved=(?<reserved>\\d+)KB,\\scommitted=(?<committed>\\d+)KB");
+
+ for (int i = 0; i < lines.length; i++) {
+ if (lines[i].startsWith("Total")) {
+ Matcher totalMemoryMatcher = totalMemoryPattern.matcher(lines[i]);
+
+- if (totalMemoryMatcher.matches() && totalMemoryMatcher.groupCount() == 2) {
++ if (totalMemoryMatcher.matches()) {
+ totalCommitted = Integer.parseInt(totalMemoryMatcher.group("committed"));
+ totalReserved = Integer.parseInt(totalMemoryMatcher.group("reserved"));
+ } else {
+--- ./hotspot/test/runtime/NMT/ThreadedMallocTestType.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/runtime/NMT/ThreadedMallocTestType.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -58,11 +58,6 @@
+ allocThread.start();
+ allocThread.join();
+
+- // Use WB API to ensure that all data has been merged before we continue
+- if (!wb.NMTWaitForDataMerge()) {
+- throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+- }
+-
+ // Run 'jcmd <pid> VM.native_memory summary'
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"});
+ output = new OutputAnalyzer(pb.start());
+@@ -80,11 +75,6 @@
+ freeThread.start();
+ freeThread.join();
+
+- // Use WB API to ensure that all data has been merged before we continue
+- if (!wb.NMTWaitForDataMerge()) {
+- throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+- }
+-
+ output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("Test (reserved=");
+ }
+--- ./hotspot/test/runtime/NMT/ThreadedVirtualAllocTestType.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/runtime/NMT/ThreadedVirtualAllocTestType.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -60,8 +60,6 @@
+ reserveThread.start();
+ reserveThread.join();
+
+- mergeData();
+-
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail"});
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Test (reserved=512KB, committed=0KB)");
+@@ -77,8 +75,6 @@
+ commitThread.start();
+ commitThread.join();
+
+- mergeData();
+-
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Test (reserved=512KB, committed=128KB)");
+ if (has_nmt_detail) {
+@@ -93,8 +89,6 @@
+ uncommitThread.start();
+ uncommitThread.join();
+
+- mergeData();
+-
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Test (reserved=512KB, committed=0KB)");
+ output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + commitSize) + "\\] committed");
+@@ -107,17 +101,9 @@
+ releaseThread.start();
+ releaseThread.join();
+
+- mergeData();
+-
+ output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("Test (reserved=");
+ output.shouldNotContain("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved");
+ }
+
+- public static void mergeData() throws Exception {
+- // Use WB API to ensure that all data has been merged before we continue
+- if (!wb.NMTWaitForDataMerge()) {
+- throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+ }
+- }
+-}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/NMT/VirtualAllocCommitUncommitRecommit.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,165 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @summary Test reserve/commit/uncommit/release of virtual memory and that we track it correctly
++ * @key nmt jcmd
++ * @library /testlibrary /testlibrary/whitebox
++ * @build VirtualAllocCommitUncommitRecommit
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail VirtualAllocCommitUncommitRecommit
++ *
++ */
++
++import com.oracle.java.testlibrary.*;
++
++import sun.hotspot.WhiteBox;
++
++public class VirtualAllocCommitUncommitRecommit {
++
++ public static WhiteBox wb = WhiteBox.getWhiteBox();
++
++ public static void main(String args[]) throws Exception {
++ OutputAnalyzer output;
++ long commitSize = 4 * 1024; // 4KB
++ long reserveSize = 1024 * 1024; // 1024KB
++ long addr;
++
++ String pid = Integer.toString(ProcessTools.getProcessId());
++ ProcessBuilder pb = new ProcessBuilder();
++
++ boolean has_nmt_detail = wb.NMTIsDetailSupported();
++ if (has_nmt_detail) {
++ System.out.println("NMT detail support detected.");
++ } else {
++ System.out.println("NMT detail support not detected.");
++ }
++
++ // reserve
++ addr = wb.NMTReserveMemory(reserveSize);
++ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid,
++ "VM.native_memory", "detail" });
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Test (reserved=1024KB, committed=0KB)");
++ if (has_nmt_detail) {
++ output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
++ + Long.toHexString(addr + reserveSize)
++ + "\\] reserved 1024KB for Test");
++ }
++
++ long addrA = addr;
++ long addrB = addr + commitSize;
++ long addrC = addr + (2 * commitSize);
++ long addrD = addr + (3 * commitSize);
++ long addrE = addr + (4 * commitSize);
++ long addrF = addr + (5 * commitSize);
++
++ // commit ABCD
++ wb.NMTCommitMemory(addrA, commitSize);
++ wb.NMTCommitMemory(addrB, commitSize);
++ wb.NMTCommitMemory(addrC, commitSize);
++ wb.NMTCommitMemory(addrD, commitSize);
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Test (reserved=1024KB, committed=16KB)");
++
++ if (has_nmt_detail) {
++ output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
++ + Long.toHexString(addr + reserveSize)
++ + "\\] reserved 1024KB for Test");
++ }
++ // uncommit BC
++ wb.NMTUncommitMemory(addrB, commitSize);
++ wb.NMTUncommitMemory(addrC, commitSize);
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Test (reserved=1024KB, committed=8KB)");
++
++ if (has_nmt_detail) {
++ output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
++ + Long.toHexString(addr + reserveSize)
++ + "\\] reserved 1024KB for Test");
++ }
++
++ // commit EF
++ wb.NMTCommitMemory(addrE, commitSize);
++ wb.NMTCommitMemory(addrF, commitSize);
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Test (reserved=1024KB, committed=16KB)");
++ if (has_nmt_detail) {
++ output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
++ + Long.toHexString(addr + reserveSize)
++ + "\\] reserved 1024KB for Test");
++ }
++
++ // uncommit A
++ wb.NMTUncommitMemory(addrA, commitSize);
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Test (reserved=1024KB, committed=12KB)");
++ if (has_nmt_detail) {
++ output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
++ + Long.toHexString(addr + reserveSize)
++ + "\\] reserved 1024KB for Test");
++ }
++
++ // commit ABC
++ wb.NMTCommitMemory(addrA, commitSize);
++ wb.NMTCommitMemory(addrB, commitSize);
++ wb.NMTCommitMemory(addrC, commitSize);
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Test (reserved=1024KB, committed=24KB)");
++ if (has_nmt_detail) {
++ output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
++ + Long.toHexString(addr + reserveSize)
++ + "\\] reserved 1024KB for Test");
++ }
++
++ // uncommit ABCDEF
++ wb.NMTUncommitMemory(addrA, commitSize);
++ wb.NMTUncommitMemory(addrB, commitSize);
++ wb.NMTUncommitMemory(addrC, commitSize);
++ wb.NMTUncommitMemory(addrD, commitSize);
++ wb.NMTUncommitMemory(addrE, commitSize);
++ wb.NMTUncommitMemory(addrF, commitSize);
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Test (reserved=1024KB, committed=0KB)");
++ if (has_nmt_detail) {
++ output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
++ + Long.toHexString(addr + reserveSize)
++ + "\\] reserved 1024KB for Test");
++ }
++
++ // release
++ wb.NMTReleaseMemory(addr, reserveSize);
++ output = new OutputAnalyzer(pb.start());
++ output.shouldNotContain("Test (reserved=");
++ output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
++ + Long.toHexString(addr + reserveSize) + "\\] reserved 1024KB for Test");
++ }
++}
+--- ./hotspot/test/runtime/NMT/VirtualAllocTestType.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/runtime/NMT/VirtualAllocTestType.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -54,7 +54,6 @@
+ }
+
+ addr = wb.NMTReserveMemory(reserveSize);
+- mergeData();
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail"});
+
+ output = new OutputAnalyzer(pb.start());
+@@ -65,7 +64,6 @@
+
+ wb.NMTCommitMemory(addr, commitSize);
+
+- mergeData();
+
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Test (reserved=256KB, committed=128KB)");
+@@ -75,24 +73,15 @@
+
+ wb.NMTUncommitMemory(addr, commitSize);
+
+- mergeData();
+
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Test (reserved=256KB, committed=0KB)");
+ output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + commitSize) + "\\] committed");
+
+ wb.NMTReleaseMemory(addr, reserveSize);
+- mergeData();
+
+ output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("Test (reserved=");
+ output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved");
+ }
+-
+- public static void mergeData() throws Exception {
+- // Use WB API to ensure that all data has been merged before we continue
+- if (!wb.NMTWaitForDataMerge()) {
+- throw new Exception("Call to WB API NMTWaitForDataMerge() failed");
+ }
+- }
+-}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/RedefineTests/RedefineAnnotations.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,410 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @library /testlibrary
++ * @summary Test that type annotations are retained after a retransform
++ * @run main RedefineAnnotations buildagent
++ * @run main/othervm -javaagent:redefineagent.jar RedefineAnnotations
++ */
++
++import static com.oracle.java.testlibrary.Asserts.assertTrue;
++import java.io.FileNotFoundException;
++import java.io.PrintWriter;
++import java.lang.NoSuchFieldException;
++import java.lang.NoSuchMethodException;
++import java.lang.RuntimeException;
++import java.lang.annotation.Annotation;
++import java.lang.annotation.ElementType;
++import java.lang.annotation.Retention;
++import java.lang.annotation.RetentionPolicy;
++import java.lang.annotation.Target;
++import java.lang.instrument.ClassFileTransformer;
++import java.lang.instrument.IllegalClassFormatException;
++import java.lang.instrument.Instrumentation;
++import java.lang.instrument.UnmodifiableClassException;
++import java.lang.reflect.AnnotatedArrayType;
++import java.lang.reflect.AnnotatedParameterizedType;
++import java.lang.reflect.AnnotatedType;
++import java.lang.reflect.AnnotatedWildcardType;
++import java.lang.reflect.Executable;
++import java.lang.reflect.TypeVariable;
++import java.security.ProtectionDomain;
++import java.util.Arrays;
++import java.util.LinkedList;
++import java.util.List;
++import java.util.Map;
++import jdk.internal.org.objectweb.asm.ClassReader;
++import jdk.internal.org.objectweb.asm.ClassVisitor;
++import jdk.internal.org.objectweb.asm.ClassWriter;
++import jdk.internal.org.objectweb.asm.FieldVisitor;
++import static jdk.internal.org.objectweb.asm.Opcodes.ASM5;
++
++@Retention(RetentionPolicy.RUNTIME)
++@Target(ElementType.TYPE_USE)
++@interface TestAnn {
++ String site();
++}
++
++public class RedefineAnnotations {
++ static Instrumentation inst;
++ public static void premain(String agentArgs, Instrumentation inst) {
++ RedefineAnnotations.inst = inst;
++ }
++
++ static class Transformer implements ClassFileTransformer {
++
++ public byte[] asm(ClassLoader loader, String className,
++ Class<?> classBeingRedefined,
++ ProtectionDomain protectionDomain, byte[] classfileBuffer)
++ throws IllegalClassFormatException {
++
++ ClassWriter cw = new ClassWriter(0);
++ ClassVisitor cv = new ReAddDummyFieldsClassVisitor(ASM5, cw) { };
++ ClassReader cr = new ClassReader(classfileBuffer);
++ cr.accept(cv, 0);
++ return cw.toByteArray();
++ }
++
++ public class ReAddDummyFieldsClassVisitor extends ClassVisitor {
++
++ LinkedList<F> fields = new LinkedList<>();
++
++ public ReAddDummyFieldsClassVisitor(int api, ClassVisitor cv) {
++ super(api, cv);
++ }
++
++ @Override public FieldVisitor visitField(int access, String name,
++ String desc, String signature, Object value) {
++ if (name.startsWith("dummy")) {
++ // Remove dummy field
++ fields.addLast(new F(access, name, desc, signature, value));
++ return null;
++ }
++ return cv.visitField(access, name, desc, signature, value);
++ }
++
++ @Override public void visitEnd() {
++ F f;
++ while ((f = fields.pollFirst()) != null) {
++ // Re-add dummy fields
++ cv.visitField(f.access, f.name, f.desc, f.signature, f.value);
++ }
++ }
++
++ private class F {
++ private int access;
++ private String name;
++ private String desc;
++ private String signature;
++ private Object value;
++ F(int access, String name, String desc, String signature, Object value) {
++ this.access = access;
++ this.name = name;
++ this.desc = desc;
++ this.signature = signature;
++ this.value = value;
++ }
++ }
++ }
++
++ @Override public byte[] transform(ClassLoader loader, String className,
++ Class<?> classBeingRedefined,
++ ProtectionDomain protectionDomain, byte[] classfileBuffer)
++ throws IllegalClassFormatException {
++
++ if (className.contains("TypeAnnotatedTestClass")) {
++ try {
++ // Here we remove and re-add the dummy fields. This shuffles the constant pool
++ return asm(loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
++ } catch (Throwable e) {
++ // The retransform native code that called this method does not propagate
++ // exceptions. Instead of getting an uninformative generic error, catch
++ // problems here and print it, then exit.
++ e.printStackTrace();
++ System.exit(1);
++ }
++ }
++ return null;
++ }
++ }
++
++ private static void buildAgent() {
++ try {
++ ClassFileInstaller.main("RedefineAnnotations");
++ } catch (Exception e) {
++ throw new RuntimeException("Could not write agent classfile", e);
++ }
++
++ try {
++ PrintWriter pw = new PrintWriter("MANIFEST.MF");
++ pw.println("Premain-Class: RedefineAnnotations");
++ pw.println("Agent-Class: RedefineAnnotations");
++ pw.println("Can-Retransform-Classes: true");
++ pw.close();
++ } catch (FileNotFoundException e) {
++ throw new RuntimeException("Could not write manifest file for the agent", e);
++ }
++
++ sun.tools.jar.Main jarTool = new sun.tools.jar.Main(System.out, System.err, "jar");
++ if (!jarTool.run(new String[] { "-cmf", "MANIFEST.MF", "redefineagent.jar", "RedefineAnnotations.class" })) {
++ throw new RuntimeException("Could not write the agent jar file");
++ }
++ }
++
++ public static void main(String argv[]) throws NoSuchFieldException, NoSuchMethodException {
++ if (argv.length == 1 && argv[0].equals("buildagent")) {
++ buildAgent();
++ return;
++ }
++
++ if (inst == null) {
++ throw new RuntimeException("Instrumentation object was null");
++ }
++
++ RedefineAnnotations test = new RedefineAnnotations();
++ test.testTransformAndVerify();
++ }
++
++ // Class type annotations
++ private Annotation classTypeParameterTA;
++ private Annotation extendsTA;
++ private Annotation implementsTA;
++
++ // Field type annotations
++ private Annotation fieldTA;
++ private Annotation innerTA;
++ private Annotation[] arrayTA = new Annotation[4];
++ private Annotation[] mapTA = new Annotation[5];
++
++ // Method type annotations
++ private Annotation returnTA, methodTypeParameterTA, formalParameterTA, throwsTA;
++
++ private void testTransformAndVerify()
++ throws NoSuchFieldException, NoSuchMethodException {
++
++ Class<TypeAnnotatedTestClass> c = TypeAnnotatedTestClass.class;
++ Class<?> myClass = c;
++
++ /*
++ * Verify that the expected annotations are where they should be before transform.
++ */
++ verifyClassTypeAnnotations(c);
++ verifyFieldTypeAnnotations(c);
++ verifyMethodTypeAnnotations(c);
++
++ try {
++ inst.addTransformer(new Transformer(), true);
++ inst.retransformClasses(myClass);
++ } catch (UnmodifiableClassException e) {
++ throw new RuntimeException(e);
++ }
++
++ /*
++ * Verify that the expected annotations are where they should be after transform.
++ * Also verify that before and after are equal.
++ */
++ verifyClassTypeAnnotations(c);
++ verifyFieldTypeAnnotations(c);
++ verifyMethodTypeAnnotations(c);
++ }
++
++ private void verifyClassTypeAnnotations(Class c) {
++ Annotation anno;
++
++ anno = c.getTypeParameters()[0].getAnnotations()[0];
++ verifyTestAnn(classTypeParameterTA, anno, "classTypeParameter");
++ classTypeParameterTA = anno;
++
++ anno = c.getAnnotatedSuperclass().getAnnotations()[0];
++ verifyTestAnn(extendsTA, anno, "extends");
++ extendsTA = anno;
++
++ anno = c.getAnnotatedInterfaces()[0].getAnnotations()[0];
++ verifyTestAnn(implementsTA, anno, "implements");
++ implementsTA = anno;
++ }
++
++ private void verifyFieldTypeAnnotations(Class c)
++ throws NoSuchFieldException, NoSuchMethodException {
++
++ verifyBasicFieldTypeAnnotations(c);
++ verifyInnerFieldTypeAnnotations(c);
++ verifyArrayFieldTypeAnnotations(c);
++ verifyMapFieldTypeAnnotations(c);
++ }
++
++ private void verifyBasicFieldTypeAnnotations(Class c)
++ throws NoSuchFieldException, NoSuchMethodException {
++
++ Annotation anno = c.getDeclaredField("typeAnnotatedBoolean").getAnnotatedType().getAnnotations()[0];
++ verifyTestAnn(fieldTA, anno, "field");
++ fieldTA = anno;
++ }
++
++ private void verifyInnerFieldTypeAnnotations(Class c)
++ throws NoSuchFieldException, NoSuchMethodException {
++
++ AnnotatedType at = c.getDeclaredField("typeAnnotatedInner").getAnnotatedType();
++ Annotation anno = at.getAnnotations()[0];
++ verifyTestAnn(innerTA, anno, "inner");
++ innerTA = anno;
++ }
++
++ private void verifyArrayFieldTypeAnnotations(Class c)
++ throws NoSuchFieldException, NoSuchMethodException {
++
++ Annotation anno;
++ AnnotatedType at;
++
++ at = c.getDeclaredField("typeAnnotatedArray").getAnnotatedType();
++ anno = at.getAnnotations()[0];
++ verifyTestAnn(arrayTA[0], anno, "array1");
++ arrayTA[0] = anno;
++
++ for (int i = 1; i <= 3; i++) {
++ at = ((AnnotatedArrayType) at).getAnnotatedGenericComponentType();
++ anno = at.getAnnotations()[0];
++ verifyTestAnn(arrayTA[i], anno, "array" + (i + 1));
++ arrayTA[i] = anno;
++ }
++ }
++
++ private void verifyMapFieldTypeAnnotations(Class c)
++ throws NoSuchFieldException, NoSuchMethodException {
++
++ Annotation anno;
++ AnnotatedType atBase;
++ AnnotatedType atParameter;
++ atBase = c.getDeclaredField("typeAnnotatedMap").getAnnotatedType();
++
++ anno = atBase.getAnnotations()[0];
++ verifyTestAnn(mapTA[0], anno, "map1");
++ mapTA[0] = anno;
++
++ atParameter =
++ ((AnnotatedParameterizedType) atBase).
++ getAnnotatedActualTypeArguments()[0];
++ anno = ((AnnotatedWildcardType) atParameter).getAnnotations()[0];
++ verifyTestAnn(mapTA[1], anno, "map2");
++ mapTA[1] = anno;
++
++ anno =
++ ((AnnotatedWildcardType) atParameter).
++ getAnnotatedUpperBounds()[0].getAnnotations()[0];
++ verifyTestAnn(mapTA[2], anno, "map3");
++ mapTA[2] = anno;
++
++ atParameter =
++ ((AnnotatedParameterizedType) atBase).
++ getAnnotatedActualTypeArguments()[1];
++ anno = ((AnnotatedParameterizedType) atParameter).getAnnotations()[0];
++ verifyTestAnn(mapTA[3], anno, "map4");
++ mapTA[3] = anno;
++
++ anno =
++ ((AnnotatedParameterizedType) atParameter).
++ getAnnotatedActualTypeArguments()[0].getAnnotations()[0];
++ verifyTestAnn(mapTA[4], anno, "map5");
++ mapTA[4] = anno;
++ }
++
++ private void verifyMethodTypeAnnotations(Class c)
++ throws NoSuchFieldException, NoSuchMethodException {
++ Annotation anno;
++ Executable typeAnnotatedMethod =
++ c.getDeclaredMethod("typeAnnotatedMethod", TypeAnnotatedTestClass.class);
++
++ anno = typeAnnotatedMethod.getAnnotatedReturnType().getAnnotations()[0];
++ verifyTestAnn(returnTA, anno, "return");
++ returnTA = anno;
++
++ anno = typeAnnotatedMethod.getTypeParameters()[0].getAnnotations()[0];
++ verifyTestAnn(methodTypeParameterTA, anno, "methodTypeParameter");
++ methodTypeParameterTA = anno;
++
++ anno = typeAnnotatedMethod.getAnnotatedParameterTypes()[0].getAnnotations()[0];
++ verifyTestAnn(formalParameterTA, anno, "formalParameter");
++ formalParameterTA = anno;
++
++ anno = typeAnnotatedMethod.getAnnotatedExceptionTypes()[0].getAnnotations()[0];
++ verifyTestAnn(throwsTA, anno, "throws");
++ throwsTA = anno;
++ }
++
++ private static void verifyTestAnn(Annotation verifyAgainst, Annotation anno, String expectedSite) {
++ verifyTestAnnSite(anno, expectedSite);
++
++ // When called before transform verifyAgainst will be null, when called
++ // after transform it will be the annotation from before the transform
++ if (verifyAgainst != null) {
++ assertTrue(anno.equals(verifyAgainst),
++ "Annotations do not match before and after." +
++ " Before: \"" + verifyAgainst + "\", After: \"" + anno + "\"");
++ }
++ }
++
++ private static void verifyTestAnnSite(Annotation testAnn, String expectedSite) {
++ String expectedAnn = "@TestAnn(site=" + expectedSite + ")";
++ assertTrue(testAnn.toString().equals(expectedAnn),
++ "Expected \"" + expectedAnn + "\", got \"" + testAnn + "\"");
++ }
++
++ public static class TypeAnnotatedTestClass <@TestAnn(site="classTypeParameter") S,T>
++ extends @TestAnn(site="extends") Thread
++ implements @TestAnn(site="implements") Runnable {
++
++ public @TestAnn(site="field") boolean typeAnnotatedBoolean;
++
++ public
++ RedefineAnnotations.
++ @TestAnn(site="inner") TypeAnnotatedTestClass
++ typeAnnotatedInner;
++
++ public
++ @TestAnn(site="array4") boolean
++ @TestAnn(site="array1") []
++ @TestAnn(site="array2") []
++ @TestAnn(site="array3") []
++ typeAnnotatedArray;
++
++ public @TestAnn(site="map1") Map
++ <@TestAnn(site="map2") ? extends @TestAnn(site="map3") String,
++ @TestAnn(site="map4") List<@TestAnn(site="map5") Object>> typeAnnotatedMap;
++
++ public int dummy1;
++ public int dummy2;
++ public int dummy3;
++
++ @TestAnn(site="return") <@TestAnn(site="methodTypeParameter") U,V> Class
++ typeAnnotatedMethod(@TestAnn(site="formalParameter") TypeAnnotatedTestClass arg)
++ throws @TestAnn(site="throws") ClassNotFoundException {
++
++ @TestAnn(site="local_variable_type") int foo = 0;
++ throw new ClassNotFoundException();
++ }
++
++ public void run() {}
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/SharedArchiveFile/ArchiveDoesNotExist.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,68 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test ArchiveDoesNotExist
++ * @summary Test how VM handles "file does not exist" situation while
++ * attempting to use CDS archive. JVM should exit gracefully
++ * when sharing mode is ON, and continue w/o sharing if sharing
++ * mode is AUTO.
++ * @library /testlibrary
++ * @run main ArchiveDoesNotExist
++ */
++
++import com.oracle.java.testlibrary.*;
++import java.io.File;
++
++public class ArchiveDoesNotExist {
++ public static void main(String[] args) throws Exception {
++ String fileName = "test.jsa";
++
++ File cdsFile = new File(fileName);
++ if (cdsFile.exists())
++ throw new RuntimeException("Test error: cds file already exists");
++
++ // Sharing: on
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:+UnlockDiagnosticVMOptions",
++ "-XX:SharedArchiveFile=./" + fileName,
++ "-Xshare:on",
++ "-version");
++
++ OutputAnalyzer output = new OutputAnalyzer(pb.start());
++ output.shouldContain("Specified shared archive not found");
++ output.shouldHaveExitValue(1);
++
++ // Sharing: auto
++ pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:+UnlockDiagnosticVMOptions",
++ "-XX:SharedArchiveFile=./" + fileName,
++ "-Xshare:auto",
++ "-version");
++
++ output = new OutputAnalyzer(pb.start());
++ output.shouldMatch("(java|openjdk) version");
++ output.shouldNotContain("sharing");
++ output.shouldHaveExitValue(0);
++ }
++}
+--- ./hotspot/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java Wed Feb 04 12:14:39 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -29,6 +29,7 @@
+ * is different from object alignment for creating a CDS file
+ * should fail when loading.
+ * @library /testlibrary
++ * @bug 8025642
+ */
+
+ import com.oracle.java.testlibrary.*;
+@@ -82,7 +83,11 @@
+ createAlignment,
+ loadAlignment);
+
+- output.shouldContain(expectedErrorMsg);
++ try {
++ output.shouldContain(expectedErrorMsg);
++ } catch (RuntimeException e) {
++ output.shouldContain("Unable to use shared archive");
++ }
+ output.shouldHaveExitValue(1);
+ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/SharedArchiveFile/DefaultUseWithClient.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,72 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test DefaultUseWithClient
++ * @summary Test default behavior of sharing with -client
++ * @library /testlibrary
++ * @run main DefaultUseWithClient
++ * @bug 8032224
++ */
++
++import com.oracle.java.testlibrary.*;
++import java.io.File;
++
++public class DefaultUseWithClient {
++ public static void main(String[] args) throws Exception {
++ String fileName = "test.jsa";
++
++ // On 32-bit windows CDS should be on by default in "-client" config
++ // Skip this test on any other platform
++ boolean is32BitWindows = (Platform.isWindows() && Platform.is32bit());
++ if (!is32BitWindows) {
++ System.out.println("Test only applicable on 32-bit Windows. Skipping");
++ return;
++ }
++
++ // create the archive
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:+UnlockDiagnosticVMOptions",
++ "-XX:SharedArchiveFile=./" + fileName,
++ "-Xshare:dump");
++ OutputAnalyzer output = new OutputAnalyzer(pb.start());
++ output.shouldHaveExitValue(0);
++
++ pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:+UnlockDiagnosticVMOptions",
++ "-XX:SharedArchiveFile=./" + fileName,
++ "-client",
++ "-XX:+PrintSharedSpaces",
++ "-version");
++
++ output = new OutputAnalyzer(pb.start());
++ try {
++ output.shouldContain("sharing");
++ } catch (RuntimeException e) {
++ // if sharing failed due to ASLR or similar reasons,
++ // check whether sharing was attempted at all (UseSharedSpaces)
++ output.shouldContain("UseSharedSpaces:");
++ }
++ output.shouldHaveExitValue(0);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,95 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/* @test LimitSharedSizes
++ * @summary Test handling of limits on shared space size
++ * @library /testlibrary
++ * @run main LimitSharedSizes
++ */
++
++import com.oracle.java.testlibrary.*;
++
++public class LimitSharedSizes {
++ private static class SharedSizeTestData {
++ public String optionName;
++ public String optionValue;
++ public String expectedErrorMsg;
++
++ public SharedSizeTestData(String name, String value, String msg) {
++ optionName = name;
++ optionValue = value;
++ expectedErrorMsg = msg;
++ }
++ }
++
++ private static final SharedSizeTestData[] testTable = {
++ // values in this part of the test table should cause failure
++ // (shared space sizes are deliberately too small)
++ new SharedSizeTestData("-XX:SharedReadOnlySize", "4M", "read only"),
++ new SharedSizeTestData("-XX:SharedReadWriteSize","4M", "read write"),
++
++ // Known issue, JDK-8038422 (assert() on Windows)
++ // new SharedSizeTestData("-XX:SharedMiscDataSize", "500k", "miscellaneous data"),
++
++ // Too small of a misc code size should not cause a vm crash.
++ // It should result in the following error message:
++ // The shared miscellaneous code space is not large enough
++ // to preload requested classes. Use -XX:SharedMiscCodeSize=
++ // to increase the initial size of shared miscellaneous code space.
++ new SharedSizeTestData("-XX:SharedMiscCodeSize", "20k", "miscellaneous code"),
++
++ // these values are larger than default ones, but should
++ // be acceptable and not cause failure
++ new SharedSizeTestData("-XX:SharedReadOnlySize", "20M", null),
++ new SharedSizeTestData("-XX:SharedReadWriteSize", "20M", null),
++ new SharedSizeTestData("-XX:SharedMiscDataSize", "20M", null),
++ new SharedSizeTestData("-XX:SharedMiscCodeSize", "20M", null)
++ };
++
++ public static void main(String[] args) throws Exception {
++ String fileName = "test.jsa";
++
++ for (SharedSizeTestData td : testTable) {
++ String option = td.optionName + "=" + td.optionValue;
++ System.out.println("testing option <" + option + ">");
++
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:+UnlockDiagnosticVMOptions",
++ "-XX:SharedArchiveFile=./" + fileName,
++ option,
++ "-Xshare:dump");
++
++ OutputAnalyzer output = new OutputAnalyzer(pb.start());
++
++ if (td.expectedErrorMsg != null) {
++ output.shouldContain("The shared " + td.expectedErrorMsg
++ + " space is not large enough");
++
++ output.shouldHaveExitValue(2);
++ } else {
++ output.shouldNotContain("space is not large enough");
++ output.shouldHaveExitValue(0);
++ }
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/SharedArchiveFile/PrintSharedArchiveAndExit.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,83 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8066670
++ * @summary Testing -XX:+PrintSharedArchiveAndExit option
++ * @library /testlibrary
++ */
++
++import com.oracle.java.testlibrary.*;
++
++public class PrintSharedArchiveAndExit {
++ public static void main(String[] args) throws Exception {
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
++ OutputAnalyzer output = new OutputAnalyzer(pb.start());
++ try {
++ output.shouldContain("Loading classes to share");
++ output.shouldHaveExitValue(0);
++
++ // (1) With a valid archive
++ pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa",
++ "-XX:+PrintSharedArchiveAndExit", "-version");
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("archive is valid");
++ output.shouldNotContain("java version"); // Should not print JVM version
++ output.shouldHaveExitValue(0); // Should report success in error code.
++
++ pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa",
++ "-XX:+PrintSharedArchiveAndExit");
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("archive is valid");
++ output.shouldNotContain("Usage:"); // Should not print JVM help message
++ output.shouldHaveExitValue(0); // Should report success in error code.
++
++ // (2) With an invalid archive (boot class path has been prepended)
++ pb = ProcessTools.createJavaProcessBuilder(
++ "-Xbootclasspath/p:foo.jar",
++ "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa",
++ "-XX:+PrintSharedArchiveAndExit", "-version");
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("archive is invalid");
++ output.shouldNotContain("java version"); // Should not print JVM version
++ output.shouldHaveExitValue(1); // Should report failure in error code.
++
++ pb = ProcessTools.createJavaProcessBuilder(
++ "-Xbootclasspath/p:foo.jar",
++ "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa",
++ "-XX:+PrintSharedArchiveAndExit");
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("archive is invalid");
++ output.shouldNotContain("Usage:"); // Should not print JVM help message
++ output.shouldHaveExitValue(1); // Should report failure in error code.
++ } catch (RuntimeException e) {
++ e.printStackTrace();
++ output.shouldContain("Unable to use shared archive");
++ output.shouldHaveExitValue(1);
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/SharedArchiveFile/SharedBaseAddress.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,77 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test SharedBaseAddress
++ * @summary Test variety of values for SharedBaseAddress, making sure
++ * VM handles normal values as well as edge values w/o a crash.
++ * @library /testlibrary
++ * @run main SharedBaseAddress
++ */
++
++import com.oracle.java.testlibrary.*;
++
++public class SharedBaseAddress {
++
++ // shared base address test table
++ private static final String[] testTable = {
++ "1g", "8g", "64g","512g", "4t",
++ "32t", "128t", "0",
++ "1", "64k", "64M"
++ };
++
++ public static void main(String[] args) throws Exception {
++ // Known issue on Solaris-Sparc
++ // @ignore JDK-8044600
++ if (Platform.isSolaris() && Platform.isSparc())
++ return;
++
++ for (String testEntry : testTable) {
++ System.out.println("sharedBaseAddress = " + testEntry);
++
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:+UnlockDiagnosticVMOptions",
++ "-XX:SharedArchiveFile=test.jsa",
++ "-XX:SharedBaseAddress=" + testEntry,
++ "-Xshare:dump");
++
++ OutputAnalyzer output = new OutputAnalyzer(pb.start());
++
++ output.shouldContain("Loading classes to share");
++
++ try {
++ pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:+UnlockDiagnosticVMOptions",
++ "-XX:SharedArchiveFile=test.jsa",
++ "-Xshare:on",
++ "-version");
++ output = new OutputAnalyzer(pb.start());
++ output.shouldContain("sharing");
++ output.shouldHaveExitValue(0);
++ } catch (RuntimeException e) {
++ output.shouldContain("Unable to use shared archive");
++ output.shouldHaveExitValue(1);
++ }
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/SharedArchiveFile/SpaceUtilizationCheck.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,96 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test SpaceUtilizationCheck
++ * @summary Check if the space utilization for shared spaces is adequate
++ * @library /testlibrary
++ * @run main SpaceUtilizationCheck
++ */
++
++import com.oracle.java.testlibrary.*;
++
++import java.util.regex.Pattern;
++import java.util.regex.Matcher;
++import java.util.ArrayList;
++import java.lang.Integer;
++
++public class SpaceUtilizationCheck {
++ // Minimum allowed utilization value (percent)
++ // The goal is to have this number to be 50% for RO and RW regions
++ // Once that feature is implemented, increase the MIN_UTILIZATION to 50
++ private static final int MIN_UTILIZATION = 30;
++
++ // Only RO and RW regions are considered for this check, since they
++ // currently account for the bulk of the shared space
++ private static final int NUMBER_OF_CHECKED_SHARED_REGIONS = 2;
++
++ public static void main(String[] args) throws Exception {
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
++ "-XX:+UnlockDiagnosticVMOptions",
++ "-XX:SharedArchiveFile=./test.jsa",
++ "-Xshare:dump");
++
++ OutputAnalyzer output = new OutputAnalyzer(pb.start());
++ String stdout = output.getStdout();
++ ArrayList<String> utilization = findUtilization(stdout);
++
++ if (utilization.size() != NUMBER_OF_CHECKED_SHARED_REGIONS )
++ throw new RuntimeException("The output format of sharing summary has changed");
++
++ for(String str : utilization) {
++ int value = Integer.parseInt(str);
++ if (value < MIN_UTILIZATION) {
++ System.out.println(stdout);
++ throw new RuntimeException("Utilization for one of the regions" +
++ "is below a threshold of " + MIN_UTILIZATION + "%");
++ }
++ }
++ }
++
++ public static ArrayList<String> findUtilization(String input) {
++ ArrayList<String> regions = filterRegionsOfInterest(input.split("\n"));
++ return filterByPattern(filterByPattern(regions, "bytes \\[.*% used\\]"), "\\d+");
++ }
++
++ private static ArrayList<String> filterByPattern(Iterable<String> input, String pattern) {
++ ArrayList<String> result = new ArrayList<String>();
++ for (String str : input) {
++ Matcher matcher = Pattern.compile(pattern).matcher(str);
++ if (matcher.find()) {
++ result.add(matcher.group());
++ }
++ }
++ return result;
++ }
++
++ private static ArrayList<String> filterRegionsOfInterest(String[] inputLines) {
++ ArrayList<String> result = new ArrayList<String>();
++ for (String str : inputLines) {
++ if (str.contains("ro space:") || str.contains("rw space:")) {
++ result.add(str);
++ }
++ }
++ return result;
++ }
++}
+--- ./hotspot/test/runtime/lambda-features/InvokespecialInterface.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/runtime/lambda-features/InvokespecialInterface.java Wed Feb 04 12:14:39 2015 -0800
+@@ -33,11 +33,12 @@
+ import java.util.function.*;
+ import java.util.*;
+
++public class InvokespecialInterface {
+ interface I {
+ default void imethod() { System.out.println("I::imethod"); }
+ }
+
+-class C implements I {
++static class C implements I {
+ public void foo() { I.super.imethod(); } // invokespecial InterfaceMethod
+ public void bar() { I i = this; i.imethod(); } // invokeinterface same
+ public void doSomeInvokedynamic() {
+@@ -48,7 +49,6 @@
+ }
+ }
+
+-public class InvokespecialInterface {
+ public static void main(java.lang.String[] unused) {
+ // need to create C and call I::foo()
+ C c = new C();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/lambda-features/TestInterfaceInit.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,87 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++/*
++ * @test
++ * @bug 8034275
++ * @summary [JDK 8u40] Test interface initialization: only for interfaces declaring default methods
++ * @run main TestInterfaceInit
++ */
++import java.util.List;
++import java.util.Arrays;
++import java.util.ArrayList;
++
++public class TestInterfaceInit {
++
++ static List<Class<?>> cInitOrder = new ArrayList<>();
++
++ // Declares a default method and initializes
++ interface I {
++ boolean v = TestInterfaceInit.out(I.class);
++ default void x() {}
++ }
++
++ // Declares a default method and initializes
++ interface J extends I {
++ boolean v = TestInterfaceInit.out(J.class);
++ default void x() {}
++ }
++ // No default method, does not initialize
++ interface JN extends J {
++ boolean v = TestInterfaceInit.out(JN.class);
++ }
++
++ // Declares a default method and initializes
++ interface K extends I {
++ boolean v = TestInterfaceInit.out(K.class);
++ default void x() {}
++ }
++
++ // No default method, does not initialize
++ interface KN extends K {
++ boolean v = TestInterfaceInit.out(KN.class);
++ }
++
++ interface L extends JN, KN {
++ boolean v = TestInterfaceInit.out(L.class);
++ default void x() {}
++ }
++
++ public static void main(String[] args) {
++ // Trigger initialization
++ boolean v = L.v;
++
++ List<Class<?>> expectedCInitOrder = Arrays.asList(I.class,J.class,K.class,L.class);
++ if (!cInitOrder.equals(expectedCInitOrder)) {
++ throw new RuntimeException(String.format("Class initialization array %s not equal to expected array %s", cInitOrder, expectedCInitOrder));
++ }
++ }
++
++ static boolean out(Class c) {
++ System.out.println("#: initializing " + c.getName());
++ cInitOrder.add(c);
++ return true;
++ }
++
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/runtime/lambda-features/TestInterfaceOrder.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,88 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++/*
++ * @test
++ * @bug 8034275
++ * @summary [JDK 8u40] Test interface initialization order
++ * @run main TestInterfaceOrder
++ */
++
++import java.util.List;
++import java.util.Arrays;
++import java.util.ArrayList;
++
++public class TestInterfaceOrder {
++ static List<Class<?>> cInitOrder = new ArrayList<>();
++
++ public static void main(java.lang.String[] args) {
++ //Trigger initialization
++ C c = new C();
++
++ List<Class<?>> expectedCInitOrder = Arrays.asList(I.class, J.class, A.class, K.class, B.class, L.class, C.class);
++ if (!cInitOrder.equals(expectedCInitOrder)) {
++ throw new RuntimeException(String.format("Class initialization order %s not equal to expected order %s", cInitOrder, expectedCInitOrder));
++ }
++ }
++
++ interface I {
++ boolean v = TestInterfaceOrder.out(I.class);
++ default void i() {}
++ }
++
++ interface J extends I {
++ boolean v = TestInterfaceOrder.out(J.class);
++ default void j() {}
++ }
++
++ static class A implements J {
++ static boolean v = TestInterfaceOrder.out(A.class);
++ }
++
++ interface K extends I {
++ boolean v = TestInterfaceOrder.out(K.class);
++ default void k() {}
++ }
++
++ static class B extends A implements K {
++ static boolean v = TestInterfaceOrder.out(B.class);
++ }
++
++ interface L {
++ boolean v = TestInterfaceOrder.out(L.class);
++ default void l() {}
++ }
++
++ static class C extends B implements L {
++ static boolean v = TestInterfaceOrder.out(C.class);
++ }
++
++
++ static boolean out(Class c) {
++ System.out.println("#: initializing " + c.getName());
++ cInitOrder.add(c);
++ return true;
++ }
++
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/testlibrary/com/oracle/java/testlibrary/BuildHelper.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,106 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package com.oracle.java.testlibrary;
++
++import java.io.File;
++import java.io.FileReader;
++import java.util.Properties;
++
++public class BuildHelper {
++
++ /**
++ * Commercial builds should have the BUILD_TYPE set to commercial
++ * within the release file, found at the root of the JDK.
++ */
++ public static boolean isCommercialBuild() throws Exception {
++ String buildType = getReleaseProperty("BUILD_TYPE","notFound");
++ return buildType.equals("commercial");
++ }
++
++
++ /**
++ * Return the value for property key, or defaultValue if no property not found.
++ * If present, double quotes are trimmed.
++ */
++ public static String getReleaseProperty(String key, String defaultValue) throws Exception {
++ Properties properties = getReleaseProperties();
++ String value = properties.getProperty(key, defaultValue);
++ return trimDoubleQuotes(value);
++ }
++
++ /**
++ * Return the value for property key, or null if no property not found.
++ * If present, double quotes are trimmed.
++ */
++ public static String getReleaseProperty(String key) throws Exception {
++ return getReleaseProperty(key, null);
++ }
++
++ /**
++ * Get properties from the release file
++ */
++ public static Properties getReleaseProperties() throws Exception {
++ Properties properties = new Properties();
++ properties.load(new FileReader(getReleaseFile()));
++ return properties;
++ }
++
++ /**
++ * Every JDK has a release file in its root.
++ * @return A handler to the release file.
++ */
++ public static File getReleaseFile() throws Exception {
++ String jdkPath = getJDKRoot();
++ File releaseFile = new File(jdkPath,"release");
++ if ( ! releaseFile.canRead() ) {
++ throw new Exception("Release file is not readable, or it is absent: " +
++ releaseFile.getCanonicalPath());
++ }
++ return releaseFile;
++ }
++
++ /**
++ * Returns path to the JDK under test.
++ * This path is obtained through the test.jdk property, usually set by JTREG.
++ */
++ public static String getJDKRoot() {
++ String jdkPath = System.getProperty("test.jdk");
++ if (jdkPath == null) {
++ throw new RuntimeException("System property 'test.jdk' not set. This property is normally set by jtreg. "
++ + "When running test separately, set this property using '-Dtest.jdk=/path/to/jdk'.");
++ }
++ return jdkPath;
++ }
++
++ /**
++ * Trim double quotes from the beginning and the end of the given string.
++ * @param original string to trim.
++ * @return a new trimmed string.
++ */
++ public static String trimDoubleQuotes(String original) {
++ if (original == null) { return null; }
++ String trimmed = original.replaceAll("^\"+|\"+$", "");
++ return trimmed;
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOption.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,165 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++package com.oracle.java.testlibrary;
++
++import com.sun.management.HotSpotDiagnosticMXBean;
++import java.lang.management.ManagementFactory;
++
++/**
++ * A utility class to work with VM options which could be altered during
++ * execution.
++ *
++ * This class is a wrapper around {@code com.sun.management.VMOption}.
++ * It provides more convenient interface to read/write the values.
++ *
++ */
++public class DynamicVMOption {
++
++ private final HotSpotDiagnosticMXBean mxBean;
++
++ /**
++ * VM option name, like "MinHeapFreeRatio".
++ */
++ public final String name;
++
++ /**
++ * Creates an instance of DynamicVMOption.
++ *
++ * @param name the VM option name
++ */
++ public DynamicVMOption(String name) {
++ this.name = name;
++ mxBean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
++ }
++
++ /**
++ * Sets a new value for the option.
++ * Trying to set not applicable value will cause IllegalArgumentException.
++ * Behavior with null is undefined, most likely NPE will be thrown.
++ *
++ * @param newValue the value to be set
++ * @see #getValue()
++ * @throws IllegalArgumentException if newValue is not applicable to the option
++ */
++ public final void setValue(String newValue) {
++ mxBean.setVMOption(name, newValue);
++ }
++
++ /**
++ * Returns the value of option.
++ *
++ * @return the current option value
++ * @see #setValue(java.lang.String)
++ */
++ public final String getValue() {
++ return mxBean.getVMOption(name).getValue();
++ }
++
++ /**
++ * Returns true, if option is writable, false otherwise.
++ *
++ * @return true, if option is writable, false otherwise
++ */
++ public final boolean isWriteable() {
++ return mxBean.getVMOption(name).isWriteable();
++ }
++
++ /**
++ * Checks if the given value is applicable for the option.
++ *
++ * This method tries to set the option to the new value. If no exception
++ * has been thrown the value is treated as valid.
++ *
++ * Calling this method will not change the option value. After an attempt
++ * to set a new value, the option will be restored to its previous value.
++ *
++ * @param value the value to verify
++ * @return true if option could be set to the given value
++ */
++ public boolean isValidValue(String value) {
++ boolean isValid = true;
++ String oldValue = getValue();
++ try {
++ setValue(value);
++ } catch (NullPointerException e) {
++ if (value == null) {
++ isValid = false;
++ }
++ } catch (IllegalArgumentException e) {
++ isValid = false;
++ } finally {
++ setValue(oldValue);
++ }
++ return isValid;
++ }
++
++ /**
++ * Returns the value of the given VM option as String.
++ *
++ * This is a simple shortcut for {@code new DynamicVMOption(name).getValue()}
++ *
++ * @param name the name of VM option
++ * @return value as a string
++ * @see #getValue()
++ */
++ public static String getString(String name) {
++ return new DynamicVMOption(name).getValue();
++ }
++
++ /**
++ * Returns the value of the given option as int.
++ *
++ * @param name the name of VM option
++ * @return value parsed as integer
++ * @see #getString(java.lang.String)
++ *
++ */
++ public static int getInt(String name) {
++ return Integer.parseInt(getString(name));
++ }
++
++ /**
++ * Sets the VM option to a new value.
++ *
++ * This is a simple shortcut for {@code new DynamicVMOption(name).setValue(value)}
++ *
++ * @param name the name of VM option
++ * @param value the value to be set
++ * @see #setValue(java.lang.String)
++ */
++ public static void setString(String name, String value) {
++ new DynamicVMOption(name).setValue(value);
++ }
++
++ /**
++ * Sets the VM option value to a new integer value.
++ *
++ * @param name the name of VM option
++ * @param value the integer value to be set
++ * @see #setString(java.lang.String, java.lang.String)
++ */
++ public static void setInt(String name, int value) {
++ new DynamicVMOption(name).setValue(Integer.toString(value));
++ }
++
++}
+--- ./hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOptionChecker.java Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,121 +0,0 @@
+-/*
+- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-package com.oracle.java.testlibrary;
+-
+-import com.sun.management.HotSpotDiagnosticMXBean;
+-import com.sun.management.VMOption;
+-import java.lang.management.ManagementFactory;
+-
+-/**
+- * Simple class to check writeability, invalid and valid values for VMOption
+- */
+-public class DynamicVMOptionChecker {
+-
+- /**
+- * Reads VM option from PlatformMXBean and parse it to integer value
+- *
+- * @param name of option
+- * @return parsed value
+- */
+- public static int getIntValue(String name) {
+-
+- VMOption option = ManagementFactory.
+- getPlatformMXBean(HotSpotDiagnosticMXBean.class).
+- getVMOption(name);
+-
+- return Integer.parseInt(option.getValue());
+- }
+-
+- /**
+- * Sets VM option value
+- *
+- * @param name of option
+- * @param value to set
+- */
+- public static void setIntValue(String name, int value) {
+- ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class).setVMOption(name, Integer.toString(value));
+- }
+-
+- /**
+- * Checks that VM option is dynamically writable
+- *
+- * @param name
+- * @throws RuntimeException if option if not writable
+- * @return always true
+- */
+- public static boolean checkIsWritable(String name) {
+- VMOption option = ManagementFactory.
+- getPlatformMXBean(HotSpotDiagnosticMXBean.class).
+- getVMOption(name);
+-
+- if (!option.isWriteable()) {
+- throw new RuntimeException(name + " is not writable");
+- }
+-
+- return true;
+- }
+-
+- /**
+- * Checks that value cannot be set
+- *
+- * @param name of flag
+- * @param value string representation of value to set
+- * @throws RuntimeException on error - when expected exception hasn't been thrown
+- */
+- public static void checkInvalidValue(String name, String value) {
+- // should throw
+- try {
+- ManagementFactory.
+- getPlatformMXBean(HotSpotDiagnosticMXBean.class).
+- setVMOption(name, value);
+-
+- } catch (IllegalArgumentException e) {
+- return;
+- }
+-
+- throw new RuntimeException("Expected IllegalArgumentException was not thrown, " + name + "= " + value);
+- }
+-
+- /**
+- * Checks that value can be set
+- *
+- * @param name of flag to set
+- * @param value string representation of value to set
+- * @throws RuntimeException on error - when value in VM is not equal to origin
+- */
+- public static void checkValidValue(String name, String value) {
+- ManagementFactory.
+- getPlatformMXBean(HotSpotDiagnosticMXBean.class).
+- setVMOption(name, value);
+-
+- VMOption option = ManagementFactory.
+- getPlatformMXBean(HotSpotDiagnosticMXBean.class).
+- getVMOption(name);
+-
+- if (!option.getValue().equals(value)) {
+- throw new RuntimeException("Actual value of " + name + " \"" + option.getValue()
+- + "\" not equal origin \"" + value + "\"");
+- }
+- }
+-
+-}
+--- ./hotspot/test/testlibrary/com/oracle/java/testlibrary/TestDynamicVMOption.java Mon Dec 08 12:28:35 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,104 +0,0 @@
+-/*
+- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-package com.oracle.java.testlibrary;
+-
+-/**
+- * Simple class to check writeability, invalid and valid values for concrete VMOption
+- */
+-public class TestDynamicVMOption {
+-
+- private final String name;
+- private final int value;
+-
+- /**
+- * Constructor
+- *
+- * @param name of VM option to test
+- */
+- public TestDynamicVMOption(String name) {
+- this.name = name;
+- this.value = DynamicVMOptionChecker.getIntValue(name);
+- System.out.println(this.name + " = " + this.value);
+- }
+-
+- /**
+- * Checks that this value can accept valid percentage values and cannot accept invalid percentage values
+- *
+- * @throws RuntimeException
+- */
+- public void testPercentageValues() {
+- checkInvalidValue(Integer.toString(Integer.MIN_VALUE));
+- checkInvalidValue(Integer.toString(Integer.MAX_VALUE));
+- checkInvalidValue("-10");
+- checkInvalidValue("190");
+- }
+-
+- /**
+- * Reads VM option from PlatformMXBean and parse it to integer value
+- *
+- * @return value
+- */
+- public int getIntValue() {
+- return DynamicVMOptionChecker.getIntValue(this.name);
+- }
+-
+- /**
+- * Sets VM option value
+- *
+- * @param value to set
+- */
+- public void setIntValue(int value) {
+- DynamicVMOptionChecker.setIntValue(this.name, value);
+- }
+-
+- /**
+- * Checks that this VM option is dynamically writable
+- *
+- * @throws RuntimeException if option if not writable
+- * @return true
+- */
+- public boolean checkIsWritable() throws RuntimeException {
+- return DynamicVMOptionChecker.checkIsWritable(this.name);
+- }
+-
+- /**
+- * Checks that value for this VM option cannot be set
+- *
+- * @param value to check
+- * @throws RuntimeException on error - when expected exception hasn't been thrown
+- */
+- public void checkInvalidValue(String value) {
+- DynamicVMOptionChecker.checkInvalidValue(this.name, value);
+- }
+-
+- /**
+- * Checks that value for this VM option can be set
+- *
+- * @param value to check
+- * @throws RuntimeException on error - when value in VM is not equal to origin
+- */
+- public void checkValidValue(String value) {
+- DynamicVMOptionChecker.checkValidValue(this.name, value);
+- }
+-
+-}
+--- ./hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Mon Dec 08 12:28:35 2014 -0800
++++ ./hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Wed Feb 04 12:14:39 2015 -0800
+@@ -25,7 +25,13 @@
+ package sun.hotspot;
+
+ import java.lang.reflect.Executable;
++import java.util.Arrays;
++import java.util.List;
++import java.util.function.Function;
++import java.util.stream.Stream;
+ import java.security.BasicPermission;
++import java.net.URL;
++
+ import sun.hotspot.parser.DiagnosticCommand;
+
+ public class WhiteBox {
+@@ -69,6 +75,8 @@
+ // Memory
+ public native long getObjectAddress(Object o);
+ public native int getHeapOopSize();
++ public native boolean isObjectInOldGen(Object o);
++ public native long getObjectSize(Object o);
+
+ // Runtime
+ // Make sure class name is in the correct format
+@@ -77,6 +85,15 @@
+ }
+ private native boolean isClassAlive0(String name);
+
++ // Resource/Class Lookup Cache
++ public native boolean classKnownToNotExist(ClassLoader loader, String name);
++ public native URL[] getLookupCacheURLs(ClassLoader loader);
++ public native int[] getLookupCacheMatches(ClassLoader loader, String name);
++
++ // JVMTI
++ public native void addToBootstrapClassLoaderSearch(String segment);
++ public native void addToSystemClassLoaderSearch(String segment);
++
+ // G1
+ public native boolean g1InConcurrentMark();
+ public native boolean g1IsHumongous(Object o);
+@@ -91,8 +108,10 @@
+ public native void NMTCommitMemory(long addr, long size);
+ public native void NMTUncommitMemory(long addr, long size);
+ public native void NMTReleaseMemory(long addr, long size);
+- public native boolean NMTWaitForDataMerge();
++ public native long NMTMallocWithPseudoStack(long size, int index);
+ public native boolean NMTIsDetailSupported();
++ public native boolean NMTChangeTrackingLevel();
++ public native int NMTGetHashSize();
+
+ // Compiler
+ public native void deoptimizeAll();
+@@ -129,7 +148,7 @@
+ }
+ public native int getCompileQueueSize(int compLevel);
+ public native boolean testSetForceInlineMethod(Executable method, boolean value);
+- public boolean enqueueMethodForCompilation(Executable method, int compLevel) {
++ public boolean enqueueMethodForCompilation(Executable method, int compLevel) {
+ return enqueueMethodForCompilation(method, compLevel, -1 /*InvocationEntryBci*/);
+ }
+ public native boolean enqueueMethodForCompilation(Executable method, int compLevel, int entry_bci);
+@@ -142,6 +161,13 @@
+
+ // Memory
+ public native void readReservedMemory();
++ public native long allocateMetaspace(ClassLoader classLoader, long size);
++ public native void freeMetaspace(ClassLoader classLoader, long addr, long size);
++ public native long incMetaspaceCapacityUntilGC(long increment);
++ public native long metaspaceCapacityUntilGC();
++
++ // force Young GC
++ public native void youngGC();
+
+ // force Full GC
+ public native void fullGC();
+@@ -150,8 +176,49 @@
+ public native int stressVirtualSpaceResize(long reservedSpaceSize, long magnitude, long iterations);
+ public native void runMemoryUnitTests();
+ public native void readFromNoaccessArea();
++ public native long getThreadStackSize();
++ public native long getThreadRemainingStackSize();
+
+ // CPU features
+ public native String getCPUFeatures();
+
++ // Native extensions
++ public native long getHeapUsageForContext(int context);
++ public native long getHeapRegionCountForContext(int context);
++ public native int getContextForObject(Object obj);
++ public native void printRegionInfo(int context);
++
++ // VM flags
++ public native void setBooleanVMFlag(String name, boolean value);
++ public native void setIntxVMFlag(String name, long value);
++ public native void setUintxVMFlag(String name, long value);
++ public native void setUint64VMFlag(String name, long value);
++ public native void setStringVMFlag(String name, String value);
++ public native void setDoubleVMFlag(String name, double value);
++ public native Boolean getBooleanVMFlag(String name);
++ public native Long getIntxVMFlag(String name);
++ public native Long getUintxVMFlag(String name);
++ public native Long getUint64VMFlag(String name);
++ public native String getStringVMFlag(String name);
++ public native Double getDoubleVMFlag(String name);
++ private final List<Function<String,Object>> flagsGetters = Arrays.asList(
++ this::getBooleanVMFlag, this::getIntxVMFlag, this::getUintxVMFlag,
++ this::getUint64VMFlag, this::getStringVMFlag, this::getDoubleVMFlag);
++
++ public Object getVMFlag(String name) {
++ return flagsGetters.stream()
++ .map(f -> f.apply(name))
++ .filter(x -> x != null)
++ .findAny()
++ .orElse(null);
++ }
++ public native int getOffsetForName0(String name);
++ public int getOffsetForName(String name) throws Exception {
++ int offset = getOffsetForName0(name);
++ if (offset == -1) {
++ throw new RuntimeException(name + " not found");
++ }
++ return offset;
++ }
++
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/testlibrary_tests/whitebox/vm_flags/BooleanTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,87 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test BooleanTest
++ * @bug 8028756
++ * @library /testlibrary /testlibrary/whitebox
++ * @build BooleanTest
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI BooleanTest
++ * @summary testing of WB::set/getBooleanVMFlag()
++ * @author igor.ignatyev@oracle.com
++ */
++
++import sun.hotspot.WhiteBox;
++import com.oracle.java.testlibrary.*;
++import sun.management.*;
++import com.sun.management.*;
++
++public class BooleanTest {
++ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
++ private static final Boolean[] TESTS = {true, false, true, true, false};
++ private static final String TEST_NAME = "BooleanTest";
++ private static final String FLAG_NAME = "PrintCompilation";
++ private static final String METHOD = TEST_NAME + "::method";
++ private static final String METHOD1 = METHOD + "1";
++ private static final String METHOD2 = METHOD + "2";
++
++ public static void main(String[] args) throws Exception {
++ if (args.length == 0) {
++ VmFlagTest.runTest(FLAG_NAME, TESTS,
++ VmFlagTest.WHITE_BOX::setBooleanVMFlag,
++ VmFlagTest.WHITE_BOX::getBooleanVMFlag);
++ testFunctional(false);
++ testFunctional(true);
++ } else {
++ boolean value = Boolean.valueOf(args[0]);
++ method1();
++ VmFlagTest.WHITE_BOX.setBooleanVMFlag(FLAG_NAME, value);
++ method2();
++ }
++ }
++
++ private static void testFunctional(boolean value) throws Exception {
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
++ "-Xbootclasspath/a:.",
++ "-XX:+UnlockDiagnosticVMOptions",
++ "-XX:+WhiteBoxAPI",
++ "-Xcomp",
++ "-XX:CompileCommand=compileonly," + METHOD + "*",
++ "-XX:" + (value ? "-" : "+") + FLAG_NAME,
++ TEST_NAME,
++ "" + value);
++ OutputAnalyzer out = new OutputAnalyzer(pb.start());
++ if (value) {
++ out.shouldNotContain(METHOD1);
++ out.shouldContain(METHOD2);
++ } else {
++ out.shouldContain(METHOD1);
++ out.shouldNotContain(METHOD2);
++ }
++ }
++
++ private static void method1() { }
++ private static void method2() { }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/testlibrary_tests/whitebox/vm_flags/DoubleTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test DoubleTest
++ * @bug 8028756
++ * @library /testlibrary /testlibrary/whitebox
++ * @build DoubleTest
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DoubleTest
++ * @summary testing of WB::set/getDoubleVMFlag()
++ * @author igor.ignatyev@oracle.com
++ */
++
++public class DoubleTest {
++ private static final String FLAG_NAME = null;
++ private static final Double[] TESTS = {0d, -0d, -1d, 1d,
++ Double.MAX_VALUE, Double.MIN_VALUE, Double.NaN,
++ Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY};
++
++ public static void main(String[] args) throws Exception {
++ VmFlagTest.runTest(FLAG_NAME, TESTS,
++ VmFlagTest.WHITE_BOX::setDoubleVMFlag,
++ VmFlagTest.WHITE_BOX::getDoubleVMFlag);
++ }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/testlibrary_tests/whitebox/vm_flags/IntxTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,46 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test IntxTest
++ * @bug 8028756
++ * @library /testlibrary /testlibrary/whitebox
++ * @build IntxTest
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI IntxTest
++ * @summary testing of WB::set/getIntxVMFlag()
++ * @author igor.ignatyev@oracle.com
++ */
++
++public class IntxTest {
++ private static final String FLAG_NAME = "OnStackReplacePercentage";
++ private static final Long[] TESTS = {0L, 100L, -1L,
++ (long) Integer.MAX_VALUE, (long) Integer.MIN_VALUE};
++
++ public static void main(String[] args) throws Exception {
++ VmFlagTest.runTest(FLAG_NAME, TESTS,
++ VmFlagTest.WHITE_BOX::setIntxVMFlag,
++ VmFlagTest.WHITE_BOX::getIntxVMFlag);
++ }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/testlibrary_tests/whitebox/vm_flags/StringTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test StringTest
++ * @bug 8028756
++ * @library /testlibrary /testlibrary/whitebox
++ * @build StringTest
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI StringTest
++ * @summary testing of WB::set/getStringVMFlag()
++ * @author igor.ignatyev@oracle.com
++ */
++
++public class StringTest {
++ private static final String FLAG_NAME = "CompileOnly";
++ private static final String[] TESTS = {"StringTest::*", ""};
++
++ public static void main(String[] args) throws Exception {
++ VmFlagTest.runTest(FLAG_NAME, TESTS,
++ VmFlagTest.WHITE_BOX::setStringVMFlag,
++ VmFlagTest.WHITE_BOX::getStringVMFlag);
++ }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/testlibrary_tests/whitebox/vm_flags/Uint64Test.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,46 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test Uint64Test
++ * @bug 8028756
++ * @library /testlibrary /testlibrary/whitebox
++ * @build Uint64Test
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI Uint64Test
++ * @summary testing of WB::set/getUint64VMFlag()
++ * @author igor.ignatyev@oracle.com
++ */
++
++public class Uint64Test {
++ private static final String FLAG_NAME = "MaxRAM";
++ private static final Long[] TESTS = {0L, 100L, (long) Integer.MAX_VALUE,
++ -1L, Long.MAX_VALUE, Long.MIN_VALUE};
++
++ public static void main(String[] args) throws Exception {
++ VmFlagTest.runTest(FLAG_NAME, TESTS,
++ VmFlagTest.WHITE_BOX::setUint64VMFlag,
++ VmFlagTest.WHITE_BOX::getUint64VMFlag);
++ }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/testlibrary_tests/whitebox/vm_flags/UintxTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,51 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test UintxTest
++ * @bug 8028756
++ * @library /testlibrary /testlibrary/whitebox
++ * @build UintxTest
++ * @run main ClassFileInstaller sun.hotspot.WhiteBox
++ * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI UintxTest
++ * @summary testing of WB::set/getUintxVMFlag()
++ * @author igor.ignatyev@oracle.com
++ */
++import com.oracle.java.testlibrary.Platform;
++
++public class UintxTest {
++ private static final String FLAG_NAME = "TypeProfileLevel";
++ private static final Long[] TESTS = {0L, 100L, (long) Integer.MAX_VALUE,
++ (1L << 32L) - 1L, 1L << 32L};
++ private static final Long[] EXPECTED_64 = TESTS;
++ private static final Long[] EXPECTED_32 = {0L, 100L,
++ (long) Integer.MAX_VALUE, (1L << 32L) - 1L, 0L};
++
++ public static void main(String[] args) throws Exception {
++ VmFlagTest.runTest(FLAG_NAME, TESTS,
++ Platform.is64bit() ? EXPECTED_64 : EXPECTED_32,
++ VmFlagTest.WHITE_BOX::setUintxVMFlag,
++ VmFlagTest.WHITE_BOX::getUintxVMFlag);
++ }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./hotspot/test/testlibrary_tests/whitebox/vm_flags/VmFlagTest.java Wed Feb 04 12:14:39 2015 -0800
+@@ -0,0 +1,115 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.util.Objects;
++import java.util.function.BiConsumer;
++import java.util.function.Function;
++import sun.hotspot.WhiteBox;
++import sun.management.*;
++import com.sun.management.*;
++import com.oracle.java.testlibrary.*;
++
++public final class VmFlagTest<T> {
++ public static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
++
++ private static final String NONEXISTENT_FLAG = "NonexistentFlag";
++ private final String flagName;
++ private final BiConsumer<T, T> test;
++ private final BiConsumer<String, T> set;
++ private final Function<String, T> get;
++
++ protected VmFlagTest(String flagName, BiConsumer<String, T> set,
++ Function<String, T> get, boolean isPositive) {
++ this.flagName = flagName;
++ this.set = set;
++ this.get = get;
++ if (isPositive) {
++ test = this::testPositive;
++ } else {
++ test = this::testNegative;
++ }
++ }
++
++ private void setNewValue(T value) {
++ set.accept(flagName, value);
++ }
++
++ private T getValue() {
++ T t = get.apply(flagName);
++ System.out.println("T = " + t);
++ return t;
++ }
++
++ protected static <T> void runTest(String existentFlag, T[] tests,
++ BiConsumer<String, T> set, Function<String, T> get) {
++ runTest(existentFlag, tests, tests, set, get);
++ }
++
++ protected static <T> void runTest(String existentFlag, T[] tests,
++ T[] results, BiConsumer<String, T> set, Function<String, T> get) {
++ if (existentFlag != null) {
++ new VmFlagTest(existentFlag, set, get, true).test(tests, results);
++ }
++ new VmFlagTest(NONEXISTENT_FLAG, set, get, false).test(tests, results);
++ }
++
++ public final void test(T[] tests, T[] results) {
++ Asserts.assertEQ(tests.length, results.length, "[TESTBUG] tests.length != results.length");
++ for (int i = 0, n = tests.length ; i < n; ++i) {
++ test.accept(tests[i], results[i]);
++ }
++ }
++
++ protected String getVMOptionAsString() {
++ HotSpotDiagnosticMXBean diagnostic
++ = ManagementFactoryHelper.getDiagnosticMXBean();
++ VMOption tmp;
++ try {
++ tmp = diagnostic.getVMOption(flagName);
++ } catch (IllegalArgumentException e) {
++ tmp = null;
++ }
++ return tmp == null ? null : tmp.getValue();
++ }
++
++ private void testPositive(T value, T expected) {
++ Asserts.assertEQ(getVMOptionAsString(), asString(getValue()));
++ setNewValue(value);
++ String newValue = getVMOptionAsString();
++ Asserts.assertEQ(newValue, asString(expected));
++ Asserts.assertEQ(getVMOptionAsString(), asString(getValue()));
++ }
++
++ private void testNegative(T value, T expected) {
++ String oldValue = getVMOptionAsString();
++ Asserts.assertEQ(oldValue, asString(getValue()));
++ setNewValue(value);
++ String newValue = getVMOptionAsString();
++ Asserts.assertEQ(oldValue, newValue);
++ }
++
++ private String asString(Object value) {
++ return value == null ? null : "" + value;
++ }
++}
++
+--- ./jaxp/.hgtags Mon Dec 08 12:29:23 2014 -0800
++++ ./jaxp/.hgtags Wed Feb 04 12:14:41 2015 -0800
+@@ -349,3 +349,29 @@
+ b5165ac3556e95c42a295d3cbeef8cd6e5607b25 jdk8u31-b10
+ f475dbc70345904bda6b520af43955e244292886 jdk8u31-b11
+ 6563e438377f2086253577e08593b1ddfb901eff jdk8u31-b12
++1dd828fd98f1b84de5dcadb904322b711e7489ff jdk8u31-b13
++3a1bba8076da4e54882123e98e219eab1c31ccef jdk8u40-b00
++f219da378d0768ff042d77221e5d20676ecc16f0 jdk8u40-b01
++16ef2134c32a4e60b5a60105b371163aa5936278 jdk8u40-b02
++d73144ee471d4d4c49db94b3cc8990479961499a jdk8u40-b03
++23c1a41d75adc6fc57f69528c2c804079f449d94 jdk8u40-b04
++8d60cebf6a0c1cf1a5669e49deb795a1445e826b jdk8u40-b05
++50a2adfa57fcbbe1587991d53f58d227070a24db jdk8u40-b06
++b2210de1587b16ca1d1d781b55e19bc70724c62b jdk8u40-b07
++641eb6543c7186d1c2c26eaf96803b1e6b411d9a jdk8u40-b08
++c45c0ee4160026207cef1850c215c2691d43a97d jdk8u40-b09
++1f5248bc0714a45160525d48bfcf455b9cdf86a3 jdk8u40-b10
++0bf6dbb6ac4e2258d4d832bb949cb1be2402a899 jdk8u40-b11
++b0cde44bdbfd6339128ca5a7dbbbffaaecac793a jdk8u40-b12
++9df027c40f0fe150f609f1a5e731b7e649923f2b jdk8u40-b13
++d8886dede94dedcad66e6d770dac6b8bca1eb51d jdk8u40-b14
++ed46c05af2570feed5ea264eca02f223055109e9 jdk8u40-b15
++cda81fbeec94b31dba27a043fbf58f442524cdf5 jdk8u40-b16
++cb63029168a52d62d82c3325f1092405c318e78c jdk8u40-b17
++6103f5a8119a85937ae006f18b8dfc04f73315d0 jdk8u40-b18
++3b73732d6886dc8155f0c1fbb125ca60d9e2fd2b jdk8u40-b19
++7bfc889330e0ec1fd495990eaa0d7f0c390b7304 jdk8u40-b20
++78d90db9de2801eec010ccb9f0db3caf969dfc3b jdk8u40-b21
++54a13451ce243f2159ed3996e6efcf374a5750ca jdk8u40-b22
++e07fbae1efeac4e50514384caa7d226af7414114 jdk8u40-b23
++048cebd17f73f23ce2295e360f31c1b6788195aa jdk8u40-b24
+--- ./jaxp/THIRD_PARTY_README Mon Dec 08 12:29:23 2014 -0800
++++ ./jaxp/THIRD_PARTY_README Wed Feb 04 12:14:41 2015 -0800
+@@ -3385,7 +3385,7 @@
+ included with JRE 8, JDK 8, and OpenJDK 8.
+
+ Apache Commons Math 3.2
+- Apache Derby 10.10.1.3
++ Apache Derby 10.11.1.2
+ Apache Jakarta BCEL 5.1
+ Apache Jakarta Regexp 1.4
+ Apache Santuario XML Security for Java 1.5.4
+--- ./jaxp/src/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java Mon Dec 08 12:29:23 2014 -0800
++++ ./jaxp/src/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java Wed Feb 04 12:14:41 2015 -0800
+@@ -213,6 +213,10 @@
+ public void visitLocalVariableTypeTable(LocalVariableTypeTable obj) {
+ stack.push(obj);
+ obj.accept(visitor);
++
++ LocalVariable[] vars = obj.getLocalVariableTypeTable();
++ for(int i=0; i < vars.length; i++)
++ vars[i].accept(this);
+ stack.pop();
+ }
+
+--- ./jaxp/src/com/sun/org/apache/bcel/internal/generic/MethodGen.java Mon Dec 08 12:29:23 2014 -0800
++++ ./jaxp/src/com/sun/org/apache/bcel/internal/generic/MethodGen.java Wed Feb 04 12:14:41 2015 -0800
+@@ -87,6 +87,7 @@
+ private boolean strip_attributes;
+
+ private ArrayList variable_vec = new ArrayList();
++ private ArrayList type_vec = new ArrayList();
+ private ArrayList line_number_vec = new ArrayList();
+ private ArrayList exception_vec = new ArrayList();
+ private ArrayList throws_vec = new ArrayList();
+@@ -260,7 +261,7 @@
+ }
+ } else if (a instanceof LocalVariableTypeTable) {
+ LocalVariable[] lv = ((LocalVariableTypeTable) a).getLocalVariableTypeTable();
+- removeLocalVariables();
++ removeLocalVariableTypes();
+ for (int k = 0; k < lv.length; k++) {
+ LocalVariable l = lv[k];
+ InstructionHandle start = il.findHandle(l.getStartPC());
+@@ -272,7 +273,7 @@
+ if (null == end) {
+ end = il.getEnd();
+ }
+- addLocalVariable(l.getName(), Type.getType(l.getSignature()), l
++ addLocalVariableType(l.getName(), Type.getType(l.getSignature()), l
+ .getIndex(), start, end);
+ }
+ } else
+@@ -406,6 +407,31 @@
+ return lg;
+ }
+
++ /*
++ * If the range of the variable has not been set yet, it will be set to be
++ * val id from the start to the end of the instruction list.
++ *
++ * @return array of declared local variable types sorted by index
++ */
++ private LocalVariableGen[] getLocalVariableTypes() {
++ int size = type_vec.size();
++ LocalVariableGen[] lg = new LocalVariableGen[size];
++ type_vec.toArray(lg);
++
++ for(int i=0; i < size; i++) {
++ if(lg[i].getStart() == null)
++ lg[i].setStart(il.getStart());
++
++ if(lg[i].getEnd() == null)
++ lg[i].setEnd(il.getEnd());
++ }
++
++ if(size > 1)
++ sort(lg, 0, size - 1);
++
++ return lg;
++ }
++
+ /**
+ * @return `LocalVariableTable' attribute of all the local variables of this method.
+ */
+@@ -422,6 +448,68 @@
+ }
+
+ /**
++ * @return `LocalVariableTypeTable' attribute of all the local variable
++ * types of this method.
++ */
++ public LocalVariableTypeTable getLocalVariableTypeTable(ConstantPoolGen cp) {
++ LocalVariableGen[] lg = getLocalVariableTypes();
++ int size = lg.length;
++ LocalVariable[] lv = new LocalVariable[size];
++
++ for(int i=0; i < size; i++)
++ lv[i] = lg[i].getLocalVariable(cp);
++
++ return new LocalVariableTypeTable(cp.addUtf8("LocalVariableTypeTable"),
++ 2 + lv.length * 10, lv, cp.getConstantPool());
++ }
++
++ /**
++ * Adds a local variable type to this method.
++ *
++ * @param name variable name
++ * @param type variable type
++ * @param slot the index of the local variable, if type is long or double, the next available
++ * index is slot+2
++ * @param start from where the variable is valid
++ * @param end until where the variable is valid
++ * @return new local variable object
++ * @see LocalVariable
++ */
++ private LocalVariableGen addLocalVariableType(String name, Type type, int slot,
++ InstructionHandle start,
++ InstructionHandle end) {
++ byte t = type.getType();
++
++ if(t != Constants.T_ADDRESS) {
++ int add = type.getSize();
++
++ if(slot + add > max_locals)
++ max_locals = slot + add;
++
++ LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end);
++ int i;
++
++ if((i = type_vec.indexOf(l)) >= 0) // Overwrite if necessary
++ type_vec.set(i, l);
++ else
++ type_vec.add(l);
++
++ return l;
++ } else {
++ throw new IllegalArgumentException("Can not use " + type +
++ " as type for local variable");
++
++ }
++ }
++
++ /**
++ * Remove all local variable types.
++ */
++ private void removeLocalVariableTypes() {
++ type_vec.clear();
++ }
++
++ /**
+ * Give an instruction a line number corresponding to the source code line.
+ *
+ * @param ih instruction to tag
+@@ -637,12 +725,17 @@
+
+ LineNumberTable lnt = null;
+ LocalVariableTable lvt = null;
++ LocalVariableTypeTable lvtt = null;
+
+- /* Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.)
++ /* Create LocalVariableTable, LocalvariableTypeTable, and LineNumberTable
++ * attributes (for debuggers, e.g.)
+ */
+ if((variable_vec.size() > 0) && !strip_attributes)
+ addCodeAttribute(lvt = getLocalVariableTable(cp));
+
++ if((type_vec.size() > 0) && !strip_attributes)
++ addCodeAttribute(lvtt = getLocalVariableTypeTable(cp));
++
+ if((line_number_vec.size() > 0) && !strip_attributes)
+ addCodeAttribute(lnt = getLineNumberTable(cp));
+
+@@ -691,6 +784,7 @@
+
+ // Undo effects of adding attributes
+ if(lvt != null) removeCodeAttribute(lvt);
++ if(lvtt != null) removeCodeAttribute(lvtt);
+ if(lnt != null) removeCodeAttribute(lnt);
+ if(code != null) removeAttribute(code);
+ if(et != null) removeAttribute(et);
+--- ./jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java Mon Dec 08 12:29:23 2014 -0800
++++ ./jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java Wed Feb 04 12:14:41 2015 -0800
+@@ -453,7 +453,8 @@
+ }
+
+ private void propagateFeatures(AbstractXMLSchema schema) {
+- schema.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, fSecurityManager != null);
++ schema.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,
++ (fSecurityManager != null && fSecurityManager.isSecureProcessing()));
+ schema.setFeature(Constants.ORACLE_FEATURE_SERVICE_MECHANISM, fUseServicesMechanism);
+ String[] features = fXMLSchemaLoader.getRecognizedFeatures();
+ for (int i = 0; i < features.length; ++i) {
+--- ./jaxp/src/com/sun/org/apache/xml/internal/dtm/ref/sax2dtm/SAX2DTM2.java Mon Dec 08 12:29:23 2014 -0800
++++ ./jaxp/src/com/sun/org/apache/xml/internal/dtm/ref/sax2dtm/SAX2DTM2.java Wed Feb 04 12:14:41 2015 -0800
+@@ -3145,7 +3145,11 @@
+ m_data.elementAt(-dataIndex+1));
+ }
+ }
+- else if (DTM.ELEMENT_NODE == type || DTM.DOCUMENT_FRAGMENT_NODE == type
++ else if (DTM.ELEMENT_NODE == type)
++ {
++ return getStringValueX(nodeHandle);
++ }
++ else if (DTM.DOCUMENT_FRAGMENT_NODE == type
+ || DTM.DOCUMENT_NODE == type)
+ {
+ return null;
+--- ./jaxp/src/com/sun/org/apache/xml/internal/resolver/readers/DOMCatalogReader.java Mon Dec 08 12:29:23 2014 -0800
++++ ./jaxp/src/com/sun/org/apache/xml/internal/resolver/readers/DOMCatalogReader.java Wed Feb 04 12:14:41 2015 -0800
+@@ -57,7 +57,6 @@
+ * <p>The selection of CatalogParsers is made on the basis of the QName
+ * of the root element of the document.</p>
+ *
+- * <p>This class requires the <a href="http://java.sun.com/aboutJava/communityprocess/final/jsr005/index.html">Java API for XML Parsing</a>.</p>
+ *
+ * @see Catalog
+ * @see CatalogReader
+--- ./jaxp/src/org/w3c/dom/package.html Mon Dec 08 12:29:23 2014 -0800
++++ ./jaxp/src/org/w3c/dom/package.html Wed Feb 04 12:14:41 2015 -0800
+@@ -3,12 +3,10 @@
+ <title>org.w3c.dom package</title>
+ </head>
+ <body bgcolor="white">
+-Provides the interfaces for the Document Object Model (DOM) which is a
+-component API of the <a href="http://java.sun.com/xml">Java API for XML
+-Processing</a>. The Document Object Model Level 2 Core API allows programs
+-to dynamically access and update the content and structure of documents.
+-See the <a href="http://www.w3.org/TR/DOM-Level-2-Core/">specification</a>
+-for more information.
++Provides the interfaces for the Document Object Model (DOM). Supports the
++<a href="http://www.w3.org/TR/DOM-Level-2-Core/">Document Object Model Level 2 Core APIi</a>,
++<a href="http://www.w3.org/TR/DOM-Level-3-Core">Document Object Model (DOM) Level 3 Core</a>,
++and <a href="http://www.w3.org/TR/DOM-Level-3-LS">Document Object Model (DOM) Level 3 Load and Save</a>.
+
+ @since JDK1.4
+ </body>
+--- ./jaxws/.hgtags Mon Dec 08 12:29:31 2014 -0800
++++ ./jaxws/.hgtags Wed Feb 04 12:14:42 2015 -0800
+@@ -347,3 +347,29 @@
+ dd0467f3fe130884849ad8fb226d76f02b4cbde4 jdk8u31-b10
+ 497c783d228ed188d61964edd409794af3ad3e5c jdk8u31-b11
+ 959e8fca46155528c8147da69a7c49edfb002cb1 jdk8u31-b12
++9d0c737694ece23547c0a27dcd0ba6cbcdf577f2 jdk8u31-b13
++31d43d250c836c13fcc87025837783788c5cd0de jdk8u40-b00
++262fb5353ffa661f88b4a9cf2581fcad8c2a43f7 jdk8u40-b01
++8043f77ef8a4ded9505269a356c4e2f4f9604cd9 jdk8u40-b02
++27bcab54f36afc2340adf525fa2a8de1b1c356ca jdk8u40-b03
++127fb2a65ca6d09bb59ff8030aac11c67f3da4d8 jdk8u40-b04
++b904fcd66860c2b069493f989b3347241266407d jdk8u40-b05
++52ae3094de1ec6974ff0250b8cabc13f110290d1 jdk8u40-b06
++3857b4b27e22cfd3f970cd77ed1a41d44444202f jdk8u40-b07
++304ea93428f83d55a558a76ebbcc318d07c03fbe jdk8u40-b08
++26529be4ae77192acf99c867f0c2a75a7ad71f28 jdk8u40-b09
++337fb10bc4da77f31b3ba3049d45180a8c215f97 jdk8u40-b10
++475f12001625b16230f29a96b6371b3cd2e955dd jdk8u40-b11
++d78fb9203a2782842810ff0197f2ce92d364a8ea jdk8u40-b12
++42a61f4bdca3f7f919b7f8aeb5cad961dc2d1660 jdk8u40-b13
++d22a374ce8569a89301b6c07301e0a803af024e7 jdk8u40-b14
++a278e39ba58d104d0731db5ab5ea6cedf3084a1d jdk8u40-b15
++8893690584dac2df7cc2e9b0a5ffe107266a160b jdk8u40-b16
++83c4d5aca2ff8fd0c6b2a7091018b71313371176 jdk8u40-b17
++fa07311627d085f1307f55298f59463bcf55db02 jdk8u40-b18
++c8b402c28fe51e25f3298e1266f2ae48bda8d3e0 jdk8u40-b19
++a21c4edfdf4402f027183ac8c8aac2db49df3b7d jdk8u40-b20
++16485a38b6bc762b363f4e439047486742fbcfcb jdk8u40-b21
++6e928fd9152541eddf25694be89eb881434a5c5f jdk8u40-b22
++b6755a463ccf6a79b1e1a43ed7bdb1c5cb1ac17d jdk8u40-b23
++5fbbfd66643edb81cfa0688825d698dcc5f2eb11 jdk8u40-b24
+--- ./jaxws/THIRD_PARTY_README Mon Dec 08 12:29:31 2014 -0800
++++ ./jaxws/THIRD_PARTY_README Wed Feb 04 12:14:42 2015 -0800
+@@ -3385,7 +3385,7 @@
+ included with JRE 8, JDK 8, and OpenJDK 8.
+
+ Apache Commons Math 3.2
+- Apache Derby 10.10.1.3
++ Apache Derby 10.11.1.2
+ Apache Jakarta BCEL 5.1
+ Apache Jakarta Regexp 1.4
+ Apache Santuario XML Security for Java 1.5.4
+--- ./jdk/.hgtags Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/.hgtags Wed Feb 04 12:14:43 2015 -0800
+@@ -350,3 +350,29 @@
+ 291505d802d9075e227f9ee865a67234e1d737cf jdk8u31-b10
+ a21dd7999d1e4ba612c951c2c78504d23eb7243a jdk8u31-b11
+ 6a12f34816d2ee12368274fc21225384a8893426 jdk8u31-b12
++1fbdd5d80d0671decd8acb5adb64866f609e986f jdk8u31-b13
++e6ed015afbbf3459ba3297e270b4f3170e989c80 jdk8u40-b00
++6e223d48080ef40f4ec11ecbcd19b4a20813b9eb jdk8u40-b01
++4797cd0713b44b009525f1276d571ade7e24f3f5 jdk8u40-b02
++c67acfb24eed87629887128df51007218ddf1f60 jdk8u40-b03
++dde62d949f7847469b2ede2ca4190c95066adc91 jdk8u40-b04
++d587834579dadd18cb8b096e61d92e2dbccc2782 jdk8u40-b05
++25788892a6723c0742a24050cc25ab103d9804de jdk8u40-b06
++07f0e22b5c238dd7b89fedbed35f02ac6b392c96 jdk8u40-b07
++0f0d70abca09b4ddb0981204ad5a427d4ce935e9 jdk8u40-b08
++064adeb65ce82f9ff3cc7898e59d19eb64743c63 jdk8u40-b09
++c3a4729c70fa29d79ad77e0643ad7715ebbc96b5 jdk8u40-b10
++693da296b395139f2fe6d7131eb0b0d85f6015f6 jdk8u40-b11
++fb8db13639204e37388904bb6e57778c5d762631 jdk8u40-b12
++ba80109a9b3eb92b56012c9ec3aafd9aee2efa69 jdk8u40-b13
++ffc348308de2e872f5d510d440604c3726a67a18 jdk8u40-b14
++31dac938108da722c56a0526fba7f6ae84773056 jdk8u40-b15
++9dc67d03e6e540f646f27092ed23e94e95fa789e jdk8u40-b16
++fc4f5546417071c70cffd89ca83302309f6f7da9 jdk8u40-b17
++20a3e2135e0867e55af72f0c66a3de558bc613e2 jdk8u40-b18
++5c31204d19e5976f025026db3d5c17331e8c44db jdk8u40-b19
++7784dab075ed82be2275f4694164bbb9cc1cde3f jdk8u40-b20
++564bca490631e4ed4f7993e6633ed9ee62067624 jdk8u40-b21
++d168113f9841a77b3cee3a6a45fcd85b7351ac90 jdk8u40-b22
++41fe61722ce96b75dd3a1ba5072473122e21e5a0 jdk8u40-b23
++9d903721276c8684706db7ecfb6cda568e9f4f69 jdk8u40-b24
+--- ./jdk/THIRD_PARTY_README Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/THIRD_PARTY_README Wed Feb 04 12:14:43 2015 -0800
+@@ -3385,7 +3385,7 @@
+ included with JRE 8, JDK 8, and OpenJDK 8.
+
+ Apache Commons Math 3.2
+- Apache Derby 10.10.1.3
++ Apache Derby 10.11.1.2
+ Apache Jakarta BCEL 5.1
+ Apache Jakarta Regexp 1.4
+ Apache Santuario XML Security for Java 1.5.4
+--- ./jdk/make/CompileDemos.gmk Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/CompileDemos.gmk Wed Feb 04 12:14:43 2015 -0800
+@@ -456,7 +456,7 @@
+ ##################################################################################################
+
+ ifndef OPENJDK
+- DB_DEMO_ZIPFILE := $(wildcard $(JDK_TOPDIR)/src/closed/share/db/*.zip)
++ DB_DEMO_ZIPFILE := $(wildcard $(JDK_TOPDIR)/src/closed/share/db/db-derby-*-bin.zip)
+
+ $(JDK_OUTPUTDIR)/demo/_the.db.unzipped: $(DB_DEMO_ZIPFILE)
+ $(MKDIR) -p $(@D)
+--- ./jdk/make/CompileJavaClasses.gmk Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/CompileJavaClasses.gmk Wed Feb 04 12:14:43 2015 -0800
+@@ -37,6 +37,11 @@
+ EXCLUDES :=
+
+ ##########################################################################################
++# Include the corresponding custom file, if present.
++
++-include $(CUSTOM_MAKE_DIR)/CompileJavaClasses.gmk
++
++##########################################################################################
+
+ EXCLUDES += com/sun/pept \
+ com/sun/tools/example/trace \
+@@ -52,8 +57,8 @@
+ endif
+
+ ifndef OPENJDK
+- # There exists two versions of this file...
+- EXFILES := $(JDK_TOPDIR)/src/share/classes/javax/crypto/JarVerifier.java
++ # There exists two versions of these files...
++ EXFILES += $(JDK_TOPDIR)/src/share/classes/javax/crypto/JarVerifier.java
+
+ ifeq ($(OPENJDK_TARGET_OS), windows)
+ # This gets built on unix platforms implicitly in the old build even though
+--- ./jdk/make/CompileNativeLibraries.gmk Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/CompileNativeLibraries.gmk Wed Feb 04 12:14:43 2015 -0800
+@@ -87,6 +87,9 @@
+
+ include lib/SoundLibraries.gmk
+
++# Include the corresponding custom file, if present.
++-include $(CUSTOM_MAKE_DIR)/CompileNativeLibraries.gmk
++
+ ##########################################################################################
+
+ all: $(COPY_FILES) $(BUILD_LIBRARIES)
+--- ./jdk/make/Images.gmk Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/Images.gmk Wed Feb 04 12:14:43 2015 -0800
+@@ -562,7 +562,7 @@
+ $(CAT) $< | $(SED) "s/XXXX/$(shell cat $(JDK_TOPDIR)/src/closed/share/db/COPYRIGHTYEAR)/" > $@
+
+ JDK_DB_TARGETS := $(patsubst $(JDK_TOPDIR)/src/closed/share/db/%, $(IMAGES_OUTPUTDIR)/_unzip/%.unzipped, \
+- $(wildcard $(JDK_TOPDIR)/src/closed/share/db/*.zip)) \
++ $(wildcard $(JDK_TOPDIR)/src/closed/share/db/db-derby-*-bin.zip)) \
+ $(JDK_IMAGE_DIR)/db/README-JDK.html $(JDK_IMAGE_DIR)/db/3RDPARTY
+
+ endif
+--- ./jdk/make/Setup.gmk Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/Setup.gmk Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -38,7 +38,7 @@
+ # boot jdk to generate tools that need to be run with the boot jdk.
+ # Thus we force the target bytecode to the previous JDK version.
+ $(eval $(call SetupJavaCompiler,GENERATE_OLDBYTECODE, \
+- JVM := $(JAVA), \
++ JVM := $(JAVA_SMALL), \
+ JAVAC := $(NEW_JAVAC), \
+ FLAGS := $(BOOT_JDK_SOURCETARGET) -bootclasspath $(BOOT_RTJAR) $(DISABLE_WARNINGS), \
+ SERVER_DIR := $(SJAVAC_SERVER_DIR), \
+@@ -60,7 +60,7 @@
+ # I.e. the rt.jar, but since rt.jar has not yet been generated
+ # (it will be in "make images") therefore we use classes instead.
+ $(eval $(call SetupJavaCompiler,GENERATE_USINGJDKBYTECODE, \
+- JVM := $(JAVA), \
++ JVM := $(JAVA_SMALL), \
+ JAVAC := $(NEW_JAVAC), \
+ FLAGS := -bootclasspath $(JDK_OUTPUTDIR)/classes $(DISABLE_WARNINGS), \
+ SERVER_DIR := $(SJAVAC_SERVER_DIR), \
+--- ./jdk/make/Tools.gmk Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/Tools.gmk Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -54,84 +54,85 @@
+ BUILD_TOOLS += $(JDK_OUTPUTDIR)/btclasses/build/tools/deps/refs.allowed
+
+ # Add a checksum ("jsum") to the end of a text file. Prevents trivial tampering with class lists.
+-TOOL_ADDJSUM = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_ADDJSUM = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.addjsum.AddJsum
+
+ # The buildmetaindex tool creates a meta-index to make core class loaders lazier.
+-TOOL_BUILDMETAINDEX = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_BUILDMETAINDEX = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.buildmetaindex.BuildMetaIndex
+
+-TOOL_COMPILEFONTCONFIG = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_COMPILEFONTCONFIG = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.compilefontconfig.CompileFontConfig
+
+-TOOL_COMPILEPROPERTIES = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_COMPILEPROPERTIES = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.compileproperties.CompileProperties
+
+-TOOL_STRIPPROPERTIES = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_STRIPPROPERTIES = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.stripproperties.StripProperties
+
+-TOOL_JARREORDER = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_JARREORDER = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.jarreorder.JarReorder
+
+-TOOL_GENERATECHARACTER = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_GENERATECHARACTER = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.generatecharacter.GenerateCharacter
+
+-TOOL_CHARACTERNAME = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_CHARACTERNAME = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.generatecharacter.CharacterName
+
+-TOOL_DTDBUILDER = $(JAVA) -Ddtd_home=$(JDK_TOPDIR)/make/data/dtdbuilder \
++TOOL_DTDBUILDER = $(JAVA_SMALL) -Ddtd_home=$(JDK_TOPDIR)/make/data/dtdbuilder \
++ -Djava.awt.headless=true \
+ -cp $(JDK_OUTPUTDIR)/btclasses build.tools.dtdbuilder.DTDBuilder
+
+-TOOL_GENERATEBREAKITERATORDATA = $(JAVA) \
++TOOL_GENERATEBREAKITERATORDATA = $(JAVA_SMALL) \
+ -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.generatebreakiteratordata.GenerateBreakIteratorData
+
+-TOOL_GENERATECURRENCYDATA = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_GENERATECURRENCYDATA = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.generatecurrencydata.GenerateCurrencyData
+
+-TOOL_HASHER = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_HASHER = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.hasher.Hasher
+
+-TOOL_TZDB = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_TZDB = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.tzdb.TzdbZoneRulesCompiler
+
+
+ # TODO: There are references to the jdwpgen.jar in jdk/make/netbeans/jdwpgen/build.xml
+ # and nbproject/project.properties in the same dir. Needs to be looked at.
+-TOOL_JDWPGEN = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses build.tools.jdwpgen.Main
++TOOL_JDWPGEN = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses build.tools.jdwpgen.Main
+
+ # TODO: Lots of files in jdk/make/tools/CharsetMapping dir
+-TOOL_CHARSETMAPPING = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_CHARSETMAPPING = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.charsetmapping.Main
+
+-TOOL_SPP = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses build.tools.spp.Spp
++TOOL_SPP = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses build.tools.spp.Spp
+
+ # Nimbus is used somewhere in the swing build.
+-TOOL_GENERATENIMBUS = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_GENERATENIMBUS = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.generatenimbus.Generator
+
+-TOOL_WRAPPERGENERATOR = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_WRAPPERGENERATOR = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
+ WrapperGenerator
+
+-TOOL_AWT_TOBIN = $(JAVA) -Djava.awt.headless=true -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_AWT_TOBIN = $(JAVA_SMALL) -Djava.awt.headless=true -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.icondata.awt.ToBin
+
+-TOOL_OSX_TOBIN = $(JAVA) -Djava.awt.headless=true -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_OSX_TOBIN = $(JAVA_SMALL) -Djava.awt.headless=true -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.icondata.osxapp.ToBin
+
+-TOOL_CLDRCONVERTER = $(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
++TOOL_CLDRCONVERTER = $(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
+ build.tools.cldrconverter.CLDRConverter
+
+-TOOL_REMOVEMETHODS = $(JAVA) -Xbootclasspath/p:$(LANGTOOLS_OUTPUTDIR)/dist/bootstrap/lib/javac.jar \
++TOOL_REMOVEMETHODS = $(JAVA_SMALL) -Xbootclasspath/p:$(LANGTOOLS_OUTPUTDIR)/dist/bootstrap/lib/javac.jar \
+ -cp $(JDK_OUTPUTDIR)/btclasses:$(JDK_OUTPUTDIR) \
+ build.tools.classfile.RemoveMethods
+
+-TOOL_CHECKDEPS = $(JAVA) -Xbootclasspath/p:$(LANGTOOLS_OUTPUTDIR)/dist/bootstrap/lib/javac.jar \
++TOOL_CHECKDEPS = $(JAVA_SMALL) -Xbootclasspath/p:$(LANGTOOLS_OUTPUTDIR)/dist/bootstrap/lib/javac.jar \
+ -cp $(JDK_OUTPUTDIR)/btclasses:$(JDK_OUTPUTDIR) \
+ build.tools.deps.CheckDeps
+
+-TOOL_ADDTORESTRICTEDPKGS=$(JAVA) -cp $(JDK_OUTPUTDIR)/btclasses \
+- build.tools.addtorestrictedpkgs.AddToRestrictedPkgs
++TOOL_ADDTORESTRICTEDPKGS=$(JAVA_SMALL) -cp $(JDK_OUTPUTDIR)/btclasses \
++ build.tools.addtorestrictedpkgs.AddToRestrictedPkgs
+
+ ##########################################################################################
+
+--- ./jdk/make/data/jdwp/jdwp.spec Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/data/jdwp/jdwp.spec Wed Feb 04 12:14:43 2015 -0800
+@@ -1147,7 +1147,8 @@
+ (ErrorSet
+ (Error INVALID_CLASS "clazz is not the ID of a class.")
+ (Error INVALID_OBJECT "clazz is not a known ID.")
+- (Error INVALID_METHODID "methodID is not the ID of a method.")
++ (Error INVALID_METHODID "methodID is not the ID of a static method in "
++ "this class type or one of its superclasses.")
+ (Error INVALID_THREAD)
+ (Error THREAD_NOT_SUSPENDED)
+ (Error VM_DEAD)
+@@ -1250,6 +1251,83 @@
+ )
+ )
+ (CommandSet InterfaceType=5
++ (Command InvokeMethod=1
++ "Invokes a static method. "
++ "The method must not be a static initializer. "
++ "The method must be a member of the interface type. "
++ "<p>Since JDWP version 1.8 "
++ "<p>"
++ "The method invocation will occur in the specified thread. "
++ "Method invocation can occur only if the specified thread "
++ "has been suspended by an event. "
++ "Method invocation is not supported "
++ "when the target VM has been suspended by the front-end. "
++ "<p>"
++ "The specified method is invoked with the arguments in the specified "
++ "argument list. "
++ "The method invocation is synchronous; the reply packet is not "
++ "sent until the invoked method returns in the target VM. "
++ "The return value (possibly the void value) is "
++ "included in the reply packet. "
++ "If the invoked method throws an exception, the "
++ "exception object ID is set in the reply packet; otherwise, the "
++ "exception object ID is null. "
++ "<p>"
++ "For primitive arguments, the argument value's type must match the "
++ "argument's type exactly. For object arguments, there must exist a "
++ "widening reference conversion from the argument value's type to the "
++ "argument's type and the argument's type must be loaded. "
++ "<p>"
++ "By default, all threads in the target VM are resumed while "
++ "the method is being invoked if they were previously "
++ "suspended by an event or by a command. "
++ "This is done to prevent the deadlocks "
++ "that will occur if any of the threads own monitors "
++ "that will be needed by the invoked method. It is possible that "
++ "breakpoints or other events might occur during the invocation. "
++ "Note, however, that this implicit resume acts exactly like "
++ "the ThreadReference resume command, so if the thread's suspend "
++ "count is greater than 1, it will remain in a suspended state "
++ "during the invocation. By default, when the invocation completes, "
++ "all threads in the target VM are suspended, regardless their state "
++ "before the invocation. "
++ "<p>"
++ "The resumption of other threads during the invoke can be prevented "
++ "by specifying the INVOKE_SINGLE_THREADED "
++ "bit flag in the <code>options</code> field; however, "
++ "there is no protection against or recovery from the deadlocks "
++ "described above, so this option should be used with great caution. "
++ "Only the specified thread will be resumed (as described for all "
++ "threads above). Upon completion of a single threaded invoke, the invoking thread "
++ "will be suspended once again. Note that any threads started during "
++ "the single threaded invocation will not be suspended when the "
++ "invocation completes. "
++ "<p>"
++ "If the target VM is disconnected during the invoke (for example, through "
++ "the VirtualMachine dispose command) the method invocation continues. "
++ (Out
++ (interfaceType clazz "The interface type ID.")
++ (threadObject thread "The thread in which to invoke.")
++ (method methodID "The method to invoke.")
++ (Repeat arguments
++ (value arg "The argument value.")
++ )
++ (int options "Invocation <a href=\"#JDWP_InvokeOptions\">options</a>")
++ )
++ (Reply
++ (value returnValue "The returned value.")
++ (tagged-object exception "The thrown exception.")
++ )
++ (ErrorSet
++ (Error INVALID_CLASS "clazz is not the ID of an interface.")
++ (Error INVALID_OBJECT "clazz is not a known ID.")
++ (Error INVALID_METHODID "methodID is not the ID of a static method in this "
++ "interface type or is the ID of a static initializer.")
++ (Error INVALID_THREAD)
++ (Error THREAD_NOT_SUSPENDED)
++ (Error VM_DEAD)
++ )
++ )
+ )
+ (CommandSet Method=6
+ (Command LineTable=1
+@@ -1543,7 +1621,7 @@
+ "<p>"
+ "By default, all threads in the target VM are resumed while "
+ "the method is being invoked if they were previously "
+- "suspended by an event or by command. "
++ "suspended by an event or by a command. "
+ "This is done to prevent the deadlocks "
+ "that will occur if any of the threads own monitors "
+ "that will be needed by the invoked method. It is possible that "
+@@ -1586,7 +1664,9 @@
+ (Error INVALID_OBJECT)
+ (Error INVALID_CLASS "clazz is not the ID of a reference "
+ "type.")
+- (Error INVALID_METHODID "methodID is not the ID of a method.")
++ (Error INVALID_METHODID "methodID is not the ID of an instance method "
++ "in this object's type or one of its superclasses, "
++ "superinterfaces, or implemented interfaces.")
+ (Error INVALID_THREAD)
+ (Error THREAD_NOT_SUSPENDED)
+ (Error VM_DEAD)
+--- ./jdk/make/gensrc/GensrcMisc.gmk Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/gensrc/GensrcMisc.gmk Wed Feb 04 12:14:43 2015 -0800
+@@ -62,25 +62,6 @@
+
+ ##########################################################################################
+
+-ifeq ($(OPENJDK_TARGET_OS_API), posix)
+- UPSUFFIX := $(OPENJDK_TARGET_OS)
+- ifeq ($(OPENJDK_TARGET_OS), macosx)
+- UPSUFFIX := bsd
+- endif
+- # UNIXProcess.java is different for solaris and linux. We need to copy
+- # the correct UNIXProcess.java over to $(JDK_OUTPUTDIR)/gensrc/java/lang/.
+-
+- $(JDK_OUTPUTDIR)/gensrc/java/lang/UNIXProcess.java: \
+- $(JDK_TOPDIR)/src/solaris/classes/java/lang/UNIXProcess.java.$(UPSUFFIX)
+- $(ECHO) $(LOG_INFO) Copying UNIXProcess.java.$(OPENJDK_TARGET_OS) to java/lang/UNIXProcess.java
+- $(call install-file)
+- $(CHMOD) u+rw $@
+-
+- GENSRC_MISC += $(JDK_OUTPUTDIR)/gensrc/java/lang/UNIXProcess.java
+-endif
+-
+-##########################################################################################
+-
+ GENSRC_MISC += $(JDK_OUTPUTDIR)/gensrc/sun/nio/ch/SocketOptionRegistry.java
+
+ GENSRC_SOR_SRC := $(JDK_TOPDIR)/src/share/native/sun/nio/ch
+--- ./jdk/make/lib/Awt2dLibraries.gmk Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/lib/Awt2dLibraries.gmk Wed Feb 04 12:14:43 2015 -0800
+@@ -318,7 +318,7 @@
+ endif
+
+ ifeq ($(OPENJDK_TARGET_OS), macosx)
+- LIBAWT_FILES += awt_LoadLibrary.c img_colors.c
++ LIBAWT_FILES += awt_LoadLibrary.c
+ LIBAWT_CFLAGS += -F/System/Library/Frameworks/JavaVM.framework/Frameworks
+ endif
+
+@@ -611,7 +611,6 @@
+ debug_mem.c \
+ debug_trace.c \
+ debug_util.c \
+- awt_Plugin.c \
+ gnome_interface.c \
+ gtk2_interface.c \
+ swing_GTKEngine.c \
+--- ./jdk/make/lib/CoreLibraries.gmk Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/lib/CoreLibraries.gmk Wed Feb 04 12:14:43 2015 -0800
+@@ -129,9 +129,9 @@
+ $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/common \
+ $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/util
+
+-ifneq ($(OPENJDK_TARGET_OS), macosx)
++ifeq ($(OPENJDK_TARGET_OS), windows)
+ LIBJAVA_SRC_DIRS += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/util/locale/provider
+-else
++else ifeq ($(OPENJDK_TARGET_OS), macosx)
+ LIBJAVA_SRC_DIRS += $(JDK_TOPDIR)/src/macosx/native/sun/util/locale/provider
+ endif
+
+--- ./jdk/make/lib/ServiceabilityLibraries.gmk Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/lib/ServiceabilityLibraries.gmk Wed Feb 04 12:14:43 2015 -0800
+@@ -23,6 +23,10 @@
+ # questions.
+ #
+
++# Include custom extensions if available.
++-include $(CUSTOM_MAKE_DIR)/lib/ServiceabilityLibraries.gmk
++
++
+ LIBATTACH_EXCLUDE_FILES :=
+ ifneq ($(OPENJDK_TARGET_OS), solaris)
+ LIBATTACH_EXCLUDE_FILES += SolarisVirtualMachine.c
+@@ -283,12 +287,12 @@
+
+ ##########################################################################################
+
+-BUILD_LIBMANAGEMENT_SRC := $(JDK_TOPDIR)/src/share/native/sun/management \
++BUILD_LIBMANAGEMENT_SRC += $(JDK_TOPDIR)/src/share/native/sun/management \
+ $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/management
+
+ BUILD_LIBMANAGEMENT_EXCLUDES :=
+
+-BUILD_LIBMANAGEMENT_CFLAGS := -I$(JDK_TOPDIR)/src/share/native/sun/management
++BUILD_LIBMANAGEMENT_CFLAGS += -I$(JDK_TOPDIR)/src/share/native/sun/management
+
+ ifneq ($(OPENJDK_TARGET_OS), solaris)
+ BUILD_LIBMANAGEMENT_EXCLUDES += SolarisOperatingSystem.c
+@@ -309,6 +313,9 @@
+ endif
+ endif
+
++# Make it possible to override this variable
++LIBMANAGEMENT_MAPFILE ?= $(JDK_TOPDIR)/make/mapfiles/libmanagement/mapfile-vers
++
+ $(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT, \
+ LIBRARY := management, \
+ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+@@ -317,7 +324,7 @@
+ LANG := C, \
+ OPTIMIZATION := $(LIBMANAGEMENT_OPTIMIZATION), \
+ CFLAGS := $(CFLAGS_JDKLIB) $(BUILD_LIBMANAGEMENT_CFLAGS), \
+- MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libmanagement/mapfile-vers, \
++ MAPFILE := $(LIBMANAGEMENT_MAPFILE), \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LDFLAGS_solaris := -lkstat, \
+--- ./jdk/make/mapfiles/libawt/mapfile-mawt-vers Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/mapfiles/libawt/mapfile-mawt-vers Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -249,11 +249,6 @@
+ Java_sun_awt_motif_XsessionWMcommand;
+ Java_sun_awt_motif_XsessionWMcommand_New;
+
+- # Java Plugin
+- getAwtLockFunctions;
+- getAwtData;
+- getAwtDisplay;
+-
+ # libfontmanager entry points
+ AWTIsHeadless;
+ AWTCountFonts;
+--- ./jdk/make/mapfiles/libawt/mapfile-vers Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/mapfiles/libawt/mapfile-vers Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -174,13 +174,6 @@
+ Java_sun_awt_motif_XsessionWMcommand;
+ Java_sun_awt_motif_XsessionWMcommand_New;
+
+- # Java Plugin
+- # This is in awt_LoadLibrary.c and falls through to libmawt.
+- # Evidently plugin needs this for backward compatability.
+- getAwtLockFunctions;
+- getAwtData;
+- getAwtDisplay;
+-
+ # libfontmanager entry points
+ AWTIsHeadless;
+ GrPrim_Sg2dGetCompInfo;
+--- ./jdk/make/mapfiles/libawt/mapfile-vers-linux Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/mapfiles/libawt/mapfile-vers-linux Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -152,13 +152,6 @@
+ # Evidently CDE needs this for backward compatability.
+ Java_sun_awt_motif_XsessionWMcommand;
+
+- # Java Plugin
+- # This is in awt_LoadLibrary.c and falls through to libmawt.
+- # Evidently plugin needs this for backward compatability.
+- getAwtLockFunctions;
+- getAwtData;
+- getAwtDisplay;
+-
+ # libfontmanager entry points
+ AWTIsHeadless;
+ GrPrim_Sg2dGetCompInfo;
+@@ -283,11 +276,6 @@
+ # CDE private entry point
+ Java_sun_awt_motif_XsessionWMcommand;
+
+- # Java Plugin
+- getAwtLockFunctions;
+- getAwtData;
+- getAwtDisplay;
+-
+ # libfontmanager entry points
+ AWTIsHeadless;
+ AWTCountFonts;
+--- ./jdk/make/mapfiles/libawt_xawt/mapfile-vers Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/mapfiles/libawt_xawt/mapfile-vers Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -449,12 +449,6 @@
+ awt_Lock;
+ awt_GetComponent;
+
+- # Java Plugin
+- # This is in awt_LoadLibrary.c and falls through to libmawt.
+- # Evidently plugin needs this for backward compatability.
+- getAwtLockFunctions;
+- getAwtData;
+- getAwtDisplay;
+ #XAWT entry point for CDE
+ Java_sun_awt_motif_XsessionWMcommand;
+ Java_sun_awt_motif_XsessionWMcommand_New;
+--- ./jdk/make/mapfiles/libjava/mapfile-vers Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/mapfiles/libjava/mapfile-vers Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -78,13 +78,13 @@
+ Java_java_io_FileInputStream_available;
+ Java_java_io_FileInputStream_close0;
+ Java_java_io_FileInputStream_initIDs;
+- Java_java_io_FileInputStream_open;
++ Java_java_io_FileInputStream_open0;
+ Java_java_io_FileInputStream_read0;
+ Java_java_io_FileInputStream_readBytes;
+ Java_java_io_FileInputStream_skip;
+ Java_java_io_FileOutputStream_close0;
+ Java_java_io_FileOutputStream_initIDs;
+- Java_java_io_FileOutputStream_open;
++ Java_java_io_FileOutputStream_open0;
+ Java_java_io_FileOutputStream_write;
+ Java_java_io_FileOutputStream_writeBytes;
+ Java_java_io_ObjectInputStream_bytesToDoubles;
+@@ -97,7 +97,7 @@
+ Java_java_io_RandomAccessFile_getFilePointer;
+ Java_java_io_RandomAccessFile_initIDs;
+ Java_java_io_RandomAccessFile_length;
+- Java_java_io_RandomAccessFile_open;
++ Java_java_io_RandomAccessFile_open0;
+ Java_java_io_RandomAccessFile_read0;
+ Java_java_io_RandomAccessFile_readBytes;
+ Java_java_io_RandomAccessFile_seek0;
+@@ -269,6 +269,9 @@
+ Java_sun_reflect_Reflection_getCallerClass__;
+ Java_sun_reflect_Reflection_getCallerClass__I;
+ Java_sun_reflect_Reflection_getClassAccessFlags;
++ Java_sun_misc_URLClassPath_knownToNotExist0;
++ Java_sun_misc_URLClassPath_getLookupCacheURLs;
++ Java_sun_misc_URLClassPath_getLookupCacheForClassLoader;
+ Java_sun_misc_Version_getJdkVersionInfo;
+ Java_sun_misc_Version_getJdkSpecialVersion;
+ Java_sun_misc_Version_getJvmVersionInfo;
+@@ -287,8 +290,6 @@
+ # Java_sun_misc_VM_unsuspendSomeThreads; threads.c
+ # Java_sun_misc_VM_unsuspendThreads; threads.c
+
+- Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPattern;
+-
+ # Outcalls from libjvm done using dlsym().
+
+ VerifyClassCodes;
+--- ./jdk/make/mapfiles/libjava/reorder-sparc Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/mapfiles/libjava/reorder-sparc Wed Feb 04 12:14:43 2015 -0800
+@@ -44,7 +44,7 @@
+ text: .text%Java_java_io_UnixFileSystem_canonicalize;
+ text: .text%JNU_GetStringPlatformChars;
+ text: .text%JNU_ReleaseStringPlatformChars;
+-text: .text%Java_java_io_FileInputStream_open;
++text: .text%Java_java_io_FileInputStream_open0;
+ text: .text%fileOpen;
+ text: .text%Java_java_io_FileInputStream_readBytes;
+ text: .text%readBytes;
+--- ./jdk/make/mapfiles/libjava/reorder-sparcv9 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/mapfiles/libjava/reorder-sparcv9 Wed Feb 04 12:14:43 2015 -0800
+@@ -47,7 +47,7 @@
+ text: .text%Java_java_io_UnixFileSystem_canonicalize;
+ text: .text%JNU_GetStringPlatformChars;
+ text: .text%JNU_ReleaseStringPlatformChars;
+-text: .text%Java_java_io_FileInputStream_open;
++text: .text%Java_java_io_FileInputStream_open0;
+ text: .text%fileOpen;
+ text: .text%Java_java_io_FileInputStream_readBytes;
+ text: .text%readBytes;
+--- ./jdk/make/mapfiles/libjava/reorder-x86 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/mapfiles/libjava/reorder-x86 Wed Feb 04 12:14:43 2015 -0800
+@@ -57,7 +57,7 @@
+ text: .text%Java_java_lang_ClassLoader_00024NativeLibrary_find;
+ text: .text%Java_java_lang_Float_floatToIntBits;
+ text: .text%Java_java_lang_Double_doubleToLongBits;
+-text: .text%Java_java_io_FileInputStream_open;
++text: .text%Java_java_io_FileInputStream_open0;
+ text: .text%fileOpen;
+ text: .text%Java_java_io_UnixFileSystem_getLength;
+ text: .text%Java_java_io_FileInputStream_readBytes;
+@@ -90,7 +90,7 @@
+ text: .text%JNU_CallMethodByName;
+ text: .text%JNU_CallMethodByNameV;
+ text: .text%Java_java_util_logging_FileHandler_lockFile;
+-text: .text%Java_java_io_FileOutputStream_open;
++text: .text%Java_java_io_FileOutputStream_open0;
+ text: .text%Java_java_io_UnixFileSystem_createDirectory;
+ text: .text%Java_java_io_UnixFileSystem_getLastModifiedTime;
+ text: .text%Java_java_util_prefs_FileSystemPreferences_lockFile0;
+--- ./jdk/make/mapfiles/libjfr/mapfile-vers Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/mapfiles/libjfr/mapfile-vers Wed Feb 04 12:14:43 2015 -0800
+@@ -10,8 +10,13 @@
+ Java_oracle_jrockit_jfr_Process_getpid;
+ Java_oracle_jrockit_jfr_Timing_counterTime;
+ Java_oracle_jrockit_jfr_Timing_init;
+- Java_oracle_jrockit_jfr_NativeLogger_output0;
+- Java_oracle_jrockit_jfr_VMJFR_isEnabled;
++ Java_oracle_jrockit_jfr_Logger_output0;
++ Java_oracle_jrockit_jfr_JFR_isCommercialFeaturesUnlocked;
++ Java_oracle_jrockit_jfr_JFR_isStarted;
++ Java_oracle_jrockit_jfr_JFR_isSupportedInVM;
++ Java_oracle_jrockit_jfr_JFR_startFlightRecorder;
++ Java_oracle_jrockit_jfr_JFR_isDisabledOnCommandLine;
++ Java_oracle_jrockit_jfr_JFR_isEnabled;
+ Java_oracle_jrockit_jfr_VMJFR_options;
+ Java_oracle_jrockit_jfr_VMJFR_init;
+ Java_oracle_jrockit_jfr_VMJFR_addConstPool;
+@@ -33,7 +38,6 @@
+ Java_oracle_jrockit_jfr_VMJFR_setPeriod;
+ Java_oracle_jrockit_jfr_VMJFR_getPeriod;
+ Java_oracle_jrockit_jfr_VMJFR_descriptors;
+- Java_oracle_jrockit_jfr_VMJFR_redefineClass0;
+ Java_oracle_jrockit_jfr_VMJFR_retransformClasses0;
+ JNI_OnLoad;
+ local:
+--- ./jdk/make/mapfiles/libsplashscreen/mapfile-vers Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/mapfiles/libsplashscreen/mapfile-vers Wed Feb 04 12:14:43 2015 -0800
+@@ -35,6 +35,7 @@
+ Java_java_awt_SplashScreen__1getImageFileName;
+ Java_java_awt_SplashScreen__1getImageJarName;
+ Java_java_awt_SplashScreen__1setImageData;
++ Java_java_awt_SplashScreen__1getScaleFactor;
+
+ SplashLoadMemory;
+ SplashLoadFile;
+--- ./jdk/make/profile-rtjar-includes.txt Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/make/profile-rtjar-includes.txt Wed Feb 04 12:14:43 2015 -0800
+@@ -117,6 +117,8 @@
+ com/sun/security/ntlm \
+ com/sun/security/sasl \
+ com/sun/tracing \
++ jdk/management \
++ jdk/internal/cmm \
+ java/lang/instrument \
+ java/lang/management \
+ java/security/acl \
+--- ./jdk/src/aix/classes/sun/awt/fontconfigs/aix.fontconfig.properties Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/aix/classes/sun/awt/fontconfigs/aix.fontconfig.properties Wed Feb 04 12:14:43 2015 -0800
+@@ -24,9 +24,14 @@
+ # questions.
+ #
+
+-# Minimal version for AIX using the standard Latin Type1 Fonts from the
+-# package X11.fnt.iso_T1. These fonts are installed by default into
+-# "/usr/lpp/X11/lib/X11/fonts/Type1" and sym-linked to "/usr/lib/X11/fonts/Type1"
++#
++# Portions Copyright (c) 2014 IBM Corporation
++#
++
++# This file references the standard Latin Type1 fonts from the AIX package
++# X11.fnt.iso_T1 and the Unicode TrueType fonts from X11.fnt.ucs.ttf. They
++# are located by default under "/usr/lpp/X11/lib/X11/fonts/{Type1,TrueType}"
++# and sym-linked to "/usr/lib/X11/fonts/".
+
+ # Version
+
+@@ -34,44 +39,381 @@
+
+ # Component Font Mappings
+
+-dialog.plain.latin-1=-*-helvetica-medium-r-normal--*-%d-100-100-p-*-iso10646-1
+-dialog.bold.latin-1=-*-helvetica-bold-r-normal--*-%d-100-100-p-*-iso10646-1
+-dialog.italic.latin-1=-*-helvetica-medium-o-normal--*-%d-100-100-p-*-iso10646-1
+-dialog.bolditalic.latin-1=-*-helvetica-bold-o-normal--*-%d-100-100-p-*-iso10646-1
++allfonts.iso10646-extB=-monotype-sansmonowtextb-medium-r-normal--*-%d-75-75-m-*-unicode-2
+
+-dialoginput.plain.latin-1=-*-courier-medium-r-normal--*-%d-100-100-m-*-iso10646-1
+-dialoginput.bold.latin-1=-*-courier-bold-r-normal--*-%d-100-100-m-*-iso10646-1
+-dialoginput.italic.latin-1=-*-courier-medium-o-normal--*-%d-100-100-m-*-iso10646-1
+-dialoginput.bolditalic.latin-1=-*-courier-bold-o-normal--*-%d-100-100-m-*-iso10646-1
+
+-sansserif.plain.latin-1=-*-helvetica-medium-r-normal--*-%d-100-100-p-*-iso10646-1
+-sansserif.bold.latin-1=-*-helvetica-bold-r-normal--*-%d-100-100-p-*-iso10646-1
+-sansserif.italic.latin-1=-*-helvetica-medium-o-normal--*-%d-100-100-p-*-iso10646-1
+-sansserif.bolditalic.latin-1=-*-helvetica-bold-o-normal--*-%d-100-100-p-*-iso10646-1
++dialog.plain.latin-1=-*-helvetica-medium-r-normal--*-%d-100-100-p-*-iso8859-1
++dialog.plain.thai=-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
++dialog.plain.ukranian-ibm1124=-*-*-medium-r-normal--*-%d-75-75-p-*-ucs2.i18n-0
++dialog.plain.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++dialog.plain.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++dialog.plain.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++dialog.plain.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++dialog.plain.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++dialog.plain.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++dialog.plain.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++dialog.plain.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++dialog.plain.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+
+-serif.plain.latin-1=-*-times new roman-medium-r-normal--*-%d-100-100-p-*-iso10646-1
+-serif.bold.latin-1=-*-times new roman-bold-r-normal--*-%d-100-100-p-*-iso10646-1
+-serif.italic.latin-1=-*-times new roman-medium-i-normal--*-%d-100-100-p-*-iso10646-1
+-serif.bolditalic.latin-1=-*-times new roman-bold-i-normal--*-%d-100-100-p-*-iso10646-1
++dialog.bold.latin-1=-*-helvetica-bold-r-normal--*-%d-100-100-p-*-iso8859-1
++dialog.bold.thai=-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
++dialog.bold.ukranian-ibm1124=-*-*-bold-r-normal--*-%d-75-75-p-*-ucs2.i18n-0
++dialog.bold.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++dialog.bold.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++dialog.bold.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++dialog.bold.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++dialog.bold.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++dialog.bold.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++dialog.bold.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++dialog.bold.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++dialog.bold.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+
+-monospaced.plain.latin-1=-*-courier-medium-r-normal--*-%d-100-100-m-*-iso10646-1
+-monospaced.bold.latin-1=-*-courier-bold-r-normal--*-%d-100-100-m-*-iso10646-1
+-monospaced.italic.latin-1=-*-courier-medium-o-normal--*-%d-100-100-m-*-iso10646-1
+-monospaced.bolditalic.latin-1=-*-courier-bold-o-normal--*-%d-100-100-m-*-iso10646-1
++dialog.italic.latin-1=-*-helvetica-medium-o-normal--*-%d-100-100-p-*-iso8859-1
++dialog.italic.thai=-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
++dialog.italic.ukranian-ibm1124=-*-*-medium-i-normal--*-%d-75-75-p-*-ucs2.i18n-0
++dialog.italic.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++dialog.italic.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++dialog.italic.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++dialog.italic.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++dialog.italic.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++dialog.italic.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++dialog.italic.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++dialog.italic.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++dialog.italic.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++dialog.bolditalic.latin-1=-*-helvetica-bold-o-normal--*-%d-100-100-p-*-iso8859-1
++dialog.bolditalic.thai=-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
++dialog.bolditalic.ukranian-ibm1124=-*-*-medium-r-normal--*-%d-75-75-p-*-ucs2.i18n-0
++dialog.bolditalic.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++dialog.bolditalic.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++dialog.bolditalic.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++dialog.bolditalic.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++dialog.bolditalic.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++dialog.bolditalic.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++dialog.bolditalic.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++dialog.bolditalic.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++dialog.bolditalic.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++dialoginput.plain.latin-1=-*-courier-medium-r-normal--*-%d-100-100-m-*-iso8859-1
++dialoginput.plain.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
++dialoginput.plain.ukranian-ibm1124=-*-*-medium-r-normal--*-%d-75-75-m-*-ucs2.i18n-0
++dialoginput.plain.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++dialoginput.plain.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++dialoginput.plain.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++dialoginput.plain.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++dialoginput.plain.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++dialoginput.plain.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++dialoginput.plain.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++dialoginput.plain.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++dialoginput.plain.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++dialoginput.bold.latin-1=-*-courier-bold-r-normal--*-%d-100-100-m-*-iso8859-1
++dialoginput.bold.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
++dialoginput.bold.ukranian-ibm1124=-*-*-bold-r-normal--*-%d-75-75-m-*-ucs2.i18n-0
++dialoginput.bold.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++dialoginput.bold.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++dialoginput.bold.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++dialoginput.bold.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++dialoginput.bold.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++dialoginput.bold.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++dialoginput.bold.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++dialoginput.bold.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++dialoginput.bold.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++dialoginput.italic.latin-1=-*-courier-medium-o-normal--*-%d-100-100-m-*-iso8859-1
++dialoginput.italic.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
++dialoginput.italic.ukranian-ibm1124=-*-*-medium-i-normal--*-%d-75-75-m-*-ucs2.i18n-0
++dialoginput.italic.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++dialoginput.italic.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++dialoginput.italic.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++dialoginput.italic.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++dialoginput.italic.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++dialoginput.italic.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++dialoginput.italic.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++dialoginput.italic.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++dialoginput.italic.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++dialoginput.bolditalic.latin-1=-*-courier-bold-o-normal--*-%d-100-100-m-*-iso8859-1
++dialoginput.bolditalic.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
++dialoginput.bolditalic.ukranian-ibm1124=-*-*-medium-r-normal--*-%d-75-75-m-*-ucs2.i18n-0
++dialoginput.bolditalic.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++dialoginput.bolditalic.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++dialoginput.bolditalic.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++dialoginput.bolditalic.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++dialoginput.bolditalic.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++dialoginput.bolditalic.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++dialoginput.bolditalic.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++dialoginput.bolditalic.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++dialoginput.bolditalic.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++sansserif.plain.latin-1=-*-helvetica-medium-r-normal--*-%d-100-100-p-*-iso8859-1
++sansserif.plain.thai=-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
++sansserif.plain.ukranian-ibm1124=-*-*-medium-r-normal--*-%d-75-75-p-*-ucs2.i18n-0
++sansserif.plain.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++sansserif.plain.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++sansserif.plain.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++sansserif.plain.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++sansserif.plain.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++sansserif.plain.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++sansserif.plain.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++sansserif.plain.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++sansserif.plain.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++sansserif.bold.latin-1=-*-helvetica-bold-r-normal--*-%d-100-100-p-*-iso8859-1
++sansserif.bold.thai=-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
++sansserif.bold.ukranian-ibm1124=-*-*-bold-r-normal--*-%d-75-75-p-*-ucs2.i18n-0
++sansserif.bold.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++sansserif.bold.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++sansserif.bold.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++sansserif.bold.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++sansserif.bold.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++sansserif.bold.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++sansserif.bold.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++sansserif.bold.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++sansserif.bold.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++sansserif.italic.latin-1=-*-helvetica-medium-o-normal--*-%d-100-100-p-*-iso8859-1
++sansserif.italic.thai=-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
++sansserif.italic.ukranian-ibm1124=-*-*-medium-i-normal--*-%d-75-75-p-*-ucs2.i18n-0
++sansserif.italic.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++sansserif.italic.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++sansserif.italic.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++sansserif.italic.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++sansserif.italic.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++sansserif.italic.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++sansserif.italic.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++sansserif.italic.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++sansserif.italic.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++sansserif.bolditalic.latin-1=-*-helvetica-bold-o-normal--*-%d-100-100-p-*-iso8859-1
++sansserif.bolditalic.thai=-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
++sansserif.bolditalic.ukranian-ibm1124=-*-*-medium-r-normal--*-%d-75-75-p-*-ucs2.i18n-0
++sansserif.bolditalic.japanese-x0208=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++sansserif.bolditalic.japanese-x0201=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++sansserif.bolditalic.japanese-udc=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++sansserif.bolditalic.japanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++sansserif.bolditalic.korean=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++sansserif.bolditalic.korean-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++sansserif.bolditalic.chinese=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++sansserif.bolditalic.chinese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++sansserif.bolditalic.taiwanese-iso10646=-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++serif.plain.latin-1=-*-times new roman-medium-r-normal--*-%d-100-100-p-*-iso8859-1
++serif.plain.thai=-ibm-thaitimes-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
++serif.plain.ukranian-ibm1124=-*-*-medium-r-normal--*-%d-75-75-p-*-ucs2.i18n-0
++serif.plain.japanese-x0208=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++serif.plain.japanese-x0201=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++serif.plain.japanese-udc=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++serif.plain.japanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++serif.plain.korean=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++serif.plain.korean-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++serif.plain.chinese=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++serif.plain.chinese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++serif.plain.taiwanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++serif.bold.latin-1=-*-times new roman-bold-r-normal--*-%d-100-100-p-*-iso8859-1
++serif.bold.thai=-ibm-thaitimes-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
++serif.bold.ukranian-ibm1124=-*-*-bold-r-normal--*-%d-75-75-p-*-ucs2.i18n-0
++serif.bold.japanese-x0208=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++serif.bold.japanese-x0201=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++serif.bold.japanese-udc=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++serif.bold.japanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++serif.bold.korean=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++serif.bold.korean-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++serif.bold.chinese=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++serif.bold.chinese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++serif.bold.taiwanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++
++serif.italic.latin-1=-*-times new roman-medium-i-normal--*-%d-100-100-p-*-iso8859-1
++serif.italic.thai=-ibm-thaitimes-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
++serif.italic.ukranian-ibm1124=-*-*-medium-i-normal--*-%d-75-75-p-*-ucs2.i18n-0
++serif.italic.japanese-x0208=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++serif.italic.japanese-x0201=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++serif.italic.japanese-udc=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++serif.italic.japanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++serif.italic.korean=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++serif.italic.korean-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++serif.italic.chinese=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++serif.italic.chinese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++serif.italic.taiwanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++serif.bolditalic.latin-1=-*-times new roman-bold-i-normal--*-%d-100-100-p-*-iso8859-1
++serif.bolditalic.thai=-ibm-thaitimes-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0
++serif.bolditalic.ukranian-ibm1124=-*-*-medium-r-normal--*-%d-75-75-p-*-ucs2.i18n-0
++serif.bolditalic.japanese-x0208=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++serif.bolditalic.japanese-x0201=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++serif.bolditalic.japanese-udc=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++serif.bolditalic.japanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++serif.bolditalic.korean=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++serif.bolditalic.korean-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++serif.bolditalic.chinese=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++serif.bolditalic.chinese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++serif.bolditalic.taiwanese-iso10646=-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++monospaced.plain.latin-1=-*-courier-medium-r-normal--*-%d-100-100-m-*-iso8859-1
++monospaced.plain.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
++monospaced.plain.ukranian-ibm1124=-*-*-medium-r-normal--*-%d-75-75-m-*-ucs2.i18n-0
++monospaced.plain.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++monospaced.plain.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++monospaced.plain.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++monospaced.plain.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++monospaced.plain.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++monospaced.plain.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++monospaced.plain.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++monospaced.plain.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++monospaced.plain.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++monospaced.bold.latin-1=-*-courier-bold-r-normal--*-%d-100-100-m-*-iso8859-1
++monospaced.bold.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
++monospaced.bold.ukranian-ibm1124=-*-*-bold-r-normal--*-%d-75-75-m-*-ucs2.i18n-0
++monospaced.bold.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++monospaced.bold.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++monospaced.bold.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++monospaced.bold.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++monospaced.bold.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++monospaced.bold.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++monospaced.bold.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++monospaced.bold.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++monospaced.bold.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++monospaced.italic.latin-1=-*-courier-medium-o-normal--*-%d-100-100-m-*-iso8859-1
++monospaced.italic.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
++monospaced.italic.ukranian-ibm1124=-*-*-medium-i-normal--*-%d-75-75-m-*-ucs2.i18n-0
++monospaced.italic.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++monospaced.italic.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++monospaced.italic.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++monospaced.italic.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++monospaced.italic.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++monospaced.italic.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++monospaced.italic.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++monospaced.italic.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++monospaced.italic.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
++
++monospaced.bolditalic.latin-1=-*-courier-bold-o-normal--*-%d-100-100-m-*-iso8859-1
++monospaced.bolditalic.thai=-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0
++monospaced.bolditalic.ukranian-ibm1124=-*-*-medium-r-normal--*-%d-75-75-m-*-ucs2.i18n-0
++monospaced.bolditalic.japanese-x0208=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0
++monospaced.bolditalic.japanese-x0201=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0
++monospaced.bolditalic.japanese-udc=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp
++monospaced.bolditalic.japanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0
++monospaced.bolditalic.korean=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0
++monospaced.bolditalic.korean-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0
++monospaced.bolditalic.chinese=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0
++monospaced.bolditalic.chinese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0
++monospaced.bolditalic.taiwanese-iso10646=-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0
+
+ # Search Sequences
+
+ sequence.allfonts=latin-1
++sequence.allfonts.UTF-8=latin-1,japanese-iso10646
++# Uk_UA
++sequence.allfonts.x-IBM1124=latin-1,ukranian-ibm1124
++# Japanese
++sequence.allfonts.x-IBM943C=latin-1,japanese-x0201,japanese-x0208,japanese-udc
++sequence.allfonts.x-IBM29626C=latin-1,japanese-x0201,japanese-x0208,japanese-udc
++sequence.allfonts.UTF-8.ja=japanese-iso10646,latin-1,iso10646-extB
++# Chinese
++sequence.allfonts.x-EUC_CN=latin-1,chinese
++sequence.allfonts.GB18030=latin-1,chinese-iso10646,iso10646-extB
++sequence.allfonts.UTF-8.zh.CN=latin-1,chinese-iso10646,iso10646-extB
++# Taiwanese
++sequence.allfonts.x-IBM964=latin-1,taiwanese-iso10646
++sequence.allfonts.Big5=latin-1,taiwanese-iso10646
++sequence.allfonts.UTF-8.zh.TW=latin-1,taiwanese-iso10646
++# Korean
++sequence.allfonts.x-IBM970=latin-1,korean
++sequence.allfonts.UTF-8.ko=latin-1,korean-iso10646
++# Thai
++sequence.allfonts.TIS-620=latin-1,thai
++sequence.allfonts.UTF-8.th=latin-1,thai
++# fallback
++sequence.fallback=thai,chinese-iso10646,taiwanese-iso10646,japanese-iso10646,korean-iso10646,iso10646-extB
+
+-filename.-*-courier-medium-r-normal--*-%d-100-100-m-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/cour.pfa
+-filename.-*-courier-bold-r-normal--*-%d-100-100-m-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/courb.pfa
+-filename.-*-courier-medium-o-normal--*-%d-100-100-m-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/couri.pfa
+-filename.-*-courier-bold-o-normal--*-%d-100-100-m-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/courbi.pfa
+-filename.-*-helvetica-medium-r-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/helv.pfa
+-filename.-*-helvetica-bold-r-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/helvb.pfa
+-filename.-*-helvetica-medium-o-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/helvi.pfa
+-filename.-*-helvetica-bold-o-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/helvbi.pfa
+-filename.-*-times_new_roman-medium-r-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/tnr.pfa
+-filename.-*-times_new_roman-bold-r-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/tnrb.pfa
+-filename.-*-times_new_roman-medium-i-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/tnri.pfa
+-filename.-*-times_new_roman-bold-i-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/tnrbi.pfa
++# Exclusion Ranges
++exclusion.japanese-iso10646=0000-00ff
++
++# Font File Names
++filename.-*-courier-medium-r-normal--*-%d-100-100-m-*-iso8859-1=/usr/lpp/X11/lib/X11/fonts/Type1/cour.pfa
++filename.-*-courier-bold-r-normal--*-%d-100-100-m-*-iso8859-1=/usr/lpp/X11/lib/X11/fonts/Type1/courb.pfa
++filename.-*-courier-medium-o-normal--*-%d-100-100-m-*-iso8859-1=/usr/lpp/X11/lib/X11/fonts/Type1/couri.pfa
++filename.-*-courier-bold-o-normal--*-%d-100-100-m-*-iso8859-1=/usr/lpp/X11/lib/X11/fonts/Type1/courbi.pfa
++filename.-*-helvetica-medium-r-normal--*-%d-100-100-p-*-iso8859-1=/usr/lpp/X11/lib/X11/fonts/Type1/helv.pfa
++filename.-*-helvetica-bold-r-normal--*-%d-100-100-p-*-iso8859-1=/usr/lpp/X11/lib/X11/fonts/Type1/helvb.pfa
++filename.-*-helvetica-medium-o-normal--*-%d-100-100-p-*-iso8859-1=/usr/lpp/X11/lib/X11/fonts/Type1/helvi.pfa
++filename.-*-helvetica-bold-o-normal--*-%d-100-100-p-*-iso8859-1=/usr/lpp/X11/lib/X11/fonts/Type1/helvbi.pfa
++filename.-*-times_new_roman-medium-r-normal--*-%d-100-100-p-*-iso8859-1=/usr/lpp/X11/lib/X11/fonts/Type1/tnr.pfa
++filename.-*-times_new_roman-bold-r-normal--*-%d-100-100-p-*-iso8859-1=/usr/lpp/X11/lib/X11/fonts/Type1/tnrb.pfa
++filename.-*-times_new_roman-medium-i-normal--*-%d-100-100-p-*-iso8859-1=/usr/lpp/X11/lib/X11/fonts/Type1/tnri.pfa
++filename.-*-times_new_roman-bold-i-normal--*-%d-100-100-p-*-iso8859-1=/usr/lpp/X11/lib/X11/fonts/Type1/tnrbi.pfa
++
++
++filename.-monotype-sansmonowtextb-medium-r-normal--*-%d-75-75-m-*-unicode-2=/usr/lpp/X11/lib/X11/fonts/TrueType/MTSanXBA.ttf
++
++filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
++filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
++filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
++filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
++filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_k.ttf
++filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_k.ttf
++filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_s.ttf
++filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_s.ttf
++filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_s.ttf
++filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_s.ttf
++filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_t.ttf
++
++filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
++filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
++filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
++filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
++filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdk.ttf
++filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdk.ttf
++filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansds.ttf
++filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansds.ttf
++filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdt.ttf
++filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0208.1983-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_j.ttf
++filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-jisx0201.1976-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_j.ttf
++filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ibm-udcjp=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_j.ttf
++filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_japan-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_j.ttf
++filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ksc5601.1987-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_k.ttf
++filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_korea-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_k.ttf
++filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-gb2312.1980-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_s.ttf
++filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_china-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_s.ttf
++filename.-monotype-sanswt-medium-r-normal--*-%d-75-75-*-*-ucs2.cjk_taiwan-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsans_t.ttf
++
++filename.-monotype-timesnewromanwt-medium-r-normal--*-%d-75-75-*-*-iso8859-15=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
++filename.-monotype-sansmonowt-medium-r-normal--*-%d-75-75-*-*-iso8859-15=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
++
++filename.-ibm-thaicourier-medium-r-normal--*-%d-75-75-m-*-ucs2.thai-0=/usr/lpp/X11/lib/X11/fonts/TrueType/courth.ttf
++filename.-ibm-thaihelvetica-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0=/usr/lpp/X11/lib/X11/fonts/TrueType/helvth.ttf
++filename.-ibm-thaitimes-medium-r-normal--*-%d-75-75-p-*-ucs2.thai-0=/usr/lpp/X11/lib/X11/fonts/TrueType/timeth.ttf
++
++filename.-*-*-medium-r-normal--*-%d-*-*-p-*-ibm-1046=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
++filename.-*-*-bold-r-normal--*-%d-*-*-p-*-ibm-1046=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
++filename.-*-*-medium-i-normal--*-%d-*-*-p-*-ibm-1046=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
++filename.-*-*-bold-i-normal--*-%d-*-*-p-*-ibm-1046=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
++filename.-*-*-medium-r-normal--*-%d-*-*-m-*-ibm-1046=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
++filename.-*-*-bold-r-normal--*-%d-*-*-m-*-ibm-1046=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
++filename.-*-*-medium-i-normal--*-%d-*-*-m-*-ibm-1046=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
++filename.-*-*-bold-i-normal--*-%d-*-*-m-*-ibm-1046=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
++
++filename.-*-*-medium-r-normal--*-%d-75-75-p-*-ucs2.i18n-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
++filename.-*-*-bold-r-normal--*-%d-75-75-p-*-ucs2.i18n-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
++filename.-*-*-medium-i-normal--*-%d-75-75-p-*-ucs2.i18n-0=/usr/lpp/X11/lib/X11/fonts/TrueType/tnrwt_j.ttf
++filename.-*-*-medium-r-normal--*-%d-75-75-m-*-ucs2.i18n-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
++filename.-*-*-bold-r-normal--*-%d-75-75-m-*-ucs2.i18n-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
++filename.-*-*-medium-i-normal--*-%d-75-75-m-*-ucs2.i18n-0=/usr/lpp/X11/lib/X11/fonts/TrueType/mtsansdj.ttf
++
++# AWT font path
++awtfontpath.japanese-x0201=/usr/lpp/X11/lib/X11/fonts/TrueType
++awtfontpath.japanese-x0208=/usr/lpp/X11/lib/X11/fonts/TrueType
++awtfontpath.japanese-udc=/usr/lpp/X11/lib/X11/fonts/TrueType
++awtfontpath.japanese-iso10646=/usr/lpp/X11/lib/X11/fonts/TrueType
++awtfontpath.korean=/usr/lpp/X11/lib/X11/fonts/TrueType
++awtfontpath.korean-iso10646=/usr/lpp/X11/lib/X11/fonts/TrueType
++awtfontpath.chinese=/usr/lpp/X11/lib/X11/fonts/TrueType
++awtfontpath.chinese-iso10646=/usr/lpp/X11/lib/X11/fonts/TrueType
++awtfontpath.taiwanese-iso10646=/usr/lpp/X11/lib/X11/fonts/TrueType
++awtfontpath.thai=/usr/lpp/X11/lib/X11/fonts/TrueType
++awtfontpath.iso10646-extB=/usr/lpp/X11/lib/X11/fonts/TrueType
++
+--- ./jdk/src/bsd/doc/man/java.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/bsd/doc/man/java.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ '\" t
+-.\" Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
++.\" Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
+ .\"
+ .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ .\"
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: java
+ .\" Language: English
+-.\" Date: 08 August 2014
++.\" Date: 03 March 2015
+ .\" SectDesc: Basic Tools
+ .\" Software: JDK 8
+ .\" Arch: generic
+-.\" Part Number: E38207-03
++.\" Part Number: E38207-04
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "java" "1" "08 August 2014" "JDK 8" "Basic Tools"
++.TH "java" "1" "03 March 2015" "JDK 8" "Basic Tools"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -333,7 +334,6 @@
+ Selects the Java HotSpot Client VM\&. The 64\-bit version of the Java SE Development Kit (JDK) currently ignores this option and instead uses the Server JVM\&.
+ .sp
+ For default JVM selection, see Server\-Class Machine Detection at
+-
+ http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/server\-class\&.html
+ .RE
+ .PP
+@@ -550,7 +550,6 @@
+ Selects the Java HotSpot Server VM\&. The 64\-bit version of the JDK supports only the Server VM, so in that case the option is implicit\&.
+ .sp
+ For default JVM selection, see Server\-Class Machine Detection at
+-
+ http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/server\-class\&.html
+ .RE
+ .PP
+@@ -772,13 +771,14 @@
+ \fBg\fR
+ or
+ \fBG\fR
+-to indicate gigabytes\&. By default, the value is set to 48 MB:
++to indicate gigabytes\&. The default maximum code cache size is 240 MB; if you disable tiered compilation with the option
++\fB\-XX:\-TieredCompilation\fR, then the default size is 48 MB:
+ .sp
+ .if n \{\
+ .RS 4
+ .\}
+ .nf
+-\fB\-Xmaxjitcodesize=48m\fR
++\fB\-Xmaxjitcodesize=240m\fR
+
+ .fi
+ .if n \{\
+@@ -889,7 +889,9 @@
+ \fB\-Xms\fR
+ and
+ \fB\-Xmx\fR
+-are often set to the same value\&. For more information, see Garbage Collector Ergonomics at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gc\-ergonomics\&.html
++are often set to the same value\&. See the section "Ergonomics" in
++\fIJava SE HotSpot Virtual Machine Garbage Collection Tuning Guide\fR
++at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gctuning/index\&.html\&.
+ .sp
+ The following examples show how to set the maximum allowed size of allocated memory to 80 MB using various units:
+ .sp
+@@ -986,28 +988,30 @@
+ .PP
+ \-Xshare:\fImode\fR
+ .RS 4
+-Sets the class data sharing mode\&. Possible
++Sets the class data sharing (CDS) mode\&. Possible
+ \fImode\fR
+ arguments for this option include the following:
+ .PP
+ auto
+ .RS 4
+-Use shared class data if possible\&. This is the default value for Java HotSpot 32\-Bit Client VM\&.
++Use CDS if possible\&. This is the default value for Java HotSpot 32\-Bit Client VM\&.
+ .RE
+ .PP
+ on
+ .RS 4
+-Require the use of class data sharing\&. Print an error message and exit if class data sharing cannot be used\&.
++Require the use of CDS\&. Print an error message and exit if class data sharing cannot be used\&.
+ .RE
+ .PP
+ off
+ .RS 4
+-Do not use shared class data\&. This is the default value for Java HotSpot 32\-Bit Server VM, Java HotSpot 64\-Bit Client VM, and Java HotSpot 64\-Bit Server VM\&.
++Do not use CDS\&. This is the default value for Java HotSpot 32\-Bit Server VM, Java HotSpot 64\-Bit Client VM, and Java HotSpot 64\-Bit Server VM\&.
+ .RE
+ .PP
+ dump
+ .RS 4
+-Manually generate the class data sharing archive\&.
++Manually generate the CDS archive\&. Specify the application class path as described in "Setting the Class Path "\&.
++.sp
++You should regenerate the CDS archive with each new JDK release\&.
+ .RE
+ .RE
+ .PP
+@@ -1120,17 +1124,6 @@
+ Oracle Solaris/x64 (64\-bit): 1024 KB
+ .RE
+ .sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-Windows: depends on virtual memory
+-.RE
+-.sp
+ The following examples set the thread stack size to 1024 KB in different units:
+ .sp
+ .if n \{\
+@@ -1172,7 +1165,7 @@
+ .PP
+ remote
+ .RS 4
+-Verify only those classes that are loaded remotely over the network\&. This is the default behavior if you do not specify the
++Verify those classes that are not loaded by the bootstrap class loader\&. This is the default behavior if you do not specify the
+ \fB\-Xverify\fR
+ option\&.
+ .RE
+@@ -1186,6 +1179,65 @@
+ .PP
+ These options control the runtime behavior of the Java HotSpot VM\&.
+ .PP
++\-XX:+CheckEndorsedAndExtDirs
++.RS 4
++Enables the option to prevent the
++\fBjava\fR
++command from running a Java application if it uses the endorsed\-standards override mechanism or the extension mechanism\&. This option checks if an application is using one of these mechanisms by checking the following:
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++The
++\fBjava\&.ext\&.dirs\fR
++or
++\fBjava\&.endorsed\&.dirs\fR
++system property is set\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++The
++\fBlib/endorsed\fR
++directory exists and is not empty\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++The
++\fBlib/ext\fR
++directory contains any JAR files other than those of the JDK\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++The system\-wide platform\-specific extension directory contains any JAR files\&.
++.RE
++.RE
++.PP
+ \-XX:+DisableAttachMechanism
+ .RS 4
+ Enables the option that disables the mechanism that lets tools attach to the JVM\&. By default, this option is disabled, meaning that the attach mechanism is enabled and you can use tools such as
+@@ -1238,7 +1290,7 @@
+ .PP
+ \-XX:LargePageSizeInBytes=\fIsize\fR
+ .RS 4
+-Sets the maximum size (in bytes) for large pages used for Java heap\&. The
++On Solaris, sets the maximum size (in bytes) for large pages used for Java heap\&. The
+ \fIsize\fR
+ argument must be a power of 2 (2, 4, 8, 16, \&.\&.\&.)\&. Append the letter
+ \fBk\fR
+@@ -1327,6 +1379,17 @@
+ .RE
+ .RE
+ .PP
++\-XX:ObjectAlignmentInBytes=\fIalignment\fR
++.RS 4
++Sets the memory alignment of Java objects (in bytes)\&. By default, the value is set to 8 bytes\&. The specified value should be a power of two, and must be within the range of 8 and 256 (inclusive)\&. This option makes it possible to use compressed pointers with large Java heap sizes\&.
++.sp
++The heap size limit in bytes is calculated as:
++.sp
++\fB4GB * ObjectAlignmentInBytes\fR
++.sp
++Note: As the alignment value increases, the unused space between objects will also increase\&. As a result, you may not realize any benefits from using compressed pointers with large Java heap sizes\&.
++.RE
++.PP
+ \-XX:OnError=\fIstring\fR
+ .RS 4
+ Sets a custom command or a series of semicolon\-separated commands to run when an irrecoverable error occurs\&. If the string contains spaces, then it must be enclosed in quotation marks\&.
+@@ -1360,6 +1423,28 @@
+ option\&.
+ .RE
+ .PP
++\-XX:+PerfDataSaveToFile
++.RS 4
++If enabled, saves
++jstat(1) binary data when the Java application exits\&. This binary data is saved in a file named
++\fBhsperfdata_\fR\fI<pid>\fR, where
++\fI<pid>\fR
++is the process identifier of the Java application you ran\&. Use
++\fBjstat\fR
++to display the performance data contained in this file as follows:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjstat \-class file:///\fR\fB\fI<path>\fR\fR\fB/hsperfdata_\fR\fB\fI<pid>\fR\fR
++\fBjstat \-gc file:///\fR\fB\fI<path>\fR\fR\fB/hsperfdata_\fR\fB\fI<pid>\fR\fR
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.PP
+ \-XX:+PrintCommandLineFlags
+ .RS 4
+ Enables printing of ergonomically selected JVM flags that appeared on the command line\&. It can be useful to know the ergonomic values set by the JVM, such as the heap space size and the selected garbage collector\&. By default, this option is disabled and flags are not printed\&.
+@@ -1463,17 +1548,6 @@
+ Oracle Solaris/x64 (64\-bit): 1024 KB
+ .RE
+ .sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-Windows: depends on virtual memory
+-.RE
+-.sp
+ The following examples show how to set the thread stack size to 1024 KB in different units:
+ .sp
+ .if n \{\
+@@ -1537,13 +1611,27 @@
+ \-XX:\-UseCompressedOops
+ .RS 4
+ Disables the use of compressed pointers\&. By default, this option is enabled, and compressed pointers are used when Java heap sizes are less than 32 GB\&. When this option is enabled, object references are represented as 32\-bit offsets instead of 64\-bit pointers, which typically increases performance when running the application with Java heap sizes less than 32 GB\&. This option works only for 64\-bit JVMs\&.
++.sp
++It is also possible to use compressed pointers when Java heap sizes are greater than 32GB\&. See the
++\fB\-XX:ObjectAlignmentInBytes\fR
++option\&.
+ .RE
+ .PP
+-\-XX:\-UseLargePages
+-.RS 4
+-Disables the use of large page memory\&. This option is enabled by default\&.
++\-XX:+UseHugeTLBFS
++.RS 4
++This option for Linux is the equivalent of specifying
++\fB\-XX:+UseLargePages\fR\&. This option is disabled by default\&. This option pre\-allocates all large pages up\-front, when memory is reserved; consequently the JVM cannot dynamically grow or shrink large pages memory areas; see
++\fB\-XX:UseTransparentHugePages\fR
++if you want this behavior\&.
+ .sp
+-For more information, see Java Support for Large Memory Pages at http://www\&.oracle\&.com/technetwork/java/javase/tech/largememory\-jsp\-137182\&.html
++For more information, see "Large Pages"\&.
++.RE
++.PP
++\-XX:+UseLargePages
++.RS 4
++Enables the use of large page memory\&. By default, this option is disabled and large page memory is not used\&.
++.sp
++For more information, see "Large Pages"\&.
+ .RE
+ .PP
+ \-XX:+UseMembar
+@@ -1563,6 +1651,13 @@
+ \fB\-XX:\-UsePerfData\fR\&.
+ .RE
+ .PP
++\-XX:+UseTransparentHugePages
++.RS 4
++On Linux, enables the use of large pages that can dynamically grow or shrink\&. This option is disabled by default\&. You may encounter performance problems with transparent huge pages as the OS moves other pages around to create huge pages; this option is made available for experimentation\&.
++.sp
++For more information, see "Large Pages"\&.
++.RE
++.PP
+ \-XX:+AllowUserSignalHandlers
+ .RS 4
+ Enables installation of signal handlers by the application\&. By default, this option is disabled and the application is not allowed to install signal handlers\&.
+@@ -2041,7 +2136,8 @@
+ .PP
+ \-XX:CompileThreshold=\fIinvocations\fR
+ .RS 4
+-Sets the number of interpreted method invocations before compilation\&. By default, in the server JVM, the JIT compiler performs 10,000 interpreted method invocations to gather information for efficient compilation\&. For the client JVM, the default setting is 1,500 invocations\&. The following example shows how to set the number of interpreted method invocations to 5,000:
++Sets the number of interpreted method invocations before compilation\&. By default, in the server JVM, the JIT compiler performs 10,000 interpreted method invocations to gather information for efficient compilation\&. For the client JVM, the default setting is 1,500 invocations\&. This option is ignored when tiered compilation is enabled; see the option
++\fB\-XX:+TieredCompilation\fR\&. The following example shows how to set the number of interpreted method invocations to 5,000:
+ .sp
+ .if n \{\
+ .RS 4
+@@ -2078,7 +2174,7 @@
+ \fBg\fR
+ or
+ \fBG\fR
+-to indicate gigabytes\&. The default value is set to 500 KB\&. The following example shows how to set the initial code cache size to 32 KB:
++to indicate gigabytes\&. The default value is set to 500 KB\&. The initial code cache size should be not less than the system\*(Aqs minimal memory page size\&. The following example shows how to set the initial code cache size to 32 KB:
+ .sp
+ .if n \{\
+ .RS 4
+@@ -2274,13 +2370,29 @@
+ \fBg\fR
+ or
+ \fBG\fR
+-to indicate gigabytes\&. This option is equivalent to
++to indicate gigabytes\&. The default maximum code cache size is 240 MB; if you disable tiered compilation with the option
++\fB\-XX:\-TieredCompilation\fR, then the default size is 48 MB\&. This option has a limit of 2 GB; otherwise, an error is generated\&. The maximum code cache size should not be less than the initial code cache size; see the option
++\fB\-XX:InitialCodeCacheSize\fR\&. This option is equivalent to
+ \fB\-Xmaxjitcodesize\fR\&.
+ .RE
+ .PP
+-\-XX:+TieredCompilation
+-.RS 4
+-Enables the use of tiered compilation\&. By default, this option is enabled\&. Only the Java HotSpot Server VM supports this option\&.
++\-XX:RTMAbortRatio=\fIabort_ratio\fR
++.RS 4
++The RTM abort ratio is specified as a percentage (%) of all executed RTM transactions\&. If a number of aborted transactions becomes greater than this ratio, then the compiled code will be deoptimized\&. This ratio is used when the
++\fB\-XX:+UseRTMDeopt\fR
++option is enabled\&. The default value of this option is 50\&. This means that the compiled code will be deoptimized if 50% of all transactions are aborted\&.
++.RE
++.PP
++\-XX:RTMRetryCount=\fInumber_of_retries\fR
++.RS 4
++RTM locking code will be retried, when it is aborted or busy, the number of times specified by this option before falling back to the normal locking mechanism\&. The default value for this option is 5\&. The
++\fB\-XX:UseRTMLocking\fR
++option must be enabled\&.
++.RE
++.PP
++\-XX:\-TieredCompilation
++.RS 4
++Disables the use of tiered compilation\&. By default, this option is enabled\&. Only the Java HotSpot Server VM supports this option\&.
+ .RE
+ .PP
+ \-XX:+UseAES
+@@ -2319,45 +2431,20 @@
+ Enables checking of whether the card is already marked before updating the card table\&. This option is disabled by default and should only be used on machines with multiple sockets, where it will increase performance of Java applications that rely heavily on concurrent operations\&. Only the Java HotSpot Server VM supports this option\&.
+ .RE
+ .PP
+-\-XX:+UseSuperWord
+-.RS 4
+-Enables the transformation of scalar operations into superword operations\&. This option is enabled by default\&. To disable the transformation of scalar operations into superword operations, specify
+-\fB\-XX:\-UseSuperWord\fR\&. Only the Java HotSpot Server VM supports this option\&.
+-.RE
+-.SS "Experimental JIT Compiler Options"
+-.PP
+-The options related to the Restricted Transactional Memory (RTM) locking feature in this section are experimental and are not officially supported in Java SE 8u20; you must enable the
+-\fB\-XX:+UnlockExperimentalVMOptions\fR
+-option to use them\&. These options are only available for the Java HotSpot Server VM on x86 CPUs that support Transactional Synchronization Extensions (TSX)\&.
+-.PP
+-\-XX:RTMAbortRatio=\fIabort_ratio\fR
+-.RS 4
+-The RTM abort ratio is specified as a percentage (%) of all executed RTM transactions\&. If a number of aborted transactions becomes greater than this ratio, then the compiled code will be deoptimized\&. This ratio is used when the
+-\fB\-XX:+UseRTMDeopt\fR
+-option is enabled\&. The default value of this option is 50\&. This means that the compiled code will be deoptimized if 50% of all transactions are aborted\&.
+-.RE
+-.PP
+-\-XX:RTMRetryCount=\fInumber_of_retries\fR
+-.RS 4
+-RTM locking code will be retried, when it is aborted or busy, the number of times specified by this option before falling back to the normal locking mechanism\&. The default value for this option is 5\&. The
+-\fB\-XX:UseRTMLocking\fR
+-option must be enabled\&.
+-.RE
+-.PP
+ \-XX:+UseRTMDeopt
+ .RS 4
+ Auto\-tunes RTM locking depending on the abort ratio\&. This ratio is specified by
+ \fB\-XX:RTMAbortRatio\fR
+ option\&. If the number of aborted transactions exceeds the abort ratio, then the method containing the lock will be deoptimized and recompiled with all locks as normal locks\&. This option is disabled by default\&. The
+-\fB\-XX:UseRTMLocking\fR
++\fB\-XX:+UseRTMLocking\fR
+ option must be enabled\&.
+ .RE
+ .PP
+ \-XX:+UseRTMLocking
+ .RS 4
+-Generate Restricted Transactional Memory (RTM) locking code for all inflated locks, with the normal locking mechanism as the fallback handler\&. This option is disabled by default\&.
++Generate Restricted Transactional Memory (RTM) locking code for all inflated locks, with the normal locking mechanism as the fallback handler\&. This option is disabled by default\&. Options related to RTM are only available for the Java HotSpot Server VM on x86 CPUs that support Transactional Synchronization Extensions (TSX)\&.
+ .sp
+-RTM is part of Intel\*(Aqs Transactional Synchronization Extensions (TSX), which is an x86 instruction set extension and facilitates the creation of multithreaded applications\&. RTM introduces the new instructions
++RTM is part of Intel\*(Aqs TSX, which is an x86 instruction set extension and facilitates the creation of multithreaded applications\&. RTM introduces the new instructions
+ \fBXBEGIN\fR,
+ \fBXABORT\fR,
+ \fBXEND\fR, and
+@@ -2377,6 +2464,52 @@
+ .sp
+ RTM improves performance for highly contended locks with low conflict in a critical region (which is code that must not be accessed by more than one thread concurrently)\&. RTM also improves the performance of coarse\-grain locking, which typically does not perform well in multithreaded applications\&. (Coarse\-grain locking is the strategy of holding locks for long periods to minimize the overhead of taking and releasing locks, while fine\-grained locking is the strategy of trying to achieve maximum parallelism by locking only when necessary and unlocking as soon as possible\&.) Also, for lightly contended locks that are used by different threads, RTM can reduce false cache line sharing, also known as cache line ping\-pong\&. This occurs when multiple threads from different processors are accessing different resources, but the resources share the same cache line\&. As a result, the processors repeatedly invalidate the cache lines of other processors, which forces them to read from main memory instead of their cache\&.
+ .RE
++.PP
++\-XX:+UseSHA
++.RS 4
++Enables hardware\-based intrinsics for SHA crypto hash functions for SPARC hardware\&.
++\fBUseSHA\fR
++is used in conjunction with the
++\fBUseSHA1Intrinsics\fR,
++\fBUseSHA256Intrinsics\fR, and
++\fBUseSHA512Intrinsics\fR
++options\&.
++.sp
++The
++\fBUseSHA\fR
++and
++\fBUseSHA*Intrinsics\fR
++flags are enabled by default, and are supported only for Java HotSpot Server VM 64\-bit on SPARC T4 and newer\&.
++.sp
++This feature is only applicable when using the
++\fBsun\&.security\&.provider\&.Sun\fR
++provider for SHA operations\&.
++.sp
++To disable all hardware\-based SHA intrinsics, specify
++\fB\-XX:\-UseSHA\fR\&. To disable only a particular SHA intrinsic, use the appropriate corresponding option\&. For example:
++\fB\-XX:\-UseSHA256Intrinsics\fR\&.
++.RE
++.PP
++\-XX:+UseSHA1Intrinsics
++.RS 4
++Enables intrinsics for SHA\-1 crypto hash function\&.
++.RE
++.PP
++\-XX:+UseSHA256Intrinsics
++.RS 4
++Enables intrinsics for SHA\-224 and SHA\-256 crypto hash functions\&.
++.RE
++.PP
++\-XX:+UseSHA512Intrinsics
++.RS 4
++Enables intrinsics for SHA\-384 and SHA\-512 crypto hash functions\&.
++.RE
++.PP
++\-XX:+UseSuperWord
++.RS 4
++Enables the transformation of scalar operations into superword operations\&. This option is enabled by default\&. To disable the transformation of scalar operations into superword operations, specify
++\fB\-XX:\-UseSuperWord\fR\&. Only the Java HotSpot Server VM supports this option\&.
++.RE
+ .SS "Advanced Serviceability Options"
+ .PP
+ These options provide the ability to gather system information and perform extensive debugging\&.
+@@ -2474,9 +2607,10 @@
+ .PP
+ \-XX:+PrintConcurrentLocks
+ .RS 4
+-Enables printing of j locks after a event\&. By default, this option is disabled\&.
++Enables printing of locks after a event\&. By default, this option is disabled\&.
+ .sp
+-Enables printing of j\fBava\&.util\&.concurrent\fR
++Enables printing of
++\fBjava\&.util\&.concurrent\fR
+ locks after a
+ \fBControl+C\fR
+ event (\fBSIGTERM\fR)\&. By default, this option is disabled\&.
+@@ -2678,7 +2812,9 @@
+ \fBg\fR
+ or
+ \fBG\fR
+-to indicate gigabytes\&. The default value is chosen at runtime based on system configuration\&. For more information, see Garbage Collector Ergonomics at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gc\-ergonomics\&.html
++to indicate gigabytes\&. The default value is chosen at runtime based on system configuration\&. See the section "Ergonomics" in
++\fIJava SE HotSpot Virtual Machine Garbage Collection Tuning Guide\fR
++at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gctuning/index\&.html\&.
+ .sp
+ The following examples show how to set the size of allocated memory to 6 MB using various units:
+ .sp
+@@ -2798,7 +2934,9 @@
+ \fB\-XX:InitialHeapSize\fR
+ and
+ \fB\-XX:MaxHeapSize\fR
+-are often set to the same value\&. For more information, see Garbage Collector Ergonomics at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gc\-ergonomics\&.html
++are often set to the same value\&. See the section "Ergonomics" in
++\fIJava SE HotSpot Virtual Machine Garbage Collection Tuning Guide\fR
++at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gctuning/index\&.html\&.
+ .sp
+ The following examples show how to set the maximum allowed size of allocated memory to 80 MB using various units:
+ .sp
+@@ -3238,6 +3376,13 @@
+ Enables the use of the serial garbage collector\&. This is generally the best choice for small and simple applications that do not require any special functionality from garbage collection\&. By default, this option is disabled and the collector is chosen automatically based on the configuration of the machine and type of the JVM\&.
+ .RE
+ .PP
++\-XX:+UseSHM
++.RS 4
++On Linux, enables the JVM to use shared memory to setup large pages\&.
++.sp
++For more information, see "Large Pages"\&.
++.RE
++.PP
+ \-XX:+UseStringDeduplication
+ .RS 4
+ Enables string deduplication\&. By default, this option is disabled\&. To use this option, you must enable the garbage\-first (G1) garbage collector\&. See the
+@@ -3352,9 +3497,7 @@
+ .PP
+ The following examples show how to use experimental tuning flags to either optimize throughput or to provide lower response time\&.
+ .PP
+-\fBExample 1\fR
+-.br
+-Tuning for Higher Throughput
++\fBExample 1 \fRTuning for Higher Throughput
+ .RS 4
+ .sp
+ .if n \{\
+@@ -3369,9 +3512,7 @@
+ .\}
+ .RE
+ .PP
+-\fBExample 2\fR
+-.br
+-Tuning for Lower Response Time
++\fBExample 2 \fRTuning for Lower Response Time
+ .RS 4
+ .sp
+ .if n \{\
+@@ -3385,6 +3526,195 @@
+ .RE
+ .\}
+ .RE
++.SH "LARGE PAGES"
++.PP
++Also known as huge pages, large pages are memory pages that are significantly larger than the standard memory page size (which varies depending on the processor and operating system)\&. Large pages optimize processor Translation\-Lookaside Buffers\&.
++.PP
++A Translation\-Lookaside Buffer (TLB) is a page translation cache that holds the most\-recently used virtual\-to\-physical address translations\&. TLB is a scarce system resource\&. A TLB miss can be costly as the processor must then read from the hierarchical page table, which may require multiple memory accesses\&. By using a larger memory page size, a single TLB entry can represent a larger memory range\&. There will be less pressure on TLB, and memory\-intensive applications may have better performance\&.
++.PP
++However, large pages page memory can negatively affect system performance\&. For example, when a large mount of memory is pinned by an application, it may create a shortage of regular memory and cause excessive paging in other applications and slow down the entire system\&. Also, a system that has been up for a long time could produce excessive fragmentation, which could make it impossible to reserve enough large page memory\&. When this happens, either the OS or JVM reverts to using regular pages\&.
++.SS "Large Pages Support"
++.PP
++Solaris and Linux support large pages\&.
++.sp
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBSolaris\fR
++.RS 4
++.PP
++Solaris 9 and later include Multiple Page Size Support (MPSS); no additional configuration is necessary\&. See http://www\&.oracle\&.com/technetwork/server\-storage/solaris10/overview/solaris9\-features\-scalability\-135663\&.html\&.
++.RE
++.sp
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBLinux\fR
++.RS 4
++.PP
++The 2\&.6 kernel supports large pages\&. Some vendors have backported the code to their 2\&.4\-based releases\&. To check if your system can support large page memory, try the following:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB# cat /proc/meminfo | grep Huge\fR
++\fBHugePages_Total: 0\fR
++\fBHugePages_Free: 0\fR
++\fBHugepagesize: 2048 kB\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.PP
++If the output shows the three "Huge" variables, then your system can support large page memory but it needs to be configured\&. If the command prints nothing, then your system does not support large pages\&. To configure the system to use large page memory, login as
++\fBroot\fR, and then follow these steps:
++.sp
++.RS 4
++.ie n \{\
++\h'-04' 1.\h'+01'\c
++.\}
++.el \{\
++.sp -1
++.IP " 1." 4.2
++.\}
++If you are using the option
++\fB\-XX:+UseSHM\fR
++(instead of
++\fB\-XX:+UseHugeTLBFS\fR), then increase the
++\fBSHMMAX\fR
++value\&. It must be larger than the Java heap size\&. On a system with 4 GB of physical RAM (or less), the following will make all the memory sharable:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB# echo 4294967295 > /proc/sys/kernel/shmmax\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04' 2.\h'+01'\c
++.\}
++.el \{\
++.sp -1
++.IP " 2." 4.2
++.\}
++If you are using the option
++\fB\-XX:+UseSHM\fR
++or
++\fB\-XX:+UseHugeTLBFS\fR, then specify the number of large pages\&. In the following example, 3 GB of a 4 GB system are reserved for large pages (assuming a large page size of 2048kB, then 3 GB = 3 * 1024 MB = 3072 MB = 3072 * 1024 kB = 3145728 kB and 3145728 kB / 2048 kB = 1536):
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB# echo 1536 > /proc/sys/vm/nr_hugepages\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.if n \{\
++.sp
++.\}
++.RS 4
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBNote\fR
++.ps -1
++.br
++.TS
++allbox tab(:);
++l.
++T{
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++Note that the values contained in
++\fB/proc\fR
++will reset after you reboot your system, so may want to set them in an initialization script (for example,
++\fBrc\&.local\fR
++or
++\fBsysctl\&.conf\fR)\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++If you configure (or resize) the OS kernel parameters
++\fB/proc/sys/kernel/shmmax\fR
++or
++\fB/proc/sys/vm/nr_hugepages\fR, Java processes may allocate large pages for areas in addition to the Java heap\&. These steps can allocate large pages for the following areas:
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++Java heap
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++Code cache
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++The marking bitmap data structure for the parallel GC
++.RE
++.sp
++Consequently, if you configure the
++\fBnr_hugepages\fR
++parameter to the size of the Java heap, then the JVM can fail in allocating the code cache areas on large pages because these areas are quite large in size\&.
++.RE
++T}
++.TE
++.sp 1
++.sp .5v
++.RE
++.RE
+ .SH "EXIT STATUS"
+ .PP
+ The following exit values are typically returned by the launcher when the launcher is called with the wrong arguments, serious errors, or exceptions thrown by the JVM\&. However, a Java application may choose to return any value by using the API call
+@@ -3456,6 +3786,17 @@
+ .\}
+ jar(1)
+ .RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++jstat(1)
++.RE
+ .br
+ 'pl 8.5i
+ 'bp
+--- ./jdk/src/bsd/doc/man/javac.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/bsd/doc/man/javac.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,2116 +1,1370 @@
+ '\" t
+-.\" Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
+-.\"
+-.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-.\"
+-.\" This code is free software; you can redistribute it and/or modify it
+-.\" under the terms of the GNU General Public License version 2 only, as
+-.\" published by the Free Software Foundation.
+-.\"
+-.\" This code is distributed in the hope that it will be useful, but WITHOUT
+-.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-.\" version 2 for more details (a copy is included in the LICENSE file that
+-.\" accompanied this code).
+-.\"
+-.\" You should have received a copy of the GNU General Public License version
+-.\" 2 along with this work; if not, write to the Free Software Foundation,
+-.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-.\"
+-.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-.\" or visit www.oracle.com if you need additional information or have any
+-.\" questions.
+-.\"
+-.\" Title: javac
+-.\" Language: English
+-.\" Date: 8 August 2014
+-.\" SectDesc: Basic Tools
+-.\" Software: JDK 8
+-.\" Arch: generic
+-.\" Part Number: E38207-03
++.\" Copyright (c) 1994, 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.
++.\"
++.\" Arch: generic
++.\" Software: JDK 8
++.\" Date: 03 March 2015
++.\" SectDesc: Basic Tools
++.\" Title: javac.1
+ .\"
+ .if n .pl 99999
+-.TH "javac" "1" "8 August 2014" "JDK 8" "Basic Tools"
+-.\" -----------------------------------------------------------------
+-.\" * Define some portability stuff
+-.\" -----------------------------------------------------------------
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.\" http://bugs.debian.org/507673
+-.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.ie \n(.g .ds Aq \(aq
+-.el .ds Aq '
+-.\" -----------------------------------------------------------------
+-.\" * set default formatting
+-.\" -----------------------------------------------------------------
+-.\" disable hyphenation
+-.nh
+-.\" disable justification (adjust text to left margin only)
+-.ad l
+-.\" -----------------------------------------------------------------
+-.\" * MAIN CONTENT STARTS HERE *
+-.\" -----------------------------------------------------------------
+-.SH "NAME"
++.TH javac 1 "03 March 2015" "JDK 8" "Basic Tools"
++.\" -----------------------------------------------------------------
++.\" * Define some portability stuff
++.\" -----------------------------------------------------------------
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.\" http://bugs.debian.org/507673
++.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.ie \n(.g .ds Aq \(aq
++.el .ds Aq '
++.\" -----------------------------------------------------------------
++.\" * set default formatting
++.\" -----------------------------------------------------------------
++.\" disable hyphenation
++.nh
++.\" disable justification (adjust text to left margin only)
++.ad l
++.\" -----------------------------------------------------------------
++.\" * MAIN CONTENT STARTS HERE *
++.\" -----------------------------------------------------------------
++
++.SH NAME
+ javac \- Reads Java class and interface definitions and compiles them into bytecode and class files\&.
+-.SH "SYNOPSIS"
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
++.SH SYNOPSIS
++.sp
++.nf
++
+ \fBjavac\fR [ \fIoptions\fR ] [ \fIsourcefiles\fR ] [ \fIclasses\fR] [ \fI@argfiles\fR ]
+-.fi
+-.if n \{\
+-.RE
+-.\}
++.fi
++.sp
++Arguments can be in any order:
++.TP
++\fIoptions\fR
++Command-line options\&. See Options\&.
++.TP
++\fIsourcefiles\fR
++One or more source files to be compiled (such as \f3MyClass\&.java\fR)\&.
++.TP
++\fIclasses\fR
++One or more classes to be processed for annotations (such as \f3MyPackage\&.MyClass\fR)\&.
++.TP
++\fI@argfiles\fR
++One or more files that list options and source files\&. The \f3-J\fR options are not allowed in these files\&. See Command-Line Argument Files\&.
++.SH DESCRIPTION
++The \f3javac\fR command reads class and interface definitions, written in the Java programming language, and compiles them into bytecode class files\&. The \f3javac\fR command can also process annotations in Java source files and classes\&.
+ .PP
+-Arguments can be in any order:
++There are two ways to pass source code file names to \f3javac\fR\&.
++.TP 0.2i
++\(bu
++For a small number of source files, list the file names on the command line\&.
++.TP 0.2i
++\(bu
++For a large number of source files, list the file names in a file that is separated by blanks or line breaks\&. Use the list file name preceded by an at sign (@) with the \f3javac\fR command\&.
+ .PP
+-\fIoptions\fR
+-.RS 4
+-Command\-line options\&. See Options\&.
+-.RE
++Source code file names must have \&.java suffixes, class file names must have \&.class suffixes, and both source and class files must have root names that identify the class\&. For example, a class called \f3MyClass\fR would be written in a source file called \f3MyClass\&.java\fR and compiled into a bytecode class file called \f3MyClass\&.class\fR\&.
+ .PP
+-\fIsourcefiles\fR
+-.RS 4
+-One or more source files to be compiled (such as
+-\fBMyClass\&.java\fR)\&.
+-.RE
++Inner class definitions produce additional class files\&. These class files have names that combine the inner and outer class names, such as \f3MyClass$MyInnerClass\&.class\fR\&.
+ .PP
+-\fIclasses\fR
+-.RS 4
+-One or more classes to be processed for annotations (such as
+-\fBMyPackage\&.MyClass\fR)\&.
+-.RE
++Arrange source files in a directory tree that reflects their package tree\&. For example, if all of your source files are in \f3/workspace\fR, then put the source code for \f3com\&.mysoft\&.mypack\&.MyClass\fR in \f3/workspace/com/mysoft/mypack/MyClass\&.java\fR\&.
+ .PP
+-\fI@argfiles\fR
+-.RS 4
+-One or more files that list options and source files\&. The
+-\fB\-J\fR
+-options are not allowed in these files\&. See Command\-Line Argument Files\&.
+-.RE
+-.SH "DESCRIPTION"
++By default, the compiler puts each class file in the same directory as its source file\&. You can specify a separate destination directory with the \f3-d\fR option\&.
++.SH OPTIONS
++The compiler has a set of standard options that are supported on the current development environment\&. An additional set of nonstandard options are specific to the current virtual machine and compiler implementations and are subject to change in the future\&. Nonstandard options begin with the \f3-X\fR option\&.
++.TP 0.2i
++\(bu
++See also Cross-Compilation Options
++.TP 0.2i
++\(bu
++See also Nonstandard Options
++.SS STANDARD\ OPTIONS
++.TP
++-A\fIkey\fR[\fI=value\fR]
++.br
++Specifies options to pass to annotation processors\&. These options are not interpreted by \f3javac\fR directly, but are made available for use by individual processors\&. The \f3key\fR value should be one or more identifiers separated by a dot (\&.)\&.
++.TP
++-cp \fIpath\fR or -classpath \fIpath\fR
++.br
++Specifies where to find user class files, and (optionally) annotation processors and source files\&. This class path overrides the user class path in the \f3CLASSPATH\fR environment variable\&. If neither \f3CLASSPATH\fR, \f3-cp\fR nor \f3-classpath\fR is specified, then the user \fIclass path\fR is the current directory\&. See Setting the Class Path\&.
++
++If the \f3-sourcepath\fR option is not specified, then the user class path is also searched for source files\&.
++
++If the \f3-processorpath\fR option is not specified, then the class path is also searched for annotation processors\&.
++.TP
++-Djava\&.ext\&.dirs=\fIdirectories\fR
++.br
++Overrides the location of installed extensions\&.
++.TP
++-Djava\&.endorsed\&.dirs=\fIdirectories\fR
++.br
++Overrides the location of the endorsed standards path\&.
++.TP
++-d \fIdirectory\fR
++.br
++Sets the destination directory for class files\&. The directory must already exist because \f3javac\fR does not create it\&. If a class is part of a package, then \f3javac\fR puts the class file in a subdirectory that reflects the package name and creates directories as needed\&.
++
++If you specify \f3-d\fR\f3/home/myclasses\fR and the class is called \f3com\&.mypackage\&.MyClass\fR, then the class file is \f3/home/myclasses/com/mypackage/MyClass\&.class\fR\&.
++
++If the \fI-d\fR option is not specified, then \f3javac\fR puts each class file in the same directory as the source file from which it was generated\&.
++
++\fINote:\fR The directory specified by the \fI-d\fR option is not automatically added to your user class path\&.
++.TP
++-deprecation
++.br
++Shows a description of each use or override of a deprecated member or class\&. Without the \f3-deprecation\fR option, \f3javac\fR shows a summary of the source files that use or override deprecated members or classes\&. The \f3-deprecation\fR option is shorthand for \f3-Xlint:deprecation\fR\&.
++.TP
++-encoding \fIencoding\fR
++.br
++Sets the source file encoding name, such as EUC-JP and UTF-8\&. If the \f3-encoding\fR option is not specified, then the platform default converter is used\&.
++.TP
++-endorseddirs \fIdirectories\fR
++.br
++Overrides the location of the endorsed standards path\&.
++.TP
++-extdirs \fIdirectories\fR
++.br
++Overrides the location of the \f3ext\fR directory\&. The directories variable is a colon-separated list of directories\&. Each JAR file in the specified directories is searched for class files\&. All JAR files found become part of the class path\&.
++
++If you are cross-compiling (compiling classes against bootstrap and extension classes of a different Java platform implementation), then this option specifies the directories that contain the extension classes\&. See Cross-Compilation Options for more information\&.
++.TP
++-g
++.br
++Generates all debugging information, including local variables\&. By default, only line number and source file information is generated\&.
++.TP
++-g:none
++.br
++Does not generate any debugging information\&.
++.TP
++-g:[\fIkeyword list\fR]
++.br
++Generates only some kinds of debugging information, specified by a comma separated list of keywords\&. Valid keywords are:
++.RS
++.TP
++source
++Source file debugging information\&.
++.TP
++lines
++Line number debugging information\&.
++.TP
++vars
++Local variable debugging information\&.
++.RE
++
++.TP
++-help
++.br
++Prints a synopsis of standard options\&.
++.TP
++-implicit:[\fIclass, none\fR]
++.br
++Controls the generation of class files for implicitly loaded source files\&. To automatically generate class files, use \f3-implicit:class\fR\&. To suppress class file generation, use \f3-implicit:none\fR\&. If this option is not specified, then the default is to automatically generate class files\&. In this case, the compiler issues a warning if any such class files are generated when also doing annotation processing\&. The warning is not issued when the \f3-implicit\fR option is set explicitly\&. See Searching for Types\&.
++.TP
++-J\fIoption\fR
++.br
++Passes \f3option\fR to the Java Virtual Machine (JVM), where option is one of the options described on the reference page for the Java launcher\&. For example, \f3-J-Xms48m\fR sets the startup memory to 48 MB\&. See java(1)\&.
++
++\fINote:\fR The \fICLASSPATH\fR, \f3-classpath\fR, \f3-bootclasspath\fR, and \f3-extdirs\fR options do not specify the classes used to run \f3javac\fR\&. Trying to customize the compiler implementation with these options and variables is risky and often does not accomplish what you want\&. If you must customize the complier implementation, then use the \f3-J\fR option to pass options through to the underlying \f3\fRJava launcher\&.
++.TP
++-nowarn
++.br
++Disables warning messages\&. This option operates the same as the \f3-Xlint:none\fR option\&.
++.TP
++-parameters
++.br
++Stores formal parameter names of constructors and methods in the generated class file so that the method \f3java\&.lang\&.reflect\&.Executable\&.getParameters\fR from the Reflection API can retrieve them\&.
++.TP
++-proc: [\fInone\fR, \fIonly\fR]
++.br
++Controls whether annotation processing and compilation are done\&. \f3-proc:none\fR means that compilation takes place without annotation processing\&. \f3-proc:only\fR means that only annotation processing is done, without any subsequent compilation\&.
++.TP
++-processor \fIclass1\fR [,\fIclass2\fR,\fIclass3\fR\&.\&.\&.]
++.br
++Names of the annotation processors to run\&. This bypasses the default discovery process\&.
++.TP
++-processorpath \fIpath\fR
++.br
++Specifies where to find annotation processors\&. If this option is not used, then the class path is searched for processors\&.
++.TP
++-s \fIdir\fR
++.br
++Specifies the directory where to place the generated source files\&. The directory must already exist because \f3javac\fR does not create it\&. If a class is part of a package, then the compiler puts the source file in a subdirectory that reflects the package name and creates directories as needed\&.
++
++If you specify \f3-s /home/mysrc\fR and the class is called \f3com\&.mypackage\&.MyClass\fR, then the source file is put in \f3/home/mysrc/com/mypackage/MyClass\&.java\fR\&.
++.TP
++-source \fIrelease\fR
++.br
++Specifies the version of source code accepted\&. The following values for \f3release\fR are allowed:
++.RS
++.TP
++1\&.3
++The compiler does not support assertions, generics, or other language features introduced after Java SE 1\&.3\&.
++.TP
++1\&.4
++The compiler accepts code containing assertions, which were introduced in Java SE 1\&.4\&.
++.TP
++1\&.5
++The compiler accepts code containing generics and other language features introduced in Java SE 5\&.
++.TP
++5
++Synonym for 1\&.5\&.
++.TP
++1\&.6
++No language changes were introduced in Java SE 6\&. However, encoding errors in source files are now reported as errors instead of warnings as in earlier releases of Java Platform, Standard Edition\&.
++.TP
++6
++Synonym for 1\&.6\&.
++.TP
++1\&.7
++The compiler accepts code with features introduced in Java SE 7\&.
++.TP
++7
++Synonym for 1\&.7\&.
++.TP
++1\&.8
++This is the default value\&. The compiler accepts code with features introduced in Java SE 8\&.
++.TP
++8
++Synonym for 1\&.8\&.
++.RE
++
++.TP
++-sourcepath \fIsourcepath\fR
++.br
++Specifies the source code path to search for class or interface definitions\&. As with the user class path, source path entries are separated by colons (:) on Oracle Solaris and semicolons on Windows and can be directories, JAR archives, or ZIP archives\&. If packages are used, then the local path name within the directory or archive must reflect the package name\&.
++
++\fINote:\fR Classes found through the class path might be recompiled when their source files are also found\&. See Searching for Types\&.
++.TP
++-verbose
++.br
++Uses verbose output, which includes information about each class loaded and each source file compiled\&.
++.TP
++-version
++.br
++Prints release information\&.
++.TP
++-werror
++.br
++Terminates compilation when warnings occur\&.
++.TP
++-X
++.br
++Displays information about nonstandard options and exits\&.
++.SS CROSS-COMPILATION\ OPTIONS
++By default, classes are compiled against the bootstrap and extension classes of the platform that \f3javac\fR shipped with\&. But \f3javac\fR also supports cross-compiling, where classes are compiled against a bootstrap and extension classes of a different Java platform implementation\&. It is important to use the \f3-bootclasspath\fR and \f3-extdirs\fR options when cross-compiling\&.
++.TP
++-target \fIversion\fR
++.br
++Generates class files that target a specified release of the virtual machine\&. Class files will run on the specified target and on later releases, but not on earlier releases of the JVM\&. Valid targets are 1\&.1, 1\&.2, 1\&.3, 1\&.4, 1\&.5 (also 5), 1\&.6 (also 6), 1\&.7 (also 7), and 1\&.8 (also 8)\&.
++
++The default for the \f3-target\fR option depends on the value of the \f3-source\fR option:
++.RS
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is not specified, then the value of the \f3-target\fR option is 1\&.8
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is 1\&.2, then the value of the \f3-target\fR option is 1\&.4
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is 1\&.3, then the value of the \f3-target\fR option is 1\&.4
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is 1\&.5, then the value of the \f3-target\fR option is 1\&.8
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is 1\&.6, then the value of the \f3-target\fR is option 1\&.8
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is 1\&.7, then the value of the \f3-target\fR is option 1\&.8
++.TP 0.2i
++\(bu
++For all other values of the \f3-source\fR option, the value of the \f3-target\fR option is the value of the \f3-source\fR option\&.
++.RE
++
++.TP
++-bootclasspath \fIbootclasspath\fR
++.br
++Cross-compiles against the specified set of boot classes\&. As with the user class path, boot class path entries are separated by colons (:) and can be directories, JAR archives, or ZIP archives\&.
++.SS COMPACT\ PROFILE\ OPTION
++Beginning with JDK 8, the \f3javac\fR compiler supports compact profiles\&. With compact profiles, applications that do not require the entire Java platform can be deployed and run with a smaller footprint\&. The compact profiles feature could be used to shorten the download time for applications from app stores\&. This feature makes for more compact deployment of Java applications that bundle the JRE\&. This feature is also useful in small devices\&.
+ .PP
+-The
+-\fBjavac\fR
+-command reads class and interface definitions, written in the Java programming language, and compiles them into bytecode class files\&. The
+-\fBjavac\fR
+-command can also process annotations in Java source files and classes\&.
++The supported profile values are \f3compact1\fR, \f3compact2\fR, and \f3compact3\fR\&. These are additive layers\&. Each higher-numbered compact profile contains all of the APIs in profiles with smaller number names\&.
++.TP
++-profile
++.br
++When using compact profiles, this option specifies the profile name when compiling\&. For example:
++.sp
++.nf
++\f3javac \-profile compact1 Hello\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++javac does not compile source code that uses any Java SE APIs that is not in the specified profile\&. Here is an example of the error message that results from attempting to compile such source code:
++.sp
++.nf
++\f3cd jdk1\&.8\&.0/bin\fP
++.fi
++.nf
++\f3\&./javac \-profile compact1 Paint\&.java\fP
++.fi
++.nf
++\f3Paint\&.java:5: error: Applet is not available in profile \&'compact1\&'\fP
++.fi
++.nf
++\f3import java\&.applet\&.Applet;\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++In this example, you can correct the error by modifying the source to not use the \f3Applet\fR class\&. You could also correct the error by compiling without the -profile option\&. Then the compilation would be run against the full set of Java SE APIs\&. (None of the compact profiles include the \f3Applet\fR class\&.)
++
++An alternative way to compile with compact profiles is to use the \f3-bootclasspath\fR option to specify a path to an \f3rt\&.jar\fR file that specifies a profile\&'s image\&. Using the \f3-profile\fR option instead does not require a profile image to be present on the system at compile time\&. This is useful when cross-compiling\&.
++.SS NONSTANDARD\ OPTIONS
++.TP
++-Xbootclasspath/p:\fIpath\fR
++.br
++Adds a suffix to the bootstrap class path\&.
++.TP
++-Xbootclasspath/a:\fIpath\fR
++.br
++Adds a prefix to the bootstrap class path\&.
++.TP
++-Xbootclasspath/:\fIpath\fR
++.br
++Overrides the location of the bootstrap class files\&.
++.TP
++-Xdoclint:[-]\fIgroup\fR [\fI/access\fR]
++.br
++Enables or disables specific groups of checks, where \fIgroup\fR is one of the following values: \f3accessibility\fR, \f3syntax\fR, \f3reference\fR, \f3html\fR or \f3missing\fR\&. For more information about these groups of checks see the \f3-Xdoclint\fR option of the \f3javadoc\fR command\&. The \f3-Xdoclint\fR option is disabled by default in the \f3javac\fR command\&.
++
++The variable \fIaccess\fR specifies the minimum visibility level of classes and members that the \f3-Xdoclint\fR option checks\&. It can have one of the following values (in order of most to least visible) : \f3public\fR, \f3protected\fR, \f3package\fR and \f3private\fR\&. For example, the following option checks classes and members (with all groups of checks) that have the access level protected and higher (which includes protected, package and public):
++.sp
++.nf
++\f3\-Xdoclint:all/protected\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The following option enables all groups of checks for all access levels, except it will not check for HTML errors for classes and members that have access level package and higher (which includes package and public):
++.sp
++.nf
++\f3\-Xdoclint:all,\-html/package\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++-Xdoclint:none
++.br
++Disables all groups of checks\&.
++.TP
++-Xdoclint:all[\fI/access\fR]
++.br
++Enables all groups of checks\&.
++.TP
++-Xlint
++.br
++\fI\fREnables all recommended warnings\&. In this release, enabling all available warnings is recommended\&.
++.TP
++-Xlint:all
++.br
++\fI\fREnables all recommended warnings\&. In this release, enabling all available warnings is recommended\&.
++.TP
++-Xlint:none
++.br
++Disables all warnings\&.
++.TP
++-Xlint:\fIname\fR
++.br
++Disables warning name\&. See Enable or Disable Warnings with the -Xlint Option for a list of warnings you can disable with this option\&.
++.TP
++-Xlint:\fI-name\fR
++.br
++Disables warning name\&. See Enable or Disable Warnings with the -Xlint Option with the \f3-Xlint\fR option to get a list of warnings that you can disable with this option\&.
++.TP
++-Xmaxerrs \fInumber\fR
++.br
++Sets the maximum number of errors to print\&.
++.TP
++-Xmaxwarns \fInumber\fR
++.br
++Sets the maximum number of warnings to print\&.
++.TP
++-Xstdout \fIfilename\fR
++.br
++Sends compiler messages to the named file\&. By default, compiler messages go to \f3System\&.err\fR\&.
++.TP
++-Xprefer:[\fInewer,source\fR]
++.br
++Specifies which file to read when both a source file and class file are found for a type\&. (See Searching for Types)\&. If the \f3-Xprefer:newer\fR option is used, then it reads the newer of the source or class file for a type (default)\&. If the \f3-Xprefer:source\fR option is used, then it reads the source file\&. Use -\f3Xprefer:source\fR when you want to be sure that any annotation processors can access annotations declared with a retention policy of \f3SOURCE\fR\&.
++.TP
++-Xpkginfo:[\fIalways\fR,\fIlegacy\fR,\fInonempty\fR]
++.br
++Control whether javac generates \f3package-info\&.class\fR files from package-info\&.java files\&. Possible mode arguments for this option include the following\&.
++.RS
++.TP
++always
++Always generate a \f3package-info\&.class\fR file for every \f3package-info\&.java\fR file\&. This option may be useful if you use a build system such as Ant, which checks that each \f3\&.java\fR file has a corresponding \f3\&.class\fR file\&.
++.TP
++legacy
++Generate a \f3package-info\&.class\fR file only if package-info\&.java contains annotations\&. Don\&'t generate a \f3package-info\&.class\fR file if package-info\&.java only contains comments\&.
++
++\fINote:\fR A \f3package-info\&.class\fR file might be generated but be empty if all the annotations in the package-info\&.java file have \f3RetentionPolicy\&.SOURCE\fR\&.
++.TP
++nonempty
++Generate a \f3package-info\&.class\fR file only if package-info\&.java contains annotations with \f3RetentionPolicy\&.CLASS\fR or \f3RetentionPolicy\&.RUNTIME\fR\&.
++.RE
++
++.TP
++-Xprint
++.br
++Prints a textual representation of specified types for debugging purposes\&. Perform neither annotation processing nor compilation\&. The format of the output could change\&.
++.TP
++-XprintProcessorInfo
++.br
++Prints information about which annotations a processor is asked to process\&.
++.TP
++-XprintRounds
++.br
++Prints information about initial and subsequent annotation processing rounds\&.
++.SH ENABLE\ OR\ DISABLE\ WARNINGS\ WITH\ THE\ -XLINT\ OPTION
++Enable warning \fIname\fR with the \f3-Xlint:name\fR option, where \f3name\fR is one of the following warning names\&. Note that you can disable a warning with the \f3-Xlint:-name:\fR option\&.
++.TP
++cast
++Warns about unnecessary and redundant casts, for example:
++.sp
++.nf
++\f3String s = (String) "Hello!"\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++classfile
++Warns about issues related to class file contents\&.
++.TP
++deprecation
++Warns about the use of deprecated items, for example:
++.sp
++.nf
++\f3java\&.util\&.Date myDate = new java\&.util\&.Date();\fP
++.fi
++.nf
++\f3int currentDay = myDate\&.getDay();\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The method \f3java\&.util\&.Date\&.getDay\fR has been deprecated since JDK 1\&.1
++.TP
++dep-ann
++Warns about items that are documented with an \f3@deprecated\fR Javadoc comment, but do not have a \f3@Deprecated\fR annotation, for example:
++.sp
++.nf
++\f3/**\fP
++.fi
++.nf
++\f3 * @deprecated As of Java SE 7, replaced by {@link #newMethod()}\fP
++.fi
++.nf
++\f3 */\fP
++.fi
++.nf
++\f3public static void deprecatedMethood() { }\fP
++.fi
++.nf
++\f3public static void newMethod() { }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++divzero
++Warns about division by the constant integer 0, for example:
++.sp
++.nf
++\f3int divideByZero = 42 / 0;\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++empty
++Warns about empty statements after \f3if\fRstatements, for example:
++.sp
++.nf
++\f3class E {\fP
++.fi
++.nf
++\f3 void m() {\fP
++.fi
++.nf
++\f3 if (true) ;\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++fallthrough
++Checks the switch blocks for fall-through cases and provides a warning message for any that are found\&. Fall-through cases are cases in a switch block, other than the last case in the block, whose code does not include a break statement, allowing code execution to fall through from that case to the next case\&. For example, the code following the case 1 label in this switch block does not end with a break statement:
++.sp
++.nf
++\f3switch (x) {\fP
++.fi
++.nf
++\f3case 1:\fP
++.fi
++.nf
++\f3 System\&.out\&.println("1");\fP
++.fi
++.nf
++\f3 // No break statement here\&.\fP
++.fi
++.nf
++\f3case 2:\fP
++.fi
++.nf
++\f3 System\&.out\&.println("2");\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++If the \f3-Xlint:fallthrough\fR option was used when compiling this code, then the compiler emits a warning about possible fall-through into case, with the line number of the case in question\&.
++.TP
++finally
++Warns about \f3finally\fR clauses that cannot complete normally, for example:
++.sp
++.nf
++\f3public static int m() {\fP
++.fi
++.nf
++\f3 try {\fP
++.fi
++.nf
++\f3 throw new NullPointerException();\fP
++.fi
++.nf
++\f3 } catch (NullPointerException(); {\fP
++.fi
++.nf
++\f3 System\&.err\&.println("Caught NullPointerException\&.");\fP
++.fi
++.nf
++\f3 return 1;\fP
++.fi
++.nf
++\f3 } finally {\fP
++.fi
++.nf
++\f3 return 0;\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The compiler generates a warning for the \f3finally\fR block in this example\&. When the \f3int\fR method is called, it returns a value of 0\&. A \f3finally\fR block executes when the \f3try\fR block exits\&. In this example, when control is transferred to the \f3catch\fR block, the \f3int\fR method exits\&. However, the \f3finally\fR block must execute, so it is executed, even though control was transferred outside the method\&.
++.TP
++options
++Warns about issues that related to the use of command-line options\&. See Cross-Compilation Options\&.
++.TP
++overrides
++Warns about issues regarding method overrides\&. For example, consider the following two classes:
++.sp
++.nf
++\f3public class ClassWithVarargsMethod {\fP
++.fi
++.nf
++\f3 void varargsMethod(String\&.\&.\&. s) { }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3public class ClassWithOverridingMethod extends ClassWithVarargsMethod {\fP
++.fi
++.nf
++\f3 @Override\fP
++.fi
++.nf
++\f3 void varargsMethod(String[] s) { }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The compiler generates a warning similar to the following:\&.
++.sp
++.nf
++\f3warning: [override] varargsMethod(String[]) in ClassWithOverridingMethod \fP
++.fi
++.nf
++\f3overrides varargsMethod(String\&.\&.\&.) in ClassWithVarargsMethod; overriding\fP
++.fi
++.nf
++\f3method is missing \&'\&.\&.\&.\&'\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++When the compiler encounters a \f3varargs\fR method, it translates the \f3varargs\fR formal parameter into an array\&. In the method \f3ClassWithVarargsMethod\&.varargsMethod\fR, the compiler translates the \f3varargs\fR formal parameter \f3String\&.\&.\&. s\fR to the formal parameter \f3String[] s\fR, an array, which matches the formal parameter of the method \f3ClassWithOverridingMethod\&.varargsMethod\fR\&. Consequently, this example compiles\&.
++.TP
++path
++Warns about invalid path elements and nonexistent path directories on the command line (with regard to the class path, the source path, and other paths)\&. Such warnings cannot be suppressed with the \f3@SuppressWarnings\fR annotation, for example:
++.sp
++.nf
++\f3javac \-Xlint:path \-classpath /nonexistentpath Example\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++processing
++Warn about issues regarding annotation processing\&. The compiler generates this warning when you have a class that has an annotation, and you use an annotation processor that cannot handle that type of exception\&. For example, the following is a simple annotation processor:
++
++\fISource file AnnocProc\&.java\fR:
++.sp
++.nf
++\f3import java\&.util\&.*;\fP
++.fi
++.nf
++\f3import javax\&.annotation\&.processing\&.*;\fP
++.fi
++.nf
++\f3import javax\&.lang\&.model\&.*;\fP
++.fi
++.nf
++\f3import\&.javaz\&.lang\&.model\&.element\&.*;\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3@SupportedAnnotationTypes("NotAnno")\fP
++.fi
++.nf
++\f3public class AnnoProc extends AbstractProcessor {\fP
++.fi
++.nf
++\f3 public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv){\fP
++.fi
++.nf
++\f3 return true;\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3 public SourceVersion getSupportedSourceVersion() {\fP
++.fi
++.nf
++\f3 return SourceVersion\&.latest();\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++\fISource file AnnosWithoutProcessors\&.java\fR:
++.sp
++.nf
++\f3@interface Anno { }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3@Anno\fP
++.fi
++.nf
++\f3class AnnosWithoutProcessors { }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The following commands compile the annotation processor \f3AnnoProc\fR, then run this annotation processor against the source file \f3AnnosWithoutProcessors\&.java\fR:
++.sp
++.nf
++\f3javac AnnoProc\&.java\fP
++.fi
++.nf
++\f3javac \-cp \&. \-Xlint:processing \-processor AnnoProc \-proc:only AnnosWithoutProcessors\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++When the compiler runs the annotation processor against the source file \f3AnnosWithoutProcessors\&.java\fR, it generates the following warning:
++.sp
++.nf
++\f3warning: [processing] No processor claimed any of these annotations: Anno\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++To resolve this issue, you can rename the annotation defined and used in the class \f3AnnosWithoutProcessors\fR from \f3Anno\fR to \f3NotAnno\fR\&.
++.TP
++rawtypes
++Warns about unchecked operations on raw types\&. The following statement generates a \f3rawtypes\fR warning:
++.sp
++.nf
++\f3void countElements(List l) { \&.\&.\&. }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The following example does not generate a \f3rawtypes\fR warning
++.sp
++.nf
++\f3void countElements(List<?> l) { \&.\&.\&. }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++\f3List\fR is a raw type\&. However, \f3List<?>\fR is an unbounded wildcard parameterized type\&. Because \f3List\fR is a parameterized interface, always specify its type argument\&. In this example, the \f3List\fR formal argument is specified with an unbounded wildcard (\f3?\fR) as its formal type parameter, which means that the \f3countElements\fR method can accept any instantiation of the \f3List\fR interface\&.
++.TP
++Serial
++Warns about missing \f3serialVersionUID\fR definitions on serializable classes, for example:
++.sp
++.nf
++\f3public class PersistentTime implements Serializable\fP
++.fi
++.nf
++\f3{\fP
++.fi
++.nf
++\f3 private Date time;\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3 public PersistentTime() {\fP
++.fi
++.nf
++\f3 time = Calendar\&.getInstance()\&.getTime();\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3 public Date getTime() {\fP
++.fi
++.nf
++\f3 return time;\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The compiler generates the following warning:
++.sp
++.nf
++\f3warning: [serial] serializable class PersistentTime has no definition of\fP
++.fi
++.nf
++\f3serialVersionUID\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++If a serializable class does not explicitly declare a field named \f3serialVersionUID\fR, then the serialization runtime environment calculates a default \f3serialVersionUID\fR value for that class based on various aspects of the class, as described in the Java Object Serialization Specification\&. However, it is strongly recommended that all serializable classes explicitly declare \f3serialVersionUID\fR values because the default process of computing \f3serialVersionUID\fR vales is highly sensitive to class details that can vary depending on compiler implementations, and as a result, might cause an unexpected \f3InvalidClassExceptions\fR during deserialization\&. To guarantee a consistent \f3serialVersionUID\fR value across different Java compiler implementations, a serializable class must declare an explicit \f3serialVersionUID\fR value\&.
++.TP
++static
++Warns about issues relating to the use of statics, for example:
++.sp
++.nf
++\f3class XLintStatic {\fP
++.fi
++.nf
++\f3 static void m1() { }\fP
++.fi
++.nf
++\f3 void m2() { this\&.m1(); }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The compiler generates the following warning:
++.sp
++.nf
++\f3warning: [static] static method should be qualified by type name, \fP
++.fi
++.nf
++\f3XLintStatic, instead of by an expression\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++To resolve this issue, you can call the \f3static\fR method \f3m1\fR as follows:
++.sp
++.nf
++\f3XLintStatic\&.m1();\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++Alternately, you can remove the \f3static\fR keyword from the declaration of the method \f3m1\fR\&.
++.TP
++try
++Warns about issues relating to use of \f3try\fR blocks, including try-with-resources statements\&. For example, a warning is generated for the following statement because the resource \f3ac\fR declared in the \f3try\fR block is not used:
++.sp
++.nf
++\f3try ( AutoCloseable ac = getResource() ) { // do nothing}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++unchecked
++Gives more detail for unchecked conversion warnings that are mandated by the Java Language Specification, for example:
++.sp
++.nf
++\f3List l = new ArrayList<Number>();\fP
++.fi
++.nf
++\f3List<String> ls = l; // unchecked warning\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++During type erasure, the types \f3ArrayList<Number>\fR and \f3List<String>\fR become \f3ArrayList\fR and \f3List\fR, respectively\&.
++
++The \f3ls\fR command has the parameterized type \f3List<String>\fR\&. When the \f3List\fR referenced by \f3l\fR is assigned to \f3ls\fR, the compiler generates an unchecked warning\&. At compile time, the compiler and JVM cannot determine whether \f3l\fR refers to a \f3List<String>\fR type\&. In this case, \f3l\fR does not refer to a \f3List<String>\fR type\&. As a result, heap pollution occurs\&.
++
++A heap pollution situation occurs when the \f3List\fR object \f3l\fR, whose static type is \f3List<Number>\fR, is assigned to another \f3List\fR object, \f3ls\fR, that has a different static type, \f3List<String>\fR\&. However, the compiler still allows this assignment\&. It must allow this assignment to preserve backward compatibility with releases of Java SE that do not support generics\&. Because of type erasure, \f3List<Number>\fR and \f3List<String>\fR both become \f3List\fR\&. Consequently, the compiler allows the assignment of the object \f3l\fR\f3,\fR which has a raw type of \f3List\fR, to the object \f3ls\fR\&.
++.TP
++varargs
++Warns about unsafe usages of variable arguments (\f3varargs\fR) methods, in particular, those that contain non-reifiable arguments, for example:
++.sp
++.nf
++\f3public class ArrayBuilder {\fP
++.fi
++.nf
++\f3 public static <T> void addToList (List<T> listArg, T\&.\&.\&. elements) {\fP
++.fi
++.nf
++\f3 for (T x : elements) {\fP
++.fi
++.nf
++\f3 listArg\&.add(x);\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++\fINote:\fR A non-reifiable type is a type whose type information is not fully available at runtime\&.
++
++The compiler generates the following warning for the definition of the method \f3ArrayBuilder\&.addToList\fR
++.sp
++.nf
++\f3warning: [varargs] Possible heap pollution from parameterized vararg type T\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++When the compiler encounters a varargs method, it translates the \f3varargs\fR formal parameter into an array\&. However, the Java programming language does not permit the creation of arrays of parameterized types\&. In the method \f3ArrayBuilder\&.addToList\fR, the compiler translates the \f3varargs\fR formal parameter \f3T\&.\&.\&.\fR elements to the formal parameter \f3T[]\fR elements, an array\&. However, because of type erasure, the compiler converts the \f3varargs\fR formal parameter to \f3Object[]\fR elements\&. Consequently, there is a possibility of heap pollution\&.
++.SH COMMAND-LINE\ ARGUMENT\ FILES
++To shorten or simplify the \f3javac\fR command, you can specify one or more files that contain arguments to the \f3javac\fR command (except \f3-J\fR options)\&. This enables you to create \f3javac\fR commands of any length on any operating system\&.
+ .PP
+-There are two ways to pass source code file names to
+-\fBjavac\fR\&.
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-For a small number of source files, list the file names on the command line\&.
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-For a large number of source files, list the file names in a file that is separated by blanks or line breaks\&. Use the list file name preceded by an at sign (@) with the
+-\fBjavac\fR
+-command\&.
+-.RE
++An argument file can include \f3javac\fR options and source file names in any combination\&. The arguments within a file can be separated by spaces or new line characters\&. If a file name contains embedded spaces, then put the whole file name in double quotation marks\&.
+ .PP
+-Source code file names must have \&.java suffixes, class file names must have \&.class suffixes, and both source and class files must have root names that identify the class\&. For example, a class called
+-\fBMyClass\fR
+-would be written in a source file called
+-\fBMyClass\&.java\fR
+-and compiled into a bytecode class file called
+-\fBMyClass\&.class\fR\&.
++File Names within an argument file are relative to the current directory, not the location of the argument file\&. Wild cards (*) are not allowed in these lists (such as for specifying \f3*\&.java\fR)\&. Use of the at sign (@) to recursively interpret files is not supported\&. The \f3-J\fR options are not supported because they are passed to the launcher, which does not support argument files\&.
+ .PP
+-Inner class definitions produce additional class files\&. These class files have names that combine the inner and outer class names, such as
+-\fBMyClass$MyInnerClass\&.class\fR\&.
++When executing the \f3javac\fR command, pass in the path and name of each argument file with the at sign (@) leading character\&. When the \f3javac\fR command encounters an argument beginning with the at sign (@), it expands the contents of that file into the argument list\&.
+ .PP
+-Arrange source files in a directory tree that reflects their package tree\&. For example, if all of your source files are in
+-\fB/workspace\fR, then put the source code for
+-\fBcom\&.mysoft\&.mypack\&.MyClass\fR
+-in
+-\fB/workspace/com/mysoft/mypack/MyClass\&.java\fR\&.
++\f3Example 1 Single Argument File\fR
+ .PP
+-By default, the compiler puts each class file in the same directory as its source file\&. You can specify a separate destination directory with the
+-\fB\-d\fR
+-option\&.
+-.SH "OPTIONS"
++You could use a single argument file named \f3argfile\fR to hold all \f3javac\fR arguments:
++.sp
++.nf
++\f3javac @argfile\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++This argument file could contain the contents of both files shown in Example 2
+ .PP
+-The compiler has a set of standard options that are supported on the current development environment\&. An additional set of nonstandard options are specific to the current virtual machine and compiler implementations and are subject to change in the future\&. Nonstandard options begin with the
+-\fB\-X\fR
+-option\&.
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-See also Cross\-Compilation Options
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-See also Nonstandard Options
+-.RE
+-.SS "Standard Options"
++\f3Example 2 Two Argument Files\fR
+ .PP
+-\-A\fIkey\fR[\fI=value\fR]
+-.RS 4
+-Specifies options to pass to annotation processors\&. These options are not interpreted by
+-\fBjavac\fR
+-directly, but are made available for use by individual processors\&. The
+-\fBkey\fR
+-value should be one or more identifiers separated by a dot (\&.)\&.
+-.RE
++You can create two argument files: one for the \f3javac\fR options and the other for the source file names\&. Note that the following lists have no line-continuation characters\&.
+ .PP
+-\-cp \fIpath\fR or \-classpath \fIpath\fR
+-.RS 4
+-Specifies where to find user class files, and (optionally) annotation processors and source files\&. This class path overrides the user class path in the
+-\fBCLASSPATH\fR
+-environment variable\&. If neither
+-\fBCLASSPATH\fR,
+-\fB\-cp\fR
+-nor
+-\fB\-classpath\fR
+-is specified, then the user
+-\fIclass path\fR
+-is the current directory\&. See Setting the Class Path \&.
+-.sp
+-If the
+-\fB\-sourcepath\fR
+-option is not specified, then the user class path is also searched for source files\&.
+-.sp
+-If the
+-\fB\-processorpath\fR
+-option is not specified, then the class path is also searched for annotation processors\&.
+-.RE
++Create a file named options that contains the following:
++.sp
++.nf
++\f3\-d classes\fP
++.fi
++.nf
++\f3\-g\fP
++.fi
++.nf
++\f3\-sourcepath /java/pubs/ws/1\&.3/src/share/classes\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++Create a file named classes that contains the following:
++.sp
++.nf
++\f3MyClass1\&.java\fP
++.fi
++.nf
++\f3MyClass2\&.java\fP
++.fi
++.nf
++\f3MyClass3\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++Then, run the \f3javac\fR command as follows:
++.sp
++.nf
++\f3javac @options @classes\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++\f3Example 3 Argument Files with Paths\fR
+ .PP
+-\-Djava\&.ext\&.dirs=\fIdirectories\fR
+-.RS 4
+-Overrides the location of installed extensions\&.
+-.RE
++The argument files can have paths, but any file names inside the files are relative to the current working directory (not \f3path1\fR or \f3path2\fR):
++.sp
++.nf
++\f3javac @path1/options @path2/classes\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++.SH ANNOTATION\ PROCESSING
++The \f3javac\fR command provides direct support for annotation processing, superseding the need for the separate annotation processing command, \f3apt\fR\&.
+ .PP
+-\-Djava\&.endorsed\&.dirs=\fIdirectories\fR
+-.RS 4
+-Overrides the location of the endorsed standards path\&.
+-.RE
+-.PP
+-\-d \fIdirectory\fR
+-.RS 4
+-Sets the destination directory for class files\&. The directory must already exist because
+-\fBjavac\fR
+-does not create it\&. If a class is part of a package, then
+-\fBjavac\fR
+-puts the class file in a subdirectory that reflects the package name and creates directories as needed\&.
+-.sp
+-If you specify
+-\fB\-d\fR
+-\fB/home/myclasses\fR
+-and the class is called
+-\fBcom\&.mypackage\&.MyClass\fR, then the class file is
+-\fB/home/myclasses/com/mypackage/MyClass\&.class\fR\&.
+-.sp
+-If the
+-\fI\-d\fR
+-option is not specified, then
+-\fBjavac\fR
+-puts each class file in the same directory as the source file from which it was generated\&.
+-.sp
+-\fBNote:\fR
+-The directory specified by the
+-\fI\-d\fR
+-option is not automatically added to your user class path\&.
+-.RE
+-.PP
+-\-deprecation
+-.RS 4
+-Shows a description of each use or override of a deprecated member or class\&. Without the
+-\fB\-deprecation\fR
+-option,
+-\fBjavac\fR
+-shows a summary of the source files that use or override deprecated members or classes\&. The
+-\fB\-deprecation\fR
+-option is shorthand for
+-\fB\-Xlint:deprecation\fR\&.
+-.RE
+-.PP
+-\-encoding \fIencoding\fR
+-.RS 4
+-Sets the source file encoding name, such as EUC\-JP and UTF\-8\&. If the
+-\fB\-encoding\fR
+-option is not specified, then the platform default converter is used\&.
+-.RE
+-.PP
+-\-endorseddirs \fIdirectories\fR
+-.RS 4
+-Overrides the location of the endorsed standards path\&.
+-.RE
+-.PP
+-\-extdirs \fIdirectories\fR
+-.RS 4
+-Overrides the location of the
+-\fBext\fR
+-directory\&. The directories variable is a colon\-separated list of directories\&. Each JAR file in the specified directories is searched for class files\&. All JAR files found become part of the class path\&.
+-.sp
+-If you are cross\-compiling (compiling classes against bootstrap and extension classes of a different Java platform implementation), then this option specifies the directories that contain the extension classes\&. See Cross\-Compilation Options for more information\&.
+-.RE
+-.PP
+-\-g
+-.RS 4
+-Generates all debugging information, including local variables\&. By default, only line number and source file information is generated\&.
+-.RE
+-.PP
+-\-g:none
+-.RS 4
+-Does not generate any debugging information\&.
+-.RE
+-.PP
+-\-g:[\fIkeyword list\fR]
+-.RS 4
+-Generates only some kinds of debugging information, specified by a comma separated list of keywords\&. Valid keywords are:
+-.PP
+-source
+-.RS 4
+-Source file debugging information\&.
+-.RE
+-.PP
+-lines
+-.RS 4
+-Line number debugging information\&.
+-.RE
+-.PP
+-vars
+-.RS 4
+-Local variable debugging information\&.
+-.RE
+-.RE
+-.PP
+-\-help
+-.RS 4
+-Prints a synopsis of standard options\&.
+-.RE
+-.PP
+-\-implicit:[\fIclass, none\fR]
+-.RS 4
+-Controls the generation of class files for implicitly loaded source files\&. To automatically generate class files, use
+-\fB\-implicit:class\fR\&. To suppress class file generation, use
+-\fB\-implicit:none\fR\&. If this option is not specified, then the default is to automatically generate class files\&. In this case, the compiler issues a warning if any such class files are generated when also doing annotation processing\&. The warning is not issued when the
+-\fB\-implicit\fR
+-option is set explicitly\&. See Searching for Types\&.
+-.RE
+-.PP
+-\-J\fIoption\fR
+-.RS 4
+-Passes
+-\fBoption\fR
+-to the Java Virtual Machine (JVM), where option is one of the options described on the reference page for the Java launcher\&. For example,
+-\fB\-J\-Xms48m\fR
+-sets the startup memory to 48 MB\&. See
+-java(1)\&.
+-.sp
+-\fBNote:\fR
+-The
+-\fICLASSPATH\fR,
+-\fB\-classpath\fR,
+-\fB\-bootclasspath\fR, and
+-\fB\-extdirs\fR
+-options do not specify the classes used to run
+-\fBjavac\fR\&. Trying to customize the compiler implementation with these options and variables is risky and often does not accomplish what you want\&. If you must customize the complier implementation, then use the
+-\fB\-J\fR
+-option to pass options through to the underlying Java launcher\&.
+-.RE
+-.PP
+-\-nowarn
+-.RS 4
+-Disables warning messages\&. This option operates the same as the
+-\fB\-Xlint:none\fR
+-option\&.
+-.RE
+-.PP
+-\-parameters
+-.RS 4
+-Stores formal parameter names of constructors and methods in the generated class file so that the method
+-\fBjava\&.lang\&.reflect\&.Executable\&.getParameters\fR
+-from the Reflection API can retrieve them\&.
+-.RE
+-.PP
+-\-proc: [\fInone\fR, \fIonly\fR]
+-.RS 4
+-Controls whether annotation processing and compilation are done\&.
+-\fB\-proc:none\fR
+-means that compilation takes place without annotation processing\&.
+-\fB\-proc:only\fR
+-means that only annotation processing is done, without any subsequent compilation\&.
+-.RE
+-.PP
+-\-processor \fIclass1\fR [,\fIclass2\fR,\fIclass3\fR\&.\&.\&.]
+-.RS 4
+-Names of the annotation processors to run\&. This bypasses the default discovery process\&.
+-.RE
+-.PP
+-\-processorpath \fIpath\fR
+-.RS 4
+-Specifies where to find annotation processors\&. If this option is not used, then the class path is searched for processors\&.
+-.RE
+-.PP
+-\-s \fIdir\fR
+-.RS 4
+-Specifies the directory where to place the generated source files\&. The directory must already exist because
+-\fBjavac\fR
+-does not create it\&. If a class is part of a package, then the compiler puts the source file in a subdirectory that reflects the package name and creates directories as needed\&.
+-.sp
+-If you specify
+-\fB\-s /home/mysrc\fR
+-and the class is called
+-\fBcom\&.mypackage\&.MyClass\fR, then the source file is put in
+-\fB/home/mysrc/com/mypackage/MyClass\&.java\fR\&.
+-.RE
+-.PP
+-\-source \fIrelease\fR
+-.RS 4
+-Specifies the version of source code accepted\&. The following values for
+-\fBrelease\fR
+-are allowed:
+-.PP
+-1\&.3
+-.RS 4
+-The compiler does not support assertions, generics, or other language features introduced after Java SE 1\&.3\&.
+-.RE
+-.PP
+-1\&.4
+-.RS 4
+-The compiler accepts code containing assertions, which were introduced in Java SE 1\&.4\&.
+-.RE
+-.PP
+-1\&.5
+-.RS 4
+-The compiler accepts code containing generics and other language features introduced in Java SE 5\&.
+-.RE
+-.PP
+-5
+-.RS 4
+-Synonym for 1\&.5\&.
+-.RE
+-.PP
+-1\&.6
+-.RS 4
+-No language changes were introduced in Java SE 6\&. However, encoding errors in source files are now reported as errors instead of warnings as in earlier releases of Java Platform, Standard Edition\&.
+-.RE
+-.PP
+-6
+-.RS 4
+-Synonym for 1\&.6\&.
+-.RE
+-.PP
+-1\&.7
+-.RS 4
+-The compiler accepts code with features introduced in Java SE 7\&.
+-.RE
+-.PP
+-7
+-.RS 4
+-Synonym for 1\&.7\&.
+-.RE
+-.PP
+-1\&.8
+-.RS 4
+-This is the default value\&. The compiler accepts code with features introduced in Java SE 8\&.
+-.RE
+-.PP
+-8
+-.RS 4
+-Synonym for 1\&.8\&.
+-.RE
+-.RE
+-.PP
+-\-sourcepath \fIsourcepath\fR
+-.RS 4
+-Specifies the source code path to search for class or interface definitions\&. As with the user class path, source path entries are separated by colons (:) on Oracle Solaris and semicolons on Windows and can be directories, JAR archives, or ZIP archives\&. If packages are used, then the local path name within the directory or archive must reflect the package name\&.
+-.sp
+-\fBNote:\fR
+-Classes found through the class path might be recompiled when their source files are also found\&. See Searching for Types\&.
+-.RE
+-.PP
+-\-verbose
+-.RS 4
+-Uses verbose output, which includes information about each class loaded and each source file compiled\&.
+-.RE
+-.PP
+-\-version
+-.RS 4
+-Prints release information\&.
+-.RE
+-.PP
+-\-werror
+-.RS 4
+-Terminates compilation when warnings occur\&.
+-.RE
+-.PP
+-\-X
+-.RS 4
+-Displays information about nonstandard options and exits\&.
+-.RE
+-.SS "Cross\-Compilation Options"
+-.PP
+-By default, classes are compiled against the bootstrap and extension classes of the platform that
+-\fBjavac\fR
+-shipped with\&. But
+-\fBjavac\fR
+-also supports cross\-compiling, where classes are compiled against a bootstrap and extension classes of a different Java platform implementation\&. It is important to use the
+-\fB\-bootclasspath\fR
+-and
+-\fB\-extdirs\fR
+-options when cross\-compiling\&.
+-.PP
+-\-target \fIversion\fR
+-.RS 4
+-Generates class files that target a specified release of the virtual machine\&. Class files will run on the specified target and on later releases, but not on earlier releases of the JVM\&. Valid targets are 1\&.1, 1\&.2, 1\&.3, 1\&.4, 1\&.5 (also 5), 1\&.6 (also 6), 1\&.7 (also 7), and 1\&.8 (also 8)\&.
+-.sp
+-The default for the
+-\fB\-target\fR
+-option depends on the value of the
+-\fB\-source\fR
+-option:
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is not specified, then the value of the
+-\fB\-target\fR
+-option is 1\&.8
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is 1\&.2, then the value of the
+-\fB\-target\fR
+-option is 1\&.4
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is 1\&.3, then the value of the
+-\fB\-target\fR
+-option is 1\&.4
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is 1\&.5, then the value of the
+-\fB\-target\fR
+-option is 1\&.8
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is 1\&.6, then the value of the
+-\fB\-target\fR
+-is option 1\&.8
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is 1\&.7, then the value of the
+-\fB\-target\fR
+-is option 1\&.8
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-For all other values of the
+-\fB\-source\fR
+-option, the value of the
+-\fB\-target\fR
+-option is the value of the
+-\fB\-source\fR
+-option\&.
+-.RE
+-.RE
+-.PP
+-\-bootclasspath \fIbootclasspath\fR
+-.RS 4
+-Cross\-compiles against the specified set of boot classes\&. As with the user class path, boot class path entries are separated by colons (:) and can be directories, JAR archives, or ZIP archives\&.
+-.RE
+-.SS "Compact Profile Option"
+-.PP
+-Beginning with JDK 8, the
+-\fBjavac\fR
+-compiler supports compact profiles\&. With compact profiles, applications that do not require the entire Java platform can be deployed and run with a smaller footprint\&. The compact profiles feature could be used to shorten the download time for applications from app stores\&. This feature makes for more compact deployment of Java applications that bundle the JRE\&. This feature is also useful in small devices\&.
+-.PP
+-The supported profile values are
+-\fBcompact1\fR,
+-\fBcompact2\fR, and
+-\fBcompact3\fR\&. These are additive layers\&. Each higher\-numbered compact profile contains all of the APIs in profiles with smaller number names\&.
+-.PP
+-\-profile
+-.RS 4
+-When using compact profiles, this option specifies the profile name when compiling\&. For example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-profile compact1 Hello\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-javac does not compile source code that uses any Java SE APIs that is not in the specified profile\&. Here is an example of the error message that results from attempting to compile such source code:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBcd jdk1\&.8\&.0/bin\fR
+-\fB\&./javac \-profile compact1 Paint\&.java\fR
+-\fBPaint\&.java:5: error: Applet is not available in profile \*(Aqcompact1\*(Aq\fR
+-\fBimport java\&.applet\&.Applet;\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-In this example, you can correct the error by modifying the source to not use the
+-\fBApplet\fR
+-class\&. You could also correct the error by compiling without the \-profile option\&. Then the compilation would be run against the full set of Java SE APIs\&. (None of the compact profiles include the
+-\fBApplet\fR
+-class\&.)
+-.sp
+-An alternative way to compile with compact profiles is to use the
+-\fB\-bootclasspath\fR
+-option to specify a path to an
+-\fBrt\&.jar\fR
+-file that specifies a profile\*(Aqs image\&. Using the
+-\fB\-profile\fR
+-option instead does not require a profile image to be present on the system at compile time\&. This is useful when cross\-compiling\&.
+-.RE
+-.SS "Nonstandard Options"
+-.PP
+-\-Xbootclasspath/p:\fIpath\fR
+-.RS 4
+-Adds a suffix to the bootstrap class path\&.
+-.RE
+-.PP
+-\-Xbootclasspath/a:\fIpath\fR
+-.RS 4
+-Adds a prefix to the bootstrap class path\&.
+-.RE
+-.PP
+-\-Xbootclasspath/:\fIpath\fR
+-.RS 4
+-Overrides the location of the bootstrap class files\&.
+-.RE
+-.PP
+-\-Xdoclint:[\-]\fIgroup\fR [\fI/access\fR]
+-.RS 4
+-Enables or disables specific groups of checks, where
+-\fIgroup\fR
+-is one of the following values:
+-\fBaccessibility\fR,
+-\fBsyntax\fR,
+-\fBreference\fR,
+-\fBhtml\fR
+-or
+-\fBmissing\fR\&. For more information about these groups of checks see the
+-\fB\-Xdoclint\fR
+-option of the
+-\fBjavadoc\fR
+-command\&. The
+-\fB\-Xdoclint\fR
+-option is disabled by default in the
+-\fBjavac\fR
+-command\&.
+-.sp
+-The variable
+-\fIaccess\fR
+-specifies the minimum visibility level of classes and members that the
+-\fB\-Xdoclint\fR
+-option checks\&. It can have one of the following values (in order of most to least visible) :
+-\fBpublic\fR,
+-\fBprotected\fR,
+-\fBpackage\fR
+-and
+-\fBprivate\fR\&. For example, the following option checks classes and members (with all groups of checks) that have the access level protected and higher (which includes protected, package and public):
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB\-Xdoclint:all/protected\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The following option enables all groups of checks for all access levels, except it will not check for HTML errors for classes and members that have access level package and higher (which includes package and public):
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB\-Xdoclint:all,\-html/package\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-\-Xdoclint:none
+-.RS 4
+-Disables all groups of checks\&.
+-.RE
+-.PP
+-\-Xdoclint:all[\fI/access\fR]
+-.RS 4
+-Enables all groups of checks\&.
+-.RE
+-.PP
+-\-Xlint
+-.RS 4
+-Enables all recommended warnings\&. In this release, enabling all available warnings is recommended\&.
+-.RE
+-.PP
+-\-Xlint:all
+-.RS 4
+-Enables all recommended warnings\&. In this release, enabling all available warnings is recommended\&.
+-.RE
+-.PP
+-\-Xlint:none
+-.RS 4
+-Disables all warnings\&.
+-.RE
+-.PP
+-\-Xlint:\fIname\fR
+-.RS 4
+-Disables warning name\&. See Enable or Disable Warnings with the \-Xlint Option for a list of warnings you can disable with this option\&.
+-.RE
+-.PP
+-\-Xlint:\fI\-name\fR
+-.RS 4
+-Disables warning name\&. See Enable or Disable Warnings with the \-Xlint Option with the
+-\fB\-Xlint\fR
+-option to get a list of warnings that you can disable with this option\&.
+-.RE
+-.PP
+-\-Xmaxerrs \fInumber\fR
+-.RS 4
+-Sets the maximum number of errors to print\&.
+-.RE
+-.PP
+-\-Xmaxwarns \fInumber\fR
+-.RS 4
+-Sets the maximum number of warnings to print\&.
+-.RE
+-.PP
+-\-Xstdout \fIfilename\fR
+-.RS 4
+-Sends compiler messages to the named file\&. By default, compiler messages go to
+-\fBSystem\&.err\fR\&.
+-.RE
+-.PP
+-\-Xprefer:[\fInewer,source\fR]
+-.RS 4
+-Specifies which file to read when both a source file and class file are found for a type\&. (See Searching for Types)\&. If the
+-\fB\-Xprefer:newer\fR
+-option is used, then it reads the newer of the source or class file for a type (default)\&. If the
+-\fB\-Xprefer:source\fR
+-option is used, then it reads the source file\&. Use \-\fBXprefer:source\fR
+-when you want to be sure that any annotation processors can access annotations declared with a retention policy of
+-\fBSOURCE\fR\&.
+-.RE
+-.PP
+-\-Xpkginfo:[\fIalways\fR,\fIlegacy\fR,\fInonempty\fR]
+-.RS 4
+-Control whether javac generates
+-\fBpackage\-info\&.class\fR
+-files from package\-info\&.java files\&. Possible mode arguments for this option include the following\&.
+-.PP
+-always
+-.RS 4
+-Always generate a
+-\fBpackage\-info\&.class\fR
+-file for every
+-\fBpackage\-info\&.java\fR
+-file\&. This option may be useful if you use a build system such as Ant, which checks that each
+-\fB\&.java\fR
+-file has a corresponding
+-\fB\&.class\fR
+-file\&.
+-.RE
+-.PP
+-legacy
+-.RS 4
+-Generate a
+-\fBpackage\-info\&.class\fR
+-file only if package\-info\&.java contains annotations\&. Don\*(Aqt generate a
+-\fBpackage\-info\&.class\fR
+-file if package\-info\&.java only contains comments\&.
+-.sp
+-\fBNote:\fR
+-A
+-\fBpackage\-info\&.class\fR
+-file might be generated but be empty if all the annotations in the package\-info\&.java file have
+-\fBRetentionPolicy\&.SOURCE\fR\&.
+-.RE
+-.PP
+-nonempty
+-.RS 4
+-Generate a
+-\fBpackage\-info\&.class\fR
+-file only if package\-info\&.java contains annotations with
+-\fBRetentionPolicy\&.CLASS\fR
+-or
+-\fBRetentionPolicy\&.RUNTIME\fR\&.
+-.RE
+-.RE
+-.PP
+-\-Xprint
+-.RS 4
+-Prints a textual representation of specified types for debugging purposes\&. Perform neither annotation processing nor compilation\&. The format of the output could change\&.
+-.RE
+-.PP
+-\-XprintProcessorInfo
+-.RS 4
+-Prints information about which annotations a processor is asked to process\&.
+-.RE
+-.PP
+-\-XprintRounds
+-.RS 4
+-Prints information about initial and subsequent annotation processing rounds\&.
+-.RE
+-.SH "ENABLE OR DISABLE WARNINGS WITH THE -XLINT OPTION"
+-.PP
+-Enable warning
+-\fIname\fR
+-with the
+-\fB\-Xlint:name\fR
+-option, where
+-\fBname\fR
+-is one of the following warning names\&. Note that you can disable a warning with the
+-\fB\-Xlint:\-name:\fR
+-option\&.
+-.PP
+-cast
+-.RS 4
+-Warns about unnecessary and redundant casts, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBString s = (String) "Hello!"\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-classfile
+-.RS 4
+-Warns about issues related to class file contents\&.
+-.RE
+-.PP
+-deprecation
+-.RS 4
+-Warns about the use of deprecated items, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjava\&.util\&.Date myDate = new java\&.util\&.Date();\fR
+-\fBint currentDay = myDate\&.getDay();\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The method
+-\fBjava\&.util\&.Date\&.getDay\fR
+-has been deprecated since JDK 1\&.1
+-.RE
+-.PP
+-dep\-ann
+-.RS 4
+-Warns about items that are documented with an
+-\fB@deprecated\fR
+-Javadoc comment, but do not have a
+-\fB@Deprecated\fR
+-annotation, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB/**\fR
+-\fB * @deprecated As of Java SE 7, replaced by {@link #newMethod()}\fR
+-\fB */\fR
+-\fBpublic static void deprecatedMethood() { }\fR
+-\fBpublic static void newMethod() { }\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-divzero
+-.RS 4
+-Warns about division by the constant integer 0, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBint divideByZero = 42 / 0;\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-empty
+-.RS 4
+-Warns about empty statements after
+-\fBif \fRstatements, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBclass E {\fR
+-\fB void m() {\fR
+-\fB if (true) ;\fR
+-\fB }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-fallthrough
+-.RS 4
+-Checks the switch blocks for fall\-through cases and provides a warning message for any that are found\&. Fall\-through cases are cases in a switch block, other than the last case in the block, whose code does not include a break statement, allowing code execution to fall through from that case to the next case\&. For example, the code following the case 1 label in this switch block does not end with a break statement:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBswitch (x) {\fR
+-\fBcase 1:\fR
+-\fB System\&.out\&.println("1");\fR
+-\fB // No break statement here\&.\fR
+-\fBcase 2:\fR
+-\fB System\&.out\&.println("2");\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-If the
+-\fB\-Xlint:fallthrough\fR
+-option was used when compiling this code, then the compiler emits a warning about possible fall\-through into case, with the line number of the case in question\&.
+-.RE
+-.PP
+-finally
+-.RS 4
+-Warns about
+-\fBfinally\fR
+-clauses that cannot complete normally, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpublic static int m() {\fR
+-\fB try {\fR
+-\fB throw new NullPointerException();\fR
+-\fB } catch (NullPointerException(); {\fR
+-\fB System\&.err\&.println("Caught NullPointerException\&.");\fR
+-\fB return 1;\fR
+-\fB } finally {\fR
+-\fB return 0;\fR
+-\fB }\fR
+-\fB }\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The compiler generates a warning for the
+-\fBfinally\fR
+-block in this example\&. When the
+-\fBint\fR
+-method is called, it returns a value of 0\&. A
+-\fBfinally\fR
+-block executes when the
+-\fBtry\fR
+-block exits\&. In this example, when control is transferred to the
+-\fBcatch\fR
+-block, the
+-\fBint\fR
+-method exits\&. However, the
+-\fBfinally\fR
+-block must execute, so it is executed, even though control was transferred outside the method\&.
+-.RE
+-.PP
+-options
+-.RS 4
+-Warns about issues that related to the use of command\-line options\&. See Cross\-Compilation Options\&.
+-.RE
+-.PP
+-overrides
+-.RS 4
+-Warns about issues regarding method overrides\&. For example, consider the following two classes:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpublic class ClassWithVarargsMethod {\fR
+-\fB void varargsMethod(String\&.\&.\&. s) { }\fR
+-\fB}\fR
+-
+-\fBpublic class ClassWithOverridingMethod extends ClassWithVarargsMethod {\fR
+-\fB @Override\fR
+-\fB void varargsMethod(String[] s) { }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The compiler generates a warning similar to the following:\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBwarning: [override] varargsMethod(String[]) in ClassWithOverridingMethod \fR
+-\fBoverrides varargsMethod(String\&.\&.\&.) in ClassWithVarargsMethod; overriding\fR
+-\fBmethod is missing \*(Aq\&.\&.\&.\*(Aq\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-When the compiler encounters a
+-\fBvarargs\fR
+-method, it translates the
+-\fBvarargs\fR
+-formal parameter into an array\&. In the method
+-\fBClassWithVarargsMethod\&.varargsMethod\fR, the compiler translates the
+-\fBvarargs\fR
+-formal parameter
+-\fBString\&.\&.\&. s\fR
+-to the formal parameter
+-\fBString[] s\fR, an array, which matches the formal parameter of the method
+-\fBClassWithOverridingMethod\&.varargsMethod\fR\&. Consequently, this example compiles\&.
+-.RE
+-.PP
+-path
+-.RS 4
+-Warns about invalid path elements and nonexistent path directories on the command line (with regard to the class path, the source path, and other paths)\&. Such warnings cannot be suppressed with the
+-\fB@SuppressWarnings\fR
+-annotation, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-Xlint:path \-classpath /nonexistentpath Example\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-processing
+-.RS 4
+-Warn about issues regarding annotation processing\&. The compiler generates this warning when you have a class that has an annotation, and you use an annotation processor that cannot handle that type of exception\&. For example, the following is a simple annotation processor:
+-.sp
+-\fBSource file AnnocProc\&.java\fR:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBimport java\&.util\&.*;\fR
+-\fBimport javax\&.annotation\&.processing\&.*;\fR
+-\fBimport javax\&.lang\&.model\&.*;\fR
+-\fBimport\&.javaz\&.lang\&.model\&.element\&.*;\fR
+-
+-\fB@SupportedAnnotationTypes("NotAnno")\fR
+-\fBpublic class AnnoProc extends AbstractProcessor {\fR
+-\fB public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv){\fR
+-\fB return true;\fR
+-\fB }\fR
+-
+-\fB public SourceVersion getSupportedSourceVersion() {\fR
+-\fB return SourceVersion\&.latest();\fR
+-\fB }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-\fBSource file AnnosWithoutProcessors\&.java\fR:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB@interface Anno { }\fR
+-\fB \fR
+-\fB@Anno\fR
+-\fBclass AnnosWithoutProcessors { }\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The following commands compile the annotation processor
+-\fBAnnoProc\fR, then run this annotation processor against the source file
+-\fBAnnosWithoutProcessors\&.java\fR:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac AnnoProc\&.java\fR
+-\fBjavac \-cp \&. \-Xlint:processing \-processor AnnoProc \-proc:only AnnosWithoutProcessors\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-When the compiler runs the annotation processor against the source file
+-\fBAnnosWithoutProcessors\&.java\fR, it generates the following warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBwarning: [processing] No processor claimed any of these annotations: Anno\fR
+-\fB \fR
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-To resolve this issue, you can rename the annotation defined and used in the class
+-\fBAnnosWithoutProcessors\fR
+-from
+-\fBAnno\fR
+-to
+-\fBNotAnno\fR\&.
+-.RE
+-.PP
+-rawtypes
+-.RS 4
+-Warns about unchecked operations on raw types\&. The following statement generates a
+-\fBrawtypes\fR
+-warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBvoid countElements(List l) { \&.\&.\&. }\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The following example does not generate a
+-\fBrawtypes\fR
+-warning
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBvoid countElements(List<?> l) { \&.\&.\&. }\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-\fBList\fR
+-is a raw type\&. However,
+-\fBList<?>\fR
+-is an unbounded wildcard parameterized type\&. Because
+-\fBList\fR
+-is a parameterized interface, always specify its type argument\&. In this example, the
+-\fBList\fR
+-formal argument is specified with an unbounded wildcard (\fB?\fR) as its formal type parameter, which means that the
+-\fBcountElements\fR
+-method can accept any instantiation of the
+-\fBList\fR
+-interface\&.
+-.RE
+-.PP
+-Serial
+-.RS 4
+-Warns about missing
+-\fBserialVersionUID\fR
+-definitions on serializable classes, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpublic class PersistentTime implements Serializable\fR
+-\fB{\fR
+-\fB private Date time;\fR
+-\fB \fR
+-\fB public PersistentTime() {\fR
+-\fB time = Calendar\&.getInstance()\&.getTime();\fR
+-\fB }\fR
+-\fB \fR
+-\fB public Date getTime() {\fR
+-\fB return time;\fR
+-\fB }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The compiler generates the following warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBwarning: [serial] serializable class PersistentTime has no definition of\fR
+-\fBserialVersionUID\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-If a serializable class does not explicitly declare a field named
+-\fBserialVersionUID\fR, then the serialization runtime environment calculates a default
+-\fBserialVersionUID\fR
+-value for that class based on various aspects of the class, as described in the Java Object Serialization Specification\&. However, it is strongly recommended that all serializable classes explicitly declare
+-\fBserialVersionUID\fR
+-values because the default process of computing
+-\fBserialVersionUID\fR
+-vales is highly sensitive to class details that can vary depending on compiler implementations, and as a result, might cause an unexpected
+-\fBInvalidClassExceptions\fR
+-during deserialization\&. To guarantee a consistent
+-\fBserialVersionUID\fR
+-value across different Java compiler implementations, a serializable class must declare an explicit
+-\fBserialVersionUID\fR
+-value\&.
+-.RE
+-.PP
+-static
+-.RS 4
+-Warns about issues relating to the use of statics, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBclass XLintStatic {\fR
+-\fB static void m1() { }\fR
+-\fB void m2() { this\&.m1(); }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The compiler generates the following warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBwarning: [static] static method should be qualified by type name, \fR
+-\fBXLintStatic, instead of by an expression\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-To resolve this issue, you can call the
+-\fBstatic\fR
+-method
+-\fBm1\fR
+-as follows:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBXLintStatic\&.m1();\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Alternately, you can remove the
+-\fBstatic\fR
+-keyword from the declaration of the method
+-\fBm1\fR\&.
+-.RE
+-.PP
+-try
+-.RS 4
+-Warns about issues relating to use of
+-\fBtry\fR
+-blocks, including try\-with\-resources statements\&. For example, a warning is generated for the following statement because the resource
+-\fBac\fR
+-declared in the
+-\fBtry\fR
+-block is not used:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBtry ( AutoCloseable ac = getResource() ) { // do nothing}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-unchecked
+-.RS 4
+-Gives more detail for unchecked conversion warnings that are mandated by the Java Language Specification, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBList l = new ArrayList<Number>();\fR
+-\fBList<String> ls = l; // unchecked warning\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-During type erasure, the types
+-\fBArrayList<Number>\fR
+-and
+-\fBList<String>\fR
+-become
+-\fBArrayList\fR
+-and
+-\fBList\fR, respectively\&.
+-.sp
+-The
+-\fBls\fR
+-command has the parameterized type
+-\fBList<String>\fR\&. When the
+-\fBList\fR
+-referenced by
+-\fBl\fR
+-is assigned to
+-\fBls\fR, the compiler generates an unchecked warning\&. At compile time, the compiler and JVM cannot determine whether
+-\fBl\fR
+-refers to a
+-\fBList<String>\fR
+-type\&. In this case,
+-\fBl\fR
+-does not refer to a
+-\fBList<String>\fR
+-type\&. As a result, heap pollution occurs\&.
+-.sp
+-A heap pollution situation occurs when the
+-\fBList\fR
+-object
+-\fBl\fR, whose static type is
+-\fBList<Number>\fR, is assigned to another
+-\fBList\fR
+-object,
+-\fBls\fR, that has a different static type,
+-\fBList<String>\fR\&. However, the compiler still allows this assignment\&. It must allow this assignment to preserve backward compatibility with releases of Java SE that do not support generics\&. Because of type erasure,
+-\fBList<Number>\fR
+-and
+-\fBList<String>\fR
+-both become
+-\fBList\fR\&. Consequently, the compiler allows the assignment of the object
+-\fBl\fR\fB,\fR
+-which has a raw type of
+-\fBList\fR, to the object
+-\fBls\fR\&.
+-.RE
+-.PP
+-varargs
+-.RS 4
+-Warns about unsafe usages of variable arguments (\fBvarargs\fR) methods, in particular, those that contain non\-reifiable arguments, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpublic class ArrayBuilder {\fR
+-\fB public static <T> void addToList (List<T> listArg, T\&.\&.\&. elements) {\fR
+-\fB for (T x : elements) {\fR
+-\fB listArg\&.add(x);\fR
+-\fB }\fR
+-\fB }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-\fBNote:\fR
+-A non\-reifiable type is a type whose type information is not fully available at runtime\&.
+-.sp
+-The compiler generates the following warning for the definition of the method
+-\fBArrayBuilder\&.addToList\fR
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBwarning: [varargs] Possible heap pollution from parameterized vararg type T\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-When the compiler encounters a varargs method, it translates the
+-\fBvarargs\fR
+-formal parameter into an array\&. However, the Java programming language does not permit the creation of arrays of parameterized types\&. In the method
+-\fBArrayBuilder\&.addToList\fR, the compiler translates the
+-\fBvarargs\fR
+-formal parameter
+-\fBT\&.\&.\&.\fR
+-elements to the formal parameter
+-\fBT[]\fR
+-elements, an array\&. However, because of type erasure, the compiler converts the
+-\fBvarargs\fR
+-formal parameter to
+-\fBObject[]\fR
+-elements\&. Consequently, there is a possibility of heap pollution\&.
+-.RE
+-.SH "COMMAND-LINE ARGUMENT FILES"
+-.PP
+-To shorten or simplify the
+-\fBjavac\fR
+-command, you can specify one or more files that contain arguments to the
+-\fBjavac\fR
+-command (except
+-\fB\-J\fR
+-options)\&. This enables you to create
+-\fBjavac\fR
+-commands of any length on any operating system\&.
+-.PP
+-An argument file can include
+-\fBjavac\fR
+-options and source file names in any combination\&. The arguments within a file can be separated by spaces or new line characters\&. If a file name contains embedded spaces, then put the whole file name in double quotation marks\&.
+-.PP
+-File Names within an argument file are relative to the current directory, not the location of the argument file\&. Wild cards (*) are not allowed in these lists (such as for specifying
+-\fB*\&.java\fR)\&. Use of the at sign (@) to recursively interpret files is not supported\&. The
+-\fB\-J\fR
+-options are not supported because they are passed to the launcher, which does not support argument files\&.
+-.PP
+-When executing the
+-\fBjavac\fR
+-command, pass in the path and name of each argument file with the at sign (@) leading character\&. When the
+-\fBjavac\fR
+-command encounters an argument beginning with the at sign (@), it expands the contents of that file into the argument list\&.
+-.PP
+-\fBExample 1\fR
+-.br
+-Single Argument File
+-.RS 4
+-You could use a single argument file named
+-\fBargfile\fR
+-to hold all
+-\fBjavac\fR
+-arguments:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac @argfile\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-This argument file could contain the contents of both files shown in Example 2
+-.RE
+-.PP
+-\fBExample 2\fR
+-.br
+-Two Argument Files
+-.RS 4
+-You can create two argument files: one for the
+-\fBjavac\fR
+-options and the other for the source file names\&. Note that the following lists have no line\-continuation characters\&.
+-.sp
+-Create a file named options that contains the following:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB\-d classes\fR
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB\-g\fR
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB\-sourcepath /java/pubs/ws/1\&.3/src/share/classes\fR
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Create a file named classes that contains the following:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBMyClass1\&.java\fR
+-\fBMyClass2\&.java\fR
+-\fBMyClass3\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Then, run the
+-\fBjavac\fR
+-command as follows:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac @options @classes\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-\fBExample 3\fR
+-.br
+-Argument Files with Paths
+-.RS 4
+-The argument files can have paths, but any file names inside the files are relative to the current working directory (not
+-\fBpath1\fR
+-or
+-\fBpath2\fR):
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac @path1/options @path2/classes\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.SH "ANNOTATION PROCESSING"
+-.PP
+-The
+-\fBjavac\fR
+-command provides direct support for annotation processing, superseding the need for the separate annotation processing command,
+-\fBapt\fR\&.
+-.PP
+-The API for annotation processors is defined in the
+-\fBjavax\&.annotation\&.processing\fR
+-and j\fBavax\&.lang\&.model\fR
+-packages and subpackages\&.
+-.SS "How Annotation Processing Works"
+-.PP
+-Unless annotation processing is disabled with the
+-\fB\-proc:none\fR
+-option, the compiler searches for any annotation processors that are available\&. The search path can be specified with the
+-\fB\-processorpath\fR
+-option\&. If no path is specified, then the user class path is used\&. Processors are located by means of service provider\-configuration files named
+-\fBMETA\-INF/services/javax\&.annotation\&.processing\fR\&.Processor on the search path\&. Such files should contain the names of any annotation processors to be used, listed one per line\&. Alternatively, processors can be specified explicitly, using the
+-\fB\-processor\fR
+-option\&.
++The API for annotation processors is defined in the \f3javax\&.annotation\&.processing\fR and j\f3avax\&.lang\&.model\fR packages and subpackages\&.
++.SS HOW\ ANNOTATION\ PROCESSING\ WORKS
++Unless annotation processing is disabled with the \f3-proc:none\fR option, the compiler searches for any annotation processors that are available\&. The search path can be specified with the \f3-processorpath\fR option\&. If no path is specified, then the user class path is used\&. Processors are located by means of service provider-configuration files named \f3META-INF/services/javax\&.annotation\&.processing\fR\&.Processor on the search path\&. Such files should contain the names of any annotation processors to be used, listed one per line\&. Alternatively, processors can be specified explicitly, using the \f3-processor\fR option\&.
+ .PP
+ After scanning the source files and classes on the command line to determine what annotations are present, the compiler queries the processors to determine what annotations they process\&. When a match is found, the processor is called\&. A processor can claim the annotations it processes, in which case no further attempt is made to find any processors for those annotations\&. After all of the annotations are claimed, the compiler does not search for additional processors\&.
+ .PP
+ If any processors generate new source files, then another round of annotation processing occurs: Any newly generated source files are scanned, and the annotations processed as before\&. Any processors called on previous rounds are also called on all subsequent rounds\&. This continues until no new source files are generated\&.
+ .PP
+-After a round occurs where no new source files are generated, the annotation processors are called one last time, to give them a chance to complete any remaining work\&. Finally, unless the
+-\fB\-proc:only\fR
+-option is used, the compiler compiles the original and all generated source files\&.
+-.SS "Implicitly Loaded Source Files"
+-.PP
+-To compile a set of source files, the compiler might need to implicitly load additional source files\&. See Searching for Types\&. Such files are currently not subject to annotation processing\&. By default, the compiler gives a warning when annotation processing occurred and any implicitly loaded source files are compiled\&. The
+-\fB\-implicit\fR
+-option provides a way to suppress the warning\&.
+-.SH "SEARCHING FOR TYPES"
+-.PP
++After a round occurs where no new source files are generated, the annotation processors are called one last time, to give them a chance to complete any remaining work\&. Finally, unless the \f3-proc:only\fR option is used, the compiler compiles the original and all generated source files\&.
++.SS IMPLICITLY\ LOADED\ SOURCE\ FILES
++To compile a set of source files, the compiler might need to implicitly load additional source files\&. See Searching for Types\&. Such files are currently not subject to annotation processing\&. By default, the compiler gives a warning when annotation processing occurred and any implicitly loaded source files are compiled\&. The \f3-implicit\fR option provides a way to suppress the warning\&.
++.SH SEARCHING\ FOR\ TYPES
+ To compile a source file, the compiler often needs information about a type, but the type definition is not in the source files specified on the command line\&. The compiler needs type information for every class or interface used, extended, or implemented in the source file\&. This includes classes and interfaces not explicitly mentioned in the source file, but that provide information through inheritance\&.
+ .PP
+-For example, when you create a subclass
+-\fBjava\&.applet\&.Applet\fR, you are also using the ancestor classes of
+-\fBApplet\fR:
+-\fBjava\&.awt\&.Panel\fR,
+-\fBjava\&.awt\&.Container\fR,
+-\fBjava\&.awt\&.Component\fR, and
+-\fBjava\&.lang\&.Object\fR\&.
++For example, when you create a subclass \f3java\&.applet\&.Applet\fR, you are also using the ancestor classes of \f3Applet\fR: \f3java\&.awt\&.Panel\fR, \f3java\&.awt\&.Container\fR, \f3java\&.awt\&.Component\fR, and \f3java\&.lang\&.Object\fR\&.
+ .PP
+-When the compiler needs type information, it searches for a source file or class file that defines the type\&. The compiler searches for class files first in the bootstrap and extension classes, then in the user class path (which by default is the current directory)\&. The user class path is defined by setting the
+-\fBCLASSPATH\fR
+-environment variable or by using the
+-\fB\-classpath\fR
+-option\&.
++When the compiler needs type information, it searches for a source file or class file that defines the type\&. The compiler searches for class files first in the bootstrap and extension classes, then in the user class path (which by default is the current directory)\&. The user class path is defined by setting the \f3CLASSPATH\fR environment variable or by using the \f3-classpath\fR option\&.
+ .PP
+-If you set the
+-\fB\-sourcepath\fR
+-option, then the compiler searches the indicated path for source files\&. Otherwise, the compiler searches the user class path for both class files and source files\&.
++If you set the \f3-sourcepath\fR option, then the compiler searches the indicated path for source files\&. Otherwise, the compiler searches the user class path for both class files and source files\&.
+ .PP
+-You can specify different bootstrap or extension classes with the
+-\fB\-bootclasspath\fR
+-and the
+-\fB\-extdirs\fR
+-options\&. See Cross\-Compilation Options\&.
++You can specify different bootstrap or extension classes with the \f3-bootclasspath\fR and the \f3-extdirs\fR options\&. See Cross-Compilation Options\&.
+ .PP
+-A successful type search may produce a class file, a source file, or both\&. If both are found, then you can use the
+-\fB\-Xprefer\fR
+-option to instruct the compiler which to use\&. If
+-\fBnewer\fR
+-is specified, then the compiler uses the newer of the two files\&. If
+-\fBsource\fR
+-is specified, the compiler uses the source file\&. The default is
+-\fBnewer\fR\&.
++A successful type search may produce a class file, a source file, or both\&. If both are found, then you can use the \f3-Xprefer\fR option to instruct the compiler which to use\&. If \f3newer\fR is specified, then the compiler uses the newer of the two files\&. If \f3source\fR is specified, the compiler uses the source file\&. The default is \f3newer\fR\&.
+ .PP
+-If a type search finds a source file for a required type, either by itself, or as a result of the setting for the
+-\fB\-Xprefer\fR
+-option, then the compiler reads the source file to get the information it needs\&. By default the compiler also compiles the source file\&. You can use the
+-\fB\-implicit\fR
+-option to specify the behavior\&. If
+-\fBnone\fR
+-is specified, then no class files are generated for the source file\&. If
+-\fBclass\fR
+-is specified, then class files are generated for the source file\&.
++If a type search finds a source file for a required type, either by itself, or as a result of the setting for the \f3-Xprefer\fR option, then the compiler reads the source file to get the information it needs\&. By default the compiler also compiles the source file\&. You can use the \f3-implicit\fR option to specify the behavior\&. If \f3none\fR is specified, then no class files are generated for the source file\&. If \f3class\fR is specified, then class files are generated for the source file\&.
+ .PP
+-The compiler might not discover the need for some type information until after annotation processing completes\&. When the type information is found in a source file and no
+-\fB\-implicit\fR
+-option is specified, the compiler gives a warning that the file is being compiled without being subject to annotation processing\&. To disable the warning, either specify the file on the command line (so that it will be subject to annotation processing) or use the
+-\fB\-implicit\fR
+-option to specify whether or not class files should be generated for such source files\&.
+-.SH "PROGRAMMATIC INTERFACE"
++The compiler might not discover the need for some type information until after annotation processing completes\&. When the type information is found in a source file and no \f3-implicit\fR option is specified, the compiler gives a warning that the file is being compiled without being subject to annotation processing\&. To disable the warning, either specify the file on the command line (so that it will be subject to annotation processing) or use the \f3-implicit\fR option to specify whether or not class files should be generated for such source files\&.
++.SH PROGRAMMATIC\ INTERFACE
++The \f3javac\fR command supports the new Java Compiler API defined by the classes and interfaces in the \f3javax\&.tools\fR package\&.
++.SS EXAMPLE
++To compile as though providing command-line arguments, use the following syntax:
++.sp
++.nf
++\f3JavaCompiler javac = ToolProvider\&.getSystemJavaCompiler();\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++The example writes diagnostics to the standard output stream and returns the exit code that \f3javac\fR would give when called from the command line\&.
+ .PP
+-The
+-\fBjavac\fR
+-command supports the new Java Compiler API defined by the classes and interfaces in the
+-\fBjavax\&.tools\fR
+-package\&.
+-.SS "Example"
++You can use other methods in the \f3javax\&.tools\&.JavaCompiler\fR interface to handle diagnostics, control where files are read from and written to, and more\&.
++.SS OLD\ INTERFACE
++\fINote:\fR This API is retained for backward compatibility only\&. All new code should use the newer Java Compiler API\&.
+ .PP
+-To compile as though providing command\-line arguments, use the following syntax:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBJavaCompiler javac = ToolProvider\&.getSystemJavaCompiler();\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
++The \f3com\&.sun\&.tools\&.javac\&.Main\fR class provides two static methods to call the compiler from a program:
++.sp
++.nf
++\f3public static int compile(String[] args);\fP
++.fi
++.nf
++\f3public static int compile(String[] args, PrintWriter out);\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++The \f3args\fR parameter represents any of the command-line arguments that would typically be passed to the compiler\&.
+ .PP
+-The example writes diagnostics to the standard output stream and returns the exit code that
+-\fBjavac\fR
+-would give when called from the command line\&.
++The \f3out\fR parameter indicates where the compiler diagnostic output is directed\&.
+ .PP
+-You can use other methods in the
+-\fBjavax\&.tools\&.JavaCompiler\fR
+-interface to handle diagnostics, control where files are read from and written to, and more\&.
+-.SS "Old Interface"
++The \f3return\fR value is equivalent to the \f3exit\fR value from \f3javac\fR\&.
+ .PP
+-\fBNote:\fR
+-This API is retained for backward compatibility only\&. All new code should use the newer Java Compiler API\&.
++\fINote:\fR All other classes and methods found in a package with names that start with \f3com\&.sun\&.tools\&.javac\fR (subpackages of \f3com\&.sun\&.tools\&.javac\fR) are strictly internal and subject to change at any time\&.
++.SH EXAMPLES
++\f3Example 1 Compile a Simple Program\fR
+ .PP
+-The
+-\fBcom\&.sun\&.tools\&.javac\&.Main\fR
+-class provides two static methods to call the compiler from a program:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpublic static int compile(String[] args);\fR
+-\fBpublic static int compile(String[] args, PrintWriter out);\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
++This example shows how to compile the \f3Hello\&.java\fR source file in the greetings directory\&. The class defined in \f3Hello\&.java\fR is called \f3greetings\&.Hello\fR\&. The greetings directory is the package directory both for the source file and the class file and is underneath the current directory\&. This makes it possible to use the default user class path\&. It also makes it unnecessary to specify a separate destination directory with the \f3-d\fR option\&.
+ .PP
+-The
+-\fBargs\fR
+-parameter represents any of the command\-line arguments that would typically be passed to the compiler\&.
++The source code in \f3Hello\&.java\fR:
++.sp
++.nf
++\f3package greetings;\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3public class Hello {\fP
++.fi
++.nf
++\f3 public static void main(String[] args) {\fP
++.fi
++.nf
++\f3 for (int i=0; i < args\&.length; i++) {\fP
++.fi
++.nf
++\f3 System\&.out\&.println("Hello " + args[i]);\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++Compile greetings\&.Hello:
++.sp
++.nf
++\f3javac greetings/Hello\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++Run \f3greetings\&.Hello\fR:
++.sp
++.nf
++\f3java greetings\&.Hello World Universe Everyone\fP
++.fi
++.nf
++\f3Hello World\fP
++.fi
++.nf
++\f3Hello Universe\fP
++.fi
++.nf
++\f3Hello Everyone\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++\f3Example 2 Compile Multiple Source Files\fR
+ .PP
+-The
+-\fBout\fR
+-parameter indicates where the compiler diagnostic output is directed\&.
++This example compiles the \f3Aloha\&.java\fR, \f3GutenTag\&.java\fR, \f3Hello\&.java\fR, and \f3Hi\&.java\fR source files in the \f3greetings\fR package\&.
++.sp
++.nf
++\f3% javac greetings/*\&.java\fP
++.fi
++.nf
++\f3% ls greetings\fP
++.fi
++.nf
++\f3Aloha\&.class GutenTag\&.class Hello\&.class Hi\&.class\fP
++.fi
++.nf
++\f3Aloha\&.java GutenTag\&.java Hello\&.java Hi\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++\f3Example 3 Specify a User Class Path\fR
+ .PP
+-The
+-\fBreturn\fR
+-value is equivalent to the
+-\fBexit\fR
+-value from
+-\fBjavac\fR\&.
++After changing one of the source files in the previous example, recompile it:
++.sp
++.nf
++\f3pwd\fP
++.fi
++.nf
++\f3/examples\fP
++.fi
++.nf
++\f3javac greetings/Hi\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++Because \f3greetings\&.Hi\fR refers to other classes in the \f3greetings\fR package, the compiler needs to find these other classes\&. The previous example works because the default user class path is the directory that contains the package directory\&. If you want to recompile this file without concern for which directory you are in, then add the examples directory to the user class path by setting \f3CLASSPATH\fR\&. This example uses the \f3-classpath\fR option\&.
++.sp
++.nf
++\f3javac \-classpath /examples /examples/greetings/Hi\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++If you change \f3greetings\&.Hi\fR to use a banner utility, then that utility also needs to be accessible through the user class path\&.
++.sp
++.nf
++\f3javac \-classpath /examples:/lib/Banners\&.jar \e\fP
++.fi
++.nf
++\f3 /examples/greetings/Hi\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++To execute a class in the \f3greetings\fR package, the program needs access to the \f3greetings\fR package, and to the classes that the \f3greetings\fR classes use\&.
++.sp
++.nf
++\f3java \-classpath /examples:/lib/Banners\&.jar greetings\&.Hi\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++\f3Example 4 Separate Source Files and Class Files\fR
+ .PP
+-\fBNote:\fR
+-All other classes and methods found in a package with names that start with
+-\fBcom\&.sun\&.tools\&.javac\fR
+-(subpackages of
+-\fBcom\&.sun\&.tools\&.javac\fR) are strictly internal and subject to change at any time\&.
+-.SH "EXAMPLES"
++The following example uses \f3javac\fR to compile code that runs on JVM 1\&.7\&.
++.sp
++.nf
++\f3javac \-source 1\&.7 \-target 1\&.7 \-bootclasspath jdk1\&.7\&.0/lib/rt\&.jar \e \fP
++.fi
++.nf
++\f3\-extdirs "" OldCode\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++The \f3-source 1\&.7\fR option specifies that release 1\&.7 (or 7) of the Java programming language be used to compile \f3OldCode\&.java\fR\&. The option \f3-target 1\&.7\fR option ensures that the generated class files are compatible with JVM 1\&.7\&. Note that in most cases, the value of the \f3-target\fR option is the value of the \f3-source\fR option; in this example, you can omit the \f3-target\fR option\&.
+ .PP
+-\fBExample 1\fR
+-.br
+-Compile a Simple Program
+-.RS 4
+-This example shows how to compile the
+-\fBHello\&.java\fR
+-source file in the greetings directory\&. The class defined in
+-\fBHello\&.java\fR
+-is called
+-\fBgreetings\&.Hello\fR\&. The greetings directory is the package directory both for the source file and the class file and is underneath the current directory\&. This makes it possible to use the default user class path\&. It also makes it unnecessary to specify a separate destination directory with the
+-\fB\-d\fR
+-option\&.
+-.sp
+-The source code in
+-\fBHello\&.java\fR:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpackage greetings;\fR
+-\fB \fR
+-\fBpublic class Hello {\fR
+-\fB public static void main(String[] args) {\fR
+-\fB for (int i=0; i < args\&.length; i++) {\fR
+-\fB System\&.out\&.println("Hello " + args[i]);\fR
+-\fB }\fR
+-\fB }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Compile greetings\&.Hello:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac greetings/Hello\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Run
+-\fBgreetings\&.Hello\fR:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjava greetings\&.Hello World Universe Everyone\fR
+-\fBHello World\fR
+-\fBHello Universe\fR
+-\fBHello Everyone\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
++You must specify the \f3-bootclasspath\fR option to specify the correct version of the bootstrap classes (the \f3rt\&.jar\fR library)\&. If not, then the compiler generates a warning:
++.sp
++.nf
++\f3javac \-source 1\&.7 OldCode\&.java\fP
++.fi
++.nf
++\f3warning: [options] bootstrap class path not set in conjunction with \fP
++.fi
++.nf
++\f3\-source 1\&.7\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++If you do not specify the correct version of bootstrap classes, then the compiler uses the old language rules (in this example, it uses version 1\&.7 of the Java programming language) combined with the new bootstrap classes, which can result in class files that do not work on the older platform (in this case, Java SE 7) because reference to nonexistent methods can get included\&.
+ .PP
+-\fBExample 2\fR
+-.br
+-Compile Multiple Source Files
+-.RS 4
+-This example compiles the
+-\fBAloha\&.java\fR,
+-\fBGutenTag\&.java\fR,
+-\fBHello\&.java\fR, and
+-\fBHi\&.java\fR
+-source files in the
+-\fBgreetings\fR
+-package\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB% javac greetings/*\&.java\fR
+-\fB% ls greetings\fR
+-\fBAloha\&.class GutenTag\&.class Hello\&.class Hi\&.class\fR
+-\fBAloha\&.java GutenTag\&.java Hello\&.java Hi\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
++\f3Example 5 Cross Compile\fR
+ .PP
+-\fBExample 3\fR
+-.br
+-Specify a User Class Path
+-.RS 4
+-After changing one of the source files in the previous example, recompile it:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpwd\fR
+-\fB/examples\fR
+-\fBjavac greetings/Hi\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Because
+-\fBgreetings\&.Hi\fR
+-refers to other classes in the
+-\fBgreetings\fR
+-package, the compiler needs to find these other classes\&. The previous example works because the default user class path is the directory that contains the package directory\&. If you want to recompile this file without concern for which directory you are in, then add the examples directory to the user class path by setting
+-\fBCLASSPATH\fR\&. This example uses the
+-\fB\-classpath\fR
+-option\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-classpath /examples /examples/greetings/Hi\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-If you change
+-\fBgreetings\&.Hi\fR
+-to use a banner utility, then that utility also needs to be accessible through the user class path\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-classpath /examples:/lib/Banners\&.jar \e\fR
+-\fB /examples/greetings/Hi\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-To execute a class in the
+-\fBgreetings\fR
+-package, the program needs access to the
+-\fBgreetings\fR
+-package, and to the classes that the
+-\fBgreetings\fR
+-classes use\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjava \-classpath /examples:/lib/Banners\&.jar greetings\&.Hi\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
++This example uses \f3javac\fR to compile code that runs on JVM 1\&.7\&.
++.sp
++.nf
++\f3javac \-source 1\&.7 \-target 1\&.7 \-bootclasspath jdk1\&.7\&.0/lib/rt\&.jar \e\fP
++.fi
++.nf
++\f3 \-extdirs "" OldCode\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++The\f3-source 1\&.7\fR option specifies that release 1\&.7 (or 7) of the Java programming language to be used to compile OldCode\&.java\&. The \f3-target 1\&.7\fR option ensures that the generated class files are compatible with JVM 1\&.7\&.
+ .PP
+-\fBExample 4\fR
+-.br
+-Separate Source Files and Class Files
+-.RS 4
+-The following example uses
+-\fBjavac\fR
+-to compile code that runs on JVM 1\&.7\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-source 1\&.7 \-target 1\&.7 \-bootclasspath jdk1\&.7\&.0/lib/rt\&.jar \e \fR
+-\fB\-extdirs "" OldCode\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The
+-\fB\-source 1\&.7\fR
+-option specifies that release 1\&.7 (or 7) of the Java programming language be used to compile
+-\fBOldCode\&.java\fR\&. The option
+-\fB\-target 1\&.7\fR
+-option ensures that the generated class files are compatible with JVM 1\&.7\&. Note that in most cases, the value of the
+-\fB\-target\fR
+-option is the value of the
+-\fB\-source\fR
+-option; in this example, you can omit the
+-\fB\-target\fR
+-option\&.
+-.sp
+-You must specify the
+-\fB\-bootclasspath\fR
+-option to specify the correct version of the bootstrap classes (the
+-\fBrt\&.jar\fR
+-library)\&. If not, then the compiler generates a warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-source 1\&.7 OldCode\&.java\fR
+-\fBwarning: [options] bootstrap class path not set in conjunction with \fR
+-\fB\-source 1\&.7\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-If you do not specify the correct version of bootstrap classes, then the compiler uses the old language rules (in this example, it uses version 1\&.7 of the Java programming language) combined with the new bootstrap classes, which can result in class files that do not work on the older platform (in this case, Java SE 7) because reference to nonexistent methods can get included\&.
+-.RE
+-.PP
+-\fBExample 5\fR
+-.br
+-Cross Compile
+-.RS 4
+-This example uses
+-\fBjavac\fR
+-to compile code that runs on JVM 1\&.7\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-source 1\&.7 \-target 1\&.7 \-bootclasspath jdk1\&.7\&.0/lib/rt\&.jar \e\fR
+-\fB \-extdirs "" OldCode\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The\fB \-source 1\&.7\fR
+-option specifies that release 1\&.7 (or 7) of the Java programming language to be used to compile OldCode\&.java\&. The
+-\fB\-target 1\&.7\fR
+-option ensures that the generated class files are compatible with JVM 1\&.7\&. In most cases, the value of the
+-\fB\-target\fR
+-is the value of
+-\fB\-source\fR\&. In this example, the
+-\fB\-target\fR
+-option is omitted\&.
+-.sp
+-You must specify the
+-\fB\-bootclasspath\fR
+-option to specify the correct version of the bootstrap classes (the
+-\fBrt\&.jar\fR
+-library)\&. If not, then the compiler generates a warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-source 1\&.7 OldCode\&.java\fR
+-\fBwarning: [options] bootstrap class path not set in conjunction with \-source 1\&.7\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
++You must specify the \f3-bootclasspath\fR option to specify the correct version of the bootstrap classes (the \f3rt\&.jar\fR library)\&. If not, then the compiler generates a warning:
++.sp
++.nf
++\f3javac \-source 1\&.7 OldCode\&.java\fP
++.fi
++.nf
++\f3warning: [options] bootstrap class path not set in conjunction with \-source 1\&.7\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
+ If you do not specify the correct version of bootstrap classes, then the compiler uses the old language rules combined with the new bootstrap classes\&. This combination can result in class files that do not work on the older platform (in this case, Java SE 7) because reference to nonexistent methods can get included\&. In this example, the compiler uses release 1\&.7 of the Java programming language\&.
+-.RE
+-.SH "SEE ALSO"
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.SH SEE\ ALSO
++.TP 0.2i
++\(bu
+ java(1)
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.TP 0.2i
++\(bu
+ jdb(1)
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.TP 0.2i
++\(bu
+ javah(1)
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.TP 0.2i
++\(bu
+ javadoc(1)
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.TP 0.2i
++\(bu
+ jar(1)
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.TP 0.2i
++\(bu
+ jdb(1)
+-.RE
+-.br
+-'pl 8.5i
+-'bp
++.RE
++.br
++'pl 8.5i
++'bp
+--- ./jdk/src/bsd/doc/man/javadoc.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/bsd/doc/man/javadoc.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ '\" t
+-.\" Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
++.\" Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
+ .\"
+ .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ .\"
+@@ -23,12 +23,12 @@
+ .\"
+ .\" Arch: generic
+ .\" Software: JDK 8
+-.\" Date: 10 May 2011
++.\" Date: 03 March 2015
+ .\" SectDesc: Basic Tools
+ .\" Title: javadoc.1
+ .\"
+ .if n .pl 99999
+-.TH javadoc 1 "10 May 2011" "JDK 8" "Basic Tools"
++.TH javadoc 1 "03 March 2015" "JDK 8" "Basic Tools"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -209,7 +209,7 @@
+ \f3package java\&.lang\&.applet;\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -251,7 +251,7 @@
+ \f3initialize, start, and stop the applet\&. \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3@since 1\&.0 \fP
+@@ -266,7 +266,7 @@
+ \f3</HTML>\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The \f3package\&.html\fR file is a typical HTML file and does not include a package declaration\&. The content of the package comment file is written in HTML with one exception\&. The documentation comment should not include the comment separators \f3/**\fR and \f3*/\fR or leading asterisks\&. When writing the comment, make the first sentence a summary about the package, and do not put a title or any other text between the \f3<body>\fR tag and the first sentence\&. You can include package tags\&. All block tags must appear after the main description\&. If you add an \f3@see\fR tag in a package comment file, then it must have a fully qualified name\&.
+@@ -334,7 +334,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SS TEST\ AND\ TEMPLATE\ FILES
+@@ -350,7 +350,7 @@
+ \f3com/package1/test\-files/\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ If your test files contain documentation comments, then you can set up a separate run of the \f3javadoc\fR command to produce test file documentation by passing in their test source file names with wild cards, such as \f3com/package1/test-files/*\&.java\fR\&.
+@@ -560,7 +560,7 @@
+ \f3implements Serializable\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The declaration for the \f3Boolean\&.valueOf\fR method is:
+@@ -569,7 +569,7 @@
+ \f3public static Boolean valueOf(String s)\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The \f3javadoc\fR command can include the modifiers \f3public\fR, \f3protected\fR, \f3private\fR, \f3abstract\fR, \f3final\fR, \f3static\fR, \f3transient\fR, and \f3volatile\fR, but not \f3synchronized\fR or \f3native\fR\&. The \f3synchronized\fR and \f3native\fR modifiers are considered implementation detail and not part of the API specification\&.
+@@ -593,7 +593,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ To save space you can put a comment on one line:
+@@ -602,7 +602,7 @@
+ \f3/** This comment takes up only one line\&. */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -623,19 +623,19 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3import com\&.example; // MISTAKE \- Important not to put import statement here\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3public class Whatever{ }\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -657,7 +657,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -676,7 +676,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -700,7 +700,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -730,7 +730,7 @@
+ \f3public int x, y; // Avoid this \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The \f3javadoc\fR command generates the following documentation from the previous code:
+@@ -739,7 +739,7 @@
+ \f3public int x\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The horizontal and vertical distances of point (x, y)\&.
+@@ -748,7 +748,7 @@
+ \f3public int y\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The horizontal and vertical distances of point (x, y)\&.
+@@ -872,7 +872,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -899,11 +899,10 @@
+ .TP 0.2i
+ \(bu
+ In the text arguments of the \f3@return\fR, \f3@param,\fR and \f3@throws\fR tags of a method\&. In this case, the tag text is copied from the corresponding tag up the hierarchy\&.
+-.RE
+-.RS
++.RE
++
++
+ See Method Comment Inheritance for a description of how comments are found in the inheritance hierarchy\&. Note that if this tag is missing, then the comment is or is not automatically inherited according to rules described in that section\&.
+-
+-.RE
+ .TP
+ {@link \fIpackage\&.class#member label\fR}
+ Introduced in JDK 1\&.2
+@@ -920,7 +919,7 @@
+ \f3Use the {@link #getComponentAt(int, int) getComponentAt} method\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -931,7 +930,7 @@
+ \f3Use the <a href="Component\&.html#getComponentAt(int, int)">getComponentAt</a> method\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -942,7 +941,7 @@
+ \f3Use the getComponentAt method\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -982,7 +981,7 @@
+ \f3}\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1014,7 +1013,7 @@
+ \f3}\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1071,7 +1070,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1091,7 +1090,7 @@
+ \f3</dl>\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1128,7 +1127,7 @@
+ \f3@see #constructor(Type argname, Type argname,\&.\&.\&.) \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3\fIReferencing another class in the current or imported packages\fR\fP
+@@ -1155,7 +1154,7 @@
+ \f3@see Class \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3\fIReferencing an element in another package (fully qualified)\fR\fP
+@@ -1185,7 +1184,7 @@
+ \f3@see package\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3\fRNotes about the previous listing:
+@@ -1215,7 +1214,7 @@
+ Any enclosing classes and interfaces searching the closest first\&.
+ .TP 0.4i
+ 3\&.
+-Any superclasses and superonterfaces, searching the closest first\&.
++Any superclasses and superinterfaces, searching the closest first\&.
+ .TP 0.4i
+ 4\&.
+ The current package\&.
+@@ -1307,7 +1306,7 @@
+ \f3@see "The Java Programming Language" // "The Java Programming Language" \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \fINote:\fR You can extend the \f3@se\fR\f3e\fR tag to link to classes not being documented with the \f3-link\fR option\&.
+@@ -1317,7 +1316,7 @@
+
+ Used in the documentation comment for a default serializable field\&. See Documenting Serializable Fields and Data for a Class at http://docs\&.oracle\&.com/javase/8/docs/platform/serialization/spec/serial-arch\&.html#5251
+
+-See also Oracle\(cqs Criteria for Including Classes in the Serialilzed Form Specification at http://www\&.oracle\&.com/technetwork/java/javase/documentation/serialized-criteria-137781\&.html
++See also Oracle\(cqs Criteria for Including Classes in the Serialized Form Specification at http://www\&.oracle\&.com/technetwork/java/javase/documentation/serialized-criteria-137781\&.html
+
+ An optional \f3field-description\fR should explain the meaning of the field and list the acceptable values\&. When needed, the description can span multiple lines\&. The standard doclet adds this information to the serialized form page\&. See Cross-Reference Pages\&.
+
+@@ -1331,13 +1330,12 @@
+ .TP 0.2i
+ \(bu
+ A private or package-private class that implements \f3Serializable\fR is excluded unless that class (or its package) is marked with the \f3@serial include\fR tag\&.
+-.RE
+-.RS
++.RE
++
++
+ For example, the \f3javax\&.swing\fR package is marked with the \f3@serial\fR\f3exclude\fR tag in package\&.html or package-info\&.java\&. The public class \f3java\&.security\&.BasicPermission\fR is marked with the \f3@serial exclude\fR tag\&. The package-private class \f3java\&.util\&.PropertyPermissionCollection\fR is marked with the \f3@serial include\fR tag\&.
+
+ The \f3@serial\fR tag at the class level overrides the \f3@serial\fR tag at the package level\&.
+-
+-.RE
+ .TP
+ @serialData \fIdata-description\fR
+ Introduced in JDK 1\&.2
+@@ -1387,7 +1385,7 @@
+ \f3public static final String SCRIPT_START = "<script>"\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1407,7 +1405,7 @@
+ \f3public String evalScript(String script) {}\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1494,7 +1492,7 @@
+ \f3}\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SS FIELD\ TAGS
+@@ -1523,7 +1521,7 @@
+ \f3 int x = 1263732;\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SS CONSTRUCTOR\ AND\ METHOD\ TAGS
+@@ -1578,7 +1576,7 @@
+ \f3 }\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SH OPTIONS
+@@ -1592,7 +1590,7 @@
+ .PP
+ The options are:
+ .PP
+--1\&.1 || -author || -bootclasspath classpathlist || -bottom text || -breakiterator || -charset name || -classpath classpathlist || -d directory || -docencoding name || -docfilesubdirs || -doclet class || -docletpath classpathlist || -doctitle title || -encoding || -exclude packagename1:packagename2:\&.\&.\&. || -excludedocfilessubdir name1:name2 || -extdirs dirist || -footer footer || -group groupheading packagepattern:packagepattern || -header header || -help || -helpfile path\efilename || -Jflag || -keywords || -link extdocURL || -linkoffline extdocURL packagelistLoc || -linksource || -locale language_country_variant || -nocomment || -nodeprecated || -nodeprecatedlist || -nohelp || -noindex || -nonavbar || -noqualifier all | packagename1:packagename2\&.\&.\&. || -nosince || -notimestamp || -notree || -overview path/filename || -package || -private || -protected || -public || -quiet || -serialwarn || -source release || -sourcepath sourcepathlist || -sourcetab tablength || -splitindex || -stylesheet path/filename || -subpackages package1:package2:\&.\&.\&. || -tag tagname:Xaoptcmf:"taghead" || -taglet class || -tagletpath tagletpathlist || -title title || -top || -use || -verbose || -version || -windowtitle title
++-1\&.1 || -author || -bootclasspath classpathlist || -bottom text || -breakiterator || -charset name || -classpath classpathlist || -d directory || -docencoding name || -docfilesubdirs || -doclet class || -docletpath classpathlist || -doctitle title || -encoding || -exclude packagename1:packagename2:\&.\&.\&. || -excludedocfilessubdir name1:name2 || -extdirs dirist || -footer footer || -group groupheading packagepattern:packagepattern || -header header || -help || -helpfile path\efilename || -Jflag || -javafx ||-keywords || -link extdocURL || -linkoffline extdocURL packagelistLoc || -linksource || -locale language_country_variant || -nocomment || -nodeprecated || -nodeprecatedlist || -nohelp || -noindex || -nonavbar || -noqualifier all | packagename1:packagename2\&.\&.\&. || -nosince || -notimestamp || -notree || -overview path/filename || -package || -private || -protected || -public || -quiet || -serialwarn || -source release || -sourcepath sourcepathlist || -sourcetab tablength || -splitindex || -stylesheet path/filename || -subpackages package1:package2:\&.\&.\&. || -tag tagname:Xaoptcmf:"taghead" || -taglet class || -tagletpath tagletpathlist || -title title || -top || -use || -verbose || -version || -windowtitle title
+ .PP
+ The following options are the core Javadoc options that are available to all doclets\&. The standard doclet provides the rest of the doclets: \f3-bootclasspath\fR, \f3-breakiterator\fR, \f3-classpath\fR, \f3-doclet\fR, \f3-docletpath\fR, \f3-encoding\fR, -\f3exclude\fR, \f3-extdirs\fR, \f3-help\fR, \f3-locale\fR, \f3-\fR\f3overview\fR, \f3-package\fR, \f3-private\fR, \f3-protected\fR, \f3-public\fR, \f3-quiet\fR, \f3-source\fR, \f3-sourcepath\fR, \f3-subpackages\fR, and \f3-verbose\fR\&.
+ .SS JAVADOC\ OPTIONS
+@@ -1635,12 +1633,11 @@
+ .TP 0.2i
+ \(bu
+ \f3-Xdoclint all,\fR\fI-group\fR : enable all except \fIgroup\fR checks
+-.RE
+-.RS
++.RE
++
++
+ The variable \fIgroup\fR has one of the following values:
+ .RS
+-
+-.RE
+ .TP 0.2i
+ \(bu
+ \f3accessibility\fR : Checks for the issues to be detected by an accessibility checker (for example, no caption or summary attributes specified in a \f3<table>\fR tag)\&.
+@@ -1656,8 +1653,9 @@
+ .TP 0.2i
+ \(bu
+ \f3syntax\fR : Checks for low level issues like unescaped angle brackets (\f3<\fR and \f3>\fR) and ampersands (\f3&\fR) and invalid Javadoc tags\&.
+-.RE
+-.RS
++.RE
++
++
+ You can specify the \f3-Xdoclint\fR option multiple times to enable the option to check errors and warnings in multiple categories\&. Alternatively, you can specify multiple error and warning categories by using the preceding options\&. For example, use either of the following commands to check for the HTML, syntax, and accessibility issues in the file \fIfilename\fR\&.
+ .sp
+ .nf
+@@ -1667,7 +1665,7 @@
+ \f3javadoc \-Xdoclint:html,syntax,accessibility \fIfilename\fR\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1675,8 +1673,6 @@
+ \fINote:\fR The \f3javadoc\fR command does not guarantee the completeness of these checks\&. In particular, it is not a full HTML compliance checker\&. The goal of the -\f3Xdoclint\fR option is to enable the \f3javadoc\fR command to report majority of common errors\&.
+
+ The \f3javadoc\fR command does not attempt to fix invalid input, it just reports it\&.
+-
+-.RE
+ .TP
+ -public
+ .br
+@@ -1740,7 +1736,7 @@
+ \f3javadoc \-sourcepath /home/user/src/ com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1755,7 +1751,7 @@
+ \f3javadoc \-sourcepath /home/user1/src:/home/user2/src com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1766,13 +1762,13 @@
+
+ If you omit \f3-sourcepath\fR, then the \f3javadoc\fR command uses \f3-classpath\fR to find the source files and class files (for backward compatibility)\&. If you want to search for source and class files in separate paths, then use both \f3-sourcepath\fR and \f3-classpath\fR\&.
+
+-For example, if you want to document \f3com\&.mypackage\fR, whose source files reside in the directory /home/user/src/com/mypackage, and if this package relies on a library in /home/user/libthen you would use the following command:
++For example, if you want to document \f3com\&.mypackage\fR, whose source files reside in the directory /home/user/src/com/mypackage, and if this package relies on a library in /home/user/lib, then you would use the following command:
+ .sp
+ .nf
+ \f3javadoc \-sourcepath /home/user/lib \-classpath /home/user/src com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1795,7 +1791,7 @@
+ \f3javadoc \-d docs \-sourcepath /home/user/src \-subpackages java:javax\&.swing \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1813,7 +1809,7 @@
+ \f3 java\&.net:java\&.lang\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1846,11 +1842,10 @@
+ .TP 0.2i
+ \(bu
+ Breakiterator sentence-break algorithm\&. Stops at a period, question mark, or exclamation point followed by a space when the next word starts with a capital letter\&. This is meant to handle most abbreviations (such as "The serial no\&. is valid", but will not handle "Mr\&. Smith")\&. The \f3-breakiterator\fR option does not stop at HTML tags or sentences that begin with numbers or symbols\&. The algorithm stops at the last period in \&.\&./filename, even when embedded in an HTML tag\&.
+-.RE
+-.RS
++.RE
++
++
+ In Java SE 1\&.5 the \f3-breakiterator\fR option warning messages are removed, and the default sentence-break algorithm is unchanged\&. If you have not modified your source code to eliminate the \f3-breakiterator\fR option warnings in Java SE 1\&.4\&.x, then you do not have to do anything\&. The warnings go away starting with Java SE 1\&.5\&.0\&.
+-
+-.RE
+ .TP
+ -locale \fIlanguage_country_variant\fR
+ .br
+@@ -1885,7 +1880,21 @@
+ \f3Java HotSpot(TM) 64\-Bit Server VM (build 23\&.5\-b02, mixed mode)\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
++.fi
++.sp
++
++.TP
++-javafx
++.br
++Generates HTML documentation using the JavaFX extensions to the standard doclet\&. The generated documentation includes a Property Summary section in addition to the other summary sections generated by the standard Java doclet\&. The listed properties are linked to the sections for the getter and setter methods of each property\&.
++
++If there are no documentation comments written explicitly for getter and setter methods, the documentation comments from the property method are automatically copied to the generated documentation for these methods\&. This option also adds a new \f3@defaultValue\fR tag that allows documenting the default value for a property\&.
++
++Example:
++.sp
++.nf
++\f3javadoc \-javafx MyClass\&.java \-d testdir\fP
+ .fi
+ .sp
+
+@@ -1957,7 +1966,7 @@
+ \f3\-link <directory>/<directory>/\&.\&.\&./<name>\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1982,7 +1991,7 @@
+ \f3javadoc \-link http://docs\&.oracle\&.com/javase/8/docs/api/ com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The command generates documentation for the package \f3com\&.mypackage\fR with links to the Java SE packages\&. The generated documentation contains links to the \f3Object\fR class, for example, in the class \f3trees\fR\&. Other options, such as the \f3-sourcepath\fR and \f3-d\fR options, are not shown\&.
+@@ -2044,7 +2053,7 @@
+ \f3and so on \&.\&.\&.\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ When \f3javadoc\fR is run without the \f3-link\fR option and encounters a name that belongs to an externally referenced class, it prints the name with no link\&. However, when the \f3-link\fR option is used, the \f3javadoc\fR command searches the package-list file at the specified \fIextdocURL\fR location for that package name\&. When it finds the package name, it prefixes the name with \fIextdocURL\fR\&.
+@@ -2094,7 +2103,7 @@
+ \f3javadoc \-linkoffline http://docs\&.oracle\&.com/javase/8/docs/api/ \&. com\&.mypackage \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2118,7 +2127,7 @@
+ \f3packagelistLoc2 \&.\&.\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2133,7 +2142,7 @@
+ \f3javadoc \-d update \-linkoffline \&. html com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ When the \f3javadoc\fR command completes, copy these generated class pages in update/com/package (not the overview or index) to the original files in html/com/package\&.
+@@ -2150,7 +2159,7 @@
+ \f3public class Button extends Component implements Accessible\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2161,7 +2170,7 @@
+ \f3public String getLabel()\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2176,8 +2185,9 @@
+ .TP 0.2i
+ \(bu
+ The \f3packagepattern\fR value can be any package name at the start of any package name followed by an asterisk (*)\&. The asterisk is the only wildcard allowed and means match any characters\&. Multiple patterns can be included in a group by separating them with colons (:)\&. If you use an asterisk in a pattern or pattern list, then the pattern list must be inside quotation marks, such as \f3"java\&.lang*:java\&.util"\fR\&.
+-.RE
+-.RS
++.RE
++
++
+ When you do not supply a \f3-group\fR option, all packages are placed in one group with the heading \fIPackages\fR and appropriate subheadings\&. If the subheadings do not include all documented packages (all groups), then the remaining packages appear in a separate group with the subheading Other Packages\&.
+
+ For example, the following \f3javadoc\fR command separates the three documented packages into \fICore\fR, \fIExtension\fR, and \fIOther Packages\fR\&. The trailing dot (\&.) does not appear in \f3java\&.lang*\fR\&. Including the dot, such as \f3java\&.lang\&.*\fR omits the\f3java\&.lang\fR package\&.
+@@ -2192,7 +2202,7 @@
+ \f3 java\&.lang java\&.lang\&.reflect java\&.util javax\&.servlet java\&.new\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2212,8 +2222,6 @@
+ \fIOther Packages\fR
+
+ \f3java\&.new\fR
+-
+-.RE
+ .TP
+ -nodeprecated
+ .br
+@@ -2251,7 +2259,7 @@
+ \f3javadoc \-helpfile /home/user/myhelp\&.html java\&.awt\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2264,7 +2272,7 @@
+ \f3javadoc \-stylesheet file /home/user/mystylesheet\&.css com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2283,7 +2291,7 @@
+ \f3<META http\-equiv="Content\-Type" content="text/html; charset=ISO\-8859\-1">\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2296,7 +2304,7 @@
+ .br
+ Specifies the encoding of the generated HTML files\&. The name should be a preferred MIME name as specified in the IANA Registry, Character Sets at http://www\&.iana\&.org/assignments/character-sets
+
+-If you omit the \f3-docencoding\fR option but use the \f3-encoding\fR option, then the encoding of the generated HTML files is determined by the \f3-encoding\fR option, for example: \f3javadoc -docencoding"iso-8859-1" mypackage\fR\&. See also the \f3-encoding\fR and \f3-docencoding name\fR options\&.
++If you omit the \f3-docencoding\fR option but use the \f3-encoding\fR option, then the encoding of the generated HTML files is determined by the \f3-encoding\fR option, for example: \f3javadoc -docencoding "iso-8859-1" mypackage\fR\&. See also the \f3-encoding\fR and \f3-docencoding name\fR options\&.
+ .TP
+ -keywords
+ .br
+@@ -2315,7 +2323,7 @@
+ \f3<META NAME="keywords" CONTENT="charAt()">\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2360,7 +2368,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2390,7 +2398,7 @@
+ \f3\-tag example:X\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2433,7 +2441,7 @@
+ \f3\-tag see\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2523,7 +2531,7 @@
+ \f3\-sourcepath /java/pubs/ws/1\&.7\&.0/src/share/classes\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ Create a file named packages that contains:
+@@ -2538,7 +2546,7 @@
+ \f3com\&.mypackage3\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ Run the \f3javadoc\fR command as follows:
+@@ -2547,7 +2555,7 @@
+ \f3javadoc @options @packages\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 3 Argument Files with Paths\fR
+@@ -2558,7 +2566,7 @@
+ \f3javadoc @path1/options @path2/packages\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 4 Option Arguments\fR
+@@ -2581,7 +2589,7 @@
+ \f3 Other names may be trademarks of their respective owners\&.</font>\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ Run the \f3javadoc\fR command as follows:\f3javadoc -bottom @bottom @packages\fR\&.
+@@ -2616,7 +2624,7 @@
+ \f3javadoc \-d /home/html \-sourcepath /home/src \-subpackages java \-exclude\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 2 Change to Root and Run Explicit Packages\fR
+@@ -2630,7 +2638,7 @@
+ \f3javadoc \-d /home/html java\&.awt java\&.awt\&.event\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ To also traverse down other package trees, append their names to the \f3-subpackages\fR argument, such as j\f3ava:javax:org\&.xml\&.sax\fR\&.
+@@ -2643,7 +2651,7 @@
+ \f3javadoc \-d /home/html \-sourcepath /home/src java\&.awt java\&.awt\&.event\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 4 Run from Any Directory on Explicit Packages in Multiple Trees\fR
+@@ -2654,7 +2662,7 @@
+ \f3javadoc \-d /home/html \-sourcepath /home/src1:/home/src2 java\&.awt java\&.awt\&.event\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The result is that all cases generate HTML-formatted documentation for the \f3public\fR and \f3protected\fR classes and interfaces in packages j\f3ava\&.awt\fR and \f3java\&.awt\&.even\fRt and save the HTML files in the specified destination directory\&. Because two or more packages are being generated, the document has three HTML frames: one for the list of packages, another for the list of classes, and the third for the main class pages\&.
+@@ -2676,7 +2684,7 @@
+ \f3javadoc \-d /home/html Button\&.java Canvas\&.java Graphics*\&.java\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 2 Change to the Root Directory of the Package\fR
+@@ -2690,7 +2698,7 @@
+ \f3javadoc \-d /home/html java/awt/Button\&.java java/applet/Applet\&.java\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 3 Document Files from Any Directory\fR
+@@ -2704,7 +2712,7 @@
+ \f3/home/src/java/awt/Graphics*\&.java\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2720,7 +2728,7 @@
+ \f3/home/src/java/applet/Applet\&.java\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SS REAL-WORLD\ EXAMPLES
+@@ -2784,7 +2792,7 @@
+ \f3@packages\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2802,7 +2810,7 @@
+ \f3import javax\&.tools\&.ToolProvider;\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3public class JavaAccessSample{\fP
+@@ -2838,7 +2846,7 @@
+ \f3 }\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The first three arguments of the \f3run\fR method specify input, standard output, and standard error streams\&. \f3Null\fR is the default value for \f3System\&.in\fR, \f3System\&.out\fR, and \f3System\&.err\fR, respectively\&.
+@@ -2891,7 +2899,7 @@
+ \f3 java\&.applet\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3WINDOWTITLE = \&'Java\(tm SE 7 API Specification\&'\fP
+@@ -2927,7 +2935,7 @@
+ \f3SRCDIR = \&'/java/jdk/1\&.7\&.0/src/share/classes\&'\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SS NOTES
+--- ./jdk/src/bsd/doc/man/jcmd.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/bsd/doc/man/jcmd.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,114 +1,211 @@
+ '\" t
+-.\" Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+-.\"
+-.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-.\"
+-.\" This code is free software; you can redistribute it and/or modify it
+-.\" under the terms of the GNU General Public License version 2 only, as
+-.\" published by the Free Software Foundation.
+-.\"
+-.\" This code is distributed in the hope that it will be useful, but WITHOUT
+-.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-.\" version 2 for more details (a copy is included in the LICENSE file that
+-.\" accompanied this code).
+-.\"
+-.\" You should have received a copy of the GNU General Public License version
+-.\" 2 along with this work; if not, write to the Free Software Foundation,
+-.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-.\"
+-.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-.\" or visit www.oracle.com if you need additional information or have any
+-.\" questions.
+-.\"
+-.\" Arch: generic
+-.\" Software: JDK 8
+-.\" Date: 21 November 2013
+-.\" SectDesc: Troubleshooting Tools
+-.\" Title: jcmd.1
++.\" Copyright (c) 2012, 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.
++.\"
++.\" Title: jcmd
++.\" Language: English
++.\" Date: 03 March 2015
++.\" SectDesc: Troubleshooting Tools
++.\" Software: JDK 8
++.\" Arch: generic
++.\" Part Number: E38207-04
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH jcmd 1 "21 November 2013" "JDK 8" "Troubleshooting Tools"
+-.\" -----------------------------------------------------------------
+-.\" * Define some portability stuff
+-.\" -----------------------------------------------------------------
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.\" http://bugs.debian.org/507673
+-.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.ie \n(.g .ds Aq \(aq
+-.el .ds Aq '
+-.\" -----------------------------------------------------------------
+-.\" * set default formatting
+-.\" -----------------------------------------------------------------
+-.\" disable hyphenation
+-.nh
+-.\" disable justification (adjust text to left margin only)
+-.ad l
+-.\" -----------------------------------------------------------------
+-.\" * MAIN CONTENT STARTS HERE *
+-.\" -----------------------------------------------------------------
+-
+-.SH NAME
++.TH "jcmd" "1" "03 March 2015" "JDK 8" "Troubleshooting Tools"
++.\" -----------------------------------------------------------------
++.\" * Define some portability stuff
++.\" -----------------------------------------------------------------
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.\" http://bugs.debian.org/507673
++.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.ie \n(.g .ds Aq \(aq
++.el .ds Aq '
++.\" -----------------------------------------------------------------
++.\" * set default formatting
++.\" -----------------------------------------------------------------
++.\" disable hyphenation
++.nh
++.\" disable justification (adjust text to left margin only)
++.ad l
++.\" -----------------------------------------------------------------
++.\" * MAIN CONTENT STARTS HERE *
++.\" -----------------------------------------------------------------
++.SH "NAME"
+ jcmd \- Sends diagnostic command requests to a running Java Virtual Machine (JVM)\&.
+-.SH SYNOPSIS
+-.sp
+-.nf
+-
++.SH "SYNOPSIS"
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
+ \fBjcmd\fR [\fB\-l\fR|\fB\-h\fR|\fB\-help\fR]
+-.fi
+-.nf
+-
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
+ \fBjcmd\fR \fIpid\fR|\fImain\-class\fR \fBPerfCounter\&.print\fR
+-.fi
+-.nf
+-
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
+ \fBjcmd\fR \fIpid\fR|\fImain\-class\fR \fB\-f\fR \fIfilename\fR
+-.fi
+-.nf
+-
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
+ \fBjcmd\fR \fIpid\fR|\fImain\-class\fR \fIcommand\fR[ \fIarguments\fR]
+-.fi
+-.sp
+-.SH DESCRIPTION
+-The \f3jcmd\fR utility is used to send diagnostic command requests to the JVM\&. It must be used on the same machine on which the JVM is running, and have the same effective user and group identifiers that were used to launch the JVM\&.
++.fi
++.if n \{\
++.RE
++.\}
++.SH "DESCRIPTION"
+ .PP
+-\fINote:\fR To invoke diagnostic commands from a remote machine or with different identiers, you can use the \f3com\&.sun\&.management\&.DiagnosticCommandMBean\fR interface\&. For more information about the \f3DiagnosticCommandMBean\fR interface, see the API documentation at http://download\&.java\&.net/jdk8/docs/jre/api/management/extension/com/sun/management/DiagnosticCommandMBean\&.html
++The
++\fBjcmd\fR
++utility is used to send diagnostic command requests to the JVM\&. It must be used on the same machine on which the JVM is running, and have the same effective user and group identifiers that were used to launch the JVM\&.
++.if n \{\
++.sp
++.\}
++.RS 4
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBNote\fR
++.ps -1
++.br
++.TS
++allbox tab(:);
++l.
++T{
+ .PP
+-If you run \f3jcmd\fR without arguments or with the \f3-l\fR option, it prints the list of running Java process identifiers with the main class and command-line arguments that were used to launch the process\&. Running \f3jcmd\fR with the \f3-h\fR or \f3-help\fR option prints the tool\(cqs help message\&.
++To invoke diagnostic commands from a remote machine or with different identifiers, you can use the
++\fBcom\&.sun\&.management\&.DiagnosticCommandMBean\fR
++interface\&. For more information about the
++\fBDiagnosticCommandMBean\fR
++interface, see the API documentation at http://docs\&.oracle\&.com/javase/8/docs/jre/api/management/extension/com/sun/management/DiagnosticCommandMBean\&.html
++T}
++.TE
++.sp 1
++.sp .5v
++.RE
+ .PP
+-If you specify the processes identifier (\fIpid\fR) or the main class (\fImain-class\fR) as the first argument, \f3jcmd\fR sends the diagnostic command request to the Java process with the specified identifier or to all Java processes with the specified name of the main class\&. You can also send the diagnostic command request to all available Java processes by specifying \f30\fR as the process identifier\&. Use one of the following as the diagnostic command request:
+-.TP
++If you run
++\fBjcmd\fR
++without arguments or with the
++\fB\-l\fR
++option, it prints the list of running Java process identifiers with the main class and command\-line arguments that were used to launch the process\&. Running
++\fBjcmd\fR
++with the
++\fB\-h\fR
++or
++\fB\-help\fR
++option prints the tool\(cqs help message\&.
++.PP
++If you specify the processes identifier (\fIpid\fR) or the main class (\fImain\-class\fR) as the first argument,
++\fBjcmd\fR
++sends the diagnostic command request to the Java process with the specified identifier or to all Java processes with the specified name of the main class\&. You can also send the diagnostic command request to all available Java processes by specifying
++\fB0\fR
++as the process identifier\&. Use one of the following as the diagnostic command request:
++.PP
+ Perfcounter\&.print
++.RS 4
+ Prints the performance counters available for the specified Java process\&. The list of performance counters might vary with the Java process\&.
+-.TP
+--f \fIfilename\fR
++.RE
++.PP
++\-f \fIfilename\fR
++.RS 4
++The name of the file from which to read diagnostic commands and send them to the specified Java process\&. Used only with the
++\fB\-f\fR
++option\&. Each command in the file must be written on a single line\&. Lines starting with a number sign (\fB#\fR) are ignored\&. Processing of the file ends when all lines have been read or when a line containing the
++\fBstop\fR
++keyword is read\&.
++.RE
++.PP
++\fIcommand\fR [\fIarguments\fR]
++.RS 4
++The command to be sent to the specified Java process\&. The list of available diagnostic commands for a given process can be obtained by sending the
++\fBhelp\fR
++command to this process\&. Each diagnostic command has its own set of arguments\&. To see the description, syntax, and a list of available arguments for a command, use the name of the command as the argument for the
++\fBhelp\fR
++command\&.
++.sp
++\fBNote:\fR
++If any arguments contain spaces, you must surround them with single or double quotation marks (\fB\*(Aq\fR
++or
++\fB"\fR)\&. In addition, you must escape single or double quotation marks with a backslash (\fB\e\fR) to prevent the operating system shell from processing quotation marks\&. Alternatively, you can surround these arguments with single quotation marks and then with double quotation marks (or with double quotation marks and then with single quotation marks)\&.
++.RE
++.SH "OPTIONS"
++.PP
++Options are mutually exclusive\&.
++.PP
++\-f \fIfilename\fR
++.RS 4
++Reads commands from the specified file\&. This option can be used only if you specify the process identifier or the main class as the first argument\&. Each command in the file must be written on a single line\&. Lines starting with a number sign (\fB#\fR) are ignored\&. Processing of the file ends when all lines have been read or when a line containing the
++\fBstop\fR
++keyword is read\&.
++.RE
++.PP
++\-h
+ .br
+-The name of the file from which to read diagnostic commands and send them to the specified Java process\&. Used only with the \f3-f\fR option\&. Each command in the file must be written on a single line\&. Lines starting with a number sign (\f3#\fR) are ignored\&. Processing of the file ends when all lines have been read or when a line containing the \f3stop\fR keyword is read\&.
+-.TP
+-\fIcommand\fR [\fIarguments\fR]
+-The command to be sent to the specified Java process\&. The list of available diagnostic commands for a given process can be obtained by sending the \f3help\fR command to this process\&. Each diagnostic command has its own set of arguments\&. To see the description, syntax, and a list of available arguments for a command, use the name of the command as the argument for the \f3help\fR command\&.
+-
+-\fINote:\fR If any arguments contain spaces, you must surround them with single or double quotation marks (\f3\&'\fR or \f3"\fR)\&. In addition, you must escape single or double quotation marks with a backslash (\f3\e\fR) to prevent the operating system shell from processing quotation marks\&. Alternatively, you can surround these arguments with single quotation marks and then with double quotation marks (or with double quotation marks and then with single quotation marks)\&.
+-.SH OPTIONS
+-Options are mutually exclusive\&.
+-.TP
+--f \fIfilename\fR
++\-help
++.RS 4
++Prints a help message\&.
++.RE
++.PP
++\-l
++.RS 4
++Prints the list of running Java processes identifiers with the main class and command\-line arguments\&.
++.RE
++.SH "SEE ALSO"
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++jps(1)
++.RE
+ .br
+-Reads commands from the specified file\&. This option can be used only if you specify the process identifier or the main class as the first argument\&. Each command in the file must be written on a single line\&. Lines starting with a number sign (\f3#\fR) are ignored\&. Processing of the file ends when all lines have been read or when a line containing the \f3stop\fR keyword is read\&.
+-.TP
+--h, -help
+-.br
+-Prints a help message\&.
+-.TP
+--l
+-.br
+-Prints the list of running Java processes identifiers with the main class and command-line arguments\&.
+-.SH SEE\ ALSO
+-.TP 0.2i
+-\(bu
+-jps(1)
+-.RE
+-.br
+-'pl 8.5i
+-'bp
++'pl 8.5i
++'bp
+--- ./jdk/src/bsd/doc/man/jjs.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/bsd/doc/man/jjs.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,352 +1,248 @@
+ '\" t
+-.\" Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+-.\"
+-.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-.\"
+-.\" This code is free software; you can redistribute it and/or modify it
+-.\" under the terms of the GNU General Public License version 2 only, as
+-.\" published by the Free Software Foundation.
+-.\"
+-.\" This code is distributed in the hope that it will be useful, but WITHOUT
+-.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-.\" version 2 for more details (a copy is included in the LICENSE file that
+-.\" accompanied this code).
+-.\"
+-.\" You should have received a copy of the GNU General Public License version
+-.\" 2 along with this work; if not, write to the Free Software Foundation,
+-.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-.\"
+-.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-.\" or visit www.oracle.com if you need additional information or have any
+-.\" questions.
+-.\"
+-.\" Arch: generic
+-.\" Software: JDK 8
+-.\" Date: 21 November 2013
+-.\" SectDesc: Basic Tools
+-.\" Title: jjs.1
++.\" Copyright (c) 1994, 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.
++.\"
++.\" Title: jjs
++.\" Language: English
++.\" Date: 03 March 2015
++.\" SectDesc: Basic Tools
++.\" Software: JDK 8
++.\" Arch: generic
++.\" Part Number: E38207-04
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH jjs 1 "21 November 2013" "JDK 8" "Basic Tools"
+-.\" -----------------------------------------------------------------
+-.\" * Define some portability stuff
+-.\" -----------------------------------------------------------------
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.\" http://bugs.debian.org/507673
+-.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.ie \n(.g .ds Aq \(aq
+-.el .ds Aq '
+-.\" -----------------------------------------------------------------
+-.\" * set default formatting
+-.\" -----------------------------------------------------------------
+-.\" disable hyphenation
+-.nh
+-.\" disable justification (adjust text to left margin only)
+-.ad l
+-.\" -----------------------------------------------------------------
+-.\" * MAIN CONTENT STARTS HERE *
+-.\" -----------------------------------------------------------------
+-
+-.SH NAME
++.TH "jjs" "1" "03 March 2015" "JDK 8" "Basic Tools"
++.\" -----------------------------------------------------------------
++.\" * Define some portability stuff
++.\" -----------------------------------------------------------------
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.\" http://bugs.debian.org/507673
++.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.ie \n(.g .ds Aq \(aq
++.el .ds Aq '
++.\" -----------------------------------------------------------------
++.\" * set default formatting
++.\" -----------------------------------------------------------------
++.\" disable hyphenation
++.nh
++.\" disable justification (adjust text to left margin only)
++.ad l
++.\" -----------------------------------------------------------------
++.\" * MAIN CONTENT STARTS HERE *
++.\" -----------------------------------------------------------------
++.SH "NAME"
+ jjs \- Invokes the Nashorn engine\&.
+-.SH SYNOPSIS
+-.sp
+-.nf
+-\f3\fBjjs\fR [\fIoptions\fR] [\fIscript\-files\fR] [\-\- \fIarguments\fR]\fP
+-.fi
+-.sp
+-.TP
++.SH "SYNOPSIS"
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB\fBjjs\fR\fR\fB [\fR\fB\fIoptions\fR\fR\fB] [\fR\fB\fIscript\-files\fR\fR\fB] [\-\- \fR\fB\fIarguments\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.PP
+ \fIoptions\fR
+-One or more options of the \f3jjs\fR command, separated by spaces\&. For more information, see Options\&.
+-.TP
+-\fIscript-files\fR
++.RS 4
++One or more options of the
++\fBjjs\fR
++command, separated by spaces\&. For more information, see Options\&.
++.RE
++.PP
++\fIscript\-files\fR
++.RS 4
+ One or more script files which you want to interpret using Nashorn, separated by spaces\&. If no files are specified, an interactive shell is started\&.
+-.TP
++.RE
++.PP
+ \fIarguments\fR
+-All values after the double hyphen marker (\f3--\fR) are passed through to the script or the interactive shell as arguments\&. These values can be accessed by using the \f3arguments\fR property (see )\&.
+-.SH DESCRIPTION
+-The \f3jjs\fR command-line tool is used to invoke the Nashorn engine\&. You can use it to interpret one or several script files, or to run an interactive shell\&.
+-.SH OPTIONS
+-The options of the \f3jjs\fR command control the conditions under which scripts are interpreted by Nashorn\&.
+-.TP
+--ccs=\fIsize\fR , --class-cache-size=\fIsize\fR
++.RS 4
++All values after the double hyphen marker (\fB\-\-\fR) are passed through to the script or the interactive shell as arguments\&. These values can be accessed by using the
++\fBarguments\fR
++property (see Example 3)\&.
++.RE
++.SH "DESCRIPTION"
++.PP
++The
++\fBjjs\fR
++command\-line tool is used to invoke the Nashorn engine\&. You can use it to interpret one or several script files, or to run an interactive shell\&.
++.SH "OPTIONS"
++.PP
++The options of the
++\fBjjs\fR
++command control the conditions under which scripts are interpreted by Nashorn\&.
++.PP
++\-cp \fIpath\fR
+ .br
+-Sets the class cache size (in bytes)\&. Append the letter \f3k\fR or \f3K\fR to indicate kilobytes (KB), \f3m\fR or \f3M\fR to indicate megabytes (MB), \f3g\fR or \f3G\fR to indicate gigabytes (GB)\&. By default, the class cache size is set to 50 bytes\&. The following example shows how to set it to 1024 bytes (1 KB):
+-.sp
+-.nf
+-\f3\-css=100\fP
+-.fi
+-.nf
+-\f3\-css=1k\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-
+-.TP
+--co, --compile-only
++\-classpath \fIpath\fR
++.RS 4
++Specifies the path to the supporting class files To set multiple paths, the option can be repeated, or you can separate each path with a colon (:)\&.
++.RE
++.PP
++\-D\fIname\fR=\fIvalue\fR
++.RS 4
++Sets a system property to be passed to the script by assigning a value to a property name\&. The following example shows how to invoke Nashorn in interactive mode and assign
++\fBmyValue\fR
++to the property named
++\fBmyKey\fR:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB>> \fR\fB\fBjjs \-DmyKey=myValue\fR\fR
++\fBjjs> \fR\fB\fBjava\&.lang\&.System\&.getProperty("myKey")\fR\fR
++\fBmyValue\fR
++\fBjjs>\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++This option can be repeated to set multiple properties\&.
++.RE
++.PP
++\-doe
+ .br
+-Compiles the script without running it\&.
+-.TP
+--cp \fIpath\fR , --classpath \fIpath\fR
++\-\-dump\-on\-error
++.RS 4
++Provides a full stack trace when an error occurs\&. By default, only a brief error message is printed\&.
++.RE
++.PP
++\-fv
+ .br
+-Specifies the path to the supporting class files To set multiple paths, the option can be repeated, or you can separate each path with a colon (:)\&.
+-.TP
+--D\fIname\fR=\fIvalue\fR
++\-\-fullversion
++.RS 4
++Prints the full Nashorn version string\&.
++.RE
++.PP
++\-fx
++.RS 4
++Launches the script as a JavaFX application\&.
++.RE
++.PP
++\-h
+ .br
+-Sets a system property to be passed to the script by assigning a value to a property name\&. The following example shows how to invoke Nashorn in interactive mode and assign \f3myValue\fR to the property named \f3myKey\fR:
+-.sp
+-.nf
+-\f3>> \fIjjs \-DmyKey=myValue\fR\fP
+-.fi
+-.nf
+-\f3jjs> \fIjava\&.lang\&.System\&.getProperty("myKey")\fR\fP
+-.fi
+-.nf
+-\f3myValue\fP
+-.fi
+-.nf
+-\f3jjs>\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-
+-
+-This option can be repeated to set multiple properties\&.
+-.TP
+--d=\fIpath\fR , --dump-debug-dir=\fIpath\fR
++\-help
++.RS 4
++Prints the list of options and their descriptions\&.
++.RE
++.PP
++\-\-language=[es5]
++.RS 4
++Specifies the ECMAScript language version\&. The default version is ES5\&.
++.RE
++.PP
++\-ot
+ .br
+-Specifies the path to the directory where class files are dumped\&.
+-.TP
+---debug-lines
++\-\-optimistic\-types=[true|false]
++.RS 4
++Enables or disables optimistic type assumptions with deoptimizing recompilation\&. Running with optimistic types will yield higher final speed, but may increase warmup time\&.
++.RE
++.PP
++\-scripting
++.RS 4
++Enables shell scripting features\&.
++.RE
++.PP
++\-strict
++.RS 4
++Enables strict mode, which enforces stronger adherence to the standard (ECMAScript Edition 5\&.1), making it easier to detect common coding errors\&.
++.RE
++.PP
++\-t=\fIzone\fR
+ .br
+-Generates a line number table in the class file\&. By default, this option is enabled\&. To disable it, specify \f3--debug-lines=false\fR\&.
+-.TP
+---debug-locals
++\-timezone=\fIzone\fR
++.RS 4
++Sets the specified time zone for script execution\&. It overrides the time zone set in the OS and used by the
++\fBDate\fR
++object\&.
++.RE
++.PP
++\-v
+ .br
+-Generates a local variable table in the class file\&.
+-.TP
+--doe, --dump-on-error
++\-version
++.RS 4
++Prints the Nashorn version string\&.
++.RE
++.SH "EXAMPLES"
++.PP
++\fBExample 1 \fRRunning a Script with Nashorn
++.RS 4
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjjs script\&.js\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.PP
++\fBExample 2 \fRRunning Nashorn in Interactive Mode
++.RS 4
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB>> \fR\fB\fBjjs\fR\fR
++\fBjjs> \fR\fB\fBprintln("Hello, World!")\fR\fR
++\fBHello, World!\fR
++\fBjjs> \fR\fB\fBquit()\fR\fR
++\fB>>\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.PP
++\fBExample 3 \fRPassing Arguments to Nashorn
++.RS 4
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB>> \fR\fB\fBjjs \-\- a b c\fR\fR
++\fBjjs> \fR\fB\fBarguments\&.join(", ")\fR\fR
++\fBa, b, c\fR
++\fBjjs>\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.SH "SEE ALSO"
++.PP
++\fBjrunscript\fR
+ .br
+-Provides a full stack trace when an arror occurs\&. By default, only a brief error message is printed\&.
+-.TP
+---early-lvalue-error
+-.br
+-Reports invalid lvalue expressions as early errors (that is, when the code is parsed)\&. By default, this option is enabled\&. To disable it, specify \f3--early-lvalue-error=false\fR\&. When disabled, invalid lvalue expressions will not be reported until the code is executed\&.
+-.TP
+---empty-statements
+-.br
+-Preserves empty statements in the Java abstract syntax tree\&.
+-.TP
+--fv, --fullversion
+-.br
+-Prints the full Nashorn version string\&.
+-.TP
+---function-statement-error
+-.br
+-Prints an error message when a function declaration is used as a statement\&.
+-.TP
+---function-statement-warning
+-.br
+-Prints a warning message when a function declaration is used as a statement\&.
+-.TP
+--fx
+-.br
+-Launches the script as a JavaFX application\&.
+-.TP
+--h, -help
+-.br
+-Prints the list of options and their descriptions\&.
+-.TP
+--J\fIoption\fR
+-.br
+-Passes the specified \f3java\fR launcher option to the JVM\&. The following example shows how to invoke Nashorn in interactive mode and set the maximum memory used by the JVM to 4 GB:
+-.sp
+-.nf
+-\f3>> \fIjjs \-J\-Xmx4g\fR\fP
+-.fi
+-.nf
+-\f3jjs> \fIjava\&.lang\&.Runtime\&.getRuntime()\&.maxMemory()\fR\fP
+-.fi
+-.nf
+-\f33817799680\fP
+-.fi
+-.nf
+-\f3jjs>\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-
+-
+-This option can be repeated to pass multiple \f3java\fR command options\&.
+-.TP
+---lazy-compilation
+-.br
+-Enables lazy code generation strategies (that is, the entire script is not compiled at once)\&. This option is experimental\&.
+-.TP
+---loader-per-compile
+-.br
+-Creates a new class loader per compile\&. By default, this option is enabled\&. To disable it, specify \f3--loader-per-compile=false\fR\&.
+-.TP
+---log=\fIsubsystem\fR:\fIlevel\fR
+-.br
+-Performs logging at a given level for the specified subsystems\&. You can specify logging levels for multiple subsystems separating them with commas\&. For example:
+-.sp
+-.nf
+-\f3\-\-log=fields:finest,codegen:info\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-
+-.TP
+---package=\fIname\fR
+-.br
+-Specifies the package to which generated class files are added\&.
+-.TP
+---parse-only
+-.br
+-Parses the code without compiling\&.
+-.TP
+---print-ast
+-.br
+-Prints the abstract syntax tree\&.
+-.TP
+---print-code
+-.br
+-Prints bytecode\&.
+-.TP
+---print-lower-ast
+-.br
+-Prints the lowered abstract syntax tree\&.
+-.TP
+---print-lower-parse
+-.br
+-Prints the lowered parse tree\&.
+-.TP
+---print-no-newline
+-.br
+-Forces other \f3--print*\fR options to print the output on one line\&.
+-.TP
+---print-parse
+-.br
+-Prints the parse tree\&.
+-.TP
+---print-symbols
+-.br
+-Prints the symbol table\&.
+-.TP
+--pcs, --profile-callsites
+-.br
+-Dumps callsite profile data\&.
+-.TP
+--scripting
+-.br
+-Enables shell scripting features\&.
+-.TP
+---stderr=\fIfilename\fR|\fIstream\fR|\fItty\fR
+-.br
+-Redirects the standard error stream to the specified file, stream (for example, to \f3stdout\fR), or text terminal\&.
+-.TP
+---stdout=\fIfilename\fR|\fIstream\fR|\fItty\fR
+-.br
+-Redirects the standard output stream to the specified file, stream (for example, to \f3stderr\fR), or text terminal\&.
+-.TP
+--strict
+-.br
+-Enables strict mode, which enforces stronger adherence to the standard (ECMAScript Edition 5\&.1), making it easier to detect common coding errors\&.
+-.TP
+--t=\fIzone\fR , -timezone=\fIzone\fR
+-.br
+-Sets the specified time zone for script execution\&. It overrides the time zone set in the OS and used by the \f3Date\fR object\&.
+-.TP
+--tcs=\fIparameter\fR , --trace-callsites=\fIparameter\fR
+-.br
+-Enables callsite trace mode\&. Possible parameters are the following:
+-.RS
+-.TP
+-miss
+-Trace callsite misses\&.
+-.TP
+-enterexit
+-Trace callsite enter/exit\&.
+-.TP
+-objects
+-Print object properties\&.
+-.RE
+-
+-.TP
+---verify-code
+-.br
+-Verifies bytecode before running\&.
+-.TP
+--v, -version
+-.br
+-Prints the Nashorn version string\&.
+-.TP
+--xhelp
+-.br
+-Prints extended help for command-line options\&.
+-.SH EXAMPLES
+-\f3Example 1 Running a Script with Nashorn\fR
+-.sp
+-.nf
+-\f3jjs script\&.js\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-\f3Example 2 Running Nashorn in Interactive Mode\fR
+-.sp
+-.nf
+-\f3>> \fIjjs\fR\fP
+-.fi
+-.nf
+-\f3jjs> \fIprintln("Hello, World!")\fR\fP
+-.fi
+-.nf
+-\f3Hello, World!\fP
+-.fi
+-.nf
+-\f3jjs> \fIquit()\fR\fP
+-.fi
+-.nf
+-\f3>>\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-\f3Example 3 Passing Arguments to Nashorn\fR
+-.sp
+-.nf
+-\f3>> \fIjjs \-\- a b c\fR\fP
+-.fi
+-.nf
+-\f3jjs> \fIarguments\&.join(", ")\fR\fP
+-.fi
+-.nf
+-\f3a, b, c\fP
+-.fi
+-.nf
+-\f3jjs>\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-.SH SEE\ ALSO
+-\f3jrunscript\fR
+-.RE
+-.br
+-'pl 8.5i
+-'bp
++'pl 8.5i
++'bp
+--- ./jdk/src/bsd/doc/man/jstat.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/bsd/doc/man/jstat.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,568 +1,778 @@
+ '\" t
+-.\" Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+-.\"
+-.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-.\"
+-.\" This code is free software; you can redistribute it and/or modify it
+-.\" under the terms of the GNU General Public License version 2 only, as
+-.\" published by the Free Software Foundation.
+-.\"
+-.\" This code is distributed in the hope that it will be useful, but WITHOUT
+-.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-.\" version 2 for more details (a copy is included in the LICENSE file that
+-.\" accompanied this code).
+-.\"
+-.\" You should have received a copy of the GNU General Public License version
+-.\" 2 along with this work; if not, write to the Free Software Foundation,
+-.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-.\"
+-.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-.\" or visit www.oracle.com if you need additional information or have any
+-.\" questions.
+-.\"
+-.\" Arch: generic
+-.\" Software: JDK 8
+-.\" Date: 10 May 2011
+-.\" SectDesc: Monitoring Tools
+-.\" Title: jstat.1
++.\" Copyright (c) 2004, 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.
++.\"
++.\" Title: jstat
++.\" Language: English
++.\" Date: 03 March 2015
++.\" SectDesc: Monitoring Tools
++.\" Software: JDK 8
++.\" Arch: generic
++.\" Part Number: E38207-04
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH jstat 1 "10 May 2011" "JDK 8" "Monitoring Tools"
+-.\" -----------------------------------------------------------------
+-.\" * Define some portability stuff
+-.\" -----------------------------------------------------------------
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.\" http://bugs.debian.org/507673
+-.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.ie \n(.g .ds Aq \(aq
+-.el .ds Aq '
+-.\" -----------------------------------------------------------------
+-.\" * set default formatting
+-.\" -----------------------------------------------------------------
+-.\" disable hyphenation
+-.nh
+-.\" disable justification (adjust text to left margin only)
+-.ad l
+-.\" -----------------------------------------------------------------
+-.\" * MAIN CONTENT STARTS HERE *
+-.\" -----------------------------------------------------------------
+-
+-.SH NAME
++.TH "jstat" "1" "03 March 2015" "JDK 8" "Monitoring Tools"
++.\" -----------------------------------------------------------------
++.\" * Define some portability stuff
++.\" -----------------------------------------------------------------
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.\" http://bugs.debian.org/507673
++.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.ie \n(.g .ds Aq \(aq
++.el .ds Aq '
++.\" -----------------------------------------------------------------
++.\" * set default formatting
++.\" -----------------------------------------------------------------
++.\" disable hyphenation
++.nh
++.\" disable justification (adjust text to left margin only)
++.ad l
++.\" -----------------------------------------------------------------
++.\" * MAIN CONTENT STARTS HERE *
++.\" -----------------------------------------------------------------
++.SH "NAME"
+ jstat \- Monitors Java Virtual Machine (JVM) statistics\&. This command is experimental and unsupported\&.
+-.SH SYNOPSIS
+-.sp
+-.nf
+-
++.SH "SYNOPSIS"
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
+ \fBjstat\fR [ \fIgeneralOption\fR | \fIoutputOptions vmid\fR [ \fIinterval\fR[s|ms] [ \fIcount \fR] ]
+-.fi
+-.sp
+-.TP
++.fi
++.if n \{\
++.RE
++.\}
++.PP
+ \fIgeneralOption\fR
+-A single general command-line option \f3-help\fR or \f3-options\fR\&. See General Options\&.
+-.TP
++.RS 4
++A single general command\-line option
++\fB\-help\fR
++or
++\fB\-options\fR\&. See General Options\&.
++.RE
++.PP
+ \fIoutputOptions\fR
+-One or more output options that consist of a single \f3statOption\fR, plus any of the \f3-t\fR, \f3-h\fR, and \f3-J\fR options\&. See Output Options\&.
+-.TP
++.RS 4
++One or more output options that consist of a single
++\fBstatOption\fR, plus any of the
++\fB\-t\fR,
++\fB\-h\fR, and
++\fB\-J\fR
++options\&. See Output Options\&.
++.RE
++.PP
+ \fIvmid\fR
++.RS 4
+ Virtual machine identifier, which is a string that indicates the target JVM\&. The general syntax is the following:
+-.sp
+-.nf
+-\f3[protocol:][//]lvmid[@hostname[:port]/servername]\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-
+-
+-The syntax of the \f3vmid\fR string corresponds to the syntax of a URI\&. The \f3vmid\fR string can vary from a simple integer that represents a local JVM to a more complex construction that specifies a communications protocol, port number, and other implementation-specific values\&. See Virtual Machine Identifier\&.
+-.TP
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[protocol:][//]lvmid[@hostname[:port]/servername]\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++The syntax of the
++\fBvmid\fR
++string corresponds to the syntax of a URI\&. The
++\fBvmid\fR
++string can vary from a simple integer that represents a local JVM to a more complex construction that specifies a communications protocol, port number, and other implementation\-specific values\&. See Virtual Machine Identifier\&.
++.RE
++.PP
+ \fIinterval\fR [s|ms]
+-Sampling interval in the specified units, seconds (s) or milliseconds (ms)\&. Default units are milliseconds\&. Must be a positive integer\&. When specified, the \f3jstat\fR command produces its output at each interval\&.
+-.TP
++.RS 4
++Sampling interval in the specified units, seconds (s) or milliseconds (ms)\&. Default units are milliseconds\&. Must be a positive integer\&. When specified, the
++\fBjstat\fR
++command produces its output at each interval\&.
++.RE
++.PP
+ \fIcount\fR
+-Number of samples to display\&. The default value is infinity which causes the \f3jstat\fR command to display statistics until the target JVM terminates or the \f3jstat\fR command is terminated\&. This value must be a positive integer\&.
+-.SH DESCRIPTION
+-The \f3jstat\fR command displays performance statistics for an instrumented Java HotSpot VM\&. The target JVM is identified by its virtual machine identifier, or \f3vmid\fR option\&.
+-.SH VIRTUAL\ MACHINE\ IDENTIFIER
+-The syntax of the \f3vmid\fR string corresponds to the syntax of a URI:
+-.sp
+-.nf
+-\f3[protocol:][//]lvmid[@hostname[:port]/servername]\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-.TP
++.RS 4
++Number of samples to display\&. The default value is infinity which causes the
++\fBjstat\fR
++command to display statistics until the target JVM terminates or the
++\fBjstat\fR
++command is terminated\&. This value must be a positive integer\&.
++.RE
++.SH "DESCRIPTION"
++.PP
++The
++\fBjstat\fR
++command displays performance statistics for an instrumented Java HotSpot VM\&. The target JVM is identified by its virtual machine identifier, or
++\fBvmid\fR
++option\&.
++.SH "VIRTUAL MACHINE IDENTIFIER"
++.PP
++The syntax of the
++\fBvmid\fR
++string corresponds to the syntax of a URI:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[protocol:][//]lvmid[@hostname[:port]/servername]\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.PP
+ \fIprotocol\fR
+-The communications protocol\&. If the \fIprotocol\fR value is omitted and a host name is not specified, then the default protocol is a platform-specific optimized local protocol\&. If the \fIprotocol\fR value is omitted and a host name is specified, then the default protocol is \f3rmi\fR\&.
+-.TP
++.RS 4
++The communications protocol\&. If the
++\fIprotocol\fR
++value is omitted and a host name is not specified, then the default protocol is a platform\-specific optimized local protocol\&. If the
++\fIprotocol\fR
++value is omitted and a host name is specified, then the default protocol is
++\fBrmi\fR\&.
++.RE
++.PP
+ \fIlvmid\fR
+-The local virtual machine identifier for the target JVM\&. The \f3lvmid\fR is a platform-specific value that uniquely identifies a JVM on a system\&. The \f3lvmid\fR is the only required component of a virtual machine identifier\&. The \f3lvmid\fR is typically, but not necessarily, the operating system\&'s process identifier for the target JVM process\&. You can use the \f3jps\fR command to determine the \f3lvmid\fR\&. Also, you can determine the \f3lvmid\fR on UNIX platforms with the \f3ps\fR command, and on Windows with the Windows Task Manager\&.
+-.TP
++.RS 4
++The local virtual machine identifier for the target JVM\&. The
++\fBlvmid\fR
++is a platform\-specific value that uniquely identifies a JVM on a system\&. The
++\fBlvmid\fR
++is the only required component of a virtual machine identifier\&. The
++\fBlvmid\fR
++is typically, but not necessarily, the operating system\*(Aqs process identifier for the target JVM process\&. You can use the
++\fBjps\fR
++command to determine the
++\fBlvmid\fR\&. Also, you can determine the
++\fBlvmid\fR
++on Solaris, Linux, and OS X platforms with the
++\fBps\fR
++command, and on Windows with the Windows Task Manager\&.
++.RE
++.PP
+ \fIhostname\fR
+-A hostname or IP address that indicates the target host\&. If the \fIhostname\fR value is omitted, then the target host is the local host\&.
+-.TP
++.RS 4
++A hostname or IP address that indicates the target host\&. If the
++\fIhostname\fR
++value is omitted, then the target host is the local host\&.
++.RE
++.PP
+ \fIport\fR
+-The default port for communicating with the remote server\&. If the \fIhostname\fR value is omitted or the \fIprotocol\fR value specifies an optimized, local protocol, then the \fIport\fR value is ignored\&. Otherwise, treatment of the \f3port\fR parameter is implementation-specific\&. For the default \f3rmi\fR protocol, the port value indicates the port number for the rmiregistry on the remote host\&. If the \fIport\fR value is omitted and the \fIprotocol\fR value indicates \f3rmi\fR, then the default rmiregistry port (1099) is used\&.
+-.TP
++.RS 4
++The default port for communicating with the remote server\&. If the
++\fIhostname\fR
++value is omitted or the
++\fIprotocol\fR
++value specifies an optimized, local protocol, then the
++\fIport\fR
++value is ignored\&. Otherwise, treatment of the
++\fBport\fR
++parameter is implementation\-specific\&. For the default
++\fBrmi\fR
++protocol, the port value indicates the port number for the rmiregistry on the remote host\&. If the
++\fIport\fR
++value is omitted and the
++\fIprotocol\fR
++value indicates
++\fBrmi\fR, then the default rmiregistry port (1099) is used\&.
++.RE
++.PP
+ \fIservername\fR
+-The treatment of the \f3servername\fR parameter depends on implementation\&. For the optimized local protocol, this field is ignored\&. For the \f3rmi\fR protocol, it represents the name of the RMI remote object on the remote host\&.
+-.SH OPTIONS
+-The \f3jstat\fR command supports two types of options, general options and output options\&. General options cause the \f3jstat\fR command to display simple usage and version information\&. Output options determine the content and format of the statistical output\&.
++.RS 4
++The treatment of the
++\fBservername\fR
++parameter depends on implementation\&. For the optimized local protocol, this field is ignored\&. For the
++\fBrmi\fR
++protocol, it represents the name of the RMI remote object on the remote host\&.
++.RE
++.SH "OPTIONS"
++.PP
++The
++\fBjstat\fR
++command supports two types of options, general options and output options\&. General options cause the
++\fBjstat\fR
++command to display simple usage and version information\&. Output options determine the content and format of the statistical output\&.
+ .PP
+ All options and their functionality are subject to change or removal in future releases\&.
+-.SS GENERAL\ OPTIONS
++.SS "General Options"
++.PP
+ If you specify one of the general options, then you cannot specify any other option or parameter\&.
+-.TP
+--help
+-.br
++.PP
++\-help
++.RS 4
+ Displays a help message\&.
+-.TP
+--options
+-.br
++.RE
++.PP
++\-options
++.RS 4
+ Displays a list of static options\&. See Output Options\&.
+-.SS OUTPUT\ OPTIONS
+-If you do not specify a general option, then you can specify output options\&. Output options determine the content and format of the \f3jstat\fR command\&'s output, and consist of a single \f3statOption\fR, plus any of the other output options (\f3-h\fR, \f3-t\fR, and \f3-J\fR)\&. The \f3statOption\fR must come first\&.
++.RE
++.SS "Output Options"
+ .PP
+-Output is formatted as a table, with columns that are separated by spaces\&. A header row with titles describes the columns\&. Use the \f3-h\fR option to set the frequency at which the header is displayed\&. Column header names are consistent among the different options\&. In general, if two options provide a column with the same name, then the data source for the two columns is the same\&.
++If you do not specify a general option, then you can specify output options\&. Output options determine the content and format of the
++\fBjstat\fR
++command\*(Aqs output, and consist of a single
++\fBstatOption\fR, plus any of the other output options (\fB\-h\fR,
++\fB\-t\fR, and
++\fB\-J\fR)\&. The
++\fBstatOption\fR
++must come first\&.
+ .PP
+-Use the \f3-t\fR option to display a time stamp column, labeled Timestamp as the first column of output\&. The Timestamp column contains the elapsed time, in seconds, since the target JVM started\&. The resolution of the time stamp is dependent on various factors and is subject to variation due to delayed thread scheduling on heavily loaded systems\&.
++Output is formatted as a table, with columns that are separated by spaces\&. A header row with titles describes the columns\&. Use the
++\fB\-h\fR
++option to set the frequency at which the header is displayed\&. Column header names are consistent among the different options\&. In general, if two options provide a column with the same name, then the data source for the two columns is the same\&.
+ .PP
+-Use the interval and count parameters to determine how frequently and how many times, respectively, the \f3jstat\fR command displays its output\&.
++Use the
++\fB\-t\fR
++option to display a time stamp column, labeled Timestamp as the first column of output\&. The Timestamp column contains the elapsed time, in seconds, since the target JVM started\&. The resolution of the time stamp is dependent on various factors and is subject to variation due to delayed thread scheduling on heavily loaded systems\&.
+ .PP
+-\fINote:\fR Do not to write scripts to parse the \f3jstat\fR command\&'s output because the format might change in future releases\&. If you write scripts that parse \f3jstat\fR command output, then expect to modify them for future releases of this tool\&.
+-.TP
+--\fIstatOption\fR
+-.br
+-Determines the statistics information the \f3jstat\fR command displays\&. The following lists the available options\&. Use the \f3-options\fR general option to display the list of options for a particular platform installation\&. See Stat Options and Output\&.
+-
+-\f3class\fR: Displays statistics about the behavior of the class loader\&.
+-
+-\f3compiler\fR: Displays statistics about the behavior of the Java HotSpot VM Just-in-Time compiler\&.
+-
+-\f3gc\fR: Displays statistics about the behavior of the garbage collected heap\&.
+-
+-\f3gccapacity\fR: Displays statistics about the capacities of the generations and their corresponding spaces\&.
+-
+-\f3gccause\fR: Displays a summary about garbage collection statistics (same as \f3-gcutil\fR), with the cause of the last and current (when applicable) garbage collection events\&.
+-
+-\f3gcnew\fR: Displays statistics of the behavior of the new generation\&.
+-
+-\f3gcnewcapacity\fR: Displays statistics about the sizes of the new generations and its corresponding spaces\&.
+-
+-\f3gcold\fR: Displays statistics about the behavior of the old generation and Metaspace Statistics\&.
+-
+-\f3gcoldcapacity\fR: Displays statistics about the sizes of the old generation\&.
+-
+-\f3gcmetacapacity\fR: Displays statistics about the sizes of the metaspace\&.
+-
+-\f3gcutil\fR: Displays a summary about garbage collection statistics\&.
+-
+-\f3printcompilation\fR: Displays Java HotSpot VM compilation method statistics\&.
+-.TP
+--h \fIn\fR
+-.br
+-Displays a column header every \fIn\fR samples (output rows), where \fIn\fR is a positive integer\&. Default value is 0, which displays the column header the first row of data\&.
+-.TP
+--t
+-.br
+-Display sa timestamp column as the first column of output\&. The time stamp is the time since the start time of the target JVM\&.
+-.TP
+--J\fIjavaOption\fR
+-.br
+-Passes \f3javaOption\fR to the Java application launcher\&. For example, \f3-J-Xms48m\fR sets the startup memory to 48 MB\&. For a complete list of options, see java(1)\&.
+-.SS STAT\ OPTIONS\ AND\ OUTPUT
+-The following information summarizes the columns that the \f3jstat\fR command outputs for each \fIstatOption\fR\&.
+-.TP
+--class \fIoption\fR
+-.br
++Use the interval and count parameters to determine how frequently and how many times, respectively, the
++\fBjstat\fR
++command displays its output\&.
++.PP
++\fBNote:\fR
++Do not to write scripts to parse the
++\fBjstat\fR
++command\*(Aqs output because the format might change in future releases\&. If you write scripts that parse
++\fBjstat\fR
++command output, then expect to modify them for future releases of this tool\&.
++.PP
++\-\fIstatOption\fR
++.RS 4
++Determines the statistics information the
++\fBjstat\fR
++command displays\&. The following lists the available options\&. Use the
++\fB\-options\fR
++general option to display the list of options for a particular platform installation\&. See Stat Options and Output\&.
++.sp
++\fBclass\fR: Displays statistics about the behavior of the class loader\&.
++.sp
++\fBcompiler\fR: Displays statistics about the behavior of the Java HotSpot VM Just\-in\-Time compiler\&.
++.sp
++\fBgc\fR: Displays statistics about the behavior of the garbage collected heap\&.
++.sp
++\fBgccapacity\fR: Displays statistics about the capacities of the generations and their corresponding spaces\&.
++.sp
++\fBgccause\fR: Displays a summary about garbage collection statistics (same as
++\fB\-gcutil\fR), with the cause of the last and current (when applicable) garbage collection events\&.
++.sp
++\fBgcnew\fR: Displays statistics of the behavior of the new generation\&.
++.sp
++\fBgcnewcapacity\fR: Displays statistics about the sizes of the new generations and its corresponding spaces\&.
++.sp
++\fBgcold\fR: Displays statistics about the behavior of the old generation and metaspace statistics\&.
++.sp
++\fBgcoldcapacity\fR: Displays statistics about the sizes of the old generation\&.
++.sp
++\fBgcmetacapacity\fR: Displays statistics about the sizes of the metaspace\&.
++.sp
++\fBgcutil\fR: Displays a summary about garbage collection statistics\&.
++.sp
++\fBprintcompilation\fR: Displays Java HotSpot VM compilation method statistics\&.
++.RE
++.PP
++\-h \fIn\fR
++.RS 4
++Displays a column header every
++\fIn\fR
++samples (output rows), where
++\fIn\fR
++is a positive integer\&. Default value is 0, which displays the column header the first row of data\&.
++.RE
++.PP
++\-t
++.RS 4
++Displays a timestamp column as the first column of output\&. The time stamp is the time since the start time of the target JVM\&.
++.RE
++.PP
++\-J\fIjavaOption\fR
++.RS 4
++Passes
++\fBjavaOption\fR
++to the Java application launcher\&. For example,
++\fB\-J\-Xms48m\fR
++sets the startup memory to 48 MB\&. For a complete list of options, see
++java(1)\&.
++.RE
++.SS "Stat Options and Output"
++.PP
++The following information summarizes the columns that the
++\fBjstat\fR
++command outputs for each
++\fIstatOption\fR\&.
++.PP
++\-class \fIoption\fR
++.RS 4
+ Class loader statistics\&.
+-
+-\f3Loaded\fR: Number of classes loaded\&.
+-
+-\f3Bytes\fR: Number of KBs loaded\&.
+-
+-\f3Unloaded\fR: Number of classes unloaded\&.
+-
+-\f3Bytes\fR: Number of Kbytes unloaded\&.
+-
+-\f3Time\fR: Time spent performing class loading and unloading operations\&.
+-.TP
+--compiler \fIoption\fR
+-.br
+-Java HotSpot VM Just-in-Time compiler statistics\&.
+-
+-\f3Compiled\fR: Number of compilation tasks performed\&.
+-
+-\f3Failed\fR: Number of compilations tasks failed\&.
+-
+-\f3Invalid\fR: Number of compilation tasks that were invalidated\&.
+-
+-\f3Time\fR: Time spent performing compilation tasks\&.
+-
+-\f3FailedType\fR: Compile type of the last failed compilation\&.
+-
+-\f3FailedMethod\fR: Class name and method of the last failed compilation\&.
+-.TP
+--gc \fIoption\fR
+-.br
+-Garbage-collected heap statistics\&.
+-
+-\f3S0C\fR: Current survivor space 0 capacity (KB)\&.
+-
+-\f3S1C\fR: Current survivor space 1 capacity (KB)\&.
+-
+-\f3S0U\fR: Survivor space 0 utilization (KB)\&.
+-
+-\f3S1U\fR: Survivor space 1 utilization (KB)\&.
+-
+-\f3EC\fR: Current eden space capacity (KB)\&.
+-
+-\f3EU\fR: Eden space utilization (KB)\&.
+-
+-\f3OC\fR: Current old space capacity (KB)\&.
+-
+-\f3OU\fR: Old space utilization (KB)\&.
+-
+-\f3MC\fR: Metaspace capacity (KB)\&.
+-
+-\f3MU\fR: Metacspace utilization (KB)\&.
+-
+-\f3YGC\fR: Number of young generation garbage collection events\&.
+-
+-\f3YGCT\fR: Young generation garbage collection time\&.
+-
+-\f3FGC\fR: Number of full GC events\&.
+-
+-\f3FGCT\fR: Full garbage collection time\&.
+-
+-\f3GCT\fR: Total garbage collection time\&.
+-.TP
+--gccapacity \fIoption\fR
+-.br
++.sp
++\fBLoaded\fR: Number of classes loaded\&.
++.sp
++\fBBytes\fR: Number of kBs loaded\&.
++.sp
++\fBUnloaded\fR: Number of classes unloaded\&.
++.sp
++\fBBytes\fR: Number of Kbytes unloaded\&.
++.sp
++\fBTime\fR: Time spent performing class loading and unloading operations\&.
++.RE
++.PP
++\-compiler \fIoption\fR
++.RS 4
++Java HotSpot VM Just\-in\-Time compiler statistics\&.
++.sp
++\fBCompiled\fR: Number of compilation tasks performed\&.
++.sp
++\fBFailed\fR: Number of compilations tasks failed\&.
++.sp
++\fBInvalid\fR: Number of compilation tasks that were invalidated\&.
++.sp
++\fBTime\fR: Time spent performing compilation tasks\&.
++.sp
++\fBFailedType\fR: Compile type of the last failed compilation\&.
++.sp
++\fBFailedMethod\fR: Class name and method of the last failed compilation\&.
++.RE
++.PP
++\-gc \fIoption\fR
++.RS 4
++Garbage\-collected heap statistics\&.
++.sp
++\fBS0C\fR: Current survivor space 0 capacity (kB)\&.
++.sp
++\fBS1C\fR: Current survivor space 1 capacity (kB)\&.
++.sp
++\fBS0U\fR: Survivor space 0 utilization (kB)\&.
++.sp
++\fBS1U\fR: Survivor space 1 utilization (kB)\&.
++.sp
++\fBEC\fR: Current eden space capacity (kB)\&.
++.sp
++\fBEU\fR: Eden space utilization (kB)\&.
++.sp
++\fBOC\fR: Current old space capacity (kB)\&.
++.sp
++\fBOU\fR: Old space utilization (kB)\&.
++.sp
++\fBMC\fR: Metaspace capacity (kB)\&.
++.sp
++\fBMU\fR: Metacspace utilization (kB)\&.
++.sp
++\fBCCSC\fR: Compressed class space capacity (kB)\&.
++.sp
++\fBCCSU\fR: Compressed class space used (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation garbage collection events\&.
++.sp
++\fBYGCT\fR: Young generation garbage collection time\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.sp
++\fBFGCT\fR: Full garbage collection time\&.
++.sp
++\fBGCT\fR: Total garbage collection time\&.
++.RE
++.PP
++\-gccapacity \fIoption\fR
++.RS 4
+ Memory pool generation and space capacities\&.
+-
+-\f3NGCMN\fR: Minimum new generation capacity (KB)\&.
+-
+-\f3NGCMX\fR: Maximum new generation capacity (KB)\&.
+-
+-\f3NGC\fR: Current new generation capacity (KB)\&.
+-
+-\f3S0C\fR: Current survivor space 0 capacity (KB)\&.
+-
+-\f3S1C\fR: Current survivor space 1 capacity (KB)\&.
+-
+-\f3EC\fR: Current eden space capacity (KB)\&.
+-
+-\f3OGCMN\fR: Minimum old generation capacity (KB)\&.
+-
+-\f3OGCMX\fR: Maximum old generation capacity (KB)\&.
+-
+-\f3OGC\fR: Current old generation capacity (KB)\&.
+-
+-\f3OC\fR: Current old space capacity (KB)\&.
+-
+-\f3MCMN\fR: Minimum metaspace capacity (KB)\&.
+-
+-\f3MCMX\fR: Maximum metaspace capacity (KB)\&.
+-
+-\f3MC\fR: Metaspace capacity (KB)\&.
+-
+-\f3YGC\fR: Number of Young generation GC Events\&.
+-
+-\f3FGC\fR: Number of Full GC Events\&.
+-.TP
+--gccause \fIoption\fR
+-.br
+-This option displays the same summary of garbage collection statistics as the \f3-gcutil\fR option, but includes the causes of the last garbage collection event and (when applicable) the current garbage collection event\&. In addition to the columns listed for \f3-gcutil\fR, this option adds the following columns\&.
+-
+-Garbage collection statistics, including garbage collection Events\&.
+-
+-\f3LGCC\fR: Cause of last garbage collection\&.
+-
+-\f3GCC\fR: Cause of current garbage collection\&.
+-.TP
+--gcnew \fIoption\fR
+-.br
++.sp
++\fBNGCMN\fR: Minimum new generation capacity (kB)\&.
++.sp
++\fBNGCMX\fR: Maximum new generation capacity (kB)\&.
++.sp
++\fBNGC\fR: Current new generation capacity (kB)\&.
++.sp
++\fBS0C\fR: Current survivor space 0 capacity (kB)\&.
++.sp
++\fBS1C\fR: Current survivor space 1 capacity (kB)\&.
++.sp
++\fBEC\fR: Current eden space capacity (kB)\&.
++.sp
++\fBOGCMN\fR: Minimum old generation capacity (kB)\&.
++.sp
++\fBOGCMX\fR: Maximum old generation capacity (kB)\&.
++.sp
++\fBOGC\fR: Current old generation capacity (kB)\&.
++.sp
++\fBOC\fR: Current old space capacity (kB)\&.
++.sp
++\fBMCMN\fR: Minimum metaspace capacity (kB)\&.
++.sp
++\fBMCMX\fR: Maximum metaspace capacity (kB)\&.
++.sp
++\fBMC\fR: Metaspace capacity (kB)\&.
++.sp
++\fBCCSMN\fR: Compressed class space minimum capacity (kB)\&.
++.sp
++\fBCCSMX\fR: Compressed class space maximum capacity (kB)\&.
++.sp
++\fBCCSC\fR: Compressed class space capacity (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.RE
++.PP
++\-gccause \fIoption\fR
++.RS 4
++This option displays the same summary of garbage collection statistics as the
++\fB\-gcutil\fR
++option, but includes the causes of the last garbage collection event and (when applicable) the current garbage collection event\&. In addition to the columns listed for
++\fB\-gcutil\fR, this option adds the following columns\&.
++.sp
++\fBLGCC\fR: Cause of last garbage collection
++.sp
++\fBGCC\fR: Cause of current garbage collection
++.RE
++.PP
++\-gcnew \fIoption\fR
++.RS 4
+ New generation statistics\&.
+-
+-\f3S0C\fR: Current survivor space 0 capacity (KB)\&.
+-
+-\f3S1C\fR: Current survivor space 1 capacity (KB)\&.
+-
+-\f3S0U\fR: Survivor space 0 utilization (KB)\&.
+-
+-\f3S1U\fR: Survivor space 1 utilization (KB)\&.
+-
+-\f3TT\fR: Tenuring threshold\&.
+-
+-\f3MTT\fR: Maximum tenuring threshold\&.
+-
+-\f3DSS\fR: Desired survivor size (KB)\&.
+-
+-\f3EC\fR: Current eden space capacity (KB)\&.
+-
+-\f3EU\fR: Eden space utilization (KB)\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3YGCT\fR: Young generation garbage collection time\&.
+-.TP
+--gcnewcapacity \fIoption\fR
+-.br
++.sp
++\fBS0C\fR: Current survivor space 0 capacity (kB)\&.
++.sp
++\fBS1C\fR: Current survivor space 1 capacity (kB)\&.
++.sp
++\fBS0U\fR: Survivor space 0 utilization (kB)\&.
++.sp
++\fBS1U\fR: Survivor space 1 utilization (kB)\&.
++.sp
++\fBTT\fR: Tenuring threshold\&.
++.sp
++\fBMTT\fR: Maximum tenuring threshold\&.
++.sp
++\fBDSS\fR: Desired survivor size (kB)\&.
++.sp
++\fBEC\fR: Current eden space capacity (kB)\&.
++.sp
++\fBEU\fR: Eden space utilization (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBYGCT\fR: Young generation garbage collection time\&.
++.RE
++.PP
++\-gcnewcapacity \fIoption\fR
++.RS 4
+ New generation space size statistics\&.
+-
+-NGCMN: Minimum new generation capacity (KB)\&.
+-
+-\f3NGCMX\fR: Maximum new generation capacity (KB)\&.
+-
+-\f3NGC\fR: Current new generation capacity (KB)\&.
+-
+-\f3S0CMX\fR: Maximum survivor space 0 capacity (KB)\&.
+-
+-\f3S0C\fR: Current survivor space 0 capacity (KB)\&.
+-
+-\f3S1CMX\fR: Maximum survivor space 1 capacity (KB)\&.
+-
+-\f3S1C\fR: Current survivor space 1 capacity (KB)\&.
+-
+-\f3ECMX\fR: Maximum eden space capacity (KB)\&.
+-
+-\f3EC\fR: Current eden space capacity (KB)\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3FGC\fR: Number of Full GC Events\&.
+-.TP
+--gcold \fIoption\fR
+-.br
+-old and permanent generation statistics\&.
+-
+-\f3MC\fR: Metaspace capacity (KB)\&.
+-
+-\f3MU\fR: Metaspace utilization (KB)\&.
+-
+-\f3OC\fR: Current old space capacity (KB)\&.
+-
+-\f3OU\fR: old space utilization (KB)\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3FGC\fR: Number of full GC events\&.
+-
+-\f3FGCT\fR: Full garbage collection time\&.
+-
+-\f3GCT\fR: Total garbage collection time\&.
+-.TP
+--gcoldcapacity \fIoption\fR
+-.br
+-Old generation statistics\&.
+-
+-\f3OGCMN\fR: Minimum old generation capacity (KB)\&.
+-
+-\f3OGCMX\fR: Maximum old generation capacity (KB)\&.
+-
+-\f3OGC\fR: Current old generation capacity (KB)\&.
+-
+-\f3OC\fR: Current old space capacity (KB)\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3FGC\fR: Number of full GC events\&.
+-
+-\f3FGCT\fR: Full garbage collection time\&.
+-
+-\f3GCT\fR: Total garbage collection time\&.
+-.TP
+--gcmetacapacity \fIoption\fR
+-.br
+-Permanent generation statistics\&.
+-
+-\f3MCMN\fR: Minimum metaspace capacity (KB)\&.
+-
+-\f3MCMX\fR: Maximum metaspace capacity (KB)\&.
+-
+-\f3MC\fR: Metaspace capacity (KB)\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3FGC\fR: Number of full GC events\&.
+-
+-\f3FGCT\fR: Full garbage collection time\&.
+-
+-\f3GCT\fR: Total garbage collection time\&.
+-.TP
+--gcutil \fIoption\fR
+-.br
++.sp
++\fBNGCMN\fR: Minimum new generation capacity (kB)\&.
++.sp
++\fBNGCMX\fR: Maximum new generation capacity (kB)\&.
++.sp
++\fBNGC\fR: Current new generation capacity (kB)\&.
++.sp
++\fBS0CMX\fR: Maximum survivor space 0 capacity (kB)\&.
++.sp
++\fBS0C\fR: Current survivor space 0 capacity (kB)\&.
++.sp
++\fBS1CMX\fR: Maximum survivor space 1 capacity (kB)\&.
++.sp
++\fBS1C\fR: Current survivor space 1 capacity (kB)\&.
++.sp
++\fBECMX\fR: Maximum eden space capacity (kB)\&.
++.sp
++\fBEC\fR: Current eden space capacity (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.RE
++.PP
++\-gcold \fIoption\fR
++.RS 4
++Old generation and metaspace behavior statistics\&.
++.sp
++\fBMC\fR: Metaspace capacity (kB)\&.
++.sp
++\fBMU\fR: Metaspace utilization (kB)\&.
++.sp
++\fBCCSC\fR: Compressed class space capacity (kB)\&.
++.sp
++\fBCCSU\fR: Compressed class space used (kB)\&.
++.sp
++\fBOC\fR: Current old space capacity (kB)\&.
++.sp
++\fBOU\fR: Old space utilization (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.sp
++\fBFGCT\fR: Full garbage collection time\&.
++.sp
++\fBGCT\fR: Total garbage collection time\&.
++.RE
++.PP
++\-gcoldcapacity \fIoption\fR
++.RS 4
++Old generation size statistics\&.
++.sp
++\fBOGCMN\fR: Minimum old generation capacity (kB)\&.
++.sp
++\fBOGCMX\fR: Maximum old generation capacity (kB)\&.
++.sp
++\fBOGC\fR: Current old generation capacity (kB)\&.
++.sp
++\fBOC\fR: Current old space capacity (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.sp
++\fBFGCT\fR: Full garbage collection time\&.
++.sp
++\fBGCT\fR: Total garbage collection time\&.
++.RE
++.PP
++\-gcmetacapacity \fIoption\fR
++.RS 4
++Metaspace size statistics\&.
++.sp
++\fBMCMN\fR: Minimum metaspace capacity (kB)\&.
++.sp
++\fBMCMX\fR: Maximum metaspace capacity (kB)\&.
++.sp
++\fBMC\fR: Metaspace capacity (kB)\&.
++.sp
++\fBCCSMN\fR: Compressed class space minimum capacity (kB)\&.
++.sp
++\fBCCSMX\fR: Compressed class space maximum capacity (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.sp
++\fBFGCT\fR: Full garbage collection time\&.
++.sp
++\fBGCT\fR: Total garbage collection time\&.
++.RE
++.PP
++\-gcutil \fIoption\fR
++.RS 4
+ Summary of garbage collection statistics\&.
+-
+-\f3S0\fR: Survivor space 0 utilization as a percentage of the space\&'s current capacity\&.
+-
+-\f3S1\fR: Survivor space 1 utilization as a percentage of the space\&'s current capacity\&.
+-
+-\f3E\fR: Eden space utilization as a percentage of the space\&'s current capacity\&.
+-
+-\f3O\fR: Old space utilization as a percentage of the space\&'s current capacity\&.
+-
+-\f3M\fR: Metaspace utilization as a percentage of the space\&'s current capacity\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3YGCT\fR: Young generation garbage collection time\&.
+-
+-\f3FGC\fR: Number of full GC events\&.
+-
+-\f3FGCT\fR: Full garbage collection time\&.
+-
+-\f3GCT\fR: Total garbage collection time\&.
+-.TP
+--printcompilation \fIoption\fR
+-.br
++.sp
++\fBS0\fR: Survivor space 0 utilization as a percentage of the space\*(Aqs current capacity\&.
++.sp
++\fBS1\fR: Survivor space 1 utilization as a percentage of the space\*(Aqs current capacity\&.
++.sp
++\fBE\fR: Eden space utilization as a percentage of the space\*(Aqs current capacity\&.
++.sp
++\fBO\fR: Old space utilization as a percentage of the space\*(Aqs current capacity\&.
++.sp
++\fBM\fR: Metaspace utilization as a percentage of the space\*(Aqs current capacity\&.
++.sp
++\fBCCS\fR: Compressed class space utilization as a percentage\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBYGCT\fR: Young generation garbage collection time\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.sp
++\fBFGCT\fR: Full garbage collection time\&.
++.sp
++\fBGCT\fR: Total garbage collection time\&.
++.RE
++.PP
++\-printcompilation \fIoption\fR
++.RS 4
+ Java HotSpot VM compiler method statistics\&.
+-
+-\f3Compiled\fR: Number of compilation tasks performed by the most recently compiled method\&.
+-
+-\f3Size\fR: Number of bytes of byte code of the most recently compiled method\&.
+-
+-\f3Type\fR: Compilation type of the most recently compiled method\&.
+-
+-\f3Method\fR: Class name and method name identifying the most recently compiled method\&. Class name uses slash (/) instead of dot (\&.) as a name space separator\&. Method name is the method within the specified class\&. The format for these two fields is consistent with the HotSpot \f3-XX:+PrintComplation\fR option\&.
+-.SH EXAMPLES
+-This section presents some examples of monitoring a local JVM with an \fIlvmid\fR of 21891\&.
+-.SS THE\ GCUTIL\ OPTION
+-This example attaches to lvmid 21891 and takes 7 samples at 250 millisecond intervals and displays the output as specified by the -\f3gcutil\fR option\&.
++.sp
++\fBCompiled\fR: Number of compilation tasks performed by the most recently compiled method\&.
++.sp
++\fBSize\fR: Number of bytes of byte code of the most recently compiled method\&.
++.sp
++\fBType\fR: Compilation type of the most recently compiled method\&.
++.sp
++\fBMethod\fR: Class name and method name identifying the most recently compiled method\&. Class name uses slash (/) instead of dot (\&.) as a name space separator\&. Method name is the method within the specified class\&. The format for these two fields is consistent with the HotSpot
++\fB\-XX:+PrintCompilation\fR
++option\&.
++.RE
++.SH "EXAMPLES"
+ .PP
+-The output of this example shows that a young generation collection occurred between the third and fourth sample\&. The collection took 0\&.001 seconds and promoted objects from the eden space (E) to the old space (O), resulting in an increase of old space utilization from 9\&.49% to 9\&.51%\&. Before the collection, the survivor space was 12\&.44% utilized, but after this collection it is only 7\&.74% utilized\&.
+-.sp
+-.nf
+-\f3jstat \-gcutil 21891 250 7\fP
+-.fi
+-.nf
+-\f3 S0 S1 E O M YGC YGCT FGC FGCT GCT\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.80 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.80 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.80 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-.SS REPEAT\ THE\ COLUMN\ HEADER\ STRING
+-This example attaches to lvmid 21891 and takes samples at 250 millisecond intervals and displays the output as specified by \f3-gcutil\fR option\&. In addition, it uses the \f3-h3\fR option to output the column header after every 3 lines of data\&.
++This section presents some examples of monitoring a local JVM with an
++\fIlvmid\fR
++of 21891\&.
++.SS "The gcutil Option"
++.PP
++This example attaches to lvmid 21891 and takes 7 samples at 250 millisecond intervals and displays the output as specified by the \-\fBgcutil\fR
++option\&.
++.PP
++The output of this example shows that a young generation collection occurred between the third and fourth sample\&. The collection took 0\&.078 seconds and promoted objects from the eden space (E) to the old space (O), resulting in an increase of old space utilization from 66\&.80% to 68\&.19%\&. Before the collection, the survivor space was 97\&.02% utilized, but after this collection it is 91\&.03% utilized\&.
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjstat \-gcutil 21891 250 7\fR
++\fB S0 S1 E O M CCS YGC YGCT FGC FGCT GCT \fR
++\fB 0\&.00 97\&.02 70\&.31 66\&.80 95\&.52 89\&.14 7 0\&.300 0 0\&.000 0\&.300\fR
++\fB 0\&.00 97\&.02 86\&.23 66\&.80 95\&.52 89\&.14 7 0\&.300 0 0\&.000 0\&.300\fR
++\fB 0\&.00 97\&.02 96\&.53 66\&.80 95\&.52 89\&.14 7 0\&.300 0 0\&.000 0\&.300\fR
++\fB 91\&.03 0\&.00 1\&.98 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++\fB 91\&.03 0\&.00 15\&.82 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++\fB 91\&.03 0\&.00 17\&.80 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++\fB 91\&.03 0\&.00 17\&.80 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++.fi
++.if n \{\
++.RE
++.\}
++.SS "Repeat the Column Header String"
++.PP
++This example attaches to lvmid 21891 and takes samples at 250 millisecond intervals and displays the output as specified by
++\fB\-gcnew\fR
++option\&. In addition, it uses the
++\fB\-h3\fR
++option to output the column header after every 3 lines of data\&.
+ .PP
+ In addition to showing the repeating header string, this example shows that between the second and third samples, a young GC occurred\&. Its duration was 0\&.001 seconds\&. The collection found enough active data that the survivor space 0 utilization (S0U) would have exceeded the desired survivor Size (DSS)\&. As a result, objects were promoted to the old generation (not visible in this output), and the tenuring threshold (TT) was lowered from 31 to 2\&.
+ .PP
+ Another collection occurs between the fifth and sixth samples\&. This collection found very few survivors and returned the tenuring threshold to 31\&.
+-.sp
+-.nf
+-\f3jstat \-gcnew \-h3 21891 250\fP
+-.fi
+-.nf
+-\f3 S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 0\&.0 31\&.7 31 31 32\&.0 512\&.0 178\&.6 249 0\&.203\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 0\&.0 31\&.7 31 31 32\&.0 512\&.0 355\&.5 249 0\&.203\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 21\&.9 250 0\&.204\fP
+-.fi
+-.nf
+-\f3 S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 245\&.9 250 0\&.204\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 421\&.1 250 0\&.204\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 0\&.0 19\&.0 31 31 32\&.0 512\&.0 84\&.4 251 0\&.204\fP
+-.fi
+-.nf
+-\f3 S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 0\&.0 19\&.0 31 31 32\&.0 512\&.0 306\&.7 251 0\&.204\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-.SS INCLUDE\ A\ TIME\ STAMP\ FOR\ EACH\ SAMPLE
+-This example attaches to lvmid 21891 and takes 3 samples at 250 millisecond intervals\&. The \f3-t\fR option is used to generate a time stamp for each sample in the first column\&.
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjstat \-gcnew \-h3 21891 250\fR
++\fB S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fR
++\fB 64\&.0 64\&.0 0\&.0 31\&.7 31 31 32\&.0 512\&.0 178\&.6 249 0\&.203\fR
++\fB 64\&.0 64\&.0 0\&.0 31\&.7 31 31 32\&.0 512\&.0 355\&.5 249 0\&.203\fR
++\fB 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 21\&.9 250 0\&.204\fR
++\fB S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fR
++\fB 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 245\&.9 250 0\&.204\fR
++\fB 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 421\&.1 250 0\&.204\fR
++\fB 64\&.0 64\&.0 0\&.0 19\&.0 31 31 32\&.0 512\&.0 84\&.4 251 0\&.204\fR
++\fB S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fR
++\fB 64\&.0 64\&.0 0\&.0 19\&.0 31 31 32\&.0 512\&.0 306\&.7 251 0\&.204\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.SS "Include a Time Stamp for Each Sample"
+ .PP
+-The Timestamp column reports the elapsed time in seconds since the start of the target JVM\&. In addition, the \f3-gcoldcapacity\fR output shows the old generation capacity (OGC) and the old space capacity (OC) increasing as the heap expands to meet allocation or promotion demands\&. The old generation capacity (OGC) has grown to from 11,696 KB to 13820 KB after the eighty-first full garbage collection (FGC)\&. The maximum capacity of the generation (and space) is 60,544 KB (OGCMX), so it still has room to expand\&.
+-.sp
+-.nf
+-\f3Timestamp OGCMN OGCMX OGC OC YGC FGC FGCT GCT\fP
+-.fi
+-.nf
+-\f3 150\&.1 1408\&.0 60544\&.0 11696\&.0 11696\&.0 194 80 2\&.874 3\&.799\fP
+-.fi
+-.nf
+-\f3 150\&.4 1408\&.0 60544\&.0 13820\&.0 13820\&.0 194 81 2\&.938 3\&.863\fP
+-.fi
+-.nf
+-\f3 150\&.7 1408\&.0 60544\&.0 13820\&.0 13820\&.0 194 81 2\&.938 3\&.863\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-.SS MONITOR\ INSTRUMENTATION\ FOR\ A\ REMOTE\ JVM
+-This example attaches to lvmid 40496 on the system named remote\&.domain using the \f3-gcutil\fR option, with samples taken every second indefinitely\&.
++This example attaches to lvmid 21891 and takes 3 samples at 250 millisecond intervals\&. The
++\fB\-t\fR
++option is used to generate a time stamp for each sample in the first column\&.
+ .PP
+-The lvmid is combined with the name of the remote host to construct a \fIvmid\fR of \f340496@remote\&.domain\fR\&. This vmid results in the use of the \f3rmi\fR protocol to communicate to the default \f3jstatd\fR server on the remote host\&. The \f3jstatd\fR server is located using the rmiregistry on \f3remote\&.domain\fR that is bound to the default rmiregistry port (port 1099)\&.
+-.sp
+-.nf
+-\f3jstat \-gcutil 40496@remote\&.domain 1000\fP
+-.fi
+-.nf
+-\f3\fI\&.\&.\&. output omitted\fR\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-.SH SEE\ ALSO
+-.TP 0.2i
+-\(bu
++The Timestamp column reports the elapsed time in seconds since the start of the target JVM\&. In addition, the
++\fB\-gcoldcapacity\fR
++output shows the old generation capacity (OGC) and the old space capacity (OC) increasing as the heap expands to meet allocation or promotion demands\&. The old generation capacity (OGC) has grown from 11,696 kB to 13,820 kB after the eighty\-first full garbage collection (FGC)\&. The maximum capacity of the generation (and space) is 60,544 kB (OGCMX), so it still has room to expand\&.
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBTimestamp OGCMN OGCMX OGC OC YGC FGC FGCT GCT\fR
++\fB 150\&.1 1408\&.0 60544\&.0 11696\&.0 11696\&.0 194 80 2\&.874 3\&.799\fR
++\fB 150\&.4 1408\&.0 60544\&.0 13820\&.0 13820\&.0 194 81 2\&.938 3\&.863\fR
++\fB 150\&.7 1408\&.0 60544\&.0 13820\&.0 13820\&.0 194 81 2\&.938 3\&.863\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.SS "Monitor Instrumentation for a Remote JVM"
++.PP
++This example attaches to lvmid 40496 on the system named remote\&.domain using the
++\fB\-gcutil\fR
++option, with samples taken every second indefinitely\&.
++.PP
++The lvmid is combined with the name of the remote host to construct a
++\fIvmid\fR
++of
++\fB40496@remote\&.domain\fR\&. This vmid results in the use of the
++\fBrmi\fR
++protocol to communicate to the default
++\fBjstatd\fR
++server on the remote host\&. The
++\fBjstatd\fR
++server is located using the
++\fBrmiregistry\fR
++command on
++\fBremote\&.domain\fR
++that is bound to the default port of the
++\fBrmiregistry\fR
++command (port 1099)\&.
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjstat \-gcutil 40496@remote\&.domain 1000\fR
++\fB\fI\&.\&.\&. output omitted\fR\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.SH "SEE ALSO"
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
+ java(1)
+-.TP 0.2i
+-\(bu
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
+ jps(1)
+-.TP 0.2i
+-\(bu
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
+ jstatd(1)
+-.TP 0.2i
+-\(bu
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
+ rmiregistry(1)
+-.RE
+-.br
+-'pl 8.5i
+-'bp
++.RE
++.br
++'pl 8.5i
++'bp
+--- ./jdk/src/bsd/doc/man/keytool.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/bsd/doc/man/keytool.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ '\" t
+-.\" Copyright (c) 1998, 2013, 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.
+ .\"
+@@ -23,12 +23,12 @@
+ .\"
+ .\" Arch: generic
+ .\" Software: JDK 8
+-.\" Date: 6 August 2013
++.\" Date: 03 March 2015
+ .\" SectDesc: Security Tools
+ .\" Title: keytool.1
+ .\"
+ .if n .pl 99999
+-.TH keytool 1 "6 August 2013" "JDK 8" "Security Tools"
++.TH keytool 1 "03 March 2015" "JDK 8" "Security Tools"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -185,10 +185,16 @@
+ .TP 0.2i
+ \(bu
+ Items in italics (option values) represent the actual values that must be supplied\&. For example, here is the format of the \f3-printcert\fR command:
++.sp
++.nf
++\f3keytool \-printcert {\-file \fIcert_file\fR} {\-v}\fP
++.fi
++.sp
+
+-\f3keytool -printcert {-file cert_file} {-v}\fR
+
+-When you specify a \f3-printcert\fR command, replace \f3cert_file\fR with the actual file name, as follows: \f3keytool -printcert -file VScert\&.cer\fR
++
++
++When you specify a \f3-printcert\fR command, replace \fIcert_file\fR with the actual file name, as follows: \f3keytool -printcert -file VScert\&.cer\fR
+ .TP 0.2i
+ \(bu
+ Option values must be put in quotation marks when they contain a blank (space)\&.
+@@ -385,10 +391,39 @@
+ .PP
+ \fINote:\fR Users should be aware that some combinations of extensions (and other certificate fields) may not conform to the Internet standard\&. See Certificate Conformance Warning\&.
+ .SH COMMANDS
+-.TP
++.TP
+ -gencert
+-.br
+-\f3{-rfc} {-infile infile} {-outfile outfile} {-alias alias} {-sigalg sigalg} {-dname dname} {-startdate startdate {-ext ext}* {-validity valDays} [-keypass keypass] {-keystore keystore} [-storepass storepass] {-storetype storetype} {-providername provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-rfc} {\-infile \fIinfile\fR} {\-outfile \fIoutfile\fR} {\-alias \fIalias\fR} {\-sigalg \fIsigalg\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-dname \fIdname\fR} {\-startdate \fIstartdate\fR {\-ext \fIext\fR}* {\-validity \fIvalDays\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-keypass \fIkeypass\fR] {\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-storetype \fIstoretype\fR} {\-providername \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Generates a certificate as a response to a certificate request file (which can be created by the \f3keytool\fR\f3-certreq\fR command)\&. The command reads the request from \fIinfile\fR (if omitted, from the standard input), signs it using alias\&'s private key, and outputs the X\&.509 certificate into \fIoutfile\fR (if omitted, to the standard output)\&. When\f3-rfc\fR is specified, the output format is Base64-encoded PEM; otherwise, a binary DER is created\&.
+
+@@ -459,10 +494,39 @@
+ .fi
+ .sp
+
+-.TP
++.TP
+ -genkeypair
+-.br
+-\f3{-alias alias} {-keyalg keyalg} {-keysize keysize} {-sigalg sigalg} [-dname dname] [-keypass keypass] {-startdate value} {-ext ext}* {-validity valDays} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-keyalg \fIkeyalg\fR} {\-keysize \fIkeysize\fR} {\-sigalg \fIsigalg\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-dname \fIdname\fR] [\-keypass \fIkeypass\fR] {\-startdate \fIvalue\fR} {\-ext \fIext\fR}*\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-validity \fIvalDays\fR} {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Generates a key pair (a public key and associated private key)\&. Wraps the public key into an X\&.509 v3 self-signed certificate, which is stored as a single-element certificate chain\&. This certificate chain and the private key are stored in a new keystore entry identified by alias\&.
+
+@@ -510,18 +574,61 @@
+ The value of \f3valDays\fR specifies the number of days (starting at the date specified by \f3-startdate\fR, or the current date when \f3-startdate\fR is not specified) for which the certificate should be considered valid\&.
+
+ This command was named \f3-genkey\fR in earlier releases\&. The old name is still supported in this release\&. The new name, \f3-genkeypair\fR, is preferred going forward\&.
+-.TP
++.TP
+ -genseckey
+-.br
+-\f3-genseckey {-alias alias} {-keyalg keyalg} {-keysize keysize} [-keypass keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-keyalg \fIkeyalg\fR} {\-keysize \fIkeysize\fR} [\-keypass \fIkeypass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}} {\-v}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Generates a secret key and stores it in a new \f3KeyStore\&.SecretKeyEntry\fR identified by \f3alias\fR\&.
+
+ The value of \f3keyalg\fR specifies the algorithm to be used to generate the secret key, and the value of \f3keysize\fR specifies the size of the key to be generated\&. The \f3keypass\fR value is a password that protects the secret key\&. If no password is provided, then the user is prompted for it\&. If you press the Return key at the prompt, then the key password is set to the same password that is used for the \f3keystore\fR\&. The \f3keypass\fR value must be at least 6 characters\&.
+-.TP
++.TP
+ -importcert
+-.br
+-\f3-importcert {-alias alias} {-file cert_file} [-keypass keypass] {-noprompt} {-trustcacerts} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-file \fIcert_file\fR} [\-keypass \fIkeypass\fR] {\-noprompt} {\-trustcacerts}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Reads the certificate or certificate chain (where the latter is supplied in a PKCS#7 formatted reply or a sequence of X\&.509 certificates) from the file \f3cert_file\fR, and stores it in the \f3keystore\fR entry identified by \f3alias\fR\&. If no file is specified, then the certificate or certificate chain is read from \f3stdin\fR\&.
+
+@@ -530,16 +637,74 @@
+ You import a certificate for two reasons: To add it to the list of trusted certificates, and to import a certificate reply received from a certificate authority (CA) as the result of submitting a Certificate Signing Request to that CA (see the \f3-certreq\fR option in Commands)\&.
+
+ Which type of import is intended is indicated by the value of the \f3-alias\fR option\&. If the alias does not point to a key entry, then the \f3keytool\fR command assumes you are adding a trusted certificate entry\&. In this case, the alias should not already exist in the keystore\&. If the alias does already exist, then the \f3keytool\fR command outputs an error because there is already a trusted certificate for that alias, and does not import the certificate\&. If the alias points to a key entry, then the \f3keytool\fR command assumes you are importing a certificate reply\&.
+-.TP
++.TP
+ -importpassword
+-.br
+-\f3{-alias alias} [-keypass keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} [\-keypass \fIkeypass\fR] {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Imports a passphrase and stores it in a new \f3KeyStore\&.SecretKeyEntry\fR identified by \f3alias\fR\&. The passphrase may be supplied via the standard input stream; otherwise the user is prompted for it\&. \f3keypass\fR is a password used to protect the imported passphrase\&. If no password is provided, the user is prompted for it\&. If you press the Return key at the prompt, the key password is set to the same password as that used for the \f3keystore\fR\&. \f3keypass\fR must be at least 6 characters long\&.
+-.TP
++.TP
+ -importkeystore
+-.br
+-\f3{-srcstoretype srcstoretype} {-deststoretype deststoretype} [-srcstorepass srcstorepass] [-deststorepass deststorepass] {-srcprotected} {-destprotected} {-srcalias srcalias {-destalias destalias} [-srckeypass srckeypass] } [-destkeypass destkeypass] {-noprompt} {-srcProviderName src_provider_name} {-destProviderName dest_provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-srcstoretype \fIsrcstoretype\fR} {\-deststoretype \fIdeststoretype\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-srcstorepass \fIsrcstorepass\fR] [\-deststorepass \fIdeststorepass\fR] {\-srcprotected}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-destprotected} \fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-srcalias \fIsrcalias\fR {\-destalias \fIdestalias\fR} [\-srckeypass \fIsrckeypass\fR]} \fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-destkeypass \fIdestkeypass\fR] {\-noprompt}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-srcProviderName \fIsrc_provider_name\fR} {\-destProviderName \fIdest_provider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}} {\-v}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Imports a single entry or all entries from a source keystore to a destination keystore\&.
+
+@@ -550,16 +715,44 @@
+ If the destination alias already exists in the destination keystore, then the user is prompted to either overwrite the entry or to create a new entry under a different alias name\&.
+
+ If the \f3-noprompt\fR option is provided, then the user is not prompted for a new destination alias\&. Existing entries are overwritten with the destination alias name\&. Entries that cannot be imported are skipped and a warning is displayed\&.
+-.TP
++.TP
+ -printcertreq
+-.br
+-\f3{-file file}\fR
++.sp
++.nf
++\f3{\-file \fIfile\fR}\fP
++.fi
++.sp
++
+
+ Prints the content of a PKCS #10 format certificate request, which can be generated by the \f3keytool\fR\f3-certreq\fR command\&. The command reads the request from file\&. If there is no file, then the request is read from the standard input\&.
+-.TP
++.TP
+ -certreq
+-.br
+-\f3{-alias alias} {-dname dname} {-sigalg sigalg} {-file certreq_file} [-keypass keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-dname \fIdname\fR} {\-sigalg \fIsigalg\fR} {\-file \fIcertreq_file\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-keypass \fIkeypass\fR] {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-storepass \fIstorepass\fR] {\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Generates a Certificate Signing Request (CSR) using the PKCS #10 format\&.
+
+@@ -572,10 +765,29 @@
+ The CSR is stored in the file certreq_file\&. If no file is specified, then the CSR is output to \f3stdout\fR\&.
+
+ Use the \f3importcert\fR command to import the response from the CA\&.
+-.TP
++.TP
+ -exportcert
+-.br
+-\f3{-alias alias} {-file cert_file} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-rfc} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-file \fIcert_file\fR} {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-storepass \fIstorepass\fR] {\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-rfc} {\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Reads from the keystore the certificate associated with \fIalias\fR and stores it in the cert_file file\&. When no file is specified, the certificate is output to \f3stdout\fR\&.
+
+@@ -584,20 +796,48 @@
+ If \f3alias\fR refers to a trusted certificate, then that certificate is output\&. Otherwise, \f3alias\fR refers to a key entry with an associated certificate chain\&. In that case, the first certificate in the chain is returned\&. This certificate authenticates the public key of the entity addressed by \f3alias\fR\&.
+
+ This command was named \f3-export\fR in earlier releases\&. The old name is still supported in this release\&. The new name, \f3-exportcert\fR, is preferred going forward\&.
+-.TP
++.TP
+ -list
+-.br
+-\f3{-alias alias} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v | -rfc} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v | \-rfc} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Prints to \f3stdout\fR the contents of the keystore entry identified by \f3alias\fR\&. If no \f3alias\fR is specified, then the contents of the entire keystore are printed\&.
+
+ This command by default prints the SHA1 fingerprint of a certificate\&. If the \f3-v\fR option is specified, then the certificate is printed in human-readable format, with additional information such as the owner, issuer, serial number, and any extensions\&. If the \f3-rfc\fR option is specified, then the certificate contents are printed using the printable encoding format, as defined by the Internet RFC 1421 Certificate Encoding Standard\&.
+
+ You cannot specify both \f3-v\fR and \f3-rfc\fR\&.
+-.TP
++.TP
+ -printcert
+-.br
+-\f3{-file cert_file | -sslserver host[:port]} {-jarfile JAR_file {-rfc} {-v} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-file \fIcert_file\fR | \-sslserver \fIhost\fR[:\fIport\fR]} {\-jarfile \fIJAR_file\fR {\-rfc} {\-v}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Reads the certificate from the file cert_file, the SSL server located at host:port, or the signed JAR file \f3JAR_file\fR (with the \f3-jarfile\fR option and prints its contents in a human-readable format\&. When no port is specified, the standard HTTPS port 443 is assumed\&. Note that \f3-sslserver\fR and -file options cannot be provided at the same time\&. Otherwise, an error is reported\&. If neither option is specified, then the certificate is read from \f3stdin\fR\&.
+
+@@ -608,40 +848,120 @@
+ If the SSL server is behind a firewall, then the \f3-J-Dhttps\&.proxyHost=proxyhost\fR and \f3-J-Dhttps\&.proxyPort=proxyport\fR options can be specified on the command line for proxy tunneling\&. See Java Secure Socket Extension (JSSE) Reference Guide at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide\&.html
+
+ \fINote:\fR This option can be used independently of a keystore\&.
+-.TP
++.TP
+ -printcrl
+-.br
+-\f3-file crl_ {-v}\fR
++.sp
++.nf
++\f3\-file \fIcrl_\fR {\-v}\fP
++.fi
++.sp
++
+
+ Reads the Certificate Revocation List (CRL) from the file \f3crl_\fR\&. A CRL is a list of digital certificates that were revoked by the CA that issued them\&. The CA generates the \f3crl_\fR file\&.
+
+ \fINote:\fR This option can be used independently of a keystore\&.
+-.TP
++.TP
+ -storepasswd
+-.br
+-\f3[-new new_storepass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-Jjavaoption}\fR
++.sp
++.nf
++\f3[\-new \fInew_storepass\fR] {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-storepass \fIstorepass\fR] {\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Changes the password used to protect the integrity of the keystore contents\&. The new password is \f3new_storepass\fR, which must be at least 6 characters\&.
+-.TP
++.TP
+ -keypasswd
+-.br
+-\f3{-alias alias} [-keypass old_keypass] [-new new_keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} [\-keypass \fIold_keypass\fR] [\-new \fInew_keypass\fR] {\-storetype \fIstoretype\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR] {\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}} {\-v}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Changes the password under which the private/secret key identified by \f3alias\fR is protected, from \f3old_keypass\fR to \f3new_keypass\fR, which must be at least 6 characters\&.
+
+ If the \f3-keypass\fR option is not provided at the command line, and the key password is different from the keystore password, then the user is prompted for it\&.
+
+ If the \f3-new\fR option is not provided at the command line, then the user is prompted for it
+-.TP
++.TP
+ -delete
+-.br
+-\f3[-alias alias] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3[\-alias \fIalias\fR] {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerName \fIprovider_name\fR} \fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Deletes from the keystore the entry identified by \f3alias\fR\&. The user is prompted for the alias, when no alias is provided at the command line\&.
+-.TP
++.TP
+ -changealias
+-.br
+-\f3{-alias alias} [-destalias destalias] [-keypass keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} [\-destalias \fIdestalias\fR] [\-keypass \fIkeypass\fR] {\-storetype \fIstoretype\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR] {\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}} {\-v}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Move an existing keystore entry from the specified \f3alias\fR to a new alias, \f3destalias\fR\&. If no destination alias is provided, then the command prompts for one\&. If the original entry is protected with an entry password, then the password can be supplied with the \f3-keypass\fR option\&. If no key password is provided, then the \f3storepass\fR (if provided) is attempted first\&. If the attempt fails, then the user is prompted for a password\&.
+ .TP
+--- ./jdk/src/bsd/doc/man/policytool.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/bsd/doc/man/policytool.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ '\" t
+-.\" Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
++.\" Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ .\"
+ .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ .\"
+@@ -23,12 +23,12 @@
+ .\"
+ .\" Arch: generic
+ .\" Software: JDK 8
+-.\" Date: 21 November 2013
++.\" Date: 03 March 2015
+ .\" SectDesc: Security Tools
+ .\" Title: policytool.1
+ .\"
+ .if n .pl 99999
+-.TH policytool 1 "21 November 2013" "JDK 8" "Security Tools"
++.TH policytool 1 "03 March 2015" "JDK 8" "Security Tools"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -80,7 +80,7 @@
+ Run the \f3policytool\fR command and load the specified file:
+ .sp
+ .nf
+-\f3policytool\-file mypolicyfile\fP
++\f3policytool \-file \fImypolicyfile\fR\fP
+ .fi
+ .nf
+ \f3\fP
+--- ./jdk/src/linux/doc/man/ja/appletviewer.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/appletviewer.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "appletviewer" "1" "2013ǯ11·î21Æü" "JDK 8" "´ðËܥġ¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/extcheck.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/extcheck.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "extcheck" "1" "2013ǯ11·î21Æü" "JDK 8" "´ðËܥġ¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/idlj.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/idlj.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "idlj" "1" "2013ǯ11·î21Æü" "JDK 8" "Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/jar.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jar.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jar" "1" "2013ǯ11·î21Æü" "JDK 8" "´ðËܥġ¼¥ë"
+@@ -384,9 +385,7 @@
+ .\}
+ .SH "Îã"
+ .PP
+-\fBÎã 1\fR
+-.br
+-¾éĹ¤Ê½ÐÎϤˤè¤ë¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤ÎÄɲÃ
++\fBÎã 1 \fR¾éĹ¤Ê½ÐÎϤˤè¤ë¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤ÎÄɲÃ
+ .RS 4
+ .sp
+ .if n \{\
+@@ -415,9 +414,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î¥Õ¥¡¥¤¥ë¤ÎÄɲÃ
++\fBÎã 2 \fR¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î¥Õ¥¡¥¤¥ë¤ÎÄɲÃ
+ .RS 4
+ .sp
+ .if n \{\
+@@ -449,9 +446,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 3\fR
+-.br
+-JAR¤Î¥³¥ó¥Æ¥ó¥Ä¤Î¥ê¥¹¥È
++\fBÎã 3 \fRJAR¤Î¥³¥ó¥Æ¥ó¥Ä¤Î¥ê¥¹¥È
+ .RS 4
+ .sp
+ .if n \{\
+@@ -485,9 +480,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 4\fR
+-.br
+-º÷°ú¤ÎÄɲÃ
++\fBÎã 4 \fRº÷°ú¤ÎÄɲÃ
+ .RS 4
+ ³ô¼°¼è°ú¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÎÁê¸ß°Í¸¥¯¥é¥¹¤ò¡¢\fBmain\&.jar\fR¡¢\fBbuy\&.jar\fR¤ª¤è¤Ó\fBsell\&.jar\fR¤Î3¤Ä¤ÎJAR¥Õ¥¡¥¤¥ë¤Ëʬ³ä¤¹¤ë¾ì¹ç¡¢\fBi\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Þ¤¹¡£\fBmain\&.jar\fR¥Þ¥Ë¥Õ¥§¥¹¥ÈÆâ¤Î\fBClass\-Path\fR°À­¤ò»ØÄꤹ¤ë¾ì¹ç¡¢\fBi\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¥¯¥é¥¹¡¦¥í¡¼¥É¤Î®ÅÙ¤ò¸þ¾å¤Ç¤­¤Þ¤¹¡£
+ .sp
+--- ./jdk/src/linux/doc/man/ja/jarsigner.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jarsigner.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jarsigner" "1" "2013ǯ11·î21Æü" "JDK 8" "¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë"
+@@ -344,7 +345,7 @@
+ .PP
+ ¤³¤ì¤é2¤Ä¤Î¥Õ¥¡¥¤¥ë¤Î¥Ù¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾¤Ï¡¢\fB\-sigFile\fR¥ª¥×¥·¥ç¥ó¤ÎÃͤ«¤éºîÀ®¤µ¤ì¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¥ª¥×¥·¥ç¥ó¤¬\fB\-sigFile MKSIGN\fR¤Î¾ì¹ç¡¢¥Õ¥¡¥¤¥ë¤Ï\fBMKSIGN\&.SF\fR¤ª¤è¤Ó\fBMKSIGN\&.DSA\fR¤È¤¤¤¦Ì¾Á°¤Ë¤Ê¤ê¤Þ¤¹¡£
+ .PP
+-¥³¥Þ¥ó¥É¹Ô¤Ç\fB\-sigfile\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¡¢\fB\&.SF\fR¥Õ¥¡¥¤¥ë¤È\fB\&.DSA\fR¥Õ¥¡¥¤¥ë¤Î¥Ù¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤵ¤ì¤¿ÊÌ̾¤ÎÀèƬ¤Î8ʸ»ú¤ò¤¹¤Ù¤ÆÂçʸ»ú¤ËÊÑ´¹¤·¤¿¤â¤Î¤Ë¤Ê¤ê¤Þ¤¹¡£ÊÌ̾¤¬8ʸ»ṳ́Ëþ¤Î¾ì¹ç¤Ï¡¢ÊÌ̾¤¬¤½¤Î¤Þ¤Þ»ÈÍѤµ¤ì¤Þ¤¹¡£ÊÌ̾¤Ë¡¢½ð̾¥Õ¥¡¥¤¥ë̾¤Ç»ÈÍѤǤ­¤Ê¤¤Ê¸»ú¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥Õ¥¡¥¤¥ë̾¤ÎºîÀ®»þ¤Ë¡¢³ºÅö¤¹¤ëʸ»ú¤¬²¼Àþ(_)ʸ»ú¤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£Í­¸ú¤Êʸ»ú¤Ï¡¢¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¡¢¿ô»ú¡¢²¼Àþ¤ª¤è¤Ó¥Ï¥¤¥Õ¥ó¤Ç¤¹¡£
++¥³¥Þ¥ó¥É¹Ô¤Ç\fB\-sigfile\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¡¢\fB\&.SF\fR¥Õ¥¡¥¤¥ë¤È\fB\&.DSA\fR¥Õ¥¡¥¤¥ë¤Î¥Ù¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤵ¤ì¤¿ÊÌ̾¤ÎÀèƬ¤Î8ʸ»ú¤ò¤¹¤Ù¤ÆÂçʸ»ú¤ËÊÑ´¹¤·¤¿¤â¤Î¤Ë¤Ê¤ê¤Þ¤¹¡£ÊÌ̾¤¬8ʸ»ṳ́Ëþ¤Î¾ì¹ç¤Ï¡¢ÊÌ̾¤¬¤½¤Î¤Þ¤Þ»ÈÍѤµ¤ì¤Þ¤¹¡£ÊÌ̾¤Ë¡¢½ð̾¥Õ¥¡¥¤¥ë̾¤Ç»ÈÍѤǤ­¤Ê¤¤Ê¸»ú¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥Õ¥¡¥¤¥ë̾¤ÎºîÀ®»þ¤Ë¡¢³ºÅö¤¹¤ëʸ»ú¤¬¥¢¥ó¥À¡¼¥¹¥³¥¢(_)ʸ»ú¤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£Í­¸ú¤Êʸ»ú¤Ï¡¢¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¡¢¿ô»ú¡¢¥¢¥ó¥À¡¼¥¹¥³¥¢¤ª¤è¤Ó¥Ï¥¤¥Õ¥ó¤Ç¤¹¡£
+ .PP
+ ½ð̾¥Õ¥¡¥¤¥ë
+ .PP
+@@ -521,7 +522,7 @@
+ .sp -1
+ .IP \(bu 2.3
+ .\}
+-¥¤¥¿¥ê¥Ã¥¯ÂΤޤ¿¤Ï²¼ÀþÉÕ¤­¤Î¹àÌÜ(¥ª¥×¥·¥ç¥ó¤ÎÃÍ)¤Î¼ÂºÝ¤ÎÃͤϡ¢»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
++¥¤¥¿¥ê¥Ã¥¯¤Þ¤¿¤Ï²¼ÀþÉÕ¤­¤Î¹àÌÜ(¥ª¥×¥·¥ç¥ó¤ÎÃÍ)¤Î¼ÂºÝ¤ÎÃͤϡ¢»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .sp
+ .RS 4
+@@ -664,9 +665,9 @@
+ .RS 4
+ À¸À®¤µ¤ì¤¿\fB\&.SF\fR¥Õ¥¡¥¤¥ë¤ª¤è¤Ó\fB\&.DSA\fR¥Õ¥¡¥¤¥ë¤Ë»ÈÍѤ¹¤ë¥Ù¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾¤ò»ØÄꤷ¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¥Õ¥¡¥¤¥ë¤¬\fBDUKESIGN\fR¤Î¾ì¹ç¡¢À¸À®¤µ¤ì¤ë\fB\&.SF\fR¤ª¤è¤Ó\fB\&.DSA\fR¥Õ¥¡¥¤¥ë¤Ï¡¢\fBDUKESIGN\&.SF\fR¤ª¤è¤Ó\fBDUKESIGN\&.DSA\fR¤È¤¤¤¦Ì¾Á°¤Ç¡¢½ð̾ÉÕ¤­JAR¥Õ¥¡¥¤¥ë¤Î\fBMETA\-INF\fR¥Ç¥£¥ì¥¯¥È¥ê¤Ë³ÊǼ¤µ¤ì¤Þ¤¹¡£
+ .sp
+-¥Õ¥¡¥¤¥ëÆâ¤Îʸ»ú¤Ï¡¢¥»¥Ã¥È\fBa\-zA\-Z0\-9_\-\fR¤«¤é»ØÄꤵ¤ì¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¡¢¿ô»ú¡¢²¼Àþ¤ª¤è¤Ó¥Ï¥¤¥Õ¥óʸ»ú¤Î¤ß¤ò»ÈÍѤǤ­¤Þ¤¹¡£\fB\&.SF\fR¤ª¤è¤Ó\fB\&.DSA\fR¤Î¥Õ¥¡¥¤¥ë̾¤Ç¤Ï¡¢¾®Ê¸»ú¤Ï¤¹¤Ù¤ÆÂçʸ»ú¤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£
++¥Õ¥¡¥¤¥ëÆâ¤Îʸ»ú¤Ï¡¢¥»¥Ã¥È\fBa\-zA\-Z0\-9_\-\fR¤«¤é»ØÄꤵ¤ì¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¡¢¿ô»ú¡¢¥¢¥ó¥À¡¼¥¹¥³¥¢¤ª¤è¤Ó¥Ï¥¤¥Õ¥óʸ»ú¤Î¤ß¤ò»ÈÍѤǤ­¤Þ¤¹¡£\fB\&.SF\fR¤ª¤è¤Ó\fB\&.DSA\fR¤Î¥Õ¥¡¥¤¥ë̾¤Ç¤Ï¡¢¾®Ê¸»ú¤Ï¤¹¤Ù¤ÆÂçʸ»ú¤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£
+ .sp
+-¥³¥Þ¥ó¥É¹Ô¤Ç\fB\-sigfile\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¡¢\fB\&.SF\fR¥Õ¥¡¥¤¥ë¤È\fB\&.DSA\fR¥Õ¥¡¥¤¥ë¤Î¥Ù¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤵ¤ì¤¿ÊÌ̾¤ÎÀèƬ¤Î8ʸ»ú¤ò¤¹¤Ù¤ÆÂçʸ»ú¤ËÊÑ´¹¤·¤¿¤â¤Î¤Ë¤Ê¤ê¤Þ¤¹¡£ÊÌ̾¤¬8ʸ»ṳ́Ëþ¤Î¾ì¹ç¤Ï¡¢ÊÌ̾¤¬¤½¤Î¤Þ¤Þ»ÈÍѤµ¤ì¤Þ¤¹¡£ÊÌ̾¤Ë¡¢½ð̾¥Õ¥¡¥¤¥ë̾¤Ç̵¸ú¤Êʸ»ú¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥Õ¥¡¥¤¥ë̾¤òºîÀ®¤¹¤ë¤¿¤á¤Ë¡¢³ºÅö¤¹¤ëʸ»ú¤¬²¼Àþ(_)ʸ»ú¤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£
++¥³¥Þ¥ó¥É¹Ô¤Ç\fB\-sigfile\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¡¢\fB\&.SF\fR¥Õ¥¡¥¤¥ë¤È\fB\&.DSA\fR¥Õ¥¡¥¤¥ë¤Î¥Ù¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤵ¤ì¤¿ÊÌ̾¤ÎÀèƬ¤Î8ʸ»ú¤ò¤¹¤Ù¤ÆÂçʸ»ú¤ËÊÑ´¹¤·¤¿¤â¤Î¤Ë¤Ê¤ê¤Þ¤¹¡£ÊÌ̾¤¬8ʸ»ṳ́Ëþ¤Î¾ì¹ç¤Ï¡¢ÊÌ̾¤¬¤½¤Î¤Þ¤Þ»ÈÍѤµ¤ì¤Þ¤¹¡£ÊÌ̾¤Ë¡¢½ð̾¥Õ¥¡¥¤¥ë̾¤Ç̵¸ú¤Êʸ»ú¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥Õ¥¡¥¤¥ë̾¤òºîÀ®¤¹¤ë¤¿¤á¤Ë¡¢³ºÅö¤¹¤ëʸ»ú¤¬¥¢¥ó¥À¡¼¥¹¥³¥¢(_)ʸ»ú¤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ \-sigalg \fIalgorithm\fR
+@@ -1001,7 +1002,7 @@
+ .RE
+ .\}
+ .PP
+-¸¡¾Ú¤¬À®¸ù¤¹¤ë¤È¡¢\fBjar verified\fR¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£¤½¤¦¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢¥¨¥é¡¼¡¦¥á¥Ã¥»¡¼¥¸¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£\fB\-verbose\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤È¡¢¾ÜºÙ¾ðÊó¤ò¼èÆÀ¤Ç¤­¤Þ¤¹¡£\fBjarsigner\fR¤ò\fB\-verbose\fR¥ª¥×¥·¥ç¥ó¤È¤È¤â¤Ë»ÈÍѤ¹¤ë¥µ¥ó¥×¥ë¤ò¡¢¼¡¤Ë¼¨¤·¤Þ¤¹¡£
++¸¡¾Ú¤¬À®¸ù¤¹¤ë¤È¡¢\fBjar verified\fR¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£Í­¸ú¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢¥¨¥é¡¼¡¦¥á¥Ã¥»¡¼¥¸¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£\fB\-verbose\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤È¡¢¾ÜºÙ¾ðÊó¤ò¼èÆÀ¤Ç¤­¤Þ¤¹¡£\fBjarsigner\fR¤ò\fB\-verbose\fR¥ª¥×¥·¥ç¥ó¤È¤È¤â¤Ë»ÈÍѤ¹¤ë¥µ¥ó¥×¥ë¤ò¡¢¼¡¤Ë¼¨¤·¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+--- ./jdk/src/linux/doc/man/ja/java.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/java.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: java
+ .\" Language: Japanese
+-.\" Date: 2014ǯ8·î8Æü
++.\" Date: 2015ǯ3·î3Æü
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "java" "1" "2014ǯ8·î8Æü" "JDK 8" "´ðËܥġ¼¥ë"
++.TH "java" "1" "2015ǯ3·î3Æü" "JDK 8" "´ðËܥġ¼¥ë"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -652,7 +653,7 @@
+ .PP
+ \-Xmx\fIsize\fR
+ .RS 4
+-¥á¥â¥ê¡¼³äÅö¤Æ¥×¡¼¥ë¤ÎºÇÂ祵¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤ò»ØÄꤷ¤Þ¤¹¡£»ØÄꤹ¤ëÃͤϡ¢2MB¤è¤êÂ礭¤¤1024¤ÎÇÜ¿ô¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢¼Â¹Ô»þ¤Ë¥·¥¹¥Æ¥à¹½À®¤Ë´ð¤Å¤¤¤ÆÁªÂò¤µ¤ì¤Þ¤¹¡£¥µ¡¼¥Ð¡¼¡¦¥Ç¥×¥í¥¤¥á¥ó¥È¤Ç¤Ï¡¢\fB\-Xms\fR¤ª¤è¤Ó\fB\-Xmx\fR¤ÏÄ̾ïƱ¤¸ÃͤËÀßÄꤵ¤ì¤Þ¤¹¡£¾ÜºÙ¤Ï¡¢http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gc\-ergonomics\&.html¤Ë¤¢¤ë¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥¿¡¦¥¨¥ë¥´¥Î¥ß¥Ã¥¯¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++¥á¥â¥ê¡¼³äÅö¤Æ¥×¡¼¥ë¤ÎºÇÂ祵¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤ò»ØÄꤷ¤Þ¤¹¡£»ØÄꤹ¤ëÃͤϡ¢2MB¤è¤êÂ礭¤¤1024¤ÎÇÜ¿ô¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢¼Â¹Ô»þ¤Ë¥·¥¹¥Æ¥à¹½À®¤Ë´ð¤Å¤¤¤ÆÁªÂò¤µ¤ì¤Þ¤¹¡£¥µ¡¼¥Ð¡¼¡¦¥Ç¥×¥í¥¤¥á¥ó¥È¤Ç¤Ï¡¢\fB\-Xms\fR¤ª¤è¤Ó\fB\-Xmx\fR¤ÏÄ̾ïƱ¤¸ÃͤËÀßÄꤵ¤ì¤Þ¤¹¡£http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gctuning/index\&.html¤Î\fIJava SE HotSpot²¾ÁÛ¥Þ¥·¥ó¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¡¦¥Á¥å¡¼¥Ë¥ó¥°¡¦¥¬¥¤¥É\fR¤Î¥¨¥ë¥´¥Î¥ß¥¯¥¹¤Ë´Ø¤¹¤ë¹à¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ ¼¡¤ÎÎã¤Ç¤Ï¡¢³ä¤êÅö¤Æ¤é¤ì¤¿¥á¥â¥ê¡¼¤Îµö²Ä¤µ¤ì¤ëºÇÂ祵¥¤¥º¤òÍÍ¡¹¤Êñ°Ì¤ò»ÈÍѤ·¤Æ80MB¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
+ .sp
+@@ -877,14 +878,14 @@
+ .RS 4
+ ¥Ð¥¤¥È¥³¡¼¥É¡¦¥Ù¥ê¥Õ¥¡¥¤¥¢¤Î¥â¡¼¥É¤òÀßÄꤷ¤Þ¤¹¡£¥Ð¥¤¥È¥³¡¼¥É¤Î¸¡¾Ú¤Ï°ìÉô¤ÎÌäÂê¤Î¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¤ËÌòΩ¤Á¤Þ¤¹¤¬¡¢¼Â¹ÔÃæ¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ø¤Î¥ª¡¼¥Ð¡¼¥Ø¥Ã¥É¤òÁýÂ礵¤»¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ç»ÈÍѲÄǽ¤Ê\fImode\fR°ú¿ô¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹¡£
+ .PP
+-none
++¤Ê¤·
+ .RS 4
+ ¥Ð¥¤¥È¥³¡¼¥É¤ò¸¡¾Ú¤·¤Þ¤»¤ó¡£¤³¤ì¤Ë¤è¤ê¡¢µ¯Æ°»þ´Ö¤¬Ã»½Ì¤µ¤ì¡¢Java¤Ë¤è¤Ã¤ÆÄ󶡤µ¤ì¤ëÊݸî¤â·Ú¸º¤µ¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ remote
+ .RS 4
+-¥Í¥Ã¥È¥ï¡¼¥¯¤ò²ð¤·¤Æ¥ê¥â¡¼¥È¤Ç¥í¡¼¥É¤µ¤ì¤ë¥¯¥é¥¹¤Î¤ß¤ò¸¡¾Ú¤·¤Þ¤¹¡£¤³¤ì¤Ï¡¢\fB\-Xverify\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤¤¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¤ÎÆ°ºî¤Ç¤¹¡£
++¥Ö¡¼¥È¥¹¥È¥é¥Ã¥×¡¦¥¯¥é¥¹¡¦¥í¡¼¥À¡¼¤Ç¥í¡¼¥É¤µ¤ì¤Æ¤¤¤Ê¤¤¤³¤ì¤é¤Î¥¯¥é¥¹¤ò¸¡¾Ú¤·¤Þ¤¹¡£¤³¤ì¤Ï¡¢\fB\-Xverify\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤¤¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¤ÎÆ°ºî¤Ç¤¹¡£
+ .RE
+ .PP
+ all
+@@ -938,9 +939,9 @@
+ .PP
+ \-XX:LargePageSizeInBytes=\fIsize\fR
+ .RS 4
+-Java¥Ò¡¼¥×¤Ë»ÈÍѤµ¤ì¤ëÂ礭¤¤¥Ú¡¼¥¸¤ÎºÇÂ祵¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£\fIsize\fR°ú¿ô¤Ï¡¢2¤ÎÎß¾è(2¡¢4¡¢8¡¢16¡¢\&.\&.\&.)¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥µ¥¤¥º¤Ï0¤ËÀßÄꤵ¤ì¡¢¤³¤ì¤Ï¡¢JVM¤Ç¤ÏÂ礭¤¤¥Ú¡¼¥¸¤Î¥µ¥¤¥º¤¬¼«Æ°Åª¤ËÁªÂò¤µ¤ì¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£
++Solaris¤Ç¤Ï¡¢Java¥Ò¡¼¥×¤Ë»ÈÍѤµ¤ì¤ë¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ÎºÇÂ祵¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£\fIsize\fR°ú¿ô¤Ï¡¢2¤ÎÎß¾è(2¡¢4¡¢8¡¢16¡¢\&.\&.\&.)¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥µ¥¤¥º¤Ï0¤ËÀßÄꤵ¤ì¡¢¤³¤ì¤Ï¡¢JVM¤Ç¤Ï¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¥µ¥¤¥º¤¬¼«Æ°Åª¤ËÁªÂò¤µ¤ì¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£
+ .sp
+-¼¡¤ÎÎã¤Ç¤Ï¡¢Â礭¤¤¥Ú¡¼¥¸¤Î¥µ¥¤¥º¤ò4¥á¥¬¥Ð¥¤¥È(MB)¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
++¼¡¤ÎÎã¤Ç¤Ï¡¢¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¥µ¥¤¥º¤ò4¥á¥¬¥Ð¥¤¥È(MB)¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+@@ -995,6 +996,17 @@
+ .RE
+ .RE
+ .PP
++\-XX:ObjectAlignmentInBytes=\fIalignment\fR
++.RS 4
++Java¥ª¥Ö¥¸¥§¥¯¥È¤Î¥á¥â¥ê¡¼ÇÛÃÖ¤òÀßÄꤷ¤Þ¤¹(¥Ð¥¤¥Èñ°Ì)¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢Ãͤ¬8¥Ð¥¤¥È¤ËÀßÄꤵ¤ì¤Þ¤¹¡£»ØÄꤵ¤ì¤ëÃͤϡ¢2¤ÎÎß¾è¤Ë¤·¤Æ8¤«¤é256(ξü¤ò´Þ¤à)¤ÎÈÏ°ÏÆâ¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¡¢Â礭¤¤Java¥Ò¡¼¥×¡¦¥µ¥¤¥º¤Ç°µ½Ì¥Ý¥¤¥ó¥¿¤ò»ÈÍѤǤ­¤Þ¤¹¡£
++.sp
++¥Ð¥¤¥Èñ°Ì¤Î¥Ò¡¼¥×¡¦¥µ¥¤¥ºÀ©¸Â¤Ï¼¡¤Î¤è¤¦¤Ë·×»»¤µ¤ì¤Þ¤¹:
++.sp
++\fB4GB * ObjectAlignmentInBytes\fR
++.sp
++Ãí°Õ: ÇÛÃÖ¤ÎÃͤ¬Áý¤¨¤ë¤È¡¢¥ª¥Ö¥¸¥§¥¯¥È´Ö¤Î̤»ÈÍѤÎÎΰè¤âÁý¤¨¤Þ¤¹¡£·ë²Ì¤È¤·¤Æ¡¢Â礭¤¤¥Ò¡¼¥×¡¦¥µ¥¤¥º¤Ç°µ½Ì¥Ý¥¤¥ó¥¿¤ò»ÈÍѤ¹¤ë¥á¥ê¥Ã¥È¤¬¤ï¤«¤é¤Ê¤¤²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£
++.RE
++.PP
+ \-XX:OnError=\fIstring\fR
+ .RS 4
+ ¥ê¥«¥Ð¥êÉÔǽ¤Ê¥¨¥é¡¼¤¬È¯À¸¤·¤¿¤È¤­¤Ë¼Â¹Ô¤¹¤ë¡¢¥«¥¹¥¿¥à¡¦¥³¥Þ¥ó¥É¤Þ¤¿¤Ï°ìÏ¢¤Î¥»¥ß¥³¥í¥ó¶èÀÚ¤ê¤Î¥³¥Þ¥ó¥É¤òÀßÄꤷ¤Þ¤¹¡£Ê¸»úÎó¤Ë¶õÇò¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢°úÍÑÉä¤Ç°Ï¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+@@ -1018,6 +1030,22 @@
+ \fBOutOfMemoryError\fRÎã³°¤¬ºÇ½é¤Ë¥¹¥í¡¼¤µ¤ì¤¿¤È¤­¤Ë¼Â¹Ô¤¹¤ë¡¢¥«¥¹¥¿¥à¡¦¥³¥Þ¥ó¥É¤Þ¤¿¤Ï°ìÏ¢¤Î¥»¥ß¥³¥í¥ó¶èÀÚ¤ê¤Î¥³¥Þ¥ó¥É¤òÀßÄꤷ¤Þ¤¹¡£Ê¸»úÎó¤Ë¶õÇò¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢°úÍÑÉä¤Ç°Ï¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥³¥Þ¥ó¥Éʸ»úÎó¤ÎÎã¤Ï¡¢\fB\-XX:OnError\fR¥ª¥×¥·¥ç¥ó¤ÎÀâÌÀ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .RE
+ .PP
++\-XX:+PerfDataSaveToFile
++.RS 4
++Í­¸ú¤Ê¾ì¹ç¡¢Java¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î½ªÎ»»þ¤Ëjstat(1)¥Ð¥¤¥Ê¥ê¡¦¥Ç¡¼¥¿¤òÊݸ¤·¤Þ¤¹¡£¤³¤Î¥Ð¥¤¥Ê¥ê¡¦¥Ç¡¼¥¿¤Ï\fBhsperfdata_\fR\fI<pid>\fR¤È¤¤¤¦Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Þ¤¹¡£\fI<pid>\fR¤Ï¡¢¼Â¹Ô¤·¤¿Java¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¥×¥í¥»¥¹¼±Ê̻ҤǤ¹¡£¼¡¤Î¤è¤¦¤Ë\fBjstat\fR¤ò»ÈÍѤ·¤Æ¡¢¤³¤Î¥Õ¥¡¥¤¥ë¤Ë´Þ¤Þ¤ì¤ë¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¡¦¥Ç¡¼¥¿¤òɽ¼¨¤·¤Þ¤¹¡£
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjstat \-class file:///\fR\fB\fI<path>\fR\fR\fB/hsperfdata_\fR\fB\fI<pid>\fR\fR
++\fBjstat \-gc file:///\fR\fB\fI<path>\fR\fR\fB/hsperfdata_\fR\fB\fI<pid>\fR\fR
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.PP
+ \-XX:+PrintCommandLineFlags
+ .RS 4
+ ¥³¥Þ¥ó¥É¹Ô¤Ëɽ¼¨¤µ¤ì¤¿¡¢¿Í´Ö¹©³ØŪ¤ËÁªÂò¤·¤¿JVM¥Õ¥é¥°¤Î°õºþ¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤ì¤Ï¡¢¥Ò¡¼¥×Îΰ襵¥¤¥º¤äÁªÂò¤µ¤ì¤¿¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥¿¤Ê¤É¡¢JVM¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤¿¥¨¥ë¥´¥Î¥ß¥Ã¥¯Ãͤò³Îǧ¤¹¤ë¾ì¹ç¤ËÌòΩ¤Á¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¢¤ê¡¢¥Õ¥é¥°¤Ï°õºþ¤µ¤ì¤Þ¤»¤ó¡£
+@@ -1166,25 +1194,32 @@
+ JVMÆâÉô¥·¥°¥Ê¥ë¤Î\fBSIGUSR1\fR¤ª¤è¤Ó\fBSIGUSR2\fR¤Î¤«¤ï¤ê¤Ë¡¢ÂåÂØ¥·¥°¥Ê¥ë¤Î»ÈÍѤòÍ­¸ú¤Ë¤·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¢¤ê¡¢ÂåÂØ¥·¥°¥Ê¥ë¤Ï»ÈÍѤµ¤ì¤Þ¤»¤ó¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï\fB\-Xusealtsigs\fR¤ÈƱÅù¤Ç¤¹¡£
+ .RE
+ .PP
+-\-XX:+UseBiasedLocking
+-.RS 4
+-¥Ð¥¤¥¢¥¹¡¦¥í¥Ã¥¯¤Î»ÈÍѤòÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤«¤Ê¤ê¤ÎÎ̤ÎÈ󶥹ç¤ÎƱ´ü²½¤¬¤¢¤ë°ìÉô¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¡¢¤³¤Î¥Õ¥é¥°¤òÍ­¸ú¤Ë¤¹¤ë¤ÈÂçÉý¤Ê¹â®²½¤¬¼Â¸½¤·¤Þ¤¹¤¬¡¢ÆÃÄê¤Î¥Ñ¥¿¡¼¥ó¤Î¥í¥Ã¥¯¤¬¤¢¤ë¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¡¢Â®ÅÙ¤¬Äã²¼¤¹¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£¥Ð¥¤¥¢¥¹¡¦¥í¥Ã¥¯¤ÎÊýË¡¤Î¾ÜºÙ¤Ï¡¢http://www\&.oracle\&.com/technetwork/java/tuning\-139912\&.html#section4\&.2\&.5¤Ë¤¢¤ëJava¥Á¥å¡¼¥Ë¥ó¥°¤Î¥Û¥ï¥¤¥È¡¦¥Ú¡¼¥Ñ¡¼¤ÎÎã¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++\-XX:\-UseBiasedLocking
++.RS 4
++¥Ð¥¤¥¢¥¹¡¦¥í¥Ã¥¯¤Î»ÈÍѤò̵¸ú¤Ë¤·¤Þ¤¹¡£¤«¤Ê¤ê¤ÎÎ̤ÎÈ󶥹ç¤ÎƱ´ü²½¤¬¤¢¤ë°ìÉô¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¡¢¤³¤Î¥Õ¥é¥°¤òÍ­¸ú¤Ë¤¹¤ë¤ÈÂçÉý¤Ê¹â®²½¤¬¼Â¸½¤·¤Þ¤¹¤¬¡¢ÆÃÄê¤Î¥Ñ¥¿¡¼¥ó¤Î¥í¥Ã¥¯¤¬¤¢¤ë¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¡¢Â®ÅÙ¤¬Äã²¼¤¹¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£¥Ð¥¤¥¢¥¹¡¦¥í¥Ã¥¯¤ÎÊýË¡¤Î¾ÜºÙ¤Ï¡¢http://www\&.oracle\&.com/technetwork/java/tuning\-139912\&.html#section4\&.2\&.5¤Ë¤¢¤ëJava¥Á¥å¡¼¥Ë¥ó¥°¤Î¥Û¥ï¥¤¥È¡¦¥Ú¡¼¥Ñ¡¼¤ÎÎã¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤ÏÍ­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£
+ .RE
+ .PP
+-\-XX:+UseCompressedOops
+-.RS 4
+-°µ½Ì¤µ¤ì¤¿¥Ý¥¤¥ó¥¿¤Î»ÈÍѤòÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤òÍ­¸ú¤Ë¤¹¤ë¤È¡¢¥ª¥Ö¥¸¥§¥¯¥È»²¾È¤Ï¡¢64¥Ó¥Ã¥È¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ï¤Ê¤¯32¥Ó¥Ã¥È¤Î¥ª¥Õ¥»¥Ã¥È¤È¤·¤Æɽ¤µ¤ì¡¢¤³¤ì¤Ë¤è¤ê¡¢32GB¤è¤ê¾®¤µ¤¤Java¥Ò¡¼¥×¡¦¥µ¥¤¥º¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¼Â¹Ô»þ¤Ë¡¢Ä̾¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤¬¸þ¾å¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢64¥Ó¥Ã¥È¤ÎJVM¤Ç¤Î¤ßµ¡Ç½¤·¤Þ¤¹¡£
++\-XX:\-UseCompressedOops
++.RS 4
++°µ½Ì¤µ¤ì¤¿¥Ý¥¤¥ó¥¿¤Î»ÈÍѤò̵¸ú¤Ë¤·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¤³¤Î¥ª¥×¥·¥ç¥ó¤¬Í­¸ú¤Ç¤¢¤ê¡¢Java¥Ò¡¼¥×¡¦¥µ¥¤¥º¤¬32GB¤è¤ê¾®¤µ¤¤¾ì¹ç¤Ë°µ½Ì¥Ý¥¤¥ó¥¿¤¬»ÈÍѤµ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤òÍ­¸ú¤Ë¤¹¤ë¤È¡¢¥ª¥Ö¥¸¥§¥¯¥È»²¾È¤Ï¡¢64¥Ó¥Ã¥È¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ï¤Ê¤¯32¥Ó¥Ã¥È¤Î¥ª¥Õ¥»¥Ã¥È¤È¤·¤Æɽ¤µ¤ì¡¢¤³¤ì¤Ë¤è¤ê¡¢32GB¤è¤ê¾®¤µ¤¤Java¥Ò¡¼¥×¡¦¥µ¥¤¥º¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¼Â¹Ô»þ¤Ë¡¢Ä̾¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤¬¸þ¾å¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢64¥Ó¥Ã¥È¤ÎJVM¤Ç¤Î¤ßµ¡Ç½¤·¤Þ¤¹¡£
+ .sp
+-¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¢¤ê¡¢°µ½Ì¥Ý¥¤¥ó¥¿¤Ï»ÈÍѤµ¤ì¤Þ¤»¤ó¡£
++Java¥Ò¡¼¥×¡¦¥µ¥¤¥º¤¬32GB¤è¤êÂ礭¤¤¾ì¹ç¤Ë¤â°µ½Ì¥Ý¥¤¥ó¥¿¤ò»ÈÍѤǤ­¤Þ¤¹¡£\fB\-XX:ObjectAlignmentInBytes\fR¥ª¥×¥·¥ç¥ó¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++.RE
++.PP
++\-XX:+UseHugeTLBFS
++.RS 4
++LinuxÍѤΤ³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢\fB\-XX:+UseLargePages\fR¤ò»ØÄꤹ¤ë¤Î¤ÈƱ¤¸¤Ç¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥á¥â¥ê¡¼¤ÎͽÌó»þ¤Ë¤¹¤Ù¤Æ¤Î¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ò»öÁ°¤Ë³ä¤êÅö¤Æ¤Þ¤¹¡£¤½¤Î¤¿¤á¡¢JVM¤Ï¥é¡¼¥¸¡¦¥Ú¡¼¥¸¡¦¥á¥â¥ê¡¼Îΰè¤òưŪ¤Ë³ÈÄ¥¤Þ¤¿¤Ï½Ì¾®¤Ç¤­¤Þ¤»¤ó¡£¤³¤ÎÆ°ºî¤ò¹Ô¤¦¾ì¹ç¤Ï¡¢\fB\-XX:UseTransparentHugePages\fR¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++.sp
++¾ÜºÙ¤Ï¡¢"¥é¡¼¥¸¡¦¥Ú¡¼¥¸"¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .RE
+ .PP
+ \-XX:+UseLargePages
+ .RS 4
+-Â礭¤¤¥Ú¡¼¥¸¤Î¥á¥â¥ê¡¼¤Î»ÈÍѤòÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Ç¥Õ¥©¥ë¥È¤ÇÍ­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£Â礭¤¤¥Ú¡¼¥¸¤Î¥á¥â¥ê¡¼¤Î»ÈÍѤò̵¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢\fB\-XX:\-UseLargePages\fR¤ò»ØÄꤷ¤Þ¤¹¡£
++¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¥á¥â¥ê¡¼¤Î»ÈÍѤòÍ­¸ú¤Ë¤·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¢¤ê¡¢¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¥á¥â¥ê¡¼¤Ï»ÈÍѤµ¤ì¤Þ¤»¤ó¡£
+ .sp
+-¾ÜºÙ¤Ï¡¢http://www\&.oracle\&.com/technetwork/java/javase/tech/largememory\-jsp\-137182\&.html¤Ë¤¢¤ëÂ礭¤¤¥á¥â¥ê¡¼¡¦¥Ú¡¼¥¸ÍѤÎJava¥µ¥Ý¡¼¥È¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++¾ÜºÙ¤Ï¡¢"¥é¡¼¥¸¡¦¥Ú¡¼¥¸"¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .RE
+ .PP
+ \-XX:+UseMembar
+@@ -1197,6 +1232,13 @@
+ \fBperfdata\fRµ¡Ç½¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Ç¥Õ¥©¥ë¥È¤ÇÍ­¸ú¤Ë¤Ê¤Ã¤Æ¤ª¤ê¡¢JVM¤Î¥â¥Ë¥¿¥ê¥ó¥°¤ª¤è¤Ó¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¡¦¥Æ¥¹¥È¤¬²Äǽ¤Ë¤Ê¤ê¤Þ¤¹¡£¤³¤ì¤ò̵¸ú¤Ë¤¹¤ë¤È¡¢\fBhsperfdata_userid\fR¥Ç¥£¥ì¥¯¥È¥ê¤ÎºîÀ®¤òÍÞÀ©¤·¤Þ¤¹¡£\fBperfdata\fRµ¡Ç½¤ò̵¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢\fB\-XX:\-UsePerfData\fR¤ò»ØÄꤷ¤Þ¤¹¡£
+ .RE
+ .PP
++\-XX:+UseTransparentHugePages
++.RS 4
++Linux¤Ç¤Ï¡¢Æ°Åª¤Ë³ÈÄ¥¤Þ¤¿¤Ï½Ì¾®¤Ç¤­¤ë¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î»ÈÍѤòÍ­¸ú²½¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£OS¤¬Â¾¤Î¥Ú¡¼¥¸¤ò°ÜÆ°¤·¤Æ¥Ò¥å¡¼¥¸¡¦¥Ú¡¼¥¸¤òºîÀ®¤¹¤ë¤¿¤á¡¢Æ©²áŪ¥Ò¥å¡¼¥¸¡¦¥Ú¡¼¥¸¤Ç¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤ÎÌäÂ꤬¸¡½Ð¤µ¤ì¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï»î¸³Åª¤Ë»ÈÍѤǤ­¤Þ¤¹¡£
++.sp
++¾ÜºÙ¤Ï¡¢"¥é¡¼¥¸¡¦¥Ú¡¼¥¸"¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++.RE
++.PP
+ \-XX:+AllowUserSignalHandlers
+ .RS 4
+ ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ë¤è¤ë¥·¥°¥Ê¥ë¡¦¥Ï¥ó¥É¥é¤Î¥¤¥ó¥¹¥È¡¼¥ë¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¢¤ê¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¥·¥°¥Ê¥ë¡¦¥Ï¥ó¥É¥é¤ò¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¤³¤È¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£
+@@ -1569,7 +1611,7 @@
+ .PP
+ \-XX:CompileThreshold=\fIinvocations\fR
+ .RS 4
+-¥³¥ó¥Ñ¥¤¥ëÁ°¤Ë²ò¼á¤µ¤ì¤¿¥á¥½¥Ã¥É¸Æ½Ð¤·¤Î¿ô¤òÀßÄꤷ¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥µ¡¼¥Ð¡¼JVM¤Ç¤Ï¡¢JIT¥³¥ó¥Ñ¥¤¥é¤Ï¡¢10,000¤Î²ò¼á¤µ¤ì¤¿¥á¥½¥Ã¥É¸Æ½Ð¤·¤ò¼Â¹Ô¤·¤Æ¡¢¸úΨŪ¤Ê¥³¥ó¥Ñ¥¤¥ë¤Î¤¿¤á¤Î¾ðÊó¤ò¼ý½¸¤·¤Þ¤¹¡£¥¯¥é¥¤¥¢¥ó¥ÈJVM¤Î¾ì¹ç¡¢¥Ç¥Õ¥©¥ë¥ÈÀßÄê¤Ï1,500¸Æ½Ð¤·¤Ç¤¹¡£¼¡¤ÎÎã¤Ç¤Ï¡¢²ò¼á¤µ¤ì¤¿¥á¥½¥Ã¥É¸Æ½Ð¤·¤Î¿ô¤ò5,000¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
++¥³¥ó¥Ñ¥¤¥ëÁ°¤Ë²ò¼á¤µ¤ì¤¿¥á¥½¥Ã¥É¸Æ½Ð¤·¤Î¿ô¤òÀßÄꤷ¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥µ¡¼¥Ð¡¼JVM¤Ç¤Ï¡¢JIT¥³¥ó¥Ñ¥¤¥é¤Ï¡¢10,000¤Î²ò¼á¤µ¤ì¤¿¥á¥½¥Ã¥É¸Æ½Ð¤·¤ò¼Â¹Ô¤·¤Æ¡¢¸úΨŪ¤Ê¥³¥ó¥Ñ¥¤¥ë¤Î¤¿¤á¤Î¾ðÊó¤ò¼ý½¸¤·¤Þ¤¹¡£¥¯¥é¥¤¥¢¥ó¥ÈJVM¤Î¾ì¹ç¡¢¥Ç¥Õ¥©¥ë¥ÈÀßÄê¤Ï1,500¸Æ½Ð¤·¤Ç¤¹¡£ÁØ¥³¥ó¥Ñ¥¤¥ë¤¬Í­¸ú¤Ê¾ì¹ç¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵»ë¤µ¤ì¤Þ¤¹¡£¥ª¥×¥·¥ç¥ó\fB\-XX:+TieredCompilation\fR¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£¼¡¤ÎÎã¤Ç¤Ï¡¢²ò¼á¤µ¤ì¤¿¥á¥½¥Ã¥É¸Æ½Ð¤·¤Î¿ô¤ò5,000¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+@@ -1591,7 +1633,7 @@
+ .PP
+ \-XX:InitialCodeCacheSize=\fIsize\fR
+ .RS 4
+-½é´ü¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤÏ500KB¤ËÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£¼¡¤ÎÎã¤Ç¤Ï¡¢½é´ü¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º¤ò32KB¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
++½é´ü¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤÏ500KB¤ËÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£½é´ü¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º¤ò¥·¥¹¥Æ¥à¤ÎºÇ¾®¥á¥â¥ê¡¼¡¦¥Ú¡¼¥¸¡¦¥µ¥¤¥º¤è¤ê¾®¤µ¤¯¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£¼¡¤ÎÎã¤Ç¤Ï¡¢½é´ü¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º¤ò32KB¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+@@ -1711,7 +1753,17 @@
+ .PP
+ \-XX:ReservedCodeCacheSize=\fIsize\fR
+ .RS 4
+-JIT¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤¿¥³¡¼¥É¤ÎºÇÂ祳¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï\fB\-Xmaxjitcodesize\fR¤ÈƱÅù¤Ç¤¹¡£
++JIT¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤¿¥³¡¼¥É¤ÎºÇÂ祳¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï2GB¤ÎÀ©¸Â¤¬¤¢¤ê¤Þ¤¹¡£¤½¤¦¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢¥¨¥é¡¼¤¬À¸À®¤µ¤ì¤Þ¤¹¡£ºÇÂ祳¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º¤ò½é´ü¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º¤è¤ê¾®¤µ¤¯¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£\fB\-XX:InitialCodeCacheSize\fR¥ª¥×¥·¥ç¥ó¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï\fB\-Xmaxjitcodesize\fR¤ÈƱÅù¤Ç¤¹¡£
++.RE
++.PP
++\-XX:RTMAbortRatio=\fIabort_ratio\fR
++.RS 4
++RTMÃæ»ßΨ¤Ï¡¢¤¹¤Ù¤Æ¤Î¼Â¹ÔºÑRTM¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤ËÂФ¹¤ë¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸(%)¤È¤·¤Æ»ØÄꤵ¤ì¤Þ¤¹¡£Ãæ»ß¤µ¤ì¤¿¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¿ô¤¬¤³¤ÎΨ¤òĶ¤¨¤¿¾ì¹ç¡¢¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤¿¥³¡¼¥É¤¬ÈóºÇŬ²½¤µ¤ì¤Þ¤¹¡£¤³¤ÎΨ¤Ï¡¢\fB\-XX:+UseRTMDeopt\fR¥ª¥×¥·¥ç¥ó¤¬Í­¸ú¤Ê¾ì¹ç¤Ë»ÈÍѤµ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤÏ50¤Ç¤¹¡£¤Ä¤Þ¤ê¡¢¤¹¤Ù¤Æ¤Î¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤Î50%¤¬Ãæ»ß¤µ¤ì¤¿¾ì¹ç¡¢¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤¿¥³¡¼¥É¤¬ÈóºÇŬ²½¤µ¤ì¤Þ¤¹¡£
++.RE
++.PP
++\-XX:RTMRetryCount=\fInumber_of_retries\fR
++.RS 4
++Ãæ»ß¤Þ¤¿¤Ï¥Ó¥¸¡¼¤Î¾ì¹ç¡¢RTM¥í¥Ã¥¯¡¦¥³¡¼¥É¤Ï¡¢É¸½à¤Î¥í¥Ã¥¯¡¦¥á¥«¥Ë¥º¥à¤Ë¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¤¹¤ëÁ°¤Ë¤³¤Î¥ª¥×¥·¥ç¥ó¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿²ó¿ôºÆ»î¹Ô¤µ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤÏ5¤Ç¤¹¡£\fB\-XX:UseRTMLocking\fR¥ª¥×¥·¥ç¥ó¤òÍ­¸ú²½¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .PP
+ \-XX:+TieredCompilation
+@@ -1751,40 +1803,53 @@
+ ¥«¡¼¥Éɽ¤Î¹¹¿·Á°¤Ë¡¢¥«¡¼¥É¤¬¤¹¤Ç¤Ë¥Þ¡¼¥¯¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Î¥Á¥§¥Ã¥¯¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤ª¤ê¡¢Ê£¿ô¤Î¥½¥±¥Ã¥È¤ò»ý¤Ä¥Þ¥·¥ó¾å¤Ç¤Î¤ß»ÈÍѤ¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢Æ±»þÁàºî¤Ë¤«¤Ê¤ê°Í¸¤·¤Æ¤¤¤ëJava¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤¬¸þ¾å¤·¤Þ¤¹¡£Java HotSpot Server VM¤Î¤ß¤¬¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
+ .RE
+ .PP
+-\-XX:+UseSuperWord
+-.RS 4
+-¥¹¥«¥é¡¼±é»»¤Î¥¹¡¼¥Ñ¡¼¥ï¡¼¥É±é»»¤Ø¤ÎÊÑ´¹¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Ç¥Õ¥©¥ë¥È¤ÇÍ­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¥¹¥«¥é¡¼±é»»¤Î¥¹¡¼¥Ñ¡¼¥ï¡¼¥É±é»»¤Ø¤ÎÊÑ´¹¤ò̵¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢\fB\-XX:\-UseSuperWord\fR¤ò»ØÄꤷ¤Þ¤¹¡£Java HotSpot Server VM¤Î¤ß¤¬¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
+-.RE
+-.SS "»î¸³Åª¤ÊJIT¥³¥ó¥Ñ¥¤¥é¡¦¥ª¥×¥·¥ç¥ó"
+-.PP
+-¤³¤Î¹à¤ÎRestricted Transactional Memory (RTM)¤Î¥í¥Ã¥¯µ¡Ç½¤Ë´ØÏ¢¤¹¤ë¥ª¥×¥·¥ç¥ó¤Ï»î¸³Åª¤Ê¤â¤Î¤Ç¡¢Java SE 8u20¤ÇÀµ¼°¤Ë¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£¤³¤ì¤é¤ò»ÈÍѤ¹¤ë¤Ë¤Ï¡¢\fB\-XX:+UnlockExperimentalVMOptions\fR¥ª¥×¥·¥ç¥ó¤òÍ­¸ú²½¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤é¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢Transactional Synchronization Extensions (TSX)¤ò¥µ¥Ý¡¼¥È¤¹¤ëx86 CPU¾å¤ÎJava HotSpot Server VM¤ËÂФ·¤Æ¤Î¤ß»ÈÍѲÄǽ¤Ç¤¹¡£
+-.PP
+-\-XX:RTMAbortRatio=\fIabort_ratio\fR
+-.RS 4
+-RTMÃæ»ßΨ¤Ï¡¢¤¹¤Ù¤Æ¤Î¼Â¹ÔºÑRTM¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤ËÂФ¹¤ë¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸(%)¤È¤·¤Æ»ØÄꤵ¤ì¤Þ¤¹¡£Ãæ»ß¤µ¤ì¤¿¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¿ô¤¬¤³¤ÎΨ¤òĶ¤¨¤¿¾ì¹ç¡¢¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤¿¥³¡¼¥É¤¬ÈóºÇŬ²½¤µ¤ì¤Þ¤¹¡£¤³¤ÎΨ¤Ï¡¢\fB\-XX:+UseRTMDeopt\fR¥ª¥×¥·¥ç¥ó¤¬Í­¸ú¤Ê¾ì¹ç¤Ë»ÈÍѤµ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤÏ50¤Ç¤¹¡£¤Ä¤Þ¤ê¡¢¤¹¤Ù¤Æ¤Î¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤Î50%¤¬Ãæ»ß¤µ¤ì¤¿¾ì¹ç¡¢¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤¿¥³¡¼¥É¤¬ÈóºÇŬ²½¤µ¤ì¤Þ¤¹¡£
+-.RE
+-.PP
+-\-XX:RTMRetryCount=\fInumber_of_retries\fR
+-.RS 4
+-Ãæ»ß¤Þ¤¿¤Ï¥Ó¥¸¡¼¤Î¾ì¹ç¡¢RTM¥í¥Ã¥¯¡¦¥³¡¼¥É¤Ï¡¢É¸½à¤Î¥í¥Ã¥¯¡¦¥á¥«¥Ë¥º¥à¤Ë¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¤¹¤ëÁ°¤Ë¤³¤Î¥ª¥×¥·¥ç¥ó¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿²ó¿ôºÆ»î¹Ô¤µ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤÏ5¤Ç¤¹¡£\fB\-XX:UseRTMLocking\fR¥ª¥×¥·¥ç¥ó¤òÍ­¸ú²½¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+-.RE
+-.PP
+ \-XX:+UseRTMDeopt
+ .RS 4
+-Ãæ»ßΨ¤Ë±þ¤¸¤Æ¡¢RTM¥í¥Ã¥¯¤ò¼«Æ°Ä´À°¤·¤Þ¤¹¡£¤³¤ÎΨ¤Ï¡¢\fB\-XX:RTMAbortRatio\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤Þ¤¹¡£Ãæ»ß¤µ¤ì¤¿¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¿ô¤¬Ãæ»ßΨ¤òĶ¤¨¤¿¾ì¹ç¡¢¥í¥Ã¥¯¤ò´Þ¤à¥á¥½¥Ã¥É¤¬¤¹¤Ù¤Æ¤Î¥í¥Ã¥¯¤Çɸ½à¤Î¥í¥Ã¥¯¤È¤·¤ÆÈóºÇŬ²½¤ª¤è¤ÓºÆ¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£\fB\-XX:UseRTMLocking\fR¥ª¥×¥·¥ç¥ó¤òÍ­¸ú²½¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
++Ãæ»ßΨ¤Ë±þ¤¸¤Æ¡¢RTM¥í¥Ã¥¯¤ò¼«Æ°Ä´À°¤·¤Þ¤¹¡£¤³¤ÎΨ¤Ï¡¢\fB\-XX:RTMAbortRatio\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤Þ¤¹¡£Ãæ»ß¤µ¤ì¤¿¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¿ô¤¬Ãæ»ßΨ¤òĶ¤¨¤¿¾ì¹ç¡¢¥í¥Ã¥¯¤ò´Þ¤à¥á¥½¥Ã¥É¤¬¤¹¤Ù¤Æ¤Î¥í¥Ã¥¯¤Çɸ½à¤Î¥í¥Ã¥¯¤È¤·¤ÆÈóºÇŬ²½¤ª¤è¤ÓºÆ¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£\fB\-XX:+UseRTMLocking\fR¥ª¥×¥·¥ç¥ó¤òÍ­¸ú²½¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .PP
+ \-XX:+UseRTMLocking
+ .RS 4
+-¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¡¦¥Ï¥ó¥É¥é¤È¤·¤Æɸ½à¤Î¥í¥Ã¥¯¡¦¥á¥«¥Ë¥º¥à¤ò»ÈÍѤ·¤Æ¡¢Å¸³«¤µ¤ì¤¿¤¹¤Ù¤Æ¤Î¥í¥Ã¥¯¤ËÂФ·¤ÆRestricted Transactional Memory (RTM)¥í¥Ã¥¯¡¦¥³¡¼¥É¤òÀ¸À®¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£
++¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¡¦¥Ï¥ó¥É¥é¤È¤·¤Æɸ½à¤Î¥í¥Ã¥¯¡¦¥á¥«¥Ë¥º¥à¤ò»ÈÍѤ·¤Æ¡¢Å¸³«¤µ¤ì¤¿¤¹¤Ù¤Æ¤Î¥í¥Ã¥¯¤ËÂФ·¤ÆRestricted Transactional Memory (RTM)¥í¥Ã¥¯¡¦¥³¡¼¥É¤òÀ¸À®¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£RTM¤Ë´ØÏ¢¤¹¤ë¥ª¥×¥·¥ç¥ó¤Ï¡¢Transactional Synchronization Extensions (TSX)¤ò¥µ¥Ý¡¼¥È¤¹¤ëx86 CPU¾å¤ÎJava HotSpot Server VM¤ËÂФ·¤Æ¤Î¤ß»ÈÍѲÄǽ¤Ç¤¹¡£
+ .sp
+-RTM¤Ï¡¢x86Ì¿Î᥻¥Ã¥È³ÈÄ¥¤Ç¥Þ¥ë¥Á¥¹¥ì¥Ã¥É¡¦¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÎºîÀ®¤òÍưפˤ¹¤ëIntel¤ÎTransactional Synchronization Extensions (TSX)¤Î°ìÉô¤Ç¤¹¡£RTM¤Ç¤Ï¡¢¿·¤·¤¤Ì¿Îá
++RTM¤Ï¡¢x86Ì¿Î᥻¥Ã¥È³ÈÄ¥¤Ç¥Þ¥ë¥Á¥¹¥ì¥Ã¥É¡¦¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÎºîÀ®¤òÍưפˤ¹¤ëIntel¤ÎTSX¤Î°ìÉô¤Ç¤¹¡£RTM¤Ç¤Ï¡¢¿·¤·¤¤Ì¿Îá
+ \fBXBEGIN\fR¡¢\fBXABORT\fR¡¢\fBXEND\fR¤ª¤è¤Ó\fBXTEST\fR¤¬Æ³Æþ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£\fBXBEGIN\fR¤ª¤è¤Ó\fBXEND\fRÌ¿Îá¤Ï¡¢¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤È¤·¤Æ¼Â¹Ô¤¹¤ë¤¿¤á¤ÎÌ¿Î᥻¥Ã¥È¤ò°Ï¤ß¤Þ¤¹¡£¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤Î¼Â¹Ô»þ¤Ë¶¥¹ç¤¬¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿¾ì¹ç¡¢¥á¥â¥ê¡¼¤È¥ì¥¸¥¹¥¿¤ÎÊѹ¹¤¬¡¢\fBXEND\fRÌ¿Îá¤ÇƱ»þ¤Ë¥³¥ß¥Ã¥È¤µ¤ì¤Þ¤¹¡£\fBXABORT\fRÌ¿Îá¤Ç¤Ï¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤òÌÀ¼¨Åª¤ËÃæ»ß¤Ç¤­¡¢\fBXEND\fRÌ¿Îá¤Ç¤ÏÌ¿Î᥻¥Ã¥È¤¬¥È¥é¥ó¥¶¥¯¥·¥ç¥óÆâ¤Ç¼Â¹ÔÃ椫¤É¤¦¤«¤ò³Îǧ¤Ç¤­¤Þ¤¹¡£
+ .sp
+ ¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤Î¥í¥Ã¥¯¤Ï¡¢Ê̤Υ¹¥ì¥Ã¥É¤¬Æ±¤¸¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤Ë¥¢¥¯¥»¥¹¤·¤è¤¦¤È¤·¤¿¤È¤­¤ËŸ³«¤µ¤ì¤Þ¤¹¡£¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤Î¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤Ø¤Î¥¢¥¯¥»¥¹¤òºÇ½é¤Ë¥ê¥¯¥¨¥¹¥È¤·¤Ê¤«¤Ã¤¿¥¹¥ì¥Ã¥É¤Ï¥Ö¥í¥Ã¥¯¤µ¤ì¤Þ¤¹¡£RTM¤Ç¤Ï¡¢¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤¬Ãæ»ß¤Þ¤¿¤Ï¼ºÇÔ¤·¤¿¾ì¹ç¤Î¤¿¤á¤Ë¡¢¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¤ÎÁàºî¥»¥Ã¥È¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£RTM¥í¥Ã¥¯¤È¤Ï¡¢TSX¤Î¥·¥¹¥Æ¥à¤Ë°Ñ¾ù¤µ¤ì¤Æ¤¤¤ë¥í¥Ã¥¯¤Ç¤¹¡£
+ .sp
+ RTM¤Ë¤è¤ê¡¢½ÅÍפʥ꡼¥¸¥ç¥ó¤Ë¤ª¤¤¤Æ¾×Æͤ¬¾¯¤Ê¤¯¶¥¹çÅ٤ι⤤¥í¥Ã¥¯¤Î¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤¬¸þ¾å¤µ¤ì¤Þ¤¹(¤³¤ì¤Ï¡¢Ê£¿ô¤Î¥¹¥ì¥Ã¥É¤Ë¤è¤Ã¤ÆƱ»þ¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤Ê¤¤¥³¡¼¥É¤Ç¤¹)¡£¤Þ¤¿¡¢RTM¤Ë¤è¤ê¡¢ÁÆγÅÙ¥í¥Ã¥¯¤Î¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤â¸þ¾å¤µ¤ì¤Þ¤¹¤¬¡¢°ìÈÌŪ¤Ë¥Þ¥ë¥Á¥¹¥ì¥Ã¥É¡¦¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ç¤Î¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤Ï¤è¤¯¤¢¤ê¤Þ¤»¤ó¡£(ÁÆγÅÙ¥í¥Ã¥¯¤È¤Ï¡¢¥í¥Ã¥¯¤Î¼èÆÀ¤ª¤è¤Ó²òÊü¤Î¥ª¡¼¥Ð¡¼¥Ø¥Ã¥É¤òºÇ¾®²½¤¹¤ë¤¿¤á¤ËŤ¤´ü´Ö¥í¥Ã¥¯¤òÊÝ»ý¤¹¤ëÀïά¤Ç¤¢¤ê¡¢°ìÊý¡¢ºÙγÅÙ¥í¥Ã¥¯¤È¤ÏɬÍפʾì¹ç¤Î¤ß¥í¥Ã¥¯¤·²Äǽ¤Ê¤«¤®¤êÁá´ü¤Ë¥í¥Ã¥¯²ò½ü¤¹¤ë¤³¤È¤ÇºÇÂç¸Â¤ÎʹԽèÍý¤ÎãÀ®¤ò»î¤ß¤ëÀïά¤Ç¤¹¡£)¤µ¤é¤Ë¡¢°Û¤Ê¤ë¥¹¥ì¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ë·ÚÅ٤ʶ¥¹ç¥í¥Ã¥¯¤Î¾ì¹ç¡¢RTM¤Ë¤è¤ê¡¢¸í¤Ã¤¿¥­¥ã¥Ã¥·¥å¡¦¥é¥¤¥ó¶¦Í­(¥­¥ã¥Ã¥·¥å¡¦¥é¥¤¥ó¡¦¥Ô¥ó¥Ý¥ó¤È¤â¸Æ¤Ð¤ì¤ë)¤òºï¸º¤Ç¤­¤Þ¤¹¡£¤³¤ì¤Ï¡¢°Û¤Ê¤ë¥×¥í¥»¥Ã¥µ¤«¤é¤ÎÊ£¿ô¤Î¥¹¥ì¥Ã¥É¤¬°Û¤Ê¤ë¥ê¥½¡¼¥¹¤Ë¥¢¥¯¥»¥¹¤·¤Æ¤¤¤ë¾ì¹ç¤ËȯÀ¸¤·¤Þ¤¹¤¬¡¢¥ê¥½¡¼¥¹¤ÏƱ¤¸¥­¥ã¥Ã¥·¥å¡¦¥é¥¤¥ó¤ò¶¦Í­¤·¤Þ¤¹¡£·ë²Ì¤È¤·¤Æ¡¢¥×¥í¥»¥Ã¥µ¤Ï¾¤Î¥×¥í¥»¥Ã¥µ¤Î¥­¥ã¥Ã¥·¥å¡¦¥é¥¤¥ó¤ò·«¤êÊÖ¤·Ìµ¸ú¤Ë¤·¡¢¤³¤ì¤Ë¤è¤ê¡¢¥­¥ã¥Ã¥·¥å¤Ç¤Ï¤Ê¤¯¥á¥¤¥ó¡¦¥á¥â¥ê¡¼¤«¤é¤ÎÆɼè¤ê¤¬¶¯À©¤µ¤ì¤Þ¤¹¡£
+ .RE
++.PP
++\-XX:+UseSHA
++.RS 4
++SPARC¥Ï¡¼¥É¥¦¥§¥¢¤ÎSHA°Å¹æ²½¥Ï¥Ã¥·¥å´Ø¿ô¤Î¥Ï¡¼¥É¥¦¥§¥¢¥Ù¡¼¥¹¤ÎÁȹþ¤ß¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£\fBUseSHA\fR¤Ï¡¢\fBUseSHA1Intrinsics\fR¡¢\fBUseSHA256Intrinsics\fR¤ª¤è¤Ó\fBUseSHA512Intrinsics\fR¥ª¥×¥·¥ç¥ó¤ÈÁȤ߹礻¤Æ»ÈÍѤ·¤Þ¤¹¡£
++.sp
++\fBUseSHA\fR¤ª¤è¤Ó\fBUseSHA*Intrinsics\fR¥Õ¥é¥°¤Ï¥Ç¥Õ¥©¥ë¥È¤ÇÍ­¸ú¤Ç¤¢¤ê¡¢SPARC T4°Ê¾å¤ÎJava HotSpot Server VM 64¥Ó¥Ã¥È¤Ç¤Î¤ß¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤¹¡£
++.sp
++SHAÁàºî¤ËÂФ·¤Æ\fBsun\&.security\&.provider\&.Sun\fR¥×¥í¥Ð¥¤¥À¤ò»ÈÍѤ¹¤ë¾ì¹ç¤Î¤ß¡¢¤³¤Îµ¡Ç½¤òŬÍѤǤ­¤Þ¤¹¡£
++.sp
++¤¹¤Ù¤Æ¤Î¥Ï¡¼¥É¥¦¥§¥¢¥Ù¡¼¥¹¤ÎSHAÁȹþ¤ß¤ò̵¸ú²½¤¹¤ë¤Ë¤Ï¡¢\fB\-XX:\-UseSHA\fR¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£ÆÃÄê¤ÎSHAÁȹþ¤ß¤Î¤ß̵¸ú²½¤¹¤ë¤Ë¤Ï¡¢Å¬ÀÚ¤ÊÂбþ¤¹¤ë¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£¤¿¤È¤¨¤Ð¡¢\fB\-XX:\-UseSHA256Intrinsics\fR¤Ê¤É¤Ç¤¹¡£
++.RE
++.PP
++\-XX:+UseSHA1Intrinsics
++.RS 4
++SHA\-1°Å¹æ²½¥Ï¥Ã¥·¥å´Ø¿ô¤ÎÁȹþ¤ß¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£
++.RE
++.PP
++\-XX:+UseSHA256Intrinsics
++.RS 4
++SHA\-224¤ª¤è¤ÓSHA\-256°Å¹æ²½¥Ï¥Ã¥·¥å´Ø¿ô¤ÎÁȹþ¤ß¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£
++.RE
++.PP
++\-XX:+UseSHA512Intrinsics
++.RS 4
++SHA\-384¤ª¤è¤ÓSHA\-512°Å¹æ²½¥Ï¥Ã¥·¥å´Ø¿ô¤ÎÁȹþ¤ß¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£
++.RE
++.PP
++\-XX:+UseSuperWord
++.RS 4
++¥¹¥«¥é¡¼±é»»¤Î¥¹¡¼¥Ñ¡¼¥ï¡¼¥É±é»»¤Ø¤ÎÊÑ´¹¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Ç¥Õ¥©¥ë¥È¤ÇÍ­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¥¹¥«¥é¡¼±é»»¤Î¥¹¡¼¥Ñ¡¼¥ï¡¼¥É±é»»¤Ø¤ÎÊÑ´¹¤ò̵¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢\fB\-XX:\-UseSuperWord\fR¤ò»ØÄꤷ¤Þ¤¹¡£Java HotSpot Server VM¤Î¤ß¤¬¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
++.RE
+ .SS "¹âÅ٤ʥµ¡¼¥Ó¥¹¥¢¥Ó¥ê¥Æ¥£¡¦¥ª¥×¥·¥ç¥ó"
+ .PP
+ ¤³¤ì¤é¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥·¥¹¥Æ¥à¾ðÊó¤ò¼ý½¸¤·¡¢¾ÜºÙ¤Ê¥Ç¥Ð¥Ã¥°¤ò¼Â¹Ô¤¹¤ëµ¡Ç½¤òÄ󶡤·¤Þ¤¹¡£
+@@ -1855,7 +1920,7 @@
+ .PP
+ \-XX:+PrintConcurrentLocks
+ .RS 4
+-¼¡¤Î°õºþ¤òÍ­¸ú²½¤·¤Þ¤¹: j ¥í¥Ã¥¯(¼¡¤Î¸å) \- ¥¤¥Ù¥ó¥È¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¹¡£
++°õºþ¤òÍ­¸ú¤Ë¤·¤Þ¤¹ ¥í¥Ã¥¯(¼¡¤Î¸å) \- ¥¤¥Ù¥ó¥È¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¹¡£
+ .sp
+ \fB[Control]+[C]\fR¥¤¥Ù¥ó¥È(\fBSIGTERM\fR)¸å¤Ë\fBjava\&.util\&.concurrent\fR¥í¥Ã¥¯¤Î°õºþ¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¹¡£
+ .sp
+@@ -2018,7 +2083,7 @@
+ .PP
+ \-XX:InitialHeapSize=\fIsize\fR
+ .RS 4
+-¥á¥â¥ê¡¼³äÅö¤Æ¥×¡¼¥ë¤Î½é´ü¥µ¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£»ØÄꤹ¤ëÃͤϡ¢0¡¢¤Þ¤¿¤Ï1MB¤è¤êÂ礭¤¤1024¤ÎÇÜ¿ô¤Î¤¤¤º¤ì¤«¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢¼Â¹Ô»þ¤Ë¥·¥¹¥Æ¥à¹½À®¤Ë´ð¤Å¤¤¤ÆÁªÂò¤µ¤ì¤Þ¤¹¡£¾ÜºÙ¤Ï¡¢http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gc\-ergonomics\&.html¤Ë¤¢¤ë¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥¿¡¦¥¨¥ë¥´¥Î¥ß¥Ã¥¯¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++¥á¥â¥ê¡¼³äÅö¤Æ¥×¡¼¥ë¤Î½é´ü¥µ¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£»ØÄꤹ¤ëÃͤϡ¢0¡¢¤Þ¤¿¤Ï1MB¤è¤êÂ礭¤¤1024¤ÎÇÜ¿ô¤Î¤¤¤º¤ì¤«¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢¼Â¹Ô»þ¤Ë¥·¥¹¥Æ¥à¹½À®¤Ë´ð¤Å¤¤¤ÆÁªÂò¤µ¤ì¤Þ¤¹¡£http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gctuning/index\&.html¤Î\fIJava SE HotSpot²¾ÁÛ¥Þ¥·¥ó¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¡¦¥Á¥å¡¼¥Ë¥ó¥°¡¦¥¬¥¤¥É\fR¤Î¥¨¥ë¥´¥Î¥ß¥¯¥¹¤Ë´Ø¤¹¤ë¹à¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ ¼¡¤ÎÎã¤Ç¤Ï¡¢³ä¤êÅö¤Æ¤é¤ì¤¿¥á¥â¥ê¡¼¤Î¥µ¥¤¥º¤òÍÍ¡¹¤Êñ°Ì¤ò»ÈÍѤ·¤Æ6MB¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
+ .sp
+@@ -2109,7 +2174,7 @@
+ .PP
+ \-XX:MaxHeapSize=\fIsize\fR
+ .RS 4
+-¥á¥â¥ê¡¼³äÅö¤Æ¥×¡¼¥ë¤ÎºÇÂ祵¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£»ØÄꤹ¤ëÃͤϡ¢2MB¤è¤êÂ礭¤¤1024¤ÎÇÜ¿ô¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢¼Â¹Ô»þ¤Ë¥·¥¹¥Æ¥à¹½À®¤Ë´ð¤Å¤¤¤ÆÁªÂò¤µ¤ì¤Þ¤¹¡£¥µ¡¼¥Ð¡¼¡¦¥Ç¥×¥í¥¤¥á¥ó¥È¤Ç¤Ï¡¢\fB\-XX:InitialHeapSize\fR¤ª¤è¤Ó\fB\-XX:MaxHeapSize\fR¤ÏÄ̾ïƱ¤¸ÃͤËÀßÄꤵ¤ì¤Þ¤¹¡£¾ÜºÙ¤Ï¡¢http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gc\-ergonomics\&.html¤Ë¤¢¤ë¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥¿¡¦¥¨¥ë¥´¥Î¥ß¥Ã¥¯¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++¥á¥â¥ê¡¼³äÅö¤Æ¥×¡¼¥ë¤ÎºÇÂ祵¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£»ØÄꤹ¤ëÃͤϡ¢2MB¤è¤êÂ礭¤¤1024¤ÎÇÜ¿ô¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢¼Â¹Ô»þ¤Ë¥·¥¹¥Æ¥à¹½À®¤Ë´ð¤Å¤¤¤ÆÁªÂò¤µ¤ì¤Þ¤¹¡£¥µ¡¼¥Ð¡¼¡¦¥Ç¥×¥í¥¤¥á¥ó¥È¤Ç¤Ï¡¢\fB\-XX:InitialHeapSize\fR¤ª¤è¤Ó\fB\-XX:MaxHeapSize\fR¤ÏÄ̾ïƱ¤¸ÃͤËÀßÄꤵ¤ì¤Þ¤¹¡£http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gctuning/index\&.html¤Î\fIJava SE HotSpot²¾ÁÛ¥Þ¥·¥ó¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¡¦¥Á¥å¡¼¥Ë¥ó¥°¡¦¥¬¥¤¥É\fR¤Î¥¨¥ë¥´¥Î¥ß¥¯¥¹¤Ë´Ø¤¹¤ë¹à¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ ¼¡¤ÎÎã¤Ç¤Ï¡¢³ä¤êÅö¤Æ¤é¤ì¤¿¥á¥â¥ê¡¼¤Îµö²Ä¤µ¤ì¤ëºÇÂ祵¥¤¥º¤òÍÍ¡¹¤Êñ°Ì¤ò»ÈÍѤ·¤Æ80MB¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
+ .sp
+@@ -2480,6 +2545,13 @@
+ ¥·¥ê¥¢¥ë¡¦¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥¿¤Î»ÈÍѤòÍ­¸ú¤Ë¤·¤Þ¤¹¡£¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¤«¤éÆÃÊ̤ʵ¡Ç½¤òɬÍפȤ·¤Ê¤¤¡¢¾®µ¬ÌϤÇñ½ã¤Ê¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¾ì¹ç¤Ë¤Ï¡¢¤³¤ì¤Ï°ìÈ̤˺ÇŬ¤ÊÁªÂò¤Ç¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤ª¤ê¡¢¥³¥ì¥¯¥¿¤Ï¡¢¥Þ¥·¥ó¤Î¹½À®¤ª¤è¤ÓJVM¤Î¥¿¥¤¥×¤Ë´ð¤Å¤¤¤Æ¡¢¼«Æ°Åª¤ËÁªÂò¤µ¤ì¤Þ¤¹¡£
+ .RE
+ .PP
++\-XX:+UseSHM
++.RS 4
++Linux¤Ç¤Ï¡¢JVM¤Ç¶¦Í­¥á¥â¥ê¡¼¤ò»ÈÍѤ·¤Æ¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤òÀßÄê¤Ç¤­¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£
++.sp
++¾ÜºÙ¤Ï¡¢"¥é¡¼¥¸¡¦¥Ú¡¼¥¸"¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++.RE
++.PP
+ \-XX:+UseStringDeduplication
+ .RS 4
+ ʸ»úÎó¤Î½ÅÊ£½ü³°¤òÍ­¸ú²½¤·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤Ë¤Ï¡¢¥¬¥Ù¡¼¥¸¥Õ¥¡¡¼¥¹¥È(G1)¡¦¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥¿¤òÍ­¸ú¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£\fB\-XX:+UseG1GC\fR¥ª¥×¥·¥ç¥ó¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+@@ -2502,7 +2574,7 @@
+ .PP
+ \-Xrun\fIlibname\fR
+ .RS 4
+-»ØÄꤷ¤¿¥Ç¥Ð¥Ã¥°/¥×¥í¥Õ¥¡¥¤¥ë¤Î¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢\fB\-agentlib\fR¥ª¥×¥·¥ç¥ó¤Ë¼è¤Ã¤ÆÂå¤ï¤é¤ì¤Þ¤·¤¿¡£
++»ØÄꤷ¤¿¥Ç¥Ð¥Ã¥°/¥×¥í¥Õ¥¡¥¤¥ê¥ó¥°¤Î¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢\fB\-agentlib\fR¥ª¥×¥·¥ç¥ó¤Ë¼è¤Ã¤ÆÂå¤ï¤é¤ì¤Þ¤·¤¿¡£
+ .RE
+ .PP
+ \-XX:CMSIncrementalDutyCycle=\fIpercent\fR
+@@ -2563,9 +2635,7 @@
+ .PP
+ ¼¡¤ÎÎã¤Ç¤Ï¡¢¥¹¥ë¡¼¥×¥Ã¥È¤ÎºÇŬ²½¤Þ¤¿¤Ï¥ì¥¹¥Ý¥ó¥¹»þ´Ö¤Îû½Ì²½¤Î¤¤¤º¤ì¤«¤ò¹Ô¤¦¤¿¤á¤Î¡¢»î¸³Åª¤Ê¥Á¥å¡¼¥Ë¥ó¥°¡¦¥Õ¥é¥°¤Î»ÈÍÑÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
+ .PP
+-\fBÎã 1\fR
+-.br
+-¥¹¥ë¡¼¥×¥Ã¥È¤ò¸þ¾å¤¹¤ë¤¿¤á¤Î¥Á¥å¡¼¥Ë¥ó¥°
++\fBÎã 1 \fR¥¹¥ë¡¼¥×¥Ã¥È¤ò¸þ¾å¤¹¤ë¤¿¤á¤Î¥Á¥å¡¼¥Ë¥ó¥°
+ .RS 4
+ .sp
+ .if n \{\
+@@ -2580,9 +2650,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-¥ì¥¹¥Ý¥ó¥¹»þ´Ö¤ò®¤¯¤¹¤ë¤¿¤á¤Î¥Á¥å¡¼¥Ë¥ó¥°
++\fBÎã 2 \fR¥ì¥¹¥Ý¥ó¥¹»þ´Ö¤ò®¤¯¤¹¤ë¤¿¤á¤Î¥Á¥å¡¼¥Ë¥ó¥°
+ .RS 4
+ .sp
+ .if n \{\
+@@ -2596,6 +2664,188 @@
+ .RE
+ .\}
+ .RE
++.SH "¥é¡¼¥¸¡¦¥Ú¡¼¥¸"
++.PP
++¥Ò¥å¡¼¥¸¡¦¥Ú¡¼¥¸¤È¤â¸Æ¤Ð¤ì¤ë¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Ï¡¢É¸½à¤Î¥á¥â¥ê¡¼¡¦¥Ú¡¼¥¸¡¦¥µ¥¤¥º(¥×¥í¥»¥Ã¥µ¤ª¤è¤Ó¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¡¦¥·¥¹¥Æ¥à¤Ë¤è¤Ã¤Æ°Û¤Ê¤ê¤Þ¤¹)¤è¤ê¤Ï¤ë¤«¤ËÂ礭¤¤¥á¥â¥ê¡¼¡¦¥Ú¡¼¥¸¤Ç¤¹¡£¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Ï¡¢¥×¥í¥»¥Ã¥µ¤ÎTranslation\-Lookaside Buffer¤òºÇŬ²½¤·¤Þ¤¹¡£
++.PP
++Translation\-Lookaside Buffer (TLB)¤Ï¡¢ºÇ¶á»ÈÍѤµ¤ì¤¿²¾ÁÛ¤«¤éʪÍý¤Ø¤Î¥¢¥É¥ì¥¹ÊÑ´¹¤òÊÝ»ý¤¹¤ë¥Ú¡¼¥¸ÊÑ´¹¥­¥ã¥Ã¥·¥å¤Ç¤¹¡£TLB¤Ï¡¢¾¯¤Ê¤¤¥·¥¹¥Æ¥à¡¦¥ê¥½¡¼¥¹¤Ç¤¹¡£¥×¥í¥»¥Ã¥µ¤¬Ê£¿ô¤Î¥á¥â¥ê¡¼¡¦¥¢¥¯¥»¥¹¤¬É¬Íפʾì¹ç¤Î¤¢¤ë³¬ÁØ¥Ú¡¼¥¸É½¤«¤éÆɤ߼è¤ëɬÍפ¬¤¢¤ë¤¿¤á¡¢TLB¥ß¥¹¤ÏÉé²Ù¤¬¤«¤«¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£Â礭¤¤¥á¥â¥ê¡¼¡¦¥Ú¡¼¥¸¡¦¥µ¥¤¥º¤ò»ÈÍѤ·¤Æ¡¢Ã±°ì¤ÎTLB¥¨¥ó¥È¥ê¤ÇÂ礭¤¤¥á¥â¥ê¡¼ÈϰϤòɽ¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£TLBÉÔ­¤¬¾¯¤Ê¤¯¤Ê¤ê¡¢¥á¥â¥ê¡¼½¸Ì󷿤Υ¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤¬¸þ¾å¤¹¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£
++.PP
++¤¿¤À¤·¡¢¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¥Ú¡¼¥¸¡¦¥á¥â¥ê¡¼¤Ï¡¢¥·¥¹¥Æ¥à¤Î¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤Ë°­±Æ¶Á¤òÍ¿¤¨¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢ÂçÎ̤Υá¥â¥ê¡¼¤¬¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ç³ÎÊݤµ¤ì¤ë¾ì¹ç¡¢Ä̾ï¥á¥â¥ê¡¼ÉÔ­¤ä¾¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î²á¾ê¤Ê¥Ú¡¼¥¸¥ó¥°¤¬È¯À¸¤·¡¢¥·¥¹¥Æ¥àÁ´ÂΤ¬ÃÙ¤¯¤Ê¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£¤Þ¤¿¡¢Ä¹»þ´Ö²ÔƯ¤·¤Æ¤¤¤ë¥·¥¹¥Æ¥à¤Ï¡¢²á¾ê¤ÊÃÇÊÒ²½¤¬È¯À¸¤¹¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢½½Ê¬¤ÊÂ礭¤µ¤Î¥Ú¡¼¥¸¡¦¥á¥â¥ê¡¼¤òͽÌó¤Ç¤­¤Ê¤¤²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤¬È¯À¸¤·¤¿¾ì¹ç¡¢OS¤Þ¤¿¤ÏJVM¤Î¤¤¤º¤ì¤«¤¬Ä̾ï¤Î¥Ú¡¼¥¸¤Î»ÈÍѤËÌá¤ê¤Þ¤¹¡£
++.SS "¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¥µ¥Ý¡¼¥È"
++.PP
++Solaris¤ª¤è¤ÓLinux¤Ï¡¢¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£
++.sp
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBSolaris\fR
++.RS 4
++.PP
++Solaris 9°Ê¾å¤Ë¤Ï¡¢Multiple Page Size Support(MPSS)¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£Äɲäι½À®¤ÏɬÍפ¢¤ê¤Þ¤»¤ó¡£http://www\&.oracle\&.com/technetwork/server\-storage/solaris10/overview/solaris9\-features\-scalability\-135663\&.html¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++.RE
++.sp
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBLinux\fR
++.RS 4
++.PP
++2\&.6¥«¡¼¥Í¥ë¤Ï¡¢¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£°ìÉô¤Î¥Ù¥ó¥À¡¼¤Ï¡¢2\&.4¥Ù¡¼¥¹¤Î¥ê¥ê¡¼¥¹¤Î¥³¡¼¥É¤ò¥Ð¥Ã¥¯¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£¥·¥¹¥Æ¥à¤¬¥é¡¼¥¸¡¦¥Ú¡¼¥¸¡¦¥á¥â¥ê¡¼¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¤«¤É¤¦¤«¤ò³Îǧ¤¹¤ë¤Ë¤Ï¡¢¼¡¤ò»î¹Ô¤·¤Æ¤¯¤À¤µ¤¤:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB# cat /proc/meminfo | grep Huge\fR
++\fBHugePages_Total: 0\fR
++\fBHugePages_Free: 0\fR
++\fBHugepagesize: 2048 kB\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.PP
++½ÐÎϤË3¤Ä¤Î"Huge"ÊÑ¿ô¤¬¼¨¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥·¥¹¥Æ¥à¤Ï¥é¡¼¥¸¡¦¥Ú¡¼¥¸¡¦¥á¥â¥ê¡¼¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¤¬¡¢¹½À®¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥³¥Þ¥ó¥É¤¬²¿¤â½ÐÎϤ·¤Ê¤¤¾ì¹ç¡¢¥·¥¹¥Æ¥à¤Ï¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£¥é¡¼¥¸¡¦¥Ú¡¼¥¸¡¦¥á¥â¥ê¡¼¤ò»ÈÍѤ¹¤ë¥·¥¹¥Æ¥à¤ò¹½À®¤¹¤ë¤Ë¤Ï¡¢\fBroot\fR¤È¤·¤Æ¥í¥°¥¤¥ó¤·¤Æ¡¢¼¡¤Î¼ê½ç¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤:
++.sp
++.RS 4
++.ie n \{\
++\h'-04' 1.\h'+01'\c
++.\}
++.el \{\
++.sp -1
++.IP " 1." 4.2
++.\}
++¥ª¥×¥·¥ç¥ó\fB\-XX:+UseSHM\fR(\fB\-XX:+UseHugeTLBFS\fR¤Î¤«¤ï¤ê)¤ò»ÈÍѤ¹¤ë¾ì¹ç¡¢\fBSHMMAX\fRÃͤòÁý¤ä¤·¤Æ¤¯¤À¤µ¤¤¡£Java¥Ò¡¼¥×¡¦¥µ¥¤¥º¤è¤êÂ礭¤¯¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£4GB°Ê²¼¤ÎʪÍýRAM¤ò»ÈÍѤ·¤¿¥·¥¹¥Æ¥à¤Ç¡¢¼¡¤Ë¤è¤ê¤¹¤Ù¤Æ¤Î¥á¥â¥ê¡¼¤¬¶¦Í­²Äǽ¤Ë¤Ê¤ê¤Þ¤¹:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB# echo 4294967295 > /proc/sys/kernel/shmmax\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04' 2.\h'+01'\c
++.\}
++.el \{\
++.sp -1
++.IP " 2." 4.2
++.\}
++¥ª¥×¥·¥ç¥ó\fB\-XX:+UseSHM\fR¤Þ¤¿¤Ï\fB\-XX:+UseHugeTLBFS\fR¤ò»ÈÍѤ¹¤ë¾ì¹ç¡¢¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¿ô¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£¼¡¤ÎÎã¤Ç¤Ï¡¢4GB¥·¥¹¥Æ¥à¤Î3GB¤¬¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ËͽÌ󤵤ì¤Þ¤¹(2048KB¤Î¥é¡¼¥¸¡¦¥Ú¡¼¥¸¡¦¥µ¥¤¥º¤ò²¾Äꤹ¤ë¾ì¹ç¡¢3GB = 3 * 1024MB = 3072MB = 3072 * 1024KB = 3145728KB and 3145728KB / 2048KB = 1536):
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB# echo 1536 > /proc/sys/vm/nr_hugepages\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.if n \{\
++.sp
++.\}
++.RS 4
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBÃíµ­\fR
++.ps -1
++.br
++.TS
++allbox tab(:);
++l.
++T{
++Ãí°Õ
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++¥·¥¹¥Æ¥à¤òºÆµ¯Æ°¤·¤¿¸å¤Ë\fB/proc\fR¤Ë´Þ¤Þ¤ì¤ëÃͤ¬¥ê¥»¥Ã¥È¤µ¤ì¤ë¤Î¤ÇÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤½¤Î¤¿¤á¡¢½é´ü²½¥¹¥¯¥ê¥×¥È(\fBrc\&.local\fR¤ä\fBsysctl\&.conf\fR¤Ê¤É)¤ÇÀßÄê¤Ç¤­¤Þ¤¹¡£
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++OS¥«¡¼¥Í¥ë¡¦¥Ñ¥é¥á¡¼¥¿\fB/proc/sys/kernel/shmmax\fR¤Þ¤¿¤Ï\fB/proc/sys/vm/nr_hugepages\fR¤ò¹½À®(¤Þ¤¿¤Ï¥µ¥¤¥ºÊѹ¹)¤¹¤ë¾ì¹ç¡¢Java¥×¥í¥»¥¹¤¬Java¥Ò¡¼¥×°Ê³°¤ÎÎΰè¤ËÂФ·¤Æ¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ò³ä¤êÅö¤Æ¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤é¤Î¼ê½ç¤ò»ÈÍѤ·¤Æ¡¢¼¡¤ÎÎΰè¤ËÂФ·¤Æ¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ò³ä¤êÅö¤Æ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++Java¥Ò¡¼¥×
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++PermanentÀ¤Âå
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥å
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++¥Ñ¥é¥ì¥ëGC¤Î¥Þ¡¼¥­¥ó¥°¡¦¥Ó¥Ã¥È¥Þ¥Ã¥×¡¦¥Ç¡¼¥¿¹½Â¤
++.RE
++.sp
++¤½¤Î·ë²Ì¡¢Java¥Ò¡¼¥×¤Î¥µ¥¤¥º¤Ë\fBnr_hugepages\fR¥Ñ¥é¥á¡¼¥¿¤ò¹½À®¤¹¤ë¤È¡¢Îΰè¤Î¥µ¥¤¥º¤¬Èó¾ï¤ËÂ礭¤¤¤¿¤á¤ËJVM¤¬PermanentÀ¤Â太¤è¤Ó¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥åÎΰè¤Î³äÅö¤Æ¤Ë¼ºÇÔ¤¹¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£
++.RE
++T}
++.TE
++.sp 1
++.sp .5v
++.RE
++.RE
+ .SH "½ªÎ»¥¹¥Æ¡¼¥¿¥¹"
+ .PP
+ Ä̾¼¡¤Î½ªÎ»Ãͤ¬µ¯Æ°¥Ä¡¼¥ë¤«¤éÊÖ¤µ¤ì¤ë¤Î¤Ï¡¢µ¯Æ°¸µ¤¬ÉÔÀµ¤Ê°ú¿ô¤Ç¸Æ¤Ó½Ð¤µ¤ì¤¿¤«¡¢¿¼¹ï¤Ê¥¨¥é¡¼¤¬È¯À¸¤·¤¿¤«¡¢¤¢¤ë¤¤¤ÏJVM¤Ë¤è¤êÎã³°¤¬¥¹¥í¡¼¤µ¤ì¤¿¾ì¹ç¤Ç¤¹¡£¤¿¤À¤·¡¢Java¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¡¢API¸Æ½Ð¤·\fBSystem\&.exit(exitValue)\fR¤ò»ÈÍѤ·¤ÆǤ°Õ¤ÎÃͤòÊÖ¤¹¤³¤È¤òÁªÂò¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£Ãͤϼ¡¤Î¤È¤ª¤ê¤Ç¤¹¡£
+@@ -2666,6 +2916,17 @@
+ .\}
+ jar(1)
+ .RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++jstat(1)
++.RE
+ .br
+ 'pl 8.5i
+ 'bp
+--- ./jdk/src/linux/doc/man/ja/javac.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/javac.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: javac
+ .\" Language: Japanese
+-.\" Date: 2014ǯ8·î8Æü
++.\" Date: 2015ǯ3·î3Æü
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "javac" "1" "2014ǯ8·î8Æü" "JDK 8" "´ðËܥġ¼¥ë"
++.TH "javac" "1" "2015ǯ3·î3Æü" "JDK 8" "´ðËܥġ¼¥ë"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -154,7 +155,7 @@
+ .PP
+ \-cp \fIpath\fR or \-classpath \fIpath\fR
+ .RS 4
+-¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¡¢¤ª¤è¤Ó(¥ª¥×¥·¥ç¥ó¤Ç)Ãí¼á¥×¥í¥»¥Ã¥µ¤È¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¸¡º÷¤¹¤ë¾ì½ê¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¥¯¥é¥¹¡¦¥Ñ¥¹¤Ï\fBCLASSPATH\fR´Ä¶­ÊÑ¿ô¤Î¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Ñ¥¹¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Þ¤¹¡£\fBCLASSPATH\fR¡¢\fB\-cp\fR¡¢\fB\-classpath\fR¤Î¤¤¤º¤ì¤â»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¡¢¥æ¡¼¥¶¡¼¤Î\fI¥¯¥é¥¹¡¦¥Ñ¥¹\fR¤Ï¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤Ê¤ê¤Þ¤¹¡£Setting the Class Path ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¡¢¤ª¤è¤Ó(¥ª¥×¥·¥ç¥ó¤Ç)Ãí¼á¥×¥í¥»¥Ã¥µ¤È¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¸¡º÷¤¹¤ë¾ì½ê¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¥¯¥é¥¹¡¦¥Ñ¥¹¤Ï\fBCLASSPATH\fR´Ä¶­ÊÑ¿ô¤Î¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Ñ¥¹¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Þ¤¹¡£\fBCLASSPATH\fR¡¢\fB\-cp\fR¡¢\fB\-classpath\fR¤Î¤¤¤º¤ì¤â»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¡¢¥æ¡¼¥¶¡¼¤Î\fI¥¯¥é¥¹¡¦¥Ñ¥¹\fR¤Ï¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤Ê¤ê¤Þ¤¹¡£¥¯¥é¥¹¡¦¥Ñ¥¹¤ÎÀßÄê ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ \fB\-sourcepath\fR¥ª¥×¥·¥ç¥ó¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤â¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Ñ¥¹¤«¤é¸¡º÷¤µ¤ì¤Þ¤¹¡£
+ .sp
+@@ -1122,9 +1123,7 @@
+ .PP
+ \fBjavac\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤¹¤ë¤È¤­¤Ë¡¢³Æ°ú¿ô¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤È̾Á°¤ÎÀèƬ¤Ë¥¢¥Ã¥È¥Þ¡¼¥¯(@)ʸ»ú¤òÉÕ¤±¤ÆÅϤ·¤Þ¤¹¡£\fBjavac\fR¥³¥Þ¥ó¥É¤Ï¡¢¥¢¥Ã¥È¥Þ¡¼¥¯(@)¤Ç»Ï¤Þ¤ë°ú¿ô¤ò¸«¤Ä¤±¤ë¤È¡¢¤½¤Î¥Õ¥¡¥¤¥ë¤ÎÆâÍƤòŸ³«¤·¤Æ°ú¿ô¥ê¥¹¥È¤ËÁÞÆþ¤·¤Þ¤¹¡£
+ .PP
+-\fBÎã 1\fR
+-.br
+-ñ°ì¤Î°ú¿ô¥Õ¥¡¥¤¥ë
++\fBÎã 1 \fRñ°ì¤Î°ú¿ô¥Õ¥¡¥¤¥ë
+ .RS 4
+ \fBargfile\fR¤È¤¤¤¦Ì¾Á°¤Îñ°ì¤Î°ú¿ô¥Õ¥¡¥¤¥ë¤ò»ÈÍѤ·¤Æ¡¢¤¹¤Ù¤Æ¤Î\fBjavac\fR°ú¿ô¤ò³ÊǼ¤¹¤ë¾ì¹ç¤Ï¡¢¼¡¤Î¤è¤¦¤Ë»ØÄꤷ¤Þ¤¹¡£
+ .sp
+@@ -1141,9 +1140,7 @@
+ ¤³¤Î°ú¿ô¥Õ¥¡¥¤¥ë¤Ë¤Ï¡¢Îã2¤Ç¼¨¤µ¤ì¤Æ¤¤¤ëξÊý¤Î¥Õ¥¡¥¤¥ë¤ÎÆâÍƤòÆþ¤ì¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-2¤Ä¤Î°ú¿ô¥Õ¥¡¥¤¥ë
++\fBÎã 2 \fR2¤Ä¤Î°ú¿ô¥Õ¥¡¥¤¥ë
+ .RS 4
+ \fBjavac\fR¥ª¥×¥·¥ç¥óÍѤȥ½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾ÍѤˡ¢2¤Ä¤Î°ú¿ô¥Õ¥¡¥¤¥ë¤òºîÀ®¤Ç¤­¤Þ¤¹¡£¼¡¤Î¥ê¥¹¥È¤Ë¤Ï¡¢¹Ô¤Î·Ñ³ʸ»ú¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+ .sp
+@@ -1216,9 +1213,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 3\fR
+-.br
+-¥Ñ¥¹¤ò»ÈÍѤ·¤¿°ú¿ô¥Õ¥¡¥¤¥ë
++\fBÎã 3 \fR¥Ñ¥¹¤ò»ÈÍѤ·¤¿°ú¿ô¥Õ¥¡¥¤¥ë
+ .RS 4
+ °ú¿ô¥Õ¥¡¥¤¥ë¤Ï¥Ñ¥¹¤ò»ØÄê¤Ç¤­¤Þ¤¹¤¬¡¢¥Õ¥¡¥¤¥ëÆâ¤Î¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë̾¤Ï¡¢(\fBpath1\fR¤ä\fBpath2\fR¤Ç¤Ï¤Ê¤¯)¼¡¤Î¤è¤¦¤Ë¸½ºß¤Îºî¶È¥Ç¥£¥ì¥¯¥È¥ê¤ËÁêÂÐŪ¤È¤Ê¤ê¤Þ¤¹¡£
+ .sp
+@@ -1317,9 +1312,7 @@
+ ̾Á°¤¬\fBcom\&.sun\&.tools\&.javac\fR¤Ç»Ï¤Þ¤ë¥Ñ¥Ã¥±¡¼¥¸(\fBcom\&.sun\&.tools\&.javac\fR¤Î¥µ¥Ö¥Ñ¥Ã¥±¡¼¥¸)¤Ç¸¡½Ð¤µ¤ì¤ë¾¤Î¤¹¤Ù¤Æ¤Î¥¯¥é¥¹¤ª¤è¤Ó¥á¥½¥Ã¥É¤Ï¡¢´°Á´¤ËÆâÉôÍѤǤ¢¤ê¡¢¤¤¤Ä¤Ç¤âÊѹ¹¤µ¤ì¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£
+ .SH "Îã"
+ .PP
+-\fBÎã 1\fR
+-.br
+-´Êñ¤Ê¥×¥í¥°¥é¥à¤Î¥³¥ó¥Ñ¥¤¥ë
++\fBÎã 1 \fR´Êñ¤Ê¥×¥í¥°¥é¥à¤Î¥³¥ó¥Ñ¥¤¥ë
+ .RS 4
+ ¤³¤ÎÎã¤Ç¤Ï¡¢greetings¥Ç¥£¥ì¥¯¥È¥ê¤Ç\fBHello\&.java\fR¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ëÊýË¡¤ò¼¨¤·¤Æ¤¤¤Þ¤¹¡£\fBHello\&.java\fR¤ÇÄêµÁ¤µ¤ì¤¿¥¯¥é¥¹¤Ï¡¢\fBgreetings\&.Hello\fR¤È¸Æ¤Ð¤ì¤Þ¤¹¡£greetings¥Ç¥£¥ì¥¯¥È¥ê¤Ï¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤È¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤ÎξÊý¤¬¤¢¤ë¥Ñ¥Ã¥±¡¼¥¸¡¦¥Ç¥£¥ì¥¯¥È¥ê¤Ç¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î¤¹¤°²¼¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Ñ¥¹¤ò»ÈÍѤǤ­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£¤Þ¤¿¡¢\fB\-d\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤ÆÊ̤νÐÎÏÀè¥Ç¥£¥ì¥¯¥È¥ê¤ò»ØÄꤹ¤ëɬÍפ⤢¤ê¤Þ¤»¤ó¡£
+ .sp
+@@ -1372,9 +1365,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-Ê£¿ô¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Î¥³¥ó¥Ñ¥¤¥ë
++\fBÎã 2 \fRÊ£¿ô¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Î¥³¥ó¥Ñ¥¤¥ë
+ .RS 4
+ ¤³¤ÎÎã¤Ç¤Ï¡¢\fBgreetings\fR¥Ñ¥Ã¥±¡¼¥¸¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë\fBAloha\&.java\fR¡¢\fBGutenTag\&.java\fR¡¢\fBHello\&.java\fR¤ª¤è¤Ó\fBHi\&.java\fR¤ò¥³¥ó¥Ñ¥¤¥ë¤·¤Þ¤¹¡£
+ .sp
+@@ -1393,9 +1384,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 3\fR
+-.br
+-¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Ñ¥¹¤Î»ØÄê
++\fBÎã 3 \fR¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Ñ¥¹¤Î»ØÄê
+ .RS 4
+ Á°½Ò¤ÎÎã¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Î¤¦¤Á1¤Ä¤òÊѹ¹¤·¤¿¸å¤Ë¡¢¤½¤Î¥Õ¥¡¥¤¥ë¤òºÆ¥³¥ó¥Ñ¥¤¥ë¤·¤Þ¤¹¡£
+ .sp
+@@ -1450,9 +1439,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 4\fR
+-.br
+-¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤È¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤ÎʬΥ
++\fBÎã 4 \fR¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤È¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤ÎʬΥ
+ .RS 4
+ ¼¡¤ÎÎã¤Ç¤Ï¡¢\fBjavac\fR¤ò»ÈÍѤ·¤Æ¡¢JVM 1\&.7¾å¤Ç¼Â¹Ô¤¹¤ë¥³¡¼¥É¤ò¥³¥ó¥Ñ¥¤¥ë¤·¤Þ¤¹¡£
+ .sp
+@@ -1486,9 +1473,7 @@
+ ŬÀڤʥС¼¥¸¥ç¥ó¤Î¥Ö¡¼¥È¥¹¥È¥é¥Ã¥×¡¦¥¯¥é¥¹¤ò»ØÄꤷ¤Ê¤¤¾ì¹ç¡¢¥³¥ó¥Ñ¥¤¥é¤Ï¸Å¤¤¸À¸ì»ÅÍÍ(¤³¤ÎÎã¤Ç¤Ï¡¢¥Ð¡¼¥¸¥ç¥ó1\&.7¤ÎJava¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì)¤ò¿·¤·¤¤¥Ö¡¼¥È¥¹¥È¥é¥Ã¥×¡¦¥¯¥é¥¹¤ÈÁȤ߹礻¤Æ»ÈÍѤ·¤Þ¤¹¡£¤½¤Î·ë²Ì¡¢Â¸ºß¤·¤Ê¤¤¥á¥½¥Ã¥É¤Ø¤Î»²¾È¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¤¿¤á¡¢¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤¬¸Å¤¤¥×¥é¥Ã¥È¥Õ¥©¡¼¥à(¤³¤Î¾ì¹ç¤ÏJava SE 7)¤ÇÆ°ºî¤·¤Ê¤¤²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .PP
+-\fBÎã 5\fR
+-.br
+-¥¯¥í¥¹¡¦¥³¥ó¥Ñ¥¤¥ë
++\fBÎã 5 \fR¥¯¥í¥¹¡¦¥³¥ó¥Ñ¥¤¥ë
+ .RS 4
+ ¤³¤ÎÎã¤Ç¤Ï¡¢\fBjavac\fR¤ò»ÈÍѤ·¤Æ¡¢JVM 1\&.7¾å¤Ç¼Â¹Ô¤¹¤ë¥³¡¼¥É¤ò¥³¥ó¥Ñ¥¤¥ë¤·¤Þ¤¹¡£
+ .sp
+@@ -1503,7 +1488,7 @@
+ .if n \{\
+ .RE
+ .\}
+-\fB \-source 1\&.7\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¡¢OldCode\&.java¤Î¥³¥ó¥Ñ¥¤¥ë¤Ë¤Ï¥ê¥ê¡¼¥¹1\&.7(¤Þ¤¿¤Ï7)¤ÎJava¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤¬»ÈÍѤµ¤ì¤Þ¤¹¡£\fB\-target 1\&.7\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¡¢JVM 1\&.7¤È¸ß´¹À­¤Î¤¢¤ë¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤¬À¸À®¤µ¤ì¤Þ¤¹¡£¤Û¤È¤ó¤É¤Î¾ì¹ç¡¢\fB\-target\fR¤ÎÃͤÏ\fB\-source\fR¤ÎÃͤˤʤê¤Þ¤¹¡£¤³¤ÎÎã¤Ç¤Ï¡¢\fB\-target\fR¥ª¥×¥·¥ç¥ó¤Ï¾Êά¤µ¤ì¤Þ¤¹¡£
++\fB \-source 1\&.7\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¡¢OldCode\&.java¤Î¥³¥ó¥Ñ¥¤¥ë¤Ë¤Ï¥ê¥ê¡¼¥¹1\&.7(¤Þ¤¿¤Ï7)¤ÎJava¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤¬»ÈÍѤµ¤ì¤Þ¤¹¡£\fB\-target 1\&.7\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¡¢JVM 1\&.7¤È¸ß´¹À­¤Î¤¢¤ë¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤¬À¸À®¤µ¤ì¤Þ¤¹¡£
+ .sp
+ \fB\-bootclasspath\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¡¢Å¬ÀڤʥС¼¥¸¥ç¥ó¤Î¥Ö¡¼¥È¥¹¥È¥é¥Ã¥×¡¦¥¯¥é¥¹(\fBrt\&.jar\fR¥é¥¤¥Ö¥é¥ê)¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£»ØÄꤷ¤Ê¤¤¾ì¹ç¤Ï¡¢¥³¥ó¥Ñ¥¤¥é¤Ë¤è¤Ã¤Æ¼¡¤Î·Ù¹ð¤¬À¸À®¤µ¤ì¤Þ¤¹¡£
+ .sp
+--- ./jdk/src/linux/doc/man/ja/javadoc.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/javadoc.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: javadoc
+ .\" Language: Japanese
+-.\" Date: 2011ǯ5·î10Æü
++.\" Date: 2015ǯ3·î3Æü
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "javadoc" "1" "2011ǯ5·î10Æü" "JDK 8" "´ðËܥġ¼¥ë"
++.TH "javadoc" "1" "2015ǯ3·î3Æü" "JDK 8" "´ðËܥġ¼¥ë"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -359,7 +360,7 @@
+ .IP \(bu 2.3
+ .\}
+ ½èÍý¤Ç¤­¤ë¤è¤¦¤Ë¥³¥á¥ó¥È¤ò¥³¥Ô¡¼¤·¤Þ¤¹¡£package\&.html¤Î¾ì¹ç¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¡¢\fB<body>\fR¤È\fB</body>\fR
+-HTML¥¿¥°´Ö¤Ç¤¹¤Ù¤Æ¤Î¥³¥ó¥Æ¥ó¥Ä¤ò¥³¥Ô¡¼¤·¤Þ¤¹¡£\fB<head>\fR¥»¥¯¥·¥ç¥ó¤ò´Þ¤á¤Æ¡¢\fB<title>\fR¥¿¥°¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Î¥³¥Ô¡¼¥é¥¤¥Èʸ¡¢¤½¤Î¾¤Î¾ðÊó¤òÇÛÃÖ¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤¹¤¬¡¢¤³¤ì¤é¤ÏÀ¸À®¤µ¤ì¤ë¥É¥­¥å¥á¥ó¥È¤Ë¤Ïɽ¼¨¤µ¤ì¤Þ¤»¤ó¡£
++HTML¥¿¥°´Ö¤Ç¤¹¤Ù¤Æ¤Î¥³¥ó¥Æ¥ó¥Ä¤ò¥³¥Ô¡¼¤·¤Þ¤¹¡£\fB<title>\fR¥¿¥°¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ÎÃøºî¸¢Ê¸¤Þ¤¿¤Ï¾¤Î¾ðÊó¤òÇÛÃÖ¤¹¤ë\fB<head>\fR¥»¥¯¥·¥ç¥ó¤ò´Þ¤á¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¤¬¡¢¤³¤ì¤é¤ÏÀ¸À®¤µ¤ì¤¿¥É¥­¥å¥á¥ó¥È¤Ëɽ¼¨¤µ¤ì¤Þ¤»¤ó¡£
+ .RE
+ .sp
+ .RS 4
+@@ -1425,9 +1426,9 @@
+ .RS 4
+ JDK 1\&.5¤ÇƳÆþ
+ .sp
+-\fB<code>{@literal}</code>\fR¤ÈƱÅù¤Ç¤¹¡£
+-.sp
+-¥Æ¥­¥¹¥È¤òHTML¥Þ¡¼¥¯¥¢¥Ã¥×¤Þ¤¿¤Ï¥Í¥¹¥È¤µ¤ì¤¿Javadoc¥¿¥°¤È¤·¤Æ²ò¼á¤»¤º¤Ë¡¢text¤ò¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Çɽ¼¨¤·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤Ç¤Ï¡¢¥Ñ¥é¥á¡¼¥¿¤Î·¿(\fB<Object>\fR)¡¢ÉÔÅù¹æ(\fB3 < 4\fR)¡¢Ìð°õ(\fB<\-\fR)¤Ê¤É¤Ç¡¢Ä̾ï¤Î»³¥«¥Ã¥³(<¤ª¤è¤Ó>)¤òHTML¥¨¥ó¥Æ¥£¥Æ¥£(\fB&lt;\fR¤ª¤è¤Ó\fB&gt;\fR)¤Î¤«¤ï¤ê¤Ë»ÈÍѤǤ­¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢À¸À®¤µ¤ì¤¿HTML¥Ú¡¼¥¸¤Ëɽ¼¨¤µ¤ì¤ë¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¡¦¥Æ¥­¥¹¥È\fB{@code A<B>C}\fR¤Ï¡¢Êѹ¹¤µ¤ì¤º\fBA<B>C\fR¤È¤Ê¤ê¤Þ¤¹¡£¤Ä¤Þ¤ê¡¢\fB<B>\fR¤¬ÂÀ»ú¤È¤·¤Æ²ò¼á¤µ¤ì¤º¡¢¤½¤Î¥Õ¥©¥ó¥È¤Ï¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Ë¤Ê¤ê¤Þ¤¹¡£¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Ê¤·¤ÇƱ¤¸µ¡Ç½¤ò¼Â¸½¤¹¤ë¤Ë¤Ï¡¢\fB{@literal}\fR¥¿¥°¤ò»ÈÍѤ·¤Þ¤¹¡£
++\fB<code>{@literal}</code>\fR¤ÈƱ¤¸¤Ç¤¹¡£
++.sp
++¥Æ¥­¥¹¥È¤òHTML¥Þ¡¼¥¯¥¢¥Ã¥×¤Þ¤¿¤Ï¥Í¥¹¥È¤µ¤ì¤¿Javadoc¥¿¥°¤È¤·¤Æ²ò¼á¤»¤º¤Ë¡¢text¤ò¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Çɽ¼¨¤·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤Ç¤Ï¡¢¥Ñ¥é¥á¡¼¥¿¤Î·¿(\fB<Object>\fR)¡¢ÉÔÅù¹æ(\fB3 < 4\fR)¡¢Ìð°õ(\fB<\-\fR)¤Ê¤É¤Ç¡¢Ä̾ï¤Î»³¥«¥Ã¥³(<¤ª¤è¤Ó>)¤òHTML¥¨¥ó¥Æ¥£¥Æ¥£(\fB&lt;\fR¤ª¤è¤Ó\fB&gt;\fR)¤Î¤«¤ï¤ê¤Ë»ÈÍѤǤ­¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¡¦¥Æ¥­¥¹¥È\fB{@code A<B>C}\fR¤Ï¡¢\fBA<B>C\fR¤È¤·¤ÆÊѹ¹¤µ¤ì¤º¤ËÀ¸À®¤µ¤ì¤¿HTML¥Ú¡¼¥¸¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£¤Ä¤Þ¤ê¡¢\fB<B>\fR¤¬ÂÀ»ú¤È¤·¤Æ²ò¼á¤µ¤ì¤º¡¢¤½¤Î¥Õ¥©¥ó¥È¤Ï¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Ë¤Ê¤ê¤Þ¤¹¡£¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Ê¤·¤ÇƱ¤¸µ¡Ç½¤ò¼Â¸½¤¹¤ë¤Ë¤Ï¡¢\fB{@literal}\fR¥¿¥°¤ò»ÈÍѤ·¤Þ¤¹¡£
+ .RE
+ .PP
+ @deprecated \fIdeprecated\-text\fR
+@@ -1594,7 +1595,7 @@
+ .RS 4
+ JDK 1\&.5¤ÇƳÆþ
+ .sp
+-¥Æ¥­¥¹¥È¤òHTML¥Þ¡¼¥¯¥¢¥Ã¥×¤Þ¤¿¤Ï¥Í¥¹¥È¤µ¤ì¤¿Javadoc¥¿¥°¤È¤·¤Æ²ò¼á¤»¤º¤Ë¡¢text¤òɽ¼¨¤·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤Ç¤Ï¡¢¥Ñ¥é¥á¡¼¥¿¤Î·¿(\fB<Object>\fR)¡¢ÉÔÅù¹æ(\fB3 < 4\fR)¡¢Ìð°õ(<\-)¤Ê¤É¤Ç¡¢»³¥«¥Ã¥³(\fB<¤ª¤è¤Ó>\fR)¤òHTML¥¨¥ó¥Æ¥£¥Æ¥£(\fB&lt;\fR¤ª¤è¤Ó\fB&gt;\fR)¤Î¤«¤ï¤ê¤Ë»ÈÍѤǤ­¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¡¦¥Æ¥­¥¹¥È\fB{@literal A<B>C}\fR¤Ï¡¢Êѹ¹¤µ¤ì¤º¤Ë¥Ö¥é¥¦¥¶¤ËÀ¸À®¤µ¤ì¤¿HTML¥Ú¡¼¥¸¤Ë\fBA<B>C\fR¤Èɽ¼¨¤µ¤ì¤Þ¤¹¡£\fB<B>\fR¤ÏÂÀ»ú¤È¤·¤Æ²ò¼á¤µ¤ì¤Þ¤»¤ó(¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Ë¤Ê¤ê¤Þ¤»¤ó)¡£¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤ÇƱ¤¸µ¡Ç½¤ò¼Â¸½¤¹¤ë¤Ë¤Ï¡¢\fB{@code}\fR¥¿¥°¤ò»ÈÍѤ·¤Þ¤¹¡£
++¥Æ¥­¥¹¥È¤òHTML¥Þ¡¼¥¯¥¢¥Ã¥×¤Þ¤¿¤Ï¥Í¥¹¥È¤µ¤ì¤¿Javadoc¥¿¥°¤È¤·¤Æ²ò¼á¤»¤º¤Ë¡¢text¤òɽ¼¨¤·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤Ç¤Ï¡¢¥Ñ¥é¥á¡¼¥¿¤Î·¿(\fB<Object>\fR)¡¢ÉÔÅù¹æ(\fB3 < 4\fR)¡¢Ìð°õ(<\-)¤Ê¤É¤Ç¡¢»³¥«¥Ã¥³(\fB<¤ª¤è¤Ó>\fR)¤òHTML¥¨¥ó¥Æ¥£¥Æ¥£(\fB&lt;\fR¤ª¤è¤Ó\fB&gt;\fR)¤Î¤«¤ï¤ê¤Ë»ÈÍѤǤ­¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¡¦¥Æ¥­¥¹¥È\fB{@literal A<B>C}\fR¤Ï¡¢\fBA<B>C\fR¤È¤·¤Æ¥Ö¥é¥¦¥¶¤ÎÀ¸À®¤µ¤ì¤¿HTML¥Ú¡¼¥¸¤ÇÊѹ¹¤µ¤ì¤º¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£\fB<B>\fR¤ÏÂÀ»ú¤È¤·¤Æ²ò¼á¤µ¤ì¤Þ¤»¤ó(¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Ë¤Ê¤ê¤Þ¤»¤ó)¡£¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤ÇƱ¤¸µ¡Ç½¤ò¼Â¸½¤¹¤ë¤Ë¤Ï¡¢\fB{@code}\fR¥¿¥°¤ò»ÈÍѤ·¤Þ¤¹¡£
+ .RE
+ .PP
+ @param \fIparameter\-name description\fR
+@@ -1664,7 +1665,7 @@
+ .sp
+ "The Java Programming Language"
+ .sp
+-\fB·Á¼°2\fR¡£\fB@see <a href="URL#value">label</a>\fR·Á¼°¤Ï¡¢\fBURL#value\fR¤ÇÄêµÁ¤µ¤ì¤¿¥ê¥ó¥¯¤òÄɲä·¤Þ¤¹¡£\fBURL#value\fR¥Ñ¥é¥á¡¼¥¿¤Ï¡¢ÁêÂÐURL¤Þ¤¿¤ÏÀäÂÐURL¤Ç¤¹¡£\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¡¢ºÇ½é¤Îʸ»ú¤È¤·¤Æ¡Ö¤è¤ê¾®¤µ¤¤¡×µ­¹æ(\fB<\fR)¤ò¸¡º÷¤·¤Æ¡¢¤³¤Î·Á¼°¤ò¾¤Î·Á¼°¤È¶èÊ̤·¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢\fB@see <a href="spec\&.html#section">Java Spec</a>\fR¤Ï¼¡¤Î¥ê¥ó¥¯¤òÀ¸À®¤·¤Þ¤¹¡£
++\fB·Á¼°2\fR¡£\fB@see <a href="URL#value">label</a>\fR¥Õ¥©¡¼¥à¤Ï¡¢\fBURL#value\fR¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë¥ê¥ó¥¯¤òÄɲä·¤Þ¤¹¡£\fBURL#value\fR¥Ñ¥é¥á¡¼¥¿¤Ï¡¢ÁêÂÐURL¤Þ¤¿¤ÏÀäÂÐURL¤Ç¤¹¡£\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¡¢ºÇ½é¤Îʸ»ú¤È¤·¤Æ¡Ö¤è¤ê¾®¤µ¤¤¡×µ­¹æ(\fB<\fR)¤ò¸¡º÷¤·¤Æ¡¢¤³¤Î·Á¼°¤ò¾¤Î·Á¼°¤È¶èÊ̤·¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢\fB@see <a href="spec\&.html#section">Java Spec</a>\fR¤Ï¡¢¼¡¤Î¥ê¥ó¥¯¤òÀ¸À®¤·¤Þ¤¹:
+ .sp
+ \fB´ØÏ¢¹àÌÜ\fR:
+ .sp
+@@ -1673,7 +1674,7 @@
+ \fB·Á¼°3\fR¡£\fB@see package\&.class#member label\fR·Á¼°¤Ï¡¢É½¼¨¥Æ¥­¥¹¥È¡¦¥é¥Ù¥ë¤È¤È¤â¤Ë¥ê¥ó¥¯¤òÄɲä·¤Þ¤¹¡£¤³¤Î¥é¥Ù¥ë¤Ï»²¾È¤µ¤ì¤Æ¤¤¤ëJava¸À¸ì¤Î»ØÄꤵ¤ì¤¿Ì¾Á°¤Î¥É¥­¥å¥á¥ó¥È¤ò»Ø¤·¼¨¤·¤Þ¤¹¡£¥é¥Ù¥ë¤Ï¥ª¥×¥·¥ç¥ó¤Ç¤¹¡£¥é¥Ù¥ë¤ò¾Êά¤·¤¿¾ì¹ç¤Ï¡¢É½¼¨¥Æ¥­¥¹¥È¤Î¤«¤ï¤ê¤Ë¡¢Ì¾Á°¤¬Å¬ÀÚ¤Ëû½Ì¤µ¤ì¤Æɽ¼¨¤µ¤ì¤Þ¤¹¡£\fB\-noqualifier\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤È¡¢¤³¤Îɽ¼¨¥Æ¥­¥¹¥È¤«¤é¥Ñ¥Ã¥±¡¼¥¸Ì¾¤¬Á´ÂÎŪ¤Ëºï½ü¤µ¤ì¤Þ¤¹¡£¥é¥Ù¥ë¤Ï¡¢¼«Æ°À¸À®¤µ¤ì¤ëɽ¼¨¥Æ¥­¥¹¥È¤È¤Ï°Û¤Ê¤ëɽ¼¨¥Æ¥­¥¹¥È¤Ë¤¹¤ë¾ì¹ç¤Ë»ÈÍѤ·¤Þ¤¹¡£¡Ö̾Á°¤¬É½¼¨¤µ¤ì¤ëÊýË¡¡×¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ Java SE 1\&.2¤À¤±¤Ï¡¢¥é¥Ù¥ë¤Ç¤Ï¤Ê¤¯Ì¾Á°¤¬\fB<code>\fR
+-HTML¥¿¥°Æâ¤Ë¼«Æ°Åª¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£Java SE 1\&.2\&.2¤«¤é¤Ï¡¢¥é¥Ù¥ë¤ò»ÈÍѤ¹¤ë¤«¤·¤Ê¤¤¤«¤Ë¤«¤«¤ï¤é¤º¡¢\fB<code>\fR¥¿¥°¤Ï¾ï¤Ëɽ¼¨¥Æ¥­¥¹¥È¤ò°Ï¤à¤«¤¿¤Á¤Ç´Þ¤Þ¤ì¤Þ¤¹¡£
++HTML¥¿¥°Æâ¤Ë¼«Æ°Åª¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£Java SE 1\&.2\&.2¤«¤é¤Ï¡¢¥é¥Ù¥ë¤ò»ÈÍѤ¹¤ë¤«¤·¤Ê¤¤¤«¤Ë¤«¤«¤ï¤é¤º¡¢\fB<code>\fR¥¿¥°¤Ï¾ï¤Ëɽ¼¨¥Æ¥­¥¹¥È¤ò°Ï¤à·Á¤Ç´Þ¤Þ¤ì¤Þ¤¹¡£
+ .sp
+ .RS 4
+ .ie n \{\
+@@ -2290,15 +2291,677 @@
+ .RE
+ .PP
+ ¥ª¥×¥·¥ç¥ó¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹¡£
+-.PP
+-\-1\&.1 || \-author || \-bootclasspath classpathlist || \-bottom text || \-breakiterator || \-charset name || \-classpath classpathlist || \-d directory || \-docencoding name || \-docfilesubdirs || \-doclet class || \-docletpath classpathlist || \-doctitle title || \-encoding || \-exclude packagename1:packagename2:\&.\&.\&. || \-excludedocfilessubdir name1:name2 || \-extdirs dirist || \-footer footer || \-group groupheading packagepattern:packagepattern || \-header header || \-help || \-helpfile path\efilename || \-Jflag || \-keywords || \-link extdocURL || \-linkoffline extdocURL packagelistLoc || \-linksource || \-locale language_country_variant || \-nocomment || \-nodeprecated || \-nodeprecatedlist || \-nohelp || \-noindex || \-nonavbar || \-noqualifier all | packagename1:packagename2\&.\&.\&. || \-nosince || \-notimestamp || \-notree ||
+-
+-\-overview path/filename ||
+-\-package || \-private || \-protected || \-public || \-quiet || \-serialwarn || \-source release || \-sourcepath sourcepathlist || \-sourcetab tablength || \-splitindex ||
+-
+-\-stylesheet path/filename ||
+-
+-||\-subpackages package1:package2:\&.\&.\&. || \-tag tagname:Xaoptcmf:"taghead" || \-taglet class || \-tagletpath tagletpathlist || \-title title || \-top || \-use || \-verbose || \-version || \-windowtitle title
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-1\&.1
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-author
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-bootclasspath classpathlist
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-bottom text
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-breakiterator
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-charset name
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-classpath classpathlist
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-d directory
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-docencoding name
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-docfilesubdirs
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-doclet class
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-docletpath classpathlist
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-doctitle title
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-encoding
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-exclude packagename1:packagename2:\&.\&.\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-excludedocfilessubdir name1:name2
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-extdirs dirist
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-footer footer
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-group groupheading packagepattern:packagepattern
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-header header
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-help
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-helpfile path\efilename
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-Jflag
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-javafx
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-keywords
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-link extdocURL
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-linkoffline extdocURL packagelistLoc
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-linksource
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-locale language_country_variant
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-nocomment
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-nodeprecated
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-nodeprecatedlist
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-nohelp
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-noindex
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-nonavbar
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-noqualifier all | packagename1:packagename2\&.\&.\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-nosince
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-notimestamp
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-notree
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-overview path/filename
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-package
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-private
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-protected
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-public
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-quiet
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-serialwarn
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-source release
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-sourcepath sourcepathlist
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-sourcetab tablength
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-splitindex
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-stylesheet path/filename
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-tag tagname:Xaoptcmf:"taghead"
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-subpackages package1:package2:\&.\&.\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-taglet class
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-tagletpath tagletpathlist
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-title title
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-top
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-use
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-verbose
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-version
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-windowtitle title
++.RE
+ .PP
+ ¼¡¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¤¹¤Ù¤Æ¤Î¥É¥Ã¥¯¥ì¥Ã¥È¤Ë»ÈÍѲÄǽ¤Ê¥³¥¢¤ÎJavadoc¥ª¥×¥·¥ç¥ó¤Ç¤¹¡£É¸½à¥É¥Ã¥¯¥ì¥Ã¥È¤Ç¤Ï¡¢¥É¥Ã¥¯¥ì¥Ã¥È¤Î¾¤ÎÉôʬ¤òÄ󶡤·¤Þ¤¹¡£\fB\-bootclasspath\fR¡¢\fB\-breakiterator\fR¡¢\fB\-classpath\fR¡¢\fB\-doclet\fR¡¢\fB\-docletpath\fR¡¢\fB\-encoding\fR¡¢\-\fBexclude\fR¡¢\fB\-extdirs\fR¡¢\fB\-help\fR¡¢\fB\-locale\fR¡¢\fB\-\fR\fBoverview\fR¡¢\fB\-package\fR¡¢\fB\-private\fR¡¢\fB\-protected\fR¡¢\fB\-public\fR¡¢\fB\-quiet\fR¡¢\fB\-source\fR¡¢\fB\-sourcepath\fR¡¢\fB\-subpackages\fR¤ª¤è¤Ó\fB\-verbose\fR¡£
+ .SS "Javadoc¥ª¥×¥·¥ç¥ó"
+@@ -2306,7 +2969,7 @@
+ \-overview \fIpath/filename \fR
+ .RS 4
+
+-\fBjavadoc\fR¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¡¢\fIpath/filename \fR¤Ç»ØÄꤵ¤ì¤¿¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤«¤é³µÍץɥ­¥å¥á¥ó¥ÈÍѤΥƥ­¥¹¥È¤ò¼èÆÀ¤·¡¢¤½¤Î¥Æ¥­¥¹¥È¤ò³µÍ×¥Ú¡¼¥¸(overview\-summary\&.html)¤ËÇÛÃÖ¤¹¤ë¤è¤¦¤Ë»ØÄꤷ¤Þ¤¹¡£\fIpath/filename\fR¤Ï¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤ÎÁêÂХѥ¹¤Ç¤¹¡£
++\fBjavadoc\fR¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¡¢\fIpath/filename \fR¤Ç»ØÄꤵ¤ì¤¿¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤«¤é³µÍץɥ­¥å¥á¥ó¥ÈÍѤΥƥ­¥¹¥È¤ò¼èÆÀ¤·¡¢¤½¤Î¥Æ¥­¥¹¥È¤ò¡Ö³µÍסץڡ¼¥¸(overview\-summary\&.html)¤ËÇÛÃÖ¤¹¤ë¤è¤¦¤Ë»ØÄꤷ¤Þ¤¹¡£\fIpath/filename\fR¤Ï¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤ÎÁêÂХѥ¹¤Ç¤¹¡£
+ .sp
+ \fBfilename\fR¤ÎÃͤÇǤ°Õ¤Î̾Á°¤ò»ÈÍѤ·¡¢path¤ÇǤ°Õ¤ÎÇÛÃÖÀè¤ò»ØÄê¤Ç¤­¤Þ¤¹¤¬¡¢Ä̾ï¤Ïoverview\&.html¤È¤¤¤¦Ì¾Á°¤òÉÕ¤±¡¢¥½¡¼¥¹¡¦¥Ä¥ê¡¼Æâ¤ÎºÇ¾å°Ì¥Ñ¥Ã¥±¡¼¥¸¡¦¥Ç¥£¥ì¥¯¥È¥ê¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤ËÇÛÃÖ¤·¤Þ¤¹¡£¤³¤Î¾ì½ê¤ËÇÛÃÖ¤¹¤ë¤È¡¢¥Ñ¥Ã¥±¡¼¥¸¤ò¥É¥­¥å¥á¥ó¥È²½¤¹¤ë¤È¤­¤Ëpath¤ò»ØÄꤹ¤ëɬÍפ¬¤Ê¤¯¤Ê¤ê¤Þ¤¹¡£¤³¤ì¤Ï¡¢\fB\-sourcepath\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤Ã¤Æ¤³¤Î¥Õ¥¡¥¤¥ë¤¬»Ø¤·¼¨¤µ¤ì¤ë¤«¤é¤Ç¤¹¡£
+ .sp
+@@ -2316,7 +2979,7 @@
+ .sp
+ \fIpath/filename\fR¤Ç»ØÄꤹ¤ë¥Õ¥¡¥¤¥ë¤Ë¤Ä¤¤¤Æ¤Ï¡¢³µÍ×¥³¥á¥ó¥È¡¦¥Õ¥¡¥¤¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+-³µÍ×¥Ú¡¼¥¸¤¬ºîÀ®¤µ¤ì¤ë¤Î¤Ï¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤ËÊ£¿ô¤Î¥Ñ¥Ã¥±¡¼¥¸Ì¾¤òÅϤ·¤¿¾ì¹ç¤Î¤ß¤Ç¤¹¡£¾ÜºÙ¤Ï¡¢HTML¥Õ¥ì¡¼¥à¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£³µÍ×¥Ú¡¼¥¸¤Î¥¿¥¤¥È¥ë¤Ï¡¢\fB\-doctitle\fR¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤Þ¤¹¡£
++¡Ö³µÍסץڡ¼¥¸¤¬ºîÀ®¤µ¤ì¤ë¤Î¤Ï¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤ËÊ£¿ô¤Î¥Ñ¥Ã¥±¡¼¥¸Ì¾¤òÅϤ·¤¿¾ì¹ç¤Î¤ß¤Ç¤¹¡£¾ÜºÙ¤Ï¡¢HTML¥Õ¥ì¡¼¥à¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£¡Ö³µÍסץڡ¼¥¸¤Î¥¿¥¤¥È¥ë¤Ï¡¢\fB\-doctitle\fR¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ \-Xdoclint:(all|none|[\-]\fI<group>\fR)
+@@ -2537,8 +3200,9 @@
+ \-sourcepath \fIsourcepathlist\fR
+ .RS 4
+ ¥Ñ¥Ã¥±¡¼¥¸Ì¾¤Þ¤¿¤Ï\fB\-subpackages\fR¥ª¥×¥·¥ç¥ó¤ò\fBjavadoc\fR¥³¥Þ¥ó¥É¤ËÅϤ¹¤È¤­¤Ë¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¸«¤Ä¤±¤ë¤¿¤á¤Î¸¡º÷¥Ñ¥¹¤ò»ØÄꤷ¤Þ¤¹¡£
+-
++.sp
+ Ê£¿ô¤Î¥Ñ¥¹¤Ï¥³¥í¥ó(:)¤Ç¶èÀÚ¤ê¤Þ¤¹¡£
++.sp
+ \fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¡¢»ØÄꤵ¤ì¤¿¥Ñ¥¹°Ê²¼¤Î¤¹¤Ù¤Æ¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ò¸¡º÷¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¡¢¥É¥­¥å¥á¥ó¥È²½¤µ¤ì¤ë¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Î°ÌÃ֤ΤߤǤʤ¯¡¢¤½¤ì¼«ÂΤϥɥ­¥å¥á¥ó¥È²½¤µ¤ì¤Ê¤¤¤¬¥É¥­¥å¥á¥ó¥È²½¤µ¤ì¤ë¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤«¤é·Ñ¾µ¤µ¤ì¤¿¥³¥á¥ó¥È¤ò»ý¤Ä¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Î°ÌÃÖ¤â³Îǧ¤Ç¤­¤Þ¤¹¡£
+ .sp
+ \fB\-sourcepath\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤǤ­¤ë¤Î¤Ï¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ë¥Ñ¥Ã¥±¡¼¥¸Ì¾¤òÅϤ¹¾ì¹ç¤Î¤ß¤Ç¤¹¡£\fBjavadoc\fR¥³¥Þ¥ó¥É¤ËÅϤµ¤ì¤ë¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Ï¸¡º÷¤µ¤ì¤Þ¤»¤ó¡£¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤òÆÃÄꤹ¤ë¤Ë¤Ï¡¢¤½¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë°ÜÆ°¤¹¤ë¤«¡¢¡Ö1¤Ä°Ê¾å¤Î¥¯¥é¥¹¤Î¥É¥­¥å¥á¥ó¥È²½¡×¤Ë¼¨¤¹¤è¤¦¤Ë³Æ¥Õ¥¡¥¤¥ë¤ÎÁ°¤Ë¥Ñ¥¹¤ò´Þ¤á¤Þ¤¹¡£\fB\-sourcepath\fR¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¡¢¥¯¥é¥¹¡¦¥Ñ¥¹¤ò»ÈÍѤ·¤Æ¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¸¡º÷¤·¤Þ¤¹(\fB\-classpath\fR¤ò»²¾È)¡£¥Ç¥Õ¥©¥ë¥È¤Î\fB\-sourcepath\fR¤Ï¡¢¥¯¥é¥¹¡¦¥Ñ¥¹¤ÎÃͤǤ¹¡£\fB\-classpath\fR¤ò¾Êά¤·¤Æ¥Ñ¥Ã¥±¡¼¥¸Ì¾¤ò\fBjavadoc\fR¥³¥Þ¥ó¥É¤ËÅϤ¹¤È¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê(¤ª¤è¤Ó¤½¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê)¤«¤é¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¸¡º÷¤·¤Þ¤¹¡£
+@@ -2578,8 +3242,9 @@
+ \-classpath \fIclasspathlist\fR
+ .RS 4
+ \fBjavadoc\fR¥³¥Þ¥ó¥É¤¬»²¾È¥¯¥é¥¹¤Î¸¡º÷¤ò¹Ô¤¦¤È¤­¤Ë»ÈÍѤ¹¤ë¥Ñ¥¹¤ò»ØÄꤷ¤Þ¤¹¡£»²¾È¥¯¥é¥¹¤È¤Ï¡¢¥É¥­¥å¥á¥ó¥È²½¤µ¤ì¤ë¥¯¥é¥¹¤È¡¢¤½¤ì¤é¤Î¥¯¥é¥¹¤Ë¤è¤Ã¤Æ»²¾È¤µ¤ì¤ë¤¹¤Ù¤Æ¤Î¥¯¥é¥¹¤Î¤³¤È¤Ç¤¹¡£
+-
++.sp
+ Ê£¿ô¤Î¥Ñ¥¹¤Ï¥³¥í¥ó(:)¤Ç¶èÀÚ¤ê¤Þ¤¹¡£
++.sp
+ \fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¡¢»ØÄꤵ¤ì¤¿¥Ñ¥¹°Ê²¼¤Î¤¹¤Ù¤Æ¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ò¸¡º÷¤·¤Þ¤¹¡£\fBclasspathlist\fR¤ÎÃͤò»ØÄꤹ¤ë¤È¤­¤Ï¡¢¥¯¥é¥¹¡¦¥Ñ¥¹¤Î¥É¥­¥å¥á¥ó¥È¤Ë¤¢¤ë»Ø¼¨¤Ë½¾¤Ã¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ \fB\-sourcepath\fR¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï\fB\-classpath\fR¤ò»ÈÍѤ·¤Æ¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ª¤è¤Ó¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¸¡º÷¤·¤Þ¤¹(¸åÊý¸ß´¹À­¤Î¤¿¤á)¡£¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤È¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤òÊÌ¡¹¤Î¥Ñ¥¹¤«¤é¸¡º÷¤¹¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤Ï¡¢\fB\-sourcepath\fR¤È\fB\-classpath\fR¤ÎξÊý¤ò»ÈÍѤ·¤Þ¤¹¡£
+@@ -2689,7 +3354,7 @@
+ .sp -1
+ .IP \(bu 2.3
+ .\}
+-breakiteratorʸ¶èÀڤꥢ¥ë¥´¥ê¥º¥à¡£¼¡¤Î¸ì¤¬Âçʸ»ú¤Ç»Ï¤Þ¤ë¾ì¹ç¡¢¶õÇòʸ»ú¤¬Â³¤¯¥Ô¥ê¥ª¥É¡¢µ¿ÌäÉä¡¢¤Þ¤¿¤Ï´¶Ã²Éä¤ÇÄä»ß¤·¤Þ¤¹¡£¤³¤Î¥¢¥ë¥´¥ê¥º¥à¤Ç¤Ï¡ÖThe serial no\&. is valid¡×¤Ê¤É¡¢¤Û¤È¤ó¤É¤Î¾Êάɽµ­¤¬½èÍý¤µ¤ì¤Þ¤¹¤¬¡¢¡ÖMr\&. Smith¡×¤Ï½èÍý¤µ¤ì¤Þ¤»¤ó¡£\fB\-breakiterator\fR¥ª¥×¥·¥ç¥ó¤Ç¤Ï¡¢HTML¥¿¥°¤ä¡¢¿ô»ú¤Þ¤¿¤Ïµ­¹æ¤Ç»Ï¤Þ¤ëʸ¤Ç¤ÏÄä»ß¤·¤Þ¤»¤ó¡£HTML¥¿¥°¤ËËä¤á¹þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ç¤â¡¢¡Ö\&.\&./filename¡×¤ÎºÇ¸å¤Î¥Ô¥ê¥ª¥É¤ÇÄä»ß¤·¤Þ¤¹¡£
++breakiteratorʸ¶èÀڤꥢ¥ë¥´¥ê¥º¥à¡£¼¡¤Î¸ì¤¬Âçʸ»ú¤Ç»Ï¤Þ¤ë¾ì¹ç¡¢¶õÇòʸ»ú¤¬Â³¤¯¥Ô¥ê¥ª¥É¡¢µ¿ÌäÉä¡¢¤Þ¤¿¤Ï´¶Ã²Éä¤ÇÄä»ß¤·¤Þ¤¹¡£¤³¤Î¥¢¥ë¥´¥ê¥º¥à¤Ç¤Ï¡ÖThe serial no\&. is valid¡×¤Ê¤É¡¢¤Û¤È¤ó¤É¤Î¾Êάɽµ­¤¬½èÍý¤µ¤ì¤Þ¤¹¤¬¡¢¡ÖMr\&. Smith¡×¤Ï½èÍý¤µ¤ì¤Þ¤»¤ó¡£\fB\-breakiterator\fR¥ª¥×¥·¥ç¥ó¤Ç¤Ï¡¢HTML¥¿¥°¤ä¡¢¿ô»ú¤Þ¤¿¤Ïµ­¹æ¤Ç»Ï¤Þ¤ëʸ¤Ç¤ÏÄä»ß¤·¤Þ¤»¤ó¡£HTML¥¿¥°¤ËËä¤á¹þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ç¤â¡¢¥¢¥ë¥´¥ê¥º¥à¤Ï¡Ö\&.\&./filename¡×¤ÎºÇ¸å¤Î¥Ô¥ê¥ª¥É¤ÇÄä»ß¤·¤Þ¤¹¡£
+ .RE
+ .sp
+ Java SE 1\&.5¤Ç¤Ï\fB\-breakiterator\fR·Ù¹ð¥á¥Ã¥»¡¼¥¸¤¬ºï½ü¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Îʸ¶èÀڤꥢ¥ë¥´¥ê¥º¥à¤ÏÊѹ¹¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£¥½¡¼¥¹¡¦¥³¡¼¥É¤òÊѹ¹¤»¤º¡¢SE 1\&.4\&.x¤Ç¤Î\fB\-breakiterator\fR¥ª¥×¥·¥ç¥ó¤Î·Ù¹ð¤ò½üµî¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ç¤â¡¢²¿¤â¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£Java SE 1\&.5\&.0¤«¤é¤Ï·Ù¹ð¤Ï¾ÃÌǤ·¤Æ¤¤¤Þ¤¹¡£
+@@ -2734,18 +3399,37 @@
+ .RE
+ .\}
+ .RE
++.PP
++\-javafx
++.RS 4
++ɸ½à¥É¥Ã¥¯¥ì¥Ã¥È¤ËÂФ·¤ÆJavaFX³ÈÄ¥µ¡Ç½¤ò»ÈÍѤ·¤Æ¡¢HTML¥É¥­¥å¥á¥ó¥È¤òÀ¸À®¤·¤Þ¤¹¡£À¸À®¤µ¤ì¤¿¥É¥­¥å¥á¥ó¥È¤Ë¤Ï¡¢É¸½àJava¥É¥Ã¥¯¥ì¥Ã¥È¤ÇÀ¸À®¤µ¤ì¤¿Â¾¤Î¥µ¥Þ¥ê¡¼¡¦¥»¥¯¥·¥ç¥ó¤Ë²Ã¤¨¤Æ¡Ö¥×¥í¥Ñ¥Æ¥£¤Î¥µ¥Þ¥ê¡¼¡×¥»¥¯¥·¥ç¥ó¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£¥ê¥¹¥È¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤Ï¡¢³Æ¥×¥í¥Ñ¥Æ¥£¤Îgetter¤ª¤è¤Ósetter¥á¥½¥Ã¥É¤Î¥»¥¯¥·¥ç¥ó¤Ë¥ê¥ó¥¯¤µ¤ì¤Þ¤¹¡£
++.sp
++getter¤ª¤è¤Ósetter¥á¥½¥Ã¥É¤ËÂФ·¤ÆÌÀ¼¨Åª¤Ëµ­ºÜ¤µ¤ì¤Æ¤¤¤ë¥É¥­¥å¥á¥ó¥È¡¦¥³¥á¥ó¥È¤¬¤Ê¤¤¾ì¹ç¡¢¥×¥í¥Ñ¥Æ¥£¡¦¥á¥½¥Ã¥É¤Î¥É¥­¥å¥á¥ó¥È¡¦¥³¥á¥ó¥È¤¬¤³¤ì¤é¤Î¥á¥½¥Ã¥É¤ËÂФ·¤ÆÀ¸À®¤µ¤ì¤¿¥É¥­¥å¥á¥ó¥È¤Ë¼«Æ°Åª¤Ë¥³¥Ô¡¼¤µ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤòµ­½Ò¤Ç¤­¤ë¿·¤·¤¤\fB@defaultValue\fR¥¿¥°¤âÄɲä·¤Þ¤¹¡£
++.sp
++Îã:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjavadoc \-javafx MyClass\&.java \-d testdir\fR
++.fi
++.if n \{\
++.RE
++.\}
++.RE
+ .SS "ɸ½à¥É¥Ã¥¯¥ì¥Ã¥È¤Î¥ª¥×¥·¥ç¥ó"
+ .PP
+ \-d \fIdirectory\fR
+ .RS 4
+ \fBjavadoc\fR¥³¥Þ¥ó¥É¤¬À¸À®¤µ¤ì¤¿HTML¥Õ¥¡¥¤¥ë¤òÊݸ¤¹¤ëÀ¸À®Àè¥Ç¥£¥ì¥¯¥È¥ê¤ò»ØÄꤷ¤Þ¤¹¡£\fB\-d\fR¥ª¥×¥·¥ç¥ó¤ò¾Êά¤¹¤ë¤È¡¢¥Õ¥¡¥¤¥ë¤Ï¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ËÊݸ¤µ¤ì¤Þ¤¹¡£\fBdirectory\fR¤ÎÃͤˤϡ¢ÀäÂХǥ£¥ì¥¯¥È¥ê¡¢¤Þ¤¿¤Ï¸½ºß¤Îºî¶È¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤ÎÁêÂХǥ£¥ì¥¯¥È¥ê¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£Java SE 1\&.4¤Ç¤Ï¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤¹¤ë¤ÈÀ¸À®Àè¥Ç¥£¥ì¥¯¥È¥ê¤¬¼«Æ°Åª¤ËºîÀ®¤µ¤ì¤Þ¤¹¡£
+ .sp
+-¤¿¤È¤¨¤Ð¡¢¼¡¤ÎÎã¤Ç¤Ï¡¢\fBcom\&.mypackage\fR¥Ñ¥Ã¥±¡¼¥¸¤Î¥É¥­¥å¥á¥ó¥È¤¬À¸À®¤µ¤ì¡¢¤½¤Î·ë²Ì¤¬/user/doc/ ¥Ç¥£¥ì¥¯¥È¥ê¤ËÊݸ¤µ¤ì¤Þ¤¹¡£\fBjavadoc \-d \fR\fB/user/doc/ \fR\fBcom\&.mypackage\fR
++¤¿¤È¤¨¤Ð¡¢¼¡¤ÎÎã¤Ç¤Ï¡¢\fBcom\&.mypackage\fR¥Ñ¥Ã¥±¡¼¥¸¤Î¥É¥­¥å¥á¥ó¥È¤¬À¸À®¤µ¤ì¡¢¤½¤Î·ë²Ì¤¬/user/doc/¥Ç¥£¥ì¥¯¥È¥ê¤ËÊݸ¤µ¤ì¤Þ¤¹¡£\fBjavadoc \-d \fR\fB/user/doc/ \fR\fBcom\&.mypackage\fR
+ .RE
+ .PP
+ \-use
+ .RS 4
+-¥É¥­¥å¥á¥ó¥È²½¤µ¤ì¤ë¥¯¥é¥¹¤ª¤è¤Ó¥Ñ¥Ã¥±¡¼¥¸¤´¤È¤Ë1¤Ä¤Î»ÈÍÑ¥Ú¡¼¥¸¤òÁȤ߹þ¤ß¤Þ¤¹¡£¤³¤Î¥Ú¡¼¥¸¤Ë¤Ï¡¢¤½¤ÎÆÃÄê¤Î¥¯¥é¥¹¤Þ¤¿¤Ï¥Ñ¥Ã¥±¡¼¥¸¤ÎAPI¤ò»ÈÍѤ·¤Æ¤¤¤ë¥Ñ¥Ã¥±¡¼¥¸¡¢¥¯¥é¥¹¡¢¥á¥½¥Ã¥É¡¢¥³¥ó¥¹¥È¥é¥¯¥¿¡¢¤ª¤è¤Ó¥Õ¥£¡¼¥ë¥É¤¬µ­½Ò¤µ¤ì¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¥¯¥é¥¹C¤òÎã¤Ë¤È¤ë¤È¡¢¥¯¥é¥¹C¤ò»ÈÍѤ·¤Æ¤¤¤ë¤â¤Î¤È¤·¤Æ¤Ï¡¢C¤Î¥µ¥Ö¥¯¥é¥¹¡¢C¤È¤·¤ÆÀë¸À¤µ¤ì¤Æ¤¤¤ë¥Õ¥£¡¼¥ë¥É¡¢C¤òÊÖ¤¹¥á¥½¥Ã¥É¡¢¤ª¤è¤Ó·¿C¤Î¥Ñ¥é¥á¡¼¥¿¤ò»ý¤Ä¥á¥½¥Ã¥É¤È¥³¥ó¥¹¥È¥é¥¯¥¿¤¬¤¢¤ê¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢\fBString\fR·¿ÍѤλÈÍÑ¥Ú¡¼¥¸¤òɽ¼¨¤Ç¤­¤Þ¤¹¡£\fBjava\&.awt\&.Font\fR¥¯¥é¥¹¤Î\fBgetName\fR¥á¥½¥Ã¥É¤Ï\fBString\fR·¿¤òÌ᤹¤Î¤Ç¡¢\fBgetName\fR¥á¥½¥Ã¥É¤Ï\fBString\fR¤ò»ÈÍѤ·¡¢\fBgetName\fR¥á¥½¥Ã¥É¤¬\fBString\fRÍѤλÈÍÑ¥Ú¡¼¥¸¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£¤³¤ì¤Ï¼ÂÁõ¤Ç¤Ï¤Ê¤¯API¤Î»ÈÍѤΤߤò¥É¥­¥å¥á¥ó¥È²½¤·¤Þ¤¹¡£¥á¥½¥Ã¥É¤¬¤½¤Î¼ÂÁõ¤Ç\fBString\fR¤ò»ÈÍѤ¹¤ë¤¬¡¢°ú¿ô¤È¤·¤Æʸ»úÎó¤ò¼è¤é¤Ê¤¤¡¢¤Þ¤¿¤Ïʸ»úÎó¤òÊÖ¤µ¤Ê¤¤¾ì¹ç¡¢¤½¤ì¤Ï\fBString\fR¤Î»ÈÍѤȤϤߤʤµ¤ì¤Þ¤»¤ó¡£À¸À®¤µ¤ì¤¿»ÈÍÑ¥Ú¡¼¥¸¤Ë¥¢¥¯¥»¥¹¤¹¤ë¤Ë¤Ï¡¢¥¯¥é¥¹¤Þ¤¿¤Ï¥Ñ¥Ã¥±¡¼¥¸¤Ë°ÜÆ°¤·¡¢¥Ê¥Ó¥²¡¼¥·¥ç¥ó¡¦¥Ð¡¼¤Î\fB¥ê¥ó¥¯¤Î»ÈÍÑ\fR¤ò¥¯¥ê¥Ã¥¯¤·¤Þ¤¹¡£
++¥É¥­¥å¥á¥ó¥È²½¤µ¤ì¤ë¥¯¥é¥¹¤ª¤è¤Ó¥Ñ¥Ã¥±¡¼¥¸¤´¤È¤Ë1¤Ä¤Î¡Ö»ÈÍѡץڡ¼¥¸¤òÁȤ߹þ¤ß¤Þ¤¹¡£¤³¤Î¥Ú¡¼¥¸¤Ë¤Ï¡¢¤½¤ÎÆÃÄê¤Î¥¯¥é¥¹¤Þ¤¿¤Ï¥Ñ¥Ã¥±¡¼¥¸¤ÎAPI¤ò»ÈÍѤ·¤Æ¤¤¤ë¥Ñ¥Ã¥±¡¼¥¸¡¢¥¯¥é¥¹¡¢¥á¥½¥Ã¥É¡¢¥³¥ó¥¹¥È¥é¥¯¥¿¡¢¤ª¤è¤Ó¥Õ¥£¡¼¥ë¥É¤¬µ­½Ò¤µ¤ì¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¥¯¥é¥¹C¤òÎã¤Ë¤È¤ë¤È¡¢¥¯¥é¥¹C¤ò»ÈÍѤ·¤Æ¤¤¤ë¤â¤Î¤È¤·¤Æ¤Ï¡¢C¤Î¥µ¥Ö¥¯¥é¥¹¡¢C¤È¤·¤ÆÀë¸À¤µ¤ì¤Æ¤¤¤ë¥Õ¥£¡¼¥ë¥É¡¢C¤òÊÖ¤¹¥á¥½¥Ã¥É¡¢¤ª¤è¤Ó·¿C¤Î¥Ñ¥é¥á¡¼¥¿¤ò»ý¤Ä¥á¥½¥Ã¥É¤È¥³¥ó¥¹¥È¥é¥¯¥¿¤¬¤¢¤ê¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢\fBString\fR·¿ÍѤΡֻÈÍѡץڡ¼¥¸¤òɽ¼¨¤Ç¤­¤Þ¤¹¡£\fBjava\&.awt\&.Font\fR¥¯¥é¥¹¤Î\fBgetName\fR¥á¥½¥Ã¥É¤Ï\fBString\fR·¿¤òÌ᤹¤Î¤Ç¡¢\fBgetName\fR¥á¥½¥Ã¥É¤Ï\fBString\fR¤ò»ÈÍѤ·¡¢\fBgetName\fR¥á¥½¥Ã¥É¤¬\fBString\fRÍѤΡֻÈÍѡץڡ¼¥¸¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£¤³¤ì¤Ï¼ÂÁõ¤Ç¤Ï¤Ê¤¯API¤Î»ÈÍѤΤߤò¥É¥­¥å¥á¥ó¥È²½¤·¤Þ¤¹¡£¥á¥½¥Ã¥É¤¬¤½¤Î¼ÂÁõ¤Ç\fBString\fR¤ò»ÈÍѤ¹¤ë¤¬¡¢°ú¿ô¤È¤·¤Æʸ»úÎó¤ò¼è¤é¤Ê¤¤¡¢¤Þ¤¿¤Ïʸ»úÎó¤òÊÖ¤µ¤Ê¤¤¾ì¹ç¡¢¤½¤ì¤Ï\fBString\fR¤Î»ÈÍѤȤϤߤʤµ¤ì¤Þ¤»¤ó¡£À¸À®¤µ¤ì¤¿¡Ö»ÈÍѡץڡ¼¥¸¤Ë¥¢¥¯¥»¥¹¤¹¤ë¤Ë¤Ï¡¢¥¯¥é¥¹¤Þ¤¿¤Ï¥Ñ¥Ã¥±¡¼¥¸¤Ë°ÜÆ°¤·¡¢¥Ê¥Ó¥²¡¼¥·¥ç¥ó¡¦¥Ð¡¼¤Î\fB¥ê¥ó¥¯¤Î»ÈÍÑ\fR¤ò¥¯¥ê¥Ã¥¯¤·¤Þ¤¹¡£
+ .RE
+ .PP
+ \-version
+@@ -2847,9 +3531,7 @@
+ .PP
+ ³°ÉôAPI¥É¥­¥å¥á¥ó¥È¤Ø¤ÎÀäÂÐURL¤ò»ÈÍѤ¹¤ë¾ì¹ç(¤½¤ÎURL¤ËÀܳ¤·¡¢Æɼè¤ê¤ò¹Ô¤¦¤³¤È¤¬¥·¥§¥ë¤Ë¤è¤Ã¤Æµö²Ä¤µ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç)¤Ï\fB\-linkoffline\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Þ¤¹¡£¤³¤Î¤è¤¦¤Ê¾õ¶·¤Ï¡¢¥Õ¥¡¥¤¥¢¥¦¥©¡¼¥ë¤ÎÆ⦤«¤é¥Õ¥¡¥¤¥¢¥¦¥©¡¼¥ë¤Î³°Â¦¤Ë¤¢¤ë¥É¥­¥å¥á¥ó¥È¤Ë¥ê¥ó¥¯¤·¤è¤¦¤È¤¹¤ë¾ì¹ç¤ËȯÀ¸¤·¤Þ¤¹¡£
+ .PP
+-\fBÎã 1\fR
+-.br
+-³°Éô¥É¥­¥å¥á¥ó¥È¤Ø¤ÎÀäÂÐ¥ê¥ó¥¯
++\fBÎã 1 \fR³°Éô¥É¥­¥å¥á¥ó¥È¤Ø¤ÎÀäÂÐ¥ê¥ó¥¯
+ .RS 4
+ http://docs\&.oracle\&.com/javase/8/docs/api/index\&.html¤Ë¼¨¤¹¤è¤¦¤Ê¡¢\fBjava\&.lang\fR¡¢\fBjava\&.io\fR¤ª¤è¤Ó¤½¤Î¾¤ÎJava¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¡¦¥Ñ¥Ã¥±¡¼¥¸¤Ë¥ê¥ó¥¯¤¹¤ë¾ì¹ç¡¢¼¡¤Î¥³¥Þ¥ó¥É¤ò»ÈÍѤ·¤Þ¤¹
+ .sp
+@@ -2866,9 +3548,7 @@
+ ¤³¤Î¥³¥Þ¥ó¥É¤Ï¡¢Java SE¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¡¦¥Ñ¥Ã¥±¡¼¥¸¤Ø¤Î¥ê¥ó¥¯»ý¤Ä\fBcom\&.mypackage\fR¥Ñ¥Ã¥±¡¼¥¸¤Î¥É¥­¥å¥á¥ó¥È¤òÀ¸À®¤·¤Þ¤¹¡£À¸À®¥É¥­¥å¥á¥ó¥È¤Ë¤Ï¡¢¤¿¤È¤¨¤Ð¥¯¥é¥¹\fBtrees\fRÆâ¤Î\fBObject\fR¥¯¥é¥¹¤Ø¤Î¥ê¥ó¥¯¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£\fB\-sourcepath\fR¤ä\fB\-d\fR¤Ê¤É¤Î¾¤Î¥ª¥×¥·¥ç¥ó¤Ïɽ¼¨¤µ¤ì¤Þ¤»¤ó¡£
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-³°Éô¥É¥­¥å¥á¥ó¥È¤Ø¤ÎÁêÂÐ¥ê¥ó¥¯
++\fBÎã 2 \fR³°Éô¥É¥­¥å¥á¥ó¥È¤Ø¤ÎÁêÂÐ¥ê¥ó¥¯
+ .RS 4
+ ¤³¤ÎÎã¤Ç¤Ï¡¢2¤Ä¤Î¥Ñ¥Ã¥±¡¼¥¸¤¬¤¢¤ê¡¢¤½¤Î¥É¥­¥å¥á¥ó¥È¤Ï\fBjavadoc\fR¥³¥Þ¥ó¥É¤òÊ£¿ô²ó¼Â¹Ô¤·¤¿·ë²ÌÀ¸À®¤µ¤ì¤¿¤â¤Î¤Ç¤¹¡£¤µ¤é¤Ë¡¢¤³¤ì¤é¤Î¥É¥­¥å¥á¥ó¥È¤ÏÁêÂХѥ¹¤Çʬ³ä¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¥Ñ¥Ã¥±¡¼¥¸¤Ï¡¢API¤Ç¤¢¤ë\fBcom\&.apipackage\fR¤È¡¢SPI(¥µ¡¼¥Ó¥¹¡¦¥×¥í¥Ð¥¤¥À¡¦¥¤¥ó¥¿¥Õ¥§¡¼¥¹)¤Ç¤¢¤ëc\fBom\&.spipackage\fR¤Ç¤¹¡£¥É¥­¥å¥á¥ó¥È¤Î³ÊǼÀè¤Ï¡¢docs/api/com/apipackage¤Èdocs/spi/com/spipackage¤Ç¤¹¡£API¥Ñ¥Ã¥±¡¼¥¸¤Î¥É¥­¥å¥á¥ó¥È¤Ï¤¹¤Ç¤ËÀ¸À®¤µ¤ì¤Æ¤¤¤Æ¡¢docs¤¬¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¢¤ë¾ì¹ç¡¢API¥É¥­¥å¥á¥ó¥È¤Ø¤Î¥ê¥ó¥¯¤ò»ý¤ÄSPI¥Ñ¥Ã¥±¡¼¥¸¤ò¥É¥­¥å¥á¥ó¥È²½¤¹¤ë¤Ë¤Ï¡¢¼¡¤Î¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Þ¤¹¡£\fBjavadoc \-d \&./spi \-link \&.\&./api com\&.spipackage\fR
+ .sp
+@@ -3034,7 +3714,7 @@
+ .PP
+ ¥É¥­¥å¥á¥ó¥È¤Î¹¹¿·
+ .PP
+-¥×¥í¥¸¥§¥¯¥È¤Ë²¿½½¤Þ¤¿¤Ï²¿É´¤Î¥Ñ¥Ã¥±¡¼¥¸¤¬´Þ¤Þ¤ì¤ë¾ì¹ç¤Ë¤â¡¢\fB\-linkoffline\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤǤ­¤Þ¤¹¡£¥½¡¼¥¹¡¦¥Ä¥ê¡¼Á´ÂΤǤ¹¤Ç¤Ë\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤¿¤³¤È¤¬¤¢¤ë¾ì¹ç¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤Ë¤ï¤º¤«¤ÊÊѹ¹¤ò¿×®¤Ë²Ã¤¨¡¢¥½¡¼¥¹¡¦¥Ä¥ê¡¼¤Î°ìÉô¤Ç\fBjavadoc\fR¥³¥Þ¥ó¥É¤òºÆ¼Â¹Ô¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£2²óÌܤμ¹Ԥϡ¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤òÊѹ¹¤·¡¢Àë¸À¤ÏÊѹ¹¤·¤Ê¤¤¾ì¹ç¤Ë¤Î¤ßÀµ¤·¤¯½èÍý¤µ¤ì¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¥½¡¼¥¹¡¦¥³¡¼¥É¤ËÂФ·¤ÆÀë¸À¤òÄɲᢺï½ü¡¢¤Þ¤¿¤ÏÊѹ¹¤·¤¿¾ì¹ç¤Ï¡¢º÷°ú¡¢¥Ñ¥Ã¥±¡¼¥¸¡¦¥Ä¥ê¡¼¡¢·Ñ¾µ¤µ¤ì¤ë¥á¥ó¥Ð¡¼¤Î¥ê¥¹¥È¡¢»ÈÍÑ¥Ú¡¼¥¸¤Ê¤É¤Î¾ì½ê¤Ç¡¢¥ê¥ó¥¯¤¬²õ¤ì¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£
++¥×¥í¥¸¥§¥¯¥È¤Ë²¿½½¤Þ¤¿¤Ï²¿É´¤Î¥Ñ¥Ã¥±¡¼¥¸¤¬´Þ¤Þ¤ì¤ë¾ì¹ç¤Ë¤â¡¢\fB\-linkoffline\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤǤ­¤Þ¤¹¡£¥½¡¼¥¹¡¦¥Ä¥ê¡¼Á´ÂΤǤ¹¤Ç¤Ë\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤¿¤³¤È¤¬¤¢¤ë¾ì¹ç¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤Ë¤ï¤º¤«¤ÊÊѹ¹¤ò¿×®¤Ë²Ã¤¨¡¢¥½¡¼¥¹¡¦¥Ä¥ê¡¼¤Î°ìÉô¤Ç\fBjavadoc\fR¥³¥Þ¥ó¥É¤òºÆ¼Â¹Ô¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£2²óÌܤμ¹Ԥϡ¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤òÊѹ¹¤·¡¢Àë¸À¤ÏÊѹ¹¤·¤Ê¤¤¾ì¹ç¤Ë¤Î¤ßÀµ¤·¤¯½èÍý¤µ¤ì¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¥½¡¼¥¹¡¦¥³¡¼¥É¤ËÂФ·¤ÆÀë¸À¤òÄɲᢺï½ü¡¢¤Þ¤¿¤ÏÊѹ¹¤·¤¿¾ì¹ç¤Ï¡¢º÷°ú¡¢¥Ñ¥Ã¥±¡¼¥¸¡¦¥Ä¥ê¡¼¡¢·Ñ¾µ¤µ¤ì¤ë¥á¥ó¥Ð¡¼¤Î¥ê¥¹¥È¡¢¡Ö»ÈÍѡץڡ¼¥¸¤Ê¤É¤Î¾ì½ê¤Ç¡¢¥ê¥ó¥¯¤¬²õ¤ì¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£
+ .PP
+ ¤Þ¤º¡¢¤³¤Î¿·¤·¤¤¾®µ¬ÌϤʼ¹ԤǻÈÍѤ¹¤ë¡¢¿·¤·¤¤À¸À®Àè¥Ç¥£¥ì¥¯¥È¥ê(update¤Ê¤É)¤òºîÀ®¤·¤Þ¤¹¡£¤³¤ÎÎã¤Ç¤Ï¡¢¸µ¤ÎÀ¸À®Àè¥Ç¥£¥ì¥¯¥È¥ê¤Î̾Á°¤Ïhtml¤Ç¤¹¡£ºÇ¤âñ½ã¤ÊÎã¤Ç¤Ï¡¢html¥Ç¥£¥ì¥¯¥È¥ê¤Î¿Æ¥Ç¥£¥ì¥¯¥È¥ê¤Ë°ÜÆ°¤·¤Þ¤¹¡£\fB\-linkoffline\fR¥ª¥×¥·¥ç¥ó¤ÎÂè1°ú¿ô¤Ë¥«¥ì¥ó¥È¡¦¥Ç¥£¥ì¥¯¥È¥ê(\&.)¤òÀßÄꤷ¡¢Âè2°ú¿ô¤Ëpackage\-list¤¬¸¡º÷¤µ¤ì¤ëhtml¤Ø¤ÎÁêÂХѥ¹¤òÀßÄꤷ¡¢¹¹¿·¤¹¤ë¥Ñ¥Ã¥±¡¼¥¸¤Î¥Ñ¥Ã¥±¡¼¥¸Ì¾¤Î¤ß¤òÅϤ·¤Þ¤¹¡£
+ .sp
+@@ -3053,7 +3733,7 @@
+ .PP
+ \-linksource
+ .RS 4
+-³Æ¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë(¹ÔÈÖ¹æÉÕ¤­)¤ÎHTML¥Ð¡¼¥¸¥ç¥ó¤òºîÀ®¤·¡¢É¸½àHTML¥É¥­¥å¥á¥ó¥È¤«¤é¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Ø¤Î¥ê¥ó¥¯¤òÄɲä·¤Þ¤¹¡£¥ê¥ó¥¯¤Ï¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ëÆâ¤ËÀë¸À¤µ¤ì¤Æ¤¤¤ë¥¯¥é¥¹¡¢¥¤¥ó¥¿¥Õ¥§¡¼¥¹¡¢¥³¥ó¥¹¥È¥é¥¯¥¿¡¢¥á¥½¥Ã¥É¡¢¥Õ¥£¡¼¥ë¥É¤ËÂФ·¤ÆºîÀ®¤µ¤ì¤Þ¤¹¡£¤½¤¦¤Ç¤Ê¤¤¾ì¹ç¡¢¤¿¤È¤¨¤Ð¥Ç¥Õ¥©¥ë¥È¡¦¥³¥ó¥¹¥È¥é¥¯¥¿¤äÀ¸À®¤µ¤ì¤¿¥¯¥é¥¹¤ËÂФ·¤Æ¤Ï¡¢¥ê¥ó¥¯¤ÏºîÀ®¤µ¤ì¤Þ¤»¤ó¡£
++³Æ¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë(¹ÔÈÖ¹æÉÕ¤­)¤ÎHTML¥Ð¡¼¥¸¥ç¥ó¤òºîÀ®¤·¡¢É¸½àHTML¥É¥­¥å¥á¥ó¥È¤«¤é¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Ø¤Î¥ê¥ó¥¯¤òÄɲä·¤Þ¤¹¡£¥ê¥ó¥¯¤Ï¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ëÆâ¤ËÀë¸À¤µ¤ì¤Æ¤¤¤ë¥¯¥é¥¹¡¢¥¤¥ó¥¿¥Õ¥§¡¼¥¹¡¢¥³¥ó¥¹¥È¥é¥¯¥¿¡¢¥á¥½¥Ã¥É¡¢¥Õ¥£¡¼¥ë¥É¤ËÂФ·¤ÆºîÀ®¤µ¤ì¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¡¦¥³¥ó¥¹¥È¥é¥¯¥¿¡¢À¸À®¤µ¤ì¤¿¥¯¥é¥¹¤Ê¤É¤ËÂФ·¤Æ¤ÏºîÀ®¤µ¤ì¤Þ¤»¤ó¡£
+ .sp
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢\fB\-public\fR¡¢\fB\-package\fR¡¢\fB\-protected\fR¤ª¤è¤Ó\fB\-private\fR¤Î³Æ¥ª¥×¥·¥ç¥ó¤È¤Ï´Ø·¸¤Ê¤¯¡¢Èó¸ø³«¤Î¥¯¥é¥¹¡¢¥Õ¥£¡¼¥ë¥É¡¢Èó¸ø³«¤Î¥á¥½¥Ã¥É¤ÎËÜÂΤò¤Ï¤¸¤á¤È¤¹¤ëÁȤ߹þ¤Þ¤ì¤¿¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ëÆâ¤Î¤¹¤Ù¤Æ¤ÎÈó¸ø³«¼ÂÁõ¤Î¾ÜºÙ¤ò¸ø³«¤·¤Þ¤¹¡£\fB\-private\fR¥ª¥×¥·¥ç¥ó¤â¤¢¤ï¤»¤Æ»ØÄꤷ¤Ê¤¤¤«¤®¤ê¡¢Èó¸ø³«¤Î¥¯¥é¥¹¤ä¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤Î°ìÉô¤Ë¤Ï¡¢¥ê¥ó¥¯¤ò²ð¤·¤Æ¥¢¥¯¥»¥¹¤Ç¤­¤Ê¤¤¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£
+ .sp
+@@ -3342,7 +4022,7 @@
+ .sp
+ ɸ½à¥¿¥°¤Ï¡¢ºÇ½é¡¢¥Ç¥Õ¥©¥ë¥È¤Î½ç½ø¤Ç¥ê¥¹¥ÈÆâ¤ËÆâÉôŪ¤Ë³ÊǼ¤µ¤ì¤Þ¤¹¡£\fB\-tag\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤È¡¢¤½¤ì¤é¤Î¥¿¥°¤Ï¤³¤Î¥ê¥¹¥È¤ËÄɲ䵤ì¤Þ¤¹¡£É¸½à¥¿¥°¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Î°ÌÃÖ¤«¤é°ÜÆ°¤µ¤ì¤Þ¤¹¡£¤½¤Î¤¿¤á¡¢É¸½à¥¿¥°¤Î\fB\-tag\fR¥ª¥×¥·¥ç¥ó¤ò¾Êά¤¹¤ë¤È¡¢¤½¤ì¤Ï¥Ç¥Õ¥©¥ë¥È¤Î°ÌÃÖ¤ËÇÛÃÖ¤µ¤ì¤¿¤Þ¤Þ¤Ë¤Ê¤ê¤Þ¤¹¡£
+ .sp
+-\fB¶¥¹ç¤Î²óÈò\fR: ¸ÇÍ­¤Î̾Á°¶õ´Ö¤òºîÀ®¤¹¤ë¤Ë¤Ï¡¢¥Ñ¥Ã¥±¡¼¥¸¤Ë»ÈÍѤµ¤ì¤Æ¤¤¤ë\fBcom\&.mycompany\&.todo\fR¤È¤¤¤¦Ì¾Á°¤Î¤è¤¦¤Ë¡¢¥É¥Ã¥È¤Ç¶èÀÚ¤é¤ì¤¿Ì¾Á°¤ò»ÈÍѤ·¤Þ¤¹¡£Oracle¤Ï¡¢º£¸å¤â̾Á°¤Ë¥É¥Ã¥È¤ò´Þ¤Þ¤Ê¤¤É¸½à¥¿¥°¤òºîÀ®¤·¤Þ¤¹¡£¥æ¡¼¥¶¡¼¤¬ºîÀ®¤·¤¿¥¿¥°¤Ï¡¢Oracle¤¬ÄêµÁ¤¹¤ëƱ¤¸Ì¾Á°¤Î¥¿¥°¤ÎÆ°ºî¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Þ¤¹¡£\fB@todo\fR¤È¤¤¤¦Ì¾Á°¤Î¥¿¥°¤Þ¤¿¤Ï¥¿¥°¥ì¥Ã¥È¤ò¥æ¡¼¥¶¡¼¤¬ºîÀ®¤·¤¿¾ì¹ç¡¢¤½¤Î¸å¤ËOracle¤¬Æ±¤¸Ì¾Á°¤Îɸ½à¥¿¥°¤òºîÀ®¤·¤Æ¤â¡¢¤½¤Î¥¿¥°¤Þ¤¿¤Ï¥¿¥°¥ì¥Ã¥È¤Ï¾ï¤Ë¥æ¡¼¥¶¡¼¤¬ÄêµÁ¤·¤¿¤Î¤ÈƱ¤¸Æ°ºî¤òÊÝ»ý¤·¤Þ¤¹¡£
++\fB¶¥¹ç¤Î²óÈò\fR: ¸ÇÍ­¤Î̾Á°¶õ´Ö¤òºîÀ®¤¹¤ë¾ì¹ç¡¢¥Ñ¥Ã¥±¡¼¥¸¤Ë»ÈÍѤµ¤ì¤Æ¤¤¤ë\fBcom\&.mycompany\&.todo\fR¤Î¤è¤¦¤Ê¥É¥Ã¥È¤Ç¶èÀÚ¤ê¤Î̿̾µ¬Â§¤ò»ÈÍѤǤ­¤Þ¤¹¡£Oracle¤Ï¡¢º£¸å¤â̾Á°¤Ë¥É¥Ã¥È¤ò´Þ¤Þ¤Ê¤¤É¸½à¥¿¥°¤òºîÀ®¤·¤Þ¤¹¡£¥æ¡¼¥¶¡¼¤¬ºîÀ®¤·¤¿¥¿¥°¤Ï¡¢Oracle¤¬ÄêµÁ¤¹¤ëƱ¤¸Ì¾Á°¤Î¥¿¥°¤ÎÆ°ºî¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Þ¤¹¡£\fB@todo\fR¤È¤¤¤¦Ì¾Á°¤Î¥¿¥°¤Þ¤¿¤Ï¥¿¥°¥ì¥Ã¥È¤ò¥æ¡¼¥¶¡¼¤¬ºîÀ®¤·¤¿¾ì¹ç¡¢¤½¤Î¸å¤ËOracle¤¬Æ±¤¸Ì¾Á°¤Îɸ½à¥¿¥°¤òºîÀ®¤·¤Æ¤â¡¢¤½¤Î¥¿¥°¤Þ¤¿¤Ï¥¿¥°¥ì¥Ã¥È¤Ï¾ï¤Ë¥æ¡¼¥¶¡¼¤¬ÄêµÁ¤·¤¿¤Î¤ÈƱ¤¸Æ°ºî¤òÊÝ»ý¤·¤Þ¤¹¡£
+ .sp
+ \fBÃí¼ávs\&. Javadoc¥¿¥°\fR: °ìÈ̤ˡ¢Äɲ乤ëɬÍפΤ¢¤ë¥Þ¡¼¥¯¥¢¥Ã¥×¤¬¡¢¥É¥­¥å¥á¥ó¥È¤Ë±Æ¶Á¤òÍ¿¤¨¤¿¤ê¥É¥­¥å¥á¥ó¥È¤òÀ¸À®¤·¤¿¤ê¤¹¤ë¤¿¤á¤Î¤â¤Î¤Ç¤¢¤ë¾ì¹ç¡¢¤½¤Î¥Þ¡¼¥¯¥¢¥Ã¥×¤ÏJavadoc¥¿¥°¤Ë¤·¤Þ¤¹¡£¤½¤ì°Ê³°¤Î¾ì¹ç¤ÏÃí¼á¤Ë¤·¤Þ¤¹¡£Javadoc¥Ä¡¼¥ë¤Ç¤ÎDoc¥³¥á¥ó¥È¤Îµ­½ÒÊýË¡¤Î¥«¥¹¥¿¥à¡¦¥¿¥°¤ÈÃí¼á¤Ë´Ø¤¹¤ë¹à
+ (http://www\&.oracle\&.com/technetwork/java/javase/documentation/index\-137868\&.html#annotations)¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+@@ -3428,16 +4108,12 @@
+ .PP
+ \fBjavadoc\fR¤ò¼Â¹Ô¤¹¤ë¤È¤­¤Ë¡¢³Æ°ú¿ô¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤È¥Õ¥¡¥¤¥ë̾¤ÎÀèƬ¤Ë@ʸ»ú¤òÉÕ¤±¤ÆÅϤ·¤Þ¤¹¡£\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¡¢¥¢¥Ã¥È¥Þ¡¼¥¯(@)ʸ»ú¤Ç»Ï¤Þ¤ë°ú¿ô¤ò¸«¤Ä¤±¤ë¤È¡¢¤½¤Î¥Õ¥¡¥¤¥ë¤ÎÆâÍƤòŸ³«¤·¤Æ°ú¿ô¥ê¥¹¥È¤ËÁÞÆþ¤·¤Þ¤¹¡£
+ .PP
+-\fBÎã 1\fR
+-.br
+-ñ°ì¤Î°ú¿ô¥Õ¥¡¥¤¥ë
++\fBÎã 1 \fRñ°ì¤Î°ú¿ô¥Õ¥¡¥¤¥ë
+ .RS 4
+ \fBargfile\fR¤È¤¤¤¦Ì¾Á°¤Î1¤Ä¤Î°ú¿ô¥Õ¥¡¥¤¥ë¤ò»ÈÍѤ·¤Æ¡¢¤¹¤Ù¤Æ¤Î\fBjavadoc\fR¥³¥Þ¥ó¥É°ú¿ô¤òÊÝ»ý¤Ç¤­¤Þ¤¹¡£\fBjavadoc @argfile\fR¼¡¤ÎÎã¤Ë¼¨¤¹¤è¤¦¤Ë¡¢¤³¤Î°ú¿ô¥Õ¥¡¥¤¥ë¤Ë¤ÏξÊý¤Î¥Õ¥¡¥¤¥ë¤ÎÆâÍƤ¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-2¤Ä¤Î°ú¿ô¥Õ¥¡¥¤¥ë
++\fBÎã 2 \fR2¤Ä¤Î°ú¿ô¥Õ¥¡¥¤¥ë
+ .RS 4
+ ¼¡¤Î¤è¤¦¤Ë¡¢2¤Ä¤Î°ú¿ô¥Õ¥¡¥¤¥ë¤òºîÀ®¤Ç¤­¤Þ¤¹¡£\fBjavadoc\fR¥³¥Þ¥ó¥É¤Î¥ª¥×¥·¥ç¥óÍѤË1¤Ä¡¢¥Ñ¥Ã¥±¡¼¥¸Ì¾¤Þ¤¿¤Ï¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾ÍѤË1¤Ä¤Ç¤¹¡£¼¡¤Î¥ê¥¹¥È¤Ç¤Ï¹Ô·Ñ³ʸ»ú¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤»¤ó¡£
+ .sp
+@@ -3490,9 +4166,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 3\fR
+-.br
+-¥Ñ¥¹¤ò»ÈÍѤ·¤¿°ú¿ô¥Õ¥¡¥¤¥ë
++\fBÎã 3 \fR¥Ñ¥¹¤ò»ÈÍѤ·¤¿°ú¿ô¥Õ¥¡¥¤¥ë
+ .RS 4
+ °ú¿ô¥Õ¥¡¥¤¥ë¤Ï¥Ñ¥¹¤ò»ØÄê¤Ç¤­¤Þ¤¹¤¬¡¢¥Õ¥¡¥¤¥ëÆâ¤Î¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë̾¤Ï¡¢(\fBpath1\fR¤ä\fBpath2\fR¤Ç¤Ï¤Ê¤¯)¼¡¤Î¤è¤¦¤Ë¸½ºß¤Îºî¶È¥Ç¥£¥ì¥¯¥È¥ê¤ËÁêÂÐŪ¤È¤Ê¤ê¤Þ¤¹¡£
+ .sp
+@@ -3508,9 +4182,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 4\fR
+-.br
+-¥ª¥×¥·¥ç¥ó°ú¿ô
++\fBÎã 4 \fR¥ª¥×¥·¥ç¥ó°ú¿ô
+ .RS 4
+ ¼¡¤Ë¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤Î¥ª¥×¥·¥ç¥ó¤ËÂФ¹¤ë°ú¿ô¤ò°ú¿ô¥Õ¥¡¥¤¥ë¤Ë³ÊǼ¤¹¤ëÎã¤ò¼¨¤·¤Þ¤¹¡£Ä¹¤¤°ú¿ô¤ò»ØÄê¤Ç¤­¤ë¤Î¤Ç¡¢\fB\-bottom\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Þ¤¹¡£¼¡¤Î¤è¤¦¤Ê¥Æ¥­¥¹¥È°ú¿ô¤ò´Þ¤à¡¢bottom¤È¤¤¤¦Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤òºîÀ®¤Ç¤­¤Þ¤¹¡£
+ .sp
+@@ -3557,12 +4229,9 @@
+ .PP
+ ¥Ç¥£¥ì¥¯¥È¥ê¤ÎÊѹ¹(\fBcd\fR¥³¥Þ¥ó¥É¤ò»ÈÍÑ)¤Þ¤¿¤Ï\fB\-sourcepath\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤Ç¤­¤Þ¤¹¡£¼¡¤ÎÎã¤ÇξÊý¤ÎÁªÂò»è¤ò¼¨¤·¤Þ¤¹¡£
+ .PP
+-\fBÎã 1\fR
+-.br
+-1¤Ä°Ê¾å¤Î¥Ñ¥Ã¥±¡¼¥¸¤«¤éºÆµ¢Åª¤Ë¼Â¹Ô
+-.RS 4
+-¤³¤ÎÎã¤Ç¤Ï\fBjavadoc\fR¥³¥Þ¥ó¥É¤¬Ç¤°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¼Â¹Ô¤Ç¤­¤ë¤è¤¦¤Ë¡¢\fB\-sourcepath\fR¤ò»ÈÍѤ·¡¢ºÆµ¢Åª½èÍý¤Î¤¿¤á¤Ë\fB\-subpackages\fR
+-(1\&.4¤Î¿·¥ª¥×¥·¥ç¥ó)¤ò»ÈÍѤ·¤Þ¤¹¡£¤³¤ì¤Ï¡¢java¥Ç¥£¥ì¥¯¥È¥ê¤Î¥µ¥Ö¥Ñ¥Ã¥±¡¼¥¸¤ò¤¿¤É¤ê¤Þ¤¹¤¬¡¢\fBjava\&.net\fR¤È\fBjava\&.lang\fR¤ò¥ë¡¼¥È¤Ë»ý¤Ä¥Ñ¥Ã¥±¡¼¥¸¤Ï½ü³°¤µ¤ì¤Þ¤¹¡£\fBjava\&.lang\fR¤Î¥µ¥Ö¥Ñ¥Ã¥±¡¼¥¸¤Ç¤¢¤ë\fBjava\&.lang\&.ref\fR¤¬½ü³°¤µ¤ì¤ëÅÀ¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤Þ¤¿¡¢Â¾¤Î¥Ñ¥Ã¥±¡¼¥¸¡¦¥Ä¥ê¡¼¤ò²¼Êý¤Ë¤¿¤É¤ë¤Ë¤Ï¡¢\fBjava:javax:org\&.xml\&.sax\fR¤Î¤è¤¦¤Ë¡¢¤½¤ì¤é¤Î¥Ñ¥Ã¥±¡¼¥¸¤Î̾Á°¤ò\fB\-subpackages\fR¤Î°ú¿ô¤ËÄɲä·¤Þ¤¹¡£
++\fBÎã 1 \fR1¤Ä°Ê¾å¤Î¥Ñ¥Ã¥±¡¼¥¸¤«¤éºÆµ¢Åª¤Ë¼Â¹Ô
++.RS 4
++¤³¤ÎÎã¤Ç¤Ï\fBjavadoc\fR¥³¥Þ¥ó¥É¤¬Ç¤°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¼Â¹Ô¤Ç¤­¤ë¤è¤¦¤Ë¡¢\fB\-sourcepath\fR¤ò»ÈÍѤ·¡¢ºÆµ¢Åª½èÍý¤Î¤¿¤á¤Ë\fB\-subpackages\fR(1\&.4¤Î¿·¥ª¥×¥·¥ç¥ó)¤ò»ÈÍѤ·¤Þ¤¹¡£¤³¤ì¤Ï¡¢java¥Ç¥£¥ì¥¯¥È¥ê¤Î¥µ¥Ö¥Ñ¥Ã¥±¡¼¥¸¤ò¤¿¤É¤ê¤Þ¤¹¤¬¡¢\fBjava\&.net\fR¤È\fBjava\&.lang\fR¤ò¥ë¡¼¥È¤Ë»ý¤Ä¥Ñ¥Ã¥±¡¼¥¸¤Ï½ü³°¤µ¤ì¤Þ¤¹¡£\fBjava\&.lang\fR¤Î¥µ¥Ö¥Ñ¥Ã¥±¡¼¥¸¤Ç¤¢¤ë\fBjava\&.lang\&.ref\fR¤¬½ü³°¤µ¤ì¤ëÅÀ¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤Þ¤¿¡¢Â¾¤Î¥Ñ¥Ã¥±¡¼¥¸¡¦¥Ä¥ê¡¼¤ò²¼Êý¤Ë¤¿¤É¤ë¤Ë¤Ï¡¢\fBjava:javax:org\&.xml\&.sax\fR¤Î¤è¤¦¤Ë¡¢¤½¤ì¤é¤Î¥Ñ¥Ã¥±¡¼¥¸¤Î̾Á°¤ò\fB\-subpackages\fR¤Î°ú¿ô¤ËÄɲä·¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+@@ -3576,9 +4245,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-¥ë¡¼¥È¤Ø¤Î°ÜÆ°¤ª¤è¤ÓÌÀ¼¨Åª¤Ê¥Ñ¥Ã¥±¡¼¥¸¤Î¼Â¹Ô
++\fBÎã 2 \fR¥ë¡¼¥È¤Ø¤Î°ÜÆ°¤ª¤è¤ÓÌÀ¼¨Åª¤Ê¥Ñ¥Ã¥±¡¼¥¸¤Î¼Â¹Ô
+ .RS 4
+ ´°Á´½¤¾þ¤µ¤ì¤¿¥Ñ¥Ã¥±¡¼¥¸¤Î¿Æ¥Ç¥£¥ì¥¯¥È¥ê¤Ë°ÜÆ°¤·¤Þ¤¹¡£¼¡¤Ë¡¢¥É¥­¥å¥á¥ó¥È²½¤¹¤ë1¤Ä°Ê¾å¤Î¥Ñ¥Ã¥±¡¼¥¸¤Î̾Á°¤ò»ØÄꤷ¤Æ\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Þ¤¹¡£
+ .sp
+@@ -3596,9 +4263,7 @@
+ ¤Þ¤¿¡¢Â¾¤Î¥Ñ¥Ã¥±¡¼¥¸¡¦¥Ä¥ê¡¼¤ò²¼Êý¤Ë¤¿¤É¤ë¤Ë¤Ï¡¢j\fBava:javax:org\&.xml\&.sax\fR¤Î¤è¤¦¤Ë¡¢¤½¤ì¤é¤Î¥Ñ¥Ã¥±¡¼¥¸¤Î̾Á°¤ò\fB\-subpackages\fR¤Î°ú¿ô¤ËÄɲä·¤Þ¤¹¡£
+ .RE
+ .PP
+-\fBÎã 3\fR
+-.br
+-1¤Ä¤Î¥Ä¥ê¡¼¤ÎÌÀ¼¨Åª¤Ê¥Ñ¥Ã¥±¡¼¥¸¤ÎǤ°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¼Â¹Ô
++\fBÎã 3 \fR1¤Ä¤Î¥Ä¥ê¡¼¤ÎÌÀ¼¨Åª¤Ê¥Ñ¥Ã¥±¡¼¥¸¤ÎǤ°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¼Â¹Ô
+ .RS 4
+ ¤³¤Î¾ì¹ç¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤¬¤É¤³¤«¤ÏÌäÂê¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¡¢ºÇ¾å°Ì¥Ñ¥Ã¥±¡¼¥¸¤Î¿Æ¥Ç¥£¥ì¥¯¥È¥ê¤ò»ØÄꤷ¤Æ\fB\-sourcepath\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Þ¤¹¡£¥É¥­¥å¥á¥ó¥È²½¤¹¤ë1¤Ä°Ê¾å¤Î¥Ñ¥Ã¥±¡¼¥¸¤Î̾Á°¤ò»ØÄꤷ¤Þ¤¹¡£
+ .sp
+@@ -3614,9 +4279,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 4\fR
+-.br
+-Ê£¿ô¤Î¥Ä¥ê¡¼¤ÎÌÀ¼¨Åª¤Ê¥Ñ¥Ã¥±¡¼¥¸¤ÎǤ°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¼Â¹Ô
++\fBÎã 4 \fRÊ£¿ô¤Î¥Ä¥ê¡¼¤ÎÌÀ¼¨Åª¤Ê¥Ñ¥Ã¥±¡¼¥¸¤ÎǤ°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¼Â¹Ô
+ .RS 4
+ \fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¡¢³Æ¥Ä¥ê¡¼¤Î¥ë¡¼¥È¤Ø¤Î¥Ñ¥¹¤Î¥³¥í¥ó¶èÀÚ¤ê¥ê¥¹¥È¤ò»ØÄꤷ¤Æ\fB\-sourcepath\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Þ¤¹¡£¥É¥­¥å¥á¥ó¥È²½¤¹¤ë1¤Ä°Ê¾å¤Î¥Ñ¥Ã¥±¡¼¥¸¤Î̾Á°¤ò»ØÄꤷ¤Þ¤¹¡£»ØÄꤷ¤¿¥Ñ¥Ã¥±¡¼¥¸¤Î¤¹¤Ù¤Æ¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤¬¡¢1¤Ä¤Î¥ë¡¼¥È¡¦¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Ë¸ºß¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¤¬¡¢¥½¡¼¥¹¡¦¥Ñ¥¹¤Ç»ØÄꤵ¤ì¤¿¾ì½ê¤Î¤É¤³¤«¤Ç¸«¤Ä¤«¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .sp
+@@ -3637,9 +4300,7 @@
+ .PP
+ ¤Þ¤¿¡¢1¤Ä°Ê¾å¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤òÅϤ·¤Æ¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£\fBjavadoc\fR¤Ï¡¢¼¡¤Î2¤Ä¤ÎÊýË¡¤Î¤¤¤º¤ì¤«¤Ç¼Â¹Ô¤Ç¤­¤Þ¤¹¡£1¤Ä¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤òÊѹ¹¤¹¤ëÊýË¡(\fBcd\fR¤ò»ÈÍÑ)¡¢¤â¤¦1¤Ä¤Ï¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Ø¤Î¥Ñ¥¹¤ò´°Á´¤Ë»ØÄꤹ¤ëÊýË¡¤Ç¤¹¡£ÁêÂХѥ¹¤Ï¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤òµ¯ÅÀ¤È¤·¤Þ¤¹¡£¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤òÅϤ¹¤È¤­¤Ï¡¢\fB\-sourcepath\fR¥ª¥×¥·¥ç¥ó¤Ï̵»ë¤µ¤ì¤Þ¤¹¡£¥¢¥¹¥¿¥ê¥¹¥¯(*)¤Î¤è¤¦¤Ê¥³¥Þ¥ó¥É¹Ô¥ï¥¤¥ë¥É¥«¡¼¥É¤ò»ÈÍѤ¹¤ë¤È¡¢¥¯¥é¥¹¤Î¥°¥ë¡¼¥×¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£
+ .PP
+-\fBÎã 1\fR
+-.br
+-¥½¡¼¥¹¡¦¥Ç¥£¥ì¥¯¥È¥ê¤ËÊѹ¹
++\fBÎã 1 \fR¥½¡¼¥¹¡¦¥Ç¥£¥ì¥¯¥È¥ê¤ËÊѹ¹
+ .RS 4
+ ¥½¡¼¥¹¤òÊÝ»ý¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤ËÊѹ¹¤·¤Þ¤¹¡£¼¡¤Ë¡¢¥É¥­¥å¥á¥ó¥È²½¤¹¤ë1¤Ä°Ê¾å¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Î̾Á°¤ò»ØÄꤷ¤Æ\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Þ¤¹¡£
+ .sp
+@@ -3658,9 +4319,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-¥Ñ¥Ã¥±¡¼¥¸¤Î¥ë¡¼¥È¡¦¥Ç¥£¥ì¥¯¥È¥ê¤ËÊѹ¹
++\fBÎã 2 \fR¥Ñ¥Ã¥±¡¼¥¸¤Î¥ë¡¼¥È¡¦¥Ç¥£¥ì¥¯¥È¥ê¤ËÊѹ¹
+ .RS 4
+ ¤³¤ì¤Ï¡¢Æ±¤¸¥ë¡¼¥È¤«¤é¤ÎÊ̤Υµ¥Ö¥Ñ¥Ã¥±¡¼¥¸¤Î¸Ä¡¹¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¥É¥­¥å¥á¥ó¥È²½¤¹¤ë¤Î¤ËÌòΩ¤Á¤Þ¤¹¡£¥Ñ¥Ã¥±¡¼¥¸¤Î¥ë¡¼¥È¡¦¥Ç¥£¥ì¥¯¥È¥ê¤Ë°Ü¤ê¡¢³Æ¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¡¢¥ë¡¼¥È¤«¤é¤Î¥Ñ¥¹¤È¤È¤â¤Ë»ØÄꤷ¤Þ¤¹¡£
+ .sp
+@@ -3677,9 +4336,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 3\fR
+-.br
+-Ǥ°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î¥Õ¥¡¥¤¥ë¤Î¥É¥­¥å¥á¥ó¥È²½
++\fBÎã 3 \fRǤ°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î¥Õ¥¡¥¤¥ë¤Î¥É¥­¥å¥á¥ó¥È²½
+ .RS 4
+ ¤³¤Î¾ì¹ç¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤¬¤É¤³¤«¤ÏÌäÂê¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¥É¥­¥å¥á¥ó¥È²½¤¹¤ë¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹(¤Þ¤¿¤Ï¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤ÎÁêÂХѥ¹)¤ò»ØÄꤷ¤Æ\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Þ¤¹¡£
+ .sp
+--- ./jdk/src/linux/doc/man/ja/javah.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/javah.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "javah" "1" "2013ǯ11·î21Æü" "JDK 8" "´ðËܥġ¼¥ë"
+@@ -77,7 +78,7 @@
+ .PP
+ \fBjavah\fR¥³¥Þ¥ó¥É¤Ï¡¢¥Í¥¤¥Æ¥£¥Ö¡¦¥á¥½¥Ã¥É¤ò¼ÂÁõ¤¹¤ë¤¿¤á¤ËɬÍפÊC¥Ø¥Ã¥À¡¼¤È¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤òÀ¸À®¤·¤Þ¤¹¡£ºîÀ®¤µ¤ì¤¿¥Ø¥Ã¥À¡¼¤È¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Ï¡¢¥Í¥¤¥Æ¥£¥Ö¡¦¥½¡¼¥¹¡¦¥³¡¼¥É¤«¤é¥ª¥Ö¥¸¥§¥¯¥È¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤ò»²¾È¤¹¤ë¤¿¤á¤ËC¥×¥í¥°¥é¥à¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Þ¤¹¡£\fB\&.h\fR¥Õ¥¡¥¤¥ë¤Ï¡¢Âбþ¤¹¤ë¥¯¥é¥¹¤È°ìÃפ¹¤ëÇÛÃÖ¤ò»ý¤Ä\fBstruct\fRÄêµÁ¤ò´Þ¤ß¤Þ¤¹¡£\fBstruct\fR¤Î¥Õ¥£¡¼¥ë¥É¤Ï¡¢¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤ËÂбþ¤·¤Þ¤¹¡£
+ .PP
+-¥Ø¥Ã¥À¡¼¡¦¥Õ¥¡¥¤¥ë¤È¤½¤ÎÃæ¤ÇÀë¸À¤µ¤ì¤ë¹½Â¤ÂΤÎ̾Á°¤Ï¥¯¥é¥¹¤Î̾Á°¤«¤éÇÉÀ¸¤·¤Þ¤¹¡£\fBjavah\fR¥³¥Þ¥ó¥É¤ËÅϤµ¤ì¤ë¥¯¥é¥¹¤¬¥Ñ¥Ã¥±¡¼¥¸¤ÎÃæ¤Ë¤¢¤ë¾ì¹ç¡¢¥Ñ¥Ã¥±¡¼¥¸Ì¾¤Ï¥Ø¥Ã¥À¡¼¡¦¥Õ¥¡¥¤¥ë̾¤È¹½Â¤ÂÎ̾¤ÎξÊý¤ÎÀèƬ¤ËÉղ䵤ì¤Þ¤¹¡£²¼Àþ(_)¤¬Ì¾Á°¤Î¶èÀÚ¤êʸ»ú¤È¤·¤Æ»ÈÍѤµ¤ì¤Þ¤¹¡£
++¥Ø¥Ã¥À¡¼¡¦¥Õ¥¡¥¤¥ë¤È¤½¤ÎÃæ¤ÇÀë¸À¤µ¤ì¤ë¹½Â¤ÂΤÎ̾Á°¤Ï¥¯¥é¥¹¤Î̾Á°¤«¤éÇÉÀ¸¤·¤Þ¤¹¡£\fBjavah\fR¥³¥Þ¥ó¥É¤ËÅϤµ¤ì¤ë¥¯¥é¥¹¤¬¥Ñ¥Ã¥±¡¼¥¸¤ÎÃæ¤Ë¤¢¤ë¾ì¹ç¡¢¥Ñ¥Ã¥±¡¼¥¸Ì¾¤Ï¥Ø¥Ã¥À¡¼¡¦¥Õ¥¡¥¤¥ë̾¤È¹½Â¤ÂÎ̾¤ÎξÊý¤ÎÀèƬ¤ËÉղ䵤ì¤Þ¤¹¡£¥¢¥ó¥À¡¼¥¹¥³¥¢(_)¤¬Ì¾Á°¤Î¶èÀÚ¤êʸ»ú¤È¤·¤Æ»ÈÍѤµ¤ì¤Þ¤¹¡£
+ .PP
+ ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï\fBjavah\fR¥³¥Þ¥ó¥É¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤Ë¥ê¥¹¥È¤µ¤ì¤ë³Æ¥¯¥é¥¹¤Î¥Ø¥Ã¥À¡¼¡¦¥Õ¥¡¥¤¥ë¤òºîÀ®¤·¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¥Õ¥¡¥¤¥ë¤òÃÖ¤­¤Þ¤¹¡£¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤òºîÀ®¤¹¤ë¤Ë¤Ï¡¢\fB\-stubs\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£1¤Ä¤Î¥Õ¥¡¥¤¥ë¤ÎÃæ¤Ë¡¢¥ê¥¹¥È¤µ¤ì¤¿¤¹¤Ù¤Æ¤Î¥¯¥é¥¹¤Î·ë²Ì¤òÏ¢·ë¤¹¤ë¤Ë¤Ï¡¢\fB\-o\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£
+ .PP
+--- ./jdk/src/linux/doc/man/ja/javap.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/javap.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "javap" "1" "2014ǯ8·î8Æü" "JDK 8" "´ðËܥġ¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/javaws.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/javaws.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java Web Start¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "javaws" "1" "2013ǯ11·î21Æü" "JDK 8" "Java Web Start¥Ä¡¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/jcmd.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jcmd.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jcmd" "1" "2013ǯ11·î21Æü" "JDK 8" "¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/jconsole.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jconsole.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¢¥×¥í¥Õ¥¡¥¤¥ê¥ó¥°¡¢¥â¥Ë¥¿¥ê¥ó¥°¤ª¤è¤Ó´ÉÍý¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jconsole" "1" "2013ǯ11·î21Æü" "JDK 8" "Java¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¢¥×¥í¥Õ¥¡¥¤¥ê¥ó¥°¡¢¥â¥Ë¥¿¥ê¥ó"
+@@ -81,7 +82,7 @@
+ .RE
+ .SH "ÀâÌÀ"
+ .PP
+-\fBjconsole\fR¥³¥Þ¥ó¥É¤Ï¡¢¥í¡¼¥«¥ë¡¦¥Þ¥·¥ó¤Þ¤¿¤Ï¥ê¥â¡¼¥È¡¦¥Þ¥·¥ó¾å¤ÎJava¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤È²¾ÁÛ¥Þ¥·¥ó¤ò¥â¥Ë¥¿¡¼¤ª¤è¤Ó´ÉÍý¤¹¤ë¥°¥é¥Õ¥£¥«¥ë¡¦¥³¥ó¥½¡¼¥ë¡¦¥Ä¡¼¥ë¤òµ¯Æ°¤·¤Þ¤¹¡£
++\fBjconsole\fR¥³¥Þ¥ó¥É¤Ï¡¢¥í¡¼¥«¥ë¡¦¥Þ¥·¥ó¤Þ¤¿¤Ï¥ê¥â¡¼¥È¡¦¥Þ¥·¥ó¾å¤ÎJava¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤È²¾ÁÛ¥Þ¥·¥ó¤Î¥â¥Ë¥¿¡¼¤È´ÉÍý¤ò¹Ô¤¦¥°¥é¥Õ¥£¥«¥ë¡¦¥³¥ó¥½¡¼¥ë¡¦¥Ä¡¼¥ë¤òµ¯Æ°¤·¤Þ¤¹¡£
+ .PP
+ Windows¾å¤Ç¤Ï¡¢\fBjconsole\fR¥³¥Þ¥ó¥É¤Ï¥³¥ó¥½¡¼¥ë¡¦¥¦¥£¥ó¥É¥¦¤È´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤Þ¤»¤ó¡£¤¿¤À¤·¡¢\fBjconsole\fR¥³¥Þ¥ó¥É¤¬¼ºÇÔ¤¹¤ë¤È¡¢¥¨¥é¡¼¾ðÊó¤ò¼¨¤¹¥À¥¤¥¢¥í¥°¡¦¥Ü¥Ã¥¯¥¹¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£
+ .SH "¥ª¥×¥·¥ç¥ó"
+@@ -93,7 +94,7 @@
+ .PP
+ \-notile
+ .RS 4
+-ºÇ½é¤Ï¥¦¥£¥ó¥É¥¦¤ò¥¿¥¤¥ëɽ¼¨¤·¤Þ¤»¤ó(Ê£¿ôÀܳ¤Î¾ì¹ç)¡£
++ºÇ½é¤Ë¥¦¥£¥ó¥É¥¦¤ò¥¿¥¤¥ëɽ¼¨¤·¤Þ¤»¤ó(Ê£¿ôÀܳ¤Î¾ì¹ç)¡£
+ .RE
+ .PP
+ \-pluginpath \fIplugins\fR
+--- ./jdk/src/linux/doc/man/ja/jdb.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jdb.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jdb" "1" "2013ǯ11·î21Æü" "JDK 8" "´ðËܥġ¼¥ë"
+@@ -318,7 +319,7 @@
+ .RS 4
+ JVM¤Ë\fBoption\fR¤òÅϤ·¤Þ¤¹¡£option¤Ë¤Ï¡¢Java¥¢¥×¥ê¥±¡¼¥·¥ç¥óµ¯Æ°¥Ä¡¼¥ë¤Î¥ê¥Õ¥¡¥ì¥ó¥¹¡¦¥Ú¡¼¥¸¤Ëµ­ºÜ¤µ¤ì¤Æ¤¤¤ë¥ª¥×¥·¥ç¥ó¤ò1¤Ä»ØÄꤷ¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢\fB\-J\-Xms48m\fR¤È»ØÄꤹ¤ë¤È¡¢¥¹¥¿¡¼¥È¥¢¥Ã¥×¡¦¥á¥â¥ê¡¼¤Ï48MB¤ËÀßÄꤵ¤ì¤Þ¤¹¡£java(1)¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .RE
+-.SH "¥Ç¥Ð¥Ã¥°ÂÐ¾Ý¤Î¥×¥í¥»¥¹¤ËžÁ÷¤µ¤ì¤ë¥ª¥×¥·¥ç¥ó"
++.SH "¥Ç¥Ð¥Ã¥¬¡¦¥×¥í¥»¥¹¤ËžÁ÷¤µ¤ì¤ë¥ª¥×¥·¥ç¥ó"
+ .PP
+ \-v \-verbose[:\fIclass\fR|gc|jni]
+ .RS 4
+--- ./jdk/src/linux/doc/man/ja/jdeps.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jdeps.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jdeps" "1" "2013ǯ11·î21Æü" "JDK 8" "´ðËܥġ¼¥ë"
+@@ -113,7 +114,7 @@
+ .RS 4
+ ¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤Î¸¡º÷¾ì½ê¤ò»ØÄꤷ¤Þ¤¹¡£
+ .sp
+-Setting the Class Path ¤â»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++¥¯¥é¥¹¡¦¥Ñ¥¹¤ÎÀßÄê ¤â»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .RE
+ .PP
+ \-p <\fIpkg name\fR>
+--- ./jdk/src/linux/doc/man/ja/jhat.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jhat.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jhat" "1" "2013ǯ11·î21Æü" "JDK 8" "¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/jinfo.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jinfo.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jinfo" "1" "2013ǯ11·î21Æü" "JDK 8" "¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë"
+@@ -115,7 +116,7 @@
+ .RE
+ .SH "ÀâÌÀ"
+ .PP
+-\fBjinfo\fR¥³¥Þ¥ó¥É¤Ï¡¢»ØÄꤵ¤ì¤¿Java¥×¥í¥»¥¹¤ä¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï¥ê¥â¡¼¥È¡¦¥Ç¥Ð¥Ã¥°¡¦¥µ¡¼¥Ð¡¼¤ÎJava¹½À®¾ðÊó¤ò½ÐÎϤ·¤Þ¤¹¡£¹½À®¾ðÊó¤Ë¤Ï¡¢Java¥·¥¹¥Æ¥à¡¦¥×¥í¥Ñ¥Æ¥£¤ÈJava Virtual Machine (JVM)¤Î¥³¥Þ¥ó¥É¹Ô¥Õ¥é¥°¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£»ØÄꤵ¤ì¤¿¥×¥í¥»¥¹¤¬64¥Ó¥Ã¥ÈJVM¾å¤Ç¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢\fB\-J\-d64\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£¼¡¤ËÎã¤ò¼¨¤·¤Þ¤¹¡£\fBjinfo\fR
++\fBjinfo\fR¥³¥Þ¥ó¥É¤Ï¡¢»ØÄꤵ¤ì¤¿Java¥×¥í¥»¥¹¤ä¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï¥ê¥â¡¼¥È¡¦¥Ç¥Ð¥Ã¥°¡¦¥µ¡¼¥Ð¡¼¤ÎJava¹½À®¾ðÊó¤ò½ÐÎϤ·¤Þ¤¹¡£¹½À®¾ðÊó¤Ë¤Ï¡¢Java¥·¥¹¥Æ¥à¡¦¥×¥í¥Ñ¥Æ¥£¤ÈJava²¾ÁÛ¥Þ¥·¥ó(JVM)¤Î¥³¥Þ¥ó¥É¹Ô¥Õ¥é¥°¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£»ØÄꤵ¤ì¤¿¥×¥í¥»¥¹¤¬64¥Ó¥Ã¥ÈJVM¾å¤Ç¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢\fB\-J\-d64\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£¼¡¤ËÎã¤ò¼¨¤·¤Þ¤¹¡£\fBjinfo\fR
+ \fB\-J\-d64 \-sysprops pid\fR¡£
+ .PP
+ ¤³¤Î¥æ¡¼¥Æ¥£¥ê¥Æ¥£¤Ï¥µ¥Ý¡¼¥ÈÂоݳ°¤Ç¤¢¤ê¡¢¾­Íè¤ÎJDK¤Î¥ê¥ê¡¼¥¹¤Ç¤ÏÍøÍѤǤ­¤Ê¤¯¤Ê¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£\fBdbgeng\&.dll\fR¤¬Â¸ºß¤·¤Æ¤¤¤Ê¤¤Windows¥·¥¹¥Æ¥à¤Ç¤Ï¡¢Debugging Tools For Windows¤ò¥¤¥ó¥¹¥È¡¼¥ë¤·¤Ê¤¤¤È¤³¤ì¤é¤Î¥Ä¡¼¥ë¤¬Àµ¾ï¤ËÆ°ºî¤·¤Þ¤»¤ó¡£\fBPATH\fR´Ä¶­ÊÑ¿ô¤Ë¤Ï¡¢¥¿¡¼¥²¥Ã¥È¡¦¥×¥í¥»¥¹¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤ëjvm\&.dll¤Î¾ì½ê¡¢¤Þ¤¿¤Ï¥¯¥é¥Ã¥·¥å¡¦¥À¥ó¥×¡¦¥Õ¥¡¥¤¥ë¤¬À¸À®¤µ¤ì¤¿¾ì½ê¤¬´Þ¤Þ¤ì¤ë¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£¤¿¤È¤¨¤Ð¡¢\fBset PATH=%JDK_HOME%\ejre\ebin\eclient;%PATH%\fR¤Ç¤¹¡£
+--- ./jdk/src/linux/doc/man/ja/jjs.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jjs.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: jjs
+ .\" Language: Japanese
+-.\" Date: 2013ǯ11·î21Æü
++.\" Date: 2015ǯ3·î3Æü
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "jjs" "1" "2013ǯ11·î21Æü" "JDK 8" "´ðËܥġ¼¥ë"
++.TH "jjs" "1" "2015ǯ3·î3Æü" "JDK 8" "´ðËܥġ¼¥ë"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -113,7 +114,7 @@
+ .PP
+ \-cp \fIpath\fR
+ .br
+-\-\-classpath \fIpath\fR
++\-classpath \fIpath\fR
+ .RS 4
+ ¥µ¥Ý¡¼¥È¤¹¤ë¥¯¥é¥¹¤Ø¤Î¥Ñ¥¹¤ò»ØÄꤷ¤Þ¤¹¡£Ê£¿ô¤Î¥Ñ¥¹¤òÀßÄꤹ¤ë¤Ë¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤ò·«¤êÊÖ¤¹¤«¡¢¤Þ¤¿¤Ï³Æ¥Ñ¥¹¤ò¥³¥í¥ó(:)¤Ç¶èÀÚ¤ê¤Þ¤¹¡£
+ .RE
+@@ -221,6 +222,11 @@
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤ò·«¤êÊÖ¤·»ÈÍѤ¹¤ë¤È¡¢Ê£¿ô¤Î\fBjava\fR¥³¥Þ¥ó¥É¡¦¥ª¥×¥·¥ç¥ó¤òÅϤ¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
+ .RE
+ .PP
++\-\-language=[es5]
++.RS 4
++ECMAScript¸À¸ì¥Ð¡¼¥¸¥ç¥ó¤ò»ØÄꤷ¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Î¥Ð¡¼¥¸¥ç¥ó¤ÏES5¤Ç¤¹¡£
++.RE
++.PP
+ \-\-lazy\-compilation
+ .RS 4
+ ¥ì¥¤¥¸¡¼¡¦¥³¡¼¥ÉÀ¸À®Àïά(¤Ä¤Þ¤ê¡¢¥¹¥¯¥ê¥×¥ÈÁ´ÂΤ¬°ìÅ٤˥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Ê¤¤)¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï»î¸³Åª¤Ê¤â¤Î¤Ç¤¹¡£
+@@ -240,13 +246,17 @@
+ .\}
+ .nf
+ \fB\-\-log=fields:finest,codegen:info\fR
+-
+ .fi
+ .if n \{\
+ .RE
+ .\}
+ .RE
+ .PP
++\-\-optimistic\-types=[true|false]
++.RS 4
++ºÆ¥³¥ó¥Ñ¥¤¥ë¤ÎºÇŬ²½¤ò²ò½ü¤·¤Æ¥ª¥×¥Æ¥£¥ß¥¹¥Æ¥£¥Ã¥¯¡¦¥¿¥¤¥×²¾Äê¤òÍ­¸ú¤Þ¤¿¤Ï̵¸ú¤Ë¤·¤Þ¤¹¡£¥ª¥×¥Æ¥£¥ß¥¹¥Æ¥£¥Ã¥¯¡¦¥¿¥¤¥×¤ò»ÈÍѤ·¤¿¼Â¹Ô¤Ë¤è¤Ã¤ÆºÇ½ªÅª¤Ê®ÅÙ¤¬¸þ¾å¤·¤Þ¤¹¤¬¡¢¥¦¥©¡¼¥à¥¢¥Ã¥×»þ´Ö¤¬Áý¤¨¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£
++.RE
++.PP
+ \-\-package=\fIname\fR
+ .RS 4
+ À¸À®¤µ¤ì¤¿¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤òÄɲ乤ë¥Ñ¥Ã¥±¡¼¥¸¤ò»ØÄꤷ¤Þ¤¹¡£
+@@ -323,7 +333,7 @@
+ .br
+ \-timezone=\fIzone\fR
+ .RS 4
+-¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô¤ËÂФ·»ØÄꤷ¤¿¥¿¥¤¥à¡¦¥¾¡¼¥ó¤òÀßÄꤷ¤Þ¤¹¡£OS¤ÇÀßÄꤵ¤ì¤¿¥¿¥¤¥à¡¦¥¾¡¼¥ó¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¡¢\fBDate\fR¥ª¥Ö¥¸¥§¥¯¥È¤Ç»ÈÍѤµ¤ì¤Þ¤¹¡£
++¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô¤ËÂФ·»ØÄꤷ¤¿¥¿¥¤¥à¥¾¡¼¥ó¤òÀßÄꤷ¤Þ¤¹¡£OS¤ÇÀßÄꤵ¤ì¤¿¥¿¥¤¥à¥¾¡¼¥ó¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¡¢\fBDate\fR¥ª¥Ö¥¸¥§¥¯¥È¤Ç»ÈÍѤµ¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ \-tcs=\fIparameter\fR
+@@ -366,9 +376,7 @@
+ .RE
+ .SH "Îã"
+ .PP
+-\fBÎã 1\fR
+-.br
+-Nashorn¤ò»ÈÍѤ·¤¿¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô
++\fBÎã 1 \fRNashorn¤ò»ÈÍѤ·¤¿¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô
+ .RS 4
+ .sp
+ .if n \{\
+@@ -383,9 +391,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-ÂÐÏ÷¿¥â¡¼¥É¤Ç¤ÎNashorn¤Î¼Â¹Ô
++\fBÎã 2 \fRÂÐÏ÷¿¥â¡¼¥É¤Ç¤ÎNashorn¤Î¼Â¹Ô
+ .RS 4
+ .sp
+ .if n \{\
+@@ -404,9 +410,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 3\fR
+-.br
+-Nashorn¤Ø¤Î°ú¿ô¤ÎÅϤ·
++\fBÎã 3 \fRNashorn¤Ø¤Î°ú¿ô¤ÎÅϤ·
+ .RS 4
+ .sp
+ .if n \{\
+--- ./jdk/src/linux/doc/man/ja/jmap.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jmap.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jmap" "1" "2013ǯ11·î21Æü" "JDK 8" "¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/jps.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jps.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥â¥Ë¥¿¥ê¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jps" "1" "2013ǯ11·î21Æü" "JDK 8" "¥â¥Ë¥¿¥ê¥ó¥°¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/jrunscript.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jrunscript.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥¹¥¯¥ê¥×¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jrunscript" "1" "2013ǯ11·î21Æü" "JDK 8" "¥¹¥¯¥ê¥×¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë"
+@@ -86,7 +87,7 @@
+ \-cp \fIpath\fR
+ .RS 4
+ \fB\-classpath\fR
+-\fBpath\fR¤ÈƱ¤¸¤Ç¤¹¡£
++\fIpath\fR¤ÈƱ¤¸¤Ç¤¹¡£
+ .RE
+ .PP
+ \-D\fIname\fR=\fIvalue\fR
+@@ -96,7 +97,7 @@
+ .PP
+ \-J\fIflag\fR
+ .RS 4
+-\fBflag\fR¤ò¡¢\fBjrunscript\fR¥³¥Þ¥ó¥É¤¬¼Â¹Ô¤µ¤ì¤Æ¤¤¤ëJava Virtual Machine¤ËľÀÜÅϤ·¤Þ¤¹¡£
++\fBflag\fR¤ò¡¢\fBjrunscript\fR¥³¥Þ¥ó¥É¤¬¼Â¹Ô¤µ¤ì¤Æ¤¤¤ëJava²¾ÁÛ¥Þ¥·¥ó¤ËľÀÜÅϤ·¤Þ¤¹¡£
+ .RE
+ .PP
+ \-I \fIlanguage\fR
+--- ./jdk/src/linux/doc/man/ja/jsadebugd.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jsadebugd.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jsadebugd" "1" "2013ǯ11·î21Æü" "JDK 8" "¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë"
+@@ -95,7 +96,7 @@
+ .RE
+ .SH "ÀâÌÀ"
+ .PP
+-\fBjsadebugd\fR¥³¥Þ¥ó¥É¤Ï¡¢Java¥×¥í¥»¥¹¤Þ¤¿¤Ï¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤ËÀܳ¤·¡¢¥Ç¥Ð¥Ã¥°¡¦¥µ¡¼¥Ð¡¼¤È¤·¤Æµ¡Ç½¤·¤Þ¤¹¡£\fBjstack\fR¡¢\fBjmap\fR¤ª¤è¤Ó\fBjinfo\fR¤Ê¤É¤Î¥ê¥â¡¼¥È¡¦¥¯¥é¥¤¥¢¥ó¥È¤Ï¡¢Java Remote Method Invocation(RMI)¤ò»ÈÍѤ·¤Æ¤¤¤ë¥µ¡¼¥Ð¡¼¤ËÀܳ¤Ç¤­¤Þ¤¹¡£\fBjsadebugd\fR¥³¥Þ¥ó¥É¤òµ¯Æ°¤¹¤ëÁ°¤Ë¡¢\fBrmiregistry\fR¥³¥Þ¥ó¥É¤ÇRMI¥ì¥¸¥¹¥È¥ê¤ò¼¡¤Î¤è¤¦¤Ëµ¯Æ°¤·¤Þ¤¹¡£\fI$JAVA_HOME\fR¤ÏJDK¤Î¥¤¥ó¥¹¥È¡¼¥ë¡¦¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹¡£
++\fBjsadebugd\fR¥³¥Þ¥ó¥É¤Ï¡¢Java¥×¥í¥»¥¹¤Þ¤¿¤Ï¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤ËÀܳ¤·¡¢¥Ç¥Ð¥Ã¥°¡¦¥µ¡¼¥Ð¡¼¤È¤·¤Æµ¡Ç½¤·¤Þ¤¹¡£\fBjstack\fR¡¢\fBjmap\fR¤ª¤è¤Ó\fBjinfo\fR¤Ê¤É¤Î¥ê¥â¡¼¥È¡¦¥¯¥é¥¤¥¢¥ó¥È¤Ï¡¢Java Remote Method Invocation (RMI)¤ò»ÈÍѤ·¤Æ¤¤¤ë¥µ¡¼¥Ð¡¼¤ËÀܳ¤Ç¤­¤Þ¤¹¡£\fBjsadebugd\fR¥³¥Þ¥ó¥É¤òµ¯Æ°¤¹¤ëÁ°¤Ë¡¢\fBrmiregistry\fR¥³¥Þ¥ó¥É¤ÇRMI¥ì¥¸¥¹¥È¥ê¤ò¼¡¤Î¤è¤¦¤Ëµ¯Æ°¤·¤Þ¤¹¡£\fI$JAVA_HOME\fR¤ÏJDK¤Î¥¤¥ó¥¹¥È¡¼¥ë¡¦¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+--- ./jdk/src/linux/doc/man/ja/jstack.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jstack.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jstack" "1" "2013ǯ11·î21Æü" "JDK 8" "¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë"
+@@ -115,7 +116,7 @@
+ .RE
+ .SH "ÀâÌÀ"
+ .PP
+-\fBjstack\fR¥³¥Þ¥ó¥É¤Ï¡¢»ØÄꤵ¤ì¤¿Java¥×¥í¥»¥¹¡¢¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï¥ê¥â¡¼¥È¡¦¥Ç¥Ð¥Ã¥°¡¦¥µ¡¼¥Ð¡¼¤ËÂФ¹¤ëJava¥¹¥ì¥Ã¥É¤ÎJava¥¹¥¿¥Ã¥¯¡¦¥È¥ì¡¼¥¹¤ò½ÐÎϤ·¤Þ¤¹¡£Java¥Õ¥ì¡¼¥à¤´¤È¤Ë¡¢¥Õ¥ë¥¯¥é¥¹Ì¾¡¢¥á¥½¥Ã¥É̾¡¢¥Ð¥¤¥È¥³¡¼¥É¡¦¥¤¥ó¥Ç¥Ã¥¯¥¹(bci)¡¢¤ª¤è¤Ó¹ÔÈÖ¹æ(ÍøÍѲÄǽ¤Ê¾ì¹ç)¤¬½ÐÎϤµ¤ì¤Þ¤¹¡£\fB\-m\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤È¡¢\fBjstack\fR¥³¥Þ¥ó¥É¤Ï¡¢¤¹¤Ù¤Æ¤Î¥¹¥ì¥Ã¥É¤ÎJava¥Õ¥ì¡¼¥à¤È¥Í¥¤¥Æ¥£¥Ö¡¦¥Õ¥ì¡¼¥à¤ÎξÊý¤ò¡¢¥×¥í¥°¥é¥à¡¦¥«¥¦¥ó¥¿(PC)¤È¤È¤â¤Ë½ÐÎϤ·¤Þ¤¹¡£¥Í¥¤¥Æ¥£¥Ö¡¦¥Õ¥ì¡¼¥à¤´¤È¤Ë¡¢PC¤ËºÇ¤â¶á¤¤¥Í¥¤¥Æ¥£¥Ö¡¦¥·¥ó¥Ü¥ë(ÍøÍѲÄǽ¤Ê¾ì¹ç)¤¬½ÐÎϤµ¤ì¤Þ¤¹¡£C++ʬ²ò̾¤Ïʬ²ò²ò½ü¤µ¤ì¤Þ¤»¤ó¡£C++̾¤òʬ²ò²ò½ü¤¹¤ë¤Ë¤Ï¡¢¤³¤Î¥³¥Þ¥ó¥É¤Î½ÐÎϤò\fBc++filt\fR¤Ë¥Ñ¥¤¥×¤·¤Þ¤¹¡£»ØÄꤵ¤ì¤¿¥×¥í¥»¥¹¤¬64¥Ó¥Ã¥ÈJava Virtual Machine¾å¤Ç¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢\fB\-J\-d64\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹(Îã:
++\fBjstack\fR¥³¥Þ¥ó¥É¤Ï¡¢»ØÄꤵ¤ì¤¿Java¥×¥í¥»¥¹¡¢¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï¥ê¥â¡¼¥È¡¦¥Ç¥Ð¥Ã¥°¡¦¥µ¡¼¥Ð¡¼¤ËÂФ¹¤ëJava¥¹¥ì¥Ã¥É¤ÎJava¥¹¥¿¥Ã¥¯¡¦¥È¥ì¡¼¥¹¤ò½ÐÎϤ·¤Þ¤¹¡£Java¥Õ¥ì¡¼¥à¤´¤È¤Ë¡¢¥Õ¥ë¥¯¥é¥¹Ì¾¡¢¥á¥½¥Ã¥É̾¡¢¥Ð¥¤¥È¥³¡¼¥É¡¦¥¤¥ó¥Ç¥Ã¥¯¥¹(bci)¡¢¤ª¤è¤Ó¹ÔÈÖ¹æ(ÍøÍѲÄǽ¤Ê¾ì¹ç)¤¬½ÐÎϤµ¤ì¤Þ¤¹¡£\fB\-m\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤È¡¢\fBjstack\fR¥³¥Þ¥ó¥É¤Ï¡¢¤¹¤Ù¤Æ¤Î¥¹¥ì¥Ã¥É¤ÎJava¥Õ¥ì¡¼¥à¤È¥Í¥¤¥Æ¥£¥Ö¡¦¥Õ¥ì¡¼¥à¤ÎξÊý¤ò¡¢¥×¥í¥°¥é¥à¡¦¥«¥¦¥ó¥¿(PC)¤È¤È¤â¤Ë½ÐÎϤ·¤Þ¤¹¡£¥Í¥¤¥Æ¥£¥Ö¡¦¥Õ¥ì¡¼¥à¤´¤È¤Ë¡¢PC¤ËºÇ¤â¶á¤¤¥Í¥¤¥Æ¥£¥Ö¡¦¥·¥ó¥Ü¥ë(ÍøÍѲÄǽ¤Ê¾ì¹ç)¤¬½ÐÎϤµ¤ì¤Þ¤¹¡£C++ʬ²ò̾¤Ïʬ²ò²ò½ü¤µ¤ì¤Þ¤»¤ó¡£C++̾¤òʬ²ò²ò½ü¤¹¤ë¤Ë¤Ï¡¢¤³¤Î¥³¥Þ¥ó¥É¤Î½ÐÎϤò\fBc++filt\fR¤Ë¥Ñ¥¤¥×¤·¤Þ¤¹¡£»ØÄꤵ¤ì¤¿¥×¥í¥»¥¹¤¬64¥Ó¥Ã¥ÈJava²¾ÁÛ¥Þ¥·¥ó¾å¤Ç¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢\fB\-J\-d64\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹(Îã:
+ \fBjstack \-J\-d64 \-m pid\fR)¡£
+ .PP
+ \fBÃí°Õ\fR
+--- ./jdk/src/linux/doc/man/ja/jstat.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jstat.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: jstat
+ .\" Language: Japanese
+-.\" Date: 2011ǯ5·î10Æü
++.\" Date: 2015ǯ3·î3Æü
+ .\" SectDesc: ¥â¥Ë¥¿¥ê¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "jstat" "1" "2011ǯ5·î10Æü" "JDK 8" "¥â¥Ë¥¿¥ê¥ó¥°¡¦¥Ä¡¼¥ë"
++.TH "jstat" "1" "2015ǯ3·î3Æü" "JDK 8" "¥â¥Ë¥¿¥ê¥ó¥°¡¦¥Ä¡¼¥ë"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -276,6 +277,10 @@
+ .sp
+ \fBMU\fR: ¥á¥¿¥¹¥Ú¡¼¥¹¤Î»ÈÍÑΨ(KB)¡£
+ .sp
++\fBCCSC\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤ÎÍÆÎÌ(KB)¡£
++.sp
++\fBCCSU\fR: »ÈÍѤµ¤ì¤Æ¤¤¤ë°µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè(KB)¡£
++.sp
+ \fBYGC\fR: ¼ã¤¤À¤Âå¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¡¦¥¤¥Ù¥ó¥È¤Î¿ô¡£
+ .sp
+ \fBYGCT\fR: ¼ã¤¤À¤Âå¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó»þ´Ö¡£
+@@ -317,6 +322,12 @@
+ .sp
+ \fBMC\fR: ¥á¥¿¥¹¥Ú¡¼¥¹¤ÎÍÆÎÌ(KB)¡£
+ .sp
++\fBCCSMN\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤ÎºÇ¾®ÍÆÎÌ(KB)¡£
++.sp
++\fBCCSMX\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤ÎºÇÂçÍÆÎÌ(KB)¡£
++.sp
++\fBCCSC\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤ÎÍÆÎÌ(KB)¡£
++.sp
+ \fBYGC\fR: ¼ã¤¤À¤Âå¤ÎGC¥¤¥Ù¥ó¥È¿ô¡£
+ .sp
+ \fBFGC\fR: ¥Õ¥ëGC¥¤¥Ù¥ó¥È¿ô¡£
+@@ -326,11 +337,9 @@
+ .RS 4
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢\fB\-gcutil\fR¥ª¥×¥·¥ç¥ó¤ÈƱ¤¸¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥óÅý·×¥Ç¡¼¥¿¤Î¥µ¥Þ¥ê¡¼¤òɽ¼¨¤·¤Þ¤¹¤¬¡¢ºÇ¸å¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¡¦¥¤¥Ù¥ó¥È¤È(ŬÍѲÄǽ¤Ê¾ì¹ç¤Ï)¸½ºß¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¡¦¥¤¥Ù¥ó¥È¤Î¸¶°ø¤¬´Þ¤Þ¤ì¤Þ¤¹¡£\fB\-gcutil\fR¤Ç°ìÍ÷ɽ¼¨¤µ¤ì¤ëÎó¤Î¤Û¤«¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ç¤Ï¼¡¤ÎÎó¤¬Äɲ䵤ì¤Þ¤¹¡£
+ .sp
+-¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¡¦¥¤¥Ù¥ó¥È¤ò´Þ¤à¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥óÅý·×¥Ç¡¼¥¿¡£
++\fBLGCC\fR: ºÇ¸å¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¤Î¸¶°ø
+ .sp
+-\fBLGCC\fR: ºÇ¸å¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¤Î¸¶°ø¡£
+-.sp
+-\fBGCC\fR: ¸½ºß¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¤Î¸¶°ø¡£
++\fBGCC\fR: ¸½ºß¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¤Î¸¶°ø
+ .RE
+ .PP
+ \-gcnew \fIoption\fR
+@@ -364,7 +373,7 @@
+ .RS 4
+ NewÀ¤ÂåÎΰ襵¥¤¥º¤ÎÅý·×¥Ç¡¼¥¿¡£
+ .sp
+-NGCMN: NewÀ¤Âå¤ÎºÇ¾®ÍÆÎÌ(KB)¡£
++\fBNGCMN\fR: NewÀ¤Âå¤ÎºÇ¾®ÍÆÎÌ(KB)¡£
+ .sp
+ \fBNGCMX\fR: NewÀ¤Âå¤ÎºÇÂçÍÆÎÌ(KB)¡£
+ .sp
+@@ -395,6 +404,10 @@
+ .sp
+ \fBMU\fR: ¥á¥¿¥¹¥Ú¡¼¥¹¤Î»ÈÍÑΨ(KB)¡£
+ .sp
++\fBCCSC\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤ÎÍÆÎÌ(KB)¡£
++.sp
++\fBCCSU\fR: »ÈÍѤµ¤ì¤Æ¤¤¤ë°µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè(KB)¡£
++.sp
+ \fBOC\fR: OldÎΰè¤Î¸½ºß¤ÎÍÆÎÌ(KB)¡£
+ .sp
+ \fBOU\fR: OldÎΰè¤Î»ÈÍÑΨ(KB)¡£
+@@ -439,6 +452,10 @@
+ .sp
+ \fBMC\fR: ¥á¥¿¥¹¥Ú¡¼¥¹¤ÎÍÆÎÌ(KB)¡£
+ .sp
++\fBCCSMN\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤ÎºÇ¾®ÍÆÎÌ(KB)¡£
++.sp
++\fBCCSMX\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤ÎºÇÂçÍÆÎÌ(KB)¡£
++.sp
+ \fBYGC\fR: ¼ã¤¤À¤Âå¤ÎGC¥¤¥Ù¥ó¥È¿ô¡£
+ .sp
+ \fBFGC\fR: ¥Õ¥ëGC¥¤¥Ù¥ó¥È¿ô¡£
+@@ -462,6 +479,8 @@
+ .sp
+ \fBM\fR: ¥á¥¿¥¹¥Ú¡¼¥¹¤Î»ÈÍÑΨ(Îΰè¤Î¸½ºß¤ÎÍÆÎ̤ËÂФ¹¤ë¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸)¡£
+ .sp
++\fBCCS\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤Î»ÈÍÑΨ(¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸)¡£
++.sp
+ \fBYGC\fR: ¼ã¤¤À¤Âå¤ÎGC¥¤¥Ù¥ó¥È¿ô¡£
+ .sp
+ \fBYGCT\fR: ¼ã¤¤À¤Âå¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó»þ´Ö¡£
+@@ -493,29 +512,28 @@
+ .PP
+ ¤³¤ÎÎã¤Ç¤Ï¡¢lvmid 21891¤ËÀܳ¤·¤Æ¡¢250¥ß¥êÉôֳ֤Ç7¤Ä¤Î¥µ¥ó¥×¥ë¤ò¼èÆÀ¤·¡¢\-\fBgcutil\fR¥ª¥×¥·¥ç¥ó¤Ç¤Î»ØÄê¤Ë½¾¤Ã¤Æ½ÐÎϤòɽ¼¨¤·¤Þ¤¹¡£
+ .PP
+-¤³¤ÎÎã¤Î½ÐÎϤϡ¢¼ã¤¤À¤Âå¤Î¥³¥ì¥¯¥·¥ç¥ó¤¬3ÈÖÌܤÈ4ÈÖÌܤΥµ¥ó¥×¥ë´Ö¤Ç¹Ô¤ï¤ì¤¿¤³¤È¤ò¼¨¤·¤Æ¤¤¤Þ¤¹¡£¥³¥ì¥¯¥·¥ç¥ó¤Ë¤Ï0\&.001É䫤«¤Ã¤Æ¤ª¤ê¡¢¥ª¥Ö¥¸¥§¥¯¥È¤¬EdenÎΰè(E)¤«¤éOldÎΰè(O)¤Ë¾º³Ê¤·¤¿¤¿¤á¡¢OldÎΰè¤Î»ÈÍÑΨ¤Ï9\&.49%¤«¤é9\&.51%¤ËÁý²Ã¤·¤Æ¤¤¤Þ¤¹¡£SurvivorÎΰè¤Ï¡¢¥³¥ì¥¯¥·¥ç¥óÁ°¤Ï12\&.44%¤¬»ÈÍѤµ¤ì¤Æ¤¤¤Þ¤·¤¿¤¬¡¢¥³¥ì¥¯¥·¥ç¥ó¸å¤Î»ÈÍѤÏ7\&.74%¤Î¤ß¤Ç¤¹¡£
++¤³¤ÎÎã¤Î½ÐÎϤϡ¢¼ã¤¤À¤Âå¤Î¥³¥ì¥¯¥·¥ç¥ó¤¬3ÈÖÌܤÈ4ÈÖÌܤΥµ¥ó¥×¥ë´Ö¤Ç¹Ô¤ï¤ì¤¿¤³¤È¤ò¼¨¤·¤Æ¤¤¤Þ¤¹¡£¥³¥ì¥¯¥·¥ç¥ó¤Ë¤Ï0\&.078É䫤«¤Ã¤Æ¤ª¤ê¡¢¥ª¥Ö¥¸¥§¥¯¥È¤¬EdenÎΰè(E)¤«¤éOldÎΰè(O)¤Ë¾º³Ê¤·¤¿¤¿¤á¡¢OldÎΰè¤Î»ÈÍÑΨ¤Ï66\&.80%¤«¤é68\&.19%¤ËÁý²Ã¤·¤Æ¤¤¤Þ¤¹¡£SurvivorÎΰè¤Ï¡¢¥³¥ì¥¯¥·¥ç¥óÁ°¤Ï97\&.02%¤¬»ÈÍѤµ¤ì¤Æ¤¤¤Þ¤·¤¿¤¬¡¢¥³¥ì¥¯¥·¥ç¥ó¸å¤Î»ÈÍѤÏ91\&.03%¤Ç¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+ .\}
+ .nf
+ \fBjstat \-gcutil 21891 250 7\fR
+-\fB S0 S1 E O M YGC YGCT FGC FGCT GCT\fR
+-\fB0\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fR
+-\fB0\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fR
+-\fB0\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fR
+-\fB0\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fR
+-\fB0\&.00 99\&.74 13\&.80 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fR
+-\fB0\&.00 99\&.74 13\&.80 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fR
+-\fB0\&.00 99\&.74 13\&.80 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fR
+-
++\fB S0 S1 E O M CCS YGC YGCT FGC FGCT GCT \fR
++\fB 0\&.00 97\&.02 70\&.31 66\&.80 95\&.52 89\&.14 7 0\&.300 0 0\&.000 0\&.300\fR
++\fB 0\&.00 97\&.02 86\&.23 66\&.80 95\&.52 89\&.14 7 0\&.300 0 0\&.000 0\&.300\fR
++\fB 0\&.00 97\&.02 96\&.53 66\&.80 95\&.52 89\&.14 7 0\&.300 0 0\&.000 0\&.300\fR
++\fB 91\&.03 0\&.00 1\&.98 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++\fB 91\&.03 0\&.00 15\&.82 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++\fB 91\&.03 0\&.00 17\&.80 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++\fB 91\&.03 0\&.00 17\&.80 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
+ .fi
+ .if n \{\
+ .RE
+ .\}
+ .SS "Îó¥Ø¥Ã¥À¡¼Ê¸»úÎó¤Î·«ÊÖ¤·"
+ .PP
+-¤³¤ÎÎã¤Ç¤Ï¡¢lvmid 21891¤ËÀܳ¤·¤Æ¡¢250¥ß¥êÉôֳ֤ǥµ¥ó¥×¥ë¤ò¼èÆÀ¤·¡¢\fB\-gcutil\fR¥ª¥×¥·¥ç¥ó¤Ç¤Î»ØÄê¤Ë½¾¤Ã¤Æ½ÐÎϤòɽ¼¨¤·¤Þ¤¹¡£¤µ¤é¤Ë¡¢\fB\-h3\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¡¢¥Ç¡¼¥¿¤¬3¹Ôɽ¼¨¤µ¤ì¤ë¤´¤È¤ËÎó¥Ø¥Ã¥À¡¼¤ò½ÐÎϤ·¤Þ¤¹¡£
++¤³¤ÎÎã¤Ç¤Ï¡¢lvmid 21891¤ËÀܳ¤·¤Æ¡¢250¥ß¥êÉôֳ֤ǥµ¥ó¥×¥ë¤ò¼èÆÀ¤·¡¢\fB\-gcnew\fR¥ª¥×¥·¥ç¥ó¤Ç¤Î»ØÄê¤Ë½¾¤Ã¤Æ½ÐÎϤòɽ¼¨¤·¤Þ¤¹¡£¤µ¤é¤Ë¡¢\fB\-h3\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¡¢¥Ç¡¼¥¿¤¬3¹Ôɽ¼¨¤µ¤ì¤ë¤´¤È¤ËÎó¥Ø¥Ã¥À¡¼¤ò½ÐÎϤ·¤Þ¤¹¡£
+ .PP
+ ¤³¤ÎÎã¤Ç¤Ï¡¢¥Ø¥Ã¥À¡¼Ê¸»úÎó¤Î·«ÊÖ¤·¤¬É½¼¨¤µ¤ì¤Æ¤¤¤ë¤Û¤«¡¢2ÈÖÌܤÈ3ÈÖÌܤΥµ¥ó¥×¥ë´Ö¤ÇYoung GC¤¬¹Ô¤ï¤ì¤¿¤³¤È¤¬¤ï¤«¤ê¤Þ¤¹¡£¤³¤Î·Ñ³»þ´Ö¤Ï0\&.001ÉäǤ·¤¿¡£¤³¤Î¥³¥ì¥¯¥·¥ç¥ó¤Ç¤Ï¡¢SurvivorÎΰè0¤Î»ÈÍÑΨ(S0U)¤¬Å¬ÀÚ¤ÊSurvivor¥µ¥¤¥º(DSS)¤òĶ²á¤¹¤ë¤³¤È¤Ë¤Ê¤ë¥¢¥¯¥Æ¥£¥Ö¡¦¥Ç¡¼¥¿¤¬¸¡½Ð¤µ¤ì¤Þ¤·¤¿¡£¤³¤Î·ë²Ì¡¢¥ª¥Ö¥¸¥§¥¯¥È¤Ï¡¢OldÀ¤Âå(¤³¤Î½ÐÎϤˤÏÈóɽ¼¨)¤Ø¾º³Ê¤µ¤ì¡¢ÅÂƲÆþ¤ê¤·¤­¤¤ÃÍ(TT)¤¬¡¢31¤«¤é2¤Ø¹ß³Ê¤µ¤ì¤Þ¤·¤¿¡£
+ .PP
+@@ -545,7 +563,7 @@
+ .PP
+ ¤³¤ÎÎã¤Ç¤Ï¡¢lvmid21891¤ØÀܳ¤·¡¢250¥ß¥êÉôֳ֤Ç3¤Ä¤Î¥µ¥ó¥×¥ë¤ò¼èÆÀ¤·¤Æ¤¤¤Þ¤¹¡£\fB\-t\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¡¢ºÇ½é¤ÎÎó¤Ë¥µ¥ó¥×¥ë¤´¤È¤Î¥¿¥¤¥à¥¹¥¿¥ó¥×¤òɽ¼¨¤·¤Æ¤¤¤Þ¤¹¡£
+ .PP
+-TimestampÎó¤Ë¤Ï¡¢¥¿¡¼¥²¥Ã¥ÈJVM¤Îµ¯Æ°»þ¤«¤é¤Î·Ð²á»þ´Ö¤¬¡¢ÉÃñ°Ì¤Ç¥ì¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤µ¤é¤Ë¡¢\fB\-gcoldcapacity\fR½ÐÎϤǤϡ¢³äÅö¥ê¥¯¥¨¥¹¥È¤Þ¤¿¤Ï¾º³Ê¥ê¥¯¥¨¥¹¥È¤¢¤ë¤¤¤Ï¤½¤ÎξÊý¤òËþ¤¿¤¹¤¿¤á¤Ë¥Ò¡¼¥×¤¬³ÈÄ¥¤¹¤ë¤¿¤Ó¤Ë¡¢OldÀ¤Âå¤ÎÍÆÎÌ(OGC)¤ÈOldÎΰè¤ÎÍÆÎÌ(OC)¤È¤¬Áý²Ã¤·¤Æ¤¤¤ë¤³¤È¤¬¤ï¤«¤ê¤Þ¤¹¡£81ÈÖÌܤΥե롦¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó(FGC)¤Î¸å¡¢OldÀ¤Âå¤ÎÍÆÎÌ(OGC)¤Ï11,696 KB¤«¤é13820 KB¤ËÁý²Ã¤·¤Þ¤·¤¿¡£¤³¤ÎÀ¤Âå(¤ª¤è¤ÓÎΰè)¤ÎºÇÂçÍÆÎ̤ϡ¢60,544 KB (OGCMX)¤Ê¤Î¤Ç¡¢¤Þ¤À³ÈÄ¥¤Ç¤­¤ë;͵¤¬»Ä¤µ¤ì¤Æ¤¤¤Þ¤¹¡£
++TimestampÎó¤Ë¤Ï¡¢¥¿¡¼¥²¥Ã¥ÈJVM¤Îµ¯Æ°»þ¤«¤é¤Î·Ð²á»þ´Ö¤¬¡¢ÉÃñ°Ì¤Ç¥ì¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤µ¤é¤Ë¡¢\fB\-gcoldcapacity\fR½ÐÎϤǤϡ¢³äÅö¥ê¥¯¥¨¥¹¥È¤Þ¤¿¤Ï¾º³Ê¥ê¥¯¥¨¥¹¥È¤¢¤ë¤¤¤Ï¤½¤ÎξÊý¤òËþ¤¿¤¹¤¿¤á¤Ë¥Ò¡¼¥×¤¬³ÈÄ¥¤¹¤ë¤¿¤Ó¤Ë¡¢OldÀ¤Âå¤ÎÍÆÎÌ(OGC)¤ÈOldÎΰè¤ÎÍÆÎÌ(OC)¤È¤¬Áý²Ã¤·¤Æ¤¤¤ë¤³¤È¤¬¤ï¤«¤ê¤Þ¤¹¡£81ÈÖÌܤΥե롦¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó(FGC)¤Î¸å¡¢OldÀ¤Âå¤ÎÍÆÎÌ(OGC)¤Ï11,696KB¤«¤é13,820KB¤ËÁý²Ã¤·¤Þ¤·¤¿¡£¤³¤ÎÀ¤Âå(¤ª¤è¤ÓÎΰè)¤ÎºÇÂçÍÆÎ̤ϡ¢60,544KB (OGCMX)¤Ê¤Î¤Ç¡¢¤Þ¤À³ÈÄ¥¤Ç¤­¤ë;͵¤¬»Ä¤µ¤ì¤Æ¤¤¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+@@ -564,7 +582,7 @@
+ .PP
+ ¤³¤ÎÎã¤Ï¡¢\fB\-gcutil\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¡¢remote\&.domain¤È¤¤¤¦¥·¥¹¥Æ¥à¾å¤Îlvmid 40496¤ËÀܳ¤·¡¢¥µ¥ó¥×¥ë¤òÉÃñ°Ì¤Ç̵´ü¸Â¤Ë¼èÆÀ¤·¤Æ¤¤¤Þ¤¹¡£
+ .PP
+-lvmid¤Ï¡¢¥ê¥â¡¼¥È¡¦¥Û¥¹¥È¤Î̾Á°¤È·ë¹ç¤µ¤ì¤Æ¡¢\fB40496@remote\&.domain\fR¤Î\fIvmid\fR¤ò¹½À®¤·¤Æ¤¤¤Þ¤¹¡£·ë²Ì¤È¤·¤Æ¡¢¤³¤Îvmid¤Ï¡¢\fBrmi\fR¥×¥í¥È¥³¥ë¤ò»ÈÍѤ·¤Æ¡¢¥ê¥â¡¼¥È¡¦¥Û¥¹¥È¾å¤Î¥Ç¥Õ¥©¥ë¥È¤Î\fBjstatd\fR¥µ¡¼¥Ð¡¼¤ÈÄÌ¿®¤·¤Þ¤¹¡£\fBjstatd\fR¥µ¡¼¥Ð¡¼¤Ï¡¢rmiregistry¤ò»ÈÍѤ·¤Æ¡¢¥Ç¥Õ¥©¥ë¥È¤Îrmiregistry¥Ý¡¼¥È(¥Ý¡¼¥È1099)¤Ë¥Ð¥¤¥ó¥É¤µ¤ì¤¿\fBremote\&.domain\fR¤ËÇÛÃÖ¤µ¤ì¤Þ¤¹¡£
++lvmid¤Ï¡¢¥ê¥â¡¼¥È¡¦¥Û¥¹¥È¤Î̾Á°¤È·ë¹ç¤µ¤ì¤Æ¡¢\fB40496@remote\&.domain\fR¤Î\fIvmid\fR¤ò¹½À®¤·¤Æ¤¤¤Þ¤¹¡£·ë²Ì¤È¤·¤Æ¡¢¤³¤Îvmid¤Ï¡¢\fBrmi\fR¥×¥í¥È¥³¥ë¤ò»ÈÍѤ·¤Æ¡¢¥ê¥â¡¼¥È¡¦¥Û¥¹¥È¾å¤Î¥Ç¥Õ¥©¥ë¥È¤Î\fBjstatd\fR¥µ¡¼¥Ð¡¼¤ÈÄÌ¿®¤·¤Þ¤¹¡£\fBjstatd\fR¥µ¡¼¥Ð¡¼¤Ï¡¢\fBrmiregistry\fR¥³¥Þ¥ó¥É¤ò»ÈÍѤ·¤Æ¡¢\fBrmiregistry\fR¥³¥Þ¥ó¥É¤Î¥Ç¥Õ¥©¥ë¥È¤Î¥Ý¡¼¥È(¥Ý¡¼¥È1099)¤Ë¥Ð¥¤¥ó¥É¤µ¤ì¤¿\fBremote\&.domain\fR¤ËÇÛÃÖ¤µ¤ì¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+--- ./jdk/src/linux/doc/man/ja/jstatd.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jstatd.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥â¥Ë¥¿¥ê¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jstatd" "1" "2013ǯ11·î21Æü" "JDK 8" "¥â¥Ë¥¿¥ê¥ó¥°¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/jvisualvm.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/jvisualvm.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¢¥×¥í¥Õ¥¡¥¤¥ê¥ó¥°¡¢¥â¥Ë¥¿¥ê¥ó¥°¤ª¤è¤Ó´ÉÍý¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jvisualvm" "1" "2013ǯ11·î21Æü" "JDK 8" "Java¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¢¥×¥í¥Õ¥¡¥¤¥ê¥ó¥°¡¢¥â¥Ë¥¿¥ê¥ó"
+@@ -51,7 +52,7 @@
+ .\" * MAIN CONTENT STARTS HERE *
+ .\" -----------------------------------------------------------------
+ .SH "̾Á°"
+-jvisualvm \- Java¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ò»ë³ÐŪ¤Ë¥â¥Ë¥¿¡¼¤·¡¢¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¤È¥×¥í¥Õ¥¡¥¤¥ê¥ó¥°¤ò¹Ô¤¤¤Þ¤¹¡£
++jvisualvm \- Java¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ò»ë³ÐŪ¤Ë¥â¥Ë¥¿¡¼¡¢¥È¥é¥Ö¥ë¥·¥å¡¼¥È¤ª¤è¤Ó¥×¥í¥Õ¥¡¥¤¥ë¤·¤Þ¤¹¡£
+ .SH "³µÍ×"
+ .sp
+ .if n \{\
+--- ./jdk/src/linux/doc/man/ja/keytool.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/keytool.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: keytool
+ .\" Language: Japanese
+-.\" Date: 2013ǯ8·î6Æü
++.\" Date: 2015ǯ3·î3Æü
+ .\" SectDesc: ¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "keytool" "1" "2013ǯ8·î6Æü" "JDK 8" "¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë"
++.TH "keytool" "1" "2015ǯ3·î3Æü" "JDK 8" "¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -375,7 +376,7 @@
+ .sp -1
+ .IP \(bu 2.3
+ .\}
+-¥¤¥¿¥ê¥Ã¥¯ÂΤˤʤäƤ¤¤Ê¤¤¤¹¤Ù¤Æ¤Î¹àÌÜ¡¢¤Þ¤¿¤ÏÃ楫¥Ã¥³¤«³Ñ¥«¥Ã¥³¤Ç°Ï¤Þ¤ì¤Æ¤¤¤ë¤¹¤Ù¤Æ¤Î¹àÌܤϡ¢¤½¤Î¤È¤ª¤ê¤Ë»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
++¥¤¥¿¥ê¥Ã¥¯¤Ë¤Ê¤Ã¤Æ¤¤¤Ê¤¤¤¹¤Ù¤Æ¤Î¹àÌÜ¡¢¤Þ¤¿¤ÏÃ楫¥Ã¥³¤«³Ñ¥«¥Ã¥³¤Ç°Ï¤Þ¤ì¤Æ¤¤¤ë¤¹¤Ù¤Æ¤Î¹àÌܤϡ¢¤½¤Î¤È¤ª¤ê¤Ë»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .sp
+ .RS 4
+@@ -408,11 +409,19 @@
+ .sp -1
+ .IP \(bu 2.3
+ .\}
+-¥¤¥¿¥ê¥Ã¥¯ÂΤιàÌܤμºݤÎÃÍ(¥ª¥×¥·¥ç¥ó¤ÎÃÍ)¤Ï¡¢»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢\fB\-printcert\fR¥³¥Þ¥ó¥É¤Î·Á¼°¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹¡£
++¥¤¥¿¥ê¥Ã¥¯¤Î¹àÌܤμºݤÎÃÍ(¥ª¥×¥·¥ç¥ó¤ÎÃÍ)¤Ï¡¢»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢\fB\-printcert\fR¥³¥Þ¥ó¥É¤Î·Á¼°¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹¡£
+ .sp
+-\fBkeytool \-printcert {\-file cert_file} {\-v}\fR
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBkeytool \-printcert {\-file \fR\fB\fIcert_file\fR\fR\fB} {\-v}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ .sp
+-\fB\-printcert\fR¥³¥Þ¥ó¥É¤ò»ØÄꤹ¤ë¾ì¹ç¤Ï¡¢\fBcert_file\fR¤ò¼ÂºÝ¤Î¥Õ¥¡¥¤¥ë̾¤ÇÃÖ¤­´¹¤¨¤Þ¤¹¡£Îã:
++\fB\-printcert\fR¥³¥Þ¥ó¥É¤ò»ØÄꤹ¤ë¾ì¹ç¤Ï¡¢\fIcert_file\fR¤ò¼ÂºÝ¤Î¥Õ¥¡¥¤¥ë̾¤ÇÃÖ¤­´¹¤¨¤Þ¤¹¡£Îã:
+ \fBkeytool \-printcert \-file VScert\&.cer\fR
+ .RE
+ .sp
+@@ -624,8 +633,7 @@
+ SAN¤Þ¤¿¤ÏSubjectAlternativeName
+ .RS 4
+ \fBÃÍ\fR:
+-\fBtype\fR:\fBvalue\fR
+-(t\fBype:value\fR)*¡¢\fBtype\fR¤Ë¤Ï\fBEMAIL\fR¡¢\fBURI\fR¡¢\fBDNS\fR¡¢\fBIP\fR¤Þ¤¿¤Ï\fBOID\fR¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£\fBvalue\fR°ú¿ô¤Ï¡¢\fBtype\fR¤Îʸ»úÎó·Á¼°¤ÎÃͤǤ¹¡£
++\fBtype\fR:\fBvalue\fR(t\fBype:value\fR)*¡¢\fBtype\fR¤Ë¤Ï\fBEMAIL\fR¡¢\fBURI\fR¡¢\fBDNS\fR¡¢\fBIP\fR¤Þ¤¿¤Ï\fBOID\fR¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£\fBvalue\fR°ú¿ô¤Ï¡¢\fBtype\fR¤Îʸ»úÎó·Á¼°¤ÎÃͤǤ¹¡£
+ .RE
+ .PP
+ IAN¤Þ¤¿¤ÏIssuerAlternativeName
+@@ -662,8 +670,66 @@
+ .PP
+ \-gencert
+ .RS 4
+-\fB{\-rfc} {\-infile infile} {\-outfile outfile} {\-alias alias} {\-sigalg sigalg} {\-dname dname} {\-startdate startdate {\-ext ext}* {\-validity valDays} [\-keypass keypass] {\-keystore keystore} [\-storepass storepass] {\-storetype storetype} {\-providername provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-rfc} {\-infile \fR\fB\fIinfile\fR\fR\fB} {\-outfile \fR\fB\fIoutfile\fR\fR\fB} {\-alias \fR\fB\fIalias\fR\fR\fB} {\-sigalg \fR\fB\fIsigalg\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-dname \fR\fB\fIdname\fR\fR\fB} {\-startdate \fR\fB\fIstartdate\fR\fR\fB {\-ext \fR\fB\fIext\fR\fR\fB}* {\-validity \fR\fB\fIvalDays\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-keypass \fR\fB\fIkeypass\fR\fR\fB] {\-keystore \fR\fB\fIkeystore\fR\fR\fB} [\-storepass \fR\fB\fIstorepass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-providername \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¾ÚÌÀ½ñ¥ê¥¯¥¨¥¹¥È¡¦¥Õ¥¡¥¤¥ë(\fBkeytool\fR
+ \fB\-certreq\fR¥³¥Þ¥ó¥É¤ÇºîÀ®²Äǽ)¤ËÂФ¹¤ë¥ì¥¹¥Ý¥ó¥¹¤È¤·¤Æ¾ÚÌÀ½ñ¤òÀ¸À®¤·¤Þ¤¹¡£¤³¤Î¥³¥Þ¥ó¥É¤Ï¡¢\fIinfile\fR¤«¤é(¾Êά¤·¤¿¾ì¹ç¤Ï¡¢É¸½àÆþÎϤ«¤é)¥ê¥¯¥¨¥¹¥È¤òÆɤ߹þ¤ß¡¢ÊÌ̾¤ÎÈëÌ©¸°¤ò»ÈÍѤ·¤Æ¤½¤Î¥ê¥¯¥¨¥¹¥È¤Ë½ð̾¤·¤Æ¡¢X\&.509¾ÚÌÀ½ñ¤ò\fIoutfile\fR¤Ë(¾Êά¤·¤¿¾ì¹ç¤Ï¡¢É¸½à½ÐÎϤË)½ÐÎϤ·¤Þ¤¹¡£\fB\-rfc\fR¤ò»ØÄꤷ¤¿¾ì¹ç¡¢½ÐÎÏ·Á¼°¤ÏBASE64Éä¹æ²½¤ÎPEM¤Ë¤Ê¤ê¤Þ¤¹¡£¤½¤ì°Ê³°¤Î¾ì¹ç¤Ï¡¢¥Ð¥¤¥Ê¥êDER¤¬ºîÀ®¤µ¤ì¤Þ¤¹¡£
+ .sp
+@@ -724,8 +790,66 @@
+ .PP
+ \-genkeypair
+ .RS 4
+-\fB{\-alias alias} {\-keyalg keyalg} {\-keysize keysize} {\-sigalg sigalg} [\-dname dname] [\-keypass keypass] {\-startdate value} {\-ext ext}* {\-validity valDays} {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} {\-keyalg \fR\fB\fIkeyalg\fR\fR\fB} {\-keysize \fR\fB\fIkeysize\fR\fR\fB} {\-sigalg \fR\fB\fIsigalg\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-dname \fR\fB\fIdname\fR\fR\fB] [\-keypass \fR\fB\fIkeypass\fR\fR\fB] {\-startdate \fR\fB\fIvalue\fR\fR\fB} {\-ext \fR\fB\fIext\fR\fR\fB}*\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-validity \fR\fB\fIvalDays\fR\fR\fB} {\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-storepass \fR\fB\fIstorepass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¸°¤Î¥Ú¥¢(¸ø³«¸°¤ª¤è¤Ó´ØÏ¢¤¹¤ëÈëÌ©¸°)¤òÀ¸À®¤·¤Þ¤¹¡£¸ø³«¸°¤ÏX\&.509 v3¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ç¥é¥Ã¥×¤µ¤ì¤Þ¤¹¡£¾ÚÌÀ½ñ¤Ï¡¢Ã±°ì¤ÎÍ×ÁǤò»ý¤Ä¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤È¤·¤Æ³ÊǼ¤µ¤ì¤Þ¤¹¡£¤³¤Î¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤ÈÈëÌ©¸°¤Ï¡¢alias¤ÇÆÃÄꤵ¤ì¤ë¿·¤·¤¤¥­¡¼¥¹¥È¥¢¡¦¥¨¥ó¥È¥ê¤Ë³ÊǼ¤µ¤ì¤Þ¤¹¡£
+ .sp
+ \fBkeyalg\fRÃͤϸ°¥Ú¥¢¤ÎÀ¸À®¤Ë»ÈÍѤ¹¤ë¥¢¥ë¥´¥ê¥º¥à¤ò¡¢\fBkeysize\fRÃͤÏÀ¸À®¤¹¤ë³Æ¸°¤Î¥µ¥¤¥º¤ò¡¢¤½¤ì¤¾¤ì»ØÄꤷ¤Þ¤¹¡£\fBsigalg\fRÃͤϡ¢¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ë½ð̾¤òÉÕ¤±¤ë¤¿¤á¤Ë»ÈÍѤ¹¤ë¥¢¥ë¥´¥ê¥º¥à¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¥¢¥ë¥´¥ê¥º¥à¤Ï\fBkeyalg\fRÃͤȸߴ¹À­¤¬¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+@@ -758,7 +882,7 @@
+ .if n \{\
+ .RE
+ .\}
+-2ÈÖÌܤηÁ¼°¤Ç¤Ï¡¢¥æ¡¼¥¶¡¼¤Ï¡¢Ç¯/·î/Æü¤È»þ´Ö:ʬ:ÉäÎ2¤Ä¤ÎÉôʬ¤«¤é¤Ê¤ëÀµ³Î¤Êȯ¹Ô»þ¹ï¤òÀßÄꤷ¤Þ¤¹(¥í¡¼¥«¥ë¤Î¥¿¥¤¥à¡¦¥¾¡¼¥ó¤ò»ÈÍÑ)¡£¥æ¡¼¥¶¡¼¤Ï¡¢1¤Ä¤ÎÉôʬ¤Î¤ß¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£¤³¤ì¤Ï¡¢¤â¤¦1¤Ä¤ÎÉôʬ¤Ï¸½ºß¤ÎÆüÉÕ(¤Þ¤¿¤Ï»þ¹ï)¤ÈƱ¤¸¤Ë¤Ê¤ë¤È¤¤¤¦¤³¤È¤Ç¤¹¡£¥æ¡¼¥¶¡¼¤Ï¡¢·Á¼°¤ÎÄêµÁ¤Ë¼¨¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë¡¢·å¿ô¤ò¸·Ì©¤Ë»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹(û¤¤¾ì¹ç¤Ï0¤ÇËä¤á¤Þ¤¹)¡£ÆüÉդȻþ¹ï¤ÎξÊý¤¬»ØÄꤵ¤ì¤¿¾õÂ֤ǡ¢2¤Ä¤ÎÉôʬ¤Î´Ö¤Ë¶õÇòʸ»ú¤¬1¤Ä(1¤Ä¤Î¤ß)¤¢¤ê¤Þ¤¹¡£»þ´Ö¤Ï¾ï¤Ë24»þ´Ö·Á¼°¤Ç»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
++2ÈÖÌܤηÁ¼°¤Ç¤Ï¡¢¥æ¡¼¥¶¡¼¤Ï¡¢Ç¯/·î/Æü¤È»þ´Ö:ʬ:ÉäÎ2¤Ä¤ÎÉôʬ¤Ç¸·Ì©¤Ê³«»Ï»þ¹ï¤òÀßÄꤷ¤Þ¤¹(Ãϸµ¤Î»þ´ÖÂÓ¤ò»ÈÍÑ)¡£¥æ¡¼¥¶¡¼¤Ï¡¢1¤Ä¤ÎÉôʬ¤Î¤ß¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£¤³¤ì¤Ï¡¢¤â¤¦1¤Ä¤ÎÉôʬ¤Ï¸½ºß¤ÎÆüÉÕ(¤Þ¤¿¤Ï»þ¹ï)¤ÈƱ¤¸¤Ë¤Ê¤ë¤È¤¤¤¦¤³¤È¤Ç¤¹¡£¥æ¡¼¥¶¡¼¤Ï¡¢·Á¼°¤ÎÄêµÁ¤Ë¼¨¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë¡¢·å¿ô¤ò¸·Ì©¤Ë»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹(û¤¤¾ì¹ç¤Ï0¤ÇËä¤á¤Þ¤¹)¡£ÆüÉդȻþ¹ï¤ÎξÊý¤¬»ØÄꤵ¤ì¤¿¾õÂ֤ǡ¢2¤Ä¤ÎÉôʬ¤Î´Ö¤Ë¶õÇòʸ»ú¤¬1¤Ä(1¤Ä¤Î¤ß)¤¢¤ê¤Þ¤¹¡£»þ´Ö¤Ï¾ï¤Ë24»þ´Ö·Á¼°¤Ç»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ ¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤¤¤È¡¢³«»ÏÆüÉդϸ½ºß¤Î»þ¹ï¤Ë¤Ê¤ê¤Þ¤¹¡£¥ª¥×¥·¥ç¥ó¤Ï¡¢ºÇÂç¤Ç1²ó»ØÄê¤Ç¤­¤Þ¤¹¡£
+ .sp
+@@ -769,8 +893,46 @@
+ .PP
+ \-genseckey
+ .RS 4
+-\fB\-genseckey {\-alias alias} {\-keyalg keyalg} {\-keysize keysize} [\-keypass keypass] {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} {\-keyalg \fR\fB\fIkeyalg\fR\fR\fB} {\-keysize \fR\fB\fIkeysize\fR\fR\fB} [\-keypass \fR\fB\fIkeypass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB} [\-storepass \fR\fB\fIstorepass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}} {\-v}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ÈëÌ©¸°¤òÀ¸À®¤·¡¢¤½¤ì¤ò¿·¤·¤¤\fBKeyStore\&.SecretKeyEntry\fR(\fBalias\fR¤ÇÆÃÄꤵ¤ì¤ë)Æâ¤Ë³ÊǼ¤·¤Þ¤¹¡£
+ .sp
+ \fBkeyalg\fRÃͤϸ°¥Ú¥¢¤ÎÀ¸À®¤Ë»ÈÍѤ¹¤ë¥¢¥ë¥´¥ê¥º¥à¤ò¡¢\fBkeysize\fRÃͤÏÀ¸À®¤¹¤ë³Æ¸°¤Î¥µ¥¤¥º¤ò¡¢¤½¤ì¤¾¤ì»ØÄꤷ¤Þ¤¹¡£\fBkeypass\fRÃͤϡ¢ÈëÌ©¸°¤òÊݸ¤ë¥Ñ¥¹¥ï¡¼¥É¤Ç¤¹¡£¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£¤³¤Î¤È¤­¡¢[Return]¥­¡¼¤ò²¡¤¹¤È¡¢\fBkeystore\fR¤Î¥Ñ¥¹¥ï¡¼¥É¤ÈƱ¤¸¥Ñ¥¹¥ï¡¼¥É¤¬¸°¤Î¥Ñ¥¹¥ï¡¼¥É¤ËÀßÄꤵ¤ì¤Þ¤¹¡£\fBkeypass\fRÃͤϡ¢6ʸ»ú°Ê¾å¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+@@ -778,8 +940,56 @@
+ .PP
+ \-importcert
+ .RS 4
+-\fB\-importcert {\-alias alias} {\-file cert_file} [\-keypass keypass] {\-noprompt} {\-trustcacerts} {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} {\-file \fR\fB\fIcert_file\fR\fR\fB} [\-keypass \fR\fB\fIkeypass\fR\fR\fB] {\-noprompt} {\-trustcacerts}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB} [\-storepass \fR\fB\fIstorepass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerName \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¥Õ¥¡¥¤¥ë\fBcert_file\fR¤«¤é¾ÚÌÀ½ñ¤Þ¤¿¤Ï¾ÚÌÀ½ñ¥Á¥§¡¼¥ó(¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤Î¾ì¹ç¤Ï¡¢PKCS#7·Á¼°¤Î±þÅú¤Þ¤¿¤Ï°ìÏ¢¤ÎX\&.509¾ÚÌÀ½ñ¤ÇÄ󶡤µ¤ì¤ë¤â¤Î)¤òÆɤ߹þ¤ß¡¢\fBalias\fR¤Ë¤è¤Ã¤ÆÆÃÄꤵ¤ì¤ë\fBkeystore\fR¥¨¥ó¥È¥ê¤Ë³ÊǼ¤·¤Þ¤¹¡£¥Õ¥¡¥¤¥ë¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢\fBstdin\fR¤«¤é¾ÚÌÀ½ñ¤Þ¤¿¤Ï¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤òÆɤ߹þ¤ß¤Þ¤¹¡£
+ .sp
+ \fBkeytool\fR¥³¥Þ¥ó¥É¤Ç¤Ï¡¢X\&.509 v1¡¢v2¡¢v3¤Î¾ÚÌÀ½ñ¡¢¤ª¤è¤ÓPKCS#7·Á¼°¤Î¾ÚÌÀ½ñ¤«¤é¹½À®¤µ¤ì¤Æ¤¤¤ëPKCS#7·Á¼°¤Î¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤ò¥¤¥ó¥Ý¡¼¥È¤Ç¤­¤Þ¤¹¡£¥¤¥ó¥Ý¡¼¥È¤¹¤ë¥Ç¡¼¥¿¤Ï¡¢¥Ð¥¤¥Ê¥êÉä¹æ²½Êý¼°¡¢¤Þ¤¿¤Ï½ÐÎϲÄǽÉä¹æ²½Êý¼°(Base64Éä¹æ²½¤È¤â¸Æ¤Ð¤ì¤ë)¤Î¤É¤Á¤é¤«¤ÇÄ󶡤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£½ÐÎϲÄǽÉä¹æ²½Êý¼°¤Ï¡¢¥¤¥ó¥¿¡¼¥Í¥Ã¥ÈRFC 1421¾ÚÌÀ½ñÉä¹æ²½µ¬³Ê¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤³¤ÎÉä¹æ²½Êý¼°¤Î¾ì¹ç¡¢¾ÚÌÀ½ñ¤Ï\fB\-\fR\fB\-\-\-\-BEGIN\fR¤Ç»Ï¤Þ¤ëʸ»úÎó¤Ç³«»Ï¤µ¤ì¡¢\fB\-\-\-\-\-END\fR¤Ç»Ï¤Þ¤ëʸ»úÎó¤Ç½ªÎ»¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+@@ -791,15 +1001,131 @@
+ .PP
+ \-importpassword
+ .RS 4
+-\fB{\-alias alias} [\-keypass keypass] {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} [\-keypass \fR\fB\fIkeypass\fR\fR\fB] {\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-storepass \fR\fB\fIstorepass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¥Ñ¥¹¥Õ¥ì¡¼¥º¤ò¥¤¥ó¥Ý¡¼¥È¤·¡¢\fBalias\fR¤Ç¼±Ê̤µ¤ì¤ë¿·µ¬\fBKeyStore\&.SecretKeyEntry\fR¤Ë³ÊǼ¤·¤Þ¤¹¡£¥Ñ¥¹¥Õ¥ì¡¼¥º¤Ï¡¢É¸½àÆþÎÏ¥¹¥È¥ê¡¼¥à¤ò²ð¤·¤ÆÄ󶡤Ǥ­¤Þ¤¹¡£¤Þ¤¿¤Ï¡¢¥æ¡¼¥¶¡¼¤Ë¤½¤Î¥×¥í¥ó¥×¥È¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£\fBkeypass\fR¤Ï¡¢¥¤¥ó¥Ý¡¼¥È¤µ¤ì¤ë¥Ñ¥¹¥Õ¥ì¡¼¥º¤ÎÊݸî¤Ë»ÈÍѤµ¤ì¤ë¥Ñ¥¹¥ï¡¼¥É¤Ç¤¹¡£¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£¤³¤Î¤È¤­¡¢[Return]¥­¡¼¤ò²¡¤¹¤È¡¢\fBkeystore\fR¤Î¥Ñ¥¹¥ï¡¼¥É¤ÈƱ¤¸¥Ñ¥¹¥ï¡¼¥É¤¬¸°¤Î¥Ñ¥¹¥ï¡¼¥É¤ËÀßÄꤵ¤ì¤Þ¤¹¡£\fBkeypass\fR¤Ï¡¢6ʸ»ú°Ê¾å¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .PP
+ \-importkeystore
+ .RS 4
+-\fB{\-srcstoretype srcstoretype} {\-deststoretype deststoretype} [\-srcstorepass srcstorepass] [\-deststorepass deststorepass] {\-srcprotected} {\-destprotected} {\-srcalias srcalias {\-destalias destalias} [\-srckeypass srckeypass] } [\-destkeypass destkeypass] {\-noprompt} {\-srcProviderName src_provider_name} {\-destProviderName dest_provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-srcstoretype \fR\fB\fIsrcstoretype\fR\fR\fB} {\-deststoretype \fR\fB\fIdeststoretype\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-srcstorepass \fR\fB\fIsrcstorepass\fR\fR\fB] [\-deststorepass \fR\fB\fIdeststorepass\fR\fR\fB] {\-srcprotected}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-destprotected} \fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-srcalias \fR\fB\fIsrcalias\fR\fR\fB {\-destalias \fR\fB\fIdestalias\fR\fR\fB} [\-srckeypass \fR\fB\fIsrckeypass\fR\fR\fB]} \fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-destkeypass \fR\fB\fIdestkeypass\fR\fR\fB] {\-noprompt}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-srcProviderName \fR\fB\fIsrc_provider_name\fR\fR\fB} {\-destProviderName \fR\fB\fIdest_provider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}} {\-v}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¥½¡¼¥¹¡¦¥­¡¼¥¹¥È¥¢¤«¤é¥¿¡¼¥²¥Ã¥È¡¦¥­¡¼¥¹¥È¥¢¤Ø¡¢Ã±°ì¤Î¥¨¥ó¥È¥ê¤Þ¤¿¤Ï¤¹¤Ù¤Æ¤Î¥¨¥ó¥È¥ê¤ò¥¤¥ó¥Ý¡¼¥È¤·¤Þ¤¹¡£
+ .sp
+ \fB\-srcalias\fR¥ª¥×¥·¥ç¥ó¤¬»ØÄꤵ¤ì¤¿¾ì¹ç¡¢¤³¤Î¥³¥Þ¥ó¥É¤Ï¡¢¤½¤ÎÊÌ̾¤ÇÆÃÄꤵ¤ì¤ëñ°ì¤Î¥¨¥ó¥È¥ê¤ò¥¿¡¼¥²¥Ã¥È¡¦¥­¡¼¥¹¥È¥¢¤Ë¥¤¥ó¥Ý¡¼¥È¤·¤Þ¤¹¡£\fBdestalias\fR·Ðͳ¤Ç¥¿¡¼¥²¥Ã¥ÈÊÌ̾¤¬»ØÄꤵ¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¡¢\fBsrcalias\fR¤¬¥¿¡¼¥²¥Ã¥ÈÊÌ̾¤È¤·¤Æ»ÈÍѤµ¤ì¤Þ¤¹¡£¥½¡¼¥¹¤Î¥¨¥ó¥È¥ê¤¬¥Ñ¥¹¥ï¡¼¥É¤ÇÊݸ¤ì¤Æ¤¤¤¿¾ì¹ç¡¢\fBsrckeypass\fR¤ò»ÈÍѤ·¤Æ¤½¤Î¥¨¥ó¥È¥ê¤¬²óÉü¤µ¤ì¤Þ¤¹¡£\fIsrckeypass\fR¤¬»ØÄꤵ¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¡¢\fBkeytool\fR¥³¥Þ¥ó¥É¤Ï\fBsrcstorepass\fR¤ò»ÈÍѤ·¤Æ¤½¤Î¥¨¥ó¥È¥ê¤ò²óÉü¤·¤è¤¦¤È¤·¤Þ¤¹¡£\fBsrcstorepass\fR¤¬»ØÄꤵ¤ì¤Ê¤«¤Ã¤¿¤«Àµ¤·¤¯¤Ê¤«¤Ã¤¿¾ì¹ç¡¢¥æ¡¼¥¶¡¼¤Ï¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£¥¿¡¼¥²¥Ã¥È¤Î¥¨¥ó¥È¥ê¤Ï\fBdestkeypass\fR¤Ë¤è¤Ã¤ÆÊݸ¤ì¤Þ¤¹¡£\fBdestkeypass\fR¤¬»ØÄꤵ¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¡¢¥¿¡¼¥²¥Ã¥È¡¦¥¨¥ó¥È¥ê¤Ï¥½¡¼¥¹¡¦¥¨¥ó¥È¥ê¤Î¥Ñ¥¹¥ï¡¼¥É¤Ë¤è¤Ã¤ÆÊݸ¤ì¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¤Û¤È¤ó¤É¤Î¥µ¡¼¥É¡¦¥Ñ¡¼¥Æ¥£¡¦¥Ä¡¼¥ë¤Ç¤Ï¡¢PKCS #12¥­¡¼¥¹¥È¥¢¤Ç\fBstorepass\fR¤È\fBkeypass\fR¤¬Æ±¤¸¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤é¤Î¥Ä¡¼¥ë¤ÎPKCS #12¥­¡¼¥¹¥È¥¢¤òºîÀ®¤¹¤ë¾ì¹ç¤Ï¡¢¾ï¤Ë\fB\-destkeypass\fR¤È\fB\-deststorepass\fR¤¬Æ±¤¸¤Ë¤Ê¤ë¤è¤¦¤Ë»ØÄꤷ¤Þ¤¹¡£
+@@ -814,16 +1140,72 @@
+ .PP
+ \-printcertreq
+ .RS 4
+-\fB{\-file file}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-file \fR\fB\fIfile\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ PKCS#10·Á¼°¤Î¾ÚÌÀ½ñ¥ê¥¯¥¨¥¹¥È¤ÎÆâÍƤò½ÐÎϤ·¤Þ¤¹¡£¤³¤Î¥ê¥¯¥¨¥¹¥È¤Ï¡¢\fBkeytool\fR
+ \fB\-certreq\fR¥³¥Þ¥ó¥É¤ÇÀ¸À®¤Ç¤­¤Þ¤¹¡£¤³¤Î¥³¥Þ¥ó¥É¤Ï¡¢¥Õ¥¡¥¤¥ë¤«¤é¥ê¥¯¥¨¥¹¥È¤òÆɤ߼è¤ê¤Þ¤¹¡£¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¡¢¥ê¥¯¥¨¥¹¥È¤Ïɸ½àÆþÎϤ«¤éÆɤ߼è¤é¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ \-certreq
+ .RS 4
+-\fB{\-alias alias} {\-dname dname} {\-sigalg sigalg} {\-file certreq_file} [\-keypass keypass] {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} {\-dname \fR\fB\fIdname\fR\fR\fB} {\-sigalg \fR\fB\fIsigalg\fR\fR\fB} {\-file \fR\fB\fIcertreq_file\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-keypass \fR\fB\fIkeypass\fR\fR\fB] {\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-storepass \fR\fB\fIstorepass\fR\fR\fB] {\-providerName \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ PKCS#10·Á¼°¤ò»ÈÍѤ·¤Æ¾ÚÌÀ½ñ½ð̾¥ê¥¯¥¨¥¹¥È(CSR)¤òÀ¸À®¤·¤Þ¤¹¡£
+ .sp
+ CSR¤Ï¡¢¾ÚÌÀ½ñȯ¹Ô¶É(CA)¤ËÁ÷¿®¤¹¤ë¤³¤È¤òÌÜŪ¤È¤·¤¿¤â¤Î¤Ç¤¹¡£CA¤Ï¡¢¾ÚÌÀ½ñÍ×µá¼Ô¤ò(Ä̾ï¤Ï¥ª¥Õ¥é¥¤¥ó¤Ç)ǧ¾Ú¤·¡¢¾ÚÌÀ½ñ¤Þ¤¿¤Ï¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤òÁ÷¤êÊÖ¤·¤Þ¤¹¡£¤³¤Î¾ÚÌÀ½ñ¤Þ¤¿¤Ï¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤Ï¡¢¥­¡¼¥¹¥È¥¢Æâ¤Î´û¸¤Î¾ÚÌÀ½ñ¥Á¥§¡¼¥ó(ºÇ½é¤Ï1¤Ä¤Î¼«¸Ê½ð̾¾ÚÌÀ½ñ¤«¤é¹½À®¤µ¤ì¤ë)¤ËÃÖ¤­´¹¤¨¤Æ»ÈÍѤ·¤Þ¤¹¡£
+@@ -839,8 +1221,46 @@
+ .PP
+ \-exportcert
+ .RS 4
+-\fB{\-alias alias} {\-file cert_file} {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-rfc} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} {\-file \fR\fB\fIcert_file\fR\fR\fB} {\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-storepass \fR\fB\fIstorepass\fR\fR\fB] {\-providerName \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-rfc} {\-v} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ \fIalias\fR¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¾ÚÌÀ½ñ¤ò¥­¡¼¥¹¥È¥¢¤«¤éÆɤ߹þ¤ß¡¢¥Õ¥¡¥¤¥ëcert_file¤Ë³ÊǼ¤·¤Þ¤¹¡£¥Õ¥¡¥¤¥ë¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢\fBstdout\fR¤Ë¾ÚÌÀ½ñ¤¬½ÐÎϤµ¤ì¤Þ¤¹¡£
+ .sp
+ ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¾ÚÌÀ½ñ¤Ï¥Ð¥¤¥Ê¥êÉä¹æ²½¤Ç½ÐÎϤµ¤ì¤Þ¤¹¡£\fB\-rfc\fR¥ª¥×¥·¥ç¥ó¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢½ÐÎϲÄǽÉä¹æ²½Êý¼°¤Î½ÐÎϤϥ¤¥ó¥¿¡¼¥Í¥Ã¥ÈRFC 1421¾ÚÌÀ½ñÉä¹æ²½µ¬³Ê¤ÇÄêµÁ¤µ¤ì¤Þ¤¹¡£
+@@ -852,8 +1272,46 @@
+ .PP
+ \-list
+ .RS 4
+-\fB{\-alias alias} {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v | \-rfc} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} {\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB} [\-storepass \fR\fB\fIstorepass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerName \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v | \-rfc} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ \fBalias\fR¤ÇÆÃÄꤵ¤ì¤ë¥­¡¼¥¹¥È¥¢¡¦¥¨¥ó¥È¥ê¤ÎÆâÍƤò\fBstdout\fR¤Ë½ÐÎϤ·¤Þ¤¹¡£\fBalias\fR¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢¥­¡¼¥¹¥È¥¢Á´ÂΤÎÆâÍƤ¬É½¼¨¤µ¤ì¤Þ¤¹¡£
+ .sp
+ ¤³¤Î¥³¥Þ¥ó¥É¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¾ÚÌÀ½ñ¤ÎSHA1¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤òɽ¼¨¤·¤Þ¤¹¡£
+@@ -864,8 +1322,26 @@
+ .PP
+ \-printcert
+ .RS 4
+-\fB{\-file cert_file | \-sslserver host[:port]} {\-jarfile JAR_file {\-rfc} {\-v} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-file \fR\fB\fIcert_file\fR\fR\fB | \-sslserver \fR\fB\fIhost\fR\fR\fB[:\fR\fB\fIport\fR\fR\fB]} {\-jarfile \fR\fB\fIJAR_file\fR\fR\fB {\-rfc} {\-v}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¥Õ¥¡¥¤¥ëcert_file¡¢host:port¤Ë¤¢¤ëSSL¥µ¡¼¥Ð¡¼¡¢¤Þ¤¿¤Ï½ð̾ÉÕ¤­JAR¥Õ¥¡¥¤¥ë\fBJAR_file\fR(\fB\-jarfile\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄê)¤«¤é¾ÚÌÀ½ñ¤òÆɤ߹þ¤ß¡¢¿Í´Ö¤¬Æɤळ¤È¤Î¤Ç¤­¤ë·Á¼°¤Ç¾ÚÌÀ½ñ¤ÎÆâÍƤòɽ¼¨¤·¤Þ¤¹¡£¥Ý¡¼¥È¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢É¸½à¤ÎHTTPS¥Ý¡¼¥È443¤¬ÁÛÄꤵ¤ì¤Þ¤¹¡£\fB\-sslserver\fR¤ª¤è¤Ó\-file¥ª¥×¥·¥ç¥ó¤òƱ»þ¤Ë»ØÄꤹ¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢¥¨¥é¡¼¤¬Êó¹ð¤µ¤ì¤Þ¤¹¡£¥ª¥×¥·¥ç¥ó¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢\fBstdin\fR¤«¤é¾ÚÌÀ½ñ¤òÆɤ߹þ¤ß¤Þ¤¹¡£
+ .sp
+ \fB\-rfc\fR¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢\fBkeytool\fR¥³¥Þ¥ó¥É¤Ï¡¢¥¤¥ó¥¿¡¼¥Í¥Ã¥ÈRFC 1421¾ÚÌÀ½ñÉä¹æ²½É¸½à¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë¡¢PEM¥â¡¼¥É¤Ç¾ÚÌÀ½ñ¤ò½ÐÎϤ·¤Þ¤¹¡£¥¤¥ó¥¿¡¼¥Í¥Ã¥ÈRFC 1421¾ÚÌÀ½ñÉä¹æ²½µ¬³Ê¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+@@ -881,8 +1357,16 @@
+ .PP
+ \-printcrl
+ .RS 4
+-\fB\-file crl_ {\-v}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB\-file \fR\fB\fIcrl_\fR\fR\fB {\-v}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¥Õ¥¡¥¤¥ë\fBcrl_\fR¤«¤é¾ÚÌÀ½ñ¼º¸ú¥ê¥¹¥È(CRL)¤òÆɤ߹þ¤ß¤Þ¤¹¡£CRL¤Ï¡¢È¯¹Ô¤·¤¿CA¤Ë¤è¤Ã¤Æ¼º¸ú¤µ¤ì¤¿¥Ç¥¸¥¿¥ë¾ÚÌÀ½ñ¤Î¥ê¥¹¥È¤Ç¤¹¡£CA¤Ï¡¢\fBcrl_\fR¤òÀ¸À®¤·¤Þ¤¹¡£
+ .sp
+ \fBÃí°Õ:\fR
+@@ -891,15 +1375,91 @@
+ .PP
+ \-storepasswd
+ .RS 4
+-\fB[\-new new_storepass] {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-new \fR\fB\fInew_storepass\fR\fR\fB] {\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-storepass \fR\fB\fIstorepass\fR\fR\fB] {\-providerName \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¥­¡¼¥¹¥È¥¢¤ÎÆâÍƤÎÀ°¹çÀ­¤òÊݸ¤ë¤¿¤á¤Ë»ÈÍѤ¹¤ë¥Ñ¥¹¥ï¡¼¥É¤òÊѹ¹¤·¤Þ¤¹¡£\fBnew_storepass\fR¤Ë¤Ï¡¢¿·¤·¤¤¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄꤷ¤Þ¤¹¡£new_storepass¤Ï¡¢6ʸ»ú°Ê¾å¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .PP
+ \-keypasswd
+ .RS 4
+-\fB{\-alias alias} [\-keypass old_keypass] [\-new new_keypass] {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} [\-keypass \fR\fB\fIold_keypass\fR\fR\fB] [\-new \fR\fB\fInew_keypass\fR\fR\fB] {\-storetype \fR\fB\fIstoretype\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-keystore \fR\fB\fIkeystore\fR\fR\fB} [\-storepass \fR\fB\fIstorepass\fR\fR\fB] {\-providerName \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}} {\-v}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ \fBalias\fR¤Ë¤è¤Ã¤ÆÆÃÄꤵ¤ì¤ëÈó¸ø³«/ÈëÌ©¸°¤òÊݸ¤ë¤¿¤á¤Î¥Ñ¥¹¥ï¡¼¥É¤ò¡¢\fBold_keypass\fR¤«¤é\fBnew_keypass\fR¤ËÊѹ¹¤·¤Þ¤¹¡£new_keypass¤Ï¡¢6ʸ»ú°Ê¾å¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .sp
+ ¥³¥Þ¥ó¥É¹Ô¤Ç\fB\-keypass\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Æ¤ª¤é¤º¡¢¸°¤Î¥Ñ¥¹¥ï¡¼¥É¤¬¥­¡¼¥¹¥È¥¢¤Î¥Ñ¥¹¥ï¡¼¥É¤È°Û¤Ê¤ë¾ì¹ç¤Ï¡¢¸°¤Î¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£
+@@ -909,15 +1469,91 @@
+ .PP
+ \-delete
+ .RS 4
+-\fB[\-alias alias] {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-alias \fR\fB\fIalias\fR\fR\fB] {\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB} [\-storepass \fR\fB\fIstorepass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerName \fR\fB\fIprovider_name\fR\fR\fB} \fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ \fBalias\fR¤Ë¤è¤Ã¤ÆÆÃÄꤵ¤ì¤ë¥¨¥ó¥È¥ê¤ò¥­¡¼¥¹¥È¥¢¤«¤éºï½ü¤·¤Þ¤¹¡£¥³¥Þ¥ó¥É¹Ô¤ÇÊÌ̾¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢ÊÌ̾¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ \-changealias
+ .RS 4
+-\fB{\-alias alias} [\-destalias destalias] [\-keypass keypass] {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} [\-destalias \fR\fB\fIdestalias\fR\fR\fB] [\-keypass \fR\fB\fIkeypass\fR\fR\fB] {\-storetype \fR\fB\fIstoretype\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-keystore \fR\fB\fIkeystore\fR\fR\fB} [\-storepass \fR\fB\fIstorepass\fR\fR\fB] {\-providerName \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}} {\-v}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ »ØÄꤵ¤ì¤¿\fBalias\fR¤«¤é¿·¤·¤¤ÊÌ̾\fBdestalias\fR¤Ø¡¢´û¸¤Î¥­¡¼¥¹¥È¥¢¡¦¥¨¥ó¥È¥ê¤ò°ÜÆ°¤·¤Þ¤¹¡£¥¿¡¼¥²¥Ã¥ÈÊÌ̾¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¡¢¥¿¡¼¥²¥Ã¥ÈÊÌ̾¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£¸µ¤Î¥¨¥ó¥È¥ê¤¬¥¨¥ó¥È¥ê¡¦¥Ñ¥¹¥ï¡¼¥É¤ÇÊݸ¤ì¤Æ¤¤¤¿¾ì¹ç¡¢\fB\-keypass\fR¥ª¥×¥·¥ç¥ó¤Ç¤½¤Î¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£¸°¥Ñ¥¹¥ï¡¼¥É¤¬»ØÄꤵ¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¡¢\fBstorepass\fR(»ØÄꤵ¤ì¤¿¾ì¹ç)¤¬¤Þ¤º»î¤ß¤é¤ì¤Þ¤¹¡£¤½¤Î»î¤ß¤¬¼ºÇÔ¤¹¤ë¤È¡¢¥æ¡¼¥¶¡¼¤Ï¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+@@ -971,7 +1607,7 @@
+ °Ê¹ß¤Ç¤Ï¡¢¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤¤¤Ç\fB\-genkeypair\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤¿¤â¤Î¤È¤·¤ÆÎã¤ò¼¨¤·¤Þ¤¹¡£¾ðÊó¤ÎÆþÎϤòµá¤á¤é¤ì¤¿¾ì¹ç¤Ï¡¢ºÇ½é¤Ë¼¨¤·¤¿\fB\-genkeypair\fR¥³¥Þ¥ó¥É¤ÎÃͤòÆþÎϤ·¤¿¤â¤Î¤È¤·¤Þ¤¹¡£¤¿¤È¤¨¤Ð¼±ÊÌ̾¤Ë¤Ï\fBcn=Mark Jones\fR¡¢\fBou=Java\fR¡¢\fBo=Oracle\fR¡¢\fBc=US\fR¤È»ØÄꤷ¤Þ¤¹¡£
+ .SS "CA¤«¤é¤Î½ð̾ÉÕ¤­¾ÚÌÀ½ñ¤Î¥ê¥¯¥¨¥¹¥È"
+ .PP
+-¼«¸Ê½ð̾¾ÚÌÀ½ñ¤òºîÀ®¤¹¤ë¸°¤Î¥Ú¥¢¤ÎÀ¸À®¡£¾ÚÌÀ½ñ¤Ë¾ÚÌÀ½ñȯ¹Ô¶É(CA)¤Î½ð̾¤¬ÉÕ¤¤¤Æ¤¤¤ì¤Ð¡¢Â¾¤Î¥æ¡¼¥¶¡¼¤«¤é¾ÚÌÀ½ñ¤¬¿®Íꤵ¤ì¤ë²ÄǽÀ­¤â¹â¤¯¤Ê¤ê¤Þ¤¹¡£CA¤Î½ð̾¤ò¼èÆÀ¤¹¤ë¤Ë¤Ï¡¢¤Þ¤º¡¢¾ÚÌÀ½ñ½ð̾¥ê¥¯¥¨¥¹¥È(CSR)¤òÀ¸À®¤·¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¼¡¤Î¤è¤¦¤Ë¤·¤Þ¤¹¡£
++¼«¸Ê½ð̾¾ÚÌÀ½ñ¤òºîÀ®¤¹¤ë¸°¤Î¥Ú¥¢¤ÎÀ¸À®¡£¾ÚÌÀ½ñ¤Ëǧ¾Ú¶É(CA)¤Î½ð̾¤¬ÉÕ¤¤¤Æ¤¤¤ì¤Ð¡¢Â¾¤Î¥æ¡¼¥¶¡¼¤«¤é¾ÚÌÀ½ñ¤¬¿®Íꤵ¤ì¤ë²ÄǽÀ­¤â¹â¤¯¤Ê¤ê¤Þ¤¹¡£CA¤Î½ð̾¤ò¼èÆÀ¤¹¤ë¤Ë¤Ï¡¢¤Þ¤º¡¢¾ÚÌÀ½ñ½ð̾¥ê¥¯¥¨¥¹¥È(CSR)¤òÀ¸À®¤·¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¼¡¤Î¤è¤¦¤Ë¤·¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+@@ -1015,7 +1651,7 @@
+ .PP
+ \fBcacerts\fR¥­¡¼¥¹¥È¥¢¡¦¥Õ¥¡¥¤¥ë¤Ï¡¢¤¤¤¯¤Ä¤«¤ÎVeriSign¥ë¡¼¥ÈCA¾ÚÌÀ½ñ¤ò´Þ¤ó¤À¾õÂ֤ǽв٤µ¤ì¤Æ¤¤¤ë¤Î¤Ç¡¢VeriSign¤Î¾ÚÌÀ½ñ¤ò¡¢¿®Íê¤Ç¤­¤ë¾ÚÌÀ½ñ¤È¤·¤Æ¥­¡¼¥¹¥È¥¢Æâ¤Ë¥¤¥ó¥Ý¡¼¥È¤¹¤ëɬÍפ¬¤Ê¤¤¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£¤¿¤À¤·¡¢Â¾¤ÎCA¤ËÂФ·¤Æ½ð̾ÉÕ¤­¾ÚÌÀ½ñ¤ò¥ê¥¯¥¨¥¹¥È¤·¤Æ¤¤¤Æ¡¢¤³¤ÎCA¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤¬¡¢\fBcacerts\fR¤Ë¤Þ¤ÀÄɲ䵤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢³ºÅö¤¹¤ëCA¤«¤é¤Î¾ÚÌÀ½ñ¤ò¡¢¡Ö¿®Íê¤Ç¤­¤ë¾ÚÌÀ½ñ¡×¤È¤·¤Æ¥¤¥ó¥Ý¡¼¥È¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .PP
+-Ä̾CA¤«¤é¤Î¾ÚÌÀ½ñ¤Ï¡¢¼«¸Ê½ð̾¾ÚÌÀ½ñ¡¢¤Þ¤¿¤Ï¾¤ÎCA¤Ë¤è¤Ã¤Æ½ð̾¤µ¤ì¤¿¾ÚÌÀ½ñ¤Ç¤¹(¸å¼Ô¤Î¾ì¹ç¤Ï¡¢³ºÅö¤¹¤ë¾¤ÎCA¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤¬É¬Í×)¡£ABC, Inc\&.,¤¬CA¤Ç¡¢ABC¤«¤é¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ç¤¢¤ëA\fBBCCA\&.cer\fR¤È¤¤¤¦Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤ò¼èÆÀ¤·¤¿¤È¤·¤Þ¤¹(¤³¤Î¾ÚÌÀ½ñ¤ÏCA¤Î¸ø³«¸°¤òǧ¾Ú¤·¤Þ¤¹)¡£¿®Íê¤Ç¤­¤ë¾ÚÌÀ½ñ¤È¤·¤Æ¾ÚÌÀ½ñ¤ò¥¤¥ó¥Ý¡¼¥È¤¹¤ë¤È¤­¤Ï¡¢¾ÚÌÀ½ñ¤¬Í­¸ú¤Ç¤¢¤ë¤³¤È¤ò³Îǧ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤Þ¤º¡¢\fBkeytool \-printcert\fR¥³¥Þ¥ó¥É¤Þ¤¿¤Ï\fB\-noprompt\fR¥ª¥×¥·¥ç¥ó¤Ê¤·¤Î\fBkeytool \-importcert\fR¥³¥Þ¥ó¥É¤Ç¤½¤ì¤òɽ¼¨¤·¡¢É½¼¨¤µ¤ì¤¿¾ÚÌÀ½ñ¤Î¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤¬´üÂÔ¤µ¤ì¤ë¤â¤Î¤È°ìÃפ¹¤ë¤«¤É¤¦¤«¤ò³Îǧ¤·¤Þ¤¹¡£¾ÚÌÀ½ñ¤òÁ÷¿®¤·¤¿¿Íʪ¤ËÏ¢Íí¤·¡¢¤³¤Î¿Íʪ¤¬Ä󼨤·¤¿(¤Þ¤¿¤Ï¥»¥­¥å¥¢¤Ê¸ø³«¸°¤Î¥ê¥Ý¥¸¥È¥ê¤Ë¤è¤Ã¤ÆÄ󼨤µ¤ì¤ë)¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤È¡¢¾å¤Î¥³¥Þ¥ó¥É¤Çɽ¼¨¤µ¤ì¤¿¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤È¤òÈæ³Ó¤·¤Þ¤¹¡£¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤¬°ìÃפ¹¤ì¤Ð¡¢Á÷¿®ÅÓÃæ¤Ç¾¤Î²¿¼Ô¤«(¹¶·â¼Ô¤Ê¤É)¤Ë¤è¤ë¾ÚÌÀ½ñ¤Î¤¹¤êÂؤ¨¤¬¹Ô¤ï¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò³Îǧ¤Ç¤­¤Þ¤¹¡£Á÷¿®ÅÓÃæ¤Ç¤³¤Î¼ï¤Î¹¶·â¤¬¹Ô¤ï¤ì¤Æ¤¤¤¿¾ì¹ç¡¢¥Á¥§¥Ã¥¯¤ò¹Ô¤ï¤º¤Ë¾ÚÌÀ½ñ¤ò¥¤¥ó¥Ý¡¼¥È¤¹¤ë¤È¡¢¹¶·â¼Ô¤Ë¤è¤Ã¤Æ½ð̾¤µ¤ì¤¿¤¹¤Ù¤Æ¤Î¤â¤Î¤ò¿®Íꤹ¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£
++Ä̾CA¤«¤é¤Î¾ÚÌÀ½ñ¤Ï¡¢¼«¸Ê½ð̾¾ÚÌÀ½ñ¡¢¤Þ¤¿¤Ï¾¤ÎCA¤Ë¤è¤Ã¤Æ½ð̾¤µ¤ì¤¿¾ÚÌÀ½ñ¤Ç¤¹(¸å¼Ô¤Î¾ì¹ç¤Ï¡¢³ºÅö¤¹¤ë¾¤ÎCA¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤¬É¬Í×)¡£ABC, Inc\&.,¤¬CA¤Ç¡¢ABC¤«¤é¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ç¤¢¤ëA\fBBCCA\&.cer\fR¤È¤¤¤¦Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤ò¼èÆÀ¤·¤¿¤È¤·¤Þ¤¹(¤³¤Î¾ÚÌÀ½ñ¤ÏCA¤Î¸ø³«¸°¤òǧ¾Ú¤·¤Þ¤¹)¡£¿®Íê¤Ç¤­¤ë¾ÚÌÀ½ñ¤È¤·¤Æ¾ÚÌÀ½ñ¤ò¥¤¥ó¥Ý¡¼¥È¤¹¤ë¤È¤­¤Ï¡¢¾ÚÌÀ½ñ¤¬Í­¸ú¤Ç¤¢¤ë¤³¤È¤ò³Îǧ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤Þ¤º¡¢¾ÚÌÀ½ñ¤ÎÆâÍƤòɽ¼¨¤·¡¢\fBkeytool \-printcert\fR¥³¥Þ¥ó¥É¤ò»ÈÍѤ¹¤ë¤«¡¢¤Þ¤¿¤Ï\fB\-noprompt\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤¤¤Ç\fBkeytool \-importcert\fR¥³¥Þ¥ó¥É¤ò»ÈÍѤ·¡¢É½¼¨¤µ¤ì¤¿¾ÚÌÀ½ñ¤Î¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤¬¡¢´üÂÔ¤µ¤ì¤ë¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤È°ìÃפ¹¤ë¤«¤É¤¦¤«¤ò³Îǧ¤·¤Þ¤¹¡£¾ÚÌÀ½ñ¤òÁ÷¿®¤·¤¿¿Íʪ¤ËÏ¢Íí¤·¡¢¤³¤Î¿Íʪ¤¬Ä󼨤·¤¿(¤Þ¤¿¤Ï°ÂÁ´¤Ê¸ø³«¸°¤Î¥ê¥Ý¥¸¥È¥ê¤Ë¤è¤Ã¤ÆÄ󼨤µ¤ì¤ë)¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤È¡¢¾å¤Î¥³¥Þ¥ó¥É¤Çɽ¼¨¤µ¤ì¤¿¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤È¤òÈæ³Ó¤·¤Þ¤¹¡£¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤¬°ìÃפ¹¤ì¤Ð¡¢Á÷¿®ÅÓÃæ¤Ç¾¤Î²¿¼Ô¤«(¹¶·â¼Ô¤Ê¤É)¤Ë¤è¤ë¾ÚÌÀ½ñ¤Î¤¹¤êÂؤ¨¤¬¹Ô¤ï¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò³Îǧ¤Ç¤­¤Þ¤¹¡£Á÷¿®ÅÓÃæ¤Ç¤³¤Î¼ï¤Î¹¶·â¤¬¹Ô¤ï¤ì¤Æ¤¤¤¿¾ì¹ç¡¢¥Á¥§¥Ã¥¯¤ò¹Ô¤ï¤º¤Ë¾ÚÌÀ½ñ¤ò¥¤¥ó¥Ý¡¼¥È¤¹¤ë¤È¡¢¹¶·â¼Ô¤Ë¤è¤Ã¤Æ½ð̾¤µ¤ì¤¿¤¹¤Ù¤Æ¤Î¤â¤Î¤ò¿®Íꤹ¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£
+ .PP
+ ¾ÚÌÀ½ñ¤¬Í­¸ú¤Ç¤¢¤ë¤È¿®Íꤹ¤ë¾ì¹ç¤Ï¡¢¼¡¤Î¥³¥Þ¥ó¥É¤Ç¥­¡¼¥¹¥È¥¢¤ËÄɲäǤ­¤Þ¤¹¡£
+ .sp
+@@ -1182,7 +1818,7 @@
+ .if n \{\
+ .RE
+ .\}
+-¥Ñ¥¹¥ï¡¼¥É¤¬¡¢\fBdukekeypasswd\fR¤«¤é\fBnewpass\fR¤ËÊѹ¹¤µ¤ì¤Þ¤¹¡£¥Æ¥¹¥È¤òÌÜŪ¤È¤¹¤ë¾ì¹ç¡¢¤Þ¤¿¤Ï°ÂÁ´¤Ç¤¢¤ë¤³¤È¤¬¤ï¤«¤Ã¤Æ¤¤¤ë¥·¥¹¥Æ¥à¤Ç¼Â¹Ô¤¹¤ë¾ì¹ç°Ê³°¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤ä¥¹¥¯¥ê¥×¥È¤Ç¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄꤷ¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£É¬Íפʥѥ¹¥ï¡¼¥É¤Î¥ª¥×¥·¥ç¥ó¤ò¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£
++¥Ñ¥¹¥ï¡¼¥É¤¬¡¢\fBdukekeypasswd\fR¤«¤é\fBnewpass\fR¤ËÊѹ¹¤µ¤ì¤Þ¤¹¡£¥Æ¥¹¥ÈÌÜŪ¤Î¾ì¹ç¡¢¤Þ¤¿¤Ï¥»¥­¥å¥¢¤Ê¥·¥¹¥Æ¥à¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç°Ê³°¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤ä¥¹¥¯¥ê¥×¥È¤Ç¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄꤷ¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£É¬Íפʥѥ¹¥ï¡¼¥É¤Î¥ª¥×¥·¥ç¥ó¤ò¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ ¥­¡¼¥¹¥È¥¢¤Î¼ÂÁõ
+@@ -1260,9 +1896,9 @@
+ .sp
+ \fB¥¨¥ó¥Æ¥£¥Æ¥£\fR: ¥¨¥ó¥Æ¥£¥Æ¥£¤Ï¡¢¿Í¡¢ÁÈ¿¥¡¢¥×¥í¥°¥é¥à¡¢¥³¥ó¥Ô¥å¡¼¥¿¡¢´ë¶È¡¢¶ä¹Ô¤Ê¤É¡¢°ìÄê¤ÎÅٹ礤¤Ç¿®Íê¤ÎÂоݤȤʤëÍÍ¡¹¤Ê¤â¤Î¤ò»Ø¤·¤Þ¤¹¡£
+ .sp
+-¸ø³«¸°°Å¹æ²½¤Ç¤Ï¡¢¥æ¡¼¥¶¡¼¤Î¸ø³«¸°¤Ë¥¢¥¯¥»¥¹¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£Â絬ÌϤʥͥåȥ¥¯´Ä¶­¤Ç¤Ï¡¢¸ß¤¤¤ËÄÌ¿®¤·¤Æ¤¤¤ë¥¨¥ó¥Æ¥£¥Æ¥£´Ö¤Ç°ÊÁ°¤Î´Ø·¸¤¬°ú³¤­³ÎΩ¤µ¤ì¤Æ¤¤¤ë¤È²¾Äꤷ¤¿¤ê¡¢»ÈÍѤµ¤ì¤Æ¤¤¤ë¤¹¤Ù¤Æ¤Î¸ø³«¸°¤ò¼ý¤á¤¿¿®Íê¤Ç¤­¤ë¥ê¥Ý¥¸¥È¥ê¤¬Â¸ºß¤¹¤ë¤È²¾Äꤷ¤¿¤ê¤¹¤ë¤³¤È¤ÏÉÔ²Äǽ¤Ç¤¹¡£¤³¤Î¤è¤¦¤Ê¸ø³«¸°¤ÎÇÛÉۤ˴ؤ¹¤ëÌäÂê¤ò²ò·è¤¹¤ë¤¿¤á¤Ë¾ÚÌÀ½ñ¤¬¹Í°Æ¤µ¤ì¤Þ¤·¤¿¡£¸½ºß¤Ç¤Ï¡¢¾ÚÌÀ½ñȯ¹Ô¶É(CA)¤¬¿®Íê¤Ç¤­¤ëÂè»°¼Ô¤È¤·¤Æµ¡Ç½¤·¤Þ¤¹¡£CA¤Ï¡¢Â¾¤Î¥¨¥ó¥Æ¥£¥Æ¥£¤Î¾ÚÌÀ½ñ¤Ë½ð̾¤¹¤ë(ȯ¹Ô¤¹¤ë)¹Ô°Ù¤ò¡¢¿®Íꤷ¤ÆǤ¤µ¤ì¤Æ¤¤¤ë¥¨¥ó¥Æ¥£¥Æ¥£(´ë¶È¤Ê¤É)¤Ç¤¹¡£CA¤ÏˡΧ¾å¤Î·ÀÌó¤Ë¹´Â«¤µ¤ì¤ë¤Î¤Ç¡¢Í­¸ú¤«¤Ä¿®Íê¤Ç¤­¤ë¾ÚÌÀ½ñ¤Î¤ß¤òºîÀ®¤¹¤ë¤â¤Î¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£VeriSign¡¢Thawte¡¢Entrust¤ò¤Ï¤¸¤á¡¢Â¿¤¯¤Î¸øŪ¤Ê¾ÚÌÀ½ñȯ¹Ô¶É¤¬Â¸ºß¤·¤Þ¤¹¡£
++¸ø³«¸°°Å¹æ²½¤Ç¤Ï¡¢¥æ¡¼¥¶¡¼¤Î¸ø³«¸°¤Ë¥¢¥¯¥»¥¹¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£Â絬ÌϤʥͥåȥ¥¯´Ä¶­¤Ç¤Ï¡¢¸ß¤¤¤ËÄÌ¿®¤·¤Æ¤¤¤ë¥¨¥ó¥Æ¥£¥Æ¥£´Ö¤Ç°ÊÁ°¤Î´Ø·¸¤¬°ú³¤­³ÎΩ¤µ¤ì¤Æ¤¤¤ë¤È²¾Äꤷ¤¿¤ê¡¢»ÈÍѤµ¤ì¤Æ¤¤¤ë¤¹¤Ù¤Æ¤Î¸ø³«¸°¤ò¼ý¤á¤¿¿®Íê¤Ç¤­¤ë¥ê¥Ý¥¸¥È¥ê¤¬Â¸ºß¤¹¤ë¤È²¾Äꤷ¤¿¤ê¤¹¤ë¤³¤È¤ÏÉÔ²Äǽ¤Ç¤¹¡£¤³¤Î¤è¤¦¤Ê¸ø³«¸°¤ÎÇÛÉۤ˴ؤ¹¤ëÌäÂê¤ò²ò·è¤¹¤ë¤¿¤á¤Ë¾ÚÌÀ½ñ¤¬¹Í°Æ¤µ¤ì¤Þ¤·¤¿¡£¸½ºß¤Ç¤Ï¡¢Ç§¾Ú¶É(CA)¤¬¿®Íê¤Ç¤­¤ëÂè»°¼Ô¤È¤·¤Æµ¡Ç½¤·¤Þ¤¹¡£CA¤Ï¡¢Â¾¤Î¥¨¥ó¥Æ¥£¥Æ¥£¤Î¾ÚÌÀ½ñ¤Ë½ð̾¤¹¤ë(ȯ¹Ô¤¹¤ë)¹Ô°Ù¤ò¡¢¿®Íꤷ¤ÆǤ¤µ¤ì¤Æ¤¤¤ë¥¨¥ó¥Æ¥£¥Æ¥£(´ë¶È¤Ê¤É)¤Ç¤¹¡£CA¤ÏˡΧ¾å¤Î·ÀÌó¤Ë¹´Â«¤µ¤ì¤ë¤Î¤Ç¡¢Í­¸ú¤«¤Ä¿®Íê¤Ç¤­¤ë¾ÚÌÀ½ñ¤Î¤ß¤òºîÀ®¤¹¤ë¤â¤Î¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£VeriSign¡¢Thawte¡¢Entrust¤ò¤Ï¤¸¤á¡¢Â¿¤¯¤Î¸øŪ¤Êǧ¾Ú¶É¤¬Â¸ºß¤·¤Þ¤¹¡£
+ .sp
+-Microsoft¤Îǧ¾Ú¥µ¡¼¥Ð¡¼¡¢Entrust¤ÎCAÀ½Éʤʤɤò½ê°ÁÈ¿¥Æâ¤ÇÍøÍѤ¹¤ì¤Ð¡¢Æȼ«¤Î¾ÚÌÀ½ñȯ¹Ô¶É¤ò±¿±Ä¤¹¤ë¤³¤È¤â²Äǽ¤Ç¤¹¡£\fBkeytool\fR¥³¥Þ¥ó¥É¤ò»ÈÍѤ¹¤ë¤È¡¢¾ÚÌÀ½ñ¤Îɽ¼¨¡¢¥¤¥ó¥Ý¡¼¥È¤ª¤è¤Ó¥¨¥¯¥¹¥Ý¡¼¥È¤ò¹Ô¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤Þ¤¿¡¢¼«¸Ê½ð̾¾ÚÌÀ½ñ¤òÀ¸À®¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£
++Microsoft¤Îǧ¾Ú¥µ¡¼¥Ð¡¼¡¢Entrust¤ÎCAÀ½Éʤʤɤò½ê°ÁÈ¿¥Æâ¤ÇÍøÍѤ¹¤ì¤Ð¡¢Æȼ«¤Îǧ¾Ú¶É¤ò±¿±Ä¤¹¤ë¤³¤È¤â²Äǽ¤Ç¤¹¡£\fBkeytool\fR¥³¥Þ¥ó¥É¤ò»ÈÍѤ¹¤ë¤È¡¢¾ÚÌÀ½ñ¤Îɽ¼¨¡¢¥¤¥ó¥Ý¡¼¥È¤ª¤è¤Ó¥¨¥¯¥¹¥Ý¡¼¥È¤ò¹Ô¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤Þ¤¿¡¢¼«¸Ê½ð̾¾ÚÌÀ½ñ¤òÀ¸À®¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£
+ .sp
+ ¸½ºß¡¢\fBkeytool\fR¥³¥Þ¥ó¥É¤ÏX\&.509¾ÚÌÀ½ñ¤òÂоݤˤ·¤Æ¤¤¤Þ¤¹¡£
+ .RE
+@@ -1312,7 +1948,7 @@
+ .sp
+ ¸°¤ò½é¤á¤ÆºîÀ®¤¹¤ë¤È¡¢¼«¸Ê½ð̾¾ÚÌÀ½ñ¤È¤¤¤¦1¤Ä¤ÎÍ×ÁǤΤߤò´Þ¤à¥Á¥§¡¼¥ó¤¬³«»Ï¤µ¤ì¤Þ¤¹¡£¥³¥Þ¥ó¥É¤Î\fB\-genkeypair\fR¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ïȯ¹Ô¼Ô(½ð̾¼Ô)¤¬¼çÂΤÈƱ¤¸¤Ç¤¹¡£¼çÂΤϡ¢¤½¤Î¸ø³«¸°¤¬¾ÚÌÀ½ñ¤Ë¤è¤Ã¤Æǧ¾Ú¤µ¤ì¤ë¥¨¥ó¥Æ¥£¥Æ¥£¤Ç¤¹¡£\fB\-genkeypair\fR¥³¥Þ¥ó¥É¤ò¸Æ¤Ó½Ð¤·¤Æ¿·¤·¤¤¸ø³«¸°¤ÈÈëÌ©¸°¤Î¥Ú¥¢¤òºîÀ®¤¹¤ë¤È¡¢¸ø³«¸°¤Ï¾ï¤Ë¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ç¥é¥Ã¥×¤µ¤ì¤Þ¤¹¡£
+ .sp
+-¤³¤Î¸å¡¢¾ÚÌÀ½ñ½ð̾¥ê¥¯¥¨¥¹¥È(CSR)¤¬\fB\-certreq\fR¥³¥Þ¥ó¥É¤ÇÀ¸À®¤µ¤ì¤Æ¡¢CSR¤¬¾ÚÌÀ½ñȯ¹Ô¶É(CA)¤ËÁ÷¿®¤µ¤ì¤ë¤È¡¢CA¤«¤é¤Î¥ì¥¹¥Ý¥ó¥¹¤¬\fB\-importcert\fR¤Ç¥¤¥ó¥Ý¡¼¥È¤µ¤ì¡¢¸µ¤Î¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ï¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤Ë¤è¤Ã¤ÆÃÖ¤­´¹¤¨¤é¤ì¤Þ¤¹¡£\fB¤Î\fR\-certreq\fB¤ª¤è¤Ó\fR\-importcert¥³¥Þ¥ó¥É¥ª¥×¥·¥ç¥ó¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£¥Á¥§¡¼¥ó¤ÎºÇ¸å¤Ë¤¢¤ë¤Î¤Ï¡¢Subject¤Î¸ø³«¸°¤òǧ¾Ú¤·¤¿CA¤¬È¯¹Ô¤·¤¿¾ÚÌÀ½ñ(±þÅú)¤Ç¤¹¡£¥Á¥§¡¼¥óÆâ¤Î¤½¤ÎÁ°¤Î¾ÚÌÀ½ñ¤Ï¡¢CA¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤Ç¤¹¡£
++¤³¤Î¸å¡¢¾ÚÌÀ½ñ½ð̾¥ê¥¯¥¨¥¹¥È(CSR)¤¬\fB\-certreq\fR¥³¥Þ¥ó¥É¤ÇÀ¸À®¤µ¤ì¤Æ¡¢CSR¤¬Ç§¾Ú¶É(CA)¤ËÁ÷¿®¤µ¤ì¤ë¤È¡¢CA¤«¤é¤Î¥ì¥¹¥Ý¥ó¥¹¤¬\fB\-importcert\fR¤Ç¥¤¥ó¥Ý¡¼¥È¤µ¤ì¡¢¸µ¤Î¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ï¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤Ë¤è¤Ã¤ÆÃÖ¤­´¹¤¨¤é¤ì¤Þ¤¹¡£\fB¤Î\fR\-certreq\fB¤ª¤è¤Ó\fR\-importcert¥³¥Þ¥ó¥É¥ª¥×¥·¥ç¥ó¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£¥Á¥§¡¼¥ó¤ÎºÇ¸å¤Ë¤¢¤ë¤Î¤Ï¡¢Subject¤Î¸ø³«¸°¤òǧ¾Ú¤·¤¿CA¤¬È¯¹Ô¤·¤¿¾ÚÌÀ½ñ(±þÅú)¤Ç¤¹¡£¥Á¥§¡¼¥óÆâ¤Î¤½¤ÎÁ°¤Î¾ÚÌÀ½ñ¤Ï¡¢CA¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤Ç¤¹¡£
+ .sp
+ CA¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤Ï¡¢Â¿¤¯¤Î¾ì¹ç¡¢¼«¸Ê½ð̾¾ÚÌÀ½ñ(¤Ä¤Þ¤êCA¤¬¼«¿È¤Î¸ø³«¸°¤òǧ¾Ú¤·¤¿¾ÚÌÀ½ñ)¤Ç¤¢¤ê¡¢¤³¤ì¤Ï¥Á¥§¡¼¥ó¤ÎºÇ½é¤Î¾ÚÌÀ½ñ¤Ë¤Ê¤ê¤Þ¤¹¡£¾ì¹ç¤Ë¤è¤Ã¤Æ¤Ï¡¢CA¤¬¾ÚÌÀ½ñ¤Î¥Á¥§¡¼¥ó¤òÊÖ¤¹¤³¤È¤â¤¢¤ê¤Þ¤¹¡£¤³¤Î¾ì¹ç¡¢¥Á¥§¡¼¥óÆâ¤ÎºÇ¸å¤Î¾ÚÌÀ½ñ(CA¤Ë¤è¤Ã¤Æ½ð̾¤µ¤ì¡¢¸°¥¨¥ó¥È¥ê¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ)¤ËÊѤï¤ê¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¡¢¥Á¥§¡¼¥óÆâ¤Î¤½¤ÎÁ°¤Î¾ÚÌÀ½ñ¤Ï¡¢CSR¤ÎÁ÷¿®Àè¤ÎCA¤È¤ÏÊ̤ÎCA¤Ë¤è¤Ã¤Æ½ð̾¤µ¤ì¡¢CSR¤ÎÁ÷¿®Àè¤ÎCA¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤Ë¤Ê¤ê¤Þ¤¹¡£¥Á¥§¡¼¥óÆâ¤Î¤½¤ÎÁ°¤Î¾ÚÌÀ½ñ¤Ï¡¢¼¡¤ÎCA¤Î¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤Ë¤Ê¤ê¤Þ¤¹¡£°Ê²¼Æ±Íͤˡ¢¼«¸Ê½ð̾¤µ¤ì¤¿¡Ö¥ë¡¼¥È¡×¾ÚÌÀ½ñ¤Ë㤹¤ë¤Þ¤Ç¥Á¥§¡¼¥ó¤¬Â³¤­¤Þ¤¹¡£¤·¤¿¤¬¤Ã¤Æ¡¢¥Á¥§¡¼¥óÆâ¤Î(ºÇ½é¤Î¾ÚÌÀ½ñ°Ê¸å¤Î)³Æ¾ÚÌÀ½ñ¤Ç¤Ï¡¢¥Á¥§¡¼¥óÆâ¤Î¼¡¤Î¾ÚÌÀ½ñ¤Î½ð̾¼Ô¤Î¸ø³«¸°¤¬Ç§¾Ú¤µ¤ì¤Æ¤¤¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£
+ .sp
+@@ -1399,7 +2035,7 @@
+ .if n \{\
+ .RE
+ .\}
+-¥¤¥¿¥ê¥Ã¥¯ÂΤιàÌܤϡ¢¼ÂºÝ¤Ë»ØÄꤹ¤ëÃͤòɽ¤·¤Þ¤¹¡£Ã»½Ì·Á¤Î¥­¡¼¥ï¡¼¥É¤Î°ÕÌ£¤Ï¡¢¼¡¤Î¤È¤ª¤ê¤Ç¤¹¡£
++¥¤¥¿¥ê¥Ã¥¯¤Î¹àÌܤϡ¢¼ÂºÝ¤Ë»ØÄꤹ¤ëÃͤòɽ¤·¤Þ¤¹¡£Ã»½Ì·Á¤Î¥­¡¼¥ï¡¼¥É¤Î°ÕÌ£¤Ï¡¢¼¡¤Î¤È¤ª¤ê¤Ç¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+@@ -1527,7 +2163,7 @@
+ ¾ÚÌÀ½ñ¤ò¥¤¥ó¥Ý¡¼¥È¤¹¤ëÁ°¤Ë\fB\-printcert\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£¥­¡¼¥¹¥È¥¢Æâ¤Î¿®Íê¤Ç¤­¤ë¾ÚÌÀ½ñ¤Î¥ê¥¹¥È¤Ë¾ÚÌÀ½ñ¤òÄɲ乤ëÁ°¤Ë¡¢\fB\-importcert\fR¥³¥Þ¥ó¥É¤Ë¤è¤Ã¤Æ¾ÚÌÀ½ñ¤Î¾ðÊó¤¬É½¼¨¤µ¤ì¡¢³Îǧ¤òµá¤á¤ë¥á¥Ã¥»¡¼¥¸¤¬É½¼¨¤µ¤ì¤ë¤¿¤á¤Ç¤¹¡£¥æ¡¼¥¶¡¼¤Ï¥¤¥ó¥Ý¡¼¥ÈÁàºî¤òÄä»ß¤Ç¤­¤Þ¤¹¡£¤¿¤À¤·¡¢¤³¤ì¤ò¼Â¹Ô¤Ç¤­¤ë¤Î¤Ï¡¢\fB\-noprompt\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤻ¤º¤Ë\fB\-importcert\fR¥³¥Þ¥ó¥É¤ò¸Æ¤Ó½Ð¤¹¾ì¹ç¤Î¤ß¤Ç¤¹¡£\fB\-noprompt\fR¥ª¥×¥·¥ç¥ó¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥æ¡¼¥¶¡¼¤È¤ÎÂÐÏäϹԤï¤ì¤Þ¤»¤ó¡£
+ .SS "¥Ñ¥¹¥ï¡¼¥É·Ù¹ð"
+ .PP
+-¥­¡¼¥¹¥È¥¢¤ËÂФ¹¤ëÁàºî¤ò¹Ô¤¦¤Û¤È¤ó¤É¤Î¥³¥Þ¥ó¥É¤Ç¤Ï¡¢¥¹¥È¥¢¤Î¥Ñ¥¹¥ï¡¼¥É¤¬É¬ÍפǤ¹¡£¤Þ¤¿¡¢°ìÉô¤Î¥³¥Þ¥ó¥É¤Ç¤Ï¡¢Èó¸ø³«/ÈëÌ©¸°¤Î¥Ñ¥¹¥ï¡¼¥É¤¬É¬Íפˤʤ뤳¤È¤¬¤¢¤ê¤Þ¤¹¡£¥Ñ¥¹¥ï¡¼¥É¤Ï¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄê¤Ç¤­¤Þ¤¹(\fB\-storepass\fR¥ª¥×¥·¥ç¥ó¤È\fB\-keypass\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍÑ)¡£¤¿¤À¤·¡¢¥Æ¥¹¥È¤òÌÜŪ¤È¤¹¤ë¾ì¹ç¡¢¤Þ¤¿¤Ï°ÂÁ´¤Ç¤¢¤ë¤³¤È¤¬¤ï¤«¤Ã¤Æ¤¤¤ë¥·¥¹¥Æ¥à¤Ç¼Â¹Ô¤¹¤ë¾ì¹ç°Ê³°¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤ä¥¹¥¯¥ê¥×¥È¤Ç¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄꤷ¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£É¬Íפʥѥ¹¥ï¡¼¥É¤Î¥ª¥×¥·¥ç¥ó¤ò¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£
++¥­¡¼¥¹¥È¥¢¤ËÂФ¹¤ëÁàºî¤ò¹Ô¤¦¤Û¤È¤ó¤É¤Î¥³¥Þ¥ó¥É¤Ç¤Ï¡¢¥¹¥È¥¢¤Î¥Ñ¥¹¥ï¡¼¥É¤¬É¬ÍפǤ¹¡£¤Þ¤¿¡¢°ìÉô¤Î¥³¥Þ¥ó¥É¤Ç¤Ï¡¢Èó¸ø³«/ÈëÌ©¸°¤Î¥Ñ¥¹¥ï¡¼¥É¤¬É¬Íפˤʤ뤳¤È¤¬¤¢¤ê¤Þ¤¹¡£¥Ñ¥¹¥ï¡¼¥É¤Ï¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄê¤Ç¤­¤Þ¤¹(\fB\-storepass\fR¥ª¥×¥·¥ç¥ó¤È\fB\-keypass\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍÑ)¡£¤¿¤À¤·¡¢¥Æ¥¹¥ÈÌÜŪ¤Î¾ì¹ç¡¢¤Þ¤¿¤Ï¥»¥­¥å¥¢¤Ê¥·¥¹¥Æ¥à¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç°Ê³°¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤ä¥¹¥¯¥ê¥×¥È¤Ç¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄꤷ¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£É¬Íפʥѥ¹¥ï¡¼¥É¤Î¥ª¥×¥·¥ç¥ó¤ò¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£
+ .SS "¾ÚÌÀ½ñ¤Î½àµò¤Ë´Ø¤¹¤ë·Ù¹ð"
+ .PP
+ ¥¤¥ó¥¿¡¼¥Í¥Ã¥Èɸ½àRFC 5280¤Ç¤Ï¡¢X\&.509¾ÚÌÀ½ñ¤Î½àµò¤Ë´Ø¤¹¤ë¥×¥í¥Õ¥¡¥¤¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤ª¤ê¡¢¾ÚÌÀ½ñ¤Î¥Õ¥£¡¼¥ë¥É¤ª¤è¤Ó¥¨¥¯¥¹¥Æ¥ó¥·¥ç¥ó¤ËÍ­¸ú¤ÊÃͤª¤è¤ÓÃͤÎÁȹ礻¤¬µ­ºÜ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£É¸½à¤Ë¤Ä¤¤¤Æ¤Ï¡¢
+--- ./jdk/src/linux/doc/man/ja/native2ascii.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/native2ascii.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¹ñºÝ²½¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "native2ascii" "1" "2013ǯ11·î21Æü" "JDK 8" "¹ñºÝ²½¥Ä¡¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/orbd.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/orbd.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "orbd" "1" "2013ǯ11·î21Æü" "JDK 8" "Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë"
+@@ -117,7 +118,7 @@
+ .PP
+ \-serverPollingTime \fImilliseconds\fR
+ .RS 4
+-\fBservertool\fR¤ò»ÈÍѤ·¤ÆÅÐÏ¿¤µ¤ì¤¿±Ê³¥µ¡¼¥Ð¡¼¤Î¥Ø¥ë¥¹¾õÂÖ¤òORBD¤¬¥Á¥§¥Ã¥¯¤¹¤ë´Ö³Ö¤ò»ØÄꤷ¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤÏ1000¥ß¥êÉäǤ¹¡£\fBmilliseconds\fR¤Ë»ØÄꤹ¤ëÃͤϡ¢Í­¸ú¤ÊÀµ¤ÎÀ°¿ô¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
++\fBservertool\fR¤ò»ÈÍѤ·¤ÆÅÐÏ¿¤µ¤ì¤¿±Ê³¥µ¡¼¥Ð¡¼¤¬Àµ¾ï¤ËÆ°ºî¤·¤Æ¤¤¤ë¤³¤È¤òORBD¤¬³Îǧ¤¹¤ë´Ö³Ö¤ò»ØÄꤷ¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤÏ1000¥ß¥êÉäǤ¹¡£\fBmilliseconds\fR¤Ë»ØÄꤹ¤ëÃͤϡ¢Í­¸ú¤ÊÀµ¤ÎÀ°¿ô¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .PP
+ \-serverStartupDelay milliseconds
+--- ./jdk/src/linux/doc/man/ja/pack200.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/pack200.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java¥Ç¥×¥í¥¤¥á¥ó¥È¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "pack200" "1" "2013ǯ11·î21Æü" "JDK 8" "Java¥Ç¥×¥í¥¤¥á¥ó¥È¡¦¥Ä¡¼¥ë"
+@@ -160,7 +161,7 @@
+ \-\-segment\-limit=\fIvalue\fR
+ .RS 4
+ ¤³¤ÎÃͤϡ¢³Æ¥¢¡¼¥«¥¤¥Ö¡¦¥»¥°¥á¥ó¥È¤ÎͽÁÛ¥¿¡¼¥²¥Ã¥È¡¦¥µ¥¤¥º\fIN\fR
+-(¥Ð¥¤¥Èñ°Ì)¤Ç¤¹¡£Ã±°ì¤ÎÆþÎÏ¥Õ¥¡¥¤¥ë¤ÎɬÍ×¥µ¥¤¥º¤¬\fIN\fR¥Ð¥¤¥È¤òĶ¤¨¤ë¤È¡¢ÆÈΩ¤·¤¿¥»¥°¥á¥ó¥È¤¬³ä¤êÅö¤Æ¤é¤ì¤Þ¤¹¡£Æüì¤Ê¥±¡¼¥¹¤È¤·¤Æ¡¢Ãͤ¬\fB\-1\fR¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤ÎÆþÎÏ¥Õ¥¡¥¤¥ë¤ò´Þ¤àÂ礭¤Êñ°ì¤Î¥»¥°¥á¥ó¥È¤¬À¸À®¤µ¤ì¡¢Ãͤ¬0¤Î¾ì¹ç¤Ï¡¢¥¯¥é¥¹¤´¤È¤Ë¥»¥°¥á¥ó¥È¤¬1¤Ä¤º¤ÄÀ¸À®¤µ¤ì¤Þ¤¹¡£¥¢¡¼¥«¥¤¥Ö¡¦¥»¥°¥á¥ó¥È¤¬Â礭¤¯¤Ê¤ë¤È¡¢ÃÇÊÒ²½¤¬¾¯¤Ê¤¯¤Ê¤ê°µ½ÌΨ¤¬¹â¤¯¤Ê¤ê¤Þ¤¹¤¬¡¢¤½¤Î½èÍý¤Ë¤Ï¿¤¯¤Î¥á¥â¥ê¡¼¤¬É¬ÍפǤ¹¡£
++(¥Ð¥¤¥Èñ°Ì)¤Ç¤¹¡£Ã±°ì¤ÎÆþÎÏ¥Õ¥¡¥¤¥ë¤ÎɬÍ×¥µ¥¤¥º¤¬\fIN\fR¥Ð¥¤¥È¤òĶ¤¨¤ë¤È¡¢¸ÇÍ­¤Î¥¢¡¼¥«¥¤¥Ö¡¦¥»¥°¥á¥ó¥È¤¬Ä󶡤µ¤ì¤Þ¤¹¡£Æüì¤Ê¥±¡¼¥¹¤È¤·¤Æ¡¢Ãͤ¬\fB\-1\fR¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤ÎÆþÎÏ¥Õ¥¡¥¤¥ë¤ò´Þ¤àÂ礭¤Êñ°ì¤Î¥»¥°¥á¥ó¥È¤¬À¸À®¤µ¤ì¡¢Ãͤ¬0¤Î¾ì¹ç¤Ï¡¢¥¯¥é¥¹¤´¤È¤Ë¥»¥°¥á¥ó¥È¤¬1¤Ä¤º¤ÄÀ¸À®¤µ¤ì¤Þ¤¹¡£¥¢¡¼¥«¥¤¥Ö¡¦¥»¥°¥á¥ó¥È¤¬Â礭¤¯¤Ê¤ë¤È¡¢ÃÇÊÒ²½¤¬¾¯¤Ê¤¯¤Ê¤ê°µ½ÌΨ¤¬¹â¤¯¤Ê¤ê¤Þ¤¹¤¬¡¢¤½¤Î½èÍý¤Ë¤Ï¿¤¯¤Î¥á¥â¥ê¡¼¤¬É¬ÍפǤ¹¡£
+ .sp
+ ³Æ¥»¥°¥á¥ó¥È¤Î¥µ¥¤¥º¤Ï¡¢¥»¥°¥á¥ó¥È¤ËÊÑ´¹¤µ¤ì¤ë¤½¤ì¤¾¤ì¤ÎÆþÎÏ¥Õ¥¡¥¤¥ë¤Î¥µ¥¤¥º¤Î¤Û¤«¡¢¤½¤Î̾Á°¤È¾¤ÎÁ÷¿®¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¤Î¥µ¥¤¥º¤ò·×»»¤·¤Æ¿ä¬¤µ¤ì¤Þ¤¹¡£
+ .sp
+--- ./jdk/src/linux/doc/man/ja/policytool.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/policytool.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: policytool
+ .\" Language: Japanese
+-.\" Date: 2013ǯ11·î21Æü
++.\" Date: 2015ǯ3·î3Æü
+ .\" SectDesc: ¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "policytool" "1" "2013ǯ11·î21Æü" "JDK 8" "¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë"
++.TH "policytool" "1" "2015ǯ3·î3Æü" "JDK 8" "¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -95,7 +96,7 @@
+ .RS 4
+ .\}
+ .nf
+-\fBpolicytool\-file mypolicyfile\fR
++\fBpolicytool \-file \fR\fB\fImypolicyfile\fR\fR
+
+ .fi
+ .if n \{\
+--- ./jdk/src/linux/doc/man/ja/rmic.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/rmic.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Remote Method Invocation (RMI)¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "rmic" "1" "2013ǯ11·î21Æü" "JDK 8" "Remote Method Invocation (RMI)"
+@@ -110,8 +111,8 @@
+ .PP
+ \-classpath path
+ .RS 4
+-\fBrmic\fR¥³¥Þ¥ó¥É¤¬¥¯¥é¥¹¤òõ¤¹¤¿¤á¤Î¥Ñ¥¹¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤ä\fBCLASSPATH\fR´Ä¶­ÊÑ¿ôÀßÄê¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Þ¤¹¡£¥Ç¥£¥ì¥¯¥È¥ê¤Ï¥³¥í¥ó¤Çʬ³ä¤·¤Þ¤¹¡£¥Ñ¥¹¤Î°ìÈÌŪ¤Ê·Á¼°¤Ï\fB\&.;<your_path>\fR¤Ç¤¹¡£Îã:
+-\fB\&.;/usr/local/java/classes\fR
++\fBrmic\fR¥³¥Þ¥ó¥É¤¬¥¯¥é¥¹¤òõ¤¹¤¿¤á¤Î¥Ñ¥¹¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤ä\fBCLASSPATH\fR´Ä¶­ÊÑ¿ôÀßÄê¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Þ¤¹¡£¥Ç¥£¥ì¥¯¥È¥ê¤Ï¥³¥í¥ó¤Çʬ³ä¤·¤Þ¤¹¡£¥Ñ¥¹¤Î°ìÈÌŪ¤Ê·Á¼°¤Ï\fB\&.:<your_path>\fR¤Ç¤¹¡£Îã:
++\fB\&.:/usr/local/java/classes\fR
+ .RE
+ .PP
+ \-d \fIdirectory\fR
+@@ -350,7 +351,7 @@
+ .sp -1
+ .IP \(bu 2.3
+ .\}
+-Setting the Class Path
++¥¯¥é¥¹¡¦¥Ñ¥¹¤ÎÀßÄê
+ .RE
+ .br
+ 'pl 8.5i
+--- ./jdk/src/linux/doc/man/ja/rmid.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/rmid.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Remote Method Invocation (RMI)¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "rmid" "1" "2013ǯ11·î21Æü" "JDK 8" "Remote Method Invocation (RMI)"
+@@ -103,9 +104,7 @@
+ .\}
+ .SH "ɬÍפ˱þ¤¸¤ÆRMID¤ò³«»Ï"
+ .PP
+-\fBrmid\fR¤ò¥³¥Þ¥ó¥É¹Ô¤«¤é³«»Ï¤¹¤ë¤Ë¤Ï¡¢\fBinetd\fR
+-(Oracle Solaris¤Î¾ì¹ç)¡¢¤Þ¤¿¤Ï\fBxinetd\fR
+-(Linux¤Î¾ì¹ç)¤ò¹½À®¤·¤Æ\fBrmid\fR¤òɬÍפ˱þ¤¸¤Æ³«»Ï¤¹¤ëÊýË¡¤â¤¢¤ê¤Þ¤¹¡£
++\fBrmid\fR¤ò¥³¥Þ¥ó¥É¹Ô¤«¤é³«»Ï¤¹¤ë¤Ë¤Ï¡¢\fBinetd\fR(Oracle Solaris¤Î¾ì¹ç)¡¢¤Þ¤¿¤Ï\fBxinetd\fR(Linux¤Î¾ì¹ç)¤ò¹½À®¤·¤Æ\fBrmid\fR¤òɬÍפ˱þ¤¸¤Æ³«»Ï¤¹¤ëÊýË¡¤â¤¢¤ê¤Þ¤¹¡£
+ .PP
+ RMID¤ò³«»Ï¤¹¤ë¤È¡¢\fBSystem\&.inheritedChannel\fR¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð¤·¤Æ¡¢·Ñ¾µ¤µ¤ì¤¿¥Á¥ã¥ó¥Í¥ë(\fBinetd\fR/\fBxinetd\fR¤«¤é·Ñ¾µ)¤ò¼èÆÀ¤·¤è¤¦¤È¤·¤Þ¤¹¡£·Ñ¾µ¤µ¤ì¤¿¥Á¥ã¥ó¥Í¥ë¤¬null¤Ç¤¢¤ë¤«¡¢\fBjava\&.nio\&.channels\&.ServerSocketChannel\fR¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ç¤Ê¤«¤Ã¤¿¾ì¹ç¡¢RMID¤Ï¤½¤Î¥Á¥ã¥ó¥Í¥ë¤Ï\fBinetd\fR/\fBxinetd\fR¤Ë¤è¤Ã¤Æµ¯Æ°¤µ¤ì¤¿¤â¤Î¤Ç¤Ï¤Ê¤¤¤ÈȽÃǤ·¡¢Á°½Ò¤Î¤è¤¦¤Ëµ¯Æ°¤·¤Þ¤¹¡£
+ .PP
+@@ -368,7 +367,7 @@
+ .sp -1
+ .IP \(bu 2.3
+ .\}
+-Setting the Class Path
++¥¯¥é¥¹¡¦¥Ñ¥¹¤ÎÀßÄê
+ .RE
+ .br
+ 'pl 8.5i
+--- ./jdk/src/linux/doc/man/ja/rmiregistry.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/rmiregistry.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Remote Method Invocation (RMI)¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "rmiregistry" "1" "2013ǯ11·î21Æü" "JDK 8" "Remote Method Invocation (RMI)"
+--- ./jdk/src/linux/doc/man/ja/schemagen.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/schemagen.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "schemagen" "1" "2013ǯ11·î21Æü" "JDK 8" "Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/serialver.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/serialver.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Remote Method Invocation (RMI)¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "serialver" "1" "2013ǯ11·î21Æü" "JDK 8" "Remote Method Invocation (RMI)"
+--- ./jdk/src/linux/doc/man/ja/servertool.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/servertool.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "servertool" "1" "2013ǯ11·î21Æü" "JDK 8" "Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/tnameserv.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/tnameserv.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "tnameserv" "1" "2013ǯ11·î21Æü" "JDK 8" "Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë"
+@@ -189,7 +190,7 @@
+ .SH "Îã"
+ .SS "¥Í¡¼¥à¥¹¥Ú¡¼¥¹¤Ø¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ÎÄɲÃ"
+ .PP
+-¼¡¤ÎÎã¤Ç¤Ï¡¢¥Í¡¼¥à¥¹¥Ú¡¼¥¹¤Ë̾Á°¤òÄɲ乤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£¤³¤Î¥µ¥ó¥×¥ë¡¦¥×¥í¥°¥é¥à¤Ï¡¢¤³¤Î¤Þ¤Þ¤Î¾õÂ֤Ǵ°Á´¤ËÆ°ºî¤¹¤ë°ì»þ¥Í¡¼¥à¡¦¥µ¡¼¥Ó¥¹¡¦¥¯¥é¥¤¥¢¥ó¥È¤Ç¡¢¼¡¤Î¤è¤¦¤Êñ½ã¤Ê¥Ä¥ê¡¼¤òºîÀ®¤¹¤ë¤â¤Î¤Ç¤¹¡£
++¼¡¤ÎÎã¤Ç¤Ï¡¢¥Í¡¼¥à¥¹¥Ú¡¼¥¹¤Ë̾Á°¤òÄɲ乤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£¤³¤Î¥µ¥ó¥×¥ë¡¦¥×¥í¥°¥é¥à¤Ï¡¢¼«¸Ê´°·ë·¿¤Î°ì»þ¥Í¡¼¥à¡¦¥µ¡¼¥Ó¥¹¡¦¥¯¥é¥¤¥¢¥ó¥È¤Ç¡¢¼¡¤Î¤è¤¦¤Êñ½ã¤Ê¥Ä¥ê¡¼¤òºîÀ®¤¹¤ë¤â¤Î¤Ç¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+--- ./jdk/src/linux/doc/man/ja/unpack200.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/unpack200.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java¥Ç¥×¥í¥¤¥á¥ó¥È¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "unpack200" "1" "2013ǯ11·î21Æü" "JDK 8" "Java¥Ç¥×¥í¥¤¥á¥ó¥È¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/wsgen.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/wsgen.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "wsgen" "1" "2013ǯ11·î21Æü" "JDK 8" "Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/wsimport.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/wsimport.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "wsimport" "1" "2013ǯ11·î21Æü" "JDK 8" "Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/linux/doc/man/ja/xjc.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/ja/xjc.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "xjc" "1" "2013ǯ11·î21Æü" "JDK 8" "Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë"
+@@ -129,7 +130,7 @@
+ .PP
+ \-p \fIpkg\fR
+ .RS 4
+-¤³¤Î¥³¥Þ¥ó¥É¹Ô¥ª¥×¥·¥ç¥ó¤Ç¥¿¡¼¥²¥Ã¥È¡¦¥Ñ¥Ã¥±¡¼¥¸¤ò»ØÄꤷ¤¿¾ì¹ç¡¢¥Ñ¥Ã¥±¡¼¥¸Ì¾¤ËÂФ¹¤ë¤¹¤Ù¤Æ¤Î¥Ð¥¤¥ó¥Ç¥£¥ó¥°¡¦¥«¥¹¥¿¥Þ¥¤¥º¤ä¡¢»ÅÍͤǵ¬Äꤵ¤ì¤Æ¤¤¤ë¥Ç¥Õ¥©¥ë¥È¤Î¥Ñ¥Ã¥±¡¼¥¸Ì¾¥¢¥ë¥´¥ê¥º¥à¤è¤ê¤âÍ¥À褵¤ì¤Þ¤¹¡£
++¤³¤Î¥³¥Þ¥ó¥É¹Ô¥ª¥×¥·¥ç¥ó¤Ç¥¿¡¼¥²¥Ã¥È¡¦¥Ñ¥Ã¥±¡¼¥¸¤ò»ØÄꤷ¤¿¾ì¹ç¡¢¤½¤Î»ØÄêÆâÍƤϡ¢¥Ñ¥Ã¥±¡¼¥¸Ì¾¤ËÂФ¹¤ë¤¹¤Ù¤Æ¤Î¥Ð¥¤¥ó¥Ç¥£¥ó¥°¡¦¥«¥¹¥¿¥Þ¥¤¥º¤ä¡¢»ÅÍͤǵ¬Äꤵ¤ì¤Æ¤¤¤ë¥Ç¥Õ¥©¥ë¥È¤Î¥Ñ¥Ã¥±¡¼¥¸Ì¾¥¢¥ë¥´¥ê¥º¥à¤è¤ê¤âÍ¥À褵¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ \-httpproxy \fIproxy\fR
+--- ./jdk/src/linux/doc/man/java.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/java.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ '\" t
+-.\" Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
++.\" Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
+ .\"
+ .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ .\"
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: java
+ .\" Language: English
+-.\" Date: 08 August 2014
++.\" Date: 03 March 2015
+ .\" SectDesc: Basic Tools
+ .\" Software: JDK 8
+ .\" Arch: generic
+-.\" Part Number: E38207-03
++.\" Part Number: E38207-04
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "java" "1" "08 August 2014" "JDK 8" "Basic Tools"
++.TH "java" "1" "03 March 2015" "JDK 8" "Basic Tools"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -333,7 +334,6 @@
+ Selects the Java HotSpot Client VM\&. The 64\-bit version of the Java SE Development Kit (JDK) currently ignores this option and instead uses the Server JVM\&.
+ .sp
+ For default JVM selection, see Server\-Class Machine Detection at
+-
+ http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/server\-class\&.html
+ .RE
+ .PP
+@@ -550,7 +550,6 @@
+ Selects the Java HotSpot Server VM\&. The 64\-bit version of the JDK supports only the Server VM, so in that case the option is implicit\&.
+ .sp
+ For default JVM selection, see Server\-Class Machine Detection at
+-
+ http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/server\-class\&.html
+ .RE
+ .PP
+@@ -772,13 +771,14 @@
+ \fBg\fR
+ or
+ \fBG\fR
+-to indicate gigabytes\&. By default, the value is set to 48 MB:
++to indicate gigabytes\&. The default maximum code cache size is 240 MB; if you disable tiered compilation with the option
++\fB\-XX:\-TieredCompilation\fR, then the default size is 48 MB:
+ .sp
+ .if n \{\
+ .RS 4
+ .\}
+ .nf
+-\fB\-Xmaxjitcodesize=48m\fR
++\fB\-Xmaxjitcodesize=240m\fR
+
+ .fi
+ .if n \{\
+@@ -889,7 +889,9 @@
+ \fB\-Xms\fR
+ and
+ \fB\-Xmx\fR
+-are often set to the same value\&. For more information, see Garbage Collector Ergonomics at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gc\-ergonomics\&.html
++are often set to the same value\&. See the section "Ergonomics" in
++\fIJava SE HotSpot Virtual Machine Garbage Collection Tuning Guide\fR
++at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gctuning/index\&.html\&.
+ .sp
+ The following examples show how to set the maximum allowed size of allocated memory to 80 MB using various units:
+ .sp
+@@ -986,28 +988,30 @@
+ .PP
+ \-Xshare:\fImode\fR
+ .RS 4
+-Sets the class data sharing mode\&. Possible
++Sets the class data sharing (CDS) mode\&. Possible
+ \fImode\fR
+ arguments for this option include the following:
+ .PP
+ auto
+ .RS 4
+-Use shared class data if possible\&. This is the default value for Java HotSpot 32\-Bit Client VM\&.
++Use CDS if possible\&. This is the default value for Java HotSpot 32\-Bit Client VM\&.
+ .RE
+ .PP
+ on
+ .RS 4
+-Require the use of class data sharing\&. Print an error message and exit if class data sharing cannot be used\&.
++Require the use of CDS\&. Print an error message and exit if class data sharing cannot be used\&.
+ .RE
+ .PP
+ off
+ .RS 4
+-Do not use shared class data\&. This is the default value for Java HotSpot 32\-Bit Server VM, Java HotSpot 64\-Bit Client VM, and Java HotSpot 64\-Bit Server VM\&.
++Do not use CDS\&. This is the default value for Java HotSpot 32\-Bit Server VM, Java HotSpot 64\-Bit Client VM, and Java HotSpot 64\-Bit Server VM\&.
+ .RE
+ .PP
+ dump
+ .RS 4
+-Manually generate the class data sharing archive\&.
++Manually generate the CDS archive\&. Specify the application class path as described in "Setting the Class Path "\&.
++.sp
++You should regenerate the CDS archive with each new JDK release\&.
+ .RE
+ .RE
+ .PP
+@@ -1120,17 +1124,6 @@
+ Oracle Solaris/x64 (64\-bit): 1024 KB
+ .RE
+ .sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-Windows: depends on virtual memory
+-.RE
+-.sp
+ The following examples set the thread stack size to 1024 KB in different units:
+ .sp
+ .if n \{\
+@@ -1172,7 +1165,7 @@
+ .PP
+ remote
+ .RS 4
+-Verify only those classes that are loaded remotely over the network\&. This is the default behavior if you do not specify the
++Verify those classes that are not loaded by the bootstrap class loader\&. This is the default behavior if you do not specify the
+ \fB\-Xverify\fR
+ option\&.
+ .RE
+@@ -1186,6 +1179,65 @@
+ .PP
+ These options control the runtime behavior of the Java HotSpot VM\&.
+ .PP
++\-XX:+CheckEndorsedAndExtDirs
++.RS 4
++Enables the option to prevent the
++\fBjava\fR
++command from running a Java application if it uses the endorsed\-standards override mechanism or the extension mechanism\&. This option checks if an application is using one of these mechanisms by checking the following:
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++The
++\fBjava\&.ext\&.dirs\fR
++or
++\fBjava\&.endorsed\&.dirs\fR
++system property is set\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++The
++\fBlib/endorsed\fR
++directory exists and is not empty\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++The
++\fBlib/ext\fR
++directory contains any JAR files other than those of the JDK\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++The system\-wide platform\-specific extension directory contains any JAR files\&.
++.RE
++.RE
++.PP
+ \-XX:+DisableAttachMechanism
+ .RS 4
+ Enables the option that disables the mechanism that lets tools attach to the JVM\&. By default, this option is disabled, meaning that the attach mechanism is enabled and you can use tools such as
+@@ -1238,7 +1290,7 @@
+ .PP
+ \-XX:LargePageSizeInBytes=\fIsize\fR
+ .RS 4
+-Sets the maximum size (in bytes) for large pages used for Java heap\&. The
++On Solaris, sets the maximum size (in bytes) for large pages used for Java heap\&. The
+ \fIsize\fR
+ argument must be a power of 2 (2, 4, 8, 16, \&.\&.\&.)\&. Append the letter
+ \fBk\fR
+@@ -1327,6 +1379,17 @@
+ .RE
+ .RE
+ .PP
++\-XX:ObjectAlignmentInBytes=\fIalignment\fR
++.RS 4
++Sets the memory alignment of Java objects (in bytes)\&. By default, the value is set to 8 bytes\&. The specified value should be a power of two, and must be within the range of 8 and 256 (inclusive)\&. This option makes it possible to use compressed pointers with large Java heap sizes\&.
++.sp
++The heap size limit in bytes is calculated as:
++.sp
++\fB4GB * ObjectAlignmentInBytes\fR
++.sp
++Note: As the alignment value increases, the unused space between objects will also increase\&. As a result, you may not realize any benefits from using compressed pointers with large Java heap sizes\&.
++.RE
++.PP
+ \-XX:OnError=\fIstring\fR
+ .RS 4
+ Sets a custom command or a series of semicolon\-separated commands to run when an irrecoverable error occurs\&. If the string contains spaces, then it must be enclosed in quotation marks\&.
+@@ -1360,6 +1423,28 @@
+ option\&.
+ .RE
+ .PP
++\-XX:+PerfDataSaveToFile
++.RS 4
++If enabled, saves
++jstat(1) binary data when the Java application exits\&. This binary data is saved in a file named
++\fBhsperfdata_\fR\fI<pid>\fR, where
++\fI<pid>\fR
++is the process identifier of the Java application you ran\&. Use
++\fBjstat\fR
++to display the performance data contained in this file as follows:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjstat \-class file:///\fR\fB\fI<path>\fR\fR\fB/hsperfdata_\fR\fB\fI<pid>\fR\fR
++\fBjstat \-gc file:///\fR\fB\fI<path>\fR\fR\fB/hsperfdata_\fR\fB\fI<pid>\fR\fR
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.PP
+ \-XX:+PrintCommandLineFlags
+ .RS 4
+ Enables printing of ergonomically selected JVM flags that appeared on the command line\&. It can be useful to know the ergonomic values set by the JVM, such as the heap space size and the selected garbage collector\&. By default, this option is disabled and flags are not printed\&.
+@@ -1463,17 +1548,6 @@
+ Oracle Solaris/x64 (64\-bit): 1024 KB
+ .RE
+ .sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-Windows: depends on virtual memory
+-.RE
+-.sp
+ The following examples show how to set the thread stack size to 1024 KB in different units:
+ .sp
+ .if n \{\
+@@ -1537,13 +1611,27 @@
+ \-XX:\-UseCompressedOops
+ .RS 4
+ Disables the use of compressed pointers\&. By default, this option is enabled, and compressed pointers are used when Java heap sizes are less than 32 GB\&. When this option is enabled, object references are represented as 32\-bit offsets instead of 64\-bit pointers, which typically increases performance when running the application with Java heap sizes less than 32 GB\&. This option works only for 64\-bit JVMs\&.
++.sp
++It is also possible to use compressed pointers when Java heap sizes are greater than 32GB\&. See the
++\fB\-XX:ObjectAlignmentInBytes\fR
++option\&.
+ .RE
+ .PP
+-\-XX:\-UseLargePages
+-.RS 4
+-Disables the use of large page memory\&. This option is enabled by default\&.
++\-XX:+UseHugeTLBFS
++.RS 4
++This option for Linux is the equivalent of specifying
++\fB\-XX:+UseLargePages\fR\&. This option is disabled by default\&. This option pre\-allocates all large pages up\-front, when memory is reserved; consequently the JVM cannot dynamically grow or shrink large pages memory areas; see
++\fB\-XX:UseTransparentHugePages\fR
++if you want this behavior\&.
+ .sp
+-For more information, see Java Support for Large Memory Pages at http://www\&.oracle\&.com/technetwork/java/javase/tech/largememory\-jsp\-137182\&.html
++For more information, see "Large Pages"\&.
++.RE
++.PP
++\-XX:+UseLargePages
++.RS 4
++Enables the use of large page memory\&. By default, this option is disabled and large page memory is not used\&.
++.sp
++For more information, see "Large Pages"\&.
+ .RE
+ .PP
+ \-XX:+UseMembar
+@@ -1563,6 +1651,13 @@
+ \fB\-XX:\-UsePerfData\fR\&.
+ .RE
+ .PP
++\-XX:+UseTransparentHugePages
++.RS 4
++On Linux, enables the use of large pages that can dynamically grow or shrink\&. This option is disabled by default\&. You may encounter performance problems with transparent huge pages as the OS moves other pages around to create huge pages; this option is made available for experimentation\&.
++.sp
++For more information, see "Large Pages"\&.
++.RE
++.PP
+ \-XX:+AllowUserSignalHandlers
+ .RS 4
+ Enables installation of signal handlers by the application\&. By default, this option is disabled and the application is not allowed to install signal handlers\&.
+@@ -2041,7 +2136,8 @@
+ .PP
+ \-XX:CompileThreshold=\fIinvocations\fR
+ .RS 4
+-Sets the number of interpreted method invocations before compilation\&. By default, in the server JVM, the JIT compiler performs 10,000 interpreted method invocations to gather information for efficient compilation\&. For the client JVM, the default setting is 1,500 invocations\&. The following example shows how to set the number of interpreted method invocations to 5,000:
++Sets the number of interpreted method invocations before compilation\&. By default, in the server JVM, the JIT compiler performs 10,000 interpreted method invocations to gather information for efficient compilation\&. For the client JVM, the default setting is 1,500 invocations\&. This option is ignored when tiered compilation is enabled; see the option
++\fB\-XX:+TieredCompilation\fR\&. The following example shows how to set the number of interpreted method invocations to 5,000:
+ .sp
+ .if n \{\
+ .RS 4
+@@ -2078,7 +2174,7 @@
+ \fBg\fR
+ or
+ \fBG\fR
+-to indicate gigabytes\&. The default value is set to 500 KB\&. The following example shows how to set the initial code cache size to 32 KB:
++to indicate gigabytes\&. The default value is set to 500 KB\&. The initial code cache size should be not less than the system\*(Aqs minimal memory page size\&. The following example shows how to set the initial code cache size to 32 KB:
+ .sp
+ .if n \{\
+ .RS 4
+@@ -2274,13 +2370,29 @@
+ \fBg\fR
+ or
+ \fBG\fR
+-to indicate gigabytes\&. This option is equivalent to
++to indicate gigabytes\&. The default maximum code cache size is 240 MB; if you disable tiered compilation with the option
++\fB\-XX:\-TieredCompilation\fR, then the default size is 48 MB\&. This option has a limit of 2 GB; otherwise, an error is generated\&. The maximum code cache size should not be less than the initial code cache size; see the option
++\fB\-XX:InitialCodeCacheSize\fR\&. This option is equivalent to
+ \fB\-Xmaxjitcodesize\fR\&.
+ .RE
+ .PP
+-\-XX:+TieredCompilation
+-.RS 4
+-Enables the use of tiered compilation\&. By default, this option is enabled\&. Only the Java HotSpot Server VM supports this option\&.
++\-XX:RTMAbortRatio=\fIabort_ratio\fR
++.RS 4
++The RTM abort ratio is specified as a percentage (%) of all executed RTM transactions\&. If a number of aborted transactions becomes greater than this ratio, then the compiled code will be deoptimized\&. This ratio is used when the
++\fB\-XX:+UseRTMDeopt\fR
++option is enabled\&. The default value of this option is 50\&. This means that the compiled code will be deoptimized if 50% of all transactions are aborted\&.
++.RE
++.PP
++\-XX:RTMRetryCount=\fInumber_of_retries\fR
++.RS 4
++RTM locking code will be retried, when it is aborted or busy, the number of times specified by this option before falling back to the normal locking mechanism\&. The default value for this option is 5\&. The
++\fB\-XX:UseRTMLocking\fR
++option must be enabled\&.
++.RE
++.PP
++\-XX:\-TieredCompilation
++.RS 4
++Disables the use of tiered compilation\&. By default, this option is enabled\&. Only the Java HotSpot Server VM supports this option\&.
+ .RE
+ .PP
+ \-XX:+UseAES
+@@ -2319,45 +2431,20 @@
+ Enables checking of whether the card is already marked before updating the card table\&. This option is disabled by default and should only be used on machines with multiple sockets, where it will increase performance of Java applications that rely heavily on concurrent operations\&. Only the Java HotSpot Server VM supports this option\&.
+ .RE
+ .PP
+-\-XX:+UseSuperWord
+-.RS 4
+-Enables the transformation of scalar operations into superword operations\&. This option is enabled by default\&. To disable the transformation of scalar operations into superword operations, specify
+-\fB\-XX:\-UseSuperWord\fR\&. Only the Java HotSpot Server VM supports this option\&.
+-.RE
+-.SS "Experimental JIT Compiler Options"
+-.PP
+-The options related to the Restricted Transactional Memory (RTM) locking feature in this section are experimental and are not officially supported in Java SE 8u20; you must enable the
+-\fB\-XX:+UnlockExperimentalVMOptions\fR
+-option to use them\&. These options are only available for the Java HotSpot Server VM on x86 CPUs that support Transactional Synchronization Extensions (TSX)\&.
+-.PP
+-\-XX:RTMAbortRatio=\fIabort_ratio\fR
+-.RS 4
+-The RTM abort ratio is specified as a percentage (%) of all executed RTM transactions\&. If a number of aborted transactions becomes greater than this ratio, then the compiled code will be deoptimized\&. This ratio is used when the
+-\fB\-XX:+UseRTMDeopt\fR
+-option is enabled\&. The default value of this option is 50\&. This means that the compiled code will be deoptimized if 50% of all transactions are aborted\&.
+-.RE
+-.PP
+-\-XX:RTMRetryCount=\fInumber_of_retries\fR
+-.RS 4
+-RTM locking code will be retried, when it is aborted or busy, the number of times specified by this option before falling back to the normal locking mechanism\&. The default value for this option is 5\&. The
+-\fB\-XX:UseRTMLocking\fR
+-option must be enabled\&.
+-.RE
+-.PP
+ \-XX:+UseRTMDeopt
+ .RS 4
+ Auto\-tunes RTM locking depending on the abort ratio\&. This ratio is specified by
+ \fB\-XX:RTMAbortRatio\fR
+ option\&. If the number of aborted transactions exceeds the abort ratio, then the method containing the lock will be deoptimized and recompiled with all locks as normal locks\&. This option is disabled by default\&. The
+-\fB\-XX:UseRTMLocking\fR
++\fB\-XX:+UseRTMLocking\fR
+ option must be enabled\&.
+ .RE
+ .PP
+ \-XX:+UseRTMLocking
+ .RS 4
+-Generate Restricted Transactional Memory (RTM) locking code for all inflated locks, with the normal locking mechanism as the fallback handler\&. This option is disabled by default\&.
++Generate Restricted Transactional Memory (RTM) locking code for all inflated locks, with the normal locking mechanism as the fallback handler\&. This option is disabled by default\&. Options related to RTM are only available for the Java HotSpot Server VM on x86 CPUs that support Transactional Synchronization Extensions (TSX)\&.
+ .sp
+-RTM is part of Intel\*(Aqs Transactional Synchronization Extensions (TSX), which is an x86 instruction set extension and facilitates the creation of multithreaded applications\&. RTM introduces the new instructions
++RTM is part of Intel\*(Aqs TSX, which is an x86 instruction set extension and facilitates the creation of multithreaded applications\&. RTM introduces the new instructions
+ \fBXBEGIN\fR,
+ \fBXABORT\fR,
+ \fBXEND\fR, and
+@@ -2377,6 +2464,52 @@
+ .sp
+ RTM improves performance for highly contended locks with low conflict in a critical region (which is code that must not be accessed by more than one thread concurrently)\&. RTM also improves the performance of coarse\-grain locking, which typically does not perform well in multithreaded applications\&. (Coarse\-grain locking is the strategy of holding locks for long periods to minimize the overhead of taking and releasing locks, while fine\-grained locking is the strategy of trying to achieve maximum parallelism by locking only when necessary and unlocking as soon as possible\&.) Also, for lightly contended locks that are used by different threads, RTM can reduce false cache line sharing, also known as cache line ping\-pong\&. This occurs when multiple threads from different processors are accessing different resources, but the resources share the same cache line\&. As a result, the processors repeatedly invalidate the cache lines of other processors, which forces them to read from main memory instead of their cache\&.
+ .RE
++.PP
++\-XX:+UseSHA
++.RS 4
++Enables hardware\-based intrinsics for SHA crypto hash functions for SPARC hardware\&.
++\fBUseSHA\fR
++is used in conjunction with the
++\fBUseSHA1Intrinsics\fR,
++\fBUseSHA256Intrinsics\fR, and
++\fBUseSHA512Intrinsics\fR
++options\&.
++.sp
++The
++\fBUseSHA\fR
++and
++\fBUseSHA*Intrinsics\fR
++flags are enabled by default, and are supported only for Java HotSpot Server VM 64\-bit on SPARC T4 and newer\&.
++.sp
++This feature is only applicable when using the
++\fBsun\&.security\&.provider\&.Sun\fR
++provider for SHA operations\&.
++.sp
++To disable all hardware\-based SHA intrinsics, specify
++\fB\-XX:\-UseSHA\fR\&. To disable only a particular SHA intrinsic, use the appropriate corresponding option\&. For example:
++\fB\-XX:\-UseSHA256Intrinsics\fR\&.
++.RE
++.PP
++\-XX:+UseSHA1Intrinsics
++.RS 4
++Enables intrinsics for SHA\-1 crypto hash function\&.
++.RE
++.PP
++\-XX:+UseSHA256Intrinsics
++.RS 4
++Enables intrinsics for SHA\-224 and SHA\-256 crypto hash functions\&.
++.RE
++.PP
++\-XX:+UseSHA512Intrinsics
++.RS 4
++Enables intrinsics for SHA\-384 and SHA\-512 crypto hash functions\&.
++.RE
++.PP
++\-XX:+UseSuperWord
++.RS 4
++Enables the transformation of scalar operations into superword operations\&. This option is enabled by default\&. To disable the transformation of scalar operations into superword operations, specify
++\fB\-XX:\-UseSuperWord\fR\&. Only the Java HotSpot Server VM supports this option\&.
++.RE
+ .SS "Advanced Serviceability Options"
+ .PP
+ These options provide the ability to gather system information and perform extensive debugging\&.
+@@ -2474,9 +2607,10 @@
+ .PP
+ \-XX:+PrintConcurrentLocks
+ .RS 4
+-Enables printing of j locks after a event\&. By default, this option is disabled\&.
++Enables printing of locks after a event\&. By default, this option is disabled\&.
+ .sp
+-Enables printing of j\fBava\&.util\&.concurrent\fR
++Enables printing of
++\fBjava\&.util\&.concurrent\fR
+ locks after a
+ \fBControl+C\fR
+ event (\fBSIGTERM\fR)\&. By default, this option is disabled\&.
+@@ -2678,7 +2812,9 @@
+ \fBg\fR
+ or
+ \fBG\fR
+-to indicate gigabytes\&. The default value is chosen at runtime based on system configuration\&. For more information, see Garbage Collector Ergonomics at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gc\-ergonomics\&.html
++to indicate gigabytes\&. The default value is chosen at runtime based on system configuration\&. See the section "Ergonomics" in
++\fIJava SE HotSpot Virtual Machine Garbage Collection Tuning Guide\fR
++at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gctuning/index\&.html\&.
+ .sp
+ The following examples show how to set the size of allocated memory to 6 MB using various units:
+ .sp
+@@ -2798,7 +2934,9 @@
+ \fB\-XX:InitialHeapSize\fR
+ and
+ \fB\-XX:MaxHeapSize\fR
+-are often set to the same value\&. For more information, see Garbage Collector Ergonomics at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gc\-ergonomics\&.html
++are often set to the same value\&. See the section "Ergonomics" in
++\fIJava SE HotSpot Virtual Machine Garbage Collection Tuning Guide\fR
++at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gctuning/index\&.html\&.
+ .sp
+ The following examples show how to set the maximum allowed size of allocated memory to 80 MB using various units:
+ .sp
+@@ -3238,6 +3376,13 @@
+ Enables the use of the serial garbage collector\&. This is generally the best choice for small and simple applications that do not require any special functionality from garbage collection\&. By default, this option is disabled and the collector is chosen automatically based on the configuration of the machine and type of the JVM\&.
+ .RE
+ .PP
++\-XX:+UseSHM
++.RS 4
++On Linux, enables the JVM to use shared memory to setup large pages\&.
++.sp
++For more information, see "Large Pages"\&.
++.RE
++.PP
+ \-XX:+UseStringDeduplication
+ .RS 4
+ Enables string deduplication\&. By default, this option is disabled\&. To use this option, you must enable the garbage\-first (G1) garbage collector\&. See the
+@@ -3352,9 +3497,7 @@
+ .PP
+ The following examples show how to use experimental tuning flags to either optimize throughput or to provide lower response time\&.
+ .PP
+-\fBExample 1\fR
+-.br
+-Tuning for Higher Throughput
++\fBExample 1 \fRTuning for Higher Throughput
+ .RS 4
+ .sp
+ .if n \{\
+@@ -3369,9 +3512,7 @@
+ .\}
+ .RE
+ .PP
+-\fBExample 2\fR
+-.br
+-Tuning for Lower Response Time
++\fBExample 2 \fRTuning for Lower Response Time
+ .RS 4
+ .sp
+ .if n \{\
+@@ -3385,6 +3526,195 @@
+ .RE
+ .\}
+ .RE
++.SH "LARGE PAGES"
++.PP
++Also known as huge pages, large pages are memory pages that are significantly larger than the standard memory page size (which varies depending on the processor and operating system)\&. Large pages optimize processor Translation\-Lookaside Buffers\&.
++.PP
++A Translation\-Lookaside Buffer (TLB) is a page translation cache that holds the most\-recently used virtual\-to\-physical address translations\&. TLB is a scarce system resource\&. A TLB miss can be costly as the processor must then read from the hierarchical page table, which may require multiple memory accesses\&. By using a larger memory page size, a single TLB entry can represent a larger memory range\&. There will be less pressure on TLB, and memory\-intensive applications may have better performance\&.
++.PP
++However, large pages page memory can negatively affect system performance\&. For example, when a large mount of memory is pinned by an application, it may create a shortage of regular memory and cause excessive paging in other applications and slow down the entire system\&. Also, a system that has been up for a long time could produce excessive fragmentation, which could make it impossible to reserve enough large page memory\&. When this happens, either the OS or JVM reverts to using regular pages\&.
++.SS "Large Pages Support"
++.PP
++Solaris and Linux support large pages\&.
++.sp
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBSolaris\fR
++.RS 4
++.PP
++Solaris 9 and later include Multiple Page Size Support (MPSS); no additional configuration is necessary\&. See http://www\&.oracle\&.com/technetwork/server\-storage/solaris10/overview/solaris9\-features\-scalability\-135663\&.html\&.
++.RE
++.sp
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBLinux\fR
++.RS 4
++.PP
++The 2\&.6 kernel supports large pages\&. Some vendors have backported the code to their 2\&.4\-based releases\&. To check if your system can support large page memory, try the following:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB# cat /proc/meminfo | grep Huge\fR
++\fBHugePages_Total: 0\fR
++\fBHugePages_Free: 0\fR
++\fBHugepagesize: 2048 kB\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.PP
++If the output shows the three "Huge" variables, then your system can support large page memory but it needs to be configured\&. If the command prints nothing, then your system does not support large pages\&. To configure the system to use large page memory, login as
++\fBroot\fR, and then follow these steps:
++.sp
++.RS 4
++.ie n \{\
++\h'-04' 1.\h'+01'\c
++.\}
++.el \{\
++.sp -1
++.IP " 1." 4.2
++.\}
++If you are using the option
++\fB\-XX:+UseSHM\fR
++(instead of
++\fB\-XX:+UseHugeTLBFS\fR), then increase the
++\fBSHMMAX\fR
++value\&. It must be larger than the Java heap size\&. On a system with 4 GB of physical RAM (or less), the following will make all the memory sharable:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB# echo 4294967295 > /proc/sys/kernel/shmmax\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04' 2.\h'+01'\c
++.\}
++.el \{\
++.sp -1
++.IP " 2." 4.2
++.\}
++If you are using the option
++\fB\-XX:+UseSHM\fR
++or
++\fB\-XX:+UseHugeTLBFS\fR, then specify the number of large pages\&. In the following example, 3 GB of a 4 GB system are reserved for large pages (assuming a large page size of 2048kB, then 3 GB = 3 * 1024 MB = 3072 MB = 3072 * 1024 kB = 3145728 kB and 3145728 kB / 2048 kB = 1536):
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB# echo 1536 > /proc/sys/vm/nr_hugepages\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.if n \{\
++.sp
++.\}
++.RS 4
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBNote\fR
++.ps -1
++.br
++.TS
++allbox tab(:);
++l.
++T{
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++Note that the values contained in
++\fB/proc\fR
++will reset after you reboot your system, so may want to set them in an initialization script (for example,
++\fBrc\&.local\fR
++or
++\fBsysctl\&.conf\fR)\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++If you configure (or resize) the OS kernel parameters
++\fB/proc/sys/kernel/shmmax\fR
++or
++\fB/proc/sys/vm/nr_hugepages\fR, Java processes may allocate large pages for areas in addition to the Java heap\&. These steps can allocate large pages for the following areas:
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++Java heap
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++Code cache
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++The marking bitmap data structure for the parallel GC
++.RE
++.sp
++Consequently, if you configure the
++\fBnr_hugepages\fR
++parameter to the size of the Java heap, then the JVM can fail in allocating the code cache areas on large pages because these areas are quite large in size\&.
++.RE
++T}
++.TE
++.sp 1
++.sp .5v
++.RE
++.RE
+ .SH "EXIT STATUS"
+ .PP
+ The following exit values are typically returned by the launcher when the launcher is called with the wrong arguments, serious errors, or exceptions thrown by the JVM\&. However, a Java application may choose to return any value by using the API call
+@@ -3456,6 +3786,17 @@
+ .\}
+ jar(1)
+ .RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++jstat(1)
++.RE
+ .br
+ 'pl 8.5i
+ 'bp
+--- ./jdk/src/linux/doc/man/javac.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/javac.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,2116 +1,1370 @@
+ '\" t
+-.\" Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
+-.\"
+-.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-.\"
+-.\" This code is free software; you can redistribute it and/or modify it
+-.\" under the terms of the GNU General Public License version 2 only, as
+-.\" published by the Free Software Foundation.
+-.\"
+-.\" This code is distributed in the hope that it will be useful, but WITHOUT
+-.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-.\" version 2 for more details (a copy is included in the LICENSE file that
+-.\" accompanied this code).
+-.\"
+-.\" You should have received a copy of the GNU General Public License version
+-.\" 2 along with this work; if not, write to the Free Software Foundation,
+-.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-.\"
+-.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-.\" or visit www.oracle.com if you need additional information or have any
+-.\" questions.
+-.\"
+-.\" Title: javac
+-.\" Language: English
+-.\" Date: 8 August 2014
+-.\" SectDesc: Basic Tools
+-.\" Software: JDK 8
+-.\" Arch: generic
+-.\" Part Number: E38207-03
++.\" Copyright (c) 1994, 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.
++.\"
++.\" Arch: generic
++.\" Software: JDK 8
++.\" Date: 03 March 2015
++.\" SectDesc: Basic Tools
++.\" Title: javac.1
+ .\"
+ .if n .pl 99999
+-.TH "javac" "1" "8 August 2014" "JDK 8" "Basic Tools"
+-.\" -----------------------------------------------------------------
+-.\" * Define some portability stuff
+-.\" -----------------------------------------------------------------
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.\" http://bugs.debian.org/507673
+-.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.ie \n(.g .ds Aq \(aq
+-.el .ds Aq '
+-.\" -----------------------------------------------------------------
+-.\" * set default formatting
+-.\" -----------------------------------------------------------------
+-.\" disable hyphenation
+-.nh
+-.\" disable justification (adjust text to left margin only)
+-.ad l
+-.\" -----------------------------------------------------------------
+-.\" * MAIN CONTENT STARTS HERE *
+-.\" -----------------------------------------------------------------
+-.SH "NAME"
++.TH javac 1 "03 March 2015" "JDK 8" "Basic Tools"
++.\" -----------------------------------------------------------------
++.\" * Define some portability stuff
++.\" -----------------------------------------------------------------
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.\" http://bugs.debian.org/507673
++.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.ie \n(.g .ds Aq \(aq
++.el .ds Aq '
++.\" -----------------------------------------------------------------
++.\" * set default formatting
++.\" -----------------------------------------------------------------
++.\" disable hyphenation
++.nh
++.\" disable justification (adjust text to left margin only)
++.ad l
++.\" -----------------------------------------------------------------
++.\" * MAIN CONTENT STARTS HERE *
++.\" -----------------------------------------------------------------
++
++.SH NAME
+ javac \- Reads Java class and interface definitions and compiles them into bytecode and class files\&.
+-.SH "SYNOPSIS"
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
++.SH SYNOPSIS
++.sp
++.nf
++
+ \fBjavac\fR [ \fIoptions\fR ] [ \fIsourcefiles\fR ] [ \fIclasses\fR] [ \fI@argfiles\fR ]
+-.fi
+-.if n \{\
+-.RE
+-.\}
++.fi
++.sp
++Arguments can be in any order:
++.TP
++\fIoptions\fR
++Command-line options\&. See Options\&.
++.TP
++\fIsourcefiles\fR
++One or more source files to be compiled (such as \f3MyClass\&.java\fR)\&.
++.TP
++\fIclasses\fR
++One or more classes to be processed for annotations (such as \f3MyPackage\&.MyClass\fR)\&.
++.TP
++\fI@argfiles\fR
++One or more files that list options and source files\&. The \f3-J\fR options are not allowed in these files\&. See Command-Line Argument Files\&.
++.SH DESCRIPTION
++The \f3javac\fR command reads class and interface definitions, written in the Java programming language, and compiles them into bytecode class files\&. The \f3javac\fR command can also process annotations in Java source files and classes\&.
+ .PP
+-Arguments can be in any order:
++There are two ways to pass source code file names to \f3javac\fR\&.
++.TP 0.2i
++\(bu
++For a small number of source files, list the file names on the command line\&.
++.TP 0.2i
++\(bu
++For a large number of source files, list the file names in a file that is separated by blanks or line breaks\&. Use the list file name preceded by an at sign (@) with the \f3javac\fR command\&.
+ .PP
+-\fIoptions\fR
+-.RS 4
+-Command\-line options\&. See Options\&.
+-.RE
++Source code file names must have \&.java suffixes, class file names must have \&.class suffixes, and both source and class files must have root names that identify the class\&. For example, a class called \f3MyClass\fR would be written in a source file called \f3MyClass\&.java\fR and compiled into a bytecode class file called \f3MyClass\&.class\fR\&.
+ .PP
+-\fIsourcefiles\fR
+-.RS 4
+-One or more source files to be compiled (such as
+-\fBMyClass\&.java\fR)\&.
+-.RE
++Inner class definitions produce additional class files\&. These class files have names that combine the inner and outer class names, such as \f3MyClass$MyInnerClass\&.class\fR\&.
+ .PP
+-\fIclasses\fR
+-.RS 4
+-One or more classes to be processed for annotations (such as
+-\fBMyPackage\&.MyClass\fR)\&.
+-.RE
++Arrange source files in a directory tree that reflects their package tree\&. For example, if all of your source files are in \f3/workspace\fR, then put the source code for \f3com\&.mysoft\&.mypack\&.MyClass\fR in \f3/workspace/com/mysoft/mypack/MyClass\&.java\fR\&.
+ .PP
+-\fI@argfiles\fR
+-.RS 4
+-One or more files that list options and source files\&. The
+-\fB\-J\fR
+-options are not allowed in these files\&. See Command\-Line Argument Files\&.
+-.RE
+-.SH "DESCRIPTION"
++By default, the compiler puts each class file in the same directory as its source file\&. You can specify a separate destination directory with the \f3-d\fR option\&.
++.SH OPTIONS
++The compiler has a set of standard options that are supported on the current development environment\&. An additional set of nonstandard options are specific to the current virtual machine and compiler implementations and are subject to change in the future\&. Nonstandard options begin with the \f3-X\fR option\&.
++.TP 0.2i
++\(bu
++See also Cross-Compilation Options
++.TP 0.2i
++\(bu
++See also Nonstandard Options
++.SS STANDARD\ OPTIONS
++.TP
++-A\fIkey\fR[\fI=value\fR]
++.br
++Specifies options to pass to annotation processors\&. These options are not interpreted by \f3javac\fR directly, but are made available for use by individual processors\&. The \f3key\fR value should be one or more identifiers separated by a dot (\&.)\&.
++.TP
++-cp \fIpath\fR or -classpath \fIpath\fR
++.br
++Specifies where to find user class files, and (optionally) annotation processors and source files\&. This class path overrides the user class path in the \f3CLASSPATH\fR environment variable\&. If neither \f3CLASSPATH\fR, \f3-cp\fR nor \f3-classpath\fR is specified, then the user \fIclass path\fR is the current directory\&. See Setting the Class Path\&.
++
++If the \f3-sourcepath\fR option is not specified, then the user class path is also searched for source files\&.
++
++If the \f3-processorpath\fR option is not specified, then the class path is also searched for annotation processors\&.
++.TP
++-Djava\&.ext\&.dirs=\fIdirectories\fR
++.br
++Overrides the location of installed extensions\&.
++.TP
++-Djava\&.endorsed\&.dirs=\fIdirectories\fR
++.br
++Overrides the location of the endorsed standards path\&.
++.TP
++-d \fIdirectory\fR
++.br
++Sets the destination directory for class files\&. The directory must already exist because \f3javac\fR does not create it\&. If a class is part of a package, then \f3javac\fR puts the class file in a subdirectory that reflects the package name and creates directories as needed\&.
++
++If you specify \f3-d\fR\f3/home/myclasses\fR and the class is called \f3com\&.mypackage\&.MyClass\fR, then the class file is \f3/home/myclasses/com/mypackage/MyClass\&.class\fR\&.
++
++If the \fI-d\fR option is not specified, then \f3javac\fR puts each class file in the same directory as the source file from which it was generated\&.
++
++\fINote:\fR The directory specified by the \fI-d\fR option is not automatically added to your user class path\&.
++.TP
++-deprecation
++.br
++Shows a description of each use or override of a deprecated member or class\&. Without the \f3-deprecation\fR option, \f3javac\fR shows a summary of the source files that use or override deprecated members or classes\&. The \f3-deprecation\fR option is shorthand for \f3-Xlint:deprecation\fR\&.
++.TP
++-encoding \fIencoding\fR
++.br
++Sets the source file encoding name, such as EUC-JP and UTF-8\&. If the \f3-encoding\fR option is not specified, then the platform default converter is used\&.
++.TP
++-endorseddirs \fIdirectories\fR
++.br
++Overrides the location of the endorsed standards path\&.
++.TP
++-extdirs \fIdirectories\fR
++.br
++Overrides the location of the \f3ext\fR directory\&. The directories variable is a colon-separated list of directories\&. Each JAR file in the specified directories is searched for class files\&. All JAR files found become part of the class path\&.
++
++If you are cross-compiling (compiling classes against bootstrap and extension classes of a different Java platform implementation), then this option specifies the directories that contain the extension classes\&. See Cross-Compilation Options for more information\&.
++.TP
++-g
++.br
++Generates all debugging information, including local variables\&. By default, only line number and source file information is generated\&.
++.TP
++-g:none
++.br
++Does not generate any debugging information\&.
++.TP
++-g:[\fIkeyword list\fR]
++.br
++Generates only some kinds of debugging information, specified by a comma separated list of keywords\&. Valid keywords are:
++.RS
++.TP
++source
++Source file debugging information\&.
++.TP
++lines
++Line number debugging information\&.
++.TP
++vars
++Local variable debugging information\&.
++.RE
++
++.TP
++-help
++.br
++Prints a synopsis of standard options\&.
++.TP
++-implicit:[\fIclass, none\fR]
++.br
++Controls the generation of class files for implicitly loaded source files\&. To automatically generate class files, use \f3-implicit:class\fR\&. To suppress class file generation, use \f3-implicit:none\fR\&. If this option is not specified, then the default is to automatically generate class files\&. In this case, the compiler issues a warning if any such class files are generated when also doing annotation processing\&. The warning is not issued when the \f3-implicit\fR option is set explicitly\&. See Searching for Types\&.
++.TP
++-J\fIoption\fR
++.br
++Passes \f3option\fR to the Java Virtual Machine (JVM), where option is one of the options described on the reference page for the Java launcher\&. For example, \f3-J-Xms48m\fR sets the startup memory to 48 MB\&. See java(1)\&.
++
++\fINote:\fR The \fICLASSPATH\fR, \f3-classpath\fR, \f3-bootclasspath\fR, and \f3-extdirs\fR options do not specify the classes used to run \f3javac\fR\&. Trying to customize the compiler implementation with these options and variables is risky and often does not accomplish what you want\&. If you must customize the complier implementation, then use the \f3-J\fR option to pass options through to the underlying \f3\fRJava launcher\&.
++.TP
++-nowarn
++.br
++Disables warning messages\&. This option operates the same as the \f3-Xlint:none\fR option\&.
++.TP
++-parameters
++.br
++Stores formal parameter names of constructors and methods in the generated class file so that the method \f3java\&.lang\&.reflect\&.Executable\&.getParameters\fR from the Reflection API can retrieve them\&.
++.TP
++-proc: [\fInone\fR, \fIonly\fR]
++.br
++Controls whether annotation processing and compilation are done\&. \f3-proc:none\fR means that compilation takes place without annotation processing\&. \f3-proc:only\fR means that only annotation processing is done, without any subsequent compilation\&.
++.TP
++-processor \fIclass1\fR [,\fIclass2\fR,\fIclass3\fR\&.\&.\&.]
++.br
++Names of the annotation processors to run\&. This bypasses the default discovery process\&.
++.TP
++-processorpath \fIpath\fR
++.br
++Specifies where to find annotation processors\&. If this option is not used, then the class path is searched for processors\&.
++.TP
++-s \fIdir\fR
++.br
++Specifies the directory where to place the generated source files\&. The directory must already exist because \f3javac\fR does not create it\&. If a class is part of a package, then the compiler puts the source file in a subdirectory that reflects the package name and creates directories as needed\&.
++
++If you specify \f3-s /home/mysrc\fR and the class is called \f3com\&.mypackage\&.MyClass\fR, then the source file is put in \f3/home/mysrc/com/mypackage/MyClass\&.java\fR\&.
++.TP
++-source \fIrelease\fR
++.br
++Specifies the version of source code accepted\&. The following values for \f3release\fR are allowed:
++.RS
++.TP
++1\&.3
++The compiler does not support assertions, generics, or other language features introduced after Java SE 1\&.3\&.
++.TP
++1\&.4
++The compiler accepts code containing assertions, which were introduced in Java SE 1\&.4\&.
++.TP
++1\&.5
++The compiler accepts code containing generics and other language features introduced in Java SE 5\&.
++.TP
++5
++Synonym for 1\&.5\&.
++.TP
++1\&.6
++No language changes were introduced in Java SE 6\&. However, encoding errors in source files are now reported as errors instead of warnings as in earlier releases of Java Platform, Standard Edition\&.
++.TP
++6
++Synonym for 1\&.6\&.
++.TP
++1\&.7
++The compiler accepts code with features introduced in Java SE 7\&.
++.TP
++7
++Synonym for 1\&.7\&.
++.TP
++1\&.8
++This is the default value\&. The compiler accepts code with features introduced in Java SE 8\&.
++.TP
++8
++Synonym for 1\&.8\&.
++.RE
++
++.TP
++-sourcepath \fIsourcepath\fR
++.br
++Specifies the source code path to search for class or interface definitions\&. As with the user class path, source path entries are separated by colons (:) on Oracle Solaris and semicolons on Windows and can be directories, JAR archives, or ZIP archives\&. If packages are used, then the local path name within the directory or archive must reflect the package name\&.
++
++\fINote:\fR Classes found through the class path might be recompiled when their source files are also found\&. See Searching for Types\&.
++.TP
++-verbose
++.br
++Uses verbose output, which includes information about each class loaded and each source file compiled\&.
++.TP
++-version
++.br
++Prints release information\&.
++.TP
++-werror
++.br
++Terminates compilation when warnings occur\&.
++.TP
++-X
++.br
++Displays information about nonstandard options and exits\&.
++.SS CROSS-COMPILATION\ OPTIONS
++By default, classes are compiled against the bootstrap and extension classes of the platform that \f3javac\fR shipped with\&. But \f3javac\fR also supports cross-compiling, where classes are compiled against a bootstrap and extension classes of a different Java platform implementation\&. It is important to use the \f3-bootclasspath\fR and \f3-extdirs\fR options when cross-compiling\&.
++.TP
++-target \fIversion\fR
++.br
++Generates class files that target a specified release of the virtual machine\&. Class files will run on the specified target and on later releases, but not on earlier releases of the JVM\&. Valid targets are 1\&.1, 1\&.2, 1\&.3, 1\&.4, 1\&.5 (also 5), 1\&.6 (also 6), 1\&.7 (also 7), and 1\&.8 (also 8)\&.
++
++The default for the \f3-target\fR option depends on the value of the \f3-source\fR option:
++.RS
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is not specified, then the value of the \f3-target\fR option is 1\&.8
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is 1\&.2, then the value of the \f3-target\fR option is 1\&.4
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is 1\&.3, then the value of the \f3-target\fR option is 1\&.4
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is 1\&.5, then the value of the \f3-target\fR option is 1\&.8
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is 1\&.6, then the value of the \f3-target\fR is option 1\&.8
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is 1\&.7, then the value of the \f3-target\fR is option 1\&.8
++.TP 0.2i
++\(bu
++For all other values of the \f3-source\fR option, the value of the \f3-target\fR option is the value of the \f3-source\fR option\&.
++.RE
++
++.TP
++-bootclasspath \fIbootclasspath\fR
++.br
++Cross-compiles against the specified set of boot classes\&. As with the user class path, boot class path entries are separated by colons (:) and can be directories, JAR archives, or ZIP archives\&.
++.SS COMPACT\ PROFILE\ OPTION
++Beginning with JDK 8, the \f3javac\fR compiler supports compact profiles\&. With compact profiles, applications that do not require the entire Java platform can be deployed and run with a smaller footprint\&. The compact profiles feature could be used to shorten the download time for applications from app stores\&. This feature makes for more compact deployment of Java applications that bundle the JRE\&. This feature is also useful in small devices\&.
+ .PP
+-The
+-\fBjavac\fR
+-command reads class and interface definitions, written in the Java programming language, and compiles them into bytecode class files\&. The
+-\fBjavac\fR
+-command can also process annotations in Java source files and classes\&.
++The supported profile values are \f3compact1\fR, \f3compact2\fR, and \f3compact3\fR\&. These are additive layers\&. Each higher-numbered compact profile contains all of the APIs in profiles with smaller number names\&.
++.TP
++-profile
++.br
++When using compact profiles, this option specifies the profile name when compiling\&. For example:
++.sp
++.nf
++\f3javac \-profile compact1 Hello\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++javac does not compile source code that uses any Java SE APIs that is not in the specified profile\&. Here is an example of the error message that results from attempting to compile such source code:
++.sp
++.nf
++\f3cd jdk1\&.8\&.0/bin\fP
++.fi
++.nf
++\f3\&./javac \-profile compact1 Paint\&.java\fP
++.fi
++.nf
++\f3Paint\&.java:5: error: Applet is not available in profile \&'compact1\&'\fP
++.fi
++.nf
++\f3import java\&.applet\&.Applet;\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++In this example, you can correct the error by modifying the source to not use the \f3Applet\fR class\&. You could also correct the error by compiling without the -profile option\&. Then the compilation would be run against the full set of Java SE APIs\&. (None of the compact profiles include the \f3Applet\fR class\&.)
++
++An alternative way to compile with compact profiles is to use the \f3-bootclasspath\fR option to specify a path to an \f3rt\&.jar\fR file that specifies a profile\&'s image\&. Using the \f3-profile\fR option instead does not require a profile image to be present on the system at compile time\&. This is useful when cross-compiling\&.
++.SS NONSTANDARD\ OPTIONS
++.TP
++-Xbootclasspath/p:\fIpath\fR
++.br
++Adds a suffix to the bootstrap class path\&.
++.TP
++-Xbootclasspath/a:\fIpath\fR
++.br
++Adds a prefix to the bootstrap class path\&.
++.TP
++-Xbootclasspath/:\fIpath\fR
++.br
++Overrides the location of the bootstrap class files\&.
++.TP
++-Xdoclint:[-]\fIgroup\fR [\fI/access\fR]
++.br
++Enables or disables specific groups of checks, where \fIgroup\fR is one of the following values: \f3accessibility\fR, \f3syntax\fR, \f3reference\fR, \f3html\fR or \f3missing\fR\&. For more information about these groups of checks see the \f3-Xdoclint\fR option of the \f3javadoc\fR command\&. The \f3-Xdoclint\fR option is disabled by default in the \f3javac\fR command\&.
++
++The variable \fIaccess\fR specifies the minimum visibility level of classes and members that the \f3-Xdoclint\fR option checks\&. It can have one of the following values (in order of most to least visible) : \f3public\fR, \f3protected\fR, \f3package\fR and \f3private\fR\&. For example, the following option checks classes and members (with all groups of checks) that have the access level protected and higher (which includes protected, package and public):
++.sp
++.nf
++\f3\-Xdoclint:all/protected\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The following option enables all groups of checks for all access levels, except it will not check for HTML errors for classes and members that have access level package and higher (which includes package and public):
++.sp
++.nf
++\f3\-Xdoclint:all,\-html/package\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++-Xdoclint:none
++.br
++Disables all groups of checks\&.
++.TP
++-Xdoclint:all[\fI/access\fR]
++.br
++Enables all groups of checks\&.
++.TP
++-Xlint
++.br
++\fI\fREnables all recommended warnings\&. In this release, enabling all available warnings is recommended\&.
++.TP
++-Xlint:all
++.br
++\fI\fREnables all recommended warnings\&. In this release, enabling all available warnings is recommended\&.
++.TP
++-Xlint:none
++.br
++Disables all warnings\&.
++.TP
++-Xlint:\fIname\fR
++.br
++Disables warning name\&. See Enable or Disable Warnings with the -Xlint Option for a list of warnings you can disable with this option\&.
++.TP
++-Xlint:\fI-name\fR
++.br
++Disables warning name\&. See Enable or Disable Warnings with the -Xlint Option with the \f3-Xlint\fR option to get a list of warnings that you can disable with this option\&.
++.TP
++-Xmaxerrs \fInumber\fR
++.br
++Sets the maximum number of errors to print\&.
++.TP
++-Xmaxwarns \fInumber\fR
++.br
++Sets the maximum number of warnings to print\&.
++.TP
++-Xstdout \fIfilename\fR
++.br
++Sends compiler messages to the named file\&. By default, compiler messages go to \f3System\&.err\fR\&.
++.TP
++-Xprefer:[\fInewer,source\fR]
++.br
++Specifies which file to read when both a source file and class file are found for a type\&. (See Searching for Types)\&. If the \f3-Xprefer:newer\fR option is used, then it reads the newer of the source or class file for a type (default)\&. If the \f3-Xprefer:source\fR option is used, then it reads the source file\&. Use -\f3Xprefer:source\fR when you want to be sure that any annotation processors can access annotations declared with a retention policy of \f3SOURCE\fR\&.
++.TP
++-Xpkginfo:[\fIalways\fR,\fIlegacy\fR,\fInonempty\fR]
++.br
++Control whether javac generates \f3package-info\&.class\fR files from package-info\&.java files\&. Possible mode arguments for this option include the following\&.
++.RS
++.TP
++always
++Always generate a \f3package-info\&.class\fR file for every \f3package-info\&.java\fR file\&. This option may be useful if you use a build system such as Ant, which checks that each \f3\&.java\fR file has a corresponding \f3\&.class\fR file\&.
++.TP
++legacy
++Generate a \f3package-info\&.class\fR file only if package-info\&.java contains annotations\&. Don\&'t generate a \f3package-info\&.class\fR file if package-info\&.java only contains comments\&.
++
++\fINote:\fR A \f3package-info\&.class\fR file might be generated but be empty if all the annotations in the package-info\&.java file have \f3RetentionPolicy\&.SOURCE\fR\&.
++.TP
++nonempty
++Generate a \f3package-info\&.class\fR file only if package-info\&.java contains annotations with \f3RetentionPolicy\&.CLASS\fR or \f3RetentionPolicy\&.RUNTIME\fR\&.
++.RE
++
++.TP
++-Xprint
++.br
++Prints a textual representation of specified types for debugging purposes\&. Perform neither annotation processing nor compilation\&. The format of the output could change\&.
++.TP
++-XprintProcessorInfo
++.br
++Prints information about which annotations a processor is asked to process\&.
++.TP
++-XprintRounds
++.br
++Prints information about initial and subsequent annotation processing rounds\&.
++.SH ENABLE\ OR\ DISABLE\ WARNINGS\ WITH\ THE\ -XLINT\ OPTION
++Enable warning \fIname\fR with the \f3-Xlint:name\fR option, where \f3name\fR is one of the following warning names\&. Note that you can disable a warning with the \f3-Xlint:-name:\fR option\&.
++.TP
++cast
++Warns about unnecessary and redundant casts, for example:
++.sp
++.nf
++\f3String s = (String) "Hello!"\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++classfile
++Warns about issues related to class file contents\&.
++.TP
++deprecation
++Warns about the use of deprecated items, for example:
++.sp
++.nf
++\f3java\&.util\&.Date myDate = new java\&.util\&.Date();\fP
++.fi
++.nf
++\f3int currentDay = myDate\&.getDay();\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The method \f3java\&.util\&.Date\&.getDay\fR has been deprecated since JDK 1\&.1
++.TP
++dep-ann
++Warns about items that are documented with an \f3@deprecated\fR Javadoc comment, but do not have a \f3@Deprecated\fR annotation, for example:
++.sp
++.nf
++\f3/**\fP
++.fi
++.nf
++\f3 * @deprecated As of Java SE 7, replaced by {@link #newMethod()}\fP
++.fi
++.nf
++\f3 */\fP
++.fi
++.nf
++\f3public static void deprecatedMethood() { }\fP
++.fi
++.nf
++\f3public static void newMethod() { }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++divzero
++Warns about division by the constant integer 0, for example:
++.sp
++.nf
++\f3int divideByZero = 42 / 0;\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++empty
++Warns about empty statements after \f3if\fRstatements, for example:
++.sp
++.nf
++\f3class E {\fP
++.fi
++.nf
++\f3 void m() {\fP
++.fi
++.nf
++\f3 if (true) ;\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++fallthrough
++Checks the switch blocks for fall-through cases and provides a warning message for any that are found\&. Fall-through cases are cases in a switch block, other than the last case in the block, whose code does not include a break statement, allowing code execution to fall through from that case to the next case\&. For example, the code following the case 1 label in this switch block does not end with a break statement:
++.sp
++.nf
++\f3switch (x) {\fP
++.fi
++.nf
++\f3case 1:\fP
++.fi
++.nf
++\f3 System\&.out\&.println("1");\fP
++.fi
++.nf
++\f3 // No break statement here\&.\fP
++.fi
++.nf
++\f3case 2:\fP
++.fi
++.nf
++\f3 System\&.out\&.println("2");\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++If the \f3-Xlint:fallthrough\fR option was used when compiling this code, then the compiler emits a warning about possible fall-through into case, with the line number of the case in question\&.
++.TP
++finally
++Warns about \f3finally\fR clauses that cannot complete normally, for example:
++.sp
++.nf
++\f3public static int m() {\fP
++.fi
++.nf
++\f3 try {\fP
++.fi
++.nf
++\f3 throw new NullPointerException();\fP
++.fi
++.nf
++\f3 } catch (NullPointerException(); {\fP
++.fi
++.nf
++\f3 System\&.err\&.println("Caught NullPointerException\&.");\fP
++.fi
++.nf
++\f3 return 1;\fP
++.fi
++.nf
++\f3 } finally {\fP
++.fi
++.nf
++\f3 return 0;\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The compiler generates a warning for the \f3finally\fR block in this example\&. When the \f3int\fR method is called, it returns a value of 0\&. A \f3finally\fR block executes when the \f3try\fR block exits\&. In this example, when control is transferred to the \f3catch\fR block, the \f3int\fR method exits\&. However, the \f3finally\fR block must execute, so it is executed, even though control was transferred outside the method\&.
++.TP
++options
++Warns about issues that related to the use of command-line options\&. See Cross-Compilation Options\&.
++.TP
++overrides
++Warns about issues regarding method overrides\&. For example, consider the following two classes:
++.sp
++.nf
++\f3public class ClassWithVarargsMethod {\fP
++.fi
++.nf
++\f3 void varargsMethod(String\&.\&.\&. s) { }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3public class ClassWithOverridingMethod extends ClassWithVarargsMethod {\fP
++.fi
++.nf
++\f3 @Override\fP
++.fi
++.nf
++\f3 void varargsMethod(String[] s) { }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The compiler generates a warning similar to the following:\&.
++.sp
++.nf
++\f3warning: [override] varargsMethod(String[]) in ClassWithOverridingMethod \fP
++.fi
++.nf
++\f3overrides varargsMethod(String\&.\&.\&.) in ClassWithVarargsMethod; overriding\fP
++.fi
++.nf
++\f3method is missing \&'\&.\&.\&.\&'\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++When the compiler encounters a \f3varargs\fR method, it translates the \f3varargs\fR formal parameter into an array\&. In the method \f3ClassWithVarargsMethod\&.varargsMethod\fR, the compiler translates the \f3varargs\fR formal parameter \f3String\&.\&.\&. s\fR to the formal parameter \f3String[] s\fR, an array, which matches the formal parameter of the method \f3ClassWithOverridingMethod\&.varargsMethod\fR\&. Consequently, this example compiles\&.
++.TP
++path
++Warns about invalid path elements and nonexistent path directories on the command line (with regard to the class path, the source path, and other paths)\&. Such warnings cannot be suppressed with the \f3@SuppressWarnings\fR annotation, for example:
++.sp
++.nf
++\f3javac \-Xlint:path \-classpath /nonexistentpath Example\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++processing
++Warn about issues regarding annotation processing\&. The compiler generates this warning when you have a class that has an annotation, and you use an annotation processor that cannot handle that type of exception\&. For example, the following is a simple annotation processor:
++
++\fISource file AnnocProc\&.java\fR:
++.sp
++.nf
++\f3import java\&.util\&.*;\fP
++.fi
++.nf
++\f3import javax\&.annotation\&.processing\&.*;\fP
++.fi
++.nf
++\f3import javax\&.lang\&.model\&.*;\fP
++.fi
++.nf
++\f3import\&.javaz\&.lang\&.model\&.element\&.*;\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3@SupportedAnnotationTypes("NotAnno")\fP
++.fi
++.nf
++\f3public class AnnoProc extends AbstractProcessor {\fP
++.fi
++.nf
++\f3 public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv){\fP
++.fi
++.nf
++\f3 return true;\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3 public SourceVersion getSupportedSourceVersion() {\fP
++.fi
++.nf
++\f3 return SourceVersion\&.latest();\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++\fISource file AnnosWithoutProcessors\&.java\fR:
++.sp
++.nf
++\f3@interface Anno { }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3@Anno\fP
++.fi
++.nf
++\f3class AnnosWithoutProcessors { }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The following commands compile the annotation processor \f3AnnoProc\fR, then run this annotation processor against the source file \f3AnnosWithoutProcessors\&.java\fR:
++.sp
++.nf
++\f3javac AnnoProc\&.java\fP
++.fi
++.nf
++\f3javac \-cp \&. \-Xlint:processing \-processor AnnoProc \-proc:only AnnosWithoutProcessors\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++When the compiler runs the annotation processor against the source file \f3AnnosWithoutProcessors\&.java\fR, it generates the following warning:
++.sp
++.nf
++\f3warning: [processing] No processor claimed any of these annotations: Anno\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++To resolve this issue, you can rename the annotation defined and used in the class \f3AnnosWithoutProcessors\fR from \f3Anno\fR to \f3NotAnno\fR\&.
++.TP
++rawtypes
++Warns about unchecked operations on raw types\&. The following statement generates a \f3rawtypes\fR warning:
++.sp
++.nf
++\f3void countElements(List l) { \&.\&.\&. }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The following example does not generate a \f3rawtypes\fR warning
++.sp
++.nf
++\f3void countElements(List<?> l) { \&.\&.\&. }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++\f3List\fR is a raw type\&. However, \f3List<?>\fR is an unbounded wildcard parameterized type\&. Because \f3List\fR is a parameterized interface, always specify its type argument\&. In this example, the \f3List\fR formal argument is specified with an unbounded wildcard (\f3?\fR) as its formal type parameter, which means that the \f3countElements\fR method can accept any instantiation of the \f3List\fR interface\&.
++.TP
++Serial
++Warns about missing \f3serialVersionUID\fR definitions on serializable classes, for example:
++.sp
++.nf
++\f3public class PersistentTime implements Serializable\fP
++.fi
++.nf
++\f3{\fP
++.fi
++.nf
++\f3 private Date time;\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3 public PersistentTime() {\fP
++.fi
++.nf
++\f3 time = Calendar\&.getInstance()\&.getTime();\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3 public Date getTime() {\fP
++.fi
++.nf
++\f3 return time;\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The compiler generates the following warning:
++.sp
++.nf
++\f3warning: [serial] serializable class PersistentTime has no definition of\fP
++.fi
++.nf
++\f3serialVersionUID\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++If a serializable class does not explicitly declare a field named \f3serialVersionUID\fR, then the serialization runtime environment calculates a default \f3serialVersionUID\fR value for that class based on various aspects of the class, as described in the Java Object Serialization Specification\&. However, it is strongly recommended that all serializable classes explicitly declare \f3serialVersionUID\fR values because the default process of computing \f3serialVersionUID\fR vales is highly sensitive to class details that can vary depending on compiler implementations, and as a result, might cause an unexpected \f3InvalidClassExceptions\fR during deserialization\&. To guarantee a consistent \f3serialVersionUID\fR value across different Java compiler implementations, a serializable class must declare an explicit \f3serialVersionUID\fR value\&.
++.TP
++static
++Warns about issues relating to the use of statics, for example:
++.sp
++.nf
++\f3class XLintStatic {\fP
++.fi
++.nf
++\f3 static void m1() { }\fP
++.fi
++.nf
++\f3 void m2() { this\&.m1(); }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The compiler generates the following warning:
++.sp
++.nf
++\f3warning: [static] static method should be qualified by type name, \fP
++.fi
++.nf
++\f3XLintStatic, instead of by an expression\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++To resolve this issue, you can call the \f3static\fR method \f3m1\fR as follows:
++.sp
++.nf
++\f3XLintStatic\&.m1();\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++Alternately, you can remove the \f3static\fR keyword from the declaration of the method \f3m1\fR\&.
++.TP
++try
++Warns about issues relating to use of \f3try\fR blocks, including try-with-resources statements\&. For example, a warning is generated for the following statement because the resource \f3ac\fR declared in the \f3try\fR block is not used:
++.sp
++.nf
++\f3try ( AutoCloseable ac = getResource() ) { // do nothing}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++unchecked
++Gives more detail for unchecked conversion warnings that are mandated by the Java Language Specification, for example:
++.sp
++.nf
++\f3List l = new ArrayList<Number>();\fP
++.fi
++.nf
++\f3List<String> ls = l; // unchecked warning\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++During type erasure, the types \f3ArrayList<Number>\fR and \f3List<String>\fR become \f3ArrayList\fR and \f3List\fR, respectively\&.
++
++The \f3ls\fR command has the parameterized type \f3List<String>\fR\&. When the \f3List\fR referenced by \f3l\fR is assigned to \f3ls\fR, the compiler generates an unchecked warning\&. At compile time, the compiler and JVM cannot determine whether \f3l\fR refers to a \f3List<String>\fR type\&. In this case, \f3l\fR does not refer to a \f3List<String>\fR type\&. As a result, heap pollution occurs\&.
++
++A heap pollution situation occurs when the \f3List\fR object \f3l\fR, whose static type is \f3List<Number>\fR, is assigned to another \f3List\fR object, \f3ls\fR, that has a different static type, \f3List<String>\fR\&. However, the compiler still allows this assignment\&. It must allow this assignment to preserve backward compatibility with releases of Java SE that do not support generics\&. Because of type erasure, \f3List<Number>\fR and \f3List<String>\fR both become \f3List\fR\&. Consequently, the compiler allows the assignment of the object \f3l\fR\f3,\fR which has a raw type of \f3List\fR, to the object \f3ls\fR\&.
++.TP
++varargs
++Warns about unsafe usages of variable arguments (\f3varargs\fR) methods, in particular, those that contain non-reifiable arguments, for example:
++.sp
++.nf
++\f3public class ArrayBuilder {\fP
++.fi
++.nf
++\f3 public static <T> void addToList (List<T> listArg, T\&.\&.\&. elements) {\fP
++.fi
++.nf
++\f3 for (T x : elements) {\fP
++.fi
++.nf
++\f3 listArg\&.add(x);\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++\fINote:\fR A non-reifiable type is a type whose type information is not fully available at runtime\&.
++
++The compiler generates the following warning for the definition of the method \f3ArrayBuilder\&.addToList\fR
++.sp
++.nf
++\f3warning: [varargs] Possible heap pollution from parameterized vararg type T\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++When the compiler encounters a varargs method, it translates the \f3varargs\fR formal parameter into an array\&. However, the Java programming language does not permit the creation of arrays of parameterized types\&. In the method \f3ArrayBuilder\&.addToList\fR, the compiler translates the \f3varargs\fR formal parameter \f3T\&.\&.\&.\fR elements to the formal parameter \f3T[]\fR elements, an array\&. However, because of type erasure, the compiler converts the \f3varargs\fR formal parameter to \f3Object[]\fR elements\&. Consequently, there is a possibility of heap pollution\&.
++.SH COMMAND-LINE\ ARGUMENT\ FILES
++To shorten or simplify the \f3javac\fR command, you can specify one or more files that contain arguments to the \f3javac\fR command (except \f3-J\fR options)\&. This enables you to create \f3javac\fR commands of any length on any operating system\&.
+ .PP
+-There are two ways to pass source code file names to
+-\fBjavac\fR\&.
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-For a small number of source files, list the file names on the command line\&.
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-For a large number of source files, list the file names in a file that is separated by blanks or line breaks\&. Use the list file name preceded by an at sign (@) with the
+-\fBjavac\fR
+-command\&.
+-.RE
++An argument file can include \f3javac\fR options and source file names in any combination\&. The arguments within a file can be separated by spaces or new line characters\&. If a file name contains embedded spaces, then put the whole file name in double quotation marks\&.
+ .PP
+-Source code file names must have \&.java suffixes, class file names must have \&.class suffixes, and both source and class files must have root names that identify the class\&. For example, a class called
+-\fBMyClass\fR
+-would be written in a source file called
+-\fBMyClass\&.java\fR
+-and compiled into a bytecode class file called
+-\fBMyClass\&.class\fR\&.
++File Names within an argument file are relative to the current directory, not the location of the argument file\&. Wild cards (*) are not allowed in these lists (such as for specifying \f3*\&.java\fR)\&. Use of the at sign (@) to recursively interpret files is not supported\&. The \f3-J\fR options are not supported because they are passed to the launcher, which does not support argument files\&.
+ .PP
+-Inner class definitions produce additional class files\&. These class files have names that combine the inner and outer class names, such as
+-\fBMyClass$MyInnerClass\&.class\fR\&.
++When executing the \f3javac\fR command, pass in the path and name of each argument file with the at sign (@) leading character\&. When the \f3javac\fR command encounters an argument beginning with the at sign (@), it expands the contents of that file into the argument list\&.
+ .PP
+-Arrange source files in a directory tree that reflects their package tree\&. For example, if all of your source files are in
+-\fB/workspace\fR, then put the source code for
+-\fBcom\&.mysoft\&.mypack\&.MyClass\fR
+-in
+-\fB/workspace/com/mysoft/mypack/MyClass\&.java\fR\&.
++\f3Example 1 Single Argument File\fR
+ .PP
+-By default, the compiler puts each class file in the same directory as its source file\&. You can specify a separate destination directory with the
+-\fB\-d\fR
+-option\&.
+-.SH "OPTIONS"
++You could use a single argument file named \f3argfile\fR to hold all \f3javac\fR arguments:
++.sp
++.nf
++\f3javac @argfile\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++This argument file could contain the contents of both files shown in Example 2
+ .PP
+-The compiler has a set of standard options that are supported on the current development environment\&. An additional set of nonstandard options are specific to the current virtual machine and compiler implementations and are subject to change in the future\&. Nonstandard options begin with the
+-\fB\-X\fR
+-option\&.
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-See also Cross\-Compilation Options
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-See also Nonstandard Options
+-.RE
+-.SS "Standard Options"
++\f3Example 2 Two Argument Files\fR
+ .PP
+-\-A\fIkey\fR[\fI=value\fR]
+-.RS 4
+-Specifies options to pass to annotation processors\&. These options are not interpreted by
+-\fBjavac\fR
+-directly, but are made available for use by individual processors\&. The
+-\fBkey\fR
+-value should be one or more identifiers separated by a dot (\&.)\&.
+-.RE
++You can create two argument files: one for the \f3javac\fR options and the other for the source file names\&. Note that the following lists have no line-continuation characters\&.
+ .PP
+-\-cp \fIpath\fR or \-classpath \fIpath\fR
+-.RS 4
+-Specifies where to find user class files, and (optionally) annotation processors and source files\&. This class path overrides the user class path in the
+-\fBCLASSPATH\fR
+-environment variable\&. If neither
+-\fBCLASSPATH\fR,
+-\fB\-cp\fR
+-nor
+-\fB\-classpath\fR
+-is specified, then the user
+-\fIclass path\fR
+-is the current directory\&. See Setting the Class Path \&.
+-.sp
+-If the
+-\fB\-sourcepath\fR
+-option is not specified, then the user class path is also searched for source files\&.
+-.sp
+-If the
+-\fB\-processorpath\fR
+-option is not specified, then the class path is also searched for annotation processors\&.
+-.RE
++Create a file named options that contains the following:
++.sp
++.nf
++\f3\-d classes\fP
++.fi
++.nf
++\f3\-g\fP
++.fi
++.nf
++\f3\-sourcepath /java/pubs/ws/1\&.3/src/share/classes\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++Create a file named classes that contains the following:
++.sp
++.nf
++\f3MyClass1\&.java\fP
++.fi
++.nf
++\f3MyClass2\&.java\fP
++.fi
++.nf
++\f3MyClass3\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++Then, run the \f3javac\fR command as follows:
++.sp
++.nf
++\f3javac @options @classes\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++\f3Example 3 Argument Files with Paths\fR
+ .PP
+-\-Djava\&.ext\&.dirs=\fIdirectories\fR
+-.RS 4
+-Overrides the location of installed extensions\&.
+-.RE
++The argument files can have paths, but any file names inside the files are relative to the current working directory (not \f3path1\fR or \f3path2\fR):
++.sp
++.nf
++\f3javac @path1/options @path2/classes\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++.SH ANNOTATION\ PROCESSING
++The \f3javac\fR command provides direct support for annotation processing, superseding the need for the separate annotation processing command, \f3apt\fR\&.
+ .PP
+-\-Djava\&.endorsed\&.dirs=\fIdirectories\fR
+-.RS 4
+-Overrides the location of the endorsed standards path\&.
+-.RE
+-.PP
+-\-d \fIdirectory\fR
+-.RS 4
+-Sets the destination directory for class files\&. The directory must already exist because
+-\fBjavac\fR
+-does not create it\&. If a class is part of a package, then
+-\fBjavac\fR
+-puts the class file in a subdirectory that reflects the package name and creates directories as needed\&.
+-.sp
+-If you specify
+-\fB\-d\fR
+-\fB/home/myclasses\fR
+-and the class is called
+-\fBcom\&.mypackage\&.MyClass\fR, then the class file is
+-\fB/home/myclasses/com/mypackage/MyClass\&.class\fR\&.
+-.sp
+-If the
+-\fI\-d\fR
+-option is not specified, then
+-\fBjavac\fR
+-puts each class file in the same directory as the source file from which it was generated\&.
+-.sp
+-\fBNote:\fR
+-The directory specified by the
+-\fI\-d\fR
+-option is not automatically added to your user class path\&.
+-.RE
+-.PP
+-\-deprecation
+-.RS 4
+-Shows a description of each use or override of a deprecated member or class\&. Without the
+-\fB\-deprecation\fR
+-option,
+-\fBjavac\fR
+-shows a summary of the source files that use or override deprecated members or classes\&. The
+-\fB\-deprecation\fR
+-option is shorthand for
+-\fB\-Xlint:deprecation\fR\&.
+-.RE
+-.PP
+-\-encoding \fIencoding\fR
+-.RS 4
+-Sets the source file encoding name, such as EUC\-JP and UTF\-8\&. If the
+-\fB\-encoding\fR
+-option is not specified, then the platform default converter is used\&.
+-.RE
+-.PP
+-\-endorseddirs \fIdirectories\fR
+-.RS 4
+-Overrides the location of the endorsed standards path\&.
+-.RE
+-.PP
+-\-extdirs \fIdirectories\fR
+-.RS 4
+-Overrides the location of the
+-\fBext\fR
+-directory\&. The directories variable is a colon\-separated list of directories\&. Each JAR file in the specified directories is searched for class files\&. All JAR files found become part of the class path\&.
+-.sp
+-If you are cross\-compiling (compiling classes against bootstrap and extension classes of a different Java platform implementation), then this option specifies the directories that contain the extension classes\&. See Cross\-Compilation Options for more information\&.
+-.RE
+-.PP
+-\-g
+-.RS 4
+-Generates all debugging information, including local variables\&. By default, only line number and source file information is generated\&.
+-.RE
+-.PP
+-\-g:none
+-.RS 4
+-Does not generate any debugging information\&.
+-.RE
+-.PP
+-\-g:[\fIkeyword list\fR]
+-.RS 4
+-Generates only some kinds of debugging information, specified by a comma separated list of keywords\&. Valid keywords are:
+-.PP
+-source
+-.RS 4
+-Source file debugging information\&.
+-.RE
+-.PP
+-lines
+-.RS 4
+-Line number debugging information\&.
+-.RE
+-.PP
+-vars
+-.RS 4
+-Local variable debugging information\&.
+-.RE
+-.RE
+-.PP
+-\-help
+-.RS 4
+-Prints a synopsis of standard options\&.
+-.RE
+-.PP
+-\-implicit:[\fIclass, none\fR]
+-.RS 4
+-Controls the generation of class files for implicitly loaded source files\&. To automatically generate class files, use
+-\fB\-implicit:class\fR\&. To suppress class file generation, use
+-\fB\-implicit:none\fR\&. If this option is not specified, then the default is to automatically generate class files\&. In this case, the compiler issues a warning if any such class files are generated when also doing annotation processing\&. The warning is not issued when the
+-\fB\-implicit\fR
+-option is set explicitly\&. See Searching for Types\&.
+-.RE
+-.PP
+-\-J\fIoption\fR
+-.RS 4
+-Passes
+-\fBoption\fR
+-to the Java Virtual Machine (JVM), where option is one of the options described on the reference page for the Java launcher\&. For example,
+-\fB\-J\-Xms48m\fR
+-sets the startup memory to 48 MB\&. See
+-java(1)\&.
+-.sp
+-\fBNote:\fR
+-The
+-\fICLASSPATH\fR,
+-\fB\-classpath\fR,
+-\fB\-bootclasspath\fR, and
+-\fB\-extdirs\fR
+-options do not specify the classes used to run
+-\fBjavac\fR\&. Trying to customize the compiler implementation with these options and variables is risky and often does not accomplish what you want\&. If you must customize the complier implementation, then use the
+-\fB\-J\fR
+-option to pass options through to the underlying Java launcher\&.
+-.RE
+-.PP
+-\-nowarn
+-.RS 4
+-Disables warning messages\&. This option operates the same as the
+-\fB\-Xlint:none\fR
+-option\&.
+-.RE
+-.PP
+-\-parameters
+-.RS 4
+-Stores formal parameter names of constructors and methods in the generated class file so that the method
+-\fBjava\&.lang\&.reflect\&.Executable\&.getParameters\fR
+-from the Reflection API can retrieve them\&.
+-.RE
+-.PP
+-\-proc: [\fInone\fR, \fIonly\fR]
+-.RS 4
+-Controls whether annotation processing and compilation are done\&.
+-\fB\-proc:none\fR
+-means that compilation takes place without annotation processing\&.
+-\fB\-proc:only\fR
+-means that only annotation processing is done, without any subsequent compilation\&.
+-.RE
+-.PP
+-\-processor \fIclass1\fR [,\fIclass2\fR,\fIclass3\fR\&.\&.\&.]
+-.RS 4
+-Names of the annotation processors to run\&. This bypasses the default discovery process\&.
+-.RE
+-.PP
+-\-processorpath \fIpath\fR
+-.RS 4
+-Specifies where to find annotation processors\&. If this option is not used, then the class path is searched for processors\&.
+-.RE
+-.PP
+-\-s \fIdir\fR
+-.RS 4
+-Specifies the directory where to place the generated source files\&. The directory must already exist because
+-\fBjavac\fR
+-does not create it\&. If a class is part of a package, then the compiler puts the source file in a subdirectory that reflects the package name and creates directories as needed\&.
+-.sp
+-If you specify
+-\fB\-s /home/mysrc\fR
+-and the class is called
+-\fBcom\&.mypackage\&.MyClass\fR, then the source file is put in
+-\fB/home/mysrc/com/mypackage/MyClass\&.java\fR\&.
+-.RE
+-.PP
+-\-source \fIrelease\fR
+-.RS 4
+-Specifies the version of source code accepted\&. The following values for
+-\fBrelease\fR
+-are allowed:
+-.PP
+-1\&.3
+-.RS 4
+-The compiler does not support assertions, generics, or other language features introduced after Java SE 1\&.3\&.
+-.RE
+-.PP
+-1\&.4
+-.RS 4
+-The compiler accepts code containing assertions, which were introduced in Java SE 1\&.4\&.
+-.RE
+-.PP
+-1\&.5
+-.RS 4
+-The compiler accepts code containing generics and other language features introduced in Java SE 5\&.
+-.RE
+-.PP
+-5
+-.RS 4
+-Synonym for 1\&.5\&.
+-.RE
+-.PP
+-1\&.6
+-.RS 4
+-No language changes were introduced in Java SE 6\&. However, encoding errors in source files are now reported as errors instead of warnings as in earlier releases of Java Platform, Standard Edition\&.
+-.RE
+-.PP
+-6
+-.RS 4
+-Synonym for 1\&.6\&.
+-.RE
+-.PP
+-1\&.7
+-.RS 4
+-The compiler accepts code with features introduced in Java SE 7\&.
+-.RE
+-.PP
+-7
+-.RS 4
+-Synonym for 1\&.7\&.
+-.RE
+-.PP
+-1\&.8
+-.RS 4
+-This is the default value\&. The compiler accepts code with features introduced in Java SE 8\&.
+-.RE
+-.PP
+-8
+-.RS 4
+-Synonym for 1\&.8\&.
+-.RE
+-.RE
+-.PP
+-\-sourcepath \fIsourcepath\fR
+-.RS 4
+-Specifies the source code path to search for class or interface definitions\&. As with the user class path, source path entries are separated by colons (:) on Oracle Solaris and semicolons on Windows and can be directories, JAR archives, or ZIP archives\&. If packages are used, then the local path name within the directory or archive must reflect the package name\&.
+-.sp
+-\fBNote:\fR
+-Classes found through the class path might be recompiled when their source files are also found\&. See Searching for Types\&.
+-.RE
+-.PP
+-\-verbose
+-.RS 4
+-Uses verbose output, which includes information about each class loaded and each source file compiled\&.
+-.RE
+-.PP
+-\-version
+-.RS 4
+-Prints release information\&.
+-.RE
+-.PP
+-\-werror
+-.RS 4
+-Terminates compilation when warnings occur\&.
+-.RE
+-.PP
+-\-X
+-.RS 4
+-Displays information about nonstandard options and exits\&.
+-.RE
+-.SS "Cross\-Compilation Options"
+-.PP
+-By default, classes are compiled against the bootstrap and extension classes of the platform that
+-\fBjavac\fR
+-shipped with\&. But
+-\fBjavac\fR
+-also supports cross\-compiling, where classes are compiled against a bootstrap and extension classes of a different Java platform implementation\&. It is important to use the
+-\fB\-bootclasspath\fR
+-and
+-\fB\-extdirs\fR
+-options when cross\-compiling\&.
+-.PP
+-\-target \fIversion\fR
+-.RS 4
+-Generates class files that target a specified release of the virtual machine\&. Class files will run on the specified target and on later releases, but not on earlier releases of the JVM\&. Valid targets are 1\&.1, 1\&.2, 1\&.3, 1\&.4, 1\&.5 (also 5), 1\&.6 (also 6), 1\&.7 (also 7), and 1\&.8 (also 8)\&.
+-.sp
+-The default for the
+-\fB\-target\fR
+-option depends on the value of the
+-\fB\-source\fR
+-option:
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is not specified, then the value of the
+-\fB\-target\fR
+-option is 1\&.8
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is 1\&.2, then the value of the
+-\fB\-target\fR
+-option is 1\&.4
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is 1\&.3, then the value of the
+-\fB\-target\fR
+-option is 1\&.4
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is 1\&.5, then the value of the
+-\fB\-target\fR
+-option is 1\&.8
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is 1\&.6, then the value of the
+-\fB\-target\fR
+-is option 1\&.8
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is 1\&.7, then the value of the
+-\fB\-target\fR
+-is option 1\&.8
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-For all other values of the
+-\fB\-source\fR
+-option, the value of the
+-\fB\-target\fR
+-option is the value of the
+-\fB\-source\fR
+-option\&.
+-.RE
+-.RE
+-.PP
+-\-bootclasspath \fIbootclasspath\fR
+-.RS 4
+-Cross\-compiles against the specified set of boot classes\&. As with the user class path, boot class path entries are separated by colons (:) and can be directories, JAR archives, or ZIP archives\&.
+-.RE
+-.SS "Compact Profile Option"
+-.PP
+-Beginning with JDK 8, the
+-\fBjavac\fR
+-compiler supports compact profiles\&. With compact profiles, applications that do not require the entire Java platform can be deployed and run with a smaller footprint\&. The compact profiles feature could be used to shorten the download time for applications from app stores\&. This feature makes for more compact deployment of Java applications that bundle the JRE\&. This feature is also useful in small devices\&.
+-.PP
+-The supported profile values are
+-\fBcompact1\fR,
+-\fBcompact2\fR, and
+-\fBcompact3\fR\&. These are additive layers\&. Each higher\-numbered compact profile contains all of the APIs in profiles with smaller number names\&.
+-.PP
+-\-profile
+-.RS 4
+-When using compact profiles, this option specifies the profile name when compiling\&. For example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-profile compact1 Hello\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-javac does not compile source code that uses any Java SE APIs that is not in the specified profile\&. Here is an example of the error message that results from attempting to compile such source code:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBcd jdk1\&.8\&.0/bin\fR
+-\fB\&./javac \-profile compact1 Paint\&.java\fR
+-\fBPaint\&.java:5: error: Applet is not available in profile \*(Aqcompact1\*(Aq\fR
+-\fBimport java\&.applet\&.Applet;\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-In this example, you can correct the error by modifying the source to not use the
+-\fBApplet\fR
+-class\&. You could also correct the error by compiling without the \-profile option\&. Then the compilation would be run against the full set of Java SE APIs\&. (None of the compact profiles include the
+-\fBApplet\fR
+-class\&.)
+-.sp
+-An alternative way to compile with compact profiles is to use the
+-\fB\-bootclasspath\fR
+-option to specify a path to an
+-\fBrt\&.jar\fR
+-file that specifies a profile\*(Aqs image\&. Using the
+-\fB\-profile\fR
+-option instead does not require a profile image to be present on the system at compile time\&. This is useful when cross\-compiling\&.
+-.RE
+-.SS "Nonstandard Options"
+-.PP
+-\-Xbootclasspath/p:\fIpath\fR
+-.RS 4
+-Adds a suffix to the bootstrap class path\&.
+-.RE
+-.PP
+-\-Xbootclasspath/a:\fIpath\fR
+-.RS 4
+-Adds a prefix to the bootstrap class path\&.
+-.RE
+-.PP
+-\-Xbootclasspath/:\fIpath\fR
+-.RS 4
+-Overrides the location of the bootstrap class files\&.
+-.RE
+-.PP
+-\-Xdoclint:[\-]\fIgroup\fR [\fI/access\fR]
+-.RS 4
+-Enables or disables specific groups of checks, where
+-\fIgroup\fR
+-is one of the following values:
+-\fBaccessibility\fR,
+-\fBsyntax\fR,
+-\fBreference\fR,
+-\fBhtml\fR
+-or
+-\fBmissing\fR\&. For more information about these groups of checks see the
+-\fB\-Xdoclint\fR
+-option of the
+-\fBjavadoc\fR
+-command\&. The
+-\fB\-Xdoclint\fR
+-option is disabled by default in the
+-\fBjavac\fR
+-command\&.
+-.sp
+-The variable
+-\fIaccess\fR
+-specifies the minimum visibility level of classes and members that the
+-\fB\-Xdoclint\fR
+-option checks\&. It can have one of the following values (in order of most to least visible) :
+-\fBpublic\fR,
+-\fBprotected\fR,
+-\fBpackage\fR
+-and
+-\fBprivate\fR\&. For example, the following option checks classes and members (with all groups of checks) that have the access level protected and higher (which includes protected, package and public):
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB\-Xdoclint:all/protected\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The following option enables all groups of checks for all access levels, except it will not check for HTML errors for classes and members that have access level package and higher (which includes package and public):
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB\-Xdoclint:all,\-html/package\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-\-Xdoclint:none
+-.RS 4
+-Disables all groups of checks\&.
+-.RE
+-.PP
+-\-Xdoclint:all[\fI/access\fR]
+-.RS 4
+-Enables all groups of checks\&.
+-.RE
+-.PP
+-\-Xlint
+-.RS 4
+-Enables all recommended warnings\&. In this release, enabling all available warnings is recommended\&.
+-.RE
+-.PP
+-\-Xlint:all
+-.RS 4
+-Enables all recommended warnings\&. In this release, enabling all available warnings is recommended\&.
+-.RE
+-.PP
+-\-Xlint:none
+-.RS 4
+-Disables all warnings\&.
+-.RE
+-.PP
+-\-Xlint:\fIname\fR
+-.RS 4
+-Disables warning name\&. See Enable or Disable Warnings with the \-Xlint Option for a list of warnings you can disable with this option\&.
+-.RE
+-.PP
+-\-Xlint:\fI\-name\fR
+-.RS 4
+-Disables warning name\&. See Enable or Disable Warnings with the \-Xlint Option with the
+-\fB\-Xlint\fR
+-option to get a list of warnings that you can disable with this option\&.
+-.RE
+-.PP
+-\-Xmaxerrs \fInumber\fR
+-.RS 4
+-Sets the maximum number of errors to print\&.
+-.RE
+-.PP
+-\-Xmaxwarns \fInumber\fR
+-.RS 4
+-Sets the maximum number of warnings to print\&.
+-.RE
+-.PP
+-\-Xstdout \fIfilename\fR
+-.RS 4
+-Sends compiler messages to the named file\&. By default, compiler messages go to
+-\fBSystem\&.err\fR\&.
+-.RE
+-.PP
+-\-Xprefer:[\fInewer,source\fR]
+-.RS 4
+-Specifies which file to read when both a source file and class file are found for a type\&. (See Searching for Types)\&. If the
+-\fB\-Xprefer:newer\fR
+-option is used, then it reads the newer of the source or class file for a type (default)\&. If the
+-\fB\-Xprefer:source\fR
+-option is used, then it reads the source file\&. Use \-\fBXprefer:source\fR
+-when you want to be sure that any annotation processors can access annotations declared with a retention policy of
+-\fBSOURCE\fR\&.
+-.RE
+-.PP
+-\-Xpkginfo:[\fIalways\fR,\fIlegacy\fR,\fInonempty\fR]
+-.RS 4
+-Control whether javac generates
+-\fBpackage\-info\&.class\fR
+-files from package\-info\&.java files\&. Possible mode arguments for this option include the following\&.
+-.PP
+-always
+-.RS 4
+-Always generate a
+-\fBpackage\-info\&.class\fR
+-file for every
+-\fBpackage\-info\&.java\fR
+-file\&. This option may be useful if you use a build system such as Ant, which checks that each
+-\fB\&.java\fR
+-file has a corresponding
+-\fB\&.class\fR
+-file\&.
+-.RE
+-.PP
+-legacy
+-.RS 4
+-Generate a
+-\fBpackage\-info\&.class\fR
+-file only if package\-info\&.java contains annotations\&. Don\*(Aqt generate a
+-\fBpackage\-info\&.class\fR
+-file if package\-info\&.java only contains comments\&.
+-.sp
+-\fBNote:\fR
+-A
+-\fBpackage\-info\&.class\fR
+-file might be generated but be empty if all the annotations in the package\-info\&.java file have
+-\fBRetentionPolicy\&.SOURCE\fR\&.
+-.RE
+-.PP
+-nonempty
+-.RS 4
+-Generate a
+-\fBpackage\-info\&.class\fR
+-file only if package\-info\&.java contains annotations with
+-\fBRetentionPolicy\&.CLASS\fR
+-or
+-\fBRetentionPolicy\&.RUNTIME\fR\&.
+-.RE
+-.RE
+-.PP
+-\-Xprint
+-.RS 4
+-Prints a textual representation of specified types for debugging purposes\&. Perform neither annotation processing nor compilation\&. The format of the output could change\&.
+-.RE
+-.PP
+-\-XprintProcessorInfo
+-.RS 4
+-Prints information about which annotations a processor is asked to process\&.
+-.RE
+-.PP
+-\-XprintRounds
+-.RS 4
+-Prints information about initial and subsequent annotation processing rounds\&.
+-.RE
+-.SH "ENABLE OR DISABLE WARNINGS WITH THE -XLINT OPTION"
+-.PP
+-Enable warning
+-\fIname\fR
+-with the
+-\fB\-Xlint:name\fR
+-option, where
+-\fBname\fR
+-is one of the following warning names\&. Note that you can disable a warning with the
+-\fB\-Xlint:\-name:\fR
+-option\&.
+-.PP
+-cast
+-.RS 4
+-Warns about unnecessary and redundant casts, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBString s = (String) "Hello!"\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-classfile
+-.RS 4
+-Warns about issues related to class file contents\&.
+-.RE
+-.PP
+-deprecation
+-.RS 4
+-Warns about the use of deprecated items, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjava\&.util\&.Date myDate = new java\&.util\&.Date();\fR
+-\fBint currentDay = myDate\&.getDay();\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The method
+-\fBjava\&.util\&.Date\&.getDay\fR
+-has been deprecated since JDK 1\&.1
+-.RE
+-.PP
+-dep\-ann
+-.RS 4
+-Warns about items that are documented with an
+-\fB@deprecated\fR
+-Javadoc comment, but do not have a
+-\fB@Deprecated\fR
+-annotation, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB/**\fR
+-\fB * @deprecated As of Java SE 7, replaced by {@link #newMethod()}\fR
+-\fB */\fR
+-\fBpublic static void deprecatedMethood() { }\fR
+-\fBpublic static void newMethod() { }\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-divzero
+-.RS 4
+-Warns about division by the constant integer 0, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBint divideByZero = 42 / 0;\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-empty
+-.RS 4
+-Warns about empty statements after
+-\fBif \fRstatements, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBclass E {\fR
+-\fB void m() {\fR
+-\fB if (true) ;\fR
+-\fB }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-fallthrough
+-.RS 4
+-Checks the switch blocks for fall\-through cases and provides a warning message for any that are found\&. Fall\-through cases are cases in a switch block, other than the last case in the block, whose code does not include a break statement, allowing code execution to fall through from that case to the next case\&. For example, the code following the case 1 label in this switch block does not end with a break statement:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBswitch (x) {\fR
+-\fBcase 1:\fR
+-\fB System\&.out\&.println("1");\fR
+-\fB // No break statement here\&.\fR
+-\fBcase 2:\fR
+-\fB System\&.out\&.println("2");\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-If the
+-\fB\-Xlint:fallthrough\fR
+-option was used when compiling this code, then the compiler emits a warning about possible fall\-through into case, with the line number of the case in question\&.
+-.RE
+-.PP
+-finally
+-.RS 4
+-Warns about
+-\fBfinally\fR
+-clauses that cannot complete normally, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpublic static int m() {\fR
+-\fB try {\fR
+-\fB throw new NullPointerException();\fR
+-\fB } catch (NullPointerException(); {\fR
+-\fB System\&.err\&.println("Caught NullPointerException\&.");\fR
+-\fB return 1;\fR
+-\fB } finally {\fR
+-\fB return 0;\fR
+-\fB }\fR
+-\fB }\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The compiler generates a warning for the
+-\fBfinally\fR
+-block in this example\&. When the
+-\fBint\fR
+-method is called, it returns a value of 0\&. A
+-\fBfinally\fR
+-block executes when the
+-\fBtry\fR
+-block exits\&. In this example, when control is transferred to the
+-\fBcatch\fR
+-block, the
+-\fBint\fR
+-method exits\&. However, the
+-\fBfinally\fR
+-block must execute, so it is executed, even though control was transferred outside the method\&.
+-.RE
+-.PP
+-options
+-.RS 4
+-Warns about issues that related to the use of command\-line options\&. See Cross\-Compilation Options\&.
+-.RE
+-.PP
+-overrides
+-.RS 4
+-Warns about issues regarding method overrides\&. For example, consider the following two classes:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpublic class ClassWithVarargsMethod {\fR
+-\fB void varargsMethod(String\&.\&.\&. s) { }\fR
+-\fB}\fR
+-
+-\fBpublic class ClassWithOverridingMethod extends ClassWithVarargsMethod {\fR
+-\fB @Override\fR
+-\fB void varargsMethod(String[] s) { }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The compiler generates a warning similar to the following:\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBwarning: [override] varargsMethod(String[]) in ClassWithOverridingMethod \fR
+-\fBoverrides varargsMethod(String\&.\&.\&.) in ClassWithVarargsMethod; overriding\fR
+-\fBmethod is missing \*(Aq\&.\&.\&.\*(Aq\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-When the compiler encounters a
+-\fBvarargs\fR
+-method, it translates the
+-\fBvarargs\fR
+-formal parameter into an array\&. In the method
+-\fBClassWithVarargsMethod\&.varargsMethod\fR, the compiler translates the
+-\fBvarargs\fR
+-formal parameter
+-\fBString\&.\&.\&. s\fR
+-to the formal parameter
+-\fBString[] s\fR, an array, which matches the formal parameter of the method
+-\fBClassWithOverridingMethod\&.varargsMethod\fR\&. Consequently, this example compiles\&.
+-.RE
+-.PP
+-path
+-.RS 4
+-Warns about invalid path elements and nonexistent path directories on the command line (with regard to the class path, the source path, and other paths)\&. Such warnings cannot be suppressed with the
+-\fB@SuppressWarnings\fR
+-annotation, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-Xlint:path \-classpath /nonexistentpath Example\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-processing
+-.RS 4
+-Warn about issues regarding annotation processing\&. The compiler generates this warning when you have a class that has an annotation, and you use an annotation processor that cannot handle that type of exception\&. For example, the following is a simple annotation processor:
+-.sp
+-\fBSource file AnnocProc\&.java\fR:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBimport java\&.util\&.*;\fR
+-\fBimport javax\&.annotation\&.processing\&.*;\fR
+-\fBimport javax\&.lang\&.model\&.*;\fR
+-\fBimport\&.javaz\&.lang\&.model\&.element\&.*;\fR
+-
+-\fB@SupportedAnnotationTypes("NotAnno")\fR
+-\fBpublic class AnnoProc extends AbstractProcessor {\fR
+-\fB public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv){\fR
+-\fB return true;\fR
+-\fB }\fR
+-
+-\fB public SourceVersion getSupportedSourceVersion() {\fR
+-\fB return SourceVersion\&.latest();\fR
+-\fB }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-\fBSource file AnnosWithoutProcessors\&.java\fR:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB@interface Anno { }\fR
+-\fB \fR
+-\fB@Anno\fR
+-\fBclass AnnosWithoutProcessors { }\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The following commands compile the annotation processor
+-\fBAnnoProc\fR, then run this annotation processor against the source file
+-\fBAnnosWithoutProcessors\&.java\fR:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac AnnoProc\&.java\fR
+-\fBjavac \-cp \&. \-Xlint:processing \-processor AnnoProc \-proc:only AnnosWithoutProcessors\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-When the compiler runs the annotation processor against the source file
+-\fBAnnosWithoutProcessors\&.java\fR, it generates the following warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBwarning: [processing] No processor claimed any of these annotations: Anno\fR
+-\fB \fR
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-To resolve this issue, you can rename the annotation defined and used in the class
+-\fBAnnosWithoutProcessors\fR
+-from
+-\fBAnno\fR
+-to
+-\fBNotAnno\fR\&.
+-.RE
+-.PP
+-rawtypes
+-.RS 4
+-Warns about unchecked operations on raw types\&. The following statement generates a
+-\fBrawtypes\fR
+-warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBvoid countElements(List l) { \&.\&.\&. }\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The following example does not generate a
+-\fBrawtypes\fR
+-warning
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBvoid countElements(List<?> l) { \&.\&.\&. }\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-\fBList\fR
+-is a raw type\&. However,
+-\fBList<?>\fR
+-is an unbounded wildcard parameterized type\&. Because
+-\fBList\fR
+-is a parameterized interface, always specify its type argument\&. In this example, the
+-\fBList\fR
+-formal argument is specified with an unbounded wildcard (\fB?\fR) as its formal type parameter, which means that the
+-\fBcountElements\fR
+-method can accept any instantiation of the
+-\fBList\fR
+-interface\&.
+-.RE
+-.PP
+-Serial
+-.RS 4
+-Warns about missing
+-\fBserialVersionUID\fR
+-definitions on serializable classes, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpublic class PersistentTime implements Serializable\fR
+-\fB{\fR
+-\fB private Date time;\fR
+-\fB \fR
+-\fB public PersistentTime() {\fR
+-\fB time = Calendar\&.getInstance()\&.getTime();\fR
+-\fB }\fR
+-\fB \fR
+-\fB public Date getTime() {\fR
+-\fB return time;\fR
+-\fB }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The compiler generates the following warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBwarning: [serial] serializable class PersistentTime has no definition of\fR
+-\fBserialVersionUID\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-If a serializable class does not explicitly declare a field named
+-\fBserialVersionUID\fR, then the serialization runtime environment calculates a default
+-\fBserialVersionUID\fR
+-value for that class based on various aspects of the class, as described in the Java Object Serialization Specification\&. However, it is strongly recommended that all serializable classes explicitly declare
+-\fBserialVersionUID\fR
+-values because the default process of computing
+-\fBserialVersionUID\fR
+-vales is highly sensitive to class details that can vary depending on compiler implementations, and as a result, might cause an unexpected
+-\fBInvalidClassExceptions\fR
+-during deserialization\&. To guarantee a consistent
+-\fBserialVersionUID\fR
+-value across different Java compiler implementations, a serializable class must declare an explicit
+-\fBserialVersionUID\fR
+-value\&.
+-.RE
+-.PP
+-static
+-.RS 4
+-Warns about issues relating to the use of statics, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBclass XLintStatic {\fR
+-\fB static void m1() { }\fR
+-\fB void m2() { this\&.m1(); }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The compiler generates the following warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBwarning: [static] static method should be qualified by type name, \fR
+-\fBXLintStatic, instead of by an expression\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-To resolve this issue, you can call the
+-\fBstatic\fR
+-method
+-\fBm1\fR
+-as follows:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBXLintStatic\&.m1();\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Alternately, you can remove the
+-\fBstatic\fR
+-keyword from the declaration of the method
+-\fBm1\fR\&.
+-.RE
+-.PP
+-try
+-.RS 4
+-Warns about issues relating to use of
+-\fBtry\fR
+-blocks, including try\-with\-resources statements\&. For example, a warning is generated for the following statement because the resource
+-\fBac\fR
+-declared in the
+-\fBtry\fR
+-block is not used:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBtry ( AutoCloseable ac = getResource() ) { // do nothing}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-unchecked
+-.RS 4
+-Gives more detail for unchecked conversion warnings that are mandated by the Java Language Specification, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBList l = new ArrayList<Number>();\fR
+-\fBList<String> ls = l; // unchecked warning\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-During type erasure, the types
+-\fBArrayList<Number>\fR
+-and
+-\fBList<String>\fR
+-become
+-\fBArrayList\fR
+-and
+-\fBList\fR, respectively\&.
+-.sp
+-The
+-\fBls\fR
+-command has the parameterized type
+-\fBList<String>\fR\&. When the
+-\fBList\fR
+-referenced by
+-\fBl\fR
+-is assigned to
+-\fBls\fR, the compiler generates an unchecked warning\&. At compile time, the compiler and JVM cannot determine whether
+-\fBl\fR
+-refers to a
+-\fBList<String>\fR
+-type\&. In this case,
+-\fBl\fR
+-does not refer to a
+-\fBList<String>\fR
+-type\&. As a result, heap pollution occurs\&.
+-.sp
+-A heap pollution situation occurs when the
+-\fBList\fR
+-object
+-\fBl\fR, whose static type is
+-\fBList<Number>\fR, is assigned to another
+-\fBList\fR
+-object,
+-\fBls\fR, that has a different static type,
+-\fBList<String>\fR\&. However, the compiler still allows this assignment\&. It must allow this assignment to preserve backward compatibility with releases of Java SE that do not support generics\&. Because of type erasure,
+-\fBList<Number>\fR
+-and
+-\fBList<String>\fR
+-both become
+-\fBList\fR\&. Consequently, the compiler allows the assignment of the object
+-\fBl\fR\fB,\fR
+-which has a raw type of
+-\fBList\fR, to the object
+-\fBls\fR\&.
+-.RE
+-.PP
+-varargs
+-.RS 4
+-Warns about unsafe usages of variable arguments (\fBvarargs\fR) methods, in particular, those that contain non\-reifiable arguments, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpublic class ArrayBuilder {\fR
+-\fB public static <T> void addToList (List<T> listArg, T\&.\&.\&. elements) {\fR
+-\fB for (T x : elements) {\fR
+-\fB listArg\&.add(x);\fR
+-\fB }\fR
+-\fB }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-\fBNote:\fR
+-A non\-reifiable type is a type whose type information is not fully available at runtime\&.
+-.sp
+-The compiler generates the following warning for the definition of the method
+-\fBArrayBuilder\&.addToList\fR
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBwarning: [varargs] Possible heap pollution from parameterized vararg type T\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-When the compiler encounters a varargs method, it translates the
+-\fBvarargs\fR
+-formal parameter into an array\&. However, the Java programming language does not permit the creation of arrays of parameterized types\&. In the method
+-\fBArrayBuilder\&.addToList\fR, the compiler translates the
+-\fBvarargs\fR
+-formal parameter
+-\fBT\&.\&.\&.\fR
+-elements to the formal parameter
+-\fBT[]\fR
+-elements, an array\&. However, because of type erasure, the compiler converts the
+-\fBvarargs\fR
+-formal parameter to
+-\fBObject[]\fR
+-elements\&. Consequently, there is a possibility of heap pollution\&.
+-.RE
+-.SH "COMMAND-LINE ARGUMENT FILES"
+-.PP
+-To shorten or simplify the
+-\fBjavac\fR
+-command, you can specify one or more files that contain arguments to the
+-\fBjavac\fR
+-command (except
+-\fB\-J\fR
+-options)\&. This enables you to create
+-\fBjavac\fR
+-commands of any length on any operating system\&.
+-.PP
+-An argument file can include
+-\fBjavac\fR
+-options and source file names in any combination\&. The arguments within a file can be separated by spaces or new line characters\&. If a file name contains embedded spaces, then put the whole file name in double quotation marks\&.
+-.PP
+-File Names within an argument file are relative to the current directory, not the location of the argument file\&. Wild cards (*) are not allowed in these lists (such as for specifying
+-\fB*\&.java\fR)\&. Use of the at sign (@) to recursively interpret files is not supported\&. The
+-\fB\-J\fR
+-options are not supported because they are passed to the launcher, which does not support argument files\&.
+-.PP
+-When executing the
+-\fBjavac\fR
+-command, pass in the path and name of each argument file with the at sign (@) leading character\&. When the
+-\fBjavac\fR
+-command encounters an argument beginning with the at sign (@), it expands the contents of that file into the argument list\&.
+-.PP
+-\fBExample 1\fR
+-.br
+-Single Argument File
+-.RS 4
+-You could use a single argument file named
+-\fBargfile\fR
+-to hold all
+-\fBjavac\fR
+-arguments:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac @argfile\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-This argument file could contain the contents of both files shown in Example 2
+-.RE
+-.PP
+-\fBExample 2\fR
+-.br
+-Two Argument Files
+-.RS 4
+-You can create two argument files: one for the
+-\fBjavac\fR
+-options and the other for the source file names\&. Note that the following lists have no line\-continuation characters\&.
+-.sp
+-Create a file named options that contains the following:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB\-d classes\fR
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB\-g\fR
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB\-sourcepath /java/pubs/ws/1\&.3/src/share/classes\fR
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Create a file named classes that contains the following:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBMyClass1\&.java\fR
+-\fBMyClass2\&.java\fR
+-\fBMyClass3\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Then, run the
+-\fBjavac\fR
+-command as follows:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac @options @classes\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-\fBExample 3\fR
+-.br
+-Argument Files with Paths
+-.RS 4
+-The argument files can have paths, but any file names inside the files are relative to the current working directory (not
+-\fBpath1\fR
+-or
+-\fBpath2\fR):
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac @path1/options @path2/classes\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.SH "ANNOTATION PROCESSING"
+-.PP
+-The
+-\fBjavac\fR
+-command provides direct support for annotation processing, superseding the need for the separate annotation processing command,
+-\fBapt\fR\&.
+-.PP
+-The API for annotation processors is defined in the
+-\fBjavax\&.annotation\&.processing\fR
+-and j\fBavax\&.lang\&.model\fR
+-packages and subpackages\&.
+-.SS "How Annotation Processing Works"
+-.PP
+-Unless annotation processing is disabled with the
+-\fB\-proc:none\fR
+-option, the compiler searches for any annotation processors that are available\&. The search path can be specified with the
+-\fB\-processorpath\fR
+-option\&. If no path is specified, then the user class path is used\&. Processors are located by means of service provider\-configuration files named
+-\fBMETA\-INF/services/javax\&.annotation\&.processing\fR\&.Processor on the search path\&. Such files should contain the names of any annotation processors to be used, listed one per line\&. Alternatively, processors can be specified explicitly, using the
+-\fB\-processor\fR
+-option\&.
++The API for annotation processors is defined in the \f3javax\&.annotation\&.processing\fR and j\f3avax\&.lang\&.model\fR packages and subpackages\&.
++.SS HOW\ ANNOTATION\ PROCESSING\ WORKS
++Unless annotation processing is disabled with the \f3-proc:none\fR option, the compiler searches for any annotation processors that are available\&. The search path can be specified with the \f3-processorpath\fR option\&. If no path is specified, then the user class path is used\&. Processors are located by means of service provider-configuration files named \f3META-INF/services/javax\&.annotation\&.processing\fR\&.Processor on the search path\&. Such files should contain the names of any annotation processors to be used, listed one per line\&. Alternatively, processors can be specified explicitly, using the \f3-processor\fR option\&.
+ .PP
+ After scanning the source files and classes on the command line to determine what annotations are present, the compiler queries the processors to determine what annotations they process\&. When a match is found, the processor is called\&. A processor can claim the annotations it processes, in which case no further attempt is made to find any processors for those annotations\&. After all of the annotations are claimed, the compiler does not search for additional processors\&.
+ .PP
+ If any processors generate new source files, then another round of annotation processing occurs: Any newly generated source files are scanned, and the annotations processed as before\&. Any processors called on previous rounds are also called on all subsequent rounds\&. This continues until no new source files are generated\&.
+ .PP
+-After a round occurs where no new source files are generated, the annotation processors are called one last time, to give them a chance to complete any remaining work\&. Finally, unless the
+-\fB\-proc:only\fR
+-option is used, the compiler compiles the original and all generated source files\&.
+-.SS "Implicitly Loaded Source Files"
+-.PP
+-To compile a set of source files, the compiler might need to implicitly load additional source files\&. See Searching for Types\&. Such files are currently not subject to annotation processing\&. By default, the compiler gives a warning when annotation processing occurred and any implicitly loaded source files are compiled\&. The
+-\fB\-implicit\fR
+-option provides a way to suppress the warning\&.
+-.SH "SEARCHING FOR TYPES"
+-.PP
++After a round occurs where no new source files are generated, the annotation processors are called one last time, to give them a chance to complete any remaining work\&. Finally, unless the \f3-proc:only\fR option is used, the compiler compiles the original and all generated source files\&.
++.SS IMPLICITLY\ LOADED\ SOURCE\ FILES
++To compile a set of source files, the compiler might need to implicitly load additional source files\&. See Searching for Types\&. Such files are currently not subject to annotation processing\&. By default, the compiler gives a warning when annotation processing occurred and any implicitly loaded source files are compiled\&. The \f3-implicit\fR option provides a way to suppress the warning\&.
++.SH SEARCHING\ FOR\ TYPES
+ To compile a source file, the compiler often needs information about a type, but the type definition is not in the source files specified on the command line\&. The compiler needs type information for every class or interface used, extended, or implemented in the source file\&. This includes classes and interfaces not explicitly mentioned in the source file, but that provide information through inheritance\&.
+ .PP
+-For example, when you create a subclass
+-\fBjava\&.applet\&.Applet\fR, you are also using the ancestor classes of
+-\fBApplet\fR:
+-\fBjava\&.awt\&.Panel\fR,
+-\fBjava\&.awt\&.Container\fR,
+-\fBjava\&.awt\&.Component\fR, and
+-\fBjava\&.lang\&.Object\fR\&.
++For example, when you create a subclass \f3java\&.applet\&.Applet\fR, you are also using the ancestor classes of \f3Applet\fR: \f3java\&.awt\&.Panel\fR, \f3java\&.awt\&.Container\fR, \f3java\&.awt\&.Component\fR, and \f3java\&.lang\&.Object\fR\&.
+ .PP
+-When the compiler needs type information, it searches for a source file or class file that defines the type\&. The compiler searches for class files first in the bootstrap and extension classes, then in the user class path (which by default is the current directory)\&. The user class path is defined by setting the
+-\fBCLASSPATH\fR
+-environment variable or by using the
+-\fB\-classpath\fR
+-option\&.
++When the compiler needs type information, it searches for a source file or class file that defines the type\&. The compiler searches for class files first in the bootstrap and extension classes, then in the user class path (which by default is the current directory)\&. The user class path is defined by setting the \f3CLASSPATH\fR environment variable or by using the \f3-classpath\fR option\&.
+ .PP
+-If you set the
+-\fB\-sourcepath\fR
+-option, then the compiler searches the indicated path for source files\&. Otherwise, the compiler searches the user class path for both class files and source files\&.
++If you set the \f3-sourcepath\fR option, then the compiler searches the indicated path for source files\&. Otherwise, the compiler searches the user class path for both class files and source files\&.
+ .PP
+-You can specify different bootstrap or extension classes with the
+-\fB\-bootclasspath\fR
+-and the
+-\fB\-extdirs\fR
+-options\&. See Cross\-Compilation Options\&.
++You can specify different bootstrap or extension classes with the \f3-bootclasspath\fR and the \f3-extdirs\fR options\&. See Cross-Compilation Options\&.
+ .PP
+-A successful type search may produce a class file, a source file, or both\&. If both are found, then you can use the
+-\fB\-Xprefer\fR
+-option to instruct the compiler which to use\&. If
+-\fBnewer\fR
+-is specified, then the compiler uses the newer of the two files\&. If
+-\fBsource\fR
+-is specified, the compiler uses the source file\&. The default is
+-\fBnewer\fR\&.
++A successful type search may produce a class file, a source file, or both\&. If both are found, then you can use the \f3-Xprefer\fR option to instruct the compiler which to use\&. If \f3newer\fR is specified, then the compiler uses the newer of the two files\&. If \f3source\fR is specified, the compiler uses the source file\&. The default is \f3newer\fR\&.
+ .PP
+-If a type search finds a source file for a required type, either by itself, or as a result of the setting for the
+-\fB\-Xprefer\fR
+-option, then the compiler reads the source file to get the information it needs\&. By default the compiler also compiles the source file\&. You can use the
+-\fB\-implicit\fR
+-option to specify the behavior\&. If
+-\fBnone\fR
+-is specified, then no class files are generated for the source file\&. If
+-\fBclass\fR
+-is specified, then class files are generated for the source file\&.
++If a type search finds a source file for a required type, either by itself, or as a result of the setting for the \f3-Xprefer\fR option, then the compiler reads the source file to get the information it needs\&. By default the compiler also compiles the source file\&. You can use the \f3-implicit\fR option to specify the behavior\&. If \f3none\fR is specified, then no class files are generated for the source file\&. If \f3class\fR is specified, then class files are generated for the source file\&.
+ .PP
+-The compiler might not discover the need for some type information until after annotation processing completes\&. When the type information is found in a source file and no
+-\fB\-implicit\fR
+-option is specified, the compiler gives a warning that the file is being compiled without being subject to annotation processing\&. To disable the warning, either specify the file on the command line (so that it will be subject to annotation processing) or use the
+-\fB\-implicit\fR
+-option to specify whether or not class files should be generated for such source files\&.
+-.SH "PROGRAMMATIC INTERFACE"
++The compiler might not discover the need for some type information until after annotation processing completes\&. When the type information is found in a source file and no \f3-implicit\fR option is specified, the compiler gives a warning that the file is being compiled without being subject to annotation processing\&. To disable the warning, either specify the file on the command line (so that it will be subject to annotation processing) or use the \f3-implicit\fR option to specify whether or not class files should be generated for such source files\&.
++.SH PROGRAMMATIC\ INTERFACE
++The \f3javac\fR command supports the new Java Compiler API defined by the classes and interfaces in the \f3javax\&.tools\fR package\&.
++.SS EXAMPLE
++To compile as though providing command-line arguments, use the following syntax:
++.sp
++.nf
++\f3JavaCompiler javac = ToolProvider\&.getSystemJavaCompiler();\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++The example writes diagnostics to the standard output stream and returns the exit code that \f3javac\fR would give when called from the command line\&.
+ .PP
+-The
+-\fBjavac\fR
+-command supports the new Java Compiler API defined by the classes and interfaces in the
+-\fBjavax\&.tools\fR
+-package\&.
+-.SS "Example"
++You can use other methods in the \f3javax\&.tools\&.JavaCompiler\fR interface to handle diagnostics, control where files are read from and written to, and more\&.
++.SS OLD\ INTERFACE
++\fINote:\fR This API is retained for backward compatibility only\&. All new code should use the newer Java Compiler API\&.
+ .PP
+-To compile as though providing command\-line arguments, use the following syntax:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBJavaCompiler javac = ToolProvider\&.getSystemJavaCompiler();\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
++The \f3com\&.sun\&.tools\&.javac\&.Main\fR class provides two static methods to call the compiler from a program:
++.sp
++.nf
++\f3public static int compile(String[] args);\fP
++.fi
++.nf
++\f3public static int compile(String[] args, PrintWriter out);\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++The \f3args\fR parameter represents any of the command-line arguments that would typically be passed to the compiler\&.
+ .PP
+-The example writes diagnostics to the standard output stream and returns the exit code that
+-\fBjavac\fR
+-would give when called from the command line\&.
++The \f3out\fR parameter indicates where the compiler diagnostic output is directed\&.
+ .PP
+-You can use other methods in the
+-\fBjavax\&.tools\&.JavaCompiler\fR
+-interface to handle diagnostics, control where files are read from and written to, and more\&.
+-.SS "Old Interface"
++The \f3return\fR value is equivalent to the \f3exit\fR value from \f3javac\fR\&.
+ .PP
+-\fBNote:\fR
+-This API is retained for backward compatibility only\&. All new code should use the newer Java Compiler API\&.
++\fINote:\fR All other classes and methods found in a package with names that start with \f3com\&.sun\&.tools\&.javac\fR (subpackages of \f3com\&.sun\&.tools\&.javac\fR) are strictly internal and subject to change at any time\&.
++.SH EXAMPLES
++\f3Example 1 Compile a Simple Program\fR
+ .PP
+-The
+-\fBcom\&.sun\&.tools\&.javac\&.Main\fR
+-class provides two static methods to call the compiler from a program:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpublic static int compile(String[] args);\fR
+-\fBpublic static int compile(String[] args, PrintWriter out);\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
++This example shows how to compile the \f3Hello\&.java\fR source file in the greetings directory\&. The class defined in \f3Hello\&.java\fR is called \f3greetings\&.Hello\fR\&. The greetings directory is the package directory both for the source file and the class file and is underneath the current directory\&. This makes it possible to use the default user class path\&. It also makes it unnecessary to specify a separate destination directory with the \f3-d\fR option\&.
+ .PP
+-The
+-\fBargs\fR
+-parameter represents any of the command\-line arguments that would typically be passed to the compiler\&.
++The source code in \f3Hello\&.java\fR:
++.sp
++.nf
++\f3package greetings;\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3public class Hello {\fP
++.fi
++.nf
++\f3 public static void main(String[] args) {\fP
++.fi
++.nf
++\f3 for (int i=0; i < args\&.length; i++) {\fP
++.fi
++.nf
++\f3 System\&.out\&.println("Hello " + args[i]);\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++Compile greetings\&.Hello:
++.sp
++.nf
++\f3javac greetings/Hello\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++Run \f3greetings\&.Hello\fR:
++.sp
++.nf
++\f3java greetings\&.Hello World Universe Everyone\fP
++.fi
++.nf
++\f3Hello World\fP
++.fi
++.nf
++\f3Hello Universe\fP
++.fi
++.nf
++\f3Hello Everyone\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++\f3Example 2 Compile Multiple Source Files\fR
+ .PP
+-The
+-\fBout\fR
+-parameter indicates where the compiler diagnostic output is directed\&.
++This example compiles the \f3Aloha\&.java\fR, \f3GutenTag\&.java\fR, \f3Hello\&.java\fR, and \f3Hi\&.java\fR source files in the \f3greetings\fR package\&.
++.sp
++.nf
++\f3% javac greetings/*\&.java\fP
++.fi
++.nf
++\f3% ls greetings\fP
++.fi
++.nf
++\f3Aloha\&.class GutenTag\&.class Hello\&.class Hi\&.class\fP
++.fi
++.nf
++\f3Aloha\&.java GutenTag\&.java Hello\&.java Hi\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++\f3Example 3 Specify a User Class Path\fR
+ .PP
+-The
+-\fBreturn\fR
+-value is equivalent to the
+-\fBexit\fR
+-value from
+-\fBjavac\fR\&.
++After changing one of the source files in the previous example, recompile it:
++.sp
++.nf
++\f3pwd\fP
++.fi
++.nf
++\f3/examples\fP
++.fi
++.nf
++\f3javac greetings/Hi\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++Because \f3greetings\&.Hi\fR refers to other classes in the \f3greetings\fR package, the compiler needs to find these other classes\&. The previous example works because the default user class path is the directory that contains the package directory\&. If you want to recompile this file without concern for which directory you are in, then add the examples directory to the user class path by setting \f3CLASSPATH\fR\&. This example uses the \f3-classpath\fR option\&.
++.sp
++.nf
++\f3javac \-classpath /examples /examples/greetings/Hi\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++If you change \f3greetings\&.Hi\fR to use a banner utility, then that utility also needs to be accessible through the user class path\&.
++.sp
++.nf
++\f3javac \-classpath /examples:/lib/Banners\&.jar \e\fP
++.fi
++.nf
++\f3 /examples/greetings/Hi\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++To execute a class in the \f3greetings\fR package, the program needs access to the \f3greetings\fR package, and to the classes that the \f3greetings\fR classes use\&.
++.sp
++.nf
++\f3java \-classpath /examples:/lib/Banners\&.jar greetings\&.Hi\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++\f3Example 4 Separate Source Files and Class Files\fR
+ .PP
+-\fBNote:\fR
+-All other classes and methods found in a package with names that start with
+-\fBcom\&.sun\&.tools\&.javac\fR
+-(subpackages of
+-\fBcom\&.sun\&.tools\&.javac\fR) are strictly internal and subject to change at any time\&.
+-.SH "EXAMPLES"
++The following example uses \f3javac\fR to compile code that runs on JVM 1\&.7\&.
++.sp
++.nf
++\f3javac \-source 1\&.7 \-target 1\&.7 \-bootclasspath jdk1\&.7\&.0/lib/rt\&.jar \e \fP
++.fi
++.nf
++\f3\-extdirs "" OldCode\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++The \f3-source 1\&.7\fR option specifies that release 1\&.7 (or 7) of the Java programming language be used to compile \f3OldCode\&.java\fR\&. The option \f3-target 1\&.7\fR option ensures that the generated class files are compatible with JVM 1\&.7\&. Note that in most cases, the value of the \f3-target\fR option is the value of the \f3-source\fR option; in this example, you can omit the \f3-target\fR option\&.
+ .PP
+-\fBExample 1\fR
+-.br
+-Compile a Simple Program
+-.RS 4
+-This example shows how to compile the
+-\fBHello\&.java\fR
+-source file in the greetings directory\&. The class defined in
+-\fBHello\&.java\fR
+-is called
+-\fBgreetings\&.Hello\fR\&. The greetings directory is the package directory both for the source file and the class file and is underneath the current directory\&. This makes it possible to use the default user class path\&. It also makes it unnecessary to specify a separate destination directory with the
+-\fB\-d\fR
+-option\&.
+-.sp
+-The source code in
+-\fBHello\&.java\fR:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpackage greetings;\fR
+-\fB \fR
+-\fBpublic class Hello {\fR
+-\fB public static void main(String[] args) {\fR
+-\fB for (int i=0; i < args\&.length; i++) {\fR
+-\fB System\&.out\&.println("Hello " + args[i]);\fR
+-\fB }\fR
+-\fB }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Compile greetings\&.Hello:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac greetings/Hello\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Run
+-\fBgreetings\&.Hello\fR:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjava greetings\&.Hello World Universe Everyone\fR
+-\fBHello World\fR
+-\fBHello Universe\fR
+-\fBHello Everyone\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
++You must specify the \f3-bootclasspath\fR option to specify the correct version of the bootstrap classes (the \f3rt\&.jar\fR library)\&. If not, then the compiler generates a warning:
++.sp
++.nf
++\f3javac \-source 1\&.7 OldCode\&.java\fP
++.fi
++.nf
++\f3warning: [options] bootstrap class path not set in conjunction with \fP
++.fi
++.nf
++\f3\-source 1\&.7\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++If you do not specify the correct version of bootstrap classes, then the compiler uses the old language rules (in this example, it uses version 1\&.7 of the Java programming language) combined with the new bootstrap classes, which can result in class files that do not work on the older platform (in this case, Java SE 7) because reference to nonexistent methods can get included\&.
+ .PP
+-\fBExample 2\fR
+-.br
+-Compile Multiple Source Files
+-.RS 4
+-This example compiles the
+-\fBAloha\&.java\fR,
+-\fBGutenTag\&.java\fR,
+-\fBHello\&.java\fR, and
+-\fBHi\&.java\fR
+-source files in the
+-\fBgreetings\fR
+-package\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB% javac greetings/*\&.java\fR
+-\fB% ls greetings\fR
+-\fBAloha\&.class GutenTag\&.class Hello\&.class Hi\&.class\fR
+-\fBAloha\&.java GutenTag\&.java Hello\&.java Hi\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
++\f3Example 5 Cross Compile\fR
+ .PP
+-\fBExample 3\fR
+-.br
+-Specify a User Class Path
+-.RS 4
+-After changing one of the source files in the previous example, recompile it:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpwd\fR
+-\fB/examples\fR
+-\fBjavac greetings/Hi\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Because
+-\fBgreetings\&.Hi\fR
+-refers to other classes in the
+-\fBgreetings\fR
+-package, the compiler needs to find these other classes\&. The previous example works because the default user class path is the directory that contains the package directory\&. If you want to recompile this file without concern for which directory you are in, then add the examples directory to the user class path by setting
+-\fBCLASSPATH\fR\&. This example uses the
+-\fB\-classpath\fR
+-option\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-classpath /examples /examples/greetings/Hi\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-If you change
+-\fBgreetings\&.Hi\fR
+-to use a banner utility, then that utility also needs to be accessible through the user class path\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-classpath /examples:/lib/Banners\&.jar \e\fR
+-\fB /examples/greetings/Hi\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-To execute a class in the
+-\fBgreetings\fR
+-package, the program needs access to the
+-\fBgreetings\fR
+-package, and to the classes that the
+-\fBgreetings\fR
+-classes use\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjava \-classpath /examples:/lib/Banners\&.jar greetings\&.Hi\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
++This example uses \f3javac\fR to compile code that runs on JVM 1\&.7\&.
++.sp
++.nf
++\f3javac \-source 1\&.7 \-target 1\&.7 \-bootclasspath jdk1\&.7\&.0/lib/rt\&.jar \e\fP
++.fi
++.nf
++\f3 \-extdirs "" OldCode\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++The\f3-source 1\&.7\fR option specifies that release 1\&.7 (or 7) of the Java programming language to be used to compile OldCode\&.java\&. The \f3-target 1\&.7\fR option ensures that the generated class files are compatible with JVM 1\&.7\&.
+ .PP
+-\fBExample 4\fR
+-.br
+-Separate Source Files and Class Files
+-.RS 4
+-The following example uses
+-\fBjavac\fR
+-to compile code that runs on JVM 1\&.7\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-source 1\&.7 \-target 1\&.7 \-bootclasspath jdk1\&.7\&.0/lib/rt\&.jar \e \fR
+-\fB\-extdirs "" OldCode\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The
+-\fB\-source 1\&.7\fR
+-option specifies that release 1\&.7 (or 7) of the Java programming language be used to compile
+-\fBOldCode\&.java\fR\&. The option
+-\fB\-target 1\&.7\fR
+-option ensures that the generated class files are compatible with JVM 1\&.7\&. Note that in most cases, the value of the
+-\fB\-target\fR
+-option is the value of the
+-\fB\-source\fR
+-option; in this example, you can omit the
+-\fB\-target\fR
+-option\&.
+-.sp
+-You must specify the
+-\fB\-bootclasspath\fR
+-option to specify the correct version of the bootstrap classes (the
+-\fBrt\&.jar\fR
+-library)\&. If not, then the compiler generates a warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-source 1\&.7 OldCode\&.java\fR
+-\fBwarning: [options] bootstrap class path not set in conjunction with \fR
+-\fB\-source 1\&.7\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-If you do not specify the correct version of bootstrap classes, then the compiler uses the old language rules (in this example, it uses version 1\&.7 of the Java programming language) combined with the new bootstrap classes, which can result in class files that do not work on the older platform (in this case, Java SE 7) because reference to nonexistent methods can get included\&.
+-.RE
+-.PP
+-\fBExample 5\fR
+-.br
+-Cross Compile
+-.RS 4
+-This example uses
+-\fBjavac\fR
+-to compile code that runs on JVM 1\&.7\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-source 1\&.7 \-target 1\&.7 \-bootclasspath jdk1\&.7\&.0/lib/rt\&.jar \e\fR
+-\fB \-extdirs "" OldCode\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The\fB \-source 1\&.7\fR
+-option specifies that release 1\&.7 (or 7) of the Java programming language to be used to compile OldCode\&.java\&. The
+-\fB\-target 1\&.7\fR
+-option ensures that the generated class files are compatible with JVM 1\&.7\&. In most cases, the value of the
+-\fB\-target\fR
+-is the value of
+-\fB\-source\fR\&. In this example, the
+-\fB\-target\fR
+-option is omitted\&.
+-.sp
+-You must specify the
+-\fB\-bootclasspath\fR
+-option to specify the correct version of the bootstrap classes (the
+-\fBrt\&.jar\fR
+-library)\&. If not, then the compiler generates a warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-source 1\&.7 OldCode\&.java\fR
+-\fBwarning: [options] bootstrap class path not set in conjunction with \-source 1\&.7\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
++You must specify the \f3-bootclasspath\fR option to specify the correct version of the bootstrap classes (the \f3rt\&.jar\fR library)\&. If not, then the compiler generates a warning:
++.sp
++.nf
++\f3javac \-source 1\&.7 OldCode\&.java\fP
++.fi
++.nf
++\f3warning: [options] bootstrap class path not set in conjunction with \-source 1\&.7\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
+ If you do not specify the correct version of bootstrap classes, then the compiler uses the old language rules combined with the new bootstrap classes\&. This combination can result in class files that do not work on the older platform (in this case, Java SE 7) because reference to nonexistent methods can get included\&. In this example, the compiler uses release 1\&.7 of the Java programming language\&.
+-.RE
+-.SH "SEE ALSO"
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.SH SEE\ ALSO
++.TP 0.2i
++\(bu
+ java(1)
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.TP 0.2i
++\(bu
+ jdb(1)
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.TP 0.2i
++\(bu
+ javah(1)
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.TP 0.2i
++\(bu
+ javadoc(1)
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.TP 0.2i
++\(bu
+ jar(1)
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.TP 0.2i
++\(bu
+ jdb(1)
+-.RE
+-.br
+-'pl 8.5i
+-'bp
++.RE
++.br
++'pl 8.5i
++'bp
+--- ./jdk/src/linux/doc/man/javadoc.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/javadoc.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ '\" t
+-.\" Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
++.\" Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
+ .\"
+ .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ .\"
+@@ -23,12 +23,12 @@
+ .\"
+ .\" Arch: generic
+ .\" Software: JDK 8
+-.\" Date: 10 May 2011
++.\" Date: 03 March 2015
+ .\" SectDesc: Basic Tools
+ .\" Title: javadoc.1
+ .\"
+ .if n .pl 99999
+-.TH javadoc 1 "10 May 2011" "JDK 8" "Basic Tools"
++.TH javadoc 1 "03 March 2015" "JDK 8" "Basic Tools"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -209,7 +209,7 @@
+ \f3package java\&.lang\&.applet;\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -251,7 +251,7 @@
+ \f3initialize, start, and stop the applet\&. \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3@since 1\&.0 \fP
+@@ -266,7 +266,7 @@
+ \f3</HTML>\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The \f3package\&.html\fR file is a typical HTML file and does not include a package declaration\&. The content of the package comment file is written in HTML with one exception\&. The documentation comment should not include the comment separators \f3/**\fR and \f3*/\fR or leading asterisks\&. When writing the comment, make the first sentence a summary about the package, and do not put a title or any other text between the \f3<body>\fR tag and the first sentence\&. You can include package tags\&. All block tags must appear after the main description\&. If you add an \f3@see\fR tag in a package comment file, then it must have a fully qualified name\&.
+@@ -334,7 +334,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SS TEST\ AND\ TEMPLATE\ FILES
+@@ -350,7 +350,7 @@
+ \f3com/package1/test\-files/\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ If your test files contain documentation comments, then you can set up a separate run of the \f3javadoc\fR command to produce test file documentation by passing in their test source file names with wild cards, such as \f3com/package1/test-files/*\&.java\fR\&.
+@@ -560,7 +560,7 @@
+ \f3implements Serializable\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The declaration for the \f3Boolean\&.valueOf\fR method is:
+@@ -569,7 +569,7 @@
+ \f3public static Boolean valueOf(String s)\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The \f3javadoc\fR command can include the modifiers \f3public\fR, \f3protected\fR, \f3private\fR, \f3abstract\fR, \f3final\fR, \f3static\fR, \f3transient\fR, and \f3volatile\fR, but not \f3synchronized\fR or \f3native\fR\&. The \f3synchronized\fR and \f3native\fR modifiers are considered implementation detail and not part of the API specification\&.
+@@ -593,7 +593,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ To save space you can put a comment on one line:
+@@ -602,7 +602,7 @@
+ \f3/** This comment takes up only one line\&. */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -623,19 +623,19 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3import com\&.example; // MISTAKE \- Important not to put import statement here\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3public class Whatever{ }\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -657,7 +657,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -676,7 +676,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -700,7 +700,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -730,7 +730,7 @@
+ \f3public int x, y; // Avoid this \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The \f3javadoc\fR command generates the following documentation from the previous code:
+@@ -739,7 +739,7 @@
+ \f3public int x\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The horizontal and vertical distances of point (x, y)\&.
+@@ -748,7 +748,7 @@
+ \f3public int y\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The horizontal and vertical distances of point (x, y)\&.
+@@ -872,7 +872,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -899,11 +899,10 @@
+ .TP 0.2i
+ \(bu
+ In the text arguments of the \f3@return\fR, \f3@param,\fR and \f3@throws\fR tags of a method\&. In this case, the tag text is copied from the corresponding tag up the hierarchy\&.
+-.RE
+-.RS
++.RE
++
++
+ See Method Comment Inheritance for a description of how comments are found in the inheritance hierarchy\&. Note that if this tag is missing, then the comment is or is not automatically inherited according to rules described in that section\&.
+-
+-.RE
+ .TP
+ {@link \fIpackage\&.class#member label\fR}
+ Introduced in JDK 1\&.2
+@@ -920,7 +919,7 @@
+ \f3Use the {@link #getComponentAt(int, int) getComponentAt} method\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -931,7 +930,7 @@
+ \f3Use the <a href="Component\&.html#getComponentAt(int, int)">getComponentAt</a> method\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -942,7 +941,7 @@
+ \f3Use the getComponentAt method\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -982,7 +981,7 @@
+ \f3}\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1014,7 +1013,7 @@
+ \f3}\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1071,7 +1070,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1091,7 +1090,7 @@
+ \f3</dl>\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1128,7 +1127,7 @@
+ \f3@see #constructor(Type argname, Type argname,\&.\&.\&.) \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3\fIReferencing another class in the current or imported packages\fR\fP
+@@ -1155,7 +1154,7 @@
+ \f3@see Class \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3\fIReferencing an element in another package (fully qualified)\fR\fP
+@@ -1185,7 +1184,7 @@
+ \f3@see package\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3\fRNotes about the previous listing:
+@@ -1215,7 +1214,7 @@
+ Any enclosing classes and interfaces searching the closest first\&.
+ .TP 0.4i
+ 3\&.
+-Any superclasses and superonterfaces, searching the closest first\&.
++Any superclasses and superinterfaces, searching the closest first\&.
+ .TP 0.4i
+ 4\&.
+ The current package\&.
+@@ -1307,7 +1306,7 @@
+ \f3@see "The Java Programming Language" // "The Java Programming Language" \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \fINote:\fR You can extend the \f3@se\fR\f3e\fR tag to link to classes not being documented with the \f3-link\fR option\&.
+@@ -1317,7 +1316,7 @@
+
+ Used in the documentation comment for a default serializable field\&. See Documenting Serializable Fields and Data for a Class at http://docs\&.oracle\&.com/javase/8/docs/platform/serialization/spec/serial-arch\&.html#5251
+
+-See also Oracle\(cqs Criteria for Including Classes in the Serialilzed Form Specification at http://www\&.oracle\&.com/technetwork/java/javase/documentation/serialized-criteria-137781\&.html
++See also Oracle\(cqs Criteria for Including Classes in the Serialized Form Specification at http://www\&.oracle\&.com/technetwork/java/javase/documentation/serialized-criteria-137781\&.html
+
+ An optional \f3field-description\fR should explain the meaning of the field and list the acceptable values\&. When needed, the description can span multiple lines\&. The standard doclet adds this information to the serialized form page\&. See Cross-Reference Pages\&.
+
+@@ -1331,13 +1330,12 @@
+ .TP 0.2i
+ \(bu
+ A private or package-private class that implements \f3Serializable\fR is excluded unless that class (or its package) is marked with the \f3@serial include\fR tag\&.
+-.RE
+-.RS
++.RE
++
++
+ For example, the \f3javax\&.swing\fR package is marked with the \f3@serial\fR\f3exclude\fR tag in package\&.html or package-info\&.java\&. The public class \f3java\&.security\&.BasicPermission\fR is marked with the \f3@serial exclude\fR tag\&. The package-private class \f3java\&.util\&.PropertyPermissionCollection\fR is marked with the \f3@serial include\fR tag\&.
+
+ The \f3@serial\fR tag at the class level overrides the \f3@serial\fR tag at the package level\&.
+-
+-.RE
+ .TP
+ @serialData \fIdata-description\fR
+ Introduced in JDK 1\&.2
+@@ -1387,7 +1385,7 @@
+ \f3public static final String SCRIPT_START = "<script>"\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1407,7 +1405,7 @@
+ \f3public String evalScript(String script) {}\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1494,7 +1492,7 @@
+ \f3}\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SS FIELD\ TAGS
+@@ -1523,7 +1521,7 @@
+ \f3 int x = 1263732;\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SS CONSTRUCTOR\ AND\ METHOD\ TAGS
+@@ -1578,7 +1576,7 @@
+ \f3 }\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SH OPTIONS
+@@ -1592,7 +1590,7 @@
+ .PP
+ The options are:
+ .PP
+--1\&.1 || -author || -bootclasspath classpathlist || -bottom text || -breakiterator || -charset name || -classpath classpathlist || -d directory || -docencoding name || -docfilesubdirs || -doclet class || -docletpath classpathlist || -doctitle title || -encoding || -exclude packagename1:packagename2:\&.\&.\&. || -excludedocfilessubdir name1:name2 || -extdirs dirist || -footer footer || -group groupheading packagepattern:packagepattern || -header header || -help || -helpfile path\efilename || -Jflag || -keywords || -link extdocURL || -linkoffline extdocURL packagelistLoc || -linksource || -locale language_country_variant || -nocomment || -nodeprecated || -nodeprecatedlist || -nohelp || -noindex || -nonavbar || -noqualifier all | packagename1:packagename2\&.\&.\&. || -nosince || -notimestamp || -notree || -overview path/filename || -package || -private || -protected || -public || -quiet || -serialwarn || -source release || -sourcepath sourcepathlist || -sourcetab tablength || -splitindex || -stylesheet path/filename || -subpackages package1:package2:\&.\&.\&. || -tag tagname:Xaoptcmf:"taghead" || -taglet class || -tagletpath tagletpathlist || -title title || -top || -use || -verbose || -version || -windowtitle title
++-1\&.1 || -author || -bootclasspath classpathlist || -bottom text || -breakiterator || -charset name || -classpath classpathlist || -d directory || -docencoding name || -docfilesubdirs || -doclet class || -docletpath classpathlist || -doctitle title || -encoding || -exclude packagename1:packagename2:\&.\&.\&. || -excludedocfilessubdir name1:name2 || -extdirs dirist || -footer footer || -group groupheading packagepattern:packagepattern || -header header || -help || -helpfile path\efilename || -Jflag || -javafx ||-keywords || -link extdocURL || -linkoffline extdocURL packagelistLoc || -linksource || -locale language_country_variant || -nocomment || -nodeprecated || -nodeprecatedlist || -nohelp || -noindex || -nonavbar || -noqualifier all | packagename1:packagename2\&.\&.\&. || -nosince || -notimestamp || -notree || -overview path/filename || -package || -private || -protected || -public || -quiet || -serialwarn || -source release || -sourcepath sourcepathlist || -sourcetab tablength || -splitindex || -stylesheet path/filename || -subpackages package1:package2:\&.\&.\&. || -tag tagname:Xaoptcmf:"taghead" || -taglet class || -tagletpath tagletpathlist || -title title || -top || -use || -verbose || -version || -windowtitle title
+ .PP
+ The following options are the core Javadoc options that are available to all doclets\&. The standard doclet provides the rest of the doclets: \f3-bootclasspath\fR, \f3-breakiterator\fR, \f3-classpath\fR, \f3-doclet\fR, \f3-docletpath\fR, \f3-encoding\fR, -\f3exclude\fR, \f3-extdirs\fR, \f3-help\fR, \f3-locale\fR, \f3-\fR\f3overview\fR, \f3-package\fR, \f3-private\fR, \f3-protected\fR, \f3-public\fR, \f3-quiet\fR, \f3-source\fR, \f3-sourcepath\fR, \f3-subpackages\fR, and \f3-verbose\fR\&.
+ .SS JAVADOC\ OPTIONS
+@@ -1635,12 +1633,11 @@
+ .TP 0.2i
+ \(bu
+ \f3-Xdoclint all,\fR\fI-group\fR : enable all except \fIgroup\fR checks
+-.RE
+-.RS
++.RE
++
++
+ The variable \fIgroup\fR has one of the following values:
+ .RS
+-
+-.RE
+ .TP 0.2i
+ \(bu
+ \f3accessibility\fR : Checks for the issues to be detected by an accessibility checker (for example, no caption or summary attributes specified in a \f3<table>\fR tag)\&.
+@@ -1656,8 +1653,9 @@
+ .TP 0.2i
+ \(bu
+ \f3syntax\fR : Checks for low level issues like unescaped angle brackets (\f3<\fR and \f3>\fR) and ampersands (\f3&\fR) and invalid Javadoc tags\&.
+-.RE
+-.RS
++.RE
++
++
+ You can specify the \f3-Xdoclint\fR option multiple times to enable the option to check errors and warnings in multiple categories\&. Alternatively, you can specify multiple error and warning categories by using the preceding options\&. For example, use either of the following commands to check for the HTML, syntax, and accessibility issues in the file \fIfilename\fR\&.
+ .sp
+ .nf
+@@ -1667,7 +1665,7 @@
+ \f3javadoc \-Xdoclint:html,syntax,accessibility \fIfilename\fR\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1675,8 +1673,6 @@
+ \fINote:\fR The \f3javadoc\fR command does not guarantee the completeness of these checks\&. In particular, it is not a full HTML compliance checker\&. The goal of the -\f3Xdoclint\fR option is to enable the \f3javadoc\fR command to report majority of common errors\&.
+
+ The \f3javadoc\fR command does not attempt to fix invalid input, it just reports it\&.
+-
+-.RE
+ .TP
+ -public
+ .br
+@@ -1740,7 +1736,7 @@
+ \f3javadoc \-sourcepath /home/user/src/ com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1755,7 +1751,7 @@
+ \f3javadoc \-sourcepath /home/user1/src:/home/user2/src com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1766,13 +1762,13 @@
+
+ If you omit \f3-sourcepath\fR, then the \f3javadoc\fR command uses \f3-classpath\fR to find the source files and class files (for backward compatibility)\&. If you want to search for source and class files in separate paths, then use both \f3-sourcepath\fR and \f3-classpath\fR\&.
+
+-For example, if you want to document \f3com\&.mypackage\fR, whose source files reside in the directory /home/user/src/com/mypackage, and if this package relies on a library in /home/user/libthen you would use the following command:
++For example, if you want to document \f3com\&.mypackage\fR, whose source files reside in the directory /home/user/src/com/mypackage, and if this package relies on a library in /home/user/lib, then you would use the following command:
+ .sp
+ .nf
+ \f3javadoc \-sourcepath /home/user/lib \-classpath /home/user/src com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1795,7 +1791,7 @@
+ \f3javadoc \-d docs \-sourcepath /home/user/src \-subpackages java:javax\&.swing \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1813,7 +1809,7 @@
+ \f3 java\&.net:java\&.lang\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1846,11 +1842,10 @@
+ .TP 0.2i
+ \(bu
+ Breakiterator sentence-break algorithm\&. Stops at a period, question mark, or exclamation point followed by a space when the next word starts with a capital letter\&. This is meant to handle most abbreviations (such as "The serial no\&. is valid", but will not handle "Mr\&. Smith")\&. The \f3-breakiterator\fR option does not stop at HTML tags or sentences that begin with numbers or symbols\&. The algorithm stops at the last period in \&.\&./filename, even when embedded in an HTML tag\&.
+-.RE
+-.RS
++.RE
++
++
+ In Java SE 1\&.5 the \f3-breakiterator\fR option warning messages are removed, and the default sentence-break algorithm is unchanged\&. If you have not modified your source code to eliminate the \f3-breakiterator\fR option warnings in Java SE 1\&.4\&.x, then you do not have to do anything\&. The warnings go away starting with Java SE 1\&.5\&.0\&.
+-
+-.RE
+ .TP
+ -locale \fIlanguage_country_variant\fR
+ .br
+@@ -1885,7 +1880,21 @@
+ \f3Java HotSpot(TM) 64\-Bit Server VM (build 23\&.5\-b02, mixed mode)\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
++.fi
++.sp
++
++.TP
++-javafx
++.br
++Generates HTML documentation using the JavaFX extensions to the standard doclet\&. The generated documentation includes a Property Summary section in addition to the other summary sections generated by the standard Java doclet\&. The listed properties are linked to the sections for the getter and setter methods of each property\&.
++
++If there are no documentation comments written explicitly for getter and setter methods, the documentation comments from the property method are automatically copied to the generated documentation for these methods\&. This option also adds a new \f3@defaultValue\fR tag that allows documenting the default value for a property\&.
++
++Example:
++.sp
++.nf
++\f3javadoc \-javafx MyClass\&.java \-d testdir\fP
+ .fi
+ .sp
+
+@@ -1957,7 +1966,7 @@
+ \f3\-link <directory>/<directory>/\&.\&.\&./<name>\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1982,7 +1991,7 @@
+ \f3javadoc \-link http://docs\&.oracle\&.com/javase/8/docs/api/ com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The command generates documentation for the package \f3com\&.mypackage\fR with links to the Java SE packages\&. The generated documentation contains links to the \f3Object\fR class, for example, in the class \f3trees\fR\&. Other options, such as the \f3-sourcepath\fR and \f3-d\fR options, are not shown\&.
+@@ -2044,7 +2053,7 @@
+ \f3and so on \&.\&.\&.\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ When \f3javadoc\fR is run without the \f3-link\fR option and encounters a name that belongs to an externally referenced class, it prints the name with no link\&. However, when the \f3-link\fR option is used, the \f3javadoc\fR command searches the package-list file at the specified \fIextdocURL\fR location for that package name\&. When it finds the package name, it prefixes the name with \fIextdocURL\fR\&.
+@@ -2094,7 +2103,7 @@
+ \f3javadoc \-linkoffline http://docs\&.oracle\&.com/javase/8/docs/api/ \&. com\&.mypackage \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2118,7 +2127,7 @@
+ \f3packagelistLoc2 \&.\&.\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2133,7 +2142,7 @@
+ \f3javadoc \-d update \-linkoffline \&. html com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ When the \f3javadoc\fR command completes, copy these generated class pages in update/com/package (not the overview or index) to the original files in html/com/package\&.
+@@ -2150,7 +2159,7 @@
+ \f3public class Button extends Component implements Accessible\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2161,7 +2170,7 @@
+ \f3public String getLabel()\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2176,8 +2185,9 @@
+ .TP 0.2i
+ \(bu
+ The \f3packagepattern\fR value can be any package name at the start of any package name followed by an asterisk (*)\&. The asterisk is the only wildcard allowed and means match any characters\&. Multiple patterns can be included in a group by separating them with colons (:)\&. If you use an asterisk in a pattern or pattern list, then the pattern list must be inside quotation marks, such as \f3"java\&.lang*:java\&.util"\fR\&.
+-.RE
+-.RS
++.RE
++
++
+ When you do not supply a \f3-group\fR option, all packages are placed in one group with the heading \fIPackages\fR and appropriate subheadings\&. If the subheadings do not include all documented packages (all groups), then the remaining packages appear in a separate group with the subheading Other Packages\&.
+
+ For example, the following \f3javadoc\fR command separates the three documented packages into \fICore\fR, \fIExtension\fR, and \fIOther Packages\fR\&. The trailing dot (\&.) does not appear in \f3java\&.lang*\fR\&. Including the dot, such as \f3java\&.lang\&.*\fR omits the\f3java\&.lang\fR package\&.
+@@ -2192,7 +2202,7 @@
+ \f3 java\&.lang java\&.lang\&.reflect java\&.util javax\&.servlet java\&.new\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2212,8 +2222,6 @@
+ \fIOther Packages\fR
+
+ \f3java\&.new\fR
+-
+-.RE
+ .TP
+ -nodeprecated
+ .br
+@@ -2251,7 +2259,7 @@
+ \f3javadoc \-helpfile /home/user/myhelp\&.html java\&.awt\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2264,7 +2272,7 @@
+ \f3javadoc \-stylesheet file /home/user/mystylesheet\&.css com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2283,7 +2291,7 @@
+ \f3<META http\-equiv="Content\-Type" content="text/html; charset=ISO\-8859\-1">\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2296,7 +2304,7 @@
+ .br
+ Specifies the encoding of the generated HTML files\&. The name should be a preferred MIME name as specified in the IANA Registry, Character Sets at http://www\&.iana\&.org/assignments/character-sets
+
+-If you omit the \f3-docencoding\fR option but use the \f3-encoding\fR option, then the encoding of the generated HTML files is determined by the \f3-encoding\fR option, for example: \f3javadoc -docencoding"iso-8859-1" mypackage\fR\&. See also the \f3-encoding\fR and \f3-docencoding name\fR options\&.
++If you omit the \f3-docencoding\fR option but use the \f3-encoding\fR option, then the encoding of the generated HTML files is determined by the \f3-encoding\fR option, for example: \f3javadoc -docencoding "iso-8859-1" mypackage\fR\&. See also the \f3-encoding\fR and \f3-docencoding name\fR options\&.
+ .TP
+ -keywords
+ .br
+@@ -2315,7 +2323,7 @@
+ \f3<META NAME="keywords" CONTENT="charAt()">\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2360,7 +2368,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2390,7 +2398,7 @@
+ \f3\-tag example:X\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2433,7 +2441,7 @@
+ \f3\-tag see\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2523,7 +2531,7 @@
+ \f3\-sourcepath /java/pubs/ws/1\&.7\&.0/src/share/classes\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ Create a file named packages that contains:
+@@ -2538,7 +2546,7 @@
+ \f3com\&.mypackage3\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ Run the \f3javadoc\fR command as follows:
+@@ -2547,7 +2555,7 @@
+ \f3javadoc @options @packages\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 3 Argument Files with Paths\fR
+@@ -2558,7 +2566,7 @@
+ \f3javadoc @path1/options @path2/packages\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 4 Option Arguments\fR
+@@ -2581,7 +2589,7 @@
+ \f3 Other names may be trademarks of their respective owners\&.</font>\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ Run the \f3javadoc\fR command as follows:\f3javadoc -bottom @bottom @packages\fR\&.
+@@ -2616,7 +2624,7 @@
+ \f3javadoc \-d /home/html \-sourcepath /home/src \-subpackages java \-exclude\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 2 Change to Root and Run Explicit Packages\fR
+@@ -2630,7 +2638,7 @@
+ \f3javadoc \-d /home/html java\&.awt java\&.awt\&.event\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ To also traverse down other package trees, append their names to the \f3-subpackages\fR argument, such as j\f3ava:javax:org\&.xml\&.sax\fR\&.
+@@ -2643,7 +2651,7 @@
+ \f3javadoc \-d /home/html \-sourcepath /home/src java\&.awt java\&.awt\&.event\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 4 Run from Any Directory on Explicit Packages in Multiple Trees\fR
+@@ -2654,7 +2662,7 @@
+ \f3javadoc \-d /home/html \-sourcepath /home/src1:/home/src2 java\&.awt java\&.awt\&.event\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The result is that all cases generate HTML-formatted documentation for the \f3public\fR and \f3protected\fR classes and interfaces in packages j\f3ava\&.awt\fR and \f3java\&.awt\&.even\fRt and save the HTML files in the specified destination directory\&. Because two or more packages are being generated, the document has three HTML frames: one for the list of packages, another for the list of classes, and the third for the main class pages\&.
+@@ -2676,7 +2684,7 @@
+ \f3javadoc \-d /home/html Button\&.java Canvas\&.java Graphics*\&.java\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 2 Change to the Root Directory of the Package\fR
+@@ -2690,7 +2698,7 @@
+ \f3javadoc \-d /home/html java/awt/Button\&.java java/applet/Applet\&.java\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 3 Document Files from Any Directory\fR
+@@ -2704,7 +2712,7 @@
+ \f3/home/src/java/awt/Graphics*\&.java\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2720,7 +2728,7 @@
+ \f3/home/src/java/applet/Applet\&.java\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SS REAL-WORLD\ EXAMPLES
+@@ -2784,7 +2792,7 @@
+ \f3@packages\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2802,7 +2810,7 @@
+ \f3import javax\&.tools\&.ToolProvider;\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3public class JavaAccessSample{\fP
+@@ -2838,7 +2846,7 @@
+ \f3 }\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The first three arguments of the \f3run\fR method specify input, standard output, and standard error streams\&. \f3Null\fR is the default value for \f3System\&.in\fR, \f3System\&.out\fR, and \f3System\&.err\fR, respectively\&.
+@@ -2891,7 +2899,7 @@
+ \f3 java\&.applet\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3WINDOWTITLE = \&'Java\(tm SE 7 API Specification\&'\fP
+@@ -2927,7 +2935,7 @@
+ \f3SRCDIR = \&'/java/jdk/1\&.7\&.0/src/share/classes\&'\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SS NOTES
+--- ./jdk/src/linux/doc/man/jcmd.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/jcmd.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,114 +1,211 @@
+ '\" t
+-.\" Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+-.\"
+-.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-.\"
+-.\" This code is free software; you can redistribute it and/or modify it
+-.\" under the terms of the GNU General Public License version 2 only, as
+-.\" published by the Free Software Foundation.
+-.\"
+-.\" This code is distributed in the hope that it will be useful, but WITHOUT
+-.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-.\" version 2 for more details (a copy is included in the LICENSE file that
+-.\" accompanied this code).
+-.\"
+-.\" You should have received a copy of the GNU General Public License version
+-.\" 2 along with this work; if not, write to the Free Software Foundation,
+-.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-.\"
+-.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-.\" or visit www.oracle.com if you need additional information or have any
+-.\" questions.
+-.\"
+-.\" Arch: generic
+-.\" Software: JDK 8
+-.\" Date: 21 November 2013
+-.\" SectDesc: Troubleshooting Tools
+-.\" Title: jcmd.1
++.\" Copyright (c) 2012, 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.
++.\"
++.\" Title: jcmd
++.\" Language: English
++.\" Date: 03 March 2015
++.\" SectDesc: Troubleshooting Tools
++.\" Software: JDK 8
++.\" Arch: generic
++.\" Part Number: E38207-04
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH jcmd 1 "21 November 2013" "JDK 8" "Troubleshooting Tools"
+-.\" -----------------------------------------------------------------
+-.\" * Define some portability stuff
+-.\" -----------------------------------------------------------------
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.\" http://bugs.debian.org/507673
+-.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.ie \n(.g .ds Aq \(aq
+-.el .ds Aq '
+-.\" -----------------------------------------------------------------
+-.\" * set default formatting
+-.\" -----------------------------------------------------------------
+-.\" disable hyphenation
+-.nh
+-.\" disable justification (adjust text to left margin only)
+-.ad l
+-.\" -----------------------------------------------------------------
+-.\" * MAIN CONTENT STARTS HERE *
+-.\" -----------------------------------------------------------------
+-
+-.SH NAME
++.TH "jcmd" "1" "03 March 2015" "JDK 8" "Troubleshooting Tools"
++.\" -----------------------------------------------------------------
++.\" * Define some portability stuff
++.\" -----------------------------------------------------------------
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.\" http://bugs.debian.org/507673
++.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.ie \n(.g .ds Aq \(aq
++.el .ds Aq '
++.\" -----------------------------------------------------------------
++.\" * set default formatting
++.\" -----------------------------------------------------------------
++.\" disable hyphenation
++.nh
++.\" disable justification (adjust text to left margin only)
++.ad l
++.\" -----------------------------------------------------------------
++.\" * MAIN CONTENT STARTS HERE *
++.\" -----------------------------------------------------------------
++.SH "NAME"
+ jcmd \- Sends diagnostic command requests to a running Java Virtual Machine (JVM)\&.
+-.SH SYNOPSIS
+-.sp
+-.nf
+-
++.SH "SYNOPSIS"
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
+ \fBjcmd\fR [\fB\-l\fR|\fB\-h\fR|\fB\-help\fR]
+-.fi
+-.nf
+-
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
+ \fBjcmd\fR \fIpid\fR|\fImain\-class\fR \fBPerfCounter\&.print\fR
+-.fi
+-.nf
+-
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
+ \fBjcmd\fR \fIpid\fR|\fImain\-class\fR \fB\-f\fR \fIfilename\fR
+-.fi
+-.nf
+-
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
+ \fBjcmd\fR \fIpid\fR|\fImain\-class\fR \fIcommand\fR[ \fIarguments\fR]
+-.fi
+-.sp
+-.SH DESCRIPTION
+-The \f3jcmd\fR utility is used to send diagnostic command requests to the JVM\&. It must be used on the same machine on which the JVM is running, and have the same effective user and group identifiers that were used to launch the JVM\&.
++.fi
++.if n \{\
++.RE
++.\}
++.SH "DESCRIPTION"
+ .PP
+-\fINote:\fR To invoke diagnostic commands from a remote machine or with different identiers, you can use the \f3com\&.sun\&.management\&.DiagnosticCommandMBean\fR interface\&. For more information about the \f3DiagnosticCommandMBean\fR interface, see the API documentation at http://download\&.java\&.net/jdk8/docs/jre/api/management/extension/com/sun/management/DiagnosticCommandMBean\&.html
++The
++\fBjcmd\fR
++utility is used to send diagnostic command requests to the JVM\&. It must be used on the same machine on which the JVM is running, and have the same effective user and group identifiers that were used to launch the JVM\&.
++.if n \{\
++.sp
++.\}
++.RS 4
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBNote\fR
++.ps -1
++.br
++.TS
++allbox tab(:);
++l.
++T{
+ .PP
+-If you run \f3jcmd\fR without arguments or with the \f3-l\fR option, it prints the list of running Java process identifiers with the main class and command-line arguments that were used to launch the process\&. Running \f3jcmd\fR with the \f3-h\fR or \f3-help\fR option prints the tool\(cqs help message\&.
++To invoke diagnostic commands from a remote machine or with different identifiers, you can use the
++\fBcom\&.sun\&.management\&.DiagnosticCommandMBean\fR
++interface\&. For more information about the
++\fBDiagnosticCommandMBean\fR
++interface, see the API documentation at http://docs\&.oracle\&.com/javase/8/docs/jre/api/management/extension/com/sun/management/DiagnosticCommandMBean\&.html
++T}
++.TE
++.sp 1
++.sp .5v
++.RE
+ .PP
+-If you specify the processes identifier (\fIpid\fR) or the main class (\fImain-class\fR) as the first argument, \f3jcmd\fR sends the diagnostic command request to the Java process with the specified identifier or to all Java processes with the specified name of the main class\&. You can also send the diagnostic command request to all available Java processes by specifying \f30\fR as the process identifier\&. Use one of the following as the diagnostic command request:
+-.TP
++If you run
++\fBjcmd\fR
++without arguments or with the
++\fB\-l\fR
++option, it prints the list of running Java process identifiers with the main class and command\-line arguments that were used to launch the process\&. Running
++\fBjcmd\fR
++with the
++\fB\-h\fR
++or
++\fB\-help\fR
++option prints the tool\(cqs help message\&.
++.PP
++If you specify the processes identifier (\fIpid\fR) or the main class (\fImain\-class\fR) as the first argument,
++\fBjcmd\fR
++sends the diagnostic command request to the Java process with the specified identifier or to all Java processes with the specified name of the main class\&. You can also send the diagnostic command request to all available Java processes by specifying
++\fB0\fR
++as the process identifier\&. Use one of the following as the diagnostic command request:
++.PP
+ Perfcounter\&.print
++.RS 4
+ Prints the performance counters available for the specified Java process\&. The list of performance counters might vary with the Java process\&.
+-.TP
+--f \fIfilename\fR
++.RE
++.PP
++\-f \fIfilename\fR
++.RS 4
++The name of the file from which to read diagnostic commands and send them to the specified Java process\&. Used only with the
++\fB\-f\fR
++option\&. Each command in the file must be written on a single line\&. Lines starting with a number sign (\fB#\fR) are ignored\&. Processing of the file ends when all lines have been read or when a line containing the
++\fBstop\fR
++keyword is read\&.
++.RE
++.PP
++\fIcommand\fR [\fIarguments\fR]
++.RS 4
++The command to be sent to the specified Java process\&. The list of available diagnostic commands for a given process can be obtained by sending the
++\fBhelp\fR
++command to this process\&. Each diagnostic command has its own set of arguments\&. To see the description, syntax, and a list of available arguments for a command, use the name of the command as the argument for the
++\fBhelp\fR
++command\&.
++.sp
++\fBNote:\fR
++If any arguments contain spaces, you must surround them with single or double quotation marks (\fB\*(Aq\fR
++or
++\fB"\fR)\&. In addition, you must escape single or double quotation marks with a backslash (\fB\e\fR) to prevent the operating system shell from processing quotation marks\&. Alternatively, you can surround these arguments with single quotation marks and then with double quotation marks (or with double quotation marks and then with single quotation marks)\&.
++.RE
++.SH "OPTIONS"
++.PP
++Options are mutually exclusive\&.
++.PP
++\-f \fIfilename\fR
++.RS 4
++Reads commands from the specified file\&. This option can be used only if you specify the process identifier or the main class as the first argument\&. Each command in the file must be written on a single line\&. Lines starting with a number sign (\fB#\fR) are ignored\&. Processing of the file ends when all lines have been read or when a line containing the
++\fBstop\fR
++keyword is read\&.
++.RE
++.PP
++\-h
+ .br
+-The name of the file from which to read diagnostic commands and send them to the specified Java process\&. Used only with the \f3-f\fR option\&. Each command in the file must be written on a single line\&. Lines starting with a number sign (\f3#\fR) are ignored\&. Processing of the file ends when all lines have been read or when a line containing the \f3stop\fR keyword is read\&.
+-.TP
+-\fIcommand\fR [\fIarguments\fR]
+-The command to be sent to the specified Java process\&. The list of available diagnostic commands for a given process can be obtained by sending the \f3help\fR command to this process\&. Each diagnostic command has its own set of arguments\&. To see the description, syntax, and a list of available arguments for a command, use the name of the command as the argument for the \f3help\fR command\&.
+-
+-\fINote:\fR If any arguments contain spaces, you must surround them with single or double quotation marks (\f3\&'\fR or \f3"\fR)\&. In addition, you must escape single or double quotation marks with a backslash (\f3\e\fR) to prevent the operating system shell from processing quotation marks\&. Alternatively, you can surround these arguments with single quotation marks and then with double quotation marks (or with double quotation marks and then with single quotation marks)\&.
+-.SH OPTIONS
+-Options are mutually exclusive\&.
+-.TP
+--f \fIfilename\fR
++\-help
++.RS 4
++Prints a help message\&.
++.RE
++.PP
++\-l
++.RS 4
++Prints the list of running Java processes identifiers with the main class and command\-line arguments\&.
++.RE
++.SH "SEE ALSO"
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++jps(1)
++.RE
+ .br
+-Reads commands from the specified file\&. This option can be used only if you specify the process identifier or the main class as the first argument\&. Each command in the file must be written on a single line\&. Lines starting with a number sign (\f3#\fR) are ignored\&. Processing of the file ends when all lines have been read or when a line containing the \f3stop\fR keyword is read\&.
+-.TP
+--h, -help
+-.br
+-Prints a help message\&.
+-.TP
+--l
+-.br
+-Prints the list of running Java processes identifiers with the main class and command-line arguments\&.
+-.SH SEE\ ALSO
+-.TP 0.2i
+-\(bu
+-jps(1)
+-.RE
+-.br
+-'pl 8.5i
+-'bp
++'pl 8.5i
++'bp
+--- ./jdk/src/linux/doc/man/jjs.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/jjs.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,352 +1,248 @@
+ '\" t
+-.\" Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+-.\"
+-.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-.\"
+-.\" This code is free software; you can redistribute it and/or modify it
+-.\" under the terms of the GNU General Public License version 2 only, as
+-.\" published by the Free Software Foundation.
+-.\"
+-.\" This code is distributed in the hope that it will be useful, but WITHOUT
+-.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-.\" version 2 for more details (a copy is included in the LICENSE file that
+-.\" accompanied this code).
+-.\"
+-.\" You should have received a copy of the GNU General Public License version
+-.\" 2 along with this work; if not, write to the Free Software Foundation,
+-.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-.\"
+-.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-.\" or visit www.oracle.com if you need additional information or have any
+-.\" questions.
+-.\"
+-.\" Arch: generic
+-.\" Software: JDK 8
+-.\" Date: 21 November 2013
+-.\" SectDesc: Basic Tools
+-.\" Title: jjs.1
++.\" Copyright (c) 1994, 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.
++.\"
++.\" Title: jjs
++.\" Language: English
++.\" Date: 03 March 2015
++.\" SectDesc: Basic Tools
++.\" Software: JDK 8
++.\" Arch: generic
++.\" Part Number: E38207-04
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH jjs 1 "21 November 2013" "JDK 8" "Basic Tools"
+-.\" -----------------------------------------------------------------
+-.\" * Define some portability stuff
+-.\" -----------------------------------------------------------------
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.\" http://bugs.debian.org/507673
+-.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.ie \n(.g .ds Aq \(aq
+-.el .ds Aq '
+-.\" -----------------------------------------------------------------
+-.\" * set default formatting
+-.\" -----------------------------------------------------------------
+-.\" disable hyphenation
+-.nh
+-.\" disable justification (adjust text to left margin only)
+-.ad l
+-.\" -----------------------------------------------------------------
+-.\" * MAIN CONTENT STARTS HERE *
+-.\" -----------------------------------------------------------------
+-
+-.SH NAME
++.TH "jjs" "1" "03 March 2015" "JDK 8" "Basic Tools"
++.\" -----------------------------------------------------------------
++.\" * Define some portability stuff
++.\" -----------------------------------------------------------------
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.\" http://bugs.debian.org/507673
++.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.ie \n(.g .ds Aq \(aq
++.el .ds Aq '
++.\" -----------------------------------------------------------------
++.\" * set default formatting
++.\" -----------------------------------------------------------------
++.\" disable hyphenation
++.nh
++.\" disable justification (adjust text to left margin only)
++.ad l
++.\" -----------------------------------------------------------------
++.\" * MAIN CONTENT STARTS HERE *
++.\" -----------------------------------------------------------------
++.SH "NAME"
+ jjs \- Invokes the Nashorn engine\&.
+-.SH SYNOPSIS
+-.sp
+-.nf
+-\f3\fBjjs\fR [\fIoptions\fR] [\fIscript\-files\fR] [\-\- \fIarguments\fR]\fP
+-.fi
+-.sp
+-.TP
++.SH "SYNOPSIS"
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB\fBjjs\fR\fR\fB [\fR\fB\fIoptions\fR\fR\fB] [\fR\fB\fIscript\-files\fR\fR\fB] [\-\- \fR\fB\fIarguments\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.PP
+ \fIoptions\fR
+-One or more options of the \f3jjs\fR command, separated by spaces\&. For more information, see Options\&.
+-.TP
+-\fIscript-files\fR
++.RS 4
++One or more options of the
++\fBjjs\fR
++command, separated by spaces\&. For more information, see Options\&.
++.RE
++.PP
++\fIscript\-files\fR
++.RS 4
+ One or more script files which you want to interpret using Nashorn, separated by spaces\&. If no files are specified, an interactive shell is started\&.
+-.TP
++.RE
++.PP
+ \fIarguments\fR
+-All values after the double hyphen marker (\f3--\fR) are passed through to the script or the interactive shell as arguments\&. These values can be accessed by using the \f3arguments\fR property (see )\&.
+-.SH DESCRIPTION
+-The \f3jjs\fR command-line tool is used to invoke the Nashorn engine\&. You can use it to interpret one or several script files, or to run an interactive shell\&.
+-.SH OPTIONS
+-The options of the \f3jjs\fR command control the conditions under which scripts are interpreted by Nashorn\&.
+-.TP
+--ccs=\fIsize\fR , --class-cache-size=\fIsize\fR
++.RS 4
++All values after the double hyphen marker (\fB\-\-\fR) are passed through to the script or the interactive shell as arguments\&. These values can be accessed by using the
++\fBarguments\fR
++property (see Example 3)\&.
++.RE
++.SH "DESCRIPTION"
++.PP
++The
++\fBjjs\fR
++command\-line tool is used to invoke the Nashorn engine\&. You can use it to interpret one or several script files, or to run an interactive shell\&.
++.SH "OPTIONS"
++.PP
++The options of the
++\fBjjs\fR
++command control the conditions under which scripts are interpreted by Nashorn\&.
++.PP
++\-cp \fIpath\fR
+ .br
+-Sets the class cache size (in bytes)\&. Append the letter \f3k\fR or \f3K\fR to indicate kilobytes (KB), \f3m\fR or \f3M\fR to indicate megabytes (MB), \f3g\fR or \f3G\fR to indicate gigabytes (GB)\&. By default, the class cache size is set to 50 bytes\&. The following example shows how to set it to 1024 bytes (1 KB):
+-.sp
+-.nf
+-\f3\-css=100\fP
+-.fi
+-.nf
+-\f3\-css=1k\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-
+-.TP
+--co, --compile-only
++\-classpath \fIpath\fR
++.RS 4
++Specifies the path to the supporting class files To set multiple paths, the option can be repeated, or you can separate each path with a colon (:)\&.
++.RE
++.PP
++\-D\fIname\fR=\fIvalue\fR
++.RS 4
++Sets a system property to be passed to the script by assigning a value to a property name\&. The following example shows how to invoke Nashorn in interactive mode and assign
++\fBmyValue\fR
++to the property named
++\fBmyKey\fR:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB>> \fR\fB\fBjjs \-DmyKey=myValue\fR\fR
++\fBjjs> \fR\fB\fBjava\&.lang\&.System\&.getProperty("myKey")\fR\fR
++\fBmyValue\fR
++\fBjjs>\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++This option can be repeated to set multiple properties\&.
++.RE
++.PP
++\-doe
+ .br
+-Compiles the script without running it\&.
+-.TP
+--cp \fIpath\fR , --classpath \fIpath\fR
++\-\-dump\-on\-error
++.RS 4
++Provides a full stack trace when an error occurs\&. By default, only a brief error message is printed\&.
++.RE
++.PP
++\-fv
+ .br
+-Specifies the path to the supporting class files To set multiple paths, the option can be repeated, or you can separate each path with a colon (:)\&.
+-.TP
+--D\fIname\fR=\fIvalue\fR
++\-\-fullversion
++.RS 4
++Prints the full Nashorn version string\&.
++.RE
++.PP
++\-fx
++.RS 4
++Launches the script as a JavaFX application\&.
++.RE
++.PP
++\-h
+ .br
+-Sets a system property to be passed to the script by assigning a value to a property name\&. The following example shows how to invoke Nashorn in interactive mode and assign \f3myValue\fR to the property named \f3myKey\fR:
+-.sp
+-.nf
+-\f3>> \fIjjs \-DmyKey=myValue\fR\fP
+-.fi
+-.nf
+-\f3jjs> \fIjava\&.lang\&.System\&.getProperty("myKey")\fR\fP
+-.fi
+-.nf
+-\f3myValue\fP
+-.fi
+-.nf
+-\f3jjs>\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-
+-
+-This option can be repeated to set multiple properties\&.
+-.TP
+--d=\fIpath\fR , --dump-debug-dir=\fIpath\fR
++\-help
++.RS 4
++Prints the list of options and their descriptions\&.
++.RE
++.PP
++\-\-language=[es5]
++.RS 4
++Specifies the ECMAScript language version\&. The default version is ES5\&.
++.RE
++.PP
++\-ot
+ .br
+-Specifies the path to the directory where class files are dumped\&.
+-.TP
+---debug-lines
++\-\-optimistic\-types=[true|false]
++.RS 4
++Enables or disables optimistic type assumptions with deoptimizing recompilation\&. Running with optimistic types will yield higher final speed, but may increase warmup time\&.
++.RE
++.PP
++\-scripting
++.RS 4
++Enables shell scripting features\&.
++.RE
++.PP
++\-strict
++.RS 4
++Enables strict mode, which enforces stronger adherence to the standard (ECMAScript Edition 5\&.1), making it easier to detect common coding errors\&.
++.RE
++.PP
++\-t=\fIzone\fR
+ .br
+-Generates a line number table in the class file\&. By default, this option is enabled\&. To disable it, specify \f3--debug-lines=false\fR\&.
+-.TP
+---debug-locals
++\-timezone=\fIzone\fR
++.RS 4
++Sets the specified time zone for script execution\&. It overrides the time zone set in the OS and used by the
++\fBDate\fR
++object\&.
++.RE
++.PP
++\-v
+ .br
+-Generates a local variable table in the class file\&.
+-.TP
+--doe, --dump-on-error
++\-version
++.RS 4
++Prints the Nashorn version string\&.
++.RE
++.SH "EXAMPLES"
++.PP
++\fBExample 1 \fRRunning a Script with Nashorn
++.RS 4
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjjs script\&.js\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.PP
++\fBExample 2 \fRRunning Nashorn in Interactive Mode
++.RS 4
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB>> \fR\fB\fBjjs\fR\fR
++\fBjjs> \fR\fB\fBprintln("Hello, World!")\fR\fR
++\fBHello, World!\fR
++\fBjjs> \fR\fB\fBquit()\fR\fR
++\fB>>\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.PP
++\fBExample 3 \fRPassing Arguments to Nashorn
++.RS 4
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB>> \fR\fB\fBjjs \-\- a b c\fR\fR
++\fBjjs> \fR\fB\fBarguments\&.join(", ")\fR\fR
++\fBa, b, c\fR
++\fBjjs>\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.SH "SEE ALSO"
++.PP
++\fBjrunscript\fR
+ .br
+-Provides a full stack trace when an arror occurs\&. By default, only a brief error message is printed\&.
+-.TP
+---early-lvalue-error
+-.br
+-Reports invalid lvalue expressions as early errors (that is, when the code is parsed)\&. By default, this option is enabled\&. To disable it, specify \f3--early-lvalue-error=false\fR\&. When disabled, invalid lvalue expressions will not be reported until the code is executed\&.
+-.TP
+---empty-statements
+-.br
+-Preserves empty statements in the Java abstract syntax tree\&.
+-.TP
+--fv, --fullversion
+-.br
+-Prints the full Nashorn version string\&.
+-.TP
+---function-statement-error
+-.br
+-Prints an error message when a function declaration is used as a statement\&.
+-.TP
+---function-statement-warning
+-.br
+-Prints a warning message when a function declaration is used as a statement\&.
+-.TP
+--fx
+-.br
+-Launches the script as a JavaFX application\&.
+-.TP
+--h, -help
+-.br
+-Prints the list of options and their descriptions\&.
+-.TP
+--J\fIoption\fR
+-.br
+-Passes the specified \f3java\fR launcher option to the JVM\&. The following example shows how to invoke Nashorn in interactive mode and set the maximum memory used by the JVM to 4 GB:
+-.sp
+-.nf
+-\f3>> \fIjjs \-J\-Xmx4g\fR\fP
+-.fi
+-.nf
+-\f3jjs> \fIjava\&.lang\&.Runtime\&.getRuntime()\&.maxMemory()\fR\fP
+-.fi
+-.nf
+-\f33817799680\fP
+-.fi
+-.nf
+-\f3jjs>\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-
+-
+-This option can be repeated to pass multiple \f3java\fR command options\&.
+-.TP
+---lazy-compilation
+-.br
+-Enables lazy code generation strategies (that is, the entire script is not compiled at once)\&. This option is experimental\&.
+-.TP
+---loader-per-compile
+-.br
+-Creates a new class loader per compile\&. By default, this option is enabled\&. To disable it, specify \f3--loader-per-compile=false\fR\&.
+-.TP
+---log=\fIsubsystem\fR:\fIlevel\fR
+-.br
+-Performs logging at a given level for the specified subsystems\&. You can specify logging levels for multiple subsystems separating them with commas\&. For example:
+-.sp
+-.nf
+-\f3\-\-log=fields:finest,codegen:info\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-
+-.TP
+---package=\fIname\fR
+-.br
+-Specifies the package to which generated class files are added\&.
+-.TP
+---parse-only
+-.br
+-Parses the code without compiling\&.
+-.TP
+---print-ast
+-.br
+-Prints the abstract syntax tree\&.
+-.TP
+---print-code
+-.br
+-Prints bytecode\&.
+-.TP
+---print-lower-ast
+-.br
+-Prints the lowered abstract syntax tree\&.
+-.TP
+---print-lower-parse
+-.br
+-Prints the lowered parse tree\&.
+-.TP
+---print-no-newline
+-.br
+-Forces other \f3--print*\fR options to print the output on one line\&.
+-.TP
+---print-parse
+-.br
+-Prints the parse tree\&.
+-.TP
+---print-symbols
+-.br
+-Prints the symbol table\&.
+-.TP
+--pcs, --profile-callsites
+-.br
+-Dumps callsite profile data\&.
+-.TP
+--scripting
+-.br
+-Enables shell scripting features\&.
+-.TP
+---stderr=\fIfilename\fR|\fIstream\fR|\fItty\fR
+-.br
+-Redirects the standard error stream to the specified file, stream (for example, to \f3stdout\fR), or text terminal\&.
+-.TP
+---stdout=\fIfilename\fR|\fIstream\fR|\fItty\fR
+-.br
+-Redirects the standard output stream to the specified file, stream (for example, to \f3stderr\fR), or text terminal\&.
+-.TP
+--strict
+-.br
+-Enables strict mode, which enforces stronger adherence to the standard (ECMAScript Edition 5\&.1), making it easier to detect common coding errors\&.
+-.TP
+--t=\fIzone\fR , -timezone=\fIzone\fR
+-.br
+-Sets the specified time zone for script execution\&. It overrides the time zone set in the OS and used by the \f3Date\fR object\&.
+-.TP
+--tcs=\fIparameter\fR , --trace-callsites=\fIparameter\fR
+-.br
+-Enables callsite trace mode\&. Possible parameters are the following:
+-.RS
+-.TP
+-miss
+-Trace callsite misses\&.
+-.TP
+-enterexit
+-Trace callsite enter/exit\&.
+-.TP
+-objects
+-Print object properties\&.
+-.RE
+-
+-.TP
+---verify-code
+-.br
+-Verifies bytecode before running\&.
+-.TP
+--v, -version
+-.br
+-Prints the Nashorn version string\&.
+-.TP
+--xhelp
+-.br
+-Prints extended help for command-line options\&.
+-.SH EXAMPLES
+-\f3Example 1 Running a Script with Nashorn\fR
+-.sp
+-.nf
+-\f3jjs script\&.js\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-\f3Example 2 Running Nashorn in Interactive Mode\fR
+-.sp
+-.nf
+-\f3>> \fIjjs\fR\fP
+-.fi
+-.nf
+-\f3jjs> \fIprintln("Hello, World!")\fR\fP
+-.fi
+-.nf
+-\f3Hello, World!\fP
+-.fi
+-.nf
+-\f3jjs> \fIquit()\fR\fP
+-.fi
+-.nf
+-\f3>>\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-\f3Example 3 Passing Arguments to Nashorn\fR
+-.sp
+-.nf
+-\f3>> \fIjjs \-\- a b c\fR\fP
+-.fi
+-.nf
+-\f3jjs> \fIarguments\&.join(", ")\fR\fP
+-.fi
+-.nf
+-\f3a, b, c\fP
+-.fi
+-.nf
+-\f3jjs>\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-.SH SEE\ ALSO
+-\f3jrunscript\fR
+-.RE
+-.br
+-'pl 8.5i
+-'bp
++'pl 8.5i
++'bp
+--- ./jdk/src/linux/doc/man/jstat.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/jstat.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,568 +1,778 @@
+ '\" t
+-.\" Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+-.\"
+-.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-.\"
+-.\" This code is free software; you can redistribute it and/or modify it
+-.\" under the terms of the GNU General Public License version 2 only, as
+-.\" published by the Free Software Foundation.
+-.\"
+-.\" This code is distributed in the hope that it will be useful, but WITHOUT
+-.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-.\" version 2 for more details (a copy is included in the LICENSE file that
+-.\" accompanied this code).
+-.\"
+-.\" You should have received a copy of the GNU General Public License version
+-.\" 2 along with this work; if not, write to the Free Software Foundation,
+-.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-.\"
+-.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-.\" or visit www.oracle.com if you need additional information or have any
+-.\" questions.
+-.\"
+-.\" Arch: generic
+-.\" Software: JDK 8
+-.\" Date: 10 May 2011
+-.\" SectDesc: Monitoring Tools
+-.\" Title: jstat.1
++.\" Copyright (c) 2004, 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.
++.\"
++.\" Title: jstat
++.\" Language: English
++.\" Date: 03 March 2015
++.\" SectDesc: Monitoring Tools
++.\" Software: JDK 8
++.\" Arch: generic
++.\" Part Number: E38207-04
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH jstat 1 "10 May 2011" "JDK 8" "Monitoring Tools"
+-.\" -----------------------------------------------------------------
+-.\" * Define some portability stuff
+-.\" -----------------------------------------------------------------
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.\" http://bugs.debian.org/507673
+-.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.ie \n(.g .ds Aq \(aq
+-.el .ds Aq '
+-.\" -----------------------------------------------------------------
+-.\" * set default formatting
+-.\" -----------------------------------------------------------------
+-.\" disable hyphenation
+-.nh
+-.\" disable justification (adjust text to left margin only)
+-.ad l
+-.\" -----------------------------------------------------------------
+-.\" * MAIN CONTENT STARTS HERE *
+-.\" -----------------------------------------------------------------
+-
+-.SH NAME
++.TH "jstat" "1" "03 March 2015" "JDK 8" "Monitoring Tools"
++.\" -----------------------------------------------------------------
++.\" * Define some portability stuff
++.\" -----------------------------------------------------------------
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.\" http://bugs.debian.org/507673
++.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.ie \n(.g .ds Aq \(aq
++.el .ds Aq '
++.\" -----------------------------------------------------------------
++.\" * set default formatting
++.\" -----------------------------------------------------------------
++.\" disable hyphenation
++.nh
++.\" disable justification (adjust text to left margin only)
++.ad l
++.\" -----------------------------------------------------------------
++.\" * MAIN CONTENT STARTS HERE *
++.\" -----------------------------------------------------------------
++.SH "NAME"
+ jstat \- Monitors Java Virtual Machine (JVM) statistics\&. This command is experimental and unsupported\&.
+-.SH SYNOPSIS
+-.sp
+-.nf
+-
++.SH "SYNOPSIS"
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
+ \fBjstat\fR [ \fIgeneralOption\fR | \fIoutputOptions vmid\fR [ \fIinterval\fR[s|ms] [ \fIcount \fR] ]
+-.fi
+-.sp
+-.TP
++.fi
++.if n \{\
++.RE
++.\}
++.PP
+ \fIgeneralOption\fR
+-A single general command-line option \f3-help\fR or \f3-options\fR\&. See General Options\&.
+-.TP
++.RS 4
++A single general command\-line option
++\fB\-help\fR
++or
++\fB\-options\fR\&. See General Options\&.
++.RE
++.PP
+ \fIoutputOptions\fR
+-One or more output options that consist of a single \f3statOption\fR, plus any of the \f3-t\fR, \f3-h\fR, and \f3-J\fR options\&. See Output Options\&.
+-.TP
++.RS 4
++One or more output options that consist of a single
++\fBstatOption\fR, plus any of the
++\fB\-t\fR,
++\fB\-h\fR, and
++\fB\-J\fR
++options\&. See Output Options\&.
++.RE
++.PP
+ \fIvmid\fR
++.RS 4
+ Virtual machine identifier, which is a string that indicates the target JVM\&. The general syntax is the following:
+-.sp
+-.nf
+-\f3[protocol:][//]lvmid[@hostname[:port]/servername]\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-
+-
+-The syntax of the \f3vmid\fR string corresponds to the syntax of a URI\&. The \f3vmid\fR string can vary from a simple integer that represents a local JVM to a more complex construction that specifies a communications protocol, port number, and other implementation-specific values\&. See Virtual Machine Identifier\&.
+-.TP
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[protocol:][//]lvmid[@hostname[:port]/servername]\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++The syntax of the
++\fBvmid\fR
++string corresponds to the syntax of a URI\&. The
++\fBvmid\fR
++string can vary from a simple integer that represents a local JVM to a more complex construction that specifies a communications protocol, port number, and other implementation\-specific values\&. See Virtual Machine Identifier\&.
++.RE
++.PP
+ \fIinterval\fR [s|ms]
+-Sampling interval in the specified units, seconds (s) or milliseconds (ms)\&. Default units are milliseconds\&. Must be a positive integer\&. When specified, the \f3jstat\fR command produces its output at each interval\&.
+-.TP
++.RS 4
++Sampling interval in the specified units, seconds (s) or milliseconds (ms)\&. Default units are milliseconds\&. Must be a positive integer\&. When specified, the
++\fBjstat\fR
++command produces its output at each interval\&.
++.RE
++.PP
+ \fIcount\fR
+-Number of samples to display\&. The default value is infinity which causes the \f3jstat\fR command to display statistics until the target JVM terminates or the \f3jstat\fR command is terminated\&. This value must be a positive integer\&.
+-.SH DESCRIPTION
+-The \f3jstat\fR command displays performance statistics for an instrumented Java HotSpot VM\&. The target JVM is identified by its virtual machine identifier, or \f3vmid\fR option\&.
+-.SH VIRTUAL\ MACHINE\ IDENTIFIER
+-The syntax of the \f3vmid\fR string corresponds to the syntax of a URI:
+-.sp
+-.nf
+-\f3[protocol:][//]lvmid[@hostname[:port]/servername]\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-.TP
++.RS 4
++Number of samples to display\&. The default value is infinity which causes the
++\fBjstat\fR
++command to display statistics until the target JVM terminates or the
++\fBjstat\fR
++command is terminated\&. This value must be a positive integer\&.
++.RE
++.SH "DESCRIPTION"
++.PP
++The
++\fBjstat\fR
++command displays performance statistics for an instrumented Java HotSpot VM\&. The target JVM is identified by its virtual machine identifier, or
++\fBvmid\fR
++option\&.
++.SH "VIRTUAL MACHINE IDENTIFIER"
++.PP
++The syntax of the
++\fBvmid\fR
++string corresponds to the syntax of a URI:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[protocol:][//]lvmid[@hostname[:port]/servername]\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.PP
+ \fIprotocol\fR
+-The communications protocol\&. If the \fIprotocol\fR value is omitted and a host name is not specified, then the default protocol is a platform-specific optimized local protocol\&. If the \fIprotocol\fR value is omitted and a host name is specified, then the default protocol is \f3rmi\fR\&.
+-.TP
++.RS 4
++The communications protocol\&. If the
++\fIprotocol\fR
++value is omitted and a host name is not specified, then the default protocol is a platform\-specific optimized local protocol\&. If the
++\fIprotocol\fR
++value is omitted and a host name is specified, then the default protocol is
++\fBrmi\fR\&.
++.RE
++.PP
+ \fIlvmid\fR
+-The local virtual machine identifier for the target JVM\&. The \f3lvmid\fR is a platform-specific value that uniquely identifies a JVM on a system\&. The \f3lvmid\fR is the only required component of a virtual machine identifier\&. The \f3lvmid\fR is typically, but not necessarily, the operating system\&'s process identifier for the target JVM process\&. You can use the \f3jps\fR command to determine the \f3lvmid\fR\&. Also, you can determine the \f3lvmid\fR on UNIX platforms with the \f3ps\fR command, and on Windows with the Windows Task Manager\&.
+-.TP
++.RS 4
++The local virtual machine identifier for the target JVM\&. The
++\fBlvmid\fR
++is a platform\-specific value that uniquely identifies a JVM on a system\&. The
++\fBlvmid\fR
++is the only required component of a virtual machine identifier\&. The
++\fBlvmid\fR
++is typically, but not necessarily, the operating system\*(Aqs process identifier for the target JVM process\&. You can use the
++\fBjps\fR
++command to determine the
++\fBlvmid\fR\&. Also, you can determine the
++\fBlvmid\fR
++on Solaris, Linux, and OS X platforms with the
++\fBps\fR
++command, and on Windows with the Windows Task Manager\&.
++.RE
++.PP
+ \fIhostname\fR
+-A hostname or IP address that indicates the target host\&. If the \fIhostname\fR value is omitted, then the target host is the local host\&.
+-.TP
++.RS 4
++A hostname or IP address that indicates the target host\&. If the
++\fIhostname\fR
++value is omitted, then the target host is the local host\&.
++.RE
++.PP
+ \fIport\fR
+-The default port for communicating with the remote server\&. If the \fIhostname\fR value is omitted or the \fIprotocol\fR value specifies an optimized, local protocol, then the \fIport\fR value is ignored\&. Otherwise, treatment of the \f3port\fR parameter is implementation-specific\&. For the default \f3rmi\fR protocol, the port value indicates the port number for the rmiregistry on the remote host\&. If the \fIport\fR value is omitted and the \fIprotocol\fR value indicates \f3rmi\fR, then the default rmiregistry port (1099) is used\&.
+-.TP
++.RS 4
++The default port for communicating with the remote server\&. If the
++\fIhostname\fR
++value is omitted or the
++\fIprotocol\fR
++value specifies an optimized, local protocol, then the
++\fIport\fR
++value is ignored\&. Otherwise, treatment of the
++\fBport\fR
++parameter is implementation\-specific\&. For the default
++\fBrmi\fR
++protocol, the port value indicates the port number for the rmiregistry on the remote host\&. If the
++\fIport\fR
++value is omitted and the
++\fIprotocol\fR
++value indicates
++\fBrmi\fR, then the default rmiregistry port (1099) is used\&.
++.RE
++.PP
+ \fIservername\fR
+-The treatment of the \f3servername\fR parameter depends on implementation\&. For the optimized local protocol, this field is ignored\&. For the \f3rmi\fR protocol, it represents the name of the RMI remote object on the remote host\&.
+-.SH OPTIONS
+-The \f3jstat\fR command supports two types of options, general options and output options\&. General options cause the \f3jstat\fR command to display simple usage and version information\&. Output options determine the content and format of the statistical output\&.
++.RS 4
++The treatment of the
++\fBservername\fR
++parameter depends on implementation\&. For the optimized local protocol, this field is ignored\&. For the
++\fBrmi\fR
++protocol, it represents the name of the RMI remote object on the remote host\&.
++.RE
++.SH "OPTIONS"
++.PP
++The
++\fBjstat\fR
++command supports two types of options, general options and output options\&. General options cause the
++\fBjstat\fR
++command to display simple usage and version information\&. Output options determine the content and format of the statistical output\&.
+ .PP
+ All options and their functionality are subject to change or removal in future releases\&.
+-.SS GENERAL\ OPTIONS
++.SS "General Options"
++.PP
+ If you specify one of the general options, then you cannot specify any other option or parameter\&.
+-.TP
+--help
+-.br
++.PP
++\-help
++.RS 4
+ Displays a help message\&.
+-.TP
+--options
+-.br
++.RE
++.PP
++\-options
++.RS 4
+ Displays a list of static options\&. See Output Options\&.
+-.SS OUTPUT\ OPTIONS
+-If you do not specify a general option, then you can specify output options\&. Output options determine the content and format of the \f3jstat\fR command\&'s output, and consist of a single \f3statOption\fR, plus any of the other output options (\f3-h\fR, \f3-t\fR, and \f3-J\fR)\&. The \f3statOption\fR must come first\&.
++.RE
++.SS "Output Options"
+ .PP
+-Output is formatted as a table, with columns that are separated by spaces\&. A header row with titles describes the columns\&. Use the \f3-h\fR option to set the frequency at which the header is displayed\&. Column header names are consistent among the different options\&. In general, if two options provide a column with the same name, then the data source for the two columns is the same\&.
++If you do not specify a general option, then you can specify output options\&. Output options determine the content and format of the
++\fBjstat\fR
++command\*(Aqs output, and consist of a single
++\fBstatOption\fR, plus any of the other output options (\fB\-h\fR,
++\fB\-t\fR, and
++\fB\-J\fR)\&. The
++\fBstatOption\fR
++must come first\&.
+ .PP
+-Use the \f3-t\fR option to display a time stamp column, labeled Timestamp as the first column of output\&. The Timestamp column contains the elapsed time, in seconds, since the target JVM started\&. The resolution of the time stamp is dependent on various factors and is subject to variation due to delayed thread scheduling on heavily loaded systems\&.
++Output is formatted as a table, with columns that are separated by spaces\&. A header row with titles describes the columns\&. Use the
++\fB\-h\fR
++option to set the frequency at which the header is displayed\&. Column header names are consistent among the different options\&. In general, if two options provide a column with the same name, then the data source for the two columns is the same\&.
+ .PP
+-Use the interval and count parameters to determine how frequently and how many times, respectively, the \f3jstat\fR command displays its output\&.
++Use the
++\fB\-t\fR
++option to display a time stamp column, labeled Timestamp as the first column of output\&. The Timestamp column contains the elapsed time, in seconds, since the target JVM started\&. The resolution of the time stamp is dependent on various factors and is subject to variation due to delayed thread scheduling on heavily loaded systems\&.
+ .PP
+-\fINote:\fR Do not to write scripts to parse the \f3jstat\fR command\&'s output because the format might change in future releases\&. If you write scripts that parse \f3jstat\fR command output, then expect to modify them for future releases of this tool\&.
+-.TP
+--\fIstatOption\fR
+-.br
+-Determines the statistics information the \f3jstat\fR command displays\&. The following lists the available options\&. Use the \f3-options\fR general option to display the list of options for a particular platform installation\&. See Stat Options and Output\&.
+-
+-\f3class\fR: Displays statistics about the behavior of the class loader\&.
+-
+-\f3compiler\fR: Displays statistics about the behavior of the Java HotSpot VM Just-in-Time compiler\&.
+-
+-\f3gc\fR: Displays statistics about the behavior of the garbage collected heap\&.
+-
+-\f3gccapacity\fR: Displays statistics about the capacities of the generations and their corresponding spaces\&.
+-
+-\f3gccause\fR: Displays a summary about garbage collection statistics (same as \f3-gcutil\fR), with the cause of the last and current (when applicable) garbage collection events\&.
+-
+-\f3gcnew\fR: Displays statistics of the behavior of the new generation\&.
+-
+-\f3gcnewcapacity\fR: Displays statistics about the sizes of the new generations and its corresponding spaces\&.
+-
+-\f3gcold\fR: Displays statistics about the behavior of the old generation and Metaspace Statistics\&.
+-
+-\f3gcoldcapacity\fR: Displays statistics about the sizes of the old generation\&.
+-
+-\f3gcmetacapacity\fR: Displays statistics about the sizes of the metaspace\&.
+-
+-\f3gcutil\fR: Displays a summary about garbage collection statistics\&.
+-
+-\f3printcompilation\fR: Displays Java HotSpot VM compilation method statistics\&.
+-.TP
+--h \fIn\fR
+-.br
+-Displays a column header every \fIn\fR samples (output rows), where \fIn\fR is a positive integer\&. Default value is 0, which displays the column header the first row of data\&.
+-.TP
+--t
+-.br
+-Display sa timestamp column as the first column of output\&. The time stamp is the time since the start time of the target JVM\&.
+-.TP
+--J\fIjavaOption\fR
+-.br
+-Passes \f3javaOption\fR to the Java application launcher\&. For example, \f3-J-Xms48m\fR sets the startup memory to 48 MB\&. For a complete list of options, see java(1)\&.
+-.SS STAT\ OPTIONS\ AND\ OUTPUT
+-The following information summarizes the columns that the \f3jstat\fR command outputs for each \fIstatOption\fR\&.
+-.TP
+--class \fIoption\fR
+-.br
++Use the interval and count parameters to determine how frequently and how many times, respectively, the
++\fBjstat\fR
++command displays its output\&.
++.PP
++\fBNote:\fR
++Do not to write scripts to parse the
++\fBjstat\fR
++command\*(Aqs output because the format might change in future releases\&. If you write scripts that parse
++\fBjstat\fR
++command output, then expect to modify them for future releases of this tool\&.
++.PP
++\-\fIstatOption\fR
++.RS 4
++Determines the statistics information the
++\fBjstat\fR
++command displays\&. The following lists the available options\&. Use the
++\fB\-options\fR
++general option to display the list of options for a particular platform installation\&. See Stat Options and Output\&.
++.sp
++\fBclass\fR: Displays statistics about the behavior of the class loader\&.
++.sp
++\fBcompiler\fR: Displays statistics about the behavior of the Java HotSpot VM Just\-in\-Time compiler\&.
++.sp
++\fBgc\fR: Displays statistics about the behavior of the garbage collected heap\&.
++.sp
++\fBgccapacity\fR: Displays statistics about the capacities of the generations and their corresponding spaces\&.
++.sp
++\fBgccause\fR: Displays a summary about garbage collection statistics (same as
++\fB\-gcutil\fR), with the cause of the last and current (when applicable) garbage collection events\&.
++.sp
++\fBgcnew\fR: Displays statistics of the behavior of the new generation\&.
++.sp
++\fBgcnewcapacity\fR: Displays statistics about the sizes of the new generations and its corresponding spaces\&.
++.sp
++\fBgcold\fR: Displays statistics about the behavior of the old generation and metaspace statistics\&.
++.sp
++\fBgcoldcapacity\fR: Displays statistics about the sizes of the old generation\&.
++.sp
++\fBgcmetacapacity\fR: Displays statistics about the sizes of the metaspace\&.
++.sp
++\fBgcutil\fR: Displays a summary about garbage collection statistics\&.
++.sp
++\fBprintcompilation\fR: Displays Java HotSpot VM compilation method statistics\&.
++.RE
++.PP
++\-h \fIn\fR
++.RS 4
++Displays a column header every
++\fIn\fR
++samples (output rows), where
++\fIn\fR
++is a positive integer\&. Default value is 0, which displays the column header the first row of data\&.
++.RE
++.PP
++\-t
++.RS 4
++Displays a timestamp column as the first column of output\&. The time stamp is the time since the start time of the target JVM\&.
++.RE
++.PP
++\-J\fIjavaOption\fR
++.RS 4
++Passes
++\fBjavaOption\fR
++to the Java application launcher\&. For example,
++\fB\-J\-Xms48m\fR
++sets the startup memory to 48 MB\&. For a complete list of options, see
++java(1)\&.
++.RE
++.SS "Stat Options and Output"
++.PP
++The following information summarizes the columns that the
++\fBjstat\fR
++command outputs for each
++\fIstatOption\fR\&.
++.PP
++\-class \fIoption\fR
++.RS 4
+ Class loader statistics\&.
+-
+-\f3Loaded\fR: Number of classes loaded\&.
+-
+-\f3Bytes\fR: Number of KBs loaded\&.
+-
+-\f3Unloaded\fR: Number of classes unloaded\&.
+-
+-\f3Bytes\fR: Number of Kbytes unloaded\&.
+-
+-\f3Time\fR: Time spent performing class loading and unloading operations\&.
+-.TP
+--compiler \fIoption\fR
+-.br
+-Java HotSpot VM Just-in-Time compiler statistics\&.
+-
+-\f3Compiled\fR: Number of compilation tasks performed\&.
+-
+-\f3Failed\fR: Number of compilations tasks failed\&.
+-
+-\f3Invalid\fR: Number of compilation tasks that were invalidated\&.
+-
+-\f3Time\fR: Time spent performing compilation tasks\&.
+-
+-\f3FailedType\fR: Compile type of the last failed compilation\&.
+-
+-\f3FailedMethod\fR: Class name and method of the last failed compilation\&.
+-.TP
+--gc \fIoption\fR
+-.br
+-Garbage-collected heap statistics\&.
+-
+-\f3S0C\fR: Current survivor space 0 capacity (KB)\&.
+-
+-\f3S1C\fR: Current survivor space 1 capacity (KB)\&.
+-
+-\f3S0U\fR: Survivor space 0 utilization (KB)\&.
+-
+-\f3S1U\fR: Survivor space 1 utilization (KB)\&.
+-
+-\f3EC\fR: Current eden space capacity (KB)\&.
+-
+-\f3EU\fR: Eden space utilization (KB)\&.
+-
+-\f3OC\fR: Current old space capacity (KB)\&.
+-
+-\f3OU\fR: Old space utilization (KB)\&.
+-
+-\f3MC\fR: Metaspace capacity (KB)\&.
+-
+-\f3MU\fR: Metacspace utilization (KB)\&.
+-
+-\f3YGC\fR: Number of young generation garbage collection events\&.
+-
+-\f3YGCT\fR: Young generation garbage collection time\&.
+-
+-\f3FGC\fR: Number of full GC events\&.
+-
+-\f3FGCT\fR: Full garbage collection time\&.
+-
+-\f3GCT\fR: Total garbage collection time\&.
+-.TP
+--gccapacity \fIoption\fR
+-.br
++.sp
++\fBLoaded\fR: Number of classes loaded\&.
++.sp
++\fBBytes\fR: Number of kBs loaded\&.
++.sp
++\fBUnloaded\fR: Number of classes unloaded\&.
++.sp
++\fBBytes\fR: Number of Kbytes unloaded\&.
++.sp
++\fBTime\fR: Time spent performing class loading and unloading operations\&.
++.RE
++.PP
++\-compiler \fIoption\fR
++.RS 4
++Java HotSpot VM Just\-in\-Time compiler statistics\&.
++.sp
++\fBCompiled\fR: Number of compilation tasks performed\&.
++.sp
++\fBFailed\fR: Number of compilations tasks failed\&.
++.sp
++\fBInvalid\fR: Number of compilation tasks that were invalidated\&.
++.sp
++\fBTime\fR: Time spent performing compilation tasks\&.
++.sp
++\fBFailedType\fR: Compile type of the last failed compilation\&.
++.sp
++\fBFailedMethod\fR: Class name and method of the last failed compilation\&.
++.RE
++.PP
++\-gc \fIoption\fR
++.RS 4
++Garbage\-collected heap statistics\&.
++.sp
++\fBS0C\fR: Current survivor space 0 capacity (kB)\&.
++.sp
++\fBS1C\fR: Current survivor space 1 capacity (kB)\&.
++.sp
++\fBS0U\fR: Survivor space 0 utilization (kB)\&.
++.sp
++\fBS1U\fR: Survivor space 1 utilization (kB)\&.
++.sp
++\fBEC\fR: Current eden space capacity (kB)\&.
++.sp
++\fBEU\fR: Eden space utilization (kB)\&.
++.sp
++\fBOC\fR: Current old space capacity (kB)\&.
++.sp
++\fBOU\fR: Old space utilization (kB)\&.
++.sp
++\fBMC\fR: Metaspace capacity (kB)\&.
++.sp
++\fBMU\fR: Metacspace utilization (kB)\&.
++.sp
++\fBCCSC\fR: Compressed class space capacity (kB)\&.
++.sp
++\fBCCSU\fR: Compressed class space used (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation garbage collection events\&.
++.sp
++\fBYGCT\fR: Young generation garbage collection time\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.sp
++\fBFGCT\fR: Full garbage collection time\&.
++.sp
++\fBGCT\fR: Total garbage collection time\&.
++.RE
++.PP
++\-gccapacity \fIoption\fR
++.RS 4
+ Memory pool generation and space capacities\&.
+-
+-\f3NGCMN\fR: Minimum new generation capacity (KB)\&.
+-
+-\f3NGCMX\fR: Maximum new generation capacity (KB)\&.
+-
+-\f3NGC\fR: Current new generation capacity (KB)\&.
+-
+-\f3S0C\fR: Current survivor space 0 capacity (KB)\&.
+-
+-\f3S1C\fR: Current survivor space 1 capacity (KB)\&.
+-
+-\f3EC\fR: Current eden space capacity (KB)\&.
+-
+-\f3OGCMN\fR: Minimum old generation capacity (KB)\&.
+-
+-\f3OGCMX\fR: Maximum old generation capacity (KB)\&.
+-
+-\f3OGC\fR: Current old generation capacity (KB)\&.
+-
+-\f3OC\fR: Current old space capacity (KB)\&.
+-
+-\f3MCMN\fR: Minimum metaspace capacity (KB)\&.
+-
+-\f3MCMX\fR: Maximum metaspace capacity (KB)\&.
+-
+-\f3MC\fR: Metaspace capacity (KB)\&.
+-
+-\f3YGC\fR: Number of Young generation GC Events\&.
+-
+-\f3FGC\fR: Number of Full GC Events\&.
+-.TP
+--gccause \fIoption\fR
+-.br
+-This option displays the same summary of garbage collection statistics as the \f3-gcutil\fR option, but includes the causes of the last garbage collection event and (when applicable) the current garbage collection event\&. In addition to the columns listed for \f3-gcutil\fR, this option adds the following columns\&.
+-
+-Garbage collection statistics, including garbage collection Events\&.
+-
+-\f3LGCC\fR: Cause of last garbage collection\&.
+-
+-\f3GCC\fR: Cause of current garbage collection\&.
+-.TP
+--gcnew \fIoption\fR
+-.br
++.sp
++\fBNGCMN\fR: Minimum new generation capacity (kB)\&.
++.sp
++\fBNGCMX\fR: Maximum new generation capacity (kB)\&.
++.sp
++\fBNGC\fR: Current new generation capacity (kB)\&.
++.sp
++\fBS0C\fR: Current survivor space 0 capacity (kB)\&.
++.sp
++\fBS1C\fR: Current survivor space 1 capacity (kB)\&.
++.sp
++\fBEC\fR: Current eden space capacity (kB)\&.
++.sp
++\fBOGCMN\fR: Minimum old generation capacity (kB)\&.
++.sp
++\fBOGCMX\fR: Maximum old generation capacity (kB)\&.
++.sp
++\fBOGC\fR: Current old generation capacity (kB)\&.
++.sp
++\fBOC\fR: Current old space capacity (kB)\&.
++.sp
++\fBMCMN\fR: Minimum metaspace capacity (kB)\&.
++.sp
++\fBMCMX\fR: Maximum metaspace capacity (kB)\&.
++.sp
++\fBMC\fR: Metaspace capacity (kB)\&.
++.sp
++\fBCCSMN\fR: Compressed class space minimum capacity (kB)\&.
++.sp
++\fBCCSMX\fR: Compressed class space maximum capacity (kB)\&.
++.sp
++\fBCCSC\fR: Compressed class space capacity (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.RE
++.PP
++\-gccause \fIoption\fR
++.RS 4
++This option displays the same summary of garbage collection statistics as the
++\fB\-gcutil\fR
++option, but includes the causes of the last garbage collection event and (when applicable) the current garbage collection event\&. In addition to the columns listed for
++\fB\-gcutil\fR, this option adds the following columns\&.
++.sp
++\fBLGCC\fR: Cause of last garbage collection
++.sp
++\fBGCC\fR: Cause of current garbage collection
++.RE
++.PP
++\-gcnew \fIoption\fR
++.RS 4
+ New generation statistics\&.
+-
+-\f3S0C\fR: Current survivor space 0 capacity (KB)\&.
+-
+-\f3S1C\fR: Current survivor space 1 capacity (KB)\&.
+-
+-\f3S0U\fR: Survivor space 0 utilization (KB)\&.
+-
+-\f3S1U\fR: Survivor space 1 utilization (KB)\&.
+-
+-\f3TT\fR: Tenuring threshold\&.
+-
+-\f3MTT\fR: Maximum tenuring threshold\&.
+-
+-\f3DSS\fR: Desired survivor size (KB)\&.
+-
+-\f3EC\fR: Current eden space capacity (KB)\&.
+-
+-\f3EU\fR: Eden space utilization (KB)\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3YGCT\fR: Young generation garbage collection time\&.
+-.TP
+--gcnewcapacity \fIoption\fR
+-.br
++.sp
++\fBS0C\fR: Current survivor space 0 capacity (kB)\&.
++.sp
++\fBS1C\fR: Current survivor space 1 capacity (kB)\&.
++.sp
++\fBS0U\fR: Survivor space 0 utilization (kB)\&.
++.sp
++\fBS1U\fR: Survivor space 1 utilization (kB)\&.
++.sp
++\fBTT\fR: Tenuring threshold\&.
++.sp
++\fBMTT\fR: Maximum tenuring threshold\&.
++.sp
++\fBDSS\fR: Desired survivor size (kB)\&.
++.sp
++\fBEC\fR: Current eden space capacity (kB)\&.
++.sp
++\fBEU\fR: Eden space utilization (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBYGCT\fR: Young generation garbage collection time\&.
++.RE
++.PP
++\-gcnewcapacity \fIoption\fR
++.RS 4
+ New generation space size statistics\&.
+-
+-NGCMN: Minimum new generation capacity (KB)\&.
+-
+-\f3NGCMX\fR: Maximum new generation capacity (KB)\&.
+-
+-\f3NGC\fR: Current new generation capacity (KB)\&.
+-
+-\f3S0CMX\fR: Maximum survivor space 0 capacity (KB)\&.
+-
+-\f3S0C\fR: Current survivor space 0 capacity (KB)\&.
+-
+-\f3S1CMX\fR: Maximum survivor space 1 capacity (KB)\&.
+-
+-\f3S1C\fR: Current survivor space 1 capacity (KB)\&.
+-
+-\f3ECMX\fR: Maximum eden space capacity (KB)\&.
+-
+-\f3EC\fR: Current eden space capacity (KB)\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3FGC\fR: Number of Full GC Events\&.
+-.TP
+--gcold \fIoption\fR
+-.br
+-old and permanent generation statistics\&.
+-
+-\f3MC\fR: Metaspace capacity (KB)\&.
+-
+-\f3MU\fR: Metaspace utilization (KB)\&.
+-
+-\f3OC\fR: Current old space capacity (KB)\&.
+-
+-\f3OU\fR: old space utilization (KB)\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3FGC\fR: Number of full GC events\&.
+-
+-\f3FGCT\fR: Full garbage collection time\&.
+-
+-\f3GCT\fR: Total garbage collection time\&.
+-.TP
+--gcoldcapacity \fIoption\fR
+-.br
+-Old generation statistics\&.
+-
+-\f3OGCMN\fR: Minimum old generation capacity (KB)\&.
+-
+-\f3OGCMX\fR: Maximum old generation capacity (KB)\&.
+-
+-\f3OGC\fR: Current old generation capacity (KB)\&.
+-
+-\f3OC\fR: Current old space capacity (KB)\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3FGC\fR: Number of full GC events\&.
+-
+-\f3FGCT\fR: Full garbage collection time\&.
+-
+-\f3GCT\fR: Total garbage collection time\&.
+-.TP
+--gcmetacapacity \fIoption\fR
+-.br
+-Permanent generation statistics\&.
+-
+-\f3MCMN\fR: Minimum metaspace capacity (KB)\&.
+-
+-\f3MCMX\fR: Maximum metaspace capacity (KB)\&.
+-
+-\f3MC\fR: Metaspace capacity (KB)\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3FGC\fR: Number of full GC events\&.
+-
+-\f3FGCT\fR: Full garbage collection time\&.
+-
+-\f3GCT\fR: Total garbage collection time\&.
+-.TP
+--gcutil \fIoption\fR
+-.br
++.sp
++\fBNGCMN\fR: Minimum new generation capacity (kB)\&.
++.sp
++\fBNGCMX\fR: Maximum new generation capacity (kB)\&.
++.sp
++\fBNGC\fR: Current new generation capacity (kB)\&.
++.sp
++\fBS0CMX\fR: Maximum survivor space 0 capacity (kB)\&.
++.sp
++\fBS0C\fR: Current survivor space 0 capacity (kB)\&.
++.sp
++\fBS1CMX\fR: Maximum survivor space 1 capacity (kB)\&.
++.sp
++\fBS1C\fR: Current survivor space 1 capacity (kB)\&.
++.sp
++\fBECMX\fR: Maximum eden space capacity (kB)\&.
++.sp
++\fBEC\fR: Current eden space capacity (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.RE
++.PP
++\-gcold \fIoption\fR
++.RS 4
++Old generation and metaspace behavior statistics\&.
++.sp
++\fBMC\fR: Metaspace capacity (kB)\&.
++.sp
++\fBMU\fR: Metaspace utilization (kB)\&.
++.sp
++\fBCCSC\fR: Compressed class space capacity (kB)\&.
++.sp
++\fBCCSU\fR: Compressed class space used (kB)\&.
++.sp
++\fBOC\fR: Current old space capacity (kB)\&.
++.sp
++\fBOU\fR: Old space utilization (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.sp
++\fBFGCT\fR: Full garbage collection time\&.
++.sp
++\fBGCT\fR: Total garbage collection time\&.
++.RE
++.PP
++\-gcoldcapacity \fIoption\fR
++.RS 4
++Old generation size statistics\&.
++.sp
++\fBOGCMN\fR: Minimum old generation capacity (kB)\&.
++.sp
++\fBOGCMX\fR: Maximum old generation capacity (kB)\&.
++.sp
++\fBOGC\fR: Current old generation capacity (kB)\&.
++.sp
++\fBOC\fR: Current old space capacity (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.sp
++\fBFGCT\fR: Full garbage collection time\&.
++.sp
++\fBGCT\fR: Total garbage collection time\&.
++.RE
++.PP
++\-gcmetacapacity \fIoption\fR
++.RS 4
++Metaspace size statistics\&.
++.sp
++\fBMCMN\fR: Minimum metaspace capacity (kB)\&.
++.sp
++\fBMCMX\fR: Maximum metaspace capacity (kB)\&.
++.sp
++\fBMC\fR: Metaspace capacity (kB)\&.
++.sp
++\fBCCSMN\fR: Compressed class space minimum capacity (kB)\&.
++.sp
++\fBCCSMX\fR: Compressed class space maximum capacity (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.sp
++\fBFGCT\fR: Full garbage collection time\&.
++.sp
++\fBGCT\fR: Total garbage collection time\&.
++.RE
++.PP
++\-gcutil \fIoption\fR
++.RS 4
+ Summary of garbage collection statistics\&.
+-
+-\f3S0\fR: Survivor space 0 utilization as a percentage of the space\&'s current capacity\&.
+-
+-\f3S1\fR: Survivor space 1 utilization as a percentage of the space\&'s current capacity\&.
+-
+-\f3E\fR: Eden space utilization as a percentage of the space\&'s current capacity\&.
+-
+-\f3O\fR: Old space utilization as a percentage of the space\&'s current capacity\&.
+-
+-\f3M\fR: Metaspace utilization as a percentage of the space\&'s current capacity\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3YGCT\fR: Young generation garbage collection time\&.
+-
+-\f3FGC\fR: Number of full GC events\&.
+-
+-\f3FGCT\fR: Full garbage collection time\&.
+-
+-\f3GCT\fR: Total garbage collection time\&.
+-.TP
+--printcompilation \fIoption\fR
+-.br
++.sp
++\fBS0\fR: Survivor space 0 utilization as a percentage of the space\*(Aqs current capacity\&.
++.sp
++\fBS1\fR: Survivor space 1 utilization as a percentage of the space\*(Aqs current capacity\&.
++.sp
++\fBE\fR: Eden space utilization as a percentage of the space\*(Aqs current capacity\&.
++.sp
++\fBO\fR: Old space utilization as a percentage of the space\*(Aqs current capacity\&.
++.sp
++\fBM\fR: Metaspace utilization as a percentage of the space\*(Aqs current capacity\&.
++.sp
++\fBCCS\fR: Compressed class space utilization as a percentage\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBYGCT\fR: Young generation garbage collection time\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.sp
++\fBFGCT\fR: Full garbage collection time\&.
++.sp
++\fBGCT\fR: Total garbage collection time\&.
++.RE
++.PP
++\-printcompilation \fIoption\fR
++.RS 4
+ Java HotSpot VM compiler method statistics\&.
+-
+-\f3Compiled\fR: Number of compilation tasks performed by the most recently compiled method\&.
+-
+-\f3Size\fR: Number of bytes of byte code of the most recently compiled method\&.
+-
+-\f3Type\fR: Compilation type of the most recently compiled method\&.
+-
+-\f3Method\fR: Class name and method name identifying the most recently compiled method\&. Class name uses slash (/) instead of dot (\&.) as a name space separator\&. Method name is the method within the specified class\&. The format for these two fields is consistent with the HotSpot \f3-XX:+PrintComplation\fR option\&.
+-.SH EXAMPLES
+-This section presents some examples of monitoring a local JVM with an \fIlvmid\fR of 21891\&.
+-.SS THE\ GCUTIL\ OPTION
+-This example attaches to lvmid 21891 and takes 7 samples at 250 millisecond intervals and displays the output as specified by the -\f3gcutil\fR option\&.
++.sp
++\fBCompiled\fR: Number of compilation tasks performed by the most recently compiled method\&.
++.sp
++\fBSize\fR: Number of bytes of byte code of the most recently compiled method\&.
++.sp
++\fBType\fR: Compilation type of the most recently compiled method\&.
++.sp
++\fBMethod\fR: Class name and method name identifying the most recently compiled method\&. Class name uses slash (/) instead of dot (\&.) as a name space separator\&. Method name is the method within the specified class\&. The format for these two fields is consistent with the HotSpot
++\fB\-XX:+PrintCompilation\fR
++option\&.
++.RE
++.SH "EXAMPLES"
+ .PP
+-The output of this example shows that a young generation collection occurred between the third and fourth sample\&. The collection took 0\&.001 seconds and promoted objects from the eden space (E) to the old space (O), resulting in an increase of old space utilization from 9\&.49% to 9\&.51%\&. Before the collection, the survivor space was 12\&.44% utilized, but after this collection it is only 7\&.74% utilized\&.
+-.sp
+-.nf
+-\f3jstat \-gcutil 21891 250 7\fP
+-.fi
+-.nf
+-\f3 S0 S1 E O M YGC YGCT FGC FGCT GCT\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.80 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.80 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.80 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-.SS REPEAT\ THE\ COLUMN\ HEADER\ STRING
+-This example attaches to lvmid 21891 and takes samples at 250 millisecond intervals and displays the output as specified by \f3-gcutil\fR option\&. In addition, it uses the \f3-h3\fR option to output the column header after every 3 lines of data\&.
++This section presents some examples of monitoring a local JVM with an
++\fIlvmid\fR
++of 21891\&.
++.SS "The gcutil Option"
++.PP
++This example attaches to lvmid 21891 and takes 7 samples at 250 millisecond intervals and displays the output as specified by the \-\fBgcutil\fR
++option\&.
++.PP
++The output of this example shows that a young generation collection occurred between the third and fourth sample\&. The collection took 0\&.078 seconds and promoted objects from the eden space (E) to the old space (O), resulting in an increase of old space utilization from 66\&.80% to 68\&.19%\&. Before the collection, the survivor space was 97\&.02% utilized, but after this collection it is 91\&.03% utilized\&.
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjstat \-gcutil 21891 250 7\fR
++\fB S0 S1 E O M CCS YGC YGCT FGC FGCT GCT \fR
++\fB 0\&.00 97\&.02 70\&.31 66\&.80 95\&.52 89\&.14 7 0\&.300 0 0\&.000 0\&.300\fR
++\fB 0\&.00 97\&.02 86\&.23 66\&.80 95\&.52 89\&.14 7 0\&.300 0 0\&.000 0\&.300\fR
++\fB 0\&.00 97\&.02 96\&.53 66\&.80 95\&.52 89\&.14 7 0\&.300 0 0\&.000 0\&.300\fR
++\fB 91\&.03 0\&.00 1\&.98 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++\fB 91\&.03 0\&.00 15\&.82 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++\fB 91\&.03 0\&.00 17\&.80 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++\fB 91\&.03 0\&.00 17\&.80 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++.fi
++.if n \{\
++.RE
++.\}
++.SS "Repeat the Column Header String"
++.PP
++This example attaches to lvmid 21891 and takes samples at 250 millisecond intervals and displays the output as specified by
++\fB\-gcnew\fR
++option\&. In addition, it uses the
++\fB\-h3\fR
++option to output the column header after every 3 lines of data\&.
+ .PP
+ In addition to showing the repeating header string, this example shows that between the second and third samples, a young GC occurred\&. Its duration was 0\&.001 seconds\&. The collection found enough active data that the survivor space 0 utilization (S0U) would have exceeded the desired survivor Size (DSS)\&. As a result, objects were promoted to the old generation (not visible in this output), and the tenuring threshold (TT) was lowered from 31 to 2\&.
+ .PP
+ Another collection occurs between the fifth and sixth samples\&. This collection found very few survivors and returned the tenuring threshold to 31\&.
+-.sp
+-.nf
+-\f3jstat \-gcnew \-h3 21891 250\fP
+-.fi
+-.nf
+-\f3 S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 0\&.0 31\&.7 31 31 32\&.0 512\&.0 178\&.6 249 0\&.203\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 0\&.0 31\&.7 31 31 32\&.0 512\&.0 355\&.5 249 0\&.203\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 21\&.9 250 0\&.204\fP
+-.fi
+-.nf
+-\f3 S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 245\&.9 250 0\&.204\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 421\&.1 250 0\&.204\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 0\&.0 19\&.0 31 31 32\&.0 512\&.0 84\&.4 251 0\&.204\fP
+-.fi
+-.nf
+-\f3 S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 0\&.0 19\&.0 31 31 32\&.0 512\&.0 306\&.7 251 0\&.204\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-.SS INCLUDE\ A\ TIME\ STAMP\ FOR\ EACH\ SAMPLE
+-This example attaches to lvmid 21891 and takes 3 samples at 250 millisecond intervals\&. The \f3-t\fR option is used to generate a time stamp for each sample in the first column\&.
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjstat \-gcnew \-h3 21891 250\fR
++\fB S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fR
++\fB 64\&.0 64\&.0 0\&.0 31\&.7 31 31 32\&.0 512\&.0 178\&.6 249 0\&.203\fR
++\fB 64\&.0 64\&.0 0\&.0 31\&.7 31 31 32\&.0 512\&.0 355\&.5 249 0\&.203\fR
++\fB 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 21\&.9 250 0\&.204\fR
++\fB S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fR
++\fB 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 245\&.9 250 0\&.204\fR
++\fB 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 421\&.1 250 0\&.204\fR
++\fB 64\&.0 64\&.0 0\&.0 19\&.0 31 31 32\&.0 512\&.0 84\&.4 251 0\&.204\fR
++\fB S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fR
++\fB 64\&.0 64\&.0 0\&.0 19\&.0 31 31 32\&.0 512\&.0 306\&.7 251 0\&.204\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.SS "Include a Time Stamp for Each Sample"
+ .PP
+-The Timestamp column reports the elapsed time in seconds since the start of the target JVM\&. In addition, the \f3-gcoldcapacity\fR output shows the old generation capacity (OGC) and the old space capacity (OC) increasing as the heap expands to meet allocation or promotion demands\&. The old generation capacity (OGC) has grown to from 11,696 KB to 13820 KB after the eighty-first full garbage collection (FGC)\&. The maximum capacity of the generation (and space) is 60,544 KB (OGCMX), so it still has room to expand\&.
+-.sp
+-.nf
+-\f3Timestamp OGCMN OGCMX OGC OC YGC FGC FGCT GCT\fP
+-.fi
+-.nf
+-\f3 150\&.1 1408\&.0 60544\&.0 11696\&.0 11696\&.0 194 80 2\&.874 3\&.799\fP
+-.fi
+-.nf
+-\f3 150\&.4 1408\&.0 60544\&.0 13820\&.0 13820\&.0 194 81 2\&.938 3\&.863\fP
+-.fi
+-.nf
+-\f3 150\&.7 1408\&.0 60544\&.0 13820\&.0 13820\&.0 194 81 2\&.938 3\&.863\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-.SS MONITOR\ INSTRUMENTATION\ FOR\ A\ REMOTE\ JVM
+-This example attaches to lvmid 40496 on the system named remote\&.domain using the \f3-gcutil\fR option, with samples taken every second indefinitely\&.
++This example attaches to lvmid 21891 and takes 3 samples at 250 millisecond intervals\&. The
++\fB\-t\fR
++option is used to generate a time stamp for each sample in the first column\&.
+ .PP
+-The lvmid is combined with the name of the remote host to construct a \fIvmid\fR of \f340496@remote\&.domain\fR\&. This vmid results in the use of the \f3rmi\fR protocol to communicate to the default \f3jstatd\fR server on the remote host\&. The \f3jstatd\fR server is located using the rmiregistry on \f3remote\&.domain\fR that is bound to the default rmiregistry port (port 1099)\&.
+-.sp
+-.nf
+-\f3jstat \-gcutil 40496@remote\&.domain 1000\fP
+-.fi
+-.nf
+-\f3\fI\&.\&.\&. output omitted\fR\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-.SH SEE\ ALSO
+-.TP 0.2i
+-\(bu
++The Timestamp column reports the elapsed time in seconds since the start of the target JVM\&. In addition, the
++\fB\-gcoldcapacity\fR
++output shows the old generation capacity (OGC) and the old space capacity (OC) increasing as the heap expands to meet allocation or promotion demands\&. The old generation capacity (OGC) has grown from 11,696 kB to 13,820 kB after the eighty\-first full garbage collection (FGC)\&. The maximum capacity of the generation (and space) is 60,544 kB (OGCMX), so it still has room to expand\&.
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBTimestamp OGCMN OGCMX OGC OC YGC FGC FGCT GCT\fR
++\fB 150\&.1 1408\&.0 60544\&.0 11696\&.0 11696\&.0 194 80 2\&.874 3\&.799\fR
++\fB 150\&.4 1408\&.0 60544\&.0 13820\&.0 13820\&.0 194 81 2\&.938 3\&.863\fR
++\fB 150\&.7 1408\&.0 60544\&.0 13820\&.0 13820\&.0 194 81 2\&.938 3\&.863\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.SS "Monitor Instrumentation for a Remote JVM"
++.PP
++This example attaches to lvmid 40496 on the system named remote\&.domain using the
++\fB\-gcutil\fR
++option, with samples taken every second indefinitely\&.
++.PP
++The lvmid is combined with the name of the remote host to construct a
++\fIvmid\fR
++of
++\fB40496@remote\&.domain\fR\&. This vmid results in the use of the
++\fBrmi\fR
++protocol to communicate to the default
++\fBjstatd\fR
++server on the remote host\&. The
++\fBjstatd\fR
++server is located using the
++\fBrmiregistry\fR
++command on
++\fBremote\&.domain\fR
++that is bound to the default port of the
++\fBrmiregistry\fR
++command (port 1099)\&.
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjstat \-gcutil 40496@remote\&.domain 1000\fR
++\fB\fI\&.\&.\&. output omitted\fR\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.SH "SEE ALSO"
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
+ java(1)
+-.TP 0.2i
+-\(bu
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
+ jps(1)
+-.TP 0.2i
+-\(bu
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
+ jstatd(1)
+-.TP 0.2i
+-\(bu
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
+ rmiregistry(1)
+-.RE
+-.br
+-'pl 8.5i
+-'bp
++.RE
++.br
++'pl 8.5i
++'bp
+--- ./jdk/src/linux/doc/man/keytool.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/keytool.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ '\" t
+-.\" Copyright (c) 1998, 2013, 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.
+ .\"
+@@ -23,12 +23,12 @@
+ .\"
+ .\" Arch: generic
+ .\" Software: JDK 8
+-.\" Date: 6 August 2013
++.\" Date: 03 March 2015
+ .\" SectDesc: Security Tools
+ .\" Title: keytool.1
+ .\"
+ .if n .pl 99999
+-.TH keytool 1 "6 August 2013" "JDK 8" "Security Tools"
++.TH keytool 1 "03 March 2015" "JDK 8" "Security Tools"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -185,10 +185,16 @@
+ .TP 0.2i
+ \(bu
+ Items in italics (option values) represent the actual values that must be supplied\&. For example, here is the format of the \f3-printcert\fR command:
++.sp
++.nf
++\f3keytool \-printcert {\-file \fIcert_file\fR} {\-v}\fP
++.fi
++.sp
+
+-\f3keytool -printcert {-file cert_file} {-v}\fR
+
+-When you specify a \f3-printcert\fR command, replace \f3cert_file\fR with the actual file name, as follows: \f3keytool -printcert -file VScert\&.cer\fR
++
++
++When you specify a \f3-printcert\fR command, replace \fIcert_file\fR with the actual file name, as follows: \f3keytool -printcert -file VScert\&.cer\fR
+ .TP 0.2i
+ \(bu
+ Option values must be put in quotation marks when they contain a blank (space)\&.
+@@ -385,10 +391,39 @@
+ .PP
+ \fINote:\fR Users should be aware that some combinations of extensions (and other certificate fields) may not conform to the Internet standard\&. See Certificate Conformance Warning\&.
+ .SH COMMANDS
+-.TP
++.TP
+ -gencert
+-.br
+-\f3{-rfc} {-infile infile} {-outfile outfile} {-alias alias} {-sigalg sigalg} {-dname dname} {-startdate startdate {-ext ext}* {-validity valDays} [-keypass keypass] {-keystore keystore} [-storepass storepass] {-storetype storetype} {-providername provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-rfc} {\-infile \fIinfile\fR} {\-outfile \fIoutfile\fR} {\-alias \fIalias\fR} {\-sigalg \fIsigalg\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-dname \fIdname\fR} {\-startdate \fIstartdate\fR {\-ext \fIext\fR}* {\-validity \fIvalDays\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-keypass \fIkeypass\fR] {\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-storetype \fIstoretype\fR} {\-providername \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Generates a certificate as a response to a certificate request file (which can be created by the \f3keytool\fR\f3-certreq\fR command)\&. The command reads the request from \fIinfile\fR (if omitted, from the standard input), signs it using alias\&'s private key, and outputs the X\&.509 certificate into \fIoutfile\fR (if omitted, to the standard output)\&. When\f3-rfc\fR is specified, the output format is Base64-encoded PEM; otherwise, a binary DER is created\&.
+
+@@ -459,10 +494,39 @@
+ .fi
+ .sp
+
+-.TP
++.TP
+ -genkeypair
+-.br
+-\f3{-alias alias} {-keyalg keyalg} {-keysize keysize} {-sigalg sigalg} [-dname dname] [-keypass keypass] {-startdate value} {-ext ext}* {-validity valDays} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-keyalg \fIkeyalg\fR} {\-keysize \fIkeysize\fR} {\-sigalg \fIsigalg\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-dname \fIdname\fR] [\-keypass \fIkeypass\fR] {\-startdate \fIvalue\fR} {\-ext \fIext\fR}*\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-validity \fIvalDays\fR} {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Generates a key pair (a public key and associated private key)\&. Wraps the public key into an X\&.509 v3 self-signed certificate, which is stored as a single-element certificate chain\&. This certificate chain and the private key are stored in a new keystore entry identified by alias\&.
+
+@@ -510,18 +574,61 @@
+ The value of \f3valDays\fR specifies the number of days (starting at the date specified by \f3-startdate\fR, or the current date when \f3-startdate\fR is not specified) for which the certificate should be considered valid\&.
+
+ This command was named \f3-genkey\fR in earlier releases\&. The old name is still supported in this release\&. The new name, \f3-genkeypair\fR, is preferred going forward\&.
+-.TP
++.TP
+ -genseckey
+-.br
+-\f3-genseckey {-alias alias} {-keyalg keyalg} {-keysize keysize} [-keypass keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-keyalg \fIkeyalg\fR} {\-keysize \fIkeysize\fR} [\-keypass \fIkeypass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}} {\-v}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Generates a secret key and stores it in a new \f3KeyStore\&.SecretKeyEntry\fR identified by \f3alias\fR\&.
+
+ The value of \f3keyalg\fR specifies the algorithm to be used to generate the secret key, and the value of \f3keysize\fR specifies the size of the key to be generated\&. The \f3keypass\fR value is a password that protects the secret key\&. If no password is provided, then the user is prompted for it\&. If you press the Return key at the prompt, then the key password is set to the same password that is used for the \f3keystore\fR\&. The \f3keypass\fR value must be at least 6 characters\&.
+-.TP
++.TP
+ -importcert
+-.br
+-\f3-importcert {-alias alias} {-file cert_file} [-keypass keypass] {-noprompt} {-trustcacerts} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-file \fIcert_file\fR} [\-keypass \fIkeypass\fR] {\-noprompt} {\-trustcacerts}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Reads the certificate or certificate chain (where the latter is supplied in a PKCS#7 formatted reply or a sequence of X\&.509 certificates) from the file \f3cert_file\fR, and stores it in the \f3keystore\fR entry identified by \f3alias\fR\&. If no file is specified, then the certificate or certificate chain is read from \f3stdin\fR\&.
+
+@@ -530,16 +637,74 @@
+ You import a certificate for two reasons: To add it to the list of trusted certificates, and to import a certificate reply received from a certificate authority (CA) as the result of submitting a Certificate Signing Request to that CA (see the \f3-certreq\fR option in Commands)\&.
+
+ Which type of import is intended is indicated by the value of the \f3-alias\fR option\&. If the alias does not point to a key entry, then the \f3keytool\fR command assumes you are adding a trusted certificate entry\&. In this case, the alias should not already exist in the keystore\&. If the alias does already exist, then the \f3keytool\fR command outputs an error because there is already a trusted certificate for that alias, and does not import the certificate\&. If the alias points to a key entry, then the \f3keytool\fR command assumes you are importing a certificate reply\&.
+-.TP
++.TP
+ -importpassword
+-.br
+-\f3{-alias alias} [-keypass keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} [\-keypass \fIkeypass\fR] {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Imports a passphrase and stores it in a new \f3KeyStore\&.SecretKeyEntry\fR identified by \f3alias\fR\&. The passphrase may be supplied via the standard input stream; otherwise the user is prompted for it\&. \f3keypass\fR is a password used to protect the imported passphrase\&. If no password is provided, the user is prompted for it\&. If you press the Return key at the prompt, the key password is set to the same password as that used for the \f3keystore\fR\&. \f3keypass\fR must be at least 6 characters long\&.
+-.TP
++.TP
+ -importkeystore
+-.br
+-\f3{-srcstoretype srcstoretype} {-deststoretype deststoretype} [-srcstorepass srcstorepass] [-deststorepass deststorepass] {-srcprotected} {-destprotected} {-srcalias srcalias {-destalias destalias} [-srckeypass srckeypass] } [-destkeypass destkeypass] {-noprompt} {-srcProviderName src_provider_name} {-destProviderName dest_provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-srcstoretype \fIsrcstoretype\fR} {\-deststoretype \fIdeststoretype\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-srcstorepass \fIsrcstorepass\fR] [\-deststorepass \fIdeststorepass\fR] {\-srcprotected}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-destprotected} \fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-srcalias \fIsrcalias\fR {\-destalias \fIdestalias\fR} [\-srckeypass \fIsrckeypass\fR]} \fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-destkeypass \fIdestkeypass\fR] {\-noprompt}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-srcProviderName \fIsrc_provider_name\fR} {\-destProviderName \fIdest_provider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}} {\-v}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Imports a single entry or all entries from a source keystore to a destination keystore\&.
+
+@@ -550,16 +715,44 @@
+ If the destination alias already exists in the destination keystore, then the user is prompted to either overwrite the entry or to create a new entry under a different alias name\&.
+
+ If the \f3-noprompt\fR option is provided, then the user is not prompted for a new destination alias\&. Existing entries are overwritten with the destination alias name\&. Entries that cannot be imported are skipped and a warning is displayed\&.
+-.TP
++.TP
+ -printcertreq
+-.br
+-\f3{-file file}\fR
++.sp
++.nf
++\f3{\-file \fIfile\fR}\fP
++.fi
++.sp
++
+
+ Prints the content of a PKCS #10 format certificate request, which can be generated by the \f3keytool\fR\f3-certreq\fR command\&. The command reads the request from file\&. If there is no file, then the request is read from the standard input\&.
+-.TP
++.TP
+ -certreq
+-.br
+-\f3{-alias alias} {-dname dname} {-sigalg sigalg} {-file certreq_file} [-keypass keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-dname \fIdname\fR} {\-sigalg \fIsigalg\fR} {\-file \fIcertreq_file\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-keypass \fIkeypass\fR] {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-storepass \fIstorepass\fR] {\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Generates a Certificate Signing Request (CSR) using the PKCS #10 format\&.
+
+@@ -572,10 +765,29 @@
+ The CSR is stored in the file certreq_file\&. If no file is specified, then the CSR is output to \f3stdout\fR\&.
+
+ Use the \f3importcert\fR command to import the response from the CA\&.
+-.TP
++.TP
+ -exportcert
+-.br
+-\f3{-alias alias} {-file cert_file} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-rfc} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-file \fIcert_file\fR} {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-storepass \fIstorepass\fR] {\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-rfc} {\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Reads from the keystore the certificate associated with \fIalias\fR and stores it in the cert_file file\&. When no file is specified, the certificate is output to \f3stdout\fR\&.
+
+@@ -584,20 +796,48 @@
+ If \f3alias\fR refers to a trusted certificate, then that certificate is output\&. Otherwise, \f3alias\fR refers to a key entry with an associated certificate chain\&. In that case, the first certificate in the chain is returned\&. This certificate authenticates the public key of the entity addressed by \f3alias\fR\&.
+
+ This command was named \f3-export\fR in earlier releases\&. The old name is still supported in this release\&. The new name, \f3-exportcert\fR, is preferred going forward\&.
+-.TP
++.TP
+ -list
+-.br
+-\f3{-alias alias} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v | -rfc} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v | \-rfc} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Prints to \f3stdout\fR the contents of the keystore entry identified by \f3alias\fR\&. If no \f3alias\fR is specified, then the contents of the entire keystore are printed\&.
+
+ This command by default prints the SHA1 fingerprint of a certificate\&. If the \f3-v\fR option is specified, then the certificate is printed in human-readable format, with additional information such as the owner, issuer, serial number, and any extensions\&. If the \f3-rfc\fR option is specified, then the certificate contents are printed using the printable encoding format, as defined by the Internet RFC 1421 Certificate Encoding Standard\&.
+
+ You cannot specify both \f3-v\fR and \f3-rfc\fR\&.
+-.TP
++.TP
+ -printcert
+-.br
+-\f3{-file cert_file | -sslserver host[:port]} {-jarfile JAR_file {-rfc} {-v} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-file \fIcert_file\fR | \-sslserver \fIhost\fR[:\fIport\fR]} {\-jarfile \fIJAR_file\fR {\-rfc} {\-v}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Reads the certificate from the file cert_file, the SSL server located at host:port, or the signed JAR file \f3JAR_file\fR (with the \f3-jarfile\fR option and prints its contents in a human-readable format\&. When no port is specified, the standard HTTPS port 443 is assumed\&. Note that \f3-sslserver\fR and -file options cannot be provided at the same time\&. Otherwise, an error is reported\&. If neither option is specified, then the certificate is read from \f3stdin\fR\&.
+
+@@ -608,40 +848,120 @@
+ If the SSL server is behind a firewall, then the \f3-J-Dhttps\&.proxyHost=proxyhost\fR and \f3-J-Dhttps\&.proxyPort=proxyport\fR options can be specified on the command line for proxy tunneling\&. See Java Secure Socket Extension (JSSE) Reference Guide at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide\&.html
+
+ \fINote:\fR This option can be used independently of a keystore\&.
+-.TP
++.TP
+ -printcrl
+-.br
+-\f3-file crl_ {-v}\fR
++.sp
++.nf
++\f3\-file \fIcrl_\fR {\-v}\fP
++.fi
++.sp
++
+
+ Reads the Certificate Revocation List (CRL) from the file \f3crl_\fR\&. A CRL is a list of digital certificates that were revoked by the CA that issued them\&. The CA generates the \f3crl_\fR file\&.
+
+ \fINote:\fR This option can be used independently of a keystore\&.
+-.TP
++.TP
+ -storepasswd
+-.br
+-\f3[-new new_storepass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-Jjavaoption}\fR
++.sp
++.nf
++\f3[\-new \fInew_storepass\fR] {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-storepass \fIstorepass\fR] {\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Changes the password used to protect the integrity of the keystore contents\&. The new password is \f3new_storepass\fR, which must be at least 6 characters\&.
+-.TP
++.TP
+ -keypasswd
+-.br
+-\f3{-alias alias} [-keypass old_keypass] [-new new_keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} [\-keypass \fIold_keypass\fR] [\-new \fInew_keypass\fR] {\-storetype \fIstoretype\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR] {\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}} {\-v}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Changes the password under which the private/secret key identified by \f3alias\fR is protected, from \f3old_keypass\fR to \f3new_keypass\fR, which must be at least 6 characters\&.
+
+ If the \f3-keypass\fR option is not provided at the command line, and the key password is different from the keystore password, then the user is prompted for it\&.
+
+ If the \f3-new\fR option is not provided at the command line, then the user is prompted for it
+-.TP
++.TP
+ -delete
+-.br
+-\f3[-alias alias] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3[\-alias \fIalias\fR] {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerName \fIprovider_name\fR} \fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Deletes from the keystore the entry identified by \f3alias\fR\&. The user is prompted for the alias, when no alias is provided at the command line\&.
+-.TP
++.TP
+ -changealias
+-.br
+-\f3{-alias alias} [-destalias destalias] [-keypass keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} [\-destalias \fIdestalias\fR] [\-keypass \fIkeypass\fR] {\-storetype \fIstoretype\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR] {\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}} {\-v}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Move an existing keystore entry from the specified \f3alias\fR to a new alias, \f3destalias\fR\&. If no destination alias is provided, then the command prompts for one\&. If the original entry is protected with an entry password, then the password can be supplied with the \f3-keypass\fR option\&. If no key password is provided, then the \f3storepass\fR (if provided) is attempted first\&. If the attempt fails, then the user is prompted for a password\&.
+ .TP
+--- ./jdk/src/linux/doc/man/policytool.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/linux/doc/man/policytool.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ '\" t
+-.\" Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
++.\" Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ .\"
+ .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ .\"
+@@ -23,12 +23,12 @@
+ .\"
+ .\" Arch: generic
+ .\" Software: JDK 8
+-.\" Date: 21 November 2013
++.\" Date: 03 March 2015
+ .\" SectDesc: Security Tools
+ .\" Title: policytool.1
+ .\"
+ .if n .pl 99999
+-.TH policytool 1 "21 November 2013" "JDK 8" "Security Tools"
++.TH policytool 1 "03 March 2015" "JDK 8" "Security Tools"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -80,7 +80,7 @@
+ Run the \f3policytool\fR command and load the specified file:
+ .sp
+ .nf
+-\f3policytool\-file mypolicyfile\fP
++\f3policytool \-file \fImypolicyfile\fR\fP
+ .fi
+ .nf
+ \f3\fP
+--- ./jdk/src/macosx/classes/apple/applescript/AppleScriptEngine.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/apple/applescript/AppleScriptEngine.java Wed Feb 04 12:14:43 2015 -0800
+@@ -155,7 +155,7 @@
+ TRACE("init()");
+ // set up our context
+ /* TODO -- name of current executable? bad java documentation at:
+- * http://docs.oracle.com/javase/6/docs/api/javax/script/ScriptEngine.html#FILENAME */
++ * https://docs.oracle.com/javase/6/docs/api/javax/script/ScriptEngine.html#FILENAME */
+ put(ScriptEngine.FILENAME, "");
+ put(ScriptEngine.ENGINE, getEngine());
+ put(ScriptEngine.ENGINE_VERSION, getEngineVersion());
+--- ./jdk/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -486,10 +486,15 @@
+
+ // This is somewhat messy. The difference here from BasicComboBoxUI.EnterAction is that
+ // arrow up or down does not automatically select the
+- private static final Action triggerSelectionAction = new AbstractAction() {
++ private final Action triggerSelectionAction = new AbstractAction() {
+ public void actionPerformed(final ActionEvent e) {
+ triggerSelectionEvent((JComboBox)e.getSource(), e);
+ }
++
++ @Override
++ public boolean isEnabled() {
++ return comboBox.isPopupVisible() && super.isEnabled();
++ }
+ };
+
+ private static final Action toggleSelectionAction = new AbstractAction() {
+--- ./jdk/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/com/apple/laf/AquaFileChooserUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1280,12 +1280,12 @@
+ filters = (FileFilter[]) e.getNewValue();
+ fireContentsChanged(this, -1, -1);
+ } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) {
+- fireContentsChanged(this, -1, -1);
++ setSelectedItem(e.getNewValue());
+ }
+ }
+
+ public void setSelectedItem(Object filter) {
+- if(filter != null) {
++ if (filter != null && !containsFileFilter(filter)) {
+ getFileChooser().setFileFilter((FileFilter) filter);
+ fireContentsChanged(this, -1, -1);
+ }
+@@ -1333,6 +1333,10 @@
+ }
+ }
+
++ private boolean containsFileFilter(Object fileFilter) {
++ return Objects.equals(fileFilter, getFileChooser().getFileFilter());
++ }
++
+ /**
+ * Acts when FilterComboBox has changed the selected item.
+ */
+@@ -1342,7 +1346,10 @@
+ }
+
+ public void actionPerformed(final ActionEvent e) {
+- getFileChooser().setFileFilter((FileFilter)filterComboBox.getSelectedItem());
++ Object selectedFilter = filterComboBox.getSelectedItem();
++ if (!containsFileFilter(selectedFilter)) {
++ getFileChooser().setFileFilter((FileFilter) selectedFilter);
++ }
+ }
+ }
+
+--- ./jdk/src/macosx/classes/com/apple/laf/AquaIcon.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/com/apple/laf/AquaIcon.java Wed Feb 04 12:14:43 2015 -0800
+@@ -62,7 +62,7 @@
+ if (w <= 0 || h <= 0) return null;
+
+ // This could be any kind of icon, so we need to make a buffer for it, draw it and then pass the new image off to appkit.
+- final BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
++ final BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
+ final Graphics g = image.getGraphics();
+ i.paintIcon(null, g, 0, 0);
+ g.dispose();
+--- ./jdk/src/macosx/classes/com/apple/laf/AquaImageFactory.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/com/apple/laf/AquaImageFactory.java Wed Feb 04 12:14:43 2015 -0800
+@@ -46,10 +46,8 @@
+ import com.apple.laf.AquaIcon.SystemIcon;
+ import com.apple.laf.AquaUtils.RecyclableObject;
+ import com.apple.laf.AquaUtils.RecyclableSingleton;
+-import java.util.Arrays;
+-import java.util.List;
+-import sun.awt.image.MultiResolutionBufferedImage;
+ import sun.awt.image.MultiResolutionImage;
++import sun.awt.image.MultiResolutionCachedImage;
+
+ public class AquaImageFactory {
+ public static IconUIResource getConfirmImageIcon() {
+@@ -107,9 +105,9 @@
+ private static final int kAlertIconSize = 64;
+ static IconUIResource getAppIconCompositedOn(final Image background) {
+
+- if (background instanceof MultiResolutionBufferedImage) {
++ if (background instanceof MultiResolutionCachedImage) {
+ int width = background.getWidth(null);
+- Image mrIconImage = ((MultiResolutionBufferedImage) background).map(
++ Image mrIconImage = ((MultiResolutionCachedImage) background).map(
+ rv -> getAppIconImageCompositedOn(rv, rv.getWidth(null) / width));
+ return new IconUIResource(new ImageIcon(mrIconImage));
+ }
+@@ -131,7 +129,7 @@
+ };
+
+ final BufferedImage image = new BufferedImage(scaledAlertIconSize,
+- scaledAlertIconSize, BufferedImage.TYPE_INT_ARGB);
++ scaledAlertIconSize, BufferedImage.TYPE_INT_ARGB_PRE);
+ final Graphics g = image.getGraphics();
+ g.drawImage(background, 0, 0,
+ scaledAlertIconSize, scaledAlertIconSize, null);
+@@ -287,21 +285,7 @@
+ private static Image getNSIcon(String imageName) {
+ Image icon = Toolkit.getDefaultToolkit()
+ .getImage("NSImage://" + imageName);
+-
+- if (icon instanceof MultiResolutionImage) {
+- return icon;
+- }
+-
+- int w = icon.getWidth(null);
+- int h = icon.getHeight(null);
+-
+- Dimension[] sizes = new Dimension[]{
+- new Dimension(w, h), new Dimension(2 * w, 2 * h)
+- };
+-
+- return new MultiResolutionBufferedImage(icon, sizes, (width, height) ->
+- AquaUtils.getCImageCreator().createImageFromName(
+- imageName, width, height));
++ return icon;
+ }
+
+ public static class NineSliceMetrics {
+--- ./jdk/src/macosx/classes/com/apple/laf/AquaMenuBarUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/com/apple/laf/AquaMenuBarUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -26,11 +26,14 @@
+ package com.apple.laf;
+
+ import java.awt.*;
++import java.security.AccessController;
+
+ import javax.swing.*;
+ import javax.swing.plaf.ComponentUI;
+ import javax.swing.plaf.basic.BasicMenuBarUI;
+
++import sun.lwawt.macosx.LWCToolkit;
++import sun.security.action.GetBooleanAction;
+ import sun.security.action.GetPropertyAction;
+
+ // MenuBar implementation for Mac L&F
+@@ -131,28 +134,20 @@
+ ScreenMenuBar fScreenMenuBar;
+ boolean useScreenMenuBar = getScreenMenuBarProperty();
+
+- private static String getPrivSysProp(final String propName) {
+- return java.security.AccessController.doPrivileged(new GetPropertyAction(propName));
+- }
+-
+ static boolean getScreenMenuBarProperty() {
+- final String props[] = new String[]{""};
+-
+- boolean useScreenMenuBar = false;
+- try {
+- props[0] = getPrivSysProp(AquaLookAndFeel.sPropertyPrefix + "useScreenMenuBar");
+-
+- if (props[0] != null && props[0].equals("true")) useScreenMenuBar = true;
+- else {
+- props[0] = getPrivSysProp(AquaLookAndFeel.sOldPropertyPrefix + "useScreenMenuBar");
+-
+- if (props[0] != null && props[0].equals("true")) {
+- System.err.println(AquaLookAndFeel.sOldPropertyPrefix + "useScreenMenuBar has been deprecated. Please switch to " + AquaLookAndFeel.sPropertyPrefix + "useScreenMenuBar");
+- useScreenMenuBar = true;
+- }
+- }
+- } catch(final Throwable t) { };
+-
+- return useScreenMenuBar;
++ // Do not allow AWT to set the screen menu bar if it's embedded in another UI toolkit
++ if (LWCToolkit.isEmbedded()) return false;
++ if (AccessController.doPrivileged(
++ new GetBooleanAction(AquaLookAndFeel.sPropertyPrefix + "useScreenMenuBar"))) {
++ return true;
++ }
++ if (AccessController.doPrivileged(
++ new GetBooleanAction(AquaLookAndFeel.sOldPropertyPrefix + "useScreenMenuBar"))) {
++ System.err.println(AquaLookAndFeel.sOldPropertyPrefix +
++ "useScreenMenuBar has been deprecated. Please switch to " +
++ AquaLookAndFeel.sPropertyPrefix + "useScreenMenuBar");
++ return true;
++ }
++ return false;
+ }
+ }
+--- ./jdk/src/macosx/classes/com/apple/laf/AquaNativeResources.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/com/apple/laf/AquaNativeResources.java Wed Feb 04 12:14:43 2015 -0800
+@@ -66,11 +66,12 @@
+ }
+
+ static BufferedImage getRadioButtonSizerImage() {
+- final BufferedImage img = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB);
++ final BufferedImage img = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB_PRE);
+
+ Graphics g = img.getGraphics();
+ g.setColor(Color.pink);
+ g.fillRect(0, 0, 20, 20);
++ g.dispose();
+
+ return img;
+ }
+--- ./jdk/src/macosx/classes/com/apple/laf/AquaPainter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/com/apple/laf/AquaPainter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -174,11 +174,7 @@
+ bounds, controlState);
+ Image img = cache.getImage(key);
+ if (img == null) {
+-
+- Image baseImage = createImage(imgX, imgY, imgW, imgH, bounds,
+- control, controlState);
+-
+- img = new MultiResolutionBufferedImage(baseImage,
++ img = new MultiResolutionCachedImage(imgW, imgH,
+ (rvWidth, rvHeight) -> createImage(imgX, imgY,
+ rvWidth, rvHeight, bounds, control, controlState));
+
+--- ./jdk/src/macosx/classes/com/apple/laf/AquaUtils.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/com/apple/laf/AquaUtils.java Wed Feb 04 12:14:43 2015 -0800
+@@ -48,7 +48,7 @@
+ import sun.swing.SwingUtilities2;
+
+ import com.apple.laf.AquaImageFactory.SlicedImageControl;
+-import sun.awt.image.MultiResolutionBufferedImage;
++import sun.awt.image.MultiResolutionCachedImage;
+
+ final class AquaUtils {
+
+@@ -124,8 +124,8 @@
+
+ static Image generateLightenedImage(final Image image, final int percent) {
+ final GrayFilter filter = new GrayFilter(true, percent);
+- return (image instanceof MultiResolutionBufferedImage)
+- ? ((MultiResolutionBufferedImage) image).map(
++ return (image instanceof MultiResolutionCachedImage)
++ ? ((MultiResolutionCachedImage) image).map(
+ rv -> generateLightenedImage(rv, filter))
+ : generateLightenedImage(image, filter);
+ }
+--- ./jdk/src/macosx/classes/sun/font/CFontManager.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/sun/font/CFontManager.java Wed Feb 04 12:14:43 2015 -0800
+@@ -43,7 +43,7 @@
+ import sun.misc.ThreadGroupUtils;
+ import sun.lwawt.macosx.*;
+
+-public class CFontManager extends SunFontManager {
++public final class CFontManager extends SunFontManager {
+ private FontConfigManager fcManager = null;
+ private static Hashtable<String, Font2D> genericFonts = new Hashtable<String, Font2D>();
+
+@@ -61,20 +61,14 @@
+ return new CFontConfiguration(this, preferLocaleFonts, preferPropFonts);
+ }
+
+- private static String[] defaultPlatformFont = null;
+-
+ /*
+ * Returns an array of two strings. The first element is the
+ * name of the font. The second element is the file name.
+ */
+ @Override
+- public synchronized String[] getDefaultPlatformFont() {
+- if (defaultPlatformFont == null) {
+- defaultPlatformFont = new String[2];
+- defaultPlatformFont[0] = "Lucida Grande";
+- defaultPlatformFont[1] = "/System/Library/Fonts/LucidaGrande.ttc";
+- }
+- return defaultPlatformFont;
++ protected String[] getDefaultPlatformFont() {
++ return new String[]{"Lucida Grande",
++ "/System/Library/Fonts/LucidaGrande.ttc"};
+ }
+
+ // This is a way to register any kind of Font2D, not just files and composites.
+--- ./jdk/src/macosx/classes/sun/lwawt/LWLightweightFramePeer.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/sun/lwawt/LWLightweightFramePeer.java Wed Feb 04 12:14:43 2015 -0800
+@@ -94,10 +94,12 @@
+
+ @Override
+ public void addDropTarget(DropTarget dt) {
++ getLwTarget().addDropTarget(dt);
+ }
+
+ @Override
+ public void removeDropTarget(DropTarget dt) {
++ getLwTarget().removeDropTarget(dt);
+ }
+
+ @Override
+--- ./jdk/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java Wed Feb 04 12:14:43 2015 -0800
+@@ -37,7 +37,8 @@
+
+ private CPlatformResponder responder;
+ private static final Object classLock = new Object();
+- private static volatile CEmbeddedFrame focusedWindow;
++ private static volatile CEmbeddedFrame globalFocusedWindow;
++ private CEmbeddedFrame browserWindowFocusedApplet;
+ private boolean parentWindowActive = true;
+
+ public CEmbeddedFrame() {
+@@ -110,10 +111,10 @@
+ synchronized (classLock) {
+ // In some cases an applet may not receive the focus lost event
+ // from the parent window (see 8012330)
+- focusedWindow = (focused) ? this
+- : ((focusedWindow == this) ? null : focusedWindow);
++ globalFocusedWindow = (focused) ? this
++ : ((globalFocusedWindow == this) ? null : globalFocusedWindow);
+ }
+- if (focusedWindow == this) {
++ if (globalFocusedWindow == this) {
+ // see bug 8010925
+ // we can't put this to handleWindowFocusEvent because
+ // it won't be invoced if focuse is moved to a html element
+@@ -144,9 +145,23 @@
+ // non-focused applet. This method can be called from different threads.
+ public void handleWindowFocusEvent(boolean parentWindowActive) {
+ this.parentWindowActive = parentWindowActive;
++ // If several applets are running in different browser's windows, it is necessary to
++ // detect the switching between the parent windows and update globalFocusedWindow accordingly.
++ synchronized (classLock) {
++ if (!parentWindowActive) {
++ this.browserWindowFocusedApplet = globalFocusedWindow;
++ }
++ if (parentWindowActive && globalFocusedWindow != this && isParentWindowChanged()) {
++ // It looks like we have switched to another browser window, let's restore focus to
++ // the previously focused applet in this window. If no applets were focused in the
++ // window, we will set focus to the first applet in the window.
++ globalFocusedWindow = (this.browserWindowFocusedApplet != null) ? this.browserWindowFocusedApplet
++ : this;
++ }
++ }
+ // ignore focus "lost" native request as it may mistakenly
+ // deactivate active window (see 8001161)
+- if (focusedWindow == this && parentWindowActive) {
++ if (globalFocusedWindow == this && parentWindowActive) {
+ responder.handleWindowFocusEvent(parentWindowActive, null);
+ }
+ }
+@@ -154,4 +169,10 @@
+ public boolean isParentWindowActive() {
+ return parentWindowActive;
+ }
++
++ private boolean isParentWindowChanged() {
++ // If globalFocusedWindow is located at inactive parent window or null, we have swithed to
++ // another window.
++ return globalFocusedWindow != null ? !globalFocusedWindow.isParentWindowActive() : true;
++ }
+ }
+--- ./jdk/src/macosx/classes/sun/lwawt/macosx/CImage.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/sun/lwawt/macosx/CImage.java Wed Feb 04 12:14:43 2015 -0800
+@@ -32,7 +32,7 @@
+ import java.util.Arrays;
+ import java.util.List;
+ import sun.awt.image.MultiResolutionImage;
+-import sun.awt.image.MultiResolutionBufferedImage;
++import sun.awt.image.MultiResolutionCachedImage;
+
+ import sun.awt.image.SunWritableRaster;
+
+@@ -60,41 +60,41 @@
+ // This is used to create a CImage with an NSImage pointer. It MUST be a CFRetained
+ // NSImage, and the CImage takes ownership of the non-GC retain. If callers need the
+ // NSImage themselves, they MUST call retain on the NSImage themselves.
+- public BufferedImage createImageUsingNativeSize(final long image) {
++ public Image createImageUsingNativeSize(final long image) {
+ if (image == 0) return null;
+ final Dimension2D size = nativeGetNSImageSize(image);
+- return createBufferedImage(image, size.getWidth(), size.getHeight());
++ return createImage(image, size.getWidth(), size.getHeight());
+ }
+
+ // the width and height passed in as a parameter could differ than the width and the height of the NSImage (image), in that case, the image will be scaled
+- BufferedImage createBufferedImage(long image, double width, double height) {
++ Image createImage(long image, double width, double height) {
+ if (image == 0) throw new Error("Unable to instantiate CImage with null native image reference.");
+ return createImageWithSize(image, width, height);
+ }
+
+- public BufferedImage createImageWithSize(final long image, final double width, final double height) {
++ public Image createImageWithSize(final long image, final double width, final double height) {
+ final CImage img = new CImage(image);
+ img.resize(width, height);
+ return img.toImage();
+ }
+
+ // This is used to create a CImage that represents the icon of the given file.
+- public BufferedImage createImageOfFile(final String file, final int width, final int height) {
+- return createBufferedImage(nativeCreateNSImageOfFileFromLaunchServices(file), width, height);
++ public Image createImageOfFile(final String file, final int width, final int height) {
++ return createImage(nativeCreateNSImageOfFileFromLaunchServices(file), width, height);
+ }
+
+- public BufferedImage createImageFromFile(final String file, final double width, final double height) {
++ public Image createImageFromFile(final String file, final double width, final double height) {
+ final long image = nativeCreateNSImageFromFileContents(file);
+ nativeSetNSImageSize(image, width, height);
+- return createBufferedImage(image, width, height);
++ return createImage(image, width, height);
+ }
+
+- public BufferedImage createSystemImageFromSelector(final String iconSelector, final int width, final int height) {
+- return createBufferedImage(nativeCreateNSImageFromIconSelector(getSelectorAsInt(iconSelector)), width, height);
++ public Image createSystemImageFromSelector(final String iconSelector, final int width, final int height) {
++ return createImage(nativeCreateNSImageFromIconSelector(getSelectorAsInt(iconSelector)), width, height);
+ }
+
+ public Image createImageFromName(final String name, final int width, final int height) {
+- return createBufferedImage(nativeCreateNSImageFromImageName(name), width, height);
++ return createImage(nativeCreateNSImageFromImageName(name), width, height);
+ }
+
+ public Image createImageFromName(final String name) {
+@@ -213,7 +213,7 @@
+ }
+
+ /** @return A MultiResolution image created from nsImagePtr, or null. */
+- private BufferedImage toImage() {
++ private Image toImage() {
+ if (ptr == 0) return null;
+
+ final Dimension2D size = nativeGetNSImageSize(ptr);
+@@ -224,11 +224,11 @@
+ = nativeGetNSImageRepresentationSizes(ptr,
+ size.getWidth(), size.getHeight());
+
+- BufferedImage baseImage = toImage(w, h, w, h);
+-
+- return sizes == null || sizes.length < 2 ? baseImage
+- : new MultiResolutionBufferedImage(baseImage, sizes,
+- (width, height) -> toImage(w, h, width, height));
++ return sizes == null || sizes.length < 2 ?
++ new MultiResolutionCachedImage(w, h, (width, height)
++ -> toImage(w, h, width, height))
++ : new MultiResolutionCachedImage(w, h, sizes, (width, height)
++ -> toImage(w, h, width, height));
+ }
+
+ private BufferedImage toImage(int srcWidth, int srcHeight, int dstWidth, int dstHeight) {
+--- ./jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Wed Feb 04 12:14:43 2015 -0800
+@@ -568,7 +568,10 @@
+ CWrapper.NSWindow.makeKeyWindow(nsWindowPtr);
+ }
+ } else {
++ // immediately hide the window
+ CWrapper.NSWindow.orderOut(nsWindowPtr);
++ // process the close
++ CWrapper.NSWindow.close(nsWindowPtr);
+ }
+ } else {
+ // otherwise, put it in a proper z-order
+@@ -674,6 +677,13 @@
+ @Override // PlatformWindow
+ public void toFront() {
+ final long nsWindowPtr = getNSWindowPtr();
++ LWCToolkit lwcToolkit = (LWCToolkit) Toolkit.getDefaultToolkit();
++ Window w = DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
++ if( w != null && w.getPeer() != null
++ && ((LWWindowPeer)w.getPeer()).getPeerType() == LWWindowPeer.PeerType.EMBEDDED_FRAME
++ && !lwcToolkit.isApplicationActive()) {
++ lwcToolkit.activateApplicationIgnoringOtherApps();
++ }
+ updateFocusabilityForAutoRequestFocus(false);
+ nativePushNSWindowToFront(nsWindowPtr);
+ updateFocusabilityForAutoRequestFocus(true);
+--- ./jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java Wed Feb 04 12:14:43 2015 -0800
+@@ -54,8 +54,26 @@
+ static native void orderFront(long window);
+ static native void orderFrontRegardless(long window);
+ static native void orderWindow(long window, int ordered, long relativeTo);
++
++ /**
++ * Removes the window from the screen.
++ *
++ * @param window the pointer of the NSWindow
++ */
+ static native void orderOut(long window);
+
++ /**
++ * Removes the window from the screen and releases it. According to
++ * documentation this method should be similar to {@link #orderOut},
++ * because we use ReleasedWhenClosed:NO, so the window shouldn't be
++ * released. But the close method works differently, for example it
++ * close the space if the window was in the full screen via
++ * {@link CPlatformWindow#toggleFullScreen()}.
++ *
++ * @param window the pointer of the NSWindow
++ */
++ static native void close(long window);
++
+ static native void addChildWindow(long parent, long child, int ordered);
+ static native void removeChildWindow(long parent, long child);
+
+--- ./jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Wed Feb 04 12:14:43 2015 -0800
+@@ -538,9 +538,9 @@
+ return super.getImage(filename);
+ }
+
+- String fileneame2x = getScaledImageName(filename);
+- return (imageExists(fileneame2x))
+- ? getImageWithResolutionVariant(filename, fileneame2x)
++ String filename2x = getScaledImageName(filename);
++ return (imageExists(filename2x))
++ ? getImageWithResolutionVariant(filename, filename2x)
+ : super.getImage(filename);
+ }
+
+@@ -686,6 +686,11 @@
+ @Override
+ public DragSourceContextPeer createDragSourceContextPeer(
+ DragGestureEvent dge) throws InvalidDnDOperationException {
++ final LightweightFrame f = SunToolkit.getLightweightFrame(dge.getComponent());
++ if (f != null) {
++ return f.createDragSourceContextPeer(dge);
++ }
++
+ return CDragSourceContextPeer.createDragSourceContextPeer(dge);
+ }
+
+@@ -693,6 +698,11 @@
+ public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
+ Class<T> abstractRecognizerClass, DragSource ds, Component c,
+ int srcActions, DragGestureListener dgl) {
++ final LightweightFrame f = SunToolkit.getLightweightFrame(c);
++ if (f != null) {
++ return f.createDragGestureRecognizer(abstractRecognizerClass, ds, c, srcActions, dgl);
++ }
++
+ DragGestureRecognizer dgr = null;
+
+ // Create a new mouse drag gesture recognizer if we have a class match:
+@@ -784,6 +794,18 @@
+ */
+ native boolean isApplicationActive();
+
++ /**
++ * Returns true if AWT toolkit is embedded, false otherwise.
++ *
++ * @return true if AWT toolkit is embedded, false otherwise
++ */
++ public static native boolean isEmbedded();
++
++ /*
++ * Activates application ignoring other apps.
++ */
++ public native void activateApplicationIgnoringOtherApps();
++
+ /************************
+ * Native methods section
+ ************************/
+@@ -891,6 +913,9 @@
+ }
+
+ private static boolean isValidPath(String path) {
+- return !path.isEmpty() && !path.endsWith("/") && !path.endsWith(".");
++ return path != null &&
++ !path.isEmpty() &&
++ !path.endsWith("/") &&
++ !path.endsWith(".");
+ }
+ }
+--- ./jdk/src/macosx/native/apple/security/KeystoreImpl.m Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/native/apple/security/KeystoreImpl.m Wed Feb 04 12:14:43 2015 -0800
+@@ -299,11 +299,21 @@
+
+ // Make a java array of certificate data from the chain.
+ jclass byteArrayClass = (*env)->FindClass(env, "[B");
++ if (byteArrayClass == NULL) {
++ goto errOut;
++ }
+ jobjectArray javaCertArray = (*env)->NewObjectArray(env, certCount, byteArrayClass, NULL);
++ // Cleanup first then check for a NULL return code
+ (*env)->DeleteLocalRef(env, byteArrayClass);
++ if (javaCertArray == NULL) {
++ goto errOut;
++ }
+
+ // And, make an array of the certificate refs.
+ jlongArray certRefArray = (*env)->NewLongArray(env, certCount);
++ if (certRefArray == NULL) {
++ goto errOut;
++ }
+
+ SecCertificateRef currCertRef = NULL;
+
+@@ -318,6 +328,9 @@
+ bzero(&currCertData, sizeof(CSSM_DATA));
+ err = SecCertificateGetData(currCertRef, &currCertData);
+ jbyteArray encodedCertData = (*env)->NewByteArray(env, currCertData.Length);
++ if (encodedCertData == NULL) {
++ goto errOut;
++ }
+ (*env)->SetByteArrayRegion(env, encodedCertData, 0, currCertData.Length, (jbyte *)currCertData.Data);
+ (*env)->SetObjectArrayElement(env, javaCertArray, i, encodedCertData);
+ jlong certRefElement = ptr_to_jlong(currCertRef);
+@@ -330,6 +343,9 @@
+
+ // Find the label. It's a 'blob', but we interpret as characters.
+ jstring alias = getLabelFromItem(env, (SecKeychainItemRef)certificate);
++ if (alias == NULL) {
++ goto errOut;
++ }
+
+ // Find the creation date.
+ jlong creationDate = getModDateFromItem(env, (SecKeychainItemRef)certificate);
+@@ -340,6 +356,7 @@
+ }
+ } while (searchResult == noErr);
+
++errOut:
+ if (identitySearch != NULL) {
+ CFRelease(identitySearch);
+ }
+@@ -362,10 +379,16 @@
+ CSSM_DATA currCertificate;
+ err = SecCertificateGetData(certRef, &currCertificate);
+ jbyteArray certData = (*env)->NewByteArray(env, currCertificate.Length);
++ if (certData == NULL) {
++ goto errOut;
++ }
+ (*env)->SetByteArrayRegion(env, certData, 0, currCertificate.Length, (jbyte *)currCertificate.Data);
+
+ // Find the label. It's a 'blob', but we interpret as characters.
+ jstring alias = getLabelFromItem(env, theItem);
++ if (alias == NULL) {
++ goto errOut;
++ }
+
+ // Find the creation date.
+ jlong creationDate = getModDateFromItem(env, theItem);
+@@ -376,6 +399,7 @@
+ }
+ } while (searchResult == noErr);
+
++errOut:
+ if (keychainItemSearch != NULL) {
+ CFRelease(keychainItemSearch);
+ }
+@@ -404,6 +428,9 @@
+
+ if (passwordLen > 0) {
+ passwordChars = (*env)->GetCharArrayElements(env, passwordObj, NULL);
++ if (passwordChars == NULL) {
++ goto errOut;
++ }
+ passwordStrRef = CFStringCreateWithCharacters(kCFAllocatorDefault, passwordChars, passwordLen);
+ }
+ }
+@@ -423,9 +450,13 @@
+ if (err == noErr) {
+ CFIndex size = CFDataGetLength(exportedData);
+ returnValue = (*env)->NewByteArray(env, size);
++ if (returnValue == NULL) {
++ goto errOut;
++ }
+ (*env)->SetByteArrayRegion(env, returnValue, 0, size, (jbyte *)CFDataGetBytePtr(exportedData));
+ }
+
++errOut:
+ if (exportedData) CFRelease(exportedData);
+ if (passwordStrRef) CFRelease(passwordStrRef);
+
+@@ -466,6 +497,9 @@
+
+ jsize dataSize = (*env)->GetArrayLength(env, rawDataObj);
+ jbyte *rawData = (*env)->GetByteArrayElements(env, rawDataObj, NULL);
++ if (rawData == NULL) {
++ goto errOut;
++ }
+
+ CFDataRef cfDataToImport = CFDataCreate(kCFAllocatorDefault, (UInt8 *)rawData, dataSize);
+ CFArrayRef createdItems = NULL;
+@@ -522,6 +556,8 @@
+ CFRelease(createdItems);
+ }
+
++errOut: ;
++
+ JNF_COCOA_EXIT(env);
+
+ return returnValue;
+--- ./jdk/src/macosx/native/java/util/MacOSXPreferencesFile.m Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/native/java/util/MacOSXPreferencesFile.m Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -71,6 +71,8 @@
+ static jclass exceptionClass = NULL;
+ jclass c;
+
++ (*env)->ExceptionClear(env); // If an exception is pending, clear it before
++ // calling FindClass() and/or ThrowNew().
+ if (exceptionClass) {
+ c = exceptionClass;
+ } else {
+@@ -534,8 +536,13 @@
+ (JNIEnv *env, jobject klass, jobject jpath,
+ jobject jname, jlong juser, jlong jhost)
+ {
+- CFStringRef path = toCF(env, jpath);
+- CFStringRef name = toCF(env, jname);
++ CFStringRef path = NULL;
++ CFStringRef name = NULL;
++
++ path = toCF(env, jpath);
++ if (path != NULL) {
++ name = toCF(env, jname);
++ }
+ CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+ CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+ CFDictionaryRef node = NULL;
+@@ -579,8 +586,13 @@
+ (JNIEnv *env, jobject klass, jobject jpath,
+ jobject jname, jlong juser, jlong jhost)
+ {
+- CFStringRef path = toCF(env, jpath);
+- CFStringRef name = toCF(env, jname);
++ CFStringRef path = NULL;
++ CFStringRef name = NULL;
++
++ path = toCF(env, jpath);
++ if (path != NULL) {
++ name = toCF(env, jname);
++ }
+ CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+ CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+ CFStringRef parentName;
+@@ -647,9 +659,17 @@
+ jobject jname, jlong juser, jlong jhost)
+ {
+ // like addNode, but can put a three-level-deep dict into the root file
+- CFStringRef path = toCF(env, jpath);
+- CFStringRef child = toCF(env, jchild);
+- CFStringRef name = toCF(env, jname);
++ CFStringRef path = NULL;
++ CFStringRef child = NULL;
++ CFStringRef name = NULL;
++
++ path = toCF(env, jpath);
++ if (path != NULL) {
++ child = toCF(env, jchild);
++ }
++ if (child != NULL) {
++ name = toCF(env, jname);
++ }
+ CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+ CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+ CFMutableDictionaryRef parent;
+@@ -693,9 +713,17 @@
+ (JNIEnv *env, jobject klass, jobject jpath, jobject jchild,
+ jobject jname, jlong juser, jlong jhost)
+ {
+- CFStringRef path = toCF(env, jpath);
+- CFStringRef child = toCF(env, jchild);
+- CFStringRef name = toCF(env, jname);
++ CFStringRef path = NULL;
++ CFStringRef child = NULL;
++ CFStringRef name = NULL;
++
++ path = toCF(env, jpath);
++ if (path != NULL) {
++ child = toCF(env, jchild);
++ }
++ if (child != NULL) {
++ name = toCF(env, jname);
++ }
+ CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+ CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+ CFDictionaryRef constParent;
+@@ -734,10 +762,21 @@
+ (JNIEnv *env, jobject klass, jobject jpath, jobject jkey, jobject jvalue,
+ jobject jname, jlong juser, jlong jhost)
+ {
+- CFStringRef path = toCF(env, jpath);
+- CFStringRef key = toCF(env, jkey);
+- CFStringRef value = toCF(env, jvalue);
+- CFStringRef name = toCF(env, jname);
++ CFStringRef path = NULL;
++ CFStringRef key = NULL;
++ CFStringRef value = NULL;
++ CFStringRef name = NULL;
++
++ path = toCF(env, jpath);
++ if (path != NULL) {
++ key = toCF(env, jkey);
++ }
++ if (key != NULL) {
++ value = toCF(env, jvalue);
++ }
++ if (value != NULL) {
++ name = toCF(env, jname);
++ }
+ CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+ CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+ CFMutableDictionaryRef node = NULL;
+@@ -771,9 +810,17 @@
+ (JNIEnv *env, jobject klass, jobject jpath, jobject jkey,
+ jobject jname, jlong juser, jlong jhost)
+ {
+- CFStringRef path = toCF(env, jpath);
+- CFStringRef key = toCF(env, jkey);
+- CFStringRef name = toCF(env, jname);
++ CFStringRef path = NULL;
++ CFStringRef key = NULL;
++ CFStringRef name = NULL;
++
++ path = toCF(env, jpath);
++ if (path != NULL) {
++ key = toCF(env, jkey);
++ }
++ if (key != NULL) {
++ name = toCF(env, jname);
++ }
+ CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+ CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+ CFDictionaryRef constNode;
+@@ -812,9 +859,17 @@
+ (JNIEnv *env, jobject klass, jobject jpath, jobject jkey,
+ jobject jname, jlong juser, jlong jhost)
+ {
+- CFStringRef path = toCF(env, jpath);
+- CFStringRef key = toCF(env, jkey);
+- CFStringRef name = toCF(env, jname);
++ CFStringRef path = NULL;
++ CFStringRef key = NULL;
++ CFStringRef name = NULL;
++
++ path = toCF(env, jpath);
++ if (path != NULL) {
++ key = toCF(env, jkey);
++ }
++ if (key != NULL) {
++ name = toCF(env, jname);
++ }
+ CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+ CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+ CFPropertyListRef value;
+@@ -914,8 +969,13 @@
+ jobject jname, jlong juser, jlong jhost,
+ Boolean allowSlash)
+ {
+- CFStringRef path = toCF(env, jpath);
+- CFStringRef name = toCF(env, jname);
++ CFStringRef path = NULL;
++ CFStringRef name = NULL;
++
++ path = toCF(env, jpath);
++ if (path != NULL) {
++ name = toCF(env, jname);
++ }
+ CFStringRef user = (CFStringRef)jlong_to_ptr(juser);
+ CFStringRef host = (CFStringRef)jlong_to_ptr(jhost);
+ CFDictionaryRef node;
+--- ./jdk/src/macosx/native/sun/awt/AWTWindow.m Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/native/sun/awt/AWTWindow.m Wed Feb 04 12:14:43 2015 -0800
+@@ -104,6 +104,67 @@
+
+ @implementation AWTWindow_Normal
+ AWT_NS_WINDOW_IMPLEMENTATION
++
++// Gesture support
++- (void)postGesture:(NSEvent *)event as:(jint)type a:(jdouble)a b:(jdouble)b {
++ AWT_ASSERT_APPKIT_THREAD;
++
++ JNIEnv *env = [ThreadUtilities getJNIEnv];
++ jobject platformWindow = [((AWTWindow *)self.delegate).javaPlatformWindow jObjectWithEnv:env];
++ if (platformWindow != NULL) {
++ // extract the target AWT Window object out of the CPlatformWindow
++ static JNF_MEMBER_CACHE(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;");
++ jobject awtWindow = JNFGetObjectField(env, platformWindow, jf_target);
++ if (awtWindow != NULL) {
++ // translate the point into Java coordinates
++ NSPoint loc = [event locationInWindow];
++ loc.y = [self frame].size.height - loc.y;
++
++ // send up to the GestureHandler to recursively dispatch on the AWT event thread
++ static JNF_CLASS_CACHE(jc_GestureHandler, "com/apple/eawt/event/GestureHandler");
++ static JNF_STATIC_MEMBER_CACHE(sjm_handleGestureFromNative, jc_GestureHandler, "handleGestureFromNative", "(Ljava/awt/Window;IDDDD)V");
++ JNFCallStaticVoidMethod(env, sjm_handleGestureFromNative, awtWindow, type, (jdouble)loc.x, (jdouble)loc.y, (jdouble)a, (jdouble)b);
++ (*env)->DeleteLocalRef(env, awtWindow);
++ }
++ (*env)->DeleteLocalRef(env, platformWindow);
++ }
++}
++
++- (void)beginGestureWithEvent:(NSEvent *)event {
++ [self postGesture:event
++ as:com_apple_eawt_event_GestureHandler_PHASE
++ a:-1.0
++ b:0.0];
++}
++
++- (void)endGestureWithEvent:(NSEvent *)event {
++ [self postGesture:event
++ as:com_apple_eawt_event_GestureHandler_PHASE
++ a:1.0
++ b:0.0];
++}
++
++- (void)magnifyWithEvent:(NSEvent *)event {
++ [self postGesture:event
++ as:com_apple_eawt_event_GestureHandler_MAGNIFY
++ a:[event magnification]
++ b:0.0];
++}
++
++- (void)rotateWithEvent:(NSEvent *)event {
++ [self postGesture:event
++ as:com_apple_eawt_event_GestureHandler_ROTATE
++ a:[event rotation]
++ b:0.0];
++}
++
++- (void)swipeWithEvent:(NSEvent *)event {
++ [self postGesture:event
++ as:com_apple_eawt_event_GestureHandler_SWIPE
++ a:[event deltaX]
++ b:[event deltaY]];
++}
++
+ @end
+ @implementation AWTWindow_Panel
+ AWT_NS_WINDOW_IMPLEMENTATION
+@@ -399,67 +460,6 @@
+ }
+
+
+-// Gesture support
+-- (void)postGesture:(NSEvent *)event as:(jint)type a:(jdouble)a b:(jdouble)b {
+-AWT_ASSERT_APPKIT_THREAD;
+-
+- JNIEnv *env = [ThreadUtilities getJNIEnv];
+- jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
+- if (platformWindow != NULL) {
+- // extract the target AWT Window object out of the CPlatformWindow
+- static JNF_MEMBER_CACHE(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;");
+- jobject awtWindow = JNFGetObjectField(env, platformWindow, jf_target);
+- if (awtWindow != NULL) {
+- // translate the point into Java coordinates
+- NSPoint loc = [event locationInWindow];
+- loc.y = [self.nsWindow frame].size.height - loc.y;
+-
+- // send up to the GestureHandler to recursively dispatch on the AWT event thread
+- static JNF_CLASS_CACHE(jc_GestureHandler, "com/apple/eawt/event/GestureHandler");
+- static JNF_STATIC_MEMBER_CACHE(sjm_handleGestureFromNative, jc_GestureHandler, "handleGestureFromNative", "(Ljava/awt/Window;IDDDD)V");
+- JNFCallStaticVoidMethod(env, sjm_handleGestureFromNative, awtWindow, type, (jdouble)loc.x, (jdouble)loc.y, (jdouble)a, (jdouble)b);
+- (*env)->DeleteLocalRef(env, awtWindow);
+- }
+- (*env)->DeleteLocalRef(env, platformWindow);
+- }
+-}
+-
+-- (void)beginGestureWithEvent:(NSEvent *)event {
+- [self postGesture:event
+- as:com_apple_eawt_event_GestureHandler_PHASE
+- a:-1.0
+- b:0.0];
+-}
+-
+-- (void)endGestureWithEvent:(NSEvent *)event {
+- [self postGesture:event
+- as:com_apple_eawt_event_GestureHandler_PHASE
+- a:1.0
+- b:0.0];
+-}
+-
+-- (void)magnifyWithEvent:(NSEvent *)event {
+- [self postGesture:event
+- as:com_apple_eawt_event_GestureHandler_MAGNIFY
+- a:[event magnification]
+- b:0.0];
+-}
+-
+-- (void)rotateWithEvent:(NSEvent *)event {
+- [self postGesture:event
+- as:com_apple_eawt_event_GestureHandler_ROTATE
+- a:[event rotation]
+- b:0.0];
+-}
+-
+-- (void)swipeWithEvent:(NSEvent *)event {
+- [self postGesture:event
+- as:com_apple_eawt_event_GestureHandler_SWIPE
+- a:[event deltaX]
+- b:[event deltaY]];
+-}
+-
+-
+ // NSWindowDelegate methods
+
+ - (void) _deliverMoveResizeEvent {
+--- ./jdk/src/macosx/native/sun/awt/CWrapper.m Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/native/sun/awt/CWrapper.m Wed Feb 04 12:14:43 2015 -0800
+@@ -175,6 +175,23 @@
+
+ /*
+ * Class: sun_lwawt_macosx_CWrapper$NSWindow
++ * Method: close
++ * Signature: (J)V
++ */
++JNIEXPORT void JNICALL
++Java_sun_lwawt_macosx_CWrapper_00024NSWindow_close
++ (JNIEnv *env, jclass cls, jlong windowPtr)
++{
++JNF_COCOA_ENTER(env);
++ NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
++ [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
++ [window close];
++ }];
++JNF_COCOA_EXIT(env);
++}
++
++/*
++ * Class: sun_lwawt_macosx_CWrapper$NSWindow
+ * Method: orderFrontRegardless
+ * Signature: (J)V
+ */
+--- ./jdk/src/macosx/native/sun/awt/JavaComponentAccessibility.m Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/native/sun/awt/JavaComponentAccessibility.m Wed Feb 04 12:14:43 2015 -0800
+@@ -1122,7 +1122,10 @@
+ JNIEnv *env = [ThreadUtilities getJNIEnv];
+ id value = nil;
+
++ NSWindow* hostWindow = [[self->fView window] retain];
+ jobject focused = JNFCallStaticObjectMethod(env, jm_getFocusOwner, fComponent); // AWT_THREADING Safe (AWTRunLoop)
++ [hostWindow release];
++
+ if (focused != NULL) {
+ if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) {
+ value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView];
+--- ./jdk/src/macosx/native/sun/awt/LWCToolkit.m Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/native/sun/awt/LWCToolkit.m Wed Feb 04 12:14:43 2015 -0800
+@@ -413,6 +413,23 @@
+ return active;
+ }
+
++/*
++ * Class: sun_lwawt_macosx_LWCToolkit
++ * Method: activateApplicationIgnoringOtherApps
++ * Signature: ()V
++ */
++JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_activateApplicationIgnoringOtherApps
++(JNIEnv *env, jclass clazz)
++{
++ JNF_COCOA_ENTER(env);
++ [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
++ if(![NSApp isActive]){
++ [NSApp activateIgnoringOtherApps:YES];
++ }
++ }];
++ JNF_COCOA_EXIT(env);
++}
++
+
+ /*
+ * Class: sun_awt_SunToolkit
+@@ -452,3 +469,14 @@
+
+ }
+
++/*
++ * Class: sun_lwawt_macosx_LWCToolkit
++ * Method: isEmbedded
++ * Signature: ()Z
++ */
++JNIEXPORT jboolean JNICALL
++Java_sun_lwawt_macosx_LWCToolkit_isEmbedded
++(JNIEnv *env, jclass klass) {
++ return [ThreadUtilities isAWTEmbedded] ? JNI_TRUE : JNI_FALSE;
++}
++
+--- ./jdk/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m Wed Feb 04 12:14:43 2015 -0800
+@@ -45,6 +45,7 @@
+ #include <dlfcn.h>
+
+ #include <sizecalc.h>
++#import "ThreadUtilities.h"
+
+ static NSScreen* SplashNSScreen()
+ {
+@@ -125,6 +126,43 @@
+ return buf;
+ }
+
++char* SplashGetScaledImageName(const char* jar, const char* file,
++ float *scaleFactor) {
++ NSAutoreleasePool *pool = [NSAutoreleasePool new];
++ *scaleFactor = 1;
++ char* scaledFile = nil;
++ __block float screenScaleFactor = 1;
++
++ [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
++ screenScaleFactor = [SplashNSScreen() backingScaleFactor];
++ }];
++
++ if (screenScaleFactor > 1) {
++ NSString *fileName = [NSString stringWithUTF8String: file];
++ NSUInteger length = [fileName length];
++ NSRange range = [fileName rangeOfString: @"."
++ options:NSBackwardsSearch];
++ NSUInteger dotIndex = range.location;
++ NSString *fileName2x = nil;
++
++ if (dotIndex == NSNotFound) {
++ fileName2x = [fileName stringByAppendingString: @"@2x"];
++ } else {
++ fileName2x = [fileName substringToIndex: dotIndex];
++ fileName2x = [fileName2x stringByAppendingString: @"@2x"];
++ fileName2x = [fileName2x stringByAppendingString:
++ [fileName substringFromIndex: dotIndex]];
++ }
++
++ if ((fileName2x != nil) && (jar || [[NSFileManager defaultManager]
++ fileExistsAtPath: fileName2x])){
++ *scaleFactor = 2;
++ scaledFile = strdup([fileName2x UTF8String]);
++ }
++ }
++ [pool drain];
++ return scaledFile;
++}
+
+ void
+ SplashInitPlatform(Splash * splash) {
+@@ -132,7 +170,7 @@
+
+ splash->maskRequired = 0;
+
+-
++
+ //TODO: the following is too much of a hack but should work in 90% cases.
+ // besides we don't use device-dependant drawing, so probably
+ // that's very fine indeed
+@@ -218,7 +256,15 @@
+ [image setBackgroundColor: [NSColor clearColor]];
+
+ [image addRepresentation: rep];
+-
++ float scaleFactor = splash->scaleFactor;
++ if (scaleFactor > 0 && scaleFactor != 1) {
++ [image setScalesWhenResized:YES];
++ NSSize size = [image size];
++ size.width /= scaleFactor;
++ size.height /= scaleFactor;
++ [image setSize: size];
++ }
++
+ NSImageView * view = [[NSImageView alloc] init];
+
+ [view setImage: image];
+--- ./jdk/src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m Wed Feb 04 12:14:43 2015 -0800
+@@ -72,7 +72,9 @@
+ }
+ [pool drain];
+ free(ctxinfo);
++ oglc->ctxInfo = NULL;
+ }
++ cglinfo->context = NULL;
+ }
+
+ free(cglinfo);
+--- ./jdk/src/macosx/native/sun/java2d/opengl/CGLSurfaceData.m Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/native/sun/java2d/opengl/CGLSurfaceData.m Wed Feb 04 12:14:43 2015 -0800
+@@ -187,6 +187,11 @@
+ }
+
+ OGLContext *oglc = cglInfo->context;
++ if (oglc == NULL) {
++ J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_SetScratchContext: ogl context is null");
++ return NULL;
++ }
++
+ CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
+
+ JNF_COCOA_ENTER(env);
+--- ./jdk/src/macosx/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/macosx/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c Wed Feb 04 12:14:43 2015 -0800
+@@ -24,6 +24,7 @@
+ */
+
+ #include "sun_util_locale_provider_HostLocaleProviderAdapterImpl.h"
++#include "jni_util.h"
+ #include <CoreFoundation/CoreFoundation.h>
+ #include <stdio.h>
+
+@@ -63,6 +64,10 @@
+ localeString = getMacOSXLocale(posixCat);
+ if (localeString == NULL) {
+ localeString = getPosixLocale(posixCat);
++ if (localeString == NULL) {
++ JNU_ThrowOutOfMemoryError(env, NULL);
++ return NULL;
++ }
+ }
+ ret = (*env)->NewStringUTF(env, localeString);
+ free(localeString);
+@@ -127,6 +132,7 @@
+ JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getAmPmStrings
+ (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray ampms) {
+ CFLocaleRef cflocale = CFLocaleCopyCurrent();
++ jstring tmp_string;
+ if (cflocale != NULL) {
+ CFDateFormatterRef df = CFDateFormatterCreate(kCFAllocatorDefault,
+ cflocale,
+@@ -138,13 +144,21 @@
+ if (amStr != NULL) {
+ CFStringGetCString(amStr, buf, BUFLEN, kCFStringEncodingUTF8);
+ CFRelease(amStr);
+- (*env)->SetObjectArrayElement(env, ampms, 0, (*env)->NewStringUTF(env, buf));
++ tmp_string = (*env)->NewStringUTF(env, buf);
++ if (tmp_string != NULL) {
++ (*env)->SetObjectArrayElement(env, ampms, 0, tmp_string);
++ }
+ }
+- CFStringRef pmStr = CFDateFormatterCopyProperty(df, kCFDateFormatterPMSymbol);
+- if (pmStr != NULL) {
+- CFStringGetCString(pmStr, buf, BUFLEN, kCFStringEncodingUTF8);
+- CFRelease(pmStr);
+- (*env)->SetObjectArrayElement(env, ampms, 1, (*env)->NewStringUTF(env, buf));
++ if (!(*env)->ExceptionCheck(env)){
++ CFStringRef pmStr = CFDateFormatterCopyProperty(df, kCFDateFormatterPMSymbol);
++ if (pmStr != NULL) {
++ CFStringGetCString(pmStr, buf, BUFLEN, kCFStringEncodingUTF8);
++ CFRelease(pmStr);
++ tmp_string = (*env)->NewStringUTF(env, buf);
++ if (tmp_string != NULL) {
++ (*env)->SetObjectArrayElement(env, ampms, 1, tmp_string);
++ }
++ }
+ }
+ CFRelease(df);
+ }
+@@ -647,10 +661,16 @@
+
+ static void copyArrayElements(JNIEnv *env, CFArrayRef cfarray, jobjectArray jarray, CFIndex sindex, int dindex, int count) {
+ char buf[BUFLEN];
++ jstring tmp_string;
+
+ for (; count > 0; sindex++, dindex++, count--) {
+ CFStringGetCString(CFArrayGetValueAtIndex(cfarray, sindex), buf, BUFLEN, kCFStringEncodingUTF8);
+- (*env)->SetObjectArrayElement(env, jarray, dindex, (*env)->NewStringUTF(env, buf));
++ tmp_string = (*env)->NewStringUTF(env, buf);
++ if (tmp_string != NULL) {
++ (*env)->SetObjectArrayElement(env, jarray, dindex, tmp_string);
++ } else {
++ break;
++ }
+ }
+ }
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/src/share/back/InterfaceTypeImpl.c Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,39 @@
++/*
++ * Copyright (c) 1998, 2005, 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.
++ */
++
++#include "util.h"
++#include "InterfaceTypeImpl.h"
++#include "inStream.h"
++#include "outStream.h"
++
++static jboolean
++invokeStatic(PacketInputStream *in, PacketOutputStream *out)
++{
++ return sharedInvoke(in, out);
++}
++
++void *InterfaceType_Cmds[] = { (void *)0x1
++ , (void *)invokeStatic
++};
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/src/share/back/InterfaceTypeImpl.h Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,25 @@
++/*
++ * Copyright (c) 1998, 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.
++ */
++extern void *InterfaceType_Cmds[];
+--- ./jdk/src/share/back/VirtualMachineImpl.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/back/VirtualMachineImpl.c Wed Feb 04 12:14:43 2015 -0800
+@@ -36,7 +36,7 @@
+
+ static char *versionName = "Java Debug Wire Protocol (Reference Implementation)";
+ static int majorVersion = 1; /* JDWP major version */
+-static int minorVersion = 6; /* JDWP minor version */
++static int minorVersion = 8; /* JDWP minor version */
+
+ static jboolean
+ version(PacketInputStream *in, PacketOutputStream *out)
+--- ./jdk/src/share/back/debugDispatch.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/back/debugDispatch.c Wed Feb 04 12:14:43 2015 -0800
+@@ -29,6 +29,7 @@
+ #include "VirtualMachineImpl.h"
+ #include "ReferenceTypeImpl.h"
+ #include "ClassTypeImpl.h"
++#include "InterfaceTypeImpl.h"
+ #include "ArrayTypeImpl.h"
+ #include "FieldImpl.h"
+ #include "MethodImpl.h"
+@@ -67,6 +68,7 @@
+ l1Array[JDWP_COMMAND_SET(VirtualMachine)] = (void *)VirtualMachine_Cmds;
+ l1Array[JDWP_COMMAND_SET(ReferenceType)] = (void *)ReferenceType_Cmds;
+ l1Array[JDWP_COMMAND_SET(ClassType)] = (void *)ClassType_Cmds;
++ l1Array[JDWP_COMMAND_SET(InterfaceType)] = (void *)InterfaceType_Cmds;
+ l1Array[JDWP_COMMAND_SET(ArrayType)] = (void *)ArrayType_Cmds;
+
+ l1Array[JDWP_COMMAND_SET(Field)] = (void *)Field_Cmds;
+--- ./jdk/src/share/back/util.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/back/util.c Wed Feb 04 12:14:43 2015 -0800
+@@ -591,6 +591,8 @@
+ invokeType = INVOKE_CONSTRUCTOR;
+ } else if (inStream_command(in) == JDWP_COMMAND(ClassType, InvokeMethod)) {
+ invokeType = INVOKE_STATIC;
++ } else if (inStream_command(in) == JDWP_COMMAND(InterfaceType, InvokeMethod)) {
++ invokeType = INVOKE_STATIC;
+ } else if (inStream_command(in) == JDWP_COMMAND(ObjectReference, InvokeMethod)) {
+ invokeType = INVOKE_INSTANCE;
+ } else {
+--- ./jdk/src/share/bin/java.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/bin/java.c Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -98,6 +98,7 @@
+ */
+ static void SetClassPath(const char *s);
+ static void SelectVersion(int argc, char **argv, char **main_class);
++static void SetJvmEnvironment(int argc, char **argv);
+ static jboolean ParseArguments(int *pargc, char ***pargv,
+ int *pmode, char **pwhat,
+ int *pret, const char *jrepath);
+@@ -238,6 +239,10 @@
+ jvmpath, sizeof(jvmpath),
+ jvmcfg, sizeof(jvmcfg));
+
++ if (!IsJavaArgs()) {
++ SetJvmEnvironment(argc,argv);
++ }
++
+ ifn.CreateJavaVM = 0;
+ ifn.GetDefaultJavaVMInitArgs = 0;
+
+@@ -633,6 +638,67 @@
+ return jvmtype;
+ }
+
++/*
++ * static void SetJvmEnvironment(int argc, char **argv);
++ * Is called just before the JVM is loaded. We can set env variables
++ * that are consumed by the JVM. This function is non-destructive,
++ * leaving the arg list intact. The first use is for the JVM flag
++ * -XX:NativeMemoryTracking=value.
++ */
++static void
++SetJvmEnvironment(int argc, char **argv) {
++
++ static const char* NMT_Env_Name = "NMT_LEVEL_";
++
++ int i;
++ for (i = 0; i < argc; i++) {
++ /*
++ * The following case checks for "-XX:NativeMemoryTracking=value".
++ * If value is non null, an environmental variable set to this value
++ * will be created to be used by the JVM.
++ * The argument is passed to the JVM, which will check validity.
++ * The JVM is responsible for removing the env variable.
++ */
++ char *arg = argv[i];
++ if (JLI_StrCCmp(arg, "-XX:NativeMemoryTracking=") == 0) {
++ int retval;
++ // get what follows this parameter, include "="
++ size_t pnlen = JLI_StrLen("-XX:NativeMemoryTracking=");
++ if (JLI_StrLen(arg) > pnlen) {
++ char* value = arg + pnlen;
++ size_t pbuflen = pnlen + JLI_StrLen(value) + 10; // 10 max pid digits
++
++ /*
++ * ensures that malloc successful
++ * DONT JLI_MemFree() pbuf. JLI_PutEnv() uses system call
++ * that could store the address.
++ */
++ char * pbuf = (char*)JLI_MemAlloc(pbuflen);
++
++ JLI_Snprintf(pbuf, pbuflen, "%s%d=%s", NMT_Env_Name, JLI_GetPid(), value);
++ retval = JLI_PutEnv(pbuf);
++ if (JLI_IsTraceLauncher()) {
++ char* envName;
++ char* envBuf;
++
++ // ensures that malloc successful
++ envName = (char*)JLI_MemAlloc(pbuflen);
++ JLI_Snprintf(envName, pbuflen, "%s%d", NMT_Env_Name, JLI_GetPid());
++
++ printf("TRACER_MARKER: NativeMemoryTracking: env var is %s\n",envName);
++ printf("TRACER_MARKER: NativeMemoryTracking: putenv arg %s\n",pbuf);
++ envBuf = getenv(envName);
++ printf("TRACER_MARKER: NativeMemoryTracking: got value %s\n",envBuf);
++ free(envName);
++ }
++
++ }
++
++ }
++
++ }
++}
++
+ /* copied from HotSpot function "atomll()" */
+ static int
+ parse_size(const char *s, jlong *result) {
+@@ -1182,11 +1248,13 @@
+ (*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s);
+ if (!(*env)->ExceptionOccurred(env)) {
+ if (makePlatformStringMID == NULL) {
+- NULL_CHECK0(makePlatformStringMID = (*env)->GetStaticMethodID(env,
++ CHECK_JNI_RETURN_0(
++ makePlatformStringMID = (*env)->GetStaticMethodID(env,
+ cls, "makePlatformString", "(Z[B)Ljava/lang/String;"));
+ }
+- str = (*env)->CallStaticObjectMethod(env, cls,
+- makePlatformStringMID, USE_STDERR, ary);
++ CHECK_JNI_RETURN_0(
++ str = (*env)->CallStaticObjectMethod(env, cls,
++ makePlatformStringMID, USE_STDERR, ary));
+ (*env)->DeleteLocalRef(env, ary);
+ return str;
+ }
+@@ -1237,7 +1305,9 @@
+ "(ZILjava/lang/String;)Ljava/lang/Class;"));
+
+ str = NewPlatformString(env, name);
+- result = (*env)->CallStaticObjectMethod(env, cls, mid, USE_STDERR, mode, str);
++ CHECK_JNI_RETURN_0(
++ result = (*env)->CallStaticObjectMethod(
++ env, cls, mid, USE_STDERR, mode, str));
+
+ if (JLI_IsTraceLauncher()) {
+ end = CounterGet();
+@@ -1804,20 +1874,48 @@
+ const char *jar_name = getenv(SPLASH_JAR_ENV_ENTRY);
+ const char *file_name = getenv(SPLASH_FILE_ENV_ENTRY);
+ int data_size;
+- void *image_data;
++ void *image_data = NULL;
++ float scale_factor = 1;
++ char *scaled_splash_name = NULL;
++
++ if (file_name == NULL){
++ return;
++ }
++
++ scaled_splash_name = DoSplashGetScaledImageName(
++ jar_name, file_name, &scale_factor);
+ if (jar_name) {
+- image_data = JLI_JarUnpackFile(jar_name, file_name, &data_size);
++
++ if (scaled_splash_name) {
++ image_data = JLI_JarUnpackFile(
++ jar_name, scaled_splash_name, &data_size);
++ }
++
++ if (!image_data) {
++ scale_factor = 1;
++ image_data = JLI_JarUnpackFile(
++ jar_name, file_name, &data_size);
++ }
+ if (image_data) {
+ DoSplashInit();
++ DoSplashSetScaleFactor(scale_factor);
+ DoSplashLoadMemory(image_data, data_size);
+ JLI_MemFree(image_data);
+ }
+- } else if (file_name) {
++ } else {
+ DoSplashInit();
+- DoSplashLoadFile(file_name);
+- } else {
+- return;
++ if (scaled_splash_name) {
++ DoSplashSetScaleFactor(scale_factor);
++ DoSplashLoadFile(scaled_splash_name);
++ } else {
++ DoSplashLoadFile(file_name);
++ }
+ }
++
++ if (scaled_splash_name) {
++ JLI_MemFree(scaled_splash_name);
++ }
++
+ DoSplashSetFileJarName(file_name, jar_name);
+
+ /*
+--- ./jdk/src/share/bin/java.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/bin/java.h Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -256,4 +256,47 @@
+ #define NULL_CHECK(NC_check_pointer) \
+ NULL_CHECK_RETURN_VALUE(NC_check_pointer, )
+
++/*
++ * For JNI calls :
++ * - check for thrown exceptions
++ * - check for null return
++ *
++ * JNI calls can return null and/or throw an exception. Check for these.
++ *
++ * : CHECK_JNI_RETURN_EXCEPTION()
++ * return the specified RETURNVALUE if exception was generated
++ * : CHECK_JNI_RETURN_0(JNISTATEMENT) : check if JNISTATEMENT was successful, return 0 if not
++ * : CHECK_JNI_RETURN_VOID(JNISTATEMENT) : check if JNISTATEMENT was successful, return void if not
++ * : CHECK_JNI_RETURN_VALUE(JNISTATEMENT,n) : check if JNISTATEMENT was successful, return n if not
++ *
++ * These macros need at least one parameter, the JNI statement [ JNISTATEMENT ].
++ *
++ * E.G.: check the JNI statement, and specify a value to return if a failure was detected.
++ *
++ * CHECK_JNI_RETURN_VALUE(str = (*env)->CallStaticObjectMethod(env, cls,
++ * makePlatformStringMID, USE_STDERR, ary), -1);
++ */
++
++#define RETURNVOID return
++#define RETURN0 return 0
++#define RETURN(N) return (N)
++
++#define CHECK_JNI_RETURN_EXCEPTION(RETURNVALUE) \
++ if ((((*env)->ExceptionOccurred(env))!=NULL)) { \
++ RETURNVALUE; \
++ }
++
++#define CHECK_JNI_RETURN_0(JNISTATEMENT) \
++ CHECK_JNI_RETURN_EXCEPTION(RETURN0); \
++ NULL_CHECK0(JNISTATEMENT);
++
++#define CHECK_JNI_RETURN_VOID(JNISTATEMENT) \
++ CHECK_JNI_RETURN_EXCEPTION(RETURNVOID); \
++ NULL_CHECK(JNISTATEMENT);
++
++#define CHECK_JNI_RETURN_VALUE(JNISTATEMENT, NCRV_return_value) \
++ CHECK_JNI_RETURN_EXCEPTION(RETURN(NCRV_return_value)); \
++ NULL_CHECK_RETURN_VALUE(JNISTATEMENT, NCRV_return_value);
++
++
+ #endif /* _JAVA_H_ */
+--- ./jdk/src/share/bin/jli_util.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/bin/jli_util.h Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -64,17 +64,22 @@
+ #ifdef _WIN32
+ #include <windows.h>
+ #include <io.h>
++#include <process.h>
+ #define JLI_StrCaseCmp(p1, p2) stricmp((p1), (p2))
+ #define JLI_StrNCaseCmp(p1, p2, p3) strnicmp((p1), (p2), (p3))
+ int JLI_Snprintf(char *buffer, size_t size, const char *format, ...);
+ void JLI_CmdToArgs(char *cmdline);
+ #define JLI_Lseek _lseeki64
++#define JLI_PutEnv _putenv
++#define JLI_GetPid _getpid
+ #else /* NIXES */
+ #include <unistd.h>
+ #include <strings.h>
+ #define JLI_StrCaseCmp(p1, p2) strcasecmp((p1), (p2))
+ #define JLI_StrNCaseCmp(p1, p2, p3) strncasecmp((p1), (p2), (p3))
+ #define JLI_Snprintf snprintf
++#define JLI_PutEnv putenv
++#define JLI_GetPid getpid
+ #ifdef __solaris__
+ #define JLI_Lseek llseek
+ #endif
+--- ./jdk/src/share/bin/splashscreen.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/bin/splashscreen.h Wed Feb 04 12:14:43 2015 -0800
+@@ -29,3 +29,6 @@
+ void DoSplashInit(void);
+ void DoSplashClose(void);
+ void DoSplashSetFileJarName(const char* fileName, const char* jarName);
++void DoSplashSetScaleFactor(float scaleFactor);
++char* DoSplashGetScaledImageName(const char* jarName, const char* fileName,
++ float* scaleFactor);
+--- ./jdk/src/share/bin/splashscreen_stubs.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/bin/splashscreen_stubs.c Wed Feb 04 12:14:43 2015 -0800
+@@ -37,6 +37,9 @@
+ typedef void (*SplashClose_t)(void);
+ typedef void (*SplashSetFileJarName_t)(const char* fileName,
+ const char* jarName);
++typedef void (*SplashSetScaleFactor_t)(float scaleFactor);
++typedef char* (*SplashGetScaledImageName_t)(const char* fileName,
++ const char* jarName, float* scaleFactor);
+
+ /*
+ * This macro invokes a function from the shared lib.
+@@ -58,11 +61,11 @@
+ #define INVOKEV(name) _INVOKE(name, ,;)
+
+ int DoSplashLoadMemory(void* pdata, int size) {
+- INVOKE(SplashLoadMemory,0)(pdata, size);
++ INVOKE(SplashLoadMemory, NULL)(pdata, size);
+ }
+
+ int DoSplashLoadFile(const char* filename) {
+- INVOKE(SplashLoadFile,0)(filename);
++ INVOKE(SplashLoadFile, NULL)(filename);
+ }
+
+ void DoSplashInit(void) {
+@@ -76,3 +79,12 @@
+ void DoSplashSetFileJarName(const char* fileName, const char* jarName) {
+ INVOKEV(SplashSetFileJarName)(fileName, jarName);
+ }
++
++void DoSplashSetScaleFactor(float scaleFactor) {
++ INVOKEV(SplashSetScaleFactor)(scaleFactor);
++}
++
++char* DoSplashGetScaledImageName(const char* fileName, const char* jarName,
++ float* scaleFactor) {
++ INVOKE(SplashGetScaledImageName, NULL)(fileName, jarName, scaleFactor);
++}
+\ No newline at end of file
+--- ./jdk/src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1254,8 +1254,11 @@
+ if (name.equals("IHDR")) {
+ IHDR_width = getIntAttribute(node, "width");
+ IHDR_height = getIntAttribute(node, "height");
+- IHDR_bitDepth = getEnumeratedAttribute(node, "bitDepth",
+- IHDR_bitDepths);
++ IHDR_bitDepth =
++ Integer.valueOf(IHDR_bitDepths[
++ getEnumeratedAttribute(node,
++ "bitDepth",
++ IHDR_bitDepths)]);
+ IHDR_colorType = getEnumeratedAttribute(node, "colorType",
+ IHDR_colorTypeNames);
+ IHDR_compressionMethod =
+--- ./jdk/src/share/classes/com/sun/jarsigner/ContentSigner.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/jarsigner/ContentSigner.java Wed Feb 04 12:14:43 2015 -0800
+@@ -37,6 +37,7 @@
+ * @author Vincent Ryan
+ */
+
++@jdk.Exported
+ public abstract class ContentSigner {
+
+ /**
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/src/share/classes/com/sun/jarsigner/package-info.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.
++ */
++/**
++ * This package comprises the interfaces and classes used to define the
++ * signing mechanism used by the <tt>jarsigner</tt> tool.
++ * <p>
++ * Clients may override the default signing mechanism of the <tt>jarsigner</tt>
++ * tool by supplying an alternative implementation of
++ * {@link com.sun.jarsigner.ContentSigner}.
++ */
++
++@jdk.Exported
++package com.sun.jarsigner;
+--- ./jdk/src/share/classes/com/sun/jarsigner/package.html Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,38 +0,0 @@
+-<html>
+-<!--
+-
+-Copyright (c) 2003, 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.
+--->
+- <head>
+- <title>Jarsigner Signing Mechanism Package</title>
+- </head>
+- <body>
+-This package comprises the interfaces and classes used to define the
+-signing mechanism used by the <tt>jarsigner</tt> tool.
+-<p>
+-Clients may override the default signing mechanism of the <tt>jarsigner</tt>
+-tool by supplying an alternative implementation of
+-{@link com.sun.jarsigner.ContentSigner}.
+- </body>
+-</html>
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1285,7 +1285,7 @@
+ /**
+ * Render different filters
+ */
+- public class FilterComboBoxRenderer extends DefaultListCellRenderer implements UIResource {
++ public class FilterComboBoxRenderer extends DefaultListCellRenderer {
+ public String getName() {
+ // As SynthComboBoxRenderer's are asked for a size BEFORE they
+ // are parented getName is overriden to force the name to be
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/AnimationController.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/AnimationController.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -130,11 +130,14 @@
+ //one second seems plausible value
+ duration = 1000;
+ } else {
+- duration = XPStyle.getXP().getThemeTransitionDuration(
+- c, part,
+- normalizeState(oldState),
+- normalizeState(newState),
+- Prop.TRANSITIONDURATIONS);
++ XPStyle xp = XPStyle.getXP();
++ duration = (xp != null)
++ ? xp.getThemeTransitionDuration(
++ c, part,
++ normalizeState(oldState),
++ normalizeState(newState),
++ Prop.TRANSITIONDURATIONS)
++ : 1000;
+ }
+ controller.startAnimation(c, part, oldState, newState, duration);
+ }
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsComboBoxUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsComboBoxUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -37,6 +37,7 @@
+ import static com.sun.java.swing.plaf.windows.TMSchema.Part;
+ import static com.sun.java.swing.plaf.windows.TMSchema.State;
+ import static com.sun.java.swing.plaf.windows.XPStyle.Skin;
++
+ import sun.swing.DefaultLookup;
+ import sun.swing.StringUIClientPropertyKey;
+
+@@ -231,6 +232,9 @@
+
+ private void paintXPComboBoxBackground(Graphics g, JComponent c) {
+ XPStyle xp = XPStyle.getXP();
++ if (xp == null) {
++ return;
++ }
+ State state = getXPComboBoxState(c);
+ Skin skin = null;
+ if (! comboBox.isEditable()
+@@ -400,17 +404,18 @@
+ * @return a button which represents the popup control
+ */
+ protected JButton createArrowButton() {
+- if (XPStyle.getXP() != null) {
+- return new XPComboBoxButton();
++ XPStyle xp = XPStyle.getXP();
++ if (xp != null) {
++ return new XPComboBoxButton(xp);
+ } else {
+ return super.createArrowButton();
+ }
+ }
+
+ private class XPComboBoxButton extends XPStyle.GlyphButton {
+- public XPComboBoxButton() {
++ public XPComboBoxButton(XPStyle xp) {
+ super(null,
+- (! XPStyle.getXP().isSkinDefined(comboBox, Part.CP_DROPDOWNBUTTONRIGHT))
++ (! xp.isSkinDefined(comboBox, Part.CP_DROPDOWNBUTTONRIGHT))
+ ? Part.CP_DROPDOWNBUTTON
+ : (comboBox.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT)
+ ? Part.CP_DROPDOWNBUTTONLEFT
+@@ -423,10 +428,11 @@
+ protected State getState() {
+ State rv;
+ rv = super.getState();
++ XPStyle xp = XPStyle.getXP();
+ if (rv != State.DISABLED
+ && comboBox != null && ! comboBox.isEditable()
+- && XPStyle.getXP().isSkinDefined(comboBox,
+- Part.CP_DROPDOWNBUTTONRIGHT)) {
++ && xp != null && xp.isSkinDefined(comboBox,
++ Part.CP_DROPDOWNBUTTONRIGHT)) {
+ /*
+ * for non editable ComboBoxes Vista seems to have the
+ * same glyph for all non DISABLED states
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsGraphicsUtils.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsGraphicsUtils.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -125,6 +125,9 @@
+ static void paintXPText(AbstractButton b, Part part, State state,
+ Graphics g, int x, int y, String text, int mnemIndex) {
+ XPStyle xp = XPStyle.getXP();
++ if (xp == null) {
++ return;
++ }
+ Color textColor = b.getForeground();
+
+ if (textColor instanceof UIResource) {
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsIconFactory.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsIconFactory.java Wed Feb 04 12:14:43 2015 -0800
+@@ -613,8 +613,8 @@
+
+ private static class MenuArrowIcon implements Icon, UIResource, Serializable {
+ public void paintIcon(Component c, Graphics g, int x, int y) {
+- if (WindowsMenuItemUI.isVistaPainting()) {
+- XPStyle xp = XPStyle.getXP();
++ XPStyle xp = XPStyle.getXP();
++ if (WindowsMenuItemUI.isVistaPainting(xp)) {
+ State state = State.NORMAL;
+ if (c instanceof JMenuItem) {
+ state = ((JMenuItem) c).getModel().isEnabled()
+@@ -647,16 +647,18 @@
+ }
+ }
+ public int getIconWidth() {
+- if (WindowsMenuItemUI.isVistaPainting()) {
+- Skin skin = XPStyle.getXP().getSkin(null, Part.MP_POPUPSUBMENU);
++ XPStyle xp = XPStyle.getXP();
++ if (WindowsMenuItemUI.isVistaPainting(xp)) {
++ Skin skin = xp.getSkin(null, Part.MP_POPUPSUBMENU);
+ return skin.getWidth();
+ } else {
+ return 4;
+ }
+ }
+ public int getIconHeight() {
+- if (WindowsMenuItemUI.isVistaPainting()) {
+- Skin skin = XPStyle.getXP().getSkin(null, Part.MP_POPUPSUBMENU);
++ XPStyle xp = XPStyle.getXP();
++ if (WindowsMenuItemUI.isVistaPainting(xp)) {
++ Skin skin = xp.getSkin(null, Part.MP_POPUPSUBMENU);
+ return skin.getHeight();
+ } else {
+ return 8;
+@@ -682,7 +684,8 @@
+ }
+
+ static int getIconWidth() {
+- return XPStyle.getXP().getSkin(null, Part.MP_POPUPCHECK).getWidth()
++ XPStyle xp = XPStyle.getXP();
++ return ((xp != null) ? xp.getSkin(null, Part.MP_POPUPCHECK).getWidth() : 16)
+ + 2 * OFFSET;
+ }
+
+@@ -745,12 +748,17 @@
+ Icon icon = getIcon();
+ int height = 0;
+ if (icon != null) {
+- height = icon.getIconHeight() + 2 * OFFSET;
++ height = icon.getIconHeight();
+ } else {
+- Skin skin =
+- XPStyle.getXP().getSkin(null, Part.MP_POPUPCHECK);
+- height = skin.getHeight() + 2 * OFFSET;
++ XPStyle xp = XPStyle.getXP();
++ if (xp != null) {
++ Skin skin = xp.getSkin(null, Part.MP_POPUPCHECK);
++ height = skin.getHeight();
++ } else {
++ height = 16;
++ }
+ }
++ height += 2 * OFFSET;
+ return height;
+ }
+
+@@ -798,14 +806,16 @@
+ ? State.BULLETDISABLED
+ : State.CHECKMARKDISABLED;
+ }
+- Skin skin;
+ XPStyle xp = XPStyle.getXP();
+- skin = xp.getSkin(c, backgroundPart);
+- skin.paintSkin(g, x, y,
+- getIconWidth(), getIconHeight(), backgroundState);
+- if (icon == null) {
+- skin = xp.getSkin(c, part);
+- skin.paintSkin(g, x + OFFSET, y + OFFSET, state);
++ if (xp != null) {
++ Skin skin;
++ skin = xp.getSkin(c, backgroundPart);
++ skin.paintSkin(g, x, y,
++ getIconWidth(), getIconHeight(), backgroundState);
++ if (icon == null) {
++ skin = xp.getSkin(c, part);
++ skin.paintSkin(g, x + OFFSET, y + OFFSET, state);
++ }
+ }
+ }
+ }
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -85,14 +85,15 @@
+ }
+ } else {
+ buttonWidth += 2;
+- selectedTitleGradientColor =
+- UIManager.getColor("InternalFrame.activeTitleGradient");
+- notSelectedTitleGradientColor =
+- UIManager.getColor("InternalFrame.inactiveTitleGradient");
+ Color activeBorderColor =
+ UIManager.getColor("InternalFrame.activeBorderColor");
+ setBorder(BorderFactory.createLineBorder(activeBorderColor, 1));
+ }
++ // JDK-8039383: initialize these colors because getXP() may return null when theme is changed
++ selectedTitleGradientColor =
++ UIManager.getColor("InternalFrame.activeTitleGradient");
++ notSelectedTitleGradientColor =
++ UIManager.getColor("InternalFrame.inactiveTitleGradient");
+ }
+
+ protected void uninstallListeners() {
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java Wed Feb 04 12:14:43 2015 -0800
+@@ -2399,8 +2399,9 @@
+ }
+
+ public Object getXPValue(UIDefaults table) {
+- Border xpBorder = XPStyle.getXP().getBorder(null, (Part)xpValue);
+- if (extraMargin != null) {
++ XPStyle xp = XPStyle.getXP();
++ Border xpBorder = xp != null ? xp.getBorder(null, (Part)xpValue) : null;
++ if (xpBorder != null && extraMargin != null) {
+ return new BorderUIResource.
+ CompoundBorderUIResource(xpBorder, extraMargin);
+ } else {
+@@ -2416,7 +2417,8 @@
+
+ public Object getXPValue(UIDefaults table) {
+ XPColorValueKey key = (XPColorValueKey)xpValue;
+- return XPStyle.getXP().getColor(key.skin, key.prop, null);
++ XPStyle xp = XPStyle.getXP();
++ return xp != null ? xp.getColor(key.skin, key.prop, null) : null;
+ }
+
+ private static class XPColorValueKey {
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsMenuBarUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsMenuBarUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -155,8 +155,8 @@
+
+ @Override
+ public void paint(Graphics g, JComponent c) {
+- if (WindowsMenuItemUI.isVistaPainting()) {
+- XPStyle xp = XPStyle.getXP();
++ XPStyle xp = XPStyle.getXP();
++ if (WindowsMenuItemUI.isVistaPainting(xp)) {
+ Skin skin;
+ skin = xp.getSkin(c, Part.MP_BARBACKGROUND);
+ int width = c.getWidth();
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsMenuItemUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsMenuItemUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -108,8 +108,9 @@
+
+ static void paintBackground(WindowsMenuItemUIAccessor menuItemUI,
+ Graphics g, JMenuItem menuItem, Color bgColor) {
+- assert isVistaPainting();
+- if (isVistaPainting()) {
++ XPStyle xp = XPStyle.getXP();
++ assert isVistaPainting(xp);
++ if (isVistaPainting(xp)) {
+ int menuWidth = menuItem.getWidth();
+ int menuHeight = menuItem.getHeight();
+ if (menuItem.isOpaque()) {
+@@ -118,7 +119,6 @@
+ g.fillRect(0,0, menuWidth, menuHeight);
+ g.setColor(oldColor);
+ }
+- XPStyle xp = XPStyle.getXP();
+ Part part = menuItemUI.getPart(menuItem);
+ Skin skin = xp.getSkin(menuItem, part);
+ skin.paintSkin(g, 0 , 0,
+@@ -170,8 +170,11 @@
+ * is it possible that in some theme some Vista parts are not defined while
+ * others are?
+ */
+- static boolean isVistaPainting() {
+- XPStyle xp = XPStyle.getXP();
++ static boolean isVistaPainting(final XPStyle xp) {
+ return xp != null && xp.isSkinDefined(null, Part.MP_POPUPITEM);
+ }
++
++ static boolean isVistaPainting() {
++ return isVistaPainting(XPStyle.getXP());
++ }
+ }
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsPopupMenuSeparatorUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsPopupMenuSeparatorUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -50,7 +50,8 @@
+
+ public void paint(Graphics g, JComponent c) {
+ Dimension s = c.getSize();
+- if (WindowsMenuItemUI.isVistaPainting()) {
++ XPStyle xp = XPStyle.getXP();
++ if (WindowsMenuItemUI.isVistaPainting(xp)) {
+ int x = 1;
+ Component parent = c.getParent();
+ if (parent instanceof JComponent) {
+@@ -67,7 +68,7 @@
+ x += WindowsPopupMenuUI.getGutterWidth();
+ }
+ }
+- Skin skin = XPStyle.getXP().getSkin(c, Part.MP_POPUPSEPARATOR);
++ Skin skin = xp.getSkin(c, Part.MP_POPUPSEPARATOR);
+ int skinHeight = skin.getHeight();
+ int y = (s.height - skinHeight) / 2;
+ skin.paintSkin(g, x, y, s.width - x - 1, skinHeight, State.NORMAL);
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsPopupMenuUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsPopupMenuUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -194,8 +194,8 @@
+
+ @Override
+ public void paint(Graphics g, JComponent c) {
+- if (WindowsMenuItemUI.isVistaPainting()) {
+- XPStyle xp = XPStyle.getXP();
++ XPStyle xp = XPStyle.getXP();
++ if (WindowsMenuItemUI.isVistaPainting(xp)) {
+ Skin skin = xp.getSkin(c, Part.MP_POPUPBACKGROUND);
+ skin.paintSkin(g, 0, 0, c.getWidth(),c.getHeight(), State.NORMAL);
+ int textOffset = getTextOffset(c);
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsProgressBarUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsProgressBarUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -322,8 +322,9 @@
+ private Rectangle getFullChunkBounds(Rectangle box) {
+ boolean vertical = (progressBar.getOrientation() == JProgressBar.VERTICAL);
+ XPStyle xp = XPStyle.getXP();
+- int gap = xp.getInt(progressBar, Part.PP_PROGRESS, null,
+- Prop.PROGRESSSPACESIZE, 0);
++ int gap = (xp != null) ? xp.getInt(progressBar, Part.PP_PROGRESS,
++ null, Prop.PROGRESSSPACESIZE, 0)
++ : 0;
+
+ if (!vertical) {
+ int chunksize = box.width+gap;
+@@ -338,6 +339,9 @@
+ boolean vertical,
+ int bgwidth, int bgheight) {
+ XPStyle xp = XPStyle.getXP();
++ if (xp == null) {
++ return;
++ }
+
+ // create a new graphics to keep drawing surface state
+ Graphics2D gfx = (Graphics2D)g.create();
+@@ -396,6 +400,9 @@
+ private void paintXPBackground(Graphics g, boolean vertical,
+ int barRectWidth, int barRectHeight) {
+ XPStyle xp = XPStyle.getXP();
++ if (xp == null) {
++ return;
++ }
+ Part part = vertical ? Part.PP_BARVERT : Part.PP_BAR;
+ Skin skin = xp.getSkin(progressBar, part);
+
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsSliderUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsSliderUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -215,7 +215,6 @@
+ }
+
+ private Part getXPThumbPart() {
+- XPStyle xp = XPStyle.getXP();
+ Part part;
+ boolean vertical = (slider.getOrientation() == JSlider.VERTICAL);
+ boolean leftToRight = slider.getComponentOrientation().isLeftToRight();
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsSpinnerUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsSpinnerUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -63,6 +63,9 @@
+
+ private void paintXPBackground(Graphics g, JComponent c) {
+ XPStyle xp = XPStyle.getXP();
++ if (xp == null) {
++ return;
++ }
+ Skin skin = xp.getSkin(c, Part.EP_EDIT);
+ State state = getXPState(c);
+ skin.paintSkin(g, 0, 0, c.getWidth(), c.getHeight(), state);
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -90,9 +90,10 @@
+ this.column = column;
+ this.hasRollover = (column == getRolloverColumn());
+ if (skin == null) {
+- skin = XPStyle.getXP().getSkin(header, Part.HP_HEADERITEM);
++ XPStyle xp = XPStyle.getXP();
++ skin = (xp != null) ? xp.getSkin(header, Part.HP_HEADERITEM) : null;
+ }
+- Insets margins = skin.getContentMargin();
++ Insets margins = (skin != null) ? skin.getContentMargin() : null;
+ Border border = null;
+ int contentTop = 0;
+ int contentLeft = 0;
+--- ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/XPStyle.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/java/swing/plaf/windows/XPStyle.java Wed Feb 04 12:14:43 2015 -0800
+@@ -115,7 +115,7 @@
+ }
+ }
+ }
+- return xp;
++ return ThemeReader.isXPStyleEnabled() ? xp : null;
+ }
+
+ static boolean isVista() {
+@@ -180,9 +180,10 @@
+ * should probably be cached there instead of here.
+ */
+ Dimension getDimension(Component c, Part part, State state, Prop prop) {
+- return ThemeReader.getPosition(part.getControlName(c), part.getValue(),
+- State.getValue(part, state),
+- prop.getValue());
++ Dimension d = ThemeReader.getPosition(part.getControlName(c), part.getValue(),
++ State.getValue(part, state),
++ prop.getValue());
++ return (d != null) ? d : new Dimension();
+ }
+
+ /** Get a named <code>Point</code> (e.g. a location or an offset) value
+@@ -199,11 +200,7 @@
+ Dimension d = ThemeReader.getPosition(part.getControlName(c), part.getValue(),
+ State.getValue(part, state),
+ prop.getValue());
+- if (d != null) {
+- return new Point(d.width, d.height);
+- } else {
+- return null;
+- }
++ return (d != null) ? new Point(d.width, d.height) : new Point();
+ }
+
+ /** Get a named <code>Insets</code> value from the current style
+@@ -217,9 +214,10 @@
+ * The return value is already cached in those places.
+ */
+ Insets getMargin(Component c, Part part, State state, Prop prop) {
+- return ThemeReader.getThemeMargins(part.getControlName(c), part.getValue(),
+- State.getValue(part, state),
+- prop.getValue());
++ Insets insets = ThemeReader.getThemeMargins(part.getControlName(c), part.getValue(),
++ State.getValue(part, state),
++ prop.getValue());
++ return (insets != null) ? insets : new Insets(0, 0, 0, 0);
+ }
+
+
+@@ -505,16 +503,17 @@
+ int boundingWidth = 100;
+ int boundingHeight = 100;
+
+- return ThemeReader.getThemeBackgroundContentMargins(
++ Insets insets = ThemeReader.getThemeBackgroundContentMargins(
+ part.getControlName(null), part.getValue(),
+ 0, boundingWidth, boundingHeight);
++ return (insets != null) ? insets : new Insets(0, 0, 0, 0);
+ }
+
+ private int getWidth(State state) {
+ if (size == null) {
+ size = getPartSize(part, state);
+ }
+- return size.width;
++ return (size != null) ? size.width : 0;
+ }
+
+ int getWidth() {
+@@ -525,7 +524,7 @@
+ if (size == null) {
+ size = getPartSize(part, state);
+ }
+- return size.height;
++ return (size != null) ? size.height : 0;
+ }
+
+ int getHeight() {
+@@ -582,6 +581,9 @@
+ * @param state which state to paint
+ */
+ void paintSkin(Graphics g, int dx, int dy, int dw, int dh, State state) {
++ if (XPStyle.getXP() == null) {
++ return;
++ }
+ if (ThemeReader.isGetThemeTransitionDurationDefined()
+ && component instanceof JComponent
+ && SwingUtilities.getAncestorOfClass(CellRendererPane.class,
+@@ -607,6 +609,9 @@
+ * @param state which state to paint
+ */
+ void paintSkinRaw(Graphics g, int dx, int dy, int dw, int dh, State state) {
++ if (XPStyle.getXP() == null) {
++ return;
++ }
+ skinPainter.paint(null, g, dx, dy, dw, dh, this, state);
+ }
+
+@@ -625,6 +630,9 @@
+ */
+ void paintSkin(Graphics g, int dx, int dy, int dw, int dh, State state,
+ boolean borderFill) {
++ if (XPStyle.getXP() == null) {
++ return;
++ }
+ if(borderFill && "borderfill".equals(getTypeEnumName(component, part,
+ state, Prop.BGTYPE))) {
+ return;
+@@ -679,7 +687,7 @@
+
+ public GlyphButton(Component parent, Part part) {
+ XPStyle xp = getXP();
+- skin = xp.getSkin(parent, part);
++ skin = xp != null ? xp.getSkin(parent, part) : null;
+ setBorder(null);
+ setContentAreaFilled(false);
+ setMinimumSize(new Dimension(5, 5));
+@@ -704,13 +712,16 @@
+ }
+
+ public void paintComponent(Graphics g) {
++ if (XPStyle.getXP() == null || skin == null) {
++ return;
++ }
+ Dimension d = getSize();
+ skin.paintSkin(g, 0, 0, d.width, d.height, getState());
+ }
+
+ public void setPart(Component parent, Part part) {
+ XPStyle xp = getXP();
+- skin = xp.getSkin(parent, part);
++ skin = xp != null ? xp.getSkin(parent, part) : null;
+ revalidate();
+ repaint();
+ }
+--- ./jdk/src/share/classes/com/sun/jdi/ClassType.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/jdi/ClassType.java Wed Feb 04 12:14:43 2015 -0800
+@@ -103,7 +103,7 @@
+ * <p>
+ * Object values must be assignment compatible with the field type
+ * (This implies that the field type must be loaded through the
+- * enclosing class's class loader). Primitive values must be
++ * enclosing class' class loader). Primitive values must be
+ * either assignment compatible with the field type or must be
+ * convertible to the field type without loss of information.
+ * See JLS section 5.2 for more information on assignment
+@@ -153,7 +153,7 @@
+ * <p>
+ * Object arguments must be assignment compatible with the argument type
+ * (This implies that the argument type must be loaded through the
+- * enclosing class's class loader). Primitive arguments must be
++ * enclosing class' class loader). Primitive arguments must be
+ * either assignment compatible with the argument type or must be
+ * convertible to the argument type without loss of information.
+ * If the method being called accepts a variable number of arguments,
+@@ -216,7 +216,7 @@
+ * @return a {@link Value} mirror of the invoked method's return value.
+ * @throws java.lang.IllegalArgumentException if the method is not
+ * a member of this class or a superclass, if the size of the argument list
+- * does not match the number of declared arguemnts for the method, or
++ * does not match the number of declared arguments for the method, or
+ * if the method is an initializer, constructor or static intializer.
+ * @throws {@link InvalidTypeException} if any argument in the
+ * argument list is not assignable to the corresponding method argument
+@@ -230,7 +230,7 @@
+ * @throws InvalidTypeException If the arguments do not meet this requirement --
+ * Object arguments must be assignment compatible with the argument
+ * type. This implies that the argument type must be
+- * loaded through the enclosing class's class loader.
++ * loaded through the enclosing class' class loader.
+ * Primitive arguments must be either assignment compatible with the
+ * argument type or must be convertible to the argument type without loss
+ * of information. See JLS section 5.2 for more information on assignment
+@@ -267,7 +267,7 @@
+ * <p>
+ * Object arguments must be assignment compatible with the argument type
+ * (This implies that the argument type must be loaded through the
+- * enclosing class's class loader). Primitive arguments must be
++ * enclosing class' class loader). Primitive arguments must be
+ * either assignment compatible with the argument type or must be
+ * convertible to the argument type without loss of information.
+ * If the method being called accepts a variable number of arguments,
+@@ -335,7 +335,7 @@
+ * @throws InvalidTypeException If the arguments do not meet this requirement --
+ * Object arguments must be assignment compatible with the argument
+ * type. This implies that the argument type must be
+- * loaded through the enclosing class's class loader.
++ * loaded through the enclosing class' class loader.
+ * Primitive arguments must be either assignment compatible with the
+ * argument type or must be convertible to the argument type without loss
+ * of information. See JLS section 5.2 for more information on assignment
+--- ./jdk/src/share/classes/com/sun/jdi/InterfaceType.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/jdi/InterfaceType.java Wed Feb 04 12:14:43 2015 -0800
+@@ -79,4 +79,123 @@
+ * If none exist, returns a zero length List.
+ */
+ List<ClassType> implementors();
++
++ /**
++ * Invokes the specified static {@link Method} in the
++ * target VM. The
++ * specified method must be defined in this interface.
++ * The method must be a static method
++ * but not a static initializer.
++ * <p>
++ * The method invocation will occur in the specified thread.
++ * Method invocation can occur only if the specified thread
++ * has been suspended by an event which occurred in that thread.
++ * Method invocation is not supported
++ * when the target VM has been suspended through
++ * {@link VirtualMachine#suspend} or when the specified thread
++ * is suspended through {@link ThreadReference#suspend}.
++ * <p>
++ * The specified method is invoked with the arguments in the specified
++ * argument list. The method invocation is synchronous; this method
++ * does not return until the invoked method returns in the target VM.
++ * If the invoked method throws an exception, this method will throw
++ * an {@link InvocationException} which contains a mirror to the exception
++ * object thrown.
++ * <p>
++ * Object arguments must be assignment compatible with the argument type
++ * (This implies that the argument type must be loaded through the
++ * enclosing class' class loader). Primitive arguments must be
++ * either assignment compatible with the argument type or must be
++ * convertible to the argument type without loss of information.
++ * If the method being called accepts a variable number of arguments,
++ * then the last argument type is an array of some component type.
++ * The argument in the matching position can be omitted, or can be null,
++ * an array of the same component type, or an argument of the
++ * component type followed by any number of other arguments of the same
++ * type. If the argument is omitted, then a 0 length array of the
++ * component type is passed. The component type can be a primitive type.
++ * Autoboxing is not supported.
++ *
++ * See Section 5.2 of
++ * <cite>The Java&trade; Language Specification</cite>
++ * for more information on assignment compatibility.
++ * <p>
++ * By default, all threads in the target VM are resumed while
++ * the method is being invoked if they were previously
++ * suspended by an event or by {@link VirtualMachine#suspend} or
++ * {@link ThreadReference#suspend}. This is done to prevent the deadlocks
++ * that will occur if any of the threads own monitors
++ * that will be needed by the invoked method.
++ * Note, however, that this implicit resume acts exactly like
++ * {@link ThreadReference#resume}, so if the thread's suspend
++ * count is greater than 1, it will remain in a suspended state
++ * during the invocation and thus a deadlock could still occur.
++ * By default, when the invocation completes,
++ * all threads in the target VM are suspended, regardless their state
++ * before the invocation.
++ * It is possible that
++ * breakpoints or other events might occur during the invocation.
++ * This can cause deadlocks as described above. It can also cause a deadlock
++ * if invokeMethod is called from the client's event handler thread. In this
++ * case, this thread will be waiting for the invokeMethod to complete and
++ * won't read the EventSet that comes in for the new event. If this
++ * new EventSet is SUSPEND_ALL, then a deadlock will occur because no
++ * one will resume the EventSet. To avoid this, all EventRequests should
++ * be disabled before doing the invokeMethod, or the invokeMethod should
++ * not be done from the client's event handler thread.
++ * <p>
++ * The resumption of other threads during the invocation can be prevented
++ * by specifying the {@link #INVOKE_SINGLE_THREADED}
++ * bit flag in the <code>options</code> argument; however,
++ * there is no protection against or recovery from the deadlocks
++ * described above, so this option should be used with great caution.
++ * Only the specified thread will be resumed (as described for all
++ * threads above). Upon completion of a single threaded invoke, the invoking thread
++ * will be suspended once again. Note that any threads started during
++ * the single threaded invocation will not be suspended when the
++ * invocation completes.
++ * <p>
++ * If the target VM is disconnected during the invoke (for example, through
++ * {@link VirtualMachine#dispose}) the method invocation continues.
++ *
++ * @param thread the thread in which to invoke.
++ * @param method the {@link Method} to invoke.
++ * @param arguments the list of {@link Value} arguments bound to the
++ * invoked method. Values from the list are assigned to arguments
++ * in the order they appear in the method signature.
++ * @param options the integer bit flag options.
++ * @return a {@link Value} mirror of the invoked method's return value.
++ * @throws java.lang.IllegalArgumentException if the method is not
++ * a member of this interface, if the size of the argument list
++ * does not match the number of declared arguments for the method, or
++ * if the method is not static or is a static initializer.
++ * @throws {@link InvalidTypeException} if any argument in the
++ * argument list is not assignable to the corresponding method argument
++ * type.
++ * @throws ClassNotLoadedException if any argument type has not yet been loaded
++ * through the appropriate class loader.
++ * @throws IncompatibleThreadStateException if the specified thread has not
++ * been suspended by an event.
++ * @throws InvocationException if the method invocation resulted in
++ * an exception in the target VM.
++ * @throws InvalidTypeException If the arguments do not meet this requirement --
++ * Object arguments must be assignment compatible with the argument
++ * type. This implies that the argument type must be
++ * loaded through the enclosing class' class loader.
++ * Primitive arguments must be either assignment compatible with the
++ * argument type or must be convertible to the argument type without loss
++ * of information. See JLS section 5.2 for more information on assignment
++ * compatibility.
++ * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}.
++ *
++ * @since 1.8
++ */
++ default Value invokeMethod(ThreadReference thread, Method method,
++ List<? extends Value> arguments, int options)
++ throws InvalidTypeException,
++ ClassNotLoadedException,
++ IncompatibleThreadStateException,
++ InvocationException {
++ throw new UnsupportedOperationException();
++ }
+ }
+--- ./jdk/src/share/classes/com/sun/jdi/Method.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/jdi/Method.java Wed Feb 04 12:14:43 2015 -0800
+@@ -138,6 +138,18 @@
+ boolean isAbstract();
+
+ /**
++ * Determine if this method is a default method
++ *
++ * @return <code>true</code> if the method is declared default;
++ * false otherwise
++ *
++ * @since 1.8
++ */
++ default boolean isDefault() {
++ throw new UnsupportedOperationException();
++ }
++
++ /**
+ * Determine if this method is synchronized.
+ *
+ * @return <code>true</code> if the method is declared synchronized;
+--- ./jdk/src/share/classes/com/sun/jdi/ObjectReference.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/jdi/ObjectReference.java Wed Feb 04 12:14:43 2015 -0800
+@@ -194,10 +194,10 @@
+ * {@link #INVOKE_NONVIRTUAL} bit flag in the <code>options</code>
+ * argument. If this flag is set, the specified method is invoked
+ * whether or not it is overridden for this object's runtime type.
+- * The method, in this case, must not belong to an interface and
+- * must not be abstract. This option is useful for performing method
+- * invocations like those done with the <code>super</code> keyword in
+- * the Java programming language.
++ * The method, in this case, must have an implementation, either in a class
++ * or an interface. This option is useful for performing method invocations
++ * like those done with the <code>super</code> keyword in the Java programming
++ * language.
+ * <p>
+ * By default, all threads in the target VM are resumed while
+ * the method is being invoked if they were previously
+@@ -246,10 +246,10 @@
+ * @return a {@link Value} mirror of the invoked method's return value.
+ * @throws java.lang.IllegalArgumentException if the method is not
+ * a member of this object's class, if the size of the argument list
+- * does not match the number of declared arguemnts for the method,
++ * does not match the number of declared arguments for the method,
+ * if the method is a constructor or static intializer, or
+ * if {@link #INVOKE_NONVIRTUAL} is specified and the method is
+- * either abstract or an interface member.
++ * either abstract or a non-default interface member.
+ * @throws {@link InvalidTypeException} if any argument in the
+ * argument list is not assignable to the corresponding method argument
+ * type.
+--- ./jdk/src/share/classes/com/sun/jndi/ldap/Connection.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/jndi/ldap/Connection.java Wed Feb 04 12:14:43 2015 -0800
+@@ -459,10 +459,13 @@
+ // will be woken up before readTimeout only if reply is
+ // available
+ ldr.wait(readTimeout);
++ waited = true;
+ } else {
+- ldr.wait(15 * 1000); // 15 second timeout
++ // no timeout is set so we wait infinitely until
++ // a response is received
++ // https://docs.oracle.com/javase/8/docs/technotes/guides/jndi/jndi-ldap.html#PROP
++ ldr.wait();
+ }
+- waited = true;
+ } else {
+ break;
+ }
+--- ./jdk/src/share/classes/com/sun/media/sound/JDK13Services.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/media/sound/JDK13Services.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -25,6 +25,8 @@
+
+ package com.sun.media.sound;
+
++import java.security.AccessController;
++import java.security.PrivilegedAction;
+ import java.util.ArrayList;
+ import java.util.Collections;
+ import java.util.List;
+@@ -176,11 +178,11 @@
+ && !Sequencer.class.equals(typeClass)) {
+ return null;
+ }
+- String value;
+- String propertyName = typeClass.getName();
+- value = JSSecurityManager.getProperty(propertyName);
++ String name = typeClass.getName();
++ String value = AccessController.doPrivileged(
++ (PrivilegedAction<String>) () -> System.getProperty(name));
+ if (value == null) {
+- value = getProperties().getProperty(propertyName);
++ value = getProperties().getProperty(name);
+ }
+ if ("".equals(value)) {
+ value = null;
+--- ./jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -73,33 +73,6 @@
+ }
+ }
+
+- static String getProperty(final String propertyName) {
+- String propertyValue;
+- if (hasSecurityManager()) {
+- if(Printer.debug) Printer.debug("using JDK 1.2 security to get property");
+- try{
+- PrivilegedAction<String> action = new PrivilegedAction<String>() {
+- public String run() {
+- try {
+- return System.getProperty(propertyName);
+- } catch (Throwable t) {
+- return null;
+- }
+- }
+- };
+- propertyValue = AccessController.doPrivileged(action);
+- } catch( Exception e ) {
+- if(Printer.debug) Printer.debug("not using JDK 1.2 security to get properties");
+- propertyValue = System.getProperty(propertyName);
+- }
+- } else {
+- if(Printer.debug) Printer.debug("not using JDK 1.2 security to get properties");
+- propertyValue = System.getProperty(propertyName);
+- }
+- return propertyValue;
+- }
+-
+-
+ /** Load properties from a file.
+ This method tries to load properties from the filename give into
+ the passed properties object.
+--- ./jdk/src/share/classes/com/sun/media/sound/Platform.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/media/sound/Platform.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -74,17 +74,6 @@
+ // intel is little-endian. sparc is big-endian.
+ private static boolean bigEndian;
+
+- // this is the value of the "java.home" system property. i am looking it up here
+- // for use when trying to load the soundbank, just so
+- // that all the privileged code is localized in this file....
+- private static String javahome;
+-
+- // this is the value of the "java.class.path" system property
+- private static String classpath;
+-
+-
+-
+-
+ static {
+ if(Printer.trace)Printer.trace(">> Platform.java: static");
+
+@@ -129,26 +118,6 @@
+ return signed8;
+ }
+
+-
+- /**
+- * Obtain javahome.
+- * $$kk: 04.16.99: this is *bad*!!
+- */
+- static String getJavahome() {
+-
+- return javahome;
+- }
+-
+- /**
+- * Obtain classpath.
+- * $$jb: 04.21.99: this is *bad* too!!
+- */
+- static String getClasspath() {
+-
+- return classpath;
+- }
+-
+-
+ // PRIVATE METHODS
+
+ /**
+@@ -157,21 +126,13 @@
+ private static void loadLibraries() {
+ if(Printer.trace)Printer.trace(">>Platform.loadLibraries");
+
+- try {
+- // load the main library
+- AccessController.doPrivileged(new PrivilegedAction<Void>() {
+- @Override
+- public Void run() {
+- System.loadLibrary(libNameMain);
+- return null;
+- }
+- });
+- // just for the heck of it...
+- loadedLibs |= LIB_MAIN;
+- } catch (SecurityException e) {
+- if(Printer.err)Printer.err("Security exception loading main native library. JavaSound requires access to these resources.");
+- throw(e);
+- }
++ // load the main library
++ AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
++ System.loadLibrary(libNameMain);
++ return null;
++ });
++ // just for the heck of it...
++ loadedLibs |= LIB_MAIN;
+
+ // now try to load extra libs. They are defined at compile time in the Makefile
+ // with the define EXTRA_SOUND_JNI_LIBS
+@@ -181,12 +142,9 @@
+ while (st.hasMoreTokens()) {
+ final String lib = st.nextToken();
+ try {
+- AccessController.doPrivileged(new PrivilegedAction<Void>() {
+- @Override
+- public Void run() {
+- System.loadLibrary(lib);
+- return null;
+- }
++ AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
++ System.loadLibrary(lib);
++ return null;
+ });
+
+ if (lib.equals(libNameALSA)) {
+@@ -239,7 +197,5 @@
+ // $$fb 2002-03-06: implement check for endianness in native. Facilitates porting !
+ bigEndian = nIsBigEndian();
+ signed8 = nIsSigned8(); // Solaris on Sparc: signed, all others unsigned
+- javahome = JSSecurityManager.getProperty("java.home");
+- classpath = JSSecurityManager.getProperty("java.class.path");
+ }
+ }
+--- ./jdk/src/share/classes/com/sun/media/sound/RIFFReader.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/media/sound/RIFFReader.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -39,21 +39,20 @@
+ private long filepointer = 0;
+ private final String fourcc;
+ private String riff_type = null;
+- private long ckSize = 0;
++ private long ckSize = Integer.MAX_VALUE;
+ private InputStream stream;
+- private long avail;
++ private long avail = Integer.MAX_VALUE;
+ private RIFFReader lastiterator = null;
+
+ public RIFFReader(InputStream stream) throws IOException {
+
+- if (stream instanceof RIFFReader)
+- root = ((RIFFReader)stream).root;
+- else
++ if (stream instanceof RIFFReader) {
++ root = ((RIFFReader) stream).root;
++ } else {
+ root = this;
++ }
+
+ this.stream = stream;
+- avail = Integer.MAX_VALUE;
+- ckSize = Integer.MAX_VALUE;
+
+ // Check for RIFF null paddings,
+ int b;
+@@ -76,10 +75,12 @@
+ readFully(fourcc, 1, 3);
+ this.fourcc = new String(fourcc, "ascii");
+ ckSize = readUnsignedInt();
+-
+- avail = this.ckSize;
++ avail = ckSize;
+
+ if (getFormat().equals("RIFF") || getFormat().equals("LIST")) {
++ if (avail > Integer.MAX_VALUE) {
++ throw new RIFFInvalidDataException("Chunk size too big");
++ }
+ byte[] format = new byte[4];
+ readFully(format);
+ this.riff_type = new String(format, "ascii");
+@@ -118,19 +119,23 @@
+ }
+
+ public int read() throws IOException {
+- if (avail == 0)
++ if (avail == 0) {
+ return -1;
++ }
+ int b = stream.read();
+- if (b == -1)
++ if (b == -1) {
++ avail = 0;
+ return -1;
++ }
+ avail--;
+ filepointer++;
+ return b;
+ }
+
+ public int read(byte[] b, int offset, int len) throws IOException {
+- if (avail == 0)
++ if (avail == 0) {
+ return -1;
++ }
+ if (len > avail) {
+ int rlen = stream.read(b, offset, (int)avail);
+ if (rlen != -1)
+@@ -139,8 +144,10 @@
+ return rlen;
+ } else {
+ int ret = stream.read(b, offset, len);
+- if (ret == -1)
++ if (ret == -1) {
++ avail = 0;
+ return -1;
++ }
+ avail -= ret;
+ filepointer += ret;
+ return ret;
+@@ -191,8 +198,10 @@
+ return len;
+ } else {
+ long ret = stream.skip(n);
+- if (ret == -1)
++ if (ret == -1) {
++ avail = 0;
+ return -1;
++ }
+ avail -= ret;
+ filepointer += ret;
+ return ret;
+@@ -210,8 +219,13 @@
+ }
+
+ // Read ASCII chars from stream
+- public String readString(int len) throws IOException {
+- byte[] buff = new byte[len];
++ public String readString(final int len) throws IOException {
++ final byte[] buff;
++ try {
++ buff = new byte[len];
++ } catch (final OutOfMemoryError oom) {
++ throw new IOException("Length too big", oom);
++ }
+ readFully(buff);
+ for (int i = 0; i < buff.length; i++) {
+ if (buff[i] == 0) {
+--- ./jdk/src/share/classes/com/sun/media/sound/SF2Soundbank.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/media/sound/SF2Soundbank.java Wed Feb 04 12:14:43 2015 -0800
+@@ -276,6 +276,9 @@
+ count--;
+ }
+
++ if (presets_bagNdx.isEmpty()) {
++ throw new RIFFInvalidDataException();
++ }
+ int offset = presets_bagNdx.get(0);
+ // Offset should be 0 (but just case)
+ for (int i = 0; i < offset; i++) {
+@@ -360,6 +363,9 @@
+ count--;
+ }
+
++ if (instruments_bagNdx.isEmpty()) {
++ throw new RIFFInvalidDataException();
++ }
+ int offset = instruments_bagNdx.get(0);
+ // Offset should be 0 (but just case)
+ for (int i = 0; i < offset; i++) {
+@@ -401,6 +407,9 @@
+ modulator.amount = chunk.readShort();
+ modulator.amountSourceOperator = chunk.readUnsignedShort();
+ modulator.transportOperator = chunk.readUnsignedShort();
++ if (i < 0 || i >= instruments_splits_gen.size()) {
++ throw new RIFFInvalidDataException();
++ }
+ SF2LayerRegion split = instruments_splits_gen.get(i);
+ if (split != null)
+ split.modulators.add(modulator);
+@@ -424,7 +433,8 @@
+ sample.name = chunk.readString(20);
+ long start = chunk.readUnsignedInt();
+ long end = chunk.readUnsignedInt();
+- sample.data = sampleData.subbuffer(start * 2, end * 2, true);
++ if (sampleData != null)
++ sample.data = sampleData.subbuffer(start * 2, end * 2, true);
+ if (sampleData24 != null)
+ sample.data24 = sampleData24.subbuffer(start, end, true);
+ /*
+@@ -462,6 +472,9 @@
+ int sampleid = split.generators.get(
+ SF2LayerRegion.GENERATOR_SAMPLEID);
+ split.generators.remove(SF2LayerRegion.GENERATOR_SAMPLEID);
++ if (sampleid < 0 || sampleid >= samples.size()) {
++ throw new RIFFInvalidDataException();
++ }
+ split.sample = samples.get(sampleid);
+ } else {
+ globalsplit = split;
+@@ -488,6 +501,9 @@
+ int instrumentid = split.generators.get(
+ SF2InstrumentRegion.GENERATOR_INSTRUMENT);
+ split.generators.remove(SF2LayerRegion.GENERATOR_INSTRUMENT);
++ if (instrumentid < 0 || instrumentid >= layers.size()) {
++ throw new RIFFInvalidDataException();
++ }
+ split.layer = layers.get(instrumentid);
+ } else {
+ globalsplit = split;
+--- ./jdk/src/share/classes/com/sun/media/sound/SoftMidiAudioFileReader.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/media/sound/SoftMidiAudioFileReader.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -22,6 +22,7 @@
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
++
+ package com.sun.media.sound;
+
+ import java.io.File;
+@@ -39,14 +40,14 @@
+ import javax.sound.midi.Sequence;
+ import javax.sound.midi.Track;
+ import javax.sound.sampled.AudioFileFormat;
++import javax.sound.sampled.AudioFileFormat.Type;
+ import javax.sound.sampled.AudioFormat;
+ import javax.sound.sampled.AudioInputStream;
+ import javax.sound.sampled.UnsupportedAudioFileException;
+-import javax.sound.sampled.AudioFileFormat.Type;
+ import javax.sound.sampled.spi.AudioFileReader;
+
+ /**
+- * MIDI File Audio Renderer/Reader
++ * MIDI File Audio Renderer/Reader.
+ *
+ * @author Karl Helgason
+ */
+@@ -109,6 +110,9 @@
+ if (divtype == Sequence.PPQ) {
+ if (((MetaMessage) msg).getType() == 0x51) {
+ byte[] data = ((MetaMessage) msg).getData();
++ if (data.length < 3) {
++ throw new UnsupportedAudioFileException();
++ }
+ mpq = ((data[0] & 0xff) << 16)
+ | ((data[1] & 0xff) << 8) | (data[2] & 0xff);
+ }
+--- ./jdk/src/share/classes/com/sun/media/sound/SoftSynthesizer.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/media/sound/SoftSynthesizer.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -28,6 +28,7 @@
+ import java.io.BufferedInputStream;
+ import java.io.File;
+ import java.io.FileInputStream;
++import java.io.FileNotFoundException;
+ import java.io.FileOutputStream;
+ import java.io.IOException;
+ import java.io.InputStream;
+@@ -732,31 +733,28 @@
+ * Save generated soundbank to disk for faster future use.
+ */
+ OutputStream out = AccessController
+- .doPrivileged(new PrivilegedAction<OutputStream>() {
+- public OutputStream run() {
+- try {
+- File userhome = new File(System
+- .getProperty("user.home"),
+- ".gervill");
+- if (!userhome.exists())
+- userhome.mkdirs();
+- File emg_soundbank_file = new File(
+- userhome, "soundbank-emg.sf2");
+- if (emg_soundbank_file.exists())
+- return null;
+- return new FileOutputStream(
+- emg_soundbank_file);
+- } catch (IOException e) {
+- } catch (SecurityException e) {
++ .doPrivileged((PrivilegedAction<OutputStream>) () -> {
++ try {
++ File userhome = new File(System
++ .getProperty("user.home"), ".gervill");
++ if (!userhome.exists()) {
++ userhome.mkdirs();
+ }
+- return null;
++ File emg_soundbank_file = new File(
++ userhome, "soundbank-emg.sf2");
++ if (emg_soundbank_file.exists()) {
++ return null;
++ }
++ return new FileOutputStream(emg_soundbank_file);
++ } catch (final FileNotFoundException ignored) {
+ }
++ return null;
+ });
+ if (out != null) {
+ try {
+ ((SF2Soundbank) defaultSoundBank).save(out);
+ out.close();
+- } catch (IOException e) {
++ } catch (final IOException ignored) {
+ }
+ }
+ }
+@@ -846,26 +844,24 @@
+
+ private Properties getStoredProperties() {
+ return AccessController
+- .doPrivileged(new PrivilegedAction<Properties>() {
+- public Properties run() {
+- Properties p = new Properties();
+- String notePath = "/com/sun/media/sound/softsynthesizer";
+- try {
+- Preferences prefroot = Preferences.userRoot();
+- if (prefroot.nodeExists(notePath)) {
+- Preferences prefs = prefroot.node(notePath);
+- String[] prefs_keys = prefs.keys();
+- for (String prefs_key : prefs_keys) {
+- String val = prefs.get(prefs_key, null);
+- if (val != null)
+- p.setProperty(prefs_key, val);
++ .doPrivileged((PrivilegedAction<Properties>) () -> {
++ Properties p = new Properties();
++ String notePath = "/com/sun/media/sound/softsynthesizer";
++ try {
++ Preferences prefroot = Preferences.userRoot();
++ if (prefroot.nodeExists(notePath)) {
++ Preferences prefs = prefroot.node(notePath);
++ String[] prefs_keys = prefs.keys();
++ for (String prefs_key : prefs_keys) {
++ String val = prefs.get(prefs_key, null);
++ if (val != null) {
++ p.setProperty(prefs_key, val);
+ }
+ }
+- } catch (BackingStoreException e) {
+- } catch (SecurityException e) {
+ }
+- return p;
++ } catch (final BackingStoreException ignored) {
+ }
++ return p;
+ });
+ }
+
+@@ -1044,7 +1040,6 @@
+ return;
+ }
+ synchronized (control_mutex) {
+- Throwable causeException = null;
+ try {
+ if (line != null) {
+ // can throw IllegalArgumentException
+@@ -1117,24 +1112,17 @@
+ weakstream.sourceDataLine = sourceDataLine;
+ }
+
+- } catch (LineUnavailableException e) {
+- causeException = e;
+- } catch (IllegalArgumentException e) {
+- causeException = e;
+- } catch (SecurityException e) {
+- causeException = e;
+- }
+-
+- if (causeException != null) {
+- if (isOpen())
++ } catch (final LineUnavailableException | SecurityException
++ | IllegalArgumentException e) {
++ if (isOpen()) {
+ close();
++ }
+ // am: need MidiUnavailableException(Throwable) ctor!
+ MidiUnavailableException ex = new MidiUnavailableException(
+ "Can not open line");
+- ex.initCause(causeException);
++ ex.initCause(e);
+ throw ex;
+ }
+-
+ }
+ }
+
+--- ./jdk/src/share/classes/com/sun/media/sound/StandardMidiFileReader.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/media/sound/StandardMidiFileReader.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -25,27 +25,25 @@
+
+ package com.sun.media.sound;
+
++import java.io.BufferedInputStream;
+ import java.io.DataInputStream;
++import java.io.EOFException;
+ import java.io.File;
+ import java.io.FileInputStream;
++import java.io.IOException;
+ import java.io.InputStream;
+-import java.io.IOException;
+-import java.io.EOFException;
+-import java.io.BufferedInputStream;
+ import java.net.URL;
+
+-import javax.sound.midi.MidiFileFormat;
+ import javax.sound.midi.InvalidMidiDataException;
+ import javax.sound.midi.MetaMessage;
+ import javax.sound.midi.MidiEvent;
++import javax.sound.midi.MidiFileFormat;
+ import javax.sound.midi.MidiMessage;
+ import javax.sound.midi.Sequence;
+ import javax.sound.midi.SysexMessage;
+ import javax.sound.midi.Track;
+ import javax.sound.midi.spi.MidiFileReader;
+
+-
+-
+ /**
+ * MIDI file reader.
+ *
+@@ -53,19 +51,23 @@
+ * @author Jan Borgersen
+ * @author Florian Bomers
+ */
+-
+ public final class StandardMidiFileReader extends MidiFileReader {
+
+ private static final int MThd_MAGIC = 0x4d546864; // 'MThd'
+
+ private static final int bisBufferSize = 1024; // buffer size in buffered input streams
+
+- public MidiFileFormat getMidiFileFormat(InputStream stream) throws InvalidMidiDataException, IOException {
++ public MidiFileFormat getMidiFileFormat(InputStream stream)
++ throws InvalidMidiDataException, IOException {
+ return getMidiFileFormatFromStream(stream, MidiFileFormat.UNKNOWN_LENGTH, null);
+ }
+
+- // $$fb 2002-04-17: part of fix for 4635286: MidiSystem.getMidiFileFormat() returns format having invalid length
+- private MidiFileFormat getMidiFileFormatFromStream(InputStream stream, int fileLength, SMFParser smfParser) throws InvalidMidiDataException, IOException {
++ // $$fb 2002-04-17: part of fix for 4635286: MidiSystem.getMidiFileFormat()
++ // returns format having invalid length
++ private MidiFileFormat getMidiFileFormatFromStream(InputStream stream,
++ int fileLength,
++ SMFParser smfParser)
++ throws InvalidMidiDataException, IOException{
+ int maxReadLength = 16;
+ int duration = MidiFileFormat.UNKNOWN_LENGTH;
+ DataInputStream dis;
+@@ -230,7 +232,7 @@
+ //=============================================================================================================
+
+ /**
+- * State variables during parsing of a MIDI file
++ * State variables during parsing of a MIDI file.
+ */
+ final class SMFParser {
+ private static final int MTrk_MAGIC = 0x4d54726b; // 'MTrk'
+@@ -297,7 +299,11 @@
+ }
+ }
+ // now read track in a byte array
+- trackData = new byte[trackLength];
++ try {
++ trackData = new byte[trackLength];
++ } catch (final OutOfMemoryError oom) {
++ throw new IOException("Track length too big", oom);
++ }
+ try {
+ // $$fb 2003-08-20: fix for 4910986: MIDI file parser breaks up on http connection
+ stream.readFully(trackData);
+@@ -386,8 +392,13 @@
+ // meta
+ int metaType = readUnsigned();
+ int metaLength = (int) readVarInt();
++ final byte[] metaData;
++ try {
++ metaData = new byte[metaLength];
++ } catch (final OutOfMemoryError oom) {
++ throw new IOException("Meta length too big", oom);
++ }
+
+- byte[] metaData = new byte[metaLength];
+ read(metaData);
+
+ MetaMessage metaMessage = new MetaMessage();
+@@ -413,5 +424,4 @@
+ throw new EOFException("invalid MIDI file");
+ }
+ }
+-
+ }
+--- ./jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -35,7 +35,7 @@
+ /**
+ * Handles SubjectKeyIdentifier (SKI) for X.509v3.
+ *
+- * @see <A HREF="http://docs.oracle.com/javase/1.5.0/docs/api/java/security/cert/X509Extension.html">
++ * @see <A HREF="https://docs.oracle.com/javase/1.5.0/docs/api/java/security/cert/X509Extension.html">
+ * Interface X509Extension</A>
+ */
+ public class XMLX509SKI extends SignatureElementProxy implements XMLX509DataContent {
+--- ./jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java Wed Feb 04 12:14:43 2015 -0800
+@@ -56,7 +56,7 @@
+ * </PRE>
+ *
+ * @see <A HREF="http://www.javaworld.com/javaworld/javatips/jw-javatip42_p.html">Java Tip 42: Write Java apps that work with proxy-based firewalls</A>
+- * @see <A HREF="http://docs.oracle.com/javase/1.4.2/docs/guide/net/properties.html">SUN J2SE docs for network properties</A>
++ * @see <A HREF="https://docs.oracle.com/javase/1.4.2/docs/guide/net/properties.html">SUN J2SE docs for network properties</A>
+ * @see <A HREF="http://metalab.unc.edu/javafaq/javafaq.html#proxy">The JAVA FAQ Question 9.5: How do I make Java work with a proxy server?</A>
+ */
+ public class ResolverDirectHTTP extends ResourceResolverSpi {
+--- ./jdk/src/share/classes/com/sun/security/ntlm/Client.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/security/ntlm/Client.java Wed Feb 04 12:14:43 2015 -0800
+@@ -46,7 +46,7 @@
+ final private String hostname;
+ final private String username;
+
+- private String domain; // might be updated by Type 2 msg
++ private String domain;
+ private byte[] pw1, pw2;
+
+ /**
+@@ -82,7 +82,7 @@
+ }
+ this.hostname = hostname;
+ this.username = username;
+- this.domain = domain;
++ this.domain = domain == null ? "" : domain;
+ this.pw1 = getP1(password);
+ this.pw2 = getP2(password);
+ debug("NTLM Client: (h,u,t,version(v)) = (%s,%s,%s,%s(%s))\n",
+@@ -95,19 +95,13 @@
+ */
+ public byte[] type1() {
+ Writer p = new Writer(1, 32);
+- int flags = 0x8203;
+- if (hostname != null) {
+- flags |= 0x2000;
+- }
+- if (domain != null) {
+- flags |= 0x1000;
+- }
++ // Negotiate always sign, Negotiate NTLM,
++ // Request Target, Negotiate OEM, Negotiate unicode
++ int flags = 0x8207;
+ if (v != Version.NTLM) {
+ flags |= 0x80000;
+ }
+ p.writeInt(12, flags);
+- p.writeSecurityBuffer(24, hostname, false);
+- p.writeSecurityBuffer(16, domain, false);
+ debug("NTLM Client: Type 1 created\n");
+ debug(p.getBytes());
+ return p.getBytes();
+@@ -133,13 +127,10 @@
+ byte[] challenge = r.readBytes(24, 8);
+ int inputFlags = r.readInt(20);
+ boolean unicode = (inputFlags & 1) == 1;
+- String domainFromServer = r.readSecurityBuffer(12, unicode);
+- if (domainFromServer != null) {
+- domain = domainFromServer;
+- }
+- if (domain == null) {
+- domain = "";
+- }
++
++ // IE uses domainFromServer to generate an alist if server has not
++ // provided one. Firefox/WebKit do not. Neither do we.
++ //String domainFromServer = r.readSecurityBuffer(12, unicode);
+
+ int flags = 0x88200 | (inputFlags & 3);
+ Writer p = new Writer(3, 64);
+@@ -163,7 +154,9 @@
+ if (writeLM) lm = calcV2(nthash,
+ username.toUpperCase(Locale.US)+domain, nonce, challenge);
+ if (writeNTLM) {
+- byte[] alist = type2.length > 48 ?
++ // Some client create a alist even if server does not send
++ // one: (i16)2 (i16)len target_in_unicode (i16)0 (i16) 0
++ byte[] alist = ((inputFlags & 0x800000) != 0) ?
+ r.readSecurityBuffer(40) : new byte[0];
+ byte[] blob = new byte[32+alist.length];
+ System.arraycopy(new byte[]{1,1,0,0,0,0,0,0}, 0, blob, 0, 8);
+--- ./jdk/src/share/classes/com/sun/security/ntlm/Server.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/security/ntlm/Server.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,3 +1,4 @@
++
+ /*
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -92,7 +93,9 @@
+ debug("NTLM Server: Type 1 received\n");
+ if (type1 != null) debug(type1);
+ Writer p = new Writer(2, 32);
+- int flags = 0x80205;
++ // Negotiate NTLM2 Key, Target Type Domain,
++ // Negotiate NTLM, Request Target, Negotiate unicode
++ int flags = 0x90205;
+ p.writeSecurityBuffer(12, domain, true);
+ p.writeInt(20, flags);
+ p.writeBytes(24, nonce);
+@@ -127,8 +130,9 @@
+ "Wrong domain: " + incomingDomain +
+ " vs " + domain); // Needed?
+ }*/
++
+ boolean verified = false;
+- char[] password = getPassword(domain, username);
++ char[] password = getPassword(incomingDomain, username);
+ if (password == null) {
+ throw new NTLMException(NTLMException.USER_UNKNOWN,
+ "Unknown user");
+@@ -179,6 +183,8 @@
+ }
+ }
+ if (incomingNTLM.length > 0) {
++ // We didn't sent alist in type2(), so there
++ // is nothing to check here.
+ byte[] clientBlob = Arrays.copyOfRange(
+ incomingNTLM, 16, incomingNTLM.length);
+ byte[] ntlmresponse = calcV2(nthash,
+--- ./jdk/src/share/classes/com/sun/security/sasl/ntlm/NTLMClient.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/security/sasl/ntlm/NTLMClient.java Wed Feb 04 12:14:43 2015 -0800
+@@ -160,9 +160,17 @@
+ }
+ }
+ try {
++ String name = ncb.getName();
++ if (name == null) {
++ name = authzid;
++ }
++ String domain = dcb.getText();
++ if (domain == null) {
++ domain = serverName;
++ }
+ client = new Client(version, hostname,
+- ncb.getName(),
+- dcb.getText(),
++ name,
++ domain,
+ pcb.getPassword());
+ } catch (NTLMException ne) {
+ throw new SaslException(
+--- ./jdk/src/share/classes/com/sun/security/sasl/ntlm/NTLMServer.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/security/sasl/ntlm/NTLMServer.java Wed Feb 04 12:14:43 2015 -0800
+@@ -141,8 +141,10 @@
+ server = new Server(version, domain) {
+ public char[] getPassword(String ntdomain, String username) {
+ try {
+- RealmCallback rcb = new RealmCallback(
+- "Domain: ", ntdomain);
++ RealmCallback rcb =
++ (ntdomain == null || ntdomain.isEmpty())
++ ? new RealmCallback("Domain: ")
++ : new RealmCallback("Domain: ", ntdomain);
+ NameCallback ncb = new NameCallback(
+ "Name: ", username);
+ PasswordCallback pcb = new PasswordCallback(
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/src/share/classes/com/sun/tools/attach/AttachOperationFailedException.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.tools.attach;
++
++import java.io.IOException;
++
++/**
++ * Exception type to signal that an attach operation failed in the target VM.
++ *
++ * <p> This exception can be thrown by the various operations of
++ * {@link com.sun.tools.attach.VirtualMachine} when the operation
++ * fails in the target VM. If there is a communication error,
++ * a regular IOException will be thrown.
++ *
++ * @since 1.9
++ */
++@jdk.Exported
++public class AttachOperationFailedException extends IOException {
++
++ private static final long serialVersionUID = 2140308168167478043L;
++
++ /**
++ * Constructs an <code>AttachOperationFailedException</code> with
++ * the specified detail message.
++ *
++ * @param s the detail message.
++ */
++ public AttachOperationFailedException(String message) {
++ super(message);
++ }
++}
+--- ./jdk/src/share/classes/com/sun/tools/attach/VirtualMachine.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/tools/attach/VirtualMachine.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -76,16 +76,10 @@
+ * // attach to target VM
+ * VirtualMachine vm = VirtualMachine.attach("2177");
+ *
+- * // get system properties in target VM
+- * Properties props = vm.getSystemProperties();
+- *
+- * // construct path to management agent
+- * String home = props.getProperty("java.home");
+- * String agent = home + File.separator + "lib" + File.separator
+- * + "management-agent.jar";
+- *
+- * // load agent into target VM
+- * vm.loadAgent(agent, "com.sun.management.jmxremote.port=5000");
++ * // start management agent
++ * Properties props = new Properties();
++ * props.put("com.sun.management.jmxremote.port", "5000");
++ * vm.startManagementAgent(props);
+ *
+ * // detach
+ * vm.detach();
+@@ -93,9 +87,9 @@
+ * </pre>
+ *
+ * <p> In this example we attach to a Java virtual machine that is identified by
+- * the process identifier <code>2177</code>. The system properties from the target
+- * VM are then used to construct the path to a <i>management agent</i> which is then
+- * loaded into the target VM. Once loaded the client detaches from the target VM. </p>
++ * the process identifier <code>2177</code>. Then the JMX management agent is
++ * started in the target process using the supplied arguments. Finally, the
++ * client detaches from the target VM. </p>
+ *
+ * <p> A VirtualMachine is safe for use by multiple concurrent threads. </p>
+ *
+@@ -564,8 +558,15 @@
+ *
+ * @return The system properties
+ *
++ * @throws AttachOperationFailedException
++ * If the target virtual machine is unable to complete the
++ * attach operation. A more specific error message will be
++ * given by {@link AttachOperationFailedException#getMessage()}.
++ *
+ * @throws IOException
+- * If an I/O error occurs
++ * If an I/O error occurs, a communication error for example,
++ * that cannot be identified as an error to indicate that the
++ * operation failed in the target VM.
+ *
+ * @see java.lang.System#getProperties
+ * @see #loadAgentLibrary
+@@ -591,12 +592,81 @@
+ *
+ * @return The agent properties
+ *
++ * @throws AttachOperationFailedException
++ * If the target virtual machine is unable to complete the
++ * attach operation. A more specific error message will be
++ * given by {@link AttachOperationFailedException#getMessage()}.
++ *
+ * @throws IOException
+- * If an I/O error occurs
++ * If an I/O error occurs, a communication error for example,
++ * that cannot be identified as an error to indicate that the
++ * operation failed in the target VM.
+ */
+ public abstract Properties getAgentProperties() throws IOException;
+
+ /**
++ * Starts the JMX management agent in the target virtual machine.
++ *
++ * <p> The configuration properties are the same as those specified on
++ * the command line when starting the JMX management agent. In the same
++ * way as on the command line, you need to specify at least the
++ * {@code com.sun.management.jmxremote.port} property.
++ *
++ * <p> See the online documentation for <a
++ * href="../../../../../../../../technotes/guides/management/agent.html">
++ * Monitoring and Management Using JMX Technology</a> for further details.
++ *
++ * @param agentProperties
++ * A Properties object containing the configuration properties
++ * for the agent.
++ *
++ * @throws AttachOperationFailedException
++ * If the target virtual machine is unable to complete the
++ * attach operation. A more specific error message will be
++ * given by {@link AttachOperationFailedException#getMessage()}.
++ *
++ * @throws IOException
++ * If an I/O error occurs, a communication error for example,
++ * that cannot be identified as an error to indicate that the
++ * operation failed in the target VM.
++ *
++ * @throws IllegalArgumentException
++ * If keys or values in agentProperties are invalid.
++ *
++ * @throws NullPointerException
++ * If agentProperties is null.
++ *
++ * @since 1.8
++ */
++ public abstract void startManagementAgent(Properties agentProperties) throws IOException;
++
++ /**
++ * Starts the local JMX management agent in the target virtual machine.
++ *
++ * <p> See the online documentation for <a
++ * href="../../../../../../../../technotes/guides/management/agent.html">
++ * Monitoring and Management Using JMX Technology</a> for further details.
++ *
++ * @return The String representation of the local connector's service address.
++ * The value can be parsed by the
++ * {@link javax.management.remote.JMXServiceURL#JMXServiceURL(String)}
++ * constructor.
++ *
++ * @throws AttachOperationFailedException
++ * If the target virtual machine is unable to complete the
++ * attach operation. A more specific error message will be
++ * given by {@link AttachOperationFailedException#getMessage()}.
++ *
++ * @throws IOException
++ * If an I/O error occurs, a communication error for example,
++ * that cannot be identified as an error to indicate that the
++ * operation failed in the target VM.
++ *
++ * @since 1.8
++ */
++ public abstract String startLocalManagementAgent() throws IOException;
++
++ /**
+ * Returns a hash-code value for this VirtualMachine. The hash
+ * code is based upon the VirtualMachine's components, and satifies
+ * the general contract of the {@link java.lang.Object#hashCode()
+--- ./jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java Wed Feb 04 12:14:43 2015 -0800
+@@ -559,6 +559,9 @@
+ } else if (refType instanceof ClassType) {
+ ClassType clazz = (ClassType)refType;
+ return jdiValue = clazz.invokeMethod(thread, matchingMethod, methodArguments, 0);
++ } else if (refType instanceof InterfaceType) {
++ InterfaceType iface = (InterfaceType)refType;
++ return jdiValue = iface.invokeMethod(thread, matchingMethod, methodArguments, 0);
+ } else {
+ throw new InvalidTypeException("Cannot invoke static method on " +
+ refType.name());
+--- ./jdk/src/share/classes/com/sun/tools/jdi/ArrayTypeImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/tools/jdi/ArrayTypeImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -31,6 +31,7 @@
+ import java.util.ArrayList;
+ import java.util.Iterator;
+ import java.util.Map;
++import java.util.Set;
+
+ public class ArrayTypeImpl extends ReferenceTypeImpl
+ implements ArrayType
+@@ -61,7 +62,8 @@
+ return findType(componentSignature());
+ }
+
+- void addVisibleMethods(Map<String, Method> map) {
++ @Override
++ void addVisibleMethods(Map<String, Method> map, Set<InterfaceType> seenInterfaces) {
+ // arrays don't have methods
+ }
+
+--- ./jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -29,9 +29,27 @@
+
+ import java.util.*;
+
+-public class ClassTypeImpl extends ReferenceTypeImpl
++final public class ClassTypeImpl extends InvokableTypeImpl
+ implements ClassType
+ {
++ private static class IResult implements InvocationResult {
++ final private JDWP.ClassType.InvokeMethod rslt;
++
++ public IResult(JDWP.ClassType.InvokeMethod rslt) {
++ this.rslt = rslt;
++ }
++
++ @Override
++ public ObjectReferenceImpl getException() {
++ return rslt.exception;
++ }
++
++ @Override
++ public ValueImpl getResult() {
++ return rslt.returnValue;
++ }
++ }
++
+ private boolean cachedSuperclass = false;
+ private ClassType superclass = null;
+ private int lastLine = -1;
+@@ -65,6 +83,7 @@
+ return superclass;
+ }
+
++ @Override
+ public List<InterfaceType> interfaces() {
+ if (interfaces == null) {
+ interfaces = getInterfaces();
+@@ -72,26 +91,9 @@
+ return interfaces;
+ }
+
+- void addInterfaces(List<InterfaceType> list) {
+- List<InterfaceType> immediate = interfaces();
+- list.addAll(interfaces());
+-
+- Iterator<InterfaceType> iter = immediate.iterator();
+- while (iter.hasNext()) {
+- InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
+- interfaze.addSuperinterfaces(list);
+- }
+-
+- ClassTypeImpl superclass = (ClassTypeImpl)superclass();
+- if (superclass != null) {
+- superclass.addInterfaces(list);
+- }
+- }
+-
+- public List<InterfaceType> allInterfaces() {
+- List<InterfaceType> all = new ArrayList<InterfaceType>();
+- addInterfaces(all);
+- return all;
++ @Override
++ public List<InterfaceType> allInterfaces() {
++ return getAllInterfaces();
+ }
+
+ public List<ClassType> subclasses() {
+@@ -159,28 +161,6 @@
+ }
+ }
+
+- PacketStream sendInvokeCommand(final ThreadReferenceImpl thread,
+- final MethodImpl method,
+- final ValueImpl[] args,
+- final int options) {
+- CommandSender sender =
+- new CommandSender() {
+- public PacketStream send() {
+- return JDWP.ClassType.InvokeMethod.enqueueCommand(
+- vm, ClassTypeImpl.this, thread,
+- method.ref(), args, options);
+- }
+- };
+-
+- PacketStream stream;
+- if ((options & INVOKE_SINGLE_THREADED) != 0) {
+- stream = thread.sendResumingCommand(sender);
+- } else {
+- stream = vm.sendResumingCommand(sender);
+- }
+- return stream;
+- }
+-
+ PacketStream sendNewInstanceCommand(final ThreadReferenceImpl thread,
+ final MethodImpl method,
+ final ValueImpl[] args,
+@@ -203,52 +183,6 @@
+ return stream;
+ }
+
+- public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
+- List<? extends Value> origArguments, int options)
+- throws InvalidTypeException,
+- ClassNotLoadedException,
+- IncompatibleThreadStateException,
+- InvocationException {
+- validateMirror(threadIntf);
+- validateMirror(methodIntf);
+- validateMirrorsOrNulls(origArguments);
+-
+- MethodImpl method = (MethodImpl)methodIntf;
+- ThreadReferenceImpl thread = (ThreadReferenceImpl)threadIntf;
+-
+- validateMethodInvocation(method);
+-
+- List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
+-
+- ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
+- JDWP.ClassType.InvokeMethod ret;
+- try {
+- PacketStream stream =
+- sendInvokeCommand(thread, method, args, options);
+- ret = JDWP.ClassType.InvokeMethod.waitForReply(vm, stream);
+- } catch (JDWPException exc) {
+- if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
+- throw new IncompatibleThreadStateException();
+- } else {
+- throw exc.toJDIException();
+- }
+- }
+-
+- /*
+- * There is an implict VM-wide suspend at the conclusion
+- * of a normal (non-single-threaded) method invoke
+- */
+- if ((options & INVOKE_SINGLE_THREADED) == 0) {
+- vm.notifySuspend();
+- }
+-
+- if (ret.exception != null) {
+- throw new InvocationException(ret.exception);
+- } else {
+- return ret.returnValue;
+- }
+- }
+-
+ public ObjectReference newInstance(ThreadReference threadIntf,
+ Method methodIntf,
+ List<? extends Value> origArguments,
+@@ -311,58 +245,6 @@
+ return method;
+ }
+
+- public List<Method> allMethods() {
+- ArrayList<Method> list = new ArrayList<Method>(methods());
+-
+- ClassType clazz = superclass();
+- while (clazz != null) {
+- list.addAll(clazz.methods());
+- clazz = clazz.superclass();
+- }
+-
+- /*
+- * Avoid duplicate checking on each method by iterating through
+- * duplicate-free allInterfaces() rather than recursing
+- */
+- for (InterfaceType interfaze : allInterfaces()) {
+- list.addAll(interfaze.methods());
+- }
+-
+- return list;
+- }
+-
+- List<ReferenceType> inheritedTypes() {
+- List<ReferenceType> inherited = new ArrayList<ReferenceType>();
+- if (superclass() != null) {
+- inherited.add(0, (ReferenceType)superclass()); /* insert at front */
+- }
+- for (ReferenceType rt : interfaces()) {
+- inherited.add(rt);
+- }
+- return inherited;
+- }
+-
+- void validateMethodInvocation(Method method)
+- throws InvalidTypeException,
+- InvocationException {
+- /*
+- * Method must be in this class or a superclass.
+- */
+- ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType();
+- if (!declType.isAssignableFrom(this)) {
+- throw new IllegalArgumentException("Invalid method");
+- }
+-
+- /*
+- * Method must be a static and not a static initializer
+- */
+- if (!method.isStatic()) {
+- throw new IllegalArgumentException("Cannot invoke instance method on a class type");
+- } else if (method.isStaticInitializer()) {
+- throw new IllegalArgumentException("Cannot invoke static initializer");
+- }
+- }
+-
+ void validateConstructorInvocation(Method method)
+ throws InvalidTypeException,
+ InvocationException {
+@@ -382,47 +264,33 @@
+ }
+ }
+
+- void addVisibleMethods(Map<String, Method> methodMap) {
+- /*
+- * Add methods from
+- * parent types first, so that the methods in this class will
+- * overwrite them in the hash table
+- */
+-
+- Iterator<InterfaceType> iter = interfaces().iterator();
+- while (iter.hasNext()) {
+- InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
+- interfaze.addVisibleMethods(methodMap);
+- }
+-
+- ClassTypeImpl clazz = (ClassTypeImpl)superclass();
+- if (clazz != null) {
+- clazz.addVisibleMethods(methodMap);
+- }
+-
+- addToMethodMap(methodMap, methods());
+- }
+-
+- boolean isAssignableTo(ReferenceType type) {
+- ClassTypeImpl superclazz = (ClassTypeImpl)superclass();
+- if (this.equals(type)) {
+- return true;
+- } else if ((superclazz != null) && superclazz.isAssignableTo(type)) {
+- return true;
+- } else {
+- List<InterfaceType> interfaces = interfaces();
+- Iterator<InterfaceType> iter = interfaces.iterator();
+- while (iter.hasNext()) {
+- InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
+- if (interfaze.isAssignableTo(type)) {
+- return true;
+- }
+- }
+- return false;
+- }
+- }
+
+ public String toString() {
+ return "class " + name() + " (" + loaderString() + ")";
+ }
++
++ @Override
++ CommandSender getInvokeMethodSender(ThreadReferenceImpl thread,
++ MethodImpl method,
++ ValueImpl[] args,
++ int options) {
++ return () ->
++ JDWP.ClassType.InvokeMethod.enqueueCommand(vm,
++ ClassTypeImpl.this,
++ thread,
++ method.ref(),
++ args,
++ options);
++ }
++
++ @Override
++ InvocationResult waitForReply(PacketStream stream) throws JDWPException {
++ return new IResult(JDWP.ClassType.InvokeMethod.waitForReply(vm, stream));
++ }
++
++ @Override
++ boolean canInvoke(Method method) {
++ // Method must be in this class or a superclass.
++ return ((ReferenceTypeImpl)method.declaringType()).isAssignableFrom(this);
++ }
+ }
+--- ./jdk/src/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -29,13 +29,31 @@
+
+ import java.util.List;
+ import java.util.ArrayList;
+-import java.util.Map;
+-import java.util.Iterator;
+ import java.util.Collections;
++import java.util.Set;
+ import java.lang.ref.SoftReference;
+
+-public class InterfaceTypeImpl extends ReferenceTypeImpl
+- implements InterfaceType {
++final public class InterfaceTypeImpl extends InvokableTypeImpl
++ implements InterfaceType {
++
++ private static class IResult implements InvocationResult {
++ final private JDWP.InterfaceType.InvokeMethod rslt;
++
++ public IResult(JDWP.InterfaceType.InvokeMethod rslt) {
++ this.rslt = rslt;
++ }
++
++ @Override
++ public ObjectReferenceImpl getException() {
++ return rslt.exception;
++ }
++
++ @Override
++ public ValueImpl getResult() {
++ return rslt.returnValue;
++ }
++
++ }
+
+ private SoftReference<List<InterfaceType>> superinterfacesRef = null;
+
+@@ -80,98 +98,6 @@
+ return implementors;
+ }
+
+- void addVisibleMethods(Map<String, Method> methodMap) {
+- /*
+- * Add methods from
+- * parent types first, so that the methods in this class will
+- * overwrite them in the hash table
+- */
+-
+- for (InterfaceType interfaze : superinterfaces()) {
+- ((InterfaceTypeImpl)interfaze).addVisibleMethods(methodMap);
+- }
+-
+- addToMethodMap(methodMap, methods());
+- }
+-
+- public List<Method> allMethods() {
+- ArrayList<Method> list = new ArrayList<Method>(methods());
+-
+- /*
+- * It's more efficient if don't do this
+- * recursively.
+- */
+- for (InterfaceType interfaze : allSuperinterfaces()) {
+- list.addAll(interfaze.methods());
+- }
+-
+- return list;
+- }
+-
+- List<InterfaceType> allSuperinterfaces() {
+- ArrayList<InterfaceType> list = new ArrayList<InterfaceType>();
+- addSuperinterfaces(list);
+- return list;
+- }
+-
+- void addSuperinterfaces(List<InterfaceType> list) {
+- /*
+- * This code is a little strange because it
+- * builds the list with a more suitable order than the
+- * depth-first approach a normal recursive solution would
+- * take. Instead, all direct superinterfaces precede all
+- * indirect ones.
+- */
+-
+- /*
+- * Get a list of direct superinterfaces that's not already in the
+- * list being built.
+- */
+- List<InterfaceType> immediate = new ArrayList<InterfaceType>(superinterfaces());
+- Iterator<InterfaceType> iter = immediate.iterator();
+- while (iter.hasNext()) {
+- InterfaceType interfaze = iter.next();
+- if (list.contains(interfaze)) {
+- iter.remove();
+- }
+- }
+-
+- /*
+- * Add all new direct superinterfaces
+- */
+- list.addAll(immediate);
+-
+- /*
+- * Recurse for all new direct superinterfaces.
+- */
+- iter = immediate.iterator();
+- while (iter.hasNext()) {
+- InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
+- interfaze.addSuperinterfaces(list);
+- }
+- }
+-
+- boolean isAssignableTo(ReferenceType type) {
+-
+- // Exact match?
+- if (this.equals(type)) {
+- return true;
+- } else {
+- // Try superinterfaces.
+- for (InterfaceType interfaze : superinterfaces()) {
+- if (((InterfaceTypeImpl)interfaze).isAssignableTo(type)) {
+- return true;
+- }
+- }
+-
+- return false;
+- }
+- }
+-
+- List<InterfaceType> inheritedTypes() {
+- return superinterfaces();
+- }
+-
+ public boolean isInitialized() {
+ return isPrepared();
+ }
+@@ -179,4 +105,39 @@
+ public String toString() {
+ return "interface " + name() + " (" + loaderString() + ")";
+ }
+-}
++
++ @Override
++ InvocationResult waitForReply(PacketStream stream) throws JDWPException {
++ return new IResult(JDWP.InterfaceType.InvokeMethod.waitForReply(vm, stream));
++ }
++
++ @Override
++ CommandSender getInvokeMethodSender(final ThreadReferenceImpl thread,
++ final MethodImpl method,
++ final ValueImpl[] args,
++ final int options) {
++ return () ->
++ JDWP.InterfaceType.InvokeMethod.enqueueCommand(vm,
++ InterfaceTypeImpl.this,
++ thread,
++ method.ref(),
++ args,
++ options);
++ }
++
++ @Override
++ ClassType superclass() {
++ return null;
++ }
++
++ @Override
++ List<InterfaceType> interfaces() {
++ return superinterfaces();
++ }
++
++ @Override
++ boolean canInvoke(Method method) {
++ // method must be directly in this interface
++ return this.equals(method.declaringType());
++ }
++}
+\ No newline at end of file
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/src/share/classes/com/sun/tools/jdi/InvokableTypeImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,305 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.tools.jdi;
++
++import com.sun.jdi.ClassNotLoadedException;
++import com.sun.jdi.ClassType;
++import com.sun.jdi.IncompatibleThreadStateException;
++import com.sun.jdi.InterfaceType;
++import com.sun.jdi.InvalidTypeException;
++import com.sun.jdi.InvocationException;
++import com.sun.jdi.Method;
++import com.sun.jdi.ReferenceType;
++import com.sun.jdi.ThreadReference;
++import com.sun.jdi.Value;
++import com.sun.jdi.VirtualMachine;
++import java.util.ArrayList;
++import java.util.Iterator;
++import java.util.List;
++import java.util.Map;
++import java.util.Set;
++
++/**
++ * A supertype for ReferenceTypes allowing method invocations
++ */
++abstract class InvokableTypeImpl extends ReferenceTypeImpl {
++ /**
++ * The invocation result wrapper
++ * It is necessary because both ClassType and InterfaceType
++ * use their own type to represent the invocation result
++ */
++ static interface InvocationResult {
++ ObjectReferenceImpl getException();
++ ValueImpl getResult();
++ }
++
++ InvokableTypeImpl(VirtualMachine aVm, long aRef) {
++ super(aVm, aRef);
++ }
++
++ /**
++ * Method invocation support.
++ * Shared by ClassType and InterfaceType
++ * @param threadIntf the thread in which to invoke.
++ * @param methodIntf method the {@link Method} to invoke.
++ * @param origArguments the list of {@link Value} arguments bound to the
++ * invoked method. Values from the list are assigned to arguments
++ * in the order they appear in the method signature.
++ * @param options the integer bit flag options.
++ * @return a {@link Value} mirror of the invoked method's return value.
++ * @throws java.lang.IllegalArgumentException if the method is not
++ * a member of this type, if the size of the argument list
++ * does not match the number of declared arguments for the method, or
++ * if the method is not static or is a static initializer.
++ * @throws {@link InvalidTypeException} if any argument in the
++ * argument list is not assignable to the corresponding method argument
++ * type.
++ * @throws ClassNotLoadedException if any argument type has not yet been loaded
++ * through the appropriate class loader.
++ * @throws IncompatibleThreadStateException if the specified thread has not
++ * been suspended by an event.
++ * @throws InvocationException if the method invocation resulted in
++ * an exception in the target VM.
++ * @throws InvalidTypeException If the arguments do not meet this requirement --
++ * Object arguments must be assignment compatible with the argument
++ * type. This implies that the argument type must be
++ * loaded through the enclosing class's class loader.
++ * Primitive arguments must be either assignment compatible with the
++ * argument type or must be convertible to the argument type without loss
++ * of information. See JLS section 5.2 for more information on assignment
++ * compatibility.
++ * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}.
++ */
++ final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
++ List<? extends Value> origArguments, int options)
++ throws InvalidTypeException,
++ ClassNotLoadedException,
++ IncompatibleThreadStateException,
++ InvocationException {
++ validateMirror(threadIntf);
++ validateMirror(methodIntf);
++ validateMirrorsOrNulls(origArguments);
++ MethodImpl method = (MethodImpl) methodIntf;
++ ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf;
++ validateMethodInvocation(method);
++ List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
++ ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
++ InvocationResult ret;
++ try {
++ PacketStream stream = sendInvokeCommand(thread, method, args, options);
++ ret = waitForReply(stream);
++ } catch (JDWPException exc) {
++ if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
++ throw new IncompatibleThreadStateException();
++ } else {
++ throw exc.toJDIException();
++ }
++ }
++ /*
++ * There is an implict VM-wide suspend at the conclusion
++ * of a normal (non-single-threaded) method invoke
++ */
++ if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) {
++ vm.notifySuspend();
++ }
++ if (ret.getException() != null) {
++ throw new InvocationException(ret.getException());
++ } else {
++ return ret.getResult();
++ }
++ }
++
++ @Override
++ boolean isAssignableTo(ReferenceType type) {
++ ClassTypeImpl superclazz = (ClassTypeImpl) superclass();
++ if (this.equals(type)) {
++ return true;
++ } else if ((superclazz != null) && superclazz.isAssignableTo(type)) {
++ return true;
++ } else {
++ List<InterfaceType> interfaces = interfaces();
++ Iterator<InterfaceType> iter = interfaces.iterator();
++ while (iter.hasNext()) {
++ InterfaceTypeImpl interfaze = (InterfaceTypeImpl) iter.next();
++ if (interfaze.isAssignableTo(type)) {
++ return true;
++ }
++ }
++ return false;
++ }
++ }
++
++ @Override
++ final void addVisibleMethods(Map<String, Method> methodMap, Set<InterfaceType> seenInterfaces) {
++ /*
++ * Add methods from
++ * parent types first, so that the methods in this class will
++ * overwrite them in the hash table
++ */
++ Iterator<InterfaceType> iter = interfaces().iterator();
++ while (iter.hasNext()) {
++ InterfaceTypeImpl interfaze = (InterfaceTypeImpl) iter.next();
++ if (!seenInterfaces.contains(interfaze)) {
++ interfaze.addVisibleMethods(methodMap, seenInterfaces);
++ seenInterfaces.add(interfaze);
++ }
++ }
++ ClassTypeImpl clazz = (ClassTypeImpl) superclass();
++ if (clazz != null) {
++ clazz.addVisibleMethods(methodMap, seenInterfaces);
++ }
++ addToMethodMap(methodMap, methods());
++ }
++
++ final void addInterfaces(List<InterfaceType> list) {
++ List<InterfaceType> immediate = interfaces();
++ list.addAll(interfaces());
++ Iterator<InterfaceType> iter = immediate.iterator();
++ while (iter.hasNext()) {
++ InterfaceTypeImpl interfaze = (InterfaceTypeImpl) iter.next();
++ interfaze.addInterfaces(list);
++ }
++ ClassTypeImpl superclass = (ClassTypeImpl) superclass();
++ if (superclass != null) {
++ superclass.addInterfaces(list);
++ }
++ }
++
++ /**
++ * Returns all the implemented interfaces recursively
++ * @return A list of all the implemented interfaces (recursively)
++ */
++ final List<InterfaceType> getAllInterfaces() {
++ List<InterfaceType> all = new ArrayList<>();
++ addInterfaces(all);
++ return all;
++ }
++
++ /**
++ * Shared implementation of {@linkplain ClassType#allMethods()} and
++ * {@linkplain InterfaceType#allMethods()}
++ * @return A list of all methods (recursively)
++ */
++ public final List<Method> allMethods() {
++ ArrayList<Method> list = new ArrayList<>(methods());
++ ClassType clazz = superclass();
++ while (clazz != null) {
++ list.addAll(clazz.methods());
++ clazz = clazz.superclass();
++ }
++ /*
++ * Avoid duplicate checking on each method by iterating through
++ * duplicate-free allInterfaces() rather than recursing
++ */
++ for (InterfaceType interfaze : getAllInterfaces()) {
++ list.addAll(interfaze.methods());
++ }
++ return list;
++ }
++
++ @Override
++ final List<ReferenceType> inheritedTypes() {
++ List<ReferenceType> inherited = new ArrayList<>();
++ if (superclass() != null) {
++ inherited.add(0, superclass()); /* insert at front */
++ }
++ for (ReferenceType rt : interfaces()) {
++ inherited.add(rt);
++ }
++ return inherited;
++ }
++
++ private PacketStream sendInvokeCommand(final ThreadReferenceImpl thread,
++ final MethodImpl method,
++ final ValueImpl[] args,
++ final int options) {
++ CommandSender sender = getInvokeMethodSender(thread, method, args, options);
++ PacketStream stream;
++ if ((options & ClassType.INVOKE_SINGLE_THREADED) != 0) {
++ stream = thread.sendResumingCommand(sender);
++ } else {
++ stream = vm.sendResumingCommand(sender);
++ }
++ return stream;
++ }
++
++ private void validateMethodInvocation(Method method)
++ throws InvalidTypeException,
++ InvocationException {
++ if (!canInvoke(method)) {
++ throw new IllegalArgumentException("Invalid method");
++ }
++ /*
++ * Method must be a static and not a static initializer
++ */
++ if (!method.isStatic()) {
++ throw new IllegalArgumentException("Cannot invoke instance method on a class/interface type");
++ } else if (method.isStaticInitializer()) {
++ throw new IllegalArgumentException("Cannot invoke static initializer");
++ }
++ }
++
++ /**
++ * A subclass will provide specific {@linkplain CommandSender}
++ * @param thread the current invocation thread
++ * @param method the method to invoke
++ * @param args the arguments to pass to the method
++ * @param options the integer bit flag options
++ * @return the specific {@literal CommandSender} instance
++ */
++ abstract CommandSender getInvokeMethodSender(ThreadReferenceImpl thread,
++ MethodImpl method,
++ ValueImpl[] args,
++ int options);
++
++ /**
++ * Waits for the reply to the last sent command
++ * @param stream the stream to listen for the reply on
++ * @return the {@linkplain InvocationResult} instance
++ * @throws JDWPException when something goes wrong in JDWP
++ */
++ abstract InvocationResult waitForReply(PacketStream stream) throws JDWPException;
++
++ /**
++ * Get the {@linkplain ReferenceType} superclass
++ * @return the superclass or null
++ */
++ abstract ClassType superclass();
++
++ /**
++ * Get the implemented/extended interfaces
++ * @return the list of implemented/extended interfaces
++ */
++ abstract List<InterfaceType> interfaces();
++
++ /**
++ * Checks the provided method whether it can be invoked
++ * @param method the method to check
++ * @return {@code TRUE} if the implementation knows how to invoke the method,
++ * {@code FALSE} otherwise
++ */
++ abstract boolean canInvoke(Method method);
++}
+--- ./jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -187,6 +187,13 @@
+ return isModifierSet(VMModifiers.ABSTRACT);
+ }
+
++ public boolean isDefault() {
++ return !isModifierSet(VMModifiers.ABSTRACT) &&
++ !isModifierSet(VMModifiers.STATIC) &&
++ !isModifierSet(VMModifiers.PRIVATE) &&
++ declaringType() instanceof InterfaceType;
++ }
++
+ public boolean isSynchronized() {
+ return isModifierSet(VMModifiers.SYNCHRONIZED);
+ }
+--- ./jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -277,7 +277,6 @@
+ void validateMethodInvocation(Method method, int options)
+ throws InvalidTypeException,
+ InvocationException {
+-
+ /*
+ * Method must be in this object's class, a superclass, or
+ * implemented interface
+@@ -287,6 +286,19 @@
+ throw new IllegalArgumentException("Invalid method");
+ }
+
++ if (declType instanceof ClassTypeImpl) {
++ validateClassMethodInvocation(method, options);
++ } else if (declType instanceof InterfaceTypeImpl) {
++ validateIfaceMethodInvocation(method, options);
++ } else {
++ throw new InvalidTypeException();
++ }
++ }
++
++ void validateClassMethodInvocation(Method method, int options)
++ throws InvalidTypeException,
++ InvocationException {
++
+ ClassTypeImpl clazz = invokableReferenceType(method);
+
+ /*
+@@ -300,9 +312,7 @@
+ * For nonvirtual invokes, method must have a body
+ */
+ if ((options & INVOKE_NONVIRTUAL) != 0) {
+- if (method.declaringType() instanceof InterfaceType) {
+- throw new IllegalArgumentException("Interface method");
+- } else if (method.isAbstract()) {
++ if (method.isAbstract()) {
+ throw new IllegalArgumentException("Abstract method");
+ }
+ }
+@@ -324,7 +334,7 @@
+ */
+ Method invoker = clazz.concreteMethodByName(method.name(),
+ method.signature());
+- // isAssignableFrom check above guarantees non-null
++ // invoker is supposed to be non-null under normal circumstances
+ invokedClass = (ClassTypeImpl)invoker.declaringType();
+ }
+ /* The above code is left over from previous versions.
+@@ -332,6 +342,17 @@
+ */
+ }
+
++ void validateIfaceMethodInvocation(Method method, int options)
++ throws InvalidTypeException,
++ InvocationException {
++ /*
++ * Only default methods allowed for nonvirtual invokes
++ */
++ if (!method.isDefault()) {
++ throw new IllegalArgumentException("Not a default method");
++ }
++ }
++
+ PacketStream sendInvokeCommand(final ThreadReferenceImpl thread,
+ final ClassTypeImpl refType,
+ final MethodImpl method,
+@@ -370,7 +391,10 @@
+ ThreadReferenceImpl thread = (ThreadReferenceImpl)threadIntf;
+
+ if (method.isStatic()) {
+- if (referenceType() instanceof ClassType) {
++ if (referenceType() instanceof InterfaceType) {
++ InterfaceType type = (InterfaceType)referenceType();
++ return type.invokeMethod(thread, method, origArguments, options);
++ } else if (referenceType() instanceof ClassType) {
+ ClassType type = (ClassType)referenceType();
+ return type.invokeMethod(thread, method, origArguments, options);
+ } else {
+--- ./jdk/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -511,7 +511,7 @@
+ methodMap.put(method.name().concat(method.signature()), method);
+ }
+
+- abstract void addVisibleMethods(Map<String, Method> methodMap);
++ abstract void addVisibleMethods(Map<String, Method> methodMap, Set<InterfaceType> seenInterfaces);
+
+ public List<Method> visibleMethods() {
+ /*
+@@ -520,7 +520,7 @@
+ * concatenation of name and signature.
+ */
+ Map<String, Method> map = new HashMap<String, Method>();
+- addVisibleMethods(map);
++ addVisibleMethods(map, new HashSet<InterfaceType>());
+
+ /*
+ * ... but the hash map destroys order. Methods should be
+--- ./jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -48,7 +48,7 @@
+ private ResourceBundle messages = null;
+ private int vmSequenceNumber = 0;
+ private static final int majorVersion = 1;
+- private static final int minorVersion = 6;
++ private static final int minorVersion = 8;
+
+ private static final Object lock = new Object();
+ private static VirtualMachineManagerImpl vmm;
+--- ./jdk/src/share/classes/java/awt/Component.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/Component.java Wed Feb 04 12:14:43 2015 -0800
+@@ -174,7 +174,7 @@
+ * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>.
+ * <p>
+ * For details on the focus subsystem, see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>, and the
+ * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
+--- ./jdk/src/share/classes/java/awt/Container.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/Container.java Wed Feb 04 12:14:43 2015 -0800
+@@ -74,7 +74,7 @@
+ * (and hence to the bottom of the stacking order).
+ * <p>
+ * <b>Note</b>: For details on the focus subsystem, see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>, and the
+ * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
+@@ -3687,7 +3687,7 @@
+ private void writeObject(ObjectOutputStream s) throws IOException {
+ ObjectOutputStream.PutField f = s.putFields();
+ f.put("ncomponents", component.size());
+- f.put("component", getComponentsSync());
++ f.put("component", component.toArray(EMPTY_ARRAY));
+ f.put("layoutMgr", layoutMgr);
+ f.put("dispatcher", dispatcher);
+ f.put("maxSize", maxSize);
+--- ./jdk/src/share/classes/java/awt/DefaultFocusTraversalPolicy.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/DefaultFocusTraversalPolicy.java Wed Feb 04 12:14:43 2015 -0800
+@@ -54,7 +54,7 @@
+ * impact, the focusability of the Component itself.
+ * <p>
+ * Please see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>, and the
+ * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
+--- ./jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java Wed Feb 04 12:14:43 2015 -0800
+@@ -49,7 +49,7 @@
+ * Container's FocusTraversalPolicy.
+ * <p>
+ * Please see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>, and the
+ * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
+--- ./jdk/src/share/classes/java/awt/DisplayMode.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/DisplayMode.java Wed Feb 04 12:14:43 2015 -0800
+@@ -35,7 +35,7 @@
+ * (see {@link GraphicsDevice#isDisplayChangeSupported}).
+ * <p>
+ * For more information on full-screen exclusive mode API, see the
+- * <a href="http://docs.oracle.com/javase/tutorial/extra/fullscreen/index.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/extra/fullscreen/index.html">
+ * Full-Screen Exclusive Mode API Tutorial</a>.
+ *
+ * @see GraphicsDevice
+--- ./jdk/src/share/classes/java/awt/FocusTraversalPolicy.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/FocusTraversalPolicy.java Wed Feb 04 12:14:43 2015 -0800
+@@ -49,7 +49,7 @@
+ * policy is used to perform the search operation.
+ * <p>
+ * Please see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>, and the
+ * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
+--- ./jdk/src/share/classes/java/awt/GraphicsDevice.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/GraphicsDevice.java Wed Feb 04 12:14:43 2015 -0800
+@@ -69,7 +69,7 @@
+ * }</pre>
+ * <p>
+ * For more information on full-screen exclusive mode API, see the
+- * <a href="http://docs.oracle.com/javase/tutorial/extra/fullscreen/index.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/extra/fullscreen/index.html">
+ * Full-Screen Exclusive Mode API Tutorial</a>.
+ *
+ * @see GraphicsEnvironment
+--- ./jdk/src/share/classes/java/awt/KeyboardFocusManager.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/KeyboardFocusManager.java Wed Feb 04 12:14:43 2015 -0800
+@@ -88,7 +88,7 @@
+ * ClassLoader.
+ * <p>
+ * Please see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>, and the
+ * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
+--- ./jdk/src/share/classes/java/awt/SplashScreen.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/SplashScreen.java Wed Feb 04 12:14:43 2015 -0800
+@@ -245,7 +245,14 @@
+ public Rectangle getBounds() throws IllegalStateException {
+ synchronized (SplashScreen.class) {
+ checkVisible();
+- return _getBounds(splashPtr);
++ float scale = _getScaleFactor(splashPtr);
++ Rectangle bounds = _getBounds(splashPtr);
++ assert scale > 0;
++ if (scale > 0 && scale != 1) {
++ bounds.setSize((int) (bounds.getWidth() / scale),
++ (int) (bounds.getWidth() / scale));
++ }
++ return bounds;
+ }
+ }
+
+@@ -286,11 +293,21 @@
+ */
+ public Graphics2D createGraphics() throws IllegalStateException {
+ synchronized (SplashScreen.class) {
++ checkVisible();
+ if (image==null) {
+- Dimension dim = getSize();
+- image = new BufferedImage(dim.width, dim.height, BufferedImage.TYPE_INT_ARGB);
++ // get unscaled splash image size
++ Dimension dim = _getBounds(splashPtr).getSize();
++ image = new BufferedImage(dim.width, dim.height,
++ BufferedImage.TYPE_INT_ARGB);
+ }
+- return image.createGraphics();
++ float scale = _getScaleFactor(splashPtr);
++ Graphics2D g = image.createGraphics();
++ assert (scale > 0);
++ if (scale <= 0) {
++ scale = 1;
++ }
++ g.scale(scale, scale);
++ return g;
+ }
+ }
+
+@@ -401,5 +418,6 @@
+ private native static String _getImageFileName(long splashPtr);
+ private native static String _getImageJarName(long SplashPtr);
+ private native static boolean _setImageData(long SplashPtr, byte[] data);
++ private native static float _getScaleFactor(long SplashPtr);
+
+-};
++}
+--- ./jdk/src/share/classes/java/awt/Toolkit.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/Toolkit.java Wed Feb 04 12:14:43 2015 -0800
+@@ -79,7 +79,7 @@
+ *
+ * <li>Moving the focus from one component to another.
+ * <br>For more information, see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html#transferTiming">Timing
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html#transferTiming">Timing
+ * Focus Transfers</a>, a section in
+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/">The Swing
+ * Tutorial</a>.
+--- ./jdk/src/share/classes/java/awt/Window.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/Window.java Wed Feb 04 12:14:43 2015 -0800
+@@ -2247,7 +2247,18 @@
+ }
+ firePropertyChange("alwaysOnTop", oldAlwaysOnTop, alwaysOnTop);
+ }
+- for (WeakReference<Window> ref : ownedWindowList) {
++ setOwnedWindowsAlwaysOnTop(alwaysOnTop);
++ }
++
++ @SuppressWarnings({"rawtypes", "unchecked"})
++ private void setOwnedWindowsAlwaysOnTop(boolean alwaysOnTop) {
++ WeakReference<Window>[] ownedWindowArray;
++ synchronized (ownedWindowList) {
++ ownedWindowArray = new WeakReference[ownedWindowList.size()];
++ ownedWindowList.copyInto(ownedWindowArray);
++ }
++
++ for (WeakReference<Window> ref : ownedWindowArray) {
+ Window window = ref.get();
+ if (window != null) {
+ try {
+--- ./jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java Wed Feb 04 12:14:43 2015 -0800
+@@ -108,7 +108,7 @@
+ * the same results.
+ * <p>
+ * For more information on the using data transfer with Swing see
+- * the <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
++ * the <a href="https://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
+ * How to Use Drag and Drop and Data Transfer</a>,
+ * section in <em>Java Tutorial</em>.
+ *
+--- ./jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java Wed Feb 04 12:14:43 2015 -0800
+@@ -38,11 +38,13 @@
+ import java.net.MalformedURLException;
+
+ import java.util.ArrayList;
++import java.util.Collections;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.LinkedHashSet;
+ import java.util.List;
+ import java.util.Map;
++import java.util.Objects;
+ import java.util.Set;
+
+ import sun.awt.AppContext;
+@@ -102,19 +104,11 @@
+ private static final String HTML_TEXT_BASE_TYPE = "text/html";
+
+ /**
+- * This constant is passed to flavorToNativeLookup() to indicate that a
+- * a native should be synthesized, stored, and returned by encoding the
+- * DataFlavor's MIME type in case if the DataFlavor is not found in
+- * 'flavorToNative' map.
+- */
+- private static final boolean SYNTHESIZE_IF_NOT_FOUND = true;
+-
+- /**
+ * Maps native Strings to Lists of DataFlavors (or base type Strings for
+ * text DataFlavors).
+ * Do not use the field directly, use getNativeToFlavor() instead.
+ */
+- private final Map<String, List<DataFlavor>> nativeToFlavor = new HashMap<>();
++ private final Map<String, LinkedHashSet<DataFlavor>> nativeToFlavor = new HashMap<>();
+
+ /**
+ * Accessor to nativeToFlavor map. Since we use lazy initialization we must
+@@ -123,7 +117,7 @@
+ *
+ * @return nativeToFlavor
+ */
+- private Map<String, List<DataFlavor>> getNativeToFlavor() {
++ private Map<String, LinkedHashSet<DataFlavor>> getNativeToFlavor() {
+ if (!isMapInitialized) {
+ initSystemFlavorMap();
+ }
+@@ -135,7 +129,7 @@
+ * native Strings.
+ * Do not use the field directly, use getFlavorToNative() instead.
+ */
+- private final Map<DataFlavor, List<String>> flavorToNative = new HashMap<>();
++ private final Map<DataFlavor, LinkedHashSet<String>> flavorToNative = new HashMap<>();
+
+ /**
+ * Accessor to flavorToNative map. Since we use lazy initialization we must
+@@ -144,7 +138,7 @@
+ *
+ * @return flavorToNative
+ */
+- private synchronized Map<DataFlavor, List<String>> getFlavorToNative() {
++ private synchronized Map<DataFlavor, LinkedHashSet<String>> getFlavorToNative() {
+ if (!isMapInitialized) {
+ initSystemFlavorMap();
+ }
+@@ -152,21 +146,44 @@
+ }
+
+ /**
++ * Maps a text DataFlavor primary mime-type to the native. Used only to store
++ * standard mappings registered in the flavormap.properties
++ * Do not use this field directly, use getTextTypeToNative() instead.
++ */
++ private Map<String, LinkedHashSet<String>> textTypeToNative = new HashMap<>();
++
++ /**
+ * Shows if the object has been initialized.
+ */
+ private boolean isMapInitialized = false;
+
+ /**
++ * An accessor to textTypeToNative map. Since we use lazy initialization we
++ * must use this accessor instead of direct access to the field which may not
++ * be initialized yet. This method will initialize the field if needed.
++ *
++ * @return textTypeToNative
++ */
++ private synchronized Map<String, LinkedHashSet<String>> getTextTypeToNative() {
++ if (!isMapInitialized) {
++ initSystemFlavorMap();
++ // From this point the map should not be modified
++ textTypeToNative = Collections.unmodifiableMap(textTypeToNative);
++ }
++ return textTypeToNative;
++ }
++
++ /**
+ * Caches the result of getNativesForFlavor(). Maps DataFlavors to
+- * SoftReferences which reference Lists of String natives.
++ * SoftReferences which reference LinkedHashSet of String natives.
+ */
+- private Map<DataFlavor, SoftReference<List<String>>> getNativesForFlavorCache = new HashMap<>();
++ private final SoftCache<DataFlavor, String> nativesForFlavorCache = new SoftCache<>();
+
+ /**
+ * Caches the result getFlavorsForNative(). Maps String natives to
+- * SoftReferences which reference Lists of DataFlavors.
++ * SoftReferences which reference LinkedHashSet of DataFlavors.
+ */
+- private Map<String, SoftReference<List<DataFlavor>>> getFlavorsForNativeCache = new HashMap<>();
++ private final SoftCache<String, DataFlavor> flavorsForNativeCache = new SoftCache<>();
+
+ /**
+ * Dynamic mapping generation used for text mappings should not be applied
+@@ -174,7 +191,7 @@
+ * explicitly specified with setFlavorsForNative() or
+ * setNativesForFlavor(). This keeps all such keys.
+ */
+- private Set disabledMappingGenerationKeys = new HashSet();
++ private Set<Object> disabledMappingGenerationKeys = new HashSet<>();
+
+ /**
+ * Returns the default FlavorMap for this thread's ClassLoader.
+@@ -403,7 +420,7 @@
+ flavor = new DataFlavor(value);
+ } catch (Exception e) {
+ try {
+- flavor = new DataFlavor(value, (String)null);
++ flavor = new DataFlavor(value, null);
+ } catch (Exception ee) {
+ ee.printStackTrace();
+ continue;
+@@ -411,11 +428,11 @@
+ }
+
+ final LinkedHashSet<DataFlavor> dfs = new LinkedHashSet<>();
+-
+ dfs.add(flavor);
+
+ if ("text".equals(flavor.getPrimaryType())) {
+ dfs.addAll(convertMimeTypeToDataFlavors(value));
++ store(flavor.mimeType.getBaseType(), key, getTextTypeToNative());
+ }
+
+ for (DataFlavor df : dfs) {
+@@ -504,10 +521,10 @@
+ * the appropriate Map location, but rather will be appended to a List
+ * stored in that location.
+ */
+- private <H, L> void store(H hashed, L listed, Map<H, List<L>> map) {
+- List<L> list = map.get(hashed);
++ private <H, L> void store(H hashed, L listed, Map<H, LinkedHashSet<L>> map) {
++ LinkedHashSet<L> list = map.get(hashed);
+ if (list == null) {
+- list = new ArrayList<>(1);
++ list = new LinkedHashSet<>(1);
+ map.put(hashed, list);
+ }
+ if (!list.contains(listed)) {
+@@ -521,17 +538,17 @@
+ * case, a new DataFlavor is synthesized, stored, and returned, if and
+ * only if the specified native is encoded as a Java MIME type.
+ */
+- private List<DataFlavor> nativeToFlavorLookup(String nat) {
+- List<DataFlavor> flavors = getNativeToFlavor().get(nat);
++ private LinkedHashSet<DataFlavor> nativeToFlavorLookup(String nat) {
++ LinkedHashSet<DataFlavor> flavors = getNativeToFlavor().get(nat);
++
+
+ if (nat != null && !disabledMappingGenerationKeys.contains(nat)) {
+ DataTransferer transferer = DataTransferer.getInstance();
+ if (transferer != null) {
+- List<DataFlavor> platformFlavors =
++ LinkedHashSet<DataFlavor> platformFlavors =
+ transferer.getPlatformMappingsForNative(nat);
+ if (!platformFlavors.isEmpty()) {
+ if (flavors != null) {
+- platformFlavors.removeAll(new HashSet<>(flavors));
+ // Prepending the platform-specific mappings ensures
+ // that the flavors added with
+ // addFlavorForUnencodedNative() are at the end of
+@@ -557,24 +574,22 @@
+ }
+
+ if (flavor != null) {
+- flavors = new ArrayList<>(1);
++ flavors = new LinkedHashSet<>(1);
+ getNativeToFlavor().put(nat, flavors);
+ flavors.add(flavor);
+- getFlavorsForNativeCache.remove(nat);
+- getFlavorsForNativeCache.remove(null);
++ flavorsForNativeCache.remove(nat);
+
+- List<String> natives = getFlavorToNative().get(flavor);
++ LinkedHashSet<String> natives = getFlavorToNative().get(flavor);
+ if (natives == null) {
+- natives = new ArrayList<>(1);
++ natives = new LinkedHashSet<>(1);
+ getFlavorToNative().put(flavor, natives);
+ }
+ natives.add(nat);
+- getNativesForFlavorCache.remove(flavor);
+- getNativesForFlavorCache.remove(null);
++ nativesForFlavorCache.remove(flavor);
+ }
+ }
+
+- return (flavors != null) ? flavors : new ArrayList<>(0);
++ return (flavors != null) ? flavors : new LinkedHashSet<>(0);
+ }
+
+ /**
+@@ -585,18 +600,18 @@
+ * encoding the DataFlavor's MIME type. Otherwise an empty List is returned
+ * and 'flavorToNative' remains unaffected.
+ */
+- private List<String> flavorToNativeLookup(final DataFlavor flav,
+- final boolean synthesize) {
+- List<String> natives = getFlavorToNative().get(flav);
++ private LinkedHashSet<String> flavorToNativeLookup(final DataFlavor flav,
++ final boolean synthesize) {
++
++ LinkedHashSet<String> natives = getFlavorToNative().get(flav);
+
+ if (flav != null && !disabledMappingGenerationKeys.contains(flav)) {
+ DataTransferer transferer = DataTransferer.getInstance();
+ if (transferer != null) {
+- List<String> platformNatives =
++ LinkedHashSet<String> platformNatives =
+ transferer.getPlatformMappingsForFlavor(flav);
+ if (!platformNatives.isEmpty()) {
+ if (natives != null) {
+- platformNatives.removeAll(new HashSet<>(natives));
+ // Prepend the platform-specific mappings to ensure
+ // that the natives added with
+ // addUnencodedNativeForFlavor() are at the end of
+@@ -611,26 +626,25 @@
+ if (natives == null) {
+ if (synthesize) {
+ String encoded = encodeDataFlavor(flav);
+- natives = new ArrayList<>(1);
++ natives = new LinkedHashSet<>(1);
+ getFlavorToNative().put(flav, natives);
+ natives.add(encoded);
+- getNativesForFlavorCache.remove(flav);
+- getNativesForFlavorCache.remove(null);
+
+- List<DataFlavor> flavors = getNativeToFlavor().get(encoded);
++ LinkedHashSet<DataFlavor> flavors = getNativeToFlavor().get(encoded);
+ if (flavors == null) {
+- flavors = new ArrayList<>(1);
++ flavors = new LinkedHashSet<>(1);
+ getNativeToFlavor().put(encoded, flavors);
+ }
+ flavors.add(flav);
+- getFlavorsForNativeCache.remove(encoded);
+- getFlavorsForNativeCache.remove(null);
++
++ nativesForFlavorCache.remove(flav);
++ flavorsForNativeCache.remove(encoded);
+ } else {
+- natives = new ArrayList<>(0);
++ natives = new LinkedHashSet<>(0);
+ }
+ }
+
+- return natives;
++ return new LinkedHashSet<>(natives);
+ }
+
+ /**
+@@ -658,103 +672,63 @@
+ * @see #encodeDataFlavor
+ * @since 1.4
+ */
++ @Override
+ public synchronized List<String> getNativesForFlavor(DataFlavor flav) {
+- List<String> retval = null;
+-
+- // Check cache, even for null flav
+- SoftReference<List<String>> ref = getNativesForFlavorCache.get(flav);
+- if (ref != null) {
+- retval = ref.get();
+- if (retval != null) {
+- // Create a copy, because client code can modify the returned
+- // list.
+- return new ArrayList<>(retval);
+- }
++ LinkedHashSet<String> retval = nativesForFlavorCache.check(flav);
++ if (retval != null) {
++ return new ArrayList<>(retval);
+ }
+
+ if (flav == null) {
+- retval = new ArrayList<>(getNativeToFlavor().keySet());
++ retval = new LinkedHashSet<>(getNativeToFlavor().keySet());
+ } else if (disabledMappingGenerationKeys.contains(flav)) {
+ // In this case we shouldn't synthesize a native for this flavor,
+ // since its mappings were explicitly specified.
+- retval = flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND);
++ retval = flavorToNativeLookup(flav, false);
+ } else if (DataTransferer.isFlavorCharsetTextType(flav)) {
++ retval = new LinkedHashSet<>(0);
+
+ // For text/* flavors, flavor-to-native mappings specified in
+ // flavormap.properties are stored per flavor's base type.
+ if ("text".equals(flav.getPrimaryType())) {
+- retval = getAllNativesForType(flav.mimeType.getBaseType());
+- if (retval != null) {
+- // To prevent the List stored in the map from modification.
+- retval = new ArrayList(retval);
++ LinkedHashSet<String> textTypeNatives =
++ getTextTypeToNative().get(flav.mimeType.getBaseType());
++ if (textTypeNatives != null) {
++ retval.addAll(textTypeNatives);
+ }
+ }
+
+ // Also include text/plain natives, but don't duplicate Strings
+- List<String> textPlainList = getAllNativesForType(TEXT_PLAIN_BASE_TYPE);
+-
+- if (textPlainList != null && !textPlainList.isEmpty()) {
+- // To prevent the List stored in the map from modification.
+- // This also guarantees that removeAll() is supported.
+- textPlainList = new ArrayList<>(textPlainList);
+- if (retval != null && !retval.isEmpty()) {
+- // Use HashSet to get constant-time performance for search.
+- textPlainList.removeAll(new HashSet<>(retval));
+- retval.addAll(textPlainList);
+- } else {
+- retval = textPlainList;
+- }
++ LinkedHashSet<String> textTypeNatives =
++ getTextTypeToNative().get(TEXT_PLAIN_BASE_TYPE);
++ if (textTypeNatives != null) {
++ retval.addAll(textTypeNatives);
+ }
+
+- if (retval == null || retval.isEmpty()) {
+- retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
++ if (retval.isEmpty()) {
++ retval = flavorToNativeLookup(flav, true);
+ } else {
+ // In this branch it is guaranteed that natives explicitly
+ // listed for flav's MIME type were added with
+ // addUnencodedNativeForFlavor(), so they have lower priority.
+- List<String> explicitList =
+- flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND);
+-
+- // flavorToNativeLookup() never returns null.
+- // It can return an empty List, however.
+- if (!explicitList.isEmpty()) {
+- // To prevent the List stored in the map from modification.
+- // This also guarantees that removeAll() is supported.
+- explicitList = new ArrayList<>(explicitList);
+- // Use HashSet to get constant-time performance for search.
+- explicitList.removeAll(new HashSet<>(retval));
+- retval.addAll(explicitList);
+- }
++ retval.addAll(flavorToNativeLookup(flav, false));
+ }
+ } else if (DataTransferer.isFlavorNoncharsetTextType(flav)) {
+- retval = getAllNativesForType(flav.mimeType.getBaseType());
++ retval = getTextTypeToNative().get(flav.mimeType.getBaseType());
+
+ if (retval == null || retval.isEmpty()) {
+- retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
++ retval = flavorToNativeLookup(flav, true);
+ } else {
+ // In this branch it is guaranteed that natives explicitly
+ // listed for flav's MIME type were added with
+ // addUnencodedNativeForFlavor(), so they have lower priority.
+- List<String> explicitList =
+- flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND);
+-
+- // flavorToNativeLookup() never returns null.
+- // It can return an empty List, however.
+- if (!explicitList.isEmpty()) {
+- // To prevent the List stored in the map from modification.
+- // This also guarantees that add/removeAll() are supported.
+- retval = new ArrayList<>(retval);
+- explicitList = new ArrayList<>(explicitList);
+- // Use HashSet to get constant-time performance for search.
+- explicitList.removeAll(new HashSet<>(retval));
+- retval.addAll(explicitList);
+- }
++ retval.addAll(flavorToNativeLookup(flav, false));
+ }
+ } else {
+- retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
++ retval = flavorToNativeLookup(flav, true);
+ }
+
+- getNativesForFlavorCache.put(flav, new SoftReference<>(retval));
++ nativesForFlavorCache.put(flav, retval);
+ // Create a copy, because client code can modify the returned list.
+ return new ArrayList<>(retval);
+ }
+@@ -790,62 +764,38 @@
+ * @see #encodeJavaMIMEType
+ * @since 1.4
+ */
++ @Override
+ public synchronized List<DataFlavor> getFlavorsForNative(String nat) {
++ LinkedHashSet<DataFlavor> returnValue = flavorsForNativeCache.check(nat);
++ if (returnValue != null) {
++ return new ArrayList<>(returnValue);
++ } else {
++ returnValue = new LinkedHashSet<>();
++ }
+
+- // Check cache, even for null nat
+- SoftReference<List<DataFlavor>> ref = getFlavorsForNativeCache.get(nat);
+- if (ref != null) {
+- List<DataFlavor> retval = ref.get();
+- if (retval != null) {
+- return new ArrayList<>(retval);
++ if (nat == null) {
++ for (String n : getNativesForFlavor(null)) {
++ returnValue.addAll(getFlavorsForNative(n));
++ }
++ } else {
++ final LinkedHashSet<DataFlavor> flavors = nativeToFlavorLookup(nat);
++ if (disabledMappingGenerationKeys.contains(nat)) {
++ return new ArrayList<>(flavors);
++ }
++
++ final LinkedHashSet<DataFlavor> flavorsWithSynthesized =
++ nativeToFlavorLookup(nat);
++
++ for (DataFlavor df : flavorsWithSynthesized) {
++ returnValue.add(df);
++ if ("text".equals(df.getPrimaryType())) {
++ String baseType = df.mimeType.getBaseType();
++ returnValue.addAll(convertMimeTypeToDataFlavors(baseType));
++ }
+ }
+ }
+-
+- final LinkedHashSet <DataFlavor> returnValue =
+- new LinkedHashSet<>();
+-
+- if (nat == null) {
+- final List<String> natives = getNativesForFlavor(null);
+-
+- for (String n : natives)
+- {
+- final List<DataFlavor> flavors = getFlavorsForNative(n);
+-
+- for (DataFlavor df : flavors)
+- {
+- returnValue.add(df);
+- }
+- }
+- } else {
+-
+- final List<DataFlavor> flavors = nativeToFlavorLookup(nat);
+-
+- if (disabledMappingGenerationKeys.contains(nat)) {
+- return flavors;
+- }
+-
+- final List<DataFlavor> flavorsAndBaseTypes =
+- nativeToFlavorLookup(nat);
+-
+- for (DataFlavor df : flavorsAndBaseTypes) {
+- returnValue.add(df);
+- if ("text".equals(df.getPrimaryType())) {
+- try {
+- returnValue.addAll(
+- convertMimeTypeToDataFlavors(
+- new MimeType(df.getMimeType()
+- ).getBaseType()));
+- } catch (MimeTypeParseException e) {
+- e.printStackTrace();
+- }
+- }
+- }
+-
+- }
+-
+- final List<DataFlavor> arrayList = new ArrayList<>(returnValue);
+- getFlavorsForNativeCache.put(nat, new SoftReference<>(arrayList));
+- return new ArrayList<>(arrayList);
++ flavorsForNativeCache.put(nat, returnValue);
++ return new ArrayList<>(returnValue);
+ }
+
+ private static Set<DataFlavor> convertMimeTypeToDataFlavors(
+@@ -861,7 +811,6 @@
+ } catch (MimeTypeParseException mtpe) {
+ // Cannot happen, since we checked all mappings
+ // on load from flavormap.properties.
+- assert(false);
+ }
+
+ if (DataTransferer.doesSubtypeSupportCharset(subType, null)) {
+@@ -940,10 +889,10 @@
+ }
+
+ private static final String [] htmlDocumntTypes =
+- new String [] {"all", "selection", "fragment"};
++ new String [] {"all", "selection", "fragment"};
+
+- private static LinkedHashSet<String> handleHtmlMimeTypes(
+- String baseType, String mimeType) {
++ private static LinkedHashSet<String> handleHtmlMimeTypes(String baseType,
++ String mimeType) {
+
+ LinkedHashSet<String> returnValues = new LinkedHashSet<>();
+
+@@ -980,14 +929,14 @@
+ * @see #getNativesForFlavor
+ * @see #encodeDataFlavor
+ */
+- public synchronized Map<DataFlavor,String>
+- getNativesForFlavors(DataFlavor[] flavors)
++ @Override
++ public synchronized Map<DataFlavor,String> getNativesForFlavors(DataFlavor[] flavors)
+ {
+ // Use getNativesForFlavor to generate extra natives for text flavors
+ // and stringFlavor
+
+ if (flavors == null) {
+- List flavor_list = getFlavorsForNative(null);
++ List<DataFlavor> flavor_list = getFlavorsForNative(null);
+ flavors = new DataFlavor[flavor_list.size()];
+ flavor_list.toArray(flavors);
+ }
+@@ -1026,15 +975,14 @@
+ * @see #getFlavorsForNative
+ * @see #encodeJavaMIMEType
+ */
+- public synchronized Map<String,DataFlavor>
+- getFlavorsForNatives(String[] natives)
++ @Override
++ public synchronized Map<String,DataFlavor> getFlavorsForNatives(String[] natives)
+ {
+ // Use getFlavorsForNative to generate extra flavors for text natives
+-
+ if (natives == null) {
+- List native_list = getNativesForFlavor(null);
+- natives = new String[native_list.size()];
+- native_list.toArray(natives);
++ List<String> nativesList = getNativesForFlavor(null);
++ natives = new String[nativesList.size()];
++ nativesList.toArray(natives);
+ }
+
+ Map<String, DataFlavor> retval = new HashMap<>(natives.length, 1.0f);
+@@ -1043,7 +991,6 @@
+ DataFlavor flav = (flavors.isEmpty())? null : flavors.get(0);
+ retval.put(aNative, flav);
+ }
+-
+ return retval;
+ }
+
+@@ -1069,20 +1016,16 @@
+ */
+ public synchronized void addUnencodedNativeForFlavor(DataFlavor flav,
+ String nat) {
+- if (flav == null || nat == null) {
+- throw new NullPointerException("null arguments not permitted");
+- }
++ Objects.requireNonNull(nat, "Null native not permitted");
++ Objects.requireNonNull(flav, "Null flavor not permitted");
+
+- List<String> natives = getFlavorToNative().get(flav);
++ LinkedHashSet<String> natives = getFlavorToNative().get(flav);
+ if (natives == null) {
+- natives = new ArrayList<>(1);
++ natives = new LinkedHashSet<>(1);
+ getFlavorToNative().put(flav, natives);
+- } else if (natives.contains(nat)) {
+- return;
+ }
+ natives.add(nat);
+- getNativesForFlavorCache.remove(flav);
+- getNativesForFlavorCache.remove(null);
++ nativesForFlavorCache.remove(flav);
+ }
+
+ /**
+@@ -1115,18 +1058,15 @@
+ */
+ public synchronized void setNativesForFlavor(DataFlavor flav,
+ String[] natives) {
+- if (flav == null || natives == null) {
+- throw new NullPointerException("null arguments not permitted");
+- }
++ Objects.requireNonNull(natives, "Null natives not permitted");
++ Objects.requireNonNull(flav, "Null flavors not permitted");
+
+ getFlavorToNative().remove(flav);
+ for (String aNative : natives) {
+ addUnencodedNativeForFlavor(flav, aNative);
+ }
+ disabledMappingGenerationKeys.add(flav);
+- // Clear the cache to handle the case of empty natives.
+- getNativesForFlavorCache.remove(flav);
+- getNativesForFlavorCache.remove(null);
++ nativesForFlavorCache.remove(flav);
+ }
+
+ /**
+@@ -1149,20 +1089,16 @@
+ */
+ public synchronized void addFlavorForUnencodedNative(String nat,
+ DataFlavor flav) {
+- if (nat == null || flav == null) {
+- throw new NullPointerException("null arguments not permitted");
+- }
++ Objects.requireNonNull(nat, "Null native not permitted");
++ Objects.requireNonNull(flav, "Null flavor not permitted");
+
+- List<DataFlavor> flavors = getNativeToFlavor().get(nat);
++ LinkedHashSet<DataFlavor> flavors = getNativeToFlavor().get(nat);
+ if (flavors == null) {
+- flavors = new ArrayList<>(1);
++ flavors = new LinkedHashSet<>(1);
+ getNativeToFlavor().put(nat, flavors);
+- } else if (flavors.contains(flav)) {
+- return;
+ }
+ flavors.add(flav);
+- getFlavorsForNativeCache.remove(nat);
+- getFlavorsForNativeCache.remove(null);
++ flavorsForNativeCache.remove(nat);
+ }
+
+ /**
+@@ -1194,18 +1130,15 @@
+ */
+ public synchronized void setFlavorsForNative(String nat,
+ DataFlavor[] flavors) {
+- if (nat == null || flavors == null) {
+- throw new NullPointerException("null arguments not permitted");
+- }
++ Objects.requireNonNull(nat, "Null native not permitted");
++ Objects.requireNonNull(flavors, "Null flavors not permitted");
+
+ getNativeToFlavor().remove(nat);
+ for (DataFlavor flavor : flavors) {
+ addFlavorForUnencodedNative(nat, flavor);
+ }
+ disabledMappingGenerationKeys.add(nat);
+- // Clear the cache to handle the case of empty flavors.
+- getFlavorsForNativeCache.remove(nat);
+- getFlavorsForNativeCache.remove(null);
++ flavorsForNativeCache.remove(nat);
+ }
+
+ /**
+@@ -1304,17 +1237,29 @@
+ : null;
+ }
+
+- private List<String> getAllNativesForType(String type) {
+- Set<String> retval = null;
+- for (DataFlavor dataFlavor : convertMimeTypeToDataFlavors(type)) {
+- List<String> natives = getFlavorToNative().get(dataFlavor);
+- if (natives != null && !natives.isEmpty()) {
+- if (retval == null) {
+- retval = new LinkedHashSet<>();
+- }
+- retval.addAll(natives);
++ private static final class SoftCache<K, V> {
++ Map<K, SoftReference<LinkedHashSet<V>>> cache;
++
++ public void put(K key, LinkedHashSet<V> value) {
++ if (cache == null) {
++ cache = new HashMap<>(1);
+ }
++ cache.put(key, new SoftReference<>(value));
+ }
+- return retval == null ? null : new ArrayList<>(retval);
++
++ public void remove(K key) {
++ if (cache == null) return;
++ cache.remove(null);
++ cache.remove(key);
++ }
++
++ public LinkedHashSet<V> check(K key) {
++ if (cache == null) return null;
++ SoftReference<LinkedHashSet<V>> ref = cache.get(key);
++ if (ref != null) {
++ return ref.get();
++ }
++ return null;
++ }
+ }
+ }
+--- ./jdk/src/share/classes/java/awt/datatransfer/Transferable.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/datatransfer/Transferable.java Wed Feb 04 12:14:43 2015 -0800
+@@ -32,7 +32,7 @@
+ * for a transfer operation.
+ * <p>
+ * For information on using data transfer with Swing, see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
+ * How to Use Drag and Drop and Data Transfer</a>,
+ * a section in <em>The Java Tutorial</em>, for more information.
+ *
+--- ./jdk/src/share/classes/java/awt/event/ActionEvent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/ActionEvent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -52,7 +52,7 @@
+ * in the range from {@code ACTION_FIRST} to {@code ACTION_LAST}.
+ *
+ * @see ActionListener
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html">Tutorial: How to Write an Action Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html">Tutorial: How to Write an Action Listener</a>
+ *
+ * @author Carl Quinn
+ * @since 1.1
+--- ./jdk/src/share/classes/java/awt/event/ActionListener.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/ActionListener.java Wed Feb 04 12:14:43 2015 -0800
+@@ -37,7 +37,7 @@
+ * invoked.
+ *
+ * @see ActionEvent
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html">How to Write an Action Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html">How to Write an Action Listener</a>
+ *
+ * @author Carl Quinn
+ * @since 1.1
+--- ./jdk/src/share/classes/java/awt/event/ComponentAdapter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/ComponentAdapter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -44,7 +44,7 @@
+ *
+ * @see ComponentEvent
+ * @see ComponentListener
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/componentlistener.html">Tutorial: Writing a Component Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/componentlistener.html">Tutorial: Writing a Component Listener</a>
+ *
+ * @author Carl Quinn
+ * @since 1.1
+--- ./jdk/src/share/classes/java/awt/event/ComponentEvent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/ComponentEvent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -60,7 +60,7 @@
+ *
+ * @see ComponentAdapter
+ * @see ComponentListener
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/componentlistener.html">Tutorial: Writing a Component Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/componentlistener.html">Tutorial: Writing a Component Listener</a>
+ *
+ * @author Carl Quinn
+ * @since 1.1
+--- ./jdk/src/share/classes/java/awt/event/ComponentListener.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/ComponentListener.java Wed Feb 04 12:14:43 2015 -0800
+@@ -46,7 +46,7 @@
+ *
+ * @see ComponentAdapter
+ * @see ComponentEvent
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/componentlistener.html">Tutorial: Writing a Component Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/componentlistener.html">Tutorial: Writing a Component Listener</a>
+ *
+ * @author Carl Quinn
+ * @since 1.1
+--- ./jdk/src/share/classes/java/awt/event/ContainerAdapter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/ContainerAdapter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -44,7 +44,7 @@
+ *
+ * @see ContainerEvent
+ * @see ContainerListener
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/containerlistener.html">Tutorial: Writing a Container Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/containerlistener.html">Tutorial: Writing a Container Listener</a>
+ *
+ * @author Amy Fowler
+ * @since 1.1
+--- ./jdk/src/share/classes/java/awt/event/ContainerEvent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/ContainerEvent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -52,7 +52,7 @@
+ *
+ * @see ContainerAdapter
+ * @see ContainerListener
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/containerlistener.html">Tutorial: Writing a Container Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/containerlistener.html">Tutorial: Writing a Container Listener</a>
+ *
+ * @author Tim Prinzing
+ * @author Amy Fowler
+--- ./jdk/src/share/classes/java/awt/event/ContainerListener.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/ContainerListener.java Wed Feb 04 12:14:43 2015 -0800
+@@ -46,7 +46,7 @@
+ *
+ * @see ContainerAdapter
+ * @see ContainerEvent
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/containerlistener.html">Tutorial: Writing a Container Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/containerlistener.html">Tutorial: Writing a Container Listener</a>
+ *
+ * @author Tim Prinzing
+ * @author Amy Fowler
+--- ./jdk/src/share/classes/java/awt/event/FocusAdapter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/FocusAdapter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -44,7 +44,7 @@
+ *
+ * @see FocusEvent
+ * @see FocusListener
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/focuslistener.html">Tutorial: Writing a Focus Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/focuslistener.html">Tutorial: Writing a Focus Listener</a>
+ *
+ * @author Carl Quinn
+ * @since 1.1
+--- ./jdk/src/share/classes/java/awt/event/FocusEvent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/FocusEvent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -57,7 +57,7 @@
+ *
+ * @see FocusAdapter
+ * @see FocusListener
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/focuslistener.html">Tutorial: Writing a Focus Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/focuslistener.html">Tutorial: Writing a Focus Listener</a>
+ *
+ * @author Carl Quinn
+ * @author Amy Fowler
+--- ./jdk/src/share/classes/java/awt/event/FocusListener.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/FocusListener.java Wed Feb 04 12:14:43 2015 -0800
+@@ -42,7 +42,7 @@
+ *
+ * @see FocusAdapter
+ * @see FocusEvent
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/focuslistener.html">Tutorial: Writing a Focus Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/focuslistener.html">Tutorial: Writing a Focus Listener</a>
+ *
+ * @author Carl Quinn
+ * @since 1.1
+--- ./jdk/src/share/classes/java/awt/event/ItemEvent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/ItemEvent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -58,7 +58,7 @@
+ *
+ * @see java.awt.ItemSelectable
+ * @see ItemListener
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/itemlistener.html">Tutorial: Writing an Item Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/itemlistener.html">Tutorial: Writing an Item Listener</a>
+ *
+ * @since 1.1
+ */
+--- ./jdk/src/share/classes/java/awt/event/ItemListener.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/ItemListener.java Wed Feb 04 12:14:43 2015 -0800
+@@ -40,7 +40,7 @@
+ *
+ * @see java.awt.ItemSelectable
+ * @see ItemEvent
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/itemlistener.html">Tutorial: Writing an Item Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/itemlistener.html">Tutorial: Writing an Item Listener</a>
+ *
+ * @since 1.1
+ */
+--- ./jdk/src/share/classes/java/awt/event/KeyAdapter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/KeyAdapter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -46,7 +46,7 @@
+ *
+ * @see KeyEvent
+ * @see KeyListener
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html">Tutorial: Writing a Key Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html">Tutorial: Writing a Key Listener</a>
+ *
+ * @since 1.1
+ */
+--- ./jdk/src/share/classes/java/awt/event/KeyEvent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/KeyEvent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -145,7 +145,7 @@
+ *
+ * @see KeyAdapter
+ * @see KeyListener
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html">Tutorial: Writing a Key Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html">Tutorial: Writing a Key Listener</a>
+ *
+ * @since 1.1
+ */
+--- ./jdk/src/share/classes/java/awt/event/KeyListener.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/KeyListener.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -44,7 +44,7 @@
+ *
+ * @see KeyAdapter
+ * @see KeyEvent
+- * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/keylistener.html">Tutorial: Writing a Key Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html">Tutorial: Writing a Key Listener</a>
+ *
+ * @since 1.1
+ */
+--- ./jdk/src/share/classes/java/awt/event/MouseAdapter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/MouseAdapter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -63,7 +63,7 @@
+ * @see MouseListener
+ * @see MouseMotionListener
+ * @see MouseWheelListener
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html">Tutorial: Writing a Mouse Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html">Tutorial: Writing a Mouse Listener</a>
+ *
+ * @since 1.1
+ */
+--- ./jdk/src/share/classes/java/awt/event/MouseEvent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/MouseEvent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -182,8 +182,8 @@
+ * @see MouseMotionAdapter
+ * @see MouseMotionListener
+ * @see MouseWheelListener
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html">Tutorial: Writing a Mouse Listener</a>
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/mousemotionlistener.html">Tutorial: Writing a Mouse Motion Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html">Tutorial: Writing a Mouse Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/mousemotionlistener.html">Tutorial: Writing a Mouse Motion Listener</a>
+ *
+ * @since 1.1
+ */
+--- ./jdk/src/share/classes/java/awt/event/MouseListener.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/MouseListener.java Wed Feb 04 12:14:43 2015 -0800
+@@ -50,7 +50,7 @@
+ *
+ * @see MouseAdapter
+ * @see MouseEvent
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html">Tutorial: Writing a Mouse Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html">Tutorial: Writing a Mouse Listener</a>
+ *
+ * @since 1.1
+ */
+--- ./jdk/src/share/classes/java/awt/event/MouseMotionAdapter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/MouseMotionAdapter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -49,7 +49,7 @@
+ *
+ * @see MouseEvent
+ * @see MouseMotionListener
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/mousemotionlistener.html">Tutorial: Writing a Mouse Motion Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/mousemotionlistener.html">Tutorial: Writing a Mouse Motion Listener</a>
+ *
+ * @since 1.1
+ */
+--- ./jdk/src/share/classes/java/awt/event/MouseMotionListener.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/MouseMotionListener.java Wed Feb 04 12:14:43 2015 -0800
+@@ -47,7 +47,7 @@
+ *
+ * @see MouseMotionAdapter
+ * @see MouseEvent
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/mousemotionlistener.html">Tutorial: Writing a Mouse Motion Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/mousemotionlistener.html">Tutorial: Writing a Mouse Motion Listener</a>
+ *
+ * @since 1.1
+ */
+--- ./jdk/src/share/classes/java/awt/event/WindowAdapter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/WindowAdapter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -45,7 +45,7 @@
+ *
+ * @see WindowEvent
+ * @see WindowListener
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/windowlistener.html">Tutorial: Writing a Window Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/windowlistener.html">Tutorial: Writing a Window Listener</a>
+ *
+ * @author Carl Quinn
+ * @author Amy Fowler
+--- ./jdk/src/share/classes/java/awt/event/WindowEvent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/WindowEvent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -52,7 +52,7 @@
+ *
+ * @see WindowAdapter
+ * @see WindowListener
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/windowlistener.html">Tutorial: Writing a Window Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/windowlistener.html">Tutorial: Writing a Window Listener</a>
+ *
+ * @since JDK1.1
+ */
+--- ./jdk/src/share/classes/java/awt/event/WindowFocusListener.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/WindowFocusListener.java Wed Feb 04 12:14:43 2015 -0800
+@@ -47,7 +47,7 @@
+ *
+ * @see WindowAdapter
+ * @see WindowEvent
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/windowlistener.html">Tutorial: Writing a Window Listener</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/windowlistener.html">Tutorial: Writing a Window Listener</a>
+ *
+ * @since 1.4
+ */
+--- ./jdk/src/share/classes/java/awt/event/WindowListener.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/event/WindowListener.java Wed Feb 04 12:14:43 2015 -0800
+@@ -44,7 +44,7 @@
+ *
+ * @see WindowAdapter
+ * @see WindowEvent
+- * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/windowlistener.html">Tutorial: How to Write Window Listeners</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/windowlistener.html">Tutorial: How to Write Window Listeners</a>
+ *
+ * @since 1.1
+ */
+--- ./jdk/src/share/classes/java/awt/geom/Line2D.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/awt/geom/Line2D.java Wed Feb 04 12:14:43 2015 -0800
+@@ -35,7 +35,7 @@
+ * default coordinate system called <i>user space</i> in which the y-axis
+ * values increase downward and x-axis values increase to the right. For
+ * more information on the user space coordinate system, see the
+- * <a href="http://docs.oracle.com/javase/1.3/docs/guide/2d/spec/j2d-intro.fm2.html#61857">
++ * <a href="https://docs.oracle.com/javase/1.3/docs/guide/2d/spec/j2d-intro.fm2.html#61857">
+ * Coordinate Systems</a> section of the Java 2D Programmer's Guide.
+ * <p>
+ * This class is only the abstract superclass for all objects that
+--- ./jdk/src/share/classes/java/beans/Introspector.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/beans/Introspector.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -729,27 +729,53 @@
+ if (igpd != null && ispd != null) {
+ // Complete indexed properties set
+ // Merge any classic property descriptors
+- if (gpd != null) {
+- PropertyDescriptor tpd = mergePropertyDescriptor(igpd, gpd);
+- if (tpd instanceof IndexedPropertyDescriptor) {
+- igpd = (IndexedPropertyDescriptor)tpd;
++ if ((gpd == spd) || (gpd == null)) {
++ pd = spd;
++ } else if (spd == null) {
++ pd = gpd;
++ } else if (spd instanceof IndexedPropertyDescriptor) {
++ pd = mergePropertyWithIndexedProperty(gpd, (IndexedPropertyDescriptor) spd);
++ } else if (gpd instanceof IndexedPropertyDescriptor) {
++ pd = mergePropertyWithIndexedProperty(spd, (IndexedPropertyDescriptor) gpd);
++ } else {
++ pd = mergePropertyDescriptor(gpd, spd);
++ }
++ if (igpd == ispd) {
++ ipd = igpd;
++ } else {
++ ipd = mergePropertyDescriptor(igpd, ispd);
++ }
++ if (pd == null) {
++ pd = ipd;
++ } else {
++ Class<?> propType = pd.getPropertyType();
++ Class<?> ipropType = ipd.getIndexedPropertyType();
++ if (propType.isArray() && propType.getComponentType() == ipropType) {
++ pd = pd.getClass0().isAssignableFrom(ipd.getClass0())
++ ? new IndexedPropertyDescriptor(pd, ipd)
++ : new IndexedPropertyDescriptor(ipd, pd);
++ } else if (pd.getClass0().isAssignableFrom(ipd.getClass0())) {
++ pd = pd.getClass0().isAssignableFrom(ipd.getClass0())
++ ? new PropertyDescriptor(pd, ipd)
++ : new PropertyDescriptor(ipd, pd);
++ } else {
++ pd = ipd;
+ }
+ }
+- if (spd != null) {
+- PropertyDescriptor tpd = mergePropertyDescriptor(ispd, spd);
+- if (tpd instanceof IndexedPropertyDescriptor) {
+- ispd = (IndexedPropertyDescriptor)tpd;
+- }
++ } else if (gpd != null && spd != null) {
++ if (igpd != null) {
++ gpd = mergePropertyWithIndexedProperty(gpd, igpd);
+ }
+- if (igpd == ispd) {
+- pd = igpd;
+- } else {
+- pd = mergePropertyDescriptor(igpd, ispd);
++ if (ispd != null) {
++ spd = mergePropertyWithIndexedProperty(spd, ispd);
+ }
+- } else if (gpd != null && spd != null) {
+ // Complete simple properties set
+ if (gpd == spd) {
+ pd = gpd;
++ } else if (spd instanceof IndexedPropertyDescriptor) {
++ pd = mergePropertyWithIndexedProperty(gpd, (IndexedPropertyDescriptor) spd);
++ } else if (gpd instanceof IndexedPropertyDescriptor) {
++ pd = mergePropertyWithIndexedProperty(spd, (IndexedPropertyDescriptor) gpd);
+ } else {
+ pd = mergePropertyDescriptor(gpd, spd);
+ }
+@@ -809,6 +835,16 @@
+ return ((current == null) || (candidate == null)) ? current == candidate : current.isAssignableFrom(candidate);
+ }
+
++ private PropertyDescriptor mergePropertyWithIndexedProperty(PropertyDescriptor pd, IndexedPropertyDescriptor ipd) {
++ Class<?> type = pd.getPropertyType();
++ if (type.isArray() && (type.getComponentType() == ipd.getIndexedPropertyType())) {
++ return pd.getClass0().isAssignableFrom(ipd.getClass0())
++ ? new IndexedPropertyDescriptor(pd, ipd)
++ : new IndexedPropertyDescriptor(ipd, pd);
++ }
++ return pd;
++ }
++
+ /**
+ * Adds the property descriptor to the indexedproperty descriptor only if the
+ * types are the same.
+@@ -828,6 +864,12 @@
+ } else {
+ result = new IndexedPropertyDescriptor(ipd, pd);
+ }
++ } else if ((ipd.getReadMethod() == null) && (ipd.getWriteMethod() == null)) {
++ if (pd.getClass0().isAssignableFrom(ipd.getClass0())) {
++ result = new PropertyDescriptor(pd, ipd);
++ } else {
++ result = new PropertyDescriptor(ipd, pd);
++ }
+ } else {
+ // Cannot merge the pd because of type mismatch
+ // Return the most specific pd
+@@ -879,7 +921,7 @@
+ }
+
+ // Handle regular ipd merge
+- private PropertyDescriptor mergePropertyDescriptor(IndexedPropertyDescriptor ipd1,
++ private IndexedPropertyDescriptor mergePropertyDescriptor(IndexedPropertyDescriptor ipd1,
+ IndexedPropertyDescriptor ipd2) {
+ if (ipd1.getClass0().isAssignableFrom(ipd2.getClass0())) {
+ return new IndexedPropertyDescriptor(ipd1, ipd2);
+--- ./jdk/src/share/classes/java/io/FileInputStream.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/io/FileInputStream.java Wed Feb 04 12:14:43 2015 -0800
+@@ -184,7 +184,16 @@
+ * Opens the specified file for reading.
+ * @param name the name of the file
+ */
+- private native void open(String name) throws FileNotFoundException;
++ private native void open0(String name) throws FileNotFoundException;
++
++ // wrap native call to allow instrumentation
++ /**
++ * Opens the specified file for reading.
++ * @param name the name of the file
++ */
++ private void open(String name) throws FileNotFoundException {
++ open0(name);
++ }
+
+ /**
+ * Reads a byte of data from this input stream. This method blocks
+--- ./jdk/src/share/classes/java/io/FileOutputStream.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/io/FileOutputStream.java Wed Feb 04 12:14:43 2015 -0800
+@@ -256,9 +256,20 @@
+ * @param name name of file to be opened
+ * @param append whether the file is to be opened in append mode
+ */
+- private native void open(String name, boolean append)
++ private native void open0(String name, boolean append)
+ throws FileNotFoundException;
+
++ // wrap native call to allow instrumentation
++ /**
++ * Opens a file, with the specified name, for overwriting or appending.
++ * @param name name of file to be opened
++ * @param append whether the file is to be opened in append mode
++ */
++ private void open(String name, boolean append)
++ throws FileNotFoundException {
++ open0(name, append);
++ }
++
+ /**
+ * Writes the specified byte to this file output stream.
+ *
+--- ./jdk/src/share/classes/java/io/RandomAccessFile.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/io/RandomAccessFile.java Wed Feb 04 12:14:43 2015 -0800
+@@ -296,9 +296,26 @@
+ * @param mode the mode flags, a combination of the O_ constants
+ * defined above
+ */
+- private native void open(String name, int mode)
++ private native void open0(String name, int mode)
+ throws FileNotFoundException;
+
++ // wrap native call to allow instrumentation
++ /**
++ * Opens a file and returns the file descriptor. The file is
++ * opened in read-write mode if the O_RDWR bit in {@code mode}
++ * is true, else the file is opened as read-only.
++ * If the {@code name} refers to a directory, an IOException
++ * is thrown.
++ *
++ * @param name the name of the file
++ * @param mode the mode flags, a combination of the O_ constants
++ * defined above
++ */
++ private void open(String name, int mode)
++ throws FileNotFoundException {
++ open0(name, mode);
++ }
++
+ // 'Read' primitives
+
+ /**
+--- ./jdk/src/share/classes/java/io/SequenceInputStream.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/io/SequenceInputStream.java Wed Feb 04 12:14:43 2015 -0800
+@@ -135,7 +135,7 @@
+ * @since JDK1.1
+ */
+ public int available() throws IOException {
+- if(in == null) {
++ if (in == null) {
+ return 0; // no way to signal EOF from available()
+ }
+ return in.available();
+@@ -160,15 +160,14 @@
+ * @exception IOException if an I/O error occurs.
+ */
+ public int read() throws IOException {
+- if (in == null) {
+- return -1;
++ while (in != null) {
++ int c = in.read();
++ if (c != -1) {
++ return c;
++ }
++ nextStream();
+ }
+- int c = in.read();
+- if (c == -1) {
+- nextStream();
+- return read();
+- }
+- return c;
++ return -1;
+ }
+
+ /**
+@@ -204,13 +203,14 @@
+ } else if (len == 0) {
+ return 0;
+ }
+-
+- int n = in.read(b, off, len);
+- if (n <= 0) {
++ do {
++ int n = in.read(b, off, len);
++ if (n > 0) {
++ return n;
++ }
+ nextStream();
+- return read(b, off, len);
+- }
+- return n;
++ } while (in != null);
++ return -1;
+ }
+
+ /**
+--- ./jdk/src/share/classes/java/lang/Class.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/Class.java Wed Feb 04 12:14:43 2015 -0800
+@@ -130,11 +130,15 @@
+ }
+
+ /*
+- * Constructor. Only the Java Virtual Machine creates Class
+- * objects.
++ * Private constructor. Only the Java Virtual Machine creates Class objects.
++ * This constructor is not used and prevents the default constructor being
++ * generated.
+ */
+- private Class() {}
+-
++ private Class(ClassLoader loader) {
++ // Initialize final field for classLoader. The initialization value of non-null
++ // prevents future JIT optimizations from assuming this final field is null.
++ classLoader = loader;
++ }
+
+ /**
+ * Converts the object to a string. The string representation is the
+@@ -682,8 +686,12 @@
+ }
+
+ // Package-private to allow ClassLoader access
+- native ClassLoader getClassLoader0();
+-
++ ClassLoader getClassLoader0() { return classLoader; }
++
++ // Initialized in JVM not by private constructor
++ // This field is filtered from reflection access, i.e. getDeclaredField
++ // will throw NoSuchFieldException
++ private final ClassLoader classLoader;
+
+ /**
+ * Returns an array of {@code TypeVariable} objects that represent the
+--- ./jdk/src/share/classes/java/lang/String.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/String.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1045,8 +1045,9 @@
+ }
+ }
+ // Argument is a String
+- if (cs.equals(this))
+- return true;
++ if (cs instanceof String) {
++ return equals(cs);
++ }
+ // Argument is a generic CharSequence
+ char v1[] = value;
+ int n = v1.length;
+--- ./jdk/src/share/classes/java/lang/System.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/System.java Wed Feb 04 12:14:43 2015 -0800
+@@ -584,7 +584,10 @@
+ * <tr><td><code>java.compiler</code></td>
+ * <td>Name of JIT compiler to use</td></tr>
+ * <tr><td><code>java.ext.dirs</code></td>
+- * <td>Path of extension directory or directories</td></tr>
++ * <td>Path of extension directory or directories
++ * <b>Deprecated.</b> <i>This property, and the mechanism
++ * which implements it, may be removed in a future
++ * release.</i> </td></tr>
+ * <tr><td><code>os.name</code></td>
+ * <td>Operating system name</td></tr>
+ * <tr><td><code>os.arch</code></td>
+--- ./jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java Wed Feb 04 12:14:43 2015 -0800
+@@ -26,11 +26,10 @@
+ package java.lang.invoke;
+
+ import static jdk.internal.org.objectweb.asm.Opcodes.*;
+-import static java.lang.invoke.LambdaForm.basicTypes;
+-import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic;
++import static java.lang.invoke.LambdaForm.*;
++import static java.lang.invoke.LambdaForm.BasicType.*;
+ import static java.lang.invoke.MethodHandleStatics.*;
+
+-import java.lang.invoke.LambdaForm.Name;
+ import java.lang.invoke.LambdaForm.NamedFunction;
+ import java.lang.invoke.MethodHandles.Lookup;
+ import java.lang.reflect.Field;
+@@ -51,89 +50,93 @@
+ *
+ * All bound arguments are encapsulated in dedicated species.
+ */
+-/* non-public */ abstract class BoundMethodHandle extends MethodHandle {
++/*non-public*/ abstract class BoundMethodHandle extends MethodHandle {
+
+- /* non-public */ BoundMethodHandle(MethodType type, LambdaForm form) {
++ /*non-public*/ BoundMethodHandle(MethodType type, LambdaForm form) {
+ super(type, form);
++ assert(speciesData() == speciesData(form));
+ }
+
+ //
+ // BMH API and internals
+ //
+
+- static MethodHandle bindSingle(MethodType type, LambdaForm form, char xtype, Object x) {
++ static BoundMethodHandle bindSingle(MethodType type, LambdaForm form, BasicType xtype, Object x) {
+ // for some type signatures, there exist pre-defined concrete BMH classes
+ try {
+ switch (xtype) {
+- case 'L':
+- if (true) return bindSingle(type, form, x); // Use known fast path.
+- return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('L').constructor[0].invokeBasic(type, form, x);
+- case 'I':
+- return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('I').constructor[0].invokeBasic(type, form, ValueConversions.widenSubword(x));
+- case 'J':
+- return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('J').constructor[0].invokeBasic(type, form, (long) x);
+- case 'F':
+- return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('F').constructor[0].invokeBasic(type, form, (float) x);
+- case 'D':
+- return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('D').constructor[0].invokeBasic(type, form, (double) x);
+- default : throw new InternalError("unexpected xtype: " + xtype);
++ case L_TYPE:
++ return bindSingle(type, form, x); // Use known fast path.
++ case I_TYPE:
++ return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(I_TYPE).constructor().invokeBasic(type, form, ValueConversions.widenSubword(x));
++ case J_TYPE:
++ return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(J_TYPE).constructor().invokeBasic(type, form, (long) x);
++ case F_TYPE:
++ return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(F_TYPE).constructor().invokeBasic(type, form, (float) x);
++ case D_TYPE:
++ return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(D_TYPE).constructor().invokeBasic(type, form, (double) x);
++ default : throw newInternalError("unexpected xtype: " + xtype);
+ }
+ } catch (Throwable t) {
+ throw newInternalError(t);
+ }
+ }
+
+- static MethodHandle bindSingle(MethodType type, LambdaForm form, Object x) {
+- return new Species_L(type, form, x);
++ /*non-public*/
++ LambdaFormEditor editor() {
++ return form.editor();
+ }
+
+- MethodHandle cloneExtend(MethodType type, LambdaForm form, char xtype, Object x) {
+- try {
+- switch (xtype) {
+- case 'L': return cloneExtendL(type, form, x);
+- case 'I': return cloneExtendI(type, form, ValueConversions.widenSubword(x));
+- case 'J': return cloneExtendJ(type, form, (long) x);
+- case 'F': return cloneExtendF(type, form, (float) x);
+- case 'D': return cloneExtendD(type, form, (double) x);
+- }
+- } catch (Throwable t) {
+- throw newInternalError(t);
+- }
+- throw new InternalError("unexpected type: " + xtype);
++ static BoundMethodHandle bindSingle(MethodType type, LambdaForm form, Object x) {
++ return Species_L.make(type, form, x);
++ }
++
++ @Override // there is a default binder in the super class, for 'L' types only
++ /*non-public*/
++ BoundMethodHandle bindArgumentL(int pos, Object value) {
++ return editor().bindArgumentL(this, pos, value);
++ }
++ /*non-public*/
++ BoundMethodHandle bindArgumentI(int pos, int value) {
++ return editor().bindArgumentI(this, pos, value);
++ }
++ /*non-public*/
++ BoundMethodHandle bindArgumentJ(int pos, long value) {
++ return editor().bindArgumentJ(this, pos, value);
++ }
++ /*non-public*/
++ BoundMethodHandle bindArgumentF(int pos, float value) {
++ return editor().bindArgumentF(this, pos, value);
++ }
++ /*non-public*/
++ BoundMethodHandle bindArgumentD(int pos, double value) {
++ return editor().bindArgumentD(this, pos, value);
+ }
+
+ @Override
+- MethodHandle bindArgument(int pos, char basicType, Object value) {
+- MethodType type = type().dropParameterTypes(pos, pos+1);
+- LambdaForm form = internalForm().bind(1+pos, speciesData());
+- return cloneExtend(type, form, basicType, value);
++ BoundMethodHandle rebind() {
++ if (!tooComplex()) {
++ return this;
++ }
++ return makeReinvoker(this);
+ }
+
+- @Override
+- MethodHandle dropArguments(MethodType srcType, int pos, int drops) {
+- LambdaForm form = internalForm().addArguments(pos, srcType.parameterList().subList(pos, pos+drops));
+- try {
+- return clone(srcType, form);
+- } catch (Throwable t) {
+- throw newInternalError(t);
+- }
++ private boolean tooComplex() {
++ return (fieldCount() > FIELD_COUNT_THRESHOLD ||
++ form.expressionCount() > FORM_EXPRESSION_THRESHOLD);
+ }
++ private static final int FIELD_COUNT_THRESHOLD = 12; // largest convenient BMH field count
++ private static final int FORM_EXPRESSION_THRESHOLD = 24; // largest convenient BMH expression count
+
+- @Override
+- MethodHandle permuteArguments(MethodType newType, int[] reorder) {
+- try {
+- return clone(newType, form.permuteArguments(1, reorder, basicTypes(newType.parameterList())));
+- } catch (Throwable t) {
+- throw newInternalError(t);
+- }
+- }
+-
+- static final String EXTENSION_TYPES = "LIJFD";
+- static final byte INDEX_L = 0, INDEX_I = 1, INDEX_J = 2, INDEX_F = 3, INDEX_D = 4;
+- static byte extensionIndex(char type) {
+- int i = EXTENSION_TYPES.indexOf(type);
+- if (i < 0) throw new InternalError();
+- return (byte) i;
++ /**
++ * A reinvoker MH has this form:
++ * {@code lambda (bmh, arg*) { thismh = bmh[0]; invokeBasic(thismh, arg*) }}
++ */
++ static BoundMethodHandle makeReinvoker(MethodHandle target) {
++ LambdaForm form = DelegatingMethodHandle.makeReinvokerForm(
++ target, MethodTypeForm.LF_REBIND,
++ Species_L.SPECIES_DATA, Species_L.SPECIES_DATA.getterFunction(0));
++ return Species_L.make(target.type(), form, target);
+ }
+
+ /**
+@@ -142,9 +145,22 @@
+ */
+ /*non-public*/ abstract SpeciesData speciesData();
+
++ /*non-public*/ static SpeciesData speciesData(LambdaForm form) {
++ Object c = form.names[0].constraint;
++ if (c instanceof SpeciesData)
++ return (SpeciesData) c;
++ // if there is no BMH constraint, then use the null constraint
++ return SpeciesData.EMPTY;
++ }
++
++ /**
++ * Return the number of fields in this BMH. Equivalent to speciesData().fieldCount().
++ */
++ /*non-public*/ abstract int fieldCount();
++
+ @Override
+- final Object internalProperties() {
+- return "/BMH="+internalValues();
++ Object internalProperties() {
++ return "\n& BMH="+internalValues();
+ }
+
+ @Override
+@@ -159,42 +175,28 @@
+ /*non-public*/ final Object arg(int i) {
+ try {
+ switch (speciesData().fieldType(i)) {
+- case 'L': return argL(i);
+- case 'I': return argI(i);
+- case 'F': return argF(i);
+- case 'D': return argD(i);
+- case 'J': return argJ(i);
++ case L_TYPE: return speciesData().getters[i].invokeBasic(this);
++ case I_TYPE: return (int) speciesData().getters[i].invokeBasic(this);
++ case J_TYPE: return (long) speciesData().getters[i].invokeBasic(this);
++ case F_TYPE: return (float) speciesData().getters[i].invokeBasic(this);
++ case D_TYPE: return (double) speciesData().getters[i].invokeBasic(this);
+ }
+ } catch (Throwable ex) {
+ throw newInternalError(ex);
+ }
+- throw new InternalError("unexpected type: " + speciesData().types+"."+i);
++ throw new InternalError("unexpected type: " + speciesData().typeChars+"."+i);
+ }
+- /*non-public*/ final Object argL(int i) throws Throwable { return speciesData().getters[i].invokeBasic(this); }
+- /*non-public*/ final int argI(int i) throws Throwable { return (int) speciesData().getters[i].invokeBasic(this); }
+- /*non-public*/ final float argF(int i) throws Throwable { return (float) speciesData().getters[i].invokeBasic(this); }
+- /*non-public*/ final double argD(int i) throws Throwable { return (double) speciesData().getters[i].invokeBasic(this); }
+- /*non-public*/ final long argJ(int i) throws Throwable { return (long) speciesData().getters[i].invokeBasic(this); }
+
+ //
+ // cloning API
+ //
+
+- /*non-public*/ abstract BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable;
+- /*non-public*/ abstract BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable;
+- /*non-public*/ abstract BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable;
+- /*non-public*/ abstract BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable;
+- /*non-public*/ abstract BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable;
+- /*non-public*/ abstract BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable;
+-
+- // The following is a grossly irregular hack:
+- @Override MethodHandle reinvokerTarget() {
+- try {
+- return (MethodHandle) argL(0);
+- } catch (Throwable ex) {
+- throw newInternalError(ex);
+- }
+- }
++ /*non-public*/ abstract BoundMethodHandle copyWith(MethodType mt, LambdaForm lf);
++ /*non-public*/ abstract BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg);
++ /*non-public*/ abstract BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg);
++ /*non-public*/ abstract BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg);
++ /*non-public*/ abstract BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg);
++ /*non-public*/ abstract BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg);
+
+ //
+ // concrete BMH classes required to close bootstrap loops
+@@ -203,150 +205,110 @@
+ private // make it private to force users to access the enclosing class first
+ static final class Species_L extends BoundMethodHandle {
+ final Object argL0;
+- /*non-public*/ Species_L(MethodType mt, LambdaForm lf, Object argL0) {
++ private Species_L(MethodType mt, LambdaForm lf, Object argL0) {
+ super(mt, lf);
+ this.argL0 = argL0;
+ }
+- // The following is a grossly irregular hack:
+- @Override MethodHandle reinvokerTarget() { return (MethodHandle) argL0; }
+ @Override
+ /*non-public*/ SpeciesData speciesData() {
+ return SPECIES_DATA;
+ }
++ @Override
++ /*non-public*/ int fieldCount() {
++ return 1;
++ }
+ /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class);
+- @Override
+- /*non-public*/ final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable {
++ /*non-public*/ static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0) {
+ return new Species_L(mt, lf, argL0);
+ }
+ @Override
+- /*non-public*/ final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable {
+- return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, narg);
++ /*non-public*/ final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) {
++ return new Species_L(mt, lf, argL0);
+ }
+ @Override
+- /*non-public*/ final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable {
+- return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, narg);
++ /*non-public*/ final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
++ try {
++ return (BoundMethodHandle) SPECIES_DATA.extendWith(L_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
++ } catch (Throwable ex) {
++ throw uncaughtException(ex);
++ }
+ }
+ @Override
+- /*non-public*/ final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable {
+- return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, narg);
++ /*non-public*/ final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
++ try {
++ return (BoundMethodHandle) SPECIES_DATA.extendWith(I_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
++ } catch (Throwable ex) {
++ throw uncaughtException(ex);
++ }
+ }
+ @Override
+- /*non-public*/ final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable {
+- return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, narg);
++ /*non-public*/ final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
++ try {
++ return (BoundMethodHandle) SPECIES_DATA.extendWith(J_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
++ } catch (Throwable ex) {
++ throw uncaughtException(ex);
++ }
+ }
+ @Override
+- /*non-public*/ final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable {
+- return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, narg);
++ /*non-public*/ final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
++ try {
++ return (BoundMethodHandle) SPECIES_DATA.extendWith(F_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
++ } catch (Throwable ex) {
++ throw uncaughtException(ex);
++ }
++ }
++ @Override
++ /*non-public*/ final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
++ try {
++ return (BoundMethodHandle) SPECIES_DATA.extendWith(D_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
++ } catch (Throwable ex) {
++ throw uncaughtException(ex);
++ }
+ }
+ }
+
+-/*
+- static final class Species_LL extends BoundMethodHandle {
+- final Object argL0;
+- final Object argL1;
+- public Species_LL(MethodType mt, LambdaForm lf, Object argL0, Object argL1) {
+- super(mt, lf);
+- this.argL0 = argL0;
+- this.argL1 = argL1;
+- }
+- @Override
+- public SpeciesData speciesData() {
+- return SPECIES_DATA;
+- }
+- public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LL", Species_LL.class);
+- @Override
+- public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable {
+- return new Species_LL(mt, lf, argL0, argL1);
+- }
+- @Override
+- public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable {
+- return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg);
+- }
+- @Override
+- public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable {
+- return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg);
+- }
+- @Override
+- public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable {
+- return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg);
+- }
+- @Override
+- public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable {
+- return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg);
+- }
+- @Override
+- public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable {
+- return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg);
+- }
+- }
+-
+- static final class Species_JL extends BoundMethodHandle {
+- final long argJ0;
+- final Object argL1;
+- public Species_JL(MethodType mt, LambdaForm lf, long argJ0, Object argL1) {
+- super(mt, lf);
+- this.argJ0 = argJ0;
+- this.argL1 = argL1;
+- }
+- @Override
+- public SpeciesData speciesData() {
+- return SPECIES_DATA;
+- }
+- public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("JL", Species_JL.class);
+- @Override public final long argJ0() { return argJ0; }
+- @Override public final Object argL1() { return argL1; }
+- @Override
+- public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable {
+- return new Species_JL(mt, lf, argJ0, argL1);
+- }
+- @Override
+- public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable {
+- return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg);
+- }
+- @Override
+- public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable {
+- return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg);
+- }
+- @Override
+- public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable {
+- return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg);
+- }
+- @Override
+- public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable {
+- return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg);
+- }
+- @Override
+- public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable {
+- return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg);
+- }
+- }
+-*/
+-
+ //
+ // BMH species meta-data
+ //
+
+ /**
+- * Meta-data wrapper for concrete BMH classes.
++ * Meta-data wrapper for concrete BMH types.
++ * Each BMH type corresponds to a given sequence of basic field types (LIJFD).
++ * The fields are immutable; their values are fully specified at object construction.
++ * Each BMH type supplies an array of getter functions which may be used in lambda forms.
++ * A BMH is constructed by cloning a shorter BMH and adding one or more new field values.
++ * The shortest possible BMH has zero fields; its class is SimpleMethodHandle.
++ * BMH species are not interrelated by subtyping, even though it would appear that
++ * a shorter BMH could serve as a supertype of a longer one which extends it.
+ */
+ static class SpeciesData {
+- final String types;
+- final Class<? extends BoundMethodHandle> clazz;
++ private final String typeChars;
++ private final BasicType[] typeCodes;
++ private final Class<? extends BoundMethodHandle> clazz;
+ // Bootstrapping requires circular relations MH -> BMH -> SpeciesData -> MH
+ // Therefore, we need a non-final link in the chain. Use array elements.
+- final MethodHandle[] constructor;
+- final MethodHandle[] getters;
+- final SpeciesData[] extensions;
++ @Stable private final MethodHandle[] constructor;
++ @Stable private final MethodHandle[] getters;
++ @Stable private final NamedFunction[] nominalGetters;
++ @Stable private final SpeciesData[] extensions;
+
+ /*non-public*/ int fieldCount() {
+- return types.length();
++ return typeCodes.length;
+ }
+- /*non-public*/ char fieldType(int i) {
+- return types.charAt(i);
++ /*non-public*/ BasicType fieldType(int i) {
++ return typeCodes[i];
+ }
+-
++ /*non-public*/ char fieldTypeChar(int i) {
++ return typeChars.charAt(i);
++ }
++ Object fieldSignature() {
++ return typeChars;
++ }
++ public Class<? extends BoundMethodHandle> fieldHolder() {
++ return clazz;
++ }
+ public String toString() {
+- return "SpeciesData["+(isPlaceholder() ? "<placeholder>" : clazz.getSimpleName())+":"+types+"]";
++ return "SpeciesData<"+fieldSignature()+">";
+ }
+
+ /**
+@@ -354,45 +316,59 @@
+ * represents a MH bound to a generic invoker, which in turn forwards to the corresponding
+ * getter.
+ */
+- Name getterName(Name mhName, int i) {
+- MethodHandle mh = getters[i];
+- assert(mh != null) : this+"."+i;
+- return new Name(mh, mhName);
++ NamedFunction getterFunction(int i) {
++ NamedFunction nf = nominalGetters[i];
++ assert(nf.memberDeclaringClassOrNull() == fieldHolder());
++ assert(nf.returnType() == fieldType(i));
++ return nf;
+ }
+
+- NamedFunction getterFunction(int i) {
+- return new NamedFunction(getters[i]);
++ NamedFunction[] getterFunctions() {
++ return nominalGetters;
++ }
++
++ MethodHandle[] getterHandles() { return getters; }
++
++ MethodHandle constructor() {
++ return constructor[0];
+ }
+
+ static final SpeciesData EMPTY = new SpeciesData("", BoundMethodHandle.class);
+
+ private SpeciesData(String types, Class<? extends BoundMethodHandle> clazz) {
+- this.types = types;
++ this.typeChars = types;
++ this.typeCodes = basicTypes(types);
+ this.clazz = clazz;
+ if (!INIT_DONE) {
+- this.constructor = new MethodHandle[1];
++ this.constructor = new MethodHandle[1]; // only one ctor
+ this.getters = new MethodHandle[types.length()];
++ this.nominalGetters = new NamedFunction[types.length()];
+ } else {
+ this.constructor = Factory.makeCtors(clazz, types, null);
+ this.getters = Factory.makeGetters(clazz, types, null);
++ this.nominalGetters = Factory.makeNominalGetters(types, null, this.getters);
+ }
+- this.extensions = new SpeciesData[EXTENSION_TYPES.length()];
++ this.extensions = new SpeciesData[ARG_TYPE_LIMIT];
+ }
+
+ private void initForBootstrap() {
+ assert(!INIT_DONE);
+- if (constructor[0] == null) {
++ if (constructor() == null) {
++ String types = typeChars;
+ Factory.makeCtors(clazz, types, this.constructor);
+ Factory.makeGetters(clazz, types, this.getters);
++ Factory.makeNominalGetters(types, this.nominalGetters, this.getters);
+ }
+ }
+
+- private SpeciesData(String types) {
++ private SpeciesData(String typeChars) {
+ // Placeholder only.
+- this.types = types;
++ this.typeChars = typeChars;
++ this.typeCodes = basicTypes(typeChars);
+ this.clazz = null;
+ this.constructor = null;
+ this.getters = null;
++ this.nominalGetters = null;
+ this.extensions = null;
+ }
+ private boolean isPlaceholder() { return clazz == null; }
+@@ -401,18 +377,15 @@
+ static { CACHE.put("", EMPTY); } // make bootstrap predictable
+ private static final boolean INIT_DONE; // set after <clinit> finishes...
+
+- SpeciesData extendWithType(char type) {
+- int i = extensionIndex(type);
+- SpeciesData d = extensions[i];
+- if (d != null) return d;
+- extensions[i] = d = get(types+type);
+- return d;
++ SpeciesData extendWith(byte type) {
++ return extendWith(BasicType.basicType(type));
+ }
+
+- SpeciesData extendWithIndex(byte index) {
+- SpeciesData d = extensions[index];
++ SpeciesData extendWith(BasicType type) {
++ int ord = type.ordinal();
++ SpeciesData d = extensions[ord];
+ if (d != null) return d;
+- extensions[index] = d = get(types+EXTENSION_TYPES.charAt(index));
++ extensions[ord] = d = get(typeChars+type.basicTypeChar());
+ return d;
+ }
+
+@@ -456,8 +429,6 @@
+ static {
+ // pre-fill the BMH speciesdata cache with BMH's inner classes
+ final Class<BoundMethodHandle> rootCls = BoundMethodHandle.class;
+- SpeciesData d0 = BoundMethodHandle.SPECIES_DATA; // trigger class init
+- assert(d0 == null || d0 == lookupCache("")) : d0;
+ try {
+ for (Class<?> c : rootCls.getDeclaredClasses()) {
+ if (rootCls.isAssignableFrom(c)) {
+@@ -465,7 +436,7 @@
+ SpeciesData d = Factory.speciesDataFromConcreteBMHClass(cbmh);
+ assert(d != null) : cbmh.getName();
+ assert(d.clazz == cbmh);
+- assert(d == lookupCache(d.types));
++ assert(d == lookupCache(d.typeChars));
+ }
+ }
+ } catch (Throwable e) {
+@@ -516,11 +487,10 @@
+ static final String BMHSPECIES_DATA_GFC_SIG = "(" + JLS_SIG + JLC_SIG + ")" + SPECIES_DATA_SIG;
+ static final String MYSPECIES_DATA_SIG = "()" + SPECIES_DATA_SIG;
+ static final String VOID_SIG = "()V";
++ static final String INT_SIG = "()I";
+
+ static final String SIG_INCIPIT = "(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;";
+
+- static final Class<?>[] TYPES = new Class<?>[] { Object.class, int.class, long.class, float.class, double.class };
+-
+ static final String[] E_THROWABLE = new String[] { "java/lang/Throwable" };
+
+ /**
+@@ -551,31 +521,35 @@
+ * final Object argL0;
+ * final Object argL1;
+ * final int argI2;
+- * Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
++ * private Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
+ * super(mt, lf);
+ * this.argL0 = argL0;
+ * this.argL1 = argL1;
+ * this.argI2 = argI2;
+ * }
+ * final SpeciesData speciesData() { return SPECIES_DATA; }
++ * final int fieldCount() { return 3; }
+ * static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LLI", Species_LLI.class);
+- * final BoundMethodHandle clone(MethodType mt, LambdaForm lf) {
+- * return SPECIES_DATA.constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2);
++ * static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
++ * return new Species_LLI(mt, lf, argL0, argL1, argI2);
+ * }
+- * final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) {
+- * return SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
++ * final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) {
++ * return new Species_LLI(mt, lf, argL0, argL1, argI2);
+ * }
+- * final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) {
+- * return SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
++ * final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
++ * return SPECIES_DATA.extendWith(L_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
+ * }
+- * final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) {
+- * return SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
++ * final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
++ * return SPECIES_DATA.extendWith(I_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
+ * }
+- * final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) {
+- * return SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
++ * final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
++ * return SPECIES_DATA.extendWith(J_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
+ * }
+- * final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) {
+- * return SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
++ * final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
++ * return SPECIES_DATA.extendWith(F_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
++ * }
++ * public final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
++ * return SPECIES_DATA.extendWith(D_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
+ * }
+ * }
+ * </pre>
+@@ -586,8 +560,9 @@
+ static Class<? extends BoundMethodHandle> generateConcreteBMHClass(String types) {
+ final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
+
+- final String className = SPECIES_PREFIX_PATH + types;
+- final String sourceFile = SPECIES_PREFIX_NAME + types;
++ String shortTypes = LambdaForm.shortenSignature(types);
++ final String className = SPECIES_PREFIX_PATH + shortTypes;
++ final String sourceFile = SPECIES_PREFIX_NAME + shortTypes;
+ final int NOT_ACC_PUBLIC = 0; // not ACC_PUBLIC
+ cw.visit(V1_6, NOT_ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, BMH, null);
+ cw.visitSource(sourceFile, null);
+@@ -606,13 +581,13 @@
+ MethodVisitor mv;
+
+ // emit constructor
+- mv = cw.visitMethod(NOT_ACC_PUBLIC, "<init>", makeSignature(types, true), null, null);
++ mv = cw.visitMethod(ACC_PRIVATE, "<init>", makeSignature(types, true), null, null);
+ mv.visitCode();
+- mv.visitVarInsn(ALOAD, 0);
+- mv.visitVarInsn(ALOAD, 1);
+- mv.visitVarInsn(ALOAD, 2);
++ mv.visitVarInsn(ALOAD, 0); // this
++ mv.visitVarInsn(ALOAD, 1); // type
++ mv.visitVarInsn(ALOAD, 2); // form
+
+- mv.visitMethodInsn(INVOKESPECIAL, BMH, "<init>", makeSignature("", true));
++ mv.visitMethodInsn(INVOKESPECIAL, BMH, "<init>", makeSignature("", true), false);
+
+ for (int i = 0, j = 0; i < types.length(); ++i, ++j) {
+ // i counts the arguments, j counts corresponding argument slots
+@@ -629,16 +604,6 @@
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+- // emit implementation of reinvokerTarget()
+- mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "reinvokerTarget", "()" + MH_SIG, null, null);
+- mv.visitCode();
+- mv.visitVarInsn(ALOAD, 0);
+- mv.visitFieldInsn(GETFIELD, className, "argL0", JLO_SIG);
+- mv.visitTypeInsn(CHECKCAST, MH);
+- mv.visitInsn(ARETURN);
+- mv.visitMaxs(0, 0);
+- mv.visitEnd();
+-
+ // emit implementation of speciesData()
+ mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "speciesData", MYSPECIES_DATA_SIG, null, null);
+ mv.visitCode();
+@@ -647,51 +612,83 @@
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+- // emit clone()
+- mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "clone", makeSignature("", false), null, E_THROWABLE);
++ // emit implementation of fieldCount()
++ mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "fieldCount", INT_SIG, null, null);
+ mv.visitCode();
+- // return speciesData().constructor[0].invokeBasic(mt, lf, argL0, ...)
+- // obtain constructor
+- mv.visitVarInsn(ALOAD, 0);
+- mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
+- mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG);
+- mv.visitInsn(ICONST_0);
+- mv.visitInsn(AALOAD);
++ int fc = types.length();
++ if (fc <= (ICONST_5 - ICONST_0)) {
++ mv.visitInsn(ICONST_0 + fc);
++ } else {
++ mv.visitIntInsn(SIPUSH, fc);
++ }
++ mv.visitInsn(IRETURN);
++ mv.visitMaxs(0, 0);
++ mv.visitEnd();
++ // emit make() ...factory method wrapping constructor
++ mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_STATIC, "make", makeSignature(types, false), null, null);
++ mv.visitCode();
++ // make instance
++ mv.visitTypeInsn(NEW, className);
++ mv.visitInsn(DUP);
++ // load mt, lf
++ mv.visitVarInsn(ALOAD, 0); // type
++ mv.visitVarInsn(ALOAD, 1); // form
++ // load factory method arguments
++ for (int i = 0, j = 0; i < types.length(); ++i, ++j) {
++ // i counts the arguments, j counts corresponding argument slots
++ char t = types.charAt(i);
++ mv.visitVarInsn(typeLoadOp(t), j + 2); // parameters start at 3
++ if (t == 'J' || t == 'D') {
++ ++j; // adjust argument register access
++ }
++ }
++
++ // finally, invoke the constructor and return
++ mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true), false);
++ mv.visitInsn(ARETURN);
++ mv.visitMaxs(0, 0);
++ mv.visitEnd();
++
++ // emit copyWith()
++ mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "copyWith", makeSignature("", false), null, null);
++ mv.visitCode();
++ // make instance
++ mv.visitTypeInsn(NEW, className);
++ mv.visitInsn(DUP);
+ // load mt, lf
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitVarInsn(ALOAD, 2);
+ // put fields on the stack
+ emitPushFields(types, className, mv);
+ // finally, invoke the constructor and return
+- mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types, false));
++ mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true), false);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+- // for each type, emit cloneExtendT()
+- for (Class<?> c : TYPES) {
+- char t = Wrapper.basicTypeChar(c);
+- mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "cloneExtend" + t, makeSignature(String.valueOf(t), false), null, E_THROWABLE);
++ // for each type, emit copyWithExtendT()
++ for (BasicType type : BasicType.ARG_TYPES) {
++ int ord = type.ordinal();
++ char btChar = type.basicTypeChar();
++ mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "copyWithExtend" + btChar, makeSignature(String.valueOf(btChar), false), null, E_THROWABLE);
+ mv.visitCode();
+- // return SPECIES_DATA.extendWithIndex(extensionIndex(t)).constructor[0].invokeBasic(mt, lf, argL0, ..., narg)
++ // return SPECIES_DATA.extendWith(t).constructor().invokeBasic(mt, lf, argL0, ..., narg)
+ // obtain constructor
+ mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
+- int iconstInsn = ICONST_0 + extensionIndex(t);
++ int iconstInsn = ICONST_0 + ord;
+ assert(iconstInsn <= ICONST_5);
+ mv.visitInsn(iconstInsn);
+- mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "extendWithIndex", BMHSPECIES_DATA_EWI_SIG);
+- mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG);
+- mv.visitInsn(ICONST_0);
+- mv.visitInsn(AALOAD);
++ mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "extendWith", BMHSPECIES_DATA_EWI_SIG, false);
++ mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "constructor", "()" + MH_SIG, false);
+ // load mt, lf
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitVarInsn(ALOAD, 2);
+ // put fields on the stack
+ emitPushFields(types, className, mv);
+ // put narg on stack
+- mv.visitVarInsn(typeLoadOp(t), 3);
++ mv.visitVarInsn(typeLoadOp(btChar), 3);
+ // finally, invoke the constructor and return
+- mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types + t, false));
++ mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types + btChar, false), false);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+@@ -702,7 +699,7 @@
+ mv.visitCode();
+ mv.visitLdcInsn(types);
+ mv.visitLdcInsn(Type.getObjectType(className));
+- mv.visitMethodInsn(INVOKESTATIC, SPECIES_DATA, "getForClass", BMHSPECIES_DATA_GFC_SIG);
++ mv.visitMethodInsn(INVOKESTATIC, SPECIES_DATA, "getForClass", BMHSPECIES_DATA_GFC_SIG, false);
+ mv.visitFieldInsn(PUTSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(0, 0);
+@@ -730,7 +727,7 @@
+ case 'J': return LLOAD;
+ case 'F': return FLOAD;
+ case 'D': return DLOAD;
+- default : throw new InternalError("unrecognized type " + t);
++ default : throw newInternalError("unrecognized type " + t);
+ }
+ }
+
+@@ -771,10 +768,19 @@
+
+ static MethodHandle[] makeCtors(Class<? extends BoundMethodHandle> cbmh, String types, MethodHandle mhs[]) {
+ if (mhs == null) mhs = new MethodHandle[1];
++ if (types.equals("")) return mhs; // hack for empty BMH species
+ mhs[0] = makeCbmhCtor(cbmh, types);
+ return mhs;
+ }
+
++ static NamedFunction[] makeNominalGetters(String types, NamedFunction[] nfs, MethodHandle[] getters) {
++ if (nfs == null) nfs = new NamedFunction[types.length()];
++ for (int i = 0; i < nfs.length; ++i) {
++ nfs[i] = new NamedFunction(getters[i]);
++ }
++ return nfs;
++ }
++
+ //
+ // Auxiliary methods.
+ //
+@@ -808,52 +814,11 @@
+
+ static MethodHandle makeCbmhCtor(Class<? extends BoundMethodHandle> cbmh, String types) {
+ try {
+- return linkConstructor(LOOKUP.findConstructor(cbmh, MethodType.fromMethodDescriptorString(makeSignature(types, true), null)));
++ return LOOKUP.findStatic(cbmh, "make", MethodType.fromMethodDescriptorString(makeSignature(types, false), null));
+ } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | TypeNotPresentException e) {
+ throw newInternalError(e);
+ }
+ }
+-
+- /**
+- * Wrap a constructor call in a {@link LambdaForm}.
+- *
+- * If constructors ({@code <init>} methods) are called in LFs, problems might arise if the LFs
+- * are turned into bytecode, because the call to the allocator is routed through an MH, and the
+- * verifier cannot find a {@code NEW} instruction preceding the {@code INVOKESPECIAL} to
+- * {@code <init>}. To avoid this, we add an indirection by invoking {@code <init>} through
+- * {@link MethodHandle#linkToSpecial}.
+- *
+- * The last {@link LambdaForm.Name Name} in the argument's form is expected to be the {@code void}
+- * result of the {@code <init>} invocation. This entry is replaced.
+- */
+- private static MethodHandle linkConstructor(MethodHandle cmh) {
+- final LambdaForm lf = cmh.form;
+- final int initNameIndex = lf.names.length - 1;
+- final Name initName = lf.names[initNameIndex];
+- final MemberName ctorMN = initName.function.member;
+- final MethodType ctorMT = ctorMN.getInvocationType();
+-
+- // obtain function member (call target)
+- // linker method type replaces initial parameter (BMH species) with BMH to avoid naming a species (anonymous class!)
+- final MethodType linkerMT = ctorMT.changeParameterType(0, BoundMethodHandle.class).appendParameterTypes(MemberName.class);
+- MemberName linkerMN = new MemberName(MethodHandle.class, "linkToSpecial", linkerMT, REF_invokeStatic);
+- try {
+- linkerMN = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linkerMN, null, NoSuchMethodException.class);
+- assert(linkerMN.isStatic());
+- } catch (ReflectiveOperationException ex) {
+- throw newInternalError(ex);
+- }
+- // extend arguments array
+- Object[] newArgs = Arrays.copyOf(initName.arguments, initName.arguments.length + 1);
+- newArgs[newArgs.length - 1] = ctorMN;
+- // replace function
+- final NamedFunction nf = new NamedFunction(linkerMN);
+- final Name linkedCtor = new Name(nf, newArgs);
+- linkedCtor.initIndex(initNameIndex);
+- lf.names[initNameIndex] = linkedCtor;
+- return cmh;
+- }
+-
+ }
+
+ private static final Lookup LOOKUP = Lookup.IMPL_LOOKUP;
+--- ./jdk/src/share/classes/java/lang/invoke/CallSite.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/CallSite.java Wed Feb 04 12:14:43 2015 -0800
+@@ -102,7 +102,7 @@
+ */
+ /*package-private*/
+ CallSite(MethodType type) {
+- target = type.invokers().uninitializedCallSite();
++ target = makeUninitializedCallSite(type);
+ }
+
+ /**
+@@ -211,27 +211,40 @@
+ public abstract MethodHandle dynamicInvoker();
+
+ /*non-public*/ MethodHandle makeDynamicInvoker() {
+- MethodHandle getTarget = GET_TARGET.bindReceiver(this);
++ MethodHandle getTarget = GET_TARGET.bindArgumentL(0, this);
+ MethodHandle invoker = MethodHandles.exactInvoker(this.type());
+ return MethodHandles.foldArguments(invoker, getTarget);
+ }
+
+ private static final MethodHandle GET_TARGET;
++ private static final MethodHandle THROW_UCS;
+ static {
+ try {
+ GET_TARGET = IMPL_LOOKUP.
+ findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
++ THROW_UCS = IMPL_LOOKUP.
++ findStatic(CallSite.class, "uninitializedCallSite", MethodType.methodType(Object.class, Object[].class));
+ } catch (ReflectiveOperationException e) {
+ throw newInternalError(e);
+ }
+ }
+
+ /** This guy is rolled into the default target if a MethodType is supplied to the constructor. */
+- /*package-private*/
+- static Empty uninitializedCallSite() {
++ private static Object uninitializedCallSite(Object... ignore) {
+ throw new IllegalStateException("uninitialized call site");
+ }
+
++ private MethodHandle makeUninitializedCallSite(MethodType targetType) {
++ MethodType basicType = targetType.basicType();
++ MethodHandle invoker = basicType.form().cachedMethodHandle(MethodTypeForm.MH_UNINIT_CS);
++ if (invoker == null) {
++ invoker = THROW_UCS.asType(basicType);
++ invoker = basicType.form().setCachedMethodHandle(MethodTypeForm.MH_UNINIT_CS, invoker);
++ }
++ // unchecked view is OK since no values will be received or returned
++ return invoker.viewAsType(targetType, false);
++ }
++
+ // unsafe stuff:
+ private static final long TARGET_OFFSET;
+ static {
+@@ -319,7 +332,7 @@
+ throw new ClassCastException("bootstrap method failed to produce a CallSite");
+ }
+ if (!site.getTarget().type().equals(type))
+- throw new WrongMethodTypeException("wrong type: "+site.getTarget());
++ throw wrongTargetType(site.getTarget(), type);
+ } catch (Throwable ex) {
+ BootstrapMethodError bex;
+ if (ex instanceof BootstrapMethodError)
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/src/share/classes/java/lang/invoke/DelegatingMethodHandle.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,164 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 java.lang.invoke;
++
++import java.util.Arrays;
++import static java.lang.invoke.LambdaForm.*;
++import static java.lang.invoke.MethodHandleStatics.*;
++
++/**
++ * A method handle whose invocation behavior is determined by a target.
++ * The delegating MH itself can hold extra "intentions" beyond the simple behavior.
++ * @author jrose
++ */
++/*non-public*/
++abstract class DelegatingMethodHandle extends MethodHandle {
++ protected DelegatingMethodHandle(MethodHandle target) {
++ this(target.type(), target);
++ }
++
++ protected DelegatingMethodHandle(MethodType type, MethodHandle target) {
++ super(type, chooseDelegatingForm(target));
++ }
++
++ protected DelegatingMethodHandle(MethodType type, LambdaForm form) {
++ super(type, form);
++ }
++
++ /** Define this to extract the delegated target which supplies the invocation behavior. */
++ abstract protected MethodHandle getTarget();
++
++ @Override
++ abstract MethodHandle asTypeUncached(MethodType newType);
++
++ @Override
++ MemberName internalMemberName() {
++ return getTarget().internalMemberName();
++ }
++
++ @Override
++ boolean isInvokeSpecial() {
++ return getTarget().isInvokeSpecial();
++ }
++
++ @Override
++ Class<?> internalCallerClass() {
++ return getTarget().internalCallerClass();
++ }
++
++ @Override
++ MethodHandle copyWith(MethodType mt, LambdaForm lf) {
++ // FIXME: rethink 'copyWith' protocol; it is too low-level for use on all MHs
++ throw newIllegalArgumentException("do not use this");
++ }
++
++ @Override
++ String internalProperties() {
++ return "\n& Class="+getClass().getSimpleName()+
++ "\n& Target="+getTarget().debugString();
++ }
++
++ @Override
++ BoundMethodHandle rebind() {
++ return getTarget().rebind();
++ }
++
++ private static LambdaForm chooseDelegatingForm(MethodHandle target) {
++ if (target instanceof SimpleMethodHandle)
++ return target.internalForm(); // no need for an indirection
++ return makeReinvokerForm(target, MethodTypeForm.LF_DELEGATE, DelegatingMethodHandle.class, NF_getTarget);
++ }
++
++ static LambdaForm makeReinvokerForm(MethodHandle target,
++ int whichCache,
++ Object constraint,
++ NamedFunction getTargetFn) {
++ String debugString;
++ switch(whichCache) {
++ case MethodTypeForm.LF_REBIND: debugString = "BMH.reinvoke"; break;
++ case MethodTypeForm.LF_DELEGATE: debugString = "MH.delegate"; break;
++ default: debugString = "MH.reinvoke"; break;
++ }
++ // No pre-action needed.
++ return makeReinvokerForm(target, whichCache, constraint, debugString, true, getTargetFn, null);
++ }
++ /** Create a LF which simply reinvokes a target of the given basic type. */
++ static LambdaForm makeReinvokerForm(MethodHandle target,
++ int whichCache,
++ Object constraint,
++ String debugString,
++ boolean forceInline,
++ NamedFunction getTargetFn,
++ NamedFunction preActionFn) {
++ MethodType mtype = target.type().basicType();
++ boolean customized = (whichCache < 0 ||
++ mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY);
++ boolean hasPreAction = (preActionFn != null);
++ LambdaForm form;
++ if (!customized) {
++ form = mtype.form().cachedLambdaForm(whichCache);
++ if (form != null) return form;
++ }
++ final int THIS_DMH = 0;
++ final int ARG_BASE = 1;
++ final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
++ int nameCursor = ARG_LIMIT;
++ final int PRE_ACTION = hasPreAction ? nameCursor++ : -1;
++ final int NEXT_MH = customized ? -1 : nameCursor++;
++ final int REINVOKE = nameCursor++;
++ LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
++ assert(names.length == nameCursor);
++ names[THIS_DMH] = names[THIS_DMH].withConstraint(constraint);
++ Object[] targetArgs;
++ if (hasPreAction) {
++ names[PRE_ACTION] = new LambdaForm.Name(preActionFn, names[THIS_DMH]);
++ }
++ if (customized) {
++ targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class);
++ names[REINVOKE] = new LambdaForm.Name(target, targetArgs); // the invoker is the target itself
++ } else {
++ names[NEXT_MH] = new LambdaForm.Name(getTargetFn, names[THIS_DMH]);
++ targetArgs = Arrays.copyOfRange(names, THIS_DMH, ARG_LIMIT, Object[].class);
++ targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH
++ names[REINVOKE] = new LambdaForm.Name(mtype, targetArgs);
++ }
++ form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline);
++ if (!customized) {
++ form = mtype.form().setCachedLambdaForm(whichCache, form);
++ }
++ return form;
++ }
++
++ static final NamedFunction NF_getTarget;
++ static {
++ try {
++ NF_getTarget = new NamedFunction(DelegatingMethodHandle.class
++ .getDeclaredMethod("getTarget"));
++ } catch (ReflectiveOperationException ex) {
++ throw newInternalError(ex);
++ }
++ }
++}
+--- ./jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java Wed Feb 04 12:14:43 2015 -0800
+@@ -31,6 +31,7 @@
+ import sun.invoke.util.VerifyAccess;
+ import static java.lang.invoke.MethodHandleNatives.Constants.*;
+ import static java.lang.invoke.LambdaForm.*;
++import static java.lang.invoke.LambdaForm.BasicType.*;
+ import static java.lang.invoke.MethodTypeForm.*;
+ import static java.lang.invoke.MethodHandleStatics.*;
+ import java.lang.ref.WeakReference;
+@@ -58,6 +59,7 @@
+ MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind());
+ m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null);
+ if (m != null && m.isPublic()) {
++ assert(member.getReferenceKind() == m.getReferenceKind()); // else this.form is wrong
+ member = m;
+ }
+ }
+@@ -125,65 +127,30 @@
+ }
+
+ @Override
++ BoundMethodHandle rebind() {
++ return BoundMethodHandle.makeReinvoker(this);
++ }
++
++ @Override
+ MethodHandle copyWith(MethodType mt, LambdaForm lf) {
++ assert(this.getClass() == DirectMethodHandle.class); // must override in subclasses
+ return new DirectMethodHandle(mt, lf, member);
+ }
+
+ @Override
+ String internalProperties() {
+- return "/DMH="+member.toString();
++ return "\n& DMH.MN="+internalMemberName();
+ }
+
+ //// Implementation methods.
+ @Override
+- MethodHandle viewAsType(MethodType newType) {
+- return new DirectMethodHandle(newType, form, member);
+- }
+- @Override
+ @ForceInline
+ MemberName internalMemberName() {
+ return member;
+ }
+
+- @Override
+- MethodHandle bindArgument(int pos, char basicType, Object value) {
+- // If the member needs dispatching, do so.
+- if (pos == 0 && basicType == 'L') {
+- DirectMethodHandle concrete = maybeRebind(value);
+- if (concrete != null)
+- return concrete.bindReceiver(value);
+- }
+- return super.bindArgument(pos, basicType, value);
+- }
+-
+- @Override
+- MethodHandle bindReceiver(Object receiver) {
+- // If the member needs dispatching, do so.
+- DirectMethodHandle concrete = maybeRebind(receiver);
+- if (concrete != null)
+- return concrete.bindReceiver(receiver);
+- return super.bindReceiver(receiver);
+- }
+-
+ private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
+
+- private DirectMethodHandle maybeRebind(Object receiver) {
+- if (receiver != null) {
+- switch (member.getReferenceKind()) {
+- case REF_invokeInterface:
+- case REF_invokeVirtual:
+- // Pre-dispatch the member.
+- Class<?> concreteClass = receiver.getClass();
+- MemberName concrete = new MemberName(concreteClass, member.getName(), member.getMethodType(), REF_invokeSpecial);
+- concrete = IMPL_NAMES.resolveOrNull(REF_invokeSpecial, concrete, concreteClass);
+- if (concrete != null)
+- return new DirectMethodHandle(type(), preparedLambdaForm(concrete), concrete);
+- break;
+- }
+- }
+- return null;
+- }
+-
+ /**
+ * Create a LF which can invoke the given method.
+ * Cache and share this structure among all methods with
+@@ -264,9 +231,10 @@
+ } else {
+ names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]);
+ }
++ assert(findDirectMethodHandle(names[GET_MEMBER]) == names[DMH_THIS]);
+ Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
+ assert(outArgs[outArgs.length-1] == names[GET_MEMBER]); // look, shifted args!
+- int result = LambdaForm.LAST_RESULT;
++ int result = LAST_RESULT;
+ if (doesAlloc) {
+ assert(outArgs[outArgs.length-2] == names[NEW_OBJ]); // got to move this one
+ System.arraycopy(outArgs, 0, outArgs, 1, outArgs.length-2);
+@@ -274,13 +242,23 @@
+ result = NEW_OBJ;
+ }
+ names[LINKER_CALL] = new Name(linker, outArgs);
+- lambdaName += "_" + LambdaForm.basicTypeSignature(mtype);
++ lambdaName += "_" + shortenSignature(basicTypeSignature(mtype));
+ LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);
+ // This is a tricky bit of code. Don't send it through the LF interpreter.
+ lform.compileToBytecode();
+ return lform;
+ }
+
++ static Object findDirectMethodHandle(Name name) {
++ if (name.function == Lazy.NF_internalMemberName ||
++ name.function == Lazy.NF_internalMemberNameEnsureInit ||
++ name.function == Lazy.NF_constructorMethod) {
++ assert(name.arguments.length == 1);
++ return name.arguments[0];
++ }
++ return null;
++ }
++
+ private static void maybeCompile(LambdaForm lform, MemberName m) {
+ if (VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
+ // Help along bootstrapping...
+@@ -393,8 +371,8 @@
+ return true;
+ }
+ @Override
+- MethodHandle viewAsType(MethodType newType) {
+- return new Special(newType, form, member);
++ MethodHandle copyWith(MethodType mt, LambdaForm lf) {
++ return new Special(mt, lf, member);
+ }
+ }
+
+@@ -411,8 +389,8 @@
+ assert(initMethod.isResolved());
+ }
+ @Override
+- MethodHandle viewAsType(MethodType newType) {
+- return new Constructor(newType, form, member, initMethod, instanceClass);
++ MethodHandle copyWith(MethodType mt, LambdaForm lf) {
++ return new Constructor(mt, lf, member, initMethod, instanceClass);
+ }
+ }
+
+@@ -441,8 +419,8 @@
+ return fieldType.cast(obj);
+ }
+ @Override
+- MethodHandle viewAsType(MethodType newType) {
+- return new Accessor(newType, form, member, fieldOffset);
++ MethodHandle copyWith(MethodType mt, LambdaForm lf) {
++ return new Accessor(mt, lf, member, fieldOffset);
+ }
+ }
+
+@@ -484,8 +462,8 @@
+ return fieldType.cast(obj);
+ }
+ @Override
+- MethodHandle viewAsType(MethodType newType) {
+- return new StaticAccessor(newType, form, member, staticBase, staticOffset);
++ MethodHandle copyWith(MethodType mt, LambdaForm lf) {
++ return new StaticAccessor(mt, lf, member, staticBase, staticOffset);
+ }
+ }
+
+--- ./jdk/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Wed Feb 04 12:14:43 2015 -0800
+@@ -193,10 +193,10 @@
+ CallSite buildCallSite() throws LambdaConversionException {
+ final Class<?> innerClass = spinInnerClass();
+ if (invokedType.parameterCount() == 0) {
+- final Constructor[] ctrs = AccessController.doPrivileged(
+- new PrivilegedAction<Constructor[]>() {
++ final Constructor<?>[] ctrs = AccessController.doPrivileged(
++ new PrivilegedAction<Constructor<?>[]>() {
+ @Override
+- public Constructor[] run() {
++ public Constructor<?>[] run() {
+ Constructor<?>[] ctrs = innerClass.getDeclaredConstructors();
+ if (ctrs.length == 1) {
+ // The lambda implementing inner class constructor is private, set
+@@ -338,7 +338,7 @@
+ m.visitVarInsn(getLoadOpcode(argType), varIndex);
+ varIndex += getParameterSize(argType);
+ }
+- m.visitMethodInsn(INVOKESPECIAL, lambdaClassName, NAME_CTOR, constructorType.toMethodDescriptorString());
++ m.visitMethodInsn(INVOKESPECIAL, lambdaClassName, NAME_CTOR, constructorType.toMethodDescriptorString(), false);
+ m.visitInsn(ARETURN);
+ m.visitMaxs(-1, -1);
+ m.visitEnd();
+@@ -354,7 +354,7 @@
+ ctor.visitCode();
+ ctor.visitVarInsn(ALOAD, 0);
+ ctor.visitMethodInsn(INVOKESPECIAL, JAVA_LANG_OBJECT, NAME_CTOR,
+- METHOD_DESCRIPTOR_VOID);
++ METHOD_DESCRIPTOR_VOID, false);
+ int parameterCount = invokedType.parameterCount();
+ for (int i = 0, lvIndex = 0; i < parameterCount; i++) {
+ ctor.visitVarInsn(ALOAD, 0);
+@@ -402,7 +402,7 @@
+ mv.visitInsn(AASTORE);
+ }
+ mv.visitMethodInsn(INVOKESPECIAL, NAME_SERIALIZED_LAMBDA, NAME_CTOR,
+- DESCR_CTOR_SERIALIZED_LAMBDA);
++ DESCR_CTOR_SERIALIZED_LAMBDA, false);
+ mv.visitInsn(ARETURN);
+ // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored
+ mv.visitMaxs(-1, -1);
+@@ -421,7 +421,7 @@
+ mv.visitInsn(DUP);
+ mv.visitLdcInsn("Non-serializable lambda");
+ mv.visitMethodInsn(INVOKESPECIAL, NAME_NOT_SERIALIZABLE_EXCEPTION, NAME_CTOR,
+- DESCR_CTOR_NOT_SERIALIZABLE_EXCEPTION);
++ DESCR_CTOR_NOT_SERIALIZABLE_EXCEPTION, false);
+ mv.visitInsn(ATHROW);
+ mv.visitMaxs(-1, -1);
+ mv.visitEnd();
+@@ -434,7 +434,7 @@
+ mv.visitInsn(DUP);
+ mv.visitLdcInsn("Non-serializable lambda");
+ mv.visitMethodInsn(INVOKESPECIAL, NAME_NOT_SERIALIZABLE_EXCEPTION, NAME_CTOR,
+- DESCR_CTOR_NOT_SERIALIZABLE_EXCEPTION);
++ DESCR_CTOR_NOT_SERIALIZABLE_EXCEPTION, false);
+ mv.visitInsn(ATHROW);
+ mv.visitMaxs(-1, -1);
+ mv.visitEnd();
+--- ./jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Wed Feb 04 12:14:43 2015 -0800
+@@ -25,20 +25,20 @@
+
+ package java.lang.invoke;
+
+-import sun.invoke.util.VerifyAccess;
+-import java.lang.invoke.LambdaForm.Name;
+-
+-import sun.invoke.util.Wrapper;
+-
+ import java.io.*;
+ import java.util.*;
++import java.lang.reflect.Modifier;
+
+ import jdk.internal.org.objectweb.asm.*;
+
+-import java.lang.reflect.*;
++import static java.lang.invoke.LambdaForm.*;
++import static java.lang.invoke.LambdaForm.BasicType.*;
+ import static java.lang.invoke.MethodHandleStatics.*;
+ import static java.lang.invoke.MethodHandleNatives.Constants.*;
++
++import sun.invoke.util.VerifyAccess;
+ import sun.invoke.util.VerifyType;
++import sun.invoke.util.Wrapper;
+ import sun.reflect.misc.ReflectUtil;
+
+ /**
+@@ -62,7 +62,7 @@
+ private static final String CLL_SIG = "(L" + CLS + ";L" + OBJ + ";)L" + OBJ + ";";
+
+ /** Name of its super class*/
+- private static final String superName = LF;
++ private static final String superName = OBJ;
+
+ /** Name of new class */
+ private final String className;
+@@ -73,7 +73,11 @@
+ private final LambdaForm lambdaForm;
+ private final String invokerName;
+ private final MethodType invokerType;
+- private final int[] localsMap;
++
++ /** Info about local variables in compiled lambda form */
++ private final int[] localsMap; // index
++ private final BasicType[] localTypes; // basic type
++ private final Class<?>[] localClasses; // type
+
+ /** ASM bytecode generation. */
+ private ClassWriter cw;
+@@ -82,6 +86,7 @@
+ private static final MemberName.Factory MEMBERNAME_FACTORY = MemberName.getFactory();
+ private static final Class<?> HOST_CLASS = LambdaForm.class;
+
++ /** Main constructor; other constructors delegate to this one. */
+ private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize,
+ String className, String invokerName, MethodType invokerType) {
+ if (invokerName.contains(".")) {
+@@ -92,23 +97,31 @@
+ if (DUMP_CLASS_FILES) {
+ className = makeDumpableClassName(className);
+ }
+- this.className = superName + "$" + className;
++ this.className = LF + "$" + className;
+ this.sourceFile = "LambdaForm$" + className;
+ this.lambdaForm = lambdaForm;
+ this.invokerName = invokerName;
+ this.invokerType = invokerType;
+- this.localsMap = new int[localsMapSize];
++ this.localsMap = new int[localsMapSize+1];
++ // last entry of localsMap is count of allocated local slots
++ this.localTypes = new BasicType[localsMapSize+1];
++ this.localClasses = new Class<?>[localsMapSize+1];
+ }
+
++ /** For generating LambdaForm interpreter entry points. */
+ private InvokerBytecodeGenerator(String className, String invokerName, MethodType invokerType) {
+ this(null, invokerType.parameterCount(),
+ className, invokerName, invokerType);
+ // Create an array to map name indexes to locals indexes.
++ localTypes[localTypes.length - 1] = V_TYPE;
+ for (int i = 0; i < localsMap.length; i++) {
+ localsMap[i] = invokerType.parameterSlotCount() - invokerType.parameterSlotDepth(i);
++ if (i < invokerType.parameterCount())
++ localTypes[i] = basicType(invokerType.parameterType(i));
+ }
+ }
+
++ /** For generating customized code for a single LambdaForm. */
+ private InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) {
+ this(form, form.names.length,
+ className, form.debugName, invokerType);
+@@ -116,7 +129,11 @@
+ Name[] names = form.names;
+ for (int i = 0, index = 0; i < localsMap.length; i++) {
+ localsMap[i] = index;
+- index += Wrapper.forBasicType(names[i].type).stackSlots();
++ if (i < names.length) {
++ BasicType type = names[i].type();
++ index += type.basicTypeSlots();
++ localTypes[i] = type;
++ }
+ }
+ }
+
+@@ -147,7 +164,6 @@
+
+ static void maybeDump(final String className, final byte[] classFile) {
+ if (DUMP_CLASS_FILES) {
+- System.out.println("dump: " + className);
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Void>() {
+ public Void run() {
+@@ -155,6 +171,7 @@
+ String dumpName = className;
+ //dumpName = dumpName.replace('/', '-');
+ File dumpFile = new File(DUMP_CLASS_FILES_DIR, dumpName+".class");
++ System.out.println("dump: " + dumpFile);
+ dumpFile.getParentFile().mkdirs();
+ FileOutputStream file = new FileOutputStream(dumpFile);
+ file.write(classFile);
+@@ -203,7 +220,7 @@
+
+ String constantPlaceholder(Object arg) {
+ String cpPlaceholder = "CONSTANT_PLACEHOLDER_" + cph++;
+- if (DUMP_CLASS_FILES) cpPlaceholder += " <<" + arg.toString() + ">>"; // debugging aid
++ if (DUMP_CLASS_FILES) cpPlaceholder += " <<" + debugString(arg) + ">>"; // debugging aid
+ if (cpPatches.containsKey(cpPlaceholder)) {
+ throw new InternalError("observed CP placeholder twice: " + cpPlaceholder);
+ }
+@@ -224,6 +241,17 @@
+ return res;
+ }
+
++ private static String debugString(Object arg) {
++ if (arg instanceof MethodHandle) {
++ MethodHandle mh = (MethodHandle) arg;
++ MemberName member = mh.internalMemberName();
++ if (member != null)
++ return member.toString();
++ return mh.debugString();
++ }
++ return arg.toString();
++ }
++
+ /**
+ * Extract the number of constant pool entries from a given class file.
+ *
+@@ -359,118 +387,212 @@
+ /*
+ * NOTE: These load/store methods use the localsMap to find the correct index!
+ */
+- private void emitLoadInsn(char type, int index) {
+- int opcode;
+- switch (type) {
+- case 'I': opcode = Opcodes.ILOAD; break;
+- case 'J': opcode = Opcodes.LLOAD; break;
+- case 'F': opcode = Opcodes.FLOAD; break;
+- case 'D': opcode = Opcodes.DLOAD; break;
+- case 'L': opcode = Opcodes.ALOAD; break;
+- default:
+- throw new InternalError("unknown type: " + type);
+- }
++ private void emitLoadInsn(BasicType type, int index) {
++ int opcode = loadInsnOpcode(type);
+ mv.visitVarInsn(opcode, localsMap[index]);
+ }
++
++ private int loadInsnOpcode(BasicType type) throws InternalError {
++ switch (type) {
++ case I_TYPE: return Opcodes.ILOAD;
++ case J_TYPE: return Opcodes.LLOAD;
++ case F_TYPE: return Opcodes.FLOAD;
++ case D_TYPE: return Opcodes.DLOAD;
++ case L_TYPE: return Opcodes.ALOAD;
++ default:
++ throw new InternalError("unknown type: " + type);
++ }
++ }
+ private void emitAloadInsn(int index) {
+- emitLoadInsn('L', index);
++ emitLoadInsn(L_TYPE, index);
+ }
+
+- private void emitStoreInsn(char type, int index) {
+- int opcode;
+- switch (type) {
+- case 'I': opcode = Opcodes.ISTORE; break;
+- case 'J': opcode = Opcodes.LSTORE; break;
+- case 'F': opcode = Opcodes.FSTORE; break;
+- case 'D': opcode = Opcodes.DSTORE; break;
+- case 'L': opcode = Opcodes.ASTORE; break;
+- default:
+- throw new InternalError("unknown type: " + type);
+- }
++ private void emitStoreInsn(BasicType type, int index) {
++ int opcode = storeInsnOpcode(type);
+ mv.visitVarInsn(opcode, localsMap[index]);
+ }
++
++ private int storeInsnOpcode(BasicType type) throws InternalError {
++ switch (type) {
++ case I_TYPE: return Opcodes.ISTORE;
++ case J_TYPE: return Opcodes.LSTORE;
++ case F_TYPE: return Opcodes.FSTORE;
++ case D_TYPE: return Opcodes.DSTORE;
++ case L_TYPE: return Opcodes.ASTORE;
++ default:
++ throw new InternalError("unknown type: " + type);
++ }
++ }
+ private void emitAstoreInsn(int index) {
+- emitStoreInsn('L', index);
++ emitStoreInsn(L_TYPE, index);
++ }
++
++ private byte arrayTypeCode(Wrapper elementType) {
++ switch (elementType) {
++ case BOOLEAN: return Opcodes.T_BOOLEAN;
++ case BYTE: return Opcodes.T_BYTE;
++ case CHAR: return Opcodes.T_CHAR;
++ case SHORT: return Opcodes.T_SHORT;
++ case INT: return Opcodes.T_INT;
++ case LONG: return Opcodes.T_LONG;
++ case FLOAT: return Opcodes.T_FLOAT;
++ case DOUBLE: return Opcodes.T_DOUBLE;
++ case OBJECT: return 0; // in place of Opcodes.T_OBJECT
++ default: throw new InternalError();
++ }
++ }
++
++ private int arrayInsnOpcode(byte tcode, int aaop) throws InternalError {
++ assert(aaop == Opcodes.AASTORE || aaop == Opcodes.AALOAD);
++ int xas;
++ switch (tcode) {
++ case Opcodes.T_BOOLEAN: xas = Opcodes.BASTORE; break;
++ case Opcodes.T_BYTE: xas = Opcodes.BASTORE; break;
++ case Opcodes.T_CHAR: xas = Opcodes.CASTORE; break;
++ case Opcodes.T_SHORT: xas = Opcodes.SASTORE; break;
++ case Opcodes.T_INT: xas = Opcodes.IASTORE; break;
++ case Opcodes.T_LONG: xas = Opcodes.LASTORE; break;
++ case Opcodes.T_FLOAT: xas = Opcodes.FASTORE; break;
++ case Opcodes.T_DOUBLE: xas = Opcodes.DASTORE; break;
++ case 0: xas = Opcodes.AASTORE; break;
++ default: throw new InternalError();
++ }
++ return xas - Opcodes.AASTORE + aaop;
++ }
++
++
++ private void freeFrameLocal(int oldFrameLocal) {
++ int i = indexForFrameLocal(oldFrameLocal);
++ if (i < 0) return;
++ BasicType type = localTypes[i];
++ int newFrameLocal = makeLocalTemp(type);
++ mv.visitVarInsn(loadInsnOpcode(type), oldFrameLocal);
++ mv.visitVarInsn(storeInsnOpcode(type), newFrameLocal);
++ assert(localsMap[i] == oldFrameLocal);
++ localsMap[i] = newFrameLocal;
++ assert(indexForFrameLocal(oldFrameLocal) < 0);
++ }
++ private int indexForFrameLocal(int frameLocal) {
++ for (int i = 0; i < localsMap.length; i++) {
++ if (localsMap[i] == frameLocal && localTypes[i] != V_TYPE)
++ return i;
++ }
++ return -1;
++ }
++ private int makeLocalTemp(BasicType type) {
++ int frameLocal = localsMap[localsMap.length - 1];
++ localsMap[localsMap.length - 1] = frameLocal + type.basicTypeSlots();
++ return frameLocal;
+ }
+
+ /**
+ * Emit a boxing call.
+ *
+- * @param type primitive type class to box.
++ * @param wrapper primitive type class to box.
+ */
+- private void emitBoxing(Class<?> type) {
+- Wrapper wrapper = Wrapper.forPrimitiveType(type);
++ private void emitBoxing(Wrapper wrapper) {
+ String owner = "java/lang/" + wrapper.wrapperType().getSimpleName();
+ String name = "valueOf";
+ String desc = "(" + wrapper.basicTypeChar() + ")L" + owner + ";";
+- mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, desc);
++ mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, desc, false);
+ }
+
+ /**
+ * Emit an unboxing call (plus preceding checkcast).
+ *
+- * @param type wrapper type class to unbox.
++ * @param wrapper wrapper type class to unbox.
+ */
+- private void emitUnboxing(Class<?> type) {
+- Wrapper wrapper = Wrapper.forWrapperType(type);
++ private void emitUnboxing(Wrapper wrapper) {
+ String owner = "java/lang/" + wrapper.wrapperType().getSimpleName();
+ String name = wrapper.primitiveSimpleName() + "Value";
+ String desc = "()" + wrapper.basicTypeChar();
+- mv.visitTypeInsn(Opcodes.CHECKCAST, owner);
+- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, desc);
++ emitReferenceCast(wrapper.wrapperType(), null);
++ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, desc, false);
+ }
+
+ /**
+- * Emit an implicit conversion.
++ * Emit an implicit conversion for an argument which must be of the given pclass.
++ * This is usually a no-op, except when pclass is a subword type or a reference other than Object or an interface.
+ *
+ * @param ptype type of value present on stack
+ * @param pclass type of value required on stack
++ * @param arg compile-time representation of value on stack (Node, constant) or null if none
+ */
+- private void emitImplicitConversion(char ptype, Class<?> pclass) {
++ private void emitImplicitConversion(BasicType ptype, Class<?> pclass, Object arg) {
++ assert(basicType(pclass) == ptype); // boxing/unboxing handled by caller
++ if (pclass == ptype.basicTypeClass() && ptype != L_TYPE)
++ return; // nothing to do
+ switch (ptype) {
+- case 'L':
+- if (VerifyType.isNullConversion(Object.class, pclass))
++ case L_TYPE:
++ if (VerifyType.isNullConversion(Object.class, pclass, false)) {
++ if (PROFILE_LEVEL > 0)
++ emitReferenceCast(Object.class, arg);
++ return;
++ }
++ emitReferenceCast(pclass, arg);
+ return;
+- if (isStaticallyNameable(pclass)) {
+- mv.visitTypeInsn(Opcodes.CHECKCAST, getInternalName(pclass));
+- } else {
+- mv.visitLdcInsn(constantPlaceholder(pclass));
+- mv.visitTypeInsn(Opcodes.CHECKCAST, CLS);
+- mv.visitInsn(Opcodes.SWAP);
+- mv.visitMethodInsn(Opcodes.INVOKESTATIC, MHI, "castReference", CLL_SIG);
+- if (pclass.isArray())
+- mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY);
++ case I_TYPE:
++ if (!VerifyType.isNullConversion(int.class, pclass, false))
++ emitPrimCast(ptype.basicTypeWrapper(), Wrapper.forPrimitiveType(pclass));
++ return;
++ }
++ throw newInternalError("bad implicit conversion: tc="+ptype+": "+pclass);
++ }
++
++ /** Update localClasses type map. Return true if the information is already present. */
++ private boolean assertStaticType(Class<?> cls, Name n) {
++ int local = n.index();
++ Class<?> aclass = localClasses[local];
++ if (aclass != null && (aclass == cls || cls.isAssignableFrom(aclass))) {
++ return true; // type info is already present
++ } else if (aclass == null || aclass.isAssignableFrom(cls)) {
++ localClasses[local] = cls; // type info can be improved
++ }
++ return false;
++ }
++
++ private void emitReferenceCast(Class<?> cls, Object arg) {
++ Name writeBack = null; // local to write back result
++ if (arg instanceof Name) {
++ Name n = (Name) arg;
++ if (assertStaticType(cls, n))
++ return; // this cast was already performed
++ if (lambdaForm.useCount(n) > 1) {
++ // This guy gets used more than once.
++ writeBack = n;
+ }
+- return;
+- case 'I':
+- if (!VerifyType.isNullConversion(int.class, pclass))
+- emitPrimCast(ptype, Wrapper.basicTypeChar(pclass));
+- return;
+- case 'J':
+- assert(pclass == long.class);
+- return;
+- case 'F':
+- assert(pclass == float.class);
+- return;
+- case 'D':
+- assert(pclass == double.class);
+- return;
+ }
+- throw new InternalError("bad implicit conversion: tc="+ptype+": "+pclass);
++ if (isStaticallyNameable(cls)) {
++ String sig = getInternalName(cls);
++ mv.visitTypeInsn(Opcodes.CHECKCAST, sig);
++ } else {
++ mv.visitLdcInsn(constantPlaceholder(cls));
++ mv.visitTypeInsn(Opcodes.CHECKCAST, CLS);
++ mv.visitInsn(Opcodes.SWAP);
++ mv.visitMethodInsn(Opcodes.INVOKESTATIC, MHI, "castReference", CLL_SIG, false);
++ if (Object[].class.isAssignableFrom(cls))
++ mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY);
++ else if (PROFILE_LEVEL > 0)
++ mv.visitTypeInsn(Opcodes.CHECKCAST, OBJ);
++ }
++ if (writeBack != null) {
++ mv.visitInsn(Opcodes.DUP);
++ emitAstoreInsn(writeBack.index());
++ }
+ }
+
+ /**
+ * Emits an actual return instruction conforming to the given return type.
+ */
+- private void emitReturnInsn(Class<?> type) {
++ private void emitReturnInsn(BasicType type) {
+ int opcode;
+- switch (Wrapper.basicTypeChar(type)) {
+- case 'I': opcode = Opcodes.IRETURN; break;
+- case 'J': opcode = Opcodes.LRETURN; break;
+- case 'F': opcode = Opcodes.FRETURN; break;
+- case 'D': opcode = Opcodes.DRETURN; break;
+- case 'L': opcode = Opcodes.ARETURN; break;
+- case 'V': opcode = Opcodes.RETURN; break;
++ switch (type) {
++ case I_TYPE: opcode = Opcodes.IRETURN; break;
++ case J_TYPE: opcode = Opcodes.LRETURN; break;
++ case F_TYPE: opcode = Opcodes.FRETURN; break;
++ case D_TYPE: opcode = Opcodes.DRETURN; break;
++ case L_TYPE: opcode = Opcodes.ARETURN; break;
++ case V_TYPE: opcode = Opcodes.RETURN; break;
+ default:
+ throw new InternalError("unknown return type: " + type);
+ }
+@@ -478,7 +600,11 @@
+ }
+
+ private static String getInternalName(Class<?> c) {
+- assert(VerifyAccess.isTypeVisible(c, Object.class));
++ if (c == Object.class) return OBJ;
++ else if (c == Object[].class) return OBJARY;
++ else if (c == Class.class) return CLS;
++ else if (c == MethodHandle.class) return MH;
++ assert(VerifyAccess.isTypeVisible(c, Object.class)) : c.getName();
+ return c.getName().replace('.', '/');
+ }
+
+@@ -502,44 +628,72 @@
+ // Mark this method as a compiled LambdaForm
+ mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Compiled;", true);
+
+- // Force inlining of this invoker method.
+- mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true);
++ if (lambdaForm.forceInline) {
++ // Force inlining of this invoker method.
++ mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true);
++ } else {
++ mv.visitAnnotation("Ljava/lang/invoke/DontInline;", true);
++ }
++
+
+ // iterate over the form's names, generating bytecode instructions for each
+ // start iterating at the first name following the arguments
++ Name onStack = null;
+ for (int i = lambdaForm.arity; i < lambdaForm.names.length; i++) {
+ Name name = lambdaForm.names[i];
++
++ emitStoreResult(onStack);
++ onStack = name; // unless otherwise modified below
++ MethodHandleImpl.Intrinsic intr = name.function.intrinsicName();
++ switch (intr) {
++ case SELECT_ALTERNATIVE:
++ assert isSelectAlternative(i);
++ onStack = emitSelectAlternative(name, lambdaForm.names[i+1]);
++ i++; // skip MH.invokeBasic of the selectAlternative result
++ continue;
++ case GUARD_WITH_CATCH:
++ assert isGuardWithCatch(i);
++ onStack = emitGuardWithCatch(i);
++ i = i+2; // Jump to the end of GWC idiom
++ continue;
++ case NEW_ARRAY:
++ Class<?> rtype = name.function.methodType().returnType();
++ if (isStaticallyNameable(rtype)) {
++ emitNewArray(name);
++ continue;
++ }
++ break;
++ case ARRAY_LOAD:
++ emitArrayLoad(name);
++ continue;
++ case ARRAY_STORE:
++ emitArrayStore(name);
++ continue;
++ case IDENTITY:
++ assert(name.arguments.length == 1);
++ emitPushArguments(name);
++ continue;
++ case ZERO:
++ assert(name.arguments.length == 0);
++ emitConst(name.type.basicTypeWrapper().zero());
++ continue;
++ case NONE:
++ // no intrinsic associated
++ break;
++ default:
++ throw newInternalError("Unknown intrinsic: "+intr);
++ }
++
+ MemberName member = name.function.member();
+-
+- if (isSelectAlternative(i)) {
+- emitSelectAlternative(name, lambdaForm.names[i + 1]);
+- i++; // skip MH.invokeBasic of the selectAlternative result
+- } else if (isGuardWithCatch(i)) {
+- emitGuardWithCatch(i);
+- i = i+2; // Jump to the end of GWC idiom
+- } else if (isStaticallyInvocable(member)) {
++ if (isStaticallyInvocable(member)) {
+ emitStaticInvoke(member, name);
+ } else {
+ emitInvoke(name);
+ }
+-
+- // Update cached form name's info in case an intrinsic spanning multiple names was encountered.
+- name = lambdaForm.names[i];
+- member = name.function.member();
+-
+- // store the result from evaluating to the target name in a local if required
+- // (if this is the last value, i.e., the one that is going to be returned,
+- // avoid store/load/return and just return)
+- if (i == lambdaForm.names.length - 1 && i == lambdaForm.result) {
+- // return value - do nothing
+- } else if (name.type != 'V') {
+- // non-void: actually assign
+- emitStoreInsn(name.type, name.index());
+- }
+ }
+
+ // return statement
+- emitReturn();
++ emitReturn(onStack);
+
+ classFileEpilogue();
+ bogusMethod(lambdaForm);
+@@ -549,33 +703,47 @@
+ return classFile;
+ }
+
++ void emitArrayLoad(Name name) { emitArrayOp(name, Opcodes.AALOAD); }
++ void emitArrayStore(Name name) { emitArrayOp(name, Opcodes.AASTORE); }
++
++ void emitArrayOp(Name name, int arrayOpcode) {
++ assert arrayOpcode == Opcodes.AALOAD || arrayOpcode == Opcodes.AASTORE;
++ Class<?> elementType = name.function.methodType().parameterType(0).getComponentType();
++ assert elementType != null;
++ emitPushArguments(name);
++ if (elementType.isPrimitive()) {
++ Wrapper w = Wrapper.forPrimitiveType(elementType);
++ arrayOpcode = arrayInsnOpcode(arrayTypeCode(w), arrayOpcode);
++ }
++ mv.visitInsn(arrayOpcode);
++ }
++
+ /**
+ * Emit an invoke for the given name.
+ */
+ void emitInvoke(Name name) {
++ assert(!isLinkerMethodInvoke(name)); // should use the static path for these
+ if (true) {
+ // push receiver
+ MethodHandle target = name.function.resolvedHandle;
+ assert(target != null) : name.exprString();
+ mv.visitLdcInsn(constantPlaceholder(target));
+- mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
++ emitReferenceCast(MethodHandle.class, target);
+ } else {
+ // load receiver
+ emitAloadInsn(0);
+- mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
++ emitReferenceCast(MethodHandle.class, null);
+ mv.visitFieldInsn(Opcodes.GETFIELD, MH, "form", LF_SIG);
+ mv.visitFieldInsn(Opcodes.GETFIELD, LF, "names", LFN_SIG);
+ // TODO more to come
+ }
+
+ // push arguments
+- for (int i = 0; i < name.arguments.length; i++) {
+- emitPushArgument(name, i);
+- }
++ emitPushArguments(name);
+
+ // invocation
+ MethodType type = name.function.methodType();
+- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", type.basicType().toMethodDescriptorString());
++ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", type.basicType().toMethodDescriptorString(), false);
+ }
+
+ static private Class<?>[] STATICALLY_INVOCABLE_PACKAGES = {
+@@ -586,6 +754,10 @@
+ //MethodHandle.class already covered
+ };
+
++ static boolean isStaticallyInvocable(Name name) {
++ return isStaticallyInvocable(name.function.member());
++ }
++
+ static boolean isStaticallyInvocable(MemberName member) {
+ if (member == null) return false;
+ if (member.isConstructor()) return false;
+@@ -612,6 +784,8 @@
+ }
+
+ static boolean isStaticallyNameable(Class<?> cls) {
++ if (cls == Object.class)
++ return true;
+ while (cls.isArray())
+ cls = cls.getComponentType();
+ if (cls.isPrimitive())
+@@ -632,12 +806,17 @@
+ return false;
+ }
+
++ void emitStaticInvoke(Name name) {
++ emitStaticInvoke(name.function.member(), name);
++ }
++
+ /**
+ * Emit an invoke for the given name, using the MemberName directly.
+ */
+ void emitStaticInvoke(MemberName member, Name name) {
+ assert(member.equals(name.function.member()));
+- String cname = getInternalName(member.getDeclaringClass());
++ Class<?> defc = member.getDeclaringClass();
++ String cname = getInternalName(defc);
+ String mname = member.getName();
+ String mtype;
+ byte refKind = member.getReferenceKind();
+@@ -654,9 +833,7 @@
+ }
+
+ // push arguments
+- for (int i = 0; i < name.arguments.length; i++) {
+- emitPushArgument(name, i);
+- }
++ emitPushArguments(name);
+
+ // invocation
+ if (member.isMethod()) {
+@@ -667,6 +844,52 @@
+ mtype = MethodType.toFieldDescriptorString(member.getFieldType());
+ mv.visitFieldInsn(refKindOpcode(refKind), cname, mname, mtype);
+ }
++ // Issue a type assertion for the result, so we can avoid casts later.
++ if (name.type == L_TYPE) {
++ Class<?> rtype = member.getInvocationType().returnType();
++ assert(!rtype.isPrimitive());
++ if (rtype != Object.class && !rtype.isInterface()) {
++ assertStaticType(rtype, name);
++ }
++ }
++ }
++
++ void emitNewArray(Name name) throws InternalError {
++ Class<?> rtype = name.function.methodType().returnType();
++ if (name.arguments.length == 0) {
++ // The array will be a constant.
++ Object emptyArray;
++ try {
++ emptyArray = name.function.resolvedHandle.invoke();
++ } catch (Throwable ex) {
++ throw newInternalError(ex);
++ }
++ assert(java.lang.reflect.Array.getLength(emptyArray) == 0);
++ assert(emptyArray.getClass() == rtype); // exact typing
++ mv.visitLdcInsn(constantPlaceholder(emptyArray));
++ emitReferenceCast(rtype, emptyArray);
++ return;
++ }
++ Class<?> arrayElementType = rtype.getComponentType();
++ assert(arrayElementType != null);
++ emitIconstInsn(name.arguments.length);
++ int xas = Opcodes.AASTORE;
++ if (!arrayElementType.isPrimitive()) {
++ mv.visitTypeInsn(Opcodes.ANEWARRAY, getInternalName(arrayElementType));
++ } else {
++ byte tc = arrayTypeCode(Wrapper.forPrimitiveType(arrayElementType));
++ xas = arrayInsnOpcode(tc, xas);
++ mv.visitIntInsn(Opcodes.NEWARRAY, tc);
++ }
++ // store arguments
++ for (int i = 0; i < name.arguments.length; i++) {
++ mv.visitInsn(Opcodes.DUP);
++ emitIconstInsn(i);
++ emitPushArgument(name, i);
++ mv.visitInsn(xas);
++ }
++ // the array is left on the stack
++ assertStaticType(rtype, name);
+ }
+ int refKindOpcode(byte refKind) {
+ switch (refKind) {
+@@ -709,6 +932,21 @@
+ }
+
+ /**
++ * Check if MemberName is a call to MethodHandle.linkToStatic, etc.
++ */
++ private boolean isLinkerMethodInvoke(Name name) {
++ if (name.function == null)
++ return false;
++ if (name.arguments.length < 1)
++ return false; // must have MH argument
++ MemberName member = name.function.member();
++ return member != null &&
++ member.getDeclaringClass() == MethodHandle.class &&
++ !member.isPublic() && member.isStatic() &&
++ member.getName().startsWith("linkTo");
++ }
++
++ /**
+ * Check if i-th name is a call to MethodHandleImpl.selectAlternative.
+ */
+ private boolean isSelectAlternative(int pos) {
+@@ -756,7 +994,9 @@
+ * t4:I=MethodHandle.invokeBasic(t3:L,a1:I);t4:I}
+ * }</pre></blockquote>
+ */
+- private void emitSelectAlternative(Name selectAlternativeName, Name invokeBasicName) {
++ private Name emitSelectAlternative(Name selectAlternativeName, Name invokeBasicName) {
++ assert isStaticallyInvocable(invokeBasicName);
++
+ Name receiver = (Name) invokeBasicName.arguments[0];
+
+ Label L_fallback = new Label();
+@@ -764,15 +1004,15 @@
+
+ // load test result
+ emitPushArgument(selectAlternativeName, 0);
+- mv.visitInsn(Opcodes.ICONST_1);
+
+ // if_icmpne L_fallback
+- mv.visitJumpInsn(Opcodes.IF_ICMPNE, L_fallback);
++ mv.visitJumpInsn(Opcodes.IFEQ, L_fallback);
+
+ // invoke selectAlternativeName.arguments[1]
++ Class<?>[] preForkClasses = localClasses.clone();
+ emitPushArgument(selectAlternativeName, 1); // get 2nd argument of selectAlternative
+ emitAstoreInsn(receiver.index()); // store the MH in the receiver slot
+- emitInvoke(invokeBasicName);
++ emitStaticInvoke(invokeBasicName);
+
+ // goto L_done
+ mv.visitJumpInsn(Opcodes.GOTO, L_done);
+@@ -781,12 +1021,17 @@
+ mv.visitLabel(L_fallback);
+
+ // invoke selectAlternativeName.arguments[2]
++ System.arraycopy(preForkClasses, 0, localClasses, 0, preForkClasses.length);
+ emitPushArgument(selectAlternativeName, 2); // get 3rd argument of selectAlternative
+ emitAstoreInsn(receiver.index()); // store the MH in the receiver slot
+- emitInvoke(invokeBasicName);
++ emitStaticInvoke(invokeBasicName);
+
+ // L_done:
+ mv.visitLabel(L_done);
++ // for now do not bother to merge typestate; just reset to the dominator state
++ System.arraycopy(preForkClasses, 0, localClasses, 0, preForkClasses.length);
++
++ return invokeBasicName; // return what's on stack
+ }
+
+ /**
+@@ -809,7 +1054,7 @@
+ * return a3.invokeBasic(ex, a6, a7);
+ * }}
+ */
+- private void emitGuardWithCatch(int pos) {
++ private Name emitGuardWithCatch(int pos) {
+ Name args = lambdaForm.names[pos];
+ Name invoker = lambdaForm.names[pos+1];
+ Name result = lambdaForm.names[pos+2];
+@@ -860,6 +1105,12 @@
+ mv.visitInsn(Opcodes.ATHROW);
+
+ mv.visitLabel(L_done);
++
++ return result;
++ }
++
++ private void emitPushArguments(Name args) {
++ emitPushArguments(args, 0);
+ }
+
+ private void emitPushArguments(Name args, int start) {
+@@ -870,75 +1121,69 @@
+
+ private void emitPushArgument(Name name, int paramIndex) {
+ Object arg = name.arguments[paramIndex];
+- char ptype = name.function.parameterType(paramIndex);
+- MethodType mtype = name.function.methodType();
++ Class<?> ptype = name.function.methodType().parameterType(paramIndex);
++ emitPushArgument(ptype, arg);
++ }
++
++ private void emitPushArgument(Class<?> ptype, Object arg) {
++ BasicType bptype = basicType(ptype);
+ if (arg instanceof Name) {
+ Name n = (Name) arg;
+ emitLoadInsn(n.type, n.index());
+- emitImplicitConversion(n.type, mtype.parameterType(paramIndex));
+- } else if ((arg == null || arg instanceof String) && ptype == 'L') {
++ emitImplicitConversion(n.type, ptype, n);
++ } else if ((arg == null || arg instanceof String) && bptype == L_TYPE) {
+ emitConst(arg);
+ } else {
+- if (Wrapper.isWrapperType(arg.getClass()) && ptype != 'L') {
++ if (Wrapper.isWrapperType(arg.getClass()) && bptype != L_TYPE) {
+ emitConst(arg);
+ } else {
+ mv.visitLdcInsn(constantPlaceholder(arg));
+- emitImplicitConversion('L', mtype.parameterType(paramIndex));
++ emitImplicitConversion(L_TYPE, ptype, arg);
+ }
+ }
+ }
+
+ /**
++ * Store the name to its local, if necessary.
++ */
++ private void emitStoreResult(Name name) {
++ if (name != null && name.type != V_TYPE) {
++ // non-void: actually assign
++ emitStoreInsn(name.type, name.index());
++ }
++ }
++
++ /**
+ * Emits a return statement from a LF invoker. If required, the result type is cast to the correct return type.
+ */
+- private void emitReturn() {
++ private void emitReturn(Name onStack) {
+ // return statement
+- if (lambdaForm.result == -1) {
++ Class<?> rclass = invokerType.returnType();
++ BasicType rtype = lambdaForm.returnType();
++ assert(rtype == basicType(rclass)); // must agree
++ if (rtype == V_TYPE) {
+ // void
+ mv.visitInsn(Opcodes.RETURN);
++ // it doesn't matter what rclass is; the JVM will discard any value
+ } else {
+ LambdaForm.Name rn = lambdaForm.names[lambdaForm.result];
+- char rtype = Wrapper.basicTypeChar(invokerType.returnType());
+
+ // put return value on the stack if it is not already there
+- if (lambdaForm.result != lambdaForm.names.length - 1) {
+- emitLoadInsn(rn.type, lambdaForm.result);
++ if (rn != onStack) {
++ emitLoadInsn(rtype, lambdaForm.result);
+ }
+
+- // potentially generate cast
+- // rtype is the return type of the invoker - generated code must conform to this
+- // rn.type is the type of the result Name in the LF
+- if (rtype != rn.type) {
+- // need cast
+- if (rtype == 'L') {
+- // possibly cast the primitive to the correct type for boxing
+- char boxedType = Wrapper.forWrapperType(invokerType.returnType()).basicTypeChar();
+- if (boxedType != rn.type) {
+- emitPrimCast(rn.type, boxedType);
+- }
+- // cast primitive to reference ("boxing")
+- emitBoxing(invokerType.returnType());
+- } else {
+- // to-primitive cast
+- if (rn.type != 'L') {
+- // prim-to-prim cast
+- emitPrimCast(rn.type, rtype);
+- } else {
+- // ref-to-prim cast ("unboxing")
+- throw new InternalError("no ref-to-prim (unboxing) casts supported right now");
+- }
+- }
+- }
++ emitImplicitConversion(rtype, rclass, rn);
+
+ // generate actual return statement
+- emitReturnInsn(invokerType.returnType());
++ emitReturnInsn(rtype);
+ }
+ }
+
+ /**
+ * Emit a type conversion bytecode casting from "from" to "to".
+ */
+- private void emitPrimCast(char from, char to) {
++ private void emitPrimCast(Wrapper from, Wrapper to) {
+ // Here's how.
+ // - indicates forbidden
+ // <-> indicates implicit
+@@ -955,17 +1200,15 @@
+ // no cast required, should be dead code anyway
+ return;
+ }
+- Wrapper wfrom = Wrapper.forBasicType(from);
+- Wrapper wto = Wrapper.forBasicType(to);
+- if (wfrom.isSubwordOrInt()) {
++ if (from.isSubwordOrInt()) {
+ // cast from {byte,short,char,int} to anything
+ emitI2X(to);
+ } else {
+ // cast from {long,float,double} to anything
+- if (wto.isSubwordOrInt()) {
++ if (to.isSubwordOrInt()) {
+ // cast to {byte,short,char,int}
+ emitX2I(from);
+- if (wto.bitWidth() < 32) {
++ if (to.bitWidth() < 32) {
+ // targets other than int require another conversion
+ emitI2X(to);
+ }
+@@ -973,20 +1216,26 @@
+ // cast to {long,float,double} - this is verbose
+ boolean error = false;
+ switch (from) {
+- case 'J':
+- if (to == 'F') { mv.visitInsn(Opcodes.L2F); }
+- else if (to == 'D') { mv.visitInsn(Opcodes.L2D); }
+- else error = true;
++ case LONG:
++ switch (to) {
++ case FLOAT: mv.visitInsn(Opcodes.L2F); break;
++ case DOUBLE: mv.visitInsn(Opcodes.L2D); break;
++ default: error = true; break;
++ }
+ break;
+- case 'F':
+- if (to == 'J') { mv.visitInsn(Opcodes.F2L); }
+- else if (to == 'D') { mv.visitInsn(Opcodes.F2D); }
+- else error = true;
++ case FLOAT:
++ switch (to) {
++ case LONG : mv.visitInsn(Opcodes.F2L); break;
++ case DOUBLE: mv.visitInsn(Opcodes.F2D); break;
++ default: error = true; break;
++ }
+ break;
+- case 'D':
+- if (to == 'J') { mv.visitInsn(Opcodes.D2L); }
+- else if (to == 'F') { mv.visitInsn(Opcodes.D2F); }
+- else error = true;
++ case DOUBLE:
++ switch (to) {
++ case LONG : mv.visitInsn(Opcodes.D2L); break;
++ case FLOAT: mv.visitInsn(Opcodes.D2F); break;
++ default: error = true; break;
++ }
+ break;
+ default:
+ error = true;
+@@ -999,16 +1248,16 @@
+ }
+ }
+
+- private void emitI2X(char type) {
++ private void emitI2X(Wrapper type) {
+ switch (type) {
+- case 'B': mv.visitInsn(Opcodes.I2B); break;
+- case 'S': mv.visitInsn(Opcodes.I2S); break;
+- case 'C': mv.visitInsn(Opcodes.I2C); break;
+- case 'I': /* naught */ break;
+- case 'J': mv.visitInsn(Opcodes.I2L); break;
+- case 'F': mv.visitInsn(Opcodes.I2F); break;
+- case 'D': mv.visitInsn(Opcodes.I2D); break;
+- case 'Z':
++ case BYTE: mv.visitInsn(Opcodes.I2B); break;
++ case SHORT: mv.visitInsn(Opcodes.I2S); break;
++ case CHAR: mv.visitInsn(Opcodes.I2C); break;
++ case INT: /* naught */ break;
++ case LONG: mv.visitInsn(Opcodes.I2L); break;
++ case FLOAT: mv.visitInsn(Opcodes.I2F); break;
++ case DOUBLE: mv.visitInsn(Opcodes.I2D); break;
++ case BOOLEAN:
+ // For compatibility with ValueConversions and explicitCastArguments:
+ mv.visitInsn(Opcodes.ICONST_1);
+ mv.visitInsn(Opcodes.IAND);
+@@ -1017,39 +1266,24 @@
+ }
+ }
+
+- private void emitX2I(char type) {
++ private void emitX2I(Wrapper type) {
+ switch (type) {
+- case 'J': mv.visitInsn(Opcodes.L2I); break;
+- case 'F': mv.visitInsn(Opcodes.F2I); break;
+- case 'D': mv.visitInsn(Opcodes.D2I); break;
+- default: throw new InternalError("unknown type: " + type);
++ case LONG: mv.visitInsn(Opcodes.L2I); break;
++ case FLOAT: mv.visitInsn(Opcodes.F2I); break;
++ case DOUBLE: mv.visitInsn(Opcodes.D2I); break;
++ default: throw new InternalError("unknown type: " + type);
+ }
+ }
+
+- private static String basicTypeCharSignature(String prefix, MethodType type) {
+- StringBuilder buf = new StringBuilder(prefix);
+- for (Class<?> ptype : type.parameterList())
+- buf.append(Wrapper.forBasicType(ptype).basicTypeChar());
+- buf.append('_').append(Wrapper.forBasicType(type.returnType()).basicTypeChar());
+- return buf.toString();
+- }
+-
+ /**
+ * Generate bytecode for a LambdaForm.vmentry which calls interpretWithArguments.
+ */
+ static MemberName generateLambdaFormInterpreterEntryPoint(String sig) {
+- assert(LambdaForm.isValidSignature(sig));
+- //System.out.println("generateExactInvoker "+sig);
+- // compute method type
+- // first parameter and return type
+- char tret = LambdaForm.signatureReturn(sig);
+- MethodType type = MethodType.methodType(LambdaForm.typeClass(tret), MethodHandle.class);
+- // other parameter types
+- int arity = LambdaForm.signatureArity(sig);
+- for (int i = 1; i < arity; i++) {
+- type = type.appendParameterTypes(LambdaForm.typeClass(sig.charAt(i)));
+- }
+- InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("LFI", "interpret_"+tret, type);
++ assert(isValidSignature(sig));
++ String name = "interpret_"+signatureReturn(sig).basicTypeChar();
++ MethodType type = signatureType(sig); // sig includes leading argument
++ type = type.changeParameterType(0, MethodHandle.class);
++ InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("LFI", name, type);
+ return g.loadMethod(g.generateLambdaFormInterpreterEntryPointBytes());
+ }
+
+@@ -1071,10 +1305,10 @@
+ Class<?> ptype = invokerType.parameterType(i);
+ mv.visitInsn(Opcodes.DUP);
+ emitIconstInsn(i);
+- emitLoadInsn(Wrapper.basicTypeChar(ptype), i);
++ emitLoadInsn(basicType(ptype), i);
+ // box if primitive type
+ if (ptype.isPrimitive()) {
+- emitBoxing(ptype);
++ emitBoxing(Wrapper.forPrimitiveType(ptype));
+ }
+ mv.visitInsn(Opcodes.AASTORE);
+ }
+@@ -1082,16 +1316,16 @@
+ emitAloadInsn(0);
+ mv.visitFieldInsn(Opcodes.GETFIELD, MH, "form", "Ljava/lang/invoke/LambdaForm;");
+ mv.visitInsn(Opcodes.SWAP); // swap form and array; avoid local variable
+- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, LF, "interpretWithArguments", "([Ljava/lang/Object;)Ljava/lang/Object;");
++ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, LF, "interpretWithArguments", "([Ljava/lang/Object;)Ljava/lang/Object;", false);
+
+ // maybe unbox
+ Class<?> rtype = invokerType.returnType();
+ if (rtype.isPrimitive() && rtype != void.class) {
+- emitUnboxing(Wrapper.asWrapperType(rtype));
++ emitUnboxing(Wrapper.forPrimitiveType(rtype));
+ }
+
+ // return statement
+- emitReturnInsn(rtype);
++ emitReturnInsn(basicType(rtype));
+
+ classFileEpilogue();
+ bogusMethod(invokerType);
+@@ -1105,14 +1339,12 @@
+ * Generate bytecode for a NamedFunction invoker.
+ */
+ static MemberName generateNamedFunctionInvoker(MethodTypeForm typeForm) {
+- MethodType invokerType = LambdaForm.NamedFunction.INVOKER_METHOD_TYPE;
+- String invokerName = basicTypeCharSignature("invoke_", typeForm.erasedType());
++ MethodType invokerType = NamedFunction.INVOKER_METHOD_TYPE;
++ String invokerName = "invoke_" + shortenSignature(basicTypeSignature(typeForm.erasedType()));
+ InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("NFI", invokerName, invokerType);
+ return g.loadMethod(g.generateNamedFunctionInvokerImpl(typeForm));
+ }
+
+- static int nfi = 0;
+-
+ private byte[] generateNamedFunctionInvokerImpl(MethodTypeForm typeForm) {
+ MethodType dstType = typeForm.erasedType();
+ classFilePrologue();
+@@ -1138,14 +1370,14 @@
+ Class<?> sptype = dstType.basicType().wrap().parameterType(i);
+ Wrapper dstWrapper = Wrapper.forBasicType(dptype);
+ Wrapper srcWrapper = dstWrapper.isSubwordOrInt() ? Wrapper.INT : dstWrapper; // narrow subword from int
+- emitUnboxing(srcWrapper.wrapperType());
+- emitPrimCast(srcWrapper.basicTypeChar(), dstWrapper.basicTypeChar());
++ emitUnboxing(srcWrapper);
++ emitPrimCast(srcWrapper, dstWrapper);
+ }
+ }
+
+ // Invoke
+ String targetDesc = dstType.basicType().toMethodDescriptorString();
+- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", targetDesc);
++ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", targetDesc, false);
+
+ // Box primitive types
+ Class<?> rtype = dstType.returnType();
+@@ -1153,15 +1385,15 @@
+ Wrapper srcWrapper = Wrapper.forBasicType(rtype);
+ Wrapper dstWrapper = srcWrapper.isSubwordOrInt() ? Wrapper.INT : srcWrapper; // widen subword to int
+ // boolean casts not allowed
+- emitPrimCast(srcWrapper.basicTypeChar(), dstWrapper.basicTypeChar());
+- emitBoxing(dstWrapper.primitiveType());
++ emitPrimCast(srcWrapper, dstWrapper);
++ emitBoxing(dstWrapper);
+ }
+
+ // If the return type is void we return a null reference.
+ if (rtype == void.class) {
+ mv.visitInsn(Opcodes.ACONST_NULL);
+ }
+- emitReturnInsn(Object.class); // NOTE: NamedFunction invokers always return a reference value.
++ emitReturnInsn(L_TYPE); // NOTE: NamedFunction invokers always return a reference value.
+
+ classFileEpilogue();
+ bogusMethod(dstType);
+--- ./jdk/src/share/classes/java/lang/invoke/Invokers.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/Invokers.java Wed Feb 04 12:14:43 2015 -0800
+@@ -25,8 +25,9 @@
+
+ package java.lang.invoke;
+
++import java.lang.reflect.Array;
+ import java.util.Arrays;
+-import sun.invoke.empty.Empty;
++
+ import static java.lang.invoke.MethodHandleStatics.*;
+ import static java.lang.invoke.MethodHandleNatives.Constants.*;
+ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+@@ -40,52 +41,63 @@
+ // exact type (sans leading taget MH) for the outgoing call
+ private final MethodType targetType;
+
+- // FIXME: Get rid of the invokers that are not useful.
+-
+- // exact invoker for the outgoing call
+- private /*lazy*/ MethodHandle exactInvoker;
+- private /*lazy*/ MethodHandle basicInvoker; // invokeBasic (unchecked exact)
+-
+- // erased (partially untyped but with primitives) invoker for the outgoing call
+- // FIXME: get rid of
+- private /*lazy*/ MethodHandle erasedInvoker;
+- // FIXME: get rid of
+- /*lazy*/ MethodHandle erasedInvokerWithDrops; // for InvokeGeneric
+-
+- // general invoker for the outgoing call
+- private /*lazy*/ MethodHandle generalInvoker;
+-
+- // general invoker for the outgoing call, uses varargs
+- private /*lazy*/ MethodHandle varargsInvoker;
+-
+- // general invoker for the outgoing call; accepts a trailing Object[]
+- private final /*lazy*/ MethodHandle[] spreadInvokers;
+-
+- // invoker for an unbound callsite
+- private /*lazy*/ MethodHandle uninitializedCallSite;
++ // Cached adapter information:
++ private final @Stable MethodHandle[] invokers = new MethodHandle[INV_LIMIT];
++ // Indexes into invokers:
++ static final int
++ INV_EXACT = 0, // MethodHandles.exactInvoker
++ INV_GENERIC = 1, // MethodHandles.invoker (generic invocation)
++ INV_BASIC = 2, // MethodHandles.basicInvoker
++ INV_LIMIT = 3;
+
+ /** Compute and cache information common to all collecting adapters
+ * that implement members of the erasure-family of the given erased type.
+ */
+ /*non-public*/ Invokers(MethodType targetType) {
+ this.targetType = targetType;
+- this.spreadInvokers = new MethodHandle[targetType.parameterCount()+1];
+ }
+
+ /*non-public*/ MethodHandle exactInvoker() {
+- MethodHandle invoker = exactInvoker;
++ MethodHandle invoker = cachedInvoker(INV_EXACT);
+ if (invoker != null) return invoker;
+ invoker = makeExactOrGeneralInvoker(true);
+- exactInvoker = invoker;
+- return invoker;
++ return setCachedInvoker(INV_EXACT, invoker);
+ }
+
+- /*non-public*/ MethodHandle generalInvoker() {
+- MethodHandle invoker = generalInvoker;
++ /*non-public*/ MethodHandle genericInvoker() {
++ MethodHandle invoker = cachedInvoker(INV_GENERIC);
+ if (invoker != null) return invoker;
+ invoker = makeExactOrGeneralInvoker(false);
+- generalInvoker = invoker;
+- return invoker;
++ return setCachedInvoker(INV_GENERIC, invoker);
++ }
++
++ /*non-public*/ MethodHandle basicInvoker() {
++ MethodHandle invoker = cachedInvoker(INV_BASIC);
++ if (invoker != null) return invoker;
++ MethodType basicType = targetType.basicType();
++ if (basicType != targetType) {
++ // double cache; not used significantly
++ return setCachedInvoker(INV_BASIC, basicType.invokers().basicInvoker());
++ }
++ invoker = basicType.form().cachedMethodHandle(MethodTypeForm.MH_BASIC_INV);
++ if (invoker == null) {
++ MemberName method = invokeBasicMethod(basicType);
++ invoker = DirectMethodHandle.make(method);
++ assert(checkInvoker(invoker));
++ invoker = basicType.form().setCachedMethodHandle(MethodTypeForm.MH_BASIC_INV, invoker);
++ }
++ return setCachedInvoker(INV_BASIC, invoker);
++ }
++
++ private MethodHandle cachedInvoker(int idx) {
++ return invokers[idx];
++ }
++
++ private synchronized MethodHandle setCachedInvoker(int idx, final MethodHandle invoker) {
++ // Simulate a CAS, to avoid racy duplication of results.
++ MethodHandle prev = invokers[idx];
++ if (prev != null) return prev;
++ return invokers[idx] = invoker;
+ }
+
+ private MethodHandle makeExactOrGeneralInvoker(boolean isExact) {
+@@ -95,7 +107,7 @@
+ LambdaForm lform = invokeHandleForm(mtype, false, which);
+ MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype);
+ String whichName = (isExact ? "invokeExact" : "invoke");
+- invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke(whichName, mtype));
++ invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke(whichName, mtype), false);
+ assert(checkInvoker(invoker));
+ maybeCompileToBytecode(invoker);
+ return invoker;
+@@ -110,21 +122,6 @@
+ }
+ }
+
+- /*non-public*/ MethodHandle basicInvoker() {
+- MethodHandle invoker = basicInvoker;
+- if (invoker != null) return invoker;
+- MethodType basicType = targetType.basicType();
+- if (basicType != targetType) {
+- // double cache; not used significantly
+- return basicInvoker = basicType.invokers().basicInvoker();
+- }
+- MemberName method = invokeBasicMethod(basicType);
+- invoker = DirectMethodHandle.make(method);
+- assert(checkInvoker(invoker));
+- basicInvoker = invoker;
+- return invoker;
+- }
+-
+ // This next one is called from LambdaForm.NamedFunction.<init>.
+ /*non-public*/ static MemberName invokeBasicMethod(MethodType basicType) {
+ assert(basicType == basicType.basicType());
+@@ -145,87 +142,42 @@
+ return true;
+ }
+
+- // FIXME: get rid of
+- /*non-public*/ MethodHandle erasedInvoker() {
+- MethodHandle xinvoker = exactInvoker();
+- MethodHandle invoker = erasedInvoker;
+- if (invoker != null) return invoker;
+- MethodType erasedType = targetType.erase();
+- invoker = xinvoker.asType(erasedType.invokerType());
+- erasedInvoker = invoker;
+- return invoker;
++ /**
++ * Find or create an invoker which passes unchanged a given number of arguments
++ * and spreads the rest from a trailing array argument.
++ * The invoker target type is the post-spread type {@code (TYPEOF(uarg*), TYPEOF(sarg*))=>RT}.
++ * All the {@code sarg}s must have a common type {@code C}. (If there are none, {@code Object} is assumed.}
++ * @param leadingArgCount the number of unchanged (non-spread) arguments
++ * @return {@code invoker.invokeExact(mh, uarg*, C[]{sarg*}) := (RT)mh.invoke(uarg*, sarg*)}
++ */
++ /*non-public*/ MethodHandle spreadInvoker(int leadingArgCount) {
++ int spreadArgCount = targetType.parameterCount() - leadingArgCount;
++ MethodType postSpreadType = targetType;
++ Class<?> argArrayType = impliedRestargType(postSpreadType, leadingArgCount);
++ if (postSpreadType.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY) {
++ return genericInvoker().asSpreader(argArrayType, spreadArgCount);
++ }
++ // Cannot build a generic invoker here of type ginvoker.invoke(mh, a*[254]).
++ // Instead, factor sinvoker.invoke(mh, a) into ainvoker.invoke(filter(mh), a)
++ // where filter(mh) == mh.asSpreader(Object[], spreadArgCount)
++ MethodType preSpreadType = postSpreadType
++ .replaceParameterTypes(leadingArgCount, postSpreadType.parameterCount(), argArrayType);
++ MethodHandle arrayInvoker = MethodHandles.invoker(preSpreadType);
++ MethodHandle makeSpreader = MethodHandles.insertArguments(Lazy.MH_asSpreader, 1, argArrayType, spreadArgCount);
++ return MethodHandles.filterArgument(arrayInvoker, 0, makeSpreader);
+ }
+
+- /*non-public*/ MethodHandle spreadInvoker(int leadingArgCount) {
+- MethodHandle vaInvoker = spreadInvokers[leadingArgCount];
+- if (vaInvoker != null) return vaInvoker;
+- int spreadArgCount = targetType.parameterCount() - leadingArgCount;
+- MethodType spreadInvokerType = targetType
+- .replaceParameterTypes(leadingArgCount, targetType.parameterCount(), Object[].class);
+- if (targetType.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY) {
+- // Factor sinvoker.invoke(mh, a) into ginvoker.asSpreader().invoke(mh, a)
+- // where ginvoker.invoke(mh, a*) => mh.invoke(a*).
+- MethodHandle genInvoker = generalInvoker();
+- vaInvoker = genInvoker.asSpreader(Object[].class, spreadArgCount);
+- } else {
+- // Cannot build a general invoker here of type ginvoker.invoke(mh, a*[254]).
+- // Instead, factor sinvoker.invoke(mh, a) into ainvoker.invoke(filter(mh), a)
+- // where filter(mh) == mh.asSpreader(Object[], spreadArgCount)
+- MethodHandle arrayInvoker = MethodHandles.exactInvoker(spreadInvokerType);
+- MethodHandle makeSpreader;
+- try {
+- makeSpreader = IMPL_LOOKUP
+- .findVirtual(MethodHandle.class, "asSpreader",
+- MethodType.methodType(MethodHandle.class, Class.class, int.class));
+- } catch (ReflectiveOperationException ex) {
+- throw newInternalError(ex);
+- }
+- makeSpreader = MethodHandles.insertArguments(makeSpreader, 1, Object[].class, spreadArgCount);
+- vaInvoker = MethodHandles.filterArgument(arrayInvoker, 0, makeSpreader);
++ private static Class<?> impliedRestargType(MethodType restargType, int fromPos) {
++ if (restargType.isGeneric()) return Object[].class; // can be nothing else
++ int maxPos = restargType.parameterCount();
++ if (fromPos >= maxPos) return Object[].class; // reasonable default
++ Class<?> argType = restargType.parameterType(fromPos);
++ for (int i = fromPos+1; i < maxPos; i++) {
++ if (argType != restargType.parameterType(i))
++ throw newIllegalArgumentException("need homogeneous rest arguments", restargType);
+ }
+- assert(vaInvoker.type().equals(spreadInvokerType.invokerType()));
+- maybeCompileToBytecode(vaInvoker);
+- spreadInvokers[leadingArgCount] = vaInvoker;
+- return vaInvoker;
+- }
+-
+- /*non-public*/ MethodHandle varargsInvoker() {
+- MethodHandle vaInvoker = varargsInvoker;
+- if (vaInvoker != null) return vaInvoker;
+- vaInvoker = spreadInvoker(0).asType(MethodType.genericMethodType(0, true).invokerType());
+- varargsInvoker = vaInvoker;
+- return vaInvoker;
+- }
+-
+- private static MethodHandle THROW_UCS = null;
+-
+- /*non-public*/ MethodHandle uninitializedCallSite() {
+- MethodHandle invoker = uninitializedCallSite;
+- if (invoker != null) return invoker;
+- if (targetType.parameterCount() > 0) {
+- MethodType type0 = targetType.dropParameterTypes(0, targetType.parameterCount());
+- Invokers invokers0 = type0.invokers();
+- invoker = MethodHandles.dropArguments(invokers0.uninitializedCallSite(),
+- 0, targetType.parameterList());
+- assert(invoker.type().equals(targetType));
+- uninitializedCallSite = invoker;
+- return invoker;
+- }
+- invoker = THROW_UCS;
+- if (invoker == null) {
+- try {
+- THROW_UCS = invoker = IMPL_LOOKUP
+- .findStatic(CallSite.class, "uninitializedCallSite",
+- MethodType.methodType(Empty.class));
+- } catch (ReflectiveOperationException ex) {
+- throw newInternalError(ex);
+- }
+- }
+- invoker = MethodHandles.explicitCastArguments(invoker, MethodType.methodType(targetType.returnType()));
+- invoker = invoker.dropArguments(targetType, 0, targetType.parameterCount());
+- assert(invoker.type().equals(targetType));
+- uninitializedCallSite = invoker;
+- return invoker;
++ if (argType == Object.class) return Object[].class;
++ return Array.newInstance(argType, 0).getClass();
+ }
+
+ public String toString() {
+@@ -308,7 +260,9 @@
+ : Arrays.asList(mtype, customized, which, nameCursor, names.length);
+ if (MTYPE_ARG >= INARG_LIMIT) {
+ assert(names[MTYPE_ARG] == null);
+- NamedFunction getter = BoundMethodHandle.getSpeciesData("L").getterFunction(0);
++ BoundMethodHandle.SpeciesData speciesData = BoundMethodHandle.speciesData_L();
++ names[THIS_MH] = names[THIS_MH].withConstraint(speciesData);
++ NamedFunction getter = speciesData.getterFunction(0);
+ names[MTYPE_ARG] = new Name(getter, names[THIS_MH]);
+ // else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM)
+ }
+@@ -360,9 +314,6 @@
+ Object checkGenericType(Object mhObj, Object expectedObj) {
+ MethodHandle mh = (MethodHandle) mhObj;
+ MethodType expected = (MethodType) expectedObj;
+- if (mh.type() == expected) return mh;
+- MethodHandle atc = mh.asTypeCache;
+- if (atc != null && atc.type() == expected) return atc;
+ return mh.asType(expected);
+ /* Maybe add more paths here. Possible optimizations:
+ * for (R)MH.invoke(a*),
+@@ -436,27 +387,40 @@
+ }
+
+ // Local constant functions:
+- private static final NamedFunction NF_checkExactType;
+- private static final NamedFunction NF_checkGenericType;
+- private static final NamedFunction NF_asType;
+- private static final NamedFunction NF_getCallSiteTarget;
++ private static final NamedFunction
++ NF_checkExactType,
++ NF_checkGenericType,
++ NF_getCallSiteTarget;
+ static {
+ try {
+- NF_checkExactType = new NamedFunction(Invokers.class
+- .getDeclaredMethod("checkExactType", Object.class, Object.class));
+- NF_checkGenericType = new NamedFunction(Invokers.class
+- .getDeclaredMethod("checkGenericType", Object.class, Object.class));
+- NF_asType = new NamedFunction(MethodHandle.class
+- .getDeclaredMethod("asType", MethodType.class));
+- NF_getCallSiteTarget = new NamedFunction(Invokers.class
+- .getDeclaredMethod("getCallSiteTarget", Object.class));
+- NF_checkExactType.resolve();
+- NF_checkGenericType.resolve();
+- NF_getCallSiteTarget.resolve();
+- // bound
++ NamedFunction nfs[] = {
++ NF_checkExactType = new NamedFunction(Invokers.class
++ .getDeclaredMethod("checkExactType", Object.class, Object.class)),
++ NF_checkGenericType = new NamedFunction(Invokers.class
++ .getDeclaredMethod("checkGenericType", Object.class, Object.class)),
++ NF_getCallSiteTarget = new NamedFunction(Invokers.class
++ .getDeclaredMethod("getCallSiteTarget", Object.class))
++ };
++ for (NamedFunction nf : nfs) {
++ // Each nf must be statically invocable or we get tied up in our bootstraps.
++ assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
++ nf.resolve();
++ }
+ } catch (ReflectiveOperationException ex) {
+ throw newInternalError(ex);
+ }
+ }
+
++ private static class Lazy {
++ private static final MethodHandle MH_asSpreader;
++
++ static {
++ try {
++ MH_asSpreader = IMPL_LOOKUP.findVirtual(MethodHandle.class, "asSpreader",
++ MethodType.methodType(MethodHandle.class, Class.class, int.class));
++ } catch (ReflectiveOperationException ex) {
++ throw newInternalError(ex);
++ }
++ }
++ }
+ }
+--- ./jdk/src/share/classes/java/lang/invoke/LambdaForm.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/LambdaForm.java Wed Feb 04 12:14:43 2015 -0800
+@@ -27,17 +27,16 @@
+
+ import java.lang.annotation.*;
+ import java.lang.reflect.Method;
+-import java.util.Map;
+ import java.util.List;
+ import java.util.Arrays;
+-import java.util.ArrayList;
+ import java.util.HashMap;
+-import java.util.concurrent.ConcurrentHashMap;
++
+ import sun.invoke.util.Wrapper;
++import java.lang.reflect.Field;
++
++import static java.lang.invoke.LambdaForm.BasicType.*;
+ import static java.lang.invoke.MethodHandleStatics.*;
+ import static java.lang.invoke.MethodHandleNatives.Constants.*;
+-import java.lang.reflect.Field;
+-import java.util.Objects;
+
+ /**
+ * The symbolic, non-executable form of a method handle's invocation semantics.
+@@ -120,36 +119,165 @@
+ class LambdaForm {
+ final int arity;
+ final int result;
++ final boolean forceInline;
+ @Stable final Name[] names;
+ final String debugName;
+ MemberName vmentry; // low-level behavior, or null if not yet prepared
+ private boolean isCompiled;
+
+- // Caches for common structural transforms:
+- LambdaForm[] bindCache;
++ volatile Object transformCache; // managed by LambdaFormEditor
+
+ public static final int VOID_RESULT = -1, LAST_RESULT = -2;
+
++ enum BasicType {
++ L_TYPE('L', Object.class, Wrapper.OBJECT), // all reference types
++ I_TYPE('I', int.class, Wrapper.INT),
++ J_TYPE('J', long.class, Wrapper.LONG),
++ F_TYPE('F', float.class, Wrapper.FLOAT),
++ D_TYPE('D', double.class, Wrapper.DOUBLE), // all primitive types
++ V_TYPE('V', void.class, Wrapper.VOID); // not valid in all contexts
++
++ static final BasicType[] ALL_TYPES = BasicType.values();
++ static final BasicType[] ARG_TYPES = Arrays.copyOf(ALL_TYPES, ALL_TYPES.length-1);
++
++ static final int ARG_TYPE_LIMIT = ARG_TYPES.length;
++ static final int TYPE_LIMIT = ALL_TYPES.length;
++
++ private final char btChar;
++ private final Class<?> btClass;
++ private final Wrapper btWrapper;
++
++ private BasicType(char btChar, Class<?> btClass, Wrapper wrapper) {
++ this.btChar = btChar;
++ this.btClass = btClass;
++ this.btWrapper = wrapper;
++ }
++
++ char basicTypeChar() {
++ return btChar;
++ }
++ Class<?> basicTypeClass() {
++ return btClass;
++ }
++ Wrapper basicTypeWrapper() {
++ return btWrapper;
++ }
++ int basicTypeSlots() {
++ return btWrapper.stackSlots();
++ }
++
++ static BasicType basicType(byte type) {
++ return ALL_TYPES[type];
++ }
++ static BasicType basicType(char type) {
++ switch (type) {
++ case 'L': return L_TYPE;
++ case 'I': return I_TYPE;
++ case 'J': return J_TYPE;
++ case 'F': return F_TYPE;
++ case 'D': return D_TYPE;
++ case 'V': return V_TYPE;
++ // all subword types are represented as ints
++ case 'Z':
++ case 'B':
++ case 'S':
++ case 'C':
++ return I_TYPE;
++ default:
++ throw newInternalError("Unknown type char: '"+type+"'");
++ }
++ }
++ static BasicType basicType(Wrapper type) {
++ char c = type.basicTypeChar();
++ return basicType(c);
++ }
++ static BasicType basicType(Class<?> type) {
++ if (!type.isPrimitive()) return L_TYPE;
++ return basicType(Wrapper.forPrimitiveType(type));
++ }
++
++ static char basicTypeChar(Class<?> type) {
++ return basicType(type).btChar;
++ }
++ static BasicType[] basicTypes(List<Class<?>> types) {
++ BasicType[] btypes = new BasicType[types.size()];
++ for (int i = 0; i < btypes.length; i++) {
++ btypes[i] = basicType(types.get(i));
++ }
++ return btypes;
++ }
++ static BasicType[] basicTypes(String types) {
++ BasicType[] btypes = new BasicType[types.length()];
++ for (int i = 0; i < btypes.length; i++) {
++ btypes[i] = basicType(types.charAt(i));
++ }
++ return btypes;
++ }
++ static byte[] basicTypesOrd(BasicType[] btypes) {
++ byte[] ords = new byte[btypes.length];
++ for (int i = 0; i < btypes.length; i++) {
++ ords[i] = (byte)btypes[i].ordinal();
++ }
++ return ords;
++ }
++ static boolean isBasicTypeChar(char c) {
++ return "LIJFDV".indexOf(c) >= 0;
++ }
++ static boolean isArgBasicTypeChar(char c) {
++ return "LIJFD".indexOf(c) >= 0;
++ }
++
++ static { assert(checkBasicType()); }
++ private static boolean checkBasicType() {
++ for (int i = 0; i < ARG_TYPE_LIMIT; i++) {
++ assert ARG_TYPES[i].ordinal() == i;
++ assert ARG_TYPES[i] == ALL_TYPES[i];
++ }
++ for (int i = 0; i < TYPE_LIMIT; i++) {
++ assert ALL_TYPES[i].ordinal() == i;
++ }
++ assert ALL_TYPES[TYPE_LIMIT - 1] == V_TYPE;
++ assert !Arrays.asList(ARG_TYPES).contains(V_TYPE);
++ return true;
++ }
++ }
++
+ LambdaForm(String debugName,
+ int arity, Name[] names, int result) {
++ this(debugName, arity, names, result, true);
++ }
++ LambdaForm(String debugName,
++ int arity, Name[] names, int result, boolean forceInline) {
+ assert(namesOK(arity, names));
+ this.arity = arity;
+ this.result = fixResult(result, names);
+ this.names = names.clone();
+- this.debugName = debugName;
+- normalize();
++ this.debugName = fixDebugName(debugName);
++ this.forceInline = forceInline;
++ int maxOutArity = normalize();
++ if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) {
++ // Cannot use LF interpreter on very high arity expressions.
++ assert(maxOutArity <= MethodType.MAX_JVM_ARITY);
++ compileToBytecode();
++ }
+ }
+-
+ LambdaForm(String debugName,
+ int arity, Name[] names) {
+- this(debugName,
+- arity, names, LAST_RESULT);
++ this(debugName, arity, names, LAST_RESULT, true);
+ }
+-
++ LambdaForm(String debugName,
++ int arity, Name[] names, boolean forceInline) {
++ this(debugName, arity, names, LAST_RESULT, forceInline);
++ }
+ LambdaForm(String debugName,
+ Name[] formals, Name[] temps, Name result) {
+ this(debugName,
+- formals.length, buildNames(formals, temps, result), LAST_RESULT);
++ formals.length, buildNames(formals, temps, result), LAST_RESULT, true);
++ }
++ LambdaForm(String debugName,
++ Name[] formals, Name[] temps, Name result, boolean forceInline) {
++ this(debugName,
++ formals.length, buildNames(formals, temps, result), LAST_RESULT, forceInline);
+ }
+
+ private static Name[] buildNames(Name[] formals, Name[] temps, Name result) {
+@@ -163,17 +291,22 @@
+ }
+
+ private LambdaForm(String sig) {
++ this(sig, true);
++ }
++
++ private LambdaForm(String sig, boolean forceInline) {
+ // Make a blank lambda form, which returns a constant zero or null.
+ // It is used as a template for managing the invocation of similar forms that are non-empty.
+ // Called only from getPreparedForm.
+ assert(isValidSignature(sig));
+ this.arity = signatureArity(sig);
+- this.result = (signatureReturn(sig) == 'V' ? -1 : arity);
++ this.result = (signatureReturn(sig) == V_TYPE ? -1 : arity);
+ this.names = buildEmptyNames(arity, sig);
+ this.debugName = "LF.zero";
++ this.forceInline = forceInline;
+ assert(nameRefsAreLegal());
+ assert(isEmpty());
+- assert(sig.equals(basicTypeSignature()));
++ assert(sig.equals(basicTypeSignature())) : sig + " != " + basicTypeSignature();
+ }
+
+ private static Name[] buildEmptyNames(int arity, String basicTypeSignature) {
+@@ -181,22 +314,53 @@
+ int resultPos = arity + 1; // skip '_'
+ if (arity < 0 || basicTypeSignature.length() != resultPos+1)
+ throw new IllegalArgumentException("bad arity for "+basicTypeSignature);
+- int numRes = (basicTypeSignature.charAt(resultPos) == 'V' ? 0 : 1);
++ int numRes = (basicType(basicTypeSignature.charAt(resultPos)) == V_TYPE ? 0 : 1);
+ Name[] names = arguments(numRes, basicTypeSignature.substring(0, arity));
+ for (int i = 0; i < numRes; i++) {
+- names[arity + i] = constantZero(arity + i, basicTypeSignature.charAt(resultPos + i));
++ Name zero = new Name(constantZero(basicType(basicTypeSignature.charAt(resultPos + i))));
++ names[arity + i] = zero.newIndex(arity + i);
+ }
+ return names;
+ }
+
+ private static int fixResult(int result, Name[] names) {
+- if (result >= 0) {
+- if (names[result].type == 'V')
+- return -1;
+- } else if (result == LAST_RESULT) {
+- return names.length - 1;
++ if (result == LAST_RESULT)
++ result = names.length - 1; // might still be void
++ if (result >= 0 && names[result].type == V_TYPE)
++ result = VOID_RESULT;
++ return result;
++ }
++
++ private static String fixDebugName(String debugName) {
++ if (DEBUG_NAME_COUNTERS != null) {
++ int under = debugName.indexOf('_');
++ int length = debugName.length();
++ if (under < 0) under = length;
++ String debugNameStem = debugName.substring(0, under);
++ Integer ctr;
++ synchronized (DEBUG_NAME_COUNTERS) {
++ ctr = DEBUG_NAME_COUNTERS.get(debugNameStem);
++ if (ctr == null) ctr = 0;
++ DEBUG_NAME_COUNTERS.put(debugNameStem, ctr+1);
++ }
++ StringBuilder buf = new StringBuilder(debugNameStem);
++ buf.append('_');
++ int leadingZero = buf.length();
++ buf.append((int) ctr);
++ for (int i = buf.length() - leadingZero; i < 3; i++)
++ buf.insert(leadingZero, '0');
++ if (under < length) {
++ ++under; // skip "_"
++ while (under < length && Character.isDigit(debugName.charAt(under))) {
++ ++under;
++ }
++ if (under < length && debugName.charAt(under) == '_') ++under;
++ if (under < length)
++ buf.append('_').append(debugName, under, length);
++ }
++ return buf.toString();
+ }
+- return result;
++ return debugName;
+ }
+
+ private static boolean namesOK(int arity, Name[] names) {
+@@ -211,9 +375,12 @@
+ return true;
+ }
+
+- /** Renumber and/or replace params so that they are interned and canonically numbered. */
+- private void normalize() {
++ /** Renumber and/or replace params so that they are interned and canonically numbered.
++ * @return maximum argument list length among the names (since we have to pass over them anyway)
++ */
++ private int normalize() {
+ Name[] oldNames = null;
++ int maxOutArity = 0;
+ int changesStart = 0;
+ for (int i = 0; i < names.length; i++) {
+ Name n = names[i];
+@@ -224,6 +391,8 @@
+ }
+ names[i] = n.cloneWithIndex(i);
+ }
++ if (n.arguments != null && maxOutArity < n.arguments.length)
++ maxOutArity = n.arguments.length;
+ }
+ if (oldNames != null) {
+ int startFixing = arity;
+@@ -250,6 +419,7 @@
+ }
+ assert(nameRefsAreLegal());
+ }
++ return maxOutArity;
+ }
+
+ /**
+@@ -261,7 +431,7 @@
+ * This allows Name references to be freely reused to construct
+ * fresh lambdas, without confusion.
+ */
+- private boolean nameRefsAreLegal() {
++ boolean nameRefsAreLegal() {
+ assert(arity >= 0 && arity <= names.length);
+ assert(result >= -1 && result < names.length);
+ // Do all names possess an index consistent with their local definition order?
+@@ -294,16 +464,28 @@
+ // }
+
+ /** Report the return type. */
+- char returnType() {
+- if (result < 0) return 'V';
++ BasicType returnType() {
++ if (result < 0) return V_TYPE;
+ Name n = names[result];
+ return n.type;
+ }
+
+ /** Report the N-th argument type. */
+- char parameterType(int n) {
++ BasicType parameterType(int n) {
++ return parameter(n).type;
++ }
++
++ /** Report the N-th argument name. */
++ Name parameter(int n) {
+ assert(n < arity);
+- return names[n].type;
++ Name param = names[n];
++ assert(param.isParam());
++ return param;
++ }
++
++ /** Report the N-th argument type constraint. */
++ Object parameterConstraint(int n) {
++ return parameter(n).constraint;
+ }
+
+ /** Report the arity. */
+@@ -311,6 +493,11 @@
+ return arity;
+ }
+
++ /** Report the number of expressions (non-parameter names). */
++ int expressionCount() {
++ return names.length - arity;
++ }
++
+ /** Return the method type corresponding to my basic type signature. */
+ MethodType methodType() {
+ return signatureType(basicTypeSignature());
+@@ -319,15 +506,15 @@
+ final String basicTypeSignature() {
+ StringBuilder buf = new StringBuilder(arity() + 3);
+ for (int i = 0, a = arity(); i < a; i++)
+- buf.append(parameterType(i));
+- return buf.append('_').append(returnType()).toString();
++ buf.append(parameterType(i).basicTypeChar());
++ return buf.append('_').append(returnType().basicTypeChar()).toString();
+ }
+ static int signatureArity(String sig) {
+ assert(isValidSignature(sig));
+ return sig.indexOf('_');
+ }
+- static char signatureReturn(String sig) {
+- return sig.charAt(signatureArity(sig)+1);
++ static BasicType signatureReturn(String sig) {
++ return basicType(sig.charAt(signatureArity(sig) + 1));
+ }
+ static boolean isValidSignature(String sig) {
+ int arity = sig.indexOf('_');
+@@ -339,27 +526,15 @@
+ char c = sig.charAt(i);
+ if (c == 'V')
+ return (i == siglen - 1 && arity == siglen - 2);
+- if (ALL_TYPES.indexOf(c) < 0) return false; // must be [LIJFD]
++ if (!isArgBasicTypeChar(c)) return false; // must be [LIJFD]
+ }
+ return true; // [LIJFD]*_[LIJFDV]
+ }
+- static Class<?> typeClass(char t) {
+- switch (t) {
+- case 'I': return int.class;
+- case 'J': return long.class;
+- case 'F': return float.class;
+- case 'D': return double.class;
+- case 'L': return Object.class;
+- case 'V': return void.class;
+- default: assert false;
+- }
+- return null;
+- }
+ static MethodType signatureType(String sig) {
+ Class<?>[] ptypes = new Class<?>[signatureArity(sig)];
+ for (int i = 0; i < ptypes.length; i++)
+- ptypes[i] = typeClass(sig.charAt(i));
+- Class<?> rtype = typeClass(signatureReturn(sig));
++ ptypes[i] = basicType(sig.charAt(i)).btClass;
++ Class<?> rtype = signatureReturn(sig).btClass;
+ return MethodType.methodType(rtype, ptypes);
+ }
+
+@@ -457,21 +632,12 @@
+ isCompiled = true;
+ return vmentry;
+ } catch (Error | Exception ex) {
+- throw newInternalError("compileToBytecode", ex);
++ throw newInternalError(this.toString(), ex);
+ }
+ }
+
+- private static final ConcurrentHashMap<String,LambdaForm> PREPARED_FORMS;
+- static {
+- int capacity = 512; // expect many distinct signatures over time
+- float loadFactor = 0.75f; // normal default
+- int writers = 1;
+- PREPARED_FORMS = new ConcurrentHashMap<>(capacity, loadFactor, writers);
+- }
+-
+- private static Map<String,LambdaForm> computeInitialPreparedForms() {
++ private static void computeInitialPreparedForms() {
+ // Find all predefined invokers and associate them with canonical empty lambda forms.
+- HashMap<String,LambdaForm> forms = new HashMap<>();
+ for (MemberName m : MemberName.getFactory().getMethods(LambdaForm.class, false, null, null, null)) {
+ if (!m.isStatic() || !m.isPackage()) continue;
+ MethodType mt = m.getMethodType();
+@@ -482,13 +648,9 @@
+ assert(m.getName().equals("interpret" + sig.substring(sig.indexOf('_'))));
+ LambdaForm form = new LambdaForm(sig);
+ form.vmentry = m;
+- form = mt.form().setCachedLambdaForm(MethodTypeForm.LF_COUNTER, form);
+- // FIXME: get rid of PREPARED_FORMS; use MethodTypeForm cache only
+- forms.put(sig, form);
++ form = mt.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, form);
+ }
+ }
+- //System.out.println("computeInitialPreparedForms => "+forms);
+- return forms;
+ }
+
+ // Set this false to disable use of the interpret_L methods defined in this file.
+@@ -522,13 +684,11 @@
+ }
+ private static LambdaForm getPreparedForm(String sig) {
+ MethodType mtype = signatureType(sig);
+- //LambdaForm prep = PREPARED_FORMS.get(sig);
+ LambdaForm prep = mtype.form().cachedLambdaForm(MethodTypeForm.LF_INTERPRET);
+ if (prep != null) return prep;
+ assert(isValidSignature(sig));
+ prep = new LambdaForm(sig);
+ prep.vmentry = InvokerBytecodeGenerator.generateLambdaFormInterpreterEntryPoint(sig);
+- //LambdaForm prep2 = PREPARED_FORMS.putIfAbsent(sig.intern(), prep);
+ return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, prep);
+ }
+
+@@ -543,21 +703,21 @@
+ assert(mt.parameterCount() == arity-1);
+ for (int i = 0; i < av.length; i++) {
+ Class<?> pt = (i == 0 ? MethodHandle.class : mt.parameterType(i-1));
+- assert(valueMatches(sig.charAt(i), pt, av[i]));
++ assert(valueMatches(basicType(sig.charAt(i)), pt, av[i]));
+ }
+ return true;
+ }
+- private static boolean valueMatches(char tc, Class<?> type, Object x) {
++ private static boolean valueMatches(BasicType tc, Class<?> type, Object x) {
+ // The following line is needed because (...)void method handles can use non-void invokers
+- if (type == void.class) tc = 'V'; // can drop any kind of value
++ if (type == void.class) tc = V_TYPE; // can drop any kind of value
+ assert tc == basicType(type) : tc + " == basicType(" + type + ")=" + basicType(type);
+ switch (tc) {
+- case 'I': assert checkInt(type, x) : "checkInt(" + type + "," + x +")"; break;
+- case 'J': assert x instanceof Long : "instanceof Long: " + x; break;
+- case 'F': assert x instanceof Float : "instanceof Float: " + x; break;
+- case 'D': assert x instanceof Double : "instanceof Double: " + x; break;
+- case 'L': assert checkRef(type, x) : "checkRef(" + type + "," + x + ")"; break;
+- case 'V': break; // allow anything here; will be dropped
++ case I_TYPE: assert checkInt(type, x) : "checkInt(" + type + "," + x +")"; break;
++ case J_TYPE: assert x instanceof Long : "instanceof Long: " + x; break;
++ case F_TYPE: assert x instanceof Float : "instanceof Float: " + x; break;
++ case D_TYPE: assert x instanceof Double : "instanceof Double: " + x; break;
++ case L_TYPE: assert checkRef(type, x) : "checkRef(" + type + "," + x + ")"; break;
++ case V_TYPE: break; // allow anything here; will be dropped
+ default: assert(false);
+ }
+ return true;
+@@ -584,10 +744,7 @@
+ /** If the invocation count hits the threshold we spin bytecodes and call that subsequently. */
+ private static final int COMPILE_THRESHOLD;
+ static {
+- if (MethodHandleStatics.COMPILE_THRESHOLD != null)
+- COMPILE_THRESHOLD = MethodHandleStatics.COMPILE_THRESHOLD;
+- else
+- COMPILE_THRESHOLD = 30; // default value
++ COMPILE_THRESHOLD = Math.max(-1, MethodHandleStatics.COMPILE_THRESHOLD);
+ }
+ private int invocationCounter = 0;
+
+@@ -603,7 +760,9 @@
+ for (int i = argumentValues.length; i < values.length; i++) {
+ values[i] = interpretName(names[i], values);
+ }
+- return (result < 0) ? null : values[result];
++ Object rv = (result < 0) ? null : values[result];
++ assert(resultCheck(argumentValues, rv));
++ return rv;
+ }
+
+ @Hidden
+@@ -660,28 +819,6 @@
+ return rval;
+ }
+
+- //** This transform is applied (statically) to every name.function. */
+- /*
+- private static MethodHandle eraseSubwordTypes(MethodHandle mh) {
+- MethodType mt = mh.type();
+- if (mt.hasPrimitives()) {
+- mt = mt.changeReturnType(eraseSubwordType(mt.returnType()));
+- for (int i = 0; i < mt.parameterCount(); i++) {
+- mt = mt.changeParameterType(i, eraseSubwordType(mt.parameterType(i)));
+- }
+- mh = MethodHandles.explicitCastArguments(mh, mt);
+- }
+- return mh;
+- }
+- private static Class<?> eraseSubwordType(Class<?> type) {
+- if (!type.isPrimitive()) return type;
+- if (type == int.class) return type;
+- Wrapper w = Wrapper.forPrimitiveType(type);
+- if (w.isSubwordOrInt()) return int.class;
+- return type;
+- }
+- */
+-
+ static void traceInterpreter(String event, Object obj, Object... args) {
+ if (TRACE_INTERPRETER) {
+ System.out.println("LFI: "+event+" "+(obj != null ? obj : "")+(args != null && args.length != 0 ? Arrays.asList(args) : ""));
+@@ -694,8 +831,16 @@
+ assert(argumentValues.length == arity) : arity+"!="+Arrays.asList(argumentValues)+".length";
+ // also check that the leading (receiver) argument is somehow bound to this LF:
+ assert(argumentValues[0] instanceof MethodHandle) : "not MH: " + argumentValues[0];
+- assert(((MethodHandle)argumentValues[0]).internalForm() == this);
++ MethodHandle mh = (MethodHandle) argumentValues[0];
++ assert(mh.internalForm() == this);
+ // note: argument #0 could also be an interface wrapper, in the future
++ argumentTypesMatch(basicTypeSignature(), argumentValues);
++ return true;
++ }
++ private boolean resultCheck(Object[] argumentValues, Object result) {
++ MethodHandle mh = (MethodHandle) argumentValues[0];
++ MethodType mt = mh.type();
++ assert(valueMatches(returnType(), mt.returnType(), result));
+ return true;
+ }
+
+@@ -714,7 +859,7 @@
+ if (i == arity) buf.append(")=>{");
+ Name n = names[i];
+ if (i >= arity) buf.append("\n ");
+- buf.append(n);
++ buf.append(n.paramString());
+ if (i < arity) {
+ if (i+1 < arity) buf.append(",");
+ continue;
+@@ -722,6 +867,7 @@
+ buf.append("=").append(n.exprString());
+ buf.append(";");
+ }
++ if (arity == names.length) buf.append(")=>{");
+ buf.append(result < 0 ? "void" : names[result]).append("}");
+ if (TRACE_INTERPRETER) {
+ // Extra verbosity:
+@@ -731,135 +877,19 @@
+ return buf.toString();
+ }
+
+- /**
+- * Apply immediate binding for a Name in this form indicated by its position relative to the form.
+- * The first parameter to a LambdaForm, a0:L, always represents the form's method handle, so 0 is not
+- * accepted as valid.
+- */
+- LambdaForm bindImmediate(int pos, char basicType, Object value) {
+- // must be an argument, and the types must match
+- assert pos > 0 && pos < arity && names[pos].type == basicType && Name.typesMatch(basicType, value);
+-
+- int arity2 = arity - 1;
+- Name[] names2 = new Name[names.length - 1];
+- for (int r = 0, w = 0; r < names.length; ++r, ++w) { // (r)ead from names, (w)rite to names2
+- Name n = names[r];
+- if (n.isParam()) {
+- if (n.index == pos) {
+- // do not copy over the argument that is to be replaced with a literal,
+- // but adjust the write index
+- --w;
+- } else {
+- names2[w] = new Name(w, n.type);
+- }
+- } else {
+- Object[] arguments2 = new Object[n.arguments.length];
+- for (int i = 0; i < n.arguments.length; ++i) {
+- Object arg = n.arguments[i];
+- if (arg instanceof Name) {
+- int ni = ((Name) arg).index;
+- if (ni == pos) {
+- arguments2[i] = value;
+- } else if (ni < pos) {
+- // replacement position not yet passed
+- arguments2[i] = names2[ni];
+- } else {
+- // replacement position passed
+- arguments2[i] = names2[ni - 1];
+- }
+- } else {
+- arguments2[i] = arg;
+- }
+- }
+- names2[w] = new Name(n.function, arguments2);
+- names2[w].initIndex(w);
+- }
+- }
+-
+- int result2 = result == -1 ? -1 : result - 1;
+- return new LambdaForm(debugName, arity2, names2, result2);
++ @Override
++ public boolean equals(Object obj) {
++ return obj instanceof LambdaForm && equals((LambdaForm)obj);
+ }
+-
+- LambdaForm bind(int namePos, BoundMethodHandle.SpeciesData oldData) {
+- Name name = names[namePos];
+- BoundMethodHandle.SpeciesData newData = oldData.extendWithType(name.type);
+- return bind(name, newData.getterName(names[0], oldData.fieldCount()), oldData, newData);
++ public boolean equals(LambdaForm that) {
++ if (this.result != that.result) return false;
++ return Arrays.equals(this.names, that.names);
+ }
+- LambdaForm bind(Name name, Name binding,
+- BoundMethodHandle.SpeciesData oldData,
+- BoundMethodHandle.SpeciesData newData) {
+- int pos = name.index;
+- assert(name.isParam());
+- assert(!binding.isParam());
+- assert(name.type == binding.type);
+- assert(0 <= pos && pos < arity && names[pos] == name);
+- assert(binding.function.memberDeclaringClassOrNull() == newData.clazz);
+- assert(oldData.getters.length == newData.getters.length-1);
+- if (bindCache != null) {
+- LambdaForm form = bindCache[pos];
+- if (form != null) {
+- assert(form.contains(binding)) : "form << " + form + " >> does not contain binding << " + binding + " >>";
+- return form;
+- }
+- } else {
+- bindCache = new LambdaForm[arity];
+- }
+- assert(nameRefsAreLegal());
+- int arity2 = arity-1;
+- Name[] names2 = names.clone();
+- names2[pos] = binding; // we might move this in a moment
+-
+- // The newly created LF will run with a different BMH.
+- // Switch over any pre-existing BMH field references to the new BMH class.
+- int firstOldRef = -1;
+- for (int i = 0; i < names2.length; i++) {
+- Name n = names[i];
+- if (n.function != null &&
+- n.function.memberDeclaringClassOrNull() == oldData.clazz) {
+- MethodHandle oldGetter = n.function.resolvedHandle;
+- MethodHandle newGetter = null;
+- for (int j = 0; j < oldData.getters.length; j++) {
+- if (oldGetter == oldData.getters[j])
+- newGetter = newData.getters[j];
+- }
+- if (newGetter != null) {
+- if (firstOldRef < 0) firstOldRef = i;
+- Name n2 = new Name(newGetter, n.arguments);
+- names2[i] = n2;
+- }
+- }
+- }
+-
+- // Walk over the new list of names once, in forward order.
+- // Replace references to 'name' with 'binding'.
+- // Replace data structure references to the old BMH species with the new.
+- // This might cause a ripple effect, but it will settle in one pass.
+- assert(firstOldRef < 0 || firstOldRef > pos);
+- for (int i = pos+1; i < names2.length; i++) {
+- if (i <= arity2) continue;
+- names2[i] = names2[i].replaceNames(names, names2, pos, i);
+- }
+-
+- // (a0, a1, name=a2, a3, a4) => (a0, a1, a3, a4, binding)
+- int insPos = pos;
+- for (; insPos+1 < names2.length; insPos++) {
+- Name n = names2[insPos+1];
+- if (n.isSiblingBindingBefore(binding)) {
+- names2[insPos] = n;
+- } else {
+- break;
+- }
+- }
+- names2[insPos] = binding;
+-
+- // Since we moved some stuff, maybe update the result reference:
+- int result2 = result;
+- if (result2 == pos)
+- result2 = insPos;
+- else if (result2 > pos && result2 <= insPos)
+- result2 -= 1;
+-
+- return bindCache[pos] = new LambdaForm(debugName, arity2, names2, result2);
++ public int hashCode() {
++ return result + 31 * Arrays.hashCode(names);
++ }
++ LambdaFormEditor editor() {
++ return LambdaFormEditor.lambdaFormEditor(this);
+ }
+
+ boolean contains(Name name) {
+@@ -874,17 +904,17 @@
+ return false;
+ }
+
+- LambdaForm addArguments(int pos, char... types) {
+- assert(pos <= arity);
++ LambdaForm addArguments(int pos, BasicType... types) {
++ // names array has MH in slot 0; skip it.
++ int argpos = pos + 1;
++ assert(argpos <= arity);
+ int length = names.length;
+ int inTypes = types.length;
+ Name[] names2 = Arrays.copyOf(names, length + inTypes);
+ int arity2 = arity + inTypes;
+ int result2 = result;
+- if (result2 >= arity)
++ if (result2 >= argpos)
+ result2 += inTypes;
+- // names array has MH in slot 0; skip it.
+- int argpos = pos + 1;
+ // Note: The LF constructor will rename names2[argpos...].
+ // Make space for new arguments (shift temporaries).
+ System.arraycopy(names, argpos, names2, argpos + inTypes, length - argpos);
+@@ -895,13 +925,10 @@
+ }
+
+ LambdaForm addArguments(int pos, List<Class<?>> types) {
+- char[] basicTypes = new char[types.size()];
+- for (int i = 0; i < basicTypes.length; i++)
+- basicTypes[i] = basicType(types.get(i));
+- return addArguments(pos, basicTypes);
++ return addArguments(pos, basicTypes(types));
+ }
+
+- LambdaForm permuteArguments(int skip, int[] reorder, char[] types) {
++ LambdaForm permuteArguments(int skip, int[] reorder, BasicType[] types) {
+ // Note: When inArg = reorder[outArg], outArg is fed by a copy of inArg.
+ // The types are the types of the new (incoming) arguments.
+ int length = names.length;
+@@ -960,7 +987,7 @@
+ return new LambdaForm(debugName, arity2, names2, result2);
+ }
+
+- static boolean permutedTypesMatch(int[] reorder, char[] types, Name[] names, int skip) {
++ static boolean permutedTypesMatch(int[] reorder, BasicType[] types, Name[] names, int skip) {
+ int inTypes = types.length;
+ int outArgs = reorder.length;
+ for (int i = 0; i < outArgs; i++) {
+@@ -980,8 +1007,9 @@
+ }
+ NamedFunction(MemberName member, MethodHandle resolvedHandle) {
+ this.member = member;
+- //resolvedHandle = eraseSubwordTypes(resolvedHandle);
+ this.resolvedHandle = resolvedHandle;
++ // The following assert is almost always correct, but will fail for corner cases, such as PrivateInvokeTest.
++ //assert(!isInvokeBasic());
+ }
+ NamedFunction(MethodType basicInvokerType) {
+ assert(basicInvokerType == basicInvokerType.basicType()) : basicInvokerType;
+@@ -992,6 +1020,13 @@
+ // necessary to pass BigArityTest
+ this.member = Invokers.invokeBasicMethod(basicInvokerType);
+ }
++ assert(isInvokeBasic());
++ }
++
++ private boolean isInvokeBasic() {
++ return member != null &&
++ member.isMethodHandleInvoke() &&
++ "invokeBasic".equals(member.getName());
+ }
+
+ // The next 3 constructors are used to break circular dependencies on MH.invokeStatic, etc.
+@@ -1044,10 +1079,10 @@
+ String sig = m.getName().substring("invoke_".length());
+ int arity = LambdaForm.signatureArity(sig);
+ MethodType srcType = MethodType.genericMethodType(arity);
+- if (LambdaForm.signatureReturn(sig) == 'V')
++ if (LambdaForm.signatureReturn(sig) == V_TYPE)
+ srcType = srcType.changeReturnType(void.class);
+ MethodTypeForm typeForm = srcType.form();
+- typeForm.namedFunctionInvoker = DirectMethodHandle.make(m);
++ typeForm.setCachedMethodHandle(MethodTypeForm.MH_NF_INV, DirectMethodHandle.make(m));
+ }
+ }
+ }
+@@ -1057,85 +1092,104 @@
+ /** void return type invokers. */
+ @Hidden
+ static Object invoke__V(MethodHandle mh, Object[] a) throws Throwable {
+- assert(a.length == 0);
++ assert(arityCheck(0, void.class, mh, a));
+ mh.invokeBasic();
+ return null;
+ }
+ @Hidden
+ static Object invoke_L_V(MethodHandle mh, Object[] a) throws Throwable {
+- assert(a.length == 1);
++ assert(arityCheck(1, void.class, mh, a));
+ mh.invokeBasic(a[0]);
+ return null;
+ }
+ @Hidden
+ static Object invoke_LL_V(MethodHandle mh, Object[] a) throws Throwable {
+- assert(a.length == 2);
++ assert(arityCheck(2, void.class, mh, a));
+ mh.invokeBasic(a[0], a[1]);
+ return null;
+ }
+ @Hidden
+ static Object invoke_LLL_V(MethodHandle mh, Object[] a) throws Throwable {
+- assert(a.length == 3);
++ assert(arityCheck(3, void.class, mh, a));
+ mh.invokeBasic(a[0], a[1], a[2]);
+ return null;
+ }
+ @Hidden
+ static Object invoke_LLLL_V(MethodHandle mh, Object[] a) throws Throwable {
+- assert(a.length == 4);
++ assert(arityCheck(4, void.class, mh, a));
+ mh.invokeBasic(a[0], a[1], a[2], a[3]);
+ return null;
+ }
+ @Hidden
+ static Object invoke_LLLLL_V(MethodHandle mh, Object[] a) throws Throwable {
+- assert(a.length == 5);
++ assert(arityCheck(5, void.class, mh, a));
+ mh.invokeBasic(a[0], a[1], a[2], a[3], a[4]);
+ return null;
+ }
+ /** Object return type invokers. */
+ @Hidden
+ static Object invoke__L(MethodHandle mh, Object[] a) throws Throwable {
+- assert(a.length == 0);
++ assert(arityCheck(0, mh, a));
+ return mh.invokeBasic();
+ }
+ @Hidden
+ static Object invoke_L_L(MethodHandle mh, Object[] a) throws Throwable {
+- assert(a.length == 1);
++ assert(arityCheck(1, mh, a));
+ return mh.invokeBasic(a[0]);
+ }
+ @Hidden
+ static Object invoke_LL_L(MethodHandle mh, Object[] a) throws Throwable {
+- assert(a.length == 2);
++ assert(arityCheck(2, mh, a));
+ return mh.invokeBasic(a[0], a[1]);
+ }
+ @Hidden
+ static Object invoke_LLL_L(MethodHandle mh, Object[] a) throws Throwable {
+- assert(a.length == 3);
++ assert(arityCheck(3, mh, a));
+ return mh.invokeBasic(a[0], a[1], a[2]);
+ }
+ @Hidden
+ static Object invoke_LLLL_L(MethodHandle mh, Object[] a) throws Throwable {
+- assert(a.length == 4);
++ assert(arityCheck(4, mh, a));
+ return mh.invokeBasic(a[0], a[1], a[2], a[3]);
+ }
+ @Hidden
+ static Object invoke_LLLLL_L(MethodHandle mh, Object[] a) throws Throwable {
+- assert(a.length == 5);
++ assert(arityCheck(5, mh, a));
+ return mh.invokeBasic(a[0], a[1], a[2], a[3], a[4]);
+ }
++ private static boolean arityCheck(int arity, MethodHandle mh, Object[] a) {
++ return arityCheck(arity, Object.class, mh, a);
++ }
++ private static boolean arityCheck(int arity, Class<?> rtype, MethodHandle mh, Object[] a) {
++ assert(a.length == arity)
++ : Arrays.asList(a.length, arity);
++ assert(mh.type().basicType() == MethodType.genericMethodType(arity).changeReturnType(rtype))
++ : Arrays.asList(mh, rtype, arity);
++ MemberName member = mh.internalMemberName();
++ if (member != null && member.getName().equals("invokeBasic") && member.isMethodHandleInvoke()) {
++ assert(arity > 0);
++ assert(a[0] instanceof MethodHandle);
++ MethodHandle mh2 = (MethodHandle) a[0];
++ assert(mh2.type().basicType() == MethodType.genericMethodType(arity-1).changeReturnType(rtype))
++ : Arrays.asList(member, mh2, rtype, arity);
++ }
++ return true;
++ }
+
+ static final MethodType INVOKER_METHOD_TYPE =
+ MethodType.methodType(Object.class, MethodHandle.class, Object[].class);
+
+ private static MethodHandle computeInvoker(MethodTypeForm typeForm) {
+- MethodHandle mh = typeForm.namedFunctionInvoker;
++ typeForm = typeForm.basicType().form(); // normalize to basic type
++ MethodHandle mh = typeForm.cachedMethodHandle(MethodTypeForm.MH_NF_INV);
+ if (mh != null) return mh;
+ MemberName invoker = InvokerBytecodeGenerator.generateNamedFunctionInvoker(typeForm); // this could take a while
+ mh = DirectMethodHandle.make(invoker);
+- MethodHandle mh2 = typeForm.namedFunctionInvoker;
++ MethodHandle mh2 = typeForm.cachedMethodHandle(MethodTypeForm.MH_NF_INV);
+ if (mh2 != null) return mh2; // benign race
+ if (!mh.type().equals(INVOKER_METHOD_TYPE))
+- throw new InternalError(mh.debugString());
+- return typeForm.namedFunctionInvoker = mh;
++ throw newInternalError(mh.debugString());
++ return typeForm.setCachedMethodHandle(MethodTypeForm.MH_NF_INV, mh);
+ }
+
+ @Hidden
+@@ -1193,11 +1247,6 @@
+ return true;
+ }
+
+- String basicTypeSignature() {
+- //return LambdaForm.basicTypeSignature(resolvedHandle.type());
+- return LambdaForm.basicTypeSignature(methodType());
+- }
+-
+ MethodType methodType() {
+ if (resolvedHandle != null)
+ return resolvedHandle.type();
+@@ -1224,18 +1273,15 @@
+ return (member == null) ? null : member.getDeclaringClass();
+ }
+
+- char returnType() {
++ BasicType returnType() {
+ return basicType(methodType().returnType());
+ }
+
+- char parameterType(int n) {
++ BasicType parameterType(int n) {
+ return basicType(methodType().parameterType(n));
+ }
+
+ int arity() {
+- //int siglen = member.getMethodType().parameterCount();
+- //if (!member.isStatic()) siglen += 1;
+- //return siglen;
+ return methodType().parameterCount();
+ }
+
+@@ -1243,74 +1289,109 @@
+ if (member == null) return String.valueOf(resolvedHandle);
+ return member.getDeclaringClass().getSimpleName()+"."+member.getName();
+ }
++
++ public boolean isIdentity() {
++ return this.equals(identity(returnType()));
++ }
++
++ public boolean isConstantZero() {
++ return this.equals(constantZero(returnType()));
++ }
++
++ public MethodHandleImpl.Intrinsic intrinsicName() {
++ return resolvedHandle == null ? MethodHandleImpl.Intrinsic.NONE
++ : resolvedHandle.intrinsicName();
++ }
+ }
+
+- void resolve() {
+- for (Name n : names) n.resolve();
+- }
+-
+- public static char basicType(Class<?> type) {
+- char c = Wrapper.basicTypeChar(type);
+- if ("ZBSC".indexOf(c) >= 0) c = 'I';
+- assert("LIJFDV".indexOf(c) >= 0);
+- return c;
+- }
+- public static char[] basicTypes(List<Class<?>> types) {
+- char[] btypes = new char[types.size()];
+- for (int i = 0; i < btypes.length; i++) {
+- btypes[i] = basicType(types.get(i));
+- }
+- return btypes;
+- }
+ public static String basicTypeSignature(MethodType type) {
+ char[] sig = new char[type.parameterCount() + 2];
+ int sigp = 0;
+ for (Class<?> pt : type.parameterList()) {
+- sig[sigp++] = basicType(pt);
++ sig[sigp++] = basicTypeChar(pt);
+ }
+ sig[sigp++] = '_';
+- sig[sigp++] = basicType(type.returnType());
++ sig[sigp++] = basicTypeChar(type.returnType());
+ assert(sigp == sig.length);
+ return String.valueOf(sig);
+ }
++ public static String shortenSignature(String signature) {
++ // Hack to make signatures more readable when they show up in method names.
++ final int NO_CHAR = -1, MIN_RUN = 3;
++ int c0, c1 = NO_CHAR, c1reps = 0;
++ StringBuilder buf = null;
++ int len = signature.length();
++ if (len < MIN_RUN) return signature;
++ for (int i = 0; i <= len; i++) {
++ // shift in the next char:
++ c0 = c1; c1 = (i == len ? NO_CHAR : signature.charAt(i));
++ if (c1 == c0) { ++c1reps; continue; }
++ // shift in the next count:
++ int c0reps = c1reps; c1reps = 1;
++ // end of a character run
++ if (c0reps < MIN_RUN) {
++ if (buf != null) {
++ while (--c0reps >= 0)
++ buf.append((char)c0);
++ }
++ continue;
++ }
++ // found three or more in a row
++ if (buf == null)
++ buf = new StringBuilder().append(signature, 0, i - c0reps);
++ buf.append((char)c0).append(c0reps);
++ }
++ return (buf == null) ? signature : buf.toString();
++ }
+
+ static final class Name {
+- final char type;
++ final BasicType type;
+ private short index;
+ final NamedFunction function;
++ final Object constraint; // additional type information, if not null
+ @Stable final Object[] arguments;
+
+- private Name(int index, char type, NamedFunction function, Object[] arguments) {
++ private Name(int index, BasicType type, NamedFunction function, Object[] arguments) {
+ this.index = (short)index;
+ this.type = type;
+ this.function = function;
+ this.arguments = arguments;
++ this.constraint = null;
+ assert(this.index == index);
+ }
++ private Name(Name that, Object constraint) {
++ this.index = that.index;
++ this.type = that.type;
++ this.function = that.function;
++ this.arguments = that.arguments;
++ this.constraint = constraint;
++ assert(constraint == null || isParam()); // only params have constraints
++ assert(constraint == null || constraint instanceof BoundMethodHandle.SpeciesData || constraint instanceof Class);
++ }
+ Name(MethodHandle function, Object... arguments) {
+ this(new NamedFunction(function), arguments);
+ }
+ Name(MethodType functionType, Object... arguments) {
+ this(new NamedFunction(functionType), arguments);
+- assert(arguments[0] instanceof Name && ((Name)arguments[0]).type == 'L');
++ assert(arguments[0] instanceof Name && ((Name)arguments[0]).type == L_TYPE);
+ }
+ Name(MemberName function, Object... arguments) {
+ this(new NamedFunction(function), arguments);
+ }
+ Name(NamedFunction function, Object... arguments) {
+- this(-1, function.returnType(), function, arguments = arguments.clone());
++ this(-1, function.returnType(), function, arguments = Arrays.copyOf(arguments, arguments.length, Object[].class));
+ assert(arguments.length == function.arity()) : "arity mismatch: arguments.length=" + arguments.length + " == function.arity()=" + function.arity() + " in " + debugString();
+ for (int i = 0; i < arguments.length; i++)
+ assert(typesMatch(function.parameterType(i), arguments[i])) : "types don't match: function.parameterType(" + i + ")=" + function.parameterType(i) + ", arguments[" + i + "]=" + arguments[i] + " in " + debugString();
+ }
+- Name(int index, char type) {
++ /** Create a raw parameter of the given type, with an expected index. */
++ Name(int index, BasicType type) {
+ this(index, type, null, null);
+ }
+- Name(char type) {
+- this(-1, type);
+- }
++ /** Create a raw parameter of the given type. */
++ Name(BasicType type) { this(-1, type); }
+
+- char type() { return type; }
++ BasicType type() { return type; }
+ int index() { return index; }
+ boolean initIndex(int i) {
+ if (index != i) {
+@@ -1319,7 +1400,9 @@
+ }
+ return true;
+ }
+-
++ char typeChar() {
++ return type.btChar;
++ }
+
+ void resolve() {
+ if (function != null)
+@@ -1332,7 +1415,11 @@
+ }
+ Name cloneWithIndex(int i) {
+ Object[] newArguments = (arguments == null) ? null : arguments.clone();
+- return new Name(i, type, function, newArguments);
++ return new Name(i, type, function, newArguments).withConstraint(constraint);
++ }
++ Name withConstraint(Object constraint) {
++ if (constraint == this.constraint) return this;
++ return new Name(this, constraint);
+ }
+ Name replaceName(Name oldName, Name newName) { // FIXME: use replaceNames uniformly
+ if (oldName == newName) return this;
+@@ -1352,7 +1439,11 @@
+ if (!replaced) return this;
+ return new Name(function, arguments);
+ }
++ /** In the arguments of this Name, replace oldNames[i] pairwise by newNames[i].
++ * Limit such replacements to {@code start<=i<end}. Return possibly changed self.
++ */
+ Name replaceNames(Name[] oldNames, Name[] newNames, int start, int end) {
++ if (start >= end) return this;
+ @SuppressWarnings("LocalVariableHidesMemberVariable")
+ Object[] arguments = this.arguments;
+ boolean replaced = false;
+@@ -1397,18 +1488,26 @@
+ return function == null;
+ }
+ boolean isConstantZero() {
+- return !isParam() && arguments.length == 0 && function.equals(constantZero(0, type).function);
++ return !isParam() && arguments.length == 0 && function.isConstantZero();
+ }
+
+ public String toString() {
+- return (isParam()?"a":"t")+(index >= 0 ? index : System.identityHashCode(this))+":"+type;
++ return (isParam()?"a":"t")+(index >= 0 ? index : System.identityHashCode(this))+":"+typeChar();
+ }
+ public String debugString() {
+- String s = toString();
++ String s = paramString();
+ return (function == null) ? s : s + "=" + exprString();
+ }
++ public String paramString() {
++ String s = toString();
++ Object c = constraint;
++ if (c == null)
++ return s;
++ if (c instanceof Class) c = ((Class<?>)c).getSimpleName();
++ return s + "/" + c;
++ }
+ public String exprString() {
+- if (function == null) return "null";
++ if (function == null) return toString();
+ StringBuilder buf = new StringBuilder(function.toString());
+ buf.append("(");
+ String cma = "";
+@@ -1423,48 +1522,20 @@
+ return buf.toString();
+ }
+
+- private static boolean typesMatch(char parameterType, Object object) {
++ static boolean typesMatch(BasicType parameterType, Object object) {
+ if (object instanceof Name) {
+ return ((Name)object).type == parameterType;
+ }
+ switch (parameterType) {
+- case 'I': return object instanceof Integer;
+- case 'J': return object instanceof Long;
+- case 'F': return object instanceof Float;
+- case 'D': return object instanceof Double;
++ case I_TYPE: return object instanceof Integer;
++ case J_TYPE: return object instanceof Long;
++ case F_TYPE: return object instanceof Float;
++ case D_TYPE: return object instanceof Double;
+ }
+- assert(parameterType == 'L');
++ assert(parameterType == L_TYPE);
+ return true;
+ }
+
+- /**
+- * Does this Name precede the given binding node in some canonical order?
+- * This predicate is used to order data bindings (via insertion sort)
+- * with some stability.
+- */
+- boolean isSiblingBindingBefore(Name binding) {
+- assert(!binding.isParam());
+- if (isParam()) return true;
+- if (function.equals(binding.function) &&
+- arguments.length == binding.arguments.length) {
+- boolean sawInt = false;
+- for (int i = 0; i < arguments.length; i++) {
+- Object a1 = arguments[i];
+- Object a2 = binding.arguments[i];
+- if (!a1.equals(a2)) {
+- if (a1 instanceof Integer && a2 instanceof Integer) {
+- if (sawInt) continue;
+- sawInt = true;
+- if ((int)a1 < (int)a2) continue; // still might be true
+- }
+- return false;
+- }
+- }
+- return sawInt;
+- }
+- return false;
+- }
+-
+ /** Return the index of the last occurrence of n in the argument array.
+ * Return -1 if the name is not used.
+ */
+@@ -1510,7 +1581,7 @@
+ @Override
+ public int hashCode() {
+ if (isParam())
+- return index | (type << 8);
++ return index | (type.ordinal() << 8);
+ return function.hashCode() ^ Arrays.hashCode(arguments);
+ }
+ }
+@@ -1545,14 +1616,17 @@
+ }
+
+ static Name argument(int which, char type) {
+- int tn = ALL_TYPES.indexOf(type);
+- if (tn < 0 || which >= INTERNED_ARGUMENT_LIMIT)
++ return argument(which, basicType(type));
++ }
++ static Name argument(int which, BasicType type) {
++ if (which >= INTERNED_ARGUMENT_LIMIT)
+ return new Name(which, type);
+- return INTERNED_ARGUMENTS[tn][which];
++ return INTERNED_ARGUMENTS[type.ordinal()][which];
+ }
+ static Name internArgument(Name n) {
+ assert(n.isParam()) : "not param: " + n;
+ assert(n.index < INTERNED_ARGUMENT_LIMIT);
++ if (n.constraint != null) return n;
+ return argument(n.index, n.type);
+ }
+ static Name[] arguments(int extra, String types) {
+@@ -1590,56 +1664,118 @@
+ names[i] = argument(i, basicType(types.parameterType(i)));
+ return names;
+ }
+- static final String ALL_TYPES = "LIJFD"; // omit V, not an argument type
+ static final int INTERNED_ARGUMENT_LIMIT = 10;
+ private static final Name[][] INTERNED_ARGUMENTS
+- = new Name[ALL_TYPES.length()][INTERNED_ARGUMENT_LIMIT];
++ = new Name[ARG_TYPE_LIMIT][INTERNED_ARGUMENT_LIMIT];
+ static {
+- for (int tn = 0; tn < ALL_TYPES.length(); tn++) {
+- for (int i = 0; i < INTERNED_ARGUMENTS[tn].length; i++) {
+- char type = ALL_TYPES.charAt(tn);
+- INTERNED_ARGUMENTS[tn][i] = new Name(i, type);
++ for (BasicType type : BasicType.ARG_TYPES) {
++ int ord = type.ordinal();
++ for (int i = 0; i < INTERNED_ARGUMENTS[ord].length; i++) {
++ INTERNED_ARGUMENTS[ord][i] = new Name(i, type);
+ }
+ }
+ }
+
+ private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
+
+- static Name constantZero(int which, char type) {
+- return CONSTANT_ZERO[ALL_TYPES.indexOf(type)].newIndex(which);
++ static LambdaForm identityForm(BasicType type) {
++ return LF_identityForm[type.ordinal()];
+ }
+- private static final Name[] CONSTANT_ZERO
+- = new Name[ALL_TYPES.length()];
+- static {
+- for (int tn = 0; tn < ALL_TYPES.length(); tn++) {
+- char bt = ALL_TYPES.charAt(tn);
+- Wrapper wrap = Wrapper.forBasicType(bt);
+- MemberName zmem = new MemberName(LambdaForm.class, "zero"+bt, MethodType.methodType(wrap.primitiveType()), REF_invokeStatic);
++ static LambdaForm zeroForm(BasicType type) {
++ return LF_zeroForm[type.ordinal()];
++ }
++ static NamedFunction identity(BasicType type) {
++ return NF_identity[type.ordinal()];
++ }
++ static NamedFunction constantZero(BasicType type) {
++ return NF_zero[type.ordinal()];
++ }
++ private static final LambdaForm[] LF_identityForm = new LambdaForm[TYPE_LIMIT];
++ private static final LambdaForm[] LF_zeroForm = new LambdaForm[TYPE_LIMIT];
++ private static final NamedFunction[] NF_identity = new NamedFunction[TYPE_LIMIT];
++ private static final NamedFunction[] NF_zero = new NamedFunction[TYPE_LIMIT];
++ private static void createIdentityForms() {
++ for (BasicType type : BasicType.ALL_TYPES) {
++ int ord = type.ordinal();
++ char btChar = type.basicTypeChar();
++ boolean isVoid = (type == V_TYPE);
++ Class<?> btClass = type.btClass;
++ MethodType zeType = MethodType.methodType(btClass);
++ MethodType idType = isVoid ? zeType : zeType.appendParameterTypes(btClass);
++
++ // Look up some symbolic names. It might not be necessary to have these,
++ // but if we need to emit direct references to bytecodes, it helps.
++ // Zero is built from a call to an identity function with a constant zero input.
++ MemberName idMem = new MemberName(LambdaForm.class, "identity_"+btChar, idType, REF_invokeStatic);
++ MemberName zeMem = new MemberName(LambdaForm.class, "zero_"+btChar, zeType, REF_invokeStatic);
+ try {
+- zmem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, zmem, null, NoSuchMethodException.class);
++ zeMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, zeMem, null, NoSuchMethodException.class);
++ idMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, idMem, null, NoSuchMethodException.class);
+ } catch (IllegalAccessException|NoSuchMethodException ex) {
+ throw newInternalError(ex);
+ }
+- NamedFunction zcon = new NamedFunction(zmem);
+- Name n = new Name(zcon).newIndex(0);
+- assert(n.type == ALL_TYPES.charAt(tn));
+- CONSTANT_ZERO[tn] = n;
+- assert(n.isConstantZero());
++
++ NamedFunction idFun = new NamedFunction(idMem);
++ LambdaForm idForm;
++ if (isVoid) {
++ Name[] idNames = new Name[] { argument(0, L_TYPE) };
++ idForm = new LambdaForm(idMem.getName(), 1, idNames, VOID_RESULT);
++ } else {
++ Name[] idNames = new Name[] { argument(0, L_TYPE), argument(1, type) };
++ idForm = new LambdaForm(idMem.getName(), 2, idNames, 1);
++ }
++ LF_identityForm[ord] = idForm;
++ NF_identity[ord] = idFun;
++
++ NamedFunction zeFun = new NamedFunction(zeMem);
++ LambdaForm zeForm;
++ if (isVoid) {
++ zeForm = idForm;
++ } else {
++ Object zeValue = Wrapper.forBasicType(btChar).zero();
++ Name[] zeNames = new Name[] { argument(0, L_TYPE), new Name(idFun, zeValue) };
++ zeForm = new LambdaForm(zeMem.getName(), 1, zeNames, 1);
++ }
++ LF_zeroForm[ord] = zeForm;
++ NF_zero[ord] = zeFun;
++
++ assert(idFun.isIdentity());
++ assert(zeFun.isConstantZero());
++ assert(new Name(zeFun).isConstantZero());
++ }
++
++ // Do this in a separate pass, so that SimpleMethodHandle.make can see the tables.
++ for (BasicType type : BasicType.ALL_TYPES) {
++ int ord = type.ordinal();
++ NamedFunction idFun = NF_identity[ord];
++ LambdaForm idForm = LF_identityForm[ord];
++ MemberName idMem = idFun.member;
++ idFun.resolvedHandle = SimpleMethodHandle.make(idMem.getInvocationType(), idForm);
++
++ NamedFunction zeFun = NF_zero[ord];
++ LambdaForm zeForm = LF_zeroForm[ord];
++ MemberName zeMem = zeFun.member;
++ zeFun.resolvedHandle = SimpleMethodHandle.make(zeMem.getInvocationType(), zeForm);
++
++ assert(idFun.isIdentity());
++ assert(zeFun.isConstantZero());
++ assert(new Name(zeFun).isConstantZero());
+ }
+ }
+
+ // Avoid appealing to ValueConversions at bootstrap time:
+- private static int zeroI() { return 0; }
+- private static long zeroJ() { return 0; }
+- private static float zeroF() { return 0; }
+- private static double zeroD() { return 0; }
+- private static Object zeroL() { return null; }
+-
+- // Put this last, so that previous static inits can run before.
+- static {
+- if (USE_PREDEFINED_INTERPRET_METHODS)
+- PREPARED_FORMS.putAll(computeInitialPreparedForms());
+- }
++ private static int identity_I(int x) { return x; }
++ private static long identity_J(long x) { return x; }
++ private static float identity_F(float x) { return x; }
++ private static double identity_D(double x) { return x; }
++ private static Object identity_L(Object x) { return x; }
++ private static void identity_V() { return; } // same as zeroV, but that's OK
++ private static int zero_I() { return 0; }
++ private static long zero_J() { return 0; }
++ private static float zero_F() { return 0; }
++ private static double zero_D() { return 0; }
++ private static Object zero_L() { return null; }
++ private static void zero_V() { return; }
+
+ /**
+ * Internal marker for byte-compiled LambdaForms.
+@@ -1659,38 +1795,21 @@
+ @interface Hidden {
+ }
+
++ private static final HashMap<String,Integer> DEBUG_NAME_COUNTERS;
++ static {
++ if (debugEnabled())
++ DEBUG_NAME_COUNTERS = new HashMap<>();
++ else
++ DEBUG_NAME_COUNTERS = null;
++ }
+
+-/*
+- // Smoke-test for the invokers used in this file.
+- static void testMethodHandleLinkers() throws Throwable {
+- MemberName.Factory lookup = MemberName.getFactory();
+- MemberName asList_MN = new MemberName(Arrays.class, "asList",
+- MethodType.methodType(List.class, Object[].class),
+- REF_invokeStatic);
+- //MethodHandleNatives.resolve(asList_MN, null);
+- asList_MN = lookup.resolveOrFail(asList_MN, REF_invokeStatic, null, NoSuchMethodException.class);
+- System.out.println("about to call "+asList_MN);
+- Object[] abc = { "a", "bc" };
+- List<?> lst = (List<?>) MethodHandle.linkToStatic(abc, asList_MN);
+- System.out.println("lst="+lst);
+- MemberName toString_MN = new MemberName(Object.class.getMethod("toString"));
+- String s1 = (String) MethodHandle.linkToVirtual(lst, toString_MN);
+- toString_MN = new MemberName(Object.class.getMethod("toString"), true);
+- String s2 = (String) MethodHandle.linkToSpecial(lst, toString_MN);
+- System.out.println("[s1,s2,lst]="+Arrays.asList(s1, s2, lst.toString()));
+- MemberName toArray_MN = new MemberName(List.class.getMethod("toArray"));
+- Object[] arr = (Object[]) MethodHandle.linkToInterface(lst, toArray_MN);
+- System.out.println("toArray="+Arrays.toString(arr));
++ // Put this last, so that previous static inits can run before.
++ static {
++ createIdentityForms();
++ if (USE_PREDEFINED_INTERPRET_METHODS)
++ computeInitialPreparedForms();
++ NamedFunction.initializeInvokers();
+ }
+- static { try { testMethodHandleLinkers(); } catch (Throwable ex) { throw new RuntimeException(ex); } }
+- // Requires these definitions in MethodHandle:
+- static final native Object linkToStatic(Object x1, MemberName mn) throws Throwable;
+- static final native Object linkToVirtual(Object x1, MemberName mn) throws Throwable;
+- static final native Object linkToSpecial(Object x1, MemberName mn) throws Throwable;
+- static final native Object linkToInterface(Object x1, MemberName mn) throws Throwable;
+- */
+-
+- static { NamedFunction.initializeInvokers(); }
+
+ // The following hack is necessary in order to suppress TRACE_INTERPRETER
+ // during execution of the static initializes of this class.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/src/share/classes/java/lang/invoke/LambdaFormBuffer.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,398 @@
++/*
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 java.lang.invoke;
++
++import java.util.ArrayList;
++import java.util.Arrays;
++import static java.lang.invoke.LambdaForm.*;
++import static java.lang.invoke.LambdaForm.BasicType.*;
++
++/** Working storage for an LF that is being transformed.
++ * Similarly to a StringBuffer, the editing can take place in multiple steps.
++ */
++final class LambdaFormBuffer {
++ private int arity, length;
++ private Name[] names;
++ private Name[] originalNames; // snapshot of pre-transaction names
++ private byte flags;
++ private int firstChange;
++ private Name resultName;
++ private String debugName;
++ private ArrayList<Name> dups;
++
++ private static final int F_TRANS = 0x10, F_OWNED = 0x03;
++
++ LambdaFormBuffer(LambdaForm lf) {
++ this.arity = lf.arity;
++ setNames(lf.names);
++ int result = lf.result;
++ if (result == LAST_RESULT) result = length - 1;
++ if (result >= 0 && lf.names[result].type != V_TYPE)
++ resultName = lf.names[result];
++ debugName = lf.debugName;
++ assert(lf.nameRefsAreLegal());
++ }
++
++ private LambdaForm lambdaForm() {
++ assert(!inTrans()); // need endEdit call to tidy things up
++ return new LambdaForm(debugName, arity, nameArray(), resultIndex());
++ }
++
++ Name name(int i) {
++ assert(i < length);
++ return names[i];
++ }
++
++ Name[] nameArray() {
++ return Arrays.copyOf(names, length);
++ }
++
++ int resultIndex() {
++ if (resultName == null) return VOID_RESULT;
++ int index = indexOf(resultName, names);
++ assert(index >= 0);
++ return index;
++ }
++
++ void setNames(Name[] names2) {
++ names = originalNames = names2; // keep a record of where everything was to start with
++ length = names2.length;
++ flags = 0;
++ }
++
++ private boolean verifyArity() {
++ for (int i = 0; i < arity && i < firstChange; i++) {
++ assert(names[i].isParam()) : "#" + i + "=" + names[i];
++ }
++ for (int i = arity; i < length; i++) {
++ assert(!names[i].isParam()) : "#" + i + "=" + names[i];
++ }
++ for (int i = length; i < names.length; i++) {
++ assert(names[i] == null) : "#" + i + "=" + names[i];
++ }
++ // check resultName also
++ if (resultName != null) {
++ int resultIndex = indexOf(resultName, names);
++ assert(resultIndex >= 0) : "not found: " + resultName.exprString() + Arrays.asList(names);
++ assert(names[resultIndex] == resultName);
++ }
++ return true;
++ }
++
++ private boolean verifyFirstChange() {
++ assert(inTrans());
++ for (int i = 0; i < length; i++) {
++ if (names[i] != originalNames[i]) {
++ assert(firstChange == i) : Arrays.asList(firstChange, i, originalNames[i].exprString(), Arrays.asList(names));
++ return true;
++ }
++ }
++ assert(firstChange == length) : Arrays.asList(firstChange, Arrays.asList(names));
++ return true;
++ }
++
++ private static int indexOf(NamedFunction fn, NamedFunction[] fns) {
++ for (int i = 0; i < fns.length; i++) {
++ if (fns[i] == fn) return i;
++ }
++ return -1;
++ }
++
++ private static int indexOf(Name n, Name[] ns) {
++ for (int i = 0; i < ns.length; i++) {
++ if (ns[i] == n) return i;
++ }
++ return -1;
++ }
++
++ boolean inTrans() {
++ return (flags & F_TRANS) != 0;
++ }
++
++ int ownedCount() {
++ return flags & F_OWNED;
++ }
++
++ void growNames(int insertPos, int growLength) {
++ int oldLength = length;
++ int newLength = oldLength + growLength;
++ int oc = ownedCount();
++ if (oc == 0 || newLength > names.length) {
++ names = Arrays.copyOf(names, (names.length + growLength) * 5 / 4);
++ if (oc == 0) {
++ flags++;
++ oc++;
++ assert(ownedCount() == oc);
++ }
++ }
++ if (originalNames != null && originalNames.length < names.length) {
++ originalNames = Arrays.copyOf(originalNames, names.length);
++ if (oc == 1) {
++ flags++;
++ oc++;
++ assert(ownedCount() == oc);
++ }
++ }
++ if (growLength == 0) return;
++ int insertEnd = insertPos + growLength;
++ int tailLength = oldLength - insertPos;
++ System.arraycopy(names, insertPos, names, insertEnd, tailLength);
++ Arrays.fill(names, insertPos, insertEnd, null);
++ if (originalNames != null) {
++ System.arraycopy(originalNames, insertPos, originalNames, insertEnd, tailLength);
++ Arrays.fill(originalNames, insertPos, insertEnd, null);
++ }
++ length = newLength;
++ if (firstChange >= insertPos) {
++ firstChange += growLength;
++ }
++ }
++
++ int lastIndexOf(Name n) {
++ int result = -1;
++ for (int i = 0; i < length; i++) {
++ if (names[i] == n) result = i;
++ }
++ return result;
++ }
++
++ /** We have just overwritten the name at pos1 with the name at pos2.
++ * This means that there are two copies of the name, which we will have to fix later.
++ */
++ private void noteDuplicate(int pos1, int pos2) {
++ Name n = names[pos1];
++ assert(n == names[pos2]);
++ assert(originalNames[pos1] != null); // something was replaced at pos1
++ assert(originalNames[pos2] == null || originalNames[pos2] == n);
++ if (dups == null) {
++ dups = new ArrayList<>();
++ }
++ dups.add(n);
++ }
++
++ /** Replace duplicate names by nulls, and remove all nulls. */
++ private void clearDuplicatesAndNulls() {
++ if (dups != null) {
++ // Remove duplicates.
++ assert(ownedCount() >= 1);
++ for (Name dup : dups) {
++ for (int i = firstChange; i < length; i++) {
++ if (names[i] == dup && originalNames[i] != dup) {
++ names[i] = null;
++ assert(Arrays.asList(names).contains(dup));
++ break; // kill only one dup
++ }
++ }
++ }
++ dups.clear();
++ }
++ // Now that we are done with originalNames, remove "killed" names.
++ int oldLength = length;
++ for (int i = firstChange; i < length; i++) {
++ if (names[i] == null) {
++ System.arraycopy(names, i + 1, names, i, (--length - i));
++ --i; // restart loop at this position
++ }
++ }
++ if (length < oldLength) {
++ Arrays.fill(names, length, oldLength, null);
++ }
++ assert(!Arrays.asList(names).subList(0, length).contains(null));
++ }
++
++ /** Create a private, writable copy of names.
++ * Preserve the original copy, for reference.
++ */
++ void startEdit() {
++ assert(verifyArity());
++ int oc = ownedCount();
++ assert(!inTrans()); // no nested transactions
++ flags |= F_TRANS;
++ Name[] oldNames = names;
++ Name[] ownBuffer = (oc == 2 ? originalNames : null);
++ assert(ownBuffer != oldNames);
++ if (ownBuffer != null && ownBuffer.length >= length) {
++ names = copyNamesInto(ownBuffer);
++ } else {
++ // make a new buffer to hold the names
++ final int SLOP = 2;
++ names = Arrays.copyOf(oldNames, Math.max(length + SLOP, oldNames.length));
++ if (oc < 2) ++flags;
++ assert(ownedCount() == oc + 1);
++ }
++ originalNames = oldNames;
++ assert(originalNames != names);
++ firstChange = length;
++ assert(inTrans());
++ }
++
++ private void changeName(int i, Name name) {
++ assert(inTrans());
++ assert(i < length);
++ Name oldName = names[i];
++ assert(oldName == originalNames[i]); // no multiple changes
++ assert(verifyFirstChange());
++ if (ownedCount() == 0)
++ growNames(0, 0);
++ names[i] = name;
++ if (firstChange > i) {
++ firstChange = i;
++ }
++ if (resultName != null && resultName == oldName) {
++ resultName = name;
++ }
++ }
++
++ /** Change the result name. Null means a void result. */
++ void setResult(Name name) {
++ assert(name == null || lastIndexOf(name) >= 0);
++ resultName = name;
++ }
++
++ /** Finish a transaction. */
++ LambdaForm endEdit() {
++ assert(verifyFirstChange());
++ // Assuming names have been changed pairwise from originalNames[i] to names[i],
++ // update arguments to ensure referential integrity.
++ for (int i = Math.max(firstChange, arity); i < length; i++) {
++ Name name = names[i];
++ if (name == null) continue; // space for removed duplicate
++ Name newName = name.replaceNames(originalNames, names, firstChange, i);
++ if (newName != name) {
++ names[i] = newName;
++ if (resultName == name) {
++ resultName = newName;
++ }
++ }
++ }
++ assert(inTrans());
++ flags &= ~F_TRANS;
++ clearDuplicatesAndNulls();
++ originalNames = null;
++ // If any parameters have been changed, then reorder them as needed.
++ // This is a "sheep-and-goats" stable sort, pushing all non-parameters
++ // to the right of all parameters.
++ if (firstChange < arity) {
++ Name[] exprs = new Name[arity - firstChange];
++ int argp = firstChange, exprp = 0;
++ for (int i = firstChange; i < arity; i++) {
++ Name name = names[i];
++ if (name.isParam()) {
++ names[argp++] = name;
++ } else {
++ exprs[exprp++] = name;
++ }
++ }
++ assert(exprp == (arity - argp));
++ // copy the exprs just after the last remaining param
++ System.arraycopy(exprs, 0, names, argp, exprp);
++ // adjust arity
++ arity -= exprp;
++ }
++ assert(verifyArity());
++ return lambdaForm();
++ }
++
++ private Name[] copyNamesInto(Name[] buffer) {
++ System.arraycopy(names, 0, buffer, 0, length);
++ Arrays.fill(buffer, length, buffer.length, null);
++ return buffer;
++ }
++
++ /** Replace any Name whose function is in oldFns with a copy
++ * whose function is in the corresponding position in newFns.
++ * Only do this if the arguments are exactly equal to the given.
++ */
++ LambdaFormBuffer replaceFunctions(NamedFunction[] oldFns, NamedFunction[] newFns,
++ Object... forArguments) {
++ assert(inTrans());
++ if (oldFns.length == 0) return this;
++ for (int i = arity; i < length; i++) {
++ Name n = names[i];
++ int nfi = indexOf(n.function, oldFns);
++ if (nfi >= 0 && Arrays.equals(n.arguments, forArguments)) {
++ changeName(i, new Name(newFns[nfi], n.arguments));
++ }
++ }
++ return this;
++ }
++
++ private void replaceName(int pos, Name binding) {
++ assert(inTrans());
++ assert(verifyArity());
++ assert(pos < arity);
++ Name param = names[pos];
++ assert(param.isParam());
++ assert(param.type == binding.type);
++ changeName(pos, binding);
++ }
++
++ /** Replace a parameter by a fresh parameter. */
++ LambdaFormBuffer renameParameter(int pos, Name newParam) {
++ assert(newParam.isParam());
++ replaceName(pos, newParam);
++ return this;
++ }
++
++ /** Replace a parameter by a fresh expression. */
++ LambdaFormBuffer replaceParameterByNewExpression(int pos, Name binding) {
++ assert(!binding.isParam());
++ assert(lastIndexOf(binding) < 0); // else use replaceParameterByCopy
++ replaceName(pos, binding);
++ return this;
++ }
++
++ /** Replace a parameter by another parameter or expression already in the form. */
++ LambdaFormBuffer replaceParameterByCopy(int pos, int valuePos) {
++ assert(pos != valuePos);
++ replaceName(pos, names[valuePos]);
++ noteDuplicate(pos, valuePos); // temporarily, will occur twice in the names array
++ return this;
++ }
++
++ private void insertName(int pos, Name expr, boolean isParameter) {
++ assert(inTrans());
++ assert(verifyArity());
++ assert(isParameter ? pos <= arity : pos >= arity);
++ growNames(pos, 1);
++ if (isParameter) arity += 1;
++ changeName(pos, expr);
++ }
++
++ /** Insert a fresh expression. */
++ LambdaFormBuffer insertExpression(int pos, Name expr) {
++ assert(!expr.isParam());
++ insertName(pos, expr, false);
++ return this;
++ }
++
++ /** Insert a fresh parameter. */
++ LambdaFormBuffer insertParameter(int pos, Name param) {
++ assert(param.isParam());
++ insertName(pos, param, true);
++ return this;
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/src/share/classes/java/lang/invoke/LambdaFormEditor.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,855 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 java.lang.invoke;
++
++import java.lang.ref.SoftReference;
++import java.util.Arrays;
++import static java.lang.invoke.LambdaForm.*;
++import static java.lang.invoke.LambdaForm.BasicType.*;
++import static java.lang.invoke.MethodHandleImpl.Intrinsic;
++import java.util.Collections;
++import java.util.concurrent.ConcurrentHashMap;
++
++import sun.invoke.util.Wrapper;
++
++/** Transforms on LFs.
++ * A lambda-form editor can derive new LFs from its base LF.
++ * The editor can cache derived LFs, which simplifies the reuse of their underlying bytecodes.
++ * To support this caching, a LF has an optional pointer to its editor.
++ */
++class LambdaFormEditor {
++ final LambdaForm lambdaForm;
++
++ private LambdaFormEditor(LambdaForm lambdaForm) {
++ this.lambdaForm = lambdaForm;
++ }
++
++ // Factory method.
++ static LambdaFormEditor lambdaFormEditor(LambdaForm lambdaForm) {
++ // TO DO: Consider placing intern logic here, to cut down on duplication.
++ // lambdaForm = findPreexistingEquivalent(lambdaForm)
++ return new LambdaFormEditor(lambdaForm);
++ }
++
++ /** A description of a cached transform, possibly associated with the result of the transform.
++ * The logical content is a sequence of byte values, starting with a Kind.ordinal value.
++ * The sequence is unterminated, ending with an indefinite number of zero bytes.
++ * Sequences that are simple (short enough and with small enough values) pack into a 64-bit long.
++ */
++ private static final class Transform extends SoftReference<LambdaForm> {
++ final long packedBytes;
++ final byte[] fullBytes;
++
++ private enum Kind {
++ NO_KIND, // necessary because ordinal must be greater than zero
++ BIND_ARG, ADD_ARG, DUP_ARG,
++ SPREAD_ARGS,
++ FILTER_ARG, FILTER_RETURN, FILTER_RETURN_TO_ZERO,
++ COLLECT_ARGS, COLLECT_ARGS_TO_VOID, COLLECT_ARGS_TO_ARRAY,
++ FOLD_ARGS, FOLD_ARGS_TO_VOID,
++ PERMUTE_ARGS
++ //maybe add more for guard with test, catch exception, pointwise type conversions
++ }
++
++ private static final boolean STRESS_TEST = false; // turn on to disable most packing
++ private static final int
++ PACKED_BYTE_SIZE = (STRESS_TEST ? 2 : 4),
++ PACKED_BYTE_MASK = (1 << PACKED_BYTE_SIZE) - 1,
++ PACKED_BYTE_MAX_LENGTH = (STRESS_TEST ? 3 : 64 / PACKED_BYTE_SIZE);
++
++ private static long packedBytes(byte[] bytes) {
++ if (bytes.length > PACKED_BYTE_MAX_LENGTH) return 0;
++ long pb = 0;
++ int bitset = 0;
++ for (int i = 0; i < bytes.length; i++) {
++ int b = bytes[i] & 0xFF;
++ bitset |= b;
++ pb |= (long)b << (i * PACKED_BYTE_SIZE);
++ }
++ if (!inRange(bitset))
++ return 0;
++ return pb;
++ }
++ private static long packedBytes(int b0, int b1) {
++ assert(inRange(b0 | b1));
++ return ( (b0 << 0*PACKED_BYTE_SIZE)
++ | (b1 << 1*PACKED_BYTE_SIZE));
++ }
++ private static long packedBytes(int b0, int b1, int b2) {
++ assert(inRange(b0 | b1 | b2));
++ return ( (b0 << 0*PACKED_BYTE_SIZE)
++ | (b1 << 1*PACKED_BYTE_SIZE)
++ | (b2 << 2*PACKED_BYTE_SIZE));
++ }
++ private static long packedBytes(int b0, int b1, int b2, int b3) {
++ assert(inRange(b0 | b1 | b2 | b3));
++ return ( (b0 << 0*PACKED_BYTE_SIZE)
++ | (b1 << 1*PACKED_BYTE_SIZE)
++ | (b2 << 2*PACKED_BYTE_SIZE)
++ | (b3 << 3*PACKED_BYTE_SIZE));
++ }
++ private static boolean inRange(int bitset) {
++ assert((bitset & 0xFF) == bitset); // incoming values must fit in *unsigned* byte
++ return ((bitset & ~PACKED_BYTE_MASK) == 0);
++ }
++ private static byte[] fullBytes(int... byteValues) {
++ byte[] bytes = new byte[byteValues.length];
++ int i = 0;
++ for (int bv : byteValues) {
++ bytes[i++] = bval(bv);
++ }
++ assert(packedBytes(bytes) == 0);
++ return bytes;
++ }
++
++ private byte byteAt(int i) {
++ long pb = packedBytes;
++ if (pb == 0) {
++ if (i >= fullBytes.length) return 0;
++ return fullBytes[i];
++ }
++ assert(fullBytes == null);
++ if (i > PACKED_BYTE_MAX_LENGTH) return 0;
++ int pos = (i * PACKED_BYTE_SIZE);
++ return (byte)((pb >>> pos) & PACKED_BYTE_MASK);
++ }
++
++ Kind kind() { return Kind.values()[byteAt(0)]; }
++
++ private Transform(long packedBytes, byte[] fullBytes, LambdaForm result) {
++ super(result);
++ this.packedBytes = packedBytes;
++ this.fullBytes = fullBytes;
++ }
++ private Transform(long packedBytes) {
++ this(packedBytes, null, null);
++ assert(packedBytes != 0);
++ }
++ private Transform(byte[] fullBytes) {
++ this(0, fullBytes, null);
++ }
++
++ private static byte bval(int b) {
++ assert((b & 0xFF) == b); // incoming value must fit in *unsigned* byte
++ return (byte)b;
++ }
++ private static byte bval(Kind k) {
++ return bval(k.ordinal());
++ }
++ static Transform of(Kind k, int b1) {
++ byte b0 = bval(k);
++ if (inRange(b0 | b1))
++ return new Transform(packedBytes(b0, b1));
++ else
++ return new Transform(fullBytes(b0, b1));
++ }
++ static Transform of(Kind k, int b1, int b2) {
++ byte b0 = (byte) k.ordinal();
++ if (inRange(b0 | b1 | b2))
++ return new Transform(packedBytes(b0, b1, b2));
++ else
++ return new Transform(fullBytes(b0, b1, b2));
++ }
++ static Transform of(Kind k, int b1, int b2, int b3) {
++ byte b0 = (byte) k.ordinal();
++ if (inRange(b0 | b1 | b2 | b3))
++ return new Transform(packedBytes(b0, b1, b2, b3));
++ else
++ return new Transform(fullBytes(b0, b1, b2, b3));
++ }
++ private static final byte[] NO_BYTES = {};
++ static Transform of(Kind k, int... b123) {
++ return ofBothArrays(k, b123, NO_BYTES);
++ }
++ static Transform of(Kind k, int b1, byte[] b234) {
++ return ofBothArrays(k, new int[]{ b1 }, b234);
++ }
++ static Transform of(Kind k, int b1, int b2, byte[] b345) {
++ return ofBothArrays(k, new int[]{ b1, b2 }, b345);
++ }
++ private static Transform ofBothArrays(Kind k, int[] b123, byte[] b456) {
++ byte[] fullBytes = new byte[1 + b123.length + b456.length];
++ int i = 0;
++ fullBytes[i++] = bval(k);
++ for (int bv : b123) {
++ fullBytes[i++] = bval(bv);
++ }
++ for (byte bv : b456) {
++ fullBytes[i++] = bv;
++ }
++ long packedBytes = packedBytes(fullBytes);
++ if (packedBytes != 0)
++ return new Transform(packedBytes);
++ else
++ return new Transform(fullBytes);
++ }
++
++ Transform withResult(LambdaForm result) {
++ return new Transform(this.packedBytes, this.fullBytes, result);
++ }
++
++ @Override
++ public boolean equals(Object obj) {
++ return obj instanceof Transform && equals((Transform)obj);
++ }
++ public boolean equals(Transform that) {
++ return this.packedBytes == that.packedBytes && Arrays.equals(this.fullBytes, that.fullBytes);
++ }
++ @Override
++ public int hashCode() {
++ if (packedBytes != 0) {
++ assert(fullBytes == null);
++ return Long.hashCode(packedBytes);
++ }
++ return Arrays.hashCode(fullBytes);
++ }
++ @Override
++ public String toString() {
++ StringBuilder buf = new StringBuilder();
++ long bits = packedBytes;
++ if (bits != 0) {
++ buf.append("(");
++ while (bits != 0) {
++ buf.append(bits & PACKED_BYTE_MASK);
++ bits >>>= PACKED_BYTE_SIZE;
++ if (bits != 0) buf.append(",");
++ }
++ buf.append(")");
++ }
++ if (fullBytes != null) {
++ buf.append("unpacked");
++ buf.append(Arrays.toString(fullBytes));
++ }
++ LambdaForm result = get();
++ if (result != null) {
++ buf.append(" result=");
++ buf.append(result);
++ }
++ return buf.toString();
++ }
++ }
++
++ /** Find a previously cached transform equivalent to the given one, and return its result. */
++ private LambdaForm getInCache(Transform key) {
++ assert(key.get() == null);
++ // The transformCache is one of null, Transform, Transform[], or ConcurrentHashMap.
++ Object c = lambdaForm.transformCache;
++ Transform k = null;
++ if (c instanceof ConcurrentHashMap) {
++ @SuppressWarnings("unchecked")
++ ConcurrentHashMap<Transform,Transform> m = (ConcurrentHashMap<Transform,Transform>) c;
++ k = m.get(key);
++ } else if (c == null) {
++ return null;
++ } else if (c instanceof Transform) {
++ // one-element cache avoids overhead of an array
++ Transform t = (Transform)c;
++ if (t.equals(key)) k = t;
++ } else {
++ Transform[] ta = (Transform[])c;
++ for (int i = 0; i < ta.length; i++) {
++ Transform t = ta[i];
++ if (t == null) break;
++ if (t.equals(key)) { k = t; break; }
++ }
++ }
++ assert(k == null || key.equals(k));
++ return (k != null) ? k.get() : null;
++ }
++
++ /** Arbitrary but reasonable limits on Transform[] size for cache. */
++ private static final int MIN_CACHE_ARRAY_SIZE = 4, MAX_CACHE_ARRAY_SIZE = 16;
++
++ /** Cache a transform with its result, and return that result.
++ * But if an equivalent transform has already been cached, return its result instead.
++ */
++ private LambdaForm putInCache(Transform key, LambdaForm form) {
++ key = key.withResult(form);
++ for (int pass = 0; ; pass++) {
++ Object c = lambdaForm.transformCache;
++ if (c instanceof ConcurrentHashMap) {
++ @SuppressWarnings("unchecked")
++ ConcurrentHashMap<Transform,Transform> m = (ConcurrentHashMap<Transform,Transform>) c;
++ Transform k = m.putIfAbsent(key, key);
++ if (k == null) return form;
++ LambdaForm result = k.get();
++ if (result != null) {
++ return result;
++ } else {
++ if (m.replace(key, k, key)) {
++ return form;
++ } else {
++ continue;
++ }
++ }
++ }
++ assert(pass == 0);
++ synchronized (lambdaForm) {
++ c = lambdaForm.transformCache;
++ if (c instanceof ConcurrentHashMap)
++ continue;
++ if (c == null) {
++ lambdaForm.transformCache = key;
++ return form;
++ }
++ Transform[] ta;
++ if (c instanceof Transform) {
++ Transform k = (Transform)c;
++ if (k.equals(key)) {
++ LambdaForm result = k.get();
++ if (result == null) {
++ lambdaForm.transformCache = key;
++ return form;
++ } else {
++ return result;
++ }
++ } else if (k.get() == null) { // overwrite stale entry
++ lambdaForm.transformCache = key;
++ return form;
++ }
++ // expand one-element cache to small array
++ ta = new Transform[MIN_CACHE_ARRAY_SIZE];
++ ta[0] = k;
++ lambdaForm.transformCache = ta;
++ } else {
++ // it is already expanded
++ ta = (Transform[])c;
++ }
++ int len = ta.length;
++ int stale = -1;
++ int i;
++ for (i = 0; i < len; i++) {
++ Transform k = ta[i];
++ if (k == null) {
++ break;
++ }
++ if (k.equals(key)) {
++ LambdaForm result = k.get();
++ if (result == null) {
++ ta[i] = key;
++ return form;
++ } else {
++ return result;
++ }
++ } else if (stale < 0 && k.get() == null) {
++ stale = i; // remember 1st stale entry index
++ }
++ }
++ if (i < len || stale >= 0) {
++ // just fall through to cache update
++ } else if (len < MAX_CACHE_ARRAY_SIZE) {
++ len = Math.min(len * 2, MAX_CACHE_ARRAY_SIZE);
++ ta = Arrays.copyOf(ta, len);
++ lambdaForm.transformCache = ta;
++ } else {
++ ConcurrentHashMap<Transform, Transform> m = new ConcurrentHashMap<>(MAX_CACHE_ARRAY_SIZE * 2);
++ for (Transform k : ta) {
++ m.put(k, k);
++ }
++ lambdaForm.transformCache = m;
++ // The second iteration will update for this query, concurrently.
++ continue;
++ }
++ int idx = (stale >= 0) ? stale : i;
++ ta[idx] = key;
++ return form;
++ }
++ }
++ }
++
++ private LambdaFormBuffer buffer() {
++ return new LambdaFormBuffer(lambdaForm);
++ }
++
++ /// Editing methods for method handles. These need to have fast paths.
++
++ private BoundMethodHandle.SpeciesData oldSpeciesData() {
++ return BoundMethodHandle.speciesData(lambdaForm);
++ }
++ private BoundMethodHandle.SpeciesData newSpeciesData(BasicType type) {
++ return oldSpeciesData().extendWith(type);
++ }
++
++ BoundMethodHandle bindArgumentL(BoundMethodHandle mh, int pos, Object value) {
++ assert(mh.speciesData() == oldSpeciesData());
++ BasicType bt = L_TYPE;
++ MethodType type2 = bindArgumentType(mh, pos, bt);
++ LambdaForm form2 = bindArgumentForm(1+pos);
++ return mh.copyWithExtendL(type2, form2, value);
++ }
++ BoundMethodHandle bindArgumentI(BoundMethodHandle mh, int pos, int value) {
++ assert(mh.speciesData() == oldSpeciesData());
++ BasicType bt = I_TYPE;
++ MethodType type2 = bindArgumentType(mh, pos, bt);
++ LambdaForm form2 = bindArgumentForm(1+pos);
++ return mh.copyWithExtendI(type2, form2, value);
++ }
++
++ BoundMethodHandle bindArgumentJ(BoundMethodHandle mh, int pos, long value) {
++ assert(mh.speciesData() == oldSpeciesData());
++ BasicType bt = J_TYPE;
++ MethodType type2 = bindArgumentType(mh, pos, bt);
++ LambdaForm form2 = bindArgumentForm(1+pos);
++ return mh.copyWithExtendJ(type2, form2, value);
++ }
++
++ BoundMethodHandle bindArgumentF(BoundMethodHandle mh, int pos, float value) {
++ assert(mh.speciesData() == oldSpeciesData());
++ BasicType bt = F_TYPE;
++ MethodType type2 = bindArgumentType(mh, pos, bt);
++ LambdaForm form2 = bindArgumentForm(1+pos);
++ return mh.copyWithExtendF(type2, form2, value);
++ }
++
++ BoundMethodHandle bindArgumentD(BoundMethodHandle mh, int pos, double value) {
++ assert(mh.speciesData() == oldSpeciesData());
++ BasicType bt = D_TYPE;
++ MethodType type2 = bindArgumentType(mh, pos, bt);
++ LambdaForm form2 = bindArgumentForm(1+pos);
++ return mh.copyWithExtendD(type2, form2, value);
++ }
++
++ private MethodType bindArgumentType(BoundMethodHandle mh, int pos, BasicType bt) {
++ assert(mh.form == lambdaForm);
++ assert(mh.form.names[1+pos].type == bt);
++ assert(BasicType.basicType(mh.type().parameterType(pos)) == bt);
++ return mh.type().dropParameterTypes(pos, pos+1);
++ }
++
++ /// Editing methods for lambda forms.
++ // Each editing method can (potentially) cache the edited LF so that it can be reused later.
++
++ LambdaForm bindArgumentForm(int pos) {
++ Transform key = Transform.of(Transform.Kind.BIND_ARG, pos);
++ LambdaForm form = getInCache(key);
++ if (form != null) {
++ assert(form.parameterConstraint(0) == newSpeciesData(lambdaForm.parameterType(pos)));
++ return form;
++ }
++ LambdaFormBuffer buf = buffer();
++ buf.startEdit();
++
++ BoundMethodHandle.SpeciesData oldData = oldSpeciesData();
++ BoundMethodHandle.SpeciesData newData = newSpeciesData(lambdaForm.parameterType(pos));
++ Name oldBaseAddress = lambdaForm.parameter(0); // BMH holding the values
++ Name newBaseAddress;
++ NamedFunction getter = newData.getterFunction(oldData.fieldCount());
++
++ if (pos != 0) {
++ // The newly created LF will run with a different BMH.
++ // Switch over any pre-existing BMH field references to the new BMH class.
++ buf.replaceFunctions(oldData.getterFunctions(), newData.getterFunctions(), oldBaseAddress);
++ newBaseAddress = oldBaseAddress.withConstraint(newData);
++ buf.renameParameter(0, newBaseAddress);
++ buf.replaceParameterByNewExpression(pos, new Name(getter, newBaseAddress));
++ } else {
++ // cannot bind the MH arg itself, unless oldData is empty
++ assert(oldData == BoundMethodHandle.SpeciesData.EMPTY);
++ newBaseAddress = new Name(L_TYPE).withConstraint(newData);
++ buf.replaceParameterByNewExpression(0, new Name(getter, newBaseAddress));
++ buf.insertParameter(0, newBaseAddress);
++ }
++
++ form = buf.endEdit();
++ return putInCache(key, form);
++ }
++
++ LambdaForm addArgumentForm(int pos, BasicType type) {
++ Transform key = Transform.of(Transform.Kind.ADD_ARG, pos, type.ordinal());
++ LambdaForm form = getInCache(key);
++ if (form != null) {
++ assert(form.arity == lambdaForm.arity+1);
++ assert(form.parameterType(pos) == type);
++ return form;
++ }
++ LambdaFormBuffer buf = buffer();
++ buf.startEdit();
++
++ buf.insertParameter(pos, new Name(type));
++
++ form = buf.endEdit();
++ return putInCache(key, form);
++ }
++
++ LambdaForm dupArgumentForm(int srcPos, int dstPos) {
++ Transform key = Transform.of(Transform.Kind.DUP_ARG, srcPos, dstPos);
++ LambdaForm form = getInCache(key);
++ if (form != null) {
++ assert(form.arity == lambdaForm.arity-1);
++ return form;
++ }
++ LambdaFormBuffer buf = buffer();
++ buf.startEdit();
++
++ assert(lambdaForm.parameter(srcPos).constraint == null);
++ assert(lambdaForm.parameter(dstPos).constraint == null);
++ buf.replaceParameterByCopy(dstPos, srcPos);
++
++ form = buf.endEdit();
++ return putInCache(key, form);
++ }
++
++ LambdaForm spreadArgumentsForm(int pos, Class<?> arrayType, int arrayLength) {
++ Class<?> elementType = arrayType.getComponentType();
++ Class<?> erasedArrayType = arrayType;
++ if (!elementType.isPrimitive())
++ erasedArrayType = Object[].class;
++ BasicType bt = basicType(elementType);
++ int elementTypeKey = bt.ordinal();
++ if (bt.basicTypeClass() != elementType) {
++ if (elementType.isPrimitive()) {
++ elementTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal();
++ }
++ }
++ Transform key = Transform.of(Transform.Kind.SPREAD_ARGS, pos, elementTypeKey, arrayLength);
++ LambdaForm form = getInCache(key);
++ if (form != null) {
++ assert(form.arity == lambdaForm.arity - arrayLength + 1);
++ return form;
++ }
++ LambdaFormBuffer buf = buffer();
++ buf.startEdit();
++
++ assert(pos <= MethodType.MAX_JVM_ARITY);
++ assert(pos + arrayLength <= lambdaForm.arity);
++ assert(pos > 0); // cannot spread the MH arg itself
++
++ Name spreadParam = new Name(L_TYPE);
++ Name checkSpread = new Name(MethodHandleImpl.Lazy.NF_checkSpreadArgument, spreadParam, arrayLength);
++
++ // insert the new expressions
++ int exprPos = lambdaForm.arity();
++ buf.insertExpression(exprPos++, checkSpread);
++ // adjust the arguments
++ MethodHandle aload = MethodHandles.arrayElementGetter(erasedArrayType);
++ for (int i = 0; i < arrayLength; i++) {
++ Name loadArgument = new Name(aload, spreadParam, i);
++ buf.insertExpression(exprPos + i, loadArgument);
++ buf.replaceParameterByCopy(pos + i, exprPos + i);
++ }
++ buf.insertParameter(pos, spreadParam);
++
++ form = buf.endEdit();
++ return putInCache(key, form);
++ }
++
++ LambdaForm collectArgumentsForm(int pos, MethodType collectorType) {
++ int collectorArity = collectorType.parameterCount();
++ boolean dropResult = (collectorType.returnType() == void.class);
++ if (collectorArity == 1 && !dropResult) {
++ return filterArgumentForm(pos, basicType(collectorType.parameterType(0)));
++ }
++ BasicType[] newTypes = BasicType.basicTypes(collectorType.parameterList());
++ Transform.Kind kind = (dropResult
++ ? Transform.Kind.COLLECT_ARGS_TO_VOID
++ : Transform.Kind.COLLECT_ARGS);
++ if (dropResult && collectorArity == 0) pos = 1; // pure side effect
++ Transform key = Transform.of(kind, pos, collectorArity, BasicType.basicTypesOrd(newTypes));
++ LambdaForm form = getInCache(key);
++ if (form != null) {
++ assert(form.arity == lambdaForm.arity - (dropResult ? 0 : 1) + collectorArity);
++ return form;
++ }
++ form = makeArgumentCombinationForm(pos, collectorType, false, dropResult);
++ return putInCache(key, form);
++ }
++
++ LambdaForm collectArgumentArrayForm(int pos, MethodHandle arrayCollector) {
++ MethodType collectorType = arrayCollector.type();
++ int collectorArity = collectorType.parameterCount();
++ assert(arrayCollector.intrinsicName() == Intrinsic.NEW_ARRAY);
++ Class<?> arrayType = collectorType.returnType();
++ Class<?> elementType = arrayType.getComponentType();
++ BasicType argType = basicType(elementType);
++ int argTypeKey = argType.ordinal();
++ if (argType.basicTypeClass() != elementType) {
++ // return null if it requires more metadata (like String[].class)
++ if (!elementType.isPrimitive())
++ return null;
++ argTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal();
++ }
++ assert(collectorType.parameterList().equals(Collections.nCopies(collectorArity, elementType)));
++ Transform.Kind kind = Transform.Kind.COLLECT_ARGS_TO_ARRAY;
++ Transform key = Transform.of(kind, pos, collectorArity, argTypeKey);
++ LambdaForm form = getInCache(key);
++ if (form != null) {
++ assert(form.arity == lambdaForm.arity - 1 + collectorArity);
++ return form;
++ }
++ LambdaFormBuffer buf = buffer();
++ buf.startEdit();
++
++ assert(pos + 1 <= lambdaForm.arity);
++ assert(pos > 0); // cannot filter the MH arg itself
++
++ Name[] newParams = new Name[collectorArity];
++ for (int i = 0; i < collectorArity; i++) {
++ newParams[i] = new Name(pos + i, argType);
++ }
++ Name callCombiner = new Name(arrayCollector, (Object[]) /*...*/ newParams);
++
++ // insert the new expression
++ int exprPos = lambdaForm.arity();
++ buf.insertExpression(exprPos, callCombiner);
++
++ // insert new arguments
++ int argPos = pos + 1; // skip result parameter
++ for (Name newParam : newParams) {
++ buf.insertParameter(argPos++, newParam);
++ }
++ assert(buf.lastIndexOf(callCombiner) == exprPos+newParams.length);
++ buf.replaceParameterByCopy(pos, exprPos+newParams.length);
++
++ form = buf.endEdit();
++ return putInCache(key, form);
++ }
++
++ LambdaForm filterArgumentForm(int pos, BasicType newType) {
++ Transform key = Transform.of(Transform.Kind.FILTER_ARG, pos, newType.ordinal());
++ LambdaForm form = getInCache(key);
++ if (form != null) {
++ assert(form.arity == lambdaForm.arity);
++ assert(form.parameterType(pos) == newType);
++ return form;
++ }
++
++ BasicType oldType = lambdaForm.parameterType(pos);
++ MethodType filterType = MethodType.methodType(oldType.basicTypeClass(),
++ newType.basicTypeClass());
++ form = makeArgumentCombinationForm(pos, filterType, false, false);
++ return putInCache(key, form);
++ }
++
++ private LambdaForm makeArgumentCombinationForm(int pos,
++ MethodType combinerType,
++ boolean keepArguments, boolean dropResult) {
++ LambdaFormBuffer buf = buffer();
++ buf.startEdit();
++ int combinerArity = combinerType.parameterCount();
++ int resultArity = (dropResult ? 0 : 1);
++
++ assert(pos <= MethodType.MAX_JVM_ARITY);
++ assert(pos + resultArity + (keepArguments ? combinerArity : 0) <= lambdaForm.arity);
++ assert(pos > 0); // cannot filter the MH arg itself
++ assert(combinerType == combinerType.basicType());
++ assert(combinerType.returnType() != void.class || dropResult);
++
++ BoundMethodHandle.SpeciesData oldData = oldSpeciesData();
++ BoundMethodHandle.SpeciesData newData = newSpeciesData(L_TYPE);
++
++ // The newly created LF will run with a different BMH.
++ // Switch over any pre-existing BMH field references to the new BMH class.
++ Name oldBaseAddress = lambdaForm.parameter(0); // BMH holding the values
++ buf.replaceFunctions(oldData.getterFunctions(), newData.getterFunctions(), oldBaseAddress);
++ Name newBaseAddress = oldBaseAddress.withConstraint(newData);
++ buf.renameParameter(0, newBaseAddress);
++
++ Name getCombiner = new Name(newData.getterFunction(oldData.fieldCount()), newBaseAddress);
++ Object[] combinerArgs = new Object[1 + combinerArity];
++ combinerArgs[0] = getCombiner;
++ Name[] newParams;
++ if (keepArguments) {
++ newParams = new Name[0];
++ System.arraycopy(lambdaForm.names, pos + resultArity,
++ combinerArgs, 1, combinerArity);
++ } else {
++ newParams = new Name[combinerArity];
++ BasicType[] newTypes = basicTypes(combinerType.parameterList());
++ for (int i = 0; i < newTypes.length; i++) {
++ newParams[i] = new Name(pos + i, newTypes[i]);
++ }
++ System.arraycopy(newParams, 0,
++ combinerArgs, 1, combinerArity);
++ }
++ Name callCombiner = new Name(combinerType, combinerArgs);
++
++ // insert the two new expressions
++ int exprPos = lambdaForm.arity();
++ buf.insertExpression(exprPos+0, getCombiner);
++ buf.insertExpression(exprPos+1, callCombiner);
++
++ // insert new arguments, if needed
++ int argPos = pos + resultArity; // skip result parameter
++ for (Name newParam : newParams) {
++ buf.insertParameter(argPos++, newParam);
++ }
++ assert(buf.lastIndexOf(callCombiner) == exprPos+1+newParams.length);
++ if (!dropResult) {
++ buf.replaceParameterByCopy(pos, exprPos+1+newParams.length);
++ }
++
++ return buf.endEdit();
++ }
++
++ LambdaForm filterReturnForm(BasicType newType, boolean constantZero) {
++ Transform.Kind kind = (constantZero ? Transform.Kind.FILTER_RETURN_TO_ZERO : Transform.Kind.FILTER_RETURN);
++ Transform key = Transform.of(kind, newType.ordinal());
++ LambdaForm form = getInCache(key);
++ if (form != null) {
++ assert(form.arity == lambdaForm.arity);
++ assert(form.returnType() == newType);
++ return form;
++ }
++ LambdaFormBuffer buf = buffer();
++ buf.startEdit();
++
++ int insPos = lambdaForm.names.length;
++ Name callFilter;
++ if (constantZero) {
++ // Synthesize a constant zero value for the given type.
++ if (newType == V_TYPE)
++ callFilter = null;
++ else
++ callFilter = new Name(constantZero(newType));
++ } else {
++ BoundMethodHandle.SpeciesData oldData = oldSpeciesData();
++ BoundMethodHandle.SpeciesData newData = newSpeciesData(L_TYPE);
++
++ // The newly created LF will run with a different BMH.
++ // Switch over any pre-existing BMH field references to the new BMH class.
++ Name oldBaseAddress = lambdaForm.parameter(0); // BMH holding the values
++ buf.replaceFunctions(oldData.getterFunctions(), newData.getterFunctions(), oldBaseAddress);
++ Name newBaseAddress = oldBaseAddress.withConstraint(newData);
++ buf.renameParameter(0, newBaseAddress);
++
++ Name getFilter = new Name(newData.getterFunction(oldData.fieldCount()), newBaseAddress);
++ buf.insertExpression(insPos++, getFilter);
++ BasicType oldType = lambdaForm.returnType();
++ if (oldType == V_TYPE) {
++ MethodType filterType = MethodType.methodType(newType.basicTypeClass());
++ callFilter = new Name(filterType, getFilter);
++ } else {
++ MethodType filterType = MethodType.methodType(newType.basicTypeClass(), oldType.basicTypeClass());
++ callFilter = new Name(filterType, getFilter, lambdaForm.names[lambdaForm.result]);
++ }
++ }
++
++ if (callFilter != null)
++ buf.insertExpression(insPos++, callFilter);
++ buf.setResult(callFilter);
++
++ form = buf.endEdit();
++ return putInCache(key, form);
++ }
++
++ LambdaForm foldArgumentsForm(int foldPos, boolean dropResult, MethodType combinerType) {
++ int combinerArity = combinerType.parameterCount();
++ Transform.Kind kind = (dropResult ? Transform.Kind.FOLD_ARGS_TO_VOID : Transform.Kind.FOLD_ARGS);
++ Transform key = Transform.of(kind, foldPos, combinerArity);
++ LambdaForm form = getInCache(key);
++ if (form != null) {
++ assert(form.arity == lambdaForm.arity - (kind == Transform.Kind.FOLD_ARGS ? 1 : 0));
++ return form;
++ }
++ form = makeArgumentCombinationForm(foldPos, combinerType, true, dropResult);
++ return putInCache(key, form);
++ }
++
++ LambdaForm permuteArgumentsForm(int skip, int[] reorder) {
++ assert(skip == 1); // skip only the leading MH argument, names[0]
++ int length = lambdaForm.names.length;
++ int outArgs = reorder.length;
++ int inTypes = 0;
++ boolean nullPerm = true;
++ for (int i = 0; i < reorder.length; i++) {
++ int inArg = reorder[i];
++ if (inArg != i) nullPerm = false;
++ inTypes = Math.max(inTypes, inArg+1);
++ }
++ assert(skip + reorder.length == lambdaForm.arity);
++ if (nullPerm) return lambdaForm; // do not bother to cache
++ Transform key = Transform.of(Transform.Kind.PERMUTE_ARGS, reorder);
++ LambdaForm form = getInCache(key);
++ if (form != null) {
++ assert(form.arity == skip+inTypes) : form;
++ return form;
++ }
++
++ BasicType[] types = new BasicType[inTypes];
++ for (int i = 0; i < outArgs; i++) {
++ int inArg = reorder[i];
++ types[inArg] = lambdaForm.names[skip + i].type;
++ }
++ assert (skip + outArgs == lambdaForm.arity);
++ assert (permutedTypesMatch(reorder, types, lambdaForm.names, skip));
++ int pos = 0;
++ while (pos < outArgs && reorder[pos] == pos) {
++ pos += 1;
++ }
++ Name[] names2 = new Name[length - outArgs + inTypes];
++ System.arraycopy(lambdaForm.names, 0, names2, 0, skip + pos);
++ int bodyLength = length - lambdaForm.arity;
++ System.arraycopy(lambdaForm.names, skip + outArgs, names2, skip + inTypes, bodyLength);
++ int arity2 = names2.length - bodyLength;
++ int result2 = lambdaForm.result;
++ if (result2 >= 0) {
++ if (result2 < skip + outArgs) {
++ result2 = reorder[result2 - skip];
++ } else {
++ result2 = result2 - outArgs + inTypes;
++ }
++ }
++ for (int j = pos; j < outArgs; j++) {
++ Name n = lambdaForm.names[skip + j];
++ int i = reorder[j];
++ Name n2 = names2[skip + i];
++ if (n2 == null) {
++ names2[skip + i] = n2 = new Name(types[i]);
++ } else {
++ assert (n2.type == types[i]);
++ }
++ for (int k = arity2; k < names2.length; k++) {
++ names2[k] = names2[k].replaceName(n, n2);
++ }
++ }
++ for (int i = skip + pos; i < arity2; i++) {
++ if (names2[i] == null) {
++ names2[i] = argument(i, types[i - skip]);
++ }
++ }
++ for (int j = lambdaForm.arity; j < lambdaForm.names.length; j++) {
++ int i = j - lambdaForm.arity + arity2;
++ Name n = lambdaForm.names[j];
++ Name n2 = names2[i];
++ if (n != n2) {
++ for (int k = i + 1; k < names2.length; k++) {
++ names2[k] = names2[k].replaceName(n, n2);
++ }
++ }
++ }
++
++ form = new LambdaForm(lambdaForm.debugName, arity2, names2, result2);
++ return putInCache(key, form);
++ }
++
++ static boolean permutedTypesMatch(int[] reorder, BasicType[] types, Name[] names, int skip) {
++ for (int i = 0; i < reorder.length; i++) {
++ assert (names[skip + i].isParam());
++ assert (names[skip + i].type == types[reorder[i]]);
++ }
++ return true;
++ }
++}
+--- ./jdk/src/share/classes/java/lang/invoke/MemberName.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/MemberName.java Wed Feb 04 12:14:43 2015 -0800
+@@ -327,10 +327,6 @@
+ assert(getReferenceKind() == oldKind);
+ assert(MethodHandleNatives.refKindIsValid(refKind));
+ flags += (((int)refKind - oldKind) << MN_REFERENCE_KIND_SHIFT);
+-// if (isConstructor() && refKind != REF_newInvokeSpecial)
+-// flags += (IS_METHOD - IS_CONSTRUCTOR);
+-// else if (refKind == REF_newInvokeSpecial && isMethod())
+-// flags += (IS_CONSTRUCTOR - IS_METHOD);
+ return this;
+ }
+
+@@ -344,9 +340,11 @@
+ return !testFlags(mask, 0);
+ }
+
+- /** Utility method to query if this member is a method handle invocation (invoke or invokeExact). */
++ /** Utility method to query if this member is a method handle invocation (invoke or invokeExact).
++ * Also returns true for the non-public MH.invokeBasic.
++ */
+ public boolean isMethodHandleInvoke() {
+- final int bits = MH_INVOKE_MODS;
++ final int bits = MH_INVOKE_MODS &~ Modifier.PUBLIC;
+ final int negs = Modifier.STATIC;
+ if (testFlags(bits | negs, bits) &&
+ clazz == MethodHandle.class) {
+@@ -355,7 +353,14 @@
+ return false;
+ }
+ public static boolean isMethodHandleInvokeName(String name) {
+- return name.equals("invoke") || name.equals("invokeExact");
++ switch (name) {
++ case "invoke":
++ case "invokeExact":
++ case "invokeBasic": // internal sig-poly method
++ return true;
++ default:
++ return false;
++ }
+ }
+ private static final int MH_INVOKE_MODS = Modifier.NATIVE | Modifier.FINAL | Modifier.PUBLIC;
+
+@@ -720,16 +725,8 @@
+ init(defClass, name, type, flagsMods(IS_FIELD, 0, refKind));
+ initResolved(false);
+ }
+- /** Create a field or type name from the given components: Declaring class, name, type.
+- * The declaring class may be supplied as null if this is to be a bare name and type.
+- * The modifier flags default to zero.
+- * The resulting name will in an unresolved state.
+- */
+- public MemberName(Class<?> defClass, String name, Class<?> type, Void unused) {
+- this(defClass, name, type, REF_NONE);
+- initResolved(false);
+- }
+- /** Create a method or constructor name from the given components: Declaring class, name, type, modifiers.
++ /** Create a method or constructor name from the given components:
++ * Declaring class, name, type, reference kind.
+ * It will be a constructor if and only if the name is {@code "&lt;init&gt;"}.
+ * The declaring class may be supplied as null if this is to be a bare name and type.
+ * The last argument is optional, a boolean which requests REF_invokeSpecial.
+--- ./jdk/src/share/classes/java/lang/invoke/MethodHandle.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/MethodHandle.java Wed Feb 04 12:14:43 2015 -0800
+@@ -27,12 +27,8 @@
+
+
+ import java.util.*;
+-import sun.invoke.util.*;
+-import sun.misc.Unsafe;
+
+ import static java.lang.invoke.MethodHandleStatics.*;
+-import java.util.logging.Level;
+-import java.util.logging.Logger;
+
+ /**
+ * A method handle is a typed, directly executable reference to an underlying method,
+@@ -625,15 +621,8 @@
+ * @see MethodHandles#spreadInvoker
+ */
+ public Object invokeWithArguments(Object... arguments) throws Throwable {
+- int argc = arguments == null ? 0 : arguments.length;
+- @SuppressWarnings("LocalVariableHidesMemberVariable")
+- MethodType type = type();
+- if (type.parameterCount() != argc || isVarargsCollector()) {
+- // simulate invoke
+- return asType(MethodType.genericMethodType(argc)).invokeWithArguments(arguments);
+- }
+- MethodHandle invoker = type.invokers().varargsInvoker();
+- return invoker.invokeExact(this, arguments);
++ MethodType invocationType = MethodType.genericMethodType(arguments == null ? 0 : arguments.length);
++ return invocationType.invokers().spreadInvoker(0).invokeExact(asType(invocationType), arguments);
+ }
+
+ /**
+@@ -731,7 +720,7 @@
+ * <li>If the return type <em>T0</em> is void and <em>T1</em> a primitive,
+ * a zero value is introduced.
+ * </ul>
+- * (<em>Note:</em> Both <em>T0</em> and <em>T1</em> may be regarded as static types,
++ * (<em>Note:</em> Both <em>T0</em> and <em>T1</em> may be regarded as static types,
+ * because neither corresponds specifically to the <em>dynamic type</em> of any
+ * actual argument or return value.)
+ * <p>
+@@ -763,18 +752,26 @@
+ return this;
+ }
+ // Return 'this.asTypeCache' if the conversion is already memoized.
++ MethodHandle atc = asTypeCached(newType);
++ if (atc != null) {
++ return atc;
++ }
++ return asTypeUncached(newType);
++ }
++
++ private MethodHandle asTypeCached(MethodType newType) {
+ MethodHandle atc = asTypeCache;
+ if (atc != null && newType == atc.type) {
+ return atc;
+ }
+- return asTypeUncached(newType);
++ return null;
+ }
+
+ /** Override this to change asType behavior. */
+ /*non-public*/ MethodHandle asTypeUncached(MethodType newType) {
+ if (!type.isConvertibleTo(newType))
+ throw new WrongMethodTypeException("cannot convert "+this+" to "+newType);
+- return asTypeCache = convertArguments(newType);
++ return asTypeCache = MethodHandleImpl.makePairwiseConvert(this, newType, true);
+ }
+
+ /**
+@@ -867,34 +864,44 @@
+ * @see #asCollector
+ */
+ public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
+- asSpreaderChecks(arrayType, arrayLength);
+- int spreadArgPos = type.parameterCount() - arrayLength;
+- return MethodHandleImpl.makeSpreadArguments(this, arrayType, spreadArgPos, arrayLength);
++ MethodType postSpreadType = asSpreaderChecks(arrayType, arrayLength);
++ int arity = type().parameterCount();
++ int spreadArgPos = arity - arrayLength;
++ MethodHandle afterSpread = this.asType(postSpreadType);
++ BoundMethodHandle mh = afterSpread.rebind();
++ LambdaForm lform = mh.editor().spreadArgumentsForm(1 + spreadArgPos, arrayType, arrayLength);
++ MethodType preSpreadType = postSpreadType.replaceParameterTypes(spreadArgPos, arity, arrayType);
++ return mh.copyWith(preSpreadType, lform);
+ }
+
+- private void asSpreaderChecks(Class<?> arrayType, int arrayLength) {
++ /**
++ * See if {@code asSpreader} can be validly called with the given arguments.
++ * Return the type of the method handle call after spreading but before conversions.
++ */
++ private MethodType asSpreaderChecks(Class<?> arrayType, int arrayLength) {
+ spreadArrayChecks(arrayType, arrayLength);
+ int nargs = type().parameterCount();
+ if (nargs < arrayLength || arrayLength < 0)
+ throw newIllegalArgumentException("bad spread array length");
+- if (arrayType != Object[].class && arrayLength != 0) {
+- boolean sawProblem = false;
+- Class<?> arrayElement = arrayType.getComponentType();
+- for (int i = nargs - arrayLength; i < nargs; i++) {
+- if (!MethodType.canConvert(arrayElement, type().parameterType(i))) {
+- sawProblem = true;
++ Class<?> arrayElement = arrayType.getComponentType();
++ MethodType mtype = type();
++ boolean match = true, fail = false;
++ for (int i = nargs - arrayLength; i < nargs; i++) {
++ Class<?> ptype = mtype.parameterType(i);
++ if (ptype != arrayElement) {
++ match = false;
++ if (!MethodType.canConvert(arrayElement, ptype)) {
++ fail = true;
+ break;
+ }
+ }
+- if (sawProblem) {
+- ArrayList<Class<?>> ptypes = new ArrayList<>(type().parameterList());
+- for (int i = nargs - arrayLength; i < nargs; i++) {
+- ptypes.set(i, arrayElement);
+- }
+- // elicit an error:
+- this.asType(MethodType.methodType(type().returnType(), ptypes));
+- }
+ }
++ if (match) return mtype;
++ MethodType needType = mtype.asSpreaderType(arrayType, arrayLength);
++ if (!fail) return needType;
++ // elicit an error:
++ this.asType(needType);
++ throw newInternalError("should not return", null);
+ }
+
+ private void spreadArrayChecks(Class<?> arrayType, int arrayLength) {
+@@ -984,16 +991,23 @@
+ */
+ public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
+ asCollectorChecks(arrayType, arrayLength);
+- int collectArgPos = type().parameterCount()-1;
+- MethodHandle target = this;
+- if (arrayType != type().parameterType(collectArgPos))
+- target = convertArguments(type().changeParameterType(collectArgPos, arrayType));
+- MethodHandle collector = ValueConversions.varargsArray(arrayType, arrayLength);
+- return MethodHandles.collectArguments(target, collectArgPos, collector);
++ int collectArgPos = type().parameterCount() - 1;
++ BoundMethodHandle mh = rebind();
++ MethodType resultType = type().asCollectorType(arrayType, arrayLength);
++ MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
++ LambdaForm lform = mh.editor().collectArgumentArrayForm(1 + collectArgPos, newArray);
++ if (lform != null) {
++ return mh.copyWith(resultType, lform);
++ }
++ lform = mh.editor().collectArgumentsForm(1 + collectArgPos, newArray.type().basicType());
++ return mh.copyWithExtendL(resultType, lform, newArray);
+ }
+
+- // private API: return true if last param exactly matches arrayType
+- private boolean asCollectorChecks(Class<?> arrayType, int arrayLength) {
++ /**
++ * See if {@code asCollector} can be validly called with the given arguments.
++ * Return false if the last parameter is not an exact match to arrayType.
++ */
++ /*non-public*/ boolean asCollectorChecks(Class<?> arrayType, int arrayLength) {
+ spreadArrayChecks(arrayType, arrayLength);
+ int nargs = type().parameterCount();
+ if (nargs != 0) {
+@@ -1155,7 +1169,7 @@
+ * @see #asFixedArity
+ */
+ public MethodHandle asVarargsCollector(Class<?> arrayType) {
+- Class<?> arrayElement = arrayType.getComponentType();
++ arrayType.getClass(); // explicit NPE
+ boolean lastMatch = asCollectorChecks(arrayType, 0);
+ if (isVarargsCollector() && lastMatch)
+ return this;
+@@ -1257,14 +1271,8 @@
+ * @see MethodHandles#insertArguments
+ */
+ public MethodHandle bindTo(Object x) {
+- Class<?> ptype;
+- @SuppressWarnings("LocalVariableHidesMemberVariable")
+- MethodType type = type();
+- if (type.parameterCount() == 0 ||
+- (ptype = type.parameterType(0)).isPrimitive())
+- throw newIllegalArgumentException("no leading reference parameter", x);
+- x = ptype.cast(x); // throw CCE if needed
+- return bindReceiver(x);
++ x = type.leadingReferenceParameter().cast(x); // throw CCE if needed
++ return bindArgumentL(0, x);
+ }
+
+ /**
+@@ -1284,14 +1292,17 @@
+ */
+ @Override
+ public String toString() {
+- if (DEBUG_METHOD_HANDLE_NAMES) return debugString();
++ if (DEBUG_METHOD_HANDLE_NAMES) return "MethodHandle"+debugString();
+ return standardString();
+ }
+ String standardString() {
+ return "MethodHandle"+type;
+ }
++ /** Return a string with a several lines describing the method handle structure.
++ * This string would be suitable for display in an IDE debugger.
++ */
+ String debugString() {
+- return standardString()+"/LF="+internalForm()+internalProperties();
++ return type+" : "+internalForm()+internalProperties();
+ }
+
+ //// Implementation methods.
+@@ -1300,22 +1311,42 @@
+
+ // Other transforms to do: convert, explicitCast, permute, drop, filter, fold, GWT, catch
+
++ BoundMethodHandle bindArgumentL(int pos, Object value) {
++ return rebind().bindArgumentL(pos, value);
++ }
++
+ /*non-public*/
+ MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
+ if (!member.isVarargs()) return this;
+- int argc = type().parameterCount();
+- if (argc != 0) {
+- Class<?> arrayType = type().parameterType(argc-1);
+- if (arrayType.isArray()) {
+- return MethodHandleImpl.makeVarargsCollector(this, arrayType);
+- }
++ Class<?> arrayType = type().lastParameterType();
++ if (arrayType.isArray()) {
++ return MethodHandleImpl.makeVarargsCollector(this, arrayType);
+ }
+ throw member.makeAccessException("cannot make variable arity", null);
+ }
++
+ /*non-public*/
+- MethodHandle viewAsType(MethodType newType) {
++ MethodHandle viewAsType(MethodType newType, boolean strict) {
+ // No actual conversions, just a new view of the same method.
+- return MethodHandleImpl.makePairwiseConvert(this, newType, 0);
++ // Note that this operation must not produce a DirectMethodHandle,
++ // because retyped DMHs, like any transformed MHs,
++ // cannot be cracked into MethodHandleInfo.
++ assert viewAsTypeChecks(newType, strict);
++ BoundMethodHandle mh = rebind();
++ assert(!((MethodHandle)mh instanceof DirectMethodHandle));
++ return mh.copyWith(newType, mh.form);
++ }
++
++ /*non-public*/
++ boolean viewAsTypeChecks(MethodType newType, boolean strict) {
++ if (strict) {
++ assert(type().isViewableAs(newType, true))
++ : Arrays.asList(this, newType);
++ } else {
++ assert(type().basicType().isViewableAs(newType.basicType(), true))
++ : Arrays.asList(this, newType);
++ }
++ return true;
+ }
+
+ // Decoding
+@@ -1336,9 +1367,15 @@
+ }
+
+ /*non-public*/
+- MethodHandle withInternalMemberName(MemberName member) {
++ MethodHandleImpl.Intrinsic intrinsicName() {
++ // no special intrinsic meaning to most MHs
++ return MethodHandleImpl.Intrinsic.NONE;
++ }
++
++ /*non-public*/
++ MethodHandle withInternalMemberName(MemberName member, boolean isInvokeSpecial) {
+ if (member != null) {
+- return MethodHandleImpl.makeWrappedMember(this, member);
++ return MethodHandleImpl.makeWrappedMember(this, member, isInvokeSpecial);
+ } else if (internalMemberName() == null) {
+ // The required internaMemberName is null, and this MH (like most) doesn't have one.
+ return this;
+@@ -1362,7 +1399,7 @@
+
+ /*non-public*/
+ Object internalProperties() {
+- // Override to something like "/FOO=bar"
++ // Override to something to follow this.form, like "\n& FOO=bar"
+ return "";
+ }
+
+@@ -1370,114 +1407,14 @@
+ //// Sub-classes can override these default implementations.
+ //// All these methods assume arguments are already validated.
+
+- /*non-public*/ MethodHandle convertArguments(MethodType newType) {
+- // Override this if it can be improved.
+- return MethodHandleImpl.makePairwiseConvert(this, newType, 1);
+- }
++ /*non-public*/
++ abstract MethodHandle copyWith(MethodType mt, LambdaForm lf);
+
+- /*non-public*/
+- MethodHandle bindArgument(int pos, char basicType, Object value) {
+- // Override this if it can be improved.
+- return rebind().bindArgument(pos, basicType, value);
+- }
+-
+- /*non-public*/
+- MethodHandle bindReceiver(Object receiver) {
+- // Override this if it can be improved.
+- return bindArgument(0, 'L', receiver);
+- }
+-
+- /*non-public*/
+- MethodHandle bindImmediate(int pos, char basicType, Object value) {
+- // Bind an immediate value to a position in the arguments.
+- // This means, elide the respective argument,
+- // and replace all references to it in NamedFunction args with the specified value.
+-
+- // CURRENT RESTRICTIONS
+- // * only for pos 0 and UNSAFE (position is adjusted in MHImpl to make API usable for others)
+- assert pos == 0 && basicType == 'L' && value instanceof Unsafe;
+- MethodType type2 = type.dropParameterTypes(pos, pos + 1); // adjustment: ignore receiver!
+- LambdaForm form2 = form.bindImmediate(pos + 1, basicType, value); // adjust pos to form-relative pos
+- return copyWith(type2, form2);
+- }
+-
+- /*non-public*/
+- MethodHandle copyWith(MethodType mt, LambdaForm lf) {
+- throw new InternalError("copyWith: " + this.getClass());
+- }
+-
+- /*non-public*/
+- MethodHandle dropArguments(MethodType srcType, int pos, int drops) {
+- // Override this if it can be improved.
+- return rebind().dropArguments(srcType, pos, drops);
+- }
+-
+- /*non-public*/
+- MethodHandle permuteArguments(MethodType newType, int[] reorder) {
+- // Override this if it can be improved.
+- return rebind().permuteArguments(newType, reorder);
+- }
+-
+- /*non-public*/
+- MethodHandle rebind() {
+- // Bind 'this' into a new invoker, of the known class BMH.
+- MethodType type2 = type();
+- LambdaForm form2 = reinvokerForm(this);
+- // form2 = lambda (bmh, arg*) { thismh = bmh[0]; invokeBasic(thismh, arg*) }
+- return BoundMethodHandle.bindSingle(type2, form2, this);
+- }
+-
+- /*non-public*/
+- MethodHandle reinvokerTarget() {
+- throw new InternalError("not a reinvoker MH: "+this.getClass().getName()+": "+this);
+- }
+-
+- /** Create a LF which simply reinvokes a target of the given basic type.
+- * The target MH must override {@link #reinvokerTarget} to provide the target.
++ /** Require this method handle to be a BMH, or else replace it with a "wrapper" BMH.
++ * Many transforms are implemented only for BMHs.
++ * @return a behaviorally equivalent BMH
+ */
+- static LambdaForm reinvokerForm(MethodHandle target) {
+- MethodType mtype = target.type().basicType();
+- LambdaForm reinvoker = mtype.form().cachedLambdaForm(MethodTypeForm.LF_REINVOKE);
+- if (reinvoker != null) return reinvoker;
+- if (mtype.parameterSlotCount() >= MethodType.MAX_MH_ARITY)
+- return makeReinvokerForm(target.type(), target); // cannot cache this
+- reinvoker = makeReinvokerForm(mtype, null);
+- return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_REINVOKE, reinvoker);
+- }
+- private static LambdaForm makeReinvokerForm(MethodType mtype, MethodHandle customTargetOrNull) {
+- boolean customized = (customTargetOrNull != null);
+- MethodHandle MH_invokeBasic = customized ? null : MethodHandles.basicInvoker(mtype);
+- final int THIS_BMH = 0;
+- final int ARG_BASE = 1;
+- final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
+- int nameCursor = ARG_LIMIT;
+- final int NEXT_MH = customized ? -1 : nameCursor++;
+- final int REINVOKE = nameCursor++;
+- LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
+- Object[] targetArgs;
+- MethodHandle targetMH;
+- if (customized) {
+- targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class);
+- targetMH = customTargetOrNull;
+- } else {
+- names[NEXT_MH] = new LambdaForm.Name(NF_reinvokerTarget, names[THIS_BMH]);
+- targetArgs = Arrays.copyOfRange(names, THIS_BMH, ARG_LIMIT, Object[].class);
+- targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH
+- targetMH = MethodHandles.basicInvoker(mtype);
+- }
+- names[REINVOKE] = new LambdaForm.Name(targetMH, targetArgs);
+- return new LambdaForm("BMH.reinvoke", ARG_LIMIT, names);
+- }
+-
+- private static final LambdaForm.NamedFunction NF_reinvokerTarget;
+- static {
+- try {
+- NF_reinvokerTarget = new LambdaForm.NamedFunction(MethodHandle.class
+- .getDeclaredMethod("reinvokerTarget"));
+- } catch (ReflectiveOperationException ex) {
+- throw newInternalError(ex);
+- }
+- }
++ abstract BoundMethodHandle rebind();
+
+ /**
+ * Replace the old lambda form of this method handle with a new one.
+@@ -1489,9 +1426,9 @@
+ /*non-public*/
+ void updateForm(LambdaForm newForm) {
+ if (form == newForm) return;
+- // ISSUE: Should we have a memory fence here?
++ newForm.prepare(); // as in MethodHandle.<init>
+ UNSAFE.putObject(this, FORM_OFFSET, newForm);
+- this.form.prepare(); // as in MethodHandle.<init>
++ UNSAFE.fullFence();
+ }
+
+ private static final long FORM_OFFSET;
+--- ./jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -27,8 +27,11 @@
+
+ import java.security.AccessController;
+ import java.security.PrivilegedAction;
++import java.util.ArrayList;
+ import java.util.Arrays;
+-import java.util.HashMap;
++import java.util.Collections;
++import java.util.function.Function;
++
+ import sun.invoke.empty.Empty;
+ import sun.invoke.util.ValueConversions;
+ import sun.invoke.util.VerifyType;
+@@ -44,6 +47,20 @@
+ * @author jrose
+ */
+ /*non-public*/ abstract class MethodHandleImpl {
++ // Do not adjust this except for special platforms:
++ private static final int MAX_ARITY;
++ static {
++ final Object[] values = { 255 };
++ AccessController.doPrivileged(new PrivilegedAction<Void>() {
++ @Override
++ public Void run() {
++ values[0] = Integer.getInteger(MethodHandleImpl.class.getName()+".MAX_ARITY", 255);
++ return null;
++ }
++ });
++ MAX_ARITY = (Integer) values[0];
++ }
++
+ /// Factory methods to create method handles:
+
+ static void initStatics() {
+@@ -52,27 +69,55 @@
+ }
+
+ static MethodHandle makeArrayElementAccessor(Class<?> arrayClass, boolean isSetter) {
++ if (arrayClass == Object[].class)
++ return (isSetter ? ArrayAccessor.OBJECT_ARRAY_SETTER : ArrayAccessor.OBJECT_ARRAY_GETTER);
+ if (!arrayClass.isArray())
+ throw newIllegalArgumentException("not an array: "+arrayClass);
+- MethodHandle accessor = ArrayAccessor.getAccessor(arrayClass, isSetter);
+- MethodType srcType = accessor.type().erase();
+- MethodType lambdaType = srcType.invokerType();
+- Name[] names = arguments(1, lambdaType);
+- Name[] args = Arrays.copyOfRange(names, 1, 1 + srcType.parameterCount());
+- names[names.length - 1] = new Name(accessor.asType(srcType), (Object[]) args);
+- LambdaForm form = new LambdaForm("getElement", lambdaType.parameterCount(), names);
+- MethodHandle mh = SimpleMethodHandle.make(srcType, form);
+- if (ArrayAccessor.needCast(arrayClass)) {
+- mh = mh.bindTo(arrayClass);
++ MethodHandle[] cache = ArrayAccessor.TYPED_ACCESSORS.get(arrayClass);
++ int cacheIndex = (isSetter ? ArrayAccessor.SETTER_INDEX : ArrayAccessor.GETTER_INDEX);
++ MethodHandle mh = cache[cacheIndex];
++ if (mh != null) return mh;
++ mh = ArrayAccessor.getAccessor(arrayClass, isSetter);
++ MethodType correctType = ArrayAccessor.correctType(arrayClass, isSetter);
++ if (mh.type() != correctType) {
++ assert(mh.type().parameterType(0) == Object[].class);
++ assert((isSetter ? mh.type().parameterType(2) : mh.type().returnType()) == Object.class);
++ assert(isSetter || correctType.parameterType(0).getComponentType() == correctType.returnType());
++ // safe to view non-strictly, because element type follows from array type
++ mh = mh.viewAsType(correctType, false);
+ }
+- mh = mh.asType(ArrayAccessor.correctType(arrayClass, isSetter));
++ mh = makeIntrinsic(mh, (isSetter ? Intrinsic.ARRAY_STORE : Intrinsic.ARRAY_LOAD));
++ // Atomically update accessor cache.
++ synchronized(cache) {
++ if (cache[cacheIndex] == null) {
++ cache[cacheIndex] = mh;
++ } else {
++ // Throw away newly constructed accessor and use cached version.
++ mh = cache[cacheIndex];
++ }
++ }
+ return mh;
+ }
+
+ static final class ArrayAccessor {
+ /// Support for array element access
+- static final HashMap<Class<?>, MethodHandle> GETTER_CACHE = new HashMap<>(); // TODO use it
+- static final HashMap<Class<?>, MethodHandle> SETTER_CACHE = new HashMap<>(); // TODO use it
++ static final int GETTER_INDEX = 0, SETTER_INDEX = 1, INDEX_LIMIT = 2;
++ static final ClassValue<MethodHandle[]> TYPED_ACCESSORS
++ = new ClassValue<MethodHandle[]>() {
++ @Override
++ protected MethodHandle[] computeValue(Class<?> type) {
++ return new MethodHandle[INDEX_LIMIT];
++ }
++ };
++ static final MethodHandle OBJECT_ARRAY_GETTER, OBJECT_ARRAY_SETTER;
++ static {
++ MethodHandle[] cache = TYPED_ACCESSORS.get(Object[].class);
++ cache[GETTER_INDEX] = OBJECT_ARRAY_GETTER = makeIntrinsic(getAccessor(Object[].class, false), Intrinsic.ARRAY_LOAD);
++ cache[SETTER_INDEX] = OBJECT_ARRAY_SETTER = makeIntrinsic(getAccessor(Object[].class, true), Intrinsic.ARRAY_STORE);
++
++ assert(InvokerBytecodeGenerator.isStaticallyInvocable(ArrayAccessor.OBJECT_ARRAY_GETTER.internalMemberName()));
++ assert(InvokerBytecodeGenerator.isStaticallyInvocable(ArrayAccessor.OBJECT_ARRAY_SETTER.internalMemberName()));
++ }
+
+ static int getElementI(int[] a, int i) { return a[i]; }
+ static long getElementJ(long[] a, int i) { return a[i]; }
+@@ -94,45 +139,21 @@
+ static void setElementC(char[] a, int i, char x) { a[i] = x; }
+ static void setElementL(Object[] a, int i, Object x) { a[i] = x; }
+
+- static Object getElementL(Class<?> arrayClass, Object[] a, int i) { arrayClass.cast(a); return a[i]; }
+- static void setElementL(Class<?> arrayClass, Object[] a, int i, Object x) { arrayClass.cast(a); a[i] = x; }
+-
+- // Weakly typed wrappers of Object[] accessors:
+- static Object getElementL(Object a, int i) { return getElementL((Object[])a, i); }
+- static void setElementL(Object a, int i, Object x) { setElementL((Object[]) a, i, x); }
+- static Object getElementL(Object arrayClass, Object a, int i) { return getElementL((Class<?>) arrayClass, (Object[])a, i); }
+- static void setElementL(Object arrayClass, Object a, int i, Object x) { setElementL((Class<?>) arrayClass, (Object[])a, i, x); }
+-
+- static boolean needCast(Class<?> arrayClass) {
+- Class<?> elemClass = arrayClass.getComponentType();
+- return !elemClass.isPrimitive() && elemClass != Object.class;
+- }
+ static String name(Class<?> arrayClass, boolean isSetter) {
+ Class<?> elemClass = arrayClass.getComponentType();
+- if (elemClass == null) throw new IllegalArgumentException();
++ if (elemClass == null) throw newIllegalArgumentException("not an array", arrayClass);
+ return (!isSetter ? "getElement" : "setElement") + Wrapper.basicTypeChar(elemClass);
+ }
+- static final boolean USE_WEAKLY_TYPED_ARRAY_ACCESSORS = false; // FIXME: decide
+ static MethodType type(Class<?> arrayClass, boolean isSetter) {
+ Class<?> elemClass = arrayClass.getComponentType();
+ Class<?> arrayArgClass = arrayClass;
+ if (!elemClass.isPrimitive()) {
+ arrayArgClass = Object[].class;
+- if (USE_WEAKLY_TYPED_ARRAY_ACCESSORS)
+- arrayArgClass = Object.class;
++ elemClass = Object.class;
+ }
+- if (!needCast(arrayClass)) {
+- return !isSetter ?
++ return !isSetter ?
+ MethodType.methodType(elemClass, arrayArgClass, int.class) :
+ MethodType.methodType(void.class, arrayArgClass, int.class, elemClass);
+- } else {
+- Class<?> classArgClass = Class.class;
+- if (USE_WEAKLY_TYPED_ARRAY_ACCESSORS)
+- classArgClass = Object.class;
+- return !isSetter ?
+- MethodType.methodType(Object.class, classArgClass, arrayArgClass, int.class) :
+- MethodType.methodType(void.class, classArgClass, arrayArgClass, int.class, Object.class);
+- }
+ }
+ static MethodType correctType(Class<?> arrayClass, boolean isSetter) {
+ Class<?> elemClass = arrayClass.getComponentType();
+@@ -159,40 +180,106 @@
+ * integral widening or narrowing, and floating point widening or narrowing.
+ * @param srcType required call type
+ * @param target original method handle
+- * @param level which strength of conversion is allowed
++ * @param strict if true, only asType conversions are allowed; if false, explicitCastArguments conversions allowed
++ * @param monobox if true, unboxing conversions are assumed to be exactly typed (Integer to int only, not long or double)
+ * @return an adapter to the original handle with the desired new type,
+ * or the original target if the types are already identical
+ * or null if the adaptation cannot be made
+ */
+- static MethodHandle makePairwiseConvert(MethodHandle target, MethodType srcType, int level) {
+- assert(level >= 0 && level <= 2);
++ static MethodHandle makePairwiseConvert(MethodHandle target, MethodType srcType,
++ boolean strict, boolean monobox) {
+ MethodType dstType = target.type();
+- assert(dstType.parameterCount() == target.type().parameterCount());
+ if (srcType == dstType)
+ return target;
++ return makePairwiseConvertByEditor(target, srcType, strict, monobox);
++ }
+
+- // Calculate extra arguments (temporaries) required in the names array.
+- // FIXME: Use an ArrayList<Name>. Some arguments require more than one conversion step.
+- final int INARG_COUNT = srcType.parameterCount();
+- int conversions = 0;
+- boolean[] needConv = new boolean[1+INARG_COUNT];
+- for (int i = 0; i <= INARG_COUNT; i++) {
+- Class<?> src = (i == INARG_COUNT) ? dstType.returnType() : srcType.parameterType(i);
+- Class<?> dst = (i == INARG_COUNT) ? srcType.returnType() : dstType.parameterType(i);
+- if (!VerifyType.isNullConversion(src, dst) ||
+- level <= 1 && dst.isInterface() && !dst.isAssignableFrom(src)) {
+- needConv[i] = true;
+- conversions++;
++ private static int countNonNull(Object[] array) {
++ int count = 0;
++ for (Object x : array) {
++ if (x != null) ++count;
++ }
++ return count;
++ }
++
++ static MethodHandle makePairwiseConvertByEditor(MethodHandle target, MethodType srcType,
++ boolean strict, boolean monobox) {
++ Object[] convSpecs = computeValueConversions(srcType, target.type(), strict, monobox);
++ int convCount = countNonNull(convSpecs);
++ if (convCount == 0)
++ return target.viewAsType(srcType, strict);
++ MethodType basicSrcType = srcType.basicType();
++ MethodType midType = target.type().basicType();
++ BoundMethodHandle mh = target.rebind();
++ // FIXME: Reduce number of bindings when there is more than one Class conversion.
++ // FIXME: Reduce number of bindings when there are repeated conversions.
++ for (int i = 0; i < convSpecs.length-1; i++) {
++ Object convSpec = convSpecs[i];
++ if (convSpec == null) continue;
++ MethodHandle fn;
++ if (convSpec instanceof Class) {
++ fn = Lazy.MH_castReference.bindTo(convSpec);
++ } else {
++ fn = (MethodHandle) convSpec;
++ }
++ Class<?> newType = basicSrcType.parameterType(i);
++ if (--convCount == 0)
++ midType = srcType;
++ else
++ midType = midType.changeParameterType(i, newType);
++ LambdaForm form2 = mh.editor().filterArgumentForm(1+i, BasicType.basicType(newType));
++ mh = mh.copyWithExtendL(midType, form2, fn);
++ mh = mh.rebind();
++ }
++ Object convSpec = convSpecs[convSpecs.length-1];
++ if (convSpec != null) {
++ MethodHandle fn;
++ if (convSpec instanceof Class) {
++ if (convSpec == void.class)
++ fn = null;
++ else
++ fn = Lazy.MH_castReference.bindTo(convSpec);
++ } else {
++ fn = (MethodHandle) convSpec;
++ }
++ Class<?> newType = basicSrcType.returnType();
++ assert(--convCount == 0);
++ midType = srcType;
++ if (fn != null) {
++ mh = mh.rebind(); // rebind if too complex
++ LambdaForm form2 = mh.editor().filterReturnForm(BasicType.basicType(newType), false);
++ mh = mh.copyWithExtendL(midType, form2, fn);
++ } else {
++ LambdaForm form2 = mh.editor().filterReturnForm(BasicType.basicType(newType), true);
++ mh = mh.copyWith(midType, form2);
+ }
+ }
+- boolean retConv = needConv[INARG_COUNT];
++ assert(convCount == 0);
++ assert(mh.type().equals(srcType));
++ return mh;
++ }
++
++ static MethodHandle makePairwiseConvertIndirect(MethodHandle target, MethodType srcType,
++ boolean strict, boolean monobox) {
++ assert(target.type().parameterCount() == srcType.parameterCount());
++ // Calculate extra arguments (temporaries) required in the names array.
++ Object[] convSpecs = computeValueConversions(srcType, target.type(), strict, monobox);
++ final int INARG_COUNT = srcType.parameterCount();
++ int convCount = countNonNull(convSpecs);
++ boolean retConv = (convSpecs[INARG_COUNT] != null);
++ boolean retVoid = srcType.returnType() == void.class;
++ if (retConv && retVoid) {
++ convCount -= 1;
++ retConv = false;
++ }
+
+ final int IN_MH = 0;
+ final int INARG_BASE = 1;
+ final int INARG_LIMIT = INARG_BASE + INARG_COUNT;
+- final int NAME_LIMIT = INARG_LIMIT + conversions + 1;
++ final int NAME_LIMIT = INARG_LIMIT + convCount + 1;
+ final int RETURN_CONV = (!retConv ? -1 : NAME_LIMIT - 1);
+ final int OUT_CALL = (!retConv ? NAME_LIMIT : RETURN_CONV) - 1;
++ final int RESULT = (retVoid ? -1 : NAME_LIMIT - 1);
+
+ // Now build a LambdaForm.
+ MethodType lambdaType = srcType.basicType().invokerType();
+@@ -204,59 +291,21 @@
+
+ int nameCursor = INARG_LIMIT;
+ for (int i = 0; i < INARG_COUNT; i++) {
+- Class<?> src = srcType.parameterType(i);
+- Class<?> dst = dstType.parameterType(i);
+-
+- if (!needConv[i]) {
++ Object convSpec = convSpecs[i];
++ if (convSpec == null) {
+ // do nothing: difference is trivial
+ outArgs[OUTARG_BASE + i] = names[INARG_BASE + i];
+ continue;
+ }
+
+- // Tricky case analysis follows.
+- MethodHandle fn = null;
+- if (src.isPrimitive()) {
+- if (dst.isPrimitive()) {
+- fn = ValueConversions.convertPrimitive(src, dst);
+- } else {
+- Wrapper w = Wrapper.forPrimitiveType(src);
+- MethodHandle boxMethod = ValueConversions.box(w);
+- if (dst == w.wrapperType())
+- fn = boxMethod;
+- else
+- fn = boxMethod.asType(MethodType.methodType(dst, src));
+- }
++ Name conv;
++ if (convSpec instanceof Class) {
++ Class<?> convClass = (Class<?>) convSpec;
++ conv = new Name(Lazy.MH_castReference, convClass, names[INARG_BASE + i]);
+ } else {
+- if (dst.isPrimitive()) {
+- // Caller has boxed a primitive. Unbox it for the target.
+- Wrapper w = Wrapper.forPrimitiveType(dst);
+- if (level == 0 || VerifyType.isNullConversion(src, w.wrapperType())) {
+- fn = ValueConversions.unbox(dst);
+- } else if (src == Object.class || !Wrapper.isWrapperType(src)) {
+- // Examples: Object->int, Number->int, Comparable->int; Byte->int, Character->int
+- // must include additional conversions
+- // src must be examined at runtime, to detect Byte, Character, etc.
+- MethodHandle unboxMethod = (level == 1
+- ? ValueConversions.unbox(dst)
+- : ValueConversions.unboxCast(dst));
+- fn = unboxMethod;
+- } else {
+- // Example: Byte->int
+- // Do this by reformulating the problem to Byte->byte.
+- Class<?> srcPrim = Wrapper.forWrapperType(src).primitiveType();
+- MethodHandle unbox = ValueConversions.unbox(srcPrim);
+- // Compose the two conversions. FIXME: should make two Names for this job
+- fn = unbox.asType(MethodType.methodType(dst, src));
+- }
+- } else {
+- // Simple reference conversion.
+- // Note: Do not check for a class hierarchy relation
+- // between src and dst. In all cases a 'null' argument
+- // will pass the cast conversion.
+- fn = ValueConversions.cast(dst, Lazy.MH_castReference);
+- }
++ MethodHandle fn = (MethodHandle) convSpec;
++ conv = new Name(fn, names[INARG_BASE + i]);
+ }
+- Name conv = new Name(fn, names[INARG_BASE + i]);
+ assert(names[nameCursor] == null);
+ names[nameCursor++] = conv;
+ assert(outArgs[OUTARG_BASE + i] == null);
+@@ -267,29 +316,29 @@
+ assert(nameCursor == OUT_CALL);
+ names[OUT_CALL] = new Name(target, outArgs);
+
+- if (RETURN_CONV < 0) {
++ Object convSpec = convSpecs[INARG_COUNT];
++ if (!retConv) {
+ assert(OUT_CALL == names.length-1);
+ } else {
+- Class<?> needReturn = srcType.returnType();
+- Class<?> haveReturn = dstType.returnType();
+- MethodHandle fn;
+- Object[] arg = { names[OUT_CALL] };
+- if (haveReturn == void.class) {
+- // synthesize a zero value for the given void
+- Object zero = Wrapper.forBasicType(needReturn).zero();
+- fn = MethodHandles.constant(needReturn, zero);
+- arg = new Object[0]; // don't pass names[OUT_CALL] to conversion
++ Name conv;
++ if (convSpec == void.class) {
++ conv = new Name(LambdaForm.constantZero(BasicType.basicType(srcType.returnType())));
++ } else if (convSpec instanceof Class) {
++ Class<?> convClass = (Class<?>) convSpec;
++ conv = new Name(Lazy.MH_castReference, convClass, names[OUT_CALL]);
+ } else {
+- MethodHandle identity = MethodHandles.identity(needReturn);
+- MethodType needConversion = identity.type().changeParameterType(0, haveReturn);
+- fn = makePairwiseConvert(identity, needConversion, level);
++ MethodHandle fn = (MethodHandle) convSpec;
++ if (fn.type().parameterCount() == 0)
++ conv = new Name(fn); // don't pass retval to void conversion
++ else
++ conv = new Name(fn, names[OUT_CALL]);
+ }
+ assert(names[RETURN_CONV] == null);
+- names[RETURN_CONV] = new Name(fn, arg);
++ names[RETURN_CONV] = conv;
+ assert(RETURN_CONV == names.length-1);
+ }
+
+- LambdaForm form = new LambdaForm("convert", lambdaType.parameterCount(), names);
++ LambdaForm form = new LambdaForm("convert", lambdaType.parameterCount(), names, RESULT);
+ return SimpleMethodHandle.make(srcType, form);
+ }
+
+@@ -312,12 +361,79 @@
+ return new ClassCastException("Cannot cast " + obj.getClass().getName() + " to " + t.getName());
+ }
+
+- static MethodHandle makeReferenceIdentity(Class<?> refType) {
+- MethodType lambdaType = MethodType.genericMethodType(1).invokerType();
+- Name[] names = arguments(1, lambdaType);
+- names[names.length - 1] = new Name(ValueConversions.identity(), names[1]);
+- LambdaForm form = new LambdaForm("identity", lambdaType.parameterCount(), names);
+- return SimpleMethodHandle.make(MethodType.methodType(refType, refType), form);
++ static Object[] computeValueConversions(MethodType srcType, MethodType dstType,
++ boolean strict, boolean monobox) {
++ final int INARG_COUNT = srcType.parameterCount();
++ Object[] convSpecs = new Object[INARG_COUNT+1];
++ for (int i = 0; i <= INARG_COUNT; i++) {
++ boolean isRet = (i == INARG_COUNT);
++ Class<?> src = isRet ? dstType.returnType() : srcType.parameterType(i);
++ Class<?> dst = isRet ? srcType.returnType() : dstType.parameterType(i);
++ if (!VerifyType.isNullConversion(src, dst, /*keepInterfaces=*/ strict)) {
++ convSpecs[i] = valueConversion(src, dst, strict, monobox);
++ }
++ }
++ return convSpecs;
++ }
++ static MethodHandle makePairwiseConvert(MethodHandle target, MethodType srcType,
++ boolean strict) {
++ return makePairwiseConvert(target, srcType, strict, /*monobox=*/ false);
++ }
++
++ /**
++ * Find a conversion function from the given source to the given destination.
++ * This conversion function will be used as a LF NamedFunction.
++ * Return a Class object if a simple cast is needed.
++ * Return void.class if void is involved.
++ */
++ static Object valueConversion(Class<?> src, Class<?> dst, boolean strict, boolean monobox) {
++ assert(!VerifyType.isNullConversion(src, dst, /*keepInterfaces=*/ strict)); // caller responsibility
++ if (dst == void.class)
++ return dst;
++ MethodHandle fn;
++ if (src.isPrimitive()) {
++ if (src == void.class) {
++ return void.class; // caller must recognize this specially
++ } else if (dst.isPrimitive()) {
++ // Examples: int->byte, byte->int, boolean->int (!strict)
++ fn = ValueConversions.convertPrimitive(src, dst);
++ } else {
++ // Examples: int->Integer, boolean->Object, float->Number
++ Wrapper wsrc = Wrapper.forPrimitiveType(src);
++ fn = ValueConversions.boxExact(wsrc);
++ assert(fn.type().parameterType(0) == wsrc.primitiveType());
++ assert(fn.type().returnType() == wsrc.wrapperType());
++ if (!VerifyType.isNullConversion(wsrc.wrapperType(), dst, strict)) {
++ // Corner case, such as int->Long, which will probably fail.
++ MethodType mt = MethodType.methodType(dst, src);
++ if (strict)
++ fn = fn.asType(mt);
++ else
++ fn = MethodHandleImpl.makePairwiseConvert(fn, mt, /*strict=*/ false);
++ }
++ }
++ } else if (dst.isPrimitive()) {
++ Wrapper wdst = Wrapper.forPrimitiveType(dst);
++ if (monobox || src == wdst.wrapperType()) {
++ // Use a strongly-typed unboxer, if possible.
++ fn = ValueConversions.unboxExact(wdst, strict);
++ } else {
++ // Examples: Object->int, Number->int, Comparable->int, Byte->int
++ // must include additional conversions
++ // src must be examined at runtime, to detect Byte, Character, etc.
++ fn = (strict
++ ? ValueConversions.unboxWiden(wdst)
++ : ValueConversions.unboxCast(wdst));
++ }
++ } else {
++ // Simple reference conversion.
++ // Note: Do not check for a class hierarchy relation
++ // between src and dst. In all cases a 'null' argument
++ // will pass the cast conversion.
++ return dst;
++ }
++ assert(fn.type().parameterCount() <= 1) : "pc"+Arrays.asList(src.getSimpleName(), dst.getSimpleName(), fn);
++ return fn;
+ }
+
+ static MethodHandle makeVarargsCollector(MethodHandle target, Class<?> arrayType) {
+@@ -326,34 +442,46 @@
+ if (type.parameterType(last) != arrayType)
+ target = target.asType(type.changeParameterType(last, arrayType));
+ target = target.asFixedArity(); // make sure this attribute is turned off
+- return new AsVarargsCollector(target, target.type(), arrayType);
++ return new AsVarargsCollector(target, arrayType);
+ }
+
+- static class AsVarargsCollector extends MethodHandle {
++ private static final class AsVarargsCollector extends DelegatingMethodHandle {
+ private final MethodHandle target;
+ private final Class<?> arrayType;
+- private /*@Stable*/ MethodHandle asCollectorCache;
++ private @Stable MethodHandle asCollectorCache;
+
+- AsVarargsCollector(MethodHandle target, MethodType type, Class<?> arrayType) {
+- super(type, reinvokerForm(target));
++ AsVarargsCollector(MethodHandle target, Class<?> arrayType) {
++ this(target.type(), target, arrayType);
++ }
++ AsVarargsCollector(MethodType type, MethodHandle target, Class<?> arrayType) {
++ super(type, target);
+ this.target = target;
+ this.arrayType = arrayType;
+ this.asCollectorCache = target.asCollector(arrayType, 0);
+ }
+
+- @Override MethodHandle reinvokerTarget() { return target; }
+-
+ @Override
+ public boolean isVarargsCollector() {
+ return true;
+ }
+
+ @Override
++ protected MethodHandle getTarget() {
++ return target;
++ }
++
++ @Override
+ public MethodHandle asFixedArity() {
+ return target;
+ }
+
+ @Override
++ MethodHandle setVarargs(MemberName member) {
++ if (member.isVarargs()) return this;
++ return asFixedArity();
++ }
++
++ @Override
+ public MethodHandle asTypeUncached(MethodType newType) {
+ MethodType type = this.type();
+ int collectArg = type.parameterCount() - 1;
+@@ -381,54 +509,15 @@
+ }
+
+ @Override
+- MethodHandle setVarargs(MemberName member) {
+- if (member.isVarargs()) return this;
+- return asFixedArity();
+- }
+-
+- @Override
+- MethodHandle viewAsType(MethodType newType) {
+- if (newType.lastParameterType() != type().lastParameterType())
+- throw new InternalError();
+- MethodHandle newTarget = asFixedArity().viewAsType(newType);
+- // put back the varargs bit:
+- return new AsVarargsCollector(newTarget, newType, arrayType);
+- }
+-
+- @Override
+- MemberName internalMemberName() {
+- return asFixedArity().internalMemberName();
+- }
+- @Override
+- Class<?> internalCallerClass() {
+- return asFixedArity().internalCallerClass();
+- }
+-
+- /*non-public*/
+- @Override
+- boolean isInvokeSpecial() {
+- return asFixedArity().isInvokeSpecial();
+- }
+-
+-
+- @Override
+- MethodHandle bindArgument(int pos, char basicType, Object value) {
+- return asFixedArity().bindArgument(pos, basicType, value);
+- }
+-
+- @Override
+- MethodHandle bindReceiver(Object receiver) {
+- return asFixedArity().bindReceiver(receiver);
+- }
+-
+- @Override
+- MethodHandle dropArguments(MethodType srcType, int pos, int drops) {
+- return asFixedArity().dropArguments(srcType, pos, drops);
+- }
+-
+- @Override
+- MethodHandle permuteArguments(MethodType newType, int[] reorder) {
+- return asFixedArity().permuteArguments(newType, reorder);
++ boolean viewAsTypeChecks(MethodType newType, boolean strict) {
++ super.viewAsTypeChecks(newType, true);
++ if (strict) return true;
++ // extra assertion for non-strict checks:
++ assert (type().lastParameterType().getComponentType()
++ .isAssignableFrom(
++ newType.lastParameterType().getComponentType()))
++ : Arrays.asList(this, newType);
++ return true;
+ }
+ }
+
+@@ -499,32 +588,52 @@
+ * Pre-initialized NamedFunctions for bootstrapping purposes.
+ * Factored in an inner class to delay initialization until first usage.
+ */
+- private static class Lazy {
++ static class Lazy {
+ private static final Class<?> MHI = MethodHandleImpl.class;
+
++ private static final MethodHandle[] ARRAYS;
++ private static final MethodHandle[] FILL_ARRAYS;
++
+ static final NamedFunction NF_checkSpreadArgument;
+ static final NamedFunction NF_guardWithCatch;
+- static final NamedFunction NF_selectAlternative;
+ static final NamedFunction NF_throwException;
+
+ static final MethodHandle MH_castReference;
++ static final MethodHandle MH_selectAlternative;
++ static final MethodHandle MH_copyAsPrimitiveArray;
++ static final MethodHandle MH_fillNewTypedArray;
++ static final MethodHandle MH_fillNewArray;
++ static final MethodHandle MH_arrayIdentity;
+
+ static {
++ ARRAYS = makeArrays();
++ FILL_ARRAYS = makeFillArrays();
++
+ try {
+ NF_checkSpreadArgument = new NamedFunction(MHI.getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
+ NF_guardWithCatch = new NamedFunction(MHI.getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class,
+ MethodHandle.class, Object[].class));
+- NF_selectAlternative = new NamedFunction(MHI.getDeclaredMethod("selectAlternative", boolean.class, MethodHandle.class,
+- MethodHandle.class));
+ NF_throwException = new NamedFunction(MHI.getDeclaredMethod("throwException", Throwable.class));
+
+ NF_checkSpreadArgument.resolve();
+ NF_guardWithCatch.resolve();
+- NF_selectAlternative.resolve();
+ NF_throwException.resolve();
+
+- MethodType mt = MethodType.methodType(Object.class, Class.class, Object.class);
+- MH_castReference = IMPL_LOOKUP.findStatic(MHI, "castReference", mt);
++ MH_castReference = IMPL_LOOKUP.findStatic(MHI, "castReference",
++ MethodType.methodType(Object.class, Class.class, Object.class));
++ MH_copyAsPrimitiveArray = IMPL_LOOKUP.findStatic(MHI, "copyAsPrimitiveArray",
++ MethodType.methodType(Object.class, Wrapper.class, Object[].class));
++ MH_arrayIdentity = IMPL_LOOKUP.findStatic(MHI, "identity",
++ MethodType.methodType(Object[].class, Object[].class));
++ MH_fillNewArray = IMPL_LOOKUP.findStatic(MHI, "fillNewArray",
++ MethodType.methodType(Object[].class, Integer.class, Object[].class));
++ MH_fillNewTypedArray = IMPL_LOOKUP.findStatic(MHI, "fillNewTypedArray",
++ MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
++
++ MH_selectAlternative = makeIntrinsic(
++ IMPL_LOOKUP.findStatic(MHI, "selectAlternative",
++ MethodType.methodType(MethodHandle.class, boolean.class, MethodHandle.class, MethodHandle.class)),
++ Intrinsic.SELECT_ALTERNATIVE);
+ } catch (ReflectiveOperationException ex) {
+ throw newInternalError(ex);
+ }
+@@ -595,29 +704,190 @@
+ MethodHandle makeGuardWithTest(MethodHandle test,
+ MethodHandle target,
+ MethodHandle fallback) {
+- MethodType basicType = target.type().basicType();
+- MethodHandle invokeBasic = MethodHandles.basicInvoker(basicType);
+- int arity = basicType.parameterCount();
+- int extraNames = 3;
++ MethodType type = target.type();
++ assert(test.type().equals(type.changeReturnType(boolean.class)) && fallback.type().equals(type));
++ MethodType basicType = type.basicType();
++ LambdaForm form = makeGuardWithTestForm(basicType);
++ BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL();
++ BoundMethodHandle mh;
++
++ try {
++ mh = (BoundMethodHandle)
++ data.constructor().invokeBasic(type, form,
++ (Object) test, (Object) profile(target), (Object) profile(fallback));
++ } catch (Throwable ex) {
++ throw uncaughtException(ex);
++ }
++ assert(mh.type() == type);
++ return mh;
++ }
++
++
++ static
++ MethodHandle profile(MethodHandle target) {
++ if (DONT_INLINE_THRESHOLD >= 0) {
++ return makeBlockInlningWrapper(target);
++ } else {
++ return target;
++ }
++ }
++
++ /**
++ * Block inlining during JIT-compilation of a target method handle if it hasn't been invoked enough times.
++ * Corresponding LambdaForm has @DontInline when compiled into bytecode.
++ */
++ static
++ MethodHandle makeBlockInlningWrapper(MethodHandle target) {
++ LambdaForm lform = PRODUCE_BLOCK_INLINING_FORM.apply(target);
++ return new CountingWrapper(target, lform,
++ PRODUCE_BLOCK_INLINING_FORM, PRODUCE_REINVOKER_FORM,
++ DONT_INLINE_THRESHOLD);
++ }
++
++ /** Constructs reinvoker lambda form which block inlining during JIT-compilation for a particular method handle */
++ private static final Function<MethodHandle, LambdaForm> PRODUCE_BLOCK_INLINING_FORM = new Function<MethodHandle, LambdaForm>() {
++ @Override
++ public LambdaForm apply(MethodHandle target) {
++ return DelegatingMethodHandle.makeReinvokerForm(target,
++ MethodTypeForm.LF_DELEGATE_BLOCK_INLINING, CountingWrapper.class, "reinvoker.dontInline", false,
++ DelegatingMethodHandle.NF_getTarget, CountingWrapper.NF_maybeStopCounting);
++ }
++ };
++
++ /** Constructs simple reinvoker lambda form for a particular method handle */
++ private static final Function<MethodHandle, LambdaForm> PRODUCE_REINVOKER_FORM = new Function<MethodHandle, LambdaForm>() {
++ @Override
++ public LambdaForm apply(MethodHandle target) {
++ return DelegatingMethodHandle.makeReinvokerForm(target,
++ MethodTypeForm.LF_DELEGATE, DelegatingMethodHandle.class, DelegatingMethodHandle.NF_getTarget);
++ }
++ };
++
++ /**
++ * Counting method handle. It has 2 states: counting and non-counting.
++ * It is in counting state for the first n invocations and then transitions to non-counting state.
++ * Behavior in counting and non-counting states is determined by lambda forms produced by
++ * countingFormProducer & nonCountingFormProducer respectively.
++ */
++ static class CountingWrapper extends DelegatingMethodHandle {
++ private final MethodHandle target;
++ private int count;
++ private Function<MethodHandle, LambdaForm> countingFormProducer;
++ private Function<MethodHandle, LambdaForm> nonCountingFormProducer;
++ private volatile boolean isCounting;
++
++ private CountingWrapper(MethodHandle target, LambdaForm lform,
++ Function<MethodHandle, LambdaForm> countingFromProducer,
++ Function<MethodHandle, LambdaForm> nonCountingFormProducer,
++ int count) {
++ super(target.type(), lform);
++ this.target = target;
++ this.count = count;
++ this.countingFormProducer = countingFromProducer;
++ this.nonCountingFormProducer = nonCountingFormProducer;
++ this.isCounting = (count > 0);
++ }
++
++ @Hidden
++ @Override
++ protected MethodHandle getTarget() {
++ return target;
++ }
++
++ @Override
++ public MethodHandle asTypeUncached(MethodType newType) {
++ MethodHandle newTarget = target.asType(newType);
++ MethodHandle wrapper;
++ if (isCounting) {
++ LambdaForm lform;
++ lform = countingFormProducer.apply(target);
++ wrapper = new CountingWrapper(newTarget, lform, countingFormProducer, nonCountingFormProducer, DONT_INLINE_THRESHOLD);
++ } else {
++ wrapper = newTarget; // no need for a counting wrapper anymore
++ }
++ return (asTypeCache = wrapper);
++ }
++
++ boolean countDown() {
++ if (count <= 0) {
++ // Try to limit number of updates. MethodHandle.updateForm() doesn't guarantee LF update visibility.
++ if (isCounting) {
++ isCounting = false;
++ return true;
++ } else {
++ return false;
++ }
++ } else {
++ --count;
++ return false;
++ }
++ }
++
++ @Hidden
++ static void maybeStopCounting(Object o1) {
++ CountingWrapper wrapper = (CountingWrapper) o1;
++ if (wrapper.countDown()) {
++ // Reached invocation threshold. Replace counting behavior with a non-counting one.
++ LambdaForm lform = wrapper.nonCountingFormProducer.apply(wrapper.target);
++ lform.compileToBytecode(); // speed up warmup by avoiding LF interpretation again after transition
++ wrapper.updateForm(lform);
++ }
++ }
++
++ static final NamedFunction NF_maybeStopCounting;
++ static {
++ Class<?> THIS_CLASS = CountingWrapper.class;
++ try {
++ NF_maybeStopCounting = new NamedFunction(THIS_CLASS.getDeclaredMethod("maybeStopCounting", Object.class));
++ } catch (ReflectiveOperationException ex) {
++ throw newInternalError(ex);
++ }
++ }
++ }
++
++ static
++ LambdaForm makeGuardWithTestForm(MethodType basicType) {
++ LambdaForm lform = basicType.form().cachedLambdaForm(MethodTypeForm.LF_GWT);
++ if (lform != null) return lform;
++ final int THIS_MH = 0; // the BMH_LLL
++ final int ARG_BASE = 1; // start of incoming arguments
++ final int ARG_LIMIT = ARG_BASE + basicType.parameterCount();
++ int nameCursor = ARG_LIMIT;
++ final int GET_TEST = nameCursor++;
++ final int GET_TARGET = nameCursor++;
++ final int GET_FALLBACK = nameCursor++;
++ final int CALL_TEST = nameCursor++;
++ final int SELECT_ALT = nameCursor++;
++ final int CALL_TARGET = nameCursor++;
++ assert(CALL_TARGET == SELECT_ALT+1); // must be true to trigger IBG.emitSelectAlternative
++
+ MethodType lambdaType = basicType.invokerType();
+- Name[] names = arguments(extraNames, lambdaType);
++ Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
+
+- Object[] testArgs = Arrays.copyOfRange(names, 1, 1 + arity, Object[].class);
+- Object[] targetArgs = Arrays.copyOfRange(names, 0, 1 + arity, Object[].class);
++ BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL();
++ names[THIS_MH] = names[THIS_MH].withConstraint(data);
++ names[GET_TEST] = new Name(data.getterFunction(0), names[THIS_MH]);
++ names[GET_TARGET] = new Name(data.getterFunction(1), names[THIS_MH]);
++ names[GET_FALLBACK] = new Name(data.getterFunction(2), names[THIS_MH]);
++
++ Object[] invokeArgs = Arrays.copyOfRange(names, 0, ARG_LIMIT, Object[].class);
+
+ // call test
+- names[arity + 1] = new Name(test, testArgs);
++ MethodType testType = basicType.changeReturnType(boolean.class).basicType();
++ invokeArgs[0] = names[GET_TEST];
++ names[CALL_TEST] = new Name(testType, invokeArgs);
+
+ // call selectAlternative
+- Object[] selectArgs = { names[arity + 1], target, fallback };
+- names[arity + 2] = new Name(Lazy.NF_selectAlternative, selectArgs);
+- targetArgs[0] = names[arity + 2];
++ names[SELECT_ALT] = new Name(Lazy.MH_selectAlternative, names[CALL_TEST],
++ names[GET_TARGET], names[GET_FALLBACK]);
+
+ // call target or fallback
+- names[arity + 3] = new Name(new NamedFunction(invokeBasic), targetArgs);
++ invokeArgs[0] = names[SELECT_ALT];
++ names[CALL_TARGET] = new Name(basicType, invokeArgs);
+
+- LambdaForm form = new LambdaForm("guard", lambdaType.parameterCount(), names);
+- return SimpleMethodHandle.make(target.type(), form);
++ lform = new LambdaForm("guard", lambdaType.parameterCount(), names);
++
++ return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWT, lform);
+ }
+
+ /**
+@@ -665,6 +935,7 @@
+ Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType);
+
+ BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLL();
++ names[THIS_MH] = names[THIS_MH].withConstraint(data);
+ names[GET_TARGET] = new Name(data.getterFunction(0), names[THIS_MH]);
+ names[GET_CLASS] = new Name(data.getterFunction(1), names[THIS_MH]);
+ names[GET_CATCHER] = new Name(data.getterFunction(2), names[THIS_MH]);
+@@ -679,7 +950,7 @@
+ Object[] args = new Object[invokeBasic.type().parameterCount()];
+ args[0] = names[GET_COLLECT_ARGS];
+ System.arraycopy(names, ARG_BASE, args, 1, ARG_LIMIT-ARG_BASE);
+- names[BOXED_ARGS] = new Name(new NamedFunction(invokeBasic), args);
++ names[BOXED_ARGS] = new Name(makeIntrinsic(invokeBasic, Intrinsic.GUARD_WITH_CATCH), args);
+
+ // t_{i+1}:L=MethodHandleImpl.guardWithCatch(target:L,exType:L,catcher:L,t_{i}:L);
+ Object[] gwcArgs = new Object[] {names[GET_TARGET], names[GET_CLASS], names[GET_CATCHER], names[BOXED_ARGS]};
+@@ -688,7 +959,7 @@
+ // t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L);
+ MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
+ Object[] unboxArgs = new Object[] {names[GET_UNBOX_RESULT], names[TRY_CATCH]};
+- names[UNBOX_RESULT] = new Name(new NamedFunction(invokeBasicUnbox), unboxArgs);
++ names[UNBOX_RESULT] = new Name(invokeBasicUnbox, unboxArgs);
+
+ lform = new LambdaForm("guardWithCatch", lambdaType.parameterCount(), names);
+
+@@ -705,22 +976,27 @@
+ // Prepare auxiliary method handles used during LambdaForm interpreation.
+ // Box arguments and wrap them into Object[]: ValueConversions.array().
+ MethodType varargsType = type.changeReturnType(Object[].class);
+- MethodHandle collectArgs = ValueConversions.varargsArray(type.parameterCount())
+- .asType(varargsType);
++ MethodHandle collectArgs = varargsArray(type.parameterCount()).asType(varargsType);
+ // Result unboxing: ValueConversions.unbox() OR ValueConversions.identity() OR ValueConversions.ignore().
+ MethodHandle unboxResult;
+- if (type.returnType().isPrimitive()) {
+- unboxResult = ValueConversions.unbox(type.returnType());
++ Class<?> rtype = type.returnType();
++ if (rtype.isPrimitive()) {
++ if (rtype == void.class) {
++ unboxResult = ValueConversions.ignore();
++ } else {
++ Wrapper w = Wrapper.forPrimitiveType(type.returnType());
++ unboxResult = ValueConversions.unboxExact(w);
++ }
+ } else {
+- unboxResult = ValueConversions.identity();
++ unboxResult = MethodHandles.identity(Object.class);
+ }
+
+ BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLL();
+ BoundMethodHandle mh;
+ try {
+ mh = (BoundMethodHandle)
+- data.constructor[0].invokeBasic(type, form, (Object) target, (Object) exType, (Object) catcher,
+- (Object) collectArgs, (Object) unboxResult);
++ data.constructor().invokeBasic(type, form, (Object) target, (Object) exType, (Object) catcher,
++ (Object) collectArgs, (Object) unboxResult);
+ } catch (Throwable ex) {
+ throw uncaughtException(ex);
+ }
+@@ -758,9 +1034,11 @@
+ assert(Throwable.class.isAssignableFrom(type.parameterType(0)));
+ int arity = type.parameterCount();
+ if (arity > 1) {
+- return throwException(type.dropParameterTypes(1, arity)).dropArguments(type, 1, arity-1);
++ MethodHandle mh = throwException(type.dropParameterTypes(1, arity));
++ mh = MethodHandles.dropArguments(mh, 1, type.parameterList().subList(1, arity));
++ return mh;
+ }
+- return makePairwiseConvert(Lazy.NF_throwException.resolvedHandle(), type, 2);
++ return makePairwiseConvert(Lazy.NF_throwException.resolvedHandle(), type, false, true);
+ }
+
+ static <T extends Throwable> Empty throwException(T t) throws T { throw t; }
+@@ -782,7 +1060,7 @@
+ mh = mh.bindTo(new UnsupportedOperationException("cannot reflectively invoke MethodHandle"));
+ if (!method.getInvocationType().equals(mh.type()))
+ throw new InternalError(method.toString());
+- mh = mh.withInternalMemberName(method);
++ mh = mh.withInternalMemberName(method, false);
+ mh = mh.asVarargsCollector(Object[].class);
+ assert(method.isVarargs());
+ FAKE_METHOD_HANDLE_INVOKE[idx] = mh;
+@@ -819,7 +1097,7 @@
+ MethodHandle vamh = prepareForInvoker(mh);
+ // Cache the result of makeInjectedInvoker once per argument class.
+ MethodHandle bccInvoker = CV_makeInjectedInvoker.get(hostClass);
+- return restoreToType(bccInvoker.bindTo(vamh), mh.type(), mh.internalMemberName(), hostClass);
++ return restoreToType(bccInvoker.bindTo(vamh), mh, hostClass);
+ }
+
+ private static MethodHandle makeInjectedInvoker(Class<?> hostClass) {
+@@ -874,12 +1152,14 @@
+ }
+
+ // Undo the adapter effect of prepareForInvoker:
+- private static MethodHandle restoreToType(MethodHandle vamh, MethodType type,
+- MemberName member,
++ private static MethodHandle restoreToType(MethodHandle vamh,
++ MethodHandle original,
+ Class<?> hostClass) {
++ MethodType type = original.type();
+ MethodHandle mh = vamh.asCollector(Object[].class, type.parameterCount());
++ MemberName member = original.internalMemberName();
+ mh = mh.asType(type);
+- mh = new WrappedMember(mh, type, member, hostClass);
++ mh = new WrappedMember(mh, type, member, original.isInvokeSpecial(), hostClass);
+ return mh;
+ }
+
+@@ -945,29 +1225,23 @@
+
+
+ /** This subclass allows a wrapped method handle to be re-associated with an arbitrary member name. */
+- static class WrappedMember extends MethodHandle {
++ private static final class WrappedMember extends DelegatingMethodHandle {
+ private final MethodHandle target;
+ private final MemberName member;
+ private final Class<?> callerClass;
++ private final boolean isInvokeSpecial;
+
+- private WrappedMember(MethodHandle target, MethodType type, MemberName member, Class<?> callerClass) {
+- super(type, reinvokerForm(target));
++ private WrappedMember(MethodHandle target, MethodType type,
++ MemberName member, boolean isInvokeSpecial,
++ Class<?> callerClass) {
++ super(type, target);
+ this.target = target;
+ this.member = member;
+ this.callerClass = callerClass;
++ this.isInvokeSpecial = isInvokeSpecial;
+ }
+
+ @Override
+- MethodHandle reinvokerTarget() {
+- return target;
+- }
+- @Override
+- public MethodHandle asTypeUncached(MethodType newType) {
+- // This MH is an alias for target, except for the MemberName
+- // Drop the MemberName if there is any conversion.
+- return asTypeCache = target.asType(newType);
+- }
+- @Override
+ MemberName internalMemberName() {
+ return member;
+ }
+@@ -977,18 +1251,368 @@
+ }
+ @Override
+ boolean isInvokeSpecial() {
+- return target.isInvokeSpecial();
++ return isInvokeSpecial;
+ }
+ @Override
+- MethodHandle viewAsType(MethodType newType) {
+- return new WrappedMember(target, newType, member, callerClass);
++ protected MethodHandle getTarget() {
++ return target;
++ }
++ @Override
++ public MethodHandle asTypeUncached(MethodType newType) {
++ // This MH is an alias for target, except for the MemberName
++ // Drop the MemberName if there is any conversion.
++ return asTypeCache = target.asType(newType);
+ }
+ }
+
+- static MethodHandle makeWrappedMember(MethodHandle target, MemberName member) {
+- if (member.equals(target.internalMemberName()))
++ static MethodHandle makeWrappedMember(MethodHandle target, MemberName member, boolean isInvokeSpecial) {
++ if (member.equals(target.internalMemberName()) && isInvokeSpecial == target.isInvokeSpecial())
+ return target;
+- return new WrappedMember(target, target.type(), member, null);
++ return new WrappedMember(target, target.type(), member, isInvokeSpecial, null);
+ }
+
++ /** Intrinsic IDs */
++ /*non-public*/
++ enum Intrinsic {
++ SELECT_ALTERNATIVE,
++ GUARD_WITH_CATCH,
++ NEW_ARRAY,
++ ARRAY_LOAD,
++ ARRAY_STORE,
++ IDENTITY,
++ ZERO,
++ NONE // no intrinsic associated
++ }
++
++ /** Mark arbitrary method handle as intrinsic.
++ * InvokerBytecodeGenerator uses this info to produce more efficient bytecode shape. */
++ private static final class IntrinsicMethodHandle extends DelegatingMethodHandle {
++ private final MethodHandle target;
++ private final Intrinsic intrinsicName;
++
++ IntrinsicMethodHandle(MethodHandle target, Intrinsic intrinsicName) {
++ super(target.type(), target);
++ this.target = target;
++ this.intrinsicName = intrinsicName;
++ }
++
++ @Override
++ protected MethodHandle getTarget() {
++ return target;
++ }
++
++ @Override
++ Intrinsic intrinsicName() {
++ return intrinsicName;
++ }
++
++ @Override
++ public MethodHandle asTypeUncached(MethodType newType) {
++ // This MH is an alias for target, except for the intrinsic name
++ // Drop the name if there is any conversion.
++ return asTypeCache = target.asType(newType);
++ }
++
++ @Override
++ String internalProperties() {
++ return super.internalProperties() +
++ "\n& Intrinsic="+intrinsicName;
++ }
++
++ @Override
++ public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
++ if (intrinsicName == Intrinsic.IDENTITY) {
++ MethodType resultType = type().asCollectorType(arrayType, arrayLength);
++ MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
++ return newArray.asType(resultType);
++ }
++ return super.asCollector(arrayType, arrayLength);
++ }
++ }
++
++ static MethodHandle makeIntrinsic(MethodHandle target, Intrinsic intrinsicName) {
++ if (intrinsicName == target.intrinsicName())
++ return target;
++ return new IntrinsicMethodHandle(target, intrinsicName);
++ }
++
++ static MethodHandle makeIntrinsic(MethodType type, LambdaForm form, Intrinsic intrinsicName) {
++ return new IntrinsicMethodHandle(SimpleMethodHandle.make(type, form), intrinsicName);
++ }
++
++ /// Collection of multiple arguments.
++
++ private static MethodHandle findCollector(String name, int nargs, Class<?> rtype, Class<?>... ptypes) {
++ MethodType type = MethodType.genericMethodType(nargs)
++ .changeReturnType(rtype)
++ .insertParameterTypes(0, ptypes);
++ try {
++ return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, name, type);
++ } catch (ReflectiveOperationException ex) {
++ return null;
++ }
++ }
++
++ private static final Object[] NO_ARGS_ARRAY = {};
++ private static Object[] makeArray(Object... args) { return args; }
++ private static Object[] array() { return NO_ARGS_ARRAY; }
++ private static Object[] array(Object a0)
++ { return makeArray(a0); }
++ private static Object[] array(Object a0, Object a1)
++ { return makeArray(a0, a1); }
++ private static Object[] array(Object a0, Object a1, Object a2)
++ { return makeArray(a0, a1, a2); }
++ private static Object[] array(Object a0, Object a1, Object a2, Object a3)
++ { return makeArray(a0, a1, a2, a3); }
++ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
++ Object a4)
++ { return makeArray(a0, a1, a2, a3, a4); }
++ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
++ Object a4, Object a5)
++ { return makeArray(a0, a1, a2, a3, a4, a5); }
++ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
++ Object a4, Object a5, Object a6)
++ { return makeArray(a0, a1, a2, a3, a4, a5, a6); }
++ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
++ Object a4, Object a5, Object a6, Object a7)
++ { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); }
++ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
++ Object a4, Object a5, Object a6, Object a7,
++ Object a8)
++ { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
++ private static Object[] array(Object a0, Object a1, Object a2, Object a3,
++ Object a4, Object a5, Object a6, Object a7,
++ Object a8, Object a9)
++ { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
++ private static MethodHandle[] makeArrays() {
++ ArrayList<MethodHandle> mhs = new ArrayList<>();
++ for (;;) {
++ MethodHandle mh = findCollector("array", mhs.size(), Object[].class);
++ if (mh == null) break;
++ mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
++ mhs.add(mh);
++ }
++ assert(mhs.size() == 11); // current number of methods
++ return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
++ }
++
++ // filling versions of the above:
++ // using Integer len instead of int len and no varargs to avoid bootstrapping problems
++ private static Object[] fillNewArray(Integer len, Object[] /*not ...*/ args) {
++ Object[] a = new Object[len];
++ fillWithArguments(a, 0, args);
++ return a;
++ }
++ private static Object[] fillNewTypedArray(Object[] example, Integer len, Object[] /*not ...*/ args) {
++ Object[] a = Arrays.copyOf(example, len);
++ assert(a.getClass() != Object[].class);
++ fillWithArguments(a, 0, args);
++ return a;
++ }
++ private static void fillWithArguments(Object[] a, int pos, Object... args) {
++ System.arraycopy(args, 0, a, pos, args.length);
++ }
++ // using Integer pos instead of int pos to avoid bootstrapping problems
++ private static Object[] fillArray(Integer pos, Object[] a, Object a0)
++ { fillWithArguments(a, pos, a0); return a; }
++ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1)
++ { fillWithArguments(a, pos, a0, a1); return a; }
++ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2)
++ { fillWithArguments(a, pos, a0, a1, a2); return a; }
++ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3)
++ { fillWithArguments(a, pos, a0, a1, a2, a3); return a; }
++ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
++ Object a4)
++ { fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; }
++ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
++ Object a4, Object a5)
++ { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; }
++ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
++ Object a4, Object a5, Object a6)
++ { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; }
++ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
++ Object a4, Object a5, Object a6, Object a7)
++ { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; }
++ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
++ Object a4, Object a5, Object a6, Object a7,
++ Object a8)
++ { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
++ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
++ Object a4, Object a5, Object a6, Object a7,
++ Object a8, Object a9)
++ { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
++
++ private static final int FILL_ARRAYS_COUNT = 11; // current number of fillArray methods
++
++ private static MethodHandle[] makeFillArrays() {
++ ArrayList<MethodHandle> mhs = new ArrayList<>();
++ mhs.add(null); // there is no empty fill; at least a0 is required
++ for (;;) {
++ MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class);
++ if (mh == null) break;
++ mhs.add(mh);
++ }
++ assert(mhs.size() == FILL_ARRAYS_COUNT);
++ return mhs.toArray(new MethodHandle[0]);
++ }
++
++ private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {
++ Object a = w.makeArray(boxes.length);
++ w.copyArrayUnboxing(boxes, 0, a, 0, boxes.length);
++ return a;
++ }
++
++ /** Return a method handle that takes the indicated number of Object
++ * arguments and returns an Object array of them, as if for varargs.
++ */
++ static MethodHandle varargsArray(int nargs) {
++ MethodHandle mh = Lazy.ARRAYS[nargs];
++ if (mh != null) return mh;
++ mh = findCollector("array", nargs, Object[].class);
++ if (mh != null) mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
++ if (mh != null) return Lazy.ARRAYS[nargs] = mh;
++ mh = buildVarargsArray(Lazy.MH_fillNewArray, Lazy.MH_arrayIdentity, nargs);
++ assert(assertCorrectArity(mh, nargs));
++ mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
++ return Lazy.ARRAYS[nargs] = mh;
++ }
++
++ private static boolean assertCorrectArity(MethodHandle mh, int arity) {
++ assert(mh.type().parameterCount() == arity) : "arity != "+arity+": "+mh;
++ return true;
++ }
++
++ // Array identity function (used as Lazy.MH_arrayIdentity).
++ static <T> T[] identity(T[] x) {
++ return x;
++ }
++
++ private static MethodHandle buildVarargsArray(MethodHandle newArray, MethodHandle finisher, int nargs) {
++ // Build up the result mh as a sequence of fills like this:
++ // finisher(fill(fill(newArrayWA(23,x1..x10),10,x11..x20),20,x21..x23))
++ // The various fill(_,10*I,___*[J]) are reusable.
++ int leftLen = Math.min(nargs, LEFT_ARGS); // absorb some arguments immediately
++ int rightLen = nargs - leftLen;
++ MethodHandle leftCollector = newArray.bindTo(nargs);
++ leftCollector = leftCollector.asCollector(Object[].class, leftLen);
++ MethodHandle mh = finisher;
++ if (rightLen > 0) {
++ MethodHandle rightFiller = fillToRight(LEFT_ARGS + rightLen);
++ if (mh == Lazy.MH_arrayIdentity)
++ mh = rightFiller;
++ else
++ mh = MethodHandles.collectArguments(mh, 0, rightFiller);
++ }
++ if (mh == Lazy.MH_arrayIdentity)
++ mh = leftCollector;
++ else
++ mh = MethodHandles.collectArguments(mh, 0, leftCollector);
++ return mh;
++ }
++
++ private static final int LEFT_ARGS = FILL_ARRAYS_COUNT - 1;
++ private static final MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY+1];
++ /** fill_array_to_right(N).invoke(a, argL..arg[N-1])
++ * fills a[L]..a[N-1] with corresponding arguments,
++ * and then returns a. The value L is a global constant (LEFT_ARGS).
++ */
++ private static MethodHandle fillToRight(int nargs) {
++ MethodHandle filler = FILL_ARRAY_TO_RIGHT[nargs];
++ if (filler != null) return filler;
++ filler = buildFiller(nargs);
++ assert(assertCorrectArity(filler, nargs - LEFT_ARGS + 1));
++ return FILL_ARRAY_TO_RIGHT[nargs] = filler;
++ }
++ private static MethodHandle buildFiller(int nargs) {
++ if (nargs <= LEFT_ARGS)
++ return Lazy.MH_arrayIdentity; // no args to fill; return the array unchanged
++ // we need room for both mh and a in mh.invoke(a, arg*[nargs])
++ final int CHUNK = LEFT_ARGS;
++ int rightLen = nargs % CHUNK;
++ int midLen = nargs - rightLen;
++ if (rightLen == 0) {
++ midLen = nargs - (rightLen = CHUNK);
++ if (FILL_ARRAY_TO_RIGHT[midLen] == null) {
++ // build some precursors from left to right
++ for (int j = LEFT_ARGS % CHUNK; j < midLen; j += CHUNK)
++ if (j > LEFT_ARGS) fillToRight(j);
++ }
++ }
++ if (midLen < LEFT_ARGS) rightLen = nargs - (midLen = LEFT_ARGS);
++ assert(rightLen > 0);
++ MethodHandle midFill = fillToRight(midLen); // recursive fill
++ MethodHandle rightFill = Lazy.FILL_ARRAYS[rightLen].bindTo(midLen); // [midLen..nargs-1]
++ assert(midFill.type().parameterCount() == 1 + midLen - LEFT_ARGS);
++ assert(rightFill.type().parameterCount() == 1 + rightLen);
++
++ // Combine the two fills:
++ // right(mid(a, x10..x19), x20..x23)
++ // The final product will look like this:
++ // right(mid(newArrayLeft(24, x0..x9), x10..x19), x20..x23)
++ if (midLen == LEFT_ARGS)
++ return rightFill;
++ else
++ return MethodHandles.collectArguments(rightFill, 0, midFill);
++ }
++
++ // Type-polymorphic version of varargs maker.
++ private static final ClassValue<MethodHandle[]> TYPED_COLLECTORS
++ = new ClassValue<MethodHandle[]>() {
++ @Override
++ protected MethodHandle[] computeValue(Class<?> type) {
++ return new MethodHandle[256];
++ }
++ };
++
++ static final int MAX_JVM_ARITY = 255; // limit imposed by the JVM
++
++ /** Return a method handle that takes the indicated number of
++ * typed arguments and returns an array of them.
++ * The type argument is the array type.
++ */
++ static MethodHandle varargsArray(Class<?> arrayType, int nargs) {
++ Class<?> elemType = arrayType.getComponentType();
++ if (elemType == null) throw new IllegalArgumentException("not an array: "+arrayType);
++ // FIXME: Need more special casing and caching here.
++ if (nargs >= MAX_JVM_ARITY/2 - 1) {
++ int slots = nargs;
++ final int MAX_ARRAY_SLOTS = MAX_JVM_ARITY - 1; // 1 for receiver MH
++ if (slots <= MAX_ARRAY_SLOTS && elemType.isPrimitive())
++ slots *= Wrapper.forPrimitiveType(elemType).stackSlots();
++ if (slots > MAX_ARRAY_SLOTS)
++ throw new IllegalArgumentException("too many arguments: "+arrayType.getSimpleName()+", length "+nargs);
++ }
++ if (elemType == Object.class)
++ return varargsArray(nargs);
++ // other cases: primitive arrays, subtypes of Object[]
++ MethodHandle cache[] = TYPED_COLLECTORS.get(elemType);
++ MethodHandle mh = nargs < cache.length ? cache[nargs] : null;
++ if (mh != null) return mh;
++ if (nargs == 0) {
++ Object example = java.lang.reflect.Array.newInstance(arrayType.getComponentType(), 0);
++ mh = MethodHandles.constant(arrayType, example);
++ } else if (elemType.isPrimitive()) {
++ MethodHandle builder = Lazy.MH_fillNewArray;
++ MethodHandle producer = buildArrayProducer(arrayType);
++ mh = buildVarargsArray(builder, producer, nargs);
++ } else {
++ Class<? extends Object[]> objArrayType = arrayType.asSubclass(Object[].class);
++ Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType);
++ MethodHandle builder = Lazy.MH_fillNewTypedArray.bindTo(example);
++ MethodHandle producer = Lazy.MH_arrayIdentity; // must be weakly typed
++ mh = buildVarargsArray(builder, producer, nargs);
++ }
++ mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
++ mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
++ assert(assertCorrectArity(mh, nargs));
++ if (nargs < cache.length)
++ cache[nargs] = mh;
++ return mh;
++ }
++
++ private static MethodHandle buildArrayProducer(Class<?> arrayType) {
++ Class<?> elemType = arrayType.getComponentType();
++ assert(elemType.isPrimitive());
++ return Lazy.MH_copyAsPrimitiveArray.bindTo(Wrapper.forPrimitiveType(elemType));
++ }
+ }
+--- ./jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Wed Feb 04 12:14:43 2015 -0800
+@@ -78,7 +78,7 @@
+
+ // The JVM calls MethodHandleNatives.<clinit>. Cascade the <clinit> calls as needed:
+ MethodHandleImpl.initStatics();
+-}
++ }
+
+ // All compile-time constants go here.
+ // There is an opportunity to check them against the JVM's idea of them.
+@@ -293,6 +293,17 @@
+ Class<?> caller = (Class<?>)callerObj;
+ String name = nameObj.toString().intern();
+ MethodType type = (MethodType)typeObj;
++ if (!TRACE_METHOD_LINKAGE)
++ return linkCallSiteImpl(caller, bootstrapMethod, name, type,
++ staticArguments, appendixResult);
++ return linkCallSiteTracing(caller, bootstrapMethod, name, type,
++ staticArguments, appendixResult);
++ }
++ static MemberName linkCallSiteImpl(Class<?> caller,
++ MethodHandle bootstrapMethod,
++ String name, MethodType type,
++ Object staticArguments,
++ Object[] appendixResult) {
+ CallSite callSite = CallSite.makeSite(bootstrapMethod,
+ name,
+ type,
+@@ -306,6 +317,30 @@
+ return Invokers.linkToCallSiteMethod(type);
+ }
+ }
++ // Tracing logic:
++ static MemberName linkCallSiteTracing(Class<?> caller,
++ MethodHandle bootstrapMethod,
++ String name, MethodType type,
++ Object staticArguments,
++ Object[] appendixResult) {
++ Object bsmReference = bootstrapMethod.internalMemberName();
++ if (bsmReference == null) bsmReference = bootstrapMethod;
++ Object staticArglist = (staticArguments instanceof Object[] ?
++ java.util.Arrays.asList((Object[]) staticArguments) :
++ staticArguments);
++ System.out.println("linkCallSite "+caller.getName()+" "+
++ bsmReference+" "+
++ name+type+"/"+staticArglist);
++ try {
++ MemberName res = linkCallSiteImpl(caller, bootstrapMethod, name, type,
++ staticArguments, appendixResult);
++ System.out.println("linkCallSite => "+res+" + "+appendixResult[0]);
++ return res;
++ } catch (Throwable ex) {
++ System.out.println("linkCallSite => throw "+ex);
++ throw ex;
++ }
++ }
+
+ /**
+ * The JVM wants a pointer to a MethodType. Oblige it by finding or creating one.
+--- ./jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java Wed Feb 04 12:14:43 2015 -0800
+@@ -33,6 +33,7 @@
+ import sun.reflect.CallerSensitive;
+ import sun.reflect.Reflection;
+ import sun.reflect.misc.ReflectUtil;
++import static java.lang.invoke.MethodHandleStatics.*;
+
+ /**
+ * This class consists exclusively of static methods that help adapt
+@@ -148,7 +149,7 @@
+ public static
+ <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
+ if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
+- throw new IllegalArgumentException("not a public interface: "+intfc.getName());
++ throw newIllegalArgumentException("not a public interface", intfc.getName());
+ final MethodHandle mh;
+ if (System.getSecurityManager() != null) {
+ final Class<?> caller = Reflection.getCallerClass();
+@@ -165,7 +166,7 @@
+ }
+ final Method[] methods = getSingleNameMethods(intfc);
+ if (methods == null)
+- throw new IllegalArgumentException("not a single-method interface: "+intfc.getName());
++ throw newIllegalArgumentException("not a single-method interface", intfc.getName());
+ final MethodHandle[] vaTargets = new MethodHandle[methods.length];
+ for (int i = 0; i < methods.length; i++) {
+ Method sm = methods[i];
+@@ -189,7 +190,7 @@
+ return getArg(method.getName());
+ if (isObjectMethod(method))
+ return callObjectMethod(proxy, method, args);
+- throw new InternalError("bad proxy method: "+method);
++ throw newInternalError("bad proxy method: "+method);
+ }
+ };
+
+@@ -240,7 +241,7 @@
+ return (WrapperInstance) x;
+ } catch (ClassCastException ex) {
+ }
+- throw new IllegalArgumentException("not a wrapper instance");
++ throw newIllegalArgumentException("not a wrapper instance");
+ }
+
+ /**
+--- ./jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java Wed Feb 04 12:14:43 2015 -0800
+@@ -45,16 +45,21 @@
+ static final boolean DUMP_CLASS_FILES;
+ static final boolean TRACE_INTERPRETER;
+ static final boolean TRACE_METHOD_LINKAGE;
+- static final Integer COMPILE_THRESHOLD;
++ static final int COMPILE_THRESHOLD;
++ static final int DONT_INLINE_THRESHOLD;
++ static final int PROFILE_LEVEL;
++
+ static {
+- final Object[] values = { false, false, false, false, null };
++ final Object[] values = new Object[7];
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES");
+ values[1] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DUMP_CLASS_FILES");
+ values[2] = Boolean.getBoolean("java.lang.invoke.MethodHandle.TRACE_INTERPRETER");
+ values[3] = Boolean.getBoolean("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE");
+- values[4] = Integer.getInteger("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD");
++ values[4] = Integer.getInteger("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", 0);
++ values[5] = Integer.getInteger("java.lang.invoke.MethodHandle.DONT_INLINE_THRESHOLD", 30);
++ values[6] = Integer.getInteger("java.lang.invoke.MethodHandle.PROFILE_LEVEL", 0);
+ return null;
+ }
+ });
+@@ -63,6 +68,18 @@
+ TRACE_INTERPRETER = (Boolean) values[2];
+ TRACE_METHOD_LINKAGE = (Boolean) values[3];
+ COMPILE_THRESHOLD = (Integer) values[4];
++ DONT_INLINE_THRESHOLD = (Integer) values[5];
++ PROFILE_LEVEL = (Integer) values[6];
++ }
++
++ /** Tell if any of the debugging switches are turned on.
++ * If this is the case, it is reasonable to perform extra checks or save extra information.
++ */
++ /*non-public*/ static boolean debugEnabled() {
++ return (DEBUG_METHOD_HANDLE_NAMES |
++ DUMP_CLASS_FILES |
++ TRACE_INTERPRETER |
++ TRACE_METHOD_LINKAGE);
+ }
+
+ /*non-public*/ static String getNameString(MethodHandle target, MethodType type) {
+@@ -93,6 +110,9 @@
+ }
+
+ // handy shared exception makers (they simplify the common case code)
++ /*non-public*/ static InternalError newInternalError(String message) {
++ return new InternalError(message);
++ }
+ /*non-public*/ static InternalError newInternalError(String message, Throwable cause) {
+ return new InternalError(message, cause);
+ }
+@@ -114,7 +134,10 @@
+ /*non-public*/ static RuntimeException newIllegalArgumentException(String message, Object obj, Object obj2) {
+ return new IllegalArgumentException(message(message, obj, obj2));
+ }
++ /** Propagate unchecked exceptions and errors, but wrap anything checked and throw that instead. */
+ /*non-public*/ static Error uncaughtException(Throwable ex) {
++ if (ex instanceof Error) throw (Error) ex;
++ if (ex instanceof RuntimeException) throw (RuntimeException) ex;
+ throw newInternalError("uncaught exception", ex);
+ }
+ static Error NYI() {
+--- ./jdk/src/share/classes/java/lang/invoke/MethodHandles.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/MethodHandles.java Wed Feb 04 12:14:43 2015 -0800
+@@ -26,8 +26,8 @@
+ package java.lang.invoke;
+
+ import java.lang.reflect.*;
++import java.util.BitSet;
+ import java.util.List;
+-import java.util.ArrayList;
+ import java.util.Arrays;
+
+ import sun.invoke.util.ValueConversions;
+@@ -37,13 +37,14 @@
+ import sun.reflect.Reflection;
+ import sun.reflect.misc.ReflectUtil;
+ import sun.security.util.SecurityConstants;
++import java.lang.invoke.LambdaForm.BasicType;
++import static java.lang.invoke.LambdaForm.BasicType.*;
+ import static java.lang.invoke.MethodHandleStatics.*;
++import static java.lang.invoke.MethodHandleImpl.Intrinsic;
+ import static java.lang.invoke.MethodHandleNatives.Constants.*;
+
+ import java.util.concurrent.ConcurrentHashMap;
+
+-import sun.security.util.SecurityConstants;
+-
+ /**
+ * This class consists exclusively of static methods that operate on or return
+ * method handles. They fall into several categories:
+@@ -863,6 +864,8 @@
+ return invoker(type);
+ if ("invokeExact".equals(name))
+ return exactInvoker(type);
++ if ("invokeBasic".equals(name))
++ return basicInvoker(type);
+ assert(!MemberName.isMethodHandleInvokeName(name));
+ return null;
+ }
+@@ -1142,7 +1145,7 @@
+ Class<? extends Object> refc = receiver.getClass(); // may get NPE
+ MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
+ MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
+- return mh.bindReceiver(receiver).setVarargs(method);
++ return mh.bindArgumentL(0, receiver).setVarargs(method);
+ }
+
+ /**
+@@ -1577,7 +1580,7 @@
+ return false;
+ return true;
+ }
+- private MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class<?> caller) throws IllegalAccessException {
++ private MethodHandle restrictReceiver(MemberName method, DirectMethodHandle mh, Class<?> caller) throws IllegalAccessException {
+ assert(!method.isStatic());
+ // receiver type of mh is too wide; narrow to caller
+ if (!method.getDeclaringClass().isAssignableFrom(caller)) {
+@@ -1586,7 +1589,9 @@
+ MethodType rawType = mh.type();
+ if (rawType.parameterType(0) == caller) return mh;
+ MethodType narrowType = rawType.changeParameterType(0, caller);
+- return mh.viewAsType(narrowType);
++ assert(!mh.isVarargsCollector()); // viewAsType will lose varargs-ness
++ assert(mh.viewAsTypeChecks(narrowType, true));
++ return mh.copyWith(narrowType, mh.form);
+ }
+
+ /** Check access and get the requested method. */
+@@ -1648,15 +1653,17 @@
+ checkMethod(refKind, refc, method);
+ }
+
+- MethodHandle mh = DirectMethodHandle.make(refKind, refc, method);
+- mh = maybeBindCaller(method, mh, callerClass);
+- mh = mh.setVarargs(method);
++ DirectMethodHandle dmh = DirectMethodHandle.make(refKind, refc, method);
++ MethodHandle mh = dmh;
+ // Optionally narrow the receiver argument to refc using restrictReceiver.
+ if (doRestrict &&
+ (refKind == REF_invokeSpecial ||
+ (MethodHandleNatives.refKindHasReceiver(refKind) &&
+- restrictProtectedReceiver(method))))
+- mh = restrictReceiver(method, mh, lookupClass());
++ restrictProtectedReceiver(method)))) {
++ mh = restrictReceiver(method, dmh, lookupClass());
++ }
++ mh = maybeBindCaller(method, mh, callerClass);
++ mh = mh.setVarargs(method);
+ return mh;
+ }
+ private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh,
+@@ -1688,12 +1695,12 @@
+ // Optionally check with the security manager; this isn't needed for unreflect* calls.
+ if (checkSecurity)
+ checkSecurityManager(refc, field);
+- MethodHandle mh = DirectMethodHandle.make(refc, field);
++ DirectMethodHandle dmh = DirectMethodHandle.make(refc, field);
+ boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(refKind) &&
+ restrictProtectedReceiver(field));
+ if (doRestrict)
+- mh = restrictReceiver(field, mh, lookupClass());
+- return mh;
++ return restrictReceiver(field, dmh, lookupClass());
++ return dmh;
+ }
+ /** Check access and get the requested constructor. */
+ private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
+@@ -1880,7 +1887,8 @@
+ static public
+ MethodHandle spreadInvoker(MethodType type, int leadingArgCount) {
+ if (leadingArgCount < 0 || leadingArgCount > type.parameterCount())
+- throw new IllegalArgumentException("bad argument count "+leadingArgCount);
++ throw newIllegalArgumentException("bad argument count", leadingArgCount);
++ type = type.asSpreaderType(Object[].class, type.parameterCount() - leadingArgCount);
+ return type.invokers().spreadInvoker(leadingArgCount);
+ }
+
+@@ -1960,12 +1968,12 @@
+ */
+ static public
+ MethodHandle invoker(MethodType type) {
+- return type.invokers().generalInvoker();
++ return type.invokers().genericInvoker();
+ }
+
+ static /*non-public*/
+ MethodHandle basicInvoker(MethodType type) {
+- return type.form().basicInvoker();
++ return type.invokers().basicInvoker();
+ }
+
+ /// method handle modification (creation from other method handles)
+@@ -2016,10 +2024,20 @@
+ */
+ public static
+ MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) {
+- if (!target.type().isCastableTo(newType)) {
+- throw new WrongMethodTypeException("cannot explicitly cast "+target+" to "+newType);
++ explicitCastArgumentsChecks(target, newType);
++ // use the asTypeCache when possible:
++ MethodType oldType = target.type();
++ if (oldType == newType) return target;
++ if (oldType.explicitCastEquivalentToAsType(newType)) {
++ return target.asFixedArity().asType(newType);
+ }
+- return MethodHandleImpl.makePairwiseConvert(target, newType, 2);
++ return MethodHandleImpl.makePairwiseConvert(target, newType, false);
++ }
++
++ private static void explicitCastArgumentsChecks(MethodHandle target, MethodType newType) {
++ if (target.type().parameterCount() != newType.parameterCount()) {
++ throw new WrongMethodTypeException("cannot explicitly cast " + target + " to " + newType);
++ }
+ }
+
+ /**
+@@ -2083,12 +2101,127 @@
+ */
+ public static
+ MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
+- reorder = reorder.clone();
+- checkReorder(reorder, newType, target.type());
+- return target.permuteArguments(newType, reorder);
++ reorder = reorder.clone(); // get a private copy
++ MethodType oldType = target.type();
++ permuteArgumentChecks(reorder, newType, oldType);
++ // first detect dropped arguments and handle them separately
++ int[] originalReorder = reorder;
++ BoundMethodHandle result = target.rebind();
++ LambdaForm form = result.form;
++ int newArity = newType.parameterCount();
++ // Normalize the reordering into a real permutation,
++ // by removing duplicates and adding dropped elements.
++ // This somewhat improves lambda form caching, as well
++ // as simplifying the transform by breaking it up into steps.
++ for (int ddIdx; (ddIdx = findFirstDupOrDrop(reorder, newArity)) != 0; ) {
++ if (ddIdx > 0) {
++ // We found a duplicated entry at reorder[ddIdx].
++ // Example: (x,y,z)->asList(x,y,z)
++ // permuted by [1*,0,1] => (a0,a1)=>asList(a1,a0,a1)
++ // permuted by [0,1,0*] => (a0,a1)=>asList(a0,a1,a0)
++ // The starred element corresponds to the argument
++ // deleted by the dupArgumentForm transform.
++ int srcPos = ddIdx, dstPos = srcPos, dupVal = reorder[srcPos];
++ boolean killFirst = false;
++ for (int val; (val = reorder[--dstPos]) != dupVal; ) {
++ // Set killFirst if the dup is larger than an intervening position.
++ // This will remove at least one inversion from the permutation.
++ if (dupVal > val) killFirst = true;
++ }
++ if (!killFirst) {
++ srcPos = dstPos;
++ dstPos = ddIdx;
++ }
++ form = form.editor().dupArgumentForm(1 + srcPos, 1 + dstPos);
++ assert (reorder[srcPos] == reorder[dstPos]);
++ oldType = oldType.dropParameterTypes(dstPos, dstPos + 1);
++ // contract the reordering by removing the element at dstPos
++ int tailPos = dstPos + 1;
++ System.arraycopy(reorder, tailPos, reorder, dstPos, reorder.length - tailPos);
++ reorder = Arrays.copyOf(reorder, reorder.length - 1);
++ } else {
++ int dropVal = ~ddIdx, insPos = 0;
++ while (insPos < reorder.length && reorder[insPos] < dropVal) {
++ // Find first element of reorder larger than dropVal.
++ // This is where we will insert the dropVal.
++ insPos += 1;
++ }
++ Class<?> ptype = newType.parameterType(dropVal);
++ form = form.editor().addArgumentForm(1 + insPos, BasicType.basicType(ptype));
++ oldType = oldType.insertParameterTypes(insPos, ptype);
++ // expand the reordering by inserting an element at insPos
++ int tailPos = insPos + 1;
++ reorder = Arrays.copyOf(reorder, reorder.length + 1);
++ System.arraycopy(reorder, insPos, reorder, tailPos, reorder.length - tailPos);
++ reorder[insPos] = dropVal;
++ }
++ assert (permuteArgumentChecks(reorder, newType, oldType));
++ }
++ assert (reorder.length == newArity); // a perfect permutation
++ // Note: This may cache too many distinct LFs. Consider backing off to varargs code.
++ form = form.editor().permuteArgumentsForm(1, reorder);
++ if (newType == result.type() && form == result.internalForm())
++ return result;
++ return result.copyWith(newType, form);
+ }
+
+- private static void checkReorder(int[] reorder, MethodType newType, MethodType oldType) {
++ /**
++ * Return an indication of any duplicate or omission in reorder.
++ * If the reorder contains a duplicate entry, return the index of the second occurrence.
++ * Otherwise, return ~(n), for the first n in [0..newArity-1] that is not present in reorder.
++ * Otherwise, return zero.
++ * If an element not in [0..newArity-1] is encountered, return reorder.length.
++ */
++ private static int findFirstDupOrDrop(int[] reorder, int newArity) {
++ final int BIT_LIMIT = 63; // max number of bits in bit mask
++ if (newArity < BIT_LIMIT) {
++ long mask = 0;
++ for (int i = 0; i < reorder.length; i++) {
++ int arg = reorder[i];
++ if (arg >= newArity) {
++ return reorder.length;
++ }
++ long bit = 1L << arg;
++ if ((mask & bit) != 0) {
++ return i; // >0 indicates a dup
++ }
++ mask |= bit;
++ }
++ if (mask == (1L << newArity) - 1) {
++ assert(Long.numberOfTrailingZeros(Long.lowestOneBit(~mask)) == newArity);
++ return 0;
++ }
++ // find first zero
++ long zeroBit = Long.lowestOneBit(~mask);
++ int zeroPos = Long.numberOfTrailingZeros(zeroBit);
++ assert(zeroPos <= newArity);
++ if (zeroPos == newArity) {
++ return 0;
++ }
++ return ~zeroPos;
++ } else {
++ // same algorithm, different bit set
++ BitSet mask = new BitSet(newArity);
++ for (int i = 0; i < reorder.length; i++) {
++ int arg = reorder[i];
++ if (arg >= newArity) {
++ return reorder.length;
++ }
++ if (mask.get(arg)) {
++ return i; // >0 indicates a dup
++ }
++ mask.set(arg);
++ }
++ int zeroPos = mask.nextClearBit(0);
++ assert(zeroPos <= newArity);
++ if (zeroPos == newArity) {
++ return 0;
++ }
++ return ~zeroPos;
++ }
++ }
++
++ private static boolean permuteArgumentChecks(int[] reorder, MethodType newType, MethodType oldType) {
+ if (newType.returnType() != oldType.returnType())
+ throw newIllegalArgumentException("return types do not match",
+ oldType, newType);
+@@ -2106,7 +2239,7 @@
+ throw newIllegalArgumentException("parameter types do not match after reorder",
+ oldType, newType);
+ }
+- if (!bad) return;
++ if (!bad) return true;
+ }
+ throw newIllegalArgumentException("bad reorder array: "+Arrays.toString(reorder));
+ }
+@@ -2132,9 +2265,14 @@
+ if (type == void.class)
+ throw newIllegalArgumentException("void type");
+ Wrapper w = Wrapper.forPrimitiveType(type);
+- return insertArguments(identity(type), 0, w.convert(value, type));
++ value = w.convert(value, type);
++ if (w.zero().equals(value))
++ return zero(w, type);
++ return insertArguments(identity(type), 0, value);
+ } else {
+- return identity(type).bindTo(type.cast(value));
++ if (value == null)
++ return zero(Wrapper.OBJECT, type);
++ return identity(type).bindTo(value);
+ }
+ }
+
+@@ -2147,14 +2285,48 @@
+ */
+ public static
+ MethodHandle identity(Class<?> type) {
+- if (type == void.class)
+- throw newIllegalArgumentException("void type");
+- else if (type == Object.class)
+- return ValueConversions.identity();
+- else if (type.isPrimitive())
+- return ValueConversions.identity(Wrapper.forPrimitiveType(type));
+- else
+- return MethodHandleImpl.makeReferenceIdentity(type);
++ Wrapper btw = (type.isPrimitive() ? Wrapper.forPrimitiveType(type) : Wrapper.OBJECT);
++ int pos = btw.ordinal();
++ MethodHandle ident = IDENTITY_MHS[pos];
++ if (ident == null) {
++ ident = setCachedMethodHandle(IDENTITY_MHS, pos, makeIdentity(btw.primitiveType()));
++ }
++ if (ident.type().returnType() == type)
++ return ident;
++ // something like identity(Foo.class); do not bother to intern these
++ assert(btw == Wrapper.OBJECT);
++ return makeIdentity(type);
++ }
++ private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.values().length];
++ private static MethodHandle makeIdentity(Class<?> ptype) {
++ MethodType mtype = MethodType.methodType(ptype, ptype);
++ LambdaForm lform = LambdaForm.identityForm(BasicType.basicType(ptype));
++ return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.IDENTITY);
++ }
++
++ private static MethodHandle zero(Wrapper btw, Class<?> rtype) {
++ int pos = btw.ordinal();
++ MethodHandle zero = ZERO_MHS[pos];
++ if (zero == null) {
++ zero = setCachedMethodHandle(ZERO_MHS, pos, makeZero(btw.primitiveType()));
++ }
++ if (zero.type().returnType() == rtype)
++ return zero;
++ assert(btw == Wrapper.OBJECT);
++ return makeZero(rtype);
++ }
++ private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.values().length];
++ private static MethodHandle makeZero(Class<?> rtype) {
++ MethodType mtype = MethodType.methodType(rtype);
++ LambdaForm lform = LambdaForm.zeroForm(BasicType.basicType(rtype));
++ return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.ZERO);
++ }
++
++ synchronized private static MethodHandle setCachedMethodHandle(MethodHandle[] cache, int pos, MethodHandle value) {
++ // Simulate a CAS, to avoid racy duplication of results.
++ MethodHandle prev = cache[pos];
++ if (prev != null) return prev;
++ return cache[pos] = value;
+ }
+
+ /**
+@@ -2190,6 +2362,37 @@
+ public static
+ MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
+ int insCount = values.length;
++ Class<?>[] ptypes = insertArgumentsChecks(target, insCount, pos);
++ if (insCount == 0) return target;
++ BoundMethodHandle result = target.rebind();
++ for (int i = 0; i < insCount; i++) {
++ Object value = values[i];
++ Class<?> ptype = ptypes[pos+i];
++ if (ptype.isPrimitive()) {
++ result = insertArgumentPrimitive(result, pos, ptype, value);
++ } else {
++ value = ptype.cast(value); // throw CCE if needed
++ result = result.bindArgumentL(pos, value);
++ }
++ }
++ return result;
++ }
++
++ private static BoundMethodHandle insertArgumentPrimitive(BoundMethodHandle result, int pos,
++ Class<?> ptype, Object value) {
++ Wrapper w = Wrapper.forPrimitiveType(ptype);
++ // perform unboxing and/or primitive conversion
++ value = w.convert(value, ptype);
++ switch (w) {
++ case INT: return result.bindArgumentI(pos, (int)value);
++ case LONG: return result.bindArgumentJ(pos, (long)value);
++ case FLOAT: return result.bindArgumentF(pos, (float)value);
++ case DOUBLE: return result.bindArgumentD(pos, (double)value);
++ default: return result.bindArgumentI(pos, ValueConversions.widenSubword(value));
++ }
++ }
++
++ private static Class<?>[] insertArgumentsChecks(MethodHandle target, int insCount, int pos) throws RuntimeException {
+ MethodType oldType = target.type();
+ int outargs = oldType.parameterCount();
+ int inargs = outargs - insCount;
+@@ -2197,31 +2400,7 @@
+ throw newIllegalArgumentException("too many values to insert");
+ if (pos < 0 || pos > inargs)
+ throw newIllegalArgumentException("no argument type to append");
+- MethodHandle result = target;
+- for (int i = 0; i < insCount; i++) {
+- Object value = values[i];
+- Class<?> ptype = oldType.parameterType(pos+i);
+- if (ptype.isPrimitive()) {
+- char btype = 'I';
+- Wrapper w = Wrapper.forPrimitiveType(ptype);
+- switch (w) {
+- case LONG: btype = 'J'; break;
+- case FLOAT: btype = 'F'; break;
+- case DOUBLE: btype = 'D'; break;
+- }
+- // perform unboxing and/or primitive conversion
+- value = w.convert(value, ptype);
+- result = result.bindArgument(pos, btype, value);
+- continue;
+- }
+- value = ptype.cast(value); // throw CCE if needed
+- if (pos == 0) {
+- result = result.bindReceiver(value);
+- } else {
+- result = result.bindArgument(pos, 'L', value);
+- }
+- }
+- return result;
++ return oldType.ptypes();
+ }
+
+ /**
+@@ -2269,18 +2448,29 @@
+ public static
+ MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
+ MethodType oldType = target.type(); // get NPE
++ int dropped = dropArgumentChecks(oldType, pos, valueTypes);
++ MethodType newType = oldType.insertParameterTypes(pos, valueTypes);
++ if (dropped == 0) return target;
++ BoundMethodHandle result = target.rebind();
++ LambdaForm lform = result.form;
++ int insertFormArg = 1 + pos;
++ for (Class<?> ptype : valueTypes) {
++ lform = lform.editor().addArgumentForm(insertFormArg++, BasicType.basicType(ptype));
++ }
++ result = result.copyWith(newType, lform);
++ return result;
++ }
++
++ private static int dropArgumentChecks(MethodType oldType, int pos, List<Class<?>> valueTypes) {
+ int dropped = valueTypes.size();
+ MethodType.checkSlotCount(dropped);
+- if (dropped == 0) return target;
+ int outargs = oldType.parameterCount();
+ int inargs = outargs + dropped;
+- if (pos < 0 || pos >= inargs)
+- throw newIllegalArgumentException("no argument type to remove");
+- ArrayList<Class<?>> ptypes = new ArrayList<>(oldType.parameterList());
+- ptypes.addAll(pos, valueTypes);
+- if (ptypes.size() != inargs) throw newIllegalArgumentException("valueTypes");
+- MethodType newType = MethodType.methodType(oldType.returnType(), ptypes);
+- return target.dropArguments(newType, pos, dropped);
++ if (pos < 0 || pos > outargs)
++ throw newIllegalArgumentException("no argument type to remove"
++ + Arrays.asList(oldType, pos, valueTypes, inargs, outargs)
++ );
++ return dropped;
+ }
+
+ /**
+@@ -2402,32 +2592,43 @@
+ */
+ public static
+ MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
+- MethodType targetType = target.type();
++ filterArgumentsCheckArity(target, pos, filters);
+ MethodHandle adapter = target;
+- MethodType adapterType = null;
+- assert((adapterType = targetType) != null);
+- int maxPos = targetType.parameterCount();
+- if (pos + filters.length > maxPos)
+- throw newIllegalArgumentException("too many filters");
+ int curPos = pos-1; // pre-incremented
+ for (MethodHandle filter : filters) {
+ curPos += 1;
+ if (filter == null) continue; // ignore null elements of filters
+ adapter = filterArgument(adapter, curPos, filter);
+- assert((adapterType = adapterType.changeParameterType(curPos, filter.type().parameterType(0))) != null);
+ }
+- assert(adapterType.equals(adapter.type()));
+ return adapter;
+ }
+
+ /*non-public*/ static
+ MethodHandle filterArgument(MethodHandle target, int pos, MethodHandle filter) {
++ filterArgumentChecks(target, pos, filter);
++ MethodType targetType = target.type();
++ MethodType filterType = filter.type();
++ BoundMethodHandle result = target.rebind();
++ Class<?> newParamType = filterType.parameterType(0);
++ LambdaForm lform = result.editor().filterArgumentForm(1 + pos, BasicType.basicType(newParamType));
++ MethodType newType = targetType.changeParameterType(pos, newParamType);
++ result = result.copyWithExtendL(newType, lform, filter);
++ return result;
++ }
++
++ private static void filterArgumentsCheckArity(MethodHandle target, int pos, MethodHandle[] filters) {
++ MethodType targetType = target.type();
++ int maxPos = targetType.parameterCount();
++ if (pos + filters.length > maxPos)
++ throw newIllegalArgumentException("too many filters");
++ }
++
++ private static void filterArgumentChecks(MethodHandle target, int pos, MethodHandle filter) throws RuntimeException {
+ MethodType targetType = target.type();
+ MethodType filterType = filter.type();
+ if (filterType.parameterCount() != 1
+ || filterType.returnType() != targetType.parameterType(pos))
+ throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
+- return MethodHandleImpl.makeCollectArguments(target, filter, pos, false);
+ }
+
+ /**
+@@ -2538,12 +2739,32 @@
+ */
+ public static
+ MethodHandle collectArguments(MethodHandle target, int pos, MethodHandle filter) {
++ MethodType newType = collectArgumentsChecks(target, pos, filter);
++ MethodType collectorType = filter.type();
++ BoundMethodHandle result = target.rebind();
++ LambdaForm lform;
++ if (collectorType.returnType().isArray() && filter.intrinsicName() == Intrinsic.NEW_ARRAY) {
++ lform = result.editor().collectArgumentArrayForm(1 + pos, filter);
++ if (lform != null) {
++ return result.copyWith(newType, lform);
++ }
++ }
++ lform = result.editor().collectArgumentsForm(1 + pos, collectorType.basicType());
++ return result.copyWithExtendL(newType, lform, filter);
++ }
++
++ private static MethodType collectArgumentsChecks(MethodHandle target, int pos, MethodHandle filter) throws RuntimeException {
+ MethodType targetType = target.type();
+ MethodType filterType = filter.type();
+- if (filterType.returnType() != void.class &&
+- filterType.returnType() != targetType.parameterType(pos))
++ Class<?> rtype = filterType.returnType();
++ List<Class<?>> filterArgs = filterType.parameterList();
++ if (rtype == void.class) {
++ return targetType.insertParameterTypes(pos, filterArgs);
++ }
++ if (rtype != targetType.parameterType(pos)) {
+ throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
+- return MethodHandleImpl.makeCollectArguments(target, filter, pos, false);
++ }
++ return targetType.dropParameterTypes(pos, pos+1).insertParameterTypes(pos, filterArgs);
+ }
+
+ /**
+@@ -2607,15 +2828,22 @@
+ MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter) {
+ MethodType targetType = target.type();
+ MethodType filterType = filter.type();
++ filterReturnValueChecks(targetType, filterType);
++ BoundMethodHandle result = target.rebind();
++ BasicType rtype = BasicType.basicType(filterType.returnType());
++ LambdaForm lform = result.editor().filterReturnForm(rtype, false);
++ MethodType newType = targetType.changeReturnType(filterType.returnType());
++ result = result.copyWithExtendL(newType, lform, filter);
++ return result;
++ }
++
++ private static void filterReturnValueChecks(MethodType targetType, MethodType filterType) throws RuntimeException {
+ Class<?> rtype = targetType.returnType();
+ int filterValues = filterType.parameterCount();
+ if (filterValues == 0
+ ? (rtype != void.class)
+ : (rtype != filterType.parameterType(0)))
+- throw newIllegalArgumentException("target and filter types do not match", target, filter);
+- // result = fold( lambda(retval, arg...) { filter(retval) },
+- // lambda( arg...) { target(arg...) } )
+- return MethodHandleImpl.makeCollectArguments(filter, target, 0, false);
++ throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
+ }
+
+ /**
+@@ -2696,24 +2924,36 @@
+ */
+ public static
+ MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
+- int pos = 0;
++ int foldPos = 0;
+ MethodType targetType = target.type();
+ MethodType combinerType = combiner.type();
+- int foldPos = pos;
+- int foldArgs = combinerType.parameterCount();
+- int foldVals = combinerType.returnType() == void.class ? 0 : 1;
++ Class<?> rtype = foldArgumentChecks(foldPos, targetType, combinerType);
++ BoundMethodHandle result = target.rebind();
++ boolean dropResult = (rtype == void.class);
++ // Note: This may cache too many distinct LFs. Consider backing off to varargs code.
++ LambdaForm lform = result.editor().foldArgumentsForm(1 + foldPos, dropResult, combinerType.basicType());
++ MethodType newType = targetType;
++ if (!dropResult)
++ newType = newType.dropParameterTypes(foldPos, foldPos + 1);
++ result = result.copyWithExtendL(newType, lform, combiner);
++ return result;
++ }
++
++ private static Class<?> foldArgumentChecks(int foldPos, MethodType targetType, MethodType combinerType) {
++ int foldArgs = combinerType.parameterCount();
++ Class<?> rtype = combinerType.returnType();
++ int foldVals = rtype == void.class ? 0 : 1;
+ int afterInsertPos = foldPos + foldVals;
+ boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
+ if (ok && !(combinerType.parameterList()
+ .equals(targetType.parameterList().subList(afterInsertPos,
+ afterInsertPos + foldArgs))))
+ ok = false;
+- if (ok && foldVals != 0 && !combinerType.returnType().equals(targetType.parameterType(0)))
++ if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(0))
+ ok = false;
+ if (!ok)
+ throw misMatchedTypes("target and combiner types", targetType, combinerType);
+- MethodType newType = targetType.dropParameterTypes(foldPos, afterInsertPos);
+- return MethodHandleImpl.makeCollectArguments(target, combiner, foldPos, true);
++ return rtype;
+ }
+
+ /**
+--- ./jdk/src/share/classes/java/lang/invoke/MethodType.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/MethodType.java Wed Feb 04 12:14:43 2015 -0800
+@@ -466,6 +466,75 @@
+ return dropParameterTypes(start, end).insertParameterTypes(start, ptypesToInsert);
+ }
+
++ /** Replace the last arrayLength parameter types with the component type of arrayType.
++ * @param arrayType any array type
++ * @param arrayLength the number of parameter types to change
++ * @return the resulting type
++ */
++ /*non-public*/ MethodType asSpreaderType(Class<?> arrayType, int arrayLength) {
++ assert(parameterCount() >= arrayLength);
++ int spreadPos = ptypes.length - arrayLength;
++ if (arrayLength == 0) return this; // nothing to change
++ if (arrayType == Object[].class) {
++ if (isGeneric()) return this; // nothing to change
++ if (spreadPos == 0) {
++ // no leading arguments to preserve; go generic
++ MethodType res = genericMethodType(arrayLength);
++ if (rtype != Object.class) {
++ res = res.changeReturnType(rtype);
++ }
++ return res;
++ }
++ }
++ Class<?> elemType = arrayType.getComponentType();
++ assert(elemType != null);
++ for (int i = spreadPos; i < ptypes.length; i++) {
++ if (ptypes[i] != elemType) {
++ Class<?>[] fixedPtypes = ptypes.clone();
++ Arrays.fill(fixedPtypes, i, ptypes.length, elemType);
++ return methodType(rtype, fixedPtypes);
++ }
++ }
++ return this; // arguments check out; no change
++ }
++
++ /** Return the leading parameter type, which must exist and be a reference.
++ * @return the leading parameter type, after error checks
++ */
++ /*non-public*/ Class<?> leadingReferenceParameter() {
++ Class<?> ptype;
++ if (ptypes.length == 0 ||
++ (ptype = ptypes[0]).isPrimitive())
++ throw newIllegalArgumentException("no leading reference parameter");
++ return ptype;
++ }
++
++ /** Delete the last parameter type and replace it with arrayLength copies of the component type of arrayType.
++ * @param arrayType any array type
++ * @param arrayLength the number of parameter types to insert
++ * @return the resulting type
++ */
++ /*non-public*/ MethodType asCollectorType(Class<?> arrayType, int arrayLength) {
++ assert(parameterCount() >= 1);
++ assert(lastParameterType().isAssignableFrom(arrayType));
++ MethodType res;
++ if (arrayType == Object[].class) {
++ res = genericMethodType(arrayLength);
++ if (rtype != Object.class) {
++ res = res.changeReturnType(rtype);
++ }
++ } else {
++ Class<?> elemType = arrayType.getComponentType();
++ assert(elemType != null);
++ res = methodType(rtype, Collections.nCopies(arrayLength, elemType));
++ }
++ if (ptypes.length == 1) {
++ return res;
++ } else {
++ return res.insertParameterTypes(0, parameterList().subList(0, ptypes.length-1));
++ }
++ }
++
+ /**
+ * Finds or creates a method type with some parameter types omitted.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+@@ -573,6 +642,10 @@
+ return genericMethodType(parameterCount());
+ }
+
++ /*non-public*/ boolean isGeneric() {
++ return this == erase() && !hasPrimitives();
++ }
++
+ /**
+ * Converts all primitive types to their corresponding wrapper types.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+@@ -728,44 +801,127 @@
+ return sb.toString();
+ }
+
+-
++ /** True if the old return type can always be viewed (w/o casting) under new return type,
++ * and the new parameters can be viewed (w/o casting) under the old parameter types.
++ */
+ /*non-public*/
+- boolean isViewableAs(MethodType newType) {
+- if (!VerifyType.isNullConversion(returnType(), newType.returnType()))
++ boolean isViewableAs(MethodType newType, boolean keepInterfaces) {
++ if (!VerifyType.isNullConversion(returnType(), newType.returnType(), keepInterfaces))
+ return false;
++ return parametersAreViewableAs(newType, keepInterfaces);
++ }
++ /** True if the new parameters can be viewed (w/o casting) under the old parameter types. */
++ /*non-public*/
++ boolean parametersAreViewableAs(MethodType newType, boolean keepInterfaces) {
++ if (form == newType.form && form.erasedType == this)
++ return true; // my reference parameters are all Object
++ if (ptypes == newType.ptypes)
++ return true;
+ int argc = parameterCount();
+ if (argc != newType.parameterCount())
+ return false;
+ for (int i = 0; i < argc; i++) {
+- if (!VerifyType.isNullConversion(newType.parameterType(i), parameterType(i)))
++ if (!VerifyType.isNullConversion(newType.parameterType(i), parameterType(i), keepInterfaces))
+ return false;
+ }
+ return true;
+ }
+ /*non-public*/
+- boolean isCastableTo(MethodType newType) {
+- int argc = parameterCount();
+- if (argc != newType.parameterCount())
+- return false;
+- return true;
+- }
+- /*non-public*/
+ boolean isConvertibleTo(MethodType newType) {
++ MethodTypeForm oldForm = this.form();
++ MethodTypeForm newForm = newType.form();
++ if (oldForm == newForm)
++ // same parameter count, same primitive/object mix
++ return true;
+ if (!canConvert(returnType(), newType.returnType()))
+ return false;
+- int argc = parameterCount();
+- if (argc != newType.parameterCount())
++ Class<?>[] srcTypes = newType.ptypes;
++ Class<?>[] dstTypes = ptypes;
++ if (srcTypes == dstTypes)
++ return true;
++ int argc;
++ if ((argc = srcTypes.length) != dstTypes.length)
+ return false;
+- for (int i = 0; i < argc; i++) {
+- if (!canConvert(newType.parameterType(i), parameterType(i)))
++ if (argc <= 1) {
++ if (argc == 1 && !canConvert(srcTypes[0], dstTypes[0]))
+ return false;
++ return true;
++ }
++ if ((oldForm.primitiveParameterCount() == 0 && oldForm.erasedType == this) ||
++ (newForm.primitiveParameterCount() == 0 && newForm.erasedType == newType)) {
++ // Somewhat complicated test to avoid a loop of 2 or more trips.
++ // If either type has only Object parameters, we know we can convert.
++ assert(canConvertParameters(srcTypes, dstTypes));
++ return true;
++ }
++ return canConvertParameters(srcTypes, dstTypes);
++ }
++
++ /** Returns true if MHs.explicitCastArguments produces the same result as MH.asType.
++ * If the type conversion is impossible for either, the result should be false.
++ */
++ /*non-public*/
++ boolean explicitCastEquivalentToAsType(MethodType newType) {
++ if (this == newType) return true;
++ if (!explicitCastEquivalentToAsType(rtype, newType.rtype)) {
++ return false;
++ }
++ Class<?>[] srcTypes = newType.ptypes;
++ Class<?>[] dstTypes = ptypes;
++ if (dstTypes == srcTypes) {
++ return true;
++ }
++ assert(dstTypes.length == srcTypes.length);
++ for (int i = 0; i < dstTypes.length; i++) {
++ if (!explicitCastEquivalentToAsType(srcTypes[i], dstTypes[i])) {
++ return false;
++ }
+ }
+ return true;
+ }
++
++ /** Reports true if the src can be converted to the dst, by both asType and MHs.eCE,
++ * and with the same effect.
++ * MHs.eCA has the following "upgrades" to MH.asType:
++ * 1. interfaces are unchecked (that is, treated as if aliased to Object)
++ * Therefore, {@code Object->CharSequence} is possible in both cases but has different semantics
++ * 2. the full matrix of primitive-to-primitive conversions is supported
++ * Narrowing like {@code long->byte} and basic-typing like {@code boolean->int}
++ * are not supported by asType, but anything supported by asType is equivalent
++ * with MHs.eCE.
++ * 3a. unboxing conversions can be followed by the full matrix of primitive conversions
++ * 3b. unboxing of null is permitted (creates a zero primitive value)
++ * Other than interfaces, reference-to-reference conversions are the same.
++ * Boxing primitives to references is the same for both operators.
++ */
++ private static boolean explicitCastEquivalentToAsType(Class<?> src, Class<?> dst) {
++ if (src == dst || dst == Object.class || dst == void.class) return true;
++ if (src.isPrimitive()) {
++ // Could be a prim/prim conversion, where casting is a strict superset.
++ // Or a boxing conversion, which is always to an exact wrapper class.
++ return canConvert(src, dst);
++ } else if (dst.isPrimitive()) {
++ // Unboxing behavior is different between MHs.eCA & MH.asType (see 3b).
++ return false;
++ } else {
++ // R->R always works, but we have to avoid a check-cast to an interface.
++ return !dst.isInterface() || dst.isAssignableFrom(src);
++ }
++ }
++
++ private boolean canConvertParameters(Class<?>[] srcTypes, Class<?>[] dstTypes) {
++ for (int i = 0; i < srcTypes.length; i++) {
++ if (!canConvert(srcTypes[i], dstTypes[i])) {
++ return false;
++ }
++ }
++ return true;
++ }
++
+ /*non-public*/
+ static boolean canConvert(Class<?> src, Class<?> dst) {
+ // short-circuit a few cases:
+- if (src == dst || dst == Object.class) return true;
++ if (src == dst || src == Object.class || dst == Object.class) return true;
+ // the remainder of this logic is documented in MethodHandle.asType
+ if (src.isPrimitive()) {
+ // can force void to an explicit null, a la reflect.Method.invoke
+@@ -907,7 +1063,7 @@
+ if (!descriptor.startsWith("(") || // also generates NPE if needed
+ descriptor.indexOf(')') < 0 ||
+ descriptor.indexOf('.') >= 0)
+- throw new IllegalArgumentException("not a method descriptor: "+descriptor);
++ throw newIllegalArgumentException("not a method descriptor: "+descriptor);
+ List<Class<?>> types = BytecodeDescriptor.parseMethod(descriptor, loader);
+ Class<?> rtype = types.remove(types.size() - 1);
+ checkSlotCount(types.size());
+--- ./jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java Wed Feb 04 12:14:43 2015 -0800
+@@ -26,9 +26,8 @@
+ package java.lang.invoke;
+
+ import sun.invoke.util.Wrapper;
++import java.lang.ref.SoftReference;
+ import static java.lang.invoke.MethodHandleStatics.*;
+-import static java.lang.invoke.MethodHandleNatives.Constants.*;
+- import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+
+ /**
+ * Shared information for a group of method types, which differ
+@@ -47,77 +46,101 @@
+ final int[] argToSlotTable, slotToArgTable;
+ final long argCounts; // packed slot & value counts
+ final long primCounts; // packed prim & double counts
+- final int vmslots; // total number of parameter slots
+ final MethodType erasedType; // the canonical erasure
+ final MethodType basicType; // the canonical erasure, with primitives simplified
+
+ // Cached adapter information:
+- @Stable String typeString; // argument type signature characters
+- @Stable MethodHandle genericInvoker; // JVM hook for inexact invoke
+- @Stable MethodHandle basicInvoker; // cached instance of MH.invokeBasic
+- @Stable MethodHandle namedFunctionInvoker; // cached helper for LF.NamedFunction
++ @Stable final SoftReference<MethodHandle>[] methodHandles;
++ // Indexes into methodHandles:
++ static final int
++ MH_BASIC_INV = 0, // cached instance of MH.invokeBasic
++ MH_NF_INV = 1, // cached helper for LF.NamedFunction
++ MH_UNINIT_CS = 2, // uninitialized call site
++ MH_LIMIT = 3;
+
+ // Cached lambda form information, for basic types only:
+- final @Stable LambdaForm[] lambdaForms;
++ final @Stable SoftReference<LambdaForm>[] lambdaForms;
+ // Indexes into lambdaForms:
+ static final int
+- LF_INVVIRTUAL = 0, // DMH invokeVirtual
+- LF_INVSTATIC = 1,
+- LF_INVSPECIAL = 2,
+- LF_NEWINVSPECIAL = 3,
+- LF_INVINTERFACE = 4,
+- LF_INVSTATIC_INIT = 5, // DMH invokeStatic with <clinit> barrier
+- LF_INTERPRET = 6, // LF interpreter
+- LF_COUNTER = 7, // CMH wrapper
+- LF_REINVOKE = 8, // other wrapper
+- LF_EX_LINKER = 9, // invokeExact_MT
+- LF_EX_INVOKER = 10, // invokeExact MH
+- LF_GEN_LINKER = 11,
+- LF_GEN_INVOKER = 12,
+- LF_CS_LINKER = 13, // linkToCallSite_CS
+- LF_MH_LINKER = 14, // linkToCallSite_MH
+- LF_GWC = 15,
+- LF_LIMIT = 16;
++ LF_INVVIRTUAL = 0, // DMH invokeVirtual
++ LF_INVSTATIC = 1,
++ LF_INVSPECIAL = 2,
++ LF_NEWINVSPECIAL = 3,
++ LF_INVINTERFACE = 4,
++ LF_INVSTATIC_INIT = 5, // DMH invokeStatic with <clinit> barrier
++ LF_INTERPRET = 6, // LF interpreter
++ LF_REBIND = 7, // BoundMethodHandle
++ LF_DELEGATE = 8, // DelegatingMethodHandle
++ LF_DELEGATE_BLOCK_INLINING = 9, // Counting DelegatingMethodHandle w/ @DontInline
++ LF_EX_LINKER = 10, // invokeExact_MT (for invokehandle)
++ LF_EX_INVOKER = 11, // MHs.invokeExact
++ LF_GEN_LINKER = 12, // generic invoke_MT (for invokehandle)
++ LF_GEN_INVOKER = 13, // generic MHs.invoke
++ LF_CS_LINKER = 14, // linkToCallSite_CS
++ LF_MH_LINKER = 15, // linkToCallSite_MH
++ LF_GWC = 16, // guardWithCatch (catchException)
++ LF_GWT = 17, // guardWithTest
++ LF_LIMIT = 18;
+
++ /** Return the type corresponding uniquely (1-1) to this MT-form.
++ * It might have any primitive returns or arguments, but will have no references except Object.
++ */
+ public MethodType erasedType() {
+ return erasedType;
+ }
+
++ /** Return the basic type derived from the erased type of this MT-form.
++ * A basic type is erased (all references Object) and also has all primitive
++ * types (except int, long, float, double, void) normalized to int.
++ * Such basic types correspond to low-level JVM calling sequences.
++ */
+ public MethodType basicType() {
+ return basicType;
+ }
+
++ private boolean assertIsBasicType() {
++ // primitives must be flattened also
++ assert(erasedType == basicType)
++ : "erasedType: " + erasedType + " != basicType: " + basicType;
++ return true;
++ }
++
++ public MethodHandle cachedMethodHandle(int which) {
++ assert(assertIsBasicType());
++ SoftReference<MethodHandle> entry = methodHandles[which];
++ return (entry != null) ? entry.get() : null;
++ }
++
++ synchronized public MethodHandle setCachedMethodHandle(int which, MethodHandle mh) {
++ // Simulate a CAS, to avoid racy duplication of results.
++ SoftReference<MethodHandle> entry = methodHandles[which];
++ if (entry != null) {
++ MethodHandle prev = entry.get();
++ if (prev != null) {
++ return prev;
++ }
++ }
++ methodHandles[which] = new SoftReference<>(mh);
++ return mh;
++ }
++
+ public LambdaForm cachedLambdaForm(int which) {
+- return lambdaForms[which];
++ assert(assertIsBasicType());
++ SoftReference<LambdaForm> entry = lambdaForms[which];
++ return (entry != null) ? entry.get() : null;
+ }
+
+ synchronized public LambdaForm setCachedLambdaForm(int which, LambdaForm form) {
+ // Simulate a CAS, to avoid racy duplication of results.
+- LambdaForm prev = lambdaForms[which];
+- if (prev != null) return prev;
+- return lambdaForms[which] = form;
+- }
+-
+- public MethodHandle basicInvoker() {
+- assert(erasedType == basicType) : "erasedType: " + erasedType + " != basicType: " + basicType; // primitives must be flattened also
+- MethodHandle invoker = basicInvoker;
+- if (invoker != null) return invoker;
+- invoker = DirectMethodHandle.make(invokeBasicMethod(basicType));
+- basicInvoker = invoker;
+- return invoker;
+- }
+-
+- // This next one is called from LambdaForm.NamedFunction.<init>.
+- /*non-public*/ static MemberName invokeBasicMethod(MethodType basicType) {
+- assert(basicType == basicType.basicType());
+- try {
+- // Do approximately the same as this public API call:
+- // Lookup.findVirtual(MethodHandle.class, name, type);
+- // But bypass access and corner case checks, since we know exactly what we need.
+- return IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, MethodHandle.class, "invokeBasic", basicType);
+- } catch (ReflectiveOperationException ex) {
+- throw newInternalError("JVM cannot find invoker for "+basicType, ex);
++ SoftReference<LambdaForm> entry = lambdaForms[which];
++ if (entry != null) {
++ LambdaForm prev = entry.get();
++ if (prev != null) {
++ return prev;
++ }
+ }
++ lambdaForms[which] = new SoftReference<>(form);
++ return form;
+ }
+
+ /**
+@@ -125,6 +148,7 @@
+ * This MTF will stand for that type and all un-erased variations.
+ * Eagerly compute some basic properties of the type, common to all variations.
+ */
++ @SuppressWarnings({"rawtypes", "unchecked"})
+ protected MethodTypeForm(MethodType erasedType) {
+ this.erasedType = erasedType;
+
+@@ -172,6 +196,16 @@
+ this.basicType = erasedType;
+ } else {
+ this.basicType = MethodType.makeImpl(bt, bpts, true);
++ // fill in rest of data from the basic type:
++ MethodTypeForm that = this.basicType.form();
++ assert(this != that);
++ this.primCounts = that.primCounts;
++ this.argCounts = that.argCounts;
++ this.argToSlotTable = that.argToSlotTable;
++ this.slotToArgTable = that.slotToArgTable;
++ this.methodHandles = null;
++ this.lambdaForms = null;
++ return;
+ }
+ if (lac != 0) {
+ int slot = ptypeCount + lac;
+@@ -187,10 +221,14 @@
+ argToSlotTab[1+i] = slot;
+ }
+ assert(slot == 0); // filled the table
+- }
+- this.primCounts = pack(lrc, prc, lac, pac);
+- this.argCounts = pack(rslotCount, rtypeCount, pslotCount, ptypeCount);
+- if (slotToArgTab == null) {
++ } else if (pac != 0) {
++ // have primitives but no long primitives; share slot counts with generic
++ assert(ptypeCount == pslotCount);
++ MethodTypeForm that = MethodType.genericMethodType(ptypeCount).form();
++ assert(this != that);
++ slotToArgTab = that.slotToArgTable;
++ argToSlotTab = that.argToSlotTable;
++ } else {
+ int slot = ptypeCount; // first arg is deepest in stack
+ slotToArgTab = new int[slot+1];
+ argToSlotTab = new int[1+ptypeCount];
+@@ -201,19 +239,17 @@
+ argToSlotTab[1+i] = slot;
+ }
+ }
++ this.primCounts = pack(lrc, prc, lac, pac);
++ this.argCounts = pack(rslotCount, rtypeCount, pslotCount, ptypeCount);
+ this.argToSlotTable = argToSlotTab;
+ this.slotToArgTable = slotToArgTab;
+
+ if (pslotCount >= 256) throw newIllegalArgumentException("too many arguments");
+
+- // send a few bits down to the JVM:
+- this.vmslots = parameterSlotCount();
+-
+- if (basicType == erasedType) {
+- lambdaForms = new LambdaForm[LF_LIMIT];
+- } else {
+- lambdaForms = null; // could be basicType.form().lambdaForms;
+- }
++ // Initialize caches, but only for basic types
++ assert(basicType == erasedType);
++ this.lambdaForms = new SoftReference[LF_LIMIT];
++ this.methodHandles = new SoftReference[MH_LIMIT];
+ }
+
+ private static long pack(int a, int b, int c, int d) {
+@@ -300,7 +336,7 @@
+ */
+ public static MethodType canonicalize(MethodType mt, int howRet, int howArgs) {
+ Class<?>[] ptypes = mt.ptypes();
+- Class<?>[] ptc = MethodTypeForm.canonicalizes(ptypes, howArgs);
++ Class<?>[] ptc = MethodTypeForm.canonicalizeAll(ptypes, howArgs);
+ Class<?> rtype = mt.returnType();
+ Class<?> rtc = MethodTypeForm.canonicalize(rtype, howRet);
+ if (ptc == null && rtc == null) {
+@@ -368,7 +404,7 @@
+ /** Canonicalize each param type in the given array.
+ * Return null if all types are already canonicalized.
+ */
+- static Class<?>[] canonicalizes(Class<?>[] ts, int how) {
++ static Class<?>[] canonicalizeAll(Class<?>[] ts, int how) {
+ Class<?>[] cs = null;
+ for (int imax = ts.length, i = 0; i < imax; i++) {
+ Class<?> c = canonicalize(ts[i], how);
+@@ -387,5 +423,4 @@
+ public String toString() {
+ return "Form"+erasedType;
+ }
+-
+ }
+--- ./jdk/src/share/classes/java/lang/invoke/SimpleMethodHandle.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/SimpleMethodHandle.java Wed Feb 04 12:14:43 2015 -0800
+@@ -25,46 +25,77 @@
+
+ package java.lang.invoke;
+
+-import static java.lang.invoke.LambdaForm.*;
+-import static java.lang.invoke.MethodHandleNatives.Constants.*;
+-import java.util.logging.Level;
+-import java.util.logging.Logger;
++import static java.lang.invoke.LambdaForm.BasicType.*;
++import static java.lang.invoke.MethodHandleStatics.*;
+
+ /**
+ * A method handle whose behavior is determined only by its LambdaForm.
+ * @author jrose
+ */
+-final class SimpleMethodHandle extends MethodHandle {
++final class SimpleMethodHandle extends BoundMethodHandle {
+ private SimpleMethodHandle(MethodType type, LambdaForm form) {
+ super(type, form);
+ }
+
+- /*non-public*/ static SimpleMethodHandle make(MethodType type, LambdaForm form) {
++ /*non-public*/ static BoundMethodHandle make(MethodType type, LambdaForm form) {
+ return new SimpleMethodHandle(type, form);
+ }
+
+- @Override
+- MethodHandle bindArgument(int pos, char basicType, Object value) {
+- MethodType type2 = type().dropParameterTypes(pos, pos+1);
+- LambdaForm form2 = internalForm().bind(1+pos, BoundMethodHandle.SpeciesData.EMPTY);
+- return BoundMethodHandle.bindSingle(type2, form2, basicType, value);
++ /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.EMPTY;
++
++ /*non-public*/ public SpeciesData speciesData() {
++ return SPECIES_DATA;
+ }
+
+ @Override
+- MethodHandle dropArguments(MethodType srcType, int pos, int drops) {
+- LambdaForm newForm = internalForm().addArguments(pos, srcType.parameterList().subList(pos, pos+drops));
+- return new SimpleMethodHandle(srcType, newForm);
++ /*non-public*/ BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) {
++ return make(mt, lf);
+ }
+
+ @Override
+- MethodHandle permuteArguments(MethodType newType, int[] reorder) {
+- LambdaForm form2 = internalForm().permuteArguments(1, reorder, basicTypes(newType.parameterList()));
+- return new SimpleMethodHandle(newType, form2);
++ String internalProperties() {
++ return "\n& Class="+getClass().getSimpleName();
+ }
+
+ @Override
+- MethodHandle copyWith(MethodType mt, LambdaForm lf) {
+- return new SimpleMethodHandle(mt, lf);
++ /*non-public*/ public int fieldCount() {
++ return 0;
+ }
+
++ @Override
++ /*non-public*/ final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
++ return BoundMethodHandle.bindSingle(mt, lf, narg); // Use known fast path.
++ }
++ @Override
++ /*non-public*/ final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
++ try {
++ return (BoundMethodHandle) SPECIES_DATA.extendWith(I_TYPE).constructor().invokeBasic(mt, lf, narg);
++ } catch (Throwable ex) {
++ throw uncaughtException(ex);
++ }
++ }
++ @Override
++ /*non-public*/ final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
++ try {
++ return (BoundMethodHandle) SPECIES_DATA.extendWith(J_TYPE).constructor().invokeBasic(mt, lf, narg);
++ } catch (Throwable ex) {
++ throw uncaughtException(ex);
++ }
++ }
++ @Override
++ /*non-public*/ final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
++ try {
++ return (BoundMethodHandle) SPECIES_DATA.extendWith(F_TYPE).constructor().invokeBasic(mt, lf, narg);
++ } catch (Throwable ex) {
++ throw uncaughtException(ex);
++ }
++ }
++ @Override
++ /*non-public*/ final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
++ try {
++ return (BoundMethodHandle) SPECIES_DATA.extendWith(D_TYPE).constructor().invokeBasic(mt, lf, narg);
++ } catch (Throwable ex) {
++ throw uncaughtException(ex);
++ }
++ }
+ }
+--- ./jdk/src/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -158,19 +158,19 @@
+ visitMethodInsn(Opcodes.INVOKESTATIC,
+ wrapperName(w),
+ NAME_BOX_METHOD,
+- boxingDescriptor(w));
++ boxingDescriptor(w), false);
+ }
+
+ /**
+ * Convert types by unboxing. The source type is known to be a primitive wrapper.
+- * @param ws A primitive wrapper corresponding to wrapped reference source type
++ * @param sname A primitive wrapper corresponding to wrapped reference source type
+ * @param wt A primitive wrapper being converted to
+ */
+ void unbox(String sname, Wrapper wt) {
+ visitMethodInsn(Opcodes.INVOKEVIRTUAL,
+ sname,
+ unboxMethod(wt),
+- unboxingDescriptor(wt));
++ unboxingDescriptor(wt), false);
+ }
+
+ private String descriptorToName(String desc) {
+--- ./jdk/src/share/classes/java/lang/management/ManagementFactory.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/management/ManagementFactory.java Wed Feb 04 12:14:43 2015 -0800
+@@ -52,6 +52,7 @@
+ import java.security.PrivilegedExceptionAction;
+ import javax.management.JMX;
+ import sun.management.ManagementFactoryHelper;
++import sun.management.ExtendedPlatformComponent;
+
+ /**
+ * The {@code ManagementFactory} class is a factory class for getting
+@@ -489,6 +490,12 @@
+ for (Map.Entry<ObjectName, DynamicMBean> e : dynmbeans.entrySet()) {
+ addDynamicMBean(platformMBeanServer, e.getValue(), e.getKey());
+ }
++ for (final PlatformManagedObject o :
++ ExtendedPlatformComponent.getMXBeans()) {
++ if (!platformMBeanServer.isRegistered(o.getObjectName())) {
++ addMXBean(platformMBeanServer, o);
++ }
++ }
+ }
+ return platformMBeanServer;
+ }
+@@ -655,9 +662,14 @@
+ public static <T extends PlatformManagedObject>
+ T getPlatformMXBean(Class<T> mxbeanInterface) {
+ PlatformComponent pc = PlatformComponent.getPlatformComponent(mxbeanInterface);
+- if (pc == null)
++ if (pc == null) {
++ T mbean = ExtendedPlatformComponent.getMXBean(mxbeanInterface);
++ if (mbean != null) {
++ return mbean;
++ }
+ throw new IllegalArgumentException(mxbeanInterface.getName() +
+ " is not a platform management interface");
++ }
+ if (!pc.isSingleton())
+ throw new IllegalArgumentException(mxbeanInterface.getName() +
+ " can have zero or more than one instances");
+@@ -690,9 +702,14 @@
+ public static <T extends PlatformManagedObject> List<T>
+ getPlatformMXBeans(Class<T> mxbeanInterface) {
+ PlatformComponent pc = PlatformComponent.getPlatformComponent(mxbeanInterface);
+- if (pc == null)
++ if (pc == null) {
++ T mbean = ExtendedPlatformComponent.getMXBean(mxbeanInterface);
++ if (mbean != null) {
++ return Collections.singletonList(mbean);
++ }
+ throw new IllegalArgumentException(mxbeanInterface.getName() +
+ " is not a platform management interface");
++ }
+ return Collections.unmodifiableList(pc.getMXBeans(mxbeanInterface));
+ }
+
+@@ -737,9 +754,17 @@
+ throws java.io.IOException
+ {
+ PlatformComponent pc = PlatformComponent.getPlatformComponent(mxbeanInterface);
+- if (pc == null)
++ if (pc == null) {
++ T mbean = ExtendedPlatformComponent.getMXBean(mxbeanInterface);
++ if (mbean != null) {
++ ObjectName on = mbean.getObjectName();
++ return ManagementFactory.newPlatformMXBeanProxy(connection,
++ on.getCanonicalName(),
++ mxbeanInterface);
++ }
+ throw new IllegalArgumentException(mxbeanInterface.getName() +
+ " is not a platform management interface");
++ }
+ if (!pc.isSingleton())
+ throw new IllegalArgumentException(mxbeanInterface.getName() +
+ " can have zero or more than one instances");
+@@ -781,6 +806,13 @@
+ {
+ PlatformComponent pc = PlatformComponent.getPlatformComponent(mxbeanInterface);
+ if (pc == null) {
++ T mbean = ExtendedPlatformComponent.getMXBean(mxbeanInterface);
++ if (mbean != null) {
++ ObjectName on = mbean.getObjectName();
++ T proxy = ManagementFactory.newPlatformMXBeanProxy(connection,
++ on.getCanonicalName(), mxbeanInterface);
++ return Collections.singletonList(proxy);
++ }
+ throw new IllegalArgumentException(mxbeanInterface.getName() +
+ " is not a platform management interface");
+ }
+--- ./jdk/src/share/classes/java/lang/ref/ReferenceQueue.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/ref/ReferenceQueue.java Wed Feb 04 12:14:43 2015 -0800
+@@ -138,11 +138,17 @@
+ synchronized (lock) {
+ Reference<? extends T> r = reallyPoll();
+ if (r != null) return r;
++ long start = (timeout == 0) ? 0 : System.nanoTime();
+ for (;;) {
+ lock.wait(timeout);
+ r = reallyPoll();
+ if (r != null) return r;
+- if (timeout != 0) return null;
++ if (timeout != 0) {
++ long end = System.nanoTime();
++ timeout -= (end - start) / 1000_000;
++ if (timeout <= 0) return null;
++ start = end;
++ }
+ }
+ }
+ }
+--- ./jdk/src/share/classes/java/lang/reflect/AccessibleObject.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/reflect/AccessibleObject.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -129,14 +129,15 @@
+ setAccessible0(this, flag);
+ }
+
+- /* Check that you aren't exposing java.lang.Class.<init>. */
++ /* Check that you aren't exposing java.lang.Class.<init> or sensitive
++ fields in java.lang.Class. */
+ private static void setAccessible0(AccessibleObject obj, boolean flag)
+ throws SecurityException
+ {
+ if (obj instanceof Constructor && flag == true) {
+ Constructor<?> c = (Constructor<?>)obj;
+ if (c.getDeclaringClass() == Class.class) {
+- throw new SecurityException("Can not make a java.lang.Class" +
++ throw new SecurityException("Cannot make a java.lang.Class" +
+ " constructor accessible");
+ }
+ }
+--- ./jdk/src/share/classes/java/lang/reflect/Constructor.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/reflect/Constructor.java Wed Feb 04 12:14:43 2015 -0800
+@@ -94,9 +94,20 @@
+ // For sharing of ConstructorAccessors. This branching structure
+ // is currently only two levels deep (i.e., one root Constructor
+ // and potentially many Constructor objects pointing to it.)
++ //
++ // If this branching structure would ever contain cycles, deadlocks can
++ // occur in annotation code.
+ private Constructor<T> root;
+
+ /**
++ * Used by Excecutable for annotation sharing.
++ */
++ @Override
++ Executable getRoot() {
++ return root;
++ }
++
++ /**
+ * Package-private constructor used by ReflectAccess to enable
+ * instantiation of these objects in Java code from the java.lang
+ * package via sun.reflect.LangReflectAccess.
+@@ -132,6 +143,9 @@
+ // which implicitly requires that new java.lang.reflect
+ // objects be fabricated for each reflective call on Class
+ // objects.)
++ if (this.root != null)
++ throw new IllegalArgumentException("Can not copy a non-root Constructor");
++
+ Constructor<T> res = new Constructor<>(clazz,
+ parameterTypes,
+ exceptionTypes, modifiers, slot,
+--- ./jdk/src/share/classes/java/lang/reflect/Executable.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/reflect/Executable.java Wed Feb 04 12:14:43 2015 -0800
+@@ -53,6 +53,11 @@
+ abstract byte[] getAnnotationBytes();
+
+ /**
++ * Accessor method to allow code sharing
++ */
++ abstract Executable getRoot();
++
++ /**
+ * Does the Executable have generic information.
+ */
+ abstract boolean hasGenericInformation();
+@@ -282,6 +287,53 @@
+ }
+
+ /**
++ * Behaves like {@code getGenericParameterTypes}, but returns type
++ * information for all parameters, including synthetic parameters.
++ */
++ Type[] getAllGenericParameterTypes() {
++ final boolean genericInfo = hasGenericInformation();
++
++ // Easy case: we don't have generic parameter information. In
++ // this case, we just return the result of
++ // getParameterTypes().
++ if (!genericInfo) {
++ return getParameterTypes();
++ } else {
++ final boolean realParamData = hasRealParameterData();
++ final Type[] genericParamTypes = getGenericParameterTypes();
++ final Type[] nonGenericParamTypes = getParameterTypes();
++ final Type[] out = new Type[nonGenericParamTypes.length];
++ final Parameter[] params = getParameters();
++ int fromidx = 0;
++ // If we have real parameter data, then we use the
++ // synthetic and mandate flags to our advantage.
++ if (realParamData) {
++ for (int i = 0; i < out.length; i++) {
++ final Parameter param = params[i];
++ if (param.isSynthetic() || param.isImplicit()) {
++ // If we hit a synthetic or mandated parameter,
++ // use the non generic parameter info.
++ out[i] = nonGenericParamTypes[i];
++ } else {
++ // Otherwise, use the generic parameter info.
++ out[i] = genericParamTypes[fromidx];
++ fromidx++;
++ }
++ }
++ } else {
++ // Otherwise, use the non-generic parameter data.
++ // Without method parameter reflection data, we have
++ // no way to figure out which parameters are
++ // synthetic/mandated, thus, no way to match up the
++ // indexes.
++ return genericParamTypes.length == nonGenericParamTypes.length ?
++ genericParamTypes : nonGenericParamTypes;
++ }
++ return out;
++ }
++ }
++
++ /**
+ * Returns an array of {@code Parameter} objects that represent
+ * all the parameters to the underlying executable represented by
+ * this object. Returns an array of length 0 if the executable
+@@ -543,11 +595,16 @@
+
+ private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
+ if (declaredAnnotations == null) {
+- declaredAnnotations = AnnotationParser.parseAnnotations(
+- getAnnotationBytes(),
+- sun.misc.SharedSecrets.getJavaLangAccess().
+- getConstantPool(getDeclaringClass()),
+- getDeclaringClass());
++ Executable root = getRoot();
++ if (root != null) {
++ declaredAnnotations = root.declaredAnnotations();
++ } else {
++ declaredAnnotations = AnnotationParser.parseAnnotations(
++ getAnnotationBytes(),
++ sun.misc.SharedSecrets.getJavaLangAccess().
++ getConstantPool(getDeclaringClass()),
++ getDeclaringClass());
++ }
+ }
+ return declaredAnnotations;
+ }
+@@ -644,7 +701,7 @@
+ getConstantPool(getDeclaringClass()),
+ this,
+ getDeclaringClass(),
+- getGenericParameterTypes(),
++ getAllGenericParameterTypes(),
+ TypeAnnotation.TypeAnnotationTarget.METHOD_FORMAL_PARAMETER);
+ }
+
+--- ./jdk/src/share/classes/java/lang/reflect/Field.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/reflect/Field.java Wed Feb 04 12:14:43 2015 -0800
+@@ -81,6 +81,9 @@
+ // For sharing of FieldAccessors. This branching structure is
+ // currently only two levels deep (i.e., one root Field and
+ // potentially many Field objects pointing to it.)
++ //
++ // If this branching structure would ever contain cycles, deadlocks can
++ // occur in annotation code.
+ private Field root;
+
+ // Generics infrastructure
+@@ -141,6 +144,9 @@
+ // which implicitly requires that new java.lang.reflect
+ // objects be fabricated for each reflective call on Class
+ // objects.)
++ if (this.root != null)
++ throw new IllegalArgumentException("Can not copy a non-root Field");
++
+ Field res = new Field(clazz, name, type, modifiers, slot, signature, annotations);
+ res.root = this;
+ // Might as well eagerly propagate this if already present
+@@ -1137,10 +1143,15 @@
+
+ private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
+ if (declaredAnnotations == null) {
+- declaredAnnotations = AnnotationParser.parseAnnotations(
+- annotations, sun.misc.SharedSecrets.getJavaLangAccess().
+- getConstantPool(getDeclaringClass()),
+- getDeclaringClass());
++ Field root = this.root;
++ if (root != null) {
++ declaredAnnotations = root.declaredAnnotations();
++ } else {
++ declaredAnnotations = AnnotationParser.parseAnnotations(
++ annotations,
++ sun.misc.SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()),
++ getDeclaringClass());
++ }
+ }
+ return declaredAnnotations;
+ }
+--- ./jdk/src/share/classes/java/lang/reflect/Method.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/reflect/Method.java Wed Feb 04 12:14:43 2015 -0800
+@@ -79,6 +79,9 @@
+ // For sharing of MethodAccessors. This branching structure is
+ // currently only two levels deep (i.e., one root Method and
+ // potentially many Method objects pointing to it.)
++ //
++ // If this branching structure would ever contain cycles, deadlocks can
++ // occur in annotation code.
+ private Method root;
+
+ // Generics infrastructure
+@@ -144,6 +147,9 @@
+ // which implicitly requires that new java.lang.reflect
+ // objects be fabricated for each reflective call on Class
+ // objects.)
++ if (this.root != null)
++ throw new IllegalArgumentException("Can not copy a non-root Method");
++
+ Method res = new Method(clazz, name, parameterTypes, returnType,
+ exceptionTypes, modifiers, slot, signature,
+ annotations, parameterAnnotations, annotationDefault);
+@@ -153,6 +159,14 @@
+ return res;
+ }
+
++ /**
++ * Used by Excecutable for annotation sharing.
++ */
++ @Override
++ Executable getRoot() {
++ return root;
++ }
++
+ @Override
+ boolean hasGenericInformation() {
+ return (getGenericSignature() != null);
+--- ./jdk/src/share/classes/java/lang/reflect/Parameter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/lang/reflect/Parameter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -198,7 +198,7 @@
+ public Type getParameterizedType() {
+ Type tmp = parameterTypeCache;
+ if (null == tmp) {
+- tmp = executable.getGenericParameterTypes()[index];
++ tmp = executable.getAllGenericParameterTypes()[index];
+ parameterTypeCache = tmp;
+ }
+
+--- ./jdk/src/share/classes/java/math/MutableBigInteger.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/math/MutableBigInteger.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1261,19 +1261,20 @@
+ int sigma = (int) Math.max(0, n32 - b.bitLength()); // step 3: sigma = max{T | (2^T)*B < beta^n}
+ MutableBigInteger bShifted = new MutableBigInteger(b);
+ bShifted.safeLeftShift(sigma); // step 4a: shift b so its length is a multiple of n
+- safeLeftShift(sigma); // step 4b: shift this by the same amount
++ MutableBigInteger aShifted = new MutableBigInteger (this);
++ aShifted.safeLeftShift(sigma); // step 4b: shift a by the same amount
+
+- // step 5: t is the number of blocks needed to accommodate this plus one additional bit
+- int t = (int) ((bitLength()+n32) / n32);
++ // step 5: t is the number of blocks needed to accommodate a plus one additional bit
++ int t = (int) ((aShifted.bitLength()+n32) / n32);
+ if (t < 2) {
+ t = 2;
+ }
+
+- // step 6: conceptually split this into blocks a[t-1], ..., a[0]
+- MutableBigInteger a1 = getBlock(t-1, t, n); // the most significant block of this
++ // step 6: conceptually split a into blocks a[t-1], ..., a[0]
++ MutableBigInteger a1 = aShifted.getBlock(t-1, t, n); // the most significant block of a
+
+ // step 7: z[t-2] = [a[t-1], a[t-2]]
+- MutableBigInteger z = getBlock(t-2, t, n); // the second to most significant block
++ MutableBigInteger z = aShifted.getBlock(t-2, t, n); // the second to most significant block
+ z.addDisjoint(a1, n); // z[t-2]
+
+ // do schoolbook division on blocks, dividing 2-block numbers by 1-block numbers
+@@ -1284,7 +1285,7 @@
+ ri = z.divide2n1n(bShifted, qi);
+
+ // step 8b: z = [ri, a[i-1]]
+- z = getBlock(i-1, t, n); // a[i-1]
++ z = aShifted.getBlock(i-1, t, n); // a[i-1]
+ z.addDisjoint(ri, n);
+ quotient.addShifted(qi, i*n); // update q (part of step 9)
+ }
+@@ -1292,7 +1293,7 @@
+ ri = z.divide2n1n(bShifted, qi);
+ quotient.add(qi);
+
+- ri.rightShift(sigma); // step 9: this and b were shifted, so shift back
++ ri.rightShift(sigma); // step 9: a and b were shifted, so shift back
+ return ri;
+ }
+ }
+--- ./jdk/src/share/classes/java/net/SocketInputStream.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/net/SocketInputStream.java Wed Feb 04 12:14:43 2015 -0800
+@@ -96,6 +96,26 @@
+ int timeout)
+ throws IOException;
+
++ // wrap native call to allow instrumentation
++ /**
++ * Reads into an array of bytes at the specified offset using
++ * the received socket primitive.
++ * @param fd the FileDescriptor
++ * @param b the buffer into which the data is read
++ * @param off the start offset of the data
++ * @param len the maximum number of bytes read
++ * @param timeout the read timeout in ms
++ * @return the actual number of bytes read, -1 is
++ * returned when the end of the stream is reached.
++ * @exception IOException If an I/O error has occurred.
++ */
++ private int socketRead(FileDescriptor fd,
++ byte b[], int off, int len,
++ int timeout)
++ throws IOException {
++ return socketRead0(fd, b, off, len, timeout);
++ }
++
+ /**
+ * Reads into a byte array data from the socket.
+ * @param b the buffer into which the data is read
+@@ -147,7 +167,7 @@
+ // acquire file descriptor and do the read
+ FileDescriptor fd = impl.acquireFD();
+ try {
+- n = socketRead0(fd, b, off, length, timeout);
++ n = socketRead(fd, b, off, length, timeout);
+ if (n > 0) {
+ return n;
+ }
+@@ -165,7 +185,7 @@
+ impl.setConnectionResetPending();
+ impl.acquireFD();
+ try {
+- n = socketRead0(fd, b, off, length, timeout);
++ n = socketRead(fd, b, off, length, timeout);
+ if (n > 0) {
+ return n;
+ }
+--- ./jdk/src/share/classes/java/net/URI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/net/URI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -188,7 +188,7 @@
+ * URI
+ *
+ * <blockquote>
+- * {@code http://docs.oracle.com/javase/1.3/docs/guide/collections/designfaq.html#28}
++ * {@code https://docs.oracle.com/javase/1.3/docs/guide/collections/designfaq.html#28}
+ * </blockquote>
+ *
+ * Resolving the relative URI
+@@ -227,7 +227,7 @@
+ * possible. For example, relativizing the URI
+ *
+ * <blockquote>
+- * {@code http://docs.oracle.com/javase/1.3/docs/guide/index.html}
++ * {@code https://docs.oracle.com/javase/1.3/docs/guide/index.html}
+ * </blockquote>
+ *
+ * against the base URI
+--- ./jdk/src/share/classes/java/net/URLClassLoader.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/net/URLClassLoader.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -354,10 +354,11 @@
+ * @exception NullPointerException if {@code name} is {@code null}.
+ */
+ protected Class<?> findClass(final String name)
+- throws ClassNotFoundException
++ throws ClassNotFoundException
+ {
++ final Class<?> result;
+ try {
+- return AccessController.doPrivileged(
++ result = AccessController.doPrivileged(
+ new PrivilegedExceptionAction<Class<?>>() {
+ public Class<?> run() throws ClassNotFoundException {
+ String path = name.replace('.', '/').concat(".class");
+@@ -369,13 +370,17 @@
+ throw new ClassNotFoundException(name, e);
+ }
+ } else {
+- throw new ClassNotFoundException(name);
++ return null;
+ }
+ }
+ }, acc);
+ } catch (java.security.PrivilegedActionException pae) {
+ throw (ClassNotFoundException) pae.getException();
+ }
++ if (result == null) {
++ throw new ClassNotFoundException(name);
++ }
++ return result;
+ }
+
+ /*
+@@ -407,6 +412,29 @@
+ return pkg;
+ }
+
++ // Also called by VM to define Package for classes loaded from the CDS
++ // archive
++ private void definePackageInternal(String pkgname, Manifest man, URL url)
++ {
++ if (getAndVerifyPackage(pkgname, man, url) == null) {
++ try {
++ if (man != null) {
++ definePackage(pkgname, man, url);
++ } else {
++ definePackage(pkgname, null, null, null, null, null, null, null);
++ }
++ } catch (IllegalArgumentException iae) {
++ // parallel-capable class loaders: re-verify in case of a
++ // race condition
++ if (getAndVerifyPackage(pkgname, man, url) == null) {
++ // Should never happen
++ throw new AssertionError("Cannot find package " +
++ pkgname);
++ }
++ }
++ }
++ }
++
+ /*
+ * Defines a Class using the class bytes obtained from the specified
+ * Resource. The resulting Class must be resolved before it can be
+@@ -420,23 +448,7 @@
+ String pkgname = name.substring(0, i);
+ // Check if package already loaded.
+ Manifest man = res.getManifest();
+- if (getAndVerifyPackage(pkgname, man, url) == null) {
+- try {
+- if (man != null) {
+- definePackage(pkgname, man, url);
+- } else {
+- definePackage(pkgname, null, null, null, null, null, null, null);
+- }
+- } catch (IllegalArgumentException iae) {
+- // parallel-capable class loaders: re-verify in case of a
+- // race condition
+- if (getAndVerifyPackage(pkgname, man, url) == null) {
+- // Should never happen
+- throw new AssertionError("Cannot find package " +
+- pkgname);
+- }
+- }
+- }
++ definePackageInternal(pkgname, man, url);
+ }
+ // Now read the class bytes and define the class
+ java.nio.ByteBuffer bb = res.getByteBuffer();
+--- ./jdk/src/share/classes/java/security/KeyPairGenerator.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/security/KeyPairGenerator.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -33,6 +33,7 @@
+
+ import sun.security.jca.*;
+ import sun.security.jca.GetInstance.Instance;
++import sun.security.util.Debug;
+
+ /**
+ * The KeyPairGenerator class is used to generate pairs of
+@@ -126,6 +127,11 @@
+
+ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi {
+
++ private static final Debug pdebug =
++ Debug.getInstance("provider", "Provider");
++ private static final boolean skipDebug =
++ Debug.isOn("engine=") && !Debug.isOn("keypairgenerator");
++
+ private final String algorithm;
+
+ // The provider
+@@ -167,6 +173,12 @@
+ kpg = new Delegate(spi, algorithm);
+ }
+ kpg.provider = instance.provider;
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("KeyPairGenerator." + algorithm +
++ " algorithm from: " + kpg.provider.getName());
++ }
++
+ return kpg;
+ }
+
+@@ -557,6 +569,11 @@
+ provider = instance.provider;
+ this.serviceIterator = serviceIterator;
+ initType = I_NONE;
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("KeyPairGenerator." + algorithm +
++ " algorithm from: " + provider.getName());
++ }
+ }
+
+ /**
+--- ./jdk/src/share/classes/java/security/KeyStore.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/security/KeyStore.java Wed Feb 04 12:14:43 2015 -0800
+@@ -37,6 +37,8 @@
+ import javax.security.auth.DestroyFailedException;
+ import javax.security.auth.callback.*;
+
++import sun.security.util.Debug;
++
+ /**
+ * This class represents a storage facility for cryptographic
+ * keys and certificates.
+@@ -177,6 +179,11 @@
+
+ public class KeyStore {
+
++ private static final Debug pdebug =
++ Debug.getInstance("provider", "Provider");
++ private static final boolean skipDebug =
++ Debug.isOn("engine=") && !Debug.isOn("keystore");
++
+ /*
+ * Constant to lookup in the Security properties file to determine
+ * the default keystore type.
+@@ -801,6 +808,11 @@
+ this.keyStoreSpi = keyStoreSpi;
+ this.provider = provider;
+ this.type = type;
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("KeyStore." + type.toUpperCase() + " type from: " +
++ this.provider.getName());
++ }
+ }
+
+ /**
+--- ./jdk/src/share/classes/java/security/MessageDigest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/security/MessageDigest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -35,6 +35,8 @@
+
+ import java.nio.ByteBuffer;
+
++import sun.security.util.Debug;
++
+ /**
+ * This MessageDigest class provides applications the functionality of a
+ * message digest algorithm, such as SHA-1 or SHA-256.
+@@ -103,6 +105,11 @@
+
+ public abstract class MessageDigest extends MessageDigestSpi {
+
++ private static final Debug pdebug =
++ Debug.getInstance("provider", "Provider");
++ private static final boolean skipDebug =
++ Debug.isOn("engine=") && !Debug.isOn("messagedigest");
++
+ private String algorithm;
+
+ // The state of this digest
+@@ -156,18 +163,23 @@
+ public static MessageDigest getInstance(String algorithm)
+ throws NoSuchAlgorithmException {
+ try {
++ MessageDigest md;
+ Object[] objs = Security.getImpl(algorithm, "MessageDigest",
+ (String)null);
+ if (objs[0] instanceof MessageDigest) {
+- MessageDigest md = (MessageDigest)objs[0];
+- md.provider = (Provider)objs[1];
+- return md;
++ md = (MessageDigest)objs[0];
+ } else {
+- MessageDigest delegate =
+- new Delegate((MessageDigestSpi)objs[0], algorithm);
+- delegate.provider = (Provider)objs[1];
+- return delegate;
++ md = new Delegate((MessageDigestSpi)objs[0], algorithm);
+ }
++ md.provider = (Provider)objs[1];
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("MessageDigest." + algorithm +
++ " algorithm from: " + md.provider.getName());
++ }
++
++ return md;
++
+ } catch(NoSuchProviderException e) {
+ throw new NoSuchAlgorithmException(algorithm + " not found");
+ }
+--- ./jdk/src/share/classes/java/security/SecureRandom.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/security/SecureRandom.java Wed Feb 04 12:14:43 2015 -0800
+@@ -32,6 +32,7 @@
+
+ import sun.security.jca.*;
+ import sun.security.jca.GetInstance.Instance;
++import sun.security.util.Debug;
+
+ /**
+ * This class provides a cryptographically strong random number
+@@ -92,6 +93,11 @@
+
+ public class SecureRandom extends java.util.Random {
+
++ private static final Debug pdebug =
++ Debug.getInstance("provider", "Provider");
++ private static final boolean skipDebug =
++ Debug.isOn("engine=") && !Debug.isOn("securerandom");
++
+ /**
+ * The provider.
+ *
+@@ -234,6 +240,11 @@
+ this.secureRandomSpi = secureRandomSpi;
+ this.provider = provider;
+ this.algorithm = algorithm;
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("SecureRandom." + algorithm +
++ " algorithm from: " + this.provider.getName());
++ }
+ }
+
+ /**
+--- ./jdk/src/share/classes/java/security/Signature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/security/Signature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -121,6 +121,11 @@
+ private static final Debug debug =
+ Debug.getInstance("jca", "Signature");
+
++ private static final Debug pdebug =
++ Debug.getInstance("provider", "Provider");
++ private static final boolean skipDebug =
++ Debug.isOn("engine=") && !Debug.isOn("signature");
++
+ /*
+ * The algorithm for this signature object.
+ * This value is used to map an OID to the particular algorithm.
+@@ -451,6 +456,11 @@
+ throws InvalidKeyException {
+ engineInitVerify(publicKey);
+ state = VERIFY;
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("Signature." + algorithm +
++ " verification algorithm from: " + this.provider.getName());
++ }
+ }
+
+ /**
+@@ -495,6 +505,11 @@
+ PublicKey publicKey = certificate.getPublicKey();
+ engineInitVerify(publicKey);
+ state = VERIFY;
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("Signature." + algorithm +
++ " verification algorithm from: " + this.provider.getName());
++ }
+ }
+
+ /**
+@@ -511,6 +526,11 @@
+ throws InvalidKeyException {
+ engineInitSign(privateKey);
+ state = SIGN;
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("Signature." + algorithm +
++ " signing algorithm from: " + this.provider.getName());
++ }
+ }
+
+ /**
+@@ -529,6 +549,11 @@
+ throws InvalidKeyException {
+ engineInitSign(privateKey, random);
+ state = SIGN;
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("Signature." + algorithm +
++ " signing algorithm from: " + this.provider.getName());
++ }
+ }
+
+ /**
+--- ./jdk/src/share/classes/java/security/package-info.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/security/package-info.java Wed Feb 04 12:14:43 2015 -0800
+@@ -92,14 +92,14 @@
+ * </b></a></li>
+ *
+ * <li><b>keytool</b>
+- * (<a href="{@docRoot}/../technotes/tools/solaris/keytool.html">
++ * (<a href="{@docRoot}/../technotes/tools/unix/keytool.html">
+ * for Solaris/Linux</a>)
+ * (<a href="{@docRoot}/../technotes/tools/windows/keytool.html">
+ * for Windows</a>)
+ * </li>
+ *
+ * <li><b>jarsigner</b>
+- * (<a href="{@docRoot}/../technotes/tools/solaris/jarsigner.html">
++ * (<a href="{@docRoot}/../technotes/tools/unix/jarsigner.html">
+ * for Solaris/Linux</a>)
+ * (<a href="{@docRoot}/../technotes/tools/windows/jarsigner.html">
+ * for Windows</a>)
+--- ./jdk/src/share/classes/java/text/DecimalFormat.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/text/DecimalFormat.java Wed Feb 04 12:14:43 2015 -0800
+@@ -371,7 +371,7 @@
+ * }
+ * }</pre></blockquote>
+ *
+- * @see <a href="http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a>
+ * @see NumberFormat
+ * @see DecimalFormatSymbols
+ * @see ParsePosition
+--- ./jdk/src/share/classes/java/text/DigitList.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/text/DigitList.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -290,25 +290,26 @@
+
+ FloatingDecimal.BinaryToASCIIConverter fdConverter = FloatingDecimal.getBinaryToASCIIConverter(source);
+ boolean hasBeenRoundedUp = fdConverter.digitsRoundedUp();
+- boolean allDecimalDigits = fdConverter.decimalDigitsExact();
++ boolean valueExactAsDecimal = fdConverter.decimalDigitsExact();
+ assert !fdConverter.isExceptional();
+ String digitsString = fdConverter.toJavaFormatString();
+
+ set(isNegative, digitsString,
+- hasBeenRoundedUp, allDecimalDigits,
++ hasBeenRoundedUp, valueExactAsDecimal,
+ maximumDigits, fixedPoint);
+ }
+
+ /**
+ * Generate a representation of the form DDDDD, DDDDD.DDDDD, or
+ * DDDDDE+/-DDDDD.
+- * @param roundedUp Boolean value indicating if the s digits were rounded-up.
+- * @param allDecimalDigits Boolean value indicating if the digits in s are
+- * an exact decimal representation of the double that was passed.
++ * @param roundedUp whether or not rounding up has already happened.
++ * @param valueExactAsDecimal whether or not collected digits provide
++ * an exact decimal representation of the value.
+ */
+ private void set(boolean isNegative, String s,
+- boolean roundedUp, boolean allDecimalDigits,
++ boolean roundedUp, boolean valueExactAsDecimal,
+ int maximumDigits, boolean fixedPoint) {
++
+ this.isNegative = isNegative;
+ int len = s.length();
+ char[] source = getDataChars(len);
+@@ -361,7 +362,7 @@
+ } else if (-decimalAt == maximumDigits) {
+ // If we round 0.0009 to 3 fractional digits, then we have to
+ // create a new one digit in the least significant location.
+- if (shouldRoundUp(0, roundedUp, allDecimalDigits)) {
++ if (shouldRoundUp(0, roundedUp, valueExactAsDecimal)) {
+ count = 1;
+ ++decimalAt;
+ digits[0] = '1';
+@@ -381,25 +382,26 @@
+ // Eliminate digits beyond maximum digits to be displayed.
+ // Round up if appropriate.
+ round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits,
+- roundedUp, allDecimalDigits);
+- }
++ roundedUp, valueExactAsDecimal);
++
++ }
+
+ /**
+ * Round the representation to the given number of digits.
+ * @param maximumDigits The maximum number of digits to be shown.
+- * @param alreadyRounded Boolean indicating if rounding up already happened.
+- * @param allDecimalDigits Boolean indicating if the digits provide an exact
+- * representation of the value.
++ * @param alreadyRounded whether or not rounding up has already happened.
++ * @param valueExactAsDecimal whether or not collected digits provide
++ * an exact decimal representation of the value.
+ *
+ * Upon return, count will be less than or equal to maximumDigits.
+ */
+ private final void round(int maximumDigits,
+ boolean alreadyRounded,
+- boolean allDecimalDigits) {
++ boolean valueExactAsDecimal) {
+ // Eliminate digits beyond maximum digits to be displayed.
+ // Round up if appropriate.
+ if (maximumDigits >= 0 && maximumDigits < count) {
+- if (shouldRoundUp(maximumDigits, alreadyRounded, allDecimalDigits)) {
++ if (shouldRoundUp(maximumDigits, alreadyRounded, valueExactAsDecimal)) {
+ // Rounding up involved incrementing digits from LSD to MSD.
+ // In most cases this is simple, but in a worst case situation
+ // (9999..99) we have to adjust the decimalAt value.
+@@ -440,6 +442,9 @@
+ * <code>count-1</code>. If 0, then all digits are rounded away, and
+ * this method returns true if a one should be generated (e.g., formatting
+ * 0.09 with "#.#").
++ * @param alreadyRounded whether or not rounding up has already happened.
++ * @param valueExactAsDecimal whether or not collected digits provide
++ * an exact decimal representation of the value.
+ * @exception ArithmeticException if rounding is needed with rounding
+ * mode being set to RoundingMode.UNNECESSARY
+ * @return true if digit <code>maximumDigits-1</code> should be
+@@ -447,7 +452,7 @@
+ */
+ private boolean shouldRoundUp(int maximumDigits,
+ boolean alreadyRounded,
+- boolean allDecimalDigits) {
++ boolean valueExactAsDecimal) {
+ if (maximumDigits < count) {
+ /*
+ * To avoid erroneous double-rounding or truncation when converting
+@@ -460,7 +465,7 @@
+ * account what FloatingDecimal has done in the binary to decimal
+ * conversion.
+ *
+- * Considering the tie cases, FloatingDecimal may round-up the
++ * Considering the tie cases, FloatingDecimal may round up the
+ * value (returning decimal digits equal to tie when it is below),
+ * or "truncate" the value to the tie while value is above it,
+ * or provide the exact decimal digits when the binary value can be
+@@ -490,7 +495,7 @@
+ *
+ * - For other numbers that are always converted to exact digits
+ * (like BigInteger, Long, ...), the passed alreadyRounded boolean
+- * have to be set to false, and allDecimalDigits has to be set to
++ * have to be set to false, and valueExactAsDecimal has to be set to
+ * true in the upper DigitList call stack, providing the right state
+ * for those situations..
+ */
+@@ -520,42 +525,31 @@
+ }
+ break;
+ case HALF_UP:
+- if (digits[maximumDigits] >= '5') {
+- // We should not round up if the rounding digits position is
+- // exactly the last index and if digits were already rounded.
+- if ((maximumDigits == (count - 1)) &&
+- (alreadyRounded))
+- return false;
+-
+- // Value was exactly at or was above tie. We must round up.
+- return true;
+- }
+- break;
+ case HALF_DOWN:
+ if (digits[maximumDigits] > '5') {
++ // Value is above tie ==> must round up
+ return true;
+- } else if (digits[maximumDigits] == '5' ) {
+- if (maximumDigits == (count - 1)) {
+- // The rounding position is exactly the last index.
+- if (allDecimalDigits || alreadyRounded)
+- /* FloatingDecimal rounded up (value was below tie),
+- * or provided the exact list of digits (value was
+- * an exact tie). We should not round up, following
+- * the HALF_DOWN rounding rule.
+- */
+- return false;
+- else
+- // Value was above the tie, we must round up.
+- return true;
+- }
+-
+- // We must round up if it gives a non null digit after '5'.
+- for (int i=maximumDigits+1; i<count; ++i) {
+- if (digits[i] != '0') {
+- return true;
++ } else if (digits[maximumDigits] == '5') {
++ // Digit at rounding position is a '5'. Tie cases.
++ if (maximumDigits != (count - 1)) {
++ // There are remaining digits. Above tie => must round up
++ return true;
++ } else {
++ // Digit at rounding position is the last one !
++ if (valueExactAsDecimal) {
++ // Exact binary representation. On the tie.
++ // Apply rounding given by roundingMode.
++ return roundingMode == RoundingMode.HALF_UP;
++ } else {
++ // Not an exact binary representation.
++ // Digit sequence either rounded up or truncated.
++ // Round up only if it was truncated.
++ return !alreadyRounded;
+ }
+ }
+ }
++ // Digit at rounding position is < '5' ==> no round up.
++ // Just let do the default, which is no round up (thus break).
+ break;
+ case HALF_EVEN:
+ // Implement IEEE half-even rounding
+@@ -569,7 +563,7 @@
+ // then we should not round up again.
+ return false;
+
+- if (!allDecimalDigits)
++ if (!valueExactAsDecimal)
+ // Otherwise if the digits don't represent exact value,
+ // value was above tie and FloatingDecimal truncated
+ // digits to tie. We must round up.
+--- ./jdk/src/share/classes/java/text/SimpleDateFormat.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/text/SimpleDateFormat.java Wed Feb 04 12:14:43 2015 -0800
+@@ -411,7 +411,7 @@
+ * If multiple threads access a format concurrently, it must be synchronized
+ * externally.
+ *
+- * @see <a href="http://docs.oracle.com/javase/tutorial/i18n/format/simpleDateFormat.html">Java Tutorial</a>
++ * @see <a href="https://docs.oracle.com/javase/tutorial/i18n/format/simpleDateFormat.html">Java Tutorial</a>
+ * @see java.util.Calendar
+ * @see java.util.TimeZone
+ * @see DateFormat
+--- ./jdk/src/share/classes/java/time/chrono/JapaneseEra.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/time/chrono/JapaneseEra.java Wed Feb 04 12:14:43 2015 -0800
+@@ -127,7 +127,7 @@
+
+ // the number of defined JapaneseEra constants.
+ // There could be an extra era defined in its configuration.
+- private static final int N_ERA_CONSTANTS = HEISEI.getValue() + ERA_OFFSET + 1;
++ private static final int N_ERA_CONSTANTS = HEISEI.getValue() + ERA_OFFSET;
+
+ /**
+ * Serialization version.
+@@ -148,7 +148,7 @@
+ for (int i = N_ERA_CONSTANTS; i < ERA_CONFIG.length; i++) {
+ CalendarDate date = ERA_CONFIG[i].getSinceDate();
+ LocalDate isoDate = LocalDate.of(date.getYear(), date.getMonth(), date.getDayOfMonth());
+- KNOWN_ERAS[i] = new JapaneseEra(i - ERA_OFFSET, isoDate);
++ KNOWN_ERAS[i] = new JapaneseEra(i - ERA_OFFSET + 1, isoDate);
+ }
+ };
+
+@@ -195,7 +195,7 @@
+ * @throws DateTimeException if the value is invalid
+ */
+ public static JapaneseEra of(int japaneseEra) {
+- if (japaneseEra < MEIJI.eraValue || japaneseEra + ERA_OFFSET - 1 >= KNOWN_ERAS.length) {
++ if (japaneseEra < MEIJI.eraValue || japaneseEra + ERA_OFFSET > KNOWN_ERAS.length) {
+ throw new DateTimeException("Invalid era: " + japaneseEra);
+ }
+ return KNOWN_ERAS[ordinal(japaneseEra)];
+--- ./jdk/src/share/classes/java/util/BitSet.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/BitSet.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -696,6 +696,9 @@
+ * <pre> {@code
+ * for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
+ * // operate on index i here
++ * if (i == Integer.MAX_VALUE) {
++ * break; // or (i+1) would overflow
++ * }
+ * }}</pre>
+ *
+ * @param fromIndex the index to start checking from (inclusive)
+@@ -1186,10 +1189,12 @@
+ int i = nextSetBit(0);
+ if (i != -1) {
+ b.append(i);
+- for (i = nextSetBit(i+1); i >= 0; i = nextSetBit(i+1)) {
++ while (true) {
++ if (++i < 0) break;
++ if ((i = nextSetBit(i)) < 0) break;
+ int endOfRun = nextClearBit(i);
+ do { b.append(", ").append(i); }
+- while (++i < endOfRun);
++ while (++i != endOfRun);
+ }
+ }
+
+--- ./jdk/src/share/classes/java/util/Collections.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/Collections.java Wed Feb 04 12:14:43 2015 -0800
+@@ -2342,7 +2342,7 @@
+
+ public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
+ synchronized (mutex) {
+- return new SynchronizedNavigableSet<>(ns.tailSet(fromElement, inclusive));
++ return new SynchronizedNavigableSet<>(ns.tailSet(fromElement, inclusive), mutex);
+ }
+ }
+ }
+--- ./jdk/src/share/classes/java/util/IdentityHashMap.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/IdentityHashMap.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -25,7 +25,6 @@
+
+ package java.util;
+
+-import java.io.*;
+ import java.lang.reflect.Array;
+ import java.util.function.BiConsumer;
+ import java.util.function.BiFunction;
+@@ -74,7 +73,7 @@
+ * maximum size and the number of buckets is unspecified.
+ *
+ * <p>If the size of the map (the number of key-value mappings) sufficiently
+- * exceeds the expected maximum size, the number of buckets is increased
++ * exceeds the expected maximum size, the number of buckets is increased.
+ * Increasing the number of buckets ("rehashing") may be fairly expensive, so
+ * it pays to create identity hash maps with a sufficiently large expected
+ * maximum size. On the other hand, iteration over collection views requires
+@@ -160,6 +159,10 @@
+ * The maximum capacity, used if a higher value is implicitly specified
+ * by either of the constructors with arguments.
+ * MUST be a power of two <= 1<<29.
++ *
++ * In fact, the map can hold no more than MAXIMUM_CAPACITY-1 items
++ * because it has to have at least one slot with the key == null
++ * in order to avoid infinite loops in get(), put(), remove()
+ */
+ private static final int MAXIMUM_CAPACITY = 1 << 29;
+
+@@ -181,11 +184,6 @@
+ transient int modCount;
+
+ /**
+- * The next size value at which to resize (capacity * load factor).
+- */
+- private transient int threshold;
+-
+- /**
+ * Value representing null keys inside tables.
+ */
+ static final Object NULL_KEY = new Object();
+@@ -229,27 +227,18 @@
+ }
+
+ /**
+- * Returns the appropriate capacity for the specified expected maximum
+- * size. Returns the smallest power of two between MINIMUM_CAPACITY
+- * and MAXIMUM_CAPACITY, inclusive, that is greater than
+- * (3 * expectedMaxSize)/2, if such a number exists. Otherwise
+- * returns MAXIMUM_CAPACITY. If (3 * expectedMaxSize)/2 is negative, it
+- * is assumed that overflow has occurred, and MAXIMUM_CAPACITY is returned.
++ * Returns the appropriate capacity for the given expected maximum size.
++ * Returns the smallest power of two between MINIMUM_CAPACITY and
++ * MAXIMUM_CAPACITY, inclusive, that is greater than (3 *
++ * expectedMaxSize)/2, if such a number exists. Otherwise returns
++ * MAXIMUM_CAPACITY.
+ */
+- private int capacity(int expectedMaxSize) {
+- // Compute min capacity for expectedMaxSize given a load factor of 2/3
+- int minCapacity = (3 * expectedMaxSize)/2;
+-
+- // Compute the appropriate capacity
+- int result;
+- if (minCapacity > MAXIMUM_CAPACITY || minCapacity < 0) {
+- result = MAXIMUM_CAPACITY;
+- } else {
+- result = MINIMUM_CAPACITY;
+- while (result < minCapacity)
+- result <<= 1;
+- }
+- return result;
++ private static int capacity(int expectedMaxSize) {
++ // assert expectedMaxSize >= 0;
++ return
++ (expectedMaxSize > MAXIMUM_CAPACITY / 3) ? MAXIMUM_CAPACITY :
++ (expectedMaxSize <= 2 * MINIMUM_CAPACITY / 3) ? MINIMUM_CAPACITY :
++ Integer.highestOneBit(expectedMaxSize + (expectedMaxSize << 1));
+ }
+
+ /**
+@@ -262,7 +251,6 @@
+ // assert initCapacity >= MINIMUM_CAPACITY;
+ // assert initCapacity <= MAXIMUM_CAPACITY;
+
+- threshold = (initCapacity * 2)/3;
+ table = new Object[2 * initCapacity];
+ }
+
+@@ -429,52 +417,58 @@
+ * @see #containsKey(Object)
+ */
+ public V put(K key, V value) {
+- Object k = maskNull(key);
+- Object[] tab = table;
+- int len = tab.length;
+- int i = hash(k, len);
++ final Object k = maskNull(key);
+
+- Object item;
+- while ( (item = tab[i]) != null) {
+- if (item == k) {
+- @SuppressWarnings("unchecked")
+- V oldValue = (V) tab[i + 1];
+- tab[i + 1] = value;
+- return oldValue;
++ retryAfterResize: for (;;) {
++ final Object[] tab = table;
++ final int len = tab.length;
++ int i = hash(k, len);
++
++ for (Object item; (item = tab[i]) != null;
++ i = nextKeyIndex(i, len)) {
++ if (item == k) {
++ @SuppressWarnings("unchecked")
++ V oldValue = (V) tab[i + 1];
++ tab[i + 1] = value;
++ return oldValue;
++ }
+ }
+- i = nextKeyIndex(i, len);
++
++ final int s = size + 1;
++ // Use optimized form of 3 * s.
++ // Next capacity is len, 2 * current capacity.
++ if (s + (s << 1) > len && resize(len))
++ continue retryAfterResize;
++
++ modCount++;
++ tab[i] = k;
++ tab[i + 1] = value;
++ size = s;
++ return null;
+ }
+-
+- modCount++;
+- tab[i] = k;
+- tab[i + 1] = value;
+- if (++size >= threshold)
+- resize(len); // len == 2 * current capacity.
+- return null;
+ }
+
+ /**
+- * Resize the table to hold given capacity.
++ * Resizes the table if necessary to hold given capacity.
+ *
+ * @param newCapacity the new capacity, must be a power of two.
++ * @return whether a resize did in fact take place
+ */
+- private void resize(int newCapacity) {
++ private boolean resize(int newCapacity) {
+ // assert (newCapacity & -newCapacity) == newCapacity; // power of 2
+ int newLength = newCapacity * 2;
+
+ Object[] oldTable = table;
+ int oldLength = oldTable.length;
+- if (oldLength == 2*MAXIMUM_CAPACITY) { // can't expand any further
+- if (threshold == MAXIMUM_CAPACITY-1)
++ if (oldLength == 2 * MAXIMUM_CAPACITY) { // can't expand any further
++ if (size == MAXIMUM_CAPACITY - 1)
+ throw new IllegalStateException("Capacity exhausted.");
+- threshold = MAXIMUM_CAPACITY-1; // Gigantic map!
+- return;
++ return false;
+ }
+ if (oldLength >= newLength)
+- return;
++ return false;
+
+ Object[] newTable = new Object[newLength];
+- threshold = newLength / 3;
+
+ for (int j = 0; j < oldLength; j += 2) {
+ Object key = oldTable[j];
+@@ -490,6 +484,7 @@
+ }
+ }
+ table = newTable;
++ return true;
+ }
+
+ /**
+@@ -504,8 +499,8 @@
+ int n = m.size();
+ if (n == 0)
+ return;
+- if (n > threshold) // conservatively pre-expand
+- resize(capacity(n));
++ if (n > size)
++ resize(capacity(n)); // conservatively pre-expand
+
+ for (Entry<? extends K, ? extends V> e : m.entrySet())
+ put(e.getKey(), e.getValue());
+@@ -542,7 +537,6 @@
+ return null;
+ i = nextKeyIndex(i, len);
+ }
+-
+ }
+
+ /**
+@@ -1266,8 +1260,8 @@
+ private static final long serialVersionUID = 8188218128353913216L;
+
+ /**
+- * Save the state of the <tt>IdentityHashMap</tt> instance to a stream
+- * (i.e., serialize it).
++ * Saves the state of the <tt>IdentityHashMap</tt> instance to a stream
++ * (i.e., serializes it).
+ *
+ * @serialData The <i>size</i> of the HashMap (the number of key-value
+ * mappings) (<tt>int</tt>), followed by the key (Object) and
+@@ -1295,8 +1289,8 @@
+ }
+
+ /**
+- * Reconstitute the <tt>IdentityHashMap</tt> instance from a stream (i.e.,
+- * deserialize it).
++ * Reconstitutes the <tt>IdentityHashMap</tt> instance from a stream (i.e.,
++ * deserializes it).
+ */
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+@@ -1305,9 +1299,10 @@
+
+ // Read in size (number of Mappings)
+ int size = s.readInt();
+-
+- // Allow for 33% growth (i.e., capacity is >= 2* size()).
+- init(capacity((size*4)/3));
++ if (size < 0)
++ throw new java.io.StreamCorruptedException
++ ("Illegal mappings count: " + size);
++ init(capacity(size));
+
+ // Read the keys and values, and put the mappings in the table
+ for (int i=0; i<size; i++) {
+@@ -1324,7 +1319,7 @@
+ * update modCount, etc.
+ */
+ private void putForCreate(K key, V value)
+- throws IOException
++ throws java.io.StreamCorruptedException
+ {
+ Object k = maskNull(key);
+ Object[] tab = table;
+--- ./jdk/src/share/classes/java/util/SplittableRandom.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/SplittableRandom.java Wed Feb 04 12:14:43 2015 -0800
+@@ -25,7 +25,6 @@
+
+ package java.util;
+
+-import java.net.NetworkInterface;
+ import java.util.concurrent.atomic.AtomicLong;
+ import java.util.function.IntConsumer;
+ import java.util.function.LongConsumer;
+@@ -140,11 +139,10 @@
+ * other cases, this split must be performed in a thread-safe
+ * manner, so we use an AtomicLong to represent the seed rather
+ * than use an explicit SplittableRandom. To bootstrap the
+- * defaultGen, we start off using a seed based on current time and
+- * network interface address unless the java.util.secureRandomSeed
+- * property is set. This serves as a slimmed-down (and insecure)
+- * variant of SecureRandom that also avoids stalls that may occur
+- * when using /dev/random.
++ * defaultGen, we start off using a seed based on current time
++ * unless the java.util.secureRandomSeed property is set. This
++ * serves as a slimmed-down (and insecure) variant of SecureRandom
++ * that also avoids stalls that may occur when using /dev/random.
+ *
+ * It is a relatively simple matter to apply the basic design here
+ * to use 128 bit seeds. However, emulating 128bit arithmetic and
+@@ -237,34 +235,7 @@
+ s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
+ return s;
+ }
+- long h = 0L;
+- try {
+- Enumeration<NetworkInterface> ifcs =
+- NetworkInterface.getNetworkInterfaces();
+- boolean retry = false; // retry once if getHardwareAddress is null
+- while (ifcs.hasMoreElements()) {
+- NetworkInterface ifc = ifcs.nextElement();
+- if (!ifc.isVirtual()) { // skip fake addresses
+- byte[] bs = ifc.getHardwareAddress();
+- if (bs != null) {
+- int n = bs.length;
+- int m = Math.min(n >>> 1, 4);
+- for (int i = 0; i < m; ++i)
+- h = (h << 16) ^ (bs[i] << 8) ^ bs[n-1-i];
+- if (m < 4)
+- h = (h << 8) ^ bs[n-1-m];
+- h = mix64(h);
+- break;
+- }
+- else if (!retry)
+- retry = true;
+- else
+- break;
+- }
+- }
+- } catch (Exception ignore) {
+- }
+- return (h ^ mix64(System.currentTimeMillis()) ^
++ return (mix64(System.currentTimeMillis()) ^
+ mix64(System.nanoTime()));
+ }
+
+--- ./jdk/src/share/classes/java/util/TimeZone.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/TimeZone.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -591,8 +591,7 @@
+ /**
+ * Gets the platform defined TimeZone ID.
+ **/
+- private static native String getSystemTimeZoneID(String javaHome,
+- String country);
++ private static native String getSystemTimeZoneID(String javaHome);
+
+ /**
+ * Gets the custom time zone ID based on the GMT offset of the
+@@ -650,12 +649,10 @@
+ // if the time zone ID is not set (yet), perform the
+ // platform to Java time zone ID mapping.
+ if (zoneID == null || zoneID.isEmpty()) {
+- String country = AccessController.doPrivileged(
+- new GetPropertyAction("user.country"));
+ String javaHome = AccessController.doPrivileged(
+ new GetPropertyAction("java.home"));
+ try {
+- zoneID = getSystemTimeZoneID(javaHome, country);
++ zoneID = getSystemTimeZoneID(javaHome);
+ if (zoneID == null) {
+ zoneID = GMT_ID;
+ }
+--- ./jdk/src/share/classes/java/util/concurrent/CompletableFuture.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/concurrent/CompletableFuture.java Wed Feb 04 12:14:43 2015 -0800
+@@ -50,7 +50,6 @@
+ import java.util.concurrent.CancellationException;
+ import java.util.concurrent.CompletionException;
+ import java.util.concurrent.CompletionStage;
+-import java.util.concurrent.atomic.AtomicInteger;
+ import java.util.concurrent.locks.LockSupport;
+
+ /**
+@@ -77,9 +76,9 @@
+ * <li>All <em>async</em> methods without an explicit Executor
+ * argument are performed using the {@link ForkJoinPool#commonPool()}
+ * (unless it does not support a parallelism level of at least two, in
+- * which case, a new Thread is used). To simplify monitoring,
+- * debugging, and tracking, all generated asynchronous tasks are
+- * instances of the marker interface {@link
++ * which case, a new Thread is created to run each task). To simplify
++ * monitoring, debugging, and tracking, all generated asynchronous
++ * tasks are instances of the marker interface {@link
+ * AsynchronousCompletionTask}. </li>
+ *
+ * <li>All CompletionStage methods are implemented independently of
+@@ -113,141 +112,1556 @@
+ /*
+ * Overview:
+ *
+- * 1. Non-nullness of field result (set via CAS) indicates done.
+- * An AltResult is used to box null as a result, as well as to
+- * hold exceptions. Using a single field makes completion fast
+- * and simple to detect and trigger, at the expense of a lot of
+- * encoding and decoding that infiltrates many methods. One minor
+- * simplification relies on the (static) NIL (to box null results)
+- * being the only AltResult with a null exception field, so we
+- * don't usually need explicit comparisons with NIL. The CF
+- * exception propagation mechanics surrounding decoding rely on
+- * unchecked casts of decoded results really being unchecked,
+- * where user type errors are caught at point of use, as is
+- * currently the case in Java. These are highlighted by using
+- * SuppressWarnings-annotated temporaries.
++ * A CompletableFuture may have dependent completion actions,
++ * collected in a linked stack. It atomically completes by CASing
++ * a result field, and then pops off and runs those actions. This
++ * applies across normal vs exceptional outcomes, sync vs async
++ * actions, binary triggers, and various forms of completions.
+ *
+- * 2. Waiters are held in a Treiber stack similar to the one used
+- * in FutureTask, Phaser, and SynchronousQueue. See their
+- * internal documentation for algorithmic details.
++ * Non-nullness of field result (set via CAS) indicates done. An
++ * AltResult is used to box null as a result, as well as to hold
++ * exceptions. Using a single field makes completion simple to
++ * detect and trigger. Encoding and decoding is straightforward
++ * but adds to the sprawl of trapping and associating exceptions
++ * with targets. Minor simplifications rely on (static) NIL (to
++ * box null results) being the only AltResult with a null
++ * exception field, so we don't usually need explicit comparisons.
++ * Even though some of the generics casts are unchecked (see
++ * SuppressWarnings annotations), they are placed to be
++ * appropriate even if checked.
+ *
+- * 3. Completions are also kept in a list/stack, and pulled off
+- * and run when completion is triggered. (We could even use the
+- * same stack as for waiters, but would give up the potential
+- * parallelism obtained because woken waiters help release/run
+- * others -- see method postComplete). Because post-processing
+- * may race with direct calls, class Completion opportunistically
+- * extends AtomicInteger so callers can claim the action via
+- * compareAndSet(0, 1). The Completion.run methods are all
+- * written a boringly similar uniform way (that sometimes includes
+- * unnecessary-looking checks, kept to maintain uniformity).
+- * There are enough dimensions upon which they differ that
+- * attempts to factor commonalities while maintaining efficiency
+- * require more lines of code than they would save.
++ * Dependent actions are represented by Completion objects linked
++ * as Treiber stacks headed by field "stack". There are Completion
++ * classes for each kind of action, grouped into single-input
++ * (UniCompletion), two-input (BiCompletion), projected
++ * (BiCompletions using either (not both) of two inputs), shared
++ * (CoCompletion, used by the second of two sources), zero-input
++ * source actions, and Signallers that unblock waiters. Class
++ * Completion extends ForkJoinTask to enable async execution
++ * (adding no space overhead because we exploit its "tag" methods
++ * to maintain claims). It is also declared as Runnable to allow
++ * usage with arbitrary executors.
+ *
+- * 4. The exported then/and/or methods do support a bit of
+- * factoring (see doThenApply etc). They must cope with the
+- * intrinsic races surrounding addition of a dependent action
+- * versus performing the action directly because the task is
+- * already complete. For example, a CF may not be complete upon
+- * entry, so a dependent completion is added, but by the time it
+- * is added, the target CF is complete, so must be directly
+- * executed. This is all done while avoiding unnecessary object
+- * construction in safe-bypass cases.
++ * Support for each kind of CompletionStage relies on a separate
++ * class, along with two CompletableFuture methods:
++ *
++ * * A Completion class with name X corresponding to function,
++ * prefaced with "Uni", "Bi", or "Or". Each class contains
++ * fields for source(s), actions, and dependent. They are
++ * boringly similar, differing from others only with respect to
++ * underlying functional forms. We do this so that users don't
++ * encounter layers of adaptors in common usages. We also
++ * include "Relay" classes/methods that don't correspond to user
++ * methods; they copy results from one stage to another.
++ *
++ * * Boolean CompletableFuture method x(...) (for example
++ * uniApply) takes all of the arguments needed to check that an
++ * action is triggerable, and then either runs the action or
++ * arranges its async execution by executing its Completion
++ * argument, if present. The method returns true if known to be
++ * complete.
++ *
++ * * Completion method tryFire(int mode) invokes the associated x
++ * method with its held arguments, and on success cleans up.
++ * The mode argument allows tryFire to be called twice (SYNC,
++ * then ASYNC); the first to screen and trap exceptions while
++ * arranging to execute, and the second when called from a
++ * task. (A few classes are not used async so take slightly
++ * different forms.) The claim() callback suppresses function
++ * invocation if already claimed by another thread.
++ *
++ * * CompletableFuture method xStage(...) is called from a public
++ * stage method of CompletableFuture x. It screens user
++ * arguments and invokes and/or creates the stage object. If
++ * not async and x is already complete, the action is run
++ * immediately. Otherwise a Completion c is created, pushed to
++ * x's stack (unless done), and started or triggered via
++ * c.tryFire. This also covers races possible if x completes
++ * while pushing. Classes with two inputs (for example BiApply)
++ * deal with races across both while pushing actions. The
++ * second completion is a CoCompletion pointing to the first,
++ * shared so that at most one performs the action. The
++ * multiple-arity methods allOf and anyOf do this pairwise to
++ * form trees of completions.
++ *
++ * Note that the generic type parameters of methods vary according
++ * to whether "this" is a source, dependent, or completion.
++ *
++ * Method postComplete is called upon completion unless the target
++ * is guaranteed not to be observable (i.e., not yet returned or
++ * linked). Multiple threads can call postComplete, which
++ * atomically pops each dependent action, and tries to trigger it
++ * via method tryFire, in NESTED mode. Triggering can propagate
++ * recursively, so NESTED mode returns its completed dependent (if
++ * one exists) for further processing by its caller (see method
++ * postFire).
++ *
++ * Blocking methods get() and join() rely on Signaller Completions
++ * that wake up waiting threads. The mechanics are similar to
++ * Treiber stack wait-nodes used in FutureTask, Phaser, and
++ * SynchronousQueue. See their internal documentation for
++ * algorithmic details.
++ *
++ * Without precautions, CompletableFutures would be prone to
++ * garbage accumulation as chains of Completions build up, each
++ * pointing back to its sources. So we null out fields as soon as
++ * possible (see especially method Completion.detach). The
++ * screening checks needed anyway harmlessly ignore null arguments
++ * that may have been obtained during races with threads nulling
++ * out fields. We also try to unlink fired Completions from
++ * stacks that might never be popped (see method postFire).
++ * Completion fields need not be declared as final or volatile
++ * because they are only visible to other threads upon safe
++ * publication.
+ */
+
+- // preliminaries
++ volatile Object result; // Either the result or boxed AltResult
++ volatile Completion stack; // Top of Treiber stack of dependent actions
+
+- static final class AltResult {
+- final Throwable ex; // null only for NIL
+- AltResult(Throwable ex) { this.ex = ex; }
++ final boolean internalComplete(Object r) { // CAS from null to r
++ return UNSAFE.compareAndSwapObject(this, RESULT, null, r);
+ }
+
++ final boolean casStack(Completion cmp, Completion val) {
++ return UNSAFE.compareAndSwapObject(this, STACK, cmp, val);
++ }
++
++ /** Returns true if successfully pushed c onto stack. */
++ final boolean tryPushStack(Completion c) {
++ Completion h = stack;
++ lazySetNext(c, h);
++ return UNSAFE.compareAndSwapObject(this, STACK, h, c);
++ }
++
++ /** Unconditionally pushes c onto stack, retrying if necessary. */
++ final void pushStack(Completion c) {
++ do {} while (!tryPushStack(c));
++ }
++
++ /* ------------- Encoding and decoding outcomes -------------- */
++
++ static final class AltResult { // See above
++ final Throwable ex; // null only for NIL
++ AltResult(Throwable x) { this.ex = x; }
++ }
++
++ /** The encoding of the null value. */
+ static final AltResult NIL = new AltResult(null);
+
+- // Fields
++ /** Completes with the null value, unless already completed. */
++ final boolean completeNull() {
++ return UNSAFE.compareAndSwapObject(this, RESULT, null,
++ NIL);
++ }
+
+- volatile Object result; // Either the result or boxed AltResult
+- volatile WaitNode waiters; // Treiber stack of threads blocked on get()
+- volatile CompletionNode completions; // list (Treiber stack) of completions
++ /** Returns the encoding of the given non-exceptional value. */
++ final Object encodeValue(T t) {
++ return (t == null) ? NIL : t;
++ }
+
+- // Basic utilities for triggering and processing completions
++ /** Completes with a non-exceptional result, unless already completed. */
++ final boolean completeValue(T t) {
++ return UNSAFE.compareAndSwapObject(this, RESULT, null,
++ (t == null) ? NIL : t);
++ }
+
+ /**
+- * Removes and signals all waiting threads and runs all completions.
++ * Returns the encoding of the given (non-null) exception as a
++ * wrapped CompletionException unless it is one already.
++ */
++ static AltResult encodeThrowable(Throwable x) {
++ return new AltResult((x instanceof CompletionException) ? x :
++ new CompletionException(x));
++ }
++
++ /** Completes with an exceptional result, unless already completed. */
++ final boolean completeThrowable(Throwable x) {
++ return UNSAFE.compareAndSwapObject(this, RESULT, null,
++ encodeThrowable(x));
++ }
++
++ /**
++ * Returns the encoding of the given (non-null) exception as a
++ * wrapped CompletionException unless it is one already. May
++ * return the given Object r (which must have been the result of a
++ * source future) if it is equivalent, i.e. if this is a simple
++ * relay of an existing CompletionException.
++ */
++ static Object encodeThrowable(Throwable x, Object r) {
++ if (!(x instanceof CompletionException))
++ x = new CompletionException(x);
++ else if (r instanceof AltResult && x == ((AltResult)r).ex)
++ return r;
++ return new AltResult(x);
++ }
++
++ /**
++ * Completes with the given (non-null) exceptional result as a
++ * wrapped CompletionException unless it is one already, unless
++ * already completed. May complete with the given Object r
++ * (which must have been the result of a source future) if it is
++ * equivalent, i.e. if this is a simple propagation of an
++ * existing CompletionException.
++ */
++ final boolean completeThrowable(Throwable x, Object r) {
++ return UNSAFE.compareAndSwapObject(this, RESULT, null,
++ encodeThrowable(x, r));
++ }
++
++ /**
++ * Returns the encoding of the given arguments: if the exception
++ * is non-null, encodes as AltResult. Otherwise uses the given
++ * value, boxed as NIL if null.
++ */
++ Object encodeOutcome(T t, Throwable x) {
++ return (x == null) ? (t == null) ? NIL : t : encodeThrowable(x);
++ }
++
++ /**
++ * Returns the encoding of a copied outcome; if exceptional,
++ * rewraps as a CompletionException, else returns argument.
++ */
++ static Object encodeRelay(Object r) {
++ Throwable x;
++ return (((r instanceof AltResult) &&
++ (x = ((AltResult)r).ex) != null &&
++ !(x instanceof CompletionException)) ?
++ new AltResult(new CompletionException(x)) : r);
++ }
++
++ /**
++ * Completes with r or a copy of r, unless already completed.
++ * If exceptional, r is first coerced to a CompletionException.
++ */
++ final boolean completeRelay(Object r) {
++ return UNSAFE.compareAndSwapObject(this, RESULT, null,
++ encodeRelay(r));
++ }
++
++ /**
++ * Reports result using Future.get conventions.
++ */
++ private static <T> T reportGet(Object r)
++ throws InterruptedException, ExecutionException {
++ if (r == null) // by convention below, null means interrupted
++ throw new InterruptedException();
++ if (r instanceof AltResult) {
++ Throwable x, cause;
++ if ((x = ((AltResult)r).ex) == null)
++ return null;
++ if (x instanceof CancellationException)
++ throw (CancellationException)x;
++ if ((x instanceof CompletionException) &&
++ (cause = x.getCause()) != null)
++ x = cause;
++ throw new ExecutionException(x);
++ }
++ @SuppressWarnings("unchecked") T t = (T) r;
++ return t;
++ }
++
++ /**
++ * Decodes outcome to return result or throw unchecked exception.
++ */
++ private static <T> T reportJoin(Object r) {
++ if (r instanceof AltResult) {
++ Throwable x;
++ if ((x = ((AltResult)r).ex) == null)
++ return null;
++ if (x instanceof CancellationException)
++ throw (CancellationException)x;
++ if (x instanceof CompletionException)
++ throw (CompletionException)x;
++ throw new CompletionException(x);
++ }
++ @SuppressWarnings("unchecked") T t = (T) r;
++ return t;
++ }
++
++ /* ------------- Async task preliminaries -------------- */
++
++ /**
++ * A marker interface identifying asynchronous tasks produced by
++ * {@code async} methods. This may be useful for monitoring,
++ * debugging, and tracking asynchronous activities.
++ *
++ * @since 1.8
++ */
++ public static interface AsynchronousCompletionTask {
++ }
++
++ private static final boolean useCommonPool =
++ (ForkJoinPool.getCommonPoolParallelism() > 1);
++
++ /**
++ * Default executor -- ForkJoinPool.commonPool() unless it cannot
++ * support parallelism.
++ */
++ private static final Executor asyncPool = useCommonPool ?
++ ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();
++
++ /** Fallback if ForkJoinPool.commonPool() cannot support parallelism */
++ static final class ThreadPerTaskExecutor implements Executor {
++ public void execute(Runnable r) { new Thread(r).start(); }
++ }
++
++ /**
++ * Null-checks user executor argument, and translates uses of
++ * commonPool to asyncPool in case parallelism disabled.
++ */
++ static Executor screenExecutor(Executor e) {
++ if (!useCommonPool && e == ForkJoinPool.commonPool())
++ return asyncPool;
++ if (e == null) throw new NullPointerException();
++ return e;
++ }
++
++ // Modes for Completion.tryFire. Signedness matters.
++ static final int SYNC = 0;
++ static final int ASYNC = 1;
++ static final int NESTED = -1;
++
++ /* ------------- Base Completion classes and operations -------------- */
++
++ @SuppressWarnings("serial")
++ abstract static class Completion extends ForkJoinTask<Void>
++ implements Runnable, AsynchronousCompletionTask {
++ volatile Completion next; // Treiber stack link
++
++ /**
++ * Performs completion action if triggered, returning a
++ * dependent that may need propagation, if one exists.
++ *
++ * @param mode SYNC, ASYNC, or NESTED
++ */
++ abstract CompletableFuture<?> tryFire(int mode);
++
++ /** Returns true if possibly still triggerable. Used by cleanStack. */
++ abstract boolean isLive();
++
++ public final void run() { tryFire(ASYNC); }
++ public final boolean exec() { tryFire(ASYNC); return true; }
++ public final Void getRawResult() { return null; }
++ public final void setRawResult(Void v) {}
++ }
++
++ static void lazySetNext(Completion c, Completion next) {
++ UNSAFE.putOrderedObject(c, NEXT, next);
++ }
++
++ /**
++ * Pops and tries to trigger all reachable dependents. Call only
++ * when known to be done.
+ */
+ final void postComplete() {
+- WaitNode q; Thread t;
+- while ((q = waiters) != null) {
+- if (UNSAFE.compareAndSwapObject(this, WAITERS, q, q.next) &&
+- (t = q.thread) != null) {
+- q.thread = null;
+- LockSupport.unpark(t);
++ /*
++ * On each step, variable f holds current dependents to pop
++ * and run. It is extended along only one path at a time,
++ * pushing others to avoid unbounded recursion.
++ */
++ CompletableFuture<?> f = this; Completion h;
++ while ((h = f.stack) != null ||
++ (f != this && (h = (f = this).stack) != null)) {
++ CompletableFuture<?> d; Completion t;
++ if (f.casStack(h, t = h.next)) {
++ if (t != null) {
++ if (f != this) {
++ pushStack(h);
++ continue;
++ }
++ h.next = null; // detach
++ }
++ f = (d = h.tryFire(NESTED)) == null ? this : d;
+ }
+ }
++ }
+
+- CompletionNode h; Completion c;
+- while ((h = completions) != null) {
+- if (UNSAFE.compareAndSwapObject(this, COMPLETIONS, h, h.next) &&
+- (c = h.completion) != null)
+- c.run();
++ /** Traverses stack and unlinks dead Completions. */
++ final void cleanStack() {
++ for (Completion p = null, q = stack; q != null;) {
++ Completion s = q.next;
++ if (q.isLive()) {
++ p = q;
++ q = s;
++ }
++ else if (p == null) {
++ casStack(q, s);
++ q = stack;
++ }
++ else {
++ p.next = s;
++ if (p.isLive())
++ q = s;
++ else {
++ p = null; // restart
++ q = stack;
++ }
++ }
++ }
++ }
++
++ /* ------------- One-input Completions -------------- */
++
++ /** A Completion with a source, dependent, and executor. */
++ @SuppressWarnings("serial")
++ abstract static class UniCompletion<T,V> extends Completion {
++ Executor executor; // executor to use (null if none)
++ CompletableFuture<V> dep; // the dependent to complete
++ CompletableFuture<T> src; // source for action
++
++ UniCompletion(Executor executor, CompletableFuture<V> dep,
++ CompletableFuture<T> src) {
++ this.executor = executor; this.dep = dep; this.src = src;
++ }
++
++ /**
++ * Returns true if action can be run. Call only when known to
++ * be triggerable. Uses FJ tag bit to ensure that only one
++ * thread claims ownership. If async, starts as task -- a
++ * later call to tryFire will run action.
++ */
++ final boolean claim() {
++ Executor e = executor;
++ if (compareAndSetForkJoinTaskTag((short)0, (short)1)) {
++ if (e == null)
++ return true;
++ executor = null; // disable
++ e.execute(this);
++ }
++ return false;
++ }
++
++ final boolean isLive() { return dep != null; }
++ }
++
++ /** Pushes the given completion (if it exists) unless done. */
++ final void push(UniCompletion<?,?> c) {
++ if (c != null) {
++ while (result == null && !tryPushStack(c))
++ lazySetNext(c, null); // clear on failure
+ }
+ }
+
+ /**
+- * Triggers completion with the encoding of the given arguments:
+- * if the exception is non-null, encodes it as a wrapped
+- * CompletionException unless it is one already. Otherwise uses
+- * the given result, boxed as NIL if null.
++ * Post-processing by dependent after successful UniCompletion
++ * tryFire. Tries to clean stack of source a, and then either runs
++ * postComplete or returns this to caller, depending on mode.
+ */
+- final void internalComplete(T v, Throwable ex) {
+- if (result == null)
+- UNSAFE.compareAndSwapObject
+- (this, RESULT, null,
+- (ex == null) ? (v == null) ? NIL : v :
+- new AltResult((ex instanceof CompletionException) ? ex :
+- new CompletionException(ex)));
+- postComplete(); // help out even if not triggered
++ final CompletableFuture<T> postFire(CompletableFuture<?> a, int mode) {
++ if (a != null && a.stack != null) {
++ if (mode < 0 || a.result == null)
++ a.cleanStack();
++ else
++ a.postComplete();
++ }
++ if (result != null && stack != null) {
++ if (mode < 0)
++ return this;
++ else
++ postComplete();
++ }
++ return null;
+ }
+
+- /**
+- * If triggered, helps release and/or process completions.
+- */
+- final void helpPostComplete() {
+- if (result != null)
+- postComplete();
++ @SuppressWarnings("serial")
++ static final class UniApply<T,V> extends UniCompletion<T,V> {
++ Function<? super T,? extends V> fn;
++ UniApply(Executor executor, CompletableFuture<V> dep,
++ CompletableFuture<T> src,
++ Function<? super T,? extends V> fn) {
++ super(executor, dep, src); this.fn = fn;
++ }
++ final CompletableFuture<V> tryFire(int mode) {
++ CompletableFuture<V> d; CompletableFuture<T> a;
++ if ((d = dep) == null ||
++ !d.uniApply(a = src, fn, mode > 0 ? null : this))
++ return null;
++ dep = null; src = null; fn = null;
++ return d.postFire(a, mode);
++ }
+ }
+
+- /* ------------- waiting for completions -------------- */
++ final <S> boolean uniApply(CompletableFuture<S> a,
++ Function<? super S,? extends T> f,
++ UniApply<S,T> c) {
++ Object r; Throwable x;
++ if (a == null || (r = a.result) == null || f == null)
++ return false;
++ tryComplete: if (result == null) {
++ if (r instanceof AltResult) {
++ if ((x = ((AltResult)r).ex) != null) {
++ completeThrowable(x, r);
++ break tryComplete;
++ }
++ r = null;
++ }
++ try {
++ if (c != null && !c.claim())
++ return false;
++ @SuppressWarnings("unchecked") S s = (S) r;
++ completeValue(f.apply(s));
++ } catch (Throwable ex) {
++ completeThrowable(ex);
++ }
++ }
++ return true;
++ }
+
+- /** Number of processors, for spin control */
+- static final int NCPU = Runtime.getRuntime().availableProcessors();
++ private <V> CompletableFuture<V> uniApplyStage(
++ Executor e, Function<? super T,? extends V> f) {
++ if (f == null) throw new NullPointerException();
++ CompletableFuture<V> d = new CompletableFuture<V>();
++ if (e != null || !d.uniApply(this, f, null)) {
++ UniApply<T,V> c = new UniApply<T,V>(e, d, this, f);
++ push(c);
++ c.tryFire(SYNC);
++ }
++ return d;
++ }
++
++ @SuppressWarnings("serial")
++ static final class UniAccept<T> extends UniCompletion<T,Void> {
++ Consumer<? super T> fn;
++ UniAccept(Executor executor, CompletableFuture<Void> dep,
++ CompletableFuture<T> src, Consumer<? super T> fn) {
++ super(executor, dep, src); this.fn = fn;
++ }
++ final CompletableFuture<Void> tryFire(int mode) {
++ CompletableFuture<Void> d; CompletableFuture<T> a;
++ if ((d = dep) == null ||
++ !d.uniAccept(a = src, fn, mode > 0 ? null : this))
++ return null;
++ dep = null; src = null; fn = null;
++ return d.postFire(a, mode);
++ }
++ }
++
++ final <S> boolean uniAccept(CompletableFuture<S> a,
++ Consumer<? super S> f, UniAccept<S> c) {
++ Object r; Throwable x;
++ if (a == null || (r = a.result) == null || f == null)
++ return false;
++ tryComplete: if (result == null) {
++ if (r instanceof AltResult) {
++ if ((x = ((AltResult)r).ex) != null) {
++ completeThrowable(x, r);
++ break tryComplete;
++ }
++ r = null;
++ }
++ try {
++ if (c != null && !c.claim())
++ return false;
++ @SuppressWarnings("unchecked") S s = (S) r;
++ f.accept(s);
++ completeNull();
++ } catch (Throwable ex) {
++ completeThrowable(ex);
++ }
++ }
++ return true;
++ }
++
++ private CompletableFuture<Void> uniAcceptStage(Executor e,
++ Consumer<? super T> f) {
++ if (f == null) throw new NullPointerException();
++ CompletableFuture<Void> d = new CompletableFuture<Void>();
++ if (e != null || !d.uniAccept(this, f, null)) {
++ UniAccept<T> c = new UniAccept<T>(e, d, this, f);
++ push(c);
++ c.tryFire(SYNC);
++ }
++ return d;
++ }
++
++ @SuppressWarnings("serial")
++ static final class UniRun<T> extends UniCompletion<T,Void> {
++ Runnable fn;
++ UniRun(Executor executor, CompletableFuture<Void> dep,
++ CompletableFuture<T> src, Runnable fn) {
++ super(executor, dep, src); this.fn = fn;
++ }
++ final CompletableFuture<Void> tryFire(int mode) {
++ CompletableFuture<Void> d; CompletableFuture<T> a;
++ if ((d = dep) == null ||
++ !d.uniRun(a = src, fn, mode > 0 ? null : this))
++ return null;
++ dep = null; src = null; fn = null;
++ return d.postFire(a, mode);
++ }
++ }
++
++ final boolean uniRun(CompletableFuture<?> a, Runnable f, UniRun<?> c) {
++ Object r; Throwable x;
++ if (a == null || (r = a.result) == null || f == null)
++ return false;
++ if (result == null) {
++ if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
++ completeThrowable(x, r);
++ else
++ try {
++ if (c != null && !c.claim())
++ return false;
++ f.run();
++ completeNull();
++ } catch (Throwable ex) {
++ completeThrowable(ex);
++ }
++ }
++ return true;
++ }
++
++ private CompletableFuture<Void> uniRunStage(Executor e, Runnable f) {
++ if (f == null) throw new NullPointerException();
++ CompletableFuture<Void> d = new CompletableFuture<Void>();
++ if (e != null || !d.uniRun(this, f, null)) {
++ UniRun<T> c = new UniRun<T>(e, d, this, f);
++ push(c);
++ c.tryFire(SYNC);
++ }
++ return d;
++ }
++
++ @SuppressWarnings("serial")
++ static final class UniWhenComplete<T> extends UniCompletion<T,T> {
++ BiConsumer<? super T, ? super Throwable> fn;
++ UniWhenComplete(Executor executor, CompletableFuture<T> dep,
++ CompletableFuture<T> src,
++ BiConsumer<? super T, ? super Throwable> fn) {
++ super(executor, dep, src); this.fn = fn;
++ }
++ final CompletableFuture<T> tryFire(int mode) {
++ CompletableFuture<T> d; CompletableFuture<T> a;
++ if ((d = dep) == null ||
++ !d.uniWhenComplete(a = src, fn, mode > 0 ? null : this))
++ return null;
++ dep = null; src = null; fn = null;
++ return d.postFire(a, mode);
++ }
++ }
++
++ final boolean uniWhenComplete(CompletableFuture<T> a,
++ BiConsumer<? super T,? super Throwable> f,
++ UniWhenComplete<T> c) {
++ Object r; T t; Throwable x = null;
++ if (a == null || (r = a.result) == null || f == null)
++ return false;
++ if (result == null) {
++ try {
++ if (c != null && !c.claim())
++ return false;
++ if (r instanceof AltResult) {
++ x = ((AltResult)r).ex;
++ t = null;
++ } else {
++ @SuppressWarnings("unchecked") T tr = (T) r;
++ t = tr;
++ }
++ f.accept(t, x);
++ if (x == null) {
++ internalComplete(r);
++ return true;
++ }
++ } catch (Throwable ex) {
++ if (x == null)
++ x = ex;
++ }
++ completeThrowable(x, r);
++ }
++ return true;
++ }
++
++ private CompletableFuture<T> uniWhenCompleteStage(
++ Executor e, BiConsumer<? super T, ? super Throwable> f) {
++ if (f == null) throw new NullPointerException();
++ CompletableFuture<T> d = new CompletableFuture<T>();
++ if (e != null || !d.uniWhenComplete(this, f, null)) {
++ UniWhenComplete<T> c = new UniWhenComplete<T>(e, d, this, f);
++ push(c);
++ c.tryFire(SYNC);
++ }
++ return d;
++ }
++
++ @SuppressWarnings("serial")
++ static final class UniHandle<T,V> extends UniCompletion<T,V> {
++ BiFunction<? super T, Throwable, ? extends V> fn;
++ UniHandle(Executor executor, CompletableFuture<V> dep,
++ CompletableFuture<T> src,
++ BiFunction<? super T, Throwable, ? extends V> fn) {
++ super(executor, dep, src); this.fn = fn;
++ }
++ final CompletableFuture<V> tryFire(int mode) {
++ CompletableFuture<V> d; CompletableFuture<T> a;
++ if ((d = dep) == null ||
++ !d.uniHandle(a = src, fn, mode > 0 ? null : this))
++ return null;
++ dep = null; src = null; fn = null;
++ return d.postFire(a, mode);
++ }
++ }
++
++ final <S> boolean uniHandle(CompletableFuture<S> a,
++ BiFunction<? super S, Throwable, ? extends T> f,
++ UniHandle<S,T> c) {
++ Object r; S s; Throwable x;
++ if (a == null || (r = a.result) == null || f == null)
++ return false;
++ if (result == null) {
++ try {
++ if (c != null && !c.claim())
++ return false;
++ if (r instanceof AltResult) {
++ x = ((AltResult)r).ex;
++ s = null;
++ } else {
++ x = null;
++ @SuppressWarnings("unchecked") S ss = (S) r;
++ s = ss;
++ }
++ completeValue(f.apply(s, x));
++ } catch (Throwable ex) {
++ completeThrowable(ex);
++ }
++ }
++ return true;
++ }
++
++ private <V> CompletableFuture<V> uniHandleStage(
++ Executor e, BiFunction<? super T, Throwable, ? extends V> f) {
++ if (f == null) throw new NullPointerException();
++ CompletableFuture<V> d = new CompletableFuture<V>();
++ if (e != null || !d.uniHandle(this, f, null)) {
++ UniHandle<T,V> c = new UniHandle<T,V>(e, d, this, f);
++ push(c);
++ c.tryFire(SYNC);
++ }
++ return d;
++ }
++
++ @SuppressWarnings("serial")
++ static final class UniExceptionally<T> extends UniCompletion<T,T> {
++ Function<? super Throwable, ? extends T> fn;
++ UniExceptionally(CompletableFuture<T> dep, CompletableFuture<T> src,
++ Function<? super Throwable, ? extends T> fn) {
++ super(null, dep, src); this.fn = fn;
++ }
++ final CompletableFuture<T> tryFire(int mode) { // never ASYNC
++ // assert mode != ASYNC;
++ CompletableFuture<T> d; CompletableFuture<T> a;
++ if ((d = dep) == null || !d.uniExceptionally(a = src, fn, this))
++ return null;
++ dep = null; src = null; fn = null;
++ return d.postFire(a, mode);
++ }
++ }
++
++ final boolean uniExceptionally(CompletableFuture<T> a,
++ Function<? super Throwable, ? extends T> f,
++ UniExceptionally<T> c) {
++ Object r; Throwable x;
++ if (a == null || (r = a.result) == null || f == null)
++ return false;
++ if (result == null) {
++ try {
++ if (r instanceof AltResult && (x = ((AltResult)r).ex) != null) {
++ if (c != null && !c.claim())
++ return false;
++ completeValue(f.apply(x));
++ } else
++ internalComplete(r);
++ } catch (Throwable ex) {
++ completeThrowable(ex);
++ }
++ }
++ return true;
++ }
++
++ private CompletableFuture<T> uniExceptionallyStage(
++ Function<Throwable, ? extends T> f) {
++ if (f == null) throw new NullPointerException();
++ CompletableFuture<T> d = new CompletableFuture<T>();
++ if (!d.uniExceptionally(this, f, null)) {
++ UniExceptionally<T> c = new UniExceptionally<T>(d, this, f);
++ push(c);
++ c.tryFire(SYNC);
++ }
++ return d;
++ }
++
++ @SuppressWarnings("serial")
++ static final class UniRelay<T> extends UniCompletion<T,T> { // for Compose
++ UniRelay(CompletableFuture<T> dep, CompletableFuture<T> src) {
++ super(null, dep, src);
++ }
++ final CompletableFuture<T> tryFire(int mode) {
++ CompletableFuture<T> d; CompletableFuture<T> a;
++ if ((d = dep) == null || !d.uniRelay(a = src))
++ return null;
++ src = null; dep = null;
++ return d.postFire(a, mode);
++ }
++ }
++
++ final boolean uniRelay(CompletableFuture<T> a) {
++ Object r;
++ if (a == null || (r = a.result) == null)
++ return false;
++ if (result == null) // no need to claim
++ completeRelay(r);
++ return true;
++ }
++
++ @SuppressWarnings("serial")
++ static final class UniCompose<T,V> extends UniCompletion<T,V> {
++ Function<? super T, ? extends CompletionStage<V>> fn;
++ UniCompose(Executor executor, CompletableFuture<V> dep,
++ CompletableFuture<T> src,
++ Function<? super T, ? extends CompletionStage<V>> fn) {
++ super(executor, dep, src); this.fn = fn;
++ }
++ final CompletableFuture<V> tryFire(int mode) {
++ CompletableFuture<V> d; CompletableFuture<T> a;
++ if ((d = dep) == null ||
++ !d.uniCompose(a = src, fn, mode > 0 ? null : this))
++ return null;
++ dep = null; src = null; fn = null;
++ return d.postFire(a, mode);
++ }
++ }
++
++ final <S> boolean uniCompose(
++ CompletableFuture<S> a,
++ Function<? super S, ? extends CompletionStage<T>> f,
++ UniCompose<S,T> c) {
++ Object r; Throwable x;
++ if (a == null || (r = a.result) == null || f == null)
++ return false;
++ tryComplete: if (result == null) {
++ if (r instanceof AltResult) {
++ if ((x = ((AltResult)r).ex) != null) {
++ completeThrowable(x, r);
++ break tryComplete;
++ }
++ r = null;
++ }
++ try {
++ if (c != null && !c.claim())
++ return false;
++ @SuppressWarnings("unchecked") S s = (S) r;
++ CompletableFuture<T> g = f.apply(s).toCompletableFuture();
++ if (g.result == null || !uniRelay(g)) {
++ UniRelay<T> copy = new UniRelay<T>(this, g);
++ g.push(copy);
++ copy.tryFire(SYNC);
++ if (result == null)
++ return false;
++ }
++ } catch (Throwable ex) {
++ completeThrowable(ex);
++ }
++ }
++ return true;
++ }
++
++ private <V> CompletableFuture<V> uniComposeStage(
++ Executor e, Function<? super T, ? extends CompletionStage<V>> f) {
++ if (f == null) throw new NullPointerException();
++ Object r; Throwable x;
++ if (e == null && (r = result) != null) {
++ // try to return function result directly
++ if (r instanceof AltResult) {
++ if ((x = ((AltResult)r).ex) != null) {
++ return new CompletableFuture<V>(encodeThrowable(x, r));
++ }
++ r = null;
++ }
++ try {
++ @SuppressWarnings("unchecked") T t = (T) r;
++ return f.apply(t).toCompletableFuture();
++ } catch (Throwable ex) {
++ return new CompletableFuture<V>(encodeThrowable(ex));
++ }
++ }
++ CompletableFuture<V> d = new CompletableFuture<V>();
++ UniCompose<T,V> c = new UniCompose<T,V>(e, d, this, f);
++ push(c);
++ c.tryFire(SYNC);
++ return d;
++ }
++
++ /* ------------- Two-input Completions -------------- */
++
++ /** A Completion for an action with two sources */
++ @SuppressWarnings("serial")
++ abstract static class BiCompletion<T,U,V> extends UniCompletion<T,V> {
++ CompletableFuture<U> snd; // second source for action
++ BiCompletion(Executor executor, CompletableFuture<V> dep,
++ CompletableFuture<T> src, CompletableFuture<U> snd) {
++ super(executor, dep, src); this.snd = snd;
++ }
++ }
++
++ /** A Completion delegating to a BiCompletion */
++ @SuppressWarnings("serial")
++ static final class CoCompletion extends Completion {
++ BiCompletion<?,?,?> base;
++ CoCompletion(BiCompletion<?,?,?> base) { this.base = base; }
++ final CompletableFuture<?> tryFire(int mode) {
++ BiCompletion<?,?,?> c; CompletableFuture<?> d;
++ if ((c = base) == null || (d = c.tryFire(mode)) == null)
++ return null;
++ base = null; // detach
++ return d;
++ }
++ final boolean isLive() {
++ BiCompletion<?,?,?> c;
++ return (c = base) != null && c.dep != null;
++ }
++ }
++
++ /** Pushes completion to this and b unless both done. */
++ final void bipush(CompletableFuture<?> b, BiCompletion<?,?,?> c) {
++ if (c != null) {
++ Object r;
++ while ((r = result) == null && !tryPushStack(c))
++ lazySetNext(c, null); // clear on failure
++ if (b != null && b != this && b.result == null) {
++ Completion q = (r != null) ? c : new CoCompletion(c);
++ while (b.result == null && !b.tryPushStack(q))
++ lazySetNext(q, null); // clear on failure
++ }
++ }
++ }
++
++ /** Post-processing after successful BiCompletion tryFire. */
++ final CompletableFuture<T> postFire(CompletableFuture<?> a,
++ CompletableFuture<?> b, int mode) {
++ if (b != null && b.stack != null) { // clean second source
++ if (mode < 0 || b.result == null)
++ b.cleanStack();
++ else
++ b.postComplete();
++ }
++ return postFire(a, mode);
++ }
++
++ @SuppressWarnings("serial")
++ static final class BiApply<T,U,V> extends BiCompletion<T,U,V> {
++ BiFunction<? super T,? super U,? extends V> fn;
++ BiApply(Executor executor, CompletableFuture<V> dep,
++ CompletableFuture<T> src, CompletableFuture<U> snd,
++ BiFunction<? super T,? super U,? extends V> fn) {
++ super(executor, dep, src, snd); this.fn = fn;
++ }
++ final CompletableFuture<V> tryFire(int mode) {
++ CompletableFuture<V> d;
++ CompletableFuture<T> a;
++ CompletableFuture<U> b;
++ if ((d = dep) == null ||
++ !d.biApply(a = src, b = snd, fn, mode > 0 ? null : this))
++ return null;
++ dep = null; src = null; snd = null; fn = null;
++ return d.postFire(a, b, mode);
++ }
++ }
++
++ final <R,S> boolean biApply(CompletableFuture<R> a,
++ CompletableFuture<S> b,
++ BiFunction<? super R,? super S,? extends T> f,
++ BiApply<R,S,T> c) {
++ Object r, s; Throwable x;
++ if (a == null || (r = a.result) == null ||
++ b == null || (s = b.result) == null || f == null)
++ return false;
++ tryComplete: if (result == null) {
++ if (r instanceof AltResult) {
++ if ((x = ((AltResult)r).ex) != null) {
++ completeThrowable(x, r);
++ break tryComplete;
++ }
++ r = null;
++ }
++ if (s instanceof AltResult) {
++ if ((x = ((AltResult)s).ex) != null) {
++ completeThrowable(x, s);
++ break tryComplete;
++ }
++ s = null;
++ }
++ try {
++ if (c != null && !c.claim())
++ return false;
++ @SuppressWarnings("unchecked") R rr = (R) r;
++ @SuppressWarnings("unchecked") S ss = (S) s;
++ completeValue(f.apply(rr, ss));
++ } catch (Throwable ex) {
++ completeThrowable(ex);
++ }
++ }
++ return true;
++ }
++
++ private <U,V> CompletableFuture<V> biApplyStage(
++ Executor e, CompletionStage<U> o,
++ BiFunction<? super T,? super U,? extends V> f) {
++ CompletableFuture<U> b;
++ if (f == null || (b = o.toCompletableFuture()) == null)
++ throw new NullPointerException();
++ CompletableFuture<V> d = new CompletableFuture<V>();
++ if (e != null || !d.biApply(this, b, f, null)) {
++ BiApply<T,U,V> c = new BiApply<T,U,V>(e, d, this, b, f);
++ bipush(b, c);
++ c.tryFire(SYNC);
++ }
++ return d;
++ }
++
++ @SuppressWarnings("serial")
++ static final class BiAccept<T,U> extends BiCompletion<T,U,Void> {
++ BiConsumer<? super T,? super U> fn;
++ BiAccept(Executor executor, CompletableFuture<Void> dep,
++ CompletableFuture<T> src, CompletableFuture<U> snd,
++ BiConsumer<? super T,? super U> fn) {
++ super(executor, dep, src, snd); this.fn = fn;
++ }
++ final CompletableFuture<Void> tryFire(int mode) {
++ CompletableFuture<Void> d;
++ CompletableFuture<T> a;
++ CompletableFuture<U> b;
++ if ((d = dep) == null ||
++ !d.biAccept(a = src, b = snd, fn, mode > 0 ? null : this))
++ return null;
++ dep = null; src = null; snd = null; fn = null;
++ return d.postFire(a, b, mode);
++ }
++ }
++
++ final <R,S> boolean biAccept(CompletableFuture<R> a,
++ CompletableFuture<S> b,
++ BiConsumer<? super R,? super S> f,
++ BiAccept<R,S> c) {
++ Object r, s; Throwable x;
++ if (a == null || (r = a.result) == null ||
++ b == null || (s = b.result) == null || f == null)
++ return false;
++ tryComplete: if (result == null) {
++ if (r instanceof AltResult) {
++ if ((x = ((AltResult)r).ex) != null) {
++ completeThrowable(x, r);
++ break tryComplete;
++ }
++ r = null;
++ }
++ if (s instanceof AltResult) {
++ if ((x = ((AltResult)s).ex) != null) {
++ completeThrowable(x, s);
++ break tryComplete;
++ }
++ s = null;
++ }
++ try {
++ if (c != null && !c.claim())
++ return false;
++ @SuppressWarnings("unchecked") R rr = (R) r;
++ @SuppressWarnings("unchecked") S ss = (S) s;
++ f.accept(rr, ss);
++ completeNull();
++ } catch (Throwable ex) {
++ completeThrowable(ex);
++ }
++ }
++ return true;
++ }
++
++ private <U> CompletableFuture<Void> biAcceptStage(
++ Executor e, CompletionStage<U> o,
++ BiConsumer<? super T,? super U> f) {
++ CompletableFuture<U> b;
++ if (f == null || (b = o.toCompletableFuture()) == null)
++ throw new NullPointerException();
++ CompletableFuture<Void> d = new CompletableFuture<Void>();
++ if (e != null || !d.biAccept(this, b, f, null)) {
++ BiAccept<T,U> c = new BiAccept<T,U>(e, d, this, b, f);
++ bipush(b, c);
++ c.tryFire(SYNC);
++ }
++ return d;
++ }
++
++ @SuppressWarnings("serial")
++ static final class BiRun<T,U> extends BiCompletion<T,U,Void> {
++ Runnable fn;
++ BiRun(Executor executor, CompletableFuture<Void> dep,
++ CompletableFuture<T> src,
++ CompletableFuture<U> snd,
++ Runnable fn) {
++ super(executor, dep, src, snd); this.fn = fn;
++ }
++ final CompletableFuture<Void> tryFire(int mode) {
++ CompletableFuture<Void> d;
++ CompletableFuture<T> a;
++ CompletableFuture<U> b;
++ if ((d = dep) == null ||
++ !d.biRun(a = src, b = snd, fn, mode > 0 ? null : this))
++ return null;
++ dep = null; src = null; snd = null; fn = null;
++ return d.postFire(a, b, mode);
++ }
++ }
++
++ final boolean biRun(CompletableFuture<?> a, CompletableFuture<?> b,
++ Runnable f, BiRun<?,?> c) {
++ Object r, s; Throwable x;
++ if (a == null || (r = a.result) == null ||
++ b == null || (s = b.result) == null || f == null)
++ return false;
++ if (result == null) {
++ if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
++ completeThrowable(x, r);
++ else if (s instanceof AltResult && (x = ((AltResult)s).ex) != null)
++ completeThrowable(x, s);
++ else
++ try {
++ if (c != null && !c.claim())
++ return false;
++ f.run();
++ completeNull();
++ } catch (Throwable ex) {
++ completeThrowable(ex);
++ }
++ }
++ return true;
++ }
++
++ private CompletableFuture<Void> biRunStage(Executor e, CompletionStage<?> o,
++ Runnable f) {
++ CompletableFuture<?> b;
++ if (f == null || (b = o.toCompletableFuture()) == null)
++ throw new NullPointerException();
++ CompletableFuture<Void> d = new CompletableFuture<Void>();
++ if (e != null || !d.biRun(this, b, f, null)) {
++ BiRun<T,?> c = new BiRun<>(e, d, this, b, f);
++ bipush(b, c);
++ c.tryFire(SYNC);
++ }
++ return d;
++ }
++
++ @SuppressWarnings("serial")
++ static final class BiRelay<T,U> extends BiCompletion<T,U,Void> { // for And
++ BiRelay(CompletableFuture<Void> dep,
++ CompletableFuture<T> src,
++ CompletableFuture<U> snd) {
++ super(null, dep, src, snd);
++ }
++ final CompletableFuture<Void> tryFire(int mode) {
++ CompletableFuture<Void> d;
++ CompletableFuture<T> a;
++ CompletableFuture<U> b;
++ if ((d = dep) == null || !d.biRelay(a = src, b = snd))
++ return null;
++ src = null; snd = null; dep = null;
++ return d.postFire(a, b, mode);
++ }
++ }
++
++ boolean biRelay(CompletableFuture<?> a, CompletableFuture<?> b) {
++ Object r, s; Throwable x;
++ if (a == null || (r = a.result) == null ||
++ b == null || (s = b.result) == null)
++ return false;
++ if (result == null) {
++ if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
++ completeThrowable(x, r);
++ else if (s instanceof AltResult && (x = ((AltResult)s).ex) != null)
++ completeThrowable(x, s);
++ else
++ completeNull();
++ }
++ return true;
++ }
++
++ /** Recursively constructs a tree of completions. */
++ static CompletableFuture<Void> andTree(CompletableFuture<?>[] cfs,
++ int lo, int hi) {
++ CompletableFuture<Void> d = new CompletableFuture<Void>();
++ if (lo > hi) // empty
++ d.result = NIL;
++ else {
++ CompletableFuture<?> a, b;
++ int mid = (lo + hi) >>> 1;
++ if ((a = (lo == mid ? cfs[lo] :
++ andTree(cfs, lo, mid))) == null ||
++ (b = (lo == hi ? a : (hi == mid+1) ? cfs[hi] :
++ andTree(cfs, mid+1, hi))) == null)
++ throw new NullPointerException();
++ if (!d.biRelay(a, b)) {
++ BiRelay<?,?> c = new BiRelay<>(d, a, b);
++ a.bipush(b, c);
++ c.tryFire(SYNC);
++ }
++ }
++ return d;
++ }
++
++ /* ------------- Projected (Ored) BiCompletions -------------- */
++
++ /** Pushes completion to this and b unless either done. */
++ final void orpush(CompletableFuture<?> b, BiCompletion<?,?,?> c) {
++ if (c != null) {
++ while ((b == null || b.result == null) && result == null) {
++ if (tryPushStack(c)) {
++ if (b != null && b != this && b.result == null) {
++ Completion q = new CoCompletion(c);
++ while (result == null && b.result == null &&
++ !b.tryPushStack(q))
++ lazySetNext(q, null); // clear on failure
++ }
++ break;
++ }
++ lazySetNext(c, null); // clear on failure
++ }
++ }
++ }
++
++ @SuppressWarnings("serial")
++ static final class OrApply<T,U extends T,V> extends BiCompletion<T,U,V> {
++ Function<? super T,? extends V> fn;
++ OrApply(Executor executor, CompletableFuture<V> dep,
++ CompletableFuture<T> src,
++ CompletableFuture<U> snd,
++ Function<? super T,? extends V> fn) {
++ super(executor, dep, src, snd); this.fn = fn;
++ }
++ final CompletableFuture<V> tryFire(int mode) {
++ CompletableFuture<V> d;
++ CompletableFuture<T> a;
++ CompletableFuture<U> b;
++ if ((d = dep) == null ||
++ !d.orApply(a = src, b = snd, fn, mode > 0 ? null : this))
++ return null;
++ dep = null; src = null; snd = null; fn = null;
++ return d.postFire(a, b, mode);
++ }
++ }
++
++ final <R,S extends R> boolean orApply(CompletableFuture<R> a,
++ CompletableFuture<S> b,
++ Function<? super R, ? extends T> f,
++ OrApply<R,S,T> c) {
++ Object r; Throwable x;
++ if (a == null || b == null ||
++ ((r = a.result) == null && (r = b.result) == null) || f == null)
++ return false;
++ tryComplete: if (result == null) {
++ try {
++ if (c != null && !c.claim())
++ return false;
++ if (r instanceof AltResult) {
++ if ((x = ((AltResult)r).ex) != null) {
++ completeThrowable(x, r);
++ break tryComplete;
++ }
++ r = null;
++ }
++ @SuppressWarnings("unchecked") R rr = (R) r;
++ completeValue(f.apply(rr));
++ } catch (Throwable ex) {
++ completeThrowable(ex);
++ }
++ }
++ return true;
++ }
++
++ private <U extends T,V> CompletableFuture<V> orApplyStage(
++ Executor e, CompletionStage<U> o,
++ Function<? super T, ? extends V> f) {
++ CompletableFuture<U> b;
++ if (f == null || (b = o.toCompletableFuture()) == null)
++ throw new NullPointerException();
++ CompletableFuture<V> d = new CompletableFuture<V>();
++ if (e != null || !d.orApply(this, b, f, null)) {
++ OrApply<T,U,V> c = new OrApply<T,U,V>(e, d, this, b, f);
++ orpush(b, c);
++ c.tryFire(SYNC);
++ }
++ return d;
++ }
++
++ @SuppressWarnings("serial")
++ static final class OrAccept<T,U extends T> extends BiCompletion<T,U,Void> {
++ Consumer<? super T> fn;
++ OrAccept(Executor executor, CompletableFuture<Void> dep,
++ CompletableFuture<T> src,
++ CompletableFuture<U> snd,
++ Consumer<? super T> fn) {
++ super(executor, dep, src, snd); this.fn = fn;
++ }
++ final CompletableFuture<Void> tryFire(int mode) {
++ CompletableFuture<Void> d;
++ CompletableFuture<T> a;
++ CompletableFuture<U> b;
++ if ((d = dep) == null ||
++ !d.orAccept(a = src, b = snd, fn, mode > 0 ? null : this))
++ return null;
++ dep = null; src = null; snd = null; fn = null;
++ return d.postFire(a, b, mode);
++ }
++ }
++
++ final <R,S extends R> boolean orAccept(CompletableFuture<R> a,
++ CompletableFuture<S> b,
++ Consumer<? super R> f,
++ OrAccept<R,S> c) {
++ Object r; Throwable x;
++ if (a == null || b == null ||
++ ((r = a.result) == null && (r = b.result) == null) || f == null)
++ return false;
++ tryComplete: if (result == null) {
++ try {
++ if (c != null && !c.claim())
++ return false;
++ if (r instanceof AltResult) {
++ if ((x = ((AltResult)r).ex) != null) {
++ completeThrowable(x, r);
++ break tryComplete;
++ }
++ r = null;
++ }
++ @SuppressWarnings("unchecked") R rr = (R) r;
++ f.accept(rr);
++ completeNull();
++ } catch (Throwable ex) {
++ completeThrowable(ex);
++ }
++ }
++ return true;
++ }
++
++ private <U extends T> CompletableFuture<Void> orAcceptStage(
++ Executor e, CompletionStage<U> o, Consumer<? super T> f) {
++ CompletableFuture<U> b;
++ if (f == null || (b = o.toCompletableFuture()) == null)
++ throw new NullPointerException();
++ CompletableFuture<Void> d = new CompletableFuture<Void>();
++ if (e != null || !d.orAccept(this, b, f, null)) {
++ OrAccept<T,U> c = new OrAccept<T,U>(e, d, this, b, f);
++ orpush(b, c);
++ c.tryFire(SYNC);
++ }
++ return d;
++ }
++
++ @SuppressWarnings("serial")
++ static final class OrRun<T,U> extends BiCompletion<T,U,Void> {
++ Runnable fn;
++ OrRun(Executor executor, CompletableFuture<Void> dep,
++ CompletableFuture<T> src,
++ CompletableFuture<U> snd,
++ Runnable fn) {
++ super(executor, dep, src, snd); this.fn = fn;
++ }
++ final CompletableFuture<Void> tryFire(int mode) {
++ CompletableFuture<Void> d;
++ CompletableFuture<T> a;
++ CompletableFuture<U> b;
++ if ((d = dep) == null ||
++ !d.orRun(a = src, b = snd, fn, mode > 0 ? null : this))
++ return null;
++ dep = null; src = null; snd = null; fn = null;
++ return d.postFire(a, b, mode);
++ }
++ }
++
++ final boolean orRun(CompletableFuture<?> a, CompletableFuture<?> b,
++ Runnable f, OrRun<?,?> c) {
++ Object r; Throwable x;
++ if (a == null || b == null ||
++ ((r = a.result) == null && (r = b.result) == null) || f == null)
++ return false;
++ if (result == null) {
++ try {
++ if (c != null && !c.claim())
++ return false;
++ if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
++ completeThrowable(x, r);
++ else {
++ f.run();
++ completeNull();
++ }
++ } catch (Throwable ex) {
++ completeThrowable(ex);
++ }
++ }
++ return true;
++ }
++
++ private CompletableFuture<Void> orRunStage(Executor e, CompletionStage<?> o,
++ Runnable f) {
++ CompletableFuture<?> b;
++ if (f == null || (b = o.toCompletableFuture()) == null)
++ throw new NullPointerException();
++ CompletableFuture<Void> d = new CompletableFuture<Void>();
++ if (e != null || !d.orRun(this, b, f, null)) {
++ OrRun<T,?> c = new OrRun<>(e, d, this, b, f);
++ orpush(b, c);
++ c.tryFire(SYNC);
++ }
++ return d;
++ }
++
++ @SuppressWarnings("serial")
++ static final class OrRelay<T,U> extends BiCompletion<T,U,Object> { // for Or
++ OrRelay(CompletableFuture<Object> dep, CompletableFuture<T> src,
++ CompletableFuture<U> snd) {
++ super(null, dep, src, snd);
++ }
++ final CompletableFuture<Object> tryFire(int mode) {
++ CompletableFuture<Object> d;
++ CompletableFuture<T> a;
++ CompletableFuture<U> b;
++ if ((d = dep) == null || !d.orRelay(a = src, b = snd))
++ return null;
++ src = null; snd = null; dep = null;
++ return d.postFire(a, b, mode);
++ }
++ }
++
++ final boolean orRelay(CompletableFuture<?> a, CompletableFuture<?> b) {
++ Object r;
++ if (a == null || b == null ||
++ ((r = a.result) == null && (r = b.result) == null))
++ return false;
++ if (result == null)
++ completeRelay(r);
++ return true;
++ }
++
++ /** Recursively constructs a tree of completions. */
++ static CompletableFuture<Object> orTree(CompletableFuture<?>[] cfs,
++ int lo, int hi) {
++ CompletableFuture<Object> d = new CompletableFuture<Object>();
++ if (lo <= hi) {
++ CompletableFuture<?> a, b;
++ int mid = (lo + hi) >>> 1;
++ if ((a = (lo == mid ? cfs[lo] :
++ orTree(cfs, lo, mid))) == null ||
++ (b = (lo == hi ? a : (hi == mid+1) ? cfs[hi] :
++ orTree(cfs, mid+1, hi))) == null)
++ throw new NullPointerException();
++ if (!d.orRelay(a, b)) {
++ OrRelay<?,?> c = new OrRelay<>(d, a, b);
++ a.orpush(b, c);
++ c.tryFire(SYNC);
++ }
++ }
++ return d;
++ }
++
++ /* ------------- Zero-input Async forms -------------- */
++
++ @SuppressWarnings("serial")
++ static final class AsyncSupply<T> extends ForkJoinTask<Void>
++ implements Runnable, AsynchronousCompletionTask {
++ CompletableFuture<T> dep; Supplier<T> fn;
++ AsyncSupply(CompletableFuture<T> dep, Supplier<T> fn) {
++ this.dep = dep; this.fn = fn;
++ }
++
++ public final Void getRawResult() { return null; }
++ public final void setRawResult(Void v) {}
++ public final boolean exec() { run(); return true; }
++
++ public void run() {
++ CompletableFuture<T> d; Supplier<T> f;
++ if ((d = dep) != null && (f = fn) != null) {
++ dep = null; fn = null;
++ if (d.result == null) {
++ try {
++ d.completeValue(f.get());
++ } catch (Throwable ex) {
++ d.completeThrowable(ex);
++ }
++ }
++ d.postComplete();
++ }
++ }
++ }
++
++ static <U> CompletableFuture<U> asyncSupplyStage(Executor e,
++ Supplier<U> f) {
++ if (f == null) throw new NullPointerException();
++ CompletableFuture<U> d = new CompletableFuture<U>();
++ e.execute(new AsyncSupply<U>(d, f));
++ return d;
++ }
++
++ @SuppressWarnings("serial")
++ static final class AsyncRun extends ForkJoinTask<Void>
++ implements Runnable, AsynchronousCompletionTask {
++ CompletableFuture<Void> dep; Runnable fn;
++ AsyncRun(CompletableFuture<Void> dep, Runnable fn) {
++ this.dep = dep; this.fn = fn;
++ }
++
++ public final Void getRawResult() { return null; }
++ public final void setRawResult(Void v) {}
++ public final boolean exec() { run(); return true; }
++
++ public void run() {
++ CompletableFuture<Void> d; Runnable f;
++ if ((d = dep) != null && (f = fn) != null) {
++ dep = null; fn = null;
++ if (d.result == null) {
++ try {
++ f.run();
++ d.completeNull();
++ } catch (Throwable ex) {
++ d.completeThrowable(ex);
++ }
++ }
++ d.postComplete();
++ }
++ }
++ }
++
++ static CompletableFuture<Void> asyncRunStage(Executor e, Runnable f) {
++ if (f == null) throw new NullPointerException();
++ CompletableFuture<Void> d = new CompletableFuture<Void>();
++ e.execute(new AsyncRun(d, f));
++ return d;
++ }
++
++ /* ------------- Signallers -------------- */
+
+ /**
+- * Heuristic spin value for waitingGet() before blocking on
+- * multiprocessors
++ * Completion for recording and releasing a waiting thread. This
++ * class implements ManagedBlocker to avoid starvation when
++ * blocking actions pile up in ForkJoinPools.
+ */
+- static final int SPINS = (NCPU > 1) ? 1 << 8 : 0;
+-
+- /**
+- * Linked nodes to record waiting threads in a Treiber stack. See
+- * other classes such as Phaser and SynchronousQueue for more
+- * detailed explanation. This class implements ManagedBlocker to
+- * avoid starvation when blocking actions pile up in
+- * ForkJoinPools.
+- */
+- static final class WaitNode implements ForkJoinPool.ManagedBlocker {
+- long nanos; // wait time if timed
+- final long deadline; // non-zero if timed
++ @SuppressWarnings("serial")
++ static final class Signaller extends Completion
++ implements ForkJoinPool.ManagedBlocker {
++ long nanos; // wait time if timed
++ final long deadline; // non-zero if timed
+ volatile int interruptControl; // > 0: interruptible, < 0: interrupted
+ volatile Thread thread;
+- volatile WaitNode next;
+- WaitNode(boolean interruptible, long nanos, long deadline) {
++
++ Signaller(boolean interruptible, long nanos, long deadline) {
+ this.thread = Thread.currentThread();
+ this.interruptControl = interruptible ? 1 : 0;
+ this.nanos = nanos;
+ this.deadline = deadline;
+ }
++ final CompletableFuture<?> tryFire(int ignore) {
++ Thread w; // no need to atomically claim
++ if ((w = thread) != null) {
++ thread = null;
++ LockSupport.unpark(w);
++ }
++ return null;
++ }
+ public boolean isReleasable() {
+ if (thread == null)
+ return true;
+@@ -273,6 +1687,7 @@
+ LockSupport.parkNanos(this, nanos);
+ return isReleasable();
+ }
++ final boolean isLive() { return thread != null; }
+ }
+
+ /**
+@@ -280,1832 +1695,89 @@
+ * interrupted.
+ */
+ private Object waitingGet(boolean interruptible) {
+- WaitNode q = null;
++ Signaller q = null;
+ boolean queued = false;
+- int spins = SPINS;
+- for (Object r;;) {
+- if ((r = result) != null) {
+- if (q != null) { // suppress unpark
+- q.thread = null;
+- if (q.interruptControl < 0) {
+- if (interruptible) {
+- removeWaiter(q);
+- return null;
+- }
+- Thread.currentThread().interrupt();
+- }
+- }
+- postComplete(); // help release others
+- return r;
+- }
++ int spins = -1;
++ Object r;
++ while ((r = result) == null) {
++ if (spins < 0)
++ spins = (Runtime.getRuntime().availableProcessors() > 1) ?
++ 1 << 8 : 0; // Use brief spin-wait on multiprocessors
+ else if (spins > 0) {
+- int rnd = ThreadLocalRandom.nextSecondarySeed();
+- if (rnd == 0)
+- rnd = ThreadLocalRandom.current().nextInt();
+- if (rnd >= 0)
++ if (ThreadLocalRandom.nextSecondarySeed() >= 0)
+ --spins;
+ }
+ else if (q == null)
+- q = new WaitNode(interruptible, 0L, 0L);
++ q = new Signaller(interruptible, 0L, 0L);
+ else if (!queued)
+- queued = UNSAFE.compareAndSwapObject(this, WAITERS,
+- q.next = waiters, q);
++ queued = tryPushStack(q);
+ else if (interruptible && q.interruptControl < 0) {
+- removeWaiter(q);
++ q.thread = null;
++ cleanStack();
+ return null;
+ }
+ else if (q.thread != null && result == null) {
+ try {
+ ForkJoinPool.managedBlock(q);
+- } catch (InterruptedException ex) {
++ } catch (InterruptedException ie) {
+ q.interruptControl = -1;
+ }
+ }
+ }
++ if (q != null) {
++ q.thread = null;
++ if (q.interruptControl < 0) {
++ if (interruptible)
++ r = null; // report interruption
++ else
++ Thread.currentThread().interrupt();
++ }
++ }
++ postComplete();
++ return r;
+ }
+
+ /**
+- * Awaits completion or aborts on interrupt or timeout.
+- *
+- * @param nanos time to wait
+- * @return raw result
++ * Returns raw result after waiting, or null if interrupted, or
++ * throws TimeoutException on timeout.
+ */
+- private Object timedAwaitDone(long nanos)
+- throws InterruptedException, TimeoutException {
+- WaitNode q = null;
++ private Object timedGet(long nanos) throws TimeoutException {
++ if (Thread.interrupted())
++ return null;
++ if (nanos <= 0L)
++ throw new TimeoutException();
++ long d = System.nanoTime() + nanos;
++ Signaller q = new Signaller(true, nanos, d == 0L ? 1L : d); // avoid 0
+ boolean queued = false;
+- for (Object r;;) {
+- if ((r = result) != null) {
+- if (q != null) {
+- q.thread = null;
+- if (q.interruptControl < 0) {
+- removeWaiter(q);
+- throw new InterruptedException();
+- }
+- }
+- postComplete();
+- return r;
+- }
+- else if (q == null) {
+- if (nanos <= 0L)
+- throw new TimeoutException();
+- long d = System.nanoTime() + nanos;
+- q = new WaitNode(true, nanos, d == 0L ? 1L : d); // avoid 0
+- }
+- else if (!queued)
+- queued = UNSAFE.compareAndSwapObject(this, WAITERS,
+- q.next = waiters, q);
+- else if (q.interruptControl < 0) {
+- removeWaiter(q);
+- throw new InterruptedException();
+- }
+- else if (q.nanos <= 0L) {
+- if (result == null) {
+- removeWaiter(q);
+- throw new TimeoutException();
+- }
++ Object r;
++ // We intentionally don't spin here (as waitingGet does) because
++ // the call to nanoTime() above acts much like a spin.
++ while ((r = result) == null) {
++ if (!queued)
++ queued = tryPushStack(q);
++ else if (q.interruptControl < 0 || q.nanos <= 0L) {
++ q.thread = null;
++ cleanStack();
++ if (q.interruptControl < 0)
++ return null;
++ throw new TimeoutException();
+ }
+ else if (q.thread != null && result == null) {
+ try {
+ ForkJoinPool.managedBlock(q);
+- } catch (InterruptedException ex) {
++ } catch (InterruptedException ie) {
+ q.interruptControl = -1;
+ }
+ }
+ }
++ if (q.interruptControl < 0)
++ r = null;
++ q.thread = null;
++ postComplete();
++ return r;
+ }
+
+- /**
+- * Tries to unlink a timed-out or interrupted wait node to avoid
+- * accumulating garbage. Internal nodes are simply unspliced
+- * without CAS since it is harmless if they are traversed anyway
+- * by releasers. To avoid effects of unsplicing from already
+- * removed nodes, the list is retraversed in case of an apparent
+- * race. This is slow when there are a lot of nodes, but we don't
+- * expect lists to be long enough to outweigh higher-overhead
+- * schemes.
+- */
+- private void removeWaiter(WaitNode node) {
+- if (node != null) {
+- node.thread = null;
+- retry:
+- for (;;) { // restart on removeWaiter race
+- for (WaitNode pred = null, q = waiters, s; q != null; q = s) {
+- s = q.next;
+- if (q.thread != null)
+- pred = q;
+- else if (pred != null) {
+- pred.next = s;
+- if (pred.thread == null) // check for race
+- continue retry;
+- }
+- else if (!UNSAFE.compareAndSwapObject(this, WAITERS, q, s))
+- continue retry;
+- }
+- break;
+- }
+- }
+- }
+-
+- /* ------------- Async tasks -------------- */
+-
+- /**
+- * A marker interface identifying asynchronous tasks produced by
+- * {@code async} methods. This may be useful for monitoring,
+- * debugging, and tracking asynchronous activities.
+- *
+- * @since 1.8
+- */
+- public static interface AsynchronousCompletionTask {
+- }
+-
+- /** Base class can act as either FJ or plain Runnable */
+- @SuppressWarnings("serial")
+- abstract static class Async extends ForkJoinTask<Void>
+- implements Runnable, AsynchronousCompletionTask {
+- public final Void getRawResult() { return null; }
+- public final void setRawResult(Void v) { }
+- public final void run() { exec(); }
+- }
+-
+- /**
+- * Starts the given async task using the given executor, unless
+- * the executor is ForkJoinPool.commonPool and it has been
+- * disabled, in which case starts a new thread.
+- */
+- static void execAsync(Executor e, Async r) {
+- if (e == ForkJoinPool.commonPool() &&
+- ForkJoinPool.getCommonPoolParallelism() <= 1)
+- new Thread(r).start();
+- else
+- e.execute(r);
+- }
+-
+- static final class AsyncRun extends Async {
+- final Runnable fn;
+- final CompletableFuture<Void> dst;
+- AsyncRun(Runnable fn, CompletableFuture<Void> dst) {
+- this.fn = fn; this.dst = dst;
+- }
+- public final boolean exec() {
+- CompletableFuture<Void> d; Throwable ex;
+- if ((d = this.dst) != null && d.result == null) {
+- try {
+- fn.run();
+- ex = null;
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- d.internalComplete(null, ex);
+- }
+- return true;
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class AsyncSupply<U> extends Async {
+- final Supplier<U> fn;
+- final CompletableFuture<U> dst;
+- AsyncSupply(Supplier<U> fn, CompletableFuture<U> dst) {
+- this.fn = fn; this.dst = dst;
+- }
+- public final boolean exec() {
+- CompletableFuture<U> d; U u; Throwable ex;
+- if ((d = this.dst) != null && d.result == null) {
+- try {
+- u = fn.get();
+- ex = null;
+- } catch (Throwable rex) {
+- ex = rex;
+- u = null;
+- }
+- d.internalComplete(u, ex);
+- }
+- return true;
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class AsyncApply<T,U> extends Async {
+- final T arg;
+- final Function<? super T,? extends U> fn;
+- final CompletableFuture<U> dst;
+- AsyncApply(T arg, Function<? super T,? extends U> fn,
+- CompletableFuture<U> dst) {
+- this.arg = arg; this.fn = fn; this.dst = dst;
+- }
+- public final boolean exec() {
+- CompletableFuture<U> d; U u; Throwable ex;
+- if ((d = this.dst) != null && d.result == null) {
+- try {
+- u = fn.apply(arg);
+- ex = null;
+- } catch (Throwable rex) {
+- ex = rex;
+- u = null;
+- }
+- d.internalComplete(u, ex);
+- }
+- return true;
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class AsyncCombine<T,U,V> extends Async {
+- final T arg1;
+- final U arg2;
+- final BiFunction<? super T,? super U,? extends V> fn;
+- final CompletableFuture<V> dst;
+- AsyncCombine(T arg1, U arg2,
+- BiFunction<? super T,? super U,? extends V> fn,
+- CompletableFuture<V> dst) {
+- this.arg1 = arg1; this.arg2 = arg2; this.fn = fn; this.dst = dst;
+- }
+- public final boolean exec() {
+- CompletableFuture<V> d; V v; Throwable ex;
+- if ((d = this.dst) != null && d.result == null) {
+- try {
+- v = fn.apply(arg1, arg2);
+- ex = null;
+- } catch (Throwable rex) {
+- ex = rex;
+- v = null;
+- }
+- d.internalComplete(v, ex);
+- }
+- return true;
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class AsyncAccept<T> extends Async {
+- final T arg;
+- final Consumer<? super T> fn;
+- final CompletableFuture<?> dst;
+- AsyncAccept(T arg, Consumer<? super T> fn,
+- CompletableFuture<?> dst) {
+- this.arg = arg; this.fn = fn; this.dst = dst;
+- }
+- public final boolean exec() {
+- CompletableFuture<?> d; Throwable ex;
+- if ((d = this.dst) != null && d.result == null) {
+- try {
+- fn.accept(arg);
+- ex = null;
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- d.internalComplete(null, ex);
+- }
+- return true;
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class AsyncAcceptBoth<T,U> extends Async {
+- final T arg1;
+- final U arg2;
+- final BiConsumer<? super T,? super U> fn;
+- final CompletableFuture<?> dst;
+- AsyncAcceptBoth(T arg1, U arg2,
+- BiConsumer<? super T,? super U> fn,
+- CompletableFuture<?> dst) {
+- this.arg1 = arg1; this.arg2 = arg2; this.fn = fn; this.dst = dst;
+- }
+- public final boolean exec() {
+- CompletableFuture<?> d; Throwable ex;
+- if ((d = this.dst) != null && d.result == null) {
+- try {
+- fn.accept(arg1, arg2);
+- ex = null;
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- d.internalComplete(null, ex);
+- }
+- return true;
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class AsyncCompose<T,U> extends Async {
+- final T arg;
+- final Function<? super T, ? extends CompletionStage<U>> fn;
+- final CompletableFuture<U> dst;
+- AsyncCompose(T arg,
+- Function<? super T, ? extends CompletionStage<U>> fn,
+- CompletableFuture<U> dst) {
+- this.arg = arg; this.fn = fn; this.dst = dst;
+- }
+- public final boolean exec() {
+- CompletableFuture<U> d, fr; U u; Throwable ex;
+- if ((d = this.dst) != null && d.result == null) {
+- try {
+- CompletionStage<U> cs = fn.apply(arg);
+- fr = (cs == null) ? null : cs.toCompletableFuture();
+- ex = (fr == null) ? new NullPointerException() : null;
+- } catch (Throwable rex) {
+- ex = rex;
+- fr = null;
+- }
+- if (ex != null)
+- u = null;
+- else {
+- Object r = fr.result;
+- if (r == null)
+- r = fr.waitingGet(false);
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- u = null;
+- }
+- else {
+- @SuppressWarnings("unchecked") U ur = (U) r;
+- u = ur;
+- }
+- }
+- d.internalComplete(u, ex);
+- }
+- return true;
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class AsyncWhenComplete<T> extends Async {
+- final T arg1;
+- final Throwable arg2;
+- final BiConsumer<? super T,? super Throwable> fn;
+- final CompletableFuture<T> dst;
+- AsyncWhenComplete(T arg1, Throwable arg2,
+- BiConsumer<? super T,? super Throwable> fn,
+- CompletableFuture<T> dst) {
+- this.arg1 = arg1; this.arg2 = arg2; this.fn = fn; this.dst = dst;
+- }
+- public final boolean exec() {
+- CompletableFuture<T> d;
+- if ((d = this.dst) != null && d.result == null) {
+- Throwable ex = arg2;
+- try {
+- fn.accept(arg1, ex);
+- } catch (Throwable rex) {
+- if (ex == null)
+- ex = rex;
+- }
+- d.internalComplete(arg1, ex);
+- }
+- return true;
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- /* ------------- Completions -------------- */
+-
+- /**
+- * Simple linked list nodes to record completions, used in
+- * basically the same way as WaitNodes. (We separate nodes from
+- * the Completions themselves mainly because for the And and Or
+- * methods, the same Completion object resides in two lists.)
+- */
+- static final class CompletionNode {
+- final Completion completion;
+- volatile CompletionNode next;
+- CompletionNode(Completion completion) { this.completion = completion; }
+- }
+-
+- // Opportunistically subclass AtomicInteger to use compareAndSet to claim.
+- @SuppressWarnings("serial")
+- abstract static class Completion extends AtomicInteger implements Runnable {
+- }
+-
+- static final class ThenApply<T,U> extends Completion {
+- final CompletableFuture<? extends T> src;
+- final Function<? super T,? extends U> fn;
+- final CompletableFuture<U> dst;
+- final Executor executor;
+- ThenApply(CompletableFuture<? extends T> src,
+- Function<? super T,? extends U> fn,
+- CompletableFuture<U> dst,
+- Executor executor) {
+- this.src = src; this.fn = fn; this.dst = dst;
+- this.executor = executor;
+- }
+- public final void run() {
+- final CompletableFuture<? extends T> a;
+- final Function<? super T,? extends U> fn;
+- final CompletableFuture<U> dst;
+- Object r; T t; Throwable ex;
+- if ((dst = this.dst) != null &&
+- (fn = this.fn) != null &&
+- (a = this.src) != null &&
+- (r = a.result) != null &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- Executor e = executor;
+- U u = null;
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncApply<T,U>(t, fn, dst));
+- else
+- u = fn.apply(t);
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(u, ex);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class ThenAccept<T> extends Completion {
+- final CompletableFuture<? extends T> src;
+- final Consumer<? super T> fn;
+- final CompletableFuture<?> dst;
+- final Executor executor;
+- ThenAccept(CompletableFuture<? extends T> src,
+- Consumer<? super T> fn,
+- CompletableFuture<?> dst,
+- Executor executor) {
+- this.src = src; this.fn = fn; this.dst = dst;
+- this.executor = executor;
+- }
+- public final void run() {
+- final CompletableFuture<? extends T> a;
+- final Consumer<? super T> fn;
+- final CompletableFuture<?> dst;
+- Object r; T t; Throwable ex;
+- if ((dst = this.dst) != null &&
+- (fn = this.fn) != null &&
+- (a = this.src) != null &&
+- (r = a.result) != null &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- Executor e = executor;
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncAccept<T>(t, fn, dst));
+- else
+- fn.accept(t);
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(null, ex);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class ThenRun extends Completion {
+- final CompletableFuture<?> src;
+- final Runnable fn;
+- final CompletableFuture<Void> dst;
+- final Executor executor;
+- ThenRun(CompletableFuture<?> src,
+- Runnable fn,
+- CompletableFuture<Void> dst,
+- Executor executor) {
+- this.src = src; this.fn = fn; this.dst = dst;
+- this.executor = executor;
+- }
+- public final void run() {
+- final CompletableFuture<?> a;
+- final Runnable fn;
+- final CompletableFuture<Void> dst;
+- Object r; Throwable ex;
+- if ((dst = this.dst) != null &&
+- (fn = this.fn) != null &&
+- (a = this.src) != null &&
+- (r = a.result) != null &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult)
+- ex = ((AltResult)r).ex;
+- else
+- ex = null;
+- Executor e = executor;
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncRun(fn, dst));
+- else
+- fn.run();
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(null, ex);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class ThenCombine<T,U,V> extends Completion {
+- final CompletableFuture<? extends T> src;
+- final CompletableFuture<? extends U> snd;
+- final BiFunction<? super T,? super U,? extends V> fn;
+- final CompletableFuture<V> dst;
+- final Executor executor;
+- ThenCombine(CompletableFuture<? extends T> src,
+- CompletableFuture<? extends U> snd,
+- BiFunction<? super T,? super U,? extends V> fn,
+- CompletableFuture<V> dst,
+- Executor executor) {
+- this.src = src; this.snd = snd;
+- this.fn = fn; this.dst = dst;
+- this.executor = executor;
+- }
+- public final void run() {
+- final CompletableFuture<? extends T> a;
+- final CompletableFuture<? extends U> b;
+- final BiFunction<? super T,? super U,? extends V> fn;
+- final CompletableFuture<V> dst;
+- Object r, s; T t; U u; Throwable ex;
+- if ((dst = this.dst) != null &&
+- (fn = this.fn) != null &&
+- (a = this.src) != null &&
+- (r = a.result) != null &&
+- (b = this.snd) != null &&
+- (s = b.result) != null &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- if (ex != null)
+- u = null;
+- else if (s instanceof AltResult) {
+- ex = ((AltResult)s).ex;
+- u = null;
+- }
+- else {
+- @SuppressWarnings("unchecked") U us = (U) s;
+- u = us;
+- }
+- Executor e = executor;
+- V v = null;
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncCombine<T,U,V>(t, u, fn, dst));
+- else
+- v = fn.apply(t, u);
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(v, ex);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class ThenAcceptBoth<T,U> extends Completion {
+- final CompletableFuture<? extends T> src;
+- final CompletableFuture<? extends U> snd;
+- final BiConsumer<? super T,? super U> fn;
+- final CompletableFuture<Void> dst;
+- final Executor executor;
+- ThenAcceptBoth(CompletableFuture<? extends T> src,
+- CompletableFuture<? extends U> snd,
+- BiConsumer<? super T,? super U> fn,
+- CompletableFuture<Void> dst,
+- Executor executor) {
+- this.src = src; this.snd = snd;
+- this.fn = fn; this.dst = dst;
+- this.executor = executor;
+- }
+- public final void run() {
+- final CompletableFuture<? extends T> a;
+- final CompletableFuture<? extends U> b;
+- final BiConsumer<? super T,? super U> fn;
+- final CompletableFuture<Void> dst;
+- Object r, s; T t; U u; Throwable ex;
+- if ((dst = this.dst) != null &&
+- (fn = this.fn) != null &&
+- (a = this.src) != null &&
+- (r = a.result) != null &&
+- (b = this.snd) != null &&
+- (s = b.result) != null &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- if (ex != null)
+- u = null;
+- else if (s instanceof AltResult) {
+- ex = ((AltResult)s).ex;
+- u = null;
+- }
+- else {
+- @SuppressWarnings("unchecked") U us = (U) s;
+- u = us;
+- }
+- Executor e = executor;
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncAcceptBoth<T,U>(t, u, fn, dst));
+- else
+- fn.accept(t, u);
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(null, ex);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class RunAfterBoth extends Completion {
+- final CompletableFuture<?> src;
+- final CompletableFuture<?> snd;
+- final Runnable fn;
+- final CompletableFuture<Void> dst;
+- final Executor executor;
+- RunAfterBoth(CompletableFuture<?> src,
+- CompletableFuture<?> snd,
+- Runnable fn,
+- CompletableFuture<Void> dst,
+- Executor executor) {
+- this.src = src; this.snd = snd;
+- this.fn = fn; this.dst = dst;
+- this.executor = executor;
+- }
+- public final void run() {
+- final CompletableFuture<?> a;
+- final CompletableFuture<?> b;
+- final Runnable fn;
+- final CompletableFuture<Void> dst;
+- Object r, s; Throwable ex;
+- if ((dst = this.dst) != null &&
+- (fn = this.fn) != null &&
+- (a = this.src) != null &&
+- (r = a.result) != null &&
+- (b = this.snd) != null &&
+- (s = b.result) != null &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult)
+- ex = ((AltResult)r).ex;
+- else
+- ex = null;
+- if (ex == null && (s instanceof AltResult))
+- ex = ((AltResult)s).ex;
+- Executor e = executor;
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncRun(fn, dst));
+- else
+- fn.run();
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(null, ex);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class AndCompletion extends Completion {
+- final CompletableFuture<?> src;
+- final CompletableFuture<?> snd;
+- final CompletableFuture<Void> dst;
+- AndCompletion(CompletableFuture<?> src,
+- CompletableFuture<?> snd,
+- CompletableFuture<Void> dst) {
+- this.src = src; this.snd = snd; this.dst = dst;
+- }
+- public final void run() {
+- final CompletableFuture<?> a;
+- final CompletableFuture<?> b;
+- final CompletableFuture<Void> dst;
+- Object r, s; Throwable ex;
+- if ((dst = this.dst) != null &&
+- (a = this.src) != null &&
+- (r = a.result) != null &&
+- (b = this.snd) != null &&
+- (s = b.result) != null &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult)
+- ex = ((AltResult)r).ex;
+- else
+- ex = null;
+- if (ex == null && (s instanceof AltResult))
+- ex = ((AltResult)s).ex;
+- dst.internalComplete(null, ex);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class ApplyToEither<T,U> extends Completion {
+- final CompletableFuture<? extends T> src;
+- final CompletableFuture<? extends T> snd;
+- final Function<? super T,? extends U> fn;
+- final CompletableFuture<U> dst;
+- final Executor executor;
+- ApplyToEither(CompletableFuture<? extends T> src,
+- CompletableFuture<? extends T> snd,
+- Function<? super T,? extends U> fn,
+- CompletableFuture<U> dst,
+- Executor executor) {
+- this.src = src; this.snd = snd;
+- this.fn = fn; this.dst = dst;
+- this.executor = executor;
+- }
+- public final void run() {
+- final CompletableFuture<? extends T> a;
+- final CompletableFuture<? extends T> b;
+- final Function<? super T,? extends U> fn;
+- final CompletableFuture<U> dst;
+- Object r; T t; Throwable ex;
+- if ((dst = this.dst) != null &&
+- (fn = this.fn) != null &&
+- (((a = this.src) != null && (r = a.result) != null) ||
+- ((b = this.snd) != null && (r = b.result) != null)) &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- Executor e = executor;
+- U u = null;
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncApply<T,U>(t, fn, dst));
+- else
+- u = fn.apply(t);
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(u, ex);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class AcceptEither<T> extends Completion {
+- final CompletableFuture<? extends T> src;
+- final CompletableFuture<? extends T> snd;
+- final Consumer<? super T> fn;
+- final CompletableFuture<Void> dst;
+- final Executor executor;
+- AcceptEither(CompletableFuture<? extends T> src,
+- CompletableFuture<? extends T> snd,
+- Consumer<? super T> fn,
+- CompletableFuture<Void> dst,
+- Executor executor) {
+- this.src = src; this.snd = snd;
+- this.fn = fn; this.dst = dst;
+- this.executor = executor;
+- }
+- public final void run() {
+- final CompletableFuture<? extends T> a;
+- final CompletableFuture<? extends T> b;
+- final Consumer<? super T> fn;
+- final CompletableFuture<Void> dst;
+- Object r; T t; Throwable ex;
+- if ((dst = this.dst) != null &&
+- (fn = this.fn) != null &&
+- (((a = this.src) != null && (r = a.result) != null) ||
+- ((b = this.snd) != null && (r = b.result) != null)) &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- Executor e = executor;
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncAccept<T>(t, fn, dst));
+- else
+- fn.accept(t);
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(null, ex);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class RunAfterEither extends Completion {
+- final CompletableFuture<?> src;
+- final CompletableFuture<?> snd;
+- final Runnable fn;
+- final CompletableFuture<Void> dst;
+- final Executor executor;
+- RunAfterEither(CompletableFuture<?> src,
+- CompletableFuture<?> snd,
+- Runnable fn,
+- CompletableFuture<Void> dst,
+- Executor executor) {
+- this.src = src; this.snd = snd;
+- this.fn = fn; this.dst = dst;
+- this.executor = executor;
+- }
+- public final void run() {
+- final CompletableFuture<?> a;
+- final CompletableFuture<?> b;
+- final Runnable fn;
+- final CompletableFuture<Void> dst;
+- Object r; Throwable ex;
+- if ((dst = this.dst) != null &&
+- (fn = this.fn) != null &&
+- (((a = this.src) != null && (r = a.result) != null) ||
+- ((b = this.snd) != null && (r = b.result) != null)) &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult)
+- ex = ((AltResult)r).ex;
+- else
+- ex = null;
+- Executor e = executor;
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncRun(fn, dst));
+- else
+- fn.run();
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(null, ex);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class OrCompletion extends Completion {
+- final CompletableFuture<?> src;
+- final CompletableFuture<?> snd;
+- final CompletableFuture<Object> dst;
+- OrCompletion(CompletableFuture<?> src,
+- CompletableFuture<?> snd,
+- CompletableFuture<Object> dst) {
+- this.src = src; this.snd = snd; this.dst = dst;
+- }
+- public final void run() {
+- final CompletableFuture<?> a;
+- final CompletableFuture<?> b;
+- final CompletableFuture<Object> dst;
+- Object r, t; Throwable ex;
+- if ((dst = this.dst) != null &&
+- (((a = this.src) != null && (r = a.result) != null) ||
+- ((b = this.snd) != null && (r = b.result) != null)) &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- t = r;
+- }
+- dst.internalComplete(t, ex);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class ExceptionCompletion<T> extends Completion {
+- final CompletableFuture<? extends T> src;
+- final Function<? super Throwable, ? extends T> fn;
+- final CompletableFuture<T> dst;
+- ExceptionCompletion(CompletableFuture<? extends T> src,
+- Function<? super Throwable, ? extends T> fn,
+- CompletableFuture<T> dst) {
+- this.src = src; this.fn = fn; this.dst = dst;
+- }
+- public final void run() {
+- final CompletableFuture<? extends T> a;
+- final Function<? super Throwable, ? extends T> fn;
+- final CompletableFuture<T> dst;
+- Object r; T t = null; Throwable ex, dx = null;
+- if ((dst = this.dst) != null &&
+- (fn = this.fn) != null &&
+- (a = this.src) != null &&
+- (r = a.result) != null &&
+- compareAndSet(0, 1)) {
+- if ((r instanceof AltResult) &&
+- (ex = ((AltResult)r).ex) != null) {
+- try {
+- t = fn.apply(ex);
+- } catch (Throwable rex) {
+- dx = rex;
+- }
+- }
+- else {
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- dst.internalComplete(t, dx);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class WhenCompleteCompletion<T> extends Completion {
+- final CompletableFuture<? extends T> src;
+- final BiConsumer<? super T, ? super Throwable> fn;
+- final CompletableFuture<T> dst;
+- final Executor executor;
+- WhenCompleteCompletion(CompletableFuture<? extends T> src,
+- BiConsumer<? super T, ? super Throwable> fn,
+- CompletableFuture<T> dst,
+- Executor executor) {
+- this.src = src; this.fn = fn; this.dst = dst;
+- this.executor = executor;
+- }
+- public final void run() {
+- final CompletableFuture<? extends T> a;
+- final BiConsumer<? super T, ? super Throwable> fn;
+- final CompletableFuture<T> dst;
+- Object r; T t; Throwable ex;
+- if ((dst = this.dst) != null &&
+- (fn = this.fn) != null &&
+- (a = this.src) != null &&
+- (r = a.result) != null &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- Executor e = executor;
+- Throwable dx = null;
+- try {
+- if (e != null)
+- execAsync(e, new AsyncWhenComplete<T>(t, ex, fn, dst));
+- else
+- fn.accept(t, ex);
+- } catch (Throwable rex) {
+- dx = rex;
+- }
+- if (e == null || dx != null)
+- dst.internalComplete(t, ex != null ? ex : dx);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class ThenCopy<T> extends Completion {
+- final CompletableFuture<?> src;
+- final CompletableFuture<T> dst;
+- ThenCopy(CompletableFuture<?> src,
+- CompletableFuture<T> dst) {
+- this.src = src; this.dst = dst;
+- }
+- public final void run() {
+- final CompletableFuture<?> a;
+- final CompletableFuture<T> dst;
+- Object r; T t; Throwable ex;
+- if ((dst = this.dst) != null &&
+- (a = this.src) != null &&
+- (r = a.result) != null &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- dst.internalComplete(t, ex);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- // version of ThenCopy for CompletableFuture<Void> dst
+- static final class ThenPropagate extends Completion {
+- final CompletableFuture<?> src;
+- final CompletableFuture<Void> dst;
+- ThenPropagate(CompletableFuture<?> src,
+- CompletableFuture<Void> dst) {
+- this.src = src; this.dst = dst;
+- }
+- public final void run() {
+- final CompletableFuture<?> a;
+- final CompletableFuture<Void> dst;
+- Object r; Throwable ex;
+- if ((dst = this.dst) != null &&
+- (a = this.src) != null &&
+- (r = a.result) != null &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult)
+- ex = ((AltResult)r).ex;
+- else
+- ex = null;
+- dst.internalComplete(null, ex);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class HandleCompletion<T,U> extends Completion {
+- final CompletableFuture<? extends T> src;
+- final BiFunction<? super T, Throwable, ? extends U> fn;
+- final CompletableFuture<U> dst;
+- final Executor executor;
+- HandleCompletion(CompletableFuture<? extends T> src,
+- BiFunction<? super T, Throwable, ? extends U> fn,
+- CompletableFuture<U> dst,
+- Executor executor) {
+- this.src = src; this.fn = fn; this.dst = dst;
+- this.executor = executor;
+- }
+- public final void run() {
+- final CompletableFuture<? extends T> a;
+- final BiFunction<? super T, Throwable, ? extends U> fn;
+- final CompletableFuture<U> dst;
+- Object r; T t; Throwable ex;
+- if ((dst = this.dst) != null &&
+- (fn = this.fn) != null &&
+- (a = this.src) != null &&
+- (r = a.result) != null &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- Executor e = executor;
+- U u = null;
+- Throwable dx = null;
+- try {
+- if (e != null)
+- execAsync(e, new AsyncCombine<T,Throwable,U>(t, ex, fn, dst));
+- else
+- u = fn.apply(t, ex);
+- } catch (Throwable rex) {
+- dx = rex;
+- }
+- if (e == null || dx != null)
+- dst.internalComplete(u, dx);
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- static final class ThenCompose<T,U> extends Completion {
+- final CompletableFuture<? extends T> src;
+- final Function<? super T, ? extends CompletionStage<U>> fn;
+- final CompletableFuture<U> dst;
+- final Executor executor;
+- ThenCompose(CompletableFuture<? extends T> src,
+- Function<? super T, ? extends CompletionStage<U>> fn,
+- CompletableFuture<U> dst,
+- Executor executor) {
+- this.src = src; this.fn = fn; this.dst = dst;
+- this.executor = executor;
+- }
+- public final void run() {
+- final CompletableFuture<? extends T> a;
+- final Function<? super T, ? extends CompletionStage<U>> fn;
+- final CompletableFuture<U> dst;
+- Object r; T t; Throwable ex; Executor e;
+- if ((dst = this.dst) != null &&
+- (fn = this.fn) != null &&
+- (a = this.src) != null &&
+- (r = a.result) != null &&
+- compareAndSet(0, 1)) {
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- CompletableFuture<U> c = null;
+- U u = null;
+- boolean complete = false;
+- if (ex == null) {
+- if ((e = executor) != null)
+- execAsync(e, new AsyncCompose<T,U>(t, fn, dst));
+- else {
+- try {
+- CompletionStage<U> cs = fn.apply(t);
+- c = (cs == null) ? null : cs.toCompletableFuture();
+- if (c == null)
+- ex = new NullPointerException();
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- }
+- if (c != null) {
+- ThenCopy<U> d = null;
+- Object s;
+- if ((s = c.result) == null) {
+- CompletionNode p = new CompletionNode
+- (d = new ThenCopy<U>(c, dst));
+- while ((s = c.result) == null) {
+- if (UNSAFE.compareAndSwapObject
+- (c, COMPLETIONS, p.next = c.completions, p))
+- break;
+- }
+- }
+- if (s != null && (d == null || d.compareAndSet(0, 1))) {
+- complete = true;
+- if (s instanceof AltResult) {
+- ex = ((AltResult)s).ex; // no rewrap
+- u = null;
+- }
+- else {
+- @SuppressWarnings("unchecked") U us = (U) s;
+- u = us;
+- }
+- }
+- }
+- if (complete || ex != null)
+- dst.internalComplete(u, ex);
+- if (c != null)
+- c.helpPostComplete();
+- }
+- }
+- private static final long serialVersionUID = 5232453952276885070L;
+- }
+-
+- // Implementations of stage methods with (plain, async, Executor) forms
+-
+- private <U> CompletableFuture<U> doThenApply
+- (Function<? super T,? extends U> fn,
+- Executor e) {
+- if (fn == null) throw new NullPointerException();
+- CompletableFuture<U> dst = new CompletableFuture<U>();
+- ThenApply<T,U> d = null;
+- Object r;
+- if ((r = result) == null) {
+- CompletionNode p = new CompletionNode
+- (d = new ThenApply<T,U>(this, fn, dst, e));
+- while ((r = result) == null) {
+- if (UNSAFE.compareAndSwapObject
+- (this, COMPLETIONS, p.next = completions, p))
+- break;
+- }
+- }
+- if (r != null && (d == null || d.compareAndSet(0, 1))) {
+- T t; Throwable ex;
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- U u = null;
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncApply<T,U>(t, fn, dst));
+- else
+- u = fn.apply(t);
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(u, ex);
+- }
+- helpPostComplete();
+- return dst;
+- }
+-
+- private CompletableFuture<Void> doThenAccept(Consumer<? super T> fn,
+- Executor e) {
+- if (fn == null) throw new NullPointerException();
+- CompletableFuture<Void> dst = new CompletableFuture<Void>();
+- ThenAccept<T> d = null;
+- Object r;
+- if ((r = result) == null) {
+- CompletionNode p = new CompletionNode
+- (d = new ThenAccept<T>(this, fn, dst, e));
+- while ((r = result) == null) {
+- if (UNSAFE.compareAndSwapObject
+- (this, COMPLETIONS, p.next = completions, p))
+- break;
+- }
+- }
+- if (r != null && (d == null || d.compareAndSet(0, 1))) {
+- T t; Throwable ex;
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncAccept<T>(t, fn, dst));
+- else
+- fn.accept(t);
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(null, ex);
+- }
+- helpPostComplete();
+- return dst;
+- }
+-
+- private CompletableFuture<Void> doThenRun(Runnable action,
+- Executor e) {
+- if (action == null) throw new NullPointerException();
+- CompletableFuture<Void> dst = new CompletableFuture<Void>();
+- ThenRun d = null;
+- Object r;
+- if ((r = result) == null) {
+- CompletionNode p = new CompletionNode
+- (d = new ThenRun(this, action, dst, e));
+- while ((r = result) == null) {
+- if (UNSAFE.compareAndSwapObject
+- (this, COMPLETIONS, p.next = completions, p))
+- break;
+- }
+- }
+- if (r != null && (d == null || d.compareAndSet(0, 1))) {
+- Throwable ex;
+- if (r instanceof AltResult)
+- ex = ((AltResult)r).ex;
+- else
+- ex = null;
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncRun(action, dst));
+- else
+- action.run();
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(null, ex);
+- }
+- helpPostComplete();
+- return dst;
+- }
+-
+- private <U,V> CompletableFuture<V> doThenCombine
+- (CompletableFuture<? extends U> other,
+- BiFunction<? super T,? super U,? extends V> fn,
+- Executor e) {
+- if (other == null || fn == null) throw new NullPointerException();
+- CompletableFuture<V> dst = new CompletableFuture<V>();
+- ThenCombine<T,U,V> d = null;
+- Object r, s = null;
+- if ((r = result) == null || (s = other.result) == null) {
+- d = new ThenCombine<T,U,V>(this, other, fn, dst, e);
+- CompletionNode q = null, p = new CompletionNode(d);
+- while ((r == null && (r = result) == null) ||
+- (s == null && (s = other.result) == null)) {
+- if (q != null) {
+- if (s != null ||
+- UNSAFE.compareAndSwapObject
+- (other, COMPLETIONS, q.next = other.completions, q))
+- break;
+- }
+- else if (r != null ||
+- UNSAFE.compareAndSwapObject
+- (this, COMPLETIONS, p.next = completions, p)) {
+- if (s != null)
+- break;
+- q = new CompletionNode(d);
+- }
+- }
+- }
+- if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
+- T t; U u; Throwable ex;
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- if (ex != null)
+- u = null;
+- else if (s instanceof AltResult) {
+- ex = ((AltResult)s).ex;
+- u = null;
+- }
+- else {
+- @SuppressWarnings("unchecked") U us = (U) s;
+- u = us;
+- }
+- V v = null;
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncCombine<T,U,V>(t, u, fn, dst));
+- else
+- v = fn.apply(t, u);
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(v, ex);
+- }
+- helpPostComplete();
+- other.helpPostComplete();
+- return dst;
+- }
+-
+- private <U> CompletableFuture<Void> doThenAcceptBoth
+- (CompletableFuture<? extends U> other,
+- BiConsumer<? super T,? super U> fn,
+- Executor e) {
+- if (other == null || fn == null) throw new NullPointerException();
+- CompletableFuture<Void> dst = new CompletableFuture<Void>();
+- ThenAcceptBoth<T,U> d = null;
+- Object r, s = null;
+- if ((r = result) == null || (s = other.result) == null) {
+- d = new ThenAcceptBoth<T,U>(this, other, fn, dst, e);
+- CompletionNode q = null, p = new CompletionNode(d);
+- while ((r == null && (r = result) == null) ||
+- (s == null && (s = other.result) == null)) {
+- if (q != null) {
+- if (s != null ||
+- UNSAFE.compareAndSwapObject
+- (other, COMPLETIONS, q.next = other.completions, q))
+- break;
+- }
+- else if (r != null ||
+- UNSAFE.compareAndSwapObject
+- (this, COMPLETIONS, p.next = completions, p)) {
+- if (s != null)
+- break;
+- q = new CompletionNode(d);
+- }
+- }
+- }
+- if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
+- T t; U u; Throwable ex;
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- if (ex != null)
+- u = null;
+- else if (s instanceof AltResult) {
+- ex = ((AltResult)s).ex;
+- u = null;
+- }
+- else {
+- @SuppressWarnings("unchecked") U us = (U) s;
+- u = us;
+- }
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncAcceptBoth<T,U>(t, u, fn, dst));
+- else
+- fn.accept(t, u);
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(null, ex);
+- }
+- helpPostComplete();
+- other.helpPostComplete();
+- return dst;
+- }
+-
+- private CompletableFuture<Void> doRunAfterBoth(CompletableFuture<?> other,
+- Runnable action,
+- Executor e) {
+- if (other == null || action == null) throw new NullPointerException();
+- CompletableFuture<Void> dst = new CompletableFuture<Void>();
+- RunAfterBoth d = null;
+- Object r, s = null;
+- if ((r = result) == null || (s = other.result) == null) {
+- d = new RunAfterBoth(this, other, action, dst, e);
+- CompletionNode q = null, p = new CompletionNode(d);
+- while ((r == null && (r = result) == null) ||
+- (s == null && (s = other.result) == null)) {
+- if (q != null) {
+- if (s != null ||
+- UNSAFE.compareAndSwapObject
+- (other, COMPLETIONS, q.next = other.completions, q))
+- break;
+- }
+- else if (r != null ||
+- UNSAFE.compareAndSwapObject
+- (this, COMPLETIONS, p.next = completions, p)) {
+- if (s != null)
+- break;
+- q = new CompletionNode(d);
+- }
+- }
+- }
+- if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
+- Throwable ex;
+- if (r instanceof AltResult)
+- ex = ((AltResult)r).ex;
+- else
+- ex = null;
+- if (ex == null && (s instanceof AltResult))
+- ex = ((AltResult)s).ex;
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncRun(action, dst));
+- else
+- action.run();
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(null, ex);
+- }
+- helpPostComplete();
+- other.helpPostComplete();
+- return dst;
+- }
+-
+- private <U> CompletableFuture<U> doApplyToEither
+- (CompletableFuture<? extends T> other,
+- Function<? super T, U> fn,
+- Executor e) {
+- if (other == null || fn == null) throw new NullPointerException();
+- CompletableFuture<U> dst = new CompletableFuture<U>();
+- ApplyToEither<T,U> d = null;
+- Object r;
+- if ((r = result) == null && (r = other.result) == null) {
+- d = new ApplyToEither<T,U>(this, other, fn, dst, e);
+- CompletionNode q = null, p = new CompletionNode(d);
+- while ((r = result) == null && (r = other.result) == null) {
+- if (q != null) {
+- if (UNSAFE.compareAndSwapObject
+- (other, COMPLETIONS, q.next = other.completions, q))
+- break;
+- }
+- else if (UNSAFE.compareAndSwapObject
+- (this, COMPLETIONS, p.next = completions, p))
+- q = new CompletionNode(d);
+- }
+- }
+- if (r != null && (d == null || d.compareAndSet(0, 1))) {
+- T t; Throwable ex;
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- U u = null;
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncApply<T,U>(t, fn, dst));
+- else
+- u = fn.apply(t);
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(u, ex);
+- }
+- helpPostComplete();
+- other.helpPostComplete();
+- return dst;
+- }
+-
+- private CompletableFuture<Void> doAcceptEither
+- (CompletableFuture<? extends T> other,
+- Consumer<? super T> fn,
+- Executor e) {
+- if (other == null || fn == null) throw new NullPointerException();
+- CompletableFuture<Void> dst = new CompletableFuture<Void>();
+- AcceptEither<T> d = null;
+- Object r;
+- if ((r = result) == null && (r = other.result) == null) {
+- d = new AcceptEither<T>(this, other, fn, dst, e);
+- CompletionNode q = null, p = new CompletionNode(d);
+- while ((r = result) == null && (r = other.result) == null) {
+- if (q != null) {
+- if (UNSAFE.compareAndSwapObject
+- (other, COMPLETIONS, q.next = other.completions, q))
+- break;
+- }
+- else if (UNSAFE.compareAndSwapObject
+- (this, COMPLETIONS, p.next = completions, p))
+- q = new CompletionNode(d);
+- }
+- }
+- if (r != null && (d == null || d.compareAndSet(0, 1))) {
+- T t; Throwable ex;
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncAccept<T>(t, fn, dst));
+- else
+- fn.accept(t);
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(null, ex);
+- }
+- helpPostComplete();
+- other.helpPostComplete();
+- return dst;
+- }
+-
+- private CompletableFuture<Void> doRunAfterEither
+- (CompletableFuture<?> other,
+- Runnable action,
+- Executor e) {
+- if (other == null || action == null) throw new NullPointerException();
+- CompletableFuture<Void> dst = new CompletableFuture<Void>();
+- RunAfterEither d = null;
+- Object r;
+- if ((r = result) == null && (r = other.result) == null) {
+- d = new RunAfterEither(this, other, action, dst, e);
+- CompletionNode q = null, p = new CompletionNode(d);
+- while ((r = result) == null && (r = other.result) == null) {
+- if (q != null) {
+- if (UNSAFE.compareAndSwapObject
+- (other, COMPLETIONS, q.next = other.completions, q))
+- break;
+- }
+- else if (UNSAFE.compareAndSwapObject
+- (this, COMPLETIONS, p.next = completions, p))
+- q = new CompletionNode(d);
+- }
+- }
+- if (r != null && (d == null || d.compareAndSet(0, 1))) {
+- Throwable ex;
+- if (r instanceof AltResult)
+- ex = ((AltResult)r).ex;
+- else
+- ex = null;
+- if (ex == null) {
+- try {
+- if (e != null)
+- execAsync(e, new AsyncRun(action, dst));
+- else
+- action.run();
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- if (e == null || ex != null)
+- dst.internalComplete(null, ex);
+- }
+- helpPostComplete();
+- other.helpPostComplete();
+- return dst;
+- }
+-
+- private <U> CompletableFuture<U> doThenCompose
+- (Function<? super T, ? extends CompletionStage<U>> fn,
+- Executor e) {
+- if (fn == null) throw new NullPointerException();
+- CompletableFuture<U> dst = null;
+- ThenCompose<T,U> d = null;
+- Object r;
+- if ((r = result) == null) {
+- dst = new CompletableFuture<U>();
+- CompletionNode p = new CompletionNode
+- (d = new ThenCompose<T,U>(this, fn, dst, e));
+- while ((r = result) == null) {
+- if (UNSAFE.compareAndSwapObject
+- (this, COMPLETIONS, p.next = completions, p))
+- break;
+- }
+- }
+- if (r != null && (d == null || d.compareAndSet(0, 1))) {
+- T t; Throwable ex;
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- if (ex == null) {
+- if (e != null) {
+- if (dst == null)
+- dst = new CompletableFuture<U>();
+- execAsync(e, new AsyncCompose<T,U>(t, fn, dst));
+- }
+- else {
+- try {
+- CompletionStage<U> cs = fn.apply(t);
+- if (cs == null ||
+- (dst = cs.toCompletableFuture()) == null)
+- ex = new NullPointerException();
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- }
+- }
+- if (dst == null)
+- dst = new CompletableFuture<U>();
+- if (ex != null)
+- dst.internalComplete(null, ex);
+- }
+- helpPostComplete();
+- dst.helpPostComplete();
+- return dst;
+- }
+-
+- private CompletableFuture<T> doWhenComplete
+- (BiConsumer<? super T, ? super Throwable> fn,
+- Executor e) {
+- if (fn == null) throw new NullPointerException();
+- CompletableFuture<T> dst = new CompletableFuture<T>();
+- WhenCompleteCompletion<T> d = null;
+- Object r;
+- if ((r = result) == null) {
+- CompletionNode p =
+- new CompletionNode(d = new WhenCompleteCompletion<T>
+- (this, fn, dst, e));
+- while ((r = result) == null) {
+- if (UNSAFE.compareAndSwapObject(this, COMPLETIONS,
+- p.next = completions, p))
+- break;
+- }
+- }
+- if (r != null && (d == null || d.compareAndSet(0, 1))) {
+- T t; Throwable ex;
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- Throwable dx = null;
+- try {
+- if (e != null)
+- execAsync(e, new AsyncWhenComplete<T>(t, ex, fn, dst));
+- else
+- fn.accept(t, ex);
+- } catch (Throwable rex) {
+- dx = rex;
+- }
+- if (e == null || dx != null)
+- dst.internalComplete(t, ex != null ? ex : dx);
+- }
+- helpPostComplete();
+- return dst;
+- }
+-
+- private <U> CompletableFuture<U> doHandle
+- (BiFunction<? super T, Throwable, ? extends U> fn,
+- Executor e) {
+- if (fn == null) throw new NullPointerException();
+- CompletableFuture<U> dst = new CompletableFuture<U>();
+- HandleCompletion<T,U> d = null;
+- Object r;
+- if ((r = result) == null) {
+- CompletionNode p =
+- new CompletionNode(d = new HandleCompletion<T,U>
+- (this, fn, dst, e));
+- while ((r = result) == null) {
+- if (UNSAFE.compareAndSwapObject(this, COMPLETIONS,
+- p.next = completions, p))
+- break;
+- }
+- }
+- if (r != null && (d == null || d.compareAndSet(0, 1))) {
+- T t; Throwable ex;
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- U u = null;
+- Throwable dx = null;
+- try {
+- if (e != null)
+- execAsync(e, new AsyncCombine<T,Throwable,U>(t, ex, fn, dst));
+- else {
+- u = fn.apply(t, ex);
+- dx = null;
+- }
+- } catch (Throwable rex) {
+- dx = rex;
+- u = null;
+- }
+- if (e == null || dx != null)
+- dst.internalComplete(u, dx);
+- }
+- helpPostComplete();
+- return dst;
+- }
+-
+-
+- // public methods
++ /* ------------- public methods -------------- */
+
+ /**
+ * Creates a new incomplete CompletableFuture.
+@@ -2114,6 +1786,13 @@
+ }
+
+ /**
++ * Creates a new complete CompletableFuture with given encoded result.
++ */
++ private CompletableFuture(Object r) {
++ this.result = r;
++ }
++
++ /**
+ * Returns a new CompletableFuture that is asynchronously completed
+ * by a task running in the {@link ForkJoinPool#commonPool()} with
+ * the value obtained by calling the given Supplier.
+@@ -2124,10 +1803,7 @@
+ * @return the new CompletableFuture
+ */
+ public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
+- if (supplier == null) throw new NullPointerException();
+- CompletableFuture<U> f = new CompletableFuture<U>();
+- execAsync(ForkJoinPool.commonPool(), new AsyncSupply<U>(supplier, f));
+- return f;
++ return asyncSupplyStage(asyncPool, supplier);
+ }
+
+ /**
+@@ -2143,11 +1819,7 @@
+ */
+ public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
+ Executor executor) {
+- if (executor == null || supplier == null)
+- throw new NullPointerException();
+- CompletableFuture<U> f = new CompletableFuture<U>();
+- execAsync(executor, new AsyncSupply<U>(supplier, f));
+- return f;
++ return asyncSupplyStage(screenExecutor(executor), supplier);
+ }
+
+ /**
+@@ -2160,10 +1832,7 @@
+ * @return the new CompletableFuture
+ */
+ public static CompletableFuture<Void> runAsync(Runnable runnable) {
+- if (runnable == null) throw new NullPointerException();
+- CompletableFuture<Void> f = new CompletableFuture<Void>();
+- execAsync(ForkJoinPool.commonPool(), new AsyncRun(runnable, f));
+- return f;
++ return asyncRunStage(asyncPool, runnable);
+ }
+
+ /**
+@@ -2178,11 +1847,7 @@
+ */
+ public static CompletableFuture<Void> runAsync(Runnable runnable,
+ Executor executor) {
+- if (executor == null || runnable == null)
+- throw new NullPointerException();
+- CompletableFuture<Void> f = new CompletableFuture<Void>();
+- execAsync(executor, new AsyncRun(runnable, f));
+- return f;
++ return asyncRunStage(screenExecutor(executor), runnable);
+ }
+
+ /**
+@@ -2194,9 +1859,7 @@
+ * @return the completed CompletableFuture
+ */
+ public static <U> CompletableFuture<U> completedFuture(U value) {
+- CompletableFuture<U> f = new CompletableFuture<U>();
+- f.result = (value == null) ? NIL : value;
+- return f;
++ return new CompletableFuture<U>((value == null) ? NIL : value);
+ }
+
+ /**
+@@ -2220,21 +1883,8 @@
+ * while waiting
+ */
+ public T get() throws InterruptedException, ExecutionException {
+- Object r; Throwable ex, cause;
+- if ((r = result) == null && (r = waitingGet(true)) == null)
+- throw new InterruptedException();
+- if (!(r instanceof AltResult)) {
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- return tr;
+- }
+- if ((ex = ((AltResult)r).ex) == null)
+- return null;
+- if (ex instanceof CancellationException)
+- throw (CancellationException)ex;
+- if ((ex instanceof CompletionException) &&
+- (cause = ex.getCause()) != null)
+- ex = cause;
+- throw new ExecutionException(ex);
++ Object r;
++ return reportGet((r = result) == null ? waitingGet(true) : r);
+ }
+
+ /**
+@@ -2252,24 +1902,9 @@
+ */
+ public T get(long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException {
+- Object r; Throwable ex, cause;
++ Object r;
+ long nanos = unit.toNanos(timeout);
+- if (Thread.interrupted())
+- throw new InterruptedException();
+- if ((r = result) == null)
+- r = timedAwaitDone(nanos);
+- if (!(r instanceof AltResult)) {
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- return tr;
+- }
+- if ((ex = ((AltResult)r).ex) == null)
+- return null;
+- if (ex instanceof CancellationException)
+- throw (CancellationException)ex;
+- if ((ex instanceof CompletionException) &&
+- (cause = ex.getCause()) != null)
+- ex = cause;
+- throw new ExecutionException(ex);
++ return reportGet((r = result) == null ? timedGet(nanos) : r);
+ }
+
+ /**
+@@ -2287,20 +1922,8 @@
+ * exceptionally or a completion computation threw an exception
+ */
+ public T join() {
+- Object r; Throwable ex;
+- if ((r = result) == null)
+- r = waitingGet(false);
+- if (!(r instanceof AltResult)) {
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- return tr;
+- }
+- if ((ex = ((AltResult)r).ex) == null)
+- return null;
+- if (ex instanceof CancellationException)
+- throw (CancellationException)ex;
+- if (ex instanceof CompletionException)
+- throw (CompletionException)ex;
+- throw new CompletionException(ex);
++ Object r;
++ return reportJoin((r = result) == null ? waitingGet(false) : r);
+ }
+
+ /**
+@@ -2314,20 +1937,8 @@
+ * exceptionally or a completion computation threw an exception
+ */
+ public T getNow(T valueIfAbsent) {
+- Object r; Throwable ex;
+- if ((r = result) == null)
+- return valueIfAbsent;
+- if (!(r instanceof AltResult)) {
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- return tr;
+- }
+- if ((ex = ((AltResult)r).ex) == null)
+- return null;
+- if (ex instanceof CancellationException)
+- throw (CancellationException)ex;
+- if (ex instanceof CompletionException)
+- throw (CompletionException)ex;
+- throw new CompletionException(ex);
++ Object r;
++ return ((r = result) == null) ? valueIfAbsent : reportJoin(r);
+ }
+
+ /**
+@@ -2339,9 +1950,7 @@
+ * to transition to a completed state, else {@code false}
+ */
+ public boolean complete(T value) {
+- boolean triggered = result == null &&
+- UNSAFE.compareAndSwapObject(this, RESULT, null,
+- value == null ? NIL : value);
++ boolean triggered = completeValue(value);
+ postComplete();
+ return triggered;
+ }
+@@ -2356,244 +1965,200 @@
+ */
+ public boolean completeExceptionally(Throwable ex) {
+ if (ex == null) throw new NullPointerException();
+- boolean triggered = result == null &&
+- UNSAFE.compareAndSwapObject(this, RESULT, null, new AltResult(ex));
++ boolean triggered = internalComplete(new AltResult(ex));
+ postComplete();
+ return triggered;
+ }
+
+- // CompletionStage methods
+-
+- public <U> CompletableFuture<U> thenApply
+- (Function<? super T,? extends U> fn) {
+- return doThenApply(fn, null);
++ public <U> CompletableFuture<U> thenApply(
++ Function<? super T,? extends U> fn) {
++ return uniApplyStage(null, fn);
+ }
+
+- public <U> CompletableFuture<U> thenApplyAsync
+- (Function<? super T,? extends U> fn) {
+- return doThenApply(fn, ForkJoinPool.commonPool());
++ public <U> CompletableFuture<U> thenApplyAsync(
++ Function<? super T,? extends U> fn) {
++ return uniApplyStage(asyncPool, fn);
+ }
+
+- public <U> CompletableFuture<U> thenApplyAsync
+- (Function<? super T,? extends U> fn,
+- Executor executor) {
+- if (executor == null) throw new NullPointerException();
+- return doThenApply(fn, executor);
++ public <U> CompletableFuture<U> thenApplyAsync(
++ Function<? super T,? extends U> fn, Executor executor) {
++ return uniApplyStage(screenExecutor(executor), fn);
+ }
+
+- public CompletableFuture<Void> thenAccept
+- (Consumer<? super T> action) {
+- return doThenAccept(action, null);
++ public CompletableFuture<Void> thenAccept(Consumer<? super T> action) {
++ return uniAcceptStage(null, action);
+ }
+
+- public CompletableFuture<Void> thenAcceptAsync
+- (Consumer<? super T> action) {
+- return doThenAccept(action, ForkJoinPool.commonPool());
++ public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action) {
++ return uniAcceptStage(asyncPool, action);
+ }
+
+- public CompletableFuture<Void> thenAcceptAsync
+- (Consumer<? super T> action,
+- Executor executor) {
+- if (executor == null) throw new NullPointerException();
+- return doThenAccept(action, executor);
++ public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action,
++ Executor executor) {
++ return uniAcceptStage(screenExecutor(executor), action);
+ }
+
+- public CompletableFuture<Void> thenRun
+- (Runnable action) {
+- return doThenRun(action, null);
++ public CompletableFuture<Void> thenRun(Runnable action) {
++ return uniRunStage(null, action);
+ }
+
+- public CompletableFuture<Void> thenRunAsync
+- (Runnable action) {
+- return doThenRun(action, ForkJoinPool.commonPool());
++ public CompletableFuture<Void> thenRunAsync(Runnable action) {
++ return uniRunStage(asyncPool, action);
+ }
+
+- public CompletableFuture<Void> thenRunAsync
+- (Runnable action,
+- Executor executor) {
+- if (executor == null) throw new NullPointerException();
+- return doThenRun(action, executor);
++ public CompletableFuture<Void> thenRunAsync(Runnable action,
++ Executor executor) {
++ return uniRunStage(screenExecutor(executor), action);
+ }
+
+- public <U,V> CompletableFuture<V> thenCombine
+- (CompletionStage<? extends U> other,
+- BiFunction<? super T,? super U,? extends V> fn) {
+- return doThenCombine(other.toCompletableFuture(), fn, null);
++ public <U,V> CompletableFuture<V> thenCombine(
++ CompletionStage<? extends U> other,
++ BiFunction<? super T,? super U,? extends V> fn) {
++ return biApplyStage(null, other, fn);
+ }
+
+- public <U,V> CompletableFuture<V> thenCombineAsync
+- (CompletionStage<? extends U> other,
+- BiFunction<? super T,? super U,? extends V> fn) {
+- return doThenCombine(other.toCompletableFuture(), fn,
+- ForkJoinPool.commonPool());
++ public <U,V> CompletableFuture<V> thenCombineAsync(
++ CompletionStage<? extends U> other,
++ BiFunction<? super T,? super U,? extends V> fn) {
++ return biApplyStage(asyncPool, other, fn);
+ }
+
+- public <U,V> CompletableFuture<V> thenCombineAsync
+- (CompletionStage<? extends U> other,
+- BiFunction<? super T,? super U,? extends V> fn,
+- Executor executor) {
+- if (executor == null) throw new NullPointerException();
+- return doThenCombine(other.toCompletableFuture(), fn, executor);
++ public <U,V> CompletableFuture<V> thenCombineAsync(
++ CompletionStage<? extends U> other,
++ BiFunction<? super T,? super U,? extends V> fn, Executor executor) {
++ return biApplyStage(screenExecutor(executor), other, fn);
+ }
+
+- public <U> CompletableFuture<Void> thenAcceptBoth
+- (CompletionStage<? extends U> other,
+- BiConsumer<? super T, ? super U> action) {
+- return doThenAcceptBoth(other.toCompletableFuture(), action, null);
++ public <U> CompletableFuture<Void> thenAcceptBoth(
++ CompletionStage<? extends U> other,
++ BiConsumer<? super T, ? super U> action) {
++ return biAcceptStage(null, other, action);
+ }
+
+- public <U> CompletableFuture<Void> thenAcceptBothAsync
+- (CompletionStage<? extends U> other,
+- BiConsumer<? super T, ? super U> action) {
+- return doThenAcceptBoth(other.toCompletableFuture(), action,
+- ForkJoinPool.commonPool());
++ public <U> CompletableFuture<Void> thenAcceptBothAsync(
++ CompletionStage<? extends U> other,
++ BiConsumer<? super T, ? super U> action) {
++ return biAcceptStage(asyncPool, other, action);
+ }
+
+- public <U> CompletableFuture<Void> thenAcceptBothAsync
+- (CompletionStage<? extends U> other,
+- BiConsumer<? super T, ? super U> action,
+- Executor executor) {
+- if (executor == null) throw new NullPointerException();
+- return doThenAcceptBoth(other.toCompletableFuture(), action, executor);
++ public <U> CompletableFuture<Void> thenAcceptBothAsync(
++ CompletionStage<? extends U> other,
++ BiConsumer<? super T, ? super U> action, Executor executor) {
++ return biAcceptStage(screenExecutor(executor), other, action);
+ }
+
+- public CompletableFuture<Void> runAfterBoth
+- (CompletionStage<?> other,
+- Runnable action) {
+- return doRunAfterBoth(other.toCompletableFuture(), action, null);
++ public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,
++ Runnable action) {
++ return biRunStage(null, other, action);
+ }
+
+- public CompletableFuture<Void> runAfterBothAsync
+- (CompletionStage<?> other,
+- Runnable action) {
+- return doRunAfterBoth(other.toCompletableFuture(), action,
+- ForkJoinPool.commonPool());
++ public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other,
++ Runnable action) {
++ return biRunStage(asyncPool, other, action);
+ }
+
+- public CompletableFuture<Void> runAfterBothAsync
+- (CompletionStage<?> other,
+- Runnable action,
+- Executor executor) {
+- if (executor == null) throw new NullPointerException();
+- return doRunAfterBoth(other.toCompletableFuture(), action, executor);
++ public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other,
++ Runnable action,
++ Executor executor) {
++ return biRunStage(screenExecutor(executor), other, action);
+ }
+
+-
+- public <U> CompletableFuture<U> applyToEither
+- (CompletionStage<? extends T> other,
+- Function<? super T, U> fn) {
+- return doApplyToEither(other.toCompletableFuture(), fn, null);
++ public <U> CompletableFuture<U> applyToEither(
++ CompletionStage<? extends T> other, Function<? super T, U> fn) {
++ return orApplyStage(null, other, fn);
+ }
+
+- public <U> CompletableFuture<U> applyToEitherAsync
+- (CompletionStage<? extends T> other,
+- Function<? super T, U> fn) {
+- return doApplyToEither(other.toCompletableFuture(), fn,
+- ForkJoinPool.commonPool());
++ public <U> CompletableFuture<U> applyToEitherAsync(
++ CompletionStage<? extends T> other, Function<? super T, U> fn) {
++ return orApplyStage(asyncPool, other, fn);
+ }
+
+- public <U> CompletableFuture<U> applyToEitherAsync
+- (CompletionStage<? extends T> other,
+- Function<? super T, U> fn,
+- Executor executor) {
+- if (executor == null) throw new NullPointerException();
+- return doApplyToEither(other.toCompletableFuture(), fn, executor);
++ public <U> CompletableFuture<U> applyToEitherAsync(
++ CompletionStage<? extends T> other, Function<? super T, U> fn,
++ Executor executor) {
++ return orApplyStage(screenExecutor(executor), other, fn);
+ }
+
+- public CompletableFuture<Void> acceptEither
+- (CompletionStage<? extends T> other,
+- Consumer<? super T> action) {
+- return doAcceptEither(other.toCompletableFuture(), action, null);
++ public CompletableFuture<Void> acceptEither(
++ CompletionStage<? extends T> other, Consumer<? super T> action) {
++ return orAcceptStage(null, other, action);
+ }
+
+- public CompletableFuture<Void> acceptEitherAsync
+- (CompletionStage<? extends T> other,
+- Consumer<? super T> action) {
+- return doAcceptEither(other.toCompletableFuture(), action,
+- ForkJoinPool.commonPool());
++ public CompletableFuture<Void> acceptEitherAsync(
++ CompletionStage<? extends T> other, Consumer<? super T> action) {
++ return orAcceptStage(asyncPool, other, action);
+ }
+
+- public CompletableFuture<Void> acceptEitherAsync
+- (CompletionStage<? extends T> other,
+- Consumer<? super T> action,
+- Executor executor) {
+- if (executor == null) throw new NullPointerException();
+- return doAcceptEither(other.toCompletableFuture(), action, executor);
++ public CompletableFuture<Void> acceptEitherAsync(
++ CompletionStage<? extends T> other, Consumer<? super T> action,
++ Executor executor) {
++ return orAcceptStage(screenExecutor(executor), other, action);
+ }
+
+ public CompletableFuture<Void> runAfterEither(CompletionStage<?> other,
+ Runnable action) {
+- return doRunAfterEither(other.toCompletableFuture(), action, null);
++ return orRunStage(null, other, action);
+ }
+
+- public CompletableFuture<Void> runAfterEitherAsync
+- (CompletionStage<?> other,
+- Runnable action) {
+- return doRunAfterEither(other.toCompletableFuture(), action,
+- ForkJoinPool.commonPool());
++ public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,
++ Runnable action) {
++ return orRunStage(asyncPool, other, action);
+ }
+
+- public CompletableFuture<Void> runAfterEitherAsync
+- (CompletionStage<?> other,
+- Runnable action,
+- Executor executor) {
+- if (executor == null) throw new NullPointerException();
+- return doRunAfterEither(other.toCompletableFuture(), action, executor);
++ public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,
++ Runnable action,
++ Executor executor) {
++ return orRunStage(screenExecutor(executor), other, action);
+ }
+
+- public <U> CompletableFuture<U> thenCompose
+- (Function<? super T, ? extends CompletionStage<U>> fn) {
+- return doThenCompose(fn, null);
++ public <U> CompletableFuture<U> thenCompose(
++ Function<? super T, ? extends CompletionStage<U>> fn) {
++ return uniComposeStage(null, fn);
+ }
+
+- public <U> CompletableFuture<U> thenComposeAsync
+- (Function<? super T, ? extends CompletionStage<U>> fn) {
+- return doThenCompose(fn, ForkJoinPool.commonPool());
++ public <U> CompletableFuture<U> thenComposeAsync(
++ Function<? super T, ? extends CompletionStage<U>> fn) {
++ return uniComposeStage(asyncPool, fn);
+ }
+
+- public <U> CompletableFuture<U> thenComposeAsync
+- (Function<? super T, ? extends CompletionStage<U>> fn,
+- Executor executor) {
+- if (executor == null) throw new NullPointerException();
+- return doThenCompose(fn, executor);
++ public <U> CompletableFuture<U> thenComposeAsync(
++ Function<? super T, ? extends CompletionStage<U>> fn,
++ Executor executor) {
++ return uniComposeStage(screenExecutor(executor), fn);
+ }
+
+- public CompletableFuture<T> whenComplete
+- (BiConsumer<? super T, ? super Throwable> action) {
+- return doWhenComplete(action, null);
++ public CompletableFuture<T> whenComplete(
++ BiConsumer<? super T, ? super Throwable> action) {
++ return uniWhenCompleteStage(null, action);
+ }
+
+- public CompletableFuture<T> whenCompleteAsync
+- (BiConsumer<? super T, ? super Throwable> action) {
+- return doWhenComplete(action, ForkJoinPool.commonPool());
++ public CompletableFuture<T> whenCompleteAsync(
++ BiConsumer<? super T, ? super Throwable> action) {
++ return uniWhenCompleteStage(asyncPool, action);
+ }
+
+- public CompletableFuture<T> whenCompleteAsync
+- (BiConsumer<? super T, ? super Throwable> action,
+- Executor executor) {
+- if (executor == null) throw new NullPointerException();
+- return doWhenComplete(action, executor);
++ public CompletableFuture<T> whenCompleteAsync(
++ BiConsumer<? super T, ? super Throwable> action, Executor executor) {
++ return uniWhenCompleteStage(screenExecutor(executor), action);
+ }
+
+- public <U> CompletableFuture<U> handle
+- (BiFunction<? super T, Throwable, ? extends U> fn) {
+- return doHandle(fn, null);
++ public <U> CompletableFuture<U> handle(
++ BiFunction<? super T, Throwable, ? extends U> fn) {
++ return uniHandleStage(null, fn);
+ }
+
+- public <U> CompletableFuture<U> handleAsync
+- (BiFunction<? super T, Throwable, ? extends U> fn) {
+- return doHandle(fn, ForkJoinPool.commonPool());
++ public <U> CompletableFuture<U> handleAsync(
++ BiFunction<? super T, Throwable, ? extends U> fn) {
++ return uniHandleStage(asyncPool, fn);
+ }
+
+- public <U> CompletableFuture<U> handleAsync
+- (BiFunction<? super T, Throwable, ? extends U> fn,
+- Executor executor) {
+- if (executor == null) throw new NullPointerException();
+- return doHandle(fn, executor);
++ public <U> CompletableFuture<U> handleAsync(
++ BiFunction<? super T, Throwable, ? extends U> fn, Executor executor) {
++ return uniHandleStage(screenExecutor(executor), fn);
+ }
+
+ /**
+- * Returns this CompletableFuture
++ * Returns this CompletableFuture.
+ *
+ * @return this CompletableFuture
+ */
+@@ -2618,52 +2183,13 @@
+ * exceptionally
+ * @return the new CompletableFuture
+ */
+- public CompletableFuture<T> exceptionally
+- (Function<Throwable, ? extends T> fn) {
+- if (fn == null) throw new NullPointerException();
+- CompletableFuture<T> dst = new CompletableFuture<T>();
+- ExceptionCompletion<T> d = null;
+- Object r;
+- if ((r = result) == null) {
+- CompletionNode p =
+- new CompletionNode(d = new ExceptionCompletion<T>
+- (this, fn, dst));
+- while ((r = result) == null) {
+- if (UNSAFE.compareAndSwapObject(this, COMPLETIONS,
+- p.next = completions, p))
+- break;
+- }
+- }
+- if (r != null && (d == null || d.compareAndSet(0, 1))) {
+- T t = null; Throwable ex, dx = null;
+- if (r instanceof AltResult) {
+- if ((ex = ((AltResult)r).ex) != null) {
+- try {
+- t = fn.apply(ex);
+- } catch (Throwable rex) {
+- dx = rex;
+- }
+- }
+- }
+- else {
+- @SuppressWarnings("unchecked") T tr = (T) r;
+- t = tr;
+- }
+- dst.internalComplete(t, dx);
+- }
+- helpPostComplete();
+- return dst;
++ public CompletableFuture<T> exceptionally(
++ Function<Throwable, ? extends T> fn) {
++ return uniExceptionallyStage(fn);
+ }
+
+ /* ------------- Arbitrary-arity constructions -------------- */
+
+- /*
+- * The basic plan of attack is to recursively form binary
+- * completion trees of elements. This can be overkill for small
+- * sets, but scales nicely. The And/All vs Or/Any forms use the
+- * same idea, but details differ.
+- */
+-
+ /**
+ * Returns a new CompletableFuture that is completed when all of
+ * the given CompletableFutures complete. If any of the given
+@@ -2688,82 +2214,7 @@
+ * {@code null}
+ */
+ public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) {
+- int len = cfs.length; // Directly handle empty and singleton cases
+- if (len > 1)
+- return allTree(cfs, 0, len - 1);
+- else {
+- CompletableFuture<Void> dst = new CompletableFuture<Void>();
+- CompletableFuture<?> f;
+- if (len == 0)
+- dst.result = NIL;
+- else if ((f = cfs[0]) == null)
+- throw new NullPointerException();
+- else {
+- ThenPropagate d = null;
+- CompletionNode p = null;
+- Object r;
+- while ((r = f.result) == null) {
+- if (d == null)
+- d = new ThenPropagate(f, dst);
+- else if (p == null)
+- p = new CompletionNode(d);
+- else if (UNSAFE.compareAndSwapObject
+- (f, COMPLETIONS, p.next = f.completions, p))
+- break;
+- }
+- if (r != null && (d == null || d.compareAndSet(0, 1)))
+- dst.internalComplete(null, (r instanceof AltResult) ?
+- ((AltResult)r).ex : null);
+- f.helpPostComplete();
+- }
+- return dst;
+- }
+- }
+-
+- /**
+- * Recursively constructs an And'ed tree of CompletableFutures.
+- * Called only when array known to have at least two elements.
+- */
+- private static CompletableFuture<Void> allTree(CompletableFuture<?>[] cfs,
+- int lo, int hi) {
+- CompletableFuture<?> fst, snd;
+- int mid = (lo + hi) >>> 1;
+- if ((fst = (lo == mid ? cfs[lo] : allTree(cfs, lo, mid))) == null ||
+- (snd = (hi == mid+1 ? cfs[hi] : allTree(cfs, mid+1, hi))) == null)
+- throw new NullPointerException();
+- CompletableFuture<Void> dst = new CompletableFuture<Void>();
+- AndCompletion d = null;
+- CompletionNode p = null, q = null;
+- Object r = null, s = null;
+- while ((r = fst.result) == null || (s = snd.result) == null) {
+- if (d == null)
+- d = new AndCompletion(fst, snd, dst);
+- else if (p == null)
+- p = new CompletionNode(d);
+- else if (q == null) {
+- if (UNSAFE.compareAndSwapObject
+- (fst, COMPLETIONS, p.next = fst.completions, p))
+- q = new CompletionNode(d);
+- }
+- else if (UNSAFE.compareAndSwapObject
+- (snd, COMPLETIONS, q.next = snd.completions, q))
+- break;
+- }
+- if ((r != null || (r = fst.result) != null) &&
+- (s != null || (s = snd.result) != null) &&
+- (d == null || d.compareAndSet(0, 1))) {
+- Throwable ex;
+- if (r instanceof AltResult)
+- ex = ((AltResult)r).ex;
+- else
+- ex = null;
+- if (ex == null && (s instanceof AltResult))
+- ex = ((AltResult)s).ex;
+- dst.internalComplete(null, ex);
+- }
+- fst.helpPostComplete();
+- snd.helpPostComplete();
+- return dst;
++ return andTree(cfs, 0, cfs.length - 1);
+ }
+
+ /**
+@@ -2782,92 +2233,7 @@
+ * {@code null}
+ */
+ public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) {
+- int len = cfs.length; // Same idea as allOf
+- if (len > 1)
+- return anyTree(cfs, 0, len - 1);
+- else {
+- CompletableFuture<Object> dst = new CompletableFuture<Object>();
+- CompletableFuture<?> f;
+- if (len == 0)
+- ; // skip
+- else if ((f = cfs[0]) == null)
+- throw new NullPointerException();
+- else {
+- ThenCopy<Object> d = null;
+- CompletionNode p = null;
+- Object r;
+- while ((r = f.result) == null) {
+- if (d == null)
+- d = new ThenCopy<Object>(f, dst);
+- else if (p == null)
+- p = new CompletionNode(d);
+- else if (UNSAFE.compareAndSwapObject
+- (f, COMPLETIONS, p.next = f.completions, p))
+- break;
+- }
+- if (r != null && (d == null || d.compareAndSet(0, 1))) {
+- Throwable ex; Object t;
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- t = r;
+- }
+- dst.internalComplete(t, ex);
+- }
+- f.helpPostComplete();
+- }
+- return dst;
+- }
+- }
+-
+- /**
+- * Recursively constructs an Or'ed tree of CompletableFutures.
+- */
+- private static CompletableFuture<Object> anyTree(CompletableFuture<?>[] cfs,
+- int lo, int hi) {
+- CompletableFuture<?> fst, snd;
+- int mid = (lo + hi) >>> 1;
+- if ((fst = (lo == mid ? cfs[lo] : anyTree(cfs, lo, mid))) == null ||
+- (snd = (hi == mid+1 ? cfs[hi] : anyTree(cfs, mid+1, hi))) == null)
+- throw new NullPointerException();
+- CompletableFuture<Object> dst = new CompletableFuture<Object>();
+- OrCompletion d = null;
+- CompletionNode p = null, q = null;
+- Object r;
+- while ((r = fst.result) == null && (r = snd.result) == null) {
+- if (d == null)
+- d = new OrCompletion(fst, snd, dst);
+- else if (p == null)
+- p = new CompletionNode(d);
+- else if (q == null) {
+- if (UNSAFE.compareAndSwapObject
+- (fst, COMPLETIONS, p.next = fst.completions, p))
+- q = new CompletionNode(d);
+- }
+- else if (UNSAFE.compareAndSwapObject
+- (snd, COMPLETIONS, q.next = snd.completions, q))
+- break;
+- }
+- if ((r != null || (r = fst.result) != null ||
+- (r = snd.result) != null) &&
+- (d == null || d.compareAndSet(0, 1))) {
+- Throwable ex; Object t;
+- if (r instanceof AltResult) {
+- ex = ((AltResult)r).ex;
+- t = null;
+- }
+- else {
+- ex = null;
+- t = r;
+- }
+- dst.internalComplete(t, ex);
+- }
+- fst.helpPostComplete();
+- snd.helpPostComplete();
+- return dst;
++ return orTree(cfs, 0, cfs.length - 1);
+ }
+
+ /* ------------- Control and status methods -------------- */
+@@ -2887,8 +2253,7 @@
+ */
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ boolean cancelled = (result == null) &&
+- UNSAFE.compareAndSwapObject
+- (this, RESULT, null, new AltResult(new CancellationException()));
++ internalComplete(new AltResult(new CancellationException()));
+ postComplete();
+ return cancelled || isCancelled();
+ }
+@@ -2940,11 +2305,12 @@
+ * Forcibly causes subsequent invocations of method {@link #get()}
+ * and related methods to throw the given exception, whether or
+ * not already completed. This method is designed for use only in
+- * recovery actions, and even in such situations may result in
+- * ongoing dependent completions using established versus
++ * error recovery actions, and even in such situations may result
++ * in ongoing dependent completions using established versus
+ * overwritten outcomes.
+ *
+ * @param ex the exception
++ * @throws NullPointerException if the exception is null
+ */
+ public void obtrudeException(Throwable ex) {
+ if (ex == null) throw new NullPointerException();
+@@ -2962,7 +2328,7 @@
+ */
+ public int getNumberOfDependents() {
+ int count = 0;
+- for (CompletionNode p = completions; p != null; p = p.next)
++ for (Completion p = stack; p != null; p = p.next)
+ ++count;
+ return count;
+ }
+@@ -2993,20 +2359,19 @@
+ // Unsafe mechanics
+ private static final sun.misc.Unsafe UNSAFE;
+ private static final long RESULT;
+- private static final long WAITERS;
+- private static final long COMPLETIONS;
++ private static final long STACK;
++ private static final long NEXT;
+ static {
+ try {
+- UNSAFE = sun.misc.Unsafe.getUnsafe();
++ final sun.misc.Unsafe u;
++ UNSAFE = u = sun.misc.Unsafe.getUnsafe();
+ Class<?> k = CompletableFuture.class;
+- RESULT = UNSAFE.objectFieldOffset
+- (k.getDeclaredField("result"));
+- WAITERS = UNSAFE.objectFieldOffset
+- (k.getDeclaredField("waiters"));
+- COMPLETIONS = UNSAFE.objectFieldOffset
+- (k.getDeclaredField("completions"));
+- } catch (Exception e) {
+- throw new Error(e);
++ RESULT = u.objectFieldOffset(k.getDeclaredField("result"));
++ STACK = u.objectFieldOffset(k.getDeclaredField("stack"));
++ NEXT = u.objectFieldOffset
++ (Completion.class.getDeclaredField("next"));
++ } catch (Exception x) {
++ throw new Error(x);
+ }
+ }
+ }
+--- ./jdk/src/share/classes/java/util/concurrent/CompletionStage.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/concurrent/CompletionStage.java Wed Feb 04 12:14:43 2015 -0800
+@@ -407,7 +407,7 @@
+ /**
+ * Returns a new CompletionStage that, when this and the other
+ * given stage complete normally, executes the given action using
+- * the supplied executor
++ * the supplied executor.
+ *
+ * See the {@link CompletionStage} documentation for rules
+ * covering exceptional completion.
+@@ -569,7 +569,7 @@
+ /**
+ * Returns a new CompletionStage that, when either this or the
+ * other given stage complete normally, executes the given action
+- * using supplied executor.
++ * using the supplied executor.
+ *
+ * See the {@link CompletionStage} documentation for rules
+ * covering exceptional completion.
+@@ -649,10 +649,15 @@
+ (Function<Throwable, ? extends T> fn);
+
+ /**
+- * Returns a new CompletionStage with the same result or exception
+- * as this stage, and when this stage completes, executes the
+- * given action with the result (or {@code null} if none) and the
+- * exception (or {@code null} if none) of this stage.
++ * Returns a new CompletionStage with the same result or exception as
++ * this stage, that executes the given action when this stage completes.
++ *
++ * <p>When this stage is complete, the given action is invoked with the
++ * result (or {@code null} if none) and the exception (or {@code null}
++ * if none) of this stage as arguments. The returned stage is completed
++ * when the action returns. If the supplied action itself encounters an
++ * exception, then the returned stage exceptionally completes with this
++ * exception unless this stage also completed exceptionally.
+ *
+ * @param action the action to perform
+ * @return the new CompletionStage
+@@ -661,12 +666,16 @@
+ (BiConsumer<? super T, ? super Throwable> action);
+
+ /**
+- * Returns a new CompletionStage with the same result or exception
+- * as this stage, and when this stage completes, executes the
+- * given action executes the given action using this stage's
+- * default asynchronous execution facility, with the result (or
+- * {@code null} if none) and the exception (or {@code null} if
+- * none) of this stage as arguments.
++ * Returns a new CompletionStage with the same result or exception as
++ * this stage, that executes the given action using this stage's
++ * default asynchronous execution facility when this stage completes.
++ *
++ * <p>When this stage is complete, the given action is invoked with the
++ * result (or {@code null} if none) and the exception (or {@code null}
++ * if none) of this stage as arguments. The returned stage is completed
++ * when the action returns. If the supplied action itself encounters an
++ * exception, then the returned stage exceptionally completes with this
++ * exception unless this stage also completed exceptionally.
+ *
+ * @param action the action to perform
+ * @return the new CompletionStage
+@@ -675,11 +684,16 @@
+ (BiConsumer<? super T, ? super Throwable> action);
+
+ /**
+- * Returns a new CompletionStage with the same result or exception
+- * as this stage, and when this stage completes, executes using
+- * the supplied Executor, the given action with the result (or
+- * {@code null} if none) and the exception (or {@code null} if
+- * none) of this stage as arguments.
++ * Returns a new CompletionStage with the same result or exception as
++ * this stage, that executes the given action using the supplied
++ * Executor when this stage completes.
++ *
++ * <p>When this stage is complete, the given action is invoked with the
++ * result (or {@code null} if none) and the exception (or {@code null}
++ * if none) of this stage as arguments. The returned stage is completed
++ * when the action returns. If the supplied action itself encounters an
++ * exception, then the returned stage exceptionally completes with this
++ * exception unless this stage also completed exceptionally.
+ *
+ * @param action the action to perform
+ * @param executor the executor to use for asynchronous execution
+@@ -693,9 +707,11 @@
+ * Returns a new CompletionStage that, when this stage completes
+ * either normally or exceptionally, is executed with this stage's
+ * result and exception as arguments to the supplied function.
+- * The given function is invoked with the result (or {@code null}
+- * if none) and the exception (or {@code null} if none) of this
+- * stage when complete as arguments.
++ *
++ * <p>When this stage is complete, the given function is invoked
++ * with the result (or {@code null} if none) and the exception (or
++ * {@code null} if none) of this stage as arguments, and the
++ * function's result is used to complete the returned stage.
+ *
+ * @param fn the function to use to compute the value of the
+ * returned CompletionStage
+@@ -710,9 +726,11 @@
+ * either normally or exceptionally, is executed using this stage's
+ * default asynchronous execution facility, with this stage's
+ * result and exception as arguments to the supplied function.
+- * The given function is invoked with the result (or {@code null}
+- * if none) and the exception (or {@code null} if none) of this
+- * stage when complete as arguments.
++ *
++ * <p>When this stage is complete, the given function is invoked
++ * with the result (or {@code null} if none) and the exception (or
++ * {@code null} if none) of this stage as arguments, and the
++ * function's result is used to complete the returned stage.
+ *
+ * @param fn the function to use to compute the value of the
+ * returned CompletionStage
+@@ -726,10 +744,12 @@
+ * Returns a new CompletionStage that, when this stage completes
+ * either normally or exceptionally, is executed using the
+ * supplied executor, with this stage's result and exception as
+- * arguments to the supplied function. The given function is
+- * invoked with the result (or {@code null} if none) and the
+- * exception (or {@code null} if none) of this stage when complete
+- * as arguments.
++ * arguments to the supplied function.
++ *
++ * <p>When this stage is complete, the given function is invoked
++ * with the result (or {@code null} if none) and the exception (or
++ * {@code null} if none) of this stage as arguments, and the
++ * function's result is used to complete the returned stage.
+ *
+ * @param fn the function to use to compute the value of the
+ * returned CompletionStage
+--- ./jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java Wed Feb 04 12:14:43 2015 -0800
+@@ -49,6 +49,7 @@
+ import java.util.concurrent.RunnableFuture;
+ import java.util.concurrent.ThreadLocalRandom;
+ import java.util.concurrent.TimeUnit;
++import java.util.concurrent.atomic.AtomicLong;
+ import java.security.AccessControlContext;
+ import java.security.ProtectionDomain;
+ import java.security.Permissions;
+@@ -80,9 +81,9 @@
+ *
+ * <p>For applications that require separate or custom pools, a {@code
+ * ForkJoinPool} may be constructed with a given target parallelism
+- * level; by default, equal to the number of available processors. The
+- * pool attempts to maintain enough active (or available) threads by
+- * dynamically adding, suspending, or resuming internal worker
++ * level; by default, equal to the number of available processors.
++ * The pool attempts to maintain enough active (or available) threads
++ * by dynamically adding, suspending, or resuming internal worker
+ * threads, even if some tasks are stalled waiting to join others.
+ * However, no such adjustments are guaranteed in the face of blocked
+ * I/O or other unmanaged synchronization. The nested {@link
+@@ -178,7 +179,14 @@
+ * that may be stolen by other workers. Preference rules give
+ * first priority to processing tasks from their own queues (LIFO
+ * or FIFO, depending on mode), then to randomized FIFO steals of
+- * tasks in other queues.
++ * tasks in other queues. This framework began as vehicle for
++ * supporting tree-structured parallelism using work-stealing.
++ * Over time, its scalability advantages led to extensions and
++ * changes to better support more diverse usage contexts. Because
++ * most internal methods and nested classes are interrelated,
++ * their main rationale and descriptions are presented here;
++ * individual methods and nested classes contain only brief
++ * comments about details.
+ *
+ * WorkQueues
+ * ==========
+@@ -198,201 +206,318 @@
+ * (http://research.sun.com/scalable/pubs/index.html) and
+ * "Idempotent work stealing" by Michael, Saraswat, and Vechev,
+ * PPoPP 2009 (http://portal.acm.org/citation.cfm?id=1504186).
+- * See also "Correct and Efficient Work-Stealing for Weak Memory
+- * Models" by Le, Pop, Cohen, and Nardelli, PPoPP 2013
+- * (http://www.di.ens.fr/~zappa/readings/ppopp13.pdf) for an
+- * analysis of memory ordering (atomic, volatile etc) issues. The
+- * main differences ultimately stem from GC requirements that we
+- * null out taken slots as soon as we can, to maintain as small a
+- * footprint as possible even in programs generating huge numbers
+- * of tasks. To accomplish this, we shift the CAS arbitrating pop
+- * vs poll (steal) from being on the indices ("base" and "top") to
+- * the slots themselves. So, both a successful pop and poll
+- * mainly entail a CAS of a slot from non-null to null. Because
+- * we rely on CASes of references, we do not need tag bits on base
+- * or top. They are simple ints as used in any circular
++ * The main differences ultimately stem from GC requirements that
++ * we null out taken slots as soon as we can, to maintain as small
++ * a footprint as possible even in programs generating huge
++ * numbers of tasks. To accomplish this, we shift the CAS
++ * arbitrating pop vs poll (steal) from being on the indices
++ * ("base" and "top") to the slots themselves.
++ *
++ * Adding tasks then takes the form of a classic array push(task):
++ * q.array[q.top] = task; ++q.top;
++ *
++ * (The actual code needs to null-check and size-check the array,
++ * properly fence the accesses, and possibly signal waiting
++ * workers to start scanning -- see below.) Both a successful pop
++ * and poll mainly entail a CAS of a slot from non-null to null.
++ *
++ * The pop operation (always performed by owner) is:
++ * if ((base != top) and
++ * (the task at top slot is not null) and
++ * (CAS slot to null))
++ * decrement top and return task;
++ *
++ * And the poll operation (usually by a stealer) is
++ * if ((base != top) and
++ * (the task at base slot is not null) and
++ * (base has not changed) and
++ * (CAS slot to null))
++ * increment base and return task;
++ *
++ * Because we rely on CASes of references, we do not need tag bits
++ * on base or top. They are simple ints as used in any circular
+ * array-based queue (see for example ArrayDeque). Updates to the
+- * indices must still be ordered in a way that guarantees that top
+- * == base means the queue is empty, but otherwise may err on the
+- * side of possibly making the queue appear nonempty when a push,
+- * pop, or poll have not fully committed. Note that this means
+- * that the poll operation, considered individually, is not
+- * wait-free. One thief cannot successfully continue until another
+- * in-progress one (or, if previously empty, a push) completes.
+- * However, in the aggregate, we ensure at least probabilistic
++ * indices guarantee that top == base means the queue is empty,
++ * but otherwise may err on the side of possibly making the queue
++ * appear nonempty when a push, pop, or poll have not fully
++ * committed. (Method isEmpty() checks the case of a partially
++ * completed removal of the last element.) Because of this, the
++ * poll operation, considered individually, is not wait-free. One
++ * thief cannot successfully continue until another in-progress
++ * one (or, if previously empty, a push) completes. However, in
++ * the aggregate, we ensure at least probabilistic
+ * non-blockingness. If an attempted steal fails, a thief always
+ * chooses a different random victim target to try next. So, in
+ * order for one thief to progress, it suffices for any
+ * in-progress poll or new push on any empty queue to
+ * complete. (This is why we normally use method pollAt and its
+ * variants that try once at the apparent base index, else
+- * consider alternative actions, rather than method poll.)
++ * consider alternative actions, rather than method poll, which
++ * retries.)
+ *
+- * This approach also enables support of a user mode in which local
+- * task processing is in FIFO, not LIFO order, simply by using
+- * poll rather than pop. This can be useful in message-passing
+- * frameworks in which tasks are never joined. However neither
+- * mode considers affinities, loads, cache localities, etc, so
+- * rarely provide the best possible performance on a given
+- * machine, but portably provide good throughput by averaging over
+- * these factors. (Further, even if we did try to use such
+- * information, we do not usually have a basis for exploiting it.
+- * For example, some sets of tasks profit from cache affinities,
+- * but others are harmed by cache pollution effects.)
++ * This approach also enables support of a user mode in which
++ * local task processing is in FIFO, not LIFO order, simply by
++ * using poll rather than pop. This can be useful in
++ * message-passing frameworks in which tasks are never joined.
++ * However neither mode considers affinities, loads, cache
++ * localities, etc, so rarely provide the best possible
++ * performance on a given machine, but portably provide good
++ * throughput by averaging over these factors. Further, even if
++ * we did try to use such information, we do not usually have a
++ * basis for exploiting it. For example, some sets of tasks
++ * profit from cache affinities, but others are harmed by cache
++ * pollution effects. Additionally, even though it requires
++ * scanning, long-term throughput is often best using random
++ * selection rather than directed selection policies, so cheap
++ * randomization of sufficient quality is used whenever
++ * applicable. Various Marsaglia XorShifts (some with different
++ * shift constants) are inlined at use points.
+ *
+ * WorkQueues are also used in a similar way for tasks submitted
+ * to the pool. We cannot mix these tasks in the same queues used
+- * for work-stealing (this would contaminate lifo/fifo
+- * processing). Instead, we randomly associate submission queues
++ * by workers. Instead, we randomly associate submission queues
+ * with submitting threads, using a form of hashing. The
+ * ThreadLocalRandom probe value serves as a hash code for
+ * choosing existing queues, and may be randomly repositioned upon
+ * contention with other submitters. In essence, submitters act
+ * like workers except that they are restricted to executing local
+ * tasks that they submitted (or in the case of CountedCompleters,
+- * others with the same root task). However, because most
+- * shared/external queue operations are more expensive than
+- * internal, and because, at steady state, external submitters
+- * will compete for CPU with workers, ForkJoinTask.join and
+- * related methods disable them from repeatedly helping to process
+- * tasks if all workers are active. Insertion of tasks in shared
++ * others with the same root task). Insertion of tasks in shared
+ * mode requires a lock (mainly to protect in the case of
+- * resizing) but we use only a simple spinlock (using bits in
+- * field qlock), because submitters encountering a busy queue move
+- * on to try or create other queues -- they block only when
+- * creating and registering new queues.
++ * resizing) but we use only a simple spinlock (using field
++ * qlock), because submitters encountering a busy queue move on to
++ * try or create other queues -- they block only when creating and
++ * registering new queues. Additionally, "qlock" saturates to an
++ * unlockable value (-1) at shutdown. Unlocking still can be and
++ * is performed by cheaper ordered writes of "qlock" in successful
++ * cases, but uses CAS in unsuccessful cases.
+ *
+ * Management
+ * ==========
+ *
+ * The main throughput advantages of work-stealing stem from
+ * decentralized control -- workers mostly take tasks from
+- * themselves or each other. We cannot negate this in the
+- * implementation of other management responsibilities. The main
+- * tactic for avoiding bottlenecks is packing nearly all
+- * essentially atomic control state into two volatile variables
+- * that are by far most often read (not written) as status and
+- * consistency checks.
++ * themselves or each other, at rates that can exceed a billion
++ * per second. The pool itself creates, activates (enables
++ * scanning for and running tasks), deactivates, blocks, and
++ * terminates threads, all with minimal central information.
++ * There are only a few properties that we can globally track or
++ * maintain, so we pack them into a small number of variables,
++ * often maintaining atomicity without blocking or locking.
++ * Nearly all essentially atomic control state is held in two
++ * volatile variables that are by far most often read (not
++ * written) as status and consistency checks. (Also, field
++ * "config" holds unchanging configuration state.)
+ *
+- * Field "ctl" contains 64 bits holding all the information needed
+- * to atomically decide to add, inactivate, enqueue (on an event
++ * Field "ctl" contains 64 bits holding information needed to
++ * atomically decide to add, inactivate, enqueue (on an event
+ * queue), dequeue, and/or re-activate workers. To enable this
+ * packing, we restrict maximum parallelism to (1<<15)-1 (which is
+ * far in excess of normal operating range) to allow ids, counts,
+ * and their negations (used for thresholding) to fit into 16bit
+- * fields.
++ * subfields.
+ *
+- * Field "plock" is a form of sequence lock with a saturating
+- * shutdown bit (similarly for per-queue "qlocks"), mainly
+- * protecting updates to the workQueues array, as well as to
+- * enable shutdown. When used as a lock, it is normally only very
+- * briefly held, so is nearly always available after at most a
+- * brief spin, but we use a monitor-based backup strategy to
+- * block when needed.
++ * Field "runState" holds lockable state bits (STARTED, STOP, etc)
++ * also protecting updates to the workQueues array. When used as
++ * a lock, it is normally held only for a few instructions (the
++ * only exceptions are one-time array initialization and uncommon
++ * resizing), so is nearly always available after at most a brief
++ * spin. But to be extra-cautious, after spinning, method
++ * awaitRunStateLock (called only if an initial CAS fails), uses a
++ * wait/notify mechanics on a builtin monitor to block when
++ * (rarely) needed. This would be a terrible idea for a highly
++ * contended lock, but most pools run without the lock ever
++ * contending after the spin limit, so this works fine as a more
++ * conservative alternative. Because we don't otherwise have an
++ * internal Object to use as a monitor, the "stealCounter" (an
++ * AtomicLong) is used when available (it too must be lazily
++ * initialized; see externalSubmit).
++ *
++ * Usages of "runState" vs "ctl" interact in only one case:
++ * deciding to add a worker thread (see tryAddWorker), in which
++ * case the ctl CAS is performed while the lock is held.
+ *
+ * Recording WorkQueues. WorkQueues are recorded in the
+- * "workQueues" array that is created upon first use and expanded
+- * if necessary. Updates to the array while recording new workers
+- * and unrecording terminated ones are protected from each other
+- * by a lock but the array is otherwise concurrently readable, and
+- * accessed directly. To simplify index-based operations, the
+- * array size is always a power of two, and all readers must
+- * tolerate null slots. Worker queues are at odd indices. Shared
+- * (submission) queues are at even indices, up to a maximum of 64
+- * slots, to limit growth even if array needs to expand to add
+- * more workers. Grouping them together in this way simplifies and
+- * speeds up task scanning.
++ * "workQueues" array. The array is created upon first use (see
++ * externalSubmit) and expanded if necessary. Updates to the
++ * array while recording new workers and unrecording terminated
++ * ones are protected from each other by the runState lock, but
++ * the array is otherwise concurrently readable, and accessed
++ * directly. We also ensure that reads of the array reference
++ * itself never become too stale. To simplify index-based
++ * operations, the array size is always a power of two, and all
++ * readers must tolerate null slots. Worker queues are at odd
++ * indices. Shared (submission) queues are at even indices, up to
++ * a maximum of 64 slots, to limit growth even if array needs to
++ * expand to add more workers. Grouping them together in this way
++ * simplifies and speeds up task scanning.
+ *
+ * All worker thread creation is on-demand, triggered by task
+ * submissions, replacement of terminated workers, and/or
+ * compensation for blocked workers. However, all other support
+ * code is set up to work with other policies. To ensure that we
+- * do not hold on to worker references that would prevent GC, ALL
++ * do not hold on to worker references that would prevent GC, All
+ * accesses to workQueues are via indices into the workQueues
+ * array (which is one source of some of the messy code
+ * constructions here). In essence, the workQueues array serves as
+- * a weak reference mechanism. Thus for example the wait queue
+- * field of ctl stores indices, not references. Access to the
+- * workQueues in associated methods (for example signalWork) must
+- * both index-check and null-check the IDs. All such accesses
+- * ignore bad IDs by returning out early from what they are doing,
+- * since this can only be associated with termination, in which
+- * case it is OK to give up. All uses of the workQueues array
+- * also check that it is non-null (even if previously
+- * non-null). This allows nulling during termination, which is
+- * currently not necessary, but remains an option for
+- * resource-revocation-based shutdown schemes. It also helps
+- * reduce JIT issuance of uncommon-trap code, which tends to
+- * unnecessarily complicate control flow in some methods.
++ * a weak reference mechanism. Thus for example the stack top
++ * subfield of ctl stores indices, not references.
+ *
+- * Event Queuing. Unlike HPC work-stealing frameworks, we cannot
+- * let workers spin indefinitely scanning for tasks when none can
+- * be found immediately, and we cannot start/resume workers unless
+- * there appear to be tasks available. On the other hand, we must
+- * quickly prod them into action when new tasks are submitted or
+- * generated. In many usages, ramp-up time to activate workers is
+- * the main limiting factor in overall performance (this is
+- * compounded at program start-up by JIT compilation and
+- * allocation). So we try to streamline this as much as possible.
+- * We park/unpark workers after placing in an event wait queue
+- * when they cannot find work. This "queue" is actually a simple
+- * Treiber stack, headed by the "id" field of ctl, plus a 15bit
+- * counter value (that reflects the number of times a worker has
+- * been inactivated) to avoid ABA effects (we need only as many
+- * version numbers as worker threads). Successors are held in
+- * field WorkQueue.nextWait. Queuing deals with several intrinsic
+- * races, mainly that a task-producing thread can miss seeing (and
+- * signalling) another thread that gave up looking for work but
+- * has not yet entered the wait queue. We solve this by requiring
+- * a full sweep of all workers (via repeated calls to method
+- * scan()) both before and after a newly waiting worker is added
+- * to the wait queue. Because enqueued workers may actually be
+- * rescanning rather than waiting, we set and clear the "parker"
++ * Queuing Idle Workers. Unlike HPC work-stealing frameworks, we
++ * cannot let workers spin indefinitely scanning for tasks when
++ * none can be found immediately, and we cannot start/resume
++ * workers unless there appear to be tasks available. On the
++ * other hand, we must quickly prod them into action when new
++ * tasks are submitted or generated. In many usages, ramp-up time
++ * to activate workers is the main limiting factor in overall
++ * performance, which is compounded at program start-up by JIT
++ * compilation and allocation. So we streamline this as much as
++ * possible.
++ *
++ * The "ctl" field atomically maintains active and total worker
++ * counts as well as a queue to place waiting threads so they can
++ * be located for signalling. Active counts also play the role of
++ * quiescence indicators, so are decremented when workers believe
++ * that there are no more tasks to execute. The "queue" is
++ * actually a form of Treiber stack. A stack is ideal for
++ * activating threads in most-recently used order. This improves
++ * performance and locality, outweighing the disadvantages of
++ * being prone to contention and inability to release a worker
++ * unless it is topmost on stack. We park/unpark workers after
++ * pushing on the idle worker stack (represented by the lower
++ * 32bit subfield of ctl) when they cannot find work. The top
++ * stack state holds the value of the "scanState" field of the
++ * worker: its index and status, plus a version counter that, in
++ * addition to the count subfields (also serving as version
++ * stamps) provide protection against Treiber stack ABA effects.
++ *
++ * Field scanState is used by both workers and the pool to manage
++ * and track whether a worker is INACTIVE (possibly blocked
++ * waiting for a signal), or SCANNING for tasks (when neither hold
++ * it is busy running tasks). When a worker is inactivated, its
++ * scanState field is set, and is prevented from executing tasks,
++ * even though it must scan once for them to avoid queuing
++ * races. Note that scanState updates lag queue CAS releases so
++ * usage requires care. When queued, the lower 16 bits of
++ * scanState must hold its pool index. So we place the index there
++ * upon initialization (see registerWorker) and otherwise keep it
++ * there or restore it when necessary.
++ *
++ * Memory ordering. See "Correct and Efficient Work-Stealing for
++ * Weak Memory Models" by Le, Pop, Cohen, and Nardelli, PPoPP 2013
++ * (http://www.di.ens.fr/~zappa/readings/ppopp13.pdf) for an
++ * analysis of memory ordering requirements in work-stealing
++ * algorithms similar to the one used here. We usually need
++ * stronger than minimal ordering because we must sometimes signal
++ * workers, requiring Dekker-like full-fences to avoid lost
++ * signals. Arranging for enough ordering without expensive
++ * over-fencing requires tradeoffs among the supported means of
++ * expressing access constraints. The most central operations,
++ * taking from queues and updating ctl state, require full-fence
++ * CAS. Array slots are read using the emulation of volatiles
++ * provided by Unsafe. Access from other threads to WorkQueue
++ * base, top, and array requires a volatile load of the first of
++ * any of these read. We use the convention of declaring the
++ * "base" index volatile, and always read it before other fields.
++ * The owner thread must ensure ordered updates, so writes use
++ * ordered intrinsics unless they can piggyback on those for other
++ * writes. Similar conventions and rationales hold for other
++ * WorkQueue fields (such as "currentSteal") that are only written
++ * by owners but observed by others.
++ *
++ * Creating workers. To create a worker, we pre-increment total
++ * count (serving as a reservation), and attempt to construct a
++ * ForkJoinWorkerThread via its factory. Upon construction, the
++ * new thread invokes registerWorker, where it constructs a
++ * WorkQueue and is assigned an index in the workQueues array
++ * (expanding the array if necessary). The thread is then
++ * started. Upon any exception across these steps, or null return
++ * from factory, deregisterWorker adjusts counts and records
++ * accordingly. If a null return, the pool continues running with
++ * fewer than the target number workers. If exceptional, the
++ * exception is propagated, generally to some external caller.
++ * Worker index assignment avoids the bias in scanning that would
++ * occur if entries were sequentially packed starting at the front
++ * of the workQueues array. We treat the array as a simple
++ * power-of-two hash table, expanding as needed. The seedIndex
++ * increment ensures no collisions until a resize is needed or a
++ * worker is deregistered and replaced, and thereafter keeps
++ * probability of collision low. We cannot use
++ * ThreadLocalRandom.getProbe() for similar purposes here because
++ * the thread has not started yet, but do so for creating
++ * submission queues for existing external threads.
++ *
++ * Deactivation and waiting. Queuing encounters several intrinsic
++ * races; most notably that a task-producing thread can miss
++ * seeing (and signalling) another thread that gave up looking for
++ * work but has not yet entered the wait queue. When a worker
++ * cannot find a task to steal, it deactivates and enqueues. Very
++ * often, the lack of tasks is transient due to GC or OS
++ * scheduling. To reduce false-alarm deactivation, scanners
++ * compute checksums of queue states during sweeps. (The
++ * stability checks used here and elsewhere are probabilistic
++ * variants of snapshot techniques -- see Herlihy & Shavit.)
++ * Workers give up and try to deactivate only after the sum is
++ * stable across scans. Further, to avoid missed signals, they
++ * repeat this scanning process after successful enqueuing until
++ * again stable. In this state, the worker cannot take/run a task
++ * it sees until it is released from the queue, so the worker
++ * itself eventually tries to release itself or any successor (see
++ * tryRelease). Otherwise, upon an empty scan, a deactivated
++ * worker uses an adaptive local spin construction (see awaitWork)
++ * before blocking (via park). Note the unusual conventions about
++ * Thread.interrupts surrounding parking and other blocking:
++ * Because interrupts are used solely to alert threads to check
++ * termination, which is checked anyway upon blocking, we clear
++ * status (using Thread.interrupted) before any call to park, so
++ * that park does not immediately return due to status being set
++ * via some other unrelated call to interrupt in user code.
++ *
++ * Signalling and activation. Workers are created or activated
++ * only when there appears to be at least one task they might be
++ * able to find and execute. Upon push (either by a worker or an
++ * external submission) to a previously (possibly) empty queue,
++ * workers are signalled if idle, or created if fewer exist than
++ * the given parallelism level. These primary signals are
++ * buttressed by others whenever other threads remove a task from
++ * a queue and notice that there are other tasks there as well.
++ * On most platforms, signalling (unpark) overhead time is
++ * noticeably long, and the time between signalling a thread and
++ * it actually making progress can be very noticeably long, so it
++ * is worth offloading these delays from critical paths as much as
++ * possible. Also, because inactive workers are often rescanning
++ * or spinning rather than blocking, we set and clear the "parker"
+ * field of WorkQueues to reduce unnecessary calls to unpark.
+ * (This requires a secondary recheck to avoid missed signals.)
+- * Note the unusual conventions about Thread.interrupts
+- * surrounding parking and other blocking: Because interrupts are
+- * used solely to alert threads to check termination, which is
+- * checked anyway upon blocking, we clear status (using
+- * Thread.interrupted) before any call to park, so that park does
+- * not immediately return due to status being set via some other
+- * unrelated call to interrupt in user code.
+- *
+- * Signalling. We create or wake up workers only when there
+- * appears to be at least one task they might be able to find and
+- * execute. When a submission is added or another worker adds a
+- * task to a queue that has fewer than two tasks, they signal
+- * waiting workers (or trigger creation of new ones if fewer than
+- * the given parallelism level -- signalWork). These primary
+- * signals are buttressed by others whenever other threads remove
+- * a task from a queue and notice that there are other tasks there
+- * as well. So in general, pools will be over-signalled. On most
+- * platforms, signalling (unpark) overhead time is noticeably
+- * long, and the time between signalling a thread and it actually
+- * making progress can be very noticeably long, so it is worth
+- * offloading these delays from critical paths as much as
+- * possible. Additionally, workers spin-down gradually, by staying
+- * alive so long as they see the ctl state changing. Similar
+- * stability-sensing techniques are also used before blocking in
+- * awaitJoin and helpComplete.
+ *
+ * Trimming workers. To release resources after periods of lack of
+ * use, a worker starting to wait when the pool is quiescent will
+- * time out and terminate if the pool has remained quiescent for a
+- * given period -- a short period if there are more threads than
+- * parallelism, longer as the number of threads decreases. This
+- * will slowly propagate, eventually terminating all workers after
+- * periods of non-use.
++ * time out and terminate (see awaitWork) if the pool has remained
++ * quiescent for period IDLE_TIMEOUT, increasing the period as the
++ * number of threads decreases, eventually removing all workers.
++ * Also, when more than two spare threads exist, excess threads
++ * are immediately terminated at the next quiescent point.
++ * (Padding by two avoids hysteresis.)
+ *
+- * Shutdown and Termination. A call to shutdownNow atomically sets
+- * a plock bit and then (non-atomically) sets each worker's
+- * qlock status, cancels all unprocessed tasks, and wakes up
+- * all waiting workers. Detecting whether termination should
+- * commence after a non-abrupt shutdown() call requires more work
+- * and bookkeeping. We need consensus about quiescence (i.e., that
+- * there is no more work). The active count provides a primary
+- * indication but non-abrupt shutdown still requires a rechecking
+- * scan for any workers that are inactive but not queued.
++ * Shutdown and Termination. A call to shutdownNow invokes
++ * tryTerminate to atomically set a runState bit. The calling
++ * thread, as well as every other worker thereafter terminating,
++ * helps terminate others by setting their (qlock) status,
++ * cancelling their unprocessed tasks, and waking them up, doing
++ * so repeatedly until stable (but with a loop bounded by the
++ * number of workers). Calls to non-abrupt shutdown() preface
++ * this by checking whether termination should commence. This
++ * relies primarily on the active count bits of "ctl" maintaining
++ * consensus -- tryTerminate is called from awaitWork whenever
++ * quiescent. However, external submitters do not take part in
++ * this consensus. So, tryTerminate sweeps through queues (until
++ * stable) to ensure lack of in-flight submissions and workers
++ * about to process them before triggering the "STOP" phase of
++ * termination. (Note: there is an intrinsic conflict if
++ * helpQuiescePool is called when shutdown is enabled. Both wait
++ * for quiescence, but tryTerminate is biased to not trigger until
++ * helpQuiescePool completes.)
++ *
+ *
+ * Joining Tasks
+ * =============
+@@ -403,9 +528,9 @@
+ * just let them block (as in Thread.join). We also cannot just
+ * reassign the joiner's run-time stack with another and replace
+ * it later, which would be a form of "continuation", that even if
+- * possible is not necessarily a good idea since we sometimes need
+- * both an unblocked task and its continuation to progress.
+- * Instead we combine two tactics:
++ * possible is not necessarily a good idea since we may need both
++ * an unblocked task and its continuation to progress. Instead we
++ * combine two tactics:
+ *
+ * Helping: Arranging for the joiner to execute some task that it
+ * would be running if the steal had not occurred.
+@@ -425,16 +550,16 @@
+ * The ManagedBlocker extension API can't use helping so relies
+ * only on compensation in method awaitBlocker.
+ *
+- * The algorithm in tryHelpStealer entails a form of "linear"
+- * helping: Each worker records (in field currentSteal) the most
+- * recent task it stole from some other worker. Plus, it records
+- * (in field currentJoin) the task it is currently actively
+- * joining. Method tryHelpStealer uses these markers to try to
+- * find a worker to help (i.e., steal back a task from and execute
+- * it) that could hasten completion of the actively joined task.
+- * In essence, the joiner executes a task that would be on its own
+- * local deque had the to-be-joined task not been stolen. This may
+- * be seen as a conservative variant of the approach in Wagner &
++ * The algorithm in helpStealer entails a form of "linear
++ * helping". Each worker records (in field currentSteal) the most
++ * recent task it stole from some other worker (or a submission).
++ * It also records (in field currentJoin) the task it is currently
++ * actively joining. Method helpStealer uses these markers to try
++ * to find a worker to help (i.e., steal back a task from and
++ * execute it) that could hasten completion of the actively joined
++ * task. Thus, the joiner executes a task that would be on its
++ * own local deque had the to-be-joined task not been stolen. This
++ * is a conservative variant of the approach described in Wagner &
+ * Calder "Leapfrogging: a portable technique for implementing
+ * efficient futures" SIGPLAN Notices, 1993
+ * (http://portal.acm.org/citation.cfm?id=155354). It differs in
+@@ -452,37 +577,40 @@
+ * which means that we miss links in the chain during long-lived
+ * tasks, GC stalls etc (which is OK since blocking in such cases
+ * is usually a good idea). (4) We bound the number of attempts
+- * to find work (see MAX_HELP) and fall back to suspending the
++ * to find work using checksums and fall back to suspending the
+ * worker and if necessary replacing it with another.
+ *
+- * Helping actions for CountedCompleters are much simpler: Method
+- * helpComplete can take and execute any task with the same root
+- * as the task being waited on. However, this still entails some
+- * traversal of completer chains, so is less efficient than using
+- * CountedCompleters without explicit joins.
++ * Helping actions for CountedCompleters do not require tracking
++ * currentJoins: Method helpComplete takes and executes any task
++ * with the same root as the task being waited on (preferring
++ * local pops to non-local polls). However, this still entails
++ * some traversal of completer chains, so is less efficient than
++ * using CountedCompleters without explicit joins.
+ *
+- * It is impossible to keep exactly the target parallelism number
+- * of threads running at any given time. Determining the
+- * existence of conservatively safe helping targets, the
+- * availability of already-created spares, and the apparent need
+- * to create new spares are all racy, so we rely on multiple
+- * retries of each. Compensation in the apparent absence of
+- * helping opportunities is challenging to control on JVMs, where
+- * GC and other activities can stall progress of tasks that in
+- * turn stall out many other dependent tasks, without us being
+- * able to determine whether they will ever require compensation.
+- * Even though work-stealing otherwise encounters little
+- * degradation in the presence of more threads than cores,
+- * aggressively adding new threads in such cases entails risk of
+- * unwanted positive feedback control loops in which more threads
+- * cause more dependent stalls (as well as delayed progress of
+- * unblocked threads to the point that we know they are available)
+- * leading to more situations requiring more threads, and so
+- * on. This aspect of control can be seen as an (analytically
+- * intractable) game with an opponent that may choose the worst
+- * (for us) active thread to stall at any time. We take several
+- * precautions to bound losses (and thus bound gains), mainly in
+- * methods tryCompensate and awaitJoin.
++ * Compensation does not aim to keep exactly the target
++ * parallelism number of unblocked threads running at any given
++ * time. Some previous versions of this class employed immediate
++ * compensations for any blocked join. However, in practice, the
++ * vast majority of blockages are transient byproducts of GC and
++ * other JVM or OS activities that are made worse by replacement.
++ * Currently, compensation is attempted only after validating that
++ * all purportedly active threads are processing tasks by checking
++ * field WorkQueue.scanState, which eliminates most false
++ * positives. Also, compensation is bypassed (tolerating fewer
++ * threads) in the most common case in which it is rarely
++ * beneficial: when a worker with an empty queue (thus no
++ * continuation tasks) blocks on a join and there still remain
++ * enough threads to ensure liveness.
++ *
++ * The compensation mechanism may be bounded. Bounds for the
++ * commonPool (see commonMaxSpares) better enable JVMs to cope
++ * with programming errors and abuse before running out of
++ * resources to do so. In other cases, users may supply factories
++ * that limit thread construction. The effects of bounding in this
++ * pool (like all others) is imprecise. Total worker counts are
++ * decremented when threads deregister, not when they exit and
++ * resources are reclaimed by the JVM and OS. So the number of
++ * simultaneously live threads may transiently exceed bounds.
+ *
+ * Common Pool
+ * ===========
+@@ -492,34 +620,52 @@
+ * never be used, we minimize initial construction overhead and
+ * footprint to the setup of about a dozen fields, with no nested
+ * allocation. Most bootstrapping occurs within method
+- * fullExternalPush during the first submission to the pool.
++ * externalSubmit during the first submission to the pool.
+ *
+ * When external threads submit to the common pool, they can
+- * perform subtask processing (see externalHelpJoin and related
+- * methods). This caller-helps policy makes it sensible to set
+- * common pool parallelism level to one (or more) less than the
+- * total number of available cores, or even zero for pure
+- * caller-runs. We do not need to record whether external
+- * submissions are to the common pool -- if not, externalHelpJoin
+- * returns quickly (at the most helping to signal some common pool
+- * workers). These submitters would otherwise be blocked waiting
+- * for completion, so the extra effort (with liberally sprinkled
+- * task status checks) in inapplicable cases amounts to an odd
+- * form of limited spin-wait before blocking in ForkJoinTask.join.
++ * perform subtask processing (see externalHelpComplete and
++ * related methods) upon joins. This caller-helps policy makes it
++ * sensible to set common pool parallelism level to one (or more)
++ * less than the total number of available cores, or even zero for
++ * pure caller-runs. We do not need to record whether external
++ * submissions are to the common pool -- if not, external help
++ * methods return quickly. These submitters would otherwise be
++ * blocked waiting for completion, so the extra effort (with
++ * liberally sprinkled task status checks) in inapplicable cases
++ * amounts to an odd form of limited spin-wait before blocking in
++ * ForkJoinTask.join.
+ *
+ * As a more appropriate default in managed environments, unless
+ * overridden by system properties, we use workers of subclass
+ * InnocuousForkJoinWorkerThread when there is a SecurityManager
+ * present. These workers have no permissions set, do not belong
+ * to any user-defined ThreadGroup, and erase all ThreadLocals
+- * after executing any top-level task (see WorkQueue.runTask). The
+- * associated mechanics (mainly in ForkJoinWorkerThread) may be
+- * JVM-dependent and must access particular Thread class fields to
+- * achieve this effect.
++ * after executing any top-level task (see WorkQueue.runTask).
++ * The associated mechanics (mainly in ForkJoinWorkerThread) may
++ * be JVM-dependent and must access particular Thread class fields
++ * to achieve this effect.
+ *
+ * Style notes
+ * ===========
+ *
++ * Memory ordering relies mainly on Unsafe intrinsics that carry
++ * the further responsibility of explicitly performing null- and
++ * bounds- checks otherwise carried out implicitly by JVMs. This
++ * can be awkward and ugly, but also reflects the need to control
++ * outcomes across the unusual cases that arise in very racy code
++ * with very few invariants. So these explicit checks would exist
++ * in some form anyway. All fields are read into locals before
++ * use, and null-checked if they are references. This is usually
++ * done in a "C"-like style of listing declarations at the heads
++ * of methods or blocks, and using inline assignments on first
++ * encounter. Array bounds-checks are usually performed by
++ * masking with array.length-1, which relies on the invariant that
++ * these arrays are created with positive lengths, which is itself
++ * paranoically checked. Nearly all explicit checks lead to
++ * bypass/return, not exception throws, because they may
++ * legitimately arise due to cancellation/revocation during
++ * shutdown.
++ *
+ * There is a lot of representation-level coupling among classes
+ * ForkJoinPool, ForkJoinWorkerThread, and ForkJoinTask. The
+ * fields of WorkQueue maintain data structures managed by
+@@ -527,22 +673,13 @@
+ * trying to reduce this, since any associated future changes in
+ * representations will need to be accompanied by algorithmic
+ * changes anyway. Several methods intrinsically sprawl because
+- * they must accumulate sets of consistent reads of volatiles held
+- * in local variables. Methods signalWork() and scan() are the
+- * main bottlenecks, so are especially heavily
+- * micro-optimized/mangled. There are lots of inline assignments
+- * (of form "while ((local = field) != 0)") which are usually the
+- * simplest way to ensure the required read orderings (which are
+- * sometimes critical). This leads to a "C"-like style of listing
+- * declarations of these locals at the heads of methods or blocks.
+- * There are several occurrences of the unusual "do {} while
+- * (!cas...)" which is the simplest way to force an update of a
+- * CAS'ed variable. There are also other coding oddities (including
+- * several unnecessary-looking hoisted null checks) that help
+- * some methods perform reasonably even when interpreted (not
+- * compiled).
++ * they must accumulate sets of consistent reads of fields held in
++ * local variables. There are also other coding oddities
++ * (including several unnecessary-looking hoisted null checks)
++ * that help some methods perform reasonably even when interpreted
++ * (not compiled).
+ *
+- * The order of declarations in this file is:
++ * The order of declarations in this file is (with a few exceptions):
+ * (1) Static utility functions
+ * (2) Nested (static) classes
+ * (3) Static fields
+@@ -609,56 +746,37 @@
+ public final boolean exec() { return true; }
+ }
+
++ // Constants shared across ForkJoinPool and WorkQueue
++
++ // Bounds
++ static final int SMASK = 0xffff; // short bits == max index
++ static final int MAX_CAP = 0x7fff; // max #workers - 1
++ static final int EVENMASK = 0xfffe; // even short bits
++ static final int SQMASK = 0x007e; // max 64 (even) slots
++
++ // Masks and units for WorkQueue.scanState and ctl sp subfield
++ static final int SCANNING = 1; // false when running tasks
++ static final int INACTIVE = 1 << 31; // must be negative
++ static final int SS_SEQ = 1 << 16; // version count
++
++ // Mode bits for ForkJoinPool.config and WorkQueue.config
++ static final int MODE_MASK = 0xffff << 16; // top half of int
++ static final int LIFO_QUEUE = 0;
++ static final int FIFO_QUEUE = 1 << 16;
++ static final int SHARED_QUEUE = 1 << 31; // must be negative
++
+ /**
+ * Queues supporting work-stealing as well as external task
+- * submission. See above for main rationale and algorithms.
+- * Implementation relies heavily on "Unsafe" intrinsics
+- * and selective use of "volatile":
+- *
+- * Field "base" is the index (mod array.length) of the least valid
+- * queue slot, which is always the next position to steal (poll)
+- * from if nonempty. Reads and writes require volatile orderings
+- * but not CAS, because updates are only performed after slot
+- * CASes.
+- *
+- * Field "top" is the index (mod array.length) of the next queue
+- * slot to push to or pop from. It is written only by owner thread
+- * for push, or under lock for external/shared push, and accessed
+- * by other threads only after reading (volatile) base. Both top
+- * and base are allowed to wrap around on overflow, but (top -
+- * base) (or more commonly -(base - top) to force volatile read of
+- * base before top) still estimates size. The lock ("qlock") is
+- * forced to -1 on termination, causing all further lock attempts
+- * to fail. (Note: we don't need CAS for termination state because
+- * upon pool shutdown, all shared-queues will stop being used
+- * anyway.) Nearly all lock bodies are set up so that exceptions
+- * within lock bodies are "impossible" (modulo JVM errors that
+- * would cause failure anyway.)
+- *
+- * The array slots are read and written using the emulation of
+- * volatiles/atomics provided by Unsafe. Insertions must in
+- * general use putOrderedObject as a form of releasing store to
+- * ensure that all writes to the task object are ordered before
+- * its publication in the queue. All removals entail a CAS to
+- * null. The array is always a power of two. To ensure safety of
+- * Unsafe array operations, all accesses perform explicit null
+- * checks and implicit bounds checks via power-of-two masking.
+- *
+- * In addition to basic queuing support, this class contains
+- * fields described elsewhere to control execution. It turns out
+- * to work better memory-layout-wise to include them in this class
+- * rather than a separate class.
+- *
++ * submission. See above for descriptions and algorithms.
+ * Performance on most platforms is very sensitive to placement of
+ * instances of both WorkQueues and their arrays -- we absolutely
+ * do not want multiple WorkQueue instances or multiple queue
+- * arrays sharing cache lines. (It would be best for queue objects
+- * and their arrays to share, but there is nothing available to
+- * help arrange that). The @Contended annotation alerts JVMs to
+- * try to keep instances apart.
++ * arrays sharing cache lines. The @Contended annotation alerts
++ * JVMs to try to keep instances apart.
+ */
+ @sun.misc.Contended
+ static final class WorkQueue {
++
+ /**
+ * Capacity of work-stealing queue array upon initialization.
+ * Must be a power of two; at least 4, but should be larger to
+@@ -679,13 +797,13 @@
+ */
+ static final int MAXIMUM_QUEUE_CAPACITY = 1 << 26; // 64M
+
+- volatile int eventCount; // encoded inactivation count; < 0 if inactive
+- int nextWait; // encoded record of next event waiter
++ // Instance fields
++ volatile int scanState; // versioned, <0: inactive; odd:scanning
++ int stackPred; // pool stack (ctl) predecessor
+ int nsteals; // number of steals
+- int hint; // steal index hint
+- short poolIndex; // index of this queue in pool
+- final short mode; // 0: lifo, > 0: fifo, < 0: shared
+- volatile int qlock; // 1: locked, -1: terminate; else 0
++ int hint; // randomization and stealer index hint
++ int config; // pool index and mode
++ volatile int qlock; // 1: locked, < 0: terminate; else 0
+ volatile int base; // index of next slot for poll
+ int top; // index of next slot for push
+ ForkJoinTask<?>[] array; // the elements (initially unallocated)
+@@ -693,19 +811,23 @@
+ final ForkJoinWorkerThread owner; // owning thread or null if shared
+ volatile Thread parker; // == owner during call to park; else null
+ volatile ForkJoinTask<?> currentJoin; // task being joined in awaitJoin
+- ForkJoinTask<?> currentSteal; // current non-local task being executed
++ volatile ForkJoinTask<?> currentSteal; // mainly used by helpStealer
+
+- WorkQueue(ForkJoinPool pool, ForkJoinWorkerThread owner, int mode,
+- int seed) {
++ WorkQueue(ForkJoinPool pool, ForkJoinWorkerThread owner) {
+ this.pool = pool;
+ this.owner = owner;
+- this.mode = (short)mode;
+- this.hint = seed; // store initial seed for runWorker
+ // Place indices in the center of array (that is not yet allocated)
+ base = top = INITIAL_QUEUE_CAPACITY >>> 1;
+ }
+
+ /**
++ * Returns an exportable index (used by ForkJoinWorkerThread).
++ */
++ final int getPoolIndex() {
++ return (config & 0xffff) >>> 1; // ignore odd/even tag bit
++ }
++
++ /**
+ * Returns the approximate number of tasks in the queue.
+ */
+ final int queueSize() {
+@@ -719,12 +841,10 @@
+ * near-empty queue has at least one unclaimed task.
+ */
+ final boolean isEmpty() {
+- ForkJoinTask<?>[] a; int m, s;
+- int n = base - (s = top);
+- return (n >= 0 ||
+- (n == -1 &&
+- ((a = array) == null ||
+- (m = a.length - 1) < 0 ||
++ ForkJoinTask<?>[] a; int n, m, s;
++ return ((n = base - (s = top)) >= 0 ||
++ (n == -1 && // possibly one task
++ ((a = array) == null || (m = a.length - 1) < 0 ||
+ U.getObject
+ (a, (long)((m & (s - 1)) << ASHIFT) + ABASE) == null)));
+ }
+@@ -738,12 +858,15 @@
+ */
+ final void push(ForkJoinTask<?> task) {
+ ForkJoinTask<?>[] a; ForkJoinPool p;
+- int s = top, n;
++ int b = base, s = top, n;
+ if ((a = array) != null) { // ignore if queue removed
+- int m = a.length - 1;
++ int m = a.length - 1; // fenced write for task visibility
+ U.putOrderedObject(a, ((m & s) << ASHIFT) + ABASE, task);
+- if ((n = (top = s + 1) - base) <= 2)
+- (p = pool).signalWork(p.workQueues, this);
++ U.putOrderedInt(this, QTOP, s + 1);
++ if ((n = s - b) <= 1) {
++ if ((p = pool) != null)
++ p.signalWork(p.workQueues, this);
++ }
+ else if (n >= m)
+ growArray();
+ }
+@@ -764,7 +887,7 @@
+ if (oldA != null && (oldMask = oldA.length - 1) >= 0 &&
+ (t = top) - (b = base) > 0) {
+ int mask = size - 1;
+- do {
++ do { // emulate poll from old array, push to new array
+ ForkJoinTask<?> x;
+ int oldj = ((b & oldMask) << ASHIFT) + ABASE;
+ int j = ((b & mask) << ASHIFT) + ABASE;
+@@ -789,7 +912,7 @@
+ if ((t = (ForkJoinTask<?>)U.getObject(a, j)) == null)
+ break;
+ if (U.compareAndSwapObject(a, j, t, null)) {
+- top = s;
++ U.putOrderedInt(this, QTOP, s);
+ return t;
+ }
+ }
+@@ -800,7 +923,7 @@
+ /**
+ * Takes a task in FIFO order if b is base of queue and a task
+ * can be claimed without contention. Specialized versions
+- * appear in ForkJoinPool methods scan and tryHelpStealer.
++ * appear in ForkJoinPool methods scan and helpStealer.
+ */
+ final ForkJoinTask<?> pollAt(int b) {
+ ForkJoinTask<?> t; ForkJoinTask<?>[] a;
+@@ -808,7 +931,7 @@
+ int j = (((a.length - 1) & b) << ASHIFT) + ABASE;
+ if ((t = (ForkJoinTask<?>)U.getObjectVolatile(a, j)) != null &&
+ base == b && U.compareAndSwapObject(a, j, t, null)) {
+- U.putOrderedInt(this, QBASE, b + 1);
++ base = b + 1;
+ return t;
+ }
+ }
+@@ -823,16 +946,15 @@
+ while ((b = base) - top < 0 && (a = array) != null) {
+ int j = (((a.length - 1) & b) << ASHIFT) + ABASE;
+ t = (ForkJoinTask<?>)U.getObjectVolatile(a, j);
+- if (t != null) {
+- if (U.compareAndSwapObject(a, j, t, null)) {
+- U.putOrderedInt(this, QBASE, b + 1);
+- return t;
++ if (base == b) {
++ if (t != null) {
++ if (U.compareAndSwapObject(a, j, t, null)) {
++ base = b + 1;
++ return t;
++ }
+ }
+- }
+- else if (base == b) {
+- if (b + 1 == top)
++ else if (b + 1 == top) // now empty
+ break;
+- Thread.yield(); // wait for lagging update (very rare)
+ }
+ }
+ return null;
+@@ -842,7 +964,7 @@
+ * Takes next task, if one exists, in order specified by mode.
+ */
+ final ForkJoinTask<?> nextLocalTask() {
+- return mode == 0 ? pop() : poll();
++ return (config & FIFO_QUEUE) == 0 ? pop() : poll();
+ }
+
+ /**
+@@ -852,7 +974,7 @@
+ ForkJoinTask<?>[] a = array; int m;
+ if (a == null || (m = a.length - 1) < 0)
+ return null;
+- int i = mode == 0 ? top - 1 : base;
++ int i = (config & FIFO_QUEUE) == 0 ? top - 1 : base;
+ int j = ((i & m) << ASHIFT) + ABASE;
+ return (ForkJoinTask<?>)U.getObjectVolatile(a, j);
+ }
+@@ -860,13 +982,13 @@
+ /**
+ * Pops the given task only if it is at the current top.
+ * (A shared version is available only via FJP.tryExternalUnpush)
+- */
++ */
+ final boolean tryUnpush(ForkJoinTask<?> t) {
+ ForkJoinTask<?>[] a; int s;
+ if ((a = array) != null && (s = top) != base &&
+ U.compareAndSwapObject
+ (a, (((a.length - 1) & --s) << ASHIFT) + ABASE, t, null)) {
+- top = s;
++ U.putOrderedInt(this, QTOP, s);
+ return true;
+ }
+ return false;
+@@ -876,9 +998,16 @@
+ * Removes and cancels all known tasks, ignoring any exceptions.
+ */
+ final void cancelAll() {
+- ForkJoinTask.cancelIgnoringExceptions(currentJoin);
+- ForkJoinTask.cancelIgnoringExceptions(currentSteal);
+- for (ForkJoinTask<?> t; (t = poll()) != null; )
++ ForkJoinTask<?> t;
++ if ((t = currentJoin) != null) {
++ currentJoin = null;
++ ForkJoinTask.cancelIgnoringExceptions(t);
++ }
++ if ((t = currentSteal) != null) {
++ currentSteal = null;
++ ForkJoinTask.cancelIgnoringExceptions(t);
++ }
++ while ((t = poll()) != null)
+ ForkJoinTask.cancelIgnoringExceptions(t);
+ }
+
+@@ -893,167 +1022,186 @@
+ }
+
+ /**
+- * Executes a top-level task and any local tasks remaining
+- * after execution.
++ * Removes and executes all local tasks. If LIFO, invokes
++ * pollAndExecAll. Otherwise implements a specialized pop loop
++ * to exec until empty.
++ */
++ final void execLocalTasks() {
++ int b = base, m, s;
++ ForkJoinTask<?>[] a = array;
++ if (b - (s = top - 1) <= 0 && a != null &&
++ (m = a.length - 1) >= 0) {
++ if ((config & FIFO_QUEUE) == 0) {
++ for (ForkJoinTask<?> t;;) {
++ if ((t = (ForkJoinTask<?>)U.getAndSetObject
++ (a, ((m & s) << ASHIFT) + ABASE, null)) == null)
++ break;
++ U.putOrderedInt(this, QTOP, s);
++ t.doExec();
++ if (base - (s = top - 1) > 0)
++ break;
++ }
++ }
++ else
++ pollAndExecAll();
++ }
++ }
++
++ /**
++ * Executes the given task and any remaining local tasks.
+ */
+ final void runTask(ForkJoinTask<?> task) {
+- if ((currentSteal = task) != null) {
+- ForkJoinWorkerThread thread;
+- task.doExec();
+- ForkJoinTask<?>[] a = array;
+- int md = mode;
+- ++nsteals;
+- currentSteal = null;
+- if (md != 0)
+- pollAndExecAll();
+- else if (a != null) {
+- int s, m = a.length - 1;
+- ForkJoinTask<?> t;
+- while ((s = top - 1) - base >= 0 &&
+- (t = (ForkJoinTask<?>)U.getAndSetObject
+- (a, ((m & s) << ASHIFT) + ABASE, null)) != null) {
+- top = s;
+- t.doExec();
+- }
+- }
+- if ((thread = owner) != null) // no need to do in finally clause
++ if (task != null) {
++ scanState &= ~SCANNING; // mark as busy
++ (currentSteal = task).doExec();
++ U.putOrderedObject(this, QCURRENTSTEAL, null); // release for GC
++ execLocalTasks();
++ ForkJoinWorkerThread thread = owner;
++ if (++nsteals < 0) // collect on overflow
++ transferStealCount(pool);
++ scanState |= SCANNING;
++ if (thread != null)
+ thread.afterTopLevelExec();
+ }
+ }
+
+ /**
+- * If present, removes from queue and executes the given task,
+- * or any other cancelled task. Returns (true) on any CAS
+- * or consistency check failure so caller can retry.
+- *
+- * @return false if no progress can be made, else true
++ * Adds steal count to pool stealCounter if it exists, and resets.
+ */
+- final boolean tryRemoveAndExec(ForkJoinTask<?> task) {
+- boolean stat;
+- ForkJoinTask<?>[] a; int m, s, b, n;
+- if (task != null && (a = array) != null && (m = a.length - 1) >= 0 &&
+- (n = (s = top) - (b = base)) > 0) {
+- boolean removed = false, empty = true;
+- stat = true;
+- for (ForkJoinTask<?> t;;) { // traverse from s to b
+- long j = ((--s & m) << ASHIFT) + ABASE;
+- t = (ForkJoinTask<?>)U.getObject(a, j);
+- if (t == null) // inconsistent length
+- break;
+- else if (t == task) {
+- if (s + 1 == top) { // pop
+- if (!U.compareAndSwapObject(a, j, task, null))
+- break;
+- top = s;
+- removed = true;
+- }
+- else if (base == b) // replace with proxy
+- removed = U.compareAndSwapObject(a, j, task,
+- new EmptyTask());
+- break;
+- }
+- else if (t.status >= 0)
+- empty = false;
+- else if (s + 1 == top) { // pop and throw away
+- if (U.compareAndSwapObject(a, j, t, null))
+- top = s;
+- break;
+- }
+- if (--n == 0) {
+- if (!empty && base == b)
+- stat = false;
+- break;
+- }
+- }
+- if (removed)
+- task.doExec();
++ final void transferStealCount(ForkJoinPool p) {
++ AtomicLong sc;
++ if (p != null && (sc = p.stealCounter) != null) {
++ int s = nsteals;
++ nsteals = 0; // if negative, correct for overflow
++ sc.getAndAdd((long)(s < 0 ? Integer.MAX_VALUE : s));
+ }
+- else
+- stat = false;
+- return stat;
+ }
+
+ /**
+- * Tries to poll for and execute the given task or any other
+- * task in its CountedCompleter computation.
++ * If present, removes from queue and executes the given task,
++ * or any other cancelled task. Used only by awaitJoin.
++ *
++ * @return true if queue empty and task not known to be done
+ */
+- final boolean pollAndExecCC(CountedCompleter<?> root) {
+- ForkJoinTask<?>[] a; int b; Object o; CountedCompleter<?> t, r;
+- if ((b = base) - top < 0 && (a = array) != null) {
+- long j = (((a.length - 1) & b) << ASHIFT) + ABASE;
+- if ((o = U.getObjectVolatile(a, j)) == null)
+- return true; // retry
+- if (o instanceof CountedCompleter) {
+- for (t = (CountedCompleter<?>)o, r = t;;) {
+- if (r == root) {
+- if (base == b &&
+- U.compareAndSwapObject(a, j, t, null)) {
+- U.putOrderedInt(this, QBASE, b + 1);
+- t.doExec();
++ final boolean tryRemoveAndExec(ForkJoinTask<?> task) {
++ ForkJoinTask<?>[] a; int m, s, b, n;
++ if ((a = array) != null && (m = a.length - 1) >= 0 &&
++ task != null) {
++ while ((n = (s = top) - (b = base)) > 0) {
++ for (ForkJoinTask<?> t;;) { // traverse from s to b
++ long j = ((--s & m) << ASHIFT) + ABASE;
++ if ((t = (ForkJoinTask<?>)U.getObject(a, j)) == null)
++ return s + 1 == top; // shorter than expected
++ else if (t == task) {
++ boolean removed = false;
++ if (s + 1 == top) { // pop
++ if (U.compareAndSwapObject(a, j, task, null)) {
++ U.putOrderedInt(this, QTOP, s);
++ removed = true;
++ }
+ }
+- return true;
++ else if (base == b) // replace with proxy
++ removed = U.compareAndSwapObject(
++ a, j, task, new EmptyTask());
++ if (removed)
++ task.doExec();
++ break;
+ }
+- else if ((r = r.completer) == null)
+- break; // not part of root computation
++ else if (t.status < 0 && s + 1 == top) {
++ if (U.compareAndSwapObject(a, j, t, null))
++ U.putOrderedInt(this, QTOP, s);
++ break; // was cancelled
++ }
++ if (--n == 0)
++ return false;
+ }
++ if (task.status < 0)
++ return false;
+ }
+ }
+- return false;
++ return true;
+ }
+
+ /**
+- * Tries to pop and execute the given task or any other task
+- * in its CountedCompleter computation.
++ * Pops task if in the same CC computation as the given task,
++ * in either shared or owned mode. Used only by helpComplete.
+ */
+- final boolean externalPopAndExecCC(CountedCompleter<?> root) {
+- ForkJoinTask<?>[] a; int s; Object o; CountedCompleter<?> t, r;
++ final CountedCompleter<?> popCC(CountedCompleter<?> task, int mode) {
++ int s; ForkJoinTask<?>[] a; Object o;
+ if (base - (s = top) < 0 && (a = array) != null) {
+ long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
+- if ((o = U.getObject(a, j)) instanceof CountedCompleter) {
+- for (t = (CountedCompleter<?>)o, r = t;;) {
+- if (r == root) {
+- if (U.compareAndSwapInt(this, QLOCK, 0, 1)) {
+- if (top == s && array == a &&
+- U.compareAndSwapObject(a, j, t, null)) {
+- top = s - 1;
+- qlock = 0;
+- t.doExec();
++ if ((o = U.getObjectVolatile(a, j)) != null &&
++ (o instanceof CountedCompleter)) {
++ CountedCompleter<?> t = (CountedCompleter<?>)o;
++ for (CountedCompleter<?> r = t;;) {
++ if (r == task) {
++ if (mode < 0) { // must lock
++ if (U.compareAndSwapInt(this, QLOCK, 0, 1)) {
++ if (top == s && array == a &&
++ U.compareAndSwapObject(a, j, t, null)) {
++ U.putOrderedInt(this, QTOP, s - 1);
++ U.putOrderedInt(this, QLOCK, 0);
++ return t;
++ }
++ U.compareAndSwapInt(this, QLOCK, 1, 0);
+ }
+- else
+- qlock = 0;
+ }
+- return true;
++ else if (U.compareAndSwapObject(a, j, t, null)) {
++ U.putOrderedInt(this, QTOP, s - 1);
++ return t;
++ }
++ break;
+ }
+- else if ((r = r.completer) == null)
++ else if ((r = r.completer) == null) // try parent
+ break;
+ }
+ }
+ }
+- return false;
++ return null;
+ }
+
+ /**
+- * Internal version
++ * Steals and runs a task in the same CC computation as the
++ * given task if one exists and can be taken without
++ * contention. Otherwise returns a checksum/control value for
++ * use by method helpComplete.
++ *
++ * @return 1 if successful, 2 if retryable (lost to another
++ * stealer), -1 if non-empty but no matching task found, else
++ * the base index, forced negative.
+ */
+- final boolean internalPopAndExecCC(CountedCompleter<?> root) {
+- ForkJoinTask<?>[] a; int s; Object o; CountedCompleter<?> t, r;
+- if (base - (s = top) < 0 && (a = array) != null) {
+- long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
+- if ((o = U.getObject(a, j)) instanceof CountedCompleter) {
+- for (t = (CountedCompleter<?>)o, r = t;;) {
+- if (r == root) {
+- if (U.compareAndSwapObject(a, j, t, null)) {
+- top = s - 1;
++ final int pollAndExecCC(CountedCompleter<?> task) {
++ int b, h; ForkJoinTask<?>[] a; Object o;
++ if ((b = base) - top >= 0 || (a = array) == null)
++ h = b | Integer.MIN_VALUE; // to sense movement on re-poll
++ else {
++ long j = (((a.length - 1) & b) << ASHIFT) + ABASE;
++ if ((o = U.getObjectVolatile(a, j)) == null)
++ h = 2; // retryable
++ else if (!(o instanceof CountedCompleter))
++ h = -1; // unmatchable
++ else {
++ CountedCompleter<?> t = (CountedCompleter<?>)o;
++ for (CountedCompleter<?> r = t;;) {
++ if (r == task) {
++ if (base == b &&
++ U.compareAndSwapObject(a, j, t, null)) {
++ base = b + 1;
+ t.doExec();
++ h = 1; // success
+ }
+- return true;
++ else
++ h = 2; // lost CAS
++ break;
+ }
+- else if ((r = r.completer) == null)
++ else if ((r = r.completer) == null) {
++ h = -1; // unmatched
+ break;
++ }
+ }
+ }
+ }
+- return false;
++ return h;
+ }
+
+ /**
+@@ -1061,28 +1209,31 @@
+ */
+ final boolean isApparentlyUnblocked() {
+ Thread wt; Thread.State s;
+- return (eventCount >= 0 &&
++ return (scanState >= 0 &&
+ (wt = owner) != null &&
+ (s = wt.getState()) != Thread.State.BLOCKED &&
+ s != Thread.State.WAITING &&
+ s != Thread.State.TIMED_WAITING);
+ }
+
+- // Unsafe mechanics
++ // Unsafe mechanics. Note that some are (and must be) the same as in FJP
+ private static final sun.misc.Unsafe U;
+- private static final long QBASE;
++ private static final int ABASE;
++ private static final int ASHIFT;
++ private static final long QTOP;
+ private static final long QLOCK;
+- private static final int ABASE;
+- private static final int ASHIFT;
++ private static final long QCURRENTSTEAL;
+ static {
+ try {
+ U = sun.misc.Unsafe.getUnsafe();
+- Class<?> k = WorkQueue.class;
++ Class<?> wk = WorkQueue.class;
+ Class<?> ak = ForkJoinTask[].class;
+- QBASE = U.objectFieldOffset
+- (k.getDeclaredField("base"));
++ QTOP = U.objectFieldOffset
++ (wk.getDeclaredField("top"));
+ QLOCK = U.objectFieldOffset
+- (k.getDeclaredField("qlock"));
++ (wk.getDeclaredField("qlock"));
++ QCURRENTSTEAL = U.objectFieldOffset
++ (wk.getDeclaredField("currentSteal"));
+ ABASE = U.arrayBaseOffset(ak);
+ int scale = U.arrayIndexScale(ak);
+ if ((scale & (scale - 1)) != 0)
+@@ -1126,6 +1277,11 @@
+ static final int commonParallelism;
+
+ /**
++ * Limit on spare thread construction in tryCompensate.
++ */
++ private static int commonMaxSpares;
++
++ /**
+ * Sequence number for creating workerNamePrefix.
+ */
+ private static int poolNumberSequence;
+@@ -1138,7 +1294,7 @@
+ return ++poolNumberSequence;
+ }
+
+- // static constants
++ // static configuration constants
+
+ /**
+ * Initial timeout value (in nanoseconds) for the thread
+@@ -1148,27 +1304,32 @@
+ * aggressive shrinkage during most transient stalls (long GCs
+ * etc).
+ */
+- private static final long IDLE_TIMEOUT = 2000L * 1000L * 1000L; // 2sec
+-
+- /**
+- * Timeout value when there are more threads than parallelism level
+- */
+- private static final long FAST_IDLE_TIMEOUT = 200L * 1000L * 1000L;
++ private static final long IDLE_TIMEOUT = 2000L * 1000L * 1000L; // 2sec
+
+ /**
+ * Tolerance for idle timeouts, to cope with timer undershoots
+ */
+- private static final long TIMEOUT_SLOP = 2000000L;
++ private static final long TIMEOUT_SLOP = 20L * 1000L * 1000L; // 20ms
+
+ /**
+- * The maximum stolen->joining link depth allowed in method
+- * tryHelpStealer. Must be a power of two. Depths for legitimate
+- * chains are unbounded, but we use a fixed constant to avoid
+- * (otherwise unchecked) cycles and to bound staleness of
+- * traversal parameters at the expense of sometimes blocking when
+- * we could be helping.
++ * The initial value for commonMaxSpares during static
++ * initialization. The value is far in excess of normal
++ * requirements, but also far short of MAX_CAP and typical
++ * OS thread limits, so allows JVMs to catch misuse/abuse
++ * before running out of resources needed to do so.
+ */
+- private static final int MAX_HELP = 64;
++ private static final int DEFAULT_COMMON_MAX_SPARES = 256;
++
++ /**
++ * Number of times to spin-wait before blocking. The spins (in
++ * awaitRunStateLock and awaitWork) currently use randomized
++ * spins. If/when MWAIT-like intrinsics becomes available, they
++ * may allow quieter spinning. The value of SPINS must be a power
++ * of two, at least 4. The current value causes spinning for a
++ * small fraction of typical context-switch times, well worthwhile
++ * given the typical likelihoods that blocking is not necessary.
++ */
++ private static final int SPINS = 1 << 11;
+
+ /**
+ * Increment for seed generators. See class ThreadLocal for
+@@ -1177,209 +1338,212 @@
+ private static final int SEED_INCREMENT = 0x9e3779b9;
+
+ /*
+- * Bits and masks for control variables
++ * Bits and masks for field ctl, packed with 4 16 bit subfields:
++ * AC: Number of active running workers minus target parallelism
++ * TC: Number of total workers minus target parallelism
++ * SS: version count and status of top waiting thread
++ * ID: poolIndex of top of Treiber stack of waiters
+ *
+- * Field ctl is a long packed with:
+- * AC: Number of active running workers minus target parallelism (16 bits)
+- * TC: Number of total workers minus target parallelism (16 bits)
+- * ST: true if pool is terminating (1 bit)
+- * EC: the wait count of top waiting thread (15 bits)
+- * ID: poolIndex of top of Treiber stack of waiters (16 bits)
++ * When convenient, we can extract the lower 32 stack top bits
++ * (including version bits) as sp=(int)ctl. The offsets of counts
++ * by the target parallelism and the positionings of fields makes
++ * it possible to perform the most common checks via sign tests of
++ * fields: When ac is negative, there are not enough active
++ * workers, when tc is negative, there are not enough total
++ * workers. When sp is non-zero, there are waiting workers. To
++ * deal with possibly negative fields, we use casts in and out of
++ * "short" and/or signed shifts to maintain signedness.
+ *
+- * When convenient, we can extract the upper 32 bits of counts and
+- * the lower 32 bits of queue state, u = (int)(ctl >>> 32) and e =
+- * (int)ctl. The ec field is never accessed alone, but always
+- * together with id and st. The offsets of counts by the target
+- * parallelism and the positionings of fields makes it possible to
+- * perform the most common checks via sign tests of fields: When
+- * ac is negative, there are not enough active workers, when tc is
+- * negative, there are not enough total workers, and when e is
+- * negative, the pool is terminating. To deal with these possibly
+- * negative fields, we use casts in and out of "short" and/or
+- * signed shifts to maintain signedness.
+- *
+- * When a thread is queued (inactivated), its eventCount field is
+- * set negative, which is the only way to tell if a worker is
+- * prevented from executing tasks, even though it must continue to
+- * scan for them to avoid queuing races. Note however that
+- * eventCount updates lag releases so usage requires care.
+- *
+- * Field plock is an int packed with:
+- * SHUTDOWN: true if shutdown is enabled (1 bit)
+- * SEQ: a sequence lock, with PL_LOCK bit set if locked (30 bits)
+- * SIGNAL: set when threads may be waiting on the lock (1 bit)
+- *
+- * The sequence number enables simple consistency checks:
+- * Staleness of read-only operations on the workQueues array can
+- * be checked by comparing plock before vs after the reads.
++ * Because it occupies uppermost bits, we can add one active count
++ * using getAndAddLong of AC_UNIT, rather than CAS, when returning
++ * from a blocked join. Other updates entail multiple subfields
++ * and masking, requiring CAS.
+ */
+
+- // bit positions/shifts for fields
++ // Lower and upper word masks
++ private static final long SP_MASK = 0xffffffffL;
++ private static final long UC_MASK = ~SP_MASK;
++
++ // Active counts
+ private static final int AC_SHIFT = 48;
++ private static final long AC_UNIT = 0x0001L << AC_SHIFT;
++ private static final long AC_MASK = 0xffffL << AC_SHIFT;
++
++ // Total counts
+ private static final int TC_SHIFT = 32;
+- private static final int ST_SHIFT = 31;
+- private static final int EC_SHIFT = 16;
++ private static final long TC_UNIT = 0x0001L << TC_SHIFT;
++ private static final long TC_MASK = 0xffffL << TC_SHIFT;
++ private static final long ADD_WORKER = 0x0001L << (TC_SHIFT + 15); // sign
+
+- // bounds
+- private static final int SMASK = 0xffff; // short bits
+- private static final int MAX_CAP = 0x7fff; // max #workers - 1
+- private static final int EVENMASK = 0xfffe; // even short bits
+- private static final int SQMASK = 0x007e; // max 64 (even) slots
+- private static final int SHORT_SIGN = 1 << 15;
+- private static final int INT_SIGN = 1 << 31;
+-
+- // masks
+- private static final long STOP_BIT = 0x0001L << ST_SHIFT;
+- private static final long AC_MASK = ((long)SMASK) << AC_SHIFT;
+- private static final long TC_MASK = ((long)SMASK) << TC_SHIFT;
+-
+- // units for incrementing and decrementing
+- private static final long TC_UNIT = 1L << TC_SHIFT;
+- private static final long AC_UNIT = 1L << AC_SHIFT;
+-
+- // masks and units for dealing with u = (int)(ctl >>> 32)
+- private static final int UAC_SHIFT = AC_SHIFT - 32;
+- private static final int UTC_SHIFT = TC_SHIFT - 32;
+- private static final int UAC_MASK = SMASK << UAC_SHIFT;
+- private static final int UTC_MASK = SMASK << UTC_SHIFT;
+- private static final int UAC_UNIT = 1 << UAC_SHIFT;
+- private static final int UTC_UNIT = 1 << UTC_SHIFT;
+-
+- // masks and units for dealing with e = (int)ctl
+- private static final int E_MASK = 0x7fffffff; // no STOP_BIT
+- private static final int E_SEQ = 1 << EC_SHIFT;
+-
+- // plock bits
+- private static final int SHUTDOWN = 1 << 31;
+- private static final int PL_LOCK = 2;
+- private static final int PL_SIGNAL = 1;
+- private static final int PL_SPINS = 1 << 8;
+-
+- // access mode for WorkQueue
+- static final int LIFO_QUEUE = 0;
+- static final int FIFO_QUEUE = 1;
+- static final int SHARED_QUEUE = -1;
++ // runState bits: SHUTDOWN must be negative, others arbitrary powers of two
++ private static final int RSLOCK = 1;
++ private static final int RSIGNAL = 1 << 1;
++ private static final int STARTED = 1 << 2;
++ private static final int STOP = 1 << 29;
++ private static final int TERMINATED = 1 << 30;
++ private static final int SHUTDOWN = 1 << 31;
+
+ // Instance fields
+- volatile long stealCount; // collects worker counts
+- volatile long ctl; // main pool control
+- volatile int plock; // shutdown status and seqLock
+- volatile int indexSeed; // worker/submitter index seed
+- final short parallelism; // parallelism level
+- final short mode; // LIFO/FIFO
+- WorkQueue[] workQueues; // main registry
++ volatile long ctl; // main pool control
++ volatile int runState; // lockable status
++ final int config; // parallelism, mode
++ int indexSeed; // to generate worker index
++ volatile WorkQueue[] workQueues; // main registry
+ final ForkJoinWorkerThreadFactory factory;
+- final UncaughtExceptionHandler ueh; // per-worker UEH
+- final String workerNamePrefix; // to create worker name string
++ final UncaughtExceptionHandler ueh; // per-worker UEH
++ final String workerNamePrefix; // to create worker name string
++ volatile AtomicLong stealCounter; // also used as sync monitor
+
+ /**
+- * Acquires the plock lock to protect worker array and related
+- * updates. This method is called only if an initial CAS on plock
+- * fails. This acts as a spinlock for normal cases, but falls back
+- * to builtin monitor to block when (rarely) needed. This would be
+- * a terrible idea for a highly contended lock, but works fine as
+- * a more conservative alternative to a pure spinlock.
++ * Acquires the runState lock; returns current (locked) runState.
+ */
+- private int acquirePlock() {
+- int spins = PL_SPINS, ps, nps;
+- for (;;) {
+- if (((ps = plock) & PL_LOCK) == 0 &&
+- U.compareAndSwapInt(this, PLOCK, ps, nps = ps + PL_LOCK))
+- return nps;
+- else if (spins >= 0) {
+- if (ThreadLocalRandom.nextSecondarySeed() >= 0)
++ private int lockRunState() {
++ int rs;
++ return ((((rs = runState) & RSLOCK) != 0 ||
++ !U.compareAndSwapInt(this, RUNSTATE, rs, rs |= RSLOCK)) ?
++ awaitRunStateLock() : rs);
++ }
++
++ /**
++ * Spins and/or blocks until runstate lock is available. See
++ * above for explanation.
++ */
++ private int awaitRunStateLock() {
++ Object lock;
++ boolean wasInterrupted = false;
++ for (int spins = SPINS, r = 0, rs, ns;;) {
++ if (((rs = runState) & RSLOCK) == 0) {
++ if (U.compareAndSwapInt(this, RUNSTATE, rs, ns = rs | RSLOCK)) {
++ if (wasInterrupted) {
++ try {
++ Thread.currentThread().interrupt();
++ } catch (SecurityException ignore) {
++ }
++ }
++ return ns;
++ }
++ }
++ else if (r == 0)
++ r = ThreadLocalRandom.nextSecondarySeed();
++ else if (spins > 0) {
++ r ^= r << 6; r ^= r >>> 21; r ^= r << 7; // xorshift
++ if (r >= 0)
+ --spins;
+ }
+- else if (U.compareAndSwapInt(this, PLOCK, ps, ps | PL_SIGNAL)) {
+- synchronized (this) {
+- if ((plock & PL_SIGNAL) != 0) {
++ else if ((rs & STARTED) == 0 || (lock = stealCounter) == null)
++ Thread.yield(); // initialization race
++ else if (U.compareAndSwapInt(this, RUNSTATE, rs, rs | RSIGNAL)) {
++ synchronized (lock) {
++ if ((runState & RSIGNAL) != 0) {
+ try {
+- wait();
++ lock.wait();
+ } catch (InterruptedException ie) {
+- try {
+- Thread.currentThread().interrupt();
+- } catch (SecurityException ignore) {
+- }
++ if (!(Thread.currentThread() instanceof
++ ForkJoinWorkerThread))
++ wasInterrupted = true;
+ }
+ }
+ else
+- notifyAll();
++ lock.notifyAll();
+ }
+ }
+ }
+ }
+
+ /**
+- * Unlocks and signals any thread waiting for plock. Called only
+- * when CAS of seq value for unlock fails.
++ * Unlocks and sets runState to newRunState.
++ *
++ * @param oldRunState a value returned from lockRunState
++ * @param newRunState the next value (must have lock bit clear).
+ */
+- private void releasePlock(int ps) {
+- plock = ps;
+- synchronized (this) { notifyAll(); }
++ private void unlockRunState(int oldRunState, int newRunState) {
++ if (!U.compareAndSwapInt(this, RUNSTATE, oldRunState, newRunState)) {
++ Object lock = stealCounter;
++ runState = newRunState; // clears RSIGNAL bit
++ if (lock != null)
++ synchronized (lock) { lock.notifyAll(); }
++ }
++ }
++
++ // Creating, registering and deregistering workers
++
++ /**
++ * Tries to construct and start one worker. Assumes that total
++ * count has already been incremented as a reservation. Invokes
++ * deregisterWorker on any failure.
++ *
++ * @return true if successful
++ */
++ private boolean createWorker() {
++ ForkJoinWorkerThreadFactory fac = factory;
++ Throwable ex = null;
++ ForkJoinWorkerThread wt = null;
++ try {
++ if (fac != null && (wt = fac.newThread(this)) != null) {
++ wt.start();
++ return true;
++ }
++ } catch (Throwable rex) {
++ ex = rex;
++ }
++ deregisterWorker(wt, ex);
++ return false;
+ }
+
+ /**
+- * Tries to create and start one worker if fewer than target
+- * parallelism level exist. Adjusts counts etc on failure.
++ * Tries to add one worker, incrementing ctl counts before doing
++ * so, relying on createWorker to back out on failure.
++ *
++ * @param c incoming ctl value, with total count negative and no
++ * idle workers. On CAS failure, c is refreshed and retried if
++ * this holds (otherwise, a new worker is not needed).
+ */
+- private void tryAddWorker() {
+- long c; int u, e;
+- while ((u = (int)((c = ctl) >>> 32)) < 0 &&
+- (u & SHORT_SIGN) != 0 && (e = (int)c) >= 0) {
+- long nc = ((long)(((u + UTC_UNIT) & UTC_MASK) |
+- ((u + UAC_UNIT) & UAC_MASK)) << 32) | (long)e;
+- if (U.compareAndSwapLong(this, CTL, c, nc)) {
+- ForkJoinWorkerThreadFactory fac;
+- Throwable ex = null;
+- ForkJoinWorkerThread wt = null;
+- try {
+- if ((fac = factory) != null &&
+- (wt = fac.newThread(this)) != null) {
+- wt.start();
+- break;
+- }
+- } catch (Throwable rex) {
+- ex = rex;
++ private void tryAddWorker(long c) {
++ boolean add = false;
++ do {
++ long nc = ((AC_MASK & (c + AC_UNIT)) |
++ (TC_MASK & (c + TC_UNIT)));
++ if (ctl == c) {
++ int rs, stop; // check if terminating
++ if ((stop = (rs = lockRunState()) & STOP) == 0)
++ add = U.compareAndSwapLong(this, CTL, c, nc);
++ unlockRunState(rs, rs & ~RSLOCK);
++ if (stop != 0)
++ break;
++ if (add) {
++ createWorker();
++ break;
+ }
+- deregisterWorker(wt, ex);
+- break;
+ }
+- }
++ } while (((c = ctl) & ADD_WORKER) != 0L && (int)c == 0);
+ }
+
+- // Registering and deregistering workers
+-
+ /**
+- * Callback from ForkJoinWorkerThread to establish and record its
+- * WorkQueue. To avoid scanning bias due to packing entries in
+- * front of the workQueues array, we treat the array as a simple
+- * power-of-two hash table using per-thread seed as hash,
+- * expanding as needed.
++ * Callback from ForkJoinWorkerThread constructor to establish and
++ * record its WorkQueue.
+ *
+ * @param wt the worker thread
+ * @return the worker's queue
+ */
+ final WorkQueue registerWorker(ForkJoinWorkerThread wt) {
+- UncaughtExceptionHandler handler; WorkQueue[] ws; int s, ps;
+- wt.setDaemon(true);
++ UncaughtExceptionHandler handler;
++ wt.setDaemon(true); // configure thread
+ if ((handler = ueh) != null)
+ wt.setUncaughtExceptionHandler(handler);
+- do {} while (!U.compareAndSwapInt(this, INDEXSEED, s = indexSeed,
+- s += SEED_INCREMENT) ||
+- s == 0); // skip 0
+- WorkQueue w = new WorkQueue(this, wt, mode, s);
+- if (((ps = plock) & PL_LOCK) != 0 ||
+- !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
+- ps = acquirePlock();
+- int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
++ WorkQueue w = new WorkQueue(this, wt);
++ int i = 0; // assign a pool index
++ int mode = config & MODE_MASK;
++ int rs = lockRunState();
+ try {
+- if ((ws = workQueues) != null) { // skip if shutting down
+- int n = ws.length, m = n - 1;
+- int r = (s << 1) | 1; // use odd-numbered indices
+- if (ws[r &= m] != null) { // collision
+- int probes = 0; // step by approx half size
++ WorkQueue[] ws; int n; // skip if no array
++ if ((ws = workQueues) != null && (n = ws.length) > 0) {
++ int s = indexSeed += SEED_INCREMENT; // unlikely to collide
++ int m = n - 1;
++ i = ((s << 1) | 1) & m; // odd-numbered indices
++ if (ws[i] != null) { // collision
++ int probes = 0; // step by approx half n
+ int step = (n <= 4) ? 2 : ((n >>> 1) & EVENMASK) + 2;
+- while (ws[r = (r + step) & m] != null) {
++ while (ws[i = (i + step) & m] != null) {
+ if (++probes >= n) {
+ workQueues = ws = Arrays.copyOf(ws, n <<= 1);
+ m = n - 1;
+@@ -1387,15 +1551,15 @@
+ }
+ }
+ }
+- w.poolIndex = (short)r;
+- w.eventCount = r; // volatile write orders
+- ws[r] = w;
++ w.hint = s; // use as random seed
++ w.config = i | mode;
++ w.scanState = i; // publication fence
++ ws[i] = w;
+ }
+ } finally {
+- if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
+- releasePlock(nps);
++ unlockRunState(rs, rs & ~RSLOCK);
+ }
+- wt.setName(workerNamePrefix.concat(Integer.toString(w.poolIndex >>> 1)));
++ wt.setName(workerNamePrefix.concat(Integer.toString(i >>> 1)));
+ return w;
+ }
+
+@@ -1411,384 +1575,322 @@
+ final void deregisterWorker(ForkJoinWorkerThread wt, Throwable ex) {
+ WorkQueue w = null;
+ if (wt != null && (w = wt.workQueue) != null) {
+- int ps;
+- w.qlock = -1; // ensure set
+- U.getAndAddLong(this, STEALCOUNT, w.nsteals); // collect steals
+- if (((ps = plock) & PL_LOCK) != 0 ||
+- !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
+- ps = acquirePlock();
+- int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
+- try {
+- int idx = w.poolIndex;
+- WorkQueue[] ws = workQueues;
+- if (ws != null && idx >= 0 && idx < ws.length && ws[idx] == w)
+- ws[idx] = null;
+- } finally {
+- if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
+- releasePlock(nps);
++ WorkQueue[] ws; // remove index from array
++ int idx = w.config & SMASK;
++ int rs = lockRunState();
++ if ((ws = workQueues) != null && ws.length > idx && ws[idx] == w)
++ ws[idx] = null;
++ unlockRunState(rs, rs & ~RSLOCK);
++ }
++ long c; // decrement counts
++ do {} while (!U.compareAndSwapLong
++ (this, CTL, c = ctl, ((AC_MASK & (c - AC_UNIT)) |
++ (TC_MASK & (c - TC_UNIT)) |
++ (SP_MASK & c))));
++ if (w != null) {
++ w.qlock = -1; // ensure set
++ w.transferStealCount(this);
++ w.cancelAll(); // cancel remaining tasks
++ }
++ for (;;) { // possibly replace
++ WorkQueue[] ws; int m, sp;
++ if (tryTerminate(false, false) || w == null || w.array == null ||
++ (runState & STOP) != 0 || (ws = workQueues) == null ||
++ (m = ws.length - 1) < 0) // already terminating
++ break;
++ if ((sp = (int)(c = ctl)) != 0) { // wake up replacement
++ if (tryRelease(c, ws[sp & m], AC_UNIT))
++ break;
+ }
++ else if (ex != null && (c & ADD_WORKER) != 0L) {
++ tryAddWorker(c); // create replacement
++ break;
++ }
++ else // don't need replacement
++ break;
+ }
+-
+- long c; // adjust ctl counts
+- do {} while (!U.compareAndSwapLong
+- (this, CTL, c = ctl, (((c - AC_UNIT) & AC_MASK) |
+- ((c - TC_UNIT) & TC_MASK) |
+- (c & ~(AC_MASK|TC_MASK)))));
+-
+- if (!tryTerminate(false, false) && w != null && w.array != null) {
+- w.cancelAll(); // cancel remaining tasks
+- WorkQueue[] ws; WorkQueue v; Thread p; int u, i, e;
+- while ((u = (int)((c = ctl) >>> 32)) < 0 && (e = (int)c) >= 0) {
+- if (e > 0) { // activate or create replacement
+- if ((ws = workQueues) == null ||
+- (i = e & SMASK) >= ws.length ||
+- (v = ws[i]) == null)
+- break;
+- long nc = (((long)(v.nextWait & E_MASK)) |
+- ((long)(u + UAC_UNIT) << 32));
+- if (v.eventCount != (e | INT_SIGN))
+- break;
+- if (U.compareAndSwapLong(this, CTL, c, nc)) {
+- v.eventCount = (e + E_SEQ) & E_MASK;
+- if ((p = v.parker) != null)
+- U.unpark(p);
+- break;
+- }
+- }
+- else {
+- if ((short)u < 0)
+- tryAddWorker();
+- break;
+- }
+- }
+- }
+- if (ex == null) // help clean refs on way out
++ if (ex == null) // help clean on way out
+ ForkJoinTask.helpExpungeStaleExceptions();
+- else // rethrow
++ else // rethrow
+ ForkJoinTask.rethrow(ex);
+ }
+
+- // Submissions
+-
+- /**
+- * Unless shutting down, adds the given task to a submission queue
+- * at submitter's current queue index (modulo submission
+- * range). Only the most common path is directly handled in this
+- * method. All others are relayed to fullExternalPush.
+- *
+- * @param task the task. Caller must ensure non-null.
+- */
+- final void externalPush(ForkJoinTask<?> task) {
+- WorkQueue q; int m, s, n, am; ForkJoinTask<?>[] a;
+- int r = ThreadLocalRandom.getProbe();
+- int ps = plock;
+- WorkQueue[] ws = workQueues;
+- if (ps > 0 && ws != null && (m = (ws.length - 1)) >= 0 &&
+- (q = ws[m & r & SQMASK]) != null && r != 0 &&
+- U.compareAndSwapInt(q, QLOCK, 0, 1)) { // lock
+- if ((a = q.array) != null &&
+- (am = a.length - 1) > (n = (s = q.top) - q.base)) {
+- int j = ((am & s) << ASHIFT) + ABASE;
+- U.putOrderedObject(a, j, task);
+- q.top = s + 1; // push on to deque
+- q.qlock = 0;
+- if (n <= 1)
+- signalWork(ws, q);
+- return;
+- }
+- q.qlock = 0;
+- }
+- fullExternalPush(task);
+- }
+-
+- /**
+- * Full version of externalPush. This method is called, among
+- * other times, upon the first submission of the first task to the
+- * pool, so must perform secondary initialization. It also
+- * detects first submission by an external thread by looking up
+- * its ThreadLocal, and creates a new shared queue if the one at
+- * index if empty or contended. The plock lock body must be
+- * exception-free (so no try/finally) so we optimistically
+- * allocate new queues outside the lock and throw them away if
+- * (very rarely) not needed.
+- *
+- * Secondary initialization occurs when plock is zero, to create
+- * workQueue array and set plock to a valid value. This lock body
+- * must also be exception-free. Because the plock seq value can
+- * eventually wrap around zero, this method harmlessly fails to
+- * reinitialize if workQueues exists, while still advancing plock.
+- */
+- private void fullExternalPush(ForkJoinTask<?> task) {
+- int r;
+- if ((r = ThreadLocalRandom.getProbe()) == 0) {
+- ThreadLocalRandom.localInit();
+- r = ThreadLocalRandom.getProbe();
+- }
+- for (;;) {
+- WorkQueue[] ws; WorkQueue q; int ps, m, k;
+- boolean move = false;
+- if ((ps = plock) < 0)
+- throw new RejectedExecutionException();
+- else if (ps == 0 || (ws = workQueues) == null ||
+- (m = ws.length - 1) < 0) { // initialize workQueues
+- int p = parallelism; // find power of two table size
+- int n = (p > 1) ? p - 1 : 1; // ensure at least 2 slots
+- n |= n >>> 1; n |= n >>> 2; n |= n >>> 4;
+- n |= n >>> 8; n |= n >>> 16; n = (n + 1) << 1;
+- WorkQueue[] nws = ((ws = workQueues) == null || ws.length == 0 ?
+- new WorkQueue[n] : null);
+- if (((ps = plock) & PL_LOCK) != 0 ||
+- !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
+- ps = acquirePlock();
+- if (((ws = workQueues) == null || ws.length == 0) && nws != null)
+- workQueues = nws;
+- int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
+- if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
+- releasePlock(nps);
+- }
+- else if ((q = ws[k = r & m & SQMASK]) != null) {
+- if (q.qlock == 0 && U.compareAndSwapInt(q, QLOCK, 0, 1)) {
+- ForkJoinTask<?>[] a = q.array;
+- int s = q.top;
+- boolean submitted = false;
+- try { // locked version of push
+- if ((a != null && a.length > s + 1 - q.base) ||
+- (a = q.growArray()) != null) { // must presize
+- int j = (((a.length - 1) & s) << ASHIFT) + ABASE;
+- U.putOrderedObject(a, j, task);
+- q.top = s + 1;
+- submitted = true;
+- }
+- } finally {
+- q.qlock = 0; // unlock
+- }
+- if (submitted) {
+- signalWork(ws, q);
+- return;
+- }
+- }
+- move = true; // move on failure
+- }
+- else if (((ps = plock) & PL_LOCK) == 0) { // create new queue
+- q = new WorkQueue(this, null, SHARED_QUEUE, r);
+- q.poolIndex = (short)k;
+- if (((ps = plock) & PL_LOCK) != 0 ||
+- !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
+- ps = acquirePlock();
+- if ((ws = workQueues) != null && k < ws.length && ws[k] == null)
+- ws[k] = q;
+- int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
+- if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
+- releasePlock(nps);
+- }
+- else
+- move = true; // move if busy
+- if (move)
+- r = ThreadLocalRandom.advanceProbe(r);
+- }
+- }
+-
+- // Maintaining ctl counts
+-
+- /**
+- * Increments active count; mainly called upon return from blocking.
+- */
+- final void incrementActiveCount() {
+- long c;
+- do {} while (!U.compareAndSwapLong
+- (this, CTL, c = ctl, ((c & ~AC_MASK) |
+- ((c & AC_MASK) + AC_UNIT))));
+- }
++ // Signalling
+
+ /**
+ * Tries to create or activate a worker if too few are active.
+ *
+ * @param ws the worker array to use to find signallees
+- * @param q if non-null, the queue holding tasks to be processed
++ * @param q a WorkQueue --if non-null, don't retry if now empty
+ */
+ final void signalWork(WorkQueue[] ws, WorkQueue q) {
+- for (;;) {
+- long c; int e, u, i; WorkQueue w; Thread p;
+- if ((u = (int)((c = ctl) >>> 32)) >= 0)
+- break;
+- if ((e = (int)c) <= 0) {
+- if ((short)u < 0)
+- tryAddWorker();
++ long c; int sp, i; WorkQueue v; Thread p;
++ while ((c = ctl) < 0L) { // too few active
++ if ((sp = (int)c) == 0) { // no idle workers
++ if ((c & ADD_WORKER) != 0L) // too few workers
++ tryAddWorker(c);
+ break;
+ }
+- if (ws == null || ws.length <= (i = e & SMASK) ||
+- (w = ws[i]) == null)
++ if (ws == null) // unstarted/terminated
+ break;
+- long nc = (((long)(w.nextWait & E_MASK)) |
+- ((long)(u + UAC_UNIT)) << 32);
+- int ne = (e + E_SEQ) & E_MASK;
+- if (w.eventCount == (e | INT_SIGN) &&
+- U.compareAndSwapLong(this, CTL, c, nc)) {
+- w.eventCount = ne;
+- if ((p = w.parker) != null)
++ if (ws.length <= (i = sp & SMASK)) // terminated
++ break;
++ if ((v = ws[i]) == null) // terminating
++ break;
++ int vs = (sp + SS_SEQ) & ~INACTIVE; // next scanState
++ int d = sp - v.scanState; // screen CAS
++ long nc = (UC_MASK & (c + AC_UNIT)) | (SP_MASK & v.stackPred);
++ if (d == 0 && U.compareAndSwapLong(this, CTL, c, nc)) {
++ v.scanState = vs; // activate v
++ if ((p = v.parker) != null)
+ U.unpark(p);
+ break;
+ }
+- if (q != null && q.base >= q.top)
++ if (q != null && q.base == q.top) // no more work
+ break;
+ }
+ }
+
++ /**
++ * Signals and releases worker v if it is top of idle worker
++ * stack. This performs a one-shot version of signalWork only if
++ * there is (apparently) at least one idle worker.
++ *
++ * @param c incoming ctl value
++ * @param v if non-null, a worker
++ * @param inc the increment to active count (zero when compensating)
++ * @return true if successful
++ */
++ private boolean tryRelease(long c, WorkQueue v, long inc) {
++ int sp = (int)c, vs = (sp + SS_SEQ) & ~INACTIVE; Thread p;
++ if (v != null && v.scanState == sp) { // v is at top of stack
++ long nc = (UC_MASK & (c + inc)) | (SP_MASK & v.stackPred);
++ if (U.compareAndSwapLong(this, CTL, c, nc)) {
++ v.scanState = vs;
++ if ((p = v.parker) != null)
++ U.unpark(p);
++ return true;
++ }
++ }
++ return false;
++ }
++
+ // Scanning for tasks
+
+ /**
+ * Top-level runloop for workers, called by ForkJoinWorkerThread.run.
+ */
+ final void runWorker(WorkQueue w) {
+- w.growArray(); // allocate queue
+- for (int r = w.hint; scan(w, r) == 0; ) {
++ w.growArray(); // allocate queue
++ int seed = w.hint; // initially holds randomization hint
++ int r = (seed == 0) ? 1 : seed; // avoid 0 for xorShift
++ for (ForkJoinTask<?> t;;) {
++ if ((t = scan(w, r)) != null)
++ w.runTask(t);
++ else if (!awaitWork(w, r))
++ break;
+ r ^= r << 13; r ^= r >>> 17; r ^= r << 5; // xorshift
+ }
+ }
+
+ /**
+- * Scans for and, if found, runs one task, else possibly
+- * inactivates the worker. This method operates on single reads of
+- * volatile state and is designed to be re-invoked continuously,
+- * in part because it returns upon detecting inconsistencies,
+- * contention, or state changes that indicate possible success on
+- * re-invocation.
+- *
+- * The scan searches for tasks across queues starting at a random
+- * index, checking each at least twice. The scan terminates upon
+- * either finding a non-empty queue, or completing the sweep. If
+- * the worker is not inactivated, it takes and runs a task from
+- * this queue. Otherwise, if not activated, it tries to activate
+- * itself or some other worker by signalling. On failure to find a
+- * task, returns (for retry) if pool state may have changed during
+- * an empty scan, or tries to inactivate if active, else possibly
+- * blocks or terminates via method awaitWork.
++ * Scans for and tries to steal a top-level task. Scans start at a
++ * random location, randomly moving on apparent contention,
++ * otherwise continuing linearly until reaching two consecutive
++ * empty passes over all queues with the same checksum (summing
++ * each base index of each queue, that moves on each steal), at
++ * which point the worker tries to inactivate and then re-scans,
++ * attempting to re-activate (itself or some other worker) if
++ * finding a task; otherwise returning null to await work. Scans
++ * otherwise touch as little memory as possible, to reduce
++ * disruption on other scanning threads.
+ *
+ * @param w the worker (via its WorkQueue)
+ * @param r a random seed
+- * @return worker qlock status if would have waited, else 0
++ * @return a task, or null if none found
+ */
+- private final int scan(WorkQueue w, int r) {
++ private ForkJoinTask<?> scan(WorkQueue w, int r) {
+ WorkQueue[] ws; int m;
+- long c = ctl; // for consistency check
+- if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 && w != null) {
+- for (int j = m + m + 1, ec = w.eventCount;;) {
+- WorkQueue q; int b, e; ForkJoinTask<?>[] a; ForkJoinTask<?> t;
+- if ((q = ws[(r - j) & m]) != null &&
+- (b = q.base) - q.top < 0 && (a = q.array) != null) {
+- long i = (((a.length - 1) & b) << ASHIFT) + ABASE;
+- if ((t = ((ForkJoinTask<?>)
+- U.getObjectVolatile(a, i))) != null) {
+- if (ec < 0)
+- helpRelease(c, ws, w, q, b);
+- else if (q.base == b &&
+- U.compareAndSwapObject(a, i, t, null)) {
+- U.putOrderedInt(q, QBASE, b + 1);
+- if ((b + 1) - q.top < 0)
+- signalWork(ws, q);
+- w.runTask(t);
++ if ((ws = workQueues) != null && (m = ws.length - 1) > 0 && w != null) {
++ int ss = w.scanState; // initially non-negative
++ for (int origin = r & m, k = origin, oldSum = 0, checkSum = 0;;) {
++ WorkQueue q; ForkJoinTask<?>[] a; ForkJoinTask<?> t;
++ int b, n; long c;
++ if ((q = ws[k]) != null) {
++ if ((n = (b = q.base) - q.top) < 0 &&
++ (a = q.array) != null) { // non-empty
++ long i = (((a.length - 1) & b) << ASHIFT) + ABASE;
++ if ((t = ((ForkJoinTask<?>)
++ U.getObjectVolatile(a, i))) != null &&
++ q.base == b) {
++ if (ss >= 0) {
++ if (U.compareAndSwapObject(a, i, t, null)) {
++ q.base = b + 1;
++ if (n < -1) // signal others
++ signalWork(ws, q);
++ return t;
++ }
++ }
++ else if (oldSum == 0 && // try to activate
++ w.scanState < 0)
++ tryRelease(c = ctl, ws[m & (int)c], AC_UNIT);
+ }
++ if (ss < 0) // refresh
++ ss = w.scanState;
++ r ^= r << 1; r ^= r >>> 3; r ^= r << 10;
++ origin = k = r & m; // move and rescan
++ oldSum = checkSum = 0;
++ continue;
+ }
+- break;
++ checkSum += b;
+ }
+- else if (--j < 0) {
+- if ((ec | (e = (int)c)) < 0) // inactive or terminating
+- return awaitWork(w, c, ec);
+- else if (ctl == c) { // try to inactivate and enqueue
+- long nc = (long)ec | ((c - AC_UNIT) & (AC_MASK|TC_MASK));
+- w.nextWait = e;
+- w.eventCount = ec | INT_SIGN;
+- if (!U.compareAndSwapLong(this, CTL, c, nc))
+- w.eventCount = ec; // back out
++ if ((k = (k + 1) & m) == origin) { // continue until stable
++ if ((ss >= 0 || (ss == (ss = w.scanState))) &&
++ oldSum == (oldSum = checkSum)) {
++ if (ss < 0 || w.qlock < 0) // already inactive
++ break;
++ int ns = ss | INACTIVE; // try to inactivate
++ long nc = ((SP_MASK & ns) |
++ (UC_MASK & ((c = ctl) - AC_UNIT)));
++ w.stackPred = (int)c; // hold prev stack top
++ U.putInt(w, QSCANSTATE, ns);
++ if (U.compareAndSwapLong(this, CTL, c, nc))
++ ss = ns;
++ else
++ w.scanState = ss; // back out
+ }
+- break;
++ checkSum = 0;
+ }
+ }
+ }
+- return 0;
++ return null;
+ }
+
+ /**
+- * A continuation of scan(), possibly blocking or terminating
+- * worker w. Returns without blocking if pool state has apparently
+- * changed since last invocation. Also, if inactivating w has
+- * caused the pool to become quiescent, checks for pool
++ * Possibly blocks worker w waiting for a task to steal, or
++ * returns false if the worker should terminate. If inactivating
++ * w has caused the pool to become quiescent, checks for pool
+ * termination, and, so long as this is not the only worker, waits
+- * for event for up to a given duration. On timeout, if ctl has
+- * not changed, terminates the worker, which will in turn wake up
++ * for up to a given duration. On timeout, if ctl has not
++ * changed, terminates the worker, which will in turn wake up
+ * another worker to possibly repeat this process.
+ *
+ * @param w the calling worker
+- * @param c the ctl value on entry to scan
+- * @param ec the worker's eventCount on entry to scan
++ * @param r a random seed (for spins)
++ * @return false if the worker should terminate
+ */
+- private final int awaitWork(WorkQueue w, long c, int ec) {
+- int stat, ns; long parkTime, deadline;
+- if ((stat = w.qlock) >= 0 && w.eventCount == ec && ctl == c &&
+- !Thread.interrupted()) {
+- int e = (int)c;
+- int u = (int)(c >>> 32);
+- int d = (u >> UAC_SHIFT) + parallelism; // active count
+-
+- if (e < 0 || (d <= 0 && tryTerminate(false, false)))
+- stat = w.qlock = -1; // pool is terminating
+- else if ((ns = w.nsteals) != 0) { // collect steals and retry
+- w.nsteals = 0;
+- U.getAndAddLong(this, STEALCOUNT, (long)ns);
++ private boolean awaitWork(WorkQueue w, int r) {
++ if (w == null || w.qlock < 0) // w is terminating
++ return false;
++ for (int pred = w.stackPred, spins = SPINS, ss;;) {
++ if ((ss = w.scanState) >= 0)
++ break;
++ else if (spins > 0) {
++ r ^= r << 6; r ^= r >>> 21; r ^= r << 7;
++ if (r >= 0 && --spins == 0) { // randomize spins
++ WorkQueue v; WorkQueue[] ws; int s, j; AtomicLong sc;
++ if (pred != 0 && (ws = workQueues) != null &&
++ (j = pred & SMASK) < ws.length &&
++ (v = ws[j]) != null && // see if pred parking
++ (v.parker == null || v.scanState >= 0))
++ spins = SPINS; // continue spinning
++ }
+ }
+- else {
+- long pc = ((d > 0 || ec != (e | INT_SIGN)) ? 0L :
+- ((long)(w.nextWait & E_MASK)) | // ctl to restore
+- ((long)(u + UAC_UNIT)) << 32);
+- if (pc != 0L) { // timed wait if last waiter
+- int dc = -(short)(c >>> TC_SHIFT);
+- parkTime = (dc < 0 ? FAST_IDLE_TIMEOUT:
+- (dc + 1) * IDLE_TIMEOUT);
++ else if (w.qlock < 0) // recheck after spins
++ return false;
++ else if (!Thread.interrupted()) {
++ long c, prevctl, parkTime, deadline;
++ int ac = (int)((c = ctl) >> AC_SHIFT) + (config & SMASK);
++ if ((ac <= 0 && tryTerminate(false, false)) ||
++ (runState & STOP) != 0) // pool terminating
++ return false;
++ if (ac <= 0 && ss == (int)c) { // is last waiter
++ prevctl = (UC_MASK & (c + AC_UNIT)) | (SP_MASK & pred);
++ int t = (short)(c >>> TC_SHIFT); // shrink excess spares
++ if (t > 2 && U.compareAndSwapLong(this, CTL, c, prevctl))
++ return false; // else use timed wait
++ parkTime = IDLE_TIMEOUT * ((t >= 0) ? 1 : 1 - t);
+ deadline = System.nanoTime() + parkTime - TIMEOUT_SLOP;
+ }
+ else
+- parkTime = deadline = 0L;
+- if (w.eventCount == ec && ctl == c) {
+- Thread wt = Thread.currentThread();
+- U.putObject(wt, PARKBLOCKER, this);
+- w.parker = wt; // emulate LockSupport.park
+- if (w.eventCount == ec && ctl == c)
+- U.park(false, parkTime); // must recheck before park
+- w.parker = null;
+- U.putObject(wt, PARKBLOCKER, null);
+- if (parkTime != 0L && ctl == c &&
+- deadline - System.nanoTime() <= 0L &&
+- U.compareAndSwapLong(this, CTL, c, pc))
+- stat = w.qlock = -1; // shrink pool
++ prevctl = parkTime = deadline = 0L;
++ Thread wt = Thread.currentThread();
++ U.putObject(wt, PARKBLOCKER, this); // emulate LockSupport
++ w.parker = wt;
++ if (w.scanState < 0 && ctl == c) // recheck before park
++ U.park(false, parkTime);
++ U.putOrderedObject(w, QPARKER, null);
++ U.putObject(wt, PARKBLOCKER, null);
++ if (w.scanState >= 0)
++ break;
++ if (parkTime != 0L && ctl == c &&
++ deadline - System.nanoTime() <= 0L &&
++ U.compareAndSwapLong(this, CTL, c, prevctl))
++ return false; // shrink pool
++ }
++ }
++ return true;
++ }
++
++ // Joining tasks
++
++ /**
++ * Tries to steal and run tasks within the target's computation.
++ * Uses a variant of the top-level algorithm, restricted to tasks
++ * with the given task as ancestor: It prefers taking and running
++ * eligible tasks popped from the worker's own queue (via
++ * popCC). Otherwise it scans others, randomly moving on
++ * contention or execution, deciding to give up based on a
++ * checksum (via return codes frob pollAndExecCC). The maxTasks
++ * argument supports external usages; internal calls use zero,
++ * allowing unbounded steps (external calls trap non-positive
++ * values).
++ *
++ * @param w caller
++ * @param maxTasks if non-zero, the maximum number of other tasks to run
++ * @return task status on exit
++ */
++ final int helpComplete(WorkQueue w, CountedCompleter<?> task,
++ int maxTasks) {
++ WorkQueue[] ws; int s = 0, m;
++ if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 &&
++ task != null && w != null) {
++ int mode = w.config; // for popCC
++ int r = w.hint ^ w.top; // arbitrary seed for origin
++ int origin = r & m; // first queue to scan
++ int h = 1; // 1:ran, >1:contended, <0:hash
++ for (int k = origin, oldSum = 0, checkSum = 0;;) {
++ CountedCompleter<?> p; WorkQueue q;
++ if ((s = task.status) < 0)
++ break;
++ if (h == 1 && (p = w.popCC(task, mode)) != null) {
++ p.doExec(); // run local task
++ if (maxTasks != 0 && --maxTasks == 0)
++ break;
++ origin = k; // reset
++ oldSum = checkSum = 0;
++ }
++ else { // poll other queues
++ if ((q = ws[k]) == null)
++ h = 0;
++ else if ((h = q.pollAndExecCC(task)) < 0)
++ checkSum += h;
++ if (h > 0) {
++ if (h == 1 && maxTasks != 0 && --maxTasks == 0)
++ break;
++ r ^= r << 13; r ^= r >>> 17; r ^= r << 5; // xorshift
++ origin = k = r & m; // move and restart
++ oldSum = checkSum = 0;
++ }
++ else if ((k = (k + 1) & m) == origin) {
++ if (oldSum == (oldSum = checkSum))
++ break;
++ checkSum = 0;
++ }
+ }
+ }
+ }
+- return stat;
+- }
+-
+- /**
+- * Possibly releases (signals) a worker. Called only from scan()
+- * when a worker with apparently inactive status finds a non-empty
+- * queue. This requires revalidating all of the associated state
+- * from caller.
+- */
+- private final void helpRelease(long c, WorkQueue[] ws, WorkQueue w,
+- WorkQueue q, int b) {
+- WorkQueue v; int e, i; Thread p;
+- if (w != null && w.eventCount < 0 && (e = (int)c) > 0 &&
+- ws != null && ws.length > (i = e & SMASK) &&
+- (v = ws[i]) != null && ctl == c) {
+- long nc = (((long)(v.nextWait & E_MASK)) |
+- ((long)((int)(c >>> 32) + UAC_UNIT)) << 32);
+- int ne = (e + E_SEQ) & E_MASK;
+- if (q != null && q.base == b && w.eventCount < 0 &&
+- v.eventCount == (e | INT_SIGN) &&
+- U.compareAndSwapLong(this, CTL, c, nc)) {
+- v.eventCount = ne;
+- if ((p = v.parker) != null)
+- U.unpark(p);
+- }
+- }
++ return s;
+ }
+
+ /**
+@@ -1799,268 +1901,167 @@
+ * execute tasks from. The first call to this method upon a
+ * waiting join will often entail scanning/search, (which is OK
+ * because the joiner has nothing better to do), but this method
+- * leaves hints in workers to speed up subsequent calls. The
+- * implementation is very branchy to cope with potential
+- * inconsistencies or loops encountering chains that are stale,
+- * unknown, or so long that they are likely cyclic.
++ * leaves hints in workers to speed up subsequent calls.
+ *
+- * @param joiner the joining worker
++ * @param w caller
+ * @param task the task to join
+- * @return 0 if no progress can be made, negative if task
+- * known complete, else positive
+ */
+- private int tryHelpStealer(WorkQueue joiner, ForkJoinTask<?> task) {
+- int stat = 0, steps = 0; // bound to avoid cycles
+- if (task != null && joiner != null &&
+- joiner.base - joiner.top >= 0) { // hoist checks
+- restart: for (;;) {
+- ForkJoinTask<?> subtask = task; // current target
+- for (WorkQueue j = joiner, v;;) { // v is stealer of subtask
+- WorkQueue[] ws; int m, s, h;
+- if ((s = task.status) < 0) {
+- stat = s;
+- break restart;
+- }
+- if ((ws = workQueues) == null || (m = ws.length - 1) <= 0)
+- break restart; // shutting down
+- if ((v = ws[h = (j.hint | 1) & m]) == null ||
+- v.currentSteal != subtask) {
+- for (int origin = h;;) { // find stealer
+- if (((h = (h + 2) & m) & 15) == 1 &&
+- (subtask.status < 0 || j.currentJoin != subtask))
+- continue restart; // occasional staleness check
+- if ((v = ws[h]) != null &&
+- v.currentSteal == subtask) {
+- j.hint = h; // save hint
++ private void helpStealer(WorkQueue w, ForkJoinTask<?> task) {
++ WorkQueue[] ws = workQueues;
++ int oldSum = 0, checkSum, m;
++ if (ws != null && (m = ws.length - 1) >= 0 && w != null &&
++ task != null) {
++ do { // restart point
++ checkSum = 0; // for stability check
++ ForkJoinTask<?> subtask;
++ WorkQueue j = w, v; // v is subtask stealer
++ descent: for (subtask = task; subtask.status >= 0; ) {
++ for (int h = j.hint | 1, k = 0, i; ; k += 2) {
++ if (k > m) // can't find stealer
++ break descent;
++ if ((v = ws[i = (h + k) & m]) != null) {
++ if (v.currentSteal == subtask) {
++ j.hint = i;
+ break;
+ }
+- if (h == origin)
+- break restart; // cannot find stealer
++ checkSum += v.base;
+ }
+ }
+- for (;;) { // help stealer or descend to its stealer
++ for (;;) { // help v or descend
+ ForkJoinTask<?>[] a; int b;
+- if (subtask.status < 0) // surround probes with
+- continue restart; // consistency checks
+- if ((b = v.base) - v.top < 0 && (a = v.array) != null) {
+- int i = (((a.length - 1) & b) << ASHIFT) + ABASE;
+- ForkJoinTask<?> t =
+- (ForkJoinTask<?>)U.getObjectVolatile(a, i);
+- if (subtask.status < 0 || j.currentJoin != subtask ||
+- v.currentSteal != subtask)
+- continue restart; // stale
+- stat = 1; // apparent progress
+- if (v.base == b) {
+- if (t == null)
+- break restart;
+- if (U.compareAndSwapObject(a, i, t, null)) {
+- U.putOrderedInt(v, QBASE, b + 1);
+- ForkJoinTask<?> ps = joiner.currentSteal;
+- int jt = joiner.top;
+- do {
+- joiner.currentSteal = t;
+- t.doExec(); // clear local tasks too
+- } while (task.status >= 0 &&
+- joiner.top != jt &&
+- (t = joiner.pop()) != null);
+- joiner.currentSteal = ps;
+- break restart;
+- }
+- }
++ checkSum += (b = v.base);
++ ForkJoinTask<?> next = v.currentJoin;
++ if (subtask.status < 0 || j.currentJoin != subtask ||
++ v.currentSteal != subtask) // stale
++ break descent;
++ if (b - v.top >= 0 || (a = v.array) == null) {
++ if ((subtask = next) == null)
++ break descent;
++ j = v;
++ break;
+ }
+- else { // empty -- try to descend
+- ForkJoinTask<?> next = v.currentJoin;
+- if (subtask.status < 0 || j.currentJoin != subtask ||
+- v.currentSteal != subtask)
+- continue restart; // stale
+- else if (next == null || ++steps == MAX_HELP)
+- break restart; // dead-end or maybe cyclic
+- else {
+- subtask = next;
+- j = v;
+- break;
++ int i = (((a.length - 1) & b) << ASHIFT) + ABASE;
++ ForkJoinTask<?> t = ((ForkJoinTask<?>)
++ U.getObjectVolatile(a, i));
++ if (v.base == b) {
++ if (t == null) // stale
++ break descent;
++ if (U.compareAndSwapObject(a, i, t, null)) {
++ v.base = b + 1;
++ ForkJoinTask<?> ps = w.currentSteal;
++ int top = w.top;
++ do {
++ U.putOrderedObject(w, QCURRENTSTEAL, t);
++ t.doExec(); // clear local tasks too
++ } while (task.status >= 0 &&
++ w.top != top &&
++ (t = w.pop()) != null);
++ U.putOrderedObject(w, QCURRENTSTEAL, ps);
++ if (w.base != w.top)
++ return; // can't further help
+ }
+ }
+ }
+ }
+- }
++ } while (task.status >= 0 && oldSum != (oldSum = checkSum));
+ }
+- return stat;
+- }
+-
+- /**
+- * Analog of tryHelpStealer for CountedCompleters. Tries to steal
+- * and run tasks within the target's computation.
+- *
+- * @param task the task to join
+- * @param maxTasks the maximum number of other tasks to run
+- */
+- final int helpComplete(WorkQueue joiner, CountedCompleter<?> task,
+- int maxTasks) {
+- WorkQueue[] ws; int m;
+- int s = 0;
+- if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 &&
+- joiner != null && task != null) {
+- int j = joiner.poolIndex;
+- int scans = m + m + 1;
+- long c = 0L; // for stability check
+- for (int k = scans; ; j += 2) {
+- WorkQueue q;
+- if ((s = task.status) < 0)
+- break;
+- else if (joiner.internalPopAndExecCC(task)) {
+- if (--maxTasks <= 0) {
+- s = task.status;
+- break;
+- }
+- k = scans;
+- }
+- else if ((s = task.status) < 0)
+- break;
+- else if ((q = ws[j & m]) != null && q.pollAndExecCC(task)) {
+- if (--maxTasks <= 0) {
+- s = task.status;
+- break;
+- }
+- k = scans;
+- }
+- else if (--k < 0) {
+- if (c == (c = ctl))
+- break;
+- k = scans;
+- }
+- }
+- }
+- return s;
+ }
+
+ /**
+ * Tries to decrement active count (sometimes implicitly) and
+ * possibly release or create a compensating worker in preparation
+- * for blocking. Fails on contention or termination. Otherwise,
+- * adds a new thread if no idle workers are available and pool
+- * may become starved.
++ * for blocking. Returns false (retryable by caller), on
++ * contention, detected staleness, instability, or termination.
+ *
+- * @param c the assumed ctl value
++ * @param w caller
+ */
+- final boolean tryCompensate(long c) {
+- WorkQueue[] ws = workQueues;
+- int pc = parallelism, e = (int)c, m, tc;
+- if (ws != null && (m = ws.length - 1) >= 0 && e >= 0 && ctl == c) {
+- WorkQueue w = ws[e & m];
+- if (e != 0 && w != null) {
+- Thread p;
+- long nc = ((long)(w.nextWait & E_MASK) |
+- (c & (AC_MASK|TC_MASK)));
+- int ne = (e + E_SEQ) & E_MASK;
+- if (w.eventCount == (e | INT_SIGN) &&
+- U.compareAndSwapLong(this, CTL, c, nc)) {
+- w.eventCount = ne;
+- if ((p = w.parker) != null)
+- U.unpark(p);
+- return true; // replace with idle worker
++ private boolean tryCompensate(WorkQueue w) {
++ boolean canBlock;
++ WorkQueue[] ws; long c; int m, pc, sp;
++ if (w == null || w.qlock < 0 || // caller terminating
++ (ws = workQueues) == null || (m = ws.length - 1) <= 0 ||
++ (pc = config & SMASK) == 0) // parallelism disabled
++ canBlock = false;
++ else if ((sp = (int)(c = ctl)) != 0) // release idle worker
++ canBlock = tryRelease(c, ws[sp & m], 0L);
++ else {
++ int ac = (int)(c >> AC_SHIFT) + pc;
++ int tc = (short)(c >> TC_SHIFT) + pc;
++ int nbusy = 0; // validate saturation
++ for (int i = 0; i <= m; ++i) { // two passes of odd indices
++ WorkQueue v;
++ if ((v = ws[((i << 1) | 1) & m]) != null) {
++ if ((v.scanState & SCANNING) != 0)
++ break;
++ ++nbusy;
+ }
+ }
+- else if ((tc = (short)(c >>> TC_SHIFT)) >= 0 &&
+- (int)(c >> AC_SHIFT) + pc > 1) {
+- long nc = ((c - AC_UNIT) & AC_MASK) | (c & ~AC_MASK);
+- if (U.compareAndSwapLong(this, CTL, c, nc))
+- return true; // no compensation
++ if (nbusy != (tc << 1) || ctl != c)
++ canBlock = false; // unstable or stale
++ else if (tc >= pc && ac > 1 && w.isEmpty()) {
++ long nc = ((AC_MASK & (c - AC_UNIT)) |
++ (~AC_MASK & c)); // uncompensated
++ canBlock = U.compareAndSwapLong(this, CTL, c, nc);
+ }
+- else if (tc + pc < MAX_CAP) {
+- long nc = ((c + TC_UNIT) & TC_MASK) | (c & ~TC_MASK);
+- if (U.compareAndSwapLong(this, CTL, c, nc)) {
+- ForkJoinWorkerThreadFactory fac;
+- Throwable ex = null;
+- ForkJoinWorkerThread wt = null;
+- try {
+- if ((fac = factory) != null &&
+- (wt = fac.newThread(this)) != null) {
+- wt.start();
+- return true;
+- }
+- } catch (Throwable rex) {
+- ex = rex;
+- }
+- deregisterWorker(wt, ex); // clean up and return false
+- }
++ else if (tc >= MAX_CAP ||
++ (this == common && tc >= pc + commonMaxSpares))
++ throw new RejectedExecutionException(
++ "Thread limit exceeded replacing blocked worker");
++ else { // similar to tryAddWorker
++ boolean add = false; int rs; // CAS within lock
++ long nc = ((AC_MASK & c) |
++ (TC_MASK & (c + TC_UNIT)));
++ if (((rs = lockRunState()) & STOP) == 0)
++ add = U.compareAndSwapLong(this, CTL, c, nc);
++ unlockRunState(rs, rs & ~RSLOCK);
++ canBlock = add && createWorker(); // throws on exception
+ }
+ }
+- return false;
++ return canBlock;
+ }
+
+ /**
+- * Helps and/or blocks until the given task is done.
++ * Helps and/or blocks until the given task is done or timeout.
+ *
+- * @param joiner the joining worker
++ * @param w caller
+ * @param task the task
++ * @param deadline for timed waits, if nonzero
+ * @return task status on exit
+ */
+- final int awaitJoin(WorkQueue joiner, ForkJoinTask<?> task) {
++ final int awaitJoin(WorkQueue w, ForkJoinTask<?> task, long deadline) {
+ int s = 0;
+- if (task != null && (s = task.status) >= 0 && joiner != null) {
+- ForkJoinTask<?> prevJoin = joiner.currentJoin;
+- joiner.currentJoin = task;
+- do {} while (joiner.tryRemoveAndExec(task) && // process local tasks
+- (s = task.status) >= 0);
+- if (s >= 0 && (task instanceof CountedCompleter))
+- s = helpComplete(joiner, (CountedCompleter<?>)task, Integer.MAX_VALUE);
+- long cc = 0; // for stability checks
+- while (s >= 0 && (s = task.status) >= 0) {
+- if ((s = tryHelpStealer(joiner, task)) == 0 &&
+- (s = task.status) >= 0) {
+- if (!tryCompensate(cc))
+- cc = ctl;
+- else {
+- if (task.trySetSignal() && (s = task.status) >= 0) {
+- synchronized (task) {
+- if (task.status >= 0) {
+- try { // see ForkJoinTask
+- task.wait(); // for explanation
+- } catch (InterruptedException ie) {
+- }
+- }
+- else
+- task.notifyAll();
+- }
+- }
+- long c; // reactivate
+- do {} while (!U.compareAndSwapLong
+- (this, CTL, c = ctl,
+- ((c & ~AC_MASK) |
+- ((c & AC_MASK) + AC_UNIT))));
+- }
++ if (task != null && w != null) {
++ ForkJoinTask<?> prevJoin = w.currentJoin;
++ U.putOrderedObject(w, QCURRENTJOIN, task);
++ CountedCompleter<?> cc = (task instanceof CountedCompleter) ?
++ (CountedCompleter<?>)task : null;
++ for (;;) {
++ if ((s = task.status) < 0)
++ break;
++ if (cc != null)
++ helpComplete(w, cc, 0);
++ else if (w.base == w.top || w.tryRemoveAndExec(task))
++ helpStealer(w, task);
++ if ((s = task.status) < 0)
++ break;
++ long ms, ns;
++ if (deadline == 0L)
++ ms = 0L;
++ else if ((ns = deadline - System.nanoTime()) <= 0L)
++ break;
++ else if ((ms = TimeUnit.NANOSECONDS.toMillis(ns)) <= 0L)
++ ms = 1L;
++ if (tryCompensate(w)) {
++ task.internalWait(ms);
++ U.getAndAddLong(this, CTL, AC_UNIT);
+ }
+ }
+- joiner.currentJoin = prevJoin;
++ U.putOrderedObject(w, QCURRENTJOIN, prevJoin);
+ }
+ return s;
+ }
+
+- /**
+- * Stripped-down variant of awaitJoin used by timed joins. Tries
+- * to help join only while there is continuous progress. (Caller
+- * will then enter a timed wait.)
+- *
+- * @param joiner the joining worker
+- * @param task the task
+- */
+- final void helpJoinOnce(WorkQueue joiner, ForkJoinTask<?> task) {
+- int s;
+- if (joiner != null && task != null && (s = task.status) >= 0) {
+- ForkJoinTask<?> prevJoin = joiner.currentJoin;
+- joiner.currentJoin = task;
+- do {} while (joiner.tryRemoveAndExec(task) && // process local tasks
+- (s = task.status) >= 0);
+- if (s >= 0) {
+- if (task instanceof CountedCompleter)
+- helpComplete(joiner, (CountedCompleter<?>)task, Integer.MAX_VALUE);
+- do {} while (task.status >= 0 &&
+- tryHelpStealer(joiner, task) > 0);
+- }
+- joiner.currentJoin = prevJoin;
+- }
+- }
++ // Specialized scanning
+
+ /**
+ * Returns a (probably) non-empty steal queue, if one is found
+@@ -2068,19 +2069,24 @@
+ * caller if, by the time it tries to use the queue, it is empty.
+ */
+ private WorkQueue findNonEmptyStealQueue() {
++ WorkQueue[] ws; int m; // one-shot version of scan loop
+ int r = ThreadLocalRandom.nextSecondarySeed();
+- for (;;) {
+- int ps = plock, m; WorkQueue[] ws; WorkQueue q;
+- if ((ws = workQueues) != null && (m = ws.length - 1) >= 0) {
+- for (int j = (m + 1) << 2; j >= 0; --j) {
+- if ((q = ws[(((r - j) << 1) | 1) & m]) != null &&
+- q.base - q.top < 0)
++ if ((ws = workQueues) != null && (m = ws.length - 1) >= 0) {
++ for (int origin = r & m, k = origin, oldSum = 0, checkSum = 0;;) {
++ WorkQueue q; int b;
++ if ((q = ws[k]) != null) {
++ if ((b = q.base) - q.top < 0)
+ return q;
++ checkSum += b;
++ }
++ if ((k = (k + 1) & m) == origin) {
++ if (oldSum == (oldSum = checkSum))
++ break;
++ checkSum = 0;
+ }
+ }
+- if (plock == ps)
+- return null;
+ }
++ return null;
+ }
+
+ /**
+@@ -2090,35 +2096,34 @@
+ * find tasks either.
+ */
+ final void helpQuiescePool(WorkQueue w) {
+- ForkJoinTask<?> ps = w.currentSteal;
++ ForkJoinTask<?> ps = w.currentSteal; // save context
+ for (boolean active = true;;) {
+ long c; WorkQueue q; ForkJoinTask<?> t; int b;
+- while ((t = w.nextLocalTask()) != null)
+- t.doExec();
++ w.execLocalTasks(); // run locals before each scan
+ if ((q = findNonEmptyStealQueue()) != null) {
+ if (!active) { // re-establish active count
+ active = true;
+- do {} while (!U.compareAndSwapLong
+- (this, CTL, c = ctl,
+- ((c & ~AC_MASK) |
+- ((c & AC_MASK) + AC_UNIT))));
++ U.getAndAddLong(this, CTL, AC_UNIT);
+ }
+- if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null)
+- w.runTask(t);
++ if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null) {
++ U.putOrderedObject(w, QCURRENTSTEAL, t);
++ t.doExec();
++ if (++w.nsteals < 0)
++ w.transferStealCount(this);
++ }
+ }
+ else if (active) { // decrement active count without queuing
+- long nc = ((c = ctl) & ~AC_MASK) | ((c & AC_MASK) - AC_UNIT);
+- if ((int)(nc >> AC_SHIFT) + parallelism == 0)
++ long nc = (AC_MASK & ((c = ctl) - AC_UNIT)) | (~AC_MASK & c);
++ if ((int)(nc >> AC_SHIFT) + (config & SMASK) <= 0)
+ break; // bypass decrement-then-increment
+ if (U.compareAndSwapLong(this, CTL, c, nc))
+ active = false;
+ }
+- else if ((int)((c = ctl) >> AC_SHIFT) + parallelism <= 0 &&
+- U.compareAndSwapLong
+- (this, CTL, c, ((c & ~AC_MASK) |
+- ((c & AC_MASK) + AC_UNIT))))
++ else if ((int)((c = ctl) >> AC_SHIFT) + (config & SMASK) <= 0 &&
++ U.compareAndSwapLong(this, CTL, c, c + AC_UNIT))
+ break;
+ }
++ U.putOrderedObject(w, QCURRENTSTEAL, ps);
+ }
+
+ /**
+@@ -2141,7 +2146,7 @@
+ /**
+ * Returns a cheap heuristic guide for task partitioning when
+ * programmers, frameworks, tools, or languages have little or no
+- * idea about task granularity. In essence by offering this
++ * idea about task granularity. In essence, by offering this
+ * method, we ask users only about tradeoffs in overhead vs
+ * expected throughput and its variance, rather than how finely to
+ * partition tasks.
+@@ -2179,15 +2184,12 @@
+ * many of these by further considering the number of "idle"
+ * threads, that are known to have zero queued tasks, so
+ * compensate by a factor of (#idle/#active) threads.
+- *
+- * Note: The approximation of #busy workers as #active workers is
+- * not very good under current signalling scheme, and should be
+- * improved.
+ */
+ static int getSurplusQueuedTaskCount() {
+ Thread t; ForkJoinWorkerThread wt; ForkJoinPool pool; WorkQueue q;
+ if (((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)) {
+- int p = (pool = (wt = (ForkJoinWorkerThread)t).pool).parallelism;
++ int p = (pool = (wt = (ForkJoinWorkerThread)t).pool).
++ config & SMASK;
+ int n = (q = wt.workQueue).top - q.base;
+ int a = (int)(pool.ctl >> AC_SHIFT) + p;
+ return n - (a > (p >>>= 1) ? 0 :
+@@ -2202,13 +2204,7 @@
+ // Termination
+
+ /**
+- * Possibly initiates and/or completes termination. The caller
+- * triggering termination runs three passes through workQueues:
+- * (0) Setting termination status, followed by wakeups of queued
+- * workers; (1) cancelling all tasks; (2) interrupting lagging
+- * threads (likely in external tasks, but possibly also blocked in
+- * joins). Each pass repeats previous steps because of potential
+- * lagging thread creation.
++ * Possibly initiates and/or completes termination.
+ *
+ * @param now if true, unconditionally terminate, else only
+ * if no work and no active workers
+@@ -2216,166 +2212,256 @@
+ * @return true if now terminating or terminated
+ */
+ private boolean tryTerminate(boolean now, boolean enable) {
+- int ps;
+- if (this == common) // cannot shut down
++ int rs;
++ if (this == common) // cannot shut down
+ return false;
+- if ((ps = plock) >= 0) { // enable by setting plock
++ if ((rs = runState) >= 0) {
+ if (!enable)
+ return false;
+- if ((ps & PL_LOCK) != 0 ||
+- !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
+- ps = acquirePlock();
+- int nps = ((ps + PL_LOCK) & ~SHUTDOWN) | SHUTDOWN;
+- if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
+- releasePlock(nps);
++ rs = lockRunState(); // enter SHUTDOWN phase
++ unlockRunState(rs, (rs & ~RSLOCK) | SHUTDOWN);
+ }
+- for (long c;;) {
+- if (((c = ctl) & STOP_BIT) != 0) { // already terminating
+- if ((short)(c >>> TC_SHIFT) + parallelism <= 0) {
+- synchronized (this) {
+- notifyAll(); // signal when 0 workers
++
++ if ((rs & STOP) == 0) {
++ if (!now) { // check quiescence
++ for (long oldSum = 0L;;) { // repeat until stable
++ WorkQueue[] ws; WorkQueue w; int m, b; long c;
++ long checkSum = ctl;
++ if ((int)(checkSum >> AC_SHIFT) + (config & SMASK) > 0)
++ return false; // still active workers
++ if ((ws = workQueues) == null || (m = ws.length - 1) <= 0)
++ break; // check queues
++ for (int i = 0; i <= m; ++i) {
++ if ((w = ws[i]) != null) {
++ if ((b = w.base) != w.top || w.scanState >= 0 ||
++ w.currentSteal != null) {
++ tryRelease(c = ctl, ws[m & (int)c], AC_UNIT);
++ return false; // arrange for recheck
++ }
++ checkSum += b;
++ if ((i & 1) == 0)
++ w.qlock = -1; // try to disable external
++ }
+ }
++ if (oldSum == (oldSum = checkSum))
++ break;
+ }
+- return true;
+ }
+- if (!now) { // check if idle & no tasks
+- WorkQueue[] ws; WorkQueue w;
+- if ((int)(c >> AC_SHIFT) + parallelism > 0)
+- return false;
+- if ((ws = workQueues) != null) {
+- for (int i = 0; i < ws.length; ++i) {
+- if ((w = ws[i]) != null &&
+- (!w.isEmpty() ||
+- ((i & 1) != 0 && w.eventCount >= 0))) {
+- signalWork(ws, w);
+- return false;
++ if ((runState & STOP) == 0) {
++ rs = lockRunState(); // enter STOP phase
++ unlockRunState(rs, (rs & ~RSLOCK) | STOP);
++ }
++ }
++
++ int pass = 0; // 3 passes to help terminate
++ for (long oldSum = 0L;;) { // or until done or stable
++ WorkQueue[] ws; WorkQueue w; ForkJoinWorkerThread wt; int m;
++ long checkSum = ctl;
++ if ((short)(checkSum >>> TC_SHIFT) + (config & SMASK) <= 0 ||
++ (ws = workQueues) == null || (m = ws.length - 1) <= 0) {
++ if ((runState & TERMINATED) == 0) {
++ rs = lockRunState(); // done
++ unlockRunState(rs, (rs & ~RSLOCK) | TERMINATED);
++ synchronized (this) { notifyAll(); } // for awaitTermination
++ }
++ break;
++ }
++ for (int i = 0; i <= m; ++i) {
++ if ((w = ws[i]) != null) {
++ checkSum += w.base;
++ w.qlock = -1; // try to disable
++ if (pass > 0) {
++ w.cancelAll(); // clear queue
++ if (pass > 1 && (wt = w.owner) != null) {
++ if (!wt.isInterrupted()) {
++ try { // unblock join
++ wt.interrupt();
++ } catch (Throwable ignore) {
++ }
++ }
++ if (w.scanState < 0)
++ U.unpark(wt); // wake up
+ }
+ }
+ }
+ }
+- if (U.compareAndSwapLong(this, CTL, c, c | STOP_BIT)) {
+- for (int pass = 0; pass < 3; ++pass) {
+- WorkQueue[] ws; WorkQueue w; Thread wt;
+- if ((ws = workQueues) != null) {
+- int n = ws.length;
+- for (int i = 0; i < n; ++i) {
+- if ((w = ws[i]) != null) {
+- w.qlock = -1;
+- if (pass > 0) {
+- w.cancelAll();
+- if (pass > 1 && (wt = w.owner) != null) {
+- if (!wt.isInterrupted()) {
+- try {
+- wt.interrupt();
+- } catch (Throwable ignore) {
+- }
+- }
+- U.unpark(wt);
+- }
+- }
+- }
++ if (checkSum != oldSum) { // unstable
++ oldSum = checkSum;
++ pass = 0;
++ }
++ else if (pass > 3 && pass > m) // can't further help
++ break;
++ else if (++pass > 1) { // try to dequeue
++ long c; int j = 0, sp; // bound attempts
++ while (j++ <= m && (sp = (int)(c = ctl)) != 0)
++ tryRelease(c, ws[sp & m], AC_UNIT);
++ }
++ }
++ return true;
++ }
++
++ // External operations
++
++ /**
++ * Full version of externalPush, handling uncommon cases, as well
++ * as performing secondary initialization upon the first
++ * submission of the first task to the pool. It also detects
++ * first submission by an external thread and creates a new shared
++ * queue if the one at index if empty or contended.
++ *
++ * @param task the task. Caller must ensure non-null.
++ */
++ private void externalSubmit(ForkJoinTask<?> task) {
++ int r; // initialize caller's probe
++ if ((r = ThreadLocalRandom.getProbe()) == 0) {
++ ThreadLocalRandom.localInit();
++ r = ThreadLocalRandom.getProbe();
++ }
++ for (;;) {
++ WorkQueue[] ws; WorkQueue q; int rs, m, k;
++ boolean move = false;
++ if ((rs = runState) < 0) {
++ tryTerminate(false, false); // help terminate
++ throw new RejectedExecutionException();
++ }
++ else if ((rs & STARTED) == 0 || // initialize
++ ((ws = workQueues) == null || (m = ws.length - 1) < 0)) {
++ int ns = 0;
++ rs = lockRunState();
++ try {
++ if ((rs & STARTED) == 0) {
++ U.compareAndSwapObject(this, STEALCOUNTER, null,
++ new AtomicLong());
++ // create workQueues array with size a power of two
++ int p = config & SMASK; // ensure at least 2 slots
++ int n = (p > 1) ? p - 1 : 1;
++ n |= n >>> 1; n |= n >>> 2; n |= n >>> 4;
++ n |= n >>> 8; n |= n >>> 16; n = (n + 1) << 1;
++ workQueues = new WorkQueue[n];
++ ns = STARTED;
++ }
++ } finally {
++ unlockRunState(rs, (rs & ~RSLOCK) | ns);
++ }
++ }
++ else if ((q = ws[k = r & m & SQMASK]) != null) {
++ if (q.qlock == 0 && U.compareAndSwapInt(q, QLOCK, 0, 1)) {
++ ForkJoinTask<?>[] a = q.array;
++ int s = q.top;
++ boolean submitted = false; // initial submission or resizing
++ try { // locked version of push
++ if ((a != null && a.length > s + 1 - q.base) ||
++ (a = q.growArray()) != null) {
++ int j = (((a.length - 1) & s) << ASHIFT) + ABASE;
++ U.putOrderedObject(a, j, task);
++ U.putOrderedInt(q, QTOP, s + 1);
++ submitted = true;
+ }
+- // Wake up workers parked on event queue
+- int i, e; long cc; Thread p;
+- while ((e = (int)(cc = ctl) & E_MASK) != 0 &&
+- (i = e & SMASK) < n && i >= 0 &&
+- (w = ws[i]) != null) {
+- long nc = ((long)(w.nextWait & E_MASK) |
+- ((cc + AC_UNIT) & AC_MASK) |
+- (cc & (TC_MASK|STOP_BIT)));
+- if (w.eventCount == (e | INT_SIGN) &&
+- U.compareAndSwapLong(this, CTL, cc, nc)) {
+- w.eventCount = (e + E_SEQ) & E_MASK;
+- w.qlock = -1;
+- if ((p = w.parker) != null)
+- U.unpark(p);
+- }
+- }
++ } finally {
++ U.compareAndSwapInt(q, QLOCK, 1, 0);
++ }
++ if (submitted) {
++ signalWork(ws, q);
++ return;
+ }
+ }
++ move = true; // move on failure
+ }
++ else if (((rs = runState) & RSLOCK) == 0) { // create new queue
++ q = new WorkQueue(this, null);
++ q.hint = r;
++ q.config = k | SHARED_QUEUE;
++ q.scanState = INACTIVE;
++ rs = lockRunState(); // publish index
++ if (rs > 0 && (ws = workQueues) != null &&
++ k < ws.length && ws[k] == null)
++ ws[k] = q; // else terminated
++ unlockRunState(rs, rs & ~RSLOCK);
++ }
++ else
++ move = true; // move if busy
++ if (move)
++ r = ThreadLocalRandom.advanceProbe(r);
+ }
+ }
+
+- // external operations on common pool
+-
+ /**
+- * Returns common pool queue for a thread that has submitted at
+- * least one task.
++ * Tries to add the given task to a submission queue at
++ * submitter's current queue. Only the (vastly) most common path
++ * is directly handled in this method, while screening for need
++ * for externalSubmit.
++ *
++ * @param task the task. Caller must ensure non-null.
+ */
+- static WorkQueue commonSubmitterQueue() {
+- ForkJoinPool p; WorkQueue[] ws; int m, z;
+- return ((z = ThreadLocalRandom.getProbe()) != 0 &&
+- (p = common) != null &&
+- (ws = p.workQueues) != null &&
+- (m = ws.length - 1) >= 0) ?
+- ws[m & z & SQMASK] : null;
++ final void externalPush(ForkJoinTask<?> task) {
++ WorkQueue[] ws; WorkQueue q; int m;
++ int r = ThreadLocalRandom.getProbe();
++ int rs = runState;
++ if ((ws = workQueues) != null && (m = (ws.length - 1)) >= 0 &&
++ (q = ws[m & r & SQMASK]) != null && r != 0 && rs > 0 &&
++ U.compareAndSwapInt(q, QLOCK, 0, 1)) {
++ ForkJoinTask<?>[] a; int am, n, s;
++ if ((a = q.array) != null &&
++ (am = a.length - 1) > (n = (s = q.top) - q.base)) {
++ int j = ((am & s) << ASHIFT) + ABASE;
++ U.putOrderedObject(a, j, task);
++ U.putOrderedInt(q, QTOP, s + 1);
++ U.putOrderedInt(q, QLOCK, 0);
++ if (n <= 1)
++ signalWork(ws, q);
++ return;
++ }
++ U.compareAndSwapInt(q, QLOCK, 1, 0);
++ }
++ externalSubmit(task);
+ }
+
+ /**
+- * Tries to pop the given task from submitter's queue in common pool.
++ * Returns common pool queue for an external thread.
++ */
++ static WorkQueue commonSubmitterQueue() {
++ ForkJoinPool p = common;
++ int r = ThreadLocalRandom.getProbe();
++ WorkQueue[] ws; int m;
++ return (p != null && (ws = p.workQueues) != null &&
++ (m = ws.length - 1) >= 0) ?
++ ws[m & r & SQMASK] : null;
++ }
++
++ /**
++ * Performs tryUnpush for an external submitter: Finds queue,
++ * locks if apparently non-empty, validates upon locking, and
++ * adjusts top. Each check can fail but rarely does.
+ */
+ final boolean tryExternalUnpush(ForkJoinTask<?> task) {
+- WorkQueue joiner; ForkJoinTask<?>[] a; int m, s;
+- WorkQueue[] ws = workQueues;
+- int z = ThreadLocalRandom.getProbe();
+- boolean popped = false;
+- if (ws != null && (m = ws.length - 1) >= 0 &&
+- (joiner = ws[z & m & SQMASK]) != null &&
+- joiner.base != (s = joiner.top) &&
+- (a = joiner.array) != null) {
++ WorkQueue[] ws; WorkQueue w; ForkJoinTask<?>[] a; int m, s;
++ int r = ThreadLocalRandom.getProbe();
++ if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 &&
++ (w = ws[m & r & SQMASK]) != null &&
++ (a = w.array) != null && (s = w.top) != w.base) {
+ long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
+- if (U.getObject(a, j) == task &&
+- U.compareAndSwapInt(joiner, QLOCK, 0, 1)) {
+- if (joiner.top == s && joiner.array == a &&
++ if (U.compareAndSwapInt(w, QLOCK, 0, 1)) {
++ if (w.top == s && w.array == a &&
++ U.getObject(a, j) == task &&
+ U.compareAndSwapObject(a, j, task, null)) {
+- joiner.top = s - 1;
+- popped = true;
++ U.putOrderedInt(w, QTOP, s - 1);
++ U.putOrderedInt(w, QLOCK, 0);
++ return true;
+ }
+- joiner.qlock = 0;
++ U.compareAndSwapInt(w, QLOCK, 1, 0);
+ }
+ }
+- return popped;
++ return false;
+ }
+
++ /**
++ * Performs helpComplete for an external submitter.
++ */
+ final int externalHelpComplete(CountedCompleter<?> task, int maxTasks) {
+- WorkQueue joiner; int m;
+- WorkQueue[] ws = workQueues;
+- int j = ThreadLocalRandom.getProbe();
+- int s = 0;
+- if (ws != null && (m = ws.length - 1) >= 0 &&
+- (joiner = ws[j & m & SQMASK]) != null && task != null) {
+- int scans = m + m + 1;
+- long c = 0L; // for stability check
+- j |= 1; // poll odd queues
+- for (int k = scans; ; j += 2) {
+- WorkQueue q;
+- if ((s = task.status) < 0)
+- break;
+- else if (joiner.externalPopAndExecCC(task)) {
+- if (--maxTasks <= 0) {
+- s = task.status;
+- break;
+- }
+- k = scans;
+- }
+- else if ((s = task.status) < 0)
+- break;
+- else if ((q = ws[j & m]) != null && q.pollAndExecCC(task)) {
+- if (--maxTasks <= 0) {
+- s = task.status;
+- break;
+- }
+- k = scans;
+- }
+- else if (--k < 0) {
+- if (c == (c = ctl))
+- break;
+- k = scans;
+- }
+- }
+- }
+- return s;
++ WorkQueue[] ws; int n;
++ int r = ThreadLocalRandom.getProbe();
++ return ((ws = workQueues) == null || (n = ws.length) == 0) ? 0 :
++ helpComplete(ws[(n - 1) & r & SQMASK], task, maxTasks);
+ }
+
+ // Exported methods
+@@ -2447,7 +2533,7 @@
+ this(checkParallelism(parallelism),
+ checkFactory(factory),
+ handler,
+- (asyncMode ? FIFO_QUEUE : LIFO_QUEUE),
++ asyncMode ? FIFO_QUEUE : LIFO_QUEUE,
+ "ForkJoinPool-" + nextPoolId() + "-worker-");
+ checkPermission();
+ }
+@@ -2478,8 +2564,7 @@
+ this.workerNamePrefix = workerNamePrefix;
+ this.factory = factory;
+ this.ueh = handler;
+- this.mode = (short)mode;
+- this.parallelism = (short)parallelism;
++ this.config = (parallelism & SMASK) | mode;
+ long np = (long)(-parallelism); // offset ctl counts
+ this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
+ }
+@@ -2624,7 +2709,7 @@
+ // In previous versions of this class, this method constructed
+ // a task to run ForkJoinTask.invokeAll, but now external
+ // invocation of multiple tasks is at least as efficient.
+- ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
++ ArrayList<Future<T>> futures = new ArrayList<>(tasks.size());
+
+ boolean done = false;
+ try {
+@@ -2670,7 +2755,7 @@
+ */
+ public int getParallelism() {
+ int par;
+- return ((par = parallelism) > 0) ? par : 1;
++ return ((par = config & SMASK) > 0) ? par : 1;
+ }
+
+ /**
+@@ -2692,7 +2777,7 @@
+ * @return the number of worker threads
+ */
+ public int getPoolSize() {
+- return parallelism + (short)(ctl >>> TC_SHIFT);
++ return (config & SMASK) + (short)(ctl >>> TC_SHIFT);
+ }
+
+ /**
+@@ -2702,7 +2787,7 @@
+ * @return {@code true} if this pool uses async mode
+ */
+ public boolean getAsyncMode() {
+- return mode == FIFO_QUEUE;
++ return (config & FIFO_QUEUE) != 0;
+ }
+
+ /**
+@@ -2733,7 +2818,7 @@
+ * @return the number of active threads
+ */
+ public int getActiveThreadCount() {
+- int r = parallelism + (int)(ctl >> AC_SHIFT);
++ int r = (config & SMASK) + (int)(ctl >> AC_SHIFT);
+ return (r <= 0) ? 0 : r; // suppress momentarily negative values
+ }
+
+@@ -2749,7 +2834,7 @@
+ * @return {@code true} if all threads are currently idle
+ */
+ public boolean isQuiescent() {
+- return parallelism + (int)(ctl >> AC_SHIFT) <= 0;
++ return (config & SMASK) + (int)(ctl >> AC_SHIFT) <= 0;
+ }
+
+ /**
+@@ -2764,7 +2849,8 @@
+ * @return the number of steals
+ */
+ public long getStealCount() {
+- long count = stealCount;
++ AtomicLong sc = stealCounter;
++ long count = (sc == null) ? 0L : sc.get();
+ WorkQueue[] ws; WorkQueue w;
+ if ((ws = workQueues) != null) {
+ for (int i = 1; i < ws.length; i += 2) {
+@@ -2894,7 +2980,8 @@
+ public String toString() {
+ // Use a single pass through workQueues to collect counts
+ long qt = 0L, qs = 0L; int rc = 0;
+- long st = stealCount;
++ AtomicLong sc = stealCounter;
++ long st = (sc == null) ? 0L : sc.get();
+ long c = ctl;
+ WorkQueue[] ws; WorkQueue w;
+ if ((ws = workQueues) != null) {
+@@ -2912,16 +2999,16 @@
+ }
+ }
+ }
+- int pc = parallelism;
++ int pc = (config & SMASK);
+ int tc = pc + (short)(c >>> TC_SHIFT);
+ int ac = pc + (int)(c >> AC_SHIFT);
+ if (ac < 0) // ignore transient negative
+ ac = 0;
+- String level;
+- if ((c & STOP_BIT) != 0)
+- level = (tc == 0) ? "Terminated" : "Terminating";
+- else
+- level = plock < 0 ? "Shutting down" : "Running";
++ int rs = runState;
++ String level = ((rs & TERMINATED) != 0 ? "Terminated" :
++ (rs & STOP) != 0 ? "Terminating" :
++ (rs & SHUTDOWN) != 0 ? "Shutting down" :
++ "Running");
+ return super.toString() +
+ "[" + level +
+ ", parallelism = " + pc +
+@@ -2983,9 +3070,7 @@
+ * @return {@code true} if all tasks have completed following shut down
+ */
+ public boolean isTerminated() {
+- long c = ctl;
+- return ((c & STOP_BIT) != 0L &&
+- (short)(c >>> TC_SHIFT) + parallelism <= 0);
++ return (runState & TERMINATED) != 0;
+ }
+
+ /**
+@@ -3002,9 +3087,8 @@
+ * @return {@code true} if terminating but not yet terminated
+ */
+ public boolean isTerminating() {
+- long c = ctl;
+- return ((c & STOP_BIT) != 0L &&
+- (short)(c >>> TC_SHIFT) + parallelism > 0);
++ int rs = runState;
++ return (rs & STOP) != 0 && (rs & TERMINATED) == 0;
+ }
+
+ /**
+@@ -3013,7 +3097,7 @@
+ * @return {@code true} if this pool has been shut down
+ */
+ public boolean isShutdown() {
+- return plock < 0;
++ return (runState & SHUTDOWN) != 0;
+ }
+
+ /**
+@@ -3090,8 +3174,9 @@
+ }
+ found = false;
+ for (int j = (m + 1) << 2; j >= 0; --j) {
+- ForkJoinTask<?> t; WorkQueue q; int b;
+- if ((q = ws[r++ & m]) != null && (b = q.base) - q.top < 0) {
++ ForkJoinTask<?> t; WorkQueue q; int b, k;
++ if ((k = r++ & m) <= m && k >= 0 && (q = ws[k]) != null &&
++ (b = q.base) - q.top < 0) {
+ found = true;
+ if ((t = q.pollAt(b)) != null)
+ t.doExec();
+@@ -3115,8 +3200,8 @@
+ * in {@link ForkJoinPool}s.
+ *
+ * <p>A {@code ManagedBlocker} provides two methods. Method
+- * {@code isReleasable} must return {@code true} if blocking is
+- * not necessary. Method {@code block} blocks the current thread
++ * {@link #isReleasable} must return {@code true} if blocking is
++ * not necessary. Method {@link #block} blocks the current thread
+ * if necessary (perhaps internally invoking {@code isReleasable}
+ * before actually blocking). These actions are performed by any
+ * thread invoking {@link ForkJoinPool#managedBlock(ManagedBlocker)}.
+@@ -3185,37 +3270,46 @@
+ }
+
+ /**
+- * Blocks in accord with the given blocker. If the current thread
+- * is a {@link ForkJoinWorkerThread}, this method possibly
+- * arranges for a spare thread to be activated if necessary to
+- * ensure sufficient parallelism while the current thread is blocked.
++ * Runs the given possibly blocking task. When {@linkplain
++ * ForkJoinTask#inForkJoinPool() running in a ForkJoinPool}, this
++ * method possibly arranges for a spare thread to be activated if
++ * necessary to ensure sufficient parallelism while the current
++ * thread is blocked in {@link ManagedBlocker#block blocker.block()}.
+ *
+- * <p>If the caller is not a {@link ForkJoinTask}, this method is
++ * <p>This method repeatedly calls {@code blocker.isReleasable()} and
++ * {@code blocker.block()} until either method returns {@code true}.
++ * Every call to {@code blocker.block()} is preceded by a call to
++ * {@code blocker.isReleasable()} that returned {@code false}.
++ *
++ * <p>If not running in a ForkJoinPool, this method is
+ * behaviorally equivalent to
+ * <pre> {@code
+ * while (!blocker.isReleasable())
+ * if (blocker.block())
+- * return;
+- * }</pre>
++ * break;}</pre>
+ *
+- * If the caller is a {@code ForkJoinTask}, then the pool may
+- * first be expanded to ensure parallelism, and later adjusted.
++ * If running in a ForkJoinPool, the pool may first be expanded to
++ * ensure sufficient parallelism available during the call to
++ * {@code blocker.block()}.
+ *
+- * @param blocker the blocker
+- * @throws InterruptedException if blocker.block did so
++ * @param blocker the blocker task
++ * @throws InterruptedException if {@code blocker.block()} did so
+ */
+ public static void managedBlock(ManagedBlocker blocker)
+ throws InterruptedException {
++ ForkJoinPool p;
++ ForkJoinWorkerThread wt;
+ Thread t = Thread.currentThread();
+- if (t instanceof ForkJoinWorkerThread) {
+- ForkJoinPool p = ((ForkJoinWorkerThread)t).pool;
++ if ((t instanceof ForkJoinWorkerThread) &&
++ (p = (wt = (ForkJoinWorkerThread)t).pool) != null) {
++ WorkQueue w = wt.workQueue;
+ while (!blocker.isReleasable()) {
+- if (p.tryCompensate(p.ctl)) {
++ if (p.tryCompensate(w)) {
+ try {
+ do {} while (!blocker.isReleasable() &&
+ !blocker.block());
+ } finally {
+- p.incrementActiveCount();
++ U.getAndAddLong(p, CTL, AC_UNIT);
+ }
+ break;
+ }
+@@ -3241,15 +3335,18 @@
+
+ // Unsafe mechanics
+ private static final sun.misc.Unsafe U;
++ private static final int ABASE;
++ private static final int ASHIFT;
+ private static final long CTL;
++ private static final long RUNSTATE;
++ private static final long STEALCOUNTER;
+ private static final long PARKBLOCKER;
+- private static final int ABASE;
+- private static final int ASHIFT;
+- private static final long STEALCOUNT;
+- private static final long PLOCK;
+- private static final long INDEXSEED;
+- private static final long QBASE;
++ private static final long QTOP;
+ private static final long QLOCK;
++ private static final long QSCANSTATE;
++ private static final long QPARKER;
++ private static final long QCURRENTSTEAL;
++ private static final long QCURRENTJOIN;
+
+ static {
+ // initialize field offsets for CAS etc
+@@ -3258,20 +3355,26 @@
+ Class<?> k = ForkJoinPool.class;
+ CTL = U.objectFieldOffset
+ (k.getDeclaredField("ctl"));
+- STEALCOUNT = U.objectFieldOffset
+- (k.getDeclaredField("stealCount"));
+- PLOCK = U.objectFieldOffset
+- (k.getDeclaredField("plock"));
+- INDEXSEED = U.objectFieldOffset
+- (k.getDeclaredField("indexSeed"));
++ RUNSTATE = U.objectFieldOffset
++ (k.getDeclaredField("runState"));
++ STEALCOUNTER = U.objectFieldOffset
++ (k.getDeclaredField("stealCounter"));
+ Class<?> tk = Thread.class;
+ PARKBLOCKER = U.objectFieldOffset
+ (tk.getDeclaredField("parkBlocker"));
+ Class<?> wk = WorkQueue.class;
+- QBASE = U.objectFieldOffset
+- (wk.getDeclaredField("base"));
++ QTOP = U.objectFieldOffset
++ (wk.getDeclaredField("top"));
+ QLOCK = U.objectFieldOffset
+ (wk.getDeclaredField("qlock"));
++ QSCANSTATE = U.objectFieldOffset
++ (wk.getDeclaredField("scanState"));
++ QPARKER = U.objectFieldOffset
++ (wk.getDeclaredField("parker"));
++ QCURRENTSTEAL = U.objectFieldOffset
++ (wk.getDeclaredField("currentSteal"));
++ QCURRENTJOIN = U.objectFieldOffset
++ (wk.getDeclaredField("currentJoin"));
+ Class<?> ak = ForkJoinTask[].class;
+ ABASE = U.arrayBaseOffset(ak);
+ int scale = U.arrayIndexScale(ak);
+@@ -3282,6 +3385,7 @@
+ throw new Error(e);
+ }
+
++ commonMaxSpares = DEFAULT_COMMON_MAX_SPARES;
+ defaultForkJoinWorkerThreadFactory =
+ new DefaultForkJoinWorkerThreadFactory();
+ modifyThreadPermission = new RuntimePermission("modifyThread");
+@@ -3289,7 +3393,7 @@
+ common = java.security.AccessController.doPrivileged
+ (new java.security.PrivilegedAction<ForkJoinPool>() {
+ public ForkJoinPool run() { return makeCommonPool(); }});
+- int par = common.parallelism; // report 1 even if threads disabled
++ int par = common.config & SMASK; // report 1 even if threads disabled
+ commonParallelism = par > 0 ? par : 1;
+ }
+
+--- ./jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java Wed Feb 04 12:14:43 2015 -0800
+@@ -297,15 +297,22 @@
+ }
+
+ /**
+- * Tries to set SIGNAL status unless already completed. Used by
+- * ForkJoinPool. Other variants are directly incorporated into
+- * externalAwaitDone etc.
++ * If not done, sets SIGNAL status and performs Object.wait(timeout).
++ * This task may or may not be done on exit. Ignores interrupts.
+ *
+- * @return true if successful
++ * @param timeout using Object.wait conventions.
+ */
+- final boolean trySetSignal() {
+- int s = status;
+- return s >= 0 && U.compareAndSwapInt(this, STATUS, s, s | SIGNAL);
++ final void internalWait(long timeout) {
++ int s;
++ if ((s = status) >= 0 && // force completer to issue notify
++ U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
++ synchronized (this) {
++ if (status >= 0)
++ try { wait(timeout); } catch (InterruptedException ie) { }
++ else
++ notifyAll();
++ }
++ }
+ }
+
+ /**
+@@ -313,35 +320,29 @@
+ * @return status upon completion
+ */
+ private int externalAwaitDone() {
+- int s;
+- ForkJoinPool cp = ForkJoinPool.common;
+- if ((s = status) >= 0) {
+- if (cp != null) {
+- if (this instanceof CountedCompleter)
+- s = cp.externalHelpComplete((CountedCompleter<?>)this, Integer.MAX_VALUE);
+- else if (cp.tryExternalUnpush(this))
+- s = doExec();
+- }
+- if (s >= 0 && (s = status) >= 0) {
+- boolean interrupted = false;
+- do {
+- if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
+- synchronized (this) {
+- if (status >= 0) {
+- try {
+- wait();
+- } catch (InterruptedException ie) {
+- interrupted = true;
+- }
++ int s = ((this instanceof CountedCompleter) ? // try helping
++ ForkJoinPool.common.externalHelpComplete(
++ (CountedCompleter<?>)this, 0) :
++ ForkJoinPool.common.tryExternalUnpush(this) ? doExec() : 0);
++ if (s >= 0 && (s = status) >= 0) {
++ boolean interrupted = false;
++ do {
++ if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
++ synchronized (this) {
++ if (status >= 0) {
++ try {
++ wait(0L);
++ } catch (InterruptedException ie) {
++ interrupted = true;
+ }
+- else
+- notifyAll();
+ }
++ else
++ notifyAll();
+ }
+- } while ((s = status) >= 0);
+- if (interrupted)
+- Thread.currentThread().interrupt();
+- }
++ }
++ } while ((s = status) >= 0);
++ if (interrupted)
++ Thread.currentThread().interrupt();
+ }
+ return s;
+ }
+@@ -351,22 +352,22 @@
+ */
+ private int externalInterruptibleAwaitDone() throws InterruptedException {
+ int s;
+- ForkJoinPool cp = ForkJoinPool.common;
+ if (Thread.interrupted())
+ throw new InterruptedException();
+- if ((s = status) >= 0 && cp != null) {
+- if (this instanceof CountedCompleter)
+- cp.externalHelpComplete((CountedCompleter<?>)this, Integer.MAX_VALUE);
+- else if (cp.tryExternalUnpush(this))
+- doExec();
+- }
+- while ((s = status) >= 0) {
+- if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
+- synchronized (this) {
+- if (status >= 0)
+- wait();
+- else
+- notifyAll();
++ if ((s = status) >= 0 &&
++ (s = ((this instanceof CountedCompleter) ?
++ ForkJoinPool.common.externalHelpComplete(
++ (CountedCompleter<?>)this, 0) :
++ ForkJoinPool.common.tryExternalUnpush(this) ? doExec() :
++ 0)) >= 0) {
++ while ((s = status) >= 0) {
++ if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
++ synchronized (this) {
++ if (status >= 0)
++ wait(0L);
++ else
++ notifyAll();
++ }
+ }
+ }
+ }
+@@ -386,7 +387,7 @@
+ ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
+ (w = (wt = (ForkJoinWorkerThread)t).workQueue).
+ tryUnpush(this) && (s = doExec()) < 0 ? s :
+- wt.pool.awaitJoin(w, this) :
++ wt.pool.awaitJoin(w, this, 0L) :
+ externalAwaitDone();
+ }
+
+@@ -399,7 +400,8 @@
+ int s; Thread t; ForkJoinWorkerThread wt;
+ return (s = doExec()) < 0 ? s :
+ ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
+- (wt = (ForkJoinWorkerThread)t).pool.awaitJoin(wt.workQueue, this) :
++ (wt = (ForkJoinWorkerThread)t).pool.
++ awaitJoin(wt.workQueue, this, 0L) :
+ externalAwaitDone();
+ }
+
+@@ -577,7 +579,7 @@
+ Throwable ex;
+ if (e == null || (ex = e.ex) == null)
+ return null;
+- if (false && e.thrower != Thread.currentThread().getId()) {
++ if (e.thrower != Thread.currentThread().getId()) {
+ Class<? extends Throwable> ec = ex.getClass();
+ try {
+ Constructor<?> noArgCtor = null;
+@@ -587,13 +589,17 @@
+ Class<?>[] ps = c.getParameterTypes();
+ if (ps.length == 0)
+ noArgCtor = c;
+- else if (ps.length == 1 && ps[0] == Throwable.class)
+- return (Throwable)(c.newInstance(ex));
++ else if (ps.length == 1 && ps[0] == Throwable.class) {
++ Throwable wx = (Throwable)c.newInstance(ex);
++ return (wx == null) ? ex : wx;
++ }
+ }
+ if (noArgCtor != null) {
+ Throwable wx = (Throwable)(noArgCtor.newInstance());
+- wx.initCause(ex);
+- return wx;
++ if (wx != null) {
++ wx.initCause(ex);
++ return wx;
++ }
+ }
+ } catch (Exception ignore) {
+ }
+@@ -1017,67 +1023,40 @@
+ */
+ public final V get(long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException {
++ int s;
++ long nanos = unit.toNanos(timeout);
+ if (Thread.interrupted())
+ throw new InterruptedException();
+- // Messy in part because we measure in nanosecs, but wait in millisecs
+- int s; long ms;
+- long ns = unit.toNanos(timeout);
+- ForkJoinPool cp;
+- if ((s = status) >= 0 && ns > 0L) {
+- long deadline = System.nanoTime() + ns;
+- ForkJoinPool p = null;
+- ForkJoinPool.WorkQueue w = null;
++ if ((s = status) >= 0 && nanos > 0L) {
++ long d = System.nanoTime() + nanos;
++ long deadline = (d == 0L) ? 1L : d; // avoid 0
+ Thread t = Thread.currentThread();
+ if (t instanceof ForkJoinWorkerThread) {
+ ForkJoinWorkerThread wt = (ForkJoinWorkerThread)t;
+- p = wt.pool;
+- w = wt.workQueue;
+- p.helpJoinOnce(w, this); // no retries on failure
++ s = wt.pool.awaitJoin(wt.workQueue, this, deadline);
+ }
+- else if ((cp = ForkJoinPool.common) != null) {
+- if (this instanceof CountedCompleter)
+- cp.externalHelpComplete((CountedCompleter<?>)this, Integer.MAX_VALUE);
+- else if (cp.tryExternalUnpush(this))
+- doExec();
+- }
+- boolean canBlock = false;
+- boolean interrupted = false;
+- try {
+- while ((s = status) >= 0) {
+- if (w != null && w.qlock < 0)
+- cancelIgnoringExceptions(this);
+- else if (!canBlock) {
+- if (p == null || p.tryCompensate(p.ctl))
+- canBlock = true;
+- }
+- else {
+- if ((ms = TimeUnit.NANOSECONDS.toMillis(ns)) > 0L &&
+- U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
+- synchronized (this) {
+- if (status >= 0) {
+- try {
+- wait(ms);
+- } catch (InterruptedException ie) {
+- if (p == null)
+- interrupted = true;
+- }
+- }
+- else
+- notifyAll();
+- }
++ else if ((s = ((this instanceof CountedCompleter) ?
++ ForkJoinPool.common.externalHelpComplete(
++ (CountedCompleter<?>)this, 0) :
++ ForkJoinPool.common.tryExternalUnpush(this) ?
++ doExec() : 0)) >= 0) {
++ long ns, ms; // measure in nanosecs, but wait in millisecs
++ while ((s = status) >= 0 &&
++ (ns = deadline - System.nanoTime()) > 0L) {
++ if ((ms = TimeUnit.NANOSECONDS.toMillis(ns)) > 0L &&
++ U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
++ synchronized (this) {
++ if (status >= 0)
++ wait(ms); // OK to throw InterruptedException
++ else
++ notifyAll();
+ }
+- if ((s = status) < 0 || interrupted ||
+- (ns = deadline - System.nanoTime()) <= 0L)
+- break;
+ }
+ }
+- } finally {
+- if (p != null && canBlock)
+- p.incrementActiveCount();
+ }
+- if (interrupted)
+- throw new InterruptedException();
+ }
++ if (s >= 0)
++ s = status;
+ if ((s &= DONE_MASK) != NORMAL) {
+ Throwable ex;
+ if (s == CANCELLED)
+--- ./jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Wed Feb 04 12:14:43 2015 -0800
+@@ -66,7 +66,7 @@
+ * owning thread.
+ *
+ * Support for (non-public) subclass InnocuousForkJoinWorkerThread
+- * requires that we break quite a lot of encapulation (via Unsafe)
++ * requires that we break quite a lot of encapsulation (via Unsafe)
+ * both here and in the subclass to access and set Thread fields.
+ */
+
+@@ -118,7 +118,7 @@
+ * @return the index number
+ */
+ public int getPoolIndex() {
+- return workQueue.poolIndex >>> 1; // ignore odd/even tag bit
++ return workQueue.getPoolIndex();
+ }
+
+ /**
+@@ -171,7 +171,7 @@
+ }
+
+ /**
+- * Erases ThreadLocals by nulling out Thread maps
++ * Erases ThreadLocals by nulling out Thread maps.
+ */
+ final void eraseThreadLocals() {
+ U.putObject(this, THREADLOCALS, null);
+@@ -246,8 +246,8 @@
+
+ /**
+ * Returns a new group with the system ThreadGroup (the
+- * topmost, parentless group) as parent. Uses Unsafe to
+- * traverse Thread group and ThreadGroup parent fields.
++ * topmost, parent-less group) as parent. Uses Unsafe to
++ * traverse Thread.group and ThreadGroup.parent fields.
+ */
+ private static ThreadGroup createThreadGroup() {
+ try {
+@@ -274,4 +274,3 @@
+ }
+
+ }
+-
+--- ./jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java Wed Feb 04 12:14:43 2015 -0800
+@@ -36,8 +36,6 @@
+ package java.util.concurrent;
+
+ import java.io.ObjectStreamField;
+-import java.net.NetworkInterface;
+-import java.util.Enumeration;
+ import java.util.Random;
+ import java.util.Spliterator;
+ import java.util.concurrent.atomic.AtomicInteger;
+@@ -147,34 +145,7 @@
+ s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
+ return s;
+ }
+- long h = 0L;
+- try {
+- Enumeration<NetworkInterface> ifcs =
+- NetworkInterface.getNetworkInterfaces();
+- boolean retry = false; // retry once if getHardwareAddress is null
+- while (ifcs.hasMoreElements()) {
+- NetworkInterface ifc = ifcs.nextElement();
+- if (!ifc.isVirtual()) { // skip fake addresses
+- byte[] bs = ifc.getHardwareAddress();
+- if (bs != null) {
+- int n = bs.length;
+- int m = Math.min(n >>> 1, 4);
+- for (int i = 0; i < m; ++i)
+- h = (h << 16) ^ (bs[i] << 8) ^ bs[n-1-i];
+- if (m < 4)
+- h = (h << 8) ^ bs[n-1-m];
+- h = mix64(h);
+- break;
+- }
+- else if (!retry)
+- retry = true;
+- else
+- break;
+- }
+- }
+- } catch (Exception ignore) {
+- }
+- return (h ^ mix64(System.currentTimeMillis()) ^
++ return (mix64(System.currentTimeMillis()) ^
+ mix64(System.nanoTime()));
+ }
+
+--- ./jdk/src/share/classes/java/util/concurrent/atomic/package-info.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/concurrent/atomic/package-info.java Wed Feb 04 12:14:43 2015 -0800
+@@ -94,7 +94,7 @@
+ *
+ * <p>The memory effects for accesses and updates of atomics generally
+ * follow the rules for volatiles, as stated in
+- * <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4">
++ * <a href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4">
+ * The Java Language Specification (17.4 Memory Model)</a>:
+ *
+ * <ul>
+--- ./jdk/src/share/classes/java/util/concurrent/locks/Lock.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/concurrent/locks/Lock.java Wed Feb 04 12:14:43 2015 -0800
+@@ -121,7 +121,7 @@
+ * <p>All {@code Lock} implementations <em>must</em> enforce the same
+ * memory synchronization semantics as provided by the built-in monitor
+ * lock, as described in
+- * <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4">
++ * <a href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4">
+ * The Java Language Specification (17.4 Memory Model)</a>:
+ * <ul>
+ * <li>A successful {@code lock} operation has the same memory
+--- ./jdk/src/share/classes/java/util/concurrent/package-info.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/concurrent/package-info.java Wed Feb 04 12:14:43 2015 -0800
+@@ -226,7 +226,7 @@
+ *
+ * <h2 id="MemoryVisibility">Memory Consistency Properties</h2>
+ *
+- * <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5">
++ * <a href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5">
+ * Chapter 17 of the Java Language Specification</a> defines the
+ * <i>happens-before</i> relation on memory operations such as reads and
+ * writes of shared variables. The results of a write by one thread are
+--- ./jdk/src/share/classes/java/util/jar/Attributes.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/jar/Attributes.java Wed Feb 04 12:14:43 2015 -0800
+@@ -550,8 +550,8 @@
+ * <code>Name</code> object for <code>Class-Path</code>
+ * manifest attribute. Bundled extensions can use this attribute
+ * to find other JAR files containing needed classes.
+- * @see <a href="../../../../technotes/guides/extensions/spec.html#bundled">
+- * Extensions Specification</a>
++ * @see <a href="../../../../technotes/guides/jar/jar.html#classpath">
++ * JAR file specification</a>
+ */
+ public static final Name CLASS_PATH = new Name("Class-Path");
+
+@@ -567,8 +567,8 @@
+ /**
+ * <code>Name</code> object for <code>Sealed</code> manifest attribute
+ * used for sealing.
+- * @see <a href="../../../../technotes/guides/extensions/spec.html#sealing">
+- * Extension Sealing</a>
++ * @see <a href="../../../../technotes/guides/jar/jar.html#sealing">
++ * Package Sealing</a>
+ */
+ public static final Name SEALED = new Name("Sealed");
+
+@@ -591,9 +591,12 @@
+ /**
+ * <code>Name</code> object for <code>Extension-Name</code> manifest attribute
+ * used for declaring dependencies on installed extensions.
++ * @deprecated Extension mechanism will be removed in a future release.
++ * Use class path instead.
+ * @see <a href="../../../../technotes/guides/extensions/spec.html#dependency">
+ * Installed extension dependency</a>
+ */
++ @Deprecated
+ public static final Name EXTENSION_INSTALLATION = new Name("Extension-Installation");
+
+ /**
+@@ -623,17 +626,23 @@
+ /**
+ * <code>Name</code> object for <code>Implementation-Vendor-Id</code>
+ * manifest attribute used for package versioning.
+- * @see <a href="../../../../technotes/guides/versioning/spec/versioning2.html#wp90779">
+- * Java Product Versioning Specification</a>
++ * @deprecated Extension mechanism will be removed in a future release.
++ * Use class path instead.
++ * @see <a href="../../../../technotes/guides/extensions/versioning.html#applet">
++ * Optional Package Versioning</a>
+ */
++ @Deprecated
+ public static final Name IMPLEMENTATION_VENDOR_ID = new Name("Implementation-Vendor-Id");
+
+ /**
+ * <code>Name</code> object for <code>Implementation-URL</code>
+ * manifest attribute used for package versioning.
+- * @see <a href="../../../../technotes/guides/versioning/spec/versioning2.html#wp90779">
+- * Java Product Versioning Specification</a>
++ * @deprecated Extension mechanism will be removed in a future release.
++ * Use class path instead.
++ * @see <a href="../../../../technotes/guides/extensions/versioning.html#applet">
++ * Optional Package Versioning</a>
+ */
++ @Deprecated
+ public static final Name IMPLEMENTATION_URL = new Name("Implementation-URL");
+
+ /**
+--- ./jdk/src/share/classes/java/util/logging/FileHandler.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/logging/FileHandler.java Wed Feb 04 12:14:43 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package java.util.logging;
+
++import static java.nio.file.StandardOpenOption.APPEND;
+ import static java.nio.file.StandardOpenOption.CREATE_NEW;
+ import static java.nio.file.StandardOpenOption.WRITE;
+
+@@ -34,10 +35,17 @@
+ import java.io.IOException;
+ import java.io.OutputStream;
+ import java.nio.channels.FileChannel;
++import java.nio.channels.OverlappingFileLockException;
+ import java.nio.file.FileAlreadyExistsException;
++import java.nio.file.Files;
++import java.nio.file.LinkOption;
++import java.nio.file.NoSuchFileException;
++import java.nio.file.Path;
+ import java.nio.file.Paths;
+ import java.security.AccessController;
+ import java.security.PrivilegedAction;
++import java.util.HashSet;
++import java.util.Set;
+
+ /**
+ * Simple file logging <tt>Handler</tt>.
+@@ -149,7 +157,7 @@
+ private FileChannel lockFileChannel;
+ private File files[];
+ private static final int MAX_LOCKS = 100;
+- private static final java.util.HashMap<String, String> locks = new java.util.HashMap<>();
++ private static final Set<String> locks = new HashSet<>();
+
+ /**
+ * A metered stream is a subclass of OutputStream that
+@@ -394,6 +402,14 @@
+ openFiles();
+ }
+
++ private boolean isParentWritable(Path path) {
++ Path parent = path.getParent();
++ if (parent == null) {
++ parent = path.toAbsolutePath().getParent();
++ }
++ return parent != null && Files.isWritable(parent);
++ }
++
+ /**
+ * Open the set of output files, based on the configured
+ * instance variables.
+@@ -428,34 +444,80 @@
+ // between processes (and not within a process), we first check
+ // if we ourself already have the file locked.
+ synchronized(locks) {
+- if (locks.get(lockFileName) != null) {
++ if (locks.contains(lockFileName)) {
+ // We already own this lock, for a different FileHandler
+ // object. Try again.
+ continue;
+ }
+
+- try {
+- lockFileChannel = FileChannel.open(Paths.get(lockFileName),
+- CREATE_NEW, WRITE);
+- } catch (FileAlreadyExistsException ix) {
+- // try the next lock file name in the sequence
+- continue;
++ final Path lockFilePath = Paths.get(lockFileName);
++ FileChannel channel = null;
++ int retries = -1;
++ boolean fileCreated = false;
++ while (channel == null && retries++ < 1) {
++ try {
++ channel = FileChannel.open(lockFilePath,
++ CREATE_NEW, WRITE);
++ fileCreated = true;
++ } catch (FileAlreadyExistsException ix) {
++ // This may be a zombie file left over by a previous
++ // execution. Reuse it - but only if we can actually
++ // write to its directory.
++ // Note that this is a situation that may happen,
++ // but not too frequently.
++ if (Files.isRegularFile(lockFilePath, LinkOption.NOFOLLOW_LINKS)
++ && isParentWritable(lockFilePath)) {
++ try {
++ channel = FileChannel.open(lockFilePath,
++ WRITE, APPEND);
++ } catch (NoSuchFileException x) {
++ // Race condition - retry once, and if that
++ // fails again just try the next name in
++ // the sequence.
++ continue;
++ } catch(IOException x) {
++ // the file may not be writable for us.
++ // try the next name in the sequence
++ break;
++ }
++ } else {
++ // at this point channel should still be null.
++ // break and try the next name in the sequence.
++ break;
++ }
++ }
+ }
+
++ if (channel == null) continue; // try the next name;
++ lockFileChannel = channel;
++
+ boolean available;
+ try {
+ available = lockFileChannel.tryLock() != null;
+ // We got the lock OK.
++ // At this point we could call File.deleteOnExit().
++ // However, this could have undesirable side effects
++ // as indicated by JDK-4872014. So we will instead
++ // rely on the fact that close() will remove the lock
++ // file and that whoever is creating FileHandlers should
++ // be responsible for closing them.
+ } catch (IOException ix) {
+ // We got an IOException while trying to get the lock.
+ // This normally indicates that locking is not supported
+ // on the target directory. We have to proceed without
+- // getting a lock. Drop through.
+- available = true;
++ // getting a lock. Drop through, but only if we did
++ // create the file...
++ available = fileCreated;
++ } catch (OverlappingFileLockException x) {
++ // someone already locked this file in this VM, through
++ // some other channel - that is - using something else
++ // than new FileHandler(...);
++ // continue searching for an available lock.
++ available = false;
+ }
+ if (available) {
+ // We got the lock. Remember it.
+- locks.put(lockFileName, lockFileName);
++ locks.add(lockFileName);
+ break;
+ }
+
+--- ./jdk/src/share/classes/java/util/logging/LogManager.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/logging/LogManager.java Wed Feb 04 12:14:43 2015 -0800
+@@ -502,11 +502,11 @@
+ JavaAWTAccess javaAwtAccess = SharedSecrets.getJavaAWTAccess();
+ if (sm != null && javaAwtAccess != null) {
+ // for each applet, it has its own LoggerContext isolated from others
+- synchronized (javaAwtAccess) {
+- // find the AppContext of the applet code
+- // will be null if we are in the main app context.
+- final Object ecx = javaAwtAccess.getAppletContext();
+- if (ecx != null) {
++ final Object ecx = javaAwtAccess.getAppletContext();
++ if (ecx != null) {
++ synchronized (javaAwtAccess) {
++ // find the AppContext of the applet code
++ // will be null if we are in the main app context.
+ if (contextsMap == null) {
+ contextsMap = new WeakHashMap<>();
+ }
+--- ./jdk/src/share/classes/java/util/stream/ForEachOps.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/stream/ForEachOps.java Wed Feb 04 12:14:43 2015 -0800
+@@ -32,6 +32,7 @@
+ import java.util.function.Consumer;
+ import java.util.function.DoubleConsumer;
+ import java.util.function.IntConsumer;
++import java.util.function.IntFunction;
+ import java.util.function.LongConsumer;
+
+ /**
+@@ -317,12 +318,55 @@
+ */
+ @SuppressWarnings("serial")
+ static final class ForEachOrderedTask<S, T> extends CountedCompleter<Void> {
++ /*
++ * Our goal is to ensure that the elements associated with a task are
++ * processed according to an in-order traversal of the computation tree.
++ * We use completion counts for representing these dependencies, so that
++ * a task does not complete until all the tasks preceding it in this
++ * order complete. We use the "completion map" to associate the next
++ * task in this order for any left child. We increase the pending count
++ * of any node on the right side of such a mapping by one to indicate
++ * its dependency, and when a node on the left side of such a mapping
++ * completes, it decrements the pending count of its corresponding right
++ * side. As the computation tree is expanded by splitting, we must
++ * atomically update the mappings to maintain the invariant that the
++ * completion map maps left children to the next node in the in-order
++ * traversal.
++ *
++ * Take, for example, the following computation tree of tasks:
++ *
++ * a
++ * / \
++ * b c
++ * / \ / \
++ * d e f g
++ *
++ * The complete map will contain (not necessarily all at the same time)
++ * the following associations:
++ *
++ * d -> e
++ * b -> f
++ * f -> g
++ *
++ * Tasks e, f, g will have their pending counts increased by 1.
++ *
++ * The following relationships hold:
++ *
++ * - completion of d "happens-before" e;
++ * - completion of d and e "happens-before b;
++ * - completion of b "happens-before" f; and
++ * - completion of f "happens-before" g
++ *
++ * Thus overall the "happens-before" relationship holds for the
++ * reporting of elements, covered by tasks d, e, f and g, as specified
++ * by the forEachOrdered operation.
++ */
++
+ private final PipelineHelper<T> helper;
+ private Spliterator<S> spliterator;
+ private final long targetSize;
+ private final ConcurrentHashMap<ForEachOrderedTask<S, T>, ForEachOrderedTask<S, T>> completionMap;
+ private final Sink<T> action;
+- private final Object lock;
+ private final ForEachOrderedTask<S, T> leftPredecessor;
+ private Node<T> node;
+
+@@ -333,9 +377,9 @@
+ this.helper = helper;
+ this.spliterator = spliterator;
+ this.targetSize = AbstractTask.suggestTargetSize(spliterator.estimateSize());
+- this.completionMap = new ConcurrentHashMap<>();
++ // Size map to avoid concurrent re-sizes
++ this.completionMap = new ConcurrentHashMap<>(Math.max(16, AbstractTask.LEAF_TARGET << 1));
+ this.action = action;
+- this.lock = new Object();
+ this.leftPredecessor = null;
+ }
+
+@@ -348,7 +392,6 @@
+ this.targetSize = parent.targetSize;
+ this.completionMap = parent.completionMap;
+ this.action = parent.action;
+- this.lock = parent.lock;
+ this.leftPredecessor = leftPredecessor;
+ }
+
+@@ -367,16 +410,42 @@
+ new ForEachOrderedTask<>(task, leftSplit, task.leftPredecessor);
+ ForEachOrderedTask<S, T> rightChild =
+ new ForEachOrderedTask<>(task, rightSplit, leftChild);
++
++ // Fork the parent task
++ // Completion of the left and right children "happens-before"
++ // completion of the parent
++ task.addToPendingCount(1);
++ // Completion of the left child "happens-before" completion of
++ // the right child
++ rightChild.addToPendingCount(1);
+ task.completionMap.put(leftChild, rightChild);
+- task.addToPendingCount(1); // forking
+- rightChild.addToPendingCount(1); // right pending on left child
++
++ // If task is not on the left spine
+ if (task.leftPredecessor != null) {
+- leftChild.addToPendingCount(1); // left pending on previous subtree, except left spine
+- if (task.completionMap.replace(task.leftPredecessor, task, leftChild))
+- task.addToPendingCount(-1); // transfer my "right child" count to my left child
+- else
+- leftChild.addToPendingCount(-1); // left child is ready to go when ready
++ /*
++ * Completion of left-predecessor, or left subtree,
++ * "happens-before" completion of left-most leaf node of
++ * right subtree.
++ * The left child's pending count needs to be updated before
++ * it is associated in the completion map, otherwise the
++ * left child can complete prematurely and violate the
++ * "happens-before" constraint.
++ */
++ leftChild.addToPendingCount(1);
++ // Update association of left-predecessor to left-most
++ // leaf node of right subtree
++ if (task.completionMap.replace(task.leftPredecessor, task, leftChild)) {
++ // If replaced, adjust the pending count of the parent
++ // to complete when its children complete
++ task.addToPendingCount(-1);
++ } else {
++ // Left-predecessor has already completed, parent's
++ // pending count is adjusted by left-predecessor;
++ // left child is ready to complete
++ leftChild.addToPendingCount(-1);
++ }
+ }
++
+ ForEachOrderedTask<S, T> taskToFork;
+ if (forkRight) {
+ forkRight = false;
+@@ -391,31 +460,49 @@
+ }
+ taskToFork.fork();
+ }
+- if (task.getPendingCount() == 0) {
+- task.helper.wrapAndCopyInto(task.action, rightSplit);
+- }
+- else {
++
++ /*
++ * Task's pending count is either 0 or 1. If 1 then the completion
++ * map will contain a value that is task, and two calls to
++ * tryComplete are required for completion, one below and one
++ * triggered by the completion of task's left-predecessor in
++ * onCompletion. Therefore there is no data race within the if
++ * block.
++ */
++ if (task.getPendingCount() > 0) {
++ // Cannot complete just yet so buffer elements into a Node
++ // for use when completion occurs
++ @SuppressWarnings("unchecked")
++ IntFunction<T[]> generator = size -> (T[]) new Object[size];
+ Node.Builder<T> nb = task.helper.makeNodeBuilder(
+- task.helper.exactOutputSizeIfKnown(rightSplit),
+- size -> (T[]) new Object[size]);
++ task.helper.exactOutputSizeIfKnown(rightSplit),
++ generator);
+ task.node = task.helper.wrapAndCopyInto(nb, rightSplit).build();
++ task.spliterator = null;
+ }
+ task.tryComplete();
+ }
+
+ @Override
+ public void onCompletion(CountedCompleter<?> caller) {
+- spliterator = null;
+ if (node != null) {
+- // Dump any data from this leaf into the sink
+- synchronized (lock) {
+- node.forEach(action);
+- }
++ // Dump buffered elements from this leaf into the sink
++ node.forEach(action);
+ node = null;
+ }
+- ForEachOrderedTask<S, T> victim = completionMap.remove(this);
+- if (victim != null)
+- victim.tryComplete();
++ else if (spliterator != null) {
++ // Dump elements output from this leaf's pipeline into the sink
++ helper.wrapAndCopyInto(action, spliterator);
++ spliterator = null;
++ }
++
++ // The completion of this task *and* the dumping of elements
++ // "happens-before" completion of the associated left-most leaf task
++ // of right subtree (if any, which can be this task's right sibling)
++ //
++ ForEachOrderedTask<S, T> leftDescendant = completionMap.remove(this);
++ if (leftDescendant != null)
++ leftDescendant.tryComplete();
+ }
+ }
+ }
+--- ./jdk/src/share/classes/java/util/stream/Nodes.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/stream/Nodes.java Wed Feb 04 12:14:43 2015 -0800
+@@ -63,7 +63,7 @@
+ // IllegalArgumentException messages
+ static final String BAD_SIZE = "Stream size exceeds max array size";
+
+- @SuppressWarnings("raw")
++ @SuppressWarnings("rawtypes")
+ private static final Node EMPTY_NODE = new EmptyNode.OfRef();
+ private static final Node.OfInt EMPTY_INT_NODE = new EmptyNode.OfInt();
+ private static final Node.OfLong EMPTY_LONG_NODE = new EmptyNode.OfLong();
+@@ -956,6 +956,7 @@
+ * Initiate a stack containing, in left-to-right order, the child nodes
+ * covered by this spliterator
+ */
++ @SuppressWarnings("unchecked")
+ protected final Deque<N> initStack() {
+ // Bias size to the case where leaf nodes are close to this node
+ // 8 is the minimum initial capacity for the ArrayDeque implementation
+@@ -969,6 +970,7 @@
+ * Depth first search, in left-to-right order, of the node tree, using
+ * an explicit stack, to find the next non-empty leaf node.
+ */
++ @SuppressWarnings("unchecked")
+ protected final N findNextLeafNode(Deque<N> stack) {
+ N n = null;
+ while ((n = stack.pollFirst()) != null) {
+@@ -984,6 +986,7 @@
+ return null;
+ }
+
++ @SuppressWarnings("unchecked")
+ protected final boolean initTryAdvance() {
+ if (curNode == null)
+ return false;
+@@ -1870,6 +1873,7 @@
+ }
+
+ assert task.offset + task.length < MAX_ARRAY_SIZE;
++ @SuppressWarnings("unchecked")
+ T_SINK sink = (T_SINK) task;
+ task.helper.wrapAndCopyInto(sink, rightSplit);
+ task.propagateCompletion();
+@@ -2173,6 +2177,7 @@
+ }
+
+ @Override
++ @SuppressWarnings("unchecked")
+ protected T_NODE doLeaf() {
+ T_BUILDER builder = builderFactory.apply(helper.exactOutputSizeIfKnown(spliterator));
+ return (T_NODE) helper.wrapAndCopyInto(builder, spliterator).build();
+--- ./jdk/src/share/classes/java/util/stream/SortedOps.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/stream/SortedOps.java Wed Feb 04 12:14:43 2015 -0800
+@@ -29,7 +29,6 @@
+ import java.util.Comparator;
+ import java.util.Objects;
+ import java.util.Spliterator;
+-import java.util.concurrent.ForkJoinTask;
+ import java.util.function.IntFunction;
+
+
+@@ -113,7 +112,9 @@
+ StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SORTED);
+ this.isNaturalSort = true;
+ // Will throw CCE when we try to sort if T is not Comparable
+- this.comparator = (Comparator<? super T>) Comparator.naturalOrder();
++ @SuppressWarnings("unchecked")
++ Comparator<? super T> comp = (Comparator<? super T>) Comparator.naturalOrder();
++ this.comparator = comp;
+ }
+
+ /**
+@@ -170,7 +171,7 @@
+ }
+
+ @Override
+- public Sink<Integer> opWrapSink(int flags, Sink sink) {
++ public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
+ Objects.requireNonNull(sink);
+
+ if (StreamOpFlag.SORTED.isKnown(flags))
+@@ -335,6 +336,7 @@
+ }
+
+ @Override
++ @SuppressWarnings("unchecked")
+ public void begin(long size) {
+ if (size >= Nodes.MAX_ARRAY_SIZE)
+ throw new IllegalArgumentException(Nodes.BAD_SIZE);
+--- ./jdk/src/share/classes/java/util/stream/SpinedBuffer.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/stream/SpinedBuffer.java Wed Feb 04 12:14:43 2015 -0800
+@@ -92,6 +92,7 @@
+ * @throws IllegalArgumentException if the specified initial capacity
+ * is negative
+ */
++ @SuppressWarnings("unchecked")
+ SpinedBuffer(int initialCapacity) {
+ super(initialCapacity);
+ curChunk = (E[]) new Object[1 << initialChunkPower];
+@@ -100,6 +101,7 @@
+ /**
+ * Constructs an empty list with an initial capacity of sixteen.
+ */
++ @SuppressWarnings("unchecked")
+ SpinedBuffer() {
+ super();
+ curChunk = (E[]) new Object[1 << initialChunkPower];
+@@ -114,6 +116,7 @@
+ : priorElementCount[spineIndex] + spine[spineIndex].length;
+ }
+
++ @SuppressWarnings("unchecked")
+ private void inflateSpine() {
+ if (spine == null) {
+ spine = (E[][]) new Object[MIN_SPINE_SIZE][];
+@@ -125,6 +128,7 @@
+ /**
+ * Ensure that the buffer has at least capacity to hold the target size
+ */
++ @SuppressWarnings("unchecked")
+ protected final void ensureCapacity(long targetSize) {
+ long capacity = capacity();
+ if (targetSize > capacity) {
+--- ./jdk/src/share/classes/java/util/stream/StreamSpliterators.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/stream/StreamSpliterators.java Wed Feb 04 12:14:43 2015 -0800
+@@ -516,6 +516,7 @@
+ }
+
+ @Override
++ @SuppressWarnings("unchecked")
+ public T_SPLITR trySplit() {
+ return (T_SPLITR) get().trySplit();
+ }
+@@ -643,6 +644,7 @@
+ // existing and additionally created F/J tasks that perform
+ // redundant work on no elements.
+ while (true) {
++ @SuppressWarnings("unchecked")
+ T_SPLITR leftSplit = (T_SPLITR) s.trySplit();
+ if (leftSplit == null)
+ return null;
+@@ -970,6 +972,7 @@
+ // Stop splitting when there are no more limit permits
+ if (permits.get() == 0)
+ return null;
++ @SuppressWarnings("unchecked")
+ T_SPLITR split = (T_SPLITR) s.trySplit();
+ return split == null ? null : makeSpliterator(split);
+ }
+@@ -1068,16 +1071,18 @@
+ super(s, skip, limit);
+ }
+
+- OfPrimitive(T_SPLITR s, UnorderedSliceSpliterator.OfPrimitive parent) {
++ OfPrimitive(T_SPLITR s, UnorderedSliceSpliterator.OfPrimitive<T, T_CONS, T_BUFF, T_SPLITR> parent) {
+ super(s, parent);
+ }
+
+ @Override
+ public boolean tryAdvance(T_CONS action) {
+ Objects.requireNonNull(action);
++ @SuppressWarnings("unchecked")
++ T_CONS consumer = (T_CONS) this;
+
+ while (permitStatus() != PermitStatus.NO_MORE) {
+- if (!s.tryAdvance((T_CONS) this))
++ if (!s.tryAdvance(consumer))
+ return false;
+ else if (acquirePermits(1) == 1) {
+ acceptConsumed(action);
+@@ -1316,7 +1321,7 @@
+ * estimate size is 0.
+ *
+ * <p>The {@code forEachRemaining} method if invoked will never terminate.
+- * The {@coe tryAdvance} method always returns true.
++ * The {@code tryAdvance} method always returns true.
+ *
+ */
+ static abstract class InfiniteSupplyingSpliterator<T> implements Spliterator<T> {
+--- ./jdk/src/share/classes/java/util/stream/Streams.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/java/util/stream/Streams.java Wed Feb 04 12:14:43 2015 -0800
+@@ -715,6 +715,7 @@
+
+ @Override
+ public T_SPLITR trySplit() {
++ @SuppressWarnings("unchecked")
+ T_SPLITR ret = beforeSplit ? aSpliterator : (T_SPLITR) bSpliterator.trySplit();
+ beforeSplit = false;
+ return ret;
+--- ./jdk/src/share/classes/javax/crypto/Cipher.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/crypto/Cipher.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -167,6 +167,11 @@
+ private static final Debug debug =
+ Debug.getInstance("jca", "Cipher");
+
++ private static final Debug pdebug =
++ Debug.getInstance("provider", "Provider");
++ private static final boolean skipDebug =
++ Debug.isOn("engine=") && !Debug.isOn("cipher");
++
+ /**
+ * Constant used to initialize cipher to encryption mode.
+ */
+@@ -1110,6 +1115,21 @@
+ }
+ }
+
++ private static String getOpmodeString(int opmode) {
++ switch (opmode) {
++ case ENCRYPT_MODE:
++ return "encryption";
++ case DECRYPT_MODE:
++ return "decryption";
++ case WRAP_MODE:
++ return "key wrapping";
++ case UNWRAP_MODE:
++ return "key unwrapping";
++ default:
++ return "";
++ }
++ }
++
+ /**
+ * Initializes this cipher with a key.
+ *
+@@ -1235,6 +1255,12 @@
+
+ initialized = true;
+ this.opmode = opmode;
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("Cipher." + transformation + " " +
++ getOpmodeString(opmode) + " algorithm from: " +
++ this.provider.getName());
++ }
+ }
+
+ /**
+@@ -1372,6 +1398,12 @@
+
+ initialized = true;
+ this.opmode = opmode;
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("Cipher." + transformation + " " +
++ getOpmodeString(opmode) + " algorithm from: " +
++ this.provider.getName());
++ }
+ }
+
+ /**
+@@ -1509,6 +1541,12 @@
+
+ initialized = true;
+ this.opmode = opmode;
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("Cipher." + transformation + " " +
++ getOpmodeString(opmode) + " algorithm from: " +
++ this.provider.getName());
++ }
+ }
+
+ /**
+@@ -1693,6 +1731,12 @@
+
+ initialized = true;
+ this.opmode = opmode;
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("Cipher." + transformation + " " +
++ getOpmodeString(opmode) + " algorithm from: " +
++ this.provider.getName());
++ }
+ }
+
+ /**
+--- ./jdk/src/share/classes/javax/crypto/KeyAgreement.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/crypto/KeyAgreement.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -78,6 +78,11 @@
+ private static final Debug debug =
+ Debug.getInstance("jca", "KeyAgreement");
+
++ private static final Debug pdebug =
++ Debug.getInstance("provider", "Provider");
++ private static final boolean skipDebug =
++ Debug.isOn("engine=") && !Debug.isOn("keyagreement");
++
+ // The provider
+ private Provider provider;
+
+@@ -468,6 +473,11 @@
+ throw new InvalidKeyException(e);
+ }
+ }
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("KeyAgreement." + algorithm + " algorithm from: " +
++ this.provider.getName());
++ }
+ }
+
+ /**
+@@ -524,6 +534,11 @@
+ } else {
+ chooseProvider(I_PARAMS, key, params, random);
+ }
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("KeyAgreement." + algorithm + " algorithm from: " +
++ this.provider.getName());
++ }
+ }
+
+ /**
+--- ./jdk/src/share/classes/javax/crypto/KeyGenerator.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/crypto/KeyGenerator.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -33,6 +33,7 @@
+
+ import sun.security.jca.*;
+ import sun.security.jca.GetInstance.Instance;
++import sun.security.util.Debug;
+
+ /**
+ * This class provides the functionality of a secret (symmetric) key generator.
+@@ -108,6 +109,11 @@
+
+ public class KeyGenerator {
+
++ private static final Debug pdebug =
++ Debug.getInstance("provider", "Provider");
++ private static final boolean skipDebug =
++ Debug.isOn("engine=") && !Debug.isOn("keygenerator");
++
+ // see java.security.KeyPairGenerator for failover notes
+
+ private final static int I_NONE = 1;
+@@ -145,6 +151,11 @@
+ this.spi = keyGenSpi;
+ this.provider = provider;
+ this.algorithm = algorithm;
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("KeyGenerator." + algorithm + " algorithm from: " +
++ this.provider.getName());
++ }
+ }
+
+ private KeyGenerator(String algorithm) throws NoSuchAlgorithmException {
+@@ -158,6 +169,11 @@
+ throw new NoSuchAlgorithmException
+ (algorithm + " KeyGenerator not available");
+ }
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("KeyGenerator." + algorithm + " algorithm from: " +
++ this.provider.getName());
++ }
+ }
+
+ /**
+--- ./jdk/src/share/classes/javax/crypto/Mac.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/crypto/Mac.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -77,6 +77,11 @@
+ private static final Debug debug =
+ Debug.getInstance("jca", "Mac");
+
++ private static final Debug pdebug =
++ Debug.getInstance("provider", "Provider");
++ private static final boolean skipDebug =
++ Debug.isOn("engine=") && !Debug.isOn("mac");
++
+ // The provider
+ private Provider provider;
+
+@@ -413,6 +418,11 @@
+ throw new InvalidKeyException("init() failed", e);
+ }
+ initialized = true;
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("Mac." + algorithm + " algorithm from: " +
++ this.provider.getName());
++ }
+ }
+
+ /**
+@@ -435,6 +445,11 @@
+ chooseProvider(key, params);
+ }
+ initialized = true;
++
++ if (!skipDebug && pdebug != null) {
++ pdebug.println("Mac." + algorithm + " algorithm from: " +
++ this.provider.getName());
++ }
+ }
+
+ /**
+--- ./jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1335,66 +1335,94 @@
+ int maxNotifications,
+ long timeout)
+ throws IOException, ClassNotFoundException {
+- IOException org;
+
++ boolean retried = false;
+ while (true) { // used for a successful re-connection
++ // or a transient network problem
+ try {
+ return connection.fetchNotifications(clientSequenceNumber,
+ maxNotifications,
+- timeout);
++ timeout); // return normally
+ } catch (IOException ioe) {
+- org = ioe;
++ // Examine the chain of exceptions to determine whether this
++ // is a deserialization issue. If so - we propagate the
++ // appropriate exception to the caller, who will then
++ // proceed with fetching notifications one by one
++ rethrowDeserializationException(ioe);
+
+- // inform of IOException
+ try {
+ communicatorAdmin.gotIOException(ioe);
++ // reconnection OK, back to "while" to do again
++ } catch (IOException ee) {
++ boolean toClose = false;
+
+- // The connection should be re-established.
+- continue;
+- } catch (IOException ee) {
+- // No more fetch, the Exception will be re-thrown.
+- break;
+- } // never reached
+- } // never reached
++ synchronized (this) {
++ if (terminated) {
++ // the connection is closed.
++ throw ioe;
++ } else if (retried) {
++ toClose = true;
++ }
++ }
++
++ if (toClose) {
++ // JDK-8049303
++ // We received an IOException - but the communicatorAdmin
++ // did not close the connection - possibly because
++ // the original exception was raised by a transient network
++ // problem?
++ // We already know that this exception is not due to a deserialization
++ // issue as we already took care of that before involving the
++ // communicatorAdmin. Moreover - we already made one retry attempt
++ // at fetching the same batch of notifications - and the
++ // problem persisted.
++ // Since trying again doesn't seem to solve the issue, we will now
++ // close the connection. Doing otherwise might cause the
++ // NotifFetcher thread to die silently.
++ final Notification failedNotif =
++ new JMXConnectionNotification(
++ JMXConnectionNotification.FAILED,
++ this,
++ connectionId,
++ clientNotifSeqNo++,
++ "Failed to communicate with the server: " + ioe.toString(),
++ ioe);
++
++ sendNotification(failedNotif);
++
++ try {
++ close(true);
++ } catch (Exception e) {
++ // OK.
++ // We are closing
++ }
++ throw ioe; // the connection is closed here.
++ } else {
++ // JDK-8049303 possible transient network problem,
++ // let's try one more time
++ retried = true;
++ }
++ }
++ }
+ }
++ }
+
++ private void rethrowDeserializationException(IOException ioe)
++ throws ClassNotFoundException, IOException {
+ // specially treating for an UnmarshalException
+- if (org instanceof UnmarshalException) {
+- UnmarshalException ume = (UnmarshalException)org;
+-
+- if (ume.detail instanceof ClassNotFoundException)
+- throw (ClassNotFoundException) ume.detail;
+-
+- /* In Sun's RMI implementation, if a method return
+- contains an unserializable object, then we get
+- UnmarshalException wrapping WriteAbortedException
+- wrapping NotSerializableException. In that case we
+- extract the NotSerializableException so that our
+- caller can realize it should try to skip past the
+- notification that presumably caused it. It's not
+- certain that every other RMI implementation will
+- generate this exact exception sequence. If not, we
+- will not detect that the problem is due to an
+- unserializable object, and we will stop trying to
+- receive notifications from the server. It's not
+- clear we can do much better. */
+- if (ume.detail instanceof WriteAbortedException) {
+- WriteAbortedException wae =
+- (WriteAbortedException) ume.detail;
+- if (wae.detail instanceof IOException)
+- throw (IOException) wae.detail;
+- }
+- } else if (org instanceof MarshalException) {
++ if (ioe instanceof UnmarshalException) {
++ throw ioe; // the fix of 6937053 made ClientNotifForwarder.fetchNotifs
++ // fetch one by one with UnmarshalException
++ } else if (ioe instanceof MarshalException) {
+ // IIOP will throw MarshalException wrapping a NotSerializableException
+ // when a server fails to serialize a response.
+- MarshalException me = (MarshalException)org;
++ MarshalException me = (MarshalException)ioe;
+ if (me.detail instanceof NotSerializableException) {
+ throw (NotSerializableException)me.detail;
+ }
+ }
+
+- // Not serialization problem, simply re-throw the orginal exception
+- throw org;
++ // Not serialization problem, return.
+ }
+
+ protected Integer addListenerForMBeanRemovedNotif()
+--- ./jdk/src/share/classes/javax/swing/AbstractButton.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/AbstractButton.java Wed Feb 04 12:14:43 2015 -0800
+@@ -53,12 +53,12 @@
+ * configuring a button. Refer to <a href="Action.html#buttonActions">
+ * Swing Components Supporting <code>Action</code></a> for more
+ * details, and you can find more information in <a
+- * href="http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
++ * href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
+ * to Use Actions</a>, a section in <em>The Java Tutorial</em>.
+ * <p>
+ * For further information see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>,
+ * a section in <em>The Java Tutorial</em>.
+ * <p>
+ * <strong>Warning:</strong>
+--- ./jdk/src/share/classes/javax/swing/BorderFactory.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/BorderFactory.java Wed Feb 04 12:14:43 2015 -0800
+@@ -35,7 +35,7 @@
+ * possible, this factory will hand out references to shared
+ * <code>Border</code> instances.
+ * For further information and examples see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.htmll">How
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/border.htmll">How
+ to Use Borders</a>,
+ * a section in <em>The Java Tutorial</em>.
+ *
+--- ./jdk/src/share/classes/javax/swing/Box.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/Box.java Wed Feb 04 12:14:43 2015 -0800
+@@ -60,7 +60,7 @@
+ * If you are implementing a <code>BoxLayout</code> you
+ * can find further information and examples in
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/layout/box.html">How to Use BoxLayout</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/layout/box.html">How to Use BoxLayout</a>,
+ * a section in <em>The Java Tutorial.</em>
+ * <p>
+ * <strong>Warning:</strong>
+--- ./jdk/src/share/classes/javax/swing/BoxLayout.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/BoxLayout.java Wed Feb 04 12:14:43 2015 -0800
+@@ -116,7 +116,7 @@
+ * <p>
+ * For further information and examples see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/layout/box.html">How to Use BoxLayout</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/layout/box.html">How to Use BoxLayout</a>,
+ * a section in <em>The Java Tutorial.</em>
+ * <p>
+ * <strong>Warning:</strong>
+--- ./jdk/src/share/classes/javax/swing/ButtonGroup.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/ButtonGroup.java Wed Feb 04 12:14:43 2015 -0800
+@@ -51,7 +51,7 @@
+ * Initially, all buttons in the group are unselected.
+ * <p>
+ * For examples and further information on using button groups see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/button.html#radiobutton">How to Use Radio Buttons</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/button.html#radiobutton">How to Use Radio Buttons</a>,
+ * a section in <em>The Java Tutorial</em>.
+ * <p>
+ * <strong>Warning:</strong>
+--- ./jdk/src/share/classes/javax/swing/CellEditor.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/CellEditor.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -47,7 +47,7 @@
+ * new component implement the interface. Or the developer can
+ * choose a wrapper based approach and provide a companion object which
+ * implements the <code>CellEditor</code> interface (See
+- * <code>JCellEditor</code> for example). The wrapper approach
++ * <code>DefaultCellEditor</code> for example). The wrapper approach
+ * is particularly useful if the user want to use a 3rd party ISV
+ * editor with <code>JTable</code>, but the ISV didn't implement the
+ * <code>CellEditor</code> interface. The user can simply create an object
+--- ./jdk/src/share/classes/javax/swing/DefaultFocusManager.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/DefaultFocusManager.java Wed Feb 04 12:14:43 2015 -0800
+@@ -37,7 +37,7 @@
+ * <code>java.awt.DefaultKeyboardFocusManager</code> instead.
+ * <p>
+ * Please see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>, and the
+ * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
+--- ./jdk/src/share/classes/javax/swing/FocusManager.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/FocusManager.java Wed Feb 04 12:14:43 2015 -0800
+@@ -34,7 +34,7 @@
+ * <code>java.awt.DefaultKeyboardFocusManager</code> instead.
+ * <p>
+ * Please see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>, and the
+ * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
+--- ./jdk/src/share/classes/javax/swing/ImageIcon.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/ImageIcon.java Wed Feb 04 12:14:43 2015 -0800
+@@ -50,7 +50,7 @@
+ *
+ * <p>
+ * For further information and examples of using image icons, see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/icon.html">How to Use Icons</a>
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/icon.html">How to Use Icons</a>
+ * in <em>The Java Tutorial.</em>
+ *
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/JApplet.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JApplet.java Wed Feb 04 12:14:43 2015 -0800
+@@ -40,7 +40,7 @@
+ * in <em>The Java Tutorial</em>,
+ * in the section
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/applet.html">How to Make Applets</a>.
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/applet.html">How to Make Applets</a>.
+ * <p>
+ * The <code>JApplet</code> class is slightly incompatible with
+ * <code>java.applet.Applet</code>. <code>JApplet</code> contains a
+@@ -184,7 +184,7 @@
+ * are currently typed to {@code JComponent}.
+ * <p>
+ * Please see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
+ * How to Use Drag and Drop and Data Transfer</a>, a section in
+ * <em>The Java Tutorial</em>, for more information.
+ *
+--- ./jdk/src/share/classes/javax/swing/JButton.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JButton.java Wed Feb 04 12:14:43 2015 -0800
+@@ -48,10 +48,10 @@
+ * configuring a button. Refer to <a href="Action.html#buttonActions">
+ * Swing Components Supporting <code>Action</code></a> for more
+ * details, and you can find more information in <a
+- * href="http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
++ * href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
+ * to Use Actions</a>, a section in <em>The Java Tutorial</em>.
+ * <p>
+- * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>
++ * See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>
+ * in <em>The Java Tutorial</em>
+ * for information and examples of using buttons.
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/JCheckBox.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JCheckBox.java Wed Feb 04 12:14:43 2015 -0800
+@@ -40,7 +40,7 @@
+ * An implementation of a check box -- an item that can be selected or
+ * deselected, and which displays its state to the user.
+ * By convention, any number of check boxes in a group can be selected.
+- * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>
++ * See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>
+ * in <em>The Java Tutorial</em>
+ * for examples and information on using check boxes.
+ * <p>
+@@ -50,7 +50,7 @@
+ * configuring a button. Refer to <a href="Action.html#buttonActions">
+ * Swing Components Supporting <code>Action</code></a> for more
+ * details, and you can find more information in <a
+- * href="http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
++ * href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
+ * to Use Actions</a>, a section in <em>The Java Tutorial</em>.
+ * <p>
+ * <strong>Warning:</strong> Swing is not thread safe. For more
+--- ./jdk/src/share/classes/javax/swing/JCheckBoxMenuItem.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JCheckBoxMenuItem.java Wed Feb 04 12:14:43 2015 -0800
+@@ -59,12 +59,12 @@
+ * configuring a menu item. Refer to <a href="Action.html#buttonActions">
+ * Swing Components Supporting <code>Action</code></a> for more
+ * details, and you can find more information in <a
+- * href="http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
++ * href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
+ * to Use Actions</a>, a section in <em>The Java Tutorial</em>.
+ * <p>
+ * For further information and examples of using check box menu items,
+ * see <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
+ * a section in <em>The Java Tutorial.</em>
+ * <p>
+ * <strong>Warning:</strong> Swing is not thread safe. For more
+--- ./jdk/src/share/classes/javax/swing/JColorChooser.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JColorChooser.java Wed Feb 04 12:14:43 2015 -0800
+@@ -42,7 +42,7 @@
+ * a user to manipulate and select a color.
+ * For information about using color choosers, see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/colorchooser.html">How to Use Color Choosers</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/colorchooser.html">How to Use Color Choosers</a>,
+ * a section in <em>The Java Tutorial</em>.
+ *
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/JComboBox.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JComboBox.java Wed Feb 04 12:14:43 2015 -0800
+@@ -62,8 +62,8 @@
+ * Please see {@link java.beans.XMLEncoder}.
+ *
+ * <p>
+- * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html">How to Use Combo Boxes</a>
+- * in <a href="http://docs.oracle.com/javase/tutorial/"><em>The Java Tutorial</em></a>
++ * See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html">How to Use Combo Boxes</a>
++ * in <a href="https://docs.oracle.com/javase/tutorial/"><em>The Java Tutorial</em></a>
+ * for further information.
+ * <p>
+ * @see ComboBoxModel
+@@ -1308,7 +1308,8 @@
+ */
+ public void actionPerformed(ActionEvent e) {
+ ComboBoxEditor editor = getEditor();
+- if ((editor != null) && (e != null) && (editor == e.getSource())) {
++ if ((editor != null) && (e != null) && (editor == e.getSource()
++ || editor.getEditorComponent() == e.getSource())) {
+ setPopupVisible(false);
+ getModel().setSelectedItem(editor.getItem());
+ String oldCommand = getActionCommand();
+--- ./jdk/src/share/classes/javax/swing/JComponent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JComponent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -56,6 +56,7 @@
+ import java.io.IOException;
+ import java.io.ObjectInputValidation;
+ import java.io.InvalidObjectException;
++import java.util.concurrent.atomic.AtomicBoolean;
+
+ import javax.swing.border.*;
+ import javax.swing.event.*;
+@@ -79,7 +80,7 @@
+ * that provide a place for other Swing components to paint themselves.
+ * For an explanation of containment hierarchies, see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html">Swing Components and the Containment Hierarchy</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html">Swing Components and the Containment Hierarchy</a>,
+ * a section in <em>The Java Tutorial</em>.
+ *
+ * <p>
+@@ -93,20 +94,20 @@
+ * <em>UI delegate</em> -- an object that descends from
+ * {@link javax.swing.plaf.ComponentUI}.
+ * See <a
+- * href="http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html">How
++ * href="https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html">How
+ * to Set the Look and Feel</a>
+ * in <em>The Java Tutorial</em>
+ * for more information.
+ * <li>Comprehensive keystroke handling.
+ * See the document <a
+- * href="http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html">How to Use Key Bindings</a>,
++ * href="https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html">How to Use Key Bindings</a>,
+ * an article in <em>The Java Tutorial</em>,
+ * for more information.
+ * <li>Support for tool tips --
+ * short descriptions that pop up when the cursor lingers
+ * over a component.
+ * See <a
+- * href="http://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How
++ * href="https://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How
+ * to Use Tool Tips</a>
+ * in <em>The Java Tutorial</em>
+ * for more information.
+@@ -125,14 +126,14 @@
+ * that includes double buffering and support for borders.
+ * For more information see <a
+ * href="http://www.oracle.com/technetwork/java/painting-140037.html#swing">Painting</a> and
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.htmll">How
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/border.htmll">How
+ * to Use Borders</a>,
+ * both of which are sections in <em>The Java Tutorial</em>.
+ * </ul>
+ * For more information on these subjects, see the
+ * <a href="package-summary.html#package_description">Swing package description</a>
+ * and <em>The Java Tutorial</em> section
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/jcomponent.html">The JComponent Class</a>.
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/jcomponent.html">The JComponent Class</a>.
+ * <p>
+ * <code>JComponent</code> and its subclasses document default values
+ * for certain properties. For example, <code>JTable</code> documents the
+@@ -150,7 +151,7 @@
+ * <p>
+ * In release 1.4, the focus subsystem was rearchitected.
+ * For more information, see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>.
+ * <p>
+@@ -352,7 +353,8 @@
+ private static final int AUTOSCROLLS_SET = 25;
+ private static final int FOCUS_TRAVERSAL_KEYS_FORWARD_SET = 26;
+ private static final int FOCUS_TRAVERSAL_KEYS_BACKWARD_SET = 27;
+- private static final int REVALIDATE_RUNNABLE_SCHEDULED = 28;
++
++ private transient AtomicBoolean revalidateRunnableScheduled = new AtomicBoolean(false);
+
+ /**
+ * Temporary rectangles.
+@@ -1291,7 +1293,7 @@
+ /**
+ * In release 1.4, the focus subsystem was rearchitected.
+ * For more information, see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>.
+ * <p>
+@@ -1353,7 +1355,7 @@
+ /**
+ * In release 1.4, the focus subsystem was rearchitected.
+ * For more information, see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>.
+ * <p>
+@@ -1386,7 +1388,7 @@
+ /**
+ * In release 1.4, the focus subsystem was rearchitected.
+ * For more information, see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>.
+ * <p>
+@@ -1419,7 +1421,7 @@
+ * all, use the <code>setFocusable</code> method instead.
+ * <p>
+ * Please see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>,
+ * for more information.
+@@ -1438,7 +1440,7 @@
+ * get focus; otherwise returns <code>false</code>.
+ * <p>
+ * Please see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>,
+ * for more information.
+@@ -1464,7 +1466,7 @@
+ * its behavior is platform dependent. Instead we recommend the
+ * use of {@link #requestFocusInWindow() requestFocusInWindow()}.
+ * If you would like more information on focus, see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>.
+ *
+@@ -1487,7 +1489,7 @@
+ * use of {@link #requestFocusInWindow(boolean)
+ * requestFocusInWindow(boolean)}.
+ * If you would like more information on focus, see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>.
+ *
+@@ -1509,7 +1511,7 @@
+ * this method.
+ * <p>
+ * If you would like more information on focus, see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>.
+ *
+@@ -1530,7 +1532,7 @@
+ * this method.
+ * <p>
+ * If you would like more information on focus, see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>.
+ *
+@@ -2595,7 +2597,7 @@
+ /**
+ * In release 1.4, the focus subsystem was rearchitected.
+ * For more information, see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
+ * How to Use the Focus Subsystem</a>,
+ * a section in <em>The Java Tutorial</em>.
+ * <p>
+@@ -2986,7 +2988,7 @@
+ * Registers the text to display in a tool tip.
+ * The text displays when the cursor lingers over the component.
+ * <p>
+- * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How to Use Tool Tips</a>
++ * See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How to Use Tool Tips</a>
+ * in <em>The Java Tutorial</em>
+ * for further documentation.
+ *
+@@ -3206,7 +3208,7 @@
+ * default value for the system property is {@code false}.
+ * <p>
+ * Please see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
+ * How to Use Drag and Drop and Data Transfer</a>,
+ * a section in <em>The Java Tutorial</em>, for more information.
+ *
+@@ -4859,16 +4861,11 @@
+ // To avoid a flood of Runnables when constructing GUIs off
+ // the EDT, a flag is maintained as to whether or not
+ // a Runnable has been scheduled.
+- synchronized(this) {
+- if (getFlag(REVALIDATE_RUNNABLE_SCHEDULED)) {
+- return;
+- }
+- setFlag(REVALIDATE_RUNNABLE_SCHEDULED, true);
++ if (revalidateRunnableScheduled.getAndSet(true)) {
++ return;
+ }
+ SunToolkit.executeOnEventHandlerThread(this, () -> {
+- synchronized(JComponent.this) {
+- setFlag(REVALIDATE_RUNNABLE_SCHEDULED, false);
+- }
++ revalidateRunnableScheduled.set(false);
+ revalidate();
+ });
+ }
+@@ -5508,6 +5505,7 @@
+ ToolTipManager.sharedInstance().registerComponent(this);
+ }
+ setWriteObjCounter(this, (byte)0);
++ revalidateRunnableScheduled = new AtomicBoolean(false);
+ }
+
+
+--- ./jdk/src/share/classes/javax/swing/JDesktopPane.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JDesktopPane.java Wed Feb 04 12:14:43 2015 -0800
+@@ -64,7 +64,7 @@
+ * (closing, resizing, etc).
+ * <p>
+ * For further documentation and examples see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html">How to Use Internal Frames</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html">How to Use Internal Frames</a>,
+ * a section in <em>The Java Tutorial</em>.
+ * <p>
+ * <strong>Warning:</strong> Swing is not thread safe. For more
+--- ./jdk/src/share/classes/javax/swing/JDialog.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JDialog.java Wed Feb 04 12:14:43 2015 -0800
+@@ -35,7 +35,7 @@
+ * For information about creating dialogs, see
+ * <em>The Java Tutorial</em> section
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html">How
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html">How
+ * to Make Dialogs</a>.
+ *
+ * <p>
+@@ -788,7 +788,7 @@
+ * are currently typed to {@code JComponent}.
+ * <p>
+ * Please see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
+ * How to Use Drag and Drop and Data Transfer</a>, a section in
+ * <em>The Java Tutorial</em>, for more information.
+ *
+--- ./jdk/src/share/classes/javax/swing/JEditorPane.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JEditorPane.java Wed Feb 04 12:14:43 2015 -0800
+@@ -43,7 +43,7 @@
+ /**
+ * A text component to edit various kinds of content.
+ * You can find how-to information and examples of using editor panes in
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/text.html">Using Text Components</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/text.html">Using Text Components</a>,
+ * a section in <em>The Java Tutorial.</em>
+ *
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/JFileChooser.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JFileChooser.java Wed Feb 04 12:14:43 2015 -0800
+@@ -57,7 +57,7 @@
+ * choose a file.
+ * For information about using <code>JFileChooser</code>, see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/filechooser.html">How to Use File Choosers</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/filechooser.html">How to Use File Choosers</a>,
+ * a section in <em>The Java Tutorial</em>.
+ *
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/JFrame.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JFrame.java Wed Feb 04 12:14:43 2015 -0800
+@@ -24,14 +24,22 @@
+ */
+ package javax.swing;
+
+-import java.awt.*;
+-import java.awt.event.*;
+-import java.beans.PropertyChangeListener;
+-import java.util.Locale;
+-import java.util.Vector;
+-import java.io.Serializable;
++import java.awt.AWTEvent;
++import java.awt.BorderLayout;
++import java.awt.Component;
++import java.awt.Container;
++import java.awt.Frame;
++import java.awt.Graphics;
++import java.awt.GraphicsConfiguration;
++import java.awt.HeadlessException;
++import java.awt.Image;
++import java.awt.LayoutManager;
++import java.awt.event.WindowEvent;
+
+-import javax.accessibility.*;
++import javax.accessibility.Accessible;
++import javax.accessibility.AccessibleContext;
++import javax.accessibility.AccessibleState;
++import javax.accessibility.AccessibleStateSet;
+
+
+ /**
+@@ -40,7 +48,7 @@
+ * You can find task-oriented documentation about using <code>JFrame</code>
+ * in <em>The Java Tutorial</em>, in the section
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/frame.html">How to Make Frames</a>.
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/frame.html">How to Make Frames</a>.
+ *
+ * <p>
+ * The <code>JFrame</code> class is slightly incompatible with <code>Frame</code>.
+@@ -78,7 +86,7 @@
+ * For more information on content panes
+ * and other features that root panes provide,
+ * see <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html">Using Top-Level Containers</a> in <em>The Java Tutorial</em>.
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html">Using Top-Level Containers</a> in <em>The Java Tutorial</em>.
+ * <p>
+ * In a multi-screen environment, you can create a <code>JFrame</code>
+ * on a different screen device. See {@link java.awt.Frame} for more
+@@ -293,33 +301,28 @@
+ * @see #setDefaultCloseOperation
+ * @see java.awt.Window#processWindowEvent
+ */
+- protected void processWindowEvent(WindowEvent e) {
++ protected void processWindowEvent(final WindowEvent e) {
+ super.processWindowEvent(e);
+
+ if (e.getID() == WindowEvent.WINDOW_CLOSING) {
+- switch(defaultCloseOperation) {
+- case HIDE_ON_CLOSE:
+- setVisible(false);
+- break;
+- case DISPOSE_ON_CLOSE:
+- dispose();
+- break;
+- case DO_NOTHING_ON_CLOSE:
+- default:
+- break;
+- case EXIT_ON_CLOSE:
+- // This needs to match the checkExit call in
+- // setDefaultCloseOperation
+- System.exit(0);
+- break;
++ switch (defaultCloseOperation) {
++ case HIDE_ON_CLOSE:
++ setVisible(false);
++ break;
++ case DISPOSE_ON_CLOSE:
++ dispose();
++ break;
++ case EXIT_ON_CLOSE:
++ // This needs to match the checkExit call in
++ // setDefaultCloseOperation
++ System.exit(0);
++ break;
++ case DO_NOTHING_ON_CLOSE:
++ default:
+ }
+ }
+ }
+
+-// public void setMenuBar(MenuBar menu) {
+-// throw new IllegalComponentStateException("Please use setJMenuBar() with JFrame.");
+-// }
+-
+ /**
+ * Sets the operation that will happen by default when
+ * the user initiates a "close" on this frame.
+@@ -431,7 +434,7 @@
+ * are currently typed to {@code JComponent}.
+ * <p>
+ * Please see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
+ * How to Use Drag and Drop and Data Transfer</a>, a section in
+ * <em>The Java Tutorial</em>, for more information.
+ *
+--- ./jdk/src/share/classes/javax/swing/JInternalFrame.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JInternalFrame.java Wed Feb 04 12:14:43 2015 -0800
+@@ -50,7 +50,7 @@
+ * resizing, title display, and support for a menu bar.
+ * For task-oriented documentation and examples of using internal frames,
+ * see <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html" target="_top">How to Use Internal Frames</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html" target="_top">How to Use Internal Frames</a>,
+ * a section in <em>The Java Tutorial</em>.
+ *
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/JLabel.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JLabel.java Wed Feb 04 12:14:43 2015 -0800
+@@ -80,7 +80,7 @@
+ * should appear between the text and the image.
+ * The default is 4 pixels.
+ * <p>
+- * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/label.html">How to Use Labels</a>
++ * See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/label.html">How to Use Labels</a>
+ * in <em>The Java Tutorial</em>
+ * for further documentation.
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/JLayeredPane.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JLayeredPane.java Wed Feb 04 12:14:43 2015 -0800
+@@ -41,7 +41,7 @@
+ * container, where higher-numbered components sit &quot;on top&quot; of other
+ * components.
+ * For task-oriented documentation and examples of using layered panes see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html">How to Use a Layered Pane</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html">How to Use a Layered Pane</a>,
+ * a section in <em>The Java Tutorial</em>.
+ *
+ * <TABLE STYLE="FLOAT:RIGHT" BORDER="0" SUMMARY="layout">
+--- ./jdk/src/share/classes/javax/swing/JList.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JList.java Wed Feb 04 12:14:43 2015 -0800
+@@ -257,8 +257,8 @@
+ * has been added to the <code>java.beans</code> package.
+ * Please see {@link java.beans.XMLEncoder}.
+ * <p>
+- * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/list.html">How to Use Lists</a>
+- * in <a href="http://docs.oracle.com/javase/tutorial/"><em>The Java Tutorial</em></a>
++ * See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/list.html">How to Use Lists</a>
++ * in <a href="https://docs.oracle.com/javase/tutorial/"><em>The Java Tutorial</em></a>
+ * for further documentation.
+ * <p>
+ * @see ListModel
+--- ./jdk/src/share/classes/javax/swing/JMenu.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JMenu.java Wed Feb 04 12:14:43 2015 -0800
+@@ -76,11 +76,11 @@
+ * configuring a menu. Refer to <a href="Action.html#buttonActions">
+ * Swing Components Supporting <code>Action</code></a> for more
+ * details, and you can find more information in <a
+- * href="http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
++ * href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
+ * to Use Actions</a>, a section in <em>The Java Tutorial</em>.
+ * <p>
+ * For information and examples of using menus see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
+ * a section in <em>The Java Tutorial.</em>
+ * <p>
+ * <strong>Warning:</strong> Swing is not thread safe. For more
+--- ./jdk/src/share/classes/javax/swing/JMenuBar.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JMenuBar.java Wed Feb 04 12:14:43 2015 -0800
+@@ -54,7 +54,7 @@
+ * <p>
+ * For information and examples of using menu bars see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
+ * a section in <em>The Java Tutorial.</em>
+ * <p>
+ * <strong>Warning:</strong> Swing is not thread safe. For more
+--- ./jdk/src/share/classes/javax/swing/JMenuItem.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JMenuItem.java Wed Feb 04 12:14:43 2015 -0800
+@@ -54,12 +54,12 @@
+ * configuring a menu item. Refer to <a href="Action.html#buttonActions">
+ * Swing Components Supporting <code>Action</code></a> for more
+ * details, and you can find more information in <a
+- * href="http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
++ * href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
+ * to Use Actions</a>, a section in <em>The Java Tutorial</em>.
+ * <p>
+ * For further documentation and for examples, see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>
+ * in <em>The Java Tutorial.</em>
+ * <p>
+ * <strong>Warning:</strong> Swing is not thread safe. For more
+--- ./jdk/src/share/classes/javax/swing/JOptionPane.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JOptionPane.java Wed Feb 04 12:14:43 2015 -0800
+@@ -62,7 +62,7 @@
+ * prompts users for a value or informs them of something.
+ * For information about using <code>JOptionPane</code>, see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html">How to Make Dialogs</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html">How to Make Dialogs</a>,
+ * a section in <em>The Java Tutorial</em>.
+ *
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/JPanel.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JPanel.java Wed Feb 04 12:14:43 2015 -0800
+@@ -39,7 +39,7 @@
+ * <code>JPanel</code> is a generic lightweight container.
+ * For examples and task-oriented documentation for JPanel, see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/panel.html">How to Use Panels</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/panel.html">How to Use Panels</a>,
+ * a section in <em>The Java Tutorial</em>.
+ * <p>
+ * <strong>Warning:</strong> Swing is not thread safe. For more
+--- ./jdk/src/share/classes/javax/swing/JPasswordField.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JPasswordField.java Wed Feb 04 12:14:43 2015 -0800
+@@ -39,7 +39,7 @@
+ * the editing of a single line of text where the view indicates
+ * something was typed, but does not show the original characters.
+ * You can find further information and examples in
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html">How to Use Text Fields</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html">How to Use Text Fields</a>,
+ * a section in <em>The Java Tutorial.</em>
+ * <p>
+ * <code>JPasswordField</code> is intended
+--- ./jdk/src/share/classes/javax/swing/JPopupMenu.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JPopupMenu.java Wed Feb 04 12:14:43 2015 -0800
+@@ -58,7 +58,7 @@
+ * <p>
+ * For information and examples of using popup menus, see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>
+ * in <em>The Java Tutorial.</em>
+ * <p>
+ * <strong>Warning:</strong> Swing is not thread safe. For more
+--- ./jdk/src/share/classes/javax/swing/JProgressBar.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JProgressBar.java Wed Feb 04 12:14:43 2015 -0800
+@@ -100,7 +100,7 @@
+ * <p>
+ *
+ * For complete examples and further documentation see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html" target="_top">How to Monitor Progress</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/progress.html" target="_top">How to Monitor Progress</a>,
+ * a section in <em>The Java Tutorial.</em>
+ *
+ * <p>
+@@ -910,7 +910,7 @@
+ * <p>
+ *
+ * See
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html" target="_top">How to Monitor Progress</a>
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/progress.html" target="_top">How to Monitor Progress</a>
+ * for examples of using indeterminate progress bars.
+ *
+ * @param newValue <code>true</code> if the progress bar
+--- ./jdk/src/share/classes/javax/swing/JRadioButton.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JRadioButton.java Wed Feb 04 12:14:43 2015 -0800
+@@ -57,10 +57,10 @@
+ * configuring a button. Refer to <a href="Action.html#buttonActions">
+ * Swing Components Supporting <code>Action</code></a> for more
+ * details, and you can find more information in <a
+- * href="http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
++ * href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
+ * to Use Actions</a>, a section in <em>The Java Tutorial</em>.
+ * <p>
+- * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>
++ * See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>
+ * in <em>The Java Tutorial</em>
+ * for further documentation.
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/JRadioButtonMenuItem.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JRadioButtonMenuItem.java Wed Feb 04 12:14:43 2015 -0800
+@@ -53,12 +53,12 @@
+ * configuring a menu item. Refer to <a href="Action.html#buttonActions">
+ * Swing Components Supporting <code>Action</code></a> for more
+ * details, and you can find more information in <a
+- * href="http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
++ * href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
+ * to Use Actions</a>, a section in <em>The Java Tutorial</em>.
+ * <p>
+ * For further documentation and examples see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
+ * a section in <em>The Java Tutorial.</em>
+ * <p>
+ * <strong>Warning:</strong> Swing is not thread safe. For more
+--- ./jdk/src/share/classes/javax/swing/JRootPane.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JRootPane.java Wed Feb 04 12:14:43 2015 -0800
+@@ -43,7 +43,7 @@
+ * <code>JFrame</code>, <code>JDialog</code>, <code>JWindow</code>,
+ * <code>JApplet</code>, and <code>JInternalFrame</code>.
+ * For task-oriented information on functionality provided by root panes
+- * see <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html">How to Use Root Panes</a>,
++ * see <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html">How to Use Root Panes</a>,
+ * a section in <em>The Java Tutorial</em>.
+ *
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/JScrollPane.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JScrollPane.java Wed Feb 04 12:14:43 2015 -0800
+@@ -50,7 +50,7 @@
+ * vertical and horizontal scroll bars, and optional row and
+ * column heading viewports.
+ * You can find task-oriented documentation of <code>JScrollPane</code> in
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html">How to Use Scroll Panes</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html">How to Use Scroll Panes</a>,
+ * a section in <em>The Java Tutorial</em>. Note that
+ * <code>JScrollPane</code> does not support heavyweight components.
+ *
+--- ./jdk/src/share/classes/javax/swing/JSeparator.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JSeparator.java Wed Feb 04 12:14:43 2015 -0800
+@@ -47,7 +47,7 @@
+ *
+ * For more information and examples see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
+ * a section in <em>The Java Tutorial.</em>
+ * <p>
+ * <strong>Warning:</strong> Swing is not thread safe. For more
+--- ./jdk/src/share/classes/javax/swing/JSlider.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JSlider.java Wed Feb 04 12:14:43 2015 -0800
+@@ -55,7 +55,7 @@
+ * <p>
+ * For further information and examples see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/slider.html">How to Use Sliders</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/slider.html">How to Use Sliders</a>,
+ * a section in <em>The Java Tutorial.</em>
+ * <p>
+ * <strong>Warning:</strong> Swing is not thread safe. For more
+--- ./jdk/src/share/classes/javax/swing/JSpinner.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JSpinner.java Wed Feb 04 12:14:43 2015 -0800
+@@ -93,7 +93,7 @@
+ * </pre>
+ * <p>
+ * For information and examples of using spinner see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/spinner.html">How to Use Spinners</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/spinner.html">How to Use Spinners</a>,
+ * a section in <em>The Java Tutorial.</em>
+ * <p>
+ * <strong>Warning:</strong> Swing is not thread safe. For more
+--- ./jdk/src/share/classes/javax/swing/JSplitPane.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JSplitPane.java Wed Feb 04 12:14:43 2015 -0800
+@@ -49,7 +49,7 @@
+ * interactively resized by the user.
+ * Information on using <code>JSplitPane</code> is in
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/splitpane.html">How to Use Split Panes</a> in
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/splitpane.html">How to Use Split Panes</a> in
+ * <em>The Java Tutorial</em>.
+ * <p>
+ * The two <code>Component</code>s in a split pane can be aligned
+--- ./jdk/src/share/classes/javax/swing/JTabbedPane.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JTabbedPane.java Wed Feb 04 12:14:43 2015 -0800
+@@ -43,7 +43,7 @@
+ * A component that lets the user switch between a group of components by
+ * clicking on a tab with a given title and/or icon.
+ * For examples and information on using tabbed panes see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/tabbedpane.html">How to Use Tabbed Panes</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/tabbedpane.html">How to Use Tabbed Panes</a>,
+ * a section in <em>The Java Tutorial</em>.
+ * <p>
+ * Tabs/components are added to a <code>TabbedPane</code> object by using the
+--- ./jdk/src/share/classes/javax/swing/JTable.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JTable.java Wed Feb 04 12:14:43 2015 -0800
+@@ -61,7 +61,7 @@
+ /**
+ * The <code>JTable</code> is used to display and edit regular two-dimensional tables
+ * of cells.
+- * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/table.html">How to Use Tables</a>
++ * See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/table.html">How to Use Tables</a>
+ * in <em>The Java Tutorial</em>
+ * for task-oriented documentation and examples of using <code>JTable</code>.
+ *
+@@ -2488,7 +2488,7 @@
+ * The default value of this property is defined by the look
+ * and feel implementation.
+ * <p>
+- * This is a <a href="http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html">JavaBeans</a> bound property.
++ * This is a <a href="https://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html">JavaBeans</a> bound property.
+ *
+ * @param selectionForeground the <code>Color</code> to use in the foreground
+ * for selected list items
+@@ -2526,7 +2526,7 @@
+ * The default value of this property is defined by the look
+ * and feel implementation.
+ * <p>
+- * This is a <a href="http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html">JavaBeans</a> bound property.
++ * This is a <a href="https://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html">JavaBeans</a> bound property.
+ *
+ * @param selectionBackground the <code>Color</code> to use for the background
+ * of selected cells
+--- ./jdk/src/share/classes/javax/swing/JTextArea.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JTextArea.java Wed Feb 04 12:14:43 2015 -0800
+@@ -44,7 +44,7 @@
+ * compatibility with the <code>java.awt.TextArea</code> class where it can
+ * reasonably do so.
+ * You can find information and examples of using all the text components in
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/text.html">Using Text Components</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/text.html">Using Text Components</a>,
+ * a section in <em>The Java Tutorial.</em>
+ *
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/JTextField.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JTextField.java Wed Feb 04 12:14:43 2015 -0800
+@@ -44,7 +44,7 @@
+ * of a single line of text.
+ * For information on and examples of using text fields,
+ * see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html">How to Use Text Fields</a>
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html">How to Use Text Fields</a>
+ * in <em>The Java Tutorial.</em>
+ *
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/JTextPane.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JTextPane.java Wed Feb 04 12:14:43 2015 -0800
+@@ -39,7 +39,7 @@
+ * A text component that can be marked up with attributes that are
+ * represented graphically.
+ * You can find how-to information and examples of using text panes in
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/text.html">Using Text Components</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/text.html">Using Text Components</a>,
+ * a section in <em>The Java Tutorial.</em>
+ *
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/JToggleButton.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JToggleButton.java Wed Feb 04 12:14:43 2015 -0800
+@@ -42,7 +42,7 @@
+ * are subclasses of this class.
+ * For information on using them see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>,
+ * a section in <em>The Java Tutorial</em>.
+ * <p>
+ * Buttons can be configured, and to some degree controlled, by
+@@ -51,7 +51,7 @@
+ * configuring a button. Refer to <a href="Action.html#buttonActions">
+ * Swing Components Supporting <code>Action</code></a> for more
+ * details, and you can find more information in <a
+- * href="http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
++ * href="https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html">How
+ * to Use Actions</a>, a section in <em>The Java Tutorial</em>.
+ * <p>
+ * <strong>Warning:</strong> Swing is not thread safe. For more
+--- ./jdk/src/share/classes/javax/swing/JToolBar.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JToolBar.java Wed Feb 04 12:14:43 2015 -0800
+@@ -52,7 +52,7 @@
+ * <code>JToolBar</code> provides a component that is useful for
+ * displaying commonly used <code>Action</code>s or controls.
+ * For examples and information on using tool bars see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/toolbar.html">How to Use Tool Bars</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/toolbar.html">How to Use Tool Bars</a>,
+ * a section in <em>The Java Tutorial</em>.
+ *
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/JToolTip.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JToolTip.java Wed Feb 04 12:14:43 2015 -0800
+@@ -44,7 +44,7 @@
+ * display can override <code>JComponent</code>'s <code>createToolTip</code>
+ * method and use a subclass of this class.
+ * <p>
+- * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How to Use Tool Tips</a>
++ * See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How to Use Tool Tips</a>
+ * in <em>The Java Tutorial</em>
+ * for further documentation.
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/JTree.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JTree.java Wed Feb 04 12:14:43 2015 -0800
+@@ -44,7 +44,7 @@
+ * <a name="jtree_description"></a>
+ * A control that displays a set of hierarchical data as an outline.
+ * You can find task-oriented documentation and examples of using trees in
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>,
+ * a section in <em>The Java Tutorial.</em>
+ * <p>
+ * A specific node in a tree can be identified either by a
+--- ./jdk/src/share/classes/javax/swing/JWindow.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/JWindow.java Wed Feb 04 12:14:43 2015 -0800
+@@ -315,7 +315,7 @@
+ * are currently typed to {@code JComponent}.
+ * <p>
+ * Please see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
+ * How to Use Drag and Drop and Data Transfer</a>, a section in
+ * <em>The Java Tutorial</em>, for more information.
+ *
+--- ./jdk/src/share/classes/javax/swing/ProgressMonitor.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/ProgressMonitor.java Wed Feb 04 12:14:43 2015 -0800
+@@ -71,7 +71,7 @@
+ *
+ * For further documentation and examples see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html">How to Monitor Progress</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/progress.html">How to Monitor Progress</a>,
+ * a section in <em>The Java Tutorial.</em>
+ *
+ * @see ProgressMonitorInputStream
+--- ./jdk/src/share/classes/javax/swing/ProgressMonitorInputStream.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/ProgressMonitorInputStream.java Wed Feb 04 12:14:43 2015 -0800
+@@ -54,7 +54,7 @@
+ * <p>
+ *
+ * For further documentation and examples see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html">How to Monitor Progress</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/progress.html">How to Monitor Progress</a>,
+ * a section in <em>The Java Tutorial.</em>
+ *
+ * @see ProgressMonitor
+--- ./jdk/src/share/classes/javax/swing/SortingFocusTraversalPolicy.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/SortingFocusTraversalPolicy.java Wed Feb 04 12:14:43 2015 -0800
+@@ -30,6 +30,11 @@
+ import java.util.*;
+ import java.awt.FocusTraversalPolicy;
+ import sun.util.logging.PlatformLogger;
++import java.lang.reflect.InvocationTargetException;
++import java.lang.reflect.Method;
++import sun.security.action.GetPropertyAction;
++import java.security.AccessController;
++import java.security.PrivilegedAction;
+
+ /**
+ * A FocusTraversalPolicy that determines traversal order by sorting the
+@@ -89,6 +94,34 @@
+ final private int FORWARD_TRAVERSAL = 0;
+ final private int BACKWARD_TRAVERSAL = 1;
+
++ /*
++ * When true (by default), the legacy merge-sort algo is used to sort an FTP cycle.
++ * When false, the default (tim-sort) algo is used, which may lead to an exception.
++ * See: JDK-8048887
++ */
++ private static final boolean legacySortingFTPEnabled;
++ private static final Method legacyMergeSortMethod;
++
++ static {
++ legacySortingFTPEnabled = "true".equals(AccessController.doPrivileged(
++ new GetPropertyAction("swing.legacySortingFTPEnabled", "true")));
++ legacyMergeSortMethod = legacySortingFTPEnabled ?
++ AccessController.doPrivileged(new PrivilegedAction<Method>() {
++ public Method run() {
++ try {
++ Class c = Class.forName("java.util.Arrays");
++ Method m = c.getDeclaredMethod("legacyMergeSort", new Class[]{Object[].class, Comparator.class});
++ m.setAccessible(true);
++ return m;
++ } catch (ClassNotFoundException | NoSuchMethodException e) {
++ // using default sorting algo
++ return null;
++ }
++ }
++ }) :
++ null;
++ }
++
+ /**
+ * Constructs a SortingFocusTraversalPolicy without a Comparator.
+ * Subclasses must set the Comparator using <code>setComparator</code>
+@@ -133,10 +166,32 @@
+ private void enumerateAndSortCycle(Container focusCycleRoot, List<Component> cycle) {
+ if (focusCycleRoot.isShowing()) {
+ enumerateCycle(focusCycleRoot, cycle);
+- Collections.sort(cycle, comparator);
++ if (!legacySortingFTPEnabled ||
++ !legacySort(cycle, comparator))
++ {
++ Collections.sort(cycle, comparator);
++ }
+ }
+ }
+
++ private boolean legacySort(List<Component> l, Comparator<? super Component> c) {
++ if (legacyMergeSortMethod == null)
++ return false;
++
++ Object[] a = l.toArray();
++ try {
++ legacyMergeSortMethod.invoke(null, a, c);
++ } catch (IllegalAccessException | InvocationTargetException e) {
++ return false;
++ }
++ ListIterator<Component> i = l.listIterator();
++ for (Object e : a) {
++ i.next();
++ i.set((Component)e);
++ }
++ return true;
++ }
++
+ private void enumerateCycle(Container container, List<Component> cycle) {
+ if (!(container.isVisible() && container.isDisplayable())) {
+ return;
+--- ./jdk/src/share/classes/javax/swing/Spring.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/Spring.java Wed Feb 04 12:14:43 2015 -0800
+@@ -109,7 +109,7 @@
+ * If you are implementing a <code>SpringLayout</code> you
+ * can find further information and examples in
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/layout/spring.html">How to Use SpringLayout</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/layout/spring.html">How to Use SpringLayout</a>,
+ * a section in <em>The Java Tutorial.</em>
+ * <p>
+ * <strong>Warning:</strong>
+--- ./jdk/src/share/classes/javax/swing/SpringLayout.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/SpringLayout.java Wed Feb 04 12:14:43 2015 -0800
+@@ -36,7 +36,7 @@
+ /**
+ * A <code>SpringLayout</code> lays out the children of its associated container
+ * according to a set of constraints.
+- * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/layout/spring.html">How to Use SpringLayout</a>
++ * See <a href="https://docs.oracle.com/javase/tutorial/uiswing/layout/spring.html">How to Use SpringLayout</a>
+ * in <em>The Java Tutorial</em> for examples of using
+ * <code>SpringLayout</code>.
+ *
+--- ./jdk/src/share/classes/javax/swing/SwingUtilities.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/SwingUtilities.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1278,7 +1278,7 @@
+ * <p>
+ * Additional documentation and examples for this method can be
+ * found in
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency in Swing</a>.
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency in Swing</a>.
+ * <p>
+ * As of 1.3 this method is just a cover for <code>java.awt.EventQueue.invokeLater()</code>.
+ * <p>
+@@ -1329,7 +1329,7 @@
+ * <p>
+ * Additional documentation and examples for this method can be
+ * found in
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency in Swing</a>.
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency in Swing</a>.
+ * <p>
+ * As of 1.3 this method is just a cover for
+ * <code>java.awt.EventQueue.invokeAndWait()</code>.
+--- ./jdk/src/share/classes/javax/swing/SwingWorker.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/SwingWorker.java Wed Feb 04 12:14:43 2015 -0800
+@@ -50,7 +50,7 @@
+ * When writing a multi-threaded application using Swing, there are
+ * two constraints to keep in mind:
+ * (refer to
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">
+ * Concurrency in Swing
+ * </a> for more details):
+ * <ul>
+--- ./jdk/src/share/classes/javax/swing/Timer.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/Timer.java Wed Feb 04 12:14:43 2015 -0800
+@@ -121,7 +121,7 @@
+ * <p>
+ * You can find further documentation
+ * and several examples of using timers by visiting
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html"
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html"
+ * target = "_top">How to Use Timers</a>,
+ * a section in <em>The Java Tutorial.</em>
+ * For more examples and help in choosing between
+--- ./jdk/src/share/classes/javax/swing/TransferHandler.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/TransferHandler.java Wed Feb 04 12:14:43 2015 -0800
+@@ -75,7 +75,7 @@
+ * of the transfer, and <code>setForeground</code> for the target of a transfer.
+ * <p>
+ * Please see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
+ * How to Use Drag and Drop and Data Transfer</a>,
+ * a section in <em>The Java Tutorial</em>, for more information.
+ *
+--- ./jdk/src/share/classes/javax/swing/WindowConstants.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/WindowConstants.java Wed Feb 04 12:14:43 2015 -0800
+@@ -36,7 +36,7 @@
+ * use these constants.
+ * For examples of setting the default window-closing operation, see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/frame.html#windowevents">Responding to Window-Closing Events</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/frame.html#windowevents">Responding to Window-Closing Events</a>,
+ * a section in <em>The Java Tutorial</em>.
+ * @see JFrame#setDefaultCloseOperation(int)
+ * @see JDialog#setDefaultCloseOperation(int)
+--- ./jdk/src/share/classes/javax/swing/border/Border.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/border/Border.java Wed Feb 04 12:14:43 2015 -0800
+@@ -33,7 +33,7 @@
+ * Interface describing an object capable of rendering a border
+ * around the edges of a swing component.
+ * For examples of using borders see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.htmll">How to Use Borders</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/border.htmll">How to Use Borders</a>,
+ * a section in <em>The Java Tutorial.</em>
+ * <p>
+ * In the Swing component set, borders supercede Insets as the
+--- ./jdk/src/share/classes/javax/swing/event/InternalFrameAdapter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/event/InternalFrameAdapter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -31,7 +31,7 @@
+ * convenience for creating listener objects, and is functionally
+ * equivalent to the WindowAdapter class in the AWT.
+ * <p>
+- * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/internalframelistener.html">How to Write an Internal Frame Listener</a>
++ * See <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/internalframelistener.html">How to Write an Internal Frame Listener</a>
+ * in <em>The Java Tutorial</em>
+ *
+ * @see InternalFrameEvent
+--- ./jdk/src/share/classes/javax/swing/event/InternalFrameEvent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/event/InternalFrameEvent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -34,7 +34,7 @@
+ * although different IDs are used.
+ * Help on handling internal frame events
+ * is in
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/internalframelistener.html" target="_top">How to Write an Internal Frame Listener</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/internalframelistener.html" target="_top">How to Write an Internal Frame Listener</a>,
+ * a section in <em>The Java Tutorial</em>.
+ * <p>
+ * <strong>Warning:</strong>
+--- ./jdk/src/share/classes/javax/swing/event/InternalFrameListener.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/event/InternalFrameListener.java Wed Feb 04 12:14:43 2015 -0800
+@@ -32,7 +32,7 @@
+ * This class is functionally equivalent to the WindowListener class
+ * in the AWT.
+ * <p>
+- * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/internalframelistener.html">How to Write an Internal Frame Listener</a>
++ * See <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/internalframelistener.html">How to Write an Internal Frame Listener</a>
+ * in <em>The Java Tutorial</em> for further documentation.
+ *
+ * @see java.awt.event.WindowListener
+--- ./jdk/src/share/classes/javax/swing/event/TreeExpansionEvent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/event/TreeExpansionEvent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -34,8 +34,8 @@
+ * <p>
+ * For further documentation and examples see
+ * the following sections in <em>The Java Tutorial</em>:
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/treeexpansionlistener.html">How to Write a Tree Expansion Listener</a> and
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/treewillexpandlistener.html">How to Write a Tree-Will-Expand Listener</a>.
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/treeexpansionlistener.html">How to Write a Tree Expansion Listener</a> and
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/treewillexpandlistener.html">How to Write a Tree-Will-Expand Listener</a>.
+ * <p>
+ * <strong>Warning:</strong>
+ * Serialized objects of this class will not be compatible with
+--- ./jdk/src/share/classes/javax/swing/event/TreeExpansionListener.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/event/TreeExpansionListener.java Wed Feb 04 12:14:43 2015 -0800
+@@ -32,7 +32,7 @@
+ * a node.
+ * For further documentation and examples see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/events/treeexpansionlistener.html">How to Write a Tree Expansion Listener</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/events/treeexpansionlistener.html">How to Write a Tree Expansion Listener</a>,
+ * a section in <em>The Java Tutorial.</em>
+ *
+ * @author Scott Violet
+--- ./jdk/src/share/classes/javax/swing/event/TreeModelEvent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/event/TreeModelEvent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -34,7 +34,7 @@
+ * used to notify tree model listeners of the change.
+ * For more information and examples see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/events/treemodellistener.html">How to Write a Tree Model Listener</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/events/treemodellistener.html">How to Write a Tree Model Listener</a>,
+ * a section in <em>The Java Tutorial.</em>
+ * <p>
+ * <strong>Warning:</strong>
+--- ./jdk/src/share/classes/javax/swing/event/TreeModelListener.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/event/TreeModelListener.java Wed Feb 04 12:14:43 2015 -0800
+@@ -32,7 +32,7 @@
+ * to changes in a TreeModel.
+ * For further information and examples see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/events/treemodellistener.html">How to Write a Tree Model Listener</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/events/treemodellistener.html">How to Write a Tree Model Listener</a>,
+ * a section in <em>The Java Tutorial.</em>
+ *
+ * @author Rob Davis
+--- ./jdk/src/share/classes/javax/swing/event/TreeSelectionListener.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/event/TreeSelectionListener.java Wed Feb 04 12:14:43 2015 -0800
+@@ -32,7 +32,7 @@
+ * changes.
+ * For more information and examples see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/events/treeselectionlistener.html">How to Write a Tree Selection Listener</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/events/treeselectionlistener.html">How to Write a Tree Selection Listener</a>,
+ * a section in <em>The Java Tutorial.</em>
+ *
+ * @see javax.swing.tree.TreeSelectionModel
+--- ./jdk/src/share/classes/javax/swing/event/TreeWillExpandListener.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/event/TreeWillExpandListener.java Wed Feb 04 12:14:43 2015 -0800
+@@ -32,7 +32,7 @@
+ * The listener that's notified when a tree expands or collapses
+ * a node.
+ * For further information and examples see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/treewillexpandlistener.html">How to Write a Tree-Will-Expand Listener</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/treewillexpandlistener.html">How to Write a Tree-Will-Expand Listener</a>,
+ * a section in <em>The Java Tutorial.</em>
+ *
+ * @author Scott Violet
+--- ./jdk/src/share/classes/javax/swing/filechooser/FileFilter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/filechooser/FileFilter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -39,7 +39,7 @@
+ * For an example implementation of a simple file filter, see
+ * <code><i>yourJDK</i>/demo/jfc/FileChooserDemo/ExampleFileFilter.java</code>.
+ * For more information and examples see
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/filechooser.html">How to Use File Choosers</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/filechooser.html">How to Use File Choosers</a>,
+ * a section in <em>The Java Tutorial</em>.
+ *
+ * @see FileNameExtensionFilter
+--- ./jdk/src/share/classes/javax/swing/filechooser/FileView.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/filechooser/FileView.java Wed Feb 04 12:14:43 2015 -0800
+@@ -57,7 +57,7 @@
+ * <code><i>yourJDK</i>/demo/jfc/FileChooserDemo/ExampleFileView.java</code>.
+ * For more information and examples see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/filechooser.html">How to Use File Choosers</a>,
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/filechooser.html">How to Use File Choosers</a>,
+ * a section in <em>The Java Tutorial</em>.
+ *
+ * @see javax.swing.JFileChooser
+--- ./jdk/src/share/classes/javax/swing/package.html Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/package.html Wed Feb 04 12:14:43 2015 -0800
+@@ -119,9 +119,9 @@
+ processing when working with Swing.
+ <p>
+ More information on this topic can be found in the
+-<a href="http://download.oracle.com/javase/tutorial/uiswing/">Swing tutorial</a>,
++<a href="https://docs.oracle.com/javase/tutorial/uiswing/">Swing tutorial</a>,
+ in particular the section on
+-<a href="http://download.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency in Swing</a>.
++<a href="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency in Swing</a>.
+
+
+ <H2>
+--- ./jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -54,7 +54,7 @@
+ * <p>
+ * For adding specific actions,
+ * overide <code>installKeyboardActions</code> to add actions in response to
+- * KeyStroke bindings. See the article <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html">How to Use Key Bindings</a>
++ * KeyStroke bindings. See the article <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html">How to Use Key Bindings</a>
+ *
+ * @author Arnaud Weber
+ * @author Tom Santos
+--- ./jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java Wed Feb 04 12:14:43 2015 -0800
+@@ -31,16 +31,14 @@
+ import javax.accessibility.AccessibleContext;
+ import javax.swing.*;
+ import javax.swing.plaf.*;
+-import javax.swing.border.*;
+ import javax.swing.event.InternalFrameEvent;
+-import java.util.EventListener;
+ import java.beans.PropertyChangeListener;
+ import java.beans.PropertyChangeEvent;
+-import java.beans.VetoableChangeListener;
+ import java.beans.PropertyVetoException;
+
+ import sun.swing.DefaultLookup;
+-import sun.swing.UIAction;
++
++import static sun.swing.SwingUtilities2.AA_TEXT_PROPERTY_KEY;
+
+ /**
+ * The class that manages a basic title bar
+@@ -125,6 +123,12 @@
+ createButtons();
+ addSubComponents();
+
++ updateProperties();
++ }
++
++ private void updateProperties() {
++ final Object aaTextInfo = frame.getClientProperty(AA_TEXT_PROPERTY_KEY);
++ putClientProperty(AA_TEXT_PROPERTY_KEY, aaTextInfo);
+ }
+
+ protected void addSubComponents() {
+--- ./jdk/src/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -33,7 +33,8 @@
+ import javax.swing.text.View;
+ import sun.swing.SwingUtilities2;
+ import sun.awt.AppContext;
+-
++import java.util.Enumeration;
++import java.util.HashSet;
+
+ /**
+ * RadioButtonUI implementation for BasicRadioButtonUI
+@@ -44,15 +45,27 @@
+ {
+ private static final Object BASIC_RADIO_BUTTON_UI_KEY = new Object();
+
++ /**
++ * The icon.
++ */
+ protected Icon icon;
+
+ private boolean defaults_initialized = false;
+
+ private final static String propertyPrefix = "RadioButton" + ".";
+
++ private KeyListener keyListener = null;
++
+ // ********************************
+ // Create PLAF
+ // ********************************
++
++ /**
++ * Returns an instance of {@code BasicRadioButtonUI}.
++ *
++ * @param b a component
++ * @return an instance of {@code BasicRadioButtonUI}
++ */
+ public static ComponentUI createUI(JComponent b) {
+ AppContext appContext = AppContext.getAppContext();
+ BasicRadioButtonUI radioButtonUI =
+@@ -64,6 +77,7 @@
+ return radioButtonUI;
+ }
+
++ @Override
+ protected String getPropertyPrefix() {
+ return propertyPrefix;
+ }
+@@ -71,7 +85,8 @@
+ // ********************************
+ // Install PLAF
+ // ********************************
+- protected void installDefaults(AbstractButton b){
++ @Override
++ protected void installDefaults(AbstractButton b) {
+ super.installDefaults(b);
+ if(!defaults_initialized) {
+ icon = UIManager.getIcon(getPropertyPrefix() + "icon");
+@@ -82,15 +97,80 @@
+ // ********************************
+ // Uninstall PLAF
+ // ********************************
+- protected void uninstallDefaults(AbstractButton b){
++ @Override
++ protected void uninstallDefaults(AbstractButton b) {
+ super.uninstallDefaults(b);
+ defaults_initialized = false;
+ }
+
++ /**
++ * Returns the default icon.
++ *
++ * @return the default icon
++ */
+ public Icon getDefaultIcon() {
+ return icon;
+ }
+
++ // ********************************
++ // Install Listeners
++ // ********************************
++ @Override
++ protected void installListeners(AbstractButton button) {
++ super.installListeners(button);
++
++ // Only for JRadioButton
++ if (!(button instanceof JRadioButton))
++ return;
++
++ keyListener = createKeyListener();
++ button.addKeyListener(keyListener);
++
++ // Need to get traversal key event
++ button.setFocusTraversalKeysEnabled(false);
++
++ // Map actions to the arrow keys
++ button.getActionMap().put("Previous", new SelectPreviousBtn());
++ button.getActionMap().put("Next", new SelectNextBtn());
++
++ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).
++ put(KeyStroke.getKeyStroke("UP"), "Previous");
++ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).
++ put(KeyStroke.getKeyStroke("DOWN"), "Next");
++ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).
++ put(KeyStroke.getKeyStroke("LEFT"), "Previous");
++ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).
++ put(KeyStroke.getKeyStroke("RIGHT"), "Next");
++ }
++
++ // ********************************
++ // UnInstall Listeners
++ // ********************************
++ @Override
++ protected void uninstallListeners(AbstractButton button) {
++ super.uninstallListeners(button);
++
++ // Only for JRadioButton
++ if (!(button instanceof JRadioButton))
++ return;
++
++ // Unmap actions from the arrow keys
++ button.getActionMap().remove("Previous");
++ button.getActionMap().remove("Next");
++ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
++ .remove(KeyStroke.getKeyStroke("UP"));
++ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
++ .remove(KeyStroke.getKeyStroke("DOWN"));
++ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
++ .remove(KeyStroke.getKeyStroke("LEFT"));
++ button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
++ .remove(KeyStroke.getKeyStroke("RIGHT"));
++
++ if (keyListener != null) {
++ button.removeKeyListener(keyListener);
++ keyListener = null;
++ }
++ }
+
+ /* These Dimensions/Rectangles are allocated once for all
+ * RadioButtonUI.paint() calls. Re-using rectangles
+@@ -106,6 +186,7 @@
+ /**
+ * paint the radio button
+ */
++ @Override
+ public synchronized void paint(Graphics g, JComponent c) {
+ AbstractButton b = (AbstractButton) c;
+ ButtonModel model = b.getModel();
+@@ -195,7 +276,14 @@
+ }
+ }
+
+- protected void paintFocus(Graphics g, Rectangle textRect, Dimension size){
++ /**
++ * Paints focused radio button.
++ *
++ * @param g an instance of {@code Graphics}
++ * @param textRect bounds
++ * @param size the size of radio button
++ */
++ protected void paintFocus(Graphics g, Rectangle textRect, Dimension size) {
+ }
+
+
+@@ -213,6 +301,7 @@
+ /**
+ * The preferred size of the radio button
+ */
++ @Override
+ public Dimension getPreferredSize(JComponent c) {
+ if(c.getComponentCount() > 0) {
+ return null;
+@@ -258,4 +347,262 @@
+ height += prefInsets.top + prefInsets.bottom;
+ return new Dimension(width, height);
+ }
++
++ /////////////////////////// Private functions ////////////////////////
++ /**
++ * Creates the key listener to handle tab navigation in JRadioButton Group.
++ */
++ private KeyListener createKeyListener() {
++ if (keyListener == null) {
++ keyListener = new KeyHandler();
++ }
++ return keyListener;
++ }
++
++
++ private boolean isValidRadioButtonObj(Object obj) {
++ return ((obj instanceof JRadioButton) &&
++ ((JRadioButton) obj).isVisible() &&
++ ((JRadioButton) obj).isEnabled());
++ }
++
++ /**
++ * Select radio button based on "Previous" or "Next" operation
++ *
++ * @param event, the event object.
++ * @param next, indicate if it's next one
++ */
++ private void selectRadioButton(ActionEvent event, boolean next) {
++ // Get the source of the event.
++ Object eventSrc = event.getSource();
++
++ // Check whether the source is JRadioButton, it so, whether it is visible
++ if (!isValidRadioButtonObj(eventSrc))
++ return;
++
++ ButtonGroupInfo btnGroupInfo = new ButtonGroupInfo((JRadioButton)eventSrc);
++ btnGroupInfo.selectNewButton(next);
++ }
++
++ /////////////////////////// Inner Classes ////////////////////////
++ @SuppressWarnings("serial")
++ private class SelectPreviousBtn extends AbstractAction {
++ public SelectPreviousBtn() {
++ super("Previous");
++ }
++
++ public void actionPerformed(ActionEvent e) {
++ BasicRadioButtonUI.this.selectRadioButton(e, false);
++ }
++ }
++
++ @SuppressWarnings("serial")
++ private class SelectNextBtn extends AbstractAction{
++ public SelectNextBtn() {
++ super("Next");
++ }
++
++ public void actionPerformed(ActionEvent e) {
++ BasicRadioButtonUI.this.selectRadioButton(e, true);
++ }
++ }
++
++ /**
++ * ButtonGroupInfo, used to get related info in button group
++ * for given radio button
++ */
++ private class ButtonGroupInfo {
++
++ JRadioButton activeBtn = null;
++
++ JRadioButton firstBtn = null;
++ JRadioButton lastBtn = null;
++
++ JRadioButton previousBtn = null;
++ JRadioButton nextBtn = null;
++
++ HashSet<JRadioButton> btnsInGroup = null;
++
++ boolean srcFound = false;
++ public ButtonGroupInfo(JRadioButton btn) {
++ activeBtn = btn;
++ btnsInGroup = new HashSet<JRadioButton>();
++ }
++
++ // Check if given object is in the button group
++ boolean containsInGroup(Object obj){
++ return btnsInGroup.contains(obj);
++ }
++
++ // Check if the next object to gain focus belongs
++ // to the button group or not
++ Component getFocusTransferBaseComponent(boolean next){
++ Component focusBaseComp = activeBtn;
++ Window container = SwingUtilities.getWindowAncestor(activeBtn);
++ if (container != null) {
++ FocusTraversalPolicy policy = container.getFocusTraversalPolicy();
++ Component comp = next ? policy.getComponentAfter(container, activeBtn)
++ : policy.getComponentBefore(container, activeBtn);
++
++ // If next component in the button group, use last/first button as base focus
++ // otherwise, use the activeBtn as the base focus
++ if (containsInGroup(comp)) {
++ focusBaseComp = next ? lastBtn : firstBtn;
++ }
++ }
++
++ return focusBaseComp;
++ }
++
++ boolean getButtonGroupInfo() {
++ if (activeBtn == null)
++ return false;
++
++ btnsInGroup.clear();
++
++ // Get the button model from the source.
++ ButtonModel model = activeBtn.getModel();
++ if (!(model instanceof DefaultButtonModel))
++ return false;
++
++ // If the button model is DefaultButtonModel, and use it, otherwise return.
++ DefaultButtonModel bm = (DefaultButtonModel) model;
++
++ // get the ButtonGroup of the button from the button model
++ ButtonGroup group = bm.getGroup();
++ if (group == null)
++ return false;
++
++ // Get all the buttons in the group
++ Enumeration<AbstractButton> e = group.getElements();
++ if (e == null)
++ return false;
++
++ while (e.hasMoreElements()) {
++ AbstractButton curElement = e.nextElement();
++ if (!isValidRadioButtonObj(curElement))
++ continue;
++
++ btnsInGroup.add((JRadioButton) curElement);
++
++ // If firstBtn is not set yet, curElement is that first button
++ if (null == firstBtn)
++ firstBtn = (JRadioButton) curElement;
++
++ if (activeBtn == curElement)
++ srcFound = true;
++ else if (!srcFound) {
++ // The source has not been yet found and the current element
++ // is the last previousBtn
++ previousBtn = (JRadioButton) curElement;
++ } else if (nextBtn == null) {
++ // The source has been found and the current element
++ // is the next valid button of the list
++ nextBtn = (JRadioButton) curElement;
++ }
++
++ // Set new last "valid" JRadioButton of the list
++ lastBtn = (JRadioButton) curElement;
++ }
++
++ return true;
++ }
++
++ /**
++ * Find the new radio button that focus needs to be
++ * moved to in the group, select the button
++ *
++ * @param next, indicate if it's arrow up/left or down/right
++ */
++ void selectNewButton(boolean next) {
++ if (!getButtonGroupInfo())
++ return;
++
++ if (srcFound) {
++ JRadioButton newSelectedBtn = null;
++ if (next) {
++ // Select Next button. Cycle to the first button if the source
++ // button is the last of the group.
++ newSelectedBtn = (null == nextBtn) ? firstBtn : nextBtn;
++ } else {
++ // Select previous button. Cycle to the last button if the source
++ // button is the first button of the group.
++ newSelectedBtn = (null == previousBtn) ? lastBtn : previousBtn;
++ }
++ if (newSelectedBtn != null &&
++ (newSelectedBtn != activeBtn)) {
++ newSelectedBtn.requestFocusInWindow();
++ newSelectedBtn.setSelected(true);
++ }
++ }
++ }
++
++ /**
++ * Find the button group the passed in JRadioButton belongs to, and
++ * move focus to next component of the last button in the group
++ * or previous component of first button
++ *
++ * @param next, indicate if jump to next component or previous
++ */
++ void jumpToNextComponent(boolean next) {
++ if (!getButtonGroupInfo()){
++ // In case the button does not belong to any group, it needs
++ // to be treated as a component
++ if (activeBtn != null){
++ lastBtn = activeBtn;
++ firstBtn = activeBtn;
++ }
++ else
++ return;
++ }
++
++ // Update the component we will use as base to transfer
++ // focus from
++ JComponent compTransferFocusFrom = activeBtn;
++
++ // If next component in the parent window is not in
++ // the button group, current active button will be
++ // base, otherwise, the base will be first or last
++ // button in the button group
++ Component focusBase = getFocusTransferBaseComponent(next);
++ if (focusBase != null){
++ if (next) {
++ KeyboardFocusManager.
++ getCurrentKeyboardFocusManager().focusNextComponent(focusBase);
++ } else {
++ KeyboardFocusManager.
++ getCurrentKeyboardFocusManager().focusPreviousComponent(focusBase);
++ }
++ }
++ }
++ }
++
++ /**
++ * Radiobutton KeyListener
++ */
++ private class KeyHandler implements KeyListener {
++
++ // This listener checks if the key event is a KeyEvent.VK_TAB
++ // or shift + KeyEvent.VK_TAB event on a radio button, consume the event
++ // if so and move the focus to next/previous component
++ public void keyPressed(KeyEvent e) {
++ if (e.getKeyCode() == KeyEvent.VK_TAB) {
++ // Get the source of the event.
++ Object eventSrc = e.getSource();
++
++ // Check whether the source is a visible and enabled JRadioButton
++ if (isValidRadioButtonObj(eventSrc)) {
++ e.consume();
++ ButtonGroupInfo btnGroupInfo = new ButtonGroupInfo((JRadioButton)eventSrc);
++ btnGroupInfo.jumpToNextComponent(!e.isShiftDown());
++ }
++ }
++ }
++
++ public void keyReleased(KeyEvent e) {
++ }
++
++ public void keyTyped(KeyEvent e) {
++ }
++ }
+ }
+--- ./jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java Wed Feb 04 12:14:43 2015 -0800
+@@ -3239,6 +3239,7 @@
+ }
+ }
+ tabScroller.tabPanel.setPreferredSize(new Dimension(totalWidth, totalHeight));
++ tabScroller.tabPanel.invalidate();
+ }
+ }
+
+@@ -3606,6 +3607,7 @@
+ setFocusIndex(tabPane.getSelectedIndex(), false);
+
+ if (scrollableTabLayoutEnabled()) {
++ ensureCurrentLayout();
+ int index = tabPane.getSelectedIndex();
+ if (index < rects.length && index != -1) {
+ tabScroller.tabPanel.scrollRectToVisible(
+--- ./jdk/src/share/classes/javax/swing/plaf/basic/BasicTransferable.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/plaf/basic/BasicTransferable.java Wed Feb 04 12:14:43 2015 -0800
+@@ -24,6 +24,8 @@
+ */
+ package javax.swing.plaf.basic;
+
++import sun.awt.datatransfer.DataTransferer;
++
+ import java.io.*;
+ import java.awt.datatransfer.*;
+ import javax.swing.plaf.UIResource;
+@@ -145,7 +147,7 @@
+ } else if (Reader.class.equals(flavor.getRepresentationClass())) {
+ return new StringReader(data);
+ } else if (InputStream.class.equals(flavor.getRepresentationClass())) {
+- return new StringBufferInputStream(data);
++ return createInputStream(flavor, data);
+ }
+ // fall through to unsupported
+ } else if (isPlainFlavor(flavor)) {
+@@ -156,7 +158,7 @@
+ } else if (Reader.class.equals(flavor.getRepresentationClass())) {
+ return new StringReader(data);
+ } else if (InputStream.class.equals(flavor.getRepresentationClass())) {
+- return new StringBufferInputStream(data);
++ return createInputStream(flavor, data);
+ }
+ // fall through to unsupported
+
+@@ -168,6 +170,15 @@
+ throw new UnsupportedFlavorException(flavor);
+ }
+
++ private InputStream createInputStream(DataFlavor flavor, String data)
++ throws IOException, UnsupportedFlavorException {
++ String cs = DataTransferer.getTextCharset(flavor);
++ if (cs == null) {
++ throw new UnsupportedFlavorException(flavor);
++ }
++ return new ByteArrayInputStream(data.getBytes(cs));
++ }
++
+ // --- richer subclass flavors ----------------------------------------------
+
+ protected boolean isRicherFlavor(DataFlavor flavor) {
+--- ./jdk/src/share/classes/javax/swing/table/TableModel.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/table/TableModel.java Wed Feb 04 12:14:43 2015 -0800
+@@ -40,7 +40,7 @@
+ * JTable table = new JTable(myData);
+ * </pre><p>
+ *
+- * For further documentation, see <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#data">Creating a Table Model</a>
++ * For further documentation, see <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/table.html#data">Creating a Table Model</a>
+ * in <em>The Java Tutorial</em>.
+ *
+ * @author Philip Milne
+--- ./jdk/src/share/classes/javax/swing/text/AbstractDocument.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/text/AbstractDocument.java Wed Feb 04 12:14:43 2015 -0800
+@@ -408,7 +408,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param r the renderer to execute
+@@ -569,7 +569,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param offs the starting offset &gt;= 0
+@@ -682,7 +682,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param offs the starting offset &gt;= 0
+@@ -816,7 +816,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param offs the position in the model &gt;= 0
+--- ./jdk/src/share/classes/javax/swing/text/DefaultCaret.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/text/DefaultCaret.java Wed Feb 04 12:14:43 2015 -0800
+@@ -237,7 +237,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ */
+ protected final synchronized void repaint() {
+--- ./jdk/src/share/classes/javax/swing/text/DefaultStyledDocument.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/text/DefaultStyledDocument.java Wed Feb 04 12:14:43 2015 -0800
+@@ -173,7 +173,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param offset the starting offset &gt;= 0
+@@ -426,7 +426,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param pos the offset from the start of the document &gt;= 0
+@@ -483,7 +483,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param offset the offset in the document &gt;= 0
+@@ -536,7 +536,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param offset the offset into the paragraph &gt;= 0
+--- ./jdk/src/share/classes/javax/swing/text/FlowView.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/text/FlowView.java Wed Feb 04 12:14:43 2015 -0800
+@@ -800,14 +800,22 @@
+ @Override
+ protected void forwardUpdate(DocumentEvent.ElementChange ec,
+ DocumentEvent e, Shape a, ViewFactory f) {
+- calculateUpdateIndexes(e);
+- // Send update event to all views followed by the changed place.
+- lastUpdateIndex = Math.max((getViewCount() - 1), 0);
+- for (int i = firstUpdateIndex; i <= lastUpdateIndex; i++) {
+- View v = getView(i);
+- if (v != null) {
+- Shape childAlloc = getChildAllocation(i, a);
+- forwardUpdateToView(v, e, childAlloc, f);
++ // Update the view responsible for the changed element by invocation of
++ // super method.
++ super.forwardUpdate(ec, e, a, f);
++ // Re-calculate the update indexes and update the views followed by
++ // the changed place. Note: we update the views only when insertion or
++ // removal takes place.
++ DocumentEvent.EventType type = e.getType();
++ if (type == DocumentEvent.EventType.INSERT ||
++ type == DocumentEvent.EventType.REMOVE) {
++ firstUpdateIndex = Math.min((lastUpdateIndex + 1), (getViewCount() - 1));
++ lastUpdateIndex = Math.max((getViewCount() - 1), 0);
++ for (int i = firstUpdateIndex; i <= lastUpdateIndex; i++) {
++ View v = getView(i);
++ if (v != null) {
++ v.updateAfterChange();
++ }
+ }
+ }
+ }
+--- ./jdk/src/share/classes/javax/swing/text/GlyphView.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/text/GlyphView.java Wed Feb 04 12:14:43 2015 -0800
+@@ -971,6 +971,14 @@
+ }
+ }
+
++ /** {@inheritDoc} */
++ @Override
++ void updateAfterChange() {
++ // Drop the break spots. They will be re-calculated during
++ // layout. It is necessary for proper line break calculation.
++ breakSpots = null;
++ }
++
+ /**
+ * Class to hold data needed to justify this GlyphView in a PargraphView.Row
+ */
+--- ./jdk/src/share/classes/javax/swing/text/JTextComponent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/text/JTextComponent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -82,7 +82,7 @@
+ * support).
+ * You can find information on how to use the functionality
+ * this class provides in
+- * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/generaltext.html">General Rules for Using Text Components</a>,
++ * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/generaltext.html">General Rules for Using Text Components</a>,
+ * a section in <em>The Java Tutorial.</em>
+ *
+ * <dl>
+@@ -2164,7 +2164,7 @@
+ * <p>
+ * This method is thread-safe, although most Swing methods are not. Please
+ * see <A
+- * HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">
++ * HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">
+ * Concurrency in Swing</A> for more information.
+ *
+ * <p>
+@@ -2422,7 +2422,7 @@
+ * <p>
+ * This method is thread-safe, although most Swing methods are not. Please
+ * see <A
+- * HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">
++ * HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">
+ * Concurrency in Swing</A> for more information.
+ *
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/text/PlainDocument.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/text/PlainDocument.java Wed Feb 04 12:14:43 2015 -0800
+@@ -100,7 +100,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param offs the starting offset &gt;= 0
+--- ./jdk/src/share/classes/javax/swing/text/StyleContext.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/text/StyleContext.java Wed Feb 04 12:14:43 2015 -0800
+@@ -292,7 +292,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param old the old attribute set
+@@ -321,7 +321,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param old the old attribute set
+@@ -349,7 +349,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param old the old set of attributes
+@@ -377,7 +377,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param old the old attribute set
+@@ -405,7 +405,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param old the old attribute set
+@@ -445,7 +445,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param a the set to reclaim
+--- ./jdk/src/share/classes/javax/swing/text/View.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/text/View.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1199,6 +1199,13 @@
+ }
+
+ /**
++ * Updates the view to reflect the changes.
++ */
++ void updateAfterChange() {
++ // Do nothing by default. Should be overridden in subclasses, if any.
++ }
++
++ /**
+ * Forwards the <code>DocumentEvent</code> to the give child view. This
+ * simply messages the view with a call to <code>insertUpdate</code>,
+ * <code>removeUpdate</code>, or <code>changedUpdate</code> depending
+--- ./jdk/src/share/classes/javax/swing/text/html/HTMLDocument.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/text/html/HTMLDocument.java Wed Feb 04 12:14:43 2015 -0800
+@@ -474,7 +474,7 @@
+ * <p>
+ * This method is thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @param offset the offset into the paragraph (must be at least 0)
+@@ -1376,8 +1376,13 @@
+ Element parent = elem.getParentElement();
+
+ if (parent != null) {
++ // If we are going to insert the string into the body
++ // section, it is necessary to set the corrsponding flag.
++ if (HTML.Tag.BODY.name.equals(parent.getName())) {
++ insertInBody = true;
++ }
+ int offset = elem.getEndOffset();
+- if (offset > getLength()) {
++ if (offset > (getLength() + 1)) {
+ offset--;
+ }
+ else if (elem.isLeaf() && getText(offset - 1, 1).
+@@ -1385,6 +1390,10 @@
+ offset--;
+ }
+ insertHTML(parent, offset, htmlText, false);
++ // Cleanup the flag, if any.
++ if (insertInBody) {
++ insertInBody = false;
++ }
+ }
+ }
+ }
+@@ -1823,6 +1832,11 @@
+ private static char[] NEWLINE;
+
+ /**
++ * Indicates that direct insertion to body section takes place.
++ */
++ private boolean insertInBody = false;
++
++ /**
+ * I18N property key.
+ *
+ * @see AbstractDocument#I18NProperty
+@@ -2571,7 +2585,9 @@
+ // Assume content should be added.
+ foundInsertTag(false);
+ foundInsertTag = true;
+- inParagraph = impliedP = true;
++ // If content is added directly to the body, it should
++ // be wrapped by p-implied.
++ inParagraph = impliedP = !insertInBody;
+ }
+ if (data.length >= 1) {
+ addContent(data, 0, data.length);
+--- ./jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java Wed Feb 04 12:14:43 2015 -0800
+@@ -36,7 +36,7 @@
+ * structure.
+ * For examples of using default mutable tree nodes, see
+ * <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
+ * in <em>The Java Tutorial.</em>
+ *
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/tree/DefaultTreeCellRenderer.java Wed Feb 04 12:14:43 2015 -0800
+@@ -49,7 +49,7 @@
+ * <code>DefaultTreeCellRenderer</code> is not opaque and
+ * unless you subclass paint you should not change this.
+ * See <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
+ * in <em>The Java Tutorial</em>
+ * for examples of customizing node display using this class.
+ * <p>
+--- ./jdk/src/share/classes/javax/swing/tree/DefaultTreeModel.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/tree/DefaultTreeModel.java Wed Feb 04 12:14:43 2015 -0800
+@@ -33,7 +33,7 @@
+ /**
+ * A simple tree data model that uses TreeNodes.
+ * For further information and examples that use DefaultTreeModel,
+- * see <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
++ * see <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
+ * in <em>The Java Tutorial.</em>
+ * <p>
+ * <strong>Warning:</strong>
+--- ./jdk/src/share/classes/javax/swing/tree/ExpandVetoException.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/tree/ExpandVetoException.java Wed Feb 04 12:14:43 2015 -0800
+@@ -30,7 +30,7 @@
+ /**
+ * Exception used to stop and expand/collapse from happening.
+ * See <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/events/treewillexpandlistener.html">How to Write a Tree-Will-Expand Listener</a>
++ href="https://docs.oracle.com/javase/tutorial/uiswing/events/treewillexpandlistener.html">How to Write a Tree-Will-Expand Listener</a>
+ * in <em>The Java Tutorial</em>
+ * for further information and examples.
+ *
+--- ./jdk/src/share/classes/javax/swing/tree/TreeCellRenderer.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/tree/TreeCellRenderer.java Wed Feb 04 12:14:43 2015 -0800
+@@ -30,7 +30,7 @@
+ /**
+ * Defines the requirements for an object that displays a tree node.
+ * See <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
+ * in <em>The Java Tutorial</em>
+ * for an example of implementing a tree cell renderer
+ * that displays custom icons.
+--- ./jdk/src/share/classes/javax/swing/tree/TreeModel.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/tree/TreeModel.java Wed Feb 04 12:14:43 2015 -0800
+@@ -50,7 +50,7 @@
+ * For further information on tree models,
+ * including an example of a custom implementation,
+ * see <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
+ * in <em>The Java Tutorial.</em>
+ *
+ * @see TreePath
+--- ./jdk/src/share/classes/javax/swing/tree/TreeNode.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/tree/TreeNode.java Wed Feb 04 12:14:43 2015 -0800
+@@ -37,7 +37,7 @@
+ *
+ * For further information and examples of using tree nodes,
+ * see <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Tree Nodes</a>
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Tree Nodes</a>
+ * in <em>The Java Tutorial.</em>
+ *
+ * @author Rob Davis
+--- ./jdk/src/share/classes/javax/swing/tree/TreePath.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/tree/TreePath.java Wed Feb 04 12:14:43 2015 -0800
+@@ -66,7 +66,7 @@
+ * <p>
+ * For further information and examples of using tree paths,
+ * see <a
+- href="http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
++ href="https://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
+ * in <em>The Java Tutorial.</em>
+ * <p>
+ * <strong>Warning:</strong>
+--- ./jdk/src/share/classes/javax/swing/tree/TreeSelectionModel.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/javax/swing/tree/TreeSelectionModel.java Wed Feb 04 12:14:43 2015 -0800
+@@ -32,7 +32,7 @@
+ * This interface represents the current state of the selection for
+ * the tree component.
+ * For information and examples of using tree selection models,
+- * see <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
++ * see <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
+ * in <em>The Java Tutorial.</em>
+ *
+ * <p>
+--- ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1858,7 +1858,7 @@
+ break;
+ case 'B': // pointer to CONSTANT_Byte
+ av.visit(name,
+- new Byte((byte) readInt(items[readUnsignedShort(v)])));
++ (byte) readInt(items[readUnsignedShort(v)]));
+ v += 2;
+ break;
+ case 'Z': // pointer to CONSTANT_Boolean
+@@ -1868,13 +1868,13 @@
+ v += 2;
+ break;
+ case 'S': // pointer to CONSTANT_Short
+- av.visit(name, new Short(
+- (short) readInt(items[readUnsignedShort(v)])));
++ av.visit(name,
++ (short) readInt(items[readUnsignedShort(v)]));
+ v += 2;
+ break;
+ case 'C': // pointer to CONSTANT_Char
+- av.visit(name, new Character(
+- (char) readInt(items[readUnsignedShort(v)])));
++ av.visit(name,
++ (char) readInt(items[readUnsignedShort(v)]));
+ v += 2;
+ break;
+ case 's': // pointer to CONSTANT_Utf8
+@@ -2498,13 +2498,13 @@
+ int index = items[item];
+ switch (b[index - 1]) {
+ case ClassWriter.INT:
+- return new Integer(readInt(index));
++ return readInt(index);
+ case ClassWriter.FLOAT:
+- return new Float(Float.intBitsToFloat(readInt(index)));
++ return Float.intBitsToFloat(readInt(index));
+ case ClassWriter.LONG:
+- return new Long(readLong(index));
++ return readLong(index);
+ case ClassWriter.DOUBLE:
+- return new Double(Double.longBitsToDouble(readLong(index)));
++ return Double.longBitsToDouble(readLong(index));
+ case ClassWriter.CLASS:
+ return Type.getObjectType(readUTF8(index, buf));
+ case ClassWriter.STR:
+--- ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/TypePath.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/TypePath.java Wed Feb 04 12:14:43 2015 -0800
+@@ -181,6 +181,9 @@
+ typeArg = typeArg * 10 + c - '0';
+ i += 1;
+ }
++ if (i < n && typePath.charAt(i) == ';') {
++ i += 1;
++ }
+ out.put11(TYPE_ARGUMENT, typeArg);
+ }
+ }
+@@ -193,7 +196,7 @@
+ * ARRAY_ELEMENT} steps are represented with '[', {@link #INNER_TYPE
+ * INNER_TYPE} steps with '.', {@link #WILDCARD_BOUND WILDCARD_BOUND} steps
+ * with '*' and {@link #TYPE_ARGUMENT TYPE_ARGUMENT} steps with their type
+- * argument index in decimal form.
++ * argument index in decimal form followed by ';'.
+ */
+ @Override
+ public String toString() {
+@@ -211,7 +214,7 @@
+ result.append('*');
+ break;
+ case TYPE_ARGUMENT:
+- result.append(getStepArgument(i));
++ result.append(getStepArgument(i)).append(';');
+ break;
+ default:
+ result.append('_');
+--- ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -408,7 +408,7 @@
+ } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
+ mv.visitIntInsn(Opcodes.SIPUSH, value);
+ } else {
+- mv.visitLdcInsn(new Integer(value));
++ mv.visitLdcInsn(value);
+ }
+ }
+
+@@ -422,7 +422,7 @@
+ if (value == 0L || value == 1L) {
+ mv.visitInsn(Opcodes.LCONST_0 + (int) value);
+ } else {
+- mv.visitLdcInsn(new Long(value));
++ mv.visitLdcInsn(value);
+ }
+ }
+
+@@ -437,7 +437,7 @@
+ if (bits == 0L || bits == 0x3f800000 || bits == 0x40000000) { // 0..2
+ mv.visitInsn(Opcodes.FCONST_0 + (int) value);
+ } else {
+- mv.visitLdcInsn(new Float(value));
++ mv.visitLdcInsn(value);
+ }
+ }
+
+@@ -452,7 +452,7 @@
+ if (bits == 0L || bits == 0x3ff0000000000000L) { // +0.0d and 1.0d
+ mv.visitInsn(Opcodes.DCONST_0 + (int) value);
+ } else {
+- mv.visitLdcInsn(new Double(value));
++ mv.visitLdcInsn(value);
+ }
+ }
+
+@@ -1647,11 +1647,13 @@
+ */
+ public void catchException(final Label start, final Label end,
+ final Type exception) {
++ Label doCatch = new Label();
+ if (exception == null) {
+- mv.visitTryCatchBlock(start, end, mark(), null);
++ mv.visitTryCatchBlock(start, end, doCatch, null);
+ } else {
+- mv.visitTryCatchBlock(start, end, mark(),
++ mv.visitTryCatchBlock(start, end, doCatch,
+ exception.getInternalName());
+ }
++ mark(doCatch);
+ }
+ }
+--- ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -737,7 +737,7 @@
+ } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
+ mv.visitIntInsn(Opcodes.SIPUSH, cst);
+ } else {
+- mv.visitLdcInsn(new Integer(cst));
++ mv.visitLdcInsn(cst);
+ }
+ }
+
+@@ -745,7 +745,7 @@
+ if (cst == 0L || cst == 1L) {
+ mv.visitInsn(Opcodes.LCONST_0 + (int) cst);
+ } else {
+- mv.visitLdcInsn(new Long(cst));
++ mv.visitLdcInsn(cst);
+ }
+ }
+
+@@ -754,7 +754,7 @@
+ if (bits == 0L || bits == 0x3f800000 || bits == 0x40000000) { // 0..2
+ mv.visitInsn(Opcodes.FCONST_0 + (int) cst);
+ } else {
+- mv.visitLdcInsn(new Float(cst));
++ mv.visitLdcInsn(cst);
+ }
+ }
+
+@@ -763,7 +763,7 @@
+ if (bits == 0L || bits == 0x3ff0000000000000L) { // +0.0d and 1.0d
+ mv.visitInsn(Opcodes.DCONST_0 + (int) cst);
+ } else {
+- mv.visitLdcInsn(new Double(cst));
++ mv.visitLdcInsn(cst);
+ }
+ }
+
+--- ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java Wed Feb 04 12:14:43 2015 -0800
+@@ -366,8 +366,7 @@
+
+ protected void addSVUID(long svuid) {
+ FieldVisitor fv = super.visitField(Opcodes.ACC_FINAL
+- + Opcodes.ACC_STATIC, "serialVersionUID", "J", null, new Long(
+- svuid));
++ + Opcodes.ACC_STATIC, "serialVersionUID", "J", null, svuid);
+ if (fv != null) {
+ fv.visitEnd();
+ }
+--- ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java Wed Feb 04 12:14:43 2015 -0800
+@@ -247,11 +247,13 @@
+ an.accept(av.visitAnnotation(name, an.desc));
+ } else if (value instanceof List) {
+ AnnotationVisitor v = av.visitArray(name);
+- List<?> array = (List<?>) value;
+- for (int j = 0; j < array.size(); ++j) {
+- accept(v, null, array.get(j));
++ if (v != null) {
++ List<?> array = (List<?>) value;
++ for (int j = 0; j < array.size(); ++j) {
++ accept(v, null, array.get(j));
++ }
++ v.visitEnd();
+ }
+- v.visitEnd();
+ } else {
+ av.visit(name, value);
+ }
+--- ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java Wed Feb 04 12:14:43 2015 -0800
+@@ -550,6 +550,7 @@
+ }
+
+ // this class is not generified because it will create bridges
++ @SuppressWarnings("rawtypes")
+ private final class InsnListIterator implements ListIterator {
+
+ AbstractInsnNode next;
+--- ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LookupSwitchInsnNode.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/LookupSwitchInsnNode.java Wed Feb 04 12:14:43 2015 -0800
+@@ -110,7 +110,7 @@
+ : labels.length);
+ if (keys != null) {
+ for (int i = 0; i < keys.length; ++i) {
+- this.keys.add(new Integer(keys[i]));
++ this.keys.add(keys[i]);
+ }
+ }
+ if (labels != null) {
+--- ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodInsnNode.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodInsnNode.java Wed Feb 04 12:14:43 2015 -0800
+@@ -160,6 +160,7 @@
+ @Override
+ public void accept(final MethodVisitor mv) {
+ mv.visitMethodInsn(opcode, owner, name, desc, itf);
++ acceptAnnotations(mv);
+ }
+
+ @Override
+--- ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java Wed Feb 04 12:14:43 2015 -0800
+@@ -399,6 +399,7 @@
+ }
+
+ @Override
++ @SuppressWarnings("unchecked")
+ public AnnotationVisitor visitParameterAnnotation(final int parameter,
+ final String desc, final boolean visible) {
+ AnnotationNode an = new AnnotationNode(desc);
+--- ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Analyzer.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Analyzer.java Wed Feb 04 12:14:43 2015 -0800
+@@ -131,6 +131,7 @@
+ * @throws AnalyzerException
+ * if a problem occurs during the analysis.
+ */
++ @SuppressWarnings("unchecked")
+ public Frame<V>[] analyze(final String owner, final MethodNode m)
+ throws AnalyzerException {
+ if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0) {
+--- ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java Wed Feb 04 12:14:43 2015 -0800
+@@ -112,6 +112,7 @@
+ * @param nStack
+ * the maximum stack size of the frame.
+ */
++ @SuppressWarnings("unchecked")
+ public Frame(final int nLocals, final int nStack) {
+ this.values = (V[]) new Value[nLocals + nStack];
+ this.locals = nLocals;
+--- ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -802,7 +802,7 @@
+ if (labels.get(label) != null) {
+ throw new IllegalArgumentException("Already visited label");
+ }
+- labels.put(label, new Integer(insnCount));
++ labels.put(label, insnCount);
+ super.visitLabel(label);
+ }
+
+--- ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java Wed Feb 04 12:14:43 2015 -0800
+@@ -732,7 +732,7 @@
+ Textifier t = createTextifier();
+ text.add(t.getText());
+ text.add(visible ? ") // parameter " : ") // invisible, parameter ");
+- text.add(new Integer(parameter));
++ text.add(parameter);
+ text.add("\n");
+ return t;
+ }
+--- ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/version.txt Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/internal/org/objectweb/asm/version.txt Wed Feb 04 12:14:43 2015 -0800
+@@ -1,12 +1,12 @@
+ Path: .
+-Working Copy Root Path: /hudson/jobs/objectweb-pull/workspace/asm-svn-2014-05-27
++Working Copy Root Path: /hudson/jobs/objectweb-init/workspace/asm-svn-2014-10-15
+ URL: file:///svnroot/asm/trunk/asm
+ Repository Root: file:///svnroot/asm
+ Repository UUID: 271bd773-ee82-43a6-9b2b-1890ed8ce7f9
+-Revision: 1748
++Revision: 1772
+ Node Kind: directory
+ Schedule: normal
+ Last Changed Author: ebruneton
+-Last Changed Rev: 1747
+-Last Changed Date: 2014-05-24 10:22:13 +0200 (Sat, 24 May 2014)
++Last Changed Rev: 1772
++Last Changed Date: 2014-09-06 09:13:07 +0200 (Sat, 06 Sep 2014)
+
+--- ./jdk/src/share/classes/jdk/net/Sockets.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/jdk/net/Sockets.java Wed Feb 04 12:14:43 2015 -0800
+@@ -119,6 +119,8 @@
+ Throwable t = ((InvocationTargetException)e).getTargetException();
+ if (t instanceof IOException) {
+ throw (IOException)t;
++ } else if (t instanceof RuntimeException) {
++ throw (RuntimeException)t;
+ }
+ }
+ throw new RuntimeException(e);
+@@ -135,6 +137,8 @@
+ Throwable t = ((InvocationTargetException)e).getTargetException();
+ if (t instanceof IOException) {
+ throw (IOException)t;
++ } else if (t instanceof RuntimeException) {
++ throw (RuntimeException)t;
+ }
+ }
+ throw new RuntimeException(e);
+@@ -367,6 +371,7 @@
+ set = new HashSet<>();
+ set.add(StandardSocketOptions.SO_RCVBUF);
+ set.add(StandardSocketOptions.SO_REUSEADDR);
++ set.add(StandardSocketOptions.IP_TOS);
+ set = Collections.unmodifiableSet(set);
+ options.put(ServerSocket.class, set);
+
+--- ./jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java Wed Feb 04 12:14:43 2015 -0800
+@@ -221,8 +221,17 @@
+ }
+
+ OutputStream os = new UnsyncBufferedOutputStream(bos);
++
++ DOMSubTreeData subTree = new DOMSubTreeData(localSiElem, true);
+ try {
+- os.close();
++ ((DOMCanonicalizationMethod)
++ canonicalizationMethod).canonicalize(subTree, context, os);
++ } catch (TransformException te) {
++ throw new XMLSignatureException(te);
++ }
++
++ try {
++ os.flush();
+ } catch (IOException e) {
+ if (log.isLoggable(java.util.logging.Level.FINE)) {
+ log.log(java.util.logging.Level.FINE, e.getMessage(), e);
+@@ -230,15 +239,6 @@
+ // Impossible
+ }
+
+- DOMSubTreeData subTree = new DOMSubTreeData(localSiElem, true);
+-
+- try {
+- ((DOMCanonicalizationMethod)
+- canonicalizationMethod).canonicalize(subTree, context, bos);
+- } catch (TransformException te) {
+- throw new XMLSignatureException(te);
+- }
+-
+ byte[] signedInfoBytes = bos.toByteArray();
+
+ // this whole block should only be done if logging is enabled
+@@ -253,6 +253,15 @@
+ }
+
+ this.canonData = new ByteArrayInputStream(signedInfoBytes);
++
++ try {
++ os.close();
++ } catch (IOException e) {
++ if (log.isLoggable(java.util.logging.Level.FINE)) {
++ log.log(java.util.logging.Level.FINE, e.getMessage(), e);
++ }
++ // Impossible
++ }
+ }
+
+ public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
+--- ./jdk/src/share/classes/sun/awt/LightweightFrame.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/awt/LightweightFrame.java Wed Feb 04 12:14:43 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package sun.awt;
+
++import java.awt.Component;
+ import java.awt.Container;
+ import java.awt.Frame;
+ import java.awt.Graphics;
+@@ -33,6 +34,13 @@
+ import java.awt.MenuComponent;
+ import java.awt.Rectangle;
+ import java.awt.Toolkit;
++import java.awt.dnd.DragGestureEvent;
++import java.awt.dnd.DragGestureListener;
++import java.awt.dnd.DragGestureRecognizer;
++import java.awt.dnd.DragSource;
++import java.awt.dnd.DropTarget;
++import java.awt.dnd.InvalidDnDOperationException;
++import java.awt.dnd.peer.DragSourceContextPeer;
+ import java.awt.peer.FramePeer;
+
+ /**
+@@ -169,4 +177,27 @@
+ hostW = w;
+ hostH = h;
+ }
++
++ /**
++ * Create a drag gesture recognizer for the lightweight frame.
++ */
++ public abstract <T extends DragGestureRecognizer> T createDragGestureRecognizer(
++ Class<T> abstractRecognizerClass,
++ DragSource ds, Component c, int srcActions,
++ DragGestureListener dgl);
++
++ /**
++ * Create a drag source context peer for the lightweight frame.
++ */
++ public abstract DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException;
++
++ /**
++ * Adds a drop target to the lightweight frame.
++ */
++ public abstract void addDropTarget(DropTarget dt);
++
++ /**
++ * Removes a drop target from the lightweight frame.
++ */
++ public abstract void removeDropTarget(DropTarget dt);
+ }
+--- ./jdk/src/share/classes/sun/awt/SunToolkit.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/awt/SunToolkit.java Wed Feb 04 12:14:43 2015 -0800
+@@ -2051,6 +2051,19 @@
+ return isInstanceOf(cls.getSuperclass(), type);
+ }
+
++ protected static LightweightFrame getLightweightFrame(Component c) {
++ for (; c != null; c = c.getParent()) {
++ if (c instanceof LightweightFrame) {
++ return (LightweightFrame)c;
++ }
++ if (c instanceof Window) {
++ // Don't traverse owner windows
++ return null;
++ }
++ }
++ return null;
++ }
++
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // The following methods help set and identify whether a particular
+--- ./jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java Wed Feb 04 12:14:43 2015 -0800
+@@ -77,6 +77,7 @@
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.Iterator;
++import java.util.LinkedHashSet;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.SortedMap;
+@@ -1294,6 +1295,15 @@
+ // bytes and dump them into a byte array. For text flavors, decode back
+ // to a String and recur to reencode according to the requested format.
+ } else if (flavor.isRepresentationClassInputStream()) {
++
++ // Workaround to JDK-8024061: Exception thrown when drag and drop
++ // between two components is executed quickly.
++ // and JDK-8065098: JColorChooser no longer supports drag and drop
++ // between two JVM instances
++ if (!(obj instanceof InputStream)) {
++ return new byte[0];
++ }
++
+ try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
+ try (InputStream is = (InputStream)obj) {
+ boolean eof = false;
+@@ -2424,8 +2434,8 @@
+ * If there are no platform-specific mappings for this native, the method
+ * returns an empty <code>List</code>.
+ */
+- public List getPlatformMappingsForNative(String nat) {
+- return new ArrayList();
++ public LinkedHashSet<DataFlavor> getPlatformMappingsForNative(String nat) {
++ return new LinkedHashSet<>();
+ }
+
+ /**
+@@ -2433,8 +2443,8 @@
+ * If there are no platform-specific mappings for this flavor, the method
+ * returns an empty <code>List</code>.
+ */
+- public List getPlatformMappingsForFlavor(DataFlavor df) {
+- return new ArrayList();
++ public LinkedHashSet<String> getPlatformMappingsForFlavor(DataFlavor df) {
++ return new LinkedHashSet<>();
+ }
+
+ /**
+@@ -2895,6 +2905,14 @@
+ return comp;
+ }
+
++ if (flavor1.isFlavorTextType()) {
++ return 1;
++ }
++
++ if (flavor2.isFlavorTextType()) {
++ return -1;
++ }
++
+ // Next, look for application/x-java-* types. Prefer unknown
+ // MIME types because if the user provides his own data flavor,
+ // it will likely be the most descriptive one.
+--- ./jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java Wed Feb 04 12:14:43 2015 -0800
+@@ -239,13 +239,6 @@
+
+ if (localTransferable != null) {
+ return localTransferable.getTransferData(df);
+- } else if (df.isMimeTypeEqual(DataFlavor.javaJVMLocalObjectMimeType)) {
+- // Workaround to JDK-8024061: Exception thrown when drag and drop
+- // between two components is executed quickly.
+- // It is expected localTransferable is not null if javaJVMLocalObjectMimeType
+- // is used. Executing further results in ClassCastException, so null is
+- // returned here as no transfer data is available in this case.
+- return null;
+ }
+
+ if (dropStatus != STATUS_ACCEPT || dropComplete) {
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/src/share/classes/sun/awt/image/AbstractMultiResolutionImage.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,122 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 sun.awt.image;
++
++import java.awt.Graphics;
++import java.awt.Image;
++import java.awt.image.*;
++
++/**
++ * This class provides default implementations for the
++ * <code>MultiResolutionImage</code> interface. The developer needs only
++ * to subclass this abstract class and define the <code>getResolutionVariant</code>,
++ * <code>getResolutionVariants</code>, and <code>getBaseImage</code> methods.
++ *
++ *
++ * For example,
++ * {@code
++ * public class CustomMultiResolutionImage extends AbstractMultiResolutionImage {
++ *
++ * int baseImageIndex;
++ * Image[] resolutionVariants;
++ *
++ * public CustomMultiResolutionImage(int baseImageIndex,
++ * Image... resolutionVariants) {
++ * this.baseImageIndex = baseImageIndex;
++ * this.resolutionVariants = resolutionVariants;
++ * }
++ *
++ * @Override
++ * public Image getResolutionVariant(float logicalDPIX, float logicalDPIY,
++ * float baseImageWidth, float baseImageHeight,
++ * float destImageWidth, float destImageHeight) {
++ * // return a resolution variant based on the given logical DPI,
++ * // base image size, or destination image size
++ * }
++ *
++ * @Override
++ * public List<Image> getResolutionVariants() {
++ * return Arrays.asList(resolutionVariants);
++ * }
++ *
++ * protected Image getBaseImage() {
++ * return resolutionVariants[baseImageIndex];
++ * }
++ * }
++ * }
++ *
++ * @see java.awt.Image
++ * @see java.awt.image.MultiResolutionImage
++ *
++ */
++public abstract class AbstractMultiResolutionImage extends java.awt.Image
++ implements MultiResolutionImage {
++
++ /**
++ * @inheritDoc
++ */
++ @Override
++ public int getWidth(ImageObserver observer) {
++ return getBaseImage().getWidth(null);
++ }
++
++ /**
++ * @inheritDoc
++ */
++ @Override
++ public int getHeight(ImageObserver observer) {
++ return getBaseImage().getHeight(null);
++ }
++
++ /**
++ * @inheritDoc
++ */
++ @Override
++ public ImageProducer getSource() {
++ return getBaseImage().getSource();
++ }
++
++ /**
++ * @inheritDoc
++ */
++ @Override
++ public Graphics getGraphics() {
++ return getBaseImage().getGraphics();
++
++ }
++
++ /**
++ * @inheritDoc
++ */
++ @Override
++ public Object getProperty(String name, ImageObserver observer) {
++ return getBaseImage().getProperty(name, observer);
++ }
++
++ /**
++ * @return base image
++ */
++ protected abstract Image getBaseImage();
++}
+--- ./jdk/src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,185 +0,0 @@
+-/*
+- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 sun.awt.image;
+-
+-import java.awt.Dimension;
+-import java.awt.Image;
+-import java.awt.Graphics;
+-import java.awt.geom.Dimension2D;
+-import java.awt.image.BufferedImage;
+-import java.awt.image.ImageObserver;
+-import java.util.Arrays;
+-import java.util.List;
+-import java.util.function.Function;
+-import java.util.function.BiFunction;
+-import java.util.stream.Collectors;
+-
+-public class MultiResolutionBufferedImage extends BufferedImage
+- implements MultiResolutionImage {
+-
+- private final BiFunction<Integer, Integer, Image> mapper;
+- private final Dimension2D[] sizes;
+- private int availableInfo;
+-
+- public MultiResolutionBufferedImage(Image baseImage,
+- BiFunction<Integer, Integer, Image> mapper) {
+- this(baseImage, new Dimension[]{new Dimension(
+- baseImage.getWidth(null), baseImage.getHeight(null))
+- }, mapper);
+- }
+-
+- public MultiResolutionBufferedImage(Image baseImage,
+- Dimension2D[] sizes, BiFunction<Integer, Integer, Image> mapper) {
+- super(baseImage.getWidth(null), baseImage.getHeight(null),
+- BufferedImage.TYPE_INT_ARGB_PRE);
+- this.sizes = sizes;
+- this.mapper = mapper;
+- this.availableInfo = getInfo(baseImage);
+- Graphics g = getGraphics();
+- g.drawImage(baseImage, 0, 0, null);
+- g.dispose();
+- }
+-
+- @Override
+- public Image getResolutionVariant(int width, int height) {
+- int baseWidth = getWidth();
+- int baseHeight = getHeight();
+-
+- if (baseWidth == width && baseHeight == height) {
+- return this;
+- }
+-
+- ImageCache cache = ImageCache.getInstance();
+- ImageCacheKey key = new ImageCacheKey(this, width, height);
+- Image resolutionVariant = cache.getImage(key);
+- if (resolutionVariant == null) {
+- resolutionVariant = mapper.apply(width, height);
+- cache.setImage(key, resolutionVariant);
+- preload(resolutionVariant, availableInfo);
+- }
+-
+- return resolutionVariant;
+- }
+-
+- @Override
+- public List<Image> getResolutionVariants() {
+- return Arrays.stream(sizes).map((Function<Dimension2D, Image>) size
+- -> getResolutionVariant((int) size.getWidth(),
+- (int) size.getHeight())).collect(Collectors.toList());
+- }
+-
+- public MultiResolutionBufferedImage map(Function<Image, Image> mapper) {
+- return new MultiResolutionBufferedImage(mapper.apply(this), sizes,
+- (width, height) ->
+- mapper.apply(getResolutionVariant(width, height)));
+- }
+-
+- @Override
+- public int getWidth(ImageObserver observer) {
+- availableInfo |= ImageObserver.WIDTH;
+- return super.getWidth(observer);
+- }
+-
+- @Override
+- public int getHeight(ImageObserver observer) {
+- availableInfo |= ImageObserver.HEIGHT;
+- return super.getHeight(observer);
+- }
+-
+- @Override
+- public Object getProperty(String name, ImageObserver observer) {
+- availableInfo |= ImageObserver.PROPERTIES;
+- return super.getProperty(name, observer);
+- }
+-
+- private static int getInfo(Image image) {
+- if (image instanceof ToolkitImage) {
+- return ((ToolkitImage) image).getImageRep().check(
+- (img, infoflags, x, y, w, h) -> false);
+- }
+- return 0;
+- }
+-
+- private static void preload(Image image, int availableInfo) {
+- if (availableInfo != 0 && image instanceof ToolkitImage) {
+- ((ToolkitImage) image).preload(new ImageObserver() {
+- int flags = availableInfo;
+-
+- @Override
+- public boolean imageUpdate(Image img, int infoflags,
+- int x, int y, int width, int height) {
+- flags &= ~infoflags;
+- return (flags != 0) && ((infoflags
+- & (ImageObserver.ERROR | ImageObserver.ABORT)) == 0);
+- }
+- });
+- }
+- }
+-
+- private static class ImageCacheKey implements ImageCache.PixelsKey {
+-
+- private final int pixelCount;
+- private final int hash;
+-
+- private final int w;
+- private final int h;
+- private final Image baseImage;
+-
+- ImageCacheKey(final Image baseImage,
+- final int w, final int h) {
+- this.baseImage = baseImage;
+- this.w = w;
+- this.h = h;
+- this.pixelCount = w * h;
+- hash = hash();
+- }
+-
+- @Override
+- public int getPixelCount() {
+- return pixelCount;
+- }
+-
+- private int hash() {
+- int hash = baseImage.hashCode();
+- hash = 31 * hash + w;
+- hash = 31 * hash + h;
+- return hash;
+- }
+-
+- @Override
+- public int hashCode() {
+- return hash;
+- }
+-
+- @Override
+- public boolean equals(Object obj) {
+- if (obj instanceof ImageCacheKey) {
+- ImageCacheKey key = (ImageCacheKey) obj;
+- return baseImage == key.baseImage && w == key.w && h == key.h;
+- }
+- return false;
+- }
+- }
+-}
+\ No newline at end of file
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/src/share/classes/sun/awt/image/MultiResolutionCachedImage.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,181 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 sun.awt.image;
++
++import java.awt.Dimension;
++import java.awt.Image;
++import java.awt.geom.Dimension2D;
++import java.awt.image.ImageObserver;
++import java.util.Arrays;
++import java.util.List;
++import java.util.function.Function;
++import java.util.function.BiFunction;
++import java.util.stream.Collectors;
++
++public class MultiResolutionCachedImage extends AbstractMultiResolutionImage {
++
++ private final int baseImageWidth;
++ private final int baseImageHeight;
++ private final Dimension2D[] sizes;
++ private final BiFunction<Integer, Integer, Image> mapper;
++ private int availableInfo;
++
++ public MultiResolutionCachedImage(int baseImageWidth, int baseImageHeight,
++ BiFunction<Integer, Integer, Image> mapper) {
++ this(baseImageWidth, baseImageHeight, new Dimension[]{new Dimension(
++ baseImageWidth, baseImageHeight)
++ }, mapper);
++ }
++
++ public MultiResolutionCachedImage(int baseImageWidth, int baseImageHeight,
++ Dimension2D[] sizes, BiFunction<Integer, Integer, Image> mapper) {
++ this.baseImageWidth = baseImageWidth;
++ this.baseImageHeight = baseImageHeight;
++ this.sizes = (sizes == null) ? null : Arrays.copyOf(sizes, sizes.length);
++ this.mapper = mapper;
++ }
++
++ @Override
++ public Image getResolutionVariant(int width, int height) {
++ ImageCache cache = ImageCache.getInstance();
++ ImageCacheKey key = new ImageCacheKey(this, width, height);
++ Image resolutionVariant = cache.getImage(key);
++ if (resolutionVariant == null) {
++ resolutionVariant = mapper.apply(width, height);
++ cache.setImage(key, resolutionVariant);
++ }
++ preload(resolutionVariant, availableInfo);
++ return resolutionVariant;
++ }
++
++ @Override
++ public List<Image> getResolutionVariants() {
++ return Arrays.stream(sizes).map((Function<Dimension2D, Image>) size
++ -> getResolutionVariant((int) size.getWidth(),
++ (int) size.getHeight())).collect(Collectors.toList());
++ }
++
++ public MultiResolutionCachedImage map(Function<Image, Image> mapper) {
++ return new MultiResolutionCachedImage(baseImageWidth, baseImageHeight,
++ sizes, (width, height) ->
++ mapper.apply(getResolutionVariant(width, height)));
++ }
++
++ @Override
++ public int getWidth(ImageObserver observer) {
++ updateInfo(observer, ImageObserver.WIDTH);
++ return super.getWidth(observer);
++ }
++
++ @Override
++ public int getHeight(ImageObserver observer) {
++ updateInfo(observer, ImageObserver.HEIGHT);
++ return super.getHeight(observer);
++ }
++
++ @Override
++ public Object getProperty(String name, ImageObserver observer) {
++ updateInfo(observer, ImageObserver.PROPERTIES);
++ return super.getProperty(name, observer);
++ }
++
++ @Override
++ protected Image getBaseImage() {
++ return getResolutionVariant(baseImageWidth, baseImageHeight);
++ }
++
++ private void updateInfo(ImageObserver observer, int info) {
++ availableInfo |= (observer == null) ? ImageObserver.ALLBITS : info;
++ }
++
++ private static int getInfo(Image image) {
++ if (image instanceof ToolkitImage) {
++ return ((ToolkitImage) image).getImageRep().check(
++ (img, infoflags, x, y, w, h) -> false);
++ }
++ return 0;
++ }
++
++ private static void preload(Image image, int availableInfo) {
++ if (availableInfo != 0 && image instanceof ToolkitImage) {
++ ((ToolkitImage) image).preload(new ImageObserver() {
++ int flags = availableInfo;
++
++ @Override
++ public boolean imageUpdate(Image img, int infoflags,
++ int x, int y, int width, int height) {
++ flags &= ~infoflags;
++ return (flags != 0) && ((infoflags
++ & (ImageObserver.ERROR | ImageObserver.ABORT)) == 0);
++ }
++ });
++ }
++ }
++
++ private static class ImageCacheKey implements ImageCache.PixelsKey {
++
++ private final int pixelCount;
++ private final int hash;
++
++ private final int w;
++ private final int h;
++ private final Image baseImage;
++
++ ImageCacheKey(final Image baseImage,
++ final int w, final int h) {
++ this.baseImage = baseImage;
++ this.w = w;
++ this.h = h;
++ this.pixelCount = w * h;
++ hash = hash();
++ }
++
++ @Override
++ public int getPixelCount() {
++ return pixelCount;
++ }
++
++ private int hash() {
++ int hash = baseImage.hashCode();
++ hash = 31 * hash + w;
++ hash = 31 * hash + h;
++ return hash;
++ }
++
++ @Override
++ public int hashCode() {
++ return hash;
++ }
++
++ @Override
++ public boolean equals(Object obj) {
++ if (obj instanceof ImageCacheKey) {
++ ImageCacheKey key = (ImageCacheKey) obj;
++ return baseImage == key.baseImage && w == key.w && h == key.h;
++ }
++ return false;
++ }
++ }
++}
+\ No newline at end of file
+--- ./jdk/src/share/classes/sun/awt/image/MultiResolutionToolkitImage.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/awt/image/MultiResolutionToolkitImage.java Wed Feb 04 12:14:43 2015 -0800
+@@ -80,7 +80,7 @@
+ }
+
+ synchronized (ObserverCache.INSTANCE) {
+- ImageObserver o = (ImageObserver) ObserverCache.INSTANCE.get(image);
++ ImageObserver o = (ImageObserver) ObserverCache.INSTANCE.get(observer);
+
+ if (o == null) {
+
+@@ -109,7 +109,7 @@
+ image, flags, x, y, width, height);
+ };
+
+- ObserverCache.INSTANCE.put(image, o);
++ ObserverCache.INSTANCE.put(observer, o);
+ }
+ return o;
+ }
+--- ./jdk/src/share/classes/sun/font/SunFontManager.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/font/SunFontManager.java Wed Feb 04 12:14:43 2015 -0800
+@@ -3182,7 +3182,7 @@
+ * Returns an array of two strings. The first element is the
+ * name of the font. The second element is the file name.
+ */
+- public abstract String[] getDefaultPlatformFont();
++ protected abstract String[] getDefaultPlatformFont();
+
+ // Begin: Refactored from SunGraphicsEnviroment.
+
+--- ./jdk/src/share/classes/sun/invoke/util/ValueConversions.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/invoke/util/ValueConversions.java Wed Feb 04 12:14:43 2015 -0800
+@@ -29,38 +29,34 @@
+ import java.lang.invoke.MethodHandles;
+ import java.lang.invoke.MethodHandles.Lookup;
+ import java.lang.invoke.MethodType;
+-import java.security.AccessController;
+-import java.security.PrivilegedAction;
+-import java.util.ArrayList;
+-import java.util.Arrays;
+-import java.util.Collections;
+ import java.util.EnumMap;
+-import java.util.List;
+
+ public class ValueConversions {
+ private static final Class<?> THIS_CLASS = ValueConversions.class;
+- // Do not adjust this except for special platforms:
+- private static final int MAX_ARITY;
+- static {
+- final Object[] values = { 255 };
+- AccessController.doPrivileged(new PrivilegedAction<Void>() {
+- @Override
+- public Void run() {
+- values[0] = Integer.getInteger(THIS_CLASS.getName()+".MAX_ARITY", 255);
+- return null;
+- }
+- });
+- MAX_ARITY = (Integer) values[0];
++ private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
++
++ /** Thread-safe canonicalized mapping from Wrapper to MethodHandle
++ * with unsynchronized reads and synchronized writes.
++ * It's safe to publish MethodHandles by data race because they are immutable. */
++ private static class WrapperCache {
++ /** EnumMap uses preconstructed array internally, which is constant during it's lifetime. */
++ private final EnumMap<Wrapper, MethodHandle> map = new EnumMap<>(Wrapper.class);
++
++ public MethodHandle get(Wrapper w) {
++ return map.get(w);
++ }
++ public synchronized MethodHandle put(final Wrapper w, final MethodHandle mh) {
++ // Simulate CAS to avoid racy duplication
++ MethodHandle prev = map.putIfAbsent(w, mh);
++ if (prev != null) return prev;
++ return mh;
++ }
+ }
+
+- private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
+-
+- private static EnumMap<Wrapper, MethodHandle>[] newWrapperCaches(int n) {
+- @SuppressWarnings("unchecked") // generic array creation
+- EnumMap<Wrapper, MethodHandle>[] caches
+- = (EnumMap<Wrapper, MethodHandle>[]) new EnumMap<?,?>[n];
++ private static WrapperCache[] newWrapperCaches(int n) {
++ WrapperCache[] caches = new WrapperCache[n];
+ for (int i = 0; i < n; i++)
+- caches[i] = new EnumMap<>(Wrapper.class);
++ caches[i] = new WrapperCache();
+ return caches;
+ }
+
+@@ -71,63 +67,92 @@
+ // implicit conversions sanctioned by JLS 5.1.2, etc.
+ // explicit conversions as allowed by explicitCastArguments
+
++ static int unboxInteger(Integer x) {
++ return x;
++ }
+ static int unboxInteger(Object x, boolean cast) {
+ if (x instanceof Integer)
+- return ((Integer) x).intValue();
++ return (Integer) x;
+ return primitiveConversion(Wrapper.INT, x, cast).intValue();
+ }
+
++ static byte unboxByte(Byte x) {
++ return x;
++ }
+ static byte unboxByte(Object x, boolean cast) {
+ if (x instanceof Byte)
+- return ((Byte) x).byteValue();
++ return (Byte) x;
+ return primitiveConversion(Wrapper.BYTE, x, cast).byteValue();
+ }
+
++ static short unboxShort(Short x) {
++ return x;
++ }
+ static short unboxShort(Object x, boolean cast) {
+ if (x instanceof Short)
+- return ((Short) x).shortValue();
++ return (Short) x;
+ return primitiveConversion(Wrapper.SHORT, x, cast).shortValue();
+ }
+
++ static boolean unboxBoolean(Boolean x) {
++ return x;
++ }
+ static boolean unboxBoolean(Object x, boolean cast) {
+ if (x instanceof Boolean)
+- return ((Boolean) x).booleanValue();
++ return (Boolean) x;
+ return (primitiveConversion(Wrapper.BOOLEAN, x, cast).intValue() & 1) != 0;
+ }
+
++ static char unboxCharacter(Character x) {
++ return x;
++ }
+ static char unboxCharacter(Object x, boolean cast) {
+ if (x instanceof Character)
+- return ((Character) x).charValue();
++ return (Character) x;
+ return (char) primitiveConversion(Wrapper.CHAR, x, cast).intValue();
+ }
+
++ static long unboxLong(Long x) {
++ return x;
++ }
+ static long unboxLong(Object x, boolean cast) {
+ if (x instanceof Long)
+- return ((Long) x).longValue();
++ return (Long) x;
+ return primitiveConversion(Wrapper.LONG, x, cast).longValue();
+ }
+
++ static float unboxFloat(Float x) {
++ return x;
++ }
+ static float unboxFloat(Object x, boolean cast) {
+ if (x instanceof Float)
+- return ((Float) x).floatValue();
++ return (Float) x;
+ return primitiveConversion(Wrapper.FLOAT, x, cast).floatValue();
+ }
+
++ static double unboxDouble(Double x) {
++ return x;
++ }
+ static double unboxDouble(Object x, boolean cast) {
+ if (x instanceof Double)
+- return ((Double) x).doubleValue();
++ return (Double) x;
+ return primitiveConversion(Wrapper.DOUBLE, x, cast).doubleValue();
+ }
+
+- private static MethodType unboxType(Wrapper wrap) {
++ private static MethodType unboxType(Wrapper wrap, int kind) {
++ if (kind == 0)
++ return MethodType.methodType(wrap.primitiveType(), wrap.wrapperType());
+ return MethodType.methodType(wrap.primitiveType(), Object.class, boolean.class);
+ }
+
+- private static final EnumMap<Wrapper, MethodHandle>[]
+- UNBOX_CONVERSIONS = newWrapperCaches(2);
++ private static final WrapperCache[] UNBOX_CONVERSIONS = newWrapperCaches(4);
+
+- private static MethodHandle unbox(Wrapper wrap, boolean cast) {
+- EnumMap<Wrapper, MethodHandle> cache = UNBOX_CONVERSIONS[(cast?1:0)];
++ private static MethodHandle unbox(Wrapper wrap, int kind) {
++ // kind 0 -> strongly typed with NPE
++ // kind 1 -> strongly typed but zero for null,
++ // kind 2 -> asType rules: accept multiple box types but only widening conversions with NPE
++ // kind 3 -> explicitCastArguments rules: allow narrowing conversions, zero for null
++ WrapperCache cache = UNBOX_CONVERSIONS[kind];
+ MethodHandle mh = cache.get(wrap);
+ if (mh != null) {
+ return mh;
+@@ -135,41 +160,59 @@
+ // slow path
+ switch (wrap) {
+ case OBJECT:
+- mh = IDENTITY; break;
+ case VOID:
+- mh = IGNORE; break;
+- }
+- if (mh != null) {
+- cache.put(wrap, mh);
+- return mh;
++ throw new IllegalArgumentException("unbox "+wrap);
+ }
+ // look up the method
+ String name = "unbox" + wrap.wrapperSimpleName();
+- MethodType type = unboxType(wrap);
++ MethodType type = unboxType(wrap, kind);
+ try {
+ mh = IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
+ } catch (ReflectiveOperationException ex) {
+ mh = null;
+ }
+ if (mh != null) {
+- mh = MethodHandles.insertArguments(mh, 1, cast);
+- cache.put(wrap, mh);
+- return mh;
++ if (kind > 0) {
++ boolean cast = (kind != 2);
++ mh = MethodHandles.insertArguments(mh, 1, cast);
++ }
++ if (kind == 1) { // casting but exact (null -> zero)
++ mh = mh.asType(unboxType(wrap, 0));
++ }
++ return cache.put(wrap, mh);
+ }
+ throw new IllegalArgumentException("cannot find unbox adapter for " + wrap
+- + (cast ? " (cast)" : ""));
++ + (kind <= 1 ? " (exact)" : kind == 3 ? " (cast)" : ""));
+ }
+
+- public static MethodHandle unboxCast(Wrapper type) {
+- return unbox(type, true);
++ /** Return an exact unboxer for the given primitive type. */
++ public static MethodHandle unboxExact(Wrapper type) {
++ return unbox(type, 0);
+ }
+
+- public static MethodHandle unbox(Class<?> type) {
+- return unbox(Wrapper.forPrimitiveType(type), false);
++ /** Return an exact unboxer for the given primitive type, with optional null-to-zero conversion.
++ * The boolean says whether to throw an NPE on a null value (false means unbox a zero).
++ * The type of the unboxer is of a form like (Integer)int.
++ */
++ public static MethodHandle unboxExact(Wrapper type, boolean throwNPE) {
++ return unbox(type, throwNPE ? 0 : 1);
+ }
+
+- public static MethodHandle unboxCast(Class<?> type) {
+- return unbox(Wrapper.forPrimitiveType(type), true);
++ /** Return a widening unboxer for the given primitive type.
++ * Widen narrower primitive boxes to the given type.
++ * Do not narrow any primitive values or convert null to zero.
++ * The type of the unboxer is of a form like (Object)int.
++ */
++ public static MethodHandle unboxWiden(Wrapper type) {
++ return unbox(type, 2);
++ }
++
++ /** Return a casting unboxer for the given primitive type.
++ * Widen or narrow primitive values to the given type, or convert null to zero, as needed.
++ * The type of the unboxer is of a form like (Object)int.
++ */
++ public static MethodHandle unboxCast(Wrapper type) {
++ return unbox(type, 3);
+ }
+
+ static private final Integer ZERO_INT = 0, ONE_INT = 1;
+@@ -266,57 +309,26 @@
+ return MethodType.methodType(boxType, wrap.primitiveType());
+ }
+
+- private static final EnumMap<Wrapper, MethodHandle>[]
+- BOX_CONVERSIONS = newWrapperCaches(2);
++ private static final WrapperCache[] BOX_CONVERSIONS = newWrapperCaches(1);
+
+- private static MethodHandle box(Wrapper wrap, boolean exact) {
+- EnumMap<Wrapper, MethodHandle> cache = BOX_CONVERSIONS[(exact?1:0)];
++ public static MethodHandle boxExact(Wrapper wrap) {
++ WrapperCache cache = BOX_CONVERSIONS[0];
+ MethodHandle mh = cache.get(wrap);
+ if (mh != null) {
+ return mh;
+ }
+- // slow path
+- switch (wrap) {
+- case OBJECT:
+- mh = IDENTITY; break;
+- case VOID:
+- mh = ZERO_OBJECT;
+- break;
+- }
+- if (mh != null) {
+- cache.put(wrap, mh);
+- return mh;
+- }
+ // look up the method
+ String name = "box" + wrap.wrapperSimpleName();
+ MethodType type = boxType(wrap);
+- if (exact) {
+- try {
+- mh = IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
+- } catch (ReflectiveOperationException ex) {
+- mh = null;
+- }
+- } else {
+- mh = box(wrap, !exact).asType(type.erase());
++ try {
++ mh = IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
++ } catch (ReflectiveOperationException ex) {
++ mh = null;
+ }
+ if (mh != null) {
+- cache.put(wrap, mh);
+- return mh;
++ return cache.put(wrap, mh);
+ }
+- throw new IllegalArgumentException("cannot find box adapter for "
+- + wrap + (exact ? " (exact)" : ""));
+- }
+-
+- public static MethodHandle box(Class<?> type) {
+- boolean exact = false;
+- // e.g., boxShort(short)Short if exact,
+- // e.g., boxShort(short)Object if !exact
+- return box(Wrapper.forPrimitiveType(type), exact);
+- }
+-
+- public static MethodHandle box(Wrapper type) {
+- boolean exact = false;
+- return box(type, exact);
++ throw new IllegalArgumentException("cannot find box adapter for " + wrap);
+ }
+
+ /// Constant functions
+@@ -348,11 +360,10 @@
+ return 0;
+ }
+
+- private static final EnumMap<Wrapper, MethodHandle>[]
+- CONSTANT_FUNCTIONS = newWrapperCaches(2);
++ private static final WrapperCache[] CONSTANT_FUNCTIONS = newWrapperCaches(2);
+
+ public static MethodHandle zeroConstantFunction(Wrapper wrap) {
+- EnumMap<Wrapper, MethodHandle> cache = CONSTANT_FUNCTIONS[0];
++ WrapperCache cache = CONSTANT_FUNCTIONS[0];
+ MethodHandle mh = cache.get(wrap);
+ if (mh != null) {
+ return mh;
+@@ -373,184 +384,37 @@
+ break;
+ }
+ if (mh != null) {
+- cache.put(wrap, mh);
+- return mh;
++ return cache.put(wrap, mh);
+ }
+
+ // use zeroInt and cast the result
+ if (wrap.isSubwordOrInt() && wrap != Wrapper.INT) {
+ mh = MethodHandles.explicitCastArguments(zeroConstantFunction(Wrapper.INT), type);
+- cache.put(wrap, mh);
+- return mh;
++ return cache.put(wrap, mh);
+ }
+ throw new IllegalArgumentException("cannot find zero constant for " + wrap);
+ }
+
+- /// Converting references to references.
+-
+- /**
+- * Identity function.
+- * @param x an arbitrary reference value
+- * @return the same value x
+- */
+- static <T> T identity(T x) {
+- return x;
+- }
+-
+- static <T> T[] identity(T[] x) {
+- return x;
+- }
+-
+- /**
+- * Identity function on ints.
+- * @param x an arbitrary int value
+- * @return the same value x
+- */
+- static int identity(int x) {
+- return x;
+- }
+-
+- static byte identity(byte x) {
+- return x;
+- }
+-
+- static short identity(short x) {
+- return x;
+- }
+-
+- static boolean identity(boolean x) {
+- return x;
+- }
+-
+- static char identity(char x) {
+- return x;
+- }
+-
+- /**
+- * Identity function on longs.
+- * @param x an arbitrary long value
+- * @return the same value x
+- */
+- static long identity(long x) {
+- return x;
+- }
+-
+- static float identity(float x) {
+- return x;
+- }
+-
+- static double identity(double x) {
+- return x;
+- }
+-
+- private static ClassCastException newClassCastException(Class<?> t, Object obj) {
+- return new ClassCastException("Cannot cast " + obj.getClass().getName() + " to " + t.getName());
+- }
+-
+- private static final MethodHandle IDENTITY, CAST_REFERENCE, ZERO_OBJECT, IGNORE, EMPTY,
+- ARRAY_IDENTITY, FILL_NEW_TYPED_ARRAY, FILL_NEW_ARRAY;
++ private static final MethodHandle CAST_REFERENCE, IGNORE, EMPTY;
+ static {
+ try {
+ MethodType idType = MethodType.genericMethodType(1);
+ MethodType ignoreType = idType.changeReturnType(void.class);
+- MethodType zeroObjectType = MethodType.genericMethodType(0);
+- IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", idType);
+ CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
+- ZERO_OBJECT = IMPL_LOOKUP.findStatic(THIS_CLASS, "zeroObject", zeroObjectType);
+ IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType);
+ EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1));
+- ARRAY_IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(Object[].class, Object[].class));
+- FILL_NEW_ARRAY = IMPL_LOOKUP
+- .findStatic(THIS_CLASS, "fillNewArray",
+- MethodType.methodType(Object[].class, Integer.class, Object[].class));
+- FILL_NEW_TYPED_ARRAY = IMPL_LOOKUP
+- .findStatic(THIS_CLASS, "fillNewTypedArray",
+- MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
+ } catch (NoSuchMethodException | IllegalAccessException ex) {
+ throw newInternalError("uncaught exception", ex);
+ }
+ }
+
+- // Varargs methods need to be in a separately initialized class, to avoid bootstrapping problems.
+- static class LazyStatics {
+- private static final MethodHandle COPY_AS_REFERENCE_ARRAY, COPY_AS_PRIMITIVE_ARRAY, MAKE_LIST;
+- static {
+- try {
+- //MAKE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "makeArray", MethodType.methodType(Object[].class, Object[].class));
+- COPY_AS_REFERENCE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "copyAsReferenceArray", MethodType.methodType(Object[].class, Class.class, Object[].class));
+- COPY_AS_PRIMITIVE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "copyAsPrimitiveArray", MethodType.methodType(Object.class, Wrapper.class, Object[].class));
+- MAKE_LIST = IMPL_LOOKUP.findStatic(THIS_CLASS, "makeList", MethodType.methodType(List.class, Object[].class));
+- } catch (ReflectiveOperationException ex) {
+- throw newInternalError("uncaught exception", ex);
+- }
+- }
++ public static MethodHandle ignore() {
++ return IGNORE;
+ }
+
+- private static final EnumMap<Wrapper, MethodHandle>[] WRAPPER_CASTS
+- = newWrapperCaches(1);
+-
+- /** Return a method that casts its sole argument (an Object) to the given type
+- * and returns it as the given type.
+- */
+- public static MethodHandle cast(Class<?> type) {
+- return cast(type, CAST_REFERENCE);
+- }
+- public static MethodHandle cast(Class<?> type, MethodHandle castReference) {
+- if (type.isPrimitive()) throw new IllegalArgumentException("cannot cast primitive type "+type);
+- MethodHandle mh;
+- Wrapper wrap = null;
+- EnumMap<Wrapper, MethodHandle> cache = null;
+- if (Wrapper.isWrapperType(type)) {
+- wrap = Wrapper.forWrapperType(type);
+- cache = WRAPPER_CASTS[0];
+- mh = cache.get(wrap);
+- if (mh != null) return mh;
+- }
+- mh = MethodHandles.insertArguments(castReference, 0, type);
+- if (cache != null)
+- cache.put(wrap, mh);
+- return mh;
+- }
+-
+- public static MethodHandle identity() {
+- return IDENTITY;
+- }
+-
+- public static MethodHandle identity(Class<?> type) {
+- if (!type.isPrimitive())
+- // Reference identity has been moved into MethodHandles:
+- return MethodHandles.identity(type);
+- return identity(Wrapper.findPrimitiveType(type));
+- }
+-
+- public static MethodHandle identity(Wrapper wrap) {
+- EnumMap<Wrapper, MethodHandle> cache = CONSTANT_FUNCTIONS[1];
+- MethodHandle mh = cache.get(wrap);
+- if (mh != null) {
+- return mh;
+- }
+- // slow path
+- MethodType type = MethodType.methodType(wrap.primitiveType());
+- if (wrap != Wrapper.VOID)
+- type = type.appendParameterTypes(wrap.primitiveType());
+- try {
+- mh = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", type);
+- } catch (ReflectiveOperationException ex) {
+- mh = null;
+- }
+- if (mh == null && wrap == Wrapper.VOID) {
+- mh = EMPTY; // #(){} : #()void
+- }
+- if (mh != null) {
+- cache.put(wrap, mh);
+- return mh;
+- }
+-
+- if (mh != null) {
+- cache.put(wrap, mh);
+- return mh;
+- }
+- throw new IllegalArgumentException("cannot find identity for " + wrap);
++ /** Return a method that casts its second argument (an Object) to the given type (a Class). */
++ public static MethodHandle cast() {
++ return CAST_REFERENCE;
+ }
+
+ /// Primitive conversions.
+@@ -759,11 +623,10 @@
+ return (x ? (byte)1 : (byte)0);
+ }
+
+- private static final EnumMap<Wrapper, MethodHandle>[]
+- CONVERT_PRIMITIVE_FUNCTIONS = newWrapperCaches(Wrapper.values().length);
++ private static final WrapperCache[] CONVERT_PRIMITIVE_FUNCTIONS = newWrapperCaches(Wrapper.values().length);
+
+ public static MethodHandle convertPrimitive(Wrapper wsrc, Wrapper wdst) {
+- EnumMap<Wrapper, MethodHandle> cache = CONVERT_PRIMITIVE_FUNCTIONS[wsrc.ordinal()];
++ WrapperCache cache = CONVERT_PRIMITIVE_FUNCTIONS[wsrc.ordinal()];
+ MethodHandle mh = cache.get(wdst);
+ if (mh != null) {
+ return mh;
+@@ -771,17 +634,9 @@
+ // slow path
+ Class<?> src = wsrc.primitiveType();
+ Class<?> dst = wdst.primitiveType();
+- MethodType type = src == void.class ? MethodType.methodType(dst) : MethodType.methodType(dst, src);
++ MethodType type = MethodType.methodType(dst, src);
+ if (wsrc == wdst) {
+- mh = identity(src);
+- } else if (wsrc == Wrapper.VOID) {
+- mh = zeroConstantFunction(wdst);
+- } else if (wdst == Wrapper.VOID) {
+- mh = MethodHandles.dropArguments(EMPTY, 0, src); // Defer back to MethodHandles.
+- } else if (wsrc == Wrapper.OBJECT) {
+- mh = unboxCast(dst);
+- } else if (wdst == Wrapper.OBJECT) {
+- mh = box(src);
++ mh = MethodHandles.identity(src);
+ } else {
+ assert(src.isPrimitive() && dst.isPrimitive());
+ try {
+@@ -792,8 +647,7 @@
+ }
+ if (mh != null) {
+ assert(mh.type() == type) : mh;
+- cache.put(wdst, mh);
+- return mh;
++ return cache.put(wdst, mh);
+ }
+
+ throw new IllegalArgumentException("cannot find primitive conversion function for " +
+@@ -808,363 +662,6 @@
+ return Character.toUpperCase(x.charAt(0))+x.substring(1);
+ }
+
+- /// Collection of multiple arguments.
+-
+- public static Object convertArrayElements(Class<?> arrayType, Object array) {
+- Class<?> src = array.getClass().getComponentType();
+- Class<?> dst = arrayType.getComponentType();
+- if (src == null || dst == null) throw new IllegalArgumentException("not array type");
+- Wrapper sw = (src.isPrimitive() ? Wrapper.forPrimitiveType(src) : null);
+- Wrapper dw = (dst.isPrimitive() ? Wrapper.forPrimitiveType(dst) : null);
+- int length;
+- if (sw == null) {
+- Object[] a = (Object[]) array;
+- length = a.length;
+- if (dw == null)
+- return Arrays.copyOf(a, length, arrayType.asSubclass(Object[].class));
+- Object res = dw.makeArray(length);
+- dw.copyArrayUnboxing(a, 0, res, 0, length);
+- return res;
+- }
+- length = java.lang.reflect.Array.getLength(array);
+- Object[] res;
+- if (dw == null) {
+- res = Arrays.copyOf(NO_ARGS_ARRAY, length, arrayType.asSubclass(Object[].class));
+- } else {
+- res = new Object[length];
+- }
+- sw.copyArrayBoxing(array, 0, res, 0, length);
+- if (dw == null) return res;
+- Object a = dw.makeArray(length);
+- dw.copyArrayUnboxing(res, 0, a, 0, length);
+- return a;
+- }
+-
+- private static MethodHandle findCollector(String name, int nargs, Class<?> rtype, Class<?>... ptypes) {
+- MethodType type = MethodType.genericMethodType(nargs)
+- .changeReturnType(rtype)
+- .insertParameterTypes(0, ptypes);
+- try {
+- return IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
+- } catch (ReflectiveOperationException ex) {
+- return null;
+- }
+- }
+-
+- private static final Object[] NO_ARGS_ARRAY = {};
+- private static Object[] makeArray(Object... args) { return args; }
+- private static Object[] array() { return NO_ARGS_ARRAY; }
+- private static Object[] array(Object a0)
+- { return makeArray(a0); }
+- private static Object[] array(Object a0, Object a1)
+- { return makeArray(a0, a1); }
+- private static Object[] array(Object a0, Object a1, Object a2)
+- { return makeArray(a0, a1, a2); }
+- private static Object[] array(Object a0, Object a1, Object a2, Object a3)
+- { return makeArray(a0, a1, a2, a3); }
+- private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+- Object a4)
+- { return makeArray(a0, a1, a2, a3, a4); }
+- private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+- Object a4, Object a5)
+- { return makeArray(a0, a1, a2, a3, a4, a5); }
+- private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+- Object a4, Object a5, Object a6)
+- { return makeArray(a0, a1, a2, a3, a4, a5, a6); }
+- private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+- Object a4, Object a5, Object a6, Object a7)
+- { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); }
+- private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+- Object a4, Object a5, Object a6, Object a7,
+- Object a8)
+- { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+- private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+- Object a4, Object a5, Object a6, Object a7,
+- Object a8, Object a9)
+- { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+- private static MethodHandle[] makeArrays() {
+- ArrayList<MethodHandle> mhs = new ArrayList<>();
+- for (;;) {
+- MethodHandle mh = findCollector("array", mhs.size(), Object[].class);
+- if (mh == null) break;
+- mhs.add(mh);
+- }
+- assert(mhs.size() == 11); // current number of methods
+- return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
+- }
+- private static final MethodHandle[] ARRAYS = makeArrays();
+-
+- // filling versions of the above:
+- // using Integer len instead of int len and no varargs to avoid bootstrapping problems
+- private static Object[] fillNewArray(Integer len, Object[] /*not ...*/ args) {
+- Object[] a = new Object[len];
+- fillWithArguments(a, 0, args);
+- return a;
+- }
+- private static Object[] fillNewTypedArray(Object[] example, Integer len, Object[] /*not ...*/ args) {
+- Object[] a = Arrays.copyOf(example, len);
+- fillWithArguments(a, 0, args);
+- return a;
+- }
+- private static void fillWithArguments(Object[] a, int pos, Object... args) {
+- System.arraycopy(args, 0, a, pos, args.length);
+- }
+- // using Integer pos instead of int pos to avoid bootstrapping problems
+- private static Object[] fillArray(Integer pos, Object[] a, Object a0)
+- { fillWithArguments(a, pos, a0); return a; }
+- private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1)
+- { fillWithArguments(a, pos, a0, a1); return a; }
+- private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2)
+- { fillWithArguments(a, pos, a0, a1, a2); return a; }
+- private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3)
+- { fillWithArguments(a, pos, a0, a1, a2, a3); return a; }
+- private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
+- Object a4)
+- { fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; }
+- private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
+- Object a4, Object a5)
+- { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; }
+- private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
+- Object a4, Object a5, Object a6)
+- { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; }
+- private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
+- Object a4, Object a5, Object a6, Object a7)
+- { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; }
+- private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
+- Object a4, Object a5, Object a6, Object a7,
+- Object a8)
+- { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
+- private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
+- Object a4, Object a5, Object a6, Object a7,
+- Object a8, Object a9)
+- { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
+- private static MethodHandle[] makeFillArrays() {
+- ArrayList<MethodHandle> mhs = new ArrayList<>();
+- mhs.add(null); // there is no empty fill; at least a0 is required
+- for (;;) {
+- MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class);
+- if (mh == null) break;
+- mhs.add(mh);
+- }
+- assert(mhs.size() == 11); // current number of methods
+- return mhs.toArray(new MethodHandle[0]);
+- }
+- private static final MethodHandle[] FILL_ARRAYS = makeFillArrays();
+-
+- private static Object[] copyAsReferenceArray(Class<? extends Object[]> arrayType, Object... a) {
+- return Arrays.copyOf(a, a.length, arrayType);
+- }
+- private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {
+- Object a = w.makeArray(boxes.length);
+- w.copyArrayUnboxing(boxes, 0, a, 0, boxes.length);
+- return a;
+- }
+-
+- /** Return a method handle that takes the indicated number of Object
+- * arguments and returns an Object array of them, as if for varargs.
+- */
+- public static MethodHandle varargsArray(int nargs) {
+- MethodHandle mh = ARRAYS[nargs];
+- if (mh != null) return mh;
+- mh = findCollector("array", nargs, Object[].class);
+- if (mh != null) return ARRAYS[nargs] = mh;
+- mh = buildVarargsArray(FILL_NEW_ARRAY, ARRAY_IDENTITY, nargs);
+- assert(assertCorrectArity(mh, nargs));
+- return ARRAYS[nargs] = mh;
+- }
+-
+- private static boolean assertCorrectArity(MethodHandle mh, int arity) {
+- assert(mh.type().parameterCount() == arity) : "arity != "+arity+": "+mh;
+- return true;
+- }
+-
+- private static MethodHandle buildVarargsArray(MethodHandle newArray, MethodHandle finisher, int nargs) {
+- // Build up the result mh as a sequence of fills like this:
+- // finisher(fill(fill(newArrayWA(23,x1..x10),10,x11..x20),20,x21..x23))
+- // The various fill(_,10*I,___*[J]) are reusable.
+- int leftLen = Math.min(nargs, LEFT_ARGS); // absorb some arguments immediately
+- int rightLen = nargs - leftLen;
+- MethodHandle leftCollector = newArray.bindTo(nargs);
+- leftCollector = leftCollector.asCollector(Object[].class, leftLen);
+- MethodHandle mh = finisher;
+- if (rightLen > 0) {
+- MethodHandle rightFiller = fillToRight(LEFT_ARGS + rightLen);
+- if (mh == ARRAY_IDENTITY)
+- mh = rightFiller;
+- else
+- mh = MethodHandles.collectArguments(mh, 0, rightFiller);
+- }
+- if (mh == ARRAY_IDENTITY)
+- mh = leftCollector;
+- else
+- mh = MethodHandles.collectArguments(mh, 0, leftCollector);
+- return mh;
+- }
+-
+- private static final int LEFT_ARGS = (FILL_ARRAYS.length - 1);
+- private static final MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY+1];
+- /** fill_array_to_right(N).invoke(a, argL..arg[N-1])
+- * fills a[L]..a[N-1] with corresponding arguments,
+- * and then returns a. The value L is a global constant (LEFT_ARGS).
+- */
+- private static MethodHandle fillToRight(int nargs) {
+- MethodHandle filler = FILL_ARRAY_TO_RIGHT[nargs];
+- if (filler != null) return filler;
+- filler = buildFiller(nargs);
+- assert(assertCorrectArity(filler, nargs - LEFT_ARGS + 1));
+- return FILL_ARRAY_TO_RIGHT[nargs] = filler;
+- }
+- private static MethodHandle buildFiller(int nargs) {
+- if (nargs <= LEFT_ARGS)
+- return ARRAY_IDENTITY; // no args to fill; return the array unchanged
+- // we need room for both mh and a in mh.invoke(a, arg*[nargs])
+- final int CHUNK = LEFT_ARGS;
+- int rightLen = nargs % CHUNK;
+- int midLen = nargs - rightLen;
+- if (rightLen == 0) {
+- midLen = nargs - (rightLen = CHUNK);
+- if (FILL_ARRAY_TO_RIGHT[midLen] == null) {
+- // build some precursors from left to right
+- for (int j = LEFT_ARGS % CHUNK; j < midLen; j += CHUNK)
+- if (j > LEFT_ARGS) fillToRight(j);
+- }
+- }
+- if (midLen < LEFT_ARGS) rightLen = nargs - (midLen = LEFT_ARGS);
+- assert(rightLen > 0);
+- MethodHandle midFill = fillToRight(midLen); // recursive fill
+- MethodHandle rightFill = FILL_ARRAYS[rightLen].bindTo(midLen); // [midLen..nargs-1]
+- assert(midFill.type().parameterCount() == 1 + midLen - LEFT_ARGS);
+- assert(rightFill.type().parameterCount() == 1 + rightLen);
+-
+- // Combine the two fills:
+- // right(mid(a, x10..x19), x20..x23)
+- // The final product will look like this:
+- // right(mid(newArrayLeft(24, x0..x9), x10..x19), x20..x23)
+- if (midLen == LEFT_ARGS)
+- return rightFill;
+- else
+- return MethodHandles.collectArguments(rightFill, 0, midFill);
+- }
+-
+- // Type-polymorphic version of varargs maker.
+- private static final ClassValue<MethodHandle[]> TYPED_COLLECTORS
+- = new ClassValue<MethodHandle[]>() {
+- @Override
+- protected MethodHandle[] computeValue(Class<?> type) {
+- return new MethodHandle[256];
+- }
+- };
+-
+- static final int MAX_JVM_ARITY = 255; // limit imposed by the JVM
+-
+- /** Return a method handle that takes the indicated number of
+- * typed arguments and returns an array of them.
+- * The type argument is the array type.
+- */
+- public static MethodHandle varargsArray(Class<?> arrayType, int nargs) {
+- Class<?> elemType = arrayType.getComponentType();
+- if (elemType == null) throw new IllegalArgumentException("not an array: "+arrayType);
+- // FIXME: Need more special casing and caching here.
+- if (nargs >= MAX_JVM_ARITY/2 - 1) {
+- int slots = nargs;
+- final int MAX_ARRAY_SLOTS = MAX_JVM_ARITY - 1; // 1 for receiver MH
+- if (arrayType == double[].class || arrayType == long[].class)
+- slots *= 2;
+- if (slots > MAX_ARRAY_SLOTS)
+- throw new IllegalArgumentException("too many arguments: "+arrayType.getSimpleName()+", length "+nargs);
+- }
+- if (elemType == Object.class)
+- return varargsArray(nargs);
+- // other cases: primitive arrays, subtypes of Object[]
+- MethodHandle cache[] = TYPED_COLLECTORS.get(elemType);
+- MethodHandle mh = nargs < cache.length ? cache[nargs] : null;
+- if (mh != null) return mh;
+- if (elemType.isPrimitive()) {
+- MethodHandle builder = FILL_NEW_ARRAY;
+- MethodHandle producer = buildArrayProducer(arrayType);
+- mh = buildVarargsArray(builder, producer, nargs);
+- } else {
+- @SuppressWarnings("unchecked")
+- Class<? extends Object[]> objArrayType = (Class<? extends Object[]>) arrayType;
+- Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType);
+- MethodHandle builder = FILL_NEW_TYPED_ARRAY.bindTo(example);
+- MethodHandle producer = ARRAY_IDENTITY;
+- mh = buildVarargsArray(builder, producer, nargs);
+- }
+- mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
+- assert(assertCorrectArity(mh, nargs));
+- if (nargs < cache.length)
+- cache[nargs] = mh;
+- return mh;
+- }
+-
+- private static MethodHandle buildArrayProducer(Class<?> arrayType) {
+- Class<?> elemType = arrayType.getComponentType();
+- if (elemType.isPrimitive())
+- return LazyStatics.COPY_AS_PRIMITIVE_ARRAY.bindTo(Wrapper.forPrimitiveType(elemType));
+- else
+- return LazyStatics.COPY_AS_REFERENCE_ARRAY.bindTo(arrayType);
+- }
+-
+- // List version of varargs maker.
+-
+- private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY);
+- private static List<Object> makeList(Object... args) { return Arrays.asList(args); }
+- private static List<Object> list() { return NO_ARGS_LIST; }
+- private static List<Object> list(Object a0)
+- { return makeList(a0); }
+- private static List<Object> list(Object a0, Object a1)
+- { return makeList(a0, a1); }
+- private static List<Object> list(Object a0, Object a1, Object a2)
+- { return makeList(a0, a1, a2); }
+- private static List<Object> list(Object a0, Object a1, Object a2, Object a3)
+- { return makeList(a0, a1, a2, a3); }
+- private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+- Object a4)
+- { return makeList(a0, a1, a2, a3, a4); }
+- private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+- Object a4, Object a5)
+- { return makeList(a0, a1, a2, a3, a4, a5); }
+- private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+- Object a4, Object a5, Object a6)
+- { return makeList(a0, a1, a2, a3, a4, a5, a6); }
+- private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+- Object a4, Object a5, Object a6, Object a7)
+- { return makeList(a0, a1, a2, a3, a4, a5, a6, a7); }
+- private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+- Object a4, Object a5, Object a6, Object a7,
+- Object a8)
+- { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+- private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+- Object a4, Object a5, Object a6, Object a7,
+- Object a8, Object a9)
+- { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+- private static MethodHandle[] makeLists() {
+- ArrayList<MethodHandle> mhs = new ArrayList<>();
+- for (;;) {
+- MethodHandle mh = findCollector("list", mhs.size(), List.class);
+- if (mh == null) break;
+- mhs.add(mh);
+- }
+- assert(mhs.size() == 11); // current number of methods
+- return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
+- }
+- private static final MethodHandle[] LISTS = makeLists();
+-
+- /** Return a method handle that takes the indicated number of Object
+- * arguments and returns a List.
+- */
+- public static MethodHandle varargsList(int nargs) {
+- MethodHandle mh = LISTS[nargs];
+- if (mh != null) return mh;
+- mh = findCollector("list", nargs, List.class);
+- if (mh != null) return LISTS[nargs] = mh;
+- return LISTS[nargs] = buildVarargsList(nargs);
+- }
+- private static MethodHandle buildVarargsList(int nargs) {
+- return MethodHandles.filterReturnValue(varargsArray(nargs), LazyStatics.MAKE_LIST);
+- }
+-
+ // handy shared exception makers (they simplify the common case code)
+ private static InternalError newInternalError(String message, Throwable cause) {
+ return new InternalError(message, cause);
+--- ./jdk/src/share/classes/sun/invoke/util/VerifyType.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/invoke/util/VerifyType.java Wed Feb 04 12:14:43 2015 -0800
+@@ -40,18 +40,38 @@
+ /**
+ * True if a value can be stacked as the source type and unstacked as the
+ * destination type, without violating the JVM's type consistency.
++ * <p>
++ * If both types are references, we apply the verifier's subclass check
++ * (or subtyping, if keepInterfaces).
++ * If the src type is a type guaranteed to be null (Void) it can be converted
++ * to any other reference type.
++ * <p>
++ * If both types are primitives, we apply the verifier's primitive conversions.
++ * These do not include Java conversions such as long to double, since those
++ * require computation and (in general) stack depth changes.
++ * But very simple 32-bit viewing changes, such as byte to int,
++ * are null conversions, because they do not require any computation.
++ * These conversions are from any type to a wider type up to 32 bits,
++ * as long as the conversion is not signed to unsigned (byte to char).
++ * <p>
++ * The primitive type 'void' does not interconvert with any other type,
++ * even though it is legal to drop any type from the stack and "return void".
++ * The stack effects, though are different between void and any other type,
++ * so it is safer to report a non-trivial conversion.
+ *
+ * @param src the type of a stacked value
+ * @param dst the type by which we'd like to treat it
++ * @param keepInterfaces if false, we treat any interface as if it were Object
+ * @return whether the retyping can be done without motion or reformatting
+ */
+- public static boolean isNullConversion(Class<?> src, Class<?> dst) {
++ public static boolean isNullConversion(Class<?> src, Class<?> dst, boolean keepInterfaces) {
+ if (src == dst) return true;
+ // Verifier allows any interface to be treated as Object:
+- if (dst.isInterface()) dst = Object.class;
+- if (src.isInterface()) src = Object.class;
+- if (src == dst) return true; // check again
+- if (dst == void.class) return true; // drop any return value
++ if (!keepInterfaces) {
++ if (dst.isInterface()) dst = Object.class;
++ if (src.isInterface()) src = Object.class;
++ if (src == dst) return true; // check again
++ }
+ if (isNullType(src)) return !dst.isPrimitive();
+ if (!src.isPrimitive()) return dst.isAssignableFrom(src);
+ if (!dst.isPrimitive()) return false;
+@@ -82,25 +102,13 @@
+ * Is the given type java.lang.Null or an equivalent null-only type?
+ */
+ public static boolean isNullType(Class<?> type) {
+- if (type == null) return false;
+- return type == NULL_CLASS
+- // This one may also be used as a null type.
+- // TO DO: Decide if we really want to legitimize it here.
+- // Probably we do, unless java.lang.Null really makes it into Java 7
+- //|| type == Void.class
+- // Locally known null-only class:
+- || type == Empty.class
+- ;
+- }
+- private static final Class<?> NULL_CLASS;
+- static {
+- Class<?> nullClass = null;
+- try {
+- nullClass = Class.forName("java.lang.Null");
+- } catch (ClassNotFoundException ex) {
+- // OK, we'll cope
+- }
+- NULL_CLASS = nullClass;
++ // Any reference statically typed as Void is guaranteed to be null.
++ // Therefore, it can be safely treated as a value of any
++ // other type that admits null, i.e., a reference type.
++ if (type == Void.class) return true;
++ // Locally known null-only class:
++ if (type == Empty.class) return true;
++ return false;
+ }
+
+ /**
+@@ -111,14 +119,14 @@
+ * @param recv the type of the method handle receiving the call
+ * @return whether the retyping can be done without motion or reformatting
+ */
+- public static boolean isNullConversion(MethodType call, MethodType recv) {
++ public static boolean isNullConversion(MethodType call, MethodType recv, boolean keepInterfaces) {
+ if (call == recv) return true;
+ int len = call.parameterCount();
+ if (len != recv.parameterCount()) return false;
+ for (int i = 0; i < len; i++)
+- if (!isNullConversion(call.parameterType(i), recv.parameterType(i)))
++ if (!isNullConversion(call.parameterType(i), recv.parameterType(i), keepInterfaces))
+ return false;
+- return isNullConversion(recv.returnType(), call.returnType());
++ return isNullConversion(recv.returnType(), call.returnType(), keepInterfaces);
+ }
+
+ /**
+--- ./jdk/src/share/classes/sun/invoke/util/Wrapper.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/invoke/util/Wrapper.java Wed Feb 04 12:14:43 2015 -0800
+@@ -26,19 +26,19 @@
+ package sun.invoke.util;
+
+ public enum Wrapper {
+- BOOLEAN(Boolean.class, boolean.class, 'Z', (Boolean)false, new boolean[0], Format.unsigned(1)),
++ // wrapperType primitiveType char zero emptyArray format
++ BOOLEAN( Boolean.class, boolean.class, 'Z', (Boolean)false, new boolean[0], Format.unsigned( 1)),
+ // These must be in the order defined for widening primitive conversions in JLS 5.1.2
+- BYTE(Byte.class, byte.class, 'B', (Byte)(byte)0, new byte[0], Format.signed(8)),
+- SHORT(Short.class, short.class, 'S', (Short)(short)0, new short[0], Format.signed(16)),
+- CHAR(Character.class, char.class, 'C', (Character)(char)0, new char[0], Format.unsigned(16)),
+- INT(Integer.class, int.class, 'I', (Integer)/*(int)*/0, new int[0], Format.signed(32)),
+- LONG(Long.class, long.class, 'J', (Long)(long)0, new long[0], Format.signed(64)),
+- FLOAT(Float.class, float.class, 'F', (Float)(float)0, new float[0], Format.floating(32)),
+- DOUBLE(Double.class, double.class, 'D', (Double)(double)0, new double[0], Format.floating(64)),
+- //NULL(Null.class, null.class, 'N', null, null, Format.other(1)),
+- OBJECT(Object.class, Object.class, 'L', null, new Object[0], Format.other(1)),
++ BYTE ( Byte.class, byte.class, 'B', (Byte)(byte)0, new byte[0], Format.signed( 8)),
++ SHORT ( Short.class, short.class, 'S', (Short)(short)0, new short[0], Format.signed( 16)),
++ CHAR (Character.class, char.class, 'C', (Character)(char)0, new char[0], Format.unsigned(16)),
++ INT ( Integer.class, int.class, 'I', (Integer)/*(int)*/0, new int[0], Format.signed( 32)),
++ LONG ( Long.class, long.class, 'J', (Long)(long)0, new long[0], Format.signed( 64)),
++ FLOAT ( Float.class, float.class, 'F', (Float)(float)0, new float[0], Format.floating(32)),
++ DOUBLE ( Double.class, double.class, 'D', (Double)(double)0, new double[0], Format.floating(64)),
++ OBJECT ( Object.class, Object.class, 'L', null, new Object[0], Format.other( 1)),
+ // VOID must be the last type, since it is "assignable" from any other type:
+- VOID(Void.class, void.class, 'V', null, null, Format.other(0)),
++ VOID ( Void.class, void.class, 'V', null, null, Format.other( 0)),
+ ;
+
+ private final Class<?> wrapperType;
+@@ -230,14 +230,6 @@
+ */
+ public <T> T zero(Class<T> type) { return convert(zero, type); }
+
+-// /** Produce a wrapper for the given wrapper or primitive type. */
+-// public static Wrapper valueOf(Class<?> type) {
+-// if (isPrimitiveType(type))
+-// return forPrimitiveType(type);
+-// else
+-// return forWrapperType(type);
+-// }
+-
+ /** Return the wrapper that wraps values of the given type.
+ * The type may be {@code Object}, meaning the {@code OBJECT} wrapper.
+ * Otherwise, the type must be a primitive.
+--- ./jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java Wed Feb 04 12:14:43 2015 -0800
+@@ -383,7 +383,8 @@
+ }
+ public static LCMSImageLayout createImageLayout(Raster r) {
+ LCMSImageLayout l = new LCMSImageLayout();
+- if (r instanceof ByteComponentRaster) {
++ if (r instanceof ByteComponentRaster &&
++ r.getSampleModel() instanceof ComponentSampleModel) {
+ ByteComponentRaster br = (ByteComponentRaster)r;
+
+ ComponentSampleModel csm = (ComponentSampleModel)r.getSampleModel();
+--- ./jdk/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java Wed Feb 04 12:14:43 2015 -0800
+@@ -47,7 +47,7 @@
+ import static sun.java2d.pipe.BufferedOpCodes.*;
+ import java.lang.annotation.Native;
+
+-class OGLBlitLoops {
++final class OGLBlitLoops {
+
+ static void register() {
+ Blit blitIntArgbPreToSurface =
+@@ -56,7 +56,9 @@
+ Blit blitIntArgbPreToTexture =
+ new OGLSwToTextureBlit(SurfaceType.IntArgbPre,
+ OGLSurfaceData.PF_INT_ARGB_PRE);
+-
++ TransformBlit transformBlitIntArgbPreToSurface =
++ new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre,
++ OGLSurfaceData.PF_INT_ARGB_PRE);
+ GraphicsPrimitive[] primitives = {
+ // surface->surface ops
+ new OGLSurfaceToSurfaceBlit(),
+@@ -100,7 +102,7 @@
+ CompositeType.AnyAlpha,
+ blitIntArgbPreToSurface),
+
+- new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLSurface),
++ new OGLAnyCompositeBlit(),
+
+ new OGLSwToSurfaceScale(SurfaceType.IntRgb,
+ OGLSurfaceData.PF_INT_RGB),
+@@ -145,8 +147,9 @@
+ OGLSurfaceData.PF_BYTE_GRAY),
+ new OGLSwToSurfaceTransform(SurfaceType.UshortGray,
+ OGLSurfaceData.PF_USHORT_GRAY),
+- new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre,
+- OGLSurfaceData.PF_INT_ARGB_PRE),
++ transformBlitIntArgbPreToSurface,
++
++ new OGLGeneralTransformedBlit(transformBlitIntArgbPreToSurface),
+
+ // texture->surface ops
+ new OGLTextureToSurfaceBlit(),
+@@ -178,9 +181,6 @@
+ new OGLGeneralBlit(OGLSurfaceData.OpenGLTexture,
+ CompositeType.SrcNoEa,
+ blitIntArgbPreToTexture),
+-
+- new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLTexture),
+-
+ };
+ GraphicsPrimitiveMgr.register(primitives);
+ }
+@@ -781,11 +781,11 @@
+ * This general Blit implementation converts any source surface to an
+ * intermediate IntArgbPre surface, and then uses the more specific
+ * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate
+- * (premultiplied) surface down to OpenGL.
++ * (premultiplied) surface down to OpenGL using simple blit.
+ */
+ class OGLGeneralBlit extends Blit {
+
+- private Blit performop;
++ private final Blit performop;
+ private WeakReference srcTmp;
+
+ OGLGeneralBlit(SurfaceType dstType,
+@@ -826,12 +826,56 @@
+ }
+ }
+
+-class OGLAnyCompositeBlit extends Blit {
++/**
++ * This general TransformedBlit implementation converts any source surface to an
++ * intermediate IntArgbPre surface, and then uses the more specific
++ * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate
++ * (premultiplied) surface down to OpenGL using simple transformBlit.
++ */
++final class OGLGeneralTransformedBlit extends TransformBlit {
++
++ private final TransformBlit performop;
++ private WeakReference<SurfaceData> srcTmp;
++
++ OGLGeneralTransformedBlit(final TransformBlit performop) {
++ super(SurfaceType.Any, CompositeType.AnyAlpha,
++ OGLSurfaceData.OpenGLSurface);
++ this.performop = performop;
++ }
++
++ @Override
++ public synchronized void Transform(SurfaceData src, SurfaceData dst,
++ Composite comp, Region clip,
++ AffineTransform at, int hint, int srcx,
++ int srcy, int dstx, int dsty, int width,
++ int height){
++ Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
++ CompositeType.SrcNoEa,
++ SurfaceType.IntArgbPre);
++ // use cached intermediate surface, if available
++ final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null;
++ // convert source to IntArgbPre
++ src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc,
++ BufferedImage.TYPE_INT_ARGB_PRE);
++
++ // transform IntArgbPre intermediate surface to OpenGL surface
++ performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty,
++ width, height);
++
++ if (src != cachedSrc) {
++ // cache the intermediate surface
++ srcTmp = new WeakReference<>(src);
++ }
++ }
++}
++
++final class OGLAnyCompositeBlit extends Blit {
+ private WeakReference<SurfaceData> dstTmp;
+
+- public OGLAnyCompositeBlit(SurfaceType dstType) {
+- super(SurfaceType.Any, CompositeType.Any, dstType);
++ OGLAnyCompositeBlit() {
++ super(SurfaceType.Any, CompositeType.Any, OGLSurfaceData.OpenGLSurface);
+ }
++
+ public synchronized void Blit(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ int sx, int sy, int dx, int dy,
+@@ -848,15 +892,15 @@
+ cachedDst = dstTmp.get();
+ }
+
+- // convert source to IntArgbPre
++ // convert destination to IntArgbPre
+ SurfaceData dstBuffer = convertFrom(convertdst, dst, dx, dy, w, h,
+ cachedDst, BufferedImage.TYPE_INT_ARGB_PRE);
++ Region bufferClip =
++ clip == null ? null : clip.getTranslatedRegion(-dx, -dy);
+
+ Blit performop = Blit.getFromCache(src.getSurfaceType(),
+ CompositeType.Any, dstBuffer.getSurfaceType());
+-
+- performop.Blit(src, dstBuffer, comp, clip,
+- sx, sy, 0, 0, w, h);
++ performop.Blit(src, dstBuffer, comp, bufferClip, sx, sy, 0, 0, w, h);
+
+ if (dstBuffer != cachedDst) {
+ // cache the intermediate surface
+--- ./jdk/src/share/classes/sun/java2d/pipe/DrawImage.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/java2d/pipe/DrawImage.java Wed Feb 04 12:14:43 2015 -0800
+@@ -278,18 +278,34 @@
+ Color bgColor, int interpType,
+ double coords[])
+ {
+- double dx = coords[0];
+- double dy = coords[1];
+- double dw = coords[2] - dx;
+- double dh = coords[3] - dy;
++ double dx1 = coords[0];
++ double dy1 = coords[1];
++ double dx2 = coords[2];
++ double dy2 = coords[3];
++ double dw = dx2 - dx1;
++ double dh = dy2 - dy1;
++
++ /* If any of the destination coordinates exceed the integer range,
++ * then the calculations performed in calls made here cannot be
++ * guaranteed to be correct, or to converge (terminate).
++ * So return out of here, deferring to code that can handle this.
++ */
++ if (dx1 < Integer.MIN_VALUE || dx1 > Integer.MAX_VALUE ||
++ dy1 < Integer.MIN_VALUE || dy1 > Integer.MAX_VALUE ||
++ dx2 < Integer.MIN_VALUE || dx2 > Integer.MAX_VALUE ||
++ dy2 < Integer.MIN_VALUE || dy2 > Integer.MAX_VALUE)
++ {
++ return false;
++ }
++
+ // First check if width and height are very close to img w&h.
+ if (closeToInteger(sx2-sx1, dw) && closeToInteger(sy2-sy1, dh)) {
+ // Round location to nearest pixel and then test
+ // if it will cause interpolation anomalies.
+- int idx = (int) Math.floor(dx + 0.5);
+- int idy = (int) Math.floor(dy + 0.5);
++ int idx = (int) Math.floor(dx1 + 0.5);
++ int idy = (int) Math.floor(dy1 + 0.5);
+ if (interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR ||
+- (closeToInteger(idx, dx) && closeToInteger(idy, dy)))
++ (closeToInteger(idx, dx1) && closeToInteger(idy, dy1)))
+ {
+ renderImageCopy(sg, img, bgColor,
+ idx, idy,
+@@ -302,7 +318,7 @@
+ if (dw > 0 && dh > 0) {
+ if (renderImageScale(sg, img, bgColor, interpType,
+ sx1, sy1, sx2, sy2,
+- coords[0], coords[1], coords[2], coords[3]))
++ dx1, dy1, dx2, dy2))
+ {
+ return true;
+ }
+@@ -348,8 +364,53 @@
+ int sx1, int sy1, int sx2, int sy2,
+ Color bgColor)
+ {
++ final AffineTransform itx;
++ try {
++ itx = tx.createInverse();
++ } catch (final NoninvertibleTransformException ignored) {
++ // Non-invertible transform means no output
++ return;
++ }
++
++ /*
++ * Find the maximum bounds on the destination that will be
++ * affected by the transformed source. First, transform all
++ * four corners of the source and then min and max the resulting
++ * destination coordinates of the transformed corners.
++ * Note that tx already has the offset to sx1,sy1 accounted
++ * for so we use the box (0, 0, sx2-sx1, sy2-sy1) as the
++ * source coordinates.
++ */
++ final double[] coords = new double[8];
++ /* corner: UL UR LL LR */
++ /* index: 0 1 2 3 4 5 6 7 */
++ /* coord: (0, 0), (w, 0), (0, h), (w, h) */
++ coords[2] = coords[6] = sx2 - sx1;
++ coords[5] = coords[7] = sy2 - sy1;
++ tx.transform(coords, 0, coords, 0, 4);
++ double ddx1, ddy1, ddx2, ddy2;
++ ddx1 = ddx2 = coords[0];
++ ddy1 = ddy2 = coords[1];
++ for (int i = 2; i < coords.length; i += 2) {
++ double d = coords[i];
++ if (ddx1 > d) ddx1 = d;
++ else if (ddx2 < d) ddx2 = d;
++ d = coords[i+1];
++ if (ddy1 > d) ddy1 = d;
++ else if (ddy2 < d) ddy2 = d;
++ }
++
+ Region clip = sg.getCompClip();
+- SurfaceData dstData = sg.surfaceData;
++ final int dx1 = Math.max((int) Math.floor(ddx1), clip.lox);
++ final int dy1 = Math.max((int) Math.floor(ddy1), clip.loy);
++ final int dx2 = Math.min((int) Math.ceil(ddx2), clip.hix);
++ final int dy2 = Math.min((int) Math.ceil(ddy2), clip.hiy);
++ if (dx2 <= dx1 || dy2 <= dy1) {
++ // empty destination means no output
++ return;
++ }
++
++ final SurfaceData dstData = sg.surfaceData;
+ SurfaceData srcData = dstData.getSourceSurfaceData(img,
+ SunGraphics2D.TRANSFORM_GENERIC,
+ sg.imageComp,
+@@ -413,56 +474,13 @@
+ // assert(helper != null);
+ }
+
+- AffineTransform itx;
+- try {
+- itx = tx.createInverse();
+- } catch (NoninvertibleTransformException e) {
+- // Non-invertible transform means no output
+- return;
+- }
+-
+- /*
+- * Find the maximum bounds on the destination that will be
+- * affected by the transformed source. First, transform all
+- * four corners of the source and then min and max the resulting
+- * destination coordinates of the transformed corners.
+- * Note that tx already has the offset to sx1,sy1 accounted
+- * for so we use the box (0, 0, sx2-sx1, sy2-sy1) as the
+- * source coordinates.
+- */
+- double coords[] = new double[8];
+- /* corner: UL UR LL LR */
+- /* index: 0 1 2 3 4 5 6 7 */
+- /* coord: (0, 0), (w, 0), (0, h), (w, h) */
+- coords[2] = coords[6] = sx2 - sx1;
+- coords[5] = coords[7] = sy2 - sy1;
+- tx.transform(coords, 0, coords, 0, 4);
+- double ddx1, ddy1, ddx2, ddy2;
+- ddx1 = ddx2 = coords[0];
+- ddy1 = ddy2 = coords[1];
+- for (int i = 2; i < coords.length; i += 2) {
+- double d = coords[i];
+- if (ddx1 > d) ddx1 = d;
+- else if (ddx2 < d) ddx2 = d;
+- d = coords[i+1];
+- if (ddy1 > d) ddy1 = d;
+- else if (ddy2 < d) ddy2 = d;
+- }
+- int dx1 = (int) Math.floor(ddx1);
+- int dy1 = (int) Math.floor(ddy1);
+- int dx2 = (int) Math.ceil(ddx2);
+- int dy2 = (int) Math.ceil(ddy2);
+-
+ SurfaceType dstType = dstData.getSurfaceType();
+- MaskBlit maskblit;
+- Blit blit;
+ if (sg.compositeState <= SunGraphics2D.COMP_ALPHA) {
+ /* NOTE: We either have, or we can make,
+ * a MaskBlit for any alpha composite type
+ */
+- maskblit = MaskBlit.getFromCache(SurfaceType.IntArgbPre,
+- sg.imageComp,
+- dstType);
++ MaskBlit maskblit = MaskBlit.getFromCache(SurfaceType.IntArgbPre,
++ sg.imageComp, dstType);
+
+ /* NOTE: We can only use the native TransformHelper
+ * func to go directly to the dest if both the helper
+@@ -480,27 +498,19 @@
+ null, 0, 0);
+ return;
+ }
+- blit = null;
+- } else {
+- /* NOTE: We either have, or we can make,
+- * a Blit for any composite type, even Custom
+- */
+- maskblit = null;
+- blit = Blit.getFromCache(SurfaceType.IntArgbPre,
+- sg.imageComp,
+- dstType);
+ }
+
+ // We need to transform to a temp image and then copy
+ // just the pieces that are valid data to the dest.
+- BufferedImage tmpimg = new BufferedImage(dx2-dx1, dy2-dy1,
+- BufferedImage.TYPE_INT_ARGB);
++ final int w = dx2 - dx1;
++ final int h = dy2 - dy1;
++ BufferedImage tmpimg = new BufferedImage(w, h,
++ BufferedImage.TYPE_INT_ARGB_PRE);
+ SurfaceData tmpData = SurfaceData.getPrimarySurfaceData(tmpimg);
+ SurfaceType tmpType = tmpData.getSurfaceType();
+- MaskBlit tmpmaskblit =
+- MaskBlit.getFromCache(SurfaceType.IntArgbPre,
+- CompositeType.SrcNoEa,
+- tmpType);
++ MaskBlit tmpmaskblit = MaskBlit.getFromCache(SurfaceType.IntArgbPre,
++ CompositeType.SrcNoEa,
++ tmpType);
+ /*
+ * The helper function fills a temporary edges buffer
+ * for us with the bounding coordinates of each scanline
+@@ -515,7 +525,7 @@
+ *
+ * edges thus has to be h*2+2 in length
+ */
+- int edges[] = new int[(dy2-dy1)*2+2];
++ final int[] edges = new int[h * 2 + 2];
+ // It is important that edges[0]=edges[1]=0 when we call
+ // Transform in case it must return early and we would
+ // not want to render anything on an error condition.
+@@ -523,35 +533,17 @@
+ AlphaComposite.Src, null,
+ itx, interpType,
+ sx1, sy1, sx2, sy2,
+- 0, 0, dx2-dx1, dy2-dy1,
++ 0, 0, w, h,
+ edges, dx1, dy1);
+
+- /*
+- * Now copy the results, scanline by scanline, into the dest.
+- * The edges array helps us minimize the work.
++ final Region region = Region.getInstance(dx1, dy1, dx2, dy2, edges);
++ clip = clip.getIntersection(region);
++
++ /* NOTE: We either have, or we can make,
++ * a Blit for any composite type, even Custom
+ */
+- int index = 2;
+- for (int y = edges[0]; y < edges[1]; y++) {
+- int relx1 = edges[index++];
+- int relx2 = edges[index++];
+- if (relx1 >= relx2) {
+- continue;
+- }
+- if (maskblit != null) {
+- maskblit.MaskBlit(tmpData, dstData,
+- sg.composite, clip,
+- relx1, y,
+- dx1+relx1, dy1+y,
+- relx2 - relx1, 1,
+- null, 0, 0);
+- } else {
+- blit.Blit(tmpData, dstData,
+- sg.composite, clip,
+- relx1, y,
+- dx1+relx1, dy1+y,
+- relx2 - relx1, 1);
+- }
+- }
++ final Blit blit = Blit.getFromCache(tmpType, sg.imageComp, dstType);
++ blit.Blit(tmpData, dstData, sg.composite, clip, 0, 0, dx1, dy1, w, h);
+ }
+
+ // Render an image using only integer translation
+--- ./jdk/src/share/classes/sun/java2d/pipe/Region.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/java2d/pipe/Region.java Wed Feb 04 12:14:43 2015 -0800
+@@ -30,6 +30,8 @@
+ import java.awt.geom.AffineTransform;
+ import java.awt.geom.RectangularShape;
+
++import sun.java2d.loops.TransformHelper;
++
+ /**
+ * This class encapsulates a definition of a two dimensional region which
+ * consists of a number of Y ranges each containing multiple X bands.
+@@ -160,6 +162,15 @@
+ this.hiy = hiy;
+ }
+
++ private Region(int lox, int loy, int hix, int hiy, int[] bands, int end) {
++ this.lox = lox;
++ this.loy = loy;
++ this.hix = hix;
++ this.hiy = hiy;
++ this.bands = bands;
++ this.endIndex = end;
++ }
++
+ /**
+ * Returns a Region object covering the pixels which would be
+ * touched by a fill or clip operation on a Graphics implementation
+@@ -256,6 +267,44 @@
+ }
+
+ /**
++ * Returns a Region object with a rectangle of interest specified by the
++ * indicated rectangular area in lox, loy, hix, hiy and edges array, which
++ * is located relative to the rectangular area. Edges array - 0,1 are y
++ * range, 2N,2N+1 are x ranges, 1 per y range.
++ *
++ * @see TransformHelper
++ */
++ static Region getInstance(final int lox, final int loy, final int hix,
++ final int hiy, final int[] edges) {
++ final int y1 = edges[0];
++ final int y2 = edges[1];
++ if (hiy <= loy || hix <= lox || y2 <= y1) {
++ return EMPTY_REGION;
++ }
++ // rowsNum * (3 + 1 * 2)
++ final int[] bands = new int[(y2 - y1) * 5];
++ int end = 0;
++ int index = 2;
++ for (int y = y1; y < y2; ++y) {
++ final int spanlox = Math.max(clipAdd(lox, edges[index++]), lox);
++ final int spanhix = Math.min(clipAdd(lox, edges[index++]), hix);
++ if (spanlox < spanhix) {
++ final int spanloy = Math.max(clipAdd(loy, y), loy);
++ final int spanhiy = Math.min(clipAdd(spanloy, 1), hiy);
++ if (spanloy < spanhiy) {
++ bands[end++] = spanloy;
++ bands[end++] = spanhiy;
++ bands[end++] = 1; // 1 span per row
++ bands[end++] = spanlox;
++ bands[end++] = spanhix;
++ }
++ }
++ }
++ return end != 0 ? new Region(lox, loy, hix, hiy, bands, end)
++ : EMPTY_REGION;
++ }
++
++ /**
+ * Returns a Region object with a rectangle of interest specified
+ * by the indicated Rectangle object.
+ * <p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/src/share/classes/sun/management/ExtendedPlatformComponent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 sun.management;
++
++import java.util.Collections;
++import java.util.List;
++import java.lang.management.PlatformManagedObject;
++
++/**
++ * Class to allow for an extended set of platform MXBeans
++ */
++public final class ExtendedPlatformComponent {
++ private ExtendedPlatformComponent() {} // Don't create any instances
++
++ /**
++ * Get the extended set of platform MXBeans that should be registered in the
++ * platform MBeanServer, or an empty list if there are no such MXBeans.
++ */
++ public static List<? extends PlatformManagedObject> getMXBeans() {
++ return Collections.emptyList();
++ }
++
++ /**
++ * Returns the extended platform MXBean implementing the given
++ * mxbeanInterface, or null if there is no such MXBean.
++ */
++ public static <T extends PlatformManagedObject>
++ T getMXBean(Class<T> mxbeanInterface) {
++ return null;
++ }
++}
+--- ./jdk/src/share/classes/sun/management/Flag.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/management/Flag.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -28,6 +28,7 @@
+ import java.util.*;
+ import com.sun.management.VMOption;
+ import com.sun.management.VMOption.Origin;
++import java.security.AccessController;
+
+ /**
+ * Flag class is a helper class for constructing a VMOption.
+@@ -114,6 +115,13 @@
+ static synchronized native void setStringValue(String name, String value);
+
+ static {
++ AccessController.doPrivileged(
++ new java.security.PrivilegedAction<Void>() {
++ public Void run() {
++ System.loadLibrary("management");
++ return null;
++ }
++ });
+ initialize();
+ }
+ private static native void initialize();
+--- ./jdk/src/share/classes/sun/misc/Launcher.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/misc/Launcher.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -162,6 +162,8 @@
+ */
+ public ExtClassLoader(File[] dirs) throws IOException {
+ super(getExtURLs(dirs), null, factory);
++ SharedSecrets.getJavaNetAccess().
++ getURLClassPath(this).initLookupCache(this);
+ }
+
+ private static File[] getExtDirs() {
+@@ -285,11 +287,15 @@
+ });
+ }
+
++ final URLClassPath ucp;
++
+ /*
+ * Creates a new AppClassLoader
+ */
+ AppClassLoader(URL[] urls, ClassLoader parent) {
+ super(urls, parent, factory);
++ ucp = SharedSecrets.getJavaNetAccess().getURLClassPath(this);
++ ucp.initLookupCache(this);
+ }
+
+ /**
+@@ -305,6 +311,23 @@
+ sm.checkPackageAccess(name.substring(0, i));
+ }
+ }
++
++ if (ucp.knownToNotExist(name)) {
++ // The class of the given name is not found in the parent
++ // class loader as well as its local URLClassPath.
++ // Check if this class has already been defined dynamically;
++ // if so, return the loaded class; otherwise, skip the parent
++ // delegation and findClass.
++ Class<?> c = findLoadedClass(name);
++ if (c != null) {
++ if (resolve) {
++ resolveClass(c);
++ }
++ return c;
++ }
++ throw new ClassNotFoundException(name);
++ }
++
+ return (super.loadClass(name, resolve));
+ }
+
+@@ -386,6 +409,7 @@
+ urls = new URL[0];
+ }
+ bcp = new URLClassPath(urls, factory);
++ bcp.initLookupCache(null);
+ }
+ }
+
+--- ./jdk/src/share/classes/sun/misc/URLClassPath.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/misc/URLClassPath.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -38,6 +38,7 @@
+ import java.net.JarURLConnection;
+ import java.net.MalformedURLException;
+ import java.net.URL;
++import java.net.URLClassLoader;
+ import java.net.URLConnection;
+ import java.net.HttpURLConnection;
+ import java.net.URLStreamHandler;
+@@ -52,6 +53,7 @@
+ import java.security.cert.Certificate;
+ import sun.misc.FileURLMapper;
+ import sun.net.util.URLUtil;
++import sun.security.action.GetPropertyAction;
+
+ /**
+ * This class is used to maintain a search path of URLs for loading classes
+@@ -63,15 +65,18 @@
+ final static String USER_AGENT_JAVA_VERSION = "UA-Java-Version";
+ final static String JAVA_VERSION;
+ private static final boolean DEBUG;
++ private static final boolean DEBUG_LOOKUP_CACHE;
+ private static final boolean DISABLE_JAR_CHECKING;
+
+ static {
+ JAVA_VERSION = java.security.AccessController.doPrivileged(
+- new sun.security.action.GetPropertyAction("java.version"));
++ new GetPropertyAction("java.version"));
+ DEBUG = (java.security.AccessController.doPrivileged(
+- new sun.security.action.GetPropertyAction("sun.misc.URLClassPath.debug")) != null);
++ new GetPropertyAction("sun.misc.URLClassPath.debug")) != null);
++ DEBUG_LOOKUP_CACHE = (java.security.AccessController.doPrivileged(
++ new GetPropertyAction("sun.misc.URLClassPath.debugLookupCache")) != null);
+ String p = java.security.AccessController.doPrivileged(
+- new sun.security.action.GetPropertyAction("sun.misc.URLClassPath.disableJarChecking"));
++ new GetPropertyAction("sun.misc.URLClassPath.disableJarChecking"));
+ DISABLE_JAR_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
+ }
+
+@@ -149,6 +154,12 @@
+
+ urls.add(0, url);
+ path.add(url);
++
++ if (lookupCacheURLs != null) {
++ // The lookup cache is no longer valid, since getLookupCache()
++ // does not consider the newly added url.
++ disableAllLookupCaches();
++ }
+ }
+ }
+
+@@ -172,7 +183,8 @@
+ */
+ public URL findResource(String name, boolean check) {
+ Loader loader;
+- for (int i = 0; (loader = getLoader(i)) != null; i++) {
++ int[] cache = getLookupCache(name);
++ for (int i = 0; (loader = getNextLoader(cache, i)) != null; i++) {
+ URL url = loader.findResource(name, check);
+ if (url != null) {
+ return url;
+@@ -195,7 +207,8 @@
+ }
+
+ Loader loader;
+- for (int i = 0; (loader = getLoader(i)) != null; i++) {
++ int[] cache = getLookupCache(name);
++ for (int i = 0; (loader = getNextLoader(cache, i)) != null; i++) {
+ Resource res = loader.getResource(name, check);
+ if (res != null) {
+ return res;
+@@ -215,6 +228,7 @@
+ final boolean check) {
+ return new Enumeration<URL>() {
+ private int index = 0;
++ private int[] cache = getLookupCache(name);
+ private URL url = null;
+
+ private boolean next() {
+@@ -222,7 +236,7 @@
+ return true;
+ } else {
+ Loader loader;
+- while ((loader = getLoader(index++)) != null) {
++ while ((loader = getNextLoader(cache, index++)) != null) {
+ url = loader.findResource(name, check);
+ if (url != null) {
+ return true;
+@@ -262,6 +276,7 @@
+ final boolean check) {
+ return new Enumeration<Resource>() {
+ private int index = 0;
++ private int[] cache = getLookupCache(name);
+ private Resource res = null;
+
+ private boolean next() {
+@@ -269,7 +284,7 @@
+ return true;
+ } else {
+ Loader loader;
+- while ((loader = getLoader(index++)) != null) {
++ while ((loader = getNextLoader(cache, index++)) != null) {
+ res = loader.getResource(name, check);
+ if (res != null) {
+ return true;
+@@ -298,6 +313,151 @@
+ return getResources(name, true);
+ }
+
++ private static volatile boolean lookupCacheEnabled
++ = "true".equals(VM.getSavedProperty("sun.cds.enableSharedLookupCache"));
++ private URL[] lookupCacheURLs;
++ private ClassLoader lookupCacheLoader;
++
++ synchronized void initLookupCache(ClassLoader loader) {
++ if ((lookupCacheURLs = getLookupCacheURLs(loader)) != null) {
++ lookupCacheLoader = loader;
++ } else {
++ // This JVM instance does not support lookup cache.
++ disableAllLookupCaches();
++ }
++ }
++
++ static void disableAllLookupCaches() {
++ lookupCacheEnabled = false;
++ }
++
++ private static native URL[] getLookupCacheURLs(ClassLoader loader);
++ private static native int[] getLookupCacheForClassLoader(ClassLoader loader,
++ String name);
++ private static native boolean knownToNotExist0(ClassLoader loader,
++ String className);
++
++ synchronized boolean knownToNotExist(String className) {
++ if (lookupCacheURLs != null && lookupCacheEnabled) {
++ return knownToNotExist0(lookupCacheLoader, className);
++ }
++
++ // Don't know if this class exists or not -- need to do a full search.
++ return false;
++ }
++
++ /**
++ * Returns an array of the index to lookupCacheURLs that may
++ * contain the specified resource. The values in the returned
++ * array are in strictly ascending order and must be a valid index
++ * to lookupCacheURLs array.
++ *
++ * This method returns an empty array if the specified resource
++ * cannot be found in this URLClassPath. If there is no lookup
++ * cache or it's disabled, this method returns null and the lookup
++ * should search the entire classpath.
++ *
++ * Example: if lookupCacheURLs contains {a.jar, b.jar, c.jar, d.jar}
++ * and package "foo" only exists in a.jar and c.jar,
++ * getLookupCache("foo/Bar.class") will return {0, 2}
++ *
++ * @param name the resource name
++ * @return an array of the index to lookupCacheURLs that may contain the
++ * specified resource; or null if no lookup cache is used.
++ */
++ private synchronized int[] getLookupCache(String name) {
++ if (lookupCacheURLs == null || !lookupCacheEnabled) {
++ return null;
++ }
++
++ int[] cache = getLookupCacheForClassLoader(lookupCacheLoader, name);
++ if (cache != null && cache.length > 0) {
++ int maxindex = cache[cache.length - 1]; // cache[] is strictly ascending.
++ if (!ensureLoaderOpened(maxindex)) {
++ if (DEBUG_LOOKUP_CACHE) {
++ System.out.println("Expanded loaders FAILED " +
++ loaders.size() + " for maxindex=" + maxindex);
++ }
++ return null;
++ }
++ }
++
++ return cache;
++ }
++
++ private boolean ensureLoaderOpened(int index) {
++ if (loaders.size() <= index) {
++ // Open all Loaders up to, and including, index
++ if (getLoader(index) == null) {
++ return false;
++ }
++ if (!lookupCacheEnabled) {
++ // cache was invalidated as the result of the above call.
++ return false;
++ }
++ if (DEBUG_LOOKUP_CACHE) {
++ System.out.println("Expanded loaders " + loaders.size() +
++ " to index=" + index);
++ }
++ }
++ return true;
++ }
++
++ /*
++ * The CLASS-PATH attribute was expanded by the VM when building
++ * the resource lookup cache in the same order as the getLoader
++ * method does. This method validates if the URL from the lookup
++ * cache matches the URL of the Loader at the given index;
++ * otherwise, this method disables the lookup cache.
++ */
++ private synchronized void validateLookupCache(int index,
++ String urlNoFragString) {
++ if (lookupCacheURLs != null && lookupCacheEnabled) {
++ if (index < lookupCacheURLs.length &&
++ urlNoFragString.equals(
++ URLUtil.urlNoFragString(lookupCacheURLs[index]))) {
++ return;
++ }
++ if (DEBUG || DEBUG_LOOKUP_CACHE) {
++ System.out.println("WARNING: resource lookup cache invalidated "
++ + "for lookupCacheLoader at " + index);
++ }
++ disableAllLookupCaches();
++ }
++ }
++
++ /**
++ * Returns the next Loader that may contain the resource to
++ * lookup. If the given cache is null, return loaders.get(index)
++ * that may be lazily created; otherwise, cache[index] is the next
++ * Loader that may contain the resource to lookup and so returns
++ * loaders.get(cache[index]).
++ *
++ * If cache is non-null, loaders.get(cache[index]) must be present.
++ *
++ * @param cache lookup cache. If null, search the entire class path
++ * @param index index to the given cache array; or to the loaders list.
++ */
++ private synchronized Loader getNextLoader(int[] cache, int index) {
++ if (closed) {
++ return null;
++ }
++ if (cache != null) {
++ if (index < cache.length) {
++ Loader loader = loaders.get(cache[index]);
++ if (DEBUG_LOOKUP_CACHE) {
++ System.out.println("HASCACHE: Loading from : " + cache[index]
++ + " = " + loader.getBaseURL());
++ }
++ return loader;
++ } else {
++ return null; // finished iterating over cache[]
++ }
++ } else {
++ return getLoader(index);
++ }
++ }
++
+ /*
+ * Returns the Loader at the specified position in the URL search
+ * path. The URLs are opened and expanded as needed. Returns null
+@@ -341,9 +501,13 @@
+ continue;
+ }
+ // Finally, add the Loader to the search path.
++ validateLookupCache(loaders.size(), urlNoFragString);
+ loaders.add(loader);
+ lmap.put(urlNoFragString, loader);
+ }
++ if (DEBUG_LOOKUP_CACHE) {
++ System.out.println("NOCACHE: Loading from : " + index );
++ }
+ return loaders.get(index);
+ }
+
+--- ./jdk/src/share/classes/sun/misc/VM.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/misc/VM.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -313,6 +313,9 @@
+
+ // used by sun.launcher.LauncherHelper
+ props.remove("sun.java.launcher.diag");
++
++ // used by sun.misc.URLClassPath
++ props.remove("sun.cds.enableSharedLookupCache");
+ }
+
+ // Initialize any miscellenous operating system settings that need to be
+--- ./jdk/src/share/classes/sun/net/www/http/HttpClient.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/net/www/http/HttpClient.java Wed Feb 04 12:14:43 2015 -0800
+@@ -657,9 +657,10 @@
+ cachedHttpClient = false;
+ if (!failedOnce && requests != null) {
+ failedOnce = true;
+- if (getRequestMethod().equals("CONNECT") ||
+- (httpuc.getRequestMethod().equals("POST") &&
+- (!retryPostProp || streaming))) {
++ if (getRequestMethod().equals("CONNECT")
++ || streaming
++ || (httpuc.getRequestMethod().equals("POST")
++ && !retryPostProp)) {
+ // do not retry the request
+ } else {
+ // try once more
+@@ -769,9 +770,10 @@
+ } else if (nread != 8) {
+ if (!failedOnce && requests != null) {
+ failedOnce = true;
+- if (getRequestMethod().equals("CONNECT") ||
+- (httpuc.getRequestMethod().equals("POST") &&
+- (!retryPostProp || streaming))) {
++ if (getRequestMethod().equals("CONNECT")
++ || streaming
++ || (httpuc.getRequestMethod().equals("POST")
++ && !retryPostProp)) {
+ // do not retry the request
+ } else {
+ closeServer();
+--- ./jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Wed Feb 04 12:14:43 2015 -0800
+@@ -301,7 +301,7 @@
+ throw new IOException(fe);
+ }
+ try {
+- ftp.login(user, password.toCharArray());
++ ftp.login(user, password == null ? null : password.toCharArray());
+ } catch (sun.net.ftp.FtpProtocolException e) {
+ ftp.close();
+ // Backward compatibility
+--- ./jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1046,7 +1046,7 @@
+ try {
+ URI uri = ParseUtil.toURI(url);
+ if (uri != null) {
+- cachedResponse = cacheHandler.get(uri, getRequestMethod(), requests.getHeaders(EXCLUDE_HEADERS));
++ cachedResponse = cacheHandler.get(uri, getRequestMethod(), getUserSetHeaders().getHeaders());
+ if ("https".equalsIgnoreCase(uri.getScheme())
+ && !(cachedResponse instanceof SecureCacheResponse)) {
+ cachedResponse = null;
+--- ./jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -195,15 +195,8 @@
+ synchronized (stateLock) {
+ ensureOpen();
+
+- if (name == StandardSocketOptions.IP_TOS) {
+- // IPv4 only; no-op for IPv6
+- if (family == StandardProtocolFamily.INET) {
+- Net.setSocketOption(fd, family, name, value);
+- }
+- return this;
+- }
+-
+- if (name == StandardSocketOptions.IP_MULTICAST_TTL ||
++ if (name == StandardSocketOptions.IP_TOS ||
++ name == StandardSocketOptions.IP_MULTICAST_TTL ||
+ name == StandardSocketOptions.IP_MULTICAST_LOOP)
+ {
+ // options are protocol dependent
+@@ -256,16 +249,8 @@
+ synchronized (stateLock) {
+ ensureOpen();
+
+- if (name == StandardSocketOptions.IP_TOS) {
+- // IPv4 only; always return 0 on IPv6
+- if (family == StandardProtocolFamily.INET) {
+- return (T) Net.getSocketOption(fd, family, name);
+- } else {
+- return (T) Integer.valueOf(0);
+- }
+- }
+-
+- if (name == StandardSocketOptions.IP_MULTICAST_TTL ||
++ if (name == StandardSocketOptions.IP_TOS ||
++ name == StandardSocketOptions.IP_MULTICAST_TTL ||
+ name == StandardSocketOptions.IP_MULTICAST_LOOP)
+ {
+ return (T) Net.getSocketOption(fd, family, name);
+--- ./jdk/src/share/classes/sun/nio/ch/Net.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/nio/ch/Net.java Wed Feb 04 12:14:43 2015 -0800
+@@ -352,7 +352,8 @@
+ }
+
+ boolean mayNeedConversion = (family == UNSPEC);
+- setIntOption0(fd, mayNeedConversion, key.level(), key.name(), arg);
++ boolean isIPv6 = (family == StandardProtocolFamily.INET6);
++ setIntOption0(fd, mayNeedConversion, key.level(), key.name(), arg, isIPv6);
+ }
+
+ static Object getSocketOption(FileDescriptor fd, ProtocolFamily family,
+@@ -499,7 +500,7 @@
+ throws IOException;
+
+ private static native void setIntOption0(FileDescriptor fd, boolean mayNeedConversion,
+- int level, int opt, int arg)
++ int level, int opt, int arg, boolean isIPv6)
+ throws IOException;
+
+ static native int poll(FileDescriptor fd, int events, long timeout)
+--- ./jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -133,6 +133,14 @@
+ synchronized (stateLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
++
++ if (name == StandardSocketOptions.IP_TOS) {
++ ProtocolFamily family = Net.isIPv6Available() ?
++ StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
++ Net.setSocketOption(fd, family, name, value);
++ return this;
++ }
++
+ if (name == StandardSocketOptions.SO_REUSEADDR &&
+ Net.useExclusiveBind())
+ {
+@@ -177,6 +185,7 @@
+ HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(2);
+ set.add(StandardSocketOptions.SO_RCVBUF);
+ set.add(StandardSocketOptions.SO_REUSEADDR);
++ set.add(StandardSocketOptions.IP_TOS);
+ return Collections.unmodifiableSet(set);
+ }
+ }
+@@ -238,7 +247,7 @@
+ return null;
+ thread = NativeThread.current();
+ for (;;) {
+- n = accept0(this.fd, newfd, isaa);
++ n = accept(this.fd, newfd, isaa);
+ if ((n == IOStatus.INTERRUPTED) && isOpen())
+ continue;
+ break;
+@@ -401,6 +410,18 @@
+ return sb.toString();
+ }
+
++ /**
++ * Accept a connection on a socket.
++ *
++ * @implNote Wrap native call to allow instrumentation.
++ */
++ private int accept(FileDescriptor ssfd, FileDescriptor newfd,
++ InetSocketAddress[] isaa)
++ throws IOException
++ {
++ return accept0(ssfd, newfd, isaa);
++ }
++
+ // -- Native methods --
+
+ // Accepts a new connection, setting the given file descriptor to refer to
+--- ./jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -173,14 +173,14 @@
+ if (!isOpen())
+ throw new ClosedChannelException();
+
+- // special handling for IP_TOS: no-op when IPv6
+ if (name == StandardSocketOptions.IP_TOS) {
+- if (!Net.isIPv6Available())
+- Net.setSocketOption(fd, StandardProtocolFamily.INET, name, value);
++ ProtocolFamily family = Net.isIPv6Available() ?
++ StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
++ Net.setSocketOption(fd, family, name, value);
+ return this;
+- } else if (name == StandardSocketOptions.SO_REUSEADDR &&
+- Net.useExclusiveBind())
+- {
++ }
++
++ if (name == StandardSocketOptions.SO_REUSEADDR && Net.useExclusiveBind()) {
+ // SO_REUSEADDR emulated when using exclusive bind
+ isReuseAddress = (Boolean)value;
+ return this;
+@@ -215,8 +215,9 @@
+
+ // special handling for IP_TOS: always return 0 when IPv6
+ if (name == StandardSocketOptions.IP_TOS) {
+- return (Net.isIPv6Available()) ? (T) Integer.valueOf(0) :
+- (T) Net.getSocketOption(fd, StandardProtocolFamily.INET, name);
++ ProtocolFamily family = Net.isIPv6Available() ?
++ StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
++ return (T) Net.getSocketOption(fd, family, name);
+ }
+
+ // no options that require special handling
+--- ./jdk/src/share/classes/sun/nio/fs/AbstractPoller.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/nio/fs/AbstractPoller.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -100,8 +100,6 @@
+ // validate arguments before request to poller
+ if (dir == null)
+ throw new NullPointerException();
+- if (events.length == 0)
+- throw new IllegalArgumentException("No events to register");
+ Set<WatchEvent.Kind<?>> eventSet = new HashSet<>(events.length);
+ for (WatchEvent.Kind<?> event: events) {
+ // standard events
+@@ -114,17 +112,16 @@
+ }
+
+ // OVERFLOW is ignored
+- if (event == StandardWatchEventKinds.OVERFLOW) {
+- if (events.length == 1)
+- throw new IllegalArgumentException("No events to register");
++ if (event == StandardWatchEventKinds.OVERFLOW)
+ continue;
+- }
+
+ // null/unsupported
+ if (event == null)
+ throw new NullPointerException("An element in event set is 'null'");
+ throw new UnsupportedOperationException(event.name());
+ }
++ if (eventSet.isEmpty())
++ throw new IllegalArgumentException("No events to register");
+ return (WatchKey)invoke(RequestType.REGISTER, dir, eventSet, modifiers);
+ }
+
+@@ -192,14 +189,17 @@
+ * the request.
+ */
+ Object awaitResult() {
++ boolean interrupted = false;
+ synchronized (this) {
+ while (!completed) {
+ try {
+ wait();
+ } catch (InterruptedException x) {
+- // ignore
++ interrupted = true;
+ }
+ }
++ if (interrupted)
++ Thread.currentThread().interrupt();
+ return result;
+ }
+ }
+--- ./jdk/src/share/classes/sun/nio/fs/PollingWatchService.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/nio/fs/PollingWatchService.java Wed Feb 04 12:14:43 2015 -0800
+@@ -74,8 +74,6 @@
+ throws IOException
+ {
+ // check events - CCE will be thrown if there are invalid elements
+- if (events.length == 0)
+- throw new IllegalArgumentException("No events to register");
+ final Set<WatchEvent.Kind<?>> eventSet =
+ new HashSet<WatchEvent.Kind<?>>(events.length);
+ for (WatchEvent.Kind<?> event: events) {
+@@ -90,8 +88,6 @@
+
+ // OVERFLOW is ignored
+ if (event == StandardWatchEventKinds.OVERFLOW) {
+- if (events.length == 1)
+- throw new IllegalArgumentException("No events to register");
+ continue;
+ }
+
+@@ -100,6 +96,8 @@
+ throw new NullPointerException("An element in event set is 'null'");
+ throw new UnsupportedOperationException(event.name());
+ }
++ if (eventSet.isEmpty())
++ throw new IllegalArgumentException("No events to register");
+
+ // A modifier may be used to specify the sensitivity level
+ SensitivityWatchEventModifier sensivity = SensitivityWatchEventModifier.MEDIUM;
+--- ./jdk/src/share/classes/sun/print/CustomMediaSizeName.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/print/CustomMediaSizeName.java Wed Feb 04 12:14:43 2015 -0800
+@@ -67,6 +67,22 @@
+ MediaSize.INCH);
+ } catch (IllegalArgumentException iae) {
+ }
++ // The public API method finds a closest match even if it not
++ // all that close. Here we want to be sure its *really* close.
++ if (mediaName != null) {
++ MediaSize sz = MediaSize.getMediaSizeForName(mediaName);
++ if (sz == null) {
++ mediaName = null;
++ } else {
++ float w = sz.getX(MediaSize.INCH);
++ float h = sz.getY(MediaSize.INCH);
++ float dw = Math.abs(w - width);
++ float dh = Math.abs(h - length);
++ if (dw > 0.1 || dh > 0.1) {
++ mediaName = null;
++ }
++ }
++ }
+ }
+
+ /**
+--- ./jdk/src/share/classes/sun/reflect/BootstrapConstructorAccessorImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/BootstrapConstructorAccessorImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -32,7 +32,7 @@
+ bootstrapping. */
+
+ class BootstrapConstructorAccessorImpl extends ConstructorAccessorImpl {
+- private Constructor<?> constructor;
++ private final Constructor<?> constructor;
+
+ BootstrapConstructorAccessorImpl(Constructor<?> c) {
+ this.constructor = c;
+--- ./jdk/src/share/classes/sun/reflect/InstantiationExceptionConstructorAccessorImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/InstantiationExceptionConstructorAccessorImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -33,7 +33,7 @@
+
+ class InstantiationExceptionConstructorAccessorImpl
+ extends ConstructorAccessorImpl {
+- private String message;
++ private final String message;
+
+ InstantiationExceptionConstructorAccessorImpl(String message) {
+ this.message = message;
+--- ./jdk/src/share/classes/sun/reflect/Label.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/Label.java Wed Feb 04 12:14:43 2015 -0800
+@@ -47,10 +47,10 @@
+ }
+ // This won't work for more than one assembler anyway, so this is
+ // unnecessary
+- ClassFileAssembler asm;
+- short instrBCI;
+- short patchBCI;
+- int stackDepth;
++ final ClassFileAssembler asm;
++ final short instrBCI;
++ final short patchBCI;
++ final int stackDepth;
+ }
+ private List<PatchInfo> patches = new ArrayList<>();
+
+--- ./jdk/src/share/classes/sun/reflect/NativeConstructorAccessorImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/NativeConstructorAccessorImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -32,7 +32,7 @@
+ afterward, switches to bytecode-based implementation */
+
+ class NativeConstructorAccessorImpl extends ConstructorAccessorImpl {
+- private Constructor<?> c;
++ private final Constructor<?> c;
+ private DelegatingConstructorAccessorImpl parent;
+ private int numInvocations;
+
+--- ./jdk/src/share/classes/sun/reflect/NativeMethodAccessorImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/NativeMethodAccessorImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -32,7 +32,7 @@
+ switches to bytecode-based implementation */
+
+ class NativeMethodAccessorImpl extends MethodAccessorImpl {
+- private Method method;
++ private final Method method;
+ private DelegatingMethodAccessorImpl parent;
+ private int numInvocations;
+
+--- ./jdk/src/share/classes/sun/reflect/Reflection.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/Reflection.java Wed Feb 04 12:14:43 2015 -0800
+@@ -46,6 +46,7 @@
+ map.put(Reflection.class,
+ new String[] {"fieldFilterMap", "methodFilterMap"});
+ map.put(System.class, new String[] {"security"});
++ map.put(Class.class, new String[] {"classLoader"});
+ fieldFilterMap = map;
+
+ methodFilterMap = new HashMap<>();
+--- ./jdk/src/share/classes/sun/reflect/ReflectionFactory.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/ReflectionFactory.java Wed Feb 04 12:14:43 2015 -0800
+@@ -50,9 +50,9 @@
+ public class ReflectionFactory {
+
+ private static boolean initted = false;
+- private static Permission reflectionFactoryAccessPerm
++ private static final Permission reflectionFactoryAccessPerm
+ = new RuntimePermission("reflectionFactoryAccess");
+- private static ReflectionFactory soleInstance = new ReflectionFactory();
++ private static final ReflectionFactory soleInstance = new ReflectionFactory();
+ // Provides access to package-private mechanisms in java.lang.reflect
+ private static volatile LangReflectAccess langReflectAccess;
+
+--- ./jdk/src/share/classes/sun/reflect/SignatureIterator.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/SignatureIterator.java Wed Feb 04 12:14:43 2015 -0800
+@@ -28,7 +28,7 @@
+ /** Assists in iterating down a method's signature */
+
+ public class SignatureIterator {
+- private String sig;
++ private final String sig;
+ private int idx;
+
+ public SignatureIterator(String sig) {
+--- ./jdk/src/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java Wed Feb 04 12:14:43 2015 -0800
+@@ -45,8 +45,8 @@
+ * core reflection (java.lang.reflect).
+ */
+ public class CoreReflectionFactory implements GenericsFactory {
+- private GenericDeclaration decl;
+- private Scope scope;
++ private final GenericDeclaration decl;
++ private final Scope scope;
+
+ private CoreReflectionFactory(GenericDeclaration d, Scope s) {
+ decl = d;
+--- ./jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -34,7 +34,7 @@
+ */
+ public class GenericArrayTypeImpl
+ implements GenericArrayType {
+- private Type genericComponentType;
++ private final Type genericComponentType;
+
+ // private constructor enforces use of static factory
+ private GenericArrayTypeImpl(Type ct) {
+--- ./jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java Wed Feb 04 12:14:43 2015 -0800
+@@ -40,7 +40,7 @@
+ *
+ */
+ public abstract class LazyReflectiveObjectGenerator {
+- private GenericsFactory factory; // cached factory
++ private final GenericsFactory factory; // cached factory
+
+ protected LazyReflectiveObjectGenerator(GenericsFactory f) {
+ factory = f;
+--- ./jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -38,9 +38,9 @@
+ /** Implementing class for ParameterizedType interface. */
+
+ public class ParameterizedTypeImpl implements ParameterizedType {
+- private Type[] actualTypeArguments;
+- private Class<?> rawType;
+- private Type ownerType;
++ private final Type[] actualTypeArguments;
++ private final Class<?> rawType;
++ private final Type ownerType;
+
+ private ParameterizedTypeImpl(Class<?> rawType,
+ Type[] actualTypeArguments,
+--- ./jdk/src/share/classes/sun/reflect/generics/repository/AbstractRepository.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/repository/AbstractRepository.java Wed Feb 04 12:14:43 2015 -0800
+@@ -40,9 +40,9 @@
+
+ // A factory used to produce reflective objects. Provided when the
+ //repository is created. Will vary across implementations.
+- private GenericsFactory factory;
++ private final GenericsFactory factory;
+
+- private T tree; // the AST for the generic type info
++ private final T tree; // the AST for the generic type info
+
+ //accessors
+ private GenericsFactory getFactory() { return factory;}
+--- ./jdk/src/share/classes/sun/reflect/generics/repository/ClassRepository.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/repository/ClassRepository.java Wed Feb 04 12:14:43 2015 -0800
+@@ -42,8 +42,8 @@
+
+ public static final ClassRepository NONE = ClassRepository.make("Ljava/lang/Object;", null);
+
+- private Type superclass; // caches the generic superclass info
+- private Type[] superInterfaces; // caches the generic superinterface info
++ private volatile Type superclass; // caches the generic superclass info
++ private volatile Type[] superInterfaces; // caches the generic superinterface info
+
+ // private, to enforce use of static factory
+ private ClassRepository(String rawSig, GenericsFactory f) {
+@@ -80,17 +80,20 @@
+ */
+
+ public Type getSuperclass(){
++ Type superclass = this.superclass;
+ if (superclass == null) { // lazily initialize superclass
+ Reifier r = getReifier(); // obtain visitor
+ // Extract superclass subtree from AST and reify
+ getTree().getSuperclass().accept(r);
+ // extract result from visitor and cache it
+ superclass = r.getResult();
++ this.superclass = superclass;
+ }
+ return superclass; // return cached result
+ }
+
+ public Type[] getSuperInterfaces(){
++ Type[] superInterfaces = this.superInterfaces;
+ if (superInterfaces == null) { // lazily initialize super interfaces
+ // first, extract super interface subtree(s) from AST
+ TypeTree[] ts = getTree().getSuperInterfaces();
+@@ -104,6 +107,7 @@
+ sis[i] = r.getResult();
+ }
+ superInterfaces = sis; // cache overall result
++ this.superInterfaces = superInterfaces;
+ }
+ return superInterfaces.clone(); // return cached result
+ }
+--- ./jdk/src/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/repository/GenericDeclRepository.java Wed Feb 04 12:14:43 2015 -0800
+@@ -42,7 +42,7 @@
+ public abstract class GenericDeclRepository<S extends Signature>
+ extends AbstractRepository<S> {
+
+- private TypeVariable<?>[] typeParams; // caches the formal type parameters
++ private volatile TypeVariable<?>[] typeParams; // caches the formal type parameters
+
+ protected GenericDeclRepository(String rawSig, GenericsFactory f) {
+ super(rawSig, f);
+@@ -65,6 +65,7 @@
+ * @return the formal type parameters of this generic declaration
+ */
+ public TypeVariable<?>[] getTypeParameters(){
++ TypeVariable[] typeParams = this.typeParams;
+ if (typeParams == null) { // lazily initialize type parameters
+ // first, extract type parameter subtree(s) from AST
+ FormalTypeParameter[] ftps = getTree().getFormalTypeParameters();
+@@ -78,6 +79,7 @@
+ tps[i] = (TypeVariable<?>) r.getResult();
+ }
+ typeParams = tps; // cache overall result
++ this.typeParams = typeParams;
+ }
+ return typeParams.clone(); // return cached result
+ }
+--- ./jdk/src/share/classes/sun/reflect/generics/scope/AbstractScope.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/scope/AbstractScope.java Wed Feb 04 12:14:43 2015 -0800
+@@ -41,8 +41,8 @@
+ public abstract class AbstractScope<D extends GenericDeclaration>
+ implements Scope {
+
+- private D recvr; // the declaration whose scope this instance represents
+- private Scope enclosingScope; // the enclosing scope of this scope
++ private final D recvr; // the declaration whose scope this instance represents
++ private volatile Scope enclosingScope; // the enclosing scope of this scope
+
+ /**
+ * Constructor. Takes a reflective object whose scope the newly
+@@ -71,7 +71,11 @@
+ * @return the enclosing scope
+ */
+ protected Scope getEnclosingScope(){
+- if (enclosingScope == null) {enclosingScope = computeEnclosingScope();}
++ Scope enclosingScope = this.enclosingScope;
++ if (enclosingScope == null) {
++ enclosingScope = computeEnclosingScope();
++ this.enclosingScope = enclosingScope;
++ }
+ return enclosingScope;
+ }
+
+--- ./jdk/src/share/classes/sun/reflect/generics/scope/DummyScope.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/scope/DummyScope.java Wed Feb 04 12:14:43 2015 -0800
+@@ -38,7 +38,7 @@
+ public class DummyScope implements Scope {
+ // Caches the unique instance of this class; instances contain no data
+ // so we can use the singleton pattern
+- private static DummyScope singleton = new DummyScope();
++ private static final DummyScope singleton = new DummyScope();
+
+ // constructor is private to enforce use of factory method
+ private DummyScope(){}
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/ArrayTypeSignature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/ArrayTypeSignature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -28,7 +28,7 @@
+ import sun.reflect.generics.visitor.TypeTreeVisitor;
+
+ public class ArrayTypeSignature implements FieldTypeSignature {
+- private TypeSignature componentType;
++ private final TypeSignature componentType;
+
+ private ArrayTypeSignature(TypeSignature ct) {componentType = ct;}
+
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/BooleanSignature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/BooleanSignature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -29,7 +29,7 @@
+
+ /** AST that represents the type boolean. */
+ public class BooleanSignature implements BaseType {
+- private static BooleanSignature singleton = new BooleanSignature();
++ private static final BooleanSignature singleton = new BooleanSignature();
+
+ private BooleanSignature(){}
+
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/BottomSignature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/BottomSignature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -28,7 +28,7 @@
+ import sun.reflect.generics.visitor.TypeTreeVisitor;
+
+ public class BottomSignature implements FieldTypeSignature {
+- private static BottomSignature singleton = new BottomSignature();
++ private static final BottomSignature singleton = new BottomSignature();
+
+ private BottomSignature(){}
+
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/ByteSignature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/ByteSignature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -29,7 +29,7 @@
+
+ /** AST that represents the type byte. */
+ public class ByteSignature implements BaseType {
+- private static ByteSignature singleton = new ByteSignature();
++ private static final ByteSignature singleton = new ByteSignature();
+
+ private ByteSignature(){}
+
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/CharSignature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/CharSignature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -29,7 +29,7 @@
+
+ /** AST that represents the type char. */
+ public class CharSignature implements BaseType {
+- private static CharSignature singleton = new CharSignature();
++ private static final CharSignature singleton = new CharSignature();
+
+ private CharSignature(){}
+
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/ClassSignature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/ClassSignature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -28,9 +28,9 @@
+ import sun.reflect.generics.visitor.Visitor;
+
+ public class ClassSignature implements Signature {
+- private FormalTypeParameter[] formalTypeParams;
+- private ClassTypeSignature superclass;
+- private ClassTypeSignature[] superInterfaces;
++ private final FormalTypeParameter[] formalTypeParams;
++ private final ClassTypeSignature superclass;
++ private final ClassTypeSignature[] superInterfaces;
+
+ private ClassSignature(FormalTypeParameter[] ftps,
+ ClassTypeSignature sc,
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/ClassTypeSignature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/ClassTypeSignature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -33,7 +33,7 @@
+ * AST representing class types.
+ */
+ public class ClassTypeSignature implements FieldTypeSignature {
+- private List<SimpleClassTypeSignature> path;
++ private final List<SimpleClassTypeSignature> path;
+
+
+ private ClassTypeSignature(List<SimpleClassTypeSignature> p) {
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/DoubleSignature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/DoubleSignature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -29,7 +29,7 @@
+
+ /** AST that represents the type double. */
+ public class DoubleSignature implements BaseType {
+- private static DoubleSignature singleton = new DoubleSignature();
++ private static final DoubleSignature singleton = new DoubleSignature();
+
+ private DoubleSignature(){}
+
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/FloatSignature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/FloatSignature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -29,7 +29,7 @@
+
+ /** AST that represents the type float. */
+ public class FloatSignature implements BaseType {
+- private static FloatSignature singleton = new FloatSignature();
++ private static final FloatSignature singleton = new FloatSignature();
+
+ private FloatSignature(){}
+
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/FormalTypeParameter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/FormalTypeParameter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -29,8 +29,8 @@
+
+ /** AST that represents a formal type parameter. */
+ public class FormalTypeParameter implements TypeTree {
+- private String name;
+- private FieldTypeSignature[] bounds;
++ private final String name;
++ private final FieldTypeSignature[] bounds;
+
+ private FormalTypeParameter(String n, FieldTypeSignature[] bs) {
+ name = n;
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/IntSignature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/IntSignature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -29,7 +29,7 @@
+
+ /** AST that represents the type int. */
+ public class IntSignature implements BaseType {
+- private static IntSignature singleton = new IntSignature();
++ private static final IntSignature singleton = new IntSignature();
+
+ private IntSignature(){}
+
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/LongSignature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/LongSignature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -29,7 +29,7 @@
+
+ /** AST that represents the type long. */
+ public class LongSignature implements BaseType {
+- private static LongSignature singleton = new LongSignature();
++ private static final LongSignature singleton = new LongSignature();
+
+ private LongSignature(){}
+
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/MethodTypeSignature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/MethodTypeSignature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -28,10 +28,10 @@
+ import sun.reflect.generics.visitor.Visitor;
+
+ public class MethodTypeSignature implements Signature {
+- private FormalTypeParameter[] formalTypeParams;
+- private TypeSignature[] parameterTypes;
+- private ReturnType returnType;
+- private FieldTypeSignature[] exceptionTypes;
++ private final FormalTypeParameter[] formalTypeParams;
++ private final TypeSignature[] parameterTypes;
++ private final ReturnType returnType;
++ private final FieldTypeSignature[] exceptionTypes;
+
+ private MethodTypeSignature(FormalTypeParameter[] ftps,
+ TypeSignature[] pts,
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/ShortSignature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/ShortSignature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -29,7 +29,7 @@
+
+ /** AST that represents the type short. */
+ public class ShortSignature implements BaseType {
+- private static ShortSignature singleton = new ShortSignature();
++ private static final ShortSignature singleton = new ShortSignature();
+
+ private ShortSignature(){}
+
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/SimpleClassTypeSignature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/SimpleClassTypeSignature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -28,9 +28,9 @@
+ import sun.reflect.generics.visitor.TypeTreeVisitor;
+
+ public class SimpleClassTypeSignature implements FieldTypeSignature {
+- private boolean dollar;
+- private String name;
+- private TypeArgument[] typeArgs;
++ private final boolean dollar;
++ private final String name;
++ private final TypeArgument[] typeArgs;
+
+ private SimpleClassTypeSignature(String n, boolean dollar, TypeArgument[] tas) {
+ name = n;
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/TypeVariableSignature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/TypeVariableSignature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -28,7 +28,7 @@
+ import sun.reflect.generics.visitor.TypeTreeVisitor;
+
+ public class TypeVariableSignature implements FieldTypeSignature {
+- private String identifier;
++ private final String identifier;
+
+ private TypeVariableSignature(String id) {identifier = id;}
+
+--- ./jdk/src/share/classes/sun/reflect/generics/tree/VoidDescriptor.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/generics/tree/VoidDescriptor.java Wed Feb 04 12:14:43 2015 -0800
+@@ -30,7 +30,7 @@
+
+ /** AST that represents the pseudo-type void. */
+ public class VoidDescriptor implements ReturnType {
+- private static VoidDescriptor singleton = new VoidDescriptor();
++ private static final VoidDescriptor singleton = new VoidDescriptor();
+
+ private VoidDescriptor(){}
+
+--- ./jdk/src/share/classes/sun/reflect/misc/MethodUtil.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/reflect/misc/MethodUtil.java Wed Feb 04 12:14:43 2015 -0800
+@@ -76,9 +76,9 @@
+ * Create a trampoline class.
+ */
+ public final class MethodUtil extends SecureClassLoader {
+- private static String MISC_PKG = "sun.reflect.misc.";
+- private static String TRAMPOLINE = MISC_PKG + "Trampoline";
+- private static Method bounce = getTrampoline();
++ private static final String MISC_PKG = "sun.reflect.misc.";
++ private static final String TRAMPOLINE = MISC_PKG + "Trampoline";
++ private static final Method bounce = getTrampoline();
+
+ private MethodUtil() {
+ super();
+--- ./jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java Wed Feb 04 12:14:43 2015 -0800
+@@ -241,8 +241,11 @@
+ * establishment.
+ */
+ public final void requestCredDeleg(boolean value) throws GSSException {
+- if (state == STATE_NEW && isInitiator())
+- credDelegState = value;
++ if (state == STATE_NEW && isInitiator()) {
++ if (myCred == null || !(myCred instanceof Krb5ProxyCredential)) {
++ credDelegState = value;
++ }
++ }
+ }
+
+ /**
+--- ./jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java Wed Feb 04 12:14:43 2015 -0800
+@@ -523,13 +523,6 @@
+ valid = false;
+ }
+
+- // get the mechanism token
+- byte[] mechToken = initToken.getMechToken();
+- if (mechToken == null) {
+- throw new GSSException(GSSException.FAILURE, -1,
+- "mechToken is missing");
+- }
+-
+ /*
+ * Select the best match between the list of mechs
+ * that the initiator requested and the list that
+@@ -545,7 +538,19 @@
+ internal_mech = mech_wanted;
+
+ // get the token for mechanism
+- byte[] accept_token = GSS_acceptSecContext(mechToken);
++ byte[] accept_token;
++
++ if (mechList[0].equals(mech_wanted)) {
++ // get the mechanism token
++ byte[] mechToken = initToken.getMechToken();
++ if (mechToken == null) {
++ throw new GSSException(GSSException.FAILURE, -1,
++ "mechToken is missing");
++ }
++ accept_token = GSS_acceptSecContext(mechToken);
++ } else {
++ accept_token = null;
++ }
+
+ // verify MIC
+ if (!GSSUtil.useMSInterop() && valid) {
+@@ -594,9 +599,27 @@
+ retVal = targToken.getEncoded();
+
+ } else if (state == STATE_IN_PROCESS) {
++ // read data
++ byte[] token = new byte[is.available()];
++ SpNegoToken.readFully(is, token);
++ if (DEBUG) {
++ System.out.println("SpNegoContext.acceptSecContext: " +
++ "receiving token = " +
++ SpNegoToken.getHexBytes(token));
++ }
++
++ // read the SPNEGO token
++ // token will be validated when parsing
++ NegTokenTarg inputToken = new NegTokenTarg(token);
++
++ if (DEBUG) {
++ System.out.println("SpNegoContext.acceptSecContext: " +
++ "received token of type = " +
++ SpNegoToken.getTokenName(inputToken.getType()));
++ }
++
+ // read the token
+- byte[] client_token = new byte[is.available()];
+- SpNegoToken.readFully(is, client_token);
++ byte[] client_token = inputToken.getResponseToken();
+ byte[] accept_token = GSS_acceptSecContext(client_token);
+ if (accept_token == null) {
+ valid = false;
+@@ -1055,7 +1078,7 @@
+ * This is only valid on the acceptor side of the context.
+ * @return GSSCredentialSpi object for the delegated credential
+ * @exception GSSException
+- * @see GSSContext#getDelegCredState
++ * @see GSSContext#getCredDelegState
+ */
+ public final GSSCredentialSpi getDelegCred() throws GSSException {
+ if (state != STATE_IN_PROCESS && state != STATE_DONE)
+--- ./jdk/src/share/classes/sun/security/jgss/wrapper/GSSLibStub.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/jgss/wrapper/GSSLibStub.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -48,10 +48,11 @@
+ /**
+ * Initialization routine to dynamically load function pointers.
+ *
+- * @param library name to dlopen
++ * @param lib library name to dlopen
++ * @param debug set to true for reporting native debugging info
+ * @return true if succeeded, false otherwise.
+ */
+- static native boolean init(String lib);
++ static native boolean init(String lib, boolean debug);
+ private static native long getMechPtr(byte[] oidDerEncoding);
+
+ // Miscellaneous routines
+--- ./jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -100,7 +100,7 @@
+ gssLibs = new String[]{ defaultLib };
+ }
+ for (String libName: gssLibs) {
+- if (GSSLibStub.init(libName)) {
++ if (GSSLibStub.init(libName, DEBUG)) {
+ debug("Loaded GSS library: " + libName);
+ Oid[] mechs = GSSLibStub.indicateMechs();
+ HashMap<String, String> map =
+--- ./jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java Wed Feb 04 12:14:43 2015 -0800
+@@ -32,9 +32,11 @@
+
+ import java.io.IOException;
+ import java.io.InputStream;
+-import java.util.Hashtable;
+-import java.util.Vector;
++import java.util.ArrayList;
++import java.util.List;
+ import java.util.StringTokenizer;
++
++import sun.misc.IOUtils;
+ import sun.security.krb5.*;
+ import sun.security.krb5.internal.*;
+ import sun.security.krb5.internal.util.KrbDataInputStream;
+@@ -74,7 +76,6 @@
+ // this needs to be public for Kinit.
+ public Tag readTag() throws IOException {
+ char[] buf = new char[1024];
+- byte[] bytes;
+ int len;
+ int tag = -1;
+ int taglen;
+@@ -85,7 +86,6 @@
+ if (len < 0) {
+ throw new IOException("stop.");
+ }
+- bytes = new byte[len + 2];
+ if (len > buf.length) {
+ throw new IOException("Invalid tag length.");
+ }
+@@ -101,11 +101,7 @@
+ }
+ len = len - (4 + taglen);
+ }
+- Tag result;
+- if (tag == -1) {
+- }
+- result = new Tag(len, tag, time_offset, usec_offset);
+- return result;
++ return new Tag(len, tag, time_offset, usec_offset);
+ }
+ /*
+ * In file-based credential cache, the realm name is stored as part of
+@@ -123,7 +119,7 @@
+ type = read(4);
+ }
+ length = readLength4();
+- String[] result = new String[length + 1];
++ List<String> result = new ArrayList<String>();
+ /*
+ * DCE includes the principal's realm in the count; the new format
+ * does not.
+@@ -132,21 +128,26 @@
+ length--;
+ for (int i = 0; i <= length; i++) {
+ namelength = readLength4();
+- if (namelength > MAXNAMELENGTH) {
+- throw new IOException("Invalid name length in principal name.");
++ byte[] bytes = IOUtils.readFully(this, namelength, true);
++ result.add(new String(bytes));
++ }
++ if (result.isEmpty()) {
++ throw new IOException("No realm or principal");
++ }
++ if (isRealm(result.get(0))) {
++ realm = result.remove(0);
++ if (result.isEmpty()) {
++ throw new IOException("No principal name components");
+ }
+- byte[] bytes = new byte[namelength];
+- read(bytes, 0, namelength);
+- result[i] = new String(bytes);
+- }
+- if (isRealm(result[0])) {
+- realm = result[0];
+- pname = new String[length];
+- System.arraycopy(result, 1, pname, 0, length);
+- return new PrincipalName(type, pname, new Realm(realm));
++ return new PrincipalName(
++ type,
++ result.toArray(new String[result.size()]),
++ new Realm(realm));
+ }
+ try {
+- return new PrincipalName(result, type);
++ return new PrincipalName(
++ result.toArray(new String[result.size()]),
++ type);
+ } catch (RealmException re) {
+ return null;
+ }
+@@ -184,10 +185,7 @@
+ if (version == KRB5_FCC_FVNO_3)
+ read(2); /* keytype recorded twice in fvno 3 */
+ keyLen = readLength4();
+- byte[] bytes = new byte[keyLen];
+- for (int i = 0; i < keyLen; i++) {
+- bytes[i] = (byte)read();
+- }
++ byte[] bytes = IOUtils.readFully(this, keyLen, true);
+ return new EncryptionKey(bytes, keyType, new Integer(version));
+ }
+
+@@ -211,7 +209,7 @@
+ int numAddrs, addrType, addrLength;
+ numAddrs = readLength4();
+ if (numAddrs > 0) {
+- HostAddress[] addrs = new HostAddress[numAddrs];
++ List<HostAddress> addrs = new ArrayList<>();
+ for (int i = 0; i < numAddrs; i++) {
+ addrType = read(2);
+ addrLength = readLength4();
+@@ -224,9 +222,9 @@
+ byte[] result = new byte[addrLength];
+ for (int j = 0; j < addrLength; j++)
+ result[j] = (byte)read(1);
+- addrs[i] = new HostAddress(addrType, result);
++ addrs.add(new HostAddress(addrType, result));
+ }
+- return addrs;
++ return addrs.toArray(new HostAddress[addrs.size()]);
+ }
+ return null;
+ }
+@@ -235,18 +233,15 @@
+ int num, adtype, adlength;
+ num = readLength4();
+ if (num > 0) {
+- AuthorizationDataEntry[] auData = new AuthorizationDataEntry[num];
++ List<AuthorizationDataEntry> auData = new ArrayList<>();
+ byte[] data = null;
+ for (int i = 0; i < num; i++) {
+ adtype = read(2);
+ adlength = readLength4();
+- data = new byte[adlength];
+- for (int j = 0; j < adlength; j++) {
+- data[j] = (byte)read();
+- }
+- auData[i] = new AuthorizationDataEntry(adtype, data);
++ data = IOUtils.readFully(this, adlength, true);
++ auData.add(new AuthorizationDataEntry(adtype, data));
+ }
+- return auData;
++ return auData.toArray(new AuthorizationDataEntry[auData.size()]);
+ }
+ else return null;
+ }
+@@ -257,9 +252,7 @@
+ if (length == 0) {
+ return null;
+ } else {
+- byte[] bytes = new byte[length];
+- read(bytes, 0, length);
+- return bytes;
++ return IOUtils.readFully(this, length, true);
+ }
+ }
+
+@@ -341,15 +334,29 @@
+ * returns null.
+ */
+ Credentials readCred(int version) throws IOException,RealmException, KrbApErrException, Asn1Exception {
+- PrincipalName cpname = readPrincipal(version);
+- if (DEBUG)
++ PrincipalName cpname = null;
++ try {
++ cpname = readPrincipal(version);
++ } catch (Exception e) {
++ // Do not return here. All data for this cred should be fully
++ // consumed so that we can read the next one.
++ }
++ if (DEBUG) {
+ System.out.println(">>>DEBUG <CCacheInputStream> client principal is " + cpname);
+- PrincipalName spname = readPrincipal(version);
+- if (DEBUG)
++ }
++ PrincipalName spname = null;
++ try {
++ spname = readPrincipal(version);
++ } catch (Exception e) {
++ // same as above
++ }
++ if (DEBUG) {
+ System.out.println(">>>DEBUG <CCacheInputStream> server principal is " + spname);
++ }
+ EncryptionKey key = readKey(version);
+- if (DEBUG)
++ if (DEBUG) {
+ System.out.println(">>>DEBUG <CCacheInputStream> key type: " + key.getEType());
++ }
+ long times[] = readTimes();
+ KerberosTime authtime = new KerberosTime(times[0]);
+ KerberosTime starttime =
+@@ -382,6 +389,11 @@
+ byte[] ticketData = readData();
+ byte[] ticketData2 = readData();
+
++ // Skip this cred if either cpname or spname isn't created.
++ if (cpname == null || spname == null) {
++ return null;
++ }
++
+ try {
+ return new Credentials(cpname, spname, key, authtime, starttime,
+ endtime, renewTill, skey, tFlags,
+--- ./jdk/src/share/classes/sun/security/krb5/internal/ccache/FileCCacheConstants.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/krb5/internal/ccache/FileCCacheConstants.java Wed Feb 04 12:14:43 2015 -0800
+@@ -49,7 +49,6 @@
+ public final int KRB5_FCC_FVNO_4 = 0x504;
+ public final int FCC_TAG_DELTATIME = 1;
+ public final int KRB5_NT_UNKNOWN = 0;
+- public final int MAXNAMELENGTH = 1024;
+ public final int TKT_FLG_FORWARDABLE = 0x40000000;
+ public final int TKT_FLG_FORWARDED = 0x20000000;
+ public final int TKT_FLG_PROXIABLE = 0x10000000;
+--- ./jdk/src/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java Wed Feb 04 12:14:43 2015 -0800
+@@ -360,7 +360,7 @@
+ String name;
+
+ // The env var can start with TYPE:, we only support FILE: here.
+- // http://docs.oracle.com/cd/E19082-01/819-2252/6n4i8rtr3/index.html
++ // https://docs.oracle.com/cd/E19082-01/819-2252/6n4i8rtr3/index.html
+ name = java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<String>() {
+ @Override
+@@ -402,8 +402,7 @@
+ String uidStr = null;
+ long uid = 0;
+
+- if (osname.startsWith("SunOS") ||
+- (osname.startsWith("Linux"))) {
++ if (!osname.startsWith("Windows")) {
+ try {
+ Class<?> c = Class.forName
+ ("com.sun.security.auth.module.UnixSystem");
+--- ./jdk/src/share/classes/sun/security/pkcs11/P11Signature.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/pkcs11/P11Signature.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -340,7 +340,10 @@
+ }
+ int minKeySize = (int) mechInfo.ulMinKeySize;
+ int maxKeySize = (int) mechInfo.ulMaxKeySize;
+-
++ // need to override the MAX keysize for SHA1withDSA
++ if (md != null && mechanism == CKM_DSA && maxKeySize > 1024) {
++ maxKeySize = 1024;
++ }
+ int keySize = 0;
+ if (key instanceof P11Key) {
+ keySize = ((P11Key) key).length();
+--- ./jdk/src/share/classes/sun/security/pkcs11/SessionManager.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/pkcs11/SessionManager.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -34,6 +34,9 @@
+ import sun.security.pkcs11.wrapper.*;
+ import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
++import java.util.concurrent.ConcurrentLinkedDeque;
++import java.util.concurrent.atomic.AtomicInteger;
++
+ /**
+ * Session manager. There is one session manager object per PKCS#11
+ * provider. It allows code to checkout a session, release it
+@@ -77,7 +80,7 @@
+ private final int maxSessions;
+
+ // total number of active sessions
+- private int activeSessions;
++ private AtomicInteger activeSessions = new AtomicInteger();
+
+ // pool of available object sessions
+ private final Pool objSessions;
+@@ -118,7 +121,7 @@
+ return (maxSessions <= DEFAULT_MAX_SESSIONS);
+ }
+
+- synchronized Session getObjSession() throws PKCS11Exception {
++ Session getObjSession() throws PKCS11Exception {
+ Session session = objSessions.poll();
+ if (session != null) {
+ return ensureValid(session);
+@@ -131,7 +134,7 @@
+ return ensureValid(session);
+ }
+
+- synchronized Session getOpSession() throws PKCS11Exception {
++ Session getOpSession() throws PKCS11Exception {
+ Session session = opSessions.poll();
+ if (session != null) {
+ return ensureValid(session);
+@@ -139,7 +142,7 @@
+ // create a new session rather than re-using an obj session
+ // that avoids potential expensive cancels() for Signatures & RSACipher
+ if (maxSessions == Integer.MAX_VALUE ||
+- activeSessions < maxSessions) {
++ activeSessions.get() < maxSessions) {
+ session = openSession();
+ return ensureValid(session);
+ }
+@@ -155,20 +158,20 @@
+ return session;
+ }
+
+- synchronized Session killSession(Session session) {
++ Session killSession(Session session) {
+ if ((session == null) || (token.isValid() == false)) {
+ return null;
+ }
+ if (debug != null) {
+ String location = new Exception().getStackTrace()[2].toString();
+ System.out.println("Killing session (" + location + ") active: "
+- + activeSessions);
++ + activeSessions.get());
+ }
+ closeSession(session);
+ return null;
+ }
+
+- synchronized Session releaseSession(Session session) {
++ Session releaseSession(Session session) {
+ if ((session == null) || (token.isValid() == false)) {
+ return null;
+ }
+@@ -181,13 +184,13 @@
+ return null;
+ }
+
+- synchronized void demoteObjSession(Session session) {
++ void demoteObjSession(Session session) {
+ if (token.isValid() == false) {
+ return;
+ }
+ if (debug != null) {
+ System.out.println("Demoting session, active: " +
+- activeSessions);
++ activeSessions.get());
+ }
+ boolean present = objSessions.remove(session);
+ if (present == false) {
+@@ -200,18 +203,21 @@
+
+ private Session openSession() throws PKCS11Exception {
+ if ((maxSessions != Integer.MAX_VALUE) &&
+- (activeSessions >= maxSessions)) {
++ (activeSessions.get() >= maxSessions)) {
+ throw new ProviderException("No more sessions available");
+ }
++
+ long id = token.p11.C_OpenSession
+ (token.provider.slotID, openSessionFlags, null, null);
+ Session session = new Session(token, id);
+- activeSessions++;
++ activeSessions.incrementAndGet();
+ if (debug != null) {
+- if (activeSessions > maxActiveSessions) {
+- maxActiveSessions = activeSessions;
+- if (maxActiveSessions % 10 == 0) {
+- System.out.println("Open sessions: " + maxActiveSessions);
++ synchronized(this) {
++ if (activeSessions.get() > maxActiveSessions) {
++ maxActiveSessions = activeSessions.get();
++ if (maxActiveSessions % 10 == 0) {
++ System.out.println("Open sessions: " + maxActiveSessions);
++ }
+ }
+ }
+ }
+@@ -220,18 +226,18 @@
+
+ private void closeSession(Session session) {
+ session.close();
+- activeSessions--;
++ activeSessions.decrementAndGet();
+ }
+
+- private static final class Pool {
++ public static final class Pool {
+
+ private final SessionManager mgr;
+
+- private final List<Session> pool;
++ private final ConcurrentLinkedDeque<Session> pool;
+
+ Pool(SessionManager mgr) {
+- this.mgr = mgr;
+- pool = new ArrayList<Session>();
++ this.mgr = mgr;
++ pool = new ConcurrentLinkedDeque<Session>();
+ }
+
+ boolean remove(Session session) {
+@@ -239,45 +245,40 @@
+ }
+
+ Session poll() {
+- int n = pool.size();
+- if (n == 0) {
+- return null;
+- }
+- Session session = pool.remove(n - 1);
+- return session;
++ return pool.pollLast();
+ }
+
+ void release(Session session) {
+- pool.add(session);
+- // if there are idle sessions, close them
++ pool.offer(session);
+ if (session.hasObjects()) {
+ return;
+ }
++
+ int n = pool.size();
+ if (n < 5) {
+ return;
+ }
+- Session oldestSession = pool.get(0);
++
++ Session oldestSession;
+ long time = System.currentTimeMillis();
+- if (session.isLive(time) && oldestSession.isLive(time)) {
+- return;
+- }
+- Collections.sort(pool);
+ int i = 0;
+- while (i < n - 1) { // always keep at least 1 session open
+- oldestSession = pool.get(i);
+- if (oldestSession.isLive(time)) {
++ // Check if the session head is too old and continue through queue
++ // until only one is left.
++ do {
++ oldestSession = pool.peek();
++ if (oldestSession == null || oldestSession.isLive(time) ||
++ !pool.remove(oldestSession)) {
+ break;
+ }
++
+ i++;
+ mgr.closeSession(oldestSession);
+- }
++ } while ((n - i) > 1);
++
+ if (debug != null) {
+ System.out.println("Closing " + i + " idle sessions, active: "
+ + mgr.activeSessions);
+ }
+- List<Session> subList = pool.subList(0, i);
+- subList.clear();
+ }
+
+ }
+--- ./jdk/src/share/classes/sun/security/provider/DSA.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/provider/DSA.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 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
+@@ -117,7 +117,6 @@
+ if (params == null) {
+ throw new InvalidKeyException("DSA private key lacks parameters");
+ }
+- checkKey(params);
+
+ this.params = params;
+ this.presetX = priv.getX();
+@@ -149,7 +148,6 @@
+ if (params == null) {
+ throw new InvalidKeyException("DSA public key lacks parameters");
+ }
+- checkKey(params);
+
+ this.params = params;
+ this.presetY = pub.getY();
+@@ -291,16 +289,6 @@
+ return null;
+ }
+
+- protected void checkKey(DSAParams params) throws InvalidKeyException {
+- // FIPS186-3 states in sec4.2 that a hash function which provides
+- // a lower security strength than the (L, N) pair ordinarily should
+- // not be used.
+- int valueN = params.getQ().bitLength();
+- if (valueN > md.getDigestLength()*8) {
+- throw new InvalidKeyException("Key is too strong for this signature algorithm");
+- }
+- }
+-
+ private BigInteger generateR(BigInteger p, BigInteger q, BigInteger g,
+ BigInteger k) {
+ BigInteger temp = g.modPow(k, p);
+@@ -480,14 +468,6 @@
+ }
+ }
+
+- @Override
+- protected void checkKey(DSAParams params) throws InvalidKeyException {
+- int valueL = params.getP().bitLength();
+- if (valueL > 1024) {
+- throw new InvalidKeyException("Key is too long for this algorithm");
+- }
+- }
+-
+ /*
+ * Please read bug report 4044247 for an alternative, faster,
+ * NON-FIPS approved method to generate K
+--- ./jdk/src/share/classes/sun/security/provider/DigestBase.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/provider/DigestBase.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -122,10 +122,10 @@
+ }
+ }
+ // compress complete blocks
+- while (len >= blockSize) {
+- implCompress(b, ofs);
+- len -= blockSize;
+- ofs += blockSize;
++ if (len >= blockSize) {
++ int limit = ofs + len;
++ ofs = implCompressMultiBlock(b, ofs, limit - blockSize);
++ len = limit - ofs;
+ }
+ // copy remainder to buffer
+ if (len > 0) {
+@@ -134,6 +134,14 @@
+ }
+ }
+
++ // compress complete blocks
++ private int implCompressMultiBlock(byte[] b, int ofs, int limit) {
++ for (; ofs <= limit; ofs += blockSize) {
++ implCompress(b, ofs);
++ }
++ return ofs;
++ }
++
+ // reset this object. See JCA doc.
+ protected final void engineReset() {
+ if (bytesProcessed == 0) {
+--- ./jdk/src/share/classes/sun/security/provider/X509Factory.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/provider/X509Factory.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -80,6 +80,7 @@
+ *
+ * @exception CertificateException on parsing errors.
+ */
++ @Override
+ public Certificate engineGenerateCertificate(InputStream is)
+ throws CertificateException
+ {
+@@ -103,8 +104,8 @@
+ throw new IOException("Empty input");
+ }
+ } catch (IOException ioe) {
+- throw (CertificateException)new CertificateException
+- ("Could not parse certificate: " + ioe.toString()).initCause(ioe);
++ throw new CertificateException("Could not parse certificate: " +
++ ioe.toString(), ioe);
+ }
+ }
+
+@@ -140,6 +141,12 @@
+ * It is useful for certificates that cannot be created via
+ * generateCertificate() and for converting other X509Certificate
+ * implementations to an X509CertImpl.
++ *
++ * @param c The source X509Certificate
++ * @return An X509CertImpl object that is either a cached certificate or a
++ * newly built X509CertImpl from the provided X509Certificate
++ * @throws CertificateException if failures occur while obtaining the DER
++ * encoding for certificate data.
+ */
+ public static synchronized X509CertImpl intern(X509Certificate c)
+ throws CertificateException {
+@@ -170,6 +177,12 @@
+ /**
+ * Return an interned X509CRLImpl for the given certificate.
+ * For more information, see intern(X509Certificate).
++ *
++ * @param c The source X509CRL
++ * @return An X509CRLImpl object that is either a cached CRL or a
++ * newly built X509CRLImpl from the provided X509CRL
++ * @throws CRLException if failures occur while obtaining the DER
++ * encoding for CRL data.
+ */
+ public static synchronized X509CRLImpl intern(X509CRL c)
+ throws CRLException {
+@@ -229,6 +242,7 @@
+ * @exception CertificateException if an exception occurs while decoding
+ * @since 1.4
+ */
++ @Override
+ public CertPath engineGenerateCertPath(InputStream inStream)
+ throws CertificateException
+ {
+@@ -260,6 +274,7 @@
+ * the encoding requested is not supported
+ * @since 1.4
+ */
++ @Override
+ public CertPath engineGenerateCertPath(InputStream inStream,
+ String encoding) throws CertificateException
+ {
+@@ -292,6 +307,7 @@
+ * @exception CertificateException if an exception occurs
+ * @since 1.4
+ */
++ @Override
+ public CertPath
+ engineGenerateCertPath(List<? extends Certificate> certificates)
+ throws CertificateException
+@@ -311,6 +327,7 @@
+ * <code>CertPath</code> encodings (as <code>String</code>s)
+ * @since 1.4
+ */
++ @Override
+ public Iterator<String> engineGetCertPathEncodings() {
+ return(X509CertPath.getEncodingsStatic());
+ }
+@@ -326,6 +343,7 @@
+ *
+ * @exception CertificateException on parsing errors.
+ */
++ @Override
+ public Collection<? extends java.security.cert.Certificate>
+ engineGenerateCertificates(InputStream is)
+ throws CertificateException {
+@@ -351,6 +369,7 @@
+ *
+ * @exception CRLException on parsing errors.
+ */
++ @Override
+ public CRL engineGenerateCRL(InputStream is)
+ throws CRLException
+ {
+@@ -388,6 +407,7 @@
+ *
+ * @exception CRLException on parsing errors.
+ */
++ @Override
+ public Collection<? extends java.security.cert.CRL> engineGenerateCRLs(
+ InputStream is) throws CRLException
+ {
+@@ -410,11 +430,30 @@
+ parseX509orPKCS7Cert(InputStream is)
+ throws CertificateException, IOException
+ {
++ int peekByte;
++ byte[] data;
++ PushbackInputStream pbis = new PushbackInputStream(is);
+ Collection<X509CertImpl> coll = new ArrayList<>();
+- byte[] data = readOneBlock(is);
++
++ // Test the InputStream for end-of-stream. If the stream's
++ // initial state is already at end-of-stream then return
++ // an empty collection. Otherwise, push the byte back into the
++ // stream and let readOneBlock look for the first certificate.
++ peekByte = pbis.read();
++ if (peekByte == -1) {
++ return new ArrayList<>(0);
++ } else {
++ pbis.unread(peekByte);
++ data = readOneBlock(pbis);
++ }
++
++ // If we end up with a null value after reading the first block
++ // then we know the end-of-stream has been reached and no certificate
++ // data has been found.
+ if (data == null) {
+- return new ArrayList<>(0);
++ throw new CertificateException("No certificate data found");
+ }
++
+ try {
+ PKCS7 pkcs7 = new PKCS7(data);
+ X509Certificate[] certs = pkcs7.getCertificates();
+@@ -422,13 +461,13 @@
+ if (certs != null) {
+ return Arrays.asList(certs);
+ } else {
+- // no crls provided
++ // no certificates provided
+ return new ArrayList<>(0);
+ }
+ } catch (ParsingException e) {
+ while (data != null) {
+ coll.add(new X509CertImpl(data));
+- data = readOneBlock(is);
++ data = readOneBlock(pbis);
+ }
+ }
+ return coll;
+@@ -443,11 +482,30 @@
+ parseX509orPKCS7CRL(InputStream is)
+ throws CRLException, IOException
+ {
++ int peekByte;
++ byte[] data;
++ PushbackInputStream pbis = new PushbackInputStream(is);
+ Collection<X509CRLImpl> coll = new ArrayList<>();
+- byte[] data = readOneBlock(is);
++
++ // Test the InputStream for end-of-stream. If the stream's
++ // initial state is already at end-of-stream then return
++ // an empty collection. Otherwise, push the byte back into the
++ // stream and let readOneBlock look for the first CRL.
++ peekByte = pbis.read();
++ if (peekByte == -1) {
++ return new ArrayList<>(0);
++ } else {
++ pbis.unread(peekByte);
++ data = readOneBlock(pbis);
++ }
++
++ // If we end up with a null value after reading the first block
++ // then we know the end-of-stream has been reached and no CRL
++ // data has been found.
+ if (data == null) {
+- return new ArrayList<>(0);
++ throw new CRLException("No CRL data found");
+ }
++
+ try {
+ PKCS7 pkcs7 = new PKCS7(data);
+ X509CRL[] crls = pkcs7.getCRLs();
+@@ -461,7 +519,7 @@
+ } catch (ParsingException e) {
+ while (data != null) {
+ coll.add(new X509CRLImpl(data));
+- data = readOneBlock(is);
++ data = readOneBlock(pbis);
+ }
+ }
+ return coll;
+@@ -519,7 +577,7 @@
+
+ // Step 2: Read the rest of header, determine the line end
+ int end;
+- StringBuffer header = new StringBuffer("-----");
++ StringBuilder header = new StringBuilder("-----");
+ while (true) {
+ int next = is.read();
+ if (next == -1) {
+@@ -562,7 +620,7 @@
+ }
+
+ // Step 4: Consume the footer
+- StringBuffer footer = new StringBuffer("-");
++ StringBuilder footer = new StringBuilder("-");
+ while (true) {
+ int next = is.read();
+ // Add next == '\n' for maximum safety, in case endline
+@@ -623,7 +681,7 @@
+
+ int n = is.read();
+ if (n == -1) {
+- throw new IOException("BER/DER length info ansent");
++ throw new IOException("BER/DER length info absent");
+ }
+ bout.write(n);
+
+--- ./jdk/src/share/classes/sun/security/smartcardio/CardImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/smartcardio/CardImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -26,9 +26,9 @@
+ package sun.security.smartcardio;
+
+ import java.nio.ByteBuffer;
+-
++import java.security.AccessController;
++import java.security.PrivilegedAction;
+ import javax.smartcardio.*;
+-
+ import static sun.security.smartcardio.PCSC.*;
+
+ /**
+@@ -62,6 +62,15 @@
+ // thread holding exclusive access to the card, or null
+ private volatile Thread exclusiveThread;
+
++ // used for platform specific logic
++ private static final boolean isWindows;
++
++ static {
++ final String osName = AccessController.doPrivileged(
++ (PrivilegedAction<String>) () -> System.getProperty("os.name"));
++ isWindows = osName.startsWith("Windows");
++ }
++
+ CardImpl(TerminalImpl terminal, String protocol) throws PCSCException {
+ this.terminal = terminal;
+ int sharingMode = SCARD_SHARE_SHARED;
+@@ -74,7 +83,12 @@
+ connectProtocol = SCARD_PROTOCOL_T1;
+ } else if (protocol.equalsIgnoreCase("direct")) {
+ // testing
+- connectProtocol = 0;
++
++ // MSDN states that the preferred protocol can be zero, but doesn't
++ // specify whether other values are allowed.
++ // pcsc-lite implementation expects the preferred protocol to be non zero.
++ connectProtocol = isWindows ? 0 : SCARD_PROTOCOL_RAW;
++
+ sharingMode = SCARD_SHARE_DIRECT;
+ } else {
+ throw new IllegalArgumentException("Unsupported protocol " + protocol);
+--- ./jdk/src/share/classes/sun/security/ssl/DHCrypt.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/ssl/DHCrypt.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -188,7 +188,7 @@
+ * the same size as the Diffie-Hellman modulus.
+ */
+ SecretKey getAgreedSecret(BigInteger peerPublicValue,
+- boolean keyIsValidated) throws IOException {
++ boolean keyIsValidated) throws SSLHandshakeException {
+ try {
+ KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
+ DHPublicKeySpec spec =
+@@ -211,7 +211,8 @@
+ ka.doPhase(publicKey, true);
+ return ka.generateSecret("TlsPremasterSecret");
+ } catch (GeneralSecurityException e) {
+- throw new RuntimeException("Could not generate secret", e);
++ throw (SSLHandshakeException) new SSLHandshakeException(
++ "Could not generate secret").initCause(e);
+ }
+ }
+
+--- ./jdk/src/share/classes/sun/security/ssl/ECDHCrypt.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/ssl/ECDHCrypt.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -31,6 +31,7 @@
+
+ import javax.crypto.SecretKey;
+ import javax.crypto.KeyAgreement;
++import javax.net.ssl.SSLHandshakeException;
+
+ /**
+ * Helper class for the ECDH key exchange. It generates the appropriate
+@@ -88,19 +89,20 @@
+ }
+
+ // called by ClientHandshaker with either the server's static or ephemeral public key
+- SecretKey getAgreedSecret(PublicKey peerPublicKey) {
++ SecretKey getAgreedSecret(PublicKey peerPublicKey) throws SSLHandshakeException {
+ try {
+ KeyAgreement ka = JsseJce.getKeyAgreement("ECDH");
+ ka.init(privateKey);
+ ka.doPhase(peerPublicKey, true);
+ return ka.generateSecret("TlsPremasterSecret");
+ } catch (GeneralSecurityException e) {
+- throw new RuntimeException("Could not generate secret", e);
++ throw (SSLHandshakeException) new SSLHandshakeException(
++ "Could not generate secret").initCause(e);
+ }
+ }
+
+ // called by ServerHandshaker
+- SecretKey getAgreedSecret(byte[] encodedPoint) {
++ SecretKey getAgreedSecret(byte[] encodedPoint) throws SSLHandshakeException {
+ try {
+ ECParameterSpec params = publicKey.getParams();
+ ECPoint point = JsseJce.decodePoint(encodedPoint, params.getCurve());
+@@ -108,10 +110,9 @@
+ ECPublicKeySpec spec = new ECPublicKeySpec(point, params);
+ PublicKey peerPublicKey = kf.generatePublic(spec);
+ return getAgreedSecret(peerPublicKey);
+- } catch (GeneralSecurityException e) {
+- throw new RuntimeException("Could not generate secret", e);
+- } catch (java.io.IOException e) {
+- throw new RuntimeException("Could not generate secret", e);
++ } catch (GeneralSecurityException | java.io.IOException e) {
++ throw (SSLHandshakeException) new SSLHandshakeException(
++ "Could not generate secret").initCause(e);
+ }
+ }
+
+--- ./jdk/src/share/classes/sun/security/ssl/Handshaker.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/ssl/Handshaker.java Wed Feb 04 12:14:43 2015 -0800
+@@ -678,6 +678,7 @@
+ */
+ ProtocolList getActiveProtocols() {
+ if (activeProtocols == null) {
++ boolean enabledSSL20Hello = false;
+ ArrayList<ProtocolVersion> protocols = new ArrayList<>(4);
+ for (ProtocolVersion protocol : enabledProtocols.collection()) {
+ if (!algorithmConstraints.permits(
+@@ -690,6 +691,12 @@
+
+ continue;
+ }
++ // Need not to check the SSL20Hello protocol.
++ if (protocol.v == ProtocolVersion.SSL20Hello.v) {
++ enabledSSL20Hello = true;
++ continue;
++ }
++
+ boolean found = false;
+ for (CipherSuite suite : enabledCipherSuites.collection()) {
+ if (suite.isAvailable() && suite.obsoleted > protocol.v &&
+@@ -716,6 +723,11 @@
+ "No available cipher suite for " + protocol);
+ }
+ }
++
++ if (!protocols.isEmpty() && enabledSSL20Hello) {
++ protocols.add(ProtocolVersion.SSL20Hello);
++ }
++
+ activeProtocols = new ProtocolList(protocols);
+ }
+
+--- ./jdk/src/share/classes/sun/security/tools/keytool/Resources.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/tools/keytool/Resources.java Wed Feb 04 12:14:43 2015 -0800
+@@ -336,7 +336,7 @@
+ {"New.prompt.", "New {0}: "},
+ {"Passwords.must.differ", "Passwords must differ"},
+ {"Re.enter.new.prompt.", "Re-enter new {0}: "},
+- {"Re.enter.passpword.", "Re-enter password: "},
++ {"Re.enter.password.", "Re-enter password: "},
+ {"Re.enter.new.password.", "Re-enter new password: "},
+ {"They.don.t.match.Try.again", "They don't match. Try again"},
+ {"Enter.prompt.alias.name.", "Enter {0} alias name: "},
+--- ./jdk/src/share/classes/sun/security/tools/keytool/Resources_de.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/tools/keytool/Resources_de.java Wed Feb 04 12:14:43 2015 -0800
+@@ -336,7 +336,7 @@
+ {"New.prompt.", "Neues {0}: "},
+ {"Passwords.must.differ", "Kennw\u00F6rter m\u00FCssen sich unterscheiden"},
+ {"Re.enter.new.prompt.", "Neues {0} erneut eingeben: "},
+- {"Re.enter.passpword.", "Geben Sie das Kennwort erneut ein: "},
++ {"Re.enter.password.", "Geben Sie das Kennwort erneut ein: "},
+ {"Re.enter.new.password.", "Neues Kennwort erneut eingeben: "},
+ {"They.don.t.match.Try.again", "Keine \u00DCbereinstimmung. Wiederholen Sie den Vorgang"},
+ {"Enter.prompt.alias.name.", "{0}-Aliasnamen eingeben: "},
+--- ./jdk/src/share/classes/sun/security/tools/keytool/Resources_es.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/tools/keytool/Resources_es.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -336,7 +336,7 @@
+ {"New.prompt.", "Nuevo {0}: "},
+ {"Passwords.must.differ", "Las contrase\u00F1as deben ser distintas"},
+ {"Re.enter.new.prompt.", "Vuelva a escribir el nuevo {0}: "},
+- {"Re.enter.passpword.", "Vuelva a introducir la contrase\u00F1a: "},
++ {"Re.enter.password.", "Vuelva a introducir la contrase\u00F1a: "},
+ {"Re.enter.new.password.", "Volver a escribir la contrase\u00F1a nueva: "},
+ {"They.don.t.match.Try.again", "No coinciden. Int\u00E9ntelo de nuevo"},
+ {"Enter.prompt.alias.name.", "Escriba el nombre de alias de {0}: "},
+--- ./jdk/src/share/classes/sun/security/tools/keytool/Resources_fr.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/tools/keytool/Resources_fr.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -336,7 +336,7 @@
+ {"New.prompt.", "Nouveau {0} : "},
+ {"Passwords.must.differ", "Les mots de passe doivent diff\u00E9rer"},
+ {"Re.enter.new.prompt.", "Indiquez encore le nouveau {0} : "},
+- {"Re.enter.passpword.", "R\u00E9p\u00E9tez le mot de passe : "},
++ {"Re.enter.password.", "R\u00E9p\u00E9tez le mot de passe : "},
+ {"Re.enter.new.password.", "Ressaisissez le nouveau mot de passe : "},
+ {"They.don.t.match.Try.again", "Ils sont diff\u00E9rents. R\u00E9essayez."},
+ {"Enter.prompt.alias.name.", "Indiquez le nom d''alias {0} : "},
+--- ./jdk/src/share/classes/sun/security/tools/keytool/Resources_it.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/tools/keytool/Resources_it.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -336,7 +336,7 @@
+ {"New.prompt.", "Nuova {0}: "},
+ {"Passwords.must.differ", "Le password non devono coincidere"},
+ {"Re.enter.new.prompt.", "Reimmettere un nuovo valore per {0}: "},
+- {"Re.enter.passpword.", "Reimmettere la password: "},
++ {"Re.enter.password.", "Reimmettere la password: "},
+ {"Re.enter.new.password.", "Immettere nuovamente la nuova password: "},
+ {"They.don.t.match.Try.again", "Non corrispondono. Riprovare."},
+ {"Enter.prompt.alias.name.", "Immettere nome alias {0}: "},
+--- ./jdk/src/share/classes/sun/security/tools/keytool/Resources_ja.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/tools/keytool/Resources_ja.java Wed Feb 04 12:14:43 2015 -0800
+@@ -336,7 +336,7 @@
+ {"New.prompt.", "\u65B0\u898F{0}: "},
+ {"Passwords.must.differ", "\u30D1\u30B9\u30EF\u30FC\u30C9\u306F\u7570\u306A\u3063\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059"},
+ {"Re.enter.new.prompt.", "\u65B0\u898F{0}\u3092\u518D\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044: "},
+- {"Re.enter.passpword.", "\u30D1\u30B9\u30EF\u30FC\u30C9\u3092\u518D\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044: "},
++ {"Re.enter.password.", "\u30D1\u30B9\u30EF\u30FC\u30C9\u3092\u518D\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044: "},
+ {"Re.enter.new.password.", "\u65B0\u898F\u30D1\u30B9\u30EF\u30FC\u30C9\u3092\u518D\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044: "},
+ {"They.don.t.match.Try.again", "\u4E00\u81F4\u3057\u307E\u305B\u3093\u3002\u3082\u3046\u4E00\u5EA6\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044"},
+ {"Enter.prompt.alias.name.", "{0}\u306E\u5225\u540D\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044: "},
+--- ./jdk/src/share/classes/sun/security/tools/keytool/Resources_ko.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/tools/keytool/Resources_ko.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -336,7 +336,7 @@
+ {"New.prompt.", "\uC0C8 {0}: "},
+ {"Passwords.must.differ", "\uBE44\uBC00\uBC88\uD638\uB294 \uB2EC\uB77C\uC57C \uD569\uB2C8\uB2E4."},
+ {"Re.enter.new.prompt.", "\uC0C8 {0} \uB2E4\uC2DC \uC785\uB825: "},
+- {"Re.enter.passpword.", "\uBE44\uBC00\uBC88\uD638 \uB2E4\uC2DC \uC785\uB825: "},
++ {"Re.enter.password.", "\uBE44\uBC00\uBC88\uD638 \uB2E4\uC2DC \uC785\uB825: "},
+ {"Re.enter.new.password.", "\uC0C8 \uBE44\uBC00\uBC88\uD638 \uB2E4\uC2DC \uC785\uB825: "},
+ {"They.don.t.match.Try.again", "\uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC2ED\uC2DC\uC624."},
+ {"Enter.prompt.alias.name.", "{0} \uBCC4\uCE6D \uC774\uB984 \uC785\uB825: "},
+--- ./jdk/src/share/classes/sun/security/tools/keytool/Resources_pt_BR.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/tools/keytool/Resources_pt_BR.java Wed Feb 04 12:14:43 2015 -0800
+@@ -336,7 +336,7 @@
+ {"New.prompt.", "Nova {0}: "},
+ {"Passwords.must.differ", "As senhas devem ser diferentes"},
+ {"Re.enter.new.prompt.", "Informe novamente a nova {0}: "},
+- {"Re.enter.passpword.", "Redigite a senha: "},
++ {"Re.enter.password.", "Redigite a senha: "},
+ {"Re.enter.new.password.", "Informe novamente a nova senha: "},
+ {"They.don.t.match.Try.again", "Elas n\u00E3o correspondem. Tente novamente"},
+ {"Enter.prompt.alias.name.", "Informe o nome do alias {0}: "},
+--- ./jdk/src/share/classes/sun/security/tools/keytool/Resources_sv.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/tools/keytool/Resources_sv.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -336,7 +336,7 @@
+ {"New.prompt.", "Nytt {0}: "},
+ {"Passwords.must.differ", "L\u00F6senorden m\u00E5ste vara olika"},
+ {"Re.enter.new.prompt.", "Ange nytt {0} igen: "},
+- {"Re.enter.passpword.", "Ange l\u00F6senord igen: "},
++ {"Re.enter.password.", "Ange l\u00F6senord igen: "},
+ {"Re.enter.new.password.", "Ange det nya l\u00F6senordet igen: "},
+ {"They.don.t.match.Try.again", "De matchar inte. F\u00F6rs\u00F6k igen"},
+ {"Enter.prompt.alias.name.", "Ange aliasnamn f\u00F6r {0}: "},
+--- ./jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_CN.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_CN.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -336,7 +336,7 @@
+ {"New.prompt.", "\u65B0{0}: "},
+ {"Passwords.must.differ", "\u53E3\u4EE4\u4E0D\u80FD\u76F8\u540C"},
+ {"Re.enter.new.prompt.", "\u91CD\u65B0\u8F93\u5165\u65B0{0}: "},
+- {"Re.enter.passpword.", "\u518D\u6B21\u8F93\u5165\u53E3\u4EE4: "},
++ {"Re.enter.password.", "\u518D\u6B21\u8F93\u5165\u53E3\u4EE4: "},
+ {"Re.enter.new.password.", "\u518D\u6B21\u8F93\u5165\u65B0\u53E3\u4EE4: "},
+ {"They.don.t.match.Try.again", "\u5B83\u4EEC\u4E0D\u5339\u914D\u3002\u8BF7\u91CD\u8BD5"},
+ {"Enter.prompt.alias.name.", "\u8F93\u5165{0}\u522B\u540D: "},
+--- ./jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -336,7 +336,7 @@
+ {"New.prompt.", "\u65B0 {0}: "},
+ {"Passwords.must.differ", "\u5FC5\u9808\u662F\u4E0D\u540C\u7684\u5BC6\u78BC"},
+ {"Re.enter.new.prompt.", "\u91CD\u65B0\u8F38\u5165\u65B0 {0}: "},
+- {"Re.enter.passpword.", "\u91CD\u65B0\u8F38\u5165\u5BC6\u78BC:"},
++ {"Re.enter.password.", "\u91CD\u65B0\u8F38\u5165\u5BC6\u78BC:"},
+ {"Re.enter.new.password.", "\u91CD\u65B0\u8F38\u5165\u65B0\u5BC6\u78BC: "},
+ {"They.don.t.match.Try.again", "\u5B83\u5011\u4E0D\u76F8\u7B26\u3002\u8ACB\u91CD\u8A66"},
+ {"Enter.prompt.alias.name.", "\u8F38\u5165 {0} \u5225\u540D\u540D\u7A31: "},
+--- ./jdk/src/share/classes/sun/security/util/Debug.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/util/Debug.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -104,7 +104,15 @@
+ System.err.println("codebase=<URL>");
+ System.err.println(" only dump output if specified codebase");
+ System.err.println(" is being checked");
+-
++ System.err.println();
++ System.err.println("The following can be used with provider:");
++ System.err.println();
++ System.err.println("engine=<engines>");
++ System.err.println(" only dump output for the specified list");
++ System.err.println(" of JCA engines. Supported values:");
++ System.err.println(" Cipher, KeyAgreement, KeyGenerator,");
++ System.err.println(" KeyPairGenerator, KeyStore, Mac,");
++ System.err.println(" MessageDigest, SecureRandom, Signature.");
+ System.err.println();
+ System.err.println("Note: Separate multiple options with a comma");
+ System.exit(0);
+--- ./jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Wed Feb 04 12:14:43 2015 -0800
+@@ -175,7 +175,7 @@
+ return true;
+ } else if (name.startsWith("SIG-")) {
+ // check filename extension
+- // see http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#Digital_Signatures
++ // see https://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#Digital_Signatures
+ // for what filename extensions are legal
+ int extIndex = name.lastIndexOf('.');
+ if (extIndex != -1) {
+--- ./jdk/src/share/classes/sun/swing/JLightweightFrame.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/swing/JLightweightFrame.java Wed Feb 04 12:14:43 2015 -0800
+@@ -37,6 +37,13 @@
+ import java.awt.Point;
+ import java.awt.Rectangle;
+ import java.awt.Window;
++import java.awt.dnd.DragGestureEvent;
++import java.awt.dnd.DragGestureListener;
++import java.awt.dnd.DragGestureRecognizer;
++import java.awt.dnd.DragSource;
++import java.awt.dnd.DropTarget;
++import java.awt.dnd.InvalidDnDOperationException;
++import java.awt.dnd.peer.DragSourceContextPeer;
+ import java.awt.event.ContainerEvent;
+ import java.awt.event.ContainerListener;
+ import java.awt.image.BufferedImage;
+@@ -470,4 +477,27 @@
+ content.setCursor(target.getCursor());
+ }
+ }
++
++ public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
++ Class<T> abstractRecognizerClass,
++ DragSource ds, Component c, int srcActions,
++ DragGestureListener dgl)
++ {
++ return content == null ? null : content.createDragGestureRecognizer(
++ abstractRecognizerClass, ds, c, srcActions, dgl);
++ }
++
++ public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException {
++ return content == null ? null : content.createDragSourceContextPeer(dge);
++ }
++
++ public void addDropTarget(DropTarget dt) {
++ if (content == null) return;
++ content.addDropTarget(dt);
++ }
++
++ public void removeDropTarget(DropTarget dt) {
++ if (content == null) return;
++ content.removeDropTarget(dt);
++ }
+ }
+--- ./jdk/src/share/classes/sun/swing/LightweightContent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/swing/LightweightContent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -26,7 +26,15 @@
+ package sun.swing;
+
+ import javax.swing.JComponent;
++import java.awt.Component;
+ import java.awt.Cursor;
++import java.awt.dnd.DragGestureEvent;
++import java.awt.dnd.DragGestureListener;
++import java.awt.dnd.DragGestureRecognizer;
++import java.awt.dnd.DragSource;
++import java.awt.dnd.DropTarget;
++import java.awt.dnd.InvalidDnDOperationException;
++import java.awt.dnd.peer.DragSourceContextPeer;
+
+ /**
+ * The interface by means of which the {@link JLightweightFrame} class
+@@ -209,4 +217,33 @@
+ * @param cursor a cursor to set
+ */
+ default public void setCursor(Cursor cursor) { }
++
++ /**
++ * Create a drag gesture recognizer for the lightweight frame.
++ */
++ default public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
++ Class<T> abstractRecognizerClass,
++ DragSource ds, Component c, int srcActions,
++ DragGestureListener dgl)
++ {
++ return null;
++ }
++
++ /**
++ * Create a drag source context peer for the lightweight frame.
++ */
++ default public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException
++ {
++ return null;
++ }
++
++ /**
++ * Adds a drop target to the lightweight frame.
++ */
++ default public void addDropTarget(DropTarget dt) {}
++
++ /**
++ * Removes a drop target from the lightweight frame.
++ */
++ default public void removeDropTarget(DropTarget dt) {}
+ }
+--- ./jdk/src/share/classes/sun/swing/PrintingStatus.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/swing/PrintingStatus.java Wed Feb 04 12:14:43 2015 -0800
+@@ -43,7 +43,7 @@
+ * <p/>
+ * Methods of these class are thread safe, although most Swing methods
+ * are not. Please see
+- * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
++ * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
+ * in Swing</A> for more information.
+ *
+ * @author Alexander Potochkin
+--- ./jdk/src/share/classes/sun/text/normalizer/UCharacter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/text/normalizer/UCharacter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -42,7 +42,7 @@
+ /**
+ * <p>
+ * The UCharacter class provides extensions to the
+- * <a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Character.html">
++ * <a href="https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Character.html">
+ * java.lang.Character</a> class. These extensions provide support for
+ * more Unicode properties and together with the <a href=../text/UTF16.html>UTF16</a>
+ * class, provide support for supplementary characters (those with code
+--- ./jdk/src/share/classes/sun/text/resources/FormatData.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/text/resources/FormatData.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -154,18 +154,18 @@
+ },
+ { "MonthNarrows",
+ new String[] {
+- "J",
+- "F",
+- "M",
+- "A",
+- "M",
+- "J",
+- "J",
+- "A",
+- "S",
+- "O",
+- "N",
+- "D",
++ "1",
++ "2",
++ "3",
++ "4",
++ "5",
++ "6",
++ "7",
++ "8",
++ "9",
++ "10",
++ "11",
++ "12",
+ "",
+ }
+ },
+--- ./jdk/src/share/classes/sun/text/resources/en/FormatData_en.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/text/resources/en/FormatData_en.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -53,6 +53,23 @@
+ // define this method as follows:
+ // return new Object[][] { };
+ return new Object[][] {
++ { "MonthNarrows",
++ new String[] {
++ "J",
++ "F",
++ "M",
++ "A",
++ "M",
++ "J",
++ "J",
++ "A",
++ "S",
++ "O",
++ "N",
++ "D",
++ "",
++ }
++ },
+ { "NumberPatterns",
+ new String[] {
+ "#,##0.###;-#,##0.###", // decimal pattern
+--- ./jdk/src/share/classes/sun/tools/attach/HotSpotVirtualMachine.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/tools/attach/HotSpotVirtualMachine.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -33,7 +33,7 @@
+ import java.io.InputStream;
+ import java.io.IOException;
+ import java.util.Properties;
+-import java.util.Map;
++import java.util.stream.Collectors;
+
+ /*
+ * The HotSpot implementation of com.sun.tools.attach.VirtualMachine.
+@@ -161,6 +161,50 @@
+ return props;
+ }
+
++ private static final String MANAGMENT_PREFIX = "com.sun.management.";
++
++ private static boolean checkedKeyName(Object key) {
++ if (!(key instanceof String)) {
++ throw new IllegalArgumentException("Invalid option (not a String): "+key);
++ }
++ if (!((String)key).startsWith(MANAGMENT_PREFIX)) {
++ throw new IllegalArgumentException("Invalid option: "+key);
++ }
++ return true;
++ }
++
++ private static String stripKeyName(Object key) {
++ return ((String)key).substring(MANAGMENT_PREFIX.length());
++ }
++
++ @Override
++ public void startManagementAgent(Properties agentProperties) throws IOException {
++ if (agentProperties == null) {
++ throw new NullPointerException("agentProperties cannot be null");
++ }
++ // Convert the arguments into arguments suitable for the Diagnostic Command:
++ // "ManagementAgent.start jmxremote.port=5555 jmxremote.authenticate=false"
++ String args = agentProperties.entrySet().stream()
++ .filter(entry -> checkedKeyName(entry.getKey()))
++ .map(entry -> stripKeyName(entry.getKey()) + "=" + escape(entry.getValue()))
++ .collect(Collectors.joining(" "));
++ executeJCmd("ManagementAgent.start " + args);
++ }
++
++ private String escape(Object arg) {
++ String value = arg.toString();
++ if (value.contains(" ")) {
++ return "'" + value + "'";
++ }
++ return value;
++ }
++
++ @Override
++ public String startLocalManagementAgent() throws IOException {
++ executeJCmd("ManagementAgent.start_local");
++ return getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress");
++ }
++
+ // --- HotSpot specific methods ---
+
+ // same as SIGQUIT
+@@ -257,6 +301,20 @@
+ return value;
+ }
+
++ /*
++ * Utility method to read data into a String.
++ */
++ String readErrorMessage(InputStream sis) throws IOException {
++ byte b[] = new byte[1024];
++ int n;
++ StringBuffer message = new StringBuffer();
++ while ((n = sis.read(b)) != -1) {
++ message.append(new String(b, 0, n, "UTF-8"));
++ }
++ return message.toString();
++ }
++
++
+ // -- attach timeout support
+
+ private static long defaultAttachTimeout = 5000;
+--- ./jdk/src/share/classes/sun/tools/jcmd/JCmd.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/tools/jcmd/JCmd.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -33,10 +33,12 @@
+ import java.util.Comparator;
+ import java.net.URISyntaxException;
+
++import com.sun.tools.attach.AttachOperationFailedException;
+ import com.sun.tools.attach.VirtualMachine;
+ import com.sun.tools.attach.VirtualMachineDescriptor;
+ import com.sun.tools.attach.AgentLoadException;
+ import com.sun.tools.attach.AttachNotSupportedException;
++
+ import sun.tools.attach.HotSpotVirtualMachine;
+ import sun.tools.jstat.JStatLogger;
+ import sun.jvmstat.monitor.Monitor;
+@@ -119,6 +121,7 @@
+ pids.add(arg.getPid() + "");
+ }
+
++ boolean success = true;
+ for (String pid : pids) {
+ System.out.println(pid + ":");
+ if (arg.isListCounters()) {
+@@ -126,11 +129,16 @@
+ } else {
+ try {
+ executeCommandForPid(pid, arg.getCommand());
++ } catch(AttachOperationFailedException ex) {
++ System.err.println(ex.getMessage());
++ success = false;
+ } catch(Exception ex) {
+ ex.printStackTrace();
++ success = false;
+ }
+ }
+ }
++ System.exit(success ? 0 : 1);
+ }
+
+ private static void executeCommandForPid(String pid, String command)
+@@ -150,13 +158,18 @@
+ // read to EOF and just print output
+ byte b[] = new byte[256];
+ int n;
++ boolean messagePrinted = false;
+ do {
+ n = in.read(b);
+ if (n > 0) {
+ String s = new String(b, 0, n, "UTF-8");
+ System.out.print(s);
++ messagePrinted = true;
+ }
+ } while (n > 0);
++ if (!messagePrinted) {
++ System.out.println("Command executed successfully");
++ }
+ }
+ }
+ vm.detach();
+--- ./jdk/src/share/classes/sun/tools/jconsole/LocalVirtualMachine.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/tools/jconsole/LocalVirtualMachine.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -32,8 +32,6 @@
+ // Sun specific
+ import com.sun.tools.attach.VirtualMachine;
+ import com.sun.tools.attach.VirtualMachineDescriptor;
+-import com.sun.tools.attach.AgentInitializationException;
+-import com.sun.tools.attach.AgentLoadException;
+ import com.sun.tools.attach.AttachNotSupportedException;
+
+ // Sun private
+@@ -238,35 +236,7 @@
+ throw ioe;
+ }
+
+- String home = vm.getSystemProperties().getProperty("java.home");
+-
+- // Normally in ${java.home}/jre/lib/management-agent.jar but might
+- // be in ${java.home}/lib in build environments.
+-
+- String agent = home + File.separator + "jre" + File.separator +
+- "lib" + File.separator + "management-agent.jar";
+- File f = new File(agent);
+- if (!f.exists()) {
+- agent = home + File.separator + "lib" + File.separator +
+- "management-agent.jar";
+- f = new File(agent);
+- if (!f.exists()) {
+- throw new IOException("Management agent not found");
+- }
+- }
+-
+- agent = f.getCanonicalPath();
+- try {
+- vm.loadAgent(agent, "com.sun.management.jmxremote");
+- } catch (AgentLoadException x) {
+- IOException ioe = new IOException(x.getMessage());
+- ioe.initCause(x);
+- throw ioe;
+- } catch (AgentInitializationException x) {
+- IOException ioe = new IOException(x.getMessage());
+- ioe.initCause(x);
+- throw ioe;
+- }
++ vm.startLocalManagementAgent();
+
+ // get the connector address
+ Properties agentProps = vm.getAgentProperties();
+--- ./jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties Wed Feb 04 12:14:43 2015 -0800
+@@ -104,7 +104,7 @@
+ HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=Masthead Graphic
+ HELP_ABOUT_DIALOG_MASTHEAD_TITLE=About JConsole
+ HELP_ABOUT_DIALOG_TITLE=JConsole: About
+-HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
++HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=https://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
+ HELP_MENU_ABOUT_TITLE=&About JConsole
+ HELP_MENU_USER_GUIDE_TITLE=Online &User Guide
+ HELP_MENU_TITLE=&Help
+--- ./jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties Wed Feb 04 12:14:43 2015 -0800
+@@ -104,7 +104,7 @@
+ HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=\u30DE\u30B9\u30C8\u30D8\u30C3\u30C9\u56F3\u5F62
+ HELP_ABOUT_DIALOG_MASTHEAD_TITLE=JConsole\u306B\u3064\u3044\u3066
+ HELP_ABOUT_DIALOG_TITLE=JConsole: \u60C5\u5831
+-HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
++HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=https://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
+ HELP_MENU_ABOUT_TITLE=JConsole\u306B\u3064\u3044\u3066(&A)
+ HELP_MENU_USER_GUIDE_TITLE=\u30AA\u30F3\u30E9\u30A4\u30F3\u30FB\u30E6\u30FC\u30B6\u30FC\u30FB\u30AC\u30A4\u30C9(&U)
+ HELP_MENU_TITLE=\u30D8\u30EB\u30D7(&H)
+--- ./jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties Wed Feb 04 12:14:43 2015 -0800
+@@ -104,7 +104,7 @@
+ HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=\u62A5\u5934\u56FE
+ HELP_ABOUT_DIALOG_MASTHEAD_TITLE=\u5173\u4E8E JConsole
+ HELP_ABOUT_DIALOG_TITLE=JConsole: \u5173\u4E8E
+-HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
++HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=https://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
+ HELP_MENU_ABOUT_TITLE=\u5173\u4E8E JConsole(&A)
+ HELP_MENU_USER_GUIDE_TITLE=\u8054\u673A\u7528\u6237\u6307\u5357(&U)
+ HELP_MENU_TITLE=\u5E2E\u52A9(&H)
+--- ./jdk/src/share/demo/README Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/demo/README Wed Feb 04 12:14:43 2015 -0800
+@@ -4,3 +4,12 @@
+ production-quality application, such as security checks, input
+ validation, and proper error handling, might not be present in the
+ sample code.
++
++In some cases, the default security settings may block an execution
++of demo applets in a browser. To adjust the security settings, please
++refer to the following resource:
++
++http://java.com/en/download/help/java_blocked.xml
++
++Some demo applets need to be accessed through the HTTP or HTTPS
++protocols to enable access to the required resources.
+--- ./jdk/src/share/demo/jfc/FileChooserDemo/FileChooserDemo.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/demo/jfc/FileChooserDemo/FileChooserDemo.java Wed Feb 04 12:14:43 2015 -0800
+@@ -800,7 +800,7 @@
+ * NOTE: By default, the look and feel will be set to the
+ * Cross Platform Look and Feel (which is currently Metal).
+ * The following code tries to set the Look and Feel to Nimbus.
+- * http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/nimbus.html
++ * https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/nimbus.html
+ */
+ try {
+ for (LookAndFeelInfo info : UIManager.
+--- ./jdk/src/share/demo/jfc/Font2DTest/resources/TextResources.properties Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,1 +0,0 @@
+-string=This is Java 2D! (Default)
+--- ./jdk/src/share/demo/jfc/Font2DTest/resources/TextResources_de.properties Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,1 +0,0 @@
+-string=This is Java 2D! (German) \u00f6 \u00df \u00dc
+--- ./jdk/src/share/demo/jfc/Font2DTest/resources/TextResources_en.properties Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,1 +0,0 @@
+-string=This is Java 2D! (English) A B C
+--- ./jdk/src/share/demo/jfc/Font2DTest/resources/TextResources_en_GB.properties Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,1 +0,0 @@
+-string=This is Java 2D! (English in Great Britain) \u0075 \u006b Z
+--- ./jdk/src/share/demo/jfc/Font2DTest/resources/TextResources_ja.properties Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,1 +0,0 @@
+-string=Java 2D\u3067\u3059\u3002(\u30C7\u30D5\u30A9\u30EB\u30C8)
+--- ./jdk/src/share/demo/jfc/Font2DTest/resources/TextResources_ko.properties Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,1 +0,0 @@
+-string=This is Java 2D! (Korean)
+--- ./jdk/src/share/demo/jfc/Font2DTest/resources/TextResources_zh_CN.properties Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,1 +0,0 @@
+-string=\u8FD9\u662F Java 2D! (\u9ED8\u8BA4\u503C)
+--- ./jdk/src/share/demo/jfc/Font2DTest/resources/resource.data Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,5 +0,0 @@
+-en US
+-en GB
+-ko KO
+-ab KO
+-de DE
+--- ./jdk/src/share/javavm/export/jvm.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/javavm/export/jvm.h Wed Feb 04 12:14:43 2015 -0800
+@@ -439,9 +439,6 @@
+ JNIEXPORT jobjectArray JNICALL
+ JVM_GetClassInterfaces(JNIEnv *env, jclass cls);
+
+-JNIEXPORT jobject JNICALL
+-JVM_GetClassLoader(JNIEnv *env, jclass cls);
+-
+ JNIEXPORT jboolean JNICALL
+ JVM_IsInterface(JNIEnv *env, jclass cls);
+
+@@ -1394,6 +1391,31 @@
+ JNIEXPORT jobjectArray JNICALL
+ JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArray values);
+
++/*
++ * Returns true if the JVM's lookup cache indicates that this class is
++ * known to NOT exist for the given loader.
++ */
++JNIEXPORT jboolean JNICALL
++JVM_KnownToNotExist(JNIEnv *env, jobject loader, const char *classname);
++
++/*
++ * Returns an array of all URLs that are stored in the JVM's lookup cache
++ * for the given loader. NULL if the lookup cache is unavailable.
++ */
++JNIEXPORT jobjectArray JNICALL
++JVM_GetResourceLookupCacheURLs(JNIEnv *env, jobject loader);
++
++/*
++ * Returns an array of all URLs that *may* contain the resource_name for the
++ * given loader. This function returns an integer array, each element
++ * of which can be used to index into the array returned by
++ * JVM_GetResourceLookupCacheURLs of the same loader to determine the
++ * URLs.
++ */
++JNIEXPORT jintArray JNICALL
++JVM_GetResourceLookupCache(JNIEnv *env, jobject loader, const char *resource_name);
++
++
+ /* =========================================================================
+ * The following defines a private JVM interface that the JDK can query
+ * for the JVM version and capabilities. sun.misc.Version defines
+--- ./jdk/src/share/lib/security/sunpkcs11-solaris.cfg Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/lib/security/sunpkcs11-solaris.cfg Wed Feb 04 12:14:43 2015 -0800
+@@ -18,16 +18,6 @@
+
+ disabledMechanisms = {
+ CKM_DSA_KEY_PAIR_GEN
+-# the following mechanisms are disabled due to CKR_SAVED_STATE_INVALID bug
+-# (Solaris bug 7058108)
+- CKM_MD2
+- CKM_MD5
+- CKM_SHA_1
+-# the following mechanisms are disabled due to no cloning support
+-# (Solaris bug 7050617)
+- CKM_SHA256
+- CKM_SHA384
+- CKM_SHA512
+ # the following mechanisms are disabled due to performance issues
+ # (Solaris bug 6337157)
+ CKM_DSA_SHA1
+@@ -36,10 +26,5 @@
+ CKM_SHA256_RSA_PKCS
+ CKM_SHA384_RSA_PKCS
+ CKM_SHA512_RSA_PKCS
+-# the following mechanisms are disabled to ensure backward compatibility
+-# (Solaris bug 6545046)
+- CKM_DES_CBC_PAD
+- CKM_DES3_CBC_PAD
+- CKM_AES_CBC_PAD
+ }
+
+--- ./jdk/src/share/native/common/check_code.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/common/check_code.c Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -1357,16 +1357,9 @@
+ }
+ (*env)->DeleteLocalRef(env, super);
+
+- /* The optimizer make cause this to happen on local code */
++ /* The optimizer may cause this to happen on local code */
+ if (not_found) {
+-#ifdef BROKEN_JAVAC
+- jobject loader = JVM_GetClassLoader(env, context->class);
+- int has_loader = (loader != 0);
+- (*env)->DeleteLocalRef(env, loader);
+- if (has_loader)
+-#endif /* BROKEN_JAVAC */
+- CCerror(context,
+- "Illegal use of nonvirtual function call");
++ CCerror(context, "Illegal use of nonvirtual function call");
+ }
+ }
+ }
+--- ./jdk/src/share/native/java/io/FileInputStream.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/java/io/FileInputStream.c Wed Feb 04 12:14:43 2015 -0800
+@@ -57,7 +57,7 @@
+ */
+
+ JNIEXPORT void JNICALL
+-Java_java_io_FileInputStream_open(JNIEnv *env, jobject this, jstring path) {
++Java_java_io_FileInputStream_open0(JNIEnv *env, jobject this, jstring path) {
+ fileOpen(env, this, path, fis_fd, O_RDONLY);
+ }
+
+--- ./jdk/src/share/native/java/io/RandomAccessFile.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/java/io/RandomAccessFile.c Wed Feb 04 12:14:43 2015 -0800
+@@ -47,8 +47,8 @@
+
+
+ JNIEXPORT void JNICALL
+-Java_java_io_RandomAccessFile_open(JNIEnv *env,
+- jobject this, jstring path, jint mode)
++Java_java_io_RandomAccessFile_open0(JNIEnv *env,
++ jobject this, jstring path, jint mode)
+ {
+ int flags = 0;
+ if (mode & java_io_RandomAccessFile_O_RDONLY)
+--- ./jdk/src/share/native/java/lang/Class.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/java/lang/Class.c Wed Feb 04 12:14:43 2015 -0800
+@@ -45,7 +45,6 @@
+ #define CLS "Ljava/lang/Class;"
+ #define CPL "Lsun/reflect/ConstantPool;"
+ #define STR "Ljava/lang/String;"
+-#define JCL "Ljava/lang/ClassLoader;"
+ #define FLD "Ljava/lang/reflect/Field;"
+ #define MHD "Ljava/lang/reflect/Method;"
+ #define CTR "Ljava/lang/reflect/Constructor;"
+@@ -56,7 +55,6 @@
+ {"getName0", "()" STR, (void *)&JVM_GetClassName},
+ {"getSuperclass", "()" CLS, NULL},
+ {"getInterfaces0", "()[" CLS, (void *)&JVM_GetClassInterfaces},
+- {"getClassLoader0", "()" JCL, (void *)&JVM_GetClassLoader},
+ {"isInterface", "()Z", (void *)&JVM_IsInterface},
+ {"getSigners", "()[" OBJ, (void *)&JVM_GetClassSigners},
+ {"setSigners", "([" OBJ ")V", (void *)&JVM_SetClassSigners},
+@@ -81,7 +79,6 @@
+ #undef OBJ
+ #undef CLS
+ #undef STR
+-#undef JCL
+ #undef FLD
+ #undef MHD
+ #undef CTR
+--- ./jdk/src/share/native/java/lang/ClassLoader.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/java/lang/ClassLoader.c Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -51,7 +51,7 @@
+
+ /* Convert java string to UTF char*. Use local buffer if possible,
+ otherwise malloc new memory. Returns null IFF malloc failed. */
+-static char*
++char*
+ getUTF(JNIEnv *env, jstring str, char* localBuf, int bufSize)
+ {
+ char* utfStr = NULL;
+--- ./jdk/src/share/native/java/lang/java_props.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/java/lang/java_props.h Wed Feb 04 12:14:43 2015 -0800
+@@ -117,7 +117,7 @@
+
+ char *exceptionList;
+
+- char *awt_headless /* java.awt.headless setting, if NULL (default) will not be set */
++ char *awt_headless; /* java.awt.headless setting, if NULL (default) will not be set */
+ #endif
+
+ } java_props_t;
+--- ./jdk/src/share/native/java/util/TimeZone.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/java/util/TimeZone.c Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -38,42 +38,28 @@
+ */
+ JNIEXPORT jstring JNICALL
+ Java_java_util_TimeZone_getSystemTimeZoneID(JNIEnv *env, jclass ign,
+- jstring java_home, jstring country)
++ jstring java_home)
+ {
+- const char *cname;
+ const char *java_home_dir;
+ char *javaTZ;
++ jstring jstrJavaTZ = NULL;
+
+- if (java_home == NULL)
+- return NULL;
++ CHECK_NULL_RETURN(java_home, NULL);
+
+ java_home_dir = JNU_GetStringPlatformChars(env, java_home, 0);
+- if (java_home_dir == NULL)
+- return NULL;
+-
+- if (country != NULL) {
+- cname = JNU_GetStringPlatformChars(env, country, 0);
+- /* ignore error cases for cname */
+- } else {
+- cname = NULL;
+- }
++ CHECK_NULL_RETURN(java_home_dir, NULL);
+
+ /*
+ * Invoke platform dependent mapping function
+ */
+- javaTZ = findJavaTZ_md(java_home_dir, cname);
+-
+- free((void *)java_home_dir);
+- if (cname != NULL) {
+- free((void *)cname);
++ javaTZ = findJavaTZ_md(java_home_dir);
++ if (javaTZ != NULL) {
++ jstrJavaTZ = JNU_NewStringPlatform(env, javaTZ);
++ free((void *)javaTZ);
+ }
+
+- if (javaTZ != NULL) {
+- jstring jstrJavaTZ = JNU_NewStringPlatform(env, javaTZ);
+- free((void *)javaTZ);
+- return jstrJavaTZ;
+- }
+- return NULL;
++ JNU_ReleaseStringPlatformChars(env, java_home, java_home_dir);
++ return jstrJavaTZ;
+ }
+
+ /*
+--- ./jdk/src/share/native/sun/awt/image/BufImgSurfaceData.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/awt/image/BufImgSurfaceData.c Wed Feb 04 12:14:43 2015 -0800
+@@ -291,7 +291,12 @@
+ = (*env)->GetBooleanField(env, bisdo->icm, allGrayID);
+ int *pRgb = (int *)
+ ((*env)->GetPrimitiveArrayCritical(env, bisdo->lutarray, NULL));
+- CHECK_NULL_RETURN(pRgb, (ColorData*)NULL);
++
++ if (pRgb == NULL) {
++ free(cData);
++ return (ColorData*)NULL;
++ }
++
+ cData->img_clr_tbl = initCubemap(pRgb, bisdo->lutsize, 32);
+ if (allGray == JNI_TRUE) {
+ initInverseGrayLut(pRgb, bisdo->lutsize, cData);
+@@ -304,7 +309,13 @@
+ if (JNU_IsNull(env, colorData)) {
+ jlong pData = ptr_to_jlong(cData);
+ colorData = (*env)->NewObjectA(env, clsICMCD, initICMCDmID, (jvalue *)&pData);
+- JNU_CHECK_EXCEPTION_RETURN(env, (ColorData*)NULL);
++
++ if ((*env)->ExceptionCheck(env))
++ {
++ free(cData);
++ return (ColorData*)NULL;
++ }
++
+ (*env)->SetObjectField(env, bisdo->icm, colorDataID, colorData);
+ }
+ }
+--- ./jdk/src/share/native/sun/awt/image/awt_parseImage.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/awt/image/awt_parseImage.c Wed Feb 04 12:14:43 2015 -0800
+@@ -508,6 +508,7 @@
+ cmP->csType = (*env)->GetIntField(env, cmP->jcmodel, g_CMcsTypeID);
+
+ cmP->cmType = getColorModelType(env, jcmodel);
++ JNU_CHECK_EXCEPTION_RETURN(env, -1);
+
+ cmP->isDefaultCM = FALSE;
+ cmP->isDefaultCompatCM = FALSE;
+--- ./jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Wed Feb 04 12:14:43 2015 -0800
+@@ -56,6 +56,12 @@
+ #undef MAX
+ #define MAX(a,b) ((a) > (b) ? (a) : (b))
+
++#ifdef __APPLE__
++/* use setjmp/longjmp versions that do not save/restore the signal mask */
++#define setjmp _setjmp
++#define longjmp _longjmp
++#endif
++
+ /* Cached Java method ids */
+ static jmethodID JPEGImageReader_readInputDataID;
+ static jmethodID JPEGImageReader_skipInputBytesID;
+--- ./jdk/src/share/native/sun/awt/image/jpeg/jpegdecoder.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/awt/image/jpeg/jpegdecoder.c Wed Feb 04 12:14:43 2015 -0800
+@@ -47,6 +47,12 @@
+ #include <jpeglib.h>
+ #include "jerror.h"
+
++#ifdef __APPLE__
++/* use setjmp/longjmp versions that do not save/restore the signal mask */
++#define setjmp _setjmp
++#define longjmp _longjmp
++#endif
++
+ /* The method IDs we cache. Note that the last two belongs to the
+ * java.io.InputStream class.
+ */
+--- ./jdk/src/share/native/sun/awt/splashscreen/java_awt_SplashScreen.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/awt/splashscreen/java_awt_SplashScreen.c Wed Feb 04 12:14:43 2015 -0800
+@@ -220,3 +220,18 @@
+ (*env)->ReleaseByteArrayElements(env, data, pBytes, JNI_ABORT);
+ return rc ? JNI_TRUE : JNI_FALSE;
+ }
++
++/*
++ * Class: java_awt_SplashScreen
++ * Method: _getScaleFactor
++ * Signature: (J)F
++ */
++JNIEXPORT jfloat JNICALL Java_java_awt_SplashScreen__1getScaleFactor
++(JNIEnv *env, jclass thisClass, jlong jsplash)
++{
++ Splash *splash = (Splash *) jlong_to_ptr(jsplash);
++ if (!splash) {
++ return 1;
++ }
++ return splash->scaleFactor;
++}
+\ No newline at end of file
+--- ./jdk/src/share/native/sun/awt/splashscreen/splashscreen_impl.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/awt/splashscreen/splashscreen_impl.c Wed Feb 04 12:14:43 2015 -0800
+@@ -59,6 +59,7 @@
+
+ memset(splash, 0, sizeof(Splash));
+ splash->currentFrame = -1;
++ splash->scaleFactor = 1;
+ initFormat(&splash->imageFormat, QUAD_RED_MASK, QUAD_GREEN_MASK,
+ QUAD_BLUE_MASK, QUAD_ALPHA_MASK);
+ SplashInitPlatform(splash);
+@@ -101,6 +102,13 @@
+ SplashSetFileJarName(NULL, NULL);
+ }
+
++SPLASHEXPORT void
++SplashSetScaleFactor(float scaleFactor)
++{
++ Splash *splash = SplashGetInstance();
++ splash->scaleFactor = scaleFactor;
++}
++
+ void
+ SplashDone(Splash * splash)
+ {
+--- ./jdk/src/share/native/sun/awt/splashscreen/splashscreen_impl.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/awt/splashscreen/splashscreen_impl.h Wed Feb 04 12:14:43 2015 -0800
+@@ -35,6 +35,9 @@
+ SPLASHEXPORT void SplashInit(void);
+ SPLASHEXPORT void SplashClose(void);
+
++SPLASHEXPORT void SplashSetScaleFactor(float);
++SPLASHEXPORT char* SplashGetScaledImageName(const char*, const char*, float*);
++
+ SPLASHEXPORT void
+ SplashSetFileJarName(const char* fileName, const char* jarName);
+
+@@ -79,6 +82,7 @@
+ int fileNameLen;
+ char* jarName; /* stored in 16-bit unicode (jchars) */
+ int jarNameLen;
++ float scaleFactor;
+ #if defined(WITH_WIN32)
+ BOOL isLayered;
+ HWND hWnd;
+@@ -115,6 +119,8 @@
+
+ unsigned SplashTime();
+ char* SplashConvertStringAlloc(const char* in, int *size);
++char* SplashGetScaledImageName(const char* jarName,
++ const char* fileName, float *scaleFactor);
+
+ void SplashLock(Splash * splash);
+ void SplashUnlock(Splash * splash);
+@@ -138,6 +144,7 @@
+ void SplashUpdateScreenData(Splash * splash);
+
+ void SplashCleanup(Splash * splash);
++void SplashSetScaleFactor(float scaleFactor);
+
+
+ typedef struct SplashStream {
+--- ./jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c Wed Feb 04 12:14:43 2015 -0800
+@@ -31,6 +31,12 @@
+
+ #include <setjmp.h>
+
++#ifdef __APPLE__
++/* use setjmp/longjmp versions that do not save/restore the signal mask */
++#define setjmp _setjmp
++#define longjmp _longjmp
++#endif
++
+ /* stream input handling */
+
+ typedef struct
+--- ./jdk/src/share/native/sun/awt/splashscreen/splashscreen_png.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/awt/splashscreen/splashscreen_png.c Wed Feb 04 12:14:43 2015 -0800
+@@ -71,7 +71,12 @@
+ goto done;
+ }
+
++#ifdef __APPLE__
++ /* use setjmp/longjmp versions that do not save/restore the signal mask */
++ if (_setjmp(png_set_longjmp_fn(png_ptr, _longjmp, sizeof(jmp_buf)))) {
++#else
+ if (setjmp(png_jmpbuf(png_ptr))) {
++#endif
+ goto done;
+ }
+
+--- ./jdk/src/share/native/sun/font/DrawGlyphList.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/font/DrawGlyphList.c Wed Feb 04 12:14:43 2015 -0800
+@@ -52,7 +52,8 @@
+
+ GlyphBlitVector* setupBlitVector(JNIEnv *env, jobject glyphlist) {
+
+- int g, bytesNeeded;
++ int g;
++ size_t bytesNeeded;
+ jlong *imagePtrs;
+ jfloat* positions = NULL;
+ GlyphInfo *ginfo;
+@@ -71,6 +72,9 @@
+
+ bytesNeeded = sizeof(GlyphBlitVector)+sizeof(ImageRef)*len;
+ gbv = (GlyphBlitVector*)malloc(bytesNeeded);
++ if (gbv == NULL) {
++ return NULL;
++ }
+ gbv->numGlyphs = len;
+ gbv->glyphs = (ImageRef*)((unsigned char*)gbv+sizeof(GlyphBlitVector));
+
+@@ -479,7 +483,8 @@
+ */
+ GlyphBlitVector* setupLCDBlitVector(JNIEnv *env, jobject glyphlist) {
+
+- int g, bytesNeeded;
++ int g;
++ size_t bytesNeeded;
+ jlong *imagePtrs;
+ jfloat* positions = NULL;
+ GlyphInfo *ginfo;
+@@ -500,6 +505,9 @@
+
+ bytesNeeded = sizeof(GlyphBlitVector)+sizeof(ImageRef)*len;
+ gbv = (GlyphBlitVector*)malloc(bytesNeeded);
++ if (gbv == NULL) {
++ return NULL;
++ }
+ gbv->numGlyphs = len;
+ gbv->glyphs = (ImageRef*)((unsigned char*)gbv+sizeof(GlyphBlitVector));
+
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c Wed Feb 04 12:14:43 2015 -0800
+@@ -467,11 +467,12 @@
+ CAM02COLOR clr;
+ cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel;
+
+- memset(&clr, 0, sizeof(clr));
+ _cmsAssert(lpMod != NULL);
+ _cmsAssert(pIn != NULL);
+ _cmsAssert(pOut != NULL);
+
++ memset(&clr, 0, sizeof(clr));
++
+ clr.XYZ[0] = pIn ->X;
+ clr.XYZ[1] = pIn ->Y;
+ clr.XYZ[2] = pIn ->Z;
+@@ -492,11 +493,12 @@
+ CAM02COLOR clr;
+ cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel;
+
+- memset(&clr, 0, sizeof(clr));
+ _cmsAssert(lpMod != NULL);
+ _cmsAssert(pIn != NULL);
+ _cmsAssert(pOut != NULL);
+
++ memset(&clr, 0, sizeof(clr));
++
+ clr.J = pIn -> J;
+ clr.C = pIn -> C;
+ clr.h = pIn -> h;
+@@ -511,4 +513,3 @@
+ pOut ->Y = clr.XYZ[1];
+ pOut ->Z = clr.XYZ[2];
+ }
+-
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c Wed Feb 04 12:14:43 2015 -0800
+@@ -77,7 +77,7 @@
+ // Symbols
+ typedef enum {
+
+- SNONE,
++ SUNDEFINED,
+ SINUM, // Integer
+ SDNUM, // Real
+ SIDENT, // Identifier
+@@ -550,7 +550,7 @@
+ else l = x + 1;
+ }
+
+- return SNONE;
++ return SUNDEFINED;
+ }
+
+
+@@ -735,7 +735,7 @@
+
+
+ key = BinSrchKey(it8->id);
+- if (key == SNONE) it8->sy = SIDENT;
++ if (key == SUNDEFINED) it8->sy = SIDENT;
+ else it8->sy = key;
+
+ }
+@@ -1326,7 +1326,7 @@
+ it8->ValidKeywords = NULL;
+ it8->ValidSampleID = NULL;
+
+- it8 -> sy = SNONE;
++ it8 -> sy = SUNDEFINED;
+ it8 -> ch = ' ';
+ it8 -> Source = NULL;
+ it8 -> inum = 0;
+@@ -2179,9 +2179,9 @@
+
+ if (cmsstrcasecmp(Fld, "SAMPLE_ID") == 0) {
+
+- t -> SampleID = idField;
+-
+- for (i=0; i < t -> nPatches; i++) {
++ t -> SampleID = idField;
++
++ for (i=0; i < t -> nPatches; i++) {
+
+ char *Data = GetData(it8, i, idField);
+ if (Data) {
+@@ -2196,7 +2196,7 @@
+ SetData(it8, i, idField, Buffer);
+
+ }
+- }
++ }
+
+ }
+
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c Wed Feb 04 12:14:43 2015 -0800
+@@ -137,15 +137,68 @@
+
+
+ // A pointer to the begining of the list
+-static cmsIntentsList *Intents = DefaultIntents;
++_cmsIntentsPluginChunkType _cmsIntentsPluginChunk = { NULL };
++
++// Duplicates the zone of memory used by the plug-in in the new context
++static
++void DupPluginIntentsList(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ _cmsIntentsPluginChunkType newHead = { NULL };
++ cmsIntentsList* entry;
++ cmsIntentsList* Anterior = NULL;
++ _cmsIntentsPluginChunkType* head = (_cmsIntentsPluginChunkType*) src->chunks[IntentPlugin];
++
++ // Walk the list copying all nodes
++ for (entry = head->Intents;
++ entry != NULL;
++ entry = entry ->Next) {
++
++ cmsIntentsList *newEntry = ( cmsIntentsList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(cmsIntentsList));
++
++ if (newEntry == NULL)
++ return;
++
++ // We want to keep the linked list order, so this is a little bit tricky
++ newEntry -> Next = NULL;
++ if (Anterior)
++ Anterior -> Next = newEntry;
++
++ Anterior = newEntry;
++
++ if (newHead.Intents == NULL)
++ newHead.Intents = newEntry;
++ }
++
++ ctx ->chunks[IntentPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsIntentsPluginChunkType));
++}
++
++void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ if (src != NULL) {
++
++ // Copy all linked list
++ DupPluginIntentsList(ctx, src);
++ }
++ else {
++ static _cmsIntentsPluginChunkType IntentsPluginChunkType = { NULL };
++ ctx ->chunks[IntentPlugin] = _cmsSubAllocDup(ctx ->MemPool, &IntentsPluginChunkType, sizeof(_cmsIntentsPluginChunkType));
++ }
++}
++
+
+ // Search the list for a suitable intent. Returns NULL if not found
+ static
+-cmsIntentsList* SearchIntent(cmsUInt32Number Intent)
++cmsIntentsList* SearchIntent(cmsContext ContextID, cmsUInt32Number Intent)
+ {
++ _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(ContextID, IntentPlugin);
+ cmsIntentsList* pt;
+
+- for (pt = Intents; pt != NULL; pt = pt -> Next)
++ for (pt = ctx -> Intents; pt != NULL; pt = pt -> Next)
++ if (pt ->Intent == Intent) return pt;
++
++ for (pt = DefaultIntents; pt != NULL; pt = pt -> Next)
+ if (pt ->Intent == Intent) return pt;
+
+ return NULL;
+@@ -1031,7 +1084,7 @@
+ // this case would present some issues if the custom intent tries to do things like
+ // preserve primaries. This solution is not perfect, but works well on most cases.
+
+- Intent = SearchIntent(TheIntents[0]);
++ Intent = SearchIntent(ContextID, TheIntents[0]);
+ if (Intent == NULL) {
+ cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported intent '%d'", TheIntents[0]);
+ return NULL;
+@@ -1046,12 +1099,14 @@
+ // Get information about available intents. nMax is the maximum space for the supplied "Codes"
+ // and "Descriptions" the function returns the total number of intents, which may be greater
+ // than nMax, although the matrices are not populated beyond this level.
+-cmsUInt32Number CMSEXPORT cmsGetSupportedIntents(cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions)
++cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions)
+ {
++ _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(ContextID, IntentPlugin);
+ cmsIntentsList* pt;
+ cmsUInt32Number nIntents;
+
+- for (nIntents=0, pt = Intents; pt != NULL; pt = pt -> Next)
++
++ for (nIntents=0, pt = ctx->Intents; pt != NULL; pt = pt -> Next)
+ {
+ if (nIntents < nMax) {
+ if (Codes != NULL)
+@@ -1064,37 +1119,52 @@
+ nIntents++;
+ }
+
++ for (nIntents=0, pt = DefaultIntents; pt != NULL; pt = pt -> Next)
++ {
++ if (nIntents < nMax) {
++ if (Codes != NULL)
++ Codes[nIntents] = pt ->Intent;
++
++ if (Descriptions != NULL)
++ Descriptions[nIntents] = pt ->Description;
++ }
++
++ nIntents++;
++ }
+ return nIntents;
+ }
+
++cmsUInt32Number CMSEXPORT cmsGetSupportedIntents(cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions)
++{
++ return cmsGetSupportedIntentsTHR(NULL, nMax, Codes, Descriptions);
++}
++
+ // The plug-in registration. User can add new intents or override default routines
+ cmsBool _cmsRegisterRenderingIntentPlugin(cmsContext id, cmsPluginBase* Data)
+ {
++ _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(id, IntentPlugin);
+ cmsPluginRenderingIntent* Plugin = (cmsPluginRenderingIntent*) Data;
+ cmsIntentsList* fl;
+
+- // Do we have to reset the intents?
++ // Do we have to reset the custom intents?
+ if (Data == NULL) {
+
+- Intents = DefaultIntents;
+- return TRUE;
++ ctx->Intents = NULL;
++ return TRUE;
+ }
+
+- fl = SearchIntent(Plugin ->Intent);
++ fl = (cmsIntentsList*) _cmsPluginMalloc(id, sizeof(cmsIntentsList));
++ if (fl == NULL) return FALSE;
+
+- if (fl == NULL) {
+- fl = (cmsIntentsList*) _cmsPluginMalloc(id, sizeof(cmsIntentsList));
+- if (fl == NULL) return FALSE;
+- }
+
+ fl ->Intent = Plugin ->Intent;
+- strncpy(fl ->Description, Plugin ->Description, 255);
+- fl ->Description[255] = 0;
++ strncpy(fl ->Description, Plugin ->Description, sizeof(fl ->Description)-1);
++ fl ->Description[sizeof(fl ->Description)-1] = 0;
+
+ fl ->Link = Plugin ->Link;
+
+- fl ->Next = Intents;
+- Intents = fl;
++ fl ->Next = ctx ->Intents;
++ ctx ->Intents = fl;
+
+ return TRUE;
+ }
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c Wed Feb 04 12:14:43 2015 -0800
+@@ -60,13 +60,14 @@
+ // compare two strings ignoring case
+ int CMSEXPORT cmsstrcasecmp(const char* s1, const char* s2)
+ {
+- register const unsigned char *us1 = (const unsigned char *)s1,
+- *us2 = (const unsigned char *)s2;
++ register const unsigned char *us1 = (const unsigned char *)s1,
++ *us2 = (const unsigned char *)s2;
+
+- while (toupper(*us1) == toupper(*us2++))
+- if (*us1++ == '\0')
+- return (0);
+- return (toupper(*us1) - toupper(*--us2));
++ while (toupper(*us1) == toupper(*us2++))
++ if (*us1++ == '\0')
++ return 0;
++
++ return (toupper(*us1) - toupper(*--us2));
+ }
+
+ // long int because C99 specifies ftell in such way (7.19.9.2)
+@@ -91,9 +92,8 @@
+ //
+ // This is the interface to low-level memory management routines. By default a simple
+ // wrapping to malloc/free/realloc is provided, although there is a limit on the max
+-// amount of memoy that can be reclaimed. This is mostly as a safety feature to
+-// prevent bogus or malintentionated code to allocate huge blocks that otherwise lcms
+-// would never need.
++// amount of memoy that can be reclaimed. This is mostly as a safety feature to prevent
++// bogus or evil code to allocate huge blocks that otherwise lcms would never need.
+
+ #define MAX_MEMORY_FOR_ALLOC ((cmsUInt32Number)(1024U*1024U*512U))
+
+@@ -103,7 +103,7 @@
+ // required to be implemented: malloc, realloc and free, although the user may want to
+ // replace the optional mallocZero, calloc and dup as well.
+
+-cmsBool _cmsRegisterMemHandlerPlugin(cmsPluginBase* Plugin);
++cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
+
+ // *********************************************************************************
+
+@@ -143,7 +143,7 @@
+ cmsUNUSED_PARAMETER(ContextID);
+ }
+
+-// The default realloc function. Again it check for exploits. If Ptr is NULL,
++// The default realloc function. Again it checks for exploits. If Ptr is NULL,
+ // realloc behaves the same way as malloc and allocates a new block of size bytes.
+ static
+ void* _cmsReallocDefaultFn(cmsContext ContextID, void* Ptr, cmsUInt32Number size)
+@@ -196,28 +196,73 @@
+ return mem;
+ }
+
+-// Pointers to malloc and _cmsFree functions in current environment
+-static void * (* MallocPtr)(cmsContext ContextID, cmsUInt32Number size) = _cmsMallocDefaultFn;
+-static void * (* MallocZeroPtr)(cmsContext ContextID, cmsUInt32Number size) = _cmsMallocZeroDefaultFn;
+-static void (* FreePtr)(cmsContext ContextID, void *Ptr) = _cmsFreeDefaultFn;
+-static void * (* ReallocPtr)(cmsContext ContextID, void *Ptr, cmsUInt32Number NewSize) = _cmsReallocDefaultFn;
+-static void * (* CallocPtr)(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size)= _cmsCallocDefaultFn;
+-static void * (* DupPtr)(cmsContext ContextID, const void* Org, cmsUInt32Number size) = _cmsDupDefaultFn;
++
++// Pointers to memory manager functions in Context0
++_cmsMemPluginChunkType _cmsMemPluginChunk = { _cmsMallocDefaultFn, _cmsMallocZeroDefaultFn, _cmsFreeDefaultFn,
++ _cmsReallocDefaultFn, _cmsCallocDefaultFn, _cmsDupDefaultFn
++ };
++
++
++// Reset and duplicate memory manager
++void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsContext_struct* src)
++{
++ _cmsAssert(ctx != NULL);
++
++ if (src != NULL) {
++
++ // Duplicate
++ ctx ->chunks[MemPlugin] = _cmsSubAllocDup(ctx ->MemPool, src ->chunks[MemPlugin], sizeof(_cmsMemPluginChunkType));
++ }
++ else {
++
++ // To reset it, we use the default allocators, which cannot be overriden
++ ctx ->chunks[MemPlugin] = &ctx ->DefaultMemoryManager;
++ }
++}
++
++// Auxiliar to fill memory management functions from plugin (or context 0 defaults)
++void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr)
++{
++ if (Plugin == NULL) {
++
++ memcpy(ptr, &_cmsMemPluginChunk, sizeof(_cmsMemPluginChunk));
++ }
++ else {
++
++ ptr ->MallocPtr = Plugin -> MallocPtr;
++ ptr ->FreePtr = Plugin -> FreePtr;
++ ptr ->ReallocPtr = Plugin -> ReallocPtr;
++
++ // Make sure we revert to defaults
++ ptr ->MallocZeroPtr= _cmsMallocZeroDefaultFn;
++ ptr ->CallocPtr = _cmsCallocDefaultFn;
++ ptr ->DupPtr = _cmsDupDefaultFn;
++
++ if (Plugin ->MallocZeroPtr != NULL) ptr ->MallocZeroPtr = Plugin -> MallocZeroPtr;
++ if (Plugin ->CallocPtr != NULL) ptr ->CallocPtr = Plugin -> CallocPtr;
++ if (Plugin ->DupPtr != NULL) ptr ->DupPtr = Plugin -> DupPtr;
++
++ }
++}
++
+
+ // Plug-in replacement entry
+-cmsBool _cmsRegisterMemHandlerPlugin(cmsPluginBase *Data)
++cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase *Data)
+ {
+ cmsPluginMemHandler* Plugin = (cmsPluginMemHandler*) Data;
++ _cmsMemPluginChunkType* ptr;
+
+- // NULL forces to reset to defaults
++ // NULL forces to reset to defaults. In this special case, the defaults are stored in the context structure.
++ // Remaining plug-ins does NOT have any copy in the context structure, but this is somehow special as the
++ // context internal data should be malloce'd by using those functions.
+ if (Data == NULL) {
+
+- MallocPtr = _cmsMallocDefaultFn;
+- MallocZeroPtr= _cmsMallocZeroDefaultFn;
+- FreePtr = _cmsFreeDefaultFn;
+- ReallocPtr = _cmsReallocDefaultFn;
+- CallocPtr = _cmsCallocDefaultFn;
+- DupPtr = _cmsDupDefaultFn;
++ struct _cmsContext_struct* ctx = ( struct _cmsContext_struct*) ContextID;
++
++ // Return to the default allocators
++ if (ContextID != NULL) {
++ ctx->chunks[MemPlugin] = (void*) &ctx->DefaultMemoryManager;
++ }
+ return TRUE;
+ }
+
+@@ -227,51 +272,56 @@
+ Plugin -> ReallocPtr == NULL) return FALSE;
+
+ // Set replacement functions
+- MallocPtr = Plugin -> MallocPtr;
+- FreePtr = Plugin -> FreePtr;
+- ReallocPtr = Plugin -> ReallocPtr;
++ ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
++ if (ptr == NULL)
++ return FALSE;
+
+- if (Plugin ->MallocZeroPtr != NULL) MallocZeroPtr = Plugin ->MallocZeroPtr;
+- if (Plugin ->CallocPtr != NULL) CallocPtr = Plugin -> CallocPtr;
+- if (Plugin ->DupPtr != NULL) DupPtr = Plugin -> DupPtr;
+-
++ _cmsInstallAllocFunctions(Plugin, ptr);
+ return TRUE;
+ }
+
+ // Generic allocate
+ void* CMSEXPORT _cmsMalloc(cmsContext ContextID, cmsUInt32Number size)
+ {
+- return MallocPtr(ContextID, size);
++ _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
++ return ptr ->MallocPtr(ContextID, size);
+ }
+
+ // Generic allocate & zero
+ void* CMSEXPORT _cmsMallocZero(cmsContext ContextID, cmsUInt32Number size)
+ {
+- return MallocZeroPtr(ContextID, size);
++ _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
++ return ptr->MallocZeroPtr(ContextID, size);
+ }
+
+ // Generic calloc
+ void* CMSEXPORT _cmsCalloc(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size)
+ {
+- return CallocPtr(ContextID, num, size);
++ _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
++ return ptr->CallocPtr(ContextID, num, size);
+ }
+
+ // Generic reallocate
+ void* CMSEXPORT _cmsRealloc(cmsContext ContextID, void* Ptr, cmsUInt32Number size)
+ {
+- return ReallocPtr(ContextID, Ptr, size);
++ _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
++ return ptr->ReallocPtr(ContextID, Ptr, size);
+ }
+
+ // Generic free memory
+ void CMSEXPORT _cmsFree(cmsContext ContextID, void* Ptr)
+ {
+- if (Ptr != NULL) FreePtr(ContextID, Ptr);
++ if (Ptr != NULL) {
++ _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
++ ptr ->FreePtr(ContextID, Ptr);
++ }
+ }
+
+ // Generic block duplication
+ void* CMSEXPORT _cmsDupMem(cmsContext ContextID, const void* Org, cmsUInt32Number size)
+ {
+- return DupPtr(ContextID, Org, size);
++ _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
++ return ptr ->DupPtr(ContextID, Org, size);
+ }
+
+ // ********************************************************************************************
+@@ -380,6 +430,26 @@
+ return (void*) ptr;
+ }
+
++// Duplicate in pool
++void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size)
++{
++ void *NewPtr;
++
++ // Dup of null pointer is also NULL
++ if (ptr == NULL)
++ return NULL;
++
++ NewPtr = _cmsSubAlloc(s, size);
++
++ if (ptr != NULL && NewPtr != NULL) {
++ memcpy(NewPtr, ptr, size);
++ }
++
++ return NewPtr;
++}
++
++
++
+ // Error logging ******************************************************************
+
+ // There is no error handling at all. When a funtion fails, it returns proper value.
+@@ -401,8 +471,26 @@
+ // This is our default log error
+ static void DefaultLogErrorHandlerFunction(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *Text);
+
+-// The current handler in actual environment
+-static cmsLogErrorHandlerFunction LogErrorHandler = DefaultLogErrorHandlerFunction;
++// Context0 storage, which is global
++_cmsLogErrorChunkType _cmsLogErrorChunk = { DefaultLogErrorHandlerFunction };
++
++// Allocates and inits error logger container for a given context. If src is NULL, only initializes the value
++// to the default. Otherwise, it duplicates the value. The interface is standard across all context clients
++void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ static _cmsLogErrorChunkType LogErrorChunk = { DefaultLogErrorHandlerFunction };
++ void* from;
++
++ if (src != NULL) {
++ from = src ->chunks[Logger];
++ }
++ else {
++ from = &LogErrorChunk;
++ }
++
++ ctx ->chunks[Logger] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsLogErrorChunkType));
++}
+
+ // The default error logger does nothing.
+ static
+@@ -416,13 +504,24 @@
+ cmsUNUSED_PARAMETER(Text);
+ }
+
+-// Change log error
++// Change log error, context based
++void CMSEXPORT cmsSetLogErrorHandlerTHR(cmsContext ContextID, cmsLogErrorHandlerFunction Fn)
++{
++ _cmsLogErrorChunkType* lhg = (_cmsLogErrorChunkType*) _cmsContextGetClientChunk(ContextID, Logger);
++
++ if (lhg != NULL) {
++
++ if (Fn == NULL)
++ lhg -> LogErrorHandler = DefaultLogErrorHandlerFunction;
++ else
++ lhg -> LogErrorHandler = Fn;
++ }
++}
++
++// Change log error, legacy
+ void CMSEXPORT cmsSetLogErrorHandler(cmsLogErrorHandlerFunction Fn)
+ {
+- if (Fn == NULL)
+- LogErrorHandler = DefaultLogErrorHandlerFunction;
+- else
+- LogErrorHandler = Fn;
++ cmsSetLogErrorHandlerTHR(NULL, Fn);
+ }
+
+ // Log an error
+@@ -431,13 +530,18 @@
+ {
+ va_list args;
+ char Buffer[MAX_ERROR_MESSAGE_LEN];
++ _cmsLogErrorChunkType* lhg;
++
+
+ va_start(args, ErrorText);
+ vsnprintf(Buffer, MAX_ERROR_MESSAGE_LEN-1, ErrorText, args);
+ va_end(args);
+
+- // Call handler
+- LogErrorHandler(ContextID, ErrorCode, Buffer);
++ // Check for the context, if specified go there. If not, go for the global
++ lhg = (_cmsLogErrorChunkType*) _cmsContextGetClientChunk(ContextID, Logger);
++ if (lhg ->LogErrorHandler) {
++ lhg ->LogErrorHandler(ContextID, ErrorCode, Buffer);
++ }
+ }
+
+ // Utility function to print signatures
+@@ -455,3 +559,125 @@
+ String[4] = 0;
+ }
+
++//--------------------------------------------------------------------------------------------------
++
++
++static
++void* defMtxCreate(cmsContext id)
++{
++ _cmsMutex* ptr_mutex = (_cmsMutex*) _cmsMalloc(id, sizeof(_cmsMutex));
++ _cmsInitMutexPrimitive(ptr_mutex);
++ return (void*) ptr_mutex;
++}
++
++static
++void defMtxDestroy(cmsContext id, void* mtx)
++{
++ _cmsDestroyMutexPrimitive((_cmsMutex *) mtx);
++ _cmsFree(id, mtx);
++}
++
++static
++cmsBool defMtxLock(cmsContext id, void* mtx)
++{
++ cmsUNUSED_PARAMETER(id);
++ return _cmsLockPrimitive((_cmsMutex *) mtx) == 0;
++}
++
++static
++void defMtxUnlock(cmsContext id, void* mtx)
++{
++ cmsUNUSED_PARAMETER(id);
++ _cmsUnlockPrimitive((_cmsMutex *) mtx);
++}
++
++
++
++// Pointers to memory manager functions in Context0
++_cmsMutexPluginChunkType _cmsMutexPluginChunk = { defMtxCreate, defMtxDestroy, defMtxLock, defMtxUnlock };
++
++// Allocate and init mutex container.
++void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ static _cmsMutexPluginChunkType MutexChunk = {defMtxCreate, defMtxDestroy, defMtxLock, defMtxUnlock };
++ void* from;
++
++ if (src != NULL) {
++ from = src ->chunks[MutexPlugin];
++ }
++ else {
++ from = &MutexChunk;
++ }
++
++ ctx ->chunks[MutexPlugin] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsMutexPluginChunkType));
++}
++
++// Register new ways to transform
++cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Data)
++{
++ cmsPluginMutex* Plugin = (cmsPluginMutex*) Data;
++ _cmsMutexPluginChunkType* ctx = ( _cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin);
++
++ if (Data == NULL) {
++
++ // No lock routines
++ ctx->CreateMutexPtr = NULL;
++ ctx->DestroyMutexPtr = NULL;
++ ctx->LockMutexPtr = NULL;
++ ctx ->UnlockMutexPtr = NULL;
++ return TRUE;
++ }
++
++ // Factory callback is required
++ if (Plugin ->CreateMutexPtr == NULL || Plugin ->DestroyMutexPtr == NULL ||
++ Plugin ->LockMutexPtr == NULL || Plugin ->UnlockMutexPtr == NULL) return FALSE;
++
++
++ ctx->CreateMutexPtr = Plugin->CreateMutexPtr;
++ ctx->DestroyMutexPtr = Plugin ->DestroyMutexPtr;
++ ctx ->LockMutexPtr = Plugin ->LockMutexPtr;
++ ctx ->UnlockMutexPtr = Plugin ->UnlockMutexPtr;
++
++ // All is ok
++ return TRUE;
++}
++
++// Generic Mutex fns
++void* CMSEXPORT _cmsCreateMutex(cmsContext ContextID)
++{
++ _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin);
++
++ if (ptr ->CreateMutexPtr == NULL) return NULL;
++
++ return ptr ->CreateMutexPtr(ContextID);
++}
++
++void CMSEXPORT _cmsDestroyMutex(cmsContext ContextID, void* mtx)
++{
++ _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin);
++
++ if (ptr ->DestroyMutexPtr != NULL) {
++
++ ptr ->DestroyMutexPtr(ContextID, mtx);
++ }
++}
++
++cmsBool CMSEXPORT _cmsLockMutex(cmsContext ContextID, void* mtx)
++{
++ _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin);
++
++ if (ptr ->LockMutexPtr == NULL) return TRUE;
++
++ return ptr ->LockMutexPtr(ContextID, mtx);
++}
++
++void CMSEXPORT _cmsUnlockMutex(cmsContext ContextID, void* mtx)
++{
++ _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin);
++
++ if (ptr ->UnlockMutexPtr != NULL) {
++
++ ptr ->UnlockMutexPtr(ContextID, mtx);
++ }
++}
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c Wed Feb 04 12:14:43 2015 -0800
+@@ -82,7 +82,6 @@
+
+ } _cmsParametricCurvesCollection;
+
+-
+ // This is the default (built-in) evaluator
+ static cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Number Params[], cmsFloat64Number R);
+
+@@ -95,22 +94,77 @@
+ NULL // Next in chain
+ };
+
++// Duplicates the zone of memory used by the plug-in in the new context
++static
++void DupPluginCurvesList(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ _cmsCurvesPluginChunkType newHead = { NULL };
++ _cmsParametricCurvesCollection* entry;
++ _cmsParametricCurvesCollection* Anterior = NULL;
++ _cmsCurvesPluginChunkType* head = (_cmsCurvesPluginChunkType*) src->chunks[CurvesPlugin];
++
++ _cmsAssert(head != NULL);
++
++ // Walk the list copying all nodes
++ for (entry = head->ParametricCurves;
++ entry != NULL;
++ entry = entry ->Next) {
++
++ _cmsParametricCurvesCollection *newEntry = ( _cmsParametricCurvesCollection *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsParametricCurvesCollection));
++
++ if (newEntry == NULL)
++ return;
++
++ // We want to keep the linked list order, so this is a little bit tricky
++ newEntry -> Next = NULL;
++ if (Anterior)
++ Anterior -> Next = newEntry;
++
++ Anterior = newEntry;
++
++ if (newHead.ParametricCurves == NULL)
++ newHead.ParametricCurves = newEntry;
++ }
++
++ ctx ->chunks[CurvesPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsCurvesPluginChunkType));
++}
++
++// The allocator have to follow the chain
++void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ _cmsAssert(ctx != NULL);
++
++ if (src != NULL) {
++
++ // Copy all linked list
++ DupPluginCurvesList(ctx, src);
++ }
++ else {
++ static _cmsCurvesPluginChunkType CurvesPluginChunk = { NULL };
++ ctx ->chunks[CurvesPlugin] = _cmsSubAllocDup(ctx ->MemPool, &CurvesPluginChunk, sizeof(_cmsCurvesPluginChunkType));
++ }
++}
++
++
+ // The linked list head
+-static _cmsParametricCurvesCollection* ParametricCurves = &DefaultCurves;
++_cmsCurvesPluginChunkType _cmsCurvesPluginChunk = { NULL };
+
+ // As a way to install new parametric curves
+-cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext id, cmsPluginBase* Data)
++cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Data)
+ {
++ _cmsCurvesPluginChunkType* ctx = ( _cmsCurvesPluginChunkType*) _cmsContextGetClientChunk(ContextID, CurvesPlugin);
+ cmsPluginParametricCurves* Plugin = (cmsPluginParametricCurves*) Data;
+ _cmsParametricCurvesCollection* fl;
+
+ if (Data == NULL) {
+
+- ParametricCurves = &DefaultCurves;
++ ctx -> ParametricCurves = NULL;
+ return TRUE;
+ }
+
+- fl = (_cmsParametricCurvesCollection*) _cmsPluginMalloc(id, sizeof(_cmsParametricCurvesCollection));
++ fl = (_cmsParametricCurvesCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsParametricCurvesCollection));
+ if (fl == NULL) return FALSE;
+
+ // Copy the parameters
+@@ -126,8 +180,8 @@
+ memmove(fl->ParameterCount, Plugin ->ParameterCount, fl->nFunctions * sizeof(cmsUInt32Number));
+
+ // Keep linked list
+- fl ->Next = ParametricCurves;
+- ParametricCurves = fl;
++ fl ->Next = ctx->ParametricCurves;
++ ctx->ParametricCurves = fl;
+
+ // All is ok
+ return TRUE;
+@@ -149,12 +203,24 @@
+
+ // Search for the collection which contains a specific type
+ static
+-_cmsParametricCurvesCollection *GetParametricCurveByType(int Type, int* index)
++_cmsParametricCurvesCollection *GetParametricCurveByType(cmsContext ContextID, int Type, int* index)
+ {
+ _cmsParametricCurvesCollection* c;
+ int Position;
++ _cmsCurvesPluginChunkType* ctx = ( _cmsCurvesPluginChunkType*) _cmsContextGetClientChunk(ContextID, CurvesPlugin);
+
+- for (c = ParametricCurves; c != NULL; c = c ->Next) {
++ for (c = ctx->ParametricCurves; c != NULL; c = c ->Next) {
++
++ Position = IsInSet(Type, c);
++
++ if (Position != -1) {
++ if (index != NULL)
++ *index = Position;
++ return c;
++ }
++ }
++ // If none found, revert for defaults
++ for (c = &DefaultCurves; c != NULL; c = c ->Next) {
+
+ Position = IsInSet(Type, c);
+
+@@ -251,7 +317,7 @@
+ p ->Segments[i].SampledPoints = NULL;
+
+
+- c = GetParametricCurveByType(Segments[i].Type, NULL);
++ c = GetParametricCurveByType(ContextID, Segments[i].Type, NULL);
+ if (c != NULL)
+ p ->Evals[i] = c ->Evaluator;
+ }
+@@ -677,12 +743,12 @@
+ cmsCurveSegment Seg0;
+ int Pos = 0;
+ cmsUInt32Number size;
+- _cmsParametricCurvesCollection* c = GetParametricCurveByType(Type, &Pos);
++ _cmsParametricCurvesCollection* c = GetParametricCurveByType(ContextID, Type, &Pos);
+
+ _cmsAssert(Params != NULL);
+
+ if (c == NULL) {
+- cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Invalid parametric curve type %d", Type);
++ cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Invalid parametric curve type %d", Type);
+ return NULL;
+ }
+
+@@ -872,7 +938,10 @@
+ _cmsAssert(InCurve != NULL);
+
+ // Try to reverse it analytically whatever possible
+- if (InCurve ->nSegments == 1 && InCurve ->Segments[0].Type > 0 && InCurve -> Segments[0].Type <= 5) {
++
++ if (InCurve ->nSegments == 1 && InCurve ->Segments[0].Type > 0 &&
++ /* InCurve -> Segments[0].Type <= 5 */
++ GetParametricCurveByType(InCurve ->InterpParams->ContextID, InCurve ->Segments[0].Type, NULL) != NULL) {
+
+ return cmsBuildParametricToneCurve(InCurve ->InterpParams->ContextID,
+ -(InCurve -> Segments[0].Type),
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c Wed Feb 04 12:14:43 2015 -0800
+@@ -191,7 +191,7 @@
+
+ out = ComputeKToLstar(ContextID, nPoints, 1,
+ Intents + (nProfiles - 1),
+- hProfiles + (nProfiles - 1),
++ &hProfiles [nProfiles - 1],
+ BPC + (nProfiles - 1),
+ AdaptationStates + (nProfiles - 1),
+ dwFlags);
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c Wed Feb 04 12:14:43 2015 -0800
+@@ -62,31 +62,57 @@
+ static cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cmsUInt32Number nOutputChannels, cmsUInt32Number dwFlags);
+
+ // This is the default factory
+-static cmsInterpFnFactory Interpolators = DefaultInterpolatorsFactory;
++_cmsInterpPluginChunkType _cmsInterpPluginChunk = { NULL };
++
++// The interpolation plug-in memory chunk allocator/dup
++void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsContext_struct* src)
++{
++ void* from;
++
++ _cmsAssert(ctx != NULL);
++
++ if (src != NULL) {
++ from = src ->chunks[InterpPlugin];
++ }
++ else {
++ static _cmsInterpPluginChunkType InterpPluginChunk = { NULL };
++
++ from = &InterpPluginChunk;
++ }
++
++ _cmsAssert(from != NULL);
++ ctx ->chunks[InterpPlugin] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsInterpPluginChunkType));
++}
+
+
+ // Main plug-in entry
+-cmsBool _cmsRegisterInterpPlugin(cmsPluginBase* Data)
++cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Data)
+ {
+ cmsPluginInterpolation* Plugin = (cmsPluginInterpolation*) Data;
++ _cmsInterpPluginChunkType* ptr = (_cmsInterpPluginChunkType*) _cmsContextGetClientChunk(ContextID, InterpPlugin);
+
+ if (Data == NULL) {
+
+- Interpolators = DefaultInterpolatorsFactory;
++ ptr ->Interpolators = NULL;
+ return TRUE;
+ }
+
+ // Set replacement functions
+- Interpolators = Plugin ->InterpolatorsFactory;
++ ptr ->Interpolators = Plugin ->InterpolatorsFactory;
+ return TRUE;
+ }
+
+
+ // Set the interpolation method
+-cmsBool _cmsSetInterpolationRoutine(cmsInterpParams* p)
++cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p)
+ {
+- // Invoke factory, possibly in the Plug-in
+- p ->Interpolation = Interpolators(p -> nInputs, p ->nOutputs, p ->dwFlags);
++ _cmsInterpPluginChunkType* ptr = (_cmsInterpPluginChunkType*) _cmsContextGetClientChunk(ContextID, InterpPlugin);
++
++ p ->Interpolation.Lerp16 = NULL;
++
++ // Invoke factory, possibly in the Plug-in
++ if (ptr ->Interpolators != NULL)
++ p ->Interpolation = ptr->Interpolators(p -> nInputs, p ->nOutputs, p ->dwFlags);
+
+ // If unsupported by the plug-in, go for the LittleCMS default.
+ // If happens only if an extern plug-in is being used
+@@ -97,6 +123,7 @@
+ if (p ->Interpolation.Lerp16 == NULL) {
+ return FALSE;
+ }
++
+ return TRUE;
+ }
+
+@@ -141,7 +168,7 @@
+ p ->opta[i] = p ->opta[i-1] * nSamples[InputChan-i];
+
+
+- if (!_cmsSetInterpolationRoutine(p)) {
++ if (!_cmsSetInterpolationRoutine(ContextID, p)) {
+ cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported interpolation (%d->%d channels)", InputChan, OutputChan);
+ _cmsFree(ContextID, p);
+ return NULL;
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c Wed Feb 04 12:14:43 2015 -0800
+@@ -229,15 +229,14 @@
+ if (ResData == NULL) return FALSE; // Housekeeping
+
+ // Check for available space. Clip.
+- if (iohandler ->UsedSpace + size > ResData->Size) {
+- size = ResData ->Size - iohandler ->UsedSpace;
++ if (ResData->Pointer + size > ResData->Size) {
++ size = ResData ->Size - ResData->Pointer;
+ }
+
+ if (size == 0) return TRUE; // Write zero bytes is ok, but does nothing
+
+ memmove(ResData ->Block + ResData ->Pointer, Ptr, size);
+ ResData ->Pointer += size;
+- iohandler->UsedSpace += size;
+
+ if (ResData ->Pointer > iohandler->UsedSpace)
+ iohandler->UsedSpace = ResData ->Pointer;
+@@ -371,7 +370,7 @@
+ static
+ cmsUInt32Number FileTell(cmsIOHANDLER* iohandler)
+ {
+- return ftell((FILE*)iohandler ->stream);
++ return (cmsUInt32Number) ftell((FILE*)iohandler ->stream);
+ }
+
+ // Writes data to stream, also keeps used space for further reference. Returns TRUE on success, FALSE on error
+@@ -414,7 +413,7 @@
+ cmsSignalError(ContextID, cmsERROR_FILE, "File '%s' not found", FileName);
+ return NULL;
+ }
+- iohandler -> ReportedSize = cmsfilelength(fm);
++ iohandler -> ReportedSize = (cmsUInt32Number) cmsfilelength(fm);
+ break;
+
+ case 'w':
+@@ -461,7 +460,7 @@
+ iohandler -> ContextID = ContextID;
+ iohandler -> stream = (void*) Stream;
+ iohandler -> UsedSpace = 0;
+- iohandler -> ReportedSize = cmsfilelength(Stream);
++ iohandler -> ReportedSize = (cmsUInt32Number) cmsfilelength(Stream);
+ iohandler -> PhysicalFile[0] = 0;
+
+ iohandler ->Read = FileRead;
+@@ -501,6 +500,9 @@
+ // Set creation date/time
+ memmove(&Icc ->Created, gmtime(&now), sizeof(Icc ->Created));
+
++ // Create a mutex if the user provided proper plugin. NULL otherwise
++ Icc ->UsrMutex = _cmsCreateMutex(ContextID);
++
+ // Return the handle
+ return (cmsHPROFILE) Icc;
+ }
+@@ -579,9 +581,39 @@
+ return n;
+ }
+
++// Deletes a tag entry
+
+-// Create a new tag entry
++static
++void _cmsDeleteTagByPos(_cmsICCPROFILE* Icc, int i)
++{
++ _cmsAssert(Icc != NULL);
++ _cmsAssert(i >= 0);
+
++
++ if (Icc -> TagPtrs[i] != NULL) {
++
++ // Free previous version
++ if (Icc ->TagSaveAsRaw[i]) {
++ _cmsFree(Icc ->ContextID, Icc ->TagPtrs[i]);
++ }
++ else {
++ cmsTagTypeHandler* TypeHandler = Icc ->TagTypeHandlers[i];
++
++ if (TypeHandler != NULL) {
++
++ cmsTagTypeHandler LocalTypeHandler = *TypeHandler;
++ LocalTypeHandler.ContextID = Icc ->ContextID; // As an additional parameter
++ LocalTypeHandler.ICCVersion = Icc ->Version;
++ LocalTypeHandler.FreePtr(&LocalTypeHandler, Icc -> TagPtrs[i]);
++ Icc ->TagPtrs[i] = NULL;
++ }
++ }
++
++ }
++}
++
++
++// Creates a new tag entry
+ static
+ cmsBool _cmsNewTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, int* NewPos)
+ {
+@@ -589,15 +621,15 @@
+
+ // Search for the tag
+ i = _cmsSearchTag(Icc, sig, FALSE);
++ if (i >= 0) {
+
+- // Now let's do it easy. If the tag has been already written, that's an error
+- if (i >= 0) {
+- cmsSignalError(Icc ->ContextID, cmsERROR_ALREADY_DEFINED, "Tag '%x' already exists", sig);
+- return FALSE;
++ // Already exists? delete it
++ _cmsDeleteTagByPos(Icc, i);
++ *NewPos = i;
+ }
+ else {
+
+- // New one
++ // No, make a new one
+
+ if (Icc -> TagCount >= MAX_TABLE_TAG) {
+ cmsSignalError(Icc ->ContextID, cmsERROR_RANGE, "Too many tags (%d)", MAX_TABLE_TAG);
+@@ -979,7 +1011,7 @@
+
+ // 4.2 -> 0x4200000
+
+- Icc -> Version = BaseToBase((cmsUInt32Number) floor(Version * 100.0), 10, 16) << 16;
++ Icc -> Version = BaseToBase((cmsUInt32Number) floor(Version * 100.0 + 0.5), 10, 16) << 16;
+ }
+
+ cmsFloat64Number CMSEXPORT cmsGetProfileVersion(cmsHPROFILE hProfile)
+@@ -1011,6 +1043,32 @@
+ return NULL;
+ }
+
++// Create profile from IOhandler
++cmsHPROFILE CMSEXPORT cmsOpenProfileFromIOhandler2THR(cmsContext ContextID, cmsIOHANDLER* io, cmsBool write)
++{
++ _cmsICCPROFILE* NewIcc;
++ cmsHPROFILE hEmpty = cmsCreateProfilePlaceholder(ContextID);
++
++ if (hEmpty == NULL) return NULL;
++
++ NewIcc = (_cmsICCPROFILE*) hEmpty;
++
++ NewIcc ->IOhandler = io;
++ if (write) {
++
++ NewIcc -> IsWrite = TRUE;
++ return hEmpty;
++ }
++
++ if (!_cmsReadHeader(NewIcc)) goto Error;
++ return hEmpty;
++
++Error:
++ cmsCloseProfile(hEmpty);
++ return NULL;
++}
++
++
+ // Create profile from disk file
+ cmsHPROFILE CMSEXPORT cmsOpenProfileFromFileTHR(cmsContext ContextID, const char *lpFileName, const char *sAccess)
+ {
+@@ -1202,7 +1260,7 @@
+ else {
+
+ // Search for support on this tag
+- TagDescriptor = _cmsGetTagDescriptor(Icc -> TagNames[i]);
++ TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, Icc -> TagNames[i]);
+ if (TagDescriptor == NULL) continue; // Unsupported, ignore it
+
+ if (TagDescriptor ->DecideType != NULL) {
+@@ -1214,7 +1272,7 @@
+ Type = TagDescriptor ->SupportedTypes[0];
+ }
+
+- TypeHandler = _cmsGetTagTypeHandler(Type);
++ TypeHandler = _cmsGetTagTypeHandler(Icc->ContextID, Type);
+
+ if (TypeHandler == NULL) {
+ cmsSignalError(Icc ->ContextID, cmsERROR_INTERNAL, "(Internal) no handler for tag %x", Icc -> TagNames[i]);
+@@ -1282,10 +1340,12 @@
+ {
+ _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
+ _cmsICCPROFILE Keep;
+- cmsIOHANDLER* PrevIO;
++ cmsIOHANDLER* PrevIO = NULL;
+ cmsUInt32Number UsedSpace;
+ cmsContext ContextID;
+
++ _cmsAssert(hProfile != NULL);
++
+ memmove(&Keep, Icc, sizeof(_cmsICCPROFILE));
+
+ ContextID = cmsGetProfileContextID(hProfile);
+@@ -1294,18 +1354,19 @@
+
+ // Pass #1 does compute offsets
+
+- if (!_cmsWriteHeader(Icc, 0)) return 0;
+- if (!SaveTags(Icc, &Keep)) return 0;
++ if (!_cmsWriteHeader(Icc, 0)) goto Error;
++ if (!SaveTags(Icc, &Keep)) goto Error;
+
+ UsedSpace = PrevIO ->UsedSpace;
+
+ // Pass #2 does save to iohandler
+
+ if (io != NULL) {
++
+ Icc ->IOhandler = io;
+- if (!SetLinks(Icc)) goto CleanUp;
+- if (!_cmsWriteHeader(Icc, UsedSpace)) goto CleanUp;
+- if (!SaveTags(Icc, &Keep)) goto CleanUp;
++ if (!SetLinks(Icc)) goto Error;
++ if (!_cmsWriteHeader(Icc, UsedSpace)) goto Error;
++ if (!SaveTags(Icc, &Keep)) goto Error;
+ }
+
+ memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
+@@ -1314,7 +1375,7 @@
+ return UsedSpace;
+
+
+-CleanUp:
++Error:
+ cmsCloseIOhandler(PrevIO);
+ memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
+ return 0;
+@@ -1362,11 +1423,13 @@
+ cmsIOHANDLER* io;
+ cmsContext ContextID = cmsGetProfileContextID(hProfile);
+
++ _cmsAssert(BytesNeeded != NULL);
++
+ // Should we just calculate the needed space?
+ if (MemPtr == NULL) {
+
+ *BytesNeeded = cmsSaveProfileToIOhandler(hProfile, NULL);
+- return (*BytesNeeded == 0 ? FALSE : TRUE);
++ return (*BytesNeeded == 0) ? FALSE : TRUE;
+ }
+
+ // That is a real write operation
+@@ -1419,6 +1482,8 @@
+ rc &= cmsCloseIOhandler(Icc->IOhandler);
+ }
+
++ _cmsDestroyMutex(Icc->ContextID, Icc->UsrMutex);
++
+ _cmsFree(Icc ->ContextID, Icc); // Free placeholder memory
+
+ return rc;
+@@ -1459,14 +1524,18 @@
+ cmsUInt32Number ElemCount;
+ int n;
+
++ if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return NULL;
++
+ n = _cmsSearchTag(Icc, sig, TRUE);
+- if (n < 0) return NULL; // Not found, return NULL
++ if (n < 0) goto Error; // Not found, return NULL
+
+
+ // If the element is already in memory, return the pointer
+ if (Icc -> TagPtrs[n]) {
+
+- if (Icc ->TagSaveAsRaw[n]) return NULL; // We don't support read raw tags as cooked
++ if (Icc ->TagSaveAsRaw[n]) goto Error; // We don't support read raw tags as cooked
++
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+ return Icc -> TagPtrs[n];
+ }
+
+@@ -1476,23 +1545,32 @@
+
+ // Seek to its location
+ if (!io -> Seek(io, Offset))
+- return NULL;
++ goto Error;
+
+ // Search for support on this tag
+- TagDescriptor = _cmsGetTagDescriptor(sig);
+- if (TagDescriptor == NULL) return NULL; // Unsupported.
++ TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
++ if (TagDescriptor == NULL) {
++
++ char String[5];
++
++ _cmsTagSignature2String(String, sig);
++
++ // An unknown element was found.
++ cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown tag type '%s' found.", String);
++ goto Error; // Unsupported.
++ }
+
+ // if supported, get type and check if in list
+ BaseType = _cmsReadTypeBase(io);
+- if (BaseType == 0) return NULL;
++ if (BaseType == 0) goto Error;
+
+- if (!IsTypeSupported(TagDescriptor, BaseType)) return NULL;
++ if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
+
+ TagSize -= 8; // Alredy read by the type base logic
+
+ // Get type handler
+- TypeHandler = _cmsGetTagTypeHandler(BaseType);
+- if (TypeHandler == NULL) return NULL;
++ TypeHandler = _cmsGetTagTypeHandler(Icc ->ContextID, BaseType);
++ if (TypeHandler == NULL) goto Error;
+ LocalTypeHandler = *TypeHandler;
+
+
+@@ -1511,7 +1589,7 @@
+
+ _cmsTagSignature2String(String, sig);
+ cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "Corrupted tag '%s'", String);
+- return NULL;
++ goto Error;
+ }
+
+ // This is a weird error that may be a symptom of something more serious, the number of
+@@ -1527,7 +1605,14 @@
+
+
+ // Return the data
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+ return Icc -> TagPtrs[n];
++
++
++ // Return error and unlock tha data
++Error:
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
++ return NULL;
+ }
+
+
+@@ -1561,49 +1646,26 @@
+ cmsFloat64Number Version;
+ char TypeString[5], SigString[5];
+
++ if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return FALSE;
+
++ // To delete tags.
+ if (data == NULL) {
+
++ // Delete the tag
+ i = _cmsSearchTag(Icc, sig, FALSE);
+- if (i >= 0)
++ if (i >= 0) {
++
++ // Use zero as a mark of deleted
++ _cmsDeleteTagByPos(Icc, i);
+ Icc ->TagNames[i] = (cmsTagSignature) 0;
+- // Unsupported by now, reserved for future ampliations (delete)
+- return FALSE;
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
++ return TRUE;
++ }
++ // Didn't find the tag
++ goto Error;
+ }
+
+- i = _cmsSearchTag(Icc, sig, FALSE);
+- if (i >=0) {
+-
+- if (Icc -> TagPtrs[i] != NULL) {
+-
+- // Already exists. Free previous version
+- if (Icc ->TagSaveAsRaw[i]) {
+- _cmsFree(Icc ->ContextID, Icc ->TagPtrs[i]);
+- }
+- else {
+- TypeHandler = Icc ->TagTypeHandlers[i];
+-
+- if (TypeHandler != NULL) {
+-
+- LocalTypeHandler = *TypeHandler;
+- LocalTypeHandler.ContextID = Icc ->ContextID; // As an additional parameter
+- LocalTypeHandler.ICCVersion = Icc ->Version;
+- LocalTypeHandler.FreePtr(&LocalTypeHandler, Icc -> TagPtrs[i]);
+- }
+- }
+- }
+- }
+- else {
+- // New one
+- i = Icc -> TagCount;
+-
+- if (i >= MAX_TABLE_TAG) {
+- cmsSignalError(Icc ->ContextID, cmsERROR_RANGE, "Too many tags (%d)", MAX_TABLE_TAG);
+- return FALSE;
+- }
+-
+- Icc -> TagCount++;
+- }
++ if (!_cmsNewTag(Icc, sig, &i)) goto Error;
+
+ // This is not raw
+ Icc ->TagSaveAsRaw[i] = FALSE;
+@@ -1612,10 +1674,10 @@
+ Icc ->TagLinked[i] = (cmsTagSignature) 0;
+
+ // Get information about the TAG.
+- TagDescriptor = _cmsGetTagDescriptor(sig);
++ TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
+ if (TagDescriptor == NULL){
+ cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported tag '%x'", sig);
+- return FALSE;
++ goto Error;
+ }
+
+
+@@ -1633,7 +1695,6 @@
+ }
+ else {
+
+-
+ Type = TagDescriptor ->SupportedTypes[0];
+ }
+
+@@ -1644,18 +1705,18 @@
+ _cmsTagSignature2String(SigString, sig);
+
+ cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported type '%s' for tag '%s'", TypeString, SigString);
+- return FALSE;
++ goto Error;
+ }
+
+ // Does we have a handler for this type?
+- TypeHandler = _cmsGetTagTypeHandler(Type);
++ TypeHandler = _cmsGetTagTypeHandler(Icc->ContextID, Type);
+ if (TypeHandler == NULL) {
+
+ _cmsTagSignature2String(TypeString, (cmsTagSignature) Type);
+ _cmsTagSignature2String(SigString, sig);
+
+ cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported type '%s' for tag '%s'", TypeString, SigString);
+- return FALSE; // Should never happen
++ goto Error; // Should never happen
+ }
+
+
+@@ -1668,7 +1729,7 @@
+ LocalTypeHandler = *TypeHandler;
+ LocalTypeHandler.ContextID = Icc ->ContextID;
+ LocalTypeHandler.ICCVersion = Icc ->Version;
+- Icc ->TagPtrs[i] = LocalTypeHandler.DupPtr(&LocalTypeHandler, data, TagDescriptor ->ElemCount);
++ Icc ->TagPtrs[i] = LocalTypeHandler.DupPtr(&LocalTypeHandler, data, TagDescriptor ->ElemCount);
+
+ if (Icc ->TagPtrs[i] == NULL) {
+
+@@ -1676,10 +1737,16 @@
+ _cmsTagSignature2String(SigString, sig);
+ cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "Malformed struct in type '%s' for tag '%s'", TypeString, SigString);
+
+- return FALSE;
++ goto Error;
+ }
+
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+ return TRUE;
++
++Error:
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
++ return FALSE;
++
+ }
+
+ // Read and write raw data. The only way those function would work and keep consistence with normal read and write
+@@ -1700,9 +1767,11 @@
+ cmsUInt32Number rc;
+ cmsUInt32Number Offset, TagSize;
+
++ if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0;
++
+ // Search for given tag in ICC profile directory
+ i = _cmsSearchTag(Icc, sig, TRUE);
+- if (i < 0) return 0; // Not found, return 0
++ if (i < 0) goto Error; // Not found,
+
+ // It is already read?
+ if (Icc -> TagPtrs[i] == NULL) {
+@@ -1717,12 +1786,14 @@
+ if (BufferSize < TagSize)
+ TagSize = BufferSize;
+
+- if (!Icc ->IOhandler ->Seek(Icc ->IOhandler, Offset)) return 0;
+- if (!Icc ->IOhandler ->Read(Icc ->IOhandler, data, 1, TagSize)) return 0;
++ if (!Icc ->IOhandler ->Seek(Icc ->IOhandler, Offset)) goto Error;
++ if (!Icc ->IOhandler ->Read(Icc ->IOhandler, data, 1, TagSize)) goto Error;
+
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+ return TagSize;
+ }
+
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+ return Icc ->TagSizes[i];
+ }
+
+@@ -1738,16 +1809,22 @@
+
+ memmove(data, Icc ->TagPtrs[i], TagSize);
+
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+ return TagSize;
+ }
+
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+ return Icc ->TagSizes[i];
+ }
+
+ // Already readed, or previously set by cmsWriteTag(). We need to serialize that
+ // data to raw in order to maintain consistency.
++
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+ Object = cmsReadTag(hProfile, sig);
+- if (Object == NULL) return 0;
++ if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0;
++
++ if (Object == NULL) goto Error;
+
+ // Now we need to serialize to a memory block: just use a memory iohandler
+
+@@ -1756,17 +1833,18 @@
+ } else{
+ MemIO = cmsOpenIOhandlerFromMem(cmsGetProfileContextID(hProfile), data, BufferSize, "w");
+ }
+- if (MemIO == NULL) return 0;
++ if (MemIO == NULL) goto Error;
+
+ // Obtain type handling for the tag
+ TypeHandler = Icc ->TagTypeHandlers[i];
+- TagDescriptor = _cmsGetTagDescriptor(sig);
++ TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
+ if (TagDescriptor == NULL) {
+ cmsCloseIOhandler(MemIO);
+- return 0;
++ goto Error;
+ }
+
+- // FIXME: No handling for TypeHandler == NULL here?
++ if (TypeHandler == NULL) goto Error;
++
+ // Serialize
+ LocalTypeHandler = *TypeHandler;
+ LocalTypeHandler.ContextID = Icc ->ContextID;
+@@ -1774,19 +1852,24 @@
+
+ if (!_cmsWriteTypeBase(MemIO, TypeHandler ->Signature)) {
+ cmsCloseIOhandler(MemIO);
+- return 0;
++ goto Error;
+ }
+
+ if (!LocalTypeHandler.WritePtr(&LocalTypeHandler, MemIO, Object, TagDescriptor ->ElemCount)) {
+ cmsCloseIOhandler(MemIO);
+- return 0;
++ goto Error;
+ }
+
+ // Get Size and close
+ rc = MemIO ->Tell(MemIO);
+ cmsCloseIOhandler(MemIO); // Ignore return code this time
+
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+ return rc;
++
++Error:
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
++ return 0;
+ }
+
+ // Similar to the anterior. This function allows to write directly to the ICC profile any data, without
+@@ -1798,7 +1881,12 @@
+ _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
+ int i;
+
+- if (!_cmsNewTag(Icc, sig, &i)) return FALSE;
++ if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0;
++
++ if (!_cmsNewTag(Icc, sig, &i)) {
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
++ return FALSE;
++ }
+
+ // Mark the tag as being written as RAW
+ Icc ->TagSaveAsRaw[i] = TRUE;
+@@ -1809,6 +1897,7 @@
+ Icc ->TagPtrs[i] = _cmsDupMem(Icc ->ContextID, data, Size);
+ Icc ->TagSizes[i] = Size;
+
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+ return TRUE;
+ }
+
+@@ -1818,7 +1907,12 @@
+ _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
+ int i;
+
+- if (!_cmsNewTag(Icc, sig, &i)) return FALSE;
++ if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return FALSE;
++
++ if (!_cmsNewTag(Icc, sig, &i)) {
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
++ return FALSE;
++ }
+
+ // Keep necessary information
+ Icc ->TagSaveAsRaw[i] = FALSE;
+@@ -1829,6 +1923,7 @@
+ Icc ->TagSizes[i] = 0;
+ Icc ->TagOffsets[i] = 0;
+
++ _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+ return TRUE;
+ }
+
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c Wed Feb 04 12:14:43 2015 -0800
+@@ -334,7 +334,8 @@
+
+
+ // Read and create a BRAND NEW MPE LUT from a given profile. All stuff dependent of version, etc
+-// is adjusted here in order to create a LUT that takes care of all those details
++// is adjusted here in order to create a LUT that takes care of all those details.
++// We add intent = -1 as a way to read matrix shaper always, no matter of other LUT
+ cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
+ {
+ cmsTagTypeSignature OriginalType;
+@@ -364,49 +365,54 @@
+ return Lut;
+ }
+
+- if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
++ // This is an attempt to reuse this funtion to retrieve the matrix-shaper as pipeline no
++ // matter other LUT are present and have precedence. Intent = -1 means just this.
++ if (Intent != -1) {
+
+- // Floating point LUT are always V4, but the encoding range is no
+- // longer 0..1.0, so we need to add an stage depending on the color space
+- return _cmsReadFloatInputTag(hProfile, tagFloat);
+- }
++ if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
+
+- // Revert to perceptual if no tag is found
+- if (!cmsIsTag(hProfile, tag16)) {
+- tag16 = Device2PCS16[0];
+- }
++ // Floating point LUT are always V4, but the encoding range is no
++ // longer 0..1.0, so we need to add an stage depending on the color space
++ return _cmsReadFloatInputTag(hProfile, tagFloat);
++ }
+
+- if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
++ // Revert to perceptual if no tag is found
++ if (!cmsIsTag(hProfile, tag16)) {
++ tag16 = Device2PCS16[0];
++ }
+
+- // Check profile version and LUT type. Do the necessary adjustments if needed
++ if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
+
+- // First read the tag
+- cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
+- if (Lut == NULL) return NULL;
++ // Check profile version and LUT type. Do the necessary adjustments if needed
+
+- // After reading it, we have now info about the original type
+- OriginalType = _cmsGetTagTrueType(hProfile, tag16);
++ // First read the tag
++ cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
++ if (Lut == NULL) return NULL;
+
+- // The profile owns the Lut, so we need to copy it
+- Lut = cmsPipelineDup(Lut);
++ // After reading it, we have now info about the original type
++ OriginalType = _cmsGetTagTrueType(hProfile, tag16);
+
+- // We need to adjust data only for Lab16 on output
+- if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData)
++ // The profile owns the Lut, so we need to copy it
++ Lut = cmsPipelineDup(Lut);
++
++ // We need to adjust data only for Lab16 on output
++ if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData)
++ return Lut;
++
++ // If the input is Lab, add also a conversion at the begin
++ if (cmsGetColorSpace(hProfile) == cmsSigLabData &&
++ !cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
++ goto Error;
++
++ // Add a matrix for conversion V2 to V4 Lab PCS
++ if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
++ goto Error;
++
+ return Lut;
+-
+- // If the input is Lab, add also a conversion at the begin
+- if (cmsGetColorSpace(hProfile) == cmsSigLabData &&
+- !cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
+- goto Error;
+-
+- // Add a matrix for conversion V2 to V4 Lab PCS
+- if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
+- goto Error;
+-
+- return Lut;
+ Error:
+- cmsPipelineFree(Lut);
+- return NULL;
++ cmsPipelineFree(Lut);
++ return NULL;
++ }
+ }
+
+ // Lut was not found, try to create a matrix-shaper
+@@ -551,7 +557,7 @@
+ _cmsStageCLutData* CLUT = (_cmsStageCLutData*) Stage ->Data;
+
+ CLUT ->Params->dwFlags |= CMS_LERP_FLAGS_TRILINEAR;
+- _cmsSetInterpolationRoutine(CLUT ->Params);
++ _cmsSetInterpolationRoutine(Lut->ContextID, CLUT ->Params);
+ }
+ }
+ }
+@@ -609,54 +615,58 @@
+ cmsTagSignature tagFloat = PCS2DeviceFloat[Intent];
+ cmsContext ContextID = cmsGetProfileContextID(hProfile);
+
+- if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
+
+- // Floating point LUT are always V4
+- return _cmsReadFloatOutputTag(hProfile, tagFloat);
+- }
++ if (Intent != -1) {
+
+- // Revert to perceptual if no tag is found
+- if (!cmsIsTag(hProfile, tag16)) {
+- tag16 = PCS2Device16[0];
+- }
++ if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
+
+- if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
++ // Floating point LUT are always V4
++ return _cmsReadFloatOutputTag(hProfile, tagFloat);
++ }
+
+- // Check profile version and LUT type. Do the necessary adjustments if needed
++ // Revert to perceptual if no tag is found
++ if (!cmsIsTag(hProfile, tag16)) {
++ tag16 = PCS2Device16[0];
++ }
+
+- // First read the tag
+- cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
+- if (Lut == NULL) return NULL;
++ if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
+
+- // After reading it, we have info about the original type
+- OriginalType = _cmsGetTagTrueType(hProfile, tag16);
++ // Check profile version and LUT type. Do the necessary adjustments if needed
+
+- // The profile owns the Lut, so we need to copy it
+- Lut = cmsPipelineDup(Lut);
+- if (Lut == NULL) return NULL;
++ // First read the tag
++ cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
++ if (Lut == NULL) return NULL;
+
+- // Now it is time for a controversial stuff. I found that for 3D LUTS using
+- // Lab used as indexer space, trilinear interpolation should be used
+- if (cmsGetPCS(hProfile) == cmsSigLabData)
+- ChangeInterpolationToTrilinear(Lut);
++ // After reading it, we have info about the original type
++ OriginalType = _cmsGetTagTrueType(hProfile, tag16);
+
+- // We need to adjust data only for Lab and Lut16 type
+- if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData)
+- return Lut;
++ // The profile owns the Lut, so we need to copy it
++ Lut = cmsPipelineDup(Lut);
++ if (Lut == NULL) return NULL;
+
+- // Add a matrix for conversion V4 to V2 Lab PCS
+- if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
+- goto Error;
++ // Now it is time for a controversial stuff. I found that for 3D LUTS using
++ // Lab used as indexer space, trilinear interpolation should be used
++ if (cmsGetPCS(hProfile) == cmsSigLabData)
++ ChangeInterpolationToTrilinear(Lut);
+
+- // If the output is Lab, add also a conversion at the end
+- if (cmsGetColorSpace(hProfile) == cmsSigLabData)
+- if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
++ // We need to adjust data only for Lab and Lut16 type
++ if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData)
++ return Lut;
++
++ // Add a matrix for conversion V4 to V2 Lab PCS
++ if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
+ goto Error;
+
+- return Lut;
++ // If the output is Lab, add also a conversion at the end
++ if (cmsGetColorSpace(hProfile) == cmsSigLabData)
++ if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
++ goto Error;
++
++ return Lut;
+ Error:
+- cmsPipelineFree(Lut);
+- return NULL;
++ cmsPipelineFree(Lut);
++ return NULL;
++ }
+ }
+
+ // Lut not found, try to create a matrix-shaper
+@@ -782,7 +792,7 @@
+
+ // Now it is time for a controversial stuff. I found that for 3D LUTS using
+ // Lab used as indexer space, trilinear interpolation should be used
+- if (cmsGetColorSpace(hProfile) == cmsSigLabData)
++ if (cmsGetPCS(hProfile) == cmsSigLabData)
+ ChangeInterpolationToTrilinear(Lut);
+
+ // After reading it, we have info about the original type
+@@ -793,12 +803,12 @@
+
+ // Here it is possible to get Lab on both sides
+
+- if (cmsGetPCS(hProfile) == cmsSigLabData) {
++ if (cmsGetColorSpace(hProfile) == cmsSigLabData) {
+ if(!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
+ goto Error2;
+ }
+
+- if (cmsGetColorSpace(hProfile) == cmsSigLabData) {
++ if (cmsGetPCS(hProfile) == cmsSigLabData) {
+ if(!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
+ goto Error2;
+ }
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsopt.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsopt.c Wed Feb 04 12:14:43 2015 -0800
+@@ -542,11 +542,13 @@
+
+ cmsToneCurve* InversePostLin = cmsReverseToneCurve(Curves[i]);
+ if (InversePostLin == NULL) {
+- WhiteOut[i] = 0;
+- continue;
++ WhiteOut[i] = WhitePointOut[i];
++
++ } else {
++
++ WhiteOut[i] = cmsEvalToneCurve16(InversePostLin, WhitePointOut[i]);
++ cmsFreeToneCurve(InversePostLin);
+ }
+- WhiteOut[i] = cmsEvalToneCurve16(InversePostLin, WhitePointOut[i]);
+- cmsFreeToneCurve(InversePostLin);
+ }
+ }
+ else {
+@@ -1666,44 +1668,102 @@
+ };
+
+ // The linked list head
+-static _cmsOptimizationCollection* OptimizationCollection = DefaultOptimization;
++_cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk = { NULL };
++
++
++// Duplicates the zone of memory used by the plug-in in the new context
++static
++void DupPluginOptimizationList(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ _cmsOptimizationPluginChunkType newHead = { NULL };
++ _cmsOptimizationCollection* entry;
++ _cmsOptimizationCollection* Anterior = NULL;
++ _cmsOptimizationPluginChunkType* head = (_cmsOptimizationPluginChunkType*) src->chunks[OptimizationPlugin];
++
++ _cmsAssert(ctx != NULL);
++ _cmsAssert(head != NULL);
++
++ // Walk the list copying all nodes
++ for (entry = head->OptimizationCollection;
++ entry != NULL;
++ entry = entry ->Next) {
++
++ _cmsOptimizationCollection *newEntry = ( _cmsOptimizationCollection *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsOptimizationCollection));
++
++ if (newEntry == NULL)
++ return;
++
++ // We want to keep the linked list order, so this is a little bit tricky
++ newEntry -> Next = NULL;
++ if (Anterior)
++ Anterior -> Next = newEntry;
++
++ Anterior = newEntry;
++
++ if (newHead.OptimizationCollection == NULL)
++ newHead.OptimizationCollection = newEntry;
++ }
++
++ ctx ->chunks[OptimizationPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsOptimizationPluginChunkType));
++}
++
++void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ if (src != NULL) {
++
++ // Copy all linked list
++ DupPluginOptimizationList(ctx, src);
++ }
++ else {
++ static _cmsOptimizationPluginChunkType OptimizationPluginChunkType = { NULL };
++ ctx ->chunks[OptimizationPlugin] = _cmsSubAllocDup(ctx ->MemPool, &OptimizationPluginChunkType, sizeof(_cmsOptimizationPluginChunkType));
++ }
++}
++
+
+ // Register new ways to optimize
+-cmsBool _cmsRegisterOptimizationPlugin(cmsContext id, cmsPluginBase* Data)
++cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Data)
+ {
+ cmsPluginOptimization* Plugin = (cmsPluginOptimization*) Data;
++ _cmsOptimizationPluginChunkType* ctx = ( _cmsOptimizationPluginChunkType*) _cmsContextGetClientChunk(ContextID, OptimizationPlugin);
+ _cmsOptimizationCollection* fl;
+
+ if (Data == NULL) {
+
+- OptimizationCollection = DefaultOptimization;
++ ctx->OptimizationCollection = NULL;
+ return TRUE;
+ }
+
+ // Optimizer callback is required
+ if (Plugin ->OptimizePtr == NULL) return FALSE;
+
+- fl = (_cmsOptimizationCollection*) _cmsPluginMalloc(id, sizeof(_cmsOptimizationCollection));
++ fl = (_cmsOptimizationCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsOptimizationCollection));
+ if (fl == NULL) return FALSE;
+
+ // Copy the parameters
+ fl ->OptimizePtr = Plugin ->OptimizePtr;
+
+ // Keep linked list
+- fl ->Next = OptimizationCollection;
+- OptimizationCollection = fl;
++ fl ->Next = ctx->OptimizationCollection;
++
++ // Set the head
++ ctx ->OptimizationCollection = fl;
+
+ // All is ok
+ return TRUE;
+ }
+
+ // The entry point for LUT optimization
+-cmsBool _cmsOptimizePipeline(cmsPipeline** PtrLut,
++cmsBool _cmsOptimizePipeline(cmsContext ContextID,
++ cmsPipeline** PtrLut,
+ int Intent,
+ cmsUInt32Number* InputFormat,
+ cmsUInt32Number* OutputFormat,
+ cmsUInt32Number* dwFlags)
+ {
++ _cmsOptimizationPluginChunkType* ctx = ( _cmsOptimizationPluginChunkType*) _cmsContextGetClientChunk(ContextID, OptimizationPlugin);
+ _cmsOptimizationCollection* Opts;
+ cmsBool AnySuccess = FALSE;
+
+@@ -1733,8 +1793,8 @@
+ if (*dwFlags & cmsFLAGS_NOOPTIMIZE)
+ return FALSE;
+
+- // Try built-in optimizations and plug-in
+- for (Opts = OptimizationCollection;
++ // Try plug-in optimizations
++ for (Opts = ctx->OptimizationCollection;
+ Opts != NULL;
+ Opts = Opts ->Next) {
+
+@@ -1745,6 +1805,17 @@
+ }
+ }
+
++ // Try built-in optimizations
++ for (Opts = DefaultOptimization;
++ Opts != NULL;
++ Opts = Opts ->Next) {
++
++ if (Opts ->OptimizePtr(PtrLut, Intent, InputFormat, OutputFormat, dwFlags)) {
++
++ return TRUE;
++ }
++ }
++
+ // Only simple optimizations succeeded
+ return AnySuccess;
+ }
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c Wed Feb 04 12:14:43 2015 -0800
+@@ -883,6 +883,42 @@
+ }
+ }
+
++// This is a conversion of XYZ float to 16 bits
++static
++cmsUInt8Number* UnrollXYZFloatTo16(register _cmsTRANSFORM* info,
++ register cmsUInt16Number wIn[],
++ register cmsUInt8Number* accum,
++ register cmsUInt32Number Stride)
++{
++ if (T_PLANAR(info -> InputFormat)) {
++
++ cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
++ cmsCIEXYZ XYZ;
++
++ XYZ.X = Pt[0];
++ XYZ.Y = Pt[Stride];
++ XYZ.Z = Pt[Stride*2];
++ cmsFloat2XYZEncoded(wIn, &XYZ);
++
++ return accum + sizeof(cmsFloat32Number);
++
++ }
++
++ else {
++ cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
++ cmsCIEXYZ XYZ;
++
++ XYZ.X = Pt[0];
++ XYZ.Y = Pt[1];
++ XYZ.Z = Pt[2];
++ cmsFloat2XYZEncoded(wIn, &XYZ);
++
++ accum += 3 * sizeof(cmsFloat32Number) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat32Number);
++
++ return accum;
++ }
++}
++
+ // Check if space is marked as ink
+ cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type)
+ {
+@@ -2334,6 +2370,39 @@
+ }
+
+ static
++cmsUInt8Number* PackXYZFloatFrom16(register _cmsTRANSFORM* Info,
++ register cmsUInt16Number wOut[],
++ register cmsUInt8Number* output,
++ register cmsUInt32Number Stride)
++{
++ if (T_PLANAR(Info -> OutputFormat)) {
++
++ cmsCIEXYZ XYZ;
++ cmsFloat32Number* Out = (cmsFloat32Number*) output;
++ cmsXYZEncoded2Float(&XYZ, wOut);
++
++ Out[0] = (cmsFloat32Number) XYZ.X;
++ Out[Stride] = (cmsFloat32Number) XYZ.Y;
++ Out[Stride*2] = (cmsFloat32Number) XYZ.Z;
++
++ return output + sizeof(cmsFloat32Number);
++
++ }
++ else {
++
++ cmsCIEXYZ XYZ;
++ cmsFloat32Number* Out = (cmsFloat32Number*) output;
++ cmsXYZEncoded2Float(&XYZ, wOut);
++
++ Out[0] = (cmsFloat32Number) XYZ.X;
++ Out[1] = (cmsFloat32Number) XYZ.Y;
++ Out[2] = (cmsFloat32Number) XYZ.Z;
++
++ return output + (3 * sizeof(cmsFloat32Number) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
++ }
++}
++
++static
+ cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+@@ -2893,6 +2962,7 @@
+ { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleTo16},
+ { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleTo16},
+ { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatTo16},
++ { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatTo16},
+ { TYPE_GRAY_DBL, 0, UnrollDouble1Chan},
+ { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
+ ANYSWAP|ANYEXTRA|ANYSPACE, UnrollDoubleTo16},
+@@ -3027,6 +3097,7 @@
+ { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFrom16},
+
+ { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFrom16},
++ { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFrom16},
+
+ { FLOAT_SH(1)|BYTES_SH(0), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
+ ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackDoubleFrom16},
+@@ -3182,40 +3253,98 @@
+
+ } cmsFormattersFactoryList;
+
+-static cmsFormattersFactoryList* FactoryList = NULL;
++_cmsFormattersPluginChunkType _cmsFormattersPluginChunk = { NULL };
++
++
++// Duplicates the zone of memory used by the plug-in in the new context
++static
++void DupFormatterFactoryList(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ _cmsFormattersPluginChunkType newHead = { NULL };
++ cmsFormattersFactoryList* entry;
++ cmsFormattersFactoryList* Anterior = NULL;
++ _cmsFormattersPluginChunkType* head = (_cmsFormattersPluginChunkType*) src->chunks[FormattersPlugin];
++
++ _cmsAssert(head != NULL);
++
++ // Walk the list copying all nodes
++ for (entry = head->FactoryList;
++ entry != NULL;
++ entry = entry ->Next) {
++
++ cmsFormattersFactoryList *newEntry = ( cmsFormattersFactoryList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(cmsFormattersFactoryList));
++
++ if (newEntry == NULL)
++ return;
++
++ // We want to keep the linked list order, so this is a little bit tricky
++ newEntry -> Next = NULL;
++ if (Anterior)
++ Anterior -> Next = newEntry;
++
++ Anterior = newEntry;
++
++ if (newHead.FactoryList == NULL)
++ newHead.FactoryList = newEntry;
++ }
++
++ ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsFormattersPluginChunkType));
++}
++
++// The interpolation plug-in memory chunk allocator/dup
++void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ _cmsAssert(ctx != NULL);
++
++ if (src != NULL) {
++
++ // Duplicate the LIST
++ DupFormatterFactoryList(ctx, src);
++ }
++ else {
++ static _cmsFormattersPluginChunkType FormattersPluginChunk = { NULL };
++ ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx ->MemPool, &FormattersPluginChunk, sizeof(_cmsFormattersPluginChunkType));
++ }
++}
++
+
+
+ // Formatters management
+-cmsBool _cmsRegisterFormattersPlugin(cmsContext id, cmsPluginBase* Data)
++cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Data)
+ {
++ _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
+ cmsPluginFormatters* Plugin = (cmsPluginFormatters*) Data;
+ cmsFormattersFactoryList* fl ;
+
+- // Reset
++ // Reset to built-in defaults
+ if (Data == NULL) {
+
+- FactoryList = NULL;
++ ctx ->FactoryList = NULL;
+ return TRUE;
+ }
+
+- fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(id, sizeof(cmsFormattersFactoryList));
++ fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(ContextID, sizeof(cmsFormattersFactoryList));
+ if (fl == NULL) return FALSE;
+
+ fl ->Factory = Plugin ->FormattersFactory;
+
+- fl ->Next = FactoryList;
+- FactoryList = fl;
++ fl ->Next = ctx -> FactoryList;
++ ctx ->FactoryList = fl;
+
+ return TRUE;
+ }
+
+-cmsFormatter _cmsGetFormatter(cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
++cmsFormatter _cmsGetFormatter(cmsContext ContextID,
++ cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
+ cmsFormatterDirection Dir,
+ cmsUInt32Number dwFlags)
+ {
++ _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
+ cmsFormattersFactoryList* f;
+
+- for (f = FactoryList; f != NULL; f = f ->Next) {
++ for (f =ctx->FactoryList; f != NULL; f = f ->Next) {
+
+ cmsFormatter fn = f ->Factory(Type, Dir, dwFlags);
+ if (fn.Fmt16 != NULL) return fn;
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsplugin.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsplugin.c Wed Feb 04 12:14:43 2015 -0800
+@@ -544,22 +544,31 @@
+
+ // Plugin memory management -------------------------------------------------------------------------------------------------
+
+-static _cmsSubAllocator* PluginPool = NULL;
++// Specialized malloc for plug-ins, that is freed upon exit.
++void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size)
++{
++ struct _cmsContext_struct* ctx = _cmsGetContext(ContextID);
+
+-// Specialized malloc for plug-ins, that is freed upon exit.
+-void* _cmsPluginMalloc(cmsContext id, cmsUInt32Number size)
+-{
+- if (PluginPool == NULL)
+- PluginPool = _cmsCreateSubAlloc(id, 4*1024);
++ if (ctx ->MemPool == NULL) {
+
+- return _cmsSubAlloc(PluginPool, size);
++ if (ContextID == NULL) {
++
++ ctx->MemPool = _cmsCreateSubAlloc(0, 2*1024);
++ }
++ else {
++ cmsSignalError(ContextID, cmsERROR_CORRUPTION_DETECTED, "NULL memory pool on context");
++ return NULL;
++ }
++ }
++
++ return _cmsSubAlloc(ctx->MemPool, size);
+ }
+
+
+ // Main plug-in dispatcher
+ cmsBool CMSEXPORT cmsPlugin(void* Plug_in)
+ {
+- return cmsPluginTHR(NULL, Plug_in);
++ return cmsPluginTHR(NULL, Plug_in);
+ }
+
+ cmsBool CMSEXPORT cmsPluginTHR(cmsContext id, void* Plug_in)
+@@ -571,12 +580,12 @@
+ Plugin = Plugin -> Next) {
+
+ if (Plugin -> Magic != cmsPluginMagicNumber) {
+- cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin");
++ cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin");
+ return FALSE;
+ }
+
+ if (Plugin ->ExpectedVersion > LCMS_VERSION) {
+- cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "plugin needs Little CMS %d, current version is %d",
++ cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "plugin needs Little CMS %d, current version is %d",
+ Plugin ->ExpectedVersion, LCMS_VERSION);
+ return FALSE;
+ }
+@@ -584,11 +593,11 @@
+ switch (Plugin -> Type) {
+
+ case cmsPluginMemHandlerSig:
+- if (!_cmsRegisterMemHandlerPlugin(Plugin)) return FALSE;
++ if (!_cmsRegisterMemHandlerPlugin(id, Plugin)) return FALSE;
+ break;
+
+ case cmsPluginInterpolationSig:
+- if (!_cmsRegisterInterpPlugin(Plugin)) return FALSE;
++ if (!_cmsRegisterInterpPlugin(id, Plugin)) return FALSE;
+ break;
+
+ case cmsPluginTagTypeSig:
+@@ -623,8 +632,12 @@
+ if (!_cmsRegisterTransformPlugin(id, Plugin)) return FALSE;
+ break;
+
++ case cmsPluginMutexSig:
++ if (!_cmsRegisterMutexPlugin(id, Plugin)) return FALSE;
++ break;
++
+ default:
+- cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
++ cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
+ return FALSE;
+ }
+ }
+@@ -637,19 +650,337 @@
+ // Revert all plug-ins to default
+ void CMSEXPORT cmsUnregisterPlugins(void)
+ {
+- _cmsRegisterMemHandlerPlugin(NULL);
+- _cmsRegisterInterpPlugin(NULL);
+- _cmsRegisterTagTypePlugin(NULL, NULL);
+- _cmsRegisterTagPlugin(NULL, NULL);
+- _cmsRegisterFormattersPlugin(NULL, NULL);
+- _cmsRegisterRenderingIntentPlugin(NULL, NULL);
+- _cmsRegisterParametricCurvesPlugin(NULL, NULL);
+- _cmsRegisterMultiProcessElementPlugin(NULL, NULL);
+- _cmsRegisterOptimizationPlugin(NULL, NULL);
+- _cmsRegisterTransformPlugin(NULL, NULL);
++ cmsUnregisterPluginsTHR(NULL);
++}
+
+- if (PluginPool != NULL)
+- _cmsSubAllocDestroy(PluginPool);
+
+- PluginPool = NULL;
++// The Global storage for system context. This is the one and only global variable
++// pointers structure. All global vars are referenced here.
++static struct _cmsContext_struct globalContext = {
++
++ NULL, // Not in the linked list
++ NULL, // No suballocator
++ {
++ NULL, // UserPtr,
++ &_cmsLogErrorChunk, // Logger,
++ &_cmsAlarmCodesChunk, // AlarmCodes,
++ &_cmsAdaptationStateChunk, // AdaptationState,
++ &_cmsMemPluginChunk, // MemPlugin,
++ &_cmsInterpPluginChunk, // InterpPlugin,
++ &_cmsCurvesPluginChunk, // CurvesPlugin,
++ &_cmsFormattersPluginChunk, // FormattersPlugin,
++ &_cmsTagTypePluginChunk, // TagTypePlugin,
++ &_cmsTagPluginChunk, // TagPlugin,
++ &_cmsIntentsPluginChunk, // IntentPlugin,
++ &_cmsMPETypePluginChunk, // MPEPlugin,
++ &_cmsOptimizationPluginChunk, // OptimizationPlugin,
++ &_cmsTransformPluginChunk, // TransformPlugin,
++ &_cmsMutexPluginChunk // MutexPlugin
++ },
++
++ { NULL, NULL, NULL, NULL, NULL, NULL } // The default memory allocator is not used for context 0
++};
++
++
++// The context pool (linked list head)
++static _cmsMutex _cmsContextPoolHeadMutex = CMS_MUTEX_INITIALIZER;
++static struct _cmsContext_struct* _cmsContextPoolHead = NULL;
++
++// Internal, get associated pointer, with guessing. Never returns NULL.
++struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID)
++{
++ struct _cmsContext_struct* id = (struct _cmsContext_struct*) ContextID;
++ struct _cmsContext_struct* ctx;
++
++
++ // On 0, use global settings
++ if (id == NULL)
++ return &globalContext;
++
++ // Search
++ for (ctx = _cmsContextPoolHead;
++ ctx != NULL;
++ ctx = ctx ->Next) {
++
++ // Found it?
++ if (id == ctx)
++ return ctx; // New-style context,
++ }
++
++ return &globalContext;
+ }
++
++
++// Internal: get the memory area associanted with each context client
++// Returns the block assigned to the specific zone.
++void* _cmsContextGetClientChunk(cmsContext ContextID, _cmsMemoryClient mc)
++{
++ struct _cmsContext_struct* ctx;
++ void *ptr;
++
++ if (mc < 0 || mc >= MemoryClientMax) {
++ cmsSignalError(ContextID, cmsERROR_RANGE, "Bad context client");
++ return NULL;
++ }
++
++ ctx = _cmsGetContext(ContextID);
++ ptr = ctx ->chunks[mc];
++
++ if (ptr != NULL)
++ return ptr;
++
++ // A null ptr means no special settings for that context, and this
++ // reverts to Context0 globals
++ return globalContext.chunks[mc];
++}
++
++
++// This function returns the given context its default pristine state,
++// as no plug-ins were declared. There is no way to unregister a single
++// plug-in, as a single call to cmsPluginTHR() function may register
++// many different plug-ins simultaneously, then there is no way to
++// identify which plug-in to unregister.
++void CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID)
++{
++ _cmsRegisterMemHandlerPlugin(ContextID, NULL);
++ _cmsRegisterInterpPlugin(ContextID, NULL);
++ _cmsRegisterTagTypePlugin(ContextID, NULL);
++ _cmsRegisterTagPlugin(ContextID, NULL);
++ _cmsRegisterFormattersPlugin(ContextID, NULL);
++ _cmsRegisterRenderingIntentPlugin(ContextID, NULL);
++ _cmsRegisterParametricCurvesPlugin(ContextID, NULL);
++ _cmsRegisterMultiProcessElementPlugin(ContextID, NULL);
++ _cmsRegisterOptimizationPlugin(ContextID, NULL);
++ _cmsRegisterTransformPlugin(ContextID, NULL);
++ _cmsRegisterMutexPlugin(ContextID, NULL);
++}
++
++
++// Returns the memory manager plug-in, if any, from the Plug-in bundle
++static
++cmsPluginMemHandler* _cmsFindMemoryPlugin(void* PluginBundle)
++{
++ cmsPluginBase* Plugin;
++
++ for (Plugin = (cmsPluginBase*) PluginBundle;
++ Plugin != NULL;
++ Plugin = Plugin -> Next) {
++
++ if (Plugin -> Magic == cmsPluginMagicNumber &&
++ Plugin -> ExpectedVersion <= LCMS_VERSION &&
++ Plugin -> Type == cmsPluginMemHandlerSig) {
++
++ // Found!
++ return (cmsPluginMemHandler*) Plugin;
++ }
++ }
++
++ // Nope, revert to defaults
++ return NULL;
++}
++
++
++// Creates a new context with optional associated plug-ins. Caller may also specify an optional pointer to user-defined
++// data that will be forwarded to plug-ins and logger.
++cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData)
++{
++ struct _cmsContext_struct* ctx;
++ struct _cmsContext_struct fakeContext;
++
++ _cmsInstallAllocFunctions(_cmsFindMemoryPlugin(Plugin), &fakeContext.DefaultMemoryManager);
++
++ fakeContext.chunks[UserPtr] = UserData;
++ fakeContext.chunks[MemPlugin] = &fakeContext.DefaultMemoryManager;
++
++ // Create the context structure.
++ ctx = (struct _cmsContext_struct*) _cmsMalloc(&fakeContext, sizeof(struct _cmsContext_struct));
++ if (ctx == NULL)
++ return NULL; // Something very wrong happened!
++
++ // Init the structure and the memory manager
++ memset(ctx, 0, sizeof(struct _cmsContext_struct));
++
++ // Keep memory manager
++ memcpy(&ctx->DefaultMemoryManager, &fakeContext.DefaultMemoryManager, sizeof(_cmsMemPluginChunk));
++
++ // Maintain the linked list (with proper locking)
++ _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
++ ctx ->Next = _cmsContextPoolHead;
++ _cmsContextPoolHead = ctx;
++ _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
++
++ ctx ->chunks[UserPtr] = UserData;
++ ctx ->chunks[MemPlugin] = &ctx->DefaultMemoryManager;
++
++ // Now we can allocate the pool by using default memory manager
++ ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*)); // default size about 32 pointers
++ if (ctx ->MemPool == NULL) {
++
++ cmsDeleteContext(ctx);
++ return NULL;
++ }
++
++ _cmsAllocLogErrorChunk(ctx, NULL);
++ _cmsAllocAlarmCodesChunk(ctx, NULL);
++ _cmsAllocAdaptationStateChunk(ctx, NULL);
++ _cmsAllocMemPluginChunk(ctx, NULL);
++ _cmsAllocInterpPluginChunk(ctx, NULL);
++ _cmsAllocCurvesPluginChunk(ctx, NULL);
++ _cmsAllocFormattersPluginChunk(ctx, NULL);
++ _cmsAllocTagTypePluginChunk(ctx, NULL);
++ _cmsAllocMPETypePluginChunk(ctx, NULL);
++ _cmsAllocTagPluginChunk(ctx, NULL);
++ _cmsAllocIntentsPluginChunk(ctx, NULL);
++ _cmsAllocOptimizationPluginChunk(ctx, NULL);
++ _cmsAllocTransformPluginChunk(ctx, NULL);
++ _cmsAllocMutexPluginChunk(ctx, NULL);
++
++ // Setup the plug-ins
++ if (!cmsPluginTHR(ctx, Plugin)) {
++
++ cmsDeleteContext(ctx);
++ return NULL;
++ }
++
++ return (cmsContext) ctx;
++}
++
++// Duplicates a context with all associated plug-ins.
++// Caller may specify an optional pointer to user-defined
++// data that will be forwarded to plug-ins and logger.
++cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData)
++{
++ int i;
++ struct _cmsContext_struct* ctx;
++ const struct _cmsContext_struct* src = _cmsGetContext(ContextID);
++
++ void* userData = (NewUserData != NULL) ? NewUserData : src -> chunks[UserPtr];
++
++
++ ctx = (struct _cmsContext_struct*) _cmsMalloc(ContextID, sizeof(struct _cmsContext_struct));
++ if (ctx == NULL)
++ return NULL; // Something very wrong happened
++
++ // Setup default memory allocators
++ memcpy(&ctx->DefaultMemoryManager, &src->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));
++
++ // Maintain the linked list
++ _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
++ ctx ->Next = _cmsContextPoolHead;
++ _cmsContextPoolHead = ctx;
++ _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
++
++ ctx ->chunks[UserPtr] = userData;
++ ctx ->chunks[MemPlugin] = &ctx->DefaultMemoryManager;
++
++ ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*));
++ if (ctx ->MemPool == NULL) {
++
++ cmsDeleteContext(ctx);
++ return NULL;
++ }
++
++ // Allocate all required chunks.
++ _cmsAllocLogErrorChunk(ctx, src);
++ _cmsAllocAlarmCodesChunk(ctx, src);
++ _cmsAllocAdaptationStateChunk(ctx, src);
++ _cmsAllocMemPluginChunk(ctx, src);
++ _cmsAllocInterpPluginChunk(ctx, src);
++ _cmsAllocCurvesPluginChunk(ctx, src);
++ _cmsAllocFormattersPluginChunk(ctx, src);
++ _cmsAllocTagTypePluginChunk(ctx, src);
++ _cmsAllocMPETypePluginChunk(ctx, src);
++ _cmsAllocTagPluginChunk(ctx, src);
++ _cmsAllocIntentsPluginChunk(ctx, src);
++ _cmsAllocOptimizationPluginChunk(ctx, src);
++ _cmsAllocTransformPluginChunk(ctx, src);
++ _cmsAllocMutexPluginChunk(ctx, src);
++
++ // Make sure no one failed
++ for (i=Logger; i < MemoryClientMax; i++) {
++
++ if (src ->chunks[i] == NULL) {
++ cmsDeleteContext((cmsContext) ctx);
++ return NULL;
++ }
++ }
++
++ return (cmsContext) ctx;
++}
++
++
++
++static
++struct _cmsContext_struct* FindPrev(struct _cmsContext_struct* id)
++{
++ struct _cmsContext_struct* prev;
++
++ // Search for previous
++ for (prev = _cmsContextPoolHead;
++ prev != NULL;
++ prev = prev ->Next)
++ {
++ if (prev ->Next == id)
++ return prev;
++ }
++
++ return NULL; // List is empty or only one element!
++}
++
++// Frees any resources associated with the given context,
++// and destroys the context placeholder.
++// The ContextID can no longer be used in any THR operation.
++void CMSEXPORT cmsDeleteContext(cmsContext ContextID)
++{
++ if (ContextID != NULL) {
++
++ struct _cmsContext_struct* ctx = (struct _cmsContext_struct*) ContextID;
++ struct _cmsContext_struct fakeContext;
++ struct _cmsContext_struct* prev;
++
++ memcpy(&fakeContext.DefaultMemoryManager, &ctx->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));
++
++ fakeContext.chunks[UserPtr] = ctx ->chunks[UserPtr];
++ fakeContext.chunks[MemPlugin] = &fakeContext.DefaultMemoryManager;
++
++ // Get rid of plugins
++ cmsUnregisterPluginsTHR(ContextID);
++
++ // Since all memory is allocated in the private pool, all what we need to do is destroy the pool
++ if (ctx -> MemPool != NULL)
++ _cmsSubAllocDestroy(ctx ->MemPool);
++ ctx -> MemPool = NULL;
++
++ // Maintain list
++ _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
++ if (_cmsContextPoolHead == ctx) {
++
++ _cmsContextPoolHead = ctx->Next;
++ }
++ else {
++
++ // Search for previous
++ for (prev = _cmsContextPoolHead;
++ prev != NULL;
++ prev = prev ->Next)
++ {
++ if (prev -> Next == ctx) {
++ prev -> Next = ctx ->Next;
++ break;
++ }
++ }
++ }
++ _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
++
++ // free the memory block itself
++ _cmsFree(&fakeContext, ctx);
++ }
++}
++
++// Returns the user data associated to the given ContextID, or NULL if no user data was attached on context creation
++void* CMSEXPORT cmsGetContextUserData(cmsContext ContextID)
++{
++ return _cmsContextGetClientChunk(ContextID, UserPtr);
++}
++
++
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c Wed Feb 04 12:14:43 2015 -0800
+@@ -942,7 +942,7 @@
+ if (DeviceLink == NULL) return 0;
+
+ dwFlags |= cmsFLAGS_FORCE_CLUT;
+- _cmsOptimizePipeline(&DeviceLink, Intent, &InputFormat, &OutFrm, &dwFlags);
++ _cmsOptimizePipeline(m->ContextID, &DeviceLink, Intent, &InputFormat, &OutFrm, &dwFlags);
+
+ rc = EmitCIEBasedDEF(m, DeviceLink, Intent, &BlackPointAdaptedToD50);
+ cmsPipelineFree(DeviceLink);
+@@ -1359,7 +1359,7 @@
+
+ // We need a CLUT
+ dwFlags |= cmsFLAGS_FORCE_CLUT;
+- _cmsOptimizePipeline(&DeviceLink, RelativeEncodingIntent, &InFrm, &OutputFormat, &dwFlags);
++ _cmsOptimizePipeline(m->ContextID, &DeviceLink, RelativeEncodingIntent, &InFrm, &OutputFormat, &dwFlags);
+
+ _cmsIOPrintf(m, "<<\n");
+ _cmsIOPrintf(m, "/ColorRenderingType 1\n");
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmstypes.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmstypes.c Wed Feb 04 12:14:43 2015 -0800
+@@ -30,7 +30,7 @@
+ //---------------------------------------------------------------------------------
+ //
+ // Little Color Management System
+-// Copyright (c) 1998-2011 Marti Maria Saguer
++// Copyright (c) 1998-2014 Marti Maria Saguer
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining
+ // a copy of this software and associated documentation files (the "Software"),
+@@ -61,7 +61,7 @@
+ // are no profiles holding them. The programmer can also extend this list by defining his own types
+ // by using the appropiate plug-in. There are three types of plug ins regarding that. First type
+ // allows to define new tags using any existing type. Next plug-in type allows to define new types
+-// and the third one is very specific: allows to extend the number of elements in the multiprofile
++// and the third one is very specific: allows to extend the number of elements in the multiprocessing
+ // elements special type.
+ //--------------------------------------------------------------------------------------------------
+
+@@ -89,54 +89,49 @@
+ // Helper macro to define a MPE handler. Callbacks do have a fixed naming convention
+ #define TYPE_MPE_HANDLER(t, x) { (t), READ_FN(x), WRITE_FN(x), GenericMPEdup, GenericMPEfree, NULL, 0 }
+
+-// Register a new type handler. This routine is shared between normal types and MPE
++// Register a new type handler. This routine is shared between normal types and MPE. LinkedList points to the optional list head
+ static
+-cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsTagTypeLinkedList* LinkedList, cmsUInt32Number DefaultListCount)
++cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsMemoryClient pos)
+ {
+ cmsPluginTagType* Plugin = (cmsPluginTagType*) Data;
+- _cmsTagTypeLinkedList *pt, *Anterior = NULL;
++ _cmsTagTypePluginChunkType* ctx = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(id, pos);
++ _cmsTagTypeLinkedList *pt;
+
+ // Calling the function with NULL as plug-in would unregister the plug in.
+ if (Data == NULL) {
+
+- LinkedList[DefaultListCount-1].Next = NULL;
++ // There is no need to set free the memory, as pool is destroyed as a whole.
++ ctx ->TagTypes = NULL;
+ return TRUE;
+ }
+
+- pt = Anterior = LinkedList;
+- while (pt != NULL) {
+-
+- if (Plugin->Handler.Signature == pt -> Handler.Signature) {
+- pt ->Handler = Plugin ->Handler; // Replace old behaviour.
+- // Note that since no memory is allocated, unregister does not
+- // reset this action.
+- return TRUE;
+- }
+-
+- Anterior = pt;
+- pt = pt ->Next;
+- }
+-
+- // Registering happens in plug-in memory pool
++ // Registering happens in plug-in memory pool.
+ pt = (_cmsTagTypeLinkedList*) _cmsPluginMalloc(id, sizeof(_cmsTagTypeLinkedList));
+ if (pt == NULL) return FALSE;
+
+ pt ->Handler = Plugin ->Handler;
+- pt ->Next = NULL;
+-
+- if (Anterior)
+- Anterior -> Next = pt;
++ pt ->Next = ctx ->TagTypes;
++
++ ctx ->TagTypes = pt;
+
+ return TRUE;
+ }
+
+-// Return handler for a given type or NULL if not found. Shared between normal types and MPE
++// Return handler for a given type or NULL if not found. Shared between normal types and MPE. It first tries the additons
++// made by plug-ins and then the built-in defaults.
+ static
+-cmsTagTypeHandler* GetHandler(cmsTagTypeSignature sig, _cmsTagTypeLinkedList* LinkedList)
++cmsTagTypeHandler* GetHandler(cmsTagTypeSignature sig, _cmsTagTypeLinkedList* PluginLinkedList, _cmsTagTypeLinkedList* DefaultLinkedList)
+ {
+ _cmsTagTypeLinkedList* pt;
+
+- for (pt = LinkedList;
++ for (pt = PluginLinkedList;
++ pt != NULL;
++ pt = pt ->Next) {
++
++ if (sig == pt -> Handler.Signature) return &pt ->Handler;
++ }
++
++ for (pt = DefaultLinkedList;
+ pt != NULL;
+ pt = pt ->Next) {
+
+@@ -163,6 +158,7 @@
+ return TRUE;
+ }
+
++// Auxiliar to read an array of wchar_t
+ static
+ cmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array)
+ {
+@@ -777,6 +773,8 @@
+
+ // Create memory
+ Text = (char*) _cmsMalloc(self ->ContextID, size);
++ if (Text == NULL) return FALSE;
++
+ cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text, size);
+
+ // Write it, including separator
+@@ -1783,7 +1781,6 @@
+ if (!_cmsReadUInt8Number(io, NULL)) goto Error;
+
+ // Do some checking
+-
+ if (InputChannels > cmsMAXCHANNELS) goto Error;
+ if (OutputChannels > cmsMAXCHANNELS) goto Error;
+
+@@ -1824,9 +1821,16 @@
+ if (T == NULL) goto Error;
+
+ Temp = (cmsUInt8Number*) _cmsMalloc(self ->ContextID, nTabSize);
+- if (Temp == NULL) goto Error;
+-
+- if (io ->Read(io, Temp, nTabSize, 1) != 1) goto Error;
++ if (Temp == NULL) {
++ _cmsFree(self ->ContextID, T);
++ goto Error;
++ }
++
++ if (io ->Read(io, Temp, nTabSize, 1) != 1) {
++ _cmsFree(self ->ContextID, T);
++ _cmsFree(self ->ContextID, Temp);
++ goto Error;
++ }
+
+ for (i = 0; i < nTabSize; i++) {
+
+@@ -2371,27 +2375,30 @@
+ // Precision can be 1 or 2 bytes
+ if (Precision == 1) {
+
+- cmsUInt8Number v;
++ cmsUInt8Number v;
+
+ for (i=0; i < Data ->nEntries; i++) {
+
+- if (io ->Read(io, &v, sizeof(cmsUInt8Number), 1) != 1) return NULL;
+- Data ->Tab.T[i] = FROM_8_TO_16(v);
++ if (io ->Read(io, &v, sizeof(cmsUInt8Number), 1) != 1) return NULL;
++ Data ->Tab.T[i] = FROM_8_TO_16(v);
+ }
+
+ }
+ else
+ if (Precision == 2) {
+
+- if (!_cmsReadUInt16Array(io, Data->nEntries, Data ->Tab.T)) return NULL;
+- }
+- else {
+- cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown precision of '%d'", Precision);
+- return NULL;
+- }
+-
+-
+- return CLUT;
++ if (!_cmsReadUInt16Array(io, Data->nEntries, Data ->Tab.T)) {
++ cmsStageFree(CLUT);
++ return NULL;
++ }
++ }
++ else {
++ cmsStageFree(CLUT);
++ cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown precision of '%d'", Precision);
++ return NULL;
++ }
++
++ return CLUT;
+ }
+
+ static
+@@ -4374,7 +4381,7 @@
+ {TYPE_MPE_HANDLER((cmsTagTypeSignature) cmsSigCLutElemType, MPEclut), NULL },
+ };
+
+-#define DEFAULT_MPE_TYPE_COUNT (sizeof(SupportedMPEtypes) / sizeof(_cmsTagTypeLinkedList))
++_cmsTagTypePluginChunkType _cmsMPETypePluginChunk = { NULL };
+
+ static
+ cmsBool ReadMPEElem(struct _cms_typehandler_struct* self,
+@@ -4387,6 +4394,8 @@
+ cmsTagTypeHandler* TypeHandler;
+ cmsUInt32Number nItems;
+ cmsPipeline *NewLUT = (cmsPipeline *) Cargo;
++ _cmsTagTypePluginChunkType* MPETypePluginChunk = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(self->ContextID, MPEPlugin);
++
+
+ // Take signature and channels for each element.
+ if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) return FALSE;
+@@ -4395,7 +4404,7 @@
+ if (!_cmsReadUInt32Number(io, NULL)) return FALSE;
+
+ // Read diverse MPE types
+- TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, SupportedMPEtypes);
++ TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, MPETypePluginChunk ->TagTypes, SupportedMPEtypes);
+ if (TypeHandler == NULL) {
+
+ char String[5];
+@@ -4472,6 +4481,7 @@
+ cmsPipeline* Lut = (cmsPipeline*) Ptr;
+ cmsStage* Elem = Lut ->Elements;
+ cmsTagTypeHandler* TypeHandler;
++ _cmsTagTypePluginChunkType* MPETypePluginChunk = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(self->ContextID, MPEPlugin);
+
+ BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
+
+@@ -4505,7 +4515,7 @@
+
+ ElementSig = Elem ->Type;
+
+- TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, SupportedMPEtypes);
++ TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, MPETypePluginChunk->TagTypes, SupportedMPEtypes);
+ if (TypeHandler == NULL) {
+
+ char String[5];
+@@ -5125,7 +5135,7 @@
+ }
+ else {
+
+- rc = cmsDictAddEntry(hDict, NameWCS, ValueWCS, DisplayNameMLU, DisplayValueMLU);
++ rc = cmsDictAddEntry(hDict, NameWCS, ValueWCS, DisplayNameMLU, DisplayValueMLU);
+ }
+
+ if (NameWCS != NULL) _cmsFree(self ->ContextID, NameWCS);
+@@ -5282,24 +5292,95 @@
+ {TYPE_HANDLER(cmsSigVcgtType, vcgt), NULL }
+ };
+
+-#define DEFAULT_TAG_TYPE_COUNT (sizeof(SupportedTagTypes) / sizeof(_cmsTagTypeLinkedList))
++
++_cmsTagTypePluginChunkType _cmsTagTypePluginChunk = { NULL };
++
++
++
++// Duplicates the zone of memory used by the plug-in in the new context
++static
++void DupTagTypeList(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src,
++ int loc)
++{
++ _cmsTagTypePluginChunkType newHead = { NULL };
++ _cmsTagTypeLinkedList* entry;
++ _cmsTagTypeLinkedList* Anterior = NULL;
++ _cmsTagTypePluginChunkType* head = (_cmsTagTypePluginChunkType*) src->chunks[loc];
++
++ // Walk the list copying all nodes
++ for (entry = head->TagTypes;
++ entry != NULL;
++ entry = entry ->Next) {
++
++ _cmsTagTypeLinkedList *newEntry = ( _cmsTagTypeLinkedList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTagTypeLinkedList));
++
++ if (newEntry == NULL)
++ return;
++
++ // We want to keep the linked list order, so this is a little bit tricky
++ newEntry -> Next = NULL;
++ if (Anterior)
++ Anterior -> Next = newEntry;
++
++ Anterior = newEntry;
++
++ if (newHead.TagTypes == NULL)
++ newHead.TagTypes = newEntry;
++ }
++
++ ctx ->chunks[loc] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTagTypePluginChunkType));
++}
++
++
++void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ if (src != NULL) {
++
++ // Duplicate the LIST
++ DupTagTypeList(ctx, src, TagTypePlugin);
++ }
++ else {
++ static _cmsTagTypePluginChunkType TagTypePluginChunk = { NULL };
++ ctx ->chunks[TagTypePlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagTypePluginChunk, sizeof(_cmsTagTypePluginChunkType));
++ }
++}
++
++void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ if (src != NULL) {
++
++ // Duplicate the LIST
++ DupTagTypeList(ctx, src, MPEPlugin);
++ }
++ else {
++ static _cmsTagTypePluginChunkType TagTypePluginChunk = { NULL };
++ ctx ->chunks[MPEPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagTypePluginChunk, sizeof(_cmsTagTypePluginChunkType));
++ }
++
++}
++
+
+ // Both kind of plug-ins share same structure
+ cmsBool _cmsRegisterTagTypePlugin(cmsContext id, cmsPluginBase* Data)
+ {
+- return RegisterTypesPlugin(id, Data, SupportedTagTypes, DEFAULT_TAG_TYPE_COUNT);
++ return RegisterTypesPlugin(id, Data, TagTypePlugin);
+ }
+
+ cmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext id, cmsPluginBase* Data)
+ {
+- return RegisterTypesPlugin(id, Data, SupportedMPEtypes, DEFAULT_MPE_TYPE_COUNT);
++ return RegisterTypesPlugin(id, Data,MPEPlugin);
+ }
+
+
+ // Wrapper for tag types
+-cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsTagTypeSignature sig)
+-{
+- return GetHandler(sig, SupportedTagTypes);
++cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig)
++{
++ _cmsTagTypePluginChunkType* ctx = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(ContextID, TagTypePlugin);
++
++ return GetHandler(sig, ctx->TagTypes, SupportedTagTypes);
+ }
+
+ // ********************************************************************************
+@@ -5414,48 +5495,94 @@
+ cmsSigDeviceSettingsTag ==> Deprecated, useless
+ */
+
+-#define DEFAULT_TAG_COUNT (sizeof(SupportedTags) / sizeof(_cmsTagLinkedList))
++
++_cmsTagPluginChunkType _cmsTagPluginChunk = { NULL };
++
++
++// Duplicates the zone of memory used by the plug-in in the new context
++static
++void DupTagList(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ _cmsTagPluginChunkType newHead = { NULL };
++ _cmsTagLinkedList* entry;
++ _cmsTagLinkedList* Anterior = NULL;
++ _cmsTagPluginChunkType* head = (_cmsTagPluginChunkType*) src->chunks[TagPlugin];
++
++ // Walk the list copying all nodes
++ for (entry = head->Tag;
++ entry != NULL;
++ entry = entry ->Next) {
++
++ _cmsTagLinkedList *newEntry = ( _cmsTagLinkedList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTagLinkedList));
++
++ if (newEntry == NULL)
++ return;
++
++ // We want to keep the linked list order, so this is a little bit tricky
++ newEntry -> Next = NULL;
++ if (Anterior)
++ Anterior -> Next = newEntry;
++
++ Anterior = newEntry;
++
++ if (newHead.Tag == NULL)
++ newHead.Tag = newEntry;
++ }
++
++ ctx ->chunks[TagPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTagPluginChunkType));
++}
++
++void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ if (src != NULL) {
++
++ DupTagList(ctx, src);
++ }
++ else {
++ static _cmsTagPluginChunkType TagPluginChunk = { NULL };
++ ctx ->chunks[TagPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagPluginChunk, sizeof(_cmsTagPluginChunkType));
++ }
++
++}
+
+ cmsBool _cmsRegisterTagPlugin(cmsContext id, cmsPluginBase* Data)
+ {
+ cmsPluginTag* Plugin = (cmsPluginTag*) Data;
+- _cmsTagLinkedList *pt, *Anterior;
+-
++ _cmsTagLinkedList *pt;
++ _cmsTagPluginChunkType* TagPluginChunk = ( _cmsTagPluginChunkType*) _cmsContextGetClientChunk(id, TagPlugin);
+
+ if (Data == NULL) {
+
+- SupportedTags[DEFAULT_TAG_COUNT-1].Next = NULL;
++ TagPluginChunk->Tag = NULL;
+ return TRUE;
+ }
+
+- pt = Anterior = SupportedTags;
+- while (pt != NULL) {
+-
+- if (Plugin->Signature == pt -> Signature) {
+- pt ->Descriptor = Plugin ->Descriptor; // Replace old behaviour
+- return TRUE;
+- }
+-
+- Anterior = pt;
+- pt = pt ->Next;
+- }
+-
+ pt = (_cmsTagLinkedList*) _cmsPluginMalloc(id, sizeof(_cmsTagLinkedList));
+ if (pt == NULL) return FALSE;
+
+ pt ->Signature = Plugin ->Signature;
+ pt ->Descriptor = Plugin ->Descriptor;
+- pt ->Next = NULL;
+-
+- if (Anterior != NULL) Anterior -> Next = pt;
++ pt ->Next = TagPluginChunk ->Tag;
++
++ TagPluginChunk ->Tag = pt;
+
+ return TRUE;
+ }
+
+ // Return a descriptor for a given tag or NULL
+-cmsTagDescriptor* _cmsGetTagDescriptor(cmsTagSignature sig)
++cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig)
+ {
+ _cmsTagLinkedList* pt;
++ _cmsTagPluginChunkType* TagPluginChunk = ( _cmsTagPluginChunkType*) _cmsContextGetClientChunk(ContextID, TagPlugin);
++
++ for (pt = TagPluginChunk->Tag;
++ pt != NULL;
++ pt = pt ->Next) {
++
++ if (sig == pt -> Signature) return &pt ->Descriptor;
++ }
+
+ for (pt = SupportedTags;
+ pt != NULL;
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c Wed Feb 04 12:14:43 2015 -0800
+@@ -30,7 +30,7 @@
+ //---------------------------------------------------------------------------------
+ //
+ // Little Color Management System
+-// Copyright (c) 1998-2011 Marti Maria Saguer
++// Copyright (c) 1998-2014 Marti Maria Saguer
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining
+ // a copy of this software and associated documentation files (the "Software"),
+@@ -1019,7 +1019,7 @@
+
+ static const cmsAllowedLUT AllowedLUTTypes[] = {
+
+- { FALSE, 0, cmsSigLut16Type, 4, { cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
++ { FALSE, 0, cmsSigLut16Type, 4, { cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
+ { FALSE, 0, cmsSigLut16Type, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
+ { FALSE, 0, cmsSigLut16Type, 2, { cmsSigCurveSetElemType, cmsSigCLutElemType}},
+ { TRUE , 0, cmsSigLutAtoBType, 1, { cmsSigCurveSetElemType }},
+@@ -1150,7 +1150,7 @@
+ if (AllowedLUT == NULL) {
+
+ // Try to optimize
+- _cmsOptimizePipeline(&LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
++ _cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
+ AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag);
+
+ }
+@@ -1159,7 +1159,7 @@
+ if (AllowedLUT == NULL) {
+
+ dwFlags |= cmsFLAGS_FORCE_CLUT;
+- _cmsOptimizePipeline(&LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
++ _cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
+
+ // Put identity curves if needed
+ if (cmsPipelineGetPtrToFirstStage(LUT) ->Type != cmsSigCurveSetElemType)
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c Wed Feb 04 12:14:43 2015 -0800
+@@ -30,7 +30,7 @@
+ //---------------------------------------------------------------------------------
+ //
+ // Little Color Management System
+-// Copyright (c) 1998-2012 Marti Maria Saguer
++// Copyright (c) 1998-2014 Marti Maria Saguer
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining
+ // a copy of this software and associated documentation files (the "Software"),
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c Wed Feb 04 12:14:43 2015 -0800
+@@ -30,7 +30,7 @@
+ //---------------------------------------------------------------------------------
+ //
+ // Little Color Management System
+-// Copyright (c) 1998-2011 Marti Maria Saguer
++// Copyright (c) 1998-2014 Marti Maria Saguer
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining
+ // a copy of this software and associated documentation files (the "Software"),
+@@ -58,44 +58,120 @@
+ // Transformations stuff
+ // -----------------------------------------------------------------------
+
+-// Alarm codes for 16-bit transformations, because the fixed range of containers there are
+-// no values left to mark out of gamut. volatile is C99 per 6.2.5
+-static volatile cmsUInt16Number Alarm[cmsMAXCHANNELS] = { 0x7F00, 0x7F00, 0x7F00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+-static volatile cmsFloat64Number GlobalAdaptationState = 1;
++#define DEFAULT_OBSERVER_ADAPTATION_STATE 1.0
++
++// The Context0 observer adaptation state.
++_cmsAdaptationStateChunkType _cmsAdaptationStateChunk = { DEFAULT_OBSERVER_ADAPTATION_STATE };
++
++// Init and duplicate observer adaptation state
++void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ static _cmsAdaptationStateChunkType AdaptationStateChunk = { DEFAULT_OBSERVER_ADAPTATION_STATE };
++ void* from;
++
++ if (src != NULL) {
++ from = src ->chunks[AdaptationStateContext];
++ }
++ else {
++ from = &AdaptationStateChunk;
++ }
++
++ ctx ->chunks[AdaptationStateContext] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsAdaptationStateChunkType));
++}
++
++
++// Sets adaptation state for absolute colorimetric intent in the given context. Adaptation state applies on all
++// but cmsCreateExtendedTransformTHR(). Little CMS can handle incomplete adaptation states.
++cmsFloat64Number CMSEXPORT cmsSetAdaptationStateTHR(cmsContext ContextID, cmsFloat64Number d)
++{
++ cmsFloat64Number prev;
++ _cmsAdaptationStateChunkType* ptr = (_cmsAdaptationStateChunkType*) _cmsContextGetClientChunk(ContextID, AdaptationStateContext);
++
++ // Get previous value for return
++ prev = ptr ->AdaptationState;
++
++ // Set the value if d is positive or zero
++ if (d >= 0.0) {
++
++ ptr ->AdaptationState = d;
++ }
++
++ // Always return previous value
++ return prev;
++}
++
+
+ // The adaptation state may be defaulted by this function. If you don't like it, use the extended transform routine
+ cmsFloat64Number CMSEXPORT cmsSetAdaptationState(cmsFloat64Number d)
+ {
+- cmsFloat64Number OldVal = GlobalAdaptationState;
+-
+- if (d >= 0)
+- GlobalAdaptationState = d;
+-
+- return OldVal;
++ return cmsSetAdaptationStateTHR(NULL, d);
+ }
+
+-// Alarm codes are always global
+-void CMSEXPORT cmsSetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS])
++// -----------------------------------------------------------------------
++
++// Alarm codes for 16-bit transformations, because the fixed range of containers there are
++// no values left to mark out of gamut.
++
++#define DEFAULT_ALARM_CODES_VALUE {0x7F00, 0x7F00, 0x7F00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
++
++_cmsAlarmCodesChunkType _cmsAlarmCodesChunk = { DEFAULT_ALARM_CODES_VALUE };
++
++// Sets the codes used to mark out-out-gamut on Proofing transforms for a given context. Values are meant to be
++// encoded in 16 bits.
++void CMSEXPORT cmsSetAlarmCodesTHR(cmsContext ContextID, const cmsUInt16Number AlarmCodesP[cmsMAXCHANNELS])
+ {
+- int i;
++ _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(ContextID, AlarmCodesContext);
+
++ _cmsAssert(ContextAlarmCodes != NULL); // Can't happen
++
++ memcpy(ContextAlarmCodes->AlarmCodes, AlarmCodesP, sizeof(ContextAlarmCodes->AlarmCodes));
++}
++
++// Gets the current codes used to mark out-out-gamut on Proofing transforms for the given context.
++// Values are meant to be encoded in 16 bits.
++void CMSEXPORT cmsGetAlarmCodesTHR(cmsContext ContextID, cmsUInt16Number AlarmCodesP[cmsMAXCHANNELS])
++{
++ _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(ContextID, AlarmCodesContext);
++
++ _cmsAssert(ContextAlarmCodes != NULL); // Can't happen
++
++ memcpy(AlarmCodesP, ContextAlarmCodes->AlarmCodes, sizeof(ContextAlarmCodes->AlarmCodes));
++}
++
++void CMSEXPORT cmsSetAlarmCodes(const cmsUInt16Number NewAlarm[cmsMAXCHANNELS])
++{
+ _cmsAssert(NewAlarm != NULL);
+
+- for (i=0; i < cmsMAXCHANNELS; i++)
+- Alarm[i] = NewAlarm[i];
++ cmsSetAlarmCodesTHR(NULL, NewAlarm);
+ }
+
+-// You can get the codes cas well
+ void CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number OldAlarm[cmsMAXCHANNELS])
+ {
+- int i;
++ _cmsAssert(OldAlarm != NULL);
++ cmsGetAlarmCodesTHR(NULL, OldAlarm);
++}
+
+- _cmsAssert(OldAlarm != NULL);
+
+- for (i=0; i < cmsMAXCHANNELS; i++)
+- OldAlarm[i] = Alarm[i];
++// Init and duplicate alarm codes
++void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ static _cmsAlarmCodesChunkType AlarmCodesChunk = { DEFAULT_ALARM_CODES_VALUE };
++ void* from;
++
++ if (src != NULL) {
++ from = src ->chunks[AlarmCodesContext];
++ }
++ else {
++ from = &AlarmCodesChunk;
++ }
++
++ ctx ->chunks[AlarmCodesContext] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsAlarmCodesChunkType));
+ }
+
++// -----------------------------------------------------------------------
++
+ // Get rid of transform resources
+ void CMSEXPORT cmsDeleteTransform(cmsHTRANSFORM hTransform)
+ {
+@@ -202,6 +278,30 @@
+ }
+ }
+
++
++static
++void NullFloatXFORM(_cmsTRANSFORM* p,
++ const void* in,
++ void* out,
++ cmsUInt32Number Size,
++ cmsUInt32Number Stride)
++{
++ cmsUInt8Number* accum;
++ cmsUInt8Number* output;
++ cmsFloat32Number fIn[cmsMAXCHANNELS];
++ cmsUInt32Number i, n;
++
++ accum = (cmsUInt8Number*) in;
++ output = (cmsUInt8Number*) out;
++ n = Size;
++
++ for (i=0; i < n; i++) {
++
++ accum = p -> FromInputFloat(p, fIn, accum, Stride);
++ output = p -> ToOutputFloat(p, fIn, output, Stride);
++ }
++}
++
+ // 16 bit precision -----------------------------------------------------------------------------------------------------------
+
+ // Null transformation, only applies formatters. No caché
+@@ -252,7 +352,7 @@
+ }
+
+
+-// Auxiliar: Handle precalculated gamut check
++// Auxiliar: Handle precalculated gamut check. The retrieval of context may be alittle bit slow, but this function is not critical.
+ static
+ void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p,
+ const cmsUInt16Number wIn[],
+@@ -264,9 +364,12 @@
+ if (wOutOfGamut >= 1) {
+
+ cmsUInt16Number i;
++ _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(p->ContextID, AlarmCodesContext);
+
+- for (i=0; i < p ->Lut->OutputChannels; i++)
+- wOut[i] = Alarm[i];
++ for (i=0; i < p ->Lut->OutputChannels; i++) {
++
++ wOut[i] = ContextAlarmCodes ->AlarmCodes[i];
++ }
+ }
+ else
+ p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
+@@ -393,34 +496,86 @@
+ } _cmsTransformCollection;
+
+ // The linked list head
+-static _cmsTransformCollection* TransformCollection = NULL;
++_cmsTransformPluginChunkType _cmsTransformPluginChunk = { NULL };
++
++
++// Duplicates the zone of memory used by the plug-in in the new context
++static
++void DupPluginTransformList(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ _cmsTransformPluginChunkType newHead = { NULL };
++ _cmsTransformCollection* entry;
++ _cmsTransformCollection* Anterior = NULL;
++ _cmsTransformPluginChunkType* head = (_cmsTransformPluginChunkType*) src->chunks[TransformPlugin];
++
++ // Walk the list copying all nodes
++ for (entry = head->TransformCollection;
++ entry != NULL;
++ entry = entry ->Next) {
++
++ _cmsTransformCollection *newEntry = ( _cmsTransformCollection *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTransformCollection));
++
++ if (newEntry == NULL)
++ return;
++
++ // We want to keep the linked list order, so this is a little bit tricky
++ newEntry -> Next = NULL;
++ if (Anterior)
++ Anterior -> Next = newEntry;
++
++ Anterior = newEntry;
++
++ if (newHead.TransformCollection == NULL)
++ newHead.TransformCollection = newEntry;
++ }
++
++ ctx ->chunks[TransformPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTransformPluginChunkType));
++}
++
++void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src)
++{
++ if (src != NULL) {
++
++ // Copy all linked list
++ DupPluginTransformList(ctx, src);
++ }
++ else {
++ static _cmsTransformPluginChunkType TransformPluginChunkType = { NULL };
++ ctx ->chunks[TransformPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TransformPluginChunkType, sizeof(_cmsTransformPluginChunkType));
++ }
++}
++
++
+
+ // Register new ways to transform
+-cmsBool _cmsRegisterTransformPlugin(cmsContext id, cmsPluginBase* Data)
++cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Data)
+ {
+ cmsPluginTransform* Plugin = (cmsPluginTransform*) Data;
+ _cmsTransformCollection* fl;
++ _cmsTransformPluginChunkType* ctx = ( _cmsTransformPluginChunkType*) _cmsContextGetClientChunk(ContextID,TransformPlugin);
+
+- if (Data == NULL) {
++ if (Data == NULL) {
+
+ // Free the chain. Memory is safely freed at exit
+- TransformCollection = NULL;
++ ctx->TransformCollection = NULL;
+ return TRUE;
+ }
+
+ // Factory callback is required
+- if (Plugin ->Factory == NULL) return FALSE;
++ if (Plugin ->Factory == NULL) return FALSE;
+
+
+- fl = (_cmsTransformCollection*) _cmsPluginMalloc(id, sizeof(_cmsTransformCollection));
++ fl = (_cmsTransformCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsTransformCollection));
+ if (fl == NULL) return FALSE;
+
+- // Copy the parameters
++ // Copy the parameters
+ fl ->Factory = Plugin ->Factory;
+
+ // Keep linked list
+- fl ->Next = TransformCollection;
+- TransformCollection = fl;
++ fl ->Next = ctx->TransformCollection;
++ ctx->TransformCollection = fl;
+
+ // All is ok
+ return TRUE;
+@@ -463,6 +618,7 @@
+ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
+ cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags)
+ {
++ _cmsTransformPluginChunkType* ctx = ( _cmsTransformPluginChunkType*) _cmsContextGetClientChunk(ContextID, TransformPlugin);
+ _cmsTransformCollection* Plugin;
+
+ // Allocate needed memory
+@@ -473,7 +629,7 @@
+ p ->Lut = lut;
+
+ // Let's see if any plug-in want to do the transform by itself
+- for (Plugin = TransformCollection;
++ for (Plugin = ctx ->TransformCollection;
+ Plugin != NULL;
+ Plugin = Plugin ->Next) {
+
+@@ -493,10 +649,10 @@
+ // Fill the formatters just in case the optimized routine is interested.
+ // No error is thrown if the formatter doesn't exist. It is up to the optimization
+ // factory to decide what to do in those cases.
+- p ->FromInput = _cmsGetFormatter(*InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
+- p ->ToOutput = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
+- p ->FromInputFloat = _cmsGetFormatter(*InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+- p ->ToOutputFloat = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
++ p ->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
++ p ->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
++ p ->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
++ p ->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+
+ return p;
+ }
+@@ -504,14 +660,14 @@
+
+ // Not suitable for the transform plug-in, let's check the pipeline plug-in
+ if (p ->Lut != NULL)
+- _cmsOptimizePipeline(&p->Lut, Intent, InputFormat, OutputFormat, dwFlags);
++ _cmsOptimizePipeline(ContextID, &p->Lut, Intent, InputFormat, OutputFormat, dwFlags);
+
+ // Check whatever this is a true floating point transform
+ if (_cmsFormatterIsFloat(*InputFormat) && _cmsFormatterIsFloat(*OutputFormat)) {
+
+ // Get formatter function always return a valid union, but the contents of this union may be NULL.
+- p ->FromInputFloat = _cmsGetFormatter(*InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+- p ->ToOutputFloat = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
++ p ->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
++ p ->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+ *dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER;
+
+ if (p ->FromInputFloat == NULL || p ->ToOutputFloat == NULL) {
+@@ -521,8 +677,15 @@
+ return NULL;
+ }
+
+- // Float transforms don't use caché, always are non-NULL
+- p ->xform = FloatXFORM;
++ if (*dwFlags & cmsFLAGS_NULLTRANSFORM) {
++
++ p ->xform = NullFloatXFORM;
++ }
++ else {
++ // Float transforms don't use caché, always are non-NULL
++ p ->xform = FloatXFORM;
++ }
++
+ }
+ else {
+
+@@ -534,8 +697,8 @@
+
+ int BytesPerPixelInput;
+
+- p ->FromInput = _cmsGetFormatter(*InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
+- p ->ToOutput = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
++ p ->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
++ p ->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
+
+ if (p ->FromInput == NULL || p ->ToOutput == NULL) {
+
+@@ -727,6 +890,7 @@
+ // Check channel count
+ if ((cmsChannelsOf(EntryColorSpace) != cmsPipelineInputChannels(Lut)) ||
+ (cmsChannelsOf(ExitColorSpace) != cmsPipelineOutputChannels(Lut))) {
++ cmsPipelineFree(Lut);
+ cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Channel count doesn't match. Profile is corrupted");
+ return NULL;
+ }
+@@ -829,7 +993,7 @@
+ for (i=0; i < nProfiles; i++) {
+ BPC[i] = dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION ? TRUE : FALSE;
+ Intents[i] = Intent;
+- AdaptationStates[i] = GlobalAdaptationState;
++ AdaptationStates[i] = cmsSetAdaptationStateTHR(ContextID, -1);
+ }
+
+
+@@ -909,7 +1073,7 @@
+ Intents[0] = nIntent; Intents[1] = nIntent; Intents[2] = INTENT_RELATIVE_COLORIMETRIC; Intents[3] = ProofingIntent;
+ BPC[0] = DoBPC; BPC[1] = DoBPC; BPC[2] = 0; BPC[3] = 0;
+
+- Adaptation[0] = Adaptation[1] = Adaptation[2] = Adaptation[3] = GlobalAdaptationState;
++ Adaptation[0] = Adaptation[1] = Adaptation[2] = Adaptation[3] = cmsSetAdaptationStateTHR(ContextID, -1);
+
+ if (!(dwFlags & (cmsFLAGS_SOFTPROOFING|cmsFLAGS_GAMUTCHECK)))
+ return cmsCreateTransformTHR(ContextID, InputProfile, InputFormat, OutputProfile, OutputFormat, nIntent, dwFlags);
+@@ -984,8 +1148,8 @@
+ return FALSE;
+ }
+
+- FromInput = _cmsGetFormatter(InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
+- ToOutput = _cmsGetFormatter(OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
++ FromInput = _cmsGetFormatter(xform->ContextID, InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
++ ToOutput = _cmsGetFormatter(xform->ContextID, OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
+
+ if (FromInput == NULL || ToOutput == NULL) {
+
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/lcms2.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/lcms2.h Wed Feb 04 12:14:43 2015 -0800
+@@ -30,7 +30,7 @@
+ //---------------------------------------------------------------------------------
+ //
+ // Little Color Management System
+-// Copyright (c) 1998-2013 Marti Maria Saguer
++// Copyright (c) 1998-2014 Marti Maria Saguer
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining
+ // a copy of this software and associated documentation files (the "Software"),
+@@ -52,7 +52,7 @@
+ //
+ //---------------------------------------------------------------------------------
+ //
+-// Version 2.5
++// Version 2.6
+ //
+
+ #ifndef _lcms2_H
+@@ -84,6 +84,9 @@
+ // Uncomment to get rid of the tables for "half" float support
+ // #define CMS_NO_HALF_SUPPORT 1
+
++// Uncomment to get rid of pthreads/windows dependency
++// #define CMS_NO_PTHREADS 1
++
+ // ********** End of configuration toggles ******************************
+
+ // Needed for streams
+@@ -101,7 +104,7 @@
+ #endif
+
+ // Version/release
+-#define LCMS_VERSION 2050
++#define LCMS_VERSION 2060
+
+ // I will give the chance of redefining basic types for compilers that are not fully C99 compliant
+ #ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
+@@ -202,28 +205,42 @@
+ // Try to detect big endian platforms. This list can be endless, so only some checks are performed over here.
+ // you can pass this toggle to the compiler by using -DCMS_USE_BIG_ENDIAN or something similar
+
+-#if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN)
++#if defined(__sgi__) || defined(__sgi) || defined(sparc)
+ # define CMS_USE_BIG_ENDIAN 1
+ #endif
+
+-#if defined(__sgi__) || defined(__sgi) || defined(__powerpc__) || defined(sparc)
+-# define CMS_USE_BIG_ENDIAN 1
+-#endif
+-
+-#if defined(__ppc__) || defined(__s390__) || defined(__s390x__)
++#if defined(__s390__) || defined(__s390x__)
+ # define CMS_USE_BIG_ENDIAN 1
+ #endif
+
+-#ifdef TARGET_CPU_PPC
+-# if TARGET_CPU_PPC
++# ifdef TARGET_CPU_PPC
++# if TARGET_CPU_PPC
++# define CMS_USE_BIG_ENDIAN 1
++# endif
++# endif
++
++#if defined(__powerpc__) || defined(__ppc__) || defined(TARGET_CPU_PPC)
+ # define CMS_USE_BIG_ENDIAN 1
+-# endif
++# if defined (__GNUC__) && defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN)
++# if __BYTE_ORDER == __LITTLE_ENDIAN
++// // Don't use big endian for PowerPC little endian mode
++# undef CMS_USE_BIG_ENDIAN
++# endif
++# endif
++#endif
++
++// WORDS_BIGENDIAN takes precedence
++#if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN)
++# define CMS_USE_BIG_ENDIAN 1
+ #endif
+
+ #ifdef macintosh
+ # ifdef __BIG_ENDIAN__
+ # define CMS_USE_BIG_ENDIAN 1
+ # endif
++# ifdef __LITTLE_ENDIAN__
++# undef CMS_USE_BIG_ENDIAN
++# endif
+ #endif
+
+ // Calling convention -- this is hardly platform and compiler dependent
+@@ -249,6 +266,14 @@
+ # define CMSAPI
+ #endif
+
++#ifdef HasTHREADS
++# if HasTHREADS == 1
++# undef CMS_NO_PTHREADS
++# else
++# define CMS_NO_PTHREADS 1
++# endif
++#endif
++
+ // Some common definitions
+ #define cmsMAX_PATH 256
+
+@@ -642,7 +667,6 @@
+
+ // Little CMS specific typedefs
+
+-typedef void* cmsContext; // Context identifier for multithreaded environments
+ typedef void* cmsHANDLE ; // Generic handle
+ typedef void* cmsHPROFILE; // Opaque typedefs to hide internals
+ typedef void* cmsHTRANSFORM;
+@@ -1012,11 +1036,25 @@
+ CMSAPI int CMSEXPORT cmsstrcasecmp(const char* s1, const char* s2);
+ CMSAPI long int CMSEXPORT cmsfilelength(FILE* f);
+
+-// Plug-In registering ---------------------------------------------------------------------------------------------------
++
++// Context handling --------------------------------------------------------------------------------------------------------
++
++// Each context holds its owns globals and its own plug-ins. There is a global context with the id = 0 for lecacy compatibility
++// though using the global context is not recomended. Proper context handling makes lcms more thread-safe.
++
++typedef struct _cmsContext_struct* cmsContext;
++
++CMSAPI cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData);
++CMSAPI void CMSEXPORT cmsDeleteContext(cmsContext ContexID);
++CMSAPI cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData);
++CMSAPI void* CMSEXPORT cmsGetContextUserData(cmsContext ContextID);
++
++// Plug-In registering --------------------------------------------------------------------------------------------------
+
+ CMSAPI cmsBool CMSEXPORT cmsPlugin(void* Plugin);
+ CMSAPI cmsBool CMSEXPORT cmsPluginTHR(cmsContext ContextID, void* Plugin);
+ CMSAPI void CMSEXPORT cmsUnregisterPlugins(void);
++CMSAPI void CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID);
+
+ // Error logging ----------------------------------------------------------------------------------------------------------
+
+@@ -1053,6 +1091,7 @@
+
+ // Allows user to set any specific logger
+ CMSAPI void CMSEXPORT cmsSetLogErrorHandler(cmsLogErrorHandlerFunction Fn);
++CMSAPI void CMSEXPORT cmsSetLogErrorHandlerTHR(cmsContext ContextID, cmsLogErrorHandlerFunction Fn);
+
+ // Conversions --------------------------------------------------------------------------------------------------------------
+
+@@ -1514,6 +1553,7 @@
+ CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromMem(const void * MemPtr, cmsUInt32Number dwSize);
+ CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromMemTHR(cmsContext ContextID, const void * MemPtr, cmsUInt32Number dwSize);
+ CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromIOhandlerTHR(cmsContext ContextID, cmsIOHANDLER* io);
++CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromIOhandler2THR(cmsContext ContextID, cmsIOHANDLER* io, cmsBool write);
+ CMSAPI cmsBool CMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile);
+
+ CMSAPI cmsBool CMSEXPORT cmsSaveProfileToFile(cmsHPROFILE hProfile, const char* FileName);
+@@ -1604,6 +1644,7 @@
+
+ // Call with NULL as parameters to get the intent count
+ CMSAPI cmsUInt32Number CMSEXPORT cmsGetSupportedIntents(cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions);
++CMSAPI cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions);
+
+ // Flags
+
+@@ -1715,11 +1756,22 @@
+ cmsUInt32Number Stride);
+
+
+-CMSAPI void CMSEXPORT cmsSetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
++CMSAPI void CMSEXPORT cmsSetAlarmCodes(const cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
+ CMSAPI void CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
+
++
++CMSAPI void CMSEXPORT cmsSetAlarmCodesTHR(cmsContext ContextID,
++ const cmsUInt16Number AlarmCodes[cmsMAXCHANNELS]);
++CMSAPI void CMSEXPORT cmsGetAlarmCodesTHR(cmsContext ContextID,
++ cmsUInt16Number AlarmCodes[cmsMAXCHANNELS]);
++
++
++
+ // Adaptation state for absolute colorimetric intent
+ CMSAPI cmsFloat64Number CMSEXPORT cmsSetAdaptationState(cmsFloat64Number d);
++CMSAPI cmsFloat64Number CMSEXPORT cmsSetAdaptationStateTHR(cmsContext ContextID, cmsFloat64Number d);
++
++
+
+ // Grab the ContextID from an open transform. Returns NULL if a NULL transform is passed
+ CMSAPI cmsContext CMSEXPORT cmsGetTransformContextID(cmsHTRANSFORM hTransform);
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/lcms2_internal.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/lcms2_internal.h Wed Feb 04 12:14:43 2015 -0800
+@@ -30,7 +30,7 @@
+
+ //
+ // Little Color Management System
+-// Copyright (c) 1998-2011 Marti Maria Saguer
++// Copyright (c) 1998-2014 Marti Maria Saguer
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining
+ // a copy of this software and associated documentation files (the "Software"),
+@@ -193,16 +193,171 @@
+ return _cmsQuickFloorWord(d);
+ }
+
+-// Plug-In registering ---------------------------------------------------------------
++
++// Pthread support --------------------------------------------------------------------
++#ifndef CMS_NO_PTHREADS
++
++// This is the threading support. Unfortunately, it has to be platform-dependent because
++// windows does not support pthreads.
++
++#ifdef CMS_IS_WINDOWS_
++
++#define WIN32_LEAN_AND_MEAN 1
++#include <windows.h>
++
++
++// From: http://locklessinc.com/articles/pthreads_on_windows/
++// The pthreads API has an initialization macro that has no correspondence to anything in
++// the windows API. By investigating the internal definition of the critical section type,
++// one may work out how to initialize one without calling InitializeCriticalSection().
++// The trick here is that InitializeCriticalSection() is not allowed to fail. It tries
++// to allocate a critical section debug object, but if no memory is available, it sets
++// the pointer to a specific value. (One would expect that value to be NULL, but it is
++// actually (void *)-1 for some reason.) Thus we can use this special value for that
++// pointer, and the critical section code will work.
++
++// The other important part of the critical section type to initialize is the number
++// of waiters. This controls whether or not the mutex is locked. Fortunately, this
++// part of the critical section is unlikely to change. Apparently, many programs
++// already test critical sections to see if they are locked using this value, so
++// Microsoft felt that it was necessary to keep it set at -1 for an unlocked critical
++// section, even when they changed the underlying algorithm to be more scalable.
++// The final parts of the critical section object are unimportant, and can be set
++// to zero for their defaults. This yields an initialization macro:
++
++typedef CRITICAL_SECTION _cmsMutex;
++
++#define CMS_MUTEX_INITIALIZER {(void*) -1,-1,0,0,0,0}
++
++cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
++{
++ EnterCriticalSection(m);
++ return 0;
++}
++
++cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
++{
++ LeaveCriticalSection(m);
++ return 0;
++}
++
++cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
++{
++ InitializeCriticalSection(m);
++ return 0;
++}
++
++cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
++{
++ DeleteCriticalSection(m);
++ return 0;
++}
++
++cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
++{
++ EnterCriticalSection(m);
++ return 0;
++}
++
++cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
++{
++ LeaveCriticalSection(m);
++ return 0;
++}
++
++#else
++
++// Rest of the wide world
++#include <pthread.h>
++
++#define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
++typedef pthread_mutex_t _cmsMutex;
++
++
++cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
++{
++ return pthread_mutex_lock(m);
++}
++
++cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
++{
++ return pthread_mutex_unlock(m);
++}
++
++cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
++{
++ return pthread_mutex_init(m, NULL);
++}
++
++cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
++{
++ return pthread_mutex_destroy(m);
++}
++
++cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
++{
++ return pthread_mutex_lock(m);
++}
++
++cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
++{
++ return pthread_mutex_unlock(m);
++}
++
++#endif
++#else
++
++#define CMS_MUTEX_INITIALIZER 0
++typedef int _cmsMutex;
++
++
++cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
++{
++ return 0;
++ cmsUNUSED_PARAMETER(m);
++}
++
++cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
++{
++ return 0;
++ cmsUNUSED_PARAMETER(m);
++}
++
++cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
++{
++ return 0;
++ cmsUNUSED_PARAMETER(m);
++}
++
++cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
++{
++ return 0;
++ cmsUNUSED_PARAMETER(m);
++}
++
++cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
++{
++ return 0;
++ cmsUNUSED_PARAMETER(m);
++}
++
++cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
++{
++ return 0;
++ cmsUNUSED_PARAMETER(m);
++}
++#endif
++
++// Plug-In registration ---------------------------------------------------------------
+
+ // Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once.
+ void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size);
+
+ // Memory management
+-cmsBool _cmsRegisterMemHandlerPlugin(cmsPluginBase* Plugin);
++cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
+
+ // Interpolation
+-cmsBool _cmsRegisterInterpPlugin(cmsPluginBase* Plugin);
++cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
+
+ // Parametric curves
+ cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
+@@ -228,9 +383,12 @@
+ // Transform
+ cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
+
++// Mutex
++cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
++
+ // ---------------------------------------------------------------------------------------------------------
+
+-// Suballocators. Those are blocks of memory that is freed at the end on whole block.
++// Suballocators.
+ typedef struct _cmsSubAllocator_chunk_st {
+
+ cmsUInt8Number* Block;
+@@ -253,9 +411,264 @@
+ _cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
+ void _cmsSubAllocDestroy(_cmsSubAllocator* s);
+ void* _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
++void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size);
+
+ // ----------------------------------------------------------------------------------
+
++// The context clients.
++typedef enum {
++
++ UserPtr, // User-defined pointer
++ Logger,
++ AlarmCodesContext,
++ AdaptationStateContext,
++ MemPlugin,
++ InterpPlugin,
++ CurvesPlugin,
++ FormattersPlugin,
++ TagTypePlugin,
++ TagPlugin,
++ IntentPlugin,
++ MPEPlugin,
++ OptimizationPlugin,
++ TransformPlugin,
++ MutexPlugin,
++
++ // Last in list
++ MemoryClientMax
++
++} _cmsMemoryClient;
++
++
++// Container for memory management plug-in.
++typedef struct {
++
++ _cmsMallocFnPtrType MallocPtr;
++ _cmsMalloZerocFnPtrType MallocZeroPtr;
++ _cmsFreeFnPtrType FreePtr;
++ _cmsReallocFnPtrType ReallocPtr;
++ _cmsCallocFnPtrType CallocPtr;
++ _cmsDupFnPtrType DupPtr;
++
++} _cmsMemPluginChunkType;
++
++// Copy memory management function pointers from plug-in to chunk, taking care of missing routines
++void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr);
++
++// Internal structure for context
++struct _cmsContext_struct {
++
++ struct _cmsContext_struct* Next; // Points to next context in the new style
++ _cmsSubAllocator* MemPool; // The memory pool that stores context data
++
++ void* chunks[MemoryClientMax]; // array of pointers to client chunks. Memory itself is hold in the suballocator.
++ // If NULL, then it reverts to global Context0
++
++ _cmsMemPluginChunkType DefaultMemoryManager; // The allocators used for creating the context itself. Cannot be overriden
++};
++
++// Returns a pointer to a valid context structure, including the global one if id is zero.
++// Verifies the magic number.
++struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID);
++
++// Returns the block assigned to the specific zone.
++void* _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc);
++
++
++// Chunks of context memory by plug-in client -------------------------------------------------------
++
++// Those structures encapsulates all variables needed by the several context clients (mostly plug-ins)
++
++// Container for error logger -- not a plug-in
++typedef struct {
++
++ cmsLogErrorHandlerFunction LogErrorHandler; // Set to NULL for Context0 fallback
++
++} _cmsLogErrorChunkType;
++
++// The global Context0 storage for error logger
++extern _cmsLogErrorChunkType _cmsLogErrorChunk;
++
++// Allocate and init error logger container.
++void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src);
++
++// Container for alarm codes -- not a plug-in
++typedef struct {
++
++ cmsUInt16Number AlarmCodes[cmsMAXCHANNELS];
++
++} _cmsAlarmCodesChunkType;
++
++// The global Context0 storage for alarm codes
++extern _cmsAlarmCodesChunkType _cmsAlarmCodesChunk;
++
++// Allocate and init alarm codes container.
++void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src);
++
++// Container for adaptation state -- not a plug-in
++typedef struct {
++
++ cmsFloat64Number AdaptationState;
++
++} _cmsAdaptationStateChunkType;
++
++// The global Context0 storage for adaptation state
++extern _cmsAdaptationStateChunkType _cmsAdaptationStateChunk;
++
++// Allocate and init adaptation state container.
++void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src);
++
++
++// The global Context0 storage for memory management
++extern _cmsMemPluginChunkType _cmsMemPluginChunk;
++
++// Allocate and init memory management container.
++void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src);
++
++// Container for interpolation plug-in
++typedef struct {
++
++ cmsInterpFnFactory Interpolators;
++
++} _cmsInterpPluginChunkType;
++
++// The global Context0 storage for interpolation plug-in
++extern _cmsInterpPluginChunkType _cmsInterpPluginChunk;
++
++// Allocate and init interpolation container.
++void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src);
++
++// Container for parametric curves plug-in
++typedef struct {
++
++ struct _cmsParametricCurvesCollection_st* ParametricCurves;
++
++} _cmsCurvesPluginChunkType;
++
++// The global Context0 storage for tone curves plug-in
++extern _cmsCurvesPluginChunkType _cmsCurvesPluginChunk;
++
++// Allocate and init parametric curves container.
++void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src);
++
++// Container for formatters plug-in
++typedef struct {
++
++ struct _cms_formatters_factory_list* FactoryList;
++
++} _cmsFormattersPluginChunkType;
++
++// The global Context0 storage for formatters plug-in
++extern _cmsFormattersPluginChunkType _cmsFormattersPluginChunk;
++
++// Allocate and init formatters container.
++void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src);
++
++// This chunk type is shared by TagType plug-in and MPE Plug-in
++typedef struct {
++
++ struct _cmsTagTypeLinkedList_st* TagTypes;
++
++} _cmsTagTypePluginChunkType;
++
++
++// The global Context0 storage for tag types plug-in
++extern _cmsTagTypePluginChunkType _cmsTagTypePluginChunk;
++
++
++// The global Context0 storage for mult process elements plug-in
++extern _cmsTagTypePluginChunkType _cmsMPETypePluginChunk;
++
++// Allocate and init Tag types container.
++void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src);
++// Allocate and init MPE container.
++void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src);
++// Container for tag plug-in
++typedef struct {
++
++ struct _cmsTagLinkedList_st* Tag;
++
++} _cmsTagPluginChunkType;
++
++
++// The global Context0 storage for tag plug-in
++extern _cmsTagPluginChunkType _cmsTagPluginChunk;
++
++// Allocate and init Tag container.
++void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src);
++
++// Container for intents plug-in
++typedef struct {
++
++ struct _cms_intents_list* Intents;
++
++} _cmsIntentsPluginChunkType;
++
++
++// The global Context0 storage for intents plug-in
++extern _cmsIntentsPluginChunkType _cmsIntentsPluginChunk;
++
++// Allocate and init intents container.
++void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src);
++
++// Container for optimization plug-in
++typedef struct {
++
++ struct _cmsOptimizationCollection_st* OptimizationCollection;
++
++} _cmsOptimizationPluginChunkType;
++
++
++// The global Context0 storage for optimizers plug-in
++extern _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk;
++
++// Allocate and init optimizers container.
++void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src);
++
++// Container for transform plug-in
++typedef struct {
++
++ struct _cmsTransformCollection_st* TransformCollection;
++
++} _cmsTransformPluginChunkType;
++
++// The global Context0 storage for full-transform replacement plug-in
++extern _cmsTransformPluginChunkType _cmsTransformPluginChunk;
++
++// Allocate and init transform container.
++void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src);
++
++// Container for mutex plug-in
++typedef struct {
++
++ _cmsCreateMutexFnPtrType CreateMutexPtr;
++ _cmsDestroyMutexFnPtrType DestroyMutexPtr;
++ _cmsLockMutexFnPtrType LockMutexPtr;
++ _cmsUnlockMutexFnPtrType UnlockMutexPtr;
++
++} _cmsMutexPluginChunkType;
++
++// The global Context0 storage for mutex plug-in
++extern _cmsMutexPluginChunkType _cmsMutexPluginChunk;
++
++// Allocate and init mutex container.
++void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
++ const struct _cmsContext_struct* src);
++
++// ----------------------------------------------------------------------------------
+ // MLU internal representation
+ typedef struct {
+
+@@ -347,10 +760,14 @@
+ cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked
+ void * TagPtrs[MAX_TABLE_TAG];
+ cmsTagTypeHandler* TagTypeHandlers[MAX_TABLE_TAG]; // Same structure may be serialized on different types
+- // depending on profile version, so we keep track of the // type handler for each tag in the list.
++ // depending on profile version, so we keep track of the
++ // type handler for each tag in the list.
+ // Special
+ cmsBool IsWrite;
+
++ // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin
++ void * UsrMutex;
++
+ } _cmsICCPROFILE;
+
+ // IO helpers for profiles
+@@ -359,9 +776,9 @@
+ int _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
+
+ // Tag types
+-cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsTagTypeSignature sig);
++cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
+ cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);
+-cmsTagDescriptor* _cmsGetTagDescriptor(cmsTagSignature sig);
++cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
+
+ // Error logging ---------------------------------------------------------------------------------------------------------
+
+@@ -372,7 +789,7 @@
+ cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
+ cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
+ void _cmsFreeInterpParams(cmsInterpParams* p);
+-cmsBool _cmsSetInterpolationRoutine(cmsInterpParams* p);
++cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
+
+ // Curves ----------------------------------------------------------------------------------------------------------------
+
+@@ -503,7 +920,8 @@
+ cmsUInt16Number **Black,
+ cmsUInt32Number *nOutputs);
+
+-cmsBool _cmsOptimizePipeline(cmsPipeline** Lut,
++cmsBool _cmsOptimizePipeline(cmsContext ContextID,
++ cmsPipeline** Lut,
+ int Intent,
+ cmsUInt32Number* InputFormat,
+ cmsUInt32Number* OutputFormat,
+@@ -528,7 +946,8 @@
+ cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type);
+ cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type);
+
+-cmsFormatter _cmsGetFormatter(cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
++cmsFormatter _cmsGetFormatter(cmsContext ContextID,
++ cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
+ cmsFormatterDirection Dir,
+ cmsUInt32Number dwFlags);
+
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/lcms2_plugin.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/lcms2_plugin.h Wed Feb 04 12:14:43 2015 -0800
+@@ -231,6 +231,7 @@
+ #define cmsPluginMultiProcessElementSig 0x6D706548 // 'mpeH'
+ #define cmsPluginOptimizationSig 0x6F707448 // 'optH'
+ #define cmsPluginTransformSig 0x7A666D48 // 'xfmH'
++#define cmsPluginMutexSig 0x6D747A48 // 'mtxH'
+
+ typedef struct _cmsPluginBaseStruct {
+
+@@ -247,19 +248,28 @@
+ //----------------------------------------------------------------------------------------------------------
+
+ // Memory handler. Each new plug-in type replaces current behaviour
++
++typedef void* (* _cmsMallocFnPtrType)(cmsContext ContextID, cmsUInt32Number size);
++typedef void (* _cmsFreeFnPtrType)(cmsContext ContextID, void *Ptr);
++typedef void* (* _cmsReallocFnPtrType)(cmsContext ContextID, void* Ptr, cmsUInt32Number NewSize);
++
++typedef void* (* _cmsMalloZerocFnPtrType)(cmsContext ContextID, cmsUInt32Number size);
++typedef void* (* _cmsCallocFnPtrType)(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size);
++typedef void* (* _cmsDupFnPtrType)(cmsContext ContextID, const void* Org, cmsUInt32Number size);
++
+ typedef struct {
+
+ cmsPluginBase base;
+
+ // Required
+- void * (* MallocPtr)(cmsContext ContextID, cmsUInt32Number size);
+- void (* FreePtr)(cmsContext ContextID, void *Ptr);
+- void * (* ReallocPtr)(cmsContext ContextID, void* Ptr, cmsUInt32Number NewSize);
++ _cmsMallocFnPtrType MallocPtr;
++ _cmsFreeFnPtrType FreePtr;
++ _cmsReallocFnPtrType ReallocPtr;
+
+ // Optional
+- void * (* MallocZeroPtr)(cmsContext ContextID, cmsUInt32Number size);
+- void * (* CallocPtr)(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size);
+- void * (* DupPtr)(cmsContext ContextID, const void* Org, cmsUInt32Number size);
++ _cmsMalloZerocFnPtrType MallocZeroPtr;
++ _cmsCallocFnPtrType CallocPtr;
++ _cmsDupFnPtrType DupPtr;
+
+ } cmsPluginMemHandler;
+
+@@ -622,6 +632,29 @@
+
+ } cmsPluginTransform;
+
++//----------------------------------------------------------------------------------------------------------
++// Mutex
++
++typedef void* (* _cmsCreateMutexFnPtrType)(cmsContext ContextID);
++typedef void (* _cmsDestroyMutexFnPtrType)(cmsContext ContextID, void* mtx);
++typedef cmsBool (* _cmsLockMutexFnPtrType)(cmsContext ContextID, void* mtx);
++typedef void (* _cmsUnlockMutexFnPtrType)(cmsContext ContextID, void* mtx);
++
++typedef struct {
++ cmsPluginBase base;
++
++ _cmsCreateMutexFnPtrType CreateMutexPtr;
++ _cmsDestroyMutexFnPtrType DestroyMutexPtr;
++ _cmsLockMutexFnPtrType LockMutexPtr;
++ _cmsUnlockMutexFnPtrType UnlockMutexPtr;
++
++} cmsPluginMutex;
++
++CMSAPI void* CMSEXPORT _cmsCreateMutex(cmsContext ContextID);
++CMSAPI void CMSEXPORT _cmsDestroyMutex(cmsContext ContextID, void* mtx);
++CMSAPI cmsBool CMSEXPORT _cmsLockMutex(cmsContext ContextID, void* mtx);
++CMSAPI void CMSEXPORT _cmsUnlockMutex(cmsContext ContextID, void* mtx);
++
+
+ #ifndef CMS_USE_CPP_API
+ # ifdef __cplusplus
+--- ./jdk/src/share/native/sun/java2d/opengl/OGLBlitLoops.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/opengl/OGLBlitLoops.c Wed Feb 04 12:14:43 2015 -0800
+@@ -674,6 +674,9 @@
+ viaTexture = JNI_TRUE;
+ break;
+ #endif
++ case OGLC_VENDOR_INTEL:
++ viaTexture = JNI_TRUE;
++ break;
+ default:
+ // just use the glDrawPixels() codepath
+ viaTexture = JNI_FALSE;
+--- ./jdk/src/share/native/sun/java2d/opengl/OGLBufImgOps.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/opengl/OGLBufImgOps.c Wed Feb 04 12:14:43 2015 -0800
+@@ -636,6 +636,9 @@
+ "OGLBufImgOps_EnableLookupOp: short=%d num=%d len=%d off=%d",
+ shortData, numBands, bandLength, offset);
+
++ for (i = 0; i < 4; i++) {
++ bands[i] = NULL;
++ }
+ RETURN_IF_NULL(oglc);
+ RETURN_IF_NULL(srcOps);
+ RESET_PREVIOUS_OP();
+--- ./jdk/src/share/native/sun/java2d/opengl/OGLContext.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/opengl/OGLContext.c Wed Feb 04 12:14:43 2015 -0800
+@@ -917,8 +917,8 @@
+ vcap = OGLC_VENDOR_ATI;
+ } else if (strncmp(vendor, "NVIDIA", 6) == 0) {
+ vcap = OGLC_VENDOR_NVIDIA;
+- } else if (strncmp(vendor, "Sun", 3) == 0) {
+- vcap = OGLC_VENDOR_SUN;
++ } else if (strncmp(vendor, "Intel", 5) == 0) {
++ vcap = OGLC_VENDOR_INTEL;
+ }
+ // REMIND: new in 7 - check if needs fixing
+ *caps |= ((vcap & OGLC_VCAP_MASK) << OGLC_VCAP_OFFSET);
+--- ./jdk/src/share/native/sun/java2d/opengl/OGLContext.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/java2d/opengl/OGLContext.h Wed Feb 04 12:14:43 2015 -0800
+@@ -152,7 +152,7 @@
+ #define OGLC_VENDOR_OTHER 0
+ #define OGLC_VENDOR_ATI 1
+ #define OGLC_VENDOR_NVIDIA 2
+-#define OGLC_VENDOR_SUN 3
++#define OGLC_VENDOR_INTEL 3
+
+ #define OGLC_VCAP_MASK 0x3
+ #define OGLC_VCAP_OFFSET 24
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/src/share/native/sun/misc/URLClassPath.c Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,109 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.
++ */
++
++#include <string.h>
++
++#include "jni.h"
++#include "jni_util.h"
++#include "jlong.h"
++#include "jvm.h"
++#include "jdk_util.h"
++
++#include "sun_misc_URLClassPath.h"
++
++extern char*
++getUTF(JNIEnv *env, jstring str, char* localBuf, int bufSize);
++
++
++JNIEXPORT jboolean JNICALL
++Java_sun_misc_URLClassPath_knownToNotExist0(JNIEnv *env, jclass cls, jobject loader,
++ jstring classname)
++{
++ char *clname;
++ jboolean result = JNI_FALSE;
++ char buf[128];
++
++ if (classname == NULL) {
++ JNU_ThrowNullPointerException(env, NULL);
++ return result;
++ }
++
++ clname = getUTF(env, classname, buf, sizeof(buf));
++ if (clname == NULL) {
++ JNU_ThrowOutOfMemoryError(env, NULL);
++ return result;
++ }
++ VerifyFixClassname(clname);
++
++ if (!VerifyClassname(clname, JNI_TRUE)) { /* expects slashed name */
++ goto done;
++ }
++
++ result = JVM_KnownToNotExist(env, loader, clname);
++
++ done:
++ if (clname != buf) {
++ free(clname);
++ }
++
++ return result;
++}
++
++JNIEXPORT jobjectArray JNICALL
++Java_sun_misc_URLClassPath_getLookupCacheURLs(JNIEnv *env, jclass cls, jobject loader)
++{
++ return JVM_GetResourceLookupCacheURLs(env, loader);
++}
++
++
++JNIEXPORT jintArray JNICALL
++Java_sun_misc_URLClassPath_getLookupCacheForClassLoader(JNIEnv *env, jclass cls,
++ jobject loader,
++ jstring resource_name)
++{
++ char *resname;
++ jintArray result = NULL;
++ char buf[128];
++
++ if (resource_name == NULL) {
++ JNU_ThrowNullPointerException(env, NULL);
++ return result;
++ }
++
++ resname = getUTF(env, resource_name, buf, sizeof(buf));
++ if (resname == NULL) {
++ JNU_ThrowOutOfMemoryError(env, NULL);
++ return result;
++ }
++ result = JVM_GetResourceLookupCache(env, loader, resname);
++
++ done:
++ if (resname != buf) {
++ free(resname);
++ }
++
++ return result;
++}
++
+--- ./jdk/src/share/native/sun/nio/ch/genSocketOptionRegistry.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/nio/ch/genSocketOptionRegistry.c Wed Feb 04 12:14:43 2015 -0800
+@@ -110,6 +110,7 @@
+ emit_inet("StandardSocketOptions.IP_MULTICAST_LOOP", IPPROTO_IP, IP_MULTICAST_LOOP);
+
+ #ifdef AF_INET6
++ emit_inet6("StandardSocketOptions.IP_TOS", IPPROTO_IPV6, IPV6_TCLASS);
+ emit_inet6("StandardSocketOptions.IP_MULTICAST_IF", IPPROTO_IPV6, IPV6_MULTICAST_IF);
+ emit_inet6("StandardSocketOptions.IP_MULTICAST_TTL", IPPROTO_IPV6, IPV6_MULTICAST_HOPS);
+ emit_inet6("StandardSocketOptions.IP_MULTICAST_LOOP", IPPROTO_IPV6, IPV6_MULTICAST_LOOP);
+--- ./jdk/src/share/native/sun/security/ec/ECC_JNI.cpp Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/security/ec/ECC_JNI.cpp Wed Feb 04 12:14:43 2015 -0800
+@@ -41,7 +41,9 @@
+ void ThrowException(JNIEnv *env, const char *exceptionName)
+ {
+ jclass exceptionClazz = env->FindClass(exceptionName);
+- env->ThrowNew(exceptionClazz, NULL);
++ if (exceptionClazz != NULL) {
++ env->ThrowNew(exceptionClazz, NULL);
++ }
+ }
+
+ /*
+@@ -80,7 +82,6 @@
+ return jEncodedBytes;
+ }
+
+-
+ /*
+ * Class: sun_security_ec_ECKeyPairGenerator
+ * Method: generateECKeyPair
+@@ -103,6 +104,9 @@
+ params_item.len = env->GetArrayLength(encodedParams);
+ params_item.data =
+ (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
++ if (params_item.data == NULL) {
++ goto cleanup;
++ }
+
+ // Fill a new ECParams using the supplied OID
+ if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
+@@ -170,6 +174,7 @@
+ SECITEM_FreeItem(&privKey->publicValue, B_FALSE);
+ free(privKey);
+ }
++
+ if (pSeedBuffer) {
+ delete [] pSeedBuffer;
+ }
+@@ -206,6 +211,7 @@
+ digest_item.len = jDigestLength;
+
+ ECPrivateKey privKey;
++ privKey.privateValue.data = NULL;
+
+ // Initialize the ECParams struct
+ ECParams *ecparams = NULL;
+@@ -213,6 +219,9 @@
+ params_item.len = env->GetArrayLength(encodedParams);
+ params_item.data =
+ (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
++ if (params_item.data == NULL) {
++ goto cleanup;
++ }
+
+ // Fill a new ECParams using the supplied OID
+ if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
+@@ -226,6 +235,9 @@
+ privKey.privateValue.len = env->GetArrayLength(privateKey);
+ privKey.privateValue.data =
+ (unsigned char *) env->GetByteArrayElements(privateKey, 0);
++ if (privKey.privateValue.data == NULL) {
++ goto cleanup;
++ }
+
+ // Prepare a buffer for the signature (twice the key length)
+ pSignedDigestBuffer = new jbyte[ecparams->order.len * 2];
+@@ -245,6 +257,9 @@
+
+ // Create new byte array
+ temp = env->NewByteArray(signature_item.len);
++ if (temp == NULL) {
++ goto cleanup;
++ }
+
+ // Copy data from native buffer
+ env->SetByteArrayRegion(temp, 0, signature_item.len, pSignedDigestBuffer);
+@@ -317,6 +332,9 @@
+ params_item.len = env->GetArrayLength(encodedParams);
+ params_item.data =
+ (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
++ if (params_item.data == NULL) {
++ goto cleanup;
++ }
+
+ // Fill a new ECParams using the supplied OID
+ if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
+@@ -369,25 +387,37 @@
+ (JNIEnv *env, jclass clazz, jbyteArray privateKey, jbyteArray publicKey, jbyteArray encodedParams)
+ {
+ jbyteArray jSecret = NULL;
++ ECParams *ecparams = NULL;
++ SECItem privateValue_item;
++ privateValue_item.data = NULL;
++ SECItem publicValue_item;
++ publicValue_item.data = NULL;
++ SECKEYECParams params_item;
++ params_item.data = NULL;
+
+ // Extract private key value
+- SECItem privateValue_item;
+ privateValue_item.len = env->GetArrayLength(privateKey);
+ privateValue_item.data =
+ (unsigned char *) env->GetByteArrayElements(privateKey, 0);
++ if (privateValue_item.data == NULL) {
++ goto cleanup;
++ }
+
+ // Extract public key value
+- SECItem publicValue_item;
+ publicValue_item.len = env->GetArrayLength(publicKey);
+ publicValue_item.data =
+ (unsigned char *) env->GetByteArrayElements(publicKey, 0);
++ if (publicValue_item.data == NULL) {
++ goto cleanup;
++ }
+
+ // Initialize the ECParams struct
+- ECParams *ecparams = NULL;
+- SECKEYECParams params_item;
+ params_item.len = env->GetArrayLength(encodedParams);
+ params_item.data =
+ (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
++ if (params_item.data == NULL) {
++ goto cleanup;
++ }
+
+ // Fill a new ECParams using the supplied OID
+ if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
+@@ -409,6 +439,9 @@
+
+ // Create new byte array
+ jSecret = env->NewByteArray(secret_item.len);
++ if (jSecret == NULL) {
++ goto cleanup;
++ }
+
+ // Copy bytes from the SECItem buffer to a Java byte array
+ env->SetByteArrayRegion(jSecret, 0, secret_item.len,
+--- ./jdk/src/share/native/sun/security/ec/impl/mpi.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/security/ec/impl/mpi.c Wed Feb 04 12:14:43 2015 -0800
+@@ -3376,7 +3376,7 @@
+ #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
+ mp_word w = 0, q;
+ #else
+- mp_digit w, q;
++ mp_digit w = 0, q;
+ #endif
+ int ix;
+ mp_err res;
+--- ./jdk/src/share/native/sun/security/jgss/wrapper/GSSLibStub.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/security/jgss/wrapper/GSSLibStub.c Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -29,19 +29,6 @@
+ #include "jlong.h"
+ #include <jni.h>
+
+-/* Throws a Java Exception by name */
+-
+-void throwByName(JNIEnv *env, const char *name, const char *msg) {
+- jclass cls = (*env)->FindClass(env, name);
+-
+- if (cls != 0) /* Otherwise an exception has already been thrown */
+- (*env)->ThrowNew(env, cls, msg);
+-}
+-
+-void throwOutOfMemoryError(JNIEnv *env, const char *message) {
+- throwByName(env, "java/lang/OutOfMemoryError", message);
+-}
+-
+ /* Constants for indicating what type of info is needed for inquiries */
+ const int TYPE_CRED_NAME = 10;
+ const int TYPE_CRED_TIME = 11;
+@@ -50,23 +37,32 @@
+ /*
+ * Class: sun_security_jgss_wrapper_GSSLibStub
+ * Method: init
+- * Signature: (Ljava/lang/String;)Z
++ * Signature: (Ljava/lang/String;Z)Z
+ */
+ JNIEXPORT jboolean JNICALL
+ Java_sun_security_jgss_wrapper_GSSLibStub_init(JNIEnv *env,
+ jclass jcls,
+- jstring jlibName) {
++ jstring jlibName,
++ jboolean jDebug) {
+ const char *libName;
+ char *error = NULL;
+
++ if (!jDebug) {
++ JGSS_DEBUG = 0;
++ } else {
++ JGSS_DEBUG = 1;
++ }
++
+ if (jlibName == NULL) {
+- debug(env, "[GSSLibStub_init] GSS lib name is NULL");
++ TRACE0("[GSSLibStub_init] GSS lib name is NULL");
+ return JNI_FALSE;
+ }
+
+ libName = (*env)->GetStringUTFChars(env, jlibName, NULL);
+- sprintf(debugBuf, "[GSSLibStub_init] libName=%s", libName);
+- debug(env, debugBuf);
++ if (libName == NULL) {
++ return JNI_FALSE;
++ }
++ TRACE1("[GSSLibStub_init] libName=%s", libName);
+
+ /* initialize global function table */
+ error = loadNative(libName);
+@@ -75,7 +71,7 @@
+ if (error == NULL) {
+ return JNI_TRUE;
+ } else {
+- debug(env, error);
++ TRACE0(error);
+ return JNI_FALSE;
+ }
+ }
+@@ -93,126 +89,137 @@
+ unsigned int i, len;
+ jbyte* bytes;
+ jthrowable gssEx;
+- jboolean found;
++ int found;
+
+ if (jbytes != NULL) {
+- found = JNI_FALSE;
++ found = 0;
+ len = (unsigned int)((*env)->GetArrayLength(env, jbytes) - 2);
+ bytes = (*env)->GetByteArrayElements(env, jbytes, NULL);
+- if (bytes != NULL) {
+- for (i = 0; i < ftab->mechs->count; i++) {
+- cOid = &(ftab->mechs->elements[i]);
+- if (len == cOid->length &&
+- (memcmp(cOid->elements, (bytes + 2), len) == 0)) {
+- // Found a match
+- found = JNI_TRUE;
+- break;
+- }
++ if (bytes == NULL) {
++ return ptr_to_jlong(NULL);
++ }
++ for (i = 0; i < ftab->mechs->count; i++) {
++ cOid = &(ftab->mechs->elements[i]);
++ if (len == cOid->length &&
++ (memcmp(cOid->elements, (bytes + 2), len) == 0)) {
++ // Found a match
++ found = 1;
++ break;
+ }
+- (*env)->ReleaseByteArrayElements(env, jbytes, bytes, 0);
+ }
+- if (found != JNI_TRUE) {
++ (*env)->ReleaseByteArrayElements(env, jbytes, bytes, 0);
++
++ if (found != 1) {
+ checkStatus(env, NULL, GSS_S_BAD_MECH, 0, "[GSSLibStub_getMechPtr]");
+ return ptr_to_jlong(NULL);
+- } else return ptr_to_jlong(cOid);
+- } else return ptr_to_jlong(GSS_C_NO_OID);
++ } else {
++ return ptr_to_jlong(cOid);
++ }
++ } else {
++ return ptr_to_jlong(GSS_C_NO_OID);
++ }
+ }
+
++/*
++ * Utility routine which releases the specified gss_channel_bindings_t
++ * structure.
++ */
++void deleteGSSCB(gss_channel_bindings_t cb) {
++ jobject jinetAddr;
++ jbyteArray value;
++
++ if (cb == GSS_C_NO_CHANNEL_BINDINGS) return;
++
++ /* release initiator address */
++ if (cb->initiator_addrtype != GSS_C_AF_NULLADDR) {
++ resetGSSBuffer(&(cb->initiator_address));
++ }
++ /* release acceptor address */
++ if (cb->acceptor_addrtype != GSS_C_AF_NULLADDR) {
++ resetGSSBuffer(&(cb->acceptor_address));
++ }
++ /* release application data */
++ if (cb->application_data.length != 0) {
++ resetGSSBuffer(&(cb->application_data));
++ }
++ free(cb);
++}
+
+ /*
+ * Utility routine which creates a gss_channel_bindings_t structure
+ * using the specified org.ietf.jgss.ChannelBinding object.
++ * NOTE: must call deleteGSSCB() to free up the resources.
+ */
+-gss_channel_bindings_t getGSSCB(JNIEnv *env, jobject jcb) {
++gss_channel_bindings_t newGSSCB(JNIEnv *env, jobject jcb) {
+ gss_channel_bindings_t cb;
+ jobject jinetAddr;
+ jbyteArray value;
++ int i;
+
+ if (jcb == NULL) {
+ return GSS_C_NO_CHANNEL_BINDINGS;
+ }
+
+ cb = malloc(sizeof(struct gss_channel_bindings_struct));
+-
+ if (cb == NULL) {
+ throwOutOfMemoryError(env,NULL);
+ return NULL;
+ }
+
++ // initialize addrtype in CB first
++ cb->initiator_addrtype = GSS_C_AF_NULLADDR;
++ cb->acceptor_addrtype = GSS_C_AF_NULLADDR;
++
+ /* set up initiator address */
+- jinetAddr =
+- (*env)->CallObjectMethod(env, jcb,
+- MID_ChannelBinding_getInitiatorAddr);
++ jinetAddr = (*env)->CallObjectMethod(env, jcb,
++ MID_ChannelBinding_getInitiatorAddr);
++ if ((*env)->ExceptionCheck(env)) {
++ goto cleanup;
++ }
+ if (jinetAddr != NULL) {
+- cb->initiator_addrtype = GSS_C_AF_INET;
+ value = (*env)->CallObjectMethod(env, jinetAddr,
+ MID_InetAddress_getAddr);
++ if ((*env)->ExceptionCheck(env)) {
++ goto cleanup;
++ }
++ cb->initiator_addrtype = GSS_C_AF_INET;
+ initGSSBuffer(env, value, &(cb->initiator_address));
+- } else {
+- cb->initiator_addrtype = GSS_C_AF_NULLADDR;
+- cb->initiator_address.length = 0;
+- cb->initiator_address.value = NULL;
++ if ((*env)->ExceptionCheck(env)) {
++ goto cleanup;
++ }
+ }
+ /* set up acceptor address */
+- jinetAddr =
+- (*env)->CallObjectMethod(env, jcb,
+- MID_ChannelBinding_getAcceptorAddr);
++ jinetAddr = (*env)->CallObjectMethod(env, jcb,
++ MID_ChannelBinding_getAcceptorAddr);
++ if ((*env)->ExceptionCheck(env)) {
++ goto cleanup;
++ }
+ if (jinetAddr != NULL) {
+- cb->acceptor_addrtype = GSS_C_AF_INET;
+ value = (*env)->CallObjectMethod(env, jinetAddr,
+ MID_InetAddress_getAddr);
++ if ((*env)->ExceptionCheck(env)) {
++ goto cleanup;
++ }
++ cb->acceptor_addrtype = GSS_C_AF_INET;
+ initGSSBuffer(env, value, &(cb->acceptor_address));
+- } else {
+- cb->acceptor_addrtype = GSS_C_AF_NULLADDR;
+- cb->acceptor_address.length = 0;
+- cb->acceptor_address.value = NULL;
++ if ((*env)->ExceptionCheck(env)) {
++ goto cleanup;
++ }
+ }
+ /* set up application data */
+ value = (*env)->CallObjectMethod(env, jcb,
+ MID_ChannelBinding_getAppData);
+- if (value != NULL) {
+- initGSSBuffer(env, value, &(cb->application_data));
+- } else {
+- cb->application_data.length = 0;
+- cb->application_data.value = NULL;
++ if ((*env)->ExceptionCheck(env)) {
++ goto cleanup;
++ }
++ initGSSBuffer(env, value, &(cb->application_data));
++ if ((*env)->ExceptionCheck(env)) {
++ goto cleanup;
+ }
+ return cb;
+-}
+-
+-/*
+- * Utility routine which releases the specified gss_channel_bindings_t
+- * structure.
+- */
+-void releaseGSSCB(JNIEnv *env, jobject jcb, gss_channel_bindings_t cb) {
+- jobject jinetAddr;
+- jbyteArray value;
+-
+- if (cb == GSS_C_NO_CHANNEL_BINDINGS) return;
+- /* release initiator address */
+- if (cb->initiator_addrtype != GSS_C_AF_NULLADDR) {
+- jinetAddr =
+- (*env)->CallObjectMethod(env, jcb,
+- MID_ChannelBinding_getInitiatorAddr);
+- value = (*env)->CallObjectMethod(env, jinetAddr,
+- MID_InetAddress_getAddr);
+- resetGSSBuffer(env, value, &(cb->initiator_address));
+- }
+- /* release acceptor address */
+- if (cb->acceptor_addrtype != GSS_C_AF_NULLADDR) {
+- jinetAddr =
+- (*env)->CallObjectMethod(env, jcb,
+- MID_ChannelBinding_getAcceptorAddr);
+- value = (*env)->CallObjectMethod(env, jinetAddr,
+- MID_InetAddress_getAddr);
+- resetGSSBuffer(env, value, &(cb->acceptor_address));
+- }
+- /* release application data */
+- if (cb->application_data.length != 0) {
+- value = (*env)->CallObjectMethod(env, jcb,
+- MID_ChannelBinding_getAppData);
+- resetGSSBuffer(env, value, &(cb->application_data));
+- }
+- free(cb);
++cleanup:
++ deleteGSSCB(cb);
++ return NULL;
+ }
+
+ /*
+@@ -230,6 +237,9 @@
+ isUnseq = ((suppInfo & GSS_S_UNSEQ_TOKEN) != 0);
+ hasGap = ((suppInfo & GSS_S_GAP_TOKEN) != 0);
+ minorMsg = getMinorMessage(env, jstub, minor);
++ if ((*env)->ExceptionCheck(env)) {
++ return;
++ }
+ (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setSupplementaryStates,
+ isDuplicate, isOld, isUnseq, hasGap, minor,
+ minorMsg);
+@@ -265,21 +275,26 @@
+ jobjectArray result;
+
+ if (ftab->inquireNamesForMech != NULL) {
++ mech = (gss_OID)jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech));
++ nameTypes = GSS_C_NO_OID_SET;
+
+- mech = (gss_OID)jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech));
+- nameTypes = GSS_C_NO_OID_SET;
++ /* gss_inquire_names_for_mech(...) => N/A */
++ major = (*ftab->inquireNamesForMech)(&minor, mech, &nameTypes);
+
+- /* gss_inquire_names_for_mech(...) => N/A */
+- major = (*ftab->inquireNamesForMech)(&minor, mech, &nameTypes);
++ /* release intermediate buffers before checking status */
++ result = getJavaOIDArray(env, nameTypes);
++ deleteGSSOIDSet(nameTypes);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+
+- result = getJavaOIDArray(env, nameTypes);
+-
+- /* release intermediate buffers */
+- deleteGSSOIDSet(nameTypes);
+-
+- checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireNamesForMech]");
+- return result;
+- } else return NULL;
++ checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireNamesForMech]");
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
++ return result;
++ }
++ return NULL;
+ }
+
+ /*
+@@ -297,8 +312,7 @@
+
+ nameHdl = (gss_name_t) jlong_to_ptr(pName);
+
+- sprintf(debugBuf, "[GSSLibStub_releaseName] %ld", (long) pName);
+- debug(env, debugBuf);
++ TRACE1("[GSSLibStub_releaseName] %ld", (long) pName);
+
+ if (nameHdl != GSS_C_NO_NAME) {
+ /* gss_release_name(...) => GSS_S_BAD_NAME */
+@@ -324,13 +338,16 @@
+ gss_name_t nameHdl;
+ nameHdl = GSS_C_NO_NAME;
+
+- debug(env, "[GSSLibStub_importName]");
++ TRACE0("[GSSLibStub_importName]");
+
+ initGSSBuffer(env, jnameVal, &nameVal);
++ if ((*env)->ExceptionCheck(env)) {
++ return jlong_zero;
++ }
++
+ nameType = newGSSOID(env, jnameType);
+ if ((*env)->ExceptionCheck(env)) {
+- deleteGSSOID(nameType);
+- resetGSSBuffer(env, jnameVal, &nameVal);
++ resetGSSBuffer(&nameVal);
+ return jlong_zero;
+ }
+
+@@ -338,14 +355,16 @@
+ GSS_S_BAD_MECH */
+ major = (*ftab->importName)(&minor, &nameVal, nameType, &nameHdl);
+
+- sprintf(debugBuf, "[GSSLibStub_importName] %ld", (long) nameHdl);
+- debug(env, debugBuf);
++ TRACE1("[GSSLibStub_importName] %ld", (long) nameHdl);
+
+ /* release intermediate buffers */
+ deleteGSSOID(nameType);
+- resetGSSBuffer(env, jnameVal, &nameVal);
++ resetGSSBuffer(&nameVal);
+
+ checkStatus(env, jobj, major, minor, "[GSSLibStub_importName]");
++ if ((*env)->ExceptionCheck(env)) {
++ return jlong_zero;
++ }
+ return ptr_to_jlong(nameHdl);
+ }
+
+@@ -369,9 +388,7 @@
+ nameHdl1 = (gss_name_t) jlong_to_ptr(pName1);
+ nameHdl2 = (gss_name_t) jlong_to_ptr(pName2);
+
+- sprintf(debugBuf, "[GSSLibStub_compareName] %ld %ld", (long) pName1,
+- (long) pName2);
+- debug(env, debugBuf);
++ TRACE2("[GSSLibStub_compareName] %ld %ld", (long)pName1, (long)pName2);
+
+ if ((nameHdl1 != GSS_C_NO_NAME) && (nameHdl2 != GSS_C_NO_NAME)) {
+
+@@ -398,8 +415,8 @@
+ gss_OID mech;
+
+ nameHdl = (gss_name_t) jlong_to_ptr(pName);
+- sprintf(debugBuf, "[GSSLibStub_canonicalizeName] %ld", (long) pName);
+- debug(env, debugBuf);
++
++ TRACE1("[GSSLibStub_canonicalizeName] %ld", (long) pName);
+
+ if (nameHdl != GSS_C_NO_NAME) {
+ mech = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech));
+@@ -409,16 +426,15 @@
+ GSS_S_BAD_NAME, GSS_S_BAD_MECH */
+ major = (*ftab->canonicalizeName)(&minor, nameHdl, mech, &mnNameHdl);
+
+- sprintf(debugBuf, "[GSSLibStub_canonicalizeName] MN=%ld",
+- (long)mnNameHdl);
+- debug(env, debugBuf);
+-
+- /* release intermediate buffers */
++ TRACE1("[GSSLibStub_canonicalizeName] MN=%ld", (long)mnNameHdl);
+
+ checkStatus(env, jobj, major, minor, "[GSSLibStub_canonicalizeName]");
+- } else mnNameHdl = GSS_C_NO_NAME;
+-
+- return ptr_to_jlong(mnNameHdl);
++ if ((*env)->ExceptionCheck(env)) {
++ return (jlong) GSS_C_NO_NAME;
++ }
++ return ptr_to_jlong(mnNameHdl);
++ }
++ return (jlong) GSS_C_NO_NAME;
+ }
+
+ /*
+@@ -436,8 +452,8 @@
+ jbyteArray jresult;
+
+ nameHdl = (gss_name_t) jlong_to_ptr(pName);
+- sprintf(debugBuf, "[GSSLibStub_exportName] %ld", (long) pName);
+- debug(env, debugBuf);
++
++ TRACE1("[GSSLibStub_exportName] %ld", (long) pName);
+
+ /* gss_export_name(...) => GSS_S_NAME_NOT_MN, GSS_S_BAD_NAMETYPE,
+ GSS_S_BAD_NAME */
+@@ -445,28 +461,38 @@
+
+ /* canonicalize the internal name to MN and retry */
+ if (major == GSS_S_NAME_NOT_MN) {
+- debug(env, "[GSSLibStub_exportName] canonicalize and re-try");
++ /* release intermediate buffers before retrying */
++ (*ftab->releaseBuffer)(&minor, &outBuf);
++
++ TRACE0("[GSSLibStub_exportName] canonicalize and re-try");
+
+ mNameHdl = (gss_name_t)jlong_to_ptr(
+ Java_sun_security_jgss_wrapper_GSSLibStub_canonicalizeName
+ (env, jobj, pName));
+- /* return immediately if an exception has occurred */
+ if ((*env)->ExceptionCheck(env)) {
+- return NULL;
++ return NULL;
+ }
++
+ major = (*ftab->exportName)(&minor, mNameHdl, &outBuf);
+ Java_sun_security_jgss_wrapper_GSSLibStub_releaseName
+ (env, jobj, ptr_to_jlong(mNameHdl));
+- /* return immediately if an exception has occurred */
+ if ((*env)->ExceptionCheck(env)) {
++ /* release intermediate buffers */
++ (*ftab->releaseBuffer)(&minor, &outBuf);
+ return NULL;
+ }
+ }
+
+- /* release intermediate buffers */
++ /* release intermediate buffers before checking status */
+ jresult = getJavaBuffer(env, &outBuf);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+
+ checkStatus(env, jobj, major, minor, "[GSSLibStub_exportName]");
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+ return jresult;
+ }
+
+@@ -488,8 +514,8 @@
+ jobjectArray jresult;
+
+ nameHdl = (gss_name_t) jlong_to_ptr(pName);
+- sprintf(debugBuf, "[GSSLibStub_displayName] %ld", (long) pName);
+- debug(env, debugBuf);
++
++ TRACE1("[GSSLibStub_displayName] %ld", (long) pName);
+
+ if (nameHdl == GSS_C_NO_NAME) {
+ checkStatus(env, jobj, GSS_S_BAD_NAME, 0, "[GSSLibStub_displayName]");
+@@ -499,21 +525,37 @@
+ /* gss_display_name(...) => GSS_S_BAD_NAME */
+ major = (*ftab->displayName)(&minor, nameHdl, &outNameBuf, &outNameType);
+
+- /* release intermediate buffers */
++ /* release intermediate buffers before checking status */
+ jname = getJavaString(env, &outNameBuf);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
++
++ checkStatus(env, jobj, major, minor, "[GSSLibStub_displayName]");
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+
+ jtype = getJavaOID(env, outNameType);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
++
+ jresult = (*env)->NewObjectArray(env, 2, CLS_Object, NULL);
+-
+ /* return immediately if an exception has occurred */
+ if ((*env)->ExceptionCheck(env)) {
+ return NULL;
+ }
+
+ (*env)->SetObjectArrayElement(env, jresult, 0, jname);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+ (*env)->SetObjectArrayElement(env, jresult, 1, jtype);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+
+- checkStatus(env, jobj, major, minor, "[GSSLibStub_displayName]");
+ return jresult;
+ }
+
+@@ -537,20 +579,14 @@
+ gss_cred_id_t credHdl;
+ credHdl = GSS_C_NO_CREDENTIAL;
+
+- debug(env, "[GSSLibStub_acquireCred]");
+-
++ TRACE0("[GSSLibStub_acquireCred]");
+
+ mech = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech));
+- mechs = newGSSOIDSet(env, mech);
+- if ((*env)->ExceptionCheck(env)) {
+- return jlong_zero;
+- }
++ mechs = newGSSOIDSet(mech);
+ credUsage = (gss_cred_usage_t) usage;
+ nameHdl = (gss_name_t) jlong_to_ptr(pName);
+
+- sprintf(debugBuf, "[GSSLibStub_acquireCred] pName=%ld, usage=%d",
+- (long) pName, usage);
+- debug(env, debugBuf);
++ TRACE2("[GSSLibStub_acquireCred] pName=%ld, usage=%d", (long)pName, usage);
+
+ /* gss_acquire_cred(...) => GSS_S_BAD_MECH, GSS_S_BAD_NAMETYPE,
+ GSS_S_BAD_NAME, GSS_S_CREDENTIALS_EXPIRED, GSS_S_NO_CRED */
+@@ -560,10 +596,12 @@
+ /* release intermediate buffers */
+ deleteGSSOIDSet(mechs);
+
+- sprintf(debugBuf, "[GSSLibStub_acquireCred] pCred=%ld", (long) credHdl);
+- debug(env, debugBuf);
++ TRACE1("[GSSLibStub_acquireCred] pCred=%ld", (long) credHdl);
+
+ checkStatus(env, jobj, major, minor, "[GSSLibStub_acquireCred]");
++ if ((*env)->ExceptionCheck(env)) {
++ return jlong_zero;
++ }
+ return ptr_to_jlong(credHdl);
+ }
+
+@@ -582,15 +620,16 @@
+
+ credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
+
+- sprintf(debugBuf, "[GSSLibStub_releaseCred] %ld", (long int)pCred);
+- debug(env, debugBuf);
++ TRACE1("[GSSLibStub_releaseCred] %ld", (long int)pCred);
+
+ if (credHdl != GSS_C_NO_CREDENTIAL) {
+-
+ /* gss_release_cred(...) => GSS_S_NO_CRED(!) */
+ major = (*ftab->releaseCred)(&minor, &credHdl);
+
+ checkStatus(env, jobj, major, minor, "[GSSLibStub_releaseCred]");
++ if ((*env)->ExceptionCheck(env)) {
++ return jlong_zero;
++ }
+ }
+ return ptr_to_jlong(credHdl);
+ }
+@@ -600,14 +639,13 @@
+ */
+ void inquireCred(JNIEnv *env, jobject jobj, gss_cred_id_t pCred,
+ jint type, void *result) {
+- OM_uint32 minor, major=0;
++ OM_uint32 minor=0, major=0;
+ OM_uint32 routineErr;
+ gss_cred_id_t credHdl;
+
+ credHdl = pCred;
+
+- sprintf(debugBuf, "[gss_inquire_cred] %ld", (long) pCred);
+- debug(env, debugBuf);
++ TRACE1("[gss_inquire_cred] %ld", (long) pCred);
+
+ /* gss_inquire_cred(...) => GSS_S_DEFECTIVE_CREDENTIAL(!),
+ GSS_S_CREDENTIALS_EXPIRED(!), GSS_S_NO_CRED(!) */
+@@ -619,8 +657,6 @@
+ major = (*ftab->inquireCred)(&minor, credHdl, NULL, NULL, result, NULL);
+ }
+
+- /* release intermediate buffers */
+-
+ routineErr = GSS_ROUTINE_ERROR(major);
+ if (routineErr == GSS_S_CREDENTIALS_EXPIRED) {
+ /* ignore GSS_S_CREDENTIALS_EXPIRED for query */
+@@ -649,20 +685,16 @@
+
+ credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
+
+- sprintf(debugBuf, "[GSSLibStub_getCredName] %ld", (long int)pCred);
+- debug(env, debugBuf);
++ TRACE1("[GSSLibStub_getCredName] %ld", (long int)pCred);
+
+ nameHdl = GSS_C_NO_NAME;
+ inquireCred(env, jobj, credHdl, TYPE_CRED_NAME, &nameHdl);
+-
+ /* return immediately if an exception has occurred */
+ if ((*env)->ExceptionCheck(env)) {
+ return jlong_zero;
+ }
+
+- sprintf(debugBuf, "[GSSLibStub_getCredName] pName=%ld", (long) nameHdl);
+- debug(env, debugBuf);
+-
++ TRACE1("[GSSLibStub_getCredName] pName=%ld", (long) nameHdl);
+ return ptr_to_jlong(nameHdl);
+ }
+
+@@ -681,12 +713,10 @@
+
+ credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
+
+- sprintf(debugBuf, "[GSSLibStub_getCredTime] %ld", (long int)pCred);
+- debug(env, debugBuf);
++ TRACE1("[GSSLibStub_getCredTime] %ld", (long int)pCred);
+
+ lifetime = 0;
+ inquireCred(env, jobj, credHdl, TYPE_CRED_TIME, &lifetime);
+-
+ /* return immediately if an exception has occurred */
+ if ((*env)->ExceptionCheck(env)) {
+ return 0;
+@@ -709,11 +739,9 @@
+
+ credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
+
+- sprintf(debugBuf, "[GSSLibStub_getCredUsage] %ld", (long int)pCred);
+- debug(env, debugBuf);
++ TRACE1("[GSSLibStub_getCredUsage] %ld", (long int)pCred);
+
+ inquireCred(env, jobj, credHdl, TYPE_CRED_USAGE, &usage);
+-
+ /* return immediately if an exception has occurred */
+ if ((*env)->ExceptionCheck(env)) {
+ return -1;
+@@ -735,21 +763,22 @@
+ gss_ctx_id_t contextHdl;
+ gss_OID mech, mech2;
+
+- debug(env, "[GSSLibStub_importContext]");
++ TRACE0("[GSSLibStub_importContext]");
+
+ contextHdl = GSS_C_NO_CONTEXT;
+ initGSSBuffer(env, jctxtToken, &ctxtToken);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+
+ /* gss_import_sec_context(...) => GSS_S_NO_CONTEXT, GSS_S_DEFECTIVE_TOKEN,
+ GSS_S_UNAVAILABLE, GSS_S_UNAUTHORIZED */
+ major = (*ftab->importSecContext)(&minor, &ctxtToken, &contextHdl);
+
+- sprintf(debugBuf, "[GSSLibStub_importContext] pContext=%ld",
+- (long) contextHdl);
+- debug(env, debugBuf);
++ TRACE1("[GSSLibStub_importContext] pContext=%ld", (long) contextHdl);
+
+ /* release intermediate buffers */
+- resetGSSBuffer(env, jctxtToken, &ctxtToken);
++ resetGSSBuffer(&ctxtToken);
+
+ checkStatus(env, jobj, major, minor, "[GSSLibStub_importContext]");
+ /* return immediately if an exception has occurred */
+@@ -768,9 +797,10 @@
+ return NULL;
+ }
+
+- mech2 = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech));
++ mech2 = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj,
++ FID_GSSLibStub_pMech));
+
+- if (sameMech(env, mech, mech2) == JNI_TRUE) {
++ if (sameMech(mech, mech2) == JNI_TRUE) {
+ /* mech match - return the context object */
+ return (*env)->NewObject(env, CLS_NativeGSSContext,
+ MID_NativeGSSContext_ctor,
+@@ -779,10 +809,11 @@
+ /* mech mismatch - clean up then return null */
+ major = (*ftab->deleteSecContext)(&minor, &contextHdl, GSS_C_NO_BUFFER);
+ checkStatus(env, jobj, major, minor,
+- "[GSSLibStub_importContext] cleanup");
++ "[GSSLibStub_importContext] cleanup");
+ return NULL;
+ }
+ }
++
+ /*
+ * Class: sun_security_jgss_wrapper_GSSLibStub
+ * Method: initContext
+@@ -812,7 +843,8 @@
+ gss_OID aMech;
+ jobject jMech;
+ */
+- debug(env, "[GSSLibStub_initContext]");
++
++ TRACE0("[GSSLibStub_initContext]");
+
+ credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
+ contextHdl = (gss_ctx_id_t) jlong_to_ptr(
+@@ -823,18 +855,19 @@
+ FID_NativeGSSContext_flags);
+ time = getGSSTime((*env)->GetIntField(env, jcontextSpi,
+ FID_NativeGSSContext_lifetime));
+- cb = getGSSCB(env, jcb);
++ cb = newGSSCB(env, jcb);
+ if ((*env)->ExceptionCheck(env)) {
+- free(cb);
+ return NULL;
+ }
+
+ initGSSBuffer(env, jinToken, &inToken);
++ if ((*env)->ExceptionCheck(env)) {
++ deleteGSSCB(cb);
++ return NULL;
++ }
+
+- sprintf(debugBuf,
+- "[GSSLibStub_initContext] before: pCred=%ld, pContext=%ld",
++ TRACE2( "[GSSLibStub_initContext] before: pCred=%ld, pContext=%ld",
+ (long)credHdl, (long)contextHdl);
+- debug(env, debugBuf);
+
+ /* gss_init_sec_context(...) => GSS_S_CONTINUE_NEEDED(!),
+ GSS_S_DEFECTIVE_TOKEN, GSS_S_NO_CRED, GSS_S_DEFECTIVE_CREDENTIAL(!),
+@@ -842,29 +875,24 @@
+ GSS_S_OLD_TOKEN, GSS_S_DUPLICATE_TOKEN, GSS_S_NO_CONTEXT(!),
+ GSS_S_BAD_NAMETYPE, GSS_S_BAD_NAME(!), GSS_S_BAD_MECH */
+ major = (*ftab->initSecContext)(&minor, credHdl,
+- &contextHdl, targetName, mech,
+- flags, time, cb, &inToken, NULL /*aMech*/,
+- &outToken, &aFlags, &aTime);
++ &contextHdl, targetName, mech,
++ flags, time, cb, &inToken, NULL /*aMech*/,
++ &outToken, &aFlags, &aTime);
+
+- sprintf(debugBuf, "[GSSLibStub_initContext] after: pContext=%ld",
+- (long)contextHdl);
+- debug(env, debugBuf);
+- sprintf(debugBuf, "[GSSLibStub_initContext] outToken len=%ld",
+- (long)outToken.length);
+- debug(env, debugBuf);
++ TRACE2("[GSSLibStub_initContext] after: pContext=%ld, outToken len=%ld",
++ (long)contextHdl, (long)outToken.length);
+
+ if (GSS_ERROR(major) == GSS_S_COMPLETE) {
+ /* update member values if needed */
+ (*env)->SetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext,
+ ptr_to_jlong(contextHdl));
+ (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_flags, aFlags);
+- sprintf(debugBuf, "[GSSLibStub_initContext] set flags=0x%x", aFlags);
+- debug(env, debugBuf);
++ TRACE1("[GSSLibStub_initContext] set flags=0x%x", aFlags);
+
+ if (major == GSS_S_COMPLETE) {
+ (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime,
+ getJavaTime(aTime));
+- debug(env, "[GSSLibStub_initContext] context established");
++ TRACE0("[GSSLibStub_initContext] context established");
+
+ (*env)->SetBooleanField(env, jcontextSpi,
+ FID_NativeGSSContext_isEstablished,
+@@ -876,16 +904,23 @@
+ FID_NativeGSSContext_actualMech, jMech);
+ */
+ } else if (major & GSS_S_CONTINUE_NEEDED) {
+- debug(env, "[GSSLibStub_initContext] context not established");
++ TRACE0("[GSSLibStub_initContext] context not established");
+ major -= GSS_S_CONTINUE_NEEDED;
+ }
+ }
+- /* release intermediate buffers */
+- releaseGSSCB(env, jcb, cb);
+- resetGSSBuffer(env, jinToken, &inToken);
++
++ /* release intermediate buffers before checking status */
++ deleteGSSCB(cb);
++ resetGSSBuffer(&inToken);
+ jresult = getJavaBuffer(env, &outToken);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+
+ checkStatus(env, jobj, major, minor, "[GSSLibStub_initContext]");
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+ return jresult;
+ }
+
+@@ -922,27 +957,27 @@
+ gss_name_t targetName;
+ jobject jtargetName;
+
+- debug(env, "[GSSLibStub_acceptContext]");
++ TRACE0("[GSSLibStub_acceptContext]");
+
+ contextHdl = (gss_ctx_id_t)jlong_to_ptr(
+ (*env)->GetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext));
+ credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
+ initGSSBuffer(env, jinToken, &inToken);
+- cb = getGSSCB(env, jcb);
+ if ((*env)->ExceptionCheck(env)) {
+- free(cb);
+- resetGSSBuffer(env, jinToken, &inToken);
+ return NULL;
+ }
+- srcName = GSS_C_NO_NAME;
++ cb = newGSSCB(env, jcb);
++ if ((*env)->ExceptionCheck(env)) {
++ resetGSSBuffer(&inToken);
++ return NULL;
++ }
++ srcName = targetName = GSS_C_NO_NAME;
+ delCred = GSS_C_NO_CREDENTIAL;
+ setTarget = (credHdl == GSS_C_NO_CREDENTIAL);
+ aFlags = 0;
+
+- sprintf(debugBuf,
+- "[GSSLibStub_acceptContext] before: pCred=%ld, pContext=%ld",
++ TRACE2( "[GSSLibStub_acceptContext] before: pCred=%ld, pContext=%ld",
+ (long) credHdl, (long) contextHdl);
+- debug(env, debugBuf);
+
+ /* gss_accept_sec_context(...) => GSS_S_CONTINUE_NEEDED(!),
+ GSS_S_DEFECTIVE_TOKEN, GSS_S_DEFECTIVE_CREDENTIAL(!),
+@@ -953,91 +988,107 @@
+ (*ftab->acceptSecContext)(&minor, &contextHdl, credHdl,
+ &inToken, cb, &srcName, &aMech, &outToken,
+ &aFlags, &aTime, &delCred);
++ /* release intermediate buffers before checking status */
+
+- sprintf(debugBuf,
+- "[GSSLibStub_acceptContext] after: pCred=%ld, pContext=%ld, pDelegCred=%ld",
++ deleteGSSCB(cb);
++ resetGSSBuffer(&inToken);
++
++ TRACE3("[GSSLibStub_acceptContext] after: pCred=%ld, pContext=%ld, pDelegCred=%ld",
+ (long)credHdl, (long)contextHdl, (long) delCred);
+- debug(env, debugBuf);
+
+ if (GSS_ERROR(major) == GSS_S_COMPLETE) {
+ /* update member values if needed */
+ (*env)->SetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext,
+ ptr_to_jlong(contextHdl));
+- sprintf(debugBuf, "[GSSLibStub_acceptContext] set pContext=%ld",
++ TRACE1("[GSSLibStub_acceptContext] set pContext=%ld",
+ (long)contextHdl);
+- debug(env, debugBuf);
++
+ // WORKAROUND for a Heimdal bug
+ if (delCred == GSS_C_NO_CREDENTIAL) {
+ aFlags &= 0xfffffffe;
+ }
+ (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_flags, aFlags);
+- sprintf(debugBuf, "[GSSLibStub_acceptContext] set flags=0x%x",
+- aFlags);
+- debug(env, debugBuf);
++
++ TRACE1("[GSSLibStub_acceptContext] set flags=0x%x", aFlags);
++
+ if (setTarget) {
+ major2 = (*ftab->inquireContext)(&minor2, contextHdl, NULL,
+ &targetName, NULL, NULL, NULL,
+ NULL, NULL);
++ checkStatus(env, jobj, major2, minor2,
++ "[GSSLibStub_acceptContext] inquire");
++ if ((*env)->ExceptionCheck(env)) {
++ goto error;
++ }
++
+ jtargetName = (*env)->NewObject(env, CLS_GSSNameElement,
+ MID_GSSNameElement_ctor,
+ ptr_to_jlong(targetName), jobj);
++ if ((*env)->ExceptionCheck(env)) {
++ goto error;
++ }
+
+- /* return immediately if an exception has occurred */
+- if ((*env)->ExceptionCheck(env)) {
+- resetGSSBuffer(env, jinToken, &inToken);
+- return NULL;
+- }
+- sprintf(debugBuf, "[GSSLibStub_acceptContext] set targetName=%ld",
++ TRACE1("[GSSLibStub_acceptContext] set targetName=%ld",
+ (long)targetName);
+- debug(env, debugBuf);
++
+ (*env)->SetObjectField(env, jcontextSpi, FID_NativeGSSContext_targetName,
+ jtargetName);
++ if ((*env)->ExceptionCheck(env)) {
++ goto error;
++ }
+ }
+ if (srcName != GSS_C_NO_NAME) {
+ jsrcName = (*env)->NewObject(env, CLS_GSSNameElement,
+ MID_GSSNameElement_ctor,
+ ptr_to_jlong(srcName), jobj);
+- /* return immediately if an exception has occurred */
+ if ((*env)->ExceptionCheck(env)) {
+- resetGSSBuffer(env, jinToken, &inToken);
+- return NULL;
++ goto error;
+ }
+- sprintf(debugBuf, "[GSSLibStub_acceptContext] set srcName=%ld",
+- (long)srcName);
+- debug(env, debugBuf);
++
++ TRACE1("[GSSLibStub_acceptContext] set srcName=%ld", (long)srcName);
++
+ (*env)->SetObjectField(env, jcontextSpi, FID_NativeGSSContext_srcName,
+ jsrcName);
++ if ((*env)->ExceptionCheck(env)) {
++ goto error;
++ }
+ }
+ if (major == GSS_S_COMPLETE) {
+- debug(env, "[GSSLibStub_acceptContext] context established");
++ TRACE0("[GSSLibStub_acceptContext] context established");
+
+ (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime,
+ getJavaTime(aTime));
+-
+ (*env)->SetBooleanField(env, jcontextSpi,
+ FID_NativeGSSContext_isEstablished,
+ JNI_TRUE);
+ jMech = getJavaOID(env, aMech);
++ if ((*env)->ExceptionCheck(env)) {
++ goto error;
++ }
+ (*env)->SetObjectField(env, jcontextSpi,
+ FID_NativeGSSContext_actualMech, jMech);
++ if ((*env)->ExceptionCheck(env)) {
++ goto error;
++ }
+ if (delCred != GSS_C_NO_CREDENTIAL) {
+ jdelCred = (*env)->NewObject(env, CLS_GSSCredElement,
+ MID_GSSCredElement_ctor,
+ ptr_to_jlong(delCred), jsrcName, jMech);
+- /* return immediately if an exception has occurred */
+ if ((*env)->ExceptionCheck(env)) {
+- resetGSSBuffer(env, jinToken, &inToken);
+- return NULL;
++ goto error;
+ }
+ (*env)->SetObjectField(env, jcontextSpi,
+ FID_NativeGSSContext_delegatedCred,
+ jdelCred);
+- sprintf(debugBuf, "[GSSLibStub_acceptContext] set delegatedCred=%ld",
++ TRACE1("[GSSLibStub_acceptContext] set delegatedCred=%ld",
+ (long) delCred);
+- debug(env, debugBuf);
++
++ if ((*env)->ExceptionCheck(env)) {
++ goto error;
++ }
+ }
+ } else if (major & GSS_S_CONTINUE_NEEDED) {
+- debug(env, "[GSSLibStub_acceptContext] context not established");
++ TRACE0("[GSSLibStub_acceptContext] context not established");
+
+ if (aFlags & GSS_C_PROT_READY_FLAG) {
+ (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime,
+@@ -1046,13 +1097,20 @@
+ major -= GSS_S_CONTINUE_NEEDED;
+ }
+ }
+- /* release intermediate buffers */
+- releaseGSSCB(env, jcb, cb);
+- resetGSSBuffer(env, jinToken, &inToken);
+- jresult = getJavaBuffer(env, &outToken);
++ return getJavaBuffer(env, &outToken);
+
+- checkStatus(env, jobj, major, minor, "[GSSLibStub_acceptContext]");
+- return jresult;
++error:
++ (*ftab->releaseBuffer)(&minor, &outToken);
++ if (srcName != GSS_C_NO_NAME) {
++ (*ftab->releaseName)(&minor, &srcName);
++ }
++ if (targetName != GSS_C_NO_NAME) {
++ (*ftab->releaseName)(&minor, &targetName);
++ }
++ if (delCred != GSS_C_NO_CREDENTIAL) {
++ (*ftab->releaseCred) (&minor, &delCred);
++ }
++ return NULL;
+ }
+
+ /*
+@@ -1076,8 +1134,7 @@
+
+ contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
+
+- sprintf(debugBuf, "[GSSLibStub_inquireContext] %ld", (long)contextHdl);
+- debug(env, debugBuf);
++ TRACE1("[GSSLibStub_inquireContext] %ld", (long)contextHdl);
+
+ srcName = targetName = GSS_C_NO_NAME;
+ time = 0;
+@@ -1088,12 +1145,13 @@
+ &targetName, &time, NULL, &flags,
+ &isInitiator, &isEstablished);
+ /* update member values if needed */
+- sprintf(debugBuf, "[GSSLibStub_inquireContext] srcName %ld", (long)srcName);
+- debug(env, debugBuf);
+- sprintf(debugBuf, "[GSSLibStub_inquireContext] targetName %ld",
+- (long)targetName);
+- debug(env, debugBuf);
++ TRACE2("[GSSLibStub_inquireContext] srcName %ld, targetName %ld",
++ (long)srcName, (long)targetName);
+
++ checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireContext]");
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+ result[0] = ptr_to_jlong(srcName);
+ result[1] = ptr_to_jlong(targetName);
+ result[2] = (jlong) isInitiator;
+@@ -1102,11 +1160,13 @@
+ result[5] = (jlong) getJavaTime(time);
+
+ jresult = (*env)->NewLongArray(env, 6);
++ if (jresult == NULL) {
++ return NULL;
++ }
+ (*env)->SetLongArrayRegion(env, jresult, 0, 6, result);
+-
+- /* release intermediate buffers */
+-
+- checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireContext]");
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+ return jresult;
+ }
+
+@@ -1126,8 +1186,7 @@
+
+ contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
+
+- sprintf(debugBuf, "[GSSLibStub_getContextMech] %ld", (long int)pContext);
+- debug(env, debugBuf);
++ TRACE1("[GSSLibStub_getContextMech] %ld", (long int)pContext);
+
+ major = (*ftab->inquireContext)(&minor, contextHdl, NULL, NULL,
+ NULL, &mech, NULL, NULL, NULL);
+@@ -1156,9 +1215,8 @@
+
+ contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
+
+- sprintf(debugBuf, "[GSSLibStub_getContextName] %ld, isSrc=%d",
++ TRACE2("[GSSLibStub_getContextName] %ld, isSrc=%d",
+ (long)contextHdl, isSrc);
+- debug(env, debugBuf);
+
+ nameHdl = GSS_C_NO_NAME;
+ if (isSrc == JNI_TRUE) {
+@@ -1175,8 +1233,7 @@
+ return jlong_zero;
+ }
+
+- sprintf(debugBuf, "[GSSLibStub_getContextName] pName=%ld", (long) nameHdl);
+- debug(env, debugBuf);
++ TRACE1("[GSSLibStub_getContextName] pName=%ld", (long) nameHdl);
+
+ return ptr_to_jlong(nameHdl);
+ }
+@@ -1195,8 +1252,8 @@
+ OM_uint32 time;
+
+ contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
+- sprintf(debugBuf, "[GSSLibStub_getContextTime] %ld", (long)contextHdl);
+- debug(env, debugBuf);
++
++ TRACE1("[GSSLibStub_getContextTime] %ld", (long)contextHdl);
+
+ if (contextHdl == GSS_C_NO_CONTEXT) return 0;
+
+@@ -1207,6 +1264,9 @@
+ major = GSS_CALLING_ERROR(major) | GSS_SUPPLEMENTARY_INFO(major);
+ }
+ checkStatus(env, jobj, major, minor, "[GSSLibStub_getContextTime]");
++ if ((*env)->ExceptionCheck(env)) {
++ return 0;
++ }
+ return getJavaTime(time);
+ }
+
+@@ -1224,8 +1284,8 @@
+ gss_ctx_id_t contextHdl;
+
+ contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
+- sprintf(debugBuf, "[GSSLibStub_deleteContext] %ld", (long)contextHdl);
+- debug(env, debugBuf);
++
++ TRACE1("[GSSLibStub_deleteContext] %ld", (long)contextHdl);
+
+ if (contextHdl == GSS_C_NO_CONTEXT) return ptr_to_jlong(GSS_C_NO_CONTEXT);
+
+@@ -1233,6 +1293,9 @@
+ major = (*ftab->deleteSecContext)(&minor, &contextHdl, GSS_C_NO_BUFFER);
+
+ checkStatus(env, jobj, major, minor, "[GSSLibStub_deleteContext]");
++ if ((*env)->ExceptionCheck(env)) {
++ return jlong_zero;
++ }
+ return (jlong) ptr_to_jlong(contextHdl);
+ }
+
+@@ -1255,20 +1318,27 @@
+ gss_qop_t qop;
+
+ contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
+- sprintf(debugBuf, "[GSSLibStub_wrapSizeLimit] %ld", (long)contextHdl);
+- debug(env, debugBuf);
+
+- // Check context handle??
++ TRACE1("[GSSLibStub_wrapSizeLimit] %ld", (long)contextHdl);
++
++ if (contextHdl == GSS_C_NO_CONTEXT) {
++ // Twik per javadoc
++ checkStatus(env, jobj, GSS_S_NO_CONTEXT, 0,
++ "[GSSLibStub_wrapSizeLimit]");
++ return 0;
++ }
+
+ qop = (gss_qop_t) jqop;
+ outSize = (OM_uint32) joutSize;
+- maxInSize = 0;
+ /* gss_wrap_size_limit(...) => GSS_S_NO_CONTEXT(!), GSS_S_CONTEXT_EXPIRED,
+ GSS_S_BAD_QOP */
+ major = (*ftab->wrapSizeLimit)(&minor, contextHdl, reqFlag,
+ qop, outSize, &maxInSize);
+
+ checkStatus(env, jobj, major, minor, "[GSSLibStub_wrapSizeLimit]");
++ if ((*env)->ExceptionCheck(env)) {
++ return 0;
++ }
+ return (jint) maxInSize;
+ }
+
+@@ -1288,8 +1358,8 @@
+ jbyteArray jresult;
+
+ contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
+- sprintf(debugBuf, "[GSSLibStub_exportContext] %ld", (long)contextHdl);
+- debug(env, debugBuf);
++
++ TRACE1("[GSSLibStub_exportContext] %ld", (long)contextHdl);
+
+ if (contextHdl == GSS_C_NO_CONTEXT) {
+ // Twik per javadoc
+@@ -1303,7 +1373,14 @@
+
+ /* release intermediate buffers */
+ jresult = getJavaBuffer(env, &interProcToken);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+ checkStatus(env, jobj, major, minor, "[GSSLibStub_exportContext]");
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
++
+ return jresult;
+ }
+
+@@ -1325,8 +1402,8 @@
+ jbyteArray jresult;
+
+ contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
+- sprintf(debugBuf, "[GSSLibStub_getMic] %ld", (long)contextHdl);
+- debug(env, debugBuf);
++
++ TRACE1("[GSSLibStub_getMic] %ld", (long)contextHdl);
+
+ if (contextHdl == GSS_C_NO_CONTEXT) {
+ // Twik per javadoc
+@@ -1336,6 +1413,9 @@
+ contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
+ qop = (gss_qop_t) jqop;
+ initGSSBuffer(env, jmsg, &msg);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+
+ /* gss_get_mic(...) => GSS_S_CONTEXT_EXPIRED, GSS_S_NO_CONTEXT(!),
+ GSS_S_BAD_QOP */
+@@ -1343,10 +1423,16 @@
+ (*ftab->getMic)(&minor, contextHdl, qop, &msg, &msgToken);
+
+ /* release intermediate buffers */
+- resetGSSBuffer(env, jmsg, &msg);
++ resetGSSBuffer(&msg);
+ jresult = getJavaBuffer(env, &msgToken);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
++ checkStatus(env, jobj, major, minor, "[GSSLibStub_getMic]");
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+
+- checkStatus(env, jobj, major, minor, "[GSSLibStub_getMic]");
+ return jresult;
+ }
+
+@@ -1370,8 +1456,8 @@
+ gss_qop_t qop;
+
+ contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
+- sprintf(debugBuf, "[GSSLibStub_verifyMic] %ld", (long)contextHdl);
+- debug(env, debugBuf);
++
++ TRACE1("[GSSLibStub_verifyMic] %ld", (long)contextHdl);
+
+ if (contextHdl == GSS_C_NO_CONTEXT) {
+ // Twik per javadoc
+@@ -1379,9 +1465,19 @@
+ "[GSSLibStub_verifyMic]");
+ return;
+ }
++
++ qop = (gss_qop_t) (*env)->CallIntMethod(env, jprop, MID_MessageProp_getQOP);
++ if ((*env)->ExceptionCheck(env)) { return; }
++
+ initGSSBuffer(env, jmsg, &msg);
++ if ((*env)->ExceptionCheck(env)) { return; }
++
+ initGSSBuffer(env, jmsgToken, &msgToken);
+- qop = (gss_qop_t) (*env)->CallIntMethod(env, jprop, MID_MessageProp_getQOP);
++ if ((*env)->ExceptionCheck(env)) {
++ resetGSSBuffer(&msg);
++ return;
++ }
++
+ /* gss_verify_mic(...) => GSS_S_DEFECTIVE_TOKEN, GSS_S_BAD_MIC,
+ GSS_S_CONTEXT_EXPIRED, GSS_S_DUPLICATE_TOKEN(!), GSS_S_OLD_TOKEN(!),
+ GSS_S_UNSEQ_TOKEN(!), GSS_S_GAP_TOKEN(!), GSS_S_NO_CONTEXT(!) */
+@@ -1389,13 +1485,24 @@
+ (*ftab->verifyMic)(&minor, contextHdl, &msg, &msgToken, &qop);
+
+ /* release intermediate buffers */
+- resetGSSBuffer(env, jmsg, &msg);
+- resetGSSBuffer(env, jmsgToken, &msgToken);
++ resetGSSBuffer(&msg);
++ resetGSSBuffer(&msgToken);
++
++ checkStatus(env, jobj, GSS_ERROR(major), minor, "[GSSLibStub_verifyMic]");
++ if ((*env)->ExceptionCheck(env)) {
++ return;
++ }
+
+ (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setQOP, qop);
++ if ((*env)->ExceptionCheck(env)) {
++ return;
++ }
++
+ setSupplementaryInfo(env, jobj, jprop, GSS_SUPPLEMENTARY_INFO(major),
+ minor);
+- checkStatus(env, jobj, GSS_ERROR(major), minor, "[GSSLibStub_verifyMic]");
++ if ((*env)->ExceptionCheck(env)) {
++ return;
++ }
+ }
+
+ /*
+@@ -1420,8 +1527,8 @@
+ jbyteArray jresult;
+
+ contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
+- sprintf(debugBuf, "[GSSLibStub_wrap] %ld", (long)contextHdl);
+- debug(env, debugBuf);
++
++ TRACE1("[GSSLibStub_wrap] %ld", (long)contextHdl);
+
+ if (contextHdl == GSS_C_NO_CONTEXT) {
+ // Twik per javadoc
+@@ -1431,22 +1538,43 @@
+
+ confFlag =
+ (*env)->CallBooleanMethod(env, jprop, MID_MessageProp_getPrivacy);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
++
+ qop = (gss_qop_t)
+ (*env)->CallIntMethod(env, jprop, MID_MessageProp_getQOP);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
++
+ initGSSBuffer(env, jmsg, &msg);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
++
+ /* gss_wrap(...) => GSS_S_CONTEXT_EXPIRED, GSS_S_NO_CONTEXT(!),
+ GSS_S_BAD_QOP */
+ major = (*ftab->wrap)(&minor, contextHdl, confFlag, qop, &msg, &confState,
+ &msgToken);
+
++ /* release intermediate buffers */
++ resetGSSBuffer(&msg);
++ jresult = getJavaBuffer(env, &msgToken);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
++
++ checkStatus(env, jobj, major, minor, "[GSSLibStub_wrap]");
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
++
+ (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setPrivacy,
+ (confState? JNI_TRUE:JNI_FALSE));
+-
+- /* release intermediate buffers */
+- resetGSSBuffer(env, jmsg, &msg);
+- jresult = getJavaBuffer(env, &msgToken);
+-
+- checkStatus(env, jobj, major, minor, "[GSSLibStub_wrap]");
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+ return jresult;
+ }
+
+@@ -1471,15 +1599,20 @@
+ jbyteArray jresult;
+
+ contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
+- sprintf(debugBuf, "[GSSLibStub_unwrap] %ld", (long)contextHdl);
+- debug(env, debugBuf);
++
++ TRACE1("[GSSLibStub_unwrap] %ld", (long)contextHdl);
+
+ if (contextHdl == GSS_C_NO_CONTEXT) {
+ // Twik per javadoc
+ checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_unwrap]");
+ return NULL;
+ }
++
+ initGSSBuffer(env, jmsgToken, &msgToken);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
++
+ confState = 0;
+ qop = GSS_C_QOP_DEFAULT;
+ /* gss_unwrap(...) => GSS_S_DEFECTIVE_TOKEN, GSS_S_BAD_MIC,
+@@ -1487,17 +1620,34 @@
+ GSS_S_UNSEQ_TOKEN(!), GSS_S_GAP_TOKEN(!), GSS_S_NO_CONTEXT(!) */
+ major =
+ (*ftab->unwrap)(&minor, contextHdl, &msgToken, &msg, &confState, &qop);
++
++ /* release intermediate buffers */
++ resetGSSBuffer(&msgToken);
++ jresult = getJavaBuffer(env, &msg);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
++
++ checkStatus(env, jobj, GSS_ERROR(major), minor, "[GSSLibStub_unwrap]");
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
++
+ /* update the message prop with relevant info */
+ (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setPrivacy,
+ (confState != 0));
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+ (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setQOP, qop);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+ setSupplementaryInfo(env, jobj, jprop, GSS_SUPPLEMENTARY_INFO(major),
+- minor);
++ minor);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+
+- /* release intermediate buffers */
+- resetGSSBuffer(env, jmsgToken, &msgToken);
+- jresult = getJavaBuffer(env, &msg);
+-
+- checkStatus(env, jobj, GSS_ERROR(major), minor, "[GSSLibStub_unwrap]");
+ return jresult;
+ }
+--- ./jdk/src/share/native/sun/security/jgss/wrapper/NativeUtil.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/security/jgss/wrapper/NativeUtil.c Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -28,8 +28,6 @@
+ #include "jlong.h"
+ #include <jni.h>
+
+-extern void throwOutOfMemoryError(JNIEnv *env, const char *message);
+-
+ const int JAVA_DUPLICATE_TOKEN_CODE = 19; /* DUPLICATE_TOKEN */
+ const int JAVA_OLD_TOKEN_CODE = 20; /* OLD_TOKEN */
+ const int JAVA_UNSEQ_TOKEN_CODE = 21; /* UNSEQ_TOKEN */
+@@ -82,7 +80,6 @@
+ jmethodID MID_GSSNameElement_ctor;
+ jmethodID MID_GSSCredElement_ctor;
+ jmethodID MID_NativeGSSContext_ctor;
+-jmethodID MID_SunNativeProvider_debug;
+ jfieldID FID_GSSLibStub_pMech;
+ jfieldID FID_NativeGSSContext_pContext;
+ jfieldID FID_NativeGSSContext_srcName;
+@@ -93,7 +90,8 @@
+ jfieldID FID_NativeGSSContext_flags;
+ jfieldID FID_NativeGSSContext_lifetime;
+ jfieldID FID_NativeGSSContext_actualMech;
+-char debugBuf[256];
++
++int JGSS_DEBUG;
+
+ JNIEXPORT jint JNICALL
+ JNI_OnLoad(JavaVM *jvm, void *reserved) {
+@@ -291,13 +289,6 @@
+ printf("Couldn't find NativeGSSContext(long, GSSLibStub) constructor\n");
+ return JNI_ERR;
+ }
+- MID_SunNativeProvider_debug =
+- (*env)->GetStaticMethodID(env, CLS_SunNativeProvider, "debug",
+- "(Ljava/lang/String;)V");
+- if (MID_SunNativeProvider_debug == NULL) {
+- printf("Couldn't find SunNativeProvider.debug(String) method\n");
+- return JNI_ERR;
+- }
+ /* Compute and cache the field ID */
+ cls = (*env)->FindClass(env, "sun/security/jgss/wrapper/GSSLibStub");
+ if (cls == NULL) {
+@@ -448,14 +439,28 @@
+ }
+ return GSS_S_COMPLETE;
+ }
++
++
++/* Throws a Java Exception by name */
++void throwByName(JNIEnv *env, const char *name, const char *msg) {
++ jclass cls = (*env)->FindClass(env, name);
++
++ if (cls != NULL) {
++ (*env)->ThrowNew(env, cls, msg);
++ }
++}
++
++void throwOutOfMemoryError(JNIEnv *env, const char *message) {
++ throwByName(env, "java/lang/OutOfMemoryError", message);
++}
++
+ /*
+ * Utility routine for creating a java.lang.String object
+- * using the specified gss_buffer_t structure. After the,
+- * String object is created, the specified gss_buffer_t
+- * structure is released.
++ * using the specified gss_buffer_t structure. The specified
++ * gss_buffer_t structure is always released.
+ */
+ jstring getJavaString(JNIEnv *env, gss_buffer_t bytes) {
+- jstring result;
++ jstring result = NULL;
+ OM_uint32 minor;
+ int len;
+ jbyteArray jbytes;
+@@ -465,9 +470,18 @@
+ NOTE: do NOT include the trailing NULL */
+ len = bytes->length;
+ jbytes = (*env)->NewByteArray(env, len);
++ if (jbytes == NULL) {
++ goto finish;
++ }
++
+ (*env)->SetByteArrayRegion(env, jbytes, 0, len, (jbyte *) bytes->value);
++ if ((*env)->ExceptionCheck(env)) {
++ goto finish;
++ }
++
+ result = (*env)->NewObject(env, CLS_String, MID_String_ctor,
+ jbytes);
++ finish:
+ (*env)->DeleteLocalRef(env, jbytes);
+ (*ftab->releaseBuffer)(&minor, bytes);
+ return result;
+@@ -490,14 +504,15 @@
+ } else {
+ mech = GSS_C_NO_OID;
+ }
++
+ /* gss_display_status(...) => GSS_S_BAD_MECH, GSS_S_BAD_STATUS */
++ // TBD: check messageContext value and repeat the call if necessary
+ major = (*ftab->displayStatus)(&minor, statusValue, GSS_C_MECH_CODE, mech,
+- &messageContext, &statusString);
+- /* release intermediate buffers */
+- msg = getJavaString(env, &statusString);
+- (*ftab->releaseBuffer)(&minor, &statusString);
+- return msg;
++ &messageContext, &statusString);
++
++ return getJavaString(env, &statusString);
+ }
++
+ /*
+ * Utility routine checking the specified major and minor
+ * status codes. GSSExceptions will be thrown if they are
+@@ -517,11 +532,9 @@
+ routineErr = GSS_ROUTINE_ERROR(major);
+ supplementaryInfo = GSS_SUPPLEMENTARY_INFO(major);
+
+- sprintf(debugBuf, "%s Status major/minor = %x/%d", methodName, major, minor);
+- debug(env, debugBuf);
+- sprintf(debugBuf, "%s Status c/r/s = %d/%d/%d ", methodName, callingErr>>24,
+- routineErr>>16, supplementaryInfo);
+- debug(env, debugBuf);
++ TRACE3("%s Status major/minor = %x/%d", methodName, major, minor);
++ TRACE3("c/r/s = %d/%d/%d ", callingErr>>24, routineErr>>16,
++ supplementaryInfo);
+
+ jmajor = getJavaErrorCode(routineErr | supplementaryInfo);
+ jminor = minor;
+@@ -529,11 +542,17 @@
+ jmsg = NULL;
+ if (minor != 0) {
+ jmsg = getMinorMessage(env, jstub, minor);
++ if ((*env)->ExceptionCheck(env)) {
++ return;
++ }
+ }
++
+ gssEx = (*env)->NewObject(env, CLS_GSSException,
+ MID_GSSException_ctor3,
+ jmajor, jminor, jmsg);
+- (*env)->Throw(env, gssEx);
++ if (gssEx != NULL) {
++ (*env)->Throw(env, gssEx);
++ }
+ } else {
+ /* Error in calling the GSS api */
+ if (callingErr == GSS_S_CALL_INACCESSIBLE_READ) {
+@@ -545,56 +564,88 @@
+ }
+ jmajor = 13; /* use GSSException.FAILURE for now */
+ jmsg = (*env)->NewStringUTF(env, msg);
++ if (jmsg == NULL) {
++ return;
++ }
+ gssEx = (*env)->NewObject(env, CLS_GSSException,
+ MID_GSSException_ctor3,
+ jmajor, jminor, jmsg);
+- (*env)->Throw(env, gssEx);
++ if (gssEx != NULL) {
++ (*env)->Throw(env, gssEx);
++ }
+ }
+ }
++
+ /*
+ * Utility routine for initializing gss_buffer_t structure
+ * with the byte[] in the specified jbyteArray object.
+- * NOTE: need to call resetGSSBuffer(...) to free up
+- * the resources.
++ * NOTE: must call resetGSSBuffer() to free up the resources
++ * inside the gss_buffer_t structure.
+ */
+ void initGSSBuffer(JNIEnv *env, jbyteArray jbytes,
+- gss_buffer_t cbytes) {
++ gss_buffer_t cbytes) {
++
++ int len;
++ void* value;
++
+ if (jbytes != NULL) {
+- cbytes->length = (*env)->GetArrayLength(env, jbytes);
+- cbytes->value = (*env)->GetByteArrayElements(env, jbytes, NULL);
++ len = (*env)->GetArrayLength(env, jbytes);
++ value = malloc(len);
++ if (value == NULL) {
++ throwOutOfMemoryError(env, NULL);
++ return;
++ } else {
++ (*env)->GetByteArrayRegion(env, jbytes, 0, len, value);
++ if ((*env)->ExceptionCheck(env)) {
++ free(value);
++ return;
++ } else {
++ cbytes->length = len;
++ cbytes->value = value;
++ }
++ }
+ } else {
+ cbytes->length = 0;
+ cbytes->value = NULL;
+ }
+ }
++
+ /*
+- * Utility routine for unpinning/releasing the byte[]
+- * associated with the specified jbyteArray object.
++ * Utility routine for freeing the bytes malloc'ed
++ * in initGSSBuffer() method.
+ * NOTE: used in conjunction with initGSSBuffer(...).
+ */
+-void resetGSSBuffer(JNIEnv *env, jbyteArray jbytes,
+- gss_buffer_t cbytes) {
+- if ((cbytes != NULL) && (cbytes != GSS_C_NO_BUFFER) &&
+- (cbytes->length != 0)) {
+- (*env)->ReleaseByteArrayElements(env, jbytes, cbytes->value,
+- JNI_ABORT);
++void resetGSSBuffer(gss_buffer_t cbytes) {
++ if ((cbytes != NULL) && (cbytes != GSS_C_NO_BUFFER)) {
++ free(cbytes->value);
++ cbytes->length = 0;
++ cbytes->value = NULL;
+ }
+ }
++
+ /*
+ * Utility routine for creating a jbyteArray object using
+ * the byte[] value in specified gss_buffer_t structure.
+- * NOTE: the specified gss_buffer_t structure will be
+- * released in this routine.
++ * NOTE: the specified gss_buffer_t structure is always
++ * released.
+ */
+ jbyteArray getJavaBuffer(JNIEnv *env, gss_buffer_t cbytes) {
+- jbyteArray result;
++ jbyteArray result = NULL;
+ OM_uint32 minor; // don't care, just so it compiles
+
+- if ((cbytes != NULL) && (cbytes != GSS_C_NO_BUFFER) &&
+- (cbytes->length != 0)) {
+- result = (*env)->NewByteArray(env, cbytes->length);
+- (*env)->SetByteArrayRegion(env, result, 0, cbytes->length,
+- cbytes->value);
++ if (cbytes != NULL) {
++ if ((cbytes != GSS_C_NO_BUFFER) && (cbytes->length != 0)) {
++ result = (*env)->NewByteArray(env, cbytes->length);
++ if (result == NULL) {
++ goto finish;
++ }
++ (*env)->SetByteArrayRegion(env, result, 0, cbytes->length,
++ cbytes->value);
++ if ((*env)->ExceptionCheck(env)) {
++ result = NULL;
++ }
++ }
++ finish:
+ (*ftab->releaseBuffer)(&minor, cbytes);
+ return result;
+ }
+@@ -604,8 +655,7 @@
+ /*
+ * Utility routine for creating a non-mech gss_OID using
+ * the specified org.ietf.jgss.Oid object.
+- * NOTE: need to call deleteGSSOID(...) afterwards to
+- * release the created gss_OID structure.
++ * NOTE: must call deleteGSSOID(...) to free up the gss_OID.
+ */
+ gss_OID newGSSOID(JNIEnv *env, jobject jOid) {
+ jbyteArray jbytes;
+@@ -614,8 +664,7 @@
+ if (jOid != NULL) {
+ jbytes = (*env)->CallObjectMethod(env, jOid, MID_Oid_getDER);
+ if ((*env)->ExceptionCheck(env)) {
+- gssEx = (*env)->ExceptionOccurred(env);
+- (*env)->Throw(env, gssEx);
++ return GSS_C_NO_OID;
+ }
+ cOid = malloc(sizeof(struct gss_OID_desc_struct));
+ if (cOid == NULL) {
+@@ -626,17 +675,24 @@
+ cOid->elements = malloc(cOid->length);
+ if (cOid->elements == NULL) {
+ throwOutOfMemoryError(env,NULL);
+- free(cOid);
+- return GSS_C_NO_OID;
++ goto cleanup;
+ }
+ (*env)->GetByteArrayRegion(env, jbytes, 2, cOid->length,
+ cOid->elements);
+- (*env)->DeleteLocalRef(env, jbytes);
++ if ((*env)->ExceptionCheck(env)) {
++ goto cleanup;
++ }
+ return cOid;
+ } else {
+ return GSS_C_NO_OID;
+ }
++ cleanup:
++ (*env)->DeleteLocalRef(env, jbytes);
++ free(cOid->elements);
++ free(cOid);
++ return GSS_C_NO_OID;
+ }
++
+ /*
+ * Utility routine for releasing the specified gss_OID
+ * structure.
+@@ -648,6 +704,7 @@
+ free(oid);
+ }
+ }
++
+ /*
+ * Utility routine for creating a org.ietf.jgss.Oid
+ * object using the specified gss_OID structure.
+@@ -656,7 +713,7 @@
+ int cLen;
+ char oidHdr[2];
+ jbyteArray jbytes;
+- jobject result;
++ jobject result = NULL;
+
+ if ((cOid == NULL) || (cOid == GSS_C_NO_OID)) {
+ return NULL;
+@@ -665,12 +722,20 @@
+ oidHdr[0] = 6;
+ oidHdr[1] = cLen;
+ jbytes = (*env)->NewByteArray(env, cLen+2);
++ if (jbytes == NULL) {
++ return NULL;
++ }
+ (*env)->SetByteArrayRegion(env, jbytes, 0, 2, (jbyte *) oidHdr);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+ (*env)->SetByteArrayRegion(env, jbytes, 2, cLen, (jbyte *) cOid->elements);
+-
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
+ result = (*env)->NewObject(env, CLS_Oid, MID_Oid_ctor1, jbytes);
+ if ((*env)->ExceptionCheck(env)) {
+- (*env)->Throw(env, (*env)->ExceptionOccurred(env));
++ return NULL;
+ }
+ (*env)->DeleteLocalRef(env, jbytes);
+ return result;
+@@ -681,7 +746,7 @@
+ * NOTE: need to call deleteGSSOIDSet(...) afterwards
+ * to release the created gss_OID_set structure.
+ */
+-gss_OID_set newGSSOIDSet(JNIEnv *env, gss_OID oid) {
++gss_OID_set newGSSOIDSet(gss_OID oid) {
+ gss_OID_set oidSet;
+ OM_uint32 minor; // don't care; just so it compiles
+
+@@ -722,26 +787,26 @@
+ if (cOidSet != NULL && cOidSet != GSS_C_NO_OID_SET) {
+ numOfOids = cOidSet->count;
+ jOidSet = (*env)->NewObjectArray(env, numOfOids, CLS_Oid, NULL);
+- if (jOidSet != NULL) {
+- for (i = 0; i < numOfOids; i++) {
+- jOid = getJavaOID(env, &(cOidSet->elements[i]));
+- (*env)->SetObjectArrayElement(env, jOidSet, i, jOid);
+- (*env)->DeleteLocalRef(env, jOid);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
++ for (i = 0; i < numOfOids; i++) {
++ jOid = getJavaOID(env, &(cOidSet->elements[i]));
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
+ }
++ (*env)->SetObjectArrayElement(env, jOidSet, i, jOid);
++ if ((*env)->ExceptionCheck(env)) {
++ return NULL;
++ }
++ (*env)->DeleteLocalRef(env, jOid);
+ }
+ return jOidSet;
+ }
+ return NULL;
+ }
+
+-void debug(JNIEnv *env, char *msg) {
+- jstring jmsg = (*env)->NewStringUTF(env, msg);
+- (*env)->CallStaticVoidMethod(env, CLS_SunNativeProvider,
+- MID_SunNativeProvider_debug, jmsg);
+- (*env)->DeleteLocalRef(env, jmsg);
+-}
+-
+-int sameMech(JNIEnv *env, gss_OID mech, gss_OID mech2) {
++int sameMech(gss_OID mech, gss_OID mech2) {
+ int result = JNI_FALSE; // default to not equal
+
+ if (mech->length == mech2->length) {
+--- ./jdk/src/share/native/sun/security/jgss/wrapper/NativeUtil.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/security/jgss/wrapper/NativeUtil.h Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -37,12 +37,13 @@
+ extern OM_uint32 getGSSTime(jint);
+ extern void checkStatus(JNIEnv *, jobject, OM_uint32, OM_uint32, char*);
+ extern jint checkTime(OM_uint32);
++ extern void throwOutOfMemoryError(JNIEnv *, const char*);
+ extern void initGSSBuffer(JNIEnv *, jbyteArray, gss_buffer_t);
+- extern void resetGSSBuffer(JNIEnv *, jbyteArray, gss_buffer_t);
++ extern void resetGSSBuffer(gss_buffer_t);
+
+ extern gss_OID newGSSOID(JNIEnv *, jobject);
+ extern void deleteGSSOID(gss_OID);
+- extern gss_OID_set newGSSOIDSet(JNIEnv *, gss_OID);
++ extern gss_OID_set newGSSOIDSet(gss_OID);
+ extern void deleteGSSOIDSet(gss_OID_set);
+
+ extern jbyteArray getJavaBuffer(JNIEnv *, gss_buffer_t);
+@@ -51,13 +52,12 @@
+ extern jobjectArray getJavaOIDArray(JNIEnv *, gss_OID_set);
+
+ extern jstring getMinorMessage(JNIEnv *, jobject, OM_uint32);
+- extern void debug(JNIEnv *, char *);
+- extern int sameMech(JNIEnv *, gss_OID, gss_OID);
++ extern int sameMech(gss_OID, gss_OID);
+
+ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *, void *);
+ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *, void *);
+
+- extern char debugBuf[];
++ extern int JGSS_DEBUG;
+
+ extern jclass CLS_Object;
+ extern jclass CLS_GSSNameElement;
+@@ -85,6 +85,12 @@
+ extern jfieldID FID_NativeGSSContext_flags;
+ extern jfieldID FID_NativeGSSContext_lifetime;
+ extern jfieldID FID_NativeGSSContext_actualMech;
++ #define TRACE0(s) { if (JGSS_DEBUG) { puts(s); fflush(stdout); }}
++ #define TRACE1(s, p1) { if (JGSS_DEBUG) { printf(s"\n", p1); fflush(stdout); }}
++ #define TRACE2(s, p1, p2) { if (JGSS_DEBUG) { printf(s"\n", p1, p2); fflush(stdout); }}
++ #define TRACE3(s, p1, p2, p3) { if (JGSS_DEBUG) { printf(s"\n", p1, p2, p3); fflush(stdout); }}
++
++
+ #ifdef __cplusplus
+ }
+ #endif
+--- ./jdk/src/share/native/sun/security/krb5/nativeccache.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/security/krb5/nativeccache.c Wed Feb 04 12:14:43 2015 -0800
+@@ -141,7 +141,7 @@
+ #endif /* DEBUG */
+
+ ticketConstructor = (*env)->GetMethodID(env, ticketClass, "<init>", "(Lsun/security/util/DerValue;)V");
+- if (derValueConstructor == 0) {
++ if (ticketConstructor == 0) {
+ printf("Couldn't find Ticket constructor\n");
+ return JNI_ERR;
+ }
+@@ -272,6 +272,7 @@
+ }
+ return 0;
+ }
++
+ /*
+ * Class: sun_security_krb5_Credentials
+ * Method: acquireDefaultNativeCreds
+@@ -309,7 +310,7 @@
+ netypes = (*env)->GetArrayLength(env, jetypes);
+ etypes = (jint *) (*env)->GetIntArrayElements(env, jetypes, NULL);
+
+- if (!err) {
++ if (etypes != NULL && !err) {
+ while ((err = krb5_cc_next_cred (kcontext, ccache, &cursor, &creds)) == 0) {
+ char *serverName = NULL;
+
+@@ -319,8 +320,16 @@
+ }
+
+ if (!err) {
+- if (strncmp (serverName, "krbtgt", sizeof("krbtgt")-1) == 0 &&
+- isIn(creds.keyblock.enctype, netypes, etypes)) {
++ char* slash = strchr(serverName, '/');
++ char* at = strchr(serverName, '@');
++ // Make sure the server's name is krbtgt/REALM@REALM, the etype
++ // is supported, and the ticket has not expired
++ if (slash && at &&
++ strncmp (serverName, "krbtgt", slash-serverName) == 0 &&
++ // the ablove line shows at must be after slash
++ strncmp (slash+1, at+1, at-slash-1) == 0 &&
++ isIn (creds.keyblock.enctype, netypes, etypes) &&
++ creds.times.endtime > time(0)) {
+ jobject ticket, clientPrincipal, targetPrincipal, encryptionKey;
+ jobject ticketFlags, startTime, endTime;
+ jobject authTime, renewTillTime, hostAddresses;
+@@ -399,8 +408,12 @@
+ if (endTime) (*env)->DeleteLocalRef(env, endTime);
+ if (renewTillTime) (*env)->DeleteLocalRef(env, renewTillTime);
+ if (hostAddresses) (*env)->DeleteLocalRef(env, hostAddresses);
++
++ // Stop if there is an exception or we already found the initial TGT
++ if ((*env)->ExceptionCheck(env) || krbCreds) {
++ break;
++ }
+ }
+-
+ }
+
+ if (serverName != NULL) { krb5_free_unparsed_name (kcontext, serverName); }
+@@ -410,7 +423,6 @@
+
+ if (err == KRB5_CC_END) { err = 0; }
+ printiferr (err, "while retrieving a ticket");
+-
+ }
+
+ if (!err) {
+@@ -445,25 +457,25 @@
+ jbyteArray ary;
+
+ ary = (*env)->NewByteArray(env, encodedTicket->length);
+- if ((*env)->ExceptionOccurred(env)) {
++ if ((*env)->ExceptionCheck(env)) {
+ return (jobject) NULL;
+ }
+
+ (*env)->SetByteArrayRegion(env, ary, (jsize) 0, encodedTicket->length, (jbyte *)encodedTicket->data);
+- if ((*env)->ExceptionOccurred(env)) {
++ if ((*env)->ExceptionCheck(env)) {
+ (*env)->DeleteLocalRef(env, ary);
+ return (jobject) NULL;
+ }
+
+ derValue = (*env)->NewObject(env, derValueClass, derValueConstructor, ary);
+- if ((*env)->ExceptionOccurred(env)) {
++ if ((*env)->ExceptionCheck(env)) {
+ (*env)->DeleteLocalRef(env, ary);
+ return (jobject) NULL;
+ }
+
+ (*env)->DeleteLocalRef(env, ary);
+ ticket = (*env)->NewObject(env, ticketClass, ticketConstructor, derValue);
+- if ((*env)->ExceptionOccurred(env)) {
++ if ((*env)->ExceptionCheck(env)) {
+ (*env)->DeleteLocalRef(env, derValue);
+ return (jobject) NULL;
+ }
+@@ -480,6 +492,10 @@
+ if (!err) {
+ // Make a PrincipalName from the full string and the type. Let the PrincipalName class parse it out.
+ jstring principalStringObj = (*env)->NewStringUTF(env, principalString);
++ if (principalStringObj == NULL) {
++ if (principalString != NULL) { krb5_free_unparsed_name (kcontext, principalString); }
++ return (jobject) NULL;
++ }
+ principal = (*env)->NewObject(env, principalNameClass, principalNameConstructor, principalStringObj, principalName->type);
+ if (principalString != NULL) { krb5_free_unparsed_name (kcontext, principalString); }
+ (*env)->DeleteLocalRef(env, principalStringObj);
+@@ -494,8 +510,13 @@
+ jobject encryptionKey = NULL;
+
+ ary = (*env)->NewByteArray(env,cryptoKey->length);
++
++ if (ary == NULL) {
++ return (jobject) NULL;
++ }
++
+ (*env)->SetByteArrayRegion(env, ary, (jsize) 0, cryptoKey->length, (jbyte *)cryptoKey->contents);
+- if (!(*env)->ExceptionOccurred(env)) {
++ if (!(*env)->ExceptionCheck(env)) {
+ encryptionKey = (*env)->NewObject(env, encryptionKeyClass, encryptionKeyConstructor, cryptoKey->enctype, ary);
+ }
+
+@@ -514,9 +535,14 @@
+ unsigned long nlflags = htonl(flags);
+
+ ary = (*env)->NewByteArray(env, sizeof(flags));
++
++ if (ary == NULL) {
++ return (jobject) NULL;
++ }
++
+ (*env)->SetByteArrayRegion(env, ary, (jsize) 0, sizeof(flags), (jbyte *)&nlflags);
+
+- if (!(*env)->ExceptionOccurred(env)) {
++ if (!(*env)->ExceptionCheck(env)) {
+ ticketFlags = (*env)->NewObject(env, ticketFlagsClass, ticketFlagsConstructor, sizeof(flags)*8, ary);
+ }
+
+@@ -550,6 +576,10 @@
+
+ jobject address_list = (*env)->NewObjectArray(env, addressCount, hostAddressClass, NULL);
+
++ if (address_list == NULL) {
++ return (jobject) NULL;
++ }
++
+ // Create a new HostAddress object for each address block.
+ // First, reset the iterator.
+ p = addresses;
+@@ -567,9 +597,16 @@
+
+ (*env)->DeleteLocalRef(env, ary);
+
++ if (address == NULL) {
++ return (jobject) NULL;
++ }
+ // Add the HostAddress to the arrray.
+ (*env)->SetObjectArrayElement(env, address_list, index, address);
+
++ if ((*env)->ExceptionCheck(env)) {
++ return (jobject) NULL;
++ }
++
+ index++;
+ p++;
+ }
+--- ./jdk/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c Wed Feb 04 12:14:43 2015 -0800
+@@ -141,8 +141,8 @@
+ (CK_BYTE_PTR)(outBufP + jOutOfs),
+ &ckEncryptedPartLen);
+
+- (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT);
+ (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
++ (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+
+ ckAssertReturnValueOK(env, rv);
+ return ckEncryptedPartLen;
+@@ -214,7 +214,7 @@
+ }
+
+ if (directOut == 0) {
+- (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT);
++ (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+ }
+
+ ckAssertReturnValueOK(env, rv);
+@@ -266,7 +266,7 @@
+ //printf("EF: ckLastEncryptedPartLen=%i", ckLastEncryptedPartLen);
+
+ if (directOut == 0) {
+- (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT);
++ (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+ }
+
+ ckAssertReturnValueOK(env, rv);
+@@ -361,8 +361,8 @@
+ (CK_BYTE_PTR)(outBufP + jOutOfs),
+ &ckPartLen);
+
+- (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT);
+ (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
++ (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+
+ ckAssertReturnValueOK(env, rv);
+
+@@ -429,7 +429,7 @@
+ }
+
+ if (directOut == 0) {
+- (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT);
++ (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+ }
+
+ ckAssertReturnValueOK(env, rv);
+@@ -478,7 +478,7 @@
+ &ckLastPartLen);
+
+ if (directOut == 0) {
+- (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT);
++ (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+
+ }
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/src/solaris/classes/java/lang/UNIXProcess.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,827 @@
++/*
++ * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 java.lang;
++
++import java.io.BufferedInputStream;
++import java.io.BufferedOutputStream;
++import java.io.ByteArrayInputStream;
++import java.io.FileDescriptor;
++import java.io.FileInputStream;
++import java.io.FileOutputStream;
++import java.io.IOException;
++import java.io.InputStream;
++import java.io.OutputStream;
++import java.util.Arrays;
++import java.util.EnumSet;
++import java.util.Locale;
++import java.util.Set;
++import java.util.concurrent.Executors;
++import java.util.concurrent.Executor;
++import java.util.concurrent.ThreadFactory;
++import java.util.concurrent.TimeUnit;
++import java.security.AccessController;
++import static java.security.AccessController.doPrivileged;
++import java.security.PrivilegedAction;
++import java.security.PrivilegedActionException;
++import java.security.PrivilegedExceptionAction;
++
++/**
++ * java.lang.Process subclass in the UNIX environment.
++ *
++ * @author Mario Wolczko and Ross Knippel.
++ * @author Konstantin Kladko (ported to Linux and Bsd)
++ * @author Martin Buchholz
++ * @author Volker Simonis (ported to AIX)
++ */
++final class UNIXProcess extends Process {
++ private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
++ = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
++
++ private final int pid;
++ private int exitcode;
++ private boolean hasExited;
++
++ private /* final */ OutputStream stdin;
++ private /* final */ InputStream stdout;
++ private /* final */ InputStream stderr;
++
++ // only used on Solaris
++ private /* final */ DeferredCloseInputStream stdout_inner_stream;
++
++ private static enum LaunchMechanism {
++ // order IS important!
++ FORK,
++ POSIX_SPAWN,
++ VFORK
++ }
++
++ private static enum Platform {
++
++ LINUX(LaunchMechanism.VFORK, LaunchMechanism.FORK),
++
++ BSD(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK),
++
++ SOLARIS(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK),
++
++ AIX(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK);
++
++ final LaunchMechanism defaultLaunchMechanism;
++ final Set<LaunchMechanism> validLaunchMechanisms;
++
++ Platform(LaunchMechanism ... launchMechanisms) {
++ this.defaultLaunchMechanism = launchMechanisms[0];
++ this.validLaunchMechanisms =
++ EnumSet.copyOf(Arrays.asList(launchMechanisms));
++ }
++
++ private String helperPath(String javahome, String osArch) {
++ switch (this) {
++ case SOLARIS:
++ if (osArch.equals("x86")) { osArch = "i386"; }
++ else if (osArch.equals("x86_64")) { osArch = "amd64"; }
++ // fall through...
++ case LINUX:
++ case AIX:
++ return javahome + "/lib/" + osArch + "/jspawnhelper";
++
++ case BSD:
++ return javahome + "/lib/jspawnhelper";
++
++ default:
++ throw new AssertionError("Unsupported platform: " + this);
++ }
++ }
++
++ String helperPath() {
++ return AccessController.doPrivileged(
++ (PrivilegedAction<String>) () ->
++ helperPath(System.getProperty("java.home"),
++ System.getProperty("os.arch"))
++ );
++ }
++
++ LaunchMechanism launchMechanism() {
++ return AccessController.doPrivileged(
++ (PrivilegedAction<LaunchMechanism>) () -> {
++ String s = System.getProperty(
++ "jdk.lang.Process.launchMechanism");
++ LaunchMechanism lm;
++ if (s == null) {
++ lm = defaultLaunchMechanism;
++ s = lm.name().toLowerCase(Locale.ENGLISH);
++ } else {
++ try {
++ lm = LaunchMechanism.valueOf(
++ s.toUpperCase(Locale.ENGLISH));
++ } catch (IllegalArgumentException e) {
++ lm = null;
++ }
++ }
++ if (lm == null || !validLaunchMechanisms.contains(lm)) {
++ throw new Error(
++ s + " is not a supported " +
++ "process launch mechanism on this platform."
++ );
++ }
++ return lm;
++ }
++ );
++ }
++
++ static Platform get() {
++ String osName = AccessController.doPrivileged(
++ (PrivilegedAction<String>) () -> System.getProperty("os.name")
++ );
++
++ if (osName.equals("Linux")) { return LINUX; }
++ if (osName.contains("OS X")) { return BSD; }
++ if (osName.equals("SunOS")) { return SOLARIS; }
++ if (osName.equals("AIX")) { return AIX; }
++
++ throw new Error(osName + " is not a supported OS platform.");
++ }
++ }
++
++ private static final Platform platform = Platform.get();
++ private static final LaunchMechanism launchMechanism = platform.launchMechanism();
++ private static final byte[] helperpath = toCString(platform.helperPath());
++
++ private static byte[] toCString(String s) {
++ if (s == null)
++ return null;
++ byte[] bytes = s.getBytes();
++ byte[] result = new byte[bytes.length + 1];
++ System.arraycopy(bytes, 0,
++ result, 0,
++ bytes.length);
++ result[result.length-1] = (byte)0;
++ return result;
++ }
++
++ /* this is for the reaping thread */
++ private native int waitForProcessExit(int pid);
++
++ /**
++ * Creates a process. Depending on the {@code mode} flag, this is done by
++ * one of the following mechanisms:
++ * <pre>
++ * 1 - fork(2) and exec(2)
++ * 2 - posix_spawn(3P)
++ * 3 - vfork(2) and exec(2)
++ *
++ * (4 - clone(2) and exec(2) - obsolete and currently disabled in native code)
++ * </pre>
++ * @param fds an array of three file descriptors.
++ * Indexes 0, 1, and 2 correspond to standard input,
++ * standard output and standard error, respectively. On
++ * input, a value of -1 means to create a pipe to connect
++ * child and parent processes. On output, a value which
++ * is not -1 is the parent pipe fd corresponding to the
++ * pipe which has been created. An element of this array
++ * is -1 on input if and only if it is <em>not</em> -1 on
++ * output.
++ * @return the pid of the subprocess
++ */
++ private native int forkAndExec(int mode, byte[] helperpath,
++ byte[] prog,
++ byte[] argBlock, int argc,
++ byte[] envBlock, int envc,
++ byte[] dir,
++ int[] fds,
++ boolean redirectErrorStream)
++ throws IOException;
++
++ /**
++ * The thread pool of "process reaper" daemon threads.
++ */
++ private static final Executor processReaperExecutor =
++ doPrivileged((PrivilegedAction<Executor>) () -> {
++
++ ThreadGroup tg = Thread.currentThread().getThreadGroup();
++ while (tg.getParent() != null) tg = tg.getParent();
++ ThreadGroup systemThreadGroup = tg;
++
++ ThreadFactory threadFactory = grimReaper -> {
++ // Our thread stack requirement is quite modest.
++ Thread t = new Thread(systemThreadGroup, grimReaper,
++ "process reaper", 32768);
++ t.setDaemon(true);
++ // A small attempt (probably futile) to avoid priority inversion
++ t.setPriority(Thread.MAX_PRIORITY);
++ return t;
++ };
++
++ return Executors.newCachedThreadPool(threadFactory);
++ });
++
++ UNIXProcess(final byte[] prog,
++ final byte[] argBlock, final int argc,
++ final byte[] envBlock, final int envc,
++ final byte[] dir,
++ final int[] fds,
++ final boolean redirectErrorStream)
++ throws IOException {
++
++ pid = forkAndExec(launchMechanism.ordinal() + 1,
++ helperpath,
++ prog,
++ argBlock, argc,
++ envBlock, envc,
++ dir,
++ fds,
++ redirectErrorStream);
++
++ try {
++ doPrivileged((PrivilegedExceptionAction<Void>) () -> {
++ initStreams(fds);
++ return null;
++ });
++ } catch (PrivilegedActionException ex) {
++ throw (IOException) ex.getException();
++ }
++ }
++
++ static FileDescriptor newFileDescriptor(int fd) {
++ FileDescriptor fileDescriptor = new FileDescriptor();
++ fdAccess.set(fileDescriptor, fd);
++ return fileDescriptor;
++ }
++
++ void initStreams(int[] fds) throws IOException {
++ switch (platform) {
++ case LINUX:
++ case BSD:
++ stdin = (fds[0] == -1) ?
++ ProcessBuilder.NullOutputStream.INSTANCE :
++ new ProcessPipeOutputStream(fds[0]);
++
++ stdout = (fds[1] == -1) ?
++ ProcessBuilder.NullInputStream.INSTANCE :
++ new ProcessPipeInputStream(fds[1]);
++
++ stderr = (fds[2] == -1) ?
++ ProcessBuilder.NullInputStream.INSTANCE :
++ new ProcessPipeInputStream(fds[2]);
++
++ processReaperExecutor.execute(() -> {
++ int exitcode = waitForProcessExit(pid);
++
++ synchronized (this) {
++ this.exitcode = exitcode;
++ this.hasExited = true;
++ this.notifyAll();
++ }
++
++ if (stdout instanceof ProcessPipeInputStream)
++ ((ProcessPipeInputStream) stdout).processExited();
++
++ if (stderr instanceof ProcessPipeInputStream)
++ ((ProcessPipeInputStream) stderr).processExited();
++
++ if (stdin instanceof ProcessPipeOutputStream)
++ ((ProcessPipeOutputStream) stdin).processExited();
++ });
++ break;
++
++ case SOLARIS:
++ stdin = (fds[0] == -1) ?
++ ProcessBuilder.NullOutputStream.INSTANCE :
++ new BufferedOutputStream(
++ new FileOutputStream(newFileDescriptor(fds[0])));
++
++ stdout = (fds[1] == -1) ?
++ ProcessBuilder.NullInputStream.INSTANCE :
++ new BufferedInputStream(
++ stdout_inner_stream =
++ new DeferredCloseInputStream(
++ newFileDescriptor(fds[1])));
++
++ stderr = (fds[2] == -1) ?
++ ProcessBuilder.NullInputStream.INSTANCE :
++ new DeferredCloseInputStream(newFileDescriptor(fds[2]));
++
++ /*
++ * For each subprocess forked a corresponding reaper task
++ * is submitted. That task is the only thread which waits
++ * for the subprocess to terminate and it doesn't hold any
++ * locks while doing so. This design allows waitFor() and
++ * exitStatus() to be safely executed in parallel (and they
++ * need no native code).
++ */
++ processReaperExecutor.execute(() -> {
++ int exitcode = waitForProcessExit(pid);
++
++ synchronized (this) {
++ this.exitcode = exitcode;
++ this.hasExited = true;
++ this.notifyAll();
++ }
++ });
++ break;
++
++ case AIX:
++ stdin = (fds[0] == -1) ?
++ ProcessBuilder.NullOutputStream.INSTANCE :
++ new ProcessPipeOutputStream(fds[0]);
++
++ stdout = (fds[1] == -1) ?
++ ProcessBuilder.NullInputStream.INSTANCE :
++ new DeferredCloseProcessPipeInputStream(fds[1]);
++
++ stderr = (fds[2] == -1) ?
++ ProcessBuilder.NullInputStream.INSTANCE :
++ new DeferredCloseProcessPipeInputStream(fds[2]);
++
++ processReaperExecutor.execute(() -> {
++ int exitcode = waitForProcessExit(pid);
++
++ synchronized (this) {
++ this.exitcode = exitcode;
++ this.hasExited = true;
++ this.notifyAll();
++ }
++
++ if (stdout instanceof DeferredCloseProcessPipeInputStream)
++ ((DeferredCloseProcessPipeInputStream) stdout).processExited();
++
++ if (stderr instanceof DeferredCloseProcessPipeInputStream)
++ ((DeferredCloseProcessPipeInputStream) stderr).processExited();
++
++ if (stdin instanceof ProcessPipeOutputStream)
++ ((ProcessPipeOutputStream) stdin).processExited();
++ });
++ break;
++
++ default: throw new AssertionError("Unsupported platform: " + platform);
++ }
++ }
++
++ public OutputStream getOutputStream() {
++ return stdin;
++ }
++
++ public InputStream getInputStream() {
++ return stdout;
++ }
++
++ public InputStream getErrorStream() {
++ return stderr;
++ }
++
++ public synchronized int waitFor() throws InterruptedException {
++ while (!hasExited) {
++ wait();
++ }
++ return exitcode;
++ }
++
++ @Override
++ public synchronized boolean waitFor(long timeout, TimeUnit unit)
++ throws InterruptedException
++ {
++ if (hasExited) return true;
++ if (timeout <= 0) return false;
++
++ long timeoutAsNanos = unit.toNanos(timeout);
++ long startTime = System.nanoTime();
++ long rem = timeoutAsNanos;
++
++ while (!hasExited && (rem > 0)) {
++ wait(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
++ rem = timeoutAsNanos - (System.nanoTime() - startTime);
++ }
++ return hasExited;
++ }
++
++ public synchronized int exitValue() {
++ if (!hasExited) {
++ throw new IllegalThreadStateException("process hasn't exited");
++ }
++ return exitcode;
++ }
++
++ private static native void destroyProcess(int pid, boolean force);
++
++ private void destroy(boolean force) {
++ switch (platform) {
++ case LINUX:
++ case BSD:
++ case AIX:
++ // There is a risk that pid will be recycled, causing us to
++ // kill the wrong process! So we only terminate processes
++ // that appear to still be running. Even with this check,
++ // there is an unavoidable race condition here, but the window
++ // is very small, and OSes try hard to not recycle pids too
++ // soon, so this is quite safe.
++ synchronized (this) {
++ if (!hasExited)
++ destroyProcess(pid, force);
++ }
++ try { stdin.close(); } catch (IOException ignored) {}
++ try { stdout.close(); } catch (IOException ignored) {}
++ try { stderr.close(); } catch (IOException ignored) {}
++ break;
++
++ case SOLARIS:
++ // There is a risk that pid will be recycled, causing us to
++ // kill the wrong process! So we only terminate processes
++ // that appear to still be running. Even with this check,
++ // there is an unavoidable race condition here, but the window
++ // is very small, and OSes try hard to not recycle pids too
++ // soon, so this is quite safe.
++ synchronized (this) {
++ if (!hasExited)
++ destroyProcess(pid, force);
++ try {
++ stdin.close();
++ if (stdout_inner_stream != null)
++ stdout_inner_stream.closeDeferred(stdout);
++ if (stderr instanceof DeferredCloseInputStream)
++ ((DeferredCloseInputStream) stderr)
++ .closeDeferred(stderr);
++ } catch (IOException e) {
++ // ignore
++ }
++ }
++ break;
++
++ default: throw new AssertionError("Unsupported platform: " + platform);
++ }
++ }
++
++ public void destroy() {
++ destroy(false);
++ }
++
++ @Override
++ public Process destroyForcibly() {
++ destroy(true);
++ return this;
++ }
++
++ @Override
++ public synchronized boolean isAlive() {
++ return !hasExited;
++ }
++
++ private static native void init();
++
++ static {
++ init();
++ }
++
++ /**
++ * A buffered input stream for a subprocess pipe file descriptor
++ * that allows the underlying file descriptor to be reclaimed when
++ * the process exits, via the processExited hook.
++ *
++ * This is tricky because we do not want the user-level InputStream to be
++ * closed until the user invokes close(), and we need to continue to be
++ * able to read any buffered data lingering in the OS pipe buffer.
++ */
++ private static class ProcessPipeInputStream extends BufferedInputStream {
++ private final Object closeLock = new Object();
++
++ ProcessPipeInputStream(int fd) {
++ super(new FileInputStream(newFileDescriptor(fd)));
++ }
++ private static byte[] drainInputStream(InputStream in)
++ throws IOException {
++ int n = 0;
++ int j;
++ byte[] a = null;
++ while ((j = in.available()) > 0) {
++ a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
++ n += in.read(a, n, j);
++ }
++ return (a == null || n == a.length) ? a : Arrays.copyOf(a, n);
++ }
++
++ /** Called by the process reaper thread when the process exits. */
++ synchronized void processExited() {
++ synchronized (closeLock) {
++ try {
++ InputStream in = this.in;
++ // this stream is closed if and only if: in == null
++ if (in != null) {
++ byte[] stragglers = drainInputStream(in);
++ in.close();
++ this.in = (stragglers == null) ?
++ ProcessBuilder.NullInputStream.INSTANCE :
++ new ByteArrayInputStream(stragglers);
++ }
++ } catch (IOException ignored) {}
++ }
++ }
++
++ @Override
++ public void close() throws IOException {
++ // BufferedInputStream#close() is not synchronized unlike most other
++ // methods. Synchronizing helps avoid race with processExited().
++ synchronized (closeLock) {
++ super.close();
++ }
++ }
++ }
++
++ /**
++ * A buffered output stream for a subprocess pipe file descriptor
++ * that allows the underlying file descriptor to be reclaimed when
++ * the process exits, via the processExited hook.
++ */
++ private static class ProcessPipeOutputStream extends BufferedOutputStream {
++ ProcessPipeOutputStream(int fd) {
++ super(new FileOutputStream(newFileDescriptor(fd)));
++ }
++
++ /** Called by the process reaper thread when the process exits. */
++ synchronized void processExited() {
++ OutputStream out = this.out;
++ if (out != null) {
++ try {
++ out.close();
++ } catch (IOException ignored) {
++ // We know of no reason to get an IOException, but if
++ // we do, there's nothing else to do but carry on.
++ }
++ this.out = ProcessBuilder.NullOutputStream.INSTANCE;
++ }
++ }
++ }
++
++ // A FileInputStream that supports the deferment of the actual close
++ // operation until the last pending I/O operation on the stream has
++ // finished. This is required on Solaris because we must close the stdin
++ // and stdout streams in the destroy method in order to reclaim the
++ // underlying file descriptors. Doing so, however, causes any thread
++ // currently blocked in a read on one of those streams to receive an
++ // IOException("Bad file number"), which is incompatible with historical
++ // behavior. By deferring the close we allow any pending reads to see -1
++ // (EOF) as they did before.
++ //
++ private static class DeferredCloseInputStream extends FileInputStream
++ {
++ DeferredCloseInputStream(FileDescriptor fd) {
++ super(fd);
++ }
++
++ private Object lock = new Object(); // For the following fields
++ private boolean closePending = false;
++ private int useCount = 0;
++ private InputStream streamToClose;
++
++ private void raise() {
++ synchronized (lock) {
++ useCount++;
++ }
++ }
++
++ private void lower() throws IOException {
++ synchronized (lock) {
++ useCount--;
++ if (useCount == 0 && closePending) {
++ streamToClose.close();
++ }
++ }
++ }
++
++ // stc is the actual stream to be closed; it might be this object, or
++ // it might be an upstream object for which this object is downstream.
++ //
++ private void closeDeferred(InputStream stc) throws IOException {
++ synchronized (lock) {
++ if (useCount == 0) {
++ stc.close();
++ } else {
++ closePending = true;
++ streamToClose = stc;
++ }
++ }
++ }
++
++ public void close() throws IOException {
++ synchronized (lock) {
++ useCount = 0;
++ closePending = false;
++ }
++ super.close();
++ }
++
++ public int read() throws IOException {
++ raise();
++ try {
++ return super.read();
++ } finally {
++ lower();
++ }
++ }
++
++ public int read(byte[] b) throws IOException {
++ raise();
++ try {
++ return super.read(b);
++ } finally {
++ lower();
++ }
++ }
++
++ public int read(byte[] b, int off, int len) throws IOException {
++ raise();
++ try {
++ return super.read(b, off, len);
++ } finally {
++ lower();
++ }
++ }
++
++ public long skip(long n) throws IOException {
++ raise();
++ try {
++ return super.skip(n);
++ } finally {
++ lower();
++ }
++ }
++
++ public int available() throws IOException {
++ raise();
++ try {
++ return super.available();
++ } finally {
++ lower();
++ }
++ }
++ }
++
++ /**
++ * A buffered input stream for a subprocess pipe file descriptor
++ * that allows the underlying file descriptor to be reclaimed when
++ * the process exits, via the processExited hook.
++ *
++ * This is tricky because we do not want the user-level InputStream to be
++ * closed until the user invokes close(), and we need to continue to be
++ * able to read any buffered data lingering in the OS pipe buffer.
++ *
++ * On AIX this is especially tricky, because the 'close()' system call
++ * will block if another thread is at the same time blocked in a file
++ * operation (e.g. 'read()') on the same file descriptor. We therefore
++ * combine 'ProcessPipeInputStream' approach used on Linux and Bsd
++ * with the DeferredCloseInputStream approach used on Solaris. This means
++ * that every potentially blocking operation on the file descriptor
++ * increments a counter before it is executed and decrements it once it
++ * finishes. The 'close()' operation will only be executed if there are
++ * no pending operations. Otherwise it is deferred after the last pending
++ * operation has finished.
++ *
++ */
++ private static class DeferredCloseProcessPipeInputStream
++ extends BufferedInputStream {
++
++ private final Object closeLock = new Object();
++ private int useCount = 0;
++ private boolean closePending = false;
++
++ DeferredCloseProcessPipeInputStream(int fd) {
++ super(new FileInputStream(newFileDescriptor(fd)));
++ }
++
++ private InputStream drainInputStream(InputStream in)
++ throws IOException {
++ int n = 0;
++ int j;
++ byte[] a = null;
++ synchronized (closeLock) {
++ if (buf == null) // asynchronous close()?
++ return null; // discard
++ j = in.available();
++ }
++ while (j > 0) {
++ a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
++ synchronized (closeLock) {
++ if (buf == null) // asynchronous close()?
++ return null; // discard
++ n += in.read(a, n, j);
++ j = in.available();
++ }
++ }
++ return (a == null) ?
++ ProcessBuilder.NullInputStream.INSTANCE :
++ new ByteArrayInputStream(n == a.length ? a : Arrays.copyOf(a, n));
++ }
++
++ /** Called by the process reaper thread when the process exits. */
++ synchronized void processExited() {
++ try {
++ InputStream in = this.in;
++ if (in != null) {
++ InputStream stragglers = drainInputStream(in);
++ in.close();
++ this.in = stragglers;
++ }
++ } catch (IOException ignored) { }
++ }
++
++ private void raise() {
++ synchronized (closeLock) {
++ useCount++;
++ }
++ }
++
++ private void lower() throws IOException {
++ synchronized (closeLock) {
++ useCount--;
++ if (useCount == 0 && closePending) {
++ closePending = false;
++ super.close();
++ }
++ }
++ }
++
++ @Override
++ public int read() throws IOException {
++ raise();
++ try {
++ return super.read();
++ } finally {
++ lower();
++ }
++ }
++
++ @Override
++ public int read(byte[] b) throws IOException {
++ raise();
++ try {
++ return super.read(b);
++ } finally {
++ lower();
++ }
++ }
++
++ @Override
++ public int read(byte[] b, int off, int len) throws IOException {
++ raise();
++ try {
++ return super.read(b, off, len);
++ } finally {
++ lower();
++ }
++ }
++
++ @Override
++ public long skip(long n) throws IOException {
++ raise();
++ try {
++ return super.skip(n);
++ } finally {
++ lower();
++ }
++ }
++
++ @Override
++ public int available() throws IOException {
++ raise();
++ try {
++ return super.available();
++ } finally {
++ lower();
++ }
++ }
++
++ @Override
++ public void close() throws IOException {
++ // BufferedInputStream#close() is not synchronized unlike most other
++ // methods. Synchronizing helps avoid racing with drainInputStream().
++ synchronized (closeLock) {
++ if (useCount == 0) {
++ super.close();
++ }
++ else {
++ closePending = true;
++ }
++ }
++ }
++ }
++}
+--- ./jdk/src/solaris/classes/java/lang/UNIXProcess.java.aix Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,504 +0,0 @@
+-/*
+- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 java.lang;
+-
+-import java.io.BufferedInputStream;
+-import java.io.BufferedOutputStream;
+-import java.io.ByteArrayInputStream;
+-import java.io.FileDescriptor;
+-import java.io.FileInputStream;
+-import java.io.FileOutputStream;
+-import java.io.IOException;
+-import java.io.InputStream;
+-import java.io.OutputStream;
+-import java.util.Arrays;
+-import java.util.concurrent.Executors;
+-import java.util.concurrent.Executor;
+-import java.util.concurrent.ThreadFactory;
+-import java.util.concurrent.TimeUnit;
+-import java.security.AccessController;
+-import static java.security.AccessController.doPrivileged;
+-import java.security.PrivilegedAction;
+-import java.security.PrivilegedActionException;
+-import java.security.PrivilegedExceptionAction;
+-
+-/**
+- * java.lang.Process subclass in the UNIX environment.
+- *
+- * @author Mario Wolczko and Ross Knippel.
+- * @author Konstantin Kladko (ported to Linux)
+- * @author Martin Buchholz
+- * @author Volker Simonis (ported to AIX)
+- */
+-final class UNIXProcess extends Process {
+- private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
+- = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
+-
+- private final int pid;
+- private int exitcode;
+- private boolean hasExited;
+-
+- private /* final */ OutputStream stdin;
+- private /* final */ InputStream stdout;
+- private /* final */ InputStream stderr;
+-
+- private static enum LaunchMechanism {
+- FORK(1),
+- POSIX_SPAWN(2);
+-
+- private int value;
+- LaunchMechanism(int x) {value = x;}
+- };
+-
+- /* On AIX, the default is to spawn */
+- private static final LaunchMechanism launchMechanism;
+- private static byte[] helperpath;
+-
+- private static byte[] toCString(String s) {
+- if (s == null)
+- return null;
+- byte[] bytes = s.getBytes();
+- byte[] result = new byte[bytes.length + 1];
+- System.arraycopy(bytes, 0,
+- result, 0,
+- bytes.length);
+- result[result.length-1] = (byte)0;
+- return result;
+- }
+-
+- static {
+- launchMechanism = AccessController.doPrivileged(
+- new PrivilegedAction<LaunchMechanism>()
+- {
+- public LaunchMechanism run() {
+- String javahome = System.getProperty("java.home");
+- String osArch = System.getProperty("os.arch");
+-
+- helperpath = toCString(javahome + "/lib/" + osArch + "/jspawnhelper");
+- String s = System.getProperty(
+- "jdk.lang.Process.launchMechanism", "posix_spawn");
+-
+- try {
+- return LaunchMechanism.valueOf(s.toUpperCase());
+- } catch (IllegalArgumentException e) {
+- throw new Error(s + " is not a supported " +
+- "process launch mechanism on this platform.");
+- }
+- }
+- });
+- }
+-
+- /* this is for the reaping thread */
+- private native int waitForProcessExit(int pid);
+-
+- /**
+- * Create a process. Depending on the mode flag, this is done by
+- * one of the following mechanisms.
+- * - fork(2) and exec(2)
+- * - clone(2) and exec(2)
+- * - vfork(2) and exec(2)
+- *
+- * @param fds an array of three file descriptors.
+- * Indexes 0, 1, and 2 correspond to standard input,
+- * standard output and standard error, respectively. On
+- * input, a value of -1 means to create a pipe to connect
+- * child and parent processes. On output, a value which
+- * is not -1 is the parent pipe fd corresponding to the
+- * pipe which has been created. An element of this array
+- * is -1 on input if and only if it is <em>not</em> -1 on
+- * output.
+- * @return the pid of the subprocess
+- */
+- private native int forkAndExec(int mode, byte[] helperpath,
+- byte[] prog,
+- byte[] argBlock, int argc,
+- byte[] envBlock, int envc,
+- byte[] dir,
+- int[] fds,
+- boolean redirectErrorStream)
+- throws IOException;
+-
+- /**
+- * The thread factory used to create "process reaper" daemon threads.
+- */
+- private static class ProcessReaperThreadFactory implements ThreadFactory {
+- private final static ThreadGroup group = getRootThreadGroup();
+-
+- private static ThreadGroup getRootThreadGroup() {
+- return doPrivileged(new PrivilegedAction<ThreadGroup> () {
+- public ThreadGroup run() {
+- ThreadGroup root = Thread.currentThread().getThreadGroup();
+- while (root.getParent() != null)
+- root = root.getParent();
+- return root;
+- }});
+- }
+-
+- public Thread newThread(Runnable grimReaper) {
+- // Our thread stack requirement is quite modest.
+- Thread t = new Thread(group, grimReaper, "process reaper", 32768);
+- t.setDaemon(true);
+- // A small attempt (probably futile) to avoid priority inversion
+- t.setPriority(Thread.MAX_PRIORITY);
+- return t;
+- }
+- }
+-
+- /**
+- * The thread pool of "process reaper" daemon threads.
+- */
+- private static final Executor processReaperExecutor =
+- doPrivileged(new PrivilegedAction<Executor>() {
+- public Executor run() {
+- return Executors.newCachedThreadPool
+- (new ProcessReaperThreadFactory());
+- }});
+-
+- UNIXProcess(final byte[] prog,
+- final byte[] argBlock, final int argc,
+- final byte[] envBlock, final int envc,
+- final byte[] dir,
+- final int[] fds,
+- final boolean redirectErrorStream)
+- throws IOException {
+-
+- pid = forkAndExec(launchMechanism.value,
+- helperpath,
+- prog,
+- argBlock, argc,
+- envBlock, envc,
+- dir,
+- fds,
+- redirectErrorStream);
+-
+- try {
+- doPrivileged(new PrivilegedExceptionAction<Void>() {
+- public Void run() throws IOException {
+- initStreams(fds);
+- return null;
+- }});
+- } catch (PrivilegedActionException ex) {
+- throw (IOException) ex.getException();
+- }
+- }
+-
+- static FileDescriptor newFileDescriptor(int fd) {
+- FileDescriptor fileDescriptor = new FileDescriptor();
+- fdAccess.set(fileDescriptor, fd);
+- return fileDescriptor;
+- }
+-
+- void initStreams(int[] fds) throws IOException {
+- stdin = (fds[0] == -1) ?
+- ProcessBuilder.NullOutputStream.INSTANCE :
+- new ProcessPipeOutputStream(fds[0]);
+-
+- stdout = (fds[1] == -1) ?
+- ProcessBuilder.NullInputStream.INSTANCE :
+- new ProcessPipeInputStream(fds[1]);
+-
+- stderr = (fds[2] == -1) ?
+- ProcessBuilder.NullInputStream.INSTANCE :
+- new ProcessPipeInputStream(fds[2]);
+-
+- processReaperExecutor.execute(new Runnable() {
+- public void run() {
+- int exitcode = waitForProcessExit(pid);
+- UNIXProcess.this.processExited(exitcode);
+- }});
+- }
+-
+- void processExited(int exitcode) {
+- synchronized (this) {
+- this.exitcode = exitcode;
+- hasExited = true;
+- notifyAll();
+- }
+-
+- if (stdout instanceof ProcessPipeInputStream)
+- ((ProcessPipeInputStream) stdout).processExited();
+-
+- if (stderr instanceof ProcessPipeInputStream)
+- ((ProcessPipeInputStream) stderr).processExited();
+-
+- if (stdin instanceof ProcessPipeOutputStream)
+- ((ProcessPipeOutputStream) stdin).processExited();
+- }
+-
+- public OutputStream getOutputStream() {
+- return stdin;
+- }
+-
+- public InputStream getInputStream() {
+- return stdout;
+- }
+-
+- public InputStream getErrorStream() {
+- return stderr;
+- }
+-
+- public synchronized int waitFor() throws InterruptedException {
+- while (!hasExited) {
+- wait();
+- }
+- return exitcode;
+- }
+-
+- @Override
+- public synchronized boolean waitFor(long timeout, TimeUnit unit)
+- throws InterruptedException
+- {
+- if (hasExited) return true;
+- if (timeout <= 0) return false;
+-
+- long timeoutAsNanos = unit.toNanos(timeout);
+- long startTime = System.nanoTime();
+- long rem = timeoutAsNanos;
+-
+- while (!hasExited && (rem > 0)) {
+- wait(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
+- rem = timeoutAsNanos - (System.nanoTime() - startTime);
+- }
+- return hasExited;
+- }
+-
+- public synchronized int exitValue() {
+- if (!hasExited) {
+- throw new IllegalThreadStateException("process hasn't exited");
+- }
+- return exitcode;
+- }
+-
+- private static native void destroyProcess(int pid, boolean force);
+- private void destroy(boolean force) {
+- // There is a risk that pid will be recycled, causing us to
+- // kill the wrong process! So we only terminate processes
+- // that appear to still be running. Even with this check,
+- // there is an unavoidable race condition here, but the window
+- // is very small, and OSes try hard to not recycle pids too
+- // soon, so this is quite safe.
+- synchronized (this) {
+- if (!hasExited)
+- destroyProcess(pid, force);
+- }
+- try { stdin.close(); } catch (IOException ignored) {}
+- try { stdout.close(); } catch (IOException ignored) {}
+- try { stderr.close(); } catch (IOException ignored) {}
+- }
+-
+- public void destroy() {
+- destroy(false);
+- }
+-
+- @Override
+- public Process destroyForcibly() {
+- destroy(true);
+- return this;
+- }
+-
+- @Override
+- public synchronized boolean isAlive() {
+- return !hasExited;
+- }
+-
+- private static native void init();
+-
+- static {
+- init();
+- }
+-
+- /**
+- * A buffered input stream for a subprocess pipe file descriptor
+- * that allows the underlying file descriptor to be reclaimed when
+- * the process exits, via the processExited hook.
+- *
+- * This is tricky because we do not want the user-level InputStream to be
+- * closed until the user invokes close(), and we need to continue to be
+- * able to read any buffered data lingering in the OS pipe buffer.
+- *
+- * On AIX this is especially tricky, because the 'close()' system call
+- * will block if another thread is at the same time blocked in a file
+- * operation (e.g. 'read()') on the same file descriptor. We therefore
+- * combine this 'ProcessPipeInputStream' with the DeferredCloseInputStream
+- * approach used on Solaris (see "UNIXProcess.java.solaris"). This means
+- * that every potentially blocking operation on the file descriptor
+- * increments a counter before it is executed and decrements it once it
+- * finishes. The 'close()' operation will only be executed if there are
+- * no pending operations. Otherwise it is deferred after the last pending
+- * operation has finished.
+- *
+- */
+- static class ProcessPipeInputStream extends BufferedInputStream {
+- private final Object closeLock = new Object();
+- private int useCount = 0;
+- private boolean closePending = false;
+-
+- ProcessPipeInputStream(int fd) {
+- super(new FileInputStream(newFileDescriptor(fd)));
+- }
+-
+- private InputStream drainInputStream(InputStream in)
+- throws IOException {
+- int n = 0;
+- int j;
+- byte[] a = null;
+- synchronized (closeLock) {
+- if (buf == null) // asynchronous close()?
+- return null; // discard
+- j = in.available();
+- }
+- while (j > 0) {
+- a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
+- synchronized (closeLock) {
+- if (buf == null) // asynchronous close()?
+- return null; // discard
+- n += in.read(a, n, j);
+- j = in.available();
+- }
+- }
+- return (a == null) ?
+- ProcessBuilder.NullInputStream.INSTANCE :
+- new ByteArrayInputStream(n == a.length ? a : Arrays.copyOf(a, n));
+- }
+-
+- /** Called by the process reaper thread when the process exits. */
+- synchronized void processExited() {
+- try {
+- InputStream in = this.in;
+- if (in != null) {
+- InputStream stragglers = drainInputStream(in);
+- in.close();
+- this.in = stragglers;
+- }
+- } catch (IOException ignored) { }
+- }
+-
+- private void raise() {
+- synchronized (closeLock) {
+- useCount++;
+- }
+- }
+-
+- private void lower() throws IOException {
+- synchronized (closeLock) {
+- useCount--;
+- if (useCount == 0 && closePending) {
+- closePending = false;
+- super.close();
+- }
+- }
+- }
+-
+- @Override
+- public int read() throws IOException {
+- raise();
+- try {
+- return super.read();
+- } finally {
+- lower();
+- }
+- }
+-
+- @Override
+- public int read(byte[] b) throws IOException {
+- raise();
+- try {
+- return super.read(b);
+- } finally {
+- lower();
+- }
+- }
+-
+- @Override
+- public int read(byte[] b, int off, int len) throws IOException {
+- raise();
+- try {
+- return super.read(b, off, len);
+- } finally {
+- lower();
+- }
+- }
+-
+- @Override
+- public long skip(long n) throws IOException {
+- raise();
+- try {
+- return super.skip(n);
+- } finally {
+- lower();
+- }
+- }
+-
+- @Override
+- public int available() throws IOException {
+- raise();
+- try {
+- return super.available();
+- } finally {
+- lower();
+- }
+- }
+-
+- @Override
+- public void close() throws IOException {
+- // BufferedInputStream#close() is not synchronized unlike most other methods.
+- // Synchronizing helps avoid racing with drainInputStream().
+- synchronized (closeLock) {
+- if (useCount == 0) {
+- super.close();
+- }
+- else {
+- closePending = true;
+- }
+- }
+- }
+- }
+-
+- /**
+- * A buffered output stream for a subprocess pipe file descriptor
+- * that allows the underlying file descriptor to be reclaimed when
+- * the process exits, via the processExited hook.
+- */
+- static class ProcessPipeOutputStream extends BufferedOutputStream {
+- ProcessPipeOutputStream(int fd) {
+- super(new FileOutputStream(newFileDescriptor(fd)));
+- }
+-
+- /** Called by the process reaper thread when the process exits. */
+- synchronized void processExited() {
+- OutputStream out = this.out;
+- if (out != null) {
+- try {
+- out.close();
+- } catch (IOException ignored) {
+- // We know of no reason to get an IOException, but if
+- // we do, there's nothing else to do but carry on.
+- }
+- this.out = ProcessBuilder.NullOutputStream.INSTANCE;
+- }
+- }
+- }
+-}
+--- ./jdk/src/solaris/classes/java/lang/UNIXProcess.java.bsd Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,408 +0,0 @@
+-/*
+- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 java.lang;
+-
+-import java.io.BufferedInputStream;
+-import java.io.BufferedOutputStream;
+-import java.io.ByteArrayInputStream;
+-import java.io.FileDescriptor;
+-import java.io.FileInputStream;
+-import java.io.FileOutputStream;
+-import java.io.IOException;
+-import java.io.InputStream;
+-import java.io.OutputStream;
+-import java.util.Arrays;
+-import java.util.concurrent.Executors;
+-import java.util.concurrent.Executor;
+-import java.util.concurrent.ThreadFactory;
+-import java.util.concurrent.TimeUnit;
+-import java.security.AccessController;
+-import static java.security.AccessController.doPrivileged;
+-import java.security.PrivilegedAction;
+-import java.security.PrivilegedActionException;
+-import java.security.PrivilegedExceptionAction;
+-
+-/**
+- * java.lang.Process subclass in the UNIX environment.
+- *
+- * @author Mario Wolczko and Ross Knippel.
+- * @author Konstantin Kladko (ported to Bsd)
+- * @author Martin Buchholz
+- */
+-final class UNIXProcess extends Process {
+- private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
+- = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
+-
+- private final int pid;
+- private int exitcode;
+- private boolean hasExited;
+-
+- private /* final */ OutputStream stdin;
+- private /* final */ InputStream stdout;
+- private /* final */ InputStream stderr;
+-
+- private static enum LaunchMechanism {
+- FORK(1),
+- POSIX_SPAWN(2);
+-
+- private int value;
+- LaunchMechanism(int x) {value = x;}
+- };
+-
+- /* On BSD, the default is to spawn */
+- private static final LaunchMechanism launchMechanism;
+- private static byte[] helperpath;
+-
+- private static byte[] toCString(String s) {
+- if (s == null)
+- return null;
+- byte[] bytes = s.getBytes();
+- byte[] result = new byte[bytes.length + 1];
+- System.arraycopy(bytes, 0,
+- result, 0,
+- bytes.length);
+- result[result.length-1] = (byte)0;
+- return result;
+- }
+-
+- static {
+- launchMechanism = AccessController.doPrivileged(
+- new PrivilegedAction<LaunchMechanism>()
+- {
+- public LaunchMechanism run() {
+- String javahome = System.getProperty("java.home");
+-
+- helperpath = toCString(javahome + "/lib/jspawnhelper");
+- String s = System.getProperty(
+- "jdk.lang.Process.launchMechanism", "posix_spawn");
+-
+- try {
+- return LaunchMechanism.valueOf(s.toUpperCase());
+- } catch (IllegalArgumentException e) {
+- throw new Error(s + " is not a supported " +
+- "process launch mechanism on this platform.");
+- }
+- }
+- });
+- }
+-
+- /* this is for the reaping thread */
+- private native int waitForProcessExit(int pid);
+-
+- /**
+- * Create a process. Depending on the mode flag, this is done by
+- * one of the following mechanisms.
+- * - fork(2) and exec(2)
+- * - posix_spawn(2)
+- *
+- * @param fds an array of three file descriptors.
+- * Indexes 0, 1, and 2 correspond to standard input,
+- * standard output and standard error, respectively. On
+- * input, a value of -1 means to create a pipe to connect
+- * child and parent processes. On output, a value which
+- * is not -1 is the parent pipe fd corresponding to the
+- * pipe which has been created. An element of this array
+- * is -1 on input if and only if it is <em>not</em> -1 on
+- * output.
+- * @return the pid of the subprocess
+- */
+- private native int forkAndExec(int mode, byte[] helperpath,
+- byte[] prog,
+- byte[] argBlock, int argc,
+- byte[] envBlock, int envc,
+- byte[] dir,
+- int[] fds,
+- boolean redirectErrorStream)
+- throws IOException;
+-
+- /**
+- * The thread factory used to create "process reaper" daemon threads.
+- */
+- private static class ProcessReaperThreadFactory implements ThreadFactory {
+- private final static ThreadGroup group = getRootThreadGroup();
+-
+- private static ThreadGroup getRootThreadGroup() {
+- return doPrivileged(new PrivilegedAction<ThreadGroup> () {
+- public ThreadGroup run() {
+- ThreadGroup root = Thread.currentThread().getThreadGroup();
+- while (root.getParent() != null)
+- root = root.getParent();
+- return root;
+- }});
+- }
+-
+- public Thread newThread(Runnable grimReaper) {
+- // Our thread stack requirement is quite modest.
+- Thread t = new Thread(group, grimReaper, "process reaper", 32768);
+- t.setDaemon(true);
+- // A small attempt (probably futile) to avoid priority inversion
+- t.setPriority(Thread.MAX_PRIORITY);
+- return t;
+- }
+- }
+-
+- /**
+- * The thread pool of "process reaper" daemon threads.
+- */
+- private static final Executor processReaperExecutor =
+- doPrivileged(new PrivilegedAction<Executor>() {
+- public Executor run() {
+- return Executors.newCachedThreadPool
+- (new ProcessReaperThreadFactory());
+- }});
+-
+- UNIXProcess(final byte[] prog,
+- final byte[] argBlock, final int argc,
+- final byte[] envBlock, final int envc,
+- final byte[] dir,
+- final int[] fds,
+- final boolean redirectErrorStream)
+- throws IOException {
+-
+- pid = forkAndExec(launchMechanism.value,
+- helperpath,
+- prog,
+- argBlock, argc,
+- envBlock, envc,
+- dir,
+- fds,
+- redirectErrorStream);
+-
+- try {
+- doPrivileged(new PrivilegedExceptionAction<Void>() {
+- public Void run() throws IOException {
+- initStreams(fds);
+- return null;
+- }});
+- } catch (PrivilegedActionException ex) {
+- throw (IOException) ex.getException();
+- }
+- }
+-
+- static FileDescriptor newFileDescriptor(int fd) {
+- FileDescriptor fileDescriptor = new FileDescriptor();
+- fdAccess.set(fileDescriptor, fd);
+- return fileDescriptor;
+- }
+-
+- void initStreams(int[] fds) throws IOException {
+- stdin = (fds[0] == -1) ?
+- ProcessBuilder.NullOutputStream.INSTANCE :
+- new ProcessPipeOutputStream(fds[0]);
+-
+- stdout = (fds[1] == -1) ?
+- ProcessBuilder.NullInputStream.INSTANCE :
+- new ProcessPipeInputStream(fds[1]);
+-
+- stderr = (fds[2] == -1) ?
+- ProcessBuilder.NullInputStream.INSTANCE :
+- new ProcessPipeInputStream(fds[2]);
+-
+- processReaperExecutor.execute(new Runnable() {
+- public void run() {
+- int exitcode = waitForProcessExit(pid);
+- UNIXProcess.this.processExited(exitcode);
+- }});
+- }
+-
+- void processExited(int exitcode) {
+- synchronized (this) {
+- this.exitcode = exitcode;
+- hasExited = true;
+- notifyAll();
+- }
+-
+- if (stdout instanceof ProcessPipeInputStream)
+- ((ProcessPipeInputStream) stdout).processExited();
+-
+- if (stderr instanceof ProcessPipeInputStream)
+- ((ProcessPipeInputStream) stderr).processExited();
+-
+- if (stdin instanceof ProcessPipeOutputStream)
+- ((ProcessPipeOutputStream) stdin).processExited();
+- }
+-
+- public OutputStream getOutputStream() {
+- return stdin;
+- }
+-
+- public InputStream getInputStream() {
+- return stdout;
+- }
+-
+- public InputStream getErrorStream() {
+- return stderr;
+- }
+-
+- public synchronized int waitFor() throws InterruptedException {
+- while (!hasExited) {
+- wait();
+- }
+- return exitcode;
+- }
+-
+- @Override
+- public synchronized boolean waitFor(long timeout, TimeUnit unit)
+- throws InterruptedException
+- {
+- if (hasExited) return true;
+- if (timeout <= 0) return false;
+-
+- long timeoutAsNanos = unit.toNanos(timeout);
+- long startTime = System.nanoTime();
+- long rem = timeoutAsNanos;
+-
+- while (!hasExited && (rem > 0)) {
+- wait(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
+- rem = timeoutAsNanos - (System.nanoTime() - startTime);
+- }
+- return hasExited;
+- }
+-
+- public synchronized int exitValue() {
+- if (!hasExited) {
+- throw new IllegalThreadStateException("process hasn't exited");
+- }
+- return exitcode;
+- }
+-
+- private static native void destroyProcess(int pid, boolean force);
+- private void destroy(boolean force) {
+- // There is a risk that pid will be recycled, causing us to
+- // kill the wrong process! So we only terminate processes
+- // that appear to still be running. Even with this check,
+- // there is an unavoidable race condition here, but the window
+- // is very small, and OSes try hard to not recycle pids too
+- // soon, so this is quite safe.
+- synchronized (this) {
+- if (!hasExited)
+- destroyProcess(pid, force);
+- }
+- try { stdin.close(); } catch (IOException ignored) {}
+- try { stdout.close(); } catch (IOException ignored) {}
+- try { stderr.close(); } catch (IOException ignored) {}
+- }
+-
+- public void destroy() {
+- destroy(false);
+- }
+-
+- @Override
+- public Process destroyForcibly() {
+- destroy(true);
+- return this;
+- }
+-
+- @Override
+- public synchronized boolean isAlive() {
+- return !hasExited;
+- }
+-
+- private static native void init();
+-
+- static {
+- init();
+- }
+-
+- /**
+- * A buffered input stream for a subprocess pipe file descriptor
+- * that allows the underlying file descriptor to be reclaimed when
+- * the process exits, via the processExited hook.
+- *
+- * This is tricky because we do not want the user-level InputStream to be
+- * closed until the user invokes close(), and we need to continue to be
+- * able to read any buffered data lingering in the OS pipe buffer.
+- */
+- static class ProcessPipeInputStream extends BufferedInputStream {
+- private final Object closeLock = new Object();
+-
+- ProcessPipeInputStream(int fd) {
+- super(new FileInputStream(newFileDescriptor(fd)));
+- }
+- private static byte[] drainInputStream(InputStream in)
+- throws IOException {
+- int n = 0;
+- int j;
+- byte[] a = null;
+- while ((j = in.available()) > 0) {
+- a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
+- n += in.read(a, n, j);
+- }
+- return (a == null || n == a.length) ? a : Arrays.copyOf(a, n);
+- }
+-
+- /** Called by the process reaper thread when the process exits. */
+- synchronized void processExited() {
+- synchronized (closeLock) {
+- try {
+- InputStream in = this.in;
+- // this stream is closed if and only if: in == null
+- if (in != null) {
+- byte[] stragglers = drainInputStream(in);
+- in.close();
+- this.in = (stragglers == null) ?
+- ProcessBuilder.NullInputStream.INSTANCE :
+- new ByteArrayInputStream(stragglers);
+- }
+- } catch (IOException ignored) {}
+- }
+- }
+-
+- @Override
+- public void close() throws IOException {
+- // BufferedInputStream#close() is not synchronized unlike most other methods.
+- // Synchronizing helps avoid race with processExited().
+- synchronized (closeLock) {
+- super.close();
+- }
+- }
+- }
+-
+- /**
+- * A buffered output stream for a subprocess pipe file descriptor
+- * that allows the underlying file descriptor to be reclaimed when
+- * the process exits, via the processExited hook.
+- */
+- static class ProcessPipeOutputStream extends BufferedOutputStream {
+- ProcessPipeOutputStream(int fd) {
+- super(new FileOutputStream(newFileDescriptor(fd)));
+- }
+-
+- /** Called by the process reaper thread when the process exits. */
+- synchronized void processExited() {
+- OutputStream out = this.out;
+- if (out != null) {
+- try {
+- out.close();
+- } catch (IOException ignored) {
+- // We know of no reason to get an IOException, but if
+- // we do, there's nothing else to do but carry on.
+- }
+- this.out = ProcessBuilder.NullOutputStream.INSTANCE;
+- }
+- }
+- }
+-}
+--- ./jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,410 +0,0 @@
+-/*
+- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 java.lang;
+-
+-import java.io.BufferedInputStream;
+-import java.io.BufferedOutputStream;
+-import java.io.ByteArrayInputStream;
+-import java.io.FileDescriptor;
+-import java.io.FileInputStream;
+-import java.io.FileOutputStream;
+-import java.io.IOException;
+-import java.io.InputStream;
+-import java.io.OutputStream;
+-import java.util.Arrays;
+-import java.util.concurrent.Executors;
+-import java.util.concurrent.Executor;
+-import java.util.concurrent.ThreadFactory;
+-import java.util.concurrent.TimeUnit;
+-import java.security.AccessController;
+-import static java.security.AccessController.doPrivileged;
+-import java.security.PrivilegedAction;
+-import java.security.PrivilegedActionException;
+-import java.security.PrivilegedExceptionAction;
+-
+-/**
+- * java.lang.Process subclass in the UNIX environment.
+- *
+- * @author Mario Wolczko and Ross Knippel.
+- * @author Konstantin Kladko (ported to Linux)
+- * @author Martin Buchholz
+- */
+-final class UNIXProcess extends Process {
+- private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
+- = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
+-
+- private final int pid;
+- private int exitcode;
+- private boolean hasExited;
+-
+- private /* final */ OutputStream stdin;
+- private /* final */ InputStream stdout;
+- private /* final */ InputStream stderr;
+-
+- private static enum LaunchMechanism {
+- FORK(1),
+- VFORK(3);
+-
+- private int value;
+- LaunchMechanism(int x) {value = x;}
+- };
+-
+- /* default is VFORK on Linux */
+- private static final LaunchMechanism launchMechanism;
+- private static byte[] helperpath;
+-
+- private static byte[] toCString(String s) {
+- if (s == null)
+- return null;
+- byte[] bytes = s.getBytes();
+- byte[] result = new byte[bytes.length + 1];
+- System.arraycopy(bytes, 0,
+- result, 0,
+- bytes.length);
+- result[result.length-1] = (byte)0;
+- return result;
+- }
+-
+- static {
+- launchMechanism = AccessController.doPrivileged(
+- new PrivilegedAction<LaunchMechanism>()
+- {
+- public LaunchMechanism run() {
+- String javahome = System.getProperty("java.home");
+- String osArch = System.getProperty("os.arch");
+-
+- helperpath = toCString(javahome + "/lib/" + osArch + "/jspawnhelper");
+- String s = System.getProperty(
+- "jdk.lang.Process.launchMechanism", "vfork");
+-
+- try {
+- return LaunchMechanism.valueOf(s.toUpperCase());
+- } catch (IllegalArgumentException e) {
+- throw new Error(s + " is not a supported " +
+- "process launch mechanism on this platform.");
+- }
+- }
+- });
+- }
+-
+- /* this is for the reaping thread */
+- private native int waitForProcessExit(int pid);
+-
+- /**
+- * Create a process. Depending on the mode flag, this is done by
+- * one of the following mechanisms.
+- * - fork(2) and exec(2)
+- * - clone(2) and exec(2)
+- * - vfork(2) and exec(2)
+- *
+- * @param fds an array of three file descriptors.
+- * Indexes 0, 1, and 2 correspond to standard input,
+- * standard output and standard error, respectively. On
+- * input, a value of -1 means to create a pipe to connect
+- * child and parent processes. On output, a value which
+- * is not -1 is the parent pipe fd corresponding to the
+- * pipe which has been created. An element of this array
+- * is -1 on input if and only if it is <em>not</em> -1 on
+- * output.
+- * @return the pid of the subprocess
+- */
+- private native int forkAndExec(int mode, byte[] helperpath,
+- byte[] prog,
+- byte[] argBlock, int argc,
+- byte[] envBlock, int envc,
+- byte[] dir,
+- int[] fds,
+- boolean redirectErrorStream)
+- throws IOException;
+-
+- /**
+- * The thread factory used to create "process reaper" daemon threads.
+- */
+- private static class ProcessReaperThreadFactory implements ThreadFactory {
+- private final static ThreadGroup group = getRootThreadGroup();
+-
+- private static ThreadGroup getRootThreadGroup() {
+- return doPrivileged(new PrivilegedAction<ThreadGroup> () {
+- public ThreadGroup run() {
+- ThreadGroup root = Thread.currentThread().getThreadGroup();
+- while (root.getParent() != null)
+- root = root.getParent();
+- return root;
+- }});
+- }
+-
+- public Thread newThread(Runnable grimReaper) {
+- // Our thread stack requirement is quite modest.
+- Thread t = new Thread(group, grimReaper, "process reaper", 32768);
+- t.setDaemon(true);
+- // A small attempt (probably futile) to avoid priority inversion
+- t.setPriority(Thread.MAX_PRIORITY);
+- return t;
+- }
+- }
+-
+- /**
+- * The thread pool of "process reaper" daemon threads.
+- */
+- private static final Executor processReaperExecutor =
+- doPrivileged(new PrivilegedAction<Executor>() {
+- public Executor run() {
+- return Executors.newCachedThreadPool
+- (new ProcessReaperThreadFactory());
+- }});
+-
+- UNIXProcess(final byte[] prog,
+- final byte[] argBlock, final int argc,
+- final byte[] envBlock, final int envc,
+- final byte[] dir,
+- final int[] fds,
+- final boolean redirectErrorStream)
+- throws IOException {
+-
+- pid = forkAndExec(launchMechanism.value,
+- helperpath,
+- prog,
+- argBlock, argc,
+- envBlock, envc,
+- dir,
+- fds,
+- redirectErrorStream);
+-
+- try {
+- doPrivileged(new PrivilegedExceptionAction<Void>() {
+- public Void run() throws IOException {
+- initStreams(fds);
+- return null;
+- }});
+- } catch (PrivilegedActionException ex) {
+- throw (IOException) ex.getException();
+- }
+- }
+-
+- static FileDescriptor newFileDescriptor(int fd) {
+- FileDescriptor fileDescriptor = new FileDescriptor();
+- fdAccess.set(fileDescriptor, fd);
+- return fileDescriptor;
+- }
+-
+- void initStreams(int[] fds) throws IOException {
+- stdin = (fds[0] == -1) ?
+- ProcessBuilder.NullOutputStream.INSTANCE :
+- new ProcessPipeOutputStream(fds[0]);
+-
+- stdout = (fds[1] == -1) ?
+- ProcessBuilder.NullInputStream.INSTANCE :
+- new ProcessPipeInputStream(fds[1]);
+-
+- stderr = (fds[2] == -1) ?
+- ProcessBuilder.NullInputStream.INSTANCE :
+- new ProcessPipeInputStream(fds[2]);
+-
+- processReaperExecutor.execute(new Runnable() {
+- public void run() {
+- int exitcode = waitForProcessExit(pid);
+- UNIXProcess.this.processExited(exitcode);
+- }});
+- }
+-
+- void processExited(int exitcode) {
+- synchronized (this) {
+- this.exitcode = exitcode;
+- hasExited = true;
+- notifyAll();
+- }
+-
+- if (stdout instanceof ProcessPipeInputStream)
+- ((ProcessPipeInputStream) stdout).processExited();
+-
+- if (stderr instanceof ProcessPipeInputStream)
+- ((ProcessPipeInputStream) stderr).processExited();
+-
+- if (stdin instanceof ProcessPipeOutputStream)
+- ((ProcessPipeOutputStream) stdin).processExited();
+- }
+-
+- public OutputStream getOutputStream() {
+- return stdin;
+- }
+-
+- public InputStream getInputStream() {
+- return stdout;
+- }
+-
+- public InputStream getErrorStream() {
+- return stderr;
+- }
+-
+- public synchronized int waitFor() throws InterruptedException {
+- while (!hasExited) {
+- wait();
+- }
+- return exitcode;
+- }
+-
+- @Override
+- public synchronized boolean waitFor(long timeout, TimeUnit unit)
+- throws InterruptedException
+- {
+- if (hasExited) return true;
+- if (timeout <= 0) return false;
+-
+- long timeoutAsNanos = unit.toNanos(timeout);
+- long startTime = System.nanoTime();
+- long rem = timeoutAsNanos;
+-
+- while (!hasExited && (rem > 0)) {
+- wait(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
+- rem = timeoutAsNanos - (System.nanoTime() - startTime);
+- }
+- return hasExited;
+- }
+-
+- public synchronized int exitValue() {
+- if (!hasExited) {
+- throw new IllegalThreadStateException("process hasn't exited");
+- }
+- return exitcode;
+- }
+-
+- private static native void destroyProcess(int pid, boolean force);
+- private void destroy(boolean force) {
+- // There is a risk that pid will be recycled, causing us to
+- // kill the wrong process! So we only terminate processes
+- // that appear to still be running. Even with this check,
+- // there is an unavoidable race condition here, but the window
+- // is very small, and OSes try hard to not recycle pids too
+- // soon, so this is quite safe.
+- synchronized (this) {
+- if (!hasExited)
+- destroyProcess(pid, force);
+- }
+- try { stdin.close(); } catch (IOException ignored) {}
+- try { stdout.close(); } catch (IOException ignored) {}
+- try { stderr.close(); } catch (IOException ignored) {}
+- }
+-
+- public void destroy() {
+- destroy(false);
+- }
+-
+- @Override
+- public Process destroyForcibly() {
+- destroy(true);
+- return this;
+- }
+-
+- @Override
+- public synchronized boolean isAlive() {
+- return !hasExited;
+- }
+-
+- private static native void init();
+-
+- static {
+- init();
+- }
+-
+- /**
+- * A buffered input stream for a subprocess pipe file descriptor
+- * that allows the underlying file descriptor to be reclaimed when
+- * the process exits, via the processExited hook.
+- *
+- * This is tricky because we do not want the user-level InputStream to be
+- * closed until the user invokes close(), and we need to continue to be
+- * able to read any buffered data lingering in the OS pipe buffer.
+- */
+- static class ProcessPipeInputStream extends BufferedInputStream {
+- private final Object closeLock = new Object();
+-
+- ProcessPipeInputStream(int fd) {
+- super(new FileInputStream(newFileDescriptor(fd)));
+- }
+- private static byte[] drainInputStream(InputStream in)
+- throws IOException {
+- int n = 0;
+- int j;
+- byte[] a = null;
+- while ((j = in.available()) > 0) {
+- a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
+- n += in.read(a, n, j);
+- }
+- return (a == null || n == a.length) ? a : Arrays.copyOf(a, n);
+- }
+-
+- /** Called by the process reaper thread when the process exits. */
+- synchronized void processExited() {
+- synchronized (closeLock) {
+- try {
+- InputStream in = this.in;
+- // this stream is closed if and only if: in == null
+- if (in != null) {
+- byte[] stragglers = drainInputStream(in);
+- in.close();
+- this.in = (stragglers == null) ?
+- ProcessBuilder.NullInputStream.INSTANCE :
+- new ByteArrayInputStream(stragglers);
+- }
+- } catch (IOException ignored) {}
+- }
+- }
+-
+- @Override
+- public void close() throws IOException {
+- // BufferedInputStream#close() is not synchronized unlike most other methods.
+- // Synchronizing helps avoid race with processExited().
+- synchronized (closeLock) {
+- super.close();
+- }
+- }
+- }
+-
+- /**
+- * A buffered output stream for a subprocess pipe file descriptor
+- * that allows the underlying file descriptor to be reclaimed when
+- * the process exits, via the processExited hook.
+- */
+- static class ProcessPipeOutputStream extends BufferedOutputStream {
+- ProcessPipeOutputStream(int fd) {
+- super(new FileOutputStream(newFileDescriptor(fd)));
+- }
+-
+- /** Called by the process reaper thread when the process exits. */
+- synchronized void processExited() {
+- OutputStream out = this.out;
+- if (out != null) {
+- try {
+- out.close();
+- } catch (IOException ignored) {
+- // We know of no reason to get an IOException, but if
+- // we do, there's nothing else to do but carry on.
+- }
+- this.out = ProcessBuilder.NullOutputStream.INSTANCE;
+- }
+- }
+- }
+-}
+--- ./jdk/src/solaris/classes/java/lang/UNIXProcess.java.solaris Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,444 +0,0 @@
+-/*
+- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 java.lang;
+-
+-import java.io.BufferedInputStream;
+-import java.io.BufferedOutputStream;
+-import java.io.FileDescriptor;
+-import java.io.FileInputStream;
+-import java.io.FileOutputStream;
+-import java.io.IOException;
+-import java.io.InputStream;
+-import java.io.OutputStream;
+-import java.util.concurrent.Executors;
+-import java.util.concurrent.Executor;
+-import java.util.concurrent.ThreadFactory;
+-import java.util.concurrent.TimeUnit;
+-import java.security.AccessController;
+-import static java.security.AccessController.doPrivileged;
+-import java.security.PrivilegedAction;
+-import java.security.PrivilegedActionException;
+-import java.security.PrivilegedExceptionAction;
+-
+-/* java.lang.Process subclass in the UNIX environment.
+- *
+- * @author Mario Wolczko and Ross Knippel.
+- */
+-
+-final class UNIXProcess extends Process {
+- private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
+- = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
+-
+- private final int pid;
+- private int exitcode;
+- private boolean hasExited;
+-
+- private OutputStream stdin_stream;
+- private InputStream stdout_stream;
+- private DeferredCloseInputStream stdout_inner_stream;
+- private InputStream stderr_stream;
+-
+- private static enum LaunchMechanism {
+- FORK(1),
+- POSIX_SPAWN(2);
+-
+- private int value;
+- LaunchMechanism(int x) {value = x;}
+- };
+-
+- /* On Solaris, the default is to spawn */
+- private static final LaunchMechanism launchMechanism;
+- private static byte[] helperpath;
+-
+- private static byte[] toCString(String s) {
+- if (s == null)
+- return null;
+- byte[] bytes = s.getBytes();
+- byte[] result = new byte[bytes.length + 1];
+- System.arraycopy(bytes, 0,
+- result, 0,
+- bytes.length);
+- result[result.length-1] = (byte)0;
+- return result;
+- }
+-
+- static {
+- launchMechanism = AccessController.doPrivileged(
+- new PrivilegedAction<LaunchMechanism>()
+- {
+- public LaunchMechanism run() {
+- String javahome = System.getProperty("java.home");
+- String osArch = System.getProperty("os.arch");
+- if (osArch.equals("x86")) {
+- osArch = "i386";
+- } else if (osArch.equals("x86_64")) {
+- osArch = "amd64";
+- }
+-
+- helperpath = toCString(javahome + "/lib/" + osArch + "/jspawnhelper");
+- String s = System.getProperty(
+- "jdk.lang.Process.launchMechanism", "posix_spawn");
+-
+- try {
+- return LaunchMechanism.valueOf(s.toUpperCase());
+- } catch (IllegalArgumentException e) {
+- throw new Error(s + " is not a supported " +
+- "process launch mechanism on this platform.");
+- }
+- }
+- });
+- }
+-
+- /* this is for the reaping thread */
+- private native int waitForProcessExit(int pid);
+-
+- /**
+- * Create a process. Depending on the mode flag, this is done by
+- * one of the following mechanisms.
+- * - fork(2) and exec(2)
+- * - posix_spawn(2)
+- *
+- * @param fds an array of three file descriptors.
+- * Indexes 0, 1, and 2 correspond to standard input,
+- * standard output and standard error, respectively. On
+- * input, a value of -1 means to create a pipe to connect
+- * child and parent processes. On output, a value which
+- * is not -1 is the parent pipe fd corresponding to the
+- * pipe which has been created. An element of this array
+- * is -1 on input if and only if it is <em>not</em> -1 on
+- * output.
+- * @return the pid of the subprocess
+- */
+- private native int forkAndExec(int mode, byte[] helperpath,
+- byte[] prog,
+- byte[] argBlock, int argc,
+- byte[] envBlock, int envc,
+- byte[] dir,
+- int[] fds,
+- boolean redirectErrorStream)
+- throws IOException;
+-
+- /**
+- * The thread factory used to create "process reaper" daemon threads.
+- */
+- private static class ProcessReaperThreadFactory implements ThreadFactory {
+- private final static ThreadGroup group = getRootThreadGroup();
+-
+- private static ThreadGroup getRootThreadGroup() {
+- return doPrivileged(new PrivilegedAction<ThreadGroup> () {
+- public ThreadGroup run() {
+- ThreadGroup root = Thread.currentThread().getThreadGroup();
+- while (root.getParent() != null)
+- root = root.getParent();
+- return root;
+- }});
+- }
+-
+- public Thread newThread(Runnable grimReaper) {
+- // Our thread stack requirement is quite modest.
+- Thread t = new Thread(group, grimReaper, "process reaper", 32768);
+- t.setDaemon(true);
+- // A small attempt (probably futile) to avoid priority inversion
+- t.setPriority(Thread.MAX_PRIORITY);
+- return t;
+- }
+- }
+-
+- /**
+- * The thread pool of "process reaper" daemon threads.
+- */
+- private static final Executor processReaperExecutor =
+- doPrivileged(new PrivilegedAction<Executor>() {
+- public Executor run() {
+- return Executors.newCachedThreadPool
+- (new ProcessReaperThreadFactory());
+- }});
+-
+- UNIXProcess(final byte[] prog,
+- final byte[] argBlock, int argc,
+- final byte[] envBlock, int envc,
+- final byte[] dir,
+- final int[] fds,
+- final boolean redirectErrorStream)
+- throws IOException {
+- pid = forkAndExec(launchMechanism.value,
+- helperpath,
+- prog,
+- argBlock, argc,
+- envBlock, envc,
+- dir,
+- fds,
+- redirectErrorStream);
+-
+- try {
+- doPrivileged(
+- new PrivilegedExceptionAction<Void>() {
+- public Void run() throws IOException {
+- initStreams(fds);
+- return null;
+- }
+- });
+- } catch (PrivilegedActionException ex) {
+- throw (IOException) ex.getException();
+- }
+- }
+-
+- void initStreams(int[] fds) throws IOException {
+- if (fds[0] == -1)
+- stdin_stream = ProcessBuilder.NullOutputStream.INSTANCE;
+- else {
+- FileDescriptor stdin_fd = new FileDescriptor();
+- fdAccess.set(stdin_fd, fds[0]);
+- stdin_stream = new BufferedOutputStream(
+- new FileOutputStream(stdin_fd));
+- }
+-
+- if (fds[1] == -1)
+- stdout_stream = ProcessBuilder.NullInputStream.INSTANCE;
+- else {
+- FileDescriptor stdout_fd = new FileDescriptor();
+- fdAccess.set(stdout_fd, fds[1]);
+- stdout_inner_stream = new DeferredCloseInputStream(stdout_fd);
+- stdout_stream = new BufferedInputStream(stdout_inner_stream);
+- }
+-
+- if (fds[2] == -1)
+- stderr_stream = ProcessBuilder.NullInputStream.INSTANCE;
+- else {
+- FileDescriptor stderr_fd = new FileDescriptor();
+- fdAccess.set(stderr_fd, fds[2]);
+- stderr_stream = new DeferredCloseInputStream(stderr_fd);
+- }
+-
+- processReaperExecutor.execute(new Runnable() {
+- public void run() {
+- int exitcode = waitForProcessExit(pid);
+- UNIXProcess.this.processExited(exitcode);
+- }});
+- }
+-
+- void processExited(int exitcode) {
+- synchronized (this) {
+- this.exitcode = exitcode;
+- hasExited = true;
+- notifyAll();
+- }
+- }
+-
+- public OutputStream getOutputStream() {
+- return stdin_stream;
+- }
+-
+- public InputStream getInputStream() {
+- return stdout_stream;
+- }
+-
+- public InputStream getErrorStream() {
+- return stderr_stream;
+- }
+-
+- public synchronized int waitFor() throws InterruptedException {
+- while (!hasExited) {
+- wait();
+- }
+- return exitcode;
+- }
+-
+- @Override
+- public synchronized boolean waitFor(long timeout, TimeUnit unit)
+- throws InterruptedException
+- {
+- if (hasExited) return true;
+- if (timeout <= 0) return false;
+-
+- long timeoutAsNanos = unit.toNanos(timeout);
+- long startTime = System.nanoTime();
+- long rem = timeoutAsNanos;
+-
+- while (!hasExited && (rem > 0)) {
+- wait(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
+- rem = timeoutAsNanos - (System.nanoTime() - startTime);
+- }
+- return hasExited;
+- }
+-
+- public synchronized int exitValue() {
+- if (!hasExited) {
+- throw new IllegalThreadStateException("process hasn't exited");
+- }
+- return exitcode;
+- }
+-
+- private static native void destroyProcess(int pid, boolean force);
+- private synchronized void destroy(boolean force) {
+- // There is a risk that pid will be recycled, causing us to
+- // kill the wrong process! So we only terminate processes
+- // that appear to still be running. Even with this check,
+- // there is an unavoidable race condition here, but the window
+- // is very small, and OSes try hard to not recycle pids too
+- // soon, so this is quite safe.
+- if (!hasExited)
+- destroyProcess(pid, force);
+- try {
+- stdin_stream.close();
+- if (stdout_inner_stream != null)
+- stdout_inner_stream.closeDeferred(stdout_stream);
+- if (stderr_stream instanceof DeferredCloseInputStream)
+- ((DeferredCloseInputStream) stderr_stream)
+- .closeDeferred(stderr_stream);
+- } catch (IOException e) {
+- // ignore
+- }
+- }
+-
+- public void destroy() {
+- destroy(false);
+- }
+-
+- @Override
+- public Process destroyForcibly() {
+- destroy(true);
+- return this;
+- }
+-
+- @Override
+- public synchronized boolean isAlive() {
+- return !hasExited;
+- }
+-
+- // A FileInputStream that supports the deferment of the actual close
+- // operation until the last pending I/O operation on the stream has
+- // finished. This is required on Solaris because we must close the stdin
+- // and stdout streams in the destroy method in order to reclaim the
+- // underlying file descriptors. Doing so, however, causes any thread
+- // currently blocked in a read on one of those streams to receive an
+- // IOException("Bad file number"), which is incompatible with historical
+- // behavior. By deferring the close we allow any pending reads to see -1
+- // (EOF) as they did before.
+- //
+- private static class DeferredCloseInputStream
+- extends FileInputStream
+- {
+-
+- private DeferredCloseInputStream(FileDescriptor fd) {
+- super(fd);
+- }
+-
+- private Object lock = new Object(); // For the following fields
+- private boolean closePending = false;
+- private int useCount = 0;
+- private InputStream streamToClose;
+-
+- private void raise() {
+- synchronized (lock) {
+- useCount++;
+- }
+- }
+-
+- private void lower() throws IOException {
+- synchronized (lock) {
+- useCount--;
+- if (useCount == 0 && closePending) {
+- streamToClose.close();
+- }
+- }
+- }
+-
+- // stc is the actual stream to be closed; it might be this object, or
+- // it might be an upstream object for which this object is downstream.
+- //
+- private void closeDeferred(InputStream stc) throws IOException {
+- synchronized (lock) {
+- if (useCount == 0) {
+- stc.close();
+- } else {
+- closePending = true;
+- streamToClose = stc;
+- }
+- }
+- }
+-
+- public void close() throws IOException {
+- synchronized (lock) {
+- useCount = 0;
+- closePending = false;
+- }
+- super.close();
+- }
+-
+- public int read() throws IOException {
+- raise();
+- try {
+- return super.read();
+- } finally {
+- lower();
+- }
+- }
+-
+- public int read(byte[] b) throws IOException {
+- raise();
+- try {
+- return super.read(b);
+- } finally {
+- lower();
+- }
+- }
+-
+- public int read(byte[] b, int off, int len) throws IOException {
+- raise();
+- try {
+- return super.read(b, off, len);
+- } finally {
+- lower();
+- }
+- }
+-
+- public long skip(long n) throws IOException {
+- raise();
+- try {
+- return super.skip(n);
+- } finally {
+- lower();
+- }
+- }
+-
+- public int available() throws IOException {
+- raise();
+- try {
+- return super.available();
+- } finally {
+- lower();
+- }
+- }
+-
+- }
+-
+- private static native void init();
+-
+- static {
+- init();
+- }
+-}
+--- ./jdk/src/solaris/classes/sun/awt/X11/ListHelper.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/awt/X11/ListHelper.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -40,7 +40,7 @@
+ * For now, this class manages the list of items and painting thereof, but not
+ * posting of Item or ActionEvents
+ */
+-public class ListHelper implements XScrollbarClient {
++final class ListHelper implements XScrollbarClient {
+ private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.ListHelper");
+
+ private final int FOCUS_INSET = 1;
+@@ -79,24 +79,16 @@
+ // Holds the true if mouse is dragging outside of the area of the list
+ // The flag is used at the moment of the dragging and releasing mouse
+ // See 6243382 for more information
+- boolean mouseDraggedOutVertically = false;
++ private boolean mouseDraggedOutVertically = false;
+ private volatile boolean vsbVisibilityChanged = false;
+
+ /*
+ * Comment
+ */
+- public ListHelper(XWindow peer,
+- Color[] colors,
+- int initialSize,
+- boolean multiSelect,
+- boolean scrollVert,
+- boolean scrollHoriz,
+- Font font,
+- int maxVisItems,
+- int SPACE,
+- int MARGIN,
+- int BORDER,
+- int SCROLLBAR) {
++ ListHelper(XWindow peer, Color[] colors, int initialSize,
++ boolean multiSelect, boolean scrollVert, boolean scrollHoriz,
++ Font font, int maxVisItems, int SPACE, int MARGIN, int BORDER,
++ int SCROLLBAR) {
+ this.peer = peer;
+ this.colors = colors;
+ this.multiSelect = multiSelect;
+@@ -121,6 +113,7 @@
+ SCROLLBAR_WIDTH = SCROLLBAR;
+ }
+
++ @Override
+ public Component getEventSource() {
+ return peer.getEventSource();
+ }
+@@ -129,36 +122,36 @@
+ /* List management methods */
+ /**********************************************************************/
+
+- public void add(String item) {
++ void add(String item) {
+ items.add(item);
+ updateScrollbars();
+ }
+
+- public void add(String item, int index) {
++ void add(String item, int index) {
+ items.add(index, item);
+ updateScrollbars();
+ }
+
+- public void remove(String item) {
++ void remove(String item) {
+ // FIXME: need to clean up select list, too?
+ items.remove(item);
+ updateScrollbars();
+ // Is vsb visible now?
+ }
+
+- public void remove(int index) {
++ void remove(int index) {
+ // FIXME: need to clean up select list, too?
+ items.remove(index);
+ updateScrollbars();
+ // Is vsb visible now?
+ }
+
+- public void removeAll() {
++ void removeAll() {
+ items.removeAll(items);
+ updateScrollbars();
+ }
+
+- public void setMultiSelect(boolean ms) {
++ void setMultiSelect(boolean ms) {
+ multiSelect = ms;
+ }
+
+@@ -167,7 +160,7 @@
+ * merely keeps internal track of which items are selected for painting
+ * dealing with target Components happens elsewhere
+ */
+- public void select(int index) {
++ void select(int index) {
+ if (index > getItemCount() - 1) {
+ index = (isEmpty() ? -1 : 0);
+ }
+@@ -182,13 +175,13 @@
+ }
+
+ /* docs */
+- public void deselect(int index) {
++ void deselect(int index) {
+ assert(false);
+ }
+
+ /* docs */
+ /* if called for multiselect, return -1 */
+- public int getSelectedIndex() {
++ int getSelectedIndex() {
+ if (!multiSelect) {
+ Integer val = (Integer)selected.get(0);
+ return val.intValue();
+@@ -202,21 +195,21 @@
+ * A getter method for XChoicePeer.
+ * Returns vsbVisiblityChanged value and sets it to false.
+ */
+- public boolean checkVsbVisibilityChangedAndReset(){
++ boolean checkVsbVisibilityChangedAndReset(){
+ boolean returnVal = vsbVisibilityChanged;
+ vsbVisibilityChanged = false;
+ return returnVal;
+ }
+
+- public boolean isEmpty() {
++ boolean isEmpty() {
+ return items.isEmpty();
+ }
+
+- public int getItemCount() {
++ int getItemCount() {
+ return items.size();
+ }
+
+- public String getItem(int index) {
++ String getItem(int index) {
+ return (String) items.get(index);
+ }
+
+@@ -224,15 +217,15 @@
+ /* GUI-related methods */
+ /**********************************************************************/
+
+- public void setFocusedIndex(int index) {
++ void setFocusedIndex(int index) {
+ focusedIndex = index;
+ }
+
+- public boolean isFocusedIndex(int index) {
++ private boolean isFocusedIndex(int index) {
+ return index == focusedIndex;
+ }
+
+- public void setFont(Font newFont) {
++ void setFont(Font newFont) {
+ if (newFont != font) {
+ font = newFont;
+ fm = Toolkit.getDefaultToolkit().getFontMetrics(font);
+@@ -243,7 +236,7 @@
+ /*
+ * Returns width of the text of the longest item
+ */
+- public int getMaxItemWidth() {
++ int getMaxItemWidth() {
+ int m = 0;
+ int end = getItemCount();
+ for(int i = 0 ; i < end ; i++) {
+@@ -260,7 +253,7 @@
+ return fm.getHeight() + (2*TEXT_SPACE);
+ }
+
+- public int y2index(int y) {
++ int y2index(int y) {
+ if (log.isLoggable(PlatformLogger.Level.FINE)) {
+ log.fine("y=" + y +", firstIdx=" + firstDisplayedIndex() +", itemHeight=" + getItemHeight()
+ + ",item_margin=" + ITEM_MARGIN);
+@@ -275,14 +268,14 @@
+ public int numItemsDisplayed() {}
+ */
+
+- public int firstDisplayedIndex() {
++ int firstDisplayedIndex() {
+ if (vsbVis) {
+ return vsb.getValue();
+ }
+ return 0;
+ }
+
+- public int lastDisplayedIndex() {
++ int lastDisplayedIndex() {
+ // FIXME: need to account for horiz scroll bar
+ if (hsbVis) {
+ assert false : "Implement for horiz scroll bar";
+@@ -294,7 +287,7 @@
+ /*
+ * If the given index is not visible in the List, scroll so that it is.
+ */
+- public void makeVisible(int index) {
++ private void makeVisible(int index) {
+ if (vsbVis) {
+ if (index < firstDisplayedIndex()) {
+ vsb.setValue(index);
+@@ -306,7 +299,7 @@
+ }
+
+ // FIXME: multi-select needs separate focused index
+- public void up() {
++ void up() {
+ int curIdx = getSelectedIndex();
+ int numItems = getItemCount();
+ int newIdx;
+@@ -323,12 +316,12 @@
+ select(newIdx);
+ }
+
+- public void down() {
++ void down() {
+ int newIdx = (getSelectedIndex() + 1) % getItemCount();
+ select(newIdx);
+ }
+
+- public void pageUp() {
++ void pageUp() {
+ // FIXME: for multi-select, move the focused item, not the selected item
+ if (vsbVis && firstDisplayedIndex() > 0) {
+ if (multiSelect) {
+@@ -343,7 +336,7 @@
+ }
+ }
+ }
+- public void pageDown() {
++ void pageDown() {
+ if (vsbVis && lastDisplayedIndex() < getItemCount() - 1) {
+ if (multiSelect) {
+ assert false : "Implement pageDown() for multiSelect";
+@@ -357,17 +350,17 @@
+ }
+ }
+ }
+- public void home() {}
+- public void end() {}
++ void home() {}
++ void end() {}
+
+
+- public boolean isVSBVisible() { return vsbVis; }
+- public boolean isHSBVisible() { return hsbVis; }
++ boolean isVSBVisible() { return vsbVis; }
++ boolean isHSBVisible() { return hsbVis; }
+
+- public XVerticalScrollbar getVSB() { return vsb; }
+- public XHorizontalScrollbar getHSB() { return hsb; }
++ XVerticalScrollbar getVSB() { return vsb; }
++ XHorizontalScrollbar getHSB() { return hsb; }
+
+- public boolean isInVertSB(Rectangle bounds, int x, int y) {
++ boolean isInVertSB(Rectangle bounds, int x, int y) {
+ if (vsbVis) {
+ assert vsb != null : "Vert scrollbar is visible, yet is null?";
+ int sbHeight = hsbVis ? bounds.height - SCROLLBAR_WIDTH : bounds.height;
+@@ -379,7 +372,7 @@
+ return false;
+ }
+
+- public boolean isInHorizSB(Rectangle bounds, int x, int y) {
++ boolean isInHorizSB(Rectangle bounds, int x, int y) {
+ if (hsbVis) {
+ assert hsb != null : "Horiz scrollbar is visible, yet is null?";
+
+@@ -392,7 +385,7 @@
+ return false;
+ }
+
+- public void handleVSBEvent(MouseEvent e, Rectangle bounds, int x, int y) {
++ void handleVSBEvent(MouseEvent e, Rectangle bounds, int x, int y) {
+ int sbHeight = hsbVis ? bounds.height - SCROLLBAR_WIDTH : bounds.height;
+
+ vsb.handleMouseEvent(e.getID(),
+@@ -405,7 +398,7 @@
+ * Called when items are added/removed.
+ * Update whether the scrollbar is visible or not, scrollbar values
+ */
+- void updateScrollbars() {
++ private void updateScrollbars() {
+ boolean oldVsbVis = vsbVis;
+ vsbVis = vsb != null && items.size() > maxVisItems;
+ if (vsbVis) {
+@@ -420,10 +413,11 @@
+ // FIXME: check if added item makes a hsb necessary (if supported, that of course)
+ }
+
+- public int getNumItemsDisplayed() {
++ private int getNumItemsDisplayed() {
+ return items.size() > maxVisItems ? maxVisItems : items.size();
+ }
+
++ @Override
+ public void repaintScrollbarRequest(XScrollbar sb) {
+ Graphics g = peer.getGraphics();
+ Rectangle bounds = peer.getBounds();
+@@ -436,6 +430,7 @@
+ g.dispose();
+ }
+
++ @Override
+ public void notifyValue(XScrollbar obj, int type, int v, boolean isAdjusting) {
+ if (obj == vsb) {
+ int oldScrollValue = vsb.getValue();
+@@ -467,7 +462,7 @@
+ }
+ }
+
+- public void updateColors(Color[] newColors) {
++ void updateColors(Color[] newColors) {
+ colors = newColors;
+ }
+
+@@ -481,7 +476,7 @@
+ XVerticalScrollbar vsb,
+ XHorizontalScrollbar hsb) {
+ */
+- public void paintItems(Graphics g,
++ void paintItems(Graphics g,
+ Color[] colors,
+ Rectangle bounds) {
+ // paint border
+@@ -490,17 +485,14 @@
+ // paint focus?
+
+ }
+- public void paintAllItems(Graphics g,
++ void paintAllItems(Graphics g,
+ Color[] colors,
+ Rectangle bounds) {
+ paintItems(g, colors, bounds,
+ firstDisplayedIndex(), lastDisplayedIndex());
+ }
+- public void paintItems(Graphics g,
+- Color[] colors,
+- Rectangle bounds,
+- int first,
+- int last) {
++ private void paintItems(Graphics g, Color[] colors, Rectangle bounds,
++ int first, int last) {
+ peer.flush();
+ int x = BORDER_WIDTH + ITEM_MARGIN;
+ int width = bounds.width - 2*ITEM_MARGIN - 2*BORDER_WIDTH - (vsbVis ? SCROLLBAR_WIDTH : 0);
+@@ -529,12 +521,9 @@
+ /*
+ * comment about what is painted (i.e. the focus rect
+ */
+- public void paintItem(Graphics g,
+- Color[] colors,
+- String string,
+- int x, int y, int width, int height,
+- boolean selected,
+- boolean focused) {
++ private void paintItem(Graphics g, Color[] colors, String string, int x,
++ int y, int width, int height, boolean selected,
++ boolean focused) {
+ //System.out.println("LP.pI(): x="+x+" y="+y+" w="+width+" h="+height);
+ //g.setColor(colors[BACKGROUND_COLOR]);
+
+@@ -575,7 +564,7 @@
+ //g.clipRect(clip.x, clip.y, clip.width, clip.height);
+ }
+
+- boolean isItemSelected(int index) {
++ private boolean isItemSelected(int index) {
+ Iterator itr = selected.iterator();
+ while (itr.hasNext()) {
+ Integer val = (Integer)itr.next();
+@@ -586,7 +575,7 @@
+ return false;
+ }
+
+- public void paintVSB(Graphics g, Color colors[], Rectangle bounds) {
++ private void paintVSB(Graphics g, Color colors[], Rectangle bounds) {
+ int height = bounds.height - 2*BORDER_WIDTH - (hsbVis ? (SCROLLBAR_WIDTH-2) : 0);
+ Graphics ng = g.create();
+
+@@ -602,7 +591,7 @@
+ }
+ }
+
+- public void paintHSB(Graphics g, Color colors[], Rectangle bounds) {
++ private void paintHSB(Graphics g, Color colors[], Rectangle bounds) {
+
+ }
+
+--- ./jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java Wed Feb 04 12:14:43 2015 -0800
+@@ -45,6 +45,7 @@
+
+ import java.util.ArrayList;
+ import java.util.Iterator;
++import java.util.LinkedHashSet;
+ import java.util.List;
+
+ import javax.imageio.ImageIO;
+@@ -328,8 +329,9 @@
+ * a valid MIME and return a list of flavors to which the data in this MIME
+ * type can be translated by the Data Transfer subsystem.
+ */
+- public List <DataFlavor> getPlatformMappingsForNative(String nat) {
+- List <DataFlavor> flavors = new ArrayList();
++ public LinkedHashSet<DataFlavor> getPlatformMappingsForNative(String nat) {
++ LinkedHashSet<DataFlavor> flavors = new LinkedHashSet<>();
++
+
+ if (nat == null) {
+ return flavors;
+@@ -389,8 +391,8 @@
+ * MIME types to which the data in this flavor can be translated by the Data
+ * Transfer subsystem.
+ */
+- public List getPlatformMappingsForFlavor(DataFlavor df) {
+- List natives = new ArrayList(1);
++ public LinkedHashSet<String> getPlatformMappingsForFlavor(DataFlavor df) {
++ LinkedHashSet<String> natives = new LinkedHashSet<>(1);
+
+ if (df == null) {
+ return natives;
+--- ./jdk/src/solaris/classes/sun/awt/X11/XLightweightFramePeer.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/awt/X11/XLightweightFramePeer.java Wed Feb 04 12:14:43 2015 -0800
+@@ -26,6 +26,7 @@
+ package sun.awt.X11;
+
+ import java.awt.Graphics;
++import java.awt.dnd.DropTarget;
+
+ import sun.awt.LightweightFrame;
+ import sun.swing.JLightweightFrame;
+@@ -69,4 +70,14 @@
+ public void updateCursorImmediately() {
+ SwingAccessor.getJLightweightFrameAccessor().updateCursor((JLightweightFrame)getLwTarget());
+ }
++
++ @Override
++ public void addDropTarget(DropTarget dt) {
++ getLwTarget().addDropTarget(dt);
++ }
++
++ @Override
++ public void removeDropTarget(DropTarget dt) {
++ getLwTarget().removeDropTarget(dt);
++ }
+ }
+--- ./jdk/src/solaris/classes/sun/awt/X11/XRootWindow.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/awt/X11/XRootWindow.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -46,7 +46,8 @@
+ }
+
+ private XRootWindow() {
+- super(new XCreateWindowParams(new Object[] {DELAYED, Boolean.TRUE}));
++ super(new XCreateWindowParams(new Object[] { DELAYED, Boolean.TRUE,
++ EVENT_MASK, XConstants.StructureNotifyMask }));
+ }
+
+ public void postInit(XCreateWindowParams params){
+--- ./jdk/src/solaris/classes/sun/awt/X11/XSelection.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/awt/X11/XSelection.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -42,7 +42,7 @@
+ /**
+ * A class which interfaces with the X11 selection service.
+ */
+-public final class XSelection {
++final class XSelection {
+
+ /* Maps atoms to XSelection instances. */
+ private static final Hashtable<XAtom, XSelection> table = new Hashtable<XAtom, XSelection>();
+@@ -118,11 +118,10 @@
+ /**
+ * Creates a selection object.
+ *
+- * @param atom the selection atom.
+- * @param clpbrd the corresponding clipoboard
+- * @exception NullPointerException if atom is <code>null</code>.
++ * @param atom the selection atom
++ * @throws NullPointerException if atom is {@code null}
+ */
+- public XSelection(XAtom atom) {
++ XSelection(XAtom atom) {
+ if (atom == null) {
+ throw new NullPointerException("Null atom");
+ }
+@@ -134,8 +133,8 @@
+ return selectionAtom;
+ }
+
+- public synchronized boolean setOwner(Transferable contents, Map formatMap,
+- long[] formats, long time)
++ synchronized boolean setOwner(Transferable contents, Map formatMap,
++ long[] formats, long time)
+ {
+ long owner = XWindow.getXAWTRootWindow().getWindow();
+ long selection = selectionAtom.getAtom();
+@@ -433,7 +432,7 @@
+ return data != null ? data : new byte[0];
+ }
+
+- void validateDataGetter(WindowPropertyGetter propertyGetter)
++ private void validateDataGetter(WindowPropertyGetter propertyGetter)
+ throws IOException
+ {
+ // The order of checks is important because a property getter
+--- ./jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Wed Feb 04 12:14:43 2015 -0800
+@@ -102,11 +102,11 @@
+ static TreeMap winMap = new TreeMap();
+ static HashMap specialPeerMap = new HashMap();
+ static HashMap winToDispatcher = new HashMap();
+- private static long _display;
+ static UIDefaults uidefaults;
+- static X11GraphicsEnvironment localEnv;
+- static X11GraphicsDevice device;
+- static final X11GraphicsConfig config;
++ static final X11GraphicsEnvironment localEnv;
++ private static final X11GraphicsDevice device;
++ private static final X11GraphicsConfig config;
++ private static final long display;
+ static int awt_multiclick_time;
+ static boolean securityWarningEnabled;
+
+@@ -117,15 +117,16 @@
+ static {
+ initSecurityWarning();
+ if (GraphicsEnvironment.isHeadless()) {
++ localEnv = null;
++ device = null;
+ config = null;
++ display = 0;
+ } else {
+ localEnv = (X11GraphicsEnvironment) GraphicsEnvironment
+ .getLocalGraphicsEnvironment();
+ device = (X11GraphicsDevice) localEnv.getDefaultScreenDevice();
+- config = (X11GraphicsConfig) (device.getDefaultConfiguration());
+- if (device != null) {
+- _display = device.getDisplay();
+- }
++ config = (X11GraphicsConfig) device.getDefaultConfiguration();
++ display = device.getDisplay();
+ setupModifierMap();
+ initIDs();
+ setBackingStoreType();
+@@ -164,7 +165,7 @@
+ }
+
+
+- public native void nativeLoadSystemColors(int[] systemColors);
++ private native void nativeLoadSystemColors(int[] systemColors);
+
+ static UIDefaults getUIDefaults() {
+ if (uidefaults == null) {
+@@ -196,10 +197,18 @@
+ }
+ }
+
+- static Object displayLock = new Object();
+-
++ /**
++ * Returns the X11 Display of the default screen device.
++ *
++ * @return X11 Display
++ * @throws AWTError thrown if local GraphicsEnvironment is null, which
++ * means we are in the headless environment
++ */
+ public static long getDisplay() {
+- return _display;
++ if (localEnv == null) {
++ throw new AWTError("Local GraphicsEnvironment must not be null");
++ }
++ return display;
+ }
+
+ public static long getDefaultRootWindow() {
+@@ -903,6 +912,11 @@
+ }
+
+ public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException {
++ final LightweightFrame f = SunToolkit.getLightweightFrame(dge.getComponent());
++ if (f != null) {
++ return f.createDragSourceContextPeer(dge);
++ }
++
+ return XDragSourceContextPeer.createDragSourceContextPeer(dge);
+ }
+
+@@ -913,6 +927,11 @@
+ int srcActions,
+ DragGestureListener dgl)
+ {
++ final LightweightFrame f = SunToolkit.getLightweightFrame(c);
++ if (f != null) {
++ return f.createDragGestureRecognizer(recognizerClass, ds, c, srcActions, dgl);
++ }
++
+ if (MouseDragGestureRecognizer.class.equals(recognizerClass))
+ return (T)new XMouseDragGestureRecognizer(ds, c, srcActions, dgl);
+ else
+@@ -2344,9 +2363,7 @@
+
+ private static XEventDispatcher oops_waiter;
+ private static boolean oops_updated;
+- private static boolean oops_failed;
+- private XAtom oops;
+- private static final long WORKAROUND_SLEEP = 100;
++ private static boolean oops_move;
+
+ /**
+ * @inheritDoc
+@@ -2357,52 +2374,33 @@
+ if (oops_waiter == null) {
+ oops_waiter = new XEventDispatcher() {
+ public void dispatchEvent(XEvent e) {
+- if (e.get_type() == XConstants.SelectionNotify) {
+- XSelectionEvent pe = e.get_xselection();
+- if (pe.get_property() == oops.getAtom()) {
+- oops_updated = true;
+- awtLockNotifyAll();
+- } else if (pe.get_selection() == XAtom.get("WM_S0").getAtom() &&
+- pe.get_target() == XAtom.get("VERSION").getAtom() &&
+- pe.get_property() == 0 &&
+- XlibWrapper.XGetSelectionOwner(getDisplay(), XAtom.get("WM_S0").getAtom()) == 0)
+- {
+- // WM forgot to acquire selection or there is no WM
+- oops_failed = true;
+- awtLockNotifyAll();
+- }
+-
++ if (e.get_type() == XConstants.ConfigureNotify) {
++ // OOPS ConfigureNotify event catched
++ oops_updated = true;
++ awtLockNotifyAll();
+ }
+ }
+ };
+ }
+
+- if (oops == null) {
+- oops = XAtom.get("OOPS");
+- }
+-
+ awtLock();
+ try {
+ addEventDispatcher(win.getWindow(), oops_waiter);
+
+ oops_updated = false;
+- oops_failed = false;
+- // Wait for selection notify for oops on win
+ long event_number = getEventNumber();
+- XAtom atom = XAtom.get("WM_S0");
+- if (eventLog.isLoggable(PlatformLogger.Level.FINER)) {
+- eventLog.finer("WM_S0 selection owner {0}", XlibWrapper.XGetSelectionOwner(getDisplay(), atom.getAtom()));
+- }
+- XlibWrapper.XConvertSelection(getDisplay(), atom.getAtom(),
+- XAtom.get("VERSION").getAtom(), oops.getAtom(),
+- win.getWindow(), XConstants.CurrentTime);
++ // Generate OOPS ConfigureNotify event
++ XlibWrapper.XMoveWindow(getDisplay(), win.getWindow(), oops_move ? 0 : 1, 0);
++ // Change win position each time to avoid system optimization
++ oops_move = !oops_move;
+ XSync();
+
+- eventLog.finer("Requested OOPS");
++ eventLog.finer("Generated OOPS ConfigureNotify event");
+
+ long start = System.currentTimeMillis();
+- while (!oops_updated && !oops_failed) {
++ while (!oops_updated) {
+ try {
++ // Wait for OOPS ConfigureNotify event
+ awtLockWait(timeout);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+@@ -2413,20 +2411,8 @@
+ throw new OperationTimedOut(Long.toString(System.currentTimeMillis() - start));
+ }
+ }
+- if (oops_failed && getEventNumber() - event_number == 1) {
+- // If selection update failed we can simply wait some time
+- // hoping some events will arrive
+- awtUnlock();
+- eventLog.finest("Emergency sleep");
+- try {
+- Thread.sleep(WORKAROUND_SLEEP);
+- } catch (InterruptedException ie) {
+- throw new RuntimeException(ie);
+- } finally {
+- awtLock();
+- }
+- }
+- return getEventNumber() - event_number > 2;
++ // Don't take into account OOPS ConfigureNotify event
++ return getEventNumber() - event_number > 1;
+ } finally {
+ removeEventDispatcher(win.getWindow(), oops_waiter);
+ eventLog.finer("Exiting syncNativeQueue");
+--- ./jdk/src/solaris/classes/sun/awt/X11/XWM.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/awt/X11/XWM.java Wed Feb 04 12:14:43 2015 -0800
+@@ -595,8 +595,13 @@
+ return isNetWMName("Mutter") || isNetWMName("GNOME Shell");
+ }
+
++ static int awtWMNonReparenting = -1;
+ static boolean isNonReparentingWM() {
+- return (XWM.getWMID() == XWM.COMPIZ_WM || XWM.getWMID() == XWM.LG3D_WM || XWM.getWMID() == XWM.CWM_WM);
++ if (awtWMNonReparenting == -1) {
++ awtWMNonReparenting = (XToolkit.getEnv("_JAVA_AWT_WM_NONREPARENTING") != null) ? 1 : 0;
++ }
++ return (awtWMNonReparenting == 1 || XWM.getWMID() == XWM.COMPIZ_WM
++ || XWM.getWMID() == XWM.LG3D_WM || XWM.getWMID() == XWM.CWM_WM);
+ }
+
+ /*
+--- ./jdk/src/solaris/classes/sun/awt/X11/XWindow.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/awt/X11/XWindow.java Wed Feb 04 12:14:43 2015 -0800
+@@ -43,7 +43,7 @@
+ import sun.java2d.SunGraphics2D;
+ import sun.java2d.SurfaceData;
+
+-public class XWindow extends XBaseWindow implements X11ComponentPeer {
++class XWindow extends XBaseWindow implements X11ComponentPeer {
+ private static PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XWindow");
+ private static PlatformLogger insLog = PlatformLogger.getLogger("sun.awt.X11.insets.XWindow");
+ private static PlatformLogger eventLog = PlatformLogger.getLogger("sun.awt.X11.event.XWindow");
+@@ -55,7 +55,6 @@
+ */
+ private final static int AWT_MULTICLICK_SMUDGE = 4;
+ // ButtonXXX events stuff
+- static int rbutton = 0;
+ static int lastX = 0, lastY = 0;
+ static long lastTime = 0;
+ static long lastButton = 0;
+@@ -632,23 +631,6 @@
+ return res;
+ }
+
+- /**
+- * Returns true if this event is disabled and shouldn't be passed to Java.
+- * Default implementation returns false for all events.
+- */
+- static int getRightButtonNumber() {
+- if (rbutton == 0) { // not initialized yet
+- XToolkit.awtLock();
+- try {
+- rbutton = XlibWrapper.XGetPointerMapping(XToolkit.getDisplay(), XlibWrapper.ibuffer, 3);
+- }
+- finally {
+- XToolkit.awtUnlock();
+- }
+- }
+- return rbutton;
+- }
+-
+ static int getMouseMovementSmudge() {
+ //TODO: It's possible to read corresponding settings
+ return AWT_MULTICLICK_SMUDGE;
+@@ -716,11 +698,7 @@
+ /*
+ Check for popup trigger !!
+ */
+- if (lbutton == getRightButtonNumber() || lbutton > 2) {
+- popupTrigger = true;
+- } else {
+- popupTrigger = false;
+- }
++ popupTrigger = (lbutton == 3);
+ }
+
+ button = XConstants.buttons[lbutton - 1];
+@@ -858,8 +836,10 @@
+
+
+ // REMIND: need to implement looking for disabled events
+- public native boolean x11inputMethodLookupString(long event, long [] keysymArray);
+- native boolean haveCurrentX11InputMethodInstance();
++ private native boolean x11inputMethodLookupString(long event,
++ long[] keysymArray);
++
++ private native boolean haveCurrentX11InputMethodInstance();
+
+ private boolean mouseAboveMe;
+
+--- ./jdk/src/solaris/classes/sun/awt/X11/XlibWrapper.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/awt/X11/XlibWrapper.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -26,12 +26,12 @@
+ package sun.awt.X11;
+
+ import java.security.AccessController;
+-import java.security.PrivilegedAction;
++
++import sun.misc.Unsafe;
+ import sun.security.action.GetPropertyAction;
+-import sun.misc.*;
+
+-final public class XlibWrapper
+-{
++final class XlibWrapper {
++
+ static Unsafe unsafe = Unsafe.getUnsafe();
+ // strange constants
+ static final int MAXSIZE = 32767;
+@@ -48,7 +48,7 @@
+ char *display_name;
+
+ */
+- public final static String eventToString[]=
++ static final String[] eventToString =
+ {"<none:0>", "<none:1>", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease",
+ "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut",
+ "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify",
+@@ -66,7 +66,7 @@
+
+ /**
+ * Gets byte string from str_ptr and copies it into byte array
+- * String should be NULL terminated
++ * String should be NULL terminated.
+ */
+ static native byte[] getStringBytes(long str_ptr);
+
+@@ -529,7 +529,7 @@
+ display Specifies the connection to the X server.
+ onoff Specifies a Boolean value that indicates whether to enable or disable synchronization.
+ */
+- public static native int XSynchronize(long display, boolean onoff);
++ static native int XSynchronize(long display, boolean onoff);
+
+ /**
+ * Extracts an X event that can be processed in a secondary loop.
+--- ./jdk/src/solaris/classes/sun/awt/X11FontManager.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/awt/X11FontManager.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,3 +1,28 @@
++/*
++ * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 sun.awt;
+
+ import java.awt.GraphicsEnvironment;
+@@ -29,7 +54,7 @@
+ /**
+ * The X11 implementation of {@link FontManager}.
+ */
+-public class X11FontManager extends SunFontManager {
++public final class X11FontManager extends SunFontManager {
+
+ // constants identifying XLFD and font ID fields
+ private static final int FOUNDRY_FIELD = 1;
+@@ -129,8 +154,6 @@
+ */
+ private static String[] fontdirs = null;
+
+- private static String[] defaultPlatformFont = null;
+-
+ private FontConfigManager fcManager = null;
+
+ public static X11FontManager getInstance() {
+@@ -768,11 +791,9 @@
+ return getFontPathNative(noType1Fonts);
+ }
+
+- public String[] getDefaultPlatformFont() {
+- if (defaultPlatformFont != null) {
+- return defaultPlatformFont;
+- }
+- String[] info = new String[2];
++ @Override
++ protected String[] getDefaultPlatformFont() {
++ final String[] info = new String[2];
+ getFontConfigManager().initFontConfigFonts(false);
+ FontConfigManager.FcCompFont[] fontConfigFonts =
+ getFontConfigManager().getFontConfigFonts();
+@@ -798,8 +819,7 @@
+ info[1] = "/dialog.ttf";
+ }
+ }
+- defaultPlatformFont = info;
+- return defaultPlatformFont;
++ return info;
+ }
+
+ public synchronized FontConfigManager getFontConfigManager() {
+--- ./jdk/src/solaris/classes/sun/awt/windows/ThemeReader.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/awt/windows/ThemeReader.java Wed Feb 04 12:14:43 2015 -0800
+@@ -45,6 +45,10 @@
+ return false;
+ }
+
++ public static boolean isXPStyleEnabled() {
++ return false;
++ }
++
+ public static void paintBackground(int[] buffer, String widget,
+ int part, int state, int x, int y, int w, int h, int stride) {
+ }
+--- ./jdk/src/solaris/classes/sun/java2d/xr/XRSolidSrcPict.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/java2d/xr/XRSolidSrcPict.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved.
+
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+@@ -31,12 +31,14 @@
+
+ XRSurfaceData srcPict;
+ XRColor xrCol;
+- int curPixVal = -1;
++ int curPixVal;
+
+ public XRSolidSrcPict(XRBackend con, int parentXid) {
+ this.con = con;
+
+ xrCol = new XRColor();
++ curPixVal = 0xFF000000;
++
+ int solidPixmap = con.createPixmap(parentXid, 32, 1, 1);
+ int solidSrcPictXID = con.createPicture(solidPixmap, XRUtils.PictStandardARGB32);
+ con.setPictureRepeat(solidSrcPictXID, XRUtils.RepeatNormal);
+--- ./jdk/src/solaris/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java Wed Feb 04 12:14:43 2015 -0800
+@@ -77,8 +77,7 @@
+
+ static {
+ defaultDomain = java.security.AccessController.doPrivileged(
+- new sun.security.action.GetPropertyAction("http.auth.ntlm.domain",
+- "domain"));
++ new sun.security.action.GetPropertyAction("http.auth.ntlm.domain", ""));
+ };
+
+ public static boolean supportsTransparentAuth () {
+@@ -100,17 +99,13 @@
+ public String run() {
+ String localhost;
+ try {
+- localhost = InetAddress.getLocalHost().getHostName().toUpperCase();
++ localhost = InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException e) {
+ localhost = "localhost";
+ }
+ return localhost;
+ }
+ });
+- int x = hostname.indexOf ('.');
+- if (x != -1) {
+- hostname = hostname.substring (0, x);
+- }
+ };
+
+ PasswordAuthentication pw;
+--- ./jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -141,7 +141,7 @@
+ Throwable exc = null;
+ try {
+ begin();
+- int n = accept0(this.fd, newfd, isaa);
++ int n = accept(this.fd, newfd, isaa);
+
+ // spurious wakeup, is this possible?
+ if (n == IOStatus.UNAVAILABLE) {
+@@ -277,7 +277,7 @@
+ try {
+ begin();
+
+- int n = accept0(this.fd, newfd, isaa);
++ int n = accept(this.fd, newfd, isaa);
+ if (n == IOStatus.UNAVAILABLE) {
+
+ // need calling context when there is security manager as
+@@ -332,6 +332,18 @@
+ }
+ }
+
++ /**
++ * Accept a connection on a socket.
++ *
++ * @implNote Wrap native call to allow instrumentation.
++ */
++ private int accept(FileDescriptor ssfd, FileDescriptor newfd,
++ InetSocketAddress[] isaa)
++ throws IOException
++ {
++ return accept0(ssfd, newfd, isaa);
++ }
++
+ // -- Native methods --
+
+ private static native void initIDs();
+--- ./jdk/src/solaris/classes/sun/print/CUPSPrinter.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/print/CUPSPrinter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -140,6 +140,9 @@
+ return cupsCustomMediaSNames;
+ }
+
++ public int getDefaultMediaIndex() {
++ return ((pageSizes.length >1) ? (int)(pageSizes[pageSizes.length -1]) : 0);
++ }
+
+ /**
+ * Returns array of MediaPrintableArea derived from PPD.
+@@ -201,8 +204,15 @@
+
+ // add this new custom msn to MediaSize array
+ if ((width > 0.0) && (length > 0.0)) {
++ try {
+ new MediaSize(width, length,
+ Size2DSyntax.INCH, msn);
++ } catch (IllegalArgumentException e) {
++ /* PDF printer in Linux for Ledger paper causes
++ "IllegalArgumentException: X dimension > Y dimension".
++ We rotate based on IPP spec. */
++ new MediaSize(length, width, Size2DSyntax.INCH, msn);
++ }
+ }
+ }
+
+--- ./jdk/src/solaris/classes/sun/print/IPPPrintService.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/print/IPPPrintService.java Wed Feb 04 12:14:43 2015 -0800
+@@ -414,6 +414,7 @@
+ mediaSizeNames = cps.getMediaSizeNames();
+ mediaTrays = cps.getMediaTrays();
+ customMediaSizeNames = cps.getCustomMediaSizeNames();
++ defaultMediaIndex = cps.getDefaultMediaIndex();
+ urlConnection.disconnect();
+ init = true;
+ return;
+@@ -1436,7 +1437,9 @@
+ return JobSheets.STANDARD;
+ }
+ } else if (category == Media.class) {
+- defaultMediaIndex = 0;
++ if (defaultMediaIndex == -1) {
++ defaultMediaIndex = 0;
++ }
+ if (mediaSizeNames.length == 0) {
+ String defaultCountry = Locale.getDefault().getCountry();
+ if (defaultCountry != null &&
+@@ -1452,17 +1455,7 @@
+ if (attribClass != null) {
+ String name = attribClass.getStringValue();
+ if (isCupsPrinter) {
+- for (int i=0; i< customMediaSizeNames.length; i++) {
+- //REMIND: get default from PPD. In native _getMedia,
+- // move default (ppd_option_t->defchoice) to index 0.
+- // In the meantime, use indexOf because PPD name
+- // may be different from the IPP attribute name.
+- if (customMediaSizeNames[i].toString().indexOf(name)
+- != -1) {
+- defaultMediaIndex = i;
+- return mediaSizeNames[defaultMediaIndex];
+- }
+- }
++ return mediaSizeNames[defaultMediaIndex];
+ } else {
+ for (int i=0; i< mediaSizeNames.length; i++) {
+ if (mediaSizeNames[i].toString().indexOf(name) != -1) {
+--- ./jdk/src/solaris/classes/sun/tools/attach/BsdVirtualMachine.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/tools/attach/BsdVirtualMachine.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,14 +24,14 @@
+ */
+ package sun.tools.attach;
+
+-import com.sun.tools.attach.VirtualMachine;
++import com.sun.tools.attach.AttachOperationFailedException;
+ import com.sun.tools.attach.AgentLoadException;
+ import com.sun.tools.attach.AttachNotSupportedException;
+ import com.sun.tools.attach.spi.AttachProvider;
++
+ import java.io.InputStream;
+ import java.io.IOException;
+ import java.io.File;
+-import java.util.Properties;
+
+ /*
+ * Bsd implementation of HotSpotVirtualMachine
+@@ -191,6 +191,8 @@
+ }
+
+ if (completionStatus != 0) {
++ // read from the stream and use that as the error message
++ String message = readErrorMessage(sis);
+ sis.close();
+
+ // In the event of a protocol mismatch then the target VM
+@@ -205,7 +207,11 @@
+ if (cmd.equals("load")) {
+ throw new AgentLoadException("Failed to load agent library");
+ } else {
+- throw new IOException("Command failed in target VM");
++ if (message == null) {
++ throw new AttachOperationFailedException("Command failed in target VM");
++ } else {
++ throw new AttachOperationFailedException(message);
++ }
+ }
+ }
+
+@@ -237,8 +243,9 @@
+ if ((off < 0) || (off > bs.length) || (len < 0) ||
+ ((off + len) > bs.length) || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException();
+- } else if (len == 0)
++ } else if (len == 0) {
+ return 0;
++ }
+
+ return BsdVirtualMachine.read(s, bs, off, len);
+ }
+--- ./jdk/src/solaris/classes/sun/tools/attach/LinuxVirtualMachine.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/tools/attach/LinuxVirtualMachine.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,14 +24,14 @@
+ */
+ package sun.tools.attach;
+
+-import com.sun.tools.attach.VirtualMachine;
++import com.sun.tools.attach.AttachOperationFailedException;
+ import com.sun.tools.attach.AgentLoadException;
+ import com.sun.tools.attach.AttachNotSupportedException;
+ import com.sun.tools.attach.spi.AttachProvider;
++
+ import java.io.InputStream;
+ import java.io.IOException;
+ import java.io.File;
+-import java.util.Properties;
+
+ /*
+ * Linux implementation of HotSpotVirtualMachine
+@@ -207,6 +207,8 @@
+ }
+
+ if (completionStatus != 0) {
++ // read from the stream and use that as the error message
++ String message = readErrorMessage(sis);
+ sis.close();
+
+ // In the event of a protocol mismatch then the target VM
+@@ -221,7 +223,11 @@
+ if (cmd.equals("load")) {
+ throw new AgentLoadException("Failed to load agent library");
+ } else {
+- throw new IOException("Command failed in target VM");
++ if (message == null) {
++ throw new AttachOperationFailedException("Command failed in target VM");
++ } else {
++ throw new AttachOperationFailedException(message);
++ }
+ }
+ }
+
+--- ./jdk/src/solaris/classes/sun/tools/attach/SolarisVirtualMachine.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/tools/attach/SolarisVirtualMachine.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,15 +24,15 @@
+ */
+ package sun.tools.attach;
+
+-import com.sun.tools.attach.VirtualMachine;
++import com.sun.tools.attach.AttachOperationFailedException;
+ import com.sun.tools.attach.AgentLoadException;
+ import com.sun.tools.attach.AttachNotSupportedException;
+ import com.sun.tools.attach.spi.AttachProvider;
++
+ import java.io.InputStream;
+ import java.io.IOException;
+ import java.io.File;
+ import java.io.FileNotFoundException;
+-import java.util.Properties;
+
+ /*
+ * Solaris implementation of HotSpotVirtualMachine.
+@@ -147,11 +147,17 @@
+ // If non-0 it means an error but we need to special-case the
+ // "load" command to ensure that the right exception is thrown.
+ if (completionStatus != 0) {
++ // read from the stream and use that as the error message
++ String message = readErrorMessage(sis);
+ sis.close();
+ if (cmd.equals("load")) {
+ throw new AgentLoadException("Failed to load agent library");
+ } else {
+- throw new IOException("Command failed in target VM");
++ if (message == null) {
++ throw new AttachOperationFailedException("Command failed in target VM");
++ } else {
++ throw new AttachOperationFailedException(message);
++ }
+ }
+ }
+
+--- ./jdk/src/solaris/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -25,100 +25,10 @@
+
+ package sun.util.locale.provider;
+
+-import java.text.DateFormat;
+-import java.text.SimpleDateFormat;
+-import java.text.spi.DateFormatProvider;
+-import java.util.Locale;
+-
+ /**
+ * LocaleProviderAdapter implementation for the Unix locale data
+ *
+ * @author Naoto Sato
+ */
+ public class HostLocaleProviderAdapterImpl {
+- static Locale[] supported = {Locale.getDefault(Locale.Category.FORMAT)};
+-
+- public static DateFormatProvider getDateFormatProvider() {
+- return new DateFormatProvider() {
+- String posixPattern;
+-
+- @Override
+- public Locale[] getAvailableLocales() {
+- // not implemented yet
+- return new Locale[0];
+ }
+- @Override
+- public DateFormat getDateInstance(int style, Locale locale) {
+- posixPattern = getPattern(style, -1, locale.toLanguageTag());
+- return new SimpleDateFormat(convertPosixToJava(posixPattern), locale);
+- }
+- @Override
+- public DateFormat getTimeInstance(int style, Locale locale) {
+- posixPattern = getPattern(-1, style, locale.toLanguageTag());
+- return new SimpleDateFormat(convertPosixToJava(posixPattern), locale);
+- }
+- @Override
+- public DateFormat getDateTimeInstance(int dateStyle,
+- int timeStyle, Locale locale) {
+- posixPattern = getPattern(dateStyle, timeStyle, locale.toLanguageTag());
+- return new SimpleDateFormat(convertPosixToJava(posixPattern), locale);
+- }
+- };
+- }
+-
+- private static String convertPosixToJava(String posixPattern) {
+- StringBuilder sb = new StringBuilder();
+- boolean conversion = false;
+-
+- for (int index = 0; index < posixPattern.length(); index++) {
+- char c = posixPattern.charAt(index);
+- if (conversion) {
+- switch (c) {
+- case 'a':
+- sb.append("EEE");
+- break;
+- case 'b':
+- sb.append("MMM");
+- break;
+- case 'e':
+- sb.append("dd");
+- break;
+- case 'H':
+- sb.append("kk");
+- break;
+- case 'M':
+- sb.append("mm");
+- break;
+- case 'S':
+- sb.append("ss");
+- break;
+- case 'Y':
+- sb.append("yyyy");
+- break;
+- case 'm':
+- sb.append("MM");
+- break;
+- case 'd':
+- sb.append("dd");
+- break;
+- case 'r':
+- sb.append("hh:mm:ss aa");
+- break;
+- case 'Z':
+- sb.append("zzz");
+- break;
+- }
+- conversion = false;
+- } else {
+- if (c == '%') {
+- conversion = true;
+- } else {
+- sb.append(c);
+- }
+- }
+- }
+- return sb.toString();
+- }
+-
+- private static native String getPattern(int dateStyle, int timeStyle, String langtag);
+-}
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/appletviewer.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/appletviewer.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "appletviewer" "1" "2013ǯ11·î21Æü" "JDK 8" "´ðËܥġ¼¥ë"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/extcheck.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/extcheck.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "extcheck" "1" "2013ǯ11·î21Æü" "JDK 8" "´ðËܥġ¼¥ë"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/idlj.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/idlj.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "idlj" "1" "2013ǯ11·î21Æü" "JDK 8" "Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jar.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jar.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jar" "1" "2013ǯ11·î21Æü" "JDK 8" "´ðËܥġ¼¥ë"
+@@ -384,9 +385,7 @@
+ .\}
+ .SH "Îã"
+ .PP
+-\fBÎã 1\fR
+-.br
+-¾éĹ¤Ê½ÐÎϤˤè¤ë¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤ÎÄɲÃ
++\fBÎã 1 \fR¾éĹ¤Ê½ÐÎϤˤè¤ë¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤ÎÄɲÃ
+ .RS 4
+ .sp
+ .if n \{\
+@@ -415,9 +414,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î¥Õ¥¡¥¤¥ë¤ÎÄɲÃ
++\fBÎã 2 \fR¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î¥Õ¥¡¥¤¥ë¤ÎÄɲÃ
+ .RS 4
+ .sp
+ .if n \{\
+@@ -449,9 +446,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 3\fR
+-.br
+-JAR¤Î¥³¥ó¥Æ¥ó¥Ä¤Î¥ê¥¹¥È
++\fBÎã 3 \fRJAR¤Î¥³¥ó¥Æ¥ó¥Ä¤Î¥ê¥¹¥È
+ .RS 4
+ .sp
+ .if n \{\
+@@ -485,9 +480,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 4\fR
+-.br
+-º÷°ú¤ÎÄɲÃ
++\fBÎã 4 \fRº÷°ú¤ÎÄɲÃ
+ .RS 4
+ ³ô¼°¼è°ú¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÎÁê¸ß°Í¸¥¯¥é¥¹¤ò¡¢\fBmain\&.jar\fR¡¢\fBbuy\&.jar\fR¤ª¤è¤Ó\fBsell\&.jar\fR¤Î3¤Ä¤ÎJAR¥Õ¥¡¥¤¥ë¤Ëʬ³ä¤¹¤ë¾ì¹ç¡¢\fBi\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Þ¤¹¡£\fBmain\&.jar\fR¥Þ¥Ë¥Õ¥§¥¹¥ÈÆâ¤Î\fBClass\-Path\fR°À­¤ò»ØÄꤹ¤ë¾ì¹ç¡¢\fBi\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¥¯¥é¥¹¡¦¥í¡¼¥É¤Î®ÅÙ¤ò¸þ¾å¤Ç¤­¤Þ¤¹¡£
+ .sp
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jarsigner.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jarsigner.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jarsigner" "1" "2013ǯ11·î21Æü" "JDK 8" "¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë"
+@@ -344,7 +345,7 @@
+ .PP
+ ¤³¤ì¤é2¤Ä¤Î¥Õ¥¡¥¤¥ë¤Î¥Ù¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾¤Ï¡¢\fB\-sigFile\fR¥ª¥×¥·¥ç¥ó¤ÎÃͤ«¤éºîÀ®¤µ¤ì¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¥ª¥×¥·¥ç¥ó¤¬\fB\-sigFile MKSIGN\fR¤Î¾ì¹ç¡¢¥Õ¥¡¥¤¥ë¤Ï\fBMKSIGN\&.SF\fR¤ª¤è¤Ó\fBMKSIGN\&.DSA\fR¤È¤¤¤¦Ì¾Á°¤Ë¤Ê¤ê¤Þ¤¹¡£
+ .PP
+-¥³¥Þ¥ó¥É¹Ô¤Ç\fB\-sigfile\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¡¢\fB\&.SF\fR¥Õ¥¡¥¤¥ë¤È\fB\&.DSA\fR¥Õ¥¡¥¤¥ë¤Î¥Ù¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤵ¤ì¤¿ÊÌ̾¤ÎÀèƬ¤Î8ʸ»ú¤ò¤¹¤Ù¤ÆÂçʸ»ú¤ËÊÑ´¹¤·¤¿¤â¤Î¤Ë¤Ê¤ê¤Þ¤¹¡£ÊÌ̾¤¬8ʸ»ṳ́Ëþ¤Î¾ì¹ç¤Ï¡¢ÊÌ̾¤¬¤½¤Î¤Þ¤Þ»ÈÍѤµ¤ì¤Þ¤¹¡£ÊÌ̾¤Ë¡¢½ð̾¥Õ¥¡¥¤¥ë̾¤Ç»ÈÍѤǤ­¤Ê¤¤Ê¸»ú¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥Õ¥¡¥¤¥ë̾¤ÎºîÀ®»þ¤Ë¡¢³ºÅö¤¹¤ëʸ»ú¤¬²¼Àþ(_)ʸ»ú¤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£Í­¸ú¤Êʸ»ú¤Ï¡¢¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¡¢¿ô»ú¡¢²¼Àþ¤ª¤è¤Ó¥Ï¥¤¥Õ¥ó¤Ç¤¹¡£
++¥³¥Þ¥ó¥É¹Ô¤Ç\fB\-sigfile\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¡¢\fB\&.SF\fR¥Õ¥¡¥¤¥ë¤È\fB\&.DSA\fR¥Õ¥¡¥¤¥ë¤Î¥Ù¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤵ¤ì¤¿ÊÌ̾¤ÎÀèƬ¤Î8ʸ»ú¤ò¤¹¤Ù¤ÆÂçʸ»ú¤ËÊÑ´¹¤·¤¿¤â¤Î¤Ë¤Ê¤ê¤Þ¤¹¡£ÊÌ̾¤¬8ʸ»ṳ́Ëþ¤Î¾ì¹ç¤Ï¡¢ÊÌ̾¤¬¤½¤Î¤Þ¤Þ»ÈÍѤµ¤ì¤Þ¤¹¡£ÊÌ̾¤Ë¡¢½ð̾¥Õ¥¡¥¤¥ë̾¤Ç»ÈÍѤǤ­¤Ê¤¤Ê¸»ú¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥Õ¥¡¥¤¥ë̾¤ÎºîÀ®»þ¤Ë¡¢³ºÅö¤¹¤ëʸ»ú¤¬¥¢¥ó¥À¡¼¥¹¥³¥¢(_)ʸ»ú¤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£Í­¸ú¤Êʸ»ú¤Ï¡¢¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¡¢¿ô»ú¡¢¥¢¥ó¥À¡¼¥¹¥³¥¢¤ª¤è¤Ó¥Ï¥¤¥Õ¥ó¤Ç¤¹¡£
+ .PP
+ ½ð̾¥Õ¥¡¥¤¥ë
+ .PP
+@@ -521,7 +522,7 @@
+ .sp -1
+ .IP \(bu 2.3
+ .\}
+-¥¤¥¿¥ê¥Ã¥¯ÂΤޤ¿¤Ï²¼ÀþÉÕ¤­¤Î¹àÌÜ(¥ª¥×¥·¥ç¥ó¤ÎÃÍ)¤Î¼ÂºÝ¤ÎÃͤϡ¢»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
++¥¤¥¿¥ê¥Ã¥¯¤Þ¤¿¤Ï²¼ÀþÉÕ¤­¤Î¹àÌÜ(¥ª¥×¥·¥ç¥ó¤ÎÃÍ)¤Î¼ÂºÝ¤ÎÃͤϡ¢»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .sp
+ .RS 4
+@@ -664,9 +665,9 @@
+ .RS 4
+ À¸À®¤µ¤ì¤¿\fB\&.SF\fR¥Õ¥¡¥¤¥ë¤ª¤è¤Ó\fB\&.DSA\fR¥Õ¥¡¥¤¥ë¤Ë»ÈÍѤ¹¤ë¥Ù¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾¤ò»ØÄꤷ¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¥Õ¥¡¥¤¥ë¤¬\fBDUKESIGN\fR¤Î¾ì¹ç¡¢À¸À®¤µ¤ì¤ë\fB\&.SF\fR¤ª¤è¤Ó\fB\&.DSA\fR¥Õ¥¡¥¤¥ë¤Ï¡¢\fBDUKESIGN\&.SF\fR¤ª¤è¤Ó\fBDUKESIGN\&.DSA\fR¤È¤¤¤¦Ì¾Á°¤Ç¡¢½ð̾ÉÕ¤­JAR¥Õ¥¡¥¤¥ë¤Î\fBMETA\-INF\fR¥Ç¥£¥ì¥¯¥È¥ê¤Ë³ÊǼ¤µ¤ì¤Þ¤¹¡£
+ .sp
+-¥Õ¥¡¥¤¥ëÆâ¤Îʸ»ú¤Ï¡¢¥»¥Ã¥È\fBa\-zA\-Z0\-9_\-\fR¤«¤é»ØÄꤵ¤ì¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¡¢¿ô»ú¡¢²¼Àþ¤ª¤è¤Ó¥Ï¥¤¥Õ¥óʸ»ú¤Î¤ß¤ò»ÈÍѤǤ­¤Þ¤¹¡£\fB\&.SF\fR¤ª¤è¤Ó\fB\&.DSA\fR¤Î¥Õ¥¡¥¤¥ë̾¤Ç¤Ï¡¢¾®Ê¸»ú¤Ï¤¹¤Ù¤ÆÂçʸ»ú¤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£
++¥Õ¥¡¥¤¥ëÆâ¤Îʸ»ú¤Ï¡¢¥»¥Ã¥È\fBa\-zA\-Z0\-9_\-\fR¤«¤é»ØÄꤵ¤ì¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¡¢¿ô»ú¡¢¥¢¥ó¥À¡¼¥¹¥³¥¢¤ª¤è¤Ó¥Ï¥¤¥Õ¥óʸ»ú¤Î¤ß¤ò»ÈÍѤǤ­¤Þ¤¹¡£\fB\&.SF\fR¤ª¤è¤Ó\fB\&.DSA\fR¤Î¥Õ¥¡¥¤¥ë̾¤Ç¤Ï¡¢¾®Ê¸»ú¤Ï¤¹¤Ù¤ÆÂçʸ»ú¤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£
+ .sp
+-¥³¥Þ¥ó¥É¹Ô¤Ç\fB\-sigfile\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¡¢\fB\&.SF\fR¥Õ¥¡¥¤¥ë¤È\fB\&.DSA\fR¥Õ¥¡¥¤¥ë¤Î¥Ù¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤵ¤ì¤¿ÊÌ̾¤ÎÀèƬ¤Î8ʸ»ú¤ò¤¹¤Ù¤ÆÂçʸ»ú¤ËÊÑ´¹¤·¤¿¤â¤Î¤Ë¤Ê¤ê¤Þ¤¹¡£ÊÌ̾¤¬8ʸ»ṳ́Ëþ¤Î¾ì¹ç¤Ï¡¢ÊÌ̾¤¬¤½¤Î¤Þ¤Þ»ÈÍѤµ¤ì¤Þ¤¹¡£ÊÌ̾¤Ë¡¢½ð̾¥Õ¥¡¥¤¥ë̾¤Ç̵¸ú¤Êʸ»ú¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥Õ¥¡¥¤¥ë̾¤òºîÀ®¤¹¤ë¤¿¤á¤Ë¡¢³ºÅö¤¹¤ëʸ»ú¤¬²¼Àþ(_)ʸ»ú¤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£
++¥³¥Þ¥ó¥É¹Ô¤Ç\fB\-sigfile\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¡¢\fB\&.SF\fR¥Õ¥¡¥¤¥ë¤È\fB\&.DSA\fR¥Õ¥¡¥¤¥ë¤Î¥Ù¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤵ¤ì¤¿ÊÌ̾¤ÎÀèƬ¤Î8ʸ»ú¤ò¤¹¤Ù¤ÆÂçʸ»ú¤ËÊÑ´¹¤·¤¿¤â¤Î¤Ë¤Ê¤ê¤Þ¤¹¡£ÊÌ̾¤¬8ʸ»ṳ́Ëþ¤Î¾ì¹ç¤Ï¡¢ÊÌ̾¤¬¤½¤Î¤Þ¤Þ»ÈÍѤµ¤ì¤Þ¤¹¡£ÊÌ̾¤Ë¡¢½ð̾¥Õ¥¡¥¤¥ë̾¤Ç̵¸ú¤Êʸ»ú¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥Õ¥¡¥¤¥ë̾¤òºîÀ®¤¹¤ë¤¿¤á¤Ë¡¢³ºÅö¤¹¤ëʸ»ú¤¬¥¢¥ó¥À¡¼¥¹¥³¥¢(_)ʸ»ú¤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ \-sigalg \fIalgorithm\fR
+@@ -1001,7 +1002,7 @@
+ .RE
+ .\}
+ .PP
+-¸¡¾Ú¤¬À®¸ù¤¹¤ë¤È¡¢\fBjar verified\fR¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£¤½¤¦¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢¥¨¥é¡¼¡¦¥á¥Ã¥»¡¼¥¸¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£\fB\-verbose\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤È¡¢¾ÜºÙ¾ðÊó¤ò¼èÆÀ¤Ç¤­¤Þ¤¹¡£\fBjarsigner\fR¤ò\fB\-verbose\fR¥ª¥×¥·¥ç¥ó¤È¤È¤â¤Ë»ÈÍѤ¹¤ë¥µ¥ó¥×¥ë¤ò¡¢¼¡¤Ë¼¨¤·¤Þ¤¹¡£
++¸¡¾Ú¤¬À®¸ù¤¹¤ë¤È¡¢\fBjar verified\fR¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£Í­¸ú¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢¥¨¥é¡¼¡¦¥á¥Ã¥»¡¼¥¸¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£\fB\-verbose\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤È¡¢¾ÜºÙ¾ðÊó¤ò¼èÆÀ¤Ç¤­¤Þ¤¹¡£\fBjarsigner\fR¤ò\fB\-verbose\fR¥ª¥×¥·¥ç¥ó¤È¤È¤â¤Ë»ÈÍѤ¹¤ë¥µ¥ó¥×¥ë¤ò¡¢¼¡¤Ë¼¨¤·¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/java.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/java.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: java
+ .\" Language: Japanese
+-.\" Date: 2014ǯ8·î8Æü
++.\" Date: 2015ǯ3·î3Æü
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "java" "1" "2014ǯ8·î8Æü" "JDK 8" "´ðËܥġ¼¥ë"
++.TH "java" "1" "2015ǯ3·î3Æü" "JDK 8" "´ðËܥġ¼¥ë"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -652,7 +653,7 @@
+ .PP
+ \-Xmx\fIsize\fR
+ .RS 4
+-¥á¥â¥ê¡¼³äÅö¤Æ¥×¡¼¥ë¤ÎºÇÂ祵¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤ò»ØÄꤷ¤Þ¤¹¡£»ØÄꤹ¤ëÃͤϡ¢2MB¤è¤êÂ礭¤¤1024¤ÎÇÜ¿ô¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢¼Â¹Ô»þ¤Ë¥·¥¹¥Æ¥à¹½À®¤Ë´ð¤Å¤¤¤ÆÁªÂò¤µ¤ì¤Þ¤¹¡£¥µ¡¼¥Ð¡¼¡¦¥Ç¥×¥í¥¤¥á¥ó¥È¤Ç¤Ï¡¢\fB\-Xms\fR¤ª¤è¤Ó\fB\-Xmx\fR¤ÏÄ̾ïƱ¤¸ÃͤËÀßÄꤵ¤ì¤Þ¤¹¡£¾ÜºÙ¤Ï¡¢http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gc\-ergonomics\&.html¤Ë¤¢¤ë¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥¿¡¦¥¨¥ë¥´¥Î¥ß¥Ã¥¯¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++¥á¥â¥ê¡¼³äÅö¤Æ¥×¡¼¥ë¤ÎºÇÂ祵¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤ò»ØÄꤷ¤Þ¤¹¡£»ØÄꤹ¤ëÃͤϡ¢2MB¤è¤êÂ礭¤¤1024¤ÎÇÜ¿ô¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢¼Â¹Ô»þ¤Ë¥·¥¹¥Æ¥à¹½À®¤Ë´ð¤Å¤¤¤ÆÁªÂò¤µ¤ì¤Þ¤¹¡£¥µ¡¼¥Ð¡¼¡¦¥Ç¥×¥í¥¤¥á¥ó¥È¤Ç¤Ï¡¢\fB\-Xms\fR¤ª¤è¤Ó\fB\-Xmx\fR¤ÏÄ̾ïƱ¤¸ÃͤËÀßÄꤵ¤ì¤Þ¤¹¡£http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gctuning/index\&.html¤Î\fIJava SE HotSpot²¾ÁÛ¥Þ¥·¥ó¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¡¦¥Á¥å¡¼¥Ë¥ó¥°¡¦¥¬¥¤¥É\fR¤Î¥¨¥ë¥´¥Î¥ß¥¯¥¹¤Ë´Ø¤¹¤ë¹à¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ ¼¡¤ÎÎã¤Ç¤Ï¡¢³ä¤êÅö¤Æ¤é¤ì¤¿¥á¥â¥ê¡¼¤Îµö²Ä¤µ¤ì¤ëºÇÂ祵¥¤¥º¤òÍÍ¡¹¤Êñ°Ì¤ò»ÈÍѤ·¤Æ80MB¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
+ .sp
+@@ -877,14 +878,14 @@
+ .RS 4
+ ¥Ð¥¤¥È¥³¡¼¥É¡¦¥Ù¥ê¥Õ¥¡¥¤¥¢¤Î¥â¡¼¥É¤òÀßÄꤷ¤Þ¤¹¡£¥Ð¥¤¥È¥³¡¼¥É¤Î¸¡¾Ú¤Ï°ìÉô¤ÎÌäÂê¤Î¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¤ËÌòΩ¤Á¤Þ¤¹¤¬¡¢¼Â¹ÔÃæ¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ø¤Î¥ª¡¼¥Ð¡¼¥Ø¥Ã¥É¤òÁýÂ礵¤»¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ç»ÈÍѲÄǽ¤Ê\fImode\fR°ú¿ô¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹¡£
+ .PP
+-none
++¤Ê¤·
+ .RS 4
+ ¥Ð¥¤¥È¥³¡¼¥É¤ò¸¡¾Ú¤·¤Þ¤»¤ó¡£¤³¤ì¤Ë¤è¤ê¡¢µ¯Æ°»þ´Ö¤¬Ã»½Ì¤µ¤ì¡¢Java¤Ë¤è¤Ã¤ÆÄ󶡤µ¤ì¤ëÊݸî¤â·Ú¸º¤µ¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ remote
+ .RS 4
+-¥Í¥Ã¥È¥ï¡¼¥¯¤ò²ð¤·¤Æ¥ê¥â¡¼¥È¤Ç¥í¡¼¥É¤µ¤ì¤ë¥¯¥é¥¹¤Î¤ß¤ò¸¡¾Ú¤·¤Þ¤¹¡£¤³¤ì¤Ï¡¢\fB\-Xverify\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤¤¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¤ÎÆ°ºî¤Ç¤¹¡£
++¥Ö¡¼¥È¥¹¥È¥é¥Ã¥×¡¦¥¯¥é¥¹¡¦¥í¡¼¥À¡¼¤Ç¥í¡¼¥É¤µ¤ì¤Æ¤¤¤Ê¤¤¤³¤ì¤é¤Î¥¯¥é¥¹¤ò¸¡¾Ú¤·¤Þ¤¹¡£¤³¤ì¤Ï¡¢\fB\-Xverify\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤¤¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¤ÎÆ°ºî¤Ç¤¹¡£
+ .RE
+ .PP
+ all
+@@ -938,9 +939,9 @@
+ .PP
+ \-XX:LargePageSizeInBytes=\fIsize\fR
+ .RS 4
+-Java¥Ò¡¼¥×¤Ë»ÈÍѤµ¤ì¤ëÂ礭¤¤¥Ú¡¼¥¸¤ÎºÇÂ祵¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£\fIsize\fR°ú¿ô¤Ï¡¢2¤ÎÎß¾è(2¡¢4¡¢8¡¢16¡¢\&.\&.\&.)¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥µ¥¤¥º¤Ï0¤ËÀßÄꤵ¤ì¡¢¤³¤ì¤Ï¡¢JVM¤Ç¤ÏÂ礭¤¤¥Ú¡¼¥¸¤Î¥µ¥¤¥º¤¬¼«Æ°Åª¤ËÁªÂò¤µ¤ì¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£
++Solaris¤Ç¤Ï¡¢Java¥Ò¡¼¥×¤Ë»ÈÍѤµ¤ì¤ë¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ÎºÇÂ祵¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£\fIsize\fR°ú¿ô¤Ï¡¢2¤ÎÎß¾è(2¡¢4¡¢8¡¢16¡¢\&.\&.\&.)¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥µ¥¤¥º¤Ï0¤ËÀßÄꤵ¤ì¡¢¤³¤ì¤Ï¡¢JVM¤Ç¤Ï¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¥µ¥¤¥º¤¬¼«Æ°Åª¤ËÁªÂò¤µ¤ì¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£
+ .sp
+-¼¡¤ÎÎã¤Ç¤Ï¡¢Â礭¤¤¥Ú¡¼¥¸¤Î¥µ¥¤¥º¤ò4¥á¥¬¥Ð¥¤¥È(MB)¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
++¼¡¤ÎÎã¤Ç¤Ï¡¢¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¥µ¥¤¥º¤ò4¥á¥¬¥Ð¥¤¥È(MB)¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+@@ -995,6 +996,17 @@
+ .RE
+ .RE
+ .PP
++\-XX:ObjectAlignmentInBytes=\fIalignment\fR
++.RS 4
++Java¥ª¥Ö¥¸¥§¥¯¥È¤Î¥á¥â¥ê¡¼ÇÛÃÖ¤òÀßÄꤷ¤Þ¤¹(¥Ð¥¤¥Èñ°Ì)¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢Ãͤ¬8¥Ð¥¤¥È¤ËÀßÄꤵ¤ì¤Þ¤¹¡£»ØÄꤵ¤ì¤ëÃͤϡ¢2¤ÎÎß¾è¤Ë¤·¤Æ8¤«¤é256(ξü¤ò´Þ¤à)¤ÎÈÏ°ÏÆâ¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¡¢Â礭¤¤Java¥Ò¡¼¥×¡¦¥µ¥¤¥º¤Ç°µ½Ì¥Ý¥¤¥ó¥¿¤ò»ÈÍѤǤ­¤Þ¤¹¡£
++.sp
++¥Ð¥¤¥Èñ°Ì¤Î¥Ò¡¼¥×¡¦¥µ¥¤¥ºÀ©¸Â¤Ï¼¡¤Î¤è¤¦¤Ë·×»»¤µ¤ì¤Þ¤¹:
++.sp
++\fB4GB * ObjectAlignmentInBytes\fR
++.sp
++Ãí°Õ: ÇÛÃÖ¤ÎÃͤ¬Áý¤¨¤ë¤È¡¢¥ª¥Ö¥¸¥§¥¯¥È´Ö¤Î̤»ÈÍѤÎÎΰè¤âÁý¤¨¤Þ¤¹¡£·ë²Ì¤È¤·¤Æ¡¢Â礭¤¤¥Ò¡¼¥×¡¦¥µ¥¤¥º¤Ç°µ½Ì¥Ý¥¤¥ó¥¿¤ò»ÈÍѤ¹¤ë¥á¥ê¥Ã¥È¤¬¤ï¤«¤é¤Ê¤¤²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£
++.RE
++.PP
+ \-XX:OnError=\fIstring\fR
+ .RS 4
+ ¥ê¥«¥Ð¥êÉÔǽ¤Ê¥¨¥é¡¼¤¬È¯À¸¤·¤¿¤È¤­¤Ë¼Â¹Ô¤¹¤ë¡¢¥«¥¹¥¿¥à¡¦¥³¥Þ¥ó¥É¤Þ¤¿¤Ï°ìÏ¢¤Î¥»¥ß¥³¥í¥ó¶èÀÚ¤ê¤Î¥³¥Þ¥ó¥É¤òÀßÄꤷ¤Þ¤¹¡£Ê¸»úÎó¤Ë¶õÇò¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢°úÍÑÉä¤Ç°Ï¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+@@ -1018,6 +1030,22 @@
+ \fBOutOfMemoryError\fRÎã³°¤¬ºÇ½é¤Ë¥¹¥í¡¼¤µ¤ì¤¿¤È¤­¤Ë¼Â¹Ô¤¹¤ë¡¢¥«¥¹¥¿¥à¡¦¥³¥Þ¥ó¥É¤Þ¤¿¤Ï°ìÏ¢¤Î¥»¥ß¥³¥í¥ó¶èÀÚ¤ê¤Î¥³¥Þ¥ó¥É¤òÀßÄꤷ¤Þ¤¹¡£Ê¸»úÎó¤Ë¶õÇò¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢°úÍÑÉä¤Ç°Ï¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥³¥Þ¥ó¥Éʸ»úÎó¤ÎÎã¤Ï¡¢\fB\-XX:OnError\fR¥ª¥×¥·¥ç¥ó¤ÎÀâÌÀ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .RE
+ .PP
++\-XX:+PerfDataSaveToFile
++.RS 4
++Í­¸ú¤Ê¾ì¹ç¡¢Java¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î½ªÎ»»þ¤Ëjstat(1)¥Ð¥¤¥Ê¥ê¡¦¥Ç¡¼¥¿¤òÊݸ¤·¤Þ¤¹¡£¤³¤Î¥Ð¥¤¥Ê¥ê¡¦¥Ç¡¼¥¿¤Ï\fBhsperfdata_\fR\fI<pid>\fR¤È¤¤¤¦Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Þ¤¹¡£\fI<pid>\fR¤Ï¡¢¼Â¹Ô¤·¤¿Java¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¥×¥í¥»¥¹¼±Ê̻ҤǤ¹¡£¼¡¤Î¤è¤¦¤Ë\fBjstat\fR¤ò»ÈÍѤ·¤Æ¡¢¤³¤Î¥Õ¥¡¥¤¥ë¤Ë´Þ¤Þ¤ì¤ë¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¡¦¥Ç¡¼¥¿¤òɽ¼¨¤·¤Þ¤¹¡£
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjstat \-class file:///\fR\fB\fI<path>\fR\fR\fB/hsperfdata_\fR\fB\fI<pid>\fR\fR
++\fBjstat \-gc file:///\fR\fB\fI<path>\fR\fR\fB/hsperfdata_\fR\fB\fI<pid>\fR\fR
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.PP
+ \-XX:+PrintCommandLineFlags
+ .RS 4
+ ¥³¥Þ¥ó¥É¹Ô¤Ëɽ¼¨¤µ¤ì¤¿¡¢¿Í´Ö¹©³ØŪ¤ËÁªÂò¤·¤¿JVM¥Õ¥é¥°¤Î°õºþ¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤ì¤Ï¡¢¥Ò¡¼¥×Îΰ襵¥¤¥º¤äÁªÂò¤µ¤ì¤¿¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥¿¤Ê¤É¡¢JVM¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤¿¥¨¥ë¥´¥Î¥ß¥Ã¥¯Ãͤò³Îǧ¤¹¤ë¾ì¹ç¤ËÌòΩ¤Á¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¢¤ê¡¢¥Õ¥é¥°¤Ï°õºþ¤µ¤ì¤Þ¤»¤ó¡£
+@@ -1166,25 +1194,32 @@
+ JVMÆâÉô¥·¥°¥Ê¥ë¤Î\fBSIGUSR1\fR¤ª¤è¤Ó\fBSIGUSR2\fR¤Î¤«¤ï¤ê¤Ë¡¢ÂåÂØ¥·¥°¥Ê¥ë¤Î»ÈÍѤòÍ­¸ú¤Ë¤·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¢¤ê¡¢ÂåÂØ¥·¥°¥Ê¥ë¤Ï»ÈÍѤµ¤ì¤Þ¤»¤ó¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï\fB\-Xusealtsigs\fR¤ÈƱÅù¤Ç¤¹¡£
+ .RE
+ .PP
+-\-XX:+UseBiasedLocking
+-.RS 4
+-¥Ð¥¤¥¢¥¹¡¦¥í¥Ã¥¯¤Î»ÈÍѤòÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤«¤Ê¤ê¤ÎÎ̤ÎÈ󶥹ç¤ÎƱ´ü²½¤¬¤¢¤ë°ìÉô¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¡¢¤³¤Î¥Õ¥é¥°¤òÍ­¸ú¤Ë¤¹¤ë¤ÈÂçÉý¤Ê¹â®²½¤¬¼Â¸½¤·¤Þ¤¹¤¬¡¢ÆÃÄê¤Î¥Ñ¥¿¡¼¥ó¤Î¥í¥Ã¥¯¤¬¤¢¤ë¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¡¢Â®ÅÙ¤¬Äã²¼¤¹¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£¥Ð¥¤¥¢¥¹¡¦¥í¥Ã¥¯¤ÎÊýË¡¤Î¾ÜºÙ¤Ï¡¢http://www\&.oracle\&.com/technetwork/java/tuning\-139912\&.html#section4\&.2\&.5¤Ë¤¢¤ëJava¥Á¥å¡¼¥Ë¥ó¥°¤Î¥Û¥ï¥¤¥È¡¦¥Ú¡¼¥Ñ¡¼¤ÎÎã¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++\-XX:\-UseBiasedLocking
++.RS 4
++¥Ð¥¤¥¢¥¹¡¦¥í¥Ã¥¯¤Î»ÈÍѤò̵¸ú¤Ë¤·¤Þ¤¹¡£¤«¤Ê¤ê¤ÎÎ̤ÎÈ󶥹ç¤ÎƱ´ü²½¤¬¤¢¤ë°ìÉô¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¡¢¤³¤Î¥Õ¥é¥°¤òÍ­¸ú¤Ë¤¹¤ë¤ÈÂçÉý¤Ê¹â®²½¤¬¼Â¸½¤·¤Þ¤¹¤¬¡¢ÆÃÄê¤Î¥Ñ¥¿¡¼¥ó¤Î¥í¥Ã¥¯¤¬¤¢¤ë¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¡¢Â®ÅÙ¤¬Äã²¼¤¹¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£¥Ð¥¤¥¢¥¹¡¦¥í¥Ã¥¯¤ÎÊýË¡¤Î¾ÜºÙ¤Ï¡¢http://www\&.oracle\&.com/technetwork/java/tuning\-139912\&.html#section4\&.2\&.5¤Ë¤¢¤ëJava¥Á¥å¡¼¥Ë¥ó¥°¤Î¥Û¥ï¥¤¥È¡¦¥Ú¡¼¥Ñ¡¼¤ÎÎã¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤ÏÍ­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£
+ .RE
+ .PP
+-\-XX:+UseCompressedOops
+-.RS 4
+-°µ½Ì¤µ¤ì¤¿¥Ý¥¤¥ó¥¿¤Î»ÈÍѤòÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤òÍ­¸ú¤Ë¤¹¤ë¤È¡¢¥ª¥Ö¥¸¥§¥¯¥È»²¾È¤Ï¡¢64¥Ó¥Ã¥È¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ï¤Ê¤¯32¥Ó¥Ã¥È¤Î¥ª¥Õ¥»¥Ã¥È¤È¤·¤Æɽ¤µ¤ì¡¢¤³¤ì¤Ë¤è¤ê¡¢32GB¤è¤ê¾®¤µ¤¤Java¥Ò¡¼¥×¡¦¥µ¥¤¥º¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¼Â¹Ô»þ¤Ë¡¢Ä̾¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤¬¸þ¾å¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢64¥Ó¥Ã¥È¤ÎJVM¤Ç¤Î¤ßµ¡Ç½¤·¤Þ¤¹¡£
++\-XX:\-UseCompressedOops
++.RS 4
++°µ½Ì¤µ¤ì¤¿¥Ý¥¤¥ó¥¿¤Î»ÈÍѤò̵¸ú¤Ë¤·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¤³¤Î¥ª¥×¥·¥ç¥ó¤¬Í­¸ú¤Ç¤¢¤ê¡¢Java¥Ò¡¼¥×¡¦¥µ¥¤¥º¤¬32GB¤è¤ê¾®¤µ¤¤¾ì¹ç¤Ë°µ½Ì¥Ý¥¤¥ó¥¿¤¬»ÈÍѤµ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤òÍ­¸ú¤Ë¤¹¤ë¤È¡¢¥ª¥Ö¥¸¥§¥¯¥È»²¾È¤Ï¡¢64¥Ó¥Ã¥È¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ï¤Ê¤¯32¥Ó¥Ã¥È¤Î¥ª¥Õ¥»¥Ã¥È¤È¤·¤Æɽ¤µ¤ì¡¢¤³¤ì¤Ë¤è¤ê¡¢32GB¤è¤ê¾®¤µ¤¤Java¥Ò¡¼¥×¡¦¥µ¥¤¥º¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¼Â¹Ô»þ¤Ë¡¢Ä̾¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤¬¸þ¾å¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢64¥Ó¥Ã¥È¤ÎJVM¤Ç¤Î¤ßµ¡Ç½¤·¤Þ¤¹¡£
+ .sp
+-¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¢¤ê¡¢°µ½Ì¥Ý¥¤¥ó¥¿¤Ï»ÈÍѤµ¤ì¤Þ¤»¤ó¡£
++Java¥Ò¡¼¥×¡¦¥µ¥¤¥º¤¬32GB¤è¤êÂ礭¤¤¾ì¹ç¤Ë¤â°µ½Ì¥Ý¥¤¥ó¥¿¤ò»ÈÍѤǤ­¤Þ¤¹¡£\fB\-XX:ObjectAlignmentInBytes\fR¥ª¥×¥·¥ç¥ó¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++.RE
++.PP
++\-XX:+UseHugeTLBFS
++.RS 4
++LinuxÍѤΤ³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢\fB\-XX:+UseLargePages\fR¤ò»ØÄꤹ¤ë¤Î¤ÈƱ¤¸¤Ç¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥á¥â¥ê¡¼¤ÎͽÌó»þ¤Ë¤¹¤Ù¤Æ¤Î¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ò»öÁ°¤Ë³ä¤êÅö¤Æ¤Þ¤¹¡£¤½¤Î¤¿¤á¡¢JVM¤Ï¥é¡¼¥¸¡¦¥Ú¡¼¥¸¡¦¥á¥â¥ê¡¼Îΰè¤òưŪ¤Ë³ÈÄ¥¤Þ¤¿¤Ï½Ì¾®¤Ç¤­¤Þ¤»¤ó¡£¤³¤ÎÆ°ºî¤ò¹Ô¤¦¾ì¹ç¤Ï¡¢\fB\-XX:UseTransparentHugePages\fR¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++.sp
++¾ÜºÙ¤Ï¡¢"¥é¡¼¥¸¡¦¥Ú¡¼¥¸"¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .RE
+ .PP
+ \-XX:+UseLargePages
+ .RS 4
+-Â礭¤¤¥Ú¡¼¥¸¤Î¥á¥â¥ê¡¼¤Î»ÈÍѤòÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Ç¥Õ¥©¥ë¥È¤ÇÍ­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£Â礭¤¤¥Ú¡¼¥¸¤Î¥á¥â¥ê¡¼¤Î»ÈÍѤò̵¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢\fB\-XX:\-UseLargePages\fR¤ò»ØÄꤷ¤Þ¤¹¡£
++¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¥á¥â¥ê¡¼¤Î»ÈÍѤòÍ­¸ú¤Ë¤·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¢¤ê¡¢¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¥á¥â¥ê¡¼¤Ï»ÈÍѤµ¤ì¤Þ¤»¤ó¡£
+ .sp
+-¾ÜºÙ¤Ï¡¢http://www\&.oracle\&.com/technetwork/java/javase/tech/largememory\-jsp\-137182\&.html¤Ë¤¢¤ëÂ礭¤¤¥á¥â¥ê¡¼¡¦¥Ú¡¼¥¸ÍѤÎJava¥µ¥Ý¡¼¥È¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++¾ÜºÙ¤Ï¡¢"¥é¡¼¥¸¡¦¥Ú¡¼¥¸"¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .RE
+ .PP
+ \-XX:+UseMembar
+@@ -1197,6 +1232,13 @@
+ \fBperfdata\fRµ¡Ç½¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Ç¥Õ¥©¥ë¥È¤ÇÍ­¸ú¤Ë¤Ê¤Ã¤Æ¤ª¤ê¡¢JVM¤Î¥â¥Ë¥¿¥ê¥ó¥°¤ª¤è¤Ó¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¡¦¥Æ¥¹¥È¤¬²Äǽ¤Ë¤Ê¤ê¤Þ¤¹¡£¤³¤ì¤ò̵¸ú¤Ë¤¹¤ë¤È¡¢\fBhsperfdata_userid\fR¥Ç¥£¥ì¥¯¥È¥ê¤ÎºîÀ®¤òÍÞÀ©¤·¤Þ¤¹¡£\fBperfdata\fRµ¡Ç½¤ò̵¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢\fB\-XX:\-UsePerfData\fR¤ò»ØÄꤷ¤Þ¤¹¡£
+ .RE
+ .PP
++\-XX:+UseTransparentHugePages
++.RS 4
++Linux¤Ç¤Ï¡¢Æ°Åª¤Ë³ÈÄ¥¤Þ¤¿¤Ï½Ì¾®¤Ç¤­¤ë¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î»ÈÍѤòÍ­¸ú²½¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£OS¤¬Â¾¤Î¥Ú¡¼¥¸¤ò°ÜÆ°¤·¤Æ¥Ò¥å¡¼¥¸¡¦¥Ú¡¼¥¸¤òºîÀ®¤¹¤ë¤¿¤á¡¢Æ©²áŪ¥Ò¥å¡¼¥¸¡¦¥Ú¡¼¥¸¤Ç¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤ÎÌäÂ꤬¸¡½Ð¤µ¤ì¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï»î¸³Åª¤Ë»ÈÍѤǤ­¤Þ¤¹¡£
++.sp
++¾ÜºÙ¤Ï¡¢"¥é¡¼¥¸¡¦¥Ú¡¼¥¸"¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++.RE
++.PP
+ \-XX:+AllowUserSignalHandlers
+ .RS 4
+ ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ë¤è¤ë¥·¥°¥Ê¥ë¡¦¥Ï¥ó¥É¥é¤Î¥¤¥ó¥¹¥È¡¼¥ë¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¢¤ê¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¥·¥°¥Ê¥ë¡¦¥Ï¥ó¥É¥é¤ò¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¤³¤È¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£
+@@ -1569,7 +1611,7 @@
+ .PP
+ \-XX:CompileThreshold=\fIinvocations\fR
+ .RS 4
+-¥³¥ó¥Ñ¥¤¥ëÁ°¤Ë²ò¼á¤µ¤ì¤¿¥á¥½¥Ã¥É¸Æ½Ð¤·¤Î¿ô¤òÀßÄꤷ¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥µ¡¼¥Ð¡¼JVM¤Ç¤Ï¡¢JIT¥³¥ó¥Ñ¥¤¥é¤Ï¡¢10,000¤Î²ò¼á¤µ¤ì¤¿¥á¥½¥Ã¥É¸Æ½Ð¤·¤ò¼Â¹Ô¤·¤Æ¡¢¸úΨŪ¤Ê¥³¥ó¥Ñ¥¤¥ë¤Î¤¿¤á¤Î¾ðÊó¤ò¼ý½¸¤·¤Þ¤¹¡£¥¯¥é¥¤¥¢¥ó¥ÈJVM¤Î¾ì¹ç¡¢¥Ç¥Õ¥©¥ë¥ÈÀßÄê¤Ï1,500¸Æ½Ð¤·¤Ç¤¹¡£¼¡¤ÎÎã¤Ç¤Ï¡¢²ò¼á¤µ¤ì¤¿¥á¥½¥Ã¥É¸Æ½Ð¤·¤Î¿ô¤ò5,000¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
++¥³¥ó¥Ñ¥¤¥ëÁ°¤Ë²ò¼á¤µ¤ì¤¿¥á¥½¥Ã¥É¸Æ½Ð¤·¤Î¿ô¤òÀßÄꤷ¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥µ¡¼¥Ð¡¼JVM¤Ç¤Ï¡¢JIT¥³¥ó¥Ñ¥¤¥é¤Ï¡¢10,000¤Î²ò¼á¤µ¤ì¤¿¥á¥½¥Ã¥É¸Æ½Ð¤·¤ò¼Â¹Ô¤·¤Æ¡¢¸úΨŪ¤Ê¥³¥ó¥Ñ¥¤¥ë¤Î¤¿¤á¤Î¾ðÊó¤ò¼ý½¸¤·¤Þ¤¹¡£¥¯¥é¥¤¥¢¥ó¥ÈJVM¤Î¾ì¹ç¡¢¥Ç¥Õ¥©¥ë¥ÈÀßÄê¤Ï1,500¸Æ½Ð¤·¤Ç¤¹¡£ÁØ¥³¥ó¥Ñ¥¤¥ë¤¬Í­¸ú¤Ê¾ì¹ç¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵»ë¤µ¤ì¤Þ¤¹¡£¥ª¥×¥·¥ç¥ó\fB\-XX:+TieredCompilation\fR¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£¼¡¤ÎÎã¤Ç¤Ï¡¢²ò¼á¤µ¤ì¤¿¥á¥½¥Ã¥É¸Æ½Ð¤·¤Î¿ô¤ò5,000¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+@@ -1591,7 +1633,7 @@
+ .PP
+ \-XX:InitialCodeCacheSize=\fIsize\fR
+ .RS 4
+-½é´ü¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤÏ500KB¤ËÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£¼¡¤ÎÎã¤Ç¤Ï¡¢½é´ü¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º¤ò32KB¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
++½é´ü¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤÏ500KB¤ËÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£½é´ü¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º¤ò¥·¥¹¥Æ¥à¤ÎºÇ¾®¥á¥â¥ê¡¼¡¦¥Ú¡¼¥¸¡¦¥µ¥¤¥º¤è¤ê¾®¤µ¤¯¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£¼¡¤ÎÎã¤Ç¤Ï¡¢½é´ü¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º¤ò32KB¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+@@ -1711,7 +1753,17 @@
+ .PP
+ \-XX:ReservedCodeCacheSize=\fIsize\fR
+ .RS 4
+-JIT¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤¿¥³¡¼¥É¤ÎºÇÂ祳¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï\fB\-Xmaxjitcodesize\fR¤ÈƱÅù¤Ç¤¹¡£
++JIT¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤¿¥³¡¼¥É¤ÎºÇÂ祳¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï2GB¤ÎÀ©¸Â¤¬¤¢¤ê¤Þ¤¹¡£¤½¤¦¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢¥¨¥é¡¼¤¬À¸À®¤µ¤ì¤Þ¤¹¡£ºÇÂ祳¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º¤ò½é´ü¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥å¡¦¥µ¥¤¥º¤è¤ê¾®¤µ¤¯¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£\fB\-XX:InitialCodeCacheSize\fR¥ª¥×¥·¥ç¥ó¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï\fB\-Xmaxjitcodesize\fR¤ÈƱÅù¤Ç¤¹¡£
++.RE
++.PP
++\-XX:RTMAbortRatio=\fIabort_ratio\fR
++.RS 4
++RTMÃæ»ßΨ¤Ï¡¢¤¹¤Ù¤Æ¤Î¼Â¹ÔºÑRTM¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤ËÂФ¹¤ë¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸(%)¤È¤·¤Æ»ØÄꤵ¤ì¤Þ¤¹¡£Ãæ»ß¤µ¤ì¤¿¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¿ô¤¬¤³¤ÎΨ¤òĶ¤¨¤¿¾ì¹ç¡¢¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤¿¥³¡¼¥É¤¬ÈóºÇŬ²½¤µ¤ì¤Þ¤¹¡£¤³¤ÎΨ¤Ï¡¢\fB\-XX:+UseRTMDeopt\fR¥ª¥×¥·¥ç¥ó¤¬Í­¸ú¤Ê¾ì¹ç¤Ë»ÈÍѤµ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤÏ50¤Ç¤¹¡£¤Ä¤Þ¤ê¡¢¤¹¤Ù¤Æ¤Î¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤Î50%¤¬Ãæ»ß¤µ¤ì¤¿¾ì¹ç¡¢¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤¿¥³¡¼¥É¤¬ÈóºÇŬ²½¤µ¤ì¤Þ¤¹¡£
++.RE
++.PP
++\-XX:RTMRetryCount=\fInumber_of_retries\fR
++.RS 4
++Ãæ»ß¤Þ¤¿¤Ï¥Ó¥¸¡¼¤Î¾ì¹ç¡¢RTM¥í¥Ã¥¯¡¦¥³¡¼¥É¤Ï¡¢É¸½à¤Î¥í¥Ã¥¯¡¦¥á¥«¥Ë¥º¥à¤Ë¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¤¹¤ëÁ°¤Ë¤³¤Î¥ª¥×¥·¥ç¥ó¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿²ó¿ôºÆ»î¹Ô¤µ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤÏ5¤Ç¤¹¡£\fB\-XX:UseRTMLocking\fR¥ª¥×¥·¥ç¥ó¤òÍ­¸ú²½¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .PP
+ \-XX:+TieredCompilation
+@@ -1751,40 +1803,53 @@
+ ¥«¡¼¥Éɽ¤Î¹¹¿·Á°¤Ë¡¢¥«¡¼¥É¤¬¤¹¤Ç¤Ë¥Þ¡¼¥¯¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Î¥Á¥§¥Ã¥¯¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤ª¤ê¡¢Ê£¿ô¤Î¥½¥±¥Ã¥È¤ò»ý¤Ä¥Þ¥·¥ó¾å¤Ç¤Î¤ß»ÈÍѤ¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢Æ±»þÁàºî¤Ë¤«¤Ê¤ê°Í¸¤·¤Æ¤¤¤ëJava¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤¬¸þ¾å¤·¤Þ¤¹¡£Java HotSpot Server VM¤Î¤ß¤¬¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
+ .RE
+ .PP
+-\-XX:+UseSuperWord
+-.RS 4
+-¥¹¥«¥é¡¼±é»»¤Î¥¹¡¼¥Ñ¡¼¥ï¡¼¥É±é»»¤Ø¤ÎÊÑ´¹¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Ç¥Õ¥©¥ë¥È¤ÇÍ­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¥¹¥«¥é¡¼±é»»¤Î¥¹¡¼¥Ñ¡¼¥ï¡¼¥É±é»»¤Ø¤ÎÊÑ´¹¤ò̵¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢\fB\-XX:\-UseSuperWord\fR¤ò»ØÄꤷ¤Þ¤¹¡£Java HotSpot Server VM¤Î¤ß¤¬¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
+-.RE
+-.SS "»î¸³Åª¤ÊJIT¥³¥ó¥Ñ¥¤¥é¡¦¥ª¥×¥·¥ç¥ó"
+-.PP
+-¤³¤Î¹à¤ÎRestricted Transactional Memory (RTM)¤Î¥í¥Ã¥¯µ¡Ç½¤Ë´ØÏ¢¤¹¤ë¥ª¥×¥·¥ç¥ó¤Ï»î¸³Åª¤Ê¤â¤Î¤Ç¡¢Java SE 8u20¤ÇÀµ¼°¤Ë¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£¤³¤ì¤é¤ò»ÈÍѤ¹¤ë¤Ë¤Ï¡¢\fB\-XX:+UnlockExperimentalVMOptions\fR¥ª¥×¥·¥ç¥ó¤òÍ­¸ú²½¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤é¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢Transactional Synchronization Extensions (TSX)¤ò¥µ¥Ý¡¼¥È¤¹¤ëx86 CPU¾å¤ÎJava HotSpot Server VM¤ËÂФ·¤Æ¤Î¤ß»ÈÍѲÄǽ¤Ç¤¹¡£
+-.PP
+-\-XX:RTMAbortRatio=\fIabort_ratio\fR
+-.RS 4
+-RTMÃæ»ßΨ¤Ï¡¢¤¹¤Ù¤Æ¤Î¼Â¹ÔºÑRTM¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤ËÂФ¹¤ë¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸(%)¤È¤·¤Æ»ØÄꤵ¤ì¤Þ¤¹¡£Ãæ»ß¤µ¤ì¤¿¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¿ô¤¬¤³¤ÎΨ¤òĶ¤¨¤¿¾ì¹ç¡¢¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤¿¥³¡¼¥É¤¬ÈóºÇŬ²½¤µ¤ì¤Þ¤¹¡£¤³¤ÎΨ¤Ï¡¢\fB\-XX:+UseRTMDeopt\fR¥ª¥×¥·¥ç¥ó¤¬Í­¸ú¤Ê¾ì¹ç¤Ë»ÈÍѤµ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤÏ50¤Ç¤¹¡£¤Ä¤Þ¤ê¡¢¤¹¤Ù¤Æ¤Î¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤Î50%¤¬Ãæ»ß¤µ¤ì¤¿¾ì¹ç¡¢¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤¿¥³¡¼¥É¤¬ÈóºÇŬ²½¤µ¤ì¤Þ¤¹¡£
+-.RE
+-.PP
+-\-XX:RTMRetryCount=\fInumber_of_retries\fR
+-.RS 4
+-Ãæ»ß¤Þ¤¿¤Ï¥Ó¥¸¡¼¤Î¾ì¹ç¡¢RTM¥í¥Ã¥¯¡¦¥³¡¼¥É¤Ï¡¢É¸½à¤Î¥í¥Ã¥¯¡¦¥á¥«¥Ë¥º¥à¤Ë¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¤¹¤ëÁ°¤Ë¤³¤Î¥ª¥×¥·¥ç¥ó¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿²ó¿ôºÆ»î¹Ô¤µ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤÏ5¤Ç¤¹¡£\fB\-XX:UseRTMLocking\fR¥ª¥×¥·¥ç¥ó¤òÍ­¸ú²½¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+-.RE
+-.PP
+ \-XX:+UseRTMDeopt
+ .RS 4
+-Ãæ»ßΨ¤Ë±þ¤¸¤Æ¡¢RTM¥í¥Ã¥¯¤ò¼«Æ°Ä´À°¤·¤Þ¤¹¡£¤³¤ÎΨ¤Ï¡¢\fB\-XX:RTMAbortRatio\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤Þ¤¹¡£Ãæ»ß¤µ¤ì¤¿¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¿ô¤¬Ãæ»ßΨ¤òĶ¤¨¤¿¾ì¹ç¡¢¥í¥Ã¥¯¤ò´Þ¤à¥á¥½¥Ã¥É¤¬¤¹¤Ù¤Æ¤Î¥í¥Ã¥¯¤Çɸ½à¤Î¥í¥Ã¥¯¤È¤·¤ÆÈóºÇŬ²½¤ª¤è¤ÓºÆ¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£\fB\-XX:UseRTMLocking\fR¥ª¥×¥·¥ç¥ó¤òÍ­¸ú²½¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
++Ãæ»ßΨ¤Ë±þ¤¸¤Æ¡¢RTM¥í¥Ã¥¯¤ò¼«Æ°Ä´À°¤·¤Þ¤¹¡£¤³¤ÎΨ¤Ï¡¢\fB\-XX:RTMAbortRatio\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤Þ¤¹¡£Ãæ»ß¤µ¤ì¤¿¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¿ô¤¬Ãæ»ßΨ¤òĶ¤¨¤¿¾ì¹ç¡¢¥í¥Ã¥¯¤ò´Þ¤à¥á¥½¥Ã¥É¤¬¤¹¤Ù¤Æ¤Î¥í¥Ã¥¯¤Çɸ½à¤Î¥í¥Ã¥¯¤È¤·¤ÆÈóºÇŬ²½¤ª¤è¤ÓºÆ¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£\fB\-XX:+UseRTMLocking\fR¥ª¥×¥·¥ç¥ó¤òÍ­¸ú²½¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .PP
+ \-XX:+UseRTMLocking
+ .RS 4
+-¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¡¦¥Ï¥ó¥É¥é¤È¤·¤Æɸ½à¤Î¥í¥Ã¥¯¡¦¥á¥«¥Ë¥º¥à¤ò»ÈÍѤ·¤Æ¡¢Å¸³«¤µ¤ì¤¿¤¹¤Ù¤Æ¤Î¥í¥Ã¥¯¤ËÂФ·¤ÆRestricted Transactional Memory (RTM)¥í¥Ã¥¯¡¦¥³¡¼¥É¤òÀ¸À®¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£
++¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¡¦¥Ï¥ó¥É¥é¤È¤·¤Æɸ½à¤Î¥í¥Ã¥¯¡¦¥á¥«¥Ë¥º¥à¤ò»ÈÍѤ·¤Æ¡¢Å¸³«¤µ¤ì¤¿¤¹¤Ù¤Æ¤Î¥í¥Ã¥¯¤ËÂФ·¤ÆRestricted Transactional Memory (RTM)¥í¥Ã¥¯¡¦¥³¡¼¥É¤òÀ¸À®¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£RTM¤Ë´ØÏ¢¤¹¤ë¥ª¥×¥·¥ç¥ó¤Ï¡¢Transactional Synchronization Extensions (TSX)¤ò¥µ¥Ý¡¼¥È¤¹¤ëx86 CPU¾å¤ÎJava HotSpot Server VM¤ËÂФ·¤Æ¤Î¤ß»ÈÍѲÄǽ¤Ç¤¹¡£
+ .sp
+-RTM¤Ï¡¢x86Ì¿Î᥻¥Ã¥È³ÈÄ¥¤Ç¥Þ¥ë¥Á¥¹¥ì¥Ã¥É¡¦¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÎºîÀ®¤òÍưפˤ¹¤ëIntel¤ÎTransactional Synchronization Extensions (TSX)¤Î°ìÉô¤Ç¤¹¡£RTM¤Ç¤Ï¡¢¿·¤·¤¤Ì¿Îá
++RTM¤Ï¡¢x86Ì¿Î᥻¥Ã¥È³ÈÄ¥¤Ç¥Þ¥ë¥Á¥¹¥ì¥Ã¥É¡¦¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÎºîÀ®¤òÍưפˤ¹¤ëIntel¤ÎTSX¤Î°ìÉô¤Ç¤¹¡£RTM¤Ç¤Ï¡¢¿·¤·¤¤Ì¿Îá
+ \fBXBEGIN\fR¡¢\fBXABORT\fR¡¢\fBXEND\fR¤ª¤è¤Ó\fBXTEST\fR¤¬Æ³Æþ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£\fBXBEGIN\fR¤ª¤è¤Ó\fBXEND\fRÌ¿Îá¤Ï¡¢¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤È¤·¤Æ¼Â¹Ô¤¹¤ë¤¿¤á¤ÎÌ¿Î᥻¥Ã¥È¤ò°Ï¤ß¤Þ¤¹¡£¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤Î¼Â¹Ô»þ¤Ë¶¥¹ç¤¬¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿¾ì¹ç¡¢¥á¥â¥ê¡¼¤È¥ì¥¸¥¹¥¿¤ÎÊѹ¹¤¬¡¢\fBXEND\fRÌ¿Îá¤ÇƱ»þ¤Ë¥³¥ß¥Ã¥È¤µ¤ì¤Þ¤¹¡£\fBXABORT\fRÌ¿Îá¤Ç¤Ï¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤òÌÀ¼¨Åª¤ËÃæ»ß¤Ç¤­¡¢\fBXEND\fRÌ¿Îá¤Ç¤ÏÌ¿Î᥻¥Ã¥È¤¬¥È¥é¥ó¥¶¥¯¥·¥ç¥óÆâ¤Ç¼Â¹ÔÃ椫¤É¤¦¤«¤ò³Îǧ¤Ç¤­¤Þ¤¹¡£
+ .sp
+ ¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤Î¥í¥Ã¥¯¤Ï¡¢Ê̤Υ¹¥ì¥Ã¥É¤¬Æ±¤¸¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤Ë¥¢¥¯¥»¥¹¤·¤è¤¦¤È¤·¤¿¤È¤­¤ËŸ³«¤µ¤ì¤Þ¤¹¡£¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤Î¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤Ø¤Î¥¢¥¯¥»¥¹¤òºÇ½é¤Ë¥ê¥¯¥¨¥¹¥È¤·¤Ê¤«¤Ã¤¿¥¹¥ì¥Ã¥É¤Ï¥Ö¥í¥Ã¥¯¤µ¤ì¤Þ¤¹¡£RTM¤Ç¤Ï¡¢¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤¬Ãæ»ß¤Þ¤¿¤Ï¼ºÇÔ¤·¤¿¾ì¹ç¤Î¤¿¤á¤Ë¡¢¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¤ÎÁàºî¥»¥Ã¥È¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£RTM¥í¥Ã¥¯¤È¤Ï¡¢TSX¤Î¥·¥¹¥Æ¥à¤Ë°Ñ¾ù¤µ¤ì¤Æ¤¤¤ë¥í¥Ã¥¯¤Ç¤¹¡£
+ .sp
+ RTM¤Ë¤è¤ê¡¢½ÅÍפʥ꡼¥¸¥ç¥ó¤Ë¤ª¤¤¤Æ¾×Æͤ¬¾¯¤Ê¤¯¶¥¹çÅ٤ι⤤¥í¥Ã¥¯¤Î¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤¬¸þ¾å¤µ¤ì¤Þ¤¹(¤³¤ì¤Ï¡¢Ê£¿ô¤Î¥¹¥ì¥Ã¥É¤Ë¤è¤Ã¤ÆƱ»þ¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤Ê¤¤¥³¡¼¥É¤Ç¤¹)¡£¤Þ¤¿¡¢RTM¤Ë¤è¤ê¡¢ÁÆγÅÙ¥í¥Ã¥¯¤Î¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤â¸þ¾å¤µ¤ì¤Þ¤¹¤¬¡¢°ìÈÌŪ¤Ë¥Þ¥ë¥Á¥¹¥ì¥Ã¥É¡¦¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ç¤Î¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤Ï¤è¤¯¤¢¤ê¤Þ¤»¤ó¡£(ÁÆγÅÙ¥í¥Ã¥¯¤È¤Ï¡¢¥í¥Ã¥¯¤Î¼èÆÀ¤ª¤è¤Ó²òÊü¤Î¥ª¡¼¥Ð¡¼¥Ø¥Ã¥É¤òºÇ¾®²½¤¹¤ë¤¿¤á¤ËŤ¤´ü´Ö¥í¥Ã¥¯¤òÊÝ»ý¤¹¤ëÀïά¤Ç¤¢¤ê¡¢°ìÊý¡¢ºÙγÅÙ¥í¥Ã¥¯¤È¤ÏɬÍפʾì¹ç¤Î¤ß¥í¥Ã¥¯¤·²Äǽ¤Ê¤«¤®¤êÁá´ü¤Ë¥í¥Ã¥¯²ò½ü¤¹¤ë¤³¤È¤ÇºÇÂç¸Â¤ÎʹԽèÍý¤ÎãÀ®¤ò»î¤ß¤ëÀïά¤Ç¤¹¡£)¤µ¤é¤Ë¡¢°Û¤Ê¤ë¥¹¥ì¥Ã¥É¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ë·ÚÅ٤ʶ¥¹ç¥í¥Ã¥¯¤Î¾ì¹ç¡¢RTM¤Ë¤è¤ê¡¢¸í¤Ã¤¿¥­¥ã¥Ã¥·¥å¡¦¥é¥¤¥ó¶¦Í­(¥­¥ã¥Ã¥·¥å¡¦¥é¥¤¥ó¡¦¥Ô¥ó¥Ý¥ó¤È¤â¸Æ¤Ð¤ì¤ë)¤òºï¸º¤Ç¤­¤Þ¤¹¡£¤³¤ì¤Ï¡¢°Û¤Ê¤ë¥×¥í¥»¥Ã¥µ¤«¤é¤ÎÊ£¿ô¤Î¥¹¥ì¥Ã¥É¤¬°Û¤Ê¤ë¥ê¥½¡¼¥¹¤Ë¥¢¥¯¥»¥¹¤·¤Æ¤¤¤ë¾ì¹ç¤ËȯÀ¸¤·¤Þ¤¹¤¬¡¢¥ê¥½¡¼¥¹¤ÏƱ¤¸¥­¥ã¥Ã¥·¥å¡¦¥é¥¤¥ó¤ò¶¦Í­¤·¤Þ¤¹¡£·ë²Ì¤È¤·¤Æ¡¢¥×¥í¥»¥Ã¥µ¤Ï¾¤Î¥×¥í¥»¥Ã¥µ¤Î¥­¥ã¥Ã¥·¥å¡¦¥é¥¤¥ó¤ò·«¤êÊÖ¤·Ìµ¸ú¤Ë¤·¡¢¤³¤ì¤Ë¤è¤ê¡¢¥­¥ã¥Ã¥·¥å¤Ç¤Ï¤Ê¤¯¥á¥¤¥ó¡¦¥á¥â¥ê¡¼¤«¤é¤ÎÆɼè¤ê¤¬¶¯À©¤µ¤ì¤Þ¤¹¡£
+ .RE
++.PP
++\-XX:+UseSHA
++.RS 4
++SPARC¥Ï¡¼¥É¥¦¥§¥¢¤ÎSHA°Å¹æ²½¥Ï¥Ã¥·¥å´Ø¿ô¤Î¥Ï¡¼¥É¥¦¥§¥¢¥Ù¡¼¥¹¤ÎÁȹþ¤ß¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£\fBUseSHA\fR¤Ï¡¢\fBUseSHA1Intrinsics\fR¡¢\fBUseSHA256Intrinsics\fR¤ª¤è¤Ó\fBUseSHA512Intrinsics\fR¥ª¥×¥·¥ç¥ó¤ÈÁȤ߹礻¤Æ»ÈÍѤ·¤Þ¤¹¡£
++.sp
++\fBUseSHA\fR¤ª¤è¤Ó\fBUseSHA*Intrinsics\fR¥Õ¥é¥°¤Ï¥Ç¥Õ¥©¥ë¥È¤ÇÍ­¸ú¤Ç¤¢¤ê¡¢SPARC T4°Ê¾å¤ÎJava HotSpot Server VM 64¥Ó¥Ã¥È¤Ç¤Î¤ß¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤¹¡£
++.sp
++SHAÁàºî¤ËÂФ·¤Æ\fBsun\&.security\&.provider\&.Sun\fR¥×¥í¥Ð¥¤¥À¤ò»ÈÍѤ¹¤ë¾ì¹ç¤Î¤ß¡¢¤³¤Îµ¡Ç½¤òŬÍѤǤ­¤Þ¤¹¡£
++.sp
++¤¹¤Ù¤Æ¤Î¥Ï¡¼¥É¥¦¥§¥¢¥Ù¡¼¥¹¤ÎSHAÁȹþ¤ß¤ò̵¸ú²½¤¹¤ë¤Ë¤Ï¡¢\fB\-XX:\-UseSHA\fR¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£ÆÃÄê¤ÎSHAÁȹþ¤ß¤Î¤ß̵¸ú²½¤¹¤ë¤Ë¤Ï¡¢Å¬ÀÚ¤ÊÂбþ¤¹¤ë¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£¤¿¤È¤¨¤Ð¡¢\fB\-XX:\-UseSHA256Intrinsics\fR¤Ê¤É¤Ç¤¹¡£
++.RE
++.PP
++\-XX:+UseSHA1Intrinsics
++.RS 4
++SHA\-1°Å¹æ²½¥Ï¥Ã¥·¥å´Ø¿ô¤ÎÁȹþ¤ß¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£
++.RE
++.PP
++\-XX:+UseSHA256Intrinsics
++.RS 4
++SHA\-224¤ª¤è¤ÓSHA\-256°Å¹æ²½¥Ï¥Ã¥·¥å´Ø¿ô¤ÎÁȹþ¤ß¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£
++.RE
++.PP
++\-XX:+UseSHA512Intrinsics
++.RS 4
++SHA\-384¤ª¤è¤ÓSHA\-512°Å¹æ²½¥Ï¥Ã¥·¥å´Ø¿ô¤ÎÁȹþ¤ß¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£
++.RE
++.PP
++\-XX:+UseSuperWord
++.RS 4
++¥¹¥«¥é¡¼±é»»¤Î¥¹¡¼¥Ñ¡¼¥ï¡¼¥É±é»»¤Ø¤ÎÊÑ´¹¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Ç¥Õ¥©¥ë¥È¤ÇÍ­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¥¹¥«¥é¡¼±é»»¤Î¥¹¡¼¥Ñ¡¼¥ï¡¼¥É±é»»¤Ø¤ÎÊÑ´¹¤ò̵¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢\fB\-XX:\-UseSuperWord\fR¤ò»ØÄꤷ¤Þ¤¹¡£Java HotSpot Server VM¤Î¤ß¤¬¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
++.RE
+ .SS "¹âÅ٤ʥµ¡¼¥Ó¥¹¥¢¥Ó¥ê¥Æ¥£¡¦¥ª¥×¥·¥ç¥ó"
+ .PP
+ ¤³¤ì¤é¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥·¥¹¥Æ¥à¾ðÊó¤ò¼ý½¸¤·¡¢¾ÜºÙ¤Ê¥Ç¥Ð¥Ã¥°¤ò¼Â¹Ô¤¹¤ëµ¡Ç½¤òÄ󶡤·¤Þ¤¹¡£
+@@ -1855,7 +1920,7 @@
+ .PP
+ \-XX:+PrintConcurrentLocks
+ .RS 4
+-¼¡¤Î°õºþ¤òÍ­¸ú²½¤·¤Þ¤¹: j ¥í¥Ã¥¯(¼¡¤Î¸å) \- ¥¤¥Ù¥ó¥È¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¹¡£
++°õºþ¤òÍ­¸ú¤Ë¤·¤Þ¤¹ ¥í¥Ã¥¯(¼¡¤Î¸å) \- ¥¤¥Ù¥ó¥È¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¹¡£
+ .sp
+ \fB[Control]+[C]\fR¥¤¥Ù¥ó¥È(\fBSIGTERM\fR)¸å¤Ë\fBjava\&.util\&.concurrent\fR¥í¥Ã¥¯¤Î°õºþ¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¹¡£
+ .sp
+@@ -2018,7 +2083,7 @@
+ .PP
+ \-XX:InitialHeapSize=\fIsize\fR
+ .RS 4
+-¥á¥â¥ê¡¼³äÅö¤Æ¥×¡¼¥ë¤Î½é´ü¥µ¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£»ØÄꤹ¤ëÃͤϡ¢0¡¢¤Þ¤¿¤Ï1MB¤è¤êÂ礭¤¤1024¤ÎÇÜ¿ô¤Î¤¤¤º¤ì¤«¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢¼Â¹Ô»þ¤Ë¥·¥¹¥Æ¥à¹½À®¤Ë´ð¤Å¤¤¤ÆÁªÂò¤µ¤ì¤Þ¤¹¡£¾ÜºÙ¤Ï¡¢http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gc\-ergonomics\&.html¤Ë¤¢¤ë¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥¿¡¦¥¨¥ë¥´¥Î¥ß¥Ã¥¯¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++¥á¥â¥ê¡¼³äÅö¤Æ¥×¡¼¥ë¤Î½é´ü¥µ¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£»ØÄꤹ¤ëÃͤϡ¢0¡¢¤Þ¤¿¤Ï1MB¤è¤êÂ礭¤¤1024¤ÎÇÜ¿ô¤Î¤¤¤º¤ì¤«¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢¼Â¹Ô»þ¤Ë¥·¥¹¥Æ¥à¹½À®¤Ë´ð¤Å¤¤¤ÆÁªÂò¤µ¤ì¤Þ¤¹¡£http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gctuning/index\&.html¤Î\fIJava SE HotSpot²¾ÁÛ¥Þ¥·¥ó¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¡¦¥Á¥å¡¼¥Ë¥ó¥°¡¦¥¬¥¤¥É\fR¤Î¥¨¥ë¥´¥Î¥ß¥¯¥¹¤Ë´Ø¤¹¤ë¹à¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ ¼¡¤ÎÎã¤Ç¤Ï¡¢³ä¤êÅö¤Æ¤é¤ì¤¿¥á¥â¥ê¡¼¤Î¥µ¥¤¥º¤òÍÍ¡¹¤Êñ°Ì¤ò»ÈÍѤ·¤Æ6MB¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
+ .sp
+@@ -2109,7 +2174,7 @@
+ .PP
+ \-XX:MaxHeapSize=\fIsize\fR
+ .RS 4
+-¥á¥â¥ê¡¼³äÅö¤Æ¥×¡¼¥ë¤ÎºÇÂ祵¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£»ØÄꤹ¤ëÃͤϡ¢2MB¤è¤êÂ礭¤¤1024¤ÎÇÜ¿ô¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢¼Â¹Ô»þ¤Ë¥·¥¹¥Æ¥à¹½À®¤Ë´ð¤Å¤¤¤ÆÁªÂò¤µ¤ì¤Þ¤¹¡£¥µ¡¼¥Ð¡¼¡¦¥Ç¥×¥í¥¤¥á¥ó¥È¤Ç¤Ï¡¢\fB\-XX:InitialHeapSize\fR¤ª¤è¤Ó\fB\-XX:MaxHeapSize\fR¤ÏÄ̾ïƱ¤¸ÃͤËÀßÄꤵ¤ì¤Þ¤¹¡£¾ÜºÙ¤Ï¡¢http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gc\-ergonomics\&.html¤Ë¤¢¤ë¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥¿¡¦¥¨¥ë¥´¥Î¥ß¥Ã¥¯¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++¥á¥â¥ê¡¼³äÅö¤Æ¥×¡¼¥ë¤ÎºÇÂ祵¥¤¥º(¥Ð¥¤¥Èñ°Ì)¤òÀßÄꤷ¤Þ¤¹¡£»ØÄꤹ¤ëÃͤϡ¢2MB¤è¤êÂ礭¤¤1024¤ÎÇÜ¿ô¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥í¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBk\fR¤Þ¤¿¤Ï\fBK\fR¡¢¥á¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBm\fR¤Þ¤¿¤Ï\fBM\fR¡¢¥®¥¬¥Ð¥¤¥È¤ò¼¨¤¹¾ì¹ç¤Ïʸ»ú\fBg\fR¤Þ¤¿¤Ï\fBG\fR¤òÄɲä·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢¼Â¹Ô»þ¤Ë¥·¥¹¥Æ¥à¹½À®¤Ë´ð¤Å¤¤¤ÆÁªÂò¤µ¤ì¤Þ¤¹¡£¥µ¡¼¥Ð¡¼¡¦¥Ç¥×¥í¥¤¥á¥ó¥È¤Ç¤Ï¡¢\fB\-XX:InitialHeapSize\fR¤ª¤è¤Ó\fB\-XX:MaxHeapSize\fR¤ÏÄ̾ïƱ¤¸ÃͤËÀßÄꤵ¤ì¤Þ¤¹¡£http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gctuning/index\&.html¤Î\fIJava SE HotSpot²¾ÁÛ¥Þ¥·¥ó¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¡¦¥Á¥å¡¼¥Ë¥ó¥°¡¦¥¬¥¤¥É\fR¤Î¥¨¥ë¥´¥Î¥ß¥¯¥¹¤Ë´Ø¤¹¤ë¹à¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ ¼¡¤ÎÎã¤Ç¤Ï¡¢³ä¤êÅö¤Æ¤é¤ì¤¿¥á¥â¥ê¡¼¤Îµö²Ä¤µ¤ì¤ëºÇÂ祵¥¤¥º¤òÍÍ¡¹¤Êñ°Ì¤ò»ÈÍѤ·¤Æ80MB¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
+ .sp
+@@ -2480,6 +2545,13 @@
+ ¥·¥ê¥¢¥ë¡¦¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥¿¤Î»ÈÍѤòÍ­¸ú¤Ë¤·¤Þ¤¹¡£¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¤«¤éÆÃÊ̤ʵ¡Ç½¤òɬÍפȤ·¤Ê¤¤¡¢¾®µ¬ÌϤÇñ½ã¤Ê¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¾ì¹ç¤Ë¤Ï¡¢¤³¤ì¤Ï°ìÈ̤˺ÇŬ¤ÊÁªÂò¤Ç¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ë¤Ê¤Ã¤Æ¤ª¤ê¡¢¥³¥ì¥¯¥¿¤Ï¡¢¥Þ¥·¥ó¤Î¹½À®¤ª¤è¤ÓJVM¤Î¥¿¥¤¥×¤Ë´ð¤Å¤¤¤Æ¡¢¼«Æ°Åª¤ËÁªÂò¤µ¤ì¤Þ¤¹¡£
+ .RE
+ .PP
++\-XX:+UseSHM
++.RS 4
++Linux¤Ç¤Ï¡¢JVM¤Ç¶¦Í­¥á¥â¥ê¡¼¤ò»ÈÍѤ·¤Æ¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤òÀßÄê¤Ç¤­¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£
++.sp
++¾ÜºÙ¤Ï¡¢"¥é¡¼¥¸¡¦¥Ú¡¼¥¸"¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++.RE
++.PP
+ \-XX:+UseStringDeduplication
+ .RS 4
+ ʸ»úÎó¤Î½ÅÊ£½ü³°¤òÍ­¸ú²½¤·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï̵¸ú¤Ç¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤Ë¤Ï¡¢¥¬¥Ù¡¼¥¸¥Õ¥¡¡¼¥¹¥È(G1)¡¦¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥¿¤òÍ­¸ú¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£\fB\-XX:+UseG1GC\fR¥ª¥×¥·¥ç¥ó¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+@@ -2502,7 +2574,7 @@
+ .PP
+ \-Xrun\fIlibname\fR
+ .RS 4
+-»ØÄꤷ¤¿¥Ç¥Ð¥Ã¥°/¥×¥í¥Õ¥¡¥¤¥ë¤Î¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢\fB\-agentlib\fR¥ª¥×¥·¥ç¥ó¤Ë¼è¤Ã¤ÆÂå¤ï¤é¤ì¤Þ¤·¤¿¡£
++»ØÄꤷ¤¿¥Ç¥Ð¥Ã¥°/¥×¥í¥Õ¥¡¥¤¥ê¥ó¥°¤Î¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢\fB\-agentlib\fR¥ª¥×¥·¥ç¥ó¤Ë¼è¤Ã¤ÆÂå¤ï¤é¤ì¤Þ¤·¤¿¡£
+ .RE
+ .PP
+ \-XX:CMSIncrementalDutyCycle=\fIpercent\fR
+@@ -2563,9 +2635,7 @@
+ .PP
+ ¼¡¤ÎÎã¤Ç¤Ï¡¢¥¹¥ë¡¼¥×¥Ã¥È¤ÎºÇŬ²½¤Þ¤¿¤Ï¥ì¥¹¥Ý¥ó¥¹»þ´Ö¤Îû½Ì²½¤Î¤¤¤º¤ì¤«¤ò¹Ô¤¦¤¿¤á¤Î¡¢»î¸³Åª¤Ê¥Á¥å¡¼¥Ë¥ó¥°¡¦¥Õ¥é¥°¤Î»ÈÍÑÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
+ .PP
+-\fBÎã 1\fR
+-.br
+-¥¹¥ë¡¼¥×¥Ã¥È¤ò¸þ¾å¤¹¤ë¤¿¤á¤Î¥Á¥å¡¼¥Ë¥ó¥°
++\fBÎã 1 \fR¥¹¥ë¡¼¥×¥Ã¥È¤ò¸þ¾å¤¹¤ë¤¿¤á¤Î¥Á¥å¡¼¥Ë¥ó¥°
+ .RS 4
+ .sp
+ .if n \{\
+@@ -2580,9 +2650,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-¥ì¥¹¥Ý¥ó¥¹»þ´Ö¤ò®¤¯¤¹¤ë¤¿¤á¤Î¥Á¥å¡¼¥Ë¥ó¥°
++\fBÎã 2 \fR¥ì¥¹¥Ý¥ó¥¹»þ´Ö¤ò®¤¯¤¹¤ë¤¿¤á¤Î¥Á¥å¡¼¥Ë¥ó¥°
+ .RS 4
+ .sp
+ .if n \{\
+@@ -2596,6 +2664,188 @@
+ .RE
+ .\}
+ .RE
++.SH "¥é¡¼¥¸¡¦¥Ú¡¼¥¸"
++.PP
++¥Ò¥å¡¼¥¸¡¦¥Ú¡¼¥¸¤È¤â¸Æ¤Ð¤ì¤ë¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Ï¡¢É¸½à¤Î¥á¥â¥ê¡¼¡¦¥Ú¡¼¥¸¡¦¥µ¥¤¥º(¥×¥í¥»¥Ã¥µ¤ª¤è¤Ó¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¡¦¥·¥¹¥Æ¥à¤Ë¤è¤Ã¤Æ°Û¤Ê¤ê¤Þ¤¹)¤è¤ê¤Ï¤ë¤«¤ËÂ礭¤¤¥á¥â¥ê¡¼¡¦¥Ú¡¼¥¸¤Ç¤¹¡£¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Ï¡¢¥×¥í¥»¥Ã¥µ¤ÎTranslation\-Lookaside Buffer¤òºÇŬ²½¤·¤Þ¤¹¡£
++.PP
++Translation\-Lookaside Buffer (TLB)¤Ï¡¢ºÇ¶á»ÈÍѤµ¤ì¤¿²¾ÁÛ¤«¤éʪÍý¤Ø¤Î¥¢¥É¥ì¥¹ÊÑ´¹¤òÊÝ»ý¤¹¤ë¥Ú¡¼¥¸ÊÑ´¹¥­¥ã¥Ã¥·¥å¤Ç¤¹¡£TLB¤Ï¡¢¾¯¤Ê¤¤¥·¥¹¥Æ¥à¡¦¥ê¥½¡¼¥¹¤Ç¤¹¡£¥×¥í¥»¥Ã¥µ¤¬Ê£¿ô¤Î¥á¥â¥ê¡¼¡¦¥¢¥¯¥»¥¹¤¬É¬Íפʾì¹ç¤Î¤¢¤ë³¬ÁØ¥Ú¡¼¥¸É½¤«¤éÆɤ߼è¤ëɬÍפ¬¤¢¤ë¤¿¤á¡¢TLB¥ß¥¹¤ÏÉé²Ù¤¬¤«¤«¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£Â礭¤¤¥á¥â¥ê¡¼¡¦¥Ú¡¼¥¸¡¦¥µ¥¤¥º¤ò»ÈÍѤ·¤Æ¡¢Ã±°ì¤ÎTLB¥¨¥ó¥È¥ê¤ÇÂ礭¤¤¥á¥â¥ê¡¼ÈϰϤòɽ¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£TLBÉÔ­¤¬¾¯¤Ê¤¯¤Ê¤ê¡¢¥á¥â¥ê¡¼½¸Ì󷿤Υ¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤¬¸þ¾å¤¹¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£
++.PP
++¤¿¤À¤·¡¢¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¥Ú¡¼¥¸¡¦¥á¥â¥ê¡¼¤Ï¡¢¥·¥¹¥Æ¥à¤Î¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤Ë°­±Æ¶Á¤òÍ¿¤¨¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢ÂçÎ̤Υá¥â¥ê¡¼¤¬¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ç³ÎÊݤµ¤ì¤ë¾ì¹ç¡¢Ä̾ï¥á¥â¥ê¡¼ÉÔ­¤ä¾¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î²á¾ê¤Ê¥Ú¡¼¥¸¥ó¥°¤¬È¯À¸¤·¡¢¥·¥¹¥Æ¥àÁ´ÂΤ¬ÃÙ¤¯¤Ê¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£¤Þ¤¿¡¢Ä¹»þ´Ö²ÔƯ¤·¤Æ¤¤¤ë¥·¥¹¥Æ¥à¤Ï¡¢²á¾ê¤ÊÃÇÊÒ²½¤¬È¯À¸¤¹¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢½½Ê¬¤ÊÂ礭¤µ¤Î¥Ú¡¼¥¸¡¦¥á¥â¥ê¡¼¤òͽÌó¤Ç¤­¤Ê¤¤²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤¬È¯À¸¤·¤¿¾ì¹ç¡¢OS¤Þ¤¿¤ÏJVM¤Î¤¤¤º¤ì¤«¤¬Ä̾ï¤Î¥Ú¡¼¥¸¤Î»ÈÍѤËÌá¤ê¤Þ¤¹¡£
++.SS "¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¥µ¥Ý¡¼¥È"
++.PP
++Solaris¤ª¤è¤ÓLinux¤Ï¡¢¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£
++.sp
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBSolaris\fR
++.RS 4
++.PP
++Solaris 9°Ê¾å¤Ë¤Ï¡¢Multiple Page Size Support(MPSS)¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£Äɲäι½À®¤ÏɬÍפ¢¤ê¤Þ¤»¤ó¡£http://www\&.oracle\&.com/technetwork/server\-storage/solaris10/overview/solaris9\-features\-scalability\-135663\&.html¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++.RE
++.sp
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBLinux\fR
++.RS 4
++.PP
++2\&.6¥«¡¼¥Í¥ë¤Ï¡¢¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£°ìÉô¤Î¥Ù¥ó¥À¡¼¤Ï¡¢2\&.4¥Ù¡¼¥¹¤Î¥ê¥ê¡¼¥¹¤Î¥³¡¼¥É¤ò¥Ð¥Ã¥¯¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£¥·¥¹¥Æ¥à¤¬¥é¡¼¥¸¡¦¥Ú¡¼¥¸¡¦¥á¥â¥ê¡¼¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¤«¤É¤¦¤«¤ò³Îǧ¤¹¤ë¤Ë¤Ï¡¢¼¡¤ò»î¹Ô¤·¤Æ¤¯¤À¤µ¤¤:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB# cat /proc/meminfo | grep Huge\fR
++\fBHugePages_Total: 0\fR
++\fBHugePages_Free: 0\fR
++\fBHugepagesize: 2048 kB\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.PP
++½ÐÎϤË3¤Ä¤Î"Huge"ÊÑ¿ô¤¬¼¨¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥·¥¹¥Æ¥à¤Ï¥é¡¼¥¸¡¦¥Ú¡¼¥¸¡¦¥á¥â¥ê¡¼¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¤¬¡¢¹½À®¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥³¥Þ¥ó¥É¤¬²¿¤â½ÐÎϤ·¤Ê¤¤¾ì¹ç¡¢¥·¥¹¥Æ¥à¤Ï¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£¥é¡¼¥¸¡¦¥Ú¡¼¥¸¡¦¥á¥â¥ê¡¼¤ò»ÈÍѤ¹¤ë¥·¥¹¥Æ¥à¤ò¹½À®¤¹¤ë¤Ë¤Ï¡¢\fBroot\fR¤È¤·¤Æ¥í¥°¥¤¥ó¤·¤Æ¡¢¼¡¤Î¼ê½ç¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤:
++.sp
++.RS 4
++.ie n \{\
++\h'-04' 1.\h'+01'\c
++.\}
++.el \{\
++.sp -1
++.IP " 1." 4.2
++.\}
++¥ª¥×¥·¥ç¥ó\fB\-XX:+UseSHM\fR(\fB\-XX:+UseHugeTLBFS\fR¤Î¤«¤ï¤ê)¤ò»ÈÍѤ¹¤ë¾ì¹ç¡¢\fBSHMMAX\fRÃͤòÁý¤ä¤·¤Æ¤¯¤À¤µ¤¤¡£Java¥Ò¡¼¥×¡¦¥µ¥¤¥º¤è¤êÂ礭¤¯¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£4GB°Ê²¼¤ÎʪÍýRAM¤ò»ÈÍѤ·¤¿¥·¥¹¥Æ¥à¤Ç¡¢¼¡¤Ë¤è¤ê¤¹¤Ù¤Æ¤Î¥á¥â¥ê¡¼¤¬¶¦Í­²Äǽ¤Ë¤Ê¤ê¤Þ¤¹:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB# echo 4294967295 > /proc/sys/kernel/shmmax\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04' 2.\h'+01'\c
++.\}
++.el \{\
++.sp -1
++.IP " 2." 4.2
++.\}
++¥ª¥×¥·¥ç¥ó\fB\-XX:+UseSHM\fR¤Þ¤¿¤Ï\fB\-XX:+UseHugeTLBFS\fR¤ò»ÈÍѤ¹¤ë¾ì¹ç¡¢¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¿ô¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£¼¡¤ÎÎã¤Ç¤Ï¡¢4GB¥·¥¹¥Æ¥à¤Î3GB¤¬¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ËͽÌ󤵤ì¤Þ¤¹(2048KB¤Î¥é¡¼¥¸¡¦¥Ú¡¼¥¸¡¦¥µ¥¤¥º¤ò²¾Äꤹ¤ë¾ì¹ç¡¢3GB = 3 * 1024MB = 3072MB = 3072 * 1024KB = 3145728KB and 3145728KB / 2048KB = 1536):
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB# echo 1536 > /proc/sys/vm/nr_hugepages\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.if n \{\
++.sp
++.\}
++.RS 4
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBÃíµ­\fR
++.ps -1
++.br
++.TS
++allbox tab(:);
++l.
++T{
++Ãí°Õ
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++¥·¥¹¥Æ¥à¤òºÆµ¯Æ°¤·¤¿¸å¤Ë\fB/proc\fR¤Ë´Þ¤Þ¤ì¤ëÃͤ¬¥ê¥»¥Ã¥È¤µ¤ì¤ë¤Î¤ÇÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤½¤Î¤¿¤á¡¢½é´ü²½¥¹¥¯¥ê¥×¥È(\fBrc\&.local\fR¤ä\fBsysctl\&.conf\fR¤Ê¤É)¤ÇÀßÄê¤Ç¤­¤Þ¤¹¡£
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++OS¥«¡¼¥Í¥ë¡¦¥Ñ¥é¥á¡¼¥¿\fB/proc/sys/kernel/shmmax\fR¤Þ¤¿¤Ï\fB/proc/sys/vm/nr_hugepages\fR¤ò¹½À®(¤Þ¤¿¤Ï¥µ¥¤¥ºÊѹ¹)¤¹¤ë¾ì¹ç¡¢Java¥×¥í¥»¥¹¤¬Java¥Ò¡¼¥×°Ê³°¤ÎÎΰè¤ËÂФ·¤Æ¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ò³ä¤êÅö¤Æ¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤é¤Î¼ê½ç¤ò»ÈÍѤ·¤Æ¡¢¼¡¤ÎÎΰè¤ËÂФ·¤Æ¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤ò³ä¤êÅö¤Æ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++Java¥Ò¡¼¥×
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++PermanentÀ¤Âå
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥å
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++¥Ñ¥é¥ì¥ëGC¤Î¥Þ¡¼¥­¥ó¥°¡¦¥Ó¥Ã¥È¥Þ¥Ã¥×¡¦¥Ç¡¼¥¿¹½Â¤
++.RE
++.sp
++¤½¤Î·ë²Ì¡¢Java¥Ò¡¼¥×¤Î¥µ¥¤¥º¤Ë\fBnr_hugepages\fR¥Ñ¥é¥á¡¼¥¿¤ò¹½À®¤¹¤ë¤È¡¢Îΰè¤Î¥µ¥¤¥º¤¬Èó¾ï¤ËÂ礭¤¤¤¿¤á¤ËJVM¤¬PermanentÀ¤Â太¤è¤Ó¥é¡¼¥¸¡¦¥Ú¡¼¥¸¤Î¥³¡¼¥É¡¦¥­¥ã¥Ã¥·¥åÎΰè¤Î³äÅö¤Æ¤Ë¼ºÇÔ¤¹¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£
++.RE
++T}
++.TE
++.sp 1
++.sp .5v
++.RE
++.RE
+ .SH "½ªÎ»¥¹¥Æ¡¼¥¿¥¹"
+ .PP
+ Ä̾¼¡¤Î½ªÎ»Ãͤ¬µ¯Æ°¥Ä¡¼¥ë¤«¤éÊÖ¤µ¤ì¤ë¤Î¤Ï¡¢µ¯Æ°¸µ¤¬ÉÔÀµ¤Ê°ú¿ô¤Ç¸Æ¤Ó½Ð¤µ¤ì¤¿¤«¡¢¿¼¹ï¤Ê¥¨¥é¡¼¤¬È¯À¸¤·¤¿¤«¡¢¤¢¤ë¤¤¤ÏJVM¤Ë¤è¤êÎã³°¤¬¥¹¥í¡¼¤µ¤ì¤¿¾ì¹ç¤Ç¤¹¡£¤¿¤À¤·¡¢Java¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¡¢API¸Æ½Ð¤·\fBSystem\&.exit(exitValue)\fR¤ò»ÈÍѤ·¤ÆǤ°Õ¤ÎÃͤòÊÖ¤¹¤³¤È¤òÁªÂò¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£Ãͤϼ¡¤Î¤È¤ª¤ê¤Ç¤¹¡£
+@@ -2666,6 +2916,17 @@
+ .\}
+ jar(1)
+ .RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++jstat(1)
++.RE
+ .br
+ 'pl 8.5i
+ 'bp
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/javac.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/javac.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: javac
+ .\" Language: Japanese
+-.\" Date: 2014ǯ8·î8Æü
++.\" Date: 2015ǯ3·î3Æü
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "javac" "1" "2014ǯ8·î8Æü" "JDK 8" "´ðËܥġ¼¥ë"
++.TH "javac" "1" "2015ǯ3·î3Æü" "JDK 8" "´ðËܥġ¼¥ë"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -154,7 +155,7 @@
+ .PP
+ \-cp \fIpath\fR or \-classpath \fIpath\fR
+ .RS 4
+-¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¡¢¤ª¤è¤Ó(¥ª¥×¥·¥ç¥ó¤Ç)Ãí¼á¥×¥í¥»¥Ã¥µ¤È¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¸¡º÷¤¹¤ë¾ì½ê¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¥¯¥é¥¹¡¦¥Ñ¥¹¤Ï\fBCLASSPATH\fR´Ä¶­ÊÑ¿ô¤Î¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Ñ¥¹¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Þ¤¹¡£\fBCLASSPATH\fR¡¢\fB\-cp\fR¡¢\fB\-classpath\fR¤Î¤¤¤º¤ì¤â»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¡¢¥æ¡¼¥¶¡¼¤Î\fI¥¯¥é¥¹¡¦¥Ñ¥¹\fR¤Ï¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤Ê¤ê¤Þ¤¹¡£Setting the Class Path ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¡¢¤ª¤è¤Ó(¥ª¥×¥·¥ç¥ó¤Ç)Ãí¼á¥×¥í¥»¥Ã¥µ¤È¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¸¡º÷¤¹¤ë¾ì½ê¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¥¯¥é¥¹¡¦¥Ñ¥¹¤Ï\fBCLASSPATH\fR´Ä¶­ÊÑ¿ô¤Î¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Ñ¥¹¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Þ¤¹¡£\fBCLASSPATH\fR¡¢\fB\-cp\fR¡¢\fB\-classpath\fR¤Î¤¤¤º¤ì¤â»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¡¢¥æ¡¼¥¶¡¼¤Î\fI¥¯¥é¥¹¡¦¥Ñ¥¹\fR¤Ï¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤Ê¤ê¤Þ¤¹¡£¥¯¥é¥¹¡¦¥Ñ¥¹¤ÎÀßÄê ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ \fB\-sourcepath\fR¥ª¥×¥·¥ç¥ó¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤â¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Ñ¥¹¤«¤é¸¡º÷¤µ¤ì¤Þ¤¹¡£
+ .sp
+@@ -1122,9 +1123,7 @@
+ .PP
+ \fBjavac\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤¹¤ë¤È¤­¤Ë¡¢³Æ°ú¿ô¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤È̾Á°¤ÎÀèƬ¤Ë¥¢¥Ã¥È¥Þ¡¼¥¯(@)ʸ»ú¤òÉÕ¤±¤ÆÅϤ·¤Þ¤¹¡£\fBjavac\fR¥³¥Þ¥ó¥É¤Ï¡¢¥¢¥Ã¥È¥Þ¡¼¥¯(@)¤Ç»Ï¤Þ¤ë°ú¿ô¤ò¸«¤Ä¤±¤ë¤È¡¢¤½¤Î¥Õ¥¡¥¤¥ë¤ÎÆâÍƤòŸ³«¤·¤Æ°ú¿ô¥ê¥¹¥È¤ËÁÞÆþ¤·¤Þ¤¹¡£
+ .PP
+-\fBÎã 1\fR
+-.br
+-ñ°ì¤Î°ú¿ô¥Õ¥¡¥¤¥ë
++\fBÎã 1 \fRñ°ì¤Î°ú¿ô¥Õ¥¡¥¤¥ë
+ .RS 4
+ \fBargfile\fR¤È¤¤¤¦Ì¾Á°¤Îñ°ì¤Î°ú¿ô¥Õ¥¡¥¤¥ë¤ò»ÈÍѤ·¤Æ¡¢¤¹¤Ù¤Æ¤Î\fBjavac\fR°ú¿ô¤ò³ÊǼ¤¹¤ë¾ì¹ç¤Ï¡¢¼¡¤Î¤è¤¦¤Ë»ØÄꤷ¤Þ¤¹¡£
+ .sp
+@@ -1141,9 +1140,7 @@
+ ¤³¤Î°ú¿ô¥Õ¥¡¥¤¥ë¤Ë¤Ï¡¢Îã2¤Ç¼¨¤µ¤ì¤Æ¤¤¤ëξÊý¤Î¥Õ¥¡¥¤¥ë¤ÎÆâÍƤòÆþ¤ì¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-2¤Ä¤Î°ú¿ô¥Õ¥¡¥¤¥ë
++\fBÎã 2 \fR2¤Ä¤Î°ú¿ô¥Õ¥¡¥¤¥ë
+ .RS 4
+ \fBjavac\fR¥ª¥×¥·¥ç¥óÍѤȥ½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾ÍѤˡ¢2¤Ä¤Î°ú¿ô¥Õ¥¡¥¤¥ë¤òºîÀ®¤Ç¤­¤Þ¤¹¡£¼¡¤Î¥ê¥¹¥È¤Ë¤Ï¡¢¹Ô¤Î·Ñ³ʸ»ú¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+ .sp
+@@ -1216,9 +1213,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 3\fR
+-.br
+-¥Ñ¥¹¤ò»ÈÍѤ·¤¿°ú¿ô¥Õ¥¡¥¤¥ë
++\fBÎã 3 \fR¥Ñ¥¹¤ò»ÈÍѤ·¤¿°ú¿ô¥Õ¥¡¥¤¥ë
+ .RS 4
+ °ú¿ô¥Õ¥¡¥¤¥ë¤Ï¥Ñ¥¹¤ò»ØÄê¤Ç¤­¤Þ¤¹¤¬¡¢¥Õ¥¡¥¤¥ëÆâ¤Î¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë̾¤Ï¡¢(\fBpath1\fR¤ä\fBpath2\fR¤Ç¤Ï¤Ê¤¯)¼¡¤Î¤è¤¦¤Ë¸½ºß¤Îºî¶È¥Ç¥£¥ì¥¯¥È¥ê¤ËÁêÂÐŪ¤È¤Ê¤ê¤Þ¤¹¡£
+ .sp
+@@ -1317,9 +1312,7 @@
+ ̾Á°¤¬\fBcom\&.sun\&.tools\&.javac\fR¤Ç»Ï¤Þ¤ë¥Ñ¥Ã¥±¡¼¥¸(\fBcom\&.sun\&.tools\&.javac\fR¤Î¥µ¥Ö¥Ñ¥Ã¥±¡¼¥¸)¤Ç¸¡½Ð¤µ¤ì¤ë¾¤Î¤¹¤Ù¤Æ¤Î¥¯¥é¥¹¤ª¤è¤Ó¥á¥½¥Ã¥É¤Ï¡¢´°Á´¤ËÆâÉôÍѤǤ¢¤ê¡¢¤¤¤Ä¤Ç¤âÊѹ¹¤µ¤ì¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£
+ .SH "Îã"
+ .PP
+-\fBÎã 1\fR
+-.br
+-´Êñ¤Ê¥×¥í¥°¥é¥à¤Î¥³¥ó¥Ñ¥¤¥ë
++\fBÎã 1 \fR´Êñ¤Ê¥×¥í¥°¥é¥à¤Î¥³¥ó¥Ñ¥¤¥ë
+ .RS 4
+ ¤³¤ÎÎã¤Ç¤Ï¡¢greetings¥Ç¥£¥ì¥¯¥È¥ê¤Ç\fBHello\&.java\fR¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ëÊýË¡¤ò¼¨¤·¤Æ¤¤¤Þ¤¹¡£\fBHello\&.java\fR¤ÇÄêµÁ¤µ¤ì¤¿¥¯¥é¥¹¤Ï¡¢\fBgreetings\&.Hello\fR¤È¸Æ¤Ð¤ì¤Þ¤¹¡£greetings¥Ç¥£¥ì¥¯¥È¥ê¤Ï¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤È¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤ÎξÊý¤¬¤¢¤ë¥Ñ¥Ã¥±¡¼¥¸¡¦¥Ç¥£¥ì¥¯¥È¥ê¤Ç¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î¤¹¤°²¼¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Ñ¥¹¤ò»ÈÍѤǤ­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£¤Þ¤¿¡¢\fB\-d\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤ÆÊ̤νÐÎÏÀè¥Ç¥£¥ì¥¯¥È¥ê¤ò»ØÄꤹ¤ëɬÍפ⤢¤ê¤Þ¤»¤ó¡£
+ .sp
+@@ -1372,9 +1365,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-Ê£¿ô¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Î¥³¥ó¥Ñ¥¤¥ë
++\fBÎã 2 \fRÊ£¿ô¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Î¥³¥ó¥Ñ¥¤¥ë
+ .RS 4
+ ¤³¤ÎÎã¤Ç¤Ï¡¢\fBgreetings\fR¥Ñ¥Ã¥±¡¼¥¸¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë\fBAloha\&.java\fR¡¢\fBGutenTag\&.java\fR¡¢\fBHello\&.java\fR¤ª¤è¤Ó\fBHi\&.java\fR¤ò¥³¥ó¥Ñ¥¤¥ë¤·¤Þ¤¹¡£
+ .sp
+@@ -1393,9 +1384,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 3\fR
+-.br
+-¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Ñ¥¹¤Î»ØÄê
++\fBÎã 3 \fR¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¹¡¦¥Ñ¥¹¤Î»ØÄê
+ .RS 4
+ Á°½Ò¤ÎÎã¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Î¤¦¤Á1¤Ä¤òÊѹ¹¤·¤¿¸å¤Ë¡¢¤½¤Î¥Õ¥¡¥¤¥ë¤òºÆ¥³¥ó¥Ñ¥¤¥ë¤·¤Þ¤¹¡£
+ .sp
+@@ -1450,9 +1439,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 4\fR
+-.br
+-¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤È¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤ÎʬΥ
++\fBÎã 4 \fR¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤È¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤ÎʬΥ
+ .RS 4
+ ¼¡¤ÎÎã¤Ç¤Ï¡¢\fBjavac\fR¤ò»ÈÍѤ·¤Æ¡¢JVM 1\&.7¾å¤Ç¼Â¹Ô¤¹¤ë¥³¡¼¥É¤ò¥³¥ó¥Ñ¥¤¥ë¤·¤Þ¤¹¡£
+ .sp
+@@ -1486,9 +1473,7 @@
+ ŬÀڤʥС¼¥¸¥ç¥ó¤Î¥Ö¡¼¥È¥¹¥È¥é¥Ã¥×¡¦¥¯¥é¥¹¤ò»ØÄꤷ¤Ê¤¤¾ì¹ç¡¢¥³¥ó¥Ñ¥¤¥é¤Ï¸Å¤¤¸À¸ì»ÅÍÍ(¤³¤ÎÎã¤Ç¤Ï¡¢¥Ð¡¼¥¸¥ç¥ó1\&.7¤ÎJava¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì)¤ò¿·¤·¤¤¥Ö¡¼¥È¥¹¥È¥é¥Ã¥×¡¦¥¯¥é¥¹¤ÈÁȤ߹礻¤Æ»ÈÍѤ·¤Þ¤¹¡£¤½¤Î·ë²Ì¡¢Â¸ºß¤·¤Ê¤¤¥á¥½¥Ã¥É¤Ø¤Î»²¾È¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤¢¤ë¤¿¤á¡¢¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤¬¸Å¤¤¥×¥é¥Ã¥È¥Õ¥©¡¼¥à(¤³¤Î¾ì¹ç¤ÏJava SE 7)¤ÇÆ°ºî¤·¤Ê¤¤²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .PP
+-\fBÎã 5\fR
+-.br
+-¥¯¥í¥¹¡¦¥³¥ó¥Ñ¥¤¥ë
++\fBÎã 5 \fR¥¯¥í¥¹¡¦¥³¥ó¥Ñ¥¤¥ë
+ .RS 4
+ ¤³¤ÎÎã¤Ç¤Ï¡¢\fBjavac\fR¤ò»ÈÍѤ·¤Æ¡¢JVM 1\&.7¾å¤Ç¼Â¹Ô¤¹¤ë¥³¡¼¥É¤ò¥³¥ó¥Ñ¥¤¥ë¤·¤Þ¤¹¡£
+ .sp
+@@ -1503,7 +1488,7 @@
+ .if n \{\
+ .RE
+ .\}
+-\fB \-source 1\&.7\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¡¢OldCode\&.java¤Î¥³¥ó¥Ñ¥¤¥ë¤Ë¤Ï¥ê¥ê¡¼¥¹1\&.7(¤Þ¤¿¤Ï7)¤ÎJava¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤¬»ÈÍѤµ¤ì¤Þ¤¹¡£\fB\-target 1\&.7\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¡¢JVM 1\&.7¤È¸ß´¹À­¤Î¤¢¤ë¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤¬À¸À®¤µ¤ì¤Þ¤¹¡£¤Û¤È¤ó¤É¤Î¾ì¹ç¡¢\fB\-target\fR¤ÎÃͤÏ\fB\-source\fR¤ÎÃͤˤʤê¤Þ¤¹¡£¤³¤ÎÎã¤Ç¤Ï¡¢\fB\-target\fR¥ª¥×¥·¥ç¥ó¤Ï¾Êά¤µ¤ì¤Þ¤¹¡£
++\fB \-source 1\&.7\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¡¢OldCode\&.java¤Î¥³¥ó¥Ñ¥¤¥ë¤Ë¤Ï¥ê¥ê¡¼¥¹1\&.7(¤Þ¤¿¤Ï7)¤ÎJava¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤¬»ÈÍѤµ¤ì¤Þ¤¹¡£\fB\-target 1\&.7\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¡¢JVM 1\&.7¤È¸ß´¹À­¤Î¤¢¤ë¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤¬À¸À®¤µ¤ì¤Þ¤¹¡£
+ .sp
+ \fB\-bootclasspath\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¡¢Å¬ÀڤʥС¼¥¸¥ç¥ó¤Î¥Ö¡¼¥È¥¹¥È¥é¥Ã¥×¡¦¥¯¥é¥¹(\fBrt\&.jar\fR¥é¥¤¥Ö¥é¥ê)¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£»ØÄꤷ¤Ê¤¤¾ì¹ç¤Ï¡¢¥³¥ó¥Ñ¥¤¥é¤Ë¤è¤Ã¤Æ¼¡¤Î·Ù¹ð¤¬À¸À®¤µ¤ì¤Þ¤¹¡£
+ .sp
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/javadoc.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/javadoc.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: javadoc
+ .\" Language: Japanese
+-.\" Date: 2011ǯ5·î10Æü
++.\" Date: 2015ǯ3·î3Æü
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "javadoc" "1" "2011ǯ5·î10Æü" "JDK 8" "´ðËܥġ¼¥ë"
++.TH "javadoc" "1" "2015ǯ3·î3Æü" "JDK 8" "´ðËܥġ¼¥ë"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -359,7 +360,7 @@
+ .IP \(bu 2.3
+ .\}
+ ½èÍý¤Ç¤­¤ë¤è¤¦¤Ë¥³¥á¥ó¥È¤ò¥³¥Ô¡¼¤·¤Þ¤¹¡£package\&.html¤Î¾ì¹ç¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¡¢\fB<body>\fR¤È\fB</body>\fR
+-HTML¥¿¥°´Ö¤Ç¤¹¤Ù¤Æ¤Î¥³¥ó¥Æ¥ó¥Ä¤ò¥³¥Ô¡¼¤·¤Þ¤¹¡£\fB<head>\fR¥»¥¯¥·¥ç¥ó¤ò´Þ¤á¤Æ¡¢\fB<title>\fR¥¿¥°¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Î¥³¥Ô¡¼¥é¥¤¥Èʸ¡¢¤½¤Î¾¤Î¾ðÊó¤òÇÛÃÖ¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤¹¤¬¡¢¤³¤ì¤é¤ÏÀ¸À®¤µ¤ì¤ë¥É¥­¥å¥á¥ó¥È¤Ë¤Ïɽ¼¨¤µ¤ì¤Þ¤»¤ó¡£
++HTML¥¿¥°´Ö¤Ç¤¹¤Ù¤Æ¤Î¥³¥ó¥Æ¥ó¥Ä¤ò¥³¥Ô¡¼¤·¤Þ¤¹¡£\fB<title>\fR¥¿¥°¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ÎÃøºî¸¢Ê¸¤Þ¤¿¤Ï¾¤Î¾ðÊó¤òÇÛÃÖ¤¹¤ë\fB<head>\fR¥»¥¯¥·¥ç¥ó¤ò´Þ¤á¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¤¬¡¢¤³¤ì¤é¤ÏÀ¸À®¤µ¤ì¤¿¥É¥­¥å¥á¥ó¥È¤Ëɽ¼¨¤µ¤ì¤Þ¤»¤ó¡£
+ .RE
+ .sp
+ .RS 4
+@@ -1425,9 +1426,9 @@
+ .RS 4
+ JDK 1\&.5¤ÇƳÆþ
+ .sp
+-\fB<code>{@literal}</code>\fR¤ÈƱÅù¤Ç¤¹¡£
+-.sp
+-¥Æ¥­¥¹¥È¤òHTML¥Þ¡¼¥¯¥¢¥Ã¥×¤Þ¤¿¤Ï¥Í¥¹¥È¤µ¤ì¤¿Javadoc¥¿¥°¤È¤·¤Æ²ò¼á¤»¤º¤Ë¡¢text¤ò¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Çɽ¼¨¤·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤Ç¤Ï¡¢¥Ñ¥é¥á¡¼¥¿¤Î·¿(\fB<Object>\fR)¡¢ÉÔÅù¹æ(\fB3 < 4\fR)¡¢Ìð°õ(\fB<\-\fR)¤Ê¤É¤Ç¡¢Ä̾ï¤Î»³¥«¥Ã¥³(<¤ª¤è¤Ó>)¤òHTML¥¨¥ó¥Æ¥£¥Æ¥£(\fB&lt;\fR¤ª¤è¤Ó\fB&gt;\fR)¤Î¤«¤ï¤ê¤Ë»ÈÍѤǤ­¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢À¸À®¤µ¤ì¤¿HTML¥Ú¡¼¥¸¤Ëɽ¼¨¤µ¤ì¤ë¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¡¦¥Æ¥­¥¹¥È\fB{@code A<B>C}\fR¤Ï¡¢Êѹ¹¤µ¤ì¤º\fBA<B>C\fR¤È¤Ê¤ê¤Þ¤¹¡£¤Ä¤Þ¤ê¡¢\fB<B>\fR¤¬ÂÀ»ú¤È¤·¤Æ²ò¼á¤µ¤ì¤º¡¢¤½¤Î¥Õ¥©¥ó¥È¤Ï¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Ë¤Ê¤ê¤Þ¤¹¡£¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Ê¤·¤ÇƱ¤¸µ¡Ç½¤ò¼Â¸½¤¹¤ë¤Ë¤Ï¡¢\fB{@literal}\fR¥¿¥°¤ò»ÈÍѤ·¤Þ¤¹¡£
++\fB<code>{@literal}</code>\fR¤ÈƱ¤¸¤Ç¤¹¡£
++.sp
++¥Æ¥­¥¹¥È¤òHTML¥Þ¡¼¥¯¥¢¥Ã¥×¤Þ¤¿¤Ï¥Í¥¹¥È¤µ¤ì¤¿Javadoc¥¿¥°¤È¤·¤Æ²ò¼á¤»¤º¤Ë¡¢text¤ò¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Çɽ¼¨¤·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤Ç¤Ï¡¢¥Ñ¥é¥á¡¼¥¿¤Î·¿(\fB<Object>\fR)¡¢ÉÔÅù¹æ(\fB3 < 4\fR)¡¢Ìð°õ(\fB<\-\fR)¤Ê¤É¤Ç¡¢Ä̾ï¤Î»³¥«¥Ã¥³(<¤ª¤è¤Ó>)¤òHTML¥¨¥ó¥Æ¥£¥Æ¥£(\fB&lt;\fR¤ª¤è¤Ó\fB&gt;\fR)¤Î¤«¤ï¤ê¤Ë»ÈÍѤǤ­¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¡¦¥Æ¥­¥¹¥È\fB{@code A<B>C}\fR¤Ï¡¢\fBA<B>C\fR¤È¤·¤ÆÊѹ¹¤µ¤ì¤º¤ËÀ¸À®¤µ¤ì¤¿HTML¥Ú¡¼¥¸¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£¤Ä¤Þ¤ê¡¢\fB<B>\fR¤¬ÂÀ»ú¤È¤·¤Æ²ò¼á¤µ¤ì¤º¡¢¤½¤Î¥Õ¥©¥ó¥È¤Ï¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Ë¤Ê¤ê¤Þ¤¹¡£¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Ê¤·¤ÇƱ¤¸µ¡Ç½¤ò¼Â¸½¤¹¤ë¤Ë¤Ï¡¢\fB{@literal}\fR¥¿¥°¤ò»ÈÍѤ·¤Þ¤¹¡£
+ .RE
+ .PP
+ @deprecated \fIdeprecated\-text\fR
+@@ -1594,7 +1595,7 @@
+ .RS 4
+ JDK 1\&.5¤ÇƳÆþ
+ .sp
+-¥Æ¥­¥¹¥È¤òHTML¥Þ¡¼¥¯¥¢¥Ã¥×¤Þ¤¿¤Ï¥Í¥¹¥È¤µ¤ì¤¿Javadoc¥¿¥°¤È¤·¤Æ²ò¼á¤»¤º¤Ë¡¢text¤òɽ¼¨¤·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤Ç¤Ï¡¢¥Ñ¥é¥á¡¼¥¿¤Î·¿(\fB<Object>\fR)¡¢ÉÔÅù¹æ(\fB3 < 4\fR)¡¢Ìð°õ(<\-)¤Ê¤É¤Ç¡¢»³¥«¥Ã¥³(\fB<¤ª¤è¤Ó>\fR)¤òHTML¥¨¥ó¥Æ¥£¥Æ¥£(\fB&lt;\fR¤ª¤è¤Ó\fB&gt;\fR)¤Î¤«¤ï¤ê¤Ë»ÈÍѤǤ­¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¡¦¥Æ¥­¥¹¥È\fB{@literal A<B>C}\fR¤Ï¡¢Êѹ¹¤µ¤ì¤º¤Ë¥Ö¥é¥¦¥¶¤ËÀ¸À®¤µ¤ì¤¿HTML¥Ú¡¼¥¸¤Ë\fBA<B>C\fR¤Èɽ¼¨¤µ¤ì¤Þ¤¹¡£\fB<B>\fR¤ÏÂÀ»ú¤È¤·¤Æ²ò¼á¤µ¤ì¤Þ¤»¤ó(¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Ë¤Ê¤ê¤Þ¤»¤ó)¡£¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤ÇƱ¤¸µ¡Ç½¤ò¼Â¸½¤¹¤ë¤Ë¤Ï¡¢\fB{@code}\fR¥¿¥°¤ò»ÈÍѤ·¤Þ¤¹¡£
++¥Æ¥­¥¹¥È¤òHTML¥Þ¡¼¥¯¥¢¥Ã¥×¤Þ¤¿¤Ï¥Í¥¹¥È¤µ¤ì¤¿Javadoc¥¿¥°¤È¤·¤Æ²ò¼á¤»¤º¤Ë¡¢text¤òɽ¼¨¤·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤Ç¤Ï¡¢¥Ñ¥é¥á¡¼¥¿¤Î·¿(\fB<Object>\fR)¡¢ÉÔÅù¹æ(\fB3 < 4\fR)¡¢Ìð°õ(<\-)¤Ê¤É¤Ç¡¢»³¥«¥Ã¥³(\fB<¤ª¤è¤Ó>\fR)¤òHTML¥¨¥ó¥Æ¥£¥Æ¥£(\fB&lt;\fR¤ª¤è¤Ó\fB&gt;\fR)¤Î¤«¤ï¤ê¤Ë»ÈÍѤǤ­¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¡¦¥Æ¥­¥¹¥È\fB{@literal A<B>C}\fR¤Ï¡¢\fBA<B>C\fR¤È¤·¤Æ¥Ö¥é¥¦¥¶¤ÎÀ¸À®¤µ¤ì¤¿HTML¥Ú¡¼¥¸¤ÇÊѹ¹¤µ¤ì¤º¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£\fB<B>\fR¤ÏÂÀ»ú¤È¤·¤Æ²ò¼á¤µ¤ì¤Þ¤»¤ó(¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤Ë¤Ê¤ê¤Þ¤»¤ó)¡£¥³¡¼¥É¡¦¥Õ¥©¥ó¥È¤ÇƱ¤¸µ¡Ç½¤ò¼Â¸½¤¹¤ë¤Ë¤Ï¡¢\fB{@code}\fR¥¿¥°¤ò»ÈÍѤ·¤Þ¤¹¡£
+ .RE
+ .PP
+ @param \fIparameter\-name description\fR
+@@ -1664,7 +1665,7 @@
+ .sp
+ "The Java Programming Language"
+ .sp
+-\fB·Á¼°2\fR¡£\fB@see <a href="URL#value">label</a>\fR·Á¼°¤Ï¡¢\fBURL#value\fR¤ÇÄêµÁ¤µ¤ì¤¿¥ê¥ó¥¯¤òÄɲä·¤Þ¤¹¡£\fBURL#value\fR¥Ñ¥é¥á¡¼¥¿¤Ï¡¢ÁêÂÐURL¤Þ¤¿¤ÏÀäÂÐURL¤Ç¤¹¡£\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¡¢ºÇ½é¤Îʸ»ú¤È¤·¤Æ¡Ö¤è¤ê¾®¤µ¤¤¡×µ­¹æ(\fB<\fR)¤ò¸¡º÷¤·¤Æ¡¢¤³¤Î·Á¼°¤ò¾¤Î·Á¼°¤È¶èÊ̤·¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢\fB@see <a href="spec\&.html#section">Java Spec</a>\fR¤Ï¼¡¤Î¥ê¥ó¥¯¤òÀ¸À®¤·¤Þ¤¹¡£
++\fB·Á¼°2\fR¡£\fB@see <a href="URL#value">label</a>\fR¥Õ¥©¡¼¥à¤Ï¡¢\fBURL#value\fR¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë¥ê¥ó¥¯¤òÄɲä·¤Þ¤¹¡£\fBURL#value\fR¥Ñ¥é¥á¡¼¥¿¤Ï¡¢ÁêÂÐURL¤Þ¤¿¤ÏÀäÂÐURL¤Ç¤¹¡£\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¡¢ºÇ½é¤Îʸ»ú¤È¤·¤Æ¡Ö¤è¤ê¾®¤µ¤¤¡×µ­¹æ(\fB<\fR)¤ò¸¡º÷¤·¤Æ¡¢¤³¤Î·Á¼°¤ò¾¤Î·Á¼°¤È¶èÊ̤·¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢\fB@see <a href="spec\&.html#section">Java Spec</a>\fR¤Ï¡¢¼¡¤Î¥ê¥ó¥¯¤òÀ¸À®¤·¤Þ¤¹:
+ .sp
+ \fB´ØÏ¢¹àÌÜ\fR:
+ .sp
+@@ -1673,7 +1674,7 @@
+ \fB·Á¼°3\fR¡£\fB@see package\&.class#member label\fR·Á¼°¤Ï¡¢É½¼¨¥Æ¥­¥¹¥È¡¦¥é¥Ù¥ë¤È¤È¤â¤Ë¥ê¥ó¥¯¤òÄɲä·¤Þ¤¹¡£¤³¤Î¥é¥Ù¥ë¤Ï»²¾È¤µ¤ì¤Æ¤¤¤ëJava¸À¸ì¤Î»ØÄꤵ¤ì¤¿Ì¾Á°¤Î¥É¥­¥å¥á¥ó¥È¤ò»Ø¤·¼¨¤·¤Þ¤¹¡£¥é¥Ù¥ë¤Ï¥ª¥×¥·¥ç¥ó¤Ç¤¹¡£¥é¥Ù¥ë¤ò¾Êά¤·¤¿¾ì¹ç¤Ï¡¢É½¼¨¥Æ¥­¥¹¥È¤Î¤«¤ï¤ê¤Ë¡¢Ì¾Á°¤¬Å¬ÀÚ¤Ëû½Ì¤µ¤ì¤Æɽ¼¨¤µ¤ì¤Þ¤¹¡£\fB\-noqualifier\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤È¡¢¤³¤Îɽ¼¨¥Æ¥­¥¹¥È¤«¤é¥Ñ¥Ã¥±¡¼¥¸Ì¾¤¬Á´ÂÎŪ¤Ëºï½ü¤µ¤ì¤Þ¤¹¡£¥é¥Ù¥ë¤Ï¡¢¼«Æ°À¸À®¤µ¤ì¤ëɽ¼¨¥Æ¥­¥¹¥È¤È¤Ï°Û¤Ê¤ëɽ¼¨¥Æ¥­¥¹¥È¤Ë¤¹¤ë¾ì¹ç¤Ë»ÈÍѤ·¤Þ¤¹¡£¡Ö̾Á°¤¬É½¼¨¤µ¤ì¤ëÊýË¡¡×¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ Java SE 1\&.2¤À¤±¤Ï¡¢¥é¥Ù¥ë¤Ç¤Ï¤Ê¤¯Ì¾Á°¤¬\fB<code>\fR
+-HTML¥¿¥°Æâ¤Ë¼«Æ°Åª¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£Java SE 1\&.2\&.2¤«¤é¤Ï¡¢¥é¥Ù¥ë¤ò»ÈÍѤ¹¤ë¤«¤·¤Ê¤¤¤«¤Ë¤«¤«¤ï¤é¤º¡¢\fB<code>\fR¥¿¥°¤Ï¾ï¤Ëɽ¼¨¥Æ¥­¥¹¥È¤ò°Ï¤à¤«¤¿¤Á¤Ç´Þ¤Þ¤ì¤Þ¤¹¡£
++HTML¥¿¥°Æâ¤Ë¼«Æ°Åª¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£Java SE 1\&.2\&.2¤«¤é¤Ï¡¢¥é¥Ù¥ë¤ò»ÈÍѤ¹¤ë¤«¤·¤Ê¤¤¤«¤Ë¤«¤«¤ï¤é¤º¡¢\fB<code>\fR¥¿¥°¤Ï¾ï¤Ëɽ¼¨¥Æ¥­¥¹¥È¤ò°Ï¤à·Á¤Ç´Þ¤Þ¤ì¤Þ¤¹¡£
+ .sp
+ .RS 4
+ .ie n \{\
+@@ -2290,15 +2291,677 @@
+ .RE
+ .PP
+ ¥ª¥×¥·¥ç¥ó¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹¡£
+-.PP
+-\-1\&.1 || \-author || \-bootclasspath classpathlist || \-bottom text || \-breakiterator || \-charset name || \-classpath classpathlist || \-d directory || \-docencoding name || \-docfilesubdirs || \-doclet class || \-docletpath classpathlist || \-doctitle title || \-encoding || \-exclude packagename1:packagename2:\&.\&.\&. || \-excludedocfilessubdir name1:name2 || \-extdirs dirist || \-footer footer || \-group groupheading packagepattern:packagepattern || \-header header || \-help || \-helpfile path\efilename || \-Jflag || \-keywords || \-link extdocURL || \-linkoffline extdocURL packagelistLoc || \-linksource || \-locale language_country_variant || \-nocomment || \-nodeprecated || \-nodeprecatedlist || \-nohelp || \-noindex || \-nonavbar || \-noqualifier all | packagename1:packagename2\&.\&.\&. || \-nosince || \-notimestamp || \-notree ||
+-
+-\-overview path/filename ||
+-\-package || \-private || \-protected || \-public || \-quiet || \-serialwarn || \-source release || \-sourcepath sourcepathlist || \-sourcetab tablength || \-splitindex ||
+-
+-\-stylesheet path/filename ||
+-
+-||\-subpackages package1:package2:\&.\&.\&. || \-tag tagname:Xaoptcmf:"taghead" || \-taglet class || \-tagletpath tagletpathlist || \-title title || \-top || \-use || \-verbose || \-version || \-windowtitle title
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-1\&.1
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-author
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-bootclasspath classpathlist
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-bottom text
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-breakiterator
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-charset name
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-classpath classpathlist
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-d directory
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-docencoding name
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-docfilesubdirs
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-doclet class
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-docletpath classpathlist
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-doctitle title
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-encoding
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-exclude packagename1:packagename2:\&.\&.\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-excludedocfilessubdir name1:name2
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-extdirs dirist
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-footer footer
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-group groupheading packagepattern:packagepattern
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-header header
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-help
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-helpfile path\efilename
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-Jflag
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-javafx
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-keywords
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-link extdocURL
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-linkoffline extdocURL packagelistLoc
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-linksource
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-locale language_country_variant
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-nocomment
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-nodeprecated
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-nodeprecatedlist
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-nohelp
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-noindex
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-nonavbar
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-noqualifier all | packagename1:packagename2\&.\&.\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-nosince
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-notimestamp
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-notree
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-overview path/filename
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-package
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-private
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-protected
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-public
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-quiet
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-serialwarn
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-source release
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-sourcepath sourcepathlist
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-sourcetab tablength
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-splitindex
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-stylesheet path/filename
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-tag tagname:Xaoptcmf:"taghead"
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-subpackages package1:package2:\&.\&.\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-taglet class
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-tagletpath tagletpathlist
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-title title
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-top
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-use
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-verbose
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-version
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++\-windowtitle title
++.RE
+ .PP
+ ¼¡¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¤¹¤Ù¤Æ¤Î¥É¥Ã¥¯¥ì¥Ã¥È¤Ë»ÈÍѲÄǽ¤Ê¥³¥¢¤ÎJavadoc¥ª¥×¥·¥ç¥ó¤Ç¤¹¡£É¸½à¥É¥Ã¥¯¥ì¥Ã¥È¤Ç¤Ï¡¢¥É¥Ã¥¯¥ì¥Ã¥È¤Î¾¤ÎÉôʬ¤òÄ󶡤·¤Þ¤¹¡£\fB\-bootclasspath\fR¡¢\fB\-breakiterator\fR¡¢\fB\-classpath\fR¡¢\fB\-doclet\fR¡¢\fB\-docletpath\fR¡¢\fB\-encoding\fR¡¢\-\fBexclude\fR¡¢\fB\-extdirs\fR¡¢\fB\-help\fR¡¢\fB\-locale\fR¡¢\fB\-\fR\fBoverview\fR¡¢\fB\-package\fR¡¢\fB\-private\fR¡¢\fB\-protected\fR¡¢\fB\-public\fR¡¢\fB\-quiet\fR¡¢\fB\-source\fR¡¢\fB\-sourcepath\fR¡¢\fB\-subpackages\fR¤ª¤è¤Ó\fB\-verbose\fR¡£
+ .SS "Javadoc¥ª¥×¥·¥ç¥ó"
+@@ -2306,7 +2969,7 @@
+ \-overview \fIpath/filename \fR
+ .RS 4
+
+-\fBjavadoc\fR¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¡¢\fIpath/filename \fR¤Ç»ØÄꤵ¤ì¤¿¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤«¤é³µÍץɥ­¥å¥á¥ó¥ÈÍѤΥƥ­¥¹¥È¤ò¼èÆÀ¤·¡¢¤½¤Î¥Æ¥­¥¹¥È¤ò³µÍ×¥Ú¡¼¥¸(overview\-summary\&.html)¤ËÇÛÃÖ¤¹¤ë¤è¤¦¤Ë»ØÄꤷ¤Þ¤¹¡£\fIpath/filename\fR¤Ï¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤ÎÁêÂХѥ¹¤Ç¤¹¡£
++\fBjavadoc\fR¥³¥Þ¥ó¥É¤ËÂФ·¤Æ¡¢\fIpath/filename \fR¤Ç»ØÄꤵ¤ì¤¿¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤«¤é³µÍץɥ­¥å¥á¥ó¥ÈÍѤΥƥ­¥¹¥È¤ò¼èÆÀ¤·¡¢¤½¤Î¥Æ¥­¥¹¥È¤ò¡Ö³µÍסץڡ¼¥¸(overview\-summary\&.html)¤ËÇÛÃÖ¤¹¤ë¤è¤¦¤Ë»ØÄꤷ¤Þ¤¹¡£\fIpath/filename\fR¤Ï¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤ÎÁêÂХѥ¹¤Ç¤¹¡£
+ .sp
+ \fBfilename\fR¤ÎÃͤÇǤ°Õ¤Î̾Á°¤ò»ÈÍѤ·¡¢path¤ÇǤ°Õ¤ÎÇÛÃÖÀè¤ò»ØÄê¤Ç¤­¤Þ¤¹¤¬¡¢Ä̾ï¤Ïoverview\&.html¤È¤¤¤¦Ì¾Á°¤òÉÕ¤±¡¢¥½¡¼¥¹¡¦¥Ä¥ê¡¼Æâ¤ÎºÇ¾å°Ì¥Ñ¥Ã¥±¡¼¥¸¡¦¥Ç¥£¥ì¥¯¥È¥ê¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤ËÇÛÃÖ¤·¤Þ¤¹¡£¤³¤Î¾ì½ê¤ËÇÛÃÖ¤¹¤ë¤È¡¢¥Ñ¥Ã¥±¡¼¥¸¤ò¥É¥­¥å¥á¥ó¥È²½¤¹¤ë¤È¤­¤Ëpath¤ò»ØÄꤹ¤ëɬÍפ¬¤Ê¤¯¤Ê¤ê¤Þ¤¹¡£¤³¤ì¤Ï¡¢\fB\-sourcepath\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤Ã¤Æ¤³¤Î¥Õ¥¡¥¤¥ë¤¬»Ø¤·¼¨¤µ¤ì¤ë¤«¤é¤Ç¤¹¡£
+ .sp
+@@ -2316,7 +2979,7 @@
+ .sp
+ \fIpath/filename\fR¤Ç»ØÄꤹ¤ë¥Õ¥¡¥¤¥ë¤Ë¤Ä¤¤¤Æ¤Ï¡¢³µÍ×¥³¥á¥ó¥È¡¦¥Õ¥¡¥¤¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+-³µÍ×¥Ú¡¼¥¸¤¬ºîÀ®¤µ¤ì¤ë¤Î¤Ï¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤ËÊ£¿ô¤Î¥Ñ¥Ã¥±¡¼¥¸Ì¾¤òÅϤ·¤¿¾ì¹ç¤Î¤ß¤Ç¤¹¡£¾ÜºÙ¤Ï¡¢HTML¥Õ¥ì¡¼¥à¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£³µÍ×¥Ú¡¼¥¸¤Î¥¿¥¤¥È¥ë¤Ï¡¢\fB\-doctitle\fR¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤Þ¤¹¡£
++¡Ö³µÍסץڡ¼¥¸¤¬ºîÀ®¤µ¤ì¤ë¤Î¤Ï¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤ËÊ£¿ô¤Î¥Ñ¥Ã¥±¡¼¥¸Ì¾¤òÅϤ·¤¿¾ì¹ç¤Î¤ß¤Ç¤¹¡£¾ÜºÙ¤Ï¡¢HTML¥Õ¥ì¡¼¥à¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£¡Ö³µÍסץڡ¼¥¸¤Î¥¿¥¤¥È¥ë¤Ï¡¢\fB\-doctitle\fR¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ \-Xdoclint:(all|none|[\-]\fI<group>\fR)
+@@ -2537,8 +3200,9 @@
+ \-sourcepath \fIsourcepathlist\fR
+ .RS 4
+ ¥Ñ¥Ã¥±¡¼¥¸Ì¾¤Þ¤¿¤Ï\fB\-subpackages\fR¥ª¥×¥·¥ç¥ó¤ò\fBjavadoc\fR¥³¥Þ¥ó¥É¤ËÅϤ¹¤È¤­¤Ë¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¸«¤Ä¤±¤ë¤¿¤á¤Î¸¡º÷¥Ñ¥¹¤ò»ØÄꤷ¤Þ¤¹¡£
+-
++.sp
+ Ê£¿ô¤Î¥Ñ¥¹¤Ï¥³¥í¥ó(:)¤Ç¶èÀÚ¤ê¤Þ¤¹¡£
++.sp
+ \fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¡¢»ØÄꤵ¤ì¤¿¥Ñ¥¹°Ê²¼¤Î¤¹¤Ù¤Æ¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ò¸¡º÷¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¡¢¥É¥­¥å¥á¥ó¥È²½¤µ¤ì¤ë¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Î°ÌÃ֤ΤߤǤʤ¯¡¢¤½¤ì¼«ÂΤϥɥ­¥å¥á¥ó¥È²½¤µ¤ì¤Ê¤¤¤¬¥É¥­¥å¥á¥ó¥È²½¤µ¤ì¤ë¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤«¤é·Ñ¾µ¤µ¤ì¤¿¥³¥á¥ó¥È¤ò»ý¤Ä¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Î°ÌÃÖ¤â³Îǧ¤Ç¤­¤Þ¤¹¡£
+ .sp
+ \fB\-sourcepath\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤǤ­¤ë¤Î¤Ï¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ë¥Ñ¥Ã¥±¡¼¥¸Ì¾¤òÅϤ¹¾ì¹ç¤Î¤ß¤Ç¤¹¡£\fBjavadoc\fR¥³¥Þ¥ó¥É¤ËÅϤµ¤ì¤ë¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Ï¸¡º÷¤µ¤ì¤Þ¤»¤ó¡£¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤òÆÃÄꤹ¤ë¤Ë¤Ï¡¢¤½¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë°ÜÆ°¤¹¤ë¤«¡¢¡Ö1¤Ä°Ê¾å¤Î¥¯¥é¥¹¤Î¥É¥­¥å¥á¥ó¥È²½¡×¤Ë¼¨¤¹¤è¤¦¤Ë³Æ¥Õ¥¡¥¤¥ë¤ÎÁ°¤Ë¥Ñ¥¹¤ò´Þ¤á¤Þ¤¹¡£\fB\-sourcepath\fR¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¡¢¥¯¥é¥¹¡¦¥Ñ¥¹¤ò»ÈÍѤ·¤Æ¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¸¡º÷¤·¤Þ¤¹(\fB\-classpath\fR¤ò»²¾È)¡£¥Ç¥Õ¥©¥ë¥È¤Î\fB\-sourcepath\fR¤Ï¡¢¥¯¥é¥¹¡¦¥Ñ¥¹¤ÎÃͤǤ¹¡£\fB\-classpath\fR¤ò¾Êά¤·¤Æ¥Ñ¥Ã¥±¡¼¥¸Ì¾¤ò\fBjavadoc\fR¥³¥Þ¥ó¥É¤ËÅϤ¹¤È¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê(¤ª¤è¤Ó¤½¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê)¤«¤é¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¸¡º÷¤·¤Þ¤¹¡£
+@@ -2578,8 +3242,9 @@
+ \-classpath \fIclasspathlist\fR
+ .RS 4
+ \fBjavadoc\fR¥³¥Þ¥ó¥É¤¬»²¾È¥¯¥é¥¹¤Î¸¡º÷¤ò¹Ô¤¦¤È¤­¤Ë»ÈÍѤ¹¤ë¥Ñ¥¹¤ò»ØÄꤷ¤Þ¤¹¡£»²¾È¥¯¥é¥¹¤È¤Ï¡¢¥É¥­¥å¥á¥ó¥È²½¤µ¤ì¤ë¥¯¥é¥¹¤È¡¢¤½¤ì¤é¤Î¥¯¥é¥¹¤Ë¤è¤Ã¤Æ»²¾È¤µ¤ì¤ë¤¹¤Ù¤Æ¤Î¥¯¥é¥¹¤Î¤³¤È¤Ç¤¹¡£
+-
++.sp
+ Ê£¿ô¤Î¥Ñ¥¹¤Ï¥³¥í¥ó(:)¤Ç¶èÀÚ¤ê¤Þ¤¹¡£
++.sp
+ \fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¡¢»ØÄꤵ¤ì¤¿¥Ñ¥¹°Ê²¼¤Î¤¹¤Ù¤Æ¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ò¸¡º÷¤·¤Þ¤¹¡£\fBclasspathlist\fR¤ÎÃͤò»ØÄꤹ¤ë¤È¤­¤Ï¡¢¥¯¥é¥¹¡¦¥Ñ¥¹¤Î¥É¥­¥å¥á¥ó¥È¤Ë¤¢¤ë»Ø¼¨¤Ë½¾¤Ã¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ \fB\-sourcepath\fR¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï\fB\-classpath\fR¤ò»ÈÍѤ·¤Æ¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ª¤è¤Ó¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¸¡º÷¤·¤Þ¤¹(¸åÊý¸ß´¹À­¤Î¤¿¤á)¡£¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤È¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤òÊÌ¡¹¤Î¥Ñ¥¹¤«¤é¸¡º÷¤¹¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤Ï¡¢\fB\-sourcepath\fR¤È\fB\-classpath\fR¤ÎξÊý¤ò»ÈÍѤ·¤Þ¤¹¡£
+@@ -2689,7 +3354,7 @@
+ .sp -1
+ .IP \(bu 2.3
+ .\}
+-breakiteratorʸ¶èÀڤꥢ¥ë¥´¥ê¥º¥à¡£¼¡¤Î¸ì¤¬Âçʸ»ú¤Ç»Ï¤Þ¤ë¾ì¹ç¡¢¶õÇòʸ»ú¤¬Â³¤¯¥Ô¥ê¥ª¥É¡¢µ¿ÌäÉä¡¢¤Þ¤¿¤Ï´¶Ã²Éä¤ÇÄä»ß¤·¤Þ¤¹¡£¤³¤Î¥¢¥ë¥´¥ê¥º¥à¤Ç¤Ï¡ÖThe serial no\&. is valid¡×¤Ê¤É¡¢¤Û¤È¤ó¤É¤Î¾Êάɽµ­¤¬½èÍý¤µ¤ì¤Þ¤¹¤¬¡¢¡ÖMr\&. Smith¡×¤Ï½èÍý¤µ¤ì¤Þ¤»¤ó¡£\fB\-breakiterator\fR¥ª¥×¥·¥ç¥ó¤Ç¤Ï¡¢HTML¥¿¥°¤ä¡¢¿ô»ú¤Þ¤¿¤Ïµ­¹æ¤Ç»Ï¤Þ¤ëʸ¤Ç¤ÏÄä»ß¤·¤Þ¤»¤ó¡£HTML¥¿¥°¤ËËä¤á¹þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ç¤â¡¢¡Ö\&.\&./filename¡×¤ÎºÇ¸å¤Î¥Ô¥ê¥ª¥É¤ÇÄä»ß¤·¤Þ¤¹¡£
++breakiteratorʸ¶èÀڤꥢ¥ë¥´¥ê¥º¥à¡£¼¡¤Î¸ì¤¬Âçʸ»ú¤Ç»Ï¤Þ¤ë¾ì¹ç¡¢¶õÇòʸ»ú¤¬Â³¤¯¥Ô¥ê¥ª¥É¡¢µ¿ÌäÉä¡¢¤Þ¤¿¤Ï´¶Ã²Éä¤ÇÄä»ß¤·¤Þ¤¹¡£¤³¤Î¥¢¥ë¥´¥ê¥º¥à¤Ç¤Ï¡ÖThe serial no\&. is valid¡×¤Ê¤É¡¢¤Û¤È¤ó¤É¤Î¾Êάɽµ­¤¬½èÍý¤µ¤ì¤Þ¤¹¤¬¡¢¡ÖMr\&. Smith¡×¤Ï½èÍý¤µ¤ì¤Þ¤»¤ó¡£\fB\-breakiterator\fR¥ª¥×¥·¥ç¥ó¤Ç¤Ï¡¢HTML¥¿¥°¤ä¡¢¿ô»ú¤Þ¤¿¤Ïµ­¹æ¤Ç»Ï¤Þ¤ëʸ¤Ç¤ÏÄä»ß¤·¤Þ¤»¤ó¡£HTML¥¿¥°¤ËËä¤á¹þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ç¤â¡¢¥¢¥ë¥´¥ê¥º¥à¤Ï¡Ö\&.\&./filename¡×¤ÎºÇ¸å¤Î¥Ô¥ê¥ª¥É¤ÇÄä»ß¤·¤Þ¤¹¡£
+ .RE
+ .sp
+ Java SE 1\&.5¤Ç¤Ï\fB\-breakiterator\fR·Ù¹ð¥á¥Ã¥»¡¼¥¸¤¬ºï½ü¤µ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Îʸ¶èÀڤꥢ¥ë¥´¥ê¥º¥à¤ÏÊѹ¹¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£¥½¡¼¥¹¡¦¥³¡¼¥É¤òÊѹ¹¤»¤º¡¢SE 1\&.4\&.x¤Ç¤Î\fB\-breakiterator\fR¥ª¥×¥·¥ç¥ó¤Î·Ù¹ð¤ò½üµî¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ç¤â¡¢²¿¤â¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£Java SE 1\&.5\&.0¤«¤é¤Ï·Ù¹ð¤Ï¾ÃÌǤ·¤Æ¤¤¤Þ¤¹¡£
+@@ -2734,18 +3399,37 @@
+ .RE
+ .\}
+ .RE
++.PP
++\-javafx
++.RS 4
++ɸ½à¥É¥Ã¥¯¥ì¥Ã¥È¤ËÂФ·¤ÆJavaFX³ÈÄ¥µ¡Ç½¤ò»ÈÍѤ·¤Æ¡¢HTML¥É¥­¥å¥á¥ó¥È¤òÀ¸À®¤·¤Þ¤¹¡£À¸À®¤µ¤ì¤¿¥É¥­¥å¥á¥ó¥È¤Ë¤Ï¡¢É¸½àJava¥É¥Ã¥¯¥ì¥Ã¥È¤ÇÀ¸À®¤µ¤ì¤¿Â¾¤Î¥µ¥Þ¥ê¡¼¡¦¥»¥¯¥·¥ç¥ó¤Ë²Ã¤¨¤Æ¡Ö¥×¥í¥Ñ¥Æ¥£¤Î¥µ¥Þ¥ê¡¼¡×¥»¥¯¥·¥ç¥ó¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£¥ê¥¹¥È¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤Ï¡¢³Æ¥×¥í¥Ñ¥Æ¥£¤Îgetter¤ª¤è¤Ósetter¥á¥½¥Ã¥É¤Î¥»¥¯¥·¥ç¥ó¤Ë¥ê¥ó¥¯¤µ¤ì¤Þ¤¹¡£
++.sp
++getter¤ª¤è¤Ósetter¥á¥½¥Ã¥É¤ËÂФ·¤ÆÌÀ¼¨Åª¤Ëµ­ºÜ¤µ¤ì¤Æ¤¤¤ë¥É¥­¥å¥á¥ó¥È¡¦¥³¥á¥ó¥È¤¬¤Ê¤¤¾ì¹ç¡¢¥×¥í¥Ñ¥Æ¥£¡¦¥á¥½¥Ã¥É¤Î¥É¥­¥å¥á¥ó¥È¡¦¥³¥á¥ó¥È¤¬¤³¤ì¤é¤Î¥á¥½¥Ã¥É¤ËÂФ·¤ÆÀ¸À®¤µ¤ì¤¿¥É¥­¥å¥á¥ó¥È¤Ë¼«Æ°Åª¤Ë¥³¥Ô¡¼¤µ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤòµ­½Ò¤Ç¤­¤ë¿·¤·¤¤\fB@defaultValue\fR¥¿¥°¤âÄɲä·¤Þ¤¹¡£
++.sp
++Îã:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjavadoc \-javafx MyClass\&.java \-d testdir\fR
++.fi
++.if n \{\
++.RE
++.\}
++.RE
+ .SS "ɸ½à¥É¥Ã¥¯¥ì¥Ã¥È¤Î¥ª¥×¥·¥ç¥ó"
+ .PP
+ \-d \fIdirectory\fR
+ .RS 4
+ \fBjavadoc\fR¥³¥Þ¥ó¥É¤¬À¸À®¤µ¤ì¤¿HTML¥Õ¥¡¥¤¥ë¤òÊݸ¤¹¤ëÀ¸À®Àè¥Ç¥£¥ì¥¯¥È¥ê¤ò»ØÄꤷ¤Þ¤¹¡£\fB\-d\fR¥ª¥×¥·¥ç¥ó¤ò¾Êά¤¹¤ë¤È¡¢¥Õ¥¡¥¤¥ë¤Ï¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ËÊݸ¤µ¤ì¤Þ¤¹¡£\fBdirectory\fR¤ÎÃͤˤϡ¢ÀäÂХǥ£¥ì¥¯¥È¥ê¡¢¤Þ¤¿¤Ï¸½ºß¤Îºî¶È¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤ÎÁêÂХǥ£¥ì¥¯¥È¥ê¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£Java SE 1\&.4¤Ç¤Ï¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤¹¤ë¤ÈÀ¸À®Àè¥Ç¥£¥ì¥¯¥È¥ê¤¬¼«Æ°Åª¤ËºîÀ®¤µ¤ì¤Þ¤¹¡£
+ .sp
+-¤¿¤È¤¨¤Ð¡¢¼¡¤ÎÎã¤Ç¤Ï¡¢\fBcom\&.mypackage\fR¥Ñ¥Ã¥±¡¼¥¸¤Î¥É¥­¥å¥á¥ó¥È¤¬À¸À®¤µ¤ì¡¢¤½¤Î·ë²Ì¤¬/user/doc/ ¥Ç¥£¥ì¥¯¥È¥ê¤ËÊݸ¤µ¤ì¤Þ¤¹¡£\fBjavadoc \-d \fR\fB/user/doc/ \fR\fBcom\&.mypackage\fR
++¤¿¤È¤¨¤Ð¡¢¼¡¤ÎÎã¤Ç¤Ï¡¢\fBcom\&.mypackage\fR¥Ñ¥Ã¥±¡¼¥¸¤Î¥É¥­¥å¥á¥ó¥È¤¬À¸À®¤µ¤ì¡¢¤½¤Î·ë²Ì¤¬/user/doc/¥Ç¥£¥ì¥¯¥È¥ê¤ËÊݸ¤µ¤ì¤Þ¤¹¡£\fBjavadoc \-d \fR\fB/user/doc/ \fR\fBcom\&.mypackage\fR
+ .RE
+ .PP
+ \-use
+ .RS 4
+-¥É¥­¥å¥á¥ó¥È²½¤µ¤ì¤ë¥¯¥é¥¹¤ª¤è¤Ó¥Ñ¥Ã¥±¡¼¥¸¤´¤È¤Ë1¤Ä¤Î»ÈÍÑ¥Ú¡¼¥¸¤òÁȤ߹þ¤ß¤Þ¤¹¡£¤³¤Î¥Ú¡¼¥¸¤Ë¤Ï¡¢¤½¤ÎÆÃÄê¤Î¥¯¥é¥¹¤Þ¤¿¤Ï¥Ñ¥Ã¥±¡¼¥¸¤ÎAPI¤ò»ÈÍѤ·¤Æ¤¤¤ë¥Ñ¥Ã¥±¡¼¥¸¡¢¥¯¥é¥¹¡¢¥á¥½¥Ã¥É¡¢¥³¥ó¥¹¥È¥é¥¯¥¿¡¢¤ª¤è¤Ó¥Õ¥£¡¼¥ë¥É¤¬µ­½Ò¤µ¤ì¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¥¯¥é¥¹C¤òÎã¤Ë¤È¤ë¤È¡¢¥¯¥é¥¹C¤ò»ÈÍѤ·¤Æ¤¤¤ë¤â¤Î¤È¤·¤Æ¤Ï¡¢C¤Î¥µ¥Ö¥¯¥é¥¹¡¢C¤È¤·¤ÆÀë¸À¤µ¤ì¤Æ¤¤¤ë¥Õ¥£¡¼¥ë¥É¡¢C¤òÊÖ¤¹¥á¥½¥Ã¥É¡¢¤ª¤è¤Ó·¿C¤Î¥Ñ¥é¥á¡¼¥¿¤ò»ý¤Ä¥á¥½¥Ã¥É¤È¥³¥ó¥¹¥È¥é¥¯¥¿¤¬¤¢¤ê¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢\fBString\fR·¿ÍѤλÈÍÑ¥Ú¡¼¥¸¤òɽ¼¨¤Ç¤­¤Þ¤¹¡£\fBjava\&.awt\&.Font\fR¥¯¥é¥¹¤Î\fBgetName\fR¥á¥½¥Ã¥É¤Ï\fBString\fR·¿¤òÌ᤹¤Î¤Ç¡¢\fBgetName\fR¥á¥½¥Ã¥É¤Ï\fBString\fR¤ò»ÈÍѤ·¡¢\fBgetName\fR¥á¥½¥Ã¥É¤¬\fBString\fRÍѤλÈÍÑ¥Ú¡¼¥¸¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£¤³¤ì¤Ï¼ÂÁõ¤Ç¤Ï¤Ê¤¯API¤Î»ÈÍѤΤߤò¥É¥­¥å¥á¥ó¥È²½¤·¤Þ¤¹¡£¥á¥½¥Ã¥É¤¬¤½¤Î¼ÂÁõ¤Ç\fBString\fR¤ò»ÈÍѤ¹¤ë¤¬¡¢°ú¿ô¤È¤·¤Æʸ»úÎó¤ò¼è¤é¤Ê¤¤¡¢¤Þ¤¿¤Ïʸ»úÎó¤òÊÖ¤µ¤Ê¤¤¾ì¹ç¡¢¤½¤ì¤Ï\fBString\fR¤Î»ÈÍѤȤϤߤʤµ¤ì¤Þ¤»¤ó¡£À¸À®¤µ¤ì¤¿»ÈÍÑ¥Ú¡¼¥¸¤Ë¥¢¥¯¥»¥¹¤¹¤ë¤Ë¤Ï¡¢¥¯¥é¥¹¤Þ¤¿¤Ï¥Ñ¥Ã¥±¡¼¥¸¤Ë°ÜÆ°¤·¡¢¥Ê¥Ó¥²¡¼¥·¥ç¥ó¡¦¥Ð¡¼¤Î\fB¥ê¥ó¥¯¤Î»ÈÍÑ\fR¤ò¥¯¥ê¥Ã¥¯¤·¤Þ¤¹¡£
++¥É¥­¥å¥á¥ó¥È²½¤µ¤ì¤ë¥¯¥é¥¹¤ª¤è¤Ó¥Ñ¥Ã¥±¡¼¥¸¤´¤È¤Ë1¤Ä¤Î¡Ö»ÈÍѡץڡ¼¥¸¤òÁȤ߹þ¤ß¤Þ¤¹¡£¤³¤Î¥Ú¡¼¥¸¤Ë¤Ï¡¢¤½¤ÎÆÃÄê¤Î¥¯¥é¥¹¤Þ¤¿¤Ï¥Ñ¥Ã¥±¡¼¥¸¤ÎAPI¤ò»ÈÍѤ·¤Æ¤¤¤ë¥Ñ¥Ã¥±¡¼¥¸¡¢¥¯¥é¥¹¡¢¥á¥½¥Ã¥É¡¢¥³¥ó¥¹¥È¥é¥¯¥¿¡¢¤ª¤è¤Ó¥Õ¥£¡¼¥ë¥É¤¬µ­½Ò¤µ¤ì¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¥¯¥é¥¹C¤òÎã¤Ë¤È¤ë¤È¡¢¥¯¥é¥¹C¤ò»ÈÍѤ·¤Æ¤¤¤ë¤â¤Î¤È¤·¤Æ¤Ï¡¢C¤Î¥µ¥Ö¥¯¥é¥¹¡¢C¤È¤·¤ÆÀë¸À¤µ¤ì¤Æ¤¤¤ë¥Õ¥£¡¼¥ë¥É¡¢C¤òÊÖ¤¹¥á¥½¥Ã¥É¡¢¤ª¤è¤Ó·¿C¤Î¥Ñ¥é¥á¡¼¥¿¤ò»ý¤Ä¥á¥½¥Ã¥É¤È¥³¥ó¥¹¥È¥é¥¯¥¿¤¬¤¢¤ê¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢\fBString\fR·¿ÍѤΡֻÈÍѡץڡ¼¥¸¤òɽ¼¨¤Ç¤­¤Þ¤¹¡£\fBjava\&.awt\&.Font\fR¥¯¥é¥¹¤Î\fBgetName\fR¥á¥½¥Ã¥É¤Ï\fBString\fR·¿¤òÌ᤹¤Î¤Ç¡¢\fBgetName\fR¥á¥½¥Ã¥É¤Ï\fBString\fR¤ò»ÈÍѤ·¡¢\fBgetName\fR¥á¥½¥Ã¥É¤¬\fBString\fRÍѤΡֻÈÍѡץڡ¼¥¸¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£¤³¤ì¤Ï¼ÂÁõ¤Ç¤Ï¤Ê¤¯API¤Î»ÈÍѤΤߤò¥É¥­¥å¥á¥ó¥È²½¤·¤Þ¤¹¡£¥á¥½¥Ã¥É¤¬¤½¤Î¼ÂÁõ¤Ç\fBString\fR¤ò»ÈÍѤ¹¤ë¤¬¡¢°ú¿ô¤È¤·¤Æʸ»úÎó¤ò¼è¤é¤Ê¤¤¡¢¤Þ¤¿¤Ïʸ»úÎó¤òÊÖ¤µ¤Ê¤¤¾ì¹ç¡¢¤½¤ì¤Ï\fBString\fR¤Î»ÈÍѤȤϤߤʤµ¤ì¤Þ¤»¤ó¡£À¸À®¤µ¤ì¤¿¡Ö»ÈÍѡץڡ¼¥¸¤Ë¥¢¥¯¥»¥¹¤¹¤ë¤Ë¤Ï¡¢¥¯¥é¥¹¤Þ¤¿¤Ï¥Ñ¥Ã¥±¡¼¥¸¤Ë°ÜÆ°¤·¡¢¥Ê¥Ó¥²¡¼¥·¥ç¥ó¡¦¥Ð¡¼¤Î\fB¥ê¥ó¥¯¤Î»ÈÍÑ\fR¤ò¥¯¥ê¥Ã¥¯¤·¤Þ¤¹¡£
+ .RE
+ .PP
+ \-version
+@@ -2847,9 +3531,7 @@
+ .PP
+ ³°ÉôAPI¥É¥­¥å¥á¥ó¥È¤Ø¤ÎÀäÂÐURL¤ò»ÈÍѤ¹¤ë¾ì¹ç(¤½¤ÎURL¤ËÀܳ¤·¡¢Æɼè¤ê¤ò¹Ô¤¦¤³¤È¤¬¥·¥§¥ë¤Ë¤è¤Ã¤Æµö²Ä¤µ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç)¤Ï\fB\-linkoffline\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Þ¤¹¡£¤³¤Î¤è¤¦¤Ê¾õ¶·¤Ï¡¢¥Õ¥¡¥¤¥¢¥¦¥©¡¼¥ë¤ÎÆ⦤«¤é¥Õ¥¡¥¤¥¢¥¦¥©¡¼¥ë¤Î³°Â¦¤Ë¤¢¤ë¥É¥­¥å¥á¥ó¥È¤Ë¥ê¥ó¥¯¤·¤è¤¦¤È¤¹¤ë¾ì¹ç¤ËȯÀ¸¤·¤Þ¤¹¡£
+ .PP
+-\fBÎã 1\fR
+-.br
+-³°Éô¥É¥­¥å¥á¥ó¥È¤Ø¤ÎÀäÂÐ¥ê¥ó¥¯
++\fBÎã 1 \fR³°Éô¥É¥­¥å¥á¥ó¥È¤Ø¤ÎÀäÂÐ¥ê¥ó¥¯
+ .RS 4
+ http://docs\&.oracle\&.com/javase/8/docs/api/index\&.html¤Ë¼¨¤¹¤è¤¦¤Ê¡¢\fBjava\&.lang\fR¡¢\fBjava\&.io\fR¤ª¤è¤Ó¤½¤Î¾¤ÎJava¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¡¦¥Ñ¥Ã¥±¡¼¥¸¤Ë¥ê¥ó¥¯¤¹¤ë¾ì¹ç¡¢¼¡¤Î¥³¥Þ¥ó¥É¤ò»ÈÍѤ·¤Þ¤¹
+ .sp
+@@ -2866,9 +3548,7 @@
+ ¤³¤Î¥³¥Þ¥ó¥É¤Ï¡¢Java SE¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¡¦¥Ñ¥Ã¥±¡¼¥¸¤Ø¤Î¥ê¥ó¥¯»ý¤Ä\fBcom\&.mypackage\fR¥Ñ¥Ã¥±¡¼¥¸¤Î¥É¥­¥å¥á¥ó¥È¤òÀ¸À®¤·¤Þ¤¹¡£À¸À®¥É¥­¥å¥á¥ó¥È¤Ë¤Ï¡¢¤¿¤È¤¨¤Ð¥¯¥é¥¹\fBtrees\fRÆâ¤Î\fBObject\fR¥¯¥é¥¹¤Ø¤Î¥ê¥ó¥¯¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£\fB\-sourcepath\fR¤ä\fB\-d\fR¤Ê¤É¤Î¾¤Î¥ª¥×¥·¥ç¥ó¤Ïɽ¼¨¤µ¤ì¤Þ¤»¤ó¡£
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-³°Éô¥É¥­¥å¥á¥ó¥È¤Ø¤ÎÁêÂÐ¥ê¥ó¥¯
++\fBÎã 2 \fR³°Éô¥É¥­¥å¥á¥ó¥È¤Ø¤ÎÁêÂÐ¥ê¥ó¥¯
+ .RS 4
+ ¤³¤ÎÎã¤Ç¤Ï¡¢2¤Ä¤Î¥Ñ¥Ã¥±¡¼¥¸¤¬¤¢¤ê¡¢¤½¤Î¥É¥­¥å¥á¥ó¥È¤Ï\fBjavadoc\fR¥³¥Þ¥ó¥É¤òÊ£¿ô²ó¼Â¹Ô¤·¤¿·ë²ÌÀ¸À®¤µ¤ì¤¿¤â¤Î¤Ç¤¹¡£¤µ¤é¤Ë¡¢¤³¤ì¤é¤Î¥É¥­¥å¥á¥ó¥È¤ÏÁêÂХѥ¹¤Çʬ³ä¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¥Ñ¥Ã¥±¡¼¥¸¤Ï¡¢API¤Ç¤¢¤ë\fBcom\&.apipackage\fR¤È¡¢SPI(¥µ¡¼¥Ó¥¹¡¦¥×¥í¥Ð¥¤¥À¡¦¥¤¥ó¥¿¥Õ¥§¡¼¥¹)¤Ç¤¢¤ëc\fBom\&.spipackage\fR¤Ç¤¹¡£¥É¥­¥å¥á¥ó¥È¤Î³ÊǼÀè¤Ï¡¢docs/api/com/apipackage¤Èdocs/spi/com/spipackage¤Ç¤¹¡£API¥Ñ¥Ã¥±¡¼¥¸¤Î¥É¥­¥å¥á¥ó¥È¤Ï¤¹¤Ç¤ËÀ¸À®¤µ¤ì¤Æ¤¤¤Æ¡¢docs¤¬¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¢¤ë¾ì¹ç¡¢API¥É¥­¥å¥á¥ó¥È¤Ø¤Î¥ê¥ó¥¯¤ò»ý¤ÄSPI¥Ñ¥Ã¥±¡¼¥¸¤ò¥É¥­¥å¥á¥ó¥È²½¤¹¤ë¤Ë¤Ï¡¢¼¡¤Î¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Þ¤¹¡£\fBjavadoc \-d \&./spi \-link \&.\&./api com\&.spipackage\fR
+ .sp
+@@ -3034,7 +3714,7 @@
+ .PP
+ ¥É¥­¥å¥á¥ó¥È¤Î¹¹¿·
+ .PP
+-¥×¥í¥¸¥§¥¯¥È¤Ë²¿½½¤Þ¤¿¤Ï²¿É´¤Î¥Ñ¥Ã¥±¡¼¥¸¤¬´Þ¤Þ¤ì¤ë¾ì¹ç¤Ë¤â¡¢\fB\-linkoffline\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤǤ­¤Þ¤¹¡£¥½¡¼¥¹¡¦¥Ä¥ê¡¼Á´ÂΤǤ¹¤Ç¤Ë\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤¿¤³¤È¤¬¤¢¤ë¾ì¹ç¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤Ë¤ï¤º¤«¤ÊÊѹ¹¤ò¿×®¤Ë²Ã¤¨¡¢¥½¡¼¥¹¡¦¥Ä¥ê¡¼¤Î°ìÉô¤Ç\fBjavadoc\fR¥³¥Þ¥ó¥É¤òºÆ¼Â¹Ô¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£2²óÌܤμ¹Ԥϡ¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤òÊѹ¹¤·¡¢Àë¸À¤ÏÊѹ¹¤·¤Ê¤¤¾ì¹ç¤Ë¤Î¤ßÀµ¤·¤¯½èÍý¤µ¤ì¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¥½¡¼¥¹¡¦¥³¡¼¥É¤ËÂФ·¤ÆÀë¸À¤òÄɲᢺï½ü¡¢¤Þ¤¿¤ÏÊѹ¹¤·¤¿¾ì¹ç¤Ï¡¢º÷°ú¡¢¥Ñ¥Ã¥±¡¼¥¸¡¦¥Ä¥ê¡¼¡¢·Ñ¾µ¤µ¤ì¤ë¥á¥ó¥Ð¡¼¤Î¥ê¥¹¥È¡¢»ÈÍÑ¥Ú¡¼¥¸¤Ê¤É¤Î¾ì½ê¤Ç¡¢¥ê¥ó¥¯¤¬²õ¤ì¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£
++¥×¥í¥¸¥§¥¯¥È¤Ë²¿½½¤Þ¤¿¤Ï²¿É´¤Î¥Ñ¥Ã¥±¡¼¥¸¤¬´Þ¤Þ¤ì¤ë¾ì¹ç¤Ë¤â¡¢\fB\-linkoffline\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤǤ­¤Þ¤¹¡£¥½¡¼¥¹¡¦¥Ä¥ê¡¼Á´ÂΤǤ¹¤Ç¤Ë\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤¿¤³¤È¤¬¤¢¤ë¾ì¹ç¡¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤Ë¤ï¤º¤«¤ÊÊѹ¹¤ò¿×®¤Ë²Ã¤¨¡¢¥½¡¼¥¹¡¦¥Ä¥ê¡¼¤Î°ìÉô¤Ç\fBjavadoc\fR¥³¥Þ¥ó¥É¤òºÆ¼Â¹Ô¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£2²óÌܤμ¹Ԥϡ¢¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥³¥á¥ó¥È¤òÊѹ¹¤·¡¢Àë¸À¤ÏÊѹ¹¤·¤Ê¤¤¾ì¹ç¤Ë¤Î¤ßÀµ¤·¤¯½èÍý¤µ¤ì¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¥½¡¼¥¹¡¦¥³¡¼¥É¤ËÂФ·¤ÆÀë¸À¤òÄɲᢺï½ü¡¢¤Þ¤¿¤ÏÊѹ¹¤·¤¿¾ì¹ç¤Ï¡¢º÷°ú¡¢¥Ñ¥Ã¥±¡¼¥¸¡¦¥Ä¥ê¡¼¡¢·Ñ¾µ¤µ¤ì¤ë¥á¥ó¥Ð¡¼¤Î¥ê¥¹¥È¡¢¡Ö»ÈÍѡץڡ¼¥¸¤Ê¤É¤Î¾ì½ê¤Ç¡¢¥ê¥ó¥¯¤¬²õ¤ì¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£
+ .PP
+ ¤Þ¤º¡¢¤³¤Î¿·¤·¤¤¾®µ¬ÌϤʼ¹ԤǻÈÍѤ¹¤ë¡¢¿·¤·¤¤À¸À®Àè¥Ç¥£¥ì¥¯¥È¥ê(update¤Ê¤É)¤òºîÀ®¤·¤Þ¤¹¡£¤³¤ÎÎã¤Ç¤Ï¡¢¸µ¤ÎÀ¸À®Àè¥Ç¥£¥ì¥¯¥È¥ê¤Î̾Á°¤Ïhtml¤Ç¤¹¡£ºÇ¤âñ½ã¤ÊÎã¤Ç¤Ï¡¢html¥Ç¥£¥ì¥¯¥È¥ê¤Î¿Æ¥Ç¥£¥ì¥¯¥È¥ê¤Ë°ÜÆ°¤·¤Þ¤¹¡£\fB\-linkoffline\fR¥ª¥×¥·¥ç¥ó¤ÎÂè1°ú¿ô¤Ë¥«¥ì¥ó¥È¡¦¥Ç¥£¥ì¥¯¥È¥ê(\&.)¤òÀßÄꤷ¡¢Âè2°ú¿ô¤Ëpackage\-list¤¬¸¡º÷¤µ¤ì¤ëhtml¤Ø¤ÎÁêÂХѥ¹¤òÀßÄꤷ¡¢¹¹¿·¤¹¤ë¥Ñ¥Ã¥±¡¼¥¸¤Î¥Ñ¥Ã¥±¡¼¥¸Ì¾¤Î¤ß¤òÅϤ·¤Þ¤¹¡£
+ .sp
+@@ -3053,7 +3733,7 @@
+ .PP
+ \-linksource
+ .RS 4
+-³Æ¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë(¹ÔÈÖ¹æÉÕ¤­)¤ÎHTML¥Ð¡¼¥¸¥ç¥ó¤òºîÀ®¤·¡¢É¸½àHTML¥É¥­¥å¥á¥ó¥È¤«¤é¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Ø¤Î¥ê¥ó¥¯¤òÄɲä·¤Þ¤¹¡£¥ê¥ó¥¯¤Ï¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ëÆâ¤ËÀë¸À¤µ¤ì¤Æ¤¤¤ë¥¯¥é¥¹¡¢¥¤¥ó¥¿¥Õ¥§¡¼¥¹¡¢¥³¥ó¥¹¥È¥é¥¯¥¿¡¢¥á¥½¥Ã¥É¡¢¥Õ¥£¡¼¥ë¥É¤ËÂФ·¤ÆºîÀ®¤µ¤ì¤Þ¤¹¡£¤½¤¦¤Ç¤Ê¤¤¾ì¹ç¡¢¤¿¤È¤¨¤Ð¥Ç¥Õ¥©¥ë¥È¡¦¥³¥ó¥¹¥È¥é¥¯¥¿¤äÀ¸À®¤µ¤ì¤¿¥¯¥é¥¹¤ËÂФ·¤Æ¤Ï¡¢¥ê¥ó¥¯¤ÏºîÀ®¤µ¤ì¤Þ¤»¤ó¡£
++³Æ¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë(¹ÔÈÖ¹æÉÕ¤­)¤ÎHTML¥Ð¡¼¥¸¥ç¥ó¤òºîÀ®¤·¡¢É¸½àHTML¥É¥­¥å¥á¥ó¥È¤«¤é¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Ø¤Î¥ê¥ó¥¯¤òÄɲä·¤Þ¤¹¡£¥ê¥ó¥¯¤Ï¡¢¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ëÆâ¤ËÀë¸À¤µ¤ì¤Æ¤¤¤ë¥¯¥é¥¹¡¢¥¤¥ó¥¿¥Õ¥§¡¼¥¹¡¢¥³¥ó¥¹¥È¥é¥¯¥¿¡¢¥á¥½¥Ã¥É¡¢¥Õ¥£¡¼¥ë¥É¤ËÂФ·¤ÆºîÀ®¤µ¤ì¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¡¦¥³¥ó¥¹¥È¥é¥¯¥¿¡¢À¸À®¤µ¤ì¤¿¥¯¥é¥¹¤Ê¤É¤ËÂФ·¤Æ¤ÏºîÀ®¤µ¤ì¤Þ¤»¤ó¡£
+ .sp
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢\fB\-public\fR¡¢\fB\-package\fR¡¢\fB\-protected\fR¤ª¤è¤Ó\fB\-private\fR¤Î³Æ¥ª¥×¥·¥ç¥ó¤È¤Ï´Ø·¸¤Ê¤¯¡¢Èó¸ø³«¤Î¥¯¥é¥¹¡¢¥Õ¥£¡¼¥ë¥É¡¢Èó¸ø³«¤Î¥á¥½¥Ã¥É¤ÎËÜÂΤò¤Ï¤¸¤á¤È¤¹¤ëÁȤ߹þ¤Þ¤ì¤¿¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ëÆâ¤Î¤¹¤Ù¤Æ¤ÎÈó¸ø³«¼ÂÁõ¤Î¾ÜºÙ¤ò¸ø³«¤·¤Þ¤¹¡£\fB\-private\fR¥ª¥×¥·¥ç¥ó¤â¤¢¤ï¤»¤Æ»ØÄꤷ¤Ê¤¤¤«¤®¤ê¡¢Èó¸ø³«¤Î¥¯¥é¥¹¤ä¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤Î°ìÉô¤Ë¤Ï¡¢¥ê¥ó¥¯¤ò²ð¤·¤Æ¥¢¥¯¥»¥¹¤Ç¤­¤Ê¤¤¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£
+ .sp
+@@ -3342,7 +4022,7 @@
+ .sp
+ ɸ½à¥¿¥°¤Ï¡¢ºÇ½é¡¢¥Ç¥Õ¥©¥ë¥È¤Î½ç½ø¤Ç¥ê¥¹¥ÈÆâ¤ËÆâÉôŪ¤Ë³ÊǼ¤µ¤ì¤Þ¤¹¡£\fB\-tag\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤È¡¢¤½¤ì¤é¤Î¥¿¥°¤Ï¤³¤Î¥ê¥¹¥È¤ËÄɲ䵤ì¤Þ¤¹¡£É¸½à¥¿¥°¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Î°ÌÃÖ¤«¤é°ÜÆ°¤µ¤ì¤Þ¤¹¡£¤½¤Î¤¿¤á¡¢É¸½à¥¿¥°¤Î\fB\-tag\fR¥ª¥×¥·¥ç¥ó¤ò¾Êά¤¹¤ë¤È¡¢¤½¤ì¤Ï¥Ç¥Õ¥©¥ë¥È¤Î°ÌÃÖ¤ËÇÛÃÖ¤µ¤ì¤¿¤Þ¤Þ¤Ë¤Ê¤ê¤Þ¤¹¡£
+ .sp
+-\fB¶¥¹ç¤Î²óÈò\fR: ¸ÇÍ­¤Î̾Á°¶õ´Ö¤òºîÀ®¤¹¤ë¤Ë¤Ï¡¢¥Ñ¥Ã¥±¡¼¥¸¤Ë»ÈÍѤµ¤ì¤Æ¤¤¤ë\fBcom\&.mycompany\&.todo\fR¤È¤¤¤¦Ì¾Á°¤Î¤è¤¦¤Ë¡¢¥É¥Ã¥È¤Ç¶èÀÚ¤é¤ì¤¿Ì¾Á°¤ò»ÈÍѤ·¤Þ¤¹¡£Oracle¤Ï¡¢º£¸å¤â̾Á°¤Ë¥É¥Ã¥È¤ò´Þ¤Þ¤Ê¤¤É¸½à¥¿¥°¤òºîÀ®¤·¤Þ¤¹¡£¥æ¡¼¥¶¡¼¤¬ºîÀ®¤·¤¿¥¿¥°¤Ï¡¢Oracle¤¬ÄêµÁ¤¹¤ëƱ¤¸Ì¾Á°¤Î¥¿¥°¤ÎÆ°ºî¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Þ¤¹¡£\fB@todo\fR¤È¤¤¤¦Ì¾Á°¤Î¥¿¥°¤Þ¤¿¤Ï¥¿¥°¥ì¥Ã¥È¤ò¥æ¡¼¥¶¡¼¤¬ºîÀ®¤·¤¿¾ì¹ç¡¢¤½¤Î¸å¤ËOracle¤¬Æ±¤¸Ì¾Á°¤Îɸ½à¥¿¥°¤òºîÀ®¤·¤Æ¤â¡¢¤½¤Î¥¿¥°¤Þ¤¿¤Ï¥¿¥°¥ì¥Ã¥È¤Ï¾ï¤Ë¥æ¡¼¥¶¡¼¤¬ÄêµÁ¤·¤¿¤Î¤ÈƱ¤¸Æ°ºî¤òÊÝ»ý¤·¤Þ¤¹¡£
++\fB¶¥¹ç¤Î²óÈò\fR: ¸ÇÍ­¤Î̾Á°¶õ´Ö¤òºîÀ®¤¹¤ë¾ì¹ç¡¢¥Ñ¥Ã¥±¡¼¥¸¤Ë»ÈÍѤµ¤ì¤Æ¤¤¤ë\fBcom\&.mycompany\&.todo\fR¤Î¤è¤¦¤Ê¥É¥Ã¥È¤Ç¶èÀÚ¤ê¤Î̿̾µ¬Â§¤ò»ÈÍѤǤ­¤Þ¤¹¡£Oracle¤Ï¡¢º£¸å¤â̾Á°¤Ë¥É¥Ã¥È¤ò´Þ¤Þ¤Ê¤¤É¸½à¥¿¥°¤òºîÀ®¤·¤Þ¤¹¡£¥æ¡¼¥¶¡¼¤¬ºîÀ®¤·¤¿¥¿¥°¤Ï¡¢Oracle¤¬ÄêµÁ¤¹¤ëƱ¤¸Ì¾Á°¤Î¥¿¥°¤ÎÆ°ºî¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Þ¤¹¡£\fB@todo\fR¤È¤¤¤¦Ì¾Á°¤Î¥¿¥°¤Þ¤¿¤Ï¥¿¥°¥ì¥Ã¥È¤ò¥æ¡¼¥¶¡¼¤¬ºîÀ®¤·¤¿¾ì¹ç¡¢¤½¤Î¸å¤ËOracle¤¬Æ±¤¸Ì¾Á°¤Îɸ½à¥¿¥°¤òºîÀ®¤·¤Æ¤â¡¢¤½¤Î¥¿¥°¤Þ¤¿¤Ï¥¿¥°¥ì¥Ã¥È¤Ï¾ï¤Ë¥æ¡¼¥¶¡¼¤¬ÄêµÁ¤·¤¿¤Î¤ÈƱ¤¸Æ°ºî¤òÊÝ»ý¤·¤Þ¤¹¡£
+ .sp
+ \fBÃí¼ávs\&. Javadoc¥¿¥°\fR: °ìÈ̤ˡ¢Äɲ乤ëɬÍפΤ¢¤ë¥Þ¡¼¥¯¥¢¥Ã¥×¤¬¡¢¥É¥­¥å¥á¥ó¥È¤Ë±Æ¶Á¤òÍ¿¤¨¤¿¤ê¥É¥­¥å¥á¥ó¥È¤òÀ¸À®¤·¤¿¤ê¤¹¤ë¤¿¤á¤Î¤â¤Î¤Ç¤¢¤ë¾ì¹ç¡¢¤½¤Î¥Þ¡¼¥¯¥¢¥Ã¥×¤ÏJavadoc¥¿¥°¤Ë¤·¤Þ¤¹¡£¤½¤ì°Ê³°¤Î¾ì¹ç¤ÏÃí¼á¤Ë¤·¤Þ¤¹¡£Javadoc¥Ä¡¼¥ë¤Ç¤ÎDoc¥³¥á¥ó¥È¤Îµ­½ÒÊýË¡¤Î¥«¥¹¥¿¥à¡¦¥¿¥°¤ÈÃí¼á¤Ë´Ø¤¹¤ë¹à
+ (http://www\&.oracle\&.com/technetwork/java/javase/documentation/index\-137868\&.html#annotations)¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+@@ -3428,16 +4108,12 @@
+ .PP
+ \fBjavadoc\fR¤ò¼Â¹Ô¤¹¤ë¤È¤­¤Ë¡¢³Æ°ú¿ô¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤È¥Õ¥¡¥¤¥ë̾¤ÎÀèƬ¤Ë@ʸ»ú¤òÉÕ¤±¤ÆÅϤ·¤Þ¤¹¡£\fBjavadoc\fR¥³¥Þ¥ó¥É¤Ï¡¢¥¢¥Ã¥È¥Þ¡¼¥¯(@)ʸ»ú¤Ç»Ï¤Þ¤ë°ú¿ô¤ò¸«¤Ä¤±¤ë¤È¡¢¤½¤Î¥Õ¥¡¥¤¥ë¤ÎÆâÍƤòŸ³«¤·¤Æ°ú¿ô¥ê¥¹¥È¤ËÁÞÆþ¤·¤Þ¤¹¡£
+ .PP
+-\fBÎã 1\fR
+-.br
+-ñ°ì¤Î°ú¿ô¥Õ¥¡¥¤¥ë
++\fBÎã 1 \fRñ°ì¤Î°ú¿ô¥Õ¥¡¥¤¥ë
+ .RS 4
+ \fBargfile\fR¤È¤¤¤¦Ì¾Á°¤Î1¤Ä¤Î°ú¿ô¥Õ¥¡¥¤¥ë¤ò»ÈÍѤ·¤Æ¡¢¤¹¤Ù¤Æ¤Î\fBjavadoc\fR¥³¥Þ¥ó¥É°ú¿ô¤òÊÝ»ý¤Ç¤­¤Þ¤¹¡£\fBjavadoc @argfile\fR¼¡¤ÎÎã¤Ë¼¨¤¹¤è¤¦¤Ë¡¢¤³¤Î°ú¿ô¥Õ¥¡¥¤¥ë¤Ë¤ÏξÊý¤Î¥Õ¥¡¥¤¥ë¤ÎÆâÍƤ¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-2¤Ä¤Î°ú¿ô¥Õ¥¡¥¤¥ë
++\fBÎã 2 \fR2¤Ä¤Î°ú¿ô¥Õ¥¡¥¤¥ë
+ .RS 4
+ ¼¡¤Î¤è¤¦¤Ë¡¢2¤Ä¤Î°ú¿ô¥Õ¥¡¥¤¥ë¤òºîÀ®¤Ç¤­¤Þ¤¹¡£\fBjavadoc\fR¥³¥Þ¥ó¥É¤Î¥ª¥×¥·¥ç¥óÍѤË1¤Ä¡¢¥Ñ¥Ã¥±¡¼¥¸Ì¾¤Þ¤¿¤Ï¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë̾ÍѤË1¤Ä¤Ç¤¹¡£¼¡¤Î¥ê¥¹¥È¤Ç¤Ï¹Ô·Ñ³ʸ»ú¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤»¤ó¡£
+ .sp
+@@ -3490,9 +4166,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 3\fR
+-.br
+-¥Ñ¥¹¤ò»ÈÍѤ·¤¿°ú¿ô¥Õ¥¡¥¤¥ë
++\fBÎã 3 \fR¥Ñ¥¹¤ò»ÈÍѤ·¤¿°ú¿ô¥Õ¥¡¥¤¥ë
+ .RS 4
+ °ú¿ô¥Õ¥¡¥¤¥ë¤Ï¥Ñ¥¹¤ò»ØÄê¤Ç¤­¤Þ¤¹¤¬¡¢¥Õ¥¡¥¤¥ëÆâ¤Î¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë̾¤Ï¡¢(\fBpath1\fR¤ä\fBpath2\fR¤Ç¤Ï¤Ê¤¯)¼¡¤Î¤è¤¦¤Ë¸½ºß¤Îºî¶È¥Ç¥£¥ì¥¯¥È¥ê¤ËÁêÂÐŪ¤È¤Ê¤ê¤Þ¤¹¡£
+ .sp
+@@ -3508,9 +4182,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 4\fR
+-.br
+-¥ª¥×¥·¥ç¥ó°ú¿ô
++\fBÎã 4 \fR¥ª¥×¥·¥ç¥ó°ú¿ô
+ .RS 4
+ ¼¡¤Ë¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤Î¥ª¥×¥·¥ç¥ó¤ËÂФ¹¤ë°ú¿ô¤ò°ú¿ô¥Õ¥¡¥¤¥ë¤Ë³ÊǼ¤¹¤ëÎã¤ò¼¨¤·¤Þ¤¹¡£Ä¹¤¤°ú¿ô¤ò»ØÄê¤Ç¤­¤ë¤Î¤Ç¡¢\fB\-bottom\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Þ¤¹¡£¼¡¤Î¤è¤¦¤Ê¥Æ¥­¥¹¥È°ú¿ô¤ò´Þ¤à¡¢bottom¤È¤¤¤¦Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤òºîÀ®¤Ç¤­¤Þ¤¹¡£
+ .sp
+@@ -3557,12 +4229,9 @@
+ .PP
+ ¥Ç¥£¥ì¥¯¥È¥ê¤ÎÊѹ¹(\fBcd\fR¥³¥Þ¥ó¥É¤ò»ÈÍÑ)¤Þ¤¿¤Ï\fB\-sourcepath\fR¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤Ç¤­¤Þ¤¹¡£¼¡¤ÎÎã¤ÇξÊý¤ÎÁªÂò»è¤ò¼¨¤·¤Þ¤¹¡£
+ .PP
+-\fBÎã 1\fR
+-.br
+-1¤Ä°Ê¾å¤Î¥Ñ¥Ã¥±¡¼¥¸¤«¤éºÆµ¢Åª¤Ë¼Â¹Ô
+-.RS 4
+-¤³¤ÎÎã¤Ç¤Ï\fBjavadoc\fR¥³¥Þ¥ó¥É¤¬Ç¤°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¼Â¹Ô¤Ç¤­¤ë¤è¤¦¤Ë¡¢\fB\-sourcepath\fR¤ò»ÈÍѤ·¡¢ºÆµ¢Åª½èÍý¤Î¤¿¤á¤Ë\fB\-subpackages\fR
+-(1\&.4¤Î¿·¥ª¥×¥·¥ç¥ó)¤ò»ÈÍѤ·¤Þ¤¹¡£¤³¤ì¤Ï¡¢java¥Ç¥£¥ì¥¯¥È¥ê¤Î¥µ¥Ö¥Ñ¥Ã¥±¡¼¥¸¤ò¤¿¤É¤ê¤Þ¤¹¤¬¡¢\fBjava\&.net\fR¤È\fBjava\&.lang\fR¤ò¥ë¡¼¥È¤Ë»ý¤Ä¥Ñ¥Ã¥±¡¼¥¸¤Ï½ü³°¤µ¤ì¤Þ¤¹¡£\fBjava\&.lang\fR¤Î¥µ¥Ö¥Ñ¥Ã¥±¡¼¥¸¤Ç¤¢¤ë\fBjava\&.lang\&.ref\fR¤¬½ü³°¤µ¤ì¤ëÅÀ¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤Þ¤¿¡¢Â¾¤Î¥Ñ¥Ã¥±¡¼¥¸¡¦¥Ä¥ê¡¼¤ò²¼Êý¤Ë¤¿¤É¤ë¤Ë¤Ï¡¢\fBjava:javax:org\&.xml\&.sax\fR¤Î¤è¤¦¤Ë¡¢¤½¤ì¤é¤Î¥Ñ¥Ã¥±¡¼¥¸¤Î̾Á°¤ò\fB\-subpackages\fR¤Î°ú¿ô¤ËÄɲä·¤Þ¤¹¡£
++\fBÎã 1 \fR1¤Ä°Ê¾å¤Î¥Ñ¥Ã¥±¡¼¥¸¤«¤éºÆµ¢Åª¤Ë¼Â¹Ô
++.RS 4
++¤³¤ÎÎã¤Ç¤Ï\fBjavadoc\fR¥³¥Þ¥ó¥É¤¬Ç¤°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¼Â¹Ô¤Ç¤­¤ë¤è¤¦¤Ë¡¢\fB\-sourcepath\fR¤ò»ÈÍѤ·¡¢ºÆµ¢Åª½èÍý¤Î¤¿¤á¤Ë\fB\-subpackages\fR(1\&.4¤Î¿·¥ª¥×¥·¥ç¥ó)¤ò»ÈÍѤ·¤Þ¤¹¡£¤³¤ì¤Ï¡¢java¥Ç¥£¥ì¥¯¥È¥ê¤Î¥µ¥Ö¥Ñ¥Ã¥±¡¼¥¸¤ò¤¿¤É¤ê¤Þ¤¹¤¬¡¢\fBjava\&.net\fR¤È\fBjava\&.lang\fR¤ò¥ë¡¼¥È¤Ë»ý¤Ä¥Ñ¥Ã¥±¡¼¥¸¤Ï½ü³°¤µ¤ì¤Þ¤¹¡£\fBjava\&.lang\fR¤Î¥µ¥Ö¥Ñ¥Ã¥±¡¼¥¸¤Ç¤¢¤ë\fBjava\&.lang\&.ref\fR¤¬½ü³°¤µ¤ì¤ëÅÀ¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤Þ¤¿¡¢Â¾¤Î¥Ñ¥Ã¥±¡¼¥¸¡¦¥Ä¥ê¡¼¤ò²¼Êý¤Ë¤¿¤É¤ë¤Ë¤Ï¡¢\fBjava:javax:org\&.xml\&.sax\fR¤Î¤è¤¦¤Ë¡¢¤½¤ì¤é¤Î¥Ñ¥Ã¥±¡¼¥¸¤Î̾Á°¤ò\fB\-subpackages\fR¤Î°ú¿ô¤ËÄɲä·¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+@@ -3576,9 +4245,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-¥ë¡¼¥È¤Ø¤Î°ÜÆ°¤ª¤è¤ÓÌÀ¼¨Åª¤Ê¥Ñ¥Ã¥±¡¼¥¸¤Î¼Â¹Ô
++\fBÎã 2 \fR¥ë¡¼¥È¤Ø¤Î°ÜÆ°¤ª¤è¤ÓÌÀ¼¨Åª¤Ê¥Ñ¥Ã¥±¡¼¥¸¤Î¼Â¹Ô
+ .RS 4
+ ´°Á´½¤¾þ¤µ¤ì¤¿¥Ñ¥Ã¥±¡¼¥¸¤Î¿Æ¥Ç¥£¥ì¥¯¥È¥ê¤Ë°ÜÆ°¤·¤Þ¤¹¡£¼¡¤Ë¡¢¥É¥­¥å¥á¥ó¥È²½¤¹¤ë1¤Ä°Ê¾å¤Î¥Ñ¥Ã¥±¡¼¥¸¤Î̾Á°¤ò»ØÄꤷ¤Æ\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Þ¤¹¡£
+ .sp
+@@ -3596,9 +4263,7 @@
+ ¤Þ¤¿¡¢Â¾¤Î¥Ñ¥Ã¥±¡¼¥¸¡¦¥Ä¥ê¡¼¤ò²¼Êý¤Ë¤¿¤É¤ë¤Ë¤Ï¡¢j\fBava:javax:org\&.xml\&.sax\fR¤Î¤è¤¦¤Ë¡¢¤½¤ì¤é¤Î¥Ñ¥Ã¥±¡¼¥¸¤Î̾Á°¤ò\fB\-subpackages\fR¤Î°ú¿ô¤ËÄɲä·¤Þ¤¹¡£
+ .RE
+ .PP
+-\fBÎã 3\fR
+-.br
+-1¤Ä¤Î¥Ä¥ê¡¼¤ÎÌÀ¼¨Åª¤Ê¥Ñ¥Ã¥±¡¼¥¸¤ÎǤ°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¼Â¹Ô
++\fBÎã 3 \fR1¤Ä¤Î¥Ä¥ê¡¼¤ÎÌÀ¼¨Åª¤Ê¥Ñ¥Ã¥±¡¼¥¸¤ÎǤ°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¼Â¹Ô
+ .RS 4
+ ¤³¤Î¾ì¹ç¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤¬¤É¤³¤«¤ÏÌäÂê¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¡¢ºÇ¾å°Ì¥Ñ¥Ã¥±¡¼¥¸¤Î¿Æ¥Ç¥£¥ì¥¯¥È¥ê¤ò»ØÄꤷ¤Æ\fB\-sourcepath\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Þ¤¹¡£¥É¥­¥å¥á¥ó¥È²½¤¹¤ë1¤Ä°Ê¾å¤Î¥Ñ¥Ã¥±¡¼¥¸¤Î̾Á°¤ò»ØÄꤷ¤Þ¤¹¡£
+ .sp
+@@ -3614,9 +4279,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 4\fR
+-.br
+-Ê£¿ô¤Î¥Ä¥ê¡¼¤ÎÌÀ¼¨Åª¤Ê¥Ñ¥Ã¥±¡¼¥¸¤ÎǤ°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¼Â¹Ô
++\fBÎã 4 \fRÊ£¿ô¤Î¥Ä¥ê¡¼¤ÎÌÀ¼¨Åª¤Ê¥Ñ¥Ã¥±¡¼¥¸¤ÎǤ°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¼Â¹Ô
+ .RS 4
+ \fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¡¢³Æ¥Ä¥ê¡¼¤Î¥ë¡¼¥È¤Ø¤Î¥Ñ¥¹¤Î¥³¥í¥ó¶èÀÚ¤ê¥ê¥¹¥È¤ò»ØÄꤷ¤Æ\fB\-sourcepath\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Þ¤¹¡£¥É¥­¥å¥á¥ó¥È²½¤¹¤ë1¤Ä°Ê¾å¤Î¥Ñ¥Ã¥±¡¼¥¸¤Î̾Á°¤ò»ØÄꤷ¤Þ¤¹¡£»ØÄꤷ¤¿¥Ñ¥Ã¥±¡¼¥¸¤Î¤¹¤Ù¤Æ¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤¬¡¢1¤Ä¤Î¥ë¡¼¥È¡¦¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Ë¸ºß¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¤¬¡¢¥½¡¼¥¹¡¦¥Ñ¥¹¤Ç»ØÄꤵ¤ì¤¿¾ì½ê¤Î¤É¤³¤«¤Ç¸«¤Ä¤«¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .sp
+@@ -3637,9 +4300,7 @@
+ .PP
+ ¤Þ¤¿¡¢1¤Ä°Ê¾å¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤òÅϤ·¤Æ¡¢\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£\fBjavadoc\fR¤Ï¡¢¼¡¤Î2¤Ä¤ÎÊýË¡¤Î¤¤¤º¤ì¤«¤Ç¼Â¹Ô¤Ç¤­¤Þ¤¹¡£1¤Ä¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤òÊѹ¹¤¹¤ëÊýË¡(\fBcd\fR¤ò»ÈÍÑ)¡¢¤â¤¦1¤Ä¤Ï¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Ø¤Î¥Ñ¥¹¤ò´°Á´¤Ë»ØÄꤹ¤ëÊýË¡¤Ç¤¹¡£ÁêÂХѥ¹¤Ï¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤òµ¯ÅÀ¤È¤·¤Þ¤¹¡£¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤òÅϤ¹¤È¤­¤Ï¡¢\fB\-sourcepath\fR¥ª¥×¥·¥ç¥ó¤Ï̵»ë¤µ¤ì¤Þ¤¹¡£¥¢¥¹¥¿¥ê¥¹¥¯(*)¤Î¤è¤¦¤Ê¥³¥Þ¥ó¥É¹Ô¥ï¥¤¥ë¥É¥«¡¼¥É¤ò»ÈÍѤ¹¤ë¤È¡¢¥¯¥é¥¹¤Î¥°¥ë¡¼¥×¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£
+ .PP
+-\fBÎã 1\fR
+-.br
+-¥½¡¼¥¹¡¦¥Ç¥£¥ì¥¯¥È¥ê¤ËÊѹ¹
++\fBÎã 1 \fR¥½¡¼¥¹¡¦¥Ç¥£¥ì¥¯¥È¥ê¤ËÊѹ¹
+ .RS 4
+ ¥½¡¼¥¹¤òÊÝ»ý¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤ËÊѹ¹¤·¤Þ¤¹¡£¼¡¤Ë¡¢¥É¥­¥å¥á¥ó¥È²½¤¹¤ë1¤Ä°Ê¾å¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Î̾Á°¤ò»ØÄꤷ¤Æ\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Þ¤¹¡£
+ .sp
+@@ -3658,9 +4319,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-¥Ñ¥Ã¥±¡¼¥¸¤Î¥ë¡¼¥È¡¦¥Ç¥£¥ì¥¯¥È¥ê¤ËÊѹ¹
++\fBÎã 2 \fR¥Ñ¥Ã¥±¡¼¥¸¤Î¥ë¡¼¥È¡¦¥Ç¥£¥ì¥¯¥È¥ê¤ËÊѹ¹
+ .RS 4
+ ¤³¤ì¤Ï¡¢Æ±¤¸¥ë¡¼¥È¤«¤é¤ÎÊ̤Υµ¥Ö¥Ñ¥Ã¥±¡¼¥¸¤Î¸Ä¡¹¤Î¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¥É¥­¥å¥á¥ó¥È²½¤¹¤ë¤Î¤ËÌòΩ¤Á¤Þ¤¹¡£¥Ñ¥Ã¥±¡¼¥¸¤Î¥ë¡¼¥È¡¦¥Ç¥£¥ì¥¯¥È¥ê¤Ë°Ü¤ê¡¢³Æ¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤ò¡¢¥ë¡¼¥È¤«¤é¤Î¥Ñ¥¹¤È¤È¤â¤Ë»ØÄꤷ¤Þ¤¹¡£
+ .sp
+@@ -3677,9 +4336,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 3\fR
+-.br
+-Ǥ°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î¥Õ¥¡¥¤¥ë¤Î¥É¥­¥å¥á¥ó¥È²½
++\fBÎã 3 \fRǤ°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î¥Õ¥¡¥¤¥ë¤Î¥É¥­¥å¥á¥ó¥È²½
+ .RS 4
+ ¤³¤Î¾ì¹ç¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤¬¤É¤³¤«¤ÏÌäÂê¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¥É¥­¥å¥á¥ó¥È²½¤¹¤ë¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Ø¤ÎÀäÂХѥ¹(¤Þ¤¿¤Ï¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤ÎÁêÂХѥ¹)¤ò»ØÄꤷ¤Æ\fBjavadoc\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Þ¤¹¡£
+ .sp
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/javah.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/javah.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "javah" "1" "2013ǯ11·î21Æü" "JDK 8" "´ðËܥġ¼¥ë"
+@@ -77,7 +78,7 @@
+ .PP
+ \fBjavah\fR¥³¥Þ¥ó¥É¤Ï¡¢¥Í¥¤¥Æ¥£¥Ö¡¦¥á¥½¥Ã¥É¤ò¼ÂÁõ¤¹¤ë¤¿¤á¤ËɬÍפÊC¥Ø¥Ã¥À¡¼¤È¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤òÀ¸À®¤·¤Þ¤¹¡£ºîÀ®¤µ¤ì¤¿¥Ø¥Ã¥À¡¼¤È¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤Ï¡¢¥Í¥¤¥Æ¥£¥Ö¡¦¥½¡¼¥¹¡¦¥³¡¼¥É¤«¤é¥ª¥Ö¥¸¥§¥¯¥È¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤ò»²¾È¤¹¤ë¤¿¤á¤ËC¥×¥í¥°¥é¥à¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤Þ¤¹¡£\fB\&.h\fR¥Õ¥¡¥¤¥ë¤Ï¡¢Âбþ¤¹¤ë¥¯¥é¥¹¤È°ìÃפ¹¤ëÇÛÃÖ¤ò»ý¤Ä\fBstruct\fRÄêµÁ¤ò´Þ¤ß¤Þ¤¹¡£\fBstruct\fR¤Î¥Õ¥£¡¼¥ë¥É¤Ï¡¢¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤ËÂбþ¤·¤Þ¤¹¡£
+ .PP
+-¥Ø¥Ã¥À¡¼¡¦¥Õ¥¡¥¤¥ë¤È¤½¤ÎÃæ¤ÇÀë¸À¤µ¤ì¤ë¹½Â¤ÂΤÎ̾Á°¤Ï¥¯¥é¥¹¤Î̾Á°¤«¤éÇÉÀ¸¤·¤Þ¤¹¡£\fBjavah\fR¥³¥Þ¥ó¥É¤ËÅϤµ¤ì¤ë¥¯¥é¥¹¤¬¥Ñ¥Ã¥±¡¼¥¸¤ÎÃæ¤Ë¤¢¤ë¾ì¹ç¡¢¥Ñ¥Ã¥±¡¼¥¸Ì¾¤Ï¥Ø¥Ã¥À¡¼¡¦¥Õ¥¡¥¤¥ë̾¤È¹½Â¤ÂÎ̾¤ÎξÊý¤ÎÀèƬ¤ËÉղ䵤ì¤Þ¤¹¡£²¼Àþ(_)¤¬Ì¾Á°¤Î¶èÀÚ¤êʸ»ú¤È¤·¤Æ»ÈÍѤµ¤ì¤Þ¤¹¡£
++¥Ø¥Ã¥À¡¼¡¦¥Õ¥¡¥¤¥ë¤È¤½¤ÎÃæ¤ÇÀë¸À¤µ¤ì¤ë¹½Â¤ÂΤÎ̾Á°¤Ï¥¯¥é¥¹¤Î̾Á°¤«¤éÇÉÀ¸¤·¤Þ¤¹¡£\fBjavah\fR¥³¥Þ¥ó¥É¤ËÅϤµ¤ì¤ë¥¯¥é¥¹¤¬¥Ñ¥Ã¥±¡¼¥¸¤ÎÃæ¤Ë¤¢¤ë¾ì¹ç¡¢¥Ñ¥Ã¥±¡¼¥¸Ì¾¤Ï¥Ø¥Ã¥À¡¼¡¦¥Õ¥¡¥¤¥ë̾¤È¹½Â¤ÂÎ̾¤ÎξÊý¤ÎÀèƬ¤ËÉղ䵤ì¤Þ¤¹¡£¥¢¥ó¥À¡¼¥¹¥³¥¢(_)¤¬Ì¾Á°¤Î¶èÀÚ¤êʸ»ú¤È¤·¤Æ»ÈÍѤµ¤ì¤Þ¤¹¡£
+ .PP
+ ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï\fBjavah\fR¥³¥Þ¥ó¥É¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤Ë¥ê¥¹¥È¤µ¤ì¤ë³Æ¥¯¥é¥¹¤Î¥Ø¥Ã¥À¡¼¡¦¥Õ¥¡¥¤¥ë¤òºîÀ®¤·¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¥Õ¥¡¥¤¥ë¤òÃÖ¤­¤Þ¤¹¡£¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤òºîÀ®¤¹¤ë¤Ë¤Ï¡¢\fB\-stubs\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£1¤Ä¤Î¥Õ¥¡¥¤¥ë¤ÎÃæ¤Ë¡¢¥ê¥¹¥È¤µ¤ì¤¿¤¹¤Ù¤Æ¤Î¥¯¥é¥¹¤Î·ë²Ì¤òÏ¢·ë¤¹¤ë¤Ë¤Ï¡¢\fB\-o\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£
+ .PP
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/javap.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/javap.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "javap" "1" "2014ǯ8·î8Æü" "JDK 8" "´ðËܥġ¼¥ë"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jcmd.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jcmd.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jcmd" "1" "2013ǯ11·î21Æü" "JDK 8" "¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jconsole.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jconsole.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¢¥×¥í¥Õ¥¡¥¤¥ê¥ó¥°¡¢¥â¥Ë¥¿¥ê¥ó¥°¤ª¤è¤Ó´ÉÍý¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jconsole" "1" "2013ǯ11·î21Æü" "JDK 8" "Java¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¢¥×¥í¥Õ¥¡¥¤¥ê¥ó¥°¡¢¥â¥Ë¥¿¥ê¥ó"
+@@ -81,7 +82,7 @@
+ .RE
+ .SH "ÀâÌÀ"
+ .PP
+-\fBjconsole\fR¥³¥Þ¥ó¥É¤Ï¡¢¥í¡¼¥«¥ë¡¦¥Þ¥·¥ó¤Þ¤¿¤Ï¥ê¥â¡¼¥È¡¦¥Þ¥·¥ó¾å¤ÎJava¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤È²¾ÁÛ¥Þ¥·¥ó¤ò¥â¥Ë¥¿¡¼¤ª¤è¤Ó´ÉÍý¤¹¤ë¥°¥é¥Õ¥£¥«¥ë¡¦¥³¥ó¥½¡¼¥ë¡¦¥Ä¡¼¥ë¤òµ¯Æ°¤·¤Þ¤¹¡£
++\fBjconsole\fR¥³¥Þ¥ó¥É¤Ï¡¢¥í¡¼¥«¥ë¡¦¥Þ¥·¥ó¤Þ¤¿¤Ï¥ê¥â¡¼¥È¡¦¥Þ¥·¥ó¾å¤ÎJava¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤È²¾ÁÛ¥Þ¥·¥ó¤Î¥â¥Ë¥¿¡¼¤È´ÉÍý¤ò¹Ô¤¦¥°¥é¥Õ¥£¥«¥ë¡¦¥³¥ó¥½¡¼¥ë¡¦¥Ä¡¼¥ë¤òµ¯Æ°¤·¤Þ¤¹¡£
+ .PP
+ Windows¾å¤Ç¤Ï¡¢\fBjconsole\fR¥³¥Þ¥ó¥É¤Ï¥³¥ó¥½¡¼¥ë¡¦¥¦¥£¥ó¥É¥¦¤È´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤Þ¤»¤ó¡£¤¿¤À¤·¡¢\fBjconsole\fR¥³¥Þ¥ó¥É¤¬¼ºÇÔ¤¹¤ë¤È¡¢¥¨¥é¡¼¾ðÊó¤ò¼¨¤¹¥À¥¤¥¢¥í¥°¡¦¥Ü¥Ã¥¯¥¹¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£
+ .SH "¥ª¥×¥·¥ç¥ó"
+@@ -93,7 +94,7 @@
+ .PP
+ \-notile
+ .RS 4
+-ºÇ½é¤Ï¥¦¥£¥ó¥É¥¦¤ò¥¿¥¤¥ëɽ¼¨¤·¤Þ¤»¤ó(Ê£¿ôÀܳ¤Î¾ì¹ç)¡£
++ºÇ½é¤Ë¥¦¥£¥ó¥É¥¦¤ò¥¿¥¤¥ëɽ¼¨¤·¤Þ¤»¤ó(Ê£¿ôÀܳ¤Î¾ì¹ç)¡£
+ .RE
+ .PP
+ \-pluginpath \fIplugins\fR
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jdb.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jdb.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jdb" "1" "2013ǯ11·î21Æü" "JDK 8" "´ðËܥġ¼¥ë"
+@@ -318,7 +319,7 @@
+ .RS 4
+ JVM¤Ë\fBoption\fR¤òÅϤ·¤Þ¤¹¡£option¤Ë¤Ï¡¢Java¥¢¥×¥ê¥±¡¼¥·¥ç¥óµ¯Æ°¥Ä¡¼¥ë¤Î¥ê¥Õ¥¡¥ì¥ó¥¹¡¦¥Ú¡¼¥¸¤Ëµ­ºÜ¤µ¤ì¤Æ¤¤¤ë¥ª¥×¥·¥ç¥ó¤ò1¤Ä»ØÄꤷ¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢\fB\-J\-Xms48m\fR¤È»ØÄꤹ¤ë¤È¡¢¥¹¥¿¡¼¥È¥¢¥Ã¥×¡¦¥á¥â¥ê¡¼¤Ï48MB¤ËÀßÄꤵ¤ì¤Þ¤¹¡£java(1)¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .RE
+-.SH "¥Ç¥Ð¥Ã¥°ÂÐ¾Ý¤Î¥×¥í¥»¥¹¤ËžÁ÷¤µ¤ì¤ë¥ª¥×¥·¥ç¥ó"
++.SH "¥Ç¥Ð¥Ã¥¬¡¦¥×¥í¥»¥¹¤ËžÁ÷¤µ¤ì¤ë¥ª¥×¥·¥ç¥ó"
+ .PP
+ \-v \-verbose[:\fIclass\fR|gc|jni]
+ .RS 4
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jdeps.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jdeps.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jdeps" "1" "2013ǯ11·î21Æü" "JDK 8" "´ðËܥġ¼¥ë"
+@@ -113,7 +114,7 @@
+ .RS 4
+ ¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤Î¸¡º÷¾ì½ê¤ò»ØÄꤷ¤Þ¤¹¡£
+ .sp
+-Setting the Class Path ¤â»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
++¥¯¥é¥¹¡¦¥Ñ¥¹¤ÎÀßÄê ¤â»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ .RE
+ .PP
+ \-p <\fIpkg name\fR>
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jhat.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jhat.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jhat" "1" "2013ǯ11·î21Æü" "JDK 8" "¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jinfo.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jinfo.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jinfo" "1" "2013ǯ11·î21Æü" "JDK 8" "¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë"
+@@ -115,7 +116,7 @@
+ .RE
+ .SH "ÀâÌÀ"
+ .PP
+-\fBjinfo\fR¥³¥Þ¥ó¥É¤Ï¡¢»ØÄꤵ¤ì¤¿Java¥×¥í¥»¥¹¤ä¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï¥ê¥â¡¼¥È¡¦¥Ç¥Ð¥Ã¥°¡¦¥µ¡¼¥Ð¡¼¤ÎJava¹½À®¾ðÊó¤ò½ÐÎϤ·¤Þ¤¹¡£¹½À®¾ðÊó¤Ë¤Ï¡¢Java¥·¥¹¥Æ¥à¡¦¥×¥í¥Ñ¥Æ¥£¤ÈJava Virtual Machine (JVM)¤Î¥³¥Þ¥ó¥É¹Ô¥Õ¥é¥°¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£»ØÄꤵ¤ì¤¿¥×¥í¥»¥¹¤¬64¥Ó¥Ã¥ÈJVM¾å¤Ç¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢\fB\-J\-d64\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£¼¡¤ËÎã¤ò¼¨¤·¤Þ¤¹¡£\fBjinfo\fR
++\fBjinfo\fR¥³¥Þ¥ó¥É¤Ï¡¢»ØÄꤵ¤ì¤¿Java¥×¥í¥»¥¹¤ä¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï¥ê¥â¡¼¥È¡¦¥Ç¥Ð¥Ã¥°¡¦¥µ¡¼¥Ð¡¼¤ÎJava¹½À®¾ðÊó¤ò½ÐÎϤ·¤Þ¤¹¡£¹½À®¾ðÊó¤Ë¤Ï¡¢Java¥·¥¹¥Æ¥à¡¦¥×¥í¥Ñ¥Æ¥£¤ÈJava²¾ÁÛ¥Þ¥·¥ó(JVM)¤Î¥³¥Þ¥ó¥É¹Ô¥Õ¥é¥°¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£»ØÄꤵ¤ì¤¿¥×¥í¥»¥¹¤¬64¥Ó¥Ã¥ÈJVM¾å¤Ç¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢\fB\-J\-d64\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£¼¡¤ËÎã¤ò¼¨¤·¤Þ¤¹¡£\fBjinfo\fR
+ \fB\-J\-d64 \-sysprops pid\fR¡£
+ .PP
+ ¤³¤Î¥æ¡¼¥Æ¥£¥ê¥Æ¥£¤Ï¥µ¥Ý¡¼¥ÈÂоݳ°¤Ç¤¢¤ê¡¢¾­Íè¤ÎJDK¤Î¥ê¥ê¡¼¥¹¤Ç¤ÏÍøÍѤǤ­¤Ê¤¯¤Ê¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£\fBdbgeng\&.dll\fR¤¬Â¸ºß¤·¤Æ¤¤¤Ê¤¤Windows¥·¥¹¥Æ¥à¤Ç¤Ï¡¢Debugging Tools For Windows¤ò¥¤¥ó¥¹¥È¡¼¥ë¤·¤Ê¤¤¤È¤³¤ì¤é¤Î¥Ä¡¼¥ë¤¬Àµ¾ï¤ËÆ°ºî¤·¤Þ¤»¤ó¡£\fBPATH\fR´Ä¶­ÊÑ¿ô¤Ë¤Ï¡¢¥¿¡¼¥²¥Ã¥È¡¦¥×¥í¥»¥¹¤Ë¤è¤Ã¤Æ»ÈÍѤµ¤ì¤ëjvm\&.dll¤Î¾ì½ê¡¢¤Þ¤¿¤Ï¥¯¥é¥Ã¥·¥å¡¦¥À¥ó¥×¡¦¥Õ¥¡¥¤¥ë¤¬À¸À®¤µ¤ì¤¿¾ì½ê¤¬´Þ¤Þ¤ì¤ë¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£¤¿¤È¤¨¤Ð¡¢\fBset PATH=%JDK_HOME%\ejre\ebin\eclient;%PATH%\fR¤Ç¤¹¡£
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jjs.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jjs.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: jjs
+ .\" Language: Japanese
+-.\" Date: 2013ǯ11·î21Æü
++.\" Date: 2015ǯ3·î3Æü
+ .\" SectDesc: ´ðËܥġ¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "jjs" "1" "2013ǯ11·î21Æü" "JDK 8" "´ðËܥġ¼¥ë"
++.TH "jjs" "1" "2015ǯ3·î3Æü" "JDK 8" "´ðËܥġ¼¥ë"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -113,7 +114,7 @@
+ .PP
+ \-cp \fIpath\fR
+ .br
+-\-\-classpath \fIpath\fR
++\-classpath \fIpath\fR
+ .RS 4
+ ¥µ¥Ý¡¼¥È¤¹¤ë¥¯¥é¥¹¤Ø¤Î¥Ñ¥¹¤ò»ØÄꤷ¤Þ¤¹¡£Ê£¿ô¤Î¥Ñ¥¹¤òÀßÄꤹ¤ë¤Ë¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤ò·«¤êÊÖ¤¹¤«¡¢¤Þ¤¿¤Ï³Æ¥Ñ¥¹¤ò¥³¥í¥ó(:)¤Ç¶èÀÚ¤ê¤Þ¤¹¡£
+ .RE
+@@ -221,6 +222,11 @@
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤ò·«¤êÊÖ¤·»ÈÍѤ¹¤ë¤È¡¢Ê£¿ô¤Î\fBjava\fR¥³¥Þ¥ó¥É¡¦¥ª¥×¥·¥ç¥ó¤òÅϤ¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
+ .RE
+ .PP
++\-\-language=[es5]
++.RS 4
++ECMAScript¸À¸ì¥Ð¡¼¥¸¥ç¥ó¤ò»ØÄꤷ¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Î¥Ð¡¼¥¸¥ç¥ó¤ÏES5¤Ç¤¹¡£
++.RE
++.PP
+ \-\-lazy\-compilation
+ .RS 4
+ ¥ì¥¤¥¸¡¼¡¦¥³¡¼¥ÉÀ¸À®Àïά(¤Ä¤Þ¤ê¡¢¥¹¥¯¥ê¥×¥ÈÁ´ÂΤ¬°ìÅ٤˥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Ê¤¤)¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï»î¸³Åª¤Ê¤â¤Î¤Ç¤¹¡£
+@@ -240,13 +246,17 @@
+ .\}
+ .nf
+ \fB\-\-log=fields:finest,codegen:info\fR
+-
+ .fi
+ .if n \{\
+ .RE
+ .\}
+ .RE
+ .PP
++\-\-optimistic\-types=[true|false]
++.RS 4
++ºÆ¥³¥ó¥Ñ¥¤¥ë¤ÎºÇŬ²½¤ò²ò½ü¤·¤Æ¥ª¥×¥Æ¥£¥ß¥¹¥Æ¥£¥Ã¥¯¡¦¥¿¥¤¥×²¾Äê¤òÍ­¸ú¤Þ¤¿¤Ï̵¸ú¤Ë¤·¤Þ¤¹¡£¥ª¥×¥Æ¥£¥ß¥¹¥Æ¥£¥Ã¥¯¡¦¥¿¥¤¥×¤ò»ÈÍѤ·¤¿¼Â¹Ô¤Ë¤è¤Ã¤ÆºÇ½ªÅª¤Ê®ÅÙ¤¬¸þ¾å¤·¤Þ¤¹¤¬¡¢¥¦¥©¡¼¥à¥¢¥Ã¥×»þ´Ö¤¬Áý¤¨¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£
++.RE
++.PP
+ \-\-package=\fIname\fR
+ .RS 4
+ À¸À®¤µ¤ì¤¿¥¯¥é¥¹¡¦¥Õ¥¡¥¤¥ë¤òÄɲ乤ë¥Ñ¥Ã¥±¡¼¥¸¤ò»ØÄꤷ¤Þ¤¹¡£
+@@ -323,7 +333,7 @@
+ .br
+ \-timezone=\fIzone\fR
+ .RS 4
+-¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô¤ËÂФ·»ØÄꤷ¤¿¥¿¥¤¥à¡¦¥¾¡¼¥ó¤òÀßÄꤷ¤Þ¤¹¡£OS¤ÇÀßÄꤵ¤ì¤¿¥¿¥¤¥à¡¦¥¾¡¼¥ó¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¡¢\fBDate\fR¥ª¥Ö¥¸¥§¥¯¥È¤Ç»ÈÍѤµ¤ì¤Þ¤¹¡£
++¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô¤ËÂФ·»ØÄꤷ¤¿¥¿¥¤¥à¥¾¡¼¥ó¤òÀßÄꤷ¤Þ¤¹¡£OS¤ÇÀßÄꤵ¤ì¤¿¥¿¥¤¥à¥¾¡¼¥ó¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¡¢\fBDate\fR¥ª¥Ö¥¸¥§¥¯¥È¤Ç»ÈÍѤµ¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ \-tcs=\fIparameter\fR
+@@ -366,9 +376,7 @@
+ .RE
+ .SH "Îã"
+ .PP
+-\fBÎã 1\fR
+-.br
+-Nashorn¤ò»ÈÍѤ·¤¿¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô
++\fBÎã 1 \fRNashorn¤ò»ÈÍѤ·¤¿¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô
+ .RS 4
+ .sp
+ .if n \{\
+@@ -383,9 +391,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 2\fR
+-.br
+-ÂÐÏ÷¿¥â¡¼¥É¤Ç¤ÎNashorn¤Î¼Â¹Ô
++\fBÎã 2 \fRÂÐÏ÷¿¥â¡¼¥É¤Ç¤ÎNashorn¤Î¼Â¹Ô
+ .RS 4
+ .sp
+ .if n \{\
+@@ -404,9 +410,7 @@
+ .\}
+ .RE
+ .PP
+-\fBÎã 3\fR
+-.br
+-Nashorn¤Ø¤Î°ú¿ô¤ÎÅϤ·
++\fBÎã 3 \fRNashorn¤Ø¤Î°ú¿ô¤ÎÅϤ·
+ .RS 4
+ .sp
+ .if n \{\
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jmap.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jmap.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jmap" "1" "2013ǯ11·î21Æü" "JDK 8" "¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jps.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jps.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥â¥Ë¥¿¥ê¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jps" "1" "2013ǯ11·î21Æü" "JDK 8" "¥â¥Ë¥¿¥ê¥ó¥°¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jrunscript.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jrunscript.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥¹¥¯¥ê¥×¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jrunscript" "1" "2013ǯ11·î21Æü" "JDK 8" "¥¹¥¯¥ê¥×¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë"
+@@ -86,7 +87,7 @@
+ \-cp \fIpath\fR
+ .RS 4
+ \fB\-classpath\fR
+-\fBpath\fR¤ÈƱ¤¸¤Ç¤¹¡£
++\fIpath\fR¤ÈƱ¤¸¤Ç¤¹¡£
+ .RE
+ .PP
+ \-D\fIname\fR=\fIvalue\fR
+@@ -96,7 +97,7 @@
+ .PP
+ \-J\fIflag\fR
+ .RS 4
+-\fBflag\fR¤ò¡¢\fBjrunscript\fR¥³¥Þ¥ó¥É¤¬¼Â¹Ô¤µ¤ì¤Æ¤¤¤ëJava Virtual Machine¤ËľÀÜÅϤ·¤Þ¤¹¡£
++\fBflag\fR¤ò¡¢\fBjrunscript\fR¥³¥Þ¥ó¥É¤¬¼Â¹Ô¤µ¤ì¤Æ¤¤¤ëJava²¾ÁÛ¥Þ¥·¥ó¤ËľÀÜÅϤ·¤Þ¤¹¡£
+ .RE
+ .PP
+ \-I \fIlanguage\fR
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jsadebugd.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jsadebugd.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jsadebugd" "1" "2013ǯ11·î21Æü" "JDK 8" "¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë"
+@@ -95,7 +96,7 @@
+ .RE
+ .SH "ÀâÌÀ"
+ .PP
+-\fBjsadebugd\fR¥³¥Þ¥ó¥É¤Ï¡¢Java¥×¥í¥»¥¹¤Þ¤¿¤Ï¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤ËÀܳ¤·¡¢¥Ç¥Ð¥Ã¥°¡¦¥µ¡¼¥Ð¡¼¤È¤·¤Æµ¡Ç½¤·¤Þ¤¹¡£\fBjstack\fR¡¢\fBjmap\fR¤ª¤è¤Ó\fBjinfo\fR¤Ê¤É¤Î¥ê¥â¡¼¥È¡¦¥¯¥é¥¤¥¢¥ó¥È¤Ï¡¢Java Remote Method Invocation(RMI)¤ò»ÈÍѤ·¤Æ¤¤¤ë¥µ¡¼¥Ð¡¼¤ËÀܳ¤Ç¤­¤Þ¤¹¡£\fBjsadebugd\fR¥³¥Þ¥ó¥É¤òµ¯Æ°¤¹¤ëÁ°¤Ë¡¢\fBrmiregistry\fR¥³¥Þ¥ó¥É¤ÇRMI¥ì¥¸¥¹¥È¥ê¤ò¼¡¤Î¤è¤¦¤Ëµ¯Æ°¤·¤Þ¤¹¡£\fI$JAVA_HOME\fR¤ÏJDK¤Î¥¤¥ó¥¹¥È¡¼¥ë¡¦¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹¡£
++\fBjsadebugd\fR¥³¥Þ¥ó¥É¤Ï¡¢Java¥×¥í¥»¥¹¤Þ¤¿¤Ï¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤ËÀܳ¤·¡¢¥Ç¥Ð¥Ã¥°¡¦¥µ¡¼¥Ð¡¼¤È¤·¤Æµ¡Ç½¤·¤Þ¤¹¡£\fBjstack\fR¡¢\fBjmap\fR¤ª¤è¤Ó\fBjinfo\fR¤Ê¤É¤Î¥ê¥â¡¼¥È¡¦¥¯¥é¥¤¥¢¥ó¥È¤Ï¡¢Java Remote Method Invocation (RMI)¤ò»ÈÍѤ·¤Æ¤¤¤ë¥µ¡¼¥Ð¡¼¤ËÀܳ¤Ç¤­¤Þ¤¹¡£\fBjsadebugd\fR¥³¥Þ¥ó¥É¤òµ¯Æ°¤¹¤ëÁ°¤Ë¡¢\fBrmiregistry\fR¥³¥Þ¥ó¥É¤ÇRMI¥ì¥¸¥¹¥È¥ê¤ò¼¡¤Î¤è¤¦¤Ëµ¯Æ°¤·¤Þ¤¹¡£\fI$JAVA_HOME\fR¤ÏJDK¤Î¥¤¥ó¥¹¥È¡¼¥ë¡¦¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jstack.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jstack.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jstack" "1" "2013ǯ11·î21Æü" "JDK 8" "¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¦¥Ä¡¼¥ë"
+@@ -115,7 +116,7 @@
+ .RE
+ .SH "ÀâÌÀ"
+ .PP
+-\fBjstack\fR¥³¥Þ¥ó¥É¤Ï¡¢»ØÄꤵ¤ì¤¿Java¥×¥í¥»¥¹¡¢¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï¥ê¥â¡¼¥È¡¦¥Ç¥Ð¥Ã¥°¡¦¥µ¡¼¥Ð¡¼¤ËÂФ¹¤ëJava¥¹¥ì¥Ã¥É¤ÎJava¥¹¥¿¥Ã¥¯¡¦¥È¥ì¡¼¥¹¤ò½ÐÎϤ·¤Þ¤¹¡£Java¥Õ¥ì¡¼¥à¤´¤È¤Ë¡¢¥Õ¥ë¥¯¥é¥¹Ì¾¡¢¥á¥½¥Ã¥É̾¡¢¥Ð¥¤¥È¥³¡¼¥É¡¦¥¤¥ó¥Ç¥Ã¥¯¥¹(bci)¡¢¤ª¤è¤Ó¹ÔÈÖ¹æ(ÍøÍѲÄǽ¤Ê¾ì¹ç)¤¬½ÐÎϤµ¤ì¤Þ¤¹¡£\fB\-m\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤È¡¢\fBjstack\fR¥³¥Þ¥ó¥É¤Ï¡¢¤¹¤Ù¤Æ¤Î¥¹¥ì¥Ã¥É¤ÎJava¥Õ¥ì¡¼¥à¤È¥Í¥¤¥Æ¥£¥Ö¡¦¥Õ¥ì¡¼¥à¤ÎξÊý¤ò¡¢¥×¥í¥°¥é¥à¡¦¥«¥¦¥ó¥¿(PC)¤È¤È¤â¤Ë½ÐÎϤ·¤Þ¤¹¡£¥Í¥¤¥Æ¥£¥Ö¡¦¥Õ¥ì¡¼¥à¤´¤È¤Ë¡¢PC¤ËºÇ¤â¶á¤¤¥Í¥¤¥Æ¥£¥Ö¡¦¥·¥ó¥Ü¥ë(ÍøÍѲÄǽ¤Ê¾ì¹ç)¤¬½ÐÎϤµ¤ì¤Þ¤¹¡£C++ʬ²ò̾¤Ïʬ²ò²ò½ü¤µ¤ì¤Þ¤»¤ó¡£C++̾¤òʬ²ò²ò½ü¤¹¤ë¤Ë¤Ï¡¢¤³¤Î¥³¥Þ¥ó¥É¤Î½ÐÎϤò\fBc++filt\fR¤Ë¥Ñ¥¤¥×¤·¤Þ¤¹¡£»ØÄꤵ¤ì¤¿¥×¥í¥»¥¹¤¬64¥Ó¥Ã¥ÈJava Virtual Machine¾å¤Ç¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢\fB\-J\-d64\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹(Îã:
++\fBjstack\fR¥³¥Þ¥ó¥É¤Ï¡¢»ØÄꤵ¤ì¤¿Java¥×¥í¥»¥¹¡¢¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï¥ê¥â¡¼¥È¡¦¥Ç¥Ð¥Ã¥°¡¦¥µ¡¼¥Ð¡¼¤ËÂФ¹¤ëJava¥¹¥ì¥Ã¥É¤ÎJava¥¹¥¿¥Ã¥¯¡¦¥È¥ì¡¼¥¹¤ò½ÐÎϤ·¤Þ¤¹¡£Java¥Õ¥ì¡¼¥à¤´¤È¤Ë¡¢¥Õ¥ë¥¯¥é¥¹Ì¾¡¢¥á¥½¥Ã¥É̾¡¢¥Ð¥¤¥È¥³¡¼¥É¡¦¥¤¥ó¥Ç¥Ã¥¯¥¹(bci)¡¢¤ª¤è¤Ó¹ÔÈÖ¹æ(ÍøÍѲÄǽ¤Ê¾ì¹ç)¤¬½ÐÎϤµ¤ì¤Þ¤¹¡£\fB\-m\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤È¡¢\fBjstack\fR¥³¥Þ¥ó¥É¤Ï¡¢¤¹¤Ù¤Æ¤Î¥¹¥ì¥Ã¥É¤ÎJava¥Õ¥ì¡¼¥à¤È¥Í¥¤¥Æ¥£¥Ö¡¦¥Õ¥ì¡¼¥à¤ÎξÊý¤ò¡¢¥×¥í¥°¥é¥à¡¦¥«¥¦¥ó¥¿(PC)¤È¤È¤â¤Ë½ÐÎϤ·¤Þ¤¹¡£¥Í¥¤¥Æ¥£¥Ö¡¦¥Õ¥ì¡¼¥à¤´¤È¤Ë¡¢PC¤ËºÇ¤â¶á¤¤¥Í¥¤¥Æ¥£¥Ö¡¦¥·¥ó¥Ü¥ë(ÍøÍѲÄǽ¤Ê¾ì¹ç)¤¬½ÐÎϤµ¤ì¤Þ¤¹¡£C++ʬ²ò̾¤Ïʬ²ò²ò½ü¤µ¤ì¤Þ¤»¤ó¡£C++̾¤òʬ²ò²ò½ü¤¹¤ë¤Ë¤Ï¡¢¤³¤Î¥³¥Þ¥ó¥É¤Î½ÐÎϤò\fBc++filt\fR¤Ë¥Ñ¥¤¥×¤·¤Þ¤¹¡£»ØÄꤵ¤ì¤¿¥×¥í¥»¥¹¤¬64¥Ó¥Ã¥ÈJava²¾ÁÛ¥Þ¥·¥ó¾å¤Ç¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢\fB\-J\-d64\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹(Îã:
+ \fBjstack \-J\-d64 \-m pid\fR)¡£
+ .PP
+ \fBÃí°Õ\fR
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jstat.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jstat.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: jstat
+ .\" Language: Japanese
+-.\" Date: 2011ǯ5·î10Æü
++.\" Date: 2015ǯ3·î3Æü
+ .\" SectDesc: ¥â¥Ë¥¿¥ê¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "jstat" "1" "2011ǯ5·î10Æü" "JDK 8" "¥â¥Ë¥¿¥ê¥ó¥°¡¦¥Ä¡¼¥ë"
++.TH "jstat" "1" "2015ǯ3·î3Æü" "JDK 8" "¥â¥Ë¥¿¥ê¥ó¥°¡¦¥Ä¡¼¥ë"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -276,6 +277,10 @@
+ .sp
+ \fBMU\fR: ¥á¥¿¥¹¥Ú¡¼¥¹¤Î»ÈÍÑΨ(KB)¡£
+ .sp
++\fBCCSC\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤ÎÍÆÎÌ(KB)¡£
++.sp
++\fBCCSU\fR: »ÈÍѤµ¤ì¤Æ¤¤¤ë°µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè(KB)¡£
++.sp
+ \fBYGC\fR: ¼ã¤¤À¤Âå¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¡¦¥¤¥Ù¥ó¥È¤Î¿ô¡£
+ .sp
+ \fBYGCT\fR: ¼ã¤¤À¤Âå¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó»þ´Ö¡£
+@@ -317,6 +322,12 @@
+ .sp
+ \fBMC\fR: ¥á¥¿¥¹¥Ú¡¼¥¹¤ÎÍÆÎÌ(KB)¡£
+ .sp
++\fBCCSMN\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤ÎºÇ¾®ÍÆÎÌ(KB)¡£
++.sp
++\fBCCSMX\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤ÎºÇÂçÍÆÎÌ(KB)¡£
++.sp
++\fBCCSC\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤ÎÍÆÎÌ(KB)¡£
++.sp
+ \fBYGC\fR: ¼ã¤¤À¤Âå¤ÎGC¥¤¥Ù¥ó¥È¿ô¡£
+ .sp
+ \fBFGC\fR: ¥Õ¥ëGC¥¤¥Ù¥ó¥È¿ô¡£
+@@ -326,11 +337,9 @@
+ .RS 4
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢\fB\-gcutil\fR¥ª¥×¥·¥ç¥ó¤ÈƱ¤¸¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥óÅý·×¥Ç¡¼¥¿¤Î¥µ¥Þ¥ê¡¼¤òɽ¼¨¤·¤Þ¤¹¤¬¡¢ºÇ¸å¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¡¦¥¤¥Ù¥ó¥È¤È(ŬÍѲÄǽ¤Ê¾ì¹ç¤Ï)¸½ºß¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¡¦¥¤¥Ù¥ó¥È¤Î¸¶°ø¤¬´Þ¤Þ¤ì¤Þ¤¹¡£\fB\-gcutil\fR¤Ç°ìÍ÷ɽ¼¨¤µ¤ì¤ëÎó¤Î¤Û¤«¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ç¤Ï¼¡¤ÎÎó¤¬Äɲ䵤ì¤Þ¤¹¡£
+ .sp
+-¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¡¦¥¤¥Ù¥ó¥È¤ò´Þ¤à¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥óÅý·×¥Ç¡¼¥¿¡£
++\fBLGCC\fR: ºÇ¸å¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¤Î¸¶°ø
+ .sp
+-\fBLGCC\fR: ºÇ¸å¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¤Î¸¶°ø¡£
+-.sp
+-\fBGCC\fR: ¸½ºß¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¤Î¸¶°ø¡£
++\fBGCC\fR: ¸½ºß¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó¤Î¸¶°ø
+ .RE
+ .PP
+ \-gcnew \fIoption\fR
+@@ -364,7 +373,7 @@
+ .RS 4
+ NewÀ¤ÂåÎΰ襵¥¤¥º¤ÎÅý·×¥Ç¡¼¥¿¡£
+ .sp
+-NGCMN: NewÀ¤Âå¤ÎºÇ¾®ÍÆÎÌ(KB)¡£
++\fBNGCMN\fR: NewÀ¤Âå¤ÎºÇ¾®ÍÆÎÌ(KB)¡£
+ .sp
+ \fBNGCMX\fR: NewÀ¤Âå¤ÎºÇÂçÍÆÎÌ(KB)¡£
+ .sp
+@@ -395,6 +404,10 @@
+ .sp
+ \fBMU\fR: ¥á¥¿¥¹¥Ú¡¼¥¹¤Î»ÈÍÑΨ(KB)¡£
+ .sp
++\fBCCSC\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤ÎÍÆÎÌ(KB)¡£
++.sp
++\fBCCSU\fR: »ÈÍѤµ¤ì¤Æ¤¤¤ë°µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè(KB)¡£
++.sp
+ \fBOC\fR: OldÎΰè¤Î¸½ºß¤ÎÍÆÎÌ(KB)¡£
+ .sp
+ \fBOU\fR: OldÎΰè¤Î»ÈÍÑΨ(KB)¡£
+@@ -439,6 +452,10 @@
+ .sp
+ \fBMC\fR: ¥á¥¿¥¹¥Ú¡¼¥¹¤ÎÍÆÎÌ(KB)¡£
+ .sp
++\fBCCSMN\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤ÎºÇ¾®ÍÆÎÌ(KB)¡£
++.sp
++\fBCCSMX\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤ÎºÇÂçÍÆÎÌ(KB)¡£
++.sp
+ \fBYGC\fR: ¼ã¤¤À¤Âå¤ÎGC¥¤¥Ù¥ó¥È¿ô¡£
+ .sp
+ \fBFGC\fR: ¥Õ¥ëGC¥¤¥Ù¥ó¥È¿ô¡£
+@@ -462,6 +479,8 @@
+ .sp
+ \fBM\fR: ¥á¥¿¥¹¥Ú¡¼¥¹¤Î»ÈÍÑΨ(Îΰè¤Î¸½ºß¤ÎÍÆÎ̤ËÂФ¹¤ë¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸)¡£
+ .sp
++\fBCCS\fR: °µ½Ì¤µ¤ì¤¿¥¯¥é¥¹Îΰè¤Î»ÈÍÑΨ(¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸)¡£
++.sp
+ \fBYGC\fR: ¼ã¤¤À¤Âå¤ÎGC¥¤¥Ù¥ó¥È¿ô¡£
+ .sp
+ \fBYGCT\fR: ¼ã¤¤À¤Âå¤Î¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó»þ´Ö¡£
+@@ -493,29 +512,28 @@
+ .PP
+ ¤³¤ÎÎã¤Ç¤Ï¡¢lvmid 21891¤ËÀܳ¤·¤Æ¡¢250¥ß¥êÉôֳ֤Ç7¤Ä¤Î¥µ¥ó¥×¥ë¤ò¼èÆÀ¤·¡¢\-\fBgcutil\fR¥ª¥×¥·¥ç¥ó¤Ç¤Î»ØÄê¤Ë½¾¤Ã¤Æ½ÐÎϤòɽ¼¨¤·¤Þ¤¹¡£
+ .PP
+-¤³¤ÎÎã¤Î½ÐÎϤϡ¢¼ã¤¤À¤Âå¤Î¥³¥ì¥¯¥·¥ç¥ó¤¬3ÈÖÌܤÈ4ÈÖÌܤΥµ¥ó¥×¥ë´Ö¤Ç¹Ô¤ï¤ì¤¿¤³¤È¤ò¼¨¤·¤Æ¤¤¤Þ¤¹¡£¥³¥ì¥¯¥·¥ç¥ó¤Ë¤Ï0\&.001É䫤«¤Ã¤Æ¤ª¤ê¡¢¥ª¥Ö¥¸¥§¥¯¥È¤¬EdenÎΰè(E)¤«¤éOldÎΰè(O)¤Ë¾º³Ê¤·¤¿¤¿¤á¡¢OldÎΰè¤Î»ÈÍÑΨ¤Ï9\&.49%¤«¤é9\&.51%¤ËÁý²Ã¤·¤Æ¤¤¤Þ¤¹¡£SurvivorÎΰè¤Ï¡¢¥³¥ì¥¯¥·¥ç¥óÁ°¤Ï12\&.44%¤¬»ÈÍѤµ¤ì¤Æ¤¤¤Þ¤·¤¿¤¬¡¢¥³¥ì¥¯¥·¥ç¥ó¸å¤Î»ÈÍѤÏ7\&.74%¤Î¤ß¤Ç¤¹¡£
++¤³¤ÎÎã¤Î½ÐÎϤϡ¢¼ã¤¤À¤Âå¤Î¥³¥ì¥¯¥·¥ç¥ó¤¬3ÈÖÌܤÈ4ÈÖÌܤΥµ¥ó¥×¥ë´Ö¤Ç¹Ô¤ï¤ì¤¿¤³¤È¤ò¼¨¤·¤Æ¤¤¤Þ¤¹¡£¥³¥ì¥¯¥·¥ç¥ó¤Ë¤Ï0\&.078É䫤«¤Ã¤Æ¤ª¤ê¡¢¥ª¥Ö¥¸¥§¥¯¥È¤¬EdenÎΰè(E)¤«¤éOldÎΰè(O)¤Ë¾º³Ê¤·¤¿¤¿¤á¡¢OldÎΰè¤Î»ÈÍÑΨ¤Ï66\&.80%¤«¤é68\&.19%¤ËÁý²Ã¤·¤Æ¤¤¤Þ¤¹¡£SurvivorÎΰè¤Ï¡¢¥³¥ì¥¯¥·¥ç¥óÁ°¤Ï97\&.02%¤¬»ÈÍѤµ¤ì¤Æ¤¤¤Þ¤·¤¿¤¬¡¢¥³¥ì¥¯¥·¥ç¥ó¸å¤Î»ÈÍѤÏ91\&.03%¤Ç¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+ .\}
+ .nf
+ \fBjstat \-gcutil 21891 250 7\fR
+-\fB S0 S1 E O M YGC YGCT FGC FGCT GCT\fR
+-\fB0\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fR
+-\fB0\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fR
+-\fB0\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fR
+-\fB0\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fR
+-\fB0\&.00 99\&.74 13\&.80 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fR
+-\fB0\&.00 99\&.74 13\&.80 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fR
+-\fB0\&.00 99\&.74 13\&.80 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fR
+-
++\fB S0 S1 E O M CCS YGC YGCT FGC FGCT GCT \fR
++\fB 0\&.00 97\&.02 70\&.31 66\&.80 95\&.52 89\&.14 7 0\&.300 0 0\&.000 0\&.300\fR
++\fB 0\&.00 97\&.02 86\&.23 66\&.80 95\&.52 89\&.14 7 0\&.300 0 0\&.000 0\&.300\fR
++\fB 0\&.00 97\&.02 96\&.53 66\&.80 95\&.52 89\&.14 7 0\&.300 0 0\&.000 0\&.300\fR
++\fB 91\&.03 0\&.00 1\&.98 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++\fB 91\&.03 0\&.00 15\&.82 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++\fB 91\&.03 0\&.00 17\&.80 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++\fB 91\&.03 0\&.00 17\&.80 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
+ .fi
+ .if n \{\
+ .RE
+ .\}
+ .SS "Îó¥Ø¥Ã¥À¡¼Ê¸»úÎó¤Î·«ÊÖ¤·"
+ .PP
+-¤³¤ÎÎã¤Ç¤Ï¡¢lvmid 21891¤ËÀܳ¤·¤Æ¡¢250¥ß¥êÉôֳ֤ǥµ¥ó¥×¥ë¤ò¼èÆÀ¤·¡¢\fB\-gcutil\fR¥ª¥×¥·¥ç¥ó¤Ç¤Î»ØÄê¤Ë½¾¤Ã¤Æ½ÐÎϤòɽ¼¨¤·¤Þ¤¹¡£¤µ¤é¤Ë¡¢\fB\-h3\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¡¢¥Ç¡¼¥¿¤¬3¹Ôɽ¼¨¤µ¤ì¤ë¤´¤È¤ËÎó¥Ø¥Ã¥À¡¼¤ò½ÐÎϤ·¤Þ¤¹¡£
++¤³¤ÎÎã¤Ç¤Ï¡¢lvmid 21891¤ËÀܳ¤·¤Æ¡¢250¥ß¥êÉôֳ֤ǥµ¥ó¥×¥ë¤ò¼èÆÀ¤·¡¢\fB\-gcnew\fR¥ª¥×¥·¥ç¥ó¤Ç¤Î»ØÄê¤Ë½¾¤Ã¤Æ½ÐÎϤòɽ¼¨¤·¤Þ¤¹¡£¤µ¤é¤Ë¡¢\fB\-h3\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¡¢¥Ç¡¼¥¿¤¬3¹Ôɽ¼¨¤µ¤ì¤ë¤´¤È¤ËÎó¥Ø¥Ã¥À¡¼¤ò½ÐÎϤ·¤Þ¤¹¡£
+ .PP
+ ¤³¤ÎÎã¤Ç¤Ï¡¢¥Ø¥Ã¥À¡¼Ê¸»úÎó¤Î·«ÊÖ¤·¤¬É½¼¨¤µ¤ì¤Æ¤¤¤ë¤Û¤«¡¢2ÈÖÌܤÈ3ÈÖÌܤΥµ¥ó¥×¥ë´Ö¤ÇYoung GC¤¬¹Ô¤ï¤ì¤¿¤³¤È¤¬¤ï¤«¤ê¤Þ¤¹¡£¤³¤Î·Ñ³»þ´Ö¤Ï0\&.001ÉäǤ·¤¿¡£¤³¤Î¥³¥ì¥¯¥·¥ç¥ó¤Ç¤Ï¡¢SurvivorÎΰè0¤Î»ÈÍÑΨ(S0U)¤¬Å¬ÀÚ¤ÊSurvivor¥µ¥¤¥º(DSS)¤òĶ²á¤¹¤ë¤³¤È¤Ë¤Ê¤ë¥¢¥¯¥Æ¥£¥Ö¡¦¥Ç¡¼¥¿¤¬¸¡½Ð¤µ¤ì¤Þ¤·¤¿¡£¤³¤Î·ë²Ì¡¢¥ª¥Ö¥¸¥§¥¯¥È¤Ï¡¢OldÀ¤Âå(¤³¤Î½ÐÎϤˤÏÈóɽ¼¨)¤Ø¾º³Ê¤µ¤ì¡¢ÅÂƲÆþ¤ê¤·¤­¤¤ÃÍ(TT)¤¬¡¢31¤«¤é2¤Ø¹ß³Ê¤µ¤ì¤Þ¤·¤¿¡£
+ .PP
+@@ -545,7 +563,7 @@
+ .PP
+ ¤³¤ÎÎã¤Ç¤Ï¡¢lvmid21891¤ØÀܳ¤·¡¢250¥ß¥êÉôֳ֤Ç3¤Ä¤Î¥µ¥ó¥×¥ë¤ò¼èÆÀ¤·¤Æ¤¤¤Þ¤¹¡£\fB\-t\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¡¢ºÇ½é¤ÎÎó¤Ë¥µ¥ó¥×¥ë¤´¤È¤Î¥¿¥¤¥à¥¹¥¿¥ó¥×¤òɽ¼¨¤·¤Æ¤¤¤Þ¤¹¡£
+ .PP
+-TimestampÎó¤Ë¤Ï¡¢¥¿¡¼¥²¥Ã¥ÈJVM¤Îµ¯Æ°»þ¤«¤é¤Î·Ð²á»þ´Ö¤¬¡¢ÉÃñ°Ì¤Ç¥ì¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤µ¤é¤Ë¡¢\fB\-gcoldcapacity\fR½ÐÎϤǤϡ¢³äÅö¥ê¥¯¥¨¥¹¥È¤Þ¤¿¤Ï¾º³Ê¥ê¥¯¥¨¥¹¥È¤¢¤ë¤¤¤Ï¤½¤ÎξÊý¤òËþ¤¿¤¹¤¿¤á¤Ë¥Ò¡¼¥×¤¬³ÈÄ¥¤¹¤ë¤¿¤Ó¤Ë¡¢OldÀ¤Âå¤ÎÍÆÎÌ(OGC)¤ÈOldÎΰè¤ÎÍÆÎÌ(OC)¤È¤¬Áý²Ã¤·¤Æ¤¤¤ë¤³¤È¤¬¤ï¤«¤ê¤Þ¤¹¡£81ÈÖÌܤΥե롦¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó(FGC)¤Î¸å¡¢OldÀ¤Âå¤ÎÍÆÎÌ(OGC)¤Ï11,696 KB¤«¤é13820 KB¤ËÁý²Ã¤·¤Þ¤·¤¿¡£¤³¤ÎÀ¤Âå(¤ª¤è¤ÓÎΰè)¤ÎºÇÂçÍÆÎ̤ϡ¢60,544 KB (OGCMX)¤Ê¤Î¤Ç¡¢¤Þ¤À³ÈÄ¥¤Ç¤­¤ë;͵¤¬»Ä¤µ¤ì¤Æ¤¤¤Þ¤¹¡£
++TimestampÎó¤Ë¤Ï¡¢¥¿¡¼¥²¥Ã¥ÈJVM¤Îµ¯Æ°»þ¤«¤é¤Î·Ð²á»þ´Ö¤¬¡¢ÉÃñ°Ì¤Ç¥ì¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤µ¤é¤Ë¡¢\fB\-gcoldcapacity\fR½ÐÎϤǤϡ¢³äÅö¥ê¥¯¥¨¥¹¥È¤Þ¤¿¤Ï¾º³Ê¥ê¥¯¥¨¥¹¥È¤¢¤ë¤¤¤Ï¤½¤ÎξÊý¤òËþ¤¿¤¹¤¿¤á¤Ë¥Ò¡¼¥×¤¬³ÈÄ¥¤¹¤ë¤¿¤Ó¤Ë¡¢OldÀ¤Âå¤ÎÍÆÎÌ(OGC)¤ÈOldÎΰè¤ÎÍÆÎÌ(OC)¤È¤¬Áý²Ã¤·¤Æ¤¤¤ë¤³¤È¤¬¤ï¤«¤ê¤Þ¤¹¡£81ÈÖÌܤΥե롦¥¬¥Ù¡¼¥¸¡¦¥³¥ì¥¯¥·¥ç¥ó(FGC)¤Î¸å¡¢OldÀ¤Âå¤ÎÍÆÎÌ(OGC)¤Ï11,696KB¤«¤é13,820KB¤ËÁý²Ã¤·¤Þ¤·¤¿¡£¤³¤ÎÀ¤Âå(¤ª¤è¤ÓÎΰè)¤ÎºÇÂçÍÆÎ̤ϡ¢60,544KB (OGCMX)¤Ê¤Î¤Ç¡¢¤Þ¤À³ÈÄ¥¤Ç¤­¤ë;͵¤¬»Ä¤µ¤ì¤Æ¤¤¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+@@ -564,7 +582,7 @@
+ .PP
+ ¤³¤ÎÎã¤Ï¡¢\fB\-gcutil\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¡¢remote\&.domain¤È¤¤¤¦¥·¥¹¥Æ¥à¾å¤Îlvmid 40496¤ËÀܳ¤·¡¢¥µ¥ó¥×¥ë¤òÉÃñ°Ì¤Ç̵´ü¸Â¤Ë¼èÆÀ¤·¤Æ¤¤¤Þ¤¹¡£
+ .PP
+-lvmid¤Ï¡¢¥ê¥â¡¼¥È¡¦¥Û¥¹¥È¤Î̾Á°¤È·ë¹ç¤µ¤ì¤Æ¡¢\fB40496@remote\&.domain\fR¤Î\fIvmid\fR¤ò¹½À®¤·¤Æ¤¤¤Þ¤¹¡£·ë²Ì¤È¤·¤Æ¡¢¤³¤Îvmid¤Ï¡¢\fBrmi\fR¥×¥í¥È¥³¥ë¤ò»ÈÍѤ·¤Æ¡¢¥ê¥â¡¼¥È¡¦¥Û¥¹¥È¾å¤Î¥Ç¥Õ¥©¥ë¥È¤Î\fBjstatd\fR¥µ¡¼¥Ð¡¼¤ÈÄÌ¿®¤·¤Þ¤¹¡£\fBjstatd\fR¥µ¡¼¥Ð¡¼¤Ï¡¢rmiregistry¤ò»ÈÍѤ·¤Æ¡¢¥Ç¥Õ¥©¥ë¥È¤Îrmiregistry¥Ý¡¼¥È(¥Ý¡¼¥È1099)¤Ë¥Ð¥¤¥ó¥É¤µ¤ì¤¿\fBremote\&.domain\fR¤ËÇÛÃÖ¤µ¤ì¤Þ¤¹¡£
++lvmid¤Ï¡¢¥ê¥â¡¼¥È¡¦¥Û¥¹¥È¤Î̾Á°¤È·ë¹ç¤µ¤ì¤Æ¡¢\fB40496@remote\&.domain\fR¤Î\fIvmid\fR¤ò¹½À®¤·¤Æ¤¤¤Þ¤¹¡£·ë²Ì¤È¤·¤Æ¡¢¤³¤Îvmid¤Ï¡¢\fBrmi\fR¥×¥í¥È¥³¥ë¤ò»ÈÍѤ·¤Æ¡¢¥ê¥â¡¼¥È¡¦¥Û¥¹¥È¾å¤Î¥Ç¥Õ¥©¥ë¥È¤Î\fBjstatd\fR¥µ¡¼¥Ð¡¼¤ÈÄÌ¿®¤·¤Þ¤¹¡£\fBjstatd\fR¥µ¡¼¥Ð¡¼¤Ï¡¢\fBrmiregistry\fR¥³¥Þ¥ó¥É¤ò»ÈÍѤ·¤Æ¡¢\fBrmiregistry\fR¥³¥Þ¥ó¥É¤Î¥Ç¥Õ¥©¥ë¥È¤Î¥Ý¡¼¥È(¥Ý¡¼¥È1099)¤Ë¥Ð¥¤¥ó¥É¤µ¤ì¤¿\fBremote\&.domain\fR¤ËÇÛÃÖ¤µ¤ì¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jstatd.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jstatd.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¥â¥Ë¥¿¥ê¥ó¥°¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jstatd" "1" "2013ǯ11·î21Æü" "JDK 8" "¥â¥Ë¥¿¥ê¥ó¥°¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/jvisualvm.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/jvisualvm.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¢¥×¥í¥Õ¥¡¥¤¥ê¥ó¥°¡¢¥â¥Ë¥¿¥ê¥ó¥°¤ª¤è¤Ó´ÉÍý¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "jvisualvm" "1" "2013ǯ11·î21Æü" "JDK 8" "Java¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¡¢¥×¥í¥Õ¥¡¥¤¥ê¥ó¥°¡¢¥â¥Ë¥¿¥ê¥ó"
+@@ -51,7 +52,7 @@
+ .\" * MAIN CONTENT STARTS HERE *
+ .\" -----------------------------------------------------------------
+ .SH "̾Á°"
+-jvisualvm \- Java¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ò»ë³ÐŪ¤Ë¥â¥Ë¥¿¡¼¤·¡¢¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¤È¥×¥í¥Õ¥¡¥¤¥ê¥ó¥°¤ò¹Ô¤¤¤Þ¤¹¡£
++jvisualvm \- Java¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ò»ë³ÐŪ¤Ë¥â¥Ë¥¿¡¼¡¢¥È¥é¥Ö¥ë¥·¥å¡¼¥È¤ª¤è¤Ó¥×¥í¥Õ¥¡¥¤¥ë¤·¤Þ¤¹¡£
+ .SH "³µÍ×"
+ .sp
+ .if n \{\
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/keytool.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/keytool.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: keytool
+ .\" Language: Japanese
+-.\" Date: 2013ǯ8·î6Æü
++.\" Date: 2015ǯ3·î3Æü
+ .\" SectDesc: ¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "keytool" "1" "2013ǯ8·î6Æü" "JDK 8" "¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë"
++.TH "keytool" "1" "2015ǯ3·î3Æü" "JDK 8" "¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -375,7 +376,7 @@
+ .sp -1
+ .IP \(bu 2.3
+ .\}
+-¥¤¥¿¥ê¥Ã¥¯ÂΤˤʤäƤ¤¤Ê¤¤¤¹¤Ù¤Æ¤Î¹àÌÜ¡¢¤Þ¤¿¤ÏÃ楫¥Ã¥³¤«³Ñ¥«¥Ã¥³¤Ç°Ï¤Þ¤ì¤Æ¤¤¤ë¤¹¤Ù¤Æ¤Î¹àÌܤϡ¢¤½¤Î¤È¤ª¤ê¤Ë»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
++¥¤¥¿¥ê¥Ã¥¯¤Ë¤Ê¤Ã¤Æ¤¤¤Ê¤¤¤¹¤Ù¤Æ¤Î¹àÌÜ¡¢¤Þ¤¿¤ÏÃ楫¥Ã¥³¤«³Ñ¥«¥Ã¥³¤Ç°Ï¤Þ¤ì¤Æ¤¤¤ë¤¹¤Ù¤Æ¤Î¹àÌܤϡ¢¤½¤Î¤È¤ª¤ê¤Ë»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .sp
+ .RS 4
+@@ -408,11 +409,19 @@
+ .sp -1
+ .IP \(bu 2.3
+ .\}
+-¥¤¥¿¥ê¥Ã¥¯ÂΤιàÌܤμºݤÎÃÍ(¥ª¥×¥·¥ç¥ó¤ÎÃÍ)¤Ï¡¢»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢\fB\-printcert\fR¥³¥Þ¥ó¥É¤Î·Á¼°¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹¡£
++¥¤¥¿¥ê¥Ã¥¯¤Î¹àÌܤμºݤÎÃÍ(¥ª¥×¥·¥ç¥ó¤ÎÃÍ)¤Ï¡¢»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢\fB\-printcert\fR¥³¥Þ¥ó¥É¤Î·Á¼°¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹¡£
+ .sp
+-\fBkeytool \-printcert {\-file cert_file} {\-v}\fR
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBkeytool \-printcert {\-file \fR\fB\fIcert_file\fR\fR\fB} {\-v}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ .sp
+-\fB\-printcert\fR¥³¥Þ¥ó¥É¤ò»ØÄꤹ¤ë¾ì¹ç¤Ï¡¢\fBcert_file\fR¤ò¼ÂºÝ¤Î¥Õ¥¡¥¤¥ë̾¤ÇÃÖ¤­´¹¤¨¤Þ¤¹¡£Îã:
++\fB\-printcert\fR¥³¥Þ¥ó¥É¤ò»ØÄꤹ¤ë¾ì¹ç¤Ï¡¢\fIcert_file\fR¤ò¼ÂºÝ¤Î¥Õ¥¡¥¤¥ë̾¤ÇÃÖ¤­´¹¤¨¤Þ¤¹¡£Îã:
+ \fBkeytool \-printcert \-file VScert\&.cer\fR
+ .RE
+ .sp
+@@ -624,8 +633,7 @@
+ SAN¤Þ¤¿¤ÏSubjectAlternativeName
+ .RS 4
+ \fBÃÍ\fR:
+-\fBtype\fR:\fBvalue\fR
+-(t\fBype:value\fR)*¡¢\fBtype\fR¤Ë¤Ï\fBEMAIL\fR¡¢\fBURI\fR¡¢\fBDNS\fR¡¢\fBIP\fR¤Þ¤¿¤Ï\fBOID\fR¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£\fBvalue\fR°ú¿ô¤Ï¡¢\fBtype\fR¤Îʸ»úÎó·Á¼°¤ÎÃͤǤ¹¡£
++\fBtype\fR:\fBvalue\fR(t\fBype:value\fR)*¡¢\fBtype\fR¤Ë¤Ï\fBEMAIL\fR¡¢\fBURI\fR¡¢\fBDNS\fR¡¢\fBIP\fR¤Þ¤¿¤Ï\fBOID\fR¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£\fBvalue\fR°ú¿ô¤Ï¡¢\fBtype\fR¤Îʸ»úÎó·Á¼°¤ÎÃͤǤ¹¡£
+ .RE
+ .PP
+ IAN¤Þ¤¿¤ÏIssuerAlternativeName
+@@ -662,8 +670,66 @@
+ .PP
+ \-gencert
+ .RS 4
+-\fB{\-rfc} {\-infile infile} {\-outfile outfile} {\-alias alias} {\-sigalg sigalg} {\-dname dname} {\-startdate startdate {\-ext ext}* {\-validity valDays} [\-keypass keypass] {\-keystore keystore} [\-storepass storepass] {\-storetype storetype} {\-providername provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-rfc} {\-infile \fR\fB\fIinfile\fR\fR\fB} {\-outfile \fR\fB\fIoutfile\fR\fR\fB} {\-alias \fR\fB\fIalias\fR\fR\fB} {\-sigalg \fR\fB\fIsigalg\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-dname \fR\fB\fIdname\fR\fR\fB} {\-startdate \fR\fB\fIstartdate\fR\fR\fB {\-ext \fR\fB\fIext\fR\fR\fB}* {\-validity \fR\fB\fIvalDays\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-keypass \fR\fB\fIkeypass\fR\fR\fB] {\-keystore \fR\fB\fIkeystore\fR\fR\fB} [\-storepass \fR\fB\fIstorepass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-providername \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¾ÚÌÀ½ñ¥ê¥¯¥¨¥¹¥È¡¦¥Õ¥¡¥¤¥ë(\fBkeytool\fR
+ \fB\-certreq\fR¥³¥Þ¥ó¥É¤ÇºîÀ®²Äǽ)¤ËÂФ¹¤ë¥ì¥¹¥Ý¥ó¥¹¤È¤·¤Æ¾ÚÌÀ½ñ¤òÀ¸À®¤·¤Þ¤¹¡£¤³¤Î¥³¥Þ¥ó¥É¤Ï¡¢\fIinfile\fR¤«¤é(¾Êά¤·¤¿¾ì¹ç¤Ï¡¢É¸½àÆþÎϤ«¤é)¥ê¥¯¥¨¥¹¥È¤òÆɤ߹þ¤ß¡¢ÊÌ̾¤ÎÈëÌ©¸°¤ò»ÈÍѤ·¤Æ¤½¤Î¥ê¥¯¥¨¥¹¥È¤Ë½ð̾¤·¤Æ¡¢X\&.509¾ÚÌÀ½ñ¤ò\fIoutfile\fR¤Ë(¾Êά¤·¤¿¾ì¹ç¤Ï¡¢É¸½à½ÐÎϤË)½ÐÎϤ·¤Þ¤¹¡£\fB\-rfc\fR¤ò»ØÄꤷ¤¿¾ì¹ç¡¢½ÐÎÏ·Á¼°¤ÏBASE64Éä¹æ²½¤ÎPEM¤Ë¤Ê¤ê¤Þ¤¹¡£¤½¤ì°Ê³°¤Î¾ì¹ç¤Ï¡¢¥Ð¥¤¥Ê¥êDER¤¬ºîÀ®¤µ¤ì¤Þ¤¹¡£
+ .sp
+@@ -724,8 +790,66 @@
+ .PP
+ \-genkeypair
+ .RS 4
+-\fB{\-alias alias} {\-keyalg keyalg} {\-keysize keysize} {\-sigalg sigalg} [\-dname dname] [\-keypass keypass] {\-startdate value} {\-ext ext}* {\-validity valDays} {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} {\-keyalg \fR\fB\fIkeyalg\fR\fR\fB} {\-keysize \fR\fB\fIkeysize\fR\fR\fB} {\-sigalg \fR\fB\fIsigalg\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-dname \fR\fB\fIdname\fR\fR\fB] [\-keypass \fR\fB\fIkeypass\fR\fR\fB] {\-startdate \fR\fB\fIvalue\fR\fR\fB} {\-ext \fR\fB\fIext\fR\fR\fB}*\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-validity \fR\fB\fIvalDays\fR\fR\fB} {\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-storepass \fR\fB\fIstorepass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¸°¤Î¥Ú¥¢(¸ø³«¸°¤ª¤è¤Ó´ØÏ¢¤¹¤ëÈëÌ©¸°)¤òÀ¸À®¤·¤Þ¤¹¡£¸ø³«¸°¤ÏX\&.509 v3¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ç¥é¥Ã¥×¤µ¤ì¤Þ¤¹¡£¾ÚÌÀ½ñ¤Ï¡¢Ã±°ì¤ÎÍ×ÁǤò»ý¤Ä¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤È¤·¤Æ³ÊǼ¤µ¤ì¤Þ¤¹¡£¤³¤Î¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤ÈÈëÌ©¸°¤Ï¡¢alias¤ÇÆÃÄꤵ¤ì¤ë¿·¤·¤¤¥­¡¼¥¹¥È¥¢¡¦¥¨¥ó¥È¥ê¤Ë³ÊǼ¤µ¤ì¤Þ¤¹¡£
+ .sp
+ \fBkeyalg\fRÃͤϸ°¥Ú¥¢¤ÎÀ¸À®¤Ë»ÈÍѤ¹¤ë¥¢¥ë¥´¥ê¥º¥à¤ò¡¢\fBkeysize\fRÃͤÏÀ¸À®¤¹¤ë³Æ¸°¤Î¥µ¥¤¥º¤ò¡¢¤½¤ì¤¾¤ì»ØÄꤷ¤Þ¤¹¡£\fBsigalg\fRÃͤϡ¢¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ë½ð̾¤òÉÕ¤±¤ë¤¿¤á¤Ë»ÈÍѤ¹¤ë¥¢¥ë¥´¥ê¥º¥à¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¥¢¥ë¥´¥ê¥º¥à¤Ï\fBkeyalg\fRÃͤȸߴ¹À­¤¬¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+@@ -758,7 +882,7 @@
+ .if n \{\
+ .RE
+ .\}
+-2ÈÖÌܤηÁ¼°¤Ç¤Ï¡¢¥æ¡¼¥¶¡¼¤Ï¡¢Ç¯/·î/Æü¤È»þ´Ö:ʬ:ÉäÎ2¤Ä¤ÎÉôʬ¤«¤é¤Ê¤ëÀµ³Î¤Êȯ¹Ô»þ¹ï¤òÀßÄꤷ¤Þ¤¹(¥í¡¼¥«¥ë¤Î¥¿¥¤¥à¡¦¥¾¡¼¥ó¤ò»ÈÍÑ)¡£¥æ¡¼¥¶¡¼¤Ï¡¢1¤Ä¤ÎÉôʬ¤Î¤ß¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£¤³¤ì¤Ï¡¢¤â¤¦1¤Ä¤ÎÉôʬ¤Ï¸½ºß¤ÎÆüÉÕ(¤Þ¤¿¤Ï»þ¹ï)¤ÈƱ¤¸¤Ë¤Ê¤ë¤È¤¤¤¦¤³¤È¤Ç¤¹¡£¥æ¡¼¥¶¡¼¤Ï¡¢·Á¼°¤ÎÄêµÁ¤Ë¼¨¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë¡¢·å¿ô¤ò¸·Ì©¤Ë»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹(û¤¤¾ì¹ç¤Ï0¤ÇËä¤á¤Þ¤¹)¡£ÆüÉդȻþ¹ï¤ÎξÊý¤¬»ØÄꤵ¤ì¤¿¾õÂ֤ǡ¢2¤Ä¤ÎÉôʬ¤Î´Ö¤Ë¶õÇòʸ»ú¤¬1¤Ä(1¤Ä¤Î¤ß)¤¢¤ê¤Þ¤¹¡£»þ´Ö¤Ï¾ï¤Ë24»þ´Ö·Á¼°¤Ç»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
++2ÈÖÌܤηÁ¼°¤Ç¤Ï¡¢¥æ¡¼¥¶¡¼¤Ï¡¢Ç¯/·î/Æü¤È»þ´Ö:ʬ:ÉäÎ2¤Ä¤ÎÉôʬ¤Ç¸·Ì©¤Ê³«»Ï»þ¹ï¤òÀßÄꤷ¤Þ¤¹(Ãϸµ¤Î»þ´ÖÂÓ¤ò»ÈÍÑ)¡£¥æ¡¼¥¶¡¼¤Ï¡¢1¤Ä¤ÎÉôʬ¤Î¤ß¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£¤³¤ì¤Ï¡¢¤â¤¦1¤Ä¤ÎÉôʬ¤Ï¸½ºß¤ÎÆüÉÕ(¤Þ¤¿¤Ï»þ¹ï)¤ÈƱ¤¸¤Ë¤Ê¤ë¤È¤¤¤¦¤³¤È¤Ç¤¹¡£¥æ¡¼¥¶¡¼¤Ï¡¢·Á¼°¤ÎÄêµÁ¤Ë¼¨¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë¡¢·å¿ô¤ò¸·Ì©¤Ë»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹(û¤¤¾ì¹ç¤Ï0¤ÇËä¤á¤Þ¤¹)¡£ÆüÉդȻþ¹ï¤ÎξÊý¤¬»ØÄꤵ¤ì¤¿¾õÂ֤ǡ¢2¤Ä¤ÎÉôʬ¤Î´Ö¤Ë¶õÇòʸ»ú¤¬1¤Ä(1¤Ä¤Î¤ß)¤¢¤ê¤Þ¤¹¡£»þ´Ö¤Ï¾ï¤Ë24»þ´Ö·Á¼°¤Ç»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+ .sp
+ ¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤¤¤È¡¢³«»ÏÆüÉդϸ½ºß¤Î»þ¹ï¤Ë¤Ê¤ê¤Þ¤¹¡£¥ª¥×¥·¥ç¥ó¤Ï¡¢ºÇÂç¤Ç1²ó»ØÄê¤Ç¤­¤Þ¤¹¡£
+ .sp
+@@ -769,8 +893,46 @@
+ .PP
+ \-genseckey
+ .RS 4
+-\fB\-genseckey {\-alias alias} {\-keyalg keyalg} {\-keysize keysize} [\-keypass keypass] {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} {\-keyalg \fR\fB\fIkeyalg\fR\fR\fB} {\-keysize \fR\fB\fIkeysize\fR\fR\fB} [\-keypass \fR\fB\fIkeypass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB} [\-storepass \fR\fB\fIstorepass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}} {\-v}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ÈëÌ©¸°¤òÀ¸À®¤·¡¢¤½¤ì¤ò¿·¤·¤¤\fBKeyStore\&.SecretKeyEntry\fR(\fBalias\fR¤ÇÆÃÄꤵ¤ì¤ë)Æâ¤Ë³ÊǼ¤·¤Þ¤¹¡£
+ .sp
+ \fBkeyalg\fRÃͤϸ°¥Ú¥¢¤ÎÀ¸À®¤Ë»ÈÍѤ¹¤ë¥¢¥ë¥´¥ê¥º¥à¤ò¡¢\fBkeysize\fRÃͤÏÀ¸À®¤¹¤ë³Æ¸°¤Î¥µ¥¤¥º¤ò¡¢¤½¤ì¤¾¤ì»ØÄꤷ¤Þ¤¹¡£\fBkeypass\fRÃͤϡ¢ÈëÌ©¸°¤òÊݸ¤ë¥Ñ¥¹¥ï¡¼¥É¤Ç¤¹¡£¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£¤³¤Î¤È¤­¡¢[Return]¥­¡¼¤ò²¡¤¹¤È¡¢\fBkeystore\fR¤Î¥Ñ¥¹¥ï¡¼¥É¤ÈƱ¤¸¥Ñ¥¹¥ï¡¼¥É¤¬¸°¤Î¥Ñ¥¹¥ï¡¼¥É¤ËÀßÄꤵ¤ì¤Þ¤¹¡£\fBkeypass\fRÃͤϡ¢6ʸ»ú°Ê¾å¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+@@ -778,8 +940,56 @@
+ .PP
+ \-importcert
+ .RS 4
+-\fB\-importcert {\-alias alias} {\-file cert_file} [\-keypass keypass] {\-noprompt} {\-trustcacerts} {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} {\-file \fR\fB\fIcert_file\fR\fR\fB} [\-keypass \fR\fB\fIkeypass\fR\fR\fB] {\-noprompt} {\-trustcacerts}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB} [\-storepass \fR\fB\fIstorepass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerName \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¥Õ¥¡¥¤¥ë\fBcert_file\fR¤«¤é¾ÚÌÀ½ñ¤Þ¤¿¤Ï¾ÚÌÀ½ñ¥Á¥§¡¼¥ó(¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤Î¾ì¹ç¤Ï¡¢PKCS#7·Á¼°¤Î±þÅú¤Þ¤¿¤Ï°ìÏ¢¤ÎX\&.509¾ÚÌÀ½ñ¤ÇÄ󶡤µ¤ì¤ë¤â¤Î)¤òÆɤ߹þ¤ß¡¢\fBalias\fR¤Ë¤è¤Ã¤ÆÆÃÄꤵ¤ì¤ë\fBkeystore\fR¥¨¥ó¥È¥ê¤Ë³ÊǼ¤·¤Þ¤¹¡£¥Õ¥¡¥¤¥ë¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢\fBstdin\fR¤«¤é¾ÚÌÀ½ñ¤Þ¤¿¤Ï¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤òÆɤ߹þ¤ß¤Þ¤¹¡£
+ .sp
+ \fBkeytool\fR¥³¥Þ¥ó¥É¤Ç¤Ï¡¢X\&.509 v1¡¢v2¡¢v3¤Î¾ÚÌÀ½ñ¡¢¤ª¤è¤ÓPKCS#7·Á¼°¤Î¾ÚÌÀ½ñ¤«¤é¹½À®¤µ¤ì¤Æ¤¤¤ëPKCS#7·Á¼°¤Î¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤ò¥¤¥ó¥Ý¡¼¥È¤Ç¤­¤Þ¤¹¡£¥¤¥ó¥Ý¡¼¥È¤¹¤ë¥Ç¡¼¥¿¤Ï¡¢¥Ð¥¤¥Ê¥êÉä¹æ²½Êý¼°¡¢¤Þ¤¿¤Ï½ÐÎϲÄǽÉä¹æ²½Êý¼°(Base64Éä¹æ²½¤È¤â¸Æ¤Ð¤ì¤ë)¤Î¤É¤Á¤é¤«¤ÇÄ󶡤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£½ÐÎϲÄǽÉä¹æ²½Êý¼°¤Ï¡¢¥¤¥ó¥¿¡¼¥Í¥Ã¥ÈRFC 1421¾ÚÌÀ½ñÉä¹æ²½µ¬³Ê¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤³¤ÎÉä¹æ²½Êý¼°¤Î¾ì¹ç¡¢¾ÚÌÀ½ñ¤Ï\fB\-\fR\fB\-\-\-\-BEGIN\fR¤Ç»Ï¤Þ¤ëʸ»úÎó¤Ç³«»Ï¤µ¤ì¡¢\fB\-\-\-\-\-END\fR¤Ç»Ï¤Þ¤ëʸ»úÎó¤Ç½ªÎ»¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+@@ -791,15 +1001,131 @@
+ .PP
+ \-importpassword
+ .RS 4
+-\fB{\-alias alias} [\-keypass keypass] {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} [\-keypass \fR\fB\fIkeypass\fR\fR\fB] {\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-storepass \fR\fB\fIstorepass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¥Ñ¥¹¥Õ¥ì¡¼¥º¤ò¥¤¥ó¥Ý¡¼¥È¤·¡¢\fBalias\fR¤Ç¼±Ê̤µ¤ì¤ë¿·µ¬\fBKeyStore\&.SecretKeyEntry\fR¤Ë³ÊǼ¤·¤Þ¤¹¡£¥Ñ¥¹¥Õ¥ì¡¼¥º¤Ï¡¢É¸½àÆþÎÏ¥¹¥È¥ê¡¼¥à¤ò²ð¤·¤ÆÄ󶡤Ǥ­¤Þ¤¹¡£¤Þ¤¿¤Ï¡¢¥æ¡¼¥¶¡¼¤Ë¤½¤Î¥×¥í¥ó¥×¥È¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£\fBkeypass\fR¤Ï¡¢¥¤¥ó¥Ý¡¼¥È¤µ¤ì¤ë¥Ñ¥¹¥Õ¥ì¡¼¥º¤ÎÊݸî¤Ë»ÈÍѤµ¤ì¤ë¥Ñ¥¹¥ï¡¼¥É¤Ç¤¹¡£¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£¤³¤Î¤È¤­¡¢[Return]¥­¡¼¤ò²¡¤¹¤È¡¢\fBkeystore\fR¤Î¥Ñ¥¹¥ï¡¼¥É¤ÈƱ¤¸¥Ñ¥¹¥ï¡¼¥É¤¬¸°¤Î¥Ñ¥¹¥ï¡¼¥É¤ËÀßÄꤵ¤ì¤Þ¤¹¡£\fBkeypass\fR¤Ï¡¢6ʸ»ú°Ê¾å¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .PP
+ \-importkeystore
+ .RS 4
+-\fB{\-srcstoretype srcstoretype} {\-deststoretype deststoretype} [\-srcstorepass srcstorepass] [\-deststorepass deststorepass] {\-srcprotected} {\-destprotected} {\-srcalias srcalias {\-destalias destalias} [\-srckeypass srckeypass] } [\-destkeypass destkeypass] {\-noprompt} {\-srcProviderName src_provider_name} {\-destProviderName dest_provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-srcstoretype \fR\fB\fIsrcstoretype\fR\fR\fB} {\-deststoretype \fR\fB\fIdeststoretype\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-srcstorepass \fR\fB\fIsrcstorepass\fR\fR\fB] [\-deststorepass \fR\fB\fIdeststorepass\fR\fR\fB] {\-srcprotected}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-destprotected} \fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-srcalias \fR\fB\fIsrcalias\fR\fR\fB {\-destalias \fR\fB\fIdestalias\fR\fR\fB} [\-srckeypass \fR\fB\fIsrckeypass\fR\fR\fB]} \fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-destkeypass \fR\fB\fIdestkeypass\fR\fR\fB] {\-noprompt}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-srcProviderName \fR\fB\fIsrc_provider_name\fR\fR\fB} {\-destProviderName \fR\fB\fIdest_provider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}} {\-v}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¥½¡¼¥¹¡¦¥­¡¼¥¹¥È¥¢¤«¤é¥¿¡¼¥²¥Ã¥È¡¦¥­¡¼¥¹¥È¥¢¤Ø¡¢Ã±°ì¤Î¥¨¥ó¥È¥ê¤Þ¤¿¤Ï¤¹¤Ù¤Æ¤Î¥¨¥ó¥È¥ê¤ò¥¤¥ó¥Ý¡¼¥È¤·¤Þ¤¹¡£
+ .sp
+ \fB\-srcalias\fR¥ª¥×¥·¥ç¥ó¤¬»ØÄꤵ¤ì¤¿¾ì¹ç¡¢¤³¤Î¥³¥Þ¥ó¥É¤Ï¡¢¤½¤ÎÊÌ̾¤ÇÆÃÄꤵ¤ì¤ëñ°ì¤Î¥¨¥ó¥È¥ê¤ò¥¿¡¼¥²¥Ã¥È¡¦¥­¡¼¥¹¥È¥¢¤Ë¥¤¥ó¥Ý¡¼¥È¤·¤Þ¤¹¡£\fBdestalias\fR·Ðͳ¤Ç¥¿¡¼¥²¥Ã¥ÈÊÌ̾¤¬»ØÄꤵ¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¡¢\fBsrcalias\fR¤¬¥¿¡¼¥²¥Ã¥ÈÊÌ̾¤È¤·¤Æ»ÈÍѤµ¤ì¤Þ¤¹¡£¥½¡¼¥¹¤Î¥¨¥ó¥È¥ê¤¬¥Ñ¥¹¥ï¡¼¥É¤ÇÊݸ¤ì¤Æ¤¤¤¿¾ì¹ç¡¢\fBsrckeypass\fR¤ò»ÈÍѤ·¤Æ¤½¤Î¥¨¥ó¥È¥ê¤¬²óÉü¤µ¤ì¤Þ¤¹¡£\fIsrckeypass\fR¤¬»ØÄꤵ¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¡¢\fBkeytool\fR¥³¥Þ¥ó¥É¤Ï\fBsrcstorepass\fR¤ò»ÈÍѤ·¤Æ¤½¤Î¥¨¥ó¥È¥ê¤ò²óÉü¤·¤è¤¦¤È¤·¤Þ¤¹¡£\fBsrcstorepass\fR¤¬»ØÄꤵ¤ì¤Ê¤«¤Ã¤¿¤«Àµ¤·¤¯¤Ê¤«¤Ã¤¿¾ì¹ç¡¢¥æ¡¼¥¶¡¼¤Ï¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£¥¿¡¼¥²¥Ã¥È¤Î¥¨¥ó¥È¥ê¤Ï\fBdestkeypass\fR¤Ë¤è¤Ã¤ÆÊݸ¤ì¤Þ¤¹¡£\fBdestkeypass\fR¤¬»ØÄꤵ¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¡¢¥¿¡¼¥²¥Ã¥È¡¦¥¨¥ó¥È¥ê¤Ï¥½¡¼¥¹¡¦¥¨¥ó¥È¥ê¤Î¥Ñ¥¹¥ï¡¼¥É¤Ë¤è¤Ã¤ÆÊݸ¤ì¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¤Û¤È¤ó¤É¤Î¥µ¡¼¥É¡¦¥Ñ¡¼¥Æ¥£¡¦¥Ä¡¼¥ë¤Ç¤Ï¡¢PKCS #12¥­¡¼¥¹¥È¥¢¤Ç\fBstorepass\fR¤È\fBkeypass\fR¤¬Æ±¤¸¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤é¤Î¥Ä¡¼¥ë¤ÎPKCS #12¥­¡¼¥¹¥È¥¢¤òºîÀ®¤¹¤ë¾ì¹ç¤Ï¡¢¾ï¤Ë\fB\-destkeypass\fR¤È\fB\-deststorepass\fR¤¬Æ±¤¸¤Ë¤Ê¤ë¤è¤¦¤Ë»ØÄꤷ¤Þ¤¹¡£
+@@ -814,16 +1140,72 @@
+ .PP
+ \-printcertreq
+ .RS 4
+-\fB{\-file file}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-file \fR\fB\fIfile\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ PKCS#10·Á¼°¤Î¾ÚÌÀ½ñ¥ê¥¯¥¨¥¹¥È¤ÎÆâÍƤò½ÐÎϤ·¤Þ¤¹¡£¤³¤Î¥ê¥¯¥¨¥¹¥È¤Ï¡¢\fBkeytool\fR
+ \fB\-certreq\fR¥³¥Þ¥ó¥É¤ÇÀ¸À®¤Ç¤­¤Þ¤¹¡£¤³¤Î¥³¥Þ¥ó¥É¤Ï¡¢¥Õ¥¡¥¤¥ë¤«¤é¥ê¥¯¥¨¥¹¥È¤òÆɤ߼è¤ê¤Þ¤¹¡£¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¡¢¥ê¥¯¥¨¥¹¥È¤Ïɸ½àÆþÎϤ«¤éÆɤ߼è¤é¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ \-certreq
+ .RS 4
+-\fB{\-alias alias} {\-dname dname} {\-sigalg sigalg} {\-file certreq_file} [\-keypass keypass] {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} {\-dname \fR\fB\fIdname\fR\fR\fB} {\-sigalg \fR\fB\fIsigalg\fR\fR\fB} {\-file \fR\fB\fIcertreq_file\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-keypass \fR\fB\fIkeypass\fR\fR\fB] {\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-storepass \fR\fB\fIstorepass\fR\fR\fB] {\-providerName \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ PKCS#10·Á¼°¤ò»ÈÍѤ·¤Æ¾ÚÌÀ½ñ½ð̾¥ê¥¯¥¨¥¹¥È(CSR)¤òÀ¸À®¤·¤Þ¤¹¡£
+ .sp
+ CSR¤Ï¡¢¾ÚÌÀ½ñȯ¹Ô¶É(CA)¤ËÁ÷¿®¤¹¤ë¤³¤È¤òÌÜŪ¤È¤·¤¿¤â¤Î¤Ç¤¹¡£CA¤Ï¡¢¾ÚÌÀ½ñÍ×µá¼Ô¤ò(Ä̾ï¤Ï¥ª¥Õ¥é¥¤¥ó¤Ç)ǧ¾Ú¤·¡¢¾ÚÌÀ½ñ¤Þ¤¿¤Ï¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤òÁ÷¤êÊÖ¤·¤Þ¤¹¡£¤³¤Î¾ÚÌÀ½ñ¤Þ¤¿¤Ï¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤Ï¡¢¥­¡¼¥¹¥È¥¢Æâ¤Î´û¸¤Î¾ÚÌÀ½ñ¥Á¥§¡¼¥ó(ºÇ½é¤Ï1¤Ä¤Î¼«¸Ê½ð̾¾ÚÌÀ½ñ¤«¤é¹½À®¤µ¤ì¤ë)¤ËÃÖ¤­´¹¤¨¤Æ»ÈÍѤ·¤Þ¤¹¡£
+@@ -839,8 +1221,46 @@
+ .PP
+ \-exportcert
+ .RS 4
+-\fB{\-alias alias} {\-file cert_file} {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-rfc} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} {\-file \fR\fB\fIcert_file\fR\fR\fB} {\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-storepass \fR\fB\fIstorepass\fR\fR\fB] {\-providerName \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-rfc} {\-v} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ \fIalias\fR¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¾ÚÌÀ½ñ¤ò¥­¡¼¥¹¥È¥¢¤«¤éÆɤ߹þ¤ß¡¢¥Õ¥¡¥¤¥ëcert_file¤Ë³ÊǼ¤·¤Þ¤¹¡£¥Õ¥¡¥¤¥ë¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢\fBstdout\fR¤Ë¾ÚÌÀ½ñ¤¬½ÐÎϤµ¤ì¤Þ¤¹¡£
+ .sp
+ ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¾ÚÌÀ½ñ¤Ï¥Ð¥¤¥Ê¥êÉä¹æ²½¤Ç½ÐÎϤµ¤ì¤Þ¤¹¡£\fB\-rfc\fR¥ª¥×¥·¥ç¥ó¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢½ÐÎϲÄǽÉä¹æ²½Êý¼°¤Î½ÐÎϤϥ¤¥ó¥¿¡¼¥Í¥Ã¥ÈRFC 1421¾ÚÌÀ½ñÉä¹æ²½µ¬³Ê¤ÇÄêµÁ¤µ¤ì¤Þ¤¹¡£
+@@ -852,8 +1272,46 @@
+ .PP
+ \-list
+ .RS 4
+-\fB{\-alias alias} {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v | \-rfc} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} {\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB} [\-storepass \fR\fB\fIstorepass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerName \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v | \-rfc} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ \fBalias\fR¤ÇÆÃÄꤵ¤ì¤ë¥­¡¼¥¹¥È¥¢¡¦¥¨¥ó¥È¥ê¤ÎÆâÍƤò\fBstdout\fR¤Ë½ÐÎϤ·¤Þ¤¹¡£\fBalias\fR¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢¥­¡¼¥¹¥È¥¢Á´ÂΤÎÆâÍƤ¬É½¼¨¤µ¤ì¤Þ¤¹¡£
+ .sp
+ ¤³¤Î¥³¥Þ¥ó¥É¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¾ÚÌÀ½ñ¤ÎSHA1¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤òɽ¼¨¤·¤Þ¤¹¡£
+@@ -864,8 +1322,26 @@
+ .PP
+ \-printcert
+ .RS 4
+-\fB{\-file cert_file | \-sslserver host[:port]} {\-jarfile JAR_file {\-rfc} {\-v} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-file \fR\fB\fIcert_file\fR\fR\fB | \-sslserver \fR\fB\fIhost\fR\fR\fB[:\fR\fB\fIport\fR\fR\fB]} {\-jarfile \fR\fB\fIJAR_file\fR\fR\fB {\-rfc} {\-v}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¥Õ¥¡¥¤¥ëcert_file¡¢host:port¤Ë¤¢¤ëSSL¥µ¡¼¥Ð¡¼¡¢¤Þ¤¿¤Ï½ð̾ÉÕ¤­JAR¥Õ¥¡¥¤¥ë\fBJAR_file\fR(\fB\-jarfile\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄê)¤«¤é¾ÚÌÀ½ñ¤òÆɤ߹þ¤ß¡¢¿Í´Ö¤¬Æɤळ¤È¤Î¤Ç¤­¤ë·Á¼°¤Ç¾ÚÌÀ½ñ¤ÎÆâÍƤòɽ¼¨¤·¤Þ¤¹¡£¥Ý¡¼¥È¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢É¸½à¤ÎHTTPS¥Ý¡¼¥È443¤¬ÁÛÄꤵ¤ì¤Þ¤¹¡£\fB\-sslserver\fR¤ª¤è¤Ó\-file¥ª¥×¥·¥ç¥ó¤òƱ»þ¤Ë»ØÄꤹ¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢¥¨¥é¡¼¤¬Êó¹ð¤µ¤ì¤Þ¤¹¡£¥ª¥×¥·¥ç¥ó¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢\fBstdin\fR¤«¤é¾ÚÌÀ½ñ¤òÆɤ߹þ¤ß¤Þ¤¹¡£
+ .sp
+ \fB\-rfc\fR¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢\fBkeytool\fR¥³¥Þ¥ó¥É¤Ï¡¢¥¤¥ó¥¿¡¼¥Í¥Ã¥ÈRFC 1421¾ÚÌÀ½ñÉä¹æ²½É¸½à¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë¡¢PEM¥â¡¼¥É¤Ç¾ÚÌÀ½ñ¤ò½ÐÎϤ·¤Þ¤¹¡£¥¤¥ó¥¿¡¼¥Í¥Ã¥ÈRFC 1421¾ÚÌÀ½ñÉä¹æ²½µ¬³Ê¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+@@ -881,8 +1357,16 @@
+ .PP
+ \-printcrl
+ .RS 4
+-\fB\-file crl_ {\-v}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB\-file \fR\fB\fIcrl_\fR\fR\fB {\-v}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¥Õ¥¡¥¤¥ë\fBcrl_\fR¤«¤é¾ÚÌÀ½ñ¼º¸ú¥ê¥¹¥È(CRL)¤òÆɤ߹þ¤ß¤Þ¤¹¡£CRL¤Ï¡¢È¯¹Ô¤·¤¿CA¤Ë¤è¤Ã¤Æ¼º¸ú¤µ¤ì¤¿¥Ç¥¸¥¿¥ë¾ÚÌÀ½ñ¤Î¥ê¥¹¥È¤Ç¤¹¡£CA¤Ï¡¢\fBcrl_\fR¤òÀ¸À®¤·¤Þ¤¹¡£
+ .sp
+ \fBÃí°Õ:\fR
+@@ -891,15 +1375,91 @@
+ .PP
+ \-storepasswd
+ .RS 4
+-\fB[\-new new_storepass] {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-new \fR\fB\fInew_storepass\fR\fR\fB] {\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-storepass \fR\fB\fIstorepass\fR\fR\fB] {\-providerName \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ ¥­¡¼¥¹¥È¥¢¤ÎÆâÍƤÎÀ°¹çÀ­¤òÊݸ¤ë¤¿¤á¤Ë»ÈÍѤ¹¤ë¥Ñ¥¹¥ï¡¼¥É¤òÊѹ¹¤·¤Þ¤¹¡£\fBnew_storepass\fR¤Ë¤Ï¡¢¿·¤·¤¤¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄꤷ¤Þ¤¹¡£new_storepass¤Ï¡¢6ʸ»ú°Ê¾å¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .PP
+ \-keypasswd
+ .RS 4
+-\fB{\-alias alias} [\-keypass old_keypass] [\-new new_keypass] {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} [\-keypass \fR\fB\fIold_keypass\fR\fR\fB] [\-new \fR\fB\fInew_keypass\fR\fR\fB] {\-storetype \fR\fB\fIstoretype\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-keystore \fR\fB\fIkeystore\fR\fR\fB} [\-storepass \fR\fB\fIstorepass\fR\fR\fB] {\-providerName \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}} {\-v}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ \fBalias\fR¤Ë¤è¤Ã¤ÆÆÃÄꤵ¤ì¤ëÈó¸ø³«/ÈëÌ©¸°¤òÊݸ¤ë¤¿¤á¤Î¥Ñ¥¹¥ï¡¼¥É¤ò¡¢\fBold_keypass\fR¤«¤é\fBnew_keypass\fR¤ËÊѹ¹¤·¤Þ¤¹¡£new_keypass¤Ï¡¢6ʸ»ú°Ê¾å¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .sp
+ ¥³¥Þ¥ó¥É¹Ô¤Ç\fB\-keypass\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Æ¤ª¤é¤º¡¢¸°¤Î¥Ñ¥¹¥ï¡¼¥É¤¬¥­¡¼¥¹¥È¥¢¤Î¥Ñ¥¹¥ï¡¼¥É¤È°Û¤Ê¤ë¾ì¹ç¤Ï¡¢¸°¤Î¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£
+@@ -909,15 +1469,91 @@
+ .PP
+ \-delete
+ .RS 4
+-\fB[\-alias alias] {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[\-alias \fR\fB\fIalias\fR\fR\fB] {\-storetype \fR\fB\fIstoretype\fR\fR\fB} {\-keystore \fR\fB\fIkeystore\fR\fR\fB} [\-storepass \fR\fB\fIstorepass\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerName \fR\fB\fIprovider_name\fR\fR\fB} \fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-v} {\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ \fBalias\fR¤Ë¤è¤Ã¤ÆÆÃÄꤵ¤ì¤ë¥¨¥ó¥È¥ê¤ò¥­¡¼¥¹¥È¥¢¤«¤éºï½ü¤·¤Þ¤¹¡£¥³¥Þ¥ó¥É¹Ô¤ÇÊÌ̾¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢ÊÌ̾¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ \-changealias
+ .RS 4
+-\fB{\-alias alias} [\-destalias destalias] [\-keypass keypass] {\-storetype storetype} {\-keystore keystore} [\-storepass storepass] {\-providerName provider_name} {\-providerClass provider_class_name {\-providerArg provider_arg}} {\-v} {\-protected} {\-Jjavaoption}\fR
+ .sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-alias \fR\fB\fIalias\fR\fR\fB} [\-destalias \fR\fB\fIdestalias\fR\fR\fB] [\-keypass \fR\fB\fIkeypass\fR\fR\fB] {\-storetype \fR\fB\fIstoretype\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-keystore \fR\fB\fIkeystore\fR\fR\fB} [\-storepass \fR\fB\fIstorepass\fR\fR\fB] {\-providerName \fR\fB\fIprovider_name\fR\fR\fB}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-providerClass \fR\fB\fIprovider_class_name\fR\fR\fB {\-providerArg \fR\fB\fIprovider_arg\fR\fR\fB}} {\-v}\fR
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB{\-protected} {\-Jjavaoption}\fR
++.fi
++.if n \{\
++.RE
++.\}
+ »ØÄꤵ¤ì¤¿\fBalias\fR¤«¤é¿·¤·¤¤ÊÌ̾\fBdestalias\fR¤Ø¡¢´û¸¤Î¥­¡¼¥¹¥È¥¢¡¦¥¨¥ó¥È¥ê¤ò°ÜÆ°¤·¤Þ¤¹¡£¥¿¡¼¥²¥Ã¥ÈÊÌ̾¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¡¢¥¿¡¼¥²¥Ã¥ÈÊÌ̾¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£¸µ¤Î¥¨¥ó¥È¥ê¤¬¥¨¥ó¥È¥ê¡¦¥Ñ¥¹¥ï¡¼¥É¤ÇÊݸ¤ì¤Æ¤¤¤¿¾ì¹ç¡¢\fB\-keypass\fR¥ª¥×¥·¥ç¥ó¤Ç¤½¤Î¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£¸°¥Ñ¥¹¥ï¡¼¥É¤¬»ØÄꤵ¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¡¢\fBstorepass\fR(»ØÄꤵ¤ì¤¿¾ì¹ç)¤¬¤Þ¤º»î¤ß¤é¤ì¤Þ¤¹¡£¤½¤Î»î¤ß¤¬¼ºÇÔ¤¹¤ë¤È¡¢¥æ¡¼¥¶¡¼¤Ï¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+@@ -971,7 +1607,7 @@
+ °Ê¹ß¤Ç¤Ï¡¢¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤¤¤Ç\fB\-genkeypair\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤¿¤â¤Î¤È¤·¤ÆÎã¤ò¼¨¤·¤Þ¤¹¡£¾ðÊó¤ÎÆþÎϤòµá¤á¤é¤ì¤¿¾ì¹ç¤Ï¡¢ºÇ½é¤Ë¼¨¤·¤¿\fB\-genkeypair\fR¥³¥Þ¥ó¥É¤ÎÃͤòÆþÎϤ·¤¿¤â¤Î¤È¤·¤Þ¤¹¡£¤¿¤È¤¨¤Ð¼±ÊÌ̾¤Ë¤Ï\fBcn=Mark Jones\fR¡¢\fBou=Java\fR¡¢\fBo=Oracle\fR¡¢\fBc=US\fR¤È»ØÄꤷ¤Þ¤¹¡£
+ .SS "CA¤«¤é¤Î½ð̾ÉÕ¤­¾ÚÌÀ½ñ¤Î¥ê¥¯¥¨¥¹¥È"
+ .PP
+-¼«¸Ê½ð̾¾ÚÌÀ½ñ¤òºîÀ®¤¹¤ë¸°¤Î¥Ú¥¢¤ÎÀ¸À®¡£¾ÚÌÀ½ñ¤Ë¾ÚÌÀ½ñȯ¹Ô¶É(CA)¤Î½ð̾¤¬ÉÕ¤¤¤Æ¤¤¤ì¤Ð¡¢Â¾¤Î¥æ¡¼¥¶¡¼¤«¤é¾ÚÌÀ½ñ¤¬¿®Íꤵ¤ì¤ë²ÄǽÀ­¤â¹â¤¯¤Ê¤ê¤Þ¤¹¡£CA¤Î½ð̾¤ò¼èÆÀ¤¹¤ë¤Ë¤Ï¡¢¤Þ¤º¡¢¾ÚÌÀ½ñ½ð̾¥ê¥¯¥¨¥¹¥È(CSR)¤òÀ¸À®¤·¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¼¡¤Î¤è¤¦¤Ë¤·¤Þ¤¹¡£
++¼«¸Ê½ð̾¾ÚÌÀ½ñ¤òºîÀ®¤¹¤ë¸°¤Î¥Ú¥¢¤ÎÀ¸À®¡£¾ÚÌÀ½ñ¤Ëǧ¾Ú¶É(CA)¤Î½ð̾¤¬ÉÕ¤¤¤Æ¤¤¤ì¤Ð¡¢Â¾¤Î¥æ¡¼¥¶¡¼¤«¤é¾ÚÌÀ½ñ¤¬¿®Íꤵ¤ì¤ë²ÄǽÀ­¤â¹â¤¯¤Ê¤ê¤Þ¤¹¡£CA¤Î½ð̾¤ò¼èÆÀ¤¹¤ë¤Ë¤Ï¡¢¤Þ¤º¡¢¾ÚÌÀ½ñ½ð̾¥ê¥¯¥¨¥¹¥È(CSR)¤òÀ¸À®¤·¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¼¡¤Î¤è¤¦¤Ë¤·¤Þ¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+@@ -1015,7 +1651,7 @@
+ .PP
+ \fBcacerts\fR¥­¡¼¥¹¥È¥¢¡¦¥Õ¥¡¥¤¥ë¤Ï¡¢¤¤¤¯¤Ä¤«¤ÎVeriSign¥ë¡¼¥ÈCA¾ÚÌÀ½ñ¤ò´Þ¤ó¤À¾õÂ֤ǽв٤µ¤ì¤Æ¤¤¤ë¤Î¤Ç¡¢VeriSign¤Î¾ÚÌÀ½ñ¤ò¡¢¿®Íê¤Ç¤­¤ë¾ÚÌÀ½ñ¤È¤·¤Æ¥­¡¼¥¹¥È¥¢Æâ¤Ë¥¤¥ó¥Ý¡¼¥È¤¹¤ëɬÍפ¬¤Ê¤¤¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£¤¿¤À¤·¡¢Â¾¤ÎCA¤ËÂФ·¤Æ½ð̾ÉÕ¤­¾ÚÌÀ½ñ¤ò¥ê¥¯¥¨¥¹¥È¤·¤Æ¤¤¤Æ¡¢¤³¤ÎCA¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤¬¡¢\fBcacerts\fR¤Ë¤Þ¤ÀÄɲ䵤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢³ºÅö¤¹¤ëCA¤«¤é¤Î¾ÚÌÀ½ñ¤ò¡¢¡Ö¿®Íê¤Ç¤­¤ë¾ÚÌÀ½ñ¡×¤È¤·¤Æ¥¤¥ó¥Ý¡¼¥È¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .PP
+-Ä̾CA¤«¤é¤Î¾ÚÌÀ½ñ¤Ï¡¢¼«¸Ê½ð̾¾ÚÌÀ½ñ¡¢¤Þ¤¿¤Ï¾¤ÎCA¤Ë¤è¤Ã¤Æ½ð̾¤µ¤ì¤¿¾ÚÌÀ½ñ¤Ç¤¹(¸å¼Ô¤Î¾ì¹ç¤Ï¡¢³ºÅö¤¹¤ë¾¤ÎCA¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤¬É¬Í×)¡£ABC, Inc\&.,¤¬CA¤Ç¡¢ABC¤«¤é¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ç¤¢¤ëA\fBBCCA\&.cer\fR¤È¤¤¤¦Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤ò¼èÆÀ¤·¤¿¤È¤·¤Þ¤¹(¤³¤Î¾ÚÌÀ½ñ¤ÏCA¤Î¸ø³«¸°¤òǧ¾Ú¤·¤Þ¤¹)¡£¿®Íê¤Ç¤­¤ë¾ÚÌÀ½ñ¤È¤·¤Æ¾ÚÌÀ½ñ¤ò¥¤¥ó¥Ý¡¼¥È¤¹¤ë¤È¤­¤Ï¡¢¾ÚÌÀ½ñ¤¬Í­¸ú¤Ç¤¢¤ë¤³¤È¤ò³Îǧ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤Þ¤º¡¢\fBkeytool \-printcert\fR¥³¥Þ¥ó¥É¤Þ¤¿¤Ï\fB\-noprompt\fR¥ª¥×¥·¥ç¥ó¤Ê¤·¤Î\fBkeytool \-importcert\fR¥³¥Þ¥ó¥É¤Ç¤½¤ì¤òɽ¼¨¤·¡¢É½¼¨¤µ¤ì¤¿¾ÚÌÀ½ñ¤Î¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤¬´üÂÔ¤µ¤ì¤ë¤â¤Î¤È°ìÃפ¹¤ë¤«¤É¤¦¤«¤ò³Îǧ¤·¤Þ¤¹¡£¾ÚÌÀ½ñ¤òÁ÷¿®¤·¤¿¿Íʪ¤ËÏ¢Íí¤·¡¢¤³¤Î¿Íʪ¤¬Ä󼨤·¤¿(¤Þ¤¿¤Ï¥»¥­¥å¥¢¤Ê¸ø³«¸°¤Î¥ê¥Ý¥¸¥È¥ê¤Ë¤è¤Ã¤ÆÄ󼨤µ¤ì¤ë)¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤È¡¢¾å¤Î¥³¥Þ¥ó¥É¤Çɽ¼¨¤µ¤ì¤¿¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤È¤òÈæ³Ó¤·¤Þ¤¹¡£¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤¬°ìÃפ¹¤ì¤Ð¡¢Á÷¿®ÅÓÃæ¤Ç¾¤Î²¿¼Ô¤«(¹¶·â¼Ô¤Ê¤É)¤Ë¤è¤ë¾ÚÌÀ½ñ¤Î¤¹¤êÂؤ¨¤¬¹Ô¤ï¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò³Îǧ¤Ç¤­¤Þ¤¹¡£Á÷¿®ÅÓÃæ¤Ç¤³¤Î¼ï¤Î¹¶·â¤¬¹Ô¤ï¤ì¤Æ¤¤¤¿¾ì¹ç¡¢¥Á¥§¥Ã¥¯¤ò¹Ô¤ï¤º¤Ë¾ÚÌÀ½ñ¤ò¥¤¥ó¥Ý¡¼¥È¤¹¤ë¤È¡¢¹¶·â¼Ô¤Ë¤è¤Ã¤Æ½ð̾¤µ¤ì¤¿¤¹¤Ù¤Æ¤Î¤â¤Î¤ò¿®Íꤹ¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£
++Ä̾CA¤«¤é¤Î¾ÚÌÀ½ñ¤Ï¡¢¼«¸Ê½ð̾¾ÚÌÀ½ñ¡¢¤Þ¤¿¤Ï¾¤ÎCA¤Ë¤è¤Ã¤Æ½ð̾¤µ¤ì¤¿¾ÚÌÀ½ñ¤Ç¤¹(¸å¼Ô¤Î¾ì¹ç¤Ï¡¢³ºÅö¤¹¤ë¾¤ÎCA¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤¬É¬Í×)¡£ABC, Inc\&.,¤¬CA¤Ç¡¢ABC¤«¤é¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ç¤¢¤ëA\fBBCCA\&.cer\fR¤È¤¤¤¦Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤ò¼èÆÀ¤·¤¿¤È¤·¤Þ¤¹(¤³¤Î¾ÚÌÀ½ñ¤ÏCA¤Î¸ø³«¸°¤òǧ¾Ú¤·¤Þ¤¹)¡£¿®Íê¤Ç¤­¤ë¾ÚÌÀ½ñ¤È¤·¤Æ¾ÚÌÀ½ñ¤ò¥¤¥ó¥Ý¡¼¥È¤¹¤ë¤È¤­¤Ï¡¢¾ÚÌÀ½ñ¤¬Í­¸ú¤Ç¤¢¤ë¤³¤È¤ò³Îǧ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤Þ¤º¡¢¾ÚÌÀ½ñ¤ÎÆâÍƤòɽ¼¨¤·¡¢\fBkeytool \-printcert\fR¥³¥Þ¥ó¥É¤ò»ÈÍѤ¹¤ë¤«¡¢¤Þ¤¿¤Ï\fB\-noprompt\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤¤¤Ç\fBkeytool \-importcert\fR¥³¥Þ¥ó¥É¤ò»ÈÍѤ·¡¢É½¼¨¤µ¤ì¤¿¾ÚÌÀ½ñ¤Î¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤¬¡¢´üÂÔ¤µ¤ì¤ë¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤È°ìÃפ¹¤ë¤«¤É¤¦¤«¤ò³Îǧ¤·¤Þ¤¹¡£¾ÚÌÀ½ñ¤òÁ÷¿®¤·¤¿¿Íʪ¤ËÏ¢Íí¤·¡¢¤³¤Î¿Íʪ¤¬Ä󼨤·¤¿(¤Þ¤¿¤Ï°ÂÁ´¤Ê¸ø³«¸°¤Î¥ê¥Ý¥¸¥È¥ê¤Ë¤è¤Ã¤ÆÄ󼨤µ¤ì¤ë)¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤È¡¢¾å¤Î¥³¥Þ¥ó¥É¤Çɽ¼¨¤µ¤ì¤¿¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤È¤òÈæ³Ó¤·¤Þ¤¹¡£¥Õ¥£¥ó¥¬¡¼¥×¥ê¥ó¥È¤¬°ìÃפ¹¤ì¤Ð¡¢Á÷¿®ÅÓÃæ¤Ç¾¤Î²¿¼Ô¤«(¹¶·â¼Ô¤Ê¤É)¤Ë¤è¤ë¾ÚÌÀ½ñ¤Î¤¹¤êÂؤ¨¤¬¹Ô¤ï¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò³Îǧ¤Ç¤­¤Þ¤¹¡£Á÷¿®ÅÓÃæ¤Ç¤³¤Î¼ï¤Î¹¶·â¤¬¹Ô¤ï¤ì¤Æ¤¤¤¿¾ì¹ç¡¢¥Á¥§¥Ã¥¯¤ò¹Ô¤ï¤º¤Ë¾ÚÌÀ½ñ¤ò¥¤¥ó¥Ý¡¼¥È¤¹¤ë¤È¡¢¹¶·â¼Ô¤Ë¤è¤Ã¤Æ½ð̾¤µ¤ì¤¿¤¹¤Ù¤Æ¤Î¤â¤Î¤ò¿®Íꤹ¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£
+ .PP
+ ¾ÚÌÀ½ñ¤¬Í­¸ú¤Ç¤¢¤ë¤È¿®Íꤹ¤ë¾ì¹ç¤Ï¡¢¼¡¤Î¥³¥Þ¥ó¥É¤Ç¥­¡¼¥¹¥È¥¢¤ËÄɲäǤ­¤Þ¤¹¡£
+ .sp
+@@ -1182,7 +1818,7 @@
+ .if n \{\
+ .RE
+ .\}
+-¥Ñ¥¹¥ï¡¼¥É¤¬¡¢\fBdukekeypasswd\fR¤«¤é\fBnewpass\fR¤ËÊѹ¹¤µ¤ì¤Þ¤¹¡£¥Æ¥¹¥È¤òÌÜŪ¤È¤¹¤ë¾ì¹ç¡¢¤Þ¤¿¤Ï°ÂÁ´¤Ç¤¢¤ë¤³¤È¤¬¤ï¤«¤Ã¤Æ¤¤¤ë¥·¥¹¥Æ¥à¤Ç¼Â¹Ô¤¹¤ë¾ì¹ç°Ê³°¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤ä¥¹¥¯¥ê¥×¥È¤Ç¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄꤷ¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£É¬Íפʥѥ¹¥ï¡¼¥É¤Î¥ª¥×¥·¥ç¥ó¤ò¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£
++¥Ñ¥¹¥ï¡¼¥É¤¬¡¢\fBdukekeypasswd\fR¤«¤é\fBnewpass\fR¤ËÊѹ¹¤µ¤ì¤Þ¤¹¡£¥Æ¥¹¥ÈÌÜŪ¤Î¾ì¹ç¡¢¤Þ¤¿¤Ï¥»¥­¥å¥¢¤Ê¥·¥¹¥Æ¥à¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç°Ê³°¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤ä¥¹¥¯¥ê¥×¥È¤Ç¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄꤷ¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£É¬Íפʥѥ¹¥ï¡¼¥É¤Î¥ª¥×¥·¥ç¥ó¤ò¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ ¥­¡¼¥¹¥È¥¢¤Î¼ÂÁõ
+@@ -1260,9 +1896,9 @@
+ .sp
+ \fB¥¨¥ó¥Æ¥£¥Æ¥£\fR: ¥¨¥ó¥Æ¥£¥Æ¥£¤Ï¡¢¿Í¡¢ÁÈ¿¥¡¢¥×¥í¥°¥é¥à¡¢¥³¥ó¥Ô¥å¡¼¥¿¡¢´ë¶È¡¢¶ä¹Ô¤Ê¤É¡¢°ìÄê¤ÎÅٹ礤¤Ç¿®Íê¤ÎÂоݤȤʤëÍÍ¡¹¤Ê¤â¤Î¤ò»Ø¤·¤Þ¤¹¡£
+ .sp
+-¸ø³«¸°°Å¹æ²½¤Ç¤Ï¡¢¥æ¡¼¥¶¡¼¤Î¸ø³«¸°¤Ë¥¢¥¯¥»¥¹¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£Â絬ÌϤʥͥåȥ¥¯´Ä¶­¤Ç¤Ï¡¢¸ß¤¤¤ËÄÌ¿®¤·¤Æ¤¤¤ë¥¨¥ó¥Æ¥£¥Æ¥£´Ö¤Ç°ÊÁ°¤Î´Ø·¸¤¬°ú³¤­³ÎΩ¤µ¤ì¤Æ¤¤¤ë¤È²¾Äꤷ¤¿¤ê¡¢»ÈÍѤµ¤ì¤Æ¤¤¤ë¤¹¤Ù¤Æ¤Î¸ø³«¸°¤ò¼ý¤á¤¿¿®Íê¤Ç¤­¤ë¥ê¥Ý¥¸¥È¥ê¤¬Â¸ºß¤¹¤ë¤È²¾Äꤷ¤¿¤ê¤¹¤ë¤³¤È¤ÏÉÔ²Äǽ¤Ç¤¹¡£¤³¤Î¤è¤¦¤Ê¸ø³«¸°¤ÎÇÛÉۤ˴ؤ¹¤ëÌäÂê¤ò²ò·è¤¹¤ë¤¿¤á¤Ë¾ÚÌÀ½ñ¤¬¹Í°Æ¤µ¤ì¤Þ¤·¤¿¡£¸½ºß¤Ç¤Ï¡¢¾ÚÌÀ½ñȯ¹Ô¶É(CA)¤¬¿®Íê¤Ç¤­¤ëÂè»°¼Ô¤È¤·¤Æµ¡Ç½¤·¤Þ¤¹¡£CA¤Ï¡¢Â¾¤Î¥¨¥ó¥Æ¥£¥Æ¥£¤Î¾ÚÌÀ½ñ¤Ë½ð̾¤¹¤ë(ȯ¹Ô¤¹¤ë)¹Ô°Ù¤ò¡¢¿®Íꤷ¤ÆǤ¤µ¤ì¤Æ¤¤¤ë¥¨¥ó¥Æ¥£¥Æ¥£(´ë¶È¤Ê¤É)¤Ç¤¹¡£CA¤ÏˡΧ¾å¤Î·ÀÌó¤Ë¹´Â«¤µ¤ì¤ë¤Î¤Ç¡¢Í­¸ú¤«¤Ä¿®Íê¤Ç¤­¤ë¾ÚÌÀ½ñ¤Î¤ß¤òºîÀ®¤¹¤ë¤â¤Î¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£VeriSign¡¢Thawte¡¢Entrust¤ò¤Ï¤¸¤á¡¢Â¿¤¯¤Î¸øŪ¤Ê¾ÚÌÀ½ñȯ¹Ô¶É¤¬Â¸ºß¤·¤Þ¤¹¡£
++¸ø³«¸°°Å¹æ²½¤Ç¤Ï¡¢¥æ¡¼¥¶¡¼¤Î¸ø³«¸°¤Ë¥¢¥¯¥»¥¹¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£Â絬ÌϤʥͥåȥ¥¯´Ä¶­¤Ç¤Ï¡¢¸ß¤¤¤ËÄÌ¿®¤·¤Æ¤¤¤ë¥¨¥ó¥Æ¥£¥Æ¥£´Ö¤Ç°ÊÁ°¤Î´Ø·¸¤¬°ú³¤­³ÎΩ¤µ¤ì¤Æ¤¤¤ë¤È²¾Äꤷ¤¿¤ê¡¢»ÈÍѤµ¤ì¤Æ¤¤¤ë¤¹¤Ù¤Æ¤Î¸ø³«¸°¤ò¼ý¤á¤¿¿®Íê¤Ç¤­¤ë¥ê¥Ý¥¸¥È¥ê¤¬Â¸ºß¤¹¤ë¤È²¾Äꤷ¤¿¤ê¤¹¤ë¤³¤È¤ÏÉÔ²Äǽ¤Ç¤¹¡£¤³¤Î¤è¤¦¤Ê¸ø³«¸°¤ÎÇÛÉۤ˴ؤ¹¤ëÌäÂê¤ò²ò·è¤¹¤ë¤¿¤á¤Ë¾ÚÌÀ½ñ¤¬¹Í°Æ¤µ¤ì¤Þ¤·¤¿¡£¸½ºß¤Ç¤Ï¡¢Ç§¾Ú¶É(CA)¤¬¿®Íê¤Ç¤­¤ëÂè»°¼Ô¤È¤·¤Æµ¡Ç½¤·¤Þ¤¹¡£CA¤Ï¡¢Â¾¤Î¥¨¥ó¥Æ¥£¥Æ¥£¤Î¾ÚÌÀ½ñ¤Ë½ð̾¤¹¤ë(ȯ¹Ô¤¹¤ë)¹Ô°Ù¤ò¡¢¿®Íꤷ¤ÆǤ¤µ¤ì¤Æ¤¤¤ë¥¨¥ó¥Æ¥£¥Æ¥£(´ë¶È¤Ê¤É)¤Ç¤¹¡£CA¤ÏˡΧ¾å¤Î·ÀÌó¤Ë¹´Â«¤µ¤ì¤ë¤Î¤Ç¡¢Í­¸ú¤«¤Ä¿®Íê¤Ç¤­¤ë¾ÚÌÀ½ñ¤Î¤ß¤òºîÀ®¤¹¤ë¤â¤Î¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£VeriSign¡¢Thawte¡¢Entrust¤ò¤Ï¤¸¤á¡¢Â¿¤¯¤Î¸øŪ¤Êǧ¾Ú¶É¤¬Â¸ºß¤·¤Þ¤¹¡£
+ .sp
+-Microsoft¤Îǧ¾Ú¥µ¡¼¥Ð¡¼¡¢Entrust¤ÎCAÀ½Éʤʤɤò½ê°ÁÈ¿¥Æâ¤ÇÍøÍѤ¹¤ì¤Ð¡¢Æȼ«¤Î¾ÚÌÀ½ñȯ¹Ô¶É¤ò±¿±Ä¤¹¤ë¤³¤È¤â²Äǽ¤Ç¤¹¡£\fBkeytool\fR¥³¥Þ¥ó¥É¤ò»ÈÍѤ¹¤ë¤È¡¢¾ÚÌÀ½ñ¤Îɽ¼¨¡¢¥¤¥ó¥Ý¡¼¥È¤ª¤è¤Ó¥¨¥¯¥¹¥Ý¡¼¥È¤ò¹Ô¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤Þ¤¿¡¢¼«¸Ê½ð̾¾ÚÌÀ½ñ¤òÀ¸À®¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£
++Microsoft¤Îǧ¾Ú¥µ¡¼¥Ð¡¼¡¢Entrust¤ÎCAÀ½Éʤʤɤò½ê°ÁÈ¿¥Æâ¤ÇÍøÍѤ¹¤ì¤Ð¡¢Æȼ«¤Îǧ¾Ú¶É¤ò±¿±Ä¤¹¤ë¤³¤È¤â²Äǽ¤Ç¤¹¡£\fBkeytool\fR¥³¥Þ¥ó¥É¤ò»ÈÍѤ¹¤ë¤È¡¢¾ÚÌÀ½ñ¤Îɽ¼¨¡¢¥¤¥ó¥Ý¡¼¥È¤ª¤è¤Ó¥¨¥¯¥¹¥Ý¡¼¥È¤ò¹Ô¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤Þ¤¿¡¢¼«¸Ê½ð̾¾ÚÌÀ½ñ¤òÀ¸À®¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£
+ .sp
+ ¸½ºß¡¢\fBkeytool\fR¥³¥Þ¥ó¥É¤ÏX\&.509¾ÚÌÀ½ñ¤òÂоݤˤ·¤Æ¤¤¤Þ¤¹¡£
+ .RE
+@@ -1312,7 +1948,7 @@
+ .sp
+ ¸°¤ò½é¤á¤ÆºîÀ®¤¹¤ë¤È¡¢¼«¸Ê½ð̾¾ÚÌÀ½ñ¤È¤¤¤¦1¤Ä¤ÎÍ×ÁǤΤߤò´Þ¤à¥Á¥§¡¼¥ó¤¬³«»Ï¤µ¤ì¤Þ¤¹¡£¥³¥Þ¥ó¥É¤Î\fB\-genkeypair\fR¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ïȯ¹Ô¼Ô(½ð̾¼Ô)¤¬¼çÂΤÈƱ¤¸¤Ç¤¹¡£¼çÂΤϡ¢¤½¤Î¸ø³«¸°¤¬¾ÚÌÀ½ñ¤Ë¤è¤Ã¤Æǧ¾Ú¤µ¤ì¤ë¥¨¥ó¥Æ¥£¥Æ¥£¤Ç¤¹¡£\fB\-genkeypair\fR¥³¥Þ¥ó¥É¤ò¸Æ¤Ó½Ð¤·¤Æ¿·¤·¤¤¸ø³«¸°¤ÈÈëÌ©¸°¤Î¥Ú¥¢¤òºîÀ®¤¹¤ë¤È¡¢¸ø³«¸°¤Ï¾ï¤Ë¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ç¥é¥Ã¥×¤µ¤ì¤Þ¤¹¡£
+ .sp
+-¤³¤Î¸å¡¢¾ÚÌÀ½ñ½ð̾¥ê¥¯¥¨¥¹¥È(CSR)¤¬\fB\-certreq\fR¥³¥Þ¥ó¥É¤ÇÀ¸À®¤µ¤ì¤Æ¡¢CSR¤¬¾ÚÌÀ½ñȯ¹Ô¶É(CA)¤ËÁ÷¿®¤µ¤ì¤ë¤È¡¢CA¤«¤é¤Î¥ì¥¹¥Ý¥ó¥¹¤¬\fB\-importcert\fR¤Ç¥¤¥ó¥Ý¡¼¥È¤µ¤ì¡¢¸µ¤Î¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ï¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤Ë¤è¤Ã¤ÆÃÖ¤­´¹¤¨¤é¤ì¤Þ¤¹¡£\fB¤Î\fR\-certreq\fB¤ª¤è¤Ó\fR\-importcert¥³¥Þ¥ó¥É¥ª¥×¥·¥ç¥ó¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£¥Á¥§¡¼¥ó¤ÎºÇ¸å¤Ë¤¢¤ë¤Î¤Ï¡¢Subject¤Î¸ø³«¸°¤òǧ¾Ú¤·¤¿CA¤¬È¯¹Ô¤·¤¿¾ÚÌÀ½ñ(±þÅú)¤Ç¤¹¡£¥Á¥§¡¼¥óÆâ¤Î¤½¤ÎÁ°¤Î¾ÚÌÀ½ñ¤Ï¡¢CA¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤Ç¤¹¡£
++¤³¤Î¸å¡¢¾ÚÌÀ½ñ½ð̾¥ê¥¯¥¨¥¹¥È(CSR)¤¬\fB\-certreq\fR¥³¥Þ¥ó¥É¤ÇÀ¸À®¤µ¤ì¤Æ¡¢CSR¤¬Ç§¾Ú¶É(CA)¤ËÁ÷¿®¤µ¤ì¤ë¤È¡¢CA¤«¤é¤Î¥ì¥¹¥Ý¥ó¥¹¤¬\fB\-importcert\fR¤Ç¥¤¥ó¥Ý¡¼¥È¤µ¤ì¡¢¸µ¤Î¼«¸Ê½ð̾¾ÚÌÀ½ñ¤Ï¾ÚÌÀ½ñ¥Á¥§¡¼¥ó¤Ë¤è¤Ã¤ÆÃÖ¤­´¹¤¨¤é¤ì¤Þ¤¹¡£\fB¤Î\fR\-certreq\fB¤ª¤è¤Ó\fR\-importcert¥³¥Þ¥ó¥É¥ª¥×¥·¥ç¥ó¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£¥Á¥§¡¼¥ó¤ÎºÇ¸å¤Ë¤¢¤ë¤Î¤Ï¡¢Subject¤Î¸ø³«¸°¤òǧ¾Ú¤·¤¿CA¤¬È¯¹Ô¤·¤¿¾ÚÌÀ½ñ(±þÅú)¤Ç¤¹¡£¥Á¥§¡¼¥óÆâ¤Î¤½¤ÎÁ°¤Î¾ÚÌÀ½ñ¤Ï¡¢CA¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤Ç¤¹¡£
+ .sp
+ CA¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤Ï¡¢Â¿¤¯¤Î¾ì¹ç¡¢¼«¸Ê½ð̾¾ÚÌÀ½ñ(¤Ä¤Þ¤êCA¤¬¼«¿È¤Î¸ø³«¸°¤òǧ¾Ú¤·¤¿¾ÚÌÀ½ñ)¤Ç¤¢¤ê¡¢¤³¤ì¤Ï¥Á¥§¡¼¥ó¤ÎºÇ½é¤Î¾ÚÌÀ½ñ¤Ë¤Ê¤ê¤Þ¤¹¡£¾ì¹ç¤Ë¤è¤Ã¤Æ¤Ï¡¢CA¤¬¾ÚÌÀ½ñ¤Î¥Á¥§¡¼¥ó¤òÊÖ¤¹¤³¤È¤â¤¢¤ê¤Þ¤¹¡£¤³¤Î¾ì¹ç¡¢¥Á¥§¡¼¥óÆâ¤ÎºÇ¸å¤Î¾ÚÌÀ½ñ(CA¤Ë¤è¤Ã¤Æ½ð̾¤µ¤ì¡¢¸°¥¨¥ó¥È¥ê¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ)¤ËÊѤï¤ê¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¡¢¥Á¥§¡¼¥óÆâ¤Î¤½¤ÎÁ°¤Î¾ÚÌÀ½ñ¤Ï¡¢CSR¤ÎÁ÷¿®Àè¤ÎCA¤È¤ÏÊ̤ÎCA¤Ë¤è¤Ã¤Æ½ð̾¤µ¤ì¡¢CSR¤ÎÁ÷¿®Àè¤ÎCA¤Î¸ø³«¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤Ë¤Ê¤ê¤Þ¤¹¡£¥Á¥§¡¼¥óÆâ¤Î¤½¤ÎÁ°¤Î¾ÚÌÀ½ñ¤Ï¡¢¼¡¤ÎCA¤Î¸°¤òǧ¾Ú¤¹¤ë¾ÚÌÀ½ñ¤Ë¤Ê¤ê¤Þ¤¹¡£°Ê²¼Æ±Íͤˡ¢¼«¸Ê½ð̾¤µ¤ì¤¿¡Ö¥ë¡¼¥È¡×¾ÚÌÀ½ñ¤Ë㤹¤ë¤Þ¤Ç¥Á¥§¡¼¥ó¤¬Â³¤­¤Þ¤¹¡£¤·¤¿¤¬¤Ã¤Æ¡¢¥Á¥§¡¼¥óÆâ¤Î(ºÇ½é¤Î¾ÚÌÀ½ñ°Ê¸å¤Î)³Æ¾ÚÌÀ½ñ¤Ç¤Ï¡¢¥Á¥§¡¼¥óÆâ¤Î¼¡¤Î¾ÚÌÀ½ñ¤Î½ð̾¼Ô¤Î¸ø³«¸°¤¬Ç§¾Ú¤µ¤ì¤Æ¤¤¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£
+ .sp
+@@ -1399,7 +2035,7 @@
+ .if n \{\
+ .RE
+ .\}
+-¥¤¥¿¥ê¥Ã¥¯ÂΤιàÌܤϡ¢¼ÂºÝ¤Ë»ØÄꤹ¤ëÃͤòɽ¤·¤Þ¤¹¡£Ã»½Ì·Á¤Î¥­¡¼¥ï¡¼¥É¤Î°ÕÌ£¤Ï¡¢¼¡¤Î¤È¤ª¤ê¤Ç¤¹¡£
++¥¤¥¿¥ê¥Ã¥¯¤Î¹àÌܤϡ¢¼ÂºÝ¤Ë»ØÄꤹ¤ëÃͤòɽ¤·¤Þ¤¹¡£Ã»½Ì·Á¤Î¥­¡¼¥ï¡¼¥É¤Î°ÕÌ£¤Ï¡¢¼¡¤Î¤È¤ª¤ê¤Ç¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+@@ -1527,7 +2163,7 @@
+ ¾ÚÌÀ½ñ¤ò¥¤¥ó¥Ý¡¼¥È¤¹¤ëÁ°¤Ë\fB\-printcert\fR¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£¥­¡¼¥¹¥È¥¢Æâ¤Î¿®Íê¤Ç¤­¤ë¾ÚÌÀ½ñ¤Î¥ê¥¹¥È¤Ë¾ÚÌÀ½ñ¤òÄɲ乤ëÁ°¤Ë¡¢\fB\-importcert\fR¥³¥Þ¥ó¥É¤Ë¤è¤Ã¤Æ¾ÚÌÀ½ñ¤Î¾ðÊó¤¬É½¼¨¤µ¤ì¡¢³Îǧ¤òµá¤á¤ë¥á¥Ã¥»¡¼¥¸¤¬É½¼¨¤µ¤ì¤ë¤¿¤á¤Ç¤¹¡£¥æ¡¼¥¶¡¼¤Ï¥¤¥ó¥Ý¡¼¥ÈÁàºî¤òÄä»ß¤Ç¤­¤Þ¤¹¡£¤¿¤À¤·¡¢¤³¤ì¤ò¼Â¹Ô¤Ç¤­¤ë¤Î¤Ï¡¢\fB\-noprompt\fR¥ª¥×¥·¥ç¥ó¤ò»ØÄꤻ¤º¤Ë\fB\-importcert\fR¥³¥Þ¥ó¥É¤ò¸Æ¤Ó½Ð¤¹¾ì¹ç¤Î¤ß¤Ç¤¹¡£\fB\-noprompt\fR¥ª¥×¥·¥ç¥ó¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥æ¡¼¥¶¡¼¤È¤ÎÂÐÏäϹԤï¤ì¤Þ¤»¤ó¡£
+ .SS "¥Ñ¥¹¥ï¡¼¥É·Ù¹ð"
+ .PP
+-¥­¡¼¥¹¥È¥¢¤ËÂФ¹¤ëÁàºî¤ò¹Ô¤¦¤Û¤È¤ó¤É¤Î¥³¥Þ¥ó¥É¤Ç¤Ï¡¢¥¹¥È¥¢¤Î¥Ñ¥¹¥ï¡¼¥É¤¬É¬ÍפǤ¹¡£¤Þ¤¿¡¢°ìÉô¤Î¥³¥Þ¥ó¥É¤Ç¤Ï¡¢Èó¸ø³«/ÈëÌ©¸°¤Î¥Ñ¥¹¥ï¡¼¥É¤¬É¬Íפˤʤ뤳¤È¤¬¤¢¤ê¤Þ¤¹¡£¥Ñ¥¹¥ï¡¼¥É¤Ï¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄê¤Ç¤­¤Þ¤¹(\fB\-storepass\fR¥ª¥×¥·¥ç¥ó¤È\fB\-keypass\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍÑ)¡£¤¿¤À¤·¡¢¥Æ¥¹¥È¤òÌÜŪ¤È¤¹¤ë¾ì¹ç¡¢¤Þ¤¿¤Ï°ÂÁ´¤Ç¤¢¤ë¤³¤È¤¬¤ï¤«¤Ã¤Æ¤¤¤ë¥·¥¹¥Æ¥à¤Ç¼Â¹Ô¤¹¤ë¾ì¹ç°Ê³°¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤ä¥¹¥¯¥ê¥×¥È¤Ç¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄꤷ¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£É¬Íפʥѥ¹¥ï¡¼¥É¤Î¥ª¥×¥·¥ç¥ó¤ò¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£
++¥­¡¼¥¹¥È¥¢¤ËÂФ¹¤ëÁàºî¤ò¹Ô¤¦¤Û¤È¤ó¤É¤Î¥³¥Þ¥ó¥É¤Ç¤Ï¡¢¥¹¥È¥¢¤Î¥Ñ¥¹¥ï¡¼¥É¤¬É¬ÍפǤ¹¡£¤Þ¤¿¡¢°ìÉô¤Î¥³¥Þ¥ó¥É¤Ç¤Ï¡¢Èó¸ø³«/ÈëÌ©¸°¤Î¥Ñ¥¹¥ï¡¼¥É¤¬É¬Íפˤʤ뤳¤È¤¬¤¢¤ê¤Þ¤¹¡£¥Ñ¥¹¥ï¡¼¥É¤Ï¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄê¤Ç¤­¤Þ¤¹(\fB\-storepass\fR¥ª¥×¥·¥ç¥ó¤È\fB\-keypass\fR¥ª¥×¥·¥ç¥ó¤ò»ÈÍÑ)¡£¤¿¤À¤·¡¢¥Æ¥¹¥ÈÌÜŪ¤Î¾ì¹ç¡¢¤Þ¤¿¤Ï¥»¥­¥å¥¢¤Ê¥·¥¹¥Æ¥à¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç°Ê³°¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤ä¥¹¥¯¥ê¥×¥È¤Ç¥Ñ¥¹¥ï¡¼¥É¤ò»ØÄꤷ¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£É¬Íפʥѥ¹¥ï¡¼¥É¤Î¥ª¥×¥·¥ç¥ó¤ò¥³¥Þ¥ó¥É¹Ô¤Ç»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòµá¤á¤é¤ì¤Þ¤¹¡£
+ .SS "¾ÚÌÀ½ñ¤Î½àµò¤Ë´Ø¤¹¤ë·Ù¹ð"
+ .PP
+ ¥¤¥ó¥¿¡¼¥Í¥Ã¥Èɸ½àRFC 5280¤Ç¤Ï¡¢X\&.509¾ÚÌÀ½ñ¤Î½àµò¤Ë´Ø¤¹¤ë¥×¥í¥Õ¥¡¥¤¥ë¤¬ÄêµÁ¤µ¤ì¤Æ¤ª¤ê¡¢¾ÚÌÀ½ñ¤Î¥Õ¥£¡¼¥ë¥É¤ª¤è¤Ó¥¨¥¯¥¹¥Æ¥ó¥·¥ç¥ó¤ËÍ­¸ú¤ÊÃͤª¤è¤ÓÃͤÎÁȹ礻¤¬µ­ºÜ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£É¸½à¤Ë¤Ä¤¤¤Æ¤Ï¡¢
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/native2ascii.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/native2ascii.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: ¹ñºÝ²½¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "native2ascii" "1" "2013ǯ11·î21Æü" "JDK 8" "¹ñºÝ²½¥Ä¡¼¥ë"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/orbd.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/orbd.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "orbd" "1" "2013ǯ11·î21Æü" "JDK 8" "Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë"
+@@ -117,7 +118,7 @@
+ .PP
+ \-serverPollingTime \fImilliseconds\fR
+ .RS 4
+-\fBservertool\fR¤ò»ÈÍѤ·¤ÆÅÐÏ¿¤µ¤ì¤¿±Ê³¥µ¡¼¥Ð¡¼¤Î¥Ø¥ë¥¹¾õÂÖ¤òORBD¤¬¥Á¥§¥Ã¥¯¤¹¤ë´Ö³Ö¤ò»ØÄꤷ¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤÏ1000¥ß¥êÉäǤ¹¡£\fBmilliseconds\fR¤Ë»ØÄꤹ¤ëÃͤϡ¢Í­¸ú¤ÊÀµ¤ÎÀ°¿ô¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
++\fBservertool\fR¤ò»ÈÍѤ·¤ÆÅÐÏ¿¤µ¤ì¤¿±Ê³¥µ¡¼¥Ð¡¼¤¬Àµ¾ï¤ËÆ°ºî¤·¤Æ¤¤¤ë¤³¤È¤òORBD¤¬³Îǧ¤¹¤ë´Ö³Ö¤ò»ØÄꤷ¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥ÈÃͤÏ1000¥ß¥êÉäǤ¹¡£\fBmilliseconds\fR¤Ë»ØÄꤹ¤ëÃͤϡ¢Í­¸ú¤ÊÀµ¤ÎÀ°¿ô¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ .RE
+ .PP
+ \-serverStartupDelay milliseconds
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/pack200.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/pack200.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java¥Ç¥×¥í¥¤¥á¥ó¥È¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "pack200" "1" "2013ǯ11·î21Æü" "JDK 8" "Java¥Ç¥×¥í¥¤¥á¥ó¥È¡¦¥Ä¡¼¥ë"
+@@ -160,7 +161,7 @@
+ \-\-segment\-limit=\fIvalue\fR
+ .RS 4
+ ¤³¤ÎÃͤϡ¢³Æ¥¢¡¼¥«¥¤¥Ö¡¦¥»¥°¥á¥ó¥È¤ÎͽÁÛ¥¿¡¼¥²¥Ã¥È¡¦¥µ¥¤¥º\fIN\fR
+-(¥Ð¥¤¥Èñ°Ì)¤Ç¤¹¡£Ã±°ì¤ÎÆþÎÏ¥Õ¥¡¥¤¥ë¤ÎɬÍ×¥µ¥¤¥º¤¬\fIN\fR¥Ð¥¤¥È¤òĶ¤¨¤ë¤È¡¢ÆÈΩ¤·¤¿¥»¥°¥á¥ó¥È¤¬³ä¤êÅö¤Æ¤é¤ì¤Þ¤¹¡£Æüì¤Ê¥±¡¼¥¹¤È¤·¤Æ¡¢Ãͤ¬\fB\-1\fR¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤ÎÆþÎÏ¥Õ¥¡¥¤¥ë¤ò´Þ¤àÂ礭¤Êñ°ì¤Î¥»¥°¥á¥ó¥È¤¬À¸À®¤µ¤ì¡¢Ãͤ¬0¤Î¾ì¹ç¤Ï¡¢¥¯¥é¥¹¤´¤È¤Ë¥»¥°¥á¥ó¥È¤¬1¤Ä¤º¤ÄÀ¸À®¤µ¤ì¤Þ¤¹¡£¥¢¡¼¥«¥¤¥Ö¡¦¥»¥°¥á¥ó¥È¤¬Â礭¤¯¤Ê¤ë¤È¡¢ÃÇÊÒ²½¤¬¾¯¤Ê¤¯¤Ê¤ê°µ½ÌΨ¤¬¹â¤¯¤Ê¤ê¤Þ¤¹¤¬¡¢¤½¤Î½èÍý¤Ë¤Ï¿¤¯¤Î¥á¥â¥ê¡¼¤¬É¬ÍפǤ¹¡£
++(¥Ð¥¤¥Èñ°Ì)¤Ç¤¹¡£Ã±°ì¤ÎÆþÎÏ¥Õ¥¡¥¤¥ë¤ÎɬÍ×¥µ¥¤¥º¤¬\fIN\fR¥Ð¥¤¥È¤òĶ¤¨¤ë¤È¡¢¸ÇÍ­¤Î¥¢¡¼¥«¥¤¥Ö¡¦¥»¥°¥á¥ó¥È¤¬Ä󶡤µ¤ì¤Þ¤¹¡£Æüì¤Ê¥±¡¼¥¹¤È¤·¤Æ¡¢Ãͤ¬\fB\-1\fR¤Î¾ì¹ç¤Ï¡¢¤¹¤Ù¤Æ¤ÎÆþÎÏ¥Õ¥¡¥¤¥ë¤ò´Þ¤àÂ礭¤Êñ°ì¤Î¥»¥°¥á¥ó¥È¤¬À¸À®¤µ¤ì¡¢Ãͤ¬0¤Î¾ì¹ç¤Ï¡¢¥¯¥é¥¹¤´¤È¤Ë¥»¥°¥á¥ó¥È¤¬1¤Ä¤º¤ÄÀ¸À®¤µ¤ì¤Þ¤¹¡£¥¢¡¼¥«¥¤¥Ö¡¦¥»¥°¥á¥ó¥È¤¬Â礭¤¯¤Ê¤ë¤È¡¢ÃÇÊÒ²½¤¬¾¯¤Ê¤¯¤Ê¤ê°µ½ÌΨ¤¬¹â¤¯¤Ê¤ê¤Þ¤¹¤¬¡¢¤½¤Î½èÍý¤Ë¤Ï¿¤¯¤Î¥á¥â¥ê¡¼¤¬É¬ÍפǤ¹¡£
+ .sp
+ ³Æ¥»¥°¥á¥ó¥È¤Î¥µ¥¤¥º¤Ï¡¢¥»¥°¥á¥ó¥È¤ËÊÑ´¹¤µ¤ì¤ë¤½¤ì¤¾¤ì¤ÎÆþÎÏ¥Õ¥¡¥¤¥ë¤Î¥µ¥¤¥º¤Î¤Û¤«¡¢¤½¤Î̾Á°¤È¾¤ÎÁ÷¿®¤µ¤ì¤ë¥×¥í¥Ñ¥Æ¥£¤Î¥µ¥¤¥º¤ò·×»»¤·¤Æ¿ä¬¤µ¤ì¤Þ¤¹¡£
+ .sp
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/policytool.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/policytool.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: policytool
+ .\" Language: Japanese
+-.\" Date: 2013ǯ11·î21Æü
++.\" Date: 2015ǯ3·î3Æü
+ .\" SectDesc: ¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "policytool" "1" "2013ǯ11·î21Æü" "JDK 8" "¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë"
++.TH "policytool" "1" "2015ǯ3·î3Æü" "JDK 8" "¥»¥­¥å¥ê¥Æ¥£¡¦¥Ä¡¼¥ë"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -95,7 +96,7 @@
+ .RS 4
+ .\}
+ .nf
+-\fBpolicytool\-file mypolicyfile\fR
++\fBpolicytool \-file \fR\fB\fImypolicyfile\fR\fR
+
+ .fi
+ .if n \{\
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/rmic.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/rmic.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Remote Method Invocation (RMI)¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "rmic" "1" "2013ǯ11·î21Æü" "JDK 8" "Remote Method Invocation (RMI)"
+@@ -110,8 +111,8 @@
+ .PP
+ \-classpath path
+ .RS 4
+-\fBrmic\fR¥³¥Þ¥ó¥É¤¬¥¯¥é¥¹¤òõ¤¹¤¿¤á¤Î¥Ñ¥¹¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤ä\fBCLASSPATH\fR´Ä¶­ÊÑ¿ôÀßÄê¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Þ¤¹¡£¥Ç¥£¥ì¥¯¥È¥ê¤Ï¥³¥í¥ó¤Çʬ³ä¤·¤Þ¤¹¡£¥Ñ¥¹¤Î°ìÈÌŪ¤Ê·Á¼°¤Ï\fB\&.;<your_path>\fR¤Ç¤¹¡£Îã:
+-\fB\&.;/usr/local/java/classes\fR
++\fBrmic\fR¥³¥Þ¥ó¥É¤¬¥¯¥é¥¹¤òõ¤¹¤¿¤á¤Î¥Ñ¥¹¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤ä\fBCLASSPATH\fR´Ä¶­ÊÑ¿ôÀßÄê¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Þ¤¹¡£¥Ç¥£¥ì¥¯¥È¥ê¤Ï¥³¥í¥ó¤Çʬ³ä¤·¤Þ¤¹¡£¥Ñ¥¹¤Î°ìÈÌŪ¤Ê·Á¼°¤Ï\fB\&.:<your_path>\fR¤Ç¤¹¡£Îã:
++\fB\&.:/usr/local/java/classes\fR
+ .RE
+ .PP
+ \-d \fIdirectory\fR
+@@ -350,7 +351,7 @@
+ .sp -1
+ .IP \(bu 2.3
+ .\}
+-Setting the Class Path
++¥¯¥é¥¹¡¦¥Ñ¥¹¤ÎÀßÄê
+ .RE
+ .br
+ 'pl 8.5i
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/rmid.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/rmid.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Remote Method Invocation (RMI)¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "rmid" "1" "2013ǯ11·î21Æü" "JDK 8" "Remote Method Invocation (RMI)"
+@@ -103,9 +104,7 @@
+ .\}
+ .SH "ɬÍפ˱þ¤¸¤ÆRMID¤ò³«»Ï"
+ .PP
+-\fBrmid\fR¤ò¥³¥Þ¥ó¥É¹Ô¤«¤é³«»Ï¤¹¤ë¤Ë¤Ï¡¢\fBinetd\fR
+-(Oracle Solaris¤Î¾ì¹ç)¡¢¤Þ¤¿¤Ï\fBxinetd\fR
+-(Linux¤Î¾ì¹ç)¤ò¹½À®¤·¤Æ\fBrmid\fR¤òɬÍפ˱þ¤¸¤Æ³«»Ï¤¹¤ëÊýË¡¤â¤¢¤ê¤Þ¤¹¡£
++\fBrmid\fR¤ò¥³¥Þ¥ó¥É¹Ô¤«¤é³«»Ï¤¹¤ë¤Ë¤Ï¡¢\fBinetd\fR(Oracle Solaris¤Î¾ì¹ç)¡¢¤Þ¤¿¤Ï\fBxinetd\fR(Linux¤Î¾ì¹ç)¤ò¹½À®¤·¤Æ\fBrmid\fR¤òɬÍפ˱þ¤¸¤Æ³«»Ï¤¹¤ëÊýË¡¤â¤¢¤ê¤Þ¤¹¡£
+ .PP
+ RMID¤ò³«»Ï¤¹¤ë¤È¡¢\fBSystem\&.inheritedChannel\fR¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð¤·¤Æ¡¢·Ñ¾µ¤µ¤ì¤¿¥Á¥ã¥ó¥Í¥ë(\fBinetd\fR/\fBxinetd\fR¤«¤é·Ñ¾µ)¤ò¼èÆÀ¤·¤è¤¦¤È¤·¤Þ¤¹¡£·Ñ¾µ¤µ¤ì¤¿¥Á¥ã¥ó¥Í¥ë¤¬null¤Ç¤¢¤ë¤«¡¢\fBjava\&.nio\&.channels\&.ServerSocketChannel\fR¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ç¤Ê¤«¤Ã¤¿¾ì¹ç¡¢RMID¤Ï¤½¤Î¥Á¥ã¥ó¥Í¥ë¤Ï\fBinetd\fR/\fBxinetd\fR¤Ë¤è¤Ã¤Æµ¯Æ°¤µ¤ì¤¿¤â¤Î¤Ç¤Ï¤Ê¤¤¤ÈȽÃǤ·¡¢Á°½Ò¤Î¤è¤¦¤Ëµ¯Æ°¤·¤Þ¤¹¡£
+ .PP
+@@ -368,7 +367,7 @@
+ .sp -1
+ .IP \(bu 2.3
+ .\}
+-Setting the Class Path
++¥¯¥é¥¹¡¦¥Ñ¥¹¤ÎÀßÄê
+ .RE
+ .br
+ 'pl 8.5i
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/rmiregistry.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/rmiregistry.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Remote Method Invocation (RMI)¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "rmiregistry" "1" "2013ǯ11·î21Æü" "JDK 8" "Remote Method Invocation (RMI)"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/schemagen.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/schemagen.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "schemagen" "1" "2013ǯ11·î21Æü" "JDK 8" "Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/serialver.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/serialver.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Remote Method Invocation (RMI)¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "serialver" "1" "2013ǯ11·î21Æü" "JDK 8" "Remote Method Invocation (RMI)"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/servertool.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/servertool.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "servertool" "1" "2013ǯ11·î21Æü" "JDK 8" "Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/tnameserv.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/tnameserv.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "tnameserv" "1" "2013ǯ11·î21Æü" "JDK 8" "Java IDL¤ª¤è¤ÓRMI-IIOP¥Ä¡¼¥ë"
+@@ -189,7 +190,7 @@
+ .SH "Îã"
+ .SS "¥Í¡¼¥à¥¹¥Ú¡¼¥¹¤Ø¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ÎÄɲÃ"
+ .PP
+-¼¡¤ÎÎã¤Ç¤Ï¡¢¥Í¡¼¥à¥¹¥Ú¡¼¥¹¤Ë̾Á°¤òÄɲ乤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£¤³¤Î¥µ¥ó¥×¥ë¡¦¥×¥í¥°¥é¥à¤Ï¡¢¤³¤Î¤Þ¤Þ¤Î¾õÂ֤Ǵ°Á´¤ËÆ°ºî¤¹¤ë°ì»þ¥Í¡¼¥à¡¦¥µ¡¼¥Ó¥¹¡¦¥¯¥é¥¤¥¢¥ó¥È¤Ç¡¢¼¡¤Î¤è¤¦¤Êñ½ã¤Ê¥Ä¥ê¡¼¤òºîÀ®¤¹¤ë¤â¤Î¤Ç¤¹¡£
++¼¡¤ÎÎã¤Ç¤Ï¡¢¥Í¡¼¥à¥¹¥Ú¡¼¥¹¤Ë̾Á°¤òÄɲ乤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£¤³¤Î¥µ¥ó¥×¥ë¡¦¥×¥í¥°¥é¥à¤Ï¡¢¼«¸Ê´°·ë·¿¤Î°ì»þ¥Í¡¼¥à¡¦¥µ¡¼¥Ó¥¹¡¦¥¯¥é¥¤¥¢¥ó¥È¤Ç¡¢¼¡¤Î¤è¤¦¤Êñ½ã¤Ê¥Ä¥ê¡¼¤òºîÀ®¤¹¤ë¤â¤Î¤Ç¤¹¡£
+ .sp
+ .if n \{\
+ .RS 4
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/unpack200.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/unpack200.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java¥Ç¥×¥í¥¤¥á¥ó¥È¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "unpack200" "1" "2013ǯ11·î21Æü" "JDK 8" "Java¥Ç¥×¥í¥¤¥á¥ó¥È¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/wsgen.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/wsgen.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "wsgen" "1" "2013ǯ11·î21Æü" "JDK 8" "Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/wsimport.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/wsimport.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "wsimport" "1" "2013ǯ11·î21Æü" "JDK 8" "Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë"
+--- ./jdk/src/solaris/doc/sun/man/man1/ja/xjc.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/ja/xjc.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,8 @@
+ .\" SectDesc: Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë
+ .\" Software: JDK 8
+ .\" Arch: ÈÆÍÑ
+-.\" Part Number: E54734-01
++.\" Part Number: E58103-01
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+ .TH "xjc" "1" "2013ǯ11·î21Æü" "JDK 8" "Java Web¥µ¡¼¥Ó¥¹¡¦¥Ä¡¼¥ë"
+@@ -129,7 +130,7 @@
+ .PP
+ \-p \fIpkg\fR
+ .RS 4
+-¤³¤Î¥³¥Þ¥ó¥É¹Ô¥ª¥×¥·¥ç¥ó¤Ç¥¿¡¼¥²¥Ã¥È¡¦¥Ñ¥Ã¥±¡¼¥¸¤ò»ØÄꤷ¤¿¾ì¹ç¡¢¥Ñ¥Ã¥±¡¼¥¸Ì¾¤ËÂФ¹¤ë¤¹¤Ù¤Æ¤Î¥Ð¥¤¥ó¥Ç¥£¥ó¥°¡¦¥«¥¹¥¿¥Þ¥¤¥º¤ä¡¢»ÅÍͤǵ¬Äꤵ¤ì¤Æ¤¤¤ë¥Ç¥Õ¥©¥ë¥È¤Î¥Ñ¥Ã¥±¡¼¥¸Ì¾¥¢¥ë¥´¥ê¥º¥à¤è¤ê¤âÍ¥À褵¤ì¤Þ¤¹¡£
++¤³¤Î¥³¥Þ¥ó¥É¹Ô¥ª¥×¥·¥ç¥ó¤Ç¥¿¡¼¥²¥Ã¥È¡¦¥Ñ¥Ã¥±¡¼¥¸¤ò»ØÄꤷ¤¿¾ì¹ç¡¢¤½¤Î»ØÄêÆâÍƤϡ¢¥Ñ¥Ã¥±¡¼¥¸Ì¾¤ËÂФ¹¤ë¤¹¤Ù¤Æ¤Î¥Ð¥¤¥ó¥Ç¥£¥ó¥°¡¦¥«¥¹¥¿¥Þ¥¤¥º¤ä¡¢»ÅÍͤǵ¬Äꤵ¤ì¤Æ¤¤¤ë¥Ç¥Õ¥©¥ë¥È¤Î¥Ñ¥Ã¥±¡¼¥¸Ì¾¥¢¥ë¥´¥ê¥º¥à¤è¤ê¤âÍ¥À褵¤ì¤Þ¤¹¡£
+ .RE
+ .PP
+ \-httpproxy \fIproxy\fR
+--- ./jdk/src/solaris/doc/sun/man/man1/java.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/java.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ '\" t
+-.\" Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
++.\" Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
+ .\"
+ .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ .\"
+@@ -23,14 +23,15 @@
+ .\"
+ .\" Title: java
+ .\" Language: English
+-.\" Date: 08 August 2014
++.\" Date: 03 March 2015
+ .\" SectDesc: Basic Tools
+ .\" Software: JDK 8
+ .\" Arch: generic
+-.\" Part Number: E38207-03
++.\" Part Number: E38207-04
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH "java" "1" "08 August 2014" "JDK 8" "Basic Tools"
++.TH "java" "1" "03 March 2015" "JDK 8" "Basic Tools"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -333,7 +334,6 @@
+ Selects the Java HotSpot Client VM\&. The 64\-bit version of the Java SE Development Kit (JDK) currently ignores this option and instead uses the Server JVM\&.
+ .sp
+ For default JVM selection, see Server\-Class Machine Detection at
+-
+ http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/server\-class\&.html
+ .RE
+ .PP
+@@ -550,7 +550,6 @@
+ Selects the Java HotSpot Server VM\&. The 64\-bit version of the JDK supports only the Server VM, so in that case the option is implicit\&.
+ .sp
+ For default JVM selection, see Server\-Class Machine Detection at
+-
+ http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/server\-class\&.html
+ .RE
+ .PP
+@@ -772,13 +771,14 @@
+ \fBg\fR
+ or
+ \fBG\fR
+-to indicate gigabytes\&. By default, the value is set to 48 MB:
++to indicate gigabytes\&. The default maximum code cache size is 240 MB; if you disable tiered compilation with the option
++\fB\-XX:\-TieredCompilation\fR, then the default size is 48 MB:
+ .sp
+ .if n \{\
+ .RS 4
+ .\}
+ .nf
+-\fB\-Xmaxjitcodesize=48m\fR
++\fB\-Xmaxjitcodesize=240m\fR
+
+ .fi
+ .if n \{\
+@@ -889,7 +889,9 @@
+ \fB\-Xms\fR
+ and
+ \fB\-Xmx\fR
+-are often set to the same value\&. For more information, see Garbage Collector Ergonomics at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gc\-ergonomics\&.html
++are often set to the same value\&. See the section "Ergonomics" in
++\fIJava SE HotSpot Virtual Machine Garbage Collection Tuning Guide\fR
++at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gctuning/index\&.html\&.
+ .sp
+ The following examples show how to set the maximum allowed size of allocated memory to 80 MB using various units:
+ .sp
+@@ -986,28 +988,30 @@
+ .PP
+ \-Xshare:\fImode\fR
+ .RS 4
+-Sets the class data sharing mode\&. Possible
++Sets the class data sharing (CDS) mode\&. Possible
+ \fImode\fR
+ arguments for this option include the following:
+ .PP
+ auto
+ .RS 4
+-Use shared class data if possible\&. This is the default value for Java HotSpot 32\-Bit Client VM\&.
++Use CDS if possible\&. This is the default value for Java HotSpot 32\-Bit Client VM\&.
+ .RE
+ .PP
+ on
+ .RS 4
+-Require the use of class data sharing\&. Print an error message and exit if class data sharing cannot be used\&.
++Require the use of CDS\&. Print an error message and exit if class data sharing cannot be used\&.
+ .RE
+ .PP
+ off
+ .RS 4
+-Do not use shared class data\&. This is the default value for Java HotSpot 32\-Bit Server VM, Java HotSpot 64\-Bit Client VM, and Java HotSpot 64\-Bit Server VM\&.
++Do not use CDS\&. This is the default value for Java HotSpot 32\-Bit Server VM, Java HotSpot 64\-Bit Client VM, and Java HotSpot 64\-Bit Server VM\&.
+ .RE
+ .PP
+ dump
+ .RS 4
+-Manually generate the class data sharing archive\&.
++Manually generate the CDS archive\&. Specify the application class path as described in "Setting the Class Path "\&.
++.sp
++You should regenerate the CDS archive with each new JDK release\&.
+ .RE
+ .RE
+ .PP
+@@ -1120,17 +1124,6 @@
+ Oracle Solaris/x64 (64\-bit): 1024 KB
+ .RE
+ .sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-Windows: depends on virtual memory
+-.RE
+-.sp
+ The following examples set the thread stack size to 1024 KB in different units:
+ .sp
+ .if n \{\
+@@ -1172,7 +1165,7 @@
+ .PP
+ remote
+ .RS 4
+-Verify only those classes that are loaded remotely over the network\&. This is the default behavior if you do not specify the
++Verify those classes that are not loaded by the bootstrap class loader\&. This is the default behavior if you do not specify the
+ \fB\-Xverify\fR
+ option\&.
+ .RE
+@@ -1186,6 +1179,65 @@
+ .PP
+ These options control the runtime behavior of the Java HotSpot VM\&.
+ .PP
++\-XX:+CheckEndorsedAndExtDirs
++.RS 4
++Enables the option to prevent the
++\fBjava\fR
++command from running a Java application if it uses the endorsed\-standards override mechanism or the extension mechanism\&. This option checks if an application is using one of these mechanisms by checking the following:
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++The
++\fBjava\&.ext\&.dirs\fR
++or
++\fBjava\&.endorsed\&.dirs\fR
++system property is set\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++The
++\fBlib/endorsed\fR
++directory exists and is not empty\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++The
++\fBlib/ext\fR
++directory contains any JAR files other than those of the JDK\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++The system\-wide platform\-specific extension directory contains any JAR files\&.
++.RE
++.RE
++.PP
+ \-XX:+DisableAttachMechanism
+ .RS 4
+ Enables the option that disables the mechanism that lets tools attach to the JVM\&. By default, this option is disabled, meaning that the attach mechanism is enabled and you can use tools such as
+@@ -1238,7 +1290,7 @@
+ .PP
+ \-XX:LargePageSizeInBytes=\fIsize\fR
+ .RS 4
+-Sets the maximum size (in bytes) for large pages used for Java heap\&. The
++On Solaris, sets the maximum size (in bytes) for large pages used for Java heap\&. The
+ \fIsize\fR
+ argument must be a power of 2 (2, 4, 8, 16, \&.\&.\&.)\&. Append the letter
+ \fBk\fR
+@@ -1327,6 +1379,17 @@
+ .RE
+ .RE
+ .PP
++\-XX:ObjectAlignmentInBytes=\fIalignment\fR
++.RS 4
++Sets the memory alignment of Java objects (in bytes)\&. By default, the value is set to 8 bytes\&. The specified value should be a power of two, and must be within the range of 8 and 256 (inclusive)\&. This option makes it possible to use compressed pointers with large Java heap sizes\&.
++.sp
++The heap size limit in bytes is calculated as:
++.sp
++\fB4GB * ObjectAlignmentInBytes\fR
++.sp
++Note: As the alignment value increases, the unused space between objects will also increase\&. As a result, you may not realize any benefits from using compressed pointers with large Java heap sizes\&.
++.RE
++.PP
+ \-XX:OnError=\fIstring\fR
+ .RS 4
+ Sets a custom command or a series of semicolon\-separated commands to run when an irrecoverable error occurs\&. If the string contains spaces, then it must be enclosed in quotation marks\&.
+@@ -1360,6 +1423,28 @@
+ option\&.
+ .RE
+ .PP
++\-XX:+PerfDataSaveToFile
++.RS 4
++If enabled, saves
++jstat(1) binary data when the Java application exits\&. This binary data is saved in a file named
++\fBhsperfdata_\fR\fI<pid>\fR, where
++\fI<pid>\fR
++is the process identifier of the Java application you ran\&. Use
++\fBjstat\fR
++to display the performance data contained in this file as follows:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjstat \-class file:///\fR\fB\fI<path>\fR\fR\fB/hsperfdata_\fR\fB\fI<pid>\fR\fR
++\fBjstat \-gc file:///\fR\fB\fI<path>\fR\fR\fB/hsperfdata_\fR\fB\fI<pid>\fR\fR
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.PP
+ \-XX:+PrintCommandLineFlags
+ .RS 4
+ Enables printing of ergonomically selected JVM flags that appeared on the command line\&. It can be useful to know the ergonomic values set by the JVM, such as the heap space size and the selected garbage collector\&. By default, this option is disabled and flags are not printed\&.
+@@ -1463,17 +1548,6 @@
+ Oracle Solaris/x64 (64\-bit): 1024 KB
+ .RE
+ .sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-Windows: depends on virtual memory
+-.RE
+-.sp
+ The following examples show how to set the thread stack size to 1024 KB in different units:
+ .sp
+ .if n \{\
+@@ -1537,13 +1611,27 @@
+ \-XX:\-UseCompressedOops
+ .RS 4
+ Disables the use of compressed pointers\&. By default, this option is enabled, and compressed pointers are used when Java heap sizes are less than 32 GB\&. When this option is enabled, object references are represented as 32\-bit offsets instead of 64\-bit pointers, which typically increases performance when running the application with Java heap sizes less than 32 GB\&. This option works only for 64\-bit JVMs\&.
++.sp
++It is also possible to use compressed pointers when Java heap sizes are greater than 32GB\&. See the
++\fB\-XX:ObjectAlignmentInBytes\fR
++option\&.
+ .RE
+ .PP
+-\-XX:\-UseLargePages
+-.RS 4
+-Disables the use of large page memory\&. This option is enabled by default\&.
++\-XX:+UseHugeTLBFS
++.RS 4
++This option for Linux is the equivalent of specifying
++\fB\-XX:+UseLargePages\fR\&. This option is disabled by default\&. This option pre\-allocates all large pages up\-front, when memory is reserved; consequently the JVM cannot dynamically grow or shrink large pages memory areas; see
++\fB\-XX:UseTransparentHugePages\fR
++if you want this behavior\&.
+ .sp
+-For more information, see Java Support for Large Memory Pages at http://www\&.oracle\&.com/technetwork/java/javase/tech/largememory\-jsp\-137182\&.html
++For more information, see "Large Pages"\&.
++.RE
++.PP
++\-XX:+UseLargePages
++.RS 4
++Enables the use of large page memory\&. By default, this option is disabled and large page memory is not used\&.
++.sp
++For more information, see "Large Pages"\&.
+ .RE
+ .PP
+ \-XX:+UseMembar
+@@ -1563,6 +1651,13 @@
+ \fB\-XX:\-UsePerfData\fR\&.
+ .RE
+ .PP
++\-XX:+UseTransparentHugePages
++.RS 4
++On Linux, enables the use of large pages that can dynamically grow or shrink\&. This option is disabled by default\&. You may encounter performance problems with transparent huge pages as the OS moves other pages around to create huge pages; this option is made available for experimentation\&.
++.sp
++For more information, see "Large Pages"\&.
++.RE
++.PP
+ \-XX:+AllowUserSignalHandlers
+ .RS 4
+ Enables installation of signal handlers by the application\&. By default, this option is disabled and the application is not allowed to install signal handlers\&.
+@@ -2041,7 +2136,8 @@
+ .PP
+ \-XX:CompileThreshold=\fIinvocations\fR
+ .RS 4
+-Sets the number of interpreted method invocations before compilation\&. By default, in the server JVM, the JIT compiler performs 10,000 interpreted method invocations to gather information for efficient compilation\&. For the client JVM, the default setting is 1,500 invocations\&. The following example shows how to set the number of interpreted method invocations to 5,000:
++Sets the number of interpreted method invocations before compilation\&. By default, in the server JVM, the JIT compiler performs 10,000 interpreted method invocations to gather information for efficient compilation\&. For the client JVM, the default setting is 1,500 invocations\&. This option is ignored when tiered compilation is enabled; see the option
++\fB\-XX:+TieredCompilation\fR\&. The following example shows how to set the number of interpreted method invocations to 5,000:
+ .sp
+ .if n \{\
+ .RS 4
+@@ -2078,7 +2174,7 @@
+ \fBg\fR
+ or
+ \fBG\fR
+-to indicate gigabytes\&. The default value is set to 500 KB\&. The following example shows how to set the initial code cache size to 32 KB:
++to indicate gigabytes\&. The default value is set to 500 KB\&. The initial code cache size should be not less than the system\*(Aqs minimal memory page size\&. The following example shows how to set the initial code cache size to 32 KB:
+ .sp
+ .if n \{\
+ .RS 4
+@@ -2274,13 +2370,29 @@
+ \fBg\fR
+ or
+ \fBG\fR
+-to indicate gigabytes\&. This option is equivalent to
++to indicate gigabytes\&. The default maximum code cache size is 240 MB; if you disable tiered compilation with the option
++\fB\-XX:\-TieredCompilation\fR, then the default size is 48 MB\&. This option has a limit of 2 GB; otherwise, an error is generated\&. The maximum code cache size should not be less than the initial code cache size; see the option
++\fB\-XX:InitialCodeCacheSize\fR\&. This option is equivalent to
+ \fB\-Xmaxjitcodesize\fR\&.
+ .RE
+ .PP
+-\-XX:+TieredCompilation
+-.RS 4
+-Enables the use of tiered compilation\&. By default, this option is enabled\&. Only the Java HotSpot Server VM supports this option\&.
++\-XX:RTMAbortRatio=\fIabort_ratio\fR
++.RS 4
++The RTM abort ratio is specified as a percentage (%) of all executed RTM transactions\&. If a number of aborted transactions becomes greater than this ratio, then the compiled code will be deoptimized\&. This ratio is used when the
++\fB\-XX:+UseRTMDeopt\fR
++option is enabled\&. The default value of this option is 50\&. This means that the compiled code will be deoptimized if 50% of all transactions are aborted\&.
++.RE
++.PP
++\-XX:RTMRetryCount=\fInumber_of_retries\fR
++.RS 4
++RTM locking code will be retried, when it is aborted or busy, the number of times specified by this option before falling back to the normal locking mechanism\&. The default value for this option is 5\&. The
++\fB\-XX:UseRTMLocking\fR
++option must be enabled\&.
++.RE
++.PP
++\-XX:\-TieredCompilation
++.RS 4
++Disables the use of tiered compilation\&. By default, this option is enabled\&. Only the Java HotSpot Server VM supports this option\&.
+ .RE
+ .PP
+ \-XX:+UseAES
+@@ -2319,45 +2431,20 @@
+ Enables checking of whether the card is already marked before updating the card table\&. This option is disabled by default and should only be used on machines with multiple sockets, where it will increase performance of Java applications that rely heavily on concurrent operations\&. Only the Java HotSpot Server VM supports this option\&.
+ .RE
+ .PP
+-\-XX:+UseSuperWord
+-.RS 4
+-Enables the transformation of scalar operations into superword operations\&. This option is enabled by default\&. To disable the transformation of scalar operations into superword operations, specify
+-\fB\-XX:\-UseSuperWord\fR\&. Only the Java HotSpot Server VM supports this option\&.
+-.RE
+-.SS "Experimental JIT Compiler Options"
+-.PP
+-The options related to the Restricted Transactional Memory (RTM) locking feature in this section are experimental and are not officially supported in Java SE 8u20; you must enable the
+-\fB\-XX:+UnlockExperimentalVMOptions\fR
+-option to use them\&. These options are only available for the Java HotSpot Server VM on x86 CPUs that support Transactional Synchronization Extensions (TSX)\&.
+-.PP
+-\-XX:RTMAbortRatio=\fIabort_ratio\fR
+-.RS 4
+-The RTM abort ratio is specified as a percentage (%) of all executed RTM transactions\&. If a number of aborted transactions becomes greater than this ratio, then the compiled code will be deoptimized\&. This ratio is used when the
+-\fB\-XX:+UseRTMDeopt\fR
+-option is enabled\&. The default value of this option is 50\&. This means that the compiled code will be deoptimized if 50% of all transactions are aborted\&.
+-.RE
+-.PP
+-\-XX:RTMRetryCount=\fInumber_of_retries\fR
+-.RS 4
+-RTM locking code will be retried, when it is aborted or busy, the number of times specified by this option before falling back to the normal locking mechanism\&. The default value for this option is 5\&. The
+-\fB\-XX:UseRTMLocking\fR
+-option must be enabled\&.
+-.RE
+-.PP
+ \-XX:+UseRTMDeopt
+ .RS 4
+ Auto\-tunes RTM locking depending on the abort ratio\&. This ratio is specified by
+ \fB\-XX:RTMAbortRatio\fR
+ option\&. If the number of aborted transactions exceeds the abort ratio, then the method containing the lock will be deoptimized and recompiled with all locks as normal locks\&. This option is disabled by default\&. The
+-\fB\-XX:UseRTMLocking\fR
++\fB\-XX:+UseRTMLocking\fR
+ option must be enabled\&.
+ .RE
+ .PP
+ \-XX:+UseRTMLocking
+ .RS 4
+-Generate Restricted Transactional Memory (RTM) locking code for all inflated locks, with the normal locking mechanism as the fallback handler\&. This option is disabled by default\&.
++Generate Restricted Transactional Memory (RTM) locking code for all inflated locks, with the normal locking mechanism as the fallback handler\&. This option is disabled by default\&. Options related to RTM are only available for the Java HotSpot Server VM on x86 CPUs that support Transactional Synchronization Extensions (TSX)\&.
+ .sp
+-RTM is part of Intel\*(Aqs Transactional Synchronization Extensions (TSX), which is an x86 instruction set extension and facilitates the creation of multithreaded applications\&. RTM introduces the new instructions
++RTM is part of Intel\*(Aqs TSX, which is an x86 instruction set extension and facilitates the creation of multithreaded applications\&. RTM introduces the new instructions
+ \fBXBEGIN\fR,
+ \fBXABORT\fR,
+ \fBXEND\fR, and
+@@ -2377,6 +2464,52 @@
+ .sp
+ RTM improves performance for highly contended locks with low conflict in a critical region (which is code that must not be accessed by more than one thread concurrently)\&. RTM also improves the performance of coarse\-grain locking, which typically does not perform well in multithreaded applications\&. (Coarse\-grain locking is the strategy of holding locks for long periods to minimize the overhead of taking and releasing locks, while fine\-grained locking is the strategy of trying to achieve maximum parallelism by locking only when necessary and unlocking as soon as possible\&.) Also, for lightly contended locks that are used by different threads, RTM can reduce false cache line sharing, also known as cache line ping\-pong\&. This occurs when multiple threads from different processors are accessing different resources, but the resources share the same cache line\&. As a result, the processors repeatedly invalidate the cache lines of other processors, which forces them to read from main memory instead of their cache\&.
+ .RE
++.PP
++\-XX:+UseSHA
++.RS 4
++Enables hardware\-based intrinsics for SHA crypto hash functions for SPARC hardware\&.
++\fBUseSHA\fR
++is used in conjunction with the
++\fBUseSHA1Intrinsics\fR,
++\fBUseSHA256Intrinsics\fR, and
++\fBUseSHA512Intrinsics\fR
++options\&.
++.sp
++The
++\fBUseSHA\fR
++and
++\fBUseSHA*Intrinsics\fR
++flags are enabled by default, and are supported only for Java HotSpot Server VM 64\-bit on SPARC T4 and newer\&.
++.sp
++This feature is only applicable when using the
++\fBsun\&.security\&.provider\&.Sun\fR
++provider for SHA operations\&.
++.sp
++To disable all hardware\-based SHA intrinsics, specify
++\fB\-XX:\-UseSHA\fR\&. To disable only a particular SHA intrinsic, use the appropriate corresponding option\&. For example:
++\fB\-XX:\-UseSHA256Intrinsics\fR\&.
++.RE
++.PP
++\-XX:+UseSHA1Intrinsics
++.RS 4
++Enables intrinsics for SHA\-1 crypto hash function\&.
++.RE
++.PP
++\-XX:+UseSHA256Intrinsics
++.RS 4
++Enables intrinsics for SHA\-224 and SHA\-256 crypto hash functions\&.
++.RE
++.PP
++\-XX:+UseSHA512Intrinsics
++.RS 4
++Enables intrinsics for SHA\-384 and SHA\-512 crypto hash functions\&.
++.RE
++.PP
++\-XX:+UseSuperWord
++.RS 4
++Enables the transformation of scalar operations into superword operations\&. This option is enabled by default\&. To disable the transformation of scalar operations into superword operations, specify
++\fB\-XX:\-UseSuperWord\fR\&. Only the Java HotSpot Server VM supports this option\&.
++.RE
+ .SS "Advanced Serviceability Options"
+ .PP
+ These options provide the ability to gather system information and perform extensive debugging\&.
+@@ -2474,9 +2607,10 @@
+ .PP
+ \-XX:+PrintConcurrentLocks
+ .RS 4
+-Enables printing of j locks after a event\&. By default, this option is disabled\&.
++Enables printing of locks after a event\&. By default, this option is disabled\&.
+ .sp
+-Enables printing of j\fBava\&.util\&.concurrent\fR
++Enables printing of
++\fBjava\&.util\&.concurrent\fR
+ locks after a
+ \fBControl+C\fR
+ event (\fBSIGTERM\fR)\&. By default, this option is disabled\&.
+@@ -2678,7 +2812,9 @@
+ \fBg\fR
+ or
+ \fBG\fR
+-to indicate gigabytes\&. The default value is chosen at runtime based on system configuration\&. For more information, see Garbage Collector Ergonomics at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gc\-ergonomics\&.html
++to indicate gigabytes\&. The default value is chosen at runtime based on system configuration\&. See the section "Ergonomics" in
++\fIJava SE HotSpot Virtual Machine Garbage Collection Tuning Guide\fR
++at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gctuning/index\&.html\&.
+ .sp
+ The following examples show how to set the size of allocated memory to 6 MB using various units:
+ .sp
+@@ -2798,7 +2934,9 @@
+ \fB\-XX:InitialHeapSize\fR
+ and
+ \fB\-XX:MaxHeapSize\fR
+-are often set to the same value\&. For more information, see Garbage Collector Ergonomics at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gc\-ergonomics\&.html
++are often set to the same value\&. See the section "Ergonomics" in
++\fIJava SE HotSpot Virtual Machine Garbage Collection Tuning Guide\fR
++at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/vm/gctuning/index\&.html\&.
+ .sp
+ The following examples show how to set the maximum allowed size of allocated memory to 80 MB using various units:
+ .sp
+@@ -3238,6 +3376,13 @@
+ Enables the use of the serial garbage collector\&. This is generally the best choice for small and simple applications that do not require any special functionality from garbage collection\&. By default, this option is disabled and the collector is chosen automatically based on the configuration of the machine and type of the JVM\&.
+ .RE
+ .PP
++\-XX:+UseSHM
++.RS 4
++On Linux, enables the JVM to use shared memory to setup large pages\&.
++.sp
++For more information, see "Large Pages"\&.
++.RE
++.PP
+ \-XX:+UseStringDeduplication
+ .RS 4
+ Enables string deduplication\&. By default, this option is disabled\&. To use this option, you must enable the garbage\-first (G1) garbage collector\&. See the
+@@ -3352,9 +3497,7 @@
+ .PP
+ The following examples show how to use experimental tuning flags to either optimize throughput or to provide lower response time\&.
+ .PP
+-\fBExample 1\fR
+-.br
+-Tuning for Higher Throughput
++\fBExample 1 \fRTuning for Higher Throughput
+ .RS 4
+ .sp
+ .if n \{\
+@@ -3369,9 +3512,7 @@
+ .\}
+ .RE
+ .PP
+-\fBExample 2\fR
+-.br
+-Tuning for Lower Response Time
++\fBExample 2 \fRTuning for Lower Response Time
+ .RS 4
+ .sp
+ .if n \{\
+@@ -3385,6 +3526,195 @@
+ .RE
+ .\}
+ .RE
++.SH "LARGE PAGES"
++.PP
++Also known as huge pages, large pages are memory pages that are significantly larger than the standard memory page size (which varies depending on the processor and operating system)\&. Large pages optimize processor Translation\-Lookaside Buffers\&.
++.PP
++A Translation\-Lookaside Buffer (TLB) is a page translation cache that holds the most\-recently used virtual\-to\-physical address translations\&. TLB is a scarce system resource\&. A TLB miss can be costly as the processor must then read from the hierarchical page table, which may require multiple memory accesses\&. By using a larger memory page size, a single TLB entry can represent a larger memory range\&. There will be less pressure on TLB, and memory\-intensive applications may have better performance\&.
++.PP
++However, large pages page memory can negatively affect system performance\&. For example, when a large mount of memory is pinned by an application, it may create a shortage of regular memory and cause excessive paging in other applications and slow down the entire system\&. Also, a system that has been up for a long time could produce excessive fragmentation, which could make it impossible to reserve enough large page memory\&. When this happens, either the OS or JVM reverts to using regular pages\&.
++.SS "Large Pages Support"
++.PP
++Solaris and Linux support large pages\&.
++.sp
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBSolaris\fR
++.RS 4
++.PP
++Solaris 9 and later include Multiple Page Size Support (MPSS); no additional configuration is necessary\&. See http://www\&.oracle\&.com/technetwork/server\-storage/solaris10/overview/solaris9\-features\-scalability\-135663\&.html\&.
++.RE
++.sp
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBLinux\fR
++.RS 4
++.PP
++The 2\&.6 kernel supports large pages\&. Some vendors have backported the code to their 2\&.4\-based releases\&. To check if your system can support large page memory, try the following:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB# cat /proc/meminfo | grep Huge\fR
++\fBHugePages_Total: 0\fR
++\fBHugePages_Free: 0\fR
++\fBHugepagesize: 2048 kB\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.PP
++If the output shows the three "Huge" variables, then your system can support large page memory but it needs to be configured\&. If the command prints nothing, then your system does not support large pages\&. To configure the system to use large page memory, login as
++\fBroot\fR, and then follow these steps:
++.sp
++.RS 4
++.ie n \{\
++\h'-04' 1.\h'+01'\c
++.\}
++.el \{\
++.sp -1
++.IP " 1." 4.2
++.\}
++If you are using the option
++\fB\-XX:+UseSHM\fR
++(instead of
++\fB\-XX:+UseHugeTLBFS\fR), then increase the
++\fBSHMMAX\fR
++value\&. It must be larger than the Java heap size\&. On a system with 4 GB of physical RAM (or less), the following will make all the memory sharable:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB# echo 4294967295 > /proc/sys/kernel/shmmax\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04' 2.\h'+01'\c
++.\}
++.el \{\
++.sp -1
++.IP " 2." 4.2
++.\}
++If you are using the option
++\fB\-XX:+UseSHM\fR
++or
++\fB\-XX:+UseHugeTLBFS\fR, then specify the number of large pages\&. In the following example, 3 GB of a 4 GB system are reserved for large pages (assuming a large page size of 2048kB, then 3 GB = 3 * 1024 MB = 3072 MB = 3072 * 1024 kB = 3145728 kB and 3145728 kB / 2048 kB = 1536):
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB# echo 1536 > /proc/sys/vm/nr_hugepages\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.if n \{\
++.sp
++.\}
++.RS 4
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBNote\fR
++.ps -1
++.br
++.TS
++allbox tab(:);
++l.
++T{
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++Note that the values contained in
++\fB/proc\fR
++will reset after you reboot your system, so may want to set them in an initialization script (for example,
++\fBrc\&.local\fR
++or
++\fBsysctl\&.conf\fR)\&.
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++If you configure (or resize) the OS kernel parameters
++\fB/proc/sys/kernel/shmmax\fR
++or
++\fB/proc/sys/vm/nr_hugepages\fR, Java processes may allocate large pages for areas in addition to the Java heap\&. These steps can allocate large pages for the following areas:
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++Java heap
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++Code cache
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++The marking bitmap data structure for the parallel GC
++.RE
++.sp
++Consequently, if you configure the
++\fBnr_hugepages\fR
++parameter to the size of the Java heap, then the JVM can fail in allocating the code cache areas on large pages because these areas are quite large in size\&.
++.RE
++T}
++.TE
++.sp 1
++.sp .5v
++.RE
++.RE
+ .SH "EXIT STATUS"
+ .PP
+ The following exit values are typically returned by the launcher when the launcher is called with the wrong arguments, serious errors, or exceptions thrown by the JVM\&. However, a Java application may choose to return any value by using the API call
+@@ -3456,6 +3786,17 @@
+ .\}
+ jar(1)
+ .RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++jstat(1)
++.RE
+ .br
+ 'pl 8.5i
+ 'bp
+--- ./jdk/src/solaris/doc/sun/man/man1/javac.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/javac.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,2116 +1,1370 @@
+ '\" t
+-.\" Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
+-.\"
+-.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-.\"
+-.\" This code is free software; you can redistribute it and/or modify it
+-.\" under the terms of the GNU General Public License version 2 only, as
+-.\" published by the Free Software Foundation.
+-.\"
+-.\" This code is distributed in the hope that it will be useful, but WITHOUT
+-.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-.\" version 2 for more details (a copy is included in the LICENSE file that
+-.\" accompanied this code).
+-.\"
+-.\" You should have received a copy of the GNU General Public License version
+-.\" 2 along with this work; if not, write to the Free Software Foundation,
+-.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-.\"
+-.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-.\" or visit www.oracle.com if you need additional information or have any
+-.\" questions.
+-.\"
+-.\" Title: javac
+-.\" Language: English
+-.\" Date: 8 August 2014
+-.\" SectDesc: Basic Tools
+-.\" Software: JDK 8
+-.\" Arch: generic
+-.\" Part Number: E38207-03
++.\" Copyright (c) 1994, 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.
++.\"
++.\" Arch: generic
++.\" Software: JDK 8
++.\" Date: 03 March 2015
++.\" SectDesc: Basic Tools
++.\" Title: javac.1
+ .\"
+ .if n .pl 99999
+-.TH "javac" "1" "8 August 2014" "JDK 8" "Basic Tools"
+-.\" -----------------------------------------------------------------
+-.\" * Define some portability stuff
+-.\" -----------------------------------------------------------------
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.\" http://bugs.debian.org/507673
+-.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.ie \n(.g .ds Aq \(aq
+-.el .ds Aq '
+-.\" -----------------------------------------------------------------
+-.\" * set default formatting
+-.\" -----------------------------------------------------------------
+-.\" disable hyphenation
+-.nh
+-.\" disable justification (adjust text to left margin only)
+-.ad l
+-.\" -----------------------------------------------------------------
+-.\" * MAIN CONTENT STARTS HERE *
+-.\" -----------------------------------------------------------------
+-.SH "NAME"
++.TH javac 1 "03 March 2015" "JDK 8" "Basic Tools"
++.\" -----------------------------------------------------------------
++.\" * Define some portability stuff
++.\" -----------------------------------------------------------------
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.\" http://bugs.debian.org/507673
++.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.ie \n(.g .ds Aq \(aq
++.el .ds Aq '
++.\" -----------------------------------------------------------------
++.\" * set default formatting
++.\" -----------------------------------------------------------------
++.\" disable hyphenation
++.nh
++.\" disable justification (adjust text to left margin only)
++.ad l
++.\" -----------------------------------------------------------------
++.\" * MAIN CONTENT STARTS HERE *
++.\" -----------------------------------------------------------------
++
++.SH NAME
+ javac \- Reads Java class and interface definitions and compiles them into bytecode and class files\&.
+-.SH "SYNOPSIS"
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
++.SH SYNOPSIS
++.sp
++.nf
++
+ \fBjavac\fR [ \fIoptions\fR ] [ \fIsourcefiles\fR ] [ \fIclasses\fR] [ \fI@argfiles\fR ]
+-.fi
+-.if n \{\
+-.RE
+-.\}
++.fi
++.sp
++Arguments can be in any order:
++.TP
++\fIoptions\fR
++Command-line options\&. See Options\&.
++.TP
++\fIsourcefiles\fR
++One or more source files to be compiled (such as \f3MyClass\&.java\fR)\&.
++.TP
++\fIclasses\fR
++One or more classes to be processed for annotations (such as \f3MyPackage\&.MyClass\fR)\&.
++.TP
++\fI@argfiles\fR
++One or more files that list options and source files\&. The \f3-J\fR options are not allowed in these files\&. See Command-Line Argument Files\&.
++.SH DESCRIPTION
++The \f3javac\fR command reads class and interface definitions, written in the Java programming language, and compiles them into bytecode class files\&. The \f3javac\fR command can also process annotations in Java source files and classes\&.
+ .PP
+-Arguments can be in any order:
++There are two ways to pass source code file names to \f3javac\fR\&.
++.TP 0.2i
++\(bu
++For a small number of source files, list the file names on the command line\&.
++.TP 0.2i
++\(bu
++For a large number of source files, list the file names in a file that is separated by blanks or line breaks\&. Use the list file name preceded by an at sign (@) with the \f3javac\fR command\&.
+ .PP
+-\fIoptions\fR
+-.RS 4
+-Command\-line options\&. See Options\&.
+-.RE
++Source code file names must have \&.java suffixes, class file names must have \&.class suffixes, and both source and class files must have root names that identify the class\&. For example, a class called \f3MyClass\fR would be written in a source file called \f3MyClass\&.java\fR and compiled into a bytecode class file called \f3MyClass\&.class\fR\&.
+ .PP
+-\fIsourcefiles\fR
+-.RS 4
+-One or more source files to be compiled (such as
+-\fBMyClass\&.java\fR)\&.
+-.RE
++Inner class definitions produce additional class files\&. These class files have names that combine the inner and outer class names, such as \f3MyClass$MyInnerClass\&.class\fR\&.
+ .PP
+-\fIclasses\fR
+-.RS 4
+-One or more classes to be processed for annotations (such as
+-\fBMyPackage\&.MyClass\fR)\&.
+-.RE
++Arrange source files in a directory tree that reflects their package tree\&. For example, if all of your source files are in \f3/workspace\fR, then put the source code for \f3com\&.mysoft\&.mypack\&.MyClass\fR in \f3/workspace/com/mysoft/mypack/MyClass\&.java\fR\&.
+ .PP
+-\fI@argfiles\fR
+-.RS 4
+-One or more files that list options and source files\&. The
+-\fB\-J\fR
+-options are not allowed in these files\&. See Command\-Line Argument Files\&.
+-.RE
+-.SH "DESCRIPTION"
++By default, the compiler puts each class file in the same directory as its source file\&. You can specify a separate destination directory with the \f3-d\fR option\&.
++.SH OPTIONS
++The compiler has a set of standard options that are supported on the current development environment\&. An additional set of nonstandard options are specific to the current virtual machine and compiler implementations and are subject to change in the future\&. Nonstandard options begin with the \f3-X\fR option\&.
++.TP 0.2i
++\(bu
++See also Cross-Compilation Options
++.TP 0.2i
++\(bu
++See also Nonstandard Options
++.SS STANDARD\ OPTIONS
++.TP
++-A\fIkey\fR[\fI=value\fR]
++.br
++Specifies options to pass to annotation processors\&. These options are not interpreted by \f3javac\fR directly, but are made available for use by individual processors\&. The \f3key\fR value should be one or more identifiers separated by a dot (\&.)\&.
++.TP
++-cp \fIpath\fR or -classpath \fIpath\fR
++.br
++Specifies where to find user class files, and (optionally) annotation processors and source files\&. This class path overrides the user class path in the \f3CLASSPATH\fR environment variable\&. If neither \f3CLASSPATH\fR, \f3-cp\fR nor \f3-classpath\fR is specified, then the user \fIclass path\fR is the current directory\&. See Setting the Class Path\&.
++
++If the \f3-sourcepath\fR option is not specified, then the user class path is also searched for source files\&.
++
++If the \f3-processorpath\fR option is not specified, then the class path is also searched for annotation processors\&.
++.TP
++-Djava\&.ext\&.dirs=\fIdirectories\fR
++.br
++Overrides the location of installed extensions\&.
++.TP
++-Djava\&.endorsed\&.dirs=\fIdirectories\fR
++.br
++Overrides the location of the endorsed standards path\&.
++.TP
++-d \fIdirectory\fR
++.br
++Sets the destination directory for class files\&. The directory must already exist because \f3javac\fR does not create it\&. If a class is part of a package, then \f3javac\fR puts the class file in a subdirectory that reflects the package name and creates directories as needed\&.
++
++If you specify \f3-d\fR\f3/home/myclasses\fR and the class is called \f3com\&.mypackage\&.MyClass\fR, then the class file is \f3/home/myclasses/com/mypackage/MyClass\&.class\fR\&.
++
++If the \fI-d\fR option is not specified, then \f3javac\fR puts each class file in the same directory as the source file from which it was generated\&.
++
++\fINote:\fR The directory specified by the \fI-d\fR option is not automatically added to your user class path\&.
++.TP
++-deprecation
++.br
++Shows a description of each use or override of a deprecated member or class\&. Without the \f3-deprecation\fR option, \f3javac\fR shows a summary of the source files that use or override deprecated members or classes\&. The \f3-deprecation\fR option is shorthand for \f3-Xlint:deprecation\fR\&.
++.TP
++-encoding \fIencoding\fR
++.br
++Sets the source file encoding name, such as EUC-JP and UTF-8\&. If the \f3-encoding\fR option is not specified, then the platform default converter is used\&.
++.TP
++-endorseddirs \fIdirectories\fR
++.br
++Overrides the location of the endorsed standards path\&.
++.TP
++-extdirs \fIdirectories\fR
++.br
++Overrides the location of the \f3ext\fR directory\&. The directories variable is a colon-separated list of directories\&. Each JAR file in the specified directories is searched for class files\&. All JAR files found become part of the class path\&.
++
++If you are cross-compiling (compiling classes against bootstrap and extension classes of a different Java platform implementation), then this option specifies the directories that contain the extension classes\&. See Cross-Compilation Options for more information\&.
++.TP
++-g
++.br
++Generates all debugging information, including local variables\&. By default, only line number and source file information is generated\&.
++.TP
++-g:none
++.br
++Does not generate any debugging information\&.
++.TP
++-g:[\fIkeyword list\fR]
++.br
++Generates only some kinds of debugging information, specified by a comma separated list of keywords\&. Valid keywords are:
++.RS
++.TP
++source
++Source file debugging information\&.
++.TP
++lines
++Line number debugging information\&.
++.TP
++vars
++Local variable debugging information\&.
++.RE
++
++.TP
++-help
++.br
++Prints a synopsis of standard options\&.
++.TP
++-implicit:[\fIclass, none\fR]
++.br
++Controls the generation of class files for implicitly loaded source files\&. To automatically generate class files, use \f3-implicit:class\fR\&. To suppress class file generation, use \f3-implicit:none\fR\&. If this option is not specified, then the default is to automatically generate class files\&. In this case, the compiler issues a warning if any such class files are generated when also doing annotation processing\&. The warning is not issued when the \f3-implicit\fR option is set explicitly\&. See Searching for Types\&.
++.TP
++-J\fIoption\fR
++.br
++Passes \f3option\fR to the Java Virtual Machine (JVM), where option is one of the options described on the reference page for the Java launcher\&. For example, \f3-J-Xms48m\fR sets the startup memory to 48 MB\&. See java(1)\&.
++
++\fINote:\fR The \fICLASSPATH\fR, \f3-classpath\fR, \f3-bootclasspath\fR, and \f3-extdirs\fR options do not specify the classes used to run \f3javac\fR\&. Trying to customize the compiler implementation with these options and variables is risky and often does not accomplish what you want\&. If you must customize the complier implementation, then use the \f3-J\fR option to pass options through to the underlying \f3\fRJava launcher\&.
++.TP
++-nowarn
++.br
++Disables warning messages\&. This option operates the same as the \f3-Xlint:none\fR option\&.
++.TP
++-parameters
++.br
++Stores formal parameter names of constructors and methods in the generated class file so that the method \f3java\&.lang\&.reflect\&.Executable\&.getParameters\fR from the Reflection API can retrieve them\&.
++.TP
++-proc: [\fInone\fR, \fIonly\fR]
++.br
++Controls whether annotation processing and compilation are done\&. \f3-proc:none\fR means that compilation takes place without annotation processing\&. \f3-proc:only\fR means that only annotation processing is done, without any subsequent compilation\&.
++.TP
++-processor \fIclass1\fR [,\fIclass2\fR,\fIclass3\fR\&.\&.\&.]
++.br
++Names of the annotation processors to run\&. This bypasses the default discovery process\&.
++.TP
++-processorpath \fIpath\fR
++.br
++Specifies where to find annotation processors\&. If this option is not used, then the class path is searched for processors\&.
++.TP
++-s \fIdir\fR
++.br
++Specifies the directory where to place the generated source files\&. The directory must already exist because \f3javac\fR does not create it\&. If a class is part of a package, then the compiler puts the source file in a subdirectory that reflects the package name and creates directories as needed\&.
++
++If you specify \f3-s /home/mysrc\fR and the class is called \f3com\&.mypackage\&.MyClass\fR, then the source file is put in \f3/home/mysrc/com/mypackage/MyClass\&.java\fR\&.
++.TP
++-source \fIrelease\fR
++.br
++Specifies the version of source code accepted\&. The following values for \f3release\fR are allowed:
++.RS
++.TP
++1\&.3
++The compiler does not support assertions, generics, or other language features introduced after Java SE 1\&.3\&.
++.TP
++1\&.4
++The compiler accepts code containing assertions, which were introduced in Java SE 1\&.4\&.
++.TP
++1\&.5
++The compiler accepts code containing generics and other language features introduced in Java SE 5\&.
++.TP
++5
++Synonym for 1\&.5\&.
++.TP
++1\&.6
++No language changes were introduced in Java SE 6\&. However, encoding errors in source files are now reported as errors instead of warnings as in earlier releases of Java Platform, Standard Edition\&.
++.TP
++6
++Synonym for 1\&.6\&.
++.TP
++1\&.7
++The compiler accepts code with features introduced in Java SE 7\&.
++.TP
++7
++Synonym for 1\&.7\&.
++.TP
++1\&.8
++This is the default value\&. The compiler accepts code with features introduced in Java SE 8\&.
++.TP
++8
++Synonym for 1\&.8\&.
++.RE
++
++.TP
++-sourcepath \fIsourcepath\fR
++.br
++Specifies the source code path to search for class or interface definitions\&. As with the user class path, source path entries are separated by colons (:) on Oracle Solaris and semicolons on Windows and can be directories, JAR archives, or ZIP archives\&. If packages are used, then the local path name within the directory or archive must reflect the package name\&.
++
++\fINote:\fR Classes found through the class path might be recompiled when their source files are also found\&. See Searching for Types\&.
++.TP
++-verbose
++.br
++Uses verbose output, which includes information about each class loaded and each source file compiled\&.
++.TP
++-version
++.br
++Prints release information\&.
++.TP
++-werror
++.br
++Terminates compilation when warnings occur\&.
++.TP
++-X
++.br
++Displays information about nonstandard options and exits\&.
++.SS CROSS-COMPILATION\ OPTIONS
++By default, classes are compiled against the bootstrap and extension classes of the platform that \f3javac\fR shipped with\&. But \f3javac\fR also supports cross-compiling, where classes are compiled against a bootstrap and extension classes of a different Java platform implementation\&. It is important to use the \f3-bootclasspath\fR and \f3-extdirs\fR options when cross-compiling\&.
++.TP
++-target \fIversion\fR
++.br
++Generates class files that target a specified release of the virtual machine\&. Class files will run on the specified target and on later releases, but not on earlier releases of the JVM\&. Valid targets are 1\&.1, 1\&.2, 1\&.3, 1\&.4, 1\&.5 (also 5), 1\&.6 (also 6), 1\&.7 (also 7), and 1\&.8 (also 8)\&.
++
++The default for the \f3-target\fR option depends on the value of the \f3-source\fR option:
++.RS
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is not specified, then the value of the \f3-target\fR option is 1\&.8
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is 1\&.2, then the value of the \f3-target\fR option is 1\&.4
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is 1\&.3, then the value of the \f3-target\fR option is 1\&.4
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is 1\&.5, then the value of the \f3-target\fR option is 1\&.8
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is 1\&.6, then the value of the \f3-target\fR is option 1\&.8
++.TP 0.2i
++\(bu
++If the \f3-source\fR option is 1\&.7, then the value of the \f3-target\fR is option 1\&.8
++.TP 0.2i
++\(bu
++For all other values of the \f3-source\fR option, the value of the \f3-target\fR option is the value of the \f3-source\fR option\&.
++.RE
++
++.TP
++-bootclasspath \fIbootclasspath\fR
++.br
++Cross-compiles against the specified set of boot classes\&. As with the user class path, boot class path entries are separated by colons (:) and can be directories, JAR archives, or ZIP archives\&.
++.SS COMPACT\ PROFILE\ OPTION
++Beginning with JDK 8, the \f3javac\fR compiler supports compact profiles\&. With compact profiles, applications that do not require the entire Java platform can be deployed and run with a smaller footprint\&. The compact profiles feature could be used to shorten the download time for applications from app stores\&. This feature makes for more compact deployment of Java applications that bundle the JRE\&. This feature is also useful in small devices\&.
+ .PP
+-The
+-\fBjavac\fR
+-command reads class and interface definitions, written in the Java programming language, and compiles them into bytecode class files\&. The
+-\fBjavac\fR
+-command can also process annotations in Java source files and classes\&.
++The supported profile values are \f3compact1\fR, \f3compact2\fR, and \f3compact3\fR\&. These are additive layers\&. Each higher-numbered compact profile contains all of the APIs in profiles with smaller number names\&.
++.TP
++-profile
++.br
++When using compact profiles, this option specifies the profile name when compiling\&. For example:
++.sp
++.nf
++\f3javac \-profile compact1 Hello\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++javac does not compile source code that uses any Java SE APIs that is not in the specified profile\&. Here is an example of the error message that results from attempting to compile such source code:
++.sp
++.nf
++\f3cd jdk1\&.8\&.0/bin\fP
++.fi
++.nf
++\f3\&./javac \-profile compact1 Paint\&.java\fP
++.fi
++.nf
++\f3Paint\&.java:5: error: Applet is not available in profile \&'compact1\&'\fP
++.fi
++.nf
++\f3import java\&.applet\&.Applet;\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++In this example, you can correct the error by modifying the source to not use the \f3Applet\fR class\&. You could also correct the error by compiling without the -profile option\&. Then the compilation would be run against the full set of Java SE APIs\&. (None of the compact profiles include the \f3Applet\fR class\&.)
++
++An alternative way to compile with compact profiles is to use the \f3-bootclasspath\fR option to specify a path to an \f3rt\&.jar\fR file that specifies a profile\&'s image\&. Using the \f3-profile\fR option instead does not require a profile image to be present on the system at compile time\&. This is useful when cross-compiling\&.
++.SS NONSTANDARD\ OPTIONS
++.TP
++-Xbootclasspath/p:\fIpath\fR
++.br
++Adds a suffix to the bootstrap class path\&.
++.TP
++-Xbootclasspath/a:\fIpath\fR
++.br
++Adds a prefix to the bootstrap class path\&.
++.TP
++-Xbootclasspath/:\fIpath\fR
++.br
++Overrides the location of the bootstrap class files\&.
++.TP
++-Xdoclint:[-]\fIgroup\fR [\fI/access\fR]
++.br
++Enables or disables specific groups of checks, where \fIgroup\fR is one of the following values: \f3accessibility\fR, \f3syntax\fR, \f3reference\fR, \f3html\fR or \f3missing\fR\&. For more information about these groups of checks see the \f3-Xdoclint\fR option of the \f3javadoc\fR command\&. The \f3-Xdoclint\fR option is disabled by default in the \f3javac\fR command\&.
++
++The variable \fIaccess\fR specifies the minimum visibility level of classes and members that the \f3-Xdoclint\fR option checks\&. It can have one of the following values (in order of most to least visible) : \f3public\fR, \f3protected\fR, \f3package\fR and \f3private\fR\&. For example, the following option checks classes and members (with all groups of checks) that have the access level protected and higher (which includes protected, package and public):
++.sp
++.nf
++\f3\-Xdoclint:all/protected\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The following option enables all groups of checks for all access levels, except it will not check for HTML errors for classes and members that have access level package and higher (which includes package and public):
++.sp
++.nf
++\f3\-Xdoclint:all,\-html/package\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++-Xdoclint:none
++.br
++Disables all groups of checks\&.
++.TP
++-Xdoclint:all[\fI/access\fR]
++.br
++Enables all groups of checks\&.
++.TP
++-Xlint
++.br
++\fI\fREnables all recommended warnings\&. In this release, enabling all available warnings is recommended\&.
++.TP
++-Xlint:all
++.br
++\fI\fREnables all recommended warnings\&. In this release, enabling all available warnings is recommended\&.
++.TP
++-Xlint:none
++.br
++Disables all warnings\&.
++.TP
++-Xlint:\fIname\fR
++.br
++Disables warning name\&. See Enable or Disable Warnings with the -Xlint Option for a list of warnings you can disable with this option\&.
++.TP
++-Xlint:\fI-name\fR
++.br
++Disables warning name\&. See Enable or Disable Warnings with the -Xlint Option with the \f3-Xlint\fR option to get a list of warnings that you can disable with this option\&.
++.TP
++-Xmaxerrs \fInumber\fR
++.br
++Sets the maximum number of errors to print\&.
++.TP
++-Xmaxwarns \fInumber\fR
++.br
++Sets the maximum number of warnings to print\&.
++.TP
++-Xstdout \fIfilename\fR
++.br
++Sends compiler messages to the named file\&. By default, compiler messages go to \f3System\&.err\fR\&.
++.TP
++-Xprefer:[\fInewer,source\fR]
++.br
++Specifies which file to read when both a source file and class file are found for a type\&. (See Searching for Types)\&. If the \f3-Xprefer:newer\fR option is used, then it reads the newer of the source or class file for a type (default)\&. If the \f3-Xprefer:source\fR option is used, then it reads the source file\&. Use -\f3Xprefer:source\fR when you want to be sure that any annotation processors can access annotations declared with a retention policy of \f3SOURCE\fR\&.
++.TP
++-Xpkginfo:[\fIalways\fR,\fIlegacy\fR,\fInonempty\fR]
++.br
++Control whether javac generates \f3package-info\&.class\fR files from package-info\&.java files\&. Possible mode arguments for this option include the following\&.
++.RS
++.TP
++always
++Always generate a \f3package-info\&.class\fR file for every \f3package-info\&.java\fR file\&. This option may be useful if you use a build system such as Ant, which checks that each \f3\&.java\fR file has a corresponding \f3\&.class\fR file\&.
++.TP
++legacy
++Generate a \f3package-info\&.class\fR file only if package-info\&.java contains annotations\&. Don\&'t generate a \f3package-info\&.class\fR file if package-info\&.java only contains comments\&.
++
++\fINote:\fR A \f3package-info\&.class\fR file might be generated but be empty if all the annotations in the package-info\&.java file have \f3RetentionPolicy\&.SOURCE\fR\&.
++.TP
++nonempty
++Generate a \f3package-info\&.class\fR file only if package-info\&.java contains annotations with \f3RetentionPolicy\&.CLASS\fR or \f3RetentionPolicy\&.RUNTIME\fR\&.
++.RE
++
++.TP
++-Xprint
++.br
++Prints a textual representation of specified types for debugging purposes\&. Perform neither annotation processing nor compilation\&. The format of the output could change\&.
++.TP
++-XprintProcessorInfo
++.br
++Prints information about which annotations a processor is asked to process\&.
++.TP
++-XprintRounds
++.br
++Prints information about initial and subsequent annotation processing rounds\&.
++.SH ENABLE\ OR\ DISABLE\ WARNINGS\ WITH\ THE\ -XLINT\ OPTION
++Enable warning \fIname\fR with the \f3-Xlint:name\fR option, where \f3name\fR is one of the following warning names\&. Note that you can disable a warning with the \f3-Xlint:-name:\fR option\&.
++.TP
++cast
++Warns about unnecessary and redundant casts, for example:
++.sp
++.nf
++\f3String s = (String) "Hello!"\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++classfile
++Warns about issues related to class file contents\&.
++.TP
++deprecation
++Warns about the use of deprecated items, for example:
++.sp
++.nf
++\f3java\&.util\&.Date myDate = new java\&.util\&.Date();\fP
++.fi
++.nf
++\f3int currentDay = myDate\&.getDay();\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The method \f3java\&.util\&.Date\&.getDay\fR has been deprecated since JDK 1\&.1
++.TP
++dep-ann
++Warns about items that are documented with an \f3@deprecated\fR Javadoc comment, but do not have a \f3@Deprecated\fR annotation, for example:
++.sp
++.nf
++\f3/**\fP
++.fi
++.nf
++\f3 * @deprecated As of Java SE 7, replaced by {@link #newMethod()}\fP
++.fi
++.nf
++\f3 */\fP
++.fi
++.nf
++\f3public static void deprecatedMethood() { }\fP
++.fi
++.nf
++\f3public static void newMethod() { }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++divzero
++Warns about division by the constant integer 0, for example:
++.sp
++.nf
++\f3int divideByZero = 42 / 0;\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++empty
++Warns about empty statements after \f3if\fRstatements, for example:
++.sp
++.nf
++\f3class E {\fP
++.fi
++.nf
++\f3 void m() {\fP
++.fi
++.nf
++\f3 if (true) ;\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++fallthrough
++Checks the switch blocks for fall-through cases and provides a warning message for any that are found\&. Fall-through cases are cases in a switch block, other than the last case in the block, whose code does not include a break statement, allowing code execution to fall through from that case to the next case\&. For example, the code following the case 1 label in this switch block does not end with a break statement:
++.sp
++.nf
++\f3switch (x) {\fP
++.fi
++.nf
++\f3case 1:\fP
++.fi
++.nf
++\f3 System\&.out\&.println("1");\fP
++.fi
++.nf
++\f3 // No break statement here\&.\fP
++.fi
++.nf
++\f3case 2:\fP
++.fi
++.nf
++\f3 System\&.out\&.println("2");\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++If the \f3-Xlint:fallthrough\fR option was used when compiling this code, then the compiler emits a warning about possible fall-through into case, with the line number of the case in question\&.
++.TP
++finally
++Warns about \f3finally\fR clauses that cannot complete normally, for example:
++.sp
++.nf
++\f3public static int m() {\fP
++.fi
++.nf
++\f3 try {\fP
++.fi
++.nf
++\f3 throw new NullPointerException();\fP
++.fi
++.nf
++\f3 } catch (NullPointerException(); {\fP
++.fi
++.nf
++\f3 System\&.err\&.println("Caught NullPointerException\&.");\fP
++.fi
++.nf
++\f3 return 1;\fP
++.fi
++.nf
++\f3 } finally {\fP
++.fi
++.nf
++\f3 return 0;\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The compiler generates a warning for the \f3finally\fR block in this example\&. When the \f3int\fR method is called, it returns a value of 0\&. A \f3finally\fR block executes when the \f3try\fR block exits\&. In this example, when control is transferred to the \f3catch\fR block, the \f3int\fR method exits\&. However, the \f3finally\fR block must execute, so it is executed, even though control was transferred outside the method\&.
++.TP
++options
++Warns about issues that related to the use of command-line options\&. See Cross-Compilation Options\&.
++.TP
++overrides
++Warns about issues regarding method overrides\&. For example, consider the following two classes:
++.sp
++.nf
++\f3public class ClassWithVarargsMethod {\fP
++.fi
++.nf
++\f3 void varargsMethod(String\&.\&.\&. s) { }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3public class ClassWithOverridingMethod extends ClassWithVarargsMethod {\fP
++.fi
++.nf
++\f3 @Override\fP
++.fi
++.nf
++\f3 void varargsMethod(String[] s) { }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The compiler generates a warning similar to the following:\&.
++.sp
++.nf
++\f3warning: [override] varargsMethod(String[]) in ClassWithOverridingMethod \fP
++.fi
++.nf
++\f3overrides varargsMethod(String\&.\&.\&.) in ClassWithVarargsMethod; overriding\fP
++.fi
++.nf
++\f3method is missing \&'\&.\&.\&.\&'\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++When the compiler encounters a \f3varargs\fR method, it translates the \f3varargs\fR formal parameter into an array\&. In the method \f3ClassWithVarargsMethod\&.varargsMethod\fR, the compiler translates the \f3varargs\fR formal parameter \f3String\&.\&.\&. s\fR to the formal parameter \f3String[] s\fR, an array, which matches the formal parameter of the method \f3ClassWithOverridingMethod\&.varargsMethod\fR\&. Consequently, this example compiles\&.
++.TP
++path
++Warns about invalid path elements and nonexistent path directories on the command line (with regard to the class path, the source path, and other paths)\&. Such warnings cannot be suppressed with the \f3@SuppressWarnings\fR annotation, for example:
++.sp
++.nf
++\f3javac \-Xlint:path \-classpath /nonexistentpath Example\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++processing
++Warn about issues regarding annotation processing\&. The compiler generates this warning when you have a class that has an annotation, and you use an annotation processor that cannot handle that type of exception\&. For example, the following is a simple annotation processor:
++
++\fISource file AnnocProc\&.java\fR:
++.sp
++.nf
++\f3import java\&.util\&.*;\fP
++.fi
++.nf
++\f3import javax\&.annotation\&.processing\&.*;\fP
++.fi
++.nf
++\f3import javax\&.lang\&.model\&.*;\fP
++.fi
++.nf
++\f3import\&.javaz\&.lang\&.model\&.element\&.*;\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3@SupportedAnnotationTypes("NotAnno")\fP
++.fi
++.nf
++\f3public class AnnoProc extends AbstractProcessor {\fP
++.fi
++.nf
++\f3 public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv){\fP
++.fi
++.nf
++\f3 return true;\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3 public SourceVersion getSupportedSourceVersion() {\fP
++.fi
++.nf
++\f3 return SourceVersion\&.latest();\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++\fISource file AnnosWithoutProcessors\&.java\fR:
++.sp
++.nf
++\f3@interface Anno { }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3@Anno\fP
++.fi
++.nf
++\f3class AnnosWithoutProcessors { }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The following commands compile the annotation processor \f3AnnoProc\fR, then run this annotation processor against the source file \f3AnnosWithoutProcessors\&.java\fR:
++.sp
++.nf
++\f3javac AnnoProc\&.java\fP
++.fi
++.nf
++\f3javac \-cp \&. \-Xlint:processing \-processor AnnoProc \-proc:only AnnosWithoutProcessors\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++When the compiler runs the annotation processor against the source file \f3AnnosWithoutProcessors\&.java\fR, it generates the following warning:
++.sp
++.nf
++\f3warning: [processing] No processor claimed any of these annotations: Anno\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++To resolve this issue, you can rename the annotation defined and used in the class \f3AnnosWithoutProcessors\fR from \f3Anno\fR to \f3NotAnno\fR\&.
++.TP
++rawtypes
++Warns about unchecked operations on raw types\&. The following statement generates a \f3rawtypes\fR warning:
++.sp
++.nf
++\f3void countElements(List l) { \&.\&.\&. }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The following example does not generate a \f3rawtypes\fR warning
++.sp
++.nf
++\f3void countElements(List<?> l) { \&.\&.\&. }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++\f3List\fR is a raw type\&. However, \f3List<?>\fR is an unbounded wildcard parameterized type\&. Because \f3List\fR is a parameterized interface, always specify its type argument\&. In this example, the \f3List\fR formal argument is specified with an unbounded wildcard (\f3?\fR) as its formal type parameter, which means that the \f3countElements\fR method can accept any instantiation of the \f3List\fR interface\&.
++.TP
++Serial
++Warns about missing \f3serialVersionUID\fR definitions on serializable classes, for example:
++.sp
++.nf
++\f3public class PersistentTime implements Serializable\fP
++.fi
++.nf
++\f3{\fP
++.fi
++.nf
++\f3 private Date time;\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3 public PersistentTime() {\fP
++.fi
++.nf
++\f3 time = Calendar\&.getInstance()\&.getTime();\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3 public Date getTime() {\fP
++.fi
++.nf
++\f3 return time;\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The compiler generates the following warning:
++.sp
++.nf
++\f3warning: [serial] serializable class PersistentTime has no definition of\fP
++.fi
++.nf
++\f3serialVersionUID\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++If a serializable class does not explicitly declare a field named \f3serialVersionUID\fR, then the serialization runtime environment calculates a default \f3serialVersionUID\fR value for that class based on various aspects of the class, as described in the Java Object Serialization Specification\&. However, it is strongly recommended that all serializable classes explicitly declare \f3serialVersionUID\fR values because the default process of computing \f3serialVersionUID\fR vales is highly sensitive to class details that can vary depending on compiler implementations, and as a result, might cause an unexpected \f3InvalidClassExceptions\fR during deserialization\&. To guarantee a consistent \f3serialVersionUID\fR value across different Java compiler implementations, a serializable class must declare an explicit \f3serialVersionUID\fR value\&.
++.TP
++static
++Warns about issues relating to the use of statics, for example:
++.sp
++.nf
++\f3class XLintStatic {\fP
++.fi
++.nf
++\f3 static void m1() { }\fP
++.fi
++.nf
++\f3 void m2() { this\&.m1(); }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++The compiler generates the following warning:
++.sp
++.nf
++\f3warning: [static] static method should be qualified by type name, \fP
++.fi
++.nf
++\f3XLintStatic, instead of by an expression\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++To resolve this issue, you can call the \f3static\fR method \f3m1\fR as follows:
++.sp
++.nf
++\f3XLintStatic\&.m1();\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++Alternately, you can remove the \f3static\fR keyword from the declaration of the method \f3m1\fR\&.
++.TP
++try
++Warns about issues relating to use of \f3try\fR blocks, including try-with-resources statements\&. For example, a warning is generated for the following statement because the resource \f3ac\fR declared in the \f3try\fR block is not used:
++.sp
++.nf
++\f3try ( AutoCloseable ac = getResource() ) { // do nothing}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++.TP
++unchecked
++Gives more detail for unchecked conversion warnings that are mandated by the Java Language Specification, for example:
++.sp
++.nf
++\f3List l = new ArrayList<Number>();\fP
++.fi
++.nf
++\f3List<String> ls = l; // unchecked warning\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++During type erasure, the types \f3ArrayList<Number>\fR and \f3List<String>\fR become \f3ArrayList\fR and \f3List\fR, respectively\&.
++
++The \f3ls\fR command has the parameterized type \f3List<String>\fR\&. When the \f3List\fR referenced by \f3l\fR is assigned to \f3ls\fR, the compiler generates an unchecked warning\&. At compile time, the compiler and JVM cannot determine whether \f3l\fR refers to a \f3List<String>\fR type\&. In this case, \f3l\fR does not refer to a \f3List<String>\fR type\&. As a result, heap pollution occurs\&.
++
++A heap pollution situation occurs when the \f3List\fR object \f3l\fR, whose static type is \f3List<Number>\fR, is assigned to another \f3List\fR object, \f3ls\fR, that has a different static type, \f3List<String>\fR\&. However, the compiler still allows this assignment\&. It must allow this assignment to preserve backward compatibility with releases of Java SE that do not support generics\&. Because of type erasure, \f3List<Number>\fR and \f3List<String>\fR both become \f3List\fR\&. Consequently, the compiler allows the assignment of the object \f3l\fR\f3,\fR which has a raw type of \f3List\fR, to the object \f3ls\fR\&.
++.TP
++varargs
++Warns about unsafe usages of variable arguments (\f3varargs\fR) methods, in particular, those that contain non-reifiable arguments, for example:
++.sp
++.nf
++\f3public class ArrayBuilder {\fP
++.fi
++.nf
++\f3 public static <T> void addToList (List<T> listArg, T\&.\&.\&. elements) {\fP
++.fi
++.nf
++\f3 for (T x : elements) {\fP
++.fi
++.nf
++\f3 listArg\&.add(x);\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++\fINote:\fR A non-reifiable type is a type whose type information is not fully available at runtime\&.
++
++The compiler generates the following warning for the definition of the method \f3ArrayBuilder\&.addToList\fR
++.sp
++.nf
++\f3warning: [varargs] Possible heap pollution from parameterized vararg type T\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++
++
++When the compiler encounters a varargs method, it translates the \f3varargs\fR formal parameter into an array\&. However, the Java programming language does not permit the creation of arrays of parameterized types\&. In the method \f3ArrayBuilder\&.addToList\fR, the compiler translates the \f3varargs\fR formal parameter \f3T\&.\&.\&.\fR elements to the formal parameter \f3T[]\fR elements, an array\&. However, because of type erasure, the compiler converts the \f3varargs\fR formal parameter to \f3Object[]\fR elements\&. Consequently, there is a possibility of heap pollution\&.
++.SH COMMAND-LINE\ ARGUMENT\ FILES
++To shorten or simplify the \f3javac\fR command, you can specify one or more files that contain arguments to the \f3javac\fR command (except \f3-J\fR options)\&. This enables you to create \f3javac\fR commands of any length on any operating system\&.
+ .PP
+-There are two ways to pass source code file names to
+-\fBjavac\fR\&.
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-For a small number of source files, list the file names on the command line\&.
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-For a large number of source files, list the file names in a file that is separated by blanks or line breaks\&. Use the list file name preceded by an at sign (@) with the
+-\fBjavac\fR
+-command\&.
+-.RE
++An argument file can include \f3javac\fR options and source file names in any combination\&. The arguments within a file can be separated by spaces or new line characters\&. If a file name contains embedded spaces, then put the whole file name in double quotation marks\&.
+ .PP
+-Source code file names must have \&.java suffixes, class file names must have \&.class suffixes, and both source and class files must have root names that identify the class\&. For example, a class called
+-\fBMyClass\fR
+-would be written in a source file called
+-\fBMyClass\&.java\fR
+-and compiled into a bytecode class file called
+-\fBMyClass\&.class\fR\&.
++File Names within an argument file are relative to the current directory, not the location of the argument file\&. Wild cards (*) are not allowed in these lists (such as for specifying \f3*\&.java\fR)\&. Use of the at sign (@) to recursively interpret files is not supported\&. The \f3-J\fR options are not supported because they are passed to the launcher, which does not support argument files\&.
+ .PP
+-Inner class definitions produce additional class files\&. These class files have names that combine the inner and outer class names, such as
+-\fBMyClass$MyInnerClass\&.class\fR\&.
++When executing the \f3javac\fR command, pass in the path and name of each argument file with the at sign (@) leading character\&. When the \f3javac\fR command encounters an argument beginning with the at sign (@), it expands the contents of that file into the argument list\&.
+ .PP
+-Arrange source files in a directory tree that reflects their package tree\&. For example, if all of your source files are in
+-\fB/workspace\fR, then put the source code for
+-\fBcom\&.mysoft\&.mypack\&.MyClass\fR
+-in
+-\fB/workspace/com/mysoft/mypack/MyClass\&.java\fR\&.
++\f3Example 1 Single Argument File\fR
+ .PP
+-By default, the compiler puts each class file in the same directory as its source file\&. You can specify a separate destination directory with the
+-\fB\-d\fR
+-option\&.
+-.SH "OPTIONS"
++You could use a single argument file named \f3argfile\fR to hold all \f3javac\fR arguments:
++.sp
++.nf
++\f3javac @argfile\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++This argument file could contain the contents of both files shown in Example 2
+ .PP
+-The compiler has a set of standard options that are supported on the current development environment\&. An additional set of nonstandard options are specific to the current virtual machine and compiler implementations and are subject to change in the future\&. Nonstandard options begin with the
+-\fB\-X\fR
+-option\&.
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-See also Cross\-Compilation Options
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-See also Nonstandard Options
+-.RE
+-.SS "Standard Options"
++\f3Example 2 Two Argument Files\fR
+ .PP
+-\-A\fIkey\fR[\fI=value\fR]
+-.RS 4
+-Specifies options to pass to annotation processors\&. These options are not interpreted by
+-\fBjavac\fR
+-directly, but are made available for use by individual processors\&. The
+-\fBkey\fR
+-value should be one or more identifiers separated by a dot (\&.)\&.
+-.RE
++You can create two argument files: one for the \f3javac\fR options and the other for the source file names\&. Note that the following lists have no line-continuation characters\&.
+ .PP
+-\-cp \fIpath\fR or \-classpath \fIpath\fR
+-.RS 4
+-Specifies where to find user class files, and (optionally) annotation processors and source files\&. This class path overrides the user class path in the
+-\fBCLASSPATH\fR
+-environment variable\&. If neither
+-\fBCLASSPATH\fR,
+-\fB\-cp\fR
+-nor
+-\fB\-classpath\fR
+-is specified, then the user
+-\fIclass path\fR
+-is the current directory\&. See Setting the Class Path \&.
+-.sp
+-If the
+-\fB\-sourcepath\fR
+-option is not specified, then the user class path is also searched for source files\&.
+-.sp
+-If the
+-\fB\-processorpath\fR
+-option is not specified, then the class path is also searched for annotation processors\&.
+-.RE
++Create a file named options that contains the following:
++.sp
++.nf
++\f3\-d classes\fP
++.fi
++.nf
++\f3\-g\fP
++.fi
++.nf
++\f3\-sourcepath /java/pubs/ws/1\&.3/src/share/classes\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++Create a file named classes that contains the following:
++.sp
++.nf
++\f3MyClass1\&.java\fP
++.fi
++.nf
++\f3MyClass2\&.java\fP
++.fi
++.nf
++\f3MyClass3\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++Then, run the \f3javac\fR command as follows:
++.sp
++.nf
++\f3javac @options @classes\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++\f3Example 3 Argument Files with Paths\fR
+ .PP
+-\-Djava\&.ext\&.dirs=\fIdirectories\fR
+-.RS 4
+-Overrides the location of installed extensions\&.
+-.RE
++The argument files can have paths, but any file names inside the files are relative to the current working directory (not \f3path1\fR or \f3path2\fR):
++.sp
++.nf
++\f3javac @path1/options @path2/classes\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++.SH ANNOTATION\ PROCESSING
++The \f3javac\fR command provides direct support for annotation processing, superseding the need for the separate annotation processing command, \f3apt\fR\&.
+ .PP
+-\-Djava\&.endorsed\&.dirs=\fIdirectories\fR
+-.RS 4
+-Overrides the location of the endorsed standards path\&.
+-.RE
+-.PP
+-\-d \fIdirectory\fR
+-.RS 4
+-Sets the destination directory for class files\&. The directory must already exist because
+-\fBjavac\fR
+-does not create it\&. If a class is part of a package, then
+-\fBjavac\fR
+-puts the class file in a subdirectory that reflects the package name and creates directories as needed\&.
+-.sp
+-If you specify
+-\fB\-d\fR
+-\fB/home/myclasses\fR
+-and the class is called
+-\fBcom\&.mypackage\&.MyClass\fR, then the class file is
+-\fB/home/myclasses/com/mypackage/MyClass\&.class\fR\&.
+-.sp
+-If the
+-\fI\-d\fR
+-option is not specified, then
+-\fBjavac\fR
+-puts each class file in the same directory as the source file from which it was generated\&.
+-.sp
+-\fBNote:\fR
+-The directory specified by the
+-\fI\-d\fR
+-option is not automatically added to your user class path\&.
+-.RE
+-.PP
+-\-deprecation
+-.RS 4
+-Shows a description of each use or override of a deprecated member or class\&. Without the
+-\fB\-deprecation\fR
+-option,
+-\fBjavac\fR
+-shows a summary of the source files that use or override deprecated members or classes\&. The
+-\fB\-deprecation\fR
+-option is shorthand for
+-\fB\-Xlint:deprecation\fR\&.
+-.RE
+-.PP
+-\-encoding \fIencoding\fR
+-.RS 4
+-Sets the source file encoding name, such as EUC\-JP and UTF\-8\&. If the
+-\fB\-encoding\fR
+-option is not specified, then the platform default converter is used\&.
+-.RE
+-.PP
+-\-endorseddirs \fIdirectories\fR
+-.RS 4
+-Overrides the location of the endorsed standards path\&.
+-.RE
+-.PP
+-\-extdirs \fIdirectories\fR
+-.RS 4
+-Overrides the location of the
+-\fBext\fR
+-directory\&. The directories variable is a colon\-separated list of directories\&. Each JAR file in the specified directories is searched for class files\&. All JAR files found become part of the class path\&.
+-.sp
+-If you are cross\-compiling (compiling classes against bootstrap and extension classes of a different Java platform implementation), then this option specifies the directories that contain the extension classes\&. See Cross\-Compilation Options for more information\&.
+-.RE
+-.PP
+-\-g
+-.RS 4
+-Generates all debugging information, including local variables\&. By default, only line number and source file information is generated\&.
+-.RE
+-.PP
+-\-g:none
+-.RS 4
+-Does not generate any debugging information\&.
+-.RE
+-.PP
+-\-g:[\fIkeyword list\fR]
+-.RS 4
+-Generates only some kinds of debugging information, specified by a comma separated list of keywords\&. Valid keywords are:
+-.PP
+-source
+-.RS 4
+-Source file debugging information\&.
+-.RE
+-.PP
+-lines
+-.RS 4
+-Line number debugging information\&.
+-.RE
+-.PP
+-vars
+-.RS 4
+-Local variable debugging information\&.
+-.RE
+-.RE
+-.PP
+-\-help
+-.RS 4
+-Prints a synopsis of standard options\&.
+-.RE
+-.PP
+-\-implicit:[\fIclass, none\fR]
+-.RS 4
+-Controls the generation of class files for implicitly loaded source files\&. To automatically generate class files, use
+-\fB\-implicit:class\fR\&. To suppress class file generation, use
+-\fB\-implicit:none\fR\&. If this option is not specified, then the default is to automatically generate class files\&. In this case, the compiler issues a warning if any such class files are generated when also doing annotation processing\&. The warning is not issued when the
+-\fB\-implicit\fR
+-option is set explicitly\&. See Searching for Types\&.
+-.RE
+-.PP
+-\-J\fIoption\fR
+-.RS 4
+-Passes
+-\fBoption\fR
+-to the Java Virtual Machine (JVM), where option is one of the options described on the reference page for the Java launcher\&. For example,
+-\fB\-J\-Xms48m\fR
+-sets the startup memory to 48 MB\&. See
+-java(1)\&.
+-.sp
+-\fBNote:\fR
+-The
+-\fICLASSPATH\fR,
+-\fB\-classpath\fR,
+-\fB\-bootclasspath\fR, and
+-\fB\-extdirs\fR
+-options do not specify the classes used to run
+-\fBjavac\fR\&. Trying to customize the compiler implementation with these options and variables is risky and often does not accomplish what you want\&. If you must customize the complier implementation, then use the
+-\fB\-J\fR
+-option to pass options through to the underlying Java launcher\&.
+-.RE
+-.PP
+-\-nowarn
+-.RS 4
+-Disables warning messages\&. This option operates the same as the
+-\fB\-Xlint:none\fR
+-option\&.
+-.RE
+-.PP
+-\-parameters
+-.RS 4
+-Stores formal parameter names of constructors and methods in the generated class file so that the method
+-\fBjava\&.lang\&.reflect\&.Executable\&.getParameters\fR
+-from the Reflection API can retrieve them\&.
+-.RE
+-.PP
+-\-proc: [\fInone\fR, \fIonly\fR]
+-.RS 4
+-Controls whether annotation processing and compilation are done\&.
+-\fB\-proc:none\fR
+-means that compilation takes place without annotation processing\&.
+-\fB\-proc:only\fR
+-means that only annotation processing is done, without any subsequent compilation\&.
+-.RE
+-.PP
+-\-processor \fIclass1\fR [,\fIclass2\fR,\fIclass3\fR\&.\&.\&.]
+-.RS 4
+-Names of the annotation processors to run\&. This bypasses the default discovery process\&.
+-.RE
+-.PP
+-\-processorpath \fIpath\fR
+-.RS 4
+-Specifies where to find annotation processors\&. If this option is not used, then the class path is searched for processors\&.
+-.RE
+-.PP
+-\-s \fIdir\fR
+-.RS 4
+-Specifies the directory where to place the generated source files\&. The directory must already exist because
+-\fBjavac\fR
+-does not create it\&. If a class is part of a package, then the compiler puts the source file in a subdirectory that reflects the package name and creates directories as needed\&.
+-.sp
+-If you specify
+-\fB\-s /home/mysrc\fR
+-and the class is called
+-\fBcom\&.mypackage\&.MyClass\fR, then the source file is put in
+-\fB/home/mysrc/com/mypackage/MyClass\&.java\fR\&.
+-.RE
+-.PP
+-\-source \fIrelease\fR
+-.RS 4
+-Specifies the version of source code accepted\&. The following values for
+-\fBrelease\fR
+-are allowed:
+-.PP
+-1\&.3
+-.RS 4
+-The compiler does not support assertions, generics, or other language features introduced after Java SE 1\&.3\&.
+-.RE
+-.PP
+-1\&.4
+-.RS 4
+-The compiler accepts code containing assertions, which were introduced in Java SE 1\&.4\&.
+-.RE
+-.PP
+-1\&.5
+-.RS 4
+-The compiler accepts code containing generics and other language features introduced in Java SE 5\&.
+-.RE
+-.PP
+-5
+-.RS 4
+-Synonym for 1\&.5\&.
+-.RE
+-.PP
+-1\&.6
+-.RS 4
+-No language changes were introduced in Java SE 6\&. However, encoding errors in source files are now reported as errors instead of warnings as in earlier releases of Java Platform, Standard Edition\&.
+-.RE
+-.PP
+-6
+-.RS 4
+-Synonym for 1\&.6\&.
+-.RE
+-.PP
+-1\&.7
+-.RS 4
+-The compiler accepts code with features introduced in Java SE 7\&.
+-.RE
+-.PP
+-7
+-.RS 4
+-Synonym for 1\&.7\&.
+-.RE
+-.PP
+-1\&.8
+-.RS 4
+-This is the default value\&. The compiler accepts code with features introduced in Java SE 8\&.
+-.RE
+-.PP
+-8
+-.RS 4
+-Synonym for 1\&.8\&.
+-.RE
+-.RE
+-.PP
+-\-sourcepath \fIsourcepath\fR
+-.RS 4
+-Specifies the source code path to search for class or interface definitions\&. As with the user class path, source path entries are separated by colons (:) on Oracle Solaris and semicolons on Windows and can be directories, JAR archives, or ZIP archives\&. If packages are used, then the local path name within the directory or archive must reflect the package name\&.
+-.sp
+-\fBNote:\fR
+-Classes found through the class path might be recompiled when their source files are also found\&. See Searching for Types\&.
+-.RE
+-.PP
+-\-verbose
+-.RS 4
+-Uses verbose output, which includes information about each class loaded and each source file compiled\&.
+-.RE
+-.PP
+-\-version
+-.RS 4
+-Prints release information\&.
+-.RE
+-.PP
+-\-werror
+-.RS 4
+-Terminates compilation when warnings occur\&.
+-.RE
+-.PP
+-\-X
+-.RS 4
+-Displays information about nonstandard options and exits\&.
+-.RE
+-.SS "Cross\-Compilation Options"
+-.PP
+-By default, classes are compiled against the bootstrap and extension classes of the platform that
+-\fBjavac\fR
+-shipped with\&. But
+-\fBjavac\fR
+-also supports cross\-compiling, where classes are compiled against a bootstrap and extension classes of a different Java platform implementation\&. It is important to use the
+-\fB\-bootclasspath\fR
+-and
+-\fB\-extdirs\fR
+-options when cross\-compiling\&.
+-.PP
+-\-target \fIversion\fR
+-.RS 4
+-Generates class files that target a specified release of the virtual machine\&. Class files will run on the specified target and on later releases, but not on earlier releases of the JVM\&. Valid targets are 1\&.1, 1\&.2, 1\&.3, 1\&.4, 1\&.5 (also 5), 1\&.6 (also 6), 1\&.7 (also 7), and 1\&.8 (also 8)\&.
+-.sp
+-The default for the
+-\fB\-target\fR
+-option depends on the value of the
+-\fB\-source\fR
+-option:
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is not specified, then the value of the
+-\fB\-target\fR
+-option is 1\&.8
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is 1\&.2, then the value of the
+-\fB\-target\fR
+-option is 1\&.4
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is 1\&.3, then the value of the
+-\fB\-target\fR
+-option is 1\&.4
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is 1\&.5, then the value of the
+-\fB\-target\fR
+-option is 1\&.8
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is 1\&.6, then the value of the
+-\fB\-target\fR
+-is option 1\&.8
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-If the
+-\fB\-source\fR
+-option is 1\&.7, then the value of the
+-\fB\-target\fR
+-is option 1\&.8
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
+-For all other values of the
+-\fB\-source\fR
+-option, the value of the
+-\fB\-target\fR
+-option is the value of the
+-\fB\-source\fR
+-option\&.
+-.RE
+-.RE
+-.PP
+-\-bootclasspath \fIbootclasspath\fR
+-.RS 4
+-Cross\-compiles against the specified set of boot classes\&. As with the user class path, boot class path entries are separated by colons (:) and can be directories, JAR archives, or ZIP archives\&.
+-.RE
+-.SS "Compact Profile Option"
+-.PP
+-Beginning with JDK 8, the
+-\fBjavac\fR
+-compiler supports compact profiles\&. With compact profiles, applications that do not require the entire Java platform can be deployed and run with a smaller footprint\&. The compact profiles feature could be used to shorten the download time for applications from app stores\&. This feature makes for more compact deployment of Java applications that bundle the JRE\&. This feature is also useful in small devices\&.
+-.PP
+-The supported profile values are
+-\fBcompact1\fR,
+-\fBcompact2\fR, and
+-\fBcompact3\fR\&. These are additive layers\&. Each higher\-numbered compact profile contains all of the APIs in profiles with smaller number names\&.
+-.PP
+-\-profile
+-.RS 4
+-When using compact profiles, this option specifies the profile name when compiling\&. For example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-profile compact1 Hello\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-javac does not compile source code that uses any Java SE APIs that is not in the specified profile\&. Here is an example of the error message that results from attempting to compile such source code:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBcd jdk1\&.8\&.0/bin\fR
+-\fB\&./javac \-profile compact1 Paint\&.java\fR
+-\fBPaint\&.java:5: error: Applet is not available in profile \*(Aqcompact1\*(Aq\fR
+-\fBimport java\&.applet\&.Applet;\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-In this example, you can correct the error by modifying the source to not use the
+-\fBApplet\fR
+-class\&. You could also correct the error by compiling without the \-profile option\&. Then the compilation would be run against the full set of Java SE APIs\&. (None of the compact profiles include the
+-\fBApplet\fR
+-class\&.)
+-.sp
+-An alternative way to compile with compact profiles is to use the
+-\fB\-bootclasspath\fR
+-option to specify a path to an
+-\fBrt\&.jar\fR
+-file that specifies a profile\*(Aqs image\&. Using the
+-\fB\-profile\fR
+-option instead does not require a profile image to be present on the system at compile time\&. This is useful when cross\-compiling\&.
+-.RE
+-.SS "Nonstandard Options"
+-.PP
+-\-Xbootclasspath/p:\fIpath\fR
+-.RS 4
+-Adds a suffix to the bootstrap class path\&.
+-.RE
+-.PP
+-\-Xbootclasspath/a:\fIpath\fR
+-.RS 4
+-Adds a prefix to the bootstrap class path\&.
+-.RE
+-.PP
+-\-Xbootclasspath/:\fIpath\fR
+-.RS 4
+-Overrides the location of the bootstrap class files\&.
+-.RE
+-.PP
+-\-Xdoclint:[\-]\fIgroup\fR [\fI/access\fR]
+-.RS 4
+-Enables or disables specific groups of checks, where
+-\fIgroup\fR
+-is one of the following values:
+-\fBaccessibility\fR,
+-\fBsyntax\fR,
+-\fBreference\fR,
+-\fBhtml\fR
+-or
+-\fBmissing\fR\&. For more information about these groups of checks see the
+-\fB\-Xdoclint\fR
+-option of the
+-\fBjavadoc\fR
+-command\&. The
+-\fB\-Xdoclint\fR
+-option is disabled by default in the
+-\fBjavac\fR
+-command\&.
+-.sp
+-The variable
+-\fIaccess\fR
+-specifies the minimum visibility level of classes and members that the
+-\fB\-Xdoclint\fR
+-option checks\&. It can have one of the following values (in order of most to least visible) :
+-\fBpublic\fR,
+-\fBprotected\fR,
+-\fBpackage\fR
+-and
+-\fBprivate\fR\&. For example, the following option checks classes and members (with all groups of checks) that have the access level protected and higher (which includes protected, package and public):
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB\-Xdoclint:all/protected\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The following option enables all groups of checks for all access levels, except it will not check for HTML errors for classes and members that have access level package and higher (which includes package and public):
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB\-Xdoclint:all,\-html/package\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-\-Xdoclint:none
+-.RS 4
+-Disables all groups of checks\&.
+-.RE
+-.PP
+-\-Xdoclint:all[\fI/access\fR]
+-.RS 4
+-Enables all groups of checks\&.
+-.RE
+-.PP
+-\-Xlint
+-.RS 4
+-Enables all recommended warnings\&. In this release, enabling all available warnings is recommended\&.
+-.RE
+-.PP
+-\-Xlint:all
+-.RS 4
+-Enables all recommended warnings\&. In this release, enabling all available warnings is recommended\&.
+-.RE
+-.PP
+-\-Xlint:none
+-.RS 4
+-Disables all warnings\&.
+-.RE
+-.PP
+-\-Xlint:\fIname\fR
+-.RS 4
+-Disables warning name\&. See Enable or Disable Warnings with the \-Xlint Option for a list of warnings you can disable with this option\&.
+-.RE
+-.PP
+-\-Xlint:\fI\-name\fR
+-.RS 4
+-Disables warning name\&. See Enable or Disable Warnings with the \-Xlint Option with the
+-\fB\-Xlint\fR
+-option to get a list of warnings that you can disable with this option\&.
+-.RE
+-.PP
+-\-Xmaxerrs \fInumber\fR
+-.RS 4
+-Sets the maximum number of errors to print\&.
+-.RE
+-.PP
+-\-Xmaxwarns \fInumber\fR
+-.RS 4
+-Sets the maximum number of warnings to print\&.
+-.RE
+-.PP
+-\-Xstdout \fIfilename\fR
+-.RS 4
+-Sends compiler messages to the named file\&. By default, compiler messages go to
+-\fBSystem\&.err\fR\&.
+-.RE
+-.PP
+-\-Xprefer:[\fInewer,source\fR]
+-.RS 4
+-Specifies which file to read when both a source file and class file are found for a type\&. (See Searching for Types)\&. If the
+-\fB\-Xprefer:newer\fR
+-option is used, then it reads the newer of the source or class file for a type (default)\&. If the
+-\fB\-Xprefer:source\fR
+-option is used, then it reads the source file\&. Use \-\fBXprefer:source\fR
+-when you want to be sure that any annotation processors can access annotations declared with a retention policy of
+-\fBSOURCE\fR\&.
+-.RE
+-.PP
+-\-Xpkginfo:[\fIalways\fR,\fIlegacy\fR,\fInonempty\fR]
+-.RS 4
+-Control whether javac generates
+-\fBpackage\-info\&.class\fR
+-files from package\-info\&.java files\&. Possible mode arguments for this option include the following\&.
+-.PP
+-always
+-.RS 4
+-Always generate a
+-\fBpackage\-info\&.class\fR
+-file for every
+-\fBpackage\-info\&.java\fR
+-file\&. This option may be useful if you use a build system such as Ant, which checks that each
+-\fB\&.java\fR
+-file has a corresponding
+-\fB\&.class\fR
+-file\&.
+-.RE
+-.PP
+-legacy
+-.RS 4
+-Generate a
+-\fBpackage\-info\&.class\fR
+-file only if package\-info\&.java contains annotations\&. Don\*(Aqt generate a
+-\fBpackage\-info\&.class\fR
+-file if package\-info\&.java only contains comments\&.
+-.sp
+-\fBNote:\fR
+-A
+-\fBpackage\-info\&.class\fR
+-file might be generated but be empty if all the annotations in the package\-info\&.java file have
+-\fBRetentionPolicy\&.SOURCE\fR\&.
+-.RE
+-.PP
+-nonempty
+-.RS 4
+-Generate a
+-\fBpackage\-info\&.class\fR
+-file only if package\-info\&.java contains annotations with
+-\fBRetentionPolicy\&.CLASS\fR
+-or
+-\fBRetentionPolicy\&.RUNTIME\fR\&.
+-.RE
+-.RE
+-.PP
+-\-Xprint
+-.RS 4
+-Prints a textual representation of specified types for debugging purposes\&. Perform neither annotation processing nor compilation\&. The format of the output could change\&.
+-.RE
+-.PP
+-\-XprintProcessorInfo
+-.RS 4
+-Prints information about which annotations a processor is asked to process\&.
+-.RE
+-.PP
+-\-XprintRounds
+-.RS 4
+-Prints information about initial and subsequent annotation processing rounds\&.
+-.RE
+-.SH "ENABLE OR DISABLE WARNINGS WITH THE -XLINT OPTION"
+-.PP
+-Enable warning
+-\fIname\fR
+-with the
+-\fB\-Xlint:name\fR
+-option, where
+-\fBname\fR
+-is one of the following warning names\&. Note that you can disable a warning with the
+-\fB\-Xlint:\-name:\fR
+-option\&.
+-.PP
+-cast
+-.RS 4
+-Warns about unnecessary and redundant casts, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBString s = (String) "Hello!"\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-classfile
+-.RS 4
+-Warns about issues related to class file contents\&.
+-.RE
+-.PP
+-deprecation
+-.RS 4
+-Warns about the use of deprecated items, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjava\&.util\&.Date myDate = new java\&.util\&.Date();\fR
+-\fBint currentDay = myDate\&.getDay();\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The method
+-\fBjava\&.util\&.Date\&.getDay\fR
+-has been deprecated since JDK 1\&.1
+-.RE
+-.PP
+-dep\-ann
+-.RS 4
+-Warns about items that are documented with an
+-\fB@deprecated\fR
+-Javadoc comment, but do not have a
+-\fB@Deprecated\fR
+-annotation, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB/**\fR
+-\fB * @deprecated As of Java SE 7, replaced by {@link #newMethod()}\fR
+-\fB */\fR
+-\fBpublic static void deprecatedMethood() { }\fR
+-\fBpublic static void newMethod() { }\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-divzero
+-.RS 4
+-Warns about division by the constant integer 0, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBint divideByZero = 42 / 0;\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-empty
+-.RS 4
+-Warns about empty statements after
+-\fBif \fRstatements, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBclass E {\fR
+-\fB void m() {\fR
+-\fB if (true) ;\fR
+-\fB }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-fallthrough
+-.RS 4
+-Checks the switch blocks for fall\-through cases and provides a warning message for any that are found\&. Fall\-through cases are cases in a switch block, other than the last case in the block, whose code does not include a break statement, allowing code execution to fall through from that case to the next case\&. For example, the code following the case 1 label in this switch block does not end with a break statement:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBswitch (x) {\fR
+-\fBcase 1:\fR
+-\fB System\&.out\&.println("1");\fR
+-\fB // No break statement here\&.\fR
+-\fBcase 2:\fR
+-\fB System\&.out\&.println("2");\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-If the
+-\fB\-Xlint:fallthrough\fR
+-option was used when compiling this code, then the compiler emits a warning about possible fall\-through into case, with the line number of the case in question\&.
+-.RE
+-.PP
+-finally
+-.RS 4
+-Warns about
+-\fBfinally\fR
+-clauses that cannot complete normally, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpublic static int m() {\fR
+-\fB try {\fR
+-\fB throw new NullPointerException();\fR
+-\fB } catch (NullPointerException(); {\fR
+-\fB System\&.err\&.println("Caught NullPointerException\&.");\fR
+-\fB return 1;\fR
+-\fB } finally {\fR
+-\fB return 0;\fR
+-\fB }\fR
+-\fB }\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The compiler generates a warning for the
+-\fBfinally\fR
+-block in this example\&. When the
+-\fBint\fR
+-method is called, it returns a value of 0\&. A
+-\fBfinally\fR
+-block executes when the
+-\fBtry\fR
+-block exits\&. In this example, when control is transferred to the
+-\fBcatch\fR
+-block, the
+-\fBint\fR
+-method exits\&. However, the
+-\fBfinally\fR
+-block must execute, so it is executed, even though control was transferred outside the method\&.
+-.RE
+-.PP
+-options
+-.RS 4
+-Warns about issues that related to the use of command\-line options\&. See Cross\-Compilation Options\&.
+-.RE
+-.PP
+-overrides
+-.RS 4
+-Warns about issues regarding method overrides\&. For example, consider the following two classes:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpublic class ClassWithVarargsMethod {\fR
+-\fB void varargsMethod(String\&.\&.\&. s) { }\fR
+-\fB}\fR
+-
+-\fBpublic class ClassWithOverridingMethod extends ClassWithVarargsMethod {\fR
+-\fB @Override\fR
+-\fB void varargsMethod(String[] s) { }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The compiler generates a warning similar to the following:\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBwarning: [override] varargsMethod(String[]) in ClassWithOverridingMethod \fR
+-\fBoverrides varargsMethod(String\&.\&.\&.) in ClassWithVarargsMethod; overriding\fR
+-\fBmethod is missing \*(Aq\&.\&.\&.\*(Aq\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-When the compiler encounters a
+-\fBvarargs\fR
+-method, it translates the
+-\fBvarargs\fR
+-formal parameter into an array\&. In the method
+-\fBClassWithVarargsMethod\&.varargsMethod\fR, the compiler translates the
+-\fBvarargs\fR
+-formal parameter
+-\fBString\&.\&.\&. s\fR
+-to the formal parameter
+-\fBString[] s\fR, an array, which matches the formal parameter of the method
+-\fBClassWithOverridingMethod\&.varargsMethod\fR\&. Consequently, this example compiles\&.
+-.RE
+-.PP
+-path
+-.RS 4
+-Warns about invalid path elements and nonexistent path directories on the command line (with regard to the class path, the source path, and other paths)\&. Such warnings cannot be suppressed with the
+-\fB@SuppressWarnings\fR
+-annotation, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-Xlint:path \-classpath /nonexistentpath Example\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-processing
+-.RS 4
+-Warn about issues regarding annotation processing\&. The compiler generates this warning when you have a class that has an annotation, and you use an annotation processor that cannot handle that type of exception\&. For example, the following is a simple annotation processor:
+-.sp
+-\fBSource file AnnocProc\&.java\fR:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBimport java\&.util\&.*;\fR
+-\fBimport javax\&.annotation\&.processing\&.*;\fR
+-\fBimport javax\&.lang\&.model\&.*;\fR
+-\fBimport\&.javaz\&.lang\&.model\&.element\&.*;\fR
+-
+-\fB@SupportedAnnotationTypes("NotAnno")\fR
+-\fBpublic class AnnoProc extends AbstractProcessor {\fR
+-\fB public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv){\fR
+-\fB return true;\fR
+-\fB }\fR
+-
+-\fB public SourceVersion getSupportedSourceVersion() {\fR
+-\fB return SourceVersion\&.latest();\fR
+-\fB }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-\fBSource file AnnosWithoutProcessors\&.java\fR:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB@interface Anno { }\fR
+-\fB \fR
+-\fB@Anno\fR
+-\fBclass AnnosWithoutProcessors { }\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The following commands compile the annotation processor
+-\fBAnnoProc\fR, then run this annotation processor against the source file
+-\fBAnnosWithoutProcessors\&.java\fR:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac AnnoProc\&.java\fR
+-\fBjavac \-cp \&. \-Xlint:processing \-processor AnnoProc \-proc:only AnnosWithoutProcessors\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-When the compiler runs the annotation processor against the source file
+-\fBAnnosWithoutProcessors\&.java\fR, it generates the following warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBwarning: [processing] No processor claimed any of these annotations: Anno\fR
+-\fB \fR
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-To resolve this issue, you can rename the annotation defined and used in the class
+-\fBAnnosWithoutProcessors\fR
+-from
+-\fBAnno\fR
+-to
+-\fBNotAnno\fR\&.
+-.RE
+-.PP
+-rawtypes
+-.RS 4
+-Warns about unchecked operations on raw types\&. The following statement generates a
+-\fBrawtypes\fR
+-warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBvoid countElements(List l) { \&.\&.\&. }\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The following example does not generate a
+-\fBrawtypes\fR
+-warning
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBvoid countElements(List<?> l) { \&.\&.\&. }\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-\fBList\fR
+-is a raw type\&. However,
+-\fBList<?>\fR
+-is an unbounded wildcard parameterized type\&. Because
+-\fBList\fR
+-is a parameterized interface, always specify its type argument\&. In this example, the
+-\fBList\fR
+-formal argument is specified with an unbounded wildcard (\fB?\fR) as its formal type parameter, which means that the
+-\fBcountElements\fR
+-method can accept any instantiation of the
+-\fBList\fR
+-interface\&.
+-.RE
+-.PP
+-Serial
+-.RS 4
+-Warns about missing
+-\fBserialVersionUID\fR
+-definitions on serializable classes, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpublic class PersistentTime implements Serializable\fR
+-\fB{\fR
+-\fB private Date time;\fR
+-\fB \fR
+-\fB public PersistentTime() {\fR
+-\fB time = Calendar\&.getInstance()\&.getTime();\fR
+-\fB }\fR
+-\fB \fR
+-\fB public Date getTime() {\fR
+-\fB return time;\fR
+-\fB }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The compiler generates the following warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBwarning: [serial] serializable class PersistentTime has no definition of\fR
+-\fBserialVersionUID\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-If a serializable class does not explicitly declare a field named
+-\fBserialVersionUID\fR, then the serialization runtime environment calculates a default
+-\fBserialVersionUID\fR
+-value for that class based on various aspects of the class, as described in the Java Object Serialization Specification\&. However, it is strongly recommended that all serializable classes explicitly declare
+-\fBserialVersionUID\fR
+-values because the default process of computing
+-\fBserialVersionUID\fR
+-vales is highly sensitive to class details that can vary depending on compiler implementations, and as a result, might cause an unexpected
+-\fBInvalidClassExceptions\fR
+-during deserialization\&. To guarantee a consistent
+-\fBserialVersionUID\fR
+-value across different Java compiler implementations, a serializable class must declare an explicit
+-\fBserialVersionUID\fR
+-value\&.
+-.RE
+-.PP
+-static
+-.RS 4
+-Warns about issues relating to the use of statics, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBclass XLintStatic {\fR
+-\fB static void m1() { }\fR
+-\fB void m2() { this\&.m1(); }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The compiler generates the following warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBwarning: [static] static method should be qualified by type name, \fR
+-\fBXLintStatic, instead of by an expression\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-To resolve this issue, you can call the
+-\fBstatic\fR
+-method
+-\fBm1\fR
+-as follows:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBXLintStatic\&.m1();\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Alternately, you can remove the
+-\fBstatic\fR
+-keyword from the declaration of the method
+-\fBm1\fR\&.
+-.RE
+-.PP
+-try
+-.RS 4
+-Warns about issues relating to use of
+-\fBtry\fR
+-blocks, including try\-with\-resources statements\&. For example, a warning is generated for the following statement because the resource
+-\fBac\fR
+-declared in the
+-\fBtry\fR
+-block is not used:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBtry ( AutoCloseable ac = getResource() ) { // do nothing}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-unchecked
+-.RS 4
+-Gives more detail for unchecked conversion warnings that are mandated by the Java Language Specification, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBList l = new ArrayList<Number>();\fR
+-\fBList<String> ls = l; // unchecked warning\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-During type erasure, the types
+-\fBArrayList<Number>\fR
+-and
+-\fBList<String>\fR
+-become
+-\fBArrayList\fR
+-and
+-\fBList\fR, respectively\&.
+-.sp
+-The
+-\fBls\fR
+-command has the parameterized type
+-\fBList<String>\fR\&. When the
+-\fBList\fR
+-referenced by
+-\fBl\fR
+-is assigned to
+-\fBls\fR, the compiler generates an unchecked warning\&. At compile time, the compiler and JVM cannot determine whether
+-\fBl\fR
+-refers to a
+-\fBList<String>\fR
+-type\&. In this case,
+-\fBl\fR
+-does not refer to a
+-\fBList<String>\fR
+-type\&. As a result, heap pollution occurs\&.
+-.sp
+-A heap pollution situation occurs when the
+-\fBList\fR
+-object
+-\fBl\fR, whose static type is
+-\fBList<Number>\fR, is assigned to another
+-\fBList\fR
+-object,
+-\fBls\fR, that has a different static type,
+-\fBList<String>\fR\&. However, the compiler still allows this assignment\&. It must allow this assignment to preserve backward compatibility with releases of Java SE that do not support generics\&. Because of type erasure,
+-\fBList<Number>\fR
+-and
+-\fBList<String>\fR
+-both become
+-\fBList\fR\&. Consequently, the compiler allows the assignment of the object
+-\fBl\fR\fB,\fR
+-which has a raw type of
+-\fBList\fR, to the object
+-\fBls\fR\&.
+-.RE
+-.PP
+-varargs
+-.RS 4
+-Warns about unsafe usages of variable arguments (\fBvarargs\fR) methods, in particular, those that contain non\-reifiable arguments, for example:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpublic class ArrayBuilder {\fR
+-\fB public static <T> void addToList (List<T> listArg, T\&.\&.\&. elements) {\fR
+-\fB for (T x : elements) {\fR
+-\fB listArg\&.add(x);\fR
+-\fB }\fR
+-\fB }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-\fBNote:\fR
+-A non\-reifiable type is a type whose type information is not fully available at runtime\&.
+-.sp
+-The compiler generates the following warning for the definition of the method
+-\fBArrayBuilder\&.addToList\fR
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBwarning: [varargs] Possible heap pollution from parameterized vararg type T\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-When the compiler encounters a varargs method, it translates the
+-\fBvarargs\fR
+-formal parameter into an array\&. However, the Java programming language does not permit the creation of arrays of parameterized types\&. In the method
+-\fBArrayBuilder\&.addToList\fR, the compiler translates the
+-\fBvarargs\fR
+-formal parameter
+-\fBT\&.\&.\&.\fR
+-elements to the formal parameter
+-\fBT[]\fR
+-elements, an array\&. However, because of type erasure, the compiler converts the
+-\fBvarargs\fR
+-formal parameter to
+-\fBObject[]\fR
+-elements\&. Consequently, there is a possibility of heap pollution\&.
+-.RE
+-.SH "COMMAND-LINE ARGUMENT FILES"
+-.PP
+-To shorten or simplify the
+-\fBjavac\fR
+-command, you can specify one or more files that contain arguments to the
+-\fBjavac\fR
+-command (except
+-\fB\-J\fR
+-options)\&. This enables you to create
+-\fBjavac\fR
+-commands of any length on any operating system\&.
+-.PP
+-An argument file can include
+-\fBjavac\fR
+-options and source file names in any combination\&. The arguments within a file can be separated by spaces or new line characters\&. If a file name contains embedded spaces, then put the whole file name in double quotation marks\&.
+-.PP
+-File Names within an argument file are relative to the current directory, not the location of the argument file\&. Wild cards (*) are not allowed in these lists (such as for specifying
+-\fB*\&.java\fR)\&. Use of the at sign (@) to recursively interpret files is not supported\&. The
+-\fB\-J\fR
+-options are not supported because they are passed to the launcher, which does not support argument files\&.
+-.PP
+-When executing the
+-\fBjavac\fR
+-command, pass in the path and name of each argument file with the at sign (@) leading character\&. When the
+-\fBjavac\fR
+-command encounters an argument beginning with the at sign (@), it expands the contents of that file into the argument list\&.
+-.PP
+-\fBExample 1\fR
+-.br
+-Single Argument File
+-.RS 4
+-You could use a single argument file named
+-\fBargfile\fR
+-to hold all
+-\fBjavac\fR
+-arguments:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac @argfile\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-This argument file could contain the contents of both files shown in Example 2
+-.RE
+-.PP
+-\fBExample 2\fR
+-.br
+-Two Argument Files
+-.RS 4
+-You can create two argument files: one for the
+-\fBjavac\fR
+-options and the other for the source file names\&. Note that the following lists have no line\-continuation characters\&.
+-.sp
+-Create a file named options that contains the following:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB\-d classes\fR
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB\-g\fR
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB\-sourcepath /java/pubs/ws/1\&.3/src/share/classes\fR
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Create a file named classes that contains the following:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBMyClass1\&.java\fR
+-\fBMyClass2\&.java\fR
+-\fBMyClass3\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Then, run the
+-\fBjavac\fR
+-command as follows:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac @options @classes\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.PP
+-\fBExample 3\fR
+-.br
+-Argument Files with Paths
+-.RS 4
+-The argument files can have paths, but any file names inside the files are relative to the current working directory (not
+-\fBpath1\fR
+-or
+-\fBpath2\fR):
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac @path1/options @path2/classes\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
+-.SH "ANNOTATION PROCESSING"
+-.PP
+-The
+-\fBjavac\fR
+-command provides direct support for annotation processing, superseding the need for the separate annotation processing command,
+-\fBapt\fR\&.
+-.PP
+-The API for annotation processors is defined in the
+-\fBjavax\&.annotation\&.processing\fR
+-and j\fBavax\&.lang\&.model\fR
+-packages and subpackages\&.
+-.SS "How Annotation Processing Works"
+-.PP
+-Unless annotation processing is disabled with the
+-\fB\-proc:none\fR
+-option, the compiler searches for any annotation processors that are available\&. The search path can be specified with the
+-\fB\-processorpath\fR
+-option\&. If no path is specified, then the user class path is used\&. Processors are located by means of service provider\-configuration files named
+-\fBMETA\-INF/services/javax\&.annotation\&.processing\fR\&.Processor on the search path\&. Such files should contain the names of any annotation processors to be used, listed one per line\&. Alternatively, processors can be specified explicitly, using the
+-\fB\-processor\fR
+-option\&.
++The API for annotation processors is defined in the \f3javax\&.annotation\&.processing\fR and j\f3avax\&.lang\&.model\fR packages and subpackages\&.
++.SS HOW\ ANNOTATION\ PROCESSING\ WORKS
++Unless annotation processing is disabled with the \f3-proc:none\fR option, the compiler searches for any annotation processors that are available\&. The search path can be specified with the \f3-processorpath\fR option\&. If no path is specified, then the user class path is used\&. Processors are located by means of service provider-configuration files named \f3META-INF/services/javax\&.annotation\&.processing\fR\&.Processor on the search path\&. Such files should contain the names of any annotation processors to be used, listed one per line\&. Alternatively, processors can be specified explicitly, using the \f3-processor\fR option\&.
+ .PP
+ After scanning the source files and classes on the command line to determine what annotations are present, the compiler queries the processors to determine what annotations they process\&. When a match is found, the processor is called\&. A processor can claim the annotations it processes, in which case no further attempt is made to find any processors for those annotations\&. After all of the annotations are claimed, the compiler does not search for additional processors\&.
+ .PP
+ If any processors generate new source files, then another round of annotation processing occurs: Any newly generated source files are scanned, and the annotations processed as before\&. Any processors called on previous rounds are also called on all subsequent rounds\&. This continues until no new source files are generated\&.
+ .PP
+-After a round occurs where no new source files are generated, the annotation processors are called one last time, to give them a chance to complete any remaining work\&. Finally, unless the
+-\fB\-proc:only\fR
+-option is used, the compiler compiles the original and all generated source files\&.
+-.SS "Implicitly Loaded Source Files"
+-.PP
+-To compile a set of source files, the compiler might need to implicitly load additional source files\&. See Searching for Types\&. Such files are currently not subject to annotation processing\&. By default, the compiler gives a warning when annotation processing occurred and any implicitly loaded source files are compiled\&. The
+-\fB\-implicit\fR
+-option provides a way to suppress the warning\&.
+-.SH "SEARCHING FOR TYPES"
+-.PP
++After a round occurs where no new source files are generated, the annotation processors are called one last time, to give them a chance to complete any remaining work\&. Finally, unless the \f3-proc:only\fR option is used, the compiler compiles the original and all generated source files\&.
++.SS IMPLICITLY\ LOADED\ SOURCE\ FILES
++To compile a set of source files, the compiler might need to implicitly load additional source files\&. See Searching for Types\&. Such files are currently not subject to annotation processing\&. By default, the compiler gives a warning when annotation processing occurred and any implicitly loaded source files are compiled\&. The \f3-implicit\fR option provides a way to suppress the warning\&.
++.SH SEARCHING\ FOR\ TYPES
+ To compile a source file, the compiler often needs information about a type, but the type definition is not in the source files specified on the command line\&. The compiler needs type information for every class or interface used, extended, or implemented in the source file\&. This includes classes and interfaces not explicitly mentioned in the source file, but that provide information through inheritance\&.
+ .PP
+-For example, when you create a subclass
+-\fBjava\&.applet\&.Applet\fR, you are also using the ancestor classes of
+-\fBApplet\fR:
+-\fBjava\&.awt\&.Panel\fR,
+-\fBjava\&.awt\&.Container\fR,
+-\fBjava\&.awt\&.Component\fR, and
+-\fBjava\&.lang\&.Object\fR\&.
++For example, when you create a subclass \f3java\&.applet\&.Applet\fR, you are also using the ancestor classes of \f3Applet\fR: \f3java\&.awt\&.Panel\fR, \f3java\&.awt\&.Container\fR, \f3java\&.awt\&.Component\fR, and \f3java\&.lang\&.Object\fR\&.
+ .PP
+-When the compiler needs type information, it searches for a source file or class file that defines the type\&. The compiler searches for class files first in the bootstrap and extension classes, then in the user class path (which by default is the current directory)\&. The user class path is defined by setting the
+-\fBCLASSPATH\fR
+-environment variable or by using the
+-\fB\-classpath\fR
+-option\&.
++When the compiler needs type information, it searches for a source file or class file that defines the type\&. The compiler searches for class files first in the bootstrap and extension classes, then in the user class path (which by default is the current directory)\&. The user class path is defined by setting the \f3CLASSPATH\fR environment variable or by using the \f3-classpath\fR option\&.
+ .PP
+-If you set the
+-\fB\-sourcepath\fR
+-option, then the compiler searches the indicated path for source files\&. Otherwise, the compiler searches the user class path for both class files and source files\&.
++If you set the \f3-sourcepath\fR option, then the compiler searches the indicated path for source files\&. Otherwise, the compiler searches the user class path for both class files and source files\&.
+ .PP
+-You can specify different bootstrap or extension classes with the
+-\fB\-bootclasspath\fR
+-and the
+-\fB\-extdirs\fR
+-options\&. See Cross\-Compilation Options\&.
++You can specify different bootstrap or extension classes with the \f3-bootclasspath\fR and the \f3-extdirs\fR options\&. See Cross-Compilation Options\&.
+ .PP
+-A successful type search may produce a class file, a source file, or both\&. If both are found, then you can use the
+-\fB\-Xprefer\fR
+-option to instruct the compiler which to use\&. If
+-\fBnewer\fR
+-is specified, then the compiler uses the newer of the two files\&. If
+-\fBsource\fR
+-is specified, the compiler uses the source file\&. The default is
+-\fBnewer\fR\&.
++A successful type search may produce a class file, a source file, or both\&. If both are found, then you can use the \f3-Xprefer\fR option to instruct the compiler which to use\&. If \f3newer\fR is specified, then the compiler uses the newer of the two files\&. If \f3source\fR is specified, the compiler uses the source file\&. The default is \f3newer\fR\&.
+ .PP
+-If a type search finds a source file for a required type, either by itself, or as a result of the setting for the
+-\fB\-Xprefer\fR
+-option, then the compiler reads the source file to get the information it needs\&. By default the compiler also compiles the source file\&. You can use the
+-\fB\-implicit\fR
+-option to specify the behavior\&. If
+-\fBnone\fR
+-is specified, then no class files are generated for the source file\&. If
+-\fBclass\fR
+-is specified, then class files are generated for the source file\&.
++If a type search finds a source file for a required type, either by itself, or as a result of the setting for the \f3-Xprefer\fR option, then the compiler reads the source file to get the information it needs\&. By default the compiler also compiles the source file\&. You can use the \f3-implicit\fR option to specify the behavior\&. If \f3none\fR is specified, then no class files are generated for the source file\&. If \f3class\fR is specified, then class files are generated for the source file\&.
+ .PP
+-The compiler might not discover the need for some type information until after annotation processing completes\&. When the type information is found in a source file and no
+-\fB\-implicit\fR
+-option is specified, the compiler gives a warning that the file is being compiled without being subject to annotation processing\&. To disable the warning, either specify the file on the command line (so that it will be subject to annotation processing) or use the
+-\fB\-implicit\fR
+-option to specify whether or not class files should be generated for such source files\&.
+-.SH "PROGRAMMATIC INTERFACE"
++The compiler might not discover the need for some type information until after annotation processing completes\&. When the type information is found in a source file and no \f3-implicit\fR option is specified, the compiler gives a warning that the file is being compiled without being subject to annotation processing\&. To disable the warning, either specify the file on the command line (so that it will be subject to annotation processing) or use the \f3-implicit\fR option to specify whether or not class files should be generated for such source files\&.
++.SH PROGRAMMATIC\ INTERFACE
++The \f3javac\fR command supports the new Java Compiler API defined by the classes and interfaces in the \f3javax\&.tools\fR package\&.
++.SS EXAMPLE
++To compile as though providing command-line arguments, use the following syntax:
++.sp
++.nf
++\f3JavaCompiler javac = ToolProvider\&.getSystemJavaCompiler();\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++The example writes diagnostics to the standard output stream and returns the exit code that \f3javac\fR would give when called from the command line\&.
+ .PP
+-The
+-\fBjavac\fR
+-command supports the new Java Compiler API defined by the classes and interfaces in the
+-\fBjavax\&.tools\fR
+-package\&.
+-.SS "Example"
++You can use other methods in the \f3javax\&.tools\&.JavaCompiler\fR interface to handle diagnostics, control where files are read from and written to, and more\&.
++.SS OLD\ INTERFACE
++\fINote:\fR This API is retained for backward compatibility only\&. All new code should use the newer Java Compiler API\&.
+ .PP
+-To compile as though providing command\-line arguments, use the following syntax:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBJavaCompiler javac = ToolProvider\&.getSystemJavaCompiler();\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
++The \f3com\&.sun\&.tools\&.javac\&.Main\fR class provides two static methods to call the compiler from a program:
++.sp
++.nf
++\f3public static int compile(String[] args);\fP
++.fi
++.nf
++\f3public static int compile(String[] args, PrintWriter out);\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++The \f3args\fR parameter represents any of the command-line arguments that would typically be passed to the compiler\&.
+ .PP
+-The example writes diagnostics to the standard output stream and returns the exit code that
+-\fBjavac\fR
+-would give when called from the command line\&.
++The \f3out\fR parameter indicates where the compiler diagnostic output is directed\&.
+ .PP
+-You can use other methods in the
+-\fBjavax\&.tools\&.JavaCompiler\fR
+-interface to handle diagnostics, control where files are read from and written to, and more\&.
+-.SS "Old Interface"
++The \f3return\fR value is equivalent to the \f3exit\fR value from \f3javac\fR\&.
+ .PP
+-\fBNote:\fR
+-This API is retained for backward compatibility only\&. All new code should use the newer Java Compiler API\&.
++\fINote:\fR All other classes and methods found in a package with names that start with \f3com\&.sun\&.tools\&.javac\fR (subpackages of \f3com\&.sun\&.tools\&.javac\fR) are strictly internal and subject to change at any time\&.
++.SH EXAMPLES
++\f3Example 1 Compile a Simple Program\fR
+ .PP
+-The
+-\fBcom\&.sun\&.tools\&.javac\&.Main\fR
+-class provides two static methods to call the compiler from a program:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpublic static int compile(String[] args);\fR
+-\fBpublic static int compile(String[] args, PrintWriter out);\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
++This example shows how to compile the \f3Hello\&.java\fR source file in the greetings directory\&. The class defined in \f3Hello\&.java\fR is called \f3greetings\&.Hello\fR\&. The greetings directory is the package directory both for the source file and the class file and is underneath the current directory\&. This makes it possible to use the default user class path\&. It also makes it unnecessary to specify a separate destination directory with the \f3-d\fR option\&.
+ .PP
+-The
+-\fBargs\fR
+-parameter represents any of the command\-line arguments that would typically be passed to the compiler\&.
++The source code in \f3Hello\&.java\fR:
++.sp
++.nf
++\f3package greetings;\fP
++.fi
++.nf
++\f3\fP
++.fi
++.nf
++\f3public class Hello {\fP
++.fi
++.nf
++\f3 public static void main(String[] args) {\fP
++.fi
++.nf
++\f3 for (int i=0; i < args\&.length; i++) {\fP
++.fi
++.nf
++\f3 System\&.out\&.println("Hello " + args[i]);\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3 }\fP
++.fi
++.nf
++\f3}\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++Compile greetings\&.Hello:
++.sp
++.nf
++\f3javac greetings/Hello\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++Run \f3greetings\&.Hello\fR:
++.sp
++.nf
++\f3java greetings\&.Hello World Universe Everyone\fP
++.fi
++.nf
++\f3Hello World\fP
++.fi
++.nf
++\f3Hello Universe\fP
++.fi
++.nf
++\f3Hello Everyone\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++\f3Example 2 Compile Multiple Source Files\fR
+ .PP
+-The
+-\fBout\fR
+-parameter indicates where the compiler diagnostic output is directed\&.
++This example compiles the \f3Aloha\&.java\fR, \f3GutenTag\&.java\fR, \f3Hello\&.java\fR, and \f3Hi\&.java\fR source files in the \f3greetings\fR package\&.
++.sp
++.nf
++\f3% javac greetings/*\&.java\fP
++.fi
++.nf
++\f3% ls greetings\fP
++.fi
++.nf
++\f3Aloha\&.class GutenTag\&.class Hello\&.class Hi\&.class\fP
++.fi
++.nf
++\f3Aloha\&.java GutenTag\&.java Hello\&.java Hi\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++\f3Example 3 Specify a User Class Path\fR
+ .PP
+-The
+-\fBreturn\fR
+-value is equivalent to the
+-\fBexit\fR
+-value from
+-\fBjavac\fR\&.
++After changing one of the source files in the previous example, recompile it:
++.sp
++.nf
++\f3pwd\fP
++.fi
++.nf
++\f3/examples\fP
++.fi
++.nf
++\f3javac greetings/Hi\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++Because \f3greetings\&.Hi\fR refers to other classes in the \f3greetings\fR package, the compiler needs to find these other classes\&. The previous example works because the default user class path is the directory that contains the package directory\&. If you want to recompile this file without concern for which directory you are in, then add the examples directory to the user class path by setting \f3CLASSPATH\fR\&. This example uses the \f3-classpath\fR option\&.
++.sp
++.nf
++\f3javac \-classpath /examples /examples/greetings/Hi\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++If you change \f3greetings\&.Hi\fR to use a banner utility, then that utility also needs to be accessible through the user class path\&.
++.sp
++.nf
++\f3javac \-classpath /examples:/lib/Banners\&.jar \e\fP
++.fi
++.nf
++\f3 /examples/greetings/Hi\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++To execute a class in the \f3greetings\fR package, the program needs access to the \f3greetings\fR package, and to the classes that the \f3greetings\fR classes use\&.
++.sp
++.nf
++\f3java \-classpath /examples:/lib/Banners\&.jar greetings\&.Hi\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++\f3Example 4 Separate Source Files and Class Files\fR
+ .PP
+-\fBNote:\fR
+-All other classes and methods found in a package with names that start with
+-\fBcom\&.sun\&.tools\&.javac\fR
+-(subpackages of
+-\fBcom\&.sun\&.tools\&.javac\fR) are strictly internal and subject to change at any time\&.
+-.SH "EXAMPLES"
++The following example uses \f3javac\fR to compile code that runs on JVM 1\&.7\&.
++.sp
++.nf
++\f3javac \-source 1\&.7 \-target 1\&.7 \-bootclasspath jdk1\&.7\&.0/lib/rt\&.jar \e \fP
++.fi
++.nf
++\f3\-extdirs "" OldCode\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++The \f3-source 1\&.7\fR option specifies that release 1\&.7 (or 7) of the Java programming language be used to compile \f3OldCode\&.java\fR\&. The option \f3-target 1\&.7\fR option ensures that the generated class files are compatible with JVM 1\&.7\&. Note that in most cases, the value of the \f3-target\fR option is the value of the \f3-source\fR option; in this example, you can omit the \f3-target\fR option\&.
+ .PP
+-\fBExample 1\fR
+-.br
+-Compile a Simple Program
+-.RS 4
+-This example shows how to compile the
+-\fBHello\&.java\fR
+-source file in the greetings directory\&. The class defined in
+-\fBHello\&.java\fR
+-is called
+-\fBgreetings\&.Hello\fR\&. The greetings directory is the package directory both for the source file and the class file and is underneath the current directory\&. This makes it possible to use the default user class path\&. It also makes it unnecessary to specify a separate destination directory with the
+-\fB\-d\fR
+-option\&.
+-.sp
+-The source code in
+-\fBHello\&.java\fR:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpackage greetings;\fR
+-\fB \fR
+-\fBpublic class Hello {\fR
+-\fB public static void main(String[] args) {\fR
+-\fB for (int i=0; i < args\&.length; i++) {\fR
+-\fB System\&.out\&.println("Hello " + args[i]);\fR
+-\fB }\fR
+-\fB }\fR
+-\fB}\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Compile greetings\&.Hello:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac greetings/Hello\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Run
+-\fBgreetings\&.Hello\fR:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjava greetings\&.Hello World Universe Everyone\fR
+-\fBHello World\fR
+-\fBHello Universe\fR
+-\fBHello Everyone\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
++You must specify the \f3-bootclasspath\fR option to specify the correct version of the bootstrap classes (the \f3rt\&.jar\fR library)\&. If not, then the compiler generates a warning:
++.sp
++.nf
++\f3javac \-source 1\&.7 OldCode\&.java\fP
++.fi
++.nf
++\f3warning: [options] bootstrap class path not set in conjunction with \fP
++.fi
++.nf
++\f3\-source 1\&.7\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++If you do not specify the correct version of bootstrap classes, then the compiler uses the old language rules (in this example, it uses version 1\&.7 of the Java programming language) combined with the new bootstrap classes, which can result in class files that do not work on the older platform (in this case, Java SE 7) because reference to nonexistent methods can get included\&.
+ .PP
+-\fBExample 2\fR
+-.br
+-Compile Multiple Source Files
+-.RS 4
+-This example compiles the
+-\fBAloha\&.java\fR,
+-\fBGutenTag\&.java\fR,
+-\fBHello\&.java\fR, and
+-\fBHi\&.java\fR
+-source files in the
+-\fBgreetings\fR
+-package\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fB% javac greetings/*\&.java\fR
+-\fB% ls greetings\fR
+-\fBAloha\&.class GutenTag\&.class Hello\&.class Hi\&.class\fR
+-\fBAloha\&.java GutenTag\&.java Hello\&.java Hi\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
++\f3Example 5 Cross Compile\fR
+ .PP
+-\fBExample 3\fR
+-.br
+-Specify a User Class Path
+-.RS 4
+-After changing one of the source files in the previous example, recompile it:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBpwd\fR
+-\fB/examples\fR
+-\fBjavac greetings/Hi\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-Because
+-\fBgreetings\&.Hi\fR
+-refers to other classes in the
+-\fBgreetings\fR
+-package, the compiler needs to find these other classes\&. The previous example works because the default user class path is the directory that contains the package directory\&. If you want to recompile this file without concern for which directory you are in, then add the examples directory to the user class path by setting
+-\fBCLASSPATH\fR\&. This example uses the
+-\fB\-classpath\fR
+-option\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-classpath /examples /examples/greetings/Hi\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-If you change
+-\fBgreetings\&.Hi\fR
+-to use a banner utility, then that utility also needs to be accessible through the user class path\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-classpath /examples:/lib/Banners\&.jar \e\fR
+-\fB /examples/greetings/Hi\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-To execute a class in the
+-\fBgreetings\fR
+-package, the program needs access to the
+-\fBgreetings\fR
+-package, and to the classes that the
+-\fBgreetings\fR
+-classes use\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjava \-classpath /examples:/lib/Banners\&.jar greetings\&.Hi\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-.RE
++This example uses \f3javac\fR to compile code that runs on JVM 1\&.7\&.
++.sp
++.nf
++\f3javac \-source 1\&.7 \-target 1\&.7 \-bootclasspath jdk1\&.7\&.0/lib/rt\&.jar \e\fP
++.fi
++.nf
++\f3 \-extdirs "" OldCode\&.java\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
++The\f3-source 1\&.7\fR option specifies that release 1\&.7 (or 7) of the Java programming language to be used to compile OldCode\&.java\&. The \f3-target 1\&.7\fR option ensures that the generated class files are compatible with JVM 1\&.7\&.
+ .PP
+-\fBExample 4\fR
+-.br
+-Separate Source Files and Class Files
+-.RS 4
+-The following example uses
+-\fBjavac\fR
+-to compile code that runs on JVM 1\&.7\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-source 1\&.7 \-target 1\&.7 \-bootclasspath jdk1\&.7\&.0/lib/rt\&.jar \e \fR
+-\fB\-extdirs "" OldCode\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The
+-\fB\-source 1\&.7\fR
+-option specifies that release 1\&.7 (or 7) of the Java programming language be used to compile
+-\fBOldCode\&.java\fR\&. The option
+-\fB\-target 1\&.7\fR
+-option ensures that the generated class files are compatible with JVM 1\&.7\&. Note that in most cases, the value of the
+-\fB\-target\fR
+-option is the value of the
+-\fB\-source\fR
+-option; in this example, you can omit the
+-\fB\-target\fR
+-option\&.
+-.sp
+-You must specify the
+-\fB\-bootclasspath\fR
+-option to specify the correct version of the bootstrap classes (the
+-\fBrt\&.jar\fR
+-library)\&. If not, then the compiler generates a warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-source 1\&.7 OldCode\&.java\fR
+-\fBwarning: [options] bootstrap class path not set in conjunction with \fR
+-\fB\-source 1\&.7\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-If you do not specify the correct version of bootstrap classes, then the compiler uses the old language rules (in this example, it uses version 1\&.7 of the Java programming language) combined with the new bootstrap classes, which can result in class files that do not work on the older platform (in this case, Java SE 7) because reference to nonexistent methods can get included\&.
+-.RE
+-.PP
+-\fBExample 5\fR
+-.br
+-Cross Compile
+-.RS 4
+-This example uses
+-\fBjavac\fR
+-to compile code that runs on JVM 1\&.7\&.
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-source 1\&.7 \-target 1\&.7 \-bootclasspath jdk1\&.7\&.0/lib/rt\&.jar \e\fR
+-\fB \-extdirs "" OldCode\&.java\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
+-The\fB \-source 1\&.7\fR
+-option specifies that release 1\&.7 (or 7) of the Java programming language to be used to compile OldCode\&.java\&. The
+-\fB\-target 1\&.7\fR
+-option ensures that the generated class files are compatible with JVM 1\&.7\&. In most cases, the value of the
+-\fB\-target\fR
+-is the value of
+-\fB\-source\fR\&. In this example, the
+-\fB\-target\fR
+-option is omitted\&.
+-.sp
+-You must specify the
+-\fB\-bootclasspath\fR
+-option to specify the correct version of the bootstrap classes (the
+-\fBrt\&.jar\fR
+-library)\&. If not, then the compiler generates a warning:
+-.sp
+-.if n \{\
+-.RS 4
+-.\}
+-.nf
+-\fBjavac \-source 1\&.7 OldCode\&.java\fR
+-\fBwarning: [options] bootstrap class path not set in conjunction with \-source 1\&.7\fR
+-
+-.fi
+-.if n \{\
+-.RE
+-.\}
++You must specify the \f3-bootclasspath\fR option to specify the correct version of the bootstrap classes (the \f3rt\&.jar\fR library)\&. If not, then the compiler generates a warning:
++.sp
++.nf
++\f3javac \-source 1\&.7 OldCode\&.java\fP
++.fi
++.nf
++\f3warning: [options] bootstrap class path not set in conjunction with \-source 1\&.7\fP
++.fi
++.nf
++\f3\fP
++.fi
++.sp
+ If you do not specify the correct version of bootstrap classes, then the compiler uses the old language rules combined with the new bootstrap classes\&. This combination can result in class files that do not work on the older platform (in this case, Java SE 7) because reference to nonexistent methods can get included\&. In this example, the compiler uses release 1\&.7 of the Java programming language\&.
+-.RE
+-.SH "SEE ALSO"
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.SH SEE\ ALSO
++.TP 0.2i
++\(bu
+ java(1)
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.TP 0.2i
++\(bu
+ jdb(1)
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.TP 0.2i
++\(bu
+ javah(1)
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.TP 0.2i
++\(bu
+ javadoc(1)
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.TP 0.2i
++\(bu
+ jar(1)
+-.RE
+-.sp
+-.RS 4
+-.ie n \{\
+-\h'-04'\(bu\h'+03'\c
+-.\}
+-.el \{\
+-.sp -1
+-.IP \(bu 2.3
+-.\}
++.TP 0.2i
++\(bu
+ jdb(1)
+-.RE
+-.br
+-'pl 8.5i
+-'bp
++.RE
++.br
++'pl 8.5i
++'bp
+--- ./jdk/src/solaris/doc/sun/man/man1/javadoc.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/javadoc.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ '\" t
+-.\" Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
++.\" Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
+ .\"
+ .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ .\"
+@@ -23,12 +23,12 @@
+ .\"
+ .\" Arch: generic
+ .\" Software: JDK 8
+-.\" Date: 10 May 2011
++.\" Date: 03 March 2015
+ .\" SectDesc: Basic Tools
+ .\" Title: javadoc.1
+ .\"
+ .if n .pl 99999
+-.TH javadoc 1 "10 May 2011" "JDK 8" "Basic Tools"
++.TH javadoc 1 "03 March 2015" "JDK 8" "Basic Tools"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -209,7 +209,7 @@
+ \f3package java\&.lang\&.applet;\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -251,7 +251,7 @@
+ \f3initialize, start, and stop the applet\&. \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3@since 1\&.0 \fP
+@@ -266,7 +266,7 @@
+ \f3</HTML>\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The \f3package\&.html\fR file is a typical HTML file and does not include a package declaration\&. The content of the package comment file is written in HTML with one exception\&. The documentation comment should not include the comment separators \f3/**\fR and \f3*/\fR or leading asterisks\&. When writing the comment, make the first sentence a summary about the package, and do not put a title or any other text between the \f3<body>\fR tag and the first sentence\&. You can include package tags\&. All block tags must appear after the main description\&. If you add an \f3@see\fR tag in a package comment file, then it must have a fully qualified name\&.
+@@ -334,7 +334,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SS TEST\ AND\ TEMPLATE\ FILES
+@@ -350,7 +350,7 @@
+ \f3com/package1/test\-files/\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ If your test files contain documentation comments, then you can set up a separate run of the \f3javadoc\fR command to produce test file documentation by passing in their test source file names with wild cards, such as \f3com/package1/test-files/*\&.java\fR\&.
+@@ -560,7 +560,7 @@
+ \f3implements Serializable\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The declaration for the \f3Boolean\&.valueOf\fR method is:
+@@ -569,7 +569,7 @@
+ \f3public static Boolean valueOf(String s)\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The \f3javadoc\fR command can include the modifiers \f3public\fR, \f3protected\fR, \f3private\fR, \f3abstract\fR, \f3final\fR, \f3static\fR, \f3transient\fR, and \f3volatile\fR, but not \f3synchronized\fR or \f3native\fR\&. The \f3synchronized\fR and \f3native\fR modifiers are considered implementation detail and not part of the API specification\&.
+@@ -593,7 +593,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ To save space you can put a comment on one line:
+@@ -602,7 +602,7 @@
+ \f3/** This comment takes up only one line\&. */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -623,19 +623,19 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3import com\&.example; // MISTAKE \- Important not to put import statement here\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3public class Whatever{ }\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -657,7 +657,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -676,7 +676,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -700,7 +700,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -730,7 +730,7 @@
+ \f3public int x, y; // Avoid this \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The \f3javadoc\fR command generates the following documentation from the previous code:
+@@ -739,7 +739,7 @@
+ \f3public int x\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The horizontal and vertical distances of point (x, y)\&.
+@@ -748,7 +748,7 @@
+ \f3public int y\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The horizontal and vertical distances of point (x, y)\&.
+@@ -872,7 +872,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -899,11 +899,10 @@
+ .TP 0.2i
+ \(bu
+ In the text arguments of the \f3@return\fR, \f3@param,\fR and \f3@throws\fR tags of a method\&. In this case, the tag text is copied from the corresponding tag up the hierarchy\&.
+-.RE
+-.RS
++.RE
++
++
+ See Method Comment Inheritance for a description of how comments are found in the inheritance hierarchy\&. Note that if this tag is missing, then the comment is or is not automatically inherited according to rules described in that section\&.
+-
+-.RE
+ .TP
+ {@link \fIpackage\&.class#member label\fR}
+ Introduced in JDK 1\&.2
+@@ -920,7 +919,7 @@
+ \f3Use the {@link #getComponentAt(int, int) getComponentAt} method\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -931,7 +930,7 @@
+ \f3Use the <a href="Component\&.html#getComponentAt(int, int)">getComponentAt</a> method\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -942,7 +941,7 @@
+ \f3Use the getComponentAt method\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -982,7 +981,7 @@
+ \f3}\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1014,7 +1013,7 @@
+ \f3}\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1071,7 +1070,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1091,7 +1090,7 @@
+ \f3</dl>\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1128,7 +1127,7 @@
+ \f3@see #constructor(Type argname, Type argname,\&.\&.\&.) \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3\fIReferencing another class in the current or imported packages\fR\fP
+@@ -1155,7 +1154,7 @@
+ \f3@see Class \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3\fIReferencing an element in another package (fully qualified)\fR\fP
+@@ -1185,7 +1184,7 @@
+ \f3@see package\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3\fRNotes about the previous listing:
+@@ -1215,7 +1214,7 @@
+ Any enclosing classes and interfaces searching the closest first\&.
+ .TP 0.4i
+ 3\&.
+-Any superclasses and superonterfaces, searching the closest first\&.
++Any superclasses and superinterfaces, searching the closest first\&.
+ .TP 0.4i
+ 4\&.
+ The current package\&.
+@@ -1307,7 +1306,7 @@
+ \f3@see "The Java Programming Language" // "The Java Programming Language" \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \fINote:\fR You can extend the \f3@se\fR\f3e\fR tag to link to classes not being documented with the \f3-link\fR option\&.
+@@ -1317,7 +1316,7 @@
+
+ Used in the documentation comment for a default serializable field\&. See Documenting Serializable Fields and Data for a Class at http://docs\&.oracle\&.com/javase/8/docs/platform/serialization/spec/serial-arch\&.html#5251
+
+-See also Oracle\(cqs Criteria for Including Classes in the Serialilzed Form Specification at http://www\&.oracle\&.com/technetwork/java/javase/documentation/serialized-criteria-137781\&.html
++See also Oracle\(cqs Criteria for Including Classes in the Serialized Form Specification at http://www\&.oracle\&.com/technetwork/java/javase/documentation/serialized-criteria-137781\&.html
+
+ An optional \f3field-description\fR should explain the meaning of the field and list the acceptable values\&. When needed, the description can span multiple lines\&. The standard doclet adds this information to the serialized form page\&. See Cross-Reference Pages\&.
+
+@@ -1331,13 +1330,12 @@
+ .TP 0.2i
+ \(bu
+ A private or package-private class that implements \f3Serializable\fR is excluded unless that class (or its package) is marked with the \f3@serial include\fR tag\&.
+-.RE
+-.RS
++.RE
++
++
+ For example, the \f3javax\&.swing\fR package is marked with the \f3@serial\fR\f3exclude\fR tag in package\&.html or package-info\&.java\&. The public class \f3java\&.security\&.BasicPermission\fR is marked with the \f3@serial exclude\fR tag\&. The package-private class \f3java\&.util\&.PropertyPermissionCollection\fR is marked with the \f3@serial include\fR tag\&.
+
+ The \f3@serial\fR tag at the class level overrides the \f3@serial\fR tag at the package level\&.
+-
+-.RE
+ .TP
+ @serialData \fIdata-description\fR
+ Introduced in JDK 1\&.2
+@@ -1387,7 +1385,7 @@
+ \f3public static final String SCRIPT_START = "<script>"\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1407,7 +1405,7 @@
+ \f3public String evalScript(String script) {}\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1494,7 +1492,7 @@
+ \f3}\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SS FIELD\ TAGS
+@@ -1523,7 +1521,7 @@
+ \f3 int x = 1263732;\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SS CONSTRUCTOR\ AND\ METHOD\ TAGS
+@@ -1578,7 +1576,7 @@
+ \f3 }\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SH OPTIONS
+@@ -1592,7 +1590,7 @@
+ .PP
+ The options are:
+ .PP
+--1\&.1 || -author || -bootclasspath classpathlist || -bottom text || -breakiterator || -charset name || -classpath classpathlist || -d directory || -docencoding name || -docfilesubdirs || -doclet class || -docletpath classpathlist || -doctitle title || -encoding || -exclude packagename1:packagename2:\&.\&.\&. || -excludedocfilessubdir name1:name2 || -extdirs dirist || -footer footer || -group groupheading packagepattern:packagepattern || -header header || -help || -helpfile path\efilename || -Jflag || -keywords || -link extdocURL || -linkoffline extdocURL packagelistLoc || -linksource || -locale language_country_variant || -nocomment || -nodeprecated || -nodeprecatedlist || -nohelp || -noindex || -nonavbar || -noqualifier all | packagename1:packagename2\&.\&.\&. || -nosince || -notimestamp || -notree || -overview path/filename || -package || -private || -protected || -public || -quiet || -serialwarn || -source release || -sourcepath sourcepathlist || -sourcetab tablength || -splitindex || -stylesheet path/filename || -subpackages package1:package2:\&.\&.\&. || -tag tagname:Xaoptcmf:"taghead" || -taglet class || -tagletpath tagletpathlist || -title title || -top || -use || -verbose || -version || -windowtitle title
++-1\&.1 || -author || -bootclasspath classpathlist || -bottom text || -breakiterator || -charset name || -classpath classpathlist || -d directory || -docencoding name || -docfilesubdirs || -doclet class || -docletpath classpathlist || -doctitle title || -encoding || -exclude packagename1:packagename2:\&.\&.\&. || -excludedocfilessubdir name1:name2 || -extdirs dirist || -footer footer || -group groupheading packagepattern:packagepattern || -header header || -help || -helpfile path\efilename || -Jflag || -javafx ||-keywords || -link extdocURL || -linkoffline extdocURL packagelistLoc || -linksource || -locale language_country_variant || -nocomment || -nodeprecated || -nodeprecatedlist || -nohelp || -noindex || -nonavbar || -noqualifier all | packagename1:packagename2\&.\&.\&. || -nosince || -notimestamp || -notree || -overview path/filename || -package || -private || -protected || -public || -quiet || -serialwarn || -source release || -sourcepath sourcepathlist || -sourcetab tablength || -splitindex || -stylesheet path/filename || -subpackages package1:package2:\&.\&.\&. || -tag tagname:Xaoptcmf:"taghead" || -taglet class || -tagletpath tagletpathlist || -title title || -top || -use || -verbose || -version || -windowtitle title
+ .PP
+ The following options are the core Javadoc options that are available to all doclets\&. The standard doclet provides the rest of the doclets: \f3-bootclasspath\fR, \f3-breakiterator\fR, \f3-classpath\fR, \f3-doclet\fR, \f3-docletpath\fR, \f3-encoding\fR, -\f3exclude\fR, \f3-extdirs\fR, \f3-help\fR, \f3-locale\fR, \f3-\fR\f3overview\fR, \f3-package\fR, \f3-private\fR, \f3-protected\fR, \f3-public\fR, \f3-quiet\fR, \f3-source\fR, \f3-sourcepath\fR, \f3-subpackages\fR, and \f3-verbose\fR\&.
+ .SS JAVADOC\ OPTIONS
+@@ -1635,12 +1633,11 @@
+ .TP 0.2i
+ \(bu
+ \f3-Xdoclint all,\fR\fI-group\fR : enable all except \fIgroup\fR checks
+-.RE
+-.RS
++.RE
++
++
+ The variable \fIgroup\fR has one of the following values:
+ .RS
+-
+-.RE
+ .TP 0.2i
+ \(bu
+ \f3accessibility\fR : Checks for the issues to be detected by an accessibility checker (for example, no caption or summary attributes specified in a \f3<table>\fR tag)\&.
+@@ -1656,8 +1653,9 @@
+ .TP 0.2i
+ \(bu
+ \f3syntax\fR : Checks for low level issues like unescaped angle brackets (\f3<\fR and \f3>\fR) and ampersands (\f3&\fR) and invalid Javadoc tags\&.
+-.RE
+-.RS
++.RE
++
++
+ You can specify the \f3-Xdoclint\fR option multiple times to enable the option to check errors and warnings in multiple categories\&. Alternatively, you can specify multiple error and warning categories by using the preceding options\&. For example, use either of the following commands to check for the HTML, syntax, and accessibility issues in the file \fIfilename\fR\&.
+ .sp
+ .nf
+@@ -1667,7 +1665,7 @@
+ \f3javadoc \-Xdoclint:html,syntax,accessibility \fIfilename\fR\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1675,8 +1673,6 @@
+ \fINote:\fR The \f3javadoc\fR command does not guarantee the completeness of these checks\&. In particular, it is not a full HTML compliance checker\&. The goal of the -\f3Xdoclint\fR option is to enable the \f3javadoc\fR command to report majority of common errors\&.
+
+ The \f3javadoc\fR command does not attempt to fix invalid input, it just reports it\&.
+-
+-.RE
+ .TP
+ -public
+ .br
+@@ -1740,7 +1736,7 @@
+ \f3javadoc \-sourcepath /home/user/src/ com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1755,7 +1751,7 @@
+ \f3javadoc \-sourcepath /home/user1/src:/home/user2/src com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1766,13 +1762,13 @@
+
+ If you omit \f3-sourcepath\fR, then the \f3javadoc\fR command uses \f3-classpath\fR to find the source files and class files (for backward compatibility)\&. If you want to search for source and class files in separate paths, then use both \f3-sourcepath\fR and \f3-classpath\fR\&.
+
+-For example, if you want to document \f3com\&.mypackage\fR, whose source files reside in the directory /home/user/src/com/mypackage, and if this package relies on a library in /home/user/libthen you would use the following command:
++For example, if you want to document \f3com\&.mypackage\fR, whose source files reside in the directory /home/user/src/com/mypackage, and if this package relies on a library in /home/user/lib, then you would use the following command:
+ .sp
+ .nf
+ \f3javadoc \-sourcepath /home/user/lib \-classpath /home/user/src com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1795,7 +1791,7 @@
+ \f3javadoc \-d docs \-sourcepath /home/user/src \-subpackages java:javax\&.swing \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1813,7 +1809,7 @@
+ \f3 java\&.net:java\&.lang\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1846,11 +1842,10 @@
+ .TP 0.2i
+ \(bu
+ Breakiterator sentence-break algorithm\&. Stops at a period, question mark, or exclamation point followed by a space when the next word starts with a capital letter\&. This is meant to handle most abbreviations (such as "The serial no\&. is valid", but will not handle "Mr\&. Smith")\&. The \f3-breakiterator\fR option does not stop at HTML tags or sentences that begin with numbers or symbols\&. The algorithm stops at the last period in \&.\&./filename, even when embedded in an HTML tag\&.
+-.RE
+-.RS
++.RE
++
++
+ In Java SE 1\&.5 the \f3-breakiterator\fR option warning messages are removed, and the default sentence-break algorithm is unchanged\&. If you have not modified your source code to eliminate the \f3-breakiterator\fR option warnings in Java SE 1\&.4\&.x, then you do not have to do anything\&. The warnings go away starting with Java SE 1\&.5\&.0\&.
+-
+-.RE
+ .TP
+ -locale \fIlanguage_country_variant\fR
+ .br
+@@ -1885,7 +1880,21 @@
+ \f3Java HotSpot(TM) 64\-Bit Server VM (build 23\&.5\-b02, mixed mode)\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
++.fi
++.sp
++
++.TP
++-javafx
++.br
++Generates HTML documentation using the JavaFX extensions to the standard doclet\&. The generated documentation includes a Property Summary section in addition to the other summary sections generated by the standard Java doclet\&. The listed properties are linked to the sections for the getter and setter methods of each property\&.
++
++If there are no documentation comments written explicitly for getter and setter methods, the documentation comments from the property method are automatically copied to the generated documentation for these methods\&. This option also adds a new \f3@defaultValue\fR tag that allows documenting the default value for a property\&.
++
++Example:
++.sp
++.nf
++\f3javadoc \-javafx MyClass\&.java \-d testdir\fP
+ .fi
+ .sp
+
+@@ -1957,7 +1966,7 @@
+ \f3\-link <directory>/<directory>/\&.\&.\&./<name>\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -1982,7 +1991,7 @@
+ \f3javadoc \-link http://docs\&.oracle\&.com/javase/8/docs/api/ com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The command generates documentation for the package \f3com\&.mypackage\fR with links to the Java SE packages\&. The generated documentation contains links to the \f3Object\fR class, for example, in the class \f3trees\fR\&. Other options, such as the \f3-sourcepath\fR and \f3-d\fR options, are not shown\&.
+@@ -2044,7 +2053,7 @@
+ \f3and so on \&.\&.\&.\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ When \f3javadoc\fR is run without the \f3-link\fR option and encounters a name that belongs to an externally referenced class, it prints the name with no link\&. However, when the \f3-link\fR option is used, the \f3javadoc\fR command searches the package-list file at the specified \fIextdocURL\fR location for that package name\&. When it finds the package name, it prefixes the name with \fIextdocURL\fR\&.
+@@ -2094,7 +2103,7 @@
+ \f3javadoc \-linkoffline http://docs\&.oracle\&.com/javase/8/docs/api/ \&. com\&.mypackage \fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2118,7 +2127,7 @@
+ \f3packagelistLoc2 \&.\&.\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2133,7 +2142,7 @@
+ \f3javadoc \-d update \-linkoffline \&. html com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ When the \f3javadoc\fR command completes, copy these generated class pages in update/com/package (not the overview or index) to the original files in html/com/package\&.
+@@ -2150,7 +2159,7 @@
+ \f3public class Button extends Component implements Accessible\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2161,7 +2170,7 @@
+ \f3public String getLabel()\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2176,8 +2185,9 @@
+ .TP 0.2i
+ \(bu
+ The \f3packagepattern\fR value can be any package name at the start of any package name followed by an asterisk (*)\&. The asterisk is the only wildcard allowed and means match any characters\&. Multiple patterns can be included in a group by separating them with colons (:)\&. If you use an asterisk in a pattern or pattern list, then the pattern list must be inside quotation marks, such as \f3"java\&.lang*:java\&.util"\fR\&.
+-.RE
+-.RS
++.RE
++
++
+ When you do not supply a \f3-group\fR option, all packages are placed in one group with the heading \fIPackages\fR and appropriate subheadings\&. If the subheadings do not include all documented packages (all groups), then the remaining packages appear in a separate group with the subheading Other Packages\&.
+
+ For example, the following \f3javadoc\fR command separates the three documented packages into \fICore\fR, \fIExtension\fR, and \fIOther Packages\fR\&. The trailing dot (\&.) does not appear in \f3java\&.lang*\fR\&. Including the dot, such as \f3java\&.lang\&.*\fR omits the\f3java\&.lang\fR package\&.
+@@ -2192,7 +2202,7 @@
+ \f3 java\&.lang java\&.lang\&.reflect java\&.util javax\&.servlet java\&.new\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2212,8 +2222,6 @@
+ \fIOther Packages\fR
+
+ \f3java\&.new\fR
+-
+-.RE
+ .TP
+ -nodeprecated
+ .br
+@@ -2251,7 +2259,7 @@
+ \f3javadoc \-helpfile /home/user/myhelp\&.html java\&.awt\&.\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2264,7 +2272,7 @@
+ \f3javadoc \-stylesheet file /home/user/mystylesheet\&.css com\&.mypackage\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2283,7 +2291,7 @@
+ \f3<META http\-equiv="Content\-Type" content="text/html; charset=ISO\-8859\-1">\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2296,7 +2304,7 @@
+ .br
+ Specifies the encoding of the generated HTML files\&. The name should be a preferred MIME name as specified in the IANA Registry, Character Sets at http://www\&.iana\&.org/assignments/character-sets
+
+-If you omit the \f3-docencoding\fR option but use the \f3-encoding\fR option, then the encoding of the generated HTML files is determined by the \f3-encoding\fR option, for example: \f3javadoc -docencoding"iso-8859-1" mypackage\fR\&. See also the \f3-encoding\fR and \f3-docencoding name\fR options\&.
++If you omit the \f3-docencoding\fR option but use the \f3-encoding\fR option, then the encoding of the generated HTML files is determined by the \f3-encoding\fR option, for example: \f3javadoc -docencoding "iso-8859-1" mypackage\fR\&. See also the \f3-encoding\fR and \f3-docencoding name\fR options\&.
+ .TP
+ -keywords
+ .br
+@@ -2315,7 +2323,7 @@
+ \f3<META NAME="keywords" CONTENT="charAt()">\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2360,7 +2368,7 @@
+ \f3 */\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2390,7 +2398,7 @@
+ \f3\-tag example:X\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2433,7 +2441,7 @@
+ \f3\-tag see\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2523,7 +2531,7 @@
+ \f3\-sourcepath /java/pubs/ws/1\&.7\&.0/src/share/classes\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ Create a file named packages that contains:
+@@ -2538,7 +2546,7 @@
+ \f3com\&.mypackage3\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ Run the \f3javadoc\fR command as follows:
+@@ -2547,7 +2555,7 @@
+ \f3javadoc @options @packages\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 3 Argument Files with Paths\fR
+@@ -2558,7 +2566,7 @@
+ \f3javadoc @path1/options @path2/packages\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 4 Option Arguments\fR
+@@ -2581,7 +2589,7 @@
+ \f3 Other names may be trademarks of their respective owners\&.</font>\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ Run the \f3javadoc\fR command as follows:\f3javadoc -bottom @bottom @packages\fR\&.
+@@ -2616,7 +2624,7 @@
+ \f3javadoc \-d /home/html \-sourcepath /home/src \-subpackages java \-exclude\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 2 Change to Root and Run Explicit Packages\fR
+@@ -2630,7 +2638,7 @@
+ \f3javadoc \-d /home/html java\&.awt java\&.awt\&.event\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ To also traverse down other package trees, append their names to the \f3-subpackages\fR argument, such as j\f3ava:javax:org\&.xml\&.sax\fR\&.
+@@ -2643,7 +2651,7 @@
+ \f3javadoc \-d /home/html \-sourcepath /home/src java\&.awt java\&.awt\&.event\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 4 Run from Any Directory on Explicit Packages in Multiple Trees\fR
+@@ -2654,7 +2662,7 @@
+ \f3javadoc \-d /home/html \-sourcepath /home/src1:/home/src2 java\&.awt java\&.awt\&.event\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The result is that all cases generate HTML-formatted documentation for the \f3public\fR and \f3protected\fR classes and interfaces in packages j\f3ava\&.awt\fR and \f3java\&.awt\&.even\fRt and save the HTML files in the specified destination directory\&. Because two or more packages are being generated, the document has three HTML frames: one for the list of packages, another for the list of classes, and the third for the main class pages\&.
+@@ -2676,7 +2684,7 @@
+ \f3javadoc \-d /home/html Button\&.java Canvas\&.java Graphics*\&.java\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 2 Change to the Root Directory of the Package\fR
+@@ -2690,7 +2698,7 @@
+ \f3javadoc \-d /home/html java/awt/Button\&.java java/applet/Applet\&.java\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ \f3Example 3 Document Files from Any Directory\fR
+@@ -2704,7 +2712,7 @@
+ \f3/home/src/java/awt/Graphics*\&.java\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2720,7 +2728,7 @@
+ \f3/home/src/java/applet/Applet\&.java\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SS REAL-WORLD\ EXAMPLES
+@@ -2784,7 +2792,7 @@
+ \f3@packages\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+
+@@ -2802,7 +2810,7 @@
+ \f3import javax\&.tools\&.ToolProvider;\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3public class JavaAccessSample{\fP
+@@ -2838,7 +2846,7 @@
+ \f3 }\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ The first three arguments of the \f3run\fR method specify input, standard output, and standard error streams\&. \f3Null\fR is the default value for \f3System\&.in\fR, \f3System\&.out\fR, and \f3System\&.err\fR, respectively\&.
+@@ -2891,7 +2899,7 @@
+ \f3 java\&.applet\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .nf
+ \f3WINDOWTITLE = \&'Java\(tm SE 7 API Specification\&'\fP
+@@ -2927,7 +2935,7 @@
+ \f3SRCDIR = \&'/java/jdk/1\&.7\&.0/src/share/classes\&'\fP
+ .fi
+ .nf
+-\f3\fR
++\f3\fP
+ .fi
+ .sp
+ .SS NOTES
+--- ./jdk/src/solaris/doc/sun/man/man1/jcmd.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/jcmd.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,114 +1,211 @@
+ '\" t
+-.\" Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+-.\"
+-.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-.\"
+-.\" This code is free software; you can redistribute it and/or modify it
+-.\" under the terms of the GNU General Public License version 2 only, as
+-.\" published by the Free Software Foundation.
+-.\"
+-.\" This code is distributed in the hope that it will be useful, but WITHOUT
+-.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-.\" version 2 for more details (a copy is included in the LICENSE file that
+-.\" accompanied this code).
+-.\"
+-.\" You should have received a copy of the GNU General Public License version
+-.\" 2 along with this work; if not, write to the Free Software Foundation,
+-.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-.\"
+-.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-.\" or visit www.oracle.com if you need additional information or have any
+-.\" questions.
+-.\"
+-.\" Arch: generic
+-.\" Software: JDK 8
+-.\" Date: 21 November 2013
+-.\" SectDesc: Troubleshooting Tools
+-.\" Title: jcmd.1
++.\" Copyright (c) 2012, 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.
++.\"
++.\" Title: jcmd
++.\" Language: English
++.\" Date: 03 March 2015
++.\" SectDesc: Troubleshooting Tools
++.\" Software: JDK 8
++.\" Arch: generic
++.\" Part Number: E38207-04
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH jcmd 1 "21 November 2013" "JDK 8" "Troubleshooting Tools"
+-.\" -----------------------------------------------------------------
+-.\" * Define some portability stuff
+-.\" -----------------------------------------------------------------
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.\" http://bugs.debian.org/507673
+-.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.ie \n(.g .ds Aq \(aq
+-.el .ds Aq '
+-.\" -----------------------------------------------------------------
+-.\" * set default formatting
+-.\" -----------------------------------------------------------------
+-.\" disable hyphenation
+-.nh
+-.\" disable justification (adjust text to left margin only)
+-.ad l
+-.\" -----------------------------------------------------------------
+-.\" * MAIN CONTENT STARTS HERE *
+-.\" -----------------------------------------------------------------
+-
+-.SH NAME
++.TH "jcmd" "1" "03 March 2015" "JDK 8" "Troubleshooting Tools"
++.\" -----------------------------------------------------------------
++.\" * Define some portability stuff
++.\" -----------------------------------------------------------------
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.\" http://bugs.debian.org/507673
++.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.ie \n(.g .ds Aq \(aq
++.el .ds Aq '
++.\" -----------------------------------------------------------------
++.\" * set default formatting
++.\" -----------------------------------------------------------------
++.\" disable hyphenation
++.nh
++.\" disable justification (adjust text to left margin only)
++.ad l
++.\" -----------------------------------------------------------------
++.\" * MAIN CONTENT STARTS HERE *
++.\" -----------------------------------------------------------------
++.SH "NAME"
+ jcmd \- Sends diagnostic command requests to a running Java Virtual Machine (JVM)\&.
+-.SH SYNOPSIS
+-.sp
+-.nf
+-
++.SH "SYNOPSIS"
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
+ \fBjcmd\fR [\fB\-l\fR|\fB\-h\fR|\fB\-help\fR]
+-.fi
+-.nf
+-
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
+ \fBjcmd\fR \fIpid\fR|\fImain\-class\fR \fBPerfCounter\&.print\fR
+-.fi
+-.nf
+-
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
+ \fBjcmd\fR \fIpid\fR|\fImain\-class\fR \fB\-f\fR \fIfilename\fR
+-.fi
+-.nf
+-
++.fi
++.if n \{\
++.RE
++.\}
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
+ \fBjcmd\fR \fIpid\fR|\fImain\-class\fR \fIcommand\fR[ \fIarguments\fR]
+-.fi
+-.sp
+-.SH DESCRIPTION
+-The \f3jcmd\fR utility is used to send diagnostic command requests to the JVM\&. It must be used on the same machine on which the JVM is running, and have the same effective user and group identifiers that were used to launch the JVM\&.
++.fi
++.if n \{\
++.RE
++.\}
++.SH "DESCRIPTION"
+ .PP
+-\fINote:\fR To invoke diagnostic commands from a remote machine or with different identiers, you can use the \f3com\&.sun\&.management\&.DiagnosticCommandMBean\fR interface\&. For more information about the \f3DiagnosticCommandMBean\fR interface, see the API documentation at http://download\&.java\&.net/jdk8/docs/jre/api/management/extension/com/sun/management/DiagnosticCommandMBean\&.html
++The
++\fBjcmd\fR
++utility is used to send diagnostic command requests to the JVM\&. It must be used on the same machine on which the JVM is running, and have the same effective user and group identifiers that were used to launch the JVM\&.
++.if n \{\
++.sp
++.\}
++.RS 4
++.it 1 an-trap
++.nr an-no-space-flag 1
++.nr an-break-flag 1
++.br
++.ps +1
++\fBNote\fR
++.ps -1
++.br
++.TS
++allbox tab(:);
++l.
++T{
+ .PP
+-If you run \f3jcmd\fR without arguments or with the \f3-l\fR option, it prints the list of running Java process identifiers with the main class and command-line arguments that were used to launch the process\&. Running \f3jcmd\fR with the \f3-h\fR or \f3-help\fR option prints the tool\(cqs help message\&.
++To invoke diagnostic commands from a remote machine or with different identifiers, you can use the
++\fBcom\&.sun\&.management\&.DiagnosticCommandMBean\fR
++interface\&. For more information about the
++\fBDiagnosticCommandMBean\fR
++interface, see the API documentation at http://docs\&.oracle\&.com/javase/8/docs/jre/api/management/extension/com/sun/management/DiagnosticCommandMBean\&.html
++T}
++.TE
++.sp 1
++.sp .5v
++.RE
+ .PP
+-If you specify the processes identifier (\fIpid\fR) or the main class (\fImain-class\fR) as the first argument, \f3jcmd\fR sends the diagnostic command request to the Java process with the specified identifier or to all Java processes with the specified name of the main class\&. You can also send the diagnostic command request to all available Java processes by specifying \f30\fR as the process identifier\&. Use one of the following as the diagnostic command request:
+-.TP
++If you run
++\fBjcmd\fR
++without arguments or with the
++\fB\-l\fR
++option, it prints the list of running Java process identifiers with the main class and command\-line arguments that were used to launch the process\&. Running
++\fBjcmd\fR
++with the
++\fB\-h\fR
++or
++\fB\-help\fR
++option prints the tool\(cqs help message\&.
++.PP
++If you specify the processes identifier (\fIpid\fR) or the main class (\fImain\-class\fR) as the first argument,
++\fBjcmd\fR
++sends the diagnostic command request to the Java process with the specified identifier or to all Java processes with the specified name of the main class\&. You can also send the diagnostic command request to all available Java processes by specifying
++\fB0\fR
++as the process identifier\&. Use one of the following as the diagnostic command request:
++.PP
+ Perfcounter\&.print
++.RS 4
+ Prints the performance counters available for the specified Java process\&. The list of performance counters might vary with the Java process\&.
+-.TP
+--f \fIfilename\fR
++.RE
++.PP
++\-f \fIfilename\fR
++.RS 4
++The name of the file from which to read diagnostic commands and send them to the specified Java process\&. Used only with the
++\fB\-f\fR
++option\&. Each command in the file must be written on a single line\&. Lines starting with a number sign (\fB#\fR) are ignored\&. Processing of the file ends when all lines have been read or when a line containing the
++\fBstop\fR
++keyword is read\&.
++.RE
++.PP
++\fIcommand\fR [\fIarguments\fR]
++.RS 4
++The command to be sent to the specified Java process\&. The list of available diagnostic commands for a given process can be obtained by sending the
++\fBhelp\fR
++command to this process\&. Each diagnostic command has its own set of arguments\&. To see the description, syntax, and a list of available arguments for a command, use the name of the command as the argument for the
++\fBhelp\fR
++command\&.
++.sp
++\fBNote:\fR
++If any arguments contain spaces, you must surround them with single or double quotation marks (\fB\*(Aq\fR
++or
++\fB"\fR)\&. In addition, you must escape single or double quotation marks with a backslash (\fB\e\fR) to prevent the operating system shell from processing quotation marks\&. Alternatively, you can surround these arguments with single quotation marks and then with double quotation marks (or with double quotation marks and then with single quotation marks)\&.
++.RE
++.SH "OPTIONS"
++.PP
++Options are mutually exclusive\&.
++.PP
++\-f \fIfilename\fR
++.RS 4
++Reads commands from the specified file\&. This option can be used only if you specify the process identifier or the main class as the first argument\&. Each command in the file must be written on a single line\&. Lines starting with a number sign (\fB#\fR) are ignored\&. Processing of the file ends when all lines have been read or when a line containing the
++\fBstop\fR
++keyword is read\&.
++.RE
++.PP
++\-h
+ .br
+-The name of the file from which to read diagnostic commands and send them to the specified Java process\&. Used only with the \f3-f\fR option\&. Each command in the file must be written on a single line\&. Lines starting with a number sign (\f3#\fR) are ignored\&. Processing of the file ends when all lines have been read or when a line containing the \f3stop\fR keyword is read\&.
+-.TP
+-\fIcommand\fR [\fIarguments\fR]
+-The command to be sent to the specified Java process\&. The list of available diagnostic commands for a given process can be obtained by sending the \f3help\fR command to this process\&. Each diagnostic command has its own set of arguments\&. To see the description, syntax, and a list of available arguments for a command, use the name of the command as the argument for the \f3help\fR command\&.
+-
+-\fINote:\fR If any arguments contain spaces, you must surround them with single or double quotation marks (\f3\&'\fR or \f3"\fR)\&. In addition, you must escape single or double quotation marks with a backslash (\f3\e\fR) to prevent the operating system shell from processing quotation marks\&. Alternatively, you can surround these arguments with single quotation marks and then with double quotation marks (or with double quotation marks and then with single quotation marks)\&.
+-.SH OPTIONS
+-Options are mutually exclusive\&.
+-.TP
+--f \fIfilename\fR
++\-help
++.RS 4
++Prints a help message\&.
++.RE
++.PP
++\-l
++.RS 4
++Prints the list of running Java processes identifiers with the main class and command\-line arguments\&.
++.RE
++.SH "SEE ALSO"
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
++jps(1)
++.RE
+ .br
+-Reads commands from the specified file\&. This option can be used only if you specify the process identifier or the main class as the first argument\&. Each command in the file must be written on a single line\&. Lines starting with a number sign (\f3#\fR) are ignored\&. Processing of the file ends when all lines have been read or when a line containing the \f3stop\fR keyword is read\&.
+-.TP
+--h, -help
+-.br
+-Prints a help message\&.
+-.TP
+--l
+-.br
+-Prints the list of running Java processes identifiers with the main class and command-line arguments\&.
+-.SH SEE\ ALSO
+-.TP 0.2i
+-\(bu
+-jps(1)
+-.RE
+-.br
+-'pl 8.5i
+-'bp
++'pl 8.5i
++'bp
+--- ./jdk/src/solaris/doc/sun/man/man1/jjs.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/jjs.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,352 +1,248 @@
+ '\" t
+-.\" Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+-.\"
+-.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-.\"
+-.\" This code is free software; you can redistribute it and/or modify it
+-.\" under the terms of the GNU General Public License version 2 only, as
+-.\" published by the Free Software Foundation.
+-.\"
+-.\" This code is distributed in the hope that it will be useful, but WITHOUT
+-.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-.\" version 2 for more details (a copy is included in the LICENSE file that
+-.\" accompanied this code).
+-.\"
+-.\" You should have received a copy of the GNU General Public License version
+-.\" 2 along with this work; if not, write to the Free Software Foundation,
+-.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-.\"
+-.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-.\" or visit www.oracle.com if you need additional information or have any
+-.\" questions.
+-.\"
+-.\" Arch: generic
+-.\" Software: JDK 8
+-.\" Date: 21 November 2013
+-.\" SectDesc: Basic Tools
+-.\" Title: jjs.1
++.\" Copyright (c) 1994, 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.
++.\"
++.\" Title: jjs
++.\" Language: English
++.\" Date: 03 March 2015
++.\" SectDesc: Basic Tools
++.\" Software: JDK 8
++.\" Arch: generic
++.\" Part Number: E38207-04
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH jjs 1 "21 November 2013" "JDK 8" "Basic Tools"
+-.\" -----------------------------------------------------------------
+-.\" * Define some portability stuff
+-.\" -----------------------------------------------------------------
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.\" http://bugs.debian.org/507673
+-.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.ie \n(.g .ds Aq \(aq
+-.el .ds Aq '
+-.\" -----------------------------------------------------------------
+-.\" * set default formatting
+-.\" -----------------------------------------------------------------
+-.\" disable hyphenation
+-.nh
+-.\" disable justification (adjust text to left margin only)
+-.ad l
+-.\" -----------------------------------------------------------------
+-.\" * MAIN CONTENT STARTS HERE *
+-.\" -----------------------------------------------------------------
+-
+-.SH NAME
++.TH "jjs" "1" "03 March 2015" "JDK 8" "Basic Tools"
++.\" -----------------------------------------------------------------
++.\" * Define some portability stuff
++.\" -----------------------------------------------------------------
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.\" http://bugs.debian.org/507673
++.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.ie \n(.g .ds Aq \(aq
++.el .ds Aq '
++.\" -----------------------------------------------------------------
++.\" * set default formatting
++.\" -----------------------------------------------------------------
++.\" disable hyphenation
++.nh
++.\" disable justification (adjust text to left margin only)
++.ad l
++.\" -----------------------------------------------------------------
++.\" * MAIN CONTENT STARTS HERE *
++.\" -----------------------------------------------------------------
++.SH "NAME"
+ jjs \- Invokes the Nashorn engine\&.
+-.SH SYNOPSIS
+-.sp
+-.nf
+-\f3\fBjjs\fR [\fIoptions\fR] [\fIscript\-files\fR] [\-\- \fIarguments\fR]\fP
+-.fi
+-.sp
+-.TP
++.SH "SYNOPSIS"
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB\fBjjs\fR\fR\fB [\fR\fB\fIoptions\fR\fR\fB] [\fR\fB\fIscript\-files\fR\fR\fB] [\-\- \fR\fB\fIarguments\fR\fR\fB]\fR
++.fi
++.if n \{\
++.RE
++.\}
++.PP
+ \fIoptions\fR
+-One or more options of the \f3jjs\fR command, separated by spaces\&. For more information, see Options\&.
+-.TP
+-\fIscript-files\fR
++.RS 4
++One or more options of the
++\fBjjs\fR
++command, separated by spaces\&. For more information, see Options\&.
++.RE
++.PP
++\fIscript\-files\fR
++.RS 4
+ One or more script files which you want to interpret using Nashorn, separated by spaces\&. If no files are specified, an interactive shell is started\&.
+-.TP
++.RE
++.PP
+ \fIarguments\fR
+-All values after the double hyphen marker (\f3--\fR) are passed through to the script or the interactive shell as arguments\&. These values can be accessed by using the \f3arguments\fR property (see )\&.
+-.SH DESCRIPTION
+-The \f3jjs\fR command-line tool is used to invoke the Nashorn engine\&. You can use it to interpret one or several script files, or to run an interactive shell\&.
+-.SH OPTIONS
+-The options of the \f3jjs\fR command control the conditions under which scripts are interpreted by Nashorn\&.
+-.TP
+--ccs=\fIsize\fR , --class-cache-size=\fIsize\fR
++.RS 4
++All values after the double hyphen marker (\fB\-\-\fR) are passed through to the script or the interactive shell as arguments\&. These values can be accessed by using the
++\fBarguments\fR
++property (see Example 3)\&.
++.RE
++.SH "DESCRIPTION"
++.PP
++The
++\fBjjs\fR
++command\-line tool is used to invoke the Nashorn engine\&. You can use it to interpret one or several script files, or to run an interactive shell\&.
++.SH "OPTIONS"
++.PP
++The options of the
++\fBjjs\fR
++command control the conditions under which scripts are interpreted by Nashorn\&.
++.PP
++\-cp \fIpath\fR
+ .br
+-Sets the class cache size (in bytes)\&. Append the letter \f3k\fR or \f3K\fR to indicate kilobytes (KB), \f3m\fR or \f3M\fR to indicate megabytes (MB), \f3g\fR or \f3G\fR to indicate gigabytes (GB)\&. By default, the class cache size is set to 50 bytes\&. The following example shows how to set it to 1024 bytes (1 KB):
+-.sp
+-.nf
+-\f3\-css=100\fP
+-.fi
+-.nf
+-\f3\-css=1k\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-
+-.TP
+--co, --compile-only
++\-classpath \fIpath\fR
++.RS 4
++Specifies the path to the supporting class files To set multiple paths, the option can be repeated, or you can separate each path with a colon (:)\&.
++.RE
++.PP
++\-D\fIname\fR=\fIvalue\fR
++.RS 4
++Sets a system property to be passed to the script by assigning a value to a property name\&. The following example shows how to invoke Nashorn in interactive mode and assign
++\fBmyValue\fR
++to the property named
++\fBmyKey\fR:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB>> \fR\fB\fBjjs \-DmyKey=myValue\fR\fR
++\fBjjs> \fR\fB\fBjava\&.lang\&.System\&.getProperty("myKey")\fR\fR
++\fBmyValue\fR
++\fBjjs>\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++This option can be repeated to set multiple properties\&.
++.RE
++.PP
++\-doe
+ .br
+-Compiles the script without running it\&.
+-.TP
+--cp \fIpath\fR , --classpath \fIpath\fR
++\-\-dump\-on\-error
++.RS 4
++Provides a full stack trace when an error occurs\&. By default, only a brief error message is printed\&.
++.RE
++.PP
++\-fv
+ .br
+-Specifies the path to the supporting class files To set multiple paths, the option can be repeated, or you can separate each path with a colon (:)\&.
+-.TP
+--D\fIname\fR=\fIvalue\fR
++\-\-fullversion
++.RS 4
++Prints the full Nashorn version string\&.
++.RE
++.PP
++\-fx
++.RS 4
++Launches the script as a JavaFX application\&.
++.RE
++.PP
++\-h
+ .br
+-Sets a system property to be passed to the script by assigning a value to a property name\&. The following example shows how to invoke Nashorn in interactive mode and assign \f3myValue\fR to the property named \f3myKey\fR:
+-.sp
+-.nf
+-\f3>> \fIjjs \-DmyKey=myValue\fR\fP
+-.fi
+-.nf
+-\f3jjs> \fIjava\&.lang\&.System\&.getProperty("myKey")\fR\fP
+-.fi
+-.nf
+-\f3myValue\fP
+-.fi
+-.nf
+-\f3jjs>\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-
+-
+-This option can be repeated to set multiple properties\&.
+-.TP
+--d=\fIpath\fR , --dump-debug-dir=\fIpath\fR
++\-help
++.RS 4
++Prints the list of options and their descriptions\&.
++.RE
++.PP
++\-\-language=[es5]
++.RS 4
++Specifies the ECMAScript language version\&. The default version is ES5\&.
++.RE
++.PP
++\-ot
+ .br
+-Specifies the path to the directory where class files are dumped\&.
+-.TP
+---debug-lines
++\-\-optimistic\-types=[true|false]
++.RS 4
++Enables or disables optimistic type assumptions with deoptimizing recompilation\&. Running with optimistic types will yield higher final speed, but may increase warmup time\&.
++.RE
++.PP
++\-scripting
++.RS 4
++Enables shell scripting features\&.
++.RE
++.PP
++\-strict
++.RS 4
++Enables strict mode, which enforces stronger adherence to the standard (ECMAScript Edition 5\&.1), making it easier to detect common coding errors\&.
++.RE
++.PP
++\-t=\fIzone\fR
+ .br
+-Generates a line number table in the class file\&. By default, this option is enabled\&. To disable it, specify \f3--debug-lines=false\fR\&.
+-.TP
+---debug-locals
++\-timezone=\fIzone\fR
++.RS 4
++Sets the specified time zone for script execution\&. It overrides the time zone set in the OS and used by the
++\fBDate\fR
++object\&.
++.RE
++.PP
++\-v
+ .br
+-Generates a local variable table in the class file\&.
+-.TP
+--doe, --dump-on-error
++\-version
++.RS 4
++Prints the Nashorn version string\&.
++.RE
++.SH "EXAMPLES"
++.PP
++\fBExample 1 \fRRunning a Script with Nashorn
++.RS 4
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjjs script\&.js\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.PP
++\fBExample 2 \fRRunning Nashorn in Interactive Mode
++.RS 4
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB>> \fR\fB\fBjjs\fR\fR
++\fBjjs> \fR\fB\fBprintln("Hello, World!")\fR\fR
++\fBHello, World!\fR
++\fBjjs> \fR\fB\fBquit()\fR\fR
++\fB>>\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.PP
++\fBExample 3 \fRPassing Arguments to Nashorn
++.RS 4
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB>> \fR\fB\fBjjs \-\- a b c\fR\fR
++\fBjjs> \fR\fB\fBarguments\&.join(", ")\fR\fR
++\fBa, b, c\fR
++\fBjjs>\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.RE
++.SH "SEE ALSO"
++.PP
++\fBjrunscript\fR
+ .br
+-Provides a full stack trace when an arror occurs\&. By default, only a brief error message is printed\&.
+-.TP
+---early-lvalue-error
+-.br
+-Reports invalid lvalue expressions as early errors (that is, when the code is parsed)\&. By default, this option is enabled\&. To disable it, specify \f3--early-lvalue-error=false\fR\&. When disabled, invalid lvalue expressions will not be reported until the code is executed\&.
+-.TP
+---empty-statements
+-.br
+-Preserves empty statements in the Java abstract syntax tree\&.
+-.TP
+--fv, --fullversion
+-.br
+-Prints the full Nashorn version string\&.
+-.TP
+---function-statement-error
+-.br
+-Prints an error message when a function declaration is used as a statement\&.
+-.TP
+---function-statement-warning
+-.br
+-Prints a warning message when a function declaration is used as a statement\&.
+-.TP
+--fx
+-.br
+-Launches the script as a JavaFX application\&.
+-.TP
+--h, -help
+-.br
+-Prints the list of options and their descriptions\&.
+-.TP
+--J\fIoption\fR
+-.br
+-Passes the specified \f3java\fR launcher option to the JVM\&. The following example shows how to invoke Nashorn in interactive mode and set the maximum memory used by the JVM to 4 GB:
+-.sp
+-.nf
+-\f3>> \fIjjs \-J\-Xmx4g\fR\fP
+-.fi
+-.nf
+-\f3jjs> \fIjava\&.lang\&.Runtime\&.getRuntime()\&.maxMemory()\fR\fP
+-.fi
+-.nf
+-\f33817799680\fP
+-.fi
+-.nf
+-\f3jjs>\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-
+-
+-This option can be repeated to pass multiple \f3java\fR command options\&.
+-.TP
+---lazy-compilation
+-.br
+-Enables lazy code generation strategies (that is, the entire script is not compiled at once)\&. This option is experimental\&.
+-.TP
+---loader-per-compile
+-.br
+-Creates a new class loader per compile\&. By default, this option is enabled\&. To disable it, specify \f3--loader-per-compile=false\fR\&.
+-.TP
+---log=\fIsubsystem\fR:\fIlevel\fR
+-.br
+-Performs logging at a given level for the specified subsystems\&. You can specify logging levels for multiple subsystems separating them with commas\&. For example:
+-.sp
+-.nf
+-\f3\-\-log=fields:finest,codegen:info\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-
+-.TP
+---package=\fIname\fR
+-.br
+-Specifies the package to which generated class files are added\&.
+-.TP
+---parse-only
+-.br
+-Parses the code without compiling\&.
+-.TP
+---print-ast
+-.br
+-Prints the abstract syntax tree\&.
+-.TP
+---print-code
+-.br
+-Prints bytecode\&.
+-.TP
+---print-lower-ast
+-.br
+-Prints the lowered abstract syntax tree\&.
+-.TP
+---print-lower-parse
+-.br
+-Prints the lowered parse tree\&.
+-.TP
+---print-no-newline
+-.br
+-Forces other \f3--print*\fR options to print the output on one line\&.
+-.TP
+---print-parse
+-.br
+-Prints the parse tree\&.
+-.TP
+---print-symbols
+-.br
+-Prints the symbol table\&.
+-.TP
+--pcs, --profile-callsites
+-.br
+-Dumps callsite profile data\&.
+-.TP
+--scripting
+-.br
+-Enables shell scripting features\&.
+-.TP
+---stderr=\fIfilename\fR|\fIstream\fR|\fItty\fR
+-.br
+-Redirects the standard error stream to the specified file, stream (for example, to \f3stdout\fR), or text terminal\&.
+-.TP
+---stdout=\fIfilename\fR|\fIstream\fR|\fItty\fR
+-.br
+-Redirects the standard output stream to the specified file, stream (for example, to \f3stderr\fR), or text terminal\&.
+-.TP
+--strict
+-.br
+-Enables strict mode, which enforces stronger adherence to the standard (ECMAScript Edition 5\&.1), making it easier to detect common coding errors\&.
+-.TP
+--t=\fIzone\fR , -timezone=\fIzone\fR
+-.br
+-Sets the specified time zone for script execution\&. It overrides the time zone set in the OS and used by the \f3Date\fR object\&.
+-.TP
+--tcs=\fIparameter\fR , --trace-callsites=\fIparameter\fR
+-.br
+-Enables callsite trace mode\&. Possible parameters are the following:
+-.RS
+-.TP
+-miss
+-Trace callsite misses\&.
+-.TP
+-enterexit
+-Trace callsite enter/exit\&.
+-.TP
+-objects
+-Print object properties\&.
+-.RE
+-
+-.TP
+---verify-code
+-.br
+-Verifies bytecode before running\&.
+-.TP
+--v, -version
+-.br
+-Prints the Nashorn version string\&.
+-.TP
+--xhelp
+-.br
+-Prints extended help for command-line options\&.
+-.SH EXAMPLES
+-\f3Example 1 Running a Script with Nashorn\fR
+-.sp
+-.nf
+-\f3jjs script\&.js\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-\f3Example 2 Running Nashorn in Interactive Mode\fR
+-.sp
+-.nf
+-\f3>> \fIjjs\fR\fP
+-.fi
+-.nf
+-\f3jjs> \fIprintln("Hello, World!")\fR\fP
+-.fi
+-.nf
+-\f3Hello, World!\fP
+-.fi
+-.nf
+-\f3jjs> \fIquit()\fR\fP
+-.fi
+-.nf
+-\f3>>\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-\f3Example 3 Passing Arguments to Nashorn\fR
+-.sp
+-.nf
+-\f3>> \fIjjs \-\- a b c\fR\fP
+-.fi
+-.nf
+-\f3jjs> \fIarguments\&.join(", ")\fR\fP
+-.fi
+-.nf
+-\f3a, b, c\fP
+-.fi
+-.nf
+-\f3jjs>\fP
+-.fi
+-.nf
+-\f3\fR
+-.fi
+-.sp
+-.SH SEE\ ALSO
+-\f3jrunscript\fR
+-.RE
+-.br
+-'pl 8.5i
+-'bp
++'pl 8.5i
++'bp
+--- ./jdk/src/solaris/doc/sun/man/man1/jstat.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/jstat.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,568 +1,778 @@
+ '\" t
+-.\" Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+-.\"
+-.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-.\"
+-.\" This code is free software; you can redistribute it and/or modify it
+-.\" under the terms of the GNU General Public License version 2 only, as
+-.\" published by the Free Software Foundation.
+-.\"
+-.\" This code is distributed in the hope that it will be useful, but WITHOUT
+-.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-.\" version 2 for more details (a copy is included in the LICENSE file that
+-.\" accompanied this code).
+-.\"
+-.\" You should have received a copy of the GNU General Public License version
+-.\" 2 along with this work; if not, write to the Free Software Foundation,
+-.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-.\"
+-.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-.\" or visit www.oracle.com if you need additional information or have any
+-.\" questions.
+-.\"
+-.\" Arch: generic
+-.\" Software: JDK 8
+-.\" Date: 10 May 2011
+-.\" SectDesc: Monitoring Tools
+-.\" Title: jstat.1
++.\" Copyright (c) 2004, 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.
++.\"
++.\" Title: jstat
++.\" Language: English
++.\" Date: 03 March 2015
++.\" SectDesc: Monitoring Tools
++.\" Software: JDK 8
++.\" Arch: generic
++.\" Part Number: E38207-04
++.\" Doc ID: JSSON
+ .\"
+ .if n .pl 99999
+-.TH jstat 1 "10 May 2011" "JDK 8" "Monitoring Tools"
+-.\" -----------------------------------------------------------------
+-.\" * Define some portability stuff
+-.\" -----------------------------------------------------------------
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.\" http://bugs.debian.org/507673
+-.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-.ie \n(.g .ds Aq \(aq
+-.el .ds Aq '
+-.\" -----------------------------------------------------------------
+-.\" * set default formatting
+-.\" -----------------------------------------------------------------
+-.\" disable hyphenation
+-.nh
+-.\" disable justification (adjust text to left margin only)
+-.ad l
+-.\" -----------------------------------------------------------------
+-.\" * MAIN CONTENT STARTS HERE *
+-.\" -----------------------------------------------------------------
+-
+-.SH NAME
++.TH "jstat" "1" "03 March 2015" "JDK 8" "Monitoring Tools"
++.\" -----------------------------------------------------------------
++.\" * Define some portability stuff
++.\" -----------------------------------------------------------------
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.\" http://bugs.debian.org/507673
++.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++.ie \n(.g .ds Aq \(aq
++.el .ds Aq '
++.\" -----------------------------------------------------------------
++.\" * set default formatting
++.\" -----------------------------------------------------------------
++.\" disable hyphenation
++.nh
++.\" disable justification (adjust text to left margin only)
++.ad l
++.\" -----------------------------------------------------------------
++.\" * MAIN CONTENT STARTS HERE *
++.\" -----------------------------------------------------------------
++.SH "NAME"
+ jstat \- Monitors Java Virtual Machine (JVM) statistics\&. This command is experimental and unsupported\&.
+-.SH SYNOPSIS
+-.sp
+-.nf
+-
++.SH "SYNOPSIS"
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
+ \fBjstat\fR [ \fIgeneralOption\fR | \fIoutputOptions vmid\fR [ \fIinterval\fR[s|ms] [ \fIcount \fR] ]
+-.fi
+-.sp
+-.TP
++.fi
++.if n \{\
++.RE
++.\}
++.PP
+ \fIgeneralOption\fR
+-A single general command-line option \f3-help\fR or \f3-options\fR\&. See General Options\&.
+-.TP
++.RS 4
++A single general command\-line option
++\fB\-help\fR
++or
++\fB\-options\fR\&. See General Options\&.
++.RE
++.PP
+ \fIoutputOptions\fR
+-One or more output options that consist of a single \f3statOption\fR, plus any of the \f3-t\fR, \f3-h\fR, and \f3-J\fR options\&. See Output Options\&.
+-.TP
++.RS 4
++One or more output options that consist of a single
++\fBstatOption\fR, plus any of the
++\fB\-t\fR,
++\fB\-h\fR, and
++\fB\-J\fR
++options\&. See Output Options\&.
++.RE
++.PP
+ \fIvmid\fR
++.RS 4
+ Virtual machine identifier, which is a string that indicates the target JVM\&. The general syntax is the following:
+-.sp
+-.nf
+-\f3[protocol:][//]lvmid[@hostname[:port]/servername]\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-
+-
+-The syntax of the \f3vmid\fR string corresponds to the syntax of a URI\&. The \f3vmid\fR string can vary from a simple integer that represents a local JVM to a more complex construction that specifies a communications protocol, port number, and other implementation-specific values\&. See Virtual Machine Identifier\&.
+-.TP
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[protocol:][//]lvmid[@hostname[:port]/servername]\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++The syntax of the
++\fBvmid\fR
++string corresponds to the syntax of a URI\&. The
++\fBvmid\fR
++string can vary from a simple integer that represents a local JVM to a more complex construction that specifies a communications protocol, port number, and other implementation\-specific values\&. See Virtual Machine Identifier\&.
++.RE
++.PP
+ \fIinterval\fR [s|ms]
+-Sampling interval in the specified units, seconds (s) or milliseconds (ms)\&. Default units are milliseconds\&. Must be a positive integer\&. When specified, the \f3jstat\fR command produces its output at each interval\&.
+-.TP
++.RS 4
++Sampling interval in the specified units, seconds (s) or milliseconds (ms)\&. Default units are milliseconds\&. Must be a positive integer\&. When specified, the
++\fBjstat\fR
++command produces its output at each interval\&.
++.RE
++.PP
+ \fIcount\fR
+-Number of samples to display\&. The default value is infinity which causes the \f3jstat\fR command to display statistics until the target JVM terminates or the \f3jstat\fR command is terminated\&. This value must be a positive integer\&.
+-.SH DESCRIPTION
+-The \f3jstat\fR command displays performance statistics for an instrumented Java HotSpot VM\&. The target JVM is identified by its virtual machine identifier, or \f3vmid\fR option\&.
+-.SH VIRTUAL\ MACHINE\ IDENTIFIER
+-The syntax of the \f3vmid\fR string corresponds to the syntax of a URI:
+-.sp
+-.nf
+-\f3[protocol:][//]lvmid[@hostname[:port]/servername]\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-.TP
++.RS 4
++Number of samples to display\&. The default value is infinity which causes the
++\fBjstat\fR
++command to display statistics until the target JVM terminates or the
++\fBjstat\fR
++command is terminated\&. This value must be a positive integer\&.
++.RE
++.SH "DESCRIPTION"
++.PP
++The
++\fBjstat\fR
++command displays performance statistics for an instrumented Java HotSpot VM\&. The target JVM is identified by its virtual machine identifier, or
++\fBvmid\fR
++option\&.
++.SH "VIRTUAL MACHINE IDENTIFIER"
++.PP
++The syntax of the
++\fBvmid\fR
++string corresponds to the syntax of a URI:
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fB[protocol:][//]lvmid[@hostname[:port]/servername]\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.PP
+ \fIprotocol\fR
+-The communications protocol\&. If the \fIprotocol\fR value is omitted and a host name is not specified, then the default protocol is a platform-specific optimized local protocol\&. If the \fIprotocol\fR value is omitted and a host name is specified, then the default protocol is \f3rmi\fR\&.
+-.TP
++.RS 4
++The communications protocol\&. If the
++\fIprotocol\fR
++value is omitted and a host name is not specified, then the default protocol is a platform\-specific optimized local protocol\&. If the
++\fIprotocol\fR
++value is omitted and a host name is specified, then the default protocol is
++\fBrmi\fR\&.
++.RE
++.PP
+ \fIlvmid\fR
+-The local virtual machine identifier for the target JVM\&. The \f3lvmid\fR is a platform-specific value that uniquely identifies a JVM on a system\&. The \f3lvmid\fR is the only required component of a virtual machine identifier\&. The \f3lvmid\fR is typically, but not necessarily, the operating system\&'s process identifier for the target JVM process\&. You can use the \f3jps\fR command to determine the \f3lvmid\fR\&. Also, you can determine the \f3lvmid\fR on UNIX platforms with the \f3ps\fR command, and on Windows with the Windows Task Manager\&.
+-.TP
++.RS 4
++The local virtual machine identifier for the target JVM\&. The
++\fBlvmid\fR
++is a platform\-specific value that uniquely identifies a JVM on a system\&. The
++\fBlvmid\fR
++is the only required component of a virtual machine identifier\&. The
++\fBlvmid\fR
++is typically, but not necessarily, the operating system\*(Aqs process identifier for the target JVM process\&. You can use the
++\fBjps\fR
++command to determine the
++\fBlvmid\fR\&. Also, you can determine the
++\fBlvmid\fR
++on Solaris, Linux, and OS X platforms with the
++\fBps\fR
++command, and on Windows with the Windows Task Manager\&.
++.RE
++.PP
+ \fIhostname\fR
+-A hostname or IP address that indicates the target host\&. If the \fIhostname\fR value is omitted, then the target host is the local host\&.
+-.TP
++.RS 4
++A hostname or IP address that indicates the target host\&. If the
++\fIhostname\fR
++value is omitted, then the target host is the local host\&.
++.RE
++.PP
+ \fIport\fR
+-The default port for communicating with the remote server\&. If the \fIhostname\fR value is omitted or the \fIprotocol\fR value specifies an optimized, local protocol, then the \fIport\fR value is ignored\&. Otherwise, treatment of the \f3port\fR parameter is implementation-specific\&. For the default \f3rmi\fR protocol, the port value indicates the port number for the rmiregistry on the remote host\&. If the \fIport\fR value is omitted and the \fIprotocol\fR value indicates \f3rmi\fR, then the default rmiregistry port (1099) is used\&.
+-.TP
++.RS 4
++The default port for communicating with the remote server\&. If the
++\fIhostname\fR
++value is omitted or the
++\fIprotocol\fR
++value specifies an optimized, local protocol, then the
++\fIport\fR
++value is ignored\&. Otherwise, treatment of the
++\fBport\fR
++parameter is implementation\-specific\&. For the default
++\fBrmi\fR
++protocol, the port value indicates the port number for the rmiregistry on the remote host\&. If the
++\fIport\fR
++value is omitted and the
++\fIprotocol\fR
++value indicates
++\fBrmi\fR, then the default rmiregistry port (1099) is used\&.
++.RE
++.PP
+ \fIservername\fR
+-The treatment of the \f3servername\fR parameter depends on implementation\&. For the optimized local protocol, this field is ignored\&. For the \f3rmi\fR protocol, it represents the name of the RMI remote object on the remote host\&.
+-.SH OPTIONS
+-The \f3jstat\fR command supports two types of options, general options and output options\&. General options cause the \f3jstat\fR command to display simple usage and version information\&. Output options determine the content and format of the statistical output\&.
++.RS 4
++The treatment of the
++\fBservername\fR
++parameter depends on implementation\&. For the optimized local protocol, this field is ignored\&. For the
++\fBrmi\fR
++protocol, it represents the name of the RMI remote object on the remote host\&.
++.RE
++.SH "OPTIONS"
++.PP
++The
++\fBjstat\fR
++command supports two types of options, general options and output options\&. General options cause the
++\fBjstat\fR
++command to display simple usage and version information\&. Output options determine the content and format of the statistical output\&.
+ .PP
+ All options and their functionality are subject to change or removal in future releases\&.
+-.SS GENERAL\ OPTIONS
++.SS "General Options"
++.PP
+ If you specify one of the general options, then you cannot specify any other option or parameter\&.
+-.TP
+--help
+-.br
++.PP
++\-help
++.RS 4
+ Displays a help message\&.
+-.TP
+--options
+-.br
++.RE
++.PP
++\-options
++.RS 4
+ Displays a list of static options\&. See Output Options\&.
+-.SS OUTPUT\ OPTIONS
+-If you do not specify a general option, then you can specify output options\&. Output options determine the content and format of the \f3jstat\fR command\&'s output, and consist of a single \f3statOption\fR, plus any of the other output options (\f3-h\fR, \f3-t\fR, and \f3-J\fR)\&. The \f3statOption\fR must come first\&.
++.RE
++.SS "Output Options"
+ .PP
+-Output is formatted as a table, with columns that are separated by spaces\&. A header row with titles describes the columns\&. Use the \f3-h\fR option to set the frequency at which the header is displayed\&. Column header names are consistent among the different options\&. In general, if two options provide a column with the same name, then the data source for the two columns is the same\&.
++If you do not specify a general option, then you can specify output options\&. Output options determine the content and format of the
++\fBjstat\fR
++command\*(Aqs output, and consist of a single
++\fBstatOption\fR, plus any of the other output options (\fB\-h\fR,
++\fB\-t\fR, and
++\fB\-J\fR)\&. The
++\fBstatOption\fR
++must come first\&.
+ .PP
+-Use the \f3-t\fR option to display a time stamp column, labeled Timestamp as the first column of output\&. The Timestamp column contains the elapsed time, in seconds, since the target JVM started\&. The resolution of the time stamp is dependent on various factors and is subject to variation due to delayed thread scheduling on heavily loaded systems\&.
++Output is formatted as a table, with columns that are separated by spaces\&. A header row with titles describes the columns\&. Use the
++\fB\-h\fR
++option to set the frequency at which the header is displayed\&. Column header names are consistent among the different options\&. In general, if two options provide a column with the same name, then the data source for the two columns is the same\&.
+ .PP
+-Use the interval and count parameters to determine how frequently and how many times, respectively, the \f3jstat\fR command displays its output\&.
++Use the
++\fB\-t\fR
++option to display a time stamp column, labeled Timestamp as the first column of output\&. The Timestamp column contains the elapsed time, in seconds, since the target JVM started\&. The resolution of the time stamp is dependent on various factors and is subject to variation due to delayed thread scheduling on heavily loaded systems\&.
+ .PP
+-\fINote:\fR Do not to write scripts to parse the \f3jstat\fR command\&'s output because the format might change in future releases\&. If you write scripts that parse \f3jstat\fR command output, then expect to modify them for future releases of this tool\&.
+-.TP
+--\fIstatOption\fR
+-.br
+-Determines the statistics information the \f3jstat\fR command displays\&. The following lists the available options\&. Use the \f3-options\fR general option to display the list of options for a particular platform installation\&. See Stat Options and Output\&.
+-
+-\f3class\fR: Displays statistics about the behavior of the class loader\&.
+-
+-\f3compiler\fR: Displays statistics about the behavior of the Java HotSpot VM Just-in-Time compiler\&.
+-
+-\f3gc\fR: Displays statistics about the behavior of the garbage collected heap\&.
+-
+-\f3gccapacity\fR: Displays statistics about the capacities of the generations and their corresponding spaces\&.
+-
+-\f3gccause\fR: Displays a summary about garbage collection statistics (same as \f3-gcutil\fR), with the cause of the last and current (when applicable) garbage collection events\&.
+-
+-\f3gcnew\fR: Displays statistics of the behavior of the new generation\&.
+-
+-\f3gcnewcapacity\fR: Displays statistics about the sizes of the new generations and its corresponding spaces\&.
+-
+-\f3gcold\fR: Displays statistics about the behavior of the old generation and Metaspace Statistics\&.
+-
+-\f3gcoldcapacity\fR: Displays statistics about the sizes of the old generation\&.
+-
+-\f3gcmetacapacity\fR: Displays statistics about the sizes of the metaspace\&.
+-
+-\f3gcutil\fR: Displays a summary about garbage collection statistics\&.
+-
+-\f3printcompilation\fR: Displays Java HotSpot VM compilation method statistics\&.
+-.TP
+--h \fIn\fR
+-.br
+-Displays a column header every \fIn\fR samples (output rows), where \fIn\fR is a positive integer\&. Default value is 0, which displays the column header the first row of data\&.
+-.TP
+--t
+-.br
+-Display sa timestamp column as the first column of output\&. The time stamp is the time since the start time of the target JVM\&.
+-.TP
+--J\fIjavaOption\fR
+-.br
+-Passes \f3javaOption\fR to the Java application launcher\&. For example, \f3-J-Xms48m\fR sets the startup memory to 48 MB\&. For a complete list of options, see java(1)\&.
+-.SS STAT\ OPTIONS\ AND\ OUTPUT
+-The following information summarizes the columns that the \f3jstat\fR command outputs for each \fIstatOption\fR\&.
+-.TP
+--class \fIoption\fR
+-.br
++Use the interval and count parameters to determine how frequently and how many times, respectively, the
++\fBjstat\fR
++command displays its output\&.
++.PP
++\fBNote:\fR
++Do not to write scripts to parse the
++\fBjstat\fR
++command\*(Aqs output because the format might change in future releases\&. If you write scripts that parse
++\fBjstat\fR
++command output, then expect to modify them for future releases of this tool\&.
++.PP
++\-\fIstatOption\fR
++.RS 4
++Determines the statistics information the
++\fBjstat\fR
++command displays\&. The following lists the available options\&. Use the
++\fB\-options\fR
++general option to display the list of options for a particular platform installation\&. See Stat Options and Output\&.
++.sp
++\fBclass\fR: Displays statistics about the behavior of the class loader\&.
++.sp
++\fBcompiler\fR: Displays statistics about the behavior of the Java HotSpot VM Just\-in\-Time compiler\&.
++.sp
++\fBgc\fR: Displays statistics about the behavior of the garbage collected heap\&.
++.sp
++\fBgccapacity\fR: Displays statistics about the capacities of the generations and their corresponding spaces\&.
++.sp
++\fBgccause\fR: Displays a summary about garbage collection statistics (same as
++\fB\-gcutil\fR), with the cause of the last and current (when applicable) garbage collection events\&.
++.sp
++\fBgcnew\fR: Displays statistics of the behavior of the new generation\&.
++.sp
++\fBgcnewcapacity\fR: Displays statistics about the sizes of the new generations and its corresponding spaces\&.
++.sp
++\fBgcold\fR: Displays statistics about the behavior of the old generation and metaspace statistics\&.
++.sp
++\fBgcoldcapacity\fR: Displays statistics about the sizes of the old generation\&.
++.sp
++\fBgcmetacapacity\fR: Displays statistics about the sizes of the metaspace\&.
++.sp
++\fBgcutil\fR: Displays a summary about garbage collection statistics\&.
++.sp
++\fBprintcompilation\fR: Displays Java HotSpot VM compilation method statistics\&.
++.RE
++.PP
++\-h \fIn\fR
++.RS 4
++Displays a column header every
++\fIn\fR
++samples (output rows), where
++\fIn\fR
++is a positive integer\&. Default value is 0, which displays the column header the first row of data\&.
++.RE
++.PP
++\-t
++.RS 4
++Displays a timestamp column as the first column of output\&. The time stamp is the time since the start time of the target JVM\&.
++.RE
++.PP
++\-J\fIjavaOption\fR
++.RS 4
++Passes
++\fBjavaOption\fR
++to the Java application launcher\&. For example,
++\fB\-J\-Xms48m\fR
++sets the startup memory to 48 MB\&. For a complete list of options, see
++java(1)\&.
++.RE
++.SS "Stat Options and Output"
++.PP
++The following information summarizes the columns that the
++\fBjstat\fR
++command outputs for each
++\fIstatOption\fR\&.
++.PP
++\-class \fIoption\fR
++.RS 4
+ Class loader statistics\&.
+-
+-\f3Loaded\fR: Number of classes loaded\&.
+-
+-\f3Bytes\fR: Number of KBs loaded\&.
+-
+-\f3Unloaded\fR: Number of classes unloaded\&.
+-
+-\f3Bytes\fR: Number of Kbytes unloaded\&.
+-
+-\f3Time\fR: Time spent performing class loading and unloading operations\&.
+-.TP
+--compiler \fIoption\fR
+-.br
+-Java HotSpot VM Just-in-Time compiler statistics\&.
+-
+-\f3Compiled\fR: Number of compilation tasks performed\&.
+-
+-\f3Failed\fR: Number of compilations tasks failed\&.
+-
+-\f3Invalid\fR: Number of compilation tasks that were invalidated\&.
+-
+-\f3Time\fR: Time spent performing compilation tasks\&.
+-
+-\f3FailedType\fR: Compile type of the last failed compilation\&.
+-
+-\f3FailedMethod\fR: Class name and method of the last failed compilation\&.
+-.TP
+--gc \fIoption\fR
+-.br
+-Garbage-collected heap statistics\&.
+-
+-\f3S0C\fR: Current survivor space 0 capacity (KB)\&.
+-
+-\f3S1C\fR: Current survivor space 1 capacity (KB)\&.
+-
+-\f3S0U\fR: Survivor space 0 utilization (KB)\&.
+-
+-\f3S1U\fR: Survivor space 1 utilization (KB)\&.
+-
+-\f3EC\fR: Current eden space capacity (KB)\&.
+-
+-\f3EU\fR: Eden space utilization (KB)\&.
+-
+-\f3OC\fR: Current old space capacity (KB)\&.
+-
+-\f3OU\fR: Old space utilization (KB)\&.
+-
+-\f3MC\fR: Metaspace capacity (KB)\&.
+-
+-\f3MU\fR: Metacspace utilization (KB)\&.
+-
+-\f3YGC\fR: Number of young generation garbage collection events\&.
+-
+-\f3YGCT\fR: Young generation garbage collection time\&.
+-
+-\f3FGC\fR: Number of full GC events\&.
+-
+-\f3FGCT\fR: Full garbage collection time\&.
+-
+-\f3GCT\fR: Total garbage collection time\&.
+-.TP
+--gccapacity \fIoption\fR
+-.br
++.sp
++\fBLoaded\fR: Number of classes loaded\&.
++.sp
++\fBBytes\fR: Number of kBs loaded\&.
++.sp
++\fBUnloaded\fR: Number of classes unloaded\&.
++.sp
++\fBBytes\fR: Number of Kbytes unloaded\&.
++.sp
++\fBTime\fR: Time spent performing class loading and unloading operations\&.
++.RE
++.PP
++\-compiler \fIoption\fR
++.RS 4
++Java HotSpot VM Just\-in\-Time compiler statistics\&.
++.sp
++\fBCompiled\fR: Number of compilation tasks performed\&.
++.sp
++\fBFailed\fR: Number of compilations tasks failed\&.
++.sp
++\fBInvalid\fR: Number of compilation tasks that were invalidated\&.
++.sp
++\fBTime\fR: Time spent performing compilation tasks\&.
++.sp
++\fBFailedType\fR: Compile type of the last failed compilation\&.
++.sp
++\fBFailedMethod\fR: Class name and method of the last failed compilation\&.
++.RE
++.PP
++\-gc \fIoption\fR
++.RS 4
++Garbage\-collected heap statistics\&.
++.sp
++\fBS0C\fR: Current survivor space 0 capacity (kB)\&.
++.sp
++\fBS1C\fR: Current survivor space 1 capacity (kB)\&.
++.sp
++\fBS0U\fR: Survivor space 0 utilization (kB)\&.
++.sp
++\fBS1U\fR: Survivor space 1 utilization (kB)\&.
++.sp
++\fBEC\fR: Current eden space capacity (kB)\&.
++.sp
++\fBEU\fR: Eden space utilization (kB)\&.
++.sp
++\fBOC\fR: Current old space capacity (kB)\&.
++.sp
++\fBOU\fR: Old space utilization (kB)\&.
++.sp
++\fBMC\fR: Metaspace capacity (kB)\&.
++.sp
++\fBMU\fR: Metacspace utilization (kB)\&.
++.sp
++\fBCCSC\fR: Compressed class space capacity (kB)\&.
++.sp
++\fBCCSU\fR: Compressed class space used (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation garbage collection events\&.
++.sp
++\fBYGCT\fR: Young generation garbage collection time\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.sp
++\fBFGCT\fR: Full garbage collection time\&.
++.sp
++\fBGCT\fR: Total garbage collection time\&.
++.RE
++.PP
++\-gccapacity \fIoption\fR
++.RS 4
+ Memory pool generation and space capacities\&.
+-
+-\f3NGCMN\fR: Minimum new generation capacity (KB)\&.
+-
+-\f3NGCMX\fR: Maximum new generation capacity (KB)\&.
+-
+-\f3NGC\fR: Current new generation capacity (KB)\&.
+-
+-\f3S0C\fR: Current survivor space 0 capacity (KB)\&.
+-
+-\f3S1C\fR: Current survivor space 1 capacity (KB)\&.
+-
+-\f3EC\fR: Current eden space capacity (KB)\&.
+-
+-\f3OGCMN\fR: Minimum old generation capacity (KB)\&.
+-
+-\f3OGCMX\fR: Maximum old generation capacity (KB)\&.
+-
+-\f3OGC\fR: Current old generation capacity (KB)\&.
+-
+-\f3OC\fR: Current old space capacity (KB)\&.
+-
+-\f3MCMN\fR: Minimum metaspace capacity (KB)\&.
+-
+-\f3MCMX\fR: Maximum metaspace capacity (KB)\&.
+-
+-\f3MC\fR: Metaspace capacity (KB)\&.
+-
+-\f3YGC\fR: Number of Young generation GC Events\&.
+-
+-\f3FGC\fR: Number of Full GC Events\&.
+-.TP
+--gccause \fIoption\fR
+-.br
+-This option displays the same summary of garbage collection statistics as the \f3-gcutil\fR option, but includes the causes of the last garbage collection event and (when applicable) the current garbage collection event\&. In addition to the columns listed for \f3-gcutil\fR, this option adds the following columns\&.
+-
+-Garbage collection statistics, including garbage collection Events\&.
+-
+-\f3LGCC\fR: Cause of last garbage collection\&.
+-
+-\f3GCC\fR: Cause of current garbage collection\&.
+-.TP
+--gcnew \fIoption\fR
+-.br
++.sp
++\fBNGCMN\fR: Minimum new generation capacity (kB)\&.
++.sp
++\fBNGCMX\fR: Maximum new generation capacity (kB)\&.
++.sp
++\fBNGC\fR: Current new generation capacity (kB)\&.
++.sp
++\fBS0C\fR: Current survivor space 0 capacity (kB)\&.
++.sp
++\fBS1C\fR: Current survivor space 1 capacity (kB)\&.
++.sp
++\fBEC\fR: Current eden space capacity (kB)\&.
++.sp
++\fBOGCMN\fR: Minimum old generation capacity (kB)\&.
++.sp
++\fBOGCMX\fR: Maximum old generation capacity (kB)\&.
++.sp
++\fBOGC\fR: Current old generation capacity (kB)\&.
++.sp
++\fBOC\fR: Current old space capacity (kB)\&.
++.sp
++\fBMCMN\fR: Minimum metaspace capacity (kB)\&.
++.sp
++\fBMCMX\fR: Maximum metaspace capacity (kB)\&.
++.sp
++\fBMC\fR: Metaspace capacity (kB)\&.
++.sp
++\fBCCSMN\fR: Compressed class space minimum capacity (kB)\&.
++.sp
++\fBCCSMX\fR: Compressed class space maximum capacity (kB)\&.
++.sp
++\fBCCSC\fR: Compressed class space capacity (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.RE
++.PP
++\-gccause \fIoption\fR
++.RS 4
++This option displays the same summary of garbage collection statistics as the
++\fB\-gcutil\fR
++option, but includes the causes of the last garbage collection event and (when applicable) the current garbage collection event\&. In addition to the columns listed for
++\fB\-gcutil\fR, this option adds the following columns\&.
++.sp
++\fBLGCC\fR: Cause of last garbage collection
++.sp
++\fBGCC\fR: Cause of current garbage collection
++.RE
++.PP
++\-gcnew \fIoption\fR
++.RS 4
+ New generation statistics\&.
+-
+-\f3S0C\fR: Current survivor space 0 capacity (KB)\&.
+-
+-\f3S1C\fR: Current survivor space 1 capacity (KB)\&.
+-
+-\f3S0U\fR: Survivor space 0 utilization (KB)\&.
+-
+-\f3S1U\fR: Survivor space 1 utilization (KB)\&.
+-
+-\f3TT\fR: Tenuring threshold\&.
+-
+-\f3MTT\fR: Maximum tenuring threshold\&.
+-
+-\f3DSS\fR: Desired survivor size (KB)\&.
+-
+-\f3EC\fR: Current eden space capacity (KB)\&.
+-
+-\f3EU\fR: Eden space utilization (KB)\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3YGCT\fR: Young generation garbage collection time\&.
+-.TP
+--gcnewcapacity \fIoption\fR
+-.br
++.sp
++\fBS0C\fR: Current survivor space 0 capacity (kB)\&.
++.sp
++\fBS1C\fR: Current survivor space 1 capacity (kB)\&.
++.sp
++\fBS0U\fR: Survivor space 0 utilization (kB)\&.
++.sp
++\fBS1U\fR: Survivor space 1 utilization (kB)\&.
++.sp
++\fBTT\fR: Tenuring threshold\&.
++.sp
++\fBMTT\fR: Maximum tenuring threshold\&.
++.sp
++\fBDSS\fR: Desired survivor size (kB)\&.
++.sp
++\fBEC\fR: Current eden space capacity (kB)\&.
++.sp
++\fBEU\fR: Eden space utilization (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBYGCT\fR: Young generation garbage collection time\&.
++.RE
++.PP
++\-gcnewcapacity \fIoption\fR
++.RS 4
+ New generation space size statistics\&.
+-
+-NGCMN: Minimum new generation capacity (KB)\&.
+-
+-\f3NGCMX\fR: Maximum new generation capacity (KB)\&.
+-
+-\f3NGC\fR: Current new generation capacity (KB)\&.
+-
+-\f3S0CMX\fR: Maximum survivor space 0 capacity (KB)\&.
+-
+-\f3S0C\fR: Current survivor space 0 capacity (KB)\&.
+-
+-\f3S1CMX\fR: Maximum survivor space 1 capacity (KB)\&.
+-
+-\f3S1C\fR: Current survivor space 1 capacity (KB)\&.
+-
+-\f3ECMX\fR: Maximum eden space capacity (KB)\&.
+-
+-\f3EC\fR: Current eden space capacity (KB)\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3FGC\fR: Number of Full GC Events\&.
+-.TP
+--gcold \fIoption\fR
+-.br
+-old and permanent generation statistics\&.
+-
+-\f3MC\fR: Metaspace capacity (KB)\&.
+-
+-\f3MU\fR: Metaspace utilization (KB)\&.
+-
+-\f3OC\fR: Current old space capacity (KB)\&.
+-
+-\f3OU\fR: old space utilization (KB)\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3FGC\fR: Number of full GC events\&.
+-
+-\f3FGCT\fR: Full garbage collection time\&.
+-
+-\f3GCT\fR: Total garbage collection time\&.
+-.TP
+--gcoldcapacity \fIoption\fR
+-.br
+-Old generation statistics\&.
+-
+-\f3OGCMN\fR: Minimum old generation capacity (KB)\&.
+-
+-\f3OGCMX\fR: Maximum old generation capacity (KB)\&.
+-
+-\f3OGC\fR: Current old generation capacity (KB)\&.
+-
+-\f3OC\fR: Current old space capacity (KB)\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3FGC\fR: Number of full GC events\&.
+-
+-\f3FGCT\fR: Full garbage collection time\&.
+-
+-\f3GCT\fR: Total garbage collection time\&.
+-.TP
+--gcmetacapacity \fIoption\fR
+-.br
+-Permanent generation statistics\&.
+-
+-\f3MCMN\fR: Minimum metaspace capacity (KB)\&.
+-
+-\f3MCMX\fR: Maximum metaspace capacity (KB)\&.
+-
+-\f3MC\fR: Metaspace capacity (KB)\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3FGC\fR: Number of full GC events\&.
+-
+-\f3FGCT\fR: Full garbage collection time\&.
+-
+-\f3GCT\fR: Total garbage collection time\&.
+-.TP
+--gcutil \fIoption\fR
+-.br
++.sp
++\fBNGCMN\fR: Minimum new generation capacity (kB)\&.
++.sp
++\fBNGCMX\fR: Maximum new generation capacity (kB)\&.
++.sp
++\fBNGC\fR: Current new generation capacity (kB)\&.
++.sp
++\fBS0CMX\fR: Maximum survivor space 0 capacity (kB)\&.
++.sp
++\fBS0C\fR: Current survivor space 0 capacity (kB)\&.
++.sp
++\fBS1CMX\fR: Maximum survivor space 1 capacity (kB)\&.
++.sp
++\fBS1C\fR: Current survivor space 1 capacity (kB)\&.
++.sp
++\fBECMX\fR: Maximum eden space capacity (kB)\&.
++.sp
++\fBEC\fR: Current eden space capacity (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.RE
++.PP
++\-gcold \fIoption\fR
++.RS 4
++Old generation and metaspace behavior statistics\&.
++.sp
++\fBMC\fR: Metaspace capacity (kB)\&.
++.sp
++\fBMU\fR: Metaspace utilization (kB)\&.
++.sp
++\fBCCSC\fR: Compressed class space capacity (kB)\&.
++.sp
++\fBCCSU\fR: Compressed class space used (kB)\&.
++.sp
++\fBOC\fR: Current old space capacity (kB)\&.
++.sp
++\fBOU\fR: Old space utilization (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.sp
++\fBFGCT\fR: Full garbage collection time\&.
++.sp
++\fBGCT\fR: Total garbage collection time\&.
++.RE
++.PP
++\-gcoldcapacity \fIoption\fR
++.RS 4
++Old generation size statistics\&.
++.sp
++\fBOGCMN\fR: Minimum old generation capacity (kB)\&.
++.sp
++\fBOGCMX\fR: Maximum old generation capacity (kB)\&.
++.sp
++\fBOGC\fR: Current old generation capacity (kB)\&.
++.sp
++\fBOC\fR: Current old space capacity (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.sp
++\fBFGCT\fR: Full garbage collection time\&.
++.sp
++\fBGCT\fR: Total garbage collection time\&.
++.RE
++.PP
++\-gcmetacapacity \fIoption\fR
++.RS 4
++Metaspace size statistics\&.
++.sp
++\fBMCMN\fR: Minimum metaspace capacity (kB)\&.
++.sp
++\fBMCMX\fR: Maximum metaspace capacity (kB)\&.
++.sp
++\fBMC\fR: Metaspace capacity (kB)\&.
++.sp
++\fBCCSMN\fR: Compressed class space minimum capacity (kB)\&.
++.sp
++\fBCCSMX\fR: Compressed class space maximum capacity (kB)\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.sp
++\fBFGCT\fR: Full garbage collection time\&.
++.sp
++\fBGCT\fR: Total garbage collection time\&.
++.RE
++.PP
++\-gcutil \fIoption\fR
++.RS 4
+ Summary of garbage collection statistics\&.
+-
+-\f3S0\fR: Survivor space 0 utilization as a percentage of the space\&'s current capacity\&.
+-
+-\f3S1\fR: Survivor space 1 utilization as a percentage of the space\&'s current capacity\&.
+-
+-\f3E\fR: Eden space utilization as a percentage of the space\&'s current capacity\&.
+-
+-\f3O\fR: Old space utilization as a percentage of the space\&'s current capacity\&.
+-
+-\f3M\fR: Metaspace utilization as a percentage of the space\&'s current capacity\&.
+-
+-\f3YGC\fR: Number of young generation GC events\&.
+-
+-\f3YGCT\fR: Young generation garbage collection time\&.
+-
+-\f3FGC\fR: Number of full GC events\&.
+-
+-\f3FGCT\fR: Full garbage collection time\&.
+-
+-\f3GCT\fR: Total garbage collection time\&.
+-.TP
+--printcompilation \fIoption\fR
+-.br
++.sp
++\fBS0\fR: Survivor space 0 utilization as a percentage of the space\*(Aqs current capacity\&.
++.sp
++\fBS1\fR: Survivor space 1 utilization as a percentage of the space\*(Aqs current capacity\&.
++.sp
++\fBE\fR: Eden space utilization as a percentage of the space\*(Aqs current capacity\&.
++.sp
++\fBO\fR: Old space utilization as a percentage of the space\*(Aqs current capacity\&.
++.sp
++\fBM\fR: Metaspace utilization as a percentage of the space\*(Aqs current capacity\&.
++.sp
++\fBCCS\fR: Compressed class space utilization as a percentage\&.
++.sp
++\fBYGC\fR: Number of young generation GC events\&.
++.sp
++\fBYGCT\fR: Young generation garbage collection time\&.
++.sp
++\fBFGC\fR: Number of full GC events\&.
++.sp
++\fBFGCT\fR: Full garbage collection time\&.
++.sp
++\fBGCT\fR: Total garbage collection time\&.
++.RE
++.PP
++\-printcompilation \fIoption\fR
++.RS 4
+ Java HotSpot VM compiler method statistics\&.
+-
+-\f3Compiled\fR: Number of compilation tasks performed by the most recently compiled method\&.
+-
+-\f3Size\fR: Number of bytes of byte code of the most recently compiled method\&.
+-
+-\f3Type\fR: Compilation type of the most recently compiled method\&.
+-
+-\f3Method\fR: Class name and method name identifying the most recently compiled method\&. Class name uses slash (/) instead of dot (\&.) as a name space separator\&. Method name is the method within the specified class\&. The format for these two fields is consistent with the HotSpot \f3-XX:+PrintComplation\fR option\&.
+-.SH EXAMPLES
+-This section presents some examples of monitoring a local JVM with an \fIlvmid\fR of 21891\&.
+-.SS THE\ GCUTIL\ OPTION
+-This example attaches to lvmid 21891 and takes 7 samples at 250 millisecond intervals and displays the output as specified by the -\f3gcutil\fR option\&.
++.sp
++\fBCompiled\fR: Number of compilation tasks performed by the most recently compiled method\&.
++.sp
++\fBSize\fR: Number of bytes of byte code of the most recently compiled method\&.
++.sp
++\fBType\fR: Compilation type of the most recently compiled method\&.
++.sp
++\fBMethod\fR: Class name and method name identifying the most recently compiled method\&. Class name uses slash (/) instead of dot (\&.) as a name space separator\&. Method name is the method within the specified class\&. The format for these two fields is consistent with the HotSpot
++\fB\-XX:+PrintCompilation\fR
++option\&.
++.RE
++.SH "EXAMPLES"
+ .PP
+-The output of this example shows that a young generation collection occurred between the third and fourth sample\&. The collection took 0\&.001 seconds and promoted objects from the eden space (E) to the old space (O), resulting in an increase of old space utilization from 9\&.49% to 9\&.51%\&. Before the collection, the survivor space was 12\&.44% utilized, but after this collection it is only 7\&.74% utilized\&.
+-.sp
+-.nf
+-\f3jstat \-gcutil 21891 250 7\fP
+-.fi
+-.nf
+-\f3 S0 S1 E O M YGC YGCT FGC FGCT GCT\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.49 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.80 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.80 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f30\&.00 99\&.74 13\&.80 7\&.86 95\&.82 3 0\&.124 0 0\&.000 0\&.124\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-.SS REPEAT\ THE\ COLUMN\ HEADER\ STRING
+-This example attaches to lvmid 21891 and takes samples at 250 millisecond intervals and displays the output as specified by \f3-gcutil\fR option\&. In addition, it uses the \f3-h3\fR option to output the column header after every 3 lines of data\&.
++This section presents some examples of monitoring a local JVM with an
++\fIlvmid\fR
++of 21891\&.
++.SS "The gcutil Option"
++.PP
++This example attaches to lvmid 21891 and takes 7 samples at 250 millisecond intervals and displays the output as specified by the \-\fBgcutil\fR
++option\&.
++.PP
++The output of this example shows that a young generation collection occurred between the third and fourth sample\&. The collection took 0\&.078 seconds and promoted objects from the eden space (E) to the old space (O), resulting in an increase of old space utilization from 66\&.80% to 68\&.19%\&. Before the collection, the survivor space was 97\&.02% utilized, but after this collection it is 91\&.03% utilized\&.
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjstat \-gcutil 21891 250 7\fR
++\fB S0 S1 E O M CCS YGC YGCT FGC FGCT GCT \fR
++\fB 0\&.00 97\&.02 70\&.31 66\&.80 95\&.52 89\&.14 7 0\&.300 0 0\&.000 0\&.300\fR
++\fB 0\&.00 97\&.02 86\&.23 66\&.80 95\&.52 89\&.14 7 0\&.300 0 0\&.000 0\&.300\fR
++\fB 0\&.00 97\&.02 96\&.53 66\&.80 95\&.52 89\&.14 7 0\&.300 0 0\&.000 0\&.300\fR
++\fB 91\&.03 0\&.00 1\&.98 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++\fB 91\&.03 0\&.00 15\&.82 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++\fB 91\&.03 0\&.00 17\&.80 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++\fB 91\&.03 0\&.00 17\&.80 68\&.19 95\&.89 91\&.24 8 0\&.378 0 0\&.000 0\&.378\fR
++.fi
++.if n \{\
++.RE
++.\}
++.SS "Repeat the Column Header String"
++.PP
++This example attaches to lvmid 21891 and takes samples at 250 millisecond intervals and displays the output as specified by
++\fB\-gcnew\fR
++option\&. In addition, it uses the
++\fB\-h3\fR
++option to output the column header after every 3 lines of data\&.
+ .PP
+ In addition to showing the repeating header string, this example shows that between the second and third samples, a young GC occurred\&. Its duration was 0\&.001 seconds\&. The collection found enough active data that the survivor space 0 utilization (S0U) would have exceeded the desired survivor Size (DSS)\&. As a result, objects were promoted to the old generation (not visible in this output), and the tenuring threshold (TT) was lowered from 31 to 2\&.
+ .PP
+ Another collection occurs between the fifth and sixth samples\&. This collection found very few survivors and returned the tenuring threshold to 31\&.
+-.sp
+-.nf
+-\f3jstat \-gcnew \-h3 21891 250\fP
+-.fi
+-.nf
+-\f3 S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 0\&.0 31\&.7 31 31 32\&.0 512\&.0 178\&.6 249 0\&.203\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 0\&.0 31\&.7 31 31 32\&.0 512\&.0 355\&.5 249 0\&.203\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 21\&.9 250 0\&.204\fP
+-.fi
+-.nf
+-\f3 S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 245\&.9 250 0\&.204\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 421\&.1 250 0\&.204\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 0\&.0 19\&.0 31 31 32\&.0 512\&.0 84\&.4 251 0\&.204\fP
+-.fi
+-.nf
+-\f3 S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fP
+-.fi
+-.nf
+-\f3 64\&.0 64\&.0 0\&.0 19\&.0 31 31 32\&.0 512\&.0 306\&.7 251 0\&.204\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-.SS INCLUDE\ A\ TIME\ STAMP\ FOR\ EACH\ SAMPLE
+-This example attaches to lvmid 21891 and takes 3 samples at 250 millisecond intervals\&. The \f3-t\fR option is used to generate a time stamp for each sample in the first column\&.
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjstat \-gcnew \-h3 21891 250\fR
++\fB S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fR
++\fB 64\&.0 64\&.0 0\&.0 31\&.7 31 31 32\&.0 512\&.0 178\&.6 249 0\&.203\fR
++\fB 64\&.0 64\&.0 0\&.0 31\&.7 31 31 32\&.0 512\&.0 355\&.5 249 0\&.203\fR
++\fB 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 21\&.9 250 0\&.204\fR
++\fB S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fR
++\fB 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 245\&.9 250 0\&.204\fR
++\fB 64\&.0 64\&.0 35\&.4 0\&.0 2 31 32\&.0 512\&.0 421\&.1 250 0\&.204\fR
++\fB 64\&.0 64\&.0 0\&.0 19\&.0 31 31 32\&.0 512\&.0 84\&.4 251 0\&.204\fR
++\fB S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT\fR
++\fB 64\&.0 64\&.0 0\&.0 19\&.0 31 31 32\&.0 512\&.0 306\&.7 251 0\&.204\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.SS "Include a Time Stamp for Each Sample"
+ .PP
+-The Timestamp column reports the elapsed time in seconds since the start of the target JVM\&. In addition, the \f3-gcoldcapacity\fR output shows the old generation capacity (OGC) and the old space capacity (OC) increasing as the heap expands to meet allocation or promotion demands\&. The old generation capacity (OGC) has grown to from 11,696 KB to 13820 KB after the eighty-first full garbage collection (FGC)\&. The maximum capacity of the generation (and space) is 60,544 KB (OGCMX), so it still has room to expand\&.
+-.sp
+-.nf
+-\f3Timestamp OGCMN OGCMX OGC OC YGC FGC FGCT GCT\fP
+-.fi
+-.nf
+-\f3 150\&.1 1408\&.0 60544\&.0 11696\&.0 11696\&.0 194 80 2\&.874 3\&.799\fP
+-.fi
+-.nf
+-\f3 150\&.4 1408\&.0 60544\&.0 13820\&.0 13820\&.0 194 81 2\&.938 3\&.863\fP
+-.fi
+-.nf
+-\f3 150\&.7 1408\&.0 60544\&.0 13820\&.0 13820\&.0 194 81 2\&.938 3\&.863\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-.SS MONITOR\ INSTRUMENTATION\ FOR\ A\ REMOTE\ JVM
+-This example attaches to lvmid 40496 on the system named remote\&.domain using the \f3-gcutil\fR option, with samples taken every second indefinitely\&.
++This example attaches to lvmid 21891 and takes 3 samples at 250 millisecond intervals\&. The
++\fB\-t\fR
++option is used to generate a time stamp for each sample in the first column\&.
+ .PP
+-The lvmid is combined with the name of the remote host to construct a \fIvmid\fR of \f340496@remote\&.domain\fR\&. This vmid results in the use of the \f3rmi\fR protocol to communicate to the default \f3jstatd\fR server on the remote host\&. The \f3jstatd\fR server is located using the rmiregistry on \f3remote\&.domain\fR that is bound to the default rmiregistry port (port 1099)\&.
+-.sp
+-.nf
+-\f3jstat \-gcutil 40496@remote\&.domain 1000\fP
+-.fi
+-.nf
+-\f3\fI\&.\&.\&. output omitted\fR\fP
+-.fi
+-.nf
+-\f3\fP
+-.fi
+-.sp
+-.SH SEE\ ALSO
+-.TP 0.2i
+-\(bu
++The Timestamp column reports the elapsed time in seconds since the start of the target JVM\&. In addition, the
++\fB\-gcoldcapacity\fR
++output shows the old generation capacity (OGC) and the old space capacity (OC) increasing as the heap expands to meet allocation or promotion demands\&. The old generation capacity (OGC) has grown from 11,696 kB to 13,820 kB after the eighty\-first full garbage collection (FGC)\&. The maximum capacity of the generation (and space) is 60,544 kB (OGCMX), so it still has room to expand\&.
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBTimestamp OGCMN OGCMX OGC OC YGC FGC FGCT GCT\fR
++\fB 150\&.1 1408\&.0 60544\&.0 11696\&.0 11696\&.0 194 80 2\&.874 3\&.799\fR
++\fB 150\&.4 1408\&.0 60544\&.0 13820\&.0 13820\&.0 194 81 2\&.938 3\&.863\fR
++\fB 150\&.7 1408\&.0 60544\&.0 13820\&.0 13820\&.0 194 81 2\&.938 3\&.863\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.SS "Monitor Instrumentation for a Remote JVM"
++.PP
++This example attaches to lvmid 40496 on the system named remote\&.domain using the
++\fB\-gcutil\fR
++option, with samples taken every second indefinitely\&.
++.PP
++The lvmid is combined with the name of the remote host to construct a
++\fIvmid\fR
++of
++\fB40496@remote\&.domain\fR\&. This vmid results in the use of the
++\fBrmi\fR
++protocol to communicate to the default
++\fBjstatd\fR
++server on the remote host\&. The
++\fBjstatd\fR
++server is located using the
++\fBrmiregistry\fR
++command on
++\fBremote\&.domain\fR
++that is bound to the default port of the
++\fBrmiregistry\fR
++command (port 1099)\&.
++.sp
++.if n \{\
++.RS 4
++.\}
++.nf
++\fBjstat \-gcutil 40496@remote\&.domain 1000\fR
++\fB\fI\&.\&.\&. output omitted\fR\fR
++
++.fi
++.if n \{\
++.RE
++.\}
++.SH "SEE ALSO"
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
+ java(1)
+-.TP 0.2i
+-\(bu
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
+ jps(1)
+-.TP 0.2i
+-\(bu
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
+ jstatd(1)
+-.TP 0.2i
+-\(bu
++.RE
++.sp
++.RS 4
++.ie n \{\
++\h'-04'\(bu\h'+03'\c
++.\}
++.el \{\
++.sp -1
++.IP \(bu 2.3
++.\}
+ rmiregistry(1)
+-.RE
+-.br
+-'pl 8.5i
+-'bp
++.RE
++.br
++'pl 8.5i
++'bp
+--- ./jdk/src/solaris/doc/sun/man/man1/keytool.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/keytool.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ '\" t
+-.\" Copyright (c) 1998, 2013, 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.
+ .\"
+@@ -23,12 +23,12 @@
+ .\"
+ .\" Arch: generic
+ .\" Software: JDK 8
+-.\" Date: 6 August 2013
++.\" Date: 03 March 2015
+ .\" SectDesc: Security Tools
+ .\" Title: keytool.1
+ .\"
+ .if n .pl 99999
+-.TH keytool 1 "6 August 2013" "JDK 8" "Security Tools"
++.TH keytool 1 "03 March 2015" "JDK 8" "Security Tools"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -185,10 +185,16 @@
+ .TP 0.2i
+ \(bu
+ Items in italics (option values) represent the actual values that must be supplied\&. For example, here is the format of the \f3-printcert\fR command:
++.sp
++.nf
++\f3keytool \-printcert {\-file \fIcert_file\fR} {\-v}\fP
++.fi
++.sp
+
+-\f3keytool -printcert {-file cert_file} {-v}\fR
+
+-When you specify a \f3-printcert\fR command, replace \f3cert_file\fR with the actual file name, as follows: \f3keytool -printcert -file VScert\&.cer\fR
++
++
++When you specify a \f3-printcert\fR command, replace \fIcert_file\fR with the actual file name, as follows: \f3keytool -printcert -file VScert\&.cer\fR
+ .TP 0.2i
+ \(bu
+ Option values must be put in quotation marks when they contain a blank (space)\&.
+@@ -385,10 +391,39 @@
+ .PP
+ \fINote:\fR Users should be aware that some combinations of extensions (and other certificate fields) may not conform to the Internet standard\&. See Certificate Conformance Warning\&.
+ .SH COMMANDS
+-.TP
++.TP
+ -gencert
+-.br
+-\f3{-rfc} {-infile infile} {-outfile outfile} {-alias alias} {-sigalg sigalg} {-dname dname} {-startdate startdate {-ext ext}* {-validity valDays} [-keypass keypass] {-keystore keystore} [-storepass storepass] {-storetype storetype} {-providername provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-rfc} {\-infile \fIinfile\fR} {\-outfile \fIoutfile\fR} {\-alias \fIalias\fR} {\-sigalg \fIsigalg\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-dname \fIdname\fR} {\-startdate \fIstartdate\fR {\-ext \fIext\fR}* {\-validity \fIvalDays\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-keypass \fIkeypass\fR] {\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-storetype \fIstoretype\fR} {\-providername \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Generates a certificate as a response to a certificate request file (which can be created by the \f3keytool\fR\f3-certreq\fR command)\&. The command reads the request from \fIinfile\fR (if omitted, from the standard input), signs it using alias\&'s private key, and outputs the X\&.509 certificate into \fIoutfile\fR (if omitted, to the standard output)\&. When\f3-rfc\fR is specified, the output format is Base64-encoded PEM; otherwise, a binary DER is created\&.
+
+@@ -459,10 +494,39 @@
+ .fi
+ .sp
+
+-.TP
++.TP
+ -genkeypair
+-.br
+-\f3{-alias alias} {-keyalg keyalg} {-keysize keysize} {-sigalg sigalg} [-dname dname] [-keypass keypass] {-startdate value} {-ext ext}* {-validity valDays} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-keyalg \fIkeyalg\fR} {\-keysize \fIkeysize\fR} {\-sigalg \fIsigalg\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-dname \fIdname\fR] [\-keypass \fIkeypass\fR] {\-startdate \fIvalue\fR} {\-ext \fIext\fR}*\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-validity \fIvalDays\fR} {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Generates a key pair (a public key and associated private key)\&. Wraps the public key into an X\&.509 v3 self-signed certificate, which is stored as a single-element certificate chain\&. This certificate chain and the private key are stored in a new keystore entry identified by alias\&.
+
+@@ -510,18 +574,61 @@
+ The value of \f3valDays\fR specifies the number of days (starting at the date specified by \f3-startdate\fR, or the current date when \f3-startdate\fR is not specified) for which the certificate should be considered valid\&.
+
+ This command was named \f3-genkey\fR in earlier releases\&. The old name is still supported in this release\&. The new name, \f3-genkeypair\fR, is preferred going forward\&.
+-.TP
++.TP
+ -genseckey
+-.br
+-\f3-genseckey {-alias alias} {-keyalg keyalg} {-keysize keysize} [-keypass keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-keyalg \fIkeyalg\fR} {\-keysize \fIkeysize\fR} [\-keypass \fIkeypass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}} {\-v}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Generates a secret key and stores it in a new \f3KeyStore\&.SecretKeyEntry\fR identified by \f3alias\fR\&.
+
+ The value of \f3keyalg\fR specifies the algorithm to be used to generate the secret key, and the value of \f3keysize\fR specifies the size of the key to be generated\&. The \f3keypass\fR value is a password that protects the secret key\&. If no password is provided, then the user is prompted for it\&. If you press the Return key at the prompt, then the key password is set to the same password that is used for the \f3keystore\fR\&. The \f3keypass\fR value must be at least 6 characters\&.
+-.TP
++.TP
+ -importcert
+-.br
+-\f3-importcert {-alias alias} {-file cert_file} [-keypass keypass] {-noprompt} {-trustcacerts} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-file \fIcert_file\fR} [\-keypass \fIkeypass\fR] {\-noprompt} {\-trustcacerts}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Reads the certificate or certificate chain (where the latter is supplied in a PKCS#7 formatted reply or a sequence of X\&.509 certificates) from the file \f3cert_file\fR, and stores it in the \f3keystore\fR entry identified by \f3alias\fR\&. If no file is specified, then the certificate or certificate chain is read from \f3stdin\fR\&.
+
+@@ -530,16 +637,74 @@
+ You import a certificate for two reasons: To add it to the list of trusted certificates, and to import a certificate reply received from a certificate authority (CA) as the result of submitting a Certificate Signing Request to that CA (see the \f3-certreq\fR option in Commands)\&.
+
+ Which type of import is intended is indicated by the value of the \f3-alias\fR option\&. If the alias does not point to a key entry, then the \f3keytool\fR command assumes you are adding a trusted certificate entry\&. In this case, the alias should not already exist in the keystore\&. If the alias does already exist, then the \f3keytool\fR command outputs an error because there is already a trusted certificate for that alias, and does not import the certificate\&. If the alias points to a key entry, then the \f3keytool\fR command assumes you are importing a certificate reply\&.
+-.TP
++.TP
+ -importpassword
+-.br
+-\f3{-alias alias} [-keypass keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} [\-keypass \fIkeypass\fR] {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Imports a passphrase and stores it in a new \f3KeyStore\&.SecretKeyEntry\fR identified by \f3alias\fR\&. The passphrase may be supplied via the standard input stream; otherwise the user is prompted for it\&. \f3keypass\fR is a password used to protect the imported passphrase\&. If no password is provided, the user is prompted for it\&. If you press the Return key at the prompt, the key password is set to the same password as that used for the \f3keystore\fR\&. \f3keypass\fR must be at least 6 characters long\&.
+-.TP
++.TP
+ -importkeystore
+-.br
+-\f3{-srcstoretype srcstoretype} {-deststoretype deststoretype} [-srcstorepass srcstorepass] [-deststorepass deststorepass] {-srcprotected} {-destprotected} {-srcalias srcalias {-destalias destalias} [-srckeypass srckeypass] } [-destkeypass destkeypass] {-noprompt} {-srcProviderName src_provider_name} {-destProviderName dest_provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-srcstoretype \fIsrcstoretype\fR} {\-deststoretype \fIdeststoretype\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-srcstorepass \fIsrcstorepass\fR] [\-deststorepass \fIdeststorepass\fR] {\-srcprotected}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-destprotected} \fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-srcalias \fIsrcalias\fR {\-destalias \fIdestalias\fR} [\-srckeypass \fIsrckeypass\fR]} \fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-destkeypass \fIdestkeypass\fR] {\-noprompt}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-srcProviderName \fIsrc_provider_name\fR} {\-destProviderName \fIdest_provider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}} {\-v}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Imports a single entry or all entries from a source keystore to a destination keystore\&.
+
+@@ -550,16 +715,44 @@
+ If the destination alias already exists in the destination keystore, then the user is prompted to either overwrite the entry or to create a new entry under a different alias name\&.
+
+ If the \f3-noprompt\fR option is provided, then the user is not prompted for a new destination alias\&. Existing entries are overwritten with the destination alias name\&. Entries that cannot be imported are skipped and a warning is displayed\&.
+-.TP
++.TP
+ -printcertreq
+-.br
+-\f3{-file file}\fR
++.sp
++.nf
++\f3{\-file \fIfile\fR}\fP
++.fi
++.sp
++
+
+ Prints the content of a PKCS #10 format certificate request, which can be generated by the \f3keytool\fR\f3-certreq\fR command\&. The command reads the request from file\&. If there is no file, then the request is read from the standard input\&.
+-.TP
++.TP
+ -certreq
+-.br
+-\f3{-alias alias} {-dname dname} {-sigalg sigalg} {-file certreq_file} [-keypass keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-dname \fIdname\fR} {\-sigalg \fIsigalg\fR} {\-file \fIcertreq_file\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-keypass \fIkeypass\fR] {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-storepass \fIstorepass\fR] {\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Generates a Certificate Signing Request (CSR) using the PKCS #10 format\&.
+
+@@ -572,10 +765,29 @@
+ The CSR is stored in the file certreq_file\&. If no file is specified, then the CSR is output to \f3stdout\fR\&.
+
+ Use the \f3importcert\fR command to import the response from the CA\&.
+-.TP
++.TP
+ -exportcert
+-.br
+-\f3{-alias alias} {-file cert_file} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-rfc} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-file \fIcert_file\fR} {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-storepass \fIstorepass\fR] {\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-rfc} {\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Reads from the keystore the certificate associated with \fIalias\fR and stores it in the cert_file file\&. When no file is specified, the certificate is output to \f3stdout\fR\&.
+
+@@ -584,20 +796,48 @@
+ If \f3alias\fR refers to a trusted certificate, then that certificate is output\&. Otherwise, \f3alias\fR refers to a key entry with an associated certificate chain\&. In that case, the first certificate in the chain is returned\&. This certificate authenticates the public key of the entity addressed by \f3alias\fR\&.
+
+ This command was named \f3-export\fR in earlier releases\&. The old name is still supported in this release\&. The new name, \f3-exportcert\fR, is preferred going forward\&.
+-.TP
++.TP
+ -list
+-.br
+-\f3{-alias alias} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v | -rfc} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v | \-rfc} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Prints to \f3stdout\fR the contents of the keystore entry identified by \f3alias\fR\&. If no \f3alias\fR is specified, then the contents of the entire keystore are printed\&.
+
+ This command by default prints the SHA1 fingerprint of a certificate\&. If the \f3-v\fR option is specified, then the certificate is printed in human-readable format, with additional information such as the owner, issuer, serial number, and any extensions\&. If the \f3-rfc\fR option is specified, then the certificate contents are printed using the printable encoding format, as defined by the Internet RFC 1421 Certificate Encoding Standard\&.
+
+ You cannot specify both \f3-v\fR and \f3-rfc\fR\&.
+-.TP
++.TP
+ -printcert
+-.br
+-\f3{-file cert_file | -sslserver host[:port]} {-jarfile JAR_file {-rfc} {-v} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-file \fIcert_file\fR | \-sslserver \fIhost\fR[:\fIport\fR]} {\-jarfile \fIJAR_file\fR {\-rfc} {\-v}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Reads the certificate from the file cert_file, the SSL server located at host:port, or the signed JAR file \f3JAR_file\fR (with the \f3-jarfile\fR option and prints its contents in a human-readable format\&. When no port is specified, the standard HTTPS port 443 is assumed\&. Note that \f3-sslserver\fR and -file options cannot be provided at the same time\&. Otherwise, an error is reported\&. If neither option is specified, then the certificate is read from \f3stdin\fR\&.
+
+@@ -608,40 +848,120 @@
+ If the SSL server is behind a firewall, then the \f3-J-Dhttps\&.proxyHost=proxyhost\fR and \f3-J-Dhttps\&.proxyPort=proxyport\fR options can be specified on the command line for proxy tunneling\&. See Java Secure Socket Extension (JSSE) Reference Guide at http://docs\&.oracle\&.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide\&.html
+
+ \fINote:\fR This option can be used independently of a keystore\&.
+-.TP
++.TP
+ -printcrl
+-.br
+-\f3-file crl_ {-v}\fR
++.sp
++.nf
++\f3\-file \fIcrl_\fR {\-v}\fP
++.fi
++.sp
++
+
+ Reads the Certificate Revocation List (CRL) from the file \f3crl_\fR\&. A CRL is a list of digital certificates that were revoked by the CA that issued them\&. The CA generates the \f3crl_\fR file\&.
+
+ \fINote:\fR This option can be used independently of a keystore\&.
+-.TP
++.TP
+ -storepasswd
+-.br
+-\f3[-new new_storepass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-Jjavaoption}\fR
++.sp
++.nf
++\f3[\-new \fInew_storepass\fR] {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3[\-storepass \fIstorepass\fR] {\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Changes the password used to protect the integrity of the keystore contents\&. The new password is \f3new_storepass\fR, which must be at least 6 characters\&.
+-.TP
++.TP
+ -keypasswd
+-.br
+-\f3{-alias alias} [-keypass old_keypass] [-new new_keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} [\-keypass \fIold_keypass\fR] [\-new \fInew_keypass\fR] {\-storetype \fIstoretype\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR] {\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}} {\-v}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Changes the password under which the private/secret key identified by \f3alias\fR is protected, from \f3old_keypass\fR to \f3new_keypass\fR, which must be at least 6 characters\&.
+
+ If the \f3-keypass\fR option is not provided at the command line, and the key password is different from the keystore password, then the user is prompted for it\&.
+
+ If the \f3-new\fR option is not provided at the command line, then the user is prompted for it
+-.TP
++.TP
+ -delete
+-.br
+-\f3[-alias alias] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3[\-alias \fIalias\fR] {\-storetype \fIstoretype\fR} {\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR]\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerName \fIprovider_name\fR} \fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-v} {\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Deletes from the keystore the entry identified by \f3alias\fR\&. The user is prompted for the alias, when no alias is provided at the command line\&.
+-.TP
++.TP
+ -changealias
+-.br
+-\f3{-alias alias} [-destalias destalias] [-keypass keypass] {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}\fR
++.sp
++.nf
++\f3{\-alias \fIalias\fR} [\-destalias \fIdestalias\fR] [\-keypass \fIkeypass\fR] {\-storetype \fIstoretype\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-keystore \fIkeystore\fR} [\-storepass \fIstorepass\fR] {\-providerName \fIprovider_name\fR}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-providerClass \fIprovider_class_name\fR {\-providerArg \fIprovider_arg\fR}} {\-v}\fP
++.fi
++.sp
++.sp
++.nf
++\f3{\-protected} {\-Jjavaoption}\fP
++.fi
++.sp
++
+
+ Move an existing keystore entry from the specified \f3alias\fR to a new alias, \f3destalias\fR\&. If no destination alias is provided, then the command prompts for one\&. If the original entry is protected with an entry password, then the password can be supplied with the \f3-keypass\fR option\&. If no key password is provided, then the \f3storepass\fR (if provided) is attempted first\&. If the attempt fails, then the user is prompted for a password\&.
+ .TP
+--- ./jdk/src/solaris/doc/sun/man/man1/policytool.1 Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/doc/sun/man/man1/policytool.1 Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ '\" t
+-.\" Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
++.\" Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ .\"
+ .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ .\"
+@@ -23,12 +23,12 @@
+ .\"
+ .\" Arch: generic
+ .\" Software: JDK 8
+-.\" Date: 21 November 2013
++.\" Date: 03 March 2015
+ .\" SectDesc: Security Tools
+ .\" Title: policytool.1
+ .\"
+ .if n .pl 99999
+-.TH policytool 1 "21 November 2013" "JDK 8" "Security Tools"
++.TH policytool 1 "03 March 2015" "JDK 8" "Security Tools"
+ .\" -----------------------------------------------------------------
+ .\" * Define some portability stuff
+ .\" -----------------------------------------------------------------
+@@ -80,7 +80,7 @@
+ Run the \f3policytool\fR command and load the specified file:
+ .sp
+ .nf
+-\f3policytool\-file mypolicyfile\fP
++\f3policytool \-file \fImypolicyfile\fR\fP
+ .fi
+ .nf
+ \f3\fP
+--- ./jdk/src/solaris/native/java/io/FileOutputStream_md.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/java/io/FileOutputStream_md.c Wed Feb 04 12:14:43 2015 -0800
+@@ -53,8 +53,8 @@
+ */
+
+ JNIEXPORT void JNICALL
+-Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this,
+- jstring path, jboolean append) {
++Java_java_io_FileOutputStream_open0(JNIEnv *env, jobject this,
++ jstring path, jboolean append) {
+ fileOpen(env, this, path, fos_fd,
+ O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC));
+ }
+--- ./jdk/src/solaris/native/java/lang/UNIXProcess_md.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/java/lang/UNIXProcess_md.c Wed Feb 04 12:14:43 2015 -0800
+@@ -598,9 +598,9 @@
+ */
+ assert(prog != NULL && argBlock != NULL);
+ if ((phelperpath = getBytes(env, helperpath)) == NULL) goto Catch;
+- if ((pprog = getBytes(env, prog)) == NULL) goto Catch;
+- if ((pargBlock = getBytes(env, argBlock)) == NULL) goto Catch;
+- if ((c->argv = NEW(const char *, argc + 3)) == NULL) goto Catch;
++ if ((pprog = getBytes(env, prog)) == NULL) goto Catch;
++ if ((pargBlock = getBytes(env, argBlock)) == NULL) goto Catch;
++ if ((c->argv = NEW(const char *, argc + 3)) == NULL) goto Catch;
+ c->argv[0] = pprog;
+ c->argc = argc + 2;
+ initVectorFromBlock(c->argv+1, pargBlock, argc);
+@@ -689,10 +689,11 @@
+ closeSafely(childenv[0]);
+ closeSafely(childenv[1]);
+
+- releaseBytes(env, prog, pprog);
+- releaseBytes(env, argBlock, pargBlock);
+- releaseBytes(env, envBlock, penvBlock);
+- releaseBytes(env, dir, c->pdir);
++ releaseBytes(env, helperpath, phelperpath);
++ releaseBytes(env, prog, pprog);
++ releaseBytes(env, argBlock, pargBlock);
++ releaseBytes(env, envBlock, penvBlock);
++ releaseBytes(env, dir, c->pdir);
+
+ free(c->argv);
+ free(c->envv);
+--- ./jdk/src/solaris/native/java/lang/locale_str.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/java/lang/locale_str.h Wed Feb 04 12:14:43 2015 -0800
+@@ -135,7 +135,7 @@
+ "sr_SP", "sr_YU",
+ "tchinese", "zh_TW",
+ #endif
+- ""
++ "", "",
+ };
+
+ /*
+@@ -188,7 +188,7 @@
+ "japanese", "ja",
+ "korean", "ko",
+ #endif
+- "",
++ "", "",
+ };
+
+ /*
+@@ -201,7 +201,7 @@
+ "iqtelif", "Latn",
+ "latin", "Latn",
+ #endif
+- "",
++ "", "",
+ };
+
+ /*
+@@ -212,7 +212,7 @@
+ "RN", "US", // used on Linux, not clear what it stands for
+ #endif
+ "YU", "CS", // YU has been removed from ISO 3166
+- "",
++ "", "",
+ };
+
+ /*
+@@ -220,5 +220,5 @@
+ */
+ static char *variant_names[] = {
+ "nynorsk", "NY",
+- "",
++ "", "",
+ };
+--- ./jdk/src/solaris/native/java/net/net_util_md.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/java/net/net_util_md.c Wed Feb 04 12:14:43 2015 -0800
+@@ -1310,7 +1310,7 @@
+ * or sending UDP packet.
+ * 2. IPv6 on Linux: By default Linux ignores flowinfo
+ * field so enable IPV6_FLOWINFO_SEND so that flowinfo
+- * will be examined.
++ * will be examined. We also set the IPv4 TOS option in this case.
+ * 3. IPv4: set socket option based on ToS and Precedence
+ * fields (otherwise get invalid argument)
+ */
+@@ -1326,8 +1326,10 @@
+ #if defined(AF_INET6) && defined(__linux__)
+ if (ipv6_available()) {
+ int optval = 1;
+- return setsockopt(fd, IPPROTO_IPV6, IPV6_FLOWINFO_SEND,
+- (void *)&optval, sizeof(optval));
++ if (setsockopt(fd, IPPROTO_IPV6, IPV6_FLOWINFO_SEND,
++ (void *)&optval, sizeof(optval)) < 0) {
++ return -1;
++ }
+ }
+ #endif
+
+--- ./jdk/src/solaris/native/java/util/TimeZone_md.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/java/util/TimeZone_md.c Wed Feb 04 12:14:43 2015 -0800
+@@ -652,11 +652,11 @@
+ * using <java_home>/lib/tzmappings. If the TZ value is not found, it
+ * trys some libc implementation dependent mappings. If it still
+ * can't map to a Java time zone ID, it falls back to the GMT+/-hh:mm
+- * form. `country', which can be null, is not used for UNIX platforms.
++ * form.
+ */
+ /*ARGSUSED1*/
+ char *
+-findJavaTZ_md(const char *java_home_dir, const char *country)
++findJavaTZ_md(const char *java_home_dir)
+ {
+ char *tz;
+ char *javatz = NULL;
+--- ./jdk/src/solaris/native/java/util/TimeZone_md.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/java/util/TimeZone_md.h Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -26,7 +26,7 @@
+ #ifndef _TIMEZONE_MD_H
+ #define _TIMEZONE_MD_H
+
+-char *findJavaTZ_md(const char *java_home_dir, const char *region);
++char *findJavaTZ_md(const char *java_home_dir);
+ char *getGMTOffsetID();
+
+ #endif
+--- ./jdk/src/solaris/native/sun/awt/CUPSfuncs.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/awt/CUPSfuncs.c Wed Feb 04 12:14:43 2015 -0800
+@@ -349,7 +349,8 @@
+ // create array of dimensions - (num_choices * 6)
+ //to cover length & height
+ DPRINTF( "CUPSfuncs::option->num_choices %d\n", option->num_choices)
+- sizeArray = (*env)->NewFloatArray(env, option->num_choices*6);
++ // +1 is for storing the default media index
++ sizeArray = (*env)->NewFloatArray(env, option->num_choices*6+1);
+ if (sizeArray == NULL) {
+ unlink(filename);
+ j2d_ppdClose(ppd);
+@@ -369,6 +370,10 @@
+ }
+ for (i = 0; i<option->num_choices; i++) {
+ choice = (option->choices)+i;
++ // get the index of the default page
++ if (!strcmp(choice->choice, option->defchoice)) {
++ dims[option->num_choices*6] = (float)i;
++ }
+ size = j2d_ppdPageSize(ppd, choice->choice);
+ if (size != NULL) {
+ // paper width and height
+--- ./jdk/src/solaris/native/sun/awt/X11Color.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/awt/X11Color.c Wed Feb 04 12:14:43 2015 -0800
+@@ -1377,7 +1377,7 @@
+
+ /* Unlock now to initialize the SystemColor class */
+ if (lock) {
+- AWT_UNLOCK ();
++ AWT_UNLOCK_CHECK_EXCEPTION(env);
+ }
+ sysColors = (*env)->FindClass (env, "java/awt/SystemColor");
+ CHECK_NULL(sysColors);
+--- ./jdk/src/solaris/native/sun/awt/awt.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/awt/awt.h Wed Feb 04 12:14:43 2015 -0800
+@@ -34,9 +34,9 @@
+ #include "jni_util.h"
+ #include "debug_util.h"
+
+-#ifndef HEADLESS
++#if !defined(HEADLESS) && !defined(MACOSX)
+ #include <X11/Intrinsic.h>
+-#endif /* !HEADLESS */
++#endif /* !HEADLESS && !MACOSX */
+
+
+ /* The JVM instance: defined in awt_MToolkit.c */
+@@ -75,6 +75,12 @@
+ AWT_NOFLUSH_UNLOCK(); \
+ } while (0)
+
++#define AWT_UNLOCK_CHECK_EXCEPTION(env) \
++ do { \
++ AWT_UNLOCK(); \
++ JNU_CHECK_EXCEPTION(env); \
++ } while (0)
++
+ #define AWT_LOCK_IMPL() \
+ (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID)
+
+@@ -110,9 +116,9 @@
+ #define AWT_NOTIFY() AWT_NOTIFY_IMPL()
+ #define AWT_NOTIFY_ALL() AWT_NOTIFY_ALL_IMPL()
+
+-#ifndef HEADLESS
++#if !defined(HEADLESS) && !defined(MACOSX)
+ extern Display *awt_display; /* awt_GraphicsEnv.c */
+ extern Boolean awt_ModLockIsShiftLock; /* XToolkit.c */
+-#endif /* !HEADLESS */
++#endif /* !HEADLESS && !MACOSX */
+
+ #endif /* ! _AWT_ */
+--- ./jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c Wed Feb 04 12:14:43 2015 -0800
+@@ -1348,7 +1348,9 @@
+ }
+
+ /* Make Color Model object for this GraphicsConfiguration */
+- colorModel = awtJNI_GetColorModel (env, adata);
++ colorModel = (*env)->ExceptionCheck(env)
++ ? NULL : awtJNI_GetColorModel (env, adata);
++
+ AWT_UNLOCK ();
+
+ return colorModel;
+@@ -2052,7 +2054,7 @@
+
+ AWT_FLUSH_UNLOCK();
+
+- if (!success) {
++ if (!success && !(*env)->ExceptionCheck(env)) {
+ JNU_ThrowInternalError(env, "Could not set display mode");
+ }
+ #endif /* !HEADLESS */
+--- ./jdk/src/solaris/native/sun/awt/awt_LoadLibrary.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/awt/awt_LoadLibrary.c Wed Feb 04 12:14:43 2015 -0800
+@@ -35,8 +35,6 @@
+ #include <sys/param.h>
+ #include <sys/utsname.h>
+
+-#include "awt_Plugin.h"
+-
+ #ifdef AIX
+ #include "porting_aix.h" /* For the 'dladdr' function. */
+ #endif
+@@ -236,55 +234,3 @@
+
+ (*XsessionWMcommand)(env, jargv);
+ }
+-
+-
+-#define REFLECT_VOID_FUNCTION(name, arglist, paramlist) \
+-typedef name##_type arglist; \
+-void name arglist \
+-{ \
+- static name##_type *name##_ptr = NULL; \
+- if (name##_ptr == NULL && awtHandle == NULL) { \
+- return; \
+- } \
+- name##_ptr = (name##_type *) \
+- dlsym(awtHandle, #name); \
+- if (name##_ptr == NULL) { \
+- return; \
+- } \
+- (*name##_ptr)paramlist; \
+-}
+-
+-#define REFLECT_FUNCTION(return_type, name, arglist, paramlist) \
+-typedef return_type name##_type arglist; \
+-return_type name arglist \
+-{ \
+- static name##_type *name##_ptr = NULL; \
+- if (name##_ptr == NULL && awtHandle == NULL) { \
+- return NULL; \
+- } \
+- name##_ptr = (name##_type *) \
+- dlsym(awtHandle, #name); \
+- if (name##_ptr == NULL) { \
+- return NULL; \
+- } \
+- return (*name##_ptr)paramlist; \
+-}
+-
+-
+-/*
+- * These entry point must remain in libawt.so ***for Java Plugin ONLY***
+- * Reflect this call over to the correct libawt_<toolkit>.so.
+- */
+-
+-REFLECT_VOID_FUNCTION(getAwtLockFunctions,
+- (void (**AwtLock)(JNIEnv *), void (**AwtUnlock)(JNIEnv *),
+- void (**AwtNoFlushUnlock)(JNIEnv *), void *reserved),
+- (AwtLock, AwtUnlock, AwtNoFlushUnlock, reserved))
+-
+-REFLECT_VOID_FUNCTION(getAwtData,
+- (int32_t *awt_depth, Colormap *awt_cmap, Visual **awt_visual,
+- int32_t *awt_num_colors, void *pReserved),
+- (awt_depth, awt_cmap, awt_visual,
+- awt_num_colors, pReserved))
+-
+-REFLECT_FUNCTION(Display *, getAwtDisplay, (void), ())
+--- ./jdk/src/solaris/native/sun/awt/awt_Plugin.c Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,149 +0,0 @@
+-/*
+- * Copyright (c) 1999, 2001, 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.
+- */
+-
+-#ifdef HEADLESS
+- #error This file should not be included in headless library
+-#endif
+-
+-#include <jni.h>
+-#include <X11/Xlib.h>
+-#include <X11/Xutil.h>
+-#include <awt.h>
+-#include <awt_p.h>
+-
+-/*
+- * Fix 4221246: Provide utility function for Netscape to use to
+- * get AWT display, depth, colormap, and number of colors.
+- *
+- */
+-
+-Display *getAwtDisplay(void)
+-{
+- return awt_display;
+-}
+-
+-void getExtAwtData(Display *display,
+- int32_t screen,
+- int32_t *awt_depth,
+- Colormap *awt_cmap,
+- Visual **awt_visual,
+- int32_t *awt_num_colors,
+- void *pReserved)
+-{
+- AwtGraphicsConfigDataPtr defaultConfig = NULL;
+-
+-#ifdef DEBUG
+- if (pReserved != NULL) {
+- jio_fprintf(stderr,
+- "getExtAwtData: warning: reserved pointer is not null\n");
+- }
+-#endif
+-
+- if (screen >= 0) {
+- defaultConfig = getDefaultConfig(screen);
+- }
+-
+- if (defaultConfig) {
+- if (awt_depth != NULL) {
+- *awt_depth = defaultConfig->awt_depth;
+- }
+-
+- if (awt_cmap != NULL) {
+- *awt_cmap = defaultConfig->awt_cmap;
+- }
+-
+- if (awt_visual != NULL) {
+- *awt_visual = defaultConfig->awt_visInfo.visual;
+- }
+-
+- if (awt_num_colors != NULL) {
+- *awt_num_colors = defaultConfig->awt_num_colors;
+- }
+- }
+-}
+-
+-/*
+- * getAwtData provided for compatibility with Solaris 1.2 Java Plug-in
+- *
+- */
+-void getAwtData(int32_t *awt_depth,
+- Colormap *awt_cmap,
+- Visual **awt_visual,
+- int32_t *awt_num_colors,
+- void *pReserved)
+-{
+- Display *display = getAwtDisplay();
+-
+- getExtAwtData(display,
+- DefaultScreen(display),
+- awt_depth,
+- awt_cmap,
+- awt_visual,
+- awt_num_colors,
+- pReserved);
+-}
+-
+-/*
+- * Fix 4221246: Provide utility funtion for Netscape to get
+- * function pointers to AWT lock functions.
+- *
+- */
+-
+-static void awt_lock_wrapper(JNIEnv *env) {
+- AWT_LOCK();
+-}
+-
+-static void awt_unlock_wrapper(JNIEnv *env) {
+- AWT_UNLOCK();
+-}
+-
+-static void awt_noflush_unlock_wrapper(JNIEnv *env) {
+- AWT_NOFLUSH_UNLOCK();
+-}
+-
+-void getAwtLockFunctions(void (**AwtLock)(JNIEnv *),
+- void (**AwtUnlock)(JNIEnv *),
+- void (**AwtNoFlushUnlock)(JNIEnv *),
+- void *pReserved)
+-{
+-#ifdef DEBUG
+- if (pReserved != NULL) {
+- jio_fprintf(stderr,
+- "getAwtLockFunctions: warning: reserved pointer is not null\n");
+- }
+-#endif
+-
+- if (AwtLock != NULL) {
+- *AwtLock = awt_lock_wrapper;
+- }
+-
+- if (AwtUnlock != NULL) {
+- *AwtUnlock = awt_unlock_wrapper;
+- }
+-
+- if (AwtNoFlushUnlock != NULL) {
+- *AwtNoFlushUnlock = awt_noflush_unlock_wrapper;
+- }
+-}
+--- ./jdk/src/solaris/native/sun/awt/awt_Plugin.h Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,54 +0,0 @@
+-/*
+- * Copyright (c) 1999, 2001, 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.
+- */
+-
+-/*
+- * Fix 4221246: Export functions for Netscape to use to get AWT info
+- */
+-
+-#ifndef _AWT_PLUGIN_H_
+-#define _AWT_PLUGIN_H_
+-
+-#include <jni.h>
+-#include <X11/Xlib.h>
+-#include <X11/Xutil.h>
+-
+-void getAwtLockFunctions(void (**AwtLock)(JNIEnv *),
+- void (**AwtUnlock)(JNIEnv *),
+- void (**AwtNoFlushUnlock)(JNIEnv *),
+- void *);
+-
+-void getExtAwtData(Display *,
+- int32_t,
+- int32_t *, /* awt_depth */
+- Colormap *, /* awt_cmap */
+- Visual **, /* awt_visInfo.visual */
+- int32_t *, /* awt_num_colors */
+- void *);
+-
+-void getAwtData(int32_t *, Colormap *, Visual **, int32_t *, void *);
+-
+-Display *getAwtDisplay(void);
+-
+-#endif /* _AWT_PLUGIN_H_ */
+--- ./jdk/src/solaris/native/sun/awt/awt_util.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/awt/awt_util.h Wed Feb 04 12:14:43 2015 -0800
+@@ -52,6 +52,8 @@
+ */
+ extern XErrorHandler current_native_xerror_handler;
+
++Window get_xawt_root_shell(JNIEnv *env);
++
+ #endif /* !HEADLESS */
+
+ #ifndef INTERSECTS
+--- ./jdk/src/solaris/native/sun/awt/color.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/awt/color.h Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1995, 2001, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -28,13 +28,13 @@
+ #include "awt.h"
+ #include "colordata.h"
+
+-#ifndef HEADLESS
++#if !defined(HEADLESS) && !defined(MACOSX)
+ typedef struct {
+ unsigned int Depth;
+ XPixmapFormatValues wsImageFormat;
+ ImgColorData clrdata;
+ ImgConvertFcn *convert[NUM_IMGCV];
+ } awtImageData;
+-#endif /* !HEADLESS */
++#endif /* !HEADLESS && !MACOSX */
+
+ #endif /* _COLOR_H_ */
+--- ./jdk/src/solaris/native/sun/awt/gtk2_interface.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/awt/gtk2_interface.c Wed Feb 04 12:14:43 2015 -0800
+@@ -783,6 +783,8 @@
+ fp_gtk_widget_show = dl_symbol("gtk_widget_show");
+ fp_gtk_main = dl_symbol("gtk_main");
+
++ fp_g_path_get_dirname = dl_symbol("g_path_get_dirname");
++
+ /**
+ * GLib thread system
+ */
+--- ./jdk/src/solaris/native/sun/awt/gtk2_interface.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/awt/gtk2_interface.h Wed Feb 04 12:14:43 2015 -0800
+@@ -817,7 +817,7 @@
+ void (*fp_gtk_widget_show)(GtkWidget *widget);
+ void (*fp_gtk_main)(void);
+ guint (*fp_gtk_main_level)(void);
+-
++gchar* (*fp_g_path_get_dirname) (const gchar *file_name);
+
+ /**
+ * This function is available for GLIB > 2.20, so it MUST be
+--- ./jdk/src/solaris/native/sun/awt/img_util_md.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/awt/img_util_md.h Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2001, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -25,7 +25,7 @@
+
+ #include "color.h"
+
+-#ifndef HEADLESS
++#if !defined(HEADLESS) && !defined(MACOSX)
+ typedef struct {
+ ImgConvertData cvdata; /* The data needed by ImgConvertFcn's */
+ struct Hsun_awt_image_ImageRepresentation *hJavaObject; /* backptr */
+@@ -68,7 +68,7 @@
+ #define MaskScan(cvdata) \
+ ((((IRData *)cvdata)->maskim->bytes_per_line) >> 2)
+
+-#endif /* !HEADLESS */
++#endif /* !HEADLESS && !MACOSX */
+
+ #define MaskOffset(x) ((x) >> 5)
+
+--- ./jdk/src/solaris/native/sun/awt/splashscreen/splashscreen_sys.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/awt/splashscreen/splashscreen_sys.c Wed Feb 04 12:14:43 2015 -0800
+@@ -794,3 +794,11 @@
+ SplashReconfigure(Splash * splash) {
+ sendctl(splash, SPLASHCTL_RECONFIGURE);
+ }
++
++SPLASHEXPORT char*
++SplashGetScaledImageName(const char* jarName, const char* fileName,
++ float *scaleFactor)
++{
++ *scaleFactor = 1;
++ return NULL;
++}
+--- ./jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c Wed Feb 04 12:14:43 2015 -0800
+@@ -59,7 +59,6 @@
+ static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, gpointer obj)
+ {
+ JNIEnv *env;
+- jclass cx;
+ jstring filename;
+
+ env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
+@@ -158,62 +157,55 @@
+ fp_gdk_threads_leave();
+ }
+
++/*
++ * baseDir should be freed by user.
++ */
++static gboolean isFromSameDirectory(GSList* list, gchar** baseDir) {
++
++ GSList *it = list;
++ gchar* prevDir = NULL;
++ gboolean isAllDirsSame = TRUE;
++
++ while (it) {
++ gchar* dir = fp_g_path_get_dirname((gchar*) it->data);
++
++ if (prevDir && strcmp(prevDir, dir) != 0) {
++ isAllDirsSame = FALSE;
++ fp_g_free(dir);
++ break;
++ }
++
++ if (!prevDir) {
++ prevDir = strdup(dir);
++ }
++ fp_g_free(dir);
++
++ it = it->next;
++ }
++
++ if (isAllDirsSame) {
++ *baseDir = prevDir;
++ } else {
++ free(prevDir);
++ *baseDir = strdup("/");
++ }
++
++ return isAllDirsSame;
++}
++
+ /**
+- * Convert a GSList to an array of filenames (without the parent folder)
++ * Convert a GSList to an array of filenames
+ */
+-static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list)
++static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list, jstring* jcurrent_folder)
+ {
+ jstring str;
+ jclass stringCls;
+ GSList *iterator;
+ jobjectArray array;
+ int i;
+- char* entry;
+-
+- if (NULL == list) {
+- return NULL;
+- }
+-
+- stringCls = (*env)->FindClass(env, "java/lang/String");
+- if (stringCls == NULL) {
+- (*env)->ExceptionClear(env);
+- JNU_ThrowInternalError(env, "Could not get java.lang.String class");
+- return NULL;
+- }
+-
+- array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls, NULL);
+- if (array == NULL) {
+- (*env)->ExceptionClear(env);
+- JNU_ThrowInternalError(env, "Could not instantiate array files array");
+- return NULL;
+- }
+-
+- i = 0;
+- for (iterator = list; iterator; iterator = iterator->next) {
+- entry = (char*) iterator->data;
+- entry = strrchr(entry, '/') + 1;
+- str = (*env)->NewStringUTF(env, entry);
+- if (str && !(*env)->ExceptionCheck(env)) {
+- (*env)->SetObjectArrayElement(env, array, i, str);
+- }
+- i++;
+- }
+-
+- return array;
+-}
+-
+-/**
+- * Convert a GSList to an array of filenames (with the parent folder)
+- */
+-static jobjectArray toPathAndFilenamesArray(JNIEnv *env, GSList* list)
+-{
+- jstring str;
+- jclass stringCls;
+- GSList *iterator;
+- jobjectArray array;
+- int i;
+- char* entry;
+-
++ gchar* entry;
++ gchar * baseDir;
++ gboolean isFromSameDir;
+
+ if (list == NULL) {
+ return NULL;
+@@ -233,61 +225,63 @@
+ return NULL;
+ }
+
+- i = 0;
+- for (iterator = list; iterator; iterator = iterator->next) {
+- entry = (char*) iterator->data;
++ isFromSameDir = isFromSameDirectory(list, &baseDir);
+
+- //check for leading slash.
+- if (entry[0] == '/') {
++ *jcurrent_folder = (*env)->NewStringUTF(env, baseDir);
++ if (*jcurrent_folder == NULL) {
++ free(baseDir);
++ return NULL;
++ }
++
++ for (iterator = list, i=0;
++ iterator;
++ iterator = iterator->next, i++) {
++
++ entry = (gchar*) iterator->data;
++
++ if (isFromSameDir) {
++ entry = strrchr(entry, '/') + 1;
++ } else if (entry[0] == '/') {
+ entry++;
+ }
+
+ str = (*env)->NewStringUTF(env, entry);
+- if (str && !(*env)->ExceptionCheck(env)) {
++ if((*env)->ExceptionCheck(env)){
++ break;
++ }
++ if (str) {
+ (*env)->SetObjectArrayElement(env, array, i, str);
++ if((*env)->ExceptionCheck(env)){
++ break;
++ }
+ }
+- i++;
+ }
+
++ free(baseDir);
+ return array;
+ }
+
+ static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj)
+ {
+ JNIEnv *env;
+- char *current_folder;
+ GSList *filenames;
+- jclass cx;
+- jstring jcurrent_folder;
++ jstring jcurrent_folder = NULL;
+ jobjectArray jfilenames;
+
+ env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
+- current_folder = NULL;
+ filenames = NULL;
+- gboolean full_path_names = FALSE;
+
+ if (responseId == GTK_RESPONSE_ACCEPT) {
+- current_folder = fp_gtk_file_chooser_get_current_folder(
+- GTK_FILE_CHOOSER(aDialog));
+- if (current_folder == NULL) {
+- full_path_names = TRUE;
+- }
+ filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog));
+ }
+- if (full_path_names) {
+- //This is a hack for use with "Recent Folders" in gtk where each
+- //file could have its own directory.
+- jfilenames = toPathAndFilenamesArray(env, filenames);
+- jcurrent_folder = (*env)->NewStringUTF(env, "/");
+- } else {
+- jfilenames = toFilenamesArray(env, filenames);
+- jcurrent_folder = (*env)->NewStringUTF(env, current_folder);
+- }
++
++ jfilenames = toFilenamesArray(env, filenames, &jcurrent_folder);
++
+ if (!(*env)->ExceptionCheck(env)) {
+ (*env)->CallVoidMethod(env, obj, setFileInternalMethodID,
+ jcurrent_folder, jfilenames);
+ }
+- fp_g_free(current_folder);
++
+ quit(env, (jobject)obj, TRUE);
+ }
+
+--- ./jdk/src/solaris/native/sun/awt/utility/rect.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/awt/utility/rect.h Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2007, 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -28,8 +28,18 @@
+ #ifndef _AWT_RECT_H
+ #define _AWT_RECT_H
+
++#ifndef MACOSX
+ #include <X11/Xlib.h>
+ typedef XRectangle RECT_T;
++#else
++// OSX still needs this for BitmapToYXBandedRectangles
++typedef struct {
++ int x;
++ int y;
++ int width;
++ int height;
++} RECT_T;
++#endif /* !MACOSX */
+
+ #define RECT_EQ_X(r1,r2) ((r1).x==(r2).x && (r1).width==(r2).width)
+
+--- ./jdk/src/solaris/native/sun/java2d/x11/X11PMBlitLoops.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/java2d/x11/X11PMBlitLoops.c Wed Feb 04 12:14:43 2015 -0800
+@@ -241,9 +241,12 @@
+ width, height, 1);
+ if (xsdo->bitmask == 0) {
+ AWT_UNLOCK();
+- JNU_ThrowOutOfMemoryError(env,
+- "Cannot create bitmask for "
+- "offscreen surface");
++ if (!(*env)->ExceptionCheck(env))
++ {
++ JNU_ThrowOutOfMemoryError(env,
++ "Cannot create bitmask for "
++ "offscreen surface");
++ }
+ return;
+ }
+ }
+@@ -253,7 +256,10 @@
+ 1, XYBitmap, 0, NULL, width, height, 32, 0);
+ if (image == NULL) {
+ AWT_UNLOCK();
+- JNU_ThrowOutOfMemoryError(env, "Cannot allocate bitmask for mask");
++ if (!(*env)->ExceptionCheck(env))
++ {
++ JNU_ThrowOutOfMemoryError(env, "Cannot allocate bitmask for mask");
++ }
+ return;
+ }
+ dstScan = image->bytes_per_line;
+@@ -261,7 +267,10 @@
+ if (image->data == NULL) {
+ XFree(image);
+ AWT_UNLOCK();
+- JNU_ThrowOutOfMemoryError(env, "Cannot allocate bitmask for mask");
++ if (!(*env)->ExceptionCheck(env))
++ {
++ JNU_ThrowOutOfMemoryError(env, "Cannot allocate bitmask for mask");
++ }
+ return;
+ }
+ pDst = (unsigned char *)image->data;
+--- ./jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c Wed Feb 04 12:14:43 2015 -0800
+@@ -454,6 +454,7 @@
+ AWT_LOCK();
+ xsdo->drawable = X11SD_CreateSharedPixmap(xsdo);
+ AWT_UNLOCK();
++ JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
+ if (xsdo->drawable) {
+ xsdo->shmPMData.usingShmPixmap = JNI_TRUE;
+ xsdo->shmPMData.shmPixmap = xsdo->drawable;
+@@ -469,6 +470,7 @@
+ xsdo->configData->awt_visInfo.screen),
+ width, height, depth);
+ AWT_UNLOCK();
++ JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
+ #ifdef MITSHM
+ xsdo->shmPMData.usingShmPixmap = JNI_FALSE;
+ xsdo->shmPMData.pixmap = xsdo->drawable;
+@@ -504,6 +506,7 @@
+
+ if (xsdo->configData->awt_cmap == (Colormap)NULL) {
+ awtJNI_CreateColorData(env, xsdo->configData, 1);
++ JNU_CHECK_EXCEPTION(env);
+ }
+ /* color_data will be initialized in awtJNI_CreateColorData for
+ 8-bit visuals */
+@@ -805,7 +808,10 @@
+ xsdo->cData->awt_icmLUT == NULL))
+ {
+ AWT_UNLOCK();
+- JNU_ThrowNullPointerException(env, "colormap lookup table");
++ if (!(*env)->ExceptionCheck(env))
++ {
++ JNU_ThrowNullPointerException(env, "colormap lookup table");
++ }
+ return SD_FAILURE;
+ }
+ if ((lockflags & SD_LOCK_INVCOLOR) != 0 &&
+@@ -816,7 +822,10 @@
+ xsdo->cData->img_oda_blue == NULL))
+ {
+ AWT_UNLOCK();
+- JNU_ThrowNullPointerException(env, "inverse colormap lookup table");
++ if (!(*env)->ExceptionCheck(env))
++ {
++ JNU_ThrowNullPointerException(env, "inverse colormap lookup table");
++ }
+ return SD_FAILURE;
+ }
+ if ((lockflags & SD_LOCK_INVGRAY) != 0 &&
+@@ -824,7 +833,10 @@
+ xsdo->cData->pGrayInverseLutData == NULL))
+ {
+ AWT_UNLOCK();
+- JNU_ThrowNullPointerException(env, "inverse gray lookup table");
++ if (!(*env)->ExceptionCheck(env))
++ {
++ JNU_ThrowNullPointerException(env, "inverse gray lookup table");
++ }
+ return SD_FAILURE;
+ }
+ if (xsdo->dgaAvailable && (lockflags & (SD_LOCK_RD_WR))) {
+--- ./jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c Wed Feb 04 12:14:43 2015 -0800
+@@ -34,6 +34,10 @@
+ #include <fcntl.h>
+ #include <sys/uio.h>
+ #include <unistd.h>
++#if defined(__linux__)
++#include <linux/fs.h>
++#include <sys/ioctl.h>
++#endif
+ #include "nio.h"
+ #include "nio_util.h"
+
+@@ -177,10 +181,21 @@
+ JNIEXPORT jlong JNICALL
+ Java_sun_nio_ch_FileDispatcherImpl_size0(JNIEnv *env, jobject this, jobject fdo)
+ {
++ jint fd = fdval(env, fdo);
+ struct stat64 fbuf;
+
+- if (fstat64(fdval(env, fdo), &fbuf) < 0)
++ if (fstat64(fd, &fbuf) < 0)
+ return handle(env, -1, "Size failed");
++
++#ifdef BLKGETSIZE64
++ if (S_ISBLK(fbuf.st_mode)) {
++ uint64_t size;
++ if (ioctl(fd, BLKGETSIZE64, &size) < 0)
++ return handle(env, -1, "Size failed");
++ return (jlong)size;
++ }
++#endif
++
+ return fbuf.st_size;
+ }
+
+--- ./jdk/src/solaris/native/sun/nio/ch/Net.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/nio/ch/Net.c Wed Feb 04 12:14:43 2015 -0800
+@@ -478,7 +478,8 @@
+
+ JNIEXPORT void JNICALL
+ Java_sun_nio_ch_Net_setIntOption0(JNIEnv *env, jclass clazz, jobject fdo,
+- jboolean mayNeedConversion, jint level, jint opt, jint arg)
++ jboolean mayNeedConversion, jint level,
++ jint opt, jint arg, jboolean isIPv6)
+ {
+ int result;
+ struct linger linger;
+@@ -521,6 +522,12 @@
+ JNU_JAVANETPKG "SocketException",
+ "sun.nio.ch.Net.setIntOption");
+ }
++#ifdef __linux__
++ if (level == IPPROTO_IPV6 && opt == IPV6_TCLASS && isIPv6) {
++ // set the V4 option also
++ setsockopt(fdval(env, fdo), IPPROTO_IP, IP_TOS, parg, arglen);
++ }
++#endif
+ }
+
+ JNIEXPORT jint JNICALL
+--- ./jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c Wed Feb 04 12:14:43 2015 -0800
+@@ -315,7 +315,7 @@
+ int res = -1;
+
+ RESTARTABLE(dup((int)fd), res);
+- if (fd == -1) {
++ if (res == -1) {
+ throwUnixException(env, errno);
+ }
+ return (jint)res;
+@@ -343,13 +343,14 @@
+ JNIEXPORT void JNICALL
+ Java_sun_nio_fs_UnixNativeDispatcher_fclose(JNIEnv* env, jclass this, jlong stream)
+ {
+- int res;
+ FILE* fp = jlong_to_ptr(stream);
+
+- do {
+- res = fclose(fp);
+- } while (res == EOF && errno == EINTR);
+- if (res == EOF) {
++ /* NOTE: fclose() wrapper is only used with read-only streams.
++ * If it ever is used with write streams, it might be better to add
++ * RESTARTABLE(fflush(fp)) before closing, to make sure the stream
++ * is completely written even if fclose() failed.
++ */
++ if (fclose(fp) == EOF && errno != EINTR) {
+ throwUnixException(env, errno);
+ }
+ }
+@@ -657,11 +658,9 @@
+
+ JNIEXPORT void JNICALL
+ Java_sun_nio_fs_UnixNativeDispatcher_closedir(JNIEnv* env, jclass this, jlong dir) {
+- int err;
+ DIR* dirp = jlong_to_ptr(dir);
+
+- RESTARTABLE(closedir(dirp), err);
+- if (errno == -1) {
++ if (closedir(dirp) == -1 && errno != EINTR) {
+ throwUnixException(env, errno);
+ }
+ }
+--- ./jdk/src/solaris/native/sun/tools/attach/BsdVirtualMachine.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/tools/attach/BsdVirtualMachine.c Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -198,14 +198,14 @@
+ len = remaining;
+ }
+
+- RESTARTABLE(read(fd, buf+off, len), n);
++ RESTARTABLE(read(fd, buf, len), n);
+ if (n == -1) {
+ JNU_ThrowIOExceptionWithLastError(env, "read");
+ } else {
+ if (n == 0) {
+ n = -1; // EOF
+ } else {
+- (*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf+off));
++ (*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf));
+ }
+ }
+ return n;
+--- ./jdk/src/solaris/native/sun/tools/attach/LinuxVirtualMachine.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/tools/attach/LinuxVirtualMachine.c Wed Feb 04 12:14:43 2015 -0800
+@@ -416,14 +416,14 @@
+ len = remaining;
+ }
+
+- RESTARTABLE(read(fd, buf+off, len), n);
++ RESTARTABLE(read(fd, buf, len), n);
+ if (n == -1) {
+ JNU_ThrowIOExceptionWithLastError(env, "read");
+ } else {
+ if (n == 0) {
+ n = -1; // EOF
+ } else {
+- (*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf+off));
++ (*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf));
+ }
+ }
+ return n;
+--- ./jdk/src/solaris/native/sun/tools/attach/SolarisVirtualMachine.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/tools/attach/SolarisVirtualMachine.c Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -161,14 +161,14 @@
+ len = remaining;
+ }
+
+- RESTARTABLE(read(fd, buf+off, len), n);
++ RESTARTABLE(read(fd, buf, len), n);
+ if (n == -1) {
+ JNU_ThrowIOExceptionWithLastError(env, "read");
+ } else {
+ if (n == 0) {
+ n = -1; // EOF
+ } else {
+- (*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf+off));
++ (*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf));
+ }
+ }
+ return n;
+--- ./jdk/src/solaris/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,77 +0,0 @@
+-/*
+- * Copyright (c) 2012, 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.
+- */
+-
+-#include "sun_util_locale_provider_HostLocaleProviderAdapterImpl.h"
+-#include <gdefs.h>
+-#include <string.h>
+-#include <langinfo.h>
+-#include <locale.h>
+-
+-#define BUFLEN 64
+-
+-/*
+- * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
+- * Method: getPattern
+- * Signature: (IILjava/lang/String;)Ljava/lang/String;
+- */
+-JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPattern
+- (JNIEnv *env, jclass cls, jint dateStyle, jint timeStyle, jstring jlangtag) {
+-
+- // TEMPORARY!
+- char locale[BUFLEN];
+- char * pch;
+- char * old;
+- char * ret;
+- const char *langtag = (*env)->GetStringUTFChars(env, jlangtag, JNI_FALSE);
+-
+- strcpy(locale, langtag);
+- pch = strchr(locale, '-');
+- if (pch != NULL) {
+- *pch = '_';
+- }
+- pch = strchr(locale, '-');
+- if (pch != NULL) {
+- *pch = '\0';
+- }
+- strcat(locale, ".UTF-8");
+- old = setlocale(LC_TIME, "");
+- setlocale(LC_TIME, locale);
+-
+- if (dateStyle != (-1) && timeStyle != (-1)) {
+- ret = nl_langinfo(D_T_FMT);
+- } else if (dateStyle != (-1)) {
+- ret = nl_langinfo(D_FMT);
+- } else if (timeStyle != (-1)) {
+- ret = nl_langinfo(T_FMT);
+- } else {
+- ret = "yyyy/MM/dd";
+- }
+-
+- setlocale(LC_TIME, old);
+-
+- (*env)->ReleaseStringUTFChars(env, jlangtag, langtag);
+-
+- return (*env)->NewStringUTF(env, ret);
+-}
+--- ./jdk/src/solaris/native/sun/xawt/XlibWrapper.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/solaris/native/sun/xawt/XlibWrapper.c Wed Feb 04 12:14:43 2015 -0800
+@@ -2011,10 +2011,14 @@
+ * Toolkit thread to process PropertyNotify or SelectionNotify events.
+ */
+ static Bool
+-secondary_loop_event(Display* dpy, XEvent* event, char* arg) {
+- return (event->type == SelectionNotify ||
+- event->type == SelectionClear ||
+- event->type == PropertyNotify) ? True : False;
++secondary_loop_event(Display* dpy, XEvent* event, XPointer xawt_root_window) {
++ return (
++ event->type == SelectionNotify ||
++ event->type == SelectionClear ||
++ event->type == PropertyNotify ||
++ (event->type == ConfigureNotify
++ && event->xany.window == *(Window*) xawt_root_window)
++ ) ? True : False;
+ }
+
+
+@@ -2025,8 +2029,11 @@
+
+ AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE);
+ exitSecondaryLoop = False;
++ Window xawt_root_window = get_xawt_root_shell(env);
++
+ while (!exitSecondaryLoop) {
+- if (XCheckIfEvent((Display*) jlong_to_ptr(display), (XEvent*) jlong_to_ptr(ptr), secondary_loop_event, NULL)) {
++ if (XCheckIfEvent((Display*) jlong_to_ptr(display),
++ (XEvent*) jlong_to_ptr(ptr), secondary_loop_event, (XPointer) &xawt_root_window)) {
+ return JNI_TRUE;
+ }
+ timeout = (timeout < AWT_SECONDARY_LOOP_TIMEOUT) ? (timeout << 1) : AWT_SECONDARY_LOOP_TIMEOUT;
+--- ./jdk/src/windows/classes/sun/awt/Win32FontManager.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/classes/sun/awt/Win32FontManager.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -37,7 +37,6 @@
+ import java.util.NoSuchElementException;
+ import java.util.StringTokenizer;
+
+-import sun.awt.Win32GraphicsEnvironment;
+ import sun.awt.windows.WFontConfiguration;
+ import sun.font.FontManager;
+ import sun.font.SunFontManager;
+@@ -48,9 +47,7 @@
+ /**
+ * The X11 implementation of {@link FontManager}.
+ */
+-public class Win32FontManager extends SunFontManager {
+-
+- private static String[] defaultPlatformFont = null;
++public final class Win32FontManager extends SunFontManager {
+
+ private static TrueTypeFont eudcFont;
+
+@@ -215,12 +212,8 @@
+
+ protected synchronized native String getFontPath(boolean noType1Fonts);
+
+- public String[] getDefaultPlatformFont() {
+-
+- if (defaultPlatformFont != null) {
+- return defaultPlatformFont;
+- }
+-
++ @Override
++ protected String[] getDefaultPlatformFont() {
+ String[] info = new String[2];
+ info[0] = "Arial";
+ info[1] = "c:\\windows\\fonts";
+@@ -247,8 +240,7 @@
+ info[1] = dirs[0];
+ }
+ info[1] = info[1] + File.separator + "arial.ttf";
+- defaultPlatformFont = info;
+- return defaultPlatformFont;
++ return info;
+ }
+
+ /* register only TrueType/OpenType fonts
+--- ./jdk/src/windows/classes/sun/awt/windows/ThemeReader.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/classes/sun/awt/windows/ThemeReader.java Wed Feb 04 12:14:43 2015 -0800
+@@ -62,14 +62,20 @@
+ private static final Lock writeLock = readWriteLock.writeLock();
+ private static volatile boolean valid = false;
+
++ static volatile boolean xpStyleEnabled;
++
+ static void flush() {
+- // Could be called on Toolkit thread, so do not try to aquire locks
++ // Could be called on Toolkit thread, so do not try to acquire locks
+ // to avoid deadlock with theme initialization
+ valid = false;
+ }
+
+ public static native boolean isThemed();
+
++ public static boolean isXPStyleEnabled() {
++ return xpStyleEnabled;
++ }
++
+ // this should be called only with writeLock held
+ private static Long getThemeImpl(String widget) {
+ Long theme = widgetToTheme.get(widget);
+--- ./jdk/src/windows/classes/sun/awt/windows/WLightweightFramePeer.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/classes/sun/awt/windows/WLightweightFramePeer.java Wed Feb 04 12:14:43 2015 -0800
+@@ -27,6 +27,7 @@
+
+ import java.awt.Component;
+ import java.awt.Graphics;
++import java.awt.dnd.DropTarget;
+ import java.awt.event.ComponentEvent;
+ import java.awt.event.MouseEvent;
+
+@@ -94,4 +95,14 @@
+ public boolean isLightweightFramePeer() {
+ return true;
+ }
++
++ @Override
++ public void addDropTarget(DropTarget dt) {
++ getLwTarget().addDropTarget(dt);
++ }
++
++ @Override
++ public void removeDropTarget(DropTarget dt) {
++ getLwTarget().removeDropTarget(dt);
++ }
+ }
+--- ./jdk/src/windows/classes/sun/awt/windows/WPathGraphics.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/classes/sun/awt/windows/WPathGraphics.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1400,7 +1400,9 @@
+ * The saved device transform is needed as the current transform
+ * is not likely to be the same.
+ */
+- deviceClip(savedClip.getPathIterator(savedTransform));
++ if (savedClip != null) {
++ deviceClip(savedClip.getPathIterator(savedTransform));
++ }
+
+ /* Scale the bounding rectangle by the scale transform.
+ * Because the scaling transform has only x and y
+--- ./jdk/src/windows/classes/sun/awt/windows/WToolkit.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/classes/sun/awt/windows/WToolkit.java Wed Feb 04 12:14:43 2015 -0800
+@@ -36,9 +36,9 @@
+ import java.beans.PropertyChangeListener;
+ import java.security.AccessController;
+ import java.security.PrivilegedAction;
++import sun.awt.AppContext;
+ import sun.awt.AWTAutoShutdown;
+ import sun.awt.LightweightFrame;
+-import sun.awt.AppContext;
+ import sun.awt.SunToolkit;
+ import sun.misc.ThreadGroupUtils;
+ import sun.awt.Win32GraphicsDevice;
+@@ -73,6 +73,9 @@
+
+ private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.windows.WToolkit");
+
++ // Desktop property which specifies whether XP visual styles are in effect
++ public static final String XPSTYLE_THEME_ACTIVE = "win.xpstyle.themeActive";
++
+ static GraphicsConfiguration config;
+
+ // System clipboard.
+@@ -580,6 +583,7 @@
+ /**
+ * Returns <code>true</code> if this frame state is supported.
+ */
++ @Override
+ public boolean isFrameStateSupported(int state) {
+ switch (state) {
+ case Frame.NORMAL:
+@@ -839,6 +843,11 @@
+
+ @Override
+ public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException {
++ final LightweightFrame f = SunToolkit.getLightweightFrame(dge.getComponent());
++ if (f != null) {
++ return f.createDragSourceContextPeer(dge);
++ }
++
+ return WDragSourceContextPeer.createDragSourceContextPeer(dge);
+ }
+
+@@ -848,6 +857,11 @@
+ DragSource ds, Component c, int srcActions,
+ DragGestureListener dgl)
+ {
++ final LightweightFrame f = SunToolkit.getLightweightFrame(c);
++ if (f != null) {
++ return f.createDragGestureRecognizer(abstractRecognizerClass, ds, c, srcActions, dgl);
++ }
++
+ if (MouseDragGestureRecognizer.class.equals(abstractRecognizerClass))
+ return (T)new WMouseDragGestureRecognizer(ds, c, srcActions, dgl);
+ else
+@@ -894,7 +908,7 @@
+ private synchronized void lazilyInitWProps() {
+ if (wprops == null) {
+ wprops = new WDesktopProperties(this);
+- updateProperties();
++ updateProperties(wprops.getProperties());
+ }
+ }
+
+@@ -929,25 +943,36 @@
+ * Windows doesn't always send WM_SETTINGCHANGE when it should.
+ */
+ private void windowsSettingChange() {
++ // JDK-8039383: Have to update the value of XPSTYLE_THEME_ACTIVE property
++ // as soon as possible to prevent NPE and other errors because theme data
++ // has become unavailable.
++ final Map<String, Object> props = getWProps();
++ if (props == null) {
++ // props has not been initialized, so we have nothing to update
++ return;
++ }
++
++ updateXPStyleEnabled(props.get(XPSTYLE_THEME_ACTIVE));
++
+ if (AppContext.getAppContext() == null) {
+ // We cannot post the update to any EventQueue. Listeners will
+ // be called on EDTs by DesktopPropertyChangeSupport
+- updateProperties();
++ updateProperties(props);
+ } else {
+ // Cannot update on Toolkit thread.
+ // DesktopPropertyChangeSupport will call listeners on Toolkit
+ // thread if it has AppContext (standalone mode)
+- EventQueue.invokeLater(this::updateProperties);
++ EventQueue.invokeLater(() -> updateProperties(props));
+ }
+ }
+
+- private synchronized void updateProperties() {
+- if (null == wprops) {
+- // wprops has not been initialized, so we have nothing to update
++ private synchronized void updateProperties(final Map<String, Object> props) {
++ if (null == props) {
+ return;
+ }
+
+- Map<String, Object> props = wprops.getProperties();
++ updateXPStyleEnabled(props.get(XPSTYLE_THEME_ACTIVE));
++
+ for (String propName : props.keySet()) {
+ Object val = props.get(propName);
+ if (log.isLoggable(PlatformLogger.Level.FINER)) {
+@@ -957,6 +982,14 @@
+ }
+ }
+
++ private synchronized Map<String, Object> getWProps() {
++ return (wprops != null) ? wprops.getProperties() : null;
++ }
++
++ private void updateXPStyleEnabled(final Object dskProp) {
++ ThemeReader.xpStyleEnabled = Boolean.TRUE.equals(dskProp);
++ }
++
+ @Override
+ public synchronized void addPropertyChangeListener(String name, PropertyChangeListener pcl) {
+ if (name == null) {
+@@ -978,6 +1011,7 @@
+ * initialize only static props here and do not try to initialize props which depends on wprops,
+ * this should be done in lazilyLoadDesktopProperty() only.
+ */
++ @Override
+ protected synchronized void initializeDesktopProperties() {
+ desktopProperties.put("DnD.Autoscroll.initialDelay",
+ Integer.valueOf(50));
+--- ./jdk/src/windows/classes/sun/java2d/d3d/D3DBlitLoops.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/classes/sun/java2d/d3d/D3DBlitLoops.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -48,7 +48,7 @@
+ import static sun.java2d.pipe.BufferedOpCodes.*;
+ import sun.java2d.windows.GDIWindowSurfaceData;
+
+-class D3DBlitLoops {
++final class D3DBlitLoops {
+
+ static void register() {
+ Blit blitIntArgbPreToSurface =
+@@ -57,7 +57,9 @@
+ Blit blitIntArgbPreToTexture =
+ new D3DSwToTextureBlit(SurfaceType.IntArgbPre,
+ D3DSurfaceData.ST_INT_ARGB_PRE);
+-
++ TransformBlit transformBlitIntArgbPreToSurface =
++ new D3DSwToSurfaceTransform(SurfaceType.IntArgbPre,
++ D3DSurfaceData.ST_INT_ARGB_PRE);
+ GraphicsPrimitive[] primitives = {
+ // prevent D3DSurface -> Screen blits
+ new D3DSurfaceToGDIWindowSurfaceBlit(),
+@@ -123,8 +125,6 @@
+
+ new D3DSwToSurfaceTransform(SurfaceType.IntArgb,
+ D3DSurfaceData.ST_INT_ARGB),
+- new D3DSwToSurfaceTransform(SurfaceType.IntArgbPre,
+- D3DSurfaceData.ST_INT_ARGB_PRE),
+ new D3DSwToSurfaceTransform(SurfaceType.IntRgb,
+ D3DSurfaceData.ST_INT_RGB),
+ new D3DSwToSurfaceTransform(SurfaceType.IntBgr,
+@@ -140,6 +140,9 @@
+ // REMIND: we don't have a native sw loop to back this loop up
+ // new D3DSwToSurfaceTransform(SurfaceType.ByteIndexedBm,
+ // D3DSurfaceData.ST_BYTE_INDEXED_BM),
++ transformBlitIntArgbPreToSurface,
++
++ new D3DGeneralTransformedBlit(transformBlitIntArgbPreToSurface),
+
+ // texture->surface ops
+ new D3DTextureToSurfaceBlit(),
+@@ -712,11 +715,11 @@
+ * This general Blit implementation converts any source surface to an
+ * intermediate IntArgbPre surface, and then uses the more specific
+ * IntArgbPre->D3DSurface/Texture loop to get the intermediate
+- * (premultiplied) surface down to D3D.
++ * (premultiplied) surface down to D3D using simple blit.
+ */
+ class D3DGeneralBlit extends Blit {
+
+- private Blit performop;
++ private final Blit performop;
+ private WeakReference srcTmp;
+
+ D3DGeneralBlit(SurfaceType dstType,
+@@ -757,6 +760,49 @@
+ }
+ }
+
++/**
++ * This general TransformedBlit implementation converts any source surface to an
++ * intermediate IntArgbPre surface, and then uses the more specific
++ * IntArgbPre->D3DSurface/Texture loop to get the intermediate
++ * (premultiplied) surface down to D3D using simple transformBlit.
++ */
++final class D3DGeneralTransformedBlit extends TransformBlit {
++
++ private final TransformBlit performop;
++ private WeakReference<SurfaceData> srcTmp;
++
++ D3DGeneralTransformedBlit(final TransformBlit performop) {
++ super(SurfaceType.Any, CompositeType.AnyAlpha,
++ D3DSurfaceData.D3DSurface);
++ this.performop = performop;
++ }
++
++ @Override
++ public synchronized void Transform(SurfaceData src, SurfaceData dst,
++ Composite comp, Region clip,
++ AffineTransform at, int hint, int srcx,
++ int srcy, int dstx, int dsty, int width,
++ int height){
++ Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
++ CompositeType.SrcNoEa,
++ SurfaceType.IntArgbPre);
++ // use cached intermediate surface, if available
++ final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null;
++ // convert source to IntArgbPre
++ src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc,
++ BufferedImage.TYPE_INT_ARGB_PRE);
++
++ // transform IntArgbPre intermediate surface to D3D surface
++ performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty,
++ width, height);
++
++ if (src != cachedSrc) {
++ // cache the intermediate surface
++ srcTmp = new WeakReference<>(src);
++ }
++ }
++}
++
+ /*
+ * The following classes prohibit copying D3DSurfaces to the screen
+ * (the D3D->sysmem->GDI path is known to be very very slow).
+--- ./jdk/src/windows/classes/sun/tools/attach/WindowsVirtualMachine.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/classes/sun/tools/attach/WindowsVirtualMachine.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,15 +24,15 @@
+ */
+ package sun.tools.attach;
+
+-import com.sun.tools.attach.VirtualMachine;
++import com.sun.tools.attach.AttachOperationFailedException;
+ import com.sun.tools.attach.AgentLoadException;
+ import com.sun.tools.attach.AttachNotSupportedException;
+ import com.sun.tools.attach.spi.AttachProvider;
++
+ import sun.tools.attach.HotSpotVirtualMachine;
++
+ import java.io.IOException;
+-import java.io.File;
+ import java.io.InputStream;
+-import java.util.Properties;
+ import java.util.Random;
+
+ public class WindowsVirtualMachine extends HotSpotVirtualMachine {
+@@ -105,11 +105,17 @@
+ // read completion status
+ int status = readInt(is);
+ if (status != 0) {
++ // read from the stream and use that as the error message
++ String message = readErrorMessage(is);
+ // special case the load command so that the right exception is thrown
+ if (cmd.equals("load")) {
+ throw new AgentLoadException("Failed to load agent library");
+ } else {
+- throw new IOException("Command failed in target VM");
++ if (message == null) {
++ throw new AttachOperationFailedException("Command failed in target VM");
++ } else {
++ throw new AttachOperationFailedException(message);
++ }
+ }
+ }
+
+--- ./jdk/src/windows/lib/tzmappings Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/lib/tzmappings Wed Feb 04 12:14:43 2015 -0800
+@@ -193,5 +193,10 @@
+ Turkey Standard Time:926,926::Asia/Istanbul:
+ Bahia Standard Time:927,927::America/Bahia:
+ Libya Standard Time:928,928:LY:Africa/Tripoli:
+-Western Brazilian Standard Time:929,929:BR:America/Rio_Branco:
+-Armenian Standard Time:930,930:AM:Asia/Yerevan:
++Belarus Standard Time:929,929:BY:Europe/Minsk:
++Line Islands Standard Time:930,930::Pacific/Kiritimati:
++Russia Time Zone 10:931,931::Asia/Srednekolymsk:
++Russia Time Zone 11:932,932::Asia/Anadyr:
++Russia Time Zone 3:933,933::Europe/Samara:
++Western Brazilian Standard Time:934,934:BR:America/Rio_Branco:
++Armenian Standard Time:935,935:AM:Asia/Yerevan:
+--- ./jdk/src/windows/native/java/io/FileOutputStream_md.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/java/io/FileOutputStream_md.c Wed Feb 04 12:14:43 2015 -0800
+@@ -54,8 +54,8 @@
+ */
+
+ JNIEXPORT void JNICALL
+-Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this,
+- jstring path, jboolean append) {
++Java_java_io_FileOutputStream_open0(JNIEnv *env, jobject this,
++ jstring path, jboolean append) {
+ fileOpen(env, this, path, fos_fd,
+ O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC));
+ }
+--- ./jdk/src/windows/native/java/lang/java_props_md.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/java/lang/java_props_md.c Wed Feb 04 12:14:43 2015 -0800
+@@ -28,6 +28,9 @@
+ #define _WIN32_WINNT 0x0601
+ #endif
+
++#include "jni.h"
++#include "jni_util.h"
++
+ #include <windows.h>
+ #include <shlobj.h>
+ #include <objidl.h>
+@@ -51,7 +54,7 @@
+ #endif
+
+ typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
+-static void SetupI18nProps(LCID lcid, char** language, char** script, char** country,
++static boolean SetupI18nProps(LCID lcid, char** language, char** script, char** country,
+ char** variant, char** encoding);
+
+ #define PROPSIZE 9 // eight-letter + null terminator
+@@ -60,8 +63,11 @@
+ static char *
+ getEncodingInternal(LCID lcid)
+ {
++ int codepage;
+ char * ret = malloc(16);
+- int codepage;
++ if (ret == NULL) {
++ return NULL;
++ }
+
+ if (GetLocaleInfo(lcid,
+ LOCALE_IDEFAULTANSICODEPAGE,
+@@ -132,7 +138,11 @@
+ static char* getConsoleEncoding()
+ {
+ char* buf = malloc(16);
+- int cp = GetConsoleCP();
++ int cp;
++ if (buf == NULL) {
++ return NULL;
++ }
++ cp = GetConsoleCP();
+ if (cp >= 874 && cp <= 950)
+ sprintf(buf, "ms%d", cp);
+ else
+@@ -152,11 +162,16 @@
+ getJavaIDFromLangID(LANGID langID)
+ {
+ char * elems[5]; // lang, script, ctry, variant, encoding
+- char * ret = malloc(SNAMESIZE);
++ char * ret;
+ int index;
+
+- SetupI18nProps(MAKELCID(langID, SORT_DEFAULT),
+- &(elems[0]), &(elems[1]), &(elems[2]), &(elems[3]), &(elems[4]));
++ ret = malloc(SNAMESIZE);
++ if (ret == NULL) {
++ return NULL;
++ }
++
++ if (SetupI18nProps(MAKELCID(langID, SORT_DEFAULT),
++ &(elems[0]), &(elems[1]), &(elems[2]), &(elems[3]), &(elems[4]))) {
+
+ // there always is the "language" tag
+ strcpy(ret, elems[0]);
+@@ -172,6 +187,9 @@
+ for (index = 0; index < 5; index++) {
+ free(elems[index]);
+ }
++ } else {
++ ret = NULL;
++ }
+
+ return ret;
+ }
+@@ -259,12 +277,15 @@
+ return NULL;
+ }
+
+-static void
++static boolean
+ SetupI18nProps(LCID lcid, char** language, char** script, char** country,
+ char** variant, char** encoding) {
+ /* script */
+ char tmp[SNAMESIZE];
+ *script = malloc(PROPSIZE);
++ if (*script == NULL) {
++ return FALSE;
++ }
+ if (GetLocaleInfo(lcid,
+ LOCALE_SNAME, tmp, SNAMESIZE) == 0 ||
+ sscanf(tmp, "%*[a-z\\-]%1[A-Z]%[a-z]", *script, &((*script)[1])) == 0 ||
+@@ -274,6 +295,9 @@
+
+ /* country */
+ *country = malloc(PROPSIZE);
++ if (*country == NULL) {
++ return FALSE;
++ }
+ if (GetLocaleInfo(lcid,
+ LOCALE_SISO3166CTRYNAME, *country, PROPSIZE) == 0 &&
+ GetLocaleInfo(lcid,
+@@ -283,6 +307,9 @@
+
+ /* language */
+ *language = malloc(PROPSIZE);
++ if (*language == NULL) {
++ return FALSE;
++ }
+ if (GetLocaleInfo(lcid,
+ LOCALE_SISO639LANGNAME, *language, PROPSIZE) == 0 &&
+ GetLocaleInfo(lcid,
+@@ -294,6 +321,9 @@
+
+ /* variant */
+ *variant = malloc(PROPSIZE);
++ if (*variant == NULL) {
++ return FALSE;
++ }
+ (*variant)[0] = '\0';
+
+ /* handling for Norwegian */
+@@ -308,6 +338,10 @@
+
+ /* encoding */
+ *encoding = getEncodingInternal(lcid);
++ if (*encoding == NULL) {
++ return FALSE;
++ }
++ return TRUE;
+ }
+
+ java_props_t *
+--- ./jdk/src/windows/native/java/net/NetworkInterface.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/java/net/NetworkInterface.c Wed Feb 04 12:14:43 2015 -0800
+@@ -1014,9 +1014,11 @@
+ case MIB_IF_TYPE_FDDI:
+ case IF_TYPE_IEEE80211:
+ len = ifRowP->dwPhysAddrLen;
+- ret = (*env)->NewByteArray(env, len);
+- if (!IS_NULL(ret)) {
+- (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *) ifRowP->bPhysAddr);
++ if (len > 0) {
++ ret = (*env)->NewByteArray(env, len);
++ if (!IS_NULL(ret)) {
++ (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *) ifRowP->bPhysAddr);
++ }
+ }
+ break;
+ }
+--- ./jdk/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c Wed Feb 04 12:14:43 2015 -0800
+@@ -489,6 +489,9 @@
+ }
+ }
+ } else {
++ /* NET_BindV6() closes both sockets upon a failure */
++ (*env)->SetObjectField(env, this, pdsi_fdID, NULL);
++ (*env)->SetObjectField(env, this, pdsi_fd1ID, NULL);
+ NET_ThrowCurrent (env, "Cannot bind");
+ return;
+ }
+--- ./jdk/src/windows/native/java/net/TwoStacksPlainSocketImpl.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/java/net/TwoStacksPlainSocketImpl.c Wed Feb 04 12:14:43 2015 -0800
+@@ -467,6 +467,10 @@
+ (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, fd1);
+ }
+ }
++ } else {
++ /* NET_BindV6() closes both sockets upon a failure */
++ (*env)->SetObjectField(env, this, psi_fdID, NULL);
++ (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
+ }
+ } else {
+ rv = NET_WinBind(fd, (struct sockaddr *)&him, len, exclBind);
+--- ./jdk/src/windows/native/java/net/net_util_md.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/java/net/net_util_md.c Wed Feb 04 12:14:43 2015 -0800
+@@ -443,6 +443,13 @@
+ {
+ int rv;
+
++ if (level == IPPROTO_IPV6 && optname == IPV6_TCLASS) {
++ int *intopt = (int *)optval;
++ *intopt = 0;
++ *optlen = sizeof(*intopt);
++ return 0;
++ }
++
+ rv = getsockopt(s, level, optname, optval, optlen);
+
+
+@@ -620,7 +627,7 @@
+ * and returns SOCKET_ERROR. Used in NET_BindV6 only.
+ */
+
+-#define CLOSE_SOCKETS_AND_RETURN { \
++#define CLOSE_SOCKETS_AND_RETURN do { \
+ if (fd != -1) { \
+ closesocket (fd); \
+ fd = -1; \
+@@ -639,7 +646,7 @@
+ } \
+ b->ipv4_fd = b->ipv6_fd = -1; \
+ return SOCKET_ERROR; \
+-}
++} while(0)
+
+ /*
+ * if ipv6 is available, call NET_BindV6 to bind to the required address/port.
+--- ./jdk/src/windows/native/java/util/TimeZone_md.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/java/util/TimeZone_md.c Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -394,31 +394,34 @@
+ *
+ * value_type is one of the following values:
+ * VALUE_KEY for exact key matching
+- * VALUE_MAPID for MapID and country-based mapping (this is
++ * VALUE_MAPID for MapID (this is
+ * required for the old Windows, such as NT 4.0 SP3).
+ */
+ static char *matchJavaTZ(const char *java_home_dir, int value_type, char *tzName,
+- char *mapID, const char *country)
++ char *mapID)
+ {
+ int line;
+ int IDmatched = 0;
+ FILE *fp;
+ char *javaTZName = NULL;
+ char *items[TZ_NITEMS];
+- char mapFileName[_MAX_PATH + 1];
++ char *mapFileName;
+ char lineBuffer[MAX_ZONE_CHAR * 4];
+- char bestMatch[MAX_ZONE_CHAR];
+- int noMapID = *mapID == '\0'; /* no mapID on Vista */
++ int noMapID = *mapID == '\0'; /* no mapID on Vista and later */
+
+- bestMatch[0] = '\0';
+-
++ mapFileName = malloc(strlen(java_home_dir) + strlen(MAPPINGS_FILE) + 1);
++ if (mapFileName == NULL) {
++ return NULL;
++ }
+ strcpy(mapFileName, java_home_dir);
+ strcat(mapFileName, MAPPINGS_FILE);
+
+ if ((fp = fopen(mapFileName, "r")) == NULL) {
+ jio_fprintf(stderr, "can't open %s.\n", mapFileName);
++ free((void *) mapFileName);
+ return NULL;
+ }
++ free((void *) mapFileName);
+
+ line = 0;
+ while (fgets(lineBuffer, sizeof(lineBuffer), fp) != NULL) {
+@@ -469,18 +472,6 @@
+ javaTZName = _strdup(items[TZ_JAVA_NAME]);
+ break;
+ }
+- /*
+- * Try to find the most likely time zone.
+- */
+- if (*items[TZ_REGION] == '\0') {
+- strncpy(bestMatch, items[TZ_JAVA_NAME], MAX_ZONE_CHAR);
+- } else if (country != NULL && strcmp(items[TZ_REGION], country) == 0) {
+- if (value_type == VALUE_MAPID) {
+- javaTZName = _strdup(items[TZ_JAVA_NAME]);
+- break;
+- }
+- strncpy(bestMatch, items[TZ_JAVA_NAME], MAX_ZONE_CHAR);
+- }
+ } else {
+ if (IDmatched == 1) {
+ /*
+@@ -492,9 +483,6 @@
+ }
+ fclose(fp);
+
+- if (javaTZName == NULL && bestMatch[0] != '\0') {
+- javaTZName = _strdup(bestMatch);
+- }
+ return javaTZName;
+
+ illegal_format:
+@@ -506,7 +494,7 @@
+ /*
+ * Detects the platform time zone which maps to a Java time zone ID.
+ */
+-char *findJavaTZ_md(const char *java_home_dir, const char *country)
++char *findJavaTZ_md(const char *java_home_dir)
+ {
+ char winZoneName[MAX_ZONE_CHAR];
+ char winMapID[MAX_MAPID_LENGTH];
+@@ -521,7 +509,7 @@
+ std_timezone = _strdup(winZoneName);
+ } else {
+ std_timezone = matchJavaTZ(java_home_dir, result,
+- winZoneName, winMapID, country);
++ winZoneName, winMapID);
+ }
+ }
+
+--- ./jdk/src/windows/native/java/util/TimeZone_md.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/java/util/TimeZone_md.h Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -26,7 +26,7 @@
+ #ifndef _TIMEZONE_MD_H
+ #define _TIMEZONE_MD_H
+
+-char *findJavaTZ_md(const char *java_home_dir, const char *region);
++char *findJavaTZ_md(const char *java_home_dir);
+ char *getGMTOffsetID();
+
+ #endif
+--- ./jdk/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c Wed Feb 04 12:14:43 2015 -0800
+@@ -568,3 +568,11 @@
+ {
+ PostMessage(splash->hWnd, WM_SPLASHRECONFIGURE, 0, 0);
+ }
++
++SPLASHEXPORT char*
++SplashGetScaledImageName(const char* jarName, const char* fileName,
++ float *scaleFactor)
++{
++ *scaleFactor = 1;
++ return NULL;
++}
+--- ./jdk/src/windows/native/sun/java2d/d3d/D3DBadHardware.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/java2d/d3d/D3DBadHardware.h Wed Feb 04 12:14:43 2015 -0800
+@@ -51,131 +51,8 @@
+
+ static const ADAPTER_INFO badHardware[] = {
+
+- // Intel HD
+- // Clarkdale (Desktop) GMA HD Lines
+- { 0x8086, 0x0042, NO_VERSION, OS_ALL },
+- // Arrandale (Mobile) GMA HD Lines
+- { 0x8086, 0x0046, NO_VERSION, OS_ALL },
+-
+- // Sandy Bridge HD Graphics 3000/2000
+- { 0x8086, 0x0102, NO_VERSION, OS_ALL },
+- { 0x8086, 0x0106, NO_VERSION, OS_ALL },
+- { 0x8086, 0x0112, NO_VERSION, OS_ALL },
+- { 0x8086, 0x0116, NO_VERSION, OS_ALL },
+- { 0x8086, 0x0122, NO_VERSION, OS_ALL },
+- { 0x8086, 0x0126, NO_VERSION, OS_ALL },
+- { 0x8086, 0x010A, NO_VERSION, OS_ALL },
+-
+- // Ivy Bridge
+- { 0x8086, 0x0162, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0162, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x0166, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0166, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x016A, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x016A, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x0152, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0152, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x0156, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0156, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x015A, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x015A, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+-
+- // Haswell
+- { 0x8086, 0x0402, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0402, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x0406, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0406, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x0412, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0412, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x0416, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0416, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x041E, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x041E, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x040A, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x040A, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x041A, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x041A, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x0A06, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0A06, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x0A16, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0A16, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x0A26, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0A26, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x0A2E, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0A2E, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x0A1E, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0A1E, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x0A0E, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0A0E, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x0D26, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0D26, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+- { 0x8086, 0x0D22, D_VERSION(6,14,10,5437), OS_WINXP | OS_WINXP_64 },
+- { 0x8086, 0x0D22, D_VERSION(9,18,10,3257), OS_VISTA | OS_WINDOWS7 },
+-
+- // Reason: workaround for 6620073, 6612195
+- // Intel 740
+- { 0x8086, 0x7800, NO_VERSION, OS_ALL },
+- { 0x8086, 0x1240, NO_VERSION, OS_ALL },
+- { 0x8086, 0x7121, NO_VERSION, OS_ALL },
+- { 0x8086, 0x7123, NO_VERSION, OS_ALL },
+- { 0x8086, 0x7125, NO_VERSION, OS_ALL },
+- { 0x8086, 0x1132, NO_VERSION, OS_ALL },
+- // IEG
+- { 0x8086, 0x2562, NO_VERSION, OS_ALL },
+- { 0x8086, 0x3577, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2572, NO_VERSION, OS_ALL },
+- { 0x8086, 0x3582, NO_VERSION, OS_ALL },
+- { 0x8086, 0x358E, NO_VERSION, OS_ALL },
+- // GMA
+- { 0x8086, 0x2582, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2782, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2592, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2792, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2772, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2776, NO_VERSION, OS_ALL },
+- { 0x8086, 0x27A2, NO_VERSION, OS_ALL },
+- { 0x8086, 0x27A6, NO_VERSION, OS_ALL },
+- { 0x8086, 0x27AE, NO_VERSION, OS_ALL },
+- { 0x8086, 0x29D2, NO_VERSION, OS_ALL },
+- { 0x8086, 0x29D3, NO_VERSION, OS_ALL },
+- { 0x8086, 0x29B2, NO_VERSION, OS_ALL },
+- { 0x8086, 0x29B3, NO_VERSION, OS_ALL },
+- { 0x8086, 0x29C2, NO_VERSION, OS_ALL },
+- { 0x8086, 0x29C3, NO_VERSION, OS_ALL },
+- { 0x8086, 0xA001, NO_VERSION, OS_ALL },
+- { 0x8086, 0xA002, NO_VERSION, OS_ALL },
+- { 0x8086, 0xA011, NO_VERSION, OS_ALL },
+- { 0x8086, 0xA012, NO_VERSION, OS_ALL },
+- // GMA
+- { 0x8086, 0x2972, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2973, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2992, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2993, NO_VERSION, OS_ALL },
+- { 0x8086, 0x29A2, NO_VERSION, OS_ALL },
+- { 0x8086, 0x29A3, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2982, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2983, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2A02, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2A03, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2A12, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2A13, NO_VERSION, OS_ALL },
+-
+- // Eaglelake (Desktop) GMA 4500 Lines
+- { 0x8086, 0x2E42, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2E43, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2E92, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2E93, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2E12, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2E13, NO_VERSION, OS_ALL },
+- // Eaglelake (Desktop) GMA X4500 Lines
+- { 0x8086, 0x2E32, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2E33, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2E22, NO_VERSION, OS_ALL },
+- // Eaglelake (Desktop) GMA X4500HD Lines
+- { 0x8086, 0x2E23, NO_VERSION, OS_ALL },
+- // Cantiga (Mobile) GMA 4500MHD Lines
+- { 0x8086, 0x2A42, NO_VERSION, OS_ALL },
+- { 0x8086, 0x2A43, NO_VERSION, OS_ALL },
++ // All Intel Chips.
++ { 0x8086, ALL_DEVICEIDS, NO_VERSION, OS_ALL },
+
+ // ATI Mobility Radeon X1600, X1400, X1450, X1300, X1350
+ // Reason: workaround for 6613066, 6687166
+--- ./jdk/src/windows/native/sun/java2d/d3d/D3DBufImgOps.cpp Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/java2d/d3d/D3DBufImgOps.cpp Wed Feb 04 12:14:43 2015 -0800
+@@ -201,6 +201,9 @@
+ int i;
+ jint flags = 0;
+
++ for (i = 0; i < 4; i++) {
++ bands[i] = NULL;
++ }
+ J2dTraceLn4(J2D_TRACE_INFO,
+ "D3DBufImgOps_EnableLookupOp: short=%d num=%d len=%d off=%d",
+ shortData, numBands, bandLength, offset);
+--- ./jdk/src/windows/native/sun/java2d/windows/GDIRenderer.cpp Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/java2d/windows/GDIRenderer.cpp Wed Feb 04 12:14:43 2015 -0800
+@@ -670,7 +670,7 @@
+ if (ypoints != NULL) {
+ pPoints = TransformPoly(xpoints, ypoints, transx, transy,
+ tmpPts, &npoints, FALSE, FALSE);
+- env->ReleasePrimitiveArrayCritical(ypointsarray, xpoints, JNI_ABORT);
++ env->ReleasePrimitiveArrayCritical(ypointsarray, ypoints, JNI_ABORT);
+ }
+ env->ReleasePrimitiveArrayCritical(xpointsarray, xpoints, JNI_ABORT);
+ }
+--- ./jdk/src/windows/native/sun/management/OperatingSystemImpl.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/management/OperatingSystemImpl.c Wed Feb 04 12:14:43 2015 -0800
+@@ -53,8 +53,6 @@
+ typedef unsigned __int32 juint;
+ typedef unsigned __int64 julong;
+
+-typedef enum boolean_values { false=0, true=1};
+-
+ static void set_low(jlong* value, jint low) {
+ *value &= (jlong)0xffffffff << 32;
+ *value |= (jlong)(julong)(juint)low;
+@@ -66,22 +64,22 @@
+ }
+
+ static jlong jlong_from(jint h, jint l) {
+- jlong result = 0; // initialization to avoid warning
+- set_high(&result, h);
+- set_low(&result, l);
+- return result;
++ jlong result = 0; // initialization to avoid warning
++ set_high(&result, h);
++ set_low(&result, l);
++ return result;
+ }
+
+ static HANDLE main_process;
+
+-int perfiInit(void);
++static void perfInit(void);
+
+ JNIEXPORT void JNICALL
+ Java_sun_management_OperatingSystemImpl_initialize
+ (JNIEnv *env, jclass cls)
+ {
+ main_process = GetCurrentProcess();
+- perfiInit();
++ perfInit();
+ }
+
+ JNIEXPORT jlong JNICALL
+@@ -155,26 +153,7 @@
+ return (jlong) ms.ullTotalPhys;
+ }
+
+-// Seems WinXP PDH returns PDH_MORE_DATA whenever we send in a NULL buffer.
+-// Let's just ignore it, since we make sure we have enough buffer anyway.
+-static int
+-pdh_fail(PDH_STATUS pdhStat) {
+- return pdhStat != ERROR_SUCCESS && pdhStat != PDH_MORE_DATA;
+-}
+-
+-// INFO: Using PDH APIs Correctly in a Localized Language (Q287159)
+-// http://support.microsoft.com/default.aspx?scid=kb;EN-US;q287159
+-// The index value for the base system counters and objects like processor,
+-// process, thread, memory, and so forth are always the same irrespective
+-// of the localized version of the operating system or service pack installed.
+-#define PDH_PROCESSOR_IDX ((DWORD) 238)
+-#define PDH_PROCESSOR_TIME_IDX ((DWORD) 6)
+-#define PDH_PRIV_PROCESSOR_TIME_IDX ((DWORD) 144)
+-#define PDH_PROCESS_IDX ((DWORD) 230)
+-#define PDH_ID_PROCESS_IDX ((DWORD) 784)
+-#define PDH_CONTEXT_SWITCH_RATE_IDX ((DWORD) 146)
+-#define PDH_SYSTEM_IDX ((DWORD) 2)
+-#define PDH_VIRTUAL_BYTES_IDX ((DWORD) 174)
++/* Performance Data Helper API (PDH) support */
+
+ typedef PDH_STATUS (WINAPI *PdhAddCounterFunc)(
+ HQUERY hQuery,
+@@ -183,48 +162,44 @@
+ HCOUNTER *phCounter
+ );
+ typedef PDH_STATUS (WINAPI *PdhOpenQueryFunc)(
+- LPCWSTR szDataSource,
+- DWORD dwUserData,
+- HQUERY *phQuery
+- );
++ LPCWSTR szDataSource,
++ DWORD dwUserData,
++ HQUERY *phQuery
++ );
++typedef PDH_STATUS (WINAPI *PdhCollectQueryDataFunc)(
++ HQUERY hQuery
++ );
++
++typedef PDH_STATUS (WINAPI *PdhEnumObjectItemsFunc)(
++ LPCTSTR szDataSource,
++ LPCTSTR szMachineName,
++ LPCTSTR szObjectName,
++ LPTSTR mszCounterList,
++ LPDWORD pcchCounterListLength,
++ LPTSTR mszInstanceList,
++ LPDWORD pcchInstanceListLength,
++ DWORD dwDetailLevel,
++ DWORD dwFlags
++ );
++typedef PDH_STATUS (WINAPI *PdhRemoveCounterFunc)(
++ HCOUNTER hCounter
++ );
++typedef PDH_STATUS (WINAPI *PdhLookupPerfNameByIndexFunc)(
++ LPCSTR szMachineName,
++ DWORD dwNameIndex,
++ LPSTR szNameBuffer,
++ LPDWORD pcchNameBufferSize
++ );
+ typedef DWORD (WINAPI *PdhCloseQueryFunc)(
+ HQUERY hQuery
+ );
+-typedef PDH_STATUS (WINAPI *PdhCollectQueryDataFunc)(
+- HQUERY hQuery
+- );
++
+ typedef DWORD (WINAPI *PdhGetFormattedCounterValueFunc)(
+- HCOUNTER hCounter,
+- DWORD dwFormat,
+- LPDWORD lpdwType,
+- PPDH_FMT_COUNTERVALUE pValue
+- );
+-typedef PDH_STATUS (WINAPI *PdhEnumObjectItemsFunc)(
+- LPCTSTR szDataSource,
+- LPCTSTR szMachineName,
+- LPCTSTR szObjectName,
+- LPTSTR mszCounterList,
+- LPDWORD pcchCounterListLength,
+- LPTSTR mszInstanceList,
+- LPDWORD pcchInstanceListLength,
+- DWORD dwDetailLevel,
+- DWORD dwFlags
+- );
+-typedef PDH_STATUS (WINAPI *PdhRemoveCounterFunc)(
+- HCOUNTER hCounter
+- );
+-typedef PDH_STATUS (WINAPI *PdhLookupPerfNameByIndexFunc)(
+- LPCSTR szMachineName,
+- DWORD dwNameIndex,
+- LPSTR szNameBuffer,
+- LPDWORD pcchNameBufferSize
+- );
+-typedef PDH_STATUS (WINAPI *PdhMakeCounterPathFunc)(
+- PDH_COUNTER_PATH_ELEMENTS *pCounterPathElements,
+- LPTSTR szFullPathBuffer,
+- LPDWORD pcchBufferSize,
+- DWORD dwFlags
+- );
++ HCOUNTER hCounter,
++ DWORD dwFormat,
++ LPDWORD lpdwType,
++ PPDH_FMT_COUNTERVALUE pValue
++ );
+
+ static PdhAddCounterFunc PdhAddCounter_i;
+ static PdhOpenQueryFunc PdhOpenQuery_i;
+@@ -234,76 +209,757 @@
+ static PdhEnumObjectItemsFunc PdhEnumObjectItems_i;
+ static PdhRemoveCounterFunc PdhRemoveCounter_i;
+ static PdhLookupPerfNameByIndexFunc PdhLookupPerfNameByIndex_i;
+-static PdhMakeCounterPathFunc PdhMakeCounterPath_i;
+
+-static HANDLE thisProcess;
+-static double cpuFactor;
+-static DWORD num_cpus;
+-
+-#define FT2JLONG(X) ((((jlong)X.dwHighDateTime) << 32) | ((jlong)X.dwLowDateTime))
+-#define COUNTER_BUF_SIZE 256
+-// Min time between query updates.
+-#define MIN_UPDATE_INTERVAL 500
+-#define CONFIG_SUCCESSFUL 0
+-
+-/**
++/*
+ * Struct for PDH queries.
+ */
+ typedef struct {
+ HQUERY query;
+- uint64_t lastUpdate; // Last time query was updated (current millis).
++ uint64_t lastUpdate; // Last time query was updated (ticks)
+ } UpdateQueryS, *UpdateQueryP;
+
+-/**
+- * Struct for the processor load counters.
++// Min time between query updates (ticks)
++static const int MIN_UPDATE_INTERVAL = 500;
++
++/*
++ * Struct for a PDH query with multiple counters.
+ */
+ typedef struct {
+- UpdateQueryS query;
+- HCOUNTER* counters;
+- int noOfCounters;
++ UpdateQueryS query;
++ HCOUNTER* counters;
++ int noOfCounters;
+ } MultipleCounterQueryS, *MultipleCounterQueryP;
+
+-/**
+- * Struct for the jvm process load counter.
++/*
++ * Struct for a PDH query with a single counter.
+ */
+ typedef struct {
+- UpdateQueryS query;
++ UpdateQueryS query;
+ HCOUNTER counter;
+ } SingleCounterQueryS, *SingleCounterQueryP;
+
+-static char* getProcessPDHHeader(void);
+
+-/**
+- * Currently available counters.
++typedef struct {
++ CRITICAL_SECTION cs;
++ DWORD owningThread;
++ DWORD recursionCount;
++} PdhCriticalSectionS, *PdhCriticalSectionP;
++
++static PdhCriticalSectionS initializationLock;
++
++static void InitializePdhCriticalSection(PdhCriticalSectionP criticalSection) {
++ assert(criticalSection);
++
++ InitializeCriticalSection(&criticalSection->cs);
++ criticalSection->owningThread = 0;
++ criticalSection->recursionCount = 0;
++}
++
++static void EnterPdhCriticalSection(PdhCriticalSectionP criticalSection) {
++ assert(criticalSection);
++
++ EnterCriticalSection(&criticalSection->cs);
++ criticalSection->recursionCount++;
++ if (!criticalSection->owningThread) {
++ criticalSection->owningThread = GetCurrentThreadId();
++ }
++}
++
++static void LeavePdhCriticalSection(PdhCriticalSectionP criticalSection) {
++ assert(criticalSection);
++ assert(GetCurrentThreadId() == criticalSection->owningThread);
++ assert(criticalSection->recursionCount >= 1);
++
++ criticalSection->recursionCount--;
++ if (!criticalSection->recursionCount) {
++ criticalSection->owningThread = 0;
++ }
++ LeaveCriticalSection(&criticalSection->cs);
++}
++
++/*
++ * INFO: Using PDH APIs Correctly in a Localized Language (Q287159)
++ * http://support.microsoft.com/default.aspx?scid=kb;EN-US;q287159
++ * The index value for the base system counters and objects like processor,
++ * process, thread, memory, and so forth are always the same irrespective
++ * of the localized version of the operating system or service pack installed.
++ * To find the correct index for an object or counter, inspect the registry key/value:
++ * [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009\Counter]
+ */
+-static SingleCounterQueryS cntCtxtSwitchRate;
+-static SingleCounterQueryS cntVirtualSize;
+-static SingleCounterQueryS cntProcLoad;
+-static SingleCounterQueryS cntProcSystemLoad;
+-static MultipleCounterQueryS multiCounterCPULoad;
++static const DWORD PDH_PROCESSOR_IDX = 238;
++static const DWORD PDH_PROCESSOR_TIME_IDX = 6;
++static const DWORD PDH_PROCESS_IDX = 230;
++static const DWORD PDH_ID_PROCESS_IDX = 784;
+
+-static CRITICAL_SECTION processHeaderLock;
+-static CRITICAL_SECTION initializationLock;
++/* useful pdh fmt's */
++static const char* const OBJECT_COUNTER_FMT = "\\%s\\%s";
++static const size_t OBJECT_COUNTER_FMT_LEN = 2;
++static const char* const OBJECT_WITH_INSTANCES_COUNTER_FMT = "\\%s(%s)\\%s";
++static const size_t OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN = 4;
++static const char* const PROCESS_OBJECT_INSTANCE_COUNTER_FMT = "\\%s(%s#%s)\\%s";
++static const size_t PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN = 5;
+
+-/**
+- * Initialize the perf module at startup.
++static const char* pdhProcessImageName = NULL; /* "java" */
++static char* pdhIDProcessCounterFmt = NULL; /* "\Process(java#%d)\ID Process" */
++
++static int numberOfJavaProcessesAtInitialization = 0;
++
++/*
++ * Currently used CPU queries/counters and variables
+ */
+-int
+-perfiInit(void)
+-{
+- InitializeCriticalSection(&processHeaderLock);
+- InitializeCriticalSection(&initializationLock);
++static SingleCounterQueryP processTotalCPULoad = NULL;
++static MultipleCounterQueryP multiCounterCPULoad = NULL;
++static double cpuFactor = .0;
++static DWORD numCpus = 0;
++
++/*
++ * Seems WinXP PDH returns PDH_MORE_DATA whenever we send in a NULL buffer.
++ * Let's just ignore it, since we make sure we have enough buffer anyway.
++ */
++static int
++pdhFail(PDH_STATUS pdhStat) {
++ return pdhStat != ERROR_SUCCESS && pdhStat != PDH_MORE_DATA;
++}
++
++static const char*
++allocateAndCopy(const char* const originalString) {
++ size_t len;
++ char* allocatedString;
++
++ assert(originalString);
++
++ len = strlen(originalString);
++
++ allocatedString = malloc(len + 1);
++
++ if (!allocatedString) {
++ return NULL;
++ }
++
++ strncpy(allocatedString, originalString, len);
++ allocatedString[len] = '\0';
++
++ return allocatedString;
++}
++
++/*
++ * Allocates memory into the supplied pointer and
++ * fills it with the localized PDH artifact description, if indexed correctly.
++ * Caller owns the memory from the point of returning from this function.
++ *
++ * @param index the PDH counter index as specified in the registry
++ * @param ppBuffer pointer to a char*.
++ * @return 0 if successful, negative on failure.
++ */
++static int
++lookupNameByIndex(DWORD index, char** ppBuffer) {
++ DWORD size;
++
++ assert(ppBuffer);
++
++ /* determine size needed */
++ if (PdhLookupPerfNameByIndex_i(NULL, index, NULL, &size) != PDH_MORE_DATA) {
++ /* invalid index? */
++ return -1;
++ }
++
++ *ppBuffer = malloc((size_t)size);
++
++ if (!*ppBuffer) {
++ return -1;
++ }
++
++ if (PdhLookupPerfNameByIndex_i(NULL, index, *ppBuffer, &size) != ERROR_SUCCESS) {
++ free(*ppBuffer);
++ *ppBuffer = NULL;
++ return -1;
++ }
++
++ /* windows vista does not null-terminate the string
++ * (although the docs says it will) */
++ (*ppBuffer)[size - 1] = '\0';
++
+ return 0;
+ }
+
+-/**
++/*
++* Construct a fully qualified PDH path
++*
++* @param objectName a PDH Object string representation (required)
++* @param counterName a PDH Counter string representation (required)
++* @param imageName a process image name string, ex. "java" (opt)
++* @param instance an instance string, ex. "0", "1", ... (opt)
++* @return the fully qualified PDH path.
++*
++* Caller will own the returned malloc:ed string
++*/
++static const char*
++makeFullCounterPath(const char* const objectName,
++ const char* const counterName,
++ const char* const imageName,
++ const char* const instance) {
++
++ size_t fullCounterPathLen;
++ char* fullCounterPath;
++
++ assert(objectName);
++ assert(counterName);
++
++ fullCounterPathLen = strlen(objectName);
++ fullCounterPathLen += strlen(counterName);
++
++ if (imageName) {
++ /*
++ * For paths using the "Process" Object.
++ *
++ * Examples:
++ * abstract: "\Process(imageName#instance)\Counter"
++ * actual: "\Process(java#2)\ID Process"
++ */
++ fullCounterPathLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
++ fullCounterPathLen += strlen(imageName);
++
++ /*
++ * imageName must be passed together with an associated
++ * instance "number" ("0", "1", "2", ...).
++ * This is required in order to create valid "Process" Object paths.
++ *
++ * Examples: "\Process(java#0)", \Process(java#1"), ...
++ */
++ assert(instance);
++
++ fullCounterPathLen += strlen(instance);
++
++ fullCounterPath = malloc(fullCounterPathLen + 1);
++
++ if (!fullCounterPath) {
++ return NULL;
++ }
++
++ _snprintf(fullCounterPath,
++ fullCounterPathLen,
++ PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
++ objectName,
++ imageName,
++ instance,
++ counterName);
++ } else {
++ if (instance) {
++ /*
++ * For paths where the Object has multiple instances.
++ *
++ * Examples:
++ * abstract: "\Object(instance)\Counter"
++ * actual: "\Processor(0)\% Privileged Time"
++ */
++ fullCounterPathLen += strlen(instance);
++ fullCounterPathLen += OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN;
++ } else {
++ /*
++ * For "normal" paths.
++ *
++ * Examples:
++ * abstract: "\Object\Counter"
++ * actual: "\Memory\Available Mbytes"
++ */
++ fullCounterPathLen += OBJECT_COUNTER_FMT_LEN;
++ }
++
++ fullCounterPath = malloc(fullCounterPathLen + 1);
++
++ if (!fullCounterPath) {
++ return NULL;
++ }
++
++ if (instance) {
++ _snprintf(fullCounterPath,
++ fullCounterPathLen,
++ OBJECT_WITH_INSTANCES_COUNTER_FMT,
++ objectName,
++ instance,
++ counterName);
++ } else {
++ _snprintf(fullCounterPath,
++ fullCounterPathLen,
++ OBJECT_COUNTER_FMT,
++ objectName,
++ counterName);
++ }
++ }
++
++ fullCounterPath[fullCounterPathLen] = '\0';
++
++ return fullCounterPath;
++}
++
++/*
++ * Resolves an index for a PDH artifact to
++ * a localized, malloc:ed string representation.
++ * Caller will own the returned malloc:ed string.
++ *
++ * @param pdhArtifactIndex PDH index
++ * @return malloc:ed string representation
++ * of the requested pdh artifact (localized).
++ * NULL on failure.
++ */
++static const char*
++getPdhLocalizedArtifact(DWORD pdhArtifactIndex) {
++ char* pdhLocalizedArtifactString;
++
++ if (lookupNameByIndex(pdhArtifactIndex,
++ &pdhLocalizedArtifactString) != 0) {
++ return NULL;
++ }
++
++ return pdhLocalizedArtifactString;
++}
++
++static void
++pdhCleanup(HQUERY* const query, HCOUNTER* const counter) {
++ if (counter && *counter) {
++ PdhRemoveCounter_i(*counter);
++ *counter = NULL;
++ }
++ if (query && *query) {
++ PdhCloseQuery_i(*query);
++ *query = NULL;
++ }
++}
++
++static void
++destroySingleCounter(SingleCounterQueryP counterQuery) {
++ if (counterQuery) {
++ pdhCleanup(&counterQuery->query.query, &counterQuery->counter);
++ }
++}
++
++static void
++destroyMultiCounter(MultipleCounterQueryP multiCounterQuery) {
++ int i;
++ if (multiCounterQuery) {
++ if (multiCounterQuery->counters) {
++ for (i = 0; i < multiCounterQuery->noOfCounters; i++) {
++ pdhCleanup(NULL, &multiCounterQuery->counters[i]);
++ }
++ free(multiCounterQuery->counters);
++ multiCounterQuery->counters = NULL;
++ }
++ pdhCleanup(&multiCounterQuery->query.query, NULL);
++ }
++}
++
++static int
++openQuery(HQUERY* const query) {
++ assert(query);
++
++ if (PdhOpenQuery_i(NULL, 0, query) != ERROR_SUCCESS) {
++ return -1;
++ }
++
++ return 0;
++}
++
++static int
++addCounter(HQUERY query,
++ const char* const fullCounterPath,
++ HCOUNTER* const counter) {
++
++ assert(fullCounterPath);
++ assert(counter);
++
++ if (PdhAddCounter_i(query,
++ fullCounterPath,
++ 0,
++ counter) != ERROR_SUCCESS) {
++ return -1;
++ }
++
++ return 0;
++}
++
++/*
++ * Sets up the supplied SingleCounterQuery to listen for the specified counter.
++ *
++ * @param counterQuery the counter query to set up.
++ * @param fullCounterPath the string specifying the full path to the counter.
++ * @returns 0 if successful, negative on failure.
++ */
++static int
++initializeSingleCounterQuery(SingleCounterQueryP counterQuery,
++ const char* const fullCounterPath) {
++ assert(counterQuery);
++ assert(fullCounterPath);
++
++ if (openQuery(&counterQuery->query.query) == 0) {
++ if (addCounter(counterQuery->query.query,
++ fullCounterPath,
++ &counterQuery->counter) == 0) {
++ return 0;
++ }
++ }
++
++ return -1;
++}
++
++/*
++ * Sets up a SingleCounterQuery
++ *
++ * param counter the counter query to set up.
++ * param localizedObject string representing the PDH object to query
++ * param localizedCounter string representing the PDH counter to query
++ * param processImageName if the counter query needs the process image name ("java")
++ * param instance if the counter has instances, this is the instance ("\Processor(0)\")
++ where 0 is the instance
++ * param firstSampleOnInit for counters that need two queries to yield their values,
++ the first query can be issued just after initialization
++ *
++ * @returns 0 if successful, negative on failure.
++ */
++static int
++initializeSingleCounter(SingleCounterQueryP const counter,
++ const char* const localizedObject,
++ const char* const localizedCounter,
++ const char* const processImageName,
++ const char* const instance,
++ BOOL firstSampleOnInit) {
++ int retValue = -1;
++
++ const char* fullCounterPath = makeFullCounterPath(localizedObject,
++ localizedCounter,
++ processImageName,
++ instance);
++
++ if (fullCounterPath) {
++
++ assert(counter);
++
++ if (initializeSingleCounterQuery(counter, fullCounterPath) == 0) {
++ /*
++ * According to the MSDN documentation, rate counters must be read twice:
++ *
++ * "Obtaining the value of rate counters such as Page faults/sec requires that
++ * PdhCollectQueryData be called twice, with a specific time interval between
++ * the two calls, before calling PdhGetFormattedCounterValue. Call Sleep to
++ * implement the waiting period between the two calls to PdhCollectQueryData."
++ *
++ * Take the first sample here already to allow for the next (first) "real" sample
++ * to succeed.
++ */
++ if (firstSampleOnInit) {
++ PdhCollectQueryData_i(counter->query.query);
++ }
++
++ retValue = 0;
++ }
++ free((char*)fullCounterPath);
++ }
++
++ return retValue;
++}
++
++static void
++perfInit(void) {
++ InitializePdhCriticalSection(&initializationLock);
++}
++
++static int
++getProcessID() {
++ static int myPid = 0;
++ if (0 == myPid) {
++ myPid = _getpid();
++ }
++ return myPid;
++}
++
++/*
++ * Working against the Process object and it's related counters is inherently problematic
++ * when using the PDH API:
++ *
++ * For PDH, a process is not primarily identified by it's process id,
++ * but with a sequential number, for example \Process(java#0), \Process(java#1), ....
++ * The really bad part is that this list is reset as soon as one process exits:
++ * If \Process(java#1) exits, \Process(java#3) now becomes \Process(java#2) etc.
++ *
++ * The PDH query api requires a process identifier to be submitted when registering
++ * a query, but as soon as the list resets, the query is invalidated (since the name
++ * changed).
++ *
++ * Solution:
++ * The #number identifier for a Process query can only decrease after process creation.
++ *
++ * Therefore we create an array of counter queries for all process object instances
++ * up to and including ourselves:
++ *
++ * Ex. we come in as third process instance (java#2), we then create and register
++ * queries for the following Process object instances:
++ * java#0, java#1, java#2
++ *
++ * currentQueryIndexForProcess() keeps track of the current "correct" query
++ * (in order to keep this index valid when the list resets from underneath,
++ * ensure to call getCurrentQueryIndexForProcess() before every query involving
++ * Process object instance data).
++ */
++static int
++currentQueryIndexForProcess(void) {
++ HQUERY tmpQuery = NULL;
++ HCOUNTER handleCounter = NULL;
++ int retValue = -1;
++
++ assert(pdhProcessImageName);
++ assert(pdhIDProcessCounterFmt);
++
++ if (openQuery(&tmpQuery) == 0) {
++ int index;
++
++ /* iterate over all instance indexes and try to find our own pid */
++ for (index = 0; index < INT_MAX; ++index) {
++ char fullIDProcessCounterPath[MAX_PATH];
++ PDH_FMT_COUNTERVALUE counterValue;
++ PDH_STATUS res;
++
++ _snprintf(fullIDProcessCounterPath,
++ MAX_PATH,
++ pdhIDProcessCounterFmt,
++ index);
++
++ if (addCounter(tmpQuery, fullIDProcessCounterPath, &handleCounter) != 0) {
++ break;
++ }
++
++ res = PdhCollectQueryData_i(tmpQuery);
++
++ if (PDH_INVALID_HANDLE == res || PDH_NO_DATA == res) {
++ break;
++ }
++
++ PdhGetFormattedCounterValue_i(handleCounter,
++ PDH_FMT_LONG,
++ NULL,
++ &counterValue);
++ /*
++ * This check seems to be needed for Win2k SMP boxes, since
++ * they for some reason don't return PDH_NO_DATA for non existing
++ * counters.
++ */
++ if (counterValue.CStatus != PDH_CSTATUS_VALID_DATA) {
++ break;
++ }
++
++ if ((LONG)getProcessID() == counterValue.longValue) {
++ retValue = index;
++ break;
++ }
++ }
++ }
++
++ pdhCleanup(&tmpQuery, &handleCounter);
++
++ return retValue;
++}
++
++/*
++ * If successful, returns the #index corresponding to our PID
++ * as resolved by the pdh query:
++ * "\Process(java#index)\ID Process" (or localized equivalent)
++ *
++ * This function should be called before attempting to read
++ * from any Process related counter(s), and the return value
++ * is the index to be used for indexing an array of Process object query's:
++ *
++ * Example:
++ * processTotalCPULoad[currentQueryIndex].query
++ *
++ * Returns -1 on failure.
++ */
++static int
++getCurrentQueryIndexForProcess() {
++ int currentQueryIndex = currentQueryIndexForProcess();
++
++ assert(currentQueryIndex >= 0 &&
++ currentQueryIndex < numberOfJavaProcessesAtInitialization);
++
++ return currentQueryIndex;
++}
++
++/*
++ * Returns the PDH string identifying the current process image name.
++ * Use this name as a qualifier when getting counters from the PDH Process Object
++ * representing your process.
++
++ * Example:
++ * "\Process(java#0)\Virtual Bytes" - where "java" is the PDH process
++ * image name.
++ *
++ * Please note that the process image name is not necessarily "java",
++ * hence the use of GetModuleFileName() to detect the process image name.
++ *
++ * @return the process image name to be used when retrieving
++ * PDH counters from the current process. The caller will
++ own the returned malloc:ed string. NULL if failure.
++ */
++static const char*
++getPdhProcessImageName() {
++ char moduleName[MAX_PATH];
++ char* processImageName;
++ char* dotPos;
++
++ // Find our module name and use it to extract the image name used by PDH
++ DWORD getmfnReturn = GetModuleFileName(NULL, moduleName, sizeof(moduleName));
++
++ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
++ return NULL;
++ }
++
++ if (getmfnReturn >= MAX_PATH || 0 == getmfnReturn) {
++ return NULL;
++ }
++
++ processImageName = strrchr(moduleName, '\\'); //drop path
++ processImageName++; //skip slash
++ dotPos = strrchr(processImageName, '.'); //drop .exe
++ dotPos[0] = '\0';
++
++ return allocateAndCopy(processImageName);
++}
++
++/*
++ * Sets up the supplied MultipleCounterQuery to check on the processors via PDH CPU counters.
++ * TODO: Refactor and prettify as with the the SingleCounter queries
++ * if more MultipleCounterQueries are discovered/needed.
++ *
++ * @param multiCounterCPULoad a pointer to a MultipleCounterQueryS, will be filled in with
++ * the necessary info to check the PDH processor counters.
++ * @return 0 if successful, negative on failure.
++ */
++static int
++initializeMultipleCounterForCPUs(MultipleCounterQueryP multiCounterCPULoad) {
++ DWORD cSize = 0;
++ DWORD iSize = 0;
++ DWORD pCount;
++ DWORD index;
++ char* processor = NULL; //'Processor' == PDH_PROCESSOR_IDX
++ char* time = NULL; //'Time' == PDH_PROCESSOR_TIME_IDX
++ char* instances = NULL;
++ char* tmp;
++ int retValue = -1;
++ PDH_STATUS pdhStat;
++
++ if (lookupNameByIndex(PDH_PROCESSOR_IDX, &processor) != 0) {
++ goto end;
++ }
++
++ if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX, &time) != 0) {
++ goto end;
++ }
++
++ //ok, now we have enough to enumerate all processors.
++ pdhStat = PdhEnumObjectItems_i(
++ NULL, // reserved
++ NULL, // local machine
++ processor, // object to enumerate
++ NULL, // pass in NULL buffers
++ &cSize, // and 0 length to get
++ NULL, // required size
++ &iSize, // of the buffers in chars
++ PERF_DETAIL_WIZARD, // counter detail level
++ 0);
++
++ if (pdhFail(pdhStat)) {
++ goto end;
++ }
++
++ instances = calloc(iSize, 1);
++
++ if (!instances) {
++ goto end;
++ }
++
++ cSize = 0;
++
++ pdhStat = PdhEnumObjectItems_i(
++ NULL, // reserved
++ NULL, // local machine
++ processor, // object to enumerate
++ NULL, // pass in NULL buffers
++ &cSize,
++ instances, // now allocated to be filled in
++ &iSize, // and size is known
++ PERF_DETAIL_WIZARD, // counter detail level
++ 0);
++
++ if (pdhFail(pdhStat)) {
++ goto end;
++ }
++
++ // enumerate the Processor instances ("\Processor(0)", "\Processor(1)", ..., "\Processor(_Total)")
++ for (pCount = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], pCount++);
++
++ assert(pCount == numCpus+1);
++
++ //ok, we now have the number of Processor instances - allocate an HCOUNTER for each
++ multiCounterCPULoad->counters = (HCOUNTER*)malloc(pCount * sizeof(HCOUNTER));
++
++ if (!multiCounterCPULoad->counters) {
++ goto end;
++ }
++
++ multiCounterCPULoad->noOfCounters = pCount;
++
++ if (openQuery(&multiCounterCPULoad->query.query) != 0) {
++ goto end;
++ }
++
++ // fetch instance and register its corresponding HCOUNTER with the query
++ for (index = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], ++index) {
++ const char* const fullCounterPath = makeFullCounterPath(processor, time, NULL, tmp);
++
++ if (!fullCounterPath) {
++ goto end;
++ }
++
++ retValue = addCounter(multiCounterCPULoad->query.query,
++ fullCounterPath,
++ &multiCounterCPULoad->counters[index]);
++
++ free((char*)fullCounterPath);
++
++ if (retValue != 0) {
++ goto end;
++ }
++ }
++
++ // Query once to initialize the counters which require at least two samples
++ // (like the % CPU usage) to calculate correctly.
++ PdhCollectQueryData_i(multiCounterCPULoad->query.query);
++
++ end:
++ if (processor) {
++ free(processor);
++ }
++
++ if (time) {
++ free(time);
++ }
++
++ if (instances) {
++ free(instances);
++ }
++
++ return retValue;
++}
++
++/*
+ * Dynamically sets up function pointers to the PDH library.
+ *
+- * @return CONFIG_SUCCESSFUL on success, negative on failure.
++ * @param h HMODULE for the PDH library
++ * @return 0 on success, negative on failure.
+ */
+ static int
+-get_functions(HMODULE h, char *ebuf, size_t elen) {
+- // The 'A' at the end means the ANSI (not the UNICODE) vesions of the methods
++bindPdhFunctionPointers(HMODULE h) {
++ assert(h);
++ assert(GetCurrentThreadId() == initializationLock.owningThread);
++
++ /* The 'A' at the end means the ANSI (not the UNICODE) vesions of the methods */
+ PdhAddCounter_i = (PdhAddCounterFunc)GetProcAddress(h, "PdhAddCounterA");
+ PdhOpenQuery_i = (PdhOpenQueryFunc)GetProcAddress(h, "PdhOpenQueryA");
+ PdhCloseQuery_i = (PdhCloseQueryFunc)GetProcAddress(h, "PdhCloseQuery");
+@@ -312,42 +968,41 @@
+ PdhEnumObjectItems_i = (PdhEnumObjectItemsFunc)GetProcAddress(h, "PdhEnumObjectItemsA");
+ PdhRemoveCounter_i = (PdhRemoveCounterFunc)GetProcAddress(h, "PdhRemoveCounter");
+ PdhLookupPerfNameByIndex_i = (PdhLookupPerfNameByIndexFunc)GetProcAddress(h, "PdhLookupPerfNameByIndexA");
+- PdhMakeCounterPath_i = (PdhMakeCounterPathFunc)GetProcAddress(h, "PdhMakeCounterPathA");
+
+- if (PdhAddCounter_i == NULL || PdhOpenQuery_i == NULL ||
+- PdhCloseQuery_i == NULL || PdhCollectQueryData_i == NULL ||
+- PdhGetFormattedCounterValue_i == NULL || PdhEnumObjectItems_i == NULL ||
+- PdhRemoveCounter_i == NULL || PdhLookupPerfNameByIndex_i == NULL || PdhMakeCounterPath_i == NULL)
++ if (!PdhAddCounter_i || !PdhOpenQuery_i ||
++ !PdhCloseQuery_i || !PdhCollectQueryData_i ||
++ !PdhGetFormattedCounterValue_i || !PdhEnumObjectItems_i ||
++ !PdhRemoveCounter_i || !PdhLookupPerfNameByIndex_i)
+ {
+- _snprintf(ebuf, elen, "Required method could not be found.");
+ return -1;
+ }
+- return CONFIG_SUCCESSFUL;
++ return 0;
+ }
+
+-/**
++/*
+ * Returns the counter value as a double for the specified query.
+ * Will collect the query data and update the counter values as necessary.
+ *
+ * @param query the query to update (if needed).
+- * @param c the counter to read.
++ * @param c the counter to read.
+ * @param value where to store the formatted value.
+ * @param format the format to use (i.e. PDH_FMT_DOUBLE, PDH_FMT_LONG etc)
+- * @return CONFIG_SUCCESSFUL if no error
++ * @return 0 if no error
+ * -1 if PdhCollectQueryData fails
+ * -2 if PdhGetFormattedCounterValue fails
+ */
+ static int
+ getPerformanceData(UpdateQueryP query, HCOUNTER c, PDH_FMT_COUNTERVALUE* value, DWORD format) {
+- clock_t now;
+- now = clock();
++ clock_t now = clock();
+
+- // Need to limit how often we update the query
+- // to mimise the heisenberg effect.
+- // (PDH behaves erratically if the counters are
+- // queried too often, especially counters that
+- // store and use values from two consecutive updates,
+- // like cpu load.)
++ /*
++ * Need to limit how often we update the query
++ * to minimize the Heisenberg effect.
++ * (PDH behaves erratically if the counters are
++ * queried too often, especially counters that
++ * store and use values from two consecutive updates,
++ * like cpu load.)
++ */
+ if (now - query->lastUpdate > MIN_UPDATE_INTERVAL) {
+ if (PdhCollectQueryData_i(query->query) != ERROR_SUCCESS) {
+ return -1;
+@@ -358,500 +1013,308 @@
+ if (PdhGetFormattedCounterValue_i(c, format, NULL, value) != ERROR_SUCCESS) {
+ return -2;
+ }
+- return CONFIG_SUCCESSFUL;
++
++ return 0;
+ }
+
+-/**
+- * Places the resolved counter name of the counter at the specified index in the
+- * supplied buffer. There must be enough space in the buffer to hold the counter name.
+- *
+- * @param index the counter index as specified in the registry.
+- * @param buf the buffer in which to place the counter name.
+- * @param size the size of the counter name buffer.
+- * @param ebuf the error message buffer.
+- * @param elen the length of the error buffer.
+- * @return CONFIG_SUCCESSFUL if successful, negative on failure.
+- */
+ static int
+-find_name(DWORD index, char *buf, DWORD size) {
+- PDH_STATUS res;
++allocateAndInitializePdhConstants() {
++ const char* pdhLocalizedProcessObject = NULL;
++ const char* pdhLocalizedIDProcessCounter = NULL;
++ size_t pdhIDProcessCounterFmtLen;
++ int currentQueryIndex;
++ int retValue = -1;
+
+- if ((res = PdhLookupPerfNameByIndex_i(NULL, index, buf, &size)) != ERROR_SUCCESS) {
++ assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+- /* printf("Could not open counter %d: error=0x%08x", index, res); */
+- /* if (res == PDH_CSTATUS_NO_MACHINE) { */
+- /* printf("User probably does not have sufficient privileges to use"); */
+- /* printf("performance counters. If you are running on Windows 2003"); */
+- /* printf("or Windows Vista, make sure the user is in the"); */
+- /* printf("Performance Logs user group."); */
+- /* } */
++ assert(!pdhProcessImageName);
++ pdhProcessImageName = getPdhProcessImageName();
++ if (!pdhProcessImageName) {
++ goto end;
++ }
++
++ pdhLocalizedProcessObject = getPdhLocalizedArtifact(PDH_PROCESS_IDX);
++ if (!pdhLocalizedProcessObject) {
++ goto end;
++ }
++
++ pdhLocalizedIDProcessCounter = getPdhLocalizedArtifact(PDH_ID_PROCESS_IDX);
++ if (!pdhLocalizedIDProcessCounter) {
++ goto end;
++ }
++
++ assert(!pdhIDProcessCounterFmt);
++
++ pdhIDProcessCounterFmtLen = strlen(pdhProcessImageName);
++ pdhIDProcessCounterFmtLen += strlen(pdhLocalizedProcessObject);
++ pdhIDProcessCounterFmtLen += strlen(pdhLocalizedIDProcessCounter);
++ pdhIDProcessCounterFmtLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
++ pdhIDProcessCounterFmtLen += 2; // "%d"
++
++ assert(pdhIDProcessCounterFmtLen < MAX_PATH);
++ pdhIDProcessCounterFmt = malloc(pdhIDProcessCounterFmtLen + 1);
++ if (!pdhIDProcessCounterFmt) {
++ goto end;
++ }
++
++ /* "\Process(java#%d)\ID Process" */
++ _snprintf(pdhIDProcessCounterFmt,
++ pdhIDProcessCounterFmtLen,
++ PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
++ pdhLocalizedProcessObject,
++ pdhProcessImageName,
++ "%d",
++ pdhLocalizedIDProcessCounter);
++
++ pdhIDProcessCounterFmt[pdhIDProcessCounterFmtLen] = '\0';
++
++ assert(0 == numberOfJavaProcessesAtInitialization);
++ currentQueryIndex = currentQueryIndexForProcess();
++ if (-1 == currentQueryIndex) {
++ goto end;
++ }
++
++ numberOfJavaProcessesAtInitialization = currentQueryIndex + 1;
++ assert(numberOfJavaProcessesAtInitialization >= 1);
++
++ retValue = 0;
++
++ end:
++
++ if (pdhLocalizedProcessObject) {
++ free((char*)pdhLocalizedProcessObject);
++ }
++
++ if (pdhLocalizedIDProcessCounter) {
++ free((char*)pdhLocalizedIDProcessCounter);
++ }
++
++ return retValue;
++}
++
++static void
++deallocatePdhConstants() {
++ assert(GetCurrentThreadId() == initializationLock.owningThread);
++
++ if (pdhProcessImageName) {
++ free((char*)pdhProcessImageName);
++ pdhProcessImageName = NULL;
++ }
++
++ if (pdhIDProcessCounterFmt) {
++ free(pdhIDProcessCounterFmt);
++ pdhIDProcessCounterFmt = NULL;
++ }
++
++ numberOfJavaProcessesAtInitialization = 0;
++}
++
++static int
++initializeCPUCounters() {
++ SYSTEM_INFO si;
++ char* localizedProcessObject;
++ char* localizedProcessorTimeCounter;
++ int i;
++ int retValue = -1;
++
++ assert(GetCurrentThreadId() == initializationLock.owningThread);
++
++ assert(0 == numCpus);
++ GetSystemInfo(&si);
++ numCpus = si.dwNumberOfProcessors;
++ assert(numCpus >= 1);
++
++ /* Initialize the denominator for the jvm load calculations */
++ assert(.0 == cpuFactor);
++ cpuFactor = numCpus * 100;
++
++ if (lookupNameByIndex(PDH_PROCESS_IDX,
++ &localizedProcessObject) == 0) {
++
++ if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX,
++ &localizedProcessorTimeCounter) == 0) {
++
++ assert(processTotalCPULoad);
++ assert(pdhProcessImageName);
++
++ for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) {
++ char instanceIndexBuffer[32];
++ retValue = initializeSingleCounter(&processTotalCPULoad[i],
++ localizedProcessObject,
++ localizedProcessorTimeCounter,
++ pdhProcessImageName,
++ itoa(i, instanceIndexBuffer, 10),
++ TRUE);
++ if (retValue != 0) {
++ break;
++ }
++ }
++ free(localizedProcessorTimeCounter);
++ }
++ free(localizedProcessObject);
++ }
++
++ if (retValue != 0) {
+ return -1;
+ }
+
+- if (size == 0) {
+- /* printf("Failed to get counter name for %d: empty string", index); */
++ assert(multiCounterCPULoad);
++ return initializeMultipleCounterForCPUs(multiCounterCPULoad);
++}
++
++static void
++deallocateCPUCounters() {
++ int i;
++
++ assert(GetCurrentThreadId() == initializationLock.owningThread);
++
++ if (processTotalCPULoad) {
++ for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) {
++ destroySingleCounter(&processTotalCPULoad[i]);
++ }
++ free(processTotalCPULoad);
++ processTotalCPULoad = NULL;
++ }
++
++ if (multiCounterCPULoad) {
++ destroyMultiCounter(multiCounterCPULoad);
++ free(multiCounterCPULoad);
++ multiCounterCPULoad = NULL;
++ }
++
++ cpuFactor = .0;
++ numCpus = 0;
++}
++
++static void
++pdhInitErrorHandler(HMODULE h) {
++ assert(GetCurrentThreadId() == initializationLock.owningThread);
++
++ deallocatePdhConstants();
++
++ if (h) {
++ FreeLibrary(h);
++ }
++}
++
++/*
++ * Helper to initialize the PDH library, function pointers and constants.
++ *
++ * @return 0 if successful, negative on failure.
++ */
++static int
++pdhInit() {
++ static BOOL initialized = FALSE;
++ int retValue;
++
++ if (initialized) {
++ return 0;
++ }
++
++ retValue = 0;
++
++ EnterPdhCriticalSection(&initializationLock); {
++ if (!initialized) {
++ HMODULE h = NULL;
++ if ((h = LoadLibrary("pdh.dll")) == NULL) {
++ retValue = -1;
++ } else if (bindPdhFunctionPointers(h) < 0) {
++ retValue = -1;
++ } else if (allocateAndInitializePdhConstants() < 0) {
++ retValue = -1;
++ }
++
++ if (0 == retValue) {
++ initialized = TRUE;
++ } else {
++ pdhInitErrorHandler(h);
++ }
++ }
++ } LeavePdhCriticalSection(&initializationLock);
++
++ return retValue;
++}
++
++static int
++allocateCPUCounters() {
++ assert(GetCurrentThreadId() == initializationLock.owningThread);
++ assert(numberOfJavaProcessesAtInitialization >= 1);
++ assert(!processTotalCPULoad);
++ assert(!multiCounterCPULoad);
++
++ /*
++ * Create an array of Process object queries, for each instance
++ * up to and including our own (java#0, java#1, java#2, ...).
++ */
++ processTotalCPULoad = calloc(numberOfJavaProcessesAtInitialization,
++ sizeof(SingleCounterQueryS));
++
++ if (!processTotalCPULoad) {
+ return -1;
+ }
+
+- // windows vista does not null-terminate the string (allthough the docs says it will)
+- buf[size - 1] = '\0';
+- return CONFIG_SUCCESSFUL;
+-}
++ multiCounterCPULoad = calloc(1, sizeof(MultipleCounterQueryS));
+
+-/**
+- * Sets up the supplied SingleCounterQuery to listen for the specified counter.
+- * initPDH() must have been run prior to calling this function!
+- *
+- * @param counterQuery the counter query to set up.
+- * @param counterString the string specifying the path to the counter.
+- * @param ebuf the error buffer.
+- * @param elen the length of the error buffer.
+- * @returns CONFIG_SUCCESSFUL if successful, negative on failure.
+- */
+-static int
+-initSingleCounterQuery(SingleCounterQueryP counterQuery, char *counterString) {
+- if (PdhOpenQuery_i(NULL, 0, &counterQuery->query.query) != ERROR_SUCCESS) {
+- /* printf("Could not open query for %s", counterString); */
++ if (!multiCounterCPULoad) {
+ return -1;
+ }
+- if (PdhAddCounter_i(counterQuery->query.query, counterString, 0, &counterQuery->counter) != ERROR_SUCCESS) {
+- /* printf("Could not add counter %s for query", counterString); */
+- if (counterQuery->counter != NULL) {
+- PdhRemoveCounter_i(counterQuery->counter);
+- }
+- if (counterQuery->query.query != NULL) {
+- PdhCloseQuery_i(counterQuery->query.query);
+- }
+- memset(counterQuery, 0, sizeof(SingleCounterQueryS));
+- return -1;
+- }
+- return CONFIG_SUCCESSFUL;
+-}
+
+-/**
+- * Sets up the supplied SingleCounterQuery to listen for the time spent
+- * by the HotSpot process.
+- *
+- * @param counterQuery the counter query to set up as a process counter.
+- * @param ebuf the error buffer.
+- * @param elen the length of the error buffer.
+- * @returns CONFIG_SUCCESSFUL if successful, negative on failure.
+- */
+-static int
+-initProcLoadCounter(void) {
+- char time[COUNTER_BUF_SIZE];
+- char counter[COUNTER_BUF_SIZE*2];
+-
+- if (find_name(PDH_PROCESSOR_TIME_IDX, time, sizeof(time)-1) < 0) {
+- return -1;
+- }
+- _snprintf(counter, sizeof(counter)-1, "%s\\%s", getProcessPDHHeader(), time);
+- return initSingleCounterQuery(&cntProcLoad, counter);
++ return 0;
+ }
+
+ static int
+-initProcSystemLoadCounter(void) {
+- char time[COUNTER_BUF_SIZE];
+- char counter[COUNTER_BUF_SIZE*2];
++initializePdhCPUCounters() {
++ static BOOL initialized = FALSE;
++ int retValue;
+
+- if (find_name(PDH_PRIV_PROCESSOR_TIME_IDX, time, sizeof(time)-1) < 0) {
+- return -1;
++ if (initialized) {
++ return 0;
+ }
+- _snprintf(counter, sizeof(counter)-1, "%s\\%s", getProcessPDHHeader(), time);
+- return initSingleCounterQuery(&cntProcSystemLoad, counter);
++
++ retValue = 0;
++
++ EnterPdhCriticalSection(&initializationLock); {
++ if (!initialized) {
++ if (pdhInit() < 0) {
++ retValue = -1;
++ } else if (allocateCPUCounters() < 0) {
++ retValue = -1;
++ } else if (initializeCPUCounters() < 0) {
++ retValue = -1;
++ }
++
++ if (0 == retValue) {
++ initialized = TRUE;
++ } else {
++ deallocateCPUCounters();
++ }
++ }
++ } LeavePdhCriticalSection(&initializationLock);
++
++ return retValue;
+ }
+
+-/**
+- * Sets up the supplied MultipleCounterQuery to check on the processors.
+- * (Comment: Refactor and prettify as with the the SingleCounter queries
+- * if more MultipleCounterQueries are discovered.)
+- *
+- * initPDH() must have been run prior to calling this function.
+- *
+- * @param multiQuery a pointer to a MultipleCounterQueryS, will be filled in with
+- * the necessary info to check the PDH processor counters.
+- * @return CONFIG_SUCCESSFUL if successful, negative on failure.
+- */
+ static int
+-initProcessorCounters(void) {
+- char processor[COUNTER_BUF_SIZE]; //'Processor' == #238
+- char time[COUNTER_BUF_SIZE]; //'Time' == 6
+- DWORD c_size, i_size;
+- HQUERY tmpQuery;
+- DWORD i, p_count;
+- BOOL error;
+- char *instances, *tmp;
+- PDH_STATUS pdhStat;
+-
+- c_size = i_size = 0;
+- tmpQuery = NULL;
+- error = false;
+-
+- // This __try / __except stuff is there since Windows 2000 beta (or so) sometimes triggered
+- // an access violation when the user had insufficient privileges to use the performance
+- // counters. This was previously guarded by a very ugly piece of code which disabled the
+- // global trap handling in JRockit. Don't know if this really is needed anymore, but otoh,
+- // if we keep it we don't crash on Win2k beta. /Ihse, 2005-05-30
+- __try {
+- if (find_name(PDH_PROCESSOR_IDX, processor, sizeof(processor)-1) < 0) {
+- return -1;
+- }
+- } __except (EXCEPTION_EXECUTE_HANDLER) { // We'll catch all exceptions here.
+- /* printf("User does not have sufficient privileges to use performance counters"); */
+- return -1;
+- }
+-
+- if (find_name(PDH_PROCESSOR_TIME_IDX, time, sizeof(time)-1) < 0) {
+- return -1;
+- }
+- //ok, now we have enough to enumerate all processors.
+- pdhStat = PdhEnumObjectItems_i (
+- NULL, // reserved
+- NULL, // local machine
+- processor, // object to enumerate
+- NULL, // pass in NULL buffers
+- &c_size, // and 0 length to get
+- NULL, // required size
+- &i_size, // of the buffers in chars
+- PERF_DETAIL_WIZARD, // counter detail level
+- 0);
+- if (pdh_fail(pdhStat)) {
+- /* printf("could not enumerate processors (1) error=%d", pdhStat); */
+- return -1;
+- }
+-
+- // use calloc because windows vista does not null terminate the instance names (allthough the docs says it will)
+- instances = calloc(i_size, 1);
+- if (instances == NULL) {
+- /* printf("could not allocate memory (1) %d bytes", i_size); */
+- error = true;
+- goto end;
+- }
+-
+- c_size = 0;
+- pdhStat = PdhEnumObjectItems_i (
+- NULL, // reserved
+- NULL, // local machine
+- processor, // object to enumerate
+- NULL, // pass in NULL buffers
+- &c_size, // and 0 length to get
+- instances, // required size
+- &i_size, // of the buffers in chars
+- PERF_DETAIL_WIZARD, // counter detail level
+- 0);
+-
+- if (pdh_fail(pdhStat)) {
+- /* printf("could not enumerate processors (2) error=%d", pdhStat); */
+- error = true;
+- goto end;
+- }
+- //count perf count instances.
+- for (p_count = 0, tmp = instances; *tmp != 0; tmp = &tmp[lstrlen(tmp)+1], p_count++);
+-
+- //is this correct for HT?
+- assert(p_count == num_cpus+1);
+-
+- //ok, have number of perf counters.
+- multiCounterCPULoad.counters = calloc(p_count, sizeof(HCOUNTER));
+- if (multiCounterCPULoad.counters == NULL) {
+- /* printf("could not allocate memory (2) count=%d", p_count); */
+- error = true;
+- goto end;
+- }
+-
+- multiCounterCPULoad.noOfCounters = p_count;
+-
+- if (PdhOpenQuery_i(NULL, 0, &multiCounterCPULoad.query.query) != ERROR_SUCCESS) {
+- /* printf("could not create query"); */
+- error = true;
+- goto end;
+- }
+- //now, fetch the counters.
+- for (i = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[lstrlen(tmp)+1], i++) {
+- char counter[2*COUNTER_BUF_SIZE];
+-
+- _snprintf(counter, sizeof(counter)-1, "\\%s(%s)\\%s", processor, tmp, time);
+-
+- if (PdhAddCounter_i(multiCounterCPULoad.query.query, counter, 0, &multiCounterCPULoad.counters[i]) != ERROR_SUCCESS) {
+- /* printf("error adding processor counter %s", counter); */
+- error = true;
+- goto end;
+- }
+- }
+-
+- free(instances);
+- instances = NULL;
+-
+- // Query once to initialize the counters needing at least two queries
+- // (like the % CPU usage) to calculate correctly.
+- if (PdhCollectQueryData_i(multiCounterCPULoad.query.query) != ERROR_SUCCESS)
+- error = true;
+-
+- end:
+- if (instances != NULL) {
+- free(instances);
+- }
+- if (tmpQuery != NULL) {
+- PdhCloseQuery_i(tmpQuery);
+- }
+- if (error) {
+- int i;
+-
+- if (multiCounterCPULoad.counters != NULL) {
+- for (i = 0; i < multiCounterCPULoad.noOfCounters; i++) {
+- if (multiCounterCPULoad.counters[i] != NULL) {
+- PdhRemoveCounter_i(multiCounterCPULoad.counters[i]);
+- }
+- }
+- free(multiCounterCPULoad.counters[i]);
+- }
+- if (multiCounterCPULoad.query.query != NULL) {
+- PdhCloseQuery_i(multiCounterCPULoad.query.query);
+- }
+- memset(&multiCounterCPULoad, 0, sizeof(MultipleCounterQueryS));
+- return -1;
+- }
+- return CONFIG_SUCCESSFUL;
++perfCPUInit() {
++ return initializePdhCPUCounters();
+ }
+
+-/**
+- * Help function that initializes the PDH process header for the JRockit process.
+- * (You should probably use getProcessPDHHeader() instead!)
+- *
+- * initPDH() must have been run prior to calling this function.
+- *
+- * @param ebuf the error buffer.
+- * @param elen the length of the error buffer.
+- *
+- * @return the PDH instance description corresponding to the JVM process.
+- */
+-static char*
+-initProcessPDHHeader(void) {
+- static char hotspotheader[2*COUNTER_BUF_SIZE];
++static double
++perfGetProcessCPULoad() {
++ PDH_FMT_COUNTERVALUE cv;
++ int currentQueryIndex;
+
+- char counter[2*COUNTER_BUF_SIZE];
+- char processes[COUNTER_BUF_SIZE]; //'Process' == #230
+- char pid[COUNTER_BUF_SIZE]; //'ID Process' == 784
+- char module_name[MAX_PATH];
+- PDH_STATUS pdhStat;
+- DWORD c_size = 0, i_size = 0;
+- HQUERY tmpQuery = NULL;
+- int i, myPid = _getpid();
+- BOOL error = false;
+- char *instances, *tmp, *instance_name, *dot_pos;
+-
+- tmpQuery = NULL;
+- myPid = _getpid();
+- error = false;
+-
+- if (find_name(PDH_PROCESS_IDX, processes, sizeof(processes) - 1) < 0) {
+- return NULL;
+- }
+-
+- if (find_name(PDH_ID_PROCESS_IDX, pid, sizeof(pid) - 1) < 0) {
+- return NULL;
+- }
+- //time is same.
+-
+- c_size = 0;
+- i_size = 0;
+-
+- pdhStat = PdhEnumObjectItems_i (
+- NULL, // reserved
+- NULL, // local machine
+- processes, // object to enumerate
+- NULL, // pass in NULL buffers
+- &c_size, // and 0 length to get
+- NULL, // required size
+- &i_size, // of the buffers in chars
+- PERF_DETAIL_WIZARD, // counter detail level
+- 0);
+-
+- //ok, now we have enough to enumerate all processes
+- if (pdh_fail(pdhStat)) {
+- /* printf("Could not enumerate processes (1) error=%d", pdhStat); */
+- return NULL;
+- }
+-
+- // use calloc because windows vista does not null terminate the instance names (allthough the docs says it will)
+- if ((instances = calloc(i_size, 1)) == NULL) {
+- /* printf("Could not allocate memory %d bytes", i_size); */
+- error = true;
+- goto end;
+- }
+-
+- c_size = 0;
+-
+- pdhStat = PdhEnumObjectItems_i (
+- NULL, // reserved
+- NULL, // local machine
+- processes, // object to enumerate
+- NULL, // pass in NULL buffers
+- &c_size, // and 0 length to get
+- instances, // required size
+- &i_size, // of the buffers in chars
+- PERF_DETAIL_WIZARD, // counter detail level
+- 0);
+-
+- // ok, now we have enough to enumerate all processes
+- if (pdh_fail(pdhStat)) {
+- /* printf("Could not enumerate processes (2) error=%d", pdhStat); */
+- error = true;
+- goto end;
+- }
+-
+- if (PdhOpenQuery_i(NULL, 0, &tmpQuery) != ERROR_SUCCESS) {
+- /* printf("Could not create temporary query"); */
+- error = true;
+- goto end;
+- }
+-
+- // Find our module name and use it to extract the instance name used by PDH
+- if (GetModuleFileName(NULL, module_name, MAX_PATH) >= MAX_PATH-1) {
+- /* printf("Module name truncated"); */
+- error = true;
+- goto end;
+- }
+- instance_name = strrchr(module_name, '\\'); //drop path
+- instance_name++; //skip slash
+- dot_pos = strchr(instance_name, '.'); //drop .exe
+- dot_pos[0] = '\0';
+-
+- //now, fetch the counters.
+- for (tmp = instances; *tmp != 0 && !error; tmp = &tmp[lstrlen(tmp)+1]) {
+- HCOUNTER hc = NULL;
+- BOOL done = false;
+-
+- // Skip until we find our own process name
+- if (strcmp(tmp, instance_name) != 0) {
+- continue;
+- }
+-
+- // iterate over all instance indexes and try to find our own pid
+- for (i = 0; !done && !error; i++){
+- PDH_STATUS res;
+- _snprintf(counter, sizeof(counter)-1, "\\%s(%s#%d)\\%s", processes, tmp, i, pid);
+-
+- if (PdhAddCounter_i(tmpQuery, counter, 0, &hc) != ERROR_SUCCESS) {
+- /* printf("Failed to create process id query"); */
+- error = true;
+- goto end;
+- }
+-
+- res = PdhCollectQueryData_i(tmpQuery);
+-
+- if (res == PDH_INVALID_HANDLE) {
+- /* printf("Failed to query process id"); */
+- res = -1;
+- done = true;
+- } else if (res == PDH_NO_DATA) {
+- done = true;
+- } else {
+- PDH_FMT_COUNTERVALUE cv;
+-
+- PdhGetFormattedCounterValue_i(hc, PDH_FMT_LONG, NULL, &cv);
+- /*
+- * This check seems to be needed for Win2k SMP boxes, since
+- * they for some reason don't return PDH_NO_DATA for non existing
+- * counters.
+- */
+- if (cv.CStatus != PDH_CSTATUS_VALID_DATA) {
+- done = true;
+- } else if (cv.longValue == myPid) {
+- _snprintf(hotspotheader, sizeof(hotspotheader)-1, "\\%s(%s#%d)\0", processes, tmp, i);
+- PdhRemoveCounter_i(hc);
+- goto end;
+- }
+- }
+- PdhRemoveCounter_i(hc);
+- }
+- }
+- end:
+- if (instances != NULL) {
+- free(instances);
+- }
+- if (tmpQuery != NULL) {
+- PdhCloseQuery_i(tmpQuery);
+- }
+- if (error) {
+- return NULL;
+- }
+- return hotspotheader;
+-}
+-
+-/**
+- * Returns the PDH string prefix identifying the HotSpot process. Use this prefix when getting
+- * counters from the PDH process object representing HotSpot.
+- *
+- * Note: this call may take some time to complete.
+- *
+- * @param ebuf error buffer.
+- * @param elen error buffer length.
+- *
+- * @return the header to be used when retrieving PDH counters from the HotSpot process.
+- * Will return NULL if the call failed.
+- */
+-static char *
+-getProcessPDHHeader(void) {
+- static char *processHeader = NULL;
+-
+- EnterCriticalSection(&processHeaderLock); {
+- if (processHeader == NULL) {
+- processHeader = initProcessPDHHeader();
+- }
+- } LeaveCriticalSection(&processHeaderLock);
+- return processHeader;
+-}
+-
+-int perfInit(void);
+-
+-double
+-perfGetCPULoad(int which)
+-{
+- PDH_FMT_COUNTERVALUE cv;
+- HCOUNTER c;
+-
+- if (perfInit() < 0) {
++ if (perfCPUInit() < 0) {
+ // warn?
+ return -1.0;
+ }
+
+- if (multiCounterCPULoad.query.query == NULL) {
+- // warn?
+- return -1.0;
+- }
++ currentQueryIndex = getCurrentQueryIndexForProcess();
+
+- if (which == -1) {
+- c = multiCounterCPULoad.counters[multiCounterCPULoad.noOfCounters - 1];
+- } else {
+- if (which < multiCounterCPULoad.noOfCounters) {
+- c = multiCounterCPULoad.counters[which];
+- } else {
+- return -1.0;
+- }
+- }
+- if (getPerformanceData(&multiCounterCPULoad.query, c, &cv, PDH_FMT_DOUBLE ) == CONFIG_SUCCESSFUL) {
+- return cv.doubleValue / 100;
+- }
+- return -1.0;
+-}
+-
+-double
+-perfGetProcessLoad(void)
+-{
+- PDH_FMT_COUNTERVALUE cv;
+-
+- if (perfInit() < 0) {
+- // warn?
+- return -1.0;
+- }
+-
+- if (cntProcLoad.query.query == NULL) {
+- // warn?
+- return -1.0;
+- }
+-
+- if (getPerformanceData(&cntProcLoad.query, cntProcLoad.counter, &cv, PDH_FMT_DOUBLE | PDH_FMT_NOCAP100) == CONFIG_SUCCESSFUL) {
++ if (getPerformanceData(&processTotalCPULoad[currentQueryIndex].query,
++ processTotalCPULoad[currentQueryIndex].counter,
++ &cv,
++ PDH_FMT_DOUBLE | PDH_FMT_NOCAP100) == 0) {
+ double d = cv.doubleValue / cpuFactor;
+ d = min(1, d);
+ d = max(0, d);
+@@ -860,70 +1323,29 @@
+ return -1.0;
+ }
+
+-/**
+- * Helper to initialize the PDH library. Loads the library and sets up the functions.
+- * Note that once loaded, we will never unload the PDH library.
+- *
+- * @return CONFIG_SUCCESSFUL if successful, negative on failure.
+- */
+-int
+-perfInit(void) {
+- static HMODULE h;
+- static BOOL running, inited;
++static double
++perfGetCPULoad(int which) {
++ PDH_FMT_COUNTERVALUE cv;
++ HCOUNTER c;
+
+- int error;
+-
+- if (running) {
+- return CONFIG_SUCCESSFUL;
++ if (perfCPUInit() < 0) {
++ // warn?
++ return -1.0;
+ }
+
+- error = CONFIG_SUCCESSFUL;
+-
+- // this is double checked locking again, but we try to bypass the worst by
+- // implicit membar at end of lock.
+- EnterCriticalSection(&initializationLock); {
+- if (!inited) {
+- char buf[64] = "";
+- SYSTEM_INFO si;
+-
+- // CMH. But windows will not care about our affinity when giving
+- // us measurements. Need the real, raw num cpus.
+-
+- GetSystemInfo(&si);
+- num_cpus = si.dwNumberOfProcessors;
+- // Initialize the denominator for the jvm load calculations
+- cpuFactor = num_cpus * 100;
+-
+- /**
+- * Do this dynamically, so we don't fail to start on systems without pdh.
+- */
+- if ((h = LoadLibrary("pdh.dll")) == NULL) {
+- /* printf("Could not load pdh.dll (%d)", GetLastError()); */
+- error = -2;
+- } else if (get_functions(h, buf, sizeof(buf)) < 0) {
+- FreeLibrary(h);
+- h = NULL;
+- error = -2;
+- /* printf("Failed to init pdh functions: %s.\n", buf); */
+- } else {
+- if (initProcessorCounters() != 0) {
+- /* printf("Failed to init system load counters.\n"); */
+- } else if (initProcLoadCounter() != 0) {
+- /* printf("Failed to init process load counter.\n"); */
+- } else if (initProcSystemLoadCounter() != 0) {
+- /* printf("Failed to init process system load counter.\n"); */
+- } else {
+- inited = true;
+- }
+- }
++ if (-1 == which) {
++ c = multiCounterCPULoad->counters[multiCounterCPULoad->noOfCounters - 1];
++ } else {
++ if (which < multiCounterCPULoad->noOfCounters) {
++ c = multiCounterCPULoad->counters[which];
++ } else {
++ return -1.0;
+ }
+- } LeaveCriticalSection(&initializationLock);
+-
+- if (inited && error == CONFIG_SUCCESSFUL) {
+- running = true;
+ }
+-
+- return error;
++ if (getPerformanceData(&multiCounterCPULoad->query, c, &cv, PDH_FMT_DOUBLE ) == 0) {
++ return cv.doubleValue / 100;
++ }
++ return -1.0;
+ }
+
+ JNIEXPORT jdouble JNICALL
+@@ -937,5 +1359,5 @@
+ Java_sun_management_OperatingSystemImpl_getProcessCpuLoad
+ (JNIEnv *env, jobject dummy)
+ {
+- return perfGetProcessLoad();
++ return perfGetProcessCPULoad();
+ }
+--- ./jdk/src/windows/native/sun/nio/ch/Net.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/nio/ch/Net.c Wed Feb 04 12:14:43 2015 -0800
+@@ -295,9 +295,9 @@
+ /**
+ * HACK: IP_TOS is deprecated on Windows and querying the option
+ * returns a protocol error. NET_GetSockOpt handles this and uses
+- * a fallback mechanism.
++ * a fallback mechanism. Same applies to IPV6_TCLASS
+ */
+- if (level == IPPROTO_IP && opt == IP_TOS) {
++ if ((level == IPPROTO_IP && opt == IP_TOS) || (level == IPPROTO_IPV6 && opt == IPV6_TCLASS)) {
+ mayNeedConversion = JNI_TRUE;
+ }
+
+@@ -319,7 +319,7 @@
+
+ JNIEXPORT void JNICALL
+ Java_sun_nio_ch_Net_setIntOption0(JNIEnv *env, jclass clazz, jobject fdo,
+- jboolean mayNeedConversion, jint level, jint opt, jint arg)
++ jboolean mayNeedConversion, jint level, jint opt, jint arg, jboolean ipv6)
+ {
+ struct linger linger;
+ char *parg;
+@@ -340,6 +340,11 @@
+ arglen = sizeof(arg);
+ }
+
++ if (level == IPPROTO_IPV6 && opt == IPV6_TCLASS) {
++ /* No op */
++ return;
++ }
++
+ if (mayNeedConversion) {
+ n = NET_SetSockOpt(fdval(env, fdo), level, opt, parg, arglen);
+ } else {
+--- ./jdk/src/windows/native/sun/security/krb5/NativeCreds.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/security/krb5/NativeCreds.c Wed Feb 04 12:14:43 2015 -0800
+@@ -463,6 +463,10 @@
+ netypes = (*env)->GetArrayLength(env, jetypes);
+ etypes = (jint *) (*env)->GetIntArrayElements(env, jetypes, NULL);
+
++ if (etypes == NULL) {
++ break;
++ }
++
+ // check TGT validity
+ if (native_debug) {
+ printf("LSA: TICKET SessionKey KeyType is %d\n", msticket->SessionKey.KeyType);
+@@ -952,8 +956,7 @@
+ if (native_debug) {
+ printf("LSA: Can't allocate String array for Principal\n");
+ }
+- LocalFree(realm);
+- return principal;
++ goto cleanup;
+ }
+
+ for (i=0; i<nameCount; i++) {
+@@ -963,18 +966,32 @@
+ // OK, got a Char array, so construct a String
+ tempString = (*env)->NewString(env, (const jchar*)scanner->Buffer,
+ scanner->Length/sizeof(WCHAR));
++
++ if (tempString == NULL) {
++ goto cleanup;
++ }
++
+ // Set the String into the StringArray
+ (*env)->SetObjectArrayElement(env, stringArray, i, tempString);
+
++ if ((*env)->ExceptionCheck(env)) {
++ goto cleanup;
++ }
++
+ // Do I have to worry about storage reclamation here?
+ }
+ // now set the realm in the principal
+ realmLen = (ULONG)wcslen((PWCHAR)realm);
+ realmStr = (*env)->NewString(env, (PWCHAR)realm, (USHORT)realmLen);
+
++ if (realmStr == NULL) {
++ goto cleanup;
++ }
++
+ principal = (*env)->NewObject(env, principalNameClass,
+ principalNameConstructor, stringArray, realmStr);
+
++cleanup:
+ // free local resources
+ LocalFree(realm);
+
+--- ./jdk/src/windows/native/sun/security/mscapi/security.cpp Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/security/mscapi/security.cpp Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -74,7 +74,10 @@
+ const char* pszHashAlgorithm = NULL;
+ ALG_ID algId = 0;
+
+- pszHashAlgorithm = env->GetStringUTFChars(jHashAlgorithm, NULL);
++ if ((pszHashAlgorithm = env->GetStringUTFChars(jHashAlgorithm, NULL))
++ == NULL) {
++ return algId;
++ }
+
+ if ((strcmp("SHA", pszHashAlgorithm) == 0) ||
+ (strcmp("SHA1", pszHashAlgorithm) == 0) ||
+@@ -179,7 +182,9 @@
+ */
+ if (length < 0) {
+ length = env->GetArrayLength(seed);
+- reseedBytes = env->GetByteArrayElements(seed, 0);
++ if ((reseedBytes = env->GetByteArrayElements(seed, 0)) == NULL) {
++ __leave;
++ }
+
+ if (::CryptGenRandom(
+ hCryptProv,
+@@ -211,7 +216,9 @@
+ } else { // length == 0
+
+ length = env->GetArrayLength(seed);
+- seedBytes = env->GetByteArrayElements(seed, 0);
++ if ((seedBytes = env->GetByteArrayElements(seed, 0)) == NULL) {
++ __leave;
++ }
+
+ if (::CryptGenRandom(
+ hCryptProv,
+@@ -275,7 +282,10 @@
+ __try
+ {
+ // Open a system certificate store.
+- pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL);
++ if ((pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL))
++ == NULL) {
++ __leave;
++ }
+ if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName))
+ == NULL) {
+
+@@ -710,7 +720,10 @@
+
+ __try
+ {
+- pszKeyContainerName = env->GetStringUTFChars(keyContainerName, NULL);
++ if ((pszKeyContainerName =
++ env->GetStringUTFChars(keyContainerName, NULL)) == NULL) {
++ __leave;
++ }
+
+ // Acquire a CSP context (create a new key container).
+ // Prefer a PROV_RSA_AES CSP, when available, due to its support
+@@ -847,7 +860,10 @@
+ __try
+ {
+ // Open a system certificate store.
+- pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL);
++ if ((pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL))
++ == NULL) {
++ __leave;
++ }
+ if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName)) == NULL) {
+ ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
+ __leave;
+@@ -1086,7 +1102,10 @@
+ __try
+ {
+ // Open a system certificate store.
+- pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL);
++ if ((pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL))
++ == NULL) {
++ __leave;
++ }
+ if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName)) == NULL) {
+ ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
+ __leave;
+@@ -1123,7 +1142,10 @@
+ cchNameString);
+
+ // Compare the certificate's friendly name with supplied alias name
+- pszCertAliasName = env->GetStringUTFChars(jCertAliasName, NULL);
++ if ((pszCertAliasName = env->GetStringUTFChars(jCertAliasName, NULL))
++ == NULL) {
++ __leave;
++ }
+ if (strcmp(pszCertAliasName, pszNameString) == 0) {
+
+ // Only delete the certificate if the alias names matches
+@@ -1181,7 +1203,10 @@
+
+ __try
+ {
+- pszKeyContainerName = env->GetStringUTFChars(keyContainerName, NULL);
++ if ((pszKeyContainerName =
++ env->GetStringUTFChars(keyContainerName, NULL)) == NULL) {
++ __leave;
++ }
+
+ // Destroying the default key container is not permitted
+ // (because it may contain more one keypair).
+@@ -1234,8 +1259,14 @@
+
+ __try
+ {
+- pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL);
+- pszCertAliasName = env->GetStringUTFChars(jCertAliasName, NULL);
++ if ((pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL))
++ == NULL) {
++ __leave;
++ }
++ if ((pszCertAliasName = env->GetStringUTFChars(jCertAliasName, NULL))
++ == NULL) {
++ __leave;
++ }
+
+ // Open a system certificate store.
+ if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName)) == NULL) {
+@@ -1530,7 +1561,9 @@
+ __try {
+
+ jsize length = env->GetArrayLength(jKeyBlob);
+- keyBlob = env->GetByteArrayElements(jKeyBlob, 0);
++ if ((keyBlob = env->GetByteArrayElements(jKeyBlob, 0)) == NULL) {
++ __leave;
++ }
+
+ PUBLICKEYSTRUC* pPublicKeyStruc = (PUBLICKEYSTRUC *) keyBlob;
+
+@@ -1580,7 +1613,9 @@
+ __try {
+
+ jsize length = env->GetArrayLength(jKeyBlob);
+- keyBlob = env->GetByteArrayElements(jKeyBlob, 0);
++ if ((keyBlob = env->GetByteArrayElements(jKeyBlob, 0)) == NULL) {
++ __leave;
++ }
+
+ PUBLICKEYSTRUC* pPublicKeyStruc = (PUBLICKEYSTRUC *) keyBlob;
+
+@@ -1632,6 +1667,9 @@
+ }
+
+ jbyte* sourceBytes = env->GetByteArrayElements(source, 0);
++ if (sourceBytes == NULL) {
++ return -1;
++ }
+
+ // Copy bytes from the end of the source array to the beginning of the
+ // destination array (until the destination array is full).
+@@ -1740,45 +1778,61 @@
+ }
+ // The length argument must be the smaller of jPublicExponentLength
+ // and sizeof(pRsaPubKey->pubkey)
+- convertToLittleEndian(env, jPublicExponent,
+- (jbyte *) &(pRsaPubKey->pubexp), jPublicExponentLength);
++ if ((jElementLength = convertToLittleEndian(env, jPublicExponent,
++ (jbyte *) &(pRsaPubKey->pubexp), jPublicExponentLength)) < 0) {
++ __leave;
++ }
+
+ // Modulus n
+ jBlobElement =
+ (jbyte *) (jBlobBytes + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY));
+- jElementLength = convertToLittleEndian(env, jModulus, jBlobElement,
+- jKeyByteLength);
++ if ((jElementLength = convertToLittleEndian(env, jModulus, jBlobElement,
++ jKeyByteLength)) < 0) {
++ __leave;
++ }
+
+ if (bGeneratePrivateKeyBlob) {
+ // Prime p
+ jBlobElement += jElementLength;
+- jElementLength = convertToLittleEndian(env, jPrimeP, jBlobElement,
+- jKeyByteLength / 2);
++ if ((jElementLength = convertToLittleEndian(env, jPrimeP,
++ jBlobElement, jKeyByteLength / 2)) < 0) {
++ __leave;
++ }
+
+ // Prime q
+ jBlobElement += jElementLength;
+- jElementLength = convertToLittleEndian(env, jPrimeQ, jBlobElement,
+- jKeyByteLength / 2);
++ if ((jElementLength = convertToLittleEndian(env, jPrimeQ,
++ jBlobElement, jKeyByteLength / 2)) < 0) {
++ __leave;
++ }
+
+ // Prime exponent p
+ jBlobElement += jElementLength;
+- jElementLength = convertToLittleEndian(env, jExponentP,
+- jBlobElement, jKeyByteLength / 2);
++ if ((jElementLength = convertToLittleEndian(env, jExponentP,
++ jBlobElement, jKeyByteLength / 2)) < 0) {
++ __leave;
++ }
+
+ // Prime exponent q
+ jBlobElement += jElementLength;
+- jElementLength = convertToLittleEndian(env, jExponentQ,
+- jBlobElement, jKeyByteLength / 2);
++ if ((jElementLength = convertToLittleEndian(env, jExponentQ,
++ jBlobElement, jKeyByteLength / 2)) < 0) {
++ __leave;
++ }
+
+ // CRT coefficient
+ jBlobElement += jElementLength;
+- jElementLength = convertToLittleEndian(env, jCrtCoefficient,
+- jBlobElement, jKeyByteLength / 2);
++ if ((jElementLength = convertToLittleEndian(env, jCrtCoefficient,
++ jBlobElement, jKeyByteLength / 2)) < 0) {
++ __leave;
++ }
+
+ // Private exponent
+ jBlobElement += jElementLength;
+- convertToLittleEndian(env, jPrivateExponent, jBlobElement,
+- jKeyByteLength);
++ if ((jElementLength = convertToLittleEndian(env, jPrivateExponent,
++ jBlobElement, jKeyByteLength)) < 0) {
++ __leave;
++ }
+ }
+
+ jBlob = env->NewByteArray(jBlobLength);
+@@ -1849,9 +1903,15 @@
+
+ __try
+ {
+- pszKeyContainerName = env->GetStringUTFChars(keyContainerName, NULL);
++ if ((pszKeyContainerName =
++ env->GetStringUTFChars(keyContainerName, NULL)) == NULL) {
++ __leave;
++ }
+ dwBlobLen = env->GetArrayLength(keyBlob);
+- pbKeyBlob = (BYTE *) env->GetByteArrayElements(keyBlob, 0);
++ if ((pbKeyBlob = (BYTE *) env->GetByteArrayElements(keyBlob, 0))
++ == NULL) {
++ __leave;
++ }
+
+ // Acquire a CSP context (create a new key container).
+ if (::CryptAcquireContext(
+@@ -1923,7 +1983,10 @@
+ __try
+ {
+ dwBlobLen = env->GetArrayLength(keyBlob);
+- pbKeyBlob = (BYTE *) env->GetByteArrayElements(keyBlob, 0);
++ if ((pbKeyBlob = (BYTE *) env->GetByteArrayElements(keyBlob, 0))
++ == NULL) {
++ __leave;
++ }
+
+ // Acquire a CSP context (create a new key container).
+ // Prefer a PROV_RSA_AES CSP, when available, due to its support
+--- ./jdk/src/windows/native/sun/security/provider/WinCAPISeedGenerator.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/security/provider/WinCAPISeedGenerator.c Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -59,11 +59,16 @@
+
+ numBytes = (*env)->GetArrayLength(env, randArray);
+ randBytes = (*env)->GetByteArrayElements(env, randArray, NULL);
++ if (randBytes == NULL) {
++ goto cleanup;
++ }
++
+ if (CryptGenRandom(hCryptProv, numBytes, randBytes)) {
+ result = JNI_TRUE;
+ }
+ (*env)->ReleaseByteArrayElements(env, randArray, randBytes, 0);
+
++cleanup:
+ CryptReleaseContext(hCryptProv, 0);
+
+ return result;
+--- ./jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c Wed Feb 04 12:14:43 2015 -0800
+@@ -23,6 +23,7 @@
+ * questions.
+ */
+ #include <windows.h>
++#include <Sddl.h>
+ #include <string.h>
+
+ #include "jni.h"
+@@ -258,6 +259,25 @@
+ HANDLE hPipe;
+ char name[MAX_PIPE_NAME_LENGTH];
+
++ SECURITY_ATTRIBUTES sa;
++ LPSECURITY_ATTRIBUTES lpSA = NULL;
++ // Custom Security Descriptor is required here to "get" Medium Integrity Level.
++ // In order to allow Medium Integrity Level clients to open
++ // and use a NamedPipe created by an High Integrity Level process.
++ TCHAR *szSD = TEXT("D:") // Discretionary ACL
++ TEXT("(A;OICI;GRGW;;;WD)") // Allow read/write to Everybody
++ TEXT("(A;OICI;GA;;;SY)") // Allow full control to System
++ TEXT("(A;OICI;GA;;;BA)"); // Allow full control to Administrators
++
++ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
++ sa.bInheritHandle = FALSE;
++ sa.lpSecurityDescriptor = NULL;
++
++ if (ConvertStringSecurityDescriptorToSecurityDescriptor
++ (szSD, SDDL_REVISION_1, &(sa.lpSecurityDescriptor), NULL)) {
++ lpSA = &sa;
++ }
++
+ jstring_to_cstring(env, pipename, name, MAX_PIPE_NAME_LENGTH);
+
+ hPipe = CreateNamedPipe(
+@@ -270,7 +290,9 @@
+ 128, // output buffer size
+ 8192, // input buffer size
+ NMPWAIT_USE_DEFAULT_WAIT, // client time-out
+- NULL); // default security attribute
++ lpSA); // security attributes
++
++ LocalFree(sa.lpSecurityDescriptor);
+
+ if (hPipe == INVALID_HANDLE_VALUE) {
+ JNU_ThrowIOExceptionWithLastError(env, "CreateNamedPipe failed");
+@@ -341,7 +363,7 @@
+ if (nread == 0) {
+ return (jint)-1; // EOF
+ } else {
+- (*env)->SetByteArrayRegion(env, ba, off, (jint)nread, (jbyte *)(buf+off));
++ (*env)->SetByteArrayRegion(env, ba, off, (jint)nread, (jbyte *)(buf));
+ }
+ }
+
+@@ -386,6 +408,7 @@
+ if (argsLen > 0) {
+ if (argsLen > MAX_ARGS) {
+ JNU_ThrowInternalError(env, "Too many arguments");
++ return;
+ }
+ for (i=0; i<argsLen; i++) {
+ jobject obj = (*env)->GetObjectArrayElement(env, args, i);
+@@ -421,6 +444,8 @@
+ stubLen = (DWORD)(*env)->GetArrayLength(env, stub);
+ stubCode = (*env)->GetByteArrayElements(env, stub, &isCopy);
+
++ if ((*env)->ExceptionOccurred(env)) return;
++
+ pCode = (PDWORD) VirtualAllocEx( hProcess, 0, stubLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
+ if (pCode == NULL) {
+ JNU_ThrowIOExceptionWithLastError(env, "VirtualAllocEx failed");
+@@ -590,6 +615,8 @@
+ cstr[0] = '\0';
+ } else {
+ str = JNU_GetStringPlatformChars(env, jstr, &isCopy);
++ if ((*env)->ExceptionOccurred(env)) return;
++
+ strncpy(cstr, str, len);
+ cstr[len-1] = '\0';
+ if (isCopy) {
+--- ./jdk/src/windows/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c Wed Feb 04 12:14:43 2015 -0800
+@@ -24,6 +24,7 @@
+ */
+
+ #include "sun_util_locale_provider_HostLocaleProviderAdapterImpl.h"
++#include "jni_util.h"
+ #include <windows.h>
+ #include <gdefs.h>
+ #include <stdlib.h>
+@@ -197,8 +198,13 @@
+ }
+
+ localeString = (char *)getJavaIDFromLangID(langid);
++ if (localeString != NULL) {
+ ret = (*env)->NewStringUTF(env, localeString);
+ free(localeString);
++ } else {
++ JNU_ThrowOutOfMemoryError(env, "memory allocation error");
++ ret = NULL;
++ }
+ return ret;
+ }
+
+@@ -211,6 +217,7 @@
+ (JNIEnv *env, jclass cls, jint dateStyle, jint timeStyle, jstring jlangtag) {
+ WCHAR pattern[BUFLEN];
+ const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
++ CHECK_NULL_RETURN(langtag, NULL);
+
+ pattern[0] = L'\0';
+
+@@ -228,7 +235,7 @@
+
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+
+- return (*env)->NewString(env, pattern, wcslen(pattern));
++ return (*env)->NewString(env, pattern, (jsize)wcslen(pattern));
+ }
+
+ /*
+@@ -238,8 +245,11 @@
+ */
+ JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarID
+ (JNIEnv *env, jclass cls, jstring jlangtag) {
+- const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
+- jint ret = getCalendarID(langtag);
++ const jchar *langtag;
++ jint ret;
++ langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
++ CHECK_NULL_RETURN(langtag, 0);
++ ret = getCalendarID(langtag);
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+ return ret;
+ }
+@@ -252,18 +262,30 @@
+ JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getAmPmStrings
+ (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray ampms) {
+ WCHAR buf[BUFLEN];
+- const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
++ const jchar *langtag;
++ jstring tmp_string;
+
+ // AM
+- int got = getLocaleInfoWrapper(langtag, LOCALE_S1159, buf, BUFLEN);
++ int got;
++ langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
++ CHECK_NULL_RETURN(langtag, NULL);
++ got = getLocaleInfoWrapper(langtag, LOCALE_S1159, buf, BUFLEN);
+ if (got) {
+- (*env)->SetObjectArrayElement(env, ampms, 0, (*env)->NewString(env, buf, wcslen(buf)));
++ tmp_string = (*env)->NewString(env, buf, (jsize)wcslen(buf));
++ if (tmp_string != NULL) {
++ (*env)->SetObjectArrayElement(env, ampms, 0, tmp_string);
++ }
+ }
+
++ if (!(*env)->ExceptionCheck(env)){
+ // PM
+ got = getLocaleInfoWrapper(langtag, LOCALE_S2359, buf, BUFLEN);
+ if (got) {
+- (*env)->SetObjectArrayElement(env, ampms, 1, (*env)->NewString(env, buf, wcslen(buf)));
++ tmp_string = (*env)->NewString(env, buf, (jsize)wcslen(buf));
++ if (tmp_string != NULL) {
++ (*env)->SetObjectArrayElement(env, ampms, 1, tmp_string);
++ }
++ }
+ }
+
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+@@ -280,12 +302,17 @@
+ (JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray eras) {
+ WCHAR ad[BUFLEN];
+ const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
++ jstring tmp_string;
++ CHECK_NULL_RETURN(langtag, eras);
+
+ getCalendarInfoWrapper(langtag, getCalendarID(langtag), NULL,
+ CAL_SERASTRING, ad, BUFLEN, NULL);
+
+ // Windows does not provide B.C. era.
+- (*env)->SetObjectArrayElement(env, eras, 1, (*env)->NewString(env, ad, wcslen(ad)));
++ tmp_string = (*env)->NewString(env, ad, (jsize)wcslen(ad));
++ if (tmp_string != NULL) {
++ (*env)->SetObjectArrayElement(env, eras, 1, tmp_string);
++ }
+
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+
+@@ -347,13 +374,17 @@
+ */
+ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getNumberPattern
+ (JNIEnv *env, jclass cls, jint numberStyle, jstring jlangtag) {
+- const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
++ const jchar *langtag;
+ jstring ret;
++ WCHAR * pattern;
+
+- WCHAR * pattern = getNumberPattern(langtag, numberStyle);
++ langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
++ CHECK_NULL_RETURN(langtag, NULL);
++ pattern = getNumberPattern(langtag, numberStyle);
++ CHECK_NULL_RETURN(pattern, NULL);
+
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+- ret = (*env)->NewString(env, pattern, wcslen(pattern));
++ ret = (*env)->NewString(env, pattern, (jsize)wcslen(pattern));
+ free(pattern);
+
+ return ret;
+@@ -367,8 +398,10 @@
+ JNIEXPORT jboolean JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_isNativeDigit
+ (JNIEnv *env, jclass cls, jstring jlangtag) {
+ DWORD num;
++ int got;
+ const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
+- int got = getLocaleInfoWrapper(langtag,
++ CHECK_NULL_RETURN(langtag, JNI_FALSE);
++ got = getLocaleInfoWrapper(langtag,
+ LOCALE_IDIGITSUBSTITUTION | LOCALE_RETURN_NUMBER,
+ (LPWSTR)&num, sizeof(num));
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+@@ -384,12 +417,14 @@
+ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCurrencySymbol
+ (JNIEnv *env, jclass cls, jstring jlangtag, jstring currencySymbol) {
+ WCHAR buf[BUFLEN];
++ int got;
+ const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
+- int got = getLocaleInfoWrapper(langtag, LOCALE_SCURRENCY, buf, BUFLEN);
++ CHECK_NULL_RETURN(langtag, currencySymbol);
++ got = getLocaleInfoWrapper(langtag, LOCALE_SCURRENCY, buf, BUFLEN);
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+
+ if (got) {
+- return (*env)->NewString(env, buf, wcslen(buf));
++ return (*env)->NewString(env, buf, (jsize)wcslen(buf));
+ } else {
+ return currencySymbol;
+ }
+@@ -403,8 +438,10 @@
+ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDecimalSeparator
+ (JNIEnv *env, jclass cls, jstring jlangtag, jchar decimalSeparator) {
+ WCHAR buf[BUFLEN];
++ int got;
+ const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
+- int got = getLocaleInfoWrapper(langtag, LOCALE_SDECIMAL, buf, BUFLEN);
++ CHECK_NULL_RETURN(langtag, decimalSeparator);
++ got = getLocaleInfoWrapper(langtag, LOCALE_SDECIMAL, buf, BUFLEN);
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+
+ if (got) {
+@@ -422,8 +459,10 @@
+ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getGroupingSeparator
+ (JNIEnv *env, jclass cls, jstring jlangtag, jchar groupingSeparator) {
+ WCHAR buf[BUFLEN];
++ int got;
+ const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
+- int got = getLocaleInfoWrapper(langtag, LOCALE_STHOUSAND, buf, BUFLEN);
++ CHECK_NULL_RETURN(langtag, groupingSeparator);
++ got = getLocaleInfoWrapper(langtag, LOCALE_STHOUSAND, buf, BUFLEN);
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+
+ if (got) {
+@@ -441,12 +480,14 @@
+ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInfinity
+ (JNIEnv *env, jclass cls, jstring jlangtag, jstring infinity) {
+ WCHAR buf[BUFLEN];
++ int got;
+ const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
+- int got = getLocaleInfoWrapper(langtag, LOCALE_SPOSINFINITY, buf, BUFLEN);
++ CHECK_NULL_RETURN(langtag, infinity);
++ got = getLocaleInfoWrapper(langtag, LOCALE_SPOSINFINITY, buf, BUFLEN);
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+
+ if (got) {
+- return (*env)->NewString(env, buf, wcslen(buf));
++ return (*env)->NewString(env, buf, (jsize)wcslen(buf));
+ } else {
+ return infinity;
+ }
+@@ -460,12 +501,14 @@
+ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInternationalCurrencySymbol
+ (JNIEnv *env, jclass cls, jstring jlangtag, jstring internationalCurrencySymbol) {
+ WCHAR buf[BUFLEN];
++ int got;
+ const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
+- int got = getLocaleInfoWrapper(langtag, LOCALE_SINTLSYMBOL, buf, BUFLEN);
++ CHECK_NULL_RETURN(langtag, internationalCurrencySymbol);
++ got = getLocaleInfoWrapper(langtag, LOCALE_SINTLSYMBOL, buf, BUFLEN);
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+
+ if (got) {
+- return (*env)->NewString(env, buf, wcslen(buf));
++ return (*env)->NewString(env, buf, (jsize)wcslen(buf));
+ } else {
+ return internationalCurrencySymbol;
+ }
+@@ -479,8 +522,10 @@
+ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMinusSign
+ (JNIEnv *env, jclass cls, jstring jlangtag, jchar minusSign) {
+ WCHAR buf[BUFLEN];
++ int got;
+ const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
+- int got = getLocaleInfoWrapper(langtag, LOCALE_SNEGATIVESIGN, buf, BUFLEN);
++ CHECK_NULL_RETURN(langtag, minusSign);
++ got = getLocaleInfoWrapper(langtag, LOCALE_SNEGATIVESIGN, buf, BUFLEN);
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+
+ if (got) {
+@@ -498,8 +543,10 @@
+ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMonetaryDecimalSeparator
+ (JNIEnv *env, jclass cls, jstring jlangtag, jchar monetaryDecimalSeparator) {
+ WCHAR buf[BUFLEN];
++ int got;
+ const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
+- int got = getLocaleInfoWrapper(langtag, LOCALE_SMONDECIMALSEP, buf, BUFLEN);
++ CHECK_NULL_RETURN(langtag, monetaryDecimalSeparator);
++ got = getLocaleInfoWrapper(langtag, LOCALE_SMONDECIMALSEP, buf, BUFLEN);
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+
+ if (got) {
+@@ -517,12 +564,14 @@
+ JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getNaN
+ (JNIEnv *env, jclass cls, jstring jlangtag, jstring nan) {
+ WCHAR buf[BUFLEN];
++ int got;
+ const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
+- int got = getLocaleInfoWrapper(langtag, LOCALE_SNAN, buf, BUFLEN);
++ CHECK_NULL_RETURN(langtag, nan);
++ got = getLocaleInfoWrapper(langtag, LOCALE_SNAN, buf, BUFLEN);
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+
+ if (got) {
+- return (*env)->NewString(env, buf, wcslen(buf));
++ return (*env)->NewString(env, buf, (jsize)wcslen(buf));
+ } else {
+ return nan;
+ }
+@@ -536,8 +585,10 @@
+ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPercent
+ (JNIEnv *env, jclass cls, jstring jlangtag, jchar percent) {
+ WCHAR buf[BUFLEN];
++ int got;
+ const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
+- int got = getLocaleInfoWrapper(langtag, LOCALE_SPERCENT, buf, BUFLEN);
++ CHECK_NULL_RETURN(langtag, percent);
++ got = getLocaleInfoWrapper(langtag, LOCALE_SPERCENT, buf, BUFLEN);
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+
+ if (got) {
+@@ -555,8 +606,12 @@
+ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPerMill
+ (JNIEnv *env, jclass cls, jstring jlangtag, jchar perMill) {
+ WCHAR buf[BUFLEN];
+- const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
+- int got = getLocaleInfoWrapper(langtag, LOCALE_SPERMILLE, buf, BUFLEN);
++ const jchar *langtag;
++ int got;
++ langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
++ CHECK_NULL_RETURN(langtag, perMill);
++ got = getLocaleInfoWrapper(langtag, LOCALE_SPERMILLE, buf, BUFLEN);
++
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+
+ if (got) {
+@@ -574,8 +629,12 @@
+ JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getZeroDigit
+ (JNIEnv *env, jclass cls, jstring jlangtag, jchar zeroDigit) {
+ WCHAR buf[BUFLEN];
+- const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
+- int got = getLocaleInfoWrapper(langtag, LOCALE_SNATIVEDIGITS, buf, BUFLEN);
++ const jchar *langtag;
++ int got;
++ langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
++ CHECK_NULL_RETURN(langtag, zeroDigit);
++ got = getLocaleInfoWrapper(langtag, LOCALE_SNATIVEDIGITS, buf, BUFLEN);
++
+ (*env)->ReleaseStringChars(env, jlangtag, langtag);
+
+ if (got) {
+@@ -593,9 +652,11 @@
+ JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarDataValue
+ (JNIEnv *env, jclass cls, jstring jlangtag, jint type) {
+ DWORD num;
+- const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
++ const jchar *langtag;
+ int got = 0;
+
++ langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
++ CHECK_NULL_RETURN(langtag, -1);
+ switch (type) {
+ case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CD_FIRSTDAYOFWEEK:
+ got = getLocaleInfoWrapper(langtag,
+@@ -648,11 +709,12 @@
+ }
+
+ pjChar = (*env)->GetStringChars(env, jStr, JNI_FALSE);
++ CHECK_NULL_RETURN(pjChar, NULL);
+ got = getLocaleInfoWrapper(pjChar, lcType, buf, BUFLEN);
+ (*env)->ReleaseStringChars(env, jStr, pjChar);
+
+ if (got) {
+- return (*env)->NewString(env, buf, wcslen(buf));
++ return (*env)->NewString(env, buf, (jsize)wcslen(buf));
+ } else {
+ return NULL;
+ }
+@@ -706,15 +768,21 @@
+ void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jobjectArray jarray, CALTYPE* pCalTypes, int offset, int length) {
+ WCHAR name[BUFLEN];
+ const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
+- int calid = getCalendarID(langtag);
++ int calid;
++ jstring tmp_string;
++
++ CHECK_NULL(langtag);
++ calid = getCalendarID(langtag);
+
+ if (calid != -1) {
+ int i;
+ for (i = 0; i < length; i++) {
+ getCalendarInfoWrapper(langtag, calid, NULL,
+ pCalTypes[i], name, BUFLEN, NULL);
+- (*env)->SetObjectArrayElement(env, jarray, i + offset,
+- (*env)->NewString(env, name, wcslen(name)));
++ tmp_string = (*env)->NewString(env, name, (jsize)wcslen(name));
++ if (tmp_string != NULL) {
++ (*env)->SetObjectArrayElement(env, jarray, i + offset, tmp_string);
++ }
+ }
+ }
+
+--- ./jdk/src/windows/native/sun/windows/WPrinterJob.cpp Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/windows/WPrinterJob.cpp Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -995,14 +995,7 @@
+ if (type == GETJOBCOUNT) {
+ ret = pPrinterInfo->cJobs;
+ } else if (type == ACCEPTJOB) {
+- if (pPrinterInfo->Status &
+- (PRINTER_STATUS_ERROR |
+- PRINTER_STATUS_NOT_AVAILABLE |
+- PRINTER_STATUS_NO_TONER |
+- PRINTER_STATUS_OUT_OF_MEMORY |
+- PRINTER_STATUS_OFFLINE |
+- PRINTER_STATUS_USER_INTERVENTION |
+- PRINTER_STATUS_DOOR_OPEN)) {
++ if (pPrinterInfo->Status & PRINTER_STATUS_PENDING_DELETION) {
+ ret = 0;
+ }
+ else {
+--- ./jdk/src/windows/native/sun/windows/awt_Component.cpp Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/windows/awt_Component.cpp Wed Feb 04 12:14:43 2015 -0800
+@@ -467,7 +467,9 @@
+ jclass win32GCCls = env->FindClass("sun/awt/Win32GraphicsConfig");
+ DASSERT(win32GCCls != NULL);
+ DASSERT(env->IsInstanceOf(compGC, win32GCCls));
+- CHECK_NULL(win32GCCls);
++ if (win32GCCls == NULL) {
++ throw std::bad_alloc();
++ }
+ env->SetObjectField(peer, AwtComponent::peerGCID, compGC);
+ }
+ }
+@@ -2141,19 +2143,7 @@
+ }
+
+ jlong getMessageTimeUTC() {
+- return windowsToUTC(getMessageTimeWindows());
+- }
+-
+- // If calling order of GetTickCount and JVM_CurrentTimeMillis
+- // is swapped, it would sometimes give different result.
+- // Anyway, we would not always have determinism
+- // and sortedness of time conversion here (due to Windows's
+- // timers peculiarities). Having some euristic algorithm might
+- // help here.
+- jlong windowsToUTC(DWORD windowsTime) {
+- jlong offset = ::GetTickCount() - windowsTime;
+- jlong jvm_time = ::JVM_CurrentTimeMillis(NULL, 0);
+- return jvm_time - offset;
++ return ::JVM_CurrentTimeMillis(NULL, 0);
+ }
+ } //TimeHelper
+
+@@ -3578,7 +3568,7 @@
+
+
+ SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED,
+- TimeHelper::windowsToUTC(msg.time), jkey, character,
++ TimeHelper::getMessageTimeUTC(), jkey, character,
+ modifiers, keyLocation, (jlong)wkey, &msg);
+
+ // bugid 4724007: Windows does not create a WM_CHAR for the Del key
+@@ -3588,7 +3578,7 @@
+ // for Java - we don't want Windows trying to process it).
+ if (jkey == java_awt_event_KeyEvent_VK_DELETE) {
+ SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED,
+- TimeHelper::windowsToUTC(msg.time),
++ TimeHelper::getMessageTimeUTC(),
+ java_awt_event_KeyEvent_VK_UNDEFINED,
+ character, modifiers,
+ java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0);
+@@ -3620,7 +3610,7 @@
+ UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
+
+ SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED,
+- TimeHelper::windowsToUTC(msg.time), jkey, character,
++ TimeHelper::getMessageTimeUTC(), jkey, character,
+ modifiers, keyLocation, (jlong)wkey, &msg);
+ return mrConsume;
+ }
+@@ -3665,7 +3655,7 @@
+
+ jint modifiers = GetJavaModifiers();
+ SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED,
+- TimeHelper::windowsToUTC(msg.time),
++ TimeHelper::getMessageTimeUTC(),
+ java_awt_event_KeyEvent_VK_UNDEFINED,
+ unicodeChar, modifiers,
+ java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
+@@ -3734,7 +3724,7 @@
+ InitMessage(&msg, message, character,
+ MAKELPARAM(repCnt, flags));
+ SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED,
+- TimeHelper::windowsToUTC(msg.time),
++ TimeHelper::getMessageTimeUTC(),
+ java_awt_event_KeyEvent_VK_UNDEFINED,
+ unicodeChar, modifiers,
+ java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
+--- ./jdk/src/windows/native/sun/windows/awt_Cursor.cpp Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/windows/awt_Cursor.cpp Wed Feb 04 12:14:43 2015 -0800
+@@ -229,9 +229,10 @@
+ if (cur != NULL) {
+ ::SetCursor(cur);
+ } else {
+- safe_ExceptionOccurred(env);
++ if (safe_ExceptionOccurred(env)) {
++ env->ExceptionClear();
++ }
+ }
+-
+ if (AwtCursor::updateCursorID == NULL) {
+ jclass cls =
+ env->FindClass("sun/awt/windows/WGlobalCursorManager");
+--- ./jdk/src/windows/native/sun/windows/awt_InputMethod.cpp Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/windows/awt_InputMethod.cpp Wed Feb 04 12:14:43 2015 -0800
+@@ -482,6 +482,7 @@
+ for (current = 0; current < destIndex; current++) {
+ if (strcmp(javaLocaleNames[current], srcLocaleName) == 0) {
+ // duplicated. ignore this HKL
++ free((void *)srcLocaleName);
+ break;
+ }
+ }
+--- ./jdk/src/windows/native/sun/windows/awt_PrintJob.cpp Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/windows/awt_PrintJob.cpp Wed Feb 04 12:14:43 2015 -0800
+@@ -758,6 +758,7 @@
+ // through print dialog or start of printing
+ // None of those may have happened yet, so call initPrinter()
+ initPrinter(env, self);
++ JNU_CHECK_EXCEPTION(env);
+ HANDLE hDevNames = AwtPrintControl::getPrintHDName(env, self);
+ HDC hdc = AwtPrintControl::getPrintDC(env, self);
+
+@@ -1102,6 +1103,7 @@
+ jboolean err;
+
+ initPrinter(env, self);
++ JNU_CHECK_EXCEPTION(env);
+
+ // check for collation
+ HGLOBAL hDevNames = AwtPrintControl::getPrintHDName(env, self);
+@@ -1362,6 +1364,13 @@
+ }
+
+ initPrinter(env, self);
++ if (env->ExceptionCheck()) {
++ if (dest != NULL) {
++ JNU_ReleaseStringPlatformChars(env, dest, destination);
++ }
++ return JNI_FALSE;
++ }
++
+ HDC printDC = AwtPrintControl::getPrintDC(env, self);
+
+ SAVE_CONTROLWORD
+@@ -3827,6 +3836,7 @@
+ // pixels per inch in y direction
+ jint yRes = GetDeviceCaps(printDC, LOGPIXELSY);
+ err = setIntField(env, self, YRES_STR, yRes);
++ if (err) return;
+
+ // x coord of printable area in pixels
+ jint xOrg = GetDeviceCaps(printDC, PHYSICALOFFSETX);
+--- ./jdk/src/windows/native/sun/windows/awt_TextArea.cpp Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/windows/awt_TextArea.cpp Wed Feb 04 12:14:43 2015 -0800
+@@ -47,16 +47,12 @@
+
+ jfieldID AwtTextArea::scrollbarVisibilityID;
+
+-WNDPROC AwtTextArea::sm_pDefWindowProc = NULL;
+-
+ /************************************************************************
+ * AwtTextArea methods
+ */
+
+ AwtTextArea::AwtTextArea() {
+- m_bIgnoreEnChange = FALSE;
+ m_bCanUndo = FALSE;
+- m_hEditCtrl = NULL;
+ m_lHDeltaAccum = 0;
+ m_lVDeltaAccum = 0;
+ }
+@@ -67,10 +63,6 @@
+
+ void AwtTextArea::Dispose()
+ {
+- if (m_hEditCtrl != NULL) {
+- VERIFY(::DestroyWindow(m_hEditCtrl));
+- m_hEditCtrl = NULL;
+- }
+ AwtTextComponent::Dispose();
+ }
+
+@@ -91,10 +83,6 @@
+ }
+ }
+
+-void AwtTextArea::EditGetSel(CHARRANGE &cr) {
+- SendMessage(EM_EXGETSEL, 0, reinterpret_cast<LPARAM>(&cr));
+-}
+-
+ /* Count how many '\n's are there in jStr */
+ size_t AwtTextArea::CountNewLines(JNIEnv *env, jstring jStr, size_t maxlen)
+ {
+@@ -149,159 +137,6 @@
+ return retValue;
+ }
+
+-/*
+- * This routine is a window procedure for the subclass of the standard edit control
+- * used to generate context menu. RichEdit controls don't have built-in context menu.
+- * To implement this functionality we have to create an invisible edit control and
+- * forward WM_CONTEXTMENU messages from a RichEdit control to this helper edit control.
+- * While the edit control context menu is active we intercept the message generated in
+- * response to particular item selection and forward it back to the RichEdit control.
+- * (See AwtTextArea::WmContextMenu for more details).
+- */
+-LRESULT
+-AwtTextArea::EditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
+-
+- static BOOL bContextMenuActive = FALSE;
+-
+- LRESULT retValue = 0;
+- MsgRouting mr = mrDoDefault;
+-
+- DASSERT(::IsWindow(::GetParent(hWnd)));
+-
+- switch (message) {
+- case WM_UNDO:
+- case WM_CUT:
+- case WM_COPY:
+- case WM_PASTE:
+- case WM_CLEAR:
+- case EM_SETSEL:
+- if (bContextMenuActive) {
+- ::SendMessage(::GetParent(hWnd), message, wParam, lParam);
+- mr = mrConsume;
+- }
+- break;
+- case WM_CONTEXTMENU:
+- bContextMenuActive = TRUE;
+- break;
+- }
+-
+- if (mr == mrDoDefault) {
+- DASSERT(sm_pDefWindowProc != NULL);
+- retValue = ::CallWindowProc(sm_pDefWindowProc,
+- hWnd, message, wParam, lParam);
+- }
+-
+- if (message == WM_CONTEXTMENU) {
+- bContextMenuActive = FALSE;
+- }
+-
+- return retValue;
+-}
+-
+-MsgRouting
+-AwtTextArea::WmContextMenu(HWND hCtrl, UINT xPos, UINT yPos) {
+- /* Use the system provided edit control class to generate context menu. */
+- if (m_hEditCtrl == NULL) {
+- DWORD dwStyle = WS_CHILD;
+- DWORD dwExStyle = 0;
+- m_hEditCtrl = ::CreateWindowEx(dwExStyle,
+- L"EDIT",
+- L"TEXT",
+- dwStyle,
+- 0, 0, 0, 0,
+- GetHWnd(),
+- reinterpret_cast<HMENU>(
+- static_cast<INT_PTR>(
+- CreateControlID())),
+- AwtToolkit::GetInstance().GetModuleHandle(),
+- NULL);
+- DASSERT(m_hEditCtrl != NULL);
+- if (sm_pDefWindowProc == NULL) {
+- sm_pDefWindowProc = (WNDPROC)::GetWindowLongPtr(m_hEditCtrl,
+- GWLP_WNDPROC);
+- }
+- ::SetLastError(0);
+- INT_PTR ret = ::SetWindowLongPtr(m_hEditCtrl, GWLP_WNDPROC,
+- (INT_PTR)AwtTextArea::EditProc);
+- DASSERT(ret != 0 || ::GetLastError() == 0);
+- }
+-
+- /*
+- * Tricks on the edit control to ensure that its context menu has
+- * the correct set of enabled items according to the RichEdit state.
+- */
+- ::SetWindowText(m_hEditCtrl, TEXT("TEXT"));
+-
+- if (m_bCanUndo == TRUE && SendMessage(EM_CANUNDO)) {
+- /* Enable 'Undo' item. */
+- ::SendMessage(m_hEditCtrl, WM_CHAR, 'A', 0);
+- }
+-
+- {
+- /*
+- * Initial selection for the edit control - (0,1).
+- * This enables 'Cut', 'Copy' and 'Delete' and 'Select All'.
+- */
+- INT nStart = 0;
+- INT nEnd = 1;
+- if (SendMessage(EM_SELECTIONTYPE) == SEL_EMPTY) {
+- /*
+- * RichEdit selection is empty - clear selection of the edit control.
+- * This disables 'Cut', 'Copy' and 'Delete'.
+- */
+- nStart = -1;
+- nEnd = 0;
+- } else {
+-
+- CHARRANGE cr;
+- EditGetSel(cr);
+- /* Check if all the text is selected. */
+- if (cr.cpMin == 0) {
+-
+- int len = ::GetWindowTextLength(GetHWnd());
+- if (cr.cpMin == 0 && cr.cpMax >= len) {
+- /*
+- * All the text is selected in RichEdit - select all the
+- * text in the edit control. This disables 'Select All'.
+- */
+- nStart = 0;
+- nEnd = -1;
+- }
+- }
+- }
+- ::SendMessage(m_hEditCtrl, EM_SETSEL, (WPARAM)nStart, (LPARAM)nEnd);
+- }
+-
+- /* Disable 'Paste' item if the RichEdit control is read-only. */
+- ::SendMessage(m_hEditCtrl, EM_SETREADONLY,
+- GetStyle() & ES_READONLY ? TRUE : FALSE, 0);
+-
+- POINT p;
+- p.x = xPos;
+- p.y = yPos;
+-
+- /*
+- * If the context menu is requested with SHIFT+F10 or VK_APPS key,
+- * we position its top left corner to the center of the RichEdit
+- * client rect.
+- */
+- if (p.x == -1 && p.y == -1) {
+- RECT r;
+- VERIFY(::GetClientRect(GetHWnd(), &r));
+- p.x = (r.left + r.right) / 2;
+- p.y = (r.top + r.bottom) / 2;
+- VERIFY(::ClientToScreen(GetHWnd(), &p));
+- }
+-
+- // The context menu steals focus from the proxy.
+- // So, set the focus-restore flag up.
+- SetRestoreFocus(TRUE);
+- ::SendMessage(m_hEditCtrl, WM_CONTEXTMENU, (WPARAM)m_hEditCtrl, MAKELPARAM(p.x, p.y));
+- SetRestoreFocus(FALSE);
+-
+- return mrConsume;
+-}
+-
+ MsgRouting
+ AwtTextArea::WmNcHitTest(UINT x, UINT y, LRESULT& retVal)
+ {
+@@ -314,27 +149,8 @@
+
+
+ MsgRouting
+-AwtTextArea::WmNotify(UINT notifyCode)
+-{
+- if (notifyCode == EN_CHANGE) {
+- /*
+- * Ignore notifications if the text hasn't been changed.
+- * EN_CHANGE sent on character formatting changes as well.
+- */
+- if (m_bIgnoreEnChange == FALSE) {
+- m_bCanUndo = TRUE;
+- DoCallback("valueChanged", "()V");
+- } else {
+- m_bCanUndo = FALSE;
+- }
+- }
+- return mrDoDefault;
+-}
+-
+-MsgRouting
+ AwtTextArea::HandleEvent(MSG *msg, BOOL synthetic)
+ {
+- MsgRouting returnVal;
+ /*
+ * RichEdit 1.0 control starts internal message loop if the
+ * left mouse button is pressed while the cursor is not over
+@@ -486,26 +302,6 @@
+ }
+ delete msg;
+ return mrConsume;
+- } else if (msg->message == WM_RBUTTONUP ||
+- (msg->message == WM_SYSKEYDOWN && msg->wParam == VK_F10 &&
+- HIBYTE(::GetKeyState(VK_SHIFT)))) {
+- POINT p;
+- if (msg->message == WM_RBUTTONUP) {
+- VERIFY(::GetCursorPos(&p));
+- } else {
+- p.x = -1;
+- p.y = -1;
+- }
+-
+- if (!::PostMessage(GetHWnd(), WM_CONTEXTMENU, (WPARAM)GetHWnd(),
+- MAKELPARAM(p.x, p.y))) {
+- JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+- JNU_ThrowInternalError(env, "Message not posted, native event queue may be full.");
+- env->ExceptionDescribe();
+- env->ExceptionClear();
+- }
+- delete msg;
+- return mrConsume;
+ } else if (msg->message == WM_MOUSEWHEEL) {
+ // 4417236: If there is an old version of RichEd32.dll which
+ // does not provide the mouse wheel scrolling we have to
+@@ -596,15 +392,7 @@
+ // 4417236: end of fix
+ }
+
+- /*
+- * Store the 'synthetic' parameter so that the WM_PASTE security check
+- * happens only for synthetic events.
+- */
+- m_synthetic = synthetic;
+- returnVal = AwtComponent::HandleEvent(msg, synthetic);
+- m_synthetic = FALSE;
+-
+- return returnVal;
++ return AwtTextComponent::HandleEvent(msg, synthetic);
+ }
+
+
+--- ./jdk/src/windows/native/sun/windows/awt_TextArea.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/windows/awt_TextArea.h Wed Feb 04 12:14:43 2015 -0800
+@@ -57,17 +57,11 @@
+ static size_t GetALength(JNIEnv* env, jstring jStr, size_t maxlen);
+
+ LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
+- static LRESULT CALLBACK EditProc(HWND hWnd, UINT message,
+- WPARAM wParam, LPARAM lParam);
+
+ MsgRouting WmEnable(BOOL fEnabled);
+- MsgRouting WmContextMenu(HWND hCtrl, UINT xPos, UINT yPos);
+- MsgRouting WmNotify(UINT notifyCode);
+ MsgRouting WmNcHitTest(UINT x, UINT y, LRESULT &retVal);
+ MsgRouting HandleEvent(MSG *msg, BOOL synthetic);
+
+- INLINE void SetIgnoreEnChange(BOOL b) { m_bIgnoreEnChange = b; }
+-
+ virtual BOOL InheritsNativeMouseWheelBehavior();
+ virtual void Reshape(int x, int y, int w, int h);
+
+@@ -81,22 +75,7 @@
+ protected:
+
+ void EditSetSel(CHARRANGE &cr);
+- void EditGetSel(CHARRANGE &cr);
+ private:
+- // RichEdit 1.0 control generates EN_CHANGE notifications not only
+- // on text changes, but also on any character formatting change.
+- // This flag is true when the latter case is detected.
+- BOOL m_bIgnoreEnChange;
+-
+- // RichEdit 1.0 control undoes a character formatting change
+- // if it is the latest. We don't create our own undo buffer,
+- // but just prohibit undo in case if the latest operation
+- // is a formatting change.
+- BOOL m_bCanUndo;
+-
+- HWND m_hEditCtrl;
+- static WNDPROC sm_pDefWindowProc;
+-
+ LONG m_lHDeltaAccum;
+ LONG m_lVDeltaAccum;
+
+--- ./jdk/src/windows/native/sun/windows/awt_TextComponent.cpp Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/windows/awt_TextComponent.cpp Wed Feb 04 12:14:43 2015 -0800
+@@ -66,6 +66,8 @@
+ m_lLastPos = -1;
+ m_isLFonly = FALSE;
+ m_EOLchecked = FALSE;
++ m_hEditCtrl = NULL;
++ m_bIgnoreEnChange = FALSE;
+ // javaEventsMask = 0; // accessibility support
+ }
+
+@@ -213,6 +215,16 @@
+ return c;
+ }
+
++void AwtTextComponent::Dispose()
++{
++ if (m_hEditCtrl != NULL) {
++ VERIFY(::DestroyWindow(m_hEditCtrl));
++ m_hEditCtrl = NULL;
++ }
++ AwtComponent::Dispose();
++}
++
++
+ LRESULT
+ AwtTextComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
+
+@@ -322,7 +334,16 @@
+ AwtTextComponent::WmNotify(UINT notifyCode)
+ {
+ if (notifyCode == EN_CHANGE) {
+- DoCallback("valueChanged", "()V");
++ /*
++ * Ignore notifications if the text hasn't been changed.
++ * EN_CHANGE sent on character formatting changes as well.
++ */
++ if (m_bIgnoreEnChange == FALSE) {
++ m_bCanUndo = TRUE;
++ DoCallback("valueChanged", "()V");
++ } else {
++ m_bCanUndo = FALSE;
++ }
+ }
+ return mrDoDefault;
+ }
+@@ -337,6 +358,28 @@
+ {
+ MsgRouting returnVal;
+
++ if (msg->message == WM_RBUTTONUP ||
++ (msg->message == WM_SYSKEYDOWN && msg->wParam == VK_F10 &&
++ HIBYTE(::GetKeyState(VK_SHIFT)))) {
++ POINT p;
++ if (msg->message == WM_RBUTTONUP) {
++ VERIFY(::GetCursorPos(&p));
++ } else {
++ p.x = -1;
++ p.y = -1;
++ }
++
++ if (!::PostMessage(GetHWnd(), WM_CONTEXTMENU, (WPARAM)GetHWnd(),
++ MAKELPARAM(p.x, p.y))) {
++ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
++ JNU_ThrowInternalError(env, "Message not posted, native event queue may be full.");
++ env->ExceptionDescribe();
++ env->ExceptionClear();
++ }
++ delete msg;
++ return mrConsume;
++ }
++
+ /*
+ * Store the 'synthetic' parameter so that the WM_PASTE security check
+ * happens only for synthetic events.
+@@ -701,6 +744,10 @@
+ SendMessage(EM_SETBKGNDCOLOR, (WPARAM)FALSE, (LPARAM)GetBackgroundColor());
+ }
+
++void AwtTextComponent::EditGetSel(CHARRANGE &cr) {
++ SendMessage(EM_EXGETSEL, 0, reinterpret_cast<LPARAM>(&cr));
++}
++
+
+ /************************************************************************
+ * WTextComponentPeer native methods
+@@ -983,6 +1030,161 @@
+ }
+
+
++/*
++ * This routine is a window procedure for the subclass of the standard edit control
++ * used to generate context menu. RichEdit controls don't have built-in context menu.
++ * To implement this functionality we have to create an invisible edit control and
++ * forward WM_CONTEXTMENU messages from a RichEdit control to this helper edit control.
++ * While the edit control context menu is active we intercept the message generated in
++ * response to particular item selection and forward it back to the RichEdit control.
++ * (See AwtTextArea::WmContextMenu for more details).
++ */
++
++WNDPROC AwtTextComponent::sm_pDefWindowProc = NULL;
++
++LRESULT
++AwtTextComponent::EditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
++
++ static BOOL bContextMenuActive = FALSE;
++
++ LRESULT retValue = 0;
++ MsgRouting mr = mrDoDefault;
++
++ DASSERT(::IsWindow(::GetParent(hWnd)));
++
++ switch (message) {
++ case WM_UNDO:
++ case WM_CUT:
++ case WM_COPY:
++ case WM_PASTE:
++ case WM_CLEAR:
++ case EM_SETSEL:
++ if (bContextMenuActive) {
++ ::SendMessage(::GetParent(hWnd), message, wParam, lParam);
++ mr = mrConsume;
++ }
++ break;
++ case WM_CONTEXTMENU:
++ bContextMenuActive = TRUE;
++ break;
++ }
++
++ if (mr == mrDoDefault) {
++ DASSERT(sm_pDefWindowProc != NULL);
++ retValue = ::CallWindowProc(sm_pDefWindowProc,
++ hWnd, message, wParam, lParam);
++ }
++
++ if (message == WM_CONTEXTMENU) {
++ bContextMenuActive = FALSE;
++ }
++
++ return retValue;
++}
++
++MsgRouting
++AwtTextComponent::WmContextMenu(HWND hCtrl, UINT xPos, UINT yPos) {
++ /* Use the system provided edit control class to generate context menu. */
++ if (m_hEditCtrl == NULL) {
++ DWORD dwStyle = WS_CHILD;
++ DWORD dwExStyle = 0;
++ m_hEditCtrl = ::CreateWindowEx(dwExStyle,
++ L"EDIT",
++ L"TEXT",
++ dwStyle,
++ 0, 0, 0, 0,
++ GetHWnd(),
++ reinterpret_cast<HMENU>(
++ static_cast<INT_PTR>(
++ CreateControlID())),
++ AwtToolkit::GetInstance().GetModuleHandle(),
++ NULL);
++ DASSERT(m_hEditCtrl != NULL);
++ if (sm_pDefWindowProc == NULL) {
++ sm_pDefWindowProc = (WNDPROC)::GetWindowLongPtr(m_hEditCtrl,
++ GWLP_WNDPROC);
++ }
++ ::SetLastError(0);
++ INT_PTR ret = ::SetWindowLongPtr(m_hEditCtrl, GWLP_WNDPROC,
++ (INT_PTR)AwtTextArea::EditProc);
++ DASSERT(ret != 0 || ::GetLastError() == 0);
++ }
++
++ /*
++ * Tricks on the edit control to ensure that its context menu has
++ * the correct set of enabled items according to the RichEdit state.
++ */
++ ::SetWindowText(m_hEditCtrl, TEXT("TEXT"));
++
++ if (m_bCanUndo == TRUE && SendMessage(EM_CANUNDO)) {
++ /* Enable 'Undo' item. */
++ ::SendMessage(m_hEditCtrl, WM_CHAR, 'A', 0);
++ }
++
++ {
++ /*
++ * Initial selection for the edit control - (0,1).
++ * This enables 'Cut', 'Copy' and 'Delete' and 'Select All'.
++ */
++ INT nStart = 0;
++ INT nEnd = 1;
++ if (SendMessage(EM_SELECTIONTYPE) == SEL_EMPTY) {
++ /*
++ * RichEdit selection is empty - clear selection of the edit control.
++ * This disables 'Cut', 'Copy' and 'Delete'.
++ */
++ nStart = -1;
++ nEnd = 0;
++ } else {
++
++ CHARRANGE cr;
++ EditGetSel(cr);
++ /* Check if all the text is selected. */
++ if (cr.cpMin == 0) {
++
++ int len = ::GetWindowTextLength(GetHWnd());
++ if (cr.cpMin == 0 && cr.cpMax >= len) {
++ /*
++ * All the text is selected in RichEdit - select all the
++ * text in the edit control. This disables 'Select All'.
++ */
++ nStart = 0;
++ nEnd = -1;
++ }
++ }
++ }
++ ::SendMessage(m_hEditCtrl, EM_SETSEL, (WPARAM)nStart, (LPARAM)nEnd);
++ }
++
++ /* Disable 'Paste' item if the RichEdit control is read-only. */
++ ::SendMessage(m_hEditCtrl, EM_SETREADONLY,
++ GetStyle() & ES_READONLY ? TRUE : FALSE, 0);
++
++ POINT p;
++ p.x = xPos;
++ p.y = yPos;
++
++ /*
++ * If the context menu is requested with SHIFT+F10 or VK_APPS key,
++ * we position its top left corner to the center of the RichEdit
++ * client rect.
++ */
++ if (p.x == -1 && p.y == -1) {
++ RECT r;
++ VERIFY(::GetClientRect(GetHWnd(), &r));
++ p.x = (r.left + r.right) / 2;
++ p.y = (r.top + r.bottom) / 2;
++ VERIFY(::ClientToScreen(GetHWnd(), &p));
++ }
++
++ // The context menu steals focus from the proxy.
++ // So, set the focus-restore flag up.
++ SetRestoreFocus(TRUE);
++ ::SendMessage(m_hEditCtrl, WM_CONTEXTMENU, (WPARAM)m_hEditCtrl, MAKELPARAM(p.x, p.y));
++ SetRestoreFocus(FALSE);
++
++ return mrConsume;
++}
+
+ //
+ // Accessibility support
+--- ./jdk/src/windows/native/sun/windows/awt_TextComponent.h Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/windows/awt_TextComponent.h Wed Feb 04 12:14:43 2015 -0800
+@@ -47,6 +47,8 @@
+
+ static AwtTextComponent* Create(jobject self, jobject parent, BOOL isMultiline);
+
++ virtual void Dispose();
++
+ virtual LPCTSTR GetClassName();
+ LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
+
+@@ -83,6 +85,8 @@
+ MsgRouting HandleEvent(MSG *msg, BOOL synthetic);
+ MsgRouting WmPaste();
+
++ INLINE void SetIgnoreEnChange(BOOL b) { m_bIgnoreEnChange = b; }
++
+ virtual BOOL IsFocusingMouseMessage(MSG *pMsg);
+
+ /* To be fully implemented in a future release
+@@ -115,11 +119,24 @@
+ INLINE VOID SetEndSelectionPos(LONG lPos) { m_lEndPos = lPos; }
+ INLINE VOID SetLastSelectionPos(LONG lPos) { m_lLastPos = lPos; }
+
++ void EditGetSel(CHARRANGE &cr);
++
+ // Used to prevent untrusted code from synthesizing a WM_PASTE message
+ // by posting a <CTRL>-V KeyEvent
+ BOOL m_synthetic;
+ LONG EditGetCharFromPos(POINT& pt);
+
++ // RichEdit 1.0 control generates EN_CHANGE notifications not only
++ // on text changes, but also on any character formatting change.
++ // This flag is true when the latter case is detected.
++ BOOL m_bIgnoreEnChange;
++
++ // RichEdit 1.0 control undoes a character formatting change
++ // if it is the latest. We don't create our own undo buffer,
++ // but just prohibit undo in case if the latest operation
++ // is a formatting change.
++ BOOL m_bCanUndo;
++
+ /*****************************************************************
+ * Inner class OleCallback declaration.
+ */
+@@ -166,6 +183,13 @@
+
+ static OleCallback sm_oleCallback;
+
++ static WNDPROC sm_pDefWindowProc;
++ HWND m_hEditCtrl;
++
++ static LRESULT CALLBACK EditProc(HWND hWnd, UINT message,
++ WPARAM wParam, LPARAM lParam);
++ MsgRouting WmContextMenu(HWND hCtrl, UINT xPos, UINT yPos);
++
+ //
+ // Accessibility support
+ //
+--- ./jdk/src/windows/native/sun/windows/awt_TextField.cpp Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/windows/awt_TextField.cpp Wed Feb 04 12:14:43 2015 -0800
+@@ -249,13 +249,7 @@
+ }
+ }
+
+- /*
+- * Store the 'synthetic' parameter so that the WM_PASTE security check
+- * happens only for synthetic events.
+- */
+- m_synthetic = synthetic;
+- returnVal = AwtComponent::HandleEvent(msg, synthetic);
+- m_synthetic = FALSE;
++ returnVal = AwtTextComponent::HandleEvent(msg, synthetic);
+
+ if(systemBeeperEnabled){
+ SystemParametersInfo(SPI_SETBEEP, 1, NULL, 0);
+--- ./jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp Wed Feb 04 12:14:43 2015 -0800
+@@ -325,7 +325,7 @@
+
+ MsgRouting AwtTrayIcon::WmMouseDown(UINT flags, int x, int y, int button)
+ {
+- jlong now = TimeHelper::windowsToUTC(::GetTickCount());
++ jlong now = TimeHelper::getMessageTimeUTC();
+ jint javaModif = AwtComponent::GetJavaModifiers();
+
+ if (lastClickTrIc == this &&
+@@ -361,14 +361,14 @@
+ MSG msg;
+ AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
+
+- SendMouseEvent(java_awt_event_MouseEvent_MOUSE_RELEASED, TimeHelper::windowsToUTC(::GetTickCount()),
++ SendMouseEvent(java_awt_event_MouseEvent_MOUSE_RELEASED, TimeHelper::getMessageTimeUTC(),
+ x, y, AwtComponent::GetJavaModifiers(), clickCount,
+ (AwtComponent::GetButton(button) == java_awt_event_MouseEvent_BUTTON3 ?
+ TRUE : FALSE), AwtComponent::GetButton(button), &msg);
+
+ if ((m_mouseButtonClickAllowed & AwtComponent::GetButtonMK(button)) != 0) { // No up-button in the drag-state
+ SendMouseEvent(java_awt_event_MouseEvent_MOUSE_CLICKED,
+- TimeHelper::windowsToUTC(::GetTickCount()), x, y, AwtComponent::GetJavaModifiers(),
++ TimeHelper::getMessageTimeUTC(), x, y, AwtComponent::GetJavaModifiers(),
+ clickCount, JNI_FALSE, AwtComponent::GetButton(button));
+ }
+ m_mouseButtonClickAllowed &= ~AwtComponent::GetButtonMK(button); // Exclude the up-button from the drag-state
+@@ -395,7 +395,7 @@
+ if ((flags & ALL_MK_BUTTONS) != 0) {
+ m_mouseButtonClickAllowed = 0;
+ } else {
+- SendMouseEvent(java_awt_event_MouseEvent_MOUSE_MOVED, TimeHelper::windowsToUTC(::GetTickCount()), x, y,
++ SendMouseEvent(java_awt_event_MouseEvent_MOUSE_MOVED, TimeHelper::getMessageTimeUTC(), x, y,
+ AwtComponent::GetJavaModifiers(), 0, JNI_FALSE,
+ java_awt_event_MouseEvent_NOBUTTON, &msg);
+ }
+@@ -408,7 +408,7 @@
+ if (AwtComponent::GetJavaModifiers() & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) {
+ MSG msg;
+ AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
+- SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, TimeHelper::windowsToUTC(::GetTickCount()),
++ SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, TimeHelper::getMessageTimeUTC(),
+ AwtComponent::GetJavaModifiers(), &msg);
+ }
+ return mrConsume;
+@@ -417,14 +417,14 @@
+ MsgRouting AwtTrayIcon::WmKeySelect(UINT flags, int x, int y)
+ {
+ static jlong lastKeySelectTime = 0;
+- jlong now = TimeHelper::windowsToUTC(::GetTickCount());
++ jlong now = TimeHelper::getMessageTimeUTC();
+
+ // If a user selects a notify icon with the ENTER key,
+ // Shell 5.0 sends double NIN_KEYSELECT notification.
+ if (lastKeySelectTime != now) {
+ MSG msg;
+ AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
+- SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, TimeHelper::windowsToUTC(::GetTickCount()),
++ SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, TimeHelper::getMessageTimeUTC(),
+ AwtComponent::GetJavaModifiers(), &msg);
+ }
+ lastKeySelectTime = now;
+@@ -441,7 +441,7 @@
+ if (clickCount == 2) {
+ MSG msg;
+ AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
+- SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, TimeHelper::windowsToUTC(::GetTickCount()),
++ SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, TimeHelper::getMessageTimeUTC(),
+ AwtComponent::GetJavaModifiers(), &msg);
+ }
+ return mrConsume;
+--- ./jdk/src/windows/native/sun/windows/awt_Win32GraphicsDevice.cpp Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/src/windows/native/sun/windows/awt_Win32GraphicsDevice.cpp Wed Feb 04 12:14:43 2015 -0800
+@@ -835,13 +835,17 @@
+ TRY;
+
+ /* class ids */
+- AwtWin32GraphicsDevice::indexCMClass =
+- (jclass)env->NewGlobalRef(env->FindClass("java/awt/image/IndexColorModel"));
++ jclass iCMClass = env->FindClass("java/awt/image/IndexColorModel");
++ CHECK_NULL(iCMClass);
++ AwtWin32GraphicsDevice::indexCMClass = (jclass) env->NewGlobalRef(iCMClass);
++ env->DeleteLocalRef(iCMClass);
+ DASSERT(AwtWin32GraphicsDevice::indexCMClass);
+ CHECK_NULL(AwtWin32GraphicsDevice::indexCMClass);
+
+- AwtWin32GraphicsDevice::wToolkitClass =
+- (jclass)env->NewGlobalRef(env->FindClass("sun/awt/windows/WToolkit"));
++ jclass wTClass = env->FindClass("sun/awt/windows/WToolkit");
++ CHECK_NULL(wTClass);
++ AwtWin32GraphicsDevice::wToolkitClass = (jclass)env->NewGlobalRef(wTClass);
++ env->DeleteLocalRef(wTClass);
+ DASSERT(AwtWin32GraphicsDevice::wToolkitClass);
+ CHECK_NULL(AwtWin32GraphicsDevice::wToolkitClass);
+
+--- ./jdk/test/ProblemList.txt Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/ProblemList.txt Wed Feb 04 12:14:43 2015 -0800
+@@ -199,6 +199,9 @@
+
+ # jdk_rmi
+
++# 7140992
++java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java generic-all
++
+ # 7146541
+ java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java linux-all
+
+@@ -251,9 +254,6 @@
+
+ # jdk_tools
+
+-# 8028474
+-sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.sh generic-all
+-
+ # Tests take too long, on sparcs see 7143279
+ tools/pack200/CommandLineTests.java solaris-all, macosx-all
+ tools/pack200/Pack200Test.java solaris-all, macosx-all
+--- ./jdk/test/TEST.groups Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/TEST.groups Wed Feb 04 12:14:43 2015 -0800
+@@ -124,15 +124,27 @@
+
+ jdk_security3 = \
+ javax/security \
++ -javax/security/auth/kerberos \
+ com/sun/security \
++ -com/sun/security/jgss \
+ com/sun/org/apache/xml/internal/security \
+ sun/security \
++ -sun/security/krb5 \
++ -sun/security/jgss \
++ javax/net \
+ lib/security
+
++jdk_security4 = \
++ com/sun/security/jgss \
++ javax/security/auth/kerberos \
++ sun/security/krb5 \
++ sun/security/jgss
++
+ jdk_security = \
+ :jdk_security1 \
+ :jdk_security2 \
+- :jdk_security3
++ :jdk_security3 \
++ :jdk_security4
+
+ jdk_text = \
+ java/text \
+@@ -314,6 +326,7 @@
+ java/io/Serializable/serialver \
+ java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java \
+ java/lang/invoke/lambda/LambdaAccessControlTest.java \
++ java/lang/invoke/lambda/LambdaAsm.java \
+ java/lang/System/MacEncoding/TestFileEncoding.java \
+ java/net/URLClassLoader/closetest/GetResourceAsStream.java \
+ java/util/Collections/EmptyIterator.java \
+@@ -333,7 +346,8 @@
+ sun/reflect/CallerSensitive/CallerSensitiveFinder.java \
+ sun/reflect/CallerSensitive/MissingCallerSensitive.java \
+ sun/security/util/Resources/NewNamesFormat.java \
+- vm/verifier/defaultMethods/DefaultMethodRegressionTestsRun.java
++ vm/verifier/defaultMethods/DefaultMethodRegressionTestsRun.java \
++ javax/xml/ws/clientjar/TestWsImport.java
+
+ # JRE adds further tests to compact3
+ #
+@@ -361,14 +375,19 @@
+ java/util/logging/Listeners.java \
+ java/util/logging/ListenersWithSM.java \
+ java/util/logging/TestMainAppContext.java \
++ java/util/logging/TestLoggingWithMainAppContext.java \
+ java/util/ResourceBundle/Control/Bug6530694.java \
+ java/text/Bidi/BidiConformance.java \
+ java/text/Bidi/BidiEmbeddingTest.java \
+- java/text/Bidi/Bug6665028.java \
+ java/text/Bidi/Bug7042148.java \
+ java/text/Bidi/Bug7051769.java \
+ javax/crypto/Cipher/CipherStreamClose.java \
+ javax/management/monitor/AttributeArbitraryDataTypeTest.java \
++ javax/management/mxbean/AmbiguousConstructorTest.java \
++ javax/management/mxbean/ExceptionDiagnosisTest.java \
++ javax/management/mxbean/LeakTest.java \
++ javax/management/mxbean/MXBeanTest.java \
++ javax/management/mxbean/PropertyNamesTest.java \
+ jdk/lambda/vm/InterfaceAccessFlagsTest.java \
+ sun/misc/URLClassPath/ClassnameCharTest.java
+
+@@ -464,6 +483,7 @@
+ sun/security/acl \
+ sun/security/jgss \
+ sun/security/krb5 \
++ java/lang/annotation/AnnotationType/AnnotationTypeDeadlockTest.java \
+ java/lang/System/MacEncoding/TestFileEncoding.java \
+ java/nio/channels/AsynchronousSocketChannel/Leaky.java \
+ java/security/PermissionCollection/Concurrent.java \
+@@ -471,6 +491,8 @@
+ java/security/cert/GetInstance.java \
+ java/util/logging/DrainFindDeadlockTest.java \
+ java/util/logging/LoggingMXBeanTest.java \
++ java/util/logging/TestLogConfigurationDeadLock.java \
++ java/util/logging/TestLoggerBundleSync.java \
+ sun/net/www/http/KeepAliveCache/B5045306.java \
+ sun/security/provider/PolicyFile/Alias.java \
+ sun/security/provider/PolicyFile/Comparator.java \
+@@ -522,6 +544,7 @@
+ java/lang/PrimitiveSumMinMaxTest.java \
+ java/lang/String/StringJoinTest.java \
+ java/lang/Thread/StopThrowable.java \
++ java/net/Authenticator/B4769350.java \
+ java/net/Authenticator/Deadlock.java \
+ java/net/CookieHandler/LocalHostCookie.java \
+ java/net/CookieHandler/CookieManagerTest.java \
+@@ -572,7 +595,6 @@
+ java/util/zip/ZipFile/StreamZipEntriesTest.java \
+ java/util/zip/ZipFile/DeleteTempJar.java \
+ javax/crypto/Cipher/CipherStreamClose.java \
+- sun/misc/URLClassPath/ClassnameCharTest.java \
+ sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsCreateSockTest.java \
+ sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsSocketFacTest.java
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/com/sun/corba/se/impl/io/CustomOutputStream.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,192 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.io.Serializable;
++
++import org.omg.CORBA.Any;
++import org.omg.CORBA.TypeCode;
++import org.omg.CORBA.Principal;
++import org.omg.CORBA_2_3.portable.OutputStream;
++import org.omg.CORBA_2_3.portable.InputStream;
++
++public class CustomOutputStream extends OutputStream {
++
++ @Override
++ public void write_value(Serializable value, Class clz) {
++ }
++
++ @Override
++ public InputStream create_input_stream() {
++ return null;
++ }
++
++ @Override
++ public void write_boolean(boolean value) {
++ }
++
++ @Override
++ public void write_char(char value) {
++ }
++
++ @Override
++ public void write_wchar(char value) {
++ }
++
++ @Override
++ public void write_octet(byte value) {
++ }
++
++ @Override
++ public void write_short(short value) {
++ }
++
++ @Override
++ public void write_ushort(short value) {
++ }
++
++ @Override
++ public void write_long(int value) {
++ }
++
++ @Override
++ public void write_ulong(int value) {
++ }
++
++ @Override
++ public void write_longlong(long value) {
++ }
++
++ @Override
++ public void write_ulonglong(long value) {
++ }
++
++ @Override
++ public void write_float(float value) {
++ }
++
++ @Override
++ public void write_double(double value) {
++ }
++
++ @Override
++ public void write_string(String value) {
++ }
++
++ @Override
++ public void write_wstring(String value) {
++ }
++
++ @Override
++ public void write_boolean_array(boolean[] value, int offset,
++ int length) {
++ }
++
++ @Override
++ public void write_char_array(char[] value, int offset,
++ int length) {
++ }
++
++ @Override
++ public void write_wchar_array(char[] value, int offset,
++ int length) {
++ }
++
++ @Override
++ public void write_octet_array(byte[] value, int offset,
++ int length) {
++ }
++
++ @Override
++ public void write_short_array(short[] value, int offset,
++ int length) {
++ }
++
++ @Override
++ public void write_ushort_array(short[] value, int offset,
++ int length) {
++ }
++
++ @Override
++ public void write_long_array(int[] value, int offset,
++ int length) {
++ }
++
++ @Override
++ public void write_ulong_array(int[] value, int offset,
++ int length) {
++ }
++
++ @Override
++ public void write_longlong_array(long[] value, int offset,
++ int length) {
++ }
++
++ @Override
++ public void write_ulonglong_array(long[] value, int offset,
++ int length) {
++ }
++
++ @Override
++ public void write_float_array(float[] value, int offset,
++ int length) {
++ }
++
++ @Override
++ public void write_double_array(double[] value, int offset,
++ int length) {
++ }
++
++ @Override
++ public void write_Object(org.omg.CORBA.Object value) {
++ }
++
++ @Override
++ public void write_TypeCode(TypeCode value) {
++ }
++
++ @Override
++ public void write_any(Any value) {
++ }
++
++ @Override
++ public void write_Principal(Principal value) {
++ }
++
++ @Override
++ public void write(int b) throws java.io.IOException {
++ }
++
++ @Override
++ public void write_fixed(java.math.BigDecimal value) {
++ }
++
++ @Override
++ public void write_Context(org.omg.CORBA.Context ctx,
++ org.omg.CORBA.ContextList contexts) {
++ }
++
++ @Override
++ public org.omg.CORBA.ORB orb() {
++ return null;
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/com/sun/corba/se/impl/io/HookPutFieldsTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 7095856
++ * @summary OutputStreamHook doesn't handle null values
++ */
++
++import java.net.InetAddress;
++import javax.rmi.CORBA.Util;
++import javax.rmi.CORBA.ValueHandler;
++
++public class HookPutFieldsTest {
++
++ public static void main(String[] args ) throws Exception {
++ CustomOutputStream os = new CustomOutputStream();
++ InetAddress a = InetAddress.getByAddress(null, new byte[] {1,2,3,4});
++ ValueHandler vh = Util.createValueHandler();
++ vh.writeValue(os, a);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/com/sun/jdi/EvalInterfaceStatic.sh Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,126 @@
++#!/bin/sh
++
++#
++# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++#
++# This code is free software; you can redistribute it and/or modify it
++# under the terms of the GNU General Public License version 2 only, as
++# published by the Free Software Foundation.
++#
++# This code is distributed in the hope that it will be useful, but WITHOUT
++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++# version 2 for more details (a copy is included in the LICENSE file that
++# accompanied this code).
++#
++# You should have received a copy of the GNU General Public License version
++# 2 along with this work; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++#
++# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++# or visit www.oracle.com if you need additional information or have any
++# questions.
++#
++
++# @test
++# @bug 8031195
++# @summary JDB allows evaluation of calls to static interface methods
++# @author Jaroslav Bachorik
++#
++# @run shell/timeout=300 EvalInterfaceStatic.sh
++
++# The test exercises the ability to invoke static methods on interfaces.
++# Static interface methods are a new feature added in JDK8.
++#
++# The test makes sure that it is, at all, possible to invoke an interface
++# static method and that the static methods are not inherited by extending
++# interfaces.
++
++classname=EvalStaticInterfaces
++
++createJavaFile()
++{
++ cat <<EOF > $classname.java.1
++public interface $classname {
++ static String staticMethod1() {
++ return "base:staticMethod1";
++ }
++
++ static String staticMethod2() {
++ return "base:staticMethod2";
++ }
++
++ public static void main(String[] args) {
++ // prove that these work
++ System.out.println("base staticMethod1(): " + $classname.staticMethod1());
++ System.out.println("base staticMethod2(): " + $classname.staticMethod2());
++ System.out.println("overridden staticMethod2(): " + Extended$classname.staticMethod2());
++ System.out.println("base staticMethod3(): " + Extended$classname.staticMethod3());
++
++ gus();
++ }
++
++ static void gus() {
++ int x = 0; // @1 breakpoint
++ }
++}
++
++interface Extended$classname extends $classname {
++ static String staticMethod2() {
++ return "extended:staticMethod2";
++ }
++
++ static String staticMethod3() {
++ return "extended:staticMethod3";
++ }
++}
++
++
++
++EOF
++}
++
++# drive jdb by sending cmds to it and examining its output
++dojdbCmds()
++{
++ setBkpts @1
++ runToBkpt @1
++
++ cmd eval "$classname.staticMethod1()"
++ jdbFailIfNotPresent "base:staticMethod1" 2
++
++ cmd eval "$classname.staticMethod2()"
++ jdbFailIfNotPresent "base:staticMethod2" 2
++
++ cmd eval "Extended$classname.staticMethod1()"
++ jdbFailIfPresent "base:staticMethod1" 2
++
++ cmd eval "Extended$classname.staticMethod2()"
++ jdbFailIfNotPresent "extended:staticMethod2" 2
++
++ cmd eval "Extended$classname.staticMethod3()"
++ jdbFailIfNotPresent "extended:staticMethod3" 2
++}
++
++
++mysetup()
++{
++ if [ -z "$TESTSRC" ] ; then
++ TESTSRC=.
++ fi
++
++ for ii in . $TESTSRC $TESTSRC/.. ; do
++ if [ -r "$ii/ShellScaffold.sh" ] ; then
++ . $ii/ShellScaffold.sh
++ break
++ fi
++ done
++}
++
++# You could replace this next line with the contents
++# of ShellScaffold.sh and this script will run just the same.
++mysetup
++
++runit
++pass
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/com/sun/jdi/InterfaceMethodsTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,422 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8031195
++ * @summary JDI: Add support for static and default methods in interfaces
++ *
++ * @run build TestScaffold VMConnection TargetListener TargetAdapter
++ * @run build InterfaceMethodsTest
++ * @run main InterfaceMethodsTest
++ */
++import com.sun.jdi.*;
++import com.sun.jdi.event.*;
++import java.util.Collections;
++
++public class InterfaceMethodsTest extends TestScaffold {
++ private static final int RESULT_A = 1;
++ private static final int RESULT_B = 1;
++ private static final int RESULT_TARGET = 1;
++ static interface InterfaceA {
++ static int staticMethodA() {
++ System.out.println("-InterfaceA: static interface method A-");
++ return RESULT_A;
++ }
++ static int staticMethodB() {
++ System.out.println("-InterfaceA: static interface method B-");
++ return RESULT_A;
++ }
++ default int defaultMethodA() {
++ System.out.println("-InterfaceA: default interface method A-");
++ return RESULT_A;
++ }
++ default int defaultMethodB() {
++ System.out.println("-InterfaceA: default interface method B-");
++ return RESULT_A;
++ }
++ default int defaultMethodC() {
++ System.out.println("-InterfaceA: default interface method C-");
++ return RESULT_A;
++ }
++
++ int implementedMethod();
++ }
++
++ static interface InterfaceB extends InterfaceA {
++ @Override
++ default int defaultMethodC() {
++ System.out.println("-InterfaceB: overridden default interface method C-");
++ return RESULT_B;
++ }
++ default int defaultMethodD() {
++ System.out.println("-InterfaceB: default interface method D-");
++ return RESULT_B;
++ }
++
++ static int staticMethodB() {
++ System.out.println("-InterfaceB: overridden static interface method B-");
++ return RESULT_B;
++ }
++
++ static int staticMethodC() {
++ System.out.println("-InterfaceB: static interface method C-");
++ return RESULT_B;
++ }
++ }
++
++ final static class TargetClass implements InterfaceB {
++ public int classMethod() {
++ System.out.println("-TargetClass: class only method-");
++ return RESULT_TARGET;
++ }
++
++ @Override
++ public int implementedMethod() {
++ System.out.println("-TargetClass: implemented non-default interface method-");
++ return RESULT_TARGET;
++ }
++
++ @Override
++ public int defaultMethodB() {
++ System.out.println("-TargetClass: overridden default interface method D");
++
++ return RESULT_TARGET;
++ }
++
++ public static void main(String[] args) {
++ TargetClass tc = new TargetClass();
++ tc.doTests(tc);
++ }
++
++ private void doTests(TargetClass ref) {
++ // break
++ }
++ }
++
++ public InterfaceMethodsTest(String[] args) {
++ super(args);
++ }
++
++ public static void main(String[] args) throws Exception {
++ new InterfaceMethodsTest(args).startTests();
++ }
++
++ private static final String TEST_CLASS_NAME = InterfaceMethodsTest.class.getName().replace('.', '/');
++ private static final String TARGET_CLASS_NAME = TargetClass.class.getName().replace('.', '/');
++ private static final String INTERFACEA_NAME = InterfaceA.class.getName().replace('.', '/');
++ private static final String INTERFACEB_NAME = InterfaceB.class.getName().replace('.', '/');
++
++ protected void runTests() throws Exception {
++ /*
++ * Get to the top of main()
++ * to determine targetClass and mainThread
++ */
++ BreakpointEvent bpe = startToMain(TARGET_CLASS_NAME);
++
++ bpe = resumeTo(TARGET_CLASS_NAME, "doTests", "(L" + TARGET_CLASS_NAME +";)V");
++
++ mainThread = bpe.thread();
++
++ StackFrame frame = mainThread.frame(0);
++ ObjectReference thisObject = frame.thisObject();
++ ObjectReference ref = (ObjectReference)frame.getArgumentValues().get(0);
++
++ ReferenceType targetClass = bpe.location().declaringType();
++ testImplementationClass(targetClass, thisObject);
++
++ testInterfaceA(ref);
++
++ testInterfaceB(ref);
++
++ /*
++ * resume the target listening for events
++ */
++ listenUntilVMDisconnect();
++
++ /*
++ * deal with results of test
++ * if anything has called failure("foo") testFailed will be true
++ */
++ if (!testFailed) {
++ println("InterfaceMethodsTest: passed");
++ } else {
++ throw new Exception("InterfaceMethodsTest: failed");
++ }
++ }
++
++ private void testInterfaceA(ObjectReference ref) {
++ // Test non-virtual calls on InterfaceA
++
++ ReferenceType ifaceClass = (ReferenceType)vm().classesByName(INTERFACEA_NAME).get(0);
++ /* Default method calls */
++
++ // invoke the InterfaceA's "defaultMethodA"
++ testInvokePos(ifaceClass, ref, "defaultMethodA", "()I", vm().mirrorOf(RESULT_A));
++
++ // invoke the InterfaceA's "defaultMethodB"
++ testInvokePos(ifaceClass, ref, "defaultMethodB", "()I", vm().mirrorOf(RESULT_A));
++
++ // invoke the InterfaceA's "defaultMethodC"
++ testInvokePos(ifaceClass, ref, "defaultMethodC", "()I", vm().mirrorOf(RESULT_A));
++
++ // "defaultMethodD" from InterfaceB is not accessible from here
++ testInvokeNeg(ifaceClass, ref, "defaultMethodD", "()I", vm().mirrorOf(RESULT_B),
++ "Attempted to invoke non-existing method");
++
++ // trying to invoke the asbtract method "implementedMethod"
++ testInvokeNeg(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(TARGET_CLASS_NAME),
++ "Invocation of non-default methods is not supported");
++
++
++ /* Static method calls */
++
++ // invoke interface static method A
++ testInvokePos(ifaceClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A));
++
++ // try to invoke static method A on the instance
++ testInvokePos(ifaceClass, ref, "staticMethodA", "()I", vm().mirrorOf(RESULT_A));
++
++ // invoke interface static method B
++ testInvokePos(ifaceClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_A));
++
++ // try to invoke static method B on the instance
++ testInvokePos(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_A));
++ }
++
++ private void testInterfaceB(ObjectReference ref) {
++ // Test non-virtual calls on InterfaceB
++ ReferenceType ifaceClass = (ReferenceType)vm().classesByName(INTERFACEB_NAME).get(0);
++
++ /* Default method calls */
++
++ // invoke the inherited "defaultMethodA"
++ testInvokePos(ifaceClass, ref, "defaultMethodA", "()I", vm().mirrorOf(RESULT_A));
++
++ // invoke the inherited "defaultMethodB"
++ testInvokePos(ifaceClass, ref, "defaultMethodB", "()I", vm().mirrorOf(RESULT_A));
++
++ // invoke the inherited and overridden "defaultMethodC"
++ testInvokePos(ifaceClass, ref, "defaultMethodC", "()I", vm().mirrorOf(RESULT_B));
++
++ // invoke InterfaceB only "defaultMethodD"
++ testInvokePos(ifaceClass, ref, "defaultMethodD", "()I", vm().mirrorOf(RESULT_B));
++
++ // "implementedMethod" is not present in InterfaceB
++ testInvokeNeg(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(RESULT_TARGET),
++ "Invocation of non-default methods is not supported");
++
++
++ /* Static method calls*/
++
++ // "staticMethodA" must not be inherited by InterfaceB
++ testInvokeNeg(ifaceClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
++ "Static interface methods are not inheritable");
++
++ // however it is possible to call "staticMethodA" on the actual instance
++ testInvokeNeg(ifaceClass, ref, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
++ "Static interface methods are not inheritable");
++
++ // "staticMethodB" is overridden in InterfaceB
++ testInvokePos(ifaceClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_B));
++
++ // the instance invokes the overriden form of "staticMethodB" from InterfaceB
++ testInvokePos(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_B));
++
++ // "staticMethodC" is present only in InterfaceB
++ testInvokePos(ifaceClass, null, "staticMethodC", "()I", vm().mirrorOf(RESULT_B));
++
++ // "staticMethodC" should be reachable from the instance too
++ testInvokePos(ifaceClass, ref, "staticMethodC", "()I", vm().mirrorOf(RESULT_B));
++ }
++
++ private void testImplementationClass(ReferenceType targetClass, ObjectReference thisObject) {
++ // Test invocations on the implementation object
++
++ /* Default method calls */
++
++ // "defaultMethodA" is accessible and not overridden
++ testInvokePos(targetClass, thisObject, "defaultMethodA", "()I", vm().mirrorOf(RESULT_TARGET));
++
++ // "defaultMethodB" is accessible and overridden in TargetClass
++ testInvokePos(targetClass, thisObject, "defaultMethodB", "()I", vm().mirrorOf(RESULT_TARGET));
++
++ // "defaultMethodC" is accessible and overridden in InterfaceB
++ testInvokePos(targetClass, thisObject, "defaultMethodC", "()I", vm().mirrorOf(RESULT_TARGET));
++
++ // "defaultMethodD" is accessible
++ testInvokePos(targetClass, thisObject, "defaultMethodD", "()I", vm().mirrorOf(RESULT_TARGET));
++
++
++ /* Non-default instance method calls */
++
++ // "classMethod" declared in TargetClass is accessible
++ testInvokePos(targetClass, thisObject, "classMethod", "()I", vm().mirrorOf(RESULT_TARGET));
++
++ // the abstract "implementedMethod" has been implemented in TargetClass
++ testInvokePos(targetClass, thisObject, "implementedMethod", "()I", vm().mirrorOf(RESULT_TARGET));
++
++
++ /* Static method calls */
++
++ // All the static methods declared by the interfaces are not reachable from the instance of the implementor class
++ testInvokeNeg(targetClass, thisObject, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
++ "Static interface methods are not inheritable");
++
++ testInvokeNeg(targetClass, thisObject, "staticMethodB", "()I", vm().mirrorOf(RESULT_B),
++ "Static interface methods are not inheritable");
++
++ testInvokeNeg(targetClass, thisObject, "staticMethodC", "()I", vm().mirrorOf(RESULT_B),
++ "Static interface methods are not inheritable");
++
++ // All the static methods declared by the interfaces are not reachable through the implementor class
++ testInvokeNeg(targetClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
++ "Static interface methods are not inheritable");
++
++ testInvokeNeg(targetClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_B),
++ "Static interface methods are not inheritable");
++
++ testInvokeNeg(targetClass, null, "staticMethodC", "()I", vm().mirrorOf(RESULT_B),
++ "Static interface methods are not inheritable");
++ }
++
++ private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName,
++ String methodSig, Value value) {
++ logInvocation(ref, methodName, methodSig, targetClass);
++ try {
++ invoke(targetClass, ref, methodName, methodSig, value);
++ System.err.println("--- PASSED");
++ } catch (Exception e) {
++ System.err.println("--- FAILED");
++ failure("FAILED: Invocation failed with error message " + e.getLocalizedMessage());
++ }
++ }
++
++ private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName,
++ String methodSig, Value value, String msg) {
++ logInvocation(ref, methodName, methodSig, targetClass);
++ try {
++ invoke(targetClass, ref, methodName, methodSig, value);
++ System.err.println("--- FAILED");
++ failure("FAILED: " + msg);
++ } catch (Exception e) {
++ System.err.println("--- PASSED");
++
++ }
++ }
++
++ private void invoke(ReferenceType targetClass, ObjectReference ref, String methodName,
++ String methodSig, Value value)
++ throws Exception {
++ Method method = getMethod(targetClass, methodName, methodSig);
++ if (method == null) {
++ throw new Exception("Can't find method: " + methodName + " for class = " + targetClass);
++ }
++
++ println("Invoking " + (method.isAbstract() ? "abstract " : " ") + "method: " + method);
++
++ Value returnValue = null;
++ if (ref != null) {
++ returnValue = invokeInstance(ref, method);
++ } else {
++ returnValue = invokeStatic(targetClass, method);
++ }
++
++ println(" return val = " + returnValue);
++ // It has to be the same value as what we passed in!
++ if (returnValue.equals(value)) {
++ println(" " + method.name() + " return value matches: "
++ + value);
++ } else {
++ if (value != null) {
++ throw new Exception(method.name() + " returned: " + returnValue +
++ " expected: " + value );
++ } else {
++ println(" " + method.name() + " return value : " + returnValue);
++ }
++
++ }
++ }
++
++ private Value invokeInstance(ObjectReference ref, Method method) throws Exception {
++ return ref.invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);
++ }
++
++ private Value invokeStatic(ReferenceType refType, Method method) throws Exception {
++ if (refType instanceof ClassType) {
++ return ((ClassType)refType).invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);
++ } else {
++ return ((InterfaceType)refType).invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);
++ }
++ }
++
++ private Method getMethod(ReferenceType rt, String name, String signature) {
++ if (rt == null) return null;
++ Method m = findMethod(rt, name, signature);
++ if (m == null) {
++ if (rt instanceof ClassType) {
++ for (Object ifc : ((ClassType)rt).interfaces()) {
++ m = getMethod((ReferenceType)ifc, name, signature);
++ if (m != null) {
++ break;
++ }
++ }
++ if (m == null) {
++ m = getMethod(((ClassType)rt).superclass(), name, signature);
++ } else {
++ if (m.isStatic()) {
++ // interface static methods are not inherited
++ m = null;
++ }
++ }
++ } else if (rt instanceof InterfaceType) {
++ for(Object ifc : ((InterfaceType)rt).superinterfaces()) {
++ m = getMethod((ReferenceType)ifc, name, signature);
++ if (m != null) {
++ if (m.isStatic()) {
++ // interface static methods are not inherited
++ m = null;
++ }
++ break;
++ }
++ }
++ }
++ }
++
++ return m;
++ }
++
++ private void logInvocation(ObjectReference ref, String methodName, String methodSig, ReferenceType targetClass) {
++ if (ref != null) {
++ System.err.println("Invoking: " + ref.referenceType().name() + "." +
++ methodName + methodSig + " with target of type " +
++ targetClass.name());
++ } else {
++ System.err.println("Invoking static : " + targetClass.name() + "." +
++ methodName + methodSig);
++ }
++ }
++}
++
++
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/com/sun/jdi/VisibleMethods.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,141 @@
++/*
++ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @summary Test ReferenceType.visibleMethods
++ * @bug 8028430
++ *
++ * @author Staffan Larsen
++ *
++ * @run build TestScaffold VMConnection TargetListener TargetAdapter
++ * @run compile -g VisibleMethods.java
++ * @run main VisibleMethods
++ */
++import com.sun.jdi.Method;
++import com.sun.jdi.ReferenceType;
++import com.sun.jdi.StackFrame;
++import com.sun.jdi.StringReference;
++import com.sun.jdi.ThreadReference;
++import com.sun.jdi.event.BreakpointEvent;
++
++import java.util.Arrays;
++import java.util.List;
++import java.util.stream.Collectors;
++
++/********** target program **********/
++
++interface Super {
++ public void m(Object o); // This method should not be visible in AC
++ public void m(String s); // This method should not be visible in AC
++}
++
++interface One extends Super {
++ public void m(Object o);
++ public void m1(); // Either this method or Two.m1 should be visible in AC
++}
++
++interface Two extends Super {
++ public void m(String s);
++ public void m1(); // Either this method or One.m1 should be visible in AC
++}
++
++abstract class AC implements One, Two {
++}
++
++class CC extends AC {
++ public void m(Object o) {
++ }
++ public void m(String s) {
++ }
++ public void m1() {
++ }
++ public static void main(String[] args) {
++ System.out.println("Goodbye from VisibleMethods!");
++ }
++}
++
++/********** test program **********/
++
++public class VisibleMethods extends TestScaffold {
++ ReferenceType targetClass;
++ ThreadReference mainThread;
++
++ VisibleMethods(String args[]) {
++ super(args);
++ }
++
++ public static void main(String[] args) throws Exception {
++ new VisibleMethods(args).startTests();
++ }
++
++ /********** test core **********/
++
++ protected void runTests()
++ throws Exception
++ {
++ /*
++ * Run to String.<init>
++ */
++ startToMain("CC");
++
++ ReferenceType ac = findReferenceType("AC");
++ List<String> visible = ac.visibleMethods().
++ stream().
++ map(Method::toString).
++ collect(Collectors.toList());
++
++ System.out.println("visibleMethods(): " + visible);
++
++ verifyContains(visible, 1, "Two.m(java.lang.String)");
++ verifyContains(visible, 1, "One.m(java.lang.Object)");
++ verifyContains(visible, 0, "Super.m(java.lang.Object)");
++ verifyContains(visible, 0, "Super.m(java.lang.String)");
++ verifyContains(visible, 1, "Two.m1()", "One.m1()");
++
++ /*
++ * resume the target listening for events
++ */
++ listenUntilVMDisconnect();
++ }
++
++ private void verifyContains(List<String> methods, int matches,
++ String... sigs) throws Exception {
++ if (countMatches(methods, sigs) != matches) {
++ throw new Exception("visibleMethods() should have contained "
++ + matches + " entry/entries from " + Arrays.toString(sigs));
++ }
++ }
++
++ private int countMatches(List<String> list1, String[] list2) {
++ int count = 0;
++ for (String s1 : list1) {
++ for (String s2 : list2) {
++ if (s1.equals(s2)) {
++ count++;
++ }
++ }
++ }
++ return count;
++ }
++}
+--- ./jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -23,6 +23,7 @@
+
+ /**
+ * @test
++ * @run main/othervm LdapTimeoutTest
+ * @bug 7094377 8000487 6176036 7056489
+ * @summary Timeout tests for ldap
+ */
+@@ -33,141 +34,56 @@
+ import java.io.*;
+ import javax.naming.*;
+ import javax.naming.directory.*;
++import java.util.List;
+ import java.util.Hashtable;
++import java.util.ArrayList;
+ import java.util.concurrent.Callable;
++import java.util.concurrent.ExecutionException;
+ import java.util.concurrent.Executors;
++import java.util.concurrent.ExecutorService;
++import java.util.concurrent.Future;
+ import java.util.concurrent.ScheduledExecutorService;
+ import java.util.concurrent.ScheduledFuture;
++import java.util.concurrent.TimeoutException;
+ import java.util.concurrent.TimeUnit;
+
+-public class LdapTimeoutTest {
+- private static final ScheduledExecutorService pool =
+- Executors.newScheduledThreadPool(1);
+- static volatile int passed = 0, failed = 0;
+- static void pass() {passed++;}
+- static void fail() {failed++; Thread.dumpStack();}
++import static java.util.concurrent.TimeUnit.MILLISECONDS;
++import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+- public static void main(String[] args) throws Exception {
+- ServerSocket serverSock = new ServerSocket(0);
+- Server s = new Server(serverSock);
+- s.start();
+- Thread.sleep(200);
+
+- Hashtable env = new Hashtable(11);
+- env.put(Context.INITIAL_CONTEXT_FACTORY,
+- "com.sun.jndi.ldap.LdapCtxFactory");
+- env.put(Context.PROVIDER_URL, "ldap://localhost:" +
+- serverSock.getLocalPort());
++abstract class LdapTest implements Callable {
+
+- env.put(Context.SECURITY_AUTHENTICATION,"simple");
++ Hashtable env;
++ TestServer server;
++ ScheduledExecutorService killSwitchPool;
++ boolean passed = false;
++ private int HANGING_TEST_TIMEOUT = 20_000;
+
+- env.put(Context.SECURITY_PRINCIPAL, "user");
+- env.put(Context.SECURITY_CREDENTIALS, "password");
+-
+- InitialContext ctx = null;
+- try {
+- new LdapTimeoutTest().deadServerNoTimeout(env);
+-
+- env.put("com.sun.jndi.ldap.connect.timeout", "10");
+- env.put("com.sun.jndi.ldap.read.timeout", "3000");
+- new LdapTimeoutTest().ldapReadTimeoutTest(env, false);
+- new LdapTimeoutTest().ldapReadTimeoutTest(env, true);
+- new LdapTimeoutTest().simpleAuthConnectTest(env);
+- } finally {
+- s.interrupt();
+- LdapTimeoutTest.pool.shutdown();
+- }
+-
+- System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+- if (failed > 0) throw new AssertionError("Some tests failed");
++ public LdapTest (TestServer server, Hashtable env) {
++ this.server = server;
++ this.env = env;
+ }
+
+- void ldapReadTimeoutTest(Hashtable env, boolean ssl) {
+- InitialContext ctx = null;
+- if (ssl) env.put(Context.SECURITY_PROTOCOL, "ssl");
+- ScheduledFuture killer = killSwitch(5000);
+- long start = System.nanoTime();
+- try {
+- ctx = new InitialDirContext(env);
+- SearchControls scl = new SearchControls();
+- scl.setSearchScope(SearchControls.SUBTREE_SCOPE);
+- NamingEnumeration<SearchResult> answer = ((InitialDirContext)ctx)
+- .search("ou=People,o=JNDITutorial", "(objectClass=*)", scl);
+- // shouldn't reach here
+- fail();
+- } catch (NamingException e) {
+- if (ssl) {
+- if (e.getCause() instanceof SocketTimeoutException) {
+- pass();
+- } else if (e.getCause() instanceof InterruptedIOException) {
+- Thread.interrupted();
+- fail();
+- }
+- } else {
+- pass();
+- }
+- } finally {
+- if (!shutItDown(killer, ctx)) fail();
+- }
++ public LdapTest(TestServer server, Hashtable env,
++ ScheduledExecutorService killSwitchPool)
++ {
++ this(server, env);
++ this.killSwitchPool = killSwitchPool;
+ }
+
+- void simpleAuthConnectTest(Hashtable env) {
+- InitialContext ctx = null;
+- ScheduledFuture killer = killSwitch(5000);
+- long start = System.nanoTime();
+- try {
+- ctx = new InitialDirContext(env);
+- // shouldn't reach here
+- System.err.println("Fail: InitialDirContext succeeded");
+- fail();
+- } catch (NamingException e) {
+- long end = System.nanoTime();
+- if (e.getCause() instanceof SocketTimeoutException) {
+- if (TimeUnit.NANOSECONDS.toMillis(end - start) < 2900) {
+- pass();
+- } else {
+- System.err.println("Fail: Waited too long");
+- fail();
+- }
+- } else if (e.getCause() instanceof InterruptedIOException) {
+- Thread.interrupted();
+- fail();
+- } else {
+- fail();
+- }
+- } finally {
+- if (!shutItDown(killer, ctx)) fail();
+- }
++ public abstract void performOp(InitialContext ctx) throws NamingException;
++ public abstract void handleNamingException(
++ NamingException e, long start, long end);
++
++ public void pass() {
++ this.passed = true;
+ }
+
+- void deadServerNoTimeout(Hashtable env) {
+- InitialContext ctx = null;
+- ScheduledFuture killer = killSwitch(30000);
+- long start = System.nanoTime();
+- try {
+- ctx = new InitialDirContext(env);
+- SearchControls scl = new SearchControls();
+- scl.setSearchScope(SearchControls.SUBTREE_SCOPE);
+- NamingEnumeration<SearchResult> answer = ((InitialDirContext)ctx)
+- .search("ou=People,o=JNDITutorial", "(objectClass=*)", scl);
+- // shouldn't reach here
+- fail();
+- } catch (NamingException e) {
+- long end = System.nanoTime();
+- if (TimeUnit.NANOSECONDS.toMillis(end - start) < 14000) {
+- System.err.println("fail: timeout should be at least 15 seconds, actual time: "
+- + TimeUnit.NANOSECONDS.toMillis(end - start));
+- fail();
+- } else {
+- pass();
+- }
+- } finally {
+- if (!shutItDown(killer, ctx)) fail();
+- }
++ public void fail() {
++ throw new RuntimeException("Test failed");
+ }
+
+- boolean shutItDown(ScheduledFuture killer, InitialContext ctx) {
+- killer.cancel(true);
++ boolean shutItDown(InitialContext ctx) {
+ try {
+ if (ctx != null) ctx.close();
+ return true;
+@@ -176,29 +92,376 @@
+ }
+ }
+
+- ScheduledFuture killSwitch(int ms) {
+- final Thread current = Thread.currentThread();
+- return LdapTimeoutTest.pool.schedule(new Callable<Void>() {
+- public Void call() throws Exception {
+- System.err.println("Fail: killSwitch()");
+- System.exit(0);
+- return null;
++ public Boolean call() {
++ InitialContext ctx = null;
++ ScheduledFuture killer = null;
++ long start = System.nanoTime();
++
++ try {
++ while(!server.accepting())
++ Thread.sleep(200); // allow the server to start up
++ Thread.sleep(200); // to be sure
++
++ // if this is a hanging test, scheduled a thread to
++ // interrupt after a certain time
++ if (killSwitchPool != null) {
++ final Thread current = Thread.currentThread();
++ killer = killSwitchPool.schedule(
++ new Callable<Void>() {
++ public Void call() throws Exception {
++ current.interrupt();
++ return null;
++ }
++ }, HANGING_TEST_TIMEOUT, MILLISECONDS);
+ }
+- }, ms, TimeUnit.MILLISECONDS);
+- }
+
+- static class Server extends Thread {
+- final ServerSocket serverSock;
++ env.put(Context.PROVIDER_URL, "ldap://localhost:" +
++ server.getLocalPort());
+
+- Server(ServerSocket serverSock) {
+- this.serverSock = serverSock;
+- }
+-
+- public void run() {
+ try {
+- Socket socket = serverSock.accept();
+- } catch (IOException e) {}
++ ctx = new InitialDirContext(env);
++ performOp(ctx);
++ fail();
++ } catch (NamingException e) {
++ long end = System.nanoTime();
++ System.out.println(this.getClass().toString() + " - elapsed: "
++ + NANOSECONDS.toMillis(end - start));
++ handleNamingException(e, start, end);
++ } finally {
++ if (killer != null && !killer.isDone())
++ killer.cancel(true);
++ shutItDown(ctx);
++ server.close();
++ }
++ return passed;
++ } catch (IOException|InterruptedException e) {
++ throw new RuntimeException(e);
+ }
+ }
+ }
+
++abstract class ReadServerTest extends LdapTest {
++
++ public ReadServerTest(Hashtable env) throws IOException {
++ super(new BindableServer(), env);
++ }
++
++ public ReadServerTest(Hashtable env,
++ ScheduledExecutorService killSwitchPool)
++ throws IOException
++ {
++ super(new BindableServer(), env, killSwitchPool);
++ }
++
++ public void performOp(InitialContext ctx) throws NamingException {
++ SearchControls scl = new SearchControls();
++ scl.setSearchScope(SearchControls.SUBTREE_SCOPE);
++ NamingEnumeration<SearchResult> answer = ((InitialDirContext)ctx)
++ .search("ou=People,o=JNDITutorial", "(objectClass=*)", scl);
++ }
++}
++
++abstract class DeadServerTest extends LdapTest {
++
++ public DeadServerTest(Hashtable env) throws IOException {
++ super(new DeadServer(), env);
++ }
++
++ public DeadServerTest(Hashtable env,
++ ScheduledExecutorService killSwitchPool)
++ throws IOException
++ {
++ super(new DeadServer(), env, killSwitchPool);
++ }
++
++ public void performOp(InitialContext ctx) throws NamingException {}
++}
++
++class DeadServerNoTimeoutTest extends DeadServerTest {
++
++ public DeadServerNoTimeoutTest(Hashtable env,
++ ScheduledExecutorService killSwitchPool)
++ throws IOException
++ {
++ super(env, killSwitchPool);
++ }
++
++ public void handleNamingException(NamingException e, long start, long end) {
++ if (e instanceof InterruptedNamingException) Thread.interrupted();
++
++ if (NANOSECONDS.toMillis(end - start) < LdapTimeoutTest.MIN_TIMEOUT) {
++ System.err.printf("DeadServerNoTimeoutTest fail: timeout should be " +
++ "at least %s ms, actual time is %s ms%n",
++ LdapTimeoutTest.MIN_TIMEOUT,
++ NANOSECONDS.toMillis(end - start));
++ fail();
++ } else {
++ pass();
++ }
++ }
++}
++
++class DeadServerTimeoutTest extends DeadServerTest {
++
++ public DeadServerTimeoutTest(Hashtable env) throws IOException {
++ super(env);
++ }
++
++ public void handleNamingException(NamingException e, long start, long end)
++ {
++ // non SSL connect will timeout via readReply using connectTimeout
++ if (NANOSECONDS.toMillis(end - start) < 2_900) {
++ pass();
++ } else {
++ System.err.println("Fail: Waited too long");
++ fail();
++ }
++ }
++}
++
++class DeadServerTimeoutSSLTest extends DeadServerTest {
++
++ public DeadServerTimeoutSSLTest(Hashtable env) throws IOException {
++ super(env);
++ }
++
++ public void handleNamingException(NamingException e, long start, long end) {
++ if (e.getCause() instanceof SocketTimeoutException) {
++ // SSL connect will timeout via readReply using
++ // SocketTimeoutException
++ pass();
++ } else {
++ fail();
++ }
++ }
++}
++
++
++class ReadServerNoTimeoutTest extends ReadServerTest {
++
++ public ReadServerNoTimeoutTest(Hashtable env,
++ ScheduledExecutorService killSwitchPool)
++ throws IOException
++ {
++ super(env, killSwitchPool);
++ }
++
++ public void handleNamingException(NamingException e, long start, long end) {
++ if (e instanceof InterruptedNamingException) Thread.interrupted();
++
++ if (NANOSECONDS.toMillis(end - start) < LdapTimeoutTest.MIN_TIMEOUT) {
++ System.err.printf("ReadServerNoTimeoutTest fail: timeout should be " +
++ "at least %s ms, actual time is %s ms%n",
++ LdapTimeoutTest.MIN_TIMEOUT,
++ NANOSECONDS.toMillis(end - start));
++ fail();
++ } else {
++ pass();
++ }
++ }
++}
++
++class ReadServerTimeoutTest extends ReadServerTest {
++
++ public ReadServerTimeoutTest(Hashtable env) throws IOException {
++ super(env);
++ }
++
++ public void handleNamingException(NamingException e, long start, long end) {
++ if (NANOSECONDS.toMillis(end - start) < 2_900) {
++ fail();
++ } else {
++ pass();
++ }
++ }
++}
++
++class TestServer extends Thread {
++ ServerSocket serverSock;
++ boolean accepting = false;
++
++ public TestServer() throws IOException {
++ this.serverSock = new ServerSocket(0);
++ start();
++ }
++
++ public int getLocalPort() {
++ return serverSock.getLocalPort();
++ }
++
++ public boolean accepting() {
++ return accepting;
++ }
++
++ public void close() throws IOException {
++ serverSock.close();
++ }
++}
++
++class BindableServer extends TestServer {
++
++ public BindableServer() throws IOException {
++ super();
++ }
++
++ private byte[] bindResponse = {
++ 0x30, 0x0C, 0x02, 0x01, 0x01, 0x61, 0x07, 0x0A,
++ 0x01, 0x00, 0x04, 0x00, 0x04, 0x00
++ };
++
++ public void run() {
++ try {
++ accepting = true;
++ Socket socket = serverSock.accept();
++ InputStream in = socket.getInputStream();
++ OutputStream out = socket.getOutputStream();
++
++ // Read the LDAP BindRequest
++ while (in.read() != -1) {
++ in.skip(in.available());
++ break;
++ }
++
++ // Write an LDAP BindResponse
++ out.write(bindResponse);
++ out.flush();
++ } catch (IOException e) {
++ // ignore
++ }
++ }
++}
++
++class DeadServer extends TestServer {
++
++ public DeadServer() throws IOException {
++ super();
++ }
++
++ public void run() {
++ while(true) {
++ try {
++ accepting = true;
++ Socket socket = serverSock.accept();
++ } catch (Exception e) {
++ break;
++ }
++ }
++ }
++}
++
++public class LdapTimeoutTest {
++
++ private static final ExecutorService testPool =
++ Executors.newFixedThreadPool(3);
++ private static final ScheduledExecutorService killSwitchPool =
++ Executors.newScheduledThreadPool(3);
++ public static int MIN_TIMEOUT = 18_000;
++
++ static Hashtable createEnv() {
++ Hashtable env = new Hashtable(11);
++ env.put(Context.INITIAL_CONTEXT_FACTORY,
++ "com.sun.jndi.ldap.LdapCtxFactory");
++ return env;
++ }
++
++ public static void main(String[] args) throws Exception {
++
++ InitialContext ctx = null;
++ List<Future> results = new ArrayList<>();
++
++ try {
++ // run the DeadServerTest with no timeouts set
++ // this should get stuck indefinitely, so we need to kill
++ // it after a timeout
++ System.out.println("Running connect timeout test with 20s kill switch");
++ Hashtable env = createEnv();
++ results.add(
++ testPool.submit(new DeadServerNoTimeoutTest(env, killSwitchPool)));
++
++ // run the ReadServerTest with connect timeout set
++ // this should get stuck indefinitely so we need to kill
++ // it after a timeout
++ System.out.println("Running read timeout test with 10ms connect timeout & 20s kill switch");
++ Hashtable env1 = createEnv();
++ env1.put("com.sun.jndi.ldap.connect.timeout", "10");
++ results.add(testPool.submit(
++ new ReadServerNoTimeoutTest(env1, killSwitchPool)));
++
++ // run the ReadServerTest with no timeouts set
++ // this should get stuck indefinitely, so we need to kill
++ // it after a timeout
++ System.out.println("Running read timeout test with 20s kill switch");
++ Hashtable env2 = createEnv();
++ results.add(testPool.submit(
++ new ReadServerNoTimeoutTest(env2, killSwitchPool)));
++
++ // run the DeadServerTest with connect / read timeouts set
++ // this should exit after the connect timeout expires
++ System.out.println("Running connect timeout test with 10ms connect timeout, 3000ms read timeout");
++ Hashtable env3 = createEnv();
++ env3.put("com.sun.jndi.ldap.connect.timeout", "10");
++ env3.put("com.sun.jndi.ldap.read.timeout", "3000");
++ results.add(testPool.submit(new DeadServerTimeoutTest(env3)));
++
++
++ // run the ReadServerTest with connect / read timeouts set
++ // this should exit after the connect timeout expires
++ System.out.println("Running read timeout test with 10ms connect timeout, 3000ms read timeout");
++ Hashtable env4 = createEnv();
++ env4.put("com.sun.jndi.ldap.connect.timeout", "10");
++ env4.put("com.sun.jndi.ldap.read.timeout", "3000");
++ results.add(testPool.submit(new ReadServerTimeoutTest(env4)));
++
++ // run the DeadServerTest with connect timeout set
++ // this should exit after the connect timeout expires
++ System.out.println("Running connect timeout test with 10ms connect timeout");
++ Hashtable env5 = createEnv();
++ env5.put("com.sun.jndi.ldap.connect.timeout", "10");
++ results.add(testPool.submit(new DeadServerTimeoutTest(env5)));
++
++ // 8000487: Java JNDI connection library on ldap conn is
++ // not honoring configured timeout
++ System.out.println("Running simple auth connection test");
++ Hashtable env6 = createEnv();
++ env6.put("com.sun.jndi.ldap.connect.timeout", "10");
++ env6.put("com.sun.jndi.ldap.read.timeout", "3000");
++ env6.put(Context.SECURITY_AUTHENTICATION, "simple");
++ env6.put(Context.SECURITY_PRINCIPAL, "user");
++ env6.put(Context.SECURITY_CREDENTIALS, "password");
++ results.add(testPool.submit(new DeadServerTimeoutTest(env6)));
++
++ boolean testFailed = false;
++ for (Future test : results) {
++ while (!test.isDone()) {
++ if ((Boolean) test.get() == false)
++ testFailed = true;
++ }
++ }
++
++ //
++ // Running this test serially as it seems to tickle a problem
++ // on older kernels
++ //
++ // run the DeadServerTest with connect / read timeouts set
++ // and ssl enabled
++ // this should exit with a SocketTimeoutException as the root cause
++ // it should also use the connect timeout instead of the read timeout
++ System.out.println("Running connect timeout test with 10ms connect timeout, 3000ms read timeout & SSL");
++ Hashtable sslenv = createEnv();
++ sslenv.put("com.sun.jndi.ldap.connect.timeout", "10");
++ sslenv.put("com.sun.jndi.ldap.read.timeout", "3000");
++ sslenv.put(Context.SECURITY_PROTOCOL, "ssl");
++ testFailed = (new DeadServerTimeoutSSLTest(sslenv).call()) ? false : true;
++
++ if (testFailed) {
++ throw new AssertionError("some tests failed");
++ }
++
++ } finally {
++ LdapTimeoutTest.killSwitchPool.shutdown();
++ LdapTimeoutTest.testPool.shutdown();
++ }
++ }
++
++}
++
+--- ./jdk/test/com/sun/security/sasl/ntlm/NTLMTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/com/sun/security/sasl/ntlm/NTLMTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -23,7 +23,7 @@
+
+ /*
+ * @test
+- * @bug 6911951
++ * @bug 6911951 7150092
+ * @summary NTLM should be a supported Java SASL mechanism
+ */
+ import java.io.IOException;
+@@ -59,7 +59,6 @@
+
+ checkAuthOnly();
+ checkClientNameOverride();
+- checkServerDomainOverride();
+ checkClientDomainOverride();
+ checkVersions();
+ checkClientHostname();
+@@ -116,15 +115,12 @@
+ Map<String,Object> ps = new HashMap<>();
+ ps.put("com.sun.security.sasl.ntlm.version", vs);
+ SaslClient clnt = Sasl.createSaslClient(
+- new String[]{MECH}, USER1, PROTOCOL, null, pc,
++ new String[]{MECH}, USER1, PROTOCOL, REALM, pc,
+ new CallbackHandler() {
+ public void handle(Callback[] callbacks)
+ throws IOException, UnsupportedCallbackException {
+ for (Callback cb: callbacks) {
+- if (cb instanceof NameCallback) {
+- NameCallback ncb = (NameCallback)cb;
+- ncb.setName(ncb.getDefaultName());
+- } else if (cb instanceof PasswordCallback) {
++ if (cb instanceof PasswordCallback) {
+ ((PasswordCallback)cb).setPassword(PASS1);
+ }
+ }
+@@ -159,15 +155,12 @@
+ Map<String,Object> pc = new HashMap<>();
+ pc.put("com.sun.security.sasl.ntlm.hostname", "this.is.com");
+ SaslClient clnt = Sasl.createSaslClient(
+- new String[]{MECH}, USER1, PROTOCOL, null, pc,
++ new String[]{MECH}, USER1, PROTOCOL, REALM, pc,
+ new CallbackHandler() {
+ public void handle(Callback[] callbacks)
+ throws IOException, UnsupportedCallbackException {
+ for (Callback cb: callbacks) {
+- if (cb instanceof NameCallback) {
+- NameCallback ncb = (NameCallback)cb;
+- ncb.setName(ncb.getDefaultName());
+- } else if (cb instanceof PasswordCallback) {
++ if (cb instanceof PasswordCallback) {
+ ((PasswordCallback)cb).setPassword(PASS1);
+ }
+ }
+@@ -212,12 +205,8 @@
+ public void handle(Callback[] callbacks)
+ throws IOException, UnsupportedCallbackException {
+ for (Callback cb: callbacks) {
+- if (cb instanceof NameCallback) {
+- NameCallback ncb = (NameCallback)cb;
+- ncb.setName(ncb.getDefaultName());
+- } else if(cb instanceof RealmCallback) {
+- RealmCallback dcb = (RealmCallback)cb;
+- dcb.setText("THIRDDOMAIN");
++ if (cb instanceof RealmCallback) {
++ ((RealmCallback)cb).setText(REALM);
+ } else if (cb instanceof PasswordCallback) {
+ ((PasswordCallback)cb).setPassword(PASS1);
+ }
+@@ -255,13 +244,13 @@
+ */
+ private static void checkClientNameOverride() throws Exception {
+ SaslClient clnt = Sasl.createSaslClient(
+- new String[]{MECH}, null, PROTOCOL, null, null,
++ new String[]{MECH}, "someone", PROTOCOL, REALM, null,
+ new CallbackHandler() {
+ public void handle(Callback[] callbacks)
+ throws IOException, UnsupportedCallbackException {
+ for (Callback cb: callbacks) {
+ if (cb instanceof NameCallback) {
+- NameCallback ncb = (NameCallback)cb;
++ NameCallback ncb = (NameCallback) cb;
+ ncb.setName(USER1);
+ } else if (cb instanceof PasswordCallback) {
+ ((PasswordCallback)cb).setPassword(PASS1);
+@@ -270,54 +259,7 @@
+ }
+ });
+
+- SaslServer srv = Sasl.createSaslServer(MECH, PROTOCOL, REALM, null,
+- new CallbackHandler() {
+- public void handle(Callback[] callbacks)
+- throws IOException, UnsupportedCallbackException {
+- String domain = null, name = null;
+- PasswordCallback pcb = null;
+- for (Callback cb: callbacks) {
+- if (cb instanceof NameCallback) {
+- name = ((NameCallback)cb).getDefaultName();
+- } else if (cb instanceof RealmCallback) {
+- domain = ((RealmCallback)cb).getDefaultText();
+- } else if (cb instanceof PasswordCallback) {
+- pcb = (PasswordCallback)cb;
+- }
+- }
+- if (pcb != null) {
+- pcb.setPassword(getPass(domain, name));
+- }
+- }
+- });
+-
+- handshake(clnt, srv);
+- }
+-
+- /**
+- * server side domain provided in props.
+- * @throws Exception
+- */
+- private static void checkServerDomainOverride() throws Exception {
+- SaslClient clnt = Sasl.createSaslClient(
+- new String[]{MECH}, USER1, PROTOCOL, null, null,
+- new CallbackHandler() {
+- public void handle(Callback[] callbacks)
+- throws IOException, UnsupportedCallbackException {
+- for (Callback cb: callbacks) {
+- if (cb instanceof NameCallback) {
+- NameCallback ncb = (NameCallback)cb;
+- ncb.setName(ncb.getDefaultName());
+- } else if (cb instanceof PasswordCallback) {
+- ((PasswordCallback)cb).setPassword(PASS1);
+- }
+- }
+- }
+- });
+-
+- Map<String,Object> ps = new HashMap<>();
+- ps.put("com.sun.security.sasl.ntlm.domain", REALM);
+- SaslServer srv = Sasl.createSaslServer(MECH, PROTOCOL, null, ps,
++ SaslServer srv = Sasl.createSaslServer(MECH, PROTOCOL, "FAKE", null,
+ new CallbackHandler() {
+ public void handle(Callback[] callbacks)
+ throws IOException, UnsupportedCallbackException {
+--- ./jdk/test/com/sun/tools/attach/SimpleProvider.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/com/sun/tools/attach/SimpleProvider.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -100,4 +100,12 @@
+
+ public void dataDumpRequest() throws IOException {
+ }
++
++ public String startLocalManagementAgent() {
++ return null;
++ }
++
++ public void startManagementAgent(Properties agentProperties) {
++ }
++
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/com/sun/tools/attach/StartManagementAgent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,211 @@
++/*
++ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import com.sun.tools.attach.AttachOperationFailedException;
++import com.sun.tools.attach.VirtualMachine;
++
++import java.io.File;
++import java.io.FileWriter;
++import java.util.Properties;
++import java.util.HashMap;
++
++import javax.management.remote.JMXServiceURL;
++import javax.management.remote.JMXConnector;
++import javax.management.remote.JMXConnectorFactory;
++
++import jdk.testlibrary.ProcessThread;
++import jdk.testlibrary.Utils;
++
++/*
++ * @test
++ * @summary Test for VirtualMachine.startManagementAgent and VirtualMachine.startLocalManagementAgent
++ * @library /lib/testlibrary
++ * @run build Application Shutdown SimpleProvider jdk.testlibrary.*
++ * @run main StartManagementAgent
++ */
++
++/*
++ * This test is not meant to test all possible configuration parameters to
++ * the JMX agent, there are other tests for that. This test makes sure it is
++ * possible to start the agent via attach.
++ */
++public class StartManagementAgent {
++ public static void main(String[] args) throws Throwable {
++ final String pidFile = "StartManagementAgent.Application.pid";
++ ProcessThread processThread = null;
++ RunnerUtil.ProcessInfo info = null;
++ try {
++ processThread = RunnerUtil.startApplication(pidFile);
++ info = RunnerUtil.readProcessInfo(pidFile);
++ runTests(info.pid);
++ } catch (Throwable t) {
++ System.out.println("StartManagementAgent got unexpected exception: " + t);
++ t.printStackTrace();
++ throw t;
++ } finally {
++ // Make sure the Application process is stopped.
++ RunnerUtil.stopApplication(info.shutdownPort, processThread);
++ }
++ }
++
++ private static void basicTests(VirtualMachine vm) throws Exception {
++
++ // Try calling with null argument
++ boolean exception = false;
++ try {
++ vm.startManagementAgent(null);
++ } catch (NullPointerException e) {
++ exception = true;
++ }
++ if (!exception) {
++ throw new Exception("startManagementAgent(null) should throw NPE");
++ }
++
++ // Try calling with a property value with a space in it
++ Properties p = new Properties();
++ File f = new File("file with space");
++ try (FileWriter fw = new FileWriter(f)) {
++ fw.write("com.sun.management.jmxremote.port=apa");
++ }
++ p.put("com.sun.management.config.file", f.getAbsolutePath());
++ try {
++ vm.startManagementAgent(p);
++ } catch(AttachOperationFailedException ex) {
++ // We expect parsing of "apa" above to fail, but if the file path
++ // can't be read we get a different exception message
++ if (!ex.getMessage().contains("java.lang.NumberFormatException")) {
++ throw ex;
++ }
++ }
++ }
++
++ private static final String LOCAL_CONNECTOR_ADDRESS_PROP =
++ "com.sun.management.jmxremote.localConnectorAddress";
++
++ private static final int MAX_RETRIES = 10;
++
++ public static void runTests(int pid) throws Exception {
++ VirtualMachine vm = VirtualMachine.attach(""+pid);
++ try {
++
++ basicTests(vm);
++
++ testLocalAgent(vm);
++
++ // we retry the remote case several times in case the error
++ // was caused by a port conflict
++ int i = 0;
++ boolean success = false;
++ do {
++ try {
++ System.err.println("Trying remote agent. Try #" + i);
++ testRemoteAgent(vm);
++ success = true;
++ } catch(Exception ex) {
++ System.err.println("testRemoteAgent failed with exception:");
++ ex.printStackTrace();
++ System.err.println("Retrying.");
++ }
++ i++;
++ } while(!success && i < MAX_RETRIES);
++ if (!success) {
++ throw new Exception("testRemoteAgent failed after " + MAX_RETRIES + " tries");
++ }
++ } finally {
++ vm.detach();
++ }
++ }
++
++ public static void testLocalAgent(VirtualMachine vm) throws Exception {
++ Properties agentProps = vm.getAgentProperties();
++ String address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
++ if (address != null) {
++ throw new Exception("Local management agent already started");
++ }
++
++ String result = vm.startLocalManagementAgent();
++
++ // try to parse the return value as a JMXServiceURL
++ new JMXServiceURL(result);
++
++ agentProps = vm.getAgentProperties();
++ address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
++ if (address == null) {
++ throw new Exception("Local management agent could not be started");
++ }
++ }
++
++ public static void testRemoteAgent(VirtualMachine vm) throws Exception {
++ int port = Utils.getFreePort();
++
++ // try to connect - should fail
++ tryConnect(port, false);
++
++ // start agent
++ System.out.println("Starting agent on port: " + port);
++ Properties mgmtProps = new Properties();
++ mgmtProps.put("com.sun.management.jmxremote.port", port);
++ mgmtProps.put("com.sun.management.jmxremote.authenticate", "false");
++ mgmtProps.put("com.sun.management.jmxremote.ssl", "false");
++ vm.startManagementAgent(mgmtProps);
++
++ // try to connect - should work
++ tryConnect(port, true);
++
++ // try to start again - should fail
++ boolean exception = false;
++ try {
++ vm.startManagementAgent(mgmtProps);
++ } catch(AttachOperationFailedException ex) {
++ // expected
++ exception = true;
++ }
++ if (!exception) {
++ throw new Exception("Expected the second call to vm.startManagementAgent() to fail");
++ }
++ }
++
++ private static void tryConnect(int port, boolean shouldSucceed) throws Exception {
++ String jmxUrlStr =
++ String.format(
++ "service:jmx:rmi:///jndi/rmi://localhost:%d/jmxrmi",
++ port);
++ JMXServiceURL url = new JMXServiceURL(jmxUrlStr);
++ HashMap<String, ?> env = new HashMap<>();
++
++ boolean succeeded;
++ try {
++ JMXConnector c = JMXConnectorFactory.connect(url, env);
++ c.getMBeanServerConnection();
++ succeeded = true;
++ } catch(Exception ex) {
++ succeeded = false;
++ }
++ if (succeeded && !shouldSucceed) {
++ throw new Exception("Could connect to agent, but should not have been possible");
++ }
++ if (!succeeded && shouldSucceed) {
++ throw new Exception("Could not connect to agent");
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/Container/ContainerAIOOBE/ContainerAIOOBE.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,74 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.awt.Button;
++import java.awt.Component;
++import java.awt.Container;
++import java.io.ByteArrayInputStream;
++import java.io.ByteArrayOutputStream;
++import java.io.ObjectInputStream;
++import java.io.ObjectOutputStream;
++
++/**
++ * @test
++ * @bug 8059590
++ * @summary ArrayIndexOutOfBoundsException occurs when Container with overridden getComponents() is deserialized.
++ * @author Alexey Ivanov
++ * @run main ContainerAIOOBE
++ */
++public class ContainerAIOOBE {
++
++ public static void main(final String[] args) throws Exception {
++ ZContainer z = new ZContainer();
++ z.add(new Button());
++
++ ByteArrayOutputStream baos = new ByteArrayOutputStream();
++ ObjectOutputStream oos = new ObjectOutputStream(baos);
++ oos.writeObject(z);
++ oos.flush();
++ oos.close();
++
++ byte[] array = baos.toByteArray();
++ ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(array));
++
++ // Reading the object must not throw ArrayIndexOutOfBoundsException
++ ZContainer zz = (ZContainer) ois.readObject();
++
++ if (zz.getComponentCount() != 1) {
++ throw new Exception("deserialized object must have 1 component");
++ }
++ if (!(zz.getComponent(0) instanceof Button)) {
++ throw new Exception("deserialized object must contain Button component");
++ }
++ if (zz.getComponents().length != 0) {
++ throw new Exception("deserialized object returns non-empty array");
++ }
++ System.out.println("Test passed");
++ }
++
++ static class ZContainer extends Container {
++ public Component[] getComponents() {
++ return new Component[0];
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/Focus/8044614/TestApplet.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.applet.Applet;
++import java.awt.TextField;
++
++public class TestApplet extends Applet {
++ TextField textField = null;
++
++ public void init() {
++ textField = new TextField(25);
++ add(textField);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/Focus/8044614/applet1.html Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,37 @@
++<!--
++ Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++
++ This code is free software; you can redistribute it and/or modify it
++ under the terms of the GNU General Public License version 2 only, as
++ published by the Free Software Foundation.
++
++ This code is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ version 2 for more details (a copy is included in the LICENSE file that
++ accompanied this code).
++
++ You should have received a copy of the GNU General Public License version
++ 2 along with this work; if not, write to the Free Software Foundation,
++ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++
++ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ or visit www.oracle.com if you need additional information or have any
++ questions.
++-->
++
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
++<html lang="en">
++<head>
++ <meta http-equiv="content-type" content="text/html; charset=utf-8">
++ <title>First Applet</title>
++</head>
++ <body>
++ <applet
++ code="TestApplet.class"
++ width="400"
++ height="200"/>
++ </applet>
++ </body>
++</html>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/Focus/8044614/applet2.html Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,37 @@
++<!--
++ Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++
++ This code is free software; you can redistribute it and/or modify it
++ under the terms of the GNU General Public License version 2 only, as
++ published by the Free Software Foundation.
++
++ This code is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ version 2 for more details (a copy is included in the LICENSE file that
++ accompanied this code).
++
++ You should have received a copy of the GNU General Public License version
++ 2 along with this work; if not, write to the Free Software Foundation,
++ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++
++ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ or visit www.oracle.com if you need additional information or have any
++ questions.
++-->
++
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
++<html lang="en">
++<head>
++ <meta http-equiv="content-type" content="text/html; charset=utf-8">
++ <title>Second Applet</title>
++</head>
++ <body>
++ <applet
++ code="TestApplet.class"
++ width="400"
++ height="200"/>
++ </applet>
++ </body>
++</html>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/Focus/8044614/bug8044614.html Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,36 @@
++<!--
++ Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++
++ This code is free software; you can redistribute it and/or modify it
++ under the terms of the GNU General Public License version 2 only, as
++ published by the Free Software Foundation.
++
++ This code is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ version 2 for more details (a copy is included in the LICENSE file that
++ accompanied this code).
++
++ You should have received a copy of the GNU General Public License version
++ 2 along with this work; if not, write to the Free Software Foundation,
++ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++
++ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ or visit www.oracle.com if you need additional information or have any
++ questions.
++-->
++
++<html>
++<head>
++<title>bug8044614</title>
++</head>
++<body>
++
++<h1>bug8044614</h1>
++
++<p> See the dialog box (usually in upper left corner) for instructions</p>
++
++<APPLET CODE="bug8044614.class" WIDTH=200 HEIGHT=200></APPLET>
++</body>
++</html>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/Focus/8044614/bug8044614.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,56 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8044614
++ * @summary Tests focus transfer between applets in different browser windows
++ * @author Dmitry Markov
++ * @library ../../regtesthelpers
++ * @build Sysout
++ * @run applet/manual=yesno bug8044614.html
++ */
++
++import javax.swing.JApplet;
++
++import test.java.awt.regtesthelpers.Sysout;
++
++public class bug8044614 extends JApplet {
++ public void init() {
++ String[] instructions = {
++ "(1) Go to the test directory test/java/awt/Focus/8044614",
++ "(2) Compile source file: javac TestApplet.java",
++ "(3) Open the \"main.html\" file in the browser",
++ "(4) Click the \"Start First Applet\" link to open the first applet window",
++ "(5) Wait for the applet to start (press \"Run\" to any security alerts that appears)",
++ "(6) Enter \"Hello\" to the text field",
++ "(7) Click the \"Start Second Applet)\" link to open the second applet window",
++ "(8) Wait for the applet to start (press \"Run\" to any security alerts that appears)",
++ "(9) Enter \"World\" to the text field",
++ "(10) Go back to the first applet and make sure you can enter some text to the text field"
++ };
++
++ Sysout.createDialogWithInstructions(instructions);
++ }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/Focus/8044614/main.html Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,46 @@
++<!--
++ Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++
++ This code is free software; you can redistribute it and/or modify it
++ under the terms of the GNU General Public License version 2 only, as
++ published by the Free Software Foundation.
++
++ This code is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ version 2 for more details (a copy is included in the LICENSE file that
++ accompanied this code).
++
++ You should have received a copy of the GNU General Public License version
++ 2 along with this work; if not, write to the Free Software Foundation,
++ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++
++ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ or visit www.oracle.com if you need additional information or have any
++ questions.
++-->
++
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
++<html lang="en">
++<head>
++ <meta http-equiv="content-type" content="text/html; charset=utf-8">
++ <title>Applet Focus Bug main window</title>
++ <script language="JavaScript">
++ function openWindow(strURL, strWindowName, strWindowFeatures) {
++ var win = window.open(strURL, strWindowName, strWindowFeatures);
++ }
++ </script>
++
++</head>
++ <body>
++ <table>
++ <tr>
++ <td><a href="javascript:openWindow('applet1.html', '', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=400, height=400, top=0, left=0, hide=no')">Start First Applet</a></td>
++ </tr>
++ <tr>
++ <td><a href="javascript:openWindow('applet2.html', '', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=400, height=400, top=0, left=350, hide=no')">Start Second Applet</a></td>
++ </tr>
++ </table>
++ </body>
++</html>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/Focus/SortingFPT/JDK8048887.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,132 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ @test
++ @bug 8048887
++ @summary Tests SortingFTP for an exception caused by the tim-sort algo.
++ @author anton.tarasov: area=awt.focus
++ @run main JDK8048887
++*/
++
++import javax.swing.JFrame;
++import javax.swing.JPanel;
++import javax.swing.SwingUtilities;
++import java.awt.Dimension;
++import java.awt.Color;
++import java.awt.GridBagLayout;
++import java.awt.GridBagConstraints;
++import java.awt.event.WindowAdapter;
++import java.awt.event.WindowEvent;
++import java.util.concurrent.CountDownLatch;
++import java.util.concurrent.TimeUnit;
++
++public class JDK8048887 {
++
++ static volatile boolean passed = true;
++
++ public static void main(String[] args) {
++ JDK8048887 app = new JDK8048887();
++ app.start();
++ }
++
++ public void start() {
++ final CountDownLatch latch = new CountDownLatch(1);
++
++ SwingUtilities.invokeLater(() -> {
++ // Catch the original exception which sounds like:
++ // java.lang.IllegalArgumentException: Comparison method violates its general contract!
++ Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
++ public void uncaughtException(Thread t, Throwable e) {
++ e.printStackTrace();
++ if (e instanceof IllegalArgumentException) {
++ passed = false;
++ latch.countDown();
++ }
++ }
++ });
++
++ TestDialog d = new TestDialog();
++ // It's expected that the dialog is focused on start.
++ // The listener is called after the FTP completes processing and the bug is reproduced or not.
++ d.addWindowFocusListener(new WindowAdapter() {
++ public void windowGainedFocus(WindowEvent e) {
++ latch.countDown();
++ }
++ });
++ d.setVisible(true);
++ });
++
++ try {
++ latch.await(5, TimeUnit.SECONDS);
++ } catch (InterruptedException e) {
++ e.printStackTrace();
++ }
++
++ if (passed)
++ System.out.println("Test passed.");
++ else
++ throw new RuntimeException("Test failed!");
++ }
++}
++
++class TestDialog extends JFrame {
++
++ // The layout of the components reproduces the transitivity issue
++ // with SortingFocusTraversalPolicy relying on the tim-sort algo.
++
++ private static int[] Xs = new int[] {71, 23, 62, 4, 79, 39, 34, 9, 84, 58, 30, 34, 38, 15, 69, 10, 44, 95, 70, 54,
++ 44, 62, 77, 64, 70, 83, 31, 48, 96, 54, 40, 3, 60, 58, 3, 20, 94, 54, 26, 19, 48, 47, 12, 70, 86, 43, 71, 97, 19,
++ 69, 90, 22, 43, 76, 10, 60, 29, 49, 9, 9, 15, 73, 85, 80, 81, 35, 87, 43, 17, 57, 38, 44, 29, 86, 96, 15, 57, 26,
++ 27, 78, 26, 87, 43, 6, 4, 16, 57, 99, 32, 86, 96, 5, 50, 69, 12, 4, 36, 84, 71, 60, 22, 46, 11, 44, 87, 3, 23, 14,
++ 43, 25, 32, 44, 11, 18, 77, 2, 51, 87, 88, 53, 69, 37, 14, 10, 25, 73, 39, 33, 91, 51, 96, 9, 74, 66, 70, 42, 72,
++ 7, 82, 40, 91, 33, 83, 54, 33, 50, 83, 1, 81, 32, 66, 11, 75, 56, 53, 45, 1, 69, 46, 31, 79, 58, 12, 20, 92, 49,
++ 50, 90, 33, 8, 43, 93, 72, 78, 9, 56, 84, 60, 30, 39, 33, 88, 84, 56, 49, 47, 4, 90, 57, 6, 23, 96, 37, 88, 22, 79,
++ 35, 80, 45, 55};
++
++ public TestDialog() {
++ JPanel panel = new JPanel(new GridBagLayout());
++ GridBagConstraints gbc = new GridBagConstraints();
++ for (int i=0; i < Xs.length; i++) {
++ gbc.gridx = Xs[i];
++ gbc.gridy = 100 - gbc.gridx;
++ panel.add(new MyComponent(), gbc);
++ }
++ getRootPane().getContentPane().add(panel);
++ pack();
++ }
++
++ public static class MyComponent extends JPanel {
++ private final static Dimension SIZE = new Dimension(1,1);
++
++ public MyComponent() {
++ setBackground(Color.BLACK);
++ setOpaque(true);
++ }
++
++ @Override
++ public Dimension getPreferredSize() {
++ return SIZE;
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.html Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,21 @@
++<html>
++<!--
++ @test
++ @bug 4051487 4145670
++ @summary Tests that disposing of an empty Frame or a Frame with a MenuBar
++ while it is being created does not crash the VM.
++ @author dpm area=Threads
++ @run applet/timeout=7200 DisposeStressTest.html
++ -->
++<head>
++<title>DisposeStressTest</title>
++</head>
++<body>
++
++<h1>DisposeStressTest<br>Bug ID: 4051487, 4145670</h1>
++
++<p> This is an AUTOMATIC test, simply wait for completion </p>
++
++<APPLET CODE="DisposeStressTest.class" WIDTH=200 HEIGHT=200></APPLET>
++</body>
++</html>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,247 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++
++/*
++ test
++ @bug 4051487 4145670 8062021
++ @summary Tests that disposing of an empty Frame or a Frame with a MenuBar
++ while it is being created does not crash the VM.
++ @author dpm area=Threads
++ @run applet/timeout=7200 DisposeStressTest.html
++*/
++
++// Note there is no @ in front of test above. This is so that the
++// harness will not mistake this file as a test file. It should
++// only see the html file as a test file. (the harness runs all
++// valid test files, so it would run this test twice if this file
++// were valid as well as the html file.)
++// Also, note the area= after Your Name in the author tag. Here, you
++// should put which functional area the test falls in. See the
++// AWT-core home page -> test areas and/or -> AWT team for a list of
++// areas.
++// Note also the 'DisposeStressTest.html' in the run tag. This should
++// be changed to the name of the test.
++
++
++/**
++ * DisposeStressTest.java
++ *
++ * summary:
++ */
++
++import java.applet.Applet;
++import java.awt.*;
++
++
++//Automated tests should run as applet tests if possible because they
++// get their environments cleaned up, including AWT threads, any
++// test created threads, and any system resources used by the test
++// such as file descriptors. (This is normally not a problem as
++// main tests usually run in a separate VM, however on some platforms
++// such as the Mac, separate VMs are not possible and non-applet
++// tests will cause problems). Also, you don't have to worry about
++// synchronisation stuff in Applet tests they way you do in main
++// tests...
++
++
++public class DisposeStressTest extends Applet
++ {
++ //Declare things used in the test, like buttons and labels here
++
++ public void init()
++ {
++ //Create instructions for the user here, as well as set up
++ // the environment -- set the layout manager, add buttons,
++ // etc.
++
++ this.setLayout (new BorderLayout ());
++
++ String[] instructions =
++ {
++ "This is an AUTOMATIC test",
++ "simply wait until it is done"
++ };
++ Sysout.createDialog( );
++ Sysout.printInstructions( instructions );
++
++ }//End init()
++
++ public void start ()
++ {
++ for (int i = 0; i < 1000; i++) {
++ Frame f = new Frame();
++ f.setBounds(10, 10, 10, 10);
++ f.show();
++ f.dispose();
++
++ Frame f2 = new Frame();
++ f2.setBounds(10, 10, 100, 100);
++ MenuBar bar = new MenuBar();
++ Menu menu = new Menu();
++ menu.add(new MenuItem("foo"));
++ bar.add(menu);
++ f2.setMenuBar(bar);
++ f2.show();
++ f2.dispose();
++ }
++ }// start()
++
++ }// class DisposeStressTest
++
++
++/****************************************************
++ Standard Test Machinery
++ DO NOT modify anything below -- it's a standard
++ chunk of code whose purpose is to make user
++ interaction uniform, and thereby make it simpler
++ to read and understand someone else's test.
++ ****************************************************/
++
++/**
++ This is part of the standard test machinery.
++ It creates a dialog (with the instructions), and is the interface
++ for sending text messages to the user.
++ To print the instructions, send an array of strings to Sysout.createDialog
++ WithInstructions method. Put one line of instructions per array entry.
++ To display a message for the tester to see, simply call Sysout.println
++ with the string to be displayed.
++ This mimics System.out.println but works within the test harness as well
++ as standalone.
++ */
++
++class Sysout
++ {
++ private static TestDialog dialog;
++
++ public static void createDialogWithInstructions( String[] instructions )
++ {
++ dialog = new TestDialog( new Frame(), "Instructions" );
++ dialog.printInstructions( instructions );
++ dialog.show();
++ println( "Any messages for the tester will display here." );
++ }
++
++ public static void createDialog( )
++ {
++ dialog = new TestDialog( new Frame(), "Instructions" );
++ String[] defInstr = { "Instructions will appear here. ", "" } ;
++ dialog.printInstructions( defInstr );
++ dialog.show();
++ println( "Any messages for the tester will display here." );
++ }
++
++
++ public static void printInstructions( String[] instructions )
++ {
++ dialog.printInstructions( instructions );
++ }
++
++
++ public static void println( String messageIn )
++ {
++ dialog.displayMessage( messageIn );
++ }
++
++ }// Sysout class
++
++/**
++ This is part of the standard test machinery. It provides a place for the
++ test instructions to be displayed, and a place for interactive messages
++ to the user to be displayed.
++ To have the test instructions displayed, see Sysout.
++ To have a message to the user be displayed, see Sysout.
++ Do not call anything in this dialog directly.
++ */
++class TestDialog extends Dialog
++ {
++
++ TextArea instructionsText;
++ TextArea messageText;
++ int maxStringLength = 80;
++
++ //DO NOT call this directly, go through Sysout
++ public TestDialog( Frame frame, String name )
++ {
++ super( frame, name );
++ int scrollBoth = TextArea.SCROLLBARS_BOTH;
++ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
++ add( "North", instructionsText );
++
++ messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
++ add("South", messageText);
++
++ pack();
++
++ show();
++ }// TestDialog()
++
++ //DO NOT call this directly, go through Sysout
++ public void printInstructions( String[] instructions )
++ {
++ //Clear out any current instructions
++ instructionsText.setText( "" );
++
++ //Go down array of instruction strings
++
++ String printStr, remainingStr;
++ for( int i=0; i < instructions.length; i++ )
++ {
++ //chop up each into pieces maxSringLength long
++ remainingStr = instructions[ i ];
++ while( remainingStr.length() > 0 )
++ {
++ //if longer than max then chop off first max chars to print
++ if( remainingStr.length() >= maxStringLength )
++ {
++ //Try to chop on a word boundary
++ int posOfSpace = remainingStr.
++ lastIndexOf( ' ', maxStringLength - 1 );
++
++ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
++
++ printStr = remainingStr.substring( 0, posOfSpace + 1 );
++ remainingStr = remainingStr.substring( posOfSpace + 1 );
++ }
++ //else just print
++ else
++ {
++ printStr = remainingStr;
++ remainingStr = "";
++ }
++
++ instructionsText.append( printStr + "\n" );
++
++ }// while
++
++ }// for
++
++ }//printInstructions()
++
++ //DO NOT call this directly, go through Sysout
++ public void displayMessage( String messageIn )
++ {
++ messageText.append( messageIn + "\n" );
++ }
++
++ }// TestDialog class
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/Graphics2D/DrawString/DrawStringCrash.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,64 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8043508
++ * @summary Drawing a very long string crashes VM
++ */
++
++import java.awt.*;
++import java.awt.image.*;
++
++public class DrawStringCrash {
++
++ public static void main(String[] args) {
++ StringBuffer sb = new StringBuffer();
++ String s = "abcdefghijklmnopqrstuzwxyz";
++ for (int x = 0; x < 100000 ; x++) {
++ sb.append(s);
++ }
++ // Now have a string which uses approx 5Mb memory
++ // Loop again drawing doubling each time until
++ // we reach 8 billion chars or get OOME which means we can't
++ // go any further.
++ // Often there is no crash because Java OOM happens
++ // long before native heap runs out.
++ long maxLen = 8L * 1024 * 1024 * 1024;
++ int len = sb.length();
++
++ BufferedImage bi =
++ new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
++ Graphics2D g2d = bi.createGraphics();
++ while (len < maxLen) {
++ try {
++ g2d.drawString(sb.toString(), 20, 20);
++ } catch (OutOfMemoryError e) {
++ return;
++ }
++ sb.append(sb);
++ len *= 2;
++ }
++ return;
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/Graphics2D/WhiteTextColorTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,76 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.awt.*;
++import java.awt.image.*;
++import javax.swing.*;
++
++/**
++ * @test
++ * @bug 8056009
++ * @summary tests whether Graphics.setColor-calls with Color.white are ignored directly
++ * after pipeline initialization for a certain set of operations.
++ * @author ceisserer
++ */
++public class WhiteTextColorTest extends Frame {
++ public static volatile boolean success = false;
++
++ public WhiteTextColorTest() {
++ Image dstImg = getGraphicsConfiguration()
++ .createCompatibleVolatileImage(30, 20);
++ Graphics g = dstImg.getGraphics();
++
++ g.setColor(Color.BLACK);
++ g.fillRect(0, 0, dstImg.getWidth(null), dstImg.getHeight(null));
++ g.setColor(Color.WHITE);
++ g.drawString("Test", 0, 15);
++
++ BufferedImage readBackImg = new BufferedImage(dstImg.getWidth(null),
++ dstImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
++ readBackImg.getGraphics().drawImage(dstImg, 0, 0, null);
++
++ for (int x = 0; x < readBackImg.getWidth(); x++) {
++ for (int y = 0; y < readBackImg.getHeight(); y++) {
++ int pixel = readBackImg.getRGB(x, y);
++
++ // In case a single white pixel is found, the
++ // setColor(Color.WHITE)
++ // call before was not ignored and the bug is not present
++ if (pixel == 0xFFFFFFFF) {
++ return;
++ }
++ }
++ }
++
++ throw new RuntimeException("Test Failed");
++ }
++
++ public static void main(String[] args) throws Exception {
++ SwingUtilities.invokeLater(new Runnable() {
++ public void run() {
++ new WhiteTextColorTest();
++ }
++ });
++ }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,161 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.awt.Color;
++import java.awt.Dialog;
++import java.awt.Graphics;
++import java.awt.Graphics2D;
++import java.awt.Panel;
++import java.awt.Rectangle;
++import java.awt.Robot;
++import java.awt.SplashScreen;
++import java.awt.Window;
++import java.awt.image.BufferedImage;
++import java.io.File;
++import javax.imageio.ImageIO;
++import sun.java2d.SunGraphics2D;
++
++/**
++ * @test
++ * @bug 8043869
++ * @author Alexander Scherbatiy
++ * @summary [macosx] java -splash does not honor 2x hi dpi notation for retina
++ * support
++ * @run main MultiResolutionSplashTest GENERATE_IMAGES
++ * @run main/othervm -splash:splash1.png MultiResolutionSplashTest TEST_SPLASH 0
++ * @run main/othervm -splash:splash2 MultiResolutionSplashTest TEST_SPLASH 1
++ * @run main/othervm -splash:splash3. MultiResolutionSplashTest TEST_SPLASH 2
++ */
++public class MultiResolutionSplashTest {
++
++ private static final int IMAGE_WIDTH = 300;
++ private static final int IMAGE_HEIGHT = 200;
++
++ private static final ImageInfo[] tests = {
++ new ImageInfo("splash1.png", "splash1@2x.png", Color.BLUE, Color.GREEN),
++ new ImageInfo("splash2", "splash2@2x", Color.WHITE, Color.BLACK),
++ new ImageInfo("splash3.", "splash3@2x.", Color.YELLOW, Color.RED)
++ };
++
++ public static void main(String[] args) throws Exception {
++
++ String test = args[0];
++
++ switch (test) {
++ case "GENERATE_IMAGES":
++ generateImages();
++ break;
++ case "TEST_SPLASH":
++ int index = Integer.parseInt(args[1]);
++ testSplash(tests[index]);
++ break;
++ default:
++ throw new RuntimeException("Unknown test: " + test);
++ }
++ }
++
++ static void testSplash(ImageInfo test) throws Exception {
++ SplashScreen splashScreen = SplashScreen.getSplashScreen();
++
++ if (splashScreen == null) {
++ throw new RuntimeException("Splash screen is not shown!");
++ }
++
++ Graphics2D g = splashScreen.createGraphics();
++ Rectangle splashBounds = splashScreen.getBounds();
++ int screenX = (int) splashBounds.getCenterX();
++ int screenY = (int) splashBounds.getCenterY();
++
++ Robot robot = new Robot();
++ Color splashScreenColor = robot.getPixelColor(screenX, screenY);
++
++ float scaleFactor = getScaleFactor();
++ Color testColor = (1 < scaleFactor) ? test.color2x : test.color1x;
++
++ if (!testColor.equals(splashScreenColor)) {
++ throw new RuntimeException(
++ "Image with wrong resolution is used for splash screen!");
++ }
++ }
++
++ static float getScaleFactor() {
++
++ final Dialog dialog = new Dialog((Window) null);
++ dialog.setSize(100, 100);
++ dialog.setModal(true);
++ final float[] scaleFactors = new float[1];
++ Panel panel = new Panel() {
++
++ @Override
++ public void paint(Graphics g) {
++ float scaleFactor = 1;
++ if (g instanceof SunGraphics2D) {
++ scaleFactor = ((SunGraphics2D) g).surfaceData.getDefaultScale();
++ }
++ scaleFactors[0] = scaleFactor;
++ dialog.setVisible(false);
++ }
++ };
++
++ dialog.add(panel);
++ dialog.setVisible(true);
++ dialog.dispose();
++
++ return scaleFactors[0];
++ }
++
++ static void generateImages() throws Exception {
++ for (ImageInfo test : tests) {
++ generateImage(test.name1x, test.color1x, 1);
++ generateImage(test.name2x, test.color2x, 2);
++ }
++ }
++
++ static void generateImage(String name, Color color, int scale) throws Exception {
++ File file = new File(name);
++ if (file.exists()) {
++ return;
++ }
++ BufferedImage image = new BufferedImage(scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT,
++ BufferedImage.TYPE_INT_RGB);
++ Graphics g = image.getGraphics();
++ g.setColor(color);
++ g.fillRect(0, 0, scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT);
++ ImageIO.write(image, "png", file);
++ }
++
++ static class ImageInfo {
++
++ final String name1x;
++ final String name2x;
++ final Color color1x;
++ final Color color2x;
++
++ public ImageInfo(String name1x, String name2x, Color color1x, Color color2x) {
++ this.name1x = name1x;
++ this.name2x = name2x;
++ this.color1x = color1x;
++ this.color2x = color2x;
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/Window/AlwaysOnTop/SyncAlwaysOnTopFieldTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.awt.Window;
++
++/**
++ * @test
++ * @bug 8064468
++ * @author Alexander Scherbatiy
++ * @summary ownedWindowList access requires synchronization in
++ * Window.setAlwaysOnTop() method
++ * @run main SyncAlwaysOnTopFieldTest
++ */
++public class SyncAlwaysOnTopFieldTest {
++
++ private static final int WINDOWS_COUNT = 200;
++ private static final int STEPS_COUNT = 20;
++
++ public static void main(String[] args) throws Exception {
++ final Window rootWindow = createWindow(null);
++
++ new Thread(() -> {
++ for (int i = 0; i < WINDOWS_COUNT; i++) {
++ createWindow(rootWindow);
++ }
++ }).start();
++
++ boolean alwaysOnTop = true;
++ for (int i = 0; i < STEPS_COUNT; i++) {
++ Thread.sleep(10);
++ rootWindow.setAlwaysOnTop(alwaysOnTop);
++ alwaysOnTop = !alwaysOnTop;
++ }
++ }
++
++ private static Window createWindow(Window parent) {
++ Window window = new Window(parent);
++ window.setSize(200, 200);
++ window.setVisible(true);
++ return window;
++ }
++}
+\ No newline at end of file
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/datatransfer/MappingGenerationTest/MappingGenerationTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,183 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.awt.datatransfer.DataFlavor;
++import java.awt.datatransfer.SystemFlavorMap;
++import java.util.List;
++
++/*
++ @test
++ @bug 4512530 8027148
++ @summary tests that mappings for text flavors are generated properly
++ @author das@sparc.spb.su area=datatransfer
++*/
++
++public class MappingGenerationTest {
++
++ private static final SystemFlavorMap fm =
++ (SystemFlavorMap)SystemFlavorMap.getDefaultFlavorMap();
++
++ public static void main(String[] args) {
++ test1();
++ test2();
++ test3();
++ test4();
++ test5();
++ test6();
++ }
++
++ /**
++ * Verifies that Lists returned from getNativesForFlavor() and
++ * getFlavorsForNative() are not modified with a subsequent call
++ * to addUnencodedNativeForFlavor() and addFlavorForUnencodedNative()
++ * respectively.
++ */
++ public static void test1() {
++ DataFlavor df = new DataFlavor("text/plain-test1", null);
++ String nat = "native1";
++
++ List<String> natives = fm.getNativesForFlavor(df);
++ fm.addUnencodedNativeForFlavor(df, nat);
++ List<String> nativesNew = fm.getNativesForFlavor(df);
++ if (natives.equals(nativesNew)) {
++ System.err.println("orig=" + natives);
++ System.err.println("new=" + nativesNew);
++ throw new RuntimeException("Test failed");
++ }
++
++ List<DataFlavor> flavors = fm.getFlavorsForNative(nat);
++ fm.addFlavorForUnencodedNative(nat, df);
++ List<DataFlavor> flavorsNew = fm.getFlavorsForNative(nat);
++ if (flavors.equals(flavorsNew)) {
++ System.err.println("orig=" + flavors);
++ System.err.println("new=" + flavorsNew);
++ throw new RuntimeException("Test failed");
++ }
++ }
++
++ /**
++ * Verifies that SystemFlavorMap is not affected by modification of
++ * the Lists returned from getNativesForFlavor() and
++ * getFlavorsForNative().
++ */
++ public static void test2() {
++ DataFlavor df = new DataFlavor("text/plain-test2", null);
++ String nat = "native2";
++ DataFlavor extraDf = new DataFlavor("text/test", null);
++
++ List<String> natives = fm.getNativesForFlavor(df);
++ natives.add("Should not be here");
++ java.util.List nativesNew = fm.getNativesForFlavor(df);
++ if (natives.equals(nativesNew)) {
++ System.err.println("orig=" + natives);
++ System.err.println("new=" + nativesNew);
++ throw new RuntimeException("Test failed");
++ }
++
++ List<DataFlavor> flavors = fm.getFlavorsForNative(nat);
++ flavors.add(extraDf);
++ java.util.List flavorsNew = fm.getFlavorsForNative(nat);
++ if (flavors.equals(flavorsNew)) {
++ System.err.println("orig=" + flavors);
++ System.err.println("new=" + flavorsNew);
++ throw new RuntimeException("Test failed");
++ }
++ }
++
++ /**
++ * Verifies that addUnencodedNativeForFlavor() for a particular text flavor
++ * doesn't affect mappings for other flavors.
++ */
++ public static void test3() {
++ DataFlavor df1 = new DataFlavor("text/plain-test3", null);
++ DataFlavor df2 = new DataFlavor("text/plain-test3; charset=Unicode; class=java.io.Reader", null);
++ String nat = "native3";
++ List<String> natives = fm.getNativesForFlavor(df2);
++ fm.addUnencodedNativeForFlavor(df1, nat);
++ List<String> nativesNew = fm.getNativesForFlavor(df2);
++ if (!natives.equals(nativesNew)) {
++ System.err.println("orig=" + natives);
++ System.err.println("new=" + nativesNew);
++ throw new RuntimeException("Test failed");
++ }
++ }
++
++ /**
++ * Verifies that addUnencodedNativeForFlavor() really adds the specified
++ * flavor-to-native mapping to the existing mappings.
++ */
++ public static void test4() {
++ DataFlavor df = new DataFlavor("text/plain-test4; charset=Unicode; class=java.io.Reader", null);
++ String nat = "native4";
++ List<String> natives = fm.getNativesForFlavor(df);
++ if (!natives.contains(nat)) {
++ fm.addUnencodedNativeForFlavor(df, nat);
++ List<String> nativesNew = fm.getNativesForFlavor(df);
++ natives.add(nat);
++ if (!natives.equals(nativesNew)) {
++ System.err.println("orig=" + natives);
++ System.err.println("new=" + nativesNew);
++ throw new RuntimeException("Test failed");
++ }
++ }
++ }
++
++ /**
++ * Verifies that a flavor doesn't have any flavor-to-native mappings after
++ * a call to setNativesForFlavor() with this flavor and an empty native
++ * array as arguments.
++ */
++ public static void test5() {
++ final DataFlavor flavor =
++ new DataFlavor("text/plain-TEST5; charset=Unicode", null);
++
++ fm.getNativesForFlavor(flavor);
++
++ fm.setNativesForFlavor(flavor, new String[0]);
++
++ List<String> natives = fm.getNativesForFlavor(flavor);
++
++ if (!natives.isEmpty()) {
++ System.err.println("natives=" + natives);
++ throw new RuntimeException("Test failed");
++ }
++ }
++
++ /**
++ * Verifies that a native doesn't have any native-to-flavor mappings after
++ * a call to setFlavorsForNative() with this native and an empty flavor
++ * array as arguments.
++ */
++ public static void test6() {
++ final String nat = "STRING";
++ fm.getFlavorsForNative(nat);
++ fm.setFlavorsForNative(nat, new DataFlavor[0]);
++
++ List<DataFlavor> flavors = fm.getFlavorsForNative(nat);
++
++ if (!flavors.isEmpty()) {
++ System.err.println("flavors=" + flavors);
++ throw new RuntimeException("Test failed");
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/event/InputEvent/EventWhenTest/EventWhenTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,132 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import sun.awt.SunToolkit;
++
++import java.awt.*;
++import java.awt.event.AWTEventListener;
++import java.awt.event.InputEvent;
++import java.awt.event.KeyEvent;
++import java.awt.event.MouseEvent;
++
++/*
++ * @test
++ * @bug 8046495
++ * @summary Verifies that mouse/key events has always increasing 'when' timestamps
++ * @author Anton Nashatyrev
++ * @run main EventWhenTest
++ */
++public class EventWhenTest {
++
++ private static volatile int eventsCount = 0;
++ private static volatile boolean failed = false;
++
++ static {
++ Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
++ long lastWhen = 0;
++
++ @Override
++ public void eventDispatched(AWTEvent event) {
++ long curWhen;
++ if (event instanceof KeyEvent) {
++ curWhen = ((KeyEvent) event).getWhen();
++ } else if (event instanceof MouseEvent) {
++ curWhen = ((MouseEvent) event).getWhen();
++ } else {
++ return;
++ }
++
++ eventsCount++;
++
++ if (curWhen < lastWhen) {
++ System.err.println("FAILED: " + curWhen + " < " + lastWhen +
++ " for " + event);
++ failed = true;
++ } else {
++ lastWhen = curWhen;
++ }
++ }
++ }, AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK);
++ }
++
++ public static void main(String[] args) throws Exception {
++
++ SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
++ Frame frame = new Frame();
++
++ try {
++ Button b = new Button("Button");
++ frame.setBounds(300, 300, 300, 300);
++ frame.add(b);
++ frame.setVisible(true);
++ toolkit.realSync();
++
++ Robot robot = new Robot();
++ robot.mouseMove((int)frame.getLocationOnScreen().getX() + 150,
++ (int)frame.getLocationOnScreen().getY() + 150);
++
++ eventsCount = 0;
++ System.out.println("Clicking mouse...");
++ for (int i = 0; i < 300 && !failed; i++) {
++ robot.mousePress(InputEvent.BUTTON1_MASK);
++ robot.mouseRelease(InputEvent.BUTTON1_MASK);
++ Thread.sleep(10);
++ b.setLabel("Click: " + i);
++ }
++
++ if (eventsCount == 0) {
++ throw new RuntimeException("No events were received");
++ }
++
++ if (failed) {
++ throw new RuntimeException("Test failed.");
++ }
++ System.out.println("Clicking mouse done: " + eventsCount + " events.");
++
++ b.requestFocusInWindow();
++ toolkit.realSync();
++
++ eventsCount = 0;
++ System.out.println("Typing a key...");
++ for (int i = 0; i < 300 && !failed; i++) {
++ robot.keyPress(KeyEvent.VK_A);
++ robot.keyRelease(KeyEvent.VK_A);
++ Thread.sleep(10);
++ b.setLabel("Type: " + i);
++ }
++ System.out.println("Key typing done: " + eventsCount + " events.");
++
++ if (eventsCount == 0) {
++ throw new RuntimeException("No events were received");
++ }
++
++ if (failed) {
++ throw new RuntimeException("Test failed.");
++ }
++
++ System.out.println("Success!");
++ } finally {
++ frame.dispose();
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/image/DrawImage/DrawImageCoordsTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,68 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8028539
++ * @summary Test that drawing a scaled image terminates.
++ * @run main/othervm/timeout=60 DrawImageCoordsTest
++*/
++
++import java.awt.Color;
++import java.awt.Graphics;
++import java.awt.Graphics2D;
++import java.awt.geom.AffineTransform;
++import java.awt.image.BufferedImage;
++
++public class DrawImageCoordsTest {
++
++ public static void main(String[] args) {
++
++ /* Create an image to draw, filled in solid red. */
++ BufferedImage srcImg =
++ new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
++ Graphics srcG = srcImg.createGraphics();
++ srcG.setColor(Color.red);
++ int w = srcImg.getWidth(null);
++ int h = srcImg.getHeight(null);
++ srcG.fillRect(0, 0, w, h);
++
++ /* Create a destination image */
++ BufferedImage dstImage =
++ new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
++ Graphics2D dstG = dstImage.createGraphics();
++ /* draw image under a scaling transform that overflows int */
++ AffineTransform tx = new AffineTransform(0.5, 0, 0, 0.5,
++ 0, 5.8658460197478485E9);
++ dstG.setTransform(tx);
++ dstG.drawImage(srcImg, 0, 0, null );
++ /* draw image under the same overflowing transform, cancelling
++ * out the 0.5 scale on the graphics
++ */
++ dstG.drawImage(srcImg, 0, 0, 2*w, 2*h, null);
++ if (Color.red.getRGB() == dstImage.getRGB(w/2, h/2)) {
++ throw new RuntimeException("Unexpected color: clipping failed.");
++ }
++ System.out.println("Test Thread Completed");
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/image/DrawImage/IncorrectAlphaConversionBicubic.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,113 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.awt.AlphaComposite;
++import java.awt.Color;
++import java.awt.Graphics2D;
++import java.awt.GraphicsConfiguration;
++import java.awt.GraphicsDevice;
++import java.awt.GraphicsEnvironment;
++import java.awt.RenderingHints;
++import java.awt.image.BufferedImage;
++import java.awt.image.DataBuffer;
++import java.awt.image.DataBufferByte;
++import java.awt.image.DataBufferInt;
++import java.awt.image.DataBufferShort;
++import java.awt.image.VolatileImage;
++
++import static java.awt.Transparency.TRANSLUCENT;
++
++/**
++ * @test
++ * @bug 8062164
++ * @summary We should get correct alpha, when we draw to/from VolatileImage and
++ * bicubic interpolation is enabled
++ * @author Sergey Bylokhov
++ */
++public final class IncorrectAlphaConversionBicubic {
++
++ private static final Color RGB = new Color(200, 255, 7, 123);
++ private static final int SIZE = 100;
++
++ public static void main(final String[] args) {
++ final GraphicsEnvironment ge =
++ GraphicsEnvironment.getLocalGraphicsEnvironment();
++ final GraphicsDevice gd = ge.getDefaultScreenDevice();
++ final GraphicsConfiguration gc = gd.getDefaultConfiguration();
++ final VolatileImage vi =
++ gc.createCompatibleVolatileImage(SIZE, SIZE, TRANSLUCENT);
++ final BufferedImage bi = makeUnmanagedBI(gc, TRANSLUCENT);
++ final int expected = bi.getRGB(2, 2);
++
++ int attempt = 0;
++ BufferedImage snapshot;
++ while (true) {
++ if (++attempt > 10) {
++ throw new RuntimeException("Too many attempts: " + attempt);
++ }
++ vi.validate(gc);
++ final Graphics2D g2d = vi.createGraphics();
++ g2d.setComposite(AlphaComposite.Src);
++ g2d.scale(2, 2);
++ g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
++ RenderingHints.VALUE_INTERPOLATION_BICUBIC);
++ g2d.drawImage(bi, 0, 0, null);
++ g2d.dispose();
++
++ snapshot = vi.getSnapshot();
++ if (vi.contentsLost()) {
++ continue;
++ }
++ break;
++ }
++ final int actual = snapshot.getRGB(2, 2);
++ if (actual != expected) {
++ System.err.println("Actual: " + Integer.toHexString(actual));
++ System.err.println("Expected: " + Integer.toHexString(expected));
++ throw new RuntimeException("Test failed");
++ }
++ }
++
++ private static BufferedImage makeUnmanagedBI(GraphicsConfiguration gc,
++ int type) {
++ BufferedImage img = gc.createCompatibleImage(SIZE, SIZE, type);
++ Graphics2D g2d = img.createGraphics();
++ g2d.setColor(RGB);
++ g2d.fillRect(0, 0, SIZE, SIZE);
++ g2d.dispose();
++ final DataBuffer db = img.getRaster().getDataBuffer();
++ if (db instanceof DataBufferInt) {
++ ((DataBufferInt) db).getData();
++ } else if (db instanceof DataBufferShort) {
++ ((DataBufferShort) db).getData();
++ } else if (db instanceof DataBufferByte) {
++ ((DataBufferByte) db).getData();
++ } else {
++ try {
++ img.setAccelerationPriority(0.0f);
++ } catch (final Throwable ignored) {
++ }
++ }
++ return img;
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/image/DrawImage/IncorrectClipXorModeSW2Surface.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,179 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.awt.Color;
++import java.awt.Graphics2D;
++import java.awt.GraphicsConfiguration;
++import java.awt.GraphicsEnvironment;
++import java.awt.Image;
++import java.awt.Rectangle;
++import java.awt.Shape;
++import java.awt.geom.AffineTransform;
++import java.awt.image.BufferedImage;
++import java.awt.image.DataBuffer;
++import java.awt.image.DataBufferByte;
++import java.awt.image.DataBufferInt;
++import java.awt.image.DataBufferShort;
++import java.awt.image.VolatileImage;
++import java.io.File;
++import java.io.IOException;
++
++import javax.imageio.ImageIO;
++
++import static java.awt.geom.Rectangle2D.Double;
++
++/**
++ * @test
++ * @bug 8061456
++ * @summary Tests drawing BI to volatile image using different clips + xor mode.
++ * Results of the blit BI to compatibleImage is used for comparison.
++ * @author Sergey Bylokhov
++ */
++public final class IncorrectClipXorModeSW2Surface {
++
++ private static int[] SIZES = {2, 10, 100};
++ private static final Shape[] SHAPES = {
++ new Rectangle(0, 0, 0, 0),
++ new Rectangle(0, 0, 1, 1),
++ new Rectangle(0, 1, 1, 1),
++ new Rectangle(1, 0, 1, 1),
++ new Rectangle(1, 1, 1, 1),
++
++ new Double(0, 0, 0.5, 0.5),
++ new Double(0, 0.5, 0.5, 0.5),
++ new Double(0.5, 0, 0.5, 0.5),
++ new Double(0.5, 0.5, 0.5, 0.5),
++ new Double(0.25, 0.25, 0.5, 0.5),
++ new Double(0, 0.25, 1, 0.5),
++ new Double(0.25, 0, 0.5, 1),
++
++ new Double(.10, .10, .20, .20),
++ new Double(.75, .75, .20, .20),
++ new Double(.75, .10, .20, .20),
++ new Double(.10, .75, .20, .20),
++ };
++
++ public static void main(final String[] args) throws IOException {
++ GraphicsEnvironment ge = GraphicsEnvironment
++ .getLocalGraphicsEnvironment();
++ GraphicsConfiguration gc = ge.getDefaultScreenDevice()
++ .getDefaultConfiguration();
++ AffineTransform at;
++ for (int size : SIZES) {
++ at = AffineTransform.getScaleInstance(size, size);
++ for (Shape clip : SHAPES) {
++ clip = at.createTransformedShape(clip);
++ for (Shape to : SHAPES) {
++ to = at.createTransformedShape(to);
++ // Prepare test images
++ BufferedImage snapshot;
++ BufferedImage bi = getBufferedImage(size);
++ VolatileImage vi = getVolatileImage(gc, size);
++ while (true) {
++ vi.validate(gc);
++ Graphics2D g2d = vi.createGraphics();
++ g2d.setColor(Color.GREEN);
++ g2d.fillRect(0, 0, size, size);
++ g2d.dispose();
++ if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
++ continue;
++ }
++ draw(clip, to, bi, vi);
++ snapshot = vi.getSnapshot();
++ if (vi.contentsLost()) {
++ continue;
++ }
++ break;
++ }
++ // Prepare gold images
++ BufferedImage goldvi = getCompatibleImage(gc, size);
++ BufferedImage goldbi = getBufferedImage(size);
++ draw(clip, to, goldbi, goldvi);
++ validate(snapshot, goldvi);
++ vi.flush();
++ }
++ }
++ }
++ }
++
++ private static void draw(Shape clip, Shape shape, Image from, Image to) {
++ Graphics2D g2d = (Graphics2D) to.getGraphics();
++ g2d.setXORMode(Color.BLACK);
++ g2d.setClip(clip);
++ Rectangle toBounds = shape.getBounds();
++ g2d.drawImage(from, toBounds.x, toBounds.y, toBounds.width,
++ toBounds.height, null);
++ g2d.dispose();
++ }
++
++ private static BufferedImage getBufferedImage(int sw) {
++ final BufferedImage bi = new BufferedImage(sw, sw, BufferedImage.TYPE_INT_ARGB);
++ Graphics2D g2d = bi.createGraphics();
++ g2d.setColor(Color.RED);
++ g2d.fillRect(0, 0, sw, sw);
++ g2d.dispose();
++
++ final DataBuffer db = bi.getRaster().getDataBuffer();
++ if (db instanceof DataBufferInt) {
++ ((DataBufferInt) db).getData();
++ } else if (db instanceof DataBufferShort) {
++ ((DataBufferShort) db).getData();
++ } else if (db instanceof DataBufferByte) {
++ ((DataBufferByte) db).getData();
++ } else {
++ try {
++ bi.setAccelerationPriority(0.0f);
++ } catch (final Throwable ignored) {
++ }
++ }
++ return bi;
++ }
++
++ private static VolatileImage getVolatileImage(GraphicsConfiguration gc,
++ int size) {
++ return gc.createCompatibleVolatileImage(size, size);
++ }
++
++ private static BufferedImage getCompatibleImage(GraphicsConfiguration gc,
++ int size) {
++ BufferedImage image = gc.createCompatibleImage(size, size);
++ Graphics2D g2d = image.createGraphics();
++ g2d.setColor(Color.GREEN);
++ g2d.fillRect(0, 0, size, size);
++ g2d.dispose();
++ return image;
++ }
++
++ private static void validate(BufferedImage bi, BufferedImage goldbi)
++ throws IOException {
++ for (int x = 0; x < bi.getWidth(); ++x) {
++ for (int y = 0; y < bi.getHeight(); ++y) {
++ if (goldbi.getRGB(x, y) != bi.getRGB(x, y)) {
++ ImageIO.write(bi, "png", new File("actual.png"));
++ ImageIO.write(goldbi, "png", new File("expected.png"));
++ throw new RuntimeException("Test failed.");
++ }
++ }
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/image/DrawImage/IncorrectUnmanagedImageRotatedClip.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,138 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.awt.AlphaComposite;
++import java.awt.Color;
++import java.awt.Graphics2D;
++import java.awt.GraphicsConfiguration;
++import java.awt.GraphicsEnvironment;
++import java.awt.Image;
++import java.awt.Rectangle;
++import java.awt.image.BufferedImage;
++import java.awt.image.DataBuffer;
++import java.awt.image.DataBufferByte;
++import java.awt.image.DataBufferInt;
++import java.awt.image.DataBufferShort;
++import java.awt.image.VolatileImage;
++import java.io.File;
++import java.io.IOException;
++
++import javax.imageio.ImageIO;
++
++import static java.awt.Transparency.TRANSLUCENT;
++import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
++
++/**
++ * @test
++ * @bug 8059942
++ * @summary Tests rotated clip when unmanaged image is drawn to VI.
++ * Results of the blit to compatibleImage are used for comparison.
++ * @author Sergey Bylokhov
++ */
++public final class IncorrectUnmanagedImageRotatedClip {
++
++ public static void main(final String[] args) throws IOException {
++ BufferedImage bi = makeUnmanagedBI();
++ fill(bi);
++ test(bi);
++ }
++
++ private static void test(final BufferedImage bi) throws IOException {
++ GraphicsEnvironment ge = GraphicsEnvironment
++ .getLocalGraphicsEnvironment();
++ GraphicsConfiguration gc = ge.getDefaultScreenDevice()
++ .getDefaultConfiguration();
++ VolatileImage vi = gc.createCompatibleVolatileImage(500, 200,
++ TRANSLUCENT);
++ BufferedImage gold = gc.createCompatibleImage(500, 200, TRANSLUCENT);
++ // draw to compatible Image
++ draw(bi, gold);
++ // draw to volatile image
++ int attempt = 0;
++ BufferedImage snapshot;
++ while (true) {
++ if (++attempt > 10) {
++ throw new RuntimeException("Too many attempts: " + attempt);
++ }
++ vi.validate(gc);
++ if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
++ continue;
++ }
++ draw(bi, vi);
++ snapshot = vi.getSnapshot();
++ if (vi.contentsLost()) {
++ continue;
++ }
++ break;
++ }
++ // validate images
++ for (int x = 0; x < gold.getWidth(); ++x) {
++ for (int y = 0; y < gold.getHeight(); ++y) {
++ if (gold.getRGB(x, y) != snapshot.getRGB(x, y)) {
++ ImageIO.write(gold, "png", new File("gold.png"));
++ ImageIO.write(snapshot, "png", new File("bi.png"));
++ throw new RuntimeException("Test failed.");
++ }
++ }
++ }
++ }
++
++ private static void draw(final BufferedImage from,final Image to) {
++ final Graphics2D g2d = (Graphics2D) to.getGraphics();
++ g2d.setComposite(AlphaComposite.Src);
++ g2d.setColor(Color.ORANGE);
++ g2d.fillRect(0, 0, to.getWidth(null), to.getHeight(null));
++ g2d.rotate(Math.toRadians(45));
++ g2d.clip(new Rectangle(41, 42, 43, 44));
++ g2d.drawImage(from, 50, 50, Color.blue, null);
++ g2d.dispose();
++ }
++
++ private static BufferedImage makeUnmanagedBI() {
++ final BufferedImage bi = new BufferedImage(500, 200, TYPE_INT_ARGB);
++ final DataBuffer db = bi.getRaster().getDataBuffer();
++ if (db instanceof DataBufferInt) {
++ ((DataBufferInt) db).getData();
++ } else if (db instanceof DataBufferShort) {
++ ((DataBufferShort) db).getData();
++ } else if (db instanceof DataBufferByte) {
++ ((DataBufferByte) db).getData();
++ } else {
++ try {
++ bi.setAccelerationPriority(0.0f);
++ } catch (final Throwable ignored) {
++ }
++ }
++ return bi;
++ }
++
++ private static void fill(final Image image) {
++ final Graphics2D graphics = (Graphics2D) image.getGraphics();
++ graphics.setComposite(AlphaComposite.Src);
++ for (int i = 0; i < image.getHeight(null); ++i) {
++ graphics.setColor(new Color(i, 0, 0));
++ graphics.fillRect(0, i, image.getWidth(null), 1);
++ }
++ graphics.dispose();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/image/DrawImage/IncorrectUnmanagedImageSourceOffset.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,150 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.awt.AlphaComposite;
++import java.awt.Color;
++import java.awt.Graphics2D;
++import java.awt.GraphicsConfiguration;
++import java.awt.GraphicsEnvironment;
++import java.awt.Image;
++import java.awt.image.BufferedImage;
++import java.awt.image.DataBuffer;
++import java.awt.image.DataBufferByte;
++import java.awt.image.DataBufferInt;
++import java.awt.image.DataBufferShort;
++import java.awt.image.VolatileImage;
++import java.io.File;
++import java.io.IOException;
++
++import javax.imageio.ImageIO;
++
++import static java.awt.Transparency.*;
++import static java.awt.image.BufferedImage.*;
++
++/**
++ * @test
++ * @bug 8029253
++ * @summary Tests asymmetric source offsets when unmanaged image is drawn to VI.
++ * Results of the blit to compatibleImage are used for comparison.
++ * @author Sergey Bylokhov
++ */
++public final class IncorrectUnmanagedImageSourceOffset {
++
++ private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB,
++ TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
++ TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR,
++ TYPE_4BYTE_ABGR_PRE,
++ /*TYPE_USHORT_565_RGB,
++ TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
++ TYPE_USHORT_GRAY,*/ TYPE_BYTE_BINARY,
++ TYPE_BYTE_INDEXED};
++ private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT};
++
++ public static void main(final String[] args) throws IOException {
++ for (final int viType : TRANSPARENCIES) {
++ for (final int biType : TYPES) {
++ BufferedImage bi = makeUnmanagedBI(biType);
++ fill(bi);
++ test(bi, viType);
++ }
++ }
++ }
++
++ private static void test(BufferedImage bi, int type)
++ throws IOException {
++ GraphicsEnvironment ge = GraphicsEnvironment
++ .getLocalGraphicsEnvironment();
++ GraphicsConfiguration gc = ge.getDefaultScreenDevice()
++ .getDefaultConfiguration();
++ VolatileImage vi = gc.createCompatibleVolatileImage(511, 255, type);
++ BufferedImage gold = gc.createCompatibleImage(511, 255, type);
++ // draw to compatible Image
++ Graphics2D big = gold.createGraphics();
++ // force scaled blit
++ big.drawImage(bi, 7, 11, 127, 111, 7, 11, 127 * 2, 111, null);
++ big.dispose();
++ // draw to volatile image
++ BufferedImage snapshot;
++ while (true) {
++ vi.validate(gc);
++ if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
++ try {
++ Thread.sleep(100);
++ } catch (final InterruptedException ignored) {
++ }
++ continue;
++ }
++ Graphics2D vig = vi.createGraphics();
++ // force scaled blit
++ vig.drawImage(bi, 7, 11, 127, 111, 7, 11, 127 * 2, 111, null);
++ vig.dispose();
++ snapshot = vi.getSnapshot();
++ if (vi.contentsLost()) {
++ try {
++ Thread.sleep(100);
++ } catch (final InterruptedException ignored) {
++ }
++ continue;
++ }
++ break;
++ }
++ // validate images
++ for (int x = 7; x < 127; ++x) {
++ for (int y = 11; y < 111; ++y) {
++ if (gold.getRGB(x, y) != snapshot.getRGB(x, y)) {
++ ImageIO.write(gold, "png", new File("gold.png"));
++ ImageIO.write(snapshot, "png", new File("bi.png"));
++ throw new RuntimeException("Test failed.");
++ }
++ }
++ }
++ }
++
++ private static BufferedImage makeUnmanagedBI(final int type) {
++ final BufferedImage bi = new BufferedImage(511, 255, type);
++ final DataBuffer db = bi.getRaster().getDataBuffer();
++ if (db instanceof DataBufferInt) {
++ ((DataBufferInt) db).getData();
++ } else if (db instanceof DataBufferShort) {
++ ((DataBufferShort) db).getData();
++ } else if (db instanceof DataBufferByte) {
++ ((DataBufferByte) db).getData();
++ } else {
++ try {
++ bi.setAccelerationPriority(0.0f);
++ } catch (final Throwable ignored) {
++ }
++ }
++ return bi;
++ }
++
++ private static void fill(final Image image) {
++ final Graphics2D graphics = (Graphics2D) image.getGraphics();
++ graphics.setComposite(AlphaComposite.Src);
++ for (int i = 0; i < image.getHeight(null); ++i) {
++ graphics.setColor(new Color(i, 0, 0));
++ graphics.fillRect(0, i, image.getWidth(null), 1);
++ }
++ graphics.dispose();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,125 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.awt.AlphaComposite;
++import java.awt.Graphics2D;
++import java.awt.GraphicsConfiguration;
++import java.awt.GraphicsDevice;
++import java.awt.GraphicsEnvironment;
++import java.awt.Image;
++import java.awt.Polygon;
++import java.awt.geom.AffineTransform;
++import java.awt.image.BufferedImage;
++import java.awt.image.DataBuffer;
++import java.awt.image.DataBufferByte;
++import java.awt.image.DataBufferInt;
++import java.awt.image.DataBufferShort;
++import java.awt.image.VolatileImage;
++
++import static java.awt.Transparency.*;
++import static java.awt.image.BufferedImage.*;
++
++/*
++ * @test
++ * @bug 8029253 8059941
++ * @summary Unmanaged images should be drawn fast.
++ * @author Sergey Bylokhov
++ */
++public final class UnmanagedDrawImagePerformance {
++
++ private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB,
++ TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
++ TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR,
++ TYPE_4BYTE_ABGR_PRE,
++ TYPE_USHORT_565_RGB,
++ TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
++ TYPE_USHORT_GRAY, TYPE_BYTE_BINARY,
++ TYPE_BYTE_INDEXED};
++ private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT};
++ private static final int SIZE = 1000;
++ private static final AffineTransform[] TRANSFORMS = {
++ AffineTransform.getScaleInstance(.5, .5),
++ AffineTransform.getScaleInstance(1, 1),
++ AffineTransform.getScaleInstance(2, 2),
++ AffineTransform.getShearInstance(7, 11)};
++
++ public static void main(final String[] args) {
++ for (final AffineTransform atfm : TRANSFORMS) {
++ for (final int viType : TRANSPARENCIES) {
++ for (final int biType : TYPES) {
++ final BufferedImage bi = makeUnmanagedBI(biType);
++ final VolatileImage vi = makeVI(viType);
++ final long time = test(bi, vi, atfm) / 1000000000;
++ if (time > 1) {
++ throw new RuntimeException(String.format(
++ "drawImage is slow: %d seconds", time));
++ }
++ }
++ }
++ }
++ }
++
++ private static long test(Image bi, Image vi, AffineTransform atfm) {
++ final Polygon p = new Polygon();
++ p.addPoint(0, 0);
++ p.addPoint(SIZE, 0);
++ p.addPoint(0, SIZE);
++ p.addPoint(SIZE, SIZE);
++ p.addPoint(0, 0);
++ Graphics2D g2d = (Graphics2D) vi.getGraphics();
++ g2d.clip(p);
++ g2d.transform(atfm);
++ g2d.setComposite(AlphaComposite.SrcOver);
++ final long start = System.nanoTime();
++ g2d.drawImage(bi, 0, 0, null);
++ final long time = System.nanoTime() - start;
++ g2d.dispose();
++ return time;
++ }
++
++ private static VolatileImage makeVI(final int type) {
++ final GraphicsEnvironment ge = GraphicsEnvironment
++ .getLocalGraphicsEnvironment();
++ final GraphicsDevice gd = ge.getDefaultScreenDevice();
++ final GraphicsConfiguration gc = gd.getDefaultConfiguration();
++ return gc.createCompatibleVolatileImage(SIZE, SIZE, type);
++ }
++
++ private static BufferedImage makeUnmanagedBI(final int type) {
++ final BufferedImage img = new BufferedImage(SIZE, SIZE, type);
++ final DataBuffer db = img.getRaster().getDataBuffer();
++ if (db instanceof DataBufferInt) {
++ ((DataBufferInt) db).getData();
++ } else if (db instanceof DataBufferShort) {
++ ((DataBufferShort) db).getData();
++ } else if (db instanceof DataBufferByte) {
++ ((DataBufferByte) db).getData();
++ } else {
++ try {
++ img.setAccelerationPriority(0.0f);
++ } catch (final Throwable ignored) {
++ }
++ }
++ return img;
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/image/MultiResolutionImage/MultiResolutionImageObserverTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,120 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++import java.awt.Color;
++import java.awt.Graphics;
++import java.awt.Graphics2D;
++import java.awt.Image;
++import java.awt.Toolkit;
++import java.awt.image.BufferedImage;
++import java.awt.image.ImageObserver;
++import static java.awt.image.ImageObserver.*;
++import java.io.File;
++import javax.imageio.ImageIO;
++/*
++ * @test
++ * @bug 8065627
++ * @summary Animated GIFs fail to display on a HiDPI display
++ * @author Alexander Scherbatiy
++ * @run main MultiResolutionImageObserverTest
++ */
++
++public class MultiResolutionImageObserverTest {
++
++ private static final int TIMEOUT = 500;
++
++ public static void main(String[] args) throws Exception {
++
++ generateImages();
++ Toolkit toolkit = Toolkit.getDefaultToolkit();
++ Image image = Toolkit.getDefaultToolkit().getImage(IMAGE_NAME_1X);
++
++ LoadImageObserver sizeObserver
++ = new LoadImageObserver(WIDTH | HEIGHT);
++ toolkit.prepareImage(image, -1, -1, sizeObserver);
++ waitForImageLoading(sizeObserver, "The first observer is not called");
++
++ LoadImageObserver bitsObserver
++ = new LoadImageObserver(SOMEBITS | FRAMEBITS | ALLBITS);
++
++ BufferedImage buffImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
++ Graphics2D g2d = (Graphics2D) buffImage.createGraphics();
++ g2d.scale(2, 2);
++ g2d.drawImage(image, 0, 0, bitsObserver);
++ waitForImageLoading(bitsObserver, "The second observer is not called!");
++ g2d.dispose();
++ }
++
++ private static void waitForImageLoading(LoadImageObserver observer,
++ String errorMessage) throws Exception {
++
++ long endTime = System.currentTimeMillis() + TIMEOUT;
++
++ while (!observer.loaded && System.currentTimeMillis() < endTime) {
++ Thread.sleep(TIMEOUT / 10);
++ }
++
++ if (!observer.loaded) {
++ throw new RuntimeException(errorMessage);
++ }
++ }
++
++ private static final String IMAGE_NAME_1X = "image.png";
++ private static final String IMAGE_NAME_2X = "image@2x.png";
++
++ private static void generateImages() throws Exception {
++ generateImage(1);
++ generateImage(2);
++ }
++
++ private static void generateImage(int scale) throws Exception {
++ BufferedImage image = new BufferedImage(
++ scale * 200, scale * 300,
++ BufferedImage.TYPE_INT_RGB);
++ Graphics g = image.createGraphics();
++ g.setColor(scale == 1 ? Color.GREEN : Color.BLUE);
++ g.fillRect(0, 0, scale * 200, scale * 300);
++ File file = new File(scale == 1 ? IMAGE_NAME_1X : IMAGE_NAME_2X);
++ ImageIO.write(image, "png", file);
++ g.dispose();
++ }
++
++ private static class LoadImageObserver implements ImageObserver {
++
++ private final int infoflags;
++ private boolean loaded;
++
++ public LoadImageObserver(int flags) {
++ this.infoflags = flags;
++ }
++
++ @Override
++ public boolean imageUpdate(Image img, int flags, int x, int y, int width, int height) {
++
++ if ((flags & infoflags) != 0) {
++ loaded = true;
++ }
++
++ return !loaded;
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/awt/print/PrinterJob/ImagePrinting/NullClipARGB.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,74 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8061392
++ * @summary Test no NPE when printing transparency with null clip.
++ */
++
++import java.awt.*;
++import java.awt.image.*;
++import java.awt.print.*;
++
++public class NullClipARGB implements Printable {
++
++ public static void main( String[] args ) {
++
++ try {
++ PrinterJob pj = PrinterJob.getPrinterJob();
++ pj.setPrintable(new NullClipARGB());
++ pj.print();
++ } catch (Exception ex) {
++ throw new RuntimeException(ex);
++ }
++ }
++
++ public int print(Graphics g, PageFormat pf, int pageIndex)
++ throws PrinterException{
++
++ if (pageIndex != 0) {
++ return NO_SUCH_PAGE;
++ }
++ Graphics2D g2 = (Graphics2D)g;
++ System.out.println("original clip="+g2.getClip());
++ g2.translate(pf.getImageableX(), pf.getImageableY());
++ g2.rotate(0.2);
++ g2.setClip(null);
++ g2.setColor( Color.BLACK );
++ g2.drawString("This text should be visible through the image", 0, 20);
++ BufferedImage bi = new BufferedImage(100, 100,
++ BufferedImage.TYPE_INT_ARGB );
++ Graphics ig = bi.createGraphics();
++ ig.setColor( new Color( 192, 192, 192, 80 ) );
++ ig.fillRect( 0, 0, 100, 100 );
++ ig.setColor( Color.BLACK );
++ ig.drawRect( 0, 0, 99, 99 );
++ ig.dispose();
++ g2.drawImage(bi, 10, 0, 90, 90, null );
++ g2.translate(100, 100);
++ g2.drawString("This text should also be visible through the image", 0, 20);
++ g2.drawImage(bi, 10, 0, 90, 90, null );
++ return PAGE_EXISTS;
++ }
++}
+--- ./jdk/test/java/beans/Introspector/Test4168833.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/beans/Introspector/Test4168833.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -23,10 +23,11 @@
+
+ /*
+ * @test
+- * @bug 4168833
++ * @bug 4168833 8034085
+ * @summary Tests that Introspector does not create IndexedPropertyDescriptor
+ * from non-indexed PropertyDescriptor
+ * @author Mark Davidson
++ * @author Sergey Malenkov
+ */
+
+ import java.awt.Color;
+@@ -42,10 +43,6 @@
+ */
+ public class Test4168833 {
+ public static void main(String[] args) throws Exception {
+- IndexedPropertyDescriptor ipd = BeanUtils.getIndexedPropertyDescriptor(Base.class, "prop");
+- if (!ipd.getIndexedPropertyType().equals(Dimension.class)) {
+- error(ipd, "Base.prop property should a Dimension");
+- }
+ // When the Sub class is introspected,
+ // the property type should be color.
+ // The complete "classic" set of properties
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/beans/Introspector/Test8034085.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,236 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.awt.Window;
++import java.beans.IndexedPropertyDescriptor;
++import java.beans.PropertyDescriptor;
++
++/*
++ * @test
++ * @bug 8034085
++ * @summary Tests that Introspector ignores indexed getter and setter for incorrect types
++ * @author Sergey Malenkov
++ */
++
++public class Test8034085 {
++ public static final StringBuilder ERROR = new StringBuilder();
++
++ public static void main(String[] args) {
++ test(Window.class, false, true, false, false);
++
++ test(Bean0000.class, false, false, false, false);
++ test(Bean0001.class, false, false, false, true);
++ test(Bean0010.class, false, false, true, false);
++ test(Bean0011.class, false, false, true, true);
++ test(Bean0100.class, false, true, false, false);
++ test(Bean0101.class, false, true, false, false);
++ test(Bean0110.class, false, true, false, false);
++ test(Bean0111.class, false, true, false, false);
++ test(Bean1000.class, true, false, false, false);
++ test(Bean1001.class, true, false, false, false);
++ test(Bean1010.class, true, false, false, false);
++ test(Bean1011.class, true, false, false, false);
++ test(Bean1100.class, true, true, false, false);
++ test(Bean1101.class, true, true, false, false);
++ test(Bean1110.class, true, true, false, false);
++ test(Bean1111.class, true, true, false, false);
++
++ if (0 < ERROR.length()) {
++ throw new Error(ERROR.toString());
++ }
++ }
++
++ private static void test(Class<?> type, boolean read, boolean write, boolean readIndexed, boolean writeIndexed) {
++ PropertyDescriptor pd = BeanUtils.findPropertyDescriptor(type, "size");
++ if (pd != null) {
++ test(type, "read", read, null != pd.getReadMethod());
++ test(type, "write", write, null != pd.getWriteMethod());
++ if (pd instanceof IndexedPropertyDescriptor) {
++ IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
++ test(type, "indexed read", readIndexed, null != ipd.getIndexedReadMethod());
++ test(type, "indexed write", writeIndexed, null != ipd.getIndexedWriteMethod());
++ } else if (readIndexed || writeIndexed) {
++ error(type, "indexed property does not exist");
++ }
++ } else if (read || write || readIndexed || writeIndexed) {
++ error(type, "property does not exist");
++ }
++ }
++
++ private static void test(Class<?> type, String name, boolean expected, boolean actual) {
++ if (expected && !actual) {
++ error(type, name + " method does not exist");
++ } else if (!expected && actual) {
++ error(type, name + " method is not expected");
++ }
++ }
++
++ private static void error(Class<?> type, String message) {
++ ERROR.append("\n\t\t").append(type.getSimpleName()).append(".size: ").append(message);
++ }
++
++ public static class Bean0000 {
++ }
++
++ public static class Bean0001 {
++ public void setSize(int index, int value) {
++ }
++ }
++
++ public static class Bean0010 {
++ public int getSize(int index) {
++ return 0;
++ }
++ }
++
++ public static class Bean0011 {
++ public int getSize(int index) {
++ return 0;
++ }
++
++ public void setSize(int index, int value) {
++ }
++ }
++
++ public static class Bean0100 {
++ public void setSize(int value) {
++ }
++ }
++
++ public static class Bean0101 {
++ public void setSize(int value) {
++ }
++
++ public void setSize(int index, int value) {
++ }
++ }
++
++ public static class Bean0110 {
++ public void setSize(int value) {
++ }
++
++ public int getSize(int index) {
++ return 0;
++ }
++ }
++
++ public static class Bean0111 {
++ public void setSize(int value) {
++ }
++
++ public int getSize(int index) {
++ return 0;
++ }
++
++ public void setSize(int index, int value) {
++ }
++ }
++
++ public static class Bean1000 {
++ public int getSize() {
++ return 0;
++ }
++ }
++
++ public static class Bean1001 {
++ public int getSize() {
++ return 0;
++ }
++
++ public void setSize(int index, int value) {
++ }
++ }
++
++ public static class Bean1010 {
++ public int getSize() {
++ return 0;
++ }
++
++ public int getSize(int index) {
++ return 0;
++ }
++ }
++
++ public static class Bean1011 {
++ public int getSize() {
++ return 0;
++ }
++
++ public int getSize(int index) {
++ return 0;
++ }
++
++ public void setSize(int index, int value) {
++ }
++ }
++
++ public static class Bean1100 {
++ public int getSize() {
++ return 0;
++ }
++
++ public void setSize(int value) {
++ }
++ }
++
++ public static class Bean1101 {
++ public int getSize() {
++ return 0;
++ }
++
++ public void setSize(int value) {
++ }
++
++ public void setSize(int index, int value) {
++ }
++ }
++
++ public static class Bean1110 {
++ public int getSize() {
++ return 0;
++ }
++
++ public void setSize(int value) {
++ }
++
++ public int getSize(int index) {
++ return 0;
++ }
++ }
++
++ public static class Bean1111 {
++ public int getSize() {
++ return 0;
++ }
++
++ public void setSize(int value) {
++ }
++
++ public int getSize(int index) {
++ return 0;
++ }
++
++ public void setSize(int index, int value) {
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/beans/Introspector/Test8034164.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,233 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.beans.IndexedPropertyDescriptor;
++import java.beans.PropertyDescriptor;
++
++/*
++ * @test
++ * @bug 8034164
++ * @summary Tests that Introspector does not ignore indexed getter and setter for correct types
++ * @author Sergey Malenkov
++ */
++
++public class Test8034164 {
++ public static final StringBuilder ERROR = new StringBuilder();
++
++ public static void main(String[] args) {
++ test(Bean0000.class, false, false, false, false);
++ test(Bean0001.class, false, false, false, true);
++ test(Bean0010.class, false, false, true, false);
++ test(Bean0011.class, false, false, true, true);
++ test(Bean0100.class, false, true, false, false);
++ test(Bean0101.class, false, true, false, true);
++ test(Bean0110.class, false, true, true, false);
++ test(Bean0111.class, false, true, true, true);
++ test(Bean1000.class, true, false, false, false);
++ test(Bean1001.class, true, false, false, true);
++ test(Bean1010.class, true, false, true, false);
++ test(Bean1011.class, true, false, true, true);
++ test(Bean1100.class, true, true, false, false);
++ test(Bean1101.class, true, true, false, true);
++ test(Bean1110.class, true, true, true, false);
++ test(Bean1111.class, true, true, true, true);
++
++ if (0 < ERROR.length()) {
++ throw new Error(ERROR.toString());
++ }
++ }
++
++ private static void test(Class<?> type, boolean read, boolean write, boolean readIndexed, boolean writeIndexed) {
++ PropertyDescriptor pd = BeanUtils.findPropertyDescriptor(type, "size");
++ if (pd != null) {
++ test(type, "read", read, null != pd.getReadMethod());
++ test(type, "write", write, null != pd.getWriteMethod());
++ if (pd instanceof IndexedPropertyDescriptor) {
++ IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
++ test(type, "indexed read", readIndexed, null != ipd.getIndexedReadMethod());
++ test(type, "indexed write", writeIndexed, null != ipd.getIndexedWriteMethod());
++ } else if (readIndexed || writeIndexed) {
++ error(type, "indexed property does not exist");
++ }
++ } else if (read || write || readIndexed || writeIndexed) {
++ error(type, "property does not exist");
++ }
++ }
++
++ private static void test(Class<?> type, String name, boolean expected, boolean actual) {
++ if (expected && !actual) {
++ error(type, name + " method does not exist");
++ } else if (!expected && actual) {
++ error(type, name + " method is not expected");
++ }
++ }
++
++ private static void error(Class<?> type, String message) {
++ ERROR.append("\n\t\t").append(type.getSimpleName()).append(".size: ").append(message);
++ }
++
++ public static class Bean0000 {
++ }
++
++ public static class Bean0001 {
++ public void setSize(int index, int value) {
++ }
++ }
++
++ public static class Bean0010 {
++ public int getSize(int index) {
++ return 0;
++ }
++ }
++
++ public static class Bean0011 {
++ public int getSize(int index) {
++ return 0;
++ }
++
++ public void setSize(int index, int value) {
++ }
++ }
++
++ public static class Bean0100 {
++ public void setSize(int[] value) {
++ }
++ }
++
++ public static class Bean0101 {
++ public void setSize(int[] value) {
++ }
++
++ public void setSize(int index, int value) {
++ }
++ }
++
++ public static class Bean0110 {
++ public void setSize(int[] value) {
++ }
++
++ public int getSize(int index) {
++ return 0;
++ }
++ }
++
++ public static class Bean0111 {
++ public void setSize(int[] value) {
++ }
++
++ public int getSize(int index) {
++ return 0;
++ }
++
++ public void setSize(int index, int value) {
++ }
++ }
++
++ public static class Bean1000 {
++ public int[] getSize() {
++ return null;
++ }
++ }
++
++ public static class Bean1001 {
++ public int[] getSize() {
++ return null;
++ }
++
++ public void setSize(int index, int value) {
++ }
++ }
++
++ public static class Bean1010 {
++ public int[] getSize() {
++ return null;
++ }
++
++ public int getSize(int index) {
++ return 0;
++ }
++ }
++
++ public static class Bean1011 {
++ public int[] getSize() {
++ return null;
++ }
++
++ public int getSize(int index) {
++ return 0;
++ }
++
++ public void setSize(int index, int value) {
++ }
++ }
++
++ public static class Bean1100 {
++ public int[] getSize() {
++ return null;
++ }
++
++ public void setSize(int[] value) {
++ }
++ }
++
++ public static class Bean1101 {
++ public int[] getSize() {
++ return null;
++ }
++
++ public void setSize(int[] value) {
++ }
++
++ public void setSize(int index, int value) {
++ }
++ }
++
++ public static class Bean1110 {
++ public int[] getSize() {
++ return null;
++ }
++
++ public void setSize(int[] value) {
++ }
++
++ public int getSize(int index) {
++ return 0;
++ }
++ }
++
++ public static class Bean1111 {
++ public int[] getSize() {
++ return null;
++ }
++
++ public void setSize(int[] value) {
++ }
++
++ public int getSize(int index) {
++ return 0;
++ }
++
++ public void setSize(int index, int value) {
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/io/SequenceInputStream/LotsOfStreams.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,66 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/* @test
++ * @bug 7011804
++ * @summary SequenceInputStream#read() was implemented recursivly,
++ * which may cause stack overflow
++ */
++
++import java.io.ByteArrayInputStream;
++import java.io.InputStream;
++import java.io.SequenceInputStream;
++import java.util.Enumeration;
++
++public class LotsOfStreams {
++
++ static final int MAX_SUBSTREAMS = 32000;
++
++ public static void main(String[] argv) throws Exception {
++ try (InputStream stream =
++ new SequenceInputStream(new LOSEnumeration())) {
++ stream.read();
++ }
++ try (InputStream stream =
++ new SequenceInputStream(new LOSEnumeration())) {
++ byte[] b = new byte[1];
++ stream.read(b, 0, 1);
++ }
++ }
++
++ static class LOSEnumeration
++ implements Enumeration<InputStream> {
++
++ private static InputStream inputStream =
++ new ByteArrayInputStream(new byte[0]);
++ private int left = MAX_SUBSTREAMS;
++
++ public boolean hasMoreElements() {
++ return (left > 0);
++ }
++ public InputStream nextElement() {
++ left--;
++ return inputStream;
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/lang/Class/getDeclaredField/ClassDeclaredFieldsTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,205 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.lang.reflect.Field;
++import java.lang.reflect.ReflectPermission;
++import java.security.CodeSource;
++import java.security.Permission;
++import java.security.PermissionCollection;
++import java.security.Permissions;
++import java.security.Policy;
++import java.security.ProtectionDomain;
++import java.util.Arrays;
++import java.util.Enumeration;
++import java.util.concurrent.atomic.AtomicBoolean;
++
++/**
++ * @test
++ * @bug 8065552
++ * @summary test that all fields returned by getDeclaredFields() can be
++ * set accessible if the right permission is granted; this test
++ * also verifies that Class.classLoader final private field is
++ * hidden from reflection access.
++ * @run main/othervm ClassDeclaredFieldsTest UNSECURE
++ * @run main/othervm ClassDeclaredFieldsTest SECURE
++ *
++ * @author danielfuchs
++ */
++public class ClassDeclaredFieldsTest {
++
++ // Test with or without a security manager
++ public static enum TestCase {
++ UNSECURE, SECURE;
++ public void run() throws Exception {
++ System.out.println("Running test case: " + name());
++ Configure.setUp(this);
++ test(this);
++ }
++ }
++ /**
++ * @param args the command line arguments
++ */
++ public static void main(String[] args) throws Exception {
++ System.out.println(System.getProperty("java.version"));
++ if (args == null || args.length == 0) {
++ args = new String[] { "SECURE" };
++ } else if (args.length != 1) {
++ throw new IllegalArgumentException("Only one arg expected: "
++ + Arrays.asList(args));
++ }
++ TestCase.valueOf(args[0]).run();
++ }
++
++ static void test(TestCase test) {
++ for (Field f : Class.class.getDeclaredFields()) {
++ f.setAccessible(true);
++ System.out.println("Field "+f.getName()+" is now accessible.");
++ if (f.getName().equals("classLoader")) {
++ throw new RuntimeException("Found "+f.getName()+" field!");
++ }
++ }
++ try {
++ Class.class.getDeclaredField("classLoader");
++ throw new RuntimeException("Expected NoSuchFieldException for"
++ + " 'classLoader' field not raised");
++ } catch(NoSuchFieldException x) {
++ System.out.println("Got expected exception: " + x);
++ }
++ System.out.println("Passed "+test);
++ }
++
++ // A helper class to configure the security manager for the test,
++ // and bypass it when needed.
++ static class Configure {
++ static Policy policy = null;
++ static final ThreadLocal<AtomicBoolean> allowAll = new ThreadLocal<AtomicBoolean>() {
++ @Override
++ protected AtomicBoolean initialValue() {
++ return new AtomicBoolean(false);
++ }
++ };
++ static void setUp(TestCase test) {
++ switch (test) {
++ case SECURE:
++ if (policy == null && System.getSecurityManager() != null) {
++ throw new IllegalStateException("SecurityManager already set");
++ } else if (policy == null) {
++ policy = new SimplePolicy(TestCase.SECURE, allowAll);
++ Policy.setPolicy(policy);
++ System.setSecurityManager(new SecurityManager());
++ }
++ if (System.getSecurityManager() == null) {
++ throw new IllegalStateException("No SecurityManager.");
++ }
++ if (policy == null) {
++ throw new IllegalStateException("policy not configured");
++ }
++ break;
++ case UNSECURE:
++ if (System.getSecurityManager() != null) {
++ throw new IllegalStateException("SecurityManager already set");
++ }
++ break;
++ default:
++ throw new InternalError("No such testcase: " + test);
++ }
++ }
++ static void doPrivileged(Runnable run) {
++ allowAll.get().set(true);
++ try {
++ run.run();
++ } finally {
++ allowAll.get().set(false);
++ }
++ }
++ }
++
++ // A Helper class to build a set of permissions.
++ final static class PermissionsBuilder {
++ final Permissions perms;
++ public PermissionsBuilder() {
++ this(new Permissions());
++ }
++ public PermissionsBuilder(Permissions perms) {
++ this.perms = perms;
++ }
++ public PermissionsBuilder add(Permission p) {
++ perms.add(p);
++ return this;
++ }
++ public PermissionsBuilder addAll(PermissionCollection col) {
++ if (col != null) {
++ for (Enumeration<Permission> e = col.elements(); e.hasMoreElements(); ) {
++ perms.add(e.nextElement());
++ }
++ }
++ return this;
++ }
++ public Permissions toPermissions() {
++ final PermissionsBuilder builder = new PermissionsBuilder();
++ builder.addAll(perms);
++ return builder.perms;
++ }
++ }
++
++ // Policy for the test...
++ public static class SimplePolicy extends Policy {
++
++ final Permissions permissions;
++ final Permissions allPermissions;
++ final ThreadLocal<AtomicBoolean> allowAll; // actually: this should be in a thread locale
++ public SimplePolicy(TestCase test, ThreadLocal<AtomicBoolean> allowAll) {
++ this.allowAll = allowAll;
++ // we don't actually need any permission to create our
++ // FileHandlers because we're passing invalid parameters
++ // which will make the creation fail...
++ permissions = new Permissions();
++ permissions.add(new RuntimePermission("accessDeclaredMembers"));
++ permissions.add(new ReflectPermission("suppressAccessChecks"));
++
++ // these are used for configuring the test itself...
++ allPermissions = new Permissions();
++ allPermissions.add(new java.security.AllPermission());
++
++ }
++
++ @Override
++ public boolean implies(ProtectionDomain domain, Permission permission) {
++ if (allowAll.get().get()) return allPermissions.implies(permission);
++ return permissions.implies(permission);
++ }
++
++ @Override
++ public PermissionCollection getPermissions(CodeSource codesource) {
++ return new PermissionsBuilder().addAll(allowAll.get().get()
++ ? allPermissions : permissions).toPermissions();
++ }
++
++ @Override
++ public PermissionCollection getPermissions(ProtectionDomain domain) {
++ return new PermissionsBuilder().addAll(allowAll.get().get()
++ ? allPermissions : permissions).toPermissions();
++ }
++ }
++
++}
+--- ./jdk/test/java/lang/ProcessBuilder/Basic.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/lang/ProcessBuilder/Basic.java Wed Feb 04 12:14:43 2015 -0800
+@@ -2246,9 +2246,10 @@
+ fail("Test failed: Process exited prematurely");
+ }
+ long end = System.nanoTime();
+- // give waitFor(timeout) a wide berth (100ms)
+- // Old AIX machines my need a little longer.
+- if ((end - start) > 100000000L * (AIX.is() ? 4 : 1))
++ // give waitFor(timeout) a wide berth (2s)
++ System.out.printf(" waitFor process: delta: %d%n",(end - start) );
++
++ if ((end - start) > TimeUnit.SECONDS.toNanos(2))
+ fail("Test failed: waitFor took too long (" + (end - start) + "ns)");
+
+ p.destroy();
+@@ -2272,19 +2273,23 @@
+ final Process p = new ProcessBuilder(childArgs).start();
+ long start = System.nanoTime();
+
+- p.waitFor(1000, TimeUnit.MILLISECONDS);
++ p.waitFor(10, TimeUnit.MILLISECONDS);
+
+ long end = System.nanoTime();
+- if ((end - start) < 500000000)
++ if ((end - start) < TimeUnit.MILLISECONDS.toNanos(10))
+ fail("Test failed: waitFor didn't take long enough (" + (end - start) + "ns)");
+
+ p.destroy();
+
+ start = System.nanoTime();
+- p.waitFor(1000, TimeUnit.MILLISECONDS);
++ p.waitFor(8, TimeUnit.SECONDS);
+ end = System.nanoTime();
+- if ((end - start) > 900000000)
+- fail("Test failed: waitFor took too long on a dead process. (" + (end - start) + "ns)");
++
++ int exitValue = p.exitValue();
++
++ if ((end - start) > TimeUnit.SECONDS.toNanos(7))
++ fail("Test failed: waitFor took too long on a dead process. (" + (end - start) + "ns)"
++ + ", exitValue: " + exitValue);
+ } catch (Throwable t) { unexpected(t); }
+
+ //----------------------------------------------------------------
+--- ./jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.sh Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.sh Wed Feb 04 12:14:43 2015 -0800
+@@ -36,9 +36,12 @@
+ exit 1
+ fi
+
++if [ "x${COMPILEJAVA}" = "x" ]; then
++ COMPILEJAVA="${TESTJAVA}"
++fi
+
+ JAVA="${TESTJAVA}/bin/java"
+-JAVAC="${TESTJAVA}/bin/javac"
++JAVAC="${COMPILEJAVA}/bin/javac"
+
+ cp -f ${TESTSRC}/InheritIO.java .
+
+--- ./jdk/test/java/lang/ProcessBuilder/SecurityManagerClinit.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/lang/ProcessBuilder/SecurityManagerClinit.java Wed Feb 04 12:14:43 2015 -0800
+@@ -54,9 +54,6 @@
+ System.getProperty("java.home") +
+ File.separator + "bin" + File.separator + "java";
+
+- // A funky contrived security setup, just for bug repro purposes.
+- java.security.Security.setProperty("package.access", "java.util");
+-
+ final Policy policy =
+ new Policy
+ (new FilePermission("<<ALL FILES>>", "execute"),
+--- ./jdk/test/java/lang/instrument/DaemonThread/TestDaemonThread.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/lang/instrument/DaemonThread/TestDaemonThread.java Wed Feb 04 12:14:43 2015 -0800
+@@ -28,7 +28,7 @@
+ *
+ * @build jdk.testlibrary.* DummyAgent DummyClass TestDaemonThreadLauncher TestDaemonThread
+ * @run shell ../MakeJAR3.sh DummyAgent
+- * @run main TestDaemonThreadLauncher /timeout=240
++ * @run main/timeout=240 TestDaemonThreadLauncher
+ *
+ */
+ import java.io.File;
+--- ./jdk/test/java/lang/instrument/NMTHelper.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/lang/instrument/NMTHelper.java Wed Feb 04 12:14:43 2015 -0800
+@@ -21,8 +21,12 @@
+ * questions.
+ */
+
++import java.io.File;
++import java.io.FileWriter;
+ import java.util.regex.Matcher;
+ import java.util.regex.Pattern;
++import java.util.Arrays;
++import java.util.stream.Collectors;
+ import sun.management.ManagementFactoryHelper;
+ import com.sun.management.DiagnosticCommandMBean;
+
+@@ -32,8 +36,8 @@
+ executeDcmd("vmNativeMemory", "baseline");
+ }
+
+- // Total: reserved=3484685KB +293KB, committed=266629KB +293KB
+- private static Pattern totalLine = Pattern.compile("^Total: reserved=\\d+KB .*KB, committed=\\d+KB (.*)KB$");
++ // Total: reserved=3484685KB +293KB, committed=266629KB +293KB
++ private static Pattern totalLine = Pattern.compile("^Total: reserved=\\d+KB .*KB, committed=\\d+KB (.*)KB$");
+
+ public static long committedDiff() throws Exception {
+ String res = (String) executeDcmd("vmNativeMemory", "detail.diff");
+@@ -53,14 +57,14 @@
+ Object[] dcmdArgs = {args};
+ String[] signature = {String[].class.getName()};
+
+- try {
+- System.out.print("> " + cmd + " ");
+- for (String s : args) {
+- System.out.print(s + " ");
+- }
+- System.out.println(":");
++ String cmdString = cmd + " " +
++ Arrays.stream(args).collect(Collectors.joining(" "));
++ File f = new File("dcmdoutput-" + cmd + "-" + System.currentTimeMillis() + ".txt");
++ System.out.println("Output from Dcmd '" + cmdString + "' is being written to file " + f);
++ try (FileWriter fw = new FileWriter(f)) {
++ fw.write("> " + cmdString + ":");
+ String result = (String) dcmd.invoke(cmd, dcmdArgs, signature);
+- System.out.println(result);
++ fw.write(result);
+ return result;
+ } catch(Exception ex) {
+ ex.printStackTrace();
+--- ./jdk/test/java/lang/instrument/RedefineBigClass.sh Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/lang/instrument/RedefineBigClass.sh Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,7 @@
+ # @author Daniel D. Daugherty
+ #
+ # @run shell MakeJAR3.sh RedefineBigClassAgent 'Can-Redefine-Classes: true'
+-# @run build BigClass RedefineBigClassApp
++# @run build BigClass RedefineBigClassApp NMTHelper
+ # @run shell/timeout=600 RedefineBigClass.sh
+ #
+
+--- ./jdk/test/java/lang/instrument/RetransformBigClass.sh Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/lang/instrument/RetransformBigClass.sh Wed Feb 04 12:14:43 2015 -0800
+@@ -27,7 +27,7 @@
+ # @author Daniel D. Daugherty
+ #
+ # @run shell MakeJAR4.sh RetransformBigClassAgent SimpleIdentityTransformer 'Can-Retransform-Classes: true'
+-# @run build BigClass RetransformBigClassApp
++# @run build BigClass RetransformBigClassApp NMTHelper
+ # @run shell/timeout=600 RetransformBigClass.sh
+ #
+
+--- ./jdk/test/java/lang/instrument/VerifyLocalVariableTableOnRetransformTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/lang/instrument/VerifyLocalVariableTableOnRetransformTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -100,7 +100,7 @@
+ // The HotSpot VM hands us class file bytes at initial class
+ // load time that match the .class file contents. However,
+ // according to the following spec that is not required:
+- // http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.html#retransformClasses(java.lang.Class...)
++ // https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.html#retransformClasses(java.lang.Class...)
+ // This test exists to catch any unintentional change in
+ // behavior by the HotSpot VM. If this behavior is intentionally
+ // changed in the future, then this test will need to be
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/lang/invoke/ExplicitCastArgumentsTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,101 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package java.lang.invoke;
++
++import sun.invoke.util.Wrapper;
++
++/* @test
++ * @summary unit tests for MethodHandles.explicitCastArguments()
++ *
++ * @run main/bootclasspath java.lang.invoke.ExplicitCastArgumentsTest
++ */
++public class ExplicitCastArgumentsTest {
++ private static final boolean VERBOSE = Boolean.getBoolean("verbose");
++ private static final Class<?> THIS_CLASS = ExplicitCastArgumentsTest.class;
++
++ public static void main(String[] args) throws Throwable {
++ testVarargsCollector();
++ testRef2Prim();
++ System.out.println("TEST PASSED");
++ }
++
++ public static String[] f(String... args) { return args; }
++
++ public static void testVarargsCollector() throws Throwable {
++ MethodType mt = MethodType.methodType(String[].class, String[].class);
++ MethodHandle mh = MethodHandles.publicLookup().findStatic(THIS_CLASS, "f", mt);
++ mh = MethodHandles.explicitCastArguments(mh, MethodType.methodType(Object.class, Object.class));
++ mh.invokeWithArguments((Object)(new String[] {"str1", "str2"}));
++ }
++
++ public static void testRef2Prim() throws Throwable {
++ for (Wrapper from : Wrapper.values()) {
++ for (Wrapper to : Wrapper.values()) {
++ if (from == Wrapper.VOID || to == Wrapper.VOID) continue;
++ testRef2Prim(from, to);
++ }
++ }
++ }
++
++ public static void testRef2Prim(Wrapper from, Wrapper to) throws Throwable {
++ // MHs.eCA javadoc:
++ // If T0 is a reference and T1 a primitive, and if the reference is null at runtime, a zero value is introduced.
++ test(from.wrapperType(), to.primitiveType(), null, false);
++ }
++
++ public static void test(Class<?> from, Class<?> to, Object param, boolean failureExpected) throws Throwable {
++ if (VERBOSE) System.out.printf("%-10s => %-10s: %5s: ", from.getSimpleName(), to.getSimpleName(), param);
++
++ MethodHandle original = MethodHandles.identity(from);
++ MethodType newType = original.type().changeReturnType(to);
++
++ try {
++ MethodHandle target = MethodHandles.explicitCastArguments(original, newType);
++ Object result = target.invokeWithArguments(param);
++
++ if (VERBOSE) {
++ String resultStr;
++ if (result != null) {
++ resultStr = String.format("%10s (%10s)", "'"+result+"'", result.getClass().getSimpleName());
++ } else {
++ resultStr = String.format("%10s", result);
++ }
++ System.out.println(resultStr);
++ }
++
++ if (failureExpected) {
++ String msg = String.format("No exception thrown: %s => %s; parameter: %s", from, to, param);
++ throw new AssertionError(msg);
++ }
++ } catch (AssertionError e) {
++ throw e; // report test failure
++ } catch (Throwable e) {
++ if (VERBOSE) System.out.printf("%s: %s\n", e.getClass(), e.getMessage());
++ if (!failureExpected) {
++ String msg = String.format("Unexpected exception was thrown: %s => %s; parameter: %s", from, to, param);
++ throw new AssertionError(msg, e);
++ }
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/lang/invoke/LFCaching/LFCachingTestCase.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,83 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.lang.invoke.MethodHandle;
++import java.lang.reflect.InvocationTargetException;
++
++/**
++ * Abstract class for lambda forms caching testing.
++ *
++ * @author kshefov
++ */
++public abstract class LFCachingTestCase extends LambdaFormTestCase {
++
++ /**
++ * Constructor for lambda forms caching test case.
++ *
++ * @param testMethod A method from {@code j.l.i.MethodHandles} class that
++ * returns a {@code j.l.i.MethodHandle} instance.
++ */
++ protected LFCachingTestCase(TestMethods testMethod) {
++ super(testMethod);
++ }
++
++ /**
++ * Checks that the lambda forms of the two adapter method handles adapter1
++ * and adapter2 are the same.
++ *
++ * @param adapter1 First method handle.
++ * @param adapter2 Second method handle.
++ */
++ public void checkLFCaching(MethodHandle adapter1, MethodHandle adapter2) {
++ try {
++
++ if (!adapter1.type().equals(adapter2.type())) {
++ throw new Error("TESTBUG: Types of the two method handles are not the same");
++ }
++
++ Object lambdaForm0 = LambdaFormTestCase.INTERNAL_FORM.invoke(adapter1);
++ Object lambdaForm1 = LambdaFormTestCase.INTERNAL_FORM.invoke(adapter2);
++
++ if (lambdaForm0 == null || lambdaForm1 == null) {
++ throw new Error("Unexpected error: One or both lambda forms of the method handles are null");
++ }
++
++ if (lambdaForm0 != lambdaForm1) {
++ // Since LambdaForm caches are based on SoftReferences, GC can cause element eviction.
++ if (noGCHappened()) {
++ System.err.println("Lambda form 0 toString is:");
++ System.err.println(lambdaForm0);
++ System.err.println("Lambda form 1 toString is:");
++ System.err.println(lambdaForm1);
++ throw new AssertionError("Error: Lambda forms of the two method handles"
++ + " are not the same. LF cahing does not work");
++ } else {
++ System.err.println("LambdaForms differ, but there was a GC in between. Ignore the failure.");
++ }
++ }
++ } catch (IllegalAccessException | IllegalArgumentException |
++ SecurityException | InvocationTargetException ex) {
++ throw new Error("Unexpected exception: ", ex);
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,108 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test LFGarbageCollectedTest
++ * @bug 8046703
++ * @summary Test verifies that lambda forms are garbage collected
++ * @author kshefov
++ * @library /lib/testlibrary/jsr292 /lib/testlibrary
++ * @ignore 8057020
++ * @build TestMethods
++ * @build LambdaFormTestCase
++ * @build LFGarbageCollectedTest
++ * @run main/othervm LFGarbageCollectedTest
++ */
++
++import java.lang.invoke.MethodHandle;
++import java.lang.ref.PhantomReference;
++import java.lang.ref.ReferenceQueue;
++import java.lang.reflect.InvocationTargetException;
++import java.util.EnumSet;
++import java.util.Map;
++
++/**
++ * Lambda forms garbage collection test class.
++ */
++public final class LFGarbageCollectedTest extends LambdaFormTestCase {
++
++ /**
++ * Constructor for a lambda forms garbage collection test case.
++ *
++ * @param testMethod A method from {@code j.l.i.MethodHandles} class that
++ * returns a {@code j.l.i.MethodHandle} instance.
++ */
++ public LFGarbageCollectedTest(TestMethods testMethod) {
++ super(testMethod);
++ }
++
++ @Override
++ public void doTest() {
++ try {
++ Map<String, Object> data = getTestMethod().getTestCaseData();
++ MethodHandle adapter;
++ try {
++ adapter = getTestMethod().getTestCaseMH(data, TestMethods.Kind.ONE);
++ } catch (NoSuchMethodException ex) {
++ throw new Error("Unexpected exception: ", ex);
++ }
++ Object lambdaForm = LambdaFormTestCase.INTERNAL_FORM.invoke(adapter);
++ if (lambdaForm == null) {
++ throw new Error("Unexpected error: Lambda form of the method handle is null");
++ }
++ ReferenceQueue rq = new ReferenceQueue();
++ PhantomReference ph = new PhantomReference(lambdaForm, rq);
++ lambdaForm = null;
++ data = null;
++ adapter = null;
++ for (int i = 0; i < 1000 && !ph.isEnqueued(); i++) {
++ System.gc();
++ }
++ if (!ph.isEnqueued()) {
++ throw new AssertionError("Error: Lambda form is not garbage collected");
++ }
++ } catch (IllegalAccessException | IllegalArgumentException |
++ InvocationTargetException ex) {
++ throw new Error("Unexpected exception: ", ex);
++ }
++ }
++
++ /**
++ * Main routine for lambda forms garbage collection test.
++ *
++ * @param args Accepts no arguments.
++ */
++ public static void main(String[] args) {
++ // The "identity", "constant", "arrayElementGetter" and "arrayElementSetter"
++ // methods should be removed from this test,
++ // because their lambda forms are stored in a static field and are not GC'ed.
++ // There can be only a finite number of such LFs for each method,
++ // so no memory leak happens.
++ EnumSet<TestMethods> testMethods = EnumSet.complementOf(EnumSet.of(
++ TestMethods.IDENTITY,
++ TestMethods.CONSTANT,
++ TestMethods.ARRAY_ELEMENT_GETTER,
++ TestMethods.ARRAY_ELEMENT_SETTER));
++ LambdaFormTestCase.runTests(LFGarbageCollectedTest::new, testMethods);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,111 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test LFMultiThreadCachingTest
++ * @bug 8046703
++ * @summary Test verifies that lambda forms are cached when run with multiple threads
++ * @author kshefov
++ * @library /lib/testlibrary/jsr292 /lib/testlibrary
++ * @build TestMethods
++ * @build LambdaFormTestCase
++ * @build LFCachingTestCase
++ * @build LFMultiThreadCachingTest
++ * @run main/othervm LFMultiThreadCachingTest
++ */
++
++import java.lang.invoke.MethodHandle;
++import java.util.EnumSet;
++import java.util.Map;
++import java.util.concurrent.BrokenBarrierException;
++import java.util.concurrent.ConcurrentLinkedQueue;
++import java.util.concurrent.CountDownLatch;
++import java.util.concurrent.CyclicBarrier;
++
++/**
++ * Multiple threaded lambda forms caching test class.
++ */
++public final class LFMultiThreadCachingTest extends LFCachingTestCase {
++ private static final TestMethods.Kind[] KINDS;
++ static {
++ EnumSet<TestMethods.Kind> set = EnumSet.complementOf(EnumSet.of(TestMethods.Kind.EXCEPT));
++ KINDS = set.toArray(new TestMethods.Kind[set.size()]);
++ if (KINDS.length < 2) {
++ throw new Error("TESTBUG: KINDS.length[" + KINDS.length + "] should be at least 2");
++ }
++ }
++ private static final int CORES = Math.max(KINDS.length, Runtime.getRuntime().availableProcessors());
++
++ /**
++ * Constructor a for multiple threaded lambda forms caching test case.
++ *
++ * @param testMethod A method from {@code j.l.i.MethodHandles} class that
++ * returns a {@code j.l.i.MethodHandle} instance.
++ */
++ public LFMultiThreadCachingTest(TestMethods testMethod) {
++ super(testMethod);
++ }
++
++ @Override
++ public void doTest() {
++ Map<String, Object> data = getTestMethod().getTestCaseData();
++ ConcurrentLinkedQueue<MethodHandle> adapters = new ConcurrentLinkedQueue<>();
++ CyclicBarrier begin = new CyclicBarrier(CORES);
++ CountDownLatch end = new CountDownLatch(CORES);
++ for (int i = 0; i < CORES; ++i) {
++ TestMethods.Kind kind = KINDS[i % KINDS.length];
++ new Thread(() -> {
++ try {
++ begin.await();
++ adapters.add(getTestMethod().getTestCaseMH(data, kind));
++ } catch (InterruptedException | BrokenBarrierException | IllegalAccessException | NoSuchMethodException ex) {
++ throw new Error("Unexpected exception: ", ex);
++ } finally {
++ end.countDown();
++ }
++ }).start();
++ }
++ try {
++ end.await();
++ } catch (InterruptedException ex) {
++ throw new Error("Unexpected exception: ", ex);
++ }
++ if (adapters.size() < CORES) {
++ throw new Error("adapters size[" + adapters.size() + "] is less than " + CORES);
++ }
++ MethodHandle prev = adapters.poll();
++ for (MethodHandle current : adapters) {
++ checkLFCaching(prev, current);
++ prev = current;
++ }
++ }
++
++ /**
++ * Main routine for multiple threaded lambda forms caching test.
++ *
++ * @param args Accepts no arguments.
++ */
++ public static void main(String[] args) {
++ LambdaFormTestCase.runTests(LFMultiThreadCachingTest::new, EnumSet.allOf(TestMethods.class));
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,78 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test LFSingleThreadCachingTest
++ * @bug 8046703
++ * @summary Test verifies that lambda forms are cached when run with single thread
++ * @author kshefov
++ * @library /lib/testlibrary/jsr292 /lib/testlibrary
++ * @build TestMethods
++ * @build LambdaFormTestCase
++ * @build LFCachingTestCase
++ * @build LFSingleThreadCachingTest
++ * @run main/othervm LFSingleThreadCachingTest
++ */
++
++import java.lang.invoke.MethodHandle;
++import java.util.EnumSet;
++import java.util.Map;
++
++/**
++ * Single threaded lambda forms caching test class.
++ */
++public final class LFSingleThreadCachingTest extends LFCachingTestCase {
++
++ /**
++ * Constructor for a single threaded lambda forms caching test case.
++ *
++ * @param testMethod A method from {@code j.l.i.MethodHandles} class that
++ * returns a {@code j.l.i.MethodHandle} instance.
++ */
++ public LFSingleThreadCachingTest(TestMethods testMethod) {
++ super(testMethod);
++ }
++
++ @Override
++ public void doTest() {
++ MethodHandle adapter1;
++ MethodHandle adapter2;
++ Map<String, Object> data = getTestMethod().getTestCaseData();
++ try {
++ adapter1 = getTestMethod().getTestCaseMH(data, TestMethods.Kind.ONE);
++ adapter2 = getTestMethod().getTestCaseMH(data, TestMethods.Kind.TWO);
++ } catch (NoSuchMethodException | IllegalAccessException ex) {
++ throw new Error("Unexpected exception: ", ex);
++ }
++ checkLFCaching(adapter1, adapter2);
++ }
++
++ /**
++ * Main routine for single threaded lambda forms caching test.
++ *
++ * @param args Accepts no arguments.
++ */
++ public static void main(String[] args) {
++ LambdaFormTestCase.runTests(LFSingleThreadCachingTest::new, EnumSet.allOf(TestMethods.class));
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,175 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import com.oracle.testlibrary.jsr292.Helper;
++import com.sun.management.HotSpotDiagnosticMXBean;
++
++import java.lang.management.GarbageCollectorMXBean;
++import java.lang.management.ManagementFactory;
++import java.lang.reflect.Method;
++import java.util.Collection;
++import java.util.List;
++import java.util.function.Function;
++import jdk.testlibrary.Utils;
++import jdk.testlibrary.TimeLimitedRunner;
++
++/**
++ * Lambda forms caching test case class. Contains all necessary test routines to
++ * test lambda forms caching in method handles returned by methods of
++ * MethodHandles class.
++ *
++ * @author kshefov
++ */
++public abstract class LambdaFormTestCase {
++
++ private final static String METHOD_HANDLE_CLASS_NAME = "java.lang.invoke.MethodHandle";
++ private final static String INTERNAL_FORM_METHOD_NAME = "internalForm";
++ private static final double ITERATIONS_TO_CODE_CACHE_SIZE_RATIO
++ = 45 / (128.0 * 1024 * 1024);
++ private static final long TIMEOUT = Helper.IS_THOROUGH ? 0L : (long) (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) * 0.9);
++
++ /**
++ * Reflection link to {@code j.l.i.MethodHandle.internalForm} method. It is
++ * used to get a lambda form from a method handle.
++ */
++ protected final static Method INTERNAL_FORM;
++ private static final List<GarbageCollectorMXBean> gcInfo;
++
++ private static long gcCount() {
++ return gcInfo.stream().mapToLong(GarbageCollectorMXBean::getCollectionCount).sum();
++ }
++
++ static {
++ try {
++ Class mhClass = Class.forName(METHOD_HANDLE_CLASS_NAME);
++ INTERNAL_FORM = mhClass.getDeclaredMethod(INTERNAL_FORM_METHOD_NAME);
++ INTERNAL_FORM.setAccessible(true);
++ } catch (Exception ex) {
++ throw new Error("Unexpected exception: ", ex);
++ }
++
++ gcInfo = ManagementFactory.getGarbageCollectorMXBeans();
++ if (gcInfo.size() == 0) {
++ throw new Error("No GarbageCollectorMXBeans found.");
++ }
++ }
++
++ private final TestMethods testMethod;
++ private static long totalIterations = 0L;
++ private static long doneIterations = 0L;
++ private static boolean passed = true;
++ private static int testCounter = 0;
++ private static int failCounter = 0;
++ private long gcCountAtStart;
++
++ /**
++ * Test case constructor. Generates test cases with random method types for
++ * given methods form {@code j.l.i.MethodHandles} class.
++ *
++ * @param testMethod A method from {@code j.l.i.MethodHandles} class which
++ * returns a {@code j.l.i.MethodHandle}.
++ */
++ protected LambdaFormTestCase(TestMethods testMethod) {
++ this.testMethod = testMethod;
++ this.gcCountAtStart = gcCount();
++ }
++
++ public TestMethods getTestMethod() {
++ return testMethod;
++ }
++
++ protected boolean noGCHappened() {
++ return gcCount() == gcCountAtStart;
++ }
++
++ /**
++ * Routine that executes a test case.
++ */
++ public abstract void doTest();
++
++ /**
++ * Runs a number of test cases defined by the size of testCases list.
++ *
++ * @param ctor constructor of LambdaFormCachingTest or its child classes
++ * object.
++ * @param testMethods list of test methods
++ */
++ public static void runTests(Function<TestMethods, LambdaFormTestCase> ctor, Collection<TestMethods> testMethods) {
++ long testCaseNum = testMethods.size();
++ totalIterations = Math.max(1, Helper.TEST_LIMIT / testCaseNum);
++ System.out.printf("Number of iterations according to -DtestLimit is %d (%d cases)%n",
++ totalIterations, totalIterations * testCaseNum);
++ HotSpotDiagnosticMXBean hsDiagBean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
++ long codeCacheSize = Long.parseLong(
++ hsDiagBean.getVMOption("ReservedCodeCacheSize").getValue());
++ System.out.printf("Code Cache Size is %d bytes%n", codeCacheSize);
++ long iterationsByCodeCacheSize = (long) (codeCacheSize
++ * ITERATIONS_TO_CODE_CACHE_SIZE_RATIO);
++ System.out.printf("Number of iterations limited by code cache size is %d (%d cases)%n",
++ iterationsByCodeCacheSize, iterationsByCodeCacheSize * testCaseNum);
++ if (totalIterations > iterationsByCodeCacheSize) {
++ totalIterations = iterationsByCodeCacheSize;
++ }
++ System.out.printf("Number of iterations is set to %d (%d cases)%n",
++ totalIterations, totalIterations * testCaseNum);
++ System.out.flush();
++ TimeLimitedRunner runner = new TimeLimitedRunner(TIMEOUT, 4.0d,
++ () -> {
++ if (doneIterations >= totalIterations) {
++ return false;
++ }
++ System.err.println(String.format("Iteration %d:", doneIterations));
++ for (TestMethods testMethod : testMethods) {
++ LambdaFormTestCase testCase = ctor.apply(testMethod);
++ try {
++ System.err.printf("Tested LF caching feature with MethodHandles.%s method.%n",
++ testCase.getTestMethod().name);
++ testCase.doTest();
++ System.err.println("PASSED");
++ } catch (Throwable t) {
++ t.printStackTrace();
++ System.err.println("FAILED");
++ passed = false;
++ failCounter++;
++ }
++ testCounter++;
++ }
++ doneIterations++;
++ return true;
++ });
++ try {
++ runner.call();
++ } catch (Throwable t) {
++ t.printStackTrace();
++ System.err.println("FAILED");
++ throw new Error("Unexpected error!");
++ }
++ if (!passed) {
++ throw new Error(String.format("%d of %d test cases FAILED! %n"
++ + "Rerun the test with the same \"-Dseed=\" option as in the log file!",
++ failCounter, testCounter));
++ } else {
++ System.err.println(String.format("All %d test cases PASSED!", testCounter));
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/lang/invoke/LFCaching/TestMethods.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,705 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import com.oracle.testlibrary.jsr292.Helper;
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.lang.invoke.MethodType;
++import java.lang.reflect.Array;
++import java.util.ArrayList;
++import java.util.HashMap;
++import java.util.List;
++import java.util.Map;
++
++/**
++ * Enumeration containing information about methods from
++ * {@code j.l.i.MethodHandles} class that are used for testing lambda forms
++ * caching.
++ *
++ * @author kshefov
++ */
++public enum TestMethods {
++
++ FOLD_ARGUMENTS("foldArguments") {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ // Arity after reducing because of long and double take 2 slots.
++ int realArity = mtTarget.parameterCount();
++ int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);
++ data.put("modifierMHArgNum", modifierMHArgNum);
++ Class<?> combinerReturnType;
++ if (realArity == 0) {
++ combinerReturnType = void.class;
++ } else {
++ combinerReturnType = Helper.RNG.nextBoolean() ? void.class : mtTarget.parameterType(0);
++ }
++ data.put("combinerReturnType", combinerReturnType);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ Class<?> combinerReturnType = (Class) data.get("combinerReturnType");
++ int modifierMHArgNum = (int) data.get("modifierMHArgNum");
++ MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
++ mtTarget.parameterList(), kind);
++ Class<?> rType = mtTarget.returnType();
++ int combListStart = (combinerReturnType == void.class) ? 0 : 1;
++ if (modifierMHArgNum < combListStart) {
++ modifierMHArgNum = combListStart;
++ }
++ MethodHandle combiner = TestMethods.methodHandleGenerator(combinerReturnType,
++ mtTarget.parameterList().subList(combListStart,
++ modifierMHArgNum), kind);
++ return MethodHandles.foldArguments(target, combiner);
++ }
++ },
++ DROP_ARGUMENTS("dropArguments") {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ // Arity after reducing because of long and double take 2 slots.
++ int realArity = mtTarget.parameterCount();
++ int dropArgsPos = Helper.RNG.nextInt(realArity + 1);
++ data.put("dropArgsPos", dropArgsPos);
++ MethodType mtDropArgs = TestMethods.randomMethodTypeGenerator(
++ Helper.RNG.nextInt(super.maxArity - realArity));
++ data.put("mtDropArgs", mtDropArgs);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ MethodType mtDropArgs = (MethodType) data.get("mtDropArgs");
++ int dropArgsPos = (int) data.get("dropArgsPos");
++ MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
++ mtTarget.parameterList(), kind);
++ int mtTgtSlotsCount = TestMethods.argSlotsCount(mtTarget);
++ int mtDASlotsCount = TestMethods.argSlotsCount(mtDropArgs);
++ List<Class<?>> fakeParList;
++ if (mtTgtSlotsCount + mtDASlotsCount > super.maxArity - 1) {
++ fakeParList = TestMethods.reduceArgListToSlotsCount(mtDropArgs.parameterList(),
++ super.maxArity - mtTgtSlotsCount - 1);
++ } else {
++ fakeParList = mtDropArgs.parameterList();
++ }
++ return MethodHandles.dropArguments(target, dropArgsPos, fakeParList);
++ }
++ },
++ EXPLICIT_CAST_ARGUMENTS("explicitCastArguments", Helper.MAX_ARITY / 2) {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ // Arity after reducing because of long and double take 2 slots.
++ int realArity = mtTarget.parameterCount();
++ MethodType mtExcplCastArgs = TestMethods.randomMethodTypeGenerator(realArity);
++ if (mtTarget.returnType() == void.class) {
++ mtExcplCastArgs = MethodType.methodType(void.class,
++ mtExcplCastArgs.parameterArray());
++ }
++ if (mtExcplCastArgs.returnType() == void.class) {
++ mtExcplCastArgs = MethodType.methodType(mtTarget.returnType(),
++ mtExcplCastArgs.parameterArray());
++ }
++ data.put("mtExcplCastArgs", mtExcplCastArgs);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ MethodType mtExcplCastArgs = (MethodType) data.get("mtExcplCastArgs");
++ MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
++ mtTarget.parameterList(), kind);
++ return MethodHandles.explicitCastArguments(target, mtExcplCastArgs);
++ }
++ },
++ FILTER_ARGUMENTS("filterArguments", Helper.MAX_ARITY / 2) {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ // Arity after reducing because of long and double take 2 slots.
++ int realArity = mtTarget.parameterCount();
++ int filterArgsPos = Helper.RNG.nextInt(realArity + 1);
++ data.put("filterArgsPos", filterArgsPos);
++ int filtersArgsArrayLength = Helper.RNG.nextInt(realArity + 1 - filterArgsPos);
++ data.put("filtersArgsArrayLength", filtersArgsArrayLength);
++ MethodType mtFilter = TestMethods.randomMethodTypeGenerator(filtersArgsArrayLength);
++ data.put("mtFilter", mtFilter);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ MethodType mtFilter = (MethodType) data.get("mtFilter");
++ int filterArgsPos = (int) data.get("filterArgsPos");
++ int filtersArgsArrayLength = (int) data.get("filtersArgsArrayLength");
++ MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
++ mtTarget.parameterList(), kind);
++ MethodHandle[] filters = new MethodHandle[filtersArgsArrayLength];
++ for (int i = 0; i < filtersArgsArrayLength; i++) {
++ filters[i] = TestMethods.filterGenerator(mtFilter.parameterType(i),
++ mtTarget.parameterType(filterArgsPos + i), kind);
++ }
++ return MethodHandles.filterArguments(target, filterArgsPos, filters);
++ }
++ },
++ FILTER_RETURN_VALUE("filterReturnValue") {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ // Arity after reducing because of long and double take 2 slots.
++ int realArity = mtTarget.parameterCount();
++ int filterArgsPos = Helper.RNG.nextInt(realArity + 1);
++ int filtersArgsArrayLength = Helper.RNG.nextInt(realArity + 1 - filterArgsPos);
++ MethodType mtFilter = TestMethods.randomMethodTypeGenerator(filtersArgsArrayLength);
++ data.put("mtFilter", mtFilter);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ MethodType mtFilter = (MethodType) data.get("mtFilter");
++ MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
++ mtTarget.parameterList(), kind);
++ MethodHandle filter = TestMethods.filterGenerator(mtTarget.returnType(),
++ mtFilter.returnType(), kind);
++ return MethodHandles.filterReturnValue(target, filter);
++ }
++ },
++ INSERT_ARGUMENTS("insertArguments") {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ // Arity after reducing because of long and double take 2 slots.
++ int realArity = mtTarget.parameterCount();
++ int insertArgsPos = Helper.RNG.nextInt(realArity + 1);
++ data.put("insertArgsPos", insertArgsPos);
++ int insertArgsArrayLength = Helper.RNG.nextInt(realArity + 1 - insertArgsPos);
++ MethodType mtInsertArgs = MethodType.methodType(void.class, mtTarget.parameterList()
++ .subList(insertArgsPos, insertArgsPos + insertArgsArrayLength));
++ data.put("mtInsertArgs", mtInsertArgs);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ MethodType mtInsertArgs = (MethodType) data.get("mtInsertArgs");
++ int insertArgsPos = (int) data.get("insertArgsPos");
++ MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
++ mtTarget.parameterList(), kind);
++ Object[] insertList = Helper.randomArgs(mtInsertArgs.parameterList());
++ return MethodHandles.insertArguments(target, insertArgsPos, insertList);
++ }
++ },
++ PERMUTE_ARGUMENTS("permuteArguments", Helper.MAX_ARITY / 2) {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ // Arity after reducing because of long and double take 2 slots.
++ int realArity = mtTarget.parameterCount();
++ int[] permuteArgsReorderArray = new int[realArity];
++ int mtPermuteArgsNum = Helper.RNG.nextInt(Helper.MAX_ARITY);
++ mtPermuteArgsNum = mtPermuteArgsNum == 0 ? 1 : mtPermuteArgsNum;
++ MethodType mtPermuteArgs = TestMethods.randomMethodTypeGenerator(mtPermuteArgsNum);
++ mtTarget = mtTarget.changeReturnType(mtPermuteArgs.returnType());
++ for (int i = 0; i < realArity; i++) {
++ int mtPermuteArgsParNum = Helper.RNG.nextInt(mtPermuteArgs.parameterCount());
++ permuteArgsReorderArray[i] = mtPermuteArgsParNum;
++ mtTarget = mtTarget.changeParameterType(
++ i, mtPermuteArgs.parameterType(mtPermuteArgsParNum));
++ }
++ data.put("mtTarget", mtTarget);
++ data.put("permuteArgsReorderArray", permuteArgsReorderArray);
++ data.put("mtPermuteArgs", mtPermuteArgs);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ MethodType mtPermuteArgs = (MethodType) data.get("mtPermuteArgs");
++ int[] permuteArgsReorderArray = (int[]) data.get("permuteArgsReorderArray");
++ MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
++ mtTarget.parameterList(), kind);
++ return MethodHandles.permuteArguments(target, mtPermuteArgs, permuteArgsReorderArray);
++ }
++ },
++ THROW_EXCEPTION("throwException") {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ Class<?> rType = mtTarget.returnType();
++ return MethodHandles.throwException(rType, Exception.class
++ );
++ }
++ },
++ GUARD_WITH_TEST("guardWithTest") {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ // Arity after reducing because of long and double take 2 slots.
++ int realArity = mtTarget.parameterCount();
++ int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);
++ data.put("modifierMHArgNum", modifierMHArgNum);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ int modifierMHArgNum = (int) data.get("modifierMHArgNum");
++ TestMethods.Kind targetKind;
++ TestMethods.Kind fallbackKind;
++ if (kind.equals(TestMethods.Kind.ONE)) {
++ targetKind = TestMethods.Kind.ONE;
++ fallbackKind = TestMethods.Kind.TWO;
++ } else {
++ targetKind = TestMethods.Kind.TWO;
++ fallbackKind = TestMethods.Kind.ONE;
++ }
++ MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
++ mtTarget.parameterList(), targetKind);
++ MethodHandle fallback = TestMethods.methodHandleGenerator(mtTarget.returnType(),
++ mtTarget.parameterList(), fallbackKind);
++ MethodHandle test = TestMethods.methodHandleGenerator(boolean.class,
++ mtTarget.parameterList().subList(0, modifierMHArgNum), kind);
++ return MethodHandles.guardWithTest(test, target, fallback);
++ }
++ },
++ CATCH_EXCEPTION("catchException") {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ // Arity after reducing because of long and double take 2 slots.
++ int realArity = mtTarget.parameterCount();
++ int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);
++ data.put("modifierMHArgNum", modifierMHArgNum);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ int modifierMHArgNum = (int) data.get("modifierMHArgNum");
++ MethodHandle target;
++ if (kind.equals(TestMethods.Kind.ONE)) {
++ target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
++ mtTarget.parameterList(), TestMethods.Kind.ONE);
++ } else {
++ target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
++ mtTarget.parameterList(), TestMethods.Kind.EXCEPT);
++ }
++ List<Class<?>> handlerParamList = new ArrayList<>(mtTarget.parameterCount() + 1);
++ handlerParamList.add(Exception.class);
++ handlerParamList.addAll(mtTarget.parameterList().subList(0, modifierMHArgNum));
++ MethodHandle handler = TestMethods.methodHandleGenerator(
++ mtTarget.returnType(), handlerParamList, TestMethods.Kind.TWO);
++ return MethodHandles.catchException(target, Exception.class, handler);
++ }
++ },
++ INVOKER("invoker", Helper.MAX_ARITY - 1) {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ return MethodHandles.invoker(mtTarget);
++ }
++ },
++ EXACT_INVOKER("exactInvoker", Helper.MAX_ARITY - 1) {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ return MethodHandles.exactInvoker(mtTarget);
++ }
++ },
++ SPREAD_INVOKER("spreadInvoker", Helper.MAX_ARITY - 1) {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ // Arity after reducing because of long and double take 2 slots.
++ int realArity = mtTarget.parameterCount();
++ int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);
++ data.put("modifierMHArgNum", modifierMHArgNum);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ int modifierMHArgNum = (int) data.get("modifierMHArgNum");
++ return MethodHandles.spreadInvoker(mtTarget, modifierMHArgNum);
++ }
++ },
++ ARRAY_ELEMENT_GETTER("arrayElementGetter") {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ Class<?> rType = mtTarget.returnType();
++ if (rType == void.class) {
++ rType = Object.class;
++ }
++ return MethodHandles.arrayElementGetter(Array.newInstance(rType, 2).getClass());
++ }
++ },
++ ARRAY_ELEMENT_SETTER("arrayElementSetter") {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ Class<?> rType = mtTarget.returnType();
++ if (rType == void.class) {
++ rType = Object.class;
++ }
++ return MethodHandles.arrayElementSetter(Array.newInstance(rType, 2).getClass());
++ }
++ },
++ CONSTANT("constant") {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ Class<?> rType = mtTarget.returnType();
++ if (rType == void.class) {
++ rType = Object.class;
++ }
++ if (rType.equals(boolean.class)) {
++ // There should be the same return values because for default values there are special "zero" forms
++ return MethodHandles.constant(rType, true);
++ } else {
++ return MethodHandles.constant(rType, kind.getValue(rType));
++ }
++ }
++ },
++ IDENTITY("identity") {
++ @Override
++ public Map<String, Object> getTestCaseData() {
++ Map<String, Object> data = new HashMap<>();
++ int desiredArity = Helper.RNG.nextInt(super.maxArity);
++ MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
++ data.put("mtTarget", mtTarget);
++ return data;
++ }
++
++ @Override
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
++ MethodType mtTarget = (MethodType) data.get("mtTarget");
++ Class<?> rType = mtTarget.returnType();
++ if (rType == void.class) {
++ rType = Object.class;
++ }
++ return MethodHandles.identity(rType);
++ }
++ };
++
++ /**
++ * Test method's name.
++ */
++ public final String name;
++
++ private final int maxArity;
++
++ private TestMethods(String name, int maxArity) {
++ this.name = name;
++ this.maxArity = maxArity;
++ }
++
++ private TestMethods(String name) {
++ this(name, Helper.MAX_ARITY);
++ }
++
++ protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
++ throw new UnsupportedOperationException("TESTBUG: getMH method is not implemented for test method " + this);
++ }
++
++ /**
++ * Creates an adapter method handle depending on a test method from
++ * MethodHandles class. Adapter is what is returned by the test method. This
++ * method is able to create two kinds of adapters, their type will be the
++ * same, but return values are different.
++ *
++ * @param data a Map containing data to create a method handle, can be
++ * obtained by {@link #getTestCaseData} method
++ * @param kind defines whether adapter ONE or adapter TWO will be
++ * initialized. Should be equal to TestMethods.Kind.ONE or
++ * TestMethods.Kind.TWO
++ * @return Method handle adapter that behaves according to
++ * TestMethods.Kind.ONE or TestMethods.Kind.TWO
++ * @throws java.lang.NoSuchMethodException
++ * @throws java.lang.IllegalAccessException
++ */
++ public MethodHandle getTestCaseMH(Map<String, Object> data, TestMethods.Kind kind)
++ throws NoSuchMethodException, IllegalAccessException {
++ if (data == null) {
++ throw new Error(String.format("TESTBUG: Data for test method %s is not prepared",
++ this.name));
++ }
++ if (!kind.equals(TestMethods.Kind.ONE) && !kind.equals(TestMethods.Kind.TWO)) {
++ throw new IllegalArgumentException("TESTBUG: Wrong \"kind\" (" + kind
++ + ") arg to getTestCaseMH function."
++ + " Should be Kind.ONE or Kind.TWO");
++ }
++ return getMH(data, kind);
++ }
++
++ /**
++ * Returns a data Map needed for {@link #getTestCaseMH} method.
++ *
++ * @return data Map needed for {@link #getTestCaseMH} method
++ */
++ public Map<String, Object> getTestCaseData() {
++ throw new UnsupportedOperationException(
++ "TESTBUG: getTestCaseData method is not implemented for test method " + this);
++ }
++
++ /**
++ * Enumeration used in methodHandleGenerator to define whether a MH returned
++ * by this method returns "2" in different type representations, "4", or
++ * throw an Exception.
++ */
++ public static enum Kind {
++
++ ONE(2),
++ TWO(4),
++ EXCEPT(0);
++
++ private final int value;
++
++ private Object getValue(Class<?> cl) {
++ return Helper.castToWrapper(value, cl);
++ }
++
++ private MethodHandle getBasicMH(Class<?> rType) throws NoSuchMethodException, IllegalAccessException {
++ MethodHandle result = null;
++ switch (this) {
++ case ONE:
++ case TWO:
++ if (rType.equals(void.class)) {
++ result = MethodHandles.lookup().findVirtual(Kind.class, "returnVoid", MethodType.methodType(void.class));
++ result = MethodHandles.insertArguments(result, 0, this);
++ } else {
++ result = MethodHandles.constant(rType, getValue(rType));
++ }
++ break;
++ case EXCEPT:
++ result = MethodHandles.throwException(rType, Exception.class);
++ result = MethodHandles.insertArguments(result, 0, new Exception());
++ break;
++ }
++ return result;
++ }
++
++ private void returnVoid() {
++ }
++
++ private Kind(int value) {
++ this.value = value;
++ }
++ }
++
++ /**
++ * Routine used to obtain a randomly generated method type.
++ *
++ * @param arity Arity of returned method type.
++ * @return MethodType generated randomly.
++ */
++ private static MethodType randomMethodTypeGenerator(int arity) {
++ final Class<?>[] CLASSES = {
++ Object.class,
++ int.class,
++ boolean.class,
++ byte.class,
++ short.class,
++ char.class,
++ long.class,
++ float.class,
++ double.class
++ };
++ if (arity > Helper.MAX_ARITY) {
++ throw new IllegalArgumentException(
++ String.format("Arity should not exceed %d!", Helper.MAX_ARITY));
++ }
++ List<Class<?>> list = Helper.randomClasses(CLASSES, arity);
++ list = Helper.getParams(list, false, arity);
++ int i = Helper.RNG.nextInt(CLASSES.length + 1);
++ Class<?> rtype = i == CLASSES.length ? void.class : CLASSES[i];
++ return MethodType.methodType(rtype, list);
++ }
++
++ /**
++ * Routine used to obtain a method handles of a given type an kind (return
++ * value).
++ *
++ * @param returnType Type of MH return value.
++ * @param argTypes Types of MH args.
++ * @param kind Defines whether the obtained MH returns "1" or "2".
++ * @return Method handle of the given type.
++ * @throws NoSuchMethodException
++ * @throws IllegalAccessException
++ */
++ private static MethodHandle methodHandleGenerator(Class<?> returnType,
++ List<Class<?>> argTypes, TestMethods.Kind kind)
++ throws NoSuchMethodException, IllegalAccessException {
++ MethodHandle result;
++ result = kind.getBasicMH(returnType);
++ return Helper.addTrailingArgs(result, argTypes.size(), argTypes);
++ }
++
++ /**
++ * Routine that generates filter method handles to test
++ * MethodHandles.filterArguments method.
++ *
++ * @param inputType Filter's argument type.
++ * @param returnType Filter's return type.
++ * @param kind Filter's return value definer.
++ * @return A filter method handle, that takes one argument.
++ * @throws NoSuchMethodException
++ * @throws IllegalAccessException
++ */
++ private static MethodHandle filterGenerator(Class<?> inputType, Class<?> returnType,
++ TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
++ MethodHandle tmpMH = kind.getBasicMH(returnType);
++ if (inputType.equals(void.class)) {
++ return tmpMH;
++ }
++ ArrayList<Class<?>> inputTypeList = new ArrayList<>(1);
++ inputTypeList.add(inputType);
++ return Helper.addTrailingArgs(tmpMH, 1, inputTypeList);
++ }
++
++ private static int argSlotsCount(MethodType mt) {
++ int result = 0;
++ for (Class cl : mt.parameterArray()) {
++ if (cl.equals(long.class) || cl.equals(double.class)) {
++ result += 2;
++ } else {
++ result++;
++ }
++ }
++ return result;
++ }
++
++ private static List<Class<?>> reduceArgListToSlotsCount(List<Class<?>> list,
++ int desiredSlotCount) {
++ List<Class<?>> result = new ArrayList<>(desiredSlotCount);
++ int count = 0;
++ for (Class<?> cl : list) {
++ if (count >= desiredSlotCount) {
++ break;
++ }
++ if (cl.equals(long.class) || cl.equals(double.class)) {
++ count += 2;
++ } else {
++ count++;
++ }
++ result.add(cl);
++ }
++ return result;
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/lang/invoke/LambdaFormTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,78 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/* @test
++ * @summary unit tests for java.lang.invoke.LambdaForm
++ * @run junit/othervm test.java.lang.invoke.LambdaFormTest
++ */
++package test.java.lang.invoke;
++
++import org.junit.Test;
++import java.lang.reflect.Method;
++import static org.junit.Assert.*;
++
++public class LambdaFormTest {
++ static final Method M_shortenSignature;
++ static {
++ try {
++ Class<?> impl = Class.forName("java.lang.invoke.LambdaForm", false, null);
++ Method m = impl.getDeclaredMethod("shortenSignature", String.class);
++ m.setAccessible(true);
++ M_shortenSignature = m;
++ } catch(Exception e) {
++ throw new AssertionError(e);
++ }
++ }
++
++ public static String shortenSignature(String signature) throws ReflectiveOperationException {
++ return (String)M_shortenSignature.invoke(null, signature);
++ }
++
++ @Test
++ public void testShortenSignature() throws ReflectiveOperationException {
++ for (String s : new String[] {
++ // invariant strings:
++ "L", "LL", "ILL", "LIL", "LLI", "IILL", "ILIL", "ILLI",
++ // a few mappings:
++ "LLL=L3", "LLLL=L4", "LLLLLLLLLL=L10",
++ "IIIDDD=I3D3", "IDDD=ID3", "IIDDD=IID3", "IIID=I3D", "IIIDD=I3DD"
++ }) {
++ String s2 = s.substring(s.indexOf('=')+1);
++ String s1 = s.equals(s2) ? s : s.substring(0, s.length() - s2.length() - 1);
++ // mix the above cases with before and after reps of Z*
++ for (int k = -3; k <= 3; k++) {
++ String beg = (k < 0 ? "ZZZZ".substring(-k) : "");
++ String end = (k > 0 ? "ZZZZ".substring(+k) : "");
++ String ks1 = beg+s1+end;
++ String ks2 = shortenSignature(beg)+s2+shortenSignature(end);
++ String ks3 = shortenSignature(ks1);
++ assertEquals(ks2, ks3);
++ }
++ }
++ }
++
++ public static void main(String[] args) throws ReflectiveOperationException {
++ LambdaFormTest test = new LambdaFormTest();
++ test.testShortenSignature();
++ }
++}
+--- ./jdk/test/java/lang/invoke/MethodHandles/CatchExceptionTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/lang/invoke/MethodHandles/CatchExceptionTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -43,6 +43,7 @@
+ public class CatchExceptionTest {
+ private static final List<Class<?>> ARGS_CLASSES;
+ protected static final int MAX_ARITY = Helper.MAX_ARITY - 1;
++
+ static {
+ Class<?> classes[] = {
+ Object.class,
+@@ -53,11 +54,8 @@
+ double[].class,
+ String.class,
+ };
+- List<Class<?>> list = new ArrayList<>(MAX_ARITY);
+- for (int i = 0; i < MAX_ARITY; ++i) {
+- list.add(classes[Helper.RNG.nextInt(classes.length)]);
+- }
+- ARGS_CLASSES = Collections.unmodifiableList(list);
++ ARGS_CLASSES = Collections.unmodifiableList(
++ Helper.randomClasses(classes, MAX_ARITY));
+ }
+
+ private final TestCase testCase;
+@@ -67,7 +65,6 @@
+ private int dropped;
+ private MethodHandle thrower;
+
+-
+ public CatchExceptionTest(TestCase testCase, final boolean isVararg, final int argsCount,
+ final int catchDrops) {
+ this.testCase = testCase;
+@@ -108,37 +105,7 @@
+ }
+
+ private List<Class<?>> getThrowerParams(boolean isVararg, int argsCount) {
+- boolean unmodifiable = true;
+- List<Class<?>> classes;
+- classes = ARGS_CLASSES.subList(0,
+- Math.min(argsCount, (MAX_ARITY / 2) - 1));
+- int extra = 0;
+- if (argsCount >= MAX_ARITY / 2) {
+- classes = new ArrayList<>(classes);
+- unmodifiable = false;
+- extra = (int) classes.stream().filter(Helper::isDoubleCost).count();
+- int i = classes.size();
+- while (classes.size() + extra < argsCount) {
+- Class<?> aClass = ARGS_CLASSES.get(i);
+- if (Helper.isDoubleCost(aClass)) {
+- ++extra;
+- if (classes.size() + extra >= argsCount) {
+- break;
+- }
+- }
+- classes.add(aClass);
+- }
+- }
+- if (isVararg && classes.size() > 0) {
+- if (unmodifiable) {
+- classes = new ArrayList<>(classes);
+- }
+- int last = classes.size() - 1;
+- Class<?> aClass = classes.get(classes.size() - 1);
+- aClass = Array.newInstance(aClass, 2).getClass();
+- classes.set(last, aClass);
+- }
+- return classes;
++ return Helper.getParams(ARGS_CLASSES, isVararg, argsCount);
+ }
+
+
+--- ./jdk/test/java/lang/invoke/MethodHandlesTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/lang/invoke/MethodHandlesTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -2160,15 +2160,23 @@
+ else
+ type = type.changeParameterType(j, argType);
+ if (done.add(type))
+- testInvokers(type);
++ testInvokersWithCatch(type);
+ MethodType vtype = type.changeReturnType(void.class);
+ if (done.add(vtype))
+- testInvokers(vtype);
++ testInvokersWithCatch(vtype);
+ }
+ }
+ }
+ }
+
++ public void testInvokersWithCatch(MethodType type) throws Throwable {
++ try {
++ testInvokers(type);
++ } catch (Throwable ex) {
++ System.out.println("*** testInvokers on "+type+" => ");
++ ex.printStackTrace(System.out);
++ }
++ }
+ public void testInvokers(MethodType type) throws Throwable {
+ if (verbosity >= 3)
+ System.out.println("test invokers for "+type);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/lang/invoke/VarargsArrayTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,224 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package java.lang.invoke;
++
++import sun.invoke.util.Wrapper;
++
++import java.util.Arrays;
++import java.util.Collections;
++
++/* @test
++ * @summary unit tests for varargs array methods: MethodHandleInfo.varargsArray(int),
++ * MethodHandleInfo.varargsArray(Class,int) & MethodHandleInfo.varargsList(int)
++ *
++ * @run main/bootclasspath java.lang.invoke.VarargsArrayTest
++ * @run main/bootclasspath -DVarargsArrayTest.MAX_ARITY=255 -DVarargsArrayTest.START_ARITY=250
++ * java.lang.invoke.VarargsArrayTest
++ */
++
++/* This might take a while and burn lots of metadata:
++ * @run main/bootclasspath -DVarargsArrayTest.MAX_ARITY=255 -DVarargsArrayTest.EXHAUSTIVE=true java.lang.invoke.VarargsArrayTest
++ */
++public class VarargsArrayTest {
++ private static final Class<?> CLASS = VarargsArrayTest.class;
++ private static final int MAX_ARITY = Integer.getInteger(CLASS.getSimpleName()+".MAX_ARITY", 40);
++ private static final int START_ARITY = Integer.getInteger(CLASS.getSimpleName()+".START_ARITY", 0);
++ private static final boolean EXHAUSTIVE = Boolean.getBoolean(CLASS.getSimpleName()+".EXHAUSTIVE");
++
++ public static void main(String[] args) throws Throwable {
++ testVarargsArray();
++ testVarargsReferenceArray();
++ testVarargsPrimitiveArray();
++ }
++
++ public static void testVarargsArray() throws Throwable {
++ final int MIN = START_ARITY;
++ final int MAX = MAX_ARITY-2; // 253+1 would cause parameter overflow with 'this' added
++ for (int nargs = MIN; nargs <= MAX; nargs = nextArgCount(nargs, 17, MAX)) {
++ MethodHandle target = MethodHandleImpl.varargsArray(nargs);
++ Object[] args = new Object[nargs];
++ for (int i = 0; i < nargs; i++)
++ args[i] = "#"+i;
++ Object res = target.invokeWithArguments(args);
++ assertArrayEquals(args, (Object[])res);
++ }
++ }
++
++ public static void testVarargsReferenceArray() throws Throwable {
++ testTypedVarargsArray(Object[].class);
++ testTypedVarargsArray(String[].class);
++ testTypedVarargsArray(Number[].class);
++ }
++
++ public static void testVarargsPrimitiveArray() throws Throwable {
++ testTypedVarargsArray(int[].class);
++ testTypedVarargsArray(long[].class);
++ testTypedVarargsArray(byte[].class);
++ testTypedVarargsArray(boolean[].class);
++ testTypedVarargsArray(short[].class);
++ testTypedVarargsArray(char[].class);
++ testTypedVarargsArray(float[].class);
++ testTypedVarargsArray(double[].class);
++ }
++
++ private static int nextArgCount(int nargs, int density, int MAX) {
++ if (EXHAUSTIVE) return nargs + 1;
++ if (nargs >= MAX) return Integer.MAX_VALUE;
++ int BOT = 20, TOP = MAX-5;
++ if (density < 10) { BOT = 10; MAX = TOP-2; }
++ if (nargs <= BOT || nargs >= TOP) {
++ ++nargs;
++ } else {
++ int bump = Math.max(1, 100 / density);
++ nargs += bump;
++ if (nargs > TOP) nargs = TOP;
++ }
++ return nargs;
++ }
++
++ private static void testTypedVarargsArray(Class<?> arrayType) throws Throwable {
++ Class<?> elemType = arrayType.getComponentType();
++ int MIN = START_ARITY;
++ int MAX = MAX_ARITY-2; // 253+1 would cause parameter overflow with 'this' added
++ int density = 3;
++ if (elemType == int.class || elemType == long.class) density = 7;
++ if (elemType == long.class || elemType == double.class) { MAX /= 2; MIN /= 2; }
++ for (int nargs = MIN; nargs <= MAX; nargs = nextArgCount(nargs, density, MAX)) {
++ Object[] args = makeTestArray(elemType, nargs);
++ MethodHandle varargsArray = MethodHandleImpl.varargsArray(arrayType, nargs);
++ MethodType vaType = varargsArray.type();
++ assertEquals(arrayType, vaType.returnType());
++ if (nargs != 0) {
++ assertEquals(elemType, vaType.parameterType(0));
++ assertEquals(elemType, vaType.parameterType(vaType.parameterCount()-1));
++ }
++ assertEquals(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)),
++ vaType);
++ Object res = varargsArray.invokeWithArguments(args);
++ assertEquals(res.getClass(), arrayType);
++ String resString = toArrayString(res);
++ assertEquals(Arrays.toString(args), resString);
++
++ MethodHandle spreader = varargsArray.asSpreader(arrayType, nargs);
++ MethodType stype = spreader.type();
++ assert(stype == MethodType.methodType(arrayType, arrayType));
++ if (nargs <= 5) {
++ // invoke target as a spreader also:
++ @SuppressWarnings("cast")
++ Object res2 = spreader.invokeWithArguments((Object)res);
++ String res2String = toArrayString(res2);
++ assertEquals(Arrays.toString(args), res2String);
++ // invoke the spreader on a generic Object[] array; check for error
++ try {
++ Object res3 = spreader.invokeWithArguments((Object)args);
++ String res3String = toArrayString(res3);
++ assertTrue(arrayType.getName(), arrayType.isAssignableFrom(Object[].class));
++ assertEquals(Arrays.toString(args), res3String);
++ } catch (ClassCastException ex) {
++ assertFalse(arrayType.getName(), arrayType.isAssignableFrom(Object[].class));
++ }
++ }
++ if (nargs == 0) {
++ // invoke spreader on null arglist
++ Object res3 = spreader.invokeWithArguments((Object)null);
++ String res3String = toArrayString(res3);
++ assertEquals(Arrays.toString(args), res3String);
++ }
++ }
++ }
++
++ private static Object[] makeTestArray(Class<?> elemType, int len) {
++ Wrapper elem = null;
++ if (elemType.isPrimitive())
++ elem = Wrapper.forPrimitiveType(elemType);
++ else if (Wrapper.isWrapperType(elemType))
++ elem = Wrapper.forWrapperType(elemType);
++ Object[] args = new Object[len];
++ for (int i = 0; i < len; i++) {
++ Object arg = i * 100;
++ if (elem == null) {
++ if (elemType == String.class)
++ arg = "#"+arg;
++ arg = elemType.cast(arg); // just to make sure
++ } else {
++ switch (elem) {
++ case BOOLEAN: arg = (i % 3 == 0); break;
++ case CHAR: arg = 'a' + i; break;
++ case LONG: arg = (long)i * 1000_000_000; break;
++ case FLOAT: arg = (float)i / 100; break;
++ case DOUBLE: arg = (double)i / 1000_000; break;
++ }
++ arg = elem.cast(arg, elemType);
++ }
++ args[i] = arg;
++ }
++ return args;
++ }
++
++ private static String toArrayString(Object a) {
++ if (a == null) return "null";
++ Class<?> elemType = a.getClass().getComponentType();
++ if (elemType == null) return a.toString();
++ if (elemType.isPrimitive()) {
++ switch (Wrapper.forPrimitiveType(elemType)) {
++ case INT: return Arrays.toString((int[])a);
++ case BYTE: return Arrays.toString((byte[])a);
++ case BOOLEAN: return Arrays.toString((boolean[])a);
++ case SHORT: return Arrays.toString((short[])a);
++ case CHAR: return Arrays.toString((char[])a);
++ case FLOAT: return Arrays.toString((float[])a);
++ case LONG: return Arrays.toString((long[])a);
++ case DOUBLE: return Arrays.toString((double[])a);
++ }
++ }
++ return Arrays.toString((Object[])a);
++ }
++
++ public static void assertArrayEquals(Object[] arr1, Object[] arr2) {
++ if (arr1 == null && arr2 == null) return;
++ if (arr1 != null && arr2 != null && arr1.length == arr2.length) {
++ for (int i = 0; i < arr1.length; i++) {
++ assertEquals(arr1[i], arr2[i]);
++ }
++ return;
++ }
++ throw new AssertionError(Arrays.deepToString(arr1) + " != " + Arrays.deepToString(arr2));
++ }
++
++ public static void assertEquals(Object o1, Object o2) {
++ if (o1 == null && o2 == null) return;
++ if (o1 != null && o1.equals(o2)) return;
++ throw new AssertionError(o1 + " != " + o2);
++ }
++
++ public static void assertTrue(String msg, boolean b) {
++ if (!b) {
++ throw new AssertionError(msg);
++ }
++ }
++
++ public static void assertFalse(String msg, boolean b) {
++ assertTrue(msg, !b);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/lang/ref/EarlyTimeout.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,104 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/* @test
++ * @bug 6853696
++ * @summary ReferenceQueue#remove(timeout) should not return null before
++ * timeout is elapsed
++ */
++
++import java.lang.InterruptedException;
++import java.lang.System;
++import java.lang.ref.Reference;
++import java.lang.ref.ReferenceQueue;
++import java.lang.ref.WeakReference;
++import java.util.concurrent.CountDownLatch;
++import static java.util.concurrent.TimeUnit.NANOSECONDS;
++
++/**
++ * In order to demonstrate the issue we make several threads (two appears to be sufficient)
++ * to block in ReferenceQueue#remove(timeout) at the same time.
++ * Then, we force a reference to be enqueued by setting its referent to null and calling System.gc().
++ * One of the threads gets the reference returned from the remove().
++ * The other threads get null:
++ * 1) with bug: this may happen before the specified timeout is elapsed,
++ * 2) without bug: this can only happen after the timeout is fully elapsed.
++ */
++
++public class EarlyTimeout extends Thread {
++
++ static final int THREADS_COUNT = 2;
++ static final int TIMEOUT = 1000;
++
++ static Object referent = new Object();
++ static final ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
++ static final WeakReference<Object> weakReference = new WeakReference<Object>(referent, queue);
++ static final CountDownLatch startedSignal = new CountDownLatch(THREADS_COUNT);
++
++ long actual;
++ Reference<?> reference;
++
++ public static void main(String[] args) throws Exception {
++ EarlyTimeout[] threads = new EarlyTimeout[THREADS_COUNT];
++ for (int i = 0; i < THREADS_COUNT; ++i) {
++ threads[i] = new EarlyTimeout();
++ threads[i].start();
++ }
++ // The main thread waits until the threads has started and give it a chance
++ // for the threads to block on the queue.remove(TIMEOUT) call
++ startedSignal.await();
++ Thread.sleep(TIMEOUT / 2);
++ referent = null;
++ System.gc();
++ for (EarlyTimeout thread : threads) {
++ thread.join();
++ }
++ if (weakReference.get() != null) {
++ throw new RuntimeException("weakReference was not cleared");
++ }
++ int nonNullRefCount = 0;
++ for (EarlyTimeout thread : threads) {
++ if (thread.reference == null && thread.actual < TIMEOUT) {
++ throw new RuntimeException("elapsed time " + thread.actual
++ + " is less than timeout " + TIMEOUT);
++ }
++ if (thread.reference != null && thread.reference == weakReference) {
++ nonNullRefCount++;
++ }
++ }
++ if (nonNullRefCount > 1) {
++ throw new RuntimeException("more than one references were removed from queue");
++ }
++ }
++
++ public void run() {
++ try {
++ startedSignal.countDown();
++ long start = System.nanoTime();
++ reference = queue.remove(TIMEOUT);
++ actual = NANOSECONDS.toMillis(System.nanoTime() - start);
++ } catch (InterruptedException ex) {
++ throw new RuntimeException(ex);
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/lang/reflect/Generics/ThreadSafety.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,129 @@
++/*
++ * Copyright 2014 Google Inc. All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8062771 8016236
++ * @summary Test publication of Class objects via a data race
++ * @run testng ThreadSafety
++ */
++
++import java.net.URL;
++import java.net.URLClassLoader;
++import java.util.Collections;
++import java.util.concurrent.BrokenBarrierException;
++import java.util.concurrent.Callable;
++import java.util.concurrent.CyclicBarrier;
++import java.util.concurrent.ExecutionException;
++import java.util.concurrent.ExecutorService;
++import java.util.concurrent.Executors;
++import java.util.concurrent.Future;
++import java.util.concurrent.TimeoutException;
++import static java.util.concurrent.TimeUnit.SECONDS;
++import static org.testng.Assert.*;
++import org.testng.annotations.Test;
++
++/**
++ * A test resulting from an attempt to repro this failure (in guice):
++ *
++ * java.lang.NullPointerException
++ * at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125)
++ * at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
++ * at sun.reflect.generics.repository.ClassRepository.getSuperclass(ClassRepository.java:84)
++ * at java.lang.Class.getGenericSuperclass(Class.java:692)
++ * at com.google.inject.TypeLiteral.getSuperclassTypeParameter(TypeLiteral.java:99)
++ * at com.google.inject.TypeLiteral.<init>(TypeLiteral.java:79)
++ *
++ * However, as one would expect with thread safety problems in reflection, these
++ * are very hard to reproduce. This very test has never been observed to fail,
++ * but a similar test has been observed to fail about once in 2000 executions
++ * (about once every 6 CPU-hours), in jdk7 only. It appears to be fixed in jdk8+ by:
++ *
++ * 8016236: Class.getGenericInterfaces performance improvement.
++ * (by making Class.genericInfo volatile)
++ */
++public class ThreadSafety {
++ public static class EmptyClass {
++ public static class EmptyGenericSuperclass<T> {}
++ public static class EmptyGenericSubclass<T> extends EmptyGenericSuperclass<T> {}
++ }
++
++ /** published via data race */
++ private Class<?> racyClass = Object.class;
++
++ private URL[] urls = ((URLClassLoader) ThreadSafety.class.getClassLoader()).getURLs();
++
++ private Class<?> createNewEmptyGenericSubclassClass() throws Exception {
++ URLClassLoader ucl = new URLClassLoader(urls, null);
++ return Class.forName("ThreadSafety$EmptyClass$EmptyGenericSubclass", true, ucl);
++ }
++
++ @Test
++ public void testRacy_getGenericSuperclass() throws Exception {
++ final int nThreads = 10;
++ final int iterations = 30;
++ final int timeout = 10;
++ final CyclicBarrier newCycle = new CyclicBarrier(nThreads);
++ final Callable<Void> task = new Callable<Void>() {
++ public Void call() throws Exception {
++ for (int i = 0; i < iterations; i++) {
++ final int threadId;
++ try {
++ threadId = newCycle.await(timeout, SECONDS);
++ } catch (BrokenBarrierException e) {
++ return null;
++ }
++ for (int j = 0; j < iterations; j++) {
++ // one thread publishes the class object via a data
++ // race, for the other threads to consume.
++ if (threadId == 0) {
++ racyClass = createNewEmptyGenericSubclassClass();
++ } else {
++ racyClass.getGenericSuperclass();
++ }
++ }
++ }
++ return null;
++ }};
++
++ final ExecutorService pool = Executors.newFixedThreadPool(nThreads);
++ try {
++ for (Future<Void> future :
++ pool.invokeAll(Collections.nCopies(nThreads, task))) {
++ try {
++ future.get(iterations * timeout, SECONDS);
++ } catch (ExecutionException e) {
++ // ignore "collateral damage"
++ if (!(e.getCause() instanceof BrokenBarrierException)
++ &&
++ !(e.getCause() instanceof TimeoutException)) {
++ throw e;
++ }
++ }
++ }
++ } finally {
++ pool.shutdownNow();
++ assertTrue(pool.awaitTermination(2 * timeout, SECONDS));
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/lang/reflect/annotationSharing/AnnotationSharing.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,205 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8054987
++ * @summary Test sharing of annotations between Executable/Field instances.
++ * Sharing should not be noticeable when performing mutating
++ * operations.
++ * @run testng AnnotationSharing
++ */
++
++import java.lang.annotation.*;
++import java.lang.reflect.*;
++
++import org.testng.annotations.Test;
++
++public class AnnotationSharing {
++ public static void main(String ... args) throws Exception {
++ }
++
++ @Test
++ public void testMethodSharing() throws Exception {
++ Method[] m1 = AnnotationSharing.class.getMethods();
++ Method[] m2 = AnnotationSharing.class.getMethods();
++ validateSharingSafelyObservable(m1, m2);
++ }
++
++ @Test
++ public void testDeclaredMethodSharing() throws Exception {
++ Method[] m3 = AnnotationSharing.class.getDeclaredMethods();
++ Method[] m4 = AnnotationSharing.class.getDeclaredMethods();
++ validateSharingSafelyObservable(m3, m4);
++ }
++
++ @Test
++ public void testFieldSharing() throws Exception {
++ Field[] f1 = AnnotationSharing.class.getFields();
++ Field[] f2 = AnnotationSharing.class.getFields();
++ validateSharingSafelyObservable(f1, f2);
++ }
++
++ @Test
++ public void testDeclaredFieldsSharing() throws Exception {
++ Field[] f3 = AnnotationSharing.class.getDeclaredFields();
++ Field[] f4 = AnnotationSharing.class.getDeclaredFields();
++ validateSharingSafelyObservable(f3, f4);
++ }
++
++ @Test
++ public void testMethodSharingOccurs() throws Exception {
++ Method mm1 = AnnotationSharing.class.getDeclaredMethod("m", (Class<?>[])null);
++ Method mm2 = AnnotationSharing.class.getDeclaredMethod("m", (Class<?>[])null);
++ validateAnnotationSharing(mm1, mm2);
++ }
++
++ @Test
++ public void testMethodSharingIsSafe() throws Exception {
++ Method mm1 = AnnotationSharing.class.getDeclaredMethod("m", (Class<?>[])null);
++ Method mm2 = AnnotationSharing.class.getDeclaredMethod("m", (Class<?>[])null);
++ validateAnnotationSharingIsSafe(mm1, mm2);
++ validateArrayValues(mm1.getAnnotation(Baz.class), mm2.getAnnotation(Baz.class));
++ }
++
++ @Test
++ public void testFieldSharingOccurs() throws Exception {
++ Field ff1 = AnnotationSharing.class.getDeclaredField("f");
++ Field ff2 = AnnotationSharing.class.getDeclaredField("f");
++ validateAnnotationSharing(ff1, ff2);
++ }
++
++ @Test
++ public void testFieldSharingIsSafe() throws Exception {
++ Field ff1 = AnnotationSharing.class.getDeclaredField("f");
++ Field ff2 = AnnotationSharing.class.getDeclaredField("f");
++ validateAnnotationSharingIsSafe(ff1, ff2);
++ validateArrayValues(ff1.getAnnotation(Baz.class), ff2.getAnnotation(Baz.class));
++ }
++
++ // Validate that AccessibleObject instances are not shared
++ private static void validateSharingSafelyObservable(AccessibleObject[] m1, AccessibleObject[] m2)
++ throws Exception {
++
++ // Validate that setAccessible works
++ for (AccessibleObject m : m1)
++ m.setAccessible(false);
++
++ for (AccessibleObject m : m2)
++ m.setAccessible(true);
++
++ for (AccessibleObject m : m1)
++ if (m.isAccessible())
++ throw new RuntimeException(m + " should not be accessible");
++
++ for (AccessibleObject m : m2)
++ if (!m.isAccessible())
++ throw new RuntimeException(m + " should be accessible");
++
++ // Validate that methods are still equal()
++ for (int i = 0; i < m1.length; i++)
++ if (!m1[i].equals(m2[i]))
++ throw new RuntimeException(m1[i] + " and " + m2[i] + " should be equal()");
++
++ // Validate that the arrays aren't shared
++ for (int i = 0; i < m1.length; i++)
++ m1[i] = null;
++
++ for (int i = 0; i < m2.length; i++)
++ if (m2[i] == null)
++ throw new RuntimeException("Detected sharing of AccessibleObject arrays");
++ }
++
++ // Validate that annotations are shared
++ private static void validateAnnotationSharing(AccessibleObject m1, AccessibleObject m2) {
++ Bar b1 = m1.getAnnotation(Bar.class);
++ Bar b2 = m2.getAnnotation(Bar.class);
++
++ if (b1 != b2)
++ throw new RuntimeException(b1 + " and " + b2 + " should be ==");
++
++ }
++
++ // Validate that Method instances representing the annotation elements
++ // behave as intended
++ private static void validateAnnotationSharingIsSafe(AccessibleObject m1, AccessibleObject m2)
++ throws Exception {
++ Bar b1 = m1.getAnnotation(Bar.class);
++ Bar b2 = m2.getAnnotation(Bar.class);
++
++ Method mm1 = b1.annotationType().getMethod("value", (Class<?>[]) null);
++ Method mm2 = b2.annotationType().getMethod("value", (Class<?>[]) null);
++ inner(mm1, mm2);
++
++ mm1 = b1.getClass().getMethod("value", (Class<?>[]) null);
++ mm2 = b2.getClass().getMethod("value", (Class<?>[]) null);
++ inner(mm1, mm2);
++
++ }
++ private static void inner(Method mm1, Method mm2)
++ throws Exception {
++ if (!mm1.equals(mm2))
++ throw new RuntimeException(mm1 + " and " + mm2 + " should be equal()");
++
++ mm1.setAccessible(false);
++ mm2.setAccessible(true);
++
++ if (mm1.isAccessible())
++ throw new RuntimeException(mm1 + " should not be accessible");
++
++ if (!mm2.isAccessible())
++ throw new RuntimeException(mm2 + " should be accessible");
++ }
++
++ // Validate that array element values are not shared
++ private static void validateArrayValues(Baz a, Baz b) {
++ String[] s1 = a.value();
++ String[] s2 = b.value();
++
++ s1[0] = "22";
++
++ if (!s2[0].equals("1"))
++ throw new RuntimeException("Mutation of array elements should not be detectable");
++ }
++
++ @Foo @Bar("val") @Baz({"1", "2"})
++ public void m() {
++ return ;
++ }
++
++ @Foo @Bar("someValue") @Baz({"1", "22", "33"})
++ public Object f = new Object();
++}
++
++@Retention(RetentionPolicy.RUNTIME)
++@interface Foo {}
++
++@Retention(RetentionPolicy.RUNTIME)
++@interface Bar {
++ String value();
++}
++
++@Retention(RetentionPolicy.RUNTIME)
++@interface Baz {
++ String [] value();
++}
+--- ./jdk/test/java/math/BigDecimal/ZeroScalingTests.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/math/BigDecimal/ZeroScalingTests.java Wed Feb 04 12:14:43 2015 -0800
+@@ -23,8 +23,10 @@
+
+ /*
+ * @test
+- * @bug 4902952 4905407 4916149
+- * @summary Tests that the scale of zero is propagated properly and has the proper effect.
++ * @bug 4902952 4905407 4916149 8057793
++ * @summary Tests that the scale of zero is propagated properly and has the
++ * proper effect and that setting the scale to zero does not mutate the
++ * BigDecimal.
+ * @author Joseph D. Darcy
+ */
+
+@@ -445,6 +447,16 @@
+ return failures;
+ }
+
++ static int setScaleDoesNotMutateTest() {
++ BigDecimal total = new BigDecimal("258815507198903607775511093103396443816569106750031264155319238473795838680758514810110764742309284477206138527975952150289602995045050194333030191178778772026538699925775139201970526695485362661420908248887297829319881475178467494779683293036572059595504702727301324759997409522995072582369210284334718757260859794972695026582432867589093687280300148141501712013226636373167978223780290547640482160818746599330924736802844173226042389174403401903999447463440670236056324929325189403433689"
++ + ".426167432065785331444814035799717606745777287606858873045971898862329763544687891847664736523584843544347118836628373041412918374550458884706686730726101338872517021688769782894793734049819222924171842793485919753186993388451909096042127903835765393729547730953942175461146061715108701615615142134282261293656760570061554783195726716403304101469782303957325142638493327692352838806741611887655695029948975509680496573999174402058593454203190963443179532640446352828089016874853634851387762579319853267317320515941105912189838719919259277721994880193541634872882180184303434360412344059435559680494807415573269199203376126242271766939666939316648575065702750502798973418978204972336924254702551350654650573582614211506856383897692911422458286912085339575875324832979140870119455620532272318122103640233069115700020760625493816902806241630788230268031695140687964931377988962507263990468276009750998066442971308866347136022907166625330623130307555914930120150437900510530537258665172619821272937026713977709974434967165159545592482710663639966781678268622620229577009317698254134914742098420792313931843709810905414336383757407675429663714210967924767434203021205270369316797752411974617662200898086335322218191674846795163102021505555508444216708745911194321674887527227200297039471799580744303346354057273540730643842091810899490590914195225087593013834388801018488174855060306804024894292757613618190472234110859436472645203753139820658279559340251226992556744343475086923568365637919479462424794554522865559888240039662899509652221329892034706445253487898044421278283079233226845124525434586324657471286953226255430662125870993375281512713207125720748163498642795960457639954616530163959004770092547297392499137383176609646505351001304840762905826237024982330597805063521162285806541220110524989649256399233792799406995068469271941269511818994954109392839548141262324660472253632382325038836831429045617036015122388070240133760858500132713255407855625837956886349324981003917084922808187223285051144454915441134217743066575863563572152133978905444998209075763950909784148142018992367290485890072303179512881131769414783097454103103347826517701720263541869335631166977965013552647906729408522950996105479525445916501155305220090853891226367184989434453290788068397817927893708837722255115237672194162924260945492012622891770365546831236789867922136747819364833843397165107825773447549885351449899330007200651144003961228091210630807333236718793283427788965479074476288255387824982443633190938302785760754436525586544523339170400053128503337395428393881357669568532722167493096151221381017320147344991331421789379785964440840684363041795410525097564979585773948558651896834067324427900848255265001498890329859444233861478388742393060996236783742654761350763876989363052609107226398858310051497856931093693697981165801539060516895227818925342535261227134364063673285588256280386915163875872231395348293505967057794409379709079685798908660258077792158532257603211711587587586356431658240229896344639704");
++ if (total.setScale(0, RoundingMode.DOWN).equals(total.setScale(0, RoundingMode.DOWN))) {
++ return 0;
++ } else {
++ return 1;
++ }
++ }
++
+ public static void main(String argv[]) {
+ int failures = 0;
+
+@@ -455,6 +467,7 @@
+ failures += setScaleTests();
+ failures += toEngineeringStringTests();
+ failures += ulpTests();
++ failures += setScaleDoesNotMutateTest();
+
+ if (failures > 0 ) {
+ throw new RuntimeException("Incurred " + failures + " failures" +
+--- ./jdk/test/java/math/BigInteger/BigIntegerTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/math/BigInteger/BigIntegerTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -71,6 +71,7 @@
+ static final int BITS_TOOM_COOK_SQUARE = 6912;
+ static final int BITS_SCHOENHAGE_BASE = 640;
+ static final int BITS_BURNIKEL_ZIEGLER = 2560;
++ static final int BITS_BURNIKEL_ZIEGLER_OFFSET = 1280;
+
+ static final int ORDER_SMALL = 60;
+ static final int ORDER_MEDIUM = 100;
+@@ -288,19 +289,19 @@
+ * where {@code abs(u) > abs(v)} and {@code a > b && b > 0}, then if
+ * {@code w/z = q1*z + r1} and {@code u/v = q2*v + r2}, then
+ * {@code q1 = q2*pow(2,a-b)} and {@code r1 = r2*pow(2,b)}. The test
+- * ensures that {@code v} is just under the B-Z threshold and that {@code w}
+- * and {@code z} are both over the threshold. This implies that {@code u/v}
+- * uses the standard division algorithm and {@code w/z} uses the B-Z
+- * algorithm. The results of the two algorithms are then compared using the
+- * observation described in the foregoing and if they are not equal a
+- * failure is logged.
++ * ensures that {@code v} is just under the B-Z threshold, that {@code z} is
++ * over the threshold and {@code w} is much larger than {@code z}. This
++ * implies that {@code u/v} uses the standard division algorithm and
++ * {@code w/z} uses the B-Z algorithm. The results of the two algorithms
++ * are then compared using the observation described in the foregoing and
++ * if they are not equal a failure is logged.
+ */
+ public static void divideLarge() {
+ int failCount = 0;
+
+- BigInteger base = BigInteger.ONE.shiftLeft(BITS_BURNIKEL_ZIEGLER - 33);
++ BigInteger base = BigInteger.ONE.shiftLeft(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 33);
+ for (int i=0; i<SIZE; i++) {
+- BigInteger addend = new BigInteger(BITS_BURNIKEL_ZIEGLER - 34, rnd);
++ BigInteger addend = new BigInteger(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 34, rnd);
+ BigInteger v = base.add(addend);
+
+ BigInteger u = v.multiply(BigInteger.valueOf(2 + rnd.nextInt(Short.MAX_VALUE - 1)));
+@@ -312,14 +313,14 @@
+ v = v.negate();
+ }
+
+- int a = 17 + rnd.nextInt(16);
++ int a = BITS_BURNIKEL_ZIEGLER_OFFSET + rnd.nextInt(16);
+ int b = 1 + rnd.nextInt(16);
+- BigInteger w = u.multiply(BigInteger.valueOf(1L << a));
+- BigInteger z = v.multiply(BigInteger.valueOf(1L << b));
++ BigInteger w = u.multiply(BigInteger.ONE.shiftLeft(a));
++ BigInteger z = v.multiply(BigInteger.ONE.shiftLeft(b));
+
+ BigInteger[] divideResult = u.divideAndRemainder(v);
+- divideResult[0] = divideResult[0].multiply(BigInteger.valueOf(1L << (a - b)));
+- divideResult[1] = divideResult[1].multiply(BigInteger.valueOf(1L << b));
++ divideResult[0] = divideResult[0].multiply(BigInteger.ONE.shiftLeft(a - b));
++ divideResult[1] = divideResult[1].multiply(BigInteger.ONE.shiftLeft(b));
+ BigInteger[] bzResult = w.divideAndRemainder(z);
+
+ if (divideResult[0].compareTo(bzResult[0]) != 0 ||
+--- ./jdk/test/java/net/InetAddress/IPv4Formats.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/net/InetAddress/IPv4Formats.java Wed Feb 04 12:14:43 2015 -0800
+@@ -27,6 +27,7 @@
+ * @summary InetAddress.getByName behaves differently on windows
+ */
+ import java.net.*;
++import java.util.UUID;
+
+ public class IPv4Formats {
+ public static void main(String[] args) {
+@@ -36,7 +37,7 @@
+ {"126.1", "126.0.0.1"},
+ {"128.50.65534", "128.50.255.254"},
+ {"192.168.1.2", "192.168.1.2"},
+- {"hello.foo.bar", null},
++ {"invalidhost.invalid", null},
+ {"1024.1.2.3", null},
+ {"128.14.66000", null }
+ };
+--- ./jdk/test/java/net/NetworkInterface/Test.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/net/NetworkInterface/Test.java Wed Feb 04 12:14:43 2015 -0800
+@@ -22,7 +22,9 @@
+ */
+
+ /* @test
+- * @bug 4405354 6594296
++ * @bug 4405354 6594296 8058216
++ * @run main Test
++ * @run main/othervm -Djava.net.preferIPv4Stack=true Test
+ * @summary Basic tests for NetworkInterface
+ */
+ import java.net.NetworkInterface;
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/net/ResponseCache/Test2.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,135 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8042622
++ * @summary Check for CRL results in IllegalArgumentException "white space not allowed"
++ * @run main/othervm Test2
++ */
++
++import com.sun.net.httpserver.*;
++
++import java.util.*;
++import java.util.concurrent.*;
++import java.io.*;
++import java.net.*;
++import java.security.*;
++import javax.security.auth.callback.*;
++import javax.net.ssl.*;
++
++public class Test2 {
++
++ static volatile boolean failed = false;
++
++ static class Cache extends ResponseCache {
++ public CacheResponse get(URI uri, String method, Map<String,List<String>> headers) {
++ Set<String> keys = headers.keySet();
++ for (String key : keys) {
++ if (key.indexOf(' ') != -1 || key.indexOf('\t') != -1
++ || key.indexOf(':') != -1)
++ {
++ failed = true;
++ }
++ }
++ return null;
++ }
++
++ public CacheRequest put(URI uri, URLConnection c) throws IOException {
++ return null;
++ }
++ }
++
++ static int port;
++
++ static String urlstring, redirstring;
++
++ public static void main (String[] args) throws Exception {
++ Handler handler = new Handler();
++ InetSocketAddress addr = new InetSocketAddress (0);
++ HttpServer server = HttpServer.create (addr, 0);
++ port = server.getAddress().getPort();
++ HttpContext ctx = server.createContext ("/test", handler);
++ System.out.println ("Server: " + server.getAddress().getPort());
++ ResponseCache.setDefault(new Cache());
++
++ ExecutorService executor = Executors.newCachedThreadPool();
++ server.setExecutor (executor);
++ server.start ();
++
++ urlstring = "http://127.0.0.1:" + Integer.toString(port)+"/test/foo";
++ redirstring = urlstring + "/redirect/bar";
++
++ URL url = new URL (urlstring);
++ HttpURLConnection urlc = (HttpURLConnection)url.openConnection();
++ urlc.addRequestProperty("X-Foo", "bar");
++ urlc.setInstanceFollowRedirects(true);
++ System.out.println(urlc.getResponseCode());
++ InputStream i = urlc.getInputStream();
++ int count=0;
++ for (int c=i.read(); c!=-1; c=i.read()) {
++ //System.out.write(c);
++ count++;
++ }
++ System.out.println("Read " + count);
++ System.out.println("FINISHED");
++ server.stop(0);
++ executor.shutdownNow();
++ if (failed) {
++ throw new RuntimeException("Test failed");
++ }
++ }
++
++ public static boolean error = false;
++ public static int count = 0;
++
++ static class Handler implements HttpHandler {
++ int invocation = 0;
++ public void handle (HttpExchange t)
++ throws IOException
++ {
++ InputStream is = t.getRequestBody();
++ Headers map = t.getRequestHeaders();
++ Headers rmap = t.getResponseHeaders();
++ invocation ++;
++ if (invocation == 1) {
++ rmap.add("Location", redirstring);
++ while (is.read () != -1) ;
++ is.close();
++ System.out.println ("sending response");
++ t.sendResponseHeaders (301, 0);
++ } else {
++ byte[] buf = "Hello world".getBytes();
++ t.sendResponseHeaders (200, buf.length);
++ OutputStream os = t.getResponseBody();
++ try {
++ os.write(buf);
++ } catch (IOException e) {
++ System.out.println ("EX 1 " + e);
++ }
++ }
++ System.out.println ("Closing");
++ t.close();
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/nio/channels/FileChannel/BlockDeviceSize.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/* @test
++ * @bug 8054029
++ * @summary Block devices should not report size=0 on Linux
++ */
++
++import java.io.RandomAccessFile;
++import java.nio.file.Path;
++import java.nio.file.Paths;
++import java.nio.channels.FileChannel;
++import java.nio.file.AccessDeniedException;
++import java.nio.file.NoSuchFileException;
++import static java.nio.file.StandardOpenOption.*;
++
++
++public class BlockDeviceSize {
++ private static final String BLK_FNAME = "/dev/sda1";
++ private static final Path BLK_PATH = Paths.get(BLK_FNAME);
++
++ public static void main(String[] args) throws Throwable {
++ try (FileChannel ch = FileChannel.open(BLK_PATH, READ);
++ RandomAccessFile file = new RandomAccessFile(BLK_FNAME, "r")) {
++
++ long size1 = ch.size();
++ long size2 = file.length();
++ if (size1 != size2) {
++ throw new RuntimeException("size differs when retrieved" +
++ " in different ways: " + size1 + " != " + size2);
++ }
++ System.out.println("OK");
++
++ } catch (NoSuchFileException nsfe) {
++ System.err.println("File " + BLK_FNAME + " not found." +
++ " Skipping test");
++ } catch (AccessDeniedException ade) {
++ System.err.println("Access to " + BLK_FNAME + " is denied." +
++ " Run test as root.");
++ }
++ }
++}
+--- ./jdk/test/java/nio/file/WatchService/Basic.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/nio/file/WatchService/Basic.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -22,7 +22,7 @@
+ */
+
+ /* @test
+- * @bug 4313887 6838333 7017446
++ * @bug 4313887 6838333 7017446 8011537 8042470
+ * @summary Unit test for java.nio.file.WatchService
+ * @library ..
+ * @run main Basic
+@@ -295,24 +295,31 @@
+ // IllegalArgumentException
+ System.out.println("IllegalArgumentException tests...");
+ try {
+- dir.register(watcher, new WatchEvent.Kind<?>[]{ } );
++ dir.register(watcher /*empty event list*/);
+ throw new RuntimeException("IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException x) {
+ }
+ try {
+ // OVERFLOW is ignored so this is equivalent to the empty set
+- dir.register(watcher, new WatchEvent.Kind<?>[]{ OVERFLOW });
++ dir.register(watcher, OVERFLOW);
++ throw new RuntimeException("IllegalArgumentException not thrown");
++ } catch (IllegalArgumentException x) {
++ }
++ try {
++ // OVERFLOW is ignored even if specified multiple times
++ dir.register(watcher, OVERFLOW, OVERFLOW);
+ throw new RuntimeException("IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException x) {
+ }
+
+ // UnsupportedOperationException
+ try {
+- dir.register(watcher, new WatchEvent.Kind<?>[]{
++ dir.register(watcher,
+ new WatchEvent.Kind<Object>() {
+ @Override public String name() { return "custom"; }
+ @Override public Class<Object> type() { return Object.class; }
+- }});
++ });
++ throw new RuntimeException("UnsupportedOperationException not thrown");
+ } catch (UnsupportedOperationException x) {
+ }
+ try {
+@@ -328,7 +335,7 @@
+ // NullPointerException
+ System.out.println("NullPointerException tests...");
+ try {
+- dir.register(null, new WatchEvent.Kind<?>[]{ ENTRY_CREATE });
++ dir.register(null, ENTRY_CREATE);
+ throw new RuntimeException("NullPointerException not thrown");
+ } catch (NullPointerException x) {
+ }
+@@ -380,7 +387,7 @@
+
+ try {
+ dir.register(watcher, new WatchEvent.Kind<?>[]{ ENTRY_CREATE });
+- throw new RuntimeException("ClosedWatchServiceException not thrown");
++ throw new RuntimeException("ClosedWatchServiceException not thrown");
+ } catch (ClosedWatchServiceException x) {
+ }
+
+@@ -468,6 +475,28 @@
+ }
+ }
+
++ /**
++ * Test that thread interruped status is preserved upon a call
++ * to register()
++ */
++ static void testThreadInterrupt(Path dir) throws IOException {
++ System.out.println("-- Thread interrupted status test --");
++
++ FileSystem fs = FileSystems.getDefault();
++ Thread curr = Thread.currentThread();
++ try (WatchService watcher = fs.newWatchService()) {
++ System.out.println("interrupting current thread");
++ curr.interrupt();
++ dir.register(watcher, ENTRY_CREATE);
++ if (!curr.isInterrupted())
++ throw new RuntimeException("thread should remain interrupted");
++ System.out.println("current thread is still interrupted");
++ System.out.println("OKAY");
++ } finally {
++ curr.interrupted();
++ }
++ }
++
+ public static void main(String[] args) throws IOException {
+ Path dir = TestUtil.createTemporaryDirectory();
+ try {
+@@ -478,6 +507,7 @@
+ testWakeup(dir);
+ testExceptions(dir);
+ testTwoWatchers(dir);
++ testThreadInterrupt(dir);
+
+ } finally {
+ TestUtil.removeAll(dir);
+--- ./jdk/test/java/security/cert/CertificateFactory/invalidEncodedCerts/DetectInvalidEncoding.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/security/cert/CertificateFactory/invalidEncodedCerts/DetectInvalidEncoding.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -23,27 +23,548 @@
+
+ /**
+ * @test
+- * @bug 4776466
++ * @bug 4776466 8032573
+ * @summary check that CertificateFactory rejects invalid encoded X.509 certs
+ */
+
+ import java.io.*;
++import java.util.Collection;
++import java.util.List;
++import java.util.LinkedList;
++import javax.security.auth.x500.X500Principal;
++import java.security.GeneralSecurityException;
+ import java.security.cert.*;
+
+ public class DetectInvalidEncoding {
+
++ // Originally found in the test file:
++ // java/security/cert/CertificateFactory/invalidEncodedCerts/invalidcert.pem
++ // The first character of the PEM encoding has been changed from "M" to
++ // "X" to force a failure during decoding.
++ private static final String INVALID_CERT =
++ "-----BEGIN CERTIFICATE-----\n" +
++ "XIICJjCCAdCgAwIBAgIBITANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCVVMx\n" +
++ "EzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xFTAT\n" +
++ "BgNVBAoTDEJFQSBXZWJMb2dpYzERMA8GA1UECxMIU2VjdXJpdHkxIzAhBgNVBAMT\n" +
++ "GkRlbW8gQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9zdXBw\n" +
++ "b3J0QGJlYS5jb20wHhcNMDAwNTMwMjEzODAxWhcNMDQwNTEzMjEzODAxWjCBjDEL\n" +
++ "MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG\n" +
++ "cmFuY2lzY28xFTATBgNVBAoTDEJFQSBXZWJMb2dpYzEZMBcGA1UEAxMQd2VibG9n\n" +
++ "aWMuYmVhLmNvbTEeMBwGCSqGSIb3DQEJARYPc3VwcG9ydEBiZWEuY29tMFwwDQYJ\n" +
++ "KoZIhvcNAQEBBQADSwAwSAJBALdsXEHqKHgs6zj0hU5sXMAUHzoT8kgWXmNkKHXH\n" +
++ "79qbPh6EfdlriW9G/AbRF/pKrCQu7hhllAxREbqTuSlf2EMCAwEAATANBgkqhkiG\n" +
++ "9w0BAQQFAANBACgmqflL5m5LNeJGpWx9aIoABCiuDcpw1fFyegsqGX7CBhffcruS\n" +
++ "1p8h5vkHVbMu1frD1UgGnPlOO/K7Ig/KrsU=\n" +
++ "-----END CERTIFICATE-----";
++
++ // Created with keytool:
++ // keytool -genkeypair -keyalg rsa -keysize 2048 -keystore <KS_FILE>
++ // -alias root -sigalg SHA256withRSA -dname "CN=Root, O=SomeCompany"
++ // -validity 730 -ext bc:critical=ca:true
++ // -ext ku:critical=keyCertSign,cRLSign
++ private static final String SINGLE_ROOT_CERT =
++ "-----BEGIN CERTIFICATE-----\n" +
++ "MIIDCjCCAfKgAwIBAgIEDUiw+DANBgkqhkiG9w0BAQsFADAlMRQwEgYDVQQKEwtT\n" +
++ "b21lQ29tcGFueTENMAsGA1UEAxMEUm9vdDAeFw0xNDA4MjgyMTI5MjZaFw0xNjA4\n" +
++ "MjcyMTI5MjZaMCUxFDASBgNVBAoTC1NvbWVDb21wYW55MQ0wCwYDVQQDEwRSb290\n" +
++ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0VFecSNdH6CJhPOSG127\n" +
++ "tuvld4y7GGJ0kQf3Q0b8qgprsXAmn0/bQR+YX7PfS408cFW+q2SWXeY2kC/3chvi\n" +
++ "2syMsGdUJrDzuMbYsbvKPKyuJ2GJskX3mSbLMJj5Tzhg4qmwbzDTFIJ51yGa1Wmh\n" +
++ "i2+4PhltqT0TohvSVJlBrOWNhmvwv5UWsF4e2i04rebDZQoWkmD3MpImZXF/HYre\n" +
++ "9P8NP97vN0xZmh5PySHy2ILXN3ZhTn3tq0YxNSQTaMUfhgoyzWFvZKAnm/tZIh/1\n" +
++ "oswwEQPIZJ25AUTm9r3YPQXl1hsNdLU0asEVYRsgzGSTX5gCuUY+KzhStzisOcUY\n" +
++ "uQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV\n" +
++ "HQ4EFgQUz1FBNixG/KCgcn6FOWzxP1hujG0wDQYJKoZIhvcNAQELBQADggEBAL60\n" +
++ "ZaNc6eIMbKntGVE/pdxxyKwPdDyAAeEevX23KRWoLbQjHXo5jrfDPhI5k45ztlyU\n" +
++ "+tIQbc81LlCl88I4dIx0fvEbxjNaAYhFNXwwSQBs2CuEAdRK8hodXbRcEeI+G10F\n" +
++ "ARIVs2C7JNm/RhxskCWgj6tFIOGaTZ9gHyvlQUEM18sr5fXZlXTqspZCmz3t5XPi\n" +
++ "5/wYLv6vk7k3G8WzMHbBE0bYI+61cCc8rbMHldtymbwSwiqfKC9y7oPEfRCbzVUe\n" +
++ "fgrKcOyVWDuw0y0hhsQL/oONjPp4uK/bl9B7T84t4+ihxdocWKx6eyhFvOvZH9t2\n" +
++ "kUylb9yBUYStwGExMHg=\n" +
++ "-----END CERTIFICATE-----";
++
++ // Created with keytool:
++ // keytool -genkeypair -keyalg rsa -keysize 2048 -keystore <KS_FILE>
++ // -alias root -sigalg SHA256withRSA
++ // -dname "CN=Intermed, O=SomeCompany" -validity 730
++ // -ext bc:critical=ca:true -ext ku:critical=keyCertSign,cRLSign
++ // keytool -certreq -keystore <KS_FILE> -sigalg SHA256withRSA
++ // -alias intermed -dname "CN=Intermed, O=SomeCompany"
++ // keytool -gencert -keystore <KS_FILE> -alias intermed
++ // -sigalg SHA256withRSA -validity 730
++ // -ext bc:critical=ca:true -ext ku:critical=keyCertSign,cRLSign
++ private static final String INTERMED_CA_CERT =
++ "-----BEGIN CERTIFICATE-----\n" +
++ "MIIDLzCCAhegAwIBAgIEIIgOyDANBgkqhkiG9w0BAQsFADAlMRQwEgYDVQQKEwtT\n" +
++ "b21lQ29tcGFueTENMAsGA1UEAxMEUm9vdDAeFw0xNDA4MjgyMjUyNDJaFw0xNjA4\n" +
++ "MDcyMjUyNDJaMCkxFDASBgNVBAoTC1NvbWVDb21wYW55MREwDwYDVQQDEwhJbnRl\n" +
++ "cm1lZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJEecvTWla8kdWx+\n" +
++ "HHu5ryfBpJ95I7V4MEajnmzJVZcwvKhDjlDgABDMuVwFEUUSyeOdbWJF3DLKnyMD\n" +
++ "KTx6/58kuVak3NX2TJ8cmmIlKf1upFbdrEtjYViSnNrApprfO8B3ORdBbO6QDYza\n" +
++ "IkAWdI5GllFnVkb4yhMUBg3zfhglF+bl3D3lVRlp9bCrUZoNRs+mZjhVbcMn22ej\n" +
++ "TfG5Y3VpNM4SN8dFIxPQLLk/aao+cmWEQdbQ0R6ydemRukqrw170olSVLeoGGala\n" +
++ "3D4oJckde8EgNPcghcsdQ6tpGhkpFhmoyzEsuToR7Gq9UT5V2kkqJneiKXqQg4wz\n" +
++ "vMAlUGECAwEAAaNjMGEwHwYDVR0jBBgwFoAUOw+92bevFoJz96pR1DrAkPPUKb0w\n" +
++ "DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLbnErBs\n" +
++ "q/Mhci5XElfjjLZp3GRyMA0GCSqGSIb3DQEBCwUAA4IBAQAq8y2DpkSV31IXZ1vr\n" +
++ "/Ye+Nj/2NvBydFeHVRGMAN1LJv6/Q42TCSXbr6cDQ4NWQUtPm90yZBYJSznkbShx\n" +
++ "HOJEE6R8PRJvoUtMm7fJrNtkybTt6jX4j50Lw8gdYB/rgZb4z8ZQZVEo/0zpW4HV\n" +
++ "Gs+q4z8TkdmLR18hl39sUEsxt99AOBk8NtKKVNfBWq9b0QDhRkXfmqhyeXdDsHOV\n" +
++ "8ksulsa7hseheHhdjziEOpQugh8qzSea2kFPrLB53VjWfa4qDzEPaNhahho9piCu\n" +
++ "82XDnOrcEk9KyHWM7sa7vtK7++W+0MXD/p9nkZ6NHrJXweLriU0DXO6ZY3mzNKJK\n" +
++ "435M\n" +
++ "-----END CERTIFICATE-----";
++
++ // Subordinate cert created using keytool, both certs exported to
++ // files individually, then use openssl to place in a PKCS#7:
++ // openssl crl2pkcs7 -nocrl -certfile <INTERMED-CERT-PEM>
++ // -certfile <ROOT-CERT-PEM> -out <P7-DEST-PEM-FILE>
++ private static final String PKCS7_INTERMED_ROOT_CERTS =
++ "-----BEGIN PKCS7-----\n" +
++ "MIIGbgYJKoZIhvcNAQcCoIIGXzCCBlsCAQExADALBgkqhkiG9w0BBwGgggZBMIID\n" +
++ "LzCCAhegAwIBAgIEIIgOyDANBgkqhkiG9w0BAQsFADAlMRQwEgYDVQQKEwtTb21l\n" +
++ "Q29tcGFueTENMAsGA1UEAxMEUm9vdDAeFw0xNDA4MjgyMjUyNDJaFw0xNjA4MDcy\n" +
++ "MjUyNDJaMCkxFDASBgNVBAoTC1NvbWVDb21wYW55MREwDwYDVQQDEwhJbnRlcm1l\n" +
++ "ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJEecvTWla8kdWx+HHu5\n" +
++ "ryfBpJ95I7V4MEajnmzJVZcwvKhDjlDgABDMuVwFEUUSyeOdbWJF3DLKnyMDKTx6\n" +
++ "/58kuVak3NX2TJ8cmmIlKf1upFbdrEtjYViSnNrApprfO8B3ORdBbO6QDYzaIkAW\n" +
++ "dI5GllFnVkb4yhMUBg3zfhglF+bl3D3lVRlp9bCrUZoNRs+mZjhVbcMn22ejTfG5\n" +
++ "Y3VpNM4SN8dFIxPQLLk/aao+cmWEQdbQ0R6ydemRukqrw170olSVLeoGGala3D4o\n" +
++ "Jckde8EgNPcghcsdQ6tpGhkpFhmoyzEsuToR7Gq9UT5V2kkqJneiKXqQg4wzvMAl\n" +
++ "UGECAwEAAaNjMGEwHwYDVR0jBBgwFoAUOw+92bevFoJz96pR1DrAkPPUKb0wDwYD\n" +
++ "VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLbnErBsq/Mh\n" +
++ "ci5XElfjjLZp3GRyMA0GCSqGSIb3DQEBCwUAA4IBAQAq8y2DpkSV31IXZ1vr/Ye+\n" +
++ "Nj/2NvBydFeHVRGMAN1LJv6/Q42TCSXbr6cDQ4NWQUtPm90yZBYJSznkbShxHOJE\n" +
++ "E6R8PRJvoUtMm7fJrNtkybTt6jX4j50Lw8gdYB/rgZb4z8ZQZVEo/0zpW4HVGs+q\n" +
++ "4z8TkdmLR18hl39sUEsxt99AOBk8NtKKVNfBWq9b0QDhRkXfmqhyeXdDsHOV8ksu\n" +
++ "lsa7hseheHhdjziEOpQugh8qzSea2kFPrLB53VjWfa4qDzEPaNhahho9piCu82XD\n" +
++ "nOrcEk9KyHWM7sa7vtK7++W+0MXD/p9nkZ6NHrJXweLriU0DXO6ZY3mzNKJK435M\n" +
++ "MIIDCjCCAfKgAwIBAgIEdffjKTANBgkqhkiG9w0BAQsFADAlMRQwEgYDVQQKEwtT\n" +
++ "b21lQ29tcGFueTENMAsGA1UEAxMEUm9vdDAeFw0xNDA4MjgyMjQ2MzZaFw0xNjA4\n" +
++ "MjcyMjQ2MzZaMCUxFDASBgNVBAoTC1NvbWVDb21wYW55MQ0wCwYDVQQDEwRSb290\n" +
++ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhnXc8Avv54Gk2xjVa2yA\n" +
++ "lBL/Cug1nyvKl5wqmN+foT6cMOX6bneCkJOJ4lSbch3gvl4ctlX/9hm3pB/+HhSr\n" +
++ "em2NcLQrLEq8l9Ar4RnqfoXQR4Uy+4P6wj9OcVV7e/v/+ZPnStOoEAtb5nAwsR2b\n" +
++ "hOC/tIFNwflrsmsmtMSoOiNftpYLFF4eOAdpDrXYMrqNu6ZxZsOQ7WZl4SsVOx1N\n" +
++ "/IINXwBLyoHJDzLZ0iJEV0O6mh846s0n6QXeK1P5d0uLcoZaZ1k8Q4sRcdoLA6rS\n" +
++ "e1WffipBFMvIuoDIigkHZIKVYRLG828rO+PFnRah0ybybkVsN6s3oLxfhswZDvut\n" +
++ "OwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV\n" +
++ "HQ4EFgQUOw+92bevFoJz96pR1DrAkPPUKb0wDQYJKoZIhvcNAQELBQADggEBACBN\n" +
++ "wEaV70FKKBINHtNwesd7TB6fgSaVgDZOO08aseHbXnm7AUhtDV3P5rQR2AsKtbg4\n" +
++ "COhlKw2/Ki18D4DfdCccFKFTRZBjqj2PxNmn6C68l1/bT4PuUXuM7rW++53RcOA7\n" +
++ "TbgLuzA25kSz7XinRvR8L4VwHtppu5tSYEthMIMgLZLGGV9r7kBfpY8lXdxQM8vb\n" +
++ "xZUIysasvVtVUFPOTV6g2dfn8QCoqLOmxyzTLdXe4M6acP6f7lmhgr3LMqDtB6K9\n" +
++ "pN+OImr77zNdZ+jTB+5e9a8gAvc5ZfG7Nk5RfwUatYTAFZ6Uggy2cKmIRpXCia18\n" +
++ "If78mc7goS1+lHkGCs2hADEA\n" +
++ "-----END PKCS7-----";
++
++ // Empty PKCS#7 in DER form can be created with openssl:
++ // openssl crl2pkcs7 -nocrl -outform DER
++ private static final byte[] PKCS7_BER_EMPTY = {
++ 48, 39, 6, 9, 42, -122, 72, -122,
++ -9, 13, 1, 7, 2, -96, 26, 48,
++ 24, 2, 1, 1, 49, 0, 48, 11,
++ 6, 9, 42, -122, 72, -122, -9, 13,
++ 1, 7, 1, -96, 0, -95, 0, 49,
++ 0
++ };
++
++ private static final String JTEST_ROOT_CRL =
++ "-----BEGIN X509 CRL-----\n" +
++ "MIICoTCBigIBATANBgkqhkiG9w0BAQsFADA1MQ4wDAYDVQQKEwVKVGVzdDELMAkG\n" +
++ "A1UECxMCSVQxFjAUBgNVBAMTDUpUZXN0IFJvb3QgQ0EXDTE0MDkwNDE4NDIyMVqg\n" +
++ "MDAuMB8GA1UdIwQYMBaAFO6bllCV6kctH77MfqAtefNeRdsmMAsGA1UdFAQEAgIA\n" +
++ "jjANBgkqhkiG9w0BAQsFAAOCAgEAmp8ihtiRthknDC+VzehmlQw5u8MftMZYQYk5\n" +
++ "EI04SwyzY9JTL8QHb4u7fXjnZAyN89aYPypI5OSyDsyyGP/JDNsBt2Um/fl0aaCl\n" +
++ "Z4Np6x+dB9+oIU1XY7y2+uyQUC5MHivQ5ddbGPoAvK/msbugTGAjHvZpM+l0okiV\n" +
++ "3SofDrii5BSosFEkXfkf2oG9ZLO3YamsFMEZaOj/eWDyGhTyJMGsq2/8NeTF21Tp\n" +
++ "YkeDcTHqR5KHoYXjOIaS7NjmErm+uDpKH9Lq+JUcYrbUhmjnq5z04EsPF2F2L7Vb\n" +
++ "THI+awQAUQit16lXGuz7fFRZi2vPyiaRP5n2QT5D+ac1dAs+oWLDJw6Tf2v9KVTe\n" +
++ "OmW62yd6zQqCwBg+n57UcNu3sv/Sq3t7iRuN0AmWlIhu659POPQv7Np6bEo6dIpp\n" +
++ "u7Ze6D2KPtM177ETHYlCx2a3g9VEZYKrVhQ2749St0Cp5szVq691jFZAWYOzcfEO\n" +
++ "XfK1y25pmlBjvhNIIVRlU+T5rjNb8GaleYKVYnKOcv700K32QxFzcPf7nbNKwW99\n" +
++ "tcaNHFNP+LW/XP8I3CJ8toXLLcOITKVwMA+0GlO5eL7eX5POc+vE9+7IzGuybmU4\n" +
++ "uslxoLdJ0NSZWpYmf6a6qrJ67cj5i3706H+eBsWQcShfSYreh+TyWQaGk+fkEiUV\n" +
++ "iy4QdJ0=\n" +
++ "-----END X509 CRL-----";
++
++ private static final String JTEST_INTERMED_CRL =
++ "-----BEGIN X509 CRL-----\n" +
++ "MIICzzCBuAIBATANBgkqhkiG9w0BAQsFADA/MQ4wDAYDVQQKEwVKVGVzdDELMAkG\n" +
++ "A1UECxMCSVQxIDAeBgNVBAMTF0pUZXN0IEludGVybWVkaWF0ZSBDQSAxFw0xNDA5\n" +
++ "MDQyMjE2NTRaMCIwIAIBBhcNMTQwOTA0MjIxNjU0WjAMMAoGA1UdFQQDCgEFoDAw\n" +
++ "LjAfBgNVHSMEGDAWgBSvRdjbkSMJ3A7s5H6EWghQ+lkw/zALBgNVHRQEBAICAJsw\n" +
++ "DQYJKoZIhvcNAQELBQADggIBALJmikMwil8oywhenoO8o9xxCOIU0xrt3KdfiSXw\n" +
++ "8MtQXZHT9d1C6tlLAsYkWAfmfTvM2OU6wquFCLLsFmDZszbbCqmn4JhYBSKQMqlm\n" +
++ "IHnsiOFPvITW2FU08fWNLM+FtQzPnTFmx/CJo+wfGpq5tZMIbsccsCJ5uvZVAWGh\n" +
++ "0KbPmYcJG/O384+kzr/2H2IaoZoMMABec5c5FEF/tpp8jawzY+0VFyaVrumKWdan\n" +
++ "+3OvRQxT1wLxfNi2vdxB2rmNPo423qanXZAoVv260um3LYlmXBNK1jwQ9lp78jkT\n" +
++ "B7zMVa4hOUWVxdWc/LE6fUYgPsNqZd+hWy/PolIRp5TS21B5hkc5K87LT59GkexK\n" +
++ "vNVKQennOLGtH+Q7htK4UeY4Gm/W7UydOQ0k7hZzyfMDkCfLfNfK0l63qKwUku36\n" +
++ "UdeI1LXqulPEvb/d7rRAAM9p5Sm+RsECj2bcrZBMdIGXcSo26A5tzZpTEC79i4S1\n" +
++ "yxYIooeBnouUkDJ9+VBsJTSKY5fpU8JSkQPRyHKt+trGAkBt2Ka5MqrHtITzQ1vP\n" +
++ "5q4tNr45JGEXllH83NlBpWURfsdtkDHa3lxTD/pkrywOCyzz7wQ22D8Kul7EN8nT\n" +
++ "7LDbN+O3G9GHICxvWlJHp6HMsqGTuH1MIUR+5uZFOJa1S0IzorUIEieLncDUPgzO\n" +
++ "M4JA\n" +
++ "-----END X509 CRL-----";
++
++ // PKCS#7 CRL Set containing JTEST root and intermediate CRLs
++ private static final String PKCS7_CRL_SET =
++ "-----BEGIN PKCS7-----\n" +
++ "MIIFpQYJKoZIhvcNAQcCoIIFljCCBZICAQExADALBgkqhkiG9w0BBwGgAKGCBXgw\n" +
++ "ggKhMIGKAgEBMA0GCSqGSIb3DQEBCwUAMDUxDjAMBgNVBAoTBUpUZXN0MQswCQYD\n" +
++ "VQQLEwJJVDEWMBQGA1UEAxMNSlRlc3QgUm9vdCBDQRcNMTQwOTA0MTg0MjIxWqAw\n" +
++ "MC4wHwYDVR0jBBgwFoAU7puWUJXqRy0fvsx+oC15815F2yYwCwYDVR0UBAQCAgCO\n" +
++ "MA0GCSqGSIb3DQEBCwUAA4ICAQCanyKG2JG2GScML5XN6GaVDDm7wx+0xlhBiTkQ\n" +
++ "jThLDLNj0lMvxAdvi7t9eOdkDI3z1pg/Kkjk5LIOzLIY/8kM2wG3ZSb9+XRpoKVn\n" +
++ "g2nrH50H36ghTVdjvLb67JBQLkweK9Dl11sY+gC8r+axu6BMYCMe9mkz6XSiSJXd\n" +
++ "Kh8OuKLkFKiwUSRd+R/agb1ks7dhqawUwRlo6P95YPIaFPIkwayrb/w15MXbVOli\n" +
++ "R4NxMepHkoehheM4hpLs2OYSub64Okof0ur4lRxittSGaOernPTgSw8XYXYvtVtM\n" +
++ "cj5rBABRCK3XqVca7Pt8VFmLa8/KJpE/mfZBPkP5pzV0Cz6hYsMnDpN/a/0pVN46\n" +
++ "ZbrbJ3rNCoLAGD6fntRw27ey/9Kre3uJG43QCZaUiG7rn0849C/s2npsSjp0imm7\n" +
++ "tl7oPYo+0zXvsRMdiULHZreD1URlgqtWFDbvj1K3QKnmzNWrr3WMVkBZg7Nx8Q5d\n" +
++ "8rXLbmmaUGO+E0ghVGVT5PmuM1vwZqV5gpVico5y/vTQrfZDEXNw9/uds0rBb321\n" +
++ "xo0cU0/4tb9c/wjcIny2hcstw4hMpXAwD7QaU7l4vt5fk85z68T37sjMa7JuZTi6\n" +
++ "yXGgt0nQ1JlaliZ/prqqsnrtyPmLfvTof54GxZBxKF9Jit6H5PJZBoaT5+QSJRWL\n" +
++ "LhB0nTCCAs8wgbgCAQEwDQYJKoZIhvcNAQELBQAwPzEOMAwGA1UEChMFSlRlc3Qx\n" +
++ "CzAJBgNVBAsTAklUMSAwHgYDVQQDExdKVGVzdCBJbnRlcm1lZGlhdGUgQ0EgMRcN\n" +
++ "MTQwOTA0MjIxNjU0WjAiMCACAQYXDTE0MDkwNDIyMTY1NFowDDAKBgNVHRUEAwoB\n" +
++ "BaAwMC4wHwYDVR0jBBgwFoAUr0XY25EjCdwO7OR+hFoIUPpZMP8wCwYDVR0UBAQC\n" +
++ "AgCbMA0GCSqGSIb3DQEBCwUAA4ICAQCyZopDMIpfKMsIXp6DvKPccQjiFNMa7dyn\n" +
++ "X4kl8PDLUF2R0/XdQurZSwLGJFgH5n07zNjlOsKrhQiy7BZg2bM22wqpp+CYWAUi\n" +
++ "kDKpZiB57IjhT7yE1thVNPH1jSzPhbUMz50xZsfwiaPsHxqaubWTCG7HHLAiebr2\n" +
++ "VQFhodCmz5mHCRvzt/OPpM6/9h9iGqGaDDAAXnOXORRBf7aafI2sM2PtFRcmla7p\n" +
++ "ilnWp/tzr0UMU9cC8XzYtr3cQdq5jT6ONt6mp12QKFb9utLpty2JZlwTStY8EPZa\n" +
++ "e/I5Ewe8zFWuITlFlcXVnPyxOn1GID7DamXfoVsvz6JSEaeU0ttQeYZHOSvOy0+f\n" +
++ "RpHsSrzVSkHp5zixrR/kO4bSuFHmOBpv1u1MnTkNJO4Wc8nzA5Any3zXytJet6is\n" +
++ "FJLt+lHXiNS16rpTxL2/3e60QADPaeUpvkbBAo9m3K2QTHSBl3EqNugObc2aUxAu\n" +
++ "/YuEtcsWCKKHgZ6LlJAyfflQbCU0imOX6VPCUpED0chyrfraxgJAbdimuTKqx7SE\n" +
++ "80Nbz+auLTa+OSRhF5ZR/NzZQaVlEX7HbZAx2t5cUw/6ZK8sDgss8+8ENtg/Crpe\n" +
++ "xDfJ0+yw2zfjtxvRhyAsb1pSR6ehzLKhk7h9TCFEfubmRTiWtUtCM6K1CBIni53A\n" +
++ "1D4MzjOCQDEA\n" +
++ "-----END PKCS7-----";
++
+ public static void main(String[] args) throws Exception {
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+- File f = new File
+- (System.getProperty("test.src", "."), "invalidcert.pem");
+- InputStream inStream = new FileInputStream(f);
+- try {
+- X509Certificate cert =
+- (X509Certificate) cf.generateCertificate(inStream);
+- } catch (CertificateParsingException ce) {
+- return;
++ List<DecodeTest> validTests = new LinkedList<>();
++ List<DecodeTest> invalidTests = new LinkedList<>();
++
++ // Load up positive test cases (for sanity checks)
++ StringBuilder sb = new StringBuilder();
++
++ validTests.add(new GenMultiCertTest("Single, valid certificate",
++ SINGLE_ROOT_CERT.getBytes(), null,
++ new X500Principal("CN=Root, O=SomeCompany")));
++ validTests.add(new GenMultiCertTest("PEM-encoded PKCS#7 chain",
++ PKCS7_INTERMED_ROOT_CERTS.getBytes(), null,
++ new X500Principal("CN=Intermed, O=SomeCompany"),
++ new X500Principal("CN=Root, O=SomeCompany")));
++ validTests.add(new GenMultiCertTest("Two PEM-encoded X509 certs",
++ (INTERMED_CA_CERT + "\n" + SINGLE_ROOT_CERT).getBytes(),
++ null,
++ new X500Principal("CN=Intermed, O=SomeCompany"),
++ new X500Principal("CN=Root, O=SomeCompany")));
++ validTests.add(new GenMultiCertTest("Empty data", new byte[0], null));
++
++ sb.append("Certificate 1: CN=Root, O=SomeCompany\n");
++ sb.append(SINGLE_ROOT_CERT).append("\n");
++ sb.append("Certificate 2: CN=Intermed, O=SomeCompany\n");
++ sb.append(INTERMED_CA_CERT).append("\n");
++ sb.append("Extra trailing data\n");
++ validTests.add(new GenMultiCertTest(
++ "Two PEM-encoded certs with leading/trailing " +
++ "text data around each.", sb.toString().getBytes(), null,
++ new X500Principal("CN=Root, O=SomeCompany"),
++ new X500Principal("CN=Intermed, O=SomeCompany")));
++ validTests.add(new GenMultiCertTest(
++ "BER-encoded PKCS#7 with empty certificates segment",
++ PKCS7_BER_EMPTY, null));
++ validTests.add(new GenMultiCRLTest(
++ "CRL with leading and trailing text data",
++ ("This is a CRL\n" + JTEST_ROOT_CRL +
++ "\nSee? Told you so\n\n").getBytes(), null,
++ new X500Principal("CN=JTest Root CA,OU=IT,O=JTest")));
++ validTests.add(new GenMultiCRLTest(
++ "Two CRLs, one after the other with leading/trailing text",
++ ("This is a CRL\n" + JTEST_ROOT_CRL +
++ "\nAnd this is another CRL\n" + JTEST_INTERMED_CRL +
++ "\nAnd this is trailing text\n").getBytes(), null,
++ new X500Principal("CN=JTest Root CA,OU=IT,O=JTest"),
++ new X500Principal(
++ "CN=JTest Intermediate CA 1,OU=IT,O=JTest")));
++ validTests.add(new GenMultiCRLTest("Two CRLs in a PKCS#7 CRL set",
++ PKCS7_CRL_SET.getBytes(), null,
++ new X500Principal("CN=JTest Root CA,OU=IT,O=JTest"),
++ new X500Principal("CN=JTest Intermediate CA 1,OU=IT,O=JTest")));
++
++ // Load up all test cases where we expect failures
++ invalidTests.add(new GenSingleCertTest("Invalid PEM encoding",
++ INVALID_CERT.getBytes(),
++ new CertificateParsingException()));
++ invalidTests.add(new GenMultiCertTest("Invalid PEM encoding",
++ INVALID_CERT.getBytes(),
++ new CertificateParsingException()));
++ invalidTests.add(new GenMultiCertTest(
++ "Two cert sequence, one valid and one invalid",
++ (INTERMED_CA_CERT + "\n" + INVALID_CERT).getBytes(),
++ new CertificateParsingException()));
++ invalidTests.add(new GenMultiCertTest("Non-certificate text",
++ "This is not a certificate".getBytes(),
++ new CertificateException()));
++ invalidTests.add(new GenMultiCertTest(
++ "Non-certificate text with partial PEM header (4 hyphens)",
++ "----This is not a valid x509 certificate".getBytes(),
++ new CertificateException()));
++ invalidTests.add(new GenMultiCertTest(
++ "Leading non-certificate text plus valid PEM header, " +
++ "but not on new line",
++ "This is not valid -----BEGIN CERTIFICATE-----".getBytes(),
++ new CertificateException()));
++ byte[] emptyCString = {0};
++ invalidTests.add(new GenMultiCertTest("Empty C-style string",
++ emptyCString, new CertificateException()));
++ invalidTests.add(new GenMultiCRLTest("Non-CRL text",
++ "This is not a CRL".getBytes(), new CRLException()));
++ invalidTests.add(new GenMultiCRLTest("Valid headers, but not a CRL",
++ INTERMED_CA_CERT.getBytes(), new CRLException()));
++
++ System.out.println("===== Valid Tests =====");
++ for (DecodeTest dt : validTests) {
++ dt.passTest();
+ }
+- throw new Exception("CertificateFactory.generateCertificate() did not "
+- + "throw CertificateParsingException on invalid X.509 cert data");
++ System.out.print("\n");
++
++ System.out.println("===== Invalid Tests =====");
++ for (DecodeTest dt : invalidTests) {
++ dt.failTest();
++ }
++ }
++
++ public static abstract class DecodeTest {
++ protected String testName;
++ protected byte[] testData;
++ protected Throwable expectedException;
++ protected X500Principal[] principals;
++ protected CertificateFactory cf;
++
++ /**
++ * Construct a DecodeTest
++ *
++ * @param name The test name
++ * @param input A byte array consisting of the input for this test
++ * @param failType An exception whose class should match the expected
++ * exception that will be thrown when this test is run
++ * @param princs Zero of more X500Principals which will be used
++ * to compare the output in a success case.
++ */
++ DecodeTest(String name, byte[] input, Throwable failType,
++ X500Principal... princs) throws CertificateException {
++ testName = name;
++ testData = input.clone();
++ expectedException = failType;
++ principals = princs;
++ cf = CertificateFactory.getInstance("X.509");
++ }
++
++ public abstract void passTest() throws GeneralSecurityException;
++
++ public abstract void failTest() throws GeneralSecurityException;
++ }
++
++ public static class GenMultiCertTest extends DecodeTest {
++ public GenMultiCertTest(String name, byte[] input, Throwable failType,
++ X500Principal... princs) throws CertificateException {
++ super(name, input, failType, princs);
++ }
++
++ @Override
++ public void passTest() throws GeneralSecurityException {
++ Collection<? extends Certificate> certs;
++
++ System.out.println("generateCertificates(): " + testName);
++ certs = cf.generateCertificates(new ByteArrayInputStream(testData));
++
++ // Walk the certs Collection and do a comparison of subject names
++ int i = 0;
++ if (certs.size() == principals.length) {
++ for (Certificate crt : certs) {
++ X509Certificate xc = (X509Certificate)crt;
++ if (!xc.getSubjectX500Principal().equals(
++ principals[i])) {
++ throw new RuntimeException("Name mismatch: " +
++ "cert: " + xc.getSubjectX500Principal() +
++ ", expected: " + principals[i]);
++ }
++ i++;
++ }
++ } else {
++ throw new RuntimeException("Size mismatch: certs = " +
++ certs.size() + ", expected = " +
++ principals.length);
++ }
++ }
++
++ @Override
++ public void failTest() throws GeneralSecurityException {
++ Throwable caughtException = null;
++ Collection<? extends Certificate> certs = null;
++
++ System.out.println("generateCertificates(): " + testName);
++ if (expectedException == null) {
++ throw new RuntimeException("failTest requires non-null " +
++ "expectedException");
++ }
++
++ try {
++ certs =
++ cf.generateCertificates(new ByteArrayInputStream(testData));
++ } catch (CertificateException ce) {
++ caughtException = ce;
++ }
++
++ if (caughtException != null) {
++ // It has to be the right kind of exception though...
++ if (!caughtException.getClass().equals(
++ expectedException.getClass())) {
++ System.err.println("Unexpected exception thrown. " +
++ "Received: " + caughtException + ", Expected: " +
++ expectedException.getClass());
++ throw new RuntimeException(caughtException);
++ }
++ } else {
++ // For a failure test, we'd expect some kind of exception
++ // to be thrown.
++ throw new RuntimeException("Failed to catch expected " +
++ "exception " + expectedException.getClass());
++ }
++ }
++ }
++
++ public static class GenSingleCertTest extends DecodeTest {
++ public GenSingleCertTest(String name, byte[] input, Throwable failType,
++ X500Principal... princs) throws CertificateException {
++ super(name, input, failType, princs);
++ }
++
++ @Override
++ public void passTest() throws GeneralSecurityException {
++ X509Certificate cert;
++
++ System.out.println("generateCertificate(): " + testName);
++ cert = (X509Certificate)cf.generateCertificate(
++ new ByteArrayInputStream(testData));
++
++ // Compare the cert's subject name against the expected value
++ // provided in the test. If multiple X500Principals were provided
++ // just use the first one as the expected value.
++ if (!cert.getSubjectX500Principal().equals(principals[0])) {
++ throw new RuntimeException("Name mismatch: " +
++ "cert: " + cert.getSubjectX500Principal() +
++ ", expected: " + principals[0]);
++ }
++ }
++
++ @Override
++ public void failTest() throws GeneralSecurityException {
++ Throwable caughtException = null;
++ X509Certificate cert = null;
++ System.out.println("generateCertificate(): " + testName);
++
++ if (expectedException == null) {
++ throw new RuntimeException("failTest requires non-null " +
++ "expectedException");
++ }
++
++ try {
++ cert = (X509Certificate)cf.generateCertificate(
++ new ByteArrayInputStream(testData));
++ } catch (CertificateException e) {
++ caughtException = e;
++ }
++
++ if (caughtException != null) {
++ // It has to be the right kind of exception though...
++ if (!caughtException.getClass().equals(
++ expectedException.getClass())) {
++ System.err.println("Unexpected exception thrown. " +
++ "Received: " + caughtException + ", Expected: " +
++ expectedException.getClass());
++ throw new RuntimeException(caughtException);
++ }
++ } else {
++ // For a failure test, we'd expect some kind of exception
++ // to be thrown.
++ throw new RuntimeException("Failed to catch expected " +
++ "exception " + expectedException.getClass());
++ }
++ }
++ }
++
++ public static class GenMultiCRLTest extends DecodeTest {
++ public GenMultiCRLTest(String name, byte[] input, Throwable failType,
++ X500Principal... princs) throws CertificateException {
++ super(name, input, failType, princs);
++ }
++
++ @Override
++ public void passTest() throws GeneralSecurityException {
++ Collection<? extends CRL> crls;
++
++ System.out.println("generateCRLs(): " + testName);
++ crls = cf.generateCRLs(new ByteArrayInputStream(testData));
++
++ // Walk the crls Collection and do a comparison of issuer names
++ int i = 0;
++ if (crls.size() == principals.length) {
++ for (CRL revlist : crls) {
++ X509CRL xc = (X509CRL)revlist;
++ if (!xc.getIssuerX500Principal().equals(principals[i])) {
++ throw new RuntimeException("Name mismatch: " +
++ "CRL: " + xc.getIssuerX500Principal() +
++ ", expected: " + principals[i]);
++ }
++ i++;
++ }
++ } else {
++ throw new RuntimeException("Size mismatch: crls = " +
++ crls.size() + ", expected = " +
++ principals.length);
++ }
++ }
++
++ @Override
++ public void failTest() throws GeneralSecurityException {
++ Throwable caughtException = null;
++ Collection<? extends CRL> crls = null;
++
++ System.out.println("generateCRLs(): " + testName);
++ if (expectedException == null) {
++ throw new RuntimeException("failTest requires non-null " +
++ "expectedException");
++ }
++
++ try {
++ crls =
++ cf.generateCRLs(new ByteArrayInputStream(testData));
++ } catch (CRLException e) {
++ caughtException = e;
++ }
++
++ if (caughtException != null) {
++ // It has to be the right kind of exception though...
++ if (!caughtException.getClass().equals(
++ expectedException.getClass())) {
++ System.err.println("Unexpected exception thrown. " +
++ "Received: " + caughtException + ", Expected: " +
++ expectedException.getClass());
++ throw new RuntimeException(caughtException);
++ }
++ } else {
++ // For a failure test, we'd expect some kind of exception
++ // to be thrown.
++ throw new RuntimeException("Failed to catch expected " +
++ "exception " + expectedException.getClass());
++ }
++ }
+ }
+ }
+--- ./jdk/test/java/security/cert/CertificateFactory/invalidEncodedCerts/invalidcert.pem Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,14 +0,0 @@
+------BEGIN CERTIFICATE-----
+-XIICJjCCAdCgAwIBAgIBITANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCVVMx
+-EzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xFTAT
+-BgNVBAoTDEJFQSBXZWJMb2dpYzERMA8GA1UECxMIU2VjdXJpdHkxIzAhBgNVBAMT
+-GkRlbW8gQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9zdXBw
+-b3J0QGJlYS5jb20wHhcNMDAwNTMwMjEzODAxWhcNMDQwNTEzMjEzODAxWjCBjDEL
+-MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG
+-cmFuY2lzY28xFTATBgNVBAoTDEJFQSBXZWJMb2dpYzEZMBcGA1UEAxMQd2VibG9n
+-aWMuYmVhLmNvbTEeMBwGCSqGSIb3DQEJARYPc3VwcG9ydEBiZWEuY29tMFwwDQYJ
+-KoZIhvcNAQEBBQADSwAwSAJBALdsXEHqKHgs6zj0hU5sXMAUHzoT8kgWXmNkKHXH
+-79qbPh6EfdlriW9G/AbRF/pKrCQu7hhllAxREbqTuSlf2EMCAwEAATANBgkqhkiG
+-9w0BAQQFAANBACgmqflL5m5LNeJGpWx9aIoABCiuDcpw1fFyegsqGX7CBhffcruS
+-1p8h5vkHVbMu1frD1UgGnPlOO/K7Ig/KrsU=
+------END CERTIFICATE-----
+--- ./jdk/test/java/text/Format/DecimalFormat/TieRoundingTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/text/Format/DecimalFormat/TieRoundingTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -23,7 +23,7 @@
+
+ /* @test
+ *
+- * @bug 7131459
++ * @bug 7131459 8039915
+ * @summary test various situations of NumberFormat rounding when close to tie
+ * @author Olivier Lagneau
+ * @run main TieRoundingTest
+@@ -56,7 +56,7 @@
+ if (!result.equals(expectedOutput)) {
+ System.out.println();
+ System.out.println("========================================");
+- System.out.println("***Error formatting double value from string : " +
++ System.out.println("***Failure : error formatting value from string : " +
+ inputDigits);
+ System.out.println("NumberFormat pattern is : " +
+ ((DecimalFormat ) nf).toPattern());
+@@ -103,7 +103,7 @@
+ if (!result.equals(expectedOutput)) {
+ System.out.println();
+ System.out.println("========================================");
+- System.out.println("***Error formatting double value from string : " +
++ System.out.println("***Failure : error formatting value from string : " +
+ inputDigits);
+ System.out.println("NumberFormat pattern is : " +
+ ((DecimalFormat ) nf).toPattern());
+@@ -144,7 +144,7 @@
+ if (!result.equals(expectedOutput)) {
+ System.out.println();
+ System.out.println("========================================");
+- System.out.println("***Error formatting number value from string : " +
++ System.out.println("***Failure : error formatting value from string : " +
+ inputDigits);
+ System.out.println("NumberFormat pattern is : " +
+ ((DecimalFormat ) nf).toPattern());
+@@ -174,7 +174,7 @@
+
+ public static void main(String[] args) {
+
+- // Only the 3 rounding modes below may be impacted by bug 7131459.
++ // The 3 HALF_* rounding modes are impacted by bugs 7131459, 8039915.
+ // So we do not test the other rounding modes.
+ RoundingMode[] roundingModes = {
+ RoundingMode.HALF_DOWN,
+@@ -183,10 +183,14 @@
+ };
+
+ // Precise the relative position of input value against its closest tie.
++ // The double values tested below for 3 and 5 fractional digits must follow
++ // this scheme (position toward tie).
+ String[] tieRelativePositions = {
+ "below", "exact", "above",
+ "below", "exact", "above",
+ "below", "exact", "above",
++ "below", "above", "above",
++ "below", "below", "above",
+ "below", "exact", "above"
+ };
+
+@@ -196,9 +200,13 @@
+ double[] values3FractDigits = {
+ // unimpacting values close to tie, with less than 3 input fract digits
+ 1.115d, 1.125d, 1.135d,
+- // impacting close to tie values covering all 6 cases
++ // HALF_* impacting close to tie values covering all 6 tie cases
+ 0.3115d, 0.3125d, 0.3135d,
+ 0.6865d, 0.6875d, 0.6885d,
++ // specific HALF_UP close to tie values
++ 0.3124d, 0.3126d, 0.3128d,
++ // specific HALF_DOWN close to tie values
++ 0.6864d, 0.6865d, 0.6868d,
+ // unimpacting values close to tie, with more than 3 input fract digits
+ 1.46885d, 2.46875d, 1.46865d
+ };
+@@ -207,6 +215,8 @@
+ "1.115d", "1.125d", "1.135d",
+ "0.3115d", "0.3125d", "0.3135d",
+ "0.6865d", "0.6875d", "0.6885d",
++ "0.3124d", "0.3126d", "0.3128d",
++ "0.6864d", "0.6865d", "0.6868d",
+ "1.46885d", "2.46875d", "1.46865d"
+ };
+
+@@ -214,16 +224,22 @@
+ {"1.115", "1.125", "1.135",
+ "0.311", "0.312", "0.314",
+ "0.686", "0.687", "0.689",
++ "0.312", "0.313", "0.313",
++ "0.686", "0.686", "0.687",
+ "1.469", "2.469", "1.469"
+ },
+ {"1.115", "1.125", "1.135",
+ "0.311", "0.312", "0.314",
+ "0.686", "0.688", "0.689",
++ "0.312", "0.313", "0.313",
++ "0.686", "0.686", "0.687",
+ "1.469", "2.469", "1.469"
+ },
+ {"1.115", "1.125", "1.135",
+ "0.311", "0.313", "0.314",
+ "0.686", "0.688", "0.689",
++ "0.312", "0.313", "0.313",
++ "0.686", "0.686", "0.687",
+ "1.469", "2.469", "1.469"
+ },
+ };
+@@ -250,9 +266,13 @@
+ double[] values5FractDigits = {
+ // unimpacting values close to tie, with less than 5 input fract digits
+ 1.3135d, 1.3125d, 1.3115d,
+- // impacting values close to tie, covering all 6 cases
++ // HALF_* impacting values close to tie, covering all 6 cases
+ 1.328115d, 1.328125d, 1.328135d,
+ 1.796865d, 1.796875d, 1.796885d,
++ // specific HALF_UP close to tie values
++ 1.328124d, 1.798876d, 1.796889d,
++ // specific HALF_DOWN close to tie values
++ 1.328114d, 1.796865d, 1.328138d,
+ // unimpacting values close to tie, with more than 5 input fract digits
+ 1.3281149999999d, 1.75390625d, 1.7968750000001d
+ };
+@@ -261,6 +281,8 @@
+ "1.3135d", "1.3125d", "1.3115d",
+ "1.328115d", "1.328125d", "1.328135d",
+ "1.796865d", "1.796875d", "1.796885d",
++ "1.328124d", "1.798876d", "1.796889d",
++ "1.328114d", "1.796865d", "1.328138d",
+ "1.3281149999999d", "1.75390625d", "1.7968750000001d"
+ };
+
+@@ -268,16 +290,22 @@
+ {"1.3135", "1.3125", "1.3115",
+ "1.32811", "1.32812", "1.32814",
+ "1.79686", "1.79687", "1.79689",
++ "1.32812", "1.79888", "1.79689",
++ "1.32811", "1.79686", "1.32814",
+ "1.32811", "1.75391", "1.79688"
+ },
+ {"1.3135", "1.3125", "1.3115",
+ "1.32811", "1.32812", "1.32814",
+ "1.79686", "1.79688", "1.79689",
++ "1.32812", "1.79888", "1.79689",
++ "1.32811", "1.79686", "1.32814",
+ "1.32811", "1.75391", "1.79688"
+ },
+ {"1.3135", "1.3125", "1.3115",
+ "1.32811", "1.32813", "1.32814",
+ "1.79686", "1.79688", "1.79689",
++ "1.32812", "1.79888", "1.79689",
++ "1.32811", "1.79686", "1.32814",
+ "1.32811", "1.75391", "1.79688"
+ }
+ };
+--- ./jdk/test/java/util/BitSet/BSMethods.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/util/BitSet/BSMethods.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -23,9 +23,10 @@
+
+ /* @test
+ * @bug 4098239 4107540 4080736 4261102 4274710 4305272
+- * 4979017 4979028 4979031 5030267 6222207
++ * 4979017 4979028 4979031 5030267 6222207 8040806
+ * @summary Test the operation of the methods of BitSet class
+ * @author Mike McCloskey, Martin Buchholz
++ * @run main/othervm BSMethods
+ */
+
+ import java.util.*;
+@@ -897,6 +898,21 @@
+ private static void testToString() {
+ check(new BitSet().toString().equals("{}"));
+ check(makeSet(2,3,42,43,234).toString().equals("{2, 3, 42, 43, 234}"));
++
++ final long MB = 1024*1024;
++ if (Runtime.getRuntime().maxMemory() >= 512*MB) {
++ // only run it if we have enough memory
++ try {
++ check(makeSet(Integer.MAX_VALUE-1).toString().equals(
++ "{" + (Integer.MAX_VALUE-1) + "}"));
++ check(makeSet(Integer.MAX_VALUE).toString().equals(
++ "{" + Integer.MAX_VALUE + "}"));
++ check(makeSet(0, 1, Integer.MAX_VALUE-1, Integer.MAX_VALUE).toString().equals(
++ "{0, 1, " + (Integer.MAX_VALUE-1) + ", " + Integer.MAX_VALUE + "}"));
++ } catch (IndexOutOfBoundsException exc) {
++ fail("toString() with indices near MAX_VALUE");
++ }
++ }
+ }
+
+ private static void testLogicalIdentities() {
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/util/Collections/SyncSubMutexes.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,270 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8048209
++ * @summary Check that Collections.synchronizedNavigableSet().tailSet() is using
++ * the same lock object as it's source.
++ * @run testng SyncSubMutexes
++ */
++import java.lang.reflect.Field;
++import java.util.*;
++import java.util.Set;
++import java.util.Arrays;
++
++import org.testng.annotations.Test;
++import org.testng.annotations.DataProvider;
++import static org.testng.Assert.assertSame;
++
++public class SyncSubMutexes {
++
++ @Test(dataProvider = "Collections")
++ public void testCollections(Collection<String> instance) {
++ // nothing to test, no subset methods
++ }
++
++ @Test(dataProvider = "Lists")
++ public void testLists(List<String> instance) {
++ assertSame(getSyncCollectionMutex(instance.subList(0, 1)), getSyncCollectionMutex(instance));
++ }
++
++ @Test(dataProvider = "Sets")
++ public void testSets(Set<String> instance) {
++ // nothing to test, no subset methods
++
++ }
++
++ @Test(dataProvider = "SortedSets")
++ public void testSortedSets(SortedSet<String> instance) {
++ assertSame(getSyncCollectionMutex(instance.headSet("Echo")), getSyncCollectionMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.tailSet("Charlie")), getSyncCollectionMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.subSet("Charlie", "Echo")), getSyncCollectionMutex(instance));
++
++ }
++
++ @Test(dataProvider = "NavigableSets")
++ public void testNavigableSets(NavigableSet<String> instance) {
++ assertSame(getSyncCollectionMutex(instance.descendingSet()), getSyncCollectionMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.headSet("Echo")), getSyncCollectionMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.headSet("Echo", true)), getSyncCollectionMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.tailSet("Charlie")), getSyncCollectionMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.tailSet("Charlie", true)), getSyncCollectionMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.subSet("Charlie", "Echo")), getSyncCollectionMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.subSet("Charlie", true, "Echo", true)), getSyncCollectionMutex(instance));
++ }
++
++ @Test(dataProvider = "Maps")
++ public void testMaps(Map<String, String> instance) {
++ assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
++ }
++
++ @Test(dataProvider = "SortedMaps")
++ public void testSortedMaps(SortedMap<String, String> instance) {
++ assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
++ assertSame(getSyncMapMutex(instance.headMap("Echo")), getSyncMapMutex(instance));
++ assertSame(getSyncMapMutex(instance.tailMap("Charlie")), getSyncMapMutex(instance));
++ assertSame(getSyncMapMutex(instance.subMap("Charlie", "Echo")), getSyncMapMutex(instance));
++ }
++
++ @Test(dataProvider = "NavigableMaps")
++ public void testNavigableMaps(NavigableMap<String, String> instance) {
++ assertSame(getSyncMapMutex(instance.descendingMap()), getSyncMapMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.descendingKeySet()), getSyncMapMutex(instance));
++ assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
++ assertSame(getSyncMapMutex(instance.headMap("Echo")), getSyncMapMutex(instance));
++ assertSame(getSyncMapMutex(instance.headMap("Echo", true)), getSyncMapMutex(instance));
++ assertSame(getSyncMapMutex(instance.tailMap("Charlie")), getSyncMapMutex(instance));
++ assertSame(getSyncMapMutex(instance.tailMap("Charlie", true)), getSyncMapMutex(instance));
++ assertSame(getSyncMapMutex(instance.subMap("Charlie", true, "Echo", true)), getSyncMapMutex(instance));
++ assertSame(getSyncMapMutex(instance.subMap("Charlie", true, "Echo", true)), getSyncMapMutex(instance));
++ }
++
++ @DataProvider(name = "Collections", parallel = true)
++ public static Iterator<Object[]> collectionProvider() {
++ return makeCollections().iterator();
++ }
++
++ @DataProvider(name = "Lists", parallel = true)
++ public static Iterator<Object[]> listProvider() {
++ return makeLists().iterator();
++ }
++
++ @DataProvider(name = "Sets", parallel = true)
++ public static Iterator<Object[]> setProvider() {
++ return makeSets().iterator();
++ }
++
++ @DataProvider(name = "SortedSets", parallel = true)
++ public static Iterator<Object[]> sortedsetProvider() {
++ return makeSortedSets().iterator();
++ }
++
++ @DataProvider(name = "NavigableSets", parallel = true)
++ public static Iterator<Object[]> navigablesetProvider() {
++ return makeNavigableSets().iterator();
++ }
++
++ @DataProvider(name = "Maps", parallel = true)
++ public static Iterator<Object[]> mapProvider() {
++ return makeMaps().iterator();
++ }
++
++ @DataProvider(name = "SortedMaps", parallel = true)
++ public static Iterator<Object[]> sortedmapProvider() {
++ return makeSortedMaps().iterator();
++ }
++
++ @DataProvider(name = "NavigableMaps", parallel = true)
++ public static Iterator<Object[]> navigablemapProvider() {
++ return makeNavigableMaps().iterator();
++ }
++
++ private static final Collection<String> BASE_COLLECTION = Collections.unmodifiableCollection(
++ Arrays.asList("Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf")
++ );
++ private static final Map<String, String> BASE_MAP;
++
++ static {
++ Map<String, String> map = new HashMap<>();
++ for(String each : BASE_COLLECTION) {
++ map.put(each, "*" + each + "*");
++ }
++ BASE_MAP = Collections.unmodifiableMap(map);
++ }
++
++ public static Collection<Object[]> makeCollections() {
++ Collection<Object[]> instances = new ArrayList<>();
++ instances.add(new Object[] {Collections.synchronizedCollection(new ArrayList<>(BASE_COLLECTION))});
++ instances.addAll(makeLists());
++
++ return instances;
++ }
++
++ public static Collection<Object[]> makeLists() {
++ Collection<Object[]> instances = new ArrayList<>();
++ instances.add(new Object[] {Collections.synchronizedList(new ArrayList<>(BASE_COLLECTION))});
++ instances.add(new Object[] {Collections.synchronizedList(new ArrayList<>(BASE_COLLECTION)).subList(1, 2)});
++
++ return instances;
++ }
++
++ public static Collection<Object[]> makeSets() {
++ Collection<Object[]> instances = new ArrayList<>();
++
++ instances.add(new Object[] {Collections.synchronizedSet(new TreeSet<>(BASE_COLLECTION))});
++ instances.addAll(makeSortedSets());
++ return instances;
++ }
++
++ public static Collection<Object[]> makeSortedSets() {
++ Collection<Object[]> instances = new ArrayList<>();
++ instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION))});
++ instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot")});
++ instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo")});
++ instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo", "Foxtrot")});
++ instances.addAll(makeNavigableSets());
++
++ return instances;
++ }
++
++ public static Collection<Object[]> makeNavigableSets() {
++ Collection<Object[]> instances = new ArrayList<>();
++
++ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION))});
++ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).descendingSet().descendingSet()});
++ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot")});
++ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot", true)});
++ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo")});
++ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo", true)});
++ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo", "Foxtrot")});
++ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo", true, "Foxtrot", true)});
++
++ return instances;
++ }
++
++ public static Collection<Object[]> makeMaps() {
++ Collection<Object[]> instances = new ArrayList<>();
++
++ instances.add(new Object[] {Collections.synchronizedMap(new HashMap<>(BASE_MAP))});
++ instances.addAll(makeSortedMaps());
++
++ return instances;
++ }
++
++ public static Collection<Object[]> makeSortedMaps() {
++ Collection<Object[]> instances = new ArrayList<>();
++
++ instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP))});
++ instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot")});
++ instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo")});
++ instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).subMap("Bravo", "Foxtrot")});
++ instances.addAll(makeNavigableMaps());
++
++ return instances;
++ }
++
++ public static Collection<Object[]> makeNavigableMaps() {
++ Collection<Object[]> instances = new ArrayList<>();
++
++ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP))});
++ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP).descendingMap().descendingMap())});
++ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot")});
++ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot", true)});
++ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo")});
++ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo", true)});
++ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).subMap("Bravo", "Foxtrot")});
++ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).subMap("Bravo", true, "Foxtrot", true)});
++
++ return instances;
++ }
++
++ private static Object getSyncCollectionMutex(Collection<?> from) {
++ try {
++ Class<?> synchronizedCollectionClazz = Class.forName("java.util.Collections$SynchronizedCollection");
++ Field f = synchronizedCollectionClazz.getDeclaredField("mutex");
++ f.setAccessible(true);
++ return f.get(from);
++ } catch ( ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
++ throw new RuntimeException("Unable to get mutex field.", e);
++ }
++ }
++
++ private static Object getSyncMapMutex(Map<?,?> from) {
++ try {
++ Class<?> synchronizedMapClazz = Class.forName("java.util.Collections$SynchronizedMap");
++ Field f = synchronizedMapClazz.getDeclaredField("mutex");
++ f.setAccessible(true);
++ return f.get(from);
++ } catch ( ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
++ throw new RuntimeException("Unable to get mutex field.", e);
++ }
++ }
++
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/util/IdentityHashMap/Capacity.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,226 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.lang.reflect.Field;
++import java.util.ArrayList;
++import java.util.Collections;
++import java.util.IdentityHashMap;
++import java.util.List;
++import java.util.Random;
++
++import org.testng.annotations.DataProvider;
++import org.testng.annotations.Test;
++
++import static org.testng.Assert.*;
++
++/*
++ * @test
++ * @bug 6904367
++ * @summary IdentityHashMap reallocates storage when inserting expected
++ * number of elements
++ * @run testng Capacity
++ */
++
++@Test
++public class Capacity {
++ static final Field tableField;
++ static final Random random = new Random();
++ static final Object[][] sizesData;
++
++ @DataProvider(name="sizes", parallel = true)
++ public Object[][] sizesToTest() { return sizesData; }
++
++ static {
++ try {
++ tableField = IdentityHashMap.class.getDeclaredField("table");
++ tableField.setAccessible(true);
++ } catch (NoSuchFieldException e) {
++ throw new LinkageError("table", e);
++ }
++
++ ArrayList<Object[]> sizes = new ArrayList<>();
++ for (int size = 0; size < 200; size++)
++ sizes.add(new Object[] { size });
++
++ // some numbers known to demonstrate bug 6904367
++ for (int size : new int[] {682, 683, 1365, 2730, 2731, 5461})
++ sizes.add(new Object[] { size });
++
++ // a few more random sizes to try
++ for (int i = 0; i != 128; i++)
++ sizes.add(new Object[] { random.nextInt(5000) });
++
++ sizesData = sizes.toArray(new Object[0][]);
++ }
++
++ static int capacity(IdentityHashMap<?,?> map) {
++ try {
++ return ((Object[]) tableField.get(map)).length / 2;
++ } catch (Throwable t) {
++ throw new LinkageError("table", t);
++ }
++ }
++
++ static void assertCapacity(IdentityHashMap<?,?> map,
++ int expectedCapacity) {
++ assertEquals(capacity(map), expectedCapacity);
++ }
++
++ static void growUsingPut(IdentityHashMap<Object,Object> map,
++ int elementsToAdd) {
++ for (int i = 0; i < elementsToAdd; i++)
++ map.put(new Object(), new Object());
++ }
++
++ static void growUsingPutAll(IdentityHashMap<Object,Object> map,
++ int elementsToAdd) {
++ IdentityHashMap<Object,Object> other = new IdentityHashMap<>();
++ growUsingPut(other, elementsToAdd);
++ map.putAll(other);
++ }
++
++ static void growUsingRepeatedPutAll(IdentityHashMap<Object,Object> map,
++ int elementsToAdd) {
++ for (int i = 0; i < elementsToAdd; i++)
++ map.putAll(Collections.singletonMap(new Object(),
++ new Object()));
++ }
++
++ /**
++ * Checks that expected number of items can be inserted into
++ * the map without resizing of the internal storage
++ */
++ @Test(dataProvider = "sizes")
++ public void canInsertExpectedItemsWithoutResizing(int size)
++ throws Throwable {
++ // First try growing using put()
++ IdentityHashMap<Object,Object> m = new IdentityHashMap<>(size);
++ int initialCapacity = capacity(m);
++ growUsingPut(m, size);
++ assertCapacity(m, initialCapacity);
++
++ // Doubling from the expected size will cause exactly one
++ // resize, except near minimum capacity.
++ if (size > 1) {
++ growUsingPut(m, size);
++ assertCapacity(m, 2 * initialCapacity);
++ }
++
++ // Try again, growing with putAll()
++ m = new IdentityHashMap<>(size);
++ initialCapacity = capacity(m);
++ growUsingPutAll(m, size);
++ assertCapacity(m, initialCapacity);
++
++ // Doubling from the expected size will cause exactly one
++ // resize, except near minimum capacity.
++ if (size > 1) {
++ growUsingPutAll(m, size);
++ assertCapacity(m, 2 * initialCapacity);
++ }
++ }
++
++ /**
++ * Given the expected size, computes such a number N of items that
++ * inserting (N+1) items will trigger resizing of the internal storage
++ */
++ static int threshold(int size) throws Throwable {
++ IdentityHashMap<Object,Object> m = new IdentityHashMap<>(size);
++ int initialCapacity = capacity(m);
++ while (capacity(m) == initialCapacity)
++ growUsingPut(m, 1);
++ return m.size() - 1;
++ }
++
++ /**
++ * Checks that inserting (threshold+1) item causes resizing
++ * of the internal storage
++ */
++ @Test(dataProvider = "sizes")
++ public void passingThresholdCausesResize(int size) throws Throwable {
++ final int threshold = threshold(size);
++ IdentityHashMap<Object,Object> m = new IdentityHashMap<>(threshold);
++ int initialCapacity = capacity(m);
++
++ growUsingPut(m, threshold);
++ assertCapacity(m, initialCapacity);
++
++ growUsingPut(m, 1);
++ assertCapacity(m, 2 * initialCapacity);
++ }
++
++ /**
++ * Checks that 4 methods of requiring capacity lead to the same
++ * internal capacity, unless sized below default capacity.
++ */
++ @Test(dataProvider = "sizes")
++ public void differentGrowthPatternsResultInSameCapacity(int size)
++ throws Throwable {
++ if (size < 21) // 21 is default maxExpectedSize
++ return;
++
++ IdentityHashMap<Object,Object> m;
++ m = new IdentityHashMap<Object,Object>(size);
++ int capacity1 = capacity(m);
++
++ m = new IdentityHashMap<>();
++ growUsingPut(m, size);
++ int capacity2 = capacity(m);
++
++ m = new IdentityHashMap<>();
++ growUsingPutAll(m, size);
++ int capacity3 = capacity(m);
++
++ m = new IdentityHashMap<>();
++ growUsingRepeatedPutAll(m, size);
++ int capacity4 = capacity(m);
++
++ if (capacity1 != capacity2 ||
++ capacity2 != capacity3 ||
++ capacity3 != capacity4)
++ throw new AssertionError("Capacities not equal: "
++ + capacity1 + " "
++ + capacity2 + " "
++ + capacity3 + " "
++ + capacity4);
++ }
++
++ public void defaultExpectedMaxSizeIs21() {
++ assertCapacity(new IdentityHashMap<Long,Long>(), 32);
++ assertCapacity(new IdentityHashMap<Long,Long>(21), 32);
++ }
++
++ public void minimumCapacityIs4() {
++ assertCapacity(new IdentityHashMap<Long,Long>(0), 4);
++ assertCapacity(new IdentityHashMap<Long,Long>(1), 4);
++ assertCapacity(new IdentityHashMap<Long,Long>(2), 4);
++ assertCapacity(new IdentityHashMap<Long,Long>(3), 8);
++ }
++
++ @Test(enabled = false)
++ /** needs too much memory to run normally */
++ public void maximumCapacityIs2ToThe29() {
++ assertCapacity(new IdentityHashMap<Long,Long>(Integer.MAX_VALUE),
++ 1 << 29);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/util/logging/CheckZombieLockTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,376 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8048020
++ * @author Daniel Fuchs
++ * @summary Regression on java.util.logging.FileHandler.
++ * The fix is to avoid filling up the file system with zombie lock files.
++ *
++ * @run main/othervm CheckZombieLockTest WRITABLE CLOSE CLEANUP
++ * @run main/othervm CheckZombieLockTest CLEANUP
++ * @run main/othervm CheckZombieLockTest WRITABLE
++ * @run main/othervm CheckZombieLockTest CREATE_FIRST
++ * @run main/othervm CheckZombieLockTest CREATE_NEXT
++ * @run main/othervm CheckZombieLockTest CREATE_NEXT
++ * @run main/othervm CheckZombieLockTest CLEANUP
++ * @run main/othervm CheckZombieLockTest REUSE
++ * @run main/othervm CheckZombieLockTest CLEANUP
++ */
++import java.io.File;
++import java.io.IOException;
++import java.nio.channels.FileChannel;
++import java.nio.file.Paths;
++import java.nio.file.StandardOpenOption;
++import java.util.ArrayList;
++import java.util.List;
++import java.util.UUID;
++import java.util.logging.FileHandler;
++import java.util.logging.Level;
++import java.util.logging.LogRecord;
++public class CheckZombieLockTest {
++
++ private static final String WRITABLE_DIR = "writable-lockfile-dir";
++ private static volatile boolean supportsLocking = true;
++
++ static enum TestCase {
++ WRITABLE, // just verifies that we can create a file in our 'writable-lockfile-dir'
++ CLOSE, // checks that closing a FileHandler removes its lock file
++ CREATE_FIRST, // verifies that 'writable-lockfile-dir' contains no lock, then creates a first FileHandler.
++ CREATE_NEXT, // verifies that 'writable-lockfile-dir' contains a single lock, then creates the next FileHandler
++ REUSE, // verifies that zombie lock files can be reused
++ CLEANUP // removes "writable-lockfile-dir"
++ };
++
++ public static void main(String... args) throws IOException {
++ // we'll base all file creation attempts on the system temp directory,
++ // %t
++ File writableDir = setup();
++ System.out.println("Writable dir is: " + writableDir.getAbsolutePath());
++ // we now have one writable directory to work with:
++ // writableDir
++ if (args == null || args.length == 0) {
++ args = new String[] { "WRITABLE", "CLOSE", "CLEANUP" };
++ }
++ try {
++ runTests(writableDir, args);
++ } catch (RuntimeException | IOException | Error x) {
++ // some error occured: cleanup
++ delete(writableDir);
++ throw x;
++ }
++ }
++
++ /**
++ * @param writableDir in which log and lock file are created
++ * @throws SecurityException
++ * @throws RuntimeException
++ * @throws IOException
++ */
++ private static void runTests(File writableDir, String... args) throws SecurityException,
++ RuntimeException, IOException {
++ for (String arg : args) {
++ switch(TestCase.valueOf(arg)) {
++ // Test 1: makes sure we can create FileHandler in writable directory
++ case WRITABLE: checkWritable(writableDir); break;
++ // Test 2: verifies that FileHandler.close() cleans up its lock file
++ case CLOSE: testFileHandlerClose(writableDir); break;
++ // Test 3: creates the first file handler
++ case CREATE_FIRST: testFileHandlerCreate(writableDir, true); break;
++ // Test 4, 5, ... creates the next file handler
++ case CREATE_NEXT: testFileHandlerCreate(writableDir, false); break;
++ // Checks that zombie lock files are reused appropriatly
++ case REUSE: testFileHandlerReuse(writableDir); break;
++ // Removes the writableDir
++ case CLEANUP: delete(writableDir); break;
++ default: throw new RuntimeException("No such test case: " + arg);
++ }
++ }
++ }
++
++ /**
++ * @param writableDir in which log and lock file are created
++ * @throws SecurityException
++ * @throws RuntimeException
++ * @throws IOException
++ */
++ private static void checkWritable(File writableDir) throws SecurityException,
++ RuntimeException, IOException {
++ // Test 1: make sure we can create/delete files in the writable dir.
++ final File file = new File(writableDir, "test.txt");
++ if (!createFile(file, false)) {
++ throw new IOException("Can't create " + file + "\n\tUnable to run test");
++ } else {
++ delete(file);
++ }
++ }
++
++
++ private static FileHandler createFileHandler(File writableDir) throws SecurityException,
++ RuntimeException, IOException {
++ // Test 1: make sure we can create FileHandler in writable directory
++ try {
++ FileHandler handler = new FileHandler("%t/" + WRITABLE_DIR + "/log.log");
++ handler.publish(new LogRecord(Level.INFO, handler.toString()));
++ handler.flush();
++ return handler;
++ } catch (IOException ex) {
++ throw new RuntimeException("Test failed: should have been able"
++ + " to create FileHandler for " + "%t/" + WRITABLE_DIR
++ + "/log.log in writable directory.", ex);
++ }
++ }
++
++ private static List<File> listLocks(File writableDir, boolean print)
++ throws IOException {
++ List<File> locks = new ArrayList<>();
++ for (File f : writableDir.listFiles()) {
++ if (print) {
++ System.out.println("Found file: " + f.getName());
++ }
++ if (f.getName().endsWith(".lck")) {
++ locks.add(f);
++ }
++ }
++ return locks;
++ }
++
++ private static void testFileHandlerClose(File writableDir) throws IOException {
++ File fakeLock = new File(writableDir, "log.log.lck");
++ if (!createFile(fakeLock, false)) {
++ throw new IOException("Can't create fake lock file: " + fakeLock);
++ }
++ try {
++ List<File> before = listLocks(writableDir, true);
++ System.out.println("before: " + before.size() + " locks found");
++ FileHandler handler = createFileHandler(writableDir);
++ System.out.println("handler created: " + handler);
++ List<File> after = listLocks(writableDir, true);
++ System.out.println("after creating handler: " + after.size() + " locks found");
++ handler.close();
++ System.out.println("handler closed: " + handler);
++ List<File> afterClose = listLocks(writableDir, true);
++ System.out.println("after closing handler: " + afterClose.size() + " locks found");
++ afterClose.removeAll(before);
++ if (!afterClose.isEmpty()) {
++ throw new RuntimeException("Zombie lock file detected: " + afterClose);
++ }
++ } finally {
++ if (fakeLock.canRead()) delete(fakeLock);
++ }
++ List<File> finalLocks = listLocks(writableDir, false);
++ System.out.println("After cleanup: " + finalLocks.size() + " locks found");
++ }
++
++
++ private static void testFileHandlerReuse(File writableDir) throws IOException {
++ List<File> before = listLocks(writableDir, true);
++ System.out.println("before: " + before.size() + " locks found");
++ try {
++ if (!before.isEmpty()) {
++ throw new RuntimeException("Expected no lock file! Found: " + before);
++ }
++ } finally {
++ before.stream().forEach(CheckZombieLockTest::delete);
++ }
++
++ FileHandler handler1 = createFileHandler(writableDir);
++ System.out.println("handler created: " + handler1);
++ List<File> after = listLocks(writableDir, true);
++ System.out.println("after creating handler: " + after.size() + " locks found");
++ if (after.size() != 1) {
++ throw new RuntimeException("Unexpected number of lock files found for "
++ + handler1 + ": " + after);
++ }
++ final File lock = after.get(0);
++ after.clear();
++ handler1.close();
++ after = listLocks(writableDir, true);
++ System.out.println("after closing handler: " + after.size() + " locks found");
++ if (!after.isEmpty()) {
++ throw new RuntimeException("Unexpected number of lock files found for "
++ + handler1 + ": " + after);
++ }
++ if (!createFile(lock, false)) {
++ throw new IOException("Can't create fake lock file: " + lock);
++ }
++ try {
++ before = listLocks(writableDir, true);
++ System.out.println("before: " + before.size() + " locks found");
++ if (before.size() != 1) {
++ throw new RuntimeException("Unexpected number of lock files found: "
++ + before + " expected [" + lock + "].");
++ }
++ FileHandler handler2 = createFileHandler(writableDir);
++ System.out.println("handler created: " + handler2);
++ after = listLocks(writableDir, true);
++ System.out.println("after creating handler: " + after.size() + " locks found");
++ after.removeAll(before);
++ if (!after.isEmpty()) {
++ throw new RuntimeException("Unexpected lock file found: " + after
++ + "\n\t" + lock + " should have been reused");
++ }
++ handler2.close();
++ System.out.println("handler closed: " + handler2);
++ List<File> afterClose = listLocks(writableDir, true);
++ System.out.println("after closing handler: " + afterClose.size() + " locks found");
++ if (!afterClose.isEmpty()) {
++ throw new RuntimeException("Zombie lock file detected: " + afterClose);
++ }
++
++ if (supportsLocking) {
++ FileChannel fc = FileChannel.open(Paths.get(lock.getAbsolutePath()),
++ StandardOpenOption.CREATE_NEW, StandardOpenOption.APPEND,
++ StandardOpenOption.WRITE);
++ try {
++ if (fc.tryLock() != null) {
++ System.out.println("locked: " + lock);
++ handler2 = createFileHandler(writableDir);
++ System.out.println("handler created: " + handler2);
++ after = listLocks(writableDir, true);
++ System.out.println("after creating handler: " + after.size()
++ + " locks found");
++ after.removeAll(before);
++ if (after.size() != 1) {
++ throw new RuntimeException("Unexpected lock files found: " + after
++ + "\n\t" + lock + " should not have been reused");
++ }
++ } else {
++ throw new RuntimeException("Failed to lock: " + lock);
++ }
++ } finally {
++ delete(lock);
++ }
++ }
++ } finally {
++ List<File> finalLocks = listLocks(writableDir, false);
++ System.out.println("end: " + finalLocks.size() + " locks found");
++ delete(writableDir);
++ }
++ }
++
++
++ private static void testFileHandlerCreate(File writableDir, boolean first)
++ throws IOException {
++ List<File> before = listLocks(writableDir, true);
++ System.out.println("before: " + before.size() + " locks found");
++ try {
++ if (first && !before.isEmpty()) {
++ throw new RuntimeException("Expected no lock file! Found: " + before);
++ } else if (!first && before.size() != 1) {
++ throw new RuntimeException("Expected a single lock file! Found: " + before);
++ }
++ } finally {
++ before.stream().forEach(CheckZombieLockTest::delete);
++ }
++ FileHandler handler = createFileHandler(writableDir);
++ System.out.println("handler created: " + handler);
++ List<File> after = listLocks(writableDir, true);
++ System.out.println("after creating handler: " + after.size() + " locks found");
++ if (after.size() != 1) {
++ throw new RuntimeException("Unexpected number of lock files found for "
++ + handler + ": " + after);
++ }
++ }
++
++
++ /**
++ * Setup all the files and directories needed for the tests
++ *
++ * @return writable directory created that needs to be deleted when done
++ * @throws RuntimeException
++ */
++ private static File setup() throws RuntimeException {
++ // First do some setup in the temporary directory (using same logic as
++ // FileHandler for %t pattern)
++ String tmpDir = System.getProperty("java.io.tmpdir"); // i.e. %t
++ if (tmpDir == null) {
++ tmpDir = System.getProperty("user.home");
++ }
++ File tmpOrHomeDir = new File(tmpDir);
++ // Create a writable directory here (%t/writable-lockfile-dir)
++ File writableDir = new File(tmpOrHomeDir, WRITABLE_DIR);
++ if (!createFile(writableDir, true)) {
++ throw new RuntimeException("Test setup failed: unable to create"
++ + " writable working directory "
++ + writableDir.getAbsolutePath() );
++ }
++
++ // try to determine whether file locking is supported
++ final String uniqueFileName = UUID.randomUUID().toString()+".lck";
++ try {
++ FileChannel fc = FileChannel.open(Paths.get(writableDir.getAbsolutePath(),
++ uniqueFileName),
++ StandardOpenOption.CREATE_NEW, StandardOpenOption.APPEND,
++ StandardOpenOption.DELETE_ON_CLOSE);
++ try {
++ fc.tryLock();
++ } catch(IOException x) {
++ supportsLocking = false;
++ } finally {
++ fc.close();
++ }
++ } catch (IOException t) {
++ // should not happen
++ System.err.println("Failed to create new file " + uniqueFileName +
++ " in " + writableDir.getAbsolutePath());
++ throw new RuntimeException("Test setup failed: unable to run test", t);
++ }
++ return writableDir;
++ }
++
++ /**
++ * @param newFile
++ * @return true if file already exists or creation succeeded
++ */
++ private static boolean createFile(File newFile, boolean makeDirectory) {
++ if (newFile.exists()) {
++ return true;
++ }
++ if (makeDirectory) {
++ return newFile.mkdir();
++ } else {
++ try {
++ return newFile.createNewFile();
++ } catch (IOException ioex) {
++ ioex.printStackTrace();
++ return false;
++ }
++ }
++ }
++
++ /*
++ * Recursively delete all files starting at specified file
++ */
++ private static void delete(File f) {
++ if (f != null && f.isDirectory()) {
++ for (File c : f.listFiles())
++ delete(c);
++ }
++ if (!f.delete())
++ System.err.println(
++ "WARNING: unable to delete/cleanup writable test directory: "
++ + f );
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/util/logging/FileHandlerPath.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,315 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++import java.io.ByteArrayInputStream;
++import java.io.ByteArrayOutputStream;
++import java.io.File;
++import java.io.FilePermission;
++import java.io.IOException;
++import java.nio.channels.FileChannel;
++import java.nio.file.Files;
++import java.nio.file.Paths;
++import static java.nio.file.StandardOpenOption.CREATE_NEW;
++import static java.nio.file.StandardOpenOption.WRITE;
++import java.security.CodeSource;
++import java.security.Permission;
++import java.security.PermissionCollection;
++import java.security.Permissions;
++import java.security.Policy;
++import java.security.ProtectionDomain;
++import java.util.Arrays;
++import java.util.Collections;
++import java.util.Enumeration;
++import java.util.List;
++import java.util.Properties;
++import java.util.PropertyPermission;
++import java.util.UUID;
++import java.util.concurrent.atomic.AtomicBoolean;
++import java.util.logging.FileHandler;
++import java.util.logging.LogManager;
++import java.util.logging.LoggingPermission;
++
++/**
++ * @test
++ * @bug 8059269
++ * @summary tests that using a simple (non composite) pattern does not lead
++ * to NPE when the lock file already exists.
++ * @run main/othervm FileHandlerPath UNSECURE
++ * @run main/othervm FileHandlerPath SECURE
++ * @author danielfuchs
++ */
++public class FileHandlerPath {
++
++ /**
++ * We will test the simple pattern in two configurations.
++ * UNSECURE: No security manager.
++ * SECURE: With the security manager present - and the required
++ * permissions granted.
++ */
++ public static enum TestCase {
++ UNSECURE, SECURE;
++ public void run(Properties propertyFile) throws Exception {
++ System.out.println("Running test case: " + name());
++ Configure.setUp(this, propertyFile);
++ test(this.name() + " " + propertyFile.getProperty("test.name"), propertyFile);
++ }
++ }
++
++
++ // Use a random name provided by UUID to avoid collision with other tests
++ final static String logFile = FileHandlerPath.class.getSimpleName() + "_"
++ + UUID.randomUUID().toString() + ".log";
++ final static String tmpLogFile;
++ final static String userDir = System.getProperty("user.dir");
++ final static String tmpDir = System.getProperty("java.io.tmpdir");
++ private static final List<Properties> properties;
++ static {
++ tmpLogFile = new File(tmpDir, logFile).toString();
++ Properties props1 = new Properties();
++ Properties props2 = new Properties();
++ props1.setProperty("test.name", "relative file");
++ props1.setProperty("test.file.name", logFile);
++ props1.setProperty(FileHandler.class.getName() + ".pattern", logFile);
++ props1.setProperty(FileHandler.class.getName() + ".count", "1");
++ props2.setProperty("test.name", "absoluste file");
++ props2.setProperty("test.file.name", tmpLogFile);
++ props2.setProperty(FileHandler.class.getName() + ".pattern", "%t/" + logFile);
++ props2.setProperty(FileHandler.class.getName() + ".count", "1");
++ properties = Collections.unmodifiableList(Arrays.asList(
++ props1,
++ props2));
++ }
++
++ public static void main(String... args) throws Exception {
++
++ if (args == null || args.length == 0) {
++ args = new String[] {
++ TestCase.UNSECURE.name(),
++ TestCase.SECURE.name(),
++ };
++ }
++
++ // Sanity checks
++
++ if (!Files.isWritable(Paths.get(userDir))) {
++ throw new RuntimeException(userDir +
++ ": user.dir is not writable - can't run test.");
++ }
++ if (!Files.isWritable(Paths.get(tmpDir))) {
++ throw new RuntimeException(tmpDir +
++ ": java.io.tmpdir is not writable - can't run test.");
++ }
++
++ File[] files = {
++ new File(logFile),
++ new File(tmpLogFile),
++ new File(logFile+".1"),
++ new File(tmpLogFile+".1"),
++ new File(logFile+".lck"),
++ new File(tmpLogFile+".lck"),
++ new File(logFile+".1.lck"),
++ new File(tmpLogFile+".1.lck")
++ };
++
++ for (File log : files) {
++ if (log.exists()) {
++ throw new Exception(log +": file already exists - can't run test.");
++ }
++ }
++
++ // Now start the real test
++
++ try {
++ for (String testName : args) {
++ for (Properties propertyFile : properties) {
++ TestCase test = TestCase.valueOf(testName);
++ test.run(propertyFile);
++ }
++ }
++ } finally {
++ // Cleanup...
++ Configure.doPrivileged(() -> {
++ for(File log : files) {
++ try {
++ final boolean isLockFile = log.getName().endsWith(".lck");
++ // lock file should already be deleted, except if the
++ // test failed in exception.
++ // log file should all be present, except if the test
++ // failed in exception.
++ if (log.exists()) {
++ if (!isLockFile) {
++ System.out.println("deleting "+log.toString());
++ } else {
++ System.err.println("deleting lock file "+log.toString());
++ }
++ log.delete();
++ } else {
++ if (!isLockFile) {
++ System.err.println(log.toString() + ": not found.");
++ }
++ }
++ } catch (Throwable t) {
++ // should not happen
++ t.printStackTrace();
++ }
++ }
++ });
++ }
++ }
++
++ static class Configure {
++ static Policy policy = null;
++ static final AtomicBoolean allowAll = new AtomicBoolean(false);
++ static void setUp(TestCase test, Properties propertyFile) {
++ switch (test) {
++ case SECURE:
++ if (policy == null && System.getSecurityManager() != null) {
++ throw new IllegalStateException("SecurityManager already set");
++ } else if (policy == null) {
++ policy = new SimplePolicy(TestCase.SECURE, allowAll);
++ Policy.setPolicy(policy);
++ System.setSecurityManager(new SecurityManager());
++ }
++ if (System.getSecurityManager() == null) {
++ throw new IllegalStateException("No SecurityManager.");
++ }
++ if (policy == null) {
++ throw new IllegalStateException("policy not configured");
++ }
++ break;
++ case UNSECURE:
++ if (System.getSecurityManager() != null) {
++ throw new IllegalStateException("SecurityManager already set");
++ }
++ break;
++ default:
++ new InternalError("No such testcase: " + test);
++ }
++ doPrivileged(() -> {
++ try {
++ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
++ propertyFile.store(bytes, propertyFile.getProperty("test.name"));
++ ByteArrayInputStream bais = new ByteArrayInputStream(bytes.toByteArray());
++ LogManager.getLogManager().readConfiguration(bais);
++ } catch (IOException ex) {
++ throw new RuntimeException(ex);
++ }
++ });
++ }
++ static void doPrivileged(Runnable run) {
++ allowAll.set(true);
++ try {
++ run.run();
++ } finally {
++ allowAll.set(false);
++ }
++ }
++ }
++
++ public static void test(String name, Properties props) throws Exception {
++ System.out.println("Testing: " + name);
++ String file = props.getProperty("test.file.name");
++ // create the lock files first - in order to take the path that
++ // used to trigger the NPE
++ Files.createFile(Paths.get(file + ".lck"));
++ Files.createFile(Paths.get(file + ".1.lck"));
++ final FileHandler f1 = new FileHandler();
++ final FileHandler f2 = new FileHandler();
++ f1.close();
++ f2.close();
++ System.out.println("Success for " + name);
++ }
++
++
++ final static class PermissionsBuilder {
++ final Permissions perms;
++ public PermissionsBuilder() {
++ this(new Permissions());
++ }
++ public PermissionsBuilder(Permissions perms) {
++ this.perms = perms;
++ }
++ public PermissionsBuilder add(Permission p) {
++ perms.add(p);
++ return this;
++ }
++ public PermissionsBuilder addAll(PermissionCollection col) {
++ if (col != null) {
++ for (Enumeration<Permission> e = col.elements(); e.hasMoreElements(); ) {
++ perms.add(e.nextElement());
++ }
++ }
++ return this;
++ }
++ public Permissions toPermissions() {
++ final PermissionsBuilder builder = new PermissionsBuilder();
++ builder.addAll(perms);
++ return builder.perms;
++ }
++ }
++
++ public static class SimplePolicy extends Policy {
++
++ final Permissions permissions;
++ final Permissions allPermissions;
++ final AtomicBoolean allowAll;
++ public SimplePolicy(TestCase test, AtomicBoolean allowAll) {
++ this.allowAll = allowAll;
++ permissions = new Permissions();
++ permissions.add(new LoggingPermission("control", null)); // needed by new FileHandler()
++ permissions.add(new FilePermission("<<ALL FILES>>", "read")); // needed by new FileHandler()
++ permissions.add(new FilePermission(logFile, "write,delete")); // needed by new FileHandler()
++ permissions.add(new FilePermission(logFile+".lck", "write,delete")); // needed by FileHandler.close()
++ permissions.add(new FilePermission(logFile+".1", "write,delete")); // needed by new FileHandler()
++ permissions.add(new FilePermission(logFile+".1.lck", "write,delete")); // needed by FileHandler.close()
++ permissions.add(new FilePermission(tmpLogFile, "write,delete")); // needed by new FileHandler()
++ permissions.add(new FilePermission(tmpLogFile+".lck", "write,delete")); // needed by FileHandler.close()
++ permissions.add(new FilePermission(tmpLogFile+".1", "write,delete")); // needed by new FileHandler()
++ permissions.add(new FilePermission(tmpLogFile+".1.lck", "write,delete")); // needed by FileHandler.close()
++ permissions.add(new FilePermission(userDir, "write")); // needed by new FileHandler()
++ permissions.add(new FilePermission(tmpDir, "write")); // needed by new FileHandler()
++ permissions.add(new PropertyPermission("user.dir", "read"));
++ permissions.add(new PropertyPermission("java.io.tmpdir", "read"));
++ allPermissions = new Permissions();
++ allPermissions.add(new java.security.AllPermission());
++ }
++
++ @Override
++ public boolean implies(ProtectionDomain domain, Permission permission) {
++ if (allowAll.get()) return allPermissions.implies(permission);
++ return permissions.implies(permission);
++ }
++
++ @Override
++ public PermissionCollection getPermissions(CodeSource codesource) {
++ return new PermissionsBuilder().addAll(allowAll.get()
++ ? allPermissions : permissions).toPermissions();
++ }
++
++ @Override
++ public PermissionCollection getPermissions(ProtectionDomain domain) {
++ return new PermissionsBuilder().addAll(allowAll.get()
++ ? allPermissions : permissions).toPermissions();
++ }
++ }
++
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/java/util/logging/LogManagerAppContextDeadlock.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,370 @@
++/*
++ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.lang.management.ManagementFactory;
++import java.lang.management.ThreadInfo;
++import java.security.CodeSource;
++import java.security.Permission;
++import java.security.PermissionCollection;
++import java.security.Permissions;
++import java.security.Policy;
++import java.security.ProtectionDomain;
++import java.util.Enumeration;
++import java.util.concurrent.Semaphore;
++import java.util.concurrent.atomic.AtomicBoolean;
++import java.util.concurrent.atomic.AtomicInteger;
++import java.util.logging.LogManager;
++import java.util.logging.Logger;
++
++/**
++ * @test
++ * @bug 8065991
++ * @summary check that when LogManager is initialized, a deadlock similar
++ * to that described in 8065709 will not occur.
++ * @run main/othervm LogManagerAppContextDeadlock UNSECURE
++ * @run main/othervm LogManagerAppContextDeadlock SECURE
++ *
++ * @author danielfuchs
++ */
++public class LogManagerAppContextDeadlock {
++
++ public static final Semaphore sem = new Semaphore(0);
++ public static final Semaphore sem2 = new Semaphore(0);
++ public static final Semaphore sem3 = new Semaphore(-2);
++ public static volatile boolean goOn = true;
++ public static volatile Exception thrown;
++
++ // Emulate EventQueue
++ static class FakeEventQueue {
++ static final Logger logger = Logger.getLogger("foo");
++ }
++
++ // Emulate AppContext
++ static class FakeAppContext {
++
++ final static AtomicInteger numAppContexts = new AtomicInteger(0);
++ static final class FakeAppContextLock {}
++ static final FakeAppContextLock lock = new FakeAppContextLock();
++ static volatile FakeAppContext appContext;
++
++ final FakeEventQueue queue;
++ FakeAppContext() {
++ appContext = this;
++ numAppContexts.incrementAndGet();
++ // release sem2 to let Thread t2 call Logger.getLogger().
++ sem2.release();
++ try {
++ // Wait until we JavaAWTAccess is called by LogManager.
++ // Thread 2 will call Logger.getLogger() which will
++ // trigger a call to JavaAWTAccess - which will release
++ // sem, thus ensuring that Thread #2 is where we want it.
++ sem.acquire();
++ System.out.println("Sem acquired: Thread #2 has called JavaAWTAccess");
++ } catch(InterruptedException x) {
++ Thread.interrupted();
++ }
++ queue = new FakeEventQueue();
++ }
++
++ static FakeAppContext getAppContext() {
++ synchronized (lock) {
++ if (numAppContexts.get() == 0) {
++ return new FakeAppContext();
++ }
++ return appContext;
++ }
++ }
++
++ static {
++ sun.misc.SharedSecrets.setJavaAWTAccess(new sun.misc.JavaAWTAccess() {
++ @Override
++ public Object getAppletContext() {
++ if (numAppContexts.get() == 0) return null;
++ // We are in JavaAWTAccess, we can release sem and let
++ // FakeAppContext constructor proceeed.
++ System.out.println("Releasing Sem");
++ sem.release();
++ return getAppContext();
++ }
++
++ });
++ }
++
++ }
++
++
++ // Test with or without a security manager
++ public static enum TestCase {
++ UNSECURE, SECURE;
++ public void run() throws Exception {
++ System.out.println("Running test case: " + name());
++ Configure.setUp(this);
++ test(this);
++ }
++ }
++
++ public static void test(TestCase test) throws Exception {
++ Thread t1 = new Thread() {
++ @Override
++ public void run() {
++ sem3.release();
++ System.out.println("FakeAppContext.getAppContext()");
++ FakeAppContext.getAppContext();
++ System.out.println("Done: FakeAppContext.getAppContext()");
++ }
++ };
++ t1.setDaemon(true);
++ t1.start();
++ Thread t2 = new Thread() {
++ public void run() {
++ sem3.release();
++ try {
++ // Wait until Thread1 is in FakeAppContext constructor
++ sem2.acquire();
++ System.out.println("Sem2 acquired: Thread #1 will be waiting to acquire Sem");
++ } catch (InterruptedException ie) {
++ Thread.interrupted();
++ }
++ System.out.println("Logger.getLogger(name).info(name)");
++ Logger.getLogger(test.name());//.info(name);
++ System.out.println("Done: Logger.getLogger(name).info(name)");
++ }
++ };
++ t2.setDaemon(true);
++ t2.start();
++ System.out.println("Should exit now...");
++ Thread detector = new DeadlockDetector();
++ detector.start();
++
++ // Wait for the 3 threads to start
++ sem3.acquire();
++
++ // Now wait for t1 & t2 to finish, or for a deadlock to be detected.
++ while (goOn && (t1.isAlive() || t2.isAlive())) {
++ if (t2.isAlive()) t2.join(1000);
++ if (test == TestCase.UNSECURE && System.getSecurityManager() == null) {
++ // if there's no security manager, AppContext.getAppContext() is
++ // not called - so Thread t2 will not end up calling
++ // sem.release(). In that case we must release the semaphore here
++ // so that t1 can proceed.
++ if (LogManager.getLogManager().getLogger(TestCase.UNSECURE.name()) != null) {
++ // means Thread t2 has created the logger
++ sem.release();
++ }
++ }
++ if (t1.isAlive()) t1.join(1000);
++ }
++ if (thrown != null) {
++ throw thrown;
++ }
++ }
++
++ // Thrown by the deadlock detector
++ static final class DeadlockException extends RuntimeException {
++ public DeadlockException(String message) {
++ super(message);
++ }
++ @Override
++ public void printStackTrace() {
++ }
++ }
++
++ public static void main(String[] args) throws Exception {
++
++ if (args.length == 0) {
++ args = new String[] { "SECURE" };
++ }
++
++ // If we don't initialize LogManager here, there will be
++ // a deadlock.
++ // See <https://bugs.openjdk.java.net/browse/JDK-8065709?focusedCommentId=13582038&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-13582038>
++ // for more details.
++ Logger.getLogger("main").info("starting...");
++ try {
++ TestCase.valueOf(args[0]).run();
++ System.out.println("Test "+args[0]+" Passed");
++ } catch(Throwable t) {
++ System.err.println("Test " + args[0] +" failed: " + t);
++ t.printStackTrace();
++ }
++ }
++
++ // Called by the deadlock detector when a deadlock is found.
++ static void fail(Exception x) {
++ x.printStackTrace();
++ if (thrown == null) {
++ thrown = x;
++ }
++ goOn = false;
++ }
++
++ // A thread that detect deadlocks.
++ final static class DeadlockDetector extends Thread {
++
++ public DeadlockDetector() {
++ this.setDaemon(true);
++ }
++
++ @Override
++ public void run() {
++ sem3.release();
++ Configure.doPrivileged(this::loop);
++ }
++ public void loop() {
++ while(goOn) {
++ try {
++ long[] ids = ManagementFactory.getThreadMXBean().findDeadlockedThreads();
++ ids = ids == null ? new long[0] : ids;
++ if (ids.length == 1) {
++ throw new RuntimeException("Found 1 deadlocked thread: "+ids[0]);
++ } else if (ids.length > 0) {
++ ThreadInfo[] infos = ManagementFactory.getThreadMXBean().getThreadInfo(ids, Integer.MAX_VALUE);
++ System.err.println("Found "+ids.length+" deadlocked threads: ");
++ for (ThreadInfo inf : infos) {
++ System.err.println(inf);
++ }
++ throw new DeadlockException("Found "+ids.length+" deadlocked threads");
++ }
++ Thread.sleep(100);
++ } catch(InterruptedException | RuntimeException x) {
++ fail(x);
++ }
++ }
++ }
++
++ }
++
++ // A helper class to configure the security manager for the test,
++ // and bypass it when needed.
++ static class Configure {
++ static Policy policy = null;
++ static final ThreadLocal<AtomicBoolean> allowAll = new ThreadLocal<AtomicBoolean>() {
++ @Override
++ protected AtomicBoolean initialValue() {
++ return new AtomicBoolean(false);
++ }
++ };
++ static void setUp(TestCase test) {
++ switch (test) {
++ case SECURE:
++ if (policy == null && System.getSecurityManager() != null) {
++ throw new IllegalStateException("SecurityManager already set");
++ } else if (policy == null) {
++ policy = new SimplePolicy(TestCase.SECURE, allowAll);
++ Policy.setPolicy(policy);
++ System.setSecurityManager(new SecurityManager());
++ }
++ if (System.getSecurityManager() == null) {
++ throw new IllegalStateException("No SecurityManager.");
++ }
++ if (policy == null) {
++ throw new IllegalStateException("policy not configured");
++ }
++ break;
++ case UNSECURE:
++ if (System.getSecurityManager() != null) {
++ throw new IllegalStateException("SecurityManager already set");
++ }
++ break;
++ default:
++ new InternalError("No such testcase: " + test);
++ }
++ }
++ static void doPrivileged(Runnable run) {
++ allowAll.get().set(true);
++ try {
++ run.run();
++ } finally {
++ allowAll.get().set(false);
++ }
++ }
++ }
++
++ // A Helper class to build a set of permissions.
++ final static class PermissionsBuilder {
++ final Permissions perms;
++ public PermissionsBuilder() {
++ this(new Permissions());
++ }
++ public PermissionsBuilder(Permissions perms) {
++ this.perms = perms;
++ }
++ public PermissionsBuilder add(Permission p) {
++ perms.add(p);
++ return this;
++ }
++ public PermissionsBuilder addAll(PermissionCollection col) {
++ if (col != null) {
++ for (Enumeration<Permission> e = col.elements(); e.hasMoreElements(); ) {
++ perms.add(e.nextElement());
++ }
++ }
++ return this;
++ }
++ public Permissions toPermissions() {
++ final PermissionsBuilder builder = new PermissionsBuilder();
++ builder.addAll(perms);
++ return builder.perms;
++ }
++ }
++
++ // Policy for the test...
++ public static class SimplePolicy extends Policy {
++
++ final Permissions permissions;
++ final Permissions allPermissions;
++ final ThreadLocal<AtomicBoolean> allowAll; // actually: this should be in a thread locale
++ public SimplePolicy(TestCase test, ThreadLocal<AtomicBoolean> allowAll) {
++ this.allowAll = allowAll;
++ // we don't actually need any permission to create our
++ // FileHandlers because we're passing invalid parameters
++ // which will make the creation fail...
++ permissions = new Permissions();
++ permissions.add(new RuntimePermission("accessClassInPackage.sun.misc"));
++
++ // these are used for configuring the test itself...
++ allPermissions = new Permissions();
++ allPermissions.add(new java.security.AllPermission());
++
++ }
++
++ @Override
++ public boolean implies(ProtectionDomain domain, Permission permission) {
++ if (allowAll.get().get()) return allPermissions.implies(permission);
++ return permissions.implies(permission);
++ }
++
++ @Override
++ public PermissionCollection getPermissions(CodeSource codesource) {
++ return new PermissionsBuilder().addAll(allowAll.get().get()
++ ? allPermissions : permissions).toPermissions();
++ }
++
++ @Override
++ public PermissionCollection getPermissions(ProtectionDomain domain) {
++ return new PermissionsBuilder().addAll(allowAll.get().get()
++ ? allPermissions : permissions).toPermissions();
++ }
++ }
++
++}
+--- ./jdk/test/java/util/logging/LoggingDeadlock2.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/util/logging/LoggingDeadlock2.java Wed Feb 04 12:14:43 2015 -0800
+@@ -28,7 +28,7 @@
+ * @author Serguei Spitsyn / Hitachi / Martin Buchholz
+ *
+ * @build LoggingDeadlock2
+- * @run main/timeout=15 LoggingDeadlock2
++ * @run main LoggingDeadlock2
+ *
+ * There is a clear deadlock between LogManager.<clinit> and
+ * Cleaner.run() methods.
+--- ./jdk/test/java/util/logging/TestLoggerBundleSync.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/java/util/logging/TestLoggerBundleSync.java Wed Feb 04 12:14:43 2015 -0800
+@@ -58,6 +58,7 @@
+ */
+ public class TestLoggerBundleSync {
+
++ static final boolean VERBOSE = false;
+ static volatile Exception thrown = null;
+ static volatile boolean goOn = true;
+
+@@ -65,6 +66,7 @@
+ static final long TIME = 4 * 1000; // 4 sec.
+ static final long STEP = 1 * 1000; // message every 1 sec.
+ static final int LCOUNT = 50; // change bundle 50 times...
++ static final AtomicLong ignoreLogCount = new AtomicLong(0);
+ static final AtomicLong setRBcount = new AtomicLong(0);
+ static final AtomicLong setRBNameCount = new AtomicLong(0);
+ static final AtomicLong getRBcount = new AtomicLong(0);
+@@ -150,6 +152,7 @@
+ long sSetRBNameCount = setRBNameCount.get();
+ long sCheckCount = checkCount.get();
+ long sNextLong = nextLong.get();
++ long sIgnoreLogCount = ignoreLogCount.get();
+ List<Thread> threads = new ArrayList<>();
+ for (Class<? extends ResourceBundle> type : classes) {
+ threads.add(new SetRB(type));
+@@ -181,21 +184,58 @@
+ + " resource bundles set by " + classes.size() + " Thread(s),");
+ System.out.println("\t " + (setRBNameCount.get() - sSetRBNameCount)
+ + " resource bundle names set by " + classes.size() + " Thread(s),");
++ System.out.println("\t " + (ignoreLogCount.get() - sIgnoreLogCount)
++ + " log messages emitted by other GetRB threads were ignored"
++ + " to ensure MT test consistency,");
+ System.out.println("\t ThreadMXBean.findDeadlockedThreads called "
+ + (checkCount.get() -sCheckCount) + " times by 1 Thread.");
+
+ }
+
+ final static class GetRB extends Thread {
+- final static class MyHandler extends Handler {
++ final class MyHandler extends Handler {
+ volatile ResourceBundle rb;
+ volatile String rbName;
+ volatile int count = 0;
+ @Override
+ public synchronized void publish(LogRecord record) {
+- count++;
+- rb = record.getResourceBundle();
+- rbName = record.getResourceBundleName();
++ Object[] params = record.getParameters();
++ // Each GetRB thread has its own handler, but since they
++ // log into the same logger, each handler may receive
++ // messages emitted by other threads.
++ // This means that GetRB#2.handler may receive a message
++ // emitted by GetRB#1 at a time where the resource bundle
++ // was still null.
++ // To avoid falling into this trap, the GetRB thread passes
++ // 'this' as argument to the messages it logs - which does
++ // allow us here to ignore messages that where not emitted
++ // by our own GetRB.this thread...
++ if (params.length == 1) {
++ if (params[0] == GetRB.this) {
++ // The message was emitted by our thread.
++ count++;
++ rb = record.getResourceBundle();
++ rbName = record.getResourceBundleName();
++ } else {
++ // The message was emitted by another thread: just
++ // ignore it, as it may have been emitted at a time
++ // where the resource bundle was still null, and
++ // processing it may overwrite the 'rb' and 'rbName'
++ // recorded from the message emitted by our own thread.
++ if (VERBOSE) {
++ System.out.println("Ignoring message logged by " + params[0]);
++ }
++ ignoreLogCount.incrementAndGet();
++ }
++ } else {
++ ignoreLogCount.incrementAndGet();
++ System.err.println("Unexpected message received");
++ }
++ }
++
++ void reset() {
++ rbName = null;
++ rb = null;
+ }
+
+ @Override
+@@ -207,6 +247,7 @@
+ }
+ };
+ final MyHandler handler = new MyHandler();
++
+ @Override
+ public void run() {
+ try {
+@@ -234,9 +275,10 @@
+ + handler.getLevel());
+ }
+ final int countBefore = handler.count;
++ handler.reset();
+ ll.setLevel(Level.FINEST);
+ ll.addHandler(handler);
+- ll.fine("dummy");
++ ll.log(Level.FINE, "dummy {0}", this);
+ ll.removeHandler(handler);
+ final int countAfter = handler.count;
+ if (countBefore == countAfter) {
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/imageio/plugins/png/PngDitDepthTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,74 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++* @test
++* @bug 4991647
++* @summary PNGMetadata.getAsTree() sets bitDepth to invalid value
++* @run main PngDitDepthTest
++*/
++
++import org.w3c.dom.Node;
++
++import javax.imageio.ImageIO;
++import javax.imageio.ImageTypeSpecifier;
++import javax.imageio.ImageWriter;
++import javax.imageio.metadata.IIOInvalidTreeException;
++import javax.imageio.metadata.IIOMetadata;
++import java.awt.image.ColorModel;
++import java.awt.image.SampleModel;
++import java.util.Iterator;
++
++public class PngDitDepthTest {
++
++ public static void main(String[] args) throws IIOInvalidTreeException {
++
++ // getting the writer for the png format
++ Iterator iter = ImageIO.getImageWritersByFormatName("png");
++ ImageWriter writer = (ImageWriter) iter.next();
++
++ // creating a color model
++ ColorModel colorModel = ColorModel.getRGBdefault();
++
++ // creating a sample model
++ SampleModel sampleModel = colorModel.createCompatibleSampleModel(640, 480);
++
++ // creating a default metadata object
++ IIOMetadata metaData = writer.getDefaultImageMetadata(new ImageTypeSpecifier(colorModel, sampleModel), null);
++ String formatName = metaData.getNativeMetadataFormatName();
++
++ // first call
++ Node metaDataNode = metaData.getAsTree(formatName);
++ try {
++ metaData.setFromTree(formatName, metaDataNode);
++ } catch (Exception ex) {
++ ex.printStackTrace();
++ }
++
++ // second call (bitdepht is already set to an invalid value)
++ metaDataNode = metaData.getAsTree(formatName);
++
++ metaData.setFromTree(formatName, metaDataNode);
++
++ }
++}
+--- ./jdk/test/javax/management/MBeanServer/MBeanFallbackTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/javax/management/MBeanServer/MBeanFallbackTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -35,7 +35,7 @@
+ * @author Jaroslav Bachorik
+ * @run clean MBeanFallbackTest
+ * @run build MBeanFallbackTest
+- * @run main MBeanFallbackTest
++ * @run main/othervm -Djdk.jmx.mbeans.allowNonPublic=true MBeanFallbackTest
+ */
+ public class MBeanFallbackTest {
+ private static interface PrivateMBean {
+@@ -51,7 +51,6 @@
+ private static int failures = 0;
+
+ public static void main(String[] args) throws Exception {
+- System.setProperty("jdk.jmx.mbeans.allowNonPublic", "true");
+ testPrivate(PrivateMBean.class, new Private());
+
+ if (failures == 0)
+--- ./jdk/test/javax/management/ObjectName/SerialCompatTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/javax/management/ObjectName/SerialCompatTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -28,7 +28,7 @@
+ * @author Eamonn McManus, Daniel Fuchs
+ * @run clean SerialCompatTest
+ * @run build SerialCompatTest
+- * @run main/othervm SerialCompatTest
++ * @run main/othervm -Djdk.jmx.mbeans.allowNonPublic=true -Djmx.serial.form=1.0 SerialCompatTest
+ */
+
+ import java.io.*;
+@@ -223,8 +223,6 @@
+ }
+
+ public static void main(String[] args) throws Exception {
+- System.setProperty("jmx.serial.form", "1.0");
+-
+ /* Check that we really are in jmx.serial.form=1.0 mode.
+ The property is frozen the first time the ObjectName class
+ is referenced so checking that it is set to the correct
+--- ./jdk/test/javax/management/monitor/AttributeArbitraryDataTypeTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/javax/management/monitor/AttributeArbitraryDataTypeTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -58,9 +58,9 @@
+ public class AttributeArbitraryDataTypeTest implements NotificationListener {
+
+ // Flag to notify that a message has been received
+- private boolean counterMessageReceived = false;
+- private boolean gaugeMessageReceived = false;
+- private boolean stringMessageReceived = false;
++ private volatile boolean counterMessageReceived = false;
++ private volatile boolean gaugeMessageReceived = false;
++ private volatile boolean stringMessageReceived = false;
+
+ // Match enum
+ public enum Match { do_not_match_0,
+@@ -195,21 +195,33 @@
+ " has reached or exceeded the threshold");
+ echo("\t\tDerived Gauge = " + n.getDerivedGauge());
+ echo("\t\tTrigger = " + n.getTrigger());
+- counterMessageReceived = true;
++
++ synchronized (this) {
++ counterMessageReceived = true;
++ notifyAll();
++ }
+ } else if (type.equals(MonitorNotification.
+ THRESHOLD_HIGH_VALUE_EXCEEDED)) {
+ echo("\t\t" + n.getObservedAttribute() +
+ " has reached or exceeded the high threshold");
+ echo("\t\tDerived Gauge = " + n.getDerivedGauge());
+ echo("\t\tTrigger = " + n.getTrigger());
+- gaugeMessageReceived = true;
++
++ synchronized (this) {
++ gaugeMessageReceived = true;
++ notifyAll();
++ }
+ } else if (type.equals(MonitorNotification.
+ STRING_TO_COMPARE_VALUE_MATCHED)) {
+ echo("\t\t" + n.getObservedAttribute() +
+ " matches the string-to-compare value");
+ echo("\t\tDerived Gauge = " + n.getDerivedGauge());
+ echo("\t\tTrigger = " + n.getTrigger());
+- stringMessageReceived = true;
++
++ synchronized (this) {
++ stringMessageReceived = true;
++ notifyAll();
++ }
+ } else {
+ echo("\t\tSkipping notification of type: " + type);
+ }
+@@ -358,6 +370,17 @@
+
+ // Check if notification was received
+ //
++ synchronized (this) {
++ while (!counterMessageReceived) {
++ try {
++ wait();
++ } catch (InterruptedException e) {
++ System.err.println("Got unexpected exception: " + e);
++ e.printStackTrace();
++ break;
++ }
++ }
++ }
+ if (counterMessageReceived) {
+ echo("\tOK: CounterMonitor notification received");
+ } else {
+@@ -525,6 +548,17 @@
+
+ // Check if notification was received
+ //
++ synchronized (this) {
++ while (!gaugeMessageReceived) {
++ try {
++ wait();
++ } catch (InterruptedException e) {
++ System.err.println("Got unexpected exception: " + e);
++ e.printStackTrace();
++ break;
++ }
++ }
++ }
+ if (gaugeMessageReceived) {
+ echo("\tOK: GaugeMonitor notification received");
+ } else {
+@@ -680,6 +714,17 @@
+
+ // Check if notification was received
+ //
++ synchronized (this) {
++ while (!stringMessageReceived) {
++ try {
++ wait();
++ } catch (InterruptedException e) {
++ System.err.println("Got unexpected exception: " + e);
++ e.printStackTrace();
++ break;
++ }
++ }
++ }
+ if (stringMessageReceived) {
+ echo("\tOK: StringMonitor notification received");
+ } else {
+--- ./jdk/test/javax/management/monitor/CounterMonitorTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/javax/management/monitor/CounterMonitorTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -26,7 +26,7 @@
+ * @bug 4981829
+ * @summary Test that the counter monitor, when running in difference mode,
+ * emits a notification every time the threshold is exceeded.
+- * @author Luis-Miguel Alventosa
++ * @author Luis-Miguel Alventosa, Shanliang JIANG
+ * @run clean CounterMonitorTest
+ * @run build CounterMonitorTest
+ * @run main CounterMonitorTest
+@@ -43,9 +43,6 @@
+ // modulus number
+ private Number modulus = new Integer(7);
+
+- // offset number
+- private int offset = 0;
+-
+ // difference mode flag
+ private boolean differenceModeFlag = true;
+
+@@ -53,26 +50,31 @@
+ private boolean notifyFlag = true;
+
+ // granularity period
+- private int granularityperiod = 500;
++ private int granularityperiod = 10;
+
+- // counter values
+- private int[] values = new int[] {4, 6, 9, 11};
+-
+- // time to wait for notification (in seconds)
+- private int timeout = 5;
++ // derived gauge
++ private volatile int derivedGauge = 2;
+
+ // flag to notify that a message has been received
+ private volatile boolean messageReceived = false;
+
++ private volatile Object observedValue = null;
++
+ // MBean class
+ public class StdObservedObject implements StdObservedObjectMBean {
+ public Object getNbObjects() {
++ echo(">>> StdObservedObject.getNbObjects: " + count);
++ synchronized(CounterMonitorTest.class) {
++ observedValue = count;
++ CounterMonitorTest.class.notifyAll();
++ }
+ return count;
+ }
+ public void setNbObjects(Object n) {
++ echo(">>> StdObservedObject.setNbObjects: " + n);
+ count = n;
+ }
+- private Object count= null;
++ private volatile Object count= null;
+ }
+
+ // MBean interface
+@@ -92,8 +94,9 @@
+ echo("\t\t" + n.getObservedAttribute() +
+ " has reached or exceeded the threshold");
+ echo("\t\tDerived Gauge = " + n.getDerivedGauge());
+- messageReceived = true;
++
+ synchronized (this) {
++ messageReceived = true;
+ notifyAll();
+ }
+ } else {
+@@ -171,18 +174,18 @@
+ Attribute attrib = new Attribute("NbObjects", data);
+ server.setAttribute(stdObsObjName, attrib);
+
+- // Wait for granularity period (multiplied by 2 for sure)
+- //
+- Thread.sleep(granularityperiod * 2);
++ waitObservation(data);
+
+ // Loop through the values
+ //
+- for (int i = 0; i < values.length; i++) {
+- data = new Integer(values[i]);
+- echo(">>> Set data = " + data.intValue());
++ while (derivedGauge++ < 10) {
++ System.out.print(">>> Set data from " + data.intValue());
++ data = new Integer(data.intValue() + derivedGauge);
++ echo(" to " + data.intValue());
+
+ attrib = new Attribute("NbObjects", data);
+ server.setAttribute(stdObsObjName, attrib);
++ waitObservation(data);
+
+ echo("\tdoWait in Counter Monitor");
+ doWait();
+@@ -205,21 +208,30 @@
+ }
+
+ /*
+- * Wait until timeout reached
++ * Wait messageReceived to be true
+ */
+- void doWait() {
+- for (int i = 0; i < timeout; i++) {
+- echo("\tdoWait: Waiting for " + timeout + " seconds. " +
+- "i = " + i + ", messageReceived = " + messageReceived);
+- if (messageReceived) {
++ synchronized void doWait() {
++ while (!messageReceived) {
++ try {
++ wait();
++ } catch (InterruptedException e) {
++ System.err.println("Got unexpected exception: " + e);
++ e.printStackTrace();
+ break;
+ }
+- try {
+- synchronized (this) {
+- wait(1000);
++ }
++ }
++
++ private void waitObservation(Object value) {
++ synchronized (CounterMonitorTest.class) {
++ while (value != observedValue) {
++ try {
++ CounterMonitorTest.class.wait();
++ } catch (InterruptedException e) {
++ System.err.println("Got unexpected exception: " + e);
++ e.printStackTrace();
++ break;
+ }
+- } catch (InterruptedException e) {
+- // OK: Ignore...
+ }
+ }
+ }
+--- ./jdk/test/javax/management/monitor/GaugeMonitorDeadlockTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/javax/management/monitor/GaugeMonitorDeadlockTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -36,8 +36,9 @@
+ */
+
+ import java.lang.management.ManagementFactory;
++import java.lang.management.ThreadInfo;
++import java.lang.management.ThreadMXBean;
+ import java.util.concurrent.atomic.AtomicInteger;
+-import javax.management.Attribute;
+ import javax.management.JMX;
+ import javax.management.MBeanServer;
+ import javax.management.Notification;
+@@ -47,10 +48,16 @@
+ import javax.management.monitor.GaugeMonitorMBean;
+
+ public class GaugeMonitorDeadlockTest {
++ private static enum When {IN_GET_ATTRIBUTE, IN_NOTIFY};
++ private static long checkingTime;
+
+ public static void main(String[] args) throws Exception {
+ if (args.length != 1)
+ throw new Exception("Arg should be test number");
++ double factor = Double.parseDouble(System.getProperty("test.timeout.factor", "1.0"));
++ checkingTime = (long)factor*1000;
++ System.out.println("=== checkingTime = " + checkingTime + "ms");
++
+ int testNo = Integer.parseInt(args[0]) - 1;
+ TestCase test = testCases[testNo];
+ System.out.println("Test: " + test.getDescription());
+@@ -58,8 +65,6 @@
+ System.out.println("Test passed");
+ }
+
+- private static enum When {IN_GET_ATTRIBUTE, IN_NOTIFY};
+-
+ private static abstract class TestCase {
+ TestCase(String description, When when) {
+ this.description = description;
+@@ -98,16 +103,29 @@
+ monitorProxy.setNotifyLow(true);
+ monitorProxy.start();
+
++ System.out.println("=== Waiting observedProxy.getGetCount() to be "
++ + "changed, presumable deadlock if timeout?");
+ final int initGetCount = observedProxy.getGetCount();
+- int getCount = initGetCount;
+- for (int i = 0; i < 2000; i++) { // 2000 * 10 = 20 seconds
+- getCount = observedProxy.getGetCount();
+- if (getCount != initGetCount)
+- break;
+- Thread.sleep(10);
++ long checkedTime = System.currentTimeMillis();
++ long nowTime;
++ ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
++ while (observedProxy.getGetCount() == initGetCount) {
++ Thread.sleep(100);
++
++ nowTime = System.currentTimeMillis();
++ if (nowTime - checkedTime >= checkingTime) {
++ System.out.println("=== Checking deadlocked ...");
++ if (threadMXBean.findDeadlockedThreads() != null) {
++ for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
++ System.out.println(info);
++ }
++ throw new Error("Found deadlocked threads: "
++ + threadMXBean.findDeadlockedThreads().length);
++ }
++ checkedTime = System.currentTimeMillis();
++ }
+ }
+- if (getCount <= initGetCount)
+- throw new Exception("Test failed: presumable deadlock");
++
+ // This won't show up as a deadlock in CTRL-\ or in
+ // ThreadMXBean.findDeadlockedThreads(), because they don't
+ // see that thread A is waiting for thread B (B.join()), and
+@@ -117,13 +135,13 @@
+ // so if we want to test notify behaviour we can trigger by
+ // exceeding the threshold.
+ if (when == When.IN_NOTIFY) {
++ final Thread testedThread = new Thread(sensitiveThing);
+ final AtomicInteger notifCount = new AtomicInteger();
+ final NotificationListener listener = new NotificationListener() {
+ public void handleNotification(Notification n, Object h) {
+- Thread t = new Thread(sensitiveThing);
+- t.start();
++ testedThread.start();
+ try {
+- t.join();
++ testedThread.join();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+@@ -132,12 +150,36 @@
+ };
+ mbs.addNotificationListener(monitorName, listener, null, null);
+ observedProxy.setThing(1000);
+- for (int i = 0; i < 2000 && notifCount.get() == 0; i++)
+- Thread.sleep(10);
+- if (notifCount.get() == 0)
+- throw new Exception("Test failed: presumable deadlock");
++ System.out.println("=== Waiting notifications, presumable "
++ + "deadlock if timeout?");
++ long startTime = System.currentTimeMillis();
++ checkedTime = startTime;
++ while (notifCount.get() == 0) {
++ Thread.sleep(100);
++
++ nowTime = System.currentTimeMillis();
++ if (nowTime - checkedTime >= checkingTime) {
++ System.out.println("=== Checking the thread state ...");
++ if (testedThread.isAlive()) {
++ System.out.println("=== Waiting testedThread to die "
++ + "after " + (nowTime - startTime) + "ms");
++
++ ThreadInfo tinfo = threadMXBean.getThreadInfo(testedThread.getId());
++ if (Thread.State.BLOCKED.equals(tinfo.getThreadState())) {
++ for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
++ System.out.println(info);
++ }
++ } else {
++ System.out.println(tinfo);
++ }
++ } else {
++ System.out.println("=== The testedThread is dead as wished, "
++ + "the test must be passed soon.");
++ }
++ checkedTime = System.currentTimeMillis();
++ }
++ }
+ }
+-
+ }
+
+ abstract void doSensitiveThing(GaugeMonitorMBean monitorProxy,
+--- ./jdk/test/javax/management/monitor/NonComparableAttributeValueTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/javax/management/monitor/NonComparableAttributeValueTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -39,7 +39,7 @@
+ public class NonComparableAttributeValueTest implements NotificationListener {
+
+ // Flag to notify that a message has been received
+- private boolean messageReceived = false;
++ private volatile boolean messageReceived = false;
+
+ // MBean class
+ public class ObservedObject implements ObservedObjectMBean {
+@@ -69,7 +69,11 @@
+ echo("\t\t" + n.getObservedAttribute() + " is null");
+ echo("\t\tDerived Gauge = " + n.getDerivedGauge());
+ echo("\t\tTrigger = " + n.getTrigger());
+- messageReceived = true;
++
++ synchronized (this) {
++ messageReceived = true;
++ notifyAll();
++ }
+ } else {
+ echo("\t\tSkipping notification of type: " + type);
+ }
+@@ -134,12 +138,9 @@
+ echo(">>> START the CounterMonitor");
+ counterMonitor.start();
+
+- // Wait for granularity period (multiplied by 2 for sure)
+- //
+- Thread.sleep(granularityperiod * 2);
+-
+ // Check if notification was received
+ //
++ doWait();
+ if (messageReceived) {
+ echo("\tOK: CounterMonitor notification received");
+ } else {
+@@ -212,12 +213,9 @@
+ echo(">>> START the GaugeMonitor");
+ gaugeMonitor.start();
+
+- // Wait for granularity period (multiplied by 2 for sure)
+- //
+- Thread.sleep(granularityperiod * 2);
+-
+ // Check if notification was received
+ //
++ doWait();
+ if (messageReceived) {
+ echo("\tOK: GaugeMonitor notification received");
+ } else {
+@@ -289,12 +287,9 @@
+ echo(">>> START the StringMonitor");
+ stringMonitor.start();
+
+- // Wait for granularity period (multiplied by 2 for sure)
+- //
+- Thread.sleep(granularityperiod * 2);
+-
+ // Check if notification was received
+ //
++ doWait();
+ if (messageReceived) {
+ echo("\tOK: StringMonitor notification received");
+ } else {
+@@ -334,6 +329,21 @@
+ }
+
+ /*
++ * Wait messageReceived to be true
++ */
++ synchronized void doWait() {
++ while (!messageReceived) {
++ try {
++ wait();
++ } catch (InterruptedException e) {
++ System.err.println("Got unexpected exception: " + e);
++ e.printStackTrace();
++ break;
++ }
++ }
++ }
++
++ /*
+ * Standalone entry point.
+ *
+ * Run the test and report to stdout.
+--- ./jdk/test/javax/management/monitor/ReflectionExceptionTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/javax/management/monitor/ReflectionExceptionTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -87,7 +87,11 @@
+ echo("\tObservedAttribute: " + mn.getObservedAttribute());
+ echo("\tDerivedGauge: " + mn.getDerivedGauge());
+ echo("\tTrigger: " + mn.getTrigger());
+- messageReceived = true;
++
++ synchronized (this) {
++ messageReceived = true;
++ notifyAll();
++ }
+ }
+ }
+ }
+@@ -135,12 +139,9 @@
+ echo(">>> START the CounterMonitor");
+ counterMonitor.start();
+
+- // Wait for granularity period (multiplied by 2 for sure)
+- //
+- Thread.sleep(granularityperiod * 2);
+-
+ // Check if notification was received
+ //
++ doWait();
+ if (messageReceived) {
+ echo("\tOK: CounterMonitor got RUNTIME_ERROR notification!");
+ } else {
+@@ -203,12 +204,9 @@
+ echo(">>> START the GaugeMonitor");
+ gaugeMonitor.start();
+
+- // Wait for granularity period (multiplied by 2 for sure)
+- //
+- Thread.sleep(granularityperiod * 2);
+-
+ // Check if notification was received
+ //
++ doWait();
+ if (messageReceived) {
+ echo("\tOK: GaugeMonitor got RUNTIME_ERROR notification!");
+ } else {
+@@ -270,12 +268,9 @@
+ echo(">>> START the StringMonitor");
+ stringMonitor.start();
+
+- // Wait for granularity period (multiplied by 2 for sure)
+- //
+- Thread.sleep(granularityperiod * 2);
+-
+ // Check if notification was received
+ //
++ doWait();
+ if (messageReceived) {
+ echo("\tOK: StringMonitor got RUNTIME_ERROR notification!");
+ } else {
+@@ -349,8 +344,23 @@
+ }
+ }
+
++ /*
++ * Wait messageReceived to be true
++ */
++ synchronized void doWait() {
++ while (!messageReceived) {
++ try {
++ wait();
++ } catch (InterruptedException e) {
++ System.err.println("Got unexpected exception: " + e);
++ e.printStackTrace();
++ break;
++ }
++ }
++ }
++
+ // Flag to notify that a message has been received
+- private boolean messageReceived = false;
++ private volatile boolean messageReceived = false;
+
+ private MBeanServer server;
+ private ObjectName obsObjName;
+--- ./jdk/test/javax/management/monitor/RuntimeExceptionTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/javax/management/monitor/RuntimeExceptionTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -86,7 +86,11 @@
+ echo("\tObservedAttribute: " + mn.getObservedAttribute());
+ echo("\tDerivedGauge: " + mn.getDerivedGauge());
+ echo("\tTrigger: " + mn.getTrigger());
+- messageReceived = true;
++
++ synchronized (this) {
++ messageReceived = true;
++ notifyAll();
++ }
+ }
+ }
+ }
+@@ -134,12 +138,9 @@
+ echo(">>> START the CounterMonitor");
+ counterMonitor.start();
+
+- // Wait for granularity period (multiplied by 2 for sure)
+- //
+- Thread.sleep(granularityperiod * 2);
+-
+ // Check if notification was received
+ //
++ doWait();
+ if (messageReceived) {
+ echo("\tOK: CounterMonitor got RUNTIME_ERROR notification!");
+ } else {
+@@ -202,12 +203,9 @@
+ echo(">>> START the GaugeMonitor");
+ gaugeMonitor.start();
+
+- // Wait for granularity period (multiplied by 2 for sure)
+- //
+- Thread.sleep(granularityperiod * 2);
+-
+ // Check if notification was received
+ //
++ doWait();
+ if (messageReceived) {
+ echo("\tOK: GaugeMonitor got RUNTIME_ERROR notification!");
+ } else {
+@@ -269,12 +267,9 @@
+ echo(">>> START the StringMonitor");
+ stringMonitor.start();
+
+- // Wait for granularity period (multiplied by 2 for sure)
+- //
+- Thread.sleep(granularityperiod * 2);
+-
+ // Check if notification was received
+ //
++ doWait();
+ if (messageReceived) {
+ echo("\tOK: StringMonitor got RUNTIME_ERROR notification!");
+ } else {
+@@ -347,8 +342,23 @@
+ }
+ }
+
++ /*
++ * Wait messageReceived to be true
++ */
++ synchronized void doWait() {
++ while (!messageReceived) {
++ try {
++ wait();
++ } catch (InterruptedException e) {
++ System.err.println("Got unexpected exception: " + e);
++ e.printStackTrace();
++ break;
++ }
++ }
++ }
++
+ // Flag to notify that a message has been received
+- private boolean messageReceived = false;
++ private volatile boolean messageReceived = false;
+
+ private MBeanServer server;
+ private ObjectName obsObjName;
+--- ./jdk/test/javax/management/mxbean/MXBeanFallbackTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/javax/management/mxbean/MXBeanFallbackTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -30,7 +30,7 @@
+ * @author Jaroslav Bachorik
+ * @run clean MXBeanFallbackTest
+ * @run build MXBeanFallbackTest
+- * @run main MXBeanFallbackTest
++ * @run main/othervm -Djdk.jmx.mbeans.allowNonPublic=true MXBeanFallbackTest
+ */
+
+ import javax.management.MBeanServer;
+@@ -40,7 +40,6 @@
+
+ public class MXBeanFallbackTest {
+ public static void main(String[] args) throws Exception {
+- System.setProperty("jdk.jmx.mbeans.allowNonPublic", "true");
+ testPrivateMXBean("Private", new Private());
+
+ if (failures == 0)
+--- ./jdk/test/javax/management/proxy/JMXProxyFallbackTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/javax/management/proxy/JMXProxyFallbackTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -36,7 +36,7 @@
+ * @author Jaroslav Bachorik
+ * @run clean JMXProxyFallbackTest
+ * @run build JMXProxyFallbackTest
+- * @run main JMXProxyFallbackTest
++ * @run main/othervm -Djdk.jmx.mbeans.allowNonPublic=true JMXProxyFallbackTest
+ */
+ public class JMXProxyFallbackTest {
+ private static interface PrivateMBean {
+@@ -56,7 +56,6 @@
+ private static int failures = 0;
+
+ public static void main(String[] args) throws Exception {
+- System.setProperty("jdk.jmx.mbeans.allowNonPublic", "true");
+ testPrivate(PrivateMBean.class);
+ testPrivate(PrivateMXBean.class);
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/net/ssl/TLSv12/ProtocolFilter.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,315 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++// SunJSSE does not support dynamic system properties, no way to re-use
++// system properties in samevm/agentvm mode.
++
++/*
++ * @test
++ * @bug 8052406
++ * @summary SSLv2Hello protocol may be filter out unexpectedly
++ * @run main/othervm ProtocolFilter
++ */
++
++import java.io.*;
++import java.net.*;
++import javax.net.ssl.*;
++
++public class ProtocolFilter {
++
++ /*
++ * =============================================================
++ * Set the various variables needed for the tests, then
++ * specify what tests to run on each side.
++ */
++
++ /*
++ * Should we run the client or server in a separate thread?
++ * Both sides can throw exceptions, but do you have a preference
++ * as to which side should be the main thread.
++ */
++ static boolean separateServerThread = false;
++
++ /*
++ * Where do we find the keystores?
++ */
++ static String pathToStores = "../../../../sun/security/ssl/etc";
++ static String keyStoreFile = "keystore";
++ static String trustStoreFile = "truststore";
++ static String passwd = "passphrase";
++
++ /*
++ * Is the server ready to serve?
++ */
++ volatile static boolean serverReady = false;
++
++ /*
++ * Turn on SSL debugging?
++ */
++ static boolean debug = false;
++
++ /*
++ * If the client or server is doing some kind of object creation
++ * that the other side depends on, and that thread prematurely
++ * exits, you may experience a hang. The test harness will
++ * terminate all hung threads after its timeout has expired,
++ * currently 3 minutes by default, but you might try to be
++ * smart about it....
++ */
++
++ /*
++ * Define the server side of the test.
++ *
++ * If the server prematurely exits, serverReady will be set to true
++ * to avoid infinite hangs.
++ */
++ void doServerSide() throws Exception {
++ SSLServerSocketFactory sslssf =
++ (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
++ SSLServerSocket sslServerSocket =
++ (SSLServerSocket) sslssf.createServerSocket(serverPort);
++
++ // Only enable cipher suites for TLS v1.2.
++ sslServerSocket.setEnabledCipherSuites(
++ new String[]{"TLS_RSA_WITH_AES_128_CBC_SHA256"});
++
++ serverPort = sslServerSocket.getLocalPort();
++
++ /*
++ * Signal Client, we're ready for his connect.
++ */
++ serverReady = true;
++
++ SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
++ InputStream sslIS = sslSocket.getInputStream();
++ OutputStream sslOS = sslSocket.getOutputStream();
++
++ sslIS.read();
++ sslOS.write(85);
++ sslOS.flush();
++
++ sslSocket.close();
++ }
++
++ /*
++ * Define the client side of the test.
++ *
++ * If the server prematurely exits, serverReady will be set to true
++ * to avoid infinite hangs.
++ */
++ void doClientSide() throws Exception {
++
++ /*
++ * Wait for server to get started.
++ */
++ while (!serverReady) {
++ Thread.sleep(50);
++ }
++
++ SSLSocketFactory sslsf =
++ (SSLSocketFactory) SSLSocketFactory.getDefault();
++ SSLSocket sslSocket = (SSLSocket)
++ sslsf.createSocket("localhost", serverPort);
++
++ // Enable all supported protocols, including SSLv2Hello.
++ sslSocket.setEnabledProtocols(sslSocket.getSupportedProtocols());
++
++ InputStream sslIS = sslSocket.getInputStream();
++ OutputStream sslOS = sslSocket.getOutputStream();
++
++ sslOS.write(280);
++ sslOS.flush();
++ sslIS.read();
++
++ sslSocket.close();
++ }
++
++ /*
++ * =============================================================
++ * The remainder is just support stuff
++ */
++
++ // use any free port by default
++ volatile int serverPort = 0;
++
++ volatile Exception serverException = null;
++ volatile Exception clientException = null;
++
++ public static void main(String[] args) throws Exception {
++ String keyFilename =
++ System.getProperty("test.src", ".") + "/" + pathToStores +
++ "/" + keyStoreFile;
++ String trustFilename =
++ System.getProperty("test.src", ".") + "/" + pathToStores +
++ "/" + trustStoreFile;
++
++ System.setProperty("javax.net.ssl.keyStore", keyFilename);
++ System.setProperty("javax.net.ssl.keyStorePassword", passwd);
++ System.setProperty("javax.net.ssl.trustStore", trustFilename);
++ System.setProperty("javax.net.ssl.trustStorePassword", passwd);
++
++ if (debug)
++ System.setProperty("javax.net.debug", "all");
++
++ /*
++ * Start the tests.
++ */
++ new ProtocolFilter();
++ }
++
++ Thread clientThread = null;
++ Thread serverThread = null;
++
++ /*
++ * Primary constructor, used to drive remainder of the test.
++ *
++ * Fork off the other side, then do your work.
++ */
++ ProtocolFilter() throws Exception {
++ Exception startException = null;
++ try {
++ if (separateServerThread) {
++ startServer(true);
++ startClient(false);
++ } else {
++ startClient(true);
++ startServer(false);
++ }
++ } catch (Exception e) {
++ startException = e;
++ }
++
++ /*
++ * Wait for other side to close down.
++ */
++ if (separateServerThread) {
++ if (serverThread != null) {
++ serverThread.join();
++ }
++ } else {
++ if (clientThread != null) {
++ clientThread.join();
++ }
++ }
++
++ /*
++ * When we get here, the test is pretty much over.
++ * Which side threw the error?
++ */
++ Exception local;
++ Exception remote;
++
++ if (separateServerThread) {
++ remote = serverException;
++ local = clientException;
++ } else {
++ remote = clientException;
++ local = serverException;
++ }
++
++ Exception exception = null;
++
++ /*
++ * Check various exception conditions.
++ */
++ if ((local != null) && (remote != null)) {
++ // If both failed, return the curthread's exception.
++ local.initCause(remote);
++ exception = local;
++ } else if (local != null) {
++ exception = local;
++ } else if (remote != null) {
++ exception = remote;
++ } else if (startException != null) {
++ exception = startException;
++ }
++
++ /*
++ * If there was an exception *AND* a startException,
++ * output it.
++ */
++ if (exception != null) {
++ if (exception != startException && startException != null) {
++ exception.addSuppressed(startException);
++ }
++ throw exception;
++ }
++
++ // Fall-through: no exception to throw!
++ }
++
++ void startServer(boolean newThread) throws Exception {
++ if (newThread) {
++ serverThread = new Thread() {
++ public void run() {
++ try {
++ doServerSide();
++ } catch (Exception e) {
++ /*
++ * Our server thread just died.
++ *
++ * Release the client, if not active already...
++ */
++ System.err.println("Server died...");
++ serverReady = true;
++ serverException = e;
++ }
++ }
++ };
++ serverThread.start();
++ } else {
++ try {
++ doServerSide();
++ } catch (Exception e) {
++ serverException = e;
++ } finally {
++ serverReady = true;
++ }
++ }
++ }
++
++ void startClient(boolean newThread) throws Exception {
++ if (newThread) {
++ clientThread = new Thread() {
++ public void run() {
++ try {
++ doClientSide();
++ } catch (Exception e) {
++ /*
++ * Our client thread just died.
++ */
++ System.err.println("Client died...");
++ clientException = e;
++ }
++ }
++ };
++ clientThread.start();
++ } else {
++ try {
++ doClientSide();
++ } catch (Exception e) {
++ clientException = e;
++ }
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/swing/DataTransfer/8059739/bug8059739.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,80 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/* @test
++ @bug 8059739
++ @summary Dragged and Dropped data is corrupted for two data types
++ @author Anton Nashatyrev
++*/
++
++import javax.swing.*;
++import java.awt.datatransfer.Clipboard;
++import java.awt.datatransfer.DataFlavor;
++import java.io.BufferedReader;
++import java.io.InputStream;
++import java.io.InputStreamReader;
++
++public class bug8059739 {
++
++ private static boolean passed = true;
++
++ public static void main(String[] args) throws Exception {
++ SwingUtilities.invokeAndWait(new Runnable() {
++ @Override
++ public void run() {
++ try {
++ runTest();
++ } catch (Exception e) {
++ e.printStackTrace();
++ passed = false;
++ }
++ }
++ });
++
++ if (!passed) {
++ throw new RuntimeException("Test FAILED.");
++ } else {
++ System.out.println("Passed.");
++ }
++ }
++
++ private static void runTest() throws Exception {
++ String testString = "my string";
++ JTextField tf = new JTextField(testString);
++ tf.selectAll();
++ Clipboard clipboard = new Clipboard("clip");
++ tf.getTransferHandler().exportToClipboard(tf, clipboard, TransferHandler.COPY);
++ DataFlavor[] dfs = clipboard.getAvailableDataFlavors();
++ for (DataFlavor df: dfs) {
++ String charset = df.getParameter("charset");
++ if (InputStream.class.isAssignableFrom(df.getRepresentationClass()) &&
++ charset != null) {
++ BufferedReader br = new BufferedReader(new InputStreamReader(
++ (InputStream) clipboard.getData(df), charset));
++ String s = br.readLine();
++ System.out.println("Content: '" + s + "'");
++ passed &= s.contains(testString);
++ }
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/swing/JColorChooser/8065098/JColorChooserDnDTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++import javax.swing.BorderFactory;
++import javax.swing.JColorChooser;
++import javax.swing.JFrame;
++import javax.swing.JPanel;
++import javax.swing.SwingUtilities;
++
++/*
++ * @bug 8065098
++ * @summary JColorChooser no longer supports drag and drop
++ * between two JVM instances
++ */
++public class JColorChooserDnDTest {
++
++ public static void main(String[] args) {
++ SwingUtilities.invokeLater(new Runnable() {
++
++ @Override
++ public void run() {
++ JFrame frame = new JFrame();
++ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
++ JPanel panel = new JPanel();
++ JColorChooser colorChooser = new JColorChooser();
++ colorChooser.setDragEnabled(true);
++ panel.setBorder(BorderFactory.createTitledBorder("JColorChoosers"));
++ panel.add(colorChooser);
++ frame.setContentPane(panel);
++ frame.pack();
++ frame.setVisible(true);
++ }
++ });
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/swing/JColorChooser/8065098/bug8065098.html Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,40 @@
++<!--
++ Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++
++ This code is free software; you can redistribute it and/or modify it
++ under the terms of the GNU General Public License version 2 only, as
++ published by the Free Software Foundation.
++
++ This code is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ version 2 for more details (a copy is included in the LICENSE file that
++ accompanied this code).
++
++ You should have received a copy of the GNU General Public License version
++ 2 along with this work; if not, write to the Free Software Foundation,
++ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++
++ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ or visit www.oracle.com if you need additional information or have any
++ questions.
++-->
++
++<html>
++ <body>
++ 1. Compile the java test JColorChooserDnDTest.java:
++ > <path-to-the-tested-jdk>/bin/javac JColorChooserDnDTest.java
++ 2. Run the first instance of the java test:
++ > <path-to-the-tested-jdk>/bin/java JColorChooserDnDTest
++ 3. Select a color in the color chooser
++ 4. Run the second instance of the java test:
++ > <path-to-the-tested-jdk>/bin/java JColorChooserDnDTest
++ 5. Drag and drop the selected color from the first color chooser
++ preview panel to the second color chooser preview panel
++ 6. If the color is dragged to the second color chooser then the test passes.
++
++ <applet width="500" height="1" code="bug8065098.class">
++ </applet>
++</body>
++</html>
+\ No newline at end of file
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/swing/JColorChooser/8065098/bug8065098.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++import javax.swing.JApplet;
++
++/*
++ * @test
++ * @bug 8065098
++ * @summary JColorChooser no longer supports drag and drop
++ * between two JVM instances
++ * @run applet/manual=yesno bug8065098.html
++ */
++public class bug8065098 extends JApplet {
++
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/swing/JComboBox/8057893/bug8057893.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,84 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.awt.EventQueue;
++import java.awt.Robot;
++import java.awt.Toolkit;
++import java.awt.event.ActionEvent;
++import java.awt.event.ActionListener;
++import java.awt.event.KeyEvent;
++import javax.swing.JComboBox;
++import javax.swing.JFrame;
++import javax.swing.WindowConstants;
++import sun.awt.SunToolkit;
++
++/**
++ * @test
++ * @bug 8057893
++ * @author Alexander Scherbatiy
++ * @summary JComboBox actionListener never receives "comboBoxEdited"
++ * from getActionCommand
++ * @run main bug8057893
++ */
++public class bug8057893 {
++
++ private static volatile boolean isComboBoxEdited = false;
++
++ public static void main(String[] args) throws Exception {
++ Robot robot = new Robot();
++ robot.setAutoDelay(50);
++ SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
++
++ EventQueue.invokeAndWait(() -> {
++ JFrame frame = new JFrame();
++ frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
++ JComboBox<String> comboBox = new JComboBox<>(new String[]{"one", "two"});
++ comboBox.setEditable(true);
++ comboBox.addActionListener(new ActionListener() {
++
++ @Override
++ public void actionPerformed(ActionEvent e) {
++ if ("comboBoxEdited".equals(e.getActionCommand())) {
++ isComboBoxEdited = true;
++ }
++ }
++ });
++ frame.add(comboBox);
++ frame.pack();
++ frame.setVisible(true);
++ comboBox.requestFocusInWindow();
++ });
++
++ toolkit.realSync();
++
++ robot.keyPress(KeyEvent.VK_A);
++ robot.keyRelease(KeyEvent.VK_A);
++ robot.keyPress(KeyEvent.VK_ENTER);
++ robot.keyRelease(KeyEvent.VK_ENTER);
++ toolkit.realSync();
++
++ if(!isComboBoxEdited){
++ throw new RuntimeException("ComboBoxEdited event is not fired!");
++ }
++ }
++}
+--- ./jdk/test/javax/swing/JComboBox/ConsumedEscTest/ConsumedEscTest.java Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,88 +0,0 @@
+-/*
+- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-import javax.swing.*;
+-import java.awt.event.ActionEvent;
+-import java.awt.event.KeyEvent;
+-import java.awt.Robot;
+-import java.awt.Toolkit;
+-import sun.awt.SunToolkit;
+-
+-/*
+- @test
+- @bug 8031485
+- @summary Combo box consuming escape and enter key events
+- @author Petr Pchelko
+- @run main ConsumedEscTest
+-*/
+-public class ConsumedEscTest {
+- private static volatile JFrame frame;
+- private static volatile boolean passed = false;
+-
+- public static void main(String... args) throws Exception {
+- try {
+- SwingUtilities.invokeAndWait(() -> {
+- frame = new JFrame();
+- JComboBox<String> combo = new JComboBox<>(new String[]{"one", "two", "three"});
+- JPanel panel = new JPanel();
+- panel.add(combo);
+- combo.requestFocusInWindow();
+- frame.setBounds(100, 150, 300, 100);
+- addAction(panel);
+- frame.add(panel);
+- frame.setVisible(true);
+- });
+-
+- Robot robot = new Robot();
+- robot.waitForIdle();
+- ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
+- robot.keyPress(KeyEvent.VK_ESCAPE);
+- robot.waitForIdle();
+- ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
+- robot.keyRelease(KeyEvent.VK_ESCAPE);
+- robot.waitForIdle();
+- ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
+- if (!passed) {
+- throw new RuntimeException("FAILED: ESC was consumed by combo box");
+- }
+- } finally {
+- if (frame != null) {
+- frame.dispose();
+- }
+- }
+- }
+-
+- private static void addAction(JComponent comp) {
+- KeyStroke k = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
+- Object actionKey = "cancel";
+- comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(k, actionKey);
+- Action cancelAction = new AbstractAction() {
+- @Override
+- public void actionPerformed(ActionEvent ev) {
+- passed = true;
+- }
+- };
+- comp.getActionMap().put(actionKey, cancelAction);
+- }
+-
+-}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/swing/JComboBox/ConsumedKeyTest/ConsumedKeyTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,94 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import javax.swing.*;
++import java.awt.event.ActionEvent;
++import java.awt.event.KeyEvent;
++import java.awt.Toolkit;
++import java.awt.Robot;
++import sun.awt.SunToolkit;
++
++/*
++ @test
++ @bug 8031485 8058193
++ @summary Combo box consuming escape and enter key events
++ @author Petr Pchelko
++ @run main ConsumedKeyTest
++*/
++public class ConsumedKeyTest {
++ private static volatile JFrame frame;
++ private static volatile boolean passed;
++
++ public static void main(String... args) throws Exception {
++ test(KeyEvent.VK_ESCAPE);
++ test(KeyEvent.VK_ENTER);
++ }
++
++ private static void test(final int key) throws Exception {
++ passed = false;
++ try {
++ SwingUtilities.invokeAndWait(() -> {
++ frame = new JFrame();
++ JComboBox<String> combo = new JComboBox<>(new String[]{"one", "two", "three"});
++ JPanel panel = new JPanel();
++ panel.add(combo);
++ combo.requestFocusInWindow();
++ frame.setBounds(100, 150, 300, 100);
++ addAction(panel, key);
++ frame.add(panel);
++ frame.setVisible(true);
++ });
++
++ Robot robot = new Robot();
++ robot.waitForIdle();
++ ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
++ robot.keyPress(key);
++ robot.waitForIdle();
++ ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
++ robot.keyRelease(key);
++ robot.waitForIdle();
++ ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
++ if (!passed) {
++ throw new RuntimeException("FAILED: " + KeyEvent.getKeyText(key) + " was consumed by combo box");
++ }
++ } finally {
++ if (frame != null) {
++ frame.dispose();
++ }
++ }
++
++ }
++
++ private static void addAction(JComponent comp, final int key) {
++ KeyStroke k = KeyStroke.getKeyStroke(key, 0);
++ Object actionKey = "cancel";
++ comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(k, actionKey);
++ Action cancelAction = new AbstractAction() {
++ @Override
++ public void actionPerformed(ActionEvent ev) {
++ passed = true;
++ }
++ };
++ comp.getActionMap().put(actionKey, cancelAction);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/swing/JFileChooser/8046391/bug8046391.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,63 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8046391
++ * @summary JFileChooser hangs if displayed in Windows L&F
++ * @author Alexey Ivanov
++ * @run main/othervm/timeout=10 bug8046391
++*/
++
++import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
++import sun.awt.OSInfo;
++import sun.awt.OSInfo.OSType;
++
++import javax.swing.JFileChooser;
++import javax.swing.SwingUtilities;
++import javax.swing.UIManager;
++import javax.swing.UnsupportedLookAndFeelException;
++
++public class bug8046391 {
++
++ public static void main(String[] args) throws Exception {
++ OSType type = OSInfo.getOSType();
++ if (type != OSType.WINDOWS) {
++ System.out.println("This test is for Windows only... skipping!");
++ return;
++ }
++
++ SwingUtilities.invokeAndWait(() -> {
++ try {
++ UIManager.setLookAndFeel(new WindowsLookAndFeel());
++ } catch (UnsupportedLookAndFeelException e) {
++ e.printStackTrace();
++ }
++ System.out.println("Creating JFileChooser...");
++ JFileChooser fileChooser = new JFileChooser();
++ System.out.println("Test passed: chooser = " + fileChooser);
++ });
++ // Test fails if creating JFileChooser hangs
++ }
++
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/swing/JFileChooser/FileFilterDescription/FileFilterDescription.html Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,40 @@
++<html>
++<!--
++ Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++
++ This code is free software; you can redistribute it and/or modify it
++ under the terms of the GNU General Public License version 2 only, as
++ published by the Free Software Foundation.
++
++ This code is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ version 2 for more details (a copy is included in the LICENSE file that
++ accompanied this code).
++
++ You should have received a copy of the GNU General Public License version
++ 2 along with this work; if not, write to the Free Software Foundation,
++ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++
++ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ or visit www.oracle.com if you need additional information or have any
++ questions.
++-->
++
++<!--
++ @test
++ @bug 8029536
++ @author Sergey Bylokhov
++ @run applet/manual=yesno FileFilterDescription.html
++-->
++
++<body>
++<applet code="FileFilterDescription.class" width=200 height=200></applet>
++Follow the instructions below.
++1) Check that current filter in the opened JFileChooser is a "CustomFileFilter".
++2) Close the JFileChooser.
++3) Test will repeat steps 1 - 2 for all supported look and feels.
++4) If it's true for all look and feels then the test passed, otherwise it failed.
++</body>
++</html>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/swing/JFileChooser/FileFilterDescription/FileFilterDescription.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,85 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.applet.Applet;
++import java.io.File;
++
++import javax.swing.JFileChooser;
++import javax.swing.SwingUtilities;
++import javax.swing.UIManager;
++import javax.swing.UnsupportedLookAndFeelException;
++import javax.swing.filechooser.FileFilter;
++
++public final class FileFilterDescription extends Applet {
++
++ @Override
++ public void init() {
++ }
++
++ @Override
++ public void start() {
++ try {
++ test();
++ } catch (Exception e) {
++ throw new RuntimeException(e);
++ }
++ }
++
++
++ public static void test() throws Exception {
++ final UIManager.LookAndFeelInfo[] infos = UIManager
++ .getInstalledLookAndFeels();
++ for (final UIManager.LookAndFeelInfo info : infos) {
++ SwingUtilities.invokeAndWait(() -> {
++ final JFileChooser chooser = new JFileChooser();
++ setLookAndFeel(info);
++ chooser.setAcceptAllFileFilterUsed(false);
++ chooser.setFileFilter(new CustomFileFilter());
++ SwingUtilities.updateComponentTreeUI(chooser);
++ chooser.showDialog(null, "Open");
++ });
++ }
++ }
++
++ private static void setLookAndFeel(final UIManager.LookAndFeelInfo info) {
++ try {
++ UIManager.setLookAndFeel(info.getClassName());
++ } catch (ClassNotFoundException | InstantiationException |
++ UnsupportedLookAndFeelException | IllegalAccessException e) {
++ throw new RuntimeException(e);
++ }
++ }
++
++ private static class CustomFileFilter extends FileFilter {
++
++ @Override
++ public boolean accept(final File f) {
++ return false;
++ }
++
++ @Override
++ public String getDescription() {
++ return "CustomFileFilter";
++ }
++ }
++}
+\ No newline at end of file
+--- ./jdk/test/javax/swing/JMenuItem/8031573/bug8031573.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/javax/swing/JMenuItem/8031573/bug8031573.java Wed Feb 04 12:14:43 2015 -0800
+@@ -28,7 +28,7 @@
+ import javax.swing.SwingUtilities;
+
+ /* @test
+- * @bug 8031573
++ * @bug 8031573 8040279
+ * @summary [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered
+ * in high resolution on Retina
+ * @author Alexander Scherbatiy
+--- ./jdk/test/javax/swing/JOptionPane/8024926/bug8024926.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/javax/swing/JOptionPane/8024926/bug8024926.java Wed Feb 04 12:14:43 2015 -0800
+@@ -31,7 +31,7 @@
+
+ /**
+ * @test
+- * @bug 8024926
++ * @bug 8024926 8040279
+ * @summary [macosx] AquaIcon HiDPI support
+ * @author Alexander Scherbatiy
+ * @run applet/manual=yesno bug8024926.html
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/swing/JRadioButton/8033699/bug8033699.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,255 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++ /*
++ * @test
++ * @library ../../regtesthelpers
++ * @build Util
++ * @bug 8033699
++ * @summary Incorrect radio button behavior when pressing tab key
++ * @author Vivi An
++ * @run main bug8033699
++ */
++
++import javax.swing.*;
++import javax.swing.event.*;
++import java.awt.event.*;
++import java.awt.*;
++import sun.awt.SunToolkit;
++
++public class bug8033699 {
++ private static Robot robot;
++ private static SunToolkit toolkit;
++
++ private static JButton btnStart;
++ private static ButtonGroup btnGrp;
++ private static JButton btnEnd;
++ private static JButton btnMiddle;
++ private static JRadioButton radioBtn1;
++ private static JRadioButton radioBtn2;
++ private static JRadioButton radioBtn3;
++ private static JRadioButton radioBtnSingle;
++
++ public static void main(String args[]) throws Throwable {
++ SwingUtilities.invokeAndWait(new Runnable() {
++ public void run() {
++ createAndShowGUI();
++ }
++ });
++
++ robot = new Robot();
++ Thread.sleep(100);
++
++ robot.setAutoDelay(100);
++ toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
++
++ // tab key test grouped radio button
++ runTest1();
++
++ // tab key test non-grouped radio button
++ runTest2();
++
++ // shift tab key test grouped and non grouped radio button
++ runTest3();
++
++ // left/up key test in grouped radio button
++ runTest4();
++
++ // down/right key test in grouped radio button
++ runTest5();
++
++ // tab from radio button in group to next component in the middle of button group layout
++ runTest6();
++
++ // tab to radio button in group from component in the middle of button group layout
++ runTest7();
++
++ // down key circle back to first button in grouped radio button
++ runTest8();
++ }
++
++ private static void createAndShowGUI() {
++ JFrame mainFrame = new JFrame("Bug 8033699 - 8 Tests for Grouped/Non Group Radio Buttons");
++
++ btnStart = new JButton("Start");
++ btnEnd = new JButton("End");
++ btnMiddle = new JButton("Middle");
++
++ JPanel box = new JPanel();
++ box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS));
++ box.setBorder(BorderFactory.createTitledBorder("Grouped Radio Buttons"));
++ radioBtn1 = new JRadioButton("A");
++ radioBtn2 = new JRadioButton("B");
++ radioBtn3 = new JRadioButton("C");
++
++ ButtonGroup btnGrp = new ButtonGroup();
++ btnGrp.add(radioBtn1);
++ btnGrp.add(radioBtn2);
++ btnGrp.add(radioBtn3);
++ radioBtn1.setSelected(true);
++
++ box.add(radioBtn1);
++ box.add(radioBtn2);
++ box.add(btnMiddle);
++ box.add(radioBtn3);
++
++ radioBtnSingle = new JRadioButton("Not Grouped");
++ radioBtnSingle.setSelected(true);
++
++ mainFrame.getContentPane().add(btnStart);
++ mainFrame.getContentPane().add(box);
++ mainFrame.getContentPane().add(radioBtnSingle);
++ mainFrame.getContentPane().add(btnEnd);
++
++ mainFrame.getRootPane().setDefaultButton(btnStart);
++ btnStart.requestFocus();
++
++ mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
++ mainFrame.setLayout(new BoxLayout(mainFrame.getContentPane(), BoxLayout.Y_AXIS));
++
++ mainFrame.setSize(300, 300);
++ mainFrame.setLocation(200, 200);
++ mainFrame.setVisible(true);
++ mainFrame.toFront();
++ }
++
++ // Radio button Group as a single component when traversing through tab key
++ private static void runTest1() throws Exception{
++ hitKey(robot, KeyEvent.VK_TAB);
++ hitKey(robot, KeyEvent.VK_TAB);
++
++ SwingUtilities.invokeAndWait(new Runnable() {
++ public void run() {
++ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtnSingle) {
++ System.out.println("Radio Button Group Go To Next Component through Tab Key failed");
++ throw new RuntimeException("Focus is not on Radio Button Single as Expected");
++ }
++ }
++ });
++ }
++
++ // Non-Grouped Radio button as a single component when traversing through tab key
++ private static void runTest2() throws Exception{
++ hitKey(robot, KeyEvent.VK_TAB);
++ SwingUtilities.invokeAndWait(new Runnable() {
++ public void run() {
++ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != btnEnd) {
++ System.out.println("Non Grouped Radio Button Go To Next Component through Tab Key failed");
++ throw new RuntimeException("Focus is not on Button End as Expected");
++ }
++ }
++ });
++ }
++
++ // Non-Grouped Radio button and Group Radio button as a single component when traversing through shift-tab key
++ private static void runTest3() throws Exception{
++ hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB);
++ hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB);
++ SwingUtilities.invokeAndWait(new Runnable() {
++ public void run() {
++ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn3) {
++ System.out.println("Radio button Group/Non Grouped Radio Button SHIFT-Tab Key Test failed");
++ throw new RuntimeException("Focus is not on Radio Button C as Expected");
++ }
++ }
++ });
++ }
++
++ // Using arrow key to move focus in radio button group
++ private static void runTest4() throws Exception{
++ hitKey(robot, KeyEvent.VK_UP);
++ hitKey(robot, KeyEvent.VK_LEFT);
++ SwingUtilities.invokeAndWait(new Runnable() {
++ public void run() {
++ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn1) {
++ System.out.println("Radio button Group UP/LEFT Arrow Key Move Focus Failed");
++ throw new RuntimeException("Focus is not on Radio Button A as Expected");
++ }
++ }
++ });
++ }
++
++ private static void runTest5() throws Exception{
++ hitKey(robot, KeyEvent.VK_DOWN);
++ hitKey(robot, KeyEvent.VK_RIGHT);
++ SwingUtilities.invokeAndWait(new Runnable() {
++ public void run() {
++ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn3) {
++ System.out.println("Radio button Group Left/Up Arrow Key Move Focus Failed");
++ throw new RuntimeException("Focus is not on Radio Button C as Expected");
++ }
++ }
++ });
++ }
++
++ private static void runTest6() throws Exception{
++ hitKey(robot, KeyEvent.VK_DOWN);
++ hitKey(robot, KeyEvent.VK_DOWN);
++ SwingUtilities.invokeAndWait(new Runnable() {
++ public void run() {
++ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn2) {
++ System.out.println("Radio button Group Circle Back To First Button Test");
++ throw new RuntimeException("Focus is not on Radio Button A as Expected");
++ }
++ }
++ });
++ }
++
++ private static void runTest7() throws Exception{
++ hitKey(robot, KeyEvent.VK_TAB);
++ SwingUtilities.invokeAndWait(new Runnable() {
++ public void run() {
++ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != btnMiddle) {
++ System.out.println("Separate Component added in button group layout");
++ throw new RuntimeException("Focus is not on Middle Button as Expected");
++ }
++ }
++ });
++ }
++
++ private static void runTest8() throws Exception{
++ hitKey(robot, KeyEvent.VK_TAB);
++ SwingUtilities.invokeAndWait(new Runnable() {
++ public void run() {
++ if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn3) {
++ System.out.println("Separate Component added in button group layout");
++ throw new RuntimeException("Focus is not on Radio Button C as Expected");
++ }
++ }
++ });
++ }
++
++ private static void hitKey(Robot robot, int keycode) {
++ robot.keyPress(keycode);
++ robot.keyRelease(keycode);
++ toolkit.realSync();
++ }
++
++ private static void hitKey(Robot robot, int mode, int keycode) {
++ robot.keyPress(mode);
++ robot.keyPress(keycode);
++ robot.keyRelease(mode);
++ robot.keyRelease(keycode);
++ toolkit.realSync();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/swing/JTabbedPane/7170310/bug7170310.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,124 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import java.awt.Component;
++import java.awt.Dimension;
++import java.awt.Rectangle;
++import java.awt.Toolkit;
++import javax.swing.JComponent;
++import javax.swing.JFrame;
++import javax.swing.JPanel;
++import javax.swing.JTabbedPane;
++import javax.swing.JViewport;
++import javax.swing.SwingUtilities;
++import javax.swing.UIManager;
++import javax.swing.plaf.metal.MetalLookAndFeel;
++
++import sun.awt.SunToolkit;
++
++/**
++ * @test
++ * @bug 7170310
++ * @author Alexey Ivanov
++ * @summary Selected tab should be scrolled into view.
++ * @run main bug7170310
++ */
++public class bug7170310 {
++ private static final int TABS_NUMBER = 3;
++
++ private static volatile JTabbedPane tabbedPane;
++ private static volatile int count = 1;
++
++ private static volatile JFrame frame;
++
++ private static volatile Exception exception = null;
++
++ public static void main(String[] args) throws Exception {
++ try {
++ UIManager.setLookAndFeel(new MetalLookAndFeel());
++ SwingUtilities.invokeAndWait(bug7170310::createAndShowUI);
++
++ SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
++ toolkit.realSync();
++
++ for (int i = 0; i < TABS_NUMBER; i++) {
++ SwingUtilities.invokeAndWait(bug7170310::addTab);
++ toolkit.realSync();
++ }
++
++ SwingUtilities.invokeAndWait(bug7170310::check);
++
++ if (exception != null) {
++ System.out.println("Test failed: " + exception.getMessage());
++ throw exception;
++ } else {
++ System.out.printf("Test passed");
++ }
++ } finally {
++ frame.dispose();
++ }
++ }
++
++ private static void createAndShowUI() {
++ frame = new JFrame("bug7170310");
++ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
++ frame.setSize(200, 100);
++
++ tabbedPane = new JTabbedPane();
++ tabbedPane.addTab("Main Tab", new JPanel());
++
++ tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
++
++ frame.getContentPane().add(tabbedPane);
++ frame.setVisible(true);
++ }
++
++ private static void addTab() {
++ tabbedPane.addTab("Added Tab " + count++, new JPanel());
++ tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
++ }
++
++ private static void check() {
++ try {
++ JViewport vp = null;
++ for (Component c : tabbedPane.getComponents()) {
++ if (c instanceof JViewport) {
++ vp = (JViewport) c;
++ break;
++ }
++ }
++
++ JComponent v = (JComponent) vp.getView();
++ Rectangle vr = vp.getViewRect();
++ Dimension vs = v.getSize();
++
++ // The tab view must be scrolled to the end so that the last tab is visible
++ if (vs.width != (vr.x + vr.width)) {
++ throw new RuntimeException("tabScroller.tabPanel view is positioned incorrectly: "
++ + vs.width + " vs " + (vr.x + vr.width));
++ }
++ } catch (Exception e) {
++ exception = e;
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/swing/text/View/8048110/bug8048110.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,121 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/* @test
++ * @bug 8048110
++ * @summary Using tables in JTextPane leads to infinite loop in FlowLayout.layoutRow
++ * @author Dmitry Markov
++ * @run main bug8048110
++ */
++
++import sun.awt.SunToolkit;
++
++import javax.swing.*;
++import javax.swing.text.Element;
++import javax.swing.text.html.HTMLDocument;
++import javax.swing.text.html.HTMLEditorKit;
++import java.awt.*;
++
++public class bug8048110 {
++ private static SunToolkit toolkit = (SunToolkit)Toolkit.getDefaultToolkit();
++ private static Object lock = new Object();
++ private static boolean isRealSyncPerformed = false;
++ private static final String htmlText = "<table width=\"100%\" cellpadding=\"10\" cellspacing=\"5\" align=\"center\">" +
++ "<tr><th align=\"left\" bgcolor=\"#bec3c6\">Devices</th><th align=\"left\" bgcolor=\"#bec3c6\">State</th></tr>" +
++ "<tr><td align=\"left\" bgcolor=\"#bec3c6\">PC</td><td align=\"left\" bgcolor=\"#46a055\">Ok</td></tr></table>";
++
++ public static void main(String[] args) throws Exception {
++ SwingUtilities.invokeAndWait(new Runnable() {
++ @Override
++ public void run() {
++ createAndShowGUI();
++ }
++ });
++
++ Thread thread = new Thread() {
++ @Override
++ public void run() {
++ toolkit.realSync();
++ synchronized (lock) {
++ isRealSyncPerformed = true;
++ lock.notifyAll();
++ }
++ }
++ };
++ thread.start();
++
++ synchronized (lock) {
++ if (!isRealSyncPerformed) {
++ lock.wait(5000);
++ }
++ }
++
++ if (!isRealSyncPerformed) {
++ throw new RuntimeException("Test Failed!");
++ }
++ }
++
++ private static void createAndShowGUI() {
++ try {
++ UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
++ } catch (Exception ex) {
++ throw new RuntimeException(ex);
++ }
++ HTMLEditorKit editorKit = new HTMLEditorKit();
++ JTextPane textPane = new JTextPane();
++ textPane.setContentType("text/html");
++ textPane.setEditorKit(editorKit);
++ textPane.setText("Initial text without table");
++
++ JFrame frame = new JFrame("bug8048110");
++ frame.getContentPane().add(textPane, BorderLayout.CENTER);
++ frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
++ frame.setSize(500, 200);
++ frame.setVisible(true);
++
++ textPane.setDocument(textPane.getEditorKit().createDefaultDocument());
++ HTMLDocument htmlDocument = (HTMLDocument) textPane.getDocument();
++ Element firstParagraph = findFirstElement(textPane.getDocument().getDefaultRootElement(), "p");
++
++ try {
++ htmlDocument.setInnerHTML(firstParagraph, htmlText);
++ } catch (Exception ex) {
++ throw new RuntimeException(ex);
++ }
++ }
++
++ private static Element findFirstElement(Element e, String name) {
++ String elementName = e.getName();
++ if (elementName != null && elementName.equalsIgnoreCase(name)) {
++ return e;
++ }
++ for (int i = 0; i < e.getElementCount(); i++) {
++ Element result = findFirstElement(e.getElement(i), name);
++ if (result != null) {
++ return result;
++ }
++ }
++ return null;
++ }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/swing/text/html/HTMLDocument/8058120/bug8058120.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,109 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/* @test
++ * @bug 8058120
++ * @summary Rendering / caret errors with HTMLDocument
++ * @author Dmitry Markov
++ * @run main bug8058120
++ */
++
++import sun.awt.SunToolkit;
++
++import javax.swing.*;
++import javax.swing.text.Element;
++import javax.swing.text.html.HTML;
++import javax.swing.text.html.HTMLDocument;
++import javax.swing.text.html.HTMLEditorKit;
++import java.awt.*;
++
++public class bug8058120 {
++ private static SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
++ private static HTMLDocument document = null;
++ private static final String text = "<p id = 'ab'>ab</p>";
++ private static final String textToInsert = "c";
++
++ public static void main(String[] args) {
++ SwingUtilities.invokeLater(new Runnable() {
++ @Override
++ public void run() {
++ createAndShowGUI();
++ }
++ });
++
++ toolkit.realSync();
++
++ SwingUtilities.invokeLater(new Runnable() {
++ @Override
++ public void run() {
++ try {
++ document.insertAfterEnd(document.getElement("ab"), textToInsert);
++ } catch (Exception ex) {
++ throw new RuntimeException(ex);
++ }
++ }
++ });
++
++ toolkit.realSync();
++
++ SwingUtilities.invokeLater(new Runnable() {
++ @Override
++ public void run() {
++ Element parent = document.getElement("ab").getParentElement();
++ int count = parent.getElementCount();
++ if (count != 2) {
++ throw new RuntimeException("Test Failed! Unexpected Element count = "+count);
++ }
++ Element insertedElement = parent.getElement(count - 1);
++ if (!HTML.Tag.IMPLIED.toString().equals(insertedElement.getName())) {
++ throw new RuntimeException("Test Failed! Inserted text is not wrapped by " + HTML.Tag.IMPLIED + " tag");
++ }
++ }
++ });
++ }
++
++ private static void createAndShowGUI() {
++ try {
++ UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
++ } catch (Exception ex) {
++ throw new RuntimeException(ex);
++ }
++
++ JFrame frame = new JFrame("bug8058120");
++ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
++
++ JEditorPane editorPane = new JEditorPane();
++ editorPane.setContentType("text/html");
++ editorPane.setEditorKit(new HTMLEditorKit());
++
++ document = (HTMLDocument) editorPane.getDocument();
++
++ editorPane.setText(text);
++
++ frame.add(editorPane);
++ frame.setSize(200, 200);
++ frame.setVisible(true);
++ }
++}
++
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/xml/jaxp/common/8032908/TestFunc.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++import org.w3c.dom.Node;
++
++public class TestFunc {
++
++ public static String test(Node node) {
++ String s = node.getTextContent();
++ return s;
++ }
++
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/xml/jaxp/common/8032908/XSLT.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8032908
++ * @summary Test if Node.getTextContent() function correctly returns children
++ * content
++ * @compile TestFunc.java XSLT.java
++ * @run main/othervm XSLT
++ */
++import java.io.ByteArrayOutputStream;
++import javax.xml.transform.Transformer;
++import javax.xml.transform.TransformerException;
++import javax.xml.transform.TransformerFactory;
++import javax.xml.transform.stream.StreamResult;
++import javax.xml.transform.stream.StreamSource;
++
++public class XSLT {
++
++ static final String XMLTOTRANSFORM = "/in.xml";
++ static final String XSLTRANSFORMER = "/test.xsl";
++ static final String EXPECTEDRESULT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>ABCDEFG";
++
++ public static void main(String[] args) throws TransformerException {
++ ByteArrayOutputStream resStream = new ByteArrayOutputStream();
++ TransformerFactory trf = TransformerFactory.newInstance();
++ Transformer tr = trf.newTransformer(new StreamSource(System.getProperty("test.src", ".") + XSLTRANSFORMER));
++ tr.transform(new StreamSource(System.getProperty("test.src", ".") + XMLTOTRANSFORM), new StreamResult(resStream));
++ System.out.println("Transformation completed. Result:" + resStream.toString());
++ if (!resStream.toString().equals(EXPECTEDRESULT)) {
++ throw new RuntimeException("Incorrect transformation result");
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/xml/jaxp/common/8032908/in.xml Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,2 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<root><elem><level2_0>ABCD</level2_0><level2_1>EFG</level2_1></elem></root>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/xml/jaxp/common/8032908/test.xsl Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,8 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<xsl:transform exclude-result-prefixes="cscdt_ufunc" version="1.0"
++ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
++ xmlns:cscdt_ufunc="http://xml.apache.org/xalan/java">
++ <xsl:template match="elem">
++ <xsl:value-of select="cscdt_ufunc:TestFunc.test(.)" />
++ </xsl:template>
++</xsl:transform>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/javax/xml/jaxp/validation/8049514/FeaturePropagationTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,71 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++
++/**
++ * @test
++ * @bug 8049514
++ * @summary verifies that feature set on the factory is propagated properly
++ * to the validator
++ * @run main/othervm FeaturePropagationTest
++ */
++
++
++import java.io.ByteArrayInputStream;
++import java.io.InputStreamReader;
++import javax.xml.XMLConstants;
++import javax.xml.transform.stream.StreamSource;
++import javax.xml.validation.*;
++
++/**
++ * JDK-8049514
++ *
++ * FEATURE_SECURE_PROCESSING can not be turned off on a validator through
++ * SchemaFactory
++ */
++public class FeaturePropagationTest {
++
++ static String xsd = "<?xml version='1.0'?>\n" + "<schema xmlns='http://www.w3.org/2001/XMLSchema'\n"
++ + " xmlns:test='jaxp13_test'\n"
++ + " targetNamespace='jaxp13_test'\n"
++ + " elementFormDefault='qualified'>\n"
++ + " <element name='test' type='string'/>\n"
++ + "</schema>\n";
++
++ public static void main(String[] args) throws Exception {
++ InputStreamReader reader = new InputStreamReader(new ByteArrayInputStream(xsd.getBytes()));
++ StreamSource xsdSource = new StreamSource(reader);
++
++ SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
++ schemaFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false);
++ Schema schema = null;
++ schema = schemaFactory.newSchema(xsdSource);
++
++ Validator validator = schema.newValidator();
++
++ if (validator.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)) {
++ throw new RuntimeException("Feature set on the factory is not inherited!");
++ }
++
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/jdk/net/Sockets/SupportedOptions.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8062744
++ * @run main SupportedOptions
++ */
++
++import java.net.*;
++import java.io.IOException;
++import jdk.net.*;
++
++public class SupportedOptions {
++
++ public static void main(String[] args) throws Exception {
++ if (!Sockets.supportedOptions(ServerSocket.class)
++ .contains(StandardSocketOptions.IP_TOS)) {
++ throw new RuntimeException("Test failed");
++ }
++ // Now set the option
++ ServerSocket ss = new ServerSocket();
++ Sockets.setOption(ss, java.net.StandardSocketOptions.IP_TOS, 128);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/lib/testlibrary/jdk/testlibrary/TimeLimitedRunner.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,86 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package jdk.testlibrary;
++
++import java.util.Objects;
++import java.util.concurrent.Callable;
++
++/**
++ * Auxiliary class to run target w/ given timeout.
++ */
++public class TimeLimitedRunner implements Callable<Void> {
++ private final long stoptime;
++ private final long timeout;
++ private final double factor;
++ private final Callable<Boolean> target;
++
++ /**
++ * @param timeout a timeout. zero means no time limitation
++ * @param factor a multiplier used to estimate next iteration time
++ * @param target a target to run
++ * @throws NullPointerException if target is null
++ * @throws IllegalArgumentException if timeout is negative or
++ factor isn't positive
++ */
++ public TimeLimitedRunner(long timeout, double factor,
++ Callable<Boolean> target) {
++ Objects.requireNonNull(target, "target must not be null");
++ if (timeout < 0) {
++ throw new IllegalArgumentException("timeout[" + timeout + "] < 0");
++ }
++ if (factor <= 0d) {
++ throw new IllegalArgumentException("factor[" + factor + "] <= 0");
++ }
++ this.stoptime = System.currentTimeMillis() + timeout;
++ this.timeout = timeout;
++ this.factor = factor;
++ this.target = target;
++ }
++
++ /**
++ * Runs @{linkplan target} while it returns true and timeout isn't exceeded
++ */
++ @Override
++ public Void call() throws Exception {
++ long maxDuration = 0L;
++ long iterStart = System.currentTimeMillis();
++ if (timeout != 0 && iterStart > stoptime) {
++ return null;
++ }
++ while (target.call()) {
++ if (timeout != 0) {
++ long iterDuration = System.currentTimeMillis() - iterStart;
++ maxDuration = Math.max(maxDuration, iterDuration);
++ iterStart = System.currentTimeMillis();
++ if (iterStart + (maxDuration * factor) > stoptime) {
++ System.out.println("Not enough time to continue execution. "
++ + "Interrupted.");
++ break;
++ }
++ }
++ }
++ return null;
++ }
++
++}
+--- ./jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java Wed Feb 04 12:14:43 2015 -0800
+@@ -35,6 +35,7 @@
+ import java.util.Collections;
+ import java.util.regex.Pattern;
+ import java.util.regex.Matcher;
++import java.util.concurrent.TimeUnit;
+
+ /**
+ * Common library for various test helper functions.
+@@ -67,6 +68,12 @@
+ TIMEOUT_FACTOR = Double.parseDouble(toFactor);
+ }
+
++ /**
++ * Returns the value of JTREG default test timeout in milliseconds
++ * converted to {@code long}.
++ */
++ public static final long DEFAULT_TEST_TIMEOUT = TimeUnit.SECONDS.toMillis(120);
++
+ private Utils() {
+ // Private constructor to prevent class instantiation
+ }
+@@ -259,4 +266,14 @@
+ throw t;
+ }
+ }
++
++ /**
++ * Adjusts the provided timeout value for the TIMEOUT_FACTOR
++ * @param tOut the timeout value to be adjusted
++ * @return The timeout value adjusted for the value of "test.timeout.factor"
++ * system property
++ */
++ public static long adjustTimeout(long tOut) {
++ return Math.round(tOut * Utils.TIMEOUT_FACTOR);
++ }
+ }
+--- ./jdk/test/lib/testlibrary/jsr292/com/oracle/testlibrary/jsr292/Helper.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/lib/testlibrary/jsr292/com/oracle/testlibrary/jsr292/Helper.java Wed Feb 04 12:14:43 2015 -0800
+@@ -52,7 +52,7 @@
+ public static final long TEST_LIMIT;
+ static {
+ String str = System.getProperty("testLimit");
+- TEST_LIMIT = str != null ? Long.parseUnsignedLong(str) : 2_000L;
++ TEST_LIMIT = str != null ? Long.parseUnsignedLong(str) : 2000L;
+ System.out.printf("-DtestLimit=%d%n", TEST_LIMIT);
+ }
+
+@@ -116,6 +116,48 @@
+ return size <= lag ? null : calledLog.get(size - lag - 1);
+ }
+
++ public static List<Class<?>> randomClasses(Class<?>[] classes, int size) {
++ List<Class<?>> result = new ArrayList<>(size);
++ for (int i = 0; i < size; ++i) {
++ result.add(classes[RNG.nextInt(classes.length)]);
++ }
++ return result;
++ }
++
++ public static List<Class<?>> getParams(List<Class<?>> classes,
++ boolean isVararg, int argsCount) {
++ boolean unmodifiable = true;
++ List<Class<?>> result = classes.subList(0,
++ Math.min(argsCount, (MAX_ARITY / 2) - 1));
++ int extra = 0;
++ if (argsCount >= MAX_ARITY / 2) {
++ result = new ArrayList<>(result);
++ unmodifiable = false;
++ extra = (int) result.stream().filter(Helper::isDoubleCost).count();
++ int i = result.size();
++ while (result.size() + extra < argsCount) {
++ Class<?> aClass = classes.get(i);
++ if (Helper.isDoubleCost(aClass)) {
++ ++extra;
++ if (result.size() + extra >= argsCount) {
++ break;
++ }
++ }
++ result.add(aClass);
++ }
++ }
++ if (isVararg && result.size() > 0) {
++ if (unmodifiable) {
++ result = new ArrayList<>(result);
++ }
++ int last = result.size() - 1;
++ Class<?> aClass = result.get(last);
++ aClass = Array.newInstance(aClass, 2).getClass();
++ result.set(last, aClass);
++ }
++ return result;
++ }
++
+ public static MethodHandle addTrailingArgs(MethodHandle target, int nargs,
+ List<Class<?>> classes) {
+ int targetLen = target.type().parameterCount();
+@@ -230,7 +272,7 @@
+ return randomArgs(params.toArray(new Class<?>[params.size()]));
+ }
+
+- private static Object castToWrapper(Object value, Class<?> dst) {
++ public static Object castToWrapper(Object value, Class<?> dst) {
+ Object wrap = null;
+ if (value instanceof Number) {
+ wrap = castToWrapperOrNull(((Number) value).longValue(), dst);
+@@ -268,7 +310,7 @@
+ if (dst == byte.class || dst == Byte.class) {
+ return (byte) (value);
+ }
+- if (dst == boolean.class || dst == boolean.class) {
++ if (dst == boolean.class || dst == Boolean.class) {
+ return ((value % 29) & 1) == 0;
+ }
+ return null;
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest1.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,115 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/* @test
++ @bug 8058473
++ @summary "Comparison method violates its general contract" when using Clipboard
++ Ensure that DataTransferer.DataFlavorComparator conforms to Comparator contract
++ @author Anton Nashatyrev
++ @run main DataFlavorComparatorTest1
++*/
++import sun.awt.datatransfer.DataTransferer;
++
++import java.awt.datatransfer.DataFlavor;
++import java.util.Comparator;
++
++public class DataFlavorComparatorTest1 {
++
++ public static void main(String[] args) throws Exception {
++ String[] mimes = new String[] {
++ "text/plain",
++ "text/plain; charset=unicode",
++ "text/plain; charset=cp1251",
++ "text/plain; charset=unicode; class=java.io.InputStream",
++ "text/plain; charset=unicode; class=java.io.Serializable",
++ "text/plain; charset=unicode; class=java.lang.Object",
++ "text/plain; class=java.lang.String",
++ "text/plain; class=java.io.Reader",
++ "text/plain; class=java.lang.Object",
++ "text/html",
++ "text/html; charset=unicode",
++ "text/html; charset=cp1251",
++ "text/html; charset=unicode; class=java.io.InputStream",
++ "text/html; charset=unicode; class=java.io.Serializable",
++ "text/html; charset=unicode; class=java.lang.Object",
++ "text/html; class=java.lang.String",
++ "text/html; class=java.io.Reader",
++ "text/html; class=java.lang.Object",
++ "text/unknown",
++ "text/unknown; charset=unicode",
++ "text/unknown; charset=cp1251",
++ "text/unknown; charset=unicode; class=java.io.InputStream",
++ "text/unknown; charset=unicode; class=java.io.Serializable",
++ "text/unknown; charset=unicode; class=java.lang.Object",
++ "text/unknown; class=java.lang.String",
++ "text/unknown; class=java.io.Reader",
++ "text/unknown; class=java.lang.Object",
++ "application/unknown; class=java.io.InputStream",
++ "application/unknown; class=java.lang.Object",
++ "application/unknown",
++ "application/x-java-jvm-local-objectref; class=java.io.InputStream",
++ "application/x-java-jvm-local-objectref; class=java.lang.Object",
++ "application/x-java-jvm-local-objectref",
++ "unknown/flavor",
++ "unknown/flavor; class=java.io.InputStream",
++ "unknown/flavor; class=java.lang.Object",
++ };
++
++ DataFlavor[] flavors = new DataFlavor[mimes.length];
++ for (int i = 0; i < flavors.length; i++) {
++ flavors[i] = new DataFlavor(mimes[i]);
++ }
++
++ testComparator(new DataTransferer.DataFlavorComparator(true), flavors);
++ testComparator(new DataTransferer.DataFlavorComparator(false), flavors);
++
++ }
++
++ private static void testComparator(Comparator cmp, DataFlavor[] flavs)
++ throws ClassNotFoundException {
++
++ for (DataFlavor x: flavs) {
++ for (DataFlavor y: flavs) {
++ if (Math.signum(cmp.compare(x,y)) != -Math.signum(cmp.compare(y,x))) {
++ throw new RuntimeException("Antisymmetry violated: " + x + ", " + y);
++ }
++ if (cmp.compare(x,y) == 0 && !x.equals(y)) {
++ throw new RuntimeException("Equals rule violated: " + x + ", " + y);
++ }
++ for (DataFlavor z: flavs) {
++ if (cmp.compare(x,y) == 0) {
++ if (Math.signum(cmp.compare(x, z)) != Math.signum(cmp.compare(y, z))) {
++ throw new RuntimeException("Transitivity (1) violated: " + x + ", " + y + ", " + z);
++ }
++ } else {
++ if (Math.signum(cmp.compare(x, y)) == Math.signum(cmp.compare(y, z))) {
++ if (Math.signum(cmp.compare(x, y)) != Math.signum(cmp.compare(x, z))) {
++ throw new RuntimeException("Transitivity (2) violated: " + x + ", " + y + ", " + z);
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++}
+--- ./jdk/test/sun/awt/dnd/8024061/bug8024061.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/awt/dnd/8024061/bug8024061.java Wed Feb 04 12:14:43 2015 -0800
+@@ -277,9 +277,6 @@
+ try {
+ Transferable t = dtde.getTransferable();
+ Object data = t.getTransferData(DropObjectFlavor);
+- if (data != null) {
+- throw new Exception("getTransferData returned non-null");
+- }
+ } catch (Exception e) {
+ dragEnterException = e;
+ e.printStackTrace();
+--- ./jdk/test/sun/awt/image/bug8038000.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/awt/image/bug8038000.java Wed Feb 04 12:14:43 2015 -0800
+@@ -23,11 +23,13 @@
+
+ /**
+ * @test
+- * @bug 8038000
++ * @bug 8038000 8047066
+ *
+ * @summary Verifies that we could create different type of Rasters with height 1
+ * and strideline which exceeds raster width.
+ * Also checks that a set of RasterOp work correctly with such kind of Rasters.
++ * For 8047066 verifies that ColorConvertOp could process
++ * Raster (ByteBuffer + SinglePixelPackedSampleModel)
+ *
+ * @run main bug8038000
+ */
+--- ./jdk/test/sun/invoke/util/ValueConversionsTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/invoke/util/ValueConversionsTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -25,11 +25,11 @@
+
+ import sun.invoke.util.ValueConversions;
+ import sun.invoke.util.Wrapper;
++import java.lang.invoke.MethodHandles;
+ import java.lang.invoke.MethodType;
+ import java.lang.invoke.MethodHandle;
+ import java.io.Serializable;
+ import java.util.Arrays;
+-import java.util.Collections;
+ import org.junit.Test;
+ import static org.junit.Assert.*;
+
+@@ -37,24 +37,13 @@
+ * @summary unit tests for value-type conversion utilities
+ * @compile -XDignore.symbol.file ValueConversionsTest.java
+ * @run junit/othervm test.sun.invoke.util.ValueConversionsTest
+- * @run junit/othervm
+- * -DValueConversionsTest.MAX_ARITY=255 -DValueConversionsTest.START_ARITY=250
+- * test.sun.invoke.util.ValueConversionsTest
+ */
+
+-// This might take a while and burn lots of metadata:
+-// @run junit/othervm -DValueConversionsTest.MAX_ARITY=255 -DValueConversionsTest.EXHAUSTIVE=true test.sun.invoke.util.ValueConversionsTest
+-
+ /**
+ *
+ * @author jrose
+ */
+ public class ValueConversionsTest {
+- private static final Class<?> CLASS = ValueConversionsTest.class;
+- private static final int MAX_ARITY = Integer.getInteger(CLASS.getSimpleName()+".MAX_ARITY", 40);
+- private static final int START_ARITY = Integer.getInteger(CLASS.getSimpleName()+".START_ARITY", 0);
+- private static final boolean EXHAUSTIVE = Boolean.getBoolean(CLASS.getSimpleName()+".EXHAUSTIVE");
+-
+ @Test
+ public void testUnbox() throws Throwable {
+ testUnbox(false);
+@@ -66,9 +55,7 @@
+ }
+
+ private void testUnbox(boolean doCast) throws Throwable {
+- //System.out.println("unbox");
+ for (Wrapper dst : Wrapper.values()) {
+- //System.out.println(dst);
+ for (Wrapper src : Wrapper.values()) {
+ testUnbox(doCast, dst, src);
+ }
+@@ -78,6 +65,7 @@
+ private void testUnbox(boolean doCast, Wrapper dst, Wrapper src) throws Throwable {
+ boolean expectThrow = !doCast && !dst.isConvertibleFrom(src);
+ if (dst == Wrapper.OBJECT || src == Wrapper.OBJECT) return; // must have prims
++ if (dst == Wrapper.VOID || src == Wrapper.VOID ) return; // must have values
+ if (dst == Wrapper.OBJECT)
+ expectThrow = false; // everything (even VOID==null here) converts to OBJECT
+ try {
+@@ -91,9 +79,9 @@
+ }
+ MethodHandle unboxer;
+ if (doCast)
+- unboxer = ValueConversions.unboxCast(dst.primitiveType());
++ unboxer = ValueConversions.unboxCast(dst);
+ else
+- unboxer = ValueConversions.unbox(dst.primitiveType());
++ unboxer = ValueConversions.unboxWiden(dst);
+ Object expResult = (box == null) ? dst.zero() : dst.wrap(box);
+ Object result = null;
+ switch (dst) {
+@@ -104,9 +92,7 @@
+ case CHAR: result = (char) unboxer.invokeExact(box); break;
+ case BYTE: result = (byte) unboxer.invokeExact(box); break;
+ case SHORT: result = (short) unboxer.invokeExact(box); break;
+- case OBJECT: result = (Object) unboxer.invokeExact(box); break;
+ case BOOLEAN: result = (boolean) unboxer.invokeExact(box); break;
+- case VOID: result = null; unboxer.invokeExact(box); break;
+ }
+ if (expectThrow) {
+ expResult = "(need an exception)";
+@@ -123,25 +109,23 @@
+
+ @Test
+ public void testBox() throws Throwable {
+- //System.out.println("box");
+ for (Wrapper w : Wrapper.values()) {
+- if (w == Wrapper.VOID) continue; // skip this; no unboxed form
+- //System.out.println(w);
++ if (w == Wrapper.VOID) continue; // skip this; no unboxed form
++ if (w == Wrapper.OBJECT) continue; // skip this; already unboxed
+ for (int n = -5; n < 10; n++) {
+ Object box = w.wrap(n);
+- MethodHandle boxer = ValueConversions.box(w.primitiveType());
++ MethodHandle boxer = ValueConversions.boxExact(w);
+ Object expResult = box;
+ Object result = null;
+ switch (w) {
+- case INT: result = boxer.invokeExact(/*int*/n); break;
+- case LONG: result = boxer.invokeExact((long)n); break;
+- case FLOAT: result = boxer.invokeExact((float)n); break;
+- case DOUBLE: result = boxer.invokeExact((double)n); break;
+- case CHAR: result = boxer.invokeExact((char)n); break;
+- case BYTE: result = boxer.invokeExact((byte)n); break;
+- case SHORT: result = boxer.invokeExact((short)n); break;
+- case OBJECT: result = boxer.invokeExact((Object)n); break;
+- case BOOLEAN: result = boxer.invokeExact((n & 1) != 0); break;
++ case INT: result = (Integer) boxer.invokeExact(/*int*/n); break;
++ case LONG: result = (Long) boxer.invokeExact((long)n); break;
++ case FLOAT: result = (Float) boxer.invokeExact((float)n); break;
++ case DOUBLE: result = (Double) boxer.invokeExact((double)n); break;
++ case CHAR: result = (Character) boxer.invokeExact((char)n); break;
++ case BYTE: result = (Byte) boxer.invokeExact((byte)n); break;
++ case SHORT: result = (Short) boxer.invokeExact((short)n); break;
++ case BOOLEAN: result = (Boolean) boxer.invokeExact((n & 1) != 0); break;
+ }
+ assertEquals("(dst,src,n,box)="+Arrays.asList(w,w,n,box),
+ expResult, result);
+@@ -151,16 +135,14 @@
+
+ @Test
+ public void testCast() throws Throwable {
+- //System.out.println("cast");
+ Class<?>[] types = { Object.class, Serializable.class, String.class, Number.class, Integer.class };
+ Object[] objects = { new Object(), Boolean.FALSE, "hello", (Long)12L, (Integer)6 };
+ for (Class<?> dst : types) {
+- MethodHandle caster = ValueConversions.cast(dst);
+- assertEquals(caster.type(), ValueConversions.identity().type());
++ MethodHandle caster = ValueConversions.cast().bindTo(dst);
++ assertEquals(caster.type(), MethodHandles.identity(Object.class).type());
+ for (Object obj : objects) {
+ Class<?> src = obj.getClass();
+ boolean canCast = dst.isAssignableFrom(src);
+- //System.out.println("obj="+obj+" <: dst="+dst+(canCast ? " (OK)" : " (will fail)"));
+ try {
+ Object result = caster.invokeExact(obj);
+ if (canCast)
+@@ -176,25 +158,12 @@
+ }
+
+ @Test
+- public void testIdentity() throws Throwable {
+- //System.out.println("identity");
+- MethodHandle id = ValueConversions.identity();
+- Object expResult = "foo";
+- Object result = id.invokeExact(expResult);
+- // compiler bug: ValueConversions.identity().invokeExact("bar");
+- assertEquals(expResult, result);
+- }
+-
+- @Test
+ public void testConvert() throws Throwable {
+- //System.out.println("convert");
+ for (long tval = 0, ctr = 0;;) {
+ if (++ctr > 99999) throw new AssertionError("too many test values");
+- // next test value:
+- //System.out.println(Long.toHexString(tval)); // prints 3776 test patterns
++ // prints 3776 test patterns (3776 = 8*59*8)
+ tval = nextTestValue(tval);
+ if (tval == 0) {
+- //System.out.println("test value count = "+ctr); // 3776 = 8*59*8
+ break; // repeat
+ }
+ }
+@@ -205,15 +174,12 @@
+ }
+ }
+ static void testConvert(Wrapper src, Wrapper dst, long tval) throws Throwable {
+- //System.out.println(src+" => "+dst);
++ if (dst == Wrapper.OBJECT || src == Wrapper.OBJECT) return; // must have prims
++ if (dst == Wrapper.VOID || src == Wrapper.VOID ) return; // must have values
+ boolean testSingleCase = (tval != 0);
+ final long tvalInit = tval;
+ MethodHandle conv = ValueConversions.convertPrimitive(src, dst);
+- MethodType convType;
+- if (src == Wrapper.VOID)
+- convType = MethodType.methodType(dst.primitiveType() /* , void */);
+- else
+- convType = MethodType.methodType(dst.primitiveType(), src.primitiveType());
++ MethodType convType = MethodType.methodType(dst.primitiveType(), src.primitiveType());
+ assertEquals(convType, conv.type());
+ MethodHandle converter = conv.asType(conv.type().changeReturnType(Object.class));
+ for (;;) {
+@@ -229,9 +195,7 @@
+ case CHAR: result = converter.invokeExact((char)n); break;
+ case BYTE: result = converter.invokeExact((byte)n); break;
+ case SHORT: result = converter.invokeExact((short)n); break;
+- case OBJECT: result = converter.invokeExact((Object)n); break;
+ case BOOLEAN: result = converter.invokeExact((n & 1) != 0); break;
+- case VOID: result = converter.invokeExact(); break;
+ default: throw new AssertionError();
+ }
+ assertEquals("(src,dst,n,testValue)="+Arrays.asList(src,dst,"0x"+Long.toHexString(n),testValue),
+@@ -269,169 +233,4 @@
+ }
+ return tweakSign(ux);
+ }
+-
+- @Test
+- public void testVarargsArray() throws Throwable {
+- //System.out.println("varargsArray");
+- final int MIN = START_ARITY;
+- final int MAX = MAX_ARITY-2; // 253+1 would cause parameter overflow with 'this' added
+- for (int nargs = MIN; nargs <= MAX; nargs = nextArgCount(nargs, 17, MAX)) {
+- MethodHandle target = ValueConversions.varargsArray(nargs);
+- Object[] args = new Object[nargs];
+- for (int i = 0; i < nargs; i++)
+- args[i] = "#"+i;
+- Object res = target.invokeWithArguments(args);
+- assertArrayEquals(args, (Object[])res);
+- }
+- }
+-
+- @Test
+- public void testVarargsReferenceArray() throws Throwable {
+- //System.out.println("varargsReferenceArray");
+- testTypedVarargsArray(Object[].class);
+- testTypedVarargsArray(String[].class);
+- testTypedVarargsArray(Number[].class);
+- }
+-
+- @Test
+- public void testVarargsPrimitiveArray() throws Throwable {
+- //System.out.println("varargsPrimitiveArray");
+- testTypedVarargsArray(int[].class);
+- testTypedVarargsArray(long[].class);
+- testTypedVarargsArray(byte[].class);
+- testTypedVarargsArray(boolean[].class);
+- testTypedVarargsArray(short[].class);
+- testTypedVarargsArray(char[].class);
+- testTypedVarargsArray(float[].class);
+- testTypedVarargsArray(double[].class);
+- }
+-
+- private static int nextArgCount(int nargs, int density, int MAX) {
+- if (EXHAUSTIVE) return nargs + 1;
+- if (nargs >= MAX) return Integer.MAX_VALUE;
+- int BOT = 20, TOP = MAX-5;
+- if (density < 10) { BOT = 10; MAX = TOP-2; }
+- if (nargs <= BOT || nargs >= TOP) {
+- ++nargs;
+- } else {
+- int bump = Math.max(1, 100 / density);
+- nargs += bump;
+- if (nargs > TOP) nargs = TOP;
+- }
+- return nargs;
+- }
+-
+- private void testTypedVarargsArray(Class<?> arrayType) throws Throwable {
+- //System.out.println(arrayType.getSimpleName());
+- Class<?> elemType = arrayType.getComponentType();
+- int MIN = START_ARITY;
+- int MAX = MAX_ARITY-2; // 253+1 would cause parameter overflow with 'this' added
+- int density = 3;
+- if (elemType == int.class || elemType == long.class) density = 7;
+- if (elemType == long.class || elemType == double.class) { MAX /= 2; MIN /= 2; }
+- for (int nargs = MIN; nargs <= MAX; nargs = nextArgCount(nargs, density, MAX)) {
+- Object[] args = makeTestArray(elemType, nargs);
+- MethodHandle varargsArray = ValueConversions.varargsArray(arrayType, nargs);
+- MethodType vaType = varargsArray.type();
+- assertEquals(arrayType, vaType.returnType());
+- if (nargs != 0) {
+- assertEquals(elemType, vaType.parameterType(0));
+- assertEquals(elemType, vaType.parameterType(vaType.parameterCount()-1));
+- }
+- assertEquals(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)),
+- vaType);
+- Object res = varargsArray.invokeWithArguments(args);
+- String resString = toArrayString(res);
+- assertEquals(Arrays.toString(args), resString);
+-
+- MethodHandle spreader = varargsArray.asSpreader(arrayType, nargs);
+- MethodType stype = spreader.type();
+- assert(stype == MethodType.methodType(arrayType, arrayType));
+- if (nargs <= 5) {
+- // invoke target as a spreader also:
+- @SuppressWarnings("cast")
+- Object res2 = spreader.invokeWithArguments((Object)res);
+- String res2String = toArrayString(res2);
+- assertEquals(Arrays.toString(args), res2String);
+- // invoke the spreader on a generic Object[] array; check for error
+- try {
+- Object res3 = spreader.invokeWithArguments((Object)args);
+- String res3String = toArrayString(res3);
+- assertTrue(arrayType.getName(), arrayType.isAssignableFrom(Object[].class));
+- assertEquals(Arrays.toString(args), res3String);
+- } catch (ClassCastException ex) {
+- assertFalse(arrayType.getName(), arrayType.isAssignableFrom(Object[].class));
+- }
+- }
+- if (nargs == 0) {
+- // invoke spreader on null arglist
+- Object res3 = spreader.invokeWithArguments((Object)null);
+- String res3String = toArrayString(res3);
+- assertEquals(Arrays.toString(args), res3String);
+- }
+- }
+- }
+-
+- private static Object[] makeTestArray(Class<?> elemType, int len) {
+- Wrapper elem = null;
+- if (elemType.isPrimitive())
+- elem = Wrapper.forPrimitiveType(elemType);
+- else if (Wrapper.isWrapperType(elemType))
+- elem = Wrapper.forWrapperType(elemType);
+- Object[] args = new Object[len];
+- for (int i = 0; i < len; i++) {
+- Object arg = i * 100;
+- if (elem == null) {
+- if (elemType == String.class)
+- arg = "#"+arg;
+- arg = elemType.cast(arg); // just to make sure
+- } else {
+- switch (elem) {
+- case BOOLEAN: arg = (i % 3 == 0); break;
+- case CHAR: arg = 'a' + i; break;
+- case LONG: arg = (long)i * 1000_000_000; break;
+- case FLOAT: arg = (float)i / 100; break;
+- case DOUBLE: arg = (double)i / 1000_000; break;
+- }
+- arg = elem.cast(arg, elemType);
+- }
+- args[i] = arg;
+- }
+- //System.out.println(elemType.getName()+Arrays.toString(args));
+- return args;
+- }
+-
+- private static String toArrayString(Object a) {
+- if (a == null) return "null";
+- Class<?> elemType = a.getClass().getComponentType();
+- if (elemType == null) return a.toString();
+- if (elemType.isPrimitive()) {
+- switch (Wrapper.forPrimitiveType(elemType)) {
+- case INT: return Arrays.toString((int[])a);
+- case BYTE: return Arrays.toString((byte[])a);
+- case BOOLEAN: return Arrays.toString((boolean[])a);
+- case SHORT: return Arrays.toString((short[])a);
+- case CHAR: return Arrays.toString((char[])a);
+- case FLOAT: return Arrays.toString((float[])a);
+- case LONG: return Arrays.toString((long[])a);
+- case DOUBLE: return Arrays.toString((double[])a);
+- }
+- }
+- return Arrays.toString((Object[])a);
+- }
+-
+- @Test
+- public void testVarargsList() throws Throwable {
+- //System.out.println("varargsList");
+- final int MIN = START_ARITY;
+- final int MAX = MAX_ARITY-2; // 253+1 would cause parameter overflow with 'this' added
+- for (int nargs = MIN; nargs <= MAX; nargs = nextArgCount(nargs, 7, MAX)) {
+- MethodHandle target = ValueConversions.varargsList(nargs);
+- Object[] args = new Object[nargs];
+- for (int i = 0; i < nargs; i++)
+- args[i] = "#"+i;
+- Object res = target.invokeWithArguments(args);
+- assertEquals(Arrays.asList(args), res);
+- }
+- }
+ }
+--- ./jdk/test/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -89,8 +89,13 @@
+ public void update(Graphics g) {}
+ };
+ frame.setBackground(bgColor);
++ frame.setUndecorated(true);
+ frame.pack();
+- frame.setSize(FRAME_W, FRAME_H);
++
++ GraphicsConfiguration gc = frame.getGraphicsConfiguration();
++ Rectangle gcBounds = gc.getBounds();
++ frame.setBounds(gcBounds.width / 4, gcBounds.height / 4, FRAME_W, FRAME_H);
++
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ done = true;
+@@ -108,9 +113,8 @@
+ ex.printStackTrace();
+ }
+
+- GraphicsConfiguration gc = frame.getGraphicsConfiguration();
+- int maxW = gc.getBounds().width /2;
+- int maxH = gc.getBounds().height/2;
++ int maxW = gcBounds.width /2;
++ int maxH = gcBounds.height/2;
+ int minW = frame.getWidth();
+ int minH = frame.getHeight();
+ int incW = 10, incH = 10, cnt = 0;
+@@ -155,6 +159,7 @@
+ Insets in = frame.getInsets();
+ frame.getGraphics().drawImage(output, in.left, in.top, null);
+ if (cnt == 90 && robot != null) {
++ robot.waitForIdle();
+ // area where we blitted to should be either white or green
+ Point p = frame.getLocationOnScreen();
+ p.translate(in.left+10, in.top+10);
+@@ -172,7 +177,7 @@
+ frame.getWidth()-in.left-in.right,
+ frame.getHeight()-in.top-in.bottom-5-IMAGE_H));
+ int accepted2[] = { Color.white.getRGB() };
+- checkBI(bi, accepted1);
++ checkBI(bi, accepted2);
+ }
+
+ Thread.yield();
+--- ./jdk/test/sun/jvmstat/monitor/MonitoredVm/CR6672135.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/jvmstat/monitor/MonitoredVm/CR6672135.java Wed Feb 04 12:14:43 2015 -0800
+@@ -34,6 +34,7 @@
+ * @bug 6672135
+ * @summary setInterval() for local MonitoredHost and local MonitoredVm
+ * @author Tomas Hurka
++ * @run main/othervm -XX:+UsePerfData CR6672135
+ */
+ public class CR6672135 {
+
+--- ./jdk/test/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -21,228 +21,305 @@
+ * questions.
+ */
+
+-import java.util.concurrent.CountDownLatch;
+-import java.util.regex.*;
+-import java.util.*;
++import java.io.File;
++import java.io.IOException;
+ import java.net.URISyntaxException;
+-import java.io.IOException;
+-import sun.jvmstat.monitor.*;
+-import sun.jvmstat.monitor.event.*;
++import java.nio.file.Files;
++import java.nio.file.Path;
++import java.nio.file.Paths;
++import java.nio.file.StandardOpenOption;
++import java.util.ArrayList;
++import java.util.List;
++import java.util.Set;
++import java.util.UUID;
++import java.util.concurrent.Semaphore;
+
+-public class MonitorVmStartTerminate {
++import jdk.testlibrary.OutputBuffer;
++import jdk.testlibrary.ProcessTools;
++import sun.jvmstat.monitor.MonitorException;
++import sun.jvmstat.monitor.MonitoredHost;
++import sun.jvmstat.monitor.MonitoredVm;
++import sun.jvmstat.monitor.MonitoredVmUtil;
++import sun.jvmstat.monitor.VmIdentifier;
++import sun.jvmstat.monitor.event.HostEvent;
++import sun.jvmstat.monitor.event.HostListener;
++import sun.jvmstat.monitor.event.VmStatusChangeEvent;
+
+- private static final int SLEEPERS = 10;
+- private static final int SLEEPTIME = 5000; // sleep time for a sleeper
+- private static final int EXECINTERVAL = 3000; // wait time between exec's
++/*
+
+- public static void main(String args[]) throws Exception {
++ Test starts ten Java processes, each with a unique id.
+
+- long now = System.currentTimeMillis();
++ Each process creates a file named after the id and then it waits for
++ the test to remove the file, at which the Java process exits.
+
+- String sleeperArgs = SLEEPTIME + " " + now;
+- String sleeperPattern = "Sleeper " + sleeperArgs + " \\d+$";
++ The processes are monitored by the test to make sure notifications
++ are sent when they are started/terminated.
++
++ To avoid Java processes being left behind, in case of an unexpected
++ failure, shutdown hooks are installed that remove files when the test
++ exits. If files are not removed, i.e. due to a JVM crash, the Java
++ processes will exit themselves after 1000 s.
++
++*/
++
++/*
++ * @test
++ * @bug 4990825
++ * @summary attach to external but local JVM processes
++ * @library /lib/testlibrary
++ * @build jdk.testlibrary.*
++ * @run main/othervm MonitorVmStartTerminate
++ */
++public final class MonitorVmStartTerminate {
++
++ private static final int PROCESS_COUNT = 10;
++
++ public static void main(String... args) throws Exception {
+
+ MonitoredHost host = MonitoredHost.getMonitoredHost("localhost");
+- host.setInterval(200);
++ host.setInterval(1); // 1 ms
+
+- Matcher matcher = Pattern.compile(sleeperPattern).matcher("");
+- SleeperListener listener = new SleeperListener(host, matcher, SLEEPERS);
++ String id = UUID.randomUUID().toString();
++
++ List<JavaProcess> javaProcesses = new ArrayList<>();
++ for (int i = 0; i < PROCESS_COUNT; i++) {
++ javaProcesses.add(new JavaProcess(id + "_" + i));
++ }
++
++ Listener listener = new Listener(host, javaProcesses);
+ host.addHostListener(listener);
++ for (JavaProcess javaProcess : javaProcesses) {
++ javaProcess.start();
++ }
+
+- SleeperStarter ss = new SleeperStarter(SLEEPERS, EXECINTERVAL,
+- sleeperArgs);
+- ss.start();
++ // Wait for all processes to start before terminating
++ // them, so pids are not reused within a poll interval.
++ System.out.println("Waiting for all processes to get started notification");
++ listener.started.acquire(PROCESS_COUNT);
+
+- System.out.println("Waiting for "
+- + SLEEPERS + " sleepers to terminate");
+- try {
+- ss.join();
+- } catch (InterruptedException e) {
+- throw new Exception("Timed out waiting for sleepers");
++ for (JavaProcess javaProcess : javaProcesses) {
++ javaProcess.terminate();
+ }
+- listener.waitForSleepersToStart();
+- listener.waitForSleepersToTerminate();
++ System.out.println("Waiting for all processes to get terminated notification");
++ listener.terminated.acquire(PROCESS_COUNT);
++
++ host.removeHostListener(listener);
+ }
+
+- public static class SleeperListener implements HostListener {
++ private static final class Listener implements HostListener {
++ private final Semaphore started = new Semaphore(0);
++ private final Semaphore terminated = new Semaphore(0);
++ private final MonitoredHost host;
++ private final List<JavaProcess> processes;
+
+- private final List<Integer> targets = new ArrayList<>();
+- private final CountDownLatch terminateLatch;
+- private final CountDownLatch startLatch;
+- private final MonitoredHost host;
+- private final Matcher patternMatcher;
+-
+- public SleeperListener(MonitoredHost host, Matcher matcher, int count) {
++ public Listener(MonitoredHost host, List<JavaProcess> processes) {
+ this.host = host;
+- this.patternMatcher = matcher;
+- this.terminateLatch = new CountDownLatch(count);
+- this.startLatch = new CountDownLatch(count);
++ this.processes = processes;
++ printStatus();
+ }
+
+- public void waitForSleepersToTerminate() throws InterruptedException {
+- terminateLatch.await();
++ @Override
++ @SuppressWarnings("unchecked")
++ public void vmStatusChanged(VmStatusChangeEvent event) {
++ releaseStarted(event.getStarted());
++ releaseTerminated(event.getTerminated());
++ printStatus();
+ }
+
+- public void waitForSleepersToStart() throws InterruptedException {
+- startLatch.await();
++ private void printStatus() {
++ System.out.printf("started=%d, terminated=%d\n",
++ started.availablePermits(), terminated.availablePermits());
+ }
+
+- private void printList(Set<Integer> list, String msg) {
+- System.out.println(msg + ":");
+- for (Integer lvmid : list) {
+- try {
+- VmIdentifier vmid = new VmIdentifier("//" + lvmid.intValue());
+- MonitoredVm target = host.getMonitoredVm(vmid);
++ @Override
++ public void disconnected(HostEvent arg0) {
++ // ignore
++ }
+
+- StringMonitor cmdMonitor =
+- (StringMonitor)target.findByName("sun.rt.javaCommand");
+- String cmd = cmdMonitor.stringValue();
++ private void releaseStarted(Set<Integer> ids) {
++ System.out.println("realeaseStarted(" + ids + ")");
++ for (Integer id : ids) {
++ releaseStarted(id);
++ }
++ }
+
+- System.out.println("\t" + lvmid.intValue() + ": "
+- + "\"" + cmd + "\"" + ": ");
+- } catch (URISyntaxException e) {
+- System.err.println("Unexpected URISyntaxException: "
+- + e.getMessage());
+- } catch (MonitorException e) {
+- System.out.println("\t" + lvmid.intValue()
+- + ": error reading monitoring data: "
+- + " target possibly terminated?");
++ private void releaseStarted(Integer id) {
++ for (JavaProcess jp : processes) {
++ if (hasMainArgs(id, jp.getMainArgsIdentifier())) {
++ // store id for terminated identification
++ jp.setId(id);
++ System.out.println("RELEASED (id=" + jp.getId() + ", args=" + jp.getMainArgsIdentifier() + ")");
++ started.release();
++ return;
+ }
+ }
+ }
+
+-
+- private int addStarted(Set<Integer> started) {
+- int found = 0;
+- for (Integer lvmid : started) {
+- try {
+- VmIdentifier vmid = new VmIdentifier("//" + lvmid.intValue());
+- MonitoredVm target = host.getMonitoredVm(vmid);
+-
+- StringMonitor cmdMonitor =
+- (StringMonitor)target.findByName("sun.rt.javaCommand");
+- String cmd = cmdMonitor.stringValue();
+-
+- patternMatcher.reset(cmd);
+- System.out.print("Started: " + lvmid.intValue()
+- + ": " + "\"" + cmd + "\"" + ": ");
+-
+- if (patternMatcher.matches()) {
+- System.out.println("matches pattern - recorded");
+- targets.add(lvmid);
+- found++;
+- }
+- else {
+- System.out.println("does not match pattern - ignored");
+- }
+- } catch (URISyntaxException e) {
+- System.err.println("Unexpected URISyntaxException: "
+- + e.getMessage());
+- } catch (MonitorException e) {
+- System.err.println("Unexpected MonitorException: "
+- + e.getMessage());
+- }
+- }
+- return found;
+- }
+-
+- private int removeTerminated(Set<Integer> terminated) {
+- int found = 0;
+- for (Integer lvmid : terminated) {
+- /*
+- * we don't attempt to attach to the target here as it's
+- * now dead and has no jvmstat share memory file. Just see
+- * if the process id is among those that we saved when we
+- * started the targets (note - duplicated allowed and somewhat
+- * expected on windows);
+- */
+- System.out.print("Terminated: " + lvmid.intValue() + ": ");
+- if (targets.contains(lvmid)) {
+- System.out.println("matches pattern - termination recorded");
+- targets.remove(lvmid);
+- found++;
+- }
+- else {
+- System.out.println("does not match pattern - ignored");
+- }
+- }
+- return found;
+- }
+-
+- @SuppressWarnings("unchecked")
+- public void vmStatusChanged(VmStatusChangeEvent ev) {
+- printList(ev.getActive(), "Active");
+- printList(ev.getStarted(), "Started");
+- printList(ev.getTerminated(), "Terminated");
+-
+- int recentlyStarted = addStarted(ev.getStarted());
+- int recentlyTerminated = removeTerminated(ev.getTerminated());
+-
+- for (int i = 0; i < recentlyTerminated; i++) {
+- terminateLatch.countDown();
+- }
+- for (int i = 0; i < recentlyStarted; i++) {
+- startLatch.countDown();
++ private void releaseTerminated(Set<Integer> ids) {
++ System.out.println("releaseTerminated(" + ids + ")");
++ for (Integer id : ids) {
++ releaseTerminated(id);
+ }
+ }
+
+- public void disconnected(HostEvent ev) {
++ private void releaseTerminated(Integer id) {
++ for (JavaProcess jp : processes) {
++ if (id.equals(jp.getId())) {
++ System.out.println("RELEASED (id=" + jp.getId() + ", args=" + jp.getMainArgsIdentifier() + ")");
++ terminated.release();
++ return;
++ }
++ }
++ }
++
++ private boolean hasMainArgs(Integer id, String args) {
++ try {
++ VmIdentifier vmid = new VmIdentifier("//" + id.intValue());
++ MonitoredVm target = host.getMonitoredVm(vmid);
++ String monitoredArgs = MonitoredVmUtil.mainArgs(target);
++ if (monitoredArgs != null && monitoredArgs.contains(args)) {
++ return true;
++ }
++ } catch (URISyntaxException | MonitorException e) {
++ // ok. process probably not running
++ }
++ return false;
+ }
+ }
+
+- public static class SleeperStarter extends Thread {
++ public final static class JavaProcess {
+
+- private final JavaProcess[] processes;
+- private final int execInterval;
+- private final String args;
++ private static final class ShutdownHook extends Thread {
++ private final JavaProcess javaProcess;
+
+- public SleeperStarter(int sleepers, int execInterval, String args) {
+- this.execInterval = execInterval;
+- this.args = args;
+- this.processes = new JavaProcess[sleepers];
++ public ShutdownHook(JavaProcess javaProcess) {
++ this.javaProcess = javaProcess;
++ }
++
++ public void run() {
++ javaProcess.terminate();
++ }
+ }
+
+- private synchronized int active() {
+- int active = processes.length;
+- for(JavaProcess jp : processes) {
+- try {
+- jp.exitValue();
+- active--;
+- } catch (IllegalThreadStateException e) {
+- // process hasn't exited yet
+- }
++ public static void main(String[] args) throws InterruptedException {
++ try {
++ Path path = Paths.get(args[0]);
++ createFile(path);
++ waitForRemoval(path);
++ } catch (Throwable t) {
++ t.printStackTrace();
++ System.exit(1);
+ }
+- return active;
+ }
+
+- public void run() {
+- System.out.println("Starting " + processes.length + " sleepers");
++ public Integer getId() {
++ return id;
++ }
+
+- String[] classpath = {
+- "-classpath",
+- System.getProperty("java.class.path")
+- };
++ public void setId(Integer id) {
++ this.id = id;
++ }
+
+- for (int i = 0; i < processes.length; i++) {
+- try {
+- System.out.println("Starting Sleeper " + i);
+- synchronized(this) {
+- processes[i] = new JavaProcess("Sleeper", args + " " + i);
+- processes[i].addOptions(classpath);
+- }
+- processes[i].start();
+- Thread.sleep(execInterval);
+- } catch (InterruptedException ignore) {
+- } catch (IOException e) {
+- System.err.println(
+- "IOException trying to start Sleeper " + i + ": "
+- + e.getMessage());
+- }
+- }
++ private static void createFile(Path path) throws IOException {
++ Files.write(path, new byte[0], StandardOpenOption.CREATE);
++ }
+
+- // spin waiting for the processes to terminate
+- while (active() > 0) ;
++ private static void waitForRemoval(Path path) {
++ String timeoutFactorText = System.getProperty("test.timeout.factor", "1.0");
++ double timeoutFactor = Double.parseDouble(timeoutFactorText);
++ long timeoutNanos = 1000_000_000L*(long)(1000*timeoutFactor);
++ long start = System.nanoTime();
++ while (true) {
++ long now = System.nanoTime();
++ long waited = now - start;
++ System.out.println("Waiting for " + path + " to be removed, " + waited + " ns");
++ if (!Files.exists(path)) {
++ return;
++ }
++ if (waited > timeoutNanos) {
++ System.out.println("Start: " + start);
++ System.out.println("Now: " + now);
++ System.out.println("Process timed out after " + waited + " ns. Abort.");
++ System.exit(1);
++ }
++ takeNap();
++ }
++ }
++
++ private static void takeNap() {
++ try {
++ Thread.sleep(100);
++ } catch (InterruptedException e) {
++ // ignore
++ }
++ }
++
++ private final String mainArgsIdentifier;
++ private final ShutdownHook shutdownHook;
++ private volatile Integer id;
++
++ public JavaProcess(String mainArgsIdentifier) {
++ this.mainArgsIdentifier = mainArgsIdentifier;
++ this.shutdownHook = new ShutdownHook(this);
++ }
++
++ /**
++ * Starts a Java process asynchronously.
++ *
++ * The process runs until {@link #stop()} is called. If test exits
++ * unexpectedly the process will be cleaned up by a shutdown hook.
++ *
++ * @throws Exception
++ */
++ public void start() throws Exception {
++ Runtime.getRuntime().addShutdownHook(shutdownHook);
++ System.out.println("Starting " + getMainArgsIdentifier());
++
++ Runnable r = new Runnable() {
++ @Override
++ public void run() {
++ try {
++ executeJava();
++ } catch (Throwable t) {
++ t.printStackTrace();
++ }
++ }
++ };
++ new Thread(r).start();
++ }
++
++ public void terminate() {
++ try {
++ System.out.println("Terminating " + mainArgsIdentifier);
++ // File must be created before proceeding,
++ // otherwise Java process may loop forever
++ // waiting for file to be removed.
++ Path path = Paths.get(mainArgsIdentifier);
++ while (!Files.exists(path)) {
++ takeNap();
++ }
++ Files.delete(path);
++ } catch (IOException e) {
++ e.printStackTrace();
++ }
++ Runtime.getRuntime().removeShutdownHook(shutdownHook);
++ }
++
++ private void executeJava() throws Exception, IOException {
++ String className = JavaProcess.class.getName();
++ String classPath = System.getProperty("test.classes");
++ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
++ "-Dtest.timeout.factor=" + System.getProperty("test.timeout.factor", "1.0"),
++ "-cp", classPath, className, mainArgsIdentifier);
++ OutputBuffer ob = ProcessTools.getOutput(pb.start());
++ System.out.println("Java Process " + getMainArgsIdentifier() + " stderr:"
++ + ob.getStderr());
++ System.err.println("Java Process " + getMainArgsIdentifier() + " stdout:"
++ + ob.getStdout());
++ }
++
++ public String getMainArgsIdentifier() {
++ return mainArgsIdentifier;
+ }
+ }
+ }
+-
+--- ./jdk/test/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.sh Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,43 +0,0 @@
+-#
+-# Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-#
+-# This code is free software; you can redistribute it and/or modify it
+-# under the terms of the GNU General Public License version 2 only, as
+-# published by the Free Software Foundation.
+-#
+-# This code is distributed in the hope that it will be useful, but WITHOUT
+-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-# version 2 for more details (a copy is included in the LICENSE file that
+-# accompanied this code).
+-#
+-# You should have received a copy of the GNU General Public License version
+-# 2 along with this work; if not, write to the Free Software Foundation,
+-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-#
+-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-# or visit www.oracle.com if you need additional information or have any
+-# questions.
+-#
+-
+-#
+-# @test
+-# @bug 4990825
+-# @summary attach to external but local JVM processes
+-# @library ../../testlibrary
+-# @build Sleeper
+-# @build JavaProcess
+-# @build MonitorVmStartTerminate
+-# @run shell MonitorVmStartTerminate.sh
+-#
+-
+-. ${TESTSRC-.}/../../testlibrary/utils.sh
+-
+-setup
+-verify_os
+-
+-JAVA="${TESTJAVA}/bin/java"
+-CP=${TESTJAVA}${FS}lib${FS}tools.jar${PS}${TESTCLASSES}${PS}${TESTCLASSES}${FS}..${FS}..${FS}testlibrary
+-
+-${JAVA} ${TESTVMOPTS} -classpath ${CP} MonitorVmStartTerminate
+--- ./jdk/test/sun/jvmstat/testlibrary/JavaProcess.java Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,151 +0,0 @@
+-/*
+- * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-/**
+- *
+- */
+-
+-import java.io.*;
+-
+-public class JavaProcess {
+-
+- protected Process process = null;
+-
+- private String classname;
+- private StringBuilder classArgs;
+- private StringBuilder javaOptions;
+-
+- private static String java = System.getProperty("java.home")
+- + File.separator + "bin"
+- + File.separator + "java";
+-
+- public JavaProcess(String classname) {
+- this(classname, "", "");
+- }
+-
+- public JavaProcess(String classname, String classArgs) {
+- this(classname, "", classArgs);
+- }
+-
+- public JavaProcess(String classname, String javaOptions, String classArgs) {
+- this.classname = classname;
+- this.javaOptions = new StringBuilder(javaOptions);
+- this.classArgs = new StringBuilder(classArgs);
+- }
+-
+- /**
+- * add java options to the java command
+- */
+- public void addOptions(String[] opts) {
+- if (javaOptions != null && javaOptions.length() > 0) {
+- javaOptions.append(" ");
+- }
+-
+- for (int i = 0; i < opts.length; i++) {
+- if (i != 0) {
+- javaOptions.append(" ");
+- }
+- javaOptions.append(opts[i]);
+- }
+- }
+-
+- /**
+- * add arguments to the class arguments
+- */
+- public void addArguments(String[] args) {
+- if (classArgs != null && classArgs.length() > 0) {
+- classArgs.append(" ");
+- }
+-
+- for (int i = 0; i < args.length; i++) {
+- if (i != 0) {
+- classArgs.append(" ");
+- }
+- classArgs.append(args[i]);
+- }
+- }
+-
+- /**
+- * start the java process
+- */
+- public void start() throws IOException {
+- if (process != null) {
+- return;
+- }
+-
+- String javaCommand = java + " " + javaOptions + " "
+- + classname + " " + classArgs;
+-
+- System.out.println("exec'ing: " + javaCommand);
+-
+- process = Runtime.getRuntime().exec(javaCommand);
+- }
+-
+- /**
+- * destroy the java process
+- */
+- public void destroy() {
+- if (process != null) {
+- process.destroy();
+- }
+- process = null;
+- }
+-
+- public int exitValue() {
+- if (process != null) {
+- return process.exitValue();
+- }
+- throw new RuntimeException("exitValue called with process == null");
+- }
+-
+- public InputStream getErrorStream() {
+- if (process != null) {
+- return process.getErrorStream();
+- }
+- throw new RuntimeException(
+- "getErrorStream() called with process == null");
+- }
+-
+- public InputStream getInputStream() {
+- if (process != null) {
+- return process.getInputStream();
+- }
+- throw new RuntimeException(
+- "getInputStream() called with process == null");
+- }
+-
+- public OutputStream getOutputStream() {
+- if (process != null) {
+- return process.getOutputStream();
+- }
+- throw new RuntimeException(
+- "getOutputStream() called with process == null");
+- }
+-
+- public int waitFor() throws InterruptedException {
+- if (process != null) {
+- return process.waitFor();
+- }
+- throw new RuntimeException("waitFor() called with process == null");
+- }
+-}
+--- ./jdk/test/sun/management/jmxremote/bootstrap/JvmstatCountersTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/management/jmxremote/bootstrap/JvmstatCountersTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -143,9 +143,12 @@
+ String vmid = name.substring(0, name.indexOf("@"));
+ System.out.println("vmid = " + vmid);
+ VirtualMachine vm = VirtualMachine.attach(vmid);
+- String agent = vm.getSystemProperties().getProperty("java.home") +
+- File.separator + "lib" + File.separator + "management-agent.jar";
+- vm.loadAgent(agent, "com.sun.management.jmxremote.port=0,com.sun.management.jmxremote.authenticate=false,com.sun.management.jmxremote.ssl=false");
++ Properties p = new Properties();
++ p.put("com.sun.management.jmxremote.port", "0");
++ p.put("com.sun.management.jmxremote.authenticate", "false");
++ p.put("com.sun.management.jmxremote.ssl", "false");
++ vm.startManagementAgent(p);
++ vm.startLocalManagementAgent();
+ vm.detach();
+ String localAddress2 = ConnectorAddressLink.importFrom(0);
+ if (localAddress2 == null) {
+--- ./jdk/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -79,16 +79,6 @@
+ return doTest("1", "-Dcom.sun.management.jmxremote");
+ }
+
+- private static boolean test2() throws Exception {
+- Path agentPath = findAgent();
+- if (agentPath != null) {
+- String agent = agentPath.toString();
+- return doTest("2", "-javaagent:" + agent);
+- } else {
+- return false;
+- }
+- }
+-
+ /**
+ * no args (blank) - manager should attach and start agent
+ */
+@@ -97,68 +87,12 @@
+ }
+
+ /**
+- * sanity check arguments to management-agent.jar
+- */
+- private static boolean test4() throws Exception {
+- Path agentPath = findAgent();
+- if (agentPath != null) {
+- ProcessBuilder builder = ProcessTools.createJavaProcessBuilder(
+- "-javaagent:" + agentPath.toString() +
+- "=com.sun.management.jmxremote.port=7775," +
+- "com.sun.management.jmxremote.authenticate=false," +
+- "com.sun.management.jmxremote.ssl=false",
+- "-cp",
+- TEST_CLASSPATH,
+- "TestApplication",
+- "-exit"
+- );
+-
+- Process prc = null;
+- try {
+- prc = ProcessTools.startProcess(
+- "TestApplication",
+- builder
+- );
+- int exitCode = prc.waitFor();
+- return exitCode == 0;
+- } finally {
+- if (prc != null) {
+- prc.destroy();
+- prc.waitFor();
+- }
+- }
+- }
+- return false;
+- }
+-
+- /**
+ * use DNS-only name service
+ */
+ private static boolean test5() throws Exception {
+ return doTest("5", "-Dsun.net.spi.namservice.provider.1=\"dns,sun\"");
+ }
+
+- private static Path findAgent() {
+- FileSystem FS = FileSystems.getDefault();
+- Path agentPath = FS.getPath(
+- TEST_JDK, "jre", "lib", "management-agent.jar"
+- );
+- if (!isFileOk(agentPath)) {
+- agentPath = FS.getPath(
+- TEST_JDK, "lib", "management-agent.jar"
+- );
+- }
+- if (!isFileOk(agentPath)) {
+- System.err.println("Can not locate management-agent.jar");
+- return null;
+- }
+- return agentPath;
+- }
+-
+- private static boolean isFileOk(Path path) {
+- return Files.isRegularFile(path) && Files.isReadable(path);
+- }
+-
+ private static boolean doTest(String testId, String arg) throws Exception {
+ List<String> args = new ArrayList<>();
+ args.add("-cp");
+--- ./jdk/test/sun/management/jmxremote/bootstrap/TestManager.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/management/jmxremote/bootstrap/TestManager.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -40,7 +40,6 @@
+ import static java.lang.management.ManagementFactory.*;
+ import java.net.Socket;
+ import java.net.InetSocketAddress;
+-import java.io.File;
+ import java.io.IOException;
+
+ // Sun specific
+@@ -55,28 +54,8 @@
+ * Starts the management agent in the target VM
+ */
+ private static void startManagementAgent(String pid) throws IOException {
+- /*
+- * JAR file normally in ${java.home}/jre/lib but may be in ${java.home}/lib
+- * with development/non-images builds
+- */
+- String home = System.getProperty("java.home");
+- String agent = home + File.separator + "jre" + File.separator + "lib"
+- + File.separator + "management-agent.jar";
+- File f = new File(agent);
+- if (!f.exists()) {
+- agent = home + File.separator + "lib" + File.separator +
+- "management-agent.jar";
+- f = new File(agent);
+- if (!f.exists()) {
+- throw new RuntimeException("management-agent.jar missing");
+- }
+- }
+- agent = f.getCanonicalPath();
+-
+- System.out.println("Loading " + agent + " into target VM ...");
+-
+ try {
+- VirtualMachine.attach(pid).loadAgent(agent);
++ VirtualMachine.attach(pid).startLocalManagementAgent();
+ } catch (Exception x) {
+ throw new IOException(x.getMessage());
+ }
+@@ -122,8 +101,7 @@
+
+ if (agentPropLocalConnectorAddress == null &&
+ jvmstatLocalConnectorAddress == null) {
+- // No JMX Connector address so attach to VM, and load
+- // management-agent.jar
++ // No JMX Connector address so attach to VM, and start local agent
+ startManagementAgent(pid);
+ agentPropLocalConnectorAddress = (String)
+ vm.getAgentProperties().get(LOCAL_CONNECTOR_ADDRESS_PROP);
+--- ./jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -31,16 +31,13 @@
+ import java.rmi.registry.Registry;
+ import java.util.ArrayList;
+ import java.util.Arrays;
+-import java.util.HashMap;
+ import java.util.Iterator;
+ import java.util.List;
+-import java.util.Map;
+ import java.util.Objects;
+ import java.util.Set;
+ import java.util.concurrent.TimeUnit;
+ import java.util.concurrent.TimeoutException;
+ import java.util.concurrent.atomic.AtomicBoolean;
+-import java.util.concurrent.atomic.AtomicReference;
+ import java.util.function.Consumer;
+
+ import javax.management.*;
+@@ -60,7 +57,6 @@
+ * JCMD achieves the desired results
+ */
+ public class JMXStartStopTest {
+- private static final String TEST_JDK = System.getProperty("test.jdk");
+ private static final String TEST_SRC = System.getProperty("test.src");
+
+ private static final boolean verbose = false;
+@@ -76,8 +72,8 @@
+ QueryExp query)
+ throws Exception {
+
+- Set names = server.queryNames(pattern,query);
+- for (Iterator i=names.iterator(); i.hasNext(); ) {
++ Set<ObjectName> names = server.queryNames(pattern,query);
++ for (Iterator<ObjectName> i = names.iterator(); i.hasNext(); ) {
+ ObjectName name = (ObjectName)i.next();
+ MBeanInfo info = server.getMBeanInfo(name);
+ dbg_print("Got MBean: " + name);
+@@ -87,7 +83,7 @@
+ continue;
+ for (MBeanAttributeInfo attr : attrs) {
+ if (attr.isReadable()) {
+- Object o = server.getAttribute(name, attr.getName());
++ server.getAttribute(name, attr.getName());
+ }
+ }
+ }
+@@ -108,9 +104,8 @@
+ }
+
+ JMXServiceURL url = new JMXServiceURL(jmxUrlStr);
+- Map m = new HashMap();
+
+- JMXConnector c = JMXConnectorFactory.connect(url,m);
++ JMXConnector c = JMXConnectorFactory.connect(url, null);
+
+ MBeanServerConnection conn = c.getMBeanServerConnection();
+ ObjectName pattern = new ObjectName("java.lang:type=Memory,*");
+@@ -180,9 +175,8 @@
+ port);
+
+ JMXServiceURL url = new JMXServiceURL(jmxUrlStr);
+- Map m = new HashMap();
+
+- JMXConnector c = JMXConnectorFactory.connect(url,m);
++ JMXConnector c = JMXConnectorFactory.connect(url, null);
+
+ MBeanServerConnection conn = c.getMBeanServerConnection();
+ ObjectName pattern = new ObjectName("java.lang:type=Memory,*");
+@@ -273,25 +267,6 @@
+ }
+ }
+
+- /**
+- * Retrieves the PID of the test application using JCMD
+- * @return The PID of the test application
+- * @throws InterruptedException
+- * @throws IOException
+- */
+- private static String getPID() throws InterruptedException, IOException {
+- final AtomicReference<String> pid = new AtomicReference<>();
+- jcmd(
+- null,
+- line -> {
+- if (line.endsWith("JMXStartStopDoSomething")) {
+- pid.set(line.split(" ")[0]);
+- }
+- }
+- );
+- return pid.get();
+- }
+-
+ private static class Something {
+ private Process p;
+ private final ProcessBuilder pb;
+@@ -434,7 +409,7 @@
+ private static final int port1 = 50234;
+ private static final int port2 = 50235;
+
+- private static void test_01() throws Exception {
++ static void test_01() throws Exception {
+ // Run an app with JMX enabled stop it and
+ // restart on other port
+
+@@ -459,7 +434,7 @@
+ }
+ }
+
+- private static void test_02() throws Exception {
++ static void test_02() throws Exception {
+ // Run an app without JMX enabled
+ // start JMX by jcmd
+
+@@ -478,7 +453,7 @@
+ }
+ }
+
+- private static void test_03() throws Exception {
++ static void test_03() throws Exception {
+ // Run an app without JMX enabled
+ // start JMX by jcmd on one port than on other one
+
+@@ -507,7 +482,7 @@
+ }
+ }
+
+- private static void test_04() throws Exception {
++ static void test_04() throws Exception {
+ // Run an app without JMX enabled
+ // start JMX by jcmd on one port, specify rmi port explicitly
+
+@@ -528,7 +503,7 @@
+ }
+ }
+
+- private static void test_05() throws Exception {
++ static void test_05() throws Exception {
+ // Run an app without JMX enabled, it will enable local server
+ // but should leave remote server disabled
+
+@@ -545,7 +520,7 @@
+ }
+ }
+
+- private static void test_06() throws Exception {
++ static void test_06() throws Exception {
+ // Run an app without JMX enabled
+ // start JMX by jcmd on one port, specify rmi port explicitly
+ // attempt to start it again
+@@ -569,7 +544,7 @@
+ final boolean[] checks = new boolean[3];
+ jcmd(
+ line -> {
+- if (line.equals("java.lang.RuntimeException: Invalid agent state")) {
++ if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
+ checks[0] = true;
+ }
+ },
+@@ -580,7 +555,7 @@
+
+ jcmd(
+ line -> {
+- if (line.equals("java.lang.RuntimeException: Invalid agent state")) {
++ if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
+ checks[1] = true;
+ }
+ },
+@@ -648,7 +623,7 @@
+ }
+ }
+
+- private static void test_08() throws Exception {
++ static void test_08() throws Exception {
+ // Run an app with JMX enabled and with some properties set
+ // in command line.
+ // stop JMX agent and then start it again with different property values
+@@ -682,7 +657,7 @@
+ }
+ }
+
+- private static void test_09() throws Exception {
++ static void test_09() throws Exception {
+ // Run an app with JMX enabled and with some properties set
+ // in command line.
+ // stop JMX agent and then start it again with different property values
+@@ -718,7 +693,7 @@
+ }
+ }
+
+- private static void test_10() throws Exception {
++ static void test_10() throws Exception {
+ // Run an app with JMX enabled and with some properties set
+ // in command line.
+ // stop JMX agent and then start it again with different property values
+@@ -754,7 +729,7 @@
+ }
+ }
+
+- private static void test_11() throws Exception {
++ static void test_11() throws Exception {
+ // Run an app with JMX enabled
+ // stop remote agent
+ // make sure local agent is not affected
+@@ -775,7 +750,7 @@
+ }
+ }
+
+- private static void test_12() throws Exception {
++ static void test_12() throws Exception {
+ // Run an app with JMX disabled
+ // start local agent only
+
+@@ -793,28 +768,4 @@
+ s.stop();
+ }
+ }
+-
+- private static void test_13() throws Exception {
+- // Run an app with -javaagent make sure it works as expected -
+- // system properties are ignored
+-
+- System.out.println("**** Test thirteen ****");
+-
+- String agent = TEST_JDK + "/jre/lib/management-agent.jar";
+- if (!new File(agent).exists()) {
+- agent = TEST_JDK + "/lib/management-agent.jar";
+- }
+-
+- Something s = doSomething("test_14",
+- "-javaagent:" + agent + "=com.sun.management.jmxremote.port=" +
+- port1 + ",com.sun.management.jmxremote.authenticate=false",
+- "-Dcom.sun.management.jmxremote.ssl=false"
+- );
+-
+- try {
+- testNoConnect(port1);
+- } finally {
+- s.stop();
+- }
+- }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/sun/misc/URLClassPath/EnableLookupCache.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,66 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/* @test
++ * @bug 8061651
++ * @summary -Dsun.cds.enableSharedLookupCache specified on the command-line
++ * should have no effect.
++ * @run main/othervm -Dsun.cds.enableSharedLookupCache=true -Xshare:off -Dfoo.foo.bar=xyz EnableLookupCache
++ */
++
++public class EnableLookupCache {
++ public static void main(String[] args) throws Exception {
++ // If JVM is started with -Xshare:off, the sun.cds.enableSharedLookupCache
++ // should never be true, even if it has been explicitly set in the
++ // command-line.
++ String prop = "sun.cds.enableSharedLookupCache";
++ String value = System.getProperty(prop);
++ System.out.println("System.getProperty(\"" + prop + "\") = \"" + value+ "\"");
++
++ if ("true".equals(value)) {
++ System.out.println("Test FAILED: system property " + prop +
++ " is \"true\" (unexpected)");
++ throw new RuntimeException(prop + " should not be " + value);
++ }
++
++ // Make sure the -D... arguments in the @run tag are indeed used.
++ prop = "foo.foo.bar";
++ value = System.getProperty(prop);
++ System.out.println("System.getProperty(\"" + prop + "\") = \"" + value+ "\"");
++ if (!"xyz".equals(value)) {
++ System.out.println("Test FAILED: system property " + prop +
++ " should be \"xyz\" -- is JTREG set up properly?");
++ throw new RuntimeException(prop + " should not be " + value);
++ }
++
++
++ // We should be able to load the other classes without issue.
++ A.test();
++ B.test();
++ System.out.println("Test PASSED");
++ }
++
++ static class A {static void test() {}}
++ static class B {static void test() {}}
++}
++
+--- ./jdk/test/sun/net/ftp/FtpURL.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/net/ftp/FtpURL.java Wed Feb 04 12:14:43 2015 -0800
+@@ -483,7 +483,7 @@
+
+ // Now let's check the URL handler
+
+- url = new URL("ftp://user2:@localhost:" + port + "/%2Fusr/bin;type=d");
++ url = new URL("ftp://user2@localhost:" + port + "/%2Fusr/bin;type=d");
+ con = url.openConnection();
+ in = new BufferedReader(new InputStreamReader(con.getInputStream()));
+ do {
+--- ./jdk/test/sun/net/www/http/HttpClient/StreamingRetry.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/net/www/http/HttpClient/StreamingRetry.java Wed Feb 04 12:14:43 2015 -0800
+@@ -23,8 +23,8 @@
+
+ /*
+ * @test
+- * @bug 6672144
+- * @summary HttpURLConnection.getInputStream sends POST request after failed chunked send
++ * @bug 6672144 8050983
++ * @summary Do not retry failed request with a streaming body.
+ */
+
+ import java.net.HttpURLConnection;
+@@ -33,31 +33,41 @@
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.io.OutputStream;
++import static java.lang.System.out;
+
+ public class StreamingRetry implements Runnable {
+ static final int ACCEPT_TIMEOUT = 20 * 1000; // 20 seconds
+- ServerSocket ss;
++ volatile ServerSocket ss;
+
+- public static void main(String[] args) throws IOException {
++ public static void main(String[] args) throws Exception {
+ (new StreamingRetry()).instanceMain();
+ }
+
+- void instanceMain() throws IOException {
+- test();
++ void instanceMain() throws Exception {
++ out.println("Test with default method");
++ test(null);
++ out.println("Test with POST method");
++ test("POST");
++ out.println("Test with PUT method");
++ test("PUT");
++
+ if (failed > 0) throw new RuntimeException("Some tests failed");
+ }
+
+- void test() throws IOException {
++ void test(String method) throws Exception {
+ ss = new ServerSocket(0);
+ ss.setSoTimeout(ACCEPT_TIMEOUT);
+ int port = ss.getLocalPort();
+
+- (new Thread(this)).start();
++ Thread otherThread = new Thread(this);
++ otherThread.start();
+
+ try {
+ URL url = new URL("http://localhost:" + port + "/");
+ HttpURLConnection uc = (HttpURLConnection) url.openConnection();
+ uc.setDoOutput(true);
++ if (method != null)
++ uc.setRequestMethod(method);
+ uc.setChunkedStreamingMode(4096);
+ OutputStream os = uc.getOutputStream();
+ os.write("Hello there".getBytes());
+@@ -68,6 +78,7 @@
+ //expected.printStackTrace();
+ } finally {
+ ss.close();
++ otherThread.join();
+ }
+ }
+
+@@ -79,7 +90,7 @@
+ ss.close();
+ fail("The server shouldn't accept a second connection");
+ } catch (IOException e) {
+- //OK, the clien will close the server socket if successfull
++ //OK, the client will close the server socket if successful
+ }
+ }
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/sun/security/jgss/GssMemoryIssues.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8028780
++ * @summary JDK KRB5 module throws OutOfMemoryError when CCache is corrupt
++ * @run main/othervm -Xmx8m GssMemoryIssues
++ */
++
++import org.ietf.jgss.GSSException;
++import org.ietf.jgss.GSSManager;
++import org.ietf.jgss.GSSName;
++
++public class GssMemoryIssues {
++
++ public static void main(String[] argv) throws Exception {
++ GSSManager man = GSSManager.getInstance();
++ String s = "me@REALM";
++ GSSName name = man.createName(s, GSSName.NT_USER_NAME);
++ byte[] exported = name.export();
++ // Offset of the length of the mech name. Length in big endian
++ int lenOffset = exported.length - s.length() - 4;
++ // Make it huge
++ exported[lenOffset] = 0x7f;
++ try {
++ man.createName(exported, GSSName.NT_EXPORT_NAME);
++ } catch (GSSException gsse) {
++ System.out.println(gsse);
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/sun/security/jgss/spnego/NotPreferredMech.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,100 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8048194
++ * @run main/othervm NotPreferredMech
++ * @summary GSSContext.acceptSecContext fails when a supported mech is not initiator preferred
++ */
++
++import org.ietf.jgss.*;
++import sun.security.jgss.*;
++import sun.security.jgss.spnego.NegTokenInit;
++import sun.security.jgss.spnego.NegTokenTarg;
++import sun.security.util.BitArray;
++import sun.security.util.DerOutputStream;
++import sun.security.util.DerValue;
++import sun.security.util.ObjectIdentifier;
++
++import java.io.ByteArrayOutputStream;
++import java.lang.reflect.Constructor;
++import java.lang.reflect.Method;
++
++public class NotPreferredMech {
++
++ public static void main(String[] argv) throws Exception {
++
++ // Generates a NegTokenInit mechTypes field, with an
++ // unsupported mech as the preferred.
++ DerOutputStream mech = new DerOutputStream();
++ mech.write(new Oid("1.2.3.4").getDER());
++ mech.write(GSSUtil.GSS_KRB5_MECH_OID.getDER());
++ DerOutputStream mechTypeList = new DerOutputStream();
++ mechTypeList.write(DerValue.tag_Sequence, mech);
++
++ // Generates a NegTokenInit mechToken field for 1.2.3.4 mech
++ GSSHeader h1 = new GSSHeader(new ObjectIdentifier("1.2.3.4"), 1);
++ ByteArrayOutputStream bout = new ByteArrayOutputStream();
++ h1.encode(bout);
++ bout.write(new byte[1]);
++
++ // Generates the NegTokenInit token
++ Constructor<NegTokenInit> ctor = NegTokenInit.class.getDeclaredConstructor(
++ byte[].class, BitArray.class, byte[].class, byte[].class);
++ ctor.setAccessible(true);
++ NegTokenInit initToken = ctor.newInstance(
++ mechTypeList.toByteArray(),
++ new BitArray(0),
++ bout.toByteArray(),
++ null);
++ Method m = Class.forName("sun.security.jgss.spnego.SpNegoToken")
++ .getDeclaredMethod("getEncoded");
++ m.setAccessible(true);
++ byte[] spnegoToken = (byte[])m.invoke(initToken);
++
++ // and wraps it into a GSSToken
++ GSSHeader h = new GSSHeader(
++ new ObjectIdentifier(GSSUtil.GSS_SPNEGO_MECH_OID.toString()),
++ spnegoToken.length);
++ bout = new ByteArrayOutputStream();
++ h.encode(bout);
++ bout.write(spnegoToken);
++ byte[] token = bout.toByteArray();
++
++ // and feeds it to a GSS acceptor
++ GSSManager man = GSSManager.getInstance();
++ GSSContext ctxt = man.createContext((GSSCredential) null);
++ token = ctxt.acceptSecContext(token, 0, token.length);
++ NegTokenTarg targ = new NegTokenTarg(token);
++
++ // Make sure it's a GO-ON message
++ Method m2 = NegTokenTarg.class.getDeclaredMethod("getNegotiatedResult");
++ m2.setAccessible(true);
++ int negResult = (int)m2.invoke(targ);
++
++ if (negResult != 1 /* ACCEPT_INCOMPLETE */) {
++ throw new Exception("Not a continue");
++ }
++ }
++}
+--- ./jdk/test/sun/security/krb5/TimeInCCache.java Mon Dec 08 12:29:42 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,94 +0,0 @@
+-/*
+- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-/*
+- * @test
+- * @bug 6590930
+- * @run main/othervm TimeInCCache
+- * @summary read/write does not match for ccache
+- */
+-
+-import java.io.ByteArrayInputStream;
+-import java.lang.reflect.Field;
+-import java.lang.reflect.Method;
+-import sun.security.krb5.internal.ccache.CCacheInputStream;
+-import sun.security.krb5.internal.ccache.Credentials;
+-
+-public class TimeInCCache {
+- public static void main(String[] args) throws Exception {
+- // A trivial cache file, with startdate and renewTill being zero.
+- // The endtime is set to sometime in year 2022, so that isValid()
+- // will always check starttime.
+- byte[] ccache = new byte[]{
+- 5, 4, 0, 12, 0, 1, 0, 8, -1, -1, -1, 19, -1, -2, 89, 51,
+- 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 10, 77, 65, 88, 73,
+- 46, 76, 79, 67, 65, 76, 0, 0, 0, 5, 100, 117, 109, 109, 121, 0,
+- 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 10, 77, 65, 88, 73, 46,
+- 76, 79, 67, 65, 76, 0, 0, 0, 5, 100, 117, 109, 109, 121, 0, 0,
+- 0, 0, 0, 0, 0, 2, 0, 0, 0, 10, 77, 65, 88, 73, 46, 76,
+- 79, 67, 65, 76, 0, 0, 0, 6, 107, 114, 98, 116, 103, 116, 0, 0,
+- 0, 10, 77, 65, 88, 73, 46, 76, 79, 67, 65, 76, 0, 17, 0, 0,
+- 0, 16, -78, -85, -90, -50, -68, 115, 68, 8, -39, -109, 91, 61, -17, -27,
+- -122, -120, 71, 69, 16, -121, 0, 0, 0, 0, 98, 69, 16, -121, 0, 0,
+- 0, 0, 0, 64, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+- 0, 1, 0, 97, -127, -3, 48, -127, -6, -96, 3, 2, 1, 5, -95, 12,
+- 27, 10, 77, 65, 88, 73, 46, 76, 79, 67, 65, 76, -94, 31, 48, 29,
+- -96, 3, 2, 1, 0, -95, 22, 48, 20, 27, 6, 107, 114, 98, 116, 103,
+- 116, 27, 10, 77, 65, 88, 73, 46, 76, 79, 67, 65, 76, -93, -127, -61,
+- 48, -127, -64, -96, 3, 2, 1, 17, -95, 3, 2, 1, 1, -94, -127, -77,
+- 4, -127, -80, 43, 65, -66, 34, 21, -34, 37, 35, 32, 50, -14, 122, 77,
+- -3, -29, 37, 99, 50, 125, -43, -96, -78, 85, 23, 41, -80, 68, 2, -109,
+- -27, 38, -41, -72, -32, 127, 63, -76, -22, 81, 33, -114, -30, 104, 125, -81,
+- -29, 70, -25, 23, 100, -75, -25, 62, -120, -78, -61, -100, -74, 50, -117, -127,
+- -16, 79, -106, 62, -39, 91, 100, -10, 23, -88, -18, -47, 51, -19, 113, 18,
+- 98, -101, 31, 98, 22, -81, 11, -41, -42, 67, 87, 92, -2, 42, -54, 79,
+- 49, -90, 43, -37, 90, -102, 125, 62, -88, -77, 100, 102, 23, -57, -51, 38,
+- 68, -44, -57, -102, 103, -6, 85, -58, 74, -117, -87, 67, -103, -36, 110, -122,
+- 115, 12, 118, -106, -114, -51, 79, 68, 32, -91, -53, -5, -51, 89, 72, 70,
+- 123, -12, -95, 9, 40, -30, -117, 74, 77, 38, 91, 126, -82, 17, 98, 98,
+- -49, 78, 36, 36, 103, -76, -100, -23, 118, -92, -8, 80, 103, -23, -98, 56,
+- 21, 65, -77, 0, 0, 0, 0
+- };
+- System.setProperty("sun.security.krb5.debug", "true"); // test code changes in DEBUG
+- CCacheInputStream cis = new CCacheInputStream(new ByteArrayInputStream(ccache));
+- cis.readVersion();
+- cis.readTag();
+- cis.readPrincipal(0x504);
+- Method m = CCacheInputStream.class.getDeclaredMethod("readCred", Integer.TYPE);
+- m.setAccessible(true);
+- Credentials c = (Credentials) m.invoke(cis, new Integer(0x504));
+- sun.security.krb5.Credentials cc = c.setKrbCreds();
+-
+- // 1. Make sure starttime is still null
+- if (cc.getStartTime() != null) {
+- throw new Exception("Fail, starttime should be zero here");
+- }
+-
+- // 2. Make sure renewTill is still null
+- if (cc.getRenewTill() != null) {
+- throw new Exception("Fail, renewTill should be zero here");
+- }
+-
+- // 3. Make sure isValid works
+- c.isValid();
+- }
+-}
+--- ./jdk/test/sun/security/krb5/auto/S4U2proxy.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/security/krb5/auto/S4U2proxy.java Wed Feb 04 12:14:43 2015 -0800
+@@ -23,7 +23,7 @@
+
+ /*
+ * @test
+- * @bug 6355584
++ * @bug 6355584 8044215
+ * @summary Introduce constrained Kerberos delegation
+ * @compile -XDignore.symbol.file S4U2proxy.java
+ * @run main/othervm S4U2proxy krb5
+@@ -69,6 +69,10 @@
+ Context p = s.delegated();
+
+ p.startAsClient(OneKDC.BACKEND, mech);
++
++ // 8044215: requestCredDeleg is useless and harmless
++ p.x().requestCredDeleg(true);
++
+ b.startAsServer(mech);
+ Context.handshake(p, b);
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/sun/security/krb5/ccache/CorruptedCC.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8028780
++ * @summary JDK KRB5 module throws OutOfMemoryError when CCache is corrupt
++ * @run main/othervm -Xmx8m CorruptedCC
++ */
++import java.nio.file.Files;
++import java.nio.file.Paths;
++import sun.security.krb5.internal.ccache.CredentialsCache;
++
++public class CorruptedCC {
++ public static void main(String[] args) throws Exception {
++ for (int i=0; i<TimeInCCache.ccache.length; i++) {
++ byte old = TimeInCCache.ccache[i];
++ TimeInCCache.ccache[i] = 0x7f;
++ Files.write(Paths.get("tmpcc"), TimeInCCache.ccache);
++ // The next line will return null for I/O issues. That's OK.
++ CredentialsCache.getInstance("tmpcc");
++ TimeInCCache.ccache[i] = old;
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/sun/security/krb5/ccache/DefaultFile.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8054817
++ * @summary File ccache only recognizes Linux and Solaris defaults
++ */
++
++import sun.security.krb5.internal.ccache.FileCredentialsCache;
++
++public class DefaultFile {
++ public static void main(String[] args) throws Exception {
++ // There are 2 cases where default ccache name is not
++ // /tmp/krb5cc_uid.
++ if (System.getenv("KRB5CCNAME") != null) {
++ return;
++ }
++ if (System.getProperty("os.name").startsWith("Windows")) {
++ return;
++ }
++ String name = FileCredentialsCache.getDefaultCacheName();
++ if (!name.startsWith("/tmp/krb5cc_")) {
++ throw new Exception("default name is " + name);
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/sun/security/krb5/ccache/EmptyRealmCC.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,68 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8048073
++ * @summary Cannot read ccache entry with a realm-less service name
++ * @compile -XDignore.symbol.file EmptyRealmCC.java
++ * @run main EmptyRealmCC
++ */
++import java.nio.file.Files;
++import java.nio.file.Paths;
++
++import sun.security.krb5.internal.ccache.CredentialsCache;
++
++public class EmptyRealmCC {
++ public static void main(String[] args) throws Exception {
++ byte[] ccache = TimeInCCache.ccache;
++
++ // The service name starts at 0x52:
++ //
++ // 0050: 00 00 00 02 00 00 00 0A 4D 41 58 49 2E 4C
++ // ----------- -----------
++ // 0060: 4F 43 41 4C 00 00 00 06 6B 72 62 74 67 74 00 00
++ // ----------- -----
++ // 0070: 00 0A 4D 41 58 49 2E 4C 4F 43 41 4C
++ // -----
++ //
++ // which contains 2 (the length of names), a 10-byte realm, a 6-byte
++ // name[0], and a 10-byte name[1].
++
++ // We will empty the realm, and pack the realm string to another
++ // name (6-byte ".LOCAL"). Finally "krbtgt/MAXI.LOCAL@MAXI.LOCAL"
++ // becomes ".LOCAL/krbtgt/MAXI.LOCAL@".
++
++ // length of names is now 3
++ ccache[0x55] = 3;
++ // The empty realm
++ System.arraycopy(new byte[4], 0, ccache, 0x56, 4);
++ // Length of inserted name is 6
++ System.arraycopy(new byte[]{0,0,0,6}, 0, ccache, 0x5A, 4);
++
++ Files.write(Paths.get("tmpcc"), TimeInCCache.ccache);
++ if (CredentialsCache.getInstance("tmpcc").getCredsList() != null) {
++ throw new Exception("Nothing should be there");
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/sun/security/krb5/ccache/TimeInCCache.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,104 @@
++/*
++ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++/*
++ * @test
++ * @bug 6590930
++ * @run main/othervm TimeInCCache
++ * @summary read/write does not match for ccache
++ */
++
++import java.io.ByteArrayInputStream;
++import java.lang.reflect.Method;
++
++import sun.security.krb5.internal.ccache.CCacheInputStream;
++import sun.security.krb5.internal.ccache.Credentials;
++
++public class TimeInCCache {
++ // Attention: this field is also used by 2 other tests:
++ // CorruptedCC.java and EmptyRealmCC.java
++ public static byte[] ccache;
++
++ static {
++ // A trivial cache file, with startdate and renewTill being zero.
++ // The endtime is set to sometime in year 2022, so that isValid()
++ // will always check starttime.
++ String var =
++ /*0000*/ "05 04 00 0C 00 01 00 08 FF FF FF 13 FF FE 59 33 " +
++ /*0010*/ "00 00 00 01 00 00 00 01 00 00 00 0A 4D 41 58 49 " +
++ /*0020*/ "2E 4C 4F 43 41 4C 00 00 00 05 64 75 6D 6D 79 00 " +
++ /*0030*/ "00 00 01 00 00 00 01 00 00 00 0A 4D 41 58 49 2E " +
++ /*0040*/ "4C 4F 43 41 4C 00 00 00 05 64 75 6D 6D 79 00 00 " +
++ /*0050*/ "00 00 00 00 00 02 00 00 00 0A 4D 41 58 49 2E 4C " +
++ /*0060*/ "4F 43 41 4C 00 00 00 06 6B 72 62 74 67 74 00 00 " +
++ /*0070*/ "00 0A 4D 41 58 49 2E 4C 4F 43 41 4C 00 11 00 00 " +
++ /*0080*/ "00 10 B2 AB A6 CE BC 73 44 08 D9 93 5B 3D EF E5 " +
++ /*0090*/ "86 88 47 45 10 87 00 00 00 00 62 45 10 87 00 00 " +
++ /*00A0*/ "00 00 00 40 E0 00 00 00 00 00 00 00 00 00 00 00 " +
++ /*00B0*/ "00 01 00 61 81 FD 30 81 FA A0 03 02 01 05 A1 0C " +
++ /*00C0*/ "1B 0A 4D 41 58 49 2E 4C 4F 43 41 4C A2 1F 30 1D " +
++ /*00D0*/ "A0 03 02 01 00 A1 16 30 14 1B 06 6B 72 62 74 67 " +
++ /*00E0*/ "74 1B 0A 4D 41 58 49 2E 4C 4F 43 41 4C A3 81 C3 " +
++ /*00F0*/ "30 81 C0 A0 03 02 01 11 A1 03 02 01 01 A2 81 B3 " +
++ /*0100*/ "04 81 B0 2B 41 BE 22 15 DE 25 23 20 32 F2 7A 4D " +
++ /*0110*/ "FD E3 25 63 32 7D D5 A0 B2 55 17 29 B0 44 02 93 " +
++ /*0120*/ "E5 26 D7 B8 E0 7F 3F B4 EA 51 21 8E E2 68 7D AF " +
++ /*0130*/ "E3 46 E7 17 64 B5 E7 3E 88 B2 C3 9C B6 32 8B 81 " +
++ /*0140*/ "F0 4F 96 3E D9 5B 64 F6 17 A8 EE D1 33 ED 71 12 " +
++ /*0150*/ "62 9B 1F 62 16 AF 0B D7 D6 43 57 5C FE 2A CA 4F " +
++ /*0160*/ "31 A6 2B DB 5A 9A 7D 3E A8 B3 64 66 17 C7 CD 26 " +
++ /*0170*/ "44 D4 C7 9A 67 FA 55 C6 4A 8B A9 43 99 DC 6E 86 " +
++ /*0180*/ "73 0C 76 96 8E CD 4F 44 20 A5 CB FB CD 59 48 46 " +
++ /*0190*/ "7B F4 A1 09 28 E2 8B 4A 4D 26 5B 7E AE 11 62 62 " +
++ /*01A0*/ "CF 4E 24 24 67 B4 9C E9 76 A4 F8 50 67 E9 9E 38 " +
++ /*01B0*/ "15 41 B3 00 00 00 00 ";
++ ccache = new byte[var.length()/3];
++ for (int i=0; i<ccache.length; i++) {
++ ccache[i] = Integer.valueOf(var.substring(3*i,3*i+2), 16).byteValue();
++ }
++ }
++
++ public static void main(String[] args) throws Exception {
++ System.setProperty("sun.security.krb5.debug", "true"); // test code changes in DEBUG
++ CCacheInputStream cis = new CCacheInputStream(new ByteArrayInputStream(ccache));
++ cis.readVersion();
++ cis.readTag();
++ cis.readPrincipal(0x504);
++ Method m = CCacheInputStream.class.getDeclaredMethod("readCred", Integer.TYPE);
++ m.setAccessible(true);
++ Credentials c = (Credentials) m.invoke(cis, new Integer(0x504));
++ sun.security.krb5.Credentials cc = c.setKrbCreds();
++
++ // 1. Make sure starttime is still null
++ if (cc.getStartTime() != null) {
++ throw new Exception("Fail, starttime should be zero here");
++ }
++
++ // 2. Make sure renewTill is still null
++ if (cc.getRenewTill() != null) {
++ throw new Exception("Fail, renewTill should be zero here");
++ }
++
++ // 3. Make sure isValid works
++ c.isValid();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/sun/security/pkcs11/Cipher/JNICheck.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,64 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8063700
++ * @run main/othervm -Xcheck:jni JNICheck
++ */
++
++import javax.crypto.Cipher;
++import javax.crypto.SealedObject;
++import javax.crypto.SecretKey;
++import javax.crypto.KeyGenerator;
++import java.security.NoSuchProviderException;
++
++public class JNICheck {
++
++ /* This test is similar to the JCK test that found 8063700. */
++ static class SealedObjectTest {
++ Cipher c;
++
++ SealedObjectTest() throws Exception {
++ try {
++ c = Cipher.getInstance("AES", "SunPKCS11-Solaris");
++ } catch (NoSuchProviderException nspe) {
++ System.out.println("No SunPKCS11-Solaris provider. Test skipped");
++ return;
++ }
++
++ String s = "Test string";
++ SealedObject so;
++ SecretKey key = KeyGenerator.getInstance("AES").generateKey();
++
++ c.init(Cipher.ENCRYPT_MODE, key);
++ so = new SealedObject(s, c);
++
++ so.getObject(key, "SunPKCS11-Solaris");
++ }
++ }
++
++ public static void main(String args[]) throws Exception {
++ new SealedObjectTest();
++ }
++}
+--- ./jdk/test/sun/security/provider/DSA/TestDSA2.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/security/provider/DSA/TestDSA2.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 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
+@@ -50,7 +50,7 @@
+ public static void main(String[] args) throws Exception {
+ boolean[] expectedToPass = { true, true, true };
+ test(1024, expectedToPass);
+- boolean[] expectedToPass2 = { false, true, true };
++ boolean[] expectedToPass2 = { true, true, true };
+ test(2048, expectedToPass2);
+ }
+
+--- ./jdk/test/sun/security/smartcardio/TestAll.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/security/smartcardio/TestAll.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -26,7 +26,7 @@
+ // Because all the tests are marked @ignore as they require special hardware,
+ // we cannot use jtreg to do this.
+
+-import java.lang.reflect.*;
++import java.lang.reflect.Method;
+
+ public class TestAll {
+
+@@ -40,6 +40,7 @@
+ TestMultiplePresent.class,
+ TestPresent.class,
+ TestTransmit.class,
++ TestDirect.class,
+ };
+
+ public static void main(String[] args) throws Exception {
+--- ./jdk/test/sun/security/smartcardio/TestChannel.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/security/smartcardio/TestChannel.java Wed Feb 04 12:14:43 2015 -0800
+@@ -30,10 +30,10 @@
+ * @run main/manual TestExclusive
+ */
+
+-import java.io.*;
+-import java.util.*;
+-
+-import javax.smartcardio.*;
++import javax.smartcardio.Card;
++import javax.smartcardio.CardChannel;
++import javax.smartcardio.CardTerminal;
++import javax.smartcardio.CommandAPDU;
+
+ public class TestChannel extends Utils {
+
+@@ -94,7 +94,7 @@
+ }
+
+ // disconnect
+- card.disconnect(false);
++ card.disconnect(true);
+
+ System.out.println("OK.");
+ }
+--- ./jdk/test/sun/security/smartcardio/TestConnect.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/security/smartcardio/TestConnect.java Wed Feb 04 12:14:43 2015 -0800
+@@ -30,10 +30,11 @@
+ * @run main/manual TestConnect
+ */
+
+-import java.io.*;
+-import java.util.*;
+-
+-import javax.smartcardio.*;
++import java.util.List;
++import javax.smartcardio.TerminalFactory;
++import javax.smartcardio.Card;
++import javax.smartcardio.CardChannel;
++import javax.smartcardio.CardTerminal;
+
+ public class TestConnect extends Utils {
+
+@@ -62,7 +63,7 @@
+ throw new Exception("Not T=0 protocol");
+ }
+ transmit(card);
+- card.disconnect(false);
++ card.disconnect(true);
+
+ try {
+ transmit(card);
+@@ -95,7 +96,7 @@
+ throw new Exception("Not T=0 protocol");
+ }
+ transmit(card);
+- card.disconnect(true);
++ card.disconnect(false);
+
+ card = terminal.connect("*");
+ System.out.println("card: " + card);
+@@ -104,7 +105,6 @@
+ }
+ transmit(card);
+ card.disconnect(true);
+- card.disconnect(true);
+
+ System.out.println("OK.");
+ }
+--- ./jdk/test/sun/security/smartcardio/TestConnectAgain.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/security/smartcardio/TestConnectAgain.java Wed Feb 04 12:14:43 2015 -0800
+@@ -30,10 +30,10 @@
+ * @run main/manual TestTransmit
+ */
+
+-import java.io.*;
+-import java.util.*;
+-
+-import javax.smartcardio.*;
++import javax.smartcardio.Card;
++import javax.smartcardio.CardException;
++import javax.smartcardio.CardChannel;
++import javax.smartcardio.CardTerminal;
+
+ public class TestConnectAgain extends Utils {
+
+@@ -94,7 +94,7 @@
+ }
+
+ // disconnect
+- card.disconnect(false);
++ card.disconnect(true);
+
+ System.out.println("OK.");
+ }
+--- ./jdk/test/sun/security/smartcardio/TestControl.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/security/smartcardio/TestControl.java Wed Feb 04 12:14:43 2015 -0800
+@@ -30,10 +30,9 @@
+ * @run main/manual TestControl
+ */
+
+-import java.io.*;
+-import java.util.*;
+-
+-import javax.smartcardio.*;
++import javax.smartcardio.Card;
++import javax.smartcardio.CardException;
++import javax.smartcardio.CardTerminal;
+
+ public class TestControl extends Utils {
+
+@@ -67,7 +66,7 @@
+ }
+
+ // disconnect
+- card.disconnect(false);
++ card.disconnect(true);
+
+ System.out.println("OK.");
+ }
+--- ./jdk/test/sun/security/smartcardio/TestDefault.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/security/smartcardio/TestDefault.java Wed Feb 04 12:14:43 2015 -0800
+@@ -30,10 +30,9 @@
+ * @run main/manual TestDefault
+ */
+
+-import java.io.*;
+-import java.util.*;
+-
+-import javax.smartcardio.*;
++import java.util.List;
++import javax.smartcardio.CardTerminal;
++import javax.smartcardio.TerminalFactory;
+
+ public class TestDefault {
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./jdk/test/sun/security/smartcardio/TestDirect.java Wed Feb 04 12:14:43 2015 -0800
+@@ -0,0 +1,53 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8046343
++ * @summary Make sure that direct protocol is available
++ * @run main/manual TestDirect
++ */
++
++// This test requires special hardware.
++
++import java.util.List;
++import javax.smartcardio.Card;
++import javax.smartcardio.CardTerminal;
++import javax.smartcardio.CardTerminals;
++import javax.smartcardio.TerminalFactory;
++
++public class TestDirect {
++ public static void main(String[] args) throws Exception {
++ TerminalFactory terminalFactory = TerminalFactory.getDefault();
++ List<CardTerminal> cardTerminals = terminalFactory.terminals().list();
++ System.out.println("Terminals: " + cardTerminals);
++ if (cardTerminals.isEmpty()) {
++ throw new Exception("No card terminals available");
++ }
++ CardTerminal cardTerminal = cardTerminals.get(0);
++ Card card = cardTerminal.connect("DIRECT");
++ card.disconnect(true);
++
++ System.out.println("OK.");
++ }
++}
+--- ./jdk/test/sun/security/smartcardio/TestExclusive.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/security/smartcardio/TestExclusive.java Wed Feb 04 12:14:43 2015 -0800
+@@ -30,10 +30,11 @@
+ * @run main/manual TestExclusive
+ */
+
+-import java.io.*;
+-import java.util.*;
+-
+-import javax.smartcardio.*;
++import javax.smartcardio.Card;
++import javax.smartcardio.CardChannel;
++import javax.smartcardio.CardException;
++import javax.smartcardio.CardTerminal;
++import javax.smartcardio.CommandAPDU;
+
+ public class TestExclusive extends Utils {
+
+@@ -83,9 +84,9 @@
+ Thread.sleep(1000);
+
+ // disconnect
+- card.disconnect(false);
++ card.disconnect(true);
+
+- if (otherOK == false) {
++ if (! otherOK) {
+ throw new Exception("Secondary thread failed");
+ }
+
+--- ./jdk/test/sun/security/smartcardio/TestMultiplePresent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/security/smartcardio/TestMultiplePresent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -30,10 +30,10 @@
+ * @run main/manual TestPresent
+ */
+
+-import java.io.*;
+-import java.util.*;
+-
+-import javax.smartcardio.*;
++import java.util.List;
++import javax.smartcardio.CardTerminal;
++import javax.smartcardio.CardTerminals;
++import javax.smartcardio.TerminalFactory;
+ import static javax.smartcardio.CardTerminals.State.*;
+
+ public class TestMultiplePresent {
+--- ./jdk/test/sun/security/smartcardio/TestPresent.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/security/smartcardio/TestPresent.java Wed Feb 04 12:14:43 2015 -0800
+@@ -30,10 +30,9 @@
+ * @run main/manual TestPresent
+ */
+
+-import java.io.*;
+-import java.util.*;
+-
+-import javax.smartcardio.*;
++import java.util.List;
++import javax.smartcardio.CardTerminal;
++import javax.smartcardio.TerminalFactory;
+
+ public class TestPresent {
+
+--- ./jdk/test/sun/security/smartcardio/TestTransmit.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/security/smartcardio/TestTransmit.java Wed Feb 04 12:14:43 2015 -0800
+@@ -30,10 +30,16 @@
+ * @run main/manual TestTransmit
+ */
+
+-import java.io.*;
+-import java.util.*;
+-
+-import javax.smartcardio.*;
++import java.io.BufferedReader;
++import java.io.ByteArrayOutputStream;
++import java.io.FileReader;
++import java.io.IOException;
++import java.io.StringReader;
++import javax.smartcardio.Card;
++import javax.smartcardio.CardChannel;
++import javax.smartcardio.CardTerminal;
++import javax.smartcardio.CommandAPDU;
++import javax.smartcardio.ResponseAPDU;
+
+ public class TestTransmit extends Utils {
+
+@@ -78,7 +84,7 @@
+ }
+
+ // disconnect
+- card.disconnect(false);
++ card.disconnect(true);
+
+ System.out.println("OK.");
+ }
+--- ./jdk/test/sun/security/smartcardio/Utils.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/security/smartcardio/Utils.java Wed Feb 04 12:14:43 2015 -0800
+@@ -24,10 +24,16 @@
+
+ // common utility functions for the PC/SC tests
+
+-import javax.smartcardio.*;
+-
+-import java.io.*;
+-import java.util.*;
++import java.io.StringReader;
++import java.io.ByteArrayOutputStream;
++import java.io.IOException;
++import java.util.Arrays;
++import java.util.List;
++import javax.smartcardio.CardTerminal;
++import javax.smartcardio.CardChannel;
++import javax.smartcardio.ResponseAPDU;
++import javax.smartcardio.CommandAPDU;
++import javax.smartcardio.TerminalFactory;
+
+ public class Utils {
+
+--- ./jdk/test/sun/text/resources/LocaleData Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/text/resources/LocaleData Wed Feb 04 12:14:43 2015 -0800
+@@ -2502,7 +2502,7 @@
+ CalendarData/pl_PL/minimalDaysInFirstWeek=4
+ CalendarData/pt_PT/minimalDaysInFirstWeek=4
+
+-#bug 4945388
++#bug 4945388
+ CurrencyNames/be_BY/BYR=\u0420\u0443\u0431
+ CurrencyNames/bg_BG/BGN=\u043B\u0432.
+
+@@ -5422,7 +5422,7 @@
+ FormatData/en_SG/DatePatterns/2=MMM d, yyyy
+ FormatData/en_SG/DatePatterns/3=M/d/yy
+ FormatData/en_SG/DateTimePatterns/0={1} {0}
+-# Use approved data
++# Use approved data
+ FormatData/ms/Eras/0=BCE
+ FormatData/ms/Eras/1=CE
+ FormatData/sr_BA/MonthNames/5=\u0458\u0443\u043d\u0438
+@@ -5571,7 +5571,7 @@
+ FormatData/fi/AmPmMarkers/0=ap.
+ FormatData/fi/AmPmMarkers/1=ip.
+
+-# bug 6507067
++# bug 6507067
+ TimeZoneNames/zh_TW/Asia\/Taipei/1=\u53f0\u7063\u6a19\u6e96\u6642\u9593
+ TimeZoneNames/zh_TW/Asia\/Taipei/2=TST
+
+@@ -7702,3 +7702,577 @@
+
+ # bug 8055222
+ CurrencyNames/lt_LT/EUR=\u20AC
++
++# bug 8042126 + missing MonthNarrows data
++FormatData//MonthNarrows/0=1
++FormatData//MonthNarrows/1=2
++FormatData//MonthNarrows/2=3
++FormatData//MonthNarrows/3=4
++FormatData//MonthNarrows/4=5
++FormatData//MonthNarrows/5=6
++FormatData//MonthNarrows/6=7
++FormatData//MonthNarrows/7=8
++FormatData//MonthNarrows/8=9
++FormatData//MonthNarrows/9=10
++FormatData//MonthNarrows/10=11
++FormatData//MonthNarrows/11=12
++FormatData//MonthNarrows/12=
++FormatData/bg/MonthNarrows/0=\u044f
++FormatData/bg/MonthNarrows/1=\u0444
++FormatData/bg/MonthNarrows/2=\u043c
++FormatData/bg/MonthNarrows/3=\u0430
++FormatData/bg/MonthNarrows/4=\u043c
++FormatData/bg/MonthNarrows/5=\u044e
++FormatData/bg/MonthNarrows/6=\u044e
++FormatData/bg/MonthNarrows/7=\u0430
++FormatData/bg/MonthNarrows/8=\u0441
++FormatData/bg/MonthNarrows/9=\u043e
++FormatData/bg/MonthNarrows/10=\u043d
++FormatData/bg/MonthNarrows/11=\u0434
++FormatData/bg/MonthNarrows/12=
++FormatData/zh_TW/MonthNarrows/0=1
++FormatData/zh_TW/MonthNarrows/1=2
++FormatData/zh_TW/MonthNarrows/2=3
++FormatData/zh_TW/MonthNarrows/3=4
++FormatData/zh_TW/MonthNarrows/4=5
++FormatData/zh_TW/MonthNarrows/5=6
++FormatData/zh_TW/MonthNarrows/6=7
++FormatData/zh_TW/MonthNarrows/7=8
++FormatData/zh_TW/MonthNarrows/8=9
++FormatData/zh_TW/MonthNarrows/9=10
++FormatData/zh_TW/MonthNarrows/10=11
++FormatData/zh_TW/MonthNarrows/11=12
++FormatData/zh_TW/MonthNarrows/12=
++FormatData/it/MonthNarrows/0=G
++FormatData/it/MonthNarrows/1=F
++FormatData/it/MonthNarrows/2=M
++FormatData/it/MonthNarrows/3=A
++FormatData/it/MonthNarrows/4=M
++FormatData/it/MonthNarrows/5=G
++FormatData/it/MonthNarrows/6=L
++FormatData/it/MonthNarrows/7=A
++FormatData/it/MonthNarrows/8=S
++FormatData/it/MonthNarrows/9=O
++FormatData/it/MonthNarrows/10=N
++FormatData/it/MonthNarrows/11=D
++FormatData/it/MonthNarrows/12=
++FormatData/ko/MonthNarrows/0=1\uc6d4
++FormatData/ko/MonthNarrows/1=2\uc6d4
++FormatData/ko/MonthNarrows/2=3\uc6d4
++FormatData/ko/MonthNarrows/3=4\uc6d4
++FormatData/ko/MonthNarrows/4=5\uc6d4
++FormatData/ko/MonthNarrows/5=6\uc6d4
++FormatData/ko/MonthNarrows/6=7\uc6d4
++FormatData/ko/MonthNarrows/7=8\uc6d4
++FormatData/ko/MonthNarrows/8=9\uc6d4
++FormatData/ko/MonthNarrows/9=10\uc6d4
++FormatData/ko/MonthNarrows/10=11\uc6d4
++FormatData/ko/MonthNarrows/11=12\uc6d4
++FormatData/ko/MonthNarrows/12=
++FormatData/uk/MonthNarrows/0=\u0421
++FormatData/uk/MonthNarrows/1=\u041b
++FormatData/uk/MonthNarrows/2=\u0411
++FormatData/uk/MonthNarrows/3=\u041a
++FormatData/uk/MonthNarrows/4=\u0422
++FormatData/uk/MonthNarrows/5=\u0427
++FormatData/uk/MonthNarrows/6=\u041b
++FormatData/uk/MonthNarrows/7=\u0421
++FormatData/uk/MonthNarrows/8=\u0412
++FormatData/uk/MonthNarrows/9=\u0416
++FormatData/uk/MonthNarrows/10=\u041b
++FormatData/uk/MonthNarrows/11=\u0413
++FormatData/uk/MonthNarrows/12=
++FormatData/lv/MonthNarrows/0=J
++FormatData/lv/MonthNarrows/1=F
++FormatData/lv/MonthNarrows/2=M
++FormatData/lv/MonthNarrows/3=A
++FormatData/lv/MonthNarrows/4=M
++FormatData/lv/MonthNarrows/5=J
++FormatData/lv/MonthNarrows/6=J
++FormatData/lv/MonthNarrows/7=A
++FormatData/lv/MonthNarrows/8=S
++FormatData/lv/MonthNarrows/9=O
++FormatData/lv/MonthNarrows/10=N
++FormatData/lv/MonthNarrows/11=D
++FormatData/lv/MonthNarrows/12=
++FormatData/pt/MonthNarrows/0=J
++FormatData/pt/MonthNarrows/1=F
++FormatData/pt/MonthNarrows/2=M
++FormatData/pt/MonthNarrows/3=A
++FormatData/pt/MonthNarrows/4=M
++FormatData/pt/MonthNarrows/5=J
++FormatData/pt/MonthNarrows/6=J
++FormatData/pt/MonthNarrows/7=A
++FormatData/pt/MonthNarrows/8=S
++FormatData/pt/MonthNarrows/9=O
++FormatData/pt/MonthNarrows/10=N
++FormatData/pt/MonthNarrows/11=D
++FormatData/pt/MonthNarrows/12=
++FormatData/sk/MonthNarrows/0=j
++FormatData/sk/MonthNarrows/1=f
++FormatData/sk/MonthNarrows/2=m
++FormatData/sk/MonthNarrows/3=a
++FormatData/sk/MonthNarrows/4=m
++FormatData/sk/MonthNarrows/5=j
++FormatData/sk/MonthNarrows/6=j
++FormatData/sk/MonthNarrows/7=a
++FormatData/sk/MonthNarrows/8=s
++FormatData/sk/MonthNarrows/9=o
++FormatData/sk/MonthNarrows/10=n
++FormatData/sk/MonthNarrows/11=d
++FormatData/sk/MonthNarrows/12=
++FormatData/hi_IN/MonthNarrows/0=\u091c
++FormatData/hi_IN/MonthNarrows/1=\u092b\u093c
++FormatData/hi_IN/MonthNarrows/2=\u092e\u093e
++FormatData/hi_IN/MonthNarrows/3=\u0905
++FormatData/hi_IN/MonthNarrows/4=\u092e
++FormatData/hi_IN/MonthNarrows/5=\u091c\u0942
++FormatData/hi_IN/MonthNarrows/6=\u091c\u0941
++FormatData/hi_IN/MonthNarrows/7=\u0905
++FormatData/hi_IN/MonthNarrows/8=\u0938\u093f
++FormatData/hi_IN/MonthNarrows/9=\u0905
++FormatData/hi_IN/MonthNarrows/10=\u0928
++FormatData/hi_IN/MonthNarrows/11=\u0926\u093f
++FormatData/hi_IN/MonthNarrows/12=
++FormatData/ga/MonthNarrows/0=E
++FormatData/ga/MonthNarrows/1=F
++FormatData/ga/MonthNarrows/2=M
++FormatData/ga/MonthNarrows/3=A
++FormatData/ga/MonthNarrows/4=B
++FormatData/ga/MonthNarrows/5=M
++FormatData/ga/MonthNarrows/6=I
++FormatData/ga/MonthNarrows/7=L
++FormatData/ga/MonthNarrows/8=M
++FormatData/ga/MonthNarrows/9=D
++FormatData/ga/MonthNarrows/10=S
++FormatData/ga/MonthNarrows/11=N
++FormatData/ga/MonthNarrows/12=
++FormatData/et/MonthNarrows/0=J
++FormatData/et/MonthNarrows/1=V
++FormatData/et/MonthNarrows/2=M
++FormatData/et/MonthNarrows/3=A
++FormatData/et/MonthNarrows/4=M
++FormatData/et/MonthNarrows/5=J
++FormatData/et/MonthNarrows/6=J
++FormatData/et/MonthNarrows/7=A
++FormatData/et/MonthNarrows/8=S
++FormatData/et/MonthNarrows/9=O
++FormatData/et/MonthNarrows/10=N
++FormatData/et/MonthNarrows/11=D
++FormatData/et/MonthNarrows/12=
++FormatData/sv/MonthNarrows/0=J
++FormatData/sv/MonthNarrows/1=F
++FormatData/sv/MonthNarrows/2=M
++FormatData/sv/MonthNarrows/3=A
++FormatData/sv/MonthNarrows/4=M
++FormatData/sv/MonthNarrows/5=J
++FormatData/sv/MonthNarrows/6=J
++FormatData/sv/MonthNarrows/7=A
++FormatData/sv/MonthNarrows/8=S
++FormatData/sv/MonthNarrows/9=O
++FormatData/sv/MonthNarrows/10=N
++FormatData/sv/MonthNarrows/11=D
++FormatData/sv/MonthNarrows/12=
++FormatData/cs/MonthNarrows/0=l
++FormatData/cs/MonthNarrows/1=\u00fa
++FormatData/cs/MonthNarrows/2=b
++FormatData/cs/MonthNarrows/3=d
++FormatData/cs/MonthNarrows/4=k
++FormatData/cs/MonthNarrows/5=\u010d
++FormatData/cs/MonthNarrows/6=\u010d
++FormatData/cs/MonthNarrows/7=s
++FormatData/cs/MonthNarrows/8=z
++FormatData/cs/MonthNarrows/9=\u0159
++FormatData/cs/MonthNarrows/10=l
++FormatData/cs/MonthNarrows/11=p
++FormatData/cs/MonthNarrows/12=
++FormatData/el/MonthNarrows/0=\u0399
++FormatData/el/MonthNarrows/1=\u03a6
++FormatData/el/MonthNarrows/2=\u039c
++FormatData/el/MonthNarrows/3=\u0391
++FormatData/el/MonthNarrows/4=\u039c
++FormatData/el/MonthNarrows/5=\u0399
++FormatData/el/MonthNarrows/6=\u0399
++FormatData/el/MonthNarrows/7=\u0391
++FormatData/el/MonthNarrows/8=\u03a3
++FormatData/el/MonthNarrows/9=\u039f
++FormatData/el/MonthNarrows/10=\u039d
++FormatData/el/MonthNarrows/11=\u0394
++FormatData/el/MonthNarrows/12=
++FormatData/hu/MonthNarrows/0=J
++FormatData/hu/MonthNarrows/1=F
++FormatData/hu/MonthNarrows/2=M
++FormatData/hu/MonthNarrows/3=\u00c1
++FormatData/hu/MonthNarrows/4=M
++FormatData/hu/MonthNarrows/5=J
++FormatData/hu/MonthNarrows/6=J
++FormatData/hu/MonthNarrows/7=A
++FormatData/hu/MonthNarrows/8=Sz
++FormatData/hu/MonthNarrows/9=O
++FormatData/hu/MonthNarrows/10=N
++FormatData/hu/MonthNarrows/11=D
++FormatData/hu/MonthNarrows/12=
++FormatData/es/MonthNarrows/0=E
++FormatData/es/MonthNarrows/1=F
++FormatData/es/MonthNarrows/2=M
++FormatData/es/MonthNarrows/3=A
++FormatData/es/MonthNarrows/4=M
++FormatData/es/MonthNarrows/5=J
++FormatData/es/MonthNarrows/6=J
++FormatData/es/MonthNarrows/7=A
++FormatData/es/MonthNarrows/8=S
++FormatData/es/MonthNarrows/9=O
++FormatData/es/MonthNarrows/10=N
++FormatData/es/MonthNarrows/11=D
++FormatData/es/MonthNarrows/12=
++FormatData/tr/MonthNarrows/0=O
++FormatData/tr/MonthNarrows/1=\u015e
++FormatData/tr/MonthNarrows/2=M
++FormatData/tr/MonthNarrows/3=N
++FormatData/tr/MonthNarrows/4=M
++FormatData/tr/MonthNarrows/5=H
++FormatData/tr/MonthNarrows/6=T
++FormatData/tr/MonthNarrows/7=A
++FormatData/tr/MonthNarrows/8=E
++FormatData/tr/MonthNarrows/9=E
++FormatData/tr/MonthNarrows/10=K
++FormatData/tr/MonthNarrows/11=A
++FormatData/tr/MonthNarrows/12=
++FormatData/hr/MonthNarrows/0=1.
++FormatData/hr/MonthNarrows/1=2.
++FormatData/hr/MonthNarrows/2=3.
++FormatData/hr/MonthNarrows/3=4.
++FormatData/hr/MonthNarrows/4=5.
++FormatData/hr/MonthNarrows/5=6.
++FormatData/hr/MonthNarrows/6=7.
++FormatData/hr/MonthNarrows/7=8.
++FormatData/hr/MonthNarrows/8=9.
++FormatData/hr/MonthNarrows/9=10.
++FormatData/hr/MonthNarrows/10=11.
++FormatData/hr/MonthNarrows/11=12.
++FormatData/hr/MonthNarrows/12=
++FormatData/lt/MonthNarrows/0=S
++FormatData/lt/MonthNarrows/1=V
++FormatData/lt/MonthNarrows/2=K
++FormatData/lt/MonthNarrows/3=B
++FormatData/lt/MonthNarrows/4=G
++FormatData/lt/MonthNarrows/5=B
++FormatData/lt/MonthNarrows/6=L
++FormatData/lt/MonthNarrows/7=R
++FormatData/lt/MonthNarrows/8=R
++FormatData/lt/MonthNarrows/9=S
++FormatData/lt/MonthNarrows/10=L
++FormatData/lt/MonthNarrows/11=G
++FormatData/lt/MonthNarrows/12=
++FormatData/sq/MonthNarrows/0=J
++FormatData/sq/MonthNarrows/1=S
++FormatData/sq/MonthNarrows/2=M
++FormatData/sq/MonthNarrows/3=P
++FormatData/sq/MonthNarrows/4=M
++FormatData/sq/MonthNarrows/5=Q
++FormatData/sq/MonthNarrows/6=K
++FormatData/sq/MonthNarrows/7=G
++FormatData/sq/MonthNarrows/8=S
++FormatData/sq/MonthNarrows/9=T
++FormatData/sq/MonthNarrows/10=N
++FormatData/sq/MonthNarrows/11=D
++FormatData/sq/MonthNarrows/12=
++FormatData/fr/MonthNarrows/0=J
++FormatData/fr/MonthNarrows/1=F
++FormatData/fr/MonthNarrows/2=M
++FormatData/fr/MonthNarrows/3=A
++FormatData/fr/MonthNarrows/4=M
++FormatData/fr/MonthNarrows/5=J
++FormatData/fr/MonthNarrows/6=J
++FormatData/fr/MonthNarrows/7=A
++FormatData/fr/MonthNarrows/8=S
++FormatData/fr/MonthNarrows/9=O
++FormatData/fr/MonthNarrows/10=N
++FormatData/fr/MonthNarrows/11=D
++FormatData/fr/MonthNarrows/12=
++FormatData/is/MonthNarrows/0=J
++FormatData/is/MonthNarrows/1=F
++FormatData/is/MonthNarrows/2=M
++FormatData/is/MonthNarrows/3=A
++FormatData/is/MonthNarrows/4=M
++FormatData/is/MonthNarrows/5=J
++FormatData/is/MonthNarrows/6=J
++FormatData/is/MonthNarrows/7=\u00c1
++FormatData/is/MonthNarrows/8=L
++FormatData/is/MonthNarrows/9=O
++FormatData/is/MonthNarrows/10=N
++FormatData/is/MonthNarrows/11=D
++FormatData/is/MonthNarrows/12=
++FormatData/de/MonthNarrows/0=J
++FormatData/de/MonthNarrows/1=F
++FormatData/de/MonthNarrows/2=M
++FormatData/de/MonthNarrows/3=A
++FormatData/de/MonthNarrows/4=M
++FormatData/de/MonthNarrows/5=J
++FormatData/de/MonthNarrows/6=J
++FormatData/de/MonthNarrows/7=A
++FormatData/de/MonthNarrows/8=S
++FormatData/de/MonthNarrows/9=O
++FormatData/de/MonthNarrows/10=N
++FormatData/de/MonthNarrows/11=D
++FormatData/de/MonthNarrows/12=
++FormatData/en/MonthNarrows/0=J
++FormatData/en/MonthNarrows/1=F
++FormatData/en/MonthNarrows/2=M
++FormatData/en/MonthNarrows/3=A
++FormatData/en/MonthNarrows/4=M
++FormatData/en/MonthNarrows/5=J
++FormatData/en/MonthNarrows/6=J
++FormatData/en/MonthNarrows/7=A
++FormatData/en/MonthNarrows/8=S
++FormatData/en/MonthNarrows/9=O
++FormatData/en/MonthNarrows/10=N
++FormatData/en/MonthNarrows/11=D
++FormatData/en/MonthNarrows/12=
++FormatData/ca/MonthNarrows/0=G
++FormatData/ca/MonthNarrows/1=F
++FormatData/ca/MonthNarrows/2=M
++FormatData/ca/MonthNarrows/3=A
++FormatData/ca/MonthNarrows/4=M
++FormatData/ca/MonthNarrows/5=J
++FormatData/ca/MonthNarrows/6=G
++FormatData/ca/MonthNarrows/7=A
++FormatData/ca/MonthNarrows/8=S
++FormatData/ca/MonthNarrows/9=O
++FormatData/ca/MonthNarrows/10=N
++FormatData/ca/MonthNarrows/11=D
++FormatData/ca/MonthNarrows/12=
++FormatData/sl/MonthNarrows/0=j
++FormatData/sl/MonthNarrows/1=f
++FormatData/sl/MonthNarrows/2=m
++FormatData/sl/MonthNarrows/3=a
++FormatData/sl/MonthNarrows/4=m
++FormatData/sl/MonthNarrows/5=j
++FormatData/sl/MonthNarrows/6=j
++FormatData/sl/MonthNarrows/7=a
++FormatData/sl/MonthNarrows/8=s
++FormatData/sl/MonthNarrows/9=o
++FormatData/sl/MonthNarrows/10=n
++FormatData/sl/MonthNarrows/11=d
++FormatData/sl/MonthNarrows/12=
++FormatData/fi/MonthNarrows/0=T
++FormatData/fi/MonthNarrows/1=H
++FormatData/fi/MonthNarrows/2=M
++FormatData/fi/MonthNarrows/3=H
++FormatData/fi/MonthNarrows/4=T
++FormatData/fi/MonthNarrows/5=K
++FormatData/fi/MonthNarrows/6=H
++FormatData/fi/MonthNarrows/7=E
++FormatData/fi/MonthNarrows/8=S
++FormatData/fi/MonthNarrows/9=L
++FormatData/fi/MonthNarrows/10=M
++FormatData/fi/MonthNarrows/11=J
++FormatData/fi/MonthNarrows/12=
++FormatData/mk/MonthNarrows/0=\u0458
++FormatData/mk/MonthNarrows/1=\u0444
++FormatData/mk/MonthNarrows/2=\u043c
++FormatData/mk/MonthNarrows/3=\u0430
++FormatData/mk/MonthNarrows/4=\u043c
++FormatData/mk/MonthNarrows/5=\u0458
++FormatData/mk/MonthNarrows/6=\u0458
++FormatData/mk/MonthNarrows/7=\u0430
++FormatData/mk/MonthNarrows/8=\u0441
++FormatData/mk/MonthNarrows/9=\u043e
++FormatData/mk/MonthNarrows/10=\u043d
++FormatData/mk/MonthNarrows/11=\u0434
++FormatData/mk/MonthNarrows/12=
++FormatData/sr-Latn/MonthNarrows/0=j
++FormatData/sr-Latn/MonthNarrows/1=f
++FormatData/sr-Latn/MonthNarrows/2=m
++FormatData/sr-Latn/MonthNarrows/3=a
++FormatData/sr-Latn/MonthNarrows/4=m
++FormatData/sr-Latn/MonthNarrows/5=j
++FormatData/sr-Latn/MonthNarrows/6=j
++FormatData/sr-Latn/MonthNarrows/7=a
++FormatData/sr-Latn/MonthNarrows/8=s
++FormatData/sr-Latn/MonthNarrows/9=o
++FormatData/sr-Latn/MonthNarrows/10=n
++FormatData/sr-Latn/MonthNarrows/11=d
++FormatData/sr-Latn/MonthNarrows/12=
++FormatData/th/MonthNarrows/0=\u0e21.\u0e04.
++FormatData/th/MonthNarrows/1=\u0e01.\u0e1e.
++FormatData/th/MonthNarrows/2=\u0e21\u0e35.\u0e04.
++FormatData/th/MonthNarrows/3=\u0e40\u0e21.\u0e22.
++FormatData/th/MonthNarrows/4=\u0e1e.\u0e04.
++FormatData/th/MonthNarrows/5=\u0e21\u0e34.\u0e22
++FormatData/th/MonthNarrows/6=\u0e01.\u0e04.
++FormatData/th/MonthNarrows/7=\u0e2a.\u0e04.
++FormatData/th/MonthNarrows/8=\u0e01.\u0e22.
++FormatData/th/MonthNarrows/9=\u0e15.\u0e04.
++FormatData/th/MonthNarrows/10=\u0e1e.\u0e22.
++FormatData/th/MonthNarrows/11=\u0e18.\u0e04.
++FormatData/th/MonthNarrows/12=
++FormatData/ar/MonthNarrows/0=\u064a
++FormatData/ar/MonthNarrows/1=\u0641
++FormatData/ar/MonthNarrows/2=\u0645
++FormatData/ar/MonthNarrows/3=\u0623
++FormatData/ar/MonthNarrows/4=\u0648
++FormatData/ar/MonthNarrows/5=\u0646
++FormatData/ar/MonthNarrows/6=\u0644
++FormatData/ar/MonthNarrows/7=\u063a
++FormatData/ar/MonthNarrows/8=\u0633
++FormatData/ar/MonthNarrows/9=\u0643
++FormatData/ar/MonthNarrows/10=\u0628
++FormatData/ar/MonthNarrows/11=\u062f
++FormatData/ar/MonthNarrows/12=
++FormatData/ru/MonthNarrows/0=\u042f
++FormatData/ru/MonthNarrows/1=\u0424
++FormatData/ru/MonthNarrows/2=\u041c
++FormatData/ru/MonthNarrows/3=\u0410
++FormatData/ru/MonthNarrows/4=\u041c
++FormatData/ru/MonthNarrows/5=\u0418
++FormatData/ru/MonthNarrows/6=\u0418
++FormatData/ru/MonthNarrows/7=\u0410
++FormatData/ru/MonthNarrows/8=\u0421
++FormatData/ru/MonthNarrows/9=\u041e
++FormatData/ru/MonthNarrows/10=\u041d
++FormatData/ru/MonthNarrows/11=\u0414
++FormatData/ru/MonthNarrows/12=
++FormatData/ms/MonthNarrows/0=J
++FormatData/ms/MonthNarrows/1=F
++FormatData/ms/MonthNarrows/2=M
++FormatData/ms/MonthNarrows/3=A
++FormatData/ms/MonthNarrows/4=M
++FormatData/ms/MonthNarrows/5=J
++FormatData/ms/MonthNarrows/6=J
++FormatData/ms/MonthNarrows/7=O
++FormatData/ms/MonthNarrows/8=S
++FormatData/ms/MonthNarrows/9=O
++FormatData/ms/MonthNarrows/10=N
++FormatData/ms/MonthNarrows/11=D
++FormatData/ms/MonthNarrows/12=
++FormatData/nl/MonthNarrows/0=J
++FormatData/nl/MonthNarrows/1=F
++FormatData/nl/MonthNarrows/2=M
++FormatData/nl/MonthNarrows/3=A
++FormatData/nl/MonthNarrows/4=M
++FormatData/nl/MonthNarrows/5=J
++FormatData/nl/MonthNarrows/6=J
++FormatData/nl/MonthNarrows/7=A
++FormatData/nl/MonthNarrows/8=S
++FormatData/nl/MonthNarrows/9=O
++FormatData/nl/MonthNarrows/10=N
++FormatData/nl/MonthNarrows/11=D
++FormatData/nl/MonthNarrows/12=
++FormatData/vi/MonthNarrows/0=1
++FormatData/vi/MonthNarrows/1=2
++FormatData/vi/MonthNarrows/2=3
++FormatData/vi/MonthNarrows/3=4
++FormatData/vi/MonthNarrows/4=5
++FormatData/vi/MonthNarrows/5=6
++FormatData/vi/MonthNarrows/6=7
++FormatData/vi/MonthNarrows/7=8
++FormatData/vi/MonthNarrows/8=9
++FormatData/vi/MonthNarrows/9=10
++FormatData/vi/MonthNarrows/10=11
++FormatData/vi/MonthNarrows/11=12
++FormatData/vi/MonthNarrows/12=
++FormatData/sr/MonthNarrows/0=\u0458
++FormatData/sr/MonthNarrows/1=\u0444
++FormatData/sr/MonthNarrows/2=\u043c
++FormatData/sr/MonthNarrows/3=\u0430
++FormatData/sr/MonthNarrows/4=\u043c
++FormatData/sr/MonthNarrows/5=\u0458
++FormatData/sr/MonthNarrows/6=\u0458
++FormatData/sr/MonthNarrows/7=\u0430
++FormatData/sr/MonthNarrows/8=\u0441
++FormatData/sr/MonthNarrows/9=\u043e
++FormatData/sr/MonthNarrows/10=\u043d
++FormatData/sr/MonthNarrows/11=\u0434
++FormatData/sr/MonthNarrows/12=
++FormatData/mt/MonthNarrows/0=J
++FormatData/mt/MonthNarrows/1=F
++FormatData/mt/MonthNarrows/2=M
++FormatData/mt/MonthNarrows/3=A
++FormatData/mt/MonthNarrows/4=M
++FormatData/mt/MonthNarrows/5=\u0120
++FormatData/mt/MonthNarrows/6=L
++FormatData/mt/MonthNarrows/7=A
++FormatData/mt/MonthNarrows/8=S
++FormatData/mt/MonthNarrows/9=O
++FormatData/mt/MonthNarrows/10=N
++FormatData/mt/MonthNarrows/11=D
++FormatData/mt/MonthNarrows/12=
++FormatData/da/MonthNarrows/0=J
++FormatData/da/MonthNarrows/1=F
++FormatData/da/MonthNarrows/2=M
++FormatData/da/MonthNarrows/3=A
++FormatData/da/MonthNarrows/4=M
++FormatData/da/MonthNarrows/5=J
++FormatData/da/MonthNarrows/6=J
++FormatData/da/MonthNarrows/7=A
++FormatData/da/MonthNarrows/8=S
++FormatData/da/MonthNarrows/9=O
++FormatData/da/MonthNarrows/10=N
++FormatData/da/MonthNarrows/11=D
++FormatData/da/MonthNarrows/12=
++FormatData/ro/MonthNarrows/0=I
++FormatData/ro/MonthNarrows/1=F
++FormatData/ro/MonthNarrows/2=M
++FormatData/ro/MonthNarrows/3=A
++FormatData/ro/MonthNarrows/4=M
++FormatData/ro/MonthNarrows/5=I
++FormatData/ro/MonthNarrows/6=I
++FormatData/ro/MonthNarrows/7=A
++FormatData/ro/MonthNarrows/8=S
++FormatData/ro/MonthNarrows/9=O
++FormatData/ro/MonthNarrows/10=N
++FormatData/ro/MonthNarrows/11=D
++FormatData/ro/MonthNarrows/12=
++FormatData/no/MonthNarrows/0=J
++FormatData/no/MonthNarrows/1=F
++FormatData/no/MonthNarrows/2=M
++FormatData/no/MonthNarrows/3=A
++FormatData/no/MonthNarrows/4=M
++FormatData/no/MonthNarrows/5=J
++FormatData/no/MonthNarrows/6=J
++FormatData/no/MonthNarrows/7=A
++FormatData/no/MonthNarrows/8=S
++FormatData/no/MonthNarrows/9=O
++FormatData/no/MonthNarrows/10=N
++FormatData/no/MonthNarrows/11=D
++FormatData/no/MonthNarrows/12=
++FormatData/pl/MonthNarrows/0=s
++FormatData/pl/MonthNarrows/1=l
++FormatData/pl/MonthNarrows/2=m
++FormatData/pl/MonthNarrows/3=k
++FormatData/pl/MonthNarrows/4=m
++FormatData/pl/MonthNarrows/5=c
++FormatData/pl/MonthNarrows/6=l
++FormatData/pl/MonthNarrows/7=s
++FormatData/pl/MonthNarrows/8=w
++FormatData/pl/MonthNarrows/9=p
++FormatData/pl/MonthNarrows/10=l
++FormatData/pl/MonthNarrows/11=g
++FormatData/pl/MonthNarrows/12=
++FormatData/iw/MonthNarrows/0=1
++FormatData/iw/MonthNarrows/1=2
++FormatData/iw/MonthNarrows/2=3
++FormatData/iw/MonthNarrows/3=4
++FormatData/iw/MonthNarrows/4=5
++FormatData/iw/MonthNarrows/5=6
++FormatData/iw/MonthNarrows/6=7
++FormatData/iw/MonthNarrows/7=8
++FormatData/iw/MonthNarrows/8=9
++FormatData/iw/MonthNarrows/9=10
++FormatData/iw/MonthNarrows/10=11
++FormatData/iw/MonthNarrows/11=12
++FormatData/iw/MonthNarrows/12=
++FormatData/zh/MonthNarrows/0=1
++FormatData/zh/MonthNarrows/1=2
++FormatData/zh/MonthNarrows/2=3
++FormatData/zh/MonthNarrows/3=4
++FormatData/zh/MonthNarrows/4=5
++FormatData/zh/MonthNarrows/5=6
++FormatData/zh/MonthNarrows/6=7
++FormatData/zh/MonthNarrows/7=8
++FormatData/zh/MonthNarrows/8=9
++FormatData/zh/MonthNarrows/9=10
++FormatData/zh/MonthNarrows/10=11
++FormatData/zh/MonthNarrows/11=12
++FormatData/zh/MonthNarrows/12=
+--- ./jdk/test/sun/text/resources/LocaleDataTest.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/text/resources/LocaleDataTest.java Wed Feb 04 12:14:43 2015 -0800
+@@ -36,7 +36,7 @@
+ * 6919624 6998391 7019267 7020960 7025837 7020583 7036905 7066203 7101495
+ * 7003124 7085757 7028073 7171028 7189611 8000983 7195759 8004489 8006509
+ * 7114053 7074882 7040556 8013836 8021121 6192407 6931564 8027695 7090826
+- * 8017142 8037343 8055222
++ * 8017142 8037343 8055222 8042126
+ * @summary Verify locale data
+ *
+ */
+--- ./jdk/test/sun/tools/jrunscript/jrunscriptTest.sh Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/sun/tools/jrunscript/jrunscriptTest.sh Wed Feb 04 12:14:43 2015 -0800
+@@ -42,7 +42,7 @@
+ rm -f jrunscriptTest.out 2>/dev/null
+ ${JRUNSCRIPT} -J-Djava.awt.headless=true -l nashorn > jrunscriptTest.out 2>&1 <<EOF
+ v = 2 + 5;
+-v *= 5;
++v *= 5; v.doubleValue();
+ v = v + " is the value";
+ if (v != 0) { println('yes v != 0'); }
+ java.lang.System.out.println('hello world from script');
+--- ./jdk/test/tools/launcher/TestSpecialArgs.java Mon Dec 08 12:29:42 2014 -0800
++++ ./jdk/test/tools/launcher/TestSpecialArgs.java Wed Feb 04 12:14:43 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -23,7 +23,7 @@
+
+ /*
+ * @test
+- * @bug 7124089 7131021
++ * @bug 7124089 7131021 8042469
+ * @summary Checks for MacOSX specific flags are accepted or rejected, and
+ * MacOSX platforms specific environment is consistent.
+ * @compile -XDignore.symbol.file TestSpecialArgs.java EnvironmentVariables.java
+@@ -69,6 +69,137 @@
+ throw new RuntimeException("Error: argument was accepted ????");
+ }
+ }
++
++ /*
++ * test argument : -XX:NativeMemoryTracking=value
++ * A JVM flag, comsumed by the JVM, but requiring launcher
++ * to set an environmental variable if and only if value is supplied.
++ * Test and order:
++ * 1) execute with valid parameter: -XX:NativeMemoryTracking=MyValue
++ * a) check for correct env variable name: "NMT_LEVEL_" + pid
++ * b) check that "MyValue" was found in local env.
++ * 2) execute with invalid parameter: -XX:NativeMemoryTracking=
++ * !) Won't find "NativeMemoryTracking:"
++ * Code to create env variable not executed.
++ * 3) execute with invalid parameter: -XX:NativeMemoryTracking
++ * !) Won't find "NativeMemoryTracking:"
++ * Code to create env variable not executed.
++ * 4) give and invalid value and check to make sure JVM commented
++ */
++ { // NativeMemoryTracking
++ String launcherPidString = "launcher.pid=";
++ String envVarPidString = "TRACER_MARKER: NativeMemoryTracking: env var is NMT_LEVEL_";
++ String NMT_Option_Value = "off";
++ String myClassName = "helloworld";
++ boolean haveLauncherPid = false;
++
++ // === Run the tests ===
++
++ // ---Test 1a
++ tr = doExec(envMap,javaCmd, "-XX:NativeMemoryTracking=" + NMT_Option_Value,
++ "-version");
++
++ // get the PID from the env var we set for the JVM
++ String envVarPid = null;
++ for (String line : tr.testOutput) {
++ if (line.contains(envVarPidString)) {
++ int sindex = envVarPidString.length();
++ envVarPid = line.substring(sindex);
++ break;
++ }
++ }
++ // did we find envVarPid?
++ if (envVarPid == null) {
++ System.out.println(tr);
++ throw new RuntimeException("Error: failed to find env Var Pid in tracking info");
++ }
++ // we think we found the pid string. min test, not "".
++ if (envVarPid.length() < 1) {
++ System.out.println(tr);
++ throw new RuntimeException("Error: env Var Pid in tracking info is empty string");
++ }
++
++ /*
++ * On Linux, Launcher Tracking will print the PID. Use this info
++ * to validate what we got as the PID in the Launcher itself.
++ * Linux is the only one that prints this, and trying to get it
++ * here for win is awful. So let the linux test make sure we get
++ * the valid pid, and for non-linux, just make sure pid string is
++ * non-zero.
++ */
++ if (isLinux) {
++ // get what the test says is the launcher pid
++ String launcherPid = null;
++ for (String line : tr.testOutput) {
++ int index = line.indexOf(launcherPidString);
++ if (index >= 0) {
++ int sindex = index + launcherPidString.length();
++ int tindex = sindex + line.substring(sindex).indexOf("'");
++ System.out.println("DEBUG INFO: sindex = " + sindex);
++ System.out.println("DEBUG INFO: searching substring: " + line.substring(sindex));
++ System.out.println("DEBUG INFO: tindex = " + tindex);
++ // DEBUG INFO
++ System.out.println(tr);
++ launcherPid = line.substring(sindex, tindex);
++ break;
++ }
++ }
++ if (launcherPid == null) {
++ System.out.println(tr);
++ throw new RuntimeException("Error: failed to find launcher Pid in launcher tracking info");
++ }
++
++ // did we create the env var with the correct pid?
++ if (!launcherPid.equals(envVarPid)) {
++ System.out.println(tr);
++ System.out.println("Error: wrong pid in creating env var");
++ System.out.println("Error Info: launcherPid = " + launcherPid);
++ System.out.println("Error Info: envVarPid = " + envVarPid);
++ throw new RuntimeException("Error: wrong pid in creating env var");
++ }
++ }
++
++
++ // --- Test 1b
++ if (!tr.contains("NativeMemoryTracking: got value " + NMT_Option_Value)) {
++ System.out.println(tr);
++ throw new RuntimeException("Error: Valid param failed to set env variable");
++ }
++
++ // --- Test 2
++ tr = doExec(envMap,javaCmd, "-XX:NativeMemoryTracking=",
++ "-version");
++ if (tr.contains("NativeMemoryTracking:")) {
++ System.out.println(tr);
++ throw new RuntimeException("Error: invalid param caused env variable to be erroneously created");
++ }
++ if (!tr.contains("Syntax error, expecting -XX:NativeMemoryTracking=")) {
++ System.out.println(tr);
++ throw new RuntimeException("Error: invalid param not checked by JVM");
++ }
++
++ // --- Test 3
++ tr = doExec(envMap,javaCmd, "-XX:NativeMemoryTracking",
++ "-version");
++ if (tr.contains("NativeMemoryTracking:")) {
++ System.out.println(tr);
++ throw new RuntimeException("Error: invalid param caused env variable to be erroneously created");
++ }
++ if (!tr.contains("Syntax error, expecting -XX:NativeMemoryTracking=")) {
++ System.out.println(tr);
++ throw new RuntimeException("Error: invalid param not checked by JVM");
++ }
++ // --- Test 4
++ tr = doExec(envMap,javaCmd, "-XX:NativeMemoryTracking=BADVALUE",
++ "-version");
++ if (!tr.contains("expecting -XX:NativeMemoryTracking")) {
++ System.out.println(tr);
++ throw new RuntimeException("Error: invalid param did not get JVM Syntax error message");
++ }
++
++ } // NativeMemoryTracking
++
++
+ // MacOSX specific tests ensue......
+ if (!isMacOSX)
+ return;
+--- ./langtools/.hgtags Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/.hgtags Wed Feb 04 12:14:46 2015 -0800
+@@ -347,3 +347,29 @@
+ 99c3209f228e1f9aa874b6bd0908fd5d9ebf7078 jdk8u31-b10
+ e72be544fa9e247fba3c6bb61e291d80e127a461 jdk8u31-b11
+ c956b12b30ee21a4fc5df1871fa3b01e84310ebe jdk8u31-b12
++7a34ec7bb1c831e82ac88da578a028572b676260 jdk8u31-b13
++d231957fe3103e790465fcf058fb8cb33bbc4c4e jdk8u40-b00
++bf89a471779d13a9407f7d1c86f7716258bc4aa6 jdk8u40-b01
++0b6cc4ea670f5d17b56c088f202869bdbb80a5ce jdk8u40-b02
++5183e8b58a03206ca65b4b211be85b3740a70c39 jdk8u40-b03
++cde557bc48f5cd0c6b6aa70bdbc7563677379347 jdk8u40-b04
++a36fce70b505ec15be8353d40d417d331fcce740 jdk8u40-b05
++7c3d27120b92b6abbd2df910722405dfb02d4399 jdk8u40-b06
++2fa3858a281f9deae15bcc49224efd5b951b745d jdk8u40-b07
++d3515520e68e26c1012fca18eef190f8aff3a7a1 jdk8u40-b08
++8bb38a35072279618aa2cacd4fea74155a6dccf9 jdk8u40-b09
++69b84370397fbb5a66b99578242c47da7f8b3cb5 jdk8u40-b10
++d3c93dc64c5e1ffd610fb31362a78bedfd8097ba jdk8u40-b11
++e7560bceb36a933f5eb6ce8c33dce030ba0288f2 jdk8u40-b12
++88ce114c6adc387dc7fc5831b8263f152f0412fb jdk8u40-b13
++f18c5b47f27b387d94487890684abe5a554b0d9b jdk8u40-b14
++682a6c1aefd766eaf774ffeb1207a5189edf94d6 jdk8u40-b15
++74c51ff270c51d17732250411fe9cd5392bc925e jdk8u40-b16
++a12a9932f649dd3df174d3e340527433d3695c49 jdk8u40-b17
++94f30e5fde53e3ddcd3c4e9842349318eae8fe10 jdk8u40-b18
++0c514d1fd006fc79d35b670de10c370c8d559db7 jdk8u40-b19
++c3d6d1a5339952fbe4124e700407b7211446c99c jdk8u40-b20
++9113c7c8d902ec94b28ca0ef4a6466bdba65fcfc jdk8u40-b21
++79177246b3dbe5296fb53755d8695acdaef59fc8 jdk8u40-b22
++fb294b49373bda0b3afc7f011d64ecefed73b42e jdk8u40-b23
++c5d4ffa220f3824c2ea5d39dc99d41a9df9e5ae5 jdk8u40-b24
+--- ./langtools/THIRD_PARTY_README Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/THIRD_PARTY_README Wed Feb 04 12:14:46 2015 -0800
+@@ -3385,7 +3385,7 @@
+ included with JRE 8, JDK 8, and OpenJDK 8.
+
+ Apache Commons Math 3.2
+- Apache Derby 10.10.1.3
++ Apache Derby 10.11.1.2
+ Apache Jakarta BCEL 5.1
+ Apache Jakarta Regexp 1.4
+ Apache Santuario XML Security for Java 1.5.4
+--- ./langtools/src/share/classes/com/sun/source/doctree/package-info.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/source/doctree/package-info.java Wed Feb 04 12:14:46 2015 -0800
+@@ -29,7 +29,7 @@
+ *
+ * @author Jonathan Gibbons
+ * @since 1.8
+- * @see <a href="http://download.oracle.com/javase/6/docs/technotes/tools/solaris/javadoc.html#javadoctags">http://download.oracle.com/javase/6/docs/technotes/tools/solaris/javadoc.html#javadoctags</a>
++ * @see <a href="https://docs.oracle.com/javase/6/docs/technotes/tools/solaris/javadoc.html#javadoctags">https://docs.oracle.com/javase/6/docs/technotes/tools/solaris/javadoc.html#javadoctags</a>
+ */
+ @jdk.Exported
+ package com.sun.source.doctree;
+--- ./langtools/src/share/classes/com/sun/tools/classfile/BootstrapMethods_attribute.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/classfile/BootstrapMethods_attribute.java Wed Feb 04 12:14:46 2015 -0800
+@@ -29,7 +29,7 @@
+
+ /**
+ * See JVMS 4.7.21
+- * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.21
++ * https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.21
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+--- ./langtools/src/share/classes/com/sun/tools/javac/code/Source.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/javac/code/Source.java Wed Feb 04 12:14:46 2015 -0800
+@@ -233,6 +233,9 @@
+ public boolean allowFunctionalInterfaceMostSpecific() {
+ return compareTo(JDK1_8) >= 0;
+ }
++ public boolean allowPostApplicabilityVarargsAccessCheck() {
++ return compareTo(JDK1_8) >= 0;
++ }
+ public static SourceVersion toSourceVersion(Source source) {
+ switch(source) {
+ case JDK1_2:
+--- ./langtools/src/share/classes/com/sun/tools/javac/code/Types.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/javac/code/Types.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1305,7 +1305,8 @@
+ UndetVar undetvar = (UndetVar)t;
+ WildcardType wt = (WildcardType)s.unannotatedType();
+ switch(wt.kind) {
+- case UNBOUND: //similar to ? extends Object
++ case UNBOUND:
++ break;
+ case EXTENDS: {
+ Type bound = wildUpperBound(s);
+ undetvar.addBound(InferenceBound.UPPER, bound, this);
+@@ -1396,6 +1397,7 @@
+ else {
+ // debugContainsType(t, s);
+ return isSameWildcard(t, s)
++ || t.type == s
+ || isCaptureOf(s, t)
+ || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), cvarLowerBound(wildLowerBound(s)))) &&
+ // TODO: JDK-8039214, cvarUpperBound call here is incorrect
+@@ -1890,7 +1892,12 @@
+ * Mapping to take element type of an arraytype
+ */
+ private Mapping elemTypeFun = new Mapping ("elemTypeFun") {
+- public Type apply(Type t) { return elemtype(t); }
++ public Type apply(Type t) {
++ while (t.hasTag(TYPEVAR)) {
++ t = t.getUpperBound();
++ }
++ return elemtype(t);
++ }
+ };
+
+ /**
+@@ -2954,6 +2961,12 @@
+ }
+
+ @Override
++ public Type visitUndetVar(UndetVar t, Void ignored) {
++ //do nothing - we should not replace inside undet variables
++ return t;
++ }
++
++ @Override
+ public Type visitClassType(ClassType t, Void ignored) {
+ if (!t.isCompound()) {
+ List<Type> typarams = t.getTypeArguments();
+@@ -3513,40 +3526,46 @@
+ }
+
+ /**
+- * Return the least upper bound of pair of types. if the lub does
++ * Return the least upper bound of list of types. if the lub does
+ * not exist return null.
+ */
+- public Type lub(Type t1, Type t2) {
+- return lub(List.of(t1, t2));
++ public Type lub(List<Type> ts) {
++ return lub(ts.toArray(new Type[ts.length()]));
+ }
+
+ /**
+ * Return the least upper bound (lub) of set of types. If the lub
+ * does not exist return the type of null (bottom).
+ */
+- public Type lub(List<Type> ts) {
++ public Type lub(Type... ts) {
++ final int UNKNOWN_BOUND = 0;
+ final int ARRAY_BOUND = 1;
+ final int CLASS_BOUND = 2;
+- int boundkind = 0;
+- for (Type t : ts) {
++
++ int[] kinds = new int[ts.length];
++
++ int boundkind = UNKNOWN_BOUND;
++ for (int i = 0 ; i < ts.length ; i++) {
++ Type t = ts[i];
+ switch (t.getTag()) {
+ case CLASS:
+- boundkind |= CLASS_BOUND;
++ boundkind |= kinds[i] = CLASS_BOUND;
+ break;
+ case ARRAY:
+- boundkind |= ARRAY_BOUND;
++ boundkind |= kinds[i] = ARRAY_BOUND;
+ break;
+ case TYPEVAR:
+ do {
+ t = t.getUpperBound();
+ } while (t.hasTag(TYPEVAR));
+ if (t.hasTag(ARRAY)) {
+- boundkind |= ARRAY_BOUND;
++ boundkind |= kinds[i] = ARRAY_BOUND;
+ } else {
+- boundkind |= CLASS_BOUND;
++ boundkind |= kinds[i] = CLASS_BOUND;
+ }
+ break;
+ default:
++ kinds[i] = UNKNOWN_BOUND;
+ if (t.isPrimitive())
+ return syms.errType;
+ }
+@@ -3557,15 +3576,16 @@
+
+ case ARRAY_BOUND:
+ // calculate lub(A[], B[])
+- List<Type> elements = Type.map(ts, elemTypeFun);
+- for (Type t : elements) {
+- if (t.isPrimitive()) {
++ Type[] elements = new Type[ts.length];
++ for (int i = 0 ; i < ts.length ; i++) {
++ Type elem = elements[i] = elemTypeFun.apply(ts[i]);
++ if (elem.isPrimitive()) {
+ // if a primitive type is found, then return
+ // arraySuperType unless all the types are the
+ // same
+- Type first = ts.head;
+- for (Type s : ts.tail) {
+- if (!isSameType(first, s)) {
++ Type first = ts[0];
++ for (int j = 1 ; j < ts.length ; j++) {
++ if (!isSameType(first, ts[j])) {
+ // lub(int[], B[]) is Cloneable & Serializable
+ return arraySuperType();
+ }
+@@ -3580,13 +3600,20 @@
+
+ case CLASS_BOUND:
+ // calculate lub(A, B)
+- while (!ts.head.hasTag(CLASS) && !ts.head.hasTag(TYPEVAR)) {
+- ts = ts.tail;
++ int startIdx = 0;
++ for (int i = 0; i < ts.length ; i++) {
++ Type t = ts[i];
++ if (t.hasTag(CLASS) || t.hasTag(TYPEVAR)) {
++ break;
++ } else {
++ startIdx++;
++ }
+ }
+- Assert.check(!ts.isEmpty());
++ Assert.check(startIdx < ts.length);
+ //step 1 - compute erased candidate set (EC)
+- List<Type> cl = erasedSupertypes(ts.head);
+- for (Type t : ts.tail) {
++ List<Type> cl = erasedSupertypes(ts[startIdx]);
++ for (int i = startIdx + 1 ; i < ts.length ; i++) {
++ Type t = ts[i];
+ if (t.hasTag(CLASS) || t.hasTag(TYPEVAR))
+ cl = intersect(cl, erasedSupertypes(t));
+ }
+@@ -3595,9 +3622,10 @@
+ //step 3 - for each element G in MEC, compute lci(Inv(G))
+ List<Type> candidates = List.nil();
+ for (Type erasedSupertype : mec) {
+- List<Type> lci = List.of(asSuper(ts.head, erasedSupertype.tsym));
+- for (Type t : ts) {
+- lci = intersect(lci, List.of(asSuper(t, erasedSupertype.tsym)));
++ List<Type> lci = List.of(asSuper(ts[startIdx], erasedSupertype.tsym));
++ for (int i = startIdx + 1 ; i < ts.length ; i++) {
++ Type superType = asSuper(ts[i], erasedSupertype.tsym);
++ lci = intersect(lci, superType != null ? List.of(superType) : List.<Type>nil());
+ }
+ candidates = candidates.appendList(lci);
+ }
+@@ -3608,9 +3636,9 @@
+ default:
+ // calculate lub(A, B[])
+ List<Type> classes = List.of(arraySuperType());
+- for (Type t : ts) {
+- if (!t.hasTag(ARRAY)) // Filter out any arrays
+- classes = classes.prepend(t);
++ for (int i = 0 ; i < ts.length ; i++) {
++ if (kinds[i] != ARRAY_BOUND) // Filter out any arrays
++ classes = classes.prepend(ts[i]);
+ }
+ // lub(A, B[]) is lub(A, arraySuperType)
+ return lub(classes);
+--- ./langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Feb 04 12:14:46 2015 -0800
+@@ -252,36 +252,30 @@
+ */
+ Type check(final JCTree tree, final Type found, final int ownkind, final ResultInfo resultInfo) {
+ InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
+- Type owntype = found;
+- if (!owntype.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) {
+- if (allowPoly && inferenceContext.free(found)) {
+- if ((ownkind & ~resultInfo.pkind) == 0) {
+- owntype = resultInfo.check(tree, inferenceContext.asUndetVar(owntype));
+- } else {
+- log.error(tree.pos(), "unexpected.type",
+- kindNames(resultInfo.pkind),
+- kindName(ownkind));
+- owntype = types.createErrorType(owntype);
+- }
++ Type owntype;
++ if (!found.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) {
++ if ((ownkind & ~resultInfo.pkind) != 0) {
++ log.error(tree.pos(), "unexpected.type",
++ kindNames(resultInfo.pkind),
++ kindName(ownkind));
++ owntype = types.createErrorType(found);
++ } else if (allowPoly && inferenceContext.free(found)) {
++ //delay the check if there are inference variables in the found type
++ //this means we are dealing with a partially inferred poly expression
++ owntype = resultInfo.pt;
+ inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() {
+ @Override
+ public void typesInferred(InferenceContext inferenceContext) {
+ ResultInfo pendingResult =
+- resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
++ resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
+ check(tree, inferenceContext.asInstType(found), ownkind, pendingResult);
+ }
+ });
+- return tree.type = resultInfo.pt;
+ } else {
+- if ((ownkind & ~resultInfo.pkind) == 0) {
+- owntype = resultInfo.check(tree, owntype);
+- } else {
+- log.error(tree.pos(), "unexpected.type",
+- kindNames(resultInfo.pkind),
+- kindName(ownkind));
+- owntype = types.createErrorType(owntype);
+- }
++ owntype = resultInfo.check(tree, found);
+ }
++ } else {
++ owntype = found;
+ }
+ tree.type = owntype;
+ return owntype;
+@@ -293,7 +287,7 @@
+ * @param env The current environment.
+ */
+ boolean isAssignableAsBlankFinal(VarSymbol v, Env<AttrContext> env) {
+- Symbol owner = owner(env);
++ Symbol owner = env.info.scope.owner;
+ // owner refers to the innermost variable, method or
+ // initializer block declaration at this point.
+ return
+@@ -308,41 +302,6 @@
+ ((v.flags() & STATIC) != 0) == Resolve.isStatic(env));
+ }
+
+- /**
+- * Return the innermost enclosing owner symbol in a given attribution context
+- */
+- Symbol owner(Env<AttrContext> env) {
+- while (true) {
+- switch (env.tree.getTag()) {
+- case VARDEF:
+- //a field can be owner
+- VarSymbol vsym = ((JCVariableDecl)env.tree).sym;
+- if (vsym.owner.kind == TYP) {
+- return vsym;
+- }
+- break;
+- case METHODDEF:
+- //method def is always an owner
+- return ((JCMethodDecl)env.tree).sym;
+- case CLASSDEF:
+- //class def is always an owner
+- return ((JCClassDecl)env.tree).sym;
+- case BLOCK:
+- //static/instance init blocks are owner
+- Symbol blockSym = env.info.scope.owner;
+- if ((blockSym.flags() & BLOCK) != 0) {
+- return blockSym;
+- }
+- break;
+- case TOPLEVEL:
+- //toplevel is always an owner (for pkge decls)
+- return env.info.scope.owner;
+- }
+- Assert.checkNonNull(env.next);
+- env = env.next;
+- }
+- }
+-
+ /** Check that variable can be assigned to.
+ * @param pos The current source code position.
+ * @param v The assigned varaible
+@@ -1051,8 +1010,12 @@
+ // parameters have already been entered
+ env.info.scope.enter(tree.sym);
+ } else {
+- memberEnter.memberEnter(tree, env);
+- annotate.flush();
++ try {
++ annotate.enterStart();
++ memberEnter.memberEnter(tree, env);
++ } finally {
++ annotate.enterDone();
++ }
+ }
+ } else {
+ if (tree.init != null) {
+@@ -2335,6 +2298,7 @@
+ currentTarget = infer.instantiateFunctionalInterface(that,
+ currentTarget, explicitParamTypes, resultInfo.checkContext);
+ }
++ currentTarget = types.removeWildcards(currentTarget);
+ lambdaType = types.findDescriptorType(currentTarget);
+ } else {
+ currentTarget = Type.recoveryType;
+@@ -2727,7 +2691,7 @@
+ resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
+ isSerializable(currentTarget);
+ if (currentTarget != Type.recoveryType) {
+- currentTarget = targetChecker.visit(currentTarget, that);
++ currentTarget = types.removeWildcards(targetChecker.visit(currentTarget, that));
+ desc = types.findDescriptorType(currentTarget);
+ } else {
+ currentTarget = Type.recoveryType;
+@@ -3262,8 +3226,9 @@
+ elt = ((ArrayType)elt.unannotatedType()).elemtype;
+ if (elt.hasTag(TYPEVAR)) {
+ log.error(tree.pos(), "type.var.cant.be.deref");
+- result = types.createErrorType(tree.type);
+- return;
++ result = tree.type = types.createErrorType(tree.name, site.tsym, site);
++ tree.sym = tree.type.tsym;
++ return ;
+ }
+ }
+
+@@ -3279,6 +3244,10 @@
+ // Determine the symbol represented by the selection.
+ env.info.pendingResolutionPhase = null;
+ Symbol sym = selectSym(tree, sitesym, site, env, resultInfo);
++ if (sym.kind == VAR && sym.name != names._super && env.info.defaultSuperCallSite != null) {
++ log.error(tree.selected.pos(), "not.encl.class", site.tsym);
++ sym = syms.errSymbol;
++ }
+ if (sym.exists() && !isType(sym) && (pkind() & (PCK | TYP)) != 0) {
+ site = capture(site);
+ sym = selectSym(tree, sitesym, site, env, resultInfo);
+@@ -3665,7 +3634,7 @@
+ // and are subject to definite assignment checking.
+ if ((env.info.enclVar == v || v.pos > tree.pos) &&
+ v.owner.kind == TYP &&
+- canOwnInitializer(owner(env)) &&
++ enclosingInitEnv(env) != null &&
+ v.owner == env.info.scope.owner.enclClass() &&
+ ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) &&
+ (!env.tree.hasTag(ASSIGN) ||
+@@ -3685,6 +3654,36 @@
+ }
+
+ /**
++ * Returns the enclosing init environment associated with this env (if any). An init env
++ * can be either a field declaration env or a static/instance initializer env.
++ */
++ Env<AttrContext> enclosingInitEnv(Env<AttrContext> env) {
++ while (true) {
++ switch (env.tree.getTag()) {
++ case VARDEF:
++ JCVariableDecl vdecl = (JCVariableDecl)env.tree;
++ if (vdecl.sym.owner.kind == TYP) {
++ //field
++ return env;
++ }
++ break;
++ case BLOCK:
++ if (env.next.tree.hasTag(CLASSDEF)) {
++ //instance/static initializer
++ return env;
++ }
++ break;
++ case METHODDEF:
++ case CLASSDEF:
++ case TOPLEVEL:
++ return null;
++ }
++ Assert.checkNonNull(env.next);
++ env = env.next;
++ }
++ }
++
++ /**
+ * Check for illegal references to static members of enum. In
+ * an enum type, constructors and initializers may not
+ * reference its static members unless they are constant.
+@@ -3737,17 +3736,6 @@
+ v.name != names._class;
+ }
+
+- /** Can the given symbol be the owner of code which forms part
+- * if class initialization? This is the case if the symbol is
+- * a type or field, or if the symbol is the synthetic method.
+- * owning a block.
+- */
+- private boolean canOwnInitializer(Symbol sym) {
+- return
+- (sym.kind & (VAR | TYP)) != 0 ||
+- (sym.kind == MTH && (sym.flags() & BLOCK) != 0);
+- }
+-
+ Warner noteWarner = new Warner();
+
+ /**
+@@ -4516,14 +4504,15 @@
+ super.visitTypeTest(tree);
+ }
+ public void visitNewClass(JCNewClass tree) {
+- if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
+- checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
+- tree.clazz.type.tsym);
+- }
+- if (tree.def != null) {
+- checkForDeclarationAnnotations(tree.def.mods.annotations, tree.clazz.type.tsym);
+- }
+- if (tree.clazz.type != null) {
++ if (tree.clazz != null && tree.clazz.type != null) {
++ if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
++ checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
++ tree.clazz.type.tsym);
++ }
++ if (tree.def != null) {
++ checkForDeclarationAnnotations(tree.def.mods.annotations, tree.clazz.type.tsym);
++ }
++
+ validateAnnotatedType(tree.clazz, tree.clazz.type);
+ }
+ super.visitNewClass(tree);
+--- ./langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Feb 04 12:14:46 2015 -0800
+@@ -531,8 +531,8 @@
+
+ Type checkType(final DiagnosticPosition pos, final Type found, final Type req, final CheckContext checkContext) {
+ final Infer.InferenceContext inferenceContext = checkContext.inferenceContext();
+- if (inferenceContext.free(req)) {
+- inferenceContext.addFreeTypeListener(List.of(req), new FreeTypeListener() {
++ if (inferenceContext.free(req) || inferenceContext.free(found)) {
++ inferenceContext.addFreeTypeListener(List.of(req, found), new FreeTypeListener() {
+ @Override
+ public void typesInferred(InferenceContext inferenceContext) {
+ checkType(pos, inferenceContext.asInstType(found), inferenceContext.asInstType(req), checkContext);
+@@ -1715,7 +1715,12 @@
+
+ // Warn if a deprecated method overridden by a non-deprecated one.
+ if (!isDeprecatedOverrideIgnorable(other, origin)) {
+- checkDeprecated(TreeInfo.diagnosticPositionFor(m, tree), m, other);
++ Lint prevLint = setLint(lint.augment(m));
++ try {
++ checkDeprecated(TreeInfo.diagnosticPositionFor(m, tree), m, other);
++ } finally {
++ setLint(prevLint);
++ }
+ }
+ }
+ // where
+--- ./langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Feb 04 12:14:46 2015 -0800
+@@ -497,13 +497,11 @@
+ }
+ }
+ if (!progress) {
+- DeferredAttrContext dac = this;
+- while (dac != emptyDeferredAttrContext) {
+- if (dac.mode == AttrMode.SPECULATIVE) {
+- //unsticking does not take place during overload
+- break;
++ if (insideOverloadPhase()) {
++ for (DeferredAttrNode deferredNode: deferredAttrNodes) {
++ deferredNode.dt.tree.type = Type.noType;
+ }
+- dac = dac.parent;
++ return;
+ }
+ //remove all variables that have already been instantiated
+ //from the list of stuck variables
+@@ -519,6 +517,17 @@
+ }
+ }
+ }
++
++ private boolean insideOverloadPhase() {
++ DeferredAttrContext dac = this;
++ if (dac == emptyDeferredAttrContext) {
++ return false;
++ }
++ if (dac.mode == AttrMode.SPECULATIVE) {
++ return true;
++ }
++ return dac.parent.insideOverloadPhase();
++ }
+ }
+
+ /**
+@@ -579,6 +588,8 @@
+ return false;
+ }
+ } else {
++ Assert.check(!deferredAttrContext.insideOverloadPhase(),
++ "attribution shouldn't be happening here");
+ ResultInfo instResultInfo =
+ resultInfo.dup(deferredAttrContext.inferenceContext.asInstType(resultInfo.pt));
+ dt.check(instResultInfo, dummyStuckPolicy, basicCompleter);
+@@ -1314,6 +1325,12 @@
+ site = env.enclClass.sym.type;
+ }
+
++ while (site.hasTag(TYPEVAR)) {
++ site = site.getUpperBound();
++ }
++
++ site = types.capture(site);
++
+ List<Type> args = rs.dummyArgs(tree.args.length());
+ Name name = TreeInfo.name(tree.meth);
+
+@@ -1337,7 +1354,9 @@
+ @Override
+ public Symbol process(MethodSymbol ms) {
+ ArgumentExpressionKind kind = ArgumentExpressionKind.methodKind(ms, types);
+- return kind != ArgumentExpressionKind.POLY ? ms.getReturnType().tsym : null;
++ if (kind == ArgumentExpressionKind.POLY || ms.getReturnType().hasTag(TYPEVAR))
++ return null;
++ return ms.getReturnType().tsym;
+ }
+ @Override
+ public Symbol reduce(Symbol s1, Symbol s2) {
+--- ./langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Wed Feb 04 12:14:46 2015 -0800
+@@ -208,7 +208,7 @@
+
+ public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
+ new AliveAnalyzer().analyzeTree(env, make);
+- new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env);
++ new AssignAnalyzer().analyzeTree(env);
+ new FlowAnalyzer().analyzeTree(env, make);
+ new CaptureAnalyzer().analyzeTree(env, make);
+ }
+@@ -241,13 +241,19 @@
+ //related errors, which will allow for more errors to be detected
+ Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
+ try {
+- new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit) {
++ new AssignAnalyzer() {
++ Scope enclosedSymbols = new Scope(env.enclClass.sym);
++ @Override
++ public void visitVarDef(JCVariableDecl tree) {
++ enclosedSymbols.enter(tree.sym);
++ super.visitVarDef(tree);
++ }
+ @Override
+ protected boolean trackable(VarSymbol sym) {
+- return !env.info.scope.includes(sym) &&
++ return enclosedSymbols.includes(sym) &&
+ sym.owner.kind == MTH;
+ }
+- }.analyzeTree(env);
++ }.analyzeTree(env, that);
+ LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer();
+ flowAnalyzer.analyzeTree(env, that, make);
+ return flowAnalyzer.inferredThrownTypes;
+@@ -1373,12 +1379,12 @@
+ * effectively-final local variables/parameters.
+ */
+
+- public abstract static class AbstractAssignAnalyzer<P extends AbstractAssignAnalyzer.AbstractAssignPendingExit>
++ public abstract class AbstractAssignAnalyzer<P extends AbstractAssignAnalyzer<P>.AbstractAssignPendingExit>
+ extends BaseAnalyzer<P> {
+
+ /** The set of definitely assigned variables.
+ */
+- protected final Bits inits;
++ protected Bits inits;
+
+ /** The set of definitely unassigned variables.
+ */
+@@ -1432,13 +1438,7 @@
+ /** The starting position of the analysed tree */
+ int startPos;
+
+- final Symtab syms;
+-
+- protected Names names;
+-
+- final boolean enforceThisDotInit;
+-
+- public static class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit {
++ public class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit {
+
+ final Bits inits;
+ final Bits uninits;
+@@ -1460,17 +1460,14 @@
+ }
+ }
+
+- public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names, boolean enforceThisDotInit) {
+- this.inits = inits;
++ public AbstractAssignAnalyzer() {
++ this.inits = new Bits();
+ uninits = new Bits();
+ uninitsTry = new Bits();
+ initsWhenTrue = new Bits(true);
+ initsWhenFalse = new Bits(true);
+ uninitsWhenTrue = new Bits(true);
+ uninitsWhenFalse = new Bits(true);
+- this.syms = syms;
+- this.names = names;
+- this.enforceThisDotInit = enforceThisDotInit;
+ }
+
+ private boolean isInitialConstructor = false;
+@@ -2439,26 +2436,15 @@
+ }
+ }
+
+- public static class AssignAnalyzer
+- extends AbstractAssignAnalyzer<AssignAnalyzer.AssignPendingExit> {
++ public class AssignAnalyzer extends AbstractAssignAnalyzer<AssignAnalyzer.AssignPendingExit> {
+
+- Log log;
+- Lint lint;
+-
+- public static class AssignPendingExit
+- extends AbstractAssignAnalyzer.AbstractAssignPendingExit {
++ public class AssignPendingExit extends AbstractAssignAnalyzer<AssignPendingExit>.AbstractAssignPendingExit {
+
+ public AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
+ super(tree, inits, uninits);
+ }
+ }
+
+- public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names, boolean enforceThisDotInit) {
+- super(new Bits(), syms, names, enforceThisDotInit);
+- this.log = log;
+- this.lint = lint;
+- }
+-
+ @Override
+ protected AssignPendingExit createNewPendingExit(JCTree tree,
+ Bits inits, Bits uninits) {
+--- ./langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Wed Feb 04 12:14:46 2015 -0800
+@@ -353,6 +353,7 @@
+ Type to, Attr.ResultInfo resultInfo,
+ InferenceContext inferenceContext) {
+ inferenceContext.solve(List.of(from.qtype), new Warner());
++ inferenceContext.notifyChange();
+ Type capturedType = resultInfo.checkContext.inferenceContext()
+ .cachedCapture(tree, from.inst, false);
+ if (types.isConvertible(capturedType,
+@@ -449,7 +450,7 @@
+ class ImplicitArgType extends DeferredAttr.DeferredTypeMap {
+
+ public ImplicitArgType(Symbol msym, Resolve.MethodResolutionPhase phase) {
+- rs.deferredAttr.super(AttrMode.SPECULATIVE, msym, phase);
++ (rs.deferredAttr).super(AttrMode.SPECULATIVE, msym, phase);
+ }
+
+ public Type apply(Type t) {
+@@ -517,6 +518,8 @@
+ //or if it's not a subtype of the original target, issue an error
+ checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
+ }
++ //propagate constraints as per JLS 18.2.1
++ checkContext.compatible(owntype, funcInterface, types.noWarnings);
+ return owntype;
+ }
+ }
+@@ -781,7 +784,10 @@
+ while (tmpTail.nonEmpty()) {
+ Type b1 = boundList.head;
+ Type b2 = tmpTail.head;
+- if (b1 != b2) {
++ /* This wildcard check is temporary workaround. This code may need to be
++ * revisited once spec bug JDK-7034922 is fixed.
++ */
++ if (b1 != b2 && !b1.hasTag(WILDCARD) && !b2.hasTag(WILDCARD)) {
+ Pair<Type, Type> commonSupers = infer.getParameterizedSupers(b1, b2);
+ if (commonSupers != null) {
+ List<Type> allParamsSuperBound1 = commonSupers.fst.allparams();
+--- ./langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Wed Feb 04 12:14:46 2015 -0800
+@@ -41,6 +41,7 @@
+ import com.sun.tools.javac.code.Symtab;
+ import com.sun.tools.javac.code.Type;
+ import com.sun.tools.javac.code.Type.MethodType;
++import com.sun.tools.javac.code.Type.TypeVar;
+ import com.sun.tools.javac.code.Types;
+ import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzerPreprocessor.*;
+ import com.sun.tools.javac.comp.Lower.BasicFreeVarCollector;
+@@ -61,6 +62,7 @@
+ import static com.sun.tools.javac.code.Kinds.*;
+ import static com.sun.tools.javac.code.TypeTag.*;
+ import static com.sun.tools.javac.tree.JCTree.Tag.*;
++import javax.lang.model.type.TypeKind;
+
+ /**
+ * This pass desugars lambda expressions into static methods
+@@ -321,7 +323,9 @@
+
+ ListBuffer<JCExpression> syntheticInits = new ListBuffer<>();
+
+- if (!sym.isStatic()) {
++ if (localContext.methodReferenceReceiver != null) {
++ syntheticInits.append(localContext.methodReferenceReceiver);
++ } else if (!sym.isStatic()) {
+ syntheticInits.append(makeThis(
+ sym.owner.enclClass().asType(),
+ localContext.owner.enclClass()));
+@@ -364,17 +368,10 @@
+
+ //first determine the method symbol to be used to generate the sam instance
+ //this is either the method reference symbol, or the bridged reference symbol
+- Symbol refSym = localContext.needsBridge()
+- ? localContext.bridgeSym
+- : localContext.isSignaturePolymorphic()
++ Symbol refSym = localContext.isSignaturePolymorphic()
+ ? localContext.sigPolySym
+ : tree.sym;
+
+- //build the bridge method, if needed
+- if (localContext.needsBridge()) {
+- bridgeMemberReference(tree, localContext);
+- }
+-
+ //the qualifying expression is treated as a special captured arg
+ JCExpression init;
+ switch(tree.kind) {
+@@ -744,126 +741,146 @@
+ // </editor-fold>
+
+ /**
+- * Generate an adapter method "bridge" for a method reference which cannot
+- * be used directly.
++ * Converts a method reference which cannot be used directly into a lambda
+ */
+- private class MemberReferenceBridger {
++ private class MemberReferenceToLambda {
+
+ private final JCMemberReference tree;
+ private final ReferenceTranslationContext localContext;
++ private final Symbol owner;
+ private final ListBuffer<JCExpression> args = new ListBuffer<>();
+ private final ListBuffer<JCVariableDecl> params = new ListBuffer<>();
+
+- MemberReferenceBridger(JCMemberReference tree, ReferenceTranslationContext localContext) {
++ private JCExpression receiverExpression = null;
++
++ MemberReferenceToLambda(JCMemberReference tree, ReferenceTranslationContext localContext, Symbol owner) {
+ this.tree = tree;
+ this.localContext = localContext;
++ this.owner = owner;
+ }
+
+- /**
+- * Generate the bridge
+- */
+- JCMethodDecl bridge() {
++ JCLambda lambda() {
+ int prevPos = make.pos;
+ try {
+ make.at(tree);
+- Type samDesc = localContext.bridgedRefSig();
+- List<Type> samPTypes = samDesc.getParameterTypes();
+
+- //an extra argument is prepended to the signature of the bridge in case
+- //the member reference is an instance method reference (in which case
+- //the receiver expression is passed to the bridge itself).
+- Type recType = null;
+- switch (tree.kind) {
+- case IMPLICIT_INNER:
+- recType = tree.sym.owner.type.getEnclosingType();
+- break;
+- case BOUND:
+- recType = tree.getQualifierExpression().type;
+- break;
+- case UNBOUND:
+- recType = samPTypes.head;
+- samPTypes = samPTypes.tail;
+- break;
+- }
++ //body generation - this can be either a method call or a
++ //new instance creation expression, depending on the member reference kind
++ VarSymbol rcvr = addParametersReturnReceiver();
++ JCExpression expr = (tree.getMode() == ReferenceMode.INVOKE)
++ ? expressionInvoke(rcvr)
++ : expressionNew();
+
+- //generate the parameter list for the bridged member reference - the
+- //bridge signature will match the signature of the target sam descriptor
+-
+- VarSymbol rcvr = (recType == null)
+- ? null
+- : addParameter("rec$", recType, false);
+-
+- List<Type> refPTypes = tree.sym.type.getParameterTypes();
+- int refSize = refPTypes.size();
+- int samSize = samPTypes.size();
+- // Last parameter to copy from referenced method
+- int last = localContext.needsVarArgsConversion() ? refSize - 1 : refSize;
+-
+- List<Type> l = refPTypes;
+- // Use parameter types of the referenced method, excluding final var args
+- for (int i = 0; l.nonEmpty() && i < last; ++i) {
+- addParameter("x$" + i, l.head, true);
+- l = l.tail;
+- }
+- // Flatten out the var args
+- for (int i = last; i < samSize; ++i) {
+- addParameter("xva$" + i, tree.varargsElement, true);
+- }
+-
+- //generate the bridge method declaration
+- JCMethodDecl bridgeDecl = make.MethodDef(make.Modifiers(localContext.bridgeSym.flags()),
+- localContext.bridgeSym.name,
+- make.QualIdent(samDesc.getReturnType().tsym),
+- List.<JCTypeParameter>nil(),
+- params.toList(),
+- tree.sym.type.getThrownTypes() == null
+- ? List.<JCExpression>nil()
+- : make.Types(tree.sym.type.getThrownTypes()),
+- null,
+- null);
+- bridgeDecl.sym = (MethodSymbol) localContext.bridgeSym;
+- bridgeDecl.type = localContext.bridgeSym.type =
+- types.createMethodTypeWithParameters(samDesc, TreeInfo.types(params.toList()));
+-
+- //bridge method body generation - this can be either a method call or a
+- //new instance creation expression, depending on the member reference kind
+- JCExpression bridgeExpr = (tree.getMode() == ReferenceMode.INVOKE)
+- ? bridgeExpressionInvoke(makeReceiver(rcvr))
+- : bridgeExpressionNew();
+-
+- //the body is either a return expression containing a method call,
+- //or the method call itself, depending on whether the return type of
+- //the bridge is non-void/void.
+- bridgeDecl.body = makeLambdaExpressionBody(bridgeExpr, bridgeDecl);
+-
+- return bridgeDecl;
++ JCLambda slam = make.Lambda(params.toList(), expr);
++ slam.targets = tree.targets;
++ slam.type = tree.type;
++ slam.pos = tree.pos;
++ return slam;
+ } finally {
+ make.at(prevPos);
+ }
+ }
+- //where
+- private JCExpression makeReceiver(VarSymbol rcvr) {
+- if (rcvr == null) return null;
+- JCExpression rcvrExpr = make.Ident(rcvr);
+- Type rcvrType = tree.sym.enclClass().type;
+- if (!rcvr.type.tsym.isSubClass(rcvrType.tsym, types)) {
+- rcvrExpr = make.TypeCast(make.Type(rcvrType), rcvrExpr).setType(rcvrType);
++
++ /**
++ * Generate the parameter list for the converted member reference.
++ *
++ * @return The receiver variable symbol, if any
++ */
++ VarSymbol addParametersReturnReceiver() {
++ Type samDesc = localContext.bridgedRefSig();
++ List<Type> samPTypes = samDesc.getParameterTypes();
++ List<Type> descPTypes = tree.getDescriptorType(types).getParameterTypes();
++
++ // Determine the receiver, if any
++ VarSymbol rcvr;
++ switch (tree.kind) {
++ case BOUND:
++ // The receiver is explicit in the method reference
++ rcvr = addParameter("rec$", tree.getQualifierExpression().type, false);
++ receiverExpression = attr.makeNullCheck(tree.getQualifierExpression());
++ break;
++ case UNBOUND:
++ // The receiver is the first parameter, extract it and
++ // adjust the SAM and unerased type lists accordingly
++ rcvr = addParameter("rec$", samDesc.getParameterTypes().head, false);
++ samPTypes = samPTypes.tail;
++ descPTypes = descPTypes.tail;
++ break;
++ default:
++ rcvr = null;
++ break;
++ }
++ List<Type> implPTypes = tree.sym.type.getParameterTypes();
++ int implSize = implPTypes.size();
++ int samSize = samPTypes.size();
++ // Last parameter to copy from referenced method, exclude final var args
++ int last = localContext.needsVarArgsConversion() ? implSize - 1 : implSize;
++
++ // Failsafe -- assure match-up
++ boolean checkForIntersection = tree.varargsElement != null || implSize == descPTypes.size();
++
++ // Use parameter types of the implementation method unless the unerased
++ // SAM parameter type is an intersection type, in that case use the
++ // erased SAM parameter type so that the supertype relationship
++ // the implementation method parameters is not obscured.
++ // Note: in this loop, the lists implPTypes, samPTypes, and descPTypes
++ // are used as pointers to the current parameter type information
++ // and are thus not usable afterwards.
++ for (int i = 0; implPTypes.nonEmpty() && i < last; ++i) {
++ // By default use the implementation method parmeter type
++ Type parmType = implPTypes.head;
++ // If the unerased parameter type is a type variable whose
++ // bound is an intersection (eg. <T extends A & B>) then
++ // use the SAM parameter type
++ if (checkForIntersection && descPTypes.head.getKind() == TypeKind.TYPEVAR) {
++ TypeVar tv = (TypeVar) descPTypes.head;
++ if (tv.bound.getKind() == TypeKind.INTERSECTION) {
++ parmType = samPTypes.head;
++ }
+ }
+- return rcvrExpr;
++ addParameter("x$" + i, parmType, true);
++
++ // Advance to the next parameter
++ implPTypes = implPTypes.tail;
++ samPTypes = samPTypes.tail;
++ descPTypes = descPTypes.tail;
++ }
++ // Flatten out the var args
++ for (int i = last; i < samSize; ++i) {
++ addParameter("xva$" + i, tree.varargsElement, true);
+ }
+
++ return rcvr;
++ }
++
++ JCExpression getReceiverExpression() {
++ return receiverExpression;
++ }
++
++ private JCExpression makeReceiver(VarSymbol rcvr) {
++ if (rcvr == null) return null;
++ JCExpression rcvrExpr = make.Ident(rcvr);
++ Type rcvrType = tree.sym.enclClass().type;
++ if (rcvrType == syms.arrayClass.type) {
++ // Map the receiver type to the actually type, not just "array"
++ rcvrType = tree.getQualifierExpression().type;
++ }
++ if (!rcvr.type.tsym.isSubClass(rcvrType.tsym, types)) {
++ rcvrExpr = make.TypeCast(make.Type(rcvrType), rcvrExpr).setType(rcvrType);
++ }
++ return rcvrExpr;
++ }
++
+ /**
+- * determine the receiver of the bridged method call - the receiver can
+- * be either the synthetic receiver parameter or a type qualifier; the
+- * original qualifier expression is never used here, as it might refer
+- * to symbols not available in the static context of the bridge
++ * determine the receiver of the method call - the receiver can
++ * be a type qualifier, the synthetic receiver parameter or 'super'.
+ */
+- private JCExpression bridgeExpressionInvoke(JCExpression rcvr) {
++ private JCExpression expressionInvoke(VarSymbol rcvr) {
+ JCExpression qualifier =
+ tree.sym.isStatic() ?
+ make.Type(tree.sym.owner.type) :
+ (rcvr != null) ?
+- rcvr :
++ makeReceiver(rcvr) :
+ tree.getQualifierExpression();
+
+ //create the qualifier expression
+@@ -882,10 +899,9 @@
+ }
+
+ /**
+- * the enclosing expression is either 'null' (no enclosing type) or set
+- * to the first bridge synthetic parameter
++ * Lambda body to use for a 'new'.
+ */
+- private JCExpression bridgeExpressionNew() {
++ private JCExpression expressionNew() {
+ if (tree.kind == ReferenceKind.ARRAY_CTOR) {
+ //create the array creation expression
+ JCNewArray newArr = make.NewArray(
+@@ -895,15 +911,10 @@
+ newArr.type = tree.getQualifierExpression().type;
+ return newArr;
+ } else {
+- JCExpression encl = null;
+- switch (tree.kind) {
+- case UNBOUND:
+- case IMPLICIT_INNER:
+- encl = make.Ident(params.first());
+- }
+-
+ //create the instance creation expression
+- JCNewClass newClass = make.NewClass(encl,
++ //note that method reference syntax does not allow an explicit
++ //enclosing class (so the enclosing class is null)
++ JCNewClass newClass = make.NewClass(null,
+ List.<JCExpression>nil(),
+ make.Type(tree.getQualifierExpression().type),
+ convertArgs(tree.sym, args.toList(), tree.varargsElement),
+@@ -917,7 +928,8 @@
+ }
+
+ private VarSymbol addParameter(String name, Type p, boolean genArg) {
+- VarSymbol vsym = new VarSymbol(0, names.fromString(name), p, localContext.bridgeSym);
++ VarSymbol vsym = new VarSymbol(PARAMETER | SYNTHETIC, names.fromString(name), p, owner);
++ vsym.pos = tree.pos;
+ params.append(make.VarDef(vsym, null));
+ if (genArg) {
+ args.append(make.Ident(vsym));
+@@ -926,15 +938,6 @@
+ }
+ }
+
+- /**
+- * Bridges a member reference - this is needed when:
+- * * Var args in the referenced method need to be flattened away
+- * * super is used
+- */
+- private void bridgeMemberReference(JCMemberReference tree, ReferenceTranslationContext localContext) {
+- kInfo.addMethod(new MemberReferenceBridger(tree, localContext).bridge());
+- }
+-
+ private MethodType typeToMethodType(Type mt) {
+ Type type = types.erasure(mt);
+ return new MethodType(type.getParameterTypes(),
+@@ -1254,9 +1257,25 @@
+
+ @Override
+ public void visitLambda(JCLambda tree) {
++ analyzeLambda(tree, "lambda.stat");
++ }
++
++ private void analyzeLambda(JCLambda tree, JCExpression methodReferenceReceiver) {
++ // Translation of the receiver expression must occur first
++ JCExpression rcvr = translate(methodReferenceReceiver);
++ LambdaTranslationContext context = analyzeLambda(tree, "mref.stat.1");
++ if (rcvr != null) {
++ context.methodReferenceReceiver = rcvr;
++ }
++ }
++
++ private LambdaTranslationContext analyzeLambda(JCLambda tree, String statKey) {
+ List<Frame> prevStack = frameStack;
+ try {
+- LambdaTranslationContext context = (LambdaTranslationContext)makeLambdaContext(tree);
++ LambdaTranslationContext context = new LambdaTranslationContext(tree);
++ if (dumpLambdaToMethodStats) {
++ log.note(tree, statKey, context.needsAltMetafactory(), context.translatedSym);
++ }
+ frameStack = frameStack.prepend(new Frame(tree));
+ for (JCVariableDecl param : tree.params) {
+ context.addSymbol(param.sym, PARAM);
+@@ -1265,6 +1284,7 @@
+ contextMap.put(tree, context);
+ super.visitLambda(tree);
+ context.complete();
++ return context;
+ }
+ finally {
+ frameStack = prevStack;
+@@ -1353,47 +1373,24 @@
+ * information added in the LambdaToMethod pass will have the wrong
+ * signature. Hooks between Lower and LambdaToMethod have been added to
+ * handle normal "new" in this case. This visitor converts potentially
+- * effected method references into a lambda containing a normal "new" of
+- * the class.
++ * affected method references into a lambda containing a normal
++ * expression.
+ *
+ * @param tree
+ */
+ @Override
+ public void visitReference(JCMemberReference tree) {
+- if (tree.getMode() == ReferenceMode.NEW
+- && tree.kind != ReferenceKind.ARRAY_CTOR
+- && tree.sym.owner.isLocal()) {
+- MethodSymbol consSym = (MethodSymbol) tree.sym;
+- List<Type> ptypes = ((MethodType) consSym.type).getParameterTypes();
+- Type classType = consSym.owner.type;
+-
+- // Build lambda parameters
+- // partially cloned from TreeMaker.Params until 8014021 is fixed
+- Symbol owner = owner();
+- ListBuffer<JCVariableDecl> paramBuff = new ListBuffer<JCVariableDecl>();
+- int i = 0;
+- for (List<Type> l = ptypes; l.nonEmpty(); l = l.tail) {
+- JCVariableDecl param = make.Param(make.paramName(i++), l.head, owner);
+- param.sym.pos = tree.pos;
+- paramBuff.append(param);
+- }
+- List<JCVariableDecl> params = paramBuff.toList();
+-
+- // Make new-class call
+- JCNewClass nc = makeNewClass(classType, make.Idents(params));
+- nc.pos = tree.pos;
+-
+- // Make lambda holding the new-class call
+- JCLambda slam = make.Lambda(params, nc);
+- slam.targets = tree.targets;
+- slam.type = tree.type;
+- slam.pos = tree.pos;
+-
+- // Now it is a lambda, process as such
+- visitLambda(slam);
++ ReferenceTranslationContext rcontext = new ReferenceTranslationContext(tree);
++ contextMap.put(tree, rcontext);
++ if (rcontext.needsConversionToLambda()) {
++ // Convert to a lambda, and process as such
++ MemberReferenceToLambda conv = new MemberReferenceToLambda(tree, rcontext, owner());
++ analyzeLambda(conv.lambda(), conv.getReceiverExpression());
+ } else {
+ super.visitReference(tree);
+- contextMap.put(tree, makeReferenceContext(tree));
++ if (dumpLambdaToMethodStats) {
++ log.note(tree, "mref.stat", rcontext.needsAltMetafactory(), null);
++ }
+ }
+ }
+
+@@ -1648,14 +1645,6 @@
+ }
+ }
+
+- private TranslationContext<JCLambda> makeLambdaContext(JCLambda tree) {
+- return new LambdaTranslationContext(tree);
+- }
+-
+- private TranslationContext<JCMemberReference> makeReferenceContext(JCMemberReference tree) {
+- return new ReferenceTranslationContext(tree);
+- }
+-
+ private class Frame {
+ final JCTree tree;
+ List<Symbol> locals;
+@@ -1775,6 +1764,13 @@
+ */
+ final Set<Symbol> freeVarProcessedLocalClasses;
+
++ /**
++ * For method references converted to lambdas. The method
++ * reference receiver expression. Must be treated like a captured
++ * variable.
++ */
++ JCExpression methodReferenceReceiver;
++
+ LambdaTranslationContext(JCLambda tree) {
+ super(tree);
+ Frame frame = frameStack.head;
+@@ -1794,9 +1790,6 @@
+ // This symbol will be filled-in in complete
+ this.translatedSym = makePrivateSyntheticMethod(0, null, null, owner.enclClass());
+
+- if (dumpLambdaToMethodStats) {
+- log.note(tree, "lambda.stat", needsAltMetafactory(), translatedSym);
+- }
+ translatedSymbols = new EnumMap<>(LambdaSymbolKind.class);
+
+ translatedSymbols.put(PARAM, new LinkedHashMap<Symbol, Symbol>());
+@@ -1994,7 +1987,11 @@
+ // If instance access isn't needed, make it static.
+ // Interface instance methods must be default methods.
+ // Lambda methods are private synthetic.
++ // Inherit ACC_STRICT from the enclosing method, or, for clinit,
++ // from the class.
+ translatedSym.flags_field = SYNTHETIC | LAMBDA_METHOD |
++ owner.flags_field & STRICTFP |
++ owner.owner.flags_field & STRICTFP |
+ PRIVATE |
+ (thisReferenced? (inInterface? DEFAULT : 0) : STATIC);
+
+@@ -2009,6 +2006,13 @@
+ for (Symbol thisSym : getSymbolMap(CAPTURED_VAR).values()) {
+ params.append(make.VarDef((VarSymbol) thisSym, null));
+ }
++ if (methodReferenceReceiver != null) {
++ params.append(make.VarDef(
++ make.Modifiers(PARAMETER|FINAL),
++ names.fromString("$rcvr$"),
++ make.Type(methodReferenceReceiver.type),
++ null));
++ }
+ for (Symbol thisSym : getSymbolMap(PARAM).values()) {
+ params.append(make.VarDef((VarSymbol) thisSym, null));
+ }
+@@ -2036,40 +2040,27 @@
+ * and the used by the main translation routines in order to adjust method
+ * references (i.e. in case a bridge is needed)
+ */
+- private class ReferenceTranslationContext extends TranslationContext<JCMemberReference> {
++ private final class ReferenceTranslationContext extends TranslationContext<JCMemberReference> {
+
+ final boolean isSuper;
+- final Symbol bridgeSym;
+ final Symbol sigPolySym;
+
+ ReferenceTranslationContext(JCMemberReference tree) {
+ super(tree);
+ this.isSuper = tree.hasKind(ReferenceKind.SUPER);
+- this.bridgeSym = needsBridge()
+- ? makePrivateSyntheticMethod(isSuper ? 0 : STATIC,
+- referenceBridgeName(), null,
+- owner.enclClass())
+- : null;
+ this.sigPolySym = isSignaturePolymorphic()
+ ? makePrivateSyntheticMethod(tree.sym.flags(),
+ tree.sym.name,
+ bridgedRefSig(),
+ tree.sym.enclClass())
+ : null;
+- if (dumpLambdaToMethodStats) {
+- String key = bridgeSym == null ?
+- "mref.stat" : "mref.stat.1";
+- log.note(tree, key, needsAltMetafactory(), bridgeSym);
+- }
+ }
+
+ /**
+ * Get the opcode associated with this method reference
+ */
+ int referenceKind() {
+- return LambdaToMethod.this.referenceKind(needsBridge()
+- ? bridgeSym
+- : tree.sym);
++ return LambdaToMethod.this.referenceKind(tree.sym);
+ }
+
+ boolean needsVarArgsConversion() {
+@@ -2077,62 +2068,6 @@
+ }
+
+ /**
+- * Generate a disambiguating string to increase stability (important
+- * if serialized)
+- *
+- * @return String to differentiate synthetic lambda method names
+- */
+- private String referenceBridgeDisambiguation() {
+- StringBuilder buf = new StringBuilder();
+- // Append the enclosing method signature to differentiate
+- // overloaded enclosing methods.
+- if (owner.type != null) {
+- buf.append(typeSig(owner.type));
+- buf.append(":");
+- }
+-
+- // Append qualifier type
+- buf.append(classSig(tree.sym.owner.type));
+-
+- // Note static/instance
+- buf.append(tree.sym.isStatic()? " S " : " I ");
+-
+- // Append referenced signature
+- buf.append(typeSig(tree.sym.erasure(types)));
+-
+- return buf.toString();
+- }
+-
+- /**
+- * Construct a unique stable name for the method reference bridge
+- *
+- * @return Name to use for the synthetic method name
+- */
+- private Name referenceBridgeName() {
+- StringBuilder buf = new StringBuilder();
+- // Append lambda ID, this is semantically significant
+- buf.append(names.lambda);
+- // Note that it is a method reference bridge
+- buf.append("MR$");
+- // Append the enclosing method name
+- buf.append(enclosingMethodName());
+- buf.append('$');
+- // Append the referenced method name
+- buf.append(syntheticMethodNameComponent(tree.sym.name));
+- buf.append('$');
+- // Append a hash of the disambiguating string : enclosing method
+- // signature, etc.
+- String disam = referenceBridgeDisambiguation();
+- buf.append(Integer.toHexString(disam.hashCode()));
+- buf.append('$');
+- // The above appended name components may not be unique, append
+- // a count based on the above name components.
+- buf.append(syntheticMethodNameCounts.getIndex(buf));
+- String result = buf.toString();
+- return names.fromString(result);
+- }
+-
+- /**
+ * @return Is this an array operation like clone()
+ */
+ boolean isArrayOp() {
+@@ -2167,13 +2102,40 @@
+ }
+
+ /**
+- * Does this reference needs a bridge (i.e. var args need to be
+- * expanded or "super" is used)
++ * Erasure destroys the implementation parameter subtype
++ * relationship for intersection types
+ */
+- final boolean needsBridge() {
+- return isSuper || needsVarArgsConversion() || isArrayOp() ||
++ boolean interfaceParameterIsIntersectionType() {
++ List<Type> tl = tree.getDescriptorType(types).getParameterTypes();
++ if (tree.kind == ReferenceKind.UNBOUND) {
++ tl = tl.tail;
++ }
++ for (; tl.nonEmpty(); tl = tl.tail) {
++ Type pt = tl.head;
++ if (pt.getKind() == TypeKind.TYPEVAR) {
++ TypeVar tv = (TypeVar) pt;
++ if (tv.bound.getKind() == TypeKind.INTERSECTION) {
++ return true;
++ }
++ }
++ }
++ return false;
++ }
++
++ /**
++ * Does this reference need to be converted to a lambda
++ * (i.e. var args need to be expanded or "super" is used)
++ */
++ final boolean needsConversionToLambda() {
++ return interfaceParameterIsIntersectionType() ||
++ isSuper ||
++ needsVarArgsConversion() ||
++ isArrayOp() ||
+ isPrivateInOtherClass() ||
+- !receiverAccessible();
++ !receiverAccessible() ||
++ (tree.getMode() == ReferenceMode.NEW &&
++ tree.kind != ReferenceKind.ARRAY_CTOR &&
++ (tree.sym.owner.isLocal() || tree.sym.owner.isInner()));
+ }
+
+ Type generatedRefSig() {
+--- ./langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Wed Feb 04 12:14:46 2015 -0800
+@@ -575,51 +575,46 @@
+
+ Env<AttrContext> localEnv = methodEnv(tree, env);
+
+- annotate.enterStart();
++ DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
+ try {
+- DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
+- try {
+- // Compute the method type
+- m.type = signature(m, tree.typarams, tree.params,
+- tree.restype, tree.recvparam,
+- tree.thrown,
+- localEnv);
+- } finally {
+- deferredLintHandler.setPos(prevLintPos);
+- }
++ // Compute the method type
++ m.type = signature(m, tree.typarams, tree.params,
++ tree.restype, tree.recvparam,
++ tree.thrown,
++ localEnv);
++ } finally {
++ deferredLintHandler.setPos(prevLintPos);
++ }
+
+- if (types.isSignaturePolymorphic(m)) {
+- m.flags_field |= SIGNATURE_POLYMORPHIC;
+- }
++ if (types.isSignaturePolymorphic(m)) {
++ m.flags_field |= SIGNATURE_POLYMORPHIC;
++ }
+
+- // Set m.params
+- ListBuffer<VarSymbol> params = new ListBuffer<VarSymbol>();
+- JCVariableDecl lastParam = null;
+- for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
+- JCVariableDecl param = lastParam = l.head;
+- params.append(Assert.checkNonNull(param.sym));
+- }
+- m.params = params.toList();
++ // Set m.params
++ ListBuffer<VarSymbol> params = new ListBuffer<VarSymbol>();
++ JCVariableDecl lastParam = null;
++ for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
++ JCVariableDecl param = lastParam = l.head;
++ params.append(Assert.checkNonNull(param.sym));
++ }
++ m.params = params.toList();
+
+- // mark the method varargs, if necessary
+- if (lastParam != null && (lastParam.mods.flags & Flags.VARARGS) != 0)
+- m.flags_field |= Flags.VARARGS;
++ // mark the method varargs, if necessary
++ if (lastParam != null && (lastParam.mods.flags & Flags.VARARGS) != 0)
++ m.flags_field |= Flags.VARARGS;
+
+- localEnv.info.scope.leave();
+- if (chk.checkUnique(tree.pos(), m, enclScope)) {
+- enclScope.enter(m);
+- }
++ localEnv.info.scope.leave();
++ if (chk.checkUnique(tree.pos(), m, enclScope)) {
++ enclScope.enter(m);
++ }
+
+- annotateLater(tree.mods.annotations, localEnv, m, tree.pos());
+- // Visit the signature of the method. Note that
+- // TypeAnnotate doesn't descend into the body.
+- typeAnnotate(tree, localEnv, m, tree.pos());
++ annotateLater(tree.mods.annotations, localEnv, m, tree.pos());
++ // Visit the signature of the method. Note that
++ // TypeAnnotate doesn't descend into the body.
++ typeAnnotate(tree, localEnv, m, tree.pos());
+
+- if (tree.defaultValue != null)
+- annotateDefaultValueLater(tree.defaultValue, localEnv, m);
+- } finally {
+- annotate.enterDone();
+- }
++ if (tree.defaultValue != null)
++ annotateDefaultValueLater(tree.defaultValue, localEnv, m);
+ }
+
+ /** Create a fresh environment for method bodies.
+@@ -647,54 +642,49 @@
+ localEnv.info.staticLevel++;
+ }
+ DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
+- annotate.enterStart();
+ try {
+- try {
+- if (TreeInfo.isEnumInit(tree)) {
+- attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
+- } else {
+- attr.attribType(tree.vartype, localEnv);
+- if (TreeInfo.isReceiverParam(tree))
+- checkReceiver(tree, localEnv);
+- }
+- } finally {
+- deferredLintHandler.setPos(prevLintPos);
++ if (TreeInfo.isEnumInit(tree)) {
++ attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
++ } else {
++ attr.attribType(tree.vartype, localEnv);
++ if (TreeInfo.isReceiverParam(tree))
++ checkReceiver(tree, localEnv);
+ }
++ } finally {
++ deferredLintHandler.setPos(prevLintPos);
++ }
+
+- if ((tree.mods.flags & VARARGS) != 0) {
+- //if we are entering a varargs parameter, we need to
+- //replace its type (a plain array type) with the more
+- //precise VarargsType --- we need to do it this way
+- //because varargs is represented in the tree as a
+- //modifier on the parameter declaration, and not as a
+- //distinct type of array node.
+- ArrayType atype = (ArrayType)tree.vartype.type.unannotatedType();
+- tree.vartype.type = atype.makeVarargs();
++ if ((tree.mods.flags & VARARGS) != 0) {
++ //if we are entering a varargs parameter, we need to
++ //replace its type (a plain array type) with the more
++ //precise VarargsType --- we need to do it this way
++ //because varargs is represented in the tree as a
++ //modifier on the parameter declaration, and not as a
++ //distinct type of array node.
++ ArrayType atype = (ArrayType)tree.vartype.type.unannotatedType();
++ tree.vartype.type = atype.makeVarargs();
++ }
++ Scope enclScope = enter.enterScope(env);
++ VarSymbol v =
++ new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner);
++ v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree);
++ tree.sym = v;
++ if (tree.init != null) {
++ v.flags_field |= HASINIT;
++ if ((v.flags_field & FINAL) != 0 &&
++ needsLazyConstValue(tree.init)) {
++ Env<AttrContext> initEnv = getInitEnv(tree, env);
++ initEnv.info.enclVar = v;
++ v.setLazyConstValue(initEnv(tree, initEnv), attr, tree);
+ }
+- Scope enclScope = enter.enterScope(env);
+- VarSymbol v =
+- new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner);
+- v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree);
+- tree.sym = v;
+- if (tree.init != null) {
+- v.flags_field |= HASINIT;
+- if ((v.flags_field & FINAL) != 0 &&
+- needsLazyConstValue(tree.init)) {
+- Env<AttrContext> initEnv = getInitEnv(tree, env);
+- initEnv.info.enclVar = v;
+- v.setLazyConstValue(initEnv(tree, initEnv), attr, tree);
+- }
+- }
+- if (chk.checkUnique(tree.pos(), v, enclScope)) {
+- chk.checkTransparentVar(tree.pos(), v, enclScope);
+- enclScope.enter(v);
+- }
+- annotateLater(tree.mods.annotations, localEnv, v, tree.pos());
+- typeAnnotate(tree.vartype, env, v, tree.pos());
+- v.pos = tree.pos;
+- } finally {
+- annotate.enterDone();
+ }
++ if (chk.checkUnique(tree.pos(), v, enclScope)) {
++ chk.checkTransparentVar(tree.pos(), v, enclScope);
++ enclScope.enter(v);
++ }
++ annotateLater(tree.mods.annotations, localEnv, v, tree.pos());
++ typeAnnotate(tree.vartype, env, v, tree.pos());
++ v.pos = tree.pos;
+ }
+ // where
+ void checkType(JCTree tree, Type type, String diag) {
+@@ -1030,189 +1020,194 @@
+ JCClassDecl tree = (JCClassDecl)env.tree;
+ boolean wasFirst = isFirst;
+ isFirst = false;
++ try {
++ annotate.enterStart();
+
+- JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
+- DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
+- try {
+- // Save class environment for later member enter (2) processing.
+- halfcompleted.append(env);
++ JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
++ DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
++ try {
++ // Save class environment for later member enter (2) processing.
++ halfcompleted.append(env);
+
+- // Mark class as not yet attributed.
+- c.flags_field |= UNATTRIBUTED;
++ // Mark class as not yet attributed.
++ c.flags_field |= UNATTRIBUTED;
+
+- // If this is a toplevel-class, make sure any preceding import
+- // clauses have been seen.
+- if (c.owner.kind == PCK) {
+- memberEnter(env.toplevel, env.enclosing(TOPLEVEL));
+- todo.append(env);
++ // If this is a toplevel-class, make sure any preceding import
++ // clauses have been seen.
++ if (c.owner.kind == PCK) {
++ memberEnter(env.toplevel, env.enclosing(TOPLEVEL));
++ todo.append(env);
++ }
++
++ if (c.owner.kind == TYP)
++ c.owner.complete();
++
++ // create an environment for evaluating the base clauses
++ Env<AttrContext> baseEnv = baseEnv(tree, env);
++
++ if (tree.extending != null)
++ typeAnnotate(tree.extending, baseEnv, sym, tree.pos());
++ for (JCExpression impl : tree.implementing)
++ typeAnnotate(impl, baseEnv, sym, tree.pos());
++ annotate.flush();
++
++ // Determine supertype.
++ Type supertype =
++ (tree.extending != null)
++ ? attr.attribBase(tree.extending, baseEnv, true, false, true)
++ : ((tree.mods.flags & Flags.ENUM) != 0)
++ ? attr.attribBase(enumBase(tree.pos, c), baseEnv,
++ true, false, false)
++ : (c.fullname == names.java_lang_Object)
++ ? Type.noType
++ : syms.objectType;
++ ct.supertype_field = modelMissingTypes(supertype, tree.extending, false);
++
++ // Determine interfaces.
++ ListBuffer<Type> interfaces = new ListBuffer<Type>();
++ ListBuffer<Type> all_interfaces = null; // lazy init
++ Set<Type> interfaceSet = new HashSet<Type>();
++ List<JCExpression> interfaceTrees = tree.implementing;
++ for (JCExpression iface : interfaceTrees) {
++ Type i = attr.attribBase(iface, baseEnv, false, true, true);
++ if (i.hasTag(CLASS)) {
++ interfaces.append(i);
++ if (all_interfaces != null) all_interfaces.append(i);
++ chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet);
++ } else {
++ if (all_interfaces == null)
++ all_interfaces = new ListBuffer<Type>().appendList(interfaces);
++ all_interfaces.append(modelMissingTypes(i, iface, true));
++ }
++ }
++ if ((c.flags_field & ANNOTATION) != 0) {
++ ct.interfaces_field = List.of(syms.annotationType);
++ ct.all_interfaces_field = ct.interfaces_field;
++ } else {
++ ct.interfaces_field = interfaces.toList();
++ ct.all_interfaces_field = (all_interfaces == null)
++ ? ct.interfaces_field : all_interfaces.toList();
++ }
++
++ if (c.fullname == names.java_lang_Object) {
++ if (tree.extending != null) {
++ chk.checkNonCyclic(tree.extending.pos(),
++ supertype);
++ ct.supertype_field = Type.noType;
++ }
++ else if (tree.implementing.nonEmpty()) {
++ chk.checkNonCyclic(tree.implementing.head.pos(),
++ ct.interfaces_field.head);
++ ct.interfaces_field = List.nil();
++ }
++ }
++
++ // Annotations.
++ // In general, we cannot fully process annotations yet, but we
++ // can attribute the annotation types and then check to see if the
++ // @Deprecated annotation is present.
++ attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
++ if (hasDeprecatedAnnotation(tree.mods.annotations))
++ c.flags_field |= DEPRECATED;
++ annotateLater(tree.mods.annotations, baseEnv, c, tree.pos());
++ // class type parameters use baseEnv but everything uses env
++
++ chk.checkNonCyclicDecl(tree);
++
++ attr.attribTypeVariables(tree.typarams, baseEnv);
++ // Do this here, where we have the symbol.
++ for (JCTypeParameter tp : tree.typarams)
++ typeAnnotate(tp, baseEnv, sym, tree.pos());
++
++ // Add default constructor if needed.
++ if ((c.flags() & INTERFACE) == 0 &&
++ !TreeInfo.hasConstructors(tree.defs)) {
++ List<Type> argtypes = List.nil();
++ List<Type> typarams = List.nil();
++ List<Type> thrown = List.nil();
++ long ctorFlags = 0;
++ boolean based = false;
++ boolean addConstructor = true;
++ JCNewClass nc = null;
++ if (c.name.isEmpty()) {
++ nc = (JCNewClass)env.next.tree;
++ if (nc.constructor != null) {
++ addConstructor = nc.constructor.kind != ERR;
++ Type superConstrType = types.memberType(c.type,
++ nc.constructor);
++ argtypes = superConstrType.getParameterTypes();
++ typarams = superConstrType.getTypeArguments();
++ ctorFlags = nc.constructor.flags() & VARARGS;
++ if (nc.encl != null) {
++ argtypes = argtypes.prepend(nc.encl.type);
++ based = true;
++ }
++ thrown = superConstrType.getThrownTypes();
++ }
++ }
++ if (addConstructor) {
++ MethodSymbol basedConstructor = nc != null ?
++ (MethodSymbol)nc.constructor : null;
++ JCTree constrDef = DefaultConstructor(make.at(tree.pos), c,
++ basedConstructor,
++ typarams, argtypes, thrown,
++ ctorFlags, based);
++ tree.defs = tree.defs.prepend(constrDef);
++ }
++ }
++
++ // enter symbols for 'this' into current scope.
++ VarSymbol thisSym =
++ new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
++ thisSym.pos = Position.FIRSTPOS;
++ env.info.scope.enter(thisSym);
++ // if this is a class, enter symbol for 'super' into current scope.
++ if ((c.flags_field & INTERFACE) == 0 &&
++ ct.supertype_field.hasTag(CLASS)) {
++ VarSymbol superSym =
++ new VarSymbol(FINAL | HASINIT, names._super,
++ ct.supertype_field, c);
++ superSym.pos = Position.FIRSTPOS;
++ env.info.scope.enter(superSym);
++ }
++
++ // check that no package exists with same fully qualified name,
++ // but admit classes in the unnamed package which have the same
++ // name as a top-level package.
++ if (checkClash &&
++ c.owner.kind == PCK && c.owner != syms.unnamedPackage &&
++ reader.packageExists(c.fullname)) {
++ log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
++ }
++ if (c.owner.kind == PCK && (c.flags_field & PUBLIC) == 0 &&
++ !env.toplevel.sourcefile.isNameCompatible(c.name.toString(),JavaFileObject.Kind.SOURCE)) {
++ c.flags_field |= AUXILIARY;
++ }
++ } catch (CompletionFailure ex) {
++ chk.completionError(tree.pos(), ex);
++ } finally {
++ deferredLintHandler.setPos(prevLintPos);
++ log.useSource(prev);
+ }
+
+- if (c.owner.kind == TYP)
+- c.owner.complete();
+-
+- // create an environment for evaluating the base clauses
+- Env<AttrContext> baseEnv = baseEnv(tree, env);
+-
+- if (tree.extending != null)
+- typeAnnotate(tree.extending, baseEnv, sym, tree.pos());
+- for (JCExpression impl : tree.implementing)
+- typeAnnotate(impl, baseEnv, sym, tree.pos());
+- annotate.flush();
+-
+- // Determine supertype.
+- Type supertype =
+- (tree.extending != null)
+- ? attr.attribBase(tree.extending, baseEnv, true, false, true)
+- : ((tree.mods.flags & Flags.ENUM) != 0)
+- ? attr.attribBase(enumBase(tree.pos, c), baseEnv,
+- true, false, false)
+- : (c.fullname == names.java_lang_Object)
+- ? Type.noType
+- : syms.objectType;
+- ct.supertype_field = modelMissingTypes(supertype, tree.extending, false);
+-
+- // Determine interfaces.
+- ListBuffer<Type> interfaces = new ListBuffer<Type>();
+- ListBuffer<Type> all_interfaces = null; // lazy init
+- Set<Type> interfaceSet = new HashSet<Type>();
+- List<JCExpression> interfaceTrees = tree.implementing;
+- for (JCExpression iface : interfaceTrees) {
+- Type i = attr.attribBase(iface, baseEnv, false, true, true);
+- if (i.hasTag(CLASS)) {
+- interfaces.append(i);
+- if (all_interfaces != null) all_interfaces.append(i);
+- chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet);
+- } else {
+- if (all_interfaces == null)
+- all_interfaces = new ListBuffer<Type>().appendList(interfaces);
+- all_interfaces.append(modelMissingTypes(i, iface, true));
++ // Enter all member fields and methods of a set of half completed
++ // classes in a second phase.
++ if (wasFirst) {
++ try {
++ while (halfcompleted.nonEmpty()) {
++ Env<AttrContext> toFinish = halfcompleted.next();
++ finish(toFinish);
++ if (allowTypeAnnos) {
++ typeAnnotations.organizeTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree);
++ typeAnnotations.validateTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree);
++ }
++ }
++ } finally {
++ isFirst = true;
+ }
+ }
+- if ((c.flags_field & ANNOTATION) != 0) {
+- ct.interfaces_field = List.of(syms.annotationType);
+- ct.all_interfaces_field = ct.interfaces_field;
+- } else {
+- ct.interfaces_field = interfaces.toList();
+- ct.all_interfaces_field = (all_interfaces == null)
+- ? ct.interfaces_field : all_interfaces.toList();
+- }
+-
+- if (c.fullname == names.java_lang_Object) {
+- if (tree.extending != null) {
+- chk.checkNonCyclic(tree.extending.pos(),
+- supertype);
+- ct.supertype_field = Type.noType;
+- }
+- else if (tree.implementing.nonEmpty()) {
+- chk.checkNonCyclic(tree.implementing.head.pos(),
+- ct.interfaces_field.head);
+- ct.interfaces_field = List.nil();
+- }
+- }
+-
+- // Annotations.
+- // In general, we cannot fully process annotations yet, but we
+- // can attribute the annotation types and then check to see if the
+- // @Deprecated annotation is present.
+- attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
+- if (hasDeprecatedAnnotation(tree.mods.annotations))
+- c.flags_field |= DEPRECATED;
+- annotateLater(tree.mods.annotations, baseEnv, c, tree.pos());
+- // class type parameters use baseEnv but everything uses env
+-
+- chk.checkNonCyclicDecl(tree);
+-
+- attr.attribTypeVariables(tree.typarams, baseEnv);
+- // Do this here, where we have the symbol.
+- for (JCTypeParameter tp : tree.typarams)
+- typeAnnotate(tp, baseEnv, sym, tree.pos());
+-
+- // Add default constructor if needed.
+- if ((c.flags() & INTERFACE) == 0 &&
+- !TreeInfo.hasConstructors(tree.defs)) {
+- List<Type> argtypes = List.nil();
+- List<Type> typarams = List.nil();
+- List<Type> thrown = List.nil();
+- long ctorFlags = 0;
+- boolean based = false;
+- boolean addConstructor = true;
+- JCNewClass nc = null;
+- if (c.name.isEmpty()) {
+- nc = (JCNewClass)env.next.tree;
+- if (nc.constructor != null) {
+- addConstructor = nc.constructor.kind != ERR;
+- Type superConstrType = types.memberType(c.type,
+- nc.constructor);
+- argtypes = superConstrType.getParameterTypes();
+- typarams = superConstrType.getTypeArguments();
+- ctorFlags = nc.constructor.flags() & VARARGS;
+- if (nc.encl != null) {
+- argtypes = argtypes.prepend(nc.encl.type);
+- based = true;
+- }
+- thrown = superConstrType.getThrownTypes();
+- }
+- }
+- if (addConstructor) {
+- MethodSymbol basedConstructor = nc != null ?
+- (MethodSymbol)nc.constructor : null;
+- JCTree constrDef = DefaultConstructor(make.at(tree.pos), c,
+- basedConstructor,
+- typarams, argtypes, thrown,
+- ctorFlags, based);
+- tree.defs = tree.defs.prepend(constrDef);
+- }
+- }
+-
+- // enter symbols for 'this' into current scope.
+- VarSymbol thisSym =
+- new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
+- thisSym.pos = Position.FIRSTPOS;
+- env.info.scope.enter(thisSym);
+- // if this is a class, enter symbol for 'super' into current scope.
+- if ((c.flags_field & INTERFACE) == 0 &&
+- ct.supertype_field.hasTag(CLASS)) {
+- VarSymbol superSym =
+- new VarSymbol(FINAL | HASINIT, names._super,
+- ct.supertype_field, c);
+- superSym.pos = Position.FIRSTPOS;
+- env.info.scope.enter(superSym);
+- }
+-
+- // check that no package exists with same fully qualified name,
+- // but admit classes in the unnamed package which have the same
+- // name as a top-level package.
+- if (checkClash &&
+- c.owner.kind == PCK && c.owner != syms.unnamedPackage &&
+- reader.packageExists(c.fullname)) {
+- log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
+- }
+- if (c.owner.kind == PCK && (c.flags_field & PUBLIC) == 0 &&
+- !env.toplevel.sourcefile.isNameCompatible(c.name.toString(),JavaFileObject.Kind.SOURCE)) {
+- c.flags_field |= AUXILIARY;
+- }
+- } catch (CompletionFailure ex) {
+- chk.completionError(tree.pos(), ex);
+ } finally {
+- deferredLintHandler.setPos(prevLintPos);
+- log.useSource(prev);
+- }
+-
+- // Enter all member fields and methods of a set of half completed
+- // classes in a second phase.
+- if (wasFirst) {
+- try {
+- while (halfcompleted.nonEmpty()) {
+- Env<AttrContext> toFinish = halfcompleted.next();
+- finish(toFinish);
+- if (allowTypeAnnos) {
+- typeAnnotations.organizeTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree);
+- typeAnnotations.validateTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree);
+- }
+- }
+- } finally {
+- isFirst = true;
+- }
++ annotate.enterDone();
+ }
+ }
+
+--- ./langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Feb 04 12:14:46 2015 -0800
+@@ -96,6 +96,7 @@
+ public final boolean varargsEnabled;
+ public final boolean allowMethodHandles;
+ public final boolean allowFunctionalInterfaceMostSpecific;
++ public final boolean checkVarargsAccessAfterResolution;
+ private final boolean debugResolve;
+ private final boolean compactMethodDiags;
+ final EnumSet<VerboseResolutionMode> verboseResolutionMode;
+@@ -137,6 +138,8 @@
+ Target target = Target.instance(context);
+ allowMethodHandles = target.hasMethodHandles();
+ allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific();
++ checkVarargsAccessAfterResolution =
++ source.allowPostApplicabilityVarargsAccessCheck();
+ polymorphicSignatureScope = new Scope(syms.noSymbol);
+
+ inapplicableMethodException = new InapplicableMethodException(diags);
+@@ -835,9 +838,15 @@
+ super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn);
+ //should we expand formals?
+ if (deferredAttrContext.phase.isVarargsRequired()) {
+- //check varargs element type accessibility
+- varargsAccessible(env, types.elemtype(formals.last()),
+- deferredAttrContext.inferenceContext);
++ Type typeToCheck = null;
++ if (!checkVarargsAccessAfterResolution) {
++ typeToCheck = types.elemtype(formals.last());
++ } else if (deferredAttrContext.mode == AttrMode.CHECK) {
++ typeToCheck = types.erasure(types.elemtype(formals.last()));
++ }
++ if (typeToCheck != null) {
++ varargsAccessible(env, typeToCheck, deferredAttrContext.inferenceContext);
++ }
+ }
+ }
+
+@@ -948,9 +957,10 @@
+ }
+
+ public boolean compatible(Type found, Type req, Warner warn) {
++ InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
+ return strict ?
+- types.isSubtypeUnchecked(found, deferredAttrContext.inferenceContext.asUndetVar(req), warn) :
+- types.isConvertible(found, deferredAttrContext.inferenceContext.asUndetVar(req), warn);
++ types.isSubtypeUnchecked(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn) :
++ types.isConvertible(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn);
+ }
+
+ public void report(DiagnosticPosition pos, JCDiagnostic details) {
+@@ -3035,7 +3045,7 @@
+ /**
+ * Should lookup stop at given phase with given result
+ */
+- protected boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
++ final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
+ return phase.ordinal() > maxPhase.ordinal() ||
+ sym.kind < ERRONEOUS || sym.kind == AMBIGUOUS;
+ }
+@@ -3210,7 +3220,7 @@
+ super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
+ if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
+ Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
+- this.site = asSuperSite;
++ this.site = types.capture(asSuperSite);
+ }
+ }
+
+@@ -4218,15 +4228,39 @@
+ VARARITY(true, true) {
+ @Override
+ public Symbol mergeResults(Symbol bestSoFar, Symbol sym) {
+- switch (sym.kind) {
+- case WRONG_MTH:
+- return (bestSoFar.kind == WRONG_MTH || bestSoFar.kind == WRONG_MTHS) ?
+- bestSoFar :
+- sym;
+- case ABSENT_MTH:
+- return bestSoFar;
+- default:
+- return sym;
++ //Check invariants (see {@code LookupHelper.shouldStop})
++ Assert.check(bestSoFar.kind >= ERRONEOUS && bestSoFar.kind != AMBIGUOUS);
++ if (sym.kind < ERRONEOUS) {
++ //varargs resolution successful
++ return sym;
++ } else {
++ //pick best error
++ switch (bestSoFar.kind) {
++ case WRONG_MTH:
++ case WRONG_MTHS:
++ //Override previous errors if they were caused by argument mismatch.
++ //This generally means preferring current symbols - but we need to pay
++ //attention to the fact that the varargs lookup returns 'less' candidates
++ //than the previous rounds, and adjust that accordingly.
++ switch (sym.kind) {
++ case WRONG_MTH:
++ //if the previous round matched more than one method, return that
++ //result instead
++ return bestSoFar.kind == WRONG_MTHS ?
++ bestSoFar : sym;
++ case ABSENT_MTH:
++ //do not override erroneous symbol if the arity lookup did not
++ //match any method
++ return bestSoFar;
++ case WRONG_MTHS:
++ default:
++ //safe to override
++ return sym;
++ }
++ default:
++ //otherwise, return first error
++ return bestSoFar;
++ }
+ }
+ }
+ };
+--- ./langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1953,12 +1953,12 @@
+ }
+ }
+
+- public void closeRange(char end) {
+- if (isLastRangeInitialized()) {
++ public void closeRange(char length) {
++ if (isLastRangeInitialized() && length > 0) {
+ Range range = lastRange();
+ if (range != null) {
+ if (range.length == Character.MAX_VALUE) {
+- range.length = end;
++ range.length = length;
+ }
+ }
+ } else {
+@@ -2017,13 +2017,12 @@
+ List<VarSymbol> locals = lvtRanges.getVars(meth, tree);
+ for (LocalVar localVar: lvar) {
+ for (VarSymbol aliveLocal : locals) {
+- if (localVar == null) {
+- return;
+- }
+- if (localVar.sym == aliveLocal && localVar.lastRange() != null) {
+- char length = (char)(closingCP - localVar.lastRange().start_pc);
+- if (length > 0 && length < Character.MAX_VALUE) {
+- localVar.closeRange(length);
++ if (localVar != null) {
++ if (localVar.sym == aliveLocal && localVar.lastRange() != null) {
++ char length = (char)(closingCP - localVar.lastRange().start_pc);
++ if (length < Character.MAX_VALUE) {
++ localVar.closeRange(length);
++ }
+ }
+ }
+ }
+@@ -2032,12 +2031,11 @@
+
+ void adjustAliveRanges(int oldCP, int delta) {
+ for (LocalVar localVar: lvar) {
+- if (localVar == null) {
+- return;
+- }
+- for (LocalVar.Range range: localVar.aliveRanges) {
+- if (range.closed() && range.start_pc + range.length >= oldCP) {
+- range.length += delta;
++ if (localVar != null) {
++ for (LocalVar.Range range: localVar.aliveRanges) {
++ if (range.closed() && range.start_pc + range.length >= oldCP) {
++ range.length += delta;
++ }
+ }
+ }
+ }
+@@ -2093,7 +2091,7 @@
+ lvar[adr].isLastRangeInitialized()) {
+ LocalVar v = lvar[adr];
+ char length = (char)(curCP() - v.lastRange().start_pc);
+- if (length > 0 && length < Character.MAX_VALUE) {
++ if (length < Character.MAX_VALUE) {
+ lvar[adr] = v.dup();
+ v.closeRange(length);
+ putVar(v);
+--- ./langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Wed Feb 04 12:14:46 2015 -0800
+@@ -74,6 +74,7 @@
+ private Name accessDollar;
+ private final Types types;
+ private final Lower lower;
++ private final Flow flow;
+
+ /** Switch: GJ mode?
+ */
+@@ -125,6 +126,7 @@
+ stringBufferAppend = new HashMap<Type,Symbol>();
+ accessDollar = names.
+ fromString("access" + target.syntheticNameChar());
++ flow = Flow.instance(context);
+ lower = Lower.instance(context);
+
+ Options options = Options.instance(context);
+@@ -2516,9 +2518,7 @@
+ */
+ if (varDebugInfo && (cdef.sym.flags() & SYNTHETIC) == 0) {
+ try {
+- LVTAssignAnalyzer lvtAssignAnalyzer = LVTAssignAnalyzer.make(
+- lvtRanges, syms, names);
+- lvtAssignAnalyzer.analyzeTree(localEnv);
++ new LVTAssignAnalyzer().analyzeTree(localEnv);
+ } catch (Throwable e) {
+ throw e;
+ }
+@@ -2609,11 +2609,10 @@
+ }
+ }
+
+- static class LVTAssignAnalyzer
++ class LVTAssignAnalyzer
+ extends Flow.AbstractAssignAnalyzer<LVTAssignAnalyzer.LVTAssignPendingExit> {
+
+ final LVTBits lvtInits;
+- final LVTRanges lvtRanges;
+
+ /* This class is anchored to a context dependent tree. The tree can
+ * vary inside the same instruction for example in the switch instruction
+@@ -2621,35 +2620,12 @@
+ * to a given case. The aim is to always anchor the bits to the tree
+ * capable of closing a DA range.
+ */
+- static class LVTBits extends Bits {
+-
+- enum BitsOpKind {
+- INIT,
+- CLEAR,
+- INCL_BIT,
+- EXCL_BIT,
+- ASSIGN,
+- AND_SET,
+- OR_SET,
+- DIFF_SET,
+- XOR_SET,
+- INCL_RANGE,
+- EXCL_RANGE,
+- }
++ class LVTBits extends Bits {
+
+ JCTree currentTree;
+- LVTAssignAnalyzer analyzer;
+ private int[] oldBits = null;
+ BitsState stateBeforeOp;
+
+- LVTBits() {
+- super(false);
+- }
+-
+- LVTBits(int[] bits, BitsState initState) {
+- super(bits, initState);
+- }
+-
+ @Override
+ public void clear() {
+ generalOp(null, -1, BitsOpKind.CLEAR);
+@@ -2757,12 +2733,11 @@
+ if (currentTree != null &&
+ stateBeforeOp != BitsState.UNKNOWN &&
+ trackTree(currentTree)) {
+- List<VarSymbol> locals =
+- analyzer.lvtRanges
+- .getVars(analyzer.currentMethod, currentTree);
++ List<VarSymbol> locals = lvtRanges
++ .getVars(currentMethod, currentTree);
+ locals = locals != null ?
+ locals : List.<VarSymbol>nil();
+- for (JCVariableDecl vardecl : analyzer.vardecls) {
++ for (JCVariableDecl vardecl : vardecls) {
+ //once the first is null, the rest will be so.
+ if (vardecl == null) {
+ break;
+@@ -2772,7 +2747,7 @@
+ }
+ }
+ if (!locals.isEmpty()) {
+- analyzer.lvtRanges.setEntry(analyzer.currentMethod,
++ lvtRanges.setEntry(currentMethod,
+ currentTree, locals);
+ }
+ }
+@@ -2789,8 +2764,8 @@
+
+ boolean trackVar(VarSymbol var) {
+ return (var.owner.kind == MTH &&
+- (var.flags() & (PARAMETER | HASINIT)) == 0 &&
+- analyzer.trackable(var));
++ (var.flags() & PARAMETER) == 0 &&
++ trackable(var));
+ }
+
+ boolean trackTree(JCTree tree) {
+@@ -2806,7 +2781,8 @@
+
+ }
+
+- public class LVTAssignPendingExit extends Flow.AssignAnalyzer.AssignPendingExit {
++ public class LVTAssignPendingExit extends
++ Flow.AbstractAssignAnalyzer<LVTAssignPendingExit>.AbstractAssignPendingExit {
+
+ LVTAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
+ super(tree, inits, uninits);
+@@ -2819,16 +2795,10 @@
+ }
+ }
+
+- private LVTAssignAnalyzer(LVTRanges lvtRanges, Symtab syms, Names names) {
+- super(new LVTBits(), syms, names, false);
+- lvtInits = (LVTBits)inits;
+- this.lvtRanges = lvtRanges;
+- }
+-
+- public static LVTAssignAnalyzer make(LVTRanges lvtRanges, Symtab syms, Names names) {
+- LVTAssignAnalyzer result = new LVTAssignAnalyzer(lvtRanges, syms, names);
+- result.lvtInits.analyzer = result;
+- return result;
++ private LVTAssignAnalyzer() {
++ flow.super();
++ lvtInits = new LVTBits();
++ inits = lvtInits;
+ }
+
+ @Override
+--- ./langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1039,7 +1039,7 @@
+ }
+
+ /**
+- * @see <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javadoc.html#javadoctags">Javadoc Tags</a>
++ * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javadoc.html#javadoctags">Javadoc Tags</a>
+ */
+ private void initTagParsers() {
+ TagParser[] parsers = {
+--- ./langtools/src/share/classes/com/sun/tools/javac/util/Bits.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/javac/util/Bits.java Wed Feb 04 12:14:46 2015 -0800
+@@ -84,6 +84,20 @@
+
+ }
+
++ public enum BitsOpKind {
++ INIT,
++ CLEAR,
++ INCL_BIT,
++ EXCL_BIT,
++ ASSIGN,
++ AND_SET,
++ OR_SET,
++ DIFF_SET,
++ XOR_SET,
++ INCL_RANGE,
++ EXCL_RANGE,
++ }
++
+ private final static int wordlen = 32;
+ private final static int wordshift = 5;
+ private final static int wordmask = wordlen - 1;
+--- ./langtools/src/share/classes/com/sun/tools/javac/util/Convert.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/javac/util/Convert.java Wed Feb 04 12:14:46 2015 -0800
+@@ -36,9 +36,9 @@
+ * <p>
+ * See also:
+ * <ul>
+- * <li><a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.7">
++ * <li><a href="https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.7">
+ * JVMS 4.4.7 </a></li>
+- * <li><a href="http://docs.oracle.com/javase/7/docs/api/java/io/DataInput.html#modified-utf-8">
++ * <li><a href="https://docs.oracle.com/javase/7/docs/api/java/io/DataInput.html#modified-utf-8">
+ java.io.DataInput: Modified UTF-8 </a></li>
+ <li><a href="https://en.wikipedia.org/wiki/UTF-8#Modified_UTF-8">
+ Modified UTF-8 (wikipedia) </a></li>
+--- ./langtools/src/share/classes/com/sun/tools/jdeps/Analyzer.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/jdeps/Analyzer.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,10 +24,8 @@
+ */
+ package com.sun.tools.jdeps;
+
+-import com.sun.tools.classfile.Dependency.Location;
+-import com.sun.tools.jdeps.PlatformClassPath.JDKArchive;
+-import java.util.ArrayList;
+ import java.util.HashMap;
++import java.util.HashSet;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Objects;
+@@ -37,6 +35,9 @@
+ import java.util.TreeMap;
+ import java.util.TreeSet;
+
++import com.sun.tools.classfile.Dependency.Location;
++import com.sun.tools.jdeps.PlatformClassPath.JDKArchive;
++
+ /**
+ * Dependency Analyzer.
+ */
+@@ -52,7 +53,16 @@
+ VERBOSE
+ };
+
++ /**
++ * Filter to be applied when analyzing the dependencies from the given archives.
++ * Only the accepted dependencies are recorded.
++ */
++ interface Filter {
++ boolean accepts(Location origin, Archive originArchive, Location target, Archive targetArchive);
++ }
++
+ private final Type type;
++ private final Filter filter;
+ private final Map<Archive, ArchiveDeps> results = new HashMap<>();
+ private final Map<Location, Archive> map = new HashMap<>();
+ private final Archive NOT_FOUND
+@@ -62,9 +72,11 @@
+ * Constructs an Analyzer instance.
+ *
+ * @param type Type of the dependency analysis
++ * @param filter
+ */
+- public Analyzer(Type type) {
++ public Analyzer(Type type, Filter filter) {
+ this.type = type;
++ this.filter = filter;
+ }
+
+ /**
+@@ -72,6 +84,18 @@
+ */
+ public void run(List<Archive> archives) {
+ // build a map from Location to Archive
++ buildLocationArchiveMap(archives);
++
++ // traverse and analyze all dependencies
++ for (Archive archive : archives) {
++ ArchiveDeps deps = new ArchiveDeps(archive, type);
++ archive.visitDependences(deps);
++ results.put(archive, deps);
++ }
++ }
++
++ private void buildLocationArchiveMap(List<Archive> archives) {
++ // build a map from Location to Archive
+ for (Archive archive: archives) {
+ for (Location l: archive.getClasses()) {
+ if (!map.containsKey(l)) {
+@@ -81,190 +105,236 @@
+ }
+ }
+ }
+- // traverse and analyze all dependencies
+- for (Archive archive : archives) {
+- ArchiveDeps deps;
+- if (type == Type.CLASS || type == Type.VERBOSE) {
+- deps = new ClassVisitor(archive);
+- } else {
+- deps = new PackageVisitor(archive);
+- }
+- archive.visitDependences(deps);
+- results.put(archive, deps);
+- }
+ }
+
+ public boolean hasDependences(Archive archive) {
+ if (results.containsKey(archive)) {
+- return results.get(archive).deps.size() > 0;
++ return results.get(archive).dependencies().size() > 0;
+ }
+ return false;
+ }
+
++ public Set<String> dependences(Archive source) {
++ ArchiveDeps result = results.get(source);
++ return result.targetDependences();
++ }
++
+ public interface Visitor {
+ /**
+- * Visits the source archive to its destination archive of
+- * a recorded dependency.
+- */
+- void visitArchiveDependence(Archive origin, Archive target, Profile profile);
+- /**
+ * Visits a recorded dependency from origin to target which can be
+- * a fully-qualified classname, a package name, a profile or
++ * a fully-qualified classname, a package name, a module or
+ * archive name depending on the Analyzer's type.
+ */
+- void visitDependence(String origin, Archive source, String target, Archive archive, Profile profile);
++ public void visitDependence(String origin, Archive originArchive,
++ String target, Archive targetArchive);
+ }
+
+- public void visitArchiveDependences(Archive source, Visitor v) {
+- ArchiveDeps r = results.get(source);
+- for (ArchiveDeps.Dep d: r.requireArchives()) {
+- v.visitArchiveDependence(r.archive, d.archive, d.profile);
++ /**
++ * Visit the dependencies of the given source.
++ * If the requested level is SUMMARY, it will visit the required archives list.
++ */
++ public void visitDependences(Archive source, Visitor v, Type level) {
++ if (level == Type.SUMMARY) {
++ final ArchiveDeps result = results.get(source);
++ SortedMap<String, Archive> sorted = new TreeMap<>();
++ for (Archive a : result.requires()) {
++ sorted.put(a.getName(), a);
++ }
++ for (Archive archive : sorted.values()) {
++ Profile profile = result.getTargetProfile(archive);
++ v.visitDependence(source.getName(), source,
++ profile != null ? profile.profileName() : archive.getName(), archive);
++ }
++ } else {
++ ArchiveDeps result = results.get(source);
++ if (level != type) {
++ // requesting different level of analysis
++ result = new ArchiveDeps(source, level);
++ source.visitDependences(result);
++ }
++ SortedSet<Dep> sorted = new TreeSet<>(result.dependencies());
++ for (Dep d : sorted) {
++ v.visitDependence(d.origin(), d.originArchive(), d.target(), d.targetArchive());
++ }
+ }
+ }
+
+ public void visitDependences(Archive source, Visitor v) {
+- ArchiveDeps r = results.get(source);
+- for (Map.Entry<String, SortedSet<ArchiveDeps.Dep>> e: r.deps.entrySet()) {
+- String origin = e.getKey();
+- for (ArchiveDeps.Dep d: e.getValue()) {
+- // filter intra-dependency unless in verbose mode
+- if (type == Type.VERBOSE || d.archive != source) {
+- v.visitDependence(origin, source, d.target, d.archive, d.profile);
++ visitDependences(source, v, type);
++ }
++
++ /**
++ * ArchiveDeps contains the dependencies for an Archive that can have one or
++ * more classes.
++ */
++ class ArchiveDeps implements Archive.Visitor {
++ protected final Archive archive;
++ protected final Set<Archive> requires;
++ protected final Set<Dep> deps;
++ protected final Type level;
++ private Profile profile;
++ ArchiveDeps(Archive archive, Type level) {
++ this.archive = archive;
++ this.deps = new HashSet<>();
++ this.requires = new HashSet<>();
++ this.level = level;
++ }
++
++ Set<Dep> dependencies() {
++ return deps;
++ }
++
++ Set<String> targetDependences() {
++ Set<String> targets = new HashSet<>();
++ for (Dep d : deps) {
++ targets.add(d.target());
++ }
++ return targets;
++ }
++
++ Set<Archive> requires() {
++ return requires;
++ }
++
++ Profile getTargetProfile(Archive target) {
++ return JDKArchive.isProfileArchive(target) ? profile : null;
++ }
++
++ Archive findArchive(Location t) {
++ Archive target = archive.getClasses().contains(t) ? archive : map.get(t);
++ if (target == null) {
++ map.put(t, target = NOT_FOUND);
++ }
++ return target;
++ }
++
++ // return classname or package name depedning on the level
++ private String getLocationName(Location o) {
++ if (level == Type.CLASS || level == Type.VERBOSE) {
++ return o.getClassName();
++ } else {
++ String pkg = o.getPackageName();
++ return pkg.isEmpty() ? "<unnamed>" : pkg;
++ }
++ }
++
++ @Override
++ public void visit(Location o, Location t) {
++ Archive targetArchive = findArchive(t);
++ if (filter.accepts(o, archive, t, targetArchive)) {
++ addDep(o, t);
++ if (!requires.contains(targetArchive)) {
++ requires.add(targetArchive);
++ }
++ }
++ if (targetArchive instanceof JDKArchive) {
++ Profile p = Profile.getProfile(t.getPackageName());
++ if (profile == null || (p != null && p.compareTo(profile) > 0)) {
++ profile = p;
+ }
+ }
+ }
+- }
+
+- /**
+- * ArchiveDeps contains the dependencies for an Archive that
+- * can have one or more classes.
+- */
+- private abstract class ArchiveDeps implements Archive.Visitor {
+- final Archive archive;
+- final SortedMap<String, SortedSet<Dep>> deps;
+- ArchiveDeps(Archive archive) {
+- this.archive = archive;
+- this.deps = new TreeMap<>();
+- }
++ private Dep curDep;
++ protected Dep addDep(Location o, Location t) {
++ String origin = getLocationName(o);
++ String target = getLocationName(t);
++ Archive targetArchive = findArchive(t);
++ if (curDep != null &&
++ curDep.origin().equals(origin) &&
++ curDep.originArchive() == archive &&
++ curDep.target().equals(target) &&
++ curDep.targetArchive() == targetArchive) {
++ return curDep;
++ }
+
+- void add(String origin, String target, Archive targetArchive, String pkgName) {
+- SortedSet<Dep> set = deps.get(origin);
+- if (set == null) {
+- deps.put(origin, set = new TreeSet<>());
+- }
+- Profile p = targetArchive instanceof JDKArchive
+- ? Profile.getProfile(pkgName) : null;
+- set.add(new Dep(target, targetArchive, p));
+- }
+-
+- /**
+- * Returns the list of Archive dependences. The returned
+- * list contains one {@code Dep} instance per one archive
+- * and with the minimum profile this archive depends on.
+- */
+- List<Dep> requireArchives() {
+- Map<Archive,Profile> map = new HashMap<>();
+- for (Set<Dep> set: deps.values()) {
+- for (Dep d: set) {
+- if (this.archive != d.archive) {
+- Profile p = map.get(d.archive);
+- if (p == null || (d.profile != null && p.profile < d.profile.profile)) {
+- map.put(d.archive, d.profile);
+- }
++ Dep e = new Dep(origin, archive, target, targetArchive);
++ if (deps.contains(e)) {
++ for (Dep e1 : deps) {
++ if (e.equals(e1)) {
++ curDep = e1;
+ }
+ }
++ } else {
++ deps.add(e);
++ curDep = e;
+ }
+- List<Dep> list = new ArrayList<>();
+- for (Map.Entry<Archive,Profile> e: map.entrySet()) {
+- list.add(new Dep("", e.getKey(), e.getValue()));
+- }
+- return list;
+- }
+-
+- /**
+- * Dep represents a dependence where the target can be
+- * a classname or packagename and the archive and profile
+- * the target belongs to.
+- */
+- class Dep implements Comparable<Dep> {
+- final String target;
+- final Archive archive;
+- final Profile profile;
+- Dep(String target, Archive archive, Profile p) {
+- this.target = target;
+- this.archive = archive;
+- this.profile = p;
+- }
+-
+- @Override
+- public boolean equals(Object o) {
+- if (o instanceof Dep) {
+- Dep d = (Dep)o;
+- return this.archive == d.archive && this.target.equals(d.target);
+- }
+- return false;
+- }
+-
+- @Override
+- public int hashCode() {
+- int hash = 3;
+- hash = 17 * hash + Objects.hashCode(this.archive);
+- hash = 17 * hash + Objects.hashCode(this.target);
+- return hash;
+- }
+-
+- @Override
+- public int compareTo(Dep o) {
+- if (this.target.equals(o.target)) {
+- if (this.archive == o.archive) {
+- return 0;
+- } else {
+- return this.archive.getFileName().compareTo(o.archive.getFileName());
+- }
+- }
+- return this.target.compareTo(o.target);
+- }
+- }
+- public abstract void visit(Location o, Location t);
+- }
+-
+- private class ClassVisitor extends ArchiveDeps {
+- ClassVisitor(Archive archive) {
+- super(archive);
+- }
+- @Override
+- public void visit(Location o, Location t) {
+- Archive targetArchive =
+- this.archive.getClasses().contains(t) ? this.archive : map.get(t);
+- if (targetArchive == null) {
+- map.put(t, targetArchive = NOT_FOUND);
+- }
+-
+- String origin = o.getClassName();
+- String target = t.getClassName();
+- add(origin, target, targetArchive, t.getPackageName());
++ return curDep;
+ }
+ }
+
+- private class PackageVisitor extends ArchiveDeps {
+- PackageVisitor(Archive archive) {
+- super(archive);
++ /*
++ * Class-level or package-level dependency
++ */
++ class Dep implements Comparable<Dep> {
++ final String origin;
++ final Archive originArchive;
++ final String target;
++ final Archive targetArchive;
++
++ Dep(String origin, Archive originArchive, String target, Archive targetArchive) {
++ this.origin = origin;
++ this.originArchive = originArchive;
++ this.target = target;
++ this.targetArchive = targetArchive;
+ }
++
++ String origin() {
++ return origin;
++ }
++
++ Archive originArchive() {
++ return originArchive;
++ }
++
++ String target() {
++ return target;
++ }
++
++ Archive targetArchive() {
++ return targetArchive;
++ }
++
+ @Override
+- public void visit(Location o, Location t) {
+- Archive targetArchive =
+- this.archive.getClasses().contains(t) ? this.archive : map.get(t);
+- if (targetArchive == null) {
+- map.put(t, targetArchive = NOT_FOUND);
++ @SuppressWarnings("unchecked")
++ public boolean equals(Object o) {
++ if (o instanceof Dep) {
++ Dep d = (Dep) o;
++ return this.origin.equals(d.origin) &&
++ this.originArchive == d.originArchive &&
++ this.target.equals(d.target) &&
++ this.targetArchive == d.targetArchive;
+ }
++ return false;
++ }
+
+- String origin = packageOf(o);
+- String target = packageOf(t);
+- add(origin, target, targetArchive, t.getPackageName());
++ @Override
++ public int hashCode() {
++ int hash = 7;
++ hash = 67*hash + Objects.hashCode(this.origin)
++ + Objects.hashCode(this.originArchive)
++ + Objects.hashCode(this.target)
++ + Objects.hashCode(this.targetArchive);
++ return hash;
+ }
+- public String packageOf(Location o) {
+- String pkg = o.getPackageName();
+- return pkg.isEmpty() ? "<unnamed>" : pkg;
++
++ @Override
++ public int compareTo(Dep o) {
++ if (this.origin.equals(o.origin)) {
++ if (this.target.equals(o.target)) {
++ if (this.originArchive == o.originArchive &&
++ this.targetArchive == o.targetArchive) {
++ return 0;
++ } else if (this.originArchive == o.originArchive) {
++ return this.targetArchive.getPathName().compareTo(o.targetArchive.getPathName());
++ } else {
++ return this.originArchive.getPathName().compareTo(o.originArchive.getPathName());
++ }
++ } else {
++ return this.target.compareTo(o.target);
++ }
++ }
++ return this.origin.compareTo(o.origin);
+ }
+ }
+ }
+--- ./langtools/src/share/classes/com/sun/tools/jdeps/Archive.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/jdeps/Archive.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -25,28 +25,34 @@
+ package com.sun.tools.jdeps;
+
+ import com.sun.tools.classfile.Dependency.Location;
++
++import java.io.IOException;
+ import java.nio.file.Path;
+-import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.Map;
+ import java.util.Set;
++import java.util.concurrent.ConcurrentHashMap;
+
+ /**
+ * Represents the source of the class files.
+ */
+ public class Archive {
++ public static Archive getInstance(Path p) throws IOException {
++ return new Archive(p, ClassFileReader.newInstance(p));
++ }
++
+ private final Path path;
+ private final String filename;
+ private final ClassFileReader reader;
+- private final Map<Location, Set<Location>> deps = new HashMap<>();
++ protected Map<Location, Set<Location>> deps = new ConcurrentHashMap<>();
+
+- public Archive(String name) {
++ protected Archive(String name) {
+ this.path = null;
+ this.filename = name;
+ this.reader = null;
+ }
+
+- public Archive(Path p, ClassFileReader reader) {
++ protected Archive(Path p, ClassFileReader reader) {
+ this.path = p;
+ this.filename = path.getFileName().toString();
+ this.reader = reader;
+@@ -56,7 +62,7 @@
+ return reader;
+ }
+
+- public String getFileName() {
++ public String getName() {
+ return filename;
+ }
+
+@@ -89,6 +95,10 @@
+ }
+ }
+
++ public boolean isEmpty() {
++ return getClasses().isEmpty();
++ }
++
+ public String getPathName() {
+ return path != null ? path.toString() : filename;
+ }
+--- ./langtools/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -68,7 +68,8 @@
+
+ protected final Path path;
+ protected final String baseFileName;
+- private ClassFileReader(Path path) {
++ protected final List<String> skippedEntries = new ArrayList<>();
++ protected ClassFileReader(Path path) {
+ this.path = path;
+ this.baseFileName = path.getFileName() != null
+ ? path.getFileName().toString()
+@@ -79,6 +80,10 @@
+ return baseFileName;
+ }
+
++ public List<String> skippedEntries() {
++ return skippedEntries;
++ }
++
+ /**
+ * Returns the ClassFile matching the given binary name
+ * or a fully-qualified class name.
+@@ -232,11 +237,12 @@
+ }
+ }
+
+- private static class JarFileReader extends ClassFileReader {
+- final JarFile jarfile;
++ static class JarFileReader extends ClassFileReader {
++ private final JarFile jarfile;
+ JarFileReader(Path path) throws IOException {
+- this(path, new JarFile(path.toFile()));
++ this(path, new JarFile(path.toFile(), false));
+ }
++
+ JarFileReader(Path path, JarFile jf) throws IOException {
+ super(path);
+ this.jarfile = jf;
+@@ -252,18 +258,18 @@
+ + entryName.substring(i + 1, entryName.length()));
+ }
+ if (e != null) {
+- return readClassFile(e);
++ return readClassFile(jarfile, e);
+ }
+ } else {
+ JarEntry e = jarfile.getJarEntry(name + ".class");
+ if (e != null) {
+- return readClassFile(e);
++ return readClassFile(jarfile, e);
+ }
+ }
+ return null;
+ }
+
+- private ClassFile readClassFile(JarEntry e) throws IOException {
++ protected ClassFile readClassFile(JarFile jarfile, JarEntry e) throws IOException {
+ InputStream is = null;
+ try {
+ is = jarfile.getInputStream(e);
+@@ -277,60 +283,76 @@
+ }
+
+ public Iterable<ClassFile> getClassFiles() throws IOException {
+- final Iterator<ClassFile> iter = new JarFileIterator();
++ final Iterator<ClassFile> iter = new JarFileIterator(this, jarfile);
+ return new Iterable<ClassFile>() {
+ public Iterator<ClassFile> iterator() {
+ return iter;
+ }
+ };
+ }
++ }
+
+- class JarFileIterator implements Iterator<ClassFile> {
+- private Enumeration<JarEntry> entries;
+- private JarEntry nextEntry;
+- JarFileIterator() {
+- this.entries = jarfile.entries();
+- while (entries.hasMoreElements()) {
+- JarEntry e = entries.nextElement();
+- String name = e.getName();
+- if (name.endsWith(".class")) {
+- this.nextEntry = e;
+- break;
+- }
++ class JarFileIterator implements Iterator<ClassFile> {
++ protected final JarFileReader reader;
++ protected Enumeration<JarEntry> entries;
++ protected JarFile jf;
++ protected JarEntry nextEntry;
++ protected ClassFile cf;
++ JarFileIterator(JarFileReader reader) {
++ this(reader, null);
++ }
++ JarFileIterator(JarFileReader reader, JarFile jarfile) {
++ this.reader = reader;
++ setJarFile(jarfile);
++ }
++
++ void setJarFile(JarFile jarfile) {
++ if (jarfile == null) return;
++
++ this.jf = jarfile;
++ this.entries = jf.entries();
++ this.nextEntry = nextEntry();
++ }
++
++ public boolean hasNext() {
++ if (nextEntry != null && cf != null) {
++ return true;
++ }
++ while (nextEntry != null) {
++ try {
++ cf = reader.readClassFile(jf, nextEntry);
++ return true;
++ } catch (ClassFileError | IOException ex) {
++ skippedEntries.add(nextEntry.getName());
++ }
++ nextEntry = nextEntry();
++ }
++ return false;
++ }
++
++ public ClassFile next() {
++ if (!hasNext()) {
++ throw new NoSuchElementException();
++ }
++ ClassFile classFile = cf;
++ cf = null;
++ nextEntry = nextEntry();
++ return classFile;
++ }
++
++ protected JarEntry nextEntry() {
++ while (entries.hasMoreElements()) {
++ JarEntry e = entries.nextElement();
++ String name = e.getName();
++ if (name.endsWith(".class")) {
++ return e;
+ }
+ }
++ return null;
++ }
+
+- public boolean hasNext() {
+- return nextEntry != null;
+- }
+-
+- public ClassFile next() {
+- if (!hasNext()) {
+- throw new NoSuchElementException();
+- }
+-
+- ClassFile cf;
+- try {
+- cf = readClassFile(nextEntry);
+- } catch (IOException ex) {
+- throw new ClassFileError(ex);
+- }
+- JarEntry entry = nextEntry;
+- nextEntry = null;
+- while (entries.hasMoreElements()) {
+- JarEntry e = entries.nextElement();
+- String name = e.getName();
+- if (name.endsWith(".class")) {
+- nextEntry = e;
+- break;
+- }
+- }
+- return cf;
+- }
+-
+- public void remove() {
+- throw new UnsupportedOperationException("Not supported yet.");
+- }
++ public void remove() {
++ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ }
+ }
+--- ./langtools/src/share/classes/com/sun/tools/jdeps/JdepsTask.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/jdeps/JdepsTask.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -30,7 +30,9 @@
+ import com.sun.tools.classfile.Dependencies;
+ import com.sun.tools.classfile.Dependencies.ClassFileError;
+ import com.sun.tools.classfile.Dependency;
++import com.sun.tools.classfile.Dependency.Location;
+ import com.sun.tools.jdeps.PlatformClassPath.JDKArchive;
++import static com.sun.tools.jdeps.Analyzer.Type.*;
+ import java.io.*;
+ import java.nio.file.DirectoryStream;
+ import java.nio.file.Files;
+@@ -110,7 +112,7 @@
+ void process(JdepsTask task, String opt, String arg) throws BadArgs {
+ Path p = Paths.get(arg);
+ if (Files.exists(p) && (!Files.isDirectory(p) || !Files.isWritable(p))) {
+- throw new BadArgs("err.dot.output.path", arg);
++ throw new BadArgs("err.invalid.path", arg);
+ }
+ task.options.dotOutputDir = arg;
+ }
+@@ -118,25 +120,26 @@
+ new Option(false, "-s", "-summary") {
+ void process(JdepsTask task, String opt, String arg) {
+ task.options.showSummary = true;
+- task.options.verbose = Analyzer.Type.SUMMARY;
++ task.options.verbose = SUMMARY;
+ }
+ },
+ new Option(false, "-v", "-verbose",
+ "-verbose:package",
+- "-verbose:class")
+- {
++ "-verbose:class") {
+ void process(JdepsTask task, String opt, String arg) throws BadArgs {
+ switch (opt) {
+ case "-v":
+ case "-verbose":
+- task.options.verbose = Analyzer.Type.VERBOSE;
++ task.options.verbose = VERBOSE;
++ task.options.filterSameArchive = false;
++ task.options.filterSamePackage = false;
+ break;
+ case "-verbose:package":
+- task.options.verbose = Analyzer.Type.PACKAGE;
+- break;
++ task.options.verbose = PACKAGE;
++ break;
+ case "-verbose:class":
+- task.options.verbose = Analyzer.Type.CLASS;
+- break;
++ task.options.verbose = CLASS;
++ break;
+ default:
+ throw new BadArgs("err.invalid.arg.for.option", opt);
+ }
+@@ -157,6 +160,32 @@
+ task.options.regex = arg;
+ }
+ },
++
++ new Option(true, "-f", "-filter") {
++ void process(JdepsTask task, String opt, String arg) {
++ task.options.filterRegex = arg;
++ }
++ },
++ new Option(false, "-filter:package",
++ "-filter:archive",
++ "-filter:none") {
++ void process(JdepsTask task, String opt, String arg) {
++ switch (opt) {
++ case "-filter:package":
++ task.options.filterSamePackage = true;
++ task.options.filterSameArchive = false;
++ break;
++ case "-filter:archive":
++ task.options.filterSameArchive = true;
++ task.options.filterSamePackage = false;
++ break;
++ case "-filter:none":
++ task.options.filterSameArchive = false;
++ task.options.filterSamePackage = false;
++ break;
++ }
++ }
++ },
+ new Option(true, "-include") {
+ void process(JdepsTask task, String opt, String arg) throws BadArgs {
+ task.options.includePattern = Pattern.compile(arg);
+@@ -178,12 +207,15 @@
+ new Option(false, "-R", "-recursive") {
+ void process(JdepsTask task, String opt, String arg) {
+ task.options.depth = 0;
++ // turn off filtering
++ task.options.filterSameArchive = false;
++ task.options.filterSamePackage = false;
+ }
+ },
+ new Option(false, "-jdkinternals") {
+ void process(JdepsTask task, String opt, String arg) {
+ task.options.findJDKInternals = true;
+- task.options.verbose = Analyzer.Type.CLASS;
++ task.options.verbose = CLASS;
+ if (task.options.includePattern == null) {
+ task.options.includePattern = Pattern.compile(".*");
+ }
+@@ -204,6 +236,11 @@
+ task.options.showLabel = true;
+ }
+ },
++ new HiddenOption(false, "-q", "-quiet") {
++ void process(JdepsTask task, String opt, String arg) {
++ task.options.nowarning = true;
++ }
++ },
+ new HiddenOption(true, "-depth") {
+ void process(JdepsTask task, String opt, String arg) throws BadArgs {
+ try {
+@@ -217,7 +254,7 @@
+
+ private static final String PROGNAME = "jdeps";
+ private final Options options = new Options();
+- private final List<String> classes = new ArrayList<String>();
++ private final List<String> classes = new ArrayList<>();
+
+ private PrintWriter log;
+ void setLog(PrintWriter out) {
+@@ -262,7 +299,7 @@
+ showHelp();
+ return EXIT_CMDERR;
+ }
+- if (options.showSummary && options.verbose != Analyzer.Type.SUMMARY) {
++ if (options.showSummary && options.verbose != SUMMARY) {
+ showHelp();
+ return EXIT_CMDERR;
+ }
+@@ -283,9 +320,30 @@
+
+ private final List<Archive> sourceLocations = new ArrayList<>();
+ private boolean run() throws IOException {
++ // parse classfiles and find all dependencies
+ findDependencies();
+- Analyzer analyzer = new Analyzer(options.verbose);
++
++ Analyzer analyzer = new Analyzer(options.verbose, new Analyzer.Filter() {
++ @Override
++ public boolean accepts(Location origin, Archive originArchive,
++ Location target, Archive targetArchive)
++ {
++ if (options.findJDKInternals) {
++ // accepts target that is JDK class but not exported
++ return isJDKArchive(targetArchive) &&
++ !((JDKArchive) targetArchive).isExported(target.getClassName());
++ } else if (options.filterSameArchive) {
++ // accepts origin and target that from different archive
++ return originArchive != targetArchive;
++ }
++ return true;
++ }
++ });
++
++ // analyze the dependencies
+ analyzer.run(sourceLocations);
++
++ // output result
+ if (options.dotOutputDir != null) {
+ Path dir = Paths.get(options.dotOutputDir);
+ Files.createDirectories(dir);
+@@ -293,30 +351,41 @@
+ } else {
+ printRawOutput(log, analyzer);
+ }
++
++ if (options.findJDKInternals && !options.nowarning) {
++ showReplacements(analyzer);
++ }
+ return true;
+ }
+
+- private void generateDotFiles(Path dir, Analyzer analyzer) throws IOException {
++ private void generateSummaryDotFile(Path dir, Analyzer analyzer) throws IOException {
++ // If verbose mode (-v or -verbose option),
++ // the summary.dot file shows package-level dependencies.
++ Analyzer.Type summaryType =
++ (options.verbose == PACKAGE || options.verbose == SUMMARY) ? SUMMARY : PACKAGE;
+ Path summary = dir.resolve("summary.dot");
+- boolean verbose = options.verbose == Analyzer.Type.VERBOSE;
+- DotGraph<?> graph = verbose ? new DotSummaryForPackage()
+- : new DotSummaryForArchive();
+- for (Archive archive : sourceLocations) {
+- analyzer.visitArchiveDependences(archive, graph);
+- if (verbose || options.showLabel) {
+- // traverse detailed dependences to generate package-level
+- // summary or build labels for edges
+- analyzer.visitDependences(archive, graph);
++ try (PrintWriter sw = new PrintWriter(Files.newOutputStream(summary));
++ SummaryDotFile dotfile = new SummaryDotFile(sw, summaryType)) {
++ for (Archive archive : sourceLocations) {
++ if (!archive.isEmpty()) {
++ if (options.verbose == PACKAGE || options.verbose == SUMMARY) {
++ if (options.showLabel) {
++ // build labels listing package-level dependencies
++ analyzer.visitDependences(archive, dotfile.labelBuilder(), PACKAGE);
++ }
++ }
++ analyzer.visitDependences(archive, dotfile, summaryType);
++ }
+ }
+ }
+- try (PrintWriter sw = new PrintWriter(Files.newOutputStream(summary))) {
+- graph.writeTo(sw);
+- }
++ }
++
++ private void generateDotFiles(Path dir, Analyzer analyzer) throws IOException {
+ // output individual .dot file for each archive
+- if (options.verbose != Analyzer.Type.SUMMARY) {
++ if (options.verbose != SUMMARY) {
+ for (Archive archive : sourceLocations) {
+ if (analyzer.hasDependences(archive)) {
+- Path dotfile = dir.resolve(archive.getFileName() + ".dot");
++ Path dotfile = dir.resolve(archive.getName() + ".dot");
+ try (PrintWriter pw = new PrintWriter(Files.newOutputStream(dotfile));
+ DotFileFormatter formatter = new DotFileFormatter(pw, archive)) {
+ analyzer.visitDependences(archive, formatter);
+@@ -324,17 +393,23 @@
+ }
+ }
+ }
++ // generate summary dot file
++ generateSummaryDotFile(dir, analyzer);
+ }
+
+ private void printRawOutput(PrintWriter writer, Analyzer analyzer) {
++ RawOutputFormatter depFormatter = new RawOutputFormatter(writer);
++ RawSummaryFormatter summaryFormatter = new RawSummaryFormatter(writer);
+ for (Archive archive : sourceLocations) {
+- RawOutputFormatter formatter = new RawOutputFormatter(writer);
+- analyzer.visitArchiveDependences(archive, formatter);
+- if (options.verbose != Analyzer.Type.SUMMARY) {
+- analyzer.visitDependences(archive, formatter);
++ if (!archive.isEmpty()) {
++ analyzer.visitDependences(archive, summaryFormatter, SUMMARY);
++ if (analyzer.hasDependences(archive) && options.verbose != SUMMARY) {
++ analyzer.visitDependences(archive, depFormatter);
++ }
+ }
+ }
+ }
++
+ private boolean isValidClassName(String name) {
+ if (!Character.isJavaIdentifierStart(name.charAt(0))) {
+ return false;
+@@ -348,21 +423,54 @@
+ return true;
+ }
+
+- private Dependency.Filter getDependencyFilter() {
+- if (options.regex != null) {
+- return Dependencies.getRegexFilter(Pattern.compile(options.regex));
+- } else if (options.packageNames.size() > 0) {
+- return Dependencies.getPackageFilter(options.packageNames, false);
+- } else {
+- return new Dependency.Filter() {
+- @Override
+- public boolean accepts(Dependency dependency) {
+- return !dependency.getOrigin().equals(dependency.getTarget());
+- }
+- };
++ /*
++ * Dep Filter configured based on the input jdeps option
++ * 1. -p and -regex to match target dependencies
++ * 2. -filter:package to filter out same-package dependencies
++ *
++ * This filter is applied when jdeps parses the class files
++ * and filtered dependencies are not stored in the Analyzer.
++ *
++ * -filter:archive is applied later in the Analyzer as the
++ * containing archive of a target class may not be known until
++ * the entire archive
++ */
++ class DependencyFilter implements Dependency.Filter {
++ final Dependency.Filter filter;
++ final Pattern filterPattern;
++ DependencyFilter() {
++ if (options.regex != null) {
++ this.filter = Dependencies.getRegexFilter(Pattern.compile(options.regex));
++ } else if (options.packageNames.size() > 0) {
++ this.filter = Dependencies.getPackageFilter(options.packageNames, false);
++ } else {
++ this.filter = null;
++ }
++
++ this.filterPattern =
++ options.filterRegex != null ? Pattern.compile(options.filterRegex) : null;
++ }
++ @Override
++ public boolean accepts(Dependency d) {
++ if (d.getOrigin().equals(d.getTarget())) {
++ return false;
++ }
++ String pn = d.getTarget().getPackageName();
++ if (options.filterSamePackage && d.getOrigin().getPackageName().equals(pn)) {
++ return false;
++ }
++
++ if (filterPattern != null && filterPattern.matcher(pn).matches()) {
++ return false;
++ }
++ return filter != null ? filter.accepts(d) : true;
+ }
+ }
+
++ /**
++ * Tests if the given class matches the pattern given in the -include option
++ * or if it's a public class if -apionly option is specified
++ */
+ private boolean matches(String classname, AccessFlags flags) {
+ if (options.apiOnly && !flags.is(AccessFlags.ACC_PUBLIC)) {
+ return false;
+@@ -377,14 +485,14 @@
+ Dependency.Finder finder =
+ options.apiOnly ? Dependencies.getAPIFinder(AccessFlags.ACC_PROTECTED)
+ : Dependencies.getClassDependencyFinder();
+- Dependency.Filter filter = getDependencyFilter();
++ Dependency.Filter filter = new DependencyFilter();
+
+ List<Archive> archives = new ArrayList<>();
+ Deque<String> roots = new LinkedList<>();
+ for (String s : classes) {
+ Path p = Paths.get(s);
+ if (Files.exists(p)) {
+- archives.add(new Archive(p, ClassFileReader.newInstance(p)));
++ archives.add(Archive.getInstance(p));
+ } else {
+ if (isValidClassName(s)) {
+ roots.add(s);
+@@ -421,19 +529,26 @@
+ throw new ClassFileError(e);
+ }
+
+- if (matches(classFileName, cf.access_flags)) {
+- if (!doneClasses.contains(classFileName)) {
+- doneClasses.add(classFileName);
++ // tests if this class matches the -include or -apiOnly option if specified
++ if (!matches(classFileName, cf.access_flags)) {
++ continue;
++ }
++
++ if (!doneClasses.contains(classFileName)) {
++ doneClasses.add(classFileName);
++ }
++
++ for (Dependency d : finder.findDependencies(cf)) {
++ if (filter.accepts(d)) {
++ String cn = d.getTarget().getName();
++ if (!doneClasses.contains(cn) && !deque.contains(cn)) {
++ deque.add(cn);
++ }
++ a.addClass(d.getOrigin(), d.getTarget());
+ }
+- for (Dependency d : finder.findDependencies(cf)) {
+- if (filter.accepts(d)) {
+- String cn = d.getTarget().getName();
+- if (!doneClasses.contains(cn) && !deque.contains(cn)) {
+- deque.add(cn);
+- }
+- a.addClass(d.getOrigin(), d.getTarget());
+- }
+- }
++ }
++ for (String name : a.reader().skippedEntries()) {
++ warning("warn.skipped.entry", name, a.getPathName());
+ }
+ }
+ }
+@@ -462,6 +577,10 @@
+ // if name is a fully-qualified class name specified
+ // from command-line, this class might already be parsed
+ doneClasses.add(classFileName);
++ // process @jdk.Exported for JDK classes
++ if (isJDKArchive(a)) {
++ ((JDKArchive)a).processJdkExported(cf);
++ }
+ for (Dependency d : finder.findDependencies(cf)) {
+ if (depth == 0) {
+ // ignore the dependency
+@@ -544,7 +663,7 @@
+ for (Option o : recognizedOptions) {
+ String name = o.aliases[0].substring(1); // there must always be at least one name
+ name = name.charAt(0) == '-' ? name.substring(1) : name;
+- if (o.isHidden() || name.equals("h")) {
++ if (o.isHidden() || name.equals("h") || name.startsWith("filter:")) {
+ continue;
+ }
+ log.println(getMessage("main.opt." + name));
+@@ -582,14 +701,19 @@
+ boolean fullVersion;
+ boolean showProfile;
+ boolean showSummary;
+- boolean wildcard;
+ boolean apiOnly;
+ boolean showLabel;
+ boolean findJDKInternals;
++ boolean nowarning;
++ // default is to show package-level dependencies
++ // and filter references from same package
++ Analyzer.Type verbose = PACKAGE;
++ boolean filterSamePackage = true;
++ boolean filterSameArchive = false;
++ String filterRegex;
+ String dotOutputDir;
+ String classpath = "";
+ int depth = 1;
+- Analyzer.Type verbose = Analyzer.Type.PACKAGE;
+ Set<String> packageNames = new HashSet<>();
+ String regex; // apply to the dependences
+ Pattern includePattern; // apply to classes
+@@ -597,6 +721,7 @@
+ private static class ResourceBundleHelper {
+ static final ResourceBundle versionRB;
+ static final ResourceBundle bundle;
++ static final ResourceBundle jdkinternals;
+
+ static {
+ Locale locale = Locale.getDefault();
+@@ -610,20 +735,12 @@
+ } catch (MissingResourceException e) {
+ throw new InternalError("version.resource.missing");
+ }
+- }
+- }
+-
+- private List<Archive> getArchives(List<String> filenames) throws IOException {
+- List<Archive> result = new ArrayList<Archive>();
+- for (String s : filenames) {
+- Path p = Paths.get(s);
+- if (Files.exists(p)) {
+- result.add(new Archive(p, ClassFileReader.newInstance(p)));
+- } else {
+- warning("warn.file.not.exist", s);
++ try {
++ jdkinternals = ResourceBundle.getBundle("com.sun.tools.jdeps.resources.jdkinternals");
++ } catch (MissingResourceException e) {
++ throw new InternalError("Cannot find jdkinternals resource bundle");
+ }
+ }
+- return result;
+ }
+
+ private List<Archive> getClassPathArchives(String paths) throws IOException {
+@@ -648,7 +765,7 @@
+ }
+ for (Path f : files) {
+ if (Files.exists(f)) {
+- result.add(new Archive(f, ClassFileReader.newInstance(f)));
++ result.add(Archive.getInstance(f));
+ }
+ }
+ }
+@@ -656,81 +773,50 @@
+ return result;
+ }
+
+- /**
+- * If the given archive is JDK archive and non-null Profile,
+- * this method returns the profile name only if -profile option is specified;
+- * a null profile indicates it accesses a private JDK API and this method
+- * will return "JDK internal API".
+- *
+- * For non-JDK archives, this method returns the file name of the archive.
+- */
+- private String getProfileArchiveInfo(Archive source, Profile profile) {
+- if (options.showProfile && profile != null)
+- return profile.toString();
+-
+- if (source instanceof JDKArchive) {
+- return profile == null ? "JDK internal API (" + source.getFileName() + ")" : "";
+- }
+- return source.getFileName();
+- }
+-
+- /**
+- * Returns the profile name or "JDK internal API" for JDK archive;
+- * otherwise empty string.
+- */
+- private String profileName(Archive archive, Profile profile) {
+- if (archive instanceof JDKArchive) {
+- return Objects.toString(profile, "JDK internal API");
+- } else {
+- return "";
+- }
+- }
+-
+ class RawOutputFormatter implements Analyzer.Visitor {
+ private final PrintWriter writer;
++ private String pkg = "";
+ RawOutputFormatter(PrintWriter writer) {
+ this.writer = writer;
+ }
+-
+- private String pkg = "";
+ @Override
+- public void visitDependence(String origin, Archive source,
+- String target, Archive archive, Profile profile) {
+- if (options.findJDKInternals &&
+- !(archive instanceof JDKArchive && profile == null)) {
+- // filter dependences other than JDK internal APIs
+- return;
+- }
+- if (options.verbose == Analyzer.Type.VERBOSE) {
+- writer.format(" %-50s -> %-50s %s%n",
+- origin, target, getProfileArchiveInfo(archive, profile));
++ public void visitDependence(String origin, Archive originArchive,
++ String target, Archive targetArchive) {
++ String tag = toTag(target, targetArchive);
++ if (options.verbose == VERBOSE) {
++ writer.format(" %-50s -> %-50s %s%n", origin, target, tag);
+ } else {
+ if (!origin.equals(pkg)) {
+ pkg = origin;
+- writer.format(" %s (%s)%n", origin, source.getFileName());
++ writer.format(" %s (%s)%n", origin, originArchive.getName());
+ }
+- writer.format(" -> %-50s %s%n",
+- target, getProfileArchiveInfo(archive, profile));
+- }
+- }
+-
+- @Override
+- public void visitArchiveDependence(Archive origin, Archive target, Profile profile) {
+- writer.format("%s -> %s", origin.getPathName(), target.getPathName());
+- if (options.showProfile && profile != null) {
+- writer.format(" (%s)%n", profile);
+- } else {
+- writer.format("%n");
++ writer.format(" -> %-50s %s%n", target, tag);
+ }
+ }
+ }
+
+- class DotFileFormatter extends DotGraph<String> implements AutoCloseable {
++ class RawSummaryFormatter implements Analyzer.Visitor {
++ private final PrintWriter writer;
++ RawSummaryFormatter(PrintWriter writer) {
++ this.writer = writer;
++ }
++ @Override
++ public void visitDependence(String origin, Archive originArchive,
++ String target, Archive targetArchive) {
++ writer.format("%s -> %s", originArchive.getName(), targetArchive.getPathName());
++ if (options.showProfile && JDKArchive.isProfileArchive(targetArchive)) {
++ writer.format(" (%s)", target);
++ }
++ writer.format("%n");
++ }
++ }
++
++ class DotFileFormatter implements Analyzer.Visitor, AutoCloseable {
+ private final PrintWriter writer;
+ private final String name;
+ DotFileFormatter(PrintWriter writer, Archive archive) {
+ this.writer = writer;
+- this.name = archive.getFileName();
++ this.name = archive.getName();
+ writer.format("digraph \"%s\" {%n", name);
+ writer.format(" // Path: %s%n", archive.getPathName());
+ }
+@@ -741,173 +827,176 @@
+ }
+
+ @Override
+- public void visitDependence(String origin, Archive source,
+- String target, Archive archive, Profile profile) {
+- if (options.findJDKInternals &&
+- !(archive instanceof JDKArchive && profile == null)) {
+- // filter dependences other than JDK internal APIs
+- return;
+- }
+- // if -P option is specified, package name -> profile will
+- // be shown and filter out multiple same edges.
+- String name = getProfileArchiveInfo(archive, profile);
+- writeEdge(writer, new Edge(origin, target, getProfileArchiveInfo(archive, profile)));
+- }
+- @Override
+- public void visitArchiveDependence(Archive origin, Archive target, Profile profile) {
+- throw new UnsupportedOperationException();
++ public void visitDependence(String origin, Archive originArchive,
++ String target, Archive targetArchive) {
++ String tag = toTag(target, targetArchive);
++ writer.format(" %-50s -> \"%s\";%n",
++ String.format("\"%s\"", origin),
++ tag.isEmpty() ? target
++ : String.format("%s (%s)", target, tag));
+ }
+ }
+
+- class DotSummaryForArchive extends DotGraph<Archive> {
++ class SummaryDotFile implements Analyzer.Visitor, AutoCloseable {
++ private final PrintWriter writer;
++ private final Analyzer.Type type;
++ private final Map<Archive, Map<Archive,StringBuilder>> edges = new HashMap<>();
++ SummaryDotFile(PrintWriter writer, Analyzer.Type type) {
++ this.writer = writer;
++ this.type = type;
++ writer.format("digraph \"summary\" {%n");
++ }
++
+ @Override
+- public void visitDependence(String origin, Archive source,
+- String target, Archive archive, Profile profile) {
+- Edge e = findEdge(source, archive);
+- assert e != null;
+- // add the dependency to the label if enabled and not compact1
+- if (profile == Profile.COMPACT1) {
+- return;
++ public void close() {
++ writer.println("}");
++ }
++
++ @Override
++ public void visitDependence(String origin, Archive originArchive,
++ String target, Archive targetArchive) {
++ String targetName = type == PACKAGE ? target : targetArchive.getName();
++ if (type == PACKAGE) {
++ String tag = toTag(target, targetArchive, type);
++ if (!tag.isEmpty())
++ targetName += " (" + tag + ")";
++ } else if (options.showProfile && JDKArchive.isProfileArchive(targetArchive)) {
++ targetName += " (" + target + ")";
+ }
+- e.addLabel(origin, target, profileName(archive, profile));
++ String label = getLabel(originArchive, targetArchive);
++ writer.format(" %-50s -> \"%s\"%s;%n",
++ String.format("\"%s\"", origin), targetName, label);
+ }
+- @Override
+- public void visitArchiveDependence(Archive origin, Archive target, Profile profile) {
+- // add an edge with the archive's name with no tag
+- // so that there is only one node for each JDK archive
+- // while there may be edges to different profiles
+- Edge e = addEdge(origin, target, "");
+- if (target instanceof JDKArchive) {
+- // add a label to print the profile
+- if (profile == null) {
+- e.addLabel("JDK internal API");
+- } else if (options.showProfile && !options.showLabel) {
+- e.addLabel(profile.toString());
++
++ String getLabel(Archive origin, Archive target) {
++ if (edges.isEmpty())
++ return "";
++
++ StringBuilder label = edges.get(origin).get(target);
++ return label == null ? "" : String.format(" [label=\"%s\",fontsize=9]", label.toString());
++ }
++
++ Analyzer.Visitor labelBuilder() {
++ // show the package-level dependencies as labels in the dot graph
++ return new Analyzer.Visitor() {
++ @Override
++ public void visitDependence(String origin, Archive originArchive,
++ String target, Archive targetArchive)
++ {
++ Map<Archive,StringBuilder> labels = edges.get(originArchive);
++ if (!edges.containsKey(originArchive)) {
++ edges.put(originArchive, labels = new HashMap<>());
++ }
++ StringBuilder sb = labels.get(targetArchive);
++ if (sb == null) {
++ labels.put(targetArchive, sb = new StringBuilder());
++ }
++ String tag = toTag(target, targetArchive, PACKAGE);
++ addLabel(sb, origin, target, tag);
++ }
++
++ void addLabel(StringBuilder label, String origin, String target, String tag) {
++ label.append(origin).append(" -> ").append(target);
++ if (!tag.isEmpty()) {
++ label.append(" (" + tag + ")");
++ }
++ label.append("\\n");
++ }
++ };
++ }
++ }
++
++ /**
++ * Test if the given archive is part of the JDK
++ */
++ private boolean isJDKArchive(Archive archive) {
++ return JDKArchive.class.isInstance(archive);
++ }
++
++ /**
++ * If the given archive is JDK archive, this method returns the profile name
++ * only if -profile option is specified; it accesses a private JDK API and
++ * the returned value will have "JDK internal API" prefix
++ *
++ * For non-JDK archives, this method returns the file name of the archive.
++ */
++ private String toTag(String name, Archive source, Analyzer.Type type) {
++ if (!isJDKArchive(source)) {
++ return source.getName();
++ }
++
++ JDKArchive jdk = (JDKArchive)source;
++ boolean isExported = false;
++ if (type == CLASS || type == VERBOSE) {
++ isExported = jdk.isExported(name);
++ } else {
++ isExported = jdk.isExportedPackage(name);
++ }
++ Profile p = getProfile(name, type);
++ if (isExported) {
++ // exported API
++ return options.showProfile && p != null ? p.profileName() : "";
++ } else {
++ return "JDK internal API (" + source.getName() + ")";
++ }
++ }
++
++ private String toTag(String name, Archive source) {
++ return toTag(name, source, options.verbose);
++ }
++
++ private Profile getProfile(String name, Analyzer.Type type) {
++ String pn = name;
++ if (type == CLASS || type == VERBOSE) {
++ int i = name.lastIndexOf('.');
++ pn = i > 0 ? name.substring(0, i) : "";
++ }
++ return Profile.getProfile(pn);
++ }
++
++ /**
++ * Returns the recommended replacement API for the given classname;
++ * or return null if replacement API is not known.
++ */
++ private String replacementFor(String cn) {
++ String name = cn;
++ String value = null;
++ while (value == null && name != null) {
++ try {
++ value = ResourceBundleHelper.jdkinternals.getString(name);
++ } catch (MissingResourceException e) {
++ // go up one subpackage level
++ int i = name.lastIndexOf('.');
++ name = i > 0 ? name.substring(0, i) : null;
++ }
++ }
++ return value;
++ };
++
++ private void showReplacements(Analyzer analyzer) {
++ Map<String,String> jdkinternals = new TreeMap<>();
++ boolean useInternals = false;
++ for (Archive source : sourceLocations) {
++ useInternals = useInternals || analyzer.hasDependences(source);
++ for (String cn : analyzer.dependences(source)) {
++ String repl = replacementFor(cn);
++ if (repl != null && !jdkinternals.containsKey(cn)) {
++ jdkinternals.put(cn, repl);
+ }
+ }
+ }
+- }
+-
+- // DotSummaryForPackage generates the summary.dot file for verbose mode
+- // (-v or -verbose option) that includes all class dependencies.
+- // The summary.dot file shows package-level dependencies.
+- class DotSummaryForPackage extends DotGraph<String> {
+- private String packageOf(String cn) {
+- int i = cn.lastIndexOf('.');
+- return i > 0 ? cn.substring(0, i) : "<unnamed>";
++ if (useInternals) {
++ log.println();
++ warning("warn.replace.useJDKInternals", getMessage("jdeps.wiki.url"));
+ }
+- @Override
+- public void visitDependence(String origin, Archive source,
+- String target, Archive archive, Profile profile) {
+- // add a package dependency edge
+- String from = packageOf(origin);
+- String to = packageOf(target);
+- Edge e = addEdge(from, to, getProfileArchiveInfo(archive, profile));
+-
+- // add the dependency to the label if enabled and not compact1
+- if (!options.showLabel || profile == Profile.COMPACT1) {
+- return;
++ if (!jdkinternals.isEmpty()) {
++ log.println();
++ log.format("%-40s %s%n", "JDK Internal API", "Suggested Replacement");
++ log.format("%-40s %s%n", "----------------", "---------------------");
++ for (Map.Entry<String,String> e : jdkinternals.entrySet()) {
++ log.format("%-40s %s%n", e.getKey(), e.getValue());
+ }
+-
+- // trim the package name of origin to shorten the label
+- int i = origin.lastIndexOf('.');
+- String n1 = i < 0 ? origin : origin.substring(i+1);
+- e.addLabel(n1, target, profileName(archive, profile));
+- }
+- @Override
+- public void visitArchiveDependence(Archive origin, Archive target, Profile profile) {
+- // nop
+- }
+- }
+- abstract class DotGraph<T> implements Analyzer.Visitor {
+- private final Set<Edge> edges = new LinkedHashSet<>();
+- private Edge curEdge;
+- public void writeTo(PrintWriter writer) {
+- writer.format("digraph \"summary\" {%n");
+- for (Edge e: edges) {
+- writeEdge(writer, e);
+- }
+- writer.println("}");
+ }
+
+- void writeEdge(PrintWriter writer, Edge e) {
+- writer.format(" %-50s -> \"%s\"%s;%n",
+- String.format("\"%s\"", e.from.toString()),
+- e.tag.isEmpty() ? e.to
+- : String.format("%s (%s)", e.to, e.tag),
+- getLabel(e));
+- }
+-
+- Edge addEdge(T origin, T target, String tag) {
+- Edge e = new Edge(origin, target, tag);
+- if (e.equals(curEdge)) {
+- return curEdge;
+- }
+-
+- if (edges.contains(e)) {
+- for (Edge e1 : edges) {
+- if (e.equals(e1)) {
+- curEdge = e1;
+- }
+- }
+- } else {
+- edges.add(e);
+- curEdge = e;
+- }
+- return curEdge;
+- }
+-
+- Edge findEdge(T origin, T target) {
+- for (Edge e : edges) {
+- if (e.from.equals(origin) && e.to.equals(target)) {
+- return e;
+- }
+- }
+- return null;
+- }
+-
+- String getLabel(Edge e) {
+- String label = e.label.toString();
+- return label.isEmpty() ? "" : String.format("[label=\"%s\",fontsize=9]", label);
+- }
+-
+- class Edge {
+- final T from;
+- final T to;
+- final String tag; // optional tag
+- final StringBuilder label = new StringBuilder();
+- Edge(T from, T to, String tag) {
+- this.from = from;
+- this.to = to;
+- this.tag = tag;
+- }
+- void addLabel(String s) {
+- label.append(s).append("\\n");
+- }
+- void addLabel(String origin, String target, String profile) {
+- label.append(origin).append(" -> ").append(target);
+- if (!profile.isEmpty()) {
+- label.append(" (" + profile + ")");
+- }
+- label.append("\\n");
+- }
+- @Override @SuppressWarnings("unchecked")
+- public boolean equals(Object o) {
+- if (o instanceof DotGraph<?>.Edge) {
+- DotGraph<?>.Edge e = (DotGraph<?>.Edge)o;
+- return this.from.equals(e.from) &&
+- this.to.equals(e.to) &&
+- this.tag.equals(e.tag);
+- }
+- return false;
+- }
+- @Override
+- public int hashCode() {
+- int hash = 7;
+- hash = 67 * hash + Objects.hashCode(this.from) +
+- Objects.hashCode(this.to) + Objects.hashCode(this.tag);
+- return hash;
+- }
+- }
+ }
+ }
+--- ./langtools/src/share/classes/com/sun/tools/jdeps/Main.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/jdeps/Main.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -63,4 +63,3 @@
+ return t.run(args);
+ }
+ }
+-
+--- ./langtools/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,6 +24,12 @@
+ */
+ package com.sun.tools.jdeps;
+
++import com.sun.tools.classfile.Annotation;
++import com.sun.tools.classfile.ClassFile;
++import com.sun.tools.classfile.ConstantPool;
++import com.sun.tools.classfile.ConstantPoolException;
++import com.sun.tools.classfile.RuntimeAnnotations_attribute;
++import com.sun.tools.classfile.Dependencies.ClassFileError;
+ import java.io.IOException;
+ import java.nio.file.FileVisitResult;
+ import java.nio.file.Files;
+@@ -33,11 +39,15 @@
+ import java.nio.file.attribute.BasicFileAttributes;
+ import java.util.*;
+
++import static com.sun.tools.classfile.Attribute.*;
++
+ /**
+ * ClassPath for Java SE and JDK
+ */
+ class PlatformClassPath {
+- private final static List<Archive> javaHomeArchives = init();
++ private static final List<String> NON_PLATFORM_JARFILES =
++ Arrays.asList("alt-rt.jar", "jfxrt.jar", "ant-javafx.jar", "javafx-mx.jar");
++ private static final List<Archive> javaHomeArchives = init();
+
+ static List<Archive> getArchives() {
+ return javaHomeArchives;
+@@ -50,12 +60,19 @@
+ if (home.endsWith("jre")) {
+ // jar files in <javahome>/jre/lib
+ result.addAll(addJarFiles(home.resolve("lib")));
++ if (home.getParent() != null) {
++ // add tools.jar and other JDK jar files
++ Path lib = home.getParent().resolve("lib");
++ if (Files.exists(lib)) {
++ result.addAll(addJarFiles(lib));
++ }
++ }
+ } else if (Files.exists(home.resolve("lib"))) {
+ // either a JRE or a jdk build image
+ Path classes = home.resolve("classes");
+ if (Files.isDirectory(classes)) {
+ // jdk build outputdir
+- result.add(new JDKArchive(classes, ClassFileReader.newInstance(classes)));
++ result.add(new JDKArchive(classes));
+ }
+ // add other JAR files
+ result.addAll(addJarFiles(home.resolve("lib")));
+@@ -91,9 +108,9 @@
+ if (fn.endsWith(".jar")) {
+ // JDK may cobundle with JavaFX that doesn't belong to any profile
+ // Treat jfxrt.jar as regular Archive
+- result.add(fn.equals("jfxrt.jar")
+- ? new Archive(p, ClassFileReader.newInstance(p))
+- : new JDKArchive(p, ClassFileReader.newInstance(p)));
++ result.add(NON_PLATFORM_JARFILES.contains(fn)
++ ? Archive.getInstance(p)
++ : new JDKArchive(p));
+ }
+ return FileVisitResult.CONTINUE;
+ }
+@@ -106,8 +123,91 @@
+ * or implementation classes (i.e. JDK internal API)
+ */
+ static class JDKArchive extends Archive {
+- JDKArchive(Path p, ClassFileReader reader) {
+- super(p, reader);
++ private static List<String> PROFILE_JARS = Arrays.asList("rt.jar", "jce.jar");
++ public static boolean isProfileArchive(Archive archive) {
++ if (archive instanceof JDKArchive) {
++ return PROFILE_JARS.contains(archive.getName());
++ }
++ return false;
++ }
++
++ private final Map<String,Boolean> exportedPackages = new HashMap<>();
++ private final Map<String,Boolean> exportedTypes = new HashMap<>();
++ JDKArchive(Path p) throws IOException {
++ super(p, ClassFileReader.newInstance(p));
++ }
++
++ /**
++ * Tests if a given fully-qualified name is an exported type.
++ */
++ public boolean isExported(String cn) {
++ int i = cn.lastIndexOf('.');
++ String pn = i > 0 ? cn.substring(0, i) : "";
++
++ boolean isJdkExported = isExportedPackage(pn);
++ if (exportedTypes.containsKey(cn)) {
++ return exportedTypes.get(cn);
++ }
++ return isJdkExported;
++ }
++
++ /**
++ * Tests if a given package name is exported.
++ */
++ public boolean isExportedPackage(String pn) {
++ if (Profile.getProfile(pn) != null || "javax.jnlp".equals(pn)) {
++ return true;
++ }
++ return exportedPackages.containsKey(pn) ? exportedPackages.get(pn) : false;
++ }
++
++ private static final String JDK_EXPORTED_ANNOTATION = "Ljdk/Exported;";
++ private Boolean isJdkExported(ClassFile cf) throws ConstantPoolException {
++ RuntimeAnnotations_attribute attr = (RuntimeAnnotations_attribute)
++ cf.attributes.get(RuntimeVisibleAnnotations);
++ if (attr != null) {
++ for (int i = 0; i < attr.annotations.length; i++) {
++ Annotation ann = attr.annotations[i];
++ String annType = cf.constant_pool.getUTF8Value(ann.type_index);
++ if (JDK_EXPORTED_ANNOTATION.equals(annType)) {
++ boolean isJdkExported = true;
++ for (int j = 0; j < ann.num_element_value_pairs; j++) {
++ Annotation.element_value_pair pair = ann.element_value_pairs[j];
++ Annotation.Primitive_element_value ev = (Annotation.Primitive_element_value) pair.value;
++ ConstantPool.CONSTANT_Integer_info info = (ConstantPool.CONSTANT_Integer_info)
++ cf.constant_pool.get(ev.const_value_index);
++ isJdkExported = info.value != 0;
++ }
++ return Boolean.valueOf(isJdkExported);
++ }
++ }
++ }
++ return null;
++ }
++
++ void processJdkExported(ClassFile cf) throws IOException {
++ try {
++ String cn = cf.getName();
++ String pn = cn.substring(0, cn.lastIndexOf('/')).replace('/', '.');
++
++ Boolean b = isJdkExported(cf);
++ if (b != null) {
++ exportedTypes.put(cn.replace('/', '.'), b);
++ }
++ if (!exportedPackages.containsKey(pn)) {
++ // check if package-info.class has @jdk.Exported
++ Boolean isJdkExported = null;
++ ClassFile pcf = reader().getClassFile(cn.substring(0, cn.lastIndexOf('/')+1) + "package-info");
++ if (pcf != null) {
++ isJdkExported = isJdkExported(pcf);
++ }
++ if (isJdkExported != null) {
++ exportedPackages.put(pn, isJdkExported);
++ }
++ }
++ } catch (ConstantPoolException e) {
++ throw new ClassFileError(e);
++ }
+ }
+ }
+ }
+--- ./langtools/src/share/classes/com/sun/tools/jdeps/Profile.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/jdeps/Profile.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -43,7 +43,6 @@
+ * Build the profile information from ct.sym if exists.
+ */
+ enum Profile {
+-
+ COMPACT1("compact1", 1),
+ COMPACT2("compact2", 2),
+ COMPACT3("compact3", 3),
+@@ -61,8 +60,7 @@
+ this.proprietaryPkgs = new HashSet<>();
+ }
+
+- @Override
+- public String toString() {
++ public String profileName() {
+ return name;
+ }
+
+@@ -77,7 +75,7 @@
+ public static Profile getProfile(String pn) {
+ Profile profile = PackageToProfile.map.get(pn);
+ return (profile != null && profile.packages.contains(pn))
+- ? profile : null;
++ ? profile : null;
+ }
+
+ static class PackageToProfile {
+--- ./langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties Wed Feb 04 12:14:46 2015 -0800
+@@ -1,6 +1,6 @@
+ main.usage.summary=\
+ Usage: {0} <options> <classes...>\n\
+-use -h, -? or --help for a list of possible options
++use -h, -? or -help for a list of possible options
+
+ main.usage=\
+ Usage: {0} <options> <classes...>\n\
+@@ -18,20 +18,29 @@
+
+ main.opt.v=\
+ \ -v -verbose Print all class level dependencies\n\
++\ Equivalent to -verbose:class -filter:none.\n\
+ \ -verbose:package Print package-level dependencies excluding\n\
+-\ dependencies within the same archive\n\
++\ dependencies within the same package by default\n\
+ \ -verbose:class Print class-level dependencies excluding\n\
+-\ dependencies within the same archive
++\ dependencies within the same package by default
++
++main.opt.f=\
++\ -f <regex> -filter <regex> Filter dependences matching the given pattern\n\
++\ If given multiple times, the last one will be used.\n\
++\ -filter:package Filter dependences within the same package (default)\n\
++\ -filter:archive Filter dependences within the same archive\n\
++\ -filter:none No -filter:package and -filter:archive filtering\n\
++\ Filtering specified via the -filter option still applies.
+
+ main.opt.s=\
+ \ -s -summary Print dependency summary only
+
+ main.opt.p=\
+-\ -p <pkgname> -package <pkgname> Finds dependences in the given package\n\
++\ -p <pkgname> -package <pkgname> Finds dependences matching the given package name\n\
+ \ (may be given multiple times)
+
+ main.opt.e=\
+-\ -e <regex> -regex <regex> Finds dependences in packages matching pattern\n\
++\ -e <regex> -regex <regex> Finds dependences matching the given pattern\n\
+ \ (-p and -e are exclusive)
+
+ main.opt.include=\
+@@ -47,7 +56,10 @@
+ \ -cp <path> -classpath <path> Specify where to find class files
+
+ main.opt.R=\
+-\ -R -recursive Recursively traverse all dependencies
++\ -R -recursive Recursively traverse all dependencies.\n\
++\ The -R option implies -filter:none. If -p, -e, -f\n\
++\ option is specified, only the matching dependences\n\
++\ are analyzed.
+
+ main.opt.apionly=\
+ \ -apionly Restrict analysis to APIs i.e. dependences\n\
+@@ -74,13 +86,19 @@
+
+ err.unknown.option=unknown option: {0}
+ err.missing.arg=no value given for {0}
+-err.internal.error=internal error: {0} {1} {2}
+ err.invalid.arg.for.option=invalid argument for option: {0}
+ err.option.after.class=option must be specified before classes: {0}
+ err.option.unsupported={0} not supported: {1}
+ err.profiles.msg=No profile information
+-err.dot.output.path=invalid path: {0}
++err.invalid.path=invalid path: {0}
+ warn.invalid.arg=Invalid classname or pathname not exist: {0}
+ warn.split.package=package {0} defined in {1} {2}
++warn.replace.useJDKInternals=\
++JDK internal APIs are unsupported and private to JDK implementation that are\n\
++subject to be removed or changed incompatibly and could break your application.\n\
++Please modify your code to eliminate dependency on any JDK internal APIs.\n\
++For the most recent update on JDK internal API replacements, please check:\n\
++{0}
+
+ artifact.not.found=not found
++jdeps.wiki.url=https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
+--- ./langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps_ja.properties Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps_ja.properties Wed Feb 04 12:14:46 2015 -0800
+@@ -1,4 +1,4 @@
+-main.usage.summary=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <classes...>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30EA\u30B9\u30C8\u306B\u3064\u3044\u3066\u306F\u3001-h\u3001-?\u307E\u305F\u306F--help\u3092\u4F7F\u7528\u3057\u307E\u3059
++main.usage.summary=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <classes...>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30EA\u30B9\u30C8\u306B\u3064\u3044\u3066\u306F\u3001-h\u3001-?\u307E\u305F\u306F-help\u3092\u4F7F\u7528\u3057\u307E\u3059
+
+ main.usage=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <classes...>\n<classes>\u306B\u306F\u3001.class\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9\u540D\u3001\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3001JAR\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u5B8C\u5168\u4FEE\u98FE\n\u30AF\u30E9\u30B9\u540D\u3092\u6307\u5B9A\u3067\u304D\u307E\u3059\u3002\u4F7F\u7528\u3067\u304D\u308B\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:
+
+@@ -9,13 +9,15 @@
+
+ main.opt.version=\ -version \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831
+
+-main.opt.v=\ -v -verbose \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u3059\u3079\u3066\u51FA\u529B\u3057\u307E\u3059\n -verbose:package \u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n (\u540C\u3058\u30A2\u30FC\u30AB\u30A4\u30D6\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F)\n -verbose:class \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n (\u540C\u3058\u30A2\u30FC\u30AB\u30A4\u30D6\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F)
++main.opt.v=\ -v -verbose \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u3059\u3079\u3066\u51FA\u529B\u3057\u307E\u3059\n -verbose:class -filter:none\u3068\u540C\u7B49\u3067\u3059\u3002\n -verbose:package \u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n (\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\u540C\u3058\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F)\n -verbose:class \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n (\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\u540C\u3058\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F)
++
++main.opt.f=\ -f <regex> -filter <regex> \u6307\u5B9A\u306E\u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059\n \u8907\u6570\u56DE\u6307\u5B9A\u3055\u308C\u305F\u5834\u5408\u3001\u6700\u5F8C\u306E\u3082\u306E\u304C\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n -filter:package \u540C\u3058\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -filter:archive \u540C\u3058\u30A2\u30FC\u30AB\u30A4\u30D6\u5185\u306E\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059\n -filter:none -filter:package\u304A\u3088\u3073-filter:archive\u306E\u30D5\u30A3\u30EB\u30BF\u30EA\u30F3\u30B0\u306F\u884C\u308F\u308C\u307E\u305B\u3093\n -filter\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u6307\u5B9A\u3057\u305F\u30D5\u30A3\u30EB\u30BF\u30EA\u30F3\u30B0\u304C\u5F15\u304D\u7D9A\u304D\u9069\u7528\u3055\u308C\u307E\u3059\u3002
+
+ main.opt.s=\ -s -summary \u4F9D\u5B58\u6027\u306E\u30B5\u30DE\u30EA\u30FC\u306E\u307F\u51FA\u529B\u3057\u307E\u3059
+
+-main.opt.p=\ -p <pkgname> -package <pkgname> \u6307\u5B9A\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n (\u8907\u6570\u56DE\u6307\u5B9A\u53EF\u80FD)
++main.opt.p=\ -p <pkgname> -package <pkgname> \u6307\u5B9A\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n (\u8907\u6570\u56DE\u6307\u5B9A\u53EF\u80FD)
+
+-main.opt.e=\ -e <regex> -regex <regex> \u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n (-p\u3068-e\u306F\u6392\u4ED6\u7684)
++main.opt.e=\ -e <regex> -regex <regex> \u6307\u5B9A\u306E\u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n (-p\u3068-e\u306F\u6392\u4ED6\u7684)
+
+ main.opt.include=\ -include <regex> \u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u30AF\u30E9\u30B9\u306B\u5206\u6790\u3092\u5236\u9650\u3057\u307E\u3059\n \u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u5206\u6790\u5BFE\u8C61\u30AF\u30E9\u30B9\u306E\n \u30EA\u30B9\u30C8\u304C\u30D5\u30A3\u30EB\u30BF\u3055\u308C\u307E\u3059\u3002\u30D1\u30BF\u30FC\u30F3\u3092\u4F9D\u5B58\u6027\u306B\n \u9069\u7528\u3059\u308B-p\u304A\u3088\u3073-e\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3067\u304D\u307E\u3059
+
+@@ -23,7 +25,7 @@
+
+ main.opt.cp=\ -cp <path> -classpath <path> \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3057\u307E\u3059
+
+-main.opt.R=\ -R -recursive \u3059\u3079\u3066\u306E\u4F9D\u5B58\u6027\u3092\u53CD\u5FA9\u7684\u306B\u8D70\u67FB\u3057\u307E\u3059
++main.opt.R=\ -R -recursive \u3059\u3079\u3066\u306E\u4F9D\u5B58\u6027\u3092\u518D\u5E30\u7684\u306B\u30C8\u30E9\u30D0\u30FC\u30B9\u3057\u307E\u3059\u3002\n -R\u30AA\u30D7\u30B7\u30E7\u30F3\u306F-filter:none\u3092\u610F\u5473\u3057\u307E\u3059\u3002-p\u3001-e\u3001-f\n \u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u306E\u307F\n \u5206\u6790\u3055\u308C\u307E\u3059\u3002
+
+ main.opt.apionly=\ -apionly \u5206\u6790\u3092API\u3001\u3064\u307E\u308A\u3001\u30D1\u30D6\u30EA\u30C3\u30AF\u30FB\u30AF\u30E9\u30B9\u306E\n \u30D1\u30D6\u30EA\u30C3\u30AF\u30FB\u30E1\u30F3\u30D0\u30FC\u304A\u3088\u3073\u4FDD\u8B77\u3055\u308C\u305F\u30E1\u30F3\u30D0\u30FC\u306E\n \u7F72\u540D\u306B\u304A\u3051\u308B\u4F9D\u5B58\u6027(\u30D5\u30A3\u30FC\u30EB\u30C9\u30FB\u30BF\u30A4\u30D7\u3001\u30E1\u30BD\u30C3\u30C9\u30FB\n \u30D1\u30E9\u30E1\u30FC\u30BF\u30FB\u30BF\u30A4\u30D7\u3001\u623B\u3055\u308C\u305F\u30BF\u30A4\u30D7\u3001\u30C1\u30A7\u30C3\u30AF\u3055\u308C\u305F\n \u4F8B\u5916\u30BF\u30A4\u30D7\u306A\u3069)\u306B\u5236\u9650\u3057\u307E\u3059
+
+@@ -36,13 +38,14 @@
+
+ err.unknown.option=\u4E0D\u660E\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0}
+ err.missing.arg={0}\u306B\u5024\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093
+-err.internal.error=\u5185\u90E8\u30A8\u30E9\u30FC: {0} {1} {2}
+ err.invalid.arg.for.option=\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u304C\u7121\u52B9\u3067\u3059: {0}
+ err.option.after.class=\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u30AF\u30E9\u30B9\u306E\u524D\u306B\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059: {0}
+ err.option.unsupported={0}\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093: {1}
+ err.profiles.msg=\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u60C5\u5831\u304C\u3042\u308A\u307E\u305B\u3093
+-err.dot.output.path=\u7121\u52B9\u306A\u30D1\u30B9: {0}
++err.invalid.path=\u7121\u52B9\u306A\u30D1\u30B9: {0}
+ warn.invalid.arg=\u7121\u52B9\u306A\u30AF\u30E9\u30B9\u540D\u307E\u305F\u306F\u30D1\u30B9\u540D\u304C\u5B58\u5728\u3057\u307E\u305B\u3093: {0}
+ warn.split.package=\u30D1\u30C3\u30B1\u30FC\u30B8{0}\u306F{1} {2}\u3067\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u307E\u3059
++warn.replace.useJDKInternals=JDK\u5185\u90E8API\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u304A\u3089\u305A\u3001JDK\u5B9F\u88C5\u5C02\u7528\u3067\u3059\u304C\u3001\u4E92\u63DB\u6027\u306A\u3057\u3067\n\u524A\u9664\u307E\u305F\u306F\u5909\u66F4\u3055\u308C\u308B\u5834\u5408\u304C\u3042\u308A\u3001\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u3092\u4E2D\u65AD\u3055\u305B\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\nJDK\u5185\u90E8API\u306E\u4F9D\u5B58\u6027\u3092\u524A\u9664\u3059\u308B\u3088\u3046\u30B3\u30FC\u30C9\u3092\u5909\u66F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002\nJDK\u5185\u90E8API\u306E\u7F6E\u63DB\u306B\u95A2\u3059\u308B\u6700\u65B0\u306E\u66F4\u65B0\u306B\u3064\u3044\u3066\u306F\u3001\u6B21\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044:\n{0}
+
+ artifact.not.found=\u898B\u3064\u304B\u308A\u307E\u305B\u3093
++jdeps.wiki.url=https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
+--- ./langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps_zh_CN.properties Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps_zh_CN.properties Wed Feb 04 12:14:46 2015 -0800
+@@ -1,4 +1,4 @@
+-main.usage.summary=\u7528\u6CD5: {0} <options> <classes...>\n\u4F7F\u7528 -h, -? \u6216 --help \u5217\u51FA\u53EF\u80FD\u7684\u9009\u9879
++main.usage.summary=\u7528\u6CD5: {0} <options> <classes...>\n\u4F7F\u7528 -h, -? \u6216 -help \u5217\u51FA\u53EF\u80FD\u7684\u9009\u9879
+
+ main.usage=\u7528\u6CD5: {0} <options> <classes...>\n\u5176\u4E2D <classes> \u53EF\u4EE5\u662F .class \u6587\u4EF6, \u76EE\u5F55, JAR \u6587\u4EF6\u7684\u8DEF\u5F84\u540D,\n\u4E5F\u53EF\u4EE5\u662F\u5168\u9650\u5B9A\u7C7B\u540D\u3002\u53EF\u80FD\u7684\u9009\u9879\u5305\u62EC:
+
+@@ -9,13 +9,15 @@
+
+ main.opt.version=\ -version \u7248\u672C\u4FE1\u606F
+
+-main.opt.v=\ -v -verbose \u8F93\u51FA\u6240\u6709\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61\n -verbose:package \u8F93\u51FA\u7A0B\u5E8F\u5305\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \u4E0D\u5305\u62EC\n \u540C\u4E00\u6863\u6848\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n -verbose:class \u8F93\u51FA\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \u4E0D\u5305\u62EC\n \u540C\u4E00\u6863\u6848\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61
++main.opt.v=\ -v -verbose \u8F93\u51FA\u6240\u6709\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61\n \u7B49\u540C\u4E8E -verbose:class -filter:none\u3002\n -verbose:package \u9ED8\u8BA4\u60C5\u51B5\u4E0B\u8F93\u51FA\u7A0B\u5E8F\u5305\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \n \u4E0D\u5305\u62EC\u540C\u4E00\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n -verbose:class \u9ED8\u8BA4\u60C5\u51B5\u4E0B\u8F93\u51FA\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \n \u4E0D\u5305\u62EC\u540C\u4E00\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61
++
++main.opt.f=\ -f <regex> -filter <regex> \u7B5B\u9009\u4E0E\u6307\u5B9A\u6A21\u5F0F\u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n \u5982\u679C\u591A\u6B21\u6307\u5B9A, \u5219\u5C06\u4F7F\u7528\u6700\u540E\u4E00\u4E2A\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n -filter:package \u7B5B\u9009\u4F4D\u4E8E\u540C\u4E00\u7A0B\u5E8F\u5305\u5185\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61 (\u9ED8\u8BA4)\n -filter:archive \u7B5B\u9009\u4F4D\u4E8E\u540C\u4E00\u6863\u6848\u5185\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n -filter:none \u4E0D\u4F7F\u7528 -filter:package \u548C -filter:archive \u7B5B\u9009\n \u901A\u8FC7 -filter \u9009\u9879\u6307\u5B9A\u7684\u7B5B\u9009\u4ECD\u65E7\u9002\u7528\u3002
+
+ main.opt.s=\ -s -summary \u4EC5\u8F93\u51FA\u88AB\u4F9D\u8D56\u5BF9\u8C61\u6982\u8981
+
+-main.opt.p=\ -p <pkgname> -package <pkgname> \u67E5\u627E\u7ED9\u5B9A\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n (\u53EF\u80FD\u591A\u6B21\u6307\u5B9A)
++main.opt.p=\ -p <pkgname> -package <pkgname> \u67E5\u627E\u4E0E\u7ED9\u5B9A\u7A0B\u5E8F\u5305\u540D\u79F0\u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n (\u53EF\u591A\u6B21\u6307\u5B9A)
+
+-main.opt.e=\ -e <regex> -regex <regex> \u67E5\u627E\u4E0E\u6A21\u5F0F\u5339\u914D\u7684\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n (-p \u548C -e \u4E92\u76F8\u6392\u65A5)
++main.opt.e=\ -e <regex> -regex <regex> \u67E5\u627E\u4E0E\u6307\u5B9A\u6A21\u5F0F\u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n (-p \u548C -e \u4E92\u76F8\u6392\u65A5)
+
+ main.opt.include=\ -include <regex> \u5C06\u5206\u6790\u9650\u5236\u4E3A\u4E0E\u6A21\u5F0F\u5339\u914D\u7684\u7C7B\n \u6B64\u9009\u9879\u7B5B\u9009\u8981\u5206\u6790\u7684\u7C7B\u7684\u5217\u8868\u3002\n \u5B83\u53EF\u4EE5\u4E0E\u5411\u88AB\u4F9D\u8D56\u5BF9\u8C61\u5E94\u7528\u6A21\u5F0F\u7684\n -p \u548C -e \u7ED3\u5408\u4F7F\u7528
+
+@@ -23,7 +25,7 @@
+
+ main.opt.cp=\ -cp <path> -classpath <path> \u6307\u5B9A\u67E5\u627E\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E
+
+-main.opt.R=\ -R -recursive \u9012\u5F52\u904D\u5386\u6240\u6709\u88AB\u4F9D\u8D56\u5BF9\u8C61
++main.opt.R=\ -R -recursive \u9012\u5F52\u904D\u5386\u6240\u6709\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n -R \u9009\u9879\u8868\u793A -filter:none\u3002\u5982\u679C\u6307\u5B9A\u4E86 -p, -e, -f\n \u9009\u9879, \u5219\u53EA\u5206\u6790\u5339\u914D\u7684\n \u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002
+
+ main.opt.apionly=\ -apionly \u901A\u8FC7\u516C\u5171\u7C7B (\u5305\u62EC\u5B57\u6BB5\u7C7B\u578B, \u65B9\u6CD5\u53C2\u6570\n \u7C7B\u578B, \u8FD4\u56DE\u7C7B\u578B, \u53D7\u63A7\u5F02\u5E38\u9519\u8BEF\u7C7B\u578B\n \u7B49) \u7684\u516C\u5171\u548C\u53D7\u4FDD\u62A4\u6210\u5458\u7684\u7B7E\u540D\n \u9650\u5236\u5BF9 API (\u5373\u88AB\u4F9D\u8D56\u5BF9\u8C61)\n \u8FDB\u884C\u5206\u6790
+
+@@ -36,13 +38,14 @@
+
+ err.unknown.option=\u672A\u77E5\u9009\u9879: {0}
+ err.missing.arg=\u6CA1\u6709\u4E3A{0}\u6307\u5B9A\u503C
+-err.internal.error=\u5185\u90E8\u9519\u8BEF: {0} {1} {2}
+ err.invalid.arg.for.option=\u9009\u9879\u7684\u53C2\u6570\u65E0\u6548: {0}
+ err.option.after.class=\u5FC5\u987B\u5728\u7C7B\u4E4B\u524D\u6307\u5B9A\u9009\u9879: {0}
+ err.option.unsupported=\u4E0D\u652F\u6301{0}: {1}
+ err.profiles.msg=\u6CA1\u6709\u914D\u7F6E\u6587\u4EF6\u4FE1\u606F
+-err.dot.output.path=\u65E0\u6548\u8DEF\u5F84: {0}
++err.invalid.path=\u65E0\u6548\u8DEF\u5F84: {0}
+ warn.invalid.arg=\u7C7B\u540D\u65E0\u6548\u6216\u8DEF\u5F84\u540D\u4E0D\u5B58\u5728: {0}
+ warn.split.package=\u5DF2\u5728{1} {2}\u4E2D\u5B9A\u4E49\u7A0B\u5E8F\u5305{0}
++warn.replace.useJDKInternals=\u4E0D\u652F\u6301 JDK \u5185\u90E8 API, \u5B83\u4EEC\u4E13\u7528\u4E8E\u901A\u8FC7\u4E0D\u517C\u5BB9\u65B9\u5F0F\u6765\u5220\u9664\n\u6216\u66F4\u6539\u7684 JDK \u5B9E\u73B0, \u53EF\u80FD\u4F1A\u635F\u574F\u60A8\u7684\u5E94\u7528\u7A0B\u5E8F\u3002\n\u8BF7\u4FEE\u6539\u60A8\u7684\u4EE3\u7801, \u6D88\u9664\u4E0E\u4EFB\u4F55 JDK \u5185\u90E8 API \u7684\u76F8\u5173\u6027\u3002\n\u6709\u5173 JDK \u5185\u90E8 API \u66FF\u6362\u7684\u6700\u65B0\u66F4\u65B0, \u8BF7\u67E5\u770B:\n{0}
+
+ artifact.not.found=\u627E\u4E0D\u5230
++jdeps.wiki.url=https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/src/share/classes/com/sun/tools/jdeps/resources/jdkinternals.properties Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,22 @@
++// No translation needed
++com.sun.crypto.provider.SunJCE=Use java.security.Security.getProvider(provider-name) @since 1.3
++com.sun.image.codec=Use javax.imageio @since 1.4
++com.sun.org.apache.xml.internal.security=Use java.xml.crypto @since 1.6
++com.sun.org.apache.xml.internal.security.utils.Base64=Use java.util.Base64 @since 1.8
++com.sun.net.ssl=Use javax.net.ssl @since 1.4
++com.sun.net.ssl.internal.ssl.Provider=Use java.security.Security.getProvider(provider-name) @since 1.3
++com.sun.rowset=Use javax.sql.rowset.RowSetProvider @since 1.7
++com.sun.tools.javac.tree=Use com.sun.source @since 1.6
++com.sun.tools.javac=Use javax.tools and javax.lang.model @since 1.6
++sun.awt.image.codec=Use javax.imageio @since 1.4
++sun.misc.BASE64Encoder=Use java.util.Base64 @since 1.8
++sun.misc.BASE64Decoder=Use java.util.Base64 @since 1.8
++sun.misc.Cleaner=Use java.lang.ref.PhantomReference @since 1.2
++sun.misc.Service=Use java.util.ServiceLoader @since 1.6
++sun.security.action=Use java.security.PrivilegedAction @since 1.1
++sun.security.krb5=Use com.sun.security.jgss
++sun.security.provider.PolicyFile=Use java.security.Policy.getInstance("JavaPolicy", new URIParameter(uri)) @since 1.6
++sun.security.provider.Sun=Use java.security.Security.getProvider(provider-name) @since 1.3
++sun.security.util.SecurityConstants=Use appropriate java.security.Permission subclass @since 1.1
++sun.security.x509.X500Name=Use javax.security.auth.x500.X500Principal @since 1.4
++sun.tools.jar=Use java.util.jar or jar tool @since 1.2
+--- ./langtools/test/com/sun/javadoc/testDocRootLink/TestDocRootLink.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/test/com/sun/javadoc/testDocRootLink/TestDocRootLink.java Wed Feb 04 12:14:46 2015 -0800
+@@ -60,21 +60,21 @@
+ };
+ private static final String[][] NEGATED_TEST1 = {
+ {BUG_ID + FS + "pkg1" + FS + "C1.html",
+- "<a href=\"http://download.oracle.com/javase/7/docs/technotes/guides/index.html\">"
++ "<a href=\"https://docs.oracle.com/javase/7/docs/technotes/guides/index.html\">"
+ },
+ {BUG_ID + FS + "pkg1" + FS + "C1.html",
+- "<a href=\"http://download.oracle.com/javase/7/docs/pkg2/C2.html\">"
++ "<a href=\"https://docs.oracle.com/javase/7/docs/pkg2/C2.html\">"
+ },
+ {BUG_ID + FS + "pkg1" + FS + "package-summary.html",
+- "<a href=\"http://download.oracle.com/javase/7/docs/technotes/guides/index.html\">"
++ "<a href=\"https://docs.oracle.com/javase/7/docs/technotes/guides/index.html\">"
+ },
+ {BUG_ID + FS + "pkg1" + FS + "package-summary.html",
+- "<a href=\"http://download.oracle.com/javase/7/docs/pkg2/C2.html\">"
++ "<a href=\"https://docs.oracle.com/javase/7/docs/pkg2/C2.html\">"
+ }
+ };
+ private static final String[][] TEST2 = {
+ {BUG_ID + "-1" + FS + "pkg2" + FS + "C2.html",
+- "Refer <a href=\"http://download.oracle.com/javase/7/docs/technotes/guides/index.html\">Here</a>"
++ "Refer <a href=\"https://docs.oracle.com/javase/7/docs/technotes/guides/index.html\">Here</a>"
+ },
+ {BUG_ID + "-1" + FS + "pkg2" + FS + "C2.html",
+ "This <a href=\"../pkg1/C1.html\">Here</a> should not be replaced" + NL +
+@@ -85,7 +85,7 @@
+ " <a href=\"../pkg1/C1.html\">Link 2</a>."
+ },
+ {BUG_ID + "-1" + FS + "pkg2" + FS + "package-summary.html",
+- "<a href=\"http://download.oracle.com/javase/7/docs/technotes/guides/index.html\">" + NL +
++ "<a href=\"https://docs.oracle.com/javase/7/docs/technotes/guides/index.html\">" + NL +
+ " Test document 1</a>"
+ },
+ {BUG_ID + "-1" + FS + "pkg2" + FS + "package-summary.html",
+@@ -100,13 +100,13 @@
+ "<a href=\"../../technotes/guides/index.html\">"
+ },
+ {BUG_ID + "-1" + FS + "pkg2" + FS + "C2.html",
+- "<a href=\"http://download.oracle.com/javase/7/docs/pkg1/C1.html\">"
++ "<a href=\"https://docs.oracle.com/javase/7/docs/pkg1/C1.html\">"
+ },
+ {BUG_ID + "-1" + FS + "pkg2" + FS + "package-summary.html",
+ "<a href=\"../../technotes/guides/index.html\">"
+ },
+ {BUG_ID + "-1" + FS + "pkg2" + FS + "package-summary.html",
+- "<a href=\"http://download.oracle.com/javase/7/docs/pkg1/C1.html\">"
++ "<a href=\"https://docs.oracle.com/javase/7/docs/pkg1/C1.html\">"
+ }
+ };
+ private static final String[] ARGS1 =
+@@ -115,7 +115,7 @@
+ };
+ private static final String[] ARGS2 =
+ new String[]{
+- "-d", BUG_ID + "-1", "-Xdocrootparent", "http://download.oracle.com/javase/7/docs", "-sourcepath", SRC_DIR, "pkg1", "pkg2"
++ "-d", BUG_ID + "-1", "-Xdocrootparent", "https://docs.oracle.com/javase/7/docs", "-sourcepath", SRC_DIR, "pkg1", "pkg2"
+ };
+
+ /**
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/8062359/UnresolvableClassNPEInAttrTest.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,17 @@
++/*
++ * @test /nodynamiccopyright/
++ * @bug 8062359
++ * @summary NullPointerException in Attr when type-annotating an anonymous
++ * inner class in an unresolvable class
++ * @compile/fail/ref=UnresolvableClassNPEInAttrTest.out -XDrawDiagnostics UnresolvableClassNPEInAttrTest.java
++ */
++
++public class UnresolvableClassNPEInAttrTest {
++ public static void main(String[] args) {
++ new Undefined() {
++ void test() {
++ new Object() {};
++ }
++ };
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/8062359/UnresolvableClassNPEInAttrTest.out Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,2 @@
++UnresolvableClassNPEInAttrTest.java:11:13: compiler.err.cant.resolve.location: kindname.class, Undefined, , , (compiler.misc.location: kindname.class, UnresolvableClassNPEInAttrTest, null)
++1 error
+--- ./langtools/test/tools/javac/T8019486/WrongLNTForLambdaTest.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/test/tools/javac/T8019486/WrongLNTForLambdaTest.java Wed Feb 04 12:14:46 2015 -0800
+@@ -138,7 +138,7 @@
+ checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
+ "Foo.class").toUri()), "$deserializeLambda$", deserializeExpectedLNT);
+ checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
+- "Foo.class").toUri()), "lambda$MR$variablesInLambdas$notify$8bc4f5bd$1", lambdaBridgeExpectedLNT);
++ "Foo.class").toUri()), "lambda$variablesInLambdas$3", lambdaBridgeExpectedLNT);
+ checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
+ "Foo.class").toUri()), "assignLambda", assignmentExpectedLNT);
+ checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/T8050386/WrongStackframeGenerationTest1.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8050386
++ * @summary Verification error due to a bad stackmap frame generated by javac
++ */
++
++public class WrongStackframeGenerationTest1 {
++ public static void main(String[] args) {}
++
++ static void foo(){
++ while (true) {
++ int i = 0;
++ break;
++ }
++ switch (1) {
++ case 1:
++ int j = 0;
++ case 2:
++ bar();
++ }
++ }
++
++ static void bar() {}
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/T8050386/WrongStackframeGenerationTest2.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,50 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8050386
++ * @summary Verification error due to a bad stackmap frame generated by javac
++ */
++
++public class WrongStackframeGenerationTest2 {
++ public static void main(String[] args) {}
++
++ static void foo() {
++ int len;
++ for (;;) {
++ try {
++ len = 1;
++ break;
++ } catch (Exception e) {
++ }
++ }
++
++ try {
++ if (len == -1) {
++ len = 0;
++ }
++ } finally {
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/T8059921/ForbidAccessToFieldUsingSuperTest.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,31 @@
++/*
++ * @test /nodynamiccopyright/
++ * @bug 8059921
++ * @summary Missing compile error in Java 8 mode for Interface.super.field access
++ * @compile/fail/ref=ForbidAccessToFieldUsingSuperTest.out -XDrawDiagnostics ForbidAccessToFieldUsingSuperTest.java
++ */
++
++public class ForbidAccessToFieldUsingSuperTest {
++ class C {
++ int m() { return 0; }
++ }
++
++ interface T {
++ int f = 0;
++ C c = null;
++ default int mm() {
++ return 0;
++ }
++ }
++
++ interface T1 extends T {}
++
++ class X implements T1 {
++ int i = T1.super.f; //fail
++ int j = T1.super.c.m(); //fail
++
++ void foo(Runnable r) {
++ foo(T1.super::mm); //should'n fail
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/T8059921/ForbidAccessToFieldUsingSuperTest.out Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,3 @@
++ForbidAccessToFieldUsingSuperTest.java:24:19: compiler.err.not.encl.class: ForbidAccessToFieldUsingSuperTest.T1
++ForbidAccessToFieldUsingSuperTest.java:25:19: compiler.err.not.encl.class: ForbidAccessToFieldUsingSuperTest.T1
++2 errors
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/annotations/FinalStringInNested.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,46 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8054448
++ * @summary Verify that constant strings in nested classes in anonymous classes
++ * can be used in annotations.
++ * @compile FinalStringInNested.java
++ */
++
++public class FinalStringInNested {
++
++ public void f() {
++ Object o = new Object() {
++ @FinalStringInNested.Annotation(Nested.ID)
++ class Nested {
++ static final String ID = "B";
++ }
++ };
++ }
++
++ @interface Annotation {
++ String value();
++ }
++}
+--- ./langtools/test/tools/javac/flow/LVTHarness.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/test/tools/javac/flow/LVTHarness.java Wed Feb 04 12:14:46 2015 -0800
+@@ -23,7 +23,7 @@
+
+ /*
+ * @test
+- * @bug 7047734 8027660 8037937
++ * @bug 7047734 8027660 8037937 8047719 8058708
+ * @summary The LVT is not generated correctly during some try/catch scenarios
+ * javac crash while creating LVT entry for a local variable defined in
+ * an inner block
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/flow/T8042741/LambdaArgumentsTest.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,44 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/* @test
++ * @bug 8054210
++ * @summary NullPointerException when compiling specific code
++ * @compile LambdaArgumentsTest.java
++ */
++
++public class LambdaArgumentsTest {
++ interface Thrower<E extends Exception> { void apply() throws E; }
++ interface Consumer<E> { void take(E arg); }
++
++ <E extends Exception>
++ void m1(Thrower<E> a1, Consumer<E> a2) {}
++
++ <E extends Exception>
++ void m2(Thrower<E> a1, Consumer<RuntimeException> a2) {}
++
++ void test() {
++ m1(() -> {}, e -> {});
++ m2(() -> {}, (RuntimeException e) -> {});
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/flow/T8062747.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,24 @@
++/**
++ * @test
++ * @bug 8062747
++ * @summary Avoiding an error for lambdas with thrown types inference inside an anonymous class.
++ * @compile T8062747.java
++ */
++public class T8062747 {
++
++ public interface Throwing<Y extends Exception> {
++ void canThrow() throws Y;
++ }
++
++ public static <Y extends Exception> void wrap(Throwing<Y> action) {
++ }
++
++ public static void invoke(String a) {
++ Runnable r = new Runnable() {
++ @Override
++ public void run() {
++ wrap(() -> System.out.println(a));
++ }
++ };
++ }
++}
+--- ./langtools/test/tools/javac/flow/tests/TestCaseIf.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/test/tools/javac/flow/tests/TestCaseIf.java Wed Feb 04 12:14:46 2015 -0800
+@@ -58,4 +58,18 @@
+ }
+ o = "";
+ }
++
++ @AliveRange(varName="finalLocal", bytecodeStart=11, bytecodeLength=6)
++ @AliveRange(varName="used", bytecodeStart=13, bytecodeLength=4)
++ void m5(Object o) {
++ if (o != null) {
++ Object notUsed;
++ Object used;
++ if (o != null) {
++ final Object finalLocal = null;
++ used = null;
++ if (o == null) {}
++ }
++ }
++ }
+ }
+--- ./langtools/test/tools/javac/flow/tests/TestCaseSwitch.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/test/tools/javac/flow/tests/TestCaseSwitch.java Wed Feb 04 12:14:46 2015 -0800
+@@ -5,7 +5,7 @@
+ @AliveRange(varName="o", bytecodeStart=31, bytecodeLength=16)
+ @AliveRange(varName="o", bytecodeStart=50, bytecodeLength=15)
+ @AliveRange(varName="o", bytecodeStart=68, bytecodeLength=1)
+- @AliveRange(varName="oo", bytecodeStart=39, bytecodeLength=26)
++ @AliveRange(varName="oo", bytecodeStart=39, bytecodeLength=8)
+ @AliveRange(varName="uu", bytecodeStart=59, bytecodeLength=6)
+ void m1(String[] args) {
+ Object o;
+@@ -29,7 +29,7 @@
+ @AliveRange(varName="o", bytecodeStart=95, bytecodeLength=18)
+ @AliveRange(varName="o", bytecodeStart=116, bytecodeLength=15)
+ @AliveRange(varName="o", bytecodeStart=134, bytecodeLength=1)
+- @AliveRange(varName="oo", bytecodeStart=104, bytecodeLength=27)
++ @AliveRange(varName="oo", bytecodeStart=104, bytecodeLength=9)
+ @AliveRange(varName="uu", bytecodeStart=125, bytecodeLength=6)
+ void m2(String[] args) {
+ Object o;
+@@ -50,12 +50,14 @@
+ o = "return";
+ }
+
+- @AliveRange(varName="o", bytecodeStart=31, bytecodeLength=8)
+- @AliveRange(varName="o", bytecodeStart=42, bytecodeLength=8)
+- @AliveRange(varName="o", bytecodeStart=53, bytecodeLength=9)
+- void m3(String[] args) {
++ @AliveRange(varName="o", bytecodeStart=35, bytecodeLength=8)
++ @AliveRange(varName="o", bytecodeStart=46, bytecodeLength=8)
++ @AliveRange(varName="o", bytecodeStart=78, bytecodeLength=5)
++ @AliveRange(varName="o", bytecodeStart=86, bytecodeLength=1)
++ @AliveRange(varName="oo", bytecodeStart=56, bytecodeLength=16)
++ void m3(int i) {
+ Object o;
+- switch (args.length) {
++ switch (i) {
+ case 0:
+ o = "0";
+ o.hashCode();
+@@ -64,10 +66,19 @@
+ o = "1";
+ o.hashCode();
+ break;
++ case 2:
++ int oo = i;
++ if (oo > 1) {
++ System.out.println("greater");
++ }
++ break;
++ case 3:
++ int uu = i;
+ default:
+ o = "default";
+ o.hashCode();
+ }
+ o = "finish";
+ }
++
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/generics/inference/8043926/T8043926.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8043926
++ * @summary javac, code valid in 7 is not compiling for 8
++ * @compile T8043926.java
++ */
++class T8043926 {
++ interface Iface<T1> {}
++
++ static class Impl implements Iface<Impl> {}
++
++ static class Acceptor<T2 extends Iface<T2>> {
++ public Acceptor(T2 obj) {}
++ }
++
++ void test(Impl impl) {
++ Acceptor<?> acceptor1 = new Acceptor<>(impl);
++ Acceptor<? extends Object> acceptor2 = new Acceptor<>(impl);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/generics/inference/8058511/T8058511a.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.
++ */
++
++/**
++ * @test
++ * @bug 8058511
++ * @summary StackOverflowError at com.sun.tools.javac.code.Types.lub
++ * @compile T8058511a.java
++ */
++class T8058511a {
++ <Z> void choose(Z z1, Z z2) { }
++
++ void test(Class<Double> cd, Class<? extends double[]> cdarr) {
++ choose(cd, cdarr);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/generics/inference/8058511/T8058511b.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.
++ */
++
++/**
++ * @test
++ * @bug 8058511
++ * @summary StackOverflowError at com.sun.tools.javac.code.Types.lub
++ * @compile T8058511b.java
++ */
++class T8058511b {
++ void test(Class<Double> cd, Class<? extends double[]> cdarr) {
++ ((false) ? cd : cdarr).toString();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/generics/inference/8058511/T8058511c.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.
++ */
++
++/**
++ * @test
++ * @bug 8058511
++ * @summary StackOverflowError at com.sun.tools.javac.code.Types.lub
++ * @compile T8058511c.java
++ */
++import java.util.List;
++
++class T8058511c {
++ void test(List<? extends double[]> l) {
++ (true ? l.get(0) : l.get(0)).toString();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/generics/inference/T8044546/CrashImplicitLambdaTest.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8044546
++ * @summary Crash on faulty reduce/lambda
++ * @compile CrashImplicitLambdaTest.java
++ */
++
++abstract class CrashImplicitLambdaTest {
++ boolean foo() {
++ return bar(true, a -> {});
++ }
++
++ abstract <T1> T1 bar(T1 t1, S<T1> s);
++
++ interface S<S1> {
++ void baz(S1 s1);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/generics/inference/T8044546/NestedInvocationsTest.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8044546
++ * @summary Crash on faulty reduce/lambda
++ * @compile NestedInvocationsTest.java
++ */
++
++class NestedInvocationsTest<T> {
++ boolean foo(I<T> i) {
++ return baz(zas(i));
++ }
++
++ <U> J<U, Boolean> zas(I<U> i) {
++ return null;
++ }
++
++ <R> R baz(J<T, R> j) {
++ return null;
++ }
++
++ interface I<I1> {}
++
++ interface J<J1, J2> {}
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/generics/wildcards/T8051402/WildcardAndCAPSubtypeTest.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,40 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8051402
++ * @summary javac, type containment should accept that CAP <= ? extends CAP and CAP <= ? super CAP
++ * @compile WildcardAndCAPSubtypeTest.java
++ */
++
++import java.util.List;
++
++public abstract class WildcardAndCAPSubtypeTest {
++ abstract <T> List<T> copyOf(List<? extends T> lx);
++ abstract <E> List<E> filter(List<E> lx);
++
++ void g(List<?> lx) {
++ copyOf(filter(lx));
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/8051958/T8051958.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,71 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.
++ */
++
++/*
++ * @test
++ * @bug 8051958
++ * @summary Cannot assign a value to final variable in lambda
++ * @compile T8051958.java
++ */
++
++class T8051958 {
++ Runnable inst_r = ()-> {
++ final int x;
++ x = 1;
++ };
++
++ Runnable static_r = ()-> {
++ final int x;
++ x = 1;
++ };
++
++ {
++ Runnable inst_r = ()-> {
++ final int x;
++ x = 1;
++ };
++ }
++
++ static {
++ Runnable static_r = ()-> {
++ final int x;
++ x = 1;
++ };
++ }
++
++ void instTest() {
++ Runnable static_r = ()-> {
++ final int x;
++ x = 1;
++ };
++ }
++
++ static void staticTest() {
++ Runnable static_r = ()-> {
++ final int x;
++ x = 1;
++ };
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/LambdaTestStrictFP.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8046060
++ * @summary Different results of floating point multiplication for lambda code block
++ */
++
++strictfp
++public class LambdaTestStrictFP {
++
++ static double fld = eval(() -> {
++ double x = Double.longBitsToDouble(0x1e7ee00000000000L);
++ double y = Double.longBitsToDouble(0x2180101010101010L);
++
++ return x * y;
++ });
++
++ public static void main(String args[]) {
++ double result = eval(() -> {
++ double x = Double.longBitsToDouble(0x1e7ee00000000000L);
++ double y = Double.longBitsToDouble(0x2180101010101010L);
++
++ return x * y;
++ });
++ {
++ double x = Double.longBitsToDouble(0x1e7ee00000000000L);
++ double y = Double.longBitsToDouble(0x2180101010101010L);
++
++ double z = x * y;
++ check(z, result, "method");
++ check(z, fld, "field");
++ }
++ }
++
++ private static void check(double expected, double got, String where) {
++ if (got != expected) {
++ throw new AssertionError(where + ": Non-strictfp " + got + " != " + expected);
++ }
++ }
++
++ private static double eval(Face arg) {
++ return arg.m();
++ }
++
++ private interface Face {
++ double m();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/LambdaTestStrictFPFlag.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,76 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8046060
++ * @summary Different results of floating point multiplication for lambda code block
++ */
++
++import java.io.*;
++import java.net.URL;
++import com.sun.tools.classfile.*;
++import static com.sun.tools.classfile.AccessFlags.ACC_STRICT;
++
++public class LambdaTestStrictFPFlag {
++ public static void main(String[] args) throws Exception {
++ new LambdaTestStrictFPFlag().run();
++ }
++
++ void run() throws Exception {
++ ClassFile cf = getClassFile("LambdaTestStrictFPFlag$Test.class");
++ ConstantPool cp = cf.constant_pool;
++ boolean found = false;
++ for (Method meth: cf.methods) {
++ if (meth.getName(cp).startsWith("lambda$")) {
++ if ((meth.access_flags.flags & ACC_STRICT) == 0) {
++ throw new Exception("strict flag missing from lambda");
++ }
++ found = true;
++ }
++ }
++ if (!found) {
++ throw new Exception("did not find lambda method");
++ }
++ }
++
++ ClassFile getClassFile(String name) throws IOException, ConstantPoolException {
++ URL url = getClass().getResource(name);
++ InputStream in = url.openStream();
++ try {
++ return ClassFile.read(in);
++ } finally {
++ in.close();
++ }
++ }
++
++ class Test {
++ strictfp void test() {
++ Face itf = () -> { };
++ }
++ }
++
++ interface Face {
++ void m();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/LambdaTestStrictFPMethod.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,65 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8046060
++ * @summary Different results of floating point multiplication for lambda code block
++ */
++
++public class LambdaTestStrictFPMethod {
++
++ public static void main(String args[]) {
++ new LambdaTestStrictFPMethod().test();
++ }
++
++ strictfp void test() {
++ double result = eval(() -> {
++ double x = Double.longBitsToDouble(0x1e7ee00000000000L);
++ double y = Double.longBitsToDouble(0x2180101010101010L);
++
++ return x * y;
++ });
++ {
++ double x = Double.longBitsToDouble(0x1e7ee00000000000L);
++ double y = Double.longBitsToDouble(0x2180101010101010L);
++
++ double z = x * y;
++ check(z, result, "method");
++ }
++ }
++
++ strictfp void check(double expected, double got, String where) {
++ if (got != expected) {
++ throw new AssertionError(where + ": Non-strictfp " + got + " != " + expected);
++ }
++ }
++
++ static double eval(Face arg) {
++ return arg.m();
++ }
++
++ interface Face {
++ double m();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/MethodReferenceArrayClone.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,67 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8056051
++ * @summary int[]::clone causes "java.lang.NoClassDefFoundError: Array"
++ * @run main MethodReferenceArrayClone
++ */
++
++import java.util.Arrays;
++import java.util.function.Function;
++import java.util.function.Supplier;
++
++public class MethodReferenceArrayClone {
++ public static void main(String[] args) {
++ int[] intArgs = new int[] {1, 2, 3, 4, 5};
++ checkInt("int[]::clone", int[]::clone, intArgs);
++ checkInt("a -> a.clone()", a -> a.clone(), intArgs);
++ checkInt("intArgs::clone", intArgs::clone, intArgs);
++
++ String[] stringArgs = new String[] {"hi", "de", "ho"};
++ checkString("String[]::clone", String[]::clone, stringArgs);
++ checkString("a -> a.clone()", a -> a.clone(), stringArgs);
++ checkString("args::clone", stringArgs::clone, stringArgs);
++ }
++
++ private static void checkInt(String label, Supplier<int[]> s, int[] expected) {
++ if (!Arrays.equals(s.get(), expected)) {
++ throw new RuntimeException("Unexpected value " + label + ": " + Arrays.toString(s.get()));
++ }
++ }
++
++ private static void checkInt(String label, Function<int[], int[]> f, int[] a) {
++ checkInt(label, () -> f.apply(a), a);
++ }
++
++ private static void checkString(String label, Supplier<String[]> s, String[] expected) {
++ if (!Arrays.equals(s.get(), expected)) {
++ throw new RuntimeException("Unexpected value " + label + ": " + Arrays.toString(s.get()));
++ }
++ }
++
++ private static void checkString(String label, Function<String[], String[]> f, String[] a) {
++ checkString(label, () -> f.apply(a), a);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest1.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,31 @@
++/*
++ * @test /nodynamiccopyright/
++ * @bug 8033483
++ * @summary Should ignore nested lambda bodies during overload resolution
++ * @compile/fail/ref=IgnoreLambdaBodyDuringResolutionTest1.out -XDrawDiagnostics IgnoreLambdaBodyDuringResolutionTest1.java
++ */
++
++class IgnoreLambdaBodyDuringResolutionTest1 {
++ interface SAM<T> {
++ T action(T t);
++ }
++
++ <T> T m(SAM<T> op) {
++ return null;
++ }
++
++ class B {
++ B x() {
++ return this;
++ }
++ }
++
++ class C {}
++
++ void foo(B arg) {}
++ void foo(C arg) {}
++
++ void bar() {
++ foo(m(arg -> new B()));
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest1.out Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,2 @@
++IgnoreLambdaBodyDuringResolutionTest1.java:29:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(IgnoreLambdaBodyDuringResolutionTest1.B), IgnoreLambdaBodyDuringResolutionTest1, kindname.method, foo(IgnoreLambdaBodyDuringResolutionTest1.C), IgnoreLambdaBodyDuringResolutionTest1
++1 error
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest2.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,34 @@
++/*
++ * @test /nodynamiccopyright/
++ * @bug 8033483
++ * @summary Should ignore nested lambda bodies during overload resolution
++ * @compile/fail/ref=IgnoreLambdaBodyDuringResolutionTest2.out -XDrawDiagnostics IgnoreLambdaBodyDuringResolutionTest2.java
++ */
++
++class IgnoreLambdaBodyDuringResolutionTest2 {
++ interface SAM<S> {
++ boolean test(S t);
++ }
++
++ <I, T extends I> I bar(final T l) {
++ return null;
++ }
++
++ class D<D1, D2> {
++ void foo() {
++ m(bar(e -> false));
++ }
++
++ void m(Class<D1> arg) {}
++ void m(SAM<D2> arg) {}
++ }
++
++ class F {
++ void foo() {
++ m(bar((String e) -> false));
++ }
++
++ <F1> void m(Class<F1> arg) {}
++ <F2> void m(SAM<F2> arg) {}
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest2.out Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,6 @@
++IgnoreLambdaBodyDuringResolutionTest2.java:19:13: compiler.err.ref.ambiguous: m, kindname.method, m(java.lang.Class<D1>), IgnoreLambdaBodyDuringResolutionTest2.D, kindname.method, m(IgnoreLambdaBodyDuringResolutionTest2.SAM<D2>), IgnoreLambdaBodyDuringResolutionTest2.D
++IgnoreLambdaBodyDuringResolutionTest2.java:19:18: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Object))
++IgnoreLambdaBodyDuringResolutionTest2.java:19:14: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Class<D1>, <any>, kindname.class, IgnoreLambdaBodyDuringResolutionTest2.D<D1,D2>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Class)))
++IgnoreLambdaBodyDuringResolutionTest2.java:28:13: compiler.err.ref.ambiguous: m, kindname.method, <F1>m(java.lang.Class<F1>), IgnoreLambdaBodyDuringResolutionTest2.F, kindname.method, <F2>m(IgnoreLambdaBodyDuringResolutionTest2.SAM<F2>), IgnoreLambdaBodyDuringResolutionTest2.F
++IgnoreLambdaBodyDuringResolutionTest2.java:28:14: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Class))
++5 errors
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/T8056014.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8056014
++ * @summary Verify that full type inference is used when calling a method on a type variable.
++ * @compile T8056014.java
++ * @run main T8056014
++ */
++
++import java.util.*;
++
++public class T8056014 {
++ public static void main(String[] args) {
++ new T8056014().run();
++ }
++
++ void run() {
++ List<S> l = Arrays.asList(new S());
++ C<S> c = new C<>(new S());
++ foo(l.get(0).copy(1));
++ foo(c.get(0).copy(1));
++ }
++
++ void foo(S d) {
++ }
++}
++
++class B {
++ public B copy(long j) {
++ throw new AssertionError("Should not get here.");
++ }
++}
++
++class S extends B {
++ public <T> T copy(int i) {
++ return null;
++ }
++}
++
++class C<T extends B> {
++ final T t;
++ public C(T t) {
++ this.t = t;
++ }
++ public T get(int i) {
++ return t;
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/T8056984.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8056984
++ * @summary Ensure that method resolution runs over a captured type variables when checking if
++ * deferred attribution is needed
++ * @compile T8056984.java
++ */
++class T8056984<T1 extends B&C, T2 extends T1> {
++ public T8056984(T1 t1, T2 t2) {
++ System.err.println(t1.hashCode());
++ System.err.println(t2.hashCode());
++ }
++}
++class B {
++}
++interface C {
++ public int hashCode();
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/T8057794.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,12 @@
++/**
++ * @test /nodynamiccopyright/
++ * @bug 8057794
++ * @summary The tree for TypeVar.class does not have a type set, which leads to an NPE when
++ * checking if deferred attribution is needed
++ * @compile/fail/ref=T8057794.out -XDrawDiagnostics T8057794.java
++ */
++class T8057794<T> {
++ void t() {
++ System.out.println(T.class.getSimpleName());
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/T8057794.out Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,2 @@
++T8057794.java:10:29: compiler.err.type.var.cant.be.deref
++1 error
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/T8057800/NPEMethodReferenceAndGenericsTest.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,39 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.
++ */
++
++/**
++ * @test
++ * @bug 8057800
++ * @summary Method reference with generic type creates NPE when compiling
++ * @compile NPEMethodReferenceAndGenericsTest.java
++ */
++
++public class NPEMethodReferenceAndGenericsTest {
++ public <T> void foo(java.util.Comparator<? super T> comparator) {}
++
++ public <C extends Comparable<? super C>> void foo() {
++ foo(C::compareTo);
++ }
++}
+--- ./langtools/test/tools/javac/lambda/TargetType61.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/test/tools/javac/lambda/TargetType61.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -23,7 +23,7 @@
+
+ /*
+ * @test
+- * @bug 8007464
++ * @bug 8007464 8051402
+ * @summary Add graph inference support
+ * check that new wildcards inference strategy doesn't run into 7190296
+ * @compile TargetType61.java
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/methodReference/MethodRef8.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8063052
++ * @summary Inference chokes on wildcard derived from method reference
++ * @compile MethodRef8.java
++ */
++
++public class MethodRef8 {
++ void test(Box<? extends Box<? extends Number>> b) {
++ Number n1 = b.map(Box::get).get();
++ Number n2 = b.<Number>map(Box::get).get();
++ }
++
++ interface Func<S,T> { T apply(S arg); }
++
++ interface Box<T> {
++ T get();
++ <R> Box<R> map(Func<T,R> f);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/methodReference/MethodRefNewInnerBootstrap.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,72 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8044748
++ * @summary JVM cannot access constructor though ::new reference although can call it directly
++ */
++
++public class MethodRefNewInnerBootstrap {
++
++ interface Constructor {
++ public MyTest execute(int i);
++ }
++
++ public class MyTest {
++ public MyTest(int i) { System.out.println("Constructor executed " + i); }
++ }
++
++ public Constructor getConstructor() {
++ return MyTest::new;
++ }
++
++ public static void main(String argv[]) {
++ new MethodRefNewInnerBootstrap().call();
++ }
++
++ public void call() {
++ MyTest mt = new MyTest(0);
++
++ Constructor c1 = MyTest::new;
++ c1.execute(1);
++
++ Constructor c2 = getConstructor();
++ c2.execute(2);
++
++ Constructor c3 = new Constructor() {
++ public MyTest execute(int i) {
++ return new MyTest(3);
++ }
++ };
++ c3.execute(3);
++
++ Constructor c4 = new Constructor() {
++ public MyTest execute(int i) {
++ Constructor c = MyTest::new;
++ return c.execute(i);
++ }
++ };
++ c4.execute(4);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/methodReference/MethodRefNewInnerInLambdaNPE1.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8037404
++ * @summary javac NPE or VerifyError for code with constructor reference of inner class
++ */
++
++import java.util.function.Supplier;
++import java.util.stream.Stream;
++
++public class MethodRefNewInnerInLambdaNPE1 {
++ public static void main(String[] args) {
++ if (new MethodRefNewInnerInLambdaNPE1().getList().get().getClass() != TT.class)
++ throw new AssertionError("sanity failed");
++ }
++
++ Supplier<TT> getList() {
++ return () -> Stream.of(1).map(TT::new).findFirst().get();
++ }
++
++ class TT {
++ public TT(int i) {
++
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/methodReference/MethodRefNewInnerInLambdaNPE2.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,57 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8044737
++ * @summary Lambda: NPE while obtaining method reference through lambda expression
++ * @compile MethodRefNewInnerInLambdaNPE2.java
++ */
++
++public class MethodRefNewInnerInLambdaNPE2 {
++
++ interface Constructor {
++ MyTest execute();
++ }
++
++ class MyTest {
++ MyTest() { System.out.println("Constructor executed"); }
++ }
++
++ public Constructor getConstructor() {
++ return getConstructor(() -> { return MyTest::new; });
++ }
++
++ public static void main(String argv[]) {
++ MethodRefNewInnerInLambdaNPE2 t = new MethodRefNewInnerInLambdaNPE2();
++ MyTest mytest = t.getConstructor().execute();
++ }
++
++ Constructor getConstructor(Wrapper arg) {
++ return arg.unwrap();
++ }
++
++ interface Wrapper {
++ Constructor unwrap();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/methodReference/MethodRefNewInnerInLambdaVerify1.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8037404
++ * @summary javac NPE or VerifyError for code with constructor reference of inner class
++ */
++
++import java.util.function.Function;
++import java.util.stream.Stream;
++
++public class MethodRefNewInnerInLambdaVerify1 {
++ public static void main(String[] args) {
++ if (new MethodRefNewInnerInLambdaVerify1().map().apply(1).getClass() != TT.class)
++ throw new AssertionError("sanity failed");
++ }
++
++ Function<Integer,TT> map() {
++ return (i) -> Stream.of(i).map(TT::new).findFirst().get();
++ }
++
++ class TT {
++ public TT(int i) {
++
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/methodReference/MethodRefNewInnerInLambdaVerify2.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8038776
++ * @summary VerifyError when running successfully compiled java class
++ */
++
++import java.util.function.Function;
++
++/**
++ * Derived from code by:
++ * @author Yawkat
++ */
++public class MethodRefNewInnerInLambdaVerify2 {
++ public static void main(String[] args) { new MethodRefNewInnerInLambdaVerify2().runTest(); }
++
++ private void runTest() {
++ Worker worker = new Worker();
++ run(() -> worker.check(field -> new SomeClass(field)));
++ run(() -> worker.check(SomeClass::new));
++ }
++
++ private void run(Runnable runnable) {
++ runnable.run();
++ }
++
++ private class SomeClass {
++ final Object field;
++
++ SomeClass(Object field) {
++ this.field = field;
++ }
++ }
++
++ private static class Worker {
++ void check(Function<Object, SomeClass> i) {
++ if (!i.apply("frank").field.equals("frank")) throw new AssertionError("sanity failed");
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/methodReference/MethodRefNewInnerInLambdaVerify2simple.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,50 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8038776
++ * @summary VerifyError when running successfully compiled java class
++ */
++
++import java.util.function.Function;
++
++/**
++ * Derived from code by:
++ * @author Yawkat
++ */
++public class MethodRefNewInnerInLambdaVerify2simple {
++ public static void main(String[] args) { new MethodRefNewInnerInLambdaVerify2simple().runTest(); }
++
++ private void runTest() {
++ Runnable r = (() -> { Sup w = SomeClass::new; } );
++ }
++
++ private class SomeClass {
++ SomeClass() { }
++ }
++}
++
++interface Sup {
++ Object get();
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/methodReference/MethodRefQualifier1.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8048121
++ * @summary javac complex method references: revamp and simplify
++ */
++
++public class MethodRefQualifier1 {
++
++ interface SAM {
++ void m();
++ }
++
++ static int count = 0;
++
++ static void assertTrue(boolean cond, String msg) {
++ if (!cond)
++ throw new AssertionError(msg);
++ }
++
++ MethodRefQualifier1 check() {
++ count++;
++ return this;
++ }
++
++ void ido(Object... args) { }
++
++ public static void main(String[] args) {
++ new MethodRefQualifier1().test();
++ }
++
++ void test() {
++ count = 0;
++ SAM s = check()::ido;
++ assertTrue(count == 1, "creation: unexpected: " + count);
++ count = 0;
++ s.m();
++ assertTrue(count == 0, "evaluation: unexpected: " + count);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/methodReference/MethodRefSingleRefEvalBridge.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8048121
++ * @summary javac complex method references: revamp and simplify
++ *
++ * Make sure that the method reference receiver is evaluated exactly once
++ * even in this bridging case.
++ */
++
++ public class MethodRefSingleRefEvalBridge {
++
++ interface SAM {
++ int m();
++ }
++
++ class ZZ {
++ // private to force bridging
++ private int four() { return 4; }
++ }
++
++ static int count = 0;
++ ZZ azz = new ZZ();
++
++ static void assertEqual(int expected, int got) {
++ if (got != expected)
++ throw new AssertionError("Expected " + expected + " got " + got);
++ }
++
++ public static void main(String[] args) {
++ new MethodRefSingleRefEvalBridge().test();
++ }
++
++ ZZ check() {
++ count++;
++ return azz;
++ }
++
++ void test() {
++ count = 0;
++ SAM s = check()::four;
++ assertEqual(1, count);
++
++ count = 0;
++ assertEqual(4, s.m());
++ assertEqual(0, count);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/methodReference/MethodRefToInner.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8047341
++ * @summary lambda reference to inner class in base class causes LambdaConversionException
++ */
++
++import java.util.List;
++import java.util.ArrayList;
++
++class MethodRefToInnerBase {
++ class TestString {
++ String str;
++ TestString(String strin) {
++ str = strin;
++ }
++ }
++}
++public class MethodRefToInner extends MethodRefToInnerBase {
++ public static void main(String[] args) {
++ new MethodRefToInner().run();
++ }
++ MethodRefToInner() {
++ super();
++ }
++ void run() {
++ List<String> list = new ArrayList<>();
++ list.stream().forEach(TestString::new);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/methodReference/MethodReferenceComplexNullCheckTest.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.
++ */
++
++/**
++ * @test
++ * @bug 8048121
++ * @summary javac complex method references: revamp and simplify
++ *
++ * Make sure NPE check is done even in the convert to Lambda case
++ */
++
++public class MethodReferenceComplexNullCheckTest {
++ public static void main(String[] args) {
++ F fr = null;
++ boolean npeFired = false;
++ try {
++ IForm frf = fr::doit;
++ } catch (NullPointerException npe) {
++ npeFired = true;
++ } finally {
++ if (!npeFired) throw new AssertionError( "NPE should have been thrown");
++ }
++ }
++
++ interface IForm {
++ void xyz(Object... args);
++ }
++
++ class F {
++ private void doit(Object... args) { }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceIntersection1.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,88 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.
++ */
++
++/**
++ * @test
++ * @bug 8058112
++ * @summary Invalid BootstrapMethod for constructor/method reference
++ */
++
++import java.util.Arrays;
++import java.util.Comparator;
++import java.util.List;
++
++import static java.util.stream.Collectors.toList;
++
++public class MethodReferenceIntersection1 {
++
++ public static void main(String[] args) {
++ MethodReferenceIntersection1 main = new MethodReferenceIntersection1();
++ List<Info_MRI1> list = main.toInfoListError(Arrays.asList(new Base_MRI1()));
++ System.out.printf("result %d\n", list.size());
++ }
++
++ public <H extends B_MRI1 & A_MRI1> List<Info_MRI1> toInfoListError(List<H> list) {
++ Comparator<B_MRI1> byNameComparator =
++ (B_MRI1 b1, B_MRI1 b2) -> b1.getB().compareToIgnoreCase(b2.getB());
++ return list.stream().sorted(byNameComparator).map(Info_MRI1::new).collect(toList());
++ }
++
++ public <H extends B_MRI1 & A_MRI1> List<Info_MRI1> toInfoListWorks(List<H> list) {
++ Comparator<B_MRI1> byNameComparator =
++ (B_MRI1 b1, B_MRI1 b2) -> b1.getB().compareToIgnoreCase(b2.getB());
++ return list.stream().sorted(byNameComparator).map(s -> new Info_MRI1(s)).collect(toList());
++ }
++}
++
++interface B_MRI1 {
++ public String getB();
++}
++
++interface A_MRI1 {
++ public long getA();
++}
++
++class Info_MRI1 {
++ private final long a;
++ private final String b;
++
++ <H extends A_MRI1 & B_MRI1> Info_MRI1(H h) {
++ a = h.getA();
++ b = h.getB();
++ }
++}
++
++class Base_MRI1 implements A_MRI1, B_MRI1 {
++
++ @Override
++ public long getA() {
++ return 7L;
++ }
++
++ @Override
++ public String getB() {
++ return "hello";
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceIntersection2.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,68 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.
++ */
++
++/**
++ * @test
++ * @bug 8058112
++ * @summary Invalid BootstrapMethod for constructor/method reference
++ */
++
++import java.util.function.Function;
++
++public class MethodReferenceIntersection2 {
++
++ interface B { }
++
++ interface A { }
++
++ static class C implements A, B { }
++
++ static class Info {
++ <H extends A & B> Info(H h) { }
++
++ static <H extends A & B> Info info(H h) {
++ return new Info(h);
++ }
++ }
++
++ public static void main(String[] args) {
++ test();
++ }
++
++ // Note the switch in order compared to that on Info
++ static <H extends B & A> void test() {
++ Function<H, Info> f1L = _h -> new Info(_h);
++ Function<H, Info> f1 = Info::new;
++ Function<H, Info> f2L = _h -> Info.info(_h);
++ Function<H, Info> f2 = Info::info;
++ H c = (H) new C();
++ if(f1.apply(c) instanceof Info &&
++ f2.apply(c) instanceof Info) {
++ System.out.println("Passes.");
++ } else {
++ throw new AssertionError();
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceIntersection3.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,50 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.
++ */
++
++/**
++ * @test
++ * @bug 8058112
++ * @summary Invalid BootstrapMethod for constructor/method reference
++ */
++
++/**
++ * @author Remi Forax
++ */
++
++public class MethodReferenceIntersection3 {
++ interface A {}
++
++ interface Foo {
++ <T extends Object & A> void foo(T t);
++ }
++
++ static <T extends A> void bar(T t) {
++ }
++
++ public static void main(String[] args) {
++ Foo foo = MethodReferenceIntersection3::bar;
++ foo.foo(new A(){});
++ }
++}
+--- ./langtools/test/tools/javac/varargs/6313164/T6313164.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/test/tools/javac/varargs/6313164/T6313164.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1,18 +1,26 @@
+ /*
+ * @test /nodynamiccopyright/
+- * @bug 6313164
++ * @bug 6313164 8036953
+ * @author mcimadamore
+ * @summary javac generates code that fails byte code verification for the varargs feature
+- * @compile/fail/ref=T6313164.out -XDrawDiagnostics T6313164.java
++ * @compile/fail/ref=T6313164Source7.out -source 7 -XDrawDiagnostics T6313164.java
++ * @compile/fail/ref=T6313164Source8AndHigher.out -XDrawDiagnostics T6313164.java
+ */
+ import p1.*;
+
+ class T6313164 {
+- { B b = new B();
+- b.foo1(new B(), new B()); //error - A not accesible
+- b.foo2(new B(), new B()); //ok - A not accessible, but foo2(Object...) applicable
+- b.foo3(null, null); //error - A (inferred) not accesible
+- b.foo4(null, null); //error - A (inferred in 15.12.2.8 - no resolution backtrack) not accesible
+- b.foo4(new B(), new C()); //ok - A (inferred in 15.12.2.7) not accessible, but foo4(Object...) applicable
++ {
++ B b = new B();
++ b.foo1(new B(), new B()); //error - A not accessible
++ /* 7 : ok - A not accessible, but foo2(Object...) applicable
++ * 8+ : error - A not accessible
++ */
++ b.foo2(new B(), new B());
++ b.foo3(null, null); //error - A (inferred) not accessible
++ b.foo4(null, null); //error - A not accesible
++ /* 7 : ok - A not accessible, but foo4(Object...) applicable
++ * 8+ : error - A not accessible
++ */
++ b.foo4(new B(), new C());
+ }
+ }
+--- ./langtools/test/tools/javac/varargs/6313164/T6313164.out Mon Dec 08 12:30:44 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,6 +0,0 @@
+-T6313164.java:12:8: compiler.err.cant.apply.symbol: kindname.method, foo1, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
+-T6313164.java:14:13: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
+-T6313164.java:15:13: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
+-- compiler.note.unchecked.filename: B.java
+-- compiler.note.unchecked.recompile
+-3 errors
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/varargs/6313164/T6313164Source7.out Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,6 @@
++- compiler.warn.source.no.bootclasspath: 1.7
++T6313164.java:14:10: compiler.err.cant.apply.symbol: kindname.method, foo1, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
++T6313164.java:19:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
++T6313164.java:20:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
++3 errors
++1 warning
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/varargs/6313164/T6313164Source8AndHigher.out Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,6 @@
++T6313164.java:14:15: compiler.err.cant.apply.symbol: kindname.method, foo1, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
++T6313164.java:18:15: compiler.err.cant.apply.symbol: kindname.method, foo2, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
++T6313164.java:19:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
++T6313164.java:20:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
++T6313164.java:24:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
++5 errors
+--- ./langtools/test/tools/javac/varargs/6313164/T7175433.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/test/tools/javac/varargs/6313164/T7175433.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1,31 +1,8 @@
+ /*
+- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-/*
+- * @test
++ * @test /nodynamiccopyright/
+ * @bug 7175433 6313164
+ * @summary Inference cleanup: add helper class to handle inference variables
+- *
++ * @compile/fail/ref=T7175433.out -XDrawDiagnostics T7175433.java
+ */
+
+ import java.util.List;
+@@ -34,26 +11,16 @@
+
+ private class Foo { }
+
+- <Z> List<Z> m(Object... o) { T7175433.assertTrue(true); return null; }
+- <Z> List<Z> m(Foo... o) { T7175433.assertTrue(false); return null; }
++ <Z> List<Z> m(Object... o) { return null; }
++ <Z> List<Z> m(Foo... o) { return null; }
+
+ Foo getFoo() { return null; }
+ }
+
+ public class T7175433 {
+
+- static int assertionCount;
+-
+- static void assertTrue(boolean b) {
+- assertionCount++;
+- if (!b) {
+- throw new AssertionError();
+- }
+- }
+-
+ public static void main(String[] args) {
+ Bar b = new Bar();
+ b.m(b.getFoo());
+- assertTrue(assertionCount == 1);
+ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/varargs/6313164/T7175433.out Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,2 @@
++T7175433.java:24:12: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: Bar.Foo, kindname.class, T7175433)
++1 error
+--- ./langtools/test/tools/javac/varargs/6313164/p1/B.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/test/tools/javac/varargs/6313164/p1/B.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -23,13 +23,12 @@
+
+ package p1;
+
++@SuppressWarnings("unchecked")
+ public class B extends A {
+- public B() {}
+ public void foo1(A... args) { }
+ public void foo2(A... args) { }
+ public void foo2(Object... args) { }
+ public <X extends A> void foo3(X... args) { }
+ public <X extends A> void foo4(X... args) { }
+ public void foo4(Object... args) { }
+-
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/varargs/8055514/T8055514.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,26 @@
++/*
++ * @test /nodynamiccopyright/
++ * @bug 8055514
++ * @summary Wrong, confusing error when non-static varargs referenced in static context
++ * @compile/fail/ref=T8055514.out -Xlint:varargs -Werror -XDrawDiagnostics T8055514.java
++ */
++class T8055514 {
++ void m(int... args) { }
++
++ void m2(int... args) { }
++ static void m2(String s) { }
++
++ void m3(int... args) { }
++ static void m3(String s) { }
++ static void m3(Runnable r) { }
++
++ void m4(int... args) { }
++ void m4(int i1, int i2, int i3) { }
++
++ static void test() {
++ m(1,2,3); //only one candidate (varargs) - varargs error wins
++ m2(1,2,3); //two candidates - only one applicable (varargs) - varargs error wins
++ m3(1,2,3); //three candidates - only one applicable (varargs) - varargs error wins
++ m4(1,2,3); //two candidates - both applicable - basic error wins
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/varargs/8055514/T8055514.out Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,5 @@
++T8055514.java:21:9: compiler.err.non-static.cant.be.ref: kindname.method, m(int...)
++T8055514.java:22:9: compiler.err.non-static.cant.be.ref: kindname.method, m2(int...)
++T8055514.java:23:9: compiler.err.non-static.cant.be.ref: kindname.method, m3(int...)
++T8055514.java:24:9: compiler.err.non-static.cant.be.ref: kindname.method, m4(int,int,int)
++4 errors
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/varargs/T8049075/VarargsAndWildcardParameterizedTypeTest.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,40 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8049075
++ * @summary javac, wildcards and generic vararg method invocation not accepted
++ * @compile VarargsAndWildcardParameterizedTypeTest.java
++ */
++
++class VarargsAndWildcardParameterizedTypeTest {
++ interface I<T> {
++ String m(T... t);
++ }
++
++ void m() {
++ I<? super Integer> i = null;
++ i.m(Integer.valueOf(1), Integer.valueOf(1));
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/warnings/suppress/Overridden.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,16 @@
++/**
++ * @test /nodynamiccopyright/
++ * @bug 8033421
++ * @summary Check that \\@SuppressWarnings works properly when overriding deprecated method.
++ * @build VerifySuppressWarnings
++ * @compile/ref=Overridden.out -XDrawDiagnostics -Xlint:deprecation Overridden.java
++ * @run main VerifySuppressWarnings Overridden.java
++ */
++
++public class Overridden implements Interface {
++ public void test() { }
++}
++
++interface Interface {
++ @Deprecated void test();
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/warnings/suppress/Overridden.out Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,2 @@
++Overridden.java:11:17: compiler.warn.has.been.deprecated: test(), Interface
++1 warning
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/javac/warnings/suppress/OverriddenSuppressed.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8033421
++ * @summary Check that \\@SuppressWarnings works properly when overriding deprecated method.
++ * @compile -Werror -Xlint:deprecation OverriddenSuppressed.java
++ */
++
++public class OverriddenSuppressed implements Interface {
++ @SuppressWarnings("deprecation")
++ public void test() { }
++}
++
++interface Interface {
++ @Deprecated void test();
++}
+--- ./langtools/test/tools/jdeps/APIDeps.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/test/tools/jdeps/APIDeps.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -23,7 +23,7 @@
+
+ /*
+ * @test
+- * @bug 8015912 8029216
++ * @bug 8015912 8029216 8048063 8050804
+ * @summary Test -apionly and -jdkinternals options
+ * @build m.Bar m.Foo m.Gee b.B c.C c.I d.D e.E f.F g.G
+ * @run main APIDeps
+@@ -81,27 +81,39 @@
+ new String[] {"compact1", "compact3", testDirBasename},
+ new String[] {"-classpath", testDir.getPath(), "-verbose", "-P"});
+ test(new File(mDir, "Foo.class"),
++ new String[] {"c.I", "e.E", "f.F"},
++ new String[] {testDirBasename},
++ new String[] {"-classpath", testDir.getPath(), "-verbose:class", "-P"});
++ test(new File(mDir, "Foo.class"),
+ new String[] {"c.I", "e.E", "f.F", "m.Bar"},
+ new String[] {testDirBasename},
++ new String[] {"-classpath", testDir.getPath(), "-verbose:class", "-filter:none", "-P"});
++ test(new File(mDir, "Gee.class"),
++ new String[] {"g.G", "sun.misc.Lock", "com.sun.tools.classfile.ClassFile",
++ "com.sun.management.ThreadMXBean", "com.sun.source.tree.BinaryTree"},
++ new String[] {testDirBasename, "JDK internal API", "compact3", ""},
+ new String[] {"-classpath", testDir.getPath(), "-verbose", "-P"});
+- test(new File(mDir, "Gee.class"),
+- new String[] {"g.G", "sun.misc.Lock"},
+- new String[] {testDirBasename, "JDK internal API"},
+- new String[] {"-classpath", testDir.getPath(), "-verbose"});
+
+ // -jdkinternals
+ test(new File(mDir, "Gee.class"),
+- new String[] {"sun.misc.Lock"},
++ new String[] {"sun.misc.Lock", "com.sun.tools.classfile.ClassFile"},
+ new String[] {"JDK internal API"},
+ new String[] {"-jdkinternals"});
+ // -jdkinternals parses all classes on -classpath and the input arguments
+ test(new File(mDir, "Gee.class"),
+- new String[] {"sun.misc.Lock", "sun.misc.Unsafe"},
++ new String[] {"com.sun.tools.jdeps.Main", "com.sun.tools.classfile.ClassFile",
++ "sun.misc.Lock", "sun.misc.Unsafe"},
+ new String[] {"JDK internal API"},
+ new String[] {"-classpath", testDir.getPath(), "-jdkinternals"});
+
+ // parse only APIs
+- // parse only APIs
++ test(mDir,
++ new String[] {"java.lang.Object", "java.lang.String",
++ "java.util.Set",
++ "c.C", "d.D", "c.I", "e.E"},
++ new String[] {"compact1", testDirBasename},
++ new String[] {"-classpath", testDir.getPath(), "-verbose:class", "-P", "-apionly"});
++
+ test(mDir,
+ new String[] {"java.lang.Object", "java.lang.String",
+ "java.util.Set",
+--- ./langtools/test/tools/jdeps/Basic.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/test/tools/jdeps/Basic.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -23,7 +23,7 @@
+
+ /*
+ * @test
+- * @bug 8003562 8005428 8015912 8027481
++ * @bug 8003562 8005428 8015912 8027481 8048063
+ * @summary Basic tests for jdeps tool
+ * @build Test p.Foo p.Bar javax.activity.NotCompactProfile
+ * @run main Basic
+@@ -86,6 +86,16 @@
+ new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"},
+ new String[] {"compact1", "compact1", "not found", "not found"},
+ new String[] {"-verbose:class"});
++ // test -filter:none option
++ test(new File(testDir, "p"),
++ new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto", "p"},
++ new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1", "p"},
++ new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:none"});
++ // test -filter:archive option
++ test(new File(testDir, "p"),
++ new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto"},
++ new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"},
++ new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:archive"});
+ // test -p option
+ test(new File(testDir, "Test.class"),
+ new String[] {"p.Foo", "p.Bar"},
+@@ -100,11 +110,12 @@
+ new String[] {"java.lang"},
+ new String[] {"compact1"},
+ new String[] {"-verbose:package", "-e", "java\\.lang\\..*"});
++
+ // test -classpath and -include options
+ test(null,
+- new String[] {"java.lang", "java.util",
+- "java.lang.management", "javax.crypto"},
+- new String[] {"compact1", "compact1", "compact3", "compact1"},
++ new String[] {"java.lang", "java.util", "java.lang.management",
++ "javax.activity", "javax.crypto"},
++ new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"},
+ new String[] {"-classpath", testDir.getPath(), "-include", "p.+|Test.class"});
+ test(new File(testDir, "Test.class"),
+ new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"},
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./langtools/test/tools/jdeps/DotFileTest.java Wed Feb 04 12:14:46 2015 -0800
+@@ -0,0 +1,272 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 8003562
++ * @summary Basic tests for jdeps -dotoutput option
++ * @build Test p.Foo p.Bar javax.activity.NotCompactProfile
++ * @run main DotFileTest
++ */
++
++import java.io.File;
++import java.io.IOException;
++import java.io.PrintWriter;
++import java.io.StringWriter;
++import java.nio.file.DirectoryStream;
++import java.nio.file.Files;
++import java.nio.file.Path;
++import java.nio.file.Paths;
++import java.util.*;
++import java.util.regex.*;
++
++public class DotFileTest {
++ private static boolean symbolFileExist = initProfiles();
++ private static boolean initProfiles() {
++ // check if ct.sym exists; if not use the profiles.properties file
++ Path home = Paths.get(System.getProperty("java.home"));
++ if (home.endsWith("jre")) {
++ home = home.getParent();
++ }
++ Path ctsym = home.resolve("lib").resolve("ct.sym");
++ boolean symbolExists = ctsym.toFile().exists();
++ if (!symbolExists) {
++ Path testSrcProfiles =
++ Paths.get(System.getProperty("test.src", "."), "profiles.properties");
++ if (!testSrcProfiles.toFile().exists())
++ throw new Error(testSrcProfiles + " does not exist");
++ System.out.format("%s doesn't exist.%nUse %s to initialize profiles info%n",
++ ctsym, testSrcProfiles);
++ System.setProperty("jdeps.profiles", testSrcProfiles.toString());
++ }
++ return symbolExists;
++ }
++
++ public static void main(String... args) throws Exception {
++ int errors = 0;
++ errors += new DotFileTest().run();
++ if (errors > 0)
++ throw new Exception(errors + " errors found");
++ }
++
++ final Path dir;
++ final Path dotoutput;
++ DotFileTest() {
++ this.dir = Paths.get(System.getProperty("test.classes", "."));
++ this.dotoutput = dir.resolve("dots");
++ }
++
++ int run() throws IOException {
++ File testDir = dir.toFile();
++ // test a .class file
++ test(new File(testDir, "Test.class"),
++ new String[] {"java.lang", "p"},
++ new String[] {"compact1", "not found"});
++ // test a directory
++ // also test non-SE javax.activity class dependency
++ test(new File(testDir, "p"),
++ new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto"},
++ new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"},
++ new String[] {"-classpath", testDir.getPath()});
++ // test class-level dependency output
++ test(new File(testDir, "Test.class"),
++ new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"},
++ new String[] {"compact1", "compact1", "not found", "not found"},
++ new String[] {"-verbose:class"});
++ // test -filter:none option
++ test(new File(testDir, "p"),
++ new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto", "p"},
++ new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1", "p"},
++ new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:none"});
++ // test -filter:archive option
++ test(new File(testDir, "p"),
++ new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto"},
++ new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"},
++ new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:archive"});
++ // test -p option
++ test(new File(testDir, "Test.class"),
++ new String[] {"p.Foo", "p.Bar"},
++ new String[] {"not found", "not found"},
++ new String[] {"-verbose:class", "-p", "p"});
++ // test -e option
++ test(new File(testDir, "Test.class"),
++ new String[] {"p.Foo", "p.Bar"},
++ new String[] {"not found", "not found"},
++ new String[] {"-verbose:class", "-e", "p\\..*"});
++ test(new File(testDir, "Test.class"),
++ new String[] {"java.lang"},
++ new String[] {"compact1"},
++ new String[] {"-verbose:package", "-e", "java\\.lang\\..*"});
++ // test -classpath options
++ test(new File(testDir, "Test.class"),
++ new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"},
++ new String[] {"compact1", "compact1", testDir.getName(), testDir.getName()},
++ new String[] {"-v", "-classpath", testDir.getPath()});
++
++ testSummary(new File(testDir, "Test.class"),
++ new String[] {"rt.jar", testDir.getName()},
++ new String[] {"compact1", ""},
++ new String[] {"-classpath", testDir.getPath()});
++ testSummary(new File(testDir, "Test.class"),
++ new String[] {"java.lang", "p"},
++ new String[] {"compact1", testDir.getName()},
++ new String[] {"-v", "-classpath", testDir.getPath()});
++ return errors;
++ }
++
++ void test(File file, String[] expect, String[] profiles) throws IOException {
++ test(file, expect, profiles, new String[0]);
++ }
++
++ void test(File file, String[] expect, String[] profiles, String[] options)
++ throws IOException
++ {
++ Path dotfile = dotoutput.resolve(file.toPath().getFileName().toString() + ".dot");
++
++ List<String> args = new ArrayList<>(Arrays.asList(options));
++ args.add("-dotoutput");
++ args.add(dotoutput.toString());
++ if (file != null) {
++ args.add(file.getPath());
++ }
++
++ Map<String,String> result = jdeps(args, dotfile);
++ checkResult("dependencies", expect, result.keySet());
++
++ // with -P option
++ List<String> argsWithDashP = new ArrayList<>();
++ argsWithDashP.add("-dotoutput");
++ argsWithDashP.add(dotoutput.toString());
++ argsWithDashP.add("-P");
++ argsWithDashP.addAll(args);
++
++ result = jdeps(argsWithDashP, dotfile);
++ checkResult("profiles", expect, profiles, result);
++ }
++
++ void testSummary(File file, String[] expect, String[] profiles, String[] options)
++ throws IOException
++ {
++ Path dotfile = dotoutput.resolve("summary.dot");
++
++ List<String> args = new ArrayList<>(Arrays.asList(options));
++ args.add("-dotoutput");
++ args.add(dotoutput.toString());
++ if (file != null) {
++ args.add(file.getPath());
++ }
++
++ Map<String,String> result = jdeps(args, dotfile);
++ checkResult("dependencies", expect, result.keySet());
++
++ // with -P option
++ List<String> argsWithDashP = new ArrayList<>();
++ argsWithDashP.add("-dotoutput");
++ argsWithDashP.add(dotoutput.toString());
++ argsWithDashP.add("-P");
++ argsWithDashP.addAll(args);
++
++ result = jdeps(argsWithDashP, dotfile);
++ checkResult("profiles", expect, profiles, result);
++ }
++
++ Map<String,String> jdeps(List<String> args, Path dotfile) throws IOException {
++ if (Files.exists(dotoutput)) {
++ try (DirectoryStream<Path> stream = Files.newDirectoryStream(dotoutput)) {
++ for (Path p : stream) {
++ Files.delete(p);
++ }
++ }
++ Files.delete(dotoutput);
++ }
++ // invoke jdeps
++ StringWriter sw = new StringWriter();
++ PrintWriter pw = new PrintWriter(sw);
++ System.err.println("jdeps " + args);
++ int rc = com.sun.tools.jdeps.Main.run(args.toArray(new String[0]), pw);
++ pw.close();
++ String out = sw.toString();
++ if (!out.isEmpty())
++ System.err.println(out);
++ if (rc != 0)
++ throw new Error("jdeps failed: rc=" + rc);
++
++ // check output files
++ if (Files.notExists(dotfile)) {
++ throw new RuntimeException(dotfile + " doesn't exist");
++ }
++ return parse(dotfile);
++ }
++ private static Pattern pattern = Pattern.compile("(.*) -> +([^ ]*) (.*)");
++ private Map<String,String> parse(Path outfile) throws IOException {
++ Map<String,String> result = new LinkedHashMap<>();
++ for (String line : Files.readAllLines(outfile)) {
++ line = line.replace('"', ' ').replace(';', ' ');
++ Matcher pm = pattern.matcher(line);
++ if (pm.find()) {
++ String origin = pm.group(1).trim();
++ String target = pm.group(2).trim();
++ String module = pm.group(3).replace('(', ' ').replace(')', ' ').trim();
++ result.put(target, module);
++ }
++ }
++ return result;
++ }
++
++ void checkResult(String label, String[] expect, Collection<String> found) {
++ List<String> list = Arrays.asList(expect);
++ if (!isEqual(list, found))
++ error("Unexpected " + label + " found: '" + found + "', expected: '" + list + "'");
++ }
++
++ void checkResult(String label, String[] expect, String[] profiles, Map<String,String> result) {
++ if (expect.length != profiles.length)
++ error("Invalid expected names and profiles");
++
++ // check the dependencies
++ checkResult(label, expect, result.keySet());
++ // check profile information
++ checkResult(label, profiles, result.values());
++ for (int i=0; i < expect.length; i++) {
++ String profile = result.get(expect[i]);
++ if (!profile.equals(profiles[i]))
++ error("Unexpected profile: '" + profile + "', expected: '" + profiles[i] + "'");
++ }
++ }
++
++ boolean isEqual(List<String> expected, Collection<String> found) {
++ if (expected.size() != found.size())
++ return false;
++
++ List<String> list = new ArrayList<>(found);
++ list.removeAll(expected);
++ return list.isEmpty();
++ }
++
++ void error(String msg) {
++ System.err.println("Error: " + msg);
++ errors++;
++ }
++
++ int errors;
++}
+--- ./langtools/test/tools/jdeps/m/Gee.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/test/tools/jdeps/m/Gee.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -26,5 +26,7 @@
+
+ class Gee extends g.G {
+ public sun.misc.Lock lock;
++ public com.sun.tools.classfile.ClassFile cf; // @jdk.Exported(false)
++ public com.sun.source.tree.BinaryTree tree; // @jdk.Exported
++ public com.sun.management.ThreadMXBean mxbean; // @jdk.Exported on package-info
+ }
+-
+--- ./langtools/test/tools/jdeps/p/Bar.java Mon Dec 08 12:30:44 2014 -0800
++++ ./langtools/test/tools/jdeps/p/Bar.java Wed Feb 04 12:14:46 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -30,4 +30,8 @@
+ public javax.crypto.Cipher getCiper() {
+ return null;
+ }
++
++ public Foo foo() {
++ return new Foo();
++ }
+ }
+--- ./nashorn/.hgtags Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/.hgtags Wed Feb 04 12:14:47 2015 -0800
+@@ -335,3 +335,29 @@
+ c68ba913a0eeea6eb94d9568e9985505ec3408a3 jdk8u31-b10
+ 599bd596fa549d882aa8fc5104c322a75a3af728 jdk8u31-b11
+ f36c71a03e4ed467f630cc46d076a5bb4c58b6d5 jdk8u31-b12
++ec36fa3b35eb00f053d624ae837579c6b8e446ac jdk8u31-b13
++f2925491b61b22ac42f8c30ee9c6723ffa401a4c jdk8u40-b00
++62468d841b842769d875bd97d10370585c296eb7 jdk8u40-b01
++b476c69c820ac1e05071f4de5abab8e2dff80e87 jdk8u40-b02
++a2e0a985764b5afd5f316429bfab4f44bf150f7f jdk8u40-b03
++34c17c95665419ed76a98f5cf1210ed58eb2eca3 jdk8u40-b04
++2d75c391f61f31538b4c3dcc9778fc6742125ec4 jdk8u40-b05
++1196f17cf7bc709766319f5bf7a5394a7251b47a jdk8u40-b06
++0032961e1866c22afe3d0bbbb217f8840be61846 jdk8u40-b07
++89551828b279233825204b72233edafc72d8feb3 jdk8u40-b08
++6a8ecdeae4a9a438eed637b5a5d0d18fddb9f711 jdk8u40-b09
++076b1f38a5ccd4692a6f93939a7fc03bc1a1bbb4 jdk8u40-b10
++57c7b273277e00f7a98fafb18ff07aa3245808f0 jdk8u40-b11
++375a3a3256d041fe7334638a95e69b4c11d6104b jdk8u40-b12
++d60fbb5343c186abbf92b0259e67efb3b71377b4 jdk8u40-b13
++7e34104c55cafa0b579be3a480dda383c616a378 jdk8u40-b14
++fc37699ddc0ed41d4ab5da821211a6d2648c8883 jdk8u40-b15
++e079f3f6d536510b1ab3589b1038d893d78302ac jdk8u40-b16
++88e22262fdb26e3154a1034c2413415e97b9a86a jdk8u40-b17
++653739706172ae94e999731a3a9f10f8ce11ffca jdk8u40-b18
++6ec61d2494283fbaca6df227f1a5b45487dc1ca7 jdk8u40-b19
++4d240320929f7b2247eeb97e43efe2370b70582e jdk8u40-b20
++dbb663a9d9aa2807ef501c7d20f29415816a1973 jdk8u40-b21
++f9f70a0f60f48fbb95275b6c1110cedf740c6177 jdk8u40-b22
++6ca090832d30fd0e46214ccc00816490ad75a8ab jdk8u40-b23
++b2ce5df33715583c898530560d4202853b9ff9bc jdk8u40-b24
+--- ./nashorn/THIRD_PARTY_README Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/THIRD_PARTY_README Wed Feb 04 12:14:47 2015 -0800
+@@ -3385,7 +3385,7 @@
+ included with JRE 8, JDK 8, and OpenJDK 8.
+
+ Apache Commons Math 3.2
+- Apache Derby 10.10.1.3
++ Apache Derby 10.11.1.2
+ Apache Jakarta BCEL 5.1
+ Apache Jakarta Regexp 1.4
+ Apache Santuario XML Security for Java 1.5.4
+--- ./nashorn/bin/checkintest.sh Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,266 +0,0 @@
+-#!/bin/bash
+-#
+-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-#
+-# This code is free software; you can redistribute it and/or modify it
+-# under the terms of the GNU General Public License version 2 only, as
+-# published by the Free Software Foundation.
+-#
+-# This code is distributed in the hope that it will be useful, but WITHOUT
+-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-# version 2 for more details (a copy is included in the LICENSE file that
+-# accompanied this code).
+-#
+-# You should have received a copy of the GNU General Public License version
+-# 2 along with this work; if not, write to the Free Software Foundation,
+-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-#
+-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-# or visit www.oracle.com if you need additional information or have any
+-# questions.
+-#
+-
+-#best pass rate at test 262 known
+-TEST262_PASS_AT_LEAST=435
+-
+-RUN_TEST="true"
+-RUN_TEST262="true"
+-RUN_NODE="true"
+-KEEP_OUTPUT="true"
+-CLEAN_AND_BUILD_NASHORN="true"
+-
+-#the stable node version to sync against
+-NODE_LAST_STABLE=v0.6.18
+-
+-#parse args
+-for arg in $*
+-do
+- if [ $arg = "--no-test" ]; then
+- RUN_TEST="false"
+- echo "**** WARNING - you have disabled 'ant test', which is a minimum checkin requirement..."
+- elif [ $arg = "--no-262" ]; then
+- RUN_TEST262="false"
+- elif [ $arg = "--no-node" ]; then
+- RUN_NODE="false"
+- elif [ $arg = "--no-build" ]; then
+- CLEAN_AND_BUILD_NASHORN="false"
+- elif [ $arg = "--no-logs" ]; then
+- KEEP_OUTPUT="false"
+- fi
+-done
+-
+-function lastpart() {
+- arr=$(echo $1 | tr "/" "\n")
+- for x in $arr
+- do
+- _last=$x
+- done
+- echo $_last
+-}
+-
+-function check_installed() {
+- which $1 >/dev/null
+- if [ $? -ne 0 ]; then
+- echo "Error $1 not installed: $?"
+- exit 2
+- fi
+-}
+-
+-check_installed hg
+-check_installed git
+-check_installed mv
+-check_installed git
+-
+-PWD=$(pwd);
+-
+-while [ -z $NASHORN_ROOT ]
+-do
+- if [ -e $PWD/.hg ]; then
+- NASHORN_ROOT=${PWD}
+- break
+- fi
+- PWD=$(dirname ${PWD})
+-done
+-
+-echo "Nashorn root detected at ${NASHORN_ROOT}"
+-
+-COMMON_ROOT=$(dirname $NASHORN_ROOT)
+-echo "Common root is ${COMMON_ROOT}"
+-
+-echo "Running checkintest..."
+-
+-ABSOLUTE_NASHORN_HOME=$COMMON_ROOT/$(lastpart $NASHORN_ROOT)
+-
+-if [ $CLEAN_AND_BUILD_NASHORN != "false" ]; then
+- echo "Cleaning and building nashorn at $ABSOLUTE_NASHORN_HOME/nashorn..."
+- $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant clean >/dev/null 2>/dev/null)
+- $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant jar >/dev/null 2>/dev/null)
+- echo "Done."
+-fi
+-
+-function failure_check() {
+- while read line
+- do
+- LINE=$(echo $line | grep "Tests run")
+- if [ "${LINE}" != "" ]; then
+- RESULT=$(echo $line | grep "Failures: 0" | grep "Errors: 0")
+- if [ "${RESULT}" == "" ]; then
+- TESTNAME=$2
+- echo "There were errors in ${TESTNAME} : ${LINE}"
+- exit 1
+- fi
+- fi
+- done < $1
+-}
+-
+-function test() {
+- TEST_OUTPUT=$ABSOLUTE_NASHORN_HOME/$(mktemp tmp.XXXXX)
+- echo "Running 'ant test' on nashorn from ${ABSOLUTE_NASHORN_HOME}/nashorn..."
+- $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant test >$TEST_OUTPUT)
+- echo "Done."
+-
+- failure_check $TEST_OUTPUT
+-
+- echo "**** SUCCESS: 'ant test' successful"
+-
+- if [ $KEEP_OUTPUT == "true" ]; then
+- cp $TEST_OUTPUT ./checkintest.test.log
+- rm -fr $TEST_OUTPUT
+- fi
+-}
+-
+-if [ $RUN_TEST != "false" ]; then
+- test;
+-fi
+-
+-function test262() {
+-
+- echo "Running 'ant test262parallel' on nashorn from ${ABSOLUTE_NASHORN_HOME}/nashorn..."
+- TEST262_OUTPUT=$ABSOLUTE_NASHORN_HOME/$(mktemp tmp.XXXXX)
+-
+- echo "Looking for ${ABSOLUTE_NASHORN_HOME}/test/test262..."
+-
+- if [ ! -e $ABSOLUTE_NASHORN_HOME/nashorn/test/test262 ]; then
+- echo "test262 is missing... looking in $COMMON_ROOT..."
+- if [ ! -e $COMMON_ROOT/test262 ]; then
+- echo "... not there either... cloning from repo..."
+- hg clone http://hg.ecmascript.org/tests/test262 $COMMON_ROOT/test262 >/dev/null 2>/dev/null
+- echo "Done."
+- fi
+- echo "Adding soft link ${COMMON_ROOT}/test262 -> ${ABSOLUTE_NASHORN_HOME}/test/test262..."
+- ln -s $COMMON_ROOT/test262 $ABSOLUTE_NASHORN_HOME/nashorn/test/test262
+- echo "Done."
+- fi
+-
+- echo "Ensuring test262 is up to date..."
+- $(cd $ABSOLUTE_NASHORN_HOME/nashorn/test/test262; hg pull -u >/dev/null 2>/dev/null)
+- echo "Done."
+-
+- echo "Running test262..."
+- $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant test262parallel > $TEST262_OUTPUT)
+-
+- FAILED=$(cat $TEST262_OUTPUT|grep "Tests run:"| cut -d ' ' -f 15 |tr -cd '"[[:digit:]]')
+- if [ $FAILED -gt $TEST262_PASS_AT_LEAST ]; then
+- echo "FAILURE: There are ${FAILED} failures in test262 and can be no more than ${TEST262_PASS_AT_LEAST}"
+- cp $TEST262_OUTPUT ./checkintest.test262.log
+- echo "See ./checkintest.test262.log"
+- echo "Terminating due to error"
+- exit 1
+- elif [ $FAILED -lt $TEST262_PASS_AT_LEAST ]; then
+- echo "There seem to have been fixes to 262. ${FAILED} < ${TEST262_PASS_AT_LEAST}. Please update limit in bin/checkintest.sh"
+- fi
+-
+- echo "**** SUCCESS: Test262 passed with no more than ${TEST262_PASS_AT_LEAST} failures."
+-
+- if [ $KEEP_OUTPUT == "true" ]; then
+- cp $TEST262_OUTPUT ./checkintest.test262.log
+- rm -fr $TEST262_OUTPUT
+- fi
+-}
+-
+-if [ $RUN_TEST262 != "false" ]; then
+- test262;
+-fi;
+-
+-function testnode() {
+- TESTNODEJAR_OUTPUT=$ABSOLUTE_NASHORN_HOME/$(mktemp tmp.XXXXX)
+-
+- echo "Running node tests..."
+-#replace node jar properties nashorn with this nashorn
+-
+- NODEJAR_PROPERTIES=~/nodejar.properties
+-
+- NODE_HOME=$(cat $NODEJAR_PROPERTIES | grep ^node.home | cut -f2 -d=)
+- NASHORN_HOME=$(cat $NODEJAR_PROPERTIES | grep ^nashorn.home | cut -f2 -d=)
+-
+- ABSOLUTE_NODE_HOME=$COMMON_ROOT/$(lastpart $NODE_HOME)
+-
+- echo "Writing nodejar.properties..."
+-
+- cat > $NODEJAR_PROPERTIES << EOF
+-node.home=../node
+-nashorn.home=../$(lastpart $NASHORN_ROOT)
+-EOF
+- echo "Done."
+- echo "Checking node home ${ABSOLUTE_NODE_HOME}..."
+-
+- if [ ! -e $ABSOLUTE_NODE_HOME ]; then
+- echo "Node base dir not found. Cloning node..."
+- $(cd $COMMON_ROOT; git clone https://github.com/joyent/node.git $(lastpart $NODE_HOME) >/dev/null 2>/dev/null)
+- echo "Done."
+- echo "Updating to last stable version ${NODE_LAST_STABLE}..."
+- $(cd $ABSOLUTE_NODE_HOME; git checkout $NODE_LAST_STABLE >/dev/null 2>/dev/null)
+- echo "Done."
+- echo "Running configure..."
+- $(cd $ABSOLUTE_NODE_HOME; ./configure >/dev/null 2>/dev/null)
+- echo "Done."
+- fi
+-
+- echo "Ensuring node is built..."
+-#make sure node is built
+- $(cd $ABSOLUTE_NODE_HOME; make >/dev/null 2>/dev/null)
+- echo "Done."
+-
+- NODEJAR_HOME=$COMMON_ROOT/nodejar
+-
+- if [ ! -e $NODEJAR_HOME ]; then
+- echo "No node jar home found. cloning from depot..."
+- $(cd $COMMON_ROOT; hg clone https://hg.kenai.com/hg/nodejs~source nodejar >/dev/null 2>/dev/null)
+- $(cd $COMMON_ROOT/nodejar; ant >/dev/null)
+- echo "Done."
+- echo "Copying node files..."
+- $(cd $COMMON_ROOT/nodejar; ant copy-node-files >/dev/null 2>/dev/null)
+- echo "Patching node files..."
+- $(cd $COMMON_ROOT/nodejar; ant patch-node-files >/dev/null 2>/dev/null)
+- echo "Done."
+- fi
+-
+- echo "Ensuring node.jar is up to date from source depot..."
+- $(cd $COMMON_ROOT/nodejar; hg pull -u >/dev/null 2>/dev/null)
+- echo "Done."
+-
+- echo "Installing nashorn..."
+- $(cd $COMMON_ROOT/nodejar; ant >/dev/null)
+- echo "Done."
+-
+- echo "Running node.jar test..."
+- $(cd $COMMON_ROOT/nodejar; mvn clean verify >$TESTNODEJAR_OUTPUT)
+- echo "Done."
+-
+- failure_check $TESTNODEJAR_OUTPUT
+-
+- echo "**** SUCCESS: Node test successful."
+-
+- if [ $KEEP_OUTPUT == "true" ]; then
+- rm -fr $TESTNODEJAR_OUTPUT
+- cp $TESTNODEJAR_OUTPUT ./checkintest.nodejar.log
+- fi
+-}
+-
+-if [ $RUN_NODE != "false" ]; then
+- testnode;
+-fi;
+-
+-echo "Finished"
+--- ./nashorn/bin/dump_octane_code.sh Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,53 +0,0 @@
+-#!/bin/bash
+-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-#
+-# This code is free software; you can redistribute it and/or modify it
+-# under the terms of the GNU General Public License version 2 only, as
+-# published by the Free Software Foundation.
+-#
+-# This code is distributed in the hope that it will be useful, but WITHOUT
+-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-# version 2 for more details (a copy is included in the LICENSE file that
+-# accompanied this code).
+-#
+-# You should have received a copy of the GNU General Public License version
+-# 2 along with this work; if not, write to the Free Software Foundation,
+-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-#
+-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-# or visit www.oracle.com if you need additional information or have any
+-# questions.
+-#
+-
+-#
+-# The purpose of this script is to provide a large amount of IR/bytecode from a known
+-# application to be diffed against the same output with a different Nashorn version.
+-# That way we can quickly detect if a seemingly minute change modifies a lot of code,
+-# which it most likely shouldn't. One example of this was when AccessSpecializer was
+-# moved into Lower the first time, it worked fine, but as a lot of Scope information
+-# at the time was finalized further down the code pipeline it did a lot fewer callsite
+-# specializations. This would have been immediately detected with a before and after
+-# diff using the output from this script.
+-#
+-
+-ITERS=$1
+-if [ -z $ITERS ]; then
+- ITERS=7
+-fi
+-NASHORN_JAR=dist/nashorn.jar
+-JVM_FLAGS="-ea -esa -server -jar ${NASHORN_JAR}"
+-
+-BENCHMARKS=( "box2d.js" "code-load.js" "crypto.js" "deltablue.js" "earley-boyer.js" "gbemu.js" "mandreel.js" "navier-stokes.js" "pdfjs.js" "raytrace.js" "regexp.js" "richards.js" "splay.js" )
+-
+-for BENCHMARK in "${BENCHMARKS[@]}"
+-do
+- echo "START: ${BENCHMARK}"
+- CMD="${JAVA_HOME}/bin/java ${JVM_FLAGS} -co --print-lower-parse test/script/external/octane/${BENCHMARK}"
+- $CMD
+- echo "END: ${BENCHMARK}"
+- echo ""
+-done
+-
+-echo "Done"
+--- ./nashorn/bin/fixorphantests.sh Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,52 +0,0 @@
+-#!/bin/sh
+-#
+-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-#
+-# This code is free software; you can redistribute it and/or modify it
+-# under the terms of the GNU General Public License version 2 only, as
+-# published by the Free Software Foundation.
+-#
+-# This code is distributed in the hope that it will be useful, but WITHOUT
+-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-# version 2 for more details (a copy is included in the LICENSE file that
+-# accompanied this code).
+-#
+-# You should have received a copy of the GNU General Public License version
+-# 2 along with this work; if not, write to the Free Software Foundation,
+-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-#
+-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-# or visit www.oracle.com if you need additional information or have any
+-# questions.
+-#
+-
+-#ensure that all tests tagged with @test are also tagged with @run
+-
+-for f in $(find test/script/basic/*.js); do
+- grep @test $f >/dev/null
+- TEST=$?
+- grep @run $f >/dev/null
+- RUN=$?
+-
+- if [ $TEST -eq 0 ] && [ ! $RUN -eq 0 ]; then
+- echo "repairing ${f}..."
+- TEMP=$(mktemp /tmp/scratch.XXXXXX)
+-
+- #IFS='', -raw flag to preserve white space
+- while IFS='' read -r line; do
+- echo $line | grep @test >/dev/null
+- TEST=$?
+- printf "%s\n" "$line"
+- if [ $TEST -eq 0 ]; then
+- printf "%s\n" "$line" | sed s/@test/@run/g
+- fi
+- done < $f >$TEMP
+-
+- cp $TEMP $f
+-
+- rm -fr $TEMP
+- fi
+-
+-done
+--- ./nashorn/bin/fixwhitespace.sh Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/bin/fixwhitespace.sh Wed Feb 04 12:14:47 2015 -0800
+@@ -22,9 +22,16 @@
+ # questions.
+ #
+
+-#convert tabs to spaces
+-find . -name "*.java" -exec sed -i "" 's/ / /g' {} \;
++fix() {
++ #convert tabs to spaces
++ find . -name $1 -exec sed -i "" 's/ / /g' {} \;
++ #remove trailing whitespace
++ find . -name $1 -exec sed -i "" 's/[ ]*$//' \{} \;
++}
+
+-#remove trailing whitespace
+-find . -name "*.java" -exec sed -i "" 's/[ ]*$//' \{} \;
+-
++if [ ! -z $1 ]; then
++ fix $1;
++else
++ fix "*.java"
++ fix "*.js"
++fi
+--- ./nashorn/bin/jjs Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,29 +0,0 @@
+-#!/bin/bash
+-#
+-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-#
+-# This code is free software; you can redistribute it and/or modify it
+-# under the terms of the GNU General Public License version 2 only, as
+-# published by the Free Software Foundation. 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.
+-#
+-
+-[ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1;
+-
+-$JAVA_HOME/bin/java -server -XX:+TieredCompilation -Xms2G -Xmx2G -esa -ea -Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -XX:+HeapDumpOnOutOfMemoryError -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -Dnashorn.debug=true jdk.nashorn.tools.Shell $*
+--- ./nashorn/bin/jjs.bat Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,27 +0,0 @@
+-rem
+-rem Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+-rem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-rem
+-rem This code is free software; you can redistribute it and/or modify it
+-rem under the terms of the GNU General Public License version 2 only, as
+-rem published by the Free Software Foundation. Oracle designates this
+-rem particular file as subject to the "Classpath" exception as provided
+-rem by Oracle in the LICENSE file that accompanied this code.
+-rem
+-rem This code is distributed in the hope that it will be useful, but WITHOUT
+-rem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-rem FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-rem version 2 for more details (a copy is included in the LICENSE file that
+-rem accompanied this code).
+-rem
+-rem You should have received a copy of the GNU General Public License version
+-rem 2 along with this work; if not, write to the Free Software Foundation,
+-rem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-rem
+-rem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-rem or visit www.oracle.com if you need additional information or have any
+-rem questions.
+-rem
+-@echo off
+-
+-java -Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -Djava.ext.dirs=%~dp0\..\dist -XX:+HeapDumpOnOutOfMemoryError -Dnashorn.debug=true -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false jdk.nashorn.tools.Shell
+--- ./nashorn/bin/jjssecure Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,29 +0,0 @@
+-#!/bin/bash
+-#
+-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-#
+-# This code is free software; you can redistribute it and/or modify it
+-# under the terms of the GNU General Public License version 2 only, as
+-# published by the Free Software Foundation. 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.
+-#
+-
+-[ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1;
+-
+-$JAVA_HOME/bin/java -Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -Djava.security.properties=`dirname $0`/../make/java.security.override -Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -XX:+HeapDumpOnOutOfMemoryError -Dnashorn.debug=true -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=true -Dnashorn.home=`dirname $0`/.. -Djava.security.manager jdk.nashorn.tools.Shell $*
+--- ./nashorn/bin/jjssecure.bat Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,27 +0,0 @@
+-rem
+-rem Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+-rem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-rem
+-rem This code is free software; you can redistribute it and/or modify it
+-rem under the terms of the GNU General Public License version 2 only, as
+-rem published by the Free Software Foundation. Oracle designates this
+-rem particular file as subject to the "Classpath" exception as provided
+-rem by Oracle in the LICENSE file that accompanied this code.
+-rem
+-rem This code is distributed in the hope that it will be useful, but WITHOUT
+-rem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-rem FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-rem version 2 for more details (a copy is included in the LICENSE file that
+-rem accompanied this code).
+-rem
+-rem You should have received a copy of the GNU General Public License version
+-rem 2 along with this work; if not, write to the Free Software Foundation,
+-rem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-rem
+-rem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-rem or visit www.oracle.com if you need additional information or have any
+-rem questions.
+-rem
+-@echo off
+-
+-java -Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -Djava.security.properties=%~dp0\..\make\java.security.override -Djava.ext.dirs=%~dp0\..\dist -XX:+HeapDumpOnOutOfMemoryError -Dnashorn.debug=true -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -Dnashorn.home=%~dp0\.. -Djava.security.manager jdk.nashorn.tools.Shell
+--- ./nashorn/bin/nashorn Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,29 +0,0 @@
+-#!/bin/bash
+-#
+-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-#
+-# This code is free software; you can redistribute it and/or modify it
+-# under the terms of the GNU General Public License version 2 only, as
+-# published by the Free Software Foundation. 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.
+-#
+-
+-[ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1;
+-
+-$JAVA_HOME/bin/jrunscript -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -J-XX:+HeapDumpOnOutOfMemoryError -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -J-Dnashorn.debug=true -l nashorn $*
+--- ./nashorn/bin/nashorn.bat Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,27 +0,0 @@
+-rem
+-rem Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+-rem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-rem
+-rem This code is free software; you can redistribute it and/or modify it
+-rem under the terms of the GNU General Public License version 2 only, as
+-rem published by the Free Software Foundation. Oracle designates this
+-rem particular file as subject to the "Classpath" exception as provided
+-rem by Oracle in the LICENSE file that accompanied this code.
+-rem
+-rem This code is distributed in the hope that it will be useful, but WITHOUT
+-rem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-rem FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-rem version 2 for more details (a copy is included in the LICENSE file that
+-rem accompanied this code).
+-rem
+-rem You should have received a copy of the GNU General Public License version
+-rem 2 along with this work; if not, write to the Free Software Foundation,
+-rem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-rem
+-rem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-rem or visit www.oracle.com if you need additional information or have any
+-rem questions.
+-rem
+-@echo off
+-
+-jrunscript -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=%~dp0\..\dist -J-XX:+HeapDumpOnOutOfMemoryError -J-Dnashorn.debug=true -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -l nashorn
+--- ./nashorn/bin/nashornsecure Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,29 +0,0 @@
+-#!/bin/bash
+-#
+-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-#
+-# This code is free software; you can redistribute it and/or modify it
+-# under the terms of the GNU General Public License version 2 only, as
+-# published by the Free Software Foundation. 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.
+-#
+-
+-[ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1;
+-
+-$JAVA_HOME/bin/jrunscript -J-Djava.security.properties=`dirname $0`/../make/java.security.override -J-Djava.security.manager -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -J-XX:+HeapDumpOnOutOfMemoryError -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -J-Dnashorn.debug=true -l nashorn $*
+--- ./nashorn/bin/nashornsecure.bat Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,27 +0,0 @@
+-rem
+-rem Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+-rem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-rem
+-rem This code is free software; you can redistribute it and/or modify it
+-rem under the terms of the GNU General Public License version 2 only, as
+-rem published by the Free Software Foundation. Oracle designates this
+-rem particular file as subject to the "Classpath" exception as provided
+-rem by Oracle in the LICENSE file that accompanied this code.
+-rem
+-rem This code is distributed in the hope that it will be useful, but WITHOUT
+-rem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-rem FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-rem version 2 for more details (a copy is included in the LICENSE file that
+-rem accompanied this code).
+-rem
+-rem You should have received a copy of the GNU General Public License version
+-rem 2 along with this work; if not, write to the Free Software Foundation,
+-rem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-rem
+-rem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-rem or visit www.oracle.com if you need additional information or have any
+-rem questions.
+-rem
+-@echo off
+-
+-jrunscript -J-Djava.security.properties=%~dp0\..\make\java.security.override -J-Djava.security.manager -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=%~dp0\..\dist -J-XX:+HeapDumpOnOutOfMemoryError -J-Dnashorn.debug=true -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -l nashorn
+--- ./nashorn/bin/rm-non-tracked.sh Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,24 +0,0 @@
+-#!/bin/bash
+-#
+-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-#
+-# This code is free software; you can redistribute it and/or modify it
+-# under the terms of the GNU General Public License version 2 only, as
+-# published by the Free Software Foundation.
+-#
+-# This code is distributed in the hope that it will be useful, but WITHOUT
+-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-# version 2 for more details (a copy is included in the LICENSE file that
+-# accompanied this code).
+-#
+-# You should have received a copy of the GNU General Public License version
+-# 2 along with this work; if not, write to the Free Software Foundation,
+-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-#
+-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-# or visit www.oracle.com if you need additional information or have any
+-# questions.
+-#
+-hg status|grep ^\?|awk '{print $2}'|xargs rm
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/bin/runopt.sh Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,136 @@
++#!/bin/sh
++#
++# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++#
++# This code is free software; you can redistribute it and/or modify it
++# under the terms of the GNU General Public License version 2 only, as
++# published by the Free Software Foundation.
++#
++# This code is distributed in the hope that it will be useful, but WITHOUT
++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++# version 2 for more details (a copy is included in the LICENSE file that
++# accompanied this code).
++#
++# You should have received a copy of the GNU General Public License version
++# 2 along with this work; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++#
++# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++# or visit www.oracle.com if you need additional information or have any
++# questions.
++#
++
++###########################################################################################
++# This is a helper script to evaluate nashorn with optimistic types
++# it produces a flight recording for every run, and uses the best
++# known flags for performance for the current configration
++###########################################################################################
++
++# Flags to enable assertions, we need the system assertions too, since
++# this script runs Nashorn in the BCP to override any nashorn.jar that might
++# reside in your $JAVA_HOME/jre/lib/ext/nashorn.jar
++#
++ENABLE_ASSERTIONS_FLAGS="-ea -esa"
++
++# Flags to instrument lambdaform computation, caching, interpretation and compilation
++# Default compile threshold for lambdaforms is 30
++#
++#LAMBDAFORM_FLAGS="\
++# -Djava.lang.invoke.MethodHandle.COMPILE_THRESHOLD=3 \
++# -Djava.lang.invoke.MethodHandle.DUMP_CLASS_FILES=true \
++# -Djava.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE=true \
++# -Djava.lang.invoke.MethodHandle.TRACE_INTERPRETER=true"
++
++# Flags to run trusted tests from the Nashorn test suite
++#
++#TRUSTED_TEST_FLAGS="\
++#-Djava.security.manager \
++#-Djava.security.policy=../build/nashorn.policy -Dnashorn.debug"
++
++# Testing out new code optimizations using the generic hotspot "new code" parameter
++#
++#USE_NEW_CODE_FLAGS=-XX:+UnlockDiagnosticVMOptions -XX:+UseNewCode
++
++#
++#-Dnashorn.typeInfo.disabled=false \
++# and for Nashorn options:
++# --class-cache-size=0 --persistent-code-cache=false
++
++# Unique timestamped file name for JFR recordings. For JFR, we also have to
++# crank up the stack cutoff depth to 1024, because of ridiculously long lambda form
++# stack traces.
++#
++# It is also recommended that you go into $JAVA_HOME/jre/lib/jfr/default.jfc and
++# set the "method-sampling-interval" Normal and Maximum sample time as low as you
++# can go (10 ms on most platforms). The default is normally higher. The increased
++# sampling overhead is usually negligible for Nashorn runs, but the data is better
++
++if [ -z $JFR_FILENAME ]; then
++ JFR_FILENAME="./nashorn_$(date|sed "s/ /_/g"|sed "s/:/_/g").jfr"
++fi
++
++# Flight recorder
++#
++# see above - already in place, copy the flags down here to disable
++ENABLE_FLIGHT_RECORDER_FLAGS="\
++ -XX:+UnlockCommercialFeatures \
++ -XX:+FlightRecorder \
++ -XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath=$JFR_FILENAME,stackdepth=1024"
++
++# Type specialization and math intrinsic replacement should be enabled by default in 8u20 and nine,
++# keeping this flag around for experimental reasons. Replace + with - to switch it off
++#
++#ENABLE_TYPE_SPECIALIZATION_FLAGS=-XX:+UseTypeSpeculation
++
++# Same with math intrinsics. They should be enabled by default in 8u20 and 9, so
++# this disables them if needed
++#
++#DISABLE_MATH_INTRINSICS_FLAGS=-XX:-UseMathExactIntrinsics
++
++# Add timing to time the compilation phases.
++#ENABLE_TIME_FLAGS=--log=time
++
++# Add ShowHiddenFrames to get lambda form internals on the stack traces
++#ENABLE_SHOW_HIDDEN_FRAMES_FLAGS=-XX:+ShowHiddenFrames
++
++# Add print optoassembly to get an asm dump. This requires 1) a debug build, not product,
++# That tired compilation is switched off, for C2 only output and that the number of
++# compiler threads is set to 1 for determinsm.
++#
++#PRINT_ASM_FLAGS=-XX:+PrintOptoAssembly -XX:-TieredCompilation -XX:CICompilerCount=1 \
++
++# Tier compile threasholds. Default value is 10. (1-100 is useful for experiments)
++#TIER_COMPILATION_THRESHOLD_FLAGS=-XX:IncreaseFirstTierCompileThresholdAt=10
++
++# Directory where to look for nashorn.jar in a dist folder. The default is "..", assuming
++# that we run the script from the make dir
++DIR=..
++NASHORN_JAR=$DIR/dist/nashorn.jar
++
++
++# The built Nashorn jar is placed first in the bootclasspath to override the JDK
++# nashorn.jar in $JAVA_HOME/jre/lib/ext. Thus, we also need -esa, as assertions in
++# nashorn count as system assertions in this configuration
++
++# Type profiling default level is 111, 222 adds some compile time, but is faster
++
++$JAVA_HOME/bin/java \
++$ENABLE_ASSERTIONS_FLAGS \
++$LAMBDAFORM_FLAGS \
++$TRUSTED_FLAGS \
++$USE_NEW_CODE_FLAGS \
++$ENABLE_SHOW_HIDDEN_FRAMES_FLAGS \
++$ENABLE_FLIGHT_RECORDER_FLAGS \
++$ENABLE_TYPE_SPECIALIZATION_FLAGS \
++$TIERED_COMPILATION_THRESOLD_FLAGS \
++$DISABLE_MATH_INTRINSICS_FLAGS \
++$PRINT_ASM_FLAGS \
++-Xbootclasspath/p:$NASHORN_JAR \
++-Xms2G -Xmx2G \
++-XX:TypeProfileLevel=222 \
++-cp $CLASSPATH:../build/test/classes/ \
++jdk.nashorn.tools.Shell $ENABLE_TIME_FLAGS ${@}
++
++
+--- ./nashorn/bin/verbose_octane.bat Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,59 +0,0 @@
+-rem
+-rem Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+-rem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-rem
+-rem This code is free software; you can redistribute it and/or modify it
+-rem under the terms of the GNU General Public License version 2 only, as
+-rem published by the Free Software Foundation.
+-rem
+-rem This code is distributed in the hope that it will be useful, but WITHOUT
+-rem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-rem FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-rem version 2 for more details (a copy is included in the LICENSE file that
+-rem accompanied this code).
+-rem
+-rem You should have received a copy of the GNU General Public License version
+-rem 2 along with this work; if not, write to the Free Software Foundation,
+-rem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-rem
+-rem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-rem or visit www.oracle.com if you need additional information or have any
+-rem questions.
+-rem
+-@echo off
+-
+-if "%JAVA_HOME%" neq "" (
+- call :run "%JAVA_HOME%/bin/java"
+-) else (
+- call :run java
+-)
+-goto :EOF
+-
+-:run
+-setlocal
+-set NASHORN_JAR=dist/nashorn.jar
+-set JVM_FLAGS=-Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -jar %NASHORN_JAR%
+-set JVM_FLAGS7=-Xbootclasspath/p:%NASHORN_JAR% %JVM_FLAGS%
+-set OCTANE_ARGS=--verbose --iterations 7
+-
+-%1 -fullversion 2>&1 | findstr /L /C:"version ""1.7"
+-if %errorlevel% equ 0 (
+- set CMD=%1 %JVM_FLAGS7%
+-) else (
+- %1 -fullversion
+- set CMD=%1 %JVM_FLAGS%
+-)
+-
+-%CMD% test/script/basic/run-octane.js -- test/script/external/octane/box2d.js %OCTANE_ARGS%
+-%CMD% test/script/basic/run-octane.js -- test/script/external/octane/code-load.js %OCTANE_ARGS%
+-%CMD% test/script/basic/run-octane.js -- test/script/external/octane/crypto.js %OCTANE_ARGS%
+-%CMD% test/script/basic/run-octane.js -- test/script/external/octane/deltablue.js %OCTANE_ARGS%
+-%CMD% test/script/basic/run-octane.js -- test/script/external/octane/gbemu.js %OCTANE_ARGS%
+-%CMD% test/script/basic/run-octane.js -- test/script/external/octane/navier-stokes.js %OCTANE_ARGS%
+-%CMD% test/script/basic/run-octane.js -- test/script/external/octane/pdfjs.js %OCTANE_ARGS%
+-%CMD% test/script/basic/run-octane.js -- test/script/external/octane/raytrace.js %OCTANE_ARGS%
+-%CMD% test/script/basic/run-octane.js -- test/script/external/octane/regexp.js %OCTANE_ARGS%
+-%CMD% test/script/basic/run-octane.js -- test/script/external/octane/richards.js %OCTANE_ARGS%
+-%CMD% test/script/basic/run-octane.js -- test/script/external/octane/splay.js %OCTANE_ARGS%
+-endlocal
+-goto :EOF
+--- ./nashorn/bin/verbose_octane.sh Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,58 +0,0 @@
+-#!/bin/bash
+-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-#
+-# This code is free software; you can redistribute it and/or modify it
+-# under the terms of the GNU General Public License version 2 only, as
+-# published by the Free Software Foundation.
+-#
+-# This code is distributed in the hope that it will be useful, but WITHOUT
+-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+-# version 2 for more details (a copy is included in the LICENSE file that
+-# accompanied this code).
+-#
+-# You should have received a copy of the GNU General Public License version
+-# 2 along with this work; if not, write to the Free Software Foundation,
+-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-#
+-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+-# or visit www.oracle.com if you need additional information or have any
+-# questions.
+-#
+-
+-ITERS=$1
+-if [ -z $ITERS ]; then
+- ITERS=7
+-fi
+-NASHORN_JAR=dist/nashorn.jar
+-JVM_FLAGS="-Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -XX:+UnlockDiagnosticVMOptions -Dnashorn.unstable.relink.threshold=8 -Xms2G -Xmx2G -XX:+TieredCompilation -server -jar ${NASHORN_JAR}"
+-JVM_FLAGS7="-Xbootclasspath/p:${NASHORN_JAR} ${JVM_FLAGS}"
+-OCTANE_ARGS="--verbose --iterations ${ITERS}"
+-
+-BENCHMARKS=( "box2d.js" "code-load.js" "crypto.js" "deltablue.js" "earley-boyer.js" "gbemu.js" "navier-stokes.js" "pdfjs.js" "raytrace.js" "regexp.js" "richards.js" "splay.js" )
+-# TODO mandreel.js has metaspace issues
+-
+-if [ ! -z $JAVA7_HOME ]; then
+- echo "running ${ITERS} iterations with java7 using JAVA_HOME=${JAVA7_HOME}..."
+- for BENCHMARK in "${BENCHMARKS[@]}"
+- do
+- CMD="${JAVA7_HOME}/bin/java ${JVM_FLAGS} test/script/basic/run-octane.js -- test/script/external/octane/${BENCHMARK} ${OCTANE_ARGS}"
+- $CMD
+- done
+-else
+- echo "no JAVA7_HOME set. skipping java7"
+-fi
+-
+-if [ ! -z $JAVA8_HOME ]; then
+- echo "running ${ITERS} iterations with java8 using JAVA_HOME=${JAVA8_HOME}..."
+- for BENCHMARK in "${BENCHMARKS[@]}"
+- do
+- CMD="${JAVA8_HOME}/bin/java ${JVM_FLAGS} test/script/basic/run-octane.js -- test/script/external/octane/${BENCHMARK} ${OCTANE_ARGS}"
+- $CMD
+- done
+-else
+- echo "no JAVA8_HOME set."
+-fi
+-
+-echo "Done"
+--- ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -31,29 +31,29 @@
+ import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC;
+ import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC;
+ import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKEVIRTUAL;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE_DESC;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_TYPE;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_INIT_DESC;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_TYPE;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.CLINIT;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_EMPTY_LIST;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_TYPE;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD_DESC;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_TYPE;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.GETTER_PREFIX;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
+-import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE;
+-import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE_DESC;
+-import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_TYPE;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.LIST_DESC;
+-import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_TYPE;
+-import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_INIT_DESC;
+-import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_TYPE;
+-import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD;
+-import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD_DESC;
+-import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_TYPE;
+-import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_EMPTY_LIST;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
+-import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC;
+@@ -292,7 +292,6 @@
+ mi.push(memInfo.getArity());
+ mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETARITY, SCRIPTFUNCTION_SETARITY_DESC);
+ }
+-
+ }
+
+ static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo memInfo) {
+--- ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -32,9 +32,9 @@
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.CONSTRUCTOR_SUFFIX;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME;
+-import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE;
+--- ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,7 +28,6 @@
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.STRING_DESC;
+-
+ import jdk.internal.org.objectweb.asm.Opcodes;
+ import jdk.internal.org.objectweb.asm.Type;
+ import jdk.nashorn.internal.objects.annotations.Where;
+@@ -75,10 +74,6 @@
+ * This is a specialized version of a function
+ */
+ SPECIALIZED_FUNCTION,
+- /**
+- * This is a specialized version of a constructor
+- */
+- SPECIALIZED_CONSTRUCTOR
+ }
+
+ // keep in sync with jdk.nashorn.internal.objects.annotations.Attribute
+@@ -107,6 +102,12 @@
+
+ private Where where;
+
++ private Type linkLogicClass;
++
++ private boolean isSpecializedConstructor;
++
++ private boolean isOptimistic;
++
+ /**
+ * @return the kind
+ */
+@@ -136,6 +137,57 @@
+ }
+
+ /**
++ * Tag something as specialized constructor or not
++ * @param isSpecializedConstructor boolean, true if specialized constructor
++ */
++ public void setIsSpecializedConstructor(final boolean isSpecializedConstructor) {
++ this.isSpecializedConstructor = isSpecializedConstructor;
++ }
++
++ /**
++ * Check if something is a specialized constructor
++ * @return true if specialized constructor
++ */
++ public boolean isSpecializedConstructor() {
++ return isSpecializedConstructor;
++ }
++
++ /**
++ * Check if this is an optimistic builtin function
++ * @return true if optimistic builtin
++ */
++ public boolean isOptimistic() {
++ return isOptimistic;
++ }
++
++ /**
++ * Tag something as optimitic builtin or not
++ * @param isOptimistic boolean, true if builtin constructor
++ */
++ public void setIsOptimistic(final boolean isOptimistic) {
++ this.isOptimistic = isOptimistic;
++ }
++
++ /**
++ * Get the SpecializedFunction guard for specializations, i.e. optimistic
++ * builtins
++ * @return specialization, null if none
++ */
++ public Type getLinkLogicClass() {
++ return linkLogicClass;
++ }
++
++ /**
++ * Set thre SpecializedFunction link logic class for specializations, i.e. optimistic
++ * builtins
++ * @param linkLogicClass link logic class
++ */
++
++ public void setLinkLogicClass(final Type linkLogicClass) {
++ this.linkLogicClass = linkLogicClass;
++ }
++
++ /**
+ * @return the attributes
+ */
+ public int getAttributes() {
+@@ -304,22 +356,9 @@
+ }
+ }
+ break;
+- case SPECIALIZED_CONSTRUCTOR: {
+- final Type returnType = Type.getReturnType(javaDesc);
+- if (!isJSObjectType(returnType)) {
+- error("return value of a @SpecializedConstructor method should be a valid JS type, found " + returnType);
+- }
+- final Type[] argTypes = Type.getArgumentTypes(javaDesc);
+- for (int i = 0; i < argTypes.length; i++) {
+- if (!isValidJSType(argTypes[i])) {
+- error(i + "'th argument of a @SpecializedConstructor method is not valid JS type, found " + argTypes[i]);
+- }
+- }
+- }
+- break;
+ case FUNCTION: {
+ final Type returnType = Type.getReturnType(javaDesc);
+- if (!isValidJSType(returnType)) {
++ if (!(isValidJSType(returnType) || Type.VOID_TYPE == returnType)) {
+ error("return value of a @Function method should be a valid JS type, found " + returnType);
+ }
+ final Type[] argTypes = Type.getArgumentTypes(javaDesc);
+@@ -351,7 +390,7 @@
+ break;
+ case SPECIALIZED_FUNCTION: {
+ final Type returnType = Type.getReturnType(javaDesc);
+- if (!isValidJSType(returnType)) {
++ if (!(isValidJSType(returnType) || (isSpecializedConstructor() && Type.VOID_TYPE == returnType))) {
+ error("return value of a @SpecializedFunction method should be a valid JS type, found " + returnType);
+ }
+ final Type[] argTypes = Type.getArgumentTypes(javaDesc);
+@@ -371,9 +410,8 @@
+ error("first argument of a @Getter method should be of Object type, found: " + argTypes[0]);
+ }
+
+- final Type returnType = Type.getReturnType(javaDesc);
+- if (!isJavaLangObject(returnType)) {
+- error("return type of a @Getter method should be Object, found: " + javaDesc);
++ if (Type.getReturnType(javaDesc).equals(Type.VOID_TYPE)) {
++ error("return type of getter should not be void");
+ }
+ }
+ break;
+@@ -413,6 +451,10 @@
+ }
+ }
+ }
++ break;
++
++ default:
++ break;
+ }
+ }
+
+@@ -451,7 +493,7 @@
+
+ if (type.getSort() == Type.OBJECT) {
+ try {
+- final Class clazz = Class.forName(type.getClassName(), false, myLoader);
++ final Class<?> clazz = Class.forName(type.getClassName(), false, myLoader);
+ return ScriptObject.class.isAssignableFrom(clazz);
+ } catch (final ClassNotFoundException cnfe) {
+ return false;
+--- ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -56,6 +56,7 @@
+ import static jdk.internal.org.objectweb.asm.Opcodes.IALOAD;
+ import static jdk.internal.org.objectweb.asm.Opcodes.IASTORE;
+ import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_0;
++import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_1;
+ import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD;
+ import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEINTERFACE;
+ import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL;
+@@ -76,13 +77,16 @@
+ import static jdk.internal.org.objectweb.asm.Opcodes.SASTORE;
+ import static jdk.internal.org.objectweb.asm.Opcodes.SIPUSH;
+ import static jdk.internal.org.objectweb.asm.Opcodes.SWAP;
+-import static jdk.nashorn.internal.tools.nasgen.StringConstants.METHODHANDLE_TYPE;
+-import static jdk.nashorn.internal.tools.nasgen.StringConstants.TYPE_METHODHANDLE;
+-
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.SPECIALIZATION_INIT2;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.SPECIALIZATION_INIT3;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.SPECIALIZATION_TYPE;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.TYPE_SPECIALIZATION;
+ import java.util.List;
+ import jdk.internal.org.objectweb.asm.Handle;
+ import jdk.internal.org.objectweb.asm.MethodVisitor;
+ import jdk.internal.org.objectweb.asm.Type;
++import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
+
+ /**
+ * Base class for all method generating classes.
+@@ -95,6 +99,8 @@
+ private final Type returnType;
+ private final Type[] argumentTypes;
+
++ static final Type EMPTY_LINK_LOGIC_TYPE = Type.getType(LinkLogic.getEmptyLinkLogicClass());
++
+ MethodGenerator(final MethodVisitor mv, final int access, final String name, final String descriptor) {
+ super(ASM4, mv);
+ this.access = access;
+@@ -380,6 +386,11 @@
+ super.visitFieldInsn(GETFIELD, owner, field, desc);
+ }
+
++ private static boolean linkLogicIsEmpty(final Type type) {
++ assert EMPTY_LINK_LOGIC_TYPE != null; //type is ok for null if we are a @SpecializedFunction without any attribs
++ return EMPTY_LINK_LOGIC_TYPE.equals(type);
++ }
++
+ void memberInfoArray(final String className, final List<MemberInfo> mis) {
+ if (mis.isEmpty()) {
+ pushNull();
+@@ -388,12 +399,22 @@
+
+ int pos = 0;
+ push(mis.size());
+- newObjectArray(METHODHANDLE_TYPE);
++ newObjectArray(SPECIALIZATION_TYPE);
+ for (final MemberInfo mi : mis) {
+ dup();
+ push(pos++);
++ visitTypeInsn(NEW, SPECIALIZATION_TYPE);
++ dup();
+ visitLdcInsn(new Handle(H_INVOKESTATIC, className, mi.getJavaName(), mi.getJavaDesc()));
+- arrayStore(TYPE_METHODHANDLE);
++ final Type linkLogicClass = mi.getLinkLogicClass();
++ final boolean linkLogic = !linkLogicIsEmpty(linkLogicClass);
++ final String ctor = linkLogic ? SPECIALIZATION_INIT3 : SPECIALIZATION_INIT2;
++ if (linkLogic) {
++ visitLdcInsn(linkLogicClass);
++ }
++ visitInsn(mi.isOptimistic() ? ICONST_1 : ICONST_0);
++ visitMethodInsn(INVOKESPECIAL, SPECIALIZATION_TYPE, INIT, ctor, false);
++ arrayStore(TYPE_SPECIALIZATION);
+ }
+ }
+
+@@ -413,7 +434,8 @@
+ super.visitMethodInsn(INVOKEVIRTUAL,
+ "java/io/PrintStream",
+ "println",
+- "(Ljava/lang/String;)V", false);
++ "(Ljava/lang/String;)V",
++ false);
+ }
+
+ // print the object on the top of the stack
+@@ -426,6 +448,7 @@
+ super.visitMethodInsn(INVOKEVIRTUAL,
+ "java/io/PrintStream",
+ "println",
+- "(Ljava/lang/Object;)V", false);
++ "(Ljava/lang/Object;)V",
++ false);
+ }
+ }
+--- ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -31,9 +31,9 @@
+ import static jdk.internal.org.objectweb.asm.Opcodes.V1_7;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
++import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME;
+-import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPE_SUFFIX;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_INIT_DESC;
+--- ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java Wed Feb 04 12:14:47 2015 -0800
+@@ -37,8 +37,8 @@
+ import jdk.nashorn.internal.objects.annotations.Property;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+ import jdk.nashorn.internal.objects.annotations.Setter;
+-import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
+ import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
++import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
+ import jdk.nashorn.internal.objects.annotations.Where;
+ import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind;
+
+@@ -56,8 +56,8 @@
+ static final String SETTER_ANNO_DESC = Type.getDescriptor(Setter.class);
+ static final String PROPERTY_ANNO_DESC = Type.getDescriptor(Property.class);
+ static final String WHERE_ENUM_DESC = Type.getDescriptor(Where.class);
++ static final String LINK_LOGIC_DESC = Type.getDescriptor(LinkLogic.class);
+ static final String SPECIALIZED_FUNCTION = Type.getDescriptor(SpecializedFunction.class);
+- static final String SPECIALIZED_CONSTRUCTOR = Type.getDescriptor(SpecializedConstructor.class);
+
+ static final Map<String, Kind> annotations = new HashMap<>();
+
+@@ -69,7 +69,6 @@
+ annotations.put(SETTER_ANNO_DESC, Kind.SETTER);
+ annotations.put(PROPERTY_ANNO_DESC, Kind.PROPERTY);
+ annotations.put(SPECIALIZED_FUNCTION, Kind.SPECIALIZED_FUNCTION);
+- annotations.put(SPECIALIZED_CONSTRUCTOR, Kind.SPECIALIZED_CONSTRUCTOR);
+ }
+
+ // name of the script class
+@@ -119,11 +118,12 @@
+ List<MemberInfo> getSpecializedConstructors() {
+ final List<MemberInfo> res = new LinkedList<>();
+ for (final MemberInfo memInfo : members) {
+- if (memInfo.getKind() == Kind.SPECIALIZED_CONSTRUCTOR) {
++ if (memInfo.isSpecializedConstructor()) {
++ assert memInfo.getKind() == Kind.SPECIALIZED_FUNCTION;
+ res.add(memInfo);
+ }
+ }
+- return res;
++ return Collections.unmodifiableList(res);
+ }
+
+ int getPrototypeMemberCount() {
+@@ -175,7 +175,7 @@
+ res.add(memInfo);
+ }
+ }
+- return res;
++ return Collections.unmodifiableList(res);
+ }
+
+ MemberInfo findSetter(final MemberInfo getter) {
+--- ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,7 +27,6 @@
+
+ import static jdk.nashorn.internal.tools.nasgen.ScriptClassInfo.SCRIPT_CLASS_ANNO_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.ScriptClassInfo.WHERE_ENUM_DESC;
+-
+ import java.io.BufferedInputStream;
+ import java.io.FileInputStream;
+ import java.io.IOException;
+@@ -41,6 +40,7 @@
+ import jdk.internal.org.objectweb.asm.FieldVisitor;
+ import jdk.internal.org.objectweb.asm.MethodVisitor;
+ import jdk.internal.org.objectweb.asm.Opcodes;
++import jdk.internal.org.objectweb.asm.Type;
+ import jdk.nashorn.internal.objects.annotations.Where;
+ import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind;
+
+@@ -194,6 +194,7 @@
+
+ final MemberInfo memInfo = new MemberInfo();
+
++ //annokind == e.g. GETTER or SPECIALIZED_FUNCTION
+ memInfo.setKind(annoKind);
+ memInfo.setJavaName(methodName);
+ memInfo.setJavaDesc(methodDesc);
+@@ -208,12 +209,18 @@
+ private Integer attributes;
+ private Integer arity;
+ private Where where;
++ private boolean isSpecializedConstructor;
++ private boolean isOptimistic;
++ private Type linkLogicClass = MethodGenerator.EMPTY_LINK_LOGIC_TYPE;
+
+ @Override
+ public void visit(final String annotationName, final Object annotationValue) {
+ switch (annotationName) {
+ case "name":
+ this.name = (String)annotationValue;
++ if (name.isEmpty()) {
++ name = null;
++ }
+ break;
+ case "attributes":
+ this.attributes = (Integer)annotationValue;
+@@ -221,6 +228,17 @@
+ case "arity":
+ this.arity = (Integer)annotationValue;
+ break;
++ case "isConstructor":
++ assert annoKind == Kind.SPECIALIZED_FUNCTION;
++ this.isSpecializedConstructor = (Boolean)annotationValue;
++ break;
++ case "isOptimistic":
++ assert annoKind == Kind.SPECIALIZED_FUNCTION;
++ this.isOptimistic = (Boolean)annotationValue;
++ break;
++ case "linkLogic":
++ this.linkLogicClass = (Type)annotationValue;
++ break;
+ default:
+ break;
+ }
+@@ -230,12 +248,19 @@
+
+ @Override
+ public void visitEnum(final String enumName, final String desc, final String enumValue) {
+- if ("where".equals(enumName) && WHERE_ENUM_DESC.equals(desc)) {
+- this.where = Where.valueOf(enumValue);
++ switch (enumName) {
++ case "where":
++ if (WHERE_ENUM_DESC.equals(desc)) {
++ this.where = Where.valueOf(enumValue);
++ }
++ break;
++ default:
++ break;
+ }
+ super.visitEnum(enumName, desc, enumValue);
+ }
+
++ @SuppressWarnings("fallthrough")
+ @Override
+ public void visitEnd() {
+ super.visitEnd();
+@@ -256,7 +281,6 @@
+ case SETTER:
+ where = Where.INSTANCE;
+ break;
+- case SPECIALIZED_CONSTRUCTOR:
+ case CONSTRUCTOR:
+ where = Where.CONSTRUCTOR;
+ break;
+@@ -264,12 +288,18 @@
+ where = Where.PROTOTYPE;
+ break;
+ case SPECIALIZED_FUNCTION:
+- //TODO is this correct
++ if (isSpecializedConstructor) {
++ where = Where.CONSTRUCTOR;
++ }
++ //fallthru
+ default:
+ break;
+ }
+ }
+ memInfo.setWhere(where);
++ memInfo.setLinkLogicClass(linkLogicClass);
++ memInfo.setIsSpecializedConstructor(isSpecializedConstructor);
++ memInfo.setIsOptimistic(isOptimistic);
+ }
+ };
+ }
+--- ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -38,7 +38,6 @@
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
+ import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_TYPE;
+-
+ import java.io.BufferedInputStream;
+ import java.io.FileInputStream;
+ import java.io.FileOutputStream;
+--- ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,9 +26,8 @@
+ package jdk.nashorn.internal.tools.nasgen;
+
+ import java.lang.invoke.MethodHandle;
+-import java.lang.reflect.Method;
++import java.util.ArrayList;
+ import java.util.Collection;
+-import java.util.ArrayList;
+ import java.util.Collections;
+ import java.util.List;
+ import jdk.internal.org.objectweb.asm.Type;
+@@ -38,6 +37,7 @@
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptObject;
++import jdk.nashorn.internal.runtime.Specialization;
+
+ /**
+ * String constants used for code generation/instrumentation.
+@@ -45,20 +45,26 @@
+ @SuppressWarnings("javadoc")
+ public interface StringConstants {
+ // standard jdk types, methods
+- static final Type TYPE_METHODHANDLE = Type.getType(MethodHandle.class);
+- static final Type TYPE_METHODHANDLE_ARRAY = Type.getType(MethodHandle[].class);
+- static final Type TYPE_OBJECT = Type.getType(Object.class);
+- static final Type TYPE_STRING = Type.getType(String.class);
+- static final Type TYPE_COLLECTION = Type.getType(Collection.class);
+- static final Type TYPE_COLLECTIONS = Type.getType(Collections.class);
+- static final Type TYPE_ARRAYLIST = Type.getType(ArrayList.class);
+- static final Type TYPE_LIST = Type.getType(List.class);
++ static final Type TYPE_METHODHANDLE = Type.getType(MethodHandle.class);
++ static final Type TYPE_METHODHANDLE_ARRAY = Type.getType(MethodHandle[].class);
++ static final Type TYPE_SPECIALIZATION = Type.getType(Specialization.class);
++ static final Type TYPE_SPECIALIZATION_ARRAY = Type.getType(Specialization[].class);
++ static final Type TYPE_OBJECT = Type.getType(Object.class);
++ static final Type TYPE_STRING = Type.getType(String.class);
++ static final Type TYPE_CLASS = Type.getType(Class.class);
++ static final Type TYPE_COLLECTION = Type.getType(Collection.class);
++ static final Type TYPE_COLLECTIONS = Type.getType(Collections.class);
++ static final Type TYPE_ARRAYLIST = Type.getType(ArrayList.class);
++ static final Type TYPE_LIST = Type.getType(List.class);
+
+ static final String CLINIT = "<clinit>";
+ static final String INIT = "<init>";
+ static final String DEFAULT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE);
+
+ static final String METHODHANDLE_TYPE = TYPE_METHODHANDLE.getInternalName();
++ static final String SPECIALIZATION_TYPE = TYPE_SPECIALIZATION.getInternalName();
++ static final String SPECIALIZATION_INIT2 = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_METHODHANDLE, Type.getType(boolean.class));
++ static final String SPECIALIZATION_INIT3 = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_METHODHANDLE, TYPE_CLASS, Type.getType(boolean.class));
+ static final String OBJECT_TYPE = TYPE_OBJECT.getInternalName();
+ static final String OBJECT_DESC = TYPE_OBJECT.getDescriptor();
+ static final String STRING_TYPE = TYPE_STRING.getInternalName();
+@@ -123,11 +129,11 @@
+ static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC =
+ Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE);
+ static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC =
+- Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE, TYPE_METHODHANDLE_ARRAY);
++ Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE, TYPE_SPECIALIZATION_ARRAY);
+ static final String SCRIPTFUNCTIONIMPL_INIT_DESC3 =
+- Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_METHODHANDLE_ARRAY);
++ Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_SPECIALIZATION_ARRAY);
+ static final String SCRIPTFUNCTIONIMPL_INIT_DESC4 =
+- Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_PROPERTYMAP, TYPE_METHODHANDLE_ARRAY);
++ Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_PROPERTYMAP, TYPE_SPECIALIZATION_ARRAY);
+
+ // ScriptObject
+ static final String SCRIPTOBJECT_TYPE = TYPE_SCRIPTOBJECT.getInternalName();
+--- ./nashorn/docs/DEVELOPER_README Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/DEVELOPER_README Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,14 @@
+ > java -Dnashorn.args="--lazy-complation --log=compiler" large-java-app-with-nashorn.jar
+ > ant -Dnashorn.args="--log=codegen" antjob
+
++SYSTEM PROPERTY: -Dnashorn.args.prepend=<string>
++
++This property behaves like nashorn.args, but adds the given arguments
++before the existing ones instead of after them. Later arguments will
++overwrite earlier ones, so this is useful for setting default arguments
++that can be overwritten.
++
++
+ SYSTEM PROPERTY: -Dnashorn.unstable.relink.threshold=x
+
+ This property controls how many call site misses are allowed before a
+@@ -42,533 +50,38 @@
+ The default value is 0x8000 (32768).
+
+
+-SYSTEM PROPERTY: -Dnashorn.compiler.intarithmetic
++SYSTEM PROPERTY: -Dnashorn.serialize.compression=<x>
+
+-(and integer arithmetic in general)
++This property sets the compression level used when deflating serialized
++AST structures of anonymous split functions. Valid values range from 0 to 9,
++the default value is 4. Higher values will reduce memory size of serialized
++AST but increase CPU usage required for compression.
+
+-<currently disabled - this is being refactored for update releases>
+
+-Arithmetic operations in Nashorn (except bitwise ones) typically
+-coerce the operands to doubles (as per the JavaScript spec). To switch
+-this off and remain in integer mode, for example for "var x = a&b; var
+-y = c&d; var z = x*y;", use this flag. This will force the
+-multiplication of variables that are ints to be done with the IMUL
+-bytecode and the result "z" to become an int.
+-
+-WARNING: Note that is is experimental only to ensure that type support
+-exists for all primitive types. The generated code is unsound. This
+-will be the case until we do optimizations based on it. There is a CR
+-in Nashorn to do better range analysis, and ensure that this is only
+-done where the operation can't overflow into a wider type. Currently
+-no overflow checking is done, so at the moment, until range analysis
+-has been completed, this option is turned off.
+-
+-We've experimented by using int arithmetic for everything and putting
+-overflow checks afterwards, which would recompute the operation with
+-the correct precision, but have yet to find a configuration where this
+-is faster than just using doubles directly, even if the int operation
+-does not overflow. Getting access to a JVM intrinsic that does branch
+-on overflow would probably alleviate this.
+-
+-The future:
+-
+-We are transitioning to an optimistic type system that uses int
+-arithmetic everywhere until proven wrong. The problem here is mostly
+-catch an overflow exception and rolling back the state to a new method
+-with less optimistic assumptions for an operation at a particular
+-program point. This will most likely not be in the Java 8.0 release
+-but likely end up in an update release
+-
+-For Java 8, several java.lang.Math methods like addExact, subExact and
+-mulExact are available to help us. Experiments intrinsifying these
+-show a lot of promise, and we have devised a system that basically
+-does on stack replacement with exceptions in bytecode to revert
+-erroneous assumptions. An explanation of how this works and what we
+-are doing can be found here:
+-http://www.slideshare.net/lagergren/lagergren-jvmls2013final
+-
+-Experiments with this show significant ~x2-3 performance increases on
+-pretty much everything, provided that optimistic assumptions don't
+-fail much. It will affect warmup time negatively, depending on how
+-many erroneous too optimistic assumptions are placed in the code at
+-compile time. We don't think this will be much of an issue.
+-
+-For example for a small benchmark that repeatedly executes this
+-method taken from the Crypto Octane benchmark
+-
+-function am3(i,x,w,j,c,n) {
+- var this_array = this.array;
+- var w_array = w.array;
+- var xl = x&0x3fff, xh = x>>14;
+- while(--n >= 0) {
+- var l = this_array[i]&0x3fff;
+- var h = this_array[i++]>>14;
+- var m = xh*l+h*xl;
+- l = xl*l+((m&0x3fff)<<14)+w_array[j]+c;
+- c = (l>>28)+(m>>14)+xh*h;
+- w_array[j++] = l&0xfffffff;
+- }
+-
+- return c;
+-}
+-
+-The performance increase more than doubles. We are also working hard
+-with the code generation team in the Java Virtual Machine to fix
+-things that are lacking in invokedynamic performance, which is another
+-area where a lot of ongoing performance work takes place
+-
+-"Pessimistic" bytecode for am3, guaranteed to be semantically correct:
+-
+-// access flags 0x9
+- public static am3(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+- L0
+- LINENUMBER 12 L0
+- ALOAD 0
+- INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
+- // handle kind 0x6 : INVOKESTATIC
+- jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+- // arguments:
+- 0
+- ]
+- ASTORE 8
+- L1
+- LINENUMBER 13 L1
+- ALOAD 3
+- INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
+- // handle kind 0x6 : INVOKESTATIC
+- jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+- // arguments:
+- 0
+- ]
+- ASTORE 9
+- L2
+- LINENUMBER 14 L2
+- ALOAD 2
+- INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
+- SIPUSH 16383
+- IAND
+- ISTORE 10
+- ALOAD 2
+- INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
+- BIPUSH 14
+- ISHR
+- ISTORE 11
+- L3
+- LINENUMBER 15 L3
+- GOTO L4
+- L5
+- LINENUMBER 16 L5
+- FRAME FULL [java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Double T java/lang/Object java/lang/Object I I] []
+- ALOAD 8
+- ALOAD 1
+- INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;Ljava/lang/Object;)I [
+- // handle kind 0x6 : INVOKESTATIC
+- jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+- // arguments:
+- 0
+- ]
+- SIPUSH 16383
+- IAND
+- INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
+- ASTORE 12
+- L6
+- LINENUMBER 17 L6
+- ALOAD 8
+- ALOAD 1
+- INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
+- DUP2
+- DCONST_1
+- DADD
+- INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
+- ASTORE 1
+- INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;D)I [
+- // handle kind 0x6 : INVOKESTATIC
+- jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+- // arguments:
+- 0
+- ]
+- BIPUSH 14
+- ISHR
+- ISTORE 13
+- L7
+- LINENUMBER 18 L7
+- ILOAD 11
+- I2D
+- ALOAD 12
+- INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
+- DMUL
+- ILOAD 13
+- I2D
+- ILOAD 10
+- I2D
+- DMUL
+- DADD
+- DSTORE 14
+- L8
+- LINENUMBER 19 L8
+- ILOAD 10
+- I2D
+- ALOAD 12
+- INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
+- DMUL
+- DLOAD 14
+- INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (D)I
+- SIPUSH 16383
+- IAND
+- BIPUSH 14
+- ISHL
+- I2D
+- DADD
+- ALOAD 9
+- ALOAD 4
+- INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; [
+- // handle kind 0x6 : INVOKESTATIC
+- jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+- // arguments:
+- 0
+- ]
+- INVOKEDYNAMIC ADD:ODO_D(DLjava/lang/Object;)Ljava/lang/Object; [
+- // handle kind 0x6 : INVOKESTATIC
+- jdk/nashorn/internal/runtime/linker/Bootstrap.runtimeBootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;)
+- // arguments: none
+- ]
+- ALOAD 5
+- INVOKEDYNAMIC ADD:OOO_I(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; [
+- // handle kind 0x6 : INVOKESTATIC
+- jdk/nashorn/internal/runtime/linker/Bootstrap.runtimeBootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;)
+- // arguments: none
+- ]
+- ASTORE 12
+- L9
+- LINENUMBER 20 L9
+- ALOAD 12
+- INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
+- BIPUSH 28
+- ISHR
+- I2D
+- DLOAD 14
+- INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (D)I
+- BIPUSH 14
+- ISHR
+- I2D
+- DADD
+- ILOAD 11
+- I2D
+- ILOAD 13
+- I2D
+- DMUL
+- DADD
+- INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
+- ASTORE 5
+- L10
+- LINENUMBER 21 L10
+- ALOAD 9
+- ALOAD 4
+- INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
+- DUP2
+- DCONST_1
+- DADD
+- INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
+- ASTORE 4
+- ALOAD 12
+- INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
+- LDC 268435455
+- IAND
+- INVOKEDYNAMIC dyn:setElem|setProp(Ljava/lang/Object;DI)V [
+- // handle kind 0x6 : INVOKESTATIC
+- jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+- // arguments:
+- 0
+- ]
+- L4
+- FRAME FULL [java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object T java/lang/Object java/lang/Object I I] []
+- ALOAD 6
+- INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
+- LDC -1.0
+- DADD
+- DUP2
+- INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
+- ASTORE 6
+- DCONST_0
+- DCMPL
+- IFGE L5
+- L11
+- LINENUMBER 24 L11
+- ALOAD 5
+- ARETURN
+-
+-"Optimistic" bytecode that requires invalidation on e.g overflow. Factor
+-x2-3 speedup:
+-
+-public static am3(Ljava/lang/Object;IILjava/lang/Object;III)I
+- L0
+- LINENUMBER 12 L0
+- ALOAD 0
+- INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
+- // handle kind 0x6 : INVOKESTATIC
+- jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+- // arguments:
+- 0
+- ]
+- ASTORE 8
+- L1
+- LINENUMBER 13 L1
+- ALOAD 3
+- INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
+- // handle kind 0x6 : INVOKESTATIC
+- jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+- // arguments:
+- 0
+- ]
+- ASTORE 9
+- L2
+- LINENUMBER 14 L2
+- ILOAD 2
+- SIPUSH 16383
+- IAND
+- ISTORE 10
+- ILOAD 2
+- BIPUSH 14
+- ISHR
+- ISTORE 11
+- L3
+- LINENUMBER 15 L3
+- GOTO L4
+- L5
+- LINENUMBER 16 L5
+- FRAME FULL [java/lang/Object I I java/lang/Object I I I T java/lang/Object java/lang/Object I I] []
+- ALOAD 8
+- ILOAD 1
+- INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [
+- // handle kind 0x6 : INVOKESTATIC
+- jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+- // arguments:
+- 0
+- ]
+- SIPUSH 16383
+- IAND
+- ISTORE 12
+- L6
+- LINENUMBER 17 L6
+- ALOAD 8
+- ILOAD 1
+- DUP
+- ICONST_1
+- IADD
+- ISTORE 1
+- INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [
+- // handle kind 0x6 : INVOKESTATIC
+- jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+- // arguments:
+- 0
+- ]
+- BIPUSH 14
+- ISHR
+- ISTORE 13
+- L7
+- LINENUMBER 18 L7
+- ILOAD 11
+- ILOAD 12
+- BIPUSH 8
+- INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
+- ILOAD 13
+- ILOAD 10
+- BIPUSH 9
+- INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
+- IADD
+- ISTORE 14
+- L8
+- LINENUMBER 19 L8
+- ILOAD 10
+- ILOAD 12
+- BIPUSH 11
+- INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
+- ILOAD 14
+- SIPUSH 16383
+- IAND
+- BIPUSH 14
+- ISHL
+- IADD
+- ALOAD 9
+- ILOAD 4
+- INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [
+- // handle kind 0x6 : INVOKESTATIC
+- jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+- // arguments:
+- 0
+- ]
+- IADD
+- ILOAD 5
+- IADD
+- ISTORE 12
+- L9
+- LINENUMBER 20 L9
+- ILOAD 12
+- BIPUSH 28
+- ISHR
+- ILOAD 14
+- BIPUSH 14
+- ISHR
+- IADD
+- ILOAD 11
+- ILOAD 13
+- BIPUSH 21
+- INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
+- IADD
+- ISTORE 5
+- L10
+- LINENUMBER 21 L10
+- ALOAD 9
+- ILOAD 4
+- DUP
+- ICONST_1
+- IADD
+- ISTORE 4
+- ILOAD 12
+- LDC 268435455
+- IAND
+- INVOKEDYNAMIC dyn:setElem|setProp(Ljava/lang/Object;II)V [
+- // handle kind 0x6 : INVOKESTATIC
+- jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+- // arguments:
+- 0
+- ]
+- L4
+- FRAME SAME
+- ILOAD 6
+- ICONST_M1
+- IADD
+- DUP
+- ISTORE 6
+- ICONST_0
+- IF_ICMPGE L5
+- L11
+- LINENUMBER 24 L11
+- ILOAD 5
+- IRETURN
+-
+-
+-SYSTEM PROPERTY: -Dnashorn.codegen.debug, -Dnashorn.codegen.debug.trace=<x>
++SYSTEM PROPERTY: -Dnashorn.codegen.debug.trace=<x>
+
+ See the description of the codegen logger below.
+
+
+-SYSTEM_PROPERTY: -Dnashorn.fields.debug
++SYSTEM PROPERTY: -Dnashorn.fields.objects
+
+-See the description on the fields logger below.
++When this property is true, Nashorn will only use object fields for
++AccessorProperties. This means that primitive values must be boxed
++when stored in a field, which is significantly slower than using
++primitive fields.
+
+-
+-SYSTEM PROPERTY: -Dnashorn.fields.dual
+-
+-When this property is true, Nashorn will attempt to use primitive
+-fields for AccessorProperties (currently just AccessorProperties, not
+-spill properties). Memory footprint for script objects will increase,
+-as we need to maintain both a primitive field (a long) as well as an
+-Object field for the property value. Ints are represented as the 32
+-low bits of the long fields. Doubles are represented as the
+-doubleToLongBits of their value. This way a single field can be used
+-for all primitive types. Packing and unpacking doubles to their bit
+-representation is intrinsified by the JVM and extremely fast.
+-
+-While dual fields in theory runs significantly faster than Object
+-fields due to reduction of boxing and memory allocation overhead,
+-there is still work to be done to make this a general purpose
+-solution. Research is ongoing.
++By default, Nashorn uses dual object and long fields. Ints are
++represented as the 32 low bits of the long fields. Doubles are
++represented as the doubleToLongBits of their value. This way a
++single field can be used for all primitive types. Packing and
++unpacking doubles to their bit representation is intrinsified by
++the JVM and extremely fast.
+
+ In the future, this might complement or be replaced by experimental
+ feature sun.misc.TaggedArray, which has been discussed on the mlvm
+ mailing list. TaggedArrays are basically a way to share data space
+ between primitives and references, and have the GC understand this.
+
+-As long as only primitive values are written to the fields and enough
+-type information exists to make sure that any reads don't have to be
+-uselessly boxed and unboxed, this is significantly faster than the
+-standard "Objects only" approach that currently is the default. See
+-test/examples/dual-fields-micro.js for an example that runs twice as
+-fast with dual fields as without them. Here, the compiler, can
+-determine that we are dealing with numbers only throughout the entire
+-property life span of the properties involved.
+-
+-If a "real" object (not a boxed primitive) is written to a field that
+-has a primitive representation, its callsite is relinked and an Object
+-field is used forevermore for that particular field in that
+-PropertyMap and its children, even if primitives are later assigned to
+-it.
+-
+-As the amount of compile time type information is very small in a
+-dynamic language like JavaScript, it is frequently the case that
+-something has to be treated as an object, because we don't know any
+-better. In reality though, it is often a boxed primitive is stored to
+-an AccessorProperty. The fastest way to handle this soundly is to use
+-a callsite typecheck and avoid blowing the field up to an Object. We
+-never revert object fields to primitives. Ping-pong:ing back and forth
+-between primitive representation and Object representation would cause
+-fatal performance overhead, so this is not an option.
+-
+-For a general application the dual fields approach is still slower
+-than objects only fields in some places, about the same in most cases,
+-and significantly faster in very few. This is due the program using
+-primitives, but we still can't prove it. For example "local_var a =
+-call(); field = a;" may very well write a double to the field, but the
+-compiler dare not guess a double type if field is a local variable,
+-due to bytecode variables being strongly typed and later non
+-interchangeable. To get around this, the entire method would have to
+-be replaced and a continuation retained to restart from. We believe
+-that the next steps we should go through are instead:
+-
+-1) Implement method specialization based on callsite, as it's quite
+-frequently the case that numbers are passed around, but currently our
+-function nodes just have object types visible to the compiler. For
+-example "var b = 17; func(a,b,17)" is an example where two parameters
+-can be specialized, but the main version of func might also be called
+-from another callsite with func(x,y,"string").
+-
+-2) This requires lazy jitting as the functions have to be specialized
+-per callsite.
+-
+-Even though "function square(x) { return x*x }" might look like a
+-trivial function that can always only take doubles, this is not
+-true. Someone might have overridden the valueOf for x so that the
+-toNumber coercion has side effects. To fulfil JavaScript semantics,
+-the coercion has to run twice for both terms of the multiplication
+-even if they are the same object. This means that call site
+-specialization is necessary, not parameter specialization on the form
+-"function square(x) { var xd = (double)x; return xd*xd; }", as one
+-might first think.
+-
+-Generating a method specialization for any variant of a function that
+-we can determine by types at compile time is a combinatorial explosion
+-of byte code (try it e.g. on all the variants of am3 in the Octane
+-benchmark crypto.js). Thus, this needs to be lazy
+-
+-3) Optimistic callsite writes, something on the form
+-
+-x = y; //x is a field known to be a primitive. y is only an object as
+-far as we can tell
+-
+-turns into
+-
+-try {
+- x = (int)y;
+-} catch (X is not an integer field right now | ClassCastException e) {
+- x = y;
+-}
+-
+-Mini POC shows that this is the key to a lot of dual field performance
+-in seemingly trivial micros where one unknown object, in reality
+-actually a primitive, foils it for us. Very common pattern. Once we
+-are "all primitives", dual fields runs a lot faster than Object fields
+-only.
+-
+-We still have to deal with objects vs primitives for local bytecode
+-slots, possibly through code copying and versioning.
+-
+-The Future:
+-
+-We expect the usefulness of dual fields to increase significantly
+-after the optimistic type system described in the section on
+-integer arithmetic above is implemented.
+-
+
+ SYSTEM PROPERTY: -Dnashorn.compiler.symbol.trace=[<x>[,*]],
+ -Dnashorn.compiler.symbol.stacktrace=[<x>[,*]]
+@@ -628,6 +141,9 @@
+ "identical" - this method compares two script objects for reference
+ equality. It is a == Java comparison
+
++"equals" - Returns true if two objects are either referentially
++identical or equal as defined by java.lang.Object.equals.
++
+ "dumpCounters" - will dump the debug counters' current values to
+ stdout.
+
+@@ -648,66 +164,66 @@
+ when a callsite has to be relinked, due to a previous assumption of
+ object layout being invalidated.
+
++"getContext" - return the current Nashorn context.
+
+-SYSTEM PROPERTY: -Dnashorn.methodhandles.debug,
+--Dnashorn.methodhandles.debug=create
++"equalWithoutType" - Returns true if if the two objects are both
++property maps, and they have identical properties in the same order,
++but allows the properties to differ in their types.
+
+-If this property is enabled, each MethodHandle related call that uses
+-the java.lang.invoke package gets its MethodHandle intercepted and an
+-instrumentation printout of arguments and return value appended to
+-it. This shows exactly which method handles are executed and from
+-where. (Also MethodTypes and SwitchPoints). This can be augmented with
+-more information, for example, instance count, by subclassing or
+-further extending the TraceMethodHandleFactory implementation in
+-MethodHandleFactory.java.
++"diffPropertyMaps" Returns a diagnostic string representing the difference
++of two property maps.
+
+-If the property is specialized with "=create" as its option,
+-instrumentation will be shown for method handles upon creation time
+-rather than at runtime usage.
++"getClass" - Returns the Java class of an object, or undefined if null.
++
++"toJavaString" - Returns the Java toString representation of an object.
++
++"toIdentString" - Returns a string representation of an object consisting
++of its java class name and hash code.
++
++"getListenerCount" - Return the number of property listeners for a
++script object.
++
++"getEventQueueCapacity" - Get the capacity of the event queue.
++
++"setEventQueueCapacity" - Set the event queue capacity.
++
++"addRuntimeEvent" - Add a runtime event to the runtime event queue.
++The queue has a fixed size (see -Dnashorn.runtime.event.queue.size)
++and the oldest entry will be thrown out of the queue is about to overflow.
++
++"expandEventQueueCapacity" - Expands the event queue capacity,
++or truncates if capacity is lower than current capacity. Then only
++the newest entries are kept.
++
++"clearRuntimeEvents" - Clear the runtime event queue.
++
++"removeRuntimeEvent" - Remove a specific runtime event from the event queue.
++
++"getRuntimeEvents" - Return all runtime events in the queue as an array.
++
++"getLastRuntimeEvent" - Return the last runtime event in the queue.
+
+
+ SYSTEM PROPERTY: -Dnashorn.methodhandles.debug.stacktrace
+
+-This does the same as nashorn.methodhandles.debug, but when enabled
+-also dumps the stack trace for every instrumented method handle
+-operation. Warning: This is enormously verbose, but provides a pretty
++This enhances methodhandles logging (see below) to also dump the
++stack trace for every instrumented method handle operation.
++Warning: This is enormously verbose, but provides a pretty
+ decent "grep:able" picture of where the calls are coming from.
+
+-See the description of the codegen logger below for a more verbose
+-description of this option
+
++SYSTEM PROPERTY: -Dnashorn.cce
+
+-SYSTEM PROPERTY: -Dnashorn.scriptfunction.specialization.disable
++Setting this system property causes the Nashorn linker to rely on
++ClassCastExceptions for triggering a callsite relink. If not set, the linker
++will add an explicit instanceof guard.
+
+-There are several "fast path" implementations of constructors and
+-functions in the NativeObject classes that, in their original form,
+-take a variable amount of arguments. Said functions are also declared
+-to take Object parameters in their original form, as this is what the
+-JavaScript specification mandates.
+-However, we often know quite a lot more at a callsite of one of these
+-functions. For example, Math.min is called with a fixed number (2) of
+-integer arguments. The overhead of boxing these ints to Objects and
+-folding them into an Object array for the generic varargs Math.min
+-function is an order of magnitude slower than calling a specialized
+-implementation of Math.min that takes two integers. Specialized
+-functions and constructors are identified by the tag
+-@SpecializedFunction and @SpecializedConstructor in the Nashorn
+-code. The linker will link in the most appropriate (narrowest types,
+-right number of types and least number of arguments) specialization if
+-specializations are available.
+
+-Every ScriptFunction may carry specializations that the linker can
+-choose from. This framework will likely be extended for user defined
+-functions. The compiler can often infer enough parameter type info
+-from callsites for in order to generate simpler versions with less
+-generic Object types. This feature depends on future lazy jitting, as
+-there tend to be many calls to user defined functions, some where the
+-callsite can be specialized, some where we mostly see object
+-parameters even at the callsite.
++SYSTEM PROPERTY: -Dnashorn.spill.threshold=<x>
+
+-If this system property is set to true, the linker will not attempt to
+-use any specialized function or constructor for native objects, but
+-just call the generic one.
++This property sets the number of fields in an object from which to use
++generic array based spill storage instead of Java fields. The default value
++is 256.
+
+
+ SYSTEM PROPERTY: -Dnashorn.tcs.miss.samplePercent=<x>
+@@ -719,8 +235,47 @@
+ should be logged. Typically this is set to 1 or 5 (percent). 1% is the
+ default value.
+
++SYSTEM PROPERTY: -Dnashorn.persistent.code.cache
+
+-SYSTEM_PROPERTY: -Dnashorn.profilefile=<filename>
++This property can be used to set the directory where Nashorn stores
++serialized script classes generated with the -pcc/--persistent-code-cache
++option. The default directory name is "nashorn_code_cache".
++
++
++SYSTEM PROPERTY: -Dnashorn.typeInfo.maxFiles
++
++Maximum number of files to store in the type info cache. The type info cache
++is used to cache type data of JavaScript functions when running with
++optimistic types (-ot/--optimistic-types). There is one file per JavaScript
++function in the cache.
++
++The default value is 0 which means the feature is disabled. Setting this
++to something like 20000 is probably good enough for most applications and
++will usually cap the cache directory to about 80MB presuming a 4kB
++filesystem allocation unit. Set this to "unlimited" to run without limit.
++
++If the value is not 0 or "unlimited", Nashorn will spawn a cleanup thread
++that makes sure the number of files in the cache does not exceed the given
++value by deleting the least recently modified files.
++
++
++SYSTEM PROPERTY: -Dnashorn.typeInfo.cacheDir
++
++This property can be used to set the directory where Nashorn stores the
++type info cache when -Dnashorn.typeInfo.maxFiles is set to a nonzero
++value. The default location is platform specific. On Windows, it is
++"${java.io.tmpdir}\com.oracle.java.NashornTypeInfo". On Linux and
++Solaris it is "~/.cache/com.oracle.java.NashornTypeInfo". On Mac OS X,
++it is "~/Library/Caches/com.oracle.java.NashornTypeInfo".
++
++
++SYSTEM PROPERTY: -Dnashorn.typeInfo.cleanupDelaySeconds=<value>
++
++This sets the delay between cleanups of the typeInfo cache, in seconds.
++The default delay is 20 seconds.
++
++
++SYSTEM PROPERTY: -Dnashorn.profilefile=<filename>
+
+ When running with the profile callsite options (-pcs), Nashorn will
+ dump profiling data for all callsites to stderr as a shutdown hook. To
+@@ -736,26 +291,11 @@
+ an implementation based on Joni, the regular expression engine used by
+ the JRuby project. The default value for this flag is "joni"
+
++SYSTEM PROPERTY: -Dnashorn.runtime.event.queue.size=<value>
+
+-SYSTEM PROPERTY: -Dnashorn.time
+-
+-This enables timers for various phases of script compilation. The timers
+-will be dumped when the Nashorn process exits. We see a percentage value
+-of how much time was spent not executing bytecode (i.e. compilation and
+-internal tasks) at the end of the report.
+-
+-Here is an example:
+-
+-[JavaScript Parsing] 61 ms
+-[Constant Folding] 11 ms
+-[Control Flow Lowering] 26 ms
+-[Type Attribution] 81 ms
+-[Range Analysis] 0 ms
+-[Code Splitting] 29 ms
+-[Type Finalization] 19 ms
+-[Bytecode Generation] 189 ms
+-[Code Installation] 7 ms
+-Total runtime: 508 ms (Non-runtime: 423 ms [83%])
++Nashorn provides a fixed sized runtime event queue for debugging purposes.
++See -Dnashorn.debug for methods to access the event queue.
++The default value is 1024.
+
+ ===============
+ 2. The loggers.
+@@ -787,7 +327,9 @@
+ For example: --log=codegen,fields:finest is equivalent to
+ --log=codegen:info --log=fields:finest
+
+-The subsystems that currently support logging are:
++The following is an incomplete list of subsystems that currently
++support logging. Look for classes implementing
++jdk.nashorn.internal.runtime.logging.Loggable for more loggers.
+
+
+ * compiler
+@@ -800,6 +342,14 @@
+ use.s
+
+
++* recompile
++
++This logger shows information about recompilation of scripts and
++functions at runtime. Recompilation may happen because a function
++was called with different parameter types, or because an optimistic
++assumption failed while executing a function with -ot/--optimistic-types.
++
++
+ * codegen
+
+ The code generator is the emitter stage of the code pipeline, and
+@@ -856,25 +406,13 @@
+ Lower is also responsible for determining control flow information
+ like end points.
+
++* symbols
+
+-* attr
++The symbols logger tracks the assignment os symbols to identifiers.
+
+-The lowering annotates a FunctionNode with symbols for each identifier
+-and transforms high level constructs into lower level ones, that the
+-CodeGenerator consumes.
++* scopedepths
+
+-Lower logging typically outputs things like post pass actions,
+-insertions of casts because symbol types have been changed and type
+-specialization information. Currently very little info is generated by
+-this logger. This will probably change.
+-
+-
+-* finalize
+-
+-This --log=finalize log option outputs information for type finalization,
+-the third tier of the compiler. This means things like placement of
+-specialized scope nodes or explicit conversions.
+-
++This logs the calculation of scope depths for non-local symbols.
+
+ * fields
+
+@@ -887,6 +425,49 @@
+ (Object in the normal case, unless running with the dual field
+ representation)
+
++* time
++
++This enables timers for various phases of script compilation. The timers
++will be dumped when the Nashorn process exits. We see a percentage value
++of how much time was spent not executing bytecode (i.e. compilation and
++internal tasks) at the end of the report.
++
++A finer level than "info" will show individual compilation timings as they
++happen.
++
++Here is an example:
++
++[time] Accumulated complation phase Timings:
++[time]
++[time] 'JavaScript Parsing' 1076 ms
++[time] 'Constant Folding' 159 ms
++[time] 'Control Flow Lowering' 303 ms
++[time] 'Program Point Calculation' 282 ms
++[time] 'Builtin Replacement' 71 ms
++[time] 'Code Splitting' 670 ms
++[time] 'Symbol Assignment' 474 ms
++[time] 'Scope Depth Computation' 249 ms
++[time] 'Optimistic Type Assignment' 186 ms
++[time] 'Local Variable Type Calculation' 526 ms
++[time] 'Bytecode Generation' 5177 ms
++[time] 'Class Installation' 1854 ms
++[time]
++[time] Total runtime: 11994 ms (Non-runtime: 11027 ms [91%])
++
++* methodhandles
++
++If this logger is enabled, each MethodHandle related call that uses
++the java.lang.invoke package gets its MethodHandle intercepted and an
++instrumentation printout of arguments and return value appended to
++it. This shows exactly which method handles are executed and from
++where. (Also MethodTypes and SwitchPoints).
++
++* classcache
++
++This logger shows information about reusing code classes using the
++in-memory class cache. Nashorn will try to avoid compilation of
++scripts by using existing classes. This can significantly improve
++performance when repeatedly evaluating the same script.
+
+ =======================
+ 3. Undocumented options
+@@ -914,11 +495,10 @@
+
+ -cp, -classpath (-cp path. Specify where to find user class files.)
+
+- -co, --compile-only (Compile script without running. Exit after compilation)
++ -co, --compile-only (Compile without running.)
+ param: [true|false] default: false
+
+- -d, --dump-debug-dir (specify a destination directory to dump class files.
+- This must be combined with the --compile-only option to work)
++ -d, --dump-debug-dir (specify a destination directory to dump class files.)
+ param: <path>
+
+ --debug-lines (Generate line number table in .class files.)
+@@ -954,10 +534,6 @@
+ -h, -help (Print help for command line flags.)
+ param: [true|false] default: false
+
+- --lazy-compilation (EXPERIMENTAL: Use lazy code generation strategies - do not compile
+- the entire script at once.)
+- param: [true|false] default: false
+-
+ --loader-per-compile (Create a new class loader per compile.)
+ param: [true|false] default: true
+
+@@ -965,16 +541,16 @@
+ param: <locale> default: en-US
+
+ --log (Enable logging of a given level for a given number of sub systems.
+- [for example: --log=fields:finest,codegen:info])
++ [for example: --log=fields:finest,codegen:info].)
+ param: <module:level>,*
+
+- -nj, --no-java (No Java support)
++ -nj, --no-java (Disable Java support.)
+ param: [true|false] default: false
+
+- -nse, --no-syntax-extensions (No non-standard syntax extensions)
++ -nse, --no-syntax-extensions (Disallow non-standard syntax extensions.)
+ param: [true|false] default: false
+
+- -nta, --no-typed-arrays (No Typed arrays support)
++ -nta, --no-typed-arrays (Disable typed arrays support.)
+ param: [true|false] default: false
+
+ --parse-only (Parse without compiling.)
+@@ -983,13 +559,15 @@
+ --print-ast (Print abstract syntax tree.)
+ param: [true|false] default: false
+
+- --print-code (Print bytecode.)
+- param: [true|false] default: false
++ -pc, --print-code (Print generated bytecode. If a directory is specified, nothing will
++ be dumped to stderr. Also, in that case, .dot files will be generated
++ for all functions or for the function with the specified name only.)
++ param: [dir:<output-dir>,function:<name>]
+
+ --print-lower-ast (Print lowered abstract syntax tree.)
+ param: [true|false] default: false
+
+- --print-lower-parse (Print the parse tree after lowering.)
++ -plp, --print-lower-parse (Print the parse tree after lowering.)
+ param: [true|false] default: false
+
+ --print-mem-usage (Print memory usage of IR after each compile stage.)
+@@ -998,7 +576,7 @@
+ --print-no-newline (Print function will not print new line char.)
+ param: [true|false] default: false
+
+- --print-parse (Print the parse tree.)
++ -pp, --print-parse (Print the parse tree.)
+ param: [true|false] default: false
+
+ --print-symbols (Print the symbol table.)
+@@ -1007,21 +585,13 @@
+ -pcs, --profile-callsites (Dump callsite profile data.)
+ param: [true|false] default: false
+
+- --range-analysis (EXPERIMENTAL: Do range analysis using known compile time types,
+- and try to narrow number types)
+- param: [true|false] default: false
+-
+ -scripting (Enable scripting features.)
+ param: [true|false] default: false
+
+- --specialize-calls (EXPERIMENTAL: Specialize all or a set of method according
+- to callsite parameter types)
+- param: [=function_1,...,function_n]
+-
+- --stderr (Redirect stderr to a filename or to another tty, e.g. stdout)
++ --stderr (Redirect stderr to a filename or to another tty, e.g. stdout.)
+ param: <output console>
+
+- --stdout (Redirect stdout to a filename or to another tty, e.g. stderr)
++ --stdout (Redirect stdout to a filename or to another tty, e.g. stderr.)
+ param: <output console>
+
+ -strict (Run scripts in strict mode.)
+@@ -1031,7 +601,7 @@
+ param: <timezone> default: Europe/Stockholm
+
+ -tcs, --trace-callsites (Enable callsite trace mode. Options are: miss [trace callsite misses]
+- enterexit [trace callsite enter/exit], objects [print object properties])
++ enterexit [trace callsite enter/exit], objects [print object properties].)
+ param: [=[option,]*]
+
+ --verify-code (Verify byte code before running.)
+--- ./nashorn/docs/genshelldoc.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/genshelldoc.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -61,7 +61,7 @@
+
+ for each (opt in Options.validOptions) {
+
+-var isTimezone = (opt.type == "timezone");
++var isTimezone = (opt.type == "timezone");
+ var defValue = opt.defaultValue;
+ if (defValue == null) {
+ defValue = "&lt;none&gt;";
+--- ./nashorn/docs/source/EvalFile.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/EvalFile.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,14 +29,16 @@
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+-import javax.script.*;
++import javax.script.ScriptEngine;
++import javax.script.ScriptEngineManager;
+
++@SuppressWarnings("javadoc")
+ public class EvalFile {
+- public static void main(String[] args) throws Exception {
++ public static void main(final String[] args) throws Exception {
+ // create a script engine manager
+- ScriptEngineManager factory = new ScriptEngineManager();
++ final ScriptEngineManager factory = new ScriptEngineManager();
+ // create JavaScript engine
+- ScriptEngine engine = factory.getEngineByName("nashorn");
++ final ScriptEngine engine = factory.getEngineByName("nashorn");
+ // evaluate JavaScript code from given file - specified by first argument
+ engine.eval(new java.io.FileReader(args[0]));
+ }
+--- ./nashorn/docs/source/EvalScript.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/EvalScript.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,14 +29,16 @@
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+-import javax.script.*;
++import javax.script.ScriptEngine;
++import javax.script.ScriptEngineManager;
+
++@SuppressWarnings("javadoc")
+ public class EvalScript {
+- public static void main(String[] args) throws Exception {
++ public static void main(final String[] args) throws Exception {
+ // create a script engine manager
+- ScriptEngineManager factory = new ScriptEngineManager();
++ final ScriptEngineManager factory = new ScriptEngineManager();
+ // create a JavaScript engine
+- ScriptEngine engine = factory.getEngineByName("nashorn");
++ final ScriptEngine engine = factory.getEngineByName("nashorn");
+ // evaluate JavaScript code from String
+ engine.eval("print('Hello, World')");
+ }
+--- ./nashorn/docs/source/InvokeScriptFunction.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/InvokeScriptFunction.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,22 +29,25 @@
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+-import javax.script.*;
++import javax.script.Invocable;
++import javax.script.ScriptEngine;
++import javax.script.ScriptEngineManager;
+
++@SuppressWarnings("javadoc")
+ public class InvokeScriptFunction {
+- public static void main(String[] args) throws Exception {
+- ScriptEngineManager manager = new ScriptEngineManager();
+- ScriptEngine engine = manager.getEngineByName("nashorn");
++ public static void main(final String[] args) throws Exception {
++ final ScriptEngineManager manager = new ScriptEngineManager();
++ final ScriptEngine engine = manager.getEngineByName("nashorn");
+
+ // JavaScript code in a String
+- String script = "function hello(name) { print('Hello, ' + name); }";
++ final String script = "function hello(name) { print('Hello, ' + name); }";
+ // evaluate script
+ engine.eval(script);
+
+ // javax.script.Invocable is an optional interface.
+ // Check whether your script engine implements or not!
+ // Note that the JavaScript engine implements Invocable interface.
+- Invocable inv = (Invocable) engine;
++ final Invocable inv = (Invocable) engine;
+
+ // invoke the global function named "hello"
+ inv.invokeFunction("hello", "Scripting!!" );
+--- ./nashorn/docs/source/InvokeScriptMethod.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/InvokeScriptMethod.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,26 +29,29 @@
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+-import javax.script.*;
++import javax.script.Invocable;
++import javax.script.ScriptEngine;
++import javax.script.ScriptEngineManager;
+
++@SuppressWarnings("javadoc")
+ public class InvokeScriptMethod {
+- public static void main(String[] args) throws Exception {
+- ScriptEngineManager manager = new ScriptEngineManager();
+- ScriptEngine engine = manager.getEngineByName("nashorn");
++ public static void main(final String[] args) throws Exception {
++ final ScriptEngineManager manager = new ScriptEngineManager();
++ final ScriptEngine engine = manager.getEngineByName("nashorn");
+
+ // JavaScript code in a String. This code defines a script object 'obj'
+ // with one method called 'hello'.
+- String script = "var obj = new Object(); obj.hello = function(name) { print('Hello, ' + name); }";
++ final String script = "var obj = new Object(); obj.hello = function(name) { print('Hello, ' + name); }";
+ // evaluate script
+ engine.eval(script);
+
+ // javax.script.Invocable is an optional interface.
+ // Check whether your script engine implements or not!
+ // Note that the JavaScript engine implements Invocable interface.
+- Invocable inv = (Invocable) engine;
++ final Invocable inv = (Invocable) engine;
+
+ // get script object on which we want to call the method
+- Object obj = engine.get("obj");
++ final Object obj = engine.get("obj");
+
+ // invoke the method named "hello" on the script object "obj"
+ inv.invokeMethod(obj, "hello", "Script Method !!" );
+--- ./nashorn/docs/source/MultiScopes.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/MultiScopes.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,12 +29,17 @@
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+-import javax.script.*;
++import javax.script.Bindings;
++import javax.script.ScriptContext;
++import javax.script.ScriptEngine;
++import javax.script.ScriptEngineManager;
++import javax.script.SimpleScriptContext;
+
++@SuppressWarnings("javadoc")
+ public class MultiScopes {
+- public static void main(String[] args) throws Exception {
+- ScriptEngineManager manager = new ScriptEngineManager();
+- ScriptEngine engine = manager.getEngineByName("nashorn");
++ public static void main(final String[] args) throws Exception {
++ final ScriptEngineManager manager = new ScriptEngineManager();
++ final ScriptEngine engine = manager.getEngineByName("nashorn");
+
+ engine.put("x", "hello");
+ // print global variable "x"
+@@ -42,9 +47,9 @@
+ // the above line prints "hello"
+
+ // Now, pass a different script context
+- ScriptContext newContext = new SimpleScriptContext();
++ final ScriptContext newContext = new SimpleScriptContext();
+ newContext.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
+- Bindings engineScope = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
++ final Bindings engineScope = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
+
+ // add new variable "x" to the new engineScope
+ engineScope.put("x", "world");
+--- ./nashorn/docs/source/RunnableImpl.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/RunnableImpl.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,28 +29,31 @@
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+-import javax.script.*;
++import javax.script.Invocable;
++import javax.script.ScriptEngine;
++import javax.script.ScriptEngineManager;
+
++@SuppressWarnings("javadoc")
+ public class RunnableImpl {
+- public static void main(String[] args) throws Exception {
+- ScriptEngineManager manager = new ScriptEngineManager();
+- ScriptEngine engine = manager.getEngineByName("nashorn");
++ public static void main(final String[] args) throws Exception {
++ final ScriptEngineManager manager = new ScriptEngineManager();
++ final ScriptEngine engine = manager.getEngineByName("nashorn");
+
+ // JavaScript code in a String
+- String script = "function run() { print('run called'); }";
++ final String script = "function run() { print('run called'); }";
+
+ // evaluate script
+ engine.eval(script);
+
+- Invocable inv = (Invocable) engine;
++ final Invocable inv = (Invocable) engine;
+
+ // get Runnable interface object from engine. This interface methods
+ // are implemented by script functions with the matching name.
+- Runnable r = inv.getInterface(Runnable.class);
++ final Runnable r = inv.getInterface(Runnable.class);
+
+ // start a new thread that runs the script implemented
+ // runnable interface
+- Thread th = new Thread(r);
++ final Thread th = new Thread(r);
+ th.start();
+ th.join();
+ }
+--- ./nashorn/docs/source/RunnableImplObject.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/RunnableImplObject.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,31 +29,34 @@
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+-import javax.script.*;
++import javax.script.Invocable;
++import javax.script.ScriptEngine;
++import javax.script.ScriptEngineManager;
+
++@SuppressWarnings("javadoc")
+ public class RunnableImplObject {
+- public static void main(String[] args) throws Exception {
+- ScriptEngineManager manager = new ScriptEngineManager();
+- ScriptEngine engine = manager.getEngineByName("nashorn");
++ public static void main(final String[] args) throws Exception {
++ final ScriptEngineManager manager = new ScriptEngineManager();
++ final ScriptEngine engine = manager.getEngineByName("nashorn");
+
+ // JavaScript code in a String
+- String script = "var obj = new Object(); obj.run = function() { print('run method called'); }";
++ final String script = "var obj = new Object(); obj.run = function() { print('run method called'); }";
+
+ // evaluate script
+ engine.eval(script);
+
+ // get script object on which we want to implement the interface with
+- Object obj = engine.get("obj");
++ final Object obj = engine.get("obj");
+
+- Invocable inv = (Invocable) engine;
++ final Invocable inv = (Invocable) engine;
+
+ // get Runnable interface object from engine. This interface methods
+ // are implemented by script methods of object 'obj'
+- Runnable r = inv.getInterface(obj, Runnable.class);
++ final Runnable r = inv.getInterface(obj, Runnable.class);
+
+ // start a new thread that runs the script implemented
+ // runnable interface
+- Thread th = new Thread(r);
++ final Thread th = new Thread(r);
+ th.start();
+ th.join();
+ }
+--- ./nashorn/docs/source/ScriptVars.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/ScriptVars.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,15 +29,17 @@
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+-import javax.script.*;
+-import java.io.*;
++import java.io.File;
++import javax.script.ScriptEngine;
++import javax.script.ScriptEngineManager;
+
++@SuppressWarnings("javadoc")
+ public class ScriptVars {
+- public static void main(String[] args) throws Exception {
+- ScriptEngineManager manager = new ScriptEngineManager();
+- ScriptEngine engine = manager.getEngineByName("nashorn");
++ public static void main(final String[] args) throws Exception {
++ final ScriptEngineManager manager = new ScriptEngineManager();
++ final ScriptEngine engine = manager.getEngineByName("nashorn");
+
+- File f = new File("test.txt");
++ final File f = new File("test.txt");
+ // expose File object as variable to script
+ engine.put("file", f);
+
+--- ./nashorn/docs/source/importpackageclass.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/importpackageclass.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -32,7 +32,7 @@
+ // load compatibility script
+ load("nashorn:mozilla_compat.js");
+
+-// Import Java packages and classes
++// Import Java packages and classes
+ // like import package.*; in Java
+ importPackage(java.awt);
+ // like import java.awt.Frame in Java
+--- ./nashorn/docs/source/javaarray.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/javaarray.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/docs/source/javaextend.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/javaextend.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/docs/source/javaimporter.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/javaimporter.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/docs/source/javatypes.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/javatypes.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/docs/source/overload.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/overload.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -31,6 +31,6 @@
+
+ var out = java.lang.System.out;
+
+-// select a particular print function
++// select a particular print function
+ out["println(java.lang.Object)"]("hello");
+
+--- ./nashorn/docs/source/runnable.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/runnable.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/docs/source/samfunc.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/samfunc.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/docs/source/test.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/docs/source/test.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/make/BuildNashorn.gmk Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/make/BuildNashorn.gmk Wed Feb 04 12:14:47 2015 -0800
+@@ -65,7 +65,7 @@
+ SETUP := GENERATE_NEWBYTECODE_DEBUG, \
+ SRC := $(NASGEN_SRC) $(ASM_SRC), \
+ BIN := $(NASHORN_OUTPUTDIR)/nasgen_classes, \
+- ADD_JAVAC_FLAGS := -cp $(NASHORN_OUTPUTDIR)/nashorn_classes))
++ ADD_JAVAC_FLAGS := -bootclasspath "$(BOOT_RTJAR)$(PATH_SEP)$(NASHORN_OUTPUTDIR)/nashorn_classes"))
+
+ # Nasgen needs nashorn classes
+ $(BUILD_NASGEN): $(BUILD_NASHORN)
+--- ./nashorn/make/build-benchmark.xml Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/make/build-benchmark.xml Wed Feb 04 12:14:47 2015 -0800
+@@ -1,381 +1,333 @@
+ <?xml version="1.0" encoding="UTF-8"?>
++
+ <!--
+- Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+-
+- This code is free software; you can redistribute it and/or modify it
+- under the terms of the GNU General Public License version 2 only, as
+- published by the Free Software Foundation.
+-
+- This code is distributed in the hope that it will be useful, but WITHOUT
+- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- version 2 for more details (a copy is included in the LICENSE file that
+- accompanied this code).
+-
+- You should have received a copy of the GNU General Public License version
+- 2 along with this work; if not, write to the Free Software Foundation,
+- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+-
+- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- or visit www.oracle.com if you need additional information or have any
+- questions.
++ Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++
++ This code is free software; you can redistribute it and/or modify it
++ under the terms of the GNU General Public License version 2 only, as
++ published by the Free Software Foundation.
++
++ This code is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ version 2 for more details (a copy is included in the LICENSE file that
++ accompanied this code).
++
++ You should have received a copy of the GNU General Public License version
++ 2 along with this work; if not, write to the Free Software Foundation,
++ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++
++ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ or visit www.oracle.com if you need additional information or have any
++ questions.
+ -->
+-<project name="nashorn-benchmarks" default="all" basedir="..">
+
+- <target name="octane-init" depends="jar">
+- <property name="octane-tests" value="box2d code-load crypto deltablue earley-boyer gbemu navier-stokes pdfjs raytrace regexp richards splay"/>
++
++<project
++ name="nashorn-benchmarks"
++ default="all"
++ basedir=".."
++ xmlns:if="ant:if">
++
++ <!--
++ Below are the octane benchmarks that should be run.
++ The ones that are excluded, as Nashorn currently has
++ some issues with them (functionality or performance)
++ are commented out
++ -->
++
++ <!-- box2d -->
++ <target name="octane-box2d" depends="octane-box2d-nashorn"/>
++ <target name="octane-box2d-nashorn" depends="jar">
++ <run-one cond="octane.benchmark.box2d" runtime="nashorn"/>
++ </target>
++ <target name="octane-box2d-v8" depends="jar">
++ <run-one cond="octane.benchmark.box2d" runtime="v8"/>
++ </target>
++ <target name="octane-box2d-rhino" depends="jar">
++ <run-one cond="octane.benchmark.box2d" runtime="rhino"/>
++ </target>
++
++ <!-- code-load -->
++ <target name="octane-code-load" depends="octane-code-load-nashorn"/>
++ <target name="octane-code-load-nashorn" depends="jar">
++ <run-one cond="octane.benchmark.code-load" runtime="nashorn"/>
++ </target>
++ <target name="octane-code-load-v8" depends="jar">
++ <run-one cond="octane.benchmark.code-load" runtime="v8"/>
++ </target>
++ <target name="octane-code-load-rhino" depends="jar">
++ <run-one cond="octane.benchmark.code-load" runtime="rhino"/>
++ </target>
++
++ <!-- crypto -->
++ <target name="octane-crypto" depends="octane-crypto-nashorn"/>
++ <target name="octane-crypto-nashorn" depends="jar">
++ <run-one cond="octane.benchmark.crypto" runtime="nashorn"/>
++ </target>
++ <target name="octane-crypto-v8" depends="jar">
++ <run-one cond="octane.benchmark.crypto" runtime="v8"/>
++ </target>
++ <target name="octane-crypto-rhino" depends="jar">
++ <run-one cond="octane.benchmark.crypto" runtime="rhino"/>
++ </target>
++
++ <!-- deltablue -->
++ <target name="octane-deltablue" depends="octane-deltablue-nashorn"/>
++ <target name="octane-deltablue-nashorn" depends="jar">
++ <run-one cond="octane.benchmark.deltablue" runtime="nashorn"/>
++ </target>
++ <target name="octane-deltablue-v8" depends="jar">
++ <run-one cond="octane.benchmark.deltablue" runtime="v8"/>
++ </target>
++ <target name="octane-deltablue-rhino" depends="jar">
++ <run-one cond="octane.benchmark.deltablue" runtime="rhino"/>
++ </target>
++
++ <!-- earley-boyer -->
++ <target name="octane-earley-boyer" depends="octane-earley-boyer-nashorn"/>
++ <target name="octane-earley-boyer-nashorn" depends="jar">
++ <run-one cond="octane.benchmark.earley-boyer" runtime="nashorn"/>
++ </target>
++ <target name="octane-earley-boyer-v8" depends="jar">
++ <run-one cond="octane.benchmark.earley-boyer" runtime="v8"/>
++ </target>
++ <target name="octane-earley-boyer-rhino" depends="jar">
++ <run-one cond="octane.benchmark.earley-boyer" runtime="rhino"/>
+ </target>
+
+- <!-- ignore benchmarks where rhino crashes -->
+- <target name="octane-init-rhino" depends="jar">
+- <property name="octane-tests" value="box2d code-load crypto deltablue earley-boyer gbemu navier-stokes raytrace regexp richards splay"/>
++ <!-- gbemu -->
++ <target name="octane-gbemu" depends="octane-gbemu-nashorn"/>
++ <target name="octane-gbemu-nashorn" depends="jar">
++ <run-one cond="octane.benchmark.gbemu" runtime="nashorn"/>
++ </target>
++ <target name="octane-gbemu-v8" depends="jar">
++ <run-one cond="octane.benchmark.gbemu" runtime="v8"/>
++ </target>
++ <target name="octane-gbemu-rhino" depends="jar">
++ <run-one cond="octane.benchmark.gbemu" runtime="rhino"/>
+ </target>
+
+- <!-- box2d -->
+- <target name="octane-box2d" depends="jar">
+- <antcall target="run-octane">
+- <param name="octane-tests" value="box2d"/>
++ <!-- mandreel -->
++ <target name="octane-mandreel" depends="octane-mandreel-nashorn"/>
++ <target name="octane-mandreel-nashorn" depends="jar">
++ <run-one cond="octane.benchmark.mandreel" runtime="nashorn"/>
++ </target>
++ <target name="octane-mandreel-v8" depends="jar">
++ <run-one cond="octane.benchmark.mandreel" runtime="v8"/>
++ </target>
++ <target name="octane-mandreel-rhino" depends="jar">
++ <run-one cond="octane.benchmark.mandreel" runtime="rhino"/>
++ </target>
++
++ <!-- navier-stokes -->
++ <target name="octane-navier-stokes" depends="octane-navier-stokes-nashorn"/>
++ <target name="octane-navier-stokes-nashorn" depends="jar">
++ <run-one cond="octane.benchmark.navier-stokes" runtime="nashorn"/>
++ </target>
++ <target name="octane-navier-stokes-v8" depends="jar">
++ <run-one cond="octane.benchmark.navier-stokes" runtime="v8"/>
++ </target>
++ <target name="octane-navier-stokes-rhino" depends="jar">
++ <run-one cond="octane.benchmark.navier-stokes" runtime="rhino"/>
++ </target>
++
++ <!-- pdfjs -->
++ <target name="octane-pdfjs" depends="octane-pdfjs-nashorn"/>
++ <target name="octane-pdfjs-nashorn" depends="jar">
++ <run-one cond="octane.benchmark.pdfjs" runtime="nashorn"/>
++ </target>
++ <target name="octane-pdfjs-v8" depends="jar">
++ <run-one cond="octane.benchmark.pdfjs" runtime="v8"/>
++ </target>
++ <target name="octane-pdfjs-rhino" depends="jar">
++ <run-one cond="octane.benchmark.pdfjs" runtime="rhino"/>
++ </target>
++
++ <!-- raytrace -->
++ <target name="octane-raytrace" depends="octane-raytrace-nashorn"/>
++ <target name="octane-raytrace-nashorn" depends="jar">
++ <run-one cond="octane.benchmark.raytrace" runtime="nashorn"/>
++ </target>
++ <target name="octane-raytrace-v8" depends="jar">
++ <run-one cond="octane.benchmark.raytrace" runtime="v8"/>
++ </target>
++ <target name="octane-raytrace-rhino" depends="jar">
++ <run-one cond="octane.benchmark.raytrace" runtime="rhino"/>
++ </target>
++
++ <!-- regexp -->
++ <target name="octane-regexp" depends="octane-regexp-nashorn"/>
++ <target name="octane-regexp-nashorn" depends="jar">
++ <run-one cond="octane.benchmark.regexp" runtime="nashorn"/>
++ </target>
++ <target name="octane-regexp-v8" depends="jar">
++ <run-one cond="octane.benchmark.regexp" runtime="v8"/>
++ </target>
++ <target name="octane-regexp-rhino" depends="jar">
++ <run-one cond="octane.benchmark.regexp" runtime="rhino"/>
++ </target>
++
++ <!-- richards -->
++ <target name="octane-richards" depends="octane-richards-nashorn"/>
++ <target name="octane-richards-nashorn" depends="jar">
++ <run-one cond="octane.benchmark.richards" runtime="nashorn"/>
++ </target>
++ <target name="octane-richards-v8" depends="jar">
++ <run-one cond="octane.benchmark.richards" runtime="v8"/>
++ </target>
++ <target name="octane-richards-rhino" depends="jar">
++ <run-one cond="octane.benchmark.richards" runtime="rhino"/>
++ </target>
++
++ <!-- splay -->
++ <target name="octane-splay" depends="octane-splay-nashorn"/>
++ <target name="octane-splay-nashorn" depends="jar">
++ <run-one cond="octane.benchmark.splay" runtime="nashorn"/>
++ </target>
++ <target name="octane-splay-v8" depends="jar">
++ <run-one cond="octane.benchmark.splay" runtime="v8"/>
++ </target>
++ <target name="octane-splay-rhino" depends="jar">
++ <run-one cond="octane.benchmark.splay" runtime="rhino"/>
++ </target>
++
++ <!-- typescript -->
++ <target name="octane-typescript" depends="octane-typescript-nashorn"/>
++ <target name="octane-typescript-nashorn" depends="jar">
++ <run-one cond="octane.benchmark.typescript" runtime="nashorn"/>
++ </target>
++ <target name="octane-typescript-v8" depends="jar">
++ <run-one cond="octane.benchmark.typescript" runtime="v8"/>
++ </target>
++ <target name="octane-typescript-rhino" depends="jar">
++ <run-one cond="octane.benchmark.typescript" runtime="rhino"/>
++ </target>
++
++ <!-- zlib -->
++ <target name="octane-zlib" depends="octane-zlib-nashorn"/>
++ <target name="octane-zlib-nashorn" depends="jar">
++ <run-one cond="octane.benchmark.zlib" runtime="nashorn"/>
++ </target>
++ <target name="octane-zlib-v8" depends="jar">
++ <run-one cond="octane.benchmark.zlib" runtime="v8"/>
++ </target>
++ <target name="octane-zlib-rhino" depends="jar">
++ <run-one cond="octane.benchmark.zlib" runtime="rhino"/>
++ </target>
++
++ <!--
++ Benchmark runners for one or more benchmarks, single
++ or multiple process
++ -->
++
++ <target name="octane-process-separate" if="${octane-test-sys-prop.separate.process}">
++ <echo message="Running each benchmark in separate processes, starting new JVMs for each."/>
++ <script language="javascript"><![CDATA[
++ var props = [];
++
++ for (var prop in project.getProperties()) {
++ if (prop.startsWith("octane.benchmark.")) {
++ props.push(prop);
++ }
++ }
++
++ //sort benchmark props in alphabetical order by name
++ props.sort(function(a, b) {
++ if (a < b) {
++ return -1;
++ } else if (a > b) {
++ return 1;
++ } else {
++ return 0;
++ }
++ });
++
++ var runtime = project.getProperty("runtime");
++
++ for (var i in props) {
++ var task = project.createTask("run-one");
++ // workaround for https://issues.apache.org/bugzilla/show_bug.cgi?id=53831, still not fixed
++ if (task.getOwningTarget() == null) {
++ task.setOwningTarget(self.getOwningTarget());
++ }
++ var prop = props[i];
++ task.setDynamicAttribute("cond", prop);
++ task.setDynamicAttribute("runtime", runtime);
++ task.perform();
++ }
++ ]]></script>
++ </target>
++
++ <target name="octane-process-single" unless="${octane-test-sys-prop.separate.process}">
++ <echo message="Running all benchmarks in the same process."/>
++ <pathconvert property="octane.benchmarks" pathsep=" ">
++ <propertyset>
++ <propertyref prefix="octane.benchmark."/>
++ </propertyset>
++ </pathconvert>
++ <antcall target="run-octane${runtime}">
++ <param name="octane-tests" value="${octane.benchmarks}"/>
+ </antcall>
+ </target>
+
+- <target name="octane-box2d-v8" depends="jar">
+- <antcall target="run-octane-v8">
+- <param name="octane-tests" value="box2d"/>
+- </antcall>
++ <!--
++ run 'octane' in single or separate processes based on config
++ This uses nashorn as the default runtime
++ -->
++ <target name="octane-nashorn" depends="jar">
++ <property name="runtime" value="nashorn"/>
++ <antcall target="octane-process-separate"/>
++ <antcall target="octane-process-single"/>
+ </target>
+
+- <target name="octane-box2d-rhino" depends="jar">
+- <antcall target="run-octane-rhino">
+- <param name="octane-tests" value="box2d"/>
+- </antcall>
+- </target>
+-
+-
+- <!-- code-load -->
+- <target name="octane-code-load" depends="jar">
+- <antcall target="run-octane">
+- <param name="octane-tests" value="code-load"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-code-load-v8" depends="jar">
+- <antcall target="run-octane-v8">
+- <param name="octane-tests" value="code-load"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-code-load-rhino" depends="jar">
+- <antcall target="run-octane-rhino">
+- <param name="octane-tests" value="code-load"/>
+- </antcall>
+- </target>
+-
+-
+- <!-- crypto -->
+- <target name="octane-crypto" depends="jar">
+- <antcall target="run-octane">
+- <param name="octane-tests" value="crypto"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-crypto-v8" depends="jar">
+- <antcall target="run-octane-v8">
+- <param name="octane-tests" value="crypto"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-crypto-rhino" depends="jar">
+- <antcall target="run-octane-rhino">
+- <param name="octane-tests" value="crypto"/>
+- </antcall>
+- </target>
+-
+-
+- <!-- deltablue -->
+- <target name="octane-deltablue" depends="jar">
+- <antcall target="run-octane">
+- <param name="octane-tests" value="deltablue"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-deltablue-v8" depends="jar">
+- <antcall target="run-octane-v8">
+- <param name="octane-tests" value="deltablue"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-deltablue-rhino" depends="jar">
+- <antcall target="run-octane-rhino">
+- <param name="octane-tests" value="deltablue"/>
+- </antcall>
+- </target>
+-
+-
+- <!-- earley-boyer -->
+- <target name="octane-earley-boyer" depends="jar">
+- <antcall target="run-octane">
+- <param name="octane-tests" value="earley-boyer"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-earley-boyer-v8" depends="jar">
+- <antcall target="run-octane-v8">
+- <param name="octane-tests" value="earley-boyer"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-earley-boyer-rhino" depends="jar">
+- <antcall target="run-octane-rhino">
+- <param name="octane-tests" value="earley-boyer"/>
+- </antcall>
+- </target>
+-
+-
+- <!-- gbemu -->
+- <target name="octane-gbemu" depends="jar">
+- <antcall target="run-octane">
+- <param name="octane-tests" value="gbemu"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-gbemu-v8" depends="jar">
+- <antcall target="run-octane-v8">
+- <param name="octane-tests" value="gbemu"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-gbemu-rhino" depends="jar">
+- <antcall target="run-octane-rhino">
+- <param name="octane-tests" value="gbemu"/>
+- </antcall>
+- </target>
+-
+-
+- <!-- mandreel -->
+- <target name="octane-mandreel" depends="jar">
+- <antcall target="run-octane">
+- <param name="octane-tests" value="mandreel"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-mandreel-v8" depends="jar">
+- <antcall target="run-octane-v8">
+- <param name="octane-tests" value="mandreel"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-mandreel-rhino" depends="jar">
+- <antcall target="run-octane-rhino">
+- <param name="octane-tests" value="mandreel"/>
+- </antcall>
+- </target>
+-
+-
+- <!-- navier-stokes -->
+- <target name="octane-navier-stokes" depends="jar">
+- <antcall target="run-octane">
+- <param name="octane-tests" value="navier-stokes"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-navier-stokes-v8" depends="jar">
+- <antcall target="run-octane-v8">
+- <param name="octane-tests" value="navier-stokes"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-navier-stokes-rhino" depends="jar">
+- <antcall target="run-octane-rhino">
+- <param name="octane-tests" value="navier-stokes"/>
+- </antcall>
+- </target>
+-
+-
+- <!-- pdfjs -->
+- <target name="octane-pdfjs" depends="jar">
+- <antcall target="run-octane">
+- <param name="octane-tests" value="pdfjs"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-pdfjs-v8" depends="jar">
+- <antcall target="run-octane-v8">
+- <param name="octane-tests" value="pdfjs"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-pdfjs-rhino" depends="jar">
+- <antcall target="run-octane-rhino">
+- <param name="octane-tests" value="pdfjs"/>
+- </antcall>
+- </target>
+-
+-
+- <!-- raytrace -->
+- <target name="octane-raytrace" depends="jar">
+- <antcall target="run-octane">
+- <param name="octane-tests" value="raytrace"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-raytrace-v8" depends="jar">
+- <antcall target="run-octane-v8">
+- <param name="octane-tests" value="raytrace"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-raytrace-rhino" depends="jar">
+- <antcall target="run-octane-rhino">
+- <param name="octane-tests" value="raytrace"/>
+- </antcall>
+- </target>
+-
+-
+- <!-- regexp -->
+- <target name="octane-regexp" depends="jar">
+- <antcall target="run-octane">
+- <param name="octane-tests" value="regexp"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-regexp-v8" depends="jar">
+- <antcall target="run-octane-v8">
+- <param name="octane-tests" value="regexp"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-regexp-rhino" depends="jar">
+- <antcall target="run-octane-rhino">
+- <param name="octane-tests" value="regexp"/>
+- </antcall>
+- </target>
+-
+-
+- <!-- richards -->
+- <target name="octane-richards" depends="jar">
+- <antcall target="run-octane">
+- <param name="octane-tests" value="richards"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-richards-v8" depends="jar">
+- <antcall target="run-octane-v8">
+- <param name="octane-tests" value="richards"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-richards-rhino" depends="jar">
+- <antcall target="run-octane-rhino">
+- <param name="octane-tests" value="richards"/>
+- </antcall>
+- </target>
+-
+-
+- <!-- splay -->
+- <target name="octane-splay" depends="jar">
+- <antcall target="run-octane">
+- <param name="octane-tests" value="splay"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-splay-v8" depends="jar">
+- <antcall target="run-octane-v8">
+- <param name="octane-tests" value="splay"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-splay-rhino" depends="jar">
+- <antcall target="run-octane-rhino">
+- <param name="octane-tests" value="splay"/>
+- </antcall>
+- </target>
+-
+- <!-- splay -->
+- <target name="octane-typescript" depends="jar">
+- <antcall target="run-octane">
+- <param name="octane-tests" value="typescript"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-typescript-v8" depends="jar">
+- <antcall target="run-octane-v8">
+- <param name="octane-typescript" value="typescript"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-typescript-rhino" depends="jar">
+- <antcall target="run-octane-rhino">
+- <param name="octane-tests" value="typescript"/>
+- </antcall>
+- </target>
+-
+- <!-- zlib -->
+- <target name="octane-zlib" depends="jar">
+- <antcall target="run-octane">
+- <param name="octane-tests" value="zlib"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-zlib-v8" depends="jar">
+- <antcall target="run-octane-v8">
+- <param name="octane-typescript" value="zlib"/>
+- </antcall>
+- </target>
+-
+- <target name="octane-zlib-rhino" depends="jar">
+- <antcall target="run-octane-rhino">
+- <param name="octane-tests" value="zlib"/>
+- </antcall>
+- </target>
+-
+- <!-- run octane benchmarks in a single process -->
+- <target name="octane-single-process" depends="octane-init">
+- <antcall target="run-octane"/>
+- </target>
+-
+- <!-- zlib excluded due to missing implementation of 'read' -->
+- <target name="octane-separate-process" depends=
+- "octane-box2d, octane-code-load, octane-crypto,
+- octane-deltablue, octane-earley-boyer, octane-gbemu,
+- octane-mandreel, octane-navier-stokes, octane-pdfjs,
+- octane-raytrace, octane-regexp, octane-richards,
+- octane-splay, octane-typescript"/>
+-
+- <target name="--single-process" unless="${octane-test-sys-prop.separate.process}">
+- <antcall target="octane-single-process"/>
+- </target>
+- <target name="--separate-process" if="${octane-test-sys-prop.separate.process}">
+- <antcall target="octane-separate-process"/>
+- </target>
+-
+- <!-- run 'octane' in single or separate processes based on config -->
+- <target name="octane" depends="init, --single-process, --separate-process"/>
++ <!-- alias for 'octane' -->
++ <target name="octane" depends="octane-nashorn"/>
+
+ <!-- run octane benchmarks using octane as runtime -->
+- <target name="octane-v8" depends="octane-init">
+- <antcall target="run-octane-v8"/>
++ <target name="octane-v8" depends="jar">
++ <property name="runtime" value="v8"/>
++ <antcall target="octane-process-separate"/>
++ <antcall target="octane-process-single"/>
+ </target>
+
+ <!-- run octane benchmarks using Rhino as runtime -->
+- <target name="octane-rhino" depends="octane-init-rhino">
+- <antcall target="run-octane-rhino"/>
++ <target name="octane-rhino" depends="jar">
++ <property name="runtime" value="rhino"/>
++ <antcall target="octane-process-separate"/>
++ <antcall target="octane-process-single"/>
+ </target>
+-
+- <target name="run-octane">
++
++ <macrodef name="run-one">
++ <attribute name="cond"/>
++ <attribute name="runtime" default=""/>
++ <sequential>
++ <antcall target="run-octane-@{runtime}" if:set="@{cond}">
++ <param name="octane-tests" value="${@{cond}}"/>
++ </antcall>
++ </sequential>
++ </macrodef>
++
++ <target name="run-octane-nashorn">
+ <java classname="${nashorn.shell.tool}"
+ classpath="${run.test.classpath}"
+ fork="true"
+ dir=".">
+ <jvmarg line="${ext.class.path}"/>
+ <jvmarg line="${run.test.jvmargs.octane} -Xms${run.test.xms} -Xmx${run.test.xmx}"/>
++ <!-- pass on all properties prefixed with 'nashorn' to the runtime -->
++ <syspropertyset>
++ <propertyref prefix="nashorn."/>
++ </syspropertyset>
+ <arg value="${octane-test-sys-prop.test.js.framework}"/>
++ <arg value="-scripting"/>
+ <arg value="--"/>
+ <arg value="${octane-tests}"/>
+ <arg value="--runtime"/>
+- <arg value="Nashorn"/>
++ <arg value="nashorn"/>
+ <arg value="--verbose"/>
+- <arg value="--iterations 8"/>
++ <arg value="--iterations ${octane.iterations}"/>
+ </java>
+ </target>
+
+@@ -383,11 +335,11 @@
+ <exec executable="${v8.shell}">
+ <arg value="${octane-test-sys-prop.test.js.framework}"/>
+ <arg value="--"/>
+- <arg value="${octane-tests}"/>
++ <arg value="${octane-tests}"/>
+ <arg value="--runtime"/>
+ <arg value="v8"/>
+ <arg value="--verbose"/>
+- <arg value="--iterations 8"/>
++ <arg value="--iterations ${octane.iterations}"/>
+ </exec>
+ </target>
+
+@@ -397,12 +349,14 @@
+ fork="true"
+ dir=".">
+ <jvmarg line="${run.test.jvmargs.octane} -Xms${run.test.xms} -Xmx${run.test.xmx}"/>
++ <arg value="-opt"/>
++ <arg value="9"/>
+ <arg value="${octane-test-sys-prop.test.js.framework}"/>
+ <arg value="${octane-tests}"/>
+ <arg value="--runtime"/>
+- <arg value="Rhino"/>
++ <arg value="rhino"/>
+ <arg value="--verbose"/>
+- <arg value="--iterations 8"/>
++ <arg value="--iterations ${octane.iterations}"/>
+ </java>
+ </target>
+
+@@ -413,18 +367,22 @@
+ <arg value="${octane-tests}/"/>
+ </exec>
+ </target>
+-
++
+ <target name="sunspider-init" depends="jar">
+ <fileset id="sunspider-set"
+- dir="${sunspider-test-sys-prop.test.js.roots}"
+- excludes="${sunspider-test-sys-prop.test.js.exclude.list}">
++ dir="${sunspider-test-sys-prop.test.js.roots}"
++ excludes="${sunspider-test-sys-prop.test.js.exclude.list}">
+ <include name="**/*.js"/>
+ </fileset>
+ <pathconvert pathsep=" " property="sunspider-tests" refid="sunspider-set"/>
+ </target>
+
++ <!--- SUNSPIDER JOB BELOW -->
++
+ <!-- run sunspider with Nashorn -->
+- <target name="sunspider" depends="sunspider-init">
++ <target name="sunspider" depends="sunspider-nashorn"/>
++
++ <target name="sunspider-nashorn" depends="sunspider-init">
+ <java classname="${nashorn.shell.tool}"
+ classpath="${run.test.classpath}"
+ fork="true"
+@@ -436,6 +394,9 @@
+ <arg value="${sunspider-test-sys-prop.test.js.framework}"/>
+ <arg value="--"/>
+ <arg value="${sunspider-tests}/"/>
++ <arg value="--verbose"/>
++ <arg value="--times"/>
++ <arg value="${sunspider.iterations}"/>
+ </java>
+ </target>
+
+@@ -445,6 +406,9 @@
+ <arg value="${sunspider-test-sys-prop.test.js.framework}"/>
+ <arg value="--"/>
+ <arg value="${sunspider-tests}/"/>
++ <arg value="--verbose"/>
++ <arg value="--times"/>
++ <arg value="${sunspider.iterations}"/>
+ </exec>
+ </target>
+
+@@ -455,8 +419,13 @@
+ fork="true"
+ dir=".">
+ <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx}"/>
++ <arg value="-opt"/>
++ <arg value="9"/>
+ <arg value="${sunspider-test-sys-prop.test.js.framework}"/>
+ <arg value="${sunspider-tests}/"/>
++ <arg value="--verbose"/>
++ <arg value="--times"/>
++ <arg value="${sunspider.iterations}"/>
+ </java>
+ </target>
+
+--- ./nashorn/make/build-nasgen.xml Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/make/build-nasgen.xml Wed Feb 04 12:14:47 2015 -0800
+@@ -25,7 +25,7 @@
+ <description>Builds and runs nasgen.</description>
+ <import file="build.xml"/>
+
+- <target name="build-nasgen" depends="compile-asm">
++ <target name="build-nasgen" depends="prepare">
+ <ant inheritAll="false" dir="${basedir}/buildtools/nasgen"
+ antfile="build.xml" target="jar"/>
+ </target>
+@@ -36,11 +36,13 @@
+ <pathelement location="${basedir}/jcov2/lib/jcov_j2se_rt.jar"/>
+ <pathelement location="${basedir}/buildtools/nasgen/dist/nasgen.jar"/>
+ <pathelement path="${basedir}/build/classes"/>
++ <pathelement location="${dist.dir}/nasgen.jar"/>
++ <pathelement path="${build.dir}/classes"/>
+ </classpath>
+ <jvmarg value="-Djava.ext.dirs="/>
+- <arg value="${basedir}/build/classes"/>
++ <arg value="${build.dir}/classes"/>
+ <arg value="jdk.nashorn.internal.objects"/>
+- <arg value="${basedir}/build/classes"/>
++ <arg value="${build.dir}/classes"/>
+ </java>
+ </target>
+
+--- ./nashorn/make/build.xml Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/make/build.xml Wed Feb 04 12:14:47 2015 -0800
+@@ -1,4 +1,5 @@
+ <?xml version="1.0" encoding="UTF-8"?>
++
+ <!--
+ Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -21,19 +22,22 @@
+ or visit www.oracle.com if you need additional information or have any
+ questions.
+ -->
++
+ <project name="nashorn" default="test" basedir="..">
+ <import file="build-nasgen.xml"/>
+- <import file="build-benchmark.xml"/>
+ <import file="code_coverage.xml"/>
+
+-
+ <target name="init-conditions">
+ <!-- loading locally defined resources and properties. NB they owerwrite default ones defined later -->
+ <property file="${user.home}/.nashorn.project.local.properties"/>
+
+ <loadproperties srcFile="make/project.properties"/>
++ <path id="dist.path">
++ <pathelement location="${dist.dir}"/>
++ </path>
+ <path id="nashorn.ext.path">
+ <pathelement location="${dist.dir}"/>
++ <pathelement location="${java.ext.dirs}"/>
+ </path>
+ <property name="ext.class.path" value="-Djava.ext.dirs=&quot;${toString:nashorn.ext.path}&quot;"/>
+ <condition property="svn.executable" value="/usr/local/bin/svn" else="svn">
+@@ -45,13 +49,11 @@
+ <condition property="git.executable" value="/usr/local/bin/git" else="git">
+ <available file="/usr/local/bin/git"/>
+ </condition>
+- <!-- check if JDK already has ASM classes -->
+- <available property="asm.available" classname="jdk.internal.org.objectweb.asm.Type"/>
+ <!-- check if testng.jar is avaiable -->
+ <available property="testng.available" file="${file.reference.testng.jar}"/>
+ <!-- check if Jemmy ang testng.jar are avaiable -->
+ <condition property="jemmy.jfx.testng.available" value="true">
+- <and>
++ <and>
+ <available file="${file.reference.jemmyfx.jar}"/>
+ <available file="${file.reference.jemmycore.jar}"/>
+ <available file="${file.reference.jemmyawtinput.jar}"/>
+@@ -69,13 +71,39 @@
+ <condition property="exclude.list" value="./exclude/exclude_list_cc.txt" else="./exclude/exclude_list.txt">
+ <istrue value="${make.code.coverage}" />
+ </condition>
++
++ <condition property="jfr.options" value="${run.test.jvmargs.jfr}" else="">
++ <istrue value="${jfr}"/>
++ </condition>
+ </target>
+
+- <target name="init" depends="init-conditions, init-cc">
++ <!-- check minimum ant version required to be 1.8.4 -->
++ <target name="check-ant-version">
++ <property name="ant.version.required" value="1.8.4"/>
++ <antversion property="ant.current.version" />
++ <fail message="The current ant version, ${ant.current.version}, is too old. Please use 1.8.4 or above.">
++ <condition>
++ <not>
++ <antversion atleast="${ant.version.required}"/>
++ </not>
++ </condition>
++ </fail>
++ </target>
+
++ <target name="check-java-version">
++ <!-- look for a Class that is available only in jdk1.8 or above -->
++ <!-- core/exposed API class is better than an implementation class -->
++ <available property="jdk1.8+" classname="java.util.stream.Stream"/>
++
++ <!-- need jdk1.8 or above -->
++ <fail message="Unsupported Java version: ${ant.java.version}. Please use Java version 1.8 or greater." unless="jdk1.8+">
++ </fail>
++ </target>
++
++ <target name="init" depends="check-ant-version, check-java-version, init-conditions, init-cc">
+ <!-- extends jvm args -->
+- <property name="run.test.jvmargs" value="${run.test.jvmargs.main} ${run.test.cc.jvmargs}"/>
+- <property name="run.test.jvmargs.octane" value="${run.test.jvmargs.octane.main} ${run.test.cc.jvmargs}" />
++ <property name="run.test.jvmargs" value="${run.test.jvmargs.main} ${run.test.cc.jvmargs} ${jfr.options}"/>
++ <property name="run.test.jvmargs.octane" value="${run.test.jvmargs.octane.main} ${run.test.cc.jvmargs} ${jfr.options}"/>
+
+ <echo message="run.test.jvmargs=${run.test.jvmargs}"/>
+ <echo message="run.test.jvmargs.octane=${run.test.jvmargs.octane}"/>
+@@ -100,19 +128,7 @@
+ <delete dir="${dist.dir}"/>
+ </target>
+
+- <!-- do it only if ASM is not available -->
+- <target name="compile-asm" depends="prepare" unless="asm.available">
+- <javac srcdir="${jdk.asm.src.dir}"
+- destdir="${build.classes.dir}"
+- excludes="**/optimizer/* **/xml/* **/attrs/*"
+- source="${javac.source}"
+- target="${javac.target}"
+- debug="${javac.debug}"
+- encoding="${javac.encoding}"
+- includeantruntime="false"/>
+- </target>
+-
+- <target name="compile" depends="compile-asm" description="Compiles nashorn">
++ <target name="compile" depends="prepare" description="Compiles nashorn">
+ <javac srcdir="${src.dir}"
+ destdir="${build.classes.dir}"
+ classpath="${javac.classpath}"
+@@ -122,8 +138,7 @@
+ encoding="${javac.encoding}"
+ includeantruntime="false" fork="true">
+ <compilerarg value="-J-Djava.ext.dirs="/>
+- <compilerarg value="-Xlint:unchecked"/>
+- <compilerarg value="-Xlint:deprecation"/>
++ <compilerarg value="-Xlint:all"/>
+ <compilerarg value="-XDignore.symbol.file"/>
+ <compilerarg value="-Xdiags:verbose"/>
+ </javac>
+@@ -140,6 +155,7 @@
+ <fileset dir="${src.dir}/jdk/nashorn/tools/resources/"/>
+ </copy>
+ <copy file="${src.dir}/jdk/internal/dynalink/support/messages.properties" todir="${build.classes.dir}/jdk/internal/dynalink/support"/>
++ <copy file="${src.dir}/jdk/nashorn/internal/codegen/anchor.properties" todir="${build.classes.dir}/jdk/nashorn/internal/codegen"/>
+
+ <echo message="full=${nashorn.fullversion}" file="${build.classes.dir}/jdk/nashorn/internal/runtime/resources/version.properties"/>
+ <echo file="${build.classes.dir}/jdk/nashorn/internal/runtime/resources/version.properties" append="true">${line.separator}</echo>
+@@ -291,6 +307,10 @@
+ <target name="generate-policy-file" depends="prepare">
+ <echo file="${build.dir}/nashorn.policy">
+
++grant codeBase "file:/${toString:dist.path}/nashorn.jar" {
++ permission java.security.AllPermission;
++};
++
+ grant codeBase "file:/${basedir}/${nashorn.internal.tests.jar}" {
+ permission java.security.AllPermission;
+ };
+@@ -298,6 +318,14 @@
+ grant codeBase "file:/${basedir}/${file.reference.testng.jar}" {
+ permission java.security.AllPermission;
+ };
++//// in case of absolute path:
++grant codeBase "file:/${nashorn.internal.tests.jar}" {
++ permission java.security.AllPermission;
++};
++
++grant codeBase "file:/${file.reference.testng.jar}" {
++ permission java.security.AllPermission;
++};
+
+ grant codeBase "file:/${basedir}/test/script/trusted/*" {
+ permission java.security.AllPermission;
+@@ -322,6 +350,13 @@
+ permission java.util.PropertyPermission "nashorn.test.*", "read";
+ };
+
++grant codeBase "file:/${basedir}/test/script/basic/es6/*" {
++ permission java.io.FilePermission "${basedir}/test/script/-", "read";
++ permission java.io.FilePermission "$${user.dir}", "read";
++ permission java.util.PropertyPermission "user.dir", "read";
++ permission java.util.PropertyPermission "nashorn.test.*", "read";
++};
++
+ grant codeBase "file:/${basedir}/test/script/basic/JDK-8010946-privileged.js" {
+ permission java.util.PropertyPermission "java.security.policy", "read";
+ };
+@@ -330,6 +365,10 @@
+ permission java.lang.RuntimePermission "nashorn.JavaReflection";
+ };
+
++grant codeBase "file:/${basedir}/test/script/markdown.js" {
++ permission java.io.FilePermission "${basedir}/test/script/external/showdown/-", "read";
++};
++
+ </echo>
+
+ <replace file="${build.dir}/nashorn.policy"><replacetoken>\</replacetoken><replacevalue>/</replacevalue></replace> <!--hack for Windows - to make URLs with normal path separators -->
+@@ -345,6 +384,7 @@
+ <available file="${test.external.dir}/yui" property="test-sys-prop.external.yui"/>
+ <available file="${test.external.dir}/jquery" property="test-sys-prop.external.jquery"/>
+ <available file="${test.external.dir}/test262" property="test-sys-prop.external.test262"/>
++ <available file="${test.external.dir}/showdown" property="test-sys-prop.external.markdown"/>
+ </target>
+
+ <target name="check-testng" unless="testng.available">
+@@ -377,10 +417,11 @@
+ <fileset id="test.nosecurity.classes" dir="${build.test.classes.dir}">
+ <include name="**/framework/ScriptTest.class"/>
+ </fileset>
+- <testng outputdir="${build.nosecurity.test.results.dir}" classfilesetref="test.nosecurity.classes"
++ <testng outputdir="${build.nosecurity.test.results.dir}/${testResultsSubDir}" classfilesetref="test.nosecurity.classes"
+ verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
+ <jvmarg line="${ext.class.path}"/>
+- <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx}"/>
++ <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} -Dbuild.dir=${build.dir}"/>
++ <sysproperty key="nashorn.jar" value="${dist.dir}/nashorn.jar"/>
+ <propertyset>
+ <propertyref prefix="nashorn."/>
+ </propertyset>
+@@ -388,6 +429,7 @@
+ <propertyref prefix="test-sys-prop-no-security."/>
+ <mapper from="test-sys-prop-no-security.*" to="*" type="glob"/>
+ </propertyset>
++ <sysproperty key="optimistic.override" value="${optimistic}"/>
+ <classpath>
+ <pathelement path="${run.test.classpath}"/>
+ </classpath>
+@@ -398,15 +440,19 @@
+ <target name="-test-security">
+ <delete dir="${build.dir}/nashorn_code_cache"/>
+ <property name="debug.test.jvmargs" value=""/>
+- <testng outputdir="${build.test.results.dir}" classfilesetref="test.classes"
+- verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
++ <testng outputdir="${build.test.results.dir}/${testResultsSubDir}" classfilesetref="test.classes"
++ verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
+ <jvmarg line="${ext.class.path}"/>
+- <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs}"/>
++ <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} -Dbuild.dir=${build.dir}"/>
+ <jvmarg line="${debug.test.jvmargs}"/>
+ <propertyset>
++ <propertyref prefix="nashorn."/>
++ </propertyset>
++ <propertyset>
+ <propertyref prefix="test-sys-prop."/>
+ <mapper from="test-sys-prop.*" to="*" type="glob"/>
+ </propertyset>
++ <sysproperty key="optimistic.override" value="${optimistic}"/>
+ <sysproperty key="test.js.excludes.file" value="${exclude.list}"/>
+ <classpath>
+ <pathelement path="${run.test.classpath}"/>
+@@ -414,18 +460,30 @@
+ </testng>
+ </target>
+
+- <target name="test" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file, -test-security, -test-nosecurity" if="testng.available"/>
++ <target name="test" depends="test-pessimistic, test-optimistic"/>
+
+- <target name="test-basicparallel" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file">
+- <!-- use just build.test.classes.dir to avoid referring to TestNG -->
+- <java classname="${parallel.test.runner}" dir="${basedir}" classpath="${build.test.classes.dir}" failonerror="true" fork="true">
+- <jvmarg line="${ext.class.path}"/>
+- <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs}"/>
+- <syspropertyset>
+- <propertyref prefix="test-sys-prop."/>
+- <mapper type="glob" from="test-sys-prop.*" to="*"/>
+- </syspropertyset>
+- </java>
++ <target name="test-optimistic" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
++ <echo message="Running test suite in OPTIMISTIC mode..."/>
++ <antcall target="-test-nosecurity" inheritRefs="true">
++ <param name="optimistic" value="true"/>
++ <param name="testResultsSubDir" value="optimistic"/>
++ </antcall>
++ <antcall target="-test-security" inheritRefs="true">
++ <param name="optimistic" value="true"/>
++ <param name="testResultsSubDir" value="optimistic"/>
++ </antcall>
++ </target>
++
++ <target name="test-pessimistic" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
++ <echo message="Running test suite in PESSIMISTIC mode..."/>
++ <antcall target="-test-nosecurity" inheritRefs="true">
++ <param name="optimistic" value="false"/>
++ <param name="testResultsSubDir" value="pessimistic"/>
++ </antcall>
++ <antcall target="-test-security" inheritRefs="true">
++ <param name="optimistic" value="false"/>
++ <param name="testResultsSubDir" value="pessimistic"/>
++ </antcall>
+ </target>
+
+ <target name="check-jemmy.jfx.testng" unless="jemmy.jfx.testng.available">
+@@ -436,19 +494,19 @@
+ <fileset id="test.classes" dir="${build.test.classes.dir}">
+ <include name="**/framework/*Test.class"/>
+ </fileset>
+-
++
+ <copy file="${file.reference.jfxrt.jar}" todir="dist"/>
+-
++
+ <condition property="jfx.prism.order" value="-Dprism.order=j2d" else=" ">
+- <not>
++ <not>
+ <os family="mac"/>
+ </not>
+- </condition>
+-
++ </condition>
++
+ <testng outputdir="${build.test.results.dir}" classfilesetref="test.classes"
+ verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
+ <jvmarg line="${ext.class.path}"/>
+- <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx}"/>
++ <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} -Dbuild.dir=${build.dir}"/>
+ <propertyset>
+ <propertyref prefix="testjfx-test-sys-prop."/>
+ <mapper from="testjfx-test-sys-prop.*" to="*" type="glob"/>
+@@ -459,7 +517,26 @@
+ </classpath>
+ </testng>
+ </target>
+-
++
++ <target name="testmarkdown" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
++ <fileset id="test.classes" dir="${build.test.classes.dir}">
++ <include name="**/framework/*Test.class"/>
++ </fileset>
++
++ <testng outputdir="${build.test.results.dir}" classfilesetref="test.classes"
++ verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
++ <jvmarg line="${ext.class.path}"/>
++ <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} -Dbuild.dir=${build.dir}"/>
++ <propertyset>
++ <propertyref prefix="testmarkdown-test-sys-prop."/>
++ <mapper from="testmarkdown-test-sys-prop.*" to="*" type="glob"/>
++ </propertyset>
++ <classpath>
++ <pathelement path="${run.test.classpath}"/>
++ </classpath>
++ </testng>
++ </target>
++
+ <target name="test262" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+ <fileset id="test.classes" dir="${build.test.classes.dir}">
+ <include name="**/framework/*Test.class"/>
+@@ -468,7 +545,10 @@
+ <testng outputdir="${build.test.results.dir}" classfilesetref="test.classes"
+ verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
+ <jvmarg line="${ext.class.path}"/>
+- <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs}"/>
++ <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} -Dbuild.dir=${build.dir}"/>
++ <propertyset>
++ <propertyref prefix="nashorn."/>
++ </propertyset>
+ <propertyset>
+ <propertyref prefix="test262-test-sys-prop."/>
+ <mapper from="test262-test-sys-prop.*" to="*" type="glob"/>
+@@ -485,7 +565,9 @@
+ <!-- use just build.test.classes.dir to avoid referring to TestNG -->
+ <java classname="${parallel.test.runner}" dir="${basedir}" fork="true">
+ <jvmarg line="${ext.class.path}"/>
+- <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs}"/>
++ <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} -Dbuild.dir=${build.dir}"/>
++ <!-- avoid too many typeinfo cache files. Each script is run only once anyway -->
++ <jvmarg line="-Dnashorn.typeInfo.disabled=true"/>
+ <classpath>
+ <pathelement path="${run.test.classpath}"/>
+ </classpath>
+@@ -496,6 +578,26 @@
+ </java>
+ </target>
+
++ <target name="testparallel" depends="test-parallel"/>
++
++ <target name="test-parallel" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
++ <!-- use just build.test.classes.dir to avoid referring to TestNG -->
++ <java classname="${parallel.test.runner}" dir="${basedir}"
++ failonerror="true"
++ fork="true">
++ <jvmarg line="${ext.class.path}"/>
++ <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs}"/>
++ <classpath>
++ <pathelement path="${run.test.classpath}"/>
++ <pathelement path="${build.test.classes.dir}"/>
++ </classpath>
++ <syspropertyset>
++ <propertyref prefix="test-sys-prop."/>
++ <mapper type="glob" from="test-sys-prop.*" to="*"/>
++ </syspropertyset>
++ </java>
++ </target>
++
+ <target name="all" depends="test, docs"
+ description="Build, test and generate docs for nashorn"/>
+
+@@ -529,6 +631,8 @@
+ <!-- clone test262 git repo -->
+ <exec executable="${git.executable}">
+ <arg value="clone"/>
++ <arg value="--branch"/>
++ <arg value="es5-tests"/>
+ <arg value="https://github.com/tc39/test262"/>
+ <arg value="${test.external.dir}/test262"/>
+ </exec>
+@@ -604,6 +708,11 @@
+ <get src="http://yui.yahooapis.com/3.5.1/build/yui/yui.js" dest="${test.external.dir}/yui" skipexisting="true" ignoreerrors="true"/>
+ <get src="http://yui.yahooapis.com/3.5.1/build/yui/yui-min.js" dest="${test.external.dir}/yui" skipexisting="true" ignoreerrors="true"/>
+
++ <!-- showdown -->
++ <mkdir dir="${test.external.dir}/showdown"/>
++ <get src="https://raw.github.com/coreyti/showdown/master/src/showdown.js" dest="${test.external.dir}/showdown" skipexisting="true" ignoreerrors="true"/>
++ <get src="https://raw.github.com/coreyti/showdown/master/src/extensions/table.js" dest="${test.external.dir}/showdown" skipexisting="true" ignoreerrors="true"/>
++
+ </target>
+
+ <!-- update external test suites that are pulled from source control systems -->
+@@ -619,4 +728,6 @@
+
+ <target name="alltests" depends="exit-if-no-testng, externals, update-externals, test, test262parallel, perf"/>
+
++ <import file="build-benchmark.xml"/>
++
+ </project>
+--- ./nashorn/make/nbproject/ide-targets.xml Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/make/nbproject/ide-targets.xml Wed Feb 04 12:14:47 2015 -0800
+@@ -31,9 +31,10 @@
+ <classpath path="${run.test.classpath}"/>
+ </nbjpdastart>
+ <java classname="jdk.nashorn.tools.Shell" classpath="${run.test.classpath}" dir="samples" fork="true">
++ <jvmarg line="-Dnashorn.optimistic"/>
+ <jvmarg line="${ext.class.path}"/>
+ <jvmarg line="${run.test.jvmargs}"/>
+- <arg value="test.js"/>
++ <arg value="../samples/test.js"/>
+ <jvmarg value="-Xdebug"/>
+ <jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
+ </java>
+--- ./nashorn/make/project.properties Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/make/project.properties Wed Feb 04 12:14:47 2015 -0800
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -53,6 +53,7 @@
+
+ # test classes directory
+ build.test.classes.dir=${build.dir}/test/classes
++
+ # nashorn test jar - internal tests jar and api tests jar
+ nashorn.internal.tests.jar=${build.dir}/nashorn-internal-tests.jar
+ nashorn.api.tests.jar=${build.dir}/nashorn-api-tests.jar
+@@ -60,6 +61,7 @@
+ # test results directory
+ build.test.results.dir=${build.dir}/test/reports
+ build.nosecurity.test.results.dir=${build.dir}/test/nosecurity/reports
++build.nooptimistic.test.results.dir=${build.dir}/test/nooptimistic/reports
+
+ # This directory is removed when the project is cleaned:
+ dist.dir=dist
+@@ -72,6 +74,9 @@
+ fxshell.dir = tools/fxshell
+ fxshell.jar = ${dist.dir}/nashornfx.jar
+
++# configuration for java flight recorder
++run.test.jvmargs.jfr=-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath=${build.dir},stackdepth=128
++
+ # jars refererred
+ file.reference.testng.jar=test/lib/testng.jar
+
+@@ -122,6 +127,7 @@
+ test262.dir=${test.external.dir}/test262
+ test262.suite.dir=${test262.dir}/test/suite
+ testjfx.dir=${test.script.dir}/jfx
++testmarkdown.dir=${test.script.dir}/markdown
+
+ test-sys-prop.test.dir=${test.dir}
+ test-sys-prop.test.js.roots=${test.basic.dir} ${test.maptests.dir} ${test.error.dir} ${test.sandbox.dir} ${test.trusted.dir}
+@@ -163,21 +169,14 @@
+ # test root for octane
+ octane-test-sys-prop.test.js.roots=${test.external.dir}/octane/
+
+-# run octane benchmars in separate processes?
++# run octane benchmars in separate processes? (recommended)
+ octane-test-sys-prop.separate.process=true
+
+ # framework root for octane
+ octane-test-sys-prop.test.js.framework=${test.basic.dir}/run-octane.js
+
+-# list of tests to be excluded
+-# mandreel excluded due to OOM
+-octane-test-sys-prop.test.js.exclude.list=\
+- base.js \
+- run.js \
+- mandreel.js
+-
+ # test root for sunspider
+-sunspider-test-sys-prop.test.js.roots=${test.external.dir}/sunspider/tests/sunspider-1.0/
++sunspider-test-sys-prop.test.js.roots=${test.external.dir}/sunspider/tests/sunspider-1.0.2/
+
+ # framework root for sunspider
+ sunspider-test-sys-prop.test.js.framework=${test.basic.dir}/runsunspider.js
+@@ -193,6 +192,7 @@
+
+ # test262 test root
+ test262-test-sys-prop.test.js.roots=${test262.suite.dir}
++
+ # test262 enable/disable strict mode tests
+ test262-test-sys-prop.test.js.enable.strict.mode=true
+
+@@ -202,7 +202,7 @@
+ # list of test262 test dirs to be excluded
+ test262-test-sys-prop.test.js.exclude.dir=\
+ ${test262.suite.dir}/intl402/ \
+- ${test262.suite.dir}/bestPractice/
++ ${test262.suite.dir}/bestPractice/
+
+ test262-test-sys-prop.test.failed.list.file=${build.dir}/test/failedTests
+
+@@ -216,8 +216,18 @@
+ ${test262.dir}/test/harness/framework.js \
+ ${test262.dir}/test/harness/sta.js
+
++# testmarkdown test root
++testmarkdown-test-sys-prop.test.js.roots=${testmarkdown.dir}
++
++# execute testmarkdown tests in shared nashorn context or not?
++testmarkdown-test-sys-prop.test.js.shared.context=false
++
++# framework root for markdown script tests
++testmarkdown-test-sys-prop.test.js.framework=\
++ ${test.script.dir}${file.separator}markdown.js
++
+ # testjfx test root
+-testjfx-test-sys-prop.test.js.roots=${testjfx.dir}
++testjfx-test-sys-prop.test.js.roots=${testjfx.dir}
+
+ # execute testjfx tests in shared nashorn context or not?
+ testjfx-test-sys-prop.test.js.shared.context=false
+@@ -254,48 +264,131 @@
+ run.test.xmx=2G
+ run.test.xms=2G
+
++# uncomment this jfr.args to enable light recordings. the stack needs to be cranked up to 1024 frames,
++# or everything will as of the now drown in lambda forms and be cut off.
++#
++#jfr.args=-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath="test_suite.jfr",stackdepth=1024 \
++
++jfr.args=
++
+ run.test.user.language=tr
+ run.test.user.country=TR
+
+-run.test.jvmargs.common=-server -XX:+TieredCompilation -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country} -XX:+HeapDumpOnOutOfMemoryError
+-
+-#-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M
+-# -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods
++run.test.jvmargs.common=\
++ -server \
++ -Dfile.encoding=UTF-8 \
++ -Duser.language=${run.test.user.language} \
++ -Duser.country=${run.test.user.country} \
++ -Dnashorn.typeInfo.cacheDir=${build.dir}${file.separator}test${file.separator}type_info_cache \
++ ${jfr.args} \
++ -XX:+HeapDumpOnOutOfMemoryError
+
+ # turn on assertions for tests
+ run.test.jvmargs.main=${run.test.jvmargs.common} -ea
+
+-#-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M
+-run.test.jvmargs.octane.main=${run.test.jvmargs.common}
++# Extra jvmargs that might be useful for debugging
++# and performance improvements/monitoring
++#
++# -XX:+UnlockDiagnosticVMOptions
++#
++# turn off compressed class pointers in metaspace
++# -XX:-UseCompressedKlassPointers
++#
++# dump the heap after every GC
++# -XX:+PrintHeapAtGC
++#
++# manually set a metaspace size for class data
++# -XX:ClassMetaspaceSize=300M
++#
++# print out methods compiled
++# -XX:+PrintCompilation
++#
++# print all compiled nmethods with oopmaps and lots of other info
++# -XX:+PrintNMethods
++#
++# activate the generic "UseNewCode" flag to test whatever functionality
++# lies behind it. This is the preferred way to test a, yet flagless,
++# feature in HotSpot - for example, the uncommon trap placement fix
++# was hidden behind this flag before it became the default
++#
++# -XX:+UnlockDiagnosticVMOptions -XX:+UseNewCode
++#
++# Crank up the type profile level to 222, which has some warmup
++# penalties, but produces much better code for JavaScript, where better
++# and more intrusive type profiling is required to get rid of
++# a large amount of unnecessary guard code, that could not otherwise
++# be eliminated
++#
++# -XX:TypeProfileLevel=222
++#
+
+-run.test.jvmsecurityargs=-Xverify:all -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy
++# Use best known performance options for octane
++run.test.jvmargs.octane.main=${run.test.jvmargs.common} -XX:TypeProfileLevel=222
++
++# Security manager args - make sure that we run with the nashorn.policy that the build creates
++run.test.jvmsecurityargs=-Xverify:all -Djava.security.manager -Djava.security.policy=${build.dir}/nashorn.policy
+
+ # VM options for script tests with @fork option
+ test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} -cp ${run.test.classpath}
+
+ # path of rhino.jar for benchmarks
+-rhino.jar=
++rhino.dir=
++rhino.jar=${rhino.dir}/js.jar
+
+ v8.shell=d8
+
++# How many iterations should 'ant octane' run for each
++# benchmark
++octane.iterations=25
++
++# List of octane tests to run, as properties prefixed with
++# "octane.benchmark." mapping to the benchmark name in
++# the test harness
++#
++# Octane tests that are disabled should have their entire line
++# commented out Tests may be disabled for functionality reasons when
++# they have bugs or when the runtime doesn't handle them (yet)
++octane.benchmark.box2d=box2d
++#octane.benchmark.code-load=code-load
++octane.benchmark.crypto=crypto
++octane.benchmark.deltablue=deltablue
++octane.benchmark.earley-boyer=earley-boyer
++octane.benchmark.gbemu=gbemu
++octane.benchmark.navier-stokes=navier-stokes
++octane.benchmark.mandreel=mandreel
++octane.benchmark.pdfjs=pdfjs
++octane.benchmark.raytrace=raytrace
++octane.benchmark.regexp=regexp
++octane.benchmark.richards=richards
++octane.benchmark.splay=splay
++#octane.benchmark.typescript=typescript
++#octane.benchmark.zlib=zlib
++
+ #path to rhino jar file
+ octaneperf-sys-prop.rhino.jar=${rhino.jar}
+
+ #timeout for performance tests in minutes
+ octaneperf-sys-prop.timeout.value=10
+
+-################
+-# codecoverage #
+-################
+- #enable/disable code coverage; please redifine in the ${user.home}/.nashorn.project.local.properties
++#how many iterations to run sunspider after warmup
++sunspider.iterations=3000
++
++#################
++# code coverage #
++#################
++
++#enable/disable code coverage; please redifine in the ${user.home}/.nashorn.project.local.properties
+ make.code.coverage=false
+- #type of codecoverage; one of static or dynamic. Now only dynamic is supported
++
++#type of codecoverage; one of static or dynamic. Now only dynamic is supported
+ jcov=dynamic
+- #naming of CC results
+- #NB directory specified in the cc.dir will be cleaned up!!!
++
++#naming of CC results
++#NB directory specified in the cc.dir will be cleaned up!!!
+ cc.dir=${basedir}/../Codecoverage_Nashorn
+ cc.result.file.name=CC_${jcov}_nashorn.xml
+- #dynamic CC parameters; please redefine in the ${user.home}/.nashorn.project.local.properties
++
++#dynamic CC parameters; please redefine in the ${user.home}/.nashorn.project.local.properties
+ jcov2.lib.dir=${basedir}/../jcov2/lib
+ jcov.jar=${jcov2.lib.dir}/jcov.jar
+ cc.include=jdk\.nashorn\.*
+--- ./nashorn/samples/BufferArray.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/BufferArray.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,8 +29,8 @@
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
++import java.nio.DoubleBuffer;
+ import jdk.nashorn.api.scripting.AbstractJSObject;
+-import java.nio.DoubleBuffer;
+
+ /**
+ * Simple class demonstrating pluggable script object
+@@ -52,41 +52,49 @@
+ // underlying nio buffer
+ private final DoubleBuffer buf;
+
+- public BufferArray(int size) {
++ /**
++ * Constructor
++ * @param size initial size
++ */
++ public BufferArray(final int size) {
+ buf = DoubleBuffer.allocate(size);
+ }
+
+- public BufferArray(DoubleBuffer buf) {
++ /**
++ * Constructur
++ * @param buf {@link DoubleBuffer} to link to
++ */
++ public BufferArray(final DoubleBuffer buf) {
+ this.buf = buf;
+ }
+
+ // called to check if indexed property exists
+ @Override
+- public boolean hasSlot(int index) {
++ public boolean hasSlot(final int index) {
+ return index > 0 && index < buf.capacity();
+ }
+
+ // get the value from that index
+ @Override
+- public Object getSlot(int index) {
++ public Object getSlot(final int index) {
+ return buf.get(index);
+ }
+
+ // set the value at that index
+ @Override
+- public void setSlot(int index, Object value) {
++ public void setSlot(final int index, final Object value) {
+ buf.put(index, ((Number)value).doubleValue());
+ }
+
+ // do you have a property of that given name?
+ @Override
+- public boolean hasMember(String name) {
++ public boolean hasMember(final String name) {
+ return "length".equals(name) || "buf".equals(name);
+ }
+
+ // get the value of that named property
+ @Override
+- public Object getMember(String name) {
++ public Object getMember(final String name) {
+ switch (name) {
+ case "length":
+ return buf.capacity();
+@@ -94,7 +102,7 @@
+ // return a 'function' value for this property
+ return new AbstractJSObject() {
+ @Override
+- public Object call(Object thiz, Object... args) {
++ public Object call(final Object thiz, final Object... args) {
+ return BufferArray.this.buf;
+ }
+
+@@ -104,6 +112,8 @@
+ return true;
+ }
+ };
++ default:
++ break;
+ }
+ return null;
+ }
+--- ./nashorn/samples/array_mapreduce.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/array_mapreduce.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -31,9 +31,9 @@
+
+ // Usage: jjs array_mapreduce.js
+
+-// Many Array.prototype functions such as map,
++// Many Array.prototype functions such as map,
+ // filter, reduce, reduceRight, every, some are generic.
+-// These functions accept ECMAScript array as well as
++// These functions accept ECMAScript array as well as
+ // many array-like objects including java arrays.
+ // So, you can do map/filter/reduce with Java streams or
+ // you can also use Array.prototype functions as below.
+@@ -73,6 +73,6 @@
+ // print sum of squares of the random numbers
+ print("Square sum:",
+ reduce.call(
+- map.call(jarr, function(x) x*x),
++ map.call(jarr, function(x) x*x),
+ function(x, y) x + y)
+ );
+--- ./nashorn/samples/astviewer.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/astviewer.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -82,7 +82,7 @@
+ // load parser.js from nashorn resources
+ load("nashorn:parser.js");
+
+-// read the full content of the file and parse it
++// read the full content of the file and parse it
+ // to get AST of the script specified
+ var ast = parse(readFully(sourceName));
+
+--- ./nashorn/samples/barchart_weather.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/barchart_weather.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/samples/browser_dom.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,91 @@
++#// Usage: jjs -fx browser.js
++
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * - Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * - Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * - Neither the name of Oracle nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++if (!$OPTIONS._fx) {
++ print("Usage: jjs -fx browser.js");
++ exit(1);
++}
++
++// JavaFX classes used
++var ChangeListener = Java.type("javafx.beans.value.ChangeListener");
++var Scene = Java.type("javafx.scene.Scene");
++var WebView = Java.type("javafx.scene.web.WebView");
++var EventListener = Java.type("org.w3c.dom.events.EventListener");
++
++// JavaFX start method
++function start(stage) {
++ start.title = "Web View";
++ var wv = new WebView();
++ wv.engine.loadContent(<<EOF
++<html>
++<head>
++<title>
++This is the title
++</title>
++<script>
++// click count for OK button
++var okCount = 0;
++</script>
++</head>
++<body>
++Button from the input html<br>
++<button type="button" onclick="okCount++">OK</button><br>
++</body>
++</html>
++EOF, "text/html");
++
++ // attach onload handler
++ wv.engine.loadWorker.stateProperty().addListener(
++ new ChangeListener() {
++ changed: function() {
++ // DOM document element
++ var document = wv.engine.document;
++ // DOM manipulation
++ var btn = document.createElement("button");
++ var n = 0;
++ // attach a button handler - nashorn function!
++ btn.onclick = new EventListener(function() {
++ n++; print("You clicked " + n + " time(s)");
++ print("you clicked OK " + wv.engine.executeScript("okCount"));
++ });
++ // attach text to button
++ var t = document.createTextNode("Click Me!");
++ btn.appendChild(t);
++ // attach button to the document
++ document.body.appendChild(btn);
++ }
++ }
++ );
++ stage.scene = new Scene(wv, 750, 500);
++ stage.show();
++}
+--- ./nashorn/samples/call_lambda.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/call_lambda.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/counters.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/counters.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/dirname.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/dirname.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/disassemble.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/disassemble.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -33,7 +33,7 @@
+
+ // Simple .class disassembler that uses bundled ObjectWeb ASM
+ // classes in jdk8. WARNING: Bundled ObjectWeb ASM classes are
+-// not part of official jdk8 API. It can be changed/removed
++// not part of official jdk8 API. It can be changed/removed
+ // without notice. So, this script is brittle by design!
+
+ // This example demonstrates passing arguments to script
+--- ./nashorn/samples/engine/accessvar.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/engine/accessvar.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/engine/callfunc.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/engine/callfunc.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -29,7 +29,7 @@
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+-// simple example showing how to call a global script
++// simple example showing how to call a global script
+ // function from caller
+
+ var ScriptEngineManager = Java.type("javax.script.ScriptEngineManager");
+@@ -42,7 +42,7 @@
+ engine.eval("function func(name) { print('I am func, hello ' + name) }");
+
+ // invoke functions, methods of code evaluated by engine
+-// from javax.script.Invocable interface. But, hey,
++// from javax.script.Invocable interface. But, hey,
+ // calling code is JavaScript and don't worry about types :)
+
+ engine.invokeFunction("func", "Nashorn");
+--- ./nashorn/samples/engine/callmethod.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/engine/callmethod.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -55,7 +55,7 @@
+ CODE);
+
+ // invoke methods of an object in script world
+-// from javax.script.Invocable interface. But, hey,
++// from javax.script.Invocable interface. But, hey,
+ // calling code is JavaScript and don't worry about types :)
+
+ // get that script object on which to call a method
+--- ./nashorn/samples/engine/exposevar.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/engine/exposevar.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/engine/foreignobject.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/engine/foreignobject.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -54,7 +54,7 @@
+ // the class jdk.nashorn.api.scripting.ScriptObjectMirror
+ // But nashorn's dynalink linker can treat these objects
+ // specially to support natural script syntax to access..
+-// In Java code, you need to use ScriptObjectMirror's
++// In Java code, you need to use ScriptObjectMirror's
+ // methods though. Once again, script world is simpler :-)
+
+ var foreignObj = engine.get("obj");
+--- ./nashorn/samples/engine/hello.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/engine/hello.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/engine/interface.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/engine/interface.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -50,7 +50,7 @@
+
+ // create Java interface object whose methods are
+ // implemented by script functions. This is from
+-// javax.script.Invocable. But we are in JS world,
++// javax.script.Invocable. But we are in JS world,
+ // don't worry about types :)
+
+ var Runnable = Java.type("java.lang.Runnable");
+--- ./nashorn/samples/engine/interface2.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/engine/interface2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/engine/lambda_as_func.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/engine/lambda_as_func.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/env.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/env.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -31,8 +31,8 @@
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+-// In nashorn -scripting mode,
+-// "$ENV" object exposes process
++// In nashorn -scripting mode,
++// "$ENV" object exposes process
+ // environment variables
+
+ print($ENV.PATH);
+--- ./nashorn/samples/expression_closure.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/expression_closure.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/filebrowser.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/filebrowser.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/fileline.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/fileline.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/samples/find_nonfinals2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,118 @@
++#// Usage: jjs find_nonfinals2.js -- <directory>
++
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * - Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * - Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * - Neither the name of Oracle nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++// This example demonstrates Java subclassing by Java.extend
++// and javac Compiler and Tree API. This example finds method
++// parameters without "final" keyword and prints info on those.
++
++if (arguments.length == 0) {
++ print("Usage: jjs find_nonfinals2.js -- <directory>");
++ exit(1);
++}
++
++// Java types used
++var File = Java.type("java.io.File");
++var Files = Java.type("java.nio.file.Files");
++var FileVisitOption = Java.type("java.nio.file.FileVisitOption");
++var StringArray = Java.type("java.lang.String[]");
++var ToolProvider = Java.type("javax.tools.ToolProvider");
++var Tree = Java.type("com.sun.source.tree.Tree");
++var TreeScanner = Java.type("com.sun.source.util.TreeScanner");
++var Modifier = Java.type("javax.lang.model.element.Modifier");
++
++function checkNonFinalParams(p) {
++ // get the system compiler tool
++ var compiler = ToolProvider.systemJavaCompiler;
++ // get standard file manager
++ var fileMgr = compiler.getStandardFileManager(null, null, null);
++ // Using Java.to convert script array (arguments) to a Java String[]
++ var compUnits = fileMgr.getJavaFileObjects(
++ Java.to(arguments, StringArray));
++ // create a new compilation task
++ var task = compiler.getTask(null, fileMgr, null, null, null, compUnits);
++ // subclass SimpleTreeVisitor - to find non-final method params
++ var NonFinalsFinder = Java.extend(TreeScanner);
++
++ function printMethod(method) {
++ print(method.modifiers + " "+ method.returnType + " " +
++ method.name + "(" + method.parameters + ")");
++ }
++
++ var pkgName, clsName, compUnitName, lineMap;
++ var visitor = new NonFinalsFinder() {
++ visitCompilationUnit: function(compUnit, p) {
++ pkgName = compUnit.packageName;
++ compUnitName = compUnit.sourceFile.name;
++ lineMap = compUnit.lineMap;
++ return Java.super(visitor).visitCompilationUnit(compUnit, p);
++ },
++
++ visitClass: function(clazz, p) {
++ clsName = clazz.name;
++ return Java.super(visitor).visitClass(clazz, p);
++ },
++
++ visitMethod: function (method, p) {
++ var params = method.parameters;
++ for each (var p in params) {
++ var modifiers = p.modifiers;
++ if (! modifiers.flags.contains(Modifier.FINAL)) {
++ print(compUnitName);
++ print(pkgName + "." + clsName);
++ printMethod(method);
++ print("->", p,
++ " @ " + lineMap.getLineNumber(p.pos) + ":" +
++ lineMap.getColumnNumber(p.pos));
++ }
++ }
++ }
++ }
++
++ for each (var cu in task.parse()) {
++ cu.accept(visitor, null);
++ }
++}
++
++// for each ".java" file in directory (recursively).
++function main(dir) {
++ var totalCount = 0;
++ Files.walk(dir.toPath(), FileVisitOption.FOLLOW_LINKS).
++ forEach(function(p) {
++ var name = p.toFile().absolutePath;
++ if (name.endsWith(".java")) {
++ checkNonFinalParams(p);
++ }
++ });
++}
++
++main(new File(arguments[0]));
+--- ./nashorn/samples/fizzbuzz.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/fizzbuzz.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/for_each.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/for_each.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -42,7 +42,7 @@
+ var arr = new JArray(10);
+
+ // store squares as values
+-for (i in arr)
++for (i in arr)
+ arr[i] = i*i;
+
+ // for .. each on java arrays
+@@ -57,7 +57,7 @@
+ print("System properties");
+ for each (p in System.properties.entrySet()) {
+ print(p.key, "=", p.value);
+-}
++}
+
+ // print process environment vars as name = value pairs
+ print("Process environment");
+--- ./nashorn/samples/gaussian_random.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/gaussian_random.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -37,7 +37,7 @@
+ var r = new Random();
+
+ // expression closure (see expression_closure.js as well)
+-// passed as lambda double generator. "print" passed as
++// passed as lambda double generator. "print" passed as
+ // double consumer lambda to 'forEach' method.
+
+ DoubleStream
+--- ./nashorn/samples/gaussian_random_bind.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/gaussian_random_bind.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -34,7 +34,7 @@
+ var Random = Java.type("java.util.Random");
+ var DoubleStream = Java.type("java.util.stream.DoubleStream");
+
+-// function as lambda double generator. "print" passed as
++// function as lambda double generator. "print" passed as
+ // double consumer lambda to 'forEach' method.
+ // Function.prototype.bind used to attach 'state' for the
+ // generator function.
+--- ./nashorn/samples/gutenberg.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/gutenberg.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -69,7 +69,7 @@
+ // capture title, description now
+ inItem = true;
+ }
+-
++
+ if (inItem) {
+ switch (local) {
+ case 'title':
+--- ./nashorn/samples/heredoc.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/heredoc.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -38,14 +38,14 @@
+
+ var sender = "Buffy the Vampire Slayer";
+ var recipient = "Spike";
+-
++
+ print(<<END
+-
++
+ Dear ${recipient},
+-
++
+ I wish you to leave Sunnydale and never return.
+-
++
+ Not Quite Love,
+ ${sender}
+-
++
+ END);
+--- ./nashorn/samples/interface_impl.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/interface_impl.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/javaastviewer.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/javaastviewer.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -56,8 +56,8 @@
+ // may not be exhaustive - any getAbc would become "abc" property or
+ // public field becomes a property of same name.
+ var ignoredProps = new HashSet();
+- for each (var word in
+- ['extending', 'implementing', 'init', 'mods', 'clazz', 'defs',
++ for each (var word in
++ ['extending', 'implementing', 'init', 'mods', 'clazz', 'defs',
+ 'expr', 'tag', 'preferredPosition', 'qualid', 'recvparam',
+ 'restype', 'params', 'startPosition', 'thrown',
+ 'tree', 'typarams', 'typetag', 'vartype']) {
+@@ -83,7 +83,7 @@
+
+ var visitor = new ConverterVisitor() {
+ // convert java AST node to a friendly script object
+- // which can be viewed. Every node ends up in defaultAction
++ // which can be viewed. Every node ends up in defaultAction
+ // method of SimpleTreeVisitor method.
+
+ defaultAction: function (node, p) {
+--- ./nashorn/samples/javacastcounter.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/javacastcounter.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -83,7 +83,7 @@
+ this.lineMap = node.lineMap;
+ this.fileName = node.sourceFile.name;
+
+- // Using Java.super API to call super class method here
++ // Using Java.super API to call super class method here
+ return Java.super(counter).visitCompilationUnit(node, p);
+ },
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/samples/javafoovars.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,103 @@
++#// Usage: jjs javafoovars.js -- <directory>
++
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * - Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * - Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * - Neither the name of Oracle nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++// This example demonstrates Java subclassing by Java.extend
++// and javac Compiler and Tree API. This example counts number
++// of variables called "foo" in the given java source files!
++if (arguments.length == 0) {
++ print("Usage: jjs javafoovars.js -- <directory>");
++ exit(1);
++}
++
++// Java types used
++var File = Java.type("java.io.File");
++var Files = Java.type("java.nio.file.Files");
++var FileVisitOption = Java.type("java.nio.file.FileVisitOption");
++var StringArray = Java.type("java.lang.String[]");
++var ToolProvider = Java.type("javax.tools.ToolProvider");
++var Tree = Java.type("com.sun.source.tree.Tree");
++var TreeScanner = Java.type("com.sun.source.util.TreeScanner");
++var VariableTree = Java.type("com.sun.source.tree.VariableTree");
++
++// count "foo"-s in the given .java files
++function countFoo() {
++ // get the system compiler tool
++ var compiler = ToolProvider.systemJavaCompiler;
++ // get standard file manager
++ var fileMgr = compiler.getStandardFileManager(null, null, null);
++ // Using Java.to convert script array (arguments) to a Java String[]
++ var compUnits = fileMgr.getJavaFileObjects(
++ Java.to(arguments, StringArray));
++ // create a new compilation task
++ var task = compiler.getTask(null, fileMgr, null, null, null, compUnits);
++ // subclass SimpleTreeVisitor - to count variables called "foo"
++ var FooCounterVisitor = Java.extend(TreeScanner);
++ var fooCount = 0;
++
++ var visitor = new FooCounterVisitor() {
++ visitVariable: function (node, p) {
++ if (node.name.toString() == "foo") {
++ fooCount++;
++ }
++ }
++ }
++
++ for each (var cu in task.parse()) {
++ cu.accept(visitor, null);
++ }
++ return fooCount;
++}
++
++// for each ".java" file in directory (recursively) count "foo".
++function main(dir) {
++ var totalCount = 0;
++ Files.walk(dir.toPath(), FileVisitOption.FOLLOW_LINKS).
++ forEach(function(p) {
++ var name = p.toFile().absolutePath;
++ if (name.endsWith(".java")) {
++ var count = 0;
++ try {
++ count = countFoo(p.toFile().getAbsolutePath());
++ } catch (e) {
++ print(e);
++ }
++ if (count != 0) {
++ print(name + ": " + count);
++ }
++ totalCount += count;
++ }
++ });
++ print("Total foo count: " + totalCount);
++}
++
++main(new File(arguments[0]));
+--- ./nashorn/samples/javaimporter.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/javaimporter.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -34,14 +34,14 @@
+
+ function readTextFromURL(url) {
+
+- // equivalent to
+- //
++ // equivalent to
++ //
+ // import java.io.*;
+ // import java.net.*;
+ // import java.lang.StringBuffer;
+ //
+ // only inside the 'with' statement
+- with (new JavaImporter(java.io,
++ with (new JavaImporter(java.io,
+ java.net,
+ java.lang.StringBuilder)) {
+ var buf = new StringBuilder();
+--- ./nashorn/samples/javalist.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/javalist.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/javamap.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/javamap.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -45,7 +45,7 @@
+ print(map['js']);
+ print(map.js);
+
+-// also assign new key-value pair
++// also assign new key-value pair
+ // as 'property-value'
+ map['language'] = 'java';
+ print(map.get("language"));
+--- ./nashorn/samples/javashell.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/javashell.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -130,7 +130,7 @@
+ // generate unique name
+ function uniqueName() {
+ var now = LocalDateTime.now().toString();
+- // replace unsafe chars with '_'
++ // replace unsafe chars with '_'
+ return "JavaShell" + now.replace(/-|:|\./g, '_');
+ }
+
+--- ./nashorn/samples/jsadapter_dom.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/jsadapter_dom.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -33,7 +33,7 @@
+
+ // Simple example that demonstrates reading XML Rss feed
+ // to generate a HTML file from script and show it by browser
+-// Uses XML DOM parser and DOM element wrapped by script
++// Uses XML DOM parser and DOM element wrapped by script
+ // "proxy" (JSAdapter constructor)
+
+ // Java classes used
+@@ -78,7 +78,7 @@
+ var node = nodeList.item(i);
+ if (node.nodeType == TEXT_NODE) {
+ text += node.nodeValue;
+- }
++ }
+ }
+
+ return text;
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/samples/jsobj_example.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,73 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * - Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * - Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * - Neither the name of Oracle nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++// Flexible script object using AbstractJSObject subclass
++
++var AbstractJSObject = Java.type("jdk.nashorn.api.scripting.AbstractJSObject");
++
++// JSObject example that uses a map for properties and
++// falls back to with methods on a java object (for missing
++// properties
++
++function makeJSObj(map, fallback) {
++ return new AbstractJSObject() {
++ getMember: function(name) {
++ if (map.containsKey(name)) {
++ return map.get(name);
++ }
++
++ var val = fallback[name];
++ if (typeof val == 'function') {
++ return function() {
++ var a = arguments;
++ switch (a.length) {
++ case 0: return fallback[name]();
++ case 1: return fallback[name](a[0]);
++ case 2: return fallback[name](a[0], a[1]);
++ case 3: return fallback[name](a[0], a[1], a[2]);
++ case 4: return fallback[name](a[0], a[1], a[2], a[3]);
++ }
++ }
++ }
++ }
++ }
++}
++
++var m = new java.util.HashMap();
++m.put("foo", 42);
++m.put("bar", 'hello');
++
++var obj = makeJSObj(m, new java.io.File("."));
++
++print(obj.foo);
++print(obj.bar);
++print(obj.getAbsolutePath());
++print(obj.isDirectory());
+--- ./nashorn/samples/jsobject.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/jsobject.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/jsobject_mapreduce.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/jsobject_mapreduce.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -31,9 +31,9 @@
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+-// Many Array.prototype functions such as map,
++// Many Array.prototype functions such as map,
+ // filter, reduce, reduceRight, every, some are generic.
+-// These functions accept ECMAScript array as well as
++// These functions accept ECMAScript array as well as
+ // many array-like objects including JSObjects.
+ // See also http://en.wikipedia.org/wiki/MapReduce
+
+@@ -57,6 +57,6 @@
+ // print sum of squares of the random numbers
+ print("Square sum:",
+ reduce.call(
+- map.call(buf, function(x) x*x),
++ map.call(buf, function(x) x*x),
+ function(x, y) x + y)
+ );
+--- ./nashorn/samples/jsonviewer.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/jsonviewer.js Wed Feb 04 12:14:47 2015 -0800
+@@ -4,22 +4,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -52,8 +52,8 @@
+
+ // read text content of a URL
+ function readTextFromURL(url) {
+- // equivalent to
+- //
++ // equivalent to
++ //
+ // import java.io.*;
+ // import java.net.*;
+ // import java.lang.StringBuffer;
+--- ./nashorn/samples/letter.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/letter.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -43,7 +43,7 @@
+ // JavaScript style line comment is ok too.
+ print(<<EOF);
+ Dear ${obj.recipient},
+-
++
+ I wish you all the best.
+
+ Regards,
+--- ./nashorn/samples/list_mapreduce.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/list_mapreduce.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -31,9 +31,9 @@
+
+ // Usage: jjs list_mapreduce.js
+
+-// Many Array.prototype functions such as map,
++// Many Array.prototype functions such as map,
+ // filter, reduce, reduceRight, every, some are generic.
+-// These functions accept ECMAScript array as well as
++// These functions accept ECMAScript array as well as
+ // many array-like objects including java.util.ArrayLists.
+ // So, you can do map/filter/reduce with Java streams or
+ // you can also use Array.prototype functions as below.
+@@ -81,6 +81,6 @@
+ // print sum of squares of the random numbers
+ print("Square sum:",
+ reduce.call(
+- map.call(list, function(x) x*x),
++ map.call(list, function(x) x*x),
+ function(x, y) x + y)
+ );
+--- ./nashorn/samples/locales.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/locales.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/logisticmap.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/logisticmap.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/options.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/options.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/parser.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/parser.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/readLine.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/readLine.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/sam_function.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/sam_function.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -46,6 +46,6 @@
+ }, 1000);
+
+ // wait for timer thread to print by
+-// reading from stdin.
++// reading from stdin.
+ print("press any key to exit after message from timer...");
+ System.in.read();
+--- ./nashorn/samples/shell.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/shell.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/stack.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/stack.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -33,7 +33,7 @@
+ // error objects. This property's value is a string
+ // that shows script stack trace.
+
+-function g() {
++function g() {
+ throw new Error("wrong");
+ }
+
+@@ -44,9 +44,9 @@
+ // Output looks something like:
+ //
+ // Error: wrong
+-// at g (stack.js:37)
+-// at f (stack.js:41)
+-// at <program> (stack.js:52)
++// at g (stack.js:37)
++// at f (stack.js:41)
++// at <program> (stack.js:52)
+
+ try {
+ f();
+--- ./nashorn/samples/uniform_random.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/uniform_random.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/uniq.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/uniq.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/uniqs.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/uniqs.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -31,7 +31,7 @@
+
+ // Usage: jjs uniqs.js -- <file>
+ // omit repeated lines and print unique lines
+-// But this version uses Stream API
++// But this version uses Stream API
+
+ if (arguments.length < 1) {
+ print("Usage: jjs uniqs.js -- <file>");
+--- ./nashorn/samples/weather.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/weather.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/samples/word_histogram.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/samples/word_histogram.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,22 +2,22 @@
+
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/samples/zipfs.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * - Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * - Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * - Neither the name of Oracle nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++if (arguments.length == 0) {
++ print("Usage: jjs zipfs.js -- <.zip/.jar file>")
++ exit(1)
++}
++
++var Files = Java.type("java.nio.file.Files")
++var FileSystems = Java.type("java.nio.file.FileSystems")
++var FileVisitOption = Java.type("java.nio.file.FileVisitOption")
++var Paths = Java.type("java.nio.file.Paths")
++
++var zipfile = Paths.get(arguments[0])
++var fs = FileSystems.newFileSystem(zipfile, null)
++var root = fs.rootDirectories[0]
++Files.walk(root, FileVisitOption.FOLLOW_LINKS).forEach(
++ function(p) (print(p), print(Files.readAttributes(p, "zip:*")))
++)
++fs.close()
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/samples/ziplist.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,80 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * - Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * - Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * - Neither the name of Oracle nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++if (arguments.length == 0) {
++ print("Usage: jjs ziplist -- <zip-file>");
++ exit(1);
++}
++
++// list the content details of a .zip or .jar file
++var file = arguments[0];
++
++// java classes used
++var Attributes = Java.type("java.util.jar.Attributes");
++var FileTime = Java.type("java.nio.file.attribute.FileTime");
++var JarFile = Java.type("java.util.jar.JarFile");
++var ZipEntry = Java.type("java.util.zip.ZipEntry");
++var ZipFile = Java.type("java.util.zip.ZipFile");
++
++var zf = file.endsWith(".jar")? new JarFile(file) : new ZipFile(file);
++
++var entries = zf.entries();
++// make overall output a valid JSON
++var zfObj = {
++ name: zf.name,
++ comment: zf.comment,
++ size: zf.size(),
++ entries: []
++};
++
++while (entries.hasMoreElements()) {
++ zfObj.entries.push(entries.nextElement());
++}
++
++print(JSON.stringify(zfObj, function (key, value) {
++ if (value instanceof ZipEntry) {
++ return Object.bindProperties({}, value);
++ } else if (value instanceof FileTime) {
++ return value.toString();
++ } else if (value instanceof Attributes) {
++ var attrs = {};
++ var itr = value.entrySet().iterator();
++ while (itr.hasNext()) {
++ var n = itr.next();
++ attrs[n.key] = String(n.value);
++ }
++ return attrs;
++ }
++
++ return value;
++}, ' '));
++
++zf.close();
+--- ./nashorn/src/jdk/internal/dynalink/ChainedCallSite.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/ChainedCallSite.java Wed Feb 04 12:14:47 2015 -0800
+@@ -103,8 +103,27 @@
+ * handle is always at the start of the chain.
+ */
+ public class ChainedCallSite extends AbstractRelinkableCallSite {
+- private static final MethodHandle PRUNE = Lookup.findOwnSpecial(MethodHandles.lookup(), "prune", MethodHandle.class,
+- MethodHandle.class);
++ private static final MethodHandle PRUNE_CATCHES =
++ MethodHandles.insertArguments(
++ Lookup.findOwnSpecial(
++ MethodHandles.lookup(),
++ "prune",
++ MethodHandle.class,
++ MethodHandle.class,
++ boolean.class),
++ 2,
++ true);
++
++ private static final MethodHandle PRUNE_SWITCHPOINTS =
++ MethodHandles.insertArguments(
++ Lookup.findOwnSpecial(
++ MethodHandles.lookup(),
++ "prune",
++ MethodHandle.class,
++ MethodHandle.class,
++ boolean.class),
++ 2,
++ false);
+
+ private final AtomicReference<LinkedList<GuardedInvocation>> invocations = new AtomicReference<>();
+
+@@ -112,7 +131,7 @@
+ * Creates a new chained call site.
+ * @param descriptor the descriptor for the call site.
+ */
+- public ChainedCallSite(CallSiteDescriptor descriptor) {
++ public ChainedCallSite(final CallSiteDescriptor descriptor) {
+ super(descriptor);
+ }
+
+@@ -126,24 +145,26 @@
+ }
+
+ @Override
+- public void relink(GuardedInvocation guardedInvocation, MethodHandle fallback) {
+- relinkInternal(guardedInvocation, fallback, false);
++ public void relink(final GuardedInvocation guardedInvocation, final MethodHandle fallback) {
++ relinkInternal(guardedInvocation, fallback, false, false);
+ }
+
+ @Override
+- public void resetAndRelink(GuardedInvocation guardedInvocation, MethodHandle fallback) {
+- relinkInternal(guardedInvocation, fallback, true);
++ public void resetAndRelink(final GuardedInvocation guardedInvocation, final MethodHandle fallback) {
++ relinkInternal(guardedInvocation, fallback, true, false);
+ }
+
+- private MethodHandle relinkInternal(GuardedInvocation invocation, MethodHandle relink, boolean reset) {
++ private MethodHandle relinkInternal(final GuardedInvocation invocation, final MethodHandle relink, final boolean reset, final boolean removeCatches) {
+ final LinkedList<GuardedInvocation> currentInvocations = invocations.get();
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ final LinkedList<GuardedInvocation> newInvocations =
+ currentInvocations == null || reset ? new LinkedList<>() : (LinkedList)currentInvocations.clone();
+
+- // First, prune the chain of invalidated switchpoints.
+- for(Iterator<GuardedInvocation> it = newInvocations.iterator(); it.hasNext();) {
+- if(it.next().hasBeenInvalidated()) {
++ // First, prune the chain of invalidated switchpoints, we always do this
++ // We also remove any catches if the remove catches flag is set
++ for(final Iterator<GuardedInvocation> it = newInvocations.iterator(); it.hasNext();) {
++ final GuardedInvocation inv = it.next();
++ if(inv.hasBeenInvalidated() || (removeCatches && inv.getException() != null)) {
+ it.remove();
+ }
+ }
+@@ -160,12 +181,13 @@
+
+ // prune-and-invoke is used as the fallback for invalidated switchpoints. If a switchpoint gets invalidated, we
+ // rebuild the chain and get rid of all invalidated switchpoints instead of letting them linger.
+- final MethodHandle pruneAndInvoke = makePruneAndInvokeMethod(relink);
++ final MethodHandle pruneAndInvokeSwitchPoints = makePruneAndInvokeMethod(relink, getPruneSwitchpoints());
++ final MethodHandle pruneAndInvokeCatches = makePruneAndInvokeMethod(relink, getPruneCatches());
+
+ // Fold the new chain
+ MethodHandle target = relink;
+- for(GuardedInvocation inv: newInvocations) {
+- target = inv.compose(pruneAndInvoke, target);
++ for(final GuardedInvocation inv: newInvocations) {
++ target = inv.compose(target, pruneAndInvokeSwitchPoints, pruneAndInvokeCatches);
+ }
+
+ // If nobody else updated the call site while we were rebuilding the chain, set the target to our chain. In case
+@@ -178,14 +200,30 @@
+ }
+
+ /**
++ * Get the switchpoint pruning function for a chained call site
++ * @return function that removes invalidated switchpoints tied to callsite guard chain and relinks
++ */
++ protected MethodHandle getPruneSwitchpoints() {
++ return PRUNE_SWITCHPOINTS;
++ }
++
++ /**
++ * Get the catch pruning function for a chained call site
++ * @return function that removes all catches tied to callsite guard chain and relinks
++ */
++ protected MethodHandle getPruneCatches() {
++ return PRUNE_CATCHES;
++ }
++
++ /**
+ * Creates a method that rebuilds our call chain, pruning it of any invalidated switchpoints, and then invokes that
+ * chain.
+ * @param relink the ultimate fallback for the chain (the {@code DynamicLinker}'s relink).
+ * @return a method handle for prune-and-invoke
+ */
+- private MethodHandle makePruneAndInvokeMethod(MethodHandle relink) {
++ private MethodHandle makePruneAndInvokeMethod(final MethodHandle relink, final MethodHandle prune) {
+ // Bind prune to (this, relink)
+- final MethodHandle boundPrune = MethodHandles.insertArguments(PRUNE, 0, this, relink);
++ final MethodHandle boundPrune = MethodHandles.insertArguments(prune, 0, this, relink);
+ // Make it ignore all incoming arguments
+ final MethodHandle ignoreArgsPrune = MethodHandles.dropArguments(boundPrune, 0, type().parameterList());
+ // Invoke prune, then invoke the call site target with original arguments
+@@ -193,7 +231,7 @@
+ }
+
+ @SuppressWarnings("unused")
+- private MethodHandle prune(MethodHandle relink) {
+- return relinkInternal(null, relink, false);
++ private MethodHandle prune(final MethodHandle relink, final boolean catches) {
++ return relinkInternal(null, relink, false, catches);
+ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/DefaultBootstrapper.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/DefaultBootstrapper.java Wed Feb 04 12:14:47 2015 -0800
+@@ -117,7 +117,7 @@
+ * @param type the method signature at the call site
+ * @return a new {@link MonomorphicCallSite} linked with the default dynamic linker.
+ */
+- public static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type) {
++ public static CallSite bootstrap(final MethodHandles.Lookup caller, final String name, final MethodType type) {
+ return bootstrapInternal(caller, name, type);
+ }
+
+@@ -133,11 +133,11 @@
+ * @param type the method signature at the call site
+ * @return a new {@link MonomorphicCallSite} linked with the default dynamic linker.
+ */
+- public static CallSite publicBootstrap(MethodHandles.Lookup caller, String name, MethodType type) {
++ public static CallSite publicBootstrap(final MethodHandles.Lookup caller, final String name, final MethodType type) {
+ return bootstrapInternal(MethodHandles.publicLookup(), name, type);
+ }
+
+- private static CallSite bootstrapInternal(MethodHandles.Lookup caller, String name, MethodType type) {
++ private static CallSite bootstrapInternal(final MethodHandles.Lookup caller, final String name, final MethodType type) {
+ return dynamicLinker.link(new MonomorphicCallSite(CallSiteDescriptorFactory.create(caller, name, type)));
+ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/DynamicLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/DynamicLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -140,7 +140,6 @@
+ * @author Attila Szegedi
+ */
+ public class DynamicLinker {
+-
+ private static final String CLASS_NAME = DynamicLinker.class.getName();
+ private static final String RELINK_METHOD_NAME = "relink";
+
+@@ -148,6 +147,7 @@
+ private static final String INITIAL_LINK_METHOD_NAME = "linkCallSite";
+
+ private final LinkerServices linkerServices;
++ private final GuardedInvocationFilter prelinkFilter;
+ private final int runtimeContextArgCount;
+ private final boolean syncOnRelink;
+ private final int unstableRelinkThreshold;
+@@ -156,18 +156,20 @@
+ * Creates a new dynamic linker.
+ *
+ * @param linkerServices the linkerServices used by the linker, created by the factory.
++ * @param prelinkFilter see {@link DynamicLinkerFactory#setPrelinkFilter(GuardedInvocationFilter)}
+ * @param runtimeContextArgCount see {@link DynamicLinkerFactory#setRuntimeContextArgCount(int)}
+ */
+- DynamicLinker(LinkerServices linkerServices, int runtimeContextArgCount, boolean syncOnRelink,
+- int unstableRelinkThreshold) {
++ DynamicLinker(final LinkerServices linkerServices, final GuardedInvocationFilter prelinkFilter, final int runtimeContextArgCount,
++ final boolean syncOnRelink, final int unstableRelinkThreshold) {
+ if(runtimeContextArgCount < 0) {
+ throw new IllegalArgumentException("runtimeContextArgCount < 0");
+ }
+ if(unstableRelinkThreshold < 0) {
+ throw new IllegalArgumentException("unstableRelinkThreshold < 0");
+ }
++ this.linkerServices = linkerServices;
++ this.prelinkFilter = prelinkFilter;
+ this.runtimeContextArgCount = runtimeContextArgCount;
+- this.linkerServices = linkerServices;
+ this.syncOnRelink = syncOnRelink;
+ this.unstableRelinkThreshold = unstableRelinkThreshold;
+ }
+@@ -199,7 +201,7 @@
+ private static final MethodHandle RELINK = Lookup.findOwnSpecial(MethodHandles.lookup(), RELINK_METHOD_NAME,
+ MethodHandle.class, RelinkableCallSite.class, int.class, Object[].class);
+
+- private MethodHandle createRelinkAndInvokeMethod(final RelinkableCallSite callSite, int relinkCount) {
++ private MethodHandle createRelinkAndInvokeMethod(final RelinkableCallSite callSite, final int relinkCount) {
+ // Make a bound MH of invoke() for this linker and call site
+ final MethodHandle boundRelinker = MethodHandles.insertArguments(RELINK, 0, this, callSite, Integer.valueOf(
+ relinkCount));
+@@ -219,16 +221,15 @@
+ * @throws Exception rethrows any exception thrown by the linkers
+ */
+ @SuppressWarnings("unused")
+- private MethodHandle relink(RelinkableCallSite callSite, int relinkCount, Object... arguments) throws Exception {
++ private MethodHandle relink(final RelinkableCallSite callSite, final int relinkCount, final Object... arguments) throws Exception {
+ final CallSiteDescriptor callSiteDescriptor = callSite.getDescriptor();
+ final boolean unstableDetectionEnabled = unstableRelinkThreshold > 0;
+ final boolean callSiteUnstable = unstableDetectionEnabled && relinkCount >= unstableRelinkThreshold;
+ final LinkRequest linkRequest =
+- runtimeContextArgCount == 0 ? new LinkRequestImpl(callSiteDescriptor, callSiteUnstable, arguments)
+- : new RuntimeContextLinkRequestImpl(callSiteDescriptor, callSiteUnstable, arguments,
+- runtimeContextArgCount);
++ runtimeContextArgCount == 0 ?
++ new LinkRequestImpl(callSiteDescriptor, callSite, relinkCount, callSiteUnstable, arguments) :
++ new RuntimeContextLinkRequestImpl(callSiteDescriptor, callSite, relinkCount, callSiteUnstable, arguments, runtimeContextArgCount);
+
+- // Find a suitable method handle with a guard
+ GuardedInvocation guardedInvocation = linkerServices.getGuardedInvocation(linkRequest);
+
+ // None found - throw an exception
+@@ -248,6 +249,11 @@
+ }
+ }
+
++ // Make sure we filter the invocation before linking it into the call site. This is typically used to match the
++ // return type of the invocation to the call site.
++ guardedInvocation = prelinkFilter.filter(guardedInvocation, linkRequest, linkerServices);
++ guardedInvocation.getClass(); // null pointer check
++
+ int newRelinkCount = relinkCount;
+ // Note that the short-circuited "&&" evaluation below ensures we'll increment the relinkCount until
+ // threshold + 1 but not beyond that. Threshold + 1 is treated as a special value to signal that resetAndRelink
+--- ./nashorn/src/jdk/internal/dynalink/DynamicLinkerFactory.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/DynamicLinkerFactory.java Wed Feb 04 12:14:47 2015 -0800
+@@ -97,24 +97,26 @@
+ import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+ import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
+ import jdk.internal.dynalink.linker.LinkRequest;
++import jdk.internal.dynalink.linker.MethodTypeConversionStrategy;
+ import jdk.internal.dynalink.support.AutoDiscovery;
+ import jdk.internal.dynalink.support.BottomGuardingDynamicLinker;
+ import jdk.internal.dynalink.support.ClassLoaderGetterContextProvider;
+ import jdk.internal.dynalink.support.CompositeGuardingDynamicLinker;
+ import jdk.internal.dynalink.support.CompositeTypeBasedGuardingDynamicLinker;
++import jdk.internal.dynalink.support.DefaultPrelinkFilter;
+ import jdk.internal.dynalink.support.LinkerServicesImpl;
+ import jdk.internal.dynalink.support.TypeConverterFactory;
++import jdk.internal.dynalink.support.TypeUtilities;
+
+ /**
+ * A factory class for creating {@link DynamicLinker}s. The most usual dynamic linker is a linker that is a composition
+ * of all {@link GuardingDynamicLinker}s known and pre-created by the caller as well as any
+- * {@link AutoDiscovery automatically discovered} guarding linkers and the standard fallback {@link BeansLinker}. See
+- * {@link DynamicLinker} documentation for tips on how to use this class.
++ * {@link AutoDiscovery automatically discovered} guarding linkers and the standard fallback {@link BeansLinker} and a
++ * {@link DefaultPrelinkFilter}. See {@link DynamicLinker} documentation for tips on how to use this class.
+ *
+ * @author Attila Szegedi
+ */
+ public class DynamicLinkerFactory {
+-
+ /**
+ * Default value for {@link #setUnstableRelinkThreshold(int) unstable relink threshold}.
+ */
+@@ -128,6 +130,8 @@
+ private int runtimeContextArgCount = 0;
+ private boolean syncOnRelink = false;
+ private int unstableRelinkThreshold = DEFAULT_UNSTABLE_RELINK_THRESHOLD;
++ private GuardedInvocationFilter prelinkFilter;
++ private MethodTypeConversionStrategy autoConversionStrategy;
+
+ /**
+ * Sets the class loader for automatic discovery of available linkers. If not set explicitly, then the thread
+@@ -135,7 +139,7 @@
+ *
+ * @param classLoader the class loader used for the autodiscovery of available linkers.
+ */
+- public void setClassLoader(ClassLoader classLoader) {
++ public void setClassLoader(final ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ classLoaderExplicitlySet = true;
+ }
+@@ -149,7 +153,7 @@
+ * @param prioritizedLinkers the list of prioritized linkers. Null can be passed to indicate no prioritized linkers
+ * (this is also the default value).
+ */
+- public void setPrioritizedLinkers(List<? extends GuardingDynamicLinker> prioritizedLinkers) {
++ public void setPrioritizedLinkers(final List<? extends GuardingDynamicLinker> prioritizedLinkers) {
+ this.prioritizedLinkers =
+ prioritizedLinkers == null ? null : new ArrayList<>(prioritizedLinkers);
+ }
+@@ -162,7 +166,7 @@
+ *
+ * @param prioritizedLinkers a list of prioritized linkers.
+ */
+- public void setPrioritizedLinkers(GuardingDynamicLinker... prioritizedLinkers) {
++ public void setPrioritizedLinkers(final GuardingDynamicLinker... prioritizedLinkers) {
+ setPrioritizedLinkers(Arrays.asList(prioritizedLinkers));
+ }
+
+@@ -173,7 +177,7 @@
+ * @param prioritizedLinker the single prioritized linker. Must not be null.
+ * @throws IllegalArgumentException if null is passed.
+ */
+- public void setPrioritizedLinker(GuardingDynamicLinker prioritizedLinker) {
++ public void setPrioritizedLinker(final GuardingDynamicLinker prioritizedLinker) {
+ if(prioritizedLinker == null) {
+ throw new IllegalArgumentException("prioritizedLinker == null");
+ }
+@@ -188,7 +192,7 @@
+ * @param fallbackLinkers the list of fallback linkers. Can be empty to indicate the caller wishes to set no
+ * fallback linkers.
+ */
+- public void setFallbackLinkers(List<? extends GuardingDynamicLinker> fallbackLinkers) {
++ public void setFallbackLinkers(final List<? extends GuardingDynamicLinker> fallbackLinkers) {
+ this.fallbackLinkers = fallbackLinkers == null ? null : new ArrayList<>(fallbackLinkers);
+ }
+
+@@ -200,7 +204,7 @@
+ * @param fallbackLinkers the list of fallback linkers. Can be empty to indicate the caller wishes to set no
+ * fallback linkers. If it is left as null, the standard fallback {@link BeansLinker} will be used.
+ */
+- public void setFallbackLinkers(GuardingDynamicLinker... fallbackLinkers) {
++ public void setFallbackLinkers(final GuardingDynamicLinker... fallbackLinkers) {
+ setFallbackLinkers(Arrays.asList(fallbackLinkers));
+ }
+
+@@ -214,7 +218,7 @@
+ *
+ * @param runtimeContextArgCount the number of language runtime context arguments in call sites.
+ */
+- public void setRuntimeContextArgCount(int runtimeContextArgCount) {
++ public void setRuntimeContextArgCount(final int runtimeContextArgCount) {
+ if(runtimeContextArgCount < 0) {
+ throw new IllegalArgumentException("runtimeContextArgCount < 0");
+ }
+@@ -227,7 +231,7 @@
+ * multithreaded execution of dynamically linked code.
+ * @param syncOnRelink true for invoking sync on relink, false otherwise.
+ */
+- public void setSyncOnRelink(boolean syncOnRelink) {
++ public void setSyncOnRelink(final boolean syncOnRelink) {
+ this.syncOnRelink = syncOnRelink;
+ }
+
+@@ -238,7 +242,7 @@
+ * call sites will never be considered unstable.
+ * @see LinkRequest#isCallSiteUnstable()
+ */
+- public void setUnstableRelinkThreshold(int unstableRelinkThreshold) {
++ public void setUnstableRelinkThreshold(final int unstableRelinkThreshold) {
+ if(unstableRelinkThreshold < 0) {
+ throw new IllegalArgumentException("unstableRelinkThreshold < 0");
+ }
+@@ -246,7 +250,42 @@
+ }
+
+ /**
+- * Creates a new dynamic linker consisting of all the prioritized, autodiscovered, and fallback linkers.
++ * Set the pre-link filter. This is a {@link GuardedInvocationFilter} that will get the final chance to modify the
++ * guarded invocation after it has been created by a component linker and before the dynamic linker links it into
++ * the call site. It is normally used to adapt the return value type of the invocation to the type of the call site.
++ * When not set explicitly, {@link DefaultPrelinkFilter} will be used.
++ * @param prelinkFilter the pre-link filter for the dynamic linker.
++ */
++ public void setPrelinkFilter(final GuardedInvocationFilter prelinkFilter) {
++ this.prelinkFilter = prelinkFilter;
++ }
++
++ /**
++ * Sets an object representing the conversion strategy for automatic type conversions. After
++ * {@link TypeConverterFactory#asType(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType)} has
++ * applied all custom conversions to a method handle, it still needs to effect
++ * {@link TypeUtilities#isMethodInvocationConvertible(Class, Class) method invocation conversions} that
++ * can usually be automatically applied as per
++ * {@link java.lang.invoke.MethodHandle#asType(java.lang.invoke.MethodType)}.
++ * However, sometimes language runtimes will want to customize even those conversions for their own call
++ * sites. A typical example is allowing unboxing of null return values, which is by default prohibited by
++ * ordinary {@code MethodHandles.asType}. In this case, a language runtime can install its own custom
++ * automatic conversion strategy, that can deal with null values. Note that when the strategy's
++ * {@link MethodTypeConversionStrategy#asType(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType)}
++ * is invoked, the custom language conversions will already have been applied to the method handle, so by
++ * design the difference between the handle's current method type and the desired final type will always
++ * only be ones that can be subjected to method invocation conversions. The strategy also doesn't need to
++ * invoke a final {@code MethodHandle.asType()} as the converter factory will do that as the final step.
++ * @param autoConversionStrategy the strategy for applying method invocation conversions for the linker
++ * created by this factory.
++ */
++ public void setAutoConversionStrategy(final MethodTypeConversionStrategy autoConversionStrategy) {
++ this.autoConversionStrategy = autoConversionStrategy;
++ }
++
++ /**
++ * Creates a new dynamic linker consisting of all the prioritized, autodiscovered, and fallback linkers as well as
++ * the pre-link filter.
+ *
+ * @return the new dynamic Linker
+ */
+@@ -275,7 +314,7 @@
+ // ... prioritized linkers, ...
+ linkers.addAll(prioritizedLinkers);
+ // ... filtered discovered linkers, ...
+- for(GuardingDynamicLinker linker: discovered) {
++ for(final GuardingDynamicLinker linker: discovered) {
+ if(!knownLinkerClasses.contains(linker.getClass())) {
+ linkers.add(linker);
+ }
+@@ -300,14 +339,19 @@
+ }
+
+ final List<GuardingTypeConverterFactory> typeConverters = new LinkedList<>();
+- for(GuardingDynamicLinker linker: linkers) {
++ for(final GuardingDynamicLinker linker: linkers) {
+ if(linker instanceof GuardingTypeConverterFactory) {
+ typeConverters.add((GuardingTypeConverterFactory)linker);
+ }
+ }
+
+- return new DynamicLinker(new LinkerServicesImpl(new TypeConverterFactory(typeConverters), composite),
+- runtimeContextArgCount, syncOnRelink, unstableRelinkThreshold);
++ if(prelinkFilter == null) {
++ prelinkFilter = new DefaultPrelinkFilter();
++ }
++
++ return new DynamicLinker(new LinkerServicesImpl(new TypeConverterFactory(typeConverters,
++ autoConversionStrategy), composite), prelinkFilter, runtimeContextArgCount, syncOnRelink,
++ unstableRelinkThreshold);
+ }
+
+ private static ClassLoader getThreadContextClassLoader() {
+@@ -319,9 +363,9 @@
+ }, ClassLoaderGetterContextProvider.GET_CLASS_LOADER_CONTEXT);
+ }
+
+- private static void addClasses(Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses,
+- List<? extends GuardingDynamicLinker> linkers) {
+- for(GuardingDynamicLinker linker: linkers) {
++ private static void addClasses(final Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses,
++ final List<? extends GuardingDynamicLinker> linkers) {
++ for(final GuardingDynamicLinker linker: linkers) {
+ knownLinkerClasses.add(linker.getClass());
+ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/internal/dynalink/GuardedInvocationFilter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,105 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.
++ */
++
++/*
++ * This file is available under and governed by the GNU General Public
++ * License version 2 only, as published by the Free Software Foundation.
++ * However, the following notice accompanied the original version of this
++ * file, and Oracle licenses the original version of this file under the BSD
++ * license:
++ */
++/*
++ Copyright 2009-2013 Attila Szegedi
++
++ Licensed under both the Apache License, Version 2.0 (the "Apache License")
++ and the BSD License (the "BSD License"), with licensee being free to
++ choose either of the two at their discretion.
++
++ You may not use this file except in compliance with either the Apache
++ License or the BSD License.
++
++ If you choose to use this file in compliance with the Apache License, the
++ following notice applies to you:
++
++ You may obtain a copy of the Apache License at
++
++ 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,
++ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
++ implied. See the License for the specific language governing
++ permissions and limitations under the License.
++
++ If you choose to use this file in compliance with the BSD License, the
++ following notice applies to you:
++
++ Redistribution and use in source and binary forms, with or without
++ modification, are permitted provided that the following conditions are
++ met:
++ * Redistributions of source code must retain the above copyright
++ notice, this list of conditions and the following disclaimer.
++ * Redistributions in binary form must reproduce the above copyright
++ notice, this list of conditions and the following disclaimer in the
++ documentation and/or other materials provided with the distribution.
++ * Neither the name of the copyright holder nor the names of
++ contributors may be used to endorse or promote products derived from
++ this software without specific prior written permission.
++
++ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
++ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
++ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
++ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
++ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
++ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++*/
++
++package jdk.internal.dynalink;
++
++import jdk.internal.dynalink.linker.GuardedInvocation;
++import jdk.internal.dynalink.linker.LinkRequest;
++import jdk.internal.dynalink.linker.LinkerServices;
++
++/**
++ * Interface for objects that are used to transform one guarded invocation into another one. Typical usage is for
++ * implementing {@link DynamicLinkerFactory#setPrelinkFilter(GuardedInvocationFilter) pre-link filters}.
++ */
++public interface GuardedInvocationFilter {
++ /**
++ * Given a guarded invocation, return a potentially different guarded invocation.
++ * @param inv the original guarded invocation. Null is never passed.
++ * @param linkRequest the link request for which the invocation was generated (usually by some linker).
++ * @param linkerServices the linker services that can be used during creation of a new invocation.
++ * @return either the passed guarded invocation or a different one, with the difference usually determined based on
++ * information in the link request and the differing invocation created with the assistance of the linker services.
++ * Whether or not {@code null} is an accepted return value is dependent on the user of the filter.
++ */
++ public GuardedInvocation filter(GuardedInvocation inv, LinkRequest linkRequest, LinkerServices linkerServices);
++}
+--- ./nashorn/src/jdk/internal/dynalink/MonomorphicCallSite.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/MonomorphicCallSite.java Wed Feb 04 12:14:47 2015 -0800
+@@ -99,17 +99,17 @@
+ * Creates a new call site with monomorphic inline caching strategy.
+ * @param descriptor the descriptor for this call site
+ */
+- public MonomorphicCallSite(CallSiteDescriptor descriptor) {
++ public MonomorphicCallSite(final CallSiteDescriptor descriptor) {
+ super(descriptor);
+ }
+
+ @Override
+- public void relink(GuardedInvocation guardedInvocation, MethodHandle relink) {
++ public void relink(final GuardedInvocation guardedInvocation, final MethodHandle relink) {
+ setTarget(guardedInvocation.compose(relink));
+ }
+
+ @Override
+- public void resetAndRelink(GuardedInvocation guardedInvocation, MethodHandle relink) {
++ public void resetAndRelink(final GuardedInvocation guardedInvocation, final MethodHandle relink) {
+ relink(guardedInvocation, relink);
+ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/NoSuchDynamicMethodException.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/NoSuchDynamicMethodException.java Wed Feb 04 12:14:47 2015 -0800
+@@ -97,7 +97,7 @@
+ * Creates a new NoSuchDynamicMethodException
+ * @param message the message of the exception.
+ */
+- public NoSuchDynamicMethodException(String message) {
++ public NoSuchDynamicMethodException(final String message) {
+ super(message);
+ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -97,7 +97,6 @@
+ import java.util.HashMap;
+ import java.util.List;
+ import java.util.Map;
+-
+ import jdk.internal.dynalink.CallSiteDescriptor;
+ import jdk.internal.dynalink.beans.GuardedInvocationComponent.ValidationType;
+ import jdk.internal.dynalink.linker.GuardedInvocation;
+@@ -107,6 +106,7 @@
+ import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+ import jdk.internal.dynalink.support.Guards;
+ import jdk.internal.dynalink.support.Lookup;
++import jdk.internal.dynalink.support.TypeUtilities;
+
+ /**
+ * A base class for both {@link StaticClassLinker} and {@link BeanLinker}. Deals with common aspects of property
+@@ -123,18 +123,18 @@
+ private final Map<String, DynamicMethod> propertySetters = new HashMap<>();
+ private final Map<String, DynamicMethod> methods = new HashMap<>();
+
+- AbstractJavaLinker(Class<?> clazz, MethodHandle classGuard) {
++ AbstractJavaLinker(final Class<?> clazz, final MethodHandle classGuard) {
+ this(clazz, classGuard, classGuard);
+ }
+
+- AbstractJavaLinker(Class<?> clazz, MethodHandle classGuard, MethodHandle assignableGuard) {
++ AbstractJavaLinker(final Class<?> clazz, final MethodHandle classGuard, final MethodHandle assignableGuard) {
+ this.clazz = clazz;
+ this.classGuard = classGuard;
+ this.assignableGuard = assignableGuard;
+
+ final FacetIntrospector introspector = createFacetIntrospector();
+ // Add methods and properties
+- for(Method method: introspector.getMethods()) {
++ for(final Method method: introspector.getMethods()) {
+ final String name = method.getName();
+ // Add method
+ addMember(name, method, methods);
+@@ -153,7 +153,7 @@
+ }
+
+ // Add field getter/setters as property getters/setters.
+- for(Field field: introspector.getFields()) {
++ for(final Field field: introspector.getFields()) {
+ final String name = field.getName();
+ // Only add a property getter when one is not defined already as a getXxx()/isXxx() method.
+ if(!propertyGetters.containsKey(name)) {
+@@ -166,7 +166,7 @@
+ }
+
+ // Add inner classes, but only those for which we don't hide a property with it
+- for(Map.Entry<String, MethodHandle> innerClassSpec: introspector.getInnerClassGetters().entrySet()) {
++ for(final Map.Entry<String, MethodHandle> innerClassSpec: introspector.getInnerClassGetters().entrySet()) {
+ final String name = innerClassSpec.getKey();
+ if(!propertyGetters.containsKey(name)) {
+ setPropertyGetter(name, innerClassSpec.getValue(), ValidationType.EXACT_CLASS);
+@@ -174,7 +174,7 @@
+ }
+ }
+
+- private static String decapitalize(String str) {
++ private static String decapitalize(final String str) {
+ assert str != null;
+ if(str.isEmpty()) {
+ return str;
+@@ -209,7 +209,7 @@
+ return getUnmodifiableKeys(methods);
+ }
+
+- private static Collection<String> getUnmodifiableKeys(Map<String, ?> m) {
++ private static Collection<String> getUnmodifiableKeys(final Map<String, ?> m) {
+ return Collections.unmodifiableCollection(m.keySet());
+ }
+
+@@ -222,7 +222,7 @@
+ * @param handle the method handle that implements the property getter
+ * @param validationType the validation type for the property
+ */
+- private void setPropertyGetter(String name, SingleDynamicMethod handle, ValidationType validationType) {
++ private void setPropertyGetter(final String name, final SingleDynamicMethod handle, final ValidationType validationType) {
+ propertyGetters.put(name, new AnnotatedDynamicMethod(handle, validationType));
+ }
+
+@@ -232,7 +232,7 @@
+ * @param prefixLen the getter prefix in the method name; should be 3 for getter names starting with "get" and 2 for
+ * names starting with "is".
+ */
+- private void setPropertyGetter(Method getter, int prefixLen) {
++ private void setPropertyGetter(final Method getter, final int prefixLen) {
+ setPropertyGetter(decapitalize(getter.getName().substring(prefixLen)), createDynamicMethod(
+ getMostGenericGetter(getter)), ValidationType.INSTANCE_OF);
+ }
+@@ -246,15 +246,15 @@
+ * @param handle the method handle that implements the property getter
+ * @param validationType the validation type for the property
+ */
+- void setPropertyGetter(String name, MethodHandle handle, ValidationType validationType) {
++ void setPropertyGetter(final String name, final MethodHandle handle, final ValidationType validationType) {
+ setPropertyGetter(name, new SimpleDynamicMethod(handle, clazz, name), validationType);
+ }
+
+- private void addMember(String name, AccessibleObject ao, Map<String, DynamicMethod> methodMap) {
++ private void addMember(final String name, final AccessibleObject ao, final Map<String, DynamicMethod> methodMap) {
+ addMember(name, createDynamicMethod(ao), methodMap);
+ }
+
+- private void addMember(String name, SingleDynamicMethod method, Map<String, DynamicMethod> methodMap) {
++ private void addMember(final String name, final SingleDynamicMethod method, final Map<String, DynamicMethod> methodMap) {
+ final DynamicMethod existingMethod = methodMap.get(name);
+ final DynamicMethod newMethod = mergeMethods(method, existingMethod, clazz, name);
+ if(newMethod != existingMethod) {
+@@ -270,9 +270,9 @@
+ * @param name the common name of the reflective members.
+ * @return a dynamic method representing all the specified reflective members.
+ */
+- static DynamicMethod createDynamicMethod(Iterable<? extends AccessibleObject> members, Class<?> clazz, String name) {
++ static DynamicMethod createDynamicMethod(final Iterable<? extends AccessibleObject> members, final Class<?> clazz, final String name) {
+ DynamicMethod dynMethod = null;
+- for(AccessibleObject method: members) {
++ for(final AccessibleObject method: members) {
+ dynMethod = mergeMethods(createDynamicMethod(method), dynMethod, clazz, name);
+ }
+ return dynMethod;
+@@ -285,12 +285,23 @@
+ * @param m the reflective member
+ * @return the single dynamic method representing the reflective member
+ */
+- private static SingleDynamicMethod createDynamicMethod(AccessibleObject m) {
++ private static SingleDynamicMethod createDynamicMethod(final AccessibleObject m) {
+ if(CallerSensitiveDetector.isCallerSensitive(m)) {
++ // Method has @CallerSensitive annotation
+ return new CallerSensitiveDynamicMethod(m);
+ }
++ // Method has no @CallerSensitive annotation
++ final MethodHandle mh;
++ try {
++ mh = unreflectSafely(m);
++ } catch (final IllegalAccessError e) {
++ // java.lang.invoke can in some case conservatively treat as caller sensitive methods that aren't
++ // marked with the annotation. In this case, we'll fall back to treating it as caller sensitive.
++ return new CallerSensitiveDynamicMethod(m);
++ }
++ // Proceed with non-caller sensitive
+ final Member member = (Member)m;
+- return new SimpleDynamicMethod(unreflectSafely(m), member.getDeclaringClass(), member.getName());
++ return new SimpleDynamicMethod(mh, member.getDeclaringClass(), member.getName(), m instanceof Constructor);
+ }
+
+ /**
+@@ -301,7 +312,7 @@
+ * @param m the method or constructor
+ * @return the method handle
+ */
+- private static MethodHandle unreflectSafely(AccessibleObject m) {
++ private static MethodHandle unreflectSafely(final AccessibleObject m) {
+ if(m instanceof Method) {
+ final Method reflMethod = (Method)m;
+ final MethodHandle handle = Lookup.PUBLIC.unreflect(reflMethod);
+@@ -313,7 +324,7 @@
+ return StaticClassIntrospector.editConstructorMethodHandle(Lookup.PUBLIC.unreflectConstructor((Constructor<?>)m));
+ }
+
+- private static DynamicMethod mergeMethods(SingleDynamicMethod method, DynamicMethod existing, Class<?> clazz, String name) {
++ private static DynamicMethod mergeMethods(final SingleDynamicMethod method, final DynamicMethod existing, final Class<?> clazz, final String name) {
+ if(existing == null) {
+ return method;
+ } else if(existing.contains(method)) {
+@@ -331,7 +342,7 @@
+ }
+
+ @Override
+- public GuardedInvocation getGuardedInvocation(LinkRequest request, final LinkerServices linkerServices)
++ public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices)
+ throws Exception {
+ final LinkRequest ncrequest = request.withoutRuntimeContext();
+ // BeansLinker already checked that the name is at least 2 elements long and the first element is "dyn".
+@@ -353,8 +364,8 @@
+ return null;
+ }
+
+- protected GuardedInvocationComponent getGuardedInvocationComponent(CallSiteDescriptor callSiteDescriptor,
+- LinkerServices linkerServices, List<String> operations) throws Exception {
++ protected GuardedInvocationComponent getGuardedInvocationComponent(final CallSiteDescriptor callSiteDescriptor,
++ final LinkerServices linkerServices, final List<String> operations) throws Exception {
+ if(operations.isEmpty()) {
+ return null;
+ }
+@@ -374,27 +385,31 @@
+ return null;
+ }
+
+- static final <T> List<T> pop(List<T> l) {
++ static final <T> List<T> pop(final List<T> l) {
+ return l.subList(1, l.size());
+ }
+
+- MethodHandle getClassGuard(CallSiteDescriptor desc) {
++ MethodHandle getClassGuard(final CallSiteDescriptor desc) {
+ return getClassGuard(desc.getMethodType());
+ }
+
+- MethodHandle getClassGuard(MethodType type) {
++ MethodHandle getClassGuard(final MethodType type) {
+ return Guards.asType(classGuard, type);
+ }
+
+- GuardedInvocationComponent getClassGuardedInvocationComponent(MethodHandle invocation, MethodType type) {
++ GuardedInvocationComponent getClassGuardedInvocationComponent(final MethodHandle invocation, final MethodType type) {
+ return new GuardedInvocationComponent(invocation, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
+ }
+
+- private MethodHandle getAssignableGuard(MethodType type) {
++ SingleDynamicMethod getConstructorMethod(final String signature) {
++ return null;
++ }
++
++ private MethodHandle getAssignableGuard(final MethodType type) {
+ return Guards.asType(assignableGuard, type);
+ }
+
+- private GuardedInvocation getCallPropWithThis(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices) {
++ private GuardedInvocation getCallPropWithThis(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) {
+ switch(callSiteDescriptor.getNameTokenCount()) {
+ case 3: {
+ return createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices,
+@@ -406,25 +421,25 @@
+ }
+ }
+
+- private GuardedInvocation createGuardedDynamicMethodInvocation(CallSiteDescriptor callSiteDescriptor,
+- LinkerServices linkerServices, String methodName, Map<String, DynamicMethod> methodMap){
++ private GuardedInvocation createGuardedDynamicMethodInvocation(final CallSiteDescriptor callSiteDescriptor,
++ final LinkerServices linkerServices, final String methodName, final Map<String, DynamicMethod> methodMap){
+ final MethodHandle inv = getDynamicMethodInvocation(callSiteDescriptor, linkerServices, methodName, methodMap);
+ return inv == null ? null : new GuardedInvocation(inv, getClassGuard(callSiteDescriptor.getMethodType()));
+ }
+
+- private static MethodHandle getDynamicMethodInvocation(CallSiteDescriptor callSiteDescriptor,
+- LinkerServices linkerServices, String methodName, Map<String, DynamicMethod> methodMap) {
++ private MethodHandle getDynamicMethodInvocation(final CallSiteDescriptor callSiteDescriptor,
++ final LinkerServices linkerServices, final String methodName, final Map<String, DynamicMethod> methodMap) {
+ final DynamicMethod dynaMethod = getDynamicMethod(methodName, methodMap);
+ return dynaMethod != null ? dynaMethod.getInvocation(callSiteDescriptor, linkerServices) : null;
+ }
+
+- private static DynamicMethod getDynamicMethod(String methodName, Map<String, DynamicMethod> methodMap) {
++ private DynamicMethod getDynamicMethod(final String methodName, final Map<String, DynamicMethod> methodMap) {
+ final DynamicMethod dynaMethod = methodMap.get(methodName);
+ return dynaMethod != null ? dynaMethod : getExplicitSignatureDynamicMethod(methodName, methodMap);
+ }
+
+- private static SingleDynamicMethod getExplicitSignatureDynamicMethod(String methodName,
+- Map<String, DynamicMethod> methodsMap) {
++ private SingleDynamicMethod getExplicitSignatureDynamicMethod(final String fullName,
++ final Map<String, DynamicMethod> methodsMap) {
+ // What's below is meant to support the "name(type, type, ...)" syntax that programmers can use in a method name
+ // to manually pin down an exact overloaded variant. This is not usually required, as the overloaded method
+ // resolution works correctly in almost every situation. However, in presence of many language-specific
+@@ -433,23 +448,33 @@
+ // for performance reasons.
+
+ // Is the method name lexically of the form "name(types)"?
+- final int lastChar = methodName.length() - 1;
+- if(methodName.charAt(lastChar) != ')') {
++ final int lastChar = fullName.length() - 1;
++ if(fullName.charAt(lastChar) != ')') {
+ return null;
+ }
+- final int openBrace = methodName.indexOf('(');
++ final int openBrace = fullName.indexOf('(');
+ if(openBrace == -1) {
+ return null;
+ }
+
++ final String name = fullName.substring(0, openBrace);
++ final String signature = fullName.substring(openBrace + 1, lastChar);
++
+ // Find an existing method for the "name" part
+- final DynamicMethod simpleNamedMethod = methodsMap.get(methodName.substring(0, openBrace));
++ final DynamicMethod simpleNamedMethod = methodsMap.get(name);
+ if(simpleNamedMethod == null) {
++ // explicit signature constructor access
++ // Java.type("java.awt.Color")["(int,int,int)"]
++ // will get Color(int,int,int) constructor of Color class.
++ if (name.isEmpty()) {
++ return getConstructorMethod(signature);
++ }
++
+ return null;
+ }
+
+ // Try to get a narrowed dynamic method for the explicit parameter types.
+- return simpleNamedMethod.getMethodForExactParamTypes(methodName.substring(openBrace + 1, lastChar));
++ return simpleNamedMethod.getMethodForExactParamTypes(signature);
+ }
+
+ private static final MethodHandle IS_METHOD_HANDLE_NOT_NULL = Guards.isNotNull().asType(MethodType.methodType(
+@@ -457,14 +482,19 @@
+ private static final MethodHandle CONSTANT_NULL_DROP_METHOD_HANDLE = MethodHandles.dropArguments(
+ MethodHandles.constant(Object.class, null), 0, MethodHandle.class);
+
+- private GuardedInvocationComponent getPropertySetter(CallSiteDescriptor callSiteDescriptor,
+- LinkerServices linkerServices, List<String> operations) throws Exception {
+- final MethodType type = callSiteDescriptor.getMethodType();
++ private GuardedInvocationComponent getPropertySetter(final CallSiteDescriptor callSiteDescriptor,
++ final LinkerServices linkerServices, final List<String> operations) throws Exception {
+ switch(callSiteDescriptor.getNameTokenCount()) {
+ case 2: {
+ // Must have three arguments: target object, property name, and property value.
+ assertParameterCount(callSiteDescriptor, 3);
+
++ // We want setters that conform to "Object(O, V)". Note, we aren't doing "R(O, V)" as it might not be
++ // valid for us to convert return values proactively. Also, since we don't know what setters will be
++ // invoked, we'll conservatively presume Object return type. The one exception is void return.
++ final MethodType origType = callSiteDescriptor.getMethodType();
++ final MethodType type = origType.returnType() == void.class ? origType : origType.changeReturnType(Object.class);
++
+ // What's below is basically:
+ // foldArguments(guardWithTest(isNotNull, invoke, null|nextComponent.invocation),
+ // get_setter_handle(type, linkerServices))
+@@ -473,13 +503,13 @@
+ // component's invocation.
+
+ // Call site type is "ret_type(object_type,property_name_type,property_value_type)", which we'll
+- // abbreviate to R(O, N, V) going forward.
+- // We want setters that conform to "R(O, V)"
++ // abbreviate to R(O, N, V) going forward, although we don't really use R here (see above about using
++ // Object return type).
+ final MethodType setterType = type.dropParameterTypes(1, 2);
+ // Bind property setter handle to the expected setter type and linker services. Type is
+ // MethodHandle(Object, String, Object)
+ final MethodHandle boundGetter = MethodHandles.insertArguments(getPropertySetterHandle, 0,
+- CallSiteDescriptorFactory.dropParameterTypes(callSiteDescriptor, 1, 2), linkerServices);
++ callSiteDescriptor.changeMethodType(setterType), linkerServices);
+
+ // Cast getter to MethodHandle(O, N, V)
+ final MethodHandle typedGetter = linkerServices.asType(boundGetter, type.changeReturnType(
+@@ -495,11 +525,11 @@
+
+ final MethodHandle fallbackFolded;
+ if(nextComponent == null) {
+- // Object(MethodHandle)->R(MethodHandle, O, N, V); returns constant null
++ // Object(MethodHandle)->Object(MethodHandle, O, N, V); returns constant null
+ fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_METHOD_HANDLE, 1,
+ type.parameterList()).asType(type.insertParameterTypes(0, MethodHandle.class));
+ } else {
+- // R(O, N, V)->R(MethodHandle, O, N, V); adapts the next component's invocation to drop the
++ // Object(O, N, V)->Object(MethodHandle, O, N, V); adapts the next component's invocation to drop the
+ // extra argument resulting from fold
+ fallbackFolded = MethodHandles.dropArguments(nextComponent.getGuardedInvocation().getInvocation(),
+ 0, MethodHandle.class);
+@@ -543,11 +573,14 @@
+ "getTarget", MethodType.methodType(MethodHandle.class, MethodHandles.Lookup.class));
+ private static final MethodHandle GETTER_INVOKER = MethodHandles.invoker(MethodType.methodType(Object.class, Object.class));
+
+- private GuardedInvocationComponent getPropertyGetter(CallSiteDescriptor callSiteDescriptor,
+- LinkerServices linkerServices, List<String> ops) throws Exception {
+- final MethodType type = callSiteDescriptor.getMethodType();
++ private GuardedInvocationComponent getPropertyGetter(final CallSiteDescriptor callSiteDescriptor,
++ final LinkerServices linkerServices, final List<String> ops) throws Exception {
+ switch(callSiteDescriptor.getNameTokenCount()) {
+ case 2: {
++ // Since we can't know what kind of a getter we'll get back on different invocations, we'll just
++ // conservatively presume Object. Note we can't just coerce to a narrower call site type as the linking
++ // runtime might not allow coercing at that call site.
++ final MethodType type = callSiteDescriptor.getMethodType().changeReturnType(Object.class);
+ // Must have exactly two arguments: receiver and name
+ assertParameterCount(callSiteDescriptor, 2);
+
+@@ -563,11 +596,11 @@
+ GET_ANNOTATED_METHOD, 1, callSiteDescriptor.getLookup());
+ final MethodHandle callSiteBoundInvoker = MethodHandles.filterArguments(GETTER_INVOKER, 0,
+ callSiteBoundMethodGetter);
+- // Object(AnnotatedDynamicMethod, Object)->R(AnnotatedDynamicMethod, T0)
++ // Object(AnnotatedDynamicMethod, Object)->Object(AnnotatedDynamicMethod, T0)
+ final MethodHandle invokeHandleTyped = linkerServices.asType(callSiteBoundInvoker,
+ MethodType.methodType(type.returnType(), AnnotatedDynamicMethod.class, type.parameterType(0)));
+ // Since it's in the target of a fold, drop the unnecessary second argument
+- // R(AnnotatedDynamicMethod, T0)->R(AnnotatedDynamicMethod, T0, T1)
++ // Object(AnnotatedDynamicMethod, T0)->Object(AnnotatedDynamicMethod, T0, T1)
+ final MethodHandle invokeHandleFolded = MethodHandles.dropArguments(invokeHandleTyped, 2,
+ type.parameterType(1));
+ final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
+@@ -575,17 +608,19 @@
+
+ final MethodHandle fallbackFolded;
+ if(nextComponent == null) {
+- // Object(AnnotatedDynamicMethod)->R(AnnotatedDynamicMethod, T0, T1); returns constant null
++ // Object(AnnotatedDynamicMethod)->Object(AnnotatedDynamicMethod, T0, T1); returns constant null
+ fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_ANNOTATED_METHOD, 1,
+ type.parameterList()).asType(type.insertParameterTypes(0, AnnotatedDynamicMethod.class));
+ } else {
+- // R(T0, T1)->R(AnnotatedDynamicMethod, T0, T1); adapts the next component's invocation to drop the
+- // extra argument resulting from fold
+- fallbackFolded = MethodHandles.dropArguments(nextComponent.getGuardedInvocation().getInvocation(),
+- 0, AnnotatedDynamicMethod.class);
++ // Object(T0, T1)->Object(AnnotatedDynamicMethod, T0, T1); adapts the next component's invocation to
++ // drop the extra argument resulting from fold and to change its return type to Object.
++ final MethodHandle nextInvocation = nextComponent.getGuardedInvocation().getInvocation();
++ final MethodType nextType = nextInvocation.type();
++ fallbackFolded = MethodHandles.dropArguments(nextInvocation.asType(
++ nextType.changeReturnType(Object.class)), 0, AnnotatedDynamicMethod.class);
+ }
+
+- // fold(R(AnnotatedDynamicMethod, T0, T1), AnnotatedDynamicMethod(T0, T1))
++ // fold(Object(AnnotatedDynamicMethod, T0, T1), AnnotatedDynamicMethod(T0, T1))
+ final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
+ IS_ANNOTATED_METHOD_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
+ if(nextComponent == null) {
+@@ -612,8 +647,8 @@
+ // value is null.
+ final ValidationType validationType = annGetter.validationType;
+ // TODO: we aren't using the type that declares the most generic getter here!
+- return new GuardedInvocationComponent(linkerServices.asType(getter, type), getGuard(validationType,
+- type), clazz, validationType);
++ return new GuardedInvocationComponent(getter, getGuard(validationType,
++ callSiteDescriptor.getMethodType()), clazz, validationType);
+ }
+ default: {
+ // Can't do anything with more than 3 name components
+@@ -622,7 +657,7 @@
+ }
+ }
+
+- private MethodHandle getGuard(ValidationType validationType, MethodType methodType) {
++ private MethodHandle getGuard(final ValidationType validationType, final MethodType methodType) {
+ switch(validationType) {
+ case EXACT_CLASS: {
+ return getClassGuard(methodType);
+@@ -642,21 +677,25 @@
+ }
+ }
+
+- private static final MethodHandle IS_DYNAMIC_METHOD_NOT_NULL = Guards.asType(Guards.isNotNull(),
+- MethodType.methodType(boolean.class, DynamicMethod.class));
+- private static final MethodHandle DYNAMIC_METHOD_IDENTITY = MethodHandles.identity(DynamicMethod.class);
++ private static final MethodHandle IS_DYNAMIC_METHOD = Guards.isInstance(DynamicMethod.class,
++ MethodType.methodType(boolean.class, Object.class));
++ private static final MethodHandle OBJECT_IDENTITY = MethodHandles.identity(Object.class);
+
+- private GuardedInvocationComponent getMethodGetter(CallSiteDescriptor callSiteDescriptor,
+- LinkerServices linkerServices, List<String> ops) throws Exception {
+- final MethodType type = callSiteDescriptor.getMethodType();
++ private GuardedInvocationComponent getMethodGetter(final CallSiteDescriptor callSiteDescriptor,
++ final LinkerServices linkerServices, final List<String> ops) throws Exception {
++ // The created method handle will always return a DynamicMethod (or null), but since we don't want that type to
++ // be visible outside of this linker, declare it to return Object.
++ final MethodType type = callSiteDescriptor.getMethodType().changeReturnType(Object.class);
+ switch(callSiteDescriptor.getNameTokenCount()) {
+ case 2: {
+ // Must have exactly two arguments: receiver and name
+ assertParameterCount(callSiteDescriptor, 2);
+ final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
+ linkerServices, ops);
+- if(nextComponent == null) {
+- // No next component operation; just return a component for this operation.
++ if(nextComponent == null || !TypeUtilities.areAssignable(DynamicMethod.class,
++ nextComponent.getGuardedInvocation().getInvocation().type().returnType())) {
++ // No next component operation, or it can never produce a dynamic method; just return a component
++ // for this operation.
+ return getClassGuardedInvocationComponent(linkerServices.asType(getDynamicMethod, type), type);
+ }
+
+@@ -665,21 +704,20 @@
+ // bunch of method signature adjustments. Basically, execute method getter; if it returns a non-null
+ // DynamicMethod, use identity to return it, otherwise delegate to nextComponent's invocation.
+
+- final MethodHandle typedGetter = linkerServices.asType(getDynamicMethod, type.changeReturnType(
+- DynamicMethod.class));
++ final MethodHandle typedGetter = linkerServices.asType(getDynamicMethod, type);
+ // Since it is part of the foldArgument() target, it will have extra args that we need to drop.
+ final MethodHandle returnMethodHandle = linkerServices.asType(MethodHandles.dropArguments(
+- DYNAMIC_METHOD_IDENTITY, 1, type.parameterList()), type.insertParameterTypes(0,
+- DynamicMethod.class));
++ OBJECT_IDENTITY, 1, type.parameterList()), type.insertParameterTypes(0, Object.class));
+ final MethodHandle nextComponentInvocation = nextComponent.getGuardedInvocation().getInvocation();
+- // The assumption is that getGuardedInvocationComponent() already asType()'d it correctly
+- assert nextComponentInvocation.type().equals(type);
++ // The assumption is that getGuardedInvocationComponent() already asType()'d it correctly modulo the
++ // return type.
++ assert nextComponentInvocation.type().changeReturnType(type.returnType()).equals(type);
+ // Since it is part of the foldArgument() target, we have to drop an extra arg it receives.
+ final MethodHandle nextCombinedInvocation = MethodHandles.dropArguments(nextComponentInvocation, 0,
+- DynamicMethod.class);
++ Object.class);
+ // Assemble it all into a fold(guard(isNotNull, identity, nextInvocation), get)
+ final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
+- IS_DYNAMIC_METHOD_NOT_NULL, returnMethodHandle, nextCombinedInvocation), typedGetter);
++ IS_DYNAMIC_METHOD, returnMethodHandle, nextCombinedInvocation), typedGetter);
+
+ return nextComponent.compose(compositeGetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
+ }
+@@ -695,7 +733,7 @@
+ // No delegation to the next component of the composite operation; if we have a method with that name,
+ // we'll always return it at this point.
+ return getClassGuardedInvocationComponent(linkerServices.asType(MethodHandles.dropArguments(
+- MethodHandles.constant(DynamicMethod.class, method), 0, type.parameterType(0)), type), type);
++ MethodHandles.constant(Object.class, method), 0, type.parameterType(0)), type), type);
+ }
+ default: {
+ // Can't do anything with more than 3 name components
+@@ -704,7 +742,31 @@
+ }
+ }
+
+- private static void assertParameterCount(CallSiteDescriptor descriptor, int paramCount) {
++ static class MethodPair {
++ final MethodHandle method1;
++ final MethodHandle method2;
++
++ MethodPair(final MethodHandle method1, final MethodHandle method2) {
++ this.method1 = method1;
++ this.method2 = method2;
++ }
++
++ MethodHandle guardWithTest(final MethodHandle test) {
++ return MethodHandles.guardWithTest(test, method1, method2);
++ }
++ }
++
++ static MethodPair matchReturnTypes(final MethodHandle m1, final MethodHandle m2) {
++ final MethodType type1 = m1.type();
++ final MethodType type2 = m2.type();
++ final Class<?> commonRetType = TypeUtilities.getCommonLosslessConversionType(type1.returnType(),
++ type2.returnType());
++ return new MethodPair(
++ m1.asType(type1.changeReturnType(commonRetType)),
++ m2.asType(type2.changeReturnType(commonRetType)));
++ }
++
++ private static void assertParameterCount(final CallSiteDescriptor descriptor, final int paramCount) {
+ if(descriptor.getMethodType().parameterCount() != paramCount) {
+ throw new BootstrapMethodError(descriptor.getName() + " must have exactly " + paramCount + " parameters.");
+ }
+@@ -719,7 +781,7 @@
+ * @return the method handle for retrieving the property, or null if the property does not exist
+ */
+ @SuppressWarnings("unused")
+- private Object getPropertyGetterHandle(Object id) {
++ private Object getPropertyGetterHandle(final Object id) {
+ return propertyGetters.get(id);
+ }
+
+@@ -733,17 +795,20 @@
+ private final MethodHandle getPropertySetterHandle = GET_PROPERTY_SETTER_HANDLE.bindTo(this);
+
+ @SuppressWarnings("unused")
+- private MethodHandle getPropertySetterHandle(CallSiteDescriptor setterDescriptor, LinkerServices linkerServices,
+- Object id) {
++ private MethodHandle getPropertySetterHandle(final CallSiteDescriptor setterDescriptor, final LinkerServices linkerServices,
++ final Object id) {
+ return getDynamicMethodInvocation(setterDescriptor, linkerServices, String.valueOf(id), propertySetters);
+ }
+
+ private static MethodHandle GET_DYNAMIC_METHOD = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
+- "getDynamicMethod", DynamicMethod.class, Object.class), 1, Object.class);
++ "getDynamicMethod", Object.class, Object.class), 1, Object.class);
+ private final MethodHandle getDynamicMethod = GET_DYNAMIC_METHOD.bindTo(this);
+
+ @SuppressWarnings("unused")
+- private DynamicMethod getDynamicMethod(Object name) {
++ // This method is marked to return Object instead of DynamicMethod as it's used as a linking component and we don't
++ // want to make the DynamicMethod type observable externally (e.g. as the return type of a MethodHandle returned for
++ // "dyn:getMethod" linking).
++ private Object getDynamicMethod(final Object name) {
+ return getDynamicMethod(String.valueOf(name), methods);
+ }
+
+@@ -754,7 +819,7 @@
+ * @return the dynamic method (either {@link SimpleDynamicMethod} or {@link OverloadedDynamicMethod}, or null if the
+ * method with the specified name does not exist.
+ */
+- DynamicMethod getDynamicMethod(String name) {
++ DynamicMethod getDynamicMethod(final String name) {
+ return getDynamicMethod(name, methods);
+ }
+
+@@ -765,16 +830,16 @@
+ * @param getter the getter
+ * @return getter with same name, declared on the most generic superclass/interface of the declaring class
+ */
+- private static Method getMostGenericGetter(Method getter) {
++ private static Method getMostGenericGetter(final Method getter) {
+ return getMostGenericGetter(getter.getName(), getter.getReturnType(), getter.getDeclaringClass());
+ }
+
+- private static Method getMostGenericGetter(String name, Class<?> returnType, Class<?> declaringClass) {
++ private static Method getMostGenericGetter(final String name, final Class<?> returnType, final Class<?> declaringClass) {
+ if(declaringClass == null) {
+ return null;
+ }
+ // Prefer interfaces
+- for(Class<?> itf: declaringClass.getInterfaces()) {
++ for(final Class<?> itf: declaringClass.getInterfaces()) {
+ final Method itfGetter = getMostGenericGetter(name, returnType, itf);
+ if(itfGetter != null) {
+ return itfGetter;
+@@ -787,7 +852,7 @@
+ if(!CheckRestrictedPackage.isRestrictedClass(declaringClass)) {
+ try {
+ return declaringClass.getMethod(name);
+- } catch(NoSuchMethodException e) {
++ } catch(final NoSuchMethodException e) {
+ // Intentionally ignored, meant to fall through
+ }
+ }
+@@ -798,18 +863,18 @@
+ private final SingleDynamicMethod method;
+ /*private*/ final ValidationType validationType;
+
+- AnnotatedDynamicMethod(SingleDynamicMethod method, ValidationType validationType) {
++ AnnotatedDynamicMethod(final SingleDynamicMethod method, final ValidationType validationType) {
+ this.method = method;
+ this.validationType = validationType;
+ }
+
+- MethodHandle getInvocation(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices) {
++ MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) {
+ return method.getInvocation(callSiteDescriptor, linkerServices);
+ }
+
+ @SuppressWarnings("unused")
+- MethodHandle getTarget(MethodHandles.Lookup lookup) {
+- MethodHandle inv = method.getTarget(lookup);
++ MethodHandle getTarget(final MethodHandles.Lookup lookup) {
++ final MethodHandle inv = method.getTarget(lookup);
+ assert inv != null;
+ return inv;
+ }
+--- ./nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java Wed Feb 04 12:14:47 2015 -0800
+@@ -104,7 +104,7 @@
+ class AccessibleMembersLookup {
+ private final Map<MethodSignature, Method> methods;
+ private final Set<Class<?>> innerClasses;
+- private boolean instance;
++ private final boolean instance;
+
+ /**
+ * Creates a mapping for all accessible methods and inner classes on a class.
+@@ -112,7 +112,7 @@
+ * @param clazz the inspected class
+ * @param instance true to inspect instance methods, false to inspect static methods.
+ */
+- AccessibleMembersLookup(final Class<?> clazz, boolean instance) {
++ AccessibleMembersLookup(final Class<?> clazz, final boolean instance) {
+ this.methods = new HashMap<>();
+ this.innerClasses = new LinkedHashSet<>();
+ this.instance = instance;
+@@ -153,7 +153,7 @@
+ * @param name the name of the method this signature represents.
+ * @param args the argument types of the method.
+ */
+- MethodSignature(String name, Class<?>[] args) {
++ MethodSignature(final String name, final Class<?>[] args) {
+ this.name = name;
+ this.args = args;
+ }
+@@ -210,7 +210,7 @@
+
+ if(!CheckRestrictedPackage.isRestrictedClass(clazz)) {
+ searchSuperTypes = false;
+- for(Method method: clazz.getMethods()) {
++ for(final Method method: clazz.getMethods()) {
+ final boolean isStatic = Modifier.isStatic(method.getModifiers());
+ if(instance != isStatic) {
+ final MethodSignature sig = new MethodSignature(method);
+@@ -237,7 +237,7 @@
+ }
+ }
+ }
+- for(Class<?> innerClass: clazz.getClasses()) {
++ for(final Class<?> innerClass: clazz.getClasses()) {
+ // Add both static and non-static classes, regardless of instance flag. StaticClassLinker will just
+ // expose non-static classes with explicit constructor outer class argument.
+ // NOTE: getting inner class objects through getClasses() does not resolve them, so if those classes
+--- ./nashorn/src/jdk/internal/dynalink/beans/ApplicableOverloadedMethods.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/ApplicableOverloadedMethods.java Wed Feb 04 12:14:47 2015 -0800
+@@ -108,7 +108,7 @@
+ ApplicableOverloadedMethods(final List<SingleDynamicMethod> methods, final MethodType callSiteType,
+ final ApplicabilityTest test) {
+ this.methods = new LinkedList<>();
+- for(SingleDynamicMethod m: methods) {
++ for(final SingleDynamicMethod m: methods) {
+ if(test.isApplicable(callSiteType, m)) {
+ this.methods.add(m);
+ }
+@@ -143,7 +143,7 @@
+ */
+ static final ApplicabilityTest APPLICABLE_BY_SUBTYPING = new ApplicabilityTest() {
+ @Override
+- boolean isApplicable(MethodType callSiteType, SingleDynamicMethod method) {
++ boolean isApplicable(final MethodType callSiteType, final SingleDynamicMethod method) {
+ final MethodType methodType = method.getMethodType();
+ final int methodArity = methodType.parameterCount();
+ if(methodArity != callSiteType.parameterCount()) {
+@@ -165,7 +165,7 @@
+ */
+ static final ApplicabilityTest APPLICABLE_BY_METHOD_INVOCATION_CONVERSION = new ApplicabilityTest() {
+ @Override
+- boolean isApplicable(MethodType callSiteType, SingleDynamicMethod method) {
++ boolean isApplicable(final MethodType callSiteType, final SingleDynamicMethod method) {
+ final MethodType methodType = method.getMethodType();
+ final int methodArity = methodType.parameterCount();
+ if(methodArity != callSiteType.parameterCount()) {
+@@ -188,7 +188,7 @@
+ */
+ static final ApplicabilityTest APPLICABLE_BY_VARIABLE_ARITY = new ApplicabilityTest() {
+ @Override
+- boolean isApplicable(MethodType callSiteType, SingleDynamicMethod method) {
++ boolean isApplicable(final MethodType callSiteType, final SingleDynamicMethod method) {
+ if(!method.isVarArgs()) {
+ return false;
+ }
+--- ./nashorn/src/jdk/internal/dynalink/beans/BeanIntrospector.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/BeanIntrospector.java Wed Feb 04 12:14:47 2015 -0800
+@@ -88,7 +88,7 @@
+ import java.util.Map;
+
+ class BeanIntrospector extends FacetIntrospector {
+- BeanIntrospector(Class<?> clazz) {
++ BeanIntrospector(final Class<?> clazz) {
+ super(clazz, true);
+ }
+
+@@ -98,7 +98,7 @@
+ }
+
+ @Override
+- MethodHandle editMethodHandle(MethodHandle mh) {
++ MethodHandle editMethodHandle(final MethodHandle mh) {
+ return mh;
+ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/beans/BeanLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/BeanLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -106,7 +106,7 @@
+ * @author Attila Szegedi
+ */
+ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicLinker {
+- BeanLinker(Class<?> clazz) {
++ BeanLinker(final Class<?> clazz) {
+ super(clazz, Guards.getClassGuard(clazz), Guards.getInstanceOfGuard(clazz));
+ if(clazz.isArray()) {
+ // Some languages won't have a notion of manipulating collections. Exposing "length" on arrays as an
+@@ -119,7 +119,7 @@
+ }
+
+ @Override
+- public boolean canLinkType(Class<?> type) {
++ public boolean canLinkType(final Class<?> type) {
+ return type == clazz;
+ }
+
+@@ -129,8 +129,8 @@
+ }
+
+ @Override
+- protected GuardedInvocationComponent getGuardedInvocationComponent(CallSiteDescriptor callSiteDescriptor,
+- LinkerServices linkerServices, List<String> operations) throws Exception {
++ protected GuardedInvocationComponent getGuardedInvocationComponent(final CallSiteDescriptor callSiteDescriptor,
++ final LinkerServices linkerServices, final List<String> operations) throws Exception {
+ final GuardedInvocationComponent superGic = super.getGuardedInvocationComponent(callSiteDescriptor,
+ linkerServices, operations);
+ if(superGic != null) {
+@@ -166,7 +166,7 @@
+ private static MethodHandle MAP_GUARD = Guards.getInstanceOfGuard(Map.class);
+
+ private GuardedInvocationComponent getElementGetter(final CallSiteDescriptor callSiteDescriptor,
+- final LinkerServices linkerServices, List<String> operations) throws Exception {
++ final LinkerServices linkerServices, final List<String> operations) throws Exception {
+ final MethodType callSiteType = callSiteDescriptor.getMethodType();
+ final Class<?> declaredType = callSiteType.parameterType(0);
+ final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
+@@ -237,8 +237,9 @@
+ } else {
+ checkGuard = convertArgToInt(RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
+ }
+- return nextComponent.compose(MethodHandles.guardWithTest(binder.bindTest(checkGuard),
+- binder.bind(invocation), nextComponent.getGuardedInvocation().getInvocation()), gi.getGuard(),
++ final MethodPair matchedInvocations = matchReturnTypes(binder.bind(invocation),
++ nextComponent.getGuardedInvocation().getInvocation());
++ return nextComponent.compose(matchedInvocations.guardWithTest(binder.bindTest(checkGuard)), gi.getGuard(),
+ gic.getValidatorClass(), gic.getValidationType());
+ }
+
+@@ -247,7 +248,7 @@
+ CallSiteDescriptor.NAME_OPERAND);
+ }
+
+- private static Object convertKeyToInteger(String fixedKey, LinkerServices linkerServices) throws Exception {
++ private static Object convertKeyToInteger(final String fixedKey, final LinkerServices linkerServices) throws Exception {
+ try {
+ if(linkerServices.canConvert(String.class, Number.class)) {
+ try {
+@@ -267,18 +268,18 @@
+ return Integer.valueOf(intIndex);
+ } catch(Exception|Error e) {
+ throw e;
+- } catch(Throwable t) {
++ } catch(final Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ return Integer.valueOf(fixedKey);
+- } catch(NumberFormatException e) {
++ } catch(final NumberFormatException e) {
+ // key is not a number
+ return null;
+ }
+ }
+
+- private static MethodHandle convertArgToInt(MethodHandle mh, LinkerServices ls, CallSiteDescriptor desc) {
++ private static MethodHandle convertArgToInt(final MethodHandle mh, final LinkerServices ls, final CallSiteDescriptor desc) {
+ final Class<?> sourceType = desc.getMethodType().parameterType(1);
+ if(TypeUtilities.isMethodInvocationConvertible(sourceType, Number.class)) {
+ return mh;
+@@ -301,21 +302,21 @@
+ private final MethodType methodType;
+ private final Object fixedKey;
+
+- Binder(LinkerServices linkerServices, MethodType methodType, Object fixedKey) {
++ Binder(final LinkerServices linkerServices, final MethodType methodType, final Object fixedKey) {
+ this.linkerServices = linkerServices;
+ this.methodType = fixedKey == null ? methodType : methodType.insertParameterTypes(1, fixedKey.getClass());
+ this.fixedKey = fixedKey;
+ }
+
+- /*private*/ MethodHandle bind(MethodHandle handle) {
+- return bindToFixedKey(linkerServices.asType(handle, methodType));
++ /*private*/ MethodHandle bind(final MethodHandle handle) {
++ return bindToFixedKey(linkerServices.asTypeLosslessReturn(handle, methodType));
+ }
+
+- /*private*/ MethodHandle bindTest(MethodHandle handle) {
++ /*private*/ MethodHandle bindTest(final MethodHandle handle) {
+ return bindToFixedKey(Guards.asType(handle, methodType));
+ }
+
+- private MethodHandle bindToFixedKey(MethodHandle handle) {
++ private MethodHandle bindToFixedKey(final MethodHandle handle) {
+ return fixedKey == null ? handle : MethodHandles.insertArguments(handle, 1, fixedKey);
+ }
+ }
+@@ -325,12 +326,12 @@
+ private static MethodHandle CONTAINS_MAP = Lookup.PUBLIC.findVirtual(Map.class, "containsKey",
+ MethodType.methodType(boolean.class, Object.class));
+
+- private static MethodHandle findRangeCheck(Class<?> collectionType) {
++ private static MethodHandle findRangeCheck(final Class<?> collectionType) {
+ return Lookup.findOwnStatic(MethodHandles.lookup(), "rangeCheck", boolean.class, collectionType, Object.class);
+ }
+
+ @SuppressWarnings("unused")
+- private static final boolean rangeCheck(Object array, Object index) {
++ private static final boolean rangeCheck(final Object array, final Object index) {
+ if(!(index instanceof Number)) {
+ return false;
+ }
+@@ -347,7 +348,7 @@
+ }
+
+ @SuppressWarnings("unused")
+- private static final boolean rangeCheck(List<?> list, Object index) {
++ private static final boolean rangeCheck(final List<?> list, final Object index) {
+ if(!(index instanceof Number)) {
+ return false;
+ }
+@@ -369,8 +370,8 @@
+ private static MethodHandle PUT_MAP_ELEMENT = Lookup.PUBLIC.findVirtual(Map.class, "put",
+ MethodType.methodType(Object.class, Object.class, Object.class));
+
+- private GuardedInvocationComponent getElementSetter(CallSiteDescriptor callSiteDescriptor,
+- LinkerServices linkerServices, List<String> operations) throws Exception {
++ private GuardedInvocationComponent getElementSetter(final CallSiteDescriptor callSiteDescriptor,
++ final LinkerServices linkerServices, final List<String> operations) throws Exception {
+ final MethodType callSiteType = callSiteDescriptor.getMethodType();
+ final Class<?> declaredType = callSiteType.parameterType(0);
+
+@@ -440,8 +441,9 @@
+
+ final MethodHandle checkGuard = convertArgToInt(invocation == SET_LIST_ELEMENT ? RANGE_CHECK_LIST :
+ RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
+- return nextComponent.compose(MethodHandles.guardWithTest(binder.bindTest(checkGuard),
+- binder.bind(invocation), nextComponent.getGuardedInvocation().getInvocation()), gi.getGuard(),
++ final MethodPair matchedInvocations = matchReturnTypes(binder.bind(invocation),
++ nextComponent.getGuardedInvocation().getInvocation());
++ return nextComponent.compose(matchedInvocations.guardWithTest(binder.bindTest(checkGuard)), gi.getGuard(),
+ gic.getValidatorClass(), gic.getValidationType());
+ }
+
+@@ -456,7 +458,7 @@
+
+ private static MethodHandle COLLECTION_GUARD = Guards.getInstanceOfGuard(Collection.class);
+
+- private GuardedInvocationComponent getLengthGetter(CallSiteDescriptor callSiteDescriptor) {
++ private GuardedInvocationComponent getLengthGetter(final CallSiteDescriptor callSiteDescriptor) {
+ assertParameterCount(callSiteDescriptor, 1);
+ final MethodType callSiteType = callSiteDescriptor.getMethodType();
+ final Class<?> declaredType = callSiteType.parameterType(0);
+@@ -486,7 +488,7 @@
+ return null;
+ }
+
+- private static void assertParameterCount(CallSiteDescriptor descriptor, int paramCount) {
++ private static void assertParameterCount(final CallSiteDescriptor descriptor, final int paramCount) {
+ if(descriptor.getMethodType().parameterCount() != paramCount) {
+ throw new BootstrapMethodError(descriptor.getName() + " must have exactly " + paramCount + " parameters.");
+ }
+--- ./nashorn/src/jdk/internal/dynalink/beans/BeansLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/BeansLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -131,7 +131,7 @@
+ public class BeansLinker implements GuardingDynamicLinker {
+ private static final ClassValue<TypeBasedGuardingDynamicLinker> linkers = new ClassValue<TypeBasedGuardingDynamicLinker>() {
+ @Override
+- protected TypeBasedGuardingDynamicLinker computeValue(Class<?> clazz) {
++ protected TypeBasedGuardingDynamicLinker computeValue(final Class<?> clazz) {
+ // If ClassValue.put() were public, we could just pre-populate with these known mappings...
+ return
+ clazz == Class.class ? new ClassLinker() :
+@@ -154,7 +154,7 @@
+ * @param clazz the class
+ * @return a bean linker for that class
+ */
+- public static TypeBasedGuardingDynamicLinker getLinkerForClass(Class<?> clazz) {
++ public static TypeBasedGuardingDynamicLinker getLinkerForClass(final Class<?> clazz) {
+ return linkers.get(clazz);
+ }
+
+@@ -169,12 +169,32 @@
+ }
+
+ /**
++ * Returns true if the object is a Dynalink Java constructor.
++ *
++ * @param obj the object we want to test for being a constructor
++ * @return true if it is a constructor, false otherwise.
++ */
++ public static boolean isDynamicConstructor(final Object obj) {
++ return obj instanceof DynamicMethod && ((DynamicMethod)obj).isConstructor();
++ }
++
++ /**
++ * Return the dynamic method of constructor of the given class and the given signature.
++ * @param clazz the class
++ * @param signature full signature of the constructor
++ * @return DynamicMethod for the constructor
++ */
++ public static Object getConstructorMethod(final Class<?> clazz, final String signature) {
++ return StaticClassLinker.getConstructorMethod(clazz, signature);
++ }
++
++ /**
+ * Returns a collection of names of all readable instance properties of a class.
+ * @param clazz the class
+ * @return a collection of names of all readable instance properties of a class.
+ */
+- public static Collection<String> getReadableInstancePropertyNames(Class<?> clazz) {
+- TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz);
++ public static Collection<String> getReadableInstancePropertyNames(final Class<?> clazz) {
++ final TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz);
+ if(linker instanceof BeanLinker) {
+ return ((BeanLinker)linker).getReadablePropertyNames();
+ }
+@@ -186,8 +206,8 @@
+ * @param clazz the class
+ * @return a collection of names of all writable instance properties of a class.
+ */
+- public static Collection<String> getWritableInstancePropertyNames(Class<?> clazz) {
+- TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz);
++ public static Collection<String> getWritableInstancePropertyNames(final Class<?> clazz) {
++ final TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz);
+ if(linker instanceof BeanLinker) {
+ return ((BeanLinker)linker).getWritablePropertyNames();
+ }
+@@ -199,8 +219,8 @@
+ * @param clazz the class
+ * @return a collection of names of all instance methods of a class.
+ */
+- public static Collection<String> getInstanceMethodNames(Class<?> clazz) {
+- TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz);
++ public static Collection<String> getInstanceMethodNames(final Class<?> clazz) {
++ final TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz);
+ if(linker instanceof BeanLinker) {
+ return ((BeanLinker)linker).getMethodNames();
+ }
+@@ -212,7 +232,7 @@
+ * @param clazz the class
+ * @return a collection of names of all readable static properties of a class.
+ */
+- public static Collection<String> getReadableStaticPropertyNames(Class<?> clazz) {
++ public static Collection<String> getReadableStaticPropertyNames(final Class<?> clazz) {
+ return StaticClassLinker.getReadableStaticPropertyNames(clazz);
+ }
+
+@@ -221,7 +241,7 @@
+ * @param clazz the class
+ * @return a collection of names of all writable static properties of a class.
+ */
+- public static Collection<String> getWritableStaticPropertyNames(Class<?> clazz) {
++ public static Collection<String> getWritableStaticPropertyNames(final Class<?> clazz) {
+ return StaticClassLinker.getWritableStaticPropertyNames(clazz);
+ }
+
+@@ -230,12 +250,12 @@
+ * @param clazz the class
+ * @return a collection of names of all static methods of a class.
+ */
+- public static Collection<String> getStaticMethodNames(Class<?> clazz) {
++ public static Collection<String> getStaticMethodNames(final Class<?> clazz) {
+ return StaticClassLinker.getStaticMethodNames(clazz);
+ }
+
+ @Override
+- public GuardedInvocation getGuardedInvocation(LinkRequest request, final LinkerServices linkerServices)
++ public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices)
+ throws Exception {
+ final CallSiteDescriptor callSiteDescriptor = request.getCallSiteDescriptor();
+ final int l = callSiteDescriptor.getNameTokenCount();
+--- ./nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDetector.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDetector.java Wed Feb 04 12:14:47 2015 -0800
+@@ -107,14 +107,14 @@
+
+ private static final DetectionStrategy DETECTION_STRATEGY = getDetectionStrategy();
+
+- static boolean isCallerSensitive(AccessibleObject ao) {
++ static boolean isCallerSensitive(final AccessibleObject ao) {
+ return DETECTION_STRATEGY.isCallerSensitive(ao);
+ }
+
+ private static DetectionStrategy getDetectionStrategy() {
+ try {
+ return new PrivilegedDetectionStrategy();
+- } catch(Throwable t) {
++ } catch(final Throwable t) {
+ return new UnprivilegedDetectionStrategy();
+ }
+ }
+@@ -127,7 +127,7 @@
+ private static final Class<? extends Annotation> CALLER_SENSITIVE_ANNOTATION_CLASS = CallerSensitive.class;
+
+ @Override
+- boolean isCallerSensitive(AccessibleObject ao) {
++ boolean isCallerSensitive(final AccessibleObject ao) {
+ return ao.getAnnotation(CALLER_SENSITIVE_ANNOTATION_CLASS) != null;
+ }
+ }
+@@ -136,8 +136,8 @@
+ private static final String CALLER_SENSITIVE_ANNOTATION_STRING = "@sun.reflect.CallerSensitive()";
+
+ @Override
+- boolean isCallerSensitive(AccessibleObject o) {
+- for(Annotation a: o.getAnnotations()) {
++ boolean isCallerSensitive(final AccessibleObject o) {
++ for(final Annotation a: o.getAnnotations()) {
+ if(String.valueOf(a).equals(CALLER_SENSITIVE_ANNOTATION_STRING)) {
+ return true;
+ }
+--- ./nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java Wed Feb 04 12:14:47 2015 -0800
+@@ -107,13 +107,13 @@
+ private final AccessibleObject target;
+ private final MethodType type;
+
+- public CallerSensitiveDynamicMethod(AccessibleObject target) {
++ public CallerSensitiveDynamicMethod(final AccessibleObject target) {
+ super(getName(target));
+ this.target = target;
+ this.type = getMethodType(target);
+ }
+
+- private static String getName(AccessibleObject target) {
++ private static String getName(final AccessibleObject target) {
+ final Member m = (Member)target;
+ return getMethodNameWithSignature(getMethodType(target), getClassAndMethodName(m.getDeclaringClass(),
+ m.getName()));
+@@ -124,7 +124,7 @@
+ return type;
+ }
+
+- private static MethodType getMethodType(AccessibleObject ao) {
++ private static MethodType getMethodType(final AccessibleObject ao) {
+ final boolean isMethod = ao instanceof Method;
+ final Class<?> rtype = isMethod ? ((Method)ao).getReturnType() : ((Constructor<?>)ao).getDeclaringClass();
+ final Class<?>[] ptypes = isMethod ? ((Method)ao).getParameterTypes() : ((Constructor<?>)ao).getParameterTypes();
+@@ -144,7 +144,7 @@
+ }
+
+ @Override
+- MethodHandle getTarget(MethodHandles.Lookup lookup) {
++ MethodHandle getTarget(final MethodHandles.Lookup lookup) {
+ if(target instanceof Method) {
+ final MethodHandle mh = Lookup.unreflect(lookup, (Method)target);
+ if(Modifier.isStatic(((Member)target).getModifiers())) {
+@@ -155,4 +155,9 @@
+ return StaticClassIntrospector.editConstructorMethodHandle(Lookup.unreflectConstructor(lookup,
+ (Constructor<?>)target));
+ }
++
++ @Override
++ boolean isConstructor() {
++ return target instanceof Constructor;
++ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/beans/CheckRestrictedPackage.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/CheckRestrictedPackage.java Wed Feb 04 12:14:47 2015 -0800
+@@ -101,7 +101,7 @@
+ * @param clazz the class to test
+ * @return true if the class is either not public, or it resides in a package with restricted access.
+ */
+- static boolean isRestrictedClass(Class<?> clazz) {
++ static boolean isRestrictedClass(final Class<?> clazz) {
+ if(!Modifier.isPublic(clazz.getModifiers())) {
+ // Non-public classes are always restricted
+ return true;
+@@ -126,7 +126,7 @@
+ return null;
+ }
+ }, NO_PERMISSIONS_CONTEXT);
+- } catch(SecurityException e) {
++ } catch(final SecurityException e) {
+ return true;
+ }
+ return false;
+--- ./nashorn/src/jdk/internal/dynalink/beans/ClassString.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/ClassString.java Wed Feb 04 12:14:47 2015 -0800
+@@ -104,16 +104,16 @@
+ private final Class<?>[] classes;
+ private int hashCode;
+
+- ClassString(Class<?>[] classes) {
++ ClassString(final Class<?>[] classes) {
+ this.classes = classes;
+ }
+
+- ClassString(MethodType type) {
++ ClassString(final MethodType type) {
+ this(type.parameterArray());
+ }
+
+ @Override
+- public boolean equals(Object other) {
++ public boolean equals(final Object other) {
+ if(!(other instanceof ClassString)) {
+ return false;
+ }
+@@ -150,7 +150,7 @@
+ return true;
+ }
+
+- List<MethodHandle> getMaximallySpecifics(List<MethodHandle> methods, LinkerServices linkerServices, boolean varArg) {
++ List<MethodHandle> getMaximallySpecifics(final List<MethodHandle> methods, final LinkerServices linkerServices, final boolean varArg) {
+ return MaximallySpecific.getMaximallySpecificMethodHandles(getApplicables(methods, linkerServices, varArg),
+ varArg, classes, linkerServices);
+ }
+@@ -158,7 +158,7 @@
+ /**
+ * Returns all methods that are applicable to actual parameter classes represented by this ClassString object.
+ */
+- LinkedList<MethodHandle> getApplicables(List<MethodHandle> methods, LinkerServices linkerServices, boolean varArg) {
++ LinkedList<MethodHandle> getApplicables(final List<MethodHandle> methods, final LinkerServices linkerServices, final boolean varArg) {
+ final LinkedList<MethodHandle> list = new LinkedList<>();
+ for(final MethodHandle member: methods) {
+ if(isApplicable(member, linkerServices, varArg)) {
+@@ -173,7 +173,7 @@
+ * object.
+ *
+ */
+- private boolean isApplicable(MethodHandle method, LinkerServices linkerServices, boolean varArg) {
++ private boolean isApplicable(final MethodHandle method, final LinkerServices linkerServices, final boolean varArg) {
+ final Class<?>[] formalTypes = method.type().parameterArray();
+ final int cl = classes.length;
+ final int fl = formalTypes.length - (varArg ? 1 : 0);
+@@ -203,7 +203,7 @@
+ return true;
+ }
+
+- private static boolean canConvert(LinkerServices ls, Class<?> from, Class<?> to) {
++ private static boolean canConvert(final LinkerServices ls, final Class<?> from, final Class<?> to) {
+ if(from == NULL_CLASS) {
+ return !to.isPrimitive();
+ }
+--- ./nashorn/src/jdk/internal/dynalink/beans/DynamicMethod.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/DynamicMethod.java Wed Feb 04 12:14:47 2015 -0800
+@@ -99,7 +99,7 @@
+ abstract class DynamicMethod {
+ private final String name;
+
+- DynamicMethod(String name) {
++ DynamicMethod(final String name) {
+ this.name = name;
+ }
+
+@@ -138,7 +138,7 @@
+ */
+ abstract boolean contains(SingleDynamicMethod method);
+
+- static String getClassAndMethodName(Class<?> clazz, String name) {
++ static String getClassAndMethodName(final Class<?> clazz, final String name) {
+ final String clazzName = clazz.getCanonicalName();
+ return (clazzName == null ? clazz.getName() : clazzName) + "." + name;
+ }
+@@ -147,4 +147,13 @@
+ public String toString() {
+ return "[" + getClass().getName() + " " + getName() + "]";
+ }
++
++ /**
++ * True if this method happens to be a constructor method.
++ *
++ * @return true if this represents a constructor.
++ */
++ boolean isConstructor() {
++ return false;
++ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/beans/DynamicMethodLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/DynamicMethodLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -99,12 +99,12 @@
+ */
+ class DynamicMethodLinker implements TypeBasedGuardingDynamicLinker {
+ @Override
+- public boolean canLinkType(Class<?> type) {
++ public boolean canLinkType(final Class<?> type) {
+ return DynamicMethod.class.isAssignableFrom(type);
+ }
+
+ @Override
+- public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) {
++ public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) {
+ final Object receiver = linkRequest.getReceiver();
+ if(!(receiver instanceof DynamicMethod)) {
+ return null;
+@@ -114,15 +114,30 @@
+ return null;
+ }
+ final String operator = desc.getNameToken(CallSiteDescriptor.OPERATOR);
+- if(operator == "call") {
+- final MethodHandle invocation = ((DynamicMethod)receiver).getInvocation(
++ final DynamicMethod dynMethod = (DynamicMethod)receiver;
++ final boolean constructor = dynMethod.isConstructor();
++ final MethodHandle invocation;
++
++ if (operator == "call" && !constructor) {
++ invocation = dynMethod.getInvocation(
+ CallSiteDescriptorFactory.dropParameterTypes(desc, 0, 1), linkerServices);
+- if(invocation == null) {
++ } else if (operator == "new" && constructor) {
++ final MethodHandle ctorInvocation = dynMethod.getInvocation(desc, linkerServices);
++ if(ctorInvocation == null) {
+ return null;
+ }
++
++ // Insert null for StaticClass parameter
++ invocation = MethodHandles.insertArguments(ctorInvocation, 0, (Object)null);
++ } else {
++ return null;
++ }
++
++ if (invocation != null) {
+ return new GuardedInvocation(MethodHandles.dropArguments(invocation, 0,
+- desc.getMethodType().parameterType(0)), Guards.getIdentityGuard(receiver));
++ desc.getMethodType().parameterType(0)), Guards.getIdentityGuard(receiver));
+ }
++
+ return null;
+ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java Wed Feb 04 12:14:47 2015 -0800
+@@ -106,7 +106,7 @@
+
+ protected final AccessibleMembersLookup membersLookup;
+
+- FacetIntrospector(Class<?> clazz, boolean instance) {
++ FacetIntrospector(final Class<?> clazz, final boolean instance) {
+ this.clazz = clazz;
+ this.instance = instance;
+ isRestricted = CheckRestrictedPackage.isRestrictedClass(clazz);
+@@ -135,7 +135,7 @@
+
+ final Field[] fields = clazz.getFields();
+ final Collection<Field> cfields = new ArrayList<>(fields.length);
+- for(Field field: fields) {
++ for(final Field field: fields) {
+ final boolean isStatic = Modifier.isStatic(field.getModifiers());
+ if(isStatic && clazz != field.getDeclaringClass()) {
+ // ignore inherited static fields
+@@ -149,7 +149,7 @@
+ return cfields;
+ }
+
+- boolean isAccessible(Member m) {
++ boolean isAccessible(final Member m) {
+ final Class<?> declaring = m.getDeclaringClass();
+ // (declaring == clazz) is just an optimization - we're calling this only from code that operates on a
+ // non-restriced class, so if the declaring class is identical to the class being inspected, then forego
+@@ -166,11 +166,11 @@
+ }
+
+
+- MethodHandle unreflectGetter(Field field) {
++ MethodHandle unreflectGetter(final Field field) {
+ return editMethodHandle(Lookup.PUBLIC.unreflectGetter(field));
+ }
+
+- MethodHandle unreflectSetter(Field field) {
++ MethodHandle unreflectSetter(final Field field) {
+ return editMethodHandle(Lookup.PUBLIC.unreflectSetter(field));
+ }
+
+--- ./nashorn/src/jdk/internal/dynalink/beans/GuardedInvocationComponent.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/GuardedInvocationComponent.java Wed Feb 04 12:14:47 2015 -0800
+@@ -105,38 +105,38 @@
+ private final GuardedInvocation guardedInvocation;
+ private final Validator validator;
+
+- GuardedInvocationComponent(MethodHandle invocation) {
++ GuardedInvocationComponent(final MethodHandle invocation) {
+ this(invocation, null, ValidationType.NONE);
+ }
+
+- GuardedInvocationComponent(MethodHandle invocation, MethodHandle guard, ValidationType validationType) {
++ GuardedInvocationComponent(final MethodHandle invocation, final MethodHandle guard, final ValidationType validationType) {
+ this(invocation, guard, null, validationType);
+ }
+
+- GuardedInvocationComponent(MethodHandle invocation, MethodHandle guard, Class<?> validatorClass,
+- ValidationType validationType) {
++ GuardedInvocationComponent(final MethodHandle invocation, final MethodHandle guard, final Class<?> validatorClass,
++ final ValidationType validationType) {
+ this(invocation, guard, new Validator(validatorClass, validationType));
+ }
+
+- GuardedInvocationComponent(GuardedInvocation guardedInvocation, Class<?> validatorClass,
+- ValidationType validationType) {
++ GuardedInvocationComponent(final GuardedInvocation guardedInvocation, final Class<?> validatorClass,
++ final ValidationType validationType) {
+ this(guardedInvocation, new Validator(validatorClass, validationType));
+ }
+
+- GuardedInvocationComponent replaceInvocation(MethodHandle newInvocation) {
++ GuardedInvocationComponent replaceInvocation(final MethodHandle newInvocation) {
+ return replaceInvocation(newInvocation, guardedInvocation.getGuard());
+ }
+
+- GuardedInvocationComponent replaceInvocation(MethodHandle newInvocation, MethodHandle newGuard) {
++ GuardedInvocationComponent replaceInvocation(final MethodHandle newInvocation, final MethodHandle newGuard) {
+ return new GuardedInvocationComponent(guardedInvocation.replaceMethods(newInvocation,
+ newGuard), validator);
+ }
+
+- private GuardedInvocationComponent(MethodHandle invocation, MethodHandle guard, Validator validator) {
++ private GuardedInvocationComponent(final MethodHandle invocation, final MethodHandle guard, final Validator validator) {
+ this(new GuardedInvocation(invocation, guard), validator);
+ }
+
+- private GuardedInvocationComponent(GuardedInvocation guardedInvocation, Validator validator) {
++ private GuardedInvocationComponent(final GuardedInvocation guardedInvocation, final Validator validator) {
+ this.guardedInvocation = guardedInvocation;
+ this.validator = validator;
+ }
+@@ -153,8 +153,8 @@
+ return validator.validationType;
+ }
+
+- GuardedInvocationComponent compose(MethodHandle compositeInvocation, MethodHandle otherGuard,
+- Class<?> otherValidatorClass, ValidationType otherValidationType) {
++ GuardedInvocationComponent compose(final MethodHandle compositeInvocation, final MethodHandle otherGuard,
++ final Class<?> otherValidatorClass, final ValidationType otherValidationType) {
+ final Validator compositeValidator = validator.compose(new Validator(otherValidatorClass, otherValidationType));
+ final MethodHandle compositeGuard = compositeValidator == validator ? guardedInvocation.getGuard() : otherGuard;
+ return new GuardedInvocationComponent(compositeInvocation, compositeGuard, compositeValidator);
+@@ -164,12 +164,12 @@
+ /*private*/ final Class<?> validatorClass;
+ /*private*/ final ValidationType validationType;
+
+- Validator(Class<?> validatorClass, ValidationType validationType) {
++ Validator(final Class<?> validatorClass, final ValidationType validationType) {
+ this.validatorClass = validatorClass;
+ this.validationType = validationType;
+ }
+
+- Validator compose(Validator other) {
++ Validator compose(final Validator other) {
+ if(other.validationType == ValidationType.NONE) {
+ return this;
+ }
+@@ -240,7 +240,7 @@
+ throw new AssertionError("Incompatible composition " + this + " vs " + other);
+ }
+
+- private boolean isAssignableFrom(Validator other) {
++ private boolean isAssignableFrom(final Validator other) {
+ return validatorClass.isAssignableFrom(other.validatorClass);
+ }
+
+--- ./nashorn/src/jdk/internal/dynalink/beans/MaximallySpecific.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/MaximallySpecific.java Wed Feb 04 12:14:47 2015 -0800
+@@ -105,7 +105,7 @@
+ * @param varArgs whether to assume the methods are varargs
+ * @return the list of maximally specific methods.
+ */
+- static List<SingleDynamicMethod> getMaximallySpecificMethods(List<SingleDynamicMethod> methods, boolean varArgs) {
++ static List<SingleDynamicMethod> getMaximallySpecificMethods(final List<SingleDynamicMethod> methods, final boolean varArgs) {
+ return getMaximallySpecificSingleDynamicMethods(methods, varArgs, null, null);
+ }
+
+@@ -116,7 +116,7 @@
+ private static final MethodTypeGetter<MethodHandle> METHOD_HANDLE_TYPE_GETTER =
+ new MethodTypeGetter<MethodHandle>() {
+ @Override
+- MethodType getMethodType(MethodHandle t) {
++ MethodType getMethodType(final MethodHandle t) {
+ return t.type();
+ }
+ };
+@@ -124,7 +124,7 @@
+ private static final MethodTypeGetter<SingleDynamicMethod> DYNAMIC_METHOD_TYPE_GETTER =
+ new MethodTypeGetter<SingleDynamicMethod>() {
+ @Override
+- MethodType getMethodType(SingleDynamicMethod t) {
++ MethodType getMethodType(final SingleDynamicMethod t) {
+ return t.getMethodType();
+ }
+ };
+@@ -138,8 +138,8 @@
+ * @param argTypes concrete argument types for the invocation
+ * @return the list of maximally specific method handles.
+ */
+- static List<MethodHandle> getMaximallySpecificMethodHandles(List<MethodHandle> methods, boolean varArgs,
+- Class<?>[] argTypes, LinkerServices ls) {
++ static List<MethodHandle> getMaximallySpecificMethodHandles(final List<MethodHandle> methods, final boolean varArgs,
++ final Class<?>[] argTypes, final LinkerServices ls) {
+ return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, METHOD_HANDLE_TYPE_GETTER);
+ }
+
+@@ -152,8 +152,8 @@
+ * @param argTypes concrete argument types for the invocation
+ * @return the list of maximally specific methods.
+ */
+- static List<SingleDynamicMethod> getMaximallySpecificSingleDynamicMethods(List<SingleDynamicMethod> methods,
+- boolean varArgs, Class<?>[] argTypes, LinkerServices ls) {
++ static List<SingleDynamicMethod> getMaximallySpecificSingleDynamicMethods(final List<SingleDynamicMethod> methods,
++ final boolean varArgs, final Class<?>[] argTypes, final LinkerServices ls) {
+ return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, DYNAMIC_METHOD_TYPE_GETTER);
+ }
+
+@@ -166,16 +166,16 @@
+ * @param argTypes concrete argument types for the invocation
+ * @return the list of maximally specific methods.
+ */
+- private static <T> List<T> getMaximallySpecificMethods(List<T> methods, boolean varArgs,
+- Class<?>[] argTypes, LinkerServices ls, MethodTypeGetter<T> methodTypeGetter) {
++ private static <T> List<T> getMaximallySpecificMethods(final List<T> methods, final boolean varArgs,
++ final Class<?>[] argTypes, final LinkerServices ls, final MethodTypeGetter<T> methodTypeGetter) {
+ if(methods.size() < 2) {
+ return methods;
+ }
+ final LinkedList<T> maximals = new LinkedList<>();
+- for(T m: methods) {
++ for(final T m: methods) {
+ final MethodType methodType = methodTypeGetter.getMethodType(m);
+ boolean lessSpecific = false;
+- for(Iterator<T> maximal = maximals.iterator(); maximal.hasNext();) {
++ for(final Iterator<T> maximal = maximals.iterator(); maximal.hasNext();) {
+ final T max = maximal.next();
+ switch(isMoreSpecific(methodType, methodTypeGetter.getMethodType(max), varArgs, argTypes, ls)) {
+ case TYPE_1_BETTER: {
+@@ -202,8 +202,8 @@
+ return maximals;
+ }
+
+- private static Comparison isMoreSpecific(MethodType t1, MethodType t2, boolean varArgs, Class<?>[] argTypes,
+- LinkerServices ls) {
++ private static Comparison isMoreSpecific(final MethodType t1, final MethodType t2, final boolean varArgs, final Class<?>[] argTypes,
++ final LinkerServices ls) {
+ final int pc1 = t1.parameterCount();
+ final int pc2 = t2.parameterCount();
+ assert varArgs || (pc1 == pc2) && (argTypes == null || argTypes.length == pc1);
+@@ -241,7 +241,7 @@
+ return Comparison.INDETERMINATE;
+ }
+
+- private static Comparison compare(Class<?> c1, Class<?> c2, Class<?>[] argTypes, int i, LinkerServices cmp) {
++ private static Comparison compare(final Class<?> c1, final Class<?> c2, final Class<?>[] argTypes, final int i, final LinkerServices cmp) {
+ if(cmp != null) {
+ final Comparison c = cmp.compareConversion(argTypes[i], c1, c2);
+ if(c != Comparison.INDETERMINATE) {
+@@ -256,7 +256,7 @@
+ return Comparison.INDETERMINATE;
+ }
+
+- private static Class<?> getParameterClass(MethodType t, int l, int i, boolean varArgs) {
++ private static Class<?> getParameterClass(final MethodType t, final int l, final int i, final boolean varArgs) {
+ return varArgs && i >= l - 1 ? t.parameterType(l - 1).getComponentType() : t.parameterType(i);
+ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java Wed Feb 04 12:14:47 2015 -0800
+@@ -115,20 +115,20 @@
+ * @param clazz the class this method belongs to
+ * @param name the name of the method
+ */
+- OverloadedDynamicMethod(Class<?> clazz, String name) {
++ OverloadedDynamicMethod(final Class<?> clazz, final String name) {
+ this(new LinkedList<SingleDynamicMethod>(), clazz.getClassLoader(), getClassAndMethodName(clazz, name));
+ }
+
+- private OverloadedDynamicMethod(LinkedList<SingleDynamicMethod> methods, ClassLoader classLoader, String name) {
++ private OverloadedDynamicMethod(final LinkedList<SingleDynamicMethod> methods, final ClassLoader classLoader, final String name) {
+ super(name);
+ this.methods = methods;
+ this.classLoader = classLoader;
+ }
+
+ @Override
+- SingleDynamicMethod getMethodForExactParamTypes(String paramTypes) {
++ SingleDynamicMethod getMethodForExactParamTypes(final String paramTypes) {
+ final LinkedList<SingleDynamicMethod> matchingMethods = new LinkedList<>();
+- for(SingleDynamicMethod method: methods) {
++ for(final SingleDynamicMethod method: methods) {
+ final SingleDynamicMethod matchingMethod = method.getMethodForExactParamTypes(paramTypes);
+ if(matchingMethod != null) {
+ matchingMethods.add(matchingMethod);
+@@ -148,7 +148,6 @@
+ }
+ }
+
+- @SuppressWarnings("fallthrough")
+ @Override
+ public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) {
+ final MethodType callSiteType = callSiteDescriptor.getMethodType();
+@@ -207,7 +206,7 @@
+ case 1: {
+ // Very lucky, we ended up with a single candidate method handle based on the call site signature; we
+ // can link it very simply by delegating to the SingleDynamicMethod.
+- invokables.iterator().next().getInvocation(callSiteDescriptor, linkerServices);
++ return invokables.iterator().next().getInvocation(callSiteDescriptor, linkerServices);
+ }
+ default: {
+ // We have more than one candidate. We have no choice but to link to a method that resolves overloads on
+@@ -218,7 +217,7 @@
+ // has an already determined Lookup.
+ final List<MethodHandle> methodHandles = new ArrayList<>(invokables.size());
+ final MethodHandles.Lookup lookup = callSiteDescriptor.getLookup();
+- for(SingleDynamicMethod method: invokables) {
++ for(final SingleDynamicMethod method: invokables) {
+ methodHandles.add(method.getTarget(lookup));
+ }
+ return new OverloadedMethod(methodHandles, this, callSiteType, linkerServices).getInvoker();
+@@ -228,8 +227,8 @@
+ }
+
+ @Override
+- public boolean contains(SingleDynamicMethod m) {
+- for(SingleDynamicMethod method: methods) {
++ public boolean contains(final SingleDynamicMethod m) {
++ for(final SingleDynamicMethod method: methods) {
+ if(method.contains(m)) {
+ return true;
+ }
+@@ -237,12 +236,18 @@
+ return false;
+ }
+
++ @Override
++ public boolean isConstructor() {
++ assert !methods.isEmpty();
++ return methods.getFirst().isConstructor();
++ }
++
+ ClassLoader getClassLoader() {
+ return classLoader;
+ }
+
+- private static boolean isApplicableDynamically(LinkerServices linkerServices, MethodType callSiteType,
+- SingleDynamicMethod m) {
++ private static boolean isApplicableDynamically(final LinkerServices linkerServices, final MethodType callSiteType,
++ final SingleDynamicMethod m) {
+ final MethodType methodType = m.getMethodType();
+ final boolean varArgs = m.isVarArgs();
+ final int fixedArgLen = methodType.parameterCount() - (varArgs ? 1 : 0);
+@@ -288,13 +293,13 @@
+ return true;
+ }
+
+- private static boolean isApplicableDynamically(LinkerServices linkerServices, Class<?> callSiteType,
+- Class<?> methodType) {
++ private static boolean isApplicableDynamically(final LinkerServices linkerServices, final Class<?> callSiteType,
++ final Class<?> methodType) {
+ return TypeUtilities.isPotentiallyConvertible(callSiteType, methodType)
+ || linkerServices.canConvert(callSiteType, methodType);
+ }
+
+- private ApplicableOverloadedMethods getApplicables(MethodType callSiteType, ApplicabilityTest test) {
++ private ApplicableOverloadedMethods getApplicables(final MethodType callSiteType, final ApplicabilityTest test) {
+ return new ApplicableOverloadedMethods(methods, callSiteType, test);
+ }
+
+@@ -303,7 +308,12 @@
+ *
+ * @param method a method to add
+ */
+- public void addMethod(SingleDynamicMethod method) {
++ public void addMethod(final SingleDynamicMethod method) {
++ assert constructorFlagConsistent(method);
+ methods.add(method);
+ }
++
++ private boolean constructorFlagConsistent(final SingleDynamicMethod method) {
++ return methods.isEmpty()? true : (methods.getFirst().isConstructor() == method.isConstructor());
++ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/beans/OverloadedMethod.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/OverloadedMethod.java Wed Feb 04 12:14:47 2015 -0800
+@@ -93,6 +93,7 @@
+ import java.util.concurrent.ConcurrentHashMap;
+ import jdk.internal.dynalink.linker.LinkerServices;
+ import jdk.internal.dynalink.support.Lookup;
++import jdk.internal.dynalink.support.TypeUtilities;
+
+ /**
+ * Represents a subset of overloaded methods for a certain method name on a certain class. It can be either a fixarg or
+@@ -111,10 +112,11 @@
+ private final ArrayList<MethodHandle> fixArgMethods;
+ private final ArrayList<MethodHandle> varArgMethods;
+
+- OverloadedMethod(List<MethodHandle> methodHandles, OverloadedDynamicMethod parent, MethodType callSiteType,
+- LinkerServices linkerServices) {
++ OverloadedMethod(final List<MethodHandle> methodHandles, final OverloadedDynamicMethod parent, final MethodType callSiteType,
++ final LinkerServices linkerServices) {
+ this.parent = parent;
+- this.callSiteType = callSiteType;
++ final Class<?> commonRetType = getCommonReturnType(methodHandles);
++ this.callSiteType = callSiteType.changeReturnType(commonRetType);
+ this.linkerServices = linkerServices;
+
+ fixArgMethods = new ArrayList<>(methodHandles.size());
+@@ -137,7 +139,7 @@
+ final MethodHandle bound = SELECT_METHOD.bindTo(this);
+ final MethodHandle collecting = SingleDynamicMethod.collectArguments(bound, argNum).asType(
+ callSiteType.changeReturnType(MethodHandle.class));
+- invoker = MethodHandles.foldArguments(MethodHandles.exactInvoker(callSiteType), collecting);
++ invoker = MethodHandles.foldArguments(MethodHandles.exactInvoker(this.callSiteType), collecting);
+ }
+
+ MethodHandle getInvoker() {
+@@ -148,8 +150,8 @@
+ MethodHandle.class, Object[].class);
+
+ @SuppressWarnings("unused")
+- private MethodHandle selectMethod(Object[] args) throws NoSuchMethodException {
+- final Class<?>[] argTypes = new Class[args.length];
++ private MethodHandle selectMethod(final Object[] args) throws NoSuchMethodException {
++ final Class<?>[] argTypes = new Class<?>[args.length];
+ for(int i = 0; i < argTypes.length; ++i) {
+ final Object arg = args[i];
+ argTypes[i] = arg == null ? ClassString.NULL_CLASS : arg.getClass();
+@@ -185,7 +187,7 @@
+ return method;
+ }
+
+- private MethodHandle getNoSuchMethodThrower(Class<?>[] argTypes) {
++ private MethodHandle getNoSuchMethodThrower(final Class<?>[] argTypes) {
+ return adaptThrower(MethodHandles.insertArguments(THROW_NO_SUCH_METHOD, 0, this, argTypes));
+ }
+
+@@ -193,7 +195,7 @@
+ "throwNoSuchMethod", void.class, Class[].class);
+
+ @SuppressWarnings("unused")
+- private void throwNoSuchMethod(Class<?>[] argTypes) throws NoSuchMethodException {
++ private void throwNoSuchMethod(final Class<?>[] argTypes) throws NoSuchMethodException {
+ if(varArgMethods.isEmpty()) {
+ throw new NoSuchMethodException("None of the fixed arity signatures " + getSignatureList(fixArgMethods) +
+ " of method " + parent.getName() + " match the argument types " + argTypesString(argTypes));
+@@ -203,11 +205,11 @@
+ parent.getName() + " match the argument types " + argTypesString(argTypes));
+ }
+
+- private MethodHandle getAmbiguousMethodThrower(Class<?>[] argTypes, List<MethodHandle> methods) {
++ private MethodHandle getAmbiguousMethodThrower(final Class<?>[] argTypes, final List<MethodHandle> methods) {
+ return adaptThrower(MethodHandles.insertArguments(THROW_AMBIGUOUS_METHOD, 0, this, argTypes, methods));
+ }
+
+- private MethodHandle adaptThrower(MethodHandle rawThrower) {
++ private MethodHandle adaptThrower(final MethodHandle rawThrower) {
+ return MethodHandles.dropArguments(rawThrower, 0, callSiteType.parameterList()).asType(callSiteType);
+ }
+
+@@ -215,20 +217,20 @@
+ "throwAmbiguousMethod", void.class, Class[].class, List.class);
+
+ @SuppressWarnings("unused")
+- private void throwAmbiguousMethod(Class<?>[] argTypes, List<MethodHandle> methods) throws NoSuchMethodException {
++ private void throwAmbiguousMethod(final Class<?>[] argTypes, final List<MethodHandle> methods) throws NoSuchMethodException {
+ final String arity = methods.get(0).isVarargsCollector() ? "variable" : "fixed";
+ throw new NoSuchMethodException("Can't unambiguously select between " + arity + " arity signatures " +
+ getSignatureList(methods) + " of the method " + parent.getName() + " for argument types " +
+ argTypesString(argTypes));
+ }
+
+- private static String argTypesString(Class<?>[] classes) {
++ private static String argTypesString(final Class<?>[] classes) {
+ final StringBuilder b = new StringBuilder().append('[');
+ appendTypes(b, classes, false);
+ return b.append(']').toString();
+ }
+
+- private static String getSignatureList(List<MethodHandle> methods) {
++ private static String getSignatureList(final List<MethodHandle> methods) {
+ final StringBuilder b = new StringBuilder().append('[');
+ final Iterator<MethodHandle> it = methods.iterator();
+ if(it.hasNext()) {
+@@ -240,13 +242,13 @@
+ return b.append(']').toString();
+ }
+
+- private static void appendSig(StringBuilder b, MethodHandle m) {
++ private static void appendSig(final StringBuilder b, final MethodHandle m) {
+ b.append('(');
+ appendTypes(b, m.type().parameterArray(), m.isVarargsCollector());
+ b.append(')');
+ }
+
+- private static void appendTypes(StringBuilder b, Class<?>[] classes, boolean varArg) {
++ private static void appendTypes(final StringBuilder b, final Class<?>[] classes, final boolean varArg) {
+ final int l = classes.length;
+ if(!varArg) {
+ if(l > 1) {
+@@ -262,4 +264,13 @@
+ b.append(classes[l - 1].getComponentType().getCanonicalName()).append("...");
+ }
+ }
++
++ private static Class<?> getCommonReturnType(final List<MethodHandle> methodHandles) {
++ final Iterator<MethodHandle> it = methodHandles.iterator();
++ Class<?> retType = it.next().type().returnType();
++ while(it.hasNext()) {
++ retType = TypeUtilities.getCommonLosslessConversionType(retType, it.next().type().returnType());
++ }
++ return retType;
++ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java Wed Feb 04 12:14:47 2015 -0800
+@@ -98,6 +98,7 @@
+ */
+ class SimpleDynamicMethod extends SingleDynamicMethod {
+ private final MethodHandle target;
++ private final boolean constructor;
+
+ /**
+ * Creates a new simple dynamic method, with a name constructed from the class name, method name, and handle
+@@ -107,12 +108,26 @@
+ * @param clazz the class declaring the method
+ * @param name the simple name of the method
+ */
+- SimpleDynamicMethod(MethodHandle target, Class<?> clazz, String name) {
++ SimpleDynamicMethod(final MethodHandle target, final Class<?> clazz, final String name) {
++ this(target, clazz, name, false);
++ }
++
++ /**
++ * Creates a new simple dynamic method, with a name constructed from the class name, method name, and handle
++ * signature.
++ *
++ * @param target the target method handle
++ * @param clazz the class declaring the method
++ * @param name the simple name of the method
++ * @param constructor does this represent a constructor?
++ */
++ SimpleDynamicMethod(final MethodHandle target, final Class<?> clazz, final String name, final boolean constructor) {
+ super(getName(target, clazz, name));
+ this.target = target;
++ this.constructor = constructor;
+ }
+
+- private static String getName(MethodHandle target, Class<?> clazz, String name) {
++ private static String getName(final MethodHandle target, final Class<?> clazz, final String name) {
+ return getMethodNameWithSignature(target.type(), getClassAndMethodName(clazz, name));
+ }
+
+@@ -127,7 +142,12 @@
+ }
+
+ @Override
+- MethodHandle getTarget(Lookup lookup) {
++ MethodHandle getTarget(final Lookup lookup) {
+ return target;
+ }
++
++ @Override
++ boolean isConstructor() {
++ return constructor;
++ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java Wed Feb 04 12:14:47 2015 -0800
+@@ -104,7 +104,7 @@
+
+ private static final MethodHandle CAN_CONVERT_TO = Lookup.findOwnStatic(MethodHandles.lookup(), "canConvertTo", boolean.class, LinkerServices.class, Class.class, Object.class);
+
+- SingleDynamicMethod(String name) {
++ SingleDynamicMethod(final String name) {
+ super(name);
+ }
+
+@@ -128,22 +128,22 @@
+ abstract MethodHandle getTarget(MethodHandles.Lookup lookup);
+
+ @Override
+- MethodHandle getInvocation(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices) {
++ MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) {
+ return getInvocation(getTarget(callSiteDescriptor.getLookup()), callSiteDescriptor.getMethodType(),
+ linkerServices);
+ }
+
+ @Override
+- SingleDynamicMethod getMethodForExactParamTypes(String paramTypes) {
++ SingleDynamicMethod getMethodForExactParamTypes(final String paramTypes) {
+ return typeMatchesDescription(paramTypes, getMethodType()) ? this : null;
+ }
+
+ @Override
+- boolean contains(SingleDynamicMethod method) {
++ boolean contains(final SingleDynamicMethod method) {
+ return getMethodType().parameterList().equals(method.getMethodType().parameterList());
+ }
+
+- static String getMethodNameWithSignature(MethodType type, String methodName) {
++ static String getMethodNameWithSignature(final MethodType type, final String methodName) {
+ final String typeStr = type.toString();
+ final int retTypeIndex = typeStr.lastIndexOf(')') + 1;
+ int secondParamIndex = typeStr.indexOf(',') + 1;
+@@ -156,13 +156,15 @@
+ /**
+ * Given a method handle and a call site type, adapts the method handle to the call site type. Performs type
+ * conversions as needed using the specified linker services, and in case that the method handle is a vararg
+- * collector, matches it to the arity of the call site.
++ * collector, matches it to the arity of the call site. The type of the return value is only changed if it can be
++ * converted using a conversion that loses neither precision nor magnitude, see
++ * {@link LinkerServices#asTypeLosslessReturn(MethodHandle, MethodType)}.
+ * @param target the method handle to adapt
+ * @param callSiteType the type of the call site
+ * @param linkerServices the linker services used for type conversions
+ * @return the adapted method handle.
+ */
+- static MethodHandle getInvocation(MethodHandle target, MethodType callSiteType, LinkerServices linkerServices) {
++ static MethodHandle getInvocation(final MethodHandle target, final MethodType callSiteType, final LinkerServices linkerServices) {
+ final MethodType methodType = target.type();
+ final int paramsLen = methodType.parameterCount();
+ final boolean varArgs = target.isVarargsCollector();
+@@ -264,7 +266,7 @@
+ }
+
+ @SuppressWarnings("unused")
+- private static boolean canConvertTo(final LinkerServices linkerServices, Class<?> to, Object obj) {
++ private static boolean canConvertTo(final LinkerServices linkerServices, final Class<?> to, final Object obj) {
+ return obj == null ? false : linkerServices.canConvert(obj.getClass(), to);
+ }
+
+@@ -277,7 +279,7 @@
+ * @param parameterCount the total number of arguments in the new method handle
+ * @return a collecting method handle
+ */
+- static MethodHandle collectArguments(MethodHandle target, final int parameterCount) {
++ static MethodHandle collectArguments(final MethodHandle target, final int parameterCount) {
+ final MethodType methodType = target.type();
+ final int fixParamsLen = methodType.parameterCount() - 1;
+ final Class<?> arrayType = methodType.parameterType(fixParamsLen);
+@@ -286,10 +288,10 @@
+
+ private static MethodHandle createConvertingInvocation(final MethodHandle sizedMethod,
+ final LinkerServices linkerServices, final MethodType callSiteType) {
+- return linkerServices.asType(sizedMethod, callSiteType);
++ return linkerServices.asTypeLosslessReturn(sizedMethod, callSiteType);
+ }
+
+- private static boolean typeMatchesDescription(String paramTypes, MethodType type) {
++ private static boolean typeMatchesDescription(final String paramTypes, final MethodType type) {
+ final StringTokenizer tok = new StringTokenizer(paramTypes, ", ");
+ for(int i = 1; i < type.parameterCount(); ++i) { // i = 1 as we ignore the receiver
+ if(!(tok.hasMoreTokens() && typeNameMatches(tok.nextToken(), type.parameterType(i)))) {
+@@ -299,7 +301,7 @@
+ return !tok.hasMoreTokens();
+ }
+
+- private static boolean typeNameMatches(String typeName, Class<?> type) {
++ private static boolean typeNameMatches(final String typeName, final Class<?> type) {
+ return typeName.equals(typeName.indexOf('.') == -1 ? type.getSimpleName() : type.getCanonicalName());
+ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/beans/StaticClass.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/StaticClass.java Wed Feb 04 12:14:47 2015 -0800
+@@ -96,7 +96,7 @@
+ public class StaticClass implements Serializable {
+ private static final ClassValue<StaticClass> staticClasses = new ClassValue<StaticClass>() {
+ @Override
+- protected StaticClass computeValue(Class<?> type) {
++ protected StaticClass computeValue(final Class<?> type) {
+ return new StaticClass(type);
+ }
+ };
+@@ -105,7 +105,7 @@
+
+ private final Class<?> clazz;
+
+- /*private*/ StaticClass(Class<?> clazz) {
++ /*private*/ StaticClass(final Class<?> clazz) {
+ clazz.getClass(); // NPE check
+ this.clazz = clazz;
+ }
+@@ -115,7 +115,7 @@
+ * @param clazz the class for which the static facet is requested.
+ * @return the {@link StaticClass} instance representing the specified class.
+ */
+- public static StaticClass forClass(Class<?> clazz) {
++ public static StaticClass forClass(final Class<?> clazz) {
+ return staticClasses.get(clazz);
+ }
+
+--- ./nashorn/src/jdk/internal/dynalink/beans/StaticClassIntrospector.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/StaticClassIntrospector.java Wed Feb 04 12:14:47 2015 -0800
+@@ -90,14 +90,14 @@
+ import java.util.Map;
+
+ class StaticClassIntrospector extends FacetIntrospector {
+- StaticClassIntrospector(Class<?> clazz) {
++ StaticClassIntrospector(final Class<?> clazz) {
+ super(clazz, false);
+ }
+
+ @Override
+ Map<String, MethodHandle> getInnerClassGetters() {
+ final Map<String, MethodHandle> map = new HashMap<>();
+- for(Class<?> innerClass: membersLookup.getInnerClasses()) {
++ for(final Class<?> innerClass: membersLookup.getInnerClasses()) {
+ map.put(innerClass.getSimpleName(), editMethodHandle(MethodHandles.constant(StaticClass.class,
+ StaticClass.forClass(innerClass))));
+ }
+@@ -105,15 +105,15 @@
+ }
+
+ @Override
+- MethodHandle editMethodHandle(MethodHandle mh) {
++ MethodHandle editMethodHandle(final MethodHandle mh) {
+ return editStaticMethodHandle(mh);
+ }
+
+- static MethodHandle editStaticMethodHandle(MethodHandle mh) {
++ static MethodHandle editStaticMethodHandle(final MethodHandle mh) {
+ return dropReceiver(mh, Object.class);
+ }
+
+- static MethodHandle editConstructorMethodHandle(MethodHandle cmh) {
++ static MethodHandle editConstructorMethodHandle(final MethodHandle cmh) {
+ return dropReceiver(cmh, StaticClass.class);
+ }
+
+--- ./nashorn/src/jdk/internal/dynalink/beans/StaticClassLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/beans/StaticClassLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -104,7 +104,7 @@
+ class StaticClassLinker implements TypeBasedGuardingDynamicLinker {
+ private static final ClassValue<SingleClassStaticsLinker> linkers = new ClassValue<SingleClassStaticsLinker>() {
+ @Override
+- protected SingleClassStaticsLinker computeValue(Class<?> clazz) {
++ protected SingleClassStaticsLinker computeValue(final Class<?> clazz) {
+ return new SingleClassStaticsLinker(clazz);
+ }
+ };
+@@ -112,7 +112,7 @@
+ private static class SingleClassStaticsLinker extends AbstractJavaLinker {
+ private final DynamicMethod constructor;
+
+- SingleClassStaticsLinker(Class<?> clazz) {
++ SingleClassStaticsLinker(final Class<?> clazz) {
+ super(clazz, IS_CLASS.bindTo(clazz));
+ // Map "staticClassObject.class" to StaticClass.getRepresentedClass(). Some adventurous soul could subclass
+ // StaticClass, so we use INSTANCE_OF validation instead of EXACT_CLASS.
+@@ -126,7 +126,7 @@
+ * @return a dynamic method containing all overloads of a class' public constructor. If the class has no public
+ * constructors, returns null.
+ */
+- private static DynamicMethod createConstructorMethod(Class<?> clazz) {
++ private static DynamicMethod createConstructorMethod(final Class<?> clazz) {
+ if(clazz.isArray()) {
+ final MethodHandle boundArrayCtor = ARRAY_CTOR.bindTo(clazz.getComponentType());
+ return new SimpleDynamicMethod(StaticClassIntrospector.editConstructorMethodHandle(
+@@ -144,7 +144,7 @@
+ }
+
+ @Override
+- public GuardedInvocation getGuardedInvocation(LinkRequest request, LinkerServices linkerServices)
++ public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices)
+ throws Exception {
+ final GuardedInvocation gi = super.getGuardedInvocation(request, linkerServices);
+ if(gi != null) {
+@@ -160,22 +160,31 @@
+ }
+ return null;
+ }
++
++ @Override
++ SingleDynamicMethod getConstructorMethod(final String signature) {
++ return constructor != null? constructor.getMethodForExactParamTypes(signature) : null;
++ }
+ }
+
+- static Collection<String> getReadableStaticPropertyNames(Class<?> clazz) {
++ static Object getConstructorMethod(final Class<?> clazz, final String signature) {
++ return linkers.get(clazz).getConstructorMethod(signature);
++ }
++
++ static Collection<String> getReadableStaticPropertyNames(final Class<?> clazz) {
+ return linkers.get(clazz).getReadablePropertyNames();
+ }
+
+- static Collection<String> getWritableStaticPropertyNames(Class<?> clazz) {
++ static Collection<String> getWritableStaticPropertyNames(final Class<?> clazz) {
+ return linkers.get(clazz).getWritablePropertyNames();
+ }
+
+- static Collection<String> getStaticMethodNames(Class<?> clazz) {
++ static Collection<String> getStaticMethodNames(final Class<?> clazz) {
+ return linkers.get(clazz).getMethodNames();
+ }
+
+ @Override
+- public GuardedInvocation getGuardedInvocation(LinkRequest request, LinkerServices linkerServices) throws Exception {
++ public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception {
+ final Object receiver = request.getReceiver();
+ if(receiver instanceof StaticClass) {
+ return linkers.get(((StaticClass)receiver).getRepresentedClass()).getGuardedInvocation(request,
+@@ -185,7 +194,7 @@
+ }
+
+ @Override
+- public boolean canLinkType(Class<?> type) {
++ public boolean canLinkType(final Class<?> type) {
+ return type == StaticClass.class;
+ }
+
+@@ -201,7 +210,7 @@
+ }
+
+ @SuppressWarnings("unused")
+- private static boolean isClass(Class<?> clazz, Object obj) {
++ private static boolean isClass(final Class<?> clazz, final Object obj) {
+ return obj instanceof StaticClass && ((StaticClass)obj).getRepresentedClass() == clazz;
+ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/linker/GuardedInvocation.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/linker/GuardedInvocation.java Wed Feb 04 12:14:47 2015 -0800
+@@ -83,6 +83,8 @@
+
+ package jdk.internal.dynalink.linker;
+
++import static jdk.nashorn.internal.lookup.Lookup.MH;
++
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+ import java.lang.invoke.MethodType;
+@@ -104,7 +106,18 @@
+ public class GuardedInvocation {
+ private final MethodHandle invocation;
+ private final MethodHandle guard;
+- private final SwitchPoint switchPoint;
++ private final Class<? extends Throwable> exception;
++ private final SwitchPoint[] switchPoints;
++
++ /**
++ * Creates a new guarded invocation. This invocation is unconditional as it has no invalidations.
++ *
++ * @param invocation the method handle representing the invocation. Must not be null.
++ * @throws NullPointerException if invocation is null.
++ */
++ public GuardedInvocation(final MethodHandle invocation) {
++ this(invocation, null, (SwitchPoint)null, null);
++ }
+
+ /**
+ * Creates a new guarded invocation.
+@@ -115,8 +128,19 @@
+ * an unconditional invocation, although that is unusual.
+ * @throws NullPointerException if invocation is null.
+ */
+- public GuardedInvocation(MethodHandle invocation, MethodHandle guard) {
+- this(invocation, guard, null);
++ public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard) {
++ this(invocation, guard, (SwitchPoint)null, null);
++ }
++
++ /**
++ * Creates a new guarded invocation.
++ *
++ * @param invocation the method handle representing the invocation. Must not be null.
++ * @param switchPoint the optional switch point that can be used to invalidate this linkage.
++ * @throws NullPointerException if invocation is null.
++ */
++ public GuardedInvocation(final MethodHandle invocation, final SwitchPoint switchPoint) {
++ this(invocation, null, switchPoint, null);
+ }
+
+ /**
+@@ -129,26 +153,50 @@
+ * @param switchPoint the optional switch point that can be used to invalidate this linkage.
+ * @throws NullPointerException if invocation is null.
+ */
+- public GuardedInvocation(MethodHandle invocation, MethodHandle guard, SwitchPoint switchPoint) {
+- invocation.getClass(); // NPE check
+- this.invocation = invocation;
+- this.guard = guard;
+- this.switchPoint = switchPoint;
++ public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard, final SwitchPoint switchPoint) {
++ this(invocation, guard, switchPoint, null);
+ }
+
+ /**
+ * Creates a new guarded invocation.
+ *
+ * @param invocation the method handle representing the invocation. Must not be null.
+- * @param switchPoint the optional switch point that can be used to invalidate this linkage.
+ * @param guard the method handle representing the guard. Must have the same method type as the invocation, except
+ * it must return boolean. For some useful guards, check out the {@link Guards} class. It can be null. If both it
+ * and the switch point are null, this represents an unconditional invocation, which is legal but unusual.
++ * @param switchPoint the optional switch point that can be used to invalidate this linkage.
++ * @param exception the optional exception type that is expected to be thrown by the invocation and that also
++ * invalidates the linkage.
+ * @throws NullPointerException if invocation is null.
+ */
+- public GuardedInvocation(MethodHandle invocation, SwitchPoint switchPoint, MethodHandle guard) {
+- this(invocation, guard, switchPoint);
++ public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard, final SwitchPoint switchPoint, final Class<? extends Throwable> exception) {
++ invocation.getClass(); // NPE check
++ this.invocation = invocation;
++ this.guard = guard;
++ this.switchPoints = switchPoint == null ? null : new SwitchPoint[] { switchPoint };
++ this.exception = exception;
+ }
++
++ /**
++ * Creates a new guarded invocation
++ *
++ * @param invocation the method handle representing the invocation. Must not be null.
++ * @param guard the method handle representing the guard. Must have the same method type as the invocation, except
++ * it must return boolean. For some useful guards, check out the {@link Guards} class. It can be null. If both it
++ * and the switch point are null, this represents an unconditional invocation, which is legal but unusual.
++ * @param switchPoints the optional switch points that can be used to invalidate this linkage.
++ * @param exception the optional exception type that is expected to be thrown by the invocation and that also
++ * invalidates the linkage.
++ * @throws NullPointerException if invocation is null.
++ */
++ public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard, final SwitchPoint[] switchPoints, final Class<? extends Throwable> exception) {
++ invocation.getClass(); // NPE check
++ this.invocation = invocation;
++ this.guard = guard;
++ this.switchPoints = switchPoints == null ? null : switchPoints.clone();
++ this.exception = exception;
++ }
++
+ /**
+ * Returns the invocation method handle.
+ *
+@@ -172,8 +220,17 @@
+ *
+ * @return the switch point that can be used to invalidate the invocation handle. Can be null.
+ */
+- public SwitchPoint getSwitchPoint() {
+- return switchPoint;
++ public SwitchPoint[] getSwitchPoints() {
++ return switchPoints == null ? null : switchPoints.clone();
++ }
++
++ /**
++ * Returns the exception type that if thrown should be used to invalidate the linkage.
++ *
++ * @return the exception type that if thrown should be used to invalidate the linkage. Can be null.
++ */
++ public Class<? extends Throwable> getException() {
++ return exception;
+ }
+
+ /**
+@@ -181,7 +238,15 @@
+ * @return true if and only if this guarded invocation has a switchpoint, and that switchpoint has been invalidated.
+ */
+ public boolean hasBeenInvalidated() {
+- return switchPoint != null && switchPoint.hasBeenInvalidated();
++ if (switchPoints == null) {
++ return false;
++ }
++ for (final SwitchPoint sp : switchPoints) {
++ if (sp.hasBeenInvalidated()) {
++ return true;
++ }
++ }
++ return false;
+ }
+
+ /**
+@@ -191,9 +256,9 @@
+ * @param type the asserted type
+ * @throws WrongMethodTypeException if the invocation and the guard are not of the expected method type.
+ */
+- public void assertType(MethodType type) {
++ public void assertType(final MethodType type) {
+ assertType(invocation, type);
+- if(guard != null) {
++ if (guard != null) {
+ assertType(guard, type.changeReturnType(Boolean.TYPE));
+ }
+ }
+@@ -205,12 +270,34 @@
+ * @param newGuard the new guard
+ * @return a new guarded invocation with the replaced methods and the same switch point as this invocation.
+ */
+- public GuardedInvocation replaceMethods(MethodHandle newInvocation, MethodHandle newGuard) {
+- return new GuardedInvocation(newInvocation, newGuard, switchPoint);
++ public GuardedInvocation replaceMethods(final MethodHandle newInvocation, final MethodHandle newGuard) {
++ return new GuardedInvocation(newInvocation, newGuard, switchPoints, exception);
+ }
+
+- private GuardedInvocation replaceMethodsOrThis(MethodHandle newInvocation, MethodHandle newGuard) {
+- if(newInvocation == invocation && newGuard == guard) {
++ /**
++ * Add a switchpoint to this guarded invocation
++ * @param newSwitchPoint new switchpoint, or null for nop
++ * @return new guarded invocation with the extra switchpoint
++ */
++ public GuardedInvocation addSwitchPoint(final SwitchPoint newSwitchPoint) {
++ if (newSwitchPoint == null) {
++ return this;
++ }
++
++ final SwitchPoint[] newSwitchPoints;
++ if (switchPoints != null) {
++ newSwitchPoints = new SwitchPoint[switchPoints.length + 1];
++ System.arraycopy(switchPoints, 0, newSwitchPoints, 0, switchPoints.length);
++ newSwitchPoints[switchPoints.length] = newSwitchPoint;
++ } else {
++ newSwitchPoints = new SwitchPoint[] { newSwitchPoint };
++ }
++
++ return new GuardedInvocation(invocation, guard, newSwitchPoints, exception);
++ }
++
++ private GuardedInvocation replaceMethodsOrThis(final MethodHandle newInvocation, final MethodHandle newGuard) {
++ if (newInvocation == invocation && newGuard == guard) {
+ return this;
+ }
+ return replaceMethods(newInvocation, newGuard);
+@@ -223,7 +310,7 @@
+ * @param newType the new type of the invocation.
+ * @return a guarded invocation with the new type applied to it.
+ */
+- public GuardedInvocation asType(MethodType newType) {
++ public GuardedInvocation asType(final MethodType newType) {
+ return replaceMethodsOrThis(invocation.asType(newType), guard == null ? null : Guards.asType(guard, newType));
+ }
+
+@@ -235,19 +322,33 @@
+ * @param newType the new type of the invocation.
+ * @return a guarded invocation with the new type applied to it.
+ */
+- public GuardedInvocation asType(LinkerServices linkerServices, MethodType newType) {
++ public GuardedInvocation asType(final LinkerServices linkerServices, final MethodType newType) {
+ return replaceMethodsOrThis(linkerServices.asType(invocation, newType), guard == null ? null :
+ Guards.asType(linkerServices, guard, newType));
+ }
+
+ /**
++ * Changes the type of the invocation, as if {@link LinkerServices#asTypeLosslessReturn(MethodHandle, MethodType)} was
++ * applied to its invocation and {@link LinkerServices#asType(MethodHandle, MethodType)} applied to its guard, if it
++ * has one (with return type changed to boolean, and parameter count potentially truncated for the guard). If the
++ * invocation doesn't change its type, returns this object.
++ * @param linkerServices the linker services to use for the conversion
++ * @param newType the new type of the invocation.
++ * @return a guarded invocation with the new type applied to it.
++ */
++ public GuardedInvocation asTypeSafeReturn(final LinkerServices linkerServices, final MethodType newType) {
++ return replaceMethodsOrThis(linkerServices.asTypeLosslessReturn(invocation, newType), guard == null ? null :
++ Guards.asType(linkerServices, guard, newType));
++ }
++
++ /**
+ * Changes the type of the invocation, as if {@link MethodHandle#asType(MethodType)} was applied to its invocation
+ * and its guard, if it has one (with return type changed to boolean for guard). If the invocation already is of the
+ * required type, returns this object.
+ * @param desc a call descriptor whose method type is adapted.
+ * @return a guarded invocation with the new type applied to it.
+ */
+- public GuardedInvocation asType(CallSiteDescriptor desc) {
++ public GuardedInvocation asType(final CallSiteDescriptor desc) {
+ return asType(desc.getMethodType());
+ }
+
+@@ -257,7 +358,7 @@
+ * @param filters the argument filters
+ * @return a filtered invocation
+ */
+- public GuardedInvocation filterArguments(int pos, MethodHandle... filters) {
++ public GuardedInvocation filterArguments(final int pos, final MethodHandle... filters) {
+ return replaceMethods(MethodHandles.filterArguments(invocation, pos, filters), guard == null ? null :
+ MethodHandles.filterArguments(guard, pos, filters));
+ }
+@@ -268,7 +369,7 @@
+ * @param valueTypes the types of the values being dropped
+ * @return an invocation that drops arguments
+ */
+- public GuardedInvocation dropArguments(int pos, List<Class<?>> valueTypes) {
++ public GuardedInvocation dropArguments(final int pos, final List<Class<?>> valueTypes) {
+ return replaceMethods(MethodHandles.dropArguments(invocation, pos, valueTypes), guard == null ? null :
+ MethodHandles.dropArguments(guard, pos, valueTypes));
+ }
+@@ -279,7 +380,7 @@
+ * @param valueTypes the types of the values being dropped
+ * @return an invocation that drops arguments
+ */
+- public GuardedInvocation dropArguments(int pos, Class<?>... valueTypes) {
++ public GuardedInvocation dropArguments(final int pos, final Class<?>... valueTypes) {
+ return replaceMethods(MethodHandles.dropArguments(invocation, pos, valueTypes), guard == null ? null :
+ MethodHandles.dropArguments(guard, pos, valueTypes));
+ }
+@@ -290,23 +391,50 @@
+ * @param fallback the fallback method handle in case switchpoint is invalidated or guard returns false.
+ * @return a composite method handle.
+ */
+- public MethodHandle compose(MethodHandle fallback) {
+- return compose(fallback, fallback);
++ public MethodHandle compose(final MethodHandle fallback) {
++ return compose(fallback, fallback, fallback);
+ }
+
+ /**
+ * Composes the invocation, switchpoint, and the guard into a composite method handle that knows how to fall back.
+ * @param switchpointFallback the fallback method handle in case switchpoint is invalidated.
+ * @param guardFallback the fallback method handle in case guard returns false.
++ * @param catchFallback the fallback method in case the exception handler triggers
+ * @return a composite method handle.
+ */
+- public MethodHandle compose(MethodHandle switchpointFallback, MethodHandle guardFallback) {
++ public MethodHandle compose(final MethodHandle guardFallback, final MethodHandle switchpointFallback, final MethodHandle catchFallback) {
+ final MethodHandle guarded =
+- guard == null ? invocation : MethodHandles.guardWithTest(guard, invocation, guardFallback);
+- return switchPoint == null ? guarded : switchPoint.guardWithTest(guarded, switchpointFallback);
++ guard == null ?
++ invocation :
++ MethodHandles.guardWithTest(
++ guard,
++ invocation,
++ guardFallback);
++
++ final MethodHandle catchGuarded =
++ exception == null ?
++ guarded :
++ MH.catchException(
++ guarded,
++ exception,
++ MethodHandles.dropArguments(
++ catchFallback,
++ 0,
++ exception));
++
++ if (switchPoints == null) {
++ return catchGuarded;
++ }
++
++ MethodHandle spGuarded = catchGuarded;
++ for (final SwitchPoint sp : switchPoints) {
++ spGuarded = sp.guardWithTest(spGuarded, switchpointFallback);
++ }
++
++ return spGuarded;
+ }
+
+- private static void assertType(MethodHandle mh, MethodType type) {
++ private static void assertType(final MethodHandle mh, final MethodType type) {
+ if(!mh.type().equals(type)) {
+ throw new WrongMethodTypeException("Expected type: " + type + " actual type: " + mh.type());
+ }
+--- ./nashorn/src/jdk/internal/dynalink/linker/GuardedTypeConversion.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/linker/GuardedTypeConversion.java Wed Feb 04 12:14:47 2015 -0800
+@@ -83,19 +83,35 @@
+
+ package jdk.internal.dynalink.linker;
+
++/**
++ * Guarded type conversion
++ */
+ public class GuardedTypeConversion {
+ private final GuardedInvocation conversionInvocation;
+ private final boolean cacheable;
+
++ /**
++ * Constructor
++ * @param conversionInvocation guarded invocation for this type conversion
++ * @param cacheable is this invocation cacheable
++ */
+ public GuardedTypeConversion(final GuardedInvocation conversionInvocation, final boolean cacheable) {
+ this.conversionInvocation = conversionInvocation;
+ this.cacheable = cacheable;
+ }
+
++ /**
++ * Get the invocation
++ * @return invocation
++ */
+ public GuardedInvocation getConversionInvocation() {
+ return conversionInvocation;
+ }
+
++ /**
++ * Check if invocation is cacheable
++ * @return true if cachable, false otherwise
++ */
+ public boolean isCacheable() {
+ return cacheable;
+ }
+--- ./nashorn/src/jdk/internal/dynalink/linker/GuardingDynamicLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/linker/GuardingDynamicLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -101,10 +101,16 @@
+ * @return a guarded invocation with a method handle suitable for the arguments, as well as a guard condition that
+ * if fails should trigger relinking. Must return null if it can't resolve the invocation. If the returned
+ * invocation is unconditional (which is actually quite rare), the guard in the return value can be null. The
+- * invocation can also have a switch point for asynchronous invalidation of the linkage. If the linker does not
+- * recognize any native language runtime contexts in arguments, or does recognize its own, but receives a call site
+- * descriptor without its recognized context in the arguments, it should invoke
+- * {@link LinkRequest#withoutRuntimeContext()} and link for that.
++ * invocation can also have a switch point for asynchronous invalidation of the linkage, as well as a
++ * {@link Throwable} subclass that describes an expected exception condition that also triggers relinking (often it
++ * is faster to rely on an infrequent but expected {@link ClassCastException} than on an always evaluated
++ * {@code instanceof} guard). If the linker does not recognize any native language runtime contexts in arguments, or
++ * does recognize its own, but receives a call site descriptor without its recognized context in the arguments, it
++ * should invoke {@link LinkRequest#withoutRuntimeContext()} and link for that. While the linker must produce an
++ * invocation with parameter types matching those in the call site descriptor of the link request, it should not try
++ * to match the return type expected at the call site except when it can do it with only the conversions that lose
++ * neither precision nor magnitude, see {@link LinkerServices#asTypeLosslessReturn(java.lang.invoke.MethodHandle,
++ * java.lang.invoke.MethodType)}.
+ * @throws Exception if the operation fails for whatever reason
+ */
+ public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices)
+--- ./nashorn/src/jdk/internal/dynalink/linker/LinkRequest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/linker/LinkRequest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -101,6 +101,17 @@
+ public CallSiteDescriptor getCallSiteDescriptor();
+
+ /**
++ * Returns the call site token for the call site being linked. This token is an opaque object that is guaranteed to
++ * have different identity for different call sites, and is also guaranteed to not become weakly reachable before
++ * the call site does and to become weakly reachable some time after the call site does. This makes it ideal as a
++ * candidate for a key in a weak hash map in which a linker might want to keep per-call site linking state (usually
++ * profiling information).
++ *
++ * @return the call site token for the call site being linked.
++ */
++ public Object getCallSiteToken();
++
++ /**
+ * Returns the arguments for the invocation being linked. The returned array is a clone; modifications to it won't
+ * affect the arguments in this request.
+ *
+@@ -116,6 +127,17 @@
+ public Object getReceiver();
+
+ /**
++ * Returns the number of times this callsite has been linked/relinked. This can be useful if you want to
++ * change e.g. exception based relinking to guard based relinking. It's probably not a good idea to keep,
++ * for example, expensive exception throwing relinkage based on failed type checks/ClassCastException in
++ * a nested callsite tree where the exception is thrown repeatedly for the common case. There it would be
++ * much more performant to use exact type guards instead.
++ *
++ * @return link count for call site
++ */
++ public int getLinkCount();
++
++ /**
+ * Returns true if the call site is considered unstable, that is, it has been relinked more times than was
+ * specified in {@link DynamicLinkerFactory#setUnstableRelinkThreshold(int)}. Linkers should use this as a
+ * hint to prefer producing linkage that is more stable (its guard fails less frequently), even if that assumption
+--- ./nashorn/src/jdk/internal/dynalink/linker/LinkerServices.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/linker/LinkerServices.java Wed Feb 04 12:14:47 2015 -0800
+@@ -87,7 +87,9 @@
+ import java.lang.invoke.MethodHandles;
+ import java.lang.invoke.MethodType;
+ import jdk.internal.dynalink.DynamicLinker;
++import jdk.internal.dynalink.DynamicLinkerFactory;
+ import jdk.internal.dynalink.linker.ConversionComparator.Comparison;
++import jdk.internal.dynalink.support.TypeUtilities;
+
+ /**
+ * Interface for services provided to {@link GuardingDynamicLinker} instances by the {@link DynamicLinker} that owns
+@@ -103,18 +105,34 @@
+ * parameters. It will apply {@link MethodHandle#asType(MethodType)} for all primitive-to-primitive,
+ * wrapper-to-primitive, primitive-to-wrapper conversions as well as for all upcasts. For all other conversions,
+ * it'll insert {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with composite filters
+- * provided by {@link GuardingTypeConverterFactory} implementations. It doesn't use language-specific conversions on
+- * the return type.
++ * provided by {@link GuardingTypeConverterFactory} implementations.
+ *
+ * @param handle target method handle
+ * @param fromType the types of source arguments
+- * @return a method handle that is a suitable combination of {@link MethodHandle#asType(MethodType)} and
+- * {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with
+- * {@link GuardingTypeConverterFactory} produced type converters as filters.
++ * @return a method handle that is a suitable combination of {@link MethodHandle#asType(MethodType)},
++ * {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)}, and
++ * {@link MethodHandles#filterReturnValue(MethodHandle, MethodHandle)} with
++ * {@link GuardingTypeConverterFactory}-produced type converters as filters.
+ */
+ public MethodHandle asType(MethodHandle handle, MethodType fromType);
+
+ /**
++ * Similar to {@link #asType(MethodHandle, MethodType)} except it only converts the return type of the method handle
++ * when it can be done using a conversion that loses neither precision nor magnitude, otherwise it leaves it
++ * unchanged. The idea is that other conversions should not be performed by individual linkers, but instead the
++ * {@link DynamicLinkerFactory#setPrelinkFilter(jdk.internal.dynalink.GuardedInvocationFilter) pre-link filter of
++ * the dynamic linker} should implement the strategy of dealing with potentially lossy return type conversions in a
++ * manner specific to the language runtime.
++ *
++ * @param handle target method handle
++ * @param fromType the types of source arguments
++ * @return a method handle that is a suitable combination of {@link MethodHandle#asType(MethodType)}, and
++ * {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with
++ * {@link GuardingTypeConverterFactory}-produced type converters as filters.
++ */
++ public MethodHandle asTypeLosslessReturn(MethodHandle handle, MethodType fromType);
++
++ /**
+ * Given a source and target type, returns a method handle that converts between them. Never returns null; in worst
+ * case it will return an identity conversion (that might fail for some values at runtime). You rarely need to use
+ * this method directly; you should mostly rely on {@link #asType(MethodHandle, MethodType)} instead. You really
+@@ -161,4 +179,23 @@
+ * conversion.
+ */
+ public Comparison compareConversion(Class<?> sourceType, Class<?> targetType1, Class<?> targetType2);
++
++ /**
++ * If we could just use Java 8 constructs, then {@code asTypeSafeReturn} would be a method with default
++ * implementation. Since we can't do that, we extract common default implementations into this static class.
++ */
++ public static class Implementation {
++ /**
++ * Default implementation for {@link LinkerServices#asTypeLosslessReturn(MethodHandle, MethodType)}.
++ * @param linkerServices the linker services that delegates to this implementation
++ * @param handle the passed handle
++ * @param fromType the passed type
++ * @return the converted method handle, as per the {@code asTypeSafeReturn} semantics.
++ */
++ public static MethodHandle asTypeLosslessReturn(final LinkerServices linkerServices, final MethodHandle handle, final MethodType fromType) {
++ final Class<?> handleReturnType = handle.type().returnType();
++ return linkerServices.asType(handle, TypeUtilities.isConvertibleWithoutLoss(handleReturnType, fromType.returnType()) ?
++ fromType : fromType.changeReturnType(handleReturnType));
++ }
++ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/internal/dynalink/linker/MethodTypeConversionStrategy.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,100 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.
++ */
++
++/*
++ * This file is available under and governed by the GNU General Public
++ * License version 2 only, as published by the Free Software Foundation.
++ * However, the following notice accompanied the original version of this
++ * file, and Oracle licenses the original version of this file under the BSD
++ * license:
++ */
++/*
++ Copyright 2014 Attila Szegedi
++
++ Licensed under both the Apache License, Version 2.0 (the "Apache License")
++ and the BSD License (the "BSD License"), with licensee being free to
++ choose either of the two at their discretion.
++
++ You may not use this file except in compliance with either the Apache
++ License or the BSD License.
++
++ If you choose to use this file in compliance with the Apache License, the
++ following notice applies to you:
++
++ You may obtain a copy of the Apache License at
++
++ 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,
++ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
++ implied. See the License for the specific language governing
++ permissions and limitations under the License.
++
++ If you choose to use this file in compliance with the BSD License, the
++ following notice applies to you:
++
++ Redistribution and use in source and binary forms, with or without
++ modification, are permitted provided that the following conditions are
++ met:
++ * Redistributions of source code must retain the above copyright
++ notice, this list of conditions and the following disclaimer.
++ * Redistributions in binary form must reproduce the above copyright
++ notice, this list of conditions and the following disclaimer in the
++ documentation and/or other materials provided with the distribution.
++ * Neither the name of the copyright holder nor the names of
++ contributors may be used to endorse or promote products derived from
++ this software without specific prior written permission.
++
++ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
++ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
++ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
++ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
++ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
++ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++*/
++
++package jdk.internal.dynalink.linker;
++
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodType;
++
++/**
++ * Interface for objects representing a strategy for converting a method handle to a new type.
++ */
++public interface MethodTypeConversionStrategy {
++ /**
++ * Converts a method handle to a new type.
++ * @param target target method handle
++ * @param newType new type
++ * @return target converted to the new type.
++ */
++ public MethodHandle asType(final MethodHandle target, final MethodType newType);
++}
+--- ./nashorn/src/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -106,7 +106,7 @@
+ }
+
+ @Override
+- public boolean equals(Object obj) {
++ public boolean equals(final Object obj) {
+ return obj instanceof CallSiteDescriptor && equals((CallSiteDescriptor)obj);
+ }
+
+@@ -115,7 +115,7 @@
+ * @param csd the other call site descriptor.
+ * @return true if they are equal.
+ */
+- public boolean equals(CallSiteDescriptor csd) {
++ public boolean equals(final CallSiteDescriptor csd) {
+ if(csd == null) {
+ return false;
+ }
+@@ -165,7 +165,7 @@
+ return l + c - 1;
+ }
+
+- private StringBuilder appendName(StringBuilder b) {
++ private StringBuilder appendName(final StringBuilder b) {
+ b.append(getNameToken(0));
+ final int c = getNameTokenCount();
+ for(int i = 1; i < c; ++i) {
+@@ -174,7 +174,7 @@
+ return b;
+ }
+
+- private static boolean lookupsEqual(Lookup l1, Lookup l2) {
++ private static boolean lookupsEqual(final Lookup l1, final Lookup l2) {
+ if(l1 == l2) {
+ return true;
+ }
+--- ./nashorn/src/jdk/internal/dynalink/support/AbstractRelinkableCallSite.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/AbstractRelinkableCallSite.java Wed Feb 04 12:14:47 2015 -0800
+@@ -100,7 +100,7 @@
+ * Creates a new relinkable call site.
+ * @param descriptor the descriptor for this call site
+ */
+- protected AbstractRelinkableCallSite(CallSiteDescriptor descriptor) {
++ protected AbstractRelinkableCallSite(final CallSiteDescriptor descriptor) {
+ super(descriptor.getMethodType());
+ this.descriptor = descriptor;
+ }
+@@ -111,7 +111,7 @@
+ }
+
+ @Override
+- public void initialize(MethodHandle relinkAndInvoke) {
++ public void initialize(final MethodHandle relinkAndInvoke) {
+ setTarget(relinkAndInvoke);
+ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/support/AutoDiscovery.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/AutoDiscovery.java Wed Feb 04 12:14:47 2015 -0800
+@@ -116,14 +116,14 @@
+ * @return a list of guarding dynamic linkers available through the specified class loader. Can be zero-length list
+ * but not null.
+ */
+- public static List<GuardingDynamicLinker> loadLinkers(ClassLoader cl) {
++ public static List<GuardingDynamicLinker> loadLinkers(final ClassLoader cl) {
+ return getLinkers(ServiceLoader.load(GuardingDynamicLinker.class, cl));
+ }
+
+ /**
+ * I can't believe there's no Collections API for making a List given an Iterator...
+ */
+- private static <T> List<T> getLinkers(ServiceLoader<T> loader) {
++ private static <T> List<T> getLinkers(final ServiceLoader<T> loader) {
+ final List<T> list = new LinkedList<>();
+ for(final T linker: loader) {
+ list.add(linker);
+--- ./nashorn/src/jdk/internal/dynalink/support/BottomGuardingDynamicLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/BottomGuardingDynamicLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -105,12 +105,12 @@
+ }
+
+ @Override
+- public boolean canLinkType(Class<?> type) {
++ public boolean canLinkType(final Class<?> type) {
+ return false;
+ }
+
+ @Override
+- public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) {
++ public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) {
+ return null;
+ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/support/CallSiteDescriptorFactory.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/CallSiteDescriptorFactory.java Wed Feb 04 12:14:47 2015 -0800
+@@ -86,6 +86,7 @@
+ import java.lang.invoke.MethodHandles;
+ import java.lang.invoke.MethodHandles.Lookup;
+ import java.lang.invoke.MethodType;
++import java.lang.ref.Reference;
+ import java.lang.ref.WeakReference;
+ import java.util.Arrays;
+ import java.util.Collections;
+@@ -103,7 +104,7 @@
+ * @author Attila Szegedi
+ */
+ public class CallSiteDescriptorFactory {
+- private static final WeakHashMap<CallSiteDescriptor, WeakReference<CallSiteDescriptor>> publicDescs =
++ private static final WeakHashMap<CallSiteDescriptor, Reference<CallSiteDescriptor>> publicDescs =
+ new WeakHashMap<>();
+
+
+@@ -121,7 +122,7 @@
+ * @return a call site descriptor representing the input. Note that although the method name is "create", it will
+ * in fact return a weakly-referenced canonical instance.
+ */
+- public static CallSiteDescriptor create(Lookup lookup, String name, MethodType methodType) {
++ public static CallSiteDescriptor create(final Lookup lookup, final String name, final MethodType methodType) {
+ name.getClass(); // NPE check
+ methodType.getClass(); // NPE check
+ lookup.getClass(); // NPE check
+@@ -134,19 +135,28 @@
+
+ static CallSiteDescriptor getCanonicalPublicDescriptor(final CallSiteDescriptor desc) {
+ synchronized(publicDescs) {
+- final WeakReference<CallSiteDescriptor> ref = publicDescs.get(desc);
++ final Reference<CallSiteDescriptor> ref = publicDescs.get(desc);
+ if(ref != null) {
+ final CallSiteDescriptor canonical = ref.get();
+ if(canonical != null) {
+ return canonical;
+ }
+ }
+- publicDescs.put(desc, new WeakReference<>(desc));
++ publicDescs.put(desc, createReference(desc));
+ }
+ return desc;
+ }
+
+- private static CallSiteDescriptor createPublicCallSiteDescriptor(String[] tokenizedName, MethodType methodType) {
++ /**
++ * Override this to use a different kind of references for the cache
++ * @param desc desc
++ * @return reference
++ */
++ protected static Reference<CallSiteDescriptor> createReference(final CallSiteDescriptor desc) {
++ return new WeakReference<>(desc);
++ }
++
++ private static CallSiteDescriptor createPublicCallSiteDescriptor(final String[] tokenizedName, final MethodType methodType) {
+ final int l = tokenizedName.length;
+ if(l > 0 && tokenizedName[0] == "dyn") {
+ if(l == 2) {
+@@ -158,7 +168,7 @@
+ return new DefaultCallSiteDescriptor(tokenizedName, methodType);
+ }
+
+- private static boolean isPublicLookup(Lookup lookup) {
++ private static boolean isPublicLookup(final Lookup lookup) {
+ return lookup == MethodHandles.publicLookup();
+ }
+
+@@ -169,7 +179,7 @@
+ * @param name the composite name consisting of colon-separated, possibly mangled tokens.
+ * @return an array of tokens
+ */
+- public static String[] tokenizeName(String name) {
++ public static String[] tokenizeName(final String name) {
+ final StringTokenizer tok = new StringTokenizer(name, CallSiteDescriptor.TOKEN_DELIMITER);
+ final String[] tokens = new String[tok.countTokens()];
+ for(int i = 0; i < tokens.length; ++i) {
+@@ -188,7 +198,7 @@
+ * @param desc the call site descriptor with the operation
+ * @return a list of tokens
+ */
+- public static List<String> tokenizeOperators(CallSiteDescriptor desc) {
++ public static List<String> tokenizeOperators(final CallSiteDescriptor desc) {
+ final String ops = desc.getNameToken(CallSiteDescriptor.OPERATOR);
+ final StringTokenizer tok = new StringTokenizer(ops, CallSiteDescriptor.OPERATOR_DELIMITER);
+ final int count = tok.countTokens();
+@@ -210,7 +220,7 @@
+ * @param end index of the first parameter to not remove
+ * @return a new call site descriptor with modified method type
+ */
+- public static CallSiteDescriptor dropParameterTypes(CallSiteDescriptor desc, int start, int end) {
++ public static CallSiteDescriptor dropParameterTypes(final CallSiteDescriptor desc, final int start, final int end) {
+ return desc.changeMethodType(desc.getMethodType().dropParameterTypes(start, end));
+ }
+
+@@ -222,7 +232,7 @@
+ * @param nptype the new parameter type
+ * @return a new call site descriptor with modified method type
+ */
+- public static CallSiteDescriptor changeParameterType(CallSiteDescriptor desc, int num, Class<?> nptype) {
++ public static CallSiteDescriptor changeParameterType(final CallSiteDescriptor desc, final int num, final Class<?> nptype) {
+ return desc.changeMethodType(desc.getMethodType().changeParameterType(num, nptype));
+ }
+
+@@ -233,7 +243,7 @@
+ * @param nrtype the new return type
+ * @return a new call site descriptor with modified method type
+ */
+- public static CallSiteDescriptor changeReturnType(CallSiteDescriptor desc, Class<?> nrtype) {
++ public static CallSiteDescriptor changeReturnType(final CallSiteDescriptor desc, final Class<?> nrtype) {
+ return desc.changeMethodType(desc.getMethodType().changeReturnType(nrtype));
+ }
+
+@@ -245,7 +255,7 @@
+ * @param ptypesToInsert the new types to insert
+ * @return a new call site descriptor with modified method type
+ */
+- public static CallSiteDescriptor insertParameterTypes(CallSiteDescriptor desc, int num, Class<?>... ptypesToInsert) {
++ public static CallSiteDescriptor insertParameterTypes(final CallSiteDescriptor desc, final int num, final Class<?>... ptypesToInsert) {
+ return desc.changeMethodType(desc.getMethodType().insertParameterTypes(num, ptypesToInsert));
+ }
+
+@@ -257,7 +267,7 @@
+ * @param ptypesToInsert the new types to insert
+ * @return a new call site descriptor with modified method type
+ */
+- public static CallSiteDescriptor insertParameterTypes(CallSiteDescriptor desc, int num, List<Class<?>> ptypesToInsert) {
++ public static CallSiteDescriptor insertParameterTypes(final CallSiteDescriptor desc, final int num, final List<Class<?>> ptypesToInsert) {
+ return desc.changeMethodType(desc.getMethodType().insertParameterTypes(num, ptypesToInsert));
+ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/support/ClassMap.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/ClassMap.java Wed Feb 04 12:14:47 2015 -0800
+@@ -110,7 +110,7 @@
+ *
+ * @param classLoader the classloader that determines strong referenceability.
+ */
+- protected ClassMap(ClassLoader classLoader) {
++ protected ClassMap(final ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
+--- ./nashorn/src/jdk/internal/dynalink/support/CompositeGuardingDynamicLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/CompositeGuardingDynamicLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -109,16 +109,16 @@
+ *
+ * @param linkers a list of component linkers.
+ */
+- public CompositeGuardingDynamicLinker(Iterable<? extends GuardingDynamicLinker> linkers) {
++ public CompositeGuardingDynamicLinker(final Iterable<? extends GuardingDynamicLinker> linkers) {
+ final List<GuardingDynamicLinker> l = new LinkedList<>();
+- for(GuardingDynamicLinker linker: linkers) {
++ for(final GuardingDynamicLinker linker: linkers) {
+ l.add(linker);
+ }
+ this.linkers = l.toArray(new GuardingDynamicLinker[l.size()]);
+ }
+
+ @Override
+- public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, final LinkerServices linkerServices)
++ public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices)
+ throws Exception {
+ for(final GuardingDynamicLinker linker: linkers) {
+ final GuardedInvocation invocation = linker.getGuardedInvocation(linkRequest, linkerServices);
+--- ./nashorn/src/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -111,8 +111,8 @@
+ private final TypeBasedGuardingDynamicLinker[] linkers;
+ private final List<TypeBasedGuardingDynamicLinker>[] singletonLinkers;
+
+- @SuppressWarnings("unchecked")
+- ClassToLinker(TypeBasedGuardingDynamicLinker[] linkers) {
++ @SuppressWarnings({"unchecked", "rawtypes"})
++ ClassToLinker(final TypeBasedGuardingDynamicLinker[] linkers) {
+ this.linkers = linkers;
+ singletonLinkers = new List[linkers.length];
+ for(int i = 0; i < linkers.length; ++i) {
+@@ -120,8 +120,9 @@
+ }
+ }
+
++ @SuppressWarnings("fallthrough")
+ @Override
+- protected List<TypeBasedGuardingDynamicLinker> computeValue(Class<?> clazz) {
++ protected List<TypeBasedGuardingDynamicLinker> computeValue(final Class<?> clazz) {
+ List<TypeBasedGuardingDynamicLinker> list = NO_LINKER;
+ for(int i = 0; i < linkers.length; ++i) {
+ final TypeBasedGuardingDynamicLinker linker = linkers[i];
+@@ -134,7 +135,6 @@
+ case 1: {
+ list = new LinkedList<>(list);
+ }
+- //$FALL-THROUGH$
+ default: {
+ list.add(linker);
+ }
+@@ -152,27 +152,27 @@
+ *
+ * @param linkers the component linkers
+ */
+- public CompositeTypeBasedGuardingDynamicLinker(Iterable<? extends TypeBasedGuardingDynamicLinker> linkers) {
++ public CompositeTypeBasedGuardingDynamicLinker(final Iterable<? extends TypeBasedGuardingDynamicLinker> linkers) {
+ final List<TypeBasedGuardingDynamicLinker> l = new LinkedList<>();
+- for(TypeBasedGuardingDynamicLinker linker: linkers) {
++ for(final TypeBasedGuardingDynamicLinker linker: linkers) {
+ l.add(linker);
+ }
+ this.classToLinker = new ClassToLinker(l.toArray(new TypeBasedGuardingDynamicLinker[l.size()]));
+ }
+
+ @Override
+- public boolean canLinkType(Class<?> type) {
++ public boolean canLinkType(final Class<?> type) {
+ return !classToLinker.get(type).isEmpty();
+ }
+
+ @Override
+- public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, final LinkerServices linkerServices)
++ public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices)
+ throws Exception {
+ final Object obj = linkRequest.getReceiver();
+ if(obj == null) {
+ return null;
+ }
+- for(TypeBasedGuardingDynamicLinker linker: classToLinker.get(obj.getClass())) {
++ for(final TypeBasedGuardingDynamicLinker linker: classToLinker.get(obj.getClass())) {
+ final GuardedInvocation invocation = linker.getGuardedInvocation(linkRequest, linkerServices);
+ if(invocation != null) {
+ return invocation;
+@@ -189,10 +189,10 @@
+ * @param linkers the list of linkers to optimize
+ * @return the optimized list
+ */
+- public static List<GuardingDynamicLinker> optimize(Iterable<? extends GuardingDynamicLinker> linkers) {
++ public static List<GuardingDynamicLinker> optimize(final Iterable<? extends GuardingDynamicLinker> linkers) {
+ final List<GuardingDynamicLinker> llinkers = new LinkedList<>();
+ final List<TypeBasedGuardingDynamicLinker> tblinkers = new LinkedList<>();
+- for(GuardingDynamicLinker linker: linkers) {
++ for(final GuardingDynamicLinker linker: linkers) {
+ if(linker instanceof TypeBasedGuardingDynamicLinker) {
+ tblinkers.add((TypeBasedGuardingDynamicLinker)linker);
+ } else {
+@@ -204,8 +204,8 @@
+ return llinkers;
+ }
+
+- private static void addTypeBased(List<GuardingDynamicLinker> llinkers,
+- List<TypeBasedGuardingDynamicLinker> tblinkers) {
++ private static void addTypeBased(final List<GuardingDynamicLinker> llinkers,
++ final List<TypeBasedGuardingDynamicLinker> tblinkers) {
+ switch(tblinkers.size()) {
+ case 0: {
+ break;
+--- ./nashorn/src/jdk/internal/dynalink/support/DefaultCallSiteDescriptor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/DefaultCallSiteDescriptor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -98,7 +98,7 @@
+ private final String[] tokenizedName;
+ private final MethodType methodType;
+
+- DefaultCallSiteDescriptor(String[] tokenizedName, MethodType methodType) {
++ DefaultCallSiteDescriptor(final String[] tokenizedName, final MethodType methodType) {
+ this.tokenizedName = tokenizedName;
+ this.methodType = methodType;
+ }
+@@ -109,10 +109,10 @@
+ }
+
+ @Override
+- public String getNameToken(int i) {
++ public String getNameToken(final int i) {
+ try {
+ return tokenizedName[i];
+- } catch(ArrayIndexOutOfBoundsException e) {
++ } catch(final ArrayIndexOutOfBoundsException e) {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ }
+@@ -127,7 +127,7 @@
+ }
+
+ @Override
+- public CallSiteDescriptor changeMethodType(MethodType newMethodType) {
++ public CallSiteDescriptor changeMethodType(final MethodType newMethodType) {
+ return CallSiteDescriptorFactory.getCanonicalPublicDescriptor(new DefaultCallSiteDescriptor(tokenizedName,
+ newMethodType));
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/internal/dynalink/support/DefaultPrelinkFilter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,99 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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.
++ */
++
++/*
++ * This file is available under and governed by the GNU General Public
++ * License version 2 only, as published by the Free Software Foundation.
++ * However, the following notice accompanied the original version of this
++ * file, and Oracle licenses the original version of this file under the BSD
++ * license:
++ */
++/*
++ Copyright 2009-2013 Attila Szegedi
++
++ Licensed under both the Apache License, Version 2.0 (the "Apache License")
++ and the BSD License (the "BSD License"), with licensee being free to
++ choose either of the two at their discretion.
++
++ You may not use this file except in compliance with either the Apache
++ License or the BSD License.
++
++ If you choose to use this file in compliance with the Apache License, the
++ following notice applies to you:
++
++ You may obtain a copy of the Apache License at
++
++ 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,
++ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
++ implied. See the License for the specific language governing
++ permissions and limitations under the License.
++
++ If you choose to use this file in compliance with the BSD License, the
++ following notice applies to you:
++
++ Redistribution and use in source and binary forms, with or without
++ modification, are permitted provided that the following conditions are
++ met:
++ * Redistributions of source code must retain the above copyright
++ notice, this list of conditions and the following disclaimer.
++ * Redistributions in binary form must reproduce the above copyright
++ notice, this list of conditions and the following disclaimer in the
++ documentation and/or other materials provided with the distribution.
++ * Neither the name of the copyright holder nor the names of
++ contributors may be used to endorse or promote products derived from
++ this software without specific prior written permission.
++
++ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
++ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
++ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
++ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
++ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
++ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++*/
++
++package jdk.internal.dynalink.support;
++
++import jdk.internal.dynalink.GuardedInvocationFilter;
++import jdk.internal.dynalink.linker.GuardedInvocation;
++import jdk.internal.dynalink.linker.LinkRequest;
++import jdk.internal.dynalink.linker.LinkerServices;
++
++/**
++ * Default filter for guarded invocation pre link filtering
++ */
++public class DefaultPrelinkFilter implements GuardedInvocationFilter {
++ @Override
++ public GuardedInvocation filter(final GuardedInvocation inv, final LinkRequest request, final LinkerServices linkerServices) {
++ return inv.asType(linkerServices, request.getCallSiteDescriptor().getMethodType());
++ }
++}
+--- ./nashorn/src/jdk/internal/dynalink/support/Guards.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/Guards.java Wed Feb 04 12:14:47 2015 -0800
+@@ -113,7 +113,7 @@
+ * @return a method handle testing whether its first argument is of the specified class.
+ */
+ @SuppressWarnings("boxing")
+- public static MethodHandle isOfClass(Class<?> clazz, MethodType type) {
++ public static MethodHandle isOfClass(final Class<?> clazz, final MethodType type) {
+ final Class<?> declaredType = type.parameterType(0);
+ if(clazz == declaredType) {
+ LOG.log(Level.WARNING, "isOfClassGuardAlwaysTrue", new Object[] { clazz.getName(), 0, type, DynamicLinker.getLinkedCallSiteLocation() });
+@@ -135,7 +135,7 @@
+ * @param type the method type
+ * @return a method handle testing whether its first argument is of the specified class or subclass.
+ */
+- public static MethodHandle isInstance(Class<?> clazz, MethodType type) {
++ public static MethodHandle isInstance(final Class<?> clazz, final MethodType type) {
+ return isInstance(clazz, 0, type);
+ }
+
+@@ -150,7 +150,7 @@
+ * @return a method handle testing whether its first argument is of the specified class or subclass.
+ */
+ @SuppressWarnings("boxing")
+- public static MethodHandle isInstance(Class<?> clazz, int pos, MethodType type) {
++ public static MethodHandle isInstance(final Class<?> clazz, final int pos, final MethodType type) {
+ final Class<?> declaredType = type.parameterType(pos);
+ if(clazz.isAssignableFrom(declaredType)) {
+ LOG.log(Level.WARNING, "isInstanceGuardAlwaysTrue", new Object[] { clazz.getName(), pos, type, DynamicLinker.getLinkedCallSiteLocation() });
+@@ -172,7 +172,7 @@
+ * the arguments are ignored.
+ */
+ @SuppressWarnings("boxing")
+- public static MethodHandle isArray(int pos, MethodType type) {
++ public static MethodHandle isArray(final int pos, final MethodType type) {
+ final Class<?> declaredType = type.parameterType(pos);
+ if(declaredType.isArray()) {
+ LOG.log(Level.WARNING, "isArrayGuardAlwaysTrue", new Object[] { pos, type, DynamicLinker.getLinkedCallSiteLocation() });
+@@ -193,7 +193,7 @@
+ * @param referredLoader the referred class loader
+ * @return true if it is safe to strongly reference the class
+ */
+- public static boolean canReferenceDirectly(ClassLoader referrerLoader, final ClassLoader referredLoader) {
++ public static boolean canReferenceDirectly(final ClassLoader referrerLoader, final ClassLoader referredLoader) {
+ if(referredLoader == null) {
+ // Can always refer directly to a system class
+ return true;
+@@ -215,7 +215,7 @@
+ return false;
+ }
+
+- private static MethodHandle getClassBoundArgumentTest(MethodHandle test, Class<?> clazz, int pos, MethodType type) {
++ private static MethodHandle getClassBoundArgumentTest(final MethodHandle test, final Class<?> clazz, final int pos, final MethodType type) {
+ // Bind the class to the first argument of the test
+ return asType(test.bindTo(clazz), pos, type);
+ }
+@@ -227,7 +227,7 @@
+ * @param type the type to adapt the method handle to
+ * @return the adapted method handle
+ */
+- public static MethodHandle asType(MethodHandle test, MethodType type) {
++ public static MethodHandle asType(final MethodHandle test, final MethodType type) {
+ return test.asType(getTestType(test, type));
+ }
+
+@@ -239,16 +239,16 @@
+ * @param type the type to adapt the method handle to
+ * @return the adapted method handle
+ */
+- public static MethodHandle asType(LinkerServices linkerServices, MethodHandle test, MethodType type) {
++ public static MethodHandle asType(final LinkerServices linkerServices, final MethodHandle test, final MethodType type) {
+ return linkerServices.asType(test, getTestType(test, type));
+ }
+
+- private static MethodType getTestType(MethodHandle test, MethodType type) {
++ private static MethodType getTestType(final MethodHandle test, final MethodType type) {
+ return type.dropParameterTypes(test.type().parameterCount(),
+ type.parameterCount()).changeReturnType(boolean.class);
+ }
+
+- private static MethodHandle asType(MethodHandle test, int pos, MethodType type) {
++ private static MethodHandle asType(final MethodHandle test, final int pos, final MethodType type) {
+ assert test != null;
+ assert type != null;
+ assert type.parameterCount() > 0;
+@@ -283,7 +283,7 @@
+ * @param clazz the class to test for.
+ * @return the desired guard method.
+ */
+- public static MethodHandle getClassGuard(Class<?> clazz) {
++ public static MethodHandle getClassGuard(final Class<?> clazz) {
+ return IS_OF_CLASS.bindTo(clazz);
+ }
+
+@@ -292,7 +292,7 @@
+ * @param clazz the class to test for.
+ * @return the desired guard method.
+ */
+- public static MethodHandle getInstanceOfGuard(Class<?> clazz) {
++ public static MethodHandle getInstanceOfGuard(final Class<?> clazz) {
+ return IS_INSTANCE.bindTo(clazz);
+ }
+
+@@ -301,7 +301,7 @@
+ * @param obj the object used as referential identity test
+ * @return the desired guard method.
+ */
+- public static MethodHandle getIdentityGuard(Object obj) {
++ public static MethodHandle getIdentityGuard(final Object obj) {
+ return IS_IDENTICAL.bindTo(obj);
+ }
+
+@@ -322,39 +322,39 @@
+ }
+
+ @SuppressWarnings("unused")
+- private static boolean isNull(Object obj) {
++ private static boolean isNull(final Object obj) {
+ return obj == null;
+ }
+
+ @SuppressWarnings("unused")
+- private static boolean isNotNull(Object obj) {
++ private static boolean isNotNull(final Object obj) {
+ return obj != null;
+ }
+
+ @SuppressWarnings("unused")
+- private static boolean isArray(Object o) {
++ private static boolean isArray(final Object o) {
+ return o != null && o.getClass().isArray();
+ }
+
+ @SuppressWarnings("unused")
+- private static boolean isOfClass(Class<?> c, Object o) {
++ private static boolean isOfClass(final Class<?> c, final Object o) {
+ return o != null && o.getClass() == c;
+ }
+
+ @SuppressWarnings("unused")
+- private static boolean isIdentical(Object o1, Object o2) {
++ private static boolean isIdentical(final Object o1, final Object o2) {
+ return o1 == o2;
+ }
+
+- private static MethodHandle constantTrue(MethodType type) {
++ private static MethodHandle constantTrue(final MethodType type) {
+ return constantBoolean(Boolean.TRUE, type);
+ }
+
+- private static MethodHandle constantFalse(MethodType type) {
++ private static MethodHandle constantFalse(final MethodType type) {
+ return constantBoolean(Boolean.FALSE, type);
+ }
+
+- private static MethodHandle constantBoolean(Boolean value, MethodType type) {
++ private static MethodHandle constantBoolean(final Boolean value, final MethodType type) {
+ return MethodHandles.permuteArguments(MethodHandles.constant(Boolean.TYPE, value),
+ type.changeReturnType(Boolean.TYPE));
+ }
+--- ./nashorn/src/jdk/internal/dynalink/support/LinkRequestImpl.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/LinkRequestImpl.java Wed Feb 04 12:14:47 2015 -0800
+@@ -95,18 +95,24 @@
+ public class LinkRequestImpl implements LinkRequest {
+
+ private final CallSiteDescriptor callSiteDescriptor;
++ private final Object callSiteToken;
+ private final Object[] arguments;
+ private final boolean callSiteUnstable;
++ private final int linkCount;
+
+ /**
+ * Creates a new link request.
+ *
+ * @param callSiteDescriptor the descriptor for the call site being linked
++ * @param callSiteToken the opaque token for the call site being linked.
++ * @param linkCount how many times this callsite has been linked/relinked
+ * @param callSiteUnstable true if the call site being linked is considered unstable
+ * @param arguments the arguments for the invocation
+ */
+- public LinkRequestImpl(CallSiteDescriptor callSiteDescriptor, boolean callSiteUnstable, Object... arguments) {
++ public LinkRequestImpl(final CallSiteDescriptor callSiteDescriptor, final Object callSiteToken, final int linkCount, final boolean callSiteUnstable, final Object... arguments) {
+ this.callSiteDescriptor = callSiteDescriptor;
++ this.callSiteToken = callSiteToken;
++ this.linkCount = linkCount;
+ this.callSiteUnstable = callSiteUnstable;
+ this.arguments = arguments;
+ }
+@@ -127,17 +133,27 @@
+ }
+
+ @Override
++ public Object getCallSiteToken() {
++ return callSiteToken;
++ }
++
++ @Override
+ public boolean isCallSiteUnstable() {
+ return callSiteUnstable;
+ }
+
+ @Override
++ public int getLinkCount() {
++ return linkCount;
++ }
++
++ @Override
+ public LinkRequest withoutRuntimeContext() {
+ return this;
+ }
+
+ @Override
+- public LinkRequest replaceArguments(CallSiteDescriptor newCallSiteDescriptor, Object[] newArguments) {
+- return new LinkRequestImpl(newCallSiteDescriptor, callSiteUnstable, newArguments);
++ public LinkRequest replaceArguments(final CallSiteDescriptor newCallSiteDescriptor, final Object[] newArguments) {
++ return new LinkRequestImpl(newCallSiteDescriptor, callSiteToken, linkCount, callSiteUnstable, newArguments);
+ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/support/LinkerServicesImpl.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/LinkerServicesImpl.java Wed Feb 04 12:14:47 2015 -0800
+@@ -117,27 +117,32 @@
+ }
+
+ @Override
+- public boolean canConvert(Class<?> from, Class<?> to) {
++ public boolean canConvert(final Class<?> from, final Class<?> to) {
+ return typeConverterFactory.canConvert(from, to);
+ }
+
+ @Override
+- public MethodHandle asType(MethodHandle handle, MethodType fromType) {
++ public MethodHandle asType(final MethodHandle handle, final MethodType fromType) {
+ return typeConverterFactory.asType(handle, fromType);
+ }
+
+ @Override
+- public MethodHandle getTypeConverter(Class<?> sourceType, Class<?> targetType) {
++ public MethodHandle asTypeLosslessReturn(final MethodHandle handle, final MethodType fromType) {
++ return Implementation.asTypeLosslessReturn(this, handle, fromType);
++ }
++
++ @Override
++ public MethodHandle getTypeConverter(final Class<?> sourceType, final Class<?> targetType) {
+ return typeConverterFactory.getTypeConverter(sourceType, targetType);
+ }
+
+ @Override
+- public Comparison compareConversion(Class<?> sourceType, Class<?> targetType1, Class<?> targetType2) {
++ public Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) {
+ return typeConverterFactory.compareConversion(sourceType, targetType1, targetType2);
+ }
+
+ @Override
+- public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest) throws Exception {
++ public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest) throws Exception {
+ final LinkRequest prevLinkRequest = threadLinkRequest.get();
+ threadLinkRequest.set(linkRequest);
+ try {
+@@ -154,7 +159,7 @@
+ * permission.
+ */
+ public static LinkRequest getCurrentLinkRequest() {
+- SecurityManager sm = System.getSecurityManager();
++ final SecurityManager sm = System.getSecurityManager();
+ if(sm != null) {
+ sm.checkPermission(GET_CURRENT_LINK_REQUEST);
+ }
+--- ./nashorn/src/jdk/internal/dynalink/support/Lookup.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/Lookup.java Wed Feb 04 12:14:47 2015 -0800
+@@ -104,7 +104,7 @@
+ *
+ * @param lookup the {@link java.lang.invoke.MethodHandles.Lookup} it delegates to.
+ */
+- public Lookup(MethodHandles.Lookup lookup) {
++ public Lookup(final MethodHandles.Lookup lookup) {
+ this.lookup = lookup;
+ }
+
+@@ -120,7 +120,7 @@
+ * @param m the method to unreflect
+ * @return the unreflected method handle.
+ */
+- public MethodHandle unreflect(Method m) {
++ public MethodHandle unreflect(final Method m) {
+ return unreflect(lookup, m);
+ }
+
+@@ -132,10 +132,10 @@
+ * @param m the method to unreflect
+ * @return the unreflected method handle.
+ */
+- public static MethodHandle unreflect(MethodHandles.Lookup lookup, Method m) {
++ public static MethodHandle unreflect(final MethodHandles.Lookup lookup, final Method m) {
+ try {
+ return lookup.unreflect(m);
+- } catch(IllegalAccessException e) {
++ } catch(final IllegalAccessException e) {
+ final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect method " + m);
+ ee.initCause(e);
+ throw ee;
+@@ -149,10 +149,10 @@
+ * @param f the field for which a getter is unreflected
+ * @return the unreflected field getter handle.
+ */
+- public MethodHandle unreflectGetter(Field f) {
++ public MethodHandle unreflectGetter(final Field f) {
+ try {
+ return lookup.unreflectGetter(f);
+- } catch(IllegalAccessException e) {
++ } catch(final IllegalAccessException e) {
+ final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect getter for field " + f);
+ ee.initCause(e);
+ throw ee;
+@@ -171,15 +171,15 @@
+ * @throws IllegalAccessError if the field is inaccessible.
+ * @throws NoSuchFieldError if the field does not exist.
+ */
+- public MethodHandle findGetter(Class<?>refc, String name, Class<?> type) {
++ public MethodHandle findGetter(final Class<?>refc, final String name, final Class<?> type) {
+ try {
+ return lookup.findGetter(refc, name, type);
+- } catch(IllegalAccessException e) {
++ } catch(final IllegalAccessException e) {
+ final IllegalAccessError ee = new IllegalAccessError("Failed to access getter for field " + refc.getName() +
+ "." + name + " of type " + type.getName());
+ ee.initCause(e);
+ throw ee;
+- } catch(NoSuchFieldException e) {
++ } catch(final NoSuchFieldException e) {
+ final NoSuchFieldError ee = new NoSuchFieldError("Failed to find getter for field " + refc.getName() +
+ "." + name + " of type " + type.getName());
+ ee.initCause(e);
+@@ -194,10 +194,10 @@
+ * @param f the field for which a setter is unreflected
+ * @return the unreflected field setter handle.
+ */
+- public MethodHandle unreflectSetter(Field f) {
++ public MethodHandle unreflectSetter(final Field f) {
+ try {
+ return lookup.unreflectSetter(f);
+- } catch(IllegalAccessException e) {
++ } catch(final IllegalAccessException e) {
+ final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect setter for field " + f);
+ ee.initCause(e);
+ throw ee;
+@@ -211,7 +211,7 @@
+ * @param c the constructor to unreflect
+ * @return the unreflected constructor handle.
+ */
+- public MethodHandle unreflectConstructor(Constructor<?> c) {
++ public MethodHandle unreflectConstructor(final Constructor<?> c) {
+ return unreflectConstructor(lookup, c);
+ }
+
+@@ -223,10 +223,10 @@
+ * @param c the constructor to unreflect
+ * @return the unreflected constructor handle.
+ */
+- public static MethodHandle unreflectConstructor(MethodHandles.Lookup lookup, Constructor<?> c) {
++ public static MethodHandle unreflectConstructor(final MethodHandles.Lookup lookup, final Constructor<?> c) {
+ try {
+ return lookup.unreflectConstructor(c);
+- } catch(IllegalAccessException e) {
++ } catch(final IllegalAccessException e) {
+ final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect constructor " + c);
+ ee.initCause(e);
+ throw ee;
+@@ -244,15 +244,15 @@
+ * @throws IllegalAccessError if the method is inaccessible.
+ * @throws NoSuchMethodError if the method does not exist.
+ */
+- public MethodHandle findSpecial(Class<?> declaringClass, String name, MethodType type) {
++ public MethodHandle findSpecial(final Class<?> declaringClass, final String name, final MethodType type) {
+ try {
+ return lookup.findSpecial(declaringClass, name, type, declaringClass);
+- } catch(IllegalAccessException e) {
++ } catch(final IllegalAccessException e) {
+ final IllegalAccessError ee = new IllegalAccessError("Failed to access special method " + methodDescription(
+ declaringClass, name, type));
+ ee.initCause(e);
+ throw ee;
+- } catch(NoSuchMethodException e) {
++ } catch(final NoSuchMethodException e) {
+ final NoSuchMethodError ee = new NoSuchMethodError("Failed to find special method " + methodDescription(
+ declaringClass, name, type));
+ ee.initCause(e);
+@@ -260,7 +260,7 @@
+ }
+ }
+
+- private static String methodDescription(Class<?> declaringClass, String name, MethodType type) {
++ private static String methodDescription(final Class<?> declaringClass, final String name, final MethodType type) {
+ return declaringClass.getName() + "#" + name + type;
+ }
+
+@@ -275,15 +275,15 @@
+ * @throws IllegalAccessError if the method is inaccessible.
+ * @throws NoSuchMethodError if the method does not exist.
+ */
+- public MethodHandle findStatic(Class<?> declaringClass, String name, MethodType type) {
++ public MethodHandle findStatic(final Class<?> declaringClass, final String name, final MethodType type) {
+ try {
+ return lookup.findStatic(declaringClass, name, type);
+- } catch(IllegalAccessException e) {
++ } catch(final IllegalAccessException e) {
+ final IllegalAccessError ee = new IllegalAccessError("Failed to access static method " + methodDescription(
+ declaringClass, name, type));
+ ee.initCause(e);
+ throw ee;
+- } catch(NoSuchMethodException e) {
++ } catch(final NoSuchMethodException e) {
+ final NoSuchMethodError ee = new NoSuchMethodError("Failed to find static method " + methodDescription(
+ declaringClass, name, type));
+ ee.initCause(e);
+@@ -302,15 +302,15 @@
+ * @throws IllegalAccessError if the method is inaccessible.
+ * @throws NoSuchMethodError if the method does not exist.
+ */
+- public MethodHandle findVirtual(Class<?> declaringClass, String name, MethodType type) {
++ public MethodHandle findVirtual(final Class<?> declaringClass, final String name, final MethodType type) {
+ try {
+ return lookup.findVirtual(declaringClass, name, type);
+- } catch(IllegalAccessException e) {
++ } catch(final IllegalAccessException e) {
+ final IllegalAccessError ee = new IllegalAccessError("Failed to access virtual method " + methodDescription(
+ declaringClass, name, type));
+ ee.initCause(e);
+ throw ee;
+- } catch(NoSuchMethodException e) {
++ } catch(final NoSuchMethodException e) {
+ final NoSuchMethodError ee = new NoSuchMethodError("Failed to find virtual method " + methodDescription(
+ declaringClass, name, type));
+ ee.initCause(e);
+@@ -327,7 +327,7 @@
+ * @param ptypes the parameter types of the method
+ * @return the method handle for the method
+ */
+- public static MethodHandle findOwnSpecial(MethodHandles.Lookup lookup, String name, Class<?> rtype, Class<?>... ptypes) {
++ public static MethodHandle findOwnSpecial(final MethodHandles.Lookup lookup, final String name, final Class<?> rtype, final Class<?>... ptypes) {
+ return new Lookup(lookup).findOwnSpecial(name, rtype, ptypes);
+ }
+
+@@ -341,7 +341,7 @@
+ * @param ptypes the parameter types of the method
+ * @return the method handle for the method
+ */
+- public MethodHandle findOwnSpecial(String name, Class<?> rtype, Class<?>... ptypes) {
++ public MethodHandle findOwnSpecial(final String name, final Class<?> rtype, final Class<?>... ptypes) {
+ return findSpecial(lookup.lookupClass(), name, MethodType.methodType(rtype, ptypes));
+ }
+
+@@ -355,7 +355,7 @@
+ * @param ptypes the parameter types of the method
+ * @return the method handle for the method
+ */
+- public static MethodHandle findOwnStatic(MethodHandles.Lookup lookup, String name, Class<?> rtype, Class<?>... ptypes) {
++ public static MethodHandle findOwnStatic(final MethodHandles.Lookup lookup, final String name, final Class<?> rtype, final Class<?>... ptypes) {
+ return new Lookup(lookup).findOwnStatic(name, rtype, ptypes);
+ }
+
+@@ -368,7 +368,7 @@
+ * @param ptypes the parameter types of the method
+ * @return the method handle for the method
+ */
+- public MethodHandle findOwnStatic(String name, Class<?> rtype, Class<?>... ptypes) {
++ public MethodHandle findOwnStatic(final String name, final Class<?> rtype, final Class<?>... ptypes) {
+ return findStatic(lookup.lookupClass(), name, MethodType.methodType(rtype, ptypes));
+ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/support/LookupCallSiteDescriptor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/LookupCallSiteDescriptor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -92,7 +92,7 @@
+ * @author Attila Szegedi
+ */
+ class LookupCallSiteDescriptor extends DefaultCallSiteDescriptor {
+- private Lookup lookup;
++ private final Lookup lookup;
+
+ /**
+ * Create a new call site descriptor from explicit information.
+@@ -100,7 +100,7 @@
+ * @param methodType the method type
+ * @param lookup the lookup
+ */
+- LookupCallSiteDescriptor(String[] tokenizedName, MethodType methodType, Lookup lookup) {
++ LookupCallSiteDescriptor(final String[] tokenizedName, final MethodType methodType, final Lookup lookup) {
+ super(tokenizedName, methodType);
+ this.lookup = lookup;
+ }
+@@ -111,7 +111,7 @@
+ }
+
+ @Override
+- public CallSiteDescriptor changeMethodType(MethodType newMethodType) {
++ public CallSiteDescriptor changeMethodType(final MethodType newMethodType) {
+ return new LookupCallSiteDescriptor(getTokenizedName(), newMethodType, lookup);
+ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/support/NameCodec.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/NameCodec.java Wed Feb 04 12:14:47 2015 -0800
+@@ -137,7 +137,7 @@
+ * @param name the symbolic name to mangle
+ * @return the mangled form of the symbolic name.
+ */
+- public static String encode(String name) {
++ public static String encode(final String name) {
+ final int l = name.length();
+ if(l == 0) {
+ return EMPTY_NAME;
+@@ -176,7 +176,7 @@
+ * @param name the symbolic name to demangle
+ * @return the demangled form of the symbolic name.
+ */
+- public static String decode(String name) {
++ public static String decode(final String name) {
+ if(name.charAt(0) != ESCAPE_CHAR) {
+ return name;
+ }
+@@ -184,11 +184,11 @@
+ if(l == 2 && name.charAt(1) == EMPTY_CHAR) {
+ return "";
+ }
+- StringBuilder b = new StringBuilder(name.length());
++ final StringBuilder b = new StringBuilder(name.length());
+ int lastEscape = -2;
+ int lastBackslash = -1;
+ for(;;) {
+- int nextBackslash = name.indexOf(ESCAPE_CHAR, lastBackslash + 1);
++ final int nextBackslash = name.indexOf(ESCAPE_CHAR, lastBackslash + 1);
+ if(nextBackslash == -1 || nextBackslash == l - 1) {
+ break;
+ }
+@@ -211,7 +211,7 @@
+ return b.toString();
+ }
+
+- private static void addEncoding(char from, char to) {
++ private static void addEncoding(final char from, final char to) {
+ ENCODING[from - MIN_ENCODING] = to;
+ DECODING[to - MIN_DECODING] = from;
+ }
+--- ./nashorn/src/jdk/internal/dynalink/support/NamedDynCallSiteDescriptor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/NamedDynCallSiteDescriptor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -89,7 +89,7 @@
+ class NamedDynCallSiteDescriptor extends UnnamedDynCallSiteDescriptor {
+ private final String name;
+
+- NamedDynCallSiteDescriptor(String op, String name, MethodType methodType) {
++ NamedDynCallSiteDescriptor(final String op, final String name, final MethodType methodType) {
+ super(op, methodType);
+ this.name = name;
+ }
+@@ -100,7 +100,7 @@
+ }
+
+ @Override
+- public String getNameToken(int i) {
++ public String getNameToken(final int i) {
+ switch(i) {
+ case 0: return "dyn";
+ case 1: return getOp();
+@@ -110,7 +110,7 @@
+ }
+
+ @Override
+- public CallSiteDescriptor changeMethodType(MethodType newMethodType) {
++ public CallSiteDescriptor changeMethodType(final MethodType newMethodType) {
+ return CallSiteDescriptorFactory.getCanonicalPublicDescriptor(new NamedDynCallSiteDescriptor(getOp(), name,
+ newMethodType));
+ }
+--- ./nashorn/src/jdk/internal/dynalink/support/RuntimeContextLinkRequestImpl.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/RuntimeContextLinkRequestImpl.java Wed Feb 04 12:14:47 2015 -0800
+@@ -101,15 +101,17 @@
+ * Creates a new link request.
+ *
+ * @param callSiteDescriptor the descriptor for the call site being linked
++ * @param callSiteToken the opaque token for the call site being linked.
+ * @param arguments the arguments for the invocation
++ * @param linkCount number of times callsite has been linked/relinked
+ * @param callSiteUnstable true if the call site being linked is considered unstable
+ * @param runtimeContextArgCount the number of the leading arguments on the stack that represent the language
+ * runtime specific context arguments.
+ * @throws IllegalArgumentException if runtimeContextArgCount is less than 1.
+ */
+- public RuntimeContextLinkRequestImpl(CallSiteDescriptor callSiteDescriptor, boolean callSiteUnstable,
+- Object[] arguments, int runtimeContextArgCount) {
+- super(callSiteDescriptor, callSiteUnstable, arguments);
++ public RuntimeContextLinkRequestImpl(final CallSiteDescriptor callSiteDescriptor, final Object callSiteToken,
++ final int linkCount, final boolean callSiteUnstable, final Object[] arguments, final int runtimeContextArgCount) {
++ super(callSiteDescriptor, callSiteToken, linkCount, callSiteUnstable, arguments);
+ if(runtimeContextArgCount < 1) {
+ throw new IllegalArgumentException("runtimeContextArgCount < 1");
+ }
+@@ -121,14 +123,14 @@
+ if(contextStrippedRequest == null) {
+ contextStrippedRequest =
+ new LinkRequestImpl(CallSiteDescriptorFactory.dropParameterTypes(getCallSiteDescriptor(), 1,
+- runtimeContextArgCount + 1), isCallSiteUnstable(), getTruncatedArguments());
++ runtimeContextArgCount + 1), getCallSiteToken(), getLinkCount(), isCallSiteUnstable(), getTruncatedArguments());
+ }
+ return contextStrippedRequest;
+ }
+
+ @Override
+- public LinkRequest replaceArguments(CallSiteDescriptor callSiteDescriptor, Object[] arguments) {
+- return new RuntimeContextLinkRequestImpl(callSiteDescriptor, isCallSiteUnstable(), arguments,
++ public LinkRequest replaceArguments(final CallSiteDescriptor callSiteDescriptor, final Object[] arguments) {
++ return new RuntimeContextLinkRequestImpl(callSiteDescriptor, getCallSiteToken(), getLinkCount(), isCallSiteUnstable(), arguments,
+ runtimeContextArgCount);
+ }
+
+--- ./nashorn/src/jdk/internal/dynalink/support/TypeConverterFactory.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/TypeConverterFactory.java Wed Feb 04 12:14:47 2015 -0800
+@@ -97,6 +97,7 @@
+ import jdk.internal.dynalink.linker.GuardedTypeConversion;
+ import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
+ import jdk.internal.dynalink.linker.LinkerServices;
++import jdk.internal.dynalink.linker.MethodTypeConversionStrategy;
+
+ /**
+ * A factory for type converters. This class is the main implementation behind the
+@@ -109,18 +110,19 @@
+
+ private final GuardingTypeConverterFactory[] factories;
+ private final ConversionComparator[] comparators;
++ private final MethodTypeConversionStrategy autoConversionStrategy;
+
+ private final ClassValue<ClassMap<MethodHandle>> converterMap = new ClassValue<ClassMap<MethodHandle>>() {
+ @Override
+ protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) {
+ return new ClassMap<MethodHandle>(getClassLoader(sourceType)) {
+ @Override
+- protected MethodHandle computeValue(Class<?> targetType) {
++ protected MethodHandle computeValue(final Class<?> targetType) {
+ try {
+ return createConverter(sourceType, targetType);
+- } catch (RuntimeException e) {
++ } catch (final RuntimeException e) {
+ throw e;
+- } catch (Exception e) {
++ } catch (final Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+@@ -133,7 +135,7 @@
+ protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) {
+ return new ClassMap<MethodHandle>(getClassLoader(sourceType)) {
+ @Override
+- protected MethodHandle computeValue(Class<?> targetType) {
++ protected MethodHandle computeValue(final Class<?> targetType) {
+ if(!canAutoConvert(sourceType, targetType)) {
+ final MethodHandle converter = getCacheableTypeConverter(sourceType, targetType);
+ if(converter != IDENTITY_CONVERSION) {
+@@ -151,12 +153,12 @@
+ protected ClassMap<Boolean> computeValue(final Class<?> sourceType) {
+ return new ClassMap<Boolean>(getClassLoader(sourceType)) {
+ @Override
+- protected Boolean computeValue(Class<?> targetType) {
++ protected Boolean computeValue(final Class<?> targetType) {
+ try {
+ return getTypeConverterNull(sourceType, targetType) != null;
+- } catch (RuntimeException e) {
++ } catch (final RuntimeException e) {
+ throw e;
+- } catch (Exception e) {
++ } catch (final Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+@@ -177,11 +179,27 @@
+ * Creates a new type converter factory from the available {@link GuardingTypeConverterFactory} instances.
+ *
+ * @param factories the {@link GuardingTypeConverterFactory} instances to compose.
++ * @param autoConversionStrategy conversion strategy for automatic type conversions. After
++ * {@link #asType(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType)} has applied all custom
++ * conversions to a method handle, it still needs to effect
++ * {@link TypeUtilities#isMethodInvocationConvertible(Class, Class) method invocation conversions} that
++ * can usually be automatically applied as per
++ * {@link java.lang.invoke.MethodHandle#asType(java.lang.invoke.MethodType)}.
++ * However, sometimes language runtimes will want to customize even those conversions for their own call
++ * sites. A typical example is allowing unboxing of null return values, which is by default prohibited by
++ * ordinary {@code MethodHandles.asType}. In this case, a language runtime can install its own custom
++ * automatic conversion strategy, that can deal with null values. Note that when the strategy's
++ * {@link MethodTypeConversionStrategy#asType(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType)}
++ * is invoked, the custom language conversions will already have been applied to the method handle, so by
++ * design the difference between the handle's current method type and the desired final type will always
++ * only be ones that can be subjected to method invocation conversions. Can be null, in which case no
++ * custom strategy is employed.
+ */
+- public TypeConverterFactory(Iterable<? extends GuardingTypeConverterFactory> factories) {
++ public TypeConverterFactory(final Iterable<? extends GuardingTypeConverterFactory> factories,
++ final MethodTypeConversionStrategy autoConversionStrategy) {
+ final List<GuardingTypeConverterFactory> l = new LinkedList<>();
+ final List<ConversionComparator> c = new LinkedList<>();
+- for(GuardingTypeConverterFactory factory: factories) {
++ for(final GuardingTypeConverterFactory factory: factories) {
+ l.add(factory);
+ if(factory instanceof ConversionComparator) {
+ c.add((ConversionComparator)factory);
+@@ -189,24 +207,28 @@
+ }
+ this.factories = l.toArray(new GuardingTypeConverterFactory[l.size()]);
+ this.comparators = c.toArray(new ConversionComparator[c.size()]);
+-
++ this.autoConversionStrategy = autoConversionStrategy;
+ }
+
+ /**
+ * Similar to {@link MethodHandle#asType(MethodType)} except it also hooks in method handles produced by
+ * {@link GuardingTypeConverterFactory} implementations, providing for language-specific type coercing of
+- * parameters. It will apply {@link MethodHandle#asType(MethodType)} for all primitive-to-primitive,
+- * wrapper-to-primitive, primitive-to-wrapper conversions as well as for all upcasts. For all other conversions,
+- * it'll insert {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with composite filters
+- * provided by {@link GuardingTypeConverterFactory} implementations.
++ * parameters. For all conversions that are not a JLS method invocation conversion it'll insert
++ * {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with composite filters
++ * provided by {@link GuardingTypeConverterFactory} implementations. For the remaining JLS method invocation
++ * conversions, it will invoke {@link MethodTypeConversionStrategy#asType(MethodHandle, MethodType)} first
++ * if an automatic conversion strategy was specified in the
++ * {@link #TypeConverterFactory(Iterable, MethodTypeConversionStrategy) constructor}, and finally apply
++ * {@link MethodHandle#asType(MethodType)} for any remaining conversions.
+ *
+ * @param handle target method handle
+ * @param fromType the types of source arguments
+- * @return a method handle that is a suitable combination of {@link MethodHandle#asType(MethodType)} and
++ * @return a method handle that is a suitable combination of {@link MethodHandle#asType(MethodType)},
++ * {@link MethodTypeConversionStrategy#asType(MethodHandle, MethodType)}, and
+ * {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with
+ * {@link GuardingTypeConverterFactory} produced type converters as filters.
+ */
+- public MethodHandle asType(MethodHandle handle, final MethodType fromType) {
++ public MethodHandle asType(final MethodHandle handle, final MethodType fromType) {
+ MethodHandle newHandle = handle;
+ final MethodType toType = newHandle.type();
+ final int l = toType.parameterCount();
+@@ -246,11 +268,15 @@
+ }
+ }
+
+- // Take care of automatic conversions
+- return newHandle.asType(fromType);
++ // Give change to automatic conversion strategy, if one is present.
++ final MethodHandle autoConvertedHandle =
++ autoConversionStrategy != null ? autoConversionStrategy.asType(newHandle, fromType) : newHandle;
++
++ // Do a final asType for any conversions that remain.
++ return autoConvertedHandle.asType(fromType);
+ }
+
+- private static MethodHandle applyConverters(MethodHandle handle, int pos, List<MethodHandle> converters) {
++ private static MethodHandle applyConverters(final MethodHandle handle, final int pos, final List<MethodHandle> converters) {
+ if(converters.isEmpty()) {
+ return handle;
+ }
+@@ -285,8 +311,8 @@
+ * @return one of Comparison constants that establish which - if any - of the target types is preferable for the
+ * conversion.
+ */
+- public Comparison compareConversion(Class<?> sourceType, Class<?> targetType1, Class<?> targetType2) {
+- for(ConversionComparator comparator: comparators) {
++ public Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) {
++ for(final ConversionComparator comparator: comparators) {
+ final Comparison result = comparator.compareConversion(sourceType, targetType1, targetType2);
+ if(result != Comparison.INDETERMINATE) {
+ return result;
+@@ -313,20 +339,20 @@
+ return TypeUtilities.isMethodInvocationConvertible(fromType, toType);
+ }
+
+- /*private*/ MethodHandle getCacheableTypeConverterNull(Class<?> sourceType, Class<?> targetType) {
++ /*private*/ MethodHandle getCacheableTypeConverterNull(final Class<?> sourceType, final Class<?> targetType) {
+ final MethodHandle converter = getCacheableTypeConverter(sourceType, targetType);
+ return converter == IDENTITY_CONVERSION ? null : converter;
+ }
+
+- /*private*/ MethodHandle getTypeConverterNull(Class<?> sourceType, Class<?> targetType) {
++ /*private*/ MethodHandle getTypeConverterNull(final Class<?> sourceType, final Class<?> targetType) {
+ try {
+ return getCacheableTypeConverterNull(sourceType, targetType);
+- } catch(NotCacheableConverter e) {
++ } catch(final NotCacheableConverter e) {
+ return e.converter;
+ }
+ }
+
+- /*private*/ MethodHandle getCacheableTypeConverter(Class<?> sourceType, Class<?> targetType) {
++ /*private*/ MethodHandle getCacheableTypeConverter(final Class<?> sourceType, final Class<?> targetType) {
+ return converterMap.get(sourceType).get(targetType);
+ }
+
+@@ -339,15 +365,15 @@
+ * @param targetType the type to convert to
+ * @return a method handle performing the conversion.
+ */
+- public MethodHandle getTypeConverter(Class<?> sourceType, Class<?> targetType) {
++ public MethodHandle getTypeConverter(final Class<?> sourceType, final Class<?> targetType) {
+ try {
+ return converterIdentityMap.get(sourceType).get(targetType);
+- } catch(NotCacheableConverter e) {
++ } catch(final NotCacheableConverter e) {
+ return e.converter;
+ }
+ }
+
+- /*private*/ MethodHandle createConverter(Class<?> sourceType, Class<?> targetType) throws Exception {
++ /*private*/ MethodHandle createConverter(final Class<?> sourceType, final Class<?> targetType) throws Exception {
+ final MethodType type = MethodType.methodType(targetType, sourceType);
+ final MethodHandle identity = IDENTITY_CONVERSION.asType(type);
+ MethodHandle last = identity;
+@@ -372,6 +398,7 @@
+
+ /*private*/ static final MethodHandle IDENTITY_CONVERSION = MethodHandles.identity(Object.class);
+
++ @SuppressWarnings("serial")
+ private static class NotCacheableConverter extends RuntimeException {
+ final MethodHandle converter;
+
+--- ./nashorn/src/jdk/internal/dynalink/support/TypeUtilities.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/TypeUtilities.java Wed Feb 04 12:14:47 2015 -0800
+@@ -106,38 +106,45 @@
+ }
+
+ /**
+- * Given two types represented by c1 and c2, returns a type that is their most specific common superclass or
+- * superinterface.
++ * Given two types represented by c1 and c2, returns a type that is their most specific common supertype for
++ * purposes of lossless conversions.
+ *
+ * @param c1 one type
+ * @param c2 another type
+- * @return their most common superclass or superinterface. If they have several unrelated superinterfaces as their
+- * most specific common type, or the types themselves are completely unrelated interfaces, {@link java.lang.Object}
+- * is returned.
++ * @return their most common superclass or superinterface for purposes of lossless conversions. If they have several
++ * unrelated superinterfaces as their most specific common type, or the types themselves are completely
++ * unrelated interfaces, {@link java.lang.Object} is returned.
+ */
+- public static Class<?> getMostSpecificCommonType(Class<?> c1, Class<?> c2) {
++ public static Class<?> getCommonLosslessConversionType(final Class<?> c1, final Class<?> c2) {
+ if(c1 == c2) {
+ return c1;
++ } else if (c1 == void.class || c2 == void.class) {
++ return Object.class;
++ } else if(isConvertibleWithoutLoss(c2, c1)) {
++ return c1;
++ } else if(isConvertibleWithoutLoss(c1, c2)) {
++ return c2;
++ } else if(c1.isPrimitive() && c2.isPrimitive()) {
++ if((c1 == byte.class && c2 == char.class) || (c1 == char.class && c2 == byte.class)) {
++ // byte + char = int
++ return int.class;
++ } else if((c1 == short.class && c2 == char.class) || (c1 == char.class && c2 == short.class)) {
++ // short + char = int
++ return int.class;
++ } else if((c1 == int.class && c2 == float.class) || (c1 == float.class && c2 == int.class)) {
++ // int + float = double
++ return double.class;
++ }
+ }
+- Class<?> c3 = c2;
+- if(c3.isPrimitive()) {
+- if(c3 == Byte.TYPE)
+- c3 = Byte.class;
+- else if(c3 == Short.TYPE)
+- c3 = Short.class;
+- else if(c3 == Character.TYPE)
+- c3 = Character.class;
+- else if(c3 == Integer.TYPE)
+- c3 = Integer.class;
+- else if(c3 == Float.TYPE)
+- c3 = Float.class;
+- else if(c3 == Long.TYPE)
+- c3 = Long.class;
+- else if(c3 == Double.TYPE)
+- c3 = Double.class;
+- }
+- Set<Class<?>> a1 = getAssignables(c1, c3);
+- Set<Class<?>> a2 = getAssignables(c3, c1);
++ // For all other cases. This will handle long + (float|double) = Number case as well as boolean + anything = Object case too.
++ return getMostSpecificCommonTypeUnequalNonprimitives(c1, c2);
++ }
++
++ private static Class<?> getMostSpecificCommonTypeUnequalNonprimitives(final Class<?> c1, final Class<?> c2) {
++ final Class<?> npc1 = c1.isPrimitive() ? getWrapperType(c1) : c1;
++ final Class<?> npc2 = c2.isPrimitive() ? getWrapperType(c2) : c2;
++ final Set<Class<?>> a1 = getAssignables(npc1, npc2);
++ final Set<Class<?>> a2 = getAssignables(npc2, npc1);
+ a1.retainAll(a2);
+ if(a1.isEmpty()) {
+ // Can happen when at least one of the arguments is an interface,
+@@ -148,10 +155,10 @@
+ // thank to interfaces. I.e., if you call this method for String.class
+ // and Number.class, you'll have Comparable, Serializable, and Object
+ // as maximal elements.
+- List<Class<?>> max = new ArrayList<>();
+- outer: for(Class<?> clazz: a1) {
+- for(Iterator<Class<?>> maxiter = max.iterator(); maxiter.hasNext();) {
+- Class<?> maxClazz = maxiter.next();
++ final List<Class<?>> max = new ArrayList<>();
++ outer: for(final Class<?> clazz: a1) {
++ for(final Iterator<Class<?>> maxiter = max.iterator(); maxiter.hasNext();) {
++ final Class<?> maxClazz = maxiter.next();
+ if(isSubtype(maxClazz, clazz)) {
+ // It can't be maximal, if there's already a more specific
+ // maximal than it.
+@@ -168,26 +175,26 @@
+ max.add(clazz);
+ }
+ if(max.size() > 1) {
+- return OBJECT_CLASS;
++ return Object.class;
+ }
+ return max.get(0);
+ }
+
+- private static Set<Class<?>> getAssignables(Class<?> c1, Class<?> c2) {
+- Set<Class<?>> s = new HashSet<>();
++ private static Set<Class<?>> getAssignables(final Class<?> c1, final Class<?> c2) {
++ final Set<Class<?>> s = new HashSet<>();
+ collectAssignables(c1, c2, s);
+ return s;
+ }
+
+- private static void collectAssignables(Class<?> c1, Class<?> c2, Set<Class<?>> s) {
++ private static void collectAssignables(final Class<?> c1, final Class<?> c2, final Set<Class<?>> s) {
+ if(c1.isAssignableFrom(c2)) {
+ s.add(c1);
+ }
+- Class<?> sc = c1.getSuperclass();
++ final Class<?> sc = c1.getSuperclass();
+ if(sc != null) {
+ collectAssignables(sc, c2, s);
+ }
+- Class<?>[] itf = c1.getInterfaces();
++ final Class<?>[] itf = c1.getInterfaces();
+ for(int i = 0; i < itf.length; ++i) {
+ collectAssignables(itf[i], c2, s);
+ }
+@@ -210,17 +217,17 @@
+ return Collections.unmodifiableMap(wrapperTypes);
+ }
+
+- private static Map<String, Class<?>> createClassNameMapping(Collection<Class<?>> classes) {
++ private static Map<String, Class<?>> createClassNameMapping(final Collection<Class<?>> classes) {
+ final Map<String, Class<?>> map = new HashMap<>();
+- for(Class<?> clazz: classes) {
++ for(final Class<?> clazz: classes) {
+ map.put(clazz.getName(), clazz);
+ }
+ return map;
+ }
+
+- private static <K, V> Map<V, K> invertMap(Map<K, V> map) {
++ private static <K, V> Map<V, K> invertMap(final Map<K, V> map) {
+ final Map<V, K> inverted = new IdentityHashMap<>(map.size());
+- for(Map.Entry<K, V> entry: map.entrySet()) {
++ for(final Map.Entry<K, V> entry: map.entrySet()) {
+ inverted.put(entry.getValue(), entry.getKey());
+ }
+ return Collections.unmodifiableMap(inverted);
+@@ -232,30 +239,63 @@
+ * {@link #isSubtype(Class, Class)}) as well as boxing conversion (JLS 5.1.7) optionally followed by widening
+ * reference conversion and unboxing conversion (JLS 5.1.8) optionally followed by widening primitive conversion.
+ *
+- * @param callSiteType the parameter type at the call site
+- * @param methodType the parameter type in the method declaration
+- * @return true if callSiteType is method invocation convertible to the methodType.
++ * @param sourceType the type being converted from (call site type for parameter types, method type for return types)
++ * @param targetType the parameter type being converted to (method type for parameter types, call site type for return types)
++ * @return true if source type is method invocation convertible to target type.
+ */
+- public static boolean isMethodInvocationConvertible(Class<?> callSiteType, Class<?> methodType) {
+- if(methodType.isAssignableFrom(callSiteType)) {
++ public static boolean isMethodInvocationConvertible(final Class<?> sourceType, final Class<?> targetType) {
++ if(targetType.isAssignableFrom(sourceType)) {
+ return true;
+ }
+- if(callSiteType.isPrimitive()) {
+- if(methodType.isPrimitive()) {
+- return isProperPrimitiveSubtype(callSiteType, methodType);
++ if(sourceType.isPrimitive()) {
++ if(targetType.isPrimitive()) {
++ return isProperPrimitiveSubtype(sourceType, targetType);
+ }
+ // Boxing + widening reference conversion
+- return methodType.isAssignableFrom(WRAPPER_TYPES.get(callSiteType));
++ assert WRAPPER_TYPES.get(sourceType) != null : sourceType.getName();
++ return targetType.isAssignableFrom(WRAPPER_TYPES.get(sourceType));
+ }
+- if(methodType.isPrimitive()) {
+- final Class<?> unboxedCallSiteType = PRIMITIVE_TYPES.get(callSiteType);
++ if(targetType.isPrimitive()) {
++ final Class<?> unboxedCallSiteType = PRIMITIVE_TYPES.get(sourceType);
+ return unboxedCallSiteType != null
+- && (unboxedCallSiteType == methodType || isProperPrimitiveSubtype(unboxedCallSiteType, methodType));
++ && (unboxedCallSiteType == targetType || isProperPrimitiveSubtype(unboxedCallSiteType, targetType));
+ }
+ return false;
+ }
+
+ /**
++ * Determines whether a type can be converted to another without losing any precision. As a special case,
++ * void is considered convertible only to Object and void, while anything can be converted to void. This
++ * is because a target type of void means we don't care about the value, so the conversion is always
++ * permissible.
++ *
++ * @param sourceType the source type
++ * @param targetType the target type
++ * @return true if lossless conversion is possible
++ */
++ public static boolean isConvertibleWithoutLoss(final Class<?> sourceType, final Class<?> targetType) {
++ if(targetType.isAssignableFrom(sourceType) || targetType == void.class) {
++ return true;
++ }
++ if(sourceType.isPrimitive()) {
++ if(sourceType == void.class) {
++ // Void should be losslessly representable by Object, either as null or as a custom value that
++ // can be set with DynamicLinkerFactory.setAutoConversionStrategy.
++ return targetType == Object.class;
++ }
++ if(targetType.isPrimitive()) {
++ return isProperPrimitiveLosslessSubtype(sourceType, targetType);
++ }
++ // Boxing + widening reference conversion
++ assert WRAPPER_TYPES.get(sourceType) != null : sourceType.getName();
++ return targetType.isAssignableFrom(WRAPPER_TYPES.get(sourceType));
++ }
++ // Can't convert from any non-primitive type to any primitive type without data loss because of null.
++ // Also, can't convert non-assignable reference types.
++ return false;
++ }
++
++ /**
+ * Determines whether one type can be potentially converted to another type at runtime. Allows a conversion between
+ * any subtype and supertype in either direction, and also allows a conversion between any two primitive types, as
+ * well as between any primitive type and any reference type that can hold a boxed primitive.
+@@ -264,9 +304,9 @@
+ * @param methodType the parameter type in the method declaration
+ * @return true if callSiteType is potentially convertible to the methodType.
+ */
+- public static boolean isPotentiallyConvertible(Class<?> callSiteType, Class<?> methodType) {
++ public static boolean isPotentiallyConvertible(final Class<?> callSiteType, final Class<?> methodType) {
+ // Widening or narrowing reference conversion
+- if(methodType.isAssignableFrom(callSiteType) || callSiteType.isAssignableFrom(methodType)) {
++ if(areAssignable(callSiteType, methodType)) {
+ return true;
+ }
+ if(callSiteType.isPrimitive()) {
+@@ -287,6 +327,16 @@
+ }
+
+ /**
++ * Returns true if either of the types is assignable from the other.
++ * @param c1 one of the types
++ * @param c2 another one of the types
++ * @return true if either c1 is assignable from c2 or c2 is assignable from c1.
++ */
++ public static boolean areAssignable(final Class<?> c1, final Class<?> c2) {
++ return c1.isAssignableFrom(c2) || c2.isAssignableFrom(c1);
++ }
++
++ /**
+ * Determines whether one type is a subtype of another type, as per JLS 4.10 "Subtyping". Note: this is not strict
+ * or proper subtype, therefore true is also returned for identical types; to be completely precise, it allows
+ * identity conversion (JLS 5.1.1), widening primitive conversion (JLS 5.1.2) and widening reference conversion (JLS
+@@ -297,7 +347,7 @@
+ * @return true if subType can be converted by identity conversion, widening primitive conversion, or widening
+ * reference conversion to superType.
+ */
+- public static boolean isSubtype(Class<?> subType, Class<?> superType) {
++ public static boolean isSubtype(final Class<?> subType, final Class<?> superType) {
+ // Covers both JLS 4.10.2 "Subtyping among Class and Interface Types"
+ // and JLS 4.10.3 "Subtyping among Array Types", as well as primitive
+ // type identity.
+@@ -328,7 +378,7 @@
+ * @param superType the supposed supertype
+ * @return true if subType is a proper (not identical to) primitive subtype of the superType
+ */
+- private static boolean isProperPrimitiveSubtype(Class<?> subType, Class<?> superType) {
++ private static boolean isProperPrimitiveSubtype(final Class<?> subType, final Class<?> superType) {
+ if(superType == boolean.class || subType == boolean.class) {
+ return false;
+ }
+@@ -353,6 +403,37 @@
+ return false;
+ }
+
++ /**
++ * Similar to {@link #isProperPrimitiveSubtype(Class, Class)}, except it disallows conversions from int and long to
++ * float, and from long to double, as those can lose precision. It also disallows conversion from and to char and
++ * anything else (similar to boolean) as char is not meant to be an arithmetic type.
++ * @param subType the supposed subtype
++ * @param superType the supposed supertype
++ * @return true if subType is a proper (not identical to) primitive subtype of the superType that can be represented
++ * by the supertype without no precision loss.
++ */
++ private static boolean isProperPrimitiveLosslessSubtype(final Class<?> subType, final Class<?> superType) {
++ if(superType == boolean.class || subType == boolean.class) {
++ return false;
++ }
++ if(superType == char.class || subType == char.class) {
++ return false;
++ }
++ if(subType == byte.class) {
++ return true;
++ }
++ if(subType == short.class) {
++ return superType != byte.class;
++ }
++ if(subType == int.class) {
++ return superType == long.class || superType == double.class;
++ }
++ if(subType == float.class) {
++ return superType == double.class;
++ }
++ return false;
++ }
++
+ private static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE_TYPES = createWrapperToPrimitiveTypes();
+
+ private static Map<Class<?>, Class<?>> createWrapperToPrimitiveTypes() {
+@@ -384,13 +465,13 @@
+ return classes.keySet();
+ }
+
+- private static void addClassHierarchy(Map<Class<?>, Class<?>> map, Class<?> clazz) {
++ private static void addClassHierarchy(final Map<Class<?>, Class<?>> map, final Class<?> clazz) {
+ if(clazz == null) {
+ return;
+ }
+ map.put(clazz, clazz);
+ addClassHierarchy(map, clazz.getSuperclass());
+- for(Class<?> itf: clazz.getInterfaces()) {
++ for(final Class<?> itf: clazz.getInterfaces()) {
+ addClassHierarchy(map, itf);
+ }
+ }
+@@ -402,7 +483,7 @@
+ * @return true if the class can be assigned from any boxed primitive. Basically, it is true if the class is any
+ * primitive wrapper class, or a superclass or superinterface of any primitive wrapper class.
+ */
+- private static boolean isAssignableFromBoxedPrimitive(Class<?> clazz) {
++ private static boolean isAssignableFromBoxedPrimitive(final Class<?> clazz) {
+ return PRIMITIVE_WRAPPER_TYPES.contains(clazz);
+ }
+
+@@ -413,7 +494,7 @@
+ * @return the class representing the primitive type, or null if the name does not correspond to a primitive type
+ * or is "void".
+ */
+- public static Class<?> getPrimitiveTypeByName(String name) {
++ public static Class<?> getPrimitiveTypeByName(final String name) {
+ return PRIMITIVE_TYPES_BY_NAME.get(name);
+ }
+
+@@ -424,7 +505,7 @@
+ * @param wrapperType the class object representing a wrapper for a primitive type
+ * @return the class object representing the primitive type, or null if the passed class is not a primitive wrapper.
+ */
+- public static Class<?> getPrimitiveType(Class<?> wrapperType) {
++ public static Class<?> getPrimitiveType(final Class<?> wrapperType) {
+ return WRAPPER_TO_PRIMITIVE_TYPES.get(wrapperType);
+ }
+
+@@ -436,7 +517,16 @@
+ * @param primitiveType the class object representing a primitive type
+ * @return the class object representing the wrapper type, or null if the passed class is not a primitive.
+ */
+- public static Class<?> getWrapperType(Class<?> primitiveType) {
++ public static Class<?> getWrapperType(final Class<?> primitiveType) {
+ return WRAPPER_TYPES.get(primitiveType);
+ }
++
++ /**
++ * Returns true if the passed type is a wrapper for a primitive type.
++ * @param type the examined type
++ * @return true if the passed type is a wrapper for a primitive type.
++ */
++ public static boolean isWrapperType(final Class<?> type) {
++ return PRIMITIVE_TYPES.containsKey(type);
++ }
+ }
+--- ./nashorn/src/jdk/internal/dynalink/support/UnnamedDynCallSiteDescriptor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/UnnamedDynCallSiteDescriptor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -90,7 +90,7 @@
+ private final MethodType methodType;
+ private final String op;
+
+- UnnamedDynCallSiteDescriptor(String op, MethodType methodType) {
++ UnnamedDynCallSiteDescriptor(final String op, final MethodType methodType) {
+ this.op = op;
+ this.methodType = methodType;
+ }
+@@ -105,7 +105,7 @@
+ }
+
+ @Override
+- public String getNameToken(int i) {
++ public String getNameToken(final int i) {
+ switch(i) {
+ case 0: return "dyn";
+ case 1: return op;
+@@ -119,7 +119,7 @@
+ }
+
+ @Override
+- public CallSiteDescriptor changeMethodType(MethodType newMethodType) {
++ public CallSiteDescriptor changeMethodType(final MethodType newMethodType) {
+ return CallSiteDescriptorFactory.getCanonicalPublicDescriptor(new UnnamedDynCallSiteDescriptor(op,
+ newMethodType));
+ }
+--- ./nashorn/src/jdk/internal/dynalink/support/messages.properties Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/internal/dynalink/support/messages.properties Wed Feb 04 12:14:47 2015 -0800
+@@ -83,4 +83,4 @@
+ isOfClassGuardAlwaysFalse=isOfClass guard for {0} in position {1} in method type {2} at {3} will always return false
+
+ isArrayGuardAlwaysTrue=isArray guard in position {0} in method type {1} at {2} will always return true
+-isArrayGuardAlwaysFalse=isArray guard in position {0} in method type {1} at {2} will always return false
+\ No newline at end of file
++isArrayGuardAlwaysFalse=isArray guard in position {0} in method type {1} at {2} will always return false
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/api/scripting/ClassFilter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.api.scripting;
++
++/**
++ * Class filter (optional) to be used by nashorn script engine.
++ * jsr-223 program embedding nashorn script can set ClassFilter instance
++ * to be used when an engine instance is created.
++ */
++public interface ClassFilter {
++ /**
++ * Should the Java class of the specified name be exposed to scripts?
++ * @param className is the fully qualified name of the java class being
++ * checked. This will not be null. Only non-array class names will be
++ * passed.
++ * @return true if the java class can be exposed to scripts false otherwise
++ */
++ public boolean exposeToScripts(String className);
++}
+--- ./nashorn/src/jdk/nashorn/api/scripting/Formatter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/api/scripting/Formatter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -65,8 +65,8 @@
+
+ while (m.find()) {
+ int index = index(m.group(1));
+- boolean previous = isPreviousArgument(m.group(2));
+- char conversion = m.group(6).charAt(0);
++ final boolean previous = isPreviousArgument(m.group(2));
++ final char conversion = m.group(6).charAt(0);
+
+ // skip over some formats
+ if (index < 0 || previous
+@@ -85,7 +85,7 @@
+ }
+
+ // current argument
+- Object arg = args[index - 1];
++ final Object arg = args[index - 1];
+
+ // for date we convert double to long
+ if (m.group(5) != null) {
+--- ./nashorn/src/jdk/nashorn/api/scripting/JSObject.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/api/scripting/JSObject.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,7 +26,6 @@
+ package jdk.nashorn.api.scripting;
+
+ import java.util.Collection;
+-import java.util.Collections;
+ import java.util.Set;
+
+ /**
+--- ./nashorn/src/jdk/nashorn/api/scripting/NashornException.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/api/scripting/NashornException.java Wed Feb 04 12:14:47 2015 -0800
+@@ -53,9 +53,6 @@
+ // underlying ECMA error object - lazily initialized
+ private Object ecmaError;
+
+- /** script source name used for "engine.js" */
+- public static final String ENGINE_SCRIPT_SOURCE_NAME = "nashorn:engine/resources/engine.js";
+-
+ /**
+ * Constructor
+ *
+@@ -182,7 +179,7 @@
+ if (ECMAErrors.isScriptFrame(st)) {
+ final String className = "<" + st.getFileName() + ">";
+ String methodName = st.getMethodName();
+- if (methodName.equals(CompilerConstants.RUN_SCRIPT.symbolName())) {
++ if (methodName.equals(CompilerConstants.PROGRAM.symbolName())) {
+ methodName = "<program>";
+ }
+
+@@ -224,10 +221,22 @@
+ return buf.toString();
+ }
+
++ /**
++ * Get the thrown object. Subclass responsibility
++ * @return thrown object
++ */
+ protected Object getThrown() {
+ return null;
+ }
+
++ /**
++ * Initialization function for ECMA errors. Stores the error
++ * in the ecmaError field of this class. It is only initialized
++ * once, and then reused
++ *
++ * @param global the global
++ * @return initialized exception
++ */
+ protected NashornException initEcmaError(final ScriptObject global) {
+ if (ecmaError != null) {
+ return this; // initialized already!
+--- ./nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,8 +25,6 @@
+
+ package jdk.nashorn.api.scripting;
+
+-import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
+-import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+ import static jdk.nashorn.internal.runtime.Source.sourceFor;
+
+ import java.io.IOException;
+@@ -34,13 +32,10 @@
+ import java.lang.invoke.MethodHandles;
+ import java.lang.reflect.Method;
+ import java.lang.reflect.Modifier;
+-import java.net.URL;
+ import java.security.AccessControlContext;
+ import java.security.AccessController;
+ import java.security.Permissions;
+ import java.security.PrivilegedAction;
+-import java.security.PrivilegedActionException;
+-import java.security.PrivilegedExceptionAction;
+ import java.security.ProtectionDomain;
+ import java.text.MessageFormat;
+ import java.util.Locale;
+@@ -58,7 +53,6 @@
+ import jdk.nashorn.internal.objects.Global;
+ import jdk.nashorn.internal.runtime.Context;
+ import jdk.nashorn.internal.runtime.ErrorManager;
+-import jdk.nashorn.internal.runtime.Property;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+@@ -98,12 +92,6 @@
+ // This is the initial default Nashorn global object.
+ // This is used as "shared" global if above option is true.
+ private final Global global;
+- // initialized bit late to be made 'final'.
+- // Property object for "context" property of global object.
+- private volatile Property contextProperty;
+-
+- // default options passed to Nashorn Options object
+- private static final String[] DEFAULT_OPTIONS = new String[] { "-doe" };
+
+ // Nashorn script engine error message management
+ private static final String MESSAGES_RESOURCE = "jdk.nashorn.api.scripting.resources.Messages";
+@@ -122,36 +110,8 @@
+ }
+ }
+
+- // load engine.js
+- @SuppressWarnings("resource")
+- private static Source loadEngineJSSource() {
+- final String script = "resources/engine.js";
+- try {
+- return AccessController.doPrivileged(
+- new PrivilegedExceptionAction<Source>() {
+- @Override
+- public Source run() throws IOException {
+- final URL url = NashornScriptEngine.class.getResource(script);
+- return sourceFor(NashornException.ENGINE_SCRIPT_SOURCE_NAME, url);
+- }
+- }
+- );
+- } catch (final PrivilegedActionException e) {
+- if (Context.DEBUG) {
+- e.printStackTrace();
+- }
+- throw new RuntimeException(e);
+- }
+- }
+-
+- // Source object for engine.js
+- private static final Source ENGINE_SCRIPT_SRC = loadEngineJSSource();
+-
+- NashornScriptEngine(final NashornScriptEngineFactory factory, final ClassLoader appLoader) {
+- this(factory, DEFAULT_OPTIONS, appLoader);
+- }
+-
+- NashornScriptEngine(final NashornScriptEngineFactory factory, final String[] args, final ClassLoader appLoader) {
++ NashornScriptEngine(final NashornScriptEngineFactory factory, final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) {
++ assert args != null : "null argument array";
+ this.factory = factory;
+ final Options options = new Options("nashorn");
+ options.process(args);
+@@ -163,7 +123,7 @@
+ @Override
+ public Context run() {
+ try {
+- return new Context(options, errMgr, appLoader);
++ return new Context(options, errMgr, appLoader, classFilter);
+ } catch (final RuntimeException e) {
+ if (Context.DEBUG) {
+ e.printStackTrace();
+@@ -249,39 +209,12 @@
+ return getInterfaceInner(thiz, clazz);
+ }
+
+- // These are called from the "engine.js" script
+-
+- /**
+- * This hook is used to search js global variables exposed from Java code.
+- *
+- * @param self 'this' passed from the script
+- * @param ctxt current ScriptContext in which name is searched
+- * @param name name of the variable searched
+- * @return the value of the named variable
+- */
+- public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) {
+- if (ctxt != null) {
+- final int scope = ctxt.getAttributesScope(name);
+- final Global ctxtGlobal = getNashornGlobalFrom(ctxt);
+- if (scope != -1) {
+- return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal);
+- }
+-
+- if (self == UNDEFINED) {
+- // scope access and so throw ReferenceError
+- throw referenceError(ctxtGlobal, "not.defined", name);
+- }
+- }
+-
+- return UNDEFINED;
+- }
+-
+ // Implementation only below this point
+
+ private static Source makeSource(final Reader reader, final ScriptContext ctxt) throws ScriptException {
+ try {
+ return sourceFor(getScriptName(ctxt), reader);
+- } catch (IOException e) {
++ } catch (final IOException e) {
+ throw new ScriptException(e);
+ }
+ }
+@@ -296,6 +229,8 @@
+ }
+
+ private <T> T getInterfaceInner(final Object thiz, final Class<T> clazz) {
++ assert !(thiz instanceof ScriptObject) : "raw ScriptObject not expected here";
++
+ if (clazz == null || !clazz.isInterface()) {
+ throw new IllegalArgumentException(getMessage("interface.class.expected"));
+ }
+@@ -321,17 +256,6 @@
+ if (! isOfContext(realGlobal, nashornContext)) {
+ throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
+ }
+- } else if (thiz instanceof ScriptObject) {
+- // called from script code.
+- realSelf = (ScriptObject)thiz;
+- realGlobal = Context.getGlobal();
+- if (realGlobal == null) {
+- throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
+- }
+-
+- if (! isOfContext(realGlobal, nashornContext)) {
+- throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
+- }
+ }
+
+ if (realSelf == null) {
+@@ -380,7 +304,7 @@
+ }
+
+ // Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it!
+- Object scope = bindings.get(NASHORN_GLOBAL);
++ final Object scope = bindings.get(NASHORN_GLOBAL);
+ if (scope instanceof ScriptObjectMirror) {
+ final Global glob = globalFromMirror((ScriptObjectMirror)scope);
+ if (glob != null) {
+@@ -397,7 +321,7 @@
+
+ // Retrieve nashorn Global object from a given ScriptObjectMirror
+ private Global globalFromMirror(final ScriptObjectMirror mirror) {
+- ScriptObject sobj = mirror.getScriptObject();
++ final ScriptObject sobj = mirror.getScriptObject();
+ if (sobj instanceof Global && isOfContext((Global)sobj, nashornContext)) {
+ return (Global)sobj;
+ }
+@@ -427,49 +351,15 @@
+ }
+ }, CREATE_GLOBAL_ACC_CTXT);
+
+- nashornContext.initGlobal(newGlobal);
++ nashornContext.initGlobal(newGlobal, this);
++ newGlobal.setScriptContext(ctxt);
+
+- final int NON_ENUMERABLE_CONSTANT = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE;
+- // current ScriptContext exposed as "context"
+- // "context" is non-writable from script - but script engine still
+- // needs to set it and so save the context Property object
+- contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, ctxt);
+- // current ScriptEngine instance exposed as "engine". We added @SuppressWarnings("LeakingThisInConstructor") as
+- // NetBeans identifies this assignment as such a leak - this is a false positive as we're setting this property
+- // in the Global of a Context we just created - both the Context and the Global were just created and can not be
+- // seen from another thread outside of this constructor.
+- newGlobal.addOwnProperty("engine", NON_ENUMERABLE_CONSTANT, this);
+- // global script arguments with undefined value
+- newGlobal.addOwnProperty("arguments", Property.NOT_ENUMERABLE, UNDEFINED);
+- // file name default is null
+- newGlobal.addOwnProperty(ScriptEngine.FILENAME, Property.NOT_ENUMERABLE, null);
+- // evaluate engine.js initialization script this new global object
+- try {
+- evalImpl(compileImpl(ENGINE_SCRIPT_SRC, newGlobal), ctxt, newGlobal);
+- } catch (final ScriptException exp) {
+- throw new RuntimeException(exp);
+- }
+ return newGlobal;
+ }
+
+- // scripts should see "context" and "engine" as variables in the given global object
+- private void setContextVariables(final Global ctxtGlobal, final ScriptContext ctxt) {
+- // set "context" global variable via contextProperty - because this
+- // property is non-writable
+- contextProperty.setObjectValue(ctxtGlobal, ctxtGlobal, ctxt, false);
+- Object args = ScriptObjectMirror.unwrap(ctxt.getAttribute("arguments"), ctxtGlobal);
+- if (args == null || args == UNDEFINED) {
+- args = ScriptRuntime.EMPTY_ARRAY;
+- }
+- // if no arguments passed, expose it
+- if (! (args instanceof ScriptObject)) {
+- args = ctxtGlobal.wrapAsObject(args);
+- ctxtGlobal.set("arguments", args, false);
+- }
+- }
+-
+ private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
+ name.getClass(); // null check
++ assert !(selfObject instanceof ScriptObject) : "raw ScriptObject not expected here";
+
+ Global invokeGlobal = null;
+ ScriptObjectMirror selfMirror = null;
+@@ -479,20 +369,6 @@
+ throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
+ }
+ invokeGlobal = selfMirror.getHomeGlobal();
+- } else if (selfObject instanceof ScriptObject) {
+- // invokeMethod called from script code - in which case we may get 'naked' ScriptObject
+- // Wrap it with oldGlobal to make a ScriptObjectMirror for the same.
+- final Global oldGlobal = Context.getGlobal();
+- invokeGlobal = oldGlobal;
+- if (oldGlobal == null) {
+- throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
+- }
+-
+- if (! isOfContext(oldGlobal, nashornContext)) {
+- throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
+- }
+-
+- selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal);
+ } else if (selfObject == null) {
+ // selfObject is null => global function call
+ final Global ctxtGlobal = getNashornGlobalFrom(context);
+@@ -525,7 +401,7 @@
+ return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt));
+ }
+
+- private Object evalImpl(final Context.MultiGlobalCompiledScript mgcs, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
++ private static Object evalImpl(final Context.MultiGlobalCompiledScript mgcs, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
+ final Global oldGlobal = Context.getGlobal();
+ final boolean globalChanged = (oldGlobal != ctxtGlobal);
+ try {
+@@ -534,11 +410,7 @@
+ }
+
+ final ScriptFunction script = mgcs.getFunction(ctxtGlobal);
+-
+- // set ScriptContext variables if ctxt is non-null
+- if (ctxt != null) {
+- setContextVariables(ctxtGlobal, ctxt);
+- }
++ ctxtGlobal.setScriptContext(ctxt);
+ return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
+ } catch (final Exception e) {
+ throwAsScriptException(e, ctxtGlobal);
+@@ -550,7 +422,7 @@
+ }
+ }
+
+- private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
++ private static Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
+ if (script == null) {
+ return null;
+ }
+@@ -561,10 +433,7 @@
+ Context.setGlobal(ctxtGlobal);
+ }
+
+- // set ScriptContext variables if ctxt is non-null
+- if (ctxt != null) {
+- setContextVariables(ctxtGlobal, ctxt);
+- }
++ ctxtGlobal.setScriptContext(ctxt);
+ return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
+ } catch (final Exception e) {
+ throwAsScriptException(e, ctxtGlobal);
+@@ -671,7 +540,7 @@
+ continue;
+ }
+
+- Object obj = sobj.get(method.getName());
++ final Object obj = sobj.get(method.getName());
+ if (! (obj instanceof ScriptFunction)) {
+ return false;
+ }
+--- ./nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Wed Feb 04 12:14:47 2015 -0800
+@@ -135,10 +135,13 @@
+ return sb.toString();
+ }
+
++ // default options passed to Nashorn script engine
++ private static final String[] DEFAULT_OPTIONS = new String[] { "-doe" };
++
+ @Override
+ public ScriptEngine getScriptEngine() {
+ try {
+- return new NashornScriptEngine(this, getAppClassLoader());
++ return new NashornScriptEngine(this, DEFAULT_OPTIONS, getAppClassLoader(), null);
+ } catch (final RuntimeException e) {
+ if (Context.DEBUG) {
+ e.printStackTrace();
+@@ -152,10 +155,27 @@
+ *
+ * @param appLoader class loader to be used as script "app" class loader.
+ * @return newly created script engine.
++ * @throws SecurityException
++ * if the security manager's {@code checkPermission}
++ * denies {@code RuntimePermission("nashorn.setConfig")}
+ */
+ public ScriptEngine getScriptEngine(final ClassLoader appLoader) {
+- checkConfigPermission();
+- return new NashornScriptEngine(this, appLoader);
++ return newEngine(DEFAULT_OPTIONS, appLoader, null);
++ }
++
++ /**
++ * Create a new Script engine initialized by given class filter.
++ *
++ * @param classFilter class filter to use.
++ * @return newly created script engine.
++ * @throws NullPointerException if {@code classFilter} is {@code null}
++ * @throws SecurityException
++ * if the security manager's {@code checkPermission}
++ * denies {@code RuntimePermission("nashorn.setConfig")}
++ */
++ public ScriptEngine getScriptEngine(final ClassFilter classFilter) {
++ classFilter.getClass(); // null check
++ return newEngine(DEFAULT_OPTIONS, getAppClassLoader(), classFilter);
+ }
+
+ /**
+@@ -163,10 +183,14 @@
+ *
+ * @param args arguments array passed to script engine.
+ * @return newly created script engine.
++ * @throws NullPointerException if {@code args} is {@code null}
++ * @throws SecurityException
++ * if the security manager's {@code checkPermission}
++ * denies {@code RuntimePermission("nashorn.setConfig")}
+ */
+- public ScriptEngine getScriptEngine(final String[] args) {
+- checkConfigPermission();
+- return new NashornScriptEngine(this, args, getAppClassLoader());
++ public ScriptEngine getScriptEngine(final String... args) {
++ args.getClass(); // null check
++ return newEngine(args, getAppClassLoader(), null);
+ }
+
+ /**
+@@ -175,10 +199,44 @@
+ * @param args arguments array passed to script engine.
+ * @param appLoader class loader to be used as script "app" class loader.
+ * @return newly created script engine.
++ * @throws NullPointerException if {@code args} is {@code null}
++ * @throws SecurityException
++ * if the security manager's {@code checkPermission}
++ * denies {@code RuntimePermission("nashorn.setConfig")}
+ */
+ public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader) {
++ args.getClass(); // null check
++ return newEngine(args, appLoader, null);
++ }
++
++ /**
++ * Create a new Script engine initialized by given arguments.
++ *
++ * @param args arguments array passed to script engine.
++ * @param appLoader class loader to be used as script "app" class loader.
++ * @param classFilter class filter to use.
++ * @return newly created script engine.
++ * @throws NullPointerException if {@code args} or {@code classFilter} is {@code null}
++ * @throws SecurityException
++ * if the security manager's {@code checkPermission}
++ * denies {@code RuntimePermission("nashorn.setConfig")}
++ */
++ public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) {
++ args.getClass(); // null check
++ classFilter.getClass(); // null check
++ return newEngine(args, appLoader, classFilter);
++ }
++
++ private ScriptEngine newEngine(final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) {
+ checkConfigPermission();
+- return new NashornScriptEngine(this, args, appLoader);
++ try {
++ return new NashornScriptEngine(this, args, appLoader, classFilter);
++ } catch (final RuntimeException e) {
++ if (Context.DEBUG) {
++ e.printStackTrace();
++ }
++ throw e;
++ }
+ }
+
+ // -- Internals only below this point
+@@ -220,7 +278,7 @@
+ // Revisit: script engine implementation needs the capability to
+ // find the class loader of the context in which the script engine
+ // is running so that classes will be found and loaded properly
+- ClassLoader ccl = Thread.currentThread().getContextClassLoader();
++ final ClassLoader ccl = Thread.currentThread().getContextClassLoader();
+ return (ccl == null)? NashornScriptEngineFactory.class.getClassLoader() : ccl;
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Wed Feb 04 12:14:47 2015 -0800
+@@ -43,13 +43,14 @@
+ import java.util.concurrent.Callable;
+ import javax.script.Bindings;
+ import jdk.nashorn.internal.objects.Global;
+-import jdk.nashorn.internal.runtime.arrays.ArrayData;
+ import jdk.nashorn.internal.runtime.ConsString;
+ import jdk.nashorn.internal.runtime.Context;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
++import jdk.nashorn.internal.runtime.arrays.ArrayData;
++import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+
+ /**
+ * Mirror object that wraps a given Nashorn Script object.
+@@ -164,11 +165,17 @@
+ return Context.getContext();
+ }
+ }, GET_CONTEXT_ACC_CTXT);
+- return wrap(context.eval(global, s, null, null, false), global);
++ return wrap(context.eval(global, s, sobj, null, false), global);
+ }
+ });
+ }
+
++ /**
++ * Call member function
++ * @param functionName function name
++ * @param args arguments
++ * @return return value of function
++ */
+ public Object callMember(final String functionName, final Object... args) {
+ functionName.getClass(); // null check
+ final Global oldGlobal = Context.getGlobal();
+@@ -255,7 +262,7 @@
+ public void setSlot(final int index, final Object value) {
+ inGlobal(new Callable<Void>() {
+ @Override public Void call() {
+- sobj.set(index, unwrap(value, global), strict);
++ sobj.set(index, unwrap(value, global), getCallSiteFlags());
+ return null;
+ }
+ });
+@@ -419,7 +426,7 @@
+ for (final Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
+ final Object value = entry.getValue();
+ final Object modValue = globalChanged? wrap(value, oldGlobal) : value;
+- sobj.set(entry.getKey(), unwrap(modValue, global), strict);
++ sobj.set(entry.getKey(), unwrap(modValue, global), getCallSiteFlags());
+ }
+ return null;
+ }
+@@ -709,6 +716,23 @@
+ return newArgs;
+ }
+
++ /**
++ * Are the given objects mirrors to same underlying object?
++ *
++ * @param obj1 first object
++ * @param obj2 second object
++ * @return true if obj1 and obj2 are identical script objects or mirrors of it.
++ */
++ public static boolean identical(final Object obj1, final Object obj2) {
++ final Object o1 = (obj1 instanceof ScriptObjectMirror)?
++ ((ScriptObjectMirror)obj1).sobj : obj1;
++
++ final Object o2 = (obj2 instanceof ScriptObjectMirror)?
++ ((ScriptObjectMirror)obj2).sobj : obj2;
++
++ return o1 == o2;
++ }
++
+ // package-privates below this.
+
+ ScriptObjectMirror(final ScriptObject sobj, final Global global) {
+@@ -729,10 +753,14 @@
+ return global;
+ }
+
+- static Object translateUndefined(Object obj) {
++ static Object translateUndefined(final Object obj) {
+ return (obj == ScriptRuntime.UNDEFINED)? null : obj;
+ }
+
++ private int getCallSiteFlags() {
++ return strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0;
++ }
++
+ // internals only below this.
+ private <V> V inGlobal(final Callable<V> callable) {
+ final Global oldGlobal = Context.getGlobal();
+--- ./nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,14 +25,16 @@
+
+ package jdk.nashorn.api.scripting;
+
++import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
++
+ import java.lang.invoke.MethodHandle;
+ import jdk.internal.dynalink.beans.StaticClass;
+ import jdk.internal.dynalink.linker.LinkerServices;
+-import jdk.nashorn.internal.runtime.linker.Bootstrap;
+ import jdk.nashorn.internal.runtime.Context;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
++import jdk.nashorn.internal.runtime.linker.Bootstrap;
+
+ /**
+ * Utilities that are to be called from script code.
+@@ -69,12 +71,12 @@
+ * Create a wrapper function that calls {@code func} synchronized on {@code sync} or, if that is undefined,
+ * {@code self}. Used to implement "sync" function in resources/mozilla_compat.js.
+ *
+- * @param func the function to invoke
++ * @param func the function to wrap
+ * @param sync the object to synchronize on
+ * @return a synchronizing wrapper function
+ */
+ public static Object makeSynchronizedFunction(final ScriptFunction func, final Object sync) {
+- return func.makeSynchronizedFunction(sync);
++ return func.makeSynchronizedFunction(unwrap(sync));
+ }
+
+ /**
+@@ -83,12 +85,8 @@
+ * @param obj object to be wrapped
+ * @return wrapped object
+ */
+- public static Object wrap(final Object obj) {
+- if (obj instanceof ScriptObject) {
+- return ScriptObjectMirror.wrap(obj, Context.getGlobal());
+- }
+-
+- return obj;
++ public static ScriptObjectMirror wrap(final ScriptObject obj) {
++ return (ScriptObjectMirror) ScriptObjectMirror.wrap(obj, Context.getGlobal());
+ }
+
+ /**
+@@ -155,14 +153,15 @@
+ }
+
+ final LinkerServices linker = Bootstrap.getLinkerServices();
+- final MethodHandle converter = linker.getTypeConverter(obj.getClass(), clazz);
++ final Object objToConvert = unwrap(obj);
++ final MethodHandle converter = linker.getTypeConverter(objToConvert.getClass(), clazz);
+ if (converter == null) {
+ // no supported conversion!
+ throw new UnsupportedOperationException("conversion not supported");
+ }
+
+ try {
+- return converter.invoke(obj);
++ return converter.invoke(objToConvert);
+ } catch (final RuntimeException | Error e) {
+ throw e;
+ } catch (final Throwable t) {
+--- ./nashorn/src/jdk/nashorn/api/scripting/URLReader.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/api/scripting/URLReader.java Wed Feb 04 12:14:47 2015 -0800
+@@ -81,7 +81,7 @@
+ }
+
+ @Override
+- public int read(char cbuf[], int off, int len) throws IOException {
++ public int read(final char cbuf[], final int off, final int len) throws IOException {
+ return getReader().read(cbuf, off, len);
+ }
+
+--- ./nashorn/src/jdk/nashorn/api/scripting/resources/engine.js Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,101 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-/**
+- * This script file is executed by script engine at the construction
+- * of the every new Global object. The functions here assume global variables
+- * "context" of type javax.script.ScriptContext and "engine" of the type
+- * jdk.nashorn.api.scripting.NashornScriptEngine.
+- **/
+-
+-Object.defineProperty(this, "__noSuchProperty__", {
+- configurable: true,
+- enumerable: false,
+- writable: true,
+- value: function (name) {
+- 'use strict';
+- return engine.__noSuchProperty__(this, context, name);
+- }
+-});
+-
+-function print() {
+- var writer = context != null? context.writer : engine.context.writer;
+- if (! (writer instanceof java.io.PrintWriter)) {
+- writer = new java.io.PrintWriter(writer);
+- }
+-
+- var buf = new java.lang.StringBuilder();
+- for (var i = 0; i < arguments.length; i++) {
+- if (i != 0) {
+- buf.append(' ');
+- }
+- buf.append(String(arguments[i]));
+- }
+- writer.println(buf.toString());
+-}
+-
+-/**
+- * This is C-like printf
+- *
+- * @param format string to format the rest of the print items
+- * @param args variadic argument list
+- */
+-Object.defineProperty(this, "printf", {
+- configurable: true,
+- enumerable: false,
+- writable: true,
+- value: function (format, args/*, more args*/) {
+- print(sprintf.apply(this, arguments));
+- }
+-});
+-
+-/**
+- * This is C-like sprintf
+- *
+- * @param format string to format the rest of the print items
+- * @param args variadic argument list
+- */
+-Object.defineProperty(this, "sprintf", {
+- configurable: true,
+- enumerable: false,
+- writable: true,
+- value: function (format, args/*, more args*/) {
+- var len = arguments.length - 1;
+- var array = [];
+-
+- if (len < 0) {
+- return "";
+- }
+-
+- for (var i = 0; i < len; i++) {
+- if (arguments[i+1] instanceof Date) {
+- array[i] = arguments[i+1].getTime();
+- } else {
+- array[i] = arguments[i+1];
+- }
+- }
+-
+- array = Java.to(array);
+- return Packages.jdk.nashorn.api.scripting.ScriptUtils.format(format, array);
+- }
+-});
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/AssertsEnabled.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal;
++
++/**
++ * Class that exposes the current state of asserts.
++ */
++@SuppressWarnings("all")
++public final class AssertsEnabled {
++ private static boolean assertsEnabled = false;
++ static {
++ assert assertsEnabled = true; // Intentional side effect
++ }
++
++ /**
++ * Returns true if asserts are enabled
++ * @return true if asserts are enabled
++ */
++ public static boolean assertsEnabled() {
++ return assertsEnabled;
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/IntDeque.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,87 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal;
++
++/**
++ * Small helper class for fast int deques
++ */
++public class IntDeque {
++ private int[] deque = new int[16];
++ private int nextFree = 0;
++
++ /**
++ * Push an int value
++ * @param value value
++ */
++ public void push(final int value) {
++ if (nextFree == deque.length) {
++ final int[] newDeque = new int[nextFree * 2];
++ System.arraycopy(deque, 0, newDeque, 0, nextFree);
++ deque = newDeque;
++ }
++ deque[nextFree++] = value;
++ }
++
++ /**
++ * Pop an int value
++ * @return value
++ */
++ public int pop() {
++ return deque[--nextFree];
++ }
++
++ /**
++ * Peek
++ * @return top value
++ */
++ public int peek() {
++ return deque[nextFree - 1];
++ }
++
++ /**
++ * Get the value of the top element and increment it.
++ * @return top value
++ */
++ public int getAndIncrement() {
++ return deque[nextFree - 1]++;
++ }
++
++ /**
++ * Decrement the value of the top element and return it.
++ * @return decremented top value
++ */
++ public int decrementAndGet() {
++ return --deque[nextFree - 1];
++ }
++
++ /**
++ * Check if deque is empty
++ * @return true if empty
++ */
++ public boolean isEmpty() {
++ return nextFree == 0;
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/ApplySpecialization.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,397 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
++
++import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS_VAR;
++import static jdk.nashorn.internal.codegen.CompilerConstants.EXPLODED_ARGUMENT_PREFIX;
++
++import java.lang.invoke.MethodType;
++import java.net.URL;
++import java.util.ArrayDeque;
++import java.util.ArrayList;
++import java.util.Deque;
++import java.util.HashSet;
++import java.util.List;
++import java.util.Set;
++import jdk.nashorn.internal.ir.AccessNode;
++import jdk.nashorn.internal.ir.CallNode;
++import jdk.nashorn.internal.ir.Expression;
++import jdk.nashorn.internal.ir.FunctionNode;
++import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
++import jdk.nashorn.internal.ir.IdentNode;
++import jdk.nashorn.internal.ir.LexicalContext;
++import jdk.nashorn.internal.ir.Node;
++import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++import jdk.nashorn.internal.objects.Global;
++import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
++import jdk.nashorn.internal.runtime.options.Options;
++
++/**
++ * An optimization that attempts to turn applies into calls. This pattern
++ * is very common for fake class instance creation, and apply
++ * introduces expensive args collection and boxing
++ *
++ * <pre>
++ * var Class = {
++ * create: function() {
++ * return function() { //vararg
++ * this.initialize.apply(this, arguments);
++ * }
++ * }
++ * };
++ *
++ * Color = Class.create();
++ *
++ * Color.prototype = {
++ * red: 0, green: 0, blue: 0,
++ * initialize: function(r,g,b) {
++ * this.red = r;
++ * this.green = g;
++ * this.blue = b;
++ * }
++ * }
++ *
++ * new Color(17, 47, 11);
++ * </pre>
++ */
++
++@Logger(name="apply2call")
++public final class ApplySpecialization extends NodeVisitor<LexicalContext> implements Loggable {
++
++ private static final boolean USE_APPLY2CALL = Options.getBooleanProperty("nashorn.apply2call", true);
++
++ private final DebugLogger log;
++
++ private final Compiler compiler;
++
++ private final Set<Integer> changed = new HashSet<>();
++
++ private final Deque<List<IdentNode>> explodedArguments = new ArrayDeque<>();
++
++ private final Deque<MethodType> callSiteTypes = new ArrayDeque<>();
++
++ private static final String ARGUMENTS = ARGUMENTS_VAR.symbolName();
++
++ /**
++ * Apply specialization optimization. Try to explode arguments and call
++ * applies as calls if they just pass on the "arguments" array and
++ * "arguments" doesn't escape.
++ *
++ * @param compiler compiler
++ */
++ public ApplySpecialization(final Compiler compiler) {
++ super(new LexicalContext());
++ this.compiler = compiler;
++ this.log = initLogger(compiler.getContext());
++ }
++
++ @Override
++ public DebugLogger getLogger() {
++ return log;
++ }
++
++ @Override
++ public DebugLogger initLogger(final Context context) {
++ return context.getLogger(this.getClass());
++ }
++
++ @SuppressWarnings("serial")
++ private static class TransformFailedException extends RuntimeException {
++ TransformFailedException(final FunctionNode fn, final String message) {
++ super(massageURL(fn.getSource().getURL()) + '.' + fn.getName() + " => " + message, null, false, false);
++ }
++ }
++
++ @SuppressWarnings("serial")
++ private static class AppliesFoundException extends RuntimeException {
++ AppliesFoundException() {
++ super("applies_found", null, false, false);
++ }
++ }
++
++ private static final AppliesFoundException HAS_APPLIES = new AppliesFoundException();
++
++ private boolean hasApplies(final FunctionNode functionNode) {
++ try {
++ functionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
++ @Override
++ public boolean enterFunctionNode(final FunctionNode fn) {
++ return fn == functionNode;
++ }
++
++ @Override
++ public boolean enterCallNode(final CallNode callNode) {
++ if (isApply(callNode)) {
++ throw HAS_APPLIES;
++ }
++ return true;
++ }
++ });
++ } catch (final AppliesFoundException e) {
++ return true;
++ }
++
++ log.fine("There are no applies in ", DebugLogger.quote(functionNode.getName()), " - nothing to do.");
++ return false; // no applies
++ }
++
++ /**
++ * Arguments may only be used as args to the apply. Everything else is disqualified
++ * We cannot control arguments if they escape from the method and go into an unknown
++ * scope, thus we are conservative and treat any access to arguments outside the
++ * apply call as a case of "we cannot apply the optimization".
++ */
++ private static void checkValidTransform(final FunctionNode functionNode) {
++
++ final Set<Expression> argumentsFound = new HashSet<>();
++ final Deque<Set<Expression>> stack = new ArrayDeque<>();
++
++ //ensure that arguments is only passed as arg to apply
++ functionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
++
++ private boolean isCurrentArg(final Expression expr) {
++ return !stack.isEmpty() && stack.peek().contains(expr); //args to current apply call
++ }
++
++ private boolean isArguments(final Expression expr) {
++ if (expr instanceof IdentNode && ARGUMENTS.equals(((IdentNode)expr).getName())) {
++ argumentsFound.add(expr);
++ return true;
++ }
++ return false;
++ }
++
++ private boolean isParam(final String name) {
++ for (final IdentNode param : functionNode.getParameters()) {
++ if (param.getName().equals(name)) {
++ return true;
++ }
++ }
++ return false;
++ }
++
++ @Override
++ public Node leaveIdentNode(final IdentNode identNode) {
++ if (isParam(identNode.getName())) {
++ throw new TransformFailedException(lc.getCurrentFunction(), "parameter: " + identNode.getName());
++ }
++ // it's OK if 'argument' occurs as the current argument of an apply
++ if (isArguments(identNode) && !isCurrentArg(identNode)) {
++ throw new TransformFailedException(lc.getCurrentFunction(), "is 'arguments': " + identNode.getName());
++ }
++ return identNode;
++ }
++
++ @Override
++ public boolean enterCallNode(final CallNode callNode) {
++ final Set<Expression> callArgs = new HashSet<>();
++ if (isApply(callNode)) {
++ final List<Expression> argList = callNode.getArgs();
++ if (argList.size() != 2 || !isArguments(argList.get(argList.size() - 1))) {
++ throw new TransformFailedException(lc.getCurrentFunction(), "argument pattern not matched: " + argList);
++ }
++ callArgs.addAll(callNode.getArgs());
++ }
++ stack.push(callArgs);
++ return true;
++ }
++
++ @Override
++ public Node leaveCallNode(final CallNode callNode) {
++ stack.pop();
++ return callNode;
++ }
++ });
++ }
++
++ @Override
++ public boolean enterCallNode(final CallNode callNode) {
++ return !explodedArguments.isEmpty();
++ }
++
++ @Override
++ public Node leaveCallNode(final CallNode callNode) {
++ //apply needs to be a global symbol or we don't allow it
++
++ final List<IdentNode> newParams = explodedArguments.peek();
++ if (isApply(callNode)) {
++ final List<Expression> newArgs = new ArrayList<>();
++ for (final Expression arg : callNode.getArgs()) {
++ if (arg instanceof IdentNode && ARGUMENTS.equals(((IdentNode)arg).getName())) {
++ newArgs.addAll(newParams);
++ } else {
++ newArgs.add(arg);
++ }
++ }
++
++ changed.add(lc.getCurrentFunction().getId());
++
++ final CallNode newCallNode = callNode.setArgs(newArgs).setIsApplyToCall();
++
++ if (log.isEnabled()) {
++ log.fine("Transformed ",
++ callNode,
++ " from apply to call => ",
++ newCallNode,
++ " in ",
++ DebugLogger.quote(lc.getCurrentFunction().getName()));
++ }
++
++ return newCallNode;
++ }
++
++ return callNode;
++ }
++
++ private void pushExplodedArgs(final FunctionNode functionNode) {
++ int start = 0;
++
++ final MethodType actualCallSiteType = compiler.getCallSiteType(functionNode);
++ if (actualCallSiteType == null) {
++ throw new TransformFailedException(lc.getCurrentFunction(), "No callsite type");
++ }
++ assert actualCallSiteType.parameterType(actualCallSiteType.parameterCount() - 1) != Object[].class : "error vararg callsite passed to apply2call " + functionNode.getName() + " " + actualCallSiteType;
++
++ final TypeMap ptm = compiler.getTypeMap();
++ if (ptm.needsCallee()) {
++ start++;
++ }
++
++ start++; //we always uses this
++
++ final List<IdentNode> params = functionNode.getParameters();
++ final List<IdentNode> newParams = new ArrayList<>();
++ final long to = Math.max(params.size(), actualCallSiteType.parameterCount() - start);
++ for (int i = 0; i < to; i++) {
++ if (i >= params.size()) {
++ newParams.add(new IdentNode(functionNode.getToken(), functionNode.getFinish(), EXPLODED_ARGUMENT_PREFIX.symbolName() + (i)));
++ } else {
++ newParams.add(params.get(i));
++ }
++ }
++
++ callSiteTypes.push(actualCallSiteType);
++ explodedArguments.push(newParams);
++ }
++
++ @Override
++ public boolean enterFunctionNode(final FunctionNode functionNode) {
++ if (!USE_APPLY2CALL) {
++ return false;
++ }
++
++ if (!Global.isBuiltinFunctionPrototypeApply()) {
++ log.fine("Apply transform disabled: apply/call overridden");
++ assert !Global.isBuiltinFunctionPrototypeCall() : "call and apply should have the same SwitchPoint";
++ return false;
++ }
++
++ if (!compiler.isOnDemandCompilation()) {
++ return false;
++ }
++
++ if (functionNode.hasEval()) {
++ return false;
++ }
++
++ if (!hasApplies(functionNode)) {
++ return false;
++ }
++
++ if (log.isEnabled()) {
++ log.info("Trying to specialize apply to call in '",
++ functionNode.getName(),
++ "' params=",
++ functionNode.getParameters(),
++ " id=",
++ functionNode.getId(),
++ " source=",
++ massageURL(functionNode.getSource().getURL()));
++ }
++
++ try {
++ checkValidTransform(functionNode);
++ pushExplodedArgs(functionNode);
++ } catch (final TransformFailedException e) {
++ log.info("Failure: ", e.getMessage());
++ return false;
++ }
++
++ return true;
++ }
++
++ /**
++ * Try to do the apply to call transformation
++ * @return true if successful, false otherwise
++ */
++ @Override
++ public Node leaveFunctionNode(final FunctionNode functionNode) {
++ FunctionNode newFunctionNode = functionNode;
++ final String functionName = newFunctionNode.getName();
++
++ if (changed.contains(newFunctionNode.getId())) {
++ newFunctionNode = newFunctionNode.clearFlag(lc, FunctionNode.USES_ARGUMENTS).
++ setFlag(lc, FunctionNode.HAS_APPLY_TO_CALL_SPECIALIZATION).
++ setParameters(lc, explodedArguments.peek());
++
++ if (log.isEnabled()) {
++ log.info("Success: ",
++ massageURL(newFunctionNode.getSource().getURL()),
++ '.',
++ functionName,
++ "' id=",
++ newFunctionNode.getId(),
++ " params=",
++ callSiteTypes.peek());
++ }
++ }
++
++ callSiteTypes.pop();
++ explodedArguments.pop();
++
++ return newFunctionNode.setState(lc, CompilationState.BUILTINS_TRANSFORMED);
++ }
++
++ private static boolean isApply(final CallNode callNode) {
++ final Expression f = callNode.getFunction();
++ return f instanceof AccessNode && "apply".equals(((AccessNode)f).getProperty());
++ }
++
++ private static String massageURL(final URL url) {
++ if (url == null) {
++ return "<null>";
++ }
++ final String str = url.toString();
++ final int slash = str.lastIndexOf('/');
++ if (slash == -1) {
++ return str;
++ }
++ return str.substring(slash + 1);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/AssignSymbols.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1072 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
++
++import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS;
++import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS_VAR;
++import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE;
++import static jdk.nashorn.internal.codegen.CompilerConstants.EXCEPTION_PREFIX;
++import static jdk.nashorn.internal.codegen.CompilerConstants.ITERATOR_PREFIX;
++import static jdk.nashorn.internal.codegen.CompilerConstants.RETURN;
++import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
++import static jdk.nashorn.internal.codegen.CompilerConstants.SWITCH_TAG_PREFIX;
++import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
++import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
++import static jdk.nashorn.internal.ir.Symbol.HAS_OBJECT_VALUE;
++import static jdk.nashorn.internal.ir.Symbol.IS_CONST;
++import static jdk.nashorn.internal.ir.Symbol.IS_FUNCTION_SELF;
++import static jdk.nashorn.internal.ir.Symbol.IS_GLOBAL;
++import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL;
++import static jdk.nashorn.internal.ir.Symbol.IS_LET;
++import static jdk.nashorn.internal.ir.Symbol.IS_PARAM;
++import static jdk.nashorn.internal.ir.Symbol.IS_PROGRAM_LEVEL;
++import static jdk.nashorn.internal.ir.Symbol.IS_SCOPE;
++import static jdk.nashorn.internal.ir.Symbol.IS_THIS;
++import static jdk.nashorn.internal.ir.Symbol.IS_VAR;
++import static jdk.nashorn.internal.ir.Symbol.KINDMASK;
++
++import java.util.ArrayDeque;
++import java.util.ArrayList;
++import java.util.Deque;
++import java.util.HashMap;
++import java.util.HashSet;
++import java.util.Iterator;
++import java.util.List;
++import java.util.ListIterator;
++import java.util.Map;
++import java.util.Set;
++import jdk.nashorn.internal.ir.AccessNode;
++import jdk.nashorn.internal.ir.BinaryNode;
++import jdk.nashorn.internal.ir.Block;
++import jdk.nashorn.internal.ir.CatchNode;
++import jdk.nashorn.internal.ir.Expression;
++import jdk.nashorn.internal.ir.ForNode;
++import jdk.nashorn.internal.ir.FunctionNode;
++import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
++import jdk.nashorn.internal.ir.IdentNode;
++import jdk.nashorn.internal.ir.IndexNode;
++import jdk.nashorn.internal.ir.LexicalContext;
++import jdk.nashorn.internal.ir.LexicalContextNode;
++import jdk.nashorn.internal.ir.LiteralNode;
++import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
++import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
++import jdk.nashorn.internal.ir.Node;
++import jdk.nashorn.internal.ir.RuntimeNode;
++import jdk.nashorn.internal.ir.RuntimeNode.Request;
++import jdk.nashorn.internal.ir.Statement;
++import jdk.nashorn.internal.ir.SwitchNode;
++import jdk.nashorn.internal.ir.Symbol;
++import jdk.nashorn.internal.ir.TryNode;
++import jdk.nashorn.internal.ir.UnaryNode;
++import jdk.nashorn.internal.ir.VarNode;
++import jdk.nashorn.internal.ir.WithNode;
++import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.ECMAErrors;
++import jdk.nashorn.internal.runtime.ErrorManager;
++import jdk.nashorn.internal.runtime.JSErrorType;
++import jdk.nashorn.internal.runtime.ParserException;
++import jdk.nashorn.internal.runtime.Source;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
++
++/**
++ * This visitor assigns symbols to identifiers denoting variables. It does few more minor calculations that are only
++ * possible after symbols have been assigned; such is the transformation of "delete" and "typeof" operators into runtime
++ * nodes and counting of number of properties assigned to "this" in constructor functions. This visitor is also notable
++ * for what it doesn't do, most significantly it does no type calculations as in JavaScript variables can change types
++ * during runtime and as such symbols don't have types. Calculation of expression types is performed by a separate
++ * visitor.
++ */
++@Logger(name="symbols")
++final class AssignSymbols extends NodeVisitor<LexicalContext> implements Loggable {
++ private final DebugLogger log;
++ private final boolean debug;
++
++ private static boolean isParamOrVar(final IdentNode identNode) {
++ final Symbol symbol = identNode.getSymbol();
++ return symbol.isParam() || symbol.isVar();
++ }
++
++ private static String name(final Node node) {
++ final String cn = node.getClass().getName();
++ final int lastDot = cn.lastIndexOf('.');
++ if (lastDot == -1) {
++ return cn;
++ }
++ return cn.substring(lastDot + 1);
++ }
++
++ /**
++ * Checks if various symbols that were provisionally marked as needing a slot ended up unused, and marks them as not
++ * needing a slot after all.
++ * @param functionNode the function node
++ * @return the passed in node, for easy chaining
++ */
++ private static FunctionNode removeUnusedSlots(final FunctionNode functionNode) {
++ if (!functionNode.needsCallee()) {
++ functionNode.compilerConstant(CALLEE).setNeedsSlot(false);
++ }
++ if (!(functionNode.hasScopeBlock() || functionNode.needsParentScope())) {
++ functionNode.compilerConstant(SCOPE).setNeedsSlot(false);
++ }
++ // Named function expressions that end up not referencing themselves won't need a local slot for the self symbol.
++ if(!functionNode.isDeclared() && !functionNode.usesSelfSymbol() && !functionNode.isAnonymous()) {
++ final Symbol selfSymbol = functionNode.getBody().getExistingSymbol(functionNode.getIdent().getName());
++ if(selfSymbol != null) {
++ if(selfSymbol.isFunctionSelf()) {
++ selfSymbol.setNeedsSlot(false);
++ selfSymbol.clearFlag(Symbol.IS_VAR);
++ }
++ } else {
++ assert functionNode.isProgram();
++ }
++ }
++ return functionNode;
++ }
++
++ private final Deque<Set<String>> thisProperties = new ArrayDeque<>();
++ private final Map<String, Symbol> globalSymbols = new HashMap<>(); //reuse the same global symbol
++ private final Compiler compiler;
++
++ public AssignSymbols(final Compiler compiler) {
++ super(new LexicalContext());
++ this.compiler = compiler;
++ this.log = initLogger(compiler.getContext());
++ this.debug = log.isEnabled();
++ }
++
++ @Override
++ public DebugLogger getLogger() {
++ return log;
++ }
++
++ @Override
++ public DebugLogger initLogger(final Context context) {
++ return context.getLogger(this.getClass());
++ }
++
++ /**
++ * Define symbols for all variable declarations at the top of the function scope. This way we can get around
++ * problems like
++ *
++ * while (true) {
++ * break;
++ * if (true) {
++ * var s;
++ * }
++ * }
++ *
++ * to an arbitrary nesting depth.
++ *
++ * see NASHORN-73
++ *
++ * @param functionNode the FunctionNode we are entering
++ * @param body the body of the FunctionNode we are entering
++ */
++ private void acceptDeclarations(final FunctionNode functionNode, final Block body) {
++ // This visitor will assign symbol to all declared variables.
++ body.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
++ @Override
++ protected boolean enterDefault(final Node node) {
++ // Don't bother visiting expressions; var is a statement, it can't be inside an expression.
++ // This will also prevent visiting nested functions (as FunctionNode is an expression).
++ return !(node instanceof Expression);
++ }
++
++ @Override
++ public Node leaveVarNode(final VarNode varNode) {
++ final IdentNode ident = varNode.getName();
++ final boolean blockScoped = varNode.isBlockScoped();
++ if (blockScoped && lc.inUnprotectedSwitchContext()) {
++ throwUnprotectedSwitchError(varNode);
++ }
++ final Block block = blockScoped ? lc.getCurrentBlock() : body;
++ final Symbol symbol = defineSymbol(block, ident.getName(), ident, varNode.getSymbolFlags());
++ if (varNode.isFunctionDeclaration()) {
++ symbol.setIsFunctionDeclaration();
++ }
++ return varNode.setName(ident.setSymbol(symbol));
++ }
++ });
++ }
++
++ private IdentNode compilerConstantIdentifier(final CompilerConstants cc) {
++ return createImplicitIdentifier(cc.symbolName()).setSymbol(lc.getCurrentFunction().compilerConstant(cc));
++ }
++
++ /**
++ * Creates an ident node for an implicit identifier within the function (one not declared in the script source
++ * code). These identifiers are defined with function's token and finish.
++ * @param name the name of the identifier
++ * @return an ident node representing the implicit identifier.
++ */
++ private IdentNode createImplicitIdentifier(final String name) {
++ final FunctionNode fn = lc.getCurrentFunction();
++ return new IdentNode(fn.getToken(), fn.getFinish(), name);
++ }
++
++ private Symbol createSymbol(final String name, final int flags) {
++ if ((flags & Symbol.KINDMASK) == IS_GLOBAL) {
++ //reuse global symbols so they can be hashed
++ Symbol global = globalSymbols.get(name);
++ if (global == null) {
++ global = new Symbol(name, flags);
++ globalSymbols.put(name, global);
++ }
++ return global;
++ }
++ return new Symbol(name, flags);
++ }
++
++ /**
++ * Creates a synthetic initializer for a variable (a var statement that doesn't occur in the source code). Typically
++ * used to create assignmnent of {@code :callee} to the function name symbol in self-referential function
++ * expressions as well as for assignment of {@code :arguments} to {@code arguments}.
++ *
++ * @param name the ident node identifying the variable to initialize
++ * @param initConstant the compiler constant it is initialized to
++ * @param fn the function node the assignment is for
++ * @return a var node with the appropriate assignment
++ */
++ private VarNode createSyntheticInitializer(final IdentNode name, final CompilerConstants initConstant, final FunctionNode fn) {
++ final IdentNode init = compilerConstantIdentifier(initConstant);
++ assert init.getSymbol() != null && init.getSymbol().isBytecodeLocal();
++
++ final VarNode synthVar = new VarNode(fn.getLineNumber(), fn.getToken(), fn.getFinish(), name, init);
++
++ final Symbol nameSymbol = fn.getBody().getExistingSymbol(name.getName());
++ assert nameSymbol != null;
++
++ return (VarNode)synthVar.setName(name.setSymbol(nameSymbol)).accept(this);
++ }
++
++ private FunctionNode createSyntheticInitializers(final FunctionNode functionNode) {
++ final List<VarNode> syntheticInitializers = new ArrayList<>(2);
++
++ // Must visit the new var nodes in the context of the body. We could also just set the new statements into the
++ // block and then revisit the entire block, but that seems to be too much double work.
++ final Block body = functionNode.getBody();
++ lc.push(body);
++ try {
++ if (functionNode.usesSelfSymbol()) {
++ // "var fn = :callee"
++ syntheticInitializers.add(createSyntheticInitializer(functionNode.getIdent(), CALLEE, functionNode));
++ }
++
++ if (functionNode.needsArguments()) {
++ // "var arguments = :arguments"
++ syntheticInitializers.add(createSyntheticInitializer(createImplicitIdentifier(ARGUMENTS_VAR.symbolName()),
++ ARGUMENTS, functionNode));
++ }
++
++ if (syntheticInitializers.isEmpty()) {
++ return functionNode;
++ }
++
++ for(final ListIterator<VarNode> it = syntheticInitializers.listIterator(); it.hasNext();) {
++ it.set((VarNode)it.next().accept(this));
++ }
++ } finally {
++ lc.pop(body);
++ }
++
++ final List<Statement> stmts = body.getStatements();
++ final List<Statement> newStatements = new ArrayList<>(stmts.size() + syntheticInitializers.size());
++ newStatements.addAll(syntheticInitializers);
++ newStatements.addAll(stmts);
++ return functionNode.setBody(lc, body.setStatements(lc, newStatements));
++ }
++
++ /**
++ * Defines a new symbol in the given block.
++ *
++ * @param block the block in which to define the symbol
++ * @param name name of symbol.
++ * @param origin origin node
++ * @param symbolFlags Symbol flags.
++ *
++ * @return Symbol for given name or null for redefinition.
++ */
++ private Symbol defineSymbol(final Block block, final String name, final Node origin, final int symbolFlags) {
++ int flags = symbolFlags;
++ final boolean isBlockScope = (flags & IS_LET) != 0 || (flags & IS_CONST) != 0;
++ final boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL;
++
++ Symbol symbol;
++ final FunctionNode function;
++ if (isBlockScope) {
++ // block scoped variables always live in current block, no need to look for existing symbols in parent blocks.
++ symbol = block.getExistingSymbol(name);
++ function = lc.getCurrentFunction();
++ } else {
++ symbol = findSymbol(block, name);
++ function = lc.getFunction(block);
++ }
++
++ // Global variables are implicitly always scope variables too.
++ if (isGlobal) {
++ flags |= IS_SCOPE;
++ }
++
++ if (lc.getCurrentFunction().isProgram()) {
++ flags |= IS_PROGRAM_LEVEL;
++ }
++
++ final boolean isParam = (flags & KINDMASK) == IS_PARAM;
++ final boolean isVar = (flags & KINDMASK) == IS_VAR;
++
++ if (symbol != null) {
++ // Symbol was already defined. Check if it needs to be redefined.
++ if (isParam) {
++ if (!isLocal(function, symbol)) {
++ // Not defined in this function. Create a new definition.
++ symbol = null;
++ } else if (symbol.isParam()) {
++ // Duplicate parameter. Null return will force an error.
++ throw new AssertionError("duplicate parameter");
++ }
++ } else if (isVar) {
++ if (isBlockScope) {
++ // Check redeclaration in same block
++ if (symbol.hasBeenDeclared()) {
++ throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin);
++ } else {
++ symbol.setHasBeenDeclared();
++ // Set scope flag on top-level block scoped symbols
++ if (function.isProgram() && function.getBody() == block) {
++ symbol.setIsScope();
++ }
++ }
++ } else if ((flags & IS_INTERNAL) != 0) {
++ // Always create a new definition.
++ symbol = null;
++ } else {
++ // Found LET or CONST in parent scope of same function - s SyntaxError
++ if (symbol.isBlockScoped() && isLocal(lc.getCurrentFunction(), symbol)) {
++ throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin);
++ }
++ // Not defined in this function. Create a new definition.
++ if (!isLocal(function, symbol) || symbol.less(IS_VAR)) {
++ symbol = null;
++ }
++ }
++ }
++ }
++
++ if (symbol == null) {
++ // If not found, then create a new one.
++ final Block symbolBlock;
++
++ // Determine where to create it.
++ if (isVar && ((flags & IS_INTERNAL) != 0 || isBlockScope)) {
++ symbolBlock = block; //internal vars are always defined in the block closest to them
++ } else if (isGlobal) {
++ symbolBlock = lc.getOutermostFunction().getBody();
++ } else {
++ symbolBlock = lc.getFunctionBody(function);
++ }
++
++ // Create and add to appropriate block.
++ symbol = createSymbol(name, flags);
++ symbolBlock.putSymbol(lc, symbol);
++
++ if ((flags & IS_SCOPE) == 0) {
++ // Initial assumption; symbol can lose its slot later
++ symbol.setNeedsSlot(true);
++ }
++ } else if (symbol.less(flags)) {
++ symbol.setFlags(flags);
++ }
++
++ return symbol;
++ }
++
++ private <T extends Node> T end(final T node) {
++ return end(node, true);
++ }
++
++ private <T extends Node> T end(final T node, final boolean printNode) {
++ if (debug) {
++ final StringBuilder sb = new StringBuilder();
++
++ sb.append("[LEAVE ").
++ append(name(node)).
++ append("] ").
++ append(printNode ? node.toString() : "").
++ append(" in '").
++ append(lc.getCurrentFunction().getName()).
++ append('\'');
++
++ if (node instanceof IdentNode) {
++ final Symbol symbol = ((IdentNode)node).getSymbol();
++ if (symbol == null) {
++ sb.append(" <NO SYMBOL>");
++ } else {
++ sb.append(" <symbol=").append(symbol).append('>');
++ }
++ }
++
++ log.unindent();
++ log.info(sb);
++ }
++
++ return node;
++ }
++
++ @Override
++ public boolean enterBlock(final Block block) {
++ start(block);
++
++ if (lc.isFunctionBody()) {
++ block.clearSymbols();
++ final FunctionNode fn = lc.getCurrentFunction();
++ if (isUnparsedFunction(fn)) {
++ // It's a skipped nested function. Just mark the symbols being used by it as being in use.
++ for(final String name: compiler.getScriptFunctionData(fn.getId()).getExternalSymbolNames()) {
++ nameIsUsed(name, null);
++ }
++ // Don't bother descending into it, it must be empty anyway.
++ assert block.getStatements().isEmpty();
++ return false;
++ }
++
++ enterFunctionBody();
++ }
++
++ return true;
++ }
++
++ private boolean isUnparsedFunction(final FunctionNode fn) {
++ return compiler.isOnDemandCompilation() && fn != lc.getOutermostFunction();
++ }
++
++ @Override
++ public boolean enterCatchNode(final CatchNode catchNode) {
++ final IdentNode exception = catchNode.getException();
++ final Block block = lc.getCurrentBlock();
++
++ start(catchNode);
++
++ // define block-local exception variable
++ final String exname = exception.getName();
++ // If the name of the exception starts with ":e", this is a synthetic catch block, likely a catch-all. Its
++ // symbol is naturally internal, and should be treated as such.
++ final boolean isInternal = exname.startsWith(EXCEPTION_PREFIX.symbolName());
++ // IS_LET flag is required to make sure symbol is not visible outside catch block. However, we need to
++ // clear the IS_LET flag after creation to allow redefinition of symbol inside the catch block.
++ final Symbol symbol = defineSymbol(block, exname, catchNode, IS_VAR | IS_LET | (isInternal ? IS_INTERNAL : 0) | HAS_OBJECT_VALUE);
++ symbol.clearFlag(IS_LET);
++
++ return true;
++ }
++
++ private void enterFunctionBody() {
++ final FunctionNode functionNode = lc.getCurrentFunction();
++ final Block body = lc.getCurrentBlock();
++
++ initFunctionWideVariables(functionNode, body);
++
++ if (!functionNode.isProgram() && !functionNode.isDeclared() && !functionNode.isAnonymous()) {
++ // It's neither declared nor program - it's a function expression then; assign it a self-symbol unless it's
++ // anonymous.
++ final String name = functionNode.getIdent().getName();
++ assert name != null;
++ assert body.getExistingSymbol(name) == null;
++ defineSymbol(body, name, functionNode, IS_VAR | IS_FUNCTION_SELF | HAS_OBJECT_VALUE);
++ if(functionNode.allVarsInScope()) { // basically, has deep eval
++ lc.setFlag(functionNode, FunctionNode.USES_SELF_SYMBOL);
++ }
++ }
++
++ acceptDeclarations(functionNode, body);
++ }
++
++ @Override
++ public boolean enterFunctionNode(final FunctionNode functionNode) {
++ start(functionNode, false);
++
++ thisProperties.push(new HashSet<String>());
++
++ // Every function has a body, even the ones skipped on reparse (they have an empty one). We're
++ // asserting this as even for those, enterBlock() must be invoked to correctly process symbols that
++ // are used in them.
++ assert functionNode.getBody() != null;
++
++ return true;
++ }
++
++ @Override
++ public boolean enterVarNode(final VarNode varNode) {
++ start(varNode);
++ // Normally, a symbol assigned in a var statement is not live for its RHS. Since we also represent function
++ // declarations as VarNodes, they are exception to the rule, as they need to have the symbol visible to the
++ // body of the declared function for self-reference.
++ if (varNode.isFunctionDeclaration()) {
++ defineVarIdent(varNode);
++ }
++ return true;
++ }
++
++ @Override
++ public Node leaveVarNode(final VarNode varNode) {
++ if (!varNode.isFunctionDeclaration()) {
++ defineVarIdent(varNode);
++ }
++ return super.leaveVarNode(varNode);
++ }
++
++ private void defineVarIdent(final VarNode varNode) {
++ final IdentNode ident = varNode.getName();
++ final int flags;
++ if (varNode.isAnonymousFunctionDeclaration()) {
++ flags = IS_INTERNAL;
++ } else if (!varNode.isBlockScoped() && lc.getCurrentFunction().isProgram()) {
++ flags = IS_SCOPE;
++ } else {
++ flags = 0;
++ }
++ defineSymbol(lc.getCurrentBlock(), ident.getName(), ident, varNode.getSymbolFlags() | flags);
++ }
++
++ private Symbol exceptionSymbol() {
++ return newObjectInternal(EXCEPTION_PREFIX);
++ }
++
++ /**
++ * This has to run before fix assignment types, store any type specializations for
++ * parameters, then turn them into objects for the generic version of this method.
++ *
++ * @param functionNode functionNode
++ */
++ private FunctionNode finalizeParameters(final FunctionNode functionNode) {
++ final List<IdentNode> newParams = new ArrayList<>();
++ final boolean isVarArg = functionNode.isVarArg();
++
++ final Block body = functionNode.getBody();
++ for (final IdentNode param : functionNode.getParameters()) {
++ final Symbol paramSymbol = body.getExistingSymbol(param.getName());
++ assert paramSymbol != null;
++ assert paramSymbol.isParam() : paramSymbol + " " + paramSymbol.getFlags();
++ newParams.add(param.setSymbol(paramSymbol));
++
++ // parameters should not be slots for a function that uses variable arity signature
++ if (isVarArg) {
++ paramSymbol.setNeedsSlot(false);
++ }
++ }
++
++ return functionNode.setParameters(lc, newParams);
++ }
++
++ /**
++ * Search for symbol in the lexical context starting from the given block.
++ * @param name Symbol name.
++ * @return Found symbol or null if not found.
++ */
++ private Symbol findSymbol(final Block block, final String name) {
++ for (final Iterator<Block> blocks = lc.getBlocks(block); blocks.hasNext();) {
++ final Symbol symbol = blocks.next().getExistingSymbol(name);
++ if (symbol != null) {
++ return symbol;
++ }
++ }
++ return null;
++ }
++
++ /**
++ * Marks the current function as one using any global symbol. The function and all its parent functions will all be
++ * marked as needing parent scope.
++ * @see FunctionNode#needsParentScope()
++ */
++ private void functionUsesGlobalSymbol() {
++ for (final Iterator<FunctionNode> fns = lc.getFunctions(); fns.hasNext();) {
++ lc.setFlag(fns.next(), FunctionNode.USES_ANCESTOR_SCOPE);
++ }
++ }
++
++ /**
++ * Marks the current function as one using a scoped symbol. The block defining the symbol will be marked as needing
++ * its own scope to hold the variable. If the symbol is defined outside of the current function, it and all
++ * functions up to (but not including) the function containing the defining block will be marked as needing parent
++ * function scope.
++ * @see FunctionNode#needsParentScope()
++ */
++ private void functionUsesScopeSymbol(final Symbol symbol) {
++ final String name = symbol.getName();
++ for (final Iterator<LexicalContextNode> contextNodeIter = lc.getAllNodes(); contextNodeIter.hasNext(); ) {
++ final LexicalContextNode node = contextNodeIter.next();
++ if (node instanceof Block) {
++ final Block block = (Block)node;
++ if (block.getExistingSymbol(name) != null) {
++ assert lc.contains(block);
++ lc.setBlockNeedsScope(block);
++ break;
++ }
++ } else if (node instanceof FunctionNode) {
++ lc.setFlag(node, FunctionNode.USES_ANCESTOR_SCOPE);
++ }
++ }
++ }
++
++ /**
++ * Declares that the current function is using the symbol.
++ * @param symbol the symbol used by the current function.
++ */
++ private void functionUsesSymbol(final Symbol symbol) {
++ assert symbol != null;
++ if (symbol.isScope()) {
++ if (symbol.isGlobal()) {
++ functionUsesGlobalSymbol();
++ } else {
++ functionUsesScopeSymbol(symbol);
++ }
++ } else {
++ assert !symbol.isGlobal(); // Every global is also scope
++ }
++ }
++
++ private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags) {
++ defineSymbol(block, cc.symbolName(), null, flags).setNeedsSlot(true);
++ }
++
++ private void initFunctionWideVariables(final FunctionNode functionNode, final Block body) {
++ initCompileConstant(CALLEE, body, IS_PARAM | IS_INTERNAL | HAS_OBJECT_VALUE);
++ initCompileConstant(THIS, body, IS_PARAM | IS_THIS | HAS_OBJECT_VALUE);
++
++ if (functionNode.isVarArg()) {
++ initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL | HAS_OBJECT_VALUE);
++ if (functionNode.needsArguments()) {
++ initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | HAS_OBJECT_VALUE);
++ defineSymbol(body, ARGUMENTS_VAR.symbolName(), null, IS_VAR | HAS_OBJECT_VALUE);
++ }
++ }
++
++ initParameters(functionNode, body);
++ initCompileConstant(SCOPE, body, IS_VAR | IS_INTERNAL | HAS_OBJECT_VALUE);
++ initCompileConstant(RETURN, body, IS_VAR | IS_INTERNAL);
++ }
++
++ /**
++ * Initialize parameters for function node.
++ * @param functionNode the function node
++ */
++ private void initParameters(final FunctionNode functionNode, final Block body) {
++ final boolean isVarArg = functionNode.isVarArg();
++ final boolean scopeParams = functionNode.allVarsInScope() || isVarArg;
++ for (final IdentNode param : functionNode.getParameters()) {
++ final Symbol symbol = defineSymbol(body, param.getName(), param, IS_PARAM);
++ if(scopeParams) {
++ // NOTE: this "set is scope" is a poor substitute for clear expression of where the symbol is stored.
++ // It will force creation of scopes where they would otherwise not necessarily be needed (functions
++ // using arguments object and other variable arity functions). Tracked by JDK-8038942.
++ symbol.setIsScope();
++ assert symbol.hasSlot();
++ if(isVarArg) {
++ symbol.setNeedsSlot(false);
++ }
++ }
++ }
++ }
++
++ /**
++ * Is the symbol local to (that is, defined in) the specified function?
++ * @param function the function
++ * @param symbol the symbol
++ * @return true if the symbol is defined in the specified function
++ */
++ private boolean isLocal(final FunctionNode function, final Symbol symbol) {
++ final FunctionNode definingFn = lc.getDefiningFunction(symbol);
++ assert definingFn != null;
++ return definingFn == function;
++ }
++
++ private void checkConstAssignment(final IdentNode ident) {
++ // Check for reassignment of constant
++ final Symbol symbol = ident.getSymbol();
++ if (symbol.isConst()) {
++ throwParserException(ECMAErrors.getMessage("syntax.error.assign.constant", symbol.getName()), ident);
++ }
++ }
++
++ @Override
++ public Node leaveBinaryNode(final BinaryNode binaryNode) {
++ if (binaryNode.isAssignment() && binaryNode.lhs() instanceof IdentNode) {
++ checkConstAssignment((IdentNode) binaryNode.lhs());
++ }
++ switch (binaryNode.tokenType()) {
++ case ASSIGN:
++ return leaveASSIGN(binaryNode);
++ default:
++ return super.leaveBinaryNode(binaryNode);
++ }
++ }
++
++ private Node leaveASSIGN(final BinaryNode binaryNode) {
++ // If we're assigning a property of the this object ("this.foo = ..."), record it.
++ final Expression lhs = binaryNode.lhs();
++ if (lhs instanceof AccessNode) {
++ final AccessNode accessNode = (AccessNode) lhs;
++ final Expression base = accessNode.getBase();
++ if (base instanceof IdentNode) {
++ final Symbol symbol = ((IdentNode)base).getSymbol();
++ if(symbol.isThis()) {
++ thisProperties.peek().add(accessNode.getProperty());
++ }
++ }
++ }
++ return binaryNode;
++ }
++
++ @Override
++ public Node leaveUnaryNode(final UnaryNode unaryNode) {
++ if (unaryNode.isAssignment() && unaryNode.getExpression() instanceof IdentNode) {
++ checkConstAssignment((IdentNode) unaryNode.getExpression());
++ }
++ switch (unaryNode.tokenType()) {
++ case DELETE:
++ return leaveDELETE(unaryNode);
++ case TYPEOF:
++ return leaveTYPEOF(unaryNode);
++ default:
++ return super.leaveUnaryNode(unaryNode);
++ }
++ }
++
++ @Override
++ public Node leaveBlock(final Block block) {
++ // It's not necessary to guard the marking of symbols as locals with this "if" condition for
++ // correctness, it's just an optimization -- runtime type calculation is not used when the compilation
++ // is not an on-demand optimistic compilation, so we can skip locals marking then.
++ if (compiler.useOptimisticTypes() && compiler.isOnDemandCompilation()) {
++ // OTOH, we must not declare symbols from nested functions to be locals. As we're doing on-demand
++ // compilation, and we're skipping parsing the function bodies for nested functions, this
++ // basically only means their parameters. It'd be enough to mistakenly declare to be a local a
++ // symbol in the outer function named the same as one of the parameters, though.
++ if (lc.getFunction(block) == lc.getOutermostFunction()) {
++ for (final Symbol symbol: block.getSymbols()) {
++ if (!symbol.isScope()) {
++ assert symbol.isVar() || symbol.isParam();
++ compiler.declareLocalSymbol(symbol.getName());
++ }
++ }
++ }
++ }
++ return block;
++ }
++
++ private Node leaveDELETE(final UnaryNode unaryNode) {
++ final FunctionNode currentFunctionNode = lc.getCurrentFunction();
++ final boolean strictMode = currentFunctionNode.isStrict();
++ final Expression rhs = unaryNode.getExpression();
++ final Expression strictFlagNode = (Expression)LiteralNode.newInstance(unaryNode, strictMode).accept(this);
++
++ Request request = Request.DELETE;
++ final List<Expression> args = new ArrayList<>();
++
++ if (rhs instanceof IdentNode) {
++ final IdentNode ident = (IdentNode)rhs;
++ // If this is a declared variable or a function parameter, delete always fails (except for globals).
++ final String name = ident.getName();
++ final Symbol symbol = ident.getSymbol();
++ final boolean failDelete = strictMode || (!symbol.isScope() && (symbol.isParam() || (symbol.isVar() && !symbol.isProgramLevel())));
++
++ if (failDelete && symbol.isThis()) {
++ return LiteralNode.newInstance(unaryNode, true).accept(this);
++ }
++ final Expression literalNode = (Expression)LiteralNode.newInstance(unaryNode, name).accept(this);
++
++ if (!failDelete) {
++ args.add(compilerConstantIdentifier(SCOPE));
++ }
++ args.add(literalNode);
++ args.add(strictFlagNode);
++
++ if (failDelete) {
++ request = Request.FAIL_DELETE;
++ }
++ } else if (rhs instanceof AccessNode) {
++ final Expression base = ((AccessNode)rhs).getBase();
++ final String property = ((AccessNode)rhs).getProperty();
++
++ args.add(base);
++ args.add((Expression)LiteralNode.newInstance(unaryNode, property).accept(this));
++ args.add(strictFlagNode);
++
++ } else if (rhs instanceof IndexNode) {
++ final IndexNode indexNode = (IndexNode)rhs;
++ final Expression base = indexNode.getBase();
++ final Expression index = indexNode.getIndex();
++
++ args.add(base);
++ args.add(index);
++ args.add(strictFlagNode);
++
++ } else {
++ return LiteralNode.newInstance(unaryNode, true).accept(this);
++ }
++ return new RuntimeNode(unaryNode, request, args).accept(this);
++ }
++
++ @Override
++ public Node leaveForNode(final ForNode forNode) {
++ if (forNode.isForIn()) {
++ forNode.setIterator(newObjectInternal(ITERATOR_PREFIX)); //NASHORN-73
++ }
++
++ return end(forNode);
++ }
++
++ @Override
++ public Node leaveFunctionNode(final FunctionNode functionNode) {
++ final FunctionNode finalizedFunction;
++ if (isUnparsedFunction(functionNode)) {
++ finalizedFunction = functionNode;
++ } else {
++ finalizedFunction =
++ markProgramBlock(
++ removeUnusedSlots(
++ createSyntheticInitializers(
++ finalizeParameters(
++ lc.applyTopFlags(functionNode))))
++ .setThisProperties(lc, thisProperties.pop().size()));
++ }
++ return finalizedFunction.setState(lc, CompilationState.SYMBOLS_ASSIGNED);
++ }
++
++ @Override
++ public Node leaveIdentNode(final IdentNode identNode) {
++ if (identNode.isPropertyName()) {
++ return identNode;
++ }
++
++ final Symbol symbol = nameIsUsed(identNode.getName(), identNode);
++
++ if (!identNode.isInitializedHere()) {
++ symbol.increaseUseCount();
++ }
++
++ IdentNode newIdentNode = identNode.setSymbol(symbol);
++
++ // If a block-scoped var is used before its declaration mark it as dead.
++ // We can only statically detect this for local vars, cross-function symbols require runtime checks.
++ if (symbol.isBlockScoped() && !symbol.hasBeenDeclared() && !identNode.isDeclaredHere() && isLocal(lc.getCurrentFunction(), symbol)) {
++ newIdentNode = newIdentNode.markDead();
++ }
++
++ return end(newIdentNode);
++ }
++
++ private Symbol nameIsUsed(final String name, final IdentNode origin) {
++ final Block block = lc.getCurrentBlock();
++
++ Symbol symbol = findSymbol(block, name);
++
++ //If an existing symbol with the name is found, use that otherwise, declare a new one
++ if (symbol != null) {
++ log.info("Existing symbol = ", symbol);
++ if (symbol.isFunctionSelf()) {
++ final FunctionNode functionNode = lc.getDefiningFunction(symbol);
++ assert functionNode != null;
++ assert lc.getFunctionBody(functionNode).getExistingSymbol(CALLEE.symbolName()) != null;
++ lc.setFlag(functionNode, FunctionNode.USES_SELF_SYMBOL);
++ }
++
++ // if symbol is non-local or we're in a with block, we need to put symbol in scope (if it isn't already)
++ maybeForceScope(symbol);
++ } else {
++ log.info("No symbol exists. Declare as global: ", name);
++ symbol = defineSymbol(block, name, origin, IS_GLOBAL | IS_SCOPE);
++ }
++
++ functionUsesSymbol(symbol);
++ return symbol;
++ }
++
++ @Override
++ public Node leaveSwitchNode(final SwitchNode switchNode) {
++ // We only need a symbol for the tag if it's not an integer switch node
++ if(!switchNode.isUniqueInteger()) {
++ switchNode.setTag(newObjectInternal(SWITCH_TAG_PREFIX));
++ }
++ return switchNode;
++ }
++
++ @Override
++ public Node leaveTryNode(final TryNode tryNode) {
++ tryNode.setException(exceptionSymbol());
++ if (tryNode.getFinallyBody() != null) {
++ tryNode.setFinallyCatchAll(exceptionSymbol());
++ }
++
++ end(tryNode);
++
++ return tryNode;
++ }
++
++ private Node leaveTYPEOF(final UnaryNode unaryNode) {
++ final Expression rhs = unaryNode.getExpression();
++
++ final List<Expression> args = new ArrayList<>();
++ if (rhs instanceof IdentNode && !isParamOrVar((IdentNode)rhs)) {
++ args.add(compilerConstantIdentifier(SCOPE));
++ args.add((Expression)LiteralNode.newInstance(rhs, ((IdentNode)rhs).getName()).accept(this)); //null
++ } else {
++ args.add(rhs);
++ args.add((Expression)LiteralNode.newInstance(unaryNode).accept(this)); //null, do not reuse token of identifier rhs, it can be e.g. 'this'
++ }
++
++ final Node runtimeNode = new RuntimeNode(unaryNode, Request.TYPEOF, args).accept(this);
++
++ end(unaryNode);
++
++ return runtimeNode;
++ }
++
++ private FunctionNode markProgramBlock(final FunctionNode functionNode) {
++ if (compiler.isOnDemandCompilation() || !functionNode.isProgram()) {
++ return functionNode;
++ }
++
++ return functionNode.setBody(lc, functionNode.getBody().setFlag(lc, Block.IS_GLOBAL_SCOPE));
++ }
++
++ /**
++ * If the symbol isn't already a scope symbol, but it needs to be (see {@link #symbolNeedsToBeScope(Symbol)}, it is
++ * promoted to a scope symbol and its block marked as needing a scope.
++ * @param symbol the symbol that might be scoped
++ */
++ private void maybeForceScope(final Symbol symbol) {
++ if (!symbol.isScope() && symbolNeedsToBeScope(symbol)) {
++ Symbol.setSymbolIsScope(lc, symbol);
++ }
++ }
++
++ private Symbol newInternal(final CompilerConstants cc, final int flags) {
++ return defineSymbol(lc.getCurrentBlock(), lc.getCurrentFunction().uniqueName(cc.symbolName()), null, IS_VAR | IS_INTERNAL | flags); //NASHORN-73
++ }
++
++ private Symbol newObjectInternal(final CompilerConstants cc) {
++ return newInternal(cc, HAS_OBJECT_VALUE);
++ }
++
++ private boolean start(final Node node) {
++ return start(node, true);
++ }
++
++ private boolean start(final Node node, final boolean printNode) {
++ if (debug) {
++ final StringBuilder sb = new StringBuilder();
++
++ sb.append("[ENTER ").
++ append(name(node)).
++ append("] ").
++ append(printNode ? node.toString() : "").
++ append(" in '").
++ append(lc.getCurrentFunction().getName()).
++ append("'");
++ log.info(sb);
++ log.indent();
++ }
++
++ return true;
++ }
++
++ /**
++ * Determines if the symbol has to be a scope symbol. In general terms, it has to be a scope symbol if it can only
++ * be reached from the current block by traversing a function node, a split node, or a with node.
++ * @param symbol the symbol checked for needing to be a scope symbol
++ * @return true if the symbol has to be a scope symbol.
++ */
++ private boolean symbolNeedsToBeScope(final Symbol symbol) {
++ if (symbol.isThis() || symbol.isInternal()) {
++ return false;
++ }
++
++ final FunctionNode func = lc.getCurrentFunction();
++ if ( func.allVarsInScope() || (!symbol.isBlockScoped() && func.isProgram())) {
++ return true;
++ }
++
++ boolean previousWasBlock = false;
++ for (final Iterator<LexicalContextNode> it = lc.getAllNodes(); it.hasNext();) {
++ final LexicalContextNode node = it.next();
++ if (node instanceof FunctionNode || isSplitArray(node)) {
++ // We reached the function boundary or a splitting boundary without seeing a definition for the symbol.
++ // It needs to be in scope.
++ return true;
++ } else if (node instanceof WithNode) {
++ if (previousWasBlock) {
++ // We reached a WithNode; the symbol must be scoped. Note that if the WithNode was not immediately
++ // preceded by a block, this means we're currently processing its expression, not its body,
++ // therefore it doesn't count.
++ return true;
++ }
++ previousWasBlock = false;
++ } else if (node instanceof Block) {
++ if (((Block)node).getExistingSymbol(symbol.getName()) == symbol) {
++ // We reached the block that defines the symbol without reaching either the function boundary, or a
++ // WithNode. The symbol need not be scoped.
++ return false;
++ }
++ previousWasBlock = true;
++ } else {
++ previousWasBlock = false;
++ }
++ }
++ throw new AssertionError();
++ }
++
++ private static boolean isSplitArray(final LexicalContextNode expr) {
++ if(!(expr instanceof ArrayLiteralNode)) {
++ return false;
++ }
++ final List<ArrayUnit> units = ((ArrayLiteralNode)expr).getUnits();
++ return !(units == null || units.isEmpty());
++ }
++
++ private void throwUnprotectedSwitchError(final VarNode varNode) {
++ // Block scoped declarations in switch statements without explicit blocks should be declared
++ // in a common block that contains all the case clauses. We cannot support this without a
++ // fundamental rewrite of how switch statements are handled (case nodes contain blocks and are
++ // directly contained by switch node). As a temporary solution we throw a reference error here.
++ final String msg = ECMAErrors.getMessage("syntax.error.unprotected.switch.declaration", varNode.isLet() ? "let" : "const");
++ throwParserException(msg, varNode);
++ }
++
++ private void throwParserException(final String message, final Node origin) {
++ if (origin == null) {
++ throw new ParserException(message);
++ }
++ final Source source = compiler.getSource();
++ final long token = origin.getToken();
++ final int line = source.getLine(origin.getStart());
++ final int column = source.getColumn(origin.getStart());
++ final String formatted = ErrorManager.format(message, source, line, column, token);
++ throw new ParserException(JSErrorType.SYNTAX_ERROR, formatted, source, line, column, token);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/AstSerializer.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,73 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
++
++import java.io.ByteArrayOutputStream;
++import java.io.IOException;
++import java.io.ObjectOutputStream;
++import java.util.Collections;
++import java.util.zip.Deflater;
++import java.util.zip.DeflaterOutputStream;
++import jdk.nashorn.internal.ir.Block;
++import jdk.nashorn.internal.ir.FunctionNode;
++import jdk.nashorn.internal.ir.LexicalContext;
++import jdk.nashorn.internal.ir.Node;
++import jdk.nashorn.internal.ir.Statement;
++import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++import jdk.nashorn.internal.runtime.options.Options;
++
++/**
++ * This static utility class performs serialization of FunctionNode ASTs to a byte array.
++ * The format is a standard Java serialization stream, deflated.
++ */
++final class AstSerializer {
++ // Experimentally, we concluded that compression level 4 gives a good tradeoff between serialization speed
++ // and size.
++ private static final int COMPRESSION_LEVEL = Options.getIntProperty("nashorn.serialize.compression", 4);
++ static byte[] serialize(final FunctionNode fn) {
++ final ByteArrayOutputStream out = new ByteArrayOutputStream();
++ final Deflater deflater = new Deflater(COMPRESSION_LEVEL);
++ try (final ObjectOutputStream oout = new ObjectOutputStream(new DeflaterOutputStream(out, deflater))) {
++ oout.writeObject(removeInnerFunctionBodies(fn));
++ } catch (final IOException e) {
++ throw new AssertionError("Unexpected exception serializing function", e);
++ } finally {
++ deflater.end();
++ }
++ return out.toByteArray();
++ }
++
++ private static FunctionNode removeInnerFunctionBodies(final FunctionNode fn) {
++ return (FunctionNode)fn.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
++ @Override
++ public Node leaveBlock(final Block block) {
++ if (lc.isFunctionBody() && lc.getFunction(block) != lc.getOutermostFunction()) {
++ return block.setStatements(lc, Collections.<Statement>emptyList());
++ }
++ return super.leaveBlock(block);
++ }
++ });
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/codegen/Attr.java Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,1947 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
+-
+-import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS_VAR;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.EXCEPTION_PREFIX;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.ITERATOR_PREFIX;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.LITERAL_PREFIX;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.RETURN;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.SWITCH_TAG_PREFIX;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
+-import static jdk.nashorn.internal.ir.Symbol.IS_ALWAYS_DEFINED;
+-import static jdk.nashorn.internal.ir.Symbol.IS_CONSTANT;
+-import static jdk.nashorn.internal.ir.Symbol.IS_FUNCTION_SELF;
+-import static jdk.nashorn.internal.ir.Symbol.IS_GLOBAL;
+-import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL;
+-import static jdk.nashorn.internal.ir.Symbol.IS_LET;
+-import static jdk.nashorn.internal.ir.Symbol.IS_PARAM;
+-import static jdk.nashorn.internal.ir.Symbol.IS_SCOPE;
+-import static jdk.nashorn.internal.ir.Symbol.IS_THIS;
+-import static jdk.nashorn.internal.ir.Symbol.IS_VAR;
+-import static jdk.nashorn.internal.ir.Symbol.KINDMASK;
+-
+-import java.util.ArrayDeque;
+-import java.util.ArrayList;
+-import java.util.Deque;
+-import java.util.HashSet;
+-import java.util.Iterator;
+-import java.util.List;
+-import java.util.Set;
+-import jdk.nashorn.internal.codegen.types.Type;
+-import jdk.nashorn.internal.ir.AccessNode;
+-import jdk.nashorn.internal.ir.BinaryNode;
+-import jdk.nashorn.internal.ir.Block;
+-import jdk.nashorn.internal.ir.CallNode;
+-import jdk.nashorn.internal.ir.CaseNode;
+-import jdk.nashorn.internal.ir.CatchNode;
+-import jdk.nashorn.internal.ir.Expression;
+-import jdk.nashorn.internal.ir.ForNode;
+-import jdk.nashorn.internal.ir.FunctionNode;
+-import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
+-import jdk.nashorn.internal.ir.IdentNode;
+-import jdk.nashorn.internal.ir.IndexNode;
+-import jdk.nashorn.internal.ir.LexicalContext;
+-import jdk.nashorn.internal.ir.LexicalContextNode;
+-import jdk.nashorn.internal.ir.LiteralNode;
+-import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
+-import jdk.nashorn.internal.ir.Node;
+-import jdk.nashorn.internal.ir.ObjectNode;
+-import jdk.nashorn.internal.ir.ReturnNode;
+-import jdk.nashorn.internal.ir.RuntimeNode;
+-import jdk.nashorn.internal.ir.RuntimeNode.Request;
+-import jdk.nashorn.internal.ir.Statement;
+-import jdk.nashorn.internal.ir.SwitchNode;
+-import jdk.nashorn.internal.ir.Symbol;
+-import jdk.nashorn.internal.ir.TemporarySymbols;
+-import jdk.nashorn.internal.ir.TernaryNode;
+-import jdk.nashorn.internal.ir.TryNode;
+-import jdk.nashorn.internal.ir.UnaryNode;
+-import jdk.nashorn.internal.ir.VarNode;
+-import jdk.nashorn.internal.ir.WithNode;
+-import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
+-import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+-import jdk.nashorn.internal.parser.TokenType;
+-import jdk.nashorn.internal.runtime.Context;
+-import jdk.nashorn.internal.runtime.Debug;
+-import jdk.nashorn.internal.runtime.DebugLogger;
+-import jdk.nashorn.internal.runtime.JSType;
+-import jdk.nashorn.internal.runtime.Property;
+-import jdk.nashorn.internal.runtime.PropertyMap;
+-
+-/**
+- * This is the attribution pass of the code generator. Attr takes Lowered IR,
+- * that is, IR where control flow has been computed and high level to low level
+- * substitions for operations have been performed.
+- *
+- * After Attr, every symbol will have a conservative correct type.
+- *
+- * Any expression that requires temporary storage as part of computation will
+- * also be detected here and give a temporary symbol
+- *
+- * Types can be narrowed after Attr by Access Specialization in FinalizeTypes,
+- * but in general, this is where the main symbol type information is
+- * computed.
+- */
+-
+-final class Attr extends NodeOperatorVisitor<LexicalContext> {
+-
+- /**
+- * Local definitions in current block (to discriminate from function
+- * declarations always defined in the function scope. This is for
+- * "can be undefined" analysis.
+- */
+- private final Deque<Set<String>> localDefs;
+-
+- /**
+- * Local definitions in current block to guard against cases like
+- * NASHORN-467 when things can be undefined as they are used before
+- * their local var definition. *sigh* JavaScript...
+- */
+- private final Deque<Set<String>> localUses;
+-
+- private final Deque<Type> returnTypes;
+-
+- private int catchNestingLevel;
+-
+- private static final DebugLogger LOG = new DebugLogger("attr");
+- private static final boolean DEBUG = LOG.isEnabled();
+-
+- private final TemporarySymbols temporarySymbols;
+-
+- /**
+- * Constructor.
+- */
+- Attr(final TemporarySymbols temporarySymbols) {
+- super(new LexicalContext());
+- this.temporarySymbols = temporarySymbols;
+- this.localDefs = new ArrayDeque<>();
+- this.localUses = new ArrayDeque<>();
+- this.returnTypes = new ArrayDeque<>();
+- }
+-
+- @Override
+- protected boolean enterDefault(final Node node) {
+- return start(node);
+- }
+-
+- @Override
+- protected Node leaveDefault(final Node node) {
+- return end(node);
+- }
+-
+- @Override
+- public Node leaveAccessNode(final AccessNode accessNode) {
+- //While Object type is assigned here, Access Specialization in FinalizeTypes may narrow this, that
+- //is why we can't set the access node base to be an object here, that will ruin access specialization
+- //for example for a.x | 17.
+- return end(ensureSymbol(Type.OBJECT, accessNode));
+- }
+-
+- private void initFunctionWideVariables(final FunctionNode functionNode, final Block body) {
+- initCompileConstant(CALLEE, body, IS_PARAM | IS_INTERNAL);
+- initCompileConstant(THIS, body, IS_PARAM | IS_THIS, Type.OBJECT);
+-
+- if (functionNode.isVarArg()) {
+- initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL);
+- if (functionNode.needsArguments()) {
+- initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED);
+- final String argumentsName = ARGUMENTS_VAR.symbolName();
+- newType(defineSymbol(body, argumentsName, IS_VAR | IS_ALWAYS_DEFINED), Type.typeFor(ARGUMENTS_VAR.type()));
+- addLocalDef(argumentsName);
+- }
+- }
+-
+- initParameters(functionNode, body);
+- initCompileConstant(SCOPE, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED);
+- initCompileConstant(RETURN, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED, Type.OBJECT);
+- }
+-
+-
+- /**
+- * This pushes all declarations (except for non-statements, i.e. for
+- * node temporaries) to the top of the function scope. This way we can
+- * get around problems like
+- *
+- * while (true) {
+- * break;
+- * if (true) {
+- * var s;
+- * }
+- * }
+- *
+- * to an arbitrary nesting depth.
+- *
+- * see NASHORN-73
+- *
+- * @param functionNode the FunctionNode we are entering
+- * @param body the body of the FunctionNode we are entering
+- */
+- private void acceptDeclarations(final FunctionNode functionNode, final Block body) {
+- // This visitor will assign symbol to all declared variables, except function declarations (which are taken care
+- // in a separate step above) and "var" declarations in for loop initializers.
+- //
+- // It also handles the case that a variable can be undefined, e.g
+- // if (cond) {
+- // x = x.y;
+- // }
+- // var x = 17;
+- //
+- // by making sure that no identifier has been found earlier in the body than the
+- // declaration - if such is the case the identifier is flagged as caBeUndefined to
+- // be safe if it turns into a local var. Otherwise corrupt bytecode results
+-
+- body.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
+- private final Set<String> uses = new HashSet<>();
+- private final Set<String> canBeUndefined = new HashSet<>();
+-
+- @Override
+- public boolean enterFunctionNode(final FunctionNode nestedFn) {
+- return false;
+- }
+-
+- @Override
+- public Node leaveIdentNode(final IdentNode identNode) {
+- uses.add(identNode.getName());
+- return identNode;
+- }
+-
+- @Override
+- public boolean enterVarNode(final VarNode varNode) {
+- final String name = varNode.getName().getName();
+- //if this is used before the var node, the var node symbol needs to be tagged as can be undefined
+- if (uses.contains(name)) {
+- canBeUndefined.add(name);
+- }
+-
+- // all uses of the declared varnode inside the var node are potentially undefined
+- // however this is a bit conservative as e.g. var x = 17; var x = 1 + x; does work
+- if (!varNode.isFunctionDeclaration() && varNode.getInit() != null) {
+- varNode.getInit().accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
+- @Override
+- public boolean enterIdentNode(final IdentNode identNode) {
+- if (name.equals(identNode.getName())) {
+- canBeUndefined.add(name);
+- }
+- return false;
+- }
+- });
+- }
+-
+- return true;
+- }
+-
+- @Override
+- public Node leaveVarNode(final VarNode varNode) {
+- // any declared symbols that aren't visited need to be typed as well, hence the list
+- if (varNode.isStatement()) {
+- final IdentNode ident = varNode.getName();
+- final Symbol symbol = defineSymbol(body, ident.getName(), IS_VAR);
+- if (canBeUndefined.contains(ident.getName())) {
+- symbol.setType(Type.OBJECT);
+- symbol.setCanBeUndefined();
+- }
+- functionNode.addDeclaredSymbol(symbol);
+- if (varNode.isFunctionDeclaration()) {
+- newType(symbol, FunctionNode.FUNCTION_TYPE);
+- symbol.setIsFunctionDeclaration();
+- }
+- return varNode.setName((IdentNode)ident.setSymbol(lc, symbol));
+- }
+-
+- return varNode;
+- }
+- });
+- }
+-
+- private void enterFunctionBody() {
+-
+- final FunctionNode functionNode = lc.getCurrentFunction();
+- final Block body = lc.getCurrentBlock();
+-
+- initFunctionWideVariables(functionNode, body);
+-
+- if (functionNode.isProgram()) {
+- initFromPropertyMap(body);
+- } else if (!functionNode.isDeclared()) {
+- // It's neither declared nor program - it's a function expression then; assign it a self-symbol.
+- assert functionNode.getSymbol() == null;
+-
+- final boolean anonymous = functionNode.isAnonymous();
+- final String name = anonymous ? null : functionNode.getIdent().getName();
+- if (!(anonymous || body.getExistingSymbol(name) != null)) {
+- assert !anonymous && name != null;
+- newType(defineSymbol(body, name, IS_VAR | IS_FUNCTION_SELF), Type.OBJECT);
+- }
+- }
+-
+- acceptDeclarations(functionNode, body);
+- }
+-
+- @Override
+- public boolean enterBlock(final Block block) {
+- start(block);
+- //ensure that we don't use information from a previous compile. This is very ugly TODO
+- //the symbols in the block should really be stateless
+- block.clearSymbols();
+-
+- if (lc.isFunctionBody()) {
+- enterFunctionBody();
+- }
+- pushLocalsBlock();
+-
+- return true;
+- }
+-
+- @Override
+- public Node leaveBlock(final Block block) {
+- popLocals();
+- return end(block);
+- }
+-
+- @Override
+- public boolean enterCallNode(final CallNode callNode) {
+- return start(callNode);
+- }
+-
+- @Override
+- public Node leaveCallNode(final CallNode callNode) {
+- return end(ensureSymbol(callNode.getType(), callNode));
+- }
+-
+- @Override
+- public boolean enterCatchNode(final CatchNode catchNode) {
+- final IdentNode exception = catchNode.getException();
+- final Block block = lc.getCurrentBlock();
+-
+- start(catchNode);
+- catchNestingLevel++;
+-
+- // define block-local exception variable
+- final String exname = exception.getName();
+- final Symbol def = defineSymbol(block, exname, IS_VAR | IS_LET | IS_ALWAYS_DEFINED);
+- newType(def, Type.OBJECT); //we can catch anything, not just ecma exceptions
+-
+- addLocalDef(exname);
+-
+- return true;
+- }
+-
+- @Override
+- public Node leaveCatchNode(final CatchNode catchNode) {
+- final IdentNode exception = catchNode.getException();
+- final Block block = lc.getCurrentBlock();
+- final Symbol symbol = findSymbol(block, exception.getName());
+-
+- catchNestingLevel--;
+-
+- assert symbol != null;
+- return end(catchNode.setException((IdentNode)exception.setSymbol(lc, symbol)));
+- }
+-
+- /**
+- * Declare the definition of a new symbol.
+- *
+- * @param name Name of symbol.
+- * @param symbolFlags Symbol flags.
+- *
+- * @return Symbol for given name or null for redefinition.
+- */
+- private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) {
+- int flags = symbolFlags;
+- Symbol symbol = findSymbol(block, name); // Locate symbol.
+- boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL;
+-
+- if (isGlobal) {
+- flags |= IS_SCOPE;
+- }
+-
+- final FunctionNode function = lc.getFunction(block);
+- if (symbol != null) {
+- // Symbol was already defined. Check if it needs to be redefined.
+- if ((flags & KINDMASK) == IS_PARAM) {
+- if (!isLocal(function, symbol)) {
+- // Not defined in this function. Create a new definition.
+- symbol = null;
+- } else if (symbol.isParam()) {
+- // Duplicate parameter. Null return will force an error.
+- assert false : "duplicate parameter";
+- return null;
+- }
+- } else if ((flags & KINDMASK) == IS_VAR) {
+- if ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET) {
+- // Always create a new definition.
+- symbol = null;
+- } else {
+- // Not defined in this function. Create a new definition.
+- if (!isLocal(function, symbol) || symbol.less(IS_VAR)) {
+- symbol = null;
+- }
+- }
+- }
+- }
+-
+- if (symbol == null) {
+- // If not found, then create a new one.
+- Block symbolBlock;
+-
+- // Determine where to create it.
+- if ((flags & Symbol.KINDMASK) == IS_VAR && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) {
+- symbolBlock = block; //internal vars are always defined in the block closest to them
+- } else if (isGlobal) {
+- symbolBlock = lc.getOutermostFunction().getBody();
+- } else {
+- symbolBlock = lc.getFunctionBody(function);
+- }
+-
+- // Create and add to appropriate block.
+- symbol = new Symbol(name, flags);
+- symbolBlock.putSymbol(lc, symbol);
+-
+- if ((flags & Symbol.KINDMASK) != IS_GLOBAL) {
+- symbol.setNeedsSlot(true);
+- }
+- } else if (symbol.less(flags)) {
+- symbol.setFlags(flags);
+- }
+-
+- return symbol;
+- }
+-
+- @Override
+- public boolean enterFunctionNode(final FunctionNode functionNode) {
+- start(functionNode, false);
+-
+- if (functionNode.isLazy()) {
+- return false;
+- }
+-
+- //an outermost function in our lexical context that is not a program (runScript)
+- //is possible - it is a function being compiled lazily
+- if (functionNode.isDeclared()) {
+- final Iterator<Block> blocks = lc.getBlocks();
+- if (blocks.hasNext()) {
+- defineSymbol(blocks.next(), functionNode.getIdent().getName(), IS_VAR);
+- }
+- }
+-
+- returnTypes.push(functionNode.getReturnType());
+- pushLocalsFunction();
+-
+- return true;
+- }
+-
+- @Override
+- public Node leaveFunctionNode(final FunctionNode functionNode) {
+- FunctionNode newFunctionNode = functionNode;
+-
+- final Block body = newFunctionNode.getBody();
+-
+- //look for this function in the parent block
+- if (functionNode.isDeclared()) {
+- final Iterator<Block> blocks = lc.getBlocks();
+- if (blocks.hasNext()) {
+- newFunctionNode = (FunctionNode)newFunctionNode.setSymbol(lc, findSymbol(blocks.next(), functionNode.getIdent().getName()));
+- }
+- } else if (!functionNode.isProgram()) {
+- final boolean anonymous = functionNode.isAnonymous();
+- final String name = anonymous ? null : functionNode.getIdent().getName();
+- if (anonymous || body.getExistingSymbol(name) != null) {
+- newFunctionNode = (FunctionNode)ensureSymbol(FunctionNode.FUNCTION_TYPE, newFunctionNode);
+- } else {
+- assert name != null;
+- final Symbol self = body.getExistingSymbol(name);
+- assert self != null && self.isFunctionSelf();
+- newFunctionNode = (FunctionNode)newFunctionNode.setSymbol(lc, body.getExistingSymbol(name));
+- }
+- }
+-
+- //unknown parameters are promoted to object type.
+- if (newFunctionNode.hasLazyChildren()) {
+- //the final body has already been assigned as we have left the function node block body by now
+- objectifySymbols(body);
+- }
+- newFunctionNode = finalizeParameters(newFunctionNode);
+- newFunctionNode = finalizeTypes(newFunctionNode);
+- for (final Symbol symbol : newFunctionNode.getDeclaredSymbols()) {
+- if (symbol.getSymbolType().isUnknown()) {
+- symbol.setType(Type.OBJECT);
+- symbol.setCanBeUndefined();
+- }
+- }
+-
+- List<VarNode> syntheticInitializers = null;
+-
+- if (body.getFlag(Block.NEEDS_SELF_SYMBOL)) {
+- syntheticInitializers = new ArrayList<>(2);
+- LOG.info("Accepting self symbol init for ", newFunctionNode.getName());
+- // "var fn = :callee"
+- syntheticInitializers.add(createSyntheticInitializer(newFunctionNode.getIdent(), CALLEE, newFunctionNode));
+- }
+-
+- if (newFunctionNode.needsArguments()) {
+- if (syntheticInitializers == null) {
+- syntheticInitializers = new ArrayList<>(1);
+- }
+- // "var arguments = :arguments"
+- syntheticInitializers.add(createSyntheticInitializer(createImplicitIdentifier(ARGUMENTS_VAR.symbolName()),
+- ARGUMENTS, newFunctionNode));
+- }
+-
+- if (syntheticInitializers != null) {
+- final List<Statement> stmts = newFunctionNode.getBody().getStatements();
+- final List<Statement> newStatements = new ArrayList<>(stmts.size() + syntheticInitializers.size());
+- newStatements.addAll(syntheticInitializers);
+- newStatements.addAll(stmts);
+- newFunctionNode = newFunctionNode.setBody(lc, newFunctionNode.getBody().setStatements(lc, newStatements));
+- }
+-
+- if (returnTypes.peek().isUnknown()) {
+- LOG.info("Unknown return type promoted to object");
+- newFunctionNode = newFunctionNode.setReturnType(lc, Type.OBJECT);
+- }
+- final Type returnType = returnTypes.pop();
+- newFunctionNode = newFunctionNode.setReturnType(lc, returnType.isUnknown() ? Type.OBJECT : returnType);
+- newFunctionNode = newFunctionNode.setState(lc, CompilationState.ATTR);
+-
+- popLocals();
+-
+- end(newFunctionNode, false);
+-
+- return newFunctionNode;
+- }
+-
+- /**
+- * Creates a synthetic initializer for a variable (a var statement that doesn't occur in the source code). Typically
+- * used to create assignmnent of {@code :callee} to the function name symbol in self-referential function
+- * expressions as well as for assignment of {@code :arguments} to {@code arguments}.
+- *
+- * @param name the ident node identifying the variable to initialize
+- * @param initConstant the compiler constant it is initialized to
+- * @param fn the function node the assignment is for
+- * @return a var node with the appropriate assignment
+- */
+- private VarNode createSyntheticInitializer(final IdentNode name, final CompilerConstants initConstant, final FunctionNode fn) {
+- final IdentNode init = compilerConstant(initConstant);
+- assert init.getSymbol() != null && init.getSymbol().hasSlot();
+-
+- VarNode synthVar = new VarNode(fn.getLineNumber(), fn.getToken(), fn.getFinish(), name, init);
+-
+- final Symbol nameSymbol = fn.getBody().getExistingSymbol(name.getName());
+- assert nameSymbol != null;
+-
+- return synthVar.setName((IdentNode)name.setSymbol(lc, nameSymbol));
+- }
+-
+- @Override
+- public Node leaveIdentNode(final IdentNode identNode) {
+- final String name = identNode.getName();
+-
+- if (identNode.isPropertyName()) {
+- // assign a pseudo symbol to property name
+- final Symbol pseudoSymbol = pseudoSymbol(name);
+- LOG.info("IdentNode is property name -> assigning pseudo symbol ", pseudoSymbol);
+- LOG.unindent();
+- return end(identNode.setSymbol(lc, pseudoSymbol));
+- }
+-
+- final Block block = lc.getCurrentBlock();
+-
+- Symbol symbol = findSymbol(block, name);
+-
+- //If an existing symbol with the name is found, use that otherwise, declare a new one
+- if (symbol != null) {
+- LOG.info("Existing symbol = ", symbol);
+- if (symbol.isFunctionSelf()) {
+- final FunctionNode functionNode = lc.getDefiningFunction(symbol);
+- assert functionNode != null;
+- assert lc.getFunctionBody(functionNode).getExistingSymbol(CALLEE.symbolName()) != null;
+- lc.setFlag(functionNode.getBody(), Block.NEEDS_SELF_SYMBOL);
+- newType(symbol, FunctionNode.FUNCTION_TYPE);
+- } else if (!identNode.isInitializedHere()) {
+- /*
+- * See NASHORN-448, JDK-8016235
+- *
+- * Here is a use outside the local def scope
+- * the inCatch check is a conservative approach to handle things that might have only been
+- * defined in the try block, but with variable declarations, which due to JavaScript rules
+- * have to be lifted up into the function scope outside the try block anyway, but as the
+- * flow can fault at almost any place in the try block and get us to the catch block, all we
+- * know is that we have a declaration, not a definition. This can be made better and less
+- * conservative once we superimpose a CFG onto the AST.
+- */
+- if (!isLocalDef(name) || inCatch()) {
+- newType(symbol, Type.OBJECT);
+- symbol.setCanBeUndefined();
+- }
+- }
+-
+- // if symbol is non-local or we're in a with block, we need to put symbol in scope (if it isn't already)
+- maybeForceScope(symbol);
+- } else {
+- LOG.info("No symbol exists. Declare undefined: ", symbol);
+- symbol = defineSymbol(block, name, IS_GLOBAL);
+- // we have never seen this before, it can be undefined
+- newType(symbol, Type.OBJECT); // TODO unknown -we have explicit casts anyway?
+- symbol.setCanBeUndefined();
+- Symbol.setSymbolIsScope(lc, symbol);
+- }
+-
+- setBlockScope(name, symbol);
+-
+- if (!identNode.isInitializedHere()) {
+- symbol.increaseUseCount();
+- }
+- addLocalUse(identNode.getName());
+-
+- return end(identNode.setSymbol(lc, symbol));
+- }
+-
+- private boolean inCatch() {
+- return catchNestingLevel > 0;
+- }
+-
+- /**
+- * If the symbol isn't already a scope symbol, and it is either not local to the current function, or it is being
+- * referenced from within a with block, we force it to be a scope symbol.
+- * @param symbol the symbol that might be scoped
+- */
+- private void maybeForceScope(final Symbol symbol) {
+- if (!symbol.isScope() && symbolNeedsToBeScope(symbol)) {
+- Symbol.setSymbolIsScope(lc, symbol);
+- }
+- }
+-
+- private boolean symbolNeedsToBeScope(Symbol symbol) {
+- if (symbol.isThis() || symbol.isInternal()) {
+- return false;
+- }
+- boolean previousWasBlock = false;
+- for (final Iterator<LexicalContextNode> it = lc.getAllNodes(); it.hasNext();) {
+- final LexicalContextNode node = it.next();
+- if (node instanceof FunctionNode) {
+- // We reached the function boundary without seeing a definition for the symbol - it needs to be in
+- // scope.
+- return true;
+- } else if (node instanceof WithNode) {
+- if (previousWasBlock) {
+- // We reached a WithNode; the symbol must be scoped. Note that if the WithNode was not immediately
+- // preceded by a block, this means we're currently processing its expression, not its body,
+- // therefore it doesn't count.
+- return true;
+- }
+- previousWasBlock = false;
+- } else if (node instanceof Block) {
+- if (((Block)node).getExistingSymbol(symbol.getName()) == symbol) {
+- // We reached the block that defines the symbol without reaching either the function boundary, or a
+- // WithNode. The symbol need not be scoped.
+- return false;
+- }
+- previousWasBlock = true;
+- } else {
+- previousWasBlock = false;
+- }
+- }
+- throw new AssertionError();
+- }
+-
+- private void setBlockScope(final String name, final Symbol symbol) {
+- assert symbol != null;
+- if (symbol.isGlobal()) {
+- setUsesGlobalSymbol();
+- return;
+- }
+-
+- if (symbol.isScope()) {
+- Block scopeBlock = null;
+- for (final Iterator<LexicalContextNode> contextNodeIter = lc.getAllNodes(); contextNodeIter.hasNext(); ) {
+- final LexicalContextNode node = contextNodeIter.next();
+- if (node instanceof Block) {
+- if (((Block)node).getExistingSymbol(name) != null) {
+- scopeBlock = (Block)node;
+- break;
+- }
+- } else if (node instanceof FunctionNode) {
+- lc.setFlag(node, FunctionNode.USES_ANCESTOR_SCOPE);
+- }
+- }
+-
+- if (scopeBlock != null) {
+- assert lc.contains(scopeBlock);
+- lc.setBlockNeedsScope(scopeBlock);
+- }
+- }
+- }
+-
+- /**
+- * Marks the current function as one using any global symbol. The function and all its parent functions will all be
+- * marked as needing parent scope.
+- * @see #needsParentScope()
+- */
+- private void setUsesGlobalSymbol() {
+- for (final Iterator<FunctionNode> fns = lc.getFunctions(); fns.hasNext();) {
+- lc.setFlag(fns.next(), FunctionNode.USES_ANCESTOR_SCOPE);
+- }
+- }
+-
+- /**
+- * Search for symbol in the lexical context starting from the given block.
+- * @param name Symbol name.
+- * @return Found symbol or null if not found.
+- */
+- private Symbol findSymbol(final Block block, final String name) {
+- // Search up block chain to locate symbol.
+-
+- for (final Iterator<Block> blocks = lc.getBlocks(block); blocks.hasNext();) {
+- // Find name.
+- final Symbol symbol = blocks.next().getExistingSymbol(name);
+- // If found then we are good.
+- if (symbol != null) {
+- return symbol;
+- }
+- }
+- return null;
+- }
+-
+- @Override
+- public Node leaveIndexNode(final IndexNode indexNode) {
+- return end(ensureSymbol(Type.OBJECT, indexNode));
+- }
+-
+- @SuppressWarnings("rawtypes")
+- @Override
+- public Node leaveLiteralNode(final LiteralNode literalNode) {
+- assert !literalNode.isTokenType(TokenType.THIS) : "tokentype for " + literalNode + " is this"; //guard against old dead code case. literal nodes should never inherit tokens
+- assert literalNode instanceof ArrayLiteralNode || !(literalNode.getValue() instanceof Node) : "literals with Node values not supported";
+- final Symbol symbol = new Symbol(lc.getCurrentFunction().uniqueName(LITERAL_PREFIX.symbolName()), IS_CONSTANT, literalNode.getType());
+- if (literalNode instanceof ArrayLiteralNode) {
+- ((ArrayLiteralNode)literalNode).analyze();
+- }
+- return end(literalNode.setSymbol(lc, symbol));
+- }
+-
+- @Override
+- public boolean enterObjectNode(final ObjectNode objectNode) {
+- return start(objectNode);
+- }
+-
+- @Override
+- public Node leaveObjectNode(final ObjectNode objectNode) {
+- return end(ensureSymbol(Type.OBJECT, objectNode));
+- }
+-
+- @Override
+- public Node leaveReturnNode(final ReturnNode returnNode) {
+- final Expression expr = returnNode.getExpression();
+- final Type returnType;
+-
+- if (expr != null) {
+- //we can't do parameter specialization if we return something that hasn't been typed yet
+- final Symbol symbol = expr.getSymbol();
+- if (expr.getType().isUnknown() && symbol.isParam()) {
+- symbol.setType(Type.OBJECT);
+- }
+-
+- returnType = widestReturnType(returnTypes.pop(), symbol.getSymbolType());
+- } else {
+- returnType = Type.OBJECT; //undefined
+- }
+- LOG.info("Returntype is now ", returnType);
+- returnTypes.push(returnType);
+-
+- end(returnNode);
+-
+- return returnNode;
+- }
+-
+- @Override
+- public Node leaveSwitchNode(final SwitchNode switchNode) {
+- Type type = Type.UNKNOWN;
+-
+- final List<CaseNode> newCases = new ArrayList<>();
+- for (final CaseNode caseNode : switchNode.getCases()) {
+- final Node test = caseNode.getTest();
+-
+- CaseNode newCaseNode = caseNode;
+- if (test != null) {
+- if (test instanceof LiteralNode) {
+- //go down to integers if we can
+- final LiteralNode<?> lit = (LiteralNode<?>)test;
+- if (lit.isNumeric() && !(lit.getValue() instanceof Integer)) {
+- if (JSType.isRepresentableAsInt(lit.getNumber())) {
+- newCaseNode = caseNode.setTest((Expression)LiteralNode.newInstance(lit, lit.getInt32()).accept(this));
+- }
+- }
+- } else {
+- // the "all integer" case that CodeGenerator optimizes for currently assumes literals only
+- type = Type.OBJECT;
+- }
+-
+- final Type newCaseType = newCaseNode.getTest().getType();
+- if (newCaseType.isBoolean()) {
+- type = Type.OBJECT; //booleans and integers aren't assignment compatible
+- } else {
+- type = Type.widest(type, newCaseType);
+- }
+- }
+-
+- newCases.add(newCaseNode);
+- }
+-
+- //only optimize for all integers
+- if (!type.isInteger()) {
+- type = Type.OBJECT;
+- }
+-
+- switchNode.setTag(newInternal(lc.getCurrentFunction().uniqueName(SWITCH_TAG_PREFIX.symbolName()), type));
+-
+- end(switchNode);
+-
+- return switchNode.setCases(lc, newCases);
+- }
+-
+- @Override
+- public Node leaveTryNode(final TryNode tryNode) {
+- tryNode.setException(exceptionSymbol());
+-
+- if (tryNode.getFinallyBody() != null) {
+- tryNode.setFinallyCatchAll(exceptionSymbol());
+- }
+-
+- end(tryNode);
+-
+- return tryNode;
+- }
+-
+- @Override
+- public boolean enterVarNode(final VarNode varNode) {
+- start(varNode);
+-
+- final IdentNode ident = varNode.getName();
+- final String name = ident.getName();
+-
+- final Symbol symbol = defineSymbol(lc.getCurrentBlock(), name, IS_VAR);
+- assert symbol != null;
+-
+- // NASHORN-467 - use before definition of vars - conservative
+- if (isLocalUse(ident.getName())) {
+- newType(symbol, Type.OBJECT);
+- symbol.setCanBeUndefined();
+- }
+-
+- return true;
+- }
+-
+- @Override
+- public Node leaveVarNode(final VarNode varNode) {
+- final Expression init = varNode.getInit();
+- final IdentNode ident = varNode.getName();
+- final String name = ident.getName();
+-
+- final Symbol symbol = findSymbol(lc.getCurrentBlock(), name);
+- assert ident.getSymbol() == symbol;
+-
+- if (init == null) {
+- // var x; with no init will be treated like a use of x by
+- // leaveIdentNode unless we remove the name from the localdef list.
+- removeLocalDef(name);
+- return end(varNode);
+- }
+-
+- addLocalDef(name);
+-
+- assert symbol != null;
+-
+- final IdentNode newIdent = (IdentNode)ident.setSymbol(lc, symbol);
+-
+- final VarNode newVarNode = varNode.setName(newIdent);
+-
+- final boolean isScript = lc.getDefiningFunction(symbol).isProgram(); //see NASHORN-56
+- if ((init.getType().isNumeric() || init.getType().isBoolean()) && !isScript) {
+- // Forbid integers as local vars for now as we have no way to treat them as undefined
+- newType(symbol, init.getType());
+- } else {
+- newType(symbol, Type.OBJECT);
+- }
+-
+- assert newVarNode.getName().hasType() : newVarNode + " has no type";
+-
+- return end(newVarNode);
+- }
+-
+- @Override
+- public Node leaveADD(final UnaryNode unaryNode) {
+- return end(ensureSymbol(arithType(), unaryNode));
+- }
+-
+- @Override
+- public Node leaveBIT_NOT(final UnaryNode unaryNode) {
+- return end(ensureSymbol(Type.INT, unaryNode));
+- }
+-
+- @Override
+- public Node leaveDECINC(final UnaryNode unaryNode) {
+- // @see assignOffset
+- final Type type = arithType();
+- newType(unaryNode.rhs().getSymbol(), type);
+- return end(ensureSymbol(type, unaryNode));
+- }
+-
+- @Override
+- public Node leaveDELETE(final UnaryNode unaryNode) {
+- final FunctionNode currentFunctionNode = lc.getCurrentFunction();
+- final boolean strictMode = currentFunctionNode.isStrict();
+- final Expression rhs = unaryNode.rhs();
+- final Expression strictFlagNode = (Expression)LiteralNode.newInstance(unaryNode, strictMode).accept(this);
+-
+- Request request = Request.DELETE;
+- final List<Expression> args = new ArrayList<>();
+-
+- if (rhs instanceof IdentNode) {
+- // If this is a declared variable or a function parameter, delete always fails (except for globals).
+- final String name = ((IdentNode)rhs).getName();
+-
+- final boolean failDelete = strictMode || rhs.getSymbol().isParam() || (rhs.getSymbol().isVar() && !isProgramLevelSymbol(name));
+-
+- if (failDelete && rhs.getSymbol().isThis()) {
+- return LiteralNode.newInstance(unaryNode, true).accept(this);
+- }
+- final Expression literalNode = (Expression)LiteralNode.newInstance(unaryNode, name).accept(this);
+-
+- if (!failDelete) {
+- args.add(compilerConstant(SCOPE));
+- }
+- args.add(literalNode);
+- args.add(strictFlagNode);
+-
+- if (failDelete) {
+- request = Request.FAIL_DELETE;
+- }
+- } else if (rhs instanceof AccessNode) {
+- final Expression base = ((AccessNode)rhs).getBase();
+- final IdentNode property = ((AccessNode)rhs).getProperty();
+-
+- args.add(base);
+- args.add((Expression)LiteralNode.newInstance(unaryNode, property.getName()).accept(this));
+- args.add(strictFlagNode);
+-
+- } else if (rhs instanceof IndexNode) {
+- final IndexNode indexNode = (IndexNode)rhs;
+- final Expression base = indexNode.getBase();
+- final Expression index = indexNode.getIndex();
+-
+- args.add(base);
+- args.add(index);
+- args.add(strictFlagNode);
+-
+- } else {
+- return LiteralNode.newInstance(unaryNode, true).accept(this);
+- }
+-
+- final RuntimeNode runtimeNode = new RuntimeNode(unaryNode, request, args);
+- assert runtimeNode.getSymbol() == unaryNode.getSymbol(); //unary parent constructor should do this
+-
+- return leaveRuntimeNode(runtimeNode);
+- }
+-
+- /**
+- * Is the symbol denoted by the specified name in the current lexical context defined in the program level
+- * @param name the name of the symbol
+- * @return true if the symbol denoted by the specified name in the current lexical context defined in the program level.
+- */
+- private boolean isProgramLevelSymbol(final String name) {
+- for(final Iterator<Block> it = lc.getBlocks(); it.hasNext();) {
+- final Block next = it.next();
+- if(next.getExistingSymbol(name) != null) {
+- return next == lc.getFunctionBody(lc.getOutermostFunction());
+- }
+- }
+- throw new AssertionError("Couldn't find symbol " + name + " in the context");
+- }
+-
+- @Override
+- public Node leaveNEW(final UnaryNode unaryNode) {
+- return end(ensureSymbol(Type.OBJECT, unaryNode.setRHS(((CallNode)unaryNode.rhs()).setIsNew())));
+- }
+-
+- @Override
+- public Node leaveNOT(final UnaryNode unaryNode) {
+- return end(ensureSymbol(Type.BOOLEAN, unaryNode));
+- }
+-
+- private IdentNode compilerConstant(CompilerConstants cc) {
+- return (IdentNode)createImplicitIdentifier(cc.symbolName()).setSymbol(lc, lc.getCurrentFunction().compilerConstant(cc));
+- }
+-
+- /**
+- * Creates an ident node for an implicit identifier within the function (one not declared in the script source
+- * code). These identifiers are defined with function's token and finish.
+- * @param name the name of the identifier
+- * @return an ident node representing the implicit identifier.
+- */
+- private IdentNode createImplicitIdentifier(final String name) {
+- final FunctionNode fn = lc.getCurrentFunction();
+- return new IdentNode(fn.getToken(), fn.getFinish(), name);
+- }
+-
+- @Override
+- public Node leaveTYPEOF(final UnaryNode unaryNode) {
+- final Expression rhs = unaryNode.rhs();
+-
+- List<Expression> args = new ArrayList<>();
+- if (rhs instanceof IdentNode && !rhs.getSymbol().isParam() && !rhs.getSymbol().isVar()) {
+- args.add(compilerConstant(SCOPE));
+- args.add((Expression)LiteralNode.newInstance(rhs, ((IdentNode)rhs).getName()).accept(this)); //null
+- } else {
+- args.add(rhs);
+- args.add((Expression)LiteralNode.newInstance(unaryNode).accept(this)); //null, do not reuse token of identifier rhs, it can be e.g. 'this'
+- }
+-
+- RuntimeNode runtimeNode = new RuntimeNode(unaryNode, Request.TYPEOF, args);
+- assert runtimeNode.getSymbol() == unaryNode.getSymbol();
+-
+- runtimeNode = (RuntimeNode)leaveRuntimeNode(runtimeNode);
+-
+- end(unaryNode);
+-
+- return runtimeNode;
+- }
+-
+- @Override
+- public Node leaveRuntimeNode(final RuntimeNode runtimeNode) {
+- return end(ensureSymbol(runtimeNode.getRequest().getReturnType(), runtimeNode));
+- }
+-
+- @Override
+- public Node leaveSUB(final UnaryNode unaryNode) {
+- return end(ensureSymbol(arithType(), unaryNode));
+- }
+-
+- @Override
+- public Node leaveVOID(final UnaryNode unaryNode) {
+- return end(ensureSymbol(Type.OBJECT, unaryNode));
+- }
+-
+- /**
+- * Add is a special binary, as it works not only on arithmetic, but for
+- * strings etc as well.
+- */
+- @Override
+- public Node leaveADD(final BinaryNode binaryNode) {
+- final Expression lhs = binaryNode.lhs();
+- final Expression rhs = binaryNode.rhs();
+-
+- ensureTypeNotUnknown(lhs);
+- ensureTypeNotUnknown(rhs);
+- //even if we are adding two known types, this can overflow. i.e.
+- //int and number -> number.
+- //int and int are also number though.
+- //something and object is object
+- return end(ensureSymbol(Type.widest(arithType(), Type.widest(lhs.getType(), rhs.getType())), binaryNode));
+- }
+-
+- @Override
+- public Node leaveAND(final BinaryNode binaryNode) {
+- return end(ensureSymbol(Type.OBJECT, binaryNode));
+- }
+-
+- /**
+- * This is a helper called before an assignment.
+- * @param binaryNode assignment node
+- */
+- private boolean enterAssignmentNode(final BinaryNode binaryNode) {
+- start(binaryNode);
+-
+- return true;
+- }
+-
+-
+- /**
+- * This assign helper is called after an assignment, when all children of
+- * the assign has been processed. It fixes the types and recursively makes
+- * sure that everyhing has slots that should have them in the chain.
+- *
+- * @param binaryNode assignment node
+- */
+- private Node leaveAssignmentNode(final BinaryNode binaryNode) {
+- final Expression lhs = binaryNode.lhs();
+- final Expression rhs = binaryNode.rhs();
+- final Type type;
+-
+- if (lhs instanceof IdentNode) {
+- final Block block = lc.getCurrentBlock();
+- final IdentNode ident = (IdentNode)lhs;
+- final String name = ident.getName();
+- final Symbol symbol = findSymbol(block, name);
+-
+- if (symbol == null) {
+- defineSymbol(block, name, IS_GLOBAL);
+- } else {
+- maybeForceScope(symbol);
+- }
+-
+- addLocalDef(name);
+- }
+-
+- if (rhs.getType().isNumeric()) {
+- type = Type.widest(lhs.getType(), rhs.getType());
+- } else {
+- type = Type.OBJECT; //force lhs to be an object if not numeric assignment, e.g. strings too.
+- }
+-
+- newType(lhs.getSymbol(), type);
+- return end(ensureSymbol(type, binaryNode));
+- }
+-
+- private boolean isLocal(FunctionNode function, Symbol symbol) {
+- final FunctionNode definingFn = lc.getDefiningFunction(symbol);
+- // Temp symbols are not assigned to a block, so their defining fn is null; those can be assumed local
+- return definingFn == null || definingFn == function;
+- }
+-
+- @Override
+- public boolean enterASSIGN(final BinaryNode binaryNode) {
+- return enterAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public Node leaveASSIGN(final BinaryNode binaryNode) {
+- return leaveAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public boolean enterASSIGN_ADD(final BinaryNode binaryNode) {
+- return enterAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public Node leaveASSIGN_ADD(final BinaryNode binaryNode) {
+- final Expression lhs = binaryNode.lhs();
+- final Expression rhs = binaryNode.rhs();
+-
+- final Type widest = Type.widest(lhs.getType(), rhs.getType());
+- //Type.NUMBER if we can't prove that the add doesn't overflow. todo
+- return leaveSelfModifyingAssignmentNode(binaryNode, widest.isNumeric() ? Type.NUMBER : Type.OBJECT);
+- }
+-
+- @Override
+- public boolean enterASSIGN_BIT_AND(final BinaryNode binaryNode) {
+- return enterAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public Node leaveASSIGN_BIT_AND(final BinaryNode binaryNode) {
+- return leaveSelfModifyingAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public boolean enterASSIGN_BIT_OR(final BinaryNode binaryNode) {
+- return enterAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public Node leaveASSIGN_BIT_OR(final BinaryNode binaryNode) {
+- return leaveSelfModifyingAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public boolean enterASSIGN_BIT_XOR(final BinaryNode binaryNode) {
+- return enterAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public Node leaveASSIGN_BIT_XOR(final BinaryNode binaryNode) {
+- return leaveSelfModifyingAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public boolean enterASSIGN_DIV(final BinaryNode binaryNode) {
+- return enterAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public Node leaveASSIGN_DIV(final BinaryNode binaryNode) {
+- return leaveSelfModifyingAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public boolean enterASSIGN_MOD(final BinaryNode binaryNode) {
+- return enterAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public Node leaveASSIGN_MOD(final BinaryNode binaryNode) {
+- return leaveSelfModifyingAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public boolean enterASSIGN_MUL(final BinaryNode binaryNode) {
+- return enterAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public Node leaveASSIGN_MUL(final BinaryNode binaryNode) {
+- return leaveSelfModifyingAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public boolean enterASSIGN_SAR(final BinaryNode binaryNode) {
+- return enterAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public Node leaveASSIGN_SAR(final BinaryNode binaryNode) {
+- return leaveSelfModifyingAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public boolean enterASSIGN_SHL(final BinaryNode binaryNode) {
+- return enterAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public Node leaveASSIGN_SHL(final BinaryNode binaryNode) {
+- return leaveSelfModifyingAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public boolean enterASSIGN_SHR(final BinaryNode binaryNode) {
+- return enterAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public Node leaveASSIGN_SHR(final BinaryNode binaryNode) {
+- return leaveSelfModifyingAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public boolean enterASSIGN_SUB(final BinaryNode binaryNode) {
+- return enterAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public Node leaveASSIGN_SUB(final BinaryNode binaryNode) {
+- return leaveSelfModifyingAssignmentNode(binaryNode);
+- }
+-
+- @Override
+- public Node leaveBIT_AND(final BinaryNode binaryNode) {
+- return end(coerce(binaryNode, Type.INT));
+- }
+-
+- @Override
+- public Node leaveBIT_OR(final BinaryNode binaryNode) {
+- return end(coerce(binaryNode, Type.INT));
+- }
+-
+- @Override
+- public Node leaveBIT_XOR(final BinaryNode binaryNode) {
+- return end(coerce(binaryNode, Type.INT));
+- }
+-
+- @Override
+- public Node leaveCOMMARIGHT(final BinaryNode binaryNode) {
+- return leaveComma(binaryNode, binaryNode.rhs());
+- }
+-
+- @Override
+- public Node leaveCOMMALEFT(final BinaryNode binaryNode) {
+- return leaveComma(binaryNode, binaryNode.lhs());
+- }
+-
+- private Node leaveComma(final BinaryNode commaNode, final Expression effectiveExpr) {
+- ensureTypeNotUnknown(effectiveExpr);
+- return end(ensureSymbol(effectiveExpr.getType(), commaNode));
+- }
+-
+- @Override
+- public Node leaveDIV(final BinaryNode binaryNode) {
+- return leaveBinaryArithmetic(binaryNode);
+- }
+-
+- private Node leaveCmp(final BinaryNode binaryNode) {
+- ensureTypeNotUnknown(binaryNode.lhs());
+- ensureTypeNotUnknown(binaryNode.rhs());
+- Type widest = Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType());
+- ensureSymbol(widest, binaryNode.lhs());
+- ensureSymbol(widest, binaryNode.rhs());
+- return end(ensureSymbol(Type.BOOLEAN, binaryNode));
+- }
+-
+- private Node coerce(final BinaryNode binaryNode, final Type operandType, final Type destType) {
+- // TODO we currently don't support changing inferred type based on uses, only on
+- // definitions. we would need some additional logic. We probably want to do that
+- // in the future, if e.g. a specialized method gets parameter that is only used
+- // as, say, an int : function(x) { return x & 4711 }, and x is not defined in
+- // the function. to make this work, uncomment the following two type inferences
+- // and debug.
+- //newType(binaryNode.lhs().getSymbol(), operandType);
+- //newType(binaryNode.rhs().getSymbol(), operandType);
+- return ensureSymbol(destType, binaryNode);
+- }
+-
+- private Node coerce(final BinaryNode binaryNode, final Type type) {
+- return coerce(binaryNode, type, type);
+- }
+-
+- //leave a binary node and inherit the widest type of lhs , rhs
+- private Node leaveBinaryArithmetic(final BinaryNode binaryNode) {
+- assert !Compiler.shouldUseIntegerArithmetic();
+- return end(coerce(binaryNode, Type.NUMBER));
+- }
+-
+- @Override
+- public Node leaveEQ(final BinaryNode binaryNode) {
+- return leaveCmp(binaryNode);
+- }
+-
+- @Override
+- public Node leaveEQ_STRICT(final BinaryNode binaryNode) {
+- return leaveCmp(binaryNode);
+- }
+-
+- @Override
+- public Node leaveGE(final BinaryNode binaryNode) {
+- return leaveCmp(binaryNode);
+- }
+-
+- @Override
+- public Node leaveGT(final BinaryNode binaryNode) {
+- return leaveCmp(binaryNode);
+- }
+-
+- @Override
+- public Node leaveIN(final BinaryNode binaryNode) {
+- return leaveBinaryRuntimeOperator(binaryNode, Request.IN);
+- }
+-
+- @Override
+- public Node leaveINSTANCEOF(final BinaryNode binaryNode) {
+- return leaveBinaryRuntimeOperator(binaryNode, Request.INSTANCEOF);
+- }
+-
+- private Node leaveBinaryRuntimeOperator(final BinaryNode binaryNode, final Request request) {
+- try {
+- // Don't do a full RuntimeNode.accept, as we don't want to double-visit the binary node operands
+- return leaveRuntimeNode(new RuntimeNode(binaryNode, request));
+- } finally {
+- end(binaryNode);
+- }
+- }
+-
+- @Override
+- public Node leaveLE(final BinaryNode binaryNode) {
+- return leaveCmp(binaryNode);
+- }
+-
+- @Override
+- public Node leaveLT(final BinaryNode binaryNode) {
+- return leaveCmp(binaryNode);
+- }
+-
+- @Override
+- public Node leaveMOD(final BinaryNode binaryNode) {
+- return leaveBinaryArithmetic(binaryNode);
+- }
+-
+- @Override
+- public Node leaveMUL(final BinaryNode binaryNode) {
+- return leaveBinaryArithmetic(binaryNode);
+- }
+-
+- @Override
+- public Node leaveNE(final BinaryNode binaryNode) {
+- return leaveCmp(binaryNode);
+- }
+-
+- @Override
+- public Node leaveNE_STRICT(final BinaryNode binaryNode) {
+- return leaveCmp(binaryNode);
+- }
+-
+- @Override
+- public Node leaveOR(final BinaryNode binaryNode) {
+- return end(ensureSymbol(Type.OBJECT, binaryNode));
+- }
+-
+- @Override
+- public Node leaveSAR(final BinaryNode binaryNode) {
+- return end(coerce(binaryNode, Type.INT));
+- }
+-
+- @Override
+- public Node leaveSHL(final BinaryNode binaryNode) {
+- return end(coerce(binaryNode, Type.INT));
+- }
+-
+- @Override
+- public Node leaveSHR(final BinaryNode binaryNode) {
+- return end(coerce(binaryNode, Type.LONG));
+- }
+-
+- @Override
+- public Node leaveSUB(final BinaryNode binaryNode) {
+- return leaveBinaryArithmetic(binaryNode);
+- }
+-
+- @Override
+- public Node leaveForNode(final ForNode forNode) {
+- if (forNode.isForIn()) {
+- forNode.setIterator(newInternal(lc.getCurrentFunction().uniqueName(ITERATOR_PREFIX.symbolName()), Type.typeFor(ITERATOR_PREFIX.type()))); //NASHORN-73
+- /*
+- * Iterators return objects, so we need to widen the scope of the
+- * init variable if it, for example, has been assigned double type
+- * see NASHORN-50
+- */
+- newType(forNode.getInit().getSymbol(), Type.OBJECT);
+- }
+-
+- end(forNode);
+-
+- return forNode;
+- }
+-
+- @Override
+- public Node leaveTernaryNode(final TernaryNode ternaryNode) {
+- final Expression trueExpr = ternaryNode.getTrueExpression();
+- final Expression falseExpr = ternaryNode.getFalseExpression();
+-
+- ensureTypeNotUnknown(trueExpr);
+- ensureTypeNotUnknown(falseExpr);
+-
+- final Type type = widestReturnType(trueExpr.getType(), falseExpr.getType());
+- return end(ensureSymbol(type, ternaryNode));
+- }
+-
+- /**
+- * When doing widening for return types of a function or a ternary operator, it is not valid to widen a boolean to
+- * anything other than Object. Also, widening a numeric type to an object type must widen to Object proper and not
+- * any more specific subclass (e.g. widest of int/long/double and String is Object).
+- * @param t1 type 1
+- * @param t2 type 2
+- * @return wider of t1 and t2, except if one is boolean and the other is neither boolean nor unknown, or if one is
+- * numeric and the other is neither numeric nor unknown in which case {@code Type.OBJECT} is returned.
+- */
+- private static Type widestReturnType(final Type t1, final Type t2) {
+- if (t1.isUnknown()) {
+- return t2;
+- } else if (t2.isUnknown()) {
+- return t1;
+- } else if (t1.isBoolean() != t2.isBoolean() || t1.isNumeric() != t2.isNumeric()) {
+- return Type.OBJECT;
+- }
+- return Type.widest(t1, t2);
+- }
+-
+- private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags) {
+- final Class<?> type = cc.type();
+- // Must not call this method for constants with no explicit types; use the one with (..., Type) signature instead.
+- assert type != null;
+- initCompileConstant(cc, block, flags, Type.typeFor(type));
+- }
+-
+- private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags, final Type type) {
+- final Symbol symbol = defineSymbol(block, cc.symbolName(), flags);
+- symbol.setTypeOverride(type);
+- symbol.setNeedsSlot(true);
+- }
+-
+- /**
+- * Initialize parameters for function node. This may require specializing
+- * types if a specialization profile is known
+- *
+- * @param functionNode the function node
+- */
+- private void initParameters(final FunctionNode functionNode, final Block body) {
+- int pos = 0;
+- for (final IdentNode param : functionNode.getParameters()) {
+- addLocalDef(param.getName());
+-
+- final Type callSiteParamType = functionNode.getHints().getParameterType(pos);
+- int flags = IS_PARAM;
+- if (callSiteParamType != null) {
+- LOG.info("Param ", param, " has a callsite type ", callSiteParamType, ". Using that.");
+- flags |= Symbol.IS_SPECIALIZED_PARAM;
+- }
+-
+- final Symbol paramSymbol = defineSymbol(body, param.getName(), flags);
+- assert paramSymbol != null;
+-
+- newType(paramSymbol, callSiteParamType == null ? Type.UNKNOWN : callSiteParamType);
+-
+- LOG.info("Initialized param ", pos, "=", paramSymbol);
+- pos++;
+- }
+-
+- }
+-
+- /**
+- * This has to run before fix assignment types, store any type specializations for
+- * paramters, then turn then to objects for the generic version of this method
+- *
+- * @param functionNode functionNode
+- */
+- private FunctionNode finalizeParameters(final FunctionNode functionNode) {
+- final List<IdentNode> newParams = new ArrayList<>();
+- final boolean isVarArg = functionNode.isVarArg();
+- final int nparams = functionNode.getParameters().size();
+-
+- int specialize = 0;
+- int pos = 0;
+- for (final IdentNode param : functionNode.getParameters()) {
+- final Symbol paramSymbol = functionNode.getBody().getExistingSymbol(param.getName());
+- assert paramSymbol != null;
+- assert paramSymbol.isParam();
+- newParams.add((IdentNode)param.setSymbol(lc, paramSymbol));
+-
+- assert paramSymbol != null;
+- Type type = functionNode.getHints().getParameterType(pos);
+- if (type == null) {
+- type = Type.OBJECT;
+- }
+-
+- // if we know that a parameter is only used as a certain type throughout
+- // this function, we can tell the runtime system that no matter what the
+- // call site is, use this information:
+- // we also need more than half of the parameters to be specializable
+- // for the heuristic to be worth it, and we need more than one use of
+- // the parameter to consider it, i.e. function(x) { call(x); } doens't count
+- if (paramSymbol.getUseCount() > 1 && !paramSymbol.getSymbolType().isObject()) {
+- LOG.finest("Parameter ", param, " could profit from specialization to ", paramSymbol.getSymbolType());
+- specialize++;
+- }
+-
+- newType(paramSymbol, Type.widest(type, paramSymbol.getSymbolType()));
+-
+- // parameters should not be slots for a function that uses variable arity signature
+- if (isVarArg) {
+- paramSymbol.setNeedsSlot(false);
+- }
+-
+- pos++;
+- }
+-
+- FunctionNode newFunctionNode = functionNode;
+-
+- if (nparams == 0 || (specialize * 2) < nparams) {
+- newFunctionNode = newFunctionNode.clearSnapshot(lc);
+- }
+-
+- return newFunctionNode.setParameters(lc, newParams);
+- }
+-
+- /**
+- * Move any properties from a global map into the scope of this method
+- * @param block the function node body for which to init scope vars
+- */
+- private void initFromPropertyMap(final Block block) {
+- // For a script, add scope symbols as defined in the property map
+-
+- final PropertyMap map = Context.getGlobalMap();
+-
+- for (final Property property : map.getProperties()) {
+- final String key = property.getKey();
+- final Symbol symbol = defineSymbol(block, key, IS_GLOBAL);
+- newType(symbol, Type.OBJECT);
+- LOG.info("Added global symbol from property map ", symbol);
+- }
+- }
+-
+- private static void ensureTypeNotUnknown(final Expression node) {
+-
+- final Symbol symbol = node.getSymbol();
+-
+- LOG.info("Ensure type not unknown for: ", symbol);
+-
+- /*
+- * Note that not just unknowns, but params need to be blown
+- * up to objects, because we can have something like
+- *
+- * function f(a) {
+- * var b = ~a; //b and a are inferred to be int
+- * return b;
+- * }
+- *
+- * In this case, it would be correct to say that "if you have
+- * an int at the callsite, just pass it".
+- *
+- * However
+- *
+- * function f(a) {
+- * var b = ~a; //b and a are inferred to be int
+- * return b == 17; //b is still inferred to be int.
+- * }
+- *
+- * can be called with f("17") and if we assume that b is an
+- * int and don't blow it up to an object in the comparison, we
+- * are screwed. I hate JavaScript.
+- *
+- * This check has to be done for any operation that might take
+- * objects as parameters, for example +, but not *, which is known
+- * to coerce types into doubles
+- */
+- if (node.getType().isUnknown() || (symbol.isParam() && !symbol.isSpecializedParam())) {
+- newType(symbol, Type.OBJECT);
+- symbol.setCanBeUndefined();
+- }
+- }
+-
+- private static Symbol pseudoSymbol(final String name) {
+- return new Symbol(name, 0, Type.OBJECT);
+- }
+-
+- private Symbol exceptionSymbol() {
+- return newInternal(lc.getCurrentFunction().uniqueName(EXCEPTION_PREFIX.symbolName()), Type.typeFor(EXCEPTION_PREFIX.type()));
+- }
+-
+- /**
+- * Return the type that arithmetic ops should use. Until we have implemented better type
+- * analysis (range based) or overflow checks that are fast enough for int arithmetic,
+- * this is the number type
+- * @return the arithetic type
+- */
+- private static Type arithType() {
+- return Compiler.shouldUseIntegerArithmetic() ? Type.INT : Type.NUMBER;
+- }
+-
+- /**
+- * If types have changed, we can have failed to update vars. For example
+- *
+- * var x = 17; //x is int
+- * x = "apa"; //x is object. This will be converted fine
+- *
+- * @param functionNode
+- */
+- private FunctionNode finalizeTypes(final FunctionNode functionNode) {
+- final Set<Node> changed = new HashSet<>();
+- FunctionNode currentFunctionNode = functionNode;
+- do {
+- changed.clear();
+- final FunctionNode newFunctionNode = (FunctionNode)currentFunctionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
+-
+- private Expression widen(final Expression node, final Type to) {
+- if (node instanceof LiteralNode) {
+- return node;
+- }
+- Type from = node.getType();
+- if (!Type.areEquivalent(from, to) && Type.widest(from, to) == to) {
+- LOG.fine("Had to post pass widen '", node, "' ", Debug.id(node), " from ", node.getType(), " to ", to);
+- Symbol symbol = node.getSymbol();
+- if (symbol.isShared() && symbol.wouldChangeType(to)) {
+- symbol = temporarySymbols.getTypedTemporarySymbol(to);
+- }
+- newType(symbol, to);
+- final Expression newNode = node.setSymbol(lc, symbol);
+- changed.add(newNode);
+- return newNode;
+- }
+- return node;
+- }
+-
+- @Override
+- public boolean enterFunctionNode(final FunctionNode node) {
+- return !node.isLazy();
+- }
+-
+- //
+- // Eg.
+- //
+- // var d = 17;
+- // var e;
+- // e = d; //initially typed as int for node type, should retype as double
+- // e = object;
+- //
+- // var d = 17;
+- // var e;
+- // e -= d; //initially type number, should number remain with a final conversion supplied by Store. ugly, but the computation result of the sub is numeric
+- // e = object;
+- //
+- @SuppressWarnings("fallthrough")
+- @Override
+- public Node leaveBinaryNode(final BinaryNode binaryNode) {
+- final Type widest = Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType());
+- BinaryNode newBinaryNode = binaryNode;
+-
+- if (isAdd(binaryNode)) {
+- newBinaryNode = (BinaryNode)widen(newBinaryNode, widest);
+- if (newBinaryNode.getType().isObject() && !isAddString(newBinaryNode)) {
+- return new RuntimeNode(newBinaryNode, Request.ADD);
+- }
+- } else if (binaryNode.isComparison()) {
+- final Expression lhs = newBinaryNode.lhs();
+- final Expression rhs = newBinaryNode.rhs();
+-
+- Type cmpWidest = Type.widest(lhs.getType(), rhs.getType());
+-
+- boolean newRuntimeNode = false, finalized = false;
+- switch (newBinaryNode.tokenType()) {
+- case EQ_STRICT:
+- case NE_STRICT:
+- if (lhs.getType().isBoolean() != rhs.getType().isBoolean()) {
+- newRuntimeNode = true;
+- cmpWidest = Type.OBJECT;
+- finalized = true;
+- }
+- //fallthru
+- default:
+- if (newRuntimeNode || cmpWidest.isObject()) {
+- return new RuntimeNode(newBinaryNode, Request.requestFor(binaryNode)).setIsFinal(finalized);
+- }
+- break;
+- }
+-
+- return newBinaryNode;
+- } else {
+- if (!binaryNode.isAssignment() || binaryNode.isSelfModifying()) {
+- return newBinaryNode;
+- }
+- checkThisAssignment(binaryNode);
+- newBinaryNode = newBinaryNode.setLHS(widen(newBinaryNode.lhs(), widest));
+- newBinaryNode = (BinaryNode)widen(newBinaryNode, widest);
+- }
+-
+- return newBinaryNode;
+-
+- }
+-
+- private boolean isAdd(final Node node) {
+- return node.isTokenType(TokenType.ADD);
+- }
+-
+- /**
+- * Determine if the outcome of + operator is a string.
+- *
+- * @param node Node to test.
+- * @return true if a string result.
+- */
+- private boolean isAddString(final Node node) {
+- if (node instanceof BinaryNode && isAdd(node)) {
+- final BinaryNode binaryNode = (BinaryNode)node;
+- final Node lhs = binaryNode.lhs();
+- final Node rhs = binaryNode.rhs();
+-
+- return isAddString(lhs) || isAddString(rhs);
+- }
+-
+- return node instanceof LiteralNode<?> && ((LiteralNode<?>)node).isString();
+- }
+-
+- private void checkThisAssignment(final BinaryNode binaryNode) {
+- if (binaryNode.isAssignment()) {
+- if (binaryNode.lhs() instanceof AccessNode) {
+- final AccessNode accessNode = (AccessNode) binaryNode.lhs();
+-
+- if (accessNode.getBase().getSymbol().isThis()) {
+- lc.getCurrentFunction().addThisProperty(accessNode.getProperty().getName());
+- }
+- }
+- }
+- }
+- });
+- lc.replace(currentFunctionNode, newFunctionNode);
+- currentFunctionNode = newFunctionNode;
+- } while (!changed.isEmpty());
+-
+- return currentFunctionNode;
+- }
+-
+- private Node leaveSelfModifyingAssignmentNode(final BinaryNode binaryNode) {
+- return leaveSelfModifyingAssignmentNode(binaryNode, binaryNode.getWidestOperationType());
+- }
+-
+- private Node leaveSelfModifyingAssignmentNode(final BinaryNode binaryNode, final Type destType) {
+- //e.g. for -=, Number, no wider, destType (binaryNode.getWidestOperationType()) is the coerce type
+- final Expression lhs = binaryNode.lhs();
+-
+- newType(lhs.getSymbol(), destType); //may not narrow if dest is already wider than destType
+-
+- return end(ensureSymbol(destType, binaryNode));
+- }
+-
+- private Expression ensureSymbol(final Type type, final Expression expr) {
+- LOG.info("New TEMPORARY added to ", lc.getCurrentFunction().getName(), " type=", type);
+- return temporarySymbols.ensureSymbol(lc, type, expr);
+- }
+-
+- private Symbol newInternal(final String name, final Type type) {
+- final Symbol iter = defineSymbol(lc.getCurrentBlock(), name, IS_VAR | IS_INTERNAL);
+- iter.setType(type); // NASHORN-73
+- return iter;
+- }
+-
+- private static void newType(final Symbol symbol, final Type type) {
+- final Type oldType = symbol.getSymbolType();
+- symbol.setType(type);
+-
+- if (symbol.getSymbolType() != oldType) {
+- LOG.info("New TYPE ", type, " for ", symbol," (was ", oldType, ")");
+- }
+-
+- if (symbol.isParam()) {
+- symbol.setType(type);
+- LOG.info("Param type change ", symbol);
+- }
+- }
+-
+- private void pushLocalsFunction() {
+- localDefs.push(new HashSet<String>());
+- localUses.push(new HashSet<String>());
+- }
+-
+- private void pushLocalsBlock() {
+- localDefs.push(new HashSet<>(localDefs.peek()));
+- localUses.push(new HashSet<>(localUses.peek()));
+- }
+-
+- private void popLocals() {
+- localDefs.pop();
+- localUses.pop();
+- }
+-
+- private boolean isLocalDef(final String name) {
+- return localDefs.peek().contains(name);
+- }
+-
+- private void addLocalDef(final String name) {
+- LOG.info("Adding local def of symbol: '", name, "'");
+- localDefs.peek().add(name);
+- }
+-
+- private void removeLocalDef(final String name) {
+- LOG.info("Removing local def of symbol: '", name, "'");
+- localDefs.peek().remove(name);
+- }
+-
+- private boolean isLocalUse(final String name) {
+- return localUses.peek().contains(name);
+- }
+-
+- private void addLocalUse(final String name) {
+- LOG.info("Adding local use of symbol: '", name, "'");
+- localUses.peek().add(name);
+- }
+-
+- /**
+- * Pessimistically promote all symbols in current function node to Object types
+- * This is done when the function contains unevaluated black boxes such as
+- * lazy sub-function nodes that have not been compiled.
+- *
+- * @param body body for the function node we are leaving
+- */
+- private static void objectifySymbols(final Block body) {
+- body.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
+- private void toObject(final Block block) {
+- for (final Symbol symbol : block.getSymbols()) {
+- if (!symbol.isTemp()) {
+- newType(symbol, Type.OBJECT);
+- }
+- }
+- }
+-
+- @Override
+- public boolean enterBlock(final Block block) {
+- toObject(block);
+- return true;
+- }
+-
+- @Override
+- public boolean enterFunctionNode(final FunctionNode node) {
+- return false;
+- }
+- });
+- }
+-
+- private static String name(final Node node) {
+- final String cn = node.getClass().getName();
+- int lastDot = cn.lastIndexOf('.');
+- if (lastDot == -1) {
+- return cn;
+- }
+- return cn.substring(lastDot + 1);
+- }
+-
+- private boolean start(final Node node) {
+- return start(node, true);
+- }
+-
+- private boolean start(final Node node, final boolean printNode) {
+- if (DEBUG) {
+- final StringBuilder sb = new StringBuilder();
+-
+- sb.append("[ENTER ").
+- append(name(node)).
+- append("] ").
+- append(printNode ? node.toString() : "").
+- append(" in '").
+- append(lc.getCurrentFunction().getName()).
+- append("'");
+- LOG.info(sb);
+- LOG.indent();
+- }
+-
+- return true;
+- }
+-
+- private <T extends Node> T end(final T node) {
+- return end(node, true);
+- }
+-
+- private <T extends Node> T end(final T node, final boolean printNode) {
+- if(node instanceof Statement) {
+- // If we're done with a statement, all temporaries can be reused.
+- temporarySymbols.reuse();
+- }
+- if (DEBUG) {
+- final StringBuilder sb = new StringBuilder();
+-
+- sb.append("[LEAVE ").
+- append(name(node)).
+- append("] ").
+- append(printNode ? node.toString() : "").
+- append(" in '").
+- append(lc.getCurrentFunction().getName()).
+- append('\'');
+-
+- if (node instanceof Expression) {
+- final Symbol symbol = ((Expression)node).getSymbol();
+- if (symbol == null) {
+- sb.append(" <NO SYMBOL>");
+- } else {
+- sb.append(" <symbol=").append(symbol).append('>');
+- }
+- }
+-
+- LOG.unindent();
+- LOG.info(sb);
+- }
+-
+- return node;
+- }
+-}
+--- ./nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java Wed Feb 04 12:14:47 2015 -0800
+@@ -32,10 +32,10 @@
+ import static jdk.nashorn.internal.codegen.Condition.LT;
+ import static jdk.nashorn.internal.codegen.Condition.NE;
+
+-import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.BinaryNode;
+ import jdk.nashorn.internal.ir.Expression;
+-import jdk.nashorn.internal.ir.TernaryNode;
++import jdk.nashorn.internal.ir.JoinPredecessorExpression;
++import jdk.nashorn.internal.ir.LocalVariableConversion;
+ import jdk.nashorn.internal.ir.UnaryNode;
+
+ /**
+@@ -57,7 +57,7 @@
+ }
+
+ private void branchOptimizer(final UnaryNode unaryNode, final Label label, final boolean state) {
+- final Expression rhs = unaryNode.rhs();
++ final Expression rhs = unaryNode.getExpression();
+
+ switch (unaryNode.tokenType()) {
+ case NOT:
+@@ -71,13 +71,7 @@
+ break;
+ }
+
+- // convert to boolean
+- codegen.load(unaryNode, Type.BOOLEAN);
+- if (state) {
+- method.ifne(label);
+- } else {
+- method.ifeq(label);
+- }
++ loadTestAndJump(unaryNode, label, state);
+ }
+
+ private void branchOptimizer(final BinaryNode binaryNode, final Label label, final boolean state) {
+@@ -88,86 +82,97 @@
+ case AND:
+ if (state) {
+ final Label skip = new Label("skip");
+- branchOptimizer(lhs, skip, false);
+- branchOptimizer(rhs, label, true);
++ optimizeLogicalOperand(lhs, skip, false, false);
++ optimizeLogicalOperand(rhs, label, true, true);
+ method.label(skip);
+ } else {
+- branchOptimizer(lhs, label, false);
+- branchOptimizer(rhs, label, false);
++ optimizeLogicalOperand(lhs, label, false, false);
++ optimizeLogicalOperand(rhs, label, false, true);
+ }
+ return;
+
+ case OR:
+ if (state) {
+- branchOptimizer(lhs, label, true);
+- branchOptimizer(rhs, label, true);
++ optimizeLogicalOperand(lhs, label, true, false);
++ optimizeLogicalOperand(rhs, label, true, true);
+ } else {
+ final Label skip = new Label("skip");
+- branchOptimizer(lhs, skip, true);
+- branchOptimizer(rhs, label, false);
++ optimizeLogicalOperand(lhs, skip, true, false);
++ optimizeLogicalOperand(rhs, label, false, true);
+ method.label(skip);
+ }
+ return;
+
+ case EQ:
+ case EQ_STRICT:
+- codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType()));
++ codegen.loadBinaryOperands(binaryNode);
+ method.conditionalJump(state ? EQ : NE, true, label);
+ return;
+
+ case NE:
+ case NE_STRICT:
+- codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType()));
++ codegen.loadBinaryOperands(binaryNode);
+ method.conditionalJump(state ? NE : EQ, true, label);
+ return;
+
+ case GE:
+- codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType()));
+- method.conditionalJump(state ? GE : LT, !state, label);
++ codegen.loadBinaryOperands(binaryNode);
++ method.conditionalJump(state ? GE : LT, false, label);
+ return;
+
+ case GT:
+- codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType()));
+- method.conditionalJump(state ? GT : LE, !state, label);
++ codegen.loadBinaryOperands(binaryNode);
++ method.conditionalJump(state ? GT : LE, false, label);
+ return;
+
+ case LE:
+- codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType()));
+- method.conditionalJump(state ? LE : GT, state, label);
++ codegen.loadBinaryOperands(binaryNode);
++ method.conditionalJump(state ? LE : GT, true, label);
+ return;
+
+ case LT:
+- codegen.loadBinaryOperands(lhs, rhs, Type.widest(lhs.getType(), rhs.getType()));
+- method.conditionalJump(state ? LT : GE, state, label);
++ codegen.loadBinaryOperands(binaryNode);
++ method.conditionalJump(state ? LT : GE, true, label);
+ return;
+
+ default:
+ break;
+ }
+
+- codegen.load(binaryNode, Type.BOOLEAN);
+- if (state) {
+- method.ifne(label);
++ loadTestAndJump(binaryNode, label, state);
++ }
++
++ private void optimizeLogicalOperand(final Expression expr, final Label label, final boolean state, final boolean isRhs) {
++ final JoinPredecessorExpression jpexpr = (JoinPredecessorExpression)expr;
++ if(LocalVariableConversion.hasLiveConversion(jpexpr)) {
++ final Label after = new Label("after");
++ branchOptimizer(jpexpr.getExpression(), after, !state);
++ method.beforeJoinPoint(jpexpr);
++ method._goto(label);
++ method.label(after);
++ if(isRhs) {
++ method.beforeJoinPoint(jpexpr);
++ }
+ } else {
+- method.ifeq(label);
++ branchOptimizer(jpexpr.getExpression(), label, state);
+ }
+ }
+-
+ private void branchOptimizer(final Expression node, final Label label, final boolean state) {
+- if (!(node instanceof TernaryNode)) {
+-
+- if (node instanceof BinaryNode) {
+- branchOptimizer((BinaryNode)node, label, state);
+- return;
+- }
+-
+- if (node instanceof UnaryNode) {
+- branchOptimizer((UnaryNode)node, label, state);
+- return;
+- }
++ if (node instanceof BinaryNode) {
++ branchOptimizer((BinaryNode)node, label, state);
++ return;
+ }
+
+- codegen.load(node, Type.BOOLEAN);
++ if (node instanceof UnaryNode) {
++ branchOptimizer((UnaryNode)node, label, state);
++ return;
++ }
++
++ loadTestAndJump(node, label, state);
++ }
++
++ private void loadTestAndJump(final Expression node, final Label label, final boolean state) {
++ codegen.loadExpressionAsBoolean(node);
+ if (state) {
+ method.ifne(label);
+ } else {
+--- ./nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -49,25 +49,27 @@
+ import static jdk.nashorn.internal.codegen.CompilerConstants.STRICT_MODE;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.className;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
++import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
+
+ import java.io.ByteArrayOutputStream;
+ import java.io.PrintWriter;
+-import java.util.Arrays;
++import java.security.AccessController;
++import java.security.PrivilegedAction;
++import java.util.Collections;
+ import java.util.EnumSet;
+ import java.util.HashSet;
+ import java.util.Set;
+-
+-import jdk.internal.org.objectweb.asm.ClassReader;
+ import jdk.internal.org.objectweb.asm.ClassWriter;
+ import jdk.internal.org.objectweb.asm.MethodVisitor;
+ import jdk.internal.org.objectweb.asm.util.TraceClassVisitor;
+ import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.FunctionNode;
+-import jdk.nashorn.internal.ir.SplitNode;
++import jdk.nashorn.internal.ir.debug.NashornClassReader;
++import jdk.nashorn.internal.ir.debug.NashornTextifier;
++import jdk.nashorn.internal.runtime.Context;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+-import jdk.nashorn.internal.runtime.ScriptEnvironment;
++import jdk.nashorn.internal.runtime.RewriteException;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.Source;
+
+@@ -106,6 +108,8 @@
+ * @see Compiler
+ */
+ public class ClassEmitter implements Emitter {
++ /** Default flags for class generation - public class */
++ private static final EnumSet<Flag> DEFAULT_METHOD_FLAGS = EnumSet.of(Flag.PUBLIC);
+
+ /** Sanity check flag - have we started on a class? */
+ private boolean classStarted;
+@@ -123,10 +127,7 @@
+ protected final ClassWriter cw;
+
+ /** The script environment */
+- protected final ScriptEnvironment env;
+-
+- /** Default flags for class generation - oublic class */
+- private static final EnumSet<Flag> DEFAULT_METHOD_FLAGS = EnumSet.of(Flag.PUBLIC);
++ protected final Context context;
+
+ /** Compile unit class name. */
+ private String unitClassName;
+@@ -134,6 +135,16 @@
+ /** Set of constants access methods required. */
+ private Set<Class<?>> constantMethodNeeded;
+
++ private int methodCount;
++
++ private int initCount;
++
++ private int clinitCount;
++
++ private int fieldCount;
++
++ private final Set<String> methodNames;
++
+ /**
+ * Constructor - only used internally in this class as it breaks
+ * abstraction towards ASM or other code generator below
+@@ -141,12 +152,19 @@
+ * @param env script environment
+ * @param cw ASM classwriter
+ */
+- private ClassEmitter(final ScriptEnvironment env, final ClassWriter cw) {
+- assert env != null;
+-
+- this.env = env;
++ private ClassEmitter(final Context context, final ClassWriter cw) {
++ this.context = context;
+ this.cw = cw;
+ this.methodsStarted = new HashSet<>();
++ this.methodNames = new HashSet<>();
++ }
++
++ /**
++ * Return the method names encountered
++ * @return method names
++ */
++ public Set<String> getMethodNames() {
++ return Collections.unmodifiableSet(methodNames);
+ }
+
+ /**
+@@ -157,8 +175,8 @@
+ * @param superClassName super class name for class
+ * @param interfaceNames names of interfaces implemented by this class, or null if none
+ */
+- ClassEmitter(final ScriptEnvironment env, final String className, final String superClassName, final String... interfaceNames) {
+- this(env, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS));
++ ClassEmitter(final Context context, final String className, final String superClassName, final String... interfaceNames) {
++ this(context, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS));
+ cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, className, null, superClassName, interfaceNames);
+ }
+
+@@ -170,8 +188,8 @@
+ * @param unitClassName Compile unit class name.
+ * @param strictMode Should we generate this method in strict mode
+ */
+- ClassEmitter(final ScriptEnvironment env, final String sourceName, final String unitClassName, final boolean strictMode) {
+- this(env,
++ ClassEmitter(final Context context, final String sourceName, final String unitClassName, final boolean strictMode) {
++ this(context,
+ new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
+ private static final String OBJECT_CLASS = "java/lang/Object";
+
+@@ -197,6 +215,10 @@
+ defineCommonStatics(strictMode);
+ }
+
++ Context getContext() {
++ return context;
++ }
++
+ /**
+ * Returns the name of the compile unit class name.
+ * @return the name of the compile unit class name.
+@@ -206,6 +228,38 @@
+ }
+
+ /**
++ * Get the method count, including init and clinit methods
++ * @return method count
++ */
++ public int getMethodCount() {
++ return methodCount;
++ }
++
++ /**
++ * Get the clinit count
++ * @return clinit count
++ */
++ public int getClinitCount() {
++ return clinitCount;
++ }
++
++ /**
++ * Get the init count
++ * @return init count
++ */
++ public int getInitCount() {
++ return initCount;
++ }
++
++ /**
++ * Get the field count
++ * @return field count
++ */
++ public int getFieldCount() {
++ return fieldCount;
++ }
++
++ /**
+ * Convert a binary name to a package/class name.
+ *
+ * @param name Binary name.
+@@ -274,51 +328,51 @@
+ }
+
+ // $getXXXX$array - get the ith entry from the constants table and cast to XXXX[].
+- for (final Class<?> cls : constantMethodNeeded) {
+- if (cls.isArray()) {
+- defineGetArrayMethod(cls);
++ for (final Class<?> clazz : constantMethodNeeded) {
++ if (clazz.isArray()) {
++ defineGetArrayMethod(clazz);
+ }
+ }
+ }
+
+ /**
+- * Constructs a primitive specific method for getting the ith entry from the constants table and cast.
+- * @param cls Array class.
++ * Constructs a primitive specific method for getting the ith entry from the constants table as an array.
++ * @param clazz Array class.
+ */
+- private void defineGetArrayMethod(final Class<?> cls) {
++ private void defineGetArrayMethod(final Class<?> clazz) {
+ assert unitClassName != null;
+
+- final String methodName = getArrayMethodName(cls);
+- final MethodEmitter getArrayMethod = method(EnumSet.of(Flag.PRIVATE, Flag.STATIC), methodName, cls, int.class);
++ final String methodName = getArrayMethodName(clazz);
++ final MethodEmitter getArrayMethod = method(EnumSet.of(Flag.PRIVATE, Flag.STATIC), methodName, clazz, int.class);
+
+ getArrayMethod.begin();
+ getArrayMethod.getStatic(unitClassName, CONSTANTS.symbolName(), CONSTANTS.descriptor())
+ .load(Type.INT, 0)
+ .arrayload()
+- .checkcast(cls)
+- .dup()
+- .arraylength()
+- .invoke(staticCallNoLookup(Arrays.class, "copyOf", cls, cls, int.class))
++ .checkcast(clazz)
++ .invoke(virtualCallNoLookup(clazz, "clone", Object.class))
++ .checkcast(clazz)
+ ._return();
+ getArrayMethod.end();
+ }
+
++
+ /**
+ * Generate the name of a get array from constant pool method.
+- * @param cls Name of array class.
++ * @param clazz Name of array class.
+ * @return Method name.
+ */
+- static String getArrayMethodName(final Class<?> cls) {
+- assert cls.isArray();
+- return GET_ARRAY_PREFIX.symbolName() + cls.getComponentType().getSimpleName() + GET_ARRAY_SUFFIX.symbolName();
++ static String getArrayMethodName(final Class<?> clazz) {
++ assert clazz.isArray();
++ return GET_ARRAY_PREFIX.symbolName() + clazz.getComponentType().getSimpleName() + GET_ARRAY_SUFFIX.symbolName();
+ }
+
+ /**
+ * Ensure a get constant method is issued for the class.
+- * @param cls Class of constant.
++ * @param clazz Class of constant.
+ */
+- void needGetConstantMethod(final Class<?> cls) {
+- constantMethodNeeded.add(cls);
++ void needGetConstantMethod(final Class<?> clazz) {
++ constantMethodNeeded.add(clazz);
+ }
+
+ /**
+@@ -356,9 +410,16 @@
+ */
+ @Override
+ public void end() {
+- assert classStarted;
++ assert classStarted : "class not started for " + unitClassName;
+
+ if (unitClassName != null) {
++ final MethodEmitter initMethod = init(EnumSet.of(Flag.PRIVATE));
++ initMethod.begin();
++ initMethod.load(Type.OBJECT, 0);
++ initMethod.newInstance(jdk.nashorn.internal.scripts.JS.class);
++ initMethod.returnVoid();
++ initMethod.end();
++
+ defineCommonUtilities();
+ }
+
+@@ -376,16 +437,19 @@
+ static String disassemble(final byte[] bytecode) {
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try (final PrintWriter pw = new PrintWriter(baos)) {
+- new ClassReader(bytecode).accept(new TraceClassVisitor(pw), 0);
++ final NashornClassReader cr = new NashornClassReader(bytecode);
++ final Context ctx = AccessController.doPrivileged(new PrivilegedAction<Context>() {
++ @Override
++ public Context run() {
++ return Context.getContext();
++ }
++ });
++ final TraceClassVisitor tcv = new TraceClassVisitor(null, new NashornTextifier(ctx.getEnv(), cr), pw);
++ cr.accept(tcv, 0);
+ }
+- return new String(baos.toByteArray());
+- }
+
+- /**
+- * @return env used for class emission
+- */
+- ScriptEnvironment getEnv() {
+- return env;
++ final String str = new String(baos.toByteArray());
++ return str;
+ }
+
+ /**
+@@ -412,10 +476,6 @@
+ methodsStarted.remove(method);
+ }
+
+- SplitMethodEmitter method(final SplitNode splitNode, final String methodName, final Class<?> rtype, final Class<?>... ptypes) {
+- return new SplitMethodEmitter(this, methodVisitor(EnumSet.of(Flag.PUBLIC, Flag.STATIC), methodName, rtype, ptypes), splitNode);
+- }
+-
+ /**
+ * Add a new method to the class - defaults to public method
+ *
+@@ -440,6 +500,8 @@
+ * @return method emitter to use for weaving this method
+ */
+ MethodEmitter method(final EnumSet<Flag> methodFlags, final String methodName, final Class<?> rtype, final Class<?>... ptypes) {
++ methodCount++;
++ methodNames.add(methodName);
+ return new MethodEmitter(this, methodVisitor(methodFlags, methodName, rtype, ptypes));
+ }
+
+@@ -465,6 +527,8 @@
+ * @return method emitter to use for weaving this method
+ */
+ MethodEmitter method(final EnumSet<Flag> methodFlags, final String methodName, final String descriptor) {
++ methodCount++;
++ methodNames.add(methodName);
+ return new MethodEmitter(this, cw.visitMethod(Flag.getValue(methodFlags), methodName, descriptor, null, null));
+ }
+
+@@ -475,10 +539,13 @@
+ * @return method emitter to use for weaving this method
+ */
+ MethodEmitter method(final FunctionNode functionNode) {
++ methodCount++;
++ methodNames.add(functionNode.getName());
++ final FunctionSignature signature = new FunctionSignature(functionNode);
+ final MethodVisitor mv = cw.visitMethod(
+ ACC_PUBLIC | ACC_STATIC | (functionNode.isVarArg() ? ACC_VARARGS : 0),
+ functionNode.getName(),
+- new FunctionSignature(functionNode).toString(),
++ signature.toString(),
+ null,
+ null);
+
+@@ -486,11 +553,32 @@
+ }
+
+ /**
++ * Add a new method to the class, representing a rest-of version of the function node
++ *
++ * @param functionNode the function node to generate a method for
++ * @return method emitter to use for weaving this method
++ */
++ MethodEmitter restOfMethod(final FunctionNode functionNode) {
++ methodCount++;
++ methodNames.add(functionNode.getName());
++ final MethodVisitor mv = cw.visitMethod(
++ ACC_PUBLIC | ACC_STATIC,
++ functionNode.getName(),
++ Type.getMethodDescriptor(functionNode.getReturnType().getTypeClass(), RewriteException.class),
++ null,
++ null);
++
++ return new MethodEmitter(this, mv, functionNode);
++ }
++
++
++ /**
+ * Start generating the <clinit> method in the class
+ *
+ * @return method emitter to use for weaving <clinit>
+ */
+ MethodEmitter clinit() {
++ clinitCount++;
+ return method(EnumSet.of(Flag.STATIC), CLINIT.symbolName(), void.class);
+ }
+
+@@ -500,6 +588,7 @@
+ * @return method emitter to use for weaving <init>()V
+ */
+ MethodEmitter init() {
++ initCount++;
+ return method(INIT.symbolName(), void.class);
+ }
+
+@@ -510,6 +599,7 @@
+ * @return method emitter to use for weaving <init>()V
+ */
+ MethodEmitter init(final Class<?>... ptypes) {
++ initCount++;
+ return method(INIT.symbolName(), void.class, ptypes);
+ }
+
+@@ -522,6 +612,7 @@
+ * @return method emitter to use for weaving <init>(...)V
+ */
+ MethodEmitter init(final EnumSet<Flag> flags, final Class<?>... ptypes) {
++ initCount++;
+ return method(flags, INIT.symbolName(), void.class, ptypes);
+ }
+
+@@ -536,6 +627,7 @@
+ * @see ClassEmitter.Flag
+ */
+ final void field(final EnumSet<Flag> fieldFlags, final String fieldName, final Class<?> fieldType, final Object value) {
++ fieldCount++;
+ cw.visitField(Flag.getValue(fieldFlags), fieldName, typeDescriptor(fieldType), null, value).visitEnd();
+ }
+
+@@ -636,7 +728,7 @@
+ }
+ }
+
+- private MethodVisitor methodVisitor(EnumSet<Flag> flags, final String methodName, final Class<?> rtype, final Class<?>... ptypes) {
++ private MethodVisitor methodVisitor(final EnumSet<Flag> flags, final String methodName, final Class<?> rtype, final Class<?>... ptypes) {
+ return cw.visitMethod(Flag.getValue(flags), methodName, methodDescriptor(rtype, ptypes), null, null);
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,13 +29,12 @@
+ import static jdk.nashorn.internal.codegen.ClassEmitter.Flag.STATIC;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE;
++import static jdk.nashorn.internal.codegen.CompilerConstants.CREATE_PROGRAM_FUNCTION;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.GET_MAP;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.GET_STRING;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.QUICK_PREFIX;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.REGEX_PREFIX;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.RETURN;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_ARRAY_ARG;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_PREFIX;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
+@@ -45,25 +44,40 @@
+ import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
++import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
++import static jdk.nashorn.internal.ir.Symbol.HAS_SLOT;
+ import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL;
+-import static jdk.nashorn.internal.ir.Symbol.IS_TEMP;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_APPLY_TO_CALL;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_DECLARE;
+ import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_FAST_SCOPE;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_OPTIMISTIC;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_PROGRAM_POINT_SHIFT;
+ import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_SCOPE;
+-import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT;
+
+ import java.io.PrintWriter;
++import java.util.ArrayDeque;
+ import java.util.ArrayList;
+ import java.util.Arrays;
++import java.util.BitSet;
++import java.util.Collection;
++import java.util.Collections;
++import java.util.Deque;
+ import java.util.EnumSet;
++import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.Iterator;
+ import java.util.LinkedList;
+ import java.util.List;
++import java.util.Map;
+ import java.util.Set;
+ import java.util.TreeMap;
++import java.util.function.Supplier;
++import jdk.nashorn.internal.AssertsEnabled;
++import jdk.nashorn.internal.IntDeque;
+ import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
+ import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+-import jdk.nashorn.internal.codegen.RuntimeCallSite.SpecializedRuntimeNode;
+ import jdk.nashorn.internal.codegen.types.ArrayType;
+ import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.AccessNode;
+@@ -83,22 +97,30 @@
+ import jdk.nashorn.internal.ir.ForNode;
+ import jdk.nashorn.internal.ir.FunctionNode;
+ import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
++import jdk.nashorn.internal.ir.GetSplitState;
+ import jdk.nashorn.internal.ir.IdentNode;
+ import jdk.nashorn.internal.ir.IfNode;
+ import jdk.nashorn.internal.ir.IndexNode;
++import jdk.nashorn.internal.ir.JoinPredecessorExpression;
++import jdk.nashorn.internal.ir.JumpStatement;
++import jdk.nashorn.internal.ir.LabelNode;
+ import jdk.nashorn.internal.ir.LexicalContext;
+ import jdk.nashorn.internal.ir.LexicalContextNode;
+ import jdk.nashorn.internal.ir.LiteralNode;
+ import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
+ import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
++import jdk.nashorn.internal.ir.LiteralNode.PrimitiveLiteralNode;
++import jdk.nashorn.internal.ir.LocalVariableConversion;
+ import jdk.nashorn.internal.ir.LoopNode;
+ import jdk.nashorn.internal.ir.Node;
+ import jdk.nashorn.internal.ir.ObjectNode;
++import jdk.nashorn.internal.ir.Optimistic;
+ import jdk.nashorn.internal.ir.PropertyNode;
+ import jdk.nashorn.internal.ir.ReturnNode;
+ import jdk.nashorn.internal.ir.RuntimeNode;
+ import jdk.nashorn.internal.ir.RuntimeNode.Request;
+-import jdk.nashorn.internal.ir.SplitNode;
++import jdk.nashorn.internal.ir.SetSplitState;
++import jdk.nashorn.internal.ir.SplitReturn;
+ import jdk.nashorn.internal.ir.Statement;
+ import jdk.nashorn.internal.ir.SwitchNode;
+ import jdk.nashorn.internal.ir.Symbol;
+@@ -117,20 +139,26 @@
+ import jdk.nashorn.internal.parser.TokenType;
+ import jdk.nashorn.internal.runtime.Context;
+ import jdk.nashorn.internal.runtime.Debug;
+-import jdk.nashorn.internal.runtime.DebugLogger;
+ import jdk.nashorn.internal.runtime.ECMAException;
+ import jdk.nashorn.internal.runtime.JSType;
+-import jdk.nashorn.internal.runtime.Property;
++import jdk.nashorn.internal.runtime.OptimisticReturnFilters;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
++import jdk.nashorn.internal.runtime.RewriteException;
+ import jdk.nashorn.internal.runtime.Scope;
++import jdk.nashorn.internal.runtime.ScriptEnvironment;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+ import jdk.nashorn.internal.runtime.Source;
+ import jdk.nashorn.internal.runtime.Undefined;
++import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
+ import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
++import jdk.nashorn.internal.runtime.options.Options;
+
+ /**
+ * This is the lowest tier of the code generator. It takes lowered ASTs emitted
+@@ -151,16 +179,44 @@
+ * The CodeGenerator visits nodes only once, tags them as resolved and emits
+ * bytecode for them.
+ */
+-final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContext> {
++@Logger(name="codegen")
++final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContext> implements Loggable {
++
++ private static final Type SCOPE_TYPE = Type.typeFor(ScriptObject.class);
+
+ private static final String GLOBAL_OBJECT = Type.getInternalName(Global.class);
+
+- private static final String SCRIPTFUNCTION_IMPL_OBJECT = Type.getInternalName(ScriptFunctionImpl.class);
++ private static final String SCRIPTFUNCTION_IMPL_NAME = Type.getInternalName(ScriptFunctionImpl.class);
++ private static final Type SCRIPTFUNCTION_IMPL_TYPE = Type.typeFor(ScriptFunction.class);
++
++ private static final Call CREATE_REWRITE_EXCEPTION = CompilerConstants.staticCallNoLookup(RewriteException.class,
++ "create", RewriteException.class, UnwarrantedOptimismException.class, Object[].class, String[].class);
++ private static final Call CREATE_REWRITE_EXCEPTION_REST_OF = CompilerConstants.staticCallNoLookup(RewriteException.class,
++ "create", RewriteException.class, UnwarrantedOptimismException.class, Object[].class, String[].class, int[].class);
++
++ private static final Call ENSURE_INT = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
++ "ensureInt", int.class, Object.class, int.class);
++ private static final Call ENSURE_LONG = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
++ "ensureLong", long.class, Object.class, int.class);
++ private static final Call ENSURE_NUMBER = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
++ "ensureNumber", double.class, Object.class, int.class);
++
++ private static final Class<?> ITERATOR_CLASS = Iterator.class;
++ static {
++ assert ITERATOR_CLASS == CompilerConstants.ITERATOR_PREFIX.type();
++ }
++ private static final Type ITERATOR_TYPE = Type.typeFor(ITERATOR_CLASS);
++ private static final Type EXCEPTION_TYPE = Type.typeFor(CompilerConstants.EXCEPTION_PREFIX.type());
++
++ private static final Integer INT_ZERO = Integer.valueOf(0);
+
+ /** Constant data & installation. The only reason the compiler keeps this is because it is assigned
+ * by reflection in class installation */
+ private final Compiler compiler;
+
++ /** Is the current code submitted by 'eval' call? */
++ private final boolean evalCode;
++
+ /** Call site flags given to the code generator to be used for all generated call sites */
+ private final int callSiteFlags;
+
+@@ -180,22 +236,48 @@
+ /** Current compile unit */
+ private CompileUnit unit;
+
+- private static final DebugLogger LOG = new DebugLogger("codegen", "nashorn.codegen.debug");
++ private final DebugLogger log;
+
+ /** From what size should we use spill instead of fields for JavaScript objects? */
+- private static final int OBJECT_SPILL_THRESHOLD = 300;
++ private static final int OBJECT_SPILL_THRESHOLD = Options.getIntProperty("nashorn.spill.threshold", 256);
+
+ private final Set<String> emittedMethods = new HashSet<>();
+
++ // Function Id -> ContinuationInfo. Used by compilation of rest-of function only.
++ private final Map<Integer, ContinuationInfo> fnIdToContinuationInfo = new HashMap<>();
++
++ private final Deque<Label> scopeEntryLabels = new ArrayDeque<>();
++
++ private static final Label METHOD_BOUNDARY = new Label("");
++ private final Deque<Label> catchLabels = new ArrayDeque<>();
++ // Number of live locals on entry to (and thus also break from) labeled blocks.
++ private final IntDeque labeledBlockBreakLiveLocals = new IntDeque();
++
++ //is this a rest of compilation
++ private final int[] continuationEntryPoints;
++
+ /**
+ * Constructor.
+ *
+ * @param compiler
+ */
+- CodeGenerator(final Compiler compiler) {
++ CodeGenerator(final Compiler compiler, final int[] continuationEntryPoints) {
+ super(new CodeGeneratorLexicalContext());
+- this.compiler = compiler;
+- this.callSiteFlags = compiler.getEnv()._callsite_flags;
++ this.compiler = compiler;
++ this.evalCode = compiler.getSource().isEvalCode();
++ this.continuationEntryPoints = continuationEntryPoints;
++ this.callSiteFlags = compiler.getScriptEnvironment()._callsite_flags;
++ this.log = initLogger(compiler.getContext());
++ }
++
++ @Override
++ public DebugLogger getLogger() {
++ return log;
++ }
++
++ @Override
++ public DebugLogger initLogger(final Context context) {
++ return context.getLogger(this.getClass());
+ }
+
+ /**
+@@ -205,7 +287,15 @@
+ * @return the correct flags for a call site in the current function
+ */
+ int getCallSiteFlags() {
+- return lc.getCurrentFunction().isStrict() ? callSiteFlags | CALLSITE_STRICT : callSiteFlags;
++ return lc.getCurrentFunction().getCallSiteFlags() | callSiteFlags;
++ }
++
++ /**
++ * Are we generating code for 'eval' code?
++ * @return true if currently compiled code is 'eval' code.
++ */
++ boolean isEvalCode() {
++ return evalCode;
+ }
+
+ /**
+@@ -214,38 +304,79 @@
+ * @param identNode an identity node to load
+ * @return the method generator used
+ */
+- private MethodEmitter loadIdent(final IdentNode identNode, final Type type) {
++ private MethodEmitter loadIdent(final IdentNode identNode, final TypeBounds resultBounds) {
++ checkTemporalDeadZone(identNode);
+ final Symbol symbol = identNode.getSymbol();
+
+ if (!symbol.isScope()) {
++ final Type type = identNode.getType();
++ if(type == Type.UNDEFINED) {
++ return method.loadUndefined(resultBounds.widest);
++ }
++
+ assert symbol.hasSlot() || symbol.isParam();
+- return method.load(symbol).convert(type);
+- }
+-
+- final String name = symbol.getName();
+- final Source source = lc.getCurrentFunction().getSource();
+-
+- if (CompilerConstants.__FILE__.name().equals(name)) {
+- return method.load(source.getName());
+- } else if (CompilerConstants.__DIR__.name().equals(name)) {
+- return method.load(source.getBase());
+- } else if (CompilerConstants.__LINE__.name().equals(name)) {
+- return method.load(source.getLine(identNode.position())).convert(Type.OBJECT);
++ return method.load(identNode);
++ }
++
++ assert identNode.getSymbol().isScope() : identNode + " is not in scope!";
++ final int flags = CALLSITE_SCOPE | getCallSiteFlags();
++ if (isFastScope(symbol)) {
++ // Only generate shared scope getter for fast-scope symbols so we know we can dial in correct scope.
++ if (symbol.getUseCount() > SharedScopeCall.FAST_SCOPE_GET_THRESHOLD && !isOptimisticOrRestOf()) {
++ method.loadCompilerConstant(SCOPE);
++ // As shared scope vars are only used in non-optimistic compilation, we switch from using TypeBounds to
++ // just a single definitive type, resultBounds.widest.
++ loadSharedScopeVar(resultBounds.widest, symbol, flags);
++ } else {
++ new LoadFastScopeVar(identNode, resultBounds, flags).emit();
++ }
+ } else {
+- assert identNode.getSymbol().isScope() : identNode + " is not in scope!";
+-
+- final int flags = CALLSITE_SCOPE | getCallSiteFlags();
+- method.loadCompilerConstant(SCOPE);
+-
+- if (isFastScope(symbol)) {
+- // Only generate shared scope getter for fast-scope symbols so we know we can dial in correct scope.
+- if (symbol.getUseCount() > SharedScopeCall.FAST_SCOPE_GET_THRESHOLD) {
+- return loadSharedScopeVar(type, symbol, flags);
++ //slow scope load, we have no proto depth
++ new LoadScopeVar(identNode, resultBounds, flags).emit();
++ }
++
++ return method;
++ }
++
++ // Any access to LET and CONST variables before their declaration must throw ReferenceError.
++ // This is called the temporal dead zone (TDZ). See https://gist.github.com/rwaldron/f0807a758aa03bcdd58a
++ private void checkTemporalDeadZone(final IdentNode identNode) {
++ if (identNode.isDead()) {
++ method.load(identNode.getSymbol().getName());
++ method.invoke(ScriptRuntime.THROW_REFERENCE_ERROR);
++ }
++ }
++
++ private boolean isRestOf() {
++ return continuationEntryPoints != null;
++ }
++
++ private boolean isOptimisticOrRestOf() {
++ return useOptimisticTypes() || isRestOf();
++ }
++
++ private boolean isCurrentContinuationEntryPoint(final int programPoint) {
++ return isRestOf() && getCurrentContinuationEntryPoint() == programPoint;
++ }
++
++ private int[] getContinuationEntryPoints() {
++ return isRestOf() ? continuationEntryPoints : null;
++ }
++
++ private int getCurrentContinuationEntryPoint() {
++ return isRestOf() ? continuationEntryPoints[0] : INVALID_PROGRAM_POINT;
++ }
++
++ private boolean isContinuationEntryPoint(final int programPoint) {
++ if (isRestOf()) {
++ assert continuationEntryPoints != null;
++ for (final int cep : continuationEntryPoints) {
++ if (cep == programPoint) {
++ return true;
+ }
+- return loadFastScopeVar(type, symbol, flags, identNode.isFunction());
+- }
+- return method.dynamicGet(type, identNode.getName(), flags, identNode.isFunction());
+- }
++ }
++ }
++ return false;
+ }
+
+ /**
+@@ -285,7 +416,7 @@
+ }
+ previousWasBlock = true;
+ } else {
+- if ((node instanceof WithNode && previousWasBlock) || (node instanceof FunctionNode && CodeGeneratorLexicalContext.isFunctionDynamicScope((FunctionNode)node))) {
++ if (node instanceof WithNode && previousWasBlock || node instanceof FunctionNode && ((FunctionNode)node).needsDynamicScope()) {
+ // If we hit a scope that can have symbols introduced into it at run time before finding the defining
+ // block, the symbol can't be fast scoped. A WithNode only counts if we've immediately seen a block
+ // before - its block. Otherwise, we are currently processing the WithNode's expression, and that's
+@@ -300,40 +431,89 @@
+ }
+
+ private MethodEmitter loadSharedScopeVar(final Type valueType, final Symbol symbol, final int flags) {
+- method.load(isFastScope(symbol) ? getScopeProtoDepth(lc.getCurrentBlock(), symbol) : -1);
+- final SharedScopeCall scopeCall = lc.getScopeGet(unit, valueType, symbol, flags | CALLSITE_FAST_SCOPE);
+- return scopeCall.generateInvoke(method);
++ assert !isOptimisticOrRestOf();
++ if (isFastScope(symbol)) {
++ method.load(getScopeProtoDepth(lc.getCurrentBlock(), symbol));
++ } else {
++ method.load(-1);
++ }
++ return lc.getScopeGet(unit, symbol, valueType, flags | CALLSITE_FAST_SCOPE).generateInvoke(method);
+ }
+
+- private MethodEmitter loadFastScopeVar(final Type valueType, final Symbol symbol, final int flags, final boolean isMethod) {
+- loadFastScopeProto(symbol, false);
+- return method.dynamicGet(valueType, symbol.getName(), flags | CALLSITE_FAST_SCOPE, isMethod);
++ private class LoadScopeVar extends OptimisticOperation {
++ final IdentNode identNode;
++ private final int flags;
++
++ LoadScopeVar(final IdentNode identNode, final TypeBounds resultBounds, final int flags) {
++ super(identNode, resultBounds);
++ this.identNode = identNode;
++ this.flags = flags;
++ }
++
++ @Override
++ void loadStack() {
++ method.loadCompilerConstant(SCOPE);
++ getProto();
++ }
++
++ void getProto() {
++ //empty
++ }
++
++ @Override
++ void consumeStack() {
++ // If this is either __FILE__, __DIR__, or __LINE__ then load the property initially as Object as we'd convert
++ // it anyway for replaceLocationPropertyPlaceholder.
++ if(identNode.isCompileTimePropertyName()) {
++ method.dynamicGet(Type.OBJECT, identNode.getSymbol().getName(), flags, identNode.isFunction(), false);
++ replaceCompileTimeProperty();
++ } else {
++ dynamicGet(identNode.getSymbol().getName(), flags, identNode.isFunction(), false);
++ }
++ }
++ }
++
++ private class LoadFastScopeVar extends LoadScopeVar {
++ LoadFastScopeVar(final IdentNode identNode, final TypeBounds resultBounds, final int flags) {
++ super(identNode, resultBounds, flags | CALLSITE_FAST_SCOPE);
++ }
++
++ @Override
++ void getProto() {
++ loadFastScopeProto(identNode.getSymbol(), false);
++ }
+ }
+
+ private MethodEmitter storeFastScopeVar(final Symbol symbol, final int flags) {
+ loadFastScopeProto(symbol, true);
+- method.dynamicSet(symbol.getName(), flags | CALLSITE_FAST_SCOPE);
++ method.dynamicSet(symbol.getName(), flags | CALLSITE_FAST_SCOPE, false);
+ return method;
+ }
+
+ private int getScopeProtoDepth(final Block startingBlock, final Symbol symbol) {
++ //walk up the chain from starting block and when we bump into the current function boundary, add the external
++ //information.
++ final FunctionNode fn = lc.getCurrentFunction();
++ final int externalDepth = compiler.getScriptFunctionData(fn.getId()).getExternalSymbolDepth(symbol.getName());
++
++ //count the number of scopes from this place to the start of the function
++
++ final int internalDepth = FindScopeDepths.findInternalDepth(lc, fn, startingBlock, symbol);
++ final int scopesToStart = FindScopeDepths.findScopesToStart(lc, fn, startingBlock);
+ int depth = 0;
+- final String name = symbol.getName();
+- for(final Iterator<Block> blocks = lc.getBlocks(startingBlock); blocks.hasNext();) {
+- final Block currentBlock = blocks.next();
+- if (currentBlock.getExistingSymbol(name) == symbol) {
+- return depth;
+- }
+- if (currentBlock.needsScope()) {
+- ++depth;
+- }
+- }
+- return -1;
++ if (internalDepth == -1) {
++ depth = scopesToStart + externalDepth;
++ } else {
++ assert internalDepth <= scopesToStart;
++ depth = internalDepth;
++ }
++
++ return depth;
+ }
+
+ private void loadFastScopeProto(final Symbol symbol, final boolean swap) {
+ final int depth = getScopeProtoDepth(lc.getCurrentBlock(), symbol);
+- assert depth != -1;
++ assert depth != -1 : "Couldn't find scope depth for symbol " + symbol.getName() + " in " + lc.getCurrentFunction();
+ if (depth > 0) {
+ if (swap) {
+ method.swap();
+@@ -348,29 +528,36 @@
+ }
+
+ /**
+- * Generate code that loads this node to the stack. This method is only
+- * public to be accessible from the maps sub package. Do not call externally
++ * Generate code that loads this node to the stack, not constraining its type
+ *
+- * @param node node to load
++ * @param expr node to load
+ *
+ * @return the method emitter used
+ */
+- MethodEmitter load(final Expression node) {
+- return load(node, node.hasType() ? node.getType() : null, false);
++ private MethodEmitter loadExpressionUnbounded(final Expression expr) {
++ return loadExpression(expr, TypeBounds.UNBOUNDED);
++ }
++
++ private MethodEmitter loadExpressionAsObject(final Expression expr) {
++ return loadExpression(expr, TypeBounds.OBJECT);
++ }
++
++ MethodEmitter loadExpressionAsBoolean(final Expression expr) {
++ return loadExpression(expr, TypeBounds.BOOLEAN);
+ }
+
+ // Test whether conversion from source to target involves a call of ES 9.1 ToPrimitive
+ // with possible side effects from calling an object's toString or valueOf methods.
+- private boolean noToPrimitiveConversion(final Type source, final Type target) {
++ private static boolean noToPrimitiveConversion(final Type source, final Type target) {
+ // Object to boolean conversion does not cause ToPrimitive call
+ return source.isJSPrimitive() || !target.isJSPrimitive() || target.isBoolean();
+ }
+
+- MethodEmitter loadBinaryOperands(final Expression lhs, final Expression rhs, final Type type) {
+- return loadBinaryOperands(lhs, rhs, type, false);
++ MethodEmitter loadBinaryOperands(final BinaryNode binaryNode) {
++ return loadBinaryOperands(binaryNode.lhs(), binaryNode.rhs(), TypeBounds.UNBOUNDED.notWiderThan(binaryNode.getWidestOperandType()), false, false);
+ }
+
+- private MethodEmitter loadBinaryOperands(final Expression lhs, final Expression rhs, final Type type, final boolean baseAlreadyOnStack) {
++ private MethodEmitter loadBinaryOperands(final Expression lhs, final Expression rhs, final TypeBounds explicitOperandBounds, final boolean baseAlreadyOnStack, final boolean forceConversionSeparation) {
+ // ECMAScript 5.1 specification (sections 11.5-11.11 and 11.13) prescribes that when evaluating a binary
+ // expression "LEFT op RIGHT", the order of operations must be: LOAD LEFT, LOAD RIGHT, CONVERT LEFT, CONVERT
+ // RIGHT, EXECUTE OP. Unfortunately, doing it in this order defeats potential optimizations that arise when we
+@@ -381,38 +568,154 @@
+ // a primitive value, or RIGHT is an expression that loads without side effects, then we can do the
+ // reordering and collapse LOAD/CONVERT into a single operation; otherwise we need to do the more costly
+ // separate operations to preserve specification semantics.
+- if (noToPrimitiveConversion(lhs.getType(), type) || rhs.isLocal()) {
+- // Can reorder. Combine load and convert into single operations.
+- load(lhs, type, baseAlreadyOnStack);
+- load(rhs, type, false);
++
++ // Operands' load type should not be narrower than the narrowest of the individual operand types, nor narrower
++ // than the lower explicit bound, but it should also not be wider than
++ final Type lhsType = undefinedToNumber(lhs.getType());
++ final Type rhsType = undefinedToNumber(rhs.getType());
++ final Type narrowestOperandType = Type.narrowest(Type.widest(lhsType, rhsType), explicitOperandBounds.widest);
++ final TypeBounds operandBounds = explicitOperandBounds.notNarrowerThan(narrowestOperandType);
++ if (noToPrimitiveConversion(lhsType, explicitOperandBounds.widest) || rhs.isLocal()) {
++ // Can reorder. We might still need to separate conversion, but at least we can do it with reordering
++ if (forceConversionSeparation) {
++ // Can reorder, but can't move conversion into the operand as the operation depends on operands
++ // exact types for its overflow guarantees. E.g. with {L}{%I}expr1 {L}* {L}{%I}expr2 we are not allowed
++ // to merge {L}{%I} into {%L}, as that can cause subsequent overflows; test for JDK-8058610 contains
++ // concrete cases where this could happen.
++ final TypeBounds safeConvertBounds = TypeBounds.UNBOUNDED.notNarrowerThan(narrowestOperandType);
++ loadExpression(lhs, safeConvertBounds, baseAlreadyOnStack);
++ method.convert(operandBounds.within(method.peekType()));
++ loadExpression(rhs, safeConvertBounds, false);
++ method.convert(operandBounds.within(method.peekType()));
++ } else {
++ // Can reorder and move conversion into the operand. Combine load and convert into single operations.
++ loadExpression(lhs, operandBounds, baseAlreadyOnStack);
++ loadExpression(rhs, operandBounds, false);
++ }
+ } else {
+ // Can't reorder. Load and convert separately.
+- load(lhs, lhs.getType(), baseAlreadyOnStack);
+- load(rhs, rhs.getType(), false);
+- method.swap().convert(type).swap().convert(type);
+- }
++ final TypeBounds safeConvertBounds = TypeBounds.UNBOUNDED.notNarrowerThan(narrowestOperandType);
++ loadExpression(lhs, safeConvertBounds, baseAlreadyOnStack);
++ final Type lhsLoadedType = method.peekType();
++ loadExpression(rhs, safeConvertBounds, false);
++ final Type convertedLhsType = operandBounds.within(method.peekType());
++ if (convertedLhsType != lhsLoadedType) {
++ // Do it conditionally, so that if conversion is a no-op we don't introduce a SWAP, SWAP.
++ method.swap().convert(convertedLhsType).swap();
++ }
++ method.convert(operandBounds.within(method.peekType()));
++ }
++ assert Type.generic(method.peekType()) == operandBounds.narrowest;
++ assert Type.generic(method.peekType(1)) == operandBounds.narrowest;
+
+ return method;
+ }
+
+- MethodEmitter loadBinaryOperands(final BinaryNode node) {
+- return loadBinaryOperands(node.lhs(), node.rhs(), node.getType(), false);
++ private static final Type undefinedToNumber(final Type type) {
++ return type == Type.UNDEFINED ? Type.NUMBER : type;
+ }
+
+- MethodEmitter load(final Expression node, final Type type) {
+- return load(node, type, false);
++ private static final class TypeBounds {
++ final Type narrowest;
++ final Type widest;
++
++ static final TypeBounds UNBOUNDED = new TypeBounds(Type.UNKNOWN, Type.OBJECT);
++ static final TypeBounds INT = exact(Type.INT);
++ static final TypeBounds OBJECT = exact(Type.OBJECT);
++ static final TypeBounds BOOLEAN = exact(Type.BOOLEAN);
++
++ static TypeBounds exact(final Type type) {
++ return new TypeBounds(type, type);
++ }
++
++ TypeBounds(final Type narrowest, final Type widest) {
++ assert widest != null && widest != Type.UNDEFINED && widest != Type.UNKNOWN : widest;
++ assert narrowest != null && narrowest != Type.UNDEFINED : narrowest;
++ assert !narrowest.widerThan(widest) : narrowest + " wider than " + widest;
++ assert !widest.narrowerThan(narrowest);
++ this.narrowest = Type.generic(narrowest);
++ this.widest = Type.generic(widest);
++ }
++
++ TypeBounds notNarrowerThan(final Type type) {
++ return maybeNew(Type.narrowest(Type.widest(narrowest, type), widest), widest);
++ }
++
++ TypeBounds notWiderThan(final Type type) {
++ return maybeNew(Type.narrowest(narrowest, type), Type.narrowest(widest, type));
++ }
++
++ boolean canBeNarrowerThan(final Type type) {
++ return narrowest.narrowerThan(type);
++ }
++
++ TypeBounds maybeNew(final Type newNarrowest, final Type newWidest) {
++ if(newNarrowest == narrowest && newWidest == widest) {
++ return this;
++ }
++ return new TypeBounds(newNarrowest, newWidest);
++ }
++
++ TypeBounds booleanToInt() {
++ return maybeNew(CodeGenerator.booleanToInt(narrowest), CodeGenerator.booleanToInt(widest));
++ }
++
++ TypeBounds objectToNumber() {
++ return maybeNew(CodeGenerator.objectToNumber(narrowest), CodeGenerator.objectToNumber(widest));
++ }
++
++ Type within(final Type type) {
++ if(type.narrowerThan(narrowest)) {
++ return narrowest;
++ }
++ if(type.widerThan(widest)) {
++ return widest;
++ }
++ return type;
++ }
++
++ @Override
++ public String toString() {
++ return "[" + narrowest + ", " + widest + "]";
++ }
+ }
+
+- private MethodEmitter load(final Expression node, final Type type, final boolean baseAlreadyOnStack) {
+- final Symbol symbol = node.getSymbol();
+-
+- // If we lack symbols, we just generate what we see.
+- if (symbol == null || type == null) {
+- node.accept(this);
+- return method;
+- }
+-
+- assert !type.isUnknown();
++ private static Type booleanToInt(final Type t) {
++ return t == Type.BOOLEAN ? Type.INT : t;
++ }
++
++ private static Type objectToNumber(final Type t) {
++ return t.isObject() ? Type.NUMBER : t;
++ }
++
++ MethodEmitter loadExpressionAsType(final Expression expr, final Type type) {
++ if(type == Type.BOOLEAN) {
++ return loadExpressionAsBoolean(expr);
++ } else if(type == Type.UNDEFINED) {
++ assert expr.getType() == Type.UNDEFINED;
++ return loadExpressionAsObject(expr);
++ }
++ // having no upper bound preserves semantics of optimistic operations in the expression (by not having them
++ // converted early) and then applies explicit conversion afterwards.
++ return loadExpression(expr, TypeBounds.UNBOUNDED.notNarrowerThan(type)).convert(type);
++ }
++
++ private MethodEmitter loadExpression(final Expression expr, final TypeBounds resultBounds) {
++ return loadExpression(expr, resultBounds, false);
++ }
++
++ /**
++ * Emits code for evaluating an expression and leaving its value on top of the stack, narrowing or widening it if
++ * necessary.
++ * @param expr the expression to load
++ * @param resultBounds the incoming type bounds. The value on the top of the stack is guaranteed to not be of narrower
++ * type than the narrowest bound, or wider type than the widest bound after it is loaded.
++ * @param baseAlreadyOnStack true if the base of an access or index node is already on the stack. Used to avoid
++ * double evaluation of bases in self-assignment expressions to access and index nodes. {@code Type.OBJECT} is used
++ * to indicate the widest possible type.
++ * @return the method emitter
++ */
++ private MethodEmitter loadExpression(final Expression expr, final TypeBounds resultBounds, final boolean baseAlreadyOnStack) {
+
+ /*
+ * The load may be of type IdentNode, e.g. "x", AccessNode, e.g. "x.y"
+@@ -421,35 +724,54 @@
+ */
+ final CodeGenerator codegen = this;
+
+- node.accept(new NodeVisitor<LexicalContext>(lc) {
++ final Node currentDiscard = codegen.lc.getCurrentDiscard();
++ expr.accept(new NodeOperatorVisitor<LexicalContext>(new LexicalContext()) {
+ @Override
+ public boolean enterIdentNode(final IdentNode identNode) {
+- loadIdent(identNode, type);
++ loadIdent(identNode, resultBounds);
+ return false;
+ }
+
+ @Override
+ public boolean enterAccessNode(final AccessNode accessNode) {
+- if (!baseAlreadyOnStack) {
+- load(accessNode.getBase(), Type.OBJECT);
+- }
+- assert method.peekType().isObject();
+- method.dynamicGet(type, accessNode.getProperty().getName(), getCallSiteFlags(), accessNode.isFunction());
++ new OptimisticOperation(accessNode, resultBounds) {
++ @Override
++ void loadStack() {
++ if (!baseAlreadyOnStack) {
++ loadExpressionAsObject(accessNode.getBase());
++ }
++ assert method.peekType().isObject();
++ }
++ @Override
++ void consumeStack() {
++ final int flags = getCallSiteFlags();
++ dynamicGet(accessNode.getProperty(), flags, accessNode.isFunction(), accessNode.isIndex());
++ }
++ }.emit(baseAlreadyOnStack ? 1 : 0);
+ return false;
+ }
+
+ @Override
+ public boolean enterIndexNode(final IndexNode indexNode) {
+- if (!baseAlreadyOnStack) {
+- load(indexNode.getBase(), Type.OBJECT);
+- load(indexNode.getIndex());
+- }
+- method.dynamicGetIndex(type, getCallSiteFlags(), indexNode.isFunction());
++ new OptimisticOperation(indexNode, resultBounds) {
++ @Override
++ void loadStack() {
++ if (!baseAlreadyOnStack) {
++ loadExpressionAsObject(indexNode.getBase());
++ loadExpressionUnbounded(indexNode.getIndex());
++ }
++ }
++ @Override
++ void consumeStack() {
++ final int flags = getCallSiteFlags();
++ dynamicGetIndex(flags, indexNode.isFunction());
++ }
++ }.emit(baseAlreadyOnStack ? 2 : 0);
+ return false;
+ }
+
+ @Override
+- public boolean enterFunctionNode(FunctionNode functionNode) {
++ public boolean enterFunctionNode(final FunctionNode functionNode) {
+ // function nodes will always leave a constructed function object on stack, no need to load the symbol
+ // separately as in enterDefault()
+ lc.pop(functionNode);
+@@ -459,204 +781,496 @@
+ // is the last element in the compilation pipeline, the AST it produces is not used externally. So, we
+ // re-push the original functionNode.
+ lc.push(functionNode);
+- method.convert(type);
+ return false;
+ }
+
+ @Override
+- public boolean enterCallNode(CallNode callNode) {
+- return codegen.enterCallNode(callNode, type);
++ public boolean enterASSIGN(final BinaryNode binaryNode) {
++ loadASSIGN(binaryNode);
++ return false;
+ }
+
+ @Override
+- public boolean enterLiteralNode(LiteralNode<?> literalNode) {
+- return codegen.enterLiteralNode(literalNode, type);
++ public boolean enterASSIGN_ADD(final BinaryNode binaryNode) {
++ loadASSIGN_ADD(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterASSIGN_BIT_AND(final BinaryNode binaryNode) {
++ loadASSIGN_BIT_AND(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterASSIGN_BIT_OR(final BinaryNode binaryNode) {
++ loadASSIGN_BIT_OR(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterASSIGN_BIT_XOR(final BinaryNode binaryNode) {
++ loadASSIGN_BIT_XOR(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterASSIGN_DIV(final BinaryNode binaryNode) {
++ loadASSIGN_DIV(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterASSIGN_MOD(final BinaryNode binaryNode) {
++ loadASSIGN_MOD(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterASSIGN_MUL(final BinaryNode binaryNode) {
++ loadASSIGN_MUL(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterASSIGN_SAR(final BinaryNode binaryNode) {
++ loadASSIGN_SAR(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterASSIGN_SHL(final BinaryNode binaryNode) {
++ loadASSIGN_SHL(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterASSIGN_SHR(final BinaryNode binaryNode) {
++ loadASSIGN_SHR(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterASSIGN_SUB(final BinaryNode binaryNode) {
++ loadASSIGN_SUB(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterCallNode(final CallNode callNode) {
++ return loadCallNode(callNode, resultBounds);
++ }
++
++ @Override
++ public boolean enterLiteralNode(final LiteralNode<?> literalNode) {
++ loadLiteral(literalNode, resultBounds);
++ return false;
++ }
++
++ @Override
++ public boolean enterTernaryNode(final TernaryNode ternaryNode) {
++ loadTernaryNode(ternaryNode, resultBounds);
++ return false;
++ }
++
++ @Override
++ public boolean enterADD(final BinaryNode binaryNode) {
++ loadADD(binaryNode, resultBounds);
++ return false;
++ }
++
++ @Override
++ public boolean enterSUB(final UnaryNode unaryNode) {
++ loadSUB(unaryNode, resultBounds);
++ return false;
++ }
++
++ @Override
++ public boolean enterSUB(final BinaryNode binaryNode) {
++ loadSUB(binaryNode, resultBounds);
++ return false;
++ }
++
++ @Override
++ public boolean enterMUL(final BinaryNode binaryNode) {
++ loadMUL(binaryNode, resultBounds);
++ return false;
++ }
++
++ @Override
++ public boolean enterDIV(final BinaryNode binaryNode) {
++ loadDIV(binaryNode, resultBounds);
++ return false;
++ }
++
++ @Override
++ public boolean enterMOD(final BinaryNode binaryNode) {
++ loadMOD(binaryNode, resultBounds);
++ return false;
++ }
++
++ @Override
++ public boolean enterSAR(final BinaryNode binaryNode) {
++ loadSAR(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterSHL(final BinaryNode binaryNode) {
++ loadSHL(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterSHR(final BinaryNode binaryNode) {
++ loadSHR(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterCOMMALEFT(final BinaryNode binaryNode) {
++ loadCOMMALEFT(binaryNode, resultBounds);
++ return false;
++ }
++
++ @Override
++ public boolean enterCOMMARIGHT(final BinaryNode binaryNode) {
++ loadCOMMARIGHT(binaryNode, resultBounds);
++ return false;
++ }
++
++ @Override
++ public boolean enterAND(final BinaryNode binaryNode) {
++ loadAND_OR(binaryNode, resultBounds, true);
++ return false;
++ }
++
++ @Override
++ public boolean enterOR(final BinaryNode binaryNode) {
++ loadAND_OR(binaryNode, resultBounds, false);
++ return false;
++ }
++
++ @Override
++ public boolean enterNOT(final UnaryNode unaryNode) {
++ loadNOT(unaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterADD(final UnaryNode unaryNode) {
++ loadADD(unaryNode, resultBounds);
++ return false;
++ }
++
++ @Override
++ public boolean enterBIT_NOT(final UnaryNode unaryNode) {
++ loadBIT_NOT(unaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterBIT_AND(final BinaryNode binaryNode) {
++ loadBIT_AND(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterBIT_OR(final BinaryNode binaryNode) {
++ loadBIT_OR(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterBIT_XOR(final BinaryNode binaryNode) {
++ loadBIT_XOR(binaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterVOID(final UnaryNode unaryNode) {
++ loadVOID(unaryNode, resultBounds);
++ return false;
++ }
++
++ @Override
++ public boolean enterEQ(final BinaryNode binaryNode) {
++ loadCmp(binaryNode, Condition.EQ);
++ return false;
++ }
++
++ @Override
++ public boolean enterEQ_STRICT(final BinaryNode binaryNode) {
++ loadCmp(binaryNode, Condition.EQ);
++ return false;
++ }
++
++ @Override
++ public boolean enterGE(final BinaryNode binaryNode) {
++ loadCmp(binaryNode, Condition.GE);
++ return false;
++ }
++
++ @Override
++ public boolean enterGT(final BinaryNode binaryNode) {
++ loadCmp(binaryNode, Condition.GT);
++ return false;
++ }
++
++ @Override
++ public boolean enterLE(final BinaryNode binaryNode) {
++ loadCmp(binaryNode, Condition.LE);
++ return false;
++ }
++
++ @Override
++ public boolean enterLT(final BinaryNode binaryNode) {
++ loadCmp(binaryNode, Condition.LT);
++ return false;
++ }
++
++ @Override
++ public boolean enterNE(final BinaryNode binaryNode) {
++ loadCmp(binaryNode, Condition.NE);
++ return false;
++ }
++
++ @Override
++ public boolean enterNE_STRICT(final BinaryNode binaryNode) {
++ loadCmp(binaryNode, Condition.NE);
++ return false;
++ }
++
++ @Override
++ public boolean enterObjectNode(final ObjectNode objectNode) {
++ loadObjectNode(objectNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterRuntimeNode(final RuntimeNode runtimeNode) {
++ loadRuntimeNode(runtimeNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterNEW(final UnaryNode unaryNode) {
++ loadNEW(unaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterDECINC(final UnaryNode unaryNode) {
++ loadDECINC(unaryNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterJoinPredecessorExpression(final JoinPredecessorExpression joinExpr) {
++ loadExpression(joinExpr.getExpression(), resultBounds);
++ return false;
++ }
++
++ @Override
++ public boolean enterGetSplitState(final GetSplitState getSplitState) {
++ method.loadScope();
++ method.invoke(Scope.GET_SPLIT_STATE);
++ return false;
+ }
+
+ @Override
+ public boolean enterDefault(final Node otherNode) {
+- final Node currentDiscard = codegen.lc.getCurrentDiscard();
+- otherNode.accept(codegen); // generate code for whatever we are looking at.
+- if(currentDiscard != otherNode) {
+- method.load(symbol); // load the final symbol to the stack (or nop if no slot, then result is already there)
+- assert method.peekType() != null;
+- method.convert(type);
+- }
+- return false;
++ // Must have handled all expressions that can legally be encountered.
++ throw new AssertionError(otherNode.getClass().getName());
+ }
+ });
+-
++ if(currentDiscard != expr) {
++ coerceStackTop(resultBounds);
++ }
+ return method;
+ }
+
+- @Override
+- public boolean enterAccessNode(final AccessNode accessNode) {
+- load(accessNode);
+- return false;
++ private MethodEmitter coerceStackTop(final TypeBounds typeBounds) {
++ return method.convert(typeBounds.within(method.peekType()));
+ }
+
+ /**
+- * Initialize a specific set of vars to undefined. This has to be done at
+- * the start of each method for local variables that aren't passed as
+- * parameters.
+- *
+- * @param symbols list of symbols.
+- */
+- private void initSymbols(final Iterable<Symbol> symbols) {
+- final LinkedList<Symbol> numbers = new LinkedList<>();
+- final LinkedList<Symbol> objects = new LinkedList<>();
+-
+- for (final Symbol symbol : symbols) {
+- /*
+- * The following symbols are guaranteed to be defined and thus safe
+- * from having undefined written to them: parameters internals this
+- *
+- * Otherwise we must, unless we perform control/escape analysis,
+- * assign them undefined.
+- */
+- final boolean isInternal = symbol.isParam() || symbol.isInternal() || symbol.isThis() || !symbol.canBeUndefined();
+-
+- if (symbol.hasSlot() && !isInternal) {
+- assert symbol.getSymbolType().isNumber() || symbol.getSymbolType().isObject() : "no potentially undefined narrower local vars than doubles are allowed: " + symbol + " in " + lc.getCurrentFunction();
+- if (symbol.getSymbolType().isNumber()) {
+- numbers.add(symbol);
+- } else if (symbol.getSymbolType().isObject()) {
+- objects.add(symbol);
+- }
+- }
+- }
+-
+- initSymbols(numbers, Type.NUMBER);
+- initSymbols(objects, Type.OBJECT);
+- }
+-
+- private void initSymbols(final LinkedList<Symbol> symbols, final Type type) {
+- final Iterator<Symbol> it = symbols.iterator();
+- if(it.hasNext()) {
+- method.loadUndefined(type);
+- boolean hasNext;
+- do {
+- final Symbol symbol = it.next();
+- hasNext = it.hasNext();
+- if(hasNext) {
+- method.dup();
+- }
+- method.store(symbol);
+- } while(hasNext);
+- }
+- }
+-
+- /**
+- * Create symbol debug information.
++ * Closes any still open entries for this block's local variables in the bytecode local variable table.
+ *
+ * @param block block containing symbols.
+ */
+- private void symbolInfo(final Block block) {
++ private void closeBlockVariables(final Block block) {
+ for (final Symbol symbol : block.getSymbols()) {
+- if (symbol.hasSlot()) {
+- method.localVariable(symbol, block.getEntryLabel(), block.getBreakLabel());
++ if (symbol.isBytecodeLocal()) {
++ method.closeLocalVariable(symbol, block.getBreakLabel());
+ }
+ }
+ }
+
+ @Override
+ public boolean enterBlock(final Block block) {
++ method.label(block.getEntryLabel());
++ if(!method.isReachable()) {
++ return false;
++ }
+ if(lc.isFunctionBody() && emittedMethods.contains(lc.getCurrentFunction().getName())) {
+ return false;
+ }
+- method.label(block.getEntryLabel());
+ initLocals(block);
+
++ assert lc.getUsedSlotCount() == method.getFirstTemp();
+ return true;
+ }
+
++ private boolean useOptimisticTypes() {
++ return !lc.inSplitNode() && compiler.useOptimisticTypes();
++ }
++
+ @Override
+ public Node leaveBlock(final Block block) {
+- method.label(block.getBreakLabel());
+- symbolInfo(block);
+-
+- if (block.needsScope() && !block.isTerminal()) {
+- popBlockScope(block);
+- }
++ popBlockScope(block);
++ method.beforeJoinPoint(block);
++
++ closeBlockVariables(block);
++ lc.releaseSlots();
++ assert !method.isReachable() || (lc.isFunctionBody() ? 0 : lc.getUsedSlotCount()) == method.getFirstTemp() :
++ "reachable="+method.isReachable() +
++ " isFunctionBody=" + lc.isFunctionBody() +
++ " usedSlotCount=" + lc.getUsedSlotCount() +
++ " firstTemp=" + method.getFirstTemp();
++
+ return block;
+ }
+
+ private void popBlockScope(final Block block) {
+- final Label exitLabel = new Label("block_exit");
+- final Label recoveryLabel = new Label("block_catch");
+- final Label skipLabel = new Label("skip_catch");
+-
+- /* pop scope a la try-finally */
++ final Label breakLabel = block.getBreakLabel();
++
++ if(!block.needsScope() || lc.isFunctionBody()) {
++ emitBlockBreakLabel(breakLabel);
++ return;
++ }
++
++ final Label beginTryLabel = scopeEntryLabels.pop();
++ final Label recoveryLabel = new Label("block_popscope_catch");
++ emitBlockBreakLabel(breakLabel);
++ final boolean bodyCanThrow = breakLabel.isAfter(beginTryLabel);
++ if(bodyCanThrow) {
++ method._try(beginTryLabel, breakLabel, recoveryLabel);
++ }
++
++ Label afterCatchLabel = null;
++
++ if(method.isReachable()) {
++ popScope();
++ if(bodyCanThrow) {
++ afterCatchLabel = new Label("block_after_catch");
++ method._goto(afterCatchLabel);
++ }
++ }
++
++ if(bodyCanThrow) {
++ assert !method.isReachable();
++ method._catch(recoveryLabel);
++ popScopeException();
++ method.athrow();
++ }
++ if(afterCatchLabel != null) {
++ method.label(afterCatchLabel);
++ }
++ }
++
++ private void emitBlockBreakLabel(final Label breakLabel) {
++ // TODO: this is totally backwards. Block should not be breakable, LabelNode should be breakable.
++ final LabelNode labelNode = lc.getCurrentBlockLabelNode();
++ if(labelNode != null) {
++ // Only have conversions if we're reachable
++ assert labelNode.getLocalVariableConversion() == null || method.isReachable();
++ method.beforeJoinPoint(labelNode);
++ method.breakLabel(breakLabel, labeledBlockBreakLiveLocals.pop());
++ } else {
++ method.label(breakLabel);
++ }
++ }
++
++ private void popScope() {
++ popScopes(1);
++ }
++
++ /**
++ * Pop scope as part of an exception handler. Similar to {@code popScope()} but also takes care of adjusting the
++ * number of scopes that needs to be popped in case a rest-of continuation handler encounters an exception while
++ * performing a ToPrimitive conversion.
++ */
++ private void popScopeException() {
++ popScope();
++ final ContinuationInfo ci = getContinuationInfo();
++ if(ci != null) {
++ final Label catchLabel = ci.catchLabel;
++ if(catchLabel != METHOD_BOUNDARY && catchLabel == catchLabels.peek()) {
++ ++ci.exceptionScopePops;
++ }
++ }
++ }
++
++ private void popScopesUntil(final LexicalContextNode until) {
++ popScopes(lc.getScopeNestingLevelTo(until));
++ }
++
++ private void popScopes(final int count) {
++ if(count == 0) {
++ return;
++ }
++ assert count > 0; // together with count == 0 check, asserts nonnegative count
++ if (!method.hasScope()) {
++ // We can sometimes invoke this method even if the method has no slot for the scope object. Typical example:
++ // for(;;) { with({}) { break; } }. WithNode normally creates a scope, but if it uses no identifiers and
++ // nothing else forces creation of a scope in the method, we just won't have the :scope local variable.
++ return;
++ }
+ method.loadCompilerConstant(SCOPE);
+- method.invoke(ScriptObject.GET_PROTO);
++ for(int i = 0; i < count; ++i) {
++ method.invoke(ScriptObject.GET_PROTO);
++ }
+ method.storeCompilerConstant(SCOPE);
+- method._goto(skipLabel);
+- method.label(exitLabel);
+-
+- method._catch(recoveryLabel);
+- method.loadCompilerConstant(SCOPE);
+- method.invoke(ScriptObject.GET_PROTO);
+- method.storeCompilerConstant(SCOPE);
+- method.athrow();
+- method.label(skipLabel);
+- method._try(block.getEntryLabel(), exitLabel, recoveryLabel, Throwable.class);
+ }
+
+ @Override
+ public boolean enterBreakNode(final BreakNode breakNode) {
+- lineNumber(breakNode);
+-
+- final BreakableNode breakFrom = lc.getBreakable(breakNode.getLabel());
+- for (int i = 0; i < lc.getScopeNestingLevelTo(breakFrom); i++) {
+- closeWith();
+- }
+- method.splitAwareGoto(lc, breakFrom.getBreakLabel());
++ return enterJumpStatement(breakNode);
++ }
++
++ private boolean enterJumpStatement(final JumpStatement jump) {
++ if(!method.isReachable()) {
++ return false;
++ }
++ enterStatement(jump);
++
++ method.beforeJoinPoint(jump);
++ final BreakableNode target = jump.getTarget(lc);
++ popScopesUntil(target);
++ final Label targetLabel = jump.getTargetLabel(target);
++ targetLabel.markAsBreakTarget();
++ method._goto(targetLabel);
+
+ return false;
+ }
+
+ private int loadArgs(final List<Expression> args) {
+- return loadArgs(args, null, false, args.size());
+- }
+-
+- private int loadArgs(final List<Expression> args, final String signature, final boolean isVarArg, final int argCount) {
++ final int argCount = args.size();
+ // arg have already been converted to objects here.
+- if (isVarArg || argCount > LinkerCallSite.ARGLIMIT) {
++ if (argCount > LinkerCallSite.ARGLIMIT) {
+ loadArgsArray(args);
+ return 1;
+ }
+
+- // pad with undefined if size is too short. argCount is the real number of args
+- int n = 0;
+- final Type[] params = signature == null ? null : Type.getMethodArguments(signature);
+ for (final Expression arg : args) {
+ assert arg != null;
+- if (n >= argCount) {
+- load(arg);
+- method.pop(); // we had to load the arg for its side effects
+- } else if (params != null) {
+- load(arg, params[n]);
+- } else {
+- load(arg);
+- }
+- n++;
+- }
+-
+- while (n < argCount) {
+- method.loadUndefined(Type.OBJECT);
+- n++;
+- }
+-
++ loadExpressionUnbounded(arg);
++ }
+ return argCount;
+ }
+
+-
+- @Override
+- public boolean enterCallNode(final CallNode callNode) {
+- return enterCallNode(callNode, callNode.getType());
+- }
+-
+- private boolean enterCallNode(final CallNode callNode, final Type callNodeType) {
++ private boolean loadCallNode(final CallNode callNode, final TypeBounds resultBounds) {
+ lineNumber(callNode.getLineNumber());
+
+ final List<Expression> args = callNode.getArgs();
+@@ -668,68 +1282,122 @@
+
+ private MethodEmitter sharedScopeCall(final IdentNode identNode, final int flags) {
+ final Symbol symbol = identNode.getSymbol();
+- int scopeCallFlags = flags;
+- method.loadCompilerConstant(SCOPE);
+- if (isFastScope(symbol)) {
+- method.load(getScopeProtoDepth(currentBlock, symbol));
+- scopeCallFlags |= CALLSITE_FAST_SCOPE;
+- } else {
+- method.load(-1); // Bypass fast-scope code in shared callsite
+- }
+- loadArgs(args);
+- final Type[] paramTypes = method.getTypesFromStack(args.size());
+- final SharedScopeCall scopeCall = codegenLexicalContext.getScopeCall(unit, symbol, identNode.getType(), callNodeType, paramTypes, scopeCallFlags);
+- return scopeCall.generateInvoke(method);
+- }
+-
+- private void scopeCall(final IdentNode node, final int flags) {
+- load(node, Type.OBJECT); // Type.OBJECT as foo() makes no sense if foo == 3
+- // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
+- method.loadUndefined(Type.OBJECT); //the 'this' object
+- method.dynamicCall(callNodeType, 2 + loadArgs(args), flags);
+- }
+-
+- private void evalCall(final IdentNode node, final int flags) {
+- load(node, Type.OBJECT); // Type.OBJECT as foo() makes no sense if foo == 3
+-
+- final Label not_eval = new Label("not_eval");
++ final boolean isFastScope = isFastScope(symbol);
++ final int scopeCallFlags = flags | (isFastScope ? CALLSITE_FAST_SCOPE : 0);
++ new OptimisticOperation(callNode, resultBounds) {
++ @Override
++ void loadStack() {
++ method.loadCompilerConstant(SCOPE);
++ if (isFastScope) {
++ method.load(getScopeProtoDepth(currentBlock, symbol));
++ } else {
++ method.load(-1); // Bypass fast-scope code in shared callsite
++ }
++ loadArgs(args);
++ }
++ @Override
++ void consumeStack() {
++ final Type[] paramTypes = method.getTypesFromStack(args.size());
++ // We have trouble finding e.g. in Type.typeFor(asm.Type) because it can't see the Context class
++ // loader, so we need to weaken reference signatures to Object.
++ for(int i = 0; i < paramTypes.length; ++i) {
++ paramTypes[i] = Type.generic(paramTypes[i]);
++ }
++ // As shared scope calls are only used in non-optimistic compilation, we switch from using
++ // TypeBounds to just a single definitive type, resultBounds.widest.
++ final SharedScopeCall scopeCall = codegenLexicalContext.getScopeCall(unit, symbol,
++ identNode.getType(), resultBounds.widest, paramTypes, scopeCallFlags);
++ scopeCall.generateInvoke(method);
++ }
++ }.emit();
++ return method;
++ }
++
++ private void scopeCall(final IdentNode ident, final int flags) {
++ new OptimisticOperation(callNode, resultBounds) {
++ int argsCount;
++ @Override
++ void loadStack() {
++ loadExpressionAsObject(ident); // foo() makes no sense if foo == 3
++ // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
++ method.loadUndefined(Type.OBJECT); //the 'this'
++ argsCount = loadArgs(args);
++ }
++ @Override
++ void consumeStack() {
++ dynamicCall(2 + argsCount, flags);
++ }
++ }.emit();
++ }
++
++ private void evalCall(final IdentNode ident, final int flags) {
++ final Label invoke_direct_eval = new Label("invoke_direct_eval");
++ final Label is_not_eval = new Label("is_not_eval");
+ final Label eval_done = new Label("eval_done");
+
+- // check if this is the real built-in eval
+- method.dup();
+- globalIsEval();
+-
+- method.ifeq(not_eval);
+- // We don't need ScriptFunction object for 'eval'
+- method.pop();
+-
+- method.loadCompilerConstant(SCOPE); // Load up self (scope).
+-
+- final CallNode.EvalArgs evalArgs = callNode.getEvalArgs();
+- // load evaluated code
+- load(evalArgs.getCode(), Type.OBJECT);
+- // load second and subsequent args for side-effect
+- final List<Expression> args = callNode.getArgs();
+- final int numArgs = args.size();
+- for (int i = 1; i < numArgs; i++) {
+- load(args.get(i)).pop();
+- }
+- // special/extra 'eval' arguments
+- load(evalArgs.getThis());
+- method.load(evalArgs.getLocation());
+- method.load(evalArgs.getStrictMode());
+- method.convert(Type.OBJECT);
+-
+- // direct call to Global.directEval
+- globalDirectEval();
+- method.convert(callNodeType);
+- method._goto(eval_done);
+-
+- method.label(not_eval);
+- // This is some scope 'eval' or global eval replaced by user
+- // but not the built-in ECMAScript 'eval' function call
+- method.loadNull();
+- method.dynamicCall(callNodeType, 2 + loadArgs(args), flags);
++ new OptimisticOperation(callNode, resultBounds) {
++ int argsCount;
++ @Override
++ void loadStack() {
++ /**
++ * We want to load 'eval' to check if it is indeed global builtin eval.
++ * If this eval call is inside a 'with' statement, dyn:getMethod|getProp|getElem
++ * would be generated if ident is a "isFunction". But, that would result in a
++ * bound function from WithObject. We don't want that as bound function as that
++ * won't be detected as builtin eval. So, we make ident as "not a function" which
++ * results in "dyn:getProp|getElem|getMethod" being generated and so WithObject
++ * would return unbounded eval function.
++ *
++ * Example:
++ *
++ * var global = this;
++ * function func() {
++ * with({ eval: global.eval) { eval("var x = 10;") }
++ * }
++ */
++ loadExpressionAsObject(ident.setIsNotFunction()); // Type.OBJECT as foo() makes no sense if foo == 3
++ globalIsEval();
++ method.ifeq(is_not_eval);
++
++ // Load up self (scope).
++ method.loadCompilerConstant(SCOPE);
++ final List<Expression> evalArgs = callNode.getEvalArgs().getArgs();
++ // load evaluated code
++ loadExpressionAsObject(evalArgs.get(0));
++ // load second and subsequent args for side-effect
++ final int numArgs = evalArgs.size();
++ for (int i = 1; i < numArgs; i++) {
++ loadAndDiscard(evalArgs.get(i));
++ }
++ method._goto(invoke_direct_eval);
++
++ method.label(is_not_eval);
++ // load this time but with dyn:getMethod|getProp|getElem
++ loadExpressionAsObject(ident); // Type.OBJECT as foo() makes no sense if foo == 3
++ // This is some scope 'eval' or global eval replaced by user
++ // but not the built-in ECMAScript 'eval' function call
++ method.loadNull();
++ argsCount = loadArgs(callNode.getArgs());
++ }
++
++ @Override
++ void consumeStack() {
++ // Ordinary call
++ dynamicCall(2 + argsCount, flags);
++ method._goto(eval_done);
++
++ method.label(invoke_direct_eval);
++ // Special/extra 'eval' arguments. These can be loaded late (in consumeStack) as we know none of
++ // them can ever be optimistic.
++ method.loadCompilerConstant(THIS);
++ method.load(callNode.getEvalArgs().getLocation());
++ method.load(CodeGenerator.this.lc.getCurrentFunction().isStrict());
++ // direct call to Global.directEval
++ globalDirectEval();
++ convertOptimisticReturnValue();
++ coerceStackTop(resultBounds);
++ }
++ }.emit();
+
+ method.label(eval_done);
+ }
+@@ -748,13 +1416,14 @@
+ if (callNode.isEval()) {
+ evalCall(node, flags);
+ } else if (useCount <= SharedScopeCall.FAST_SCOPE_CALL_THRESHOLD
+- || (!isFastScope(symbol) && useCount <= SharedScopeCall.SLOW_SCOPE_CALL_THRESHOLD)
+- || CodeGenerator.this.lc.inDynamicScope()) {
++ || !isFastScope(symbol) && useCount <= SharedScopeCall.SLOW_SCOPE_CALL_THRESHOLD
++ || CodeGenerator.this.lc.inDynamicScope()
++ || isOptimisticOrRestOf()) {
+ scopeCall(node, flags);
+ } else {
+ sharedScopeCall(node, flags);
+ }
+- assert method.peekType().equals(callNodeType) : method.peekType() + "!=" + callNode.getType();
++ assert method.peekType().equals(resultBounds.within(callNode.getType())) : method.peekType() + " != " + resultBounds + "(" + callNode.getType() + ")";
+ } else {
+ enterDefault(node);
+ }
+@@ -764,189 +1433,239 @@
+
+ @Override
+ public boolean enterAccessNode(final AccessNode node) {
+- load(node.getBase(), Type.OBJECT);
+- method.dup();
+- method.dynamicGet(node.getType(), node.getProperty().getName(), getCallSiteFlags(), true);
+- method.swap();
+- method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags());
++ //check if this is an apply to call node. only real applies, that haven't been
++ //shadowed from their way to the global scope counts
++
++ //call nodes have program points.
++
++ final int flags = getCallSiteFlags() | (callNode.isApplyToCall() ? CALLSITE_APPLY_TO_CALL : 0);
++
++ new OptimisticOperation(callNode, resultBounds) {
++ int argCount;
++ @Override
++ void loadStack() {
++ loadExpressionAsObject(node.getBase());
++ method.dup();
++ // NOTE: not using a nested OptimisticOperation on this dynamicGet, as we expect to get back
++ // a callable object. Nobody in their right mind would optimistically type this call site.
++ assert !node.isOptimistic();
++ method.dynamicGet(node.getType(), node.getProperty(), flags, true, node.isIndex());
++ method.swap();
++ argCount = loadArgs(args);
++ }
++ @Override
++ void consumeStack() {
++ dynamicCall(2 + argCount, flags);
++ }
++ }.emit();
+
+ return false;
+ }
+
+ @Override
+ public boolean enterFunctionNode(final FunctionNode origCallee) {
+- // NOTE: visiting the callee will leave a constructed ScriptFunction object on the stack if
+- // callee.needsCallee() == true
+- final FunctionNode callee = (FunctionNode)origCallee.accept(CodeGenerator.this);
+-
+- final boolean isVarArg = callee.isVarArg();
+- final int argCount = isVarArg ? -1 : callee.getParameters().size();
+-
+- final String signature = new FunctionSignature(true, callee.needsCallee(), callee.getReturnType(), isVarArg ? null : callee.getParameters()).toString();
+-
+- if (callee.isStrict()) { // self is undefined
+- method.loadUndefined(Type.OBJECT);
+- } else { // get global from scope (which is the self)
+- globalInstance();
+- }
+- loadArgs(args, signature, isVarArg, argCount);
+- assert callee.getCompileUnit() != null : "no compile unit for " + callee.getName() + " " + Debug.id(callee) + " " + callNode;
+- method.invokestatic(callee.getCompileUnit().getUnitClassName(), callee.getName(), signature);
+- assert method.peekType().equals(callee.getReturnType()) : method.peekType() + " != " + callee.getReturnType();
+- method.convert(callNodeType);
++ new OptimisticOperation(callNode, resultBounds) {
++ FunctionNode callee;
++ int argsCount;
++ @Override
++ void loadStack() {
++ callee = (FunctionNode)origCallee.accept(CodeGenerator.this);
++ if (callee.isStrict()) { // "this" is undefined
++ method.loadUndefined(Type.OBJECT);
++ } else { // get global from scope (which is the self)
++ globalInstance();
++ }
++ argsCount = loadArgs(args);
++ }
++
++ @Override
++ void consumeStack() {
++ final int flags = getCallSiteFlags();
++ //assert callNodeType.equals(callee.getReturnType()) : callNodeType + " != " + callee.getReturnType();
++ dynamicCall(2 + argsCount, flags);
++ }
++ }.emit();
+ return false;
+ }
+
+ @Override
+ public boolean enterIndexNode(final IndexNode node) {
+- load(node.getBase(), Type.OBJECT);
+- method.dup();
+- final Type indexType = node.getIndex().getType();
+- if (indexType.isObject() || indexType.isBoolean()) {
+- load(node.getIndex(), Type.OBJECT); //TODO
+- } else {
+- load(node.getIndex());
+- }
+- method.dynamicGetIndex(node.getType(), getCallSiteFlags(), true);
+- method.swap();
+- method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags());
+-
++ new OptimisticOperation(callNode, resultBounds) {
++ int argsCount;
++ @Override
++ void loadStack() {
++ loadExpressionAsObject(node.getBase());
++ method.dup();
++ final Type indexType = node.getIndex().getType();
++ if (indexType.isObject() || indexType.isBoolean()) {
++ loadExpressionAsObject(node.getIndex()); //TODO boolean
++ } else {
++ loadExpressionUnbounded(node.getIndex());
++ }
++ // NOTE: not using a nested OptimisticOperation on this dynamicGetIndex, as we expect to get
++ // back a callable object. Nobody in their right mind would optimistically type this call site.
++ assert !node.isOptimistic();
++ method.dynamicGetIndex(node.getType(), getCallSiteFlags(), true);
++ method.swap();
++ argsCount = loadArgs(args);
++ }
++ @Override
++ void consumeStack() {
++ final int flags = getCallSiteFlags();
++ dynamicCall(2 + argsCount, flags);
++ }
++ }.emit();
+ return false;
+ }
+
+ @Override
+ protected boolean enterDefault(final Node node) {
+- // Load up function.
+- load(function, Type.OBJECT); //TODO, e.g. booleans can be used as functions
+- method.loadUndefined(Type.OBJECT); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
+- method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags() | CALLSITE_SCOPE);
+-
++ new OptimisticOperation(callNode, resultBounds) {
++ int argsCount;
++ @Override
++ void loadStack() {
++ // Load up function.
++ loadExpressionAsObject(function); //TODO, e.g. booleans can be used as functions
++ method.loadUndefined(Type.OBJECT); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
++ argsCount = loadArgs(args);
++ }
++ @Override
++ void consumeStack() {
++ final int flags = getCallSiteFlags() | CALLSITE_SCOPE;
++ dynamicCall(2 + argsCount, flags);
++ }
++ }.emit();
+ return false;
+ }
+ });
+
+- method.store(callNode.getSymbol());
+-
+ return false;
+ }
+
++ /**
++ * Returns the flags with optimistic flag and program point removed.
++ * @param flags the flags that need optimism stripped from them.
++ * @return flags without optimism
++ */
++ static int nonOptimisticFlags(final int flags) {
++ return flags & ~(CALLSITE_OPTIMISTIC | -1 << CALLSITE_PROGRAM_POINT_SHIFT);
++ }
++
+ @Override
+ public boolean enterContinueNode(final ContinueNode continueNode) {
+- lineNumber(continueNode);
+-
+- final LoopNode continueTo = lc.getContinueTo(continueNode.getLabel());
+- for (int i = 0; i < lc.getScopeNestingLevelTo(continueTo); i++) {
+- closeWith();
+- }
+- method.splitAwareGoto(lc, continueTo.getContinueLabel());
++ return enterJumpStatement(continueNode);
++ }
++
++ @Override
++ public boolean enterEmptyNode(final EmptyNode emptyNode) {
++ if(!method.isReachable()) {
++ return false;
++ }
++ enterStatement(emptyNode);
+
+ return false;
+ }
+
+ @Override
+- public boolean enterEmptyNode(final EmptyNode emptyNode) {
+- lineNumber(emptyNode);
++ public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) {
++ if(!method.isReachable()) {
++ return false;
++ }
++ enterStatement(expressionStatement);
++
++ loadAndDiscard(expressionStatement.getExpression());
++ assert method.getStackSize() == 0;
+
+ return false;
+ }
+
+ @Override
+- public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) {
+- lineNumber(expressionStatement);
+-
+- expressionStatement.getExpression().accept(this);
++ public boolean enterBlockStatement(final BlockStatement blockStatement) {
++ if(!method.isReachable()) {
++ return false;
++ }
++ enterStatement(blockStatement);
++
++ blockStatement.getBlock().accept(this);
+
+ return false;
+ }
+
+ @Override
+- public boolean enterBlockStatement(final BlockStatement blockStatement) {
+- lineNumber(blockStatement);
+-
+- blockStatement.getBlock().accept(this);
+-
+- return false;
+- }
+-
+- @Override
+ public boolean enterForNode(final ForNode forNode) {
+- lineNumber(forNode);
+-
++ if(!method.isReachable()) {
++ return false;
++ }
++ enterStatement(forNode);
+ if (forNode.isForIn()) {
+ enterForIn(forNode);
+ } else {
+- enterFor(forNode);
++ final Expression init = forNode.getInit();
++ if (init != null) {
++ loadAndDiscard(init);
++ }
++ enterForOrWhile(forNode, forNode.getModify());
+ }
+
+ return false;
+ }
+
+- private void enterFor(final ForNode forNode) {
+- final Expression init = forNode.getInit();
+- final Expression test = forNode.getTest();
+- final Block body = forNode.getBody();
+- final Expression modify = forNode.getModify();
+-
+- if (init != null) {
+- init.accept(this);
+- }
+-
+- final Label loopLabel = new Label("loop");
+- final Label testLabel = new Label("test");
+-
+- method._goto(testLabel);
+- method.label(loopLabel);
+- body.accept(this);
+- method.label(forNode.getContinueLabel());
+-
+- if (!body.isTerminal() && modify != null) {
+- load(modify);
+- }
+-
+- method.label(testLabel);
+- if (test != null) {
+- new BranchOptimizer(this, method).execute(test, loopLabel, true);
++ private void enterForIn(final ForNode forNode) {
++ loadExpression(forNode.getModify(), TypeBounds.OBJECT);
++ method.invoke(forNode.isForEach() ? ScriptRuntime.TO_VALUE_ITERATOR : ScriptRuntime.TO_PROPERTY_ITERATOR);
++ final Symbol iterSymbol = forNode.getIterator();
++ final int iterSlot = iterSymbol.getSlot(Type.OBJECT);
++ method.store(iterSymbol, ITERATOR_TYPE);
++
++ method.beforeJoinPoint(forNode);
++
++ final Label continueLabel = forNode.getContinueLabel();
++ final Label breakLabel = forNode.getBreakLabel();
++
++ method.label(continueLabel);
++ method.load(ITERATOR_TYPE, iterSlot);
++ method.invoke(interfaceCallNoLookup(ITERATOR_CLASS, "hasNext", boolean.class));
++ final JoinPredecessorExpression test = forNode.getTest();
++ final Block body = forNode.getBody();
++ if(LocalVariableConversion.hasLiveConversion(test)) {
++ final Label afterConversion = new Label("for_in_after_test_conv");
++ method.ifne(afterConversion);
++ method.beforeJoinPoint(test);
++ method._goto(breakLabel);
++ method.label(afterConversion);
+ } else {
+- method._goto(loopLabel);
+- }
+-
+- method.label(forNode.getBreakLabel());
+- }
+-
+- private void enterForIn(final ForNode forNode) {
+- final Block body = forNode.getBody();
+- final Expression modify = forNode.getModify();
+-
+- final Symbol iter = forNode.getIterator();
+- final Label loopLabel = new Label("loop");
+-
+- final Expression init = forNode.getInit();
+-
+- load(modify, Type.OBJECT);
+- method.invoke(forNode.isForEach() ? ScriptRuntime.TO_VALUE_ITERATOR : ScriptRuntime.TO_PROPERTY_ITERATOR);
+- method.store(iter);
+- method._goto(forNode.getContinueLabel());
+- method.label(loopLabel);
+-
+- new Store<Expression>(init) {
++ method.ifeq(breakLabel);
++ }
++
++ new Store<Expression>(forNode.getInit()) {
+ @Override
+ protected void storeNonDiscard() {
+- return;
+- }
++ // This expression is neither part of a discard, nor needs to be left on the stack after it was
++ // stored, so we override storeNonDiscard to be a no-op.
++ }
++
+ @Override
+ protected void evaluate() {
+- method.load(iter);
+- method.invoke(interfaceCallNoLookup(Iterator.class, "next", Object.class));
++ new OptimisticOperation((Optimistic)forNode.getInit(), TypeBounds.UNBOUNDED) {
++ @Override
++ void loadStack() {
++ method.load(ITERATOR_TYPE, iterSlot);
++ }
++
++ @Override
++ void consumeStack() {
++ method.invoke(interfaceCallNoLookup(ITERATOR_CLASS, "next", Object.class));
++ convertOptimisticReturnValue();
++ }
++ }.emit();
+ }
+ }.store();
+-
+ body.accept(this);
+
+- method.label(forNode.getContinueLabel());
+- method.load(iter);
+- method.invoke(interfaceCallNoLookup(Iterator.class, "hasNext", boolean.class));
+- method.ifne(loopLabel);
+- method.label(forNode.getBreakLabel());
++ if(method.isReachable()) {
++ method._goto(continueLabel);
++ }
++ method.label(breakLabel);
+ }
+
+ /**
+@@ -955,13 +1674,16 @@
+ * @param block block with local vars.
+ */
+ private void initLocals(final Block block) {
+- lc.nextFreeSlot(block);
++ lc.onEnterBlock(block);
+
+ final boolean isFunctionBody = lc.isFunctionBody();
+-
+ final FunctionNode function = lc.getCurrentFunction();
+ if (isFunctionBody) {
+- if(method.hasScope()) {
++ initializeMethodParameters(function);
++ if(!function.isVarArg()) {
++ expandParameterSlots(function);
++ }
++ if (method.hasScope()) {
+ if (function.needsParentScope()) {
+ method.loadCompilerConstant(CALLEE);
+ method.invoke(ScriptFunction.GET_SCOPE);
+@@ -988,76 +1710,173 @@
+
+ // TODO for LET we can do better: if *block* does not contain any eval/with, we don't need its vars in scope.
+
+- final List<String> nameList = new ArrayList<>();
+- final List<Symbol> locals = new ArrayList<>();
+-
+- // Initalize symbols and values
+- final List<Symbol> newSymbols = new ArrayList<>();
+- final List<Symbol> values = new ArrayList<>();
+-
+ final boolean hasArguments = function.needsArguments();
+-
++ final List<MapTuple<Symbol>> tuples = new ArrayList<>();
++ final Iterator<IdentNode> paramIter = function.getParameters().iterator();
+ for (final Symbol symbol : block.getSymbols()) {
+-
+- if (symbol.isInternal() || symbol.isThis() || symbol.isTemp()) {
++ if (symbol.isInternal() || symbol.isThis()) {
+ continue;
+ }
+
+ if (symbol.isVar()) {
++ assert !varsInScope || symbol.isScope();
+ if (varsInScope || symbol.isScope()) {
+- nameList.add(symbol.getName());
+- newSymbols.add(symbol);
+- values.add(null);
+ assert symbol.isScope() : "scope for " + symbol + " should have been set in Lower already " + function.getName();
+ assert !symbol.hasSlot() : "slot for " + symbol + " should have been removed in Lower already" + function.getName();
++
++ //this tuple will not be put fielded, as it has no value, just a symbol
++ tuples.add(new MapTuple<Symbol>(symbol.getName(), symbol, null));
+ } else {
+- assert symbol.hasSlot() : symbol + " should have a slot only, no scope";
+- locals.add(symbol);
++ assert symbol.hasSlot() || symbol.slotCount() == 0 : symbol + " should have a slot only, no scope";
+ }
+ } else if (symbol.isParam() && (varsInScope || hasArguments || symbol.isScope())) {
+- nameList.add(symbol.getName());
+- newSymbols.add(symbol);
+- values.add(hasArguments ? null : symbol);
+- assert symbol.isScope() : "scope for " + symbol + " should have been set in Lower already " + function.getName() + " varsInScope="+varsInScope+" hasArguments="+hasArguments+" symbol.isScope()=" + symbol.isScope();
++ assert symbol.isScope() : "scope for " + symbol + " should have been set in AssignSymbols already " + function.getName() + " varsInScope="+varsInScope+" hasArguments="+hasArguments+" symbol.isScope()=" + symbol.isScope();
+ assert !(hasArguments && symbol.hasSlot()) : "slot for " + symbol + " should have been removed in Lower already " + function.getName();
++
++ final Type paramType;
++ final Symbol paramSymbol;
++
++ if (hasArguments) {
++ assert !symbol.hasSlot() : "slot for " + symbol + " should have been removed in Lower already ";
++ paramSymbol = null;
++ paramType = null;
++ } else {
++ paramSymbol = symbol;
++ // NOTE: We're relying on the fact here that Block.symbols is a LinkedHashMap, hence it will
++ // return symbols in the order they were defined, and parameters are defined in the same order
++ // they appear in the function. That's why we can have a single pass over the parameter list
++ // with an iterator, always just scanning forward for the next parameter that matches the symbol
++ // name.
++ for(;;) {
++ final IdentNode nextParam = paramIter.next();
++ if(nextParam.getName().equals(symbol.getName())) {
++ paramType = nextParam.getType();
++ break;
++ }
++ }
++ }
++
++ tuples.add(new MapTuple<Symbol>(symbol.getName(), symbol, paramType, paramSymbol) {
++ //this symbol will be put fielded, we can't initialize it as undefined with a known type
++ @Override
++ public Class<?> getValueType() {
++ if (OBJECT_FIELDS_ONLY || value == null || paramType == null) {
++ return Object.class;
++ }
++ return paramType.isBoolean() ? Object.class : paramType.getTypeClass();
++ }
++ });
+ }
+ }
+
+- // we may have locals that need to be initialized
+- initSymbols(locals);
+-
+ /*
+ * Create a new object based on the symbols and values, generate
+ * bootstrap code for object
+ */
+- new FieldObjectCreator<Symbol>(this, nameList, newSymbols, values, true, hasArguments) {
++ new FieldObjectCreator<Symbol>(this, tuples, true, hasArguments) {
+ @Override
+- protected void loadValue(final Symbol value) {
+- method.load(value);
++ protected void loadValue(final Symbol value, final Type type) {
++ method.load(value, type);
+ }
+ }.makeObject(method);
+-
+- // runScript(): merge scope into global
++ // program function: merge scope into global
+ if (isFunctionBody && function.isProgram()) {
+ method.invoke(ScriptRuntime.MERGE_SCOPE);
+ }
+
+ method.storeCompilerConstant(SCOPE);
+- } else {
++ if(!isFunctionBody) {
++ // Function body doesn't need a try/catch to restore scope, as it'd be a dead store anyway. Allowing it
++ // actually causes issues with UnwarrantedOptimismException handlers as ASM will sort this handler to
++ // the top of the exception handler table, so it'll be triggered instead of the UOE handlers.
++ final Label scopeEntryLabel = new Label("scope_entry");
++ scopeEntryLabels.push(scopeEntryLabel);
++ method.label(scopeEntryLabel);
++ }
++ } else if (isFunctionBody && function.isVarArg()) {
+ // Since we don't have a scope, parameters didn't get assigned array indices by the FieldObjectCreator, so
+ // we need to assign them separately here.
+ int nextParam = 0;
+- if (isFunctionBody && function.isVarArg()) {
+- for (final IdentNode param : function.getParameters()) {
+- param.getSymbol().setFieldIndex(nextParam++);
++ for (final IdentNode param : function.getParameters()) {
++ param.getSymbol().setFieldIndex(nextParam++);
++ }
++ }
++
++ // Debugging: print symbols? @see --print-symbols flag
++ printSymbols(block, function, (isFunctionBody ? "Function " : "Block in ") + (function.getIdent() == null ? "<anonymous>" : function.getIdent().getName()));
++ }
++
++ /**
++ * Incoming method parameters are always declared on method entry; declare them in the local variable table.
++ * @param function function for which code is being generated.
++ */
++ private void initializeMethodParameters(final FunctionNode function) {
++ final Label functionStart = new Label("fn_start");
++ method.label(functionStart);
++ int nextSlot = 0;
++ if(function.needsCallee()) {
++ initializeInternalFunctionParameter(CALLEE, function, functionStart, nextSlot++);
++ }
++ initializeInternalFunctionParameter(THIS, function, functionStart, nextSlot++);
++ if(function.isVarArg()) {
++ initializeInternalFunctionParameter(VARARGS, function, functionStart, nextSlot++);
++ } else {
++ for(final IdentNode param: function.getParameters()) {
++ final Symbol symbol = param.getSymbol();
++ if(symbol.isBytecodeLocal()) {
++ method.initializeMethodParameter(symbol, param.getType(), functionStart);
+ }
+ }
+-
+- initSymbols(block.getSymbols());
+- }
+-
+- // Debugging: print symbols? @see --print-symbols flag
+- printSymbols(block, (isFunctionBody ? "Function " : "Block in ") + (function.getIdent() == null ? "<anonymous>" : function.getIdent().getName()));
++ }
++ }
++
++ private void initializeInternalFunctionParameter(final CompilerConstants cc, final FunctionNode fn, final Label functionStart, final int slot) {
++ final Symbol symbol = initializeInternalFunctionOrSplitParameter(cc, fn, functionStart, slot);
++ // Internal function params (:callee, this, and :varargs) are never expanded to multiple slots
++ assert symbol.getFirstSlot() == slot;
++ }
++
++ private Symbol initializeInternalFunctionOrSplitParameter(final CompilerConstants cc, final FunctionNode fn, final Label functionStart, final int slot) {
++ final Symbol symbol = fn.getBody().getExistingSymbol(cc.symbolName());
++ final Type type = Type.typeFor(cc.type());
++ method.initializeMethodParameter(symbol, type, functionStart);
++ method.onLocalStore(type, slot);
++ return symbol;
++ }
++
++ /**
++ * Parameters come into the method packed into local variable slots next to each other. Nashorn on the other hand
++ * can use 1-6 slots for a local variable depending on all the types it needs to store. When this method is invoked,
++ * the symbols are already allocated such wider slots, but the values are still in tightly packed incoming slots,
++ * and we need to spread them into their new locations.
++ * @param function the function for which parameter-spreading code needs to be emitted
++ */
++ private void expandParameterSlots(final FunctionNode function) {
++ final List<IdentNode> parameters = function.getParameters();
++ // Calculate the total number of incoming parameter slots
++ int currentIncomingSlot = function.needsCallee() ? 2 : 1;
++ for(final IdentNode parameter: parameters) {
++ currentIncomingSlot += parameter.getType().getSlots();
++ }
++ // Starting from last parameter going backwards, move the parameter values into their new slots.
++ for(int i = parameters.size(); i-- > 0;) {
++ final IdentNode parameter = parameters.get(i);
++ final Type parameterType = parameter.getType();
++ final int typeWidth = parameterType.getSlots();
++ currentIncomingSlot -= typeWidth;
++ final Symbol symbol = parameter.getSymbol();
++ final int slotCount = symbol.slotCount();
++ assert slotCount > 0;
++ // Scoped parameters must not hold more than one value
++ assert symbol.isBytecodeLocal() || slotCount == typeWidth;
++
++ // Mark it as having its value stored into it by the method invocation.
++ method.onLocalStore(parameterType, currentIncomingSlot);
++ if(currentIncomingSlot != symbol.getSlot(parameterType)) {
++ method.load(parameterType, currentIncomingSlot);
++ method.store(symbol, parameterType);
++ }
++ }
+ }
+
+ private void initArguments(final FunctionNode function) {
+@@ -1075,15 +1894,45 @@
+ method.storeCompilerConstant(ARGUMENTS);
+ }
+
++ private boolean skipFunction(final FunctionNode functionNode) {
++ final ScriptEnvironment env = compiler.getScriptEnvironment();
++ final boolean lazy = env._lazy_compilation;
++ final boolean onDemand = compiler.isOnDemandCompilation();
++
++ // If this is on-demand or lazy compilation, don't compile a nested (not topmost) function.
++ if((onDemand || lazy) && lc.getOutermostFunction() != functionNode) {
++ return true;
++ }
++
++ // If lazy compiling with optimistic types, don't compile the program eagerly either. It will soon be
++ // invalidated anyway. In presence of a class cache, this further means that an obsoleted program version
++ // lingers around. Also, currently loading previously persisted optimistic types information only works if
++ // we're on-demand compiling a function, so with this strategy the :program method can also have the warmup
++ // benefit of using previously persisted types.
++ //
++ // NOTE that this means the first compiled class will effectively just have a :createProgramFunction method, and
++ // the RecompilableScriptFunctionData (RSFD) object in its constants array. It won't even have the :program
++ // method. This is by design. It does mean that we're wasting one compiler execution (and we could minimize this
++ // by just running it up to scope depth calculation, which creates the RSFDs and then this limited codegen).
++ // We could emit an initial separate compile unit with the initial version of :program in it to better utilize
++ // the compilation pipeline, but that would need more invasive changes, as currently the assumption that
++ // :program is emitted into the first compilation unit of the function lives in many places.
++ return !onDemand && lazy && env._optimistic_types && functionNode.isProgram();
++ }
++
+ @Override
+ public boolean enterFunctionNode(final FunctionNode functionNode) {
+- if (functionNode.isLazy()) {
+- // Must do it now; can't postpone it until leaveFunctionNode()
+- newFunctionObject(functionNode, functionNode);
++ final int fnId = functionNode.getId();
++
++ if (skipFunction(functionNode)) {
++ // In case we are not generating code for the function, we must create or retrieve the function object and
++ // load it on the stack here.
++ newFunctionObject(functionNode, false);
+ return false;
+ }
+
+ final String fnName = functionNode.getName();
++
+ // NOTE: we only emit the method for a function with the given name once. We can have multiple functions with
+ // the same name as a result of inlining finally blocks. However, in the future -- with type specialization,
+ // notably -- we might need to check for both name *and* signature. Of course, even that might not be
+@@ -1092,35 +1941,67 @@
+ // to decide to either generate a unique method for each inlined copy of the function, maybe figure out its
+ // exact type closure and deduplicate based on that, or just decide that functions in finally blocks aren't
+ // worth it, and generate one method with most generic type closure.
+- if(!emittedMethods.contains(fnName)) {
+- LOG.info("=== BEGIN ", fnName);
++ if (!emittedMethods.contains(fnName)) {
++ log.info("=== BEGIN ", fnName);
+
+ assert functionNode.getCompileUnit() != null : "no compile unit for " + fnName + " " + Debug.id(functionNode);
+ unit = lc.pushCompileUnit(functionNode.getCompileUnit());
+ assert lc.hasCompileUnits();
+
+- method = lc.pushMethodEmitter(unit.getClassEmitter().method(functionNode));
++ final ClassEmitter classEmitter = unit.getClassEmitter();
++ pushMethodEmitter(isRestOf() ? classEmitter.restOfMethod(functionNode) : classEmitter.method(functionNode));
++ method.setPreventUndefinedLoad();
++ if(useOptimisticTypes()) {
++ lc.pushUnwarrantedOptimismHandlers();
++ }
++
+ // new method - reset last line number
+ lastLineNumber = -1;
+- // Mark end for variable tables.
++
+ method.begin();
++
++ if (isRestOf()) {
++ final ContinuationInfo ci = new ContinuationInfo();
++ fnIdToContinuationInfo.put(fnId, ci);
++ method.gotoLoopStart(ci.getHandlerLabel());
++ }
+ }
+
+ return true;
+ }
+
++ private void pushMethodEmitter(final MethodEmitter newMethod) {
++ method = lc.pushMethodEmitter(newMethod);
++ catchLabels.push(METHOD_BOUNDARY);
++ }
++
++ private void popMethodEmitter() {
++ method = lc.popMethodEmitter(method);
++ assert catchLabels.peek() == METHOD_BOUNDARY;
++ catchLabels.pop();
++ }
++
+ @Override
+ public Node leaveFunctionNode(final FunctionNode functionNode) {
+ try {
+- if(emittedMethods.add(functionNode.getName())) {
++ final boolean markOptimistic;
++ if (emittedMethods.add(functionNode.getName())) {
++ markOptimistic = generateUnwarrantedOptimismExceptionHandlers(functionNode);
++ generateContinuationHandler();
+ method.end(); // wrap up this method
+ unit = lc.popCompileUnit(functionNode.getCompileUnit());
+- method = lc.popMethodEmitter(method);
+- LOG.info("=== END ", functionNode.getName());
+- }
+-
+- final FunctionNode newFunctionNode = functionNode.setState(lc, CompilationState.EMITTED);
+- newFunctionObject(newFunctionNode, functionNode);
++ popMethodEmitter();
++ log.info("=== END ", functionNode.getName());
++ } else {
++ markOptimistic = false;
++ }
++
++ FunctionNode newFunctionNode = functionNode.setState(lc, CompilationState.BYTECODE_GENERATED);
++ if (markOptimistic) {
++ newFunctionNode = newFunctionNode.setFlag(lc, FunctionNode.IS_DEOPTIMIZABLE);
++ }
++
++ newFunctionObject(newFunctionNode, true);
+ return newFunctionNode;
+ } catch (final Throwable t) {
+ Context.printStackTrace(t);
+@@ -1131,62 +2012,75 @@
+ }
+
+ @Override
+- public boolean enterIdentNode(final IdentNode identNode) {
+- return false;
+- }
+-
+- @Override
+ public boolean enterIfNode(final IfNode ifNode) {
+- lineNumber(ifNode);
++ if(!method.isReachable()) {
++ return false;
++ }
++ enterStatement(ifNode);
+
+ final Expression test = ifNode.getTest();
+ final Block pass = ifNode.getPass();
+ final Block fail = ifNode.getFail();
+
++ if (Expression.isAlwaysTrue(test)) {
++ loadAndDiscard(test);
++ pass.accept(this);
++ return false;
++ } else if (Expression.isAlwaysFalse(test)) {
++ loadAndDiscard(test);
++ if (fail != null) {
++ fail.accept(this);
++ }
++ return false;
++ }
++
++ final boolean hasFailConversion = LocalVariableConversion.hasLiveConversion(ifNode);
++
+ final Label failLabel = new Label("if_fail");
+- final Label afterLabel = fail == null ? failLabel : new Label("if_done");
+-
+- new BranchOptimizer(this, method).execute(test, failLabel, false);
+-
+- boolean passTerminal = false;
+- boolean failTerminal = false;
++ final Label afterLabel = (fail == null && !hasFailConversion) ? null : new Label("if_done");
++
++ emitBranch(test, failLabel, false);
+
+ pass.accept(this);
+- if (!pass.hasTerminalFlags()) {
++ if(method.isReachable() && afterLabel != null) {
+ method._goto(afterLabel); //don't fallthru to fail block
+- } else {
+- passTerminal = pass.isTerminal();
+- }
++ }
++ method.label(failLabel);
+
+ if (fail != null) {
+- method.label(failLabel);
+ fail.accept(this);
+- failTerminal = fail.isTerminal();
+- }
+-
+- //if if terminates, put the after label there
+- if (!passTerminal || !failTerminal) {
++ } else if(hasFailConversion) {
++ method.beforeJoinPoint(ifNode);
++ }
++
++ if(afterLabel != null && afterLabel.isReachable()) {
+ method.label(afterLabel);
+ }
+
+ return false;
+ }
+
+- @Override
+- public boolean enterIndexNode(final IndexNode indexNode) {
+- load(indexNode);
+- return false;
++ private void emitBranch(final Expression test, final Label label, final boolean jumpWhenTrue) {
++ new BranchOptimizer(this, method).execute(test, label, jumpWhenTrue);
++ }
++
++ private void enterStatement(final Statement statement) {
++ lineNumber(statement);
+ }
+
+ private void lineNumber(final Statement statement) {
+ lineNumber(statement.getLineNumber());
+ }
+
+- private void lineNumber(int lineNumber) {
+- if (lineNumber != lastLineNumber) {
++ private void lineNumber(final int lineNumber) {
++ if (lineNumber != lastLineNumber && lineNumber != Node.NO_LINE_NUMBER) {
+ method.lineNumber(lineNumber);
+- }
+- lastLineNumber = lineNumber;
++ lastLineNumber = lineNumber;
++ }
++ }
++
++ int getLastLineNumber() {
++ return lastLineNumber;
+ }
+
+ /**
+@@ -1219,26 +2113,35 @@
+ unit = lc.pushCompileUnit(arrayUnit.getCompileUnit());
+
+ final String className = unit.getUnitClassName();
++ assert unit != null;
+ final String name = currentFunction.uniqueName(SPLIT_PREFIX.symbolName());
+ final String signature = methodDescriptor(type, ScriptFunction.class, Object.class, ScriptObject.class, type);
+
+- final MethodEmitter me = unit.getClassEmitter().method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), name, signature);
+- method = lc.pushMethodEmitter(me);
++ pushMethodEmitter(unit.getClassEmitter().method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), name, signature));
+
+ method.setFunctionNode(currentFunction);
+ method.begin();
+
+- fixScopeSlot(currentFunction);
+-
+- method.load(arrayType, SPLIT_ARRAY_ARG.slot());
++ defineCommonSplitMethodParameters();
++ defineSplitMethodParameter(CompilerConstants.SPLIT_ARRAY_ARG.slot(), arrayType);
++
++ // NOTE: when this is no longer needed, SplitIntoFunctions will no longer have to add IS_SPLIT
++ // to synthetic functions, and FunctionNode.needsCallee() will no longer need to test for isSplit().
++ final int arraySlot = fixScopeSlot(currentFunction, 3);
++
++ lc.enterSplitNode();
+
+ for (int i = arrayUnit.getLo(); i < arrayUnit.getHi(); i++) {
++ method.load(arrayType, arraySlot);
+ storeElement(nodes, elementType, postsets[i]);
+ }
+
++ method.load(arrayType, arraySlot);
+ method._return();
++ lc.exitSplitNode();
+ method.end();
+- method = lc.popMethodEmitter(me);
++ lc.releaseSlots();
++ popMethodEmitter();
+
+ assert method == savedMethod;
+ method.loadCompilerConstant(CALLEE);
+@@ -1255,15 +2158,19 @@
+ return method;
+ }
+
+- for (final int postset : postsets) {
+- storeElement(nodes, elementType, postset);
+- }
+-
++ if(postsets.length > 0) {
++ final int arraySlot = method.getUsedSlotsWithLiveTemporaries();
++ method.storeTemp(arrayType, arraySlot);
++ for (final int postset : postsets) {
++ method.load(arrayType, arraySlot);
++ storeElement(nodes, elementType, postset);
++ }
++ method.load(arrayType, arraySlot);
++ }
+ return method;
+ }
+
+ private void storeElement(final Expression[] nodes, final Type elementType, final int index) {
+- method.dup();
+ method.load(index);
+
+ final Expression element = nodes[index];
+@@ -1271,7 +2178,7 @@
+ if (element == null) {
+ method.loadEmpty(elementType);
+ } else {
+- load(element, elementType);
++ loadExpressionAsType(element, elementType);
+ }
+
+ method.arraystore();
+@@ -1284,7 +2191,7 @@
+ for (int i = 0; i < args.size(); i++) {
+ method.dup();
+ method.load(i);
+- load(args.get(i), Type.OBJECT); //has to be upcast to object or we fail
++ loadExpression(args.get(i), TypeBounds.OBJECT); // variable arity methods always take objects
+ method.arraystore();
+ }
+
+@@ -1314,44 +2221,48 @@
+ * @param object object to load
+ */
+ void loadConstant(final Object object) {
+- final String unitClassName = unit.getUnitClassName();
+- final ClassEmitter classEmitter = unit.getClassEmitter();
++ loadConstant(object, unit, method);
++ }
++
++ private void loadConstant(final Object object, final CompileUnit compileUnit, final MethodEmitter methodEmitter) {
++ final String unitClassName = compileUnit.getUnitClassName();
++ final ClassEmitter classEmitter = compileUnit.getClassEmitter();
+ final int index = compiler.getConstantData().add(object);
+ final Class<?> cls = object.getClass();
+
+ if (cls == PropertyMap.class) {
+- method.load(index);
+- method.invokestatic(unitClassName, GET_MAP.symbolName(), methodDescriptor(PropertyMap.class, int.class));
++ methodEmitter.load(index);
++ methodEmitter.invokestatic(unitClassName, GET_MAP.symbolName(), methodDescriptor(PropertyMap.class, int.class));
+ classEmitter.needGetConstantMethod(PropertyMap.class);
+ } else if (cls.isArray()) {
+- method.load(index);
++ methodEmitter.load(index);
+ final String methodName = ClassEmitter.getArrayMethodName(cls);
+- method.invokestatic(unitClassName, methodName, methodDescriptor(cls, int.class));
++ methodEmitter.invokestatic(unitClassName, methodName, methodDescriptor(cls, int.class));
+ classEmitter.needGetConstantMethod(cls);
+ } else {
+- method.loadConstants().load(index).arrayload();
++ methodEmitter.loadConstants().load(index).arrayload();
+ if (object instanceof ArrayData) {
+ // avoid cast to non-public ArrayData subclass
+- method.checkcast(ArrayData.class);
+- method.invoke(virtualCallNoLookup(ArrayData.class, "copy", ArrayData.class));
++ methodEmitter.checkcast(ArrayData.class);
++ methodEmitter.invoke(virtualCallNoLookup(ArrayData.class, "copy", ArrayData.class));
+ } else if (cls != Object.class) {
+- method.checkcast(cls);
++ methodEmitter.checkcast(cls);
+ }
+ }
+ }
+
+ // literal values
+- private MethodEmitter loadLiteral(final LiteralNode<?> node, final Type type) {
++ private void loadLiteral(final LiteralNode<?> node, final TypeBounds resultBounds) {
+ final Object value = node.getValue();
+
+ if (value == null) {
+ method.loadNull();
+ } else if (value instanceof Undefined) {
+- method.loadUndefined(Type.OBJECT);
++ method.loadUndefined(resultBounds.within(Type.OBJECT));
+ } else if (value instanceof String) {
+ final String string = (String)value;
+
+- if (string.length() > (MethodEmitter.LARGE_STRING_THRESHOLD / 3)) { // 3 == max bytes per encoded char
++ if (string.length() > MethodEmitter.LARGE_STRING_THRESHOLD / 3) { // 3 == max bytes per encoded char
+ loadConstant(string);
+ } else {
+ method.load(string);
+@@ -1361,31 +2272,40 @@
+ } else if (value instanceof Boolean) {
+ method.load((Boolean)value);
+ } else if (value instanceof Integer) {
+- if(type.isEquivalentTo(Type.NUMBER)) {
++ if(!resultBounds.canBeNarrowerThan(Type.OBJECT)) {
++ method.load((Integer)value);
++ method.convert(Type.OBJECT);
++ } else if(!resultBounds.canBeNarrowerThan(Type.NUMBER)) {
+ method.load(((Integer)value).doubleValue());
+- } else if(type.isEquivalentTo(Type.LONG)) {
++ } else if(!resultBounds.canBeNarrowerThan(Type.LONG)) {
+ method.load(((Integer)value).longValue());
+ } else {
+ method.load((Integer)value);
+ }
+ } else if (value instanceof Long) {
+- if(type.isEquivalentTo(Type.NUMBER)) {
++ if(!resultBounds.canBeNarrowerThan(Type.OBJECT)) {
++ method.load((Long)value);
++ method.convert(Type.OBJECT);
++ } else if(!resultBounds.canBeNarrowerThan(Type.NUMBER)) {
+ method.load(((Long)value).doubleValue());
+ } else {
+ method.load((Long)value);
+ }
+ } else if (value instanceof Double) {
+- method.load((Double)value);
++ if(!resultBounds.canBeNarrowerThan(Type.OBJECT)) {
++ method.load((Double)value);
++ method.convert(Type.OBJECT);
++ } else {
++ method.load((Double)value);
++ }
+ } else if (node instanceof ArrayLiteralNode) {
+ final ArrayLiteralNode arrayLiteral = (ArrayLiteralNode)node;
+ final ArrayType atype = arrayLiteral.getArrayType();
+ loadArray(arrayLiteral, atype);
+ globalAllocateArray(atype);
+ } else {
+- assert false : "Unknown literal for " + node.getClass() + " " + value.getClass() + " " + value;
+- }
+-
+- return method;
++ throw new UnsupportedOperationException("Unknown literal for " + node.getClass() + " " + value.getClass() + " " + value);
++ }
+ }
+
+ private MethodEmitter loadRegexToken(final RegexToken value) {
+@@ -1422,35 +2342,65 @@
+ return method;
+ }
+
+- @Override
+- public boolean enterLiteralNode(final LiteralNode<?> literalNode) {
+- return enterLiteralNode(literalNode, literalNode.getType());
++ /**
++ * Check if a property value contains a particular program point
++ * @param value value
++ * @param pp program point
++ * @return true if it's there.
++ */
++ private static boolean propertyValueContains(final Expression value, final int pp) {
++ return new Supplier<Boolean>() {
++ boolean contains;
++
++ @Override
++ public Boolean get() {
++ value.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
++ @Override
++ public boolean enterFunctionNode(final FunctionNode functionNode) {
++ return false;
++ }
++
++ @Override
++ public boolean enterObjectNode(final ObjectNode objectNode) {
++ return false;
++ }
++
++ @Override
++ public boolean enterDefault(final Node node) {
++ if (contains) {
++ return false;
++ }
++ if (node instanceof Optimistic && ((Optimistic)node).getProgramPoint() == pp) {
++ contains = true;
++ return false;
++ }
++ return true;
++ }
++ });
++
++ return contains;
++ }
++ }.get();
+ }
+
+- private boolean enterLiteralNode(final LiteralNode<?> literalNode, final Type type) {
+- assert literalNode.getSymbol() != null : literalNode + " has no symbol";
+- loadLiteral(literalNode, type).convert(type).store(literalNode.getSymbol());
+- return false;
+- }
+-
+- @Override
+- public boolean enterObjectNode(final ObjectNode objectNode) {
++ private void loadObjectNode(final ObjectNode objectNode) {
+ final List<PropertyNode> elements = objectNode.getElements();
+
+- final List<String> keys = new ArrayList<>();
+- final List<Symbol> symbols = new ArrayList<>();
+- final List<Expression> values = new ArrayList<>();
+-
+- boolean hasGettersSetters = false;
++ final List<MapTuple<Expression>> tuples = new ArrayList<>();
++ final List<PropertyNode> gettersSetters = new ArrayList<>();
++ final int ccp = getCurrentContinuationEntryPoint();
++
+ Expression protoNode = null;
+-
+- for (PropertyNode propertyNode: elements) {
+- final Expression value = propertyNode.getValue();
+- final String key = propertyNode.getKeyName();
+- final Symbol symbol = value == null ? null : propertyNode.getKey().getSymbol();
++ boolean restOfProperty = false;
++
++ for (final PropertyNode propertyNode : elements) {
++ final Expression value = propertyNode.getValue();
++ final String key = propertyNode.getKeyName();
++ // Just use a pseudo-symbol. We just need something non null; use the name and zero flags.
++ final Symbol symbol = value == null ? null : new Symbol(key, 0);
+
+ if (value == null) {
+- hasGettersSetters = true;
++ gettersSetters.add(propertyNode);
+ } else if (propertyNode.getKey() instanceof IdentNode &&
+ key.equals(ScriptObject.PROTO_PROPERTY_NAME)) {
+ // ES6 draft compliant __proto__ inside object literal
+@@ -1459,111 +2409,178 @@
+ continue;
+ }
+
+- keys.add(key);
+- symbols.add(symbol);
+- values.add(value);
+- }
+-
++ restOfProperty |=
++ value != null &&
++ isValid(ccp) &&
++ propertyValueContains(value, ccp);
++
++ //for literals, a value of null means object type, i.e. the value null or getter setter function
++ //(I think)
++ final Class<?> valueType = (OBJECT_FIELDS_ONLY || value == null || value.getType().isBoolean()) ? Object.class : value.getType().getTypeClass();
++ tuples.add(new MapTuple<Expression>(key, symbol, Type.typeFor(valueType), value) {
++ @Override
++ public Class<?> getValueType() {
++ return type.getTypeClass();
++ }
++ });
++ }
++
++ final ObjectCreator<?> oc;
+ if (elements.size() > OBJECT_SPILL_THRESHOLD) {
+- new SpillObjectCreator(this, keys, symbols, values).makeObject(method);
++ oc = new SpillObjectCreator(this, tuples);
+ } else {
+- new FieldObjectCreator<Expression>(this, keys, symbols, values) {
++ oc = new FieldObjectCreator<Expression>(this, tuples) {
+ @Override
+- protected void loadValue(final Expression node) {
+- load(node);
+- }
+-
+- /**
+- * Ensure that the properties start out as object types so that
+- * we can do putfield initializations instead of dynamicSetIndex
+- * which would be the case to determine initial property type
+- * otherwise.
+- *
+- * Use case, it's very expensive to do a million var x = {a:obj, b:obj}
+- * just to have to invalidate them immediately on initialization
+- *
+- * see NASHORN-594
+- */
+- @Override
+- protected MapCreator newMapCreator(final Class<?> fieldObjectClass) {
+- return new MapCreator(fieldObjectClass, keys, symbols) {
+- @Override
+- protected int getPropertyFlags(final Symbol symbol, final boolean hasArguments) {
+- return super.getPropertyFlags(symbol, hasArguments) | Property.IS_ALWAYS_OBJECT;
+- }
+- };
+- }
+-
+- }.makeObject(method);
++ protected void loadValue(final Expression node, final Type type) {
++ loadExpressionAsType(node, type);
++ }};
++ }
++ oc.makeObject(method);
++
++ //if this is a rest of method and our continuation point was found as one of the values
++ //in the properties above, we need to reset the map to oc.getMap() in the continuation
++ //handler
++ if (restOfProperty) {
++ final ContinuationInfo ci = getContinuationInfo();
++ // Can be set at most once for a single rest-of method
++ assert ci.getObjectLiteralMap() == null;
++ ci.setObjectLiteralMap(oc.getMap());
++ ci.setObjectLiteralStackDepth(method.getStackSize());
+ }
+
+ method.dup();
+ if (protoNode != null) {
+- load(protoNode);
++ loadExpressionAsObject(protoNode);
+ // take care of { __proto__: 34 } or some such!
+ method.convert(Type.OBJECT);
+ method.invoke(ScriptObject.SET_PROTO_FROM_LITERAL);
+ } else {
+- globalObjectPrototype();
+- method.invoke(ScriptObject.SET_PROTO);
+- }
+-
+- if (hasGettersSetters) {
+- for (final PropertyNode propertyNode : elements) {
+- final FunctionNode getter = propertyNode.getGetter();
+- final FunctionNode setter = propertyNode.getSetter();
+-
+- if (getter == null && setter == null) {
+- continue;
+- }
+-
+- method.dup().loadKey(propertyNode.getKey());
+-
+- if (getter == null) {
+- method.loadNull();
+- } else {
+- getter.accept(this);
+- }
+-
+- if (setter == null) {
+- method.loadNull();
+- } else {
+- setter.accept(this);
+- }
+-
+- method.invoke(ScriptObject.SET_USER_ACCESSORS);
+- }
+- }
+-
+- method.store(objectNode.getSymbol());
++ method.invoke(ScriptObject.SET_GLOBAL_OBJECT_PROTO);
++ }
++
++ for (final PropertyNode propertyNode : gettersSetters) {
++ final FunctionNode getter = propertyNode.getGetter();
++ final FunctionNode setter = propertyNode.getSetter();
++
++ assert getter != null || setter != null;
++
++ method.dup().loadKey(propertyNode.getKey());
++ if (getter == null) {
++ method.loadNull();
++ } else {
++ getter.accept(this);
++ }
++
++ if (setter == null) {
++ method.loadNull();
++ } else {
++ setter.accept(this);
++ }
++
++ method.invoke(ScriptObject.SET_USER_ACCESSORS);
++ }
++ }
++
++ @Override
++ public boolean enterReturnNode(final ReturnNode returnNode) {
++ if(!method.isReachable()) {
++ return false;
++ }
++ enterStatement(returnNode);
++
++ method.registerReturn();
++
++ final Type returnType = lc.getCurrentFunction().getReturnType();
++
++ final Expression expression = returnNode.getExpression();
++ if (expression != null) {
++ loadExpressionUnbounded(expression);
++ } else {
++ method.loadUndefined(returnType);
++ }
++
++ method._return(returnType);
++
+ return false;
+ }
+
+- @Override
+- public boolean enterReturnNode(final ReturnNode returnNode) {
+- lineNumber(returnNode);
+-
+- method.registerReturn();
+-
+- final Type returnType = lc.getCurrentFunction().getReturnType();
+-
+- final Expression expression = returnNode.getExpression();
+- if (expression != null) {
+- load(expression);
++ private boolean undefinedCheck(final RuntimeNode runtimeNode, final List<Expression> args) {
++ final Request request = runtimeNode.getRequest();
++
++ if (!Request.isUndefinedCheck(request)) {
++ return false;
++ }
++
++ final Expression lhs = args.get(0);
++ final Expression rhs = args.get(1);
++
++ final Symbol lhsSymbol = lhs instanceof IdentNode ? ((IdentNode)lhs).getSymbol() : null;
++ final Symbol rhsSymbol = rhs instanceof IdentNode ? ((IdentNode)rhs).getSymbol() : null;
++ // One must be a "undefined" identifier, otherwise we can't get here
++ assert lhsSymbol != null || rhsSymbol != null;
++
++ final Symbol undefinedSymbol;
++ if (isUndefinedSymbol(lhsSymbol)) {
++ undefinedSymbol = lhsSymbol;
+ } else {
+- method.loadUndefined(returnType);
+- }
+-
+- method._return(returnType);
+-
+- return false;
++ assert isUndefinedSymbol(rhsSymbol);
++ undefinedSymbol = rhsSymbol;
++ }
++
++ assert undefinedSymbol != null; //remove warning
++ if (!undefinedSymbol.isScope()) {
++ return false; //disallow undefined as local var or parameter
++ }
++
++ if (lhsSymbol == undefinedSymbol && lhs.getType().isPrimitive()) {
++ //we load the undefined first. never mind, because this will deoptimize anyway
++ return false;
++ }
++
++ if(isDeoptimizedExpression(lhs)) {
++ // This is actually related to "lhs.getType().isPrimitive()" above: any expression being deoptimized in
++ // the current chain of rest-of compilations used to have a type narrower than Object (so it was primitive).
++ // We must not perform undefined check specialization for them, as then we'd violate the basic rule of
++ // "Thou shalt not alter the stack shape between a deoptimized method and any of its (transitive) rest-ofs."
++ return false;
++ }
++
++ //make sure that undefined has not been overridden or scoped as a local var
++ //between us and global
++ if (!compiler.isGlobalSymbol(lc.getCurrentFunction(), "undefined")) {
++ return false;
++ }
++
++ final boolean isUndefinedCheck = request == Request.IS_UNDEFINED;
++ final Expression expr = undefinedSymbol == lhsSymbol ? rhs : lhs;
++ if (expr.getType().isPrimitive()) {
++ loadAndDiscard(expr); //throw away lhs, but it still needs to be evaluated for side effects, even if not in scope, as it can be optimistic
++ method.load(!isUndefinedCheck);
++ } else {
++ final Label checkTrue = new Label("ud_check_true");
++ final Label end = new Label("end");
++ loadExpressionAsObject(expr);
++ method.loadUndefined(Type.OBJECT);
++ method.if_acmpeq(checkTrue);
++ method.load(!isUndefinedCheck);
++ method._goto(end);
++ method.label(checkTrue);
++ method.load(isUndefinedCheck);
++ method.label(end);
++ }
++
++ return true;
++ }
++
++ private static boolean isUndefinedSymbol(final Symbol symbol) {
++ return symbol != null && "undefined".equals(symbol.getName());
+ }
+
+ private static boolean isNullLiteral(final Node node) {
+ return node instanceof LiteralNode<?> && ((LiteralNode<?>) node).isNull();
+ }
+
+- private boolean nullCheck(final RuntimeNode runtimeNode, final List<Expression> args, final String signature) {
++ private boolean nullCheck(final RuntimeNode runtimeNode, final List<Expression> args) {
+ final Request request = runtimeNode.getRequest();
+
+ if (!Request.isEQ(request) && !Request.isNE(request)) {
+@@ -1581,344 +2598,239 @@
+ rhs = tmp;
+ }
+
++ if (!isNullLiteral(rhs)) {
++ return false;
++ }
++
++ if (!lhs.getType().isObject()) {
++ return false;
++ }
++
++ if(isDeoptimizedExpression(lhs)) {
++ // This is actually related to "!lhs.getType().isObject()" above: any expression being deoptimized in
++ // the current chain of rest-of compilations used to have a type narrower than Object. We must not
++ // perform null check specialization for them, as then we'd no longer be loading aconst_null on stack
++ // and thus violate the basic rule of "Thou shalt not alter the stack shape between a deoptimized
++ // method and any of its (transitive) rest-ofs."
++ // NOTE also that if we had a representation for well-known constants (e.g. null, 0, 1, -1, etc.) in
++ // Label$Stack.localLoads then this wouldn't be an issue, as we would never (somewhat ridiculously)
++ // allocate a temporary local to hold the result of aconst_null before attempting an optimistic
++ // operation.
++ return false;
++ }
++
+ // this is a null literal check, so if there is implicit coercion
+ // involved like {D}x=null, we will fail - this is very rare
+- if (isNullLiteral(rhs) && lhs.getType().isObject()) {
+- final Label trueLabel = new Label("trueLabel");
+- final Label falseLabel = new Label("falseLabel");
+- final Label endLabel = new Label("end");
+-
+- load(lhs);
+- method.dup();
+- if (Request.isEQ(request)) {
+- method.ifnull(trueLabel);
+- } else if (Request.isNE(request)) {
+- method.ifnonnull(trueLabel);
++ final Label trueLabel = new Label("trueLabel");
++ final Label falseLabel = new Label("falseLabel");
++ final Label endLabel = new Label("end");
++
++ loadExpressionUnbounded(lhs); //lhs
++ final Label popLabel;
++ if (!Request.isStrict(request)) {
++ method.dup(); //lhs lhs
++ popLabel = new Label("pop");
++ } else {
++ popLabel = null;
++ }
++
++ if (Request.isEQ(request)) {
++ method.ifnull(!Request.isStrict(request) ? popLabel : trueLabel);
++ if (!Request.isStrict(request)) {
++ method.loadUndefined(Type.OBJECT);
++ method.if_acmpeq(trueLabel);
++ }
++ method.label(falseLabel);
++ method.load(false);
++ method._goto(endLabel);
++ if (!Request.isStrict(request)) {
++ method.label(popLabel);
++ method.pop();
++ }
++ method.label(trueLabel);
++ method.load(true);
++ method.label(endLabel);
++ } else if (Request.isNE(request)) {
++ method.ifnull(!Request.isStrict(request) ? popLabel : falseLabel);
++ if (!Request.isStrict(request)) {
++ method.loadUndefined(Type.OBJECT);
++ method.if_acmpeq(falseLabel);
++ }
++ method.label(trueLabel);
++ method.load(true);
++ method._goto(endLabel);
++ if (!Request.isStrict(request)) {
++ method.label(popLabel);
++ method.pop();
++ }
++ method.label(falseLabel);
++ method.load(false);
++ method.label(endLabel);
++ }
++
++ assert runtimeNode.getType().isBoolean();
++ method.convert(runtimeNode.getType());
++
++ return true;
++ }
++
++ /**
++ * Was this expression or any of its subexpressions deoptimized in the current recompilation chain of rest-of methods?
++ * @param rootExpr the expression being tested
++ * @return true if the expression or any of its subexpressions was deoptimized in the current recompilation chain.
++ */
++ private boolean isDeoptimizedExpression(final Expression rootExpr) {
++ if(!isRestOf()) {
++ return false;
++ }
++ return new Supplier<Boolean>() {
++ boolean contains;
++ @Override
++ public Boolean get() {
++ rootExpr.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
++ @Override
++ public boolean enterFunctionNode(final FunctionNode functionNode) {
++ return false;
++ }
++ @Override
++ public boolean enterDefault(final Node node) {
++ if(!contains && node instanceof Optimistic) {
++ final int pp = ((Optimistic)node).getProgramPoint();
++ contains = isValid(pp) && isContinuationEntryPoint(pp);
++ }
++ return !contains;
++ }
++ });
++ return contains;
++ }
++ }.get();
++ }
++
++ private void loadRuntimeNode(final RuntimeNode runtimeNode) {
++ final List<Expression> args = new ArrayList<>(runtimeNode.getArgs());
++ if (nullCheck(runtimeNode, args)) {
++ return;
++ } else if(undefinedCheck(runtimeNode, args)) {
++ return;
++ }
++ // Revert a false undefined check to a strict equality check
++ final RuntimeNode newRuntimeNode;
++ final Request request = runtimeNode.getRequest();
++ if (Request.isUndefinedCheck(request)) {
++ newRuntimeNode = runtimeNode.setRequest(request == Request.IS_UNDEFINED ? Request.EQ_STRICT : Request.NE_STRICT);
++ } else {
++ newRuntimeNode = runtimeNode;
++ }
++
++ new OptimisticOperation(newRuntimeNode, TypeBounds.UNBOUNDED) {
++ @Override
++ void loadStack() {
++ for (final Expression arg : args) {
++ loadExpression(arg, TypeBounds.OBJECT);
++ }
++ }
++ @Override
++ void consumeStack() {
++ method.invokestatic(
++ CompilerConstants.className(ScriptRuntime.class),
++ newRuntimeNode.getRequest().toString(),
++ new FunctionSignature(
++ false,
++ false,
++ newRuntimeNode.getType(),
++ args.size()).toString());
++ }
++ }.emit();
++
++ method.convert(newRuntimeNode.getType());
++ }
++
++ private void defineCommonSplitMethodParameters() {
++ defineSplitMethodParameter(0, CALLEE);
++ defineSplitMethodParameter(1, THIS);
++ defineSplitMethodParameter(2, SCOPE);
++ }
++
++ private void defineSplitMethodParameter(final int slot, final CompilerConstants cc) {
++ defineSplitMethodParameter(slot, Type.typeFor(cc.type()));
++ }
++
++ private void defineSplitMethodParameter(final int slot, final Type type) {
++ method.defineBlockLocalVariable(slot, slot + type.getSlots());
++ method.onLocalStore(type, slot);
++ }
++
++ private int fixScopeSlot(final FunctionNode functionNode, final int extraSlot) {
++ // TODO hack to move the scope to the expected slot (needed because split methods reuse the same slots as the root method)
++ final int actualScopeSlot = functionNode.compilerConstant(SCOPE).getSlot(SCOPE_TYPE);
++ final int defaultScopeSlot = SCOPE.slot();
++ int newExtraSlot = extraSlot;
++ if (actualScopeSlot != defaultScopeSlot) {
++ if (actualScopeSlot == extraSlot) {
++ newExtraSlot = extraSlot + 1;
++ method.defineBlockLocalVariable(newExtraSlot, newExtraSlot + 1);
++ method.load(Type.OBJECT, extraSlot);
++ method.storeHidden(Type.OBJECT, newExtraSlot);
+ } else {
+- assert false : "Invalid request " + request;
+- }
+-
+- method.label(falseLabel);
+- load(rhs);
+- method.invokestatic(CompilerConstants.className(ScriptRuntime.class), request.toString(), signature);
+- method._goto(endLabel);
+-
+- method.label(trueLabel);
+- // if NE (not strict) this can be "undefined != null" which is supposed to be false
+- if (request == Request.NE) {
+- method.loadUndefined(Type.OBJECT);
+- final Label isUndefined = new Label("isUndefined");
+- final Label afterUndefinedCheck = new Label("afterUndefinedCheck");
+- method.if_acmpeq(isUndefined);
+- // not undefined
+- method.load(true);
+- method._goto(afterUndefinedCheck);
+- method.label(isUndefined);
+- method.load(false);
+- method.label(afterUndefinedCheck);
+- } else {
+- method.pop();
+- method.load(true);
+- }
+- method.label(endLabel);
+- method.convert(runtimeNode.getType());
+- method.store(runtimeNode.getSymbol());
+-
+- return true;
+- }
+-
++ method.defineBlockLocalVariable(actualScopeSlot, actualScopeSlot + 1);
++ }
++ method.load(SCOPE_TYPE, defaultScopeSlot);
++ method.storeCompilerConstant(SCOPE);
++ }
++ return newExtraSlot;
++ }
++
++ @Override
++ public boolean enterSplitReturn(final SplitReturn splitReturn) {
++ if (method.isReachable()) {
++ method.loadUndefined(lc.getCurrentFunction().getReturnType())._return();
++ }
+ return false;
+ }
+
+- private boolean specializationCheck(final RuntimeNode.Request request, final Expression node, final List<Expression> args) {
+- if (!request.canSpecialize()) {
+- return false;
+- }
+-
+- assert args.size() == 2;
+- final Type returnType = node.getType();
+-
+- load(args.get(0));
+- load(args.get(1));
+-
+- Request finalRequest = request;
+-
+- //if the request is a comparison, i.e. one that can be reversed
+- //it keeps its semantic, but make sure that the object comes in
+- //last
+- final Request reverse = Request.reverse(request);
+- if (method.peekType().isObject() && reverse != null) { //rhs is object
+- if (!method.peekType(1).isObject()) { //lhs is not object
+- method.swap(); //prefer object as lhs
+- finalRequest = reverse;
+- }
+- }
+-
+- method.dynamicRuntimeCall(
+- new SpecializedRuntimeNode(
+- finalRequest,
+- new Type[] {
+- method.peekType(1),
+- method.peekType()
+- },
+- returnType).getInitialName(),
+- returnType,
+- finalRequest);
+-
+- method.convert(node.getType());
+- method.store(node.getSymbol());
+-
+- return true;
+- }
+-
+- private static boolean isReducible(final Request request) {
+- return Request.isComparison(request) || request == Request.ADD;
+- }
+-
+ @Override
+- public boolean enterRuntimeNode(final RuntimeNode runtimeNode) {
+- /*
+- * First check if this should be something other than a runtime node
+- * AccessSpecializer might have changed the type
+- *
+- * TODO - remove this - Access Specializer will always know after Attr/Lower
+- */
+- final List<Expression> args = runtimeNode.getArgs();
+- if (runtimeNode.isPrimitive() && !runtimeNode.isFinal() && isReducible(runtimeNode.getRequest())) {
+- final Expression lhs = args.get(0);
+- assert args.size() > 1 : runtimeNode + " must have two args";
+- final Expression rhs = args.get(1);
+-
+- final Type type = runtimeNode.getType();
+- final Symbol symbol = runtimeNode.getSymbol();
+-
+- switch (runtimeNode.getRequest()) {
+- case EQ:
+- case EQ_STRICT:
+- return enterCmp(lhs, rhs, Condition.EQ, type, symbol);
+- case NE:
+- case NE_STRICT:
+- return enterCmp(lhs, rhs, Condition.NE, type, symbol);
+- case LE:
+- return enterCmp(lhs, rhs, Condition.LE, type, symbol);
+- case LT:
+- return enterCmp(lhs, rhs, Condition.LT, type, symbol);
+- case GE:
+- return enterCmp(lhs, rhs, Condition.GE, type, symbol);
+- case GT:
+- return enterCmp(lhs, rhs, Condition.GT, type, symbol);
+- case ADD:
+- Type widest = Type.widest(lhs.getType(), rhs.getType());
+- load(lhs, widest);
+- load(rhs, widest);
+- method.add();
+- method.convert(type);
+- method.store(symbol);
+- return false;
+- default:
+- // it's ok to send this one on with only primitive arguments, maybe INSTANCEOF(true, true) or similar
+- // assert false : runtimeNode + " has all primitive arguments. This is an inconsistent state";
+- break;
+- }
+- }
+-
+- if (nullCheck(runtimeNode, args, new FunctionSignature(false, false, runtimeNode.getType(), args).toString())) {
+- return false;
+- }
+-
+- if (!runtimeNode.isFinal() && specializationCheck(runtimeNode.getRequest(), runtimeNode, args)) {
+- return false;
+- }
+-
+- for (final Expression arg : args) {
+- load(arg, Type.OBJECT);
+- }
+-
+- method.invokestatic(
+- CompilerConstants.className(ScriptRuntime.class),
+- runtimeNode.getRequest().toString(),
+- new FunctionSignature(
+- false,
+- false,
+- runtimeNode.getType(),
+- args.size()).toString());
+- method.convert(runtimeNode.getType());
+- method.store(runtimeNode.getSymbol());
+-
++ public boolean enterSetSplitState(final SetSplitState setSplitState) {
++ if (method.isReachable()) {
++ method.setSplitState(setSplitState.getState());
++ }
+ return false;
+ }
+
+ @Override
+- public boolean enterSplitNode(final SplitNode splitNode) {
+- final CompileUnit splitCompileUnit = splitNode.getCompileUnit();
+-
+- final FunctionNode fn = lc.getCurrentFunction();
+- final String className = splitCompileUnit.getUnitClassName();
+- final String name = splitNode.getName();
+-
+- final Class<?> rtype = fn.getReturnType().getTypeClass();
+- final boolean needsArguments = fn.needsArguments();
+- final Class<?>[] ptypes = needsArguments ?
+- new Class<?>[] {ScriptFunction.class, Object.class, ScriptObject.class, Object.class} :
+- new Class<?>[] {ScriptFunction.class, Object.class, ScriptObject.class};
+-
+- final MethodEmitter caller = method;
+- unit = lc.pushCompileUnit(splitCompileUnit);
+-
+- final Call splitCall = staticCallNoLookup(
+- className,
+- name,
+- methodDescriptor(rtype, ptypes));
+-
+- final MethodEmitter splitEmitter =
+- splitCompileUnit.getClassEmitter().method(
+- splitNode,
+- name,
+- rtype,
+- ptypes);
+-
+- method = lc.pushMethodEmitter(splitEmitter);
+- method.setFunctionNode(fn);
+-
+- assert fn.needsCallee() : "split function should require callee";
+- caller.loadCompilerConstant(CALLEE);
+- caller.loadCompilerConstant(THIS);
+- caller.loadCompilerConstant(SCOPE);
+- if (needsArguments) {
+- caller.loadCompilerConstant(ARGUMENTS);
+- }
+- caller.invoke(splitCall);
+- caller.storeCompilerConstant(RETURN);
+-
+- method.begin();
+- // Copy scope to its target slot as first thing because the original slot could be used by return symbol.
+- fixScopeSlot(fn);
+-
+- method.loadUndefined(fn.getReturnType());
+- method.storeCompilerConstant(RETURN);
+-
+- return true;
+- }
+-
+- private void fixScopeSlot(final FunctionNode functionNode) {
+- // TODO hack to move the scope to the expected slot (needed because split methods reuse the same slots as the root method)
+- if (functionNode.compilerConstant(SCOPE).getSlot() != SCOPE.slot()) {
+- method.load(Type.typeFor(ScriptObject.class), SCOPE.slot());
+- method.storeCompilerConstant(SCOPE);
+- }
+- }
+-
+- @Override
+- public Node leaveSplitNode(final SplitNode splitNode) {
+- assert method instanceof SplitMethodEmitter;
+- final boolean hasReturn = method.hasReturn();
+- final List<Label> targets = method.getExternalTargets();
+-
+- try {
+- // Wrap up this method.
+-
+- method.loadCompilerConstant(RETURN);
+- method._return(lc.getCurrentFunction().getReturnType());
+- method.end();
+-
+- unit = lc.popCompileUnit(splitNode.getCompileUnit());
+- method = lc.popMethodEmitter(method);
+-
+- } catch (final Throwable t) {
+- Context.printStackTrace(t);
+- final VerifyError e = new VerifyError("Code generation bug in \"" + splitNode.getName() + "\": likely stack misaligned: " + t + " " + lc.getCurrentFunction().getSource().getName());
+- e.initCause(t);
+- throw e;
+- }
+-
+- // Handle return from split method if there was one.
+- final MethodEmitter caller = method;
+- final int targetCount = targets.size();
+-
+- //no external jump targets or return in switch node
+- if (!hasReturn && targets.isEmpty()) {
+- return splitNode;
+- }
+-
+- caller.loadCompilerConstant(SCOPE);
+- caller.checkcast(Scope.class);
+- caller.invoke(Scope.GET_SPLIT_STATE);
+-
+- final Label breakLabel = new Label("no_split_state");
+- // Split state is -1 for no split state, 0 for return, 1..n+1 for break/continue
+-
+- //the common case is that we don't need a switch
+- if (targetCount == 0) {
+- assert hasReturn;
+- caller.ifne(breakLabel);
+- //has to be zero
+- caller.label(new Label("split_return"));
+- caller.loadCompilerConstant(RETURN);
+- caller._return(lc.getCurrentFunction().getReturnType());
+- caller.label(breakLabel);
+- } else {
+- assert !targets.isEmpty();
+-
+- final int low = hasReturn ? 0 : 1;
+- final int labelCount = targetCount + 1 - low;
+- final Label[] labels = new Label[labelCount];
+-
+- for (int i = 0; i < labelCount; i++) {
+- labels[i] = new Label(i == 0 ? "split_return" : "split_" + targets.get(i - 1));
+- }
+- caller.tableswitch(low, targetCount, breakLabel, labels);
+- for (int i = low; i <= targetCount; i++) {
+- caller.label(labels[i - low]);
+- if (i == 0) {
+- caller.loadCompilerConstant(RETURN);
+- caller._return(lc.getCurrentFunction().getReturnType());
+- } else {
+- // Clear split state.
+- caller.loadCompilerConstant(SCOPE);
+- caller.checkcast(Scope.class);
+- caller.load(-1);
+- caller.invoke(Scope.SET_SPLIT_STATE);
+- caller.splitAwareGoto(lc, targets.get(i - 1));
+- }
+- }
+- caller.label(breakLabel);
+- }
+-
+- // If split has a return and caller is itself a split method it needs to propagate the return.
+- if (hasReturn) {
+- caller.setHasReturn();
+- }
+-
+- return splitNode;
+- }
+-
+- @Override
+ public boolean enterSwitchNode(final SwitchNode switchNode) {
+- lineNumber(switchNode);
++ if(!method.isReachable()) {
++ return false;
++ }
++ enterStatement(switchNode);
+
+ final Expression expression = switchNode.getExpression();
+- final Symbol tag = switchNode.getTag();
+- final boolean allInteger = tag.getSymbolType().isInteger();
+ final List<CaseNode> cases = switchNode.getCases();
+- final CaseNode defaultCase = switchNode.getDefaultCase();
+- final Label breakLabel = switchNode.getBreakLabel();
+-
+- Label defaultLabel = breakLabel;
+- boolean hasDefault = false;
+-
+- if (defaultCase != null) {
+- defaultLabel = defaultCase.getEntry();
+- hasDefault = true;
+- }
+
+ if (cases.isEmpty()) {
+ // still evaluate expression for side-effects.
+- load(expression).pop();
+- method.label(breakLabel);
++ loadAndDiscard(expression);
+ return false;
+ }
+
+- if (allInteger) {
++ final CaseNode defaultCase = switchNode.getDefaultCase();
++ final Label breakLabel = switchNode.getBreakLabel();
++ final int liveLocalsOnBreak = method.getUsedSlotsWithLiveTemporaries();
++
++ if (defaultCase != null && cases.size() == 1) {
++ // default case only
++ assert cases.get(0) == defaultCase;
++ loadAndDiscard(expression);
++ defaultCase.getBody().accept(this);
++ method.breakLabel(breakLabel, liveLocalsOnBreak);
++ return false;
++ }
++
++ // NOTE: it can still change in the tableswitch/lookupswitch case if there's no default case
++ // but we need to add a synthetic default case for local variable conversions
++ Label defaultLabel = defaultCase != null ? defaultCase.getEntry() : breakLabel;
++ final boolean hasSkipConversion = LocalVariableConversion.hasLiveConversion(switchNode);
++
++ if (switchNode.isUniqueInteger()) {
+ // Tree for sorting values.
+ final TreeMap<Integer, Label> tree = new TreeMap<>();
+
+@@ -1931,7 +2843,7 @@
+ final Label entry = caseNode.getEntry();
+
+ // Take first duplicate.
+- if (!(tree.containsKey(value))) {
++ if (!tree.containsKey(value)) {
+ tree.put(value, entry);
+ }
+ }
+@@ -1945,7 +2857,7 @@
+ // Discern low, high and range.
+ final int lo = values[0];
+ final int hi = values[size - 1];
+- final int range = hi - lo + 1;
++ final long range = (long)hi - (long)lo + 1;
+
+ // Find an unused value for default.
+ int deflt = Integer.MIN_VALUE;
+@@ -1958,7 +2870,7 @@
+ }
+
+ // Load switch expression.
+- load(expression);
++ loadExpressionUnbounded(expression);
+ final Type type = expression.getType();
+
+ // If expression not int see if we can convert, if not use deflt to trigger default.
+@@ -1968,11 +2880,15 @@
+ method.invoke(staticCallNoLookup(ScriptRuntime.class, "switchTagAsInt", int.class, exprClass.isPrimitive()? exprClass : Object.class, int.class));
+ }
+
+- // If reasonable size and not too sparse (80%), use table otherwise use lookup.
+- if (range > 0 && range < 4096 && range < (size * 5 / 4)) {
+- final Label[] table = new Label[range];
++ if(hasSkipConversion) {
++ assert defaultLabel == breakLabel;
++ defaultLabel = new Label("switch_skip");
++ }
++ // TABLESWITCH needs (range + 3) 32-bit values; LOOKUPSWITCH needs ((size * 2) + 2). Choose the one with
++ // smaller representation, favor TABLESWITCH when they're equal size.
++ if (range + 1 <= (size * 2) && range <= Integer.MAX_VALUE) {
++ final Label[] table = new Label[(int)range];
+ Arrays.fill(table, defaultLabel);
+-
+ for (int i = 0; i < size; i++) {
+ final int value = values[i];
+ table[value - lo] = labels[i];
+@@ -1987,97 +2903,163 @@
+
+ method.lookupswitch(defaultLabel, ints, labels);
+ }
++ // This is a synthetic "default case" used in absence of actual default case, created if we need to apply
++ // local variable conversions if neither case is taken.
++ if(hasSkipConversion) {
++ method.label(defaultLabel);
++ method.beforeJoinPoint(switchNode);
++ method._goto(breakLabel);
++ }
+ } else {
+- load(expression, Type.OBJECT);
+- method.store(tag);
++ final Symbol tagSymbol = switchNode.getTag();
++ // TODO: we could have non-object tag
++ final int tagSlot = tagSymbol.getSlot(Type.OBJECT);
++ loadExpressionAsObject(expression);
++ method.store(tagSymbol, Type.OBJECT);
+
+ for (final CaseNode caseNode : cases) {
+ final Expression test = caseNode.getTest();
+
+ if (test != null) {
+- method.load(tag);
+- load(test, Type.OBJECT);
++ method.load(Type.OBJECT, tagSlot);
++ loadExpressionAsObject(test);
+ method.invoke(ScriptRuntime.EQ_STRICT);
+ method.ifne(caseNode.getEntry());
+ }
+ }
+
+- method._goto(hasDefault ? defaultLabel : breakLabel);
+- }
++ if (defaultCase != null) {
++ method._goto(defaultLabel);
++ } else {
++ method.beforeJoinPoint(switchNode);
++ method._goto(breakLabel);
++ }
++ }
++
++ // First case is only reachable through jump
++ assert !method.isReachable();
+
+ for (final CaseNode caseNode : cases) {
++ final Label fallThroughLabel;
++ if(caseNode.getLocalVariableConversion() != null && method.isReachable()) {
++ fallThroughLabel = new Label("fallthrough");
++ method._goto(fallThroughLabel);
++ } else {
++ fallThroughLabel = null;
++ }
+ method.label(caseNode.getEntry());
++ method.beforeJoinPoint(caseNode);
++ if(fallThroughLabel != null) {
++ method.label(fallThroughLabel);
++ }
+ caseNode.getBody().accept(this);
+ }
+
+- if (!switchNode.isTerminal()) {
+- method.label(breakLabel);
+- }
++ method.breakLabel(breakLabel, liveLocalsOnBreak);
+
+ return false;
+ }
+
+ @Override
+ public boolean enterThrowNode(final ThrowNode throwNode) {
+- lineNumber(throwNode);
++ if(!method.isReachable()) {
++ return false;
++ }
++ enterStatement(throwNode);
+
+ if (throwNode.isSyntheticRethrow()) {
++ method.beforeJoinPoint(throwNode);
++
+ //do not wrap whatever this is in an ecma exception, just rethrow it
+- load(throwNode.getExpression());
++ final IdentNode exceptionExpr = (IdentNode)throwNode.getExpression();
++ final Symbol exceptionSymbol = exceptionExpr.getSymbol();
++ method.load(exceptionSymbol, EXCEPTION_TYPE);
++ method.checkcast(EXCEPTION_TYPE.getTypeClass());
+ method.athrow();
+ return false;
+ }
+
+- final Source source = lc.getCurrentFunction().getSource();
+-
++ final Source source = getCurrentSource();
+ final Expression expression = throwNode.getExpression();
+ final int position = throwNode.position();
+ final int line = throwNode.getLineNumber();
+ final int column = source.getColumn(position);
+
+- load(expression, Type.OBJECT);
++ // NOTE: we first evaluate the expression, and only after it was evaluated do we create the new ECMAException
++ // object and then somewhat cumbersomely move it beneath the evaluated expression on the stack. The reason for
++ // this is that if expression is optimistic (or contains an optimistic subexpression), we'd potentially access
++ // the not-yet-<init>ialized object on the stack from the UnwarrantedOptimismException handler, and bytecode
++ // verifier forbids that.
++ loadExpressionAsObject(expression);
+
+ method.load(source.getName());
+ method.load(line);
+ method.load(column);
+ method.invoke(ECMAException.CREATE);
+
++ method.beforeJoinPoint(throwNode);
+ method.athrow();
+
+ return false;
+ }
+
++ private Source getCurrentSource() {
++ return lc.getCurrentFunction().getSource();
++ }
++
+ @Override
+ public boolean enterTryNode(final TryNode tryNode) {
+- lineNumber(tryNode);
++ if(!method.isReachable()) {
++ return false;
++ }
++ enterStatement(tryNode);
+
+ final Block body = tryNode.getBody();
+ final List<Block> catchBlocks = tryNode.getCatchBlocks();
+- final Symbol symbol = tryNode.getException();
++ final Symbol vmException = tryNode.getException();
+ final Label entry = new Label("try");
+ final Label recovery = new Label("catch");
+- final Label exit = tryNode.getExit();
++ final Label exit = new Label("end_try");
+ final Label skip = new Label("skip");
+
++ method.canThrow(recovery);
++ // Effect any conversions that might be observed at the entry of the catch node before entering the try node.
++ // This is because even the first instruction in the try block must be presumed to be able to transfer control
++ // to the catch block. Note that this doesn't kill the original values; in this regard it works a lot like
++ // conversions of assignments within the try block.
++ method.beforeTry(tryNode, recovery);
+ method.label(entry);
+-
+- body.accept(this);
+-
+- if (!body.hasTerminalFlags()) {
++ catchLabels.push(recovery);
++ try {
++ body.accept(this);
++ } finally {
++ assert catchLabels.peek() == recovery;
++ catchLabels.pop();
++ }
++
++ method.label(exit);
++ final boolean bodyCanThrow = exit.isAfter(entry);
++ if(!bodyCanThrow) {
++ // The body can't throw an exception; don't even bother emitting the catch handlers, they're all dead code.
++ return false;
++ }
++
++ method._try(entry, exit, recovery, Throwable.class);
++
++ if (method.isReachable()) {
+ method._goto(skip);
+ }
+-
+- method.label(exit);
+-
+ method._catch(recovery);
+- method.store(symbol);
+-
+- for (int i = 0; i < catchBlocks.size(); i++) {
++ method.store(vmException, EXCEPTION_TYPE);
++
++ final int catchBlockCount = catchBlocks.size();
++ final Label afterCatch = new Label("after_catch");
++ for (int i = 0; i < catchBlockCount; i++) {
++ assert method.isReachable();
+ final Block catchBlock = catchBlocks.get(i);
+
+- //TODO this is very ugly - try not to call enter/leave methods directly
+- //better to use the implicit lexical context scoping given by the visitor's
+- //accept method.
++ // Because of the peculiarities of the flow control, we need to use an explicit push/enterBlock/leaveBlock
++ // here.
+ lc.push(catchBlock);
+ enterBlock(catchBlock);
+
+@@ -2089,13 +3071,14 @@
+ new Store<IdentNode>(exception) {
+ @Override
+ protected void storeNonDiscard() {
+- return;
++ // This expression is neither part of a discard, nor needs to be left on the stack after it was
++ // stored, so we override storeNonDiscard to be a no-op.
+ }
+
+ @Override
+ protected void evaluate() {
+ if (catchNode.isSyntheticRethrow()) {
+- method.load(symbol);
++ method.load(vmException, EXCEPTION_TYPE);
+ return;
+ }
+ /*
+@@ -2104,126 +3087,273 @@
+ * caught object itself to the script catch var.
+ */
+ final Label notEcmaException = new Label("no_ecma_exception");
+- method.load(symbol).dup()._instanceof(ECMAException.class).ifeq(notEcmaException);
++ method.load(vmException, EXCEPTION_TYPE).dup()._instanceof(ECMAException.class).ifeq(notEcmaException);
+ method.checkcast(ECMAException.class); //TODO is this necessary?
+ method.getField(ECMAException.THROWN);
+ method.label(notEcmaException);
+ }
+ }.store();
+
+- final Label next;
+-
+- if (exceptionCondition != null) {
+- next = new Label("next");
+- load(exceptionCondition, Type.BOOLEAN).ifeq(next);
++ final boolean isConditionalCatch = exceptionCondition != null;
++ final Label nextCatch;
++ if (isConditionalCatch) {
++ loadExpressionAsBoolean(exceptionCondition);
++ nextCatch = new Label("next_catch");
++ method.ifeq(nextCatch);
+ } else {
+- next = null;
++ nextCatch = null;
+ }
+
+ catchBody.accept(this);
+-
+- if (i + 1 != catchBlocks.size() && !catchBody.hasTerminalFlags()) {
+- method._goto(skip);
+- }
+-
+- if (next != null) {
+- if (i + 1 == catchBlocks.size()) {
+- // no next catch block - rethrow if condition failed
+- method._goto(skip);
+- method.label(next);
+- method.load(symbol).athrow();
+- } else {
+- method.label(next);
+- }
+- }
+-
+ leaveBlock(catchBlock);
+ lc.pop(catchBlock);
+- }
+-
++ if(method.isReachable()) {
++ method._goto(afterCatch);
++ }
++ if(nextCatch != null) {
++ method.label(nextCatch);
++ }
++ }
++
++ assert !method.isReachable();
++ // afterCatch could be the same as skip, except that we need to establish that the vmException is dead.
++ method.label(afterCatch);
++ if(method.isReachable()) {
++ method.markDeadLocalVariable(vmException);
++ }
+ method.label(skip);
+- method._try(entry, exit, recovery, Throwable.class);
+
+ // Finally body is always inlined elsewhere so it doesn't need to be emitted
+-
+ return false;
+ }
+
+ @Override
+ public boolean enterVarNode(final VarNode varNode) {
+-
++ if(!method.isReachable()) {
++ return false;
++ }
+ final Expression init = varNode.getInit();
+-
+- if (init == null) {
+- return false;
+- }
+-
+- lineNumber(varNode);
+-
+ final IdentNode identNode = varNode.getName();
+ final Symbol identSymbol = identNode.getSymbol();
+ assert identSymbol != null : "variable node " + varNode + " requires a name with a symbol";
+-
++ final boolean needsScope = identSymbol.isScope();
++
++ if (init == null) {
++ if (needsScope && varNode.isBlockScoped()) {
++ // block scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ)
++ method.loadCompilerConstant(SCOPE);
++ method.loadUndefined(Type.OBJECT);
++ final int flags = CALLSITE_SCOPE | getCallSiteFlags() | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0);
++ assert isFastScope(identSymbol);
++ storeFastScopeVar(identSymbol, flags);
++ }
++ return false;
++ }
++
++ enterStatement(varNode);
+ assert method != null;
+
+- final boolean needsScope = identSymbol.isScope();
+ if (needsScope) {
+ method.loadCompilerConstant(SCOPE);
+ }
+
+ if (needsScope) {
+- load(init);
+- int flags = CALLSITE_SCOPE | getCallSiteFlags();
++ loadExpressionUnbounded(init);
++ // block scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ)
++ final int flags = CALLSITE_SCOPE | getCallSiteFlags() | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0);
+ if (isFastScope(identSymbol)) {
+ storeFastScopeVar(identSymbol, flags);
+ } else {
+- method.dynamicSet(identNode.getName(), flags);
++ method.dynamicSet(identNode.getName(), flags, false);
+ }
+ } else {
+- load(init, identNode.getType());
+- method.store(identSymbol);
++ final Type identType = identNode.getType();
++ if(identType == Type.UNDEFINED) {
++ // The initializer is either itself undefined (explicit assignment of undefined to undefined),
++ // or the left hand side is a dead variable.
++ assert init.getType() == Type.UNDEFINED || identNode.getSymbol().slotCount() == 0;
++ loadAndDiscard(init);
++ return false;
++ }
++ loadExpressionAsType(init, identType);
++ storeIdentWithCatchConversion(identNode, identType);
+ }
+
+ return false;
+ }
+
++ private void storeIdentWithCatchConversion(final IdentNode identNode, final Type type) {
++ // Assignments happening in try/catch blocks need to ensure that they also store a possibly wider typed value
++ // that will be live at the exit from the try block
++ final LocalVariableConversion conversion = identNode.getLocalVariableConversion();
++ final Symbol symbol = identNode.getSymbol();
++ if(conversion != null && conversion.isLive()) {
++ assert symbol == conversion.getSymbol();
++ assert symbol.isBytecodeLocal();
++ // Only a single conversion from the target type to the join type is expected.
++ assert conversion.getNext() == null;
++ assert conversion.getFrom() == type;
++ // We must propagate potential type change to the catch block
++ final Label catchLabel = catchLabels.peek();
++ assert catchLabel != METHOD_BOUNDARY; // ident conversion only exists in try blocks
++ assert catchLabel.isReachable();
++ final Type joinType = conversion.getTo();
++ final Label.Stack catchStack = catchLabel.getStack();
++ final int joinSlot = symbol.getSlot(joinType);
++ // With nested try/catch blocks (incl. synthetic ones for finally), we can have a supposed conversion for
++ // the exception symbol in the nested catch, but it isn't live in the outer catch block, so prevent doing
++ // conversions for it. E.g. in "try { try { ... } catch(e) { e = 1; } } catch(e2) { ... }", we must not
++ // introduce an I->O conversion on "e = 1" assignment as "e" is not live in "catch(e2)".
++ if(catchStack.getUsedSlotsWithLiveTemporaries() > joinSlot) {
++ method.dup();
++ method.convert(joinType);
++ method.store(symbol, joinType);
++ catchLabel.getStack().onLocalStore(joinType, joinSlot, true);
++ method.canThrow(catchLabel);
++ // Store but keep the previous store live too.
++ method.store(symbol, type, false);
++ return;
++ }
++ }
++
++ method.store(symbol, type, true);
++ }
++
+ @Override
+ public boolean enterWhileNode(final WhileNode whileNode) {
+- final Expression test = whileNode.getTest();
+- final Block body = whileNode.getBody();
+- final Label breakLabel = whileNode.getBreakLabel();
+- final Label continueLabel = whileNode.getContinueLabel();
+- final boolean isDoWhile = whileNode.isDoWhile();
+- final Label loopLabel = new Label("loop");
+-
+- if (!isDoWhile) {
+- method._goto(continueLabel);
+- }
+-
+- method.label(loopLabel);
+- body.accept(this);
+- if (!whileNode.isTerminal()) {
+- method.label(continueLabel);
+- lineNumber(whileNode);
+- new BranchOptimizer(this, method).execute(test, loopLabel, true);
+- method.label(breakLabel);
+- }
+-
++ if(!method.isReachable()) {
++ return false;
++ }
++ if(whileNode.isDoWhile()) {
++ enterDoWhile(whileNode);
++ } else {
++ enterStatement(whileNode);
++ enterForOrWhile(whileNode, null);
++ }
+ return false;
+ }
+
+- private void closeWith() {
+- if (method.hasScope()) {
++ private void enterForOrWhile(final LoopNode loopNode, final JoinPredecessorExpression modify) {
++ // NOTE: the usual pattern for compiling test-first loops is "GOTO test; body; test; IFNE body". We use the less
++ // conventional "test; IFEQ break; body; GOTO test; break;". It has one extra unconditional GOTO in each repeat
++ // of the loop, but it's not a problem for modern JIT compilers. We do this because our local variable type
++ // tracking is unfortunately not really prepared for out-of-order execution, e.g. compiling the following
++ // contrived but legal JavaScript code snippet would fail because the test changes the type of "i" from object
++ // to double: var i = {valueOf: function() { return 1} }; while(--i >= 0) { ... }
++ // Instead of adding more complexity to the local variable type tracking, we instead choose to emit this
++ // different code shape.
++ final int liveLocalsOnBreak = method.getUsedSlotsWithLiveTemporaries();
++ final JoinPredecessorExpression test = loopNode.getTest();
++ if(Expression.isAlwaysFalse(test)) {
++ loadAndDiscard(test);
++ return;
++ }
++
++ method.beforeJoinPoint(loopNode);
++
++ final Label continueLabel = loopNode.getContinueLabel();
++ final Label repeatLabel = modify != null ? new Label("for_repeat") : continueLabel;
++ method.label(repeatLabel);
++ final int liveLocalsOnContinue = method.getUsedSlotsWithLiveTemporaries();
++
++ final Block body = loopNode.getBody();
++ final Label breakLabel = loopNode.getBreakLabel();
++ final boolean testHasLiveConversion = test != null && LocalVariableConversion.hasLiveConversion(test);
++
++ if(Expression.isAlwaysTrue(test)) {
++ if(test != null) {
++ loadAndDiscard(test);
++ if(testHasLiveConversion) {
++ method.beforeJoinPoint(test);
++ }
++ }
++ } else if (test != null) {
++ if (testHasLiveConversion) {
++ emitBranch(test.getExpression(), body.getEntryLabel(), true);
++ method.beforeJoinPoint(test);
++ method._goto(breakLabel);
++ } else {
++ emitBranch(test.getExpression(), breakLabel, false);
++ }
++ }
++
++ body.accept(this);
++ if(repeatLabel != continueLabel) {
++ emitContinueLabel(continueLabel, liveLocalsOnContinue);
++ }
++
++ if (loopNode.hasPerIterationScope() && lc.getCurrentBlock().needsScope()) {
++ // ES6 for loops with LET init need a new scope for each iteration. We just create a shallow copy here.
+ method.loadCompilerConstant(SCOPE);
+- method.invoke(ScriptRuntime.CLOSE_WITH);
++ method.invoke(virtualCallNoLookup(ScriptObject.class, "copy", ScriptObject.class));
+ method.storeCompilerConstant(SCOPE);
+ }
++
++ if(method.isReachable()) {
++ if(modify != null) {
++ lineNumber(loopNode);
++ loadAndDiscard(modify);
++ method.beforeJoinPoint(modify);
++ }
++ method._goto(repeatLabel);
++ }
++
++ method.breakLabel(breakLabel, liveLocalsOnBreak);
+ }
+
++ private void emitContinueLabel(final Label continueLabel, final int liveLocals) {
++ final boolean reachable = method.isReachable();
++ method.breakLabel(continueLabel, liveLocals);
++ // If we reach here only through a continue statement (e.g. body does not exit normally) then the
++ // continueLabel can have extra non-temp symbols (e.g. exception from a try/catch contained in the body). We
++ // must make sure those are thrown away.
++ if(!reachable) {
++ method.undefineLocalVariables(lc.getUsedSlotCount(), false);
++ }
++ }
++
++ private void enterDoWhile(final WhileNode whileNode) {
++ final int liveLocalsOnContinueOrBreak = method.getUsedSlotsWithLiveTemporaries();
++ method.beforeJoinPoint(whileNode);
++
++ final Block body = whileNode.getBody();
++ body.accept(this);
++
++ emitContinueLabel(whileNode.getContinueLabel(), liveLocalsOnContinueOrBreak);
++ if(method.isReachable()) {
++ lineNumber(whileNode);
++ final JoinPredecessorExpression test = whileNode.getTest();
++ final Label bodyEntryLabel = body.getEntryLabel();
++ final boolean testHasLiveConversion = LocalVariableConversion.hasLiveConversion(test);
++ if(Expression.isAlwaysFalse(test)) {
++ loadAndDiscard(test);
++ if(testHasLiveConversion) {
++ method.beforeJoinPoint(test);
++ }
++ } else if(testHasLiveConversion) {
++ // If we have conversions after the test in do-while, they need to be effected on both branches.
++ final Label beforeExit = new Label("do_while_preexit");
++ emitBranch(test.getExpression(), beforeExit, false);
++ method.beforeJoinPoint(test);
++ method._goto(bodyEntryLabel);
++ method.label(beforeExit);
++ method.beforeJoinPoint(test);
++ } else {
++ emitBranch(test.getExpression(), bodyEntryLabel, true);
++ }
++ }
++ method.breakLabel(whileNode.getBreakLabel(), liveLocalsOnContinueOrBreak);
++ }
++
++
+ @Override
+ public boolean enterWithNode(final WithNode withNode) {
++ if(!method.isReachable()) {
++ return false;
++ }
++ enterStatement(withNode);
+ final Expression expression = withNode.getExpression();
+- final Node body = withNode.getBody();
++ final Block body = withNode.getBody();
+
+ // It is possible to have a "pathological" case where the with block does not reference *any* identifiers. It's
+ // pointless, but legal. In that case, if nothing else in the method forced the assignment of a slot to the
+@@ -2231,27 +3361,25 @@
+ // for its side effect and visit the body, and not bother opening and closing a WithObject.
+ final boolean hasScope = method.hasScope();
+
++ if (hasScope) {
++ method.loadCompilerConstant(SCOPE);
++ }
++
++ loadExpressionAsObject(expression);
++
+ final Label tryLabel;
+ if (hasScope) {
+- tryLabel = new Label("with_try");
+- method.label(tryLabel);
+- method.loadCompilerConstant(SCOPE);
+- } else {
+- tryLabel = null;
+- }
+-
+- load(expression, Type.OBJECT);
+-
+- if (hasScope) {
+ // Construct a WithObject if we have a scope
+ method.invoke(ScriptRuntime.OPEN_WITH);
+ method.storeCompilerConstant(SCOPE);
++ tryLabel = new Label("with_try");
++ method.label(tryLabel);
+ } else {
+ // We just loaded the expression for its side effect and to check
+ // for null or undefined value.
+ globalCheckObjectCoercible();
+- }
+-
++ tryLabel = null;
++ }
+
+ // Always process body
+ body.accept(this);
+@@ -2262,62 +3390,78 @@
+ final Label catchLabel = new Label("with_catch");
+ final Label exitLabel = new Label("with_exit");
+
+- if (!body.isTerminal()) {
+- closeWith();
+- method._goto(exitLabel);
+- }
+-
+ method.label(endLabel);
+-
+- method._catch(catchLabel);
+- closeWith();
+- method.athrow();
+-
+- method.label(exitLabel);
+-
+- method._try(tryLabel, endLabel, catchLabel);
++ // Somewhat conservatively presume that if the body is not empty, it can throw an exception. In any case,
++ // we must prevent trying to emit a try-catch for empty range, as it causes a verification error.
++ final boolean bodyCanThrow = endLabel.isAfter(tryLabel);
++ if(bodyCanThrow) {
++ method._try(tryLabel, endLabel, catchLabel);
++ }
++
++ final boolean reachable = method.isReachable();
++ if(reachable) {
++ popScope();
++ if(bodyCanThrow) {
++ method._goto(exitLabel);
++ }
++ }
++
++ if(bodyCanThrow) {
++ method._catch(catchLabel);
++ popScopeException();
++ method.athrow();
++ if(reachable) {
++ method.label(exitLabel);
++ }
++ }
+ }
+ return false;
+ }
+
+- @Override
+- public boolean enterADD(final UnaryNode unaryNode) {
+- load(unaryNode.rhs(), unaryNode.getType());
+- assert unaryNode.getType().isNumeric();
+- method.store(unaryNode.getSymbol());
+- return false;
++ private void loadADD(final UnaryNode unaryNode, final TypeBounds resultBounds) {
++ loadExpression(unaryNode.getExpression(), resultBounds.booleanToInt().notWiderThan(Type.NUMBER));
++ if(method.peekType() == Type.BOOLEAN) {
++ // It's a no-op in bytecode, but we must make sure it is treated as an int for purposes of type signatures
++ method.convert(Type.INT);
++ }
+ }
+
+- @Override
+- public boolean enterBIT_NOT(final UnaryNode unaryNode) {
+- load(unaryNode.rhs(), Type.INT).load(-1).xor().store(unaryNode.getSymbol());
+- return false;
++ private void loadBIT_NOT(final UnaryNode unaryNode) {
++ loadExpression(unaryNode.getExpression(), TypeBounds.INT).load(-1).xor();
+ }
+
+- @Override
+- public boolean enterDECINC(final UnaryNode unaryNode) {
+- final Expression rhs = unaryNode.rhs();
++ private void loadDECINC(final UnaryNode unaryNode) {
++ final Expression operand = unaryNode.getExpression();
+ final Type type = unaryNode.getType();
++ final TypeBounds typeBounds = new TypeBounds(type, Type.NUMBER);
+ final TokenType tokenType = unaryNode.tokenType();
+ final boolean isPostfix = tokenType == TokenType.DECPOSTFIX || tokenType == TokenType.INCPOSTFIX;
+ final boolean isIncrement = tokenType == TokenType.INCPREFIX || tokenType == TokenType.INCPOSTFIX;
+
+ assert !type.isObject();
+
+- new SelfModifyingStore<UnaryNode>(unaryNode, rhs) {
++ new SelfModifyingStore<UnaryNode>(unaryNode, operand) {
++
++ private void loadRhs() {
++ loadExpression(operand, typeBounds, true);
++ }
+
+ @Override
+ protected void evaluate() {
+- load(rhs, type, true);
+- if (!isPostfix) {
+- if (type.isInteger()) {
+- method.load(isIncrement ? 1 : -1);
+- } else if (type.isLong()) {
+- method.load(isIncrement ? 1L : -1L);
+- } else {
+- method.load(isIncrement ? 1.0 : -1.0);
+- }
+- method.add();
++ if(isPostfix) {
++ loadRhs();
++ } else {
++ new OptimisticOperation(unaryNode, typeBounds) {
++ @Override
++ void loadStack() {
++ loadRhs();
++ loadMinusOne();
++ }
++ @Override
++ void consumeStack() {
++ doDecInc(getProgramPoint());
++ }
++ }.emit(getOptimisticIgnoreCountForSelfModifyingExpression(operand));
+ }
+ }
+
+@@ -2325,448 +3469,485 @@
+ protected void storeNonDiscard() {
+ super.storeNonDiscard();
+ if (isPostfix) {
+- if (type.isInteger()) {
+- method.load(isIncrement ? 1 : -1);
+- } else if (type.isLong()) {
+- method.load(isIncrement ? 1L : 1L);
+- } else {
+- method.load(isIncrement ? 1.0 : -1.0);
+- }
+- method.add();
++ new OptimisticOperation(unaryNode, typeBounds) {
++ @Override
++ void loadStack() {
++ loadMinusOne();
++ }
++ @Override
++ void consumeStack() {
++ doDecInc(getProgramPoint());
++ }
++ }.emit(1); // 1 for non-incremented result on the top of the stack pushed in evaluate()
+ }
+ }
++
++ private void loadMinusOne() {
++ if (type.isInteger()) {
++ method.load(isIncrement ? 1 : -1);
++ } else if (type.isLong()) {
++ method.load(isIncrement ? 1L : -1L);
++ } else {
++ method.load(isIncrement ? 1.0 : -1.0);
++ }
++ }
++
++ private void doDecInc(final int programPoint) {
++ method.add(programPoint);
++ }
+ }.store();
+-
+- return false;
+ }
+
+- @Override
+- public boolean enterDISCARD(final UnaryNode unaryNode) {
+- final Expression rhs = unaryNode.rhs();
+-
+- lc.pushDiscard(rhs);
+- load(rhs);
+-
+- if (lc.getCurrentDiscard() == rhs) {
+- assert !rhs.isAssignment();
++ private static int getOptimisticIgnoreCountForSelfModifyingExpression(final Expression target) {
++ return target instanceof AccessNode ? 1 : target instanceof IndexNode ? 2 : 0;
++ }
++
++ private void loadAndDiscard(final Expression expr) {
++ // TODO: move checks for discarding to actual expression load code (e.g. as we do with void). That way we might
++ // be able to eliminate even more checks.
++ if(expr instanceof PrimitiveLiteralNode | isLocalVariable(expr)) {
++ assert lc.getCurrentDiscard() != expr;
++ // Don't bother evaluating expressions without side effects. Typical usage is "void 0" for reliably generating
++ // undefined.
++ return;
++ }
++
++ lc.pushDiscard(expr);
++ loadExpression(expr, TypeBounds.UNBOUNDED);
++ if (lc.getCurrentDiscard() == expr) {
++ assert !expr.isAssignment();
++ // NOTE: if we had a way to load with type void, we could avoid popping
+ method.pop();
+ lc.popDiscard();
+ }
+-
+- return false;
+ }
+
+- @Override
+- public boolean enterNEW(final UnaryNode unaryNode) {
+- final CallNode callNode = (CallNode)unaryNode.rhs();
++ private void loadNEW(final UnaryNode unaryNode) {
++ final CallNode callNode = (CallNode)unaryNode.getExpression();
+ final List<Expression> args = callNode.getArgs();
+
+ // Load function reference.
+- load(callNode.getFunction(), Type.OBJECT); // must detect type error
++ loadExpressionAsObject(callNode.getFunction()); // must detect type error
+
+ method.dynamicNew(1 + loadArgs(args), getCallSiteFlags());
+- method.store(unaryNode.getSymbol());
+-
+- return false;
+ }
+
+- @Override
+- public boolean enterNOT(final UnaryNode unaryNode) {
+- final Expression rhs = unaryNode.rhs();
+-
+- load(rhs, Type.BOOLEAN);
+-
+- final Label trueLabel = new Label("true");
+- final Label afterLabel = new Label("after");
+-
+- method.ifne(trueLabel);
+- method.load(true);
+- method._goto(afterLabel);
+- method.label(trueLabel);
+- method.load(false);
+- method.label(afterLabel);
+- method.store(unaryNode.getSymbol());
+-
+- return false;
++ private void loadNOT(final UnaryNode unaryNode) {
++ final Expression expr = unaryNode.getExpression();
++ if(expr instanceof UnaryNode && expr.isTokenType(TokenType.NOT)) {
++ // !!x is idiomatic boolean cast in JavaScript
++ loadExpressionAsBoolean(((UnaryNode)expr).getExpression());
++ } else {
++ final Label trueLabel = new Label("true");
++ final Label afterLabel = new Label("after");
++
++ emitBranch(expr, trueLabel, true);
++ method.load(true);
++ method._goto(afterLabel);
++ method.label(trueLabel);
++ method.load(false);
++ method.label(afterLabel);
++ }
+ }
+
+- @Override
+- public boolean enterSUB(final UnaryNode unaryNode) {
+- assert unaryNode.getType().isNumeric();
+- load(unaryNode.rhs(), unaryNode.getType()).neg().store(unaryNode.getSymbol());
+- return false;
++ private void loadSUB(final UnaryNode unaryNode, final TypeBounds resultBounds) {
++ final Type type = unaryNode.getType();
++ assert type.isNumeric();
++ final TypeBounds numericBounds = resultBounds.booleanToInt();
++ new OptimisticOperation(unaryNode, numericBounds) {
++ @Override
++ void loadStack() {
++ final Expression expr = unaryNode.getExpression();
++ loadExpression(expr, numericBounds.notWiderThan(Type.NUMBER));
++ }
++ @Override
++ void consumeStack() {
++ // Must do an explicit conversion to the operation's type when it's double so that we correctly handle
++ // negation of an int 0 to a double -0. With this, we get the correct negation of a local variable after
++ // it deoptimized, e.g. "iload_2; i2d; dneg". Without this, we get "iload_2; ineg; i2d".
++ if(type.isNumber()) {
++ method.convert(type);
++ }
++ method.neg(getProgramPoint());
++ }
++ }.emit();
+ }
+
+- @Override
+- public boolean enterVOID(final UnaryNode unaryNode) {
+- load(unaryNode.rhs()).pop();
+- method.loadUndefined(Type.OBJECT);
+-
+- return false;
++ public void loadVOID(final UnaryNode unaryNode, final TypeBounds resultBounds) {
++ loadAndDiscard(unaryNode.getExpression());
++ if(lc.getCurrentDiscard() == unaryNode) {
++ lc.popDiscard();
++ } else {
++ method.loadUndefined(resultBounds.widest);
++ }
+ }
+
+- private void enterNumericAdd(final Expression lhs, final Expression rhs, final Type type, final Symbol symbol) {
+- loadBinaryOperands(lhs, rhs, type);
+- method.add(); //if the symbol is optimistic, it always needs to be written, not on the stack?
+- method.store(symbol);
++ public void loadADD(final BinaryNode binaryNode, final TypeBounds resultBounds) {
++ new OptimisticOperation(binaryNode, resultBounds) {
++ @Override
++ void loadStack() {
++ final TypeBounds operandBounds;
++ final boolean isOptimistic = isValid(getProgramPoint());
++ boolean forceConversionSeparation = false;
++ if(isOptimistic) {
++ operandBounds = new TypeBounds(binaryNode.getType(), Type.OBJECT);
++ } else {
++ // Non-optimistic, non-FP +. Allow it to overflow.
++ final Type widestOperationType = binaryNode.getWidestOperationType();
++ operandBounds = new TypeBounds(Type.narrowest(binaryNode.getWidestOperandType(), resultBounds.widest), widestOperationType);
++ forceConversionSeparation = widestOperationType.narrowerThan(resultBounds.widest);
++ }
++ loadBinaryOperands(binaryNode.lhs(), binaryNode.rhs(), operandBounds, false, forceConversionSeparation);
++ }
++
++ @Override
++ void consumeStack() {
++ method.add(getProgramPoint());
++ }
++ }.emit();
+ }
+
+- @Override
+- public boolean enterADD(final BinaryNode binaryNode) {
++ private void loadAND_OR(final BinaryNode binaryNode, final TypeBounds resultBounds, final boolean isAnd) {
++ final Type narrowestOperandType = Type.widestReturnType(binaryNode.lhs().getType(), binaryNode.rhs().getType());
++
++ final Label skip = new Label("skip");
++ if(narrowestOperandType == Type.BOOLEAN) {
++ // optimize all-boolean logical expressions
++ final Label onTrue = new Label("andor_true");
++ emitBranch(binaryNode, onTrue, true);
++ method.load(false);
++ method._goto(skip);
++ method.label(onTrue);
++ method.load(true);
++ method.label(skip);
++ return;
++ }
++
++ final TypeBounds outBounds = resultBounds.notNarrowerThan(narrowestOperandType);
++ final JoinPredecessorExpression lhs = (JoinPredecessorExpression)binaryNode.lhs();
++ final boolean lhsConvert = LocalVariableConversion.hasLiveConversion(lhs);
++ final Label evalRhs = lhsConvert ? new Label("eval_rhs") : null;
++
++ loadExpression(lhs, outBounds).dup().convert(Type.BOOLEAN);
++ if (isAnd) {
++ if(lhsConvert) {
++ method.ifne(evalRhs);
++ } else {
++ method.ifeq(skip);
++ }
++ } else if(lhsConvert) {
++ method.ifeq(evalRhs);
++ } else {
++ method.ifne(skip);
++ }
++
++ if(lhsConvert) {
++ method.beforeJoinPoint(lhs);
++ method._goto(skip);
++ method.label(evalRhs);
++ }
++
++ method.pop();
++ final JoinPredecessorExpression rhs = (JoinPredecessorExpression)binaryNode.rhs();
++ loadExpression(rhs, outBounds);
++ method.beforeJoinPoint(rhs);
++ method.label(skip);
++ }
++
++ private static boolean isLocalVariable(final Expression lhs) {
++ return lhs instanceof IdentNode && isLocalVariable((IdentNode)lhs);
++ }
++
++ private static boolean isLocalVariable(final IdentNode lhs) {
++ return lhs.getSymbol().isBytecodeLocal();
++ }
++
++ // NOTE: does not use resultBounds as the assignment is driven by the type of the RHS
++ private void loadASSIGN(final BinaryNode binaryNode) {
+ final Expression lhs = binaryNode.lhs();
+ final Expression rhs = binaryNode.rhs();
+
+- final Type type = binaryNode.getType();
+- if (type.isNumeric()) {
+- enterNumericAdd(lhs, rhs, type, binaryNode.getSymbol());
+- } else {
+- loadBinaryOperands(binaryNode);
+- method.add();
+- method.store(binaryNode.getSymbol());
+- }
+-
+- return false;
+- }
+-
+- private boolean enterAND_OR(final BinaryNode binaryNode) {
+- final Expression lhs = binaryNode.lhs();
+- final Expression rhs = binaryNode.rhs();
+-
+- final Label skip = new Label("skip");
+-
+- load(lhs, Type.OBJECT).dup().convert(Type.BOOLEAN);
+-
+- if (binaryNode.tokenType() == TokenType.AND) {
+- method.ifeq(skip);
+- } else {
+- method.ifne(skip);
+- }
+-
+- method.pop();
+- load(rhs, Type.OBJECT);
+- method.label(skip);
+- method.store(binaryNode.getSymbol());
+-
+- return false;
+- }
+-
+- @Override
+- public boolean enterAND(final BinaryNode binaryNode) {
+- return enterAND_OR(binaryNode);
+- }
+-
+- @Override
+- public boolean enterASSIGN(final BinaryNode binaryNode) {
+- final Expression lhs = binaryNode.lhs();
+- final Expression rhs = binaryNode.rhs();
+-
+- final Type lhsType = lhs.getType();
+ final Type rhsType = rhs.getType();
+-
+- if (!lhsType.isEquivalentTo(rhsType)) {
+- //this is OK if scoped, only locals are wrong
++ // Detect dead assignments
++ if(lhs instanceof IdentNode) {
++ final Symbol symbol = ((IdentNode)lhs).getSymbol();
++ if(!symbol.isScope() && !symbol.hasSlotFor(rhsType) && lc.getCurrentDiscard() == binaryNode) {
++ loadAndDiscard(rhs);
++ lc.popDiscard();
++ method.markDeadLocalVariable(symbol);
++ return;
++ }
+ }
+
+ new Store<BinaryNode>(binaryNode, lhs) {
+ @Override
+ protected void evaluate() {
+- if ((lhs instanceof IdentNode) && !lhs.getSymbol().isScope()) {
+- load(rhs, lhsType);
+- } else {
+- load(rhs);
+- }
++ // NOTE: we're loading with "at least as wide as" so optimistic operations on the right hand side
++ // remain optimistic, and then explicitly convert to the required type if needed.
++ loadExpressionAsType(rhs, rhsType);
+ }
+ }.store();
+-
+- return false;
+ }
+
+ /**
+- * Helper class for assignment ops, e.g. *=, += and so on..
++ * Binary self-assignment that can be optimistic: +=, -=, *=, and /=.
+ */
+- private abstract class AssignOp extends SelfModifyingStore<BinaryNode> {
+-
+- /** The type of the resulting operation */
+- private final Type opType;
++ private abstract class BinaryOptimisticSelfAssignment extends SelfModifyingStore<BinaryNode> {
+
+ /**
+ * Constructor
+ *
+ * @param node the assign op node
+ */
+- AssignOp(final BinaryNode node) {
+- this(node.getType(), node);
+- }
+-
+- /**
+- * Constructor
+- *
+- * @param opType type of the computation - overriding the type of the node
+- * @param node the assign op node
+- */
+- AssignOp(final Type opType, final BinaryNode node) {
++ BinaryOptimisticSelfAssignment(final BinaryNode node) {
+ super(node, node.lhs());
+- this.opType = opType;
+- }
+-
+- protected abstract void op();
++ }
++
++ protected abstract void op(OptimisticOperation oo);
+
+ @Override
+ protected void evaluate() {
+- loadBinaryOperands(assignNode.lhs(), assignNode.rhs(), opType, true);
++ final Expression lhs = assignNode.lhs();
++ final Expression rhs = assignNode.rhs();
++ final Type widestOperationType = assignNode.getWidestOperationType();
++ final TypeBounds bounds = new TypeBounds(assignNode.getType(), widestOperationType);
++ new OptimisticOperation(assignNode, bounds) {
++ @Override
++ void loadStack() {
++ final boolean forceConversionSeparation;
++ if (isValid(getProgramPoint()) || widestOperationType == Type.NUMBER) {
++ forceConversionSeparation = false;
++ } else {
++ final Type operandType = Type.widest(booleanToInt(objectToNumber(lhs.getType())), booleanToInt(objectToNumber(rhs.getType())));
++ forceConversionSeparation = operandType.narrowerThan(widestOperationType);
++ }
++ loadBinaryOperands(lhs, rhs, bounds, true, forceConversionSeparation);
++ }
++ @Override
++ void consumeStack() {
++ op(this);
++ }
++ }.emit(getOptimisticIgnoreCountForSelfModifyingExpression(lhs));
++ method.convert(assignNode.getType());
++ }
++ }
++
++ /**
++ * Non-optimistic binary self-assignment operation. Basically, everything except +=, -=, *=, and /=.
++ */
++ private abstract class BinarySelfAssignment extends SelfModifyingStore<BinaryNode> {
++ BinarySelfAssignment(final BinaryNode node) {
++ super(node, node.lhs());
++ }
++
++ protected abstract void op();
++
++ @Override
++ protected void evaluate() {
++ loadBinaryOperands(assignNode.lhs(), assignNode.rhs(), TypeBounds.UNBOUNDED.notWiderThan(assignNode.getWidestOperandType()), true, false);
+ op();
+- method.convert(assignNode.getType());
+ }
+ }
+
+- @Override
+- public boolean enterASSIGN_ADD(final BinaryNode binaryNode) {
+- assert RuntimeNode.Request.ADD.canSpecialize();
+- final Type lhsType = binaryNode.lhs().getType();
+- final Type rhsType = binaryNode.rhs().getType();
+- final boolean specialize = binaryNode.getType() == Type.OBJECT;
+-
+- new AssignOp(binaryNode) {
+-
++ private void loadASSIGN_ADD(final BinaryNode binaryNode) {
++ new BinaryOptimisticSelfAssignment(binaryNode) {
+ @Override
+- protected void op() {
+- if (specialize) {
+- method.dynamicRuntimeCall(
+- new SpecializedRuntimeNode(
+- Request.ADD,
+- new Type[] {
+- lhsType,
+- rhsType,
+- },
+- Type.OBJECT).getInitialName(),
+- Type.OBJECT,
+- Request.ADD);
+- } else {
+- method.add();
+- }
+- }
+-
+- @Override
+- protected void evaluate() {
+- super.evaluate();
++ protected void op(final OptimisticOperation oo) {
++ assert !(binaryNode.getType().isObject() && oo.isOptimistic);
++ method.add(oo.getProgramPoint());
+ }
+ }.store();
+-
+- return false;
+ }
+
+- @Override
+- public boolean enterASSIGN_BIT_AND(final BinaryNode binaryNode) {
+- new AssignOp(Type.INT, binaryNode) {
++ private void loadASSIGN_BIT_AND(final BinaryNode binaryNode) {
++ new BinarySelfAssignment(binaryNode) {
+ @Override
+ protected void op() {
+ method.and();
+ }
+ }.store();
+-
+- return false;
+ }
+
+- @Override
+- public boolean enterASSIGN_BIT_OR(final BinaryNode binaryNode) {
+- new AssignOp(Type.INT, binaryNode) {
++ private void loadASSIGN_BIT_OR(final BinaryNode binaryNode) {
++ new BinarySelfAssignment(binaryNode) {
+ @Override
+ protected void op() {
+ method.or();
+ }
+ }.store();
+-
+- return false;
+ }
+
+- @Override
+- public boolean enterASSIGN_BIT_XOR(final BinaryNode binaryNode) {
+- new AssignOp(Type.INT, binaryNode) {
++ private void loadASSIGN_BIT_XOR(final BinaryNode binaryNode) {
++ new BinarySelfAssignment(binaryNode) {
+ @Override
+ protected void op() {
+ method.xor();
+ }
+ }.store();
+-
+- return false;
+ }
+
+- @Override
+- public boolean enterASSIGN_DIV(final BinaryNode binaryNode) {
+- new AssignOp(binaryNode) {
++ private void loadASSIGN_DIV(final BinaryNode binaryNode) {
++ new BinaryOptimisticSelfAssignment(binaryNode) {
+ @Override
+- protected void op() {
+- method.div();
++ protected void op(final OptimisticOperation oo) {
++ method.div(oo.getProgramPoint());
+ }
+ }.store();
+-
+- return false;
+ }
+
+- @Override
+- public boolean enterASSIGN_MOD(final BinaryNode binaryNode) {
+- new AssignOp(binaryNode) {
++ private void loadASSIGN_MOD(final BinaryNode binaryNode) {
++ new BinaryOptimisticSelfAssignment(binaryNode) {
+ @Override
+- protected void op() {
+- method.rem();
++ protected void op(final OptimisticOperation oo) {
++ method.rem(oo.getProgramPoint());
+ }
+ }.store();
+-
+- return false;
+ }
+
+- @Override
+- public boolean enterASSIGN_MUL(final BinaryNode binaryNode) {
+- new AssignOp(binaryNode) {
++ private void loadASSIGN_MUL(final BinaryNode binaryNode) {
++ new BinaryOptimisticSelfAssignment(binaryNode) {
+ @Override
+- protected void op() {
+- method.mul();
++ protected void op(final OptimisticOperation oo) {
++ method.mul(oo.getProgramPoint());
+ }
+ }.store();
+-
+- return false;
+ }
+
+- @Override
+- public boolean enterASSIGN_SAR(final BinaryNode binaryNode) {
+- new AssignOp(Type.INT, binaryNode) {
++ private void loadASSIGN_SAR(final BinaryNode binaryNode) {
++ new BinarySelfAssignment(binaryNode) {
+ @Override
+ protected void op() {
+ method.sar();
+ }
+ }.store();
+-
+- return false;
+ }
+
+- @Override
+- public boolean enterASSIGN_SHL(final BinaryNode binaryNode) {
+- new AssignOp(Type.INT, binaryNode) {
++ private void loadASSIGN_SHL(final BinaryNode binaryNode) {
++ new BinarySelfAssignment(binaryNode) {
+ @Override
+ protected void op() {
+ method.shl();
+ }
+ }.store();
+-
+- return false;
+ }
+
+- @Override
+- public boolean enterASSIGN_SHR(final BinaryNode binaryNode) {
+- new AssignOp(Type.INT, binaryNode) {
++ private void loadASSIGN_SHR(final BinaryNode binaryNode) {
++ new BinarySelfAssignment(binaryNode) {
+ @Override
+ protected void op() {
+- method.shr();
+- method.convert(Type.LONG).load(JSType.MAX_UINT).and();
+- }
++ doSHR();
++ }
++
+ }.store();
+-
+- return false;
+ }
+
+- @Override
+- public boolean enterASSIGN_SUB(final BinaryNode binaryNode) {
+- new AssignOp(binaryNode) {
++ private void doSHR() {
++ // TODO: make SHR optimistic
++ method.shr();
++ toUint();
++ }
++
++ private void toUint() {
++ JSType.TO_UINT32_I.invoke(method);
++ }
++
++ private void loadASSIGN_SUB(final BinaryNode binaryNode) {
++ new BinaryOptimisticSelfAssignment(binaryNode) {
+ @Override
+- protected void op() {
+- method.sub();
++ protected void op(final OptimisticOperation oo) {
++ method.sub(oo.getProgramPoint());
+ }
+ }.store();
+-
+- return false;
+ }
+
+ /**
+ * Helper class for binary arithmetic ops
+ */
+ private abstract class BinaryArith {
+-
+- protected abstract void op();
+-
+- protected void evaluate(final BinaryNode node) {
+- loadBinaryOperands(node);
+- op();
+- method.store(node.getSymbol());
++ protected abstract void op(int programPoint);
++
++ protected void evaluate(final BinaryNode node, final TypeBounds resultBounds) {
++ final TypeBounds numericBounds = resultBounds.booleanToInt().objectToNumber();
++ new OptimisticOperation(node, numericBounds) {
++ @Override
++ void loadStack() {
++ final TypeBounds operandBounds;
++ boolean forceConversionSeparation = false;
++ if(numericBounds.narrowest == Type.NUMBER) {
++ // Result should be double always. Propagate it into the operands so we don't have lots of I2D
++ // and L2D after operand evaluation.
++ assert numericBounds.widest == Type.NUMBER;
++ operandBounds = numericBounds;
++ } else {
++ final boolean isOptimistic = isValid(getProgramPoint());
++ if(isOptimistic || node.isTokenType(TokenType.DIV) || node.isTokenType(TokenType.MOD)) {
++ operandBounds = new TypeBounds(node.getType(), Type.NUMBER);
++ } else {
++ // Non-optimistic, non-FP subtraction or multiplication. Allow them to overflow.
++ operandBounds = new TypeBounds(Type.narrowest(node.getWidestOperandType(),
++ numericBounds.widest), Type.NUMBER);
++ forceConversionSeparation = node.getWidestOperationType().narrowerThan(numericBounds.widest);
++ }
++ }
++ loadBinaryOperands(node.lhs(), node.rhs(), operandBounds, false, forceConversionSeparation);
++ }
++
++ @Override
++ void consumeStack() {
++ op(getProgramPoint());
++ }
++ }.emit();
+ }
+ }
+
+- @Override
+- public boolean enterBIT_AND(final BinaryNode binaryNode) {
++ private void loadBIT_AND(final BinaryNode binaryNode) {
++ loadBinaryOperands(binaryNode);
++ method.and();
++ }
++
++ private void loadBIT_OR(final BinaryNode binaryNode) {
++ // Optimize x|0 to (int)x
++ if (isRhsZero(binaryNode)) {
++ loadExpressionAsType(binaryNode.lhs(), Type.INT);
++ } else {
++ loadBinaryOperands(binaryNode);
++ method.or();
++ }
++ }
++
++ private static boolean isRhsZero(final BinaryNode binaryNode) {
++ final Expression rhs = binaryNode.rhs();
++ return rhs instanceof LiteralNode && INT_ZERO.equals(((LiteralNode<?>)rhs).getValue());
++ }
++
++ private void loadBIT_XOR(final BinaryNode binaryNode) {
++ loadBinaryOperands(binaryNode);
++ method.xor();
++ }
++
++ private void loadCOMMARIGHT(final BinaryNode binaryNode, final TypeBounds resultBounds) {
++ loadAndDiscard(binaryNode.lhs());
++ loadExpression(binaryNode.rhs(), resultBounds);
++ }
++
++ private void loadCOMMALEFT(final BinaryNode binaryNode, final TypeBounds resultBounds) {
++ loadExpression(binaryNode.lhs(), resultBounds);
++ loadAndDiscard(binaryNode.rhs());
++ }
++
++ private void loadDIV(final BinaryNode binaryNode, final TypeBounds resultBounds) {
+ new BinaryArith() {
+ @Override
+- protected void op() {
+- method.and();
+- }
+- }.evaluate(binaryNode);
+-
+- return false;
++ protected void op(final int programPoint) {
++ method.div(programPoint);
++ }
++ }.evaluate(binaryNode, resultBounds);
+ }
+
+- @Override
+- public boolean enterBIT_OR(final BinaryNode binaryNode) {
+- new BinaryArith() {
+- @Override
+- protected void op() {
+- method.or();
+- }
+- }.evaluate(binaryNode);
+-
+- return false;
+- }
+-
+- @Override
+- public boolean enterBIT_XOR(final BinaryNode binaryNode) {
+- new BinaryArith() {
+- @Override
+- protected void op() {
+- method.xor();
+- }
+- }.evaluate(binaryNode);
+-
+- return false;
+- }
+-
+- private boolean enterComma(final BinaryNode binaryNode) {
+- final Expression lhs = binaryNode.lhs();
+- final Expression rhs = binaryNode.rhs();
+-
+- load(lhs);
+- load(rhs);
+- method.store(binaryNode.getSymbol());
+-
+- return false;
+- }
+-
+- @Override
+- public boolean enterCOMMARIGHT(final BinaryNode binaryNode) {
+- return enterComma(binaryNode);
+- }
+-
+- @Override
+- public boolean enterCOMMALEFT(final BinaryNode binaryNode) {
+- return enterComma(binaryNode);
+- }
+-
+- @Override
+- public boolean enterDIV(final BinaryNode binaryNode) {
+- new BinaryArith() {
+- @Override
+- protected void op() {
+- method.div();
+- }
+- }.evaluate(binaryNode);
+-
+- return false;
+- }
+-
+- private boolean enterCmp(final Expression lhs, final Expression rhs, final Condition cond, final Type type, final Symbol symbol) {
+- final Type lhsType = lhs.getType();
+- final Type rhsType = rhs.getType();
+-
+- final Type widest = Type.widest(lhsType, rhsType);
+- assert widest.isNumeric() || widest.isBoolean() : widest;
+-
+- loadBinaryOperands(lhs, rhs, widest);
++ private void loadCmp(final BinaryNode binaryNode, final Condition cond) {
++ assert comparisonOperandsArePrimitive(binaryNode) : binaryNode;
++ loadBinaryOperands(binaryNode);
++
+ final Label trueLabel = new Label("trueLabel");
+ final Label afterLabel = new Label("skip");
+
+@@ -2777,177 +3958,100 @@
+ method.label(trueLabel);
+ method.load(Boolean.TRUE);
+ method.label(afterLabel);
+-
+- method.convert(type);
+- method.store(symbol);
+-
+- return false;
+ }
+
+- private boolean enterCmp(final BinaryNode binaryNode, final Condition cond) {
+- return enterCmp(binaryNode.lhs(), binaryNode.rhs(), cond, binaryNode.getType(), binaryNode.getSymbol());
++ private static boolean comparisonOperandsArePrimitive(final BinaryNode binaryNode) {
++ final Type widest = Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType());
++ return widest.isNumeric() || widest.isBoolean();
+ }
+
+- @Override
+- public boolean enterEQ(final BinaryNode binaryNode) {
+- return enterCmp(binaryNode, Condition.EQ);
+- }
+-
+- @Override
+- public boolean enterEQ_STRICT(final BinaryNode binaryNode) {
+- return enterCmp(binaryNode, Condition.EQ);
+- }
+-
+- @Override
+- public boolean enterGE(final BinaryNode binaryNode) {
+- return enterCmp(binaryNode, Condition.GE);
+- }
+-
+- @Override
+- public boolean enterGT(final BinaryNode binaryNode) {
+- return enterCmp(binaryNode, Condition.GT);
+- }
+-
+- @Override
+- public boolean enterLE(final BinaryNode binaryNode) {
+- return enterCmp(binaryNode, Condition.LE);
+- }
+-
+- @Override
+- public boolean enterLT(final BinaryNode binaryNode) {
+- return enterCmp(binaryNode, Condition.LT);
+- }
+-
+- @Override
+- public boolean enterMOD(final BinaryNode binaryNode) {
++ private void loadMOD(final BinaryNode binaryNode, final TypeBounds resultBounds) {
+ new BinaryArith() {
+ @Override
+- protected void op() {
+- method.rem();
+- }
+- }.evaluate(binaryNode);
+-
+- return false;
++ protected void op(final int programPoint) {
++ method.rem(programPoint);
++ }
++ }.evaluate(binaryNode, resultBounds);
+ }
+
+- @Override
+- public boolean enterMUL(final BinaryNode binaryNode) {
++ private void loadMUL(final BinaryNode binaryNode, final TypeBounds resultBounds) {
+ new BinaryArith() {
+ @Override
+- protected void op() {
+- method.mul();
+- }
+- }.evaluate(binaryNode);
+-
+- return false;
++ protected void op(final int programPoint) {
++ method.mul(programPoint);
++ }
++ }.evaluate(binaryNode, resultBounds);
+ }
+
+- @Override
+- public boolean enterNE(final BinaryNode binaryNode) {
+- return enterCmp(binaryNode, Condition.NE);
++ private void loadSAR(final BinaryNode binaryNode) {
++ loadBinaryOperands(binaryNode);
++ method.sar();
+ }
+
+- @Override
+- public boolean enterNE_STRICT(final BinaryNode binaryNode) {
+- return enterCmp(binaryNode, Condition.NE);
++ private void loadSHL(final BinaryNode binaryNode) {
++ loadBinaryOperands(binaryNode);
++ method.shl();
+ }
+
+- @Override
+- public boolean enterOR(final BinaryNode binaryNode) {
+- return enterAND_OR(binaryNode);
++ private void loadSHR(final BinaryNode binaryNode) {
++ // Optimize x >>> 0 to (uint)x
++ if (isRhsZero(binaryNode)) {
++ loadExpressionAsType(binaryNode.lhs(), Type.INT);
++ toUint();
++ } else {
++ loadBinaryOperands(binaryNode);
++ doSHR();
++ }
+ }
+
+- @Override
+- public boolean enterSAR(final BinaryNode binaryNode) {
++ private void loadSUB(final BinaryNode binaryNode, final TypeBounds resultBounds) {
+ new BinaryArith() {
+ @Override
+- protected void op() {
+- method.sar();
+- }
+- }.evaluate(binaryNode);
+-
+- return false;
++ protected void op(final int programPoint) {
++ method.sub(programPoint);
++ }
++ }.evaluate(binaryNode, resultBounds);
+ }
+
+ @Override
+- public boolean enterSHL(final BinaryNode binaryNode) {
+- new BinaryArith() {
+- @Override
+- protected void op() {
+- method.shl();
+- }
+- }.evaluate(binaryNode);
+-
+- return false;
++ public boolean enterLabelNode(final LabelNode labelNode) {
++ labeledBlockBreakLiveLocals.push(lc.getUsedSlotCount());
++ return true;
+ }
+
+ @Override
+- public boolean enterSHR(final BinaryNode binaryNode) {
+- new BinaryArith() {
+- @Override
+- protected void evaluate(final BinaryNode node) {
+- loadBinaryOperands(node.lhs(), node.rhs(), Type.INT);
+- op();
+- method.store(node.getSymbol());
+- }
+- @Override
+- protected void op() {
+- method.shr();
+- method.convert(Type.LONG).load(JSType.MAX_UINT).and();
+- }
+- }.evaluate(binaryNode);
+-
+- return false;
++ protected boolean enterDefault(final Node node) {
++ throw new AssertionError("Code generator entered node of type " + node.getClass().getName());
+ }
+
+- @Override
+- public boolean enterSUB(final BinaryNode binaryNode) {
+- new BinaryArith() {
+- @Override
+- protected void op() {
+- method.sub();
+- }
+- }.evaluate(binaryNode);
+-
+- return false;
+- }
+-
+- @Override
+- public boolean enterTernaryNode(final TernaryNode ternaryNode) {
+- final Expression test = ternaryNode.getTest();
+- final Expression trueExpr = ternaryNode.getTrueExpression();
+- final Expression falseExpr = ternaryNode.getFalseExpression();
+-
+- final Symbol symbol = ternaryNode.getSymbol();
+- final Label falseLabel = new Label("ternary_false");
+- final Label exitLabel = new Label("ternary_exit");
+-
+- Type widest = Type.widest(ternaryNode.getType(), Type.widest(trueExpr.getType(), falseExpr.getType()));
+- if (trueExpr.getType().isArray() || falseExpr.getType().isArray()) { //loadArray creates a Java array type on the stack, calls global allocate, which creates a native array type
+- widest = Type.OBJECT;
+- }
+-
+- load(test, Type.BOOLEAN);
+- // we still keep the conversion here as the AccessSpecializer can have separated the types, e.g. var y = x ? x=55 : 17
+- // will left as (Object)x=55 : (Object)17 by Lower. Then the first term can be {I}x=55 of type int, which breaks the
+- // symmetry for the temporary slot for this TernaryNode. This is evidence that we assign types and explicit conversions
+- // too early, or Apply the AccessSpecializer too late. We are mostly probably looking for a separate type pass to
+- // do this property. Then we never need any conversions in CodeGenerator
+- method.ifeq(falseLabel);
+- load(trueExpr, widest);
++ private void loadTernaryNode(final TernaryNode ternaryNode, final TypeBounds resultBounds) {
++ final Expression test = ternaryNode.getTest();
++ final JoinPredecessorExpression trueExpr = ternaryNode.getTrueExpression();
++ final JoinPredecessorExpression falseExpr = ternaryNode.getFalseExpression();
++
++ final Label falseLabel = new Label("ternary_false");
++ final Label exitLabel = new Label("ternary_exit");
++
++ final Type outNarrowest = Type.narrowest(resultBounds.widest, Type.generic(Type.widestReturnType(trueExpr.getType(), falseExpr.getType())));
++ final TypeBounds outBounds = resultBounds.notNarrowerThan(outNarrowest);
++
++ emitBranch(test, falseLabel, false);
++
++ loadExpression(trueExpr.getExpression(), outBounds);
++ assert Type.generic(method.peekType()) == outBounds.narrowest;
++ method.beforeJoinPoint(trueExpr);
+ method._goto(exitLabel);
+ method.label(falseLabel);
+- load(falseExpr, widest);
++ loadExpression(falseExpr.getExpression(), outBounds);
++ assert Type.generic(method.peekType()) == outBounds.narrowest;
++ method.beforeJoinPoint(falseExpr);
+ method.label(exitLabel);
+- method.store(symbol);
+-
+- return false;
+ }
+
+ /**
+ * Generate all shared scope calls generated during codegen.
+ */
+- protected void generateScopeCalls() {
++ void generateScopeCalls() {
+ for (final SharedScopeCall scopeAccess : lc.getScopeCalls()) {
+ scopeAccess.generateScopeCall();
+ }
+@@ -2957,20 +4061,18 @@
+ * Debug code used to print symbols
+ *
+ * @param block the block we are in
++ * @param function the function we are in
+ * @param ident identifier for block or function where applicable
+ */
+- @SuppressWarnings("resource")
+- private void printSymbols(final Block block, final String ident) {
+- if (!compiler.getEnv()._print_symbols) {
+- return;
+- }
+-
+- final PrintWriter out = compiler.getEnv().getErr();
+- out.println("[BLOCK in '" + ident + "']");
+- if (!block.printSymbols(out)) {
+- out.println("<no symbols>");
+- }
+- out.println();
++ private void printSymbols(final Block block, final FunctionNode function, final String ident) {
++ if (compiler.getScriptEnvironment()._print_symbols || function.getFlag(FunctionNode.IS_PRINT_SYMBOLS)) {
++ final PrintWriter out = compiler.getScriptEnvironment().getErr();
++ out.println("[BLOCK in '" + ident + "']");
++ if (!block.printSymbols(out)) {
++ out.println("<no symbols>");
++ }
++ out.println();
++ }
+ }
+
+
+@@ -3015,7 +4117,7 @@
+ private int depth;
+
+ /** If we have too many arguments, we need temporary storage, this is stored in 'quick' */
+- private Symbol quick;
++ private IdentNode quick;
+
+ /**
+ * Constructor
+@@ -3046,9 +4148,6 @@
+ }
+
+ private void prologue() {
+- final Symbol targetSymbol = target.getSymbol();
+- final Symbol scopeSymbol = lc.getCurrentFunction().compilerConstant(SCOPE);
+-
+ /**
+ * This loads the parts of the target, e.g base and index. they are kept
+ * on the stack throughout the store and used at the end to execute it
+@@ -3057,9 +4156,10 @@
+ target.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
+ @Override
+ public boolean enterIdentNode(final IdentNode node) {
+- if (targetSymbol.isScope()) {
+- method.load(scopeSymbol);
+- depth++;
++ if (node.getSymbol().isScope()) {
++ method.loadCompilerConstant(SCOPE);
++ depth += Type.SCOPE.getSlots();
++ assert depth == 1;
+ }
+ return false;
+ }
+@@ -3069,8 +4169,9 @@
+ final BaseNode baseNode = (BaseNode)target;
+ final Expression base = baseNode.getBase();
+
+- load(base, Type.OBJECT);
++ loadExpressionAsObject(base);
+ depth += Type.OBJECT.getSlots();
++ assert depth == 1;
+
+ if (isSelfModifying()) {
+ method.dup();
+@@ -3090,9 +4191,9 @@
+ final Expression index = node.getIndex();
+ if (!index.getType().isNumeric()) {
+ // could be boolean here as well
+- load(index, Type.OBJECT);
++ loadExpressionAsObject(index);
+ } else {
+- load(index);
++ loadExpressionUnbounded(index);
+ }
+ depth += index.getType().getSlots();
+
+@@ -3107,28 +4208,23 @@
+ });
+ }
+
+- private Symbol quickSymbol(final Type type) {
+- return quickSymbol(type, QUICK_PREFIX.symbolName());
+- }
+-
+ /**
+- * Quick symbol generates an extra local variable, always using the same
+- * slot, one that is available after the end of the frame.
++ * Generates an extra local variable, always using the same slot, one that is available after the end of the
++ * frame.
+ *
+- * @param type the type of the symbol
+- * @param prefix the prefix for the variable name for the symbol
++ * @param type the type of the variable
+ *
+- * @return the quick symbol
++ * @return the quick variable
+ */
+- private Symbol quickSymbol(final Type type, final String prefix) {
+- final String name = lc.getCurrentFunction().uniqueName(prefix);
+- final Symbol symbol = new Symbol(name, IS_TEMP | IS_INTERNAL);
+-
+- symbol.setType(type);
+-
+- symbol.setSlot(lc.quickSlot(symbol));
+-
+- return symbol;
++ private IdentNode quickLocalVariable(final Type type) {
++ final String name = lc.getCurrentFunction().uniqueName(QUICK_PREFIX.symbolName());
++ final Symbol symbol = new Symbol(name, IS_INTERNAL | HAS_SLOT);
++ symbol.setHasSlotFor(type);
++ symbol.setFirstSlot(lc.quickSlot(type));
++
++ final IdentNode quickIdent = IdentNode.createInternalIdentifier(symbol).setType(type);
++
++ return quickIdent;
+ }
+
+ // store the result that "lives on" after the op, e.g. "i" in i++ postfix.
+@@ -3139,16 +4235,12 @@
+ return;
+ }
+
+- final Symbol symbol = assignNode.getSymbol();
+- if (symbol.hasSlot()) {
+- method.dup().store(symbol);
+- return;
+- }
+-
+ if (method.dup(depth) == null) {
+ method.dup();
+- this.quick = quickSymbol(method.peekType());
+- method.store(quick);
++ final Type quickType = method.peekType();
++ this.quick = quickLocalVariable(quickType);
++ final Symbol quickSymbol = quick.getSymbol();
++ method.storeTemp(quickType, quickSymbol.getFirstSlot());
+ }
+ }
+
+@@ -3163,7 +4255,7 @@
+ */
+ target.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
+ @Override
+- protected boolean enterDefault(Node node) {
++ protected boolean enterDefault(final Node node) {
+ throw new AssertionError("Unexpected node " + node + " in store epilogue");
+ }
+
+@@ -3172,14 +4264,20 @@
+ final Symbol symbol = node.getSymbol();
+ assert symbol != null;
+ if (symbol.isScope()) {
++ final int flags = CALLSITE_SCOPE | getCallSiteFlags();
+ if (isFastScope(symbol)) {
+- storeFastScopeVar(symbol, CALLSITE_SCOPE | getCallSiteFlags());
++ storeFastScopeVar(symbol, flags);
+ } else {
+- method.dynamicSet(node.getName(), CALLSITE_SCOPE | getCallSiteFlags());
++ method.dynamicSet(node.getName(), flags, false);
+ }
+ } else {
+- method.convert(node.getType());
+- method.store(symbol);
++ final Type storeType = assignNode.getType();
++ if (symbol.hasSlotFor(storeType)) {
++ // Only emit a convert for a store known to be live; converts for dead stores can
++ // give us an unnecessary ClassCastException.
++ method.convert(storeType);
++ }
++ storeIdentWithCatchConversion(node, storeType);
+ }
+ return false;
+
+@@ -3187,7 +4285,7 @@
+
+ @Override
+ public boolean enterAccessNode(final AccessNode node) {
+- method.dynamicSet(node.getProperty().getName(), getCallSiteFlags());
++ method.dynamicSet(node.getProperty(), getCallSiteFlags(), node.isIndex());
+ return false;
+ }
+
+@@ -3205,6 +4303,9 @@
+ protected abstract void evaluate();
+
+ void store() {
++ if (target instanceof IdentNode) {
++ checkTemporalDeadZone((IdentNode)target);
++ }
+ prologue();
+ evaluate(); // leaves an operation of whatever the operationType was on the stack
+ storeNonDiscard();
+@@ -3215,35 +4316,44 @@
+ }
+ }
+
+- private void newFunctionObject(final FunctionNode functionNode, final FunctionNode originalFunctionNode) {
++ private void newFunctionObject(final FunctionNode functionNode, final boolean addInitializer) {
+ assert lc.peek() == functionNode;
+- // We don't emit a ScriptFunction on stack for:
+- // 1. the outermost compiled function (as there's no code being generated in its outer context that'd need it
+- // as a callee), and
+- // 2. for functions that are immediately called upon definition and they don't need a callee, e.g. (function(){})().
+- // Such immediately-called functions are invoked using INVOKESTATIC (see enterFunctionNode() of the embedded
+- // visitor of enterCallNode() for details), and if they don't need a callee, they don't have it on their
+- // static method's parameter list.
+- if (lc.getOutermostFunction() == functionNode ||
+- (!functionNode.needsCallee()) && lc.isFunctionDefinedInCurrentCall(originalFunctionNode)) {
++
++ final RecompilableScriptFunctionData data = compiler.getScriptFunctionData(functionNode.getId());
++
++ if (functionNode.isProgram() && !compiler.isOnDemandCompilation()) {
++ final CompileUnit fnUnit = functionNode.getCompileUnit();
++ final MethodEmitter createFunction = fnUnit.getClassEmitter().method(
++ EnumSet.of(Flag.PUBLIC, Flag.STATIC), CREATE_PROGRAM_FUNCTION.symbolName(),
++ ScriptFunction.class, ScriptObject.class);
++ createFunction.begin();
++ createFunction._new(SCRIPTFUNCTION_IMPL_NAME, SCRIPTFUNCTION_IMPL_TYPE).dup();
++ loadConstant(data, fnUnit, createFunction);
++ createFunction.load(SCOPE_TYPE, 0);
++ createFunction.invoke(constructorNoLookup(SCRIPTFUNCTION_IMPL_NAME, RecompilableScriptFunctionData.class, ScriptObject.class));
++ createFunction._return();
++ createFunction.end();
++ }
++
++ if (addInitializer && !compiler.isOnDemandCompilation()) {
++ compiler.addFunctionInitializer(data, functionNode);
++ }
++
++ // We don't emit a ScriptFunction on stack for the outermost compiled function (as there's no code being
++ // generated in its outer context that'd need it as a callee).
++ if (lc.getOutermostFunction() == functionNode) {
+ return;
+ }
+
+- // Generate the object class and property map in case this function is ever used as constructor
+- final String className = SCRIPTFUNCTION_IMPL_OBJECT;
+- final int fieldCount = ObjectClassGenerator.getPaddedFieldCount(functionNode.countThisProperties());
+- final String allocatorClassName = Compiler.binaryName(ObjectClassGenerator.getClassName(fieldCount));
+- final PropertyMap allocatorMap = PropertyMap.newMap(null, allocatorClassName, 0, fieldCount, 0);
+-
+- method._new(className).dup();
+- loadConstant(new RecompilableScriptFunctionData(functionNode, compiler.getCodeInstaller(), allocatorClassName, allocatorMap));
+-
+- if (functionNode.isLazy() || functionNode.needsParentScope()) {
++ method._new(SCRIPTFUNCTION_IMPL_NAME, SCRIPTFUNCTION_IMPL_TYPE).dup();
++ loadConstant(data);
++
++ if (functionNode.needsParentScope()) {
+ method.loadCompilerConstant(SCOPE);
+ } else {
+ method.loadNull();
+ }
+- method.invoke(constructorNoLookup(className, RecompilableScriptFunctionData.class, ScriptObject.class));
++ method.invoke(constructorNoLookup(SCRIPTFUNCTION_IMPL_NAME, RecompilableScriptFunctionData.class, ScriptObject.class));
+ }
+
+ // calls on Global class.
+@@ -3251,10 +4361,6 @@
+ return method.invokestatic(GLOBAL_OBJECT, "instance", "()L" + GLOBAL_OBJECT + ';');
+ }
+
+- private MethodEmitter globalObjectPrototype() {
+- return method.invokestatic(GLOBAL_OBJECT, "objectPrototype", methodDescriptor(ScriptObject.class));
+- }
+-
+ private MethodEmitter globalAllocateArguments() {
+ return method.invokestatic(GLOBAL_OBJECT, "allocateArguments", methodDescriptor(ScriptObject.class, Object[].class, Object.class, int.class));
+ }
+@@ -3276,12 +4382,907 @@
+ return method.invokestatic(GLOBAL_OBJECT, "isEval", methodDescriptor(boolean.class, Object.class));
+ }
+
++ private MethodEmitter globalReplaceLocationPropertyPlaceholder() {
++ return method.invokestatic(GLOBAL_OBJECT, "replaceLocationPropertyPlaceholder", methodDescriptor(Object.class, Object.class, Object.class));
++ }
++
+ private MethodEmitter globalCheckObjectCoercible() {
+ return method.invokestatic(GLOBAL_OBJECT, "checkObjectCoercible", methodDescriptor(void.class, Object.class));
+ }
+
+ private MethodEmitter globalDirectEval() {
+ return method.invokestatic(GLOBAL_OBJECT, "directEval",
+- methodDescriptor(Object.class, Object.class, Object.class, Object.class, Object.class, Object.class));
++ methodDescriptor(Object.class, Object.class, Object.class, Object.class, Object.class, boolean.class));
++ }
++
++ private abstract class OptimisticOperation {
++ private final boolean isOptimistic;
++ // expression and optimistic are the same reference
++ private final Expression expression;
++ private final Optimistic optimistic;
++ private final TypeBounds resultBounds;
++
++ OptimisticOperation(final Optimistic optimistic, final TypeBounds resultBounds) {
++ this.optimistic = optimistic;
++ this.expression = (Expression)optimistic;
++ this.resultBounds = resultBounds;
++ this.isOptimistic = isOptimistic(optimistic) && useOptimisticTypes() &&
++ // Operation is only effectively optimistic if its type, after being coerced into the result bounds
++ // is narrower than the upper bound.
++ resultBounds.within(Type.generic(((Expression)optimistic).getType())).narrowerThan(resultBounds.widest);
++ }
++
++ MethodEmitter emit() {
++ return emit(0);
++ }
++
++ MethodEmitter emit(final int ignoredArgCount) {
++ final int programPoint = optimistic.getProgramPoint();
++ final boolean optimisticOrContinuation = isOptimistic || isContinuationEntryPoint(programPoint);
++ final boolean currentContinuationEntryPoint = isCurrentContinuationEntryPoint(programPoint);
++ final int stackSizeOnEntry = method.getStackSize() - ignoredArgCount;
++
++ // First store the values on the stack opportunistically into local variables. Doing it before loadStack()
++ // allows us to not have to pop/load any arguments that are pushed onto it by loadStack() in the second
++ // storeStack().
++ storeStack(ignoredArgCount, optimisticOrContinuation);
++
++ // Now, load the stack
++ loadStack();
++
++ // Now store the values on the stack ultimately into local variables. In vast majority of cases, this is
++ // (aside from creating the local types map) a no-op, as the first opportunistic stack store will already
++ // store all variables. However, there can be operations in the loadStack() that invalidate some of the
++ // stack stores, e.g. in "x[i] = x[++i]", "++i" will invalidate the already stored value for "i". In such
++ // unfortunate cases this second storeStack() will restore the invariant that everything on the stack is
++ // stored into a local variable, although at the cost of doing a store/load on the loaded arguments as well.
++ final int liveLocalsCount = storeStack(method.getStackSize() - stackSizeOnEntry, optimisticOrContinuation);
++ assert optimisticOrContinuation == (liveLocalsCount != -1);
++
++ final Label beginTry;
++ final Label catchLabel;
++ final Label afterConsumeStack = isOptimistic || currentContinuationEntryPoint ? new Label("after_consume_stack") : null;
++ if(isOptimistic) {
++ beginTry = new Label("try_optimistic");
++ final String catchLabelName = (afterConsumeStack == null ? "" : afterConsumeStack.toString()) + "_handler";
++ catchLabel = new Label(catchLabelName);
++ method.label(beginTry);
++ } else {
++ beginTry = catchLabel = null;
++ }
++
++ consumeStack();
++
++ if(isOptimistic) {
++ method._try(beginTry, afterConsumeStack, catchLabel, UnwarrantedOptimismException.class);
++ }
++
++ if(isOptimistic || currentContinuationEntryPoint) {
++ method.label(afterConsumeStack);
++
++ final int[] localLoads = method.getLocalLoadsOnStack(0, stackSizeOnEntry);
++ assert everyStackValueIsLocalLoad(localLoads) : Arrays.toString(localLoads) + ", " + stackSizeOnEntry + ", " + ignoredArgCount;
++ final List<Type> localTypesList = method.getLocalVariableTypes();
++ final int usedLocals = method.getUsedSlotsWithLiveTemporaries();
++ final List<Type> localTypes = method.getWidestLiveLocals(localTypesList.subList(0, usedLocals));
++ assert everyLocalLoadIsValid(localLoads, usedLocals) : Arrays.toString(localLoads) + " ~ " + localTypes;
++
++ if(isOptimistic) {
++ addUnwarrantedOptimismHandlerLabel(localTypes, catchLabel);
++ }
++ if(currentContinuationEntryPoint) {
++ final ContinuationInfo ci = getContinuationInfo();
++ assert ci != null : "no continuation info found for " + lc.getCurrentFunction();
++ assert !ci.hasTargetLabel(); // No duplicate program points
++ ci.setTargetLabel(afterConsumeStack);
++ ci.getHandlerLabel().markAsOptimisticContinuationHandlerFor(afterConsumeStack);
++ // Can't rely on targetLabel.stack.localVariableTypes.length, as it can be higher due to effectively
++ // dead local variables.
++ ci.lvarCount = localTypes.size();
++ ci.setStackStoreSpec(localLoads);
++ ci.setStackTypes(Arrays.copyOf(method.getTypesFromStack(method.getStackSize()), stackSizeOnEntry));
++ assert ci.getStackStoreSpec().length == ci.getStackTypes().length;
++ ci.setReturnValueType(method.peekType());
++ ci.lineNumber = getLastLineNumber();
++ ci.catchLabel = catchLabels.peek();
++ }
++ }
++ return method;
++ }
++
++ /**
++ * Stores the current contents of the stack into local variables so they are not lost before invoking something that
++ * can result in an {@code UnwarantedOptimizationException}.
++ * @param ignoreArgCount the number of topmost arguments on stack to ignore when deciding on the shape of the catch
++ * block. Those are used in the situations when we could not place the call to {@code storeStack} early enough
++ * (before emitting code for pushing the arguments that the optimistic call will pop). This is admittedly a
++ * deficiency in the design of the code generator when it deals with self-assignments and we should probably look
++ * into fixing it.
++ * @return types of the significant local variables after the stack was stored (types for local variables used
++ * for temporary storage of ignored arguments are not returned).
++ * @param optimisticOrContinuation if false, this method should not execute
++ * a label for a catch block for the {@code UnwarantedOptimizationException}, suitable for capturing the
++ * currently live local variables, tailored to their types.
++ */
++ private int storeStack(final int ignoreArgCount, final boolean optimisticOrContinuation) {
++ if(!optimisticOrContinuation) {
++ return -1; // NOTE: correct value to return is lc.getUsedSlotCount(), but it wouldn't be used anyway
++ }
++
++ final int stackSize = method.getStackSize();
++ final Type[] stackTypes = method.getTypesFromStack(stackSize);
++ final int[] localLoadsOnStack = method.getLocalLoadsOnStack(0, stackSize);
++ final int usedSlots = method.getUsedSlotsWithLiveTemporaries();
++
++ final int firstIgnored = stackSize - ignoreArgCount;
++ // Find the first value on the stack (from the bottom) that is not a load from a local variable.
++ int firstNonLoad = 0;
++ while(firstNonLoad < firstIgnored && localLoadsOnStack[firstNonLoad] != Label.Stack.NON_LOAD) {
++ firstNonLoad++;
++ }
++
++ // Only do the store/load if first non-load is not an ignored argument. Otherwise, do nothing and return
++ // the number of used slots as the number of live local variables.
++ if(firstNonLoad >= firstIgnored) {
++ return usedSlots;
++ }
++
++ // Find the number of new temporary local variables that we need; it's the number of values on the stack that
++ // are not direct loads of existing local variables.
++ int tempSlotsNeeded = 0;
++ for(int i = firstNonLoad; i < stackSize; ++i) {
++ if(localLoadsOnStack[i] == Label.Stack.NON_LOAD) {
++ tempSlotsNeeded += stackTypes[i].getSlots();
++ }
++ }
++
++ // Ensure all values on the stack that weren't directly loaded from a local variable are stored in a local
++ // variable. We're starting from highest local variable index, so that in case ignoreArgCount > 0 the ignored
++ // ones end up at the end of the local variable table.
++ int lastTempSlot = usedSlots + tempSlotsNeeded;
++ int ignoreSlotCount = 0;
++ for(int i = stackSize; i -- > firstNonLoad;) {
++ final int loadSlot = localLoadsOnStack[i];
++ if(loadSlot == Label.Stack.NON_LOAD) {
++ final Type type = stackTypes[i];
++ final int slots = type.getSlots();
++ lastTempSlot -= slots;
++ if(i >= firstIgnored) {
++ ignoreSlotCount += slots;
++ }
++ method.storeTemp(type, lastTempSlot);
++ } else {
++ method.pop();
++ }
++ }
++ assert lastTempSlot == usedSlots; // used all temporary locals
++
++ final List<Type> localTypesList = method.getLocalVariableTypes();
++
++ // Load values back on stack.
++ for(int i = firstNonLoad; i < stackSize; ++i) {
++ final int loadSlot = localLoadsOnStack[i];
++ final Type stackType = stackTypes[i];
++ final boolean isLoad = loadSlot != Label.Stack.NON_LOAD;
++ final int lvarSlot = isLoad ? loadSlot : lastTempSlot;
++ final Type lvarType = localTypesList.get(lvarSlot);
++ method.load(lvarType, lvarSlot);
++ if(isLoad) {
++ // Conversion operators (I2L etc.) preserve "load"-ness of the value despite the fact that, in the
++ // strict sense they are creating a derived value from the loaded value. This special behavior of
++ // on-stack conversion operators is necessary to accommodate for differences in local variable types
++ // after deoptimization; having a conversion operator throw away "load"-ness would create different
++ // local variable table shapes between optimism-failed code and its deoptimized rest-of method).
++ // After we load the value back, we need to redo the conversion to the stack type if stack type is
++ // different.
++ // NOTE: this would only strictly be necessary for widening conversions (I2L, L2D, I2D), and not for
++ // narrowing ones (L2I, D2L, D2I) as only widening conversions are the ones that can get eliminated
++ // in a deoptimized method, as their original input argument got widened. Maybe experiment with
++ // throwing away "load"-ness for narrowing conversions in MethodEmitter.convert()?
++ method.convert(stackType);
++ } else {
++ // temporary stores never needs a convert, as their type is always the same as the stack type.
++ assert lvarType == stackType;
++ lastTempSlot += lvarType.getSlots();
++ }
++ }
++ // used all temporaries
++ assert lastTempSlot == usedSlots + tempSlotsNeeded;
++
++ return lastTempSlot - ignoreSlotCount;
++ }
++
++ private void addUnwarrantedOptimismHandlerLabel(final List<Type> localTypes, final Label label) {
++ final String lvarTypesDescriptor = getLvarTypesDescriptor(localTypes);
++ final Map<String, Collection<Label>> unwarrantedOptimismHandlers = lc.getUnwarrantedOptimismHandlers();
++ Collection<Label> labels = unwarrantedOptimismHandlers.get(lvarTypesDescriptor);
++ if(labels == null) {
++ labels = new LinkedList<>();
++ unwarrantedOptimismHandlers.put(lvarTypesDescriptor, labels);
++ }
++ method.markLabelAsOptimisticCatchHandler(label, localTypes.size());
++ labels.add(label);
++ }
++
++ abstract void loadStack();
++
++ // Make sure that whatever indy call site you emit from this method uses {@code getCallSiteFlagsOptimistic(node)}
++ // or otherwise ensure optimistic flag is correctly set in the call site, otherwise it doesn't make much sense
++ // to use OptimisticExpression for emitting it.
++ abstract void consumeStack();
++
++ /**
++ * Emits the correct dynamic getter code. Normally just delegates to method emitter, except when the target
++ * expression is optimistic, and the desired type is narrower than the optimistic type. In that case, it'll emit a
++ * dynamic getter with its original optimistic type, and explicitly insert a narrowing conversion. This way we can
++ * preserve the optimism of the values even if they're subsequently immediately coerced into a narrower type. This
++ * is beneficial because in this case we can still presume that since the original getter was optimistic, the
++ * conversion has no side effects.
++ * @param name the name of the property being get
++ * @param flags call site flags
++ * @param isMethod whether we're preferrably retrieving a function
++ * @return the current method emitter
++ */
++ MethodEmitter dynamicGet(final String name, final int flags, final boolean isMethod, final boolean isIndex) {
++ if(isOptimistic) {
++ return method.dynamicGet(getOptimisticCoercedType(), name, getOptimisticFlags(flags), isMethod, isIndex);
++ }
++ return method.dynamicGet(resultBounds.within(expression.getType()), name, nonOptimisticFlags(flags), isMethod, isIndex);
++ }
++
++ MethodEmitter dynamicGetIndex(final int flags, final boolean isMethod) {
++ if(isOptimistic) {
++ return method.dynamicGetIndex(getOptimisticCoercedType(), getOptimisticFlags(flags), isMethod);
++ }
++ return method.dynamicGetIndex(resultBounds.within(expression.getType()), nonOptimisticFlags(flags), isMethod);
++ }
++
++ MethodEmitter dynamicCall(final int argCount, final int flags) {
++ if (isOptimistic) {
++ return method.dynamicCall(getOptimisticCoercedType(), argCount, getOptimisticFlags(flags));
++ }
++ return method.dynamicCall(resultBounds.within(expression.getType()), argCount, nonOptimisticFlags(flags));
++ }
++
++ int getOptimisticFlags(final int flags) {
++ return flags | CALLSITE_OPTIMISTIC | (optimistic.getProgramPoint() << CALLSITE_PROGRAM_POINT_SHIFT); //encode program point in high bits
++ }
++
++ int getProgramPoint() {
++ return isOptimistic ? optimistic.getProgramPoint() : INVALID_PROGRAM_POINT;
++ }
++
++ void convertOptimisticReturnValue() {
++ if (isOptimistic) {
++ final Type optimisticType = getOptimisticCoercedType();
++ if(!optimisticType.isObject()) {
++ method.load(optimistic.getProgramPoint());
++ if(optimisticType.isInteger()) {
++ method.invoke(ENSURE_INT);
++ } else if(optimisticType.isLong()) {
++ method.invoke(ENSURE_LONG);
++ } else if(optimisticType.isNumber()) {
++ method.invoke(ENSURE_NUMBER);
++ } else {
++ throw new AssertionError(optimisticType);
++ }
++ }
++ }
++ }
++
++ void replaceCompileTimeProperty() {
++ final IdentNode identNode = (IdentNode)expression;
++ final String name = identNode.getSymbol().getName();
++ if (CompilerConstants.__FILE__.name().equals(name)) {
++ replaceCompileTimeProperty(getCurrentSource().getName());
++ } else if (CompilerConstants.__DIR__.name().equals(name)) {
++ replaceCompileTimeProperty(getCurrentSource().getBase());
++ } else if (CompilerConstants.__LINE__.name().equals(name)) {
++ replaceCompileTimeProperty(getCurrentSource().getLine(identNode.position()));
++ }
++ }
++
++ /**
++ * When an ident with name __FILE__, __DIR__, or __LINE__ is loaded, we'll try to look it up as any other
++ * identifier. However, if it gets all the way up to the Global object, it will send back a special value that
++ * represents a placeholder for these compile-time location properties. This method will generate code that loads
++ * the value of the compile-time location property and then invokes a method in Global that will replace the
++ * placeholder with the value. Effectively, if the symbol for these properties is defined anywhere in the lexical
++ * scope, they take precedence, but if they aren't, then they resolve to the compile-time location property.
++ * @param propertyValue the actual value of the property
++ */
++ private void replaceCompileTimeProperty(final Object propertyValue) {
++ assert method.peekType().isObject();
++ if(propertyValue instanceof String || propertyValue == null) {
++ method.load((String)propertyValue);
++ } else if(propertyValue instanceof Integer) {
++ method.load(((Integer)propertyValue).intValue());
++ method.convert(Type.OBJECT);
++ } else {
++ throw new AssertionError();
++ }
++ globalReplaceLocationPropertyPlaceholder();
++ convertOptimisticReturnValue();
++ }
++
++ /**
++ * Returns the type that should be used as the return type of the dynamic invocation that is emitted as the code
++ * for the current optimistic operation. If the type bounds is exact boolean or narrower than the expression's
++ * optimistic type, then the optimistic type is returned, otherwise the coercing type. Effectively, this method
++ * allows for moving the coercion into the optimistic type when it won't adversely affect the optimistic
++ * evaluation semantics, and for preserving the optimistic type and doing a separate coercion when it would
++ * affect it.
++ * @return
++ */
++ private Type getOptimisticCoercedType() {
++ final Type optimisticType = expression.getType();
++ assert resultBounds.widest.widerThan(optimisticType);
++ final Type narrowest = resultBounds.narrowest;
++
++ if(narrowest.isBoolean() || narrowest.narrowerThan(optimisticType)) {
++ assert !optimisticType.isObject();
++ return optimisticType;
++ }
++ assert !narrowest.isObject();
++ return narrowest;
++ }
++ }
++
++ private static boolean isOptimistic(final Optimistic optimistic) {
++ if(!optimistic.canBeOptimistic()) {
++ return false;
++ }
++ final Expression expr = (Expression)optimistic;
++ return expr.getType().narrowerThan(expr.getWidestOperationType());
++ }
++
++ private static boolean everyLocalLoadIsValid(final int[] loads, final int localCount) {
++ for (final int load : loads) {
++ if(load < 0 || load >= localCount) {
++ return false;
++ }
++ }
++ return true;
++ }
++
++ private static boolean everyStackValueIsLocalLoad(final int[] loads) {
++ for (final int load : loads) {
++ if(load == Label.Stack.NON_LOAD) {
++ return false;
++ }
++ }
++ return true;
++ }
++
++ private String getLvarTypesDescriptor(final List<Type> localVarTypes) {
++ final int count = localVarTypes.size();
++ final StringBuilder desc = new StringBuilder(count);
++ for(int i = 0; i < count;) {
++ i += appendType(desc, localVarTypes.get(i));
++ }
++ return method.markSymbolBoundariesInLvarTypesDescriptor(desc.toString());
++ }
++
++ private static int appendType(final StringBuilder b, final Type t) {
++ b.append(t.getBytecodeStackType());
++ return t.getSlots();
++ }
++
++ private static int countSymbolsInLvarTypeDescriptor(final String lvarTypeDescriptor) {
++ int count = 0;
++ for(int i = 0; i < lvarTypeDescriptor.length(); ++i) {
++ if(Character.isUpperCase(lvarTypeDescriptor.charAt(i))) {
++ ++count;
++ }
++ }
++ return count;
++
++ }
++ /**
++ * Generates all the required {@code UnwarrantedOptimismException} handlers for the current function. The employed
++ * strategy strives to maximize code reuse. Every handler constructs an array to hold the local variables, then
++ * fills in some trailing part of the local variables (those for which it has a unique suffix in the descriptor),
++ * then jumps to a handler for a prefix that's shared with other handlers. A handler that fills up locals up to
++ * position 0 will not jump to a prefix handler (as it has no prefix), but instead end with constructing and
++ * throwing a {@code RewriteException}. Since we lexicographically sort the entries, we only need to check every
++ * entry to its immediately preceding one for longest matching prefix.
++ * @return true if there is at least one exception handler
++ */
++ private boolean generateUnwarrantedOptimismExceptionHandlers(final FunctionNode fn) {
++ if(!useOptimisticTypes()) {
++ return false;
++ }
++
++ // Take the mapping of lvarSpecs -> labels, and turn them into a descending lexicographically sorted list of
++ // handler specifications.
++ final Map<String, Collection<Label>> unwarrantedOptimismHandlers = lc.popUnwarrantedOptimismHandlers();
++ if(unwarrantedOptimismHandlers.isEmpty()) {
++ return false;
++ }
++
++ method.lineNumber(0);
++
++ final List<OptimismExceptionHandlerSpec> handlerSpecs = new ArrayList<>(unwarrantedOptimismHandlers.size() * 4/3);
++ for(final String spec: unwarrantedOptimismHandlers.keySet()) {
++ handlerSpecs.add(new OptimismExceptionHandlerSpec(spec, true));
++ }
++ Collections.sort(handlerSpecs, Collections.reverseOrder());
++
++ // Map of local variable specifications to labels for populating the array for that local variable spec.
++ final Map<String, Label> delegationLabels = new HashMap<>();
++
++ // Do everything in a single pass over the handlerSpecs list. Note that the list can actually grow as we're
++ // passing through it as we might add new prefix handlers into it, so can't hoist size() outside of the loop.
++ for(int handlerIndex = 0; handlerIndex < handlerSpecs.size(); ++handlerIndex) {
++ final OptimismExceptionHandlerSpec spec = handlerSpecs.get(handlerIndex);
++ final String lvarSpec = spec.lvarSpec;
++ if(spec.catchTarget) {
++ assert !method.isReachable();
++ // Start a catch block and assign the labels for this lvarSpec with it.
++ method._catch(unwarrantedOptimismHandlers.get(lvarSpec));
++ // This spec is a catch target, so emit array creation code. The length of the array is the number of
++ // symbols - the number of uppercase characters.
++ method.load(countSymbolsInLvarTypeDescriptor(lvarSpec));
++ method.newarray(Type.OBJECT_ARRAY);
++ }
++ if(spec.delegationTarget) {
++ // If another handler can delegate to this handler as its prefix, then put a jump target here for the
++ // shared code (after the array creation code, which is never shared).
++ method.label(delegationLabels.get(lvarSpec)); // label must exist
++ }
++
++ final boolean lastHandler = handlerIndex == handlerSpecs.size() - 1;
++
++ int lvarIndex;
++ final int firstArrayIndex;
++ final int firstLvarIndex;
++ Label delegationLabel;
++ final String commonLvarSpec;
++ if(lastHandler) {
++ // Last handler block, doesn't delegate to anything.
++ lvarIndex = 0;
++ firstLvarIndex = 0;
++ firstArrayIndex = 0;
++ delegationLabel = null;
++ commonLvarSpec = null;
++ } else {
++ // Not yet the last handler block, will definitely delegate to another handler; let's figure out which
++ // one. It can be an already declared handler further down the list, or it might need to declare a new
++ // prefix handler.
++
++ // Since we're lexicographically ordered, the common prefix handler is defined by the common prefix of
++ // this handler and the next handler on the list.
++ final int nextHandlerIndex = handlerIndex + 1;
++ final String nextLvarSpec = handlerSpecs.get(nextHandlerIndex).lvarSpec;
++ commonLvarSpec = commonPrefix(lvarSpec, nextLvarSpec);
++ // We don't chop symbols in half
++ assert Character.isUpperCase(commonLvarSpec.charAt(commonLvarSpec.length() - 1));
++
++ // Let's find if we already have a declaration for such handler, or we need to insert it.
++ {
++ boolean addNewHandler = true;
++ int commonHandlerIndex = nextHandlerIndex;
++ for(; commonHandlerIndex < handlerSpecs.size(); ++commonHandlerIndex) {
++ final OptimismExceptionHandlerSpec forwardHandlerSpec = handlerSpecs.get(commonHandlerIndex);
++ final String forwardLvarSpec = forwardHandlerSpec.lvarSpec;
++ if(forwardLvarSpec.equals(commonLvarSpec)) {
++ // We already have a handler for the common prefix.
++ addNewHandler = false;
++ // Make sure we mark it as a delegation target.
++ forwardHandlerSpec.delegationTarget = true;
++ break;
++ } else if(!forwardLvarSpec.startsWith(commonLvarSpec)) {
++ break;
++ }
++ }
++ if(addNewHandler) {
++ // We need to insert a common prefix handler. Note handlers created with catchTarget == false
++ // will automatically have delegationTarget == true (because that's the only reason for their
++ // existence).
++ handlerSpecs.add(commonHandlerIndex, new OptimismExceptionHandlerSpec(commonLvarSpec, false));
++ }
++ }
++
++ firstArrayIndex = countSymbolsInLvarTypeDescriptor(commonLvarSpec);
++ lvarIndex = 0;
++ for(int j = 0; j < commonLvarSpec.length(); ++j) {
++ lvarIndex += CodeGeneratorLexicalContext.getTypeForSlotDescriptor(commonLvarSpec.charAt(j)).getSlots();
++ }
++ firstLvarIndex = lvarIndex;
++
++ // Create a delegation label if not already present
++ delegationLabel = delegationLabels.get(commonLvarSpec);
++ if(delegationLabel == null) {
++ // uo_pa == "unwarranted optimism, populate array"
++ delegationLabel = new Label("uo_pa_" + commonLvarSpec);
++ delegationLabels.put(commonLvarSpec, delegationLabel);
++ }
++ }
++
++ // Load local variables handled by this handler on stack
++ int args = 0;
++ boolean symbolHadValue = false;
++ for(int typeIndex = commonLvarSpec == null ? 0 : commonLvarSpec.length(); typeIndex < lvarSpec.length(); ++typeIndex) {
++ final char typeDesc = lvarSpec.charAt(typeIndex);
++ final Type lvarType = CodeGeneratorLexicalContext.getTypeForSlotDescriptor(typeDesc);
++ if (!lvarType.isUnknown()) {
++ method.load(lvarType, lvarIndex);
++ symbolHadValue = true;
++ args++;
++ } else if(typeDesc == 'U' && !symbolHadValue) {
++ // Symbol boundary with undefined last value. Check if all previous values for this symbol were also
++ // undefined; if so, emit one explicit Undefined. This serves to ensure that we're emiting exactly
++ // one value for every symbol that uses local slots. While we could in theory ignore symbols that
++ // are undefined (in other words, dead) at the point where this exception was thrown, unfortunately
++ // we can't do it in practice. The reason for this is that currently our liveness analysis is
++ // coarse (it can determine whether a symbol has not been read with a particular type anywhere in
++ // the function being compiled, but that's it), and a symbol being promoted to Object due to a
++ // deoptimization will suddenly show up as "live for Object type", and previously dead U->O
++ // conversions on loop entries will suddenly become alive in the deoptimized method which will then
++ // expect a value for that slot in its continuation handler. If we had precise liveness analysis, we
++ // could go back to excluding known dead symbols from the payload of the RewriteException.
++ if(method.peekType() == Type.UNDEFINED) {
++ method.dup();
++ } else {
++ method.loadUndefined(Type.OBJECT);
++ }
++ args++;
++ }
++ if(Character.isUpperCase(typeDesc)) {
++ // Reached symbol boundary; reset flag for the next symbol.
++ symbolHadValue = false;
++ }
++ lvarIndex += lvarType.getSlots();
++ }
++ assert args > 0;
++ // Delegate actual storing into array to an array populator utility method.
++ //on the stack:
++ // object array to be populated
++ // start index
++ // a lot of types
++ method.dynamicArrayPopulatorCall(args + 1, firstArrayIndex);
++ if(delegationLabel != null) {
++ // We cascade to a prefix handler to fill out the rest of the local variables and throw the
++ // RewriteException.
++ assert !lastHandler;
++ assert commonLvarSpec != null;
++ // Must undefine the local variables that we have already processed for the sake of correct join on the
++ // delegate label
++ method.undefineLocalVariables(firstLvarIndex, true);
++ final OptimismExceptionHandlerSpec nextSpec = handlerSpecs.get(handlerIndex + 1);
++ // If the delegate immediately follows, and it's not a catch target (so it doesn't have array setup
++ // code) don't bother emitting a jump, as we'd just jump to the next instruction.
++ if(!nextSpec.lvarSpec.equals(commonLvarSpec) || nextSpec.catchTarget) {
++ method._goto(delegationLabel);
++ }
++ } else {
++ assert lastHandler;
++ // Nothing to delegate to, so this handler must create and throw the RewriteException.
++ // At this point we have the UnwarrantedOptimismException and the Object[] with local variables on
++ // stack. We need to create a RewriteException, push two references to it below the constructor
++ // arguments, invoke the constructor, and throw the exception.
++ loadConstant(getByteCodeSymbolNames(fn));
++ if (isRestOf()) {
++ loadConstant(getContinuationEntryPoints());
++ method.invoke(CREATE_REWRITE_EXCEPTION_REST_OF);
++ } else {
++ method.invoke(CREATE_REWRITE_EXCEPTION);
++ }
++ method.athrow();
++ }
++ }
++ return true;
++ }
++
++ private static String[] getByteCodeSymbolNames(final FunctionNode fn) {
++ // Only names of local variables on the function level are captured. This information is used to reduce
++ // deoptimizations, so as much as we can capture will help. We rely on the fact that function wide variables are
++ // all live all the time, so the array passed to rewrite exception contains one element for every slotted symbol
++ // here.
++ final List<String> names = new ArrayList<>();
++ for (final Symbol symbol: fn.getBody().getSymbols()) {
++ if (symbol.hasSlot()) {
++ if (symbol.isScope()) {
++ // slot + scope can only be true for parameters
++ assert symbol.isParam();
++ names.add(null);
++ } else {
++ names.add(symbol.getName());
++ }
++ }
++ }
++ return names.toArray(new String[names.size()]);
++ }
++
++ private static String commonPrefix(final String s1, final String s2) {
++ final int l1 = s1.length();
++ final int l = Math.min(l1, s2.length());
++ int lms = -1; // last matching symbol
++ for(int i = 0; i < l; ++i) {
++ final char c1 = s1.charAt(i);
++ if(c1 != s2.charAt(i)) {
++ return s1.substring(0, lms + 1);
++ } else if(Character.isUpperCase(c1)) {
++ lms = i;
++ }
++ }
++ return l == l1 ? s1 : s2;
++ }
++
++ private static class OptimismExceptionHandlerSpec implements Comparable<OptimismExceptionHandlerSpec> {
++ private final String lvarSpec;
++ private final boolean catchTarget;
++ private boolean delegationTarget;
++
++ OptimismExceptionHandlerSpec(final String lvarSpec, final boolean catchTarget) {
++ this.lvarSpec = lvarSpec;
++ this.catchTarget = catchTarget;
++ if(!catchTarget) {
++ delegationTarget = true;
++ }
++ }
++
++ @Override
++ public int compareTo(final OptimismExceptionHandlerSpec o) {
++ return lvarSpec.compareTo(o.lvarSpec);
++ }
++
++ @Override
++ public String toString() {
++ final StringBuilder b = new StringBuilder(64).append("[HandlerSpec ").append(lvarSpec);
++ if(catchTarget) {
++ b.append(", catchTarget");
++ }
++ if(delegationTarget) {
++ b.append(", delegationTarget");
++ }
++ return b.append("]").toString();
++ }
++ }
++
++ private static class ContinuationInfo {
++ private final Label handlerLabel;
++ private Label targetLabel; // Label for the target instruction.
++ int lvarCount;
++ // Indices of local variables that need to be loaded on the stack when this node completes
++ private int[] stackStoreSpec;
++ // Types of values loaded on the stack
++ private Type[] stackTypes;
++ // If non-null, this node should perform the requisite type conversion
++ private Type returnValueType;
++ // If we are in the middle of an object literal initialization, we need to update the map
++ private PropertyMap objectLiteralMap;
++ // Object literal stack depth for object literal - not necessarly top if property is a tree
++ private int objectLiteralStackDepth = -1;
++ // The line number at the continuation point
++ private int lineNumber;
++ // The active catch label, in case the continuation point is in a try/catch block
++ private Label catchLabel;
++ // The number of scopes that need to be popped before control is transferred to the catch label.
++ private int exceptionScopePops;
++
++ ContinuationInfo() {
++ this.handlerLabel = new Label("continuation_handler");
++ }
++
++ Label getHandlerLabel() {
++ return handlerLabel;
++ }
++
++ boolean hasTargetLabel() {
++ return targetLabel != null;
++ }
++
++ Label getTargetLabel() {
++ return targetLabel;
++ }
++
++ void setTargetLabel(final Label targetLabel) {
++ this.targetLabel = targetLabel;
++ }
++
++ int[] getStackStoreSpec() {
++ return stackStoreSpec.clone();
++ }
++
++ void setStackStoreSpec(final int[] stackStoreSpec) {
++ this.stackStoreSpec = stackStoreSpec;
++ }
++
++ Type[] getStackTypes() {
++ return stackTypes.clone();
++ }
++
++ void setStackTypes(final Type[] stackTypes) {
++ this.stackTypes = stackTypes;
++ }
++
++ Type getReturnValueType() {
++ return returnValueType;
++ }
++
++ void setReturnValueType(final Type returnValueType) {
++ this.returnValueType = returnValueType;
++ }
++
++ int getObjectLiteralStackDepth() {
++ return objectLiteralStackDepth;
++ }
++
++ void setObjectLiteralStackDepth(final int objectLiteralStackDepth) {
++ this.objectLiteralStackDepth = objectLiteralStackDepth;
++ }
++
++ PropertyMap getObjectLiteralMap() {
++ return objectLiteralMap;
++ }
++
++ void setObjectLiteralMap(final PropertyMap objectLiteralMap) {
++ this.objectLiteralMap = objectLiteralMap;
++ }
++
++ @Override
++ public String toString() {
++ return "[localVariableTypes=" + targetLabel.getStack().getLocalVariableTypesCopy() + ", stackStoreSpec=" +
++ Arrays.toString(stackStoreSpec) + ", returnValueType=" + returnValueType + "]";
++ }
++ }
++
++ private ContinuationInfo getContinuationInfo() {
++ return fnIdToContinuationInfo.get(lc.getCurrentFunction().getId());
++ }
++
++ private void generateContinuationHandler() {
++ if (!isRestOf()) {
++ return;
++ }
++
++ final ContinuationInfo ci = getContinuationInfo();
++ method.label(ci.getHandlerLabel());
++
++ // There should never be an exception thrown from the continuation handler, but in case there is (meaning,
++ // Nashorn has a bug), then line number 0 will be an indication of where it came from (line numbers are Uint16).
++ method.lineNumber(0);
++
++ final Label.Stack stack = ci.getTargetLabel().getStack();
++ final List<Type> lvarTypes = stack.getLocalVariableTypesCopy();
++ final BitSet symbolBoundary = stack.getSymbolBoundaryCopy();
++ final int lvarCount = ci.lvarCount;
++
++ final Type rewriteExceptionType = Type.typeFor(RewriteException.class);
++ // Store the RewriteException into an unused local variable slot.
++ method.load(rewriteExceptionType, 0);
++ method.storeTemp(rewriteExceptionType, lvarCount);
++ // Get local variable array
++ method.load(rewriteExceptionType, 0);
++ method.invoke(RewriteException.GET_BYTECODE_SLOTS);
++ // Store local variables. Note that deoptimization might introduce new value types for existing local variables,
++ // so we must use both liveLocals and symbolBoundary, as in some cases (when the continuation is inside of a try
++ // block) we need to store the incoming value into multiple slots. The optimism exception handlers will have
++ // exactly one array element for every symbol that uses bytecode storage. If in the originating method the value
++ // was undefined, there will be an explicit Undefined value in the array.
++ int arrayIndex = 0;
++ for(int lvarIndex = 0; lvarIndex < lvarCount;) {
++ final Type lvarType = lvarTypes.get(lvarIndex);
++ if(!lvarType.isUnknown()) {
++ method.dup();
++ method.load(arrayIndex).arrayload();
++ final Class<?> typeClass = lvarType.getTypeClass();
++ // Deoptimization in array initializers can cause arrays to undergo component type widening
++ if(typeClass == long[].class) {
++ method.load(rewriteExceptionType, lvarCount);
++ method.invoke(RewriteException.TO_LONG_ARRAY);
++ } else if(typeClass == double[].class) {
++ method.load(rewriteExceptionType, lvarCount);
++ method.invoke(RewriteException.TO_DOUBLE_ARRAY);
++ } else if(typeClass == Object[].class) {
++ method.load(rewriteExceptionType, lvarCount);
++ method.invoke(RewriteException.TO_OBJECT_ARRAY);
++ } else {
++ if(!(typeClass.isPrimitive() || typeClass == Object.class)) {
++ // NOTE: this can only happen with dead stores. E.g. for the program "1; []; f();" in which the
++ // call to f() will deoptimize the call site, but it'll expect :return to have the type
++ // NativeArray. However, in the more optimal version, :return's only live type is int, therefore
++ // "{O}:return = []" is a dead store, and the variable will be sent into the continuation as
++ // Undefined, however NativeArray can't hold Undefined instance.
++ method.loadType(Type.getInternalName(typeClass));
++ method.invoke(RewriteException.INSTANCE_OR_NULL);
++ }
++ method.convert(lvarType);
++ }
++ method.storeHidden(lvarType, lvarIndex, false);
++ }
++ final int nextLvarIndex = lvarIndex + lvarType.getSlots();
++ if(symbolBoundary.get(nextLvarIndex - 1)) {
++ ++arrayIndex;
++ }
++ lvarIndex = nextLvarIndex;
++ }
++ if (AssertsEnabled.assertsEnabled()) {
++ method.load(arrayIndex);
++ method.invoke(RewriteException.ASSERT_ARRAY_LENGTH);
++ } else {
++ method.pop();
++ }
++
++ final int[] stackStoreSpec = ci.getStackStoreSpec();
++ final Type[] stackTypes = ci.getStackTypes();
++ final boolean isStackEmpty = stackStoreSpec.length == 0;
++ boolean replacedObjectLiteralMap = false;
++ if(!isStackEmpty) {
++ // Load arguments on the stack
++ final int objectLiteralStackDepth = ci.getObjectLiteralStackDepth();
++ for(int i = 0; i < stackStoreSpec.length; ++i) {
++ final int slot = stackStoreSpec[i];
++ method.load(lvarTypes.get(slot), slot);
++ method.convert(stackTypes[i]);
++ // stack: s0=object literal being initialized
++ // change map of s0 so that the property we are initilizing when we failed
++ // is now ci.returnValueType
++ if (i == objectLiteralStackDepth) {
++ method.dup();
++ assert ci.getObjectLiteralMap() != null;
++ assert ScriptObject.class.isAssignableFrom(method.peekType().getTypeClass()) : method.peekType().getTypeClass() + " is not a script object";
++ loadConstant(ci.getObjectLiteralMap());
++ method.invoke(ScriptObject.SET_MAP);
++ replacedObjectLiteralMap = true;
++ }
++ }
++ }
++ // Must have emitted the code for replacing the map of an object literal if we have a set object literal stack depth
++ assert ci.getObjectLiteralStackDepth() == -1 || replacedObjectLiteralMap;
++ // Load RewriteException back.
++ method.load(rewriteExceptionType, lvarCount);
++ // Get rid of the stored reference
++ method.loadNull();
++ method.storeHidden(Type.OBJECT, lvarCount);
++ // Mark it dead
++ method.markDeadSlots(lvarCount, Type.OBJECT.getSlots());
++
++ // Load return value on the stack
++ method.invoke(RewriteException.GET_RETURN_VALUE);
++
++ final Type returnValueType = ci.getReturnValueType();
++
++ // Set up an exception handler for primitive type conversion of return value if needed
++ boolean needsCatch = false;
++ final Label targetCatchLabel = ci.catchLabel;
++ Label _try = null;
++ if(returnValueType.isPrimitive()) {
++ // If the conversion throws an exception, we want to report the line number of the continuation point.
++ method.lineNumber(ci.lineNumber);
++
++ if(targetCatchLabel != METHOD_BOUNDARY) {
++ _try = new Label("");
++ method.label(_try);
++ needsCatch = true;
++ }
++ }
++
++ // Convert return value
++ method.convert(returnValueType);
++
++ final int scopePopCount = needsCatch ? ci.exceptionScopePops : 0;
++
++ // Declare a try/catch for the conversion. If no scopes need to be popped until the target catch block, just
++ // jump into it. Otherwise, we'll need to create a scope-popping catch block below.
++ final Label catchLabel = scopePopCount > 0 ? new Label("") : targetCatchLabel;
++ if(needsCatch) {
++ final Label _end_try = new Label("");
++ method.label(_end_try);
++ method._try(_try, _end_try, catchLabel);
++ }
++
++ // Jump to continuation point
++ method._goto(ci.getTargetLabel());
++
++ // Make a scope-popping exception delegate if needed
++ if(catchLabel != targetCatchLabel) {
++ method.lineNumber(0);
++ assert scopePopCount > 0;
++ method._catch(catchLabel);
++ popScopes(scopePopCount);
++ method.uncheckedGoto(targetCatchLabel);
++ }
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/CodeGeneratorLexicalContext.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/CodeGeneratorLexicalContext.java Wed Feb 04 12:14:47 2015 -0800
+@@ -31,7 +31,7 @@
+ import java.util.Deque;
+ import java.util.HashMap;
+ import java.util.Map;
+-
++import jdk.nashorn.internal.IntDeque;
+ import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.Block;
+ import jdk.nashorn.internal.ir.FunctionNode;
+@@ -63,6 +63,10 @@
+ * i.e. should we keep it or throw it away */
+ private final Deque<Node> discard = new ArrayDeque<>();
+
++ private final Deque<Map<String, Collection<Label>>> unwarrantedOptimismHandlers = new ArrayDeque<>();
++ private final Deque<StringBuilder> slotTypesDescriptors = new ArrayDeque<>();
++ private final IntDeque splitNodes = new IntDeque();
++
+ /** A stack tracking the next free local variable slot in the blocks. There's one entry for every block
+ * currently on the lexical context stack. */
+ private int[] nextFreeSlots = new int[16];
+@@ -70,46 +74,56 @@
+ /** size of next free slot vector */
+ private int nextFreeSlotsSize;
+
++ private boolean isWithBoundary(final LexicalContextNode node) {
++ return node instanceof Block && !isEmpty() && peek() instanceof WithNode;
++ }
++
+ @Override
+ public <T extends LexicalContextNode> T push(final T node) {
+- if (isDynamicScopeBoundary(node)) {
+- ++dynamicScopeCount;
++ if (isWithBoundary(node)) {
++ dynamicScopeCount++;
++ } else if (node instanceof FunctionNode) {
++ if (((FunctionNode)node).inDynamicContext()) {
++ dynamicScopeCount++;
++ }
++ splitNodes.push(0);
+ }
+ return super.push(node);
+ }
+
++ void enterSplitNode() {
++ splitNodes.getAndIncrement();
++ pushFreeSlots(methodEmitters.peek().getUsedSlotsWithLiveTemporaries());
++ }
++
++ void exitSplitNode() {
++ final int count = splitNodes.decrementAndGet();
++ assert count >= 0;
++ }
++
+ @Override
+ public <T extends LexicalContextNode> T pop(final T node) {
+ final T popped = super.pop(node);
+- if (isDynamicScopeBoundary(popped)) {
+- --dynamicScopeCount;
+- }
+- if (node instanceof Block) {
+- --nextFreeSlotsSize;
++ if (isWithBoundary(node)) {
++ dynamicScopeCount--;
++ assert dynamicScopeCount >= 0;
++ } else if (node instanceof FunctionNode) {
++ if (((FunctionNode)node).inDynamicContext()) {
++ dynamicScopeCount--;
++ assert dynamicScopeCount >= 0;
++ }
++ assert splitNodes.peek() == 0;
++ splitNodes.pop();
+ }
+ return popped;
+ }
+
+- private boolean isDynamicScopeBoundary(final LexicalContextNode node) {
+- if (node instanceof Block) {
+- // Block's immediate parent is a with node. Note we aren't testing for a WithNode, as that'd capture
+- // processing of WithNode.expression too, but it should be unaffected.
+- return !isEmpty() && peek() instanceof WithNode;
+- } else if (node instanceof FunctionNode) {
+- // Function has a direct eval in it (so a top-level "var ..." in the eval code can introduce a new
+- // variable into the function's scope), and it isn't strict (as evals in strict functions get an
+- // isolated scope).
+- return isFunctionDynamicScope((FunctionNode)node);
+- }
+- return false;
+- }
+-
+ boolean inDynamicScope() {
+ return dynamicScopeCount > 0;
+ }
+
+- static boolean isFunctionDynamicScope(FunctionNode fn) {
+- return fn.hasEval() && !fn.isStrict();
++ boolean inSplitNode() {
++ return !splitNodes.isEmpty() && splitNodes.peek() > 0;
+ }
+
+ MethodEmitter pushMethodEmitter(final MethodEmitter newMethod) {
+@@ -123,6 +137,20 @@
+ return methodEmitters.isEmpty() ? null : methodEmitters.peek();
+ }
+
++ void pushUnwarrantedOptimismHandlers() {
++ unwarrantedOptimismHandlers.push(new HashMap<String, Collection<Label>>());
++ slotTypesDescriptors.push(new StringBuilder());
++ }
++
++ Map<String, Collection<Label>> getUnwarrantedOptimismHandlers() {
++ return unwarrantedOptimismHandlers.peek();
++ }
++
++ Map<String, Collection<Label>> popUnwarrantedOptimismHandlers() {
++ slotTypesDescriptors.pop();
++ return unwarrantedOptimismHandlers.pop();
++ }
++
+ CompileUnit pushCompileUnit(final CompileUnit newUnit) {
+ compileUnits.push(newUnit);
+ return newUnit;
+@@ -130,7 +158,9 @@
+
+ CompileUnit popCompileUnit(final CompileUnit oldUnit) {
+ assert compileUnits.peek() == oldUnit;
+- compileUnits.pop();
++ final CompileUnit unit = compileUnits.pop();
++ assert unit.hasCode() : "compile unit popped without code";
++ unit.setUsed();
+ return compileUnits.isEmpty() ? null : compileUnits.peek();
+ }
+
+@@ -167,50 +197,77 @@
+ * Get a shared static method representing a dynamic scope get access.
+ *
+ * @param unit current compile unit
+- * @param type the type of the variable
+ * @param symbol the symbol
++ * @param valueType the type of the variable
+ * @param flags the callsite flags
+ * @return an object representing a shared scope call
+ */
+- SharedScopeCall getScopeGet(final CompileUnit unit, final Type type, final Symbol symbol, final int flags) {
+- final SharedScopeCall scopeCall = new SharedScopeCall(symbol, type, type, null, flags);
+- if (scopeCalls.containsKey(scopeCall)) {
+- return scopeCalls.get(scopeCall);
+- }
+- scopeCall.setClassAndName(unit, getCurrentFunction().uniqueName(":scopeCall"));
+- scopeCalls.put(scopeCall, scopeCall);
+- return scopeCall;
++ SharedScopeCall getScopeGet(final CompileUnit unit, final Symbol symbol, final Type valueType, final int flags) {
++ return getScopeCall(unit, symbol, valueType, valueType, null, flags);
+ }
+
++ void onEnterBlock(final Block block) {
++ pushFreeSlots(assignSlots(block, isFunctionBody() ? 0 : getUsedSlotCount()));
++ }
+
+- void nextFreeSlot(final Block block) {
+- final boolean isFunctionBody = isFunctionBody();
+-
+- final int nextFreeSlot;
+- if (isFunctionBody) {
+- // On entry to function, start with slot 0
+- nextFreeSlot = 0;
+- } else {
+- // Otherwise, continue from previous block's first free slot
+- nextFreeSlot = nextFreeSlots[nextFreeSlotsSize - 1];
+- }
++ private void pushFreeSlots(final int freeSlots) {
+ if (nextFreeSlotsSize == nextFreeSlots.length) {
+ final int[] newNextFreeSlots = new int[nextFreeSlotsSize * 2];
+ System.arraycopy(nextFreeSlots, 0, newNextFreeSlots, 0, nextFreeSlotsSize);
+ nextFreeSlots = newNextFreeSlots;
+ }
+- nextFreeSlots[nextFreeSlotsSize++] = assignSlots(block, nextFreeSlot);
++ nextFreeSlots[nextFreeSlotsSize++] = freeSlots;
+ }
+
+- private static int assignSlots(final Block block, final int firstSlot) {
+- int nextSlot = firstSlot;
++ int getUsedSlotCount() {
++ return nextFreeSlots[nextFreeSlotsSize - 1];
++ }
++
++ void releaseSlots() {
++ --nextFreeSlotsSize;
++ final int undefinedFromSlot = nextFreeSlotsSize == 0 ? 0 : nextFreeSlots[nextFreeSlotsSize - 1];
++ if(!slotTypesDescriptors.isEmpty()) {
++ slotTypesDescriptors.peek().setLength(undefinedFromSlot);
++ }
++ methodEmitters.peek().undefineLocalVariables(undefinedFromSlot, false);
++ }
++
++ private int assignSlots(final Block block, final int firstSlot) {
++ int fromSlot = firstSlot;
++ final MethodEmitter method = methodEmitters.peek();
+ for (final Symbol symbol : block.getSymbols()) {
+ if (symbol.hasSlot()) {
+- symbol.setSlot(nextSlot);
+- nextSlot += symbol.slotCount();
++ symbol.setFirstSlot(fromSlot);
++ final int toSlot = fromSlot + symbol.slotCount();
++ method.defineBlockLocalVariable(fromSlot, toSlot);
++ fromSlot = toSlot;
+ }
+ }
+- return nextSlot;
++ return fromSlot;
++ }
++
++ static Type getTypeForSlotDescriptor(final char typeDesc) {
++ // Recognizing both lowercase and uppercase as we're using both to signify symbol boundaries; see
++ // MethodEmitter.markSymbolBoundariesInLvarTypesDescriptor().
++ switch (typeDesc) {
++ case 'I':
++ case 'i':
++ return Type.INT;
++ case 'J':
++ case 'j':
++ return Type.LONG;
++ case 'D':
++ case 'd':
++ return Type.NUMBER;
++ case 'A':
++ case 'a':
++ return Type.OBJECT;
++ case 'U':
++ case 'u':
++ return Type.UNKNOWN;
++ default:
++ throw new AssertionError();
++ }
+ }
+
+ void pushDiscard(final Node node) {
+@@ -225,11 +282,8 @@
+ return discard.peek();
+ }
+
+- int quickSlot(final Symbol symbol) {
+- final int quickSlot = nextFreeSlots[nextFreeSlotsSize - 1];
+- nextFreeSlots[nextFreeSlotsSize - 1] = quickSlot + symbol.slotCount();
+- return quickSlot;
++ int quickSlot(final Type type) {
++ return methodEmitters.peek().defineTemporaryLocalVariable(type.getSlots());
+ }
+-
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java Wed Feb 04 12:14:47 2015 -0800
+@@ -1,129 +1,376 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
+
+-import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.ATTR;
++import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.BUILTINS_TRANSFORMED;
++import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.BYTECODE_GENERATED;
++import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.BYTECODE_INSTALLED;
+ import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.CONSTANT_FOLDED;
+-import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.FINALIZED;
+ import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.INITIALIZED;
++import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.LOCAL_VARIABLE_TYPES_CALCULATED;
+ import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.LOWERED;
++import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.OPTIMISTIC_TYPES_ASSIGNED;
+ import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.PARSED;
++import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.SCOPE_DEPTHS_COMPUTED;
+ import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.SPLIT;
++import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.SYMBOLS_ASSIGNED;
++import static jdk.nashorn.internal.runtime.logging.DebugLogger.quote;
+
+-import java.io.File;
+-import java.io.FileOutputStream;
+-import java.io.IOException;
+-import java.util.ArrayDeque;
+-import java.util.ArrayList;
+-import java.util.Deque;
++import java.io.PrintWriter;
+ import java.util.EnumSet;
+-import java.util.HashSet;
+-import java.util.List;
++import java.util.HashMap;
++import java.util.LinkedHashMap;
++import java.util.Map;
++import java.util.Map.Entry;
+ import java.util.Set;
+-import jdk.nashorn.internal.codegen.types.Range;
+-import jdk.nashorn.internal.codegen.types.Type;
+-import jdk.nashorn.internal.ir.CallNode;
+-import jdk.nashorn.internal.ir.Expression;
++import jdk.nashorn.internal.AssertsEnabled;
++import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
+ import jdk.nashorn.internal.ir.FunctionNode;
+ import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
+ import jdk.nashorn.internal.ir.LexicalContext;
++import jdk.nashorn.internal.ir.LiteralNode;
+ import jdk.nashorn.internal.ir.Node;
+-import jdk.nashorn.internal.ir.ReturnNode;
+-import jdk.nashorn.internal.ir.Symbol;
+-import jdk.nashorn.internal.ir.TemporarySymbols;
+ import jdk.nashorn.internal.ir.debug.ASTWriter;
+ import jdk.nashorn.internal.ir.debug.PrintVisitor;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+-import jdk.nashorn.internal.runtime.ECMAErrors;
++import jdk.nashorn.internal.runtime.CodeInstaller;
++import jdk.nashorn.internal.runtime.FunctionInitializer;
++import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
+ import jdk.nashorn.internal.runtime.ScriptEnvironment;
+-import jdk.nashorn.internal.runtime.Timing;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
+
+ /**
+ * A compilation phase is a step in the processes of turning a JavaScript
+ * FunctionNode into bytecode. It has an optional return value.
+ */
+ enum CompilationPhase {
++ /**
++ * Constant folding pass Simple constant folding that will make elementary
++ * constructs go away
++ */
++ CONSTANT_FOLDING_PHASE(
++ EnumSet.of(
++ INITIALIZED,
++ PARSED)) {
++ @Override
++ FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
++ return transformFunction(fn, new FoldConstants(compiler));
++ }
+
+- /*
+- * Lazy initialization - tag all function nodes not the script as lazy as
+- * default policy. The will get trampolines and only be generated when
+- * called
++ @Override
++ public String toString() {
++ return "'Constant Folding'";
++ }
++ },
++
++ /**
++ * Lower (Control flow pass) Finalizes the control flow. Clones blocks for
++ * finally constructs and similar things. Establishes termination criteria
++ * for nodes Guarantee return instructions to method making sure control
++ * flow cannot fall off the end. Replacing high level nodes with lower such
++ * as runtime nodes where applicable.
+ */
+- LAZY_INITIALIZATION_PHASE(EnumSet.of(INITIALIZED, PARSED)) {
++ LOWERING_PHASE(
++ EnumSet.of(
++ INITIALIZED,
++ PARSED,
++ CONSTANT_FOLDED)) {
+ @Override
+- FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
++ FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
++ return transformFunction(fn, new Lower(compiler));
++ }
+
+- /*
+- * For lazy compilation, we might be given a node previously marked
+- * as lazy to compile as the outermost function node in the
+- * compiler. Unmark it so it can be compiled and not cause
+- * recursion. Make sure the return type is unknown so it can be
+- * correctly deduced. Return types are always Objects in Lazy nodes
+- * as we haven't got a change to generate code for them and decude
+- * its parameter specialization
+- *
+- * TODO: in the future specializations from a callsite will be
+- * passed here so we can generate a better non-lazy version of a
+- * function from a trampoline
+- */
++ @Override
++ public String toString() {
++ return "'Control Flow Lowering'";
++ }
++ },
+
+- final FunctionNode outermostFunctionNode = fn;
++ /**
++ * Phase used only when doing optimistic code generation. It assigns all potentially
++ * optimistic ops a program point so that an UnwarrantedException knows from where
++ * a guess went wrong when creating the continuation to roll back this execution
++ */
++ TRANSFORM_BUILTINS_PHASE(
++ EnumSet.of(
++ INITIALIZED,
++ PARSED,
++ CONSTANT_FOLDED,
++ LOWERED)) {
++ //we only do this if we have a param type map, otherwise this is not a specialized recompile
++ @Override
++ FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
++ return setStates(transformFunction(fn, new ApplySpecialization(compiler)), BUILTINS_TRANSFORMED);
++ }
+
+- final Set<FunctionNode> neverLazy = new HashSet<>();
+- final Set<FunctionNode> lazy = new HashSet<>();
++ @Override
++ public String toString() {
++ return "'Builtin Replacement'";
++ }
++ },
+
+- FunctionNode newFunctionNode = outermostFunctionNode;
++ /**
++ * Splitter Split the AST into several compile units based on a heuristic size calculation.
++ * Split IR can lead to scope information being changed.
++ */
++ SPLITTING_PHASE(
++ EnumSet.of(
++ INITIALIZED,
++ PARSED,
++ CONSTANT_FOLDED,
++ LOWERED,
++ BUILTINS_TRANSFORMED)) {
++ @Override
++ FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
++ final CompileUnit outermostCompileUnit = compiler.addCompileUnit(0L);
+
+- newFunctionNode = (FunctionNode)newFunctionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
+- // self references are done with invokestatic and thus cannot
+- // have trampolines - never lazy
++ FunctionNode newFunctionNode;
++
++ //ensure elementTypes, postsets and presets exist for splitter and arraynodes
++ newFunctionNode = transformFunction(fn, new NodeVisitor<LexicalContext>(new LexicalContext()) {
+ @Override
+- public boolean enterCallNode(final CallNode node) {
+- final Node callee = node.getFunction();
+- if (callee instanceof FunctionNode) {
+- neverLazy.add(((FunctionNode)callee));
+- return false;
++ public LiteralNode<?> leaveLiteralNode(final LiteralNode<?> literalNode) {
++ return literalNode.initialize(lc);
++ }
++ });
++
++ newFunctionNode = new Splitter(compiler, newFunctionNode, outermostCompileUnit).split(newFunctionNode, true);
++ newFunctionNode = transformFunction(newFunctionNode, new SplitIntoFunctions(compiler));
++ assert newFunctionNode.getCompileUnit() == outermostCompileUnit : "fn=" + fn.getName() + ", fn.compileUnit (" + newFunctionNode.getCompileUnit() + ") != " + outermostCompileUnit;
++ assert newFunctionNode.isStrict() == compiler.isStrict() : "functionNode.isStrict() != compiler.isStrict() for " + quote(newFunctionNode.getName());
++
++ return newFunctionNode;
++ }
++
++ @Override
++ public String toString() {
++ return "'Code Splitting'";
++ }
++ },
++
++ PROGRAM_POINT_PHASE(
++ EnumSet.of(
++ INITIALIZED,
++ PARSED,
++ CONSTANT_FOLDED,
++ LOWERED,
++ BUILTINS_TRANSFORMED,
++ SPLIT)) {
++ @Override
++ FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
++ return transformFunction(fn, new ProgramPoints());
++ }
++
++ @Override
++ public String toString() {
++ return "'Program Point Calculation'";
++ }
++ },
++
++ SERIALIZE_SPLIT_PHASE(
++ EnumSet.of(
++ INITIALIZED,
++ PARSED,
++ CONSTANT_FOLDED,
++ LOWERED,
++ BUILTINS_TRANSFORMED,
++ SPLIT)) {
++ @Override
++ FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
++ return transformFunction(fn, new NodeVisitor<LexicalContext>(new LexicalContext()) {
++ @Override
++ public boolean enterFunctionNode(final FunctionNode functionNode) {
++ if (functionNode.isSplit()) {
++ compiler.serializeAst(functionNode);
+ }
+ return true;
+ }
++ });
++ }
+
+- //any function that isn't the outermost one must be marked as lazy
+- @Override
+- public boolean enterFunctionNode(final FunctionNode node) {
+- assert compiler.isLazy();
+- lazy.add(node);
+- return true;
+- }
+- });
++ @Override
++ public String toString() {
++ return "'Serialize Split Functions'";
++ }
++ },
+
+- //at least one method is non lazy - the outermost one
+- neverLazy.add(newFunctionNode);
++ SYMBOL_ASSIGNMENT_PHASE(
++ EnumSet.of(
++ INITIALIZED,
++ PARSED,
++ CONSTANT_FOLDED,
++ LOWERED,
++ BUILTINS_TRANSFORMED,
++ SPLIT)) {
++ @Override
++ FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
++ return transformFunction(fn, new AssignSymbols(compiler));
++ }
+
+- for (final FunctionNode node : neverLazy) {
+- Compiler.LOG.fine(
+- "Marking ",
+- node.getName(),
+- " as non lazy, as it's a self reference");
+- lazy.remove(node);
++ @Override
++ public String toString() {
++ return "'Symbol Assignment'";
++ }
++ },
++
++ SCOPE_DEPTH_COMPUTATION_PHASE(
++ EnumSet.of(
++ INITIALIZED,
++ PARSED,
++ CONSTANT_FOLDED,
++ LOWERED,
++ BUILTINS_TRANSFORMED,
++ SPLIT,
++ SYMBOLS_ASSIGNED)) {
++ @Override
++ FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
++ return transformFunction(fn, new FindScopeDepths(compiler));
++ }
++
++ @Override
++ public String toString() {
++ return "'Scope Depth Computation'";
++ }
++ },
++
++ OPTIMISTIC_TYPE_ASSIGNMENT_PHASE(
++ EnumSet.of(
++ INITIALIZED,
++ PARSED,
++ CONSTANT_FOLDED,
++ LOWERED,
++ BUILTINS_TRANSFORMED,
++ SPLIT,
++ SYMBOLS_ASSIGNED,
++ SCOPE_DEPTHS_COMPUTED)) {
++ @Override
++ FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
++ if (compiler.useOptimisticTypes()) {
++ return transformFunction(fn, new OptimisticTypesCalculator(compiler));
++ }
++ return setStates(fn, OPTIMISTIC_TYPES_ASSIGNED);
++ }
++
++ @Override
++ public String toString() {
++ return "'Optimistic Type Assignment'";
++ }
++ },
++
++ LOCAL_VARIABLE_TYPE_CALCULATION_PHASE(
++ EnumSet.of(
++ INITIALIZED,
++ PARSED,
++ CONSTANT_FOLDED,
++ LOWERED,
++ BUILTINS_TRANSFORMED,
++ SPLIT,
++ SYMBOLS_ASSIGNED,
++ SCOPE_DEPTHS_COMPUTED,
++ OPTIMISTIC_TYPES_ASSIGNED)) {
++ @Override
++ FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
++ final FunctionNode newFunctionNode = transformFunction(fn, new LocalVariableTypesCalculator(compiler));
++ final ScriptEnvironment senv = compiler.getScriptEnvironment();
++ final PrintWriter err = senv.getErr();
++
++ //TODO separate phase for the debug printouts for abstraction and clarity
++ if (senv._print_lower_ast || fn.getFlag(FunctionNode.IS_PRINT_LOWER_AST)) {
++ err.println("Lower AST for: " + quote(newFunctionNode.getName()));
++ err.println(new ASTWriter(newFunctionNode));
+ }
+
+- newFunctionNode = (FunctionNode)newFunctionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
++ if (senv._print_lower_parse || fn.getFlag(FunctionNode.IS_PRINT_LOWER_PARSE)) {
++ err.println("Lower AST for: " + quote(newFunctionNode.getName()));
++ err.println(new PrintVisitor(newFunctionNode));
++ }
++
++ return newFunctionNode;
++ }
++
++ @Override
++ public String toString() {
++ return "'Local Variable Type Calculation'";
++ }
++ },
++
++
++ /**
++ * Reuse compile units, if they are already present. We are using the same compiler
++ * to recompile stuff
++ */
++ REUSE_COMPILE_UNITS_PHASE(
++ EnumSet.of(
++ INITIALIZED,
++ PARSED,
++ CONSTANT_FOLDED,
++ LOWERED,
++ BUILTINS_TRANSFORMED,
++ SPLIT,
++ SYMBOLS_ASSIGNED,
++ SCOPE_DEPTHS_COMPUTED,
++ OPTIMISTIC_TYPES_ASSIGNED,
++ LOCAL_VARIABLE_TYPES_CALCULATED)) {
++ @Override
++ FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
++ assert phases.isRestOfCompilation() : "reuse compile units currently only used for Rest-Of methods";
++
++ final Map<CompileUnit, CompileUnit> map = new HashMap<>();
++ final Set<CompileUnit> newUnits = CompileUnit.createCompileUnitSet();
++
++ final DebugLogger log = compiler.getLogger();
++
++ log.fine("Clearing bytecode cache");
++ compiler.clearBytecode();
++
++ for (final CompileUnit oldUnit : compiler.getCompileUnits()) {
++ assert map.get(oldUnit) == null;
++ final CompileUnit newUnit = createNewCompileUnit(compiler, phases);
++ log.fine("Creating new compile unit ", oldUnit, " => ", newUnit);
++ map.put(oldUnit, newUnit);
++ assert newUnit != null;
++ newUnits.add(newUnit);
++ }
++
++ log.fine("Replacing compile units in Compiler...");
++ compiler.replaceCompileUnits(newUnits);
++ log.fine("Done");
++
++ //replace old compile units in function nodes, if any are assigned,
++ //for example by running the splitter on this function node in a previous
++ //partial code generation
++ final FunctionNode newFunctionNode = transformFunction(fn, new ReplaceCompileUnits() {
+ @Override
+- public Node leaveFunctionNode(final FunctionNode functionNode) {
+- if (lazy.contains(functionNode)) {
+- Compiler.LOG.fine(
+- "Marking ",
+- functionNode.getName(),
+- " as lazy");
+- final FunctionNode parent = lc.getParentFunction(functionNode);
+- assert parent != null;
+- lc.setFlag(parent, FunctionNode.HAS_LAZY_CHILDREN);
+- lc.setBlockNeedsScope(parent.getBody());
+- lc.setFlag(functionNode, FunctionNode.IS_LAZY);
+- return functionNode;
+- }
++ CompileUnit getReplacement(CompileUnit original) {
++ return map.get(original);
++ }
+
+- return functionNode.
+- clearFlag(lc, FunctionNode.IS_LAZY).
+- setReturnType(lc, Type.UNKNOWN);
++ @Override
++ public Node leaveDefault(final Node node) {
++ return node.ensureUniqueLabels(lc);
+ }
+ });
+
+@@ -132,189 +379,136 @@
+
+ @Override
+ public String toString() {
+- return "[Lazy JIT Initialization]";
++ return "'Reuse Compile Units'";
+ }
+ },
+
+- /*
+- * Constant folding pass Simple constant folding that will make elementary
+- * constructs go away
+- */
+- CONSTANT_FOLDING_PHASE(EnumSet.of(INITIALIZED, PARSED)) {
++ REINITIALIZE_SERIALIZED(
++ EnumSet.of(
++ INITIALIZED,
++ PARSED,
++ CONSTANT_FOLDED,
++ LOWERED,
++ BUILTINS_TRANSFORMED,
++ SPLIT)) {
+ @Override
+- FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
+- return (FunctionNode)fn.accept(new FoldConstants());
++ FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
++ final Set<CompileUnit> unitSet = CompileUnit.createCompileUnitSet();
++ final Map<CompileUnit, CompileUnit> unitMap = new HashMap<>();
++
++ // Ensure that the FunctionNode's compile unit is the first in the list of new units. Install phase
++ // will use that as the root class.
++ createCompileUnit(fn.getCompileUnit(), unitSet, unitMap, compiler, phases);
++
++ final FunctionNode newFn = transformFunction(fn, new ReplaceCompileUnits() {
++ @Override
++ CompileUnit getReplacement(final CompileUnit oldUnit) {
++ final CompileUnit existing = unitMap.get(oldUnit);
++ if (existing != null) {
++ return existing;
++ }
++ return createCompileUnit(oldUnit, unitSet, unitMap, compiler, phases);
++ }
++
++ @Override
++ public Node leaveFunctionNode(final FunctionNode fn2) {
++ return super.leaveFunctionNode(
++ // restore flags for deserialized nested function nodes
++ compiler.getScriptFunctionData(fn2.getId()).restoreFlags(lc, fn2));
++ };
++ });
++ compiler.replaceCompileUnits(unitSet);
++ return newFn;
++ }
++
++ private CompileUnit createCompileUnit(final CompileUnit oldUnit, final Set<CompileUnit> unitSet,
++ final Map<CompileUnit, CompileUnit> unitMap, final Compiler compiler, final CompilationPhases phases) {
++ final CompileUnit newUnit = createNewCompileUnit(compiler, phases);
++ unitMap.put(oldUnit, newUnit);
++ unitSet.add(newUnit);
++ return newUnit;
+ }
+
+ @Override
+ public String toString() {
+- return "[Constant Folding]";
++ return "'Deserialize'";
+ }
+ },
+
+- /*
+- * Lower (Control flow pass) Finalizes the control flow. Clones blocks for
+- * finally constructs and similar things. Establishes termination criteria
+- * for nodes Guarantee return instructions to method making sure control
+- * flow cannot fall off the end. Replacing high level nodes with lower such
+- * as runtime nodes where applicable.
++ /**
++ * Bytecode generation:
++ *
++ * Generate the byte code class(es) resulting from the compiled FunctionNode
+ */
+- LOWERING_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED)) {
+- @Override
+- FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
+- return (FunctionNode)fn.accept(new Lower(compiler.getCodeInstaller()));
+- }
++ BYTECODE_GENERATION_PHASE(
++ EnumSet.of(
++ INITIALIZED,
++ PARSED,
++ CONSTANT_FOLDED,
++ LOWERED,
++ BUILTINS_TRANSFORMED,
++ SPLIT,
++ SYMBOLS_ASSIGNED,
++ SCOPE_DEPTHS_COMPUTED,
++ OPTIMISTIC_TYPES_ASSIGNED,
++ LOCAL_VARIABLE_TYPES_CALCULATED)) {
+
+ @Override
+- public String toString() {
+- return "[Control Flow Lowering]";
+- }
+- },
++ FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
++ final ScriptEnvironment senv = compiler.getScriptEnvironment();
+
+- /*
+- * Attribution Assign symbols and types to all nodes.
+- */
+- ATTRIBUTION_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED)) {
+- @Override
+- FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
+- final TemporarySymbols ts = compiler.getTemporarySymbols();
+- final FunctionNode newFunctionNode = (FunctionNode)enterAttr(fn, ts).accept(new Attr(ts));
+- if (compiler.getEnv()._print_mem_usage) {
+- Compiler.LOG.info("Attr temporary symbol count: " + ts.getTotalSymbolCount());
+- }
+- return newFunctionNode;
+- }
++ FunctionNode newFunctionNode = fn;
+
+- /**
+- * Pessimistically set all lazy functions' return types to Object
+- * and the function symbols to object
+- * @param functionNode node where to start iterating
+- */
+- private FunctionNode enterAttr(final FunctionNode functionNode, final TemporarySymbols ts) {
+- return (FunctionNode)functionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
+- @Override
+- public Node leaveFunctionNode(final FunctionNode node) {
+- if (node.isLazy()) {
+- FunctionNode newNode = node.setReturnType(lc, Type.OBJECT);
+- return ts.ensureSymbol(lc, Type.OBJECT, newNode);
++ //root class is special, as it is bootstrapped from createProgramFunction, thus it's skipped
++ //in CodeGeneration - the rest can be used as a working "is compile unit used" metric
++ fn.getCompileUnit().setUsed();
++
++ compiler.getLogger().fine("Starting bytecode generation for ", quote(fn.getName()), " - restOf=", phases.isRestOfCompilation());
++
++ final CodeGenerator codegen = new CodeGenerator(compiler, phases.isRestOfCompilation() ? compiler.getContinuationEntryPoints() : null);
++
++ try {
++ // Explicitly set BYTECODE_GENERATED here; it can not be set in case of skipping codegen for :program
++ // in the lazy + optimistic world. See CodeGenerator.skipFunction().
++ newFunctionNode = transformFunction(newFunctionNode, codegen).setState(null, BYTECODE_GENERATED);
++ codegen.generateScopeCalls();
++ } catch (final VerifyError e) {
++ if (senv._verify_code || senv._print_code) {
++ senv.getErr().println(e.getClass().getSimpleName() + ": " + e.getMessage());
++ if (senv._dump_on_error) {
++ e.printStackTrace(senv.getErr());
+ }
+- //node may have a reference here that needs to be nulled if it was referred to by
+- //its outer context, if it is lazy and not attributed
+- return node.setReturnType(lc, Type.UNKNOWN).setSymbol(lc, null);
++ } else {
++ throw e;
+ }
+- });
+- }
+-
+- @Override
+- public String toString() {
+- return "[Type Attribution]";
+- }
+- },
+-
+- /*
+- * Range analysis
+- * Conservatively prove that certain variables can be narrower than
+- * the most generic number type
+- */
+- RANGE_ANALYSIS_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED, ATTR)) {
+- @Override
+- FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
+- if (!compiler.getEnv()._range_analysis) {
+- return fn;
++ } catch (final Throwable e) {
++ // Provide source file and line number being compiled when the assertion occurred
++ throw new AssertionError("Failed generating bytecode for " + fn.getSourceName() + ":" + codegen.getLastLineNumber(), e);
+ }
+
+- FunctionNode newFunctionNode = (FunctionNode)fn.accept(new RangeAnalyzer());
+- final List<ReturnNode> returns = new ArrayList<>();
++ for (final CompileUnit compileUnit : compiler.getCompileUnits()) {
++ final ClassEmitter classEmitter = compileUnit.getClassEmitter();
++ classEmitter.end();
+
+- newFunctionNode = (FunctionNode)newFunctionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
+- private final Deque<ArrayList<ReturnNode>> returnStack = new ArrayDeque<>();
+-
+- @Override
+- public boolean enterFunctionNode(final FunctionNode functionNode) {
+- returnStack.push(new ArrayList<ReturnNode>());
+- return true;
++ if (!compileUnit.isUsed()) {
++ compiler.getLogger().fine("Skipping unused compile unit ", compileUnit);
++ continue;
+ }
+
+- @Override
+- public Node leaveFunctionNode(final FunctionNode functionNode) {
+- Type returnType = Type.UNKNOWN;
+- for (final ReturnNode ret : returnStack.pop()) {
+- if (ret.getExpression() == null) {
+- returnType = Type.OBJECT;
+- break;
+- }
+- returnType = Type.widest(returnType, ret.getExpression().getType());
+- }
+- return functionNode.setReturnType(lc, returnType);
++ final byte[] bytecode = classEmitter.toByteArray();
++ assert bytecode != null;
++
++ final String className = compileUnit.getUnitClassName();
++ compiler.addClass(className, bytecode); //classes are only added to the bytecode map if compile unit is used
++
++ CompileUnit.increaseEmitCount();
++
++ // should we verify the generated code?
++ if (senv._verify_code) {
++ compiler.getCodeInstaller().verify(bytecode);
+ }
+
+- @Override
+- public Node leaveReturnNode(final ReturnNode returnNode) {
+- final ReturnNode result = (ReturnNode)leaveDefault(returnNode);
+- returns.add(result);
+- return result;
+- }
+-
+- @Override
+- public Node leaveDefault(final Node node) {
+- if(node instanceof Expression) {
+- final Expression expr = (Expression)node;
+- final Symbol symbol = expr.getSymbol();
+- if (symbol != null) {
+- final Range range = symbol.getRange();
+- final Type symbolType = symbol.getSymbolType();
+- if (!symbolType.isNumeric()) {
+- return expr;
+- }
+- final Type rangeType = range.getType();
+- if (!Type.areEquivalent(symbolType, rangeType) && Type.widest(symbolType, rangeType) == symbolType) { //we can narrow range
+- RangeAnalyzer.LOG.info("[", lc.getCurrentFunction().getName(), "] ", symbol, " can be ", range.getType(), " ", symbol.getRange());
+- return expr.setSymbol(lc, symbol.setTypeOverrideShared(range.getType(), compiler.getTemporarySymbols()));
+- }
+- }
+- }
+- return node;
+- }
+- });
+-
+- Type returnType = Type.UNKNOWN;
+- for (final ReturnNode node : returns) {
+- if (node.getExpression() != null) {
+- returnType = Type.widest(returnType, node.getExpression().getType());
+- } else {
+- returnType = Type.OBJECT;
+- break;
+- }
+- }
+-
+- return newFunctionNode.setReturnType(null, returnType);
+- }
+-
+- @Override
+- public String toString() {
+- return "[Range Analysis]";
+- }
+- },
+-
+-
+- /*
+- * Splitter Split the AST into several compile units based on a size
+- * heuristic Splitter needs attributed AST for weight calculations (e.g. is
+- * a + b a ScriptRuntime.ADD with call overhead or a dadd with much less).
+- * Split IR can lead to scope information being changed.
+- */
+- SPLITTING_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED, ATTR)) {
+- @Override
+- FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
+- final CompileUnit outermostCompileUnit = compiler.addCompileUnit(compiler.firstCompileUnitName());
+-
+- final FunctionNode newFunctionNode = new Splitter(compiler, fn, outermostCompileUnit).split(fn);
+-
+- assert newFunctionNode.getCompileUnit() == outermostCompileUnit : "fn.compileUnit (" + newFunctionNode.getCompileUnit() + ") != " + outermostCompileUnit;
+-
+- if (newFunctionNode.isStrict()) {
+- assert compiler.getStrictMode();
+- compiler.setStrictMode(true);
++ DumpBytecode.dumpBytecode(senv, compiler.getLogger(), bytecode, className);
+ }
+
+ return newFunctionNode;
+@@ -322,171 +516,179 @@
+
+ @Override
+ public String toString() {
+- return "[Code Splitting]";
++ return "'Bytecode Generation'";
+ }
+ },
+
+- /*
+- * FinalizeTypes
+- *
+- * This pass finalizes the types for nodes. If Attr created wider types than
+- * known during the first pass, convert nodes are inserted or access nodes
+- * are specialized where scope accesses.
+- *
+- * Runtime nodes may be removed and primitivized or reintroduced depending
+- * on information that was established in Attr.
+- *
+- * Contract: all variables must have slot assignments and scope assignments
+- * before type finalization.
+- */
+- TYPE_FINALIZATION_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED, ATTR, SPLIT)) {
++ INSTALL_PHASE(
++ EnumSet.of(
++ INITIALIZED,
++ PARSED,
++ CONSTANT_FOLDED,
++ LOWERED,
++ BUILTINS_TRANSFORMED,
++ SPLIT,
++ SYMBOLS_ASSIGNED,
++ SCOPE_DEPTHS_COMPUTED,
++ OPTIMISTIC_TYPES_ASSIGNED,
++ LOCAL_VARIABLE_TYPES_CALCULATED,
++ BYTECODE_GENERATED)) {
++
+ @Override
+- FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
+- final ScriptEnvironment env = compiler.getEnv();
++ FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
++ final DebugLogger log = compiler.getLogger();
+
+- final FunctionNode newFunctionNode = (FunctionNode)fn.accept(new FinalizeTypes(compiler.getTemporarySymbols()));
++ final Map<String, Class<?>> installedClasses = new LinkedHashMap<>();
+
+- if (env._print_lower_ast) {
+- env.getErr().println(new ASTWriter(newFunctionNode));
++ boolean first = true;
++ Class<?> rootClass = null;
++ long length = 0L;
++
++ final CodeInstaller<ScriptEnvironment> codeInstaller = compiler.getCodeInstaller();
++ final Map<String, byte[]> bytecode = compiler.getBytecode();
++
++ for (final Entry<String, byte[]> entry : bytecode.entrySet()) {
++ final String className = entry.getKey();
++ //assert !first || className.equals(compiler.getFirstCompileUnit().getUnitClassName()) : "first=" + first + " className=" + className + " != " + compiler.getFirstCompileUnit().getUnitClassName();
++ final byte[] code = entry.getValue();
++ length += code.length;
++
++ final Class<?> clazz = codeInstaller.install(className, code);
++ if (first) {
++ rootClass = clazz;
++ first = false;
++ }
++ installedClasses.put(className, clazz);
+ }
+
+- if (env._print_lower_parse) {
+- env.getErr().println(new PrintVisitor(newFunctionNode));
++ if (rootClass == null) {
++ throw new CompilationException("Internal compiler error: root class not found!");
+ }
+
+- return newFunctionNode;
++ final Object[] constants = compiler.getConstantData().toArray();
++ codeInstaller.initialize(installedClasses.values(), compiler.getSource(), constants);
++
++ // initialize transient fields on recompilable script function data
++ for (final Object constant: constants) {
++ if (constant instanceof RecompilableScriptFunctionData) {
++ ((RecompilableScriptFunctionData)constant).initTransients(compiler.getSource(), codeInstaller);
++ }
++ }
++
++ // initialize function in the compile units
++ for (final CompileUnit unit : compiler.getCompileUnits()) {
++ if (!unit.isUsed()) {
++ continue;
++ }
++ unit.setCode(installedClasses.get(unit.getUnitClassName()));
++ }
++
++ if (!compiler.isOnDemandCompilation()) {
++ // Initialize functions
++ final Map<Integer, FunctionInitializer> initializers = compiler.getFunctionInitializers();
++ if (initializers != null) {
++ for (final Entry<Integer, FunctionInitializer> entry : initializers.entrySet()) {
++ final FunctionInitializer initializer = entry.getValue();
++ initializer.setCode(installedClasses.get(initializer.getClassName()));
++ compiler.getScriptFunctionData(entry.getKey()).initializeCode(initializer);
++ }
++ }
++ }
++
++ if (log.isEnabled()) {
++ final StringBuilder sb = new StringBuilder();
++
++ sb.append("Installed class '").
++ append(rootClass.getSimpleName()).
++ append('\'').
++ append(" [").
++ append(rootClass.getName()).
++ append(", size=").
++ append(length).
++ append(" bytes, ").
++ append(compiler.getCompileUnits().size()).
++ append(" compile unit(s)]");
++
++ log.fine(sb.toString());
++ }
++
++ return setStates(fn.setRootClass(null, rootClass), BYTECODE_INSTALLED);
+ }
+
+ @Override
+ public String toString() {
+- return "[Type Finalization]";
+- }
+- },
+-
+- /*
+- * Bytecode generation:
+- *
+- * Generate the byte code class(es) resulting from the compiled FunctionNode
+- */
+- BYTECODE_GENERATION_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED, ATTR, SPLIT, FINALIZED)) {
+- @Override
+- FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
+- final ScriptEnvironment env = compiler.getEnv();
+- FunctionNode newFunctionNode = fn;
+-
+- try {
+- final CodeGenerator codegen = new CodeGenerator(compiler);
+- newFunctionNode = (FunctionNode)newFunctionNode.accept(codegen);
+- codegen.generateScopeCalls();
+- } catch (final VerifyError e) {
+- if (env._verify_code || env._print_code) {
+- env.getErr().println(e.getClass().getSimpleName() + ": " + e.getMessage());
+- if (env._dump_on_error) {
+- e.printStackTrace(env.getErr());
+- }
+- } else {
+- throw e;
+- }
+- }
+-
+- for (final CompileUnit compileUnit : compiler.getCompileUnits()) {
+- final ClassEmitter classEmitter = compileUnit.getClassEmitter();
+- classEmitter.end();
+-
+- final byte[] bytecode = classEmitter.toByteArray();
+- assert bytecode != null;
+-
+- final String className = compileUnit.getUnitClassName();
+-
+- compiler.addClass(className, bytecode);
+-
+- // should could be printed to stderr for generate class?
+- if (env._print_code) {
+- final StringBuilder sb = new StringBuilder();
+- sb.append("class: " + className).append('\n')
+- .append(ClassEmitter.disassemble(bytecode))
+- .append("=====");
+- env.getErr().println(sb);
+- }
+-
+- // should we verify the generated code?
+- if (env._verify_code) {
+- compiler.getCodeInstaller().verify(bytecode);
+- }
+-
+- // should code be dumped to disk - only valid in compile_only mode?
+- if (env._dest_dir != null && env._compile_only) {
+- final String fileName = className.replace('.', File.separatorChar) + ".class";
+- final int index = fileName.lastIndexOf(File.separatorChar);
+-
+- final File dir;
+- if (index != -1) {
+- dir = new File(env._dest_dir, fileName.substring(0, index));
+- } else {
+- dir = new File(env._dest_dir);
+- }
+-
+- try {
+- if (!dir.exists() && !dir.mkdirs()) {
+- throw new IOException(dir.toString());
+- }
+- final File file = new File(env._dest_dir, fileName);
+- try (final FileOutputStream fos = new FileOutputStream(file)) {
+- fos.write(bytecode);
+- }
+- Compiler.LOG.info("Wrote class to '" + file.getAbsolutePath() + '\'');
+- } catch (final IOException e) {
+- Compiler.LOG.warning("Skipping class dump for ",
+- className,
+- ": ",
+- ECMAErrors.getMessage(
+- "io.error.cant.write",
+- dir.toString()));
+- }
+- }
+- }
+-
+- return newFunctionNode;
++ return "'Class Installation'";
+ }
+
+- @Override
+- public String toString() {
+- return "[Bytecode Generation]";
+- }
+- };
++ };
+
++ /** pre conditions required for function node to which this transform is to be applied */
+ private final EnumSet<CompilationState> pre;
++
++ /** start time of transform - used for timing, see {@link jdk.nashorn.internal.runtime.Timing} */
+ private long startTime;
++
++ /** start time of transform - used for timing, see {@link jdk.nashorn.internal.runtime.Timing} */
+ private long endTime;
++
++ /** boolean that is true upon transform completion */
+ private boolean isFinished;
+
+ private CompilationPhase(final EnumSet<CompilationState> pre) {
+ this.pre = pre;
+ }
+
+- boolean isApplicable(final FunctionNode functionNode) {
+- return functionNode.hasState(pre);
++ private static FunctionNode setStates(final FunctionNode functionNode, final CompilationState state) {
++ if (!AssertsEnabled.assertsEnabled()) {
++ return functionNode;
++ }
++ return transformFunction(functionNode, new NodeVisitor<LexicalContext>(new LexicalContext()) {
++ @Override
++ public Node leaveFunctionNode(final FunctionNode fn) {
++ return fn.setState(lc, state);
++ }
++ });
+ }
+
+- protected FunctionNode begin(final FunctionNode functionNode) {
+- if (pre != null) {
+- // check that everything in pre is present
+- for (final CompilationState state : pre) {
+- assert functionNode.hasState(state);
+- }
+- // check that nothing else is present
+- for (final CompilationState state : CompilationState.values()) {
+- assert !(functionNode.hasState(state) && !pre.contains(state));
+- }
+- }
++ /**
++ * Start a compilation phase
++ * @param compiler the compiler to use
++ * @param functionNode function to compile
++ * @return function node
++ */
++ protected FunctionNode begin(final Compiler compiler, final FunctionNode functionNode) {
++ compiler.getLogger().indent();
+
+- startTime = System.currentTimeMillis();
+- return functionNode;
+- }
++ assert pre != null;
+
+- protected FunctionNode end(final FunctionNode functionNode) {
+- endTime = System.currentTimeMillis();
+- Timing.accumulateTime(toString(), endTime - startTime);
++ if (!functionNode.hasState(pre)) {
++ final StringBuilder sb = new StringBuilder("Compilation phase ");
++ sb.append(this).
++ append(" is not applicable to ").
++ append(quote(functionNode.getName())).
++ append("\n\tFunctionNode state = ").
++ append(functionNode.getState()).
++ append("\n\tRequired state = ").
++ append(this.pre);
++
++ throw new CompilationException(sb.toString());
++ }
++
++ startTime = System.nanoTime();
++
++ return functionNode;
++ }
++
++ /**
++ * End a compilation phase
++ * @param compiler the compiler
++ * @param functionNode function node to compile
++ * @return function node
++ */
++ protected FunctionNode end(final Compiler compiler, final FunctionNode functionNode) {
++ compiler.getLogger().unindent();
++ endTime = System.nanoTime();
++ compiler.getScriptEnvironment()._timing.accumulateTime(toString(), endTime - startTime);
+
+ isFinished = true;
+ return functionNode;
+@@ -504,13 +706,39 @@
+ return endTime;
+ }
+
+- abstract FunctionNode transform(final Compiler compiler, final FunctionNode functionNode) throws CompilationException;
++ abstract FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode functionNode) throws CompilationException;
+
+- final FunctionNode apply(final Compiler compiler, final FunctionNode functionNode) throws CompilationException {
+- if (!isApplicable(functionNode)) {
+- throw new CompilationException("compile phase not applicable: " + this + " to " + functionNode.getName() + " state=" + functionNode.getState());
+- }
+- return end(transform(compiler, begin(functionNode)));
++ /**
++ * Apply a transform to a function node, returning the transfored function node. If the transform is not
++ * applicable, an exception is thrown. Every transform requires the function to have a certain number of
++ * states to operate. It can have more states set, but not fewer. The state list, i.e. the constructor
++ * arguments to any of the CompilationPhase enum entries, is a set of REQUIRED states.
++ *
++ * @param compiler compiler
++ * @param phases current complete pipeline of which this phase is one
++ * @param functionNode function node to transform
++ *
++ * @return transformed function node
++ *
++ * @throws CompilationException if function node lacks the state required to run the transform on it
++ */
++ final FunctionNode apply(final Compiler compiler, final CompilationPhases phases, final FunctionNode functionNode) throws CompilationException {
++ assert phases.contains(this);
++
++ return end(compiler, transform(compiler, phases, begin(compiler, functionNode)));
+ }
+
++ private static FunctionNode transformFunction(final FunctionNode fn, final NodeVisitor<?> visitor) {
++ return (FunctionNode) fn.accept(visitor);
++ }
++
++ private static CompileUnit createNewCompileUnit(final Compiler compiler, final CompilationPhases phases) {
++ final StringBuilder sb = new StringBuilder(compiler.nextCompileUnitName());
++ if (phases.isRestOfCompilation()) {
++ sb.append("$restOf");
++ }
++ //it's ok to not copy the initCount, methodCount and clinitCount here, as codegen is what
++ //fills those out anyway. Thus no need for a copy constructor
++ return compiler.createCompileUnit(sb.toString(), 0);
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,28 +25,77 @@
+
+ package jdk.nashorn.internal.codegen;
+
++import java.io.Serializable;
++import java.util.Set;
++import java.util.TreeSet;
++import jdk.nashorn.internal.ir.CompileUnitHolder;
++
+ /**
+- * Used to track split class compilation.
+- */
+-public class CompileUnit implements Comparable<CompileUnit> {
++ * Used to track split class compilation. Note that instances of the class are serializable, but all fields are
++ * transient, making the serialized version of the class only useful for tracking the referential topology of other
++ * AST nodes referencing the same or different compile units. We do want to preserve this topology though as
++ * {@link CompileUnitHolder}s in a deserialized AST will undergo reinitialization.
++ */
++public final class CompileUnit implements Comparable<CompileUnit>, Serializable {
++ private static final long serialVersionUID = 1L;
++
+ /** Current class name */
+- private final String className;
++ private transient final String className;
+
+ /** Current class generator */
+- private ClassEmitter classEmitter;
++ private transient ClassEmitter classEmitter;
+
+- private long weight;
++ private transient long weight;
+
+- private Class<?> clazz;
++ private transient Class<?> clazz;
+
+- CompileUnit(final String className, final ClassEmitter classEmitter) {
+- this(className, classEmitter, 0L);
+- }
++ private transient boolean isUsed;
++
++ private static int emittedUnitCount;
+
+ CompileUnit(final String className, final ClassEmitter classEmitter, final long initialWeight) {
+ this.className = className;
++ this.weight = initialWeight;
+ this.classEmitter = classEmitter;
+- this.weight = initialWeight;
++ }
++
++ static Set<CompileUnit> createCompileUnitSet() {
++ return new TreeSet<>();
++ }
++
++ static void increaseEmitCount() {
++ emittedUnitCount++;
++ }
++
++ /**
++ * Get the amount of emitted compile units so far in the system
++ * @return emitted compile unit count
++ */
++ public static int getEmittedUnitCount() {
++ return emittedUnitCount;
++ }
++
++ /**
++ * Check if this compile unit is used
++ * @return true if tagged as in use - i.e active code that needs to be generated
++ */
++ public boolean isUsed() {
++ return isUsed;
++ }
++
++ /**
++ * Check if a compile unit has code, not counting inits and clinits
++ * @return true of if there is "real code" in the compile unit
++ */
++ public boolean hasCode() {
++ return (classEmitter.getMethodCount() - classEmitter.getInitCount() - classEmitter.getClinitCount()) > 0;
++ }
++
++ /**
++ * Tag this compile unit as used
++ */
++ public void setUsed() {
++ this.isUsed = true;
+ }
+
+ /**
+@@ -80,14 +129,6 @@
+ }
+
+ /**
+- * Get the current weight of the compile unit.
+- * @return the unit's weight
+- */
+- long getWeight() {
+- return weight;
+- }
+-
+- /**
+ * Check if this compile unit can hold {@code weight} more units of weight
+ * @param w weight to check if can be added
+ * @return true if weight fits in this compile unit
+@@ -112,13 +153,18 @@
+ return className;
+ }
+
+- @Override
+- public String toString() {
+- return "[classname=" + className + " weight=" + weight + '/' + Splitter.SPLIT_THRESHOLD + ']';
++ private static String shortName(final String name) {
++ return name == null ? null : name.lastIndexOf('/') == -1 ? name : name.substring(name.lastIndexOf('/') + 1);
+ }
+
+ @Override
+- public int compareTo(CompileUnit o) {
++ public String toString() {
++ final String methods = classEmitter != null ? classEmitter.getMethodNames().toString() : "<anon>";
++ return "[CompileUnit className=" + shortName(className) + " weight=" + weight + '/' + Splitter.SPLIT_THRESHOLD + " hasCode=" + methods + ']';
++ }
++
++ @Override
++ public int compareTo(final CompileUnit o) {
+ return className.compareTo(o.className);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/Compiler.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/Compiler.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,47 +27,48 @@
+
+ import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.CONSTANTS;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.DEFAULT_SCRIPT_NAME;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.LAZY;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.RETURN;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
++import static jdk.nashorn.internal.runtime.logging.DebugLogger.quote;
+
+ import java.io.File;
+-import java.lang.reflect.Field;
+-import java.security.AccessController;
+-import java.security.PrivilegedActionException;
+-import java.security.PrivilegedExceptionAction;
++import java.lang.invoke.MethodType;
++import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Collections;
+ import java.util.Comparator;
+-import java.util.EnumSet;
+ import java.util.HashMap;
++import java.util.Iterator;
+ import java.util.LinkedHashMap;
+-import java.util.LinkedList;
+ import java.util.List;
+ import java.util.Map;
+-import java.util.Map.Entry;
+ import java.util.Set;
+-import java.util.TreeSet;
++import java.util.TreeMap;
++import java.util.concurrent.atomic.AtomicInteger;
++import java.util.function.Consumer;
+ import java.util.logging.Level;
+ import jdk.internal.dynalink.support.NameCodec;
+-import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
+ import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.ir.Expression;
+ import jdk.nashorn.internal.ir.FunctionNode;
+-import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
+-import jdk.nashorn.internal.ir.TemporarySymbols;
++import jdk.nashorn.internal.ir.Optimistic;
+ import jdk.nashorn.internal.ir.debug.ClassHistogramElement;
+ import jdk.nashorn.internal.ir.debug.ObjectSizeCalculator;
+ import jdk.nashorn.internal.runtime.CodeInstaller;
+-import jdk.nashorn.internal.runtime.DebugLogger;
++import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.ErrorManager;
++import jdk.nashorn.internal.runtime.FunctionInitializer;
++import jdk.nashorn.internal.runtime.ParserException;
++import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
+ import jdk.nashorn.internal.runtime.ScriptEnvironment;
++import jdk.nashorn.internal.runtime.ScriptObject;
++import jdk.nashorn.internal.runtime.ScriptRuntime;
+ import jdk.nashorn.internal.runtime.Source;
+-import jdk.nashorn.internal.runtime.Timing;
+-import jdk.nashorn.internal.runtime.options.Options;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
+
+ /**
+ * Responsible for converting JavaScripts to java byte code. Main entry
+@@ -75,7 +76,8 @@
+ * predefined Code installation policy, given to it at construction time.
+ * @see CodeInstaller
+ */
+-public final class Compiler {
++@Logger(name="compiler")
++public final class Compiler implements Loggable {
+
+ /** Name of the scripts package */
+ public static final String SCRIPTS_PACKAGE = "jdk/nashorn/internal/scripts";
+@@ -83,9 +85,15 @@
+ /** Name of the objects package */
+ public static final String OBJECTS_PACKAGE = "jdk/nashorn/internal/objects";
+
+- private Source source;
++ private final ScriptEnvironment env;
+
+- private String sourceName;
++ private final Source source;
++
++ private final String sourceName;
++
++ private final ErrorManager errors;
++
++ private final boolean optimistic;
+
+ private final Map<String, byte[]> bytecode;
+
+@@ -93,21 +101,233 @@
+
+ private final ConstantData constantData;
+
+- private final CompilationSequence sequence;
+-
+- private final ScriptEnvironment env;
+-
+- private String scriptName;
+-
+- private boolean strict;
+-
+ private final CodeInstaller<ScriptEnvironment> installer;
+
+- private final TemporarySymbols temporarySymbols = new TemporarySymbols();
+-
+ /** logger for compiler, trampolines, splits and related code generation events
+ * that affect classes */
+- public static final DebugLogger LOG = new DebugLogger("compiler");
++ private final DebugLogger log;
++
++ private final Context context;
++
++ private final TypeMap types;
++
++ // Runtime scope in effect at the time of the compilation. Used to evaluate types of expressions and prevent overly
++ // optimistic assumptions (which will lead to unnecessary deoptimizing recompilations).
++ private final TypeEvaluator typeEvaluator;
++
++ private final boolean strict;
++
++ private final boolean onDemand;
++
++ /**
++ * If this is a recompilation, this is how we pass in the invalidations, e.g. programPoint=17, Type == int means
++ * that using whatever was at program point 17 as an int failed.
++ */
++ private final Map<Integer, Type> invalidatedProgramPoints;
++
++ /**
++ * Descriptor of the location where we write the type information after compilation.
++ */
++ private final Object typeInformationFile;
++
++ /**
++ * Compile unit name of first compile unit - this prefix will be used for all
++ * classes that a compilation generates.
++ */
++ private final String firstCompileUnitName;
++
++ /**
++ * Contains the program point that should be used as the continuation entry point, as well as all previous
++ * continuation entry points executed as part of a single logical invocation of the function. In practical terms, if
++ * we execute a rest-of method from the program point 17, but then we hit deoptimization again during it at program
++ * point 42, and execute a rest-of method from the program point 42, and then we hit deoptimization again at program
++ * point 57 and are compiling a rest-of method for it, the values in the array will be [57, 42, 17]. This is only
++ * set when compiling a rest-of method. If this method is a rest-of for a non-rest-of method, the array will have
++ * one element. If it is a rest-of for a rest-of, the array will have two elements, and so on.
++ */
++ private final int[] continuationEntryPoints;
++
++ /**
++ * ScriptFunction data for what is being compile, where applicable.
++ * TODO: make this immutable, propagate it through the CompilationPhases
++ */
++ private RecompilableScriptFunctionData compiledFunction;
++
++ /**
++ * Most compile unit names are longer than the default StringBuilder buffer,
++ * worth startup performance when massive class generation is going on to increase
++ * this
++ */
++ private static final int COMPILE_UNIT_NAME_BUFFER_SIZE = 32;
++
++ private final Map<Integer, byte[]> serializedAsts = new HashMap<>();
++
++ /**
++ * Compilation phases that a compilation goes through
++ */
++ public static class CompilationPhases implements Iterable<CompilationPhase> {
++
++ /**
++ * Singleton that describes compilation up to the phase where a function can be serialized.
++ */
++ private final static CompilationPhases COMPILE_UPTO_SERIALIZABLE = new CompilationPhases(
++ "Common initial phases",
++ CompilationPhase.CONSTANT_FOLDING_PHASE,
++ CompilationPhase.LOWERING_PHASE,
++ CompilationPhase.TRANSFORM_BUILTINS_PHASE,
++ CompilationPhase.SPLITTING_PHASE,
++ CompilationPhase.PROGRAM_POINT_PHASE,
++ CompilationPhase.SERIALIZE_SPLIT_PHASE
++ );
++
++ private final static CompilationPhases COMPILE_SERIALIZABLE_UPTO_BYTECODE = new CompilationPhases(
++ "After common phases, before bytecode generator",
++ CompilationPhase.SYMBOL_ASSIGNMENT_PHASE,
++ CompilationPhase.SCOPE_DEPTH_COMPUTATION_PHASE,
++ CompilationPhase.OPTIMISTIC_TYPE_ASSIGNMENT_PHASE,
++ CompilationPhase.LOCAL_VARIABLE_TYPE_CALCULATION_PHASE
++ );
++
++ /**
++ * Singleton that describes additional steps to be taken after deserializing, all the way up to (but not
++ * including) generating and installing code.
++ */
++ public final static CompilationPhases RECOMPILE_SERIALIZED_UPTO_BYTECODE = new CompilationPhases(
++ "Recompile serialized function up to bytecode",
++ CompilationPhase.REINITIALIZE_SERIALIZED,
++ COMPILE_SERIALIZABLE_UPTO_BYTECODE
++ );
++
++ /**
++ * Singleton that describes back end of method generation, given that we have generated the normal
++ * method up to CodeGenerator as in {@link CompilationPhases#COMPILE_UPTO_BYTECODE}
++ */
++ public final static CompilationPhases GENERATE_BYTECODE_AND_INSTALL = new CompilationPhases(
++ "Generate bytecode and install",
++ CompilationPhase.BYTECODE_GENERATION_PHASE,
++ CompilationPhase.INSTALL_PHASE
++ );
++
++ /** Singleton that describes compilation up to the CodeGenerator, but not actually generating code */
++ public final static CompilationPhases COMPILE_UPTO_BYTECODE = new CompilationPhases(
++ "Compile upto bytecode",
++ COMPILE_UPTO_SERIALIZABLE,
++ COMPILE_SERIALIZABLE_UPTO_BYTECODE);
++
++ /** Singleton that describes a standard eager compilation, but no installation, for example used by --compile-only */
++ public final static CompilationPhases COMPILE_ALL_NO_INSTALL = new CompilationPhases(
++ "Compile without install",
++ COMPILE_UPTO_BYTECODE,
++ CompilationPhase.BYTECODE_GENERATION_PHASE);
++
++ /** Singleton that describes a standard eager compilation - this includes code installation */
++ public final static CompilationPhases COMPILE_ALL = new CompilationPhases(
++ "Full eager compilation",
++ COMPILE_UPTO_BYTECODE,
++ GENERATE_BYTECODE_AND_INSTALL);
++
++ /** Singleton that describes a full compilation - this includes code installation - from serialized state*/
++ public final static CompilationPhases COMPILE_ALL_SERIALIZED = new CompilationPhases(
++ "Eager compilation from serializaed state",
++ RECOMPILE_SERIALIZED_UPTO_BYTECODE,
++ GENERATE_BYTECODE_AND_INSTALL);
++
++ /**
++ * Singleton that describes restOf method generation, given that we have generated the normal
++ * method up to CodeGenerator as in {@link CompilationPhases#COMPILE_UPTO_BYTECODE}
++ */
++ public final static CompilationPhases GENERATE_BYTECODE_AND_INSTALL_RESTOF = new CompilationPhases(
++ "Generate bytecode and install - RestOf method",
++ CompilationPhase.REUSE_COMPILE_UNITS_PHASE,
++ GENERATE_BYTECODE_AND_INSTALL);
++
++ /** Compile all for a rest of method */
++ public final static CompilationPhases COMPILE_ALL_RESTOF = new CompilationPhases(
++ "Compile all, rest of",
++ COMPILE_UPTO_BYTECODE,
++ GENERATE_BYTECODE_AND_INSTALL_RESTOF);
++
++ /** Compile from serialized for a rest of method */
++ public final static CompilationPhases COMPILE_SERIALIZED_RESTOF = new CompilationPhases(
++ "Compile serialized, rest of",
++ RECOMPILE_SERIALIZED_UPTO_BYTECODE,
++ GENERATE_BYTECODE_AND_INSTALL_RESTOF);
++
++ private final List<CompilationPhase> phases;
++
++ private final String desc;
++
++ private CompilationPhases(final String desc, final CompilationPhase... phases) {
++ this(desc, Arrays.asList(phases));
++ }
++
++ private CompilationPhases(final String desc, final CompilationPhases base, final CompilationPhase... phases) {
++ this(desc, concat(base.phases, Arrays.asList(phases)));
++ }
++
++ private CompilationPhases(final String desc, final CompilationPhase first, final CompilationPhases rest) {
++ this(desc, concat(Collections.singletonList(first), rest.phases));
++ }
++
++ private CompilationPhases(final String desc, final CompilationPhases base) {
++ this(desc, base.phases);
++ }
++
++ private CompilationPhases(final String desc, final CompilationPhases... bases) {
++ this(desc, concatPhases(bases));
++ }
++
++ private CompilationPhases(final String desc, final List<CompilationPhase> phases) {
++ this.desc = desc;
++ this.phases = phases;
++ }
++
++ private static List<CompilationPhase> concatPhases(final CompilationPhases[] bases) {
++ final ArrayList<CompilationPhase> l = new ArrayList<>();
++ for(final CompilationPhases base: bases) {
++ l.addAll(base.phases);
++ }
++ l.trimToSize();
++ return l;
++ }
++
++ private static <T> List<T> concat(final List<T> l1, final List<T> l2) {
++ final ArrayList<T> l = new ArrayList<>(l1);
++ l.addAll(l2);
++ l.trimToSize();
++ return l;
++ }
++
++ @Override
++ public String toString() {
++ return "'" + desc + "' " + phases.toString();
++ }
++
++ boolean contains(final CompilationPhase phase) {
++ return phases.contains(phase);
++ }
++
++ @Override
++ public Iterator<CompilationPhase> iterator() {
++ return phases.iterator();
++ }
++
++ boolean isRestOfCompilation() {
++ return this == COMPILE_ALL_RESTOF || this == GENERATE_BYTECODE_AND_INSTALL_RESTOF || this == COMPILE_SERIALIZED_RESTOF;
++ }
++
++ String getDesc() {
++ return desc;
++ }
++
++ String toString(final String prefix) {
++ final StringBuilder sb = new StringBuilder();
++ for (final CompilationPhase phase : phases) {
++ sb.append(prefix).append(phase).append('\n');
++ }
++ return sb.toString();
++ }
++ }
+
+ /**
+ * This array contains names that need to be reserved at the start
+@@ -124,374 +344,343 @@
+ ARGUMENTS.symbolName()
+ };
+
+- /**
+- * This class makes it possible to do your own compilation sequence
+- * from the code generation package. There are predefined compilation
+- * sequences already
+- */
+- @SuppressWarnings("serial")
+- static class CompilationSequence extends LinkedList<CompilationPhase> {
++ // per instance
++ private final int compilationId = COMPILATION_ID.getAndIncrement();
+
+- CompilationSequence(final CompilationPhase... phases) {
+- super(Arrays.asList(phases));
+- }
++ // per instance
++ private final AtomicInteger nextCompileUnitId = new AtomicInteger(0);
+
+- CompilationSequence(final CompilationSequence sequence) {
+- this(sequence.toArray(new CompilationPhase[sequence.size()]));
+- }
+-
+- CompilationSequence insertAfter(final CompilationPhase phase, final CompilationPhase newPhase) {
+- final CompilationSequence newSeq = new CompilationSequence();
+- for (final CompilationPhase elem : this) {
+- newSeq.add(phase);
+- if (elem.equals(phase)) {
+- newSeq.add(newPhase);
+- }
+- }
+- assert newSeq.contains(newPhase);
+- return newSeq;
+- }
+-
+- CompilationSequence insertBefore(final CompilationPhase phase, final CompilationPhase newPhase) {
+- final CompilationSequence newSeq = new CompilationSequence();
+- for (final CompilationPhase elem : this) {
+- if (elem.equals(phase)) {
+- newSeq.add(newPhase);
+- }
+- newSeq.add(phase);
+- }
+- assert newSeq.contains(newPhase);
+- return newSeq;
+- }
+-
+- CompilationSequence insertFirst(final CompilationPhase phase) {
+- final CompilationSequence newSeq = new CompilationSequence(this);
+- newSeq.addFirst(phase);
+- return newSeq;
+- }
+-
+- CompilationSequence insertLast(final CompilationPhase phase) {
+- final CompilationSequence newSeq = new CompilationSequence(this);
+- newSeq.addLast(phase);
+- return newSeq;
+- }
+- }
++ private static final AtomicInteger COMPILATION_ID = new AtomicInteger(0);
+
+ /**
+- * Environment information known to the compile, e.g. params
++ * Constructor
++ *
++ * @param context context
++ * @param env script environment
++ * @param installer code installer
++ * @param source source to compile
++ * @param errors error manager
++ * @param isStrict is this a strict compilation
+ */
+- public static class Hints {
+- private final Type[] paramTypes;
+-
+- /** singleton empty hints */
+- public static final Hints EMPTY = new Hints();
+-
+- private Hints() {
+- this.paramTypes = null;
+- }
+-
+- /**
+- * Constructor
+- * @param paramTypes known parameter types for this callsite
+- */
+- public Hints(final Type[] paramTypes) {
+- this.paramTypes = paramTypes;
+- }
+-
+- /**
+- * Get the parameter type for this parameter position, or
+- * null if now known
+- * @param pos position
+- * @return parameter type for this callsite if known
+- */
+- public Type getParameterType(final int pos) {
+- if (paramTypes != null && pos < paramTypes.length) {
+- return paramTypes[pos];
+- }
+- return null;
+- }
+- }
+-
+- /**
+- * Standard (non-lazy) compilation, that basically will take an entire script
+- * and JIT it at once. This can lead to long startup time and fewer type
+- * specializations
+- */
+- final static CompilationSequence SEQUENCE_EAGER = new CompilationSequence(
+- CompilationPhase.CONSTANT_FOLDING_PHASE,
+- CompilationPhase.LOWERING_PHASE,
+- CompilationPhase.ATTRIBUTION_PHASE,
+- CompilationPhase.RANGE_ANALYSIS_PHASE,
+- CompilationPhase.SPLITTING_PHASE,
+- CompilationPhase.TYPE_FINALIZATION_PHASE,
+- CompilationPhase.BYTECODE_GENERATION_PHASE);
+-
+- final static CompilationSequence SEQUENCE_LAZY =
+- SEQUENCE_EAGER.insertFirst(CompilationPhase.LAZY_INITIALIZATION_PHASE);
+-
+- private static CompilationSequence sequence(final boolean lazy) {
+- return lazy ? SEQUENCE_LAZY : SEQUENCE_EAGER;
+- }
+-
+- boolean isLazy() {
+- return sequence == SEQUENCE_LAZY;
+- }
+-
+- private static String lazyTag(final FunctionNode functionNode) {
+- if (functionNode.isLazy()) {
+- return '$' + LAZY.symbolName() + '$' + functionNode.getName();
+- }
+- return "";
++ public Compiler(
++ final Context context,
++ final ScriptEnvironment env,
++ final CodeInstaller<ScriptEnvironment> installer,
++ final Source source,
++ final ErrorManager errors,
++ final boolean isStrict) {
++ this(context, env, installer, source, errors, isStrict, false, null, null, null, null, null, null);
+ }
+
+ /**
+ * Constructor
+ *
+- * @param env script environment
+- * @param installer code installer
+- * @param sequence {@link Compiler.CompilationSequence} of {@link CompilationPhase}s to apply as this compilation
+- * @param strict should this compilation use strict mode semantics
++ * @param context context
++ * @param env script environment
++ * @param installer code installer
++ * @param source source to compile
++ * @param errors error manager
++ * @param isStrict is this a strict compilation
++ * @param isOnDemand is this an on demand compilation
++ * @param compiledFunction compiled function, if any
++ * @param types parameter and return value type information, if any is known
++ * @param invalidatedProgramPoints invalidated program points for recompilation
++ * @param typeInformationFile descriptor of the location where type information is persisted
++ * @param continuationEntryPoints continuation entry points for restof method
++ * @param runtimeScope runtime scope for recompilation type lookup in {@code TypeEvaluator}
+ */
+- //TODO support an array of FunctionNodes for batch lazy compilation
+- Compiler(final ScriptEnvironment env, final CodeInstaller<ScriptEnvironment> installer, final CompilationSequence sequence, final boolean strict) {
+- this.env = env;
+- this.sequence = sequence;
+- this.installer = installer;
+- this.constantData = new ConstantData();
+- this.compileUnits = new TreeSet<>();
+- this.bytecode = new LinkedHashMap<>();
++ @SuppressWarnings("unused")
++ public Compiler(
++ final Context context,
++ final ScriptEnvironment env,
++ final CodeInstaller<ScriptEnvironment> installer,
++ final Source source,
++ final ErrorManager errors,
++ final boolean isStrict,
++ final boolean isOnDemand,
++ final RecompilableScriptFunctionData compiledFunction,
++ final TypeMap types,
++ final Map<Integer, Type> invalidatedProgramPoints,
++ final Object typeInformationFile,
++ final int[] continuationEntryPoints,
++ final ScriptObject runtimeScope) {
++ this.context = context;
++ this.env = env;
++ this.installer = installer;
++ this.constantData = new ConstantData();
++ this.compileUnits = CompileUnit.createCompileUnitSet();
++ this.bytecode = new LinkedHashMap<>();
++ this.log = initLogger(context);
++ this.source = source;
++ this.errors = errors;
++ this.sourceName = FunctionNode.getSourceName(source);
++ this.onDemand = isOnDemand;
++ this.compiledFunction = compiledFunction;
++ this.types = types;
++ this.invalidatedProgramPoints = invalidatedProgramPoints == null ? new HashMap<Integer, Type>() : invalidatedProgramPoints;
++ this.typeInformationFile = typeInformationFile;
++ this.continuationEntryPoints = continuationEntryPoints == null ? null: continuationEntryPoints.clone();
++ this.typeEvaluator = new TypeEvaluator(this, runtimeScope);
++ this.firstCompileUnitName = firstCompileUnitName();
++ this.strict = isStrict;
++
++ this.optimistic = env._optimistic_types;
+ }
+
+- private void initCompiler(final FunctionNode functionNode) {
+- this.strict = strict || functionNode.isStrict();
+- final StringBuilder sb = new StringBuilder();
+- sb.append(functionNode.uniqueName(DEFAULT_SCRIPT_NAME.symbolName() + lazyTag(functionNode))).
+- append('$').
+- append(safeSourceName(functionNode.getSource()));
+- this.source = functionNode.getSource();
+- this.sourceName = functionNode.getSourceName();
+- this.scriptName = sb.toString();
++ private static String safeSourceName(final ScriptEnvironment env, final CodeInstaller<ScriptEnvironment> installer, final Source source) {
++ String baseName = new File(source.getName()).getName();
++
++ final int index = baseName.lastIndexOf(".js");
++ if (index != -1) {
++ baseName = baseName.substring(0, index);
++ }
++
++ baseName = baseName.replace('.', '_').replace('-', '_');
++ if (!env._loader_per_compile) {
++ baseName = baseName + installer.getUniqueScriptId();
++ }
++
++ // ASM's bytecode verifier does not allow JVM allowed safe escapes using '\' as escape char.
++ // While ASM accepts such escapes for method names, field names, it enforces Java identifier
++ // for class names. Workaround that ASM bug here by replacing JVM 'dangerous' chars with '_'
++ // rather than safe encoding using '\'.
++ final String mangled = env._verify_code? replaceDangerChars(baseName) : NameCodec.encode(baseName);
++ return mangled != null ? mangled : baseName;
++ }
++
++ private static final String DANGEROUS_CHARS = "\\/.;:$[]<>";
++ private static String replaceDangerChars(final String name) {
++ final int len = name.length();
++ final StringBuilder buf = new StringBuilder();
++ for (int i = 0; i < len; i++) {
++ final char ch = name.charAt(i);
++ if (DANGEROUS_CHARS.indexOf(ch) != -1) {
++ buf.append('_');
++ } else {
++ buf.append(ch);
++ }
++ }
++ return buf.toString();
++ }
++
++ private String firstCompileUnitName() {
++ final StringBuilder sb = new StringBuilder(SCRIPTS_PACKAGE).
++ append('/').
++ append(CompilerConstants.DEFAULT_SCRIPT_NAME.symbolName()).
++ append('$');
++
++ if (isOnDemandCompilation()) {
++ sb.append(RecompilableScriptFunctionData.RECOMPILATION_PREFIX);
++ }
++
++ if (compilationId > 0) {
++ sb.append(compilationId).append('$');
++ }
++
++ if (types != null && compiledFunction.getFunctionNodeId() > 0) {
++ sb.append(compiledFunction.getFunctionNodeId());
++ final Type[] paramTypes = types.getParameterTypes(compiledFunction.getFunctionNodeId());
++ for (final Type t : paramTypes) {
++ sb.append(Type.getShortSignatureDescriptor(t));
++ }
++ sb.append('$');
++ }
++
++ sb.append(Compiler.safeSourceName(env, installer, source));
++
++ return sb.toString();
++ }
++
++ void declareLocalSymbol(final String symbolName) {
++ typeEvaluator.declareLocalSymbol(symbolName);
++ }
++
++ void setData(final RecompilableScriptFunctionData data) {
++ assert this.compiledFunction == null : data;
++ this.compiledFunction = data;
++ }
++
++ @Override
++ public DebugLogger getLogger() {
++ return log;
++ }
++
++ @Override
++ public DebugLogger initLogger(final Context ctxt) {
++ final boolean optimisticTypes = env._optimistic_types;
++ final boolean lazyCompilation = env._lazy_compilation;
++
++ return ctxt.getLogger(this.getClass(), new Consumer<DebugLogger>() {
++ @Override
++ public void accept(final DebugLogger newLogger) {
++ if (!lazyCompilation) {
++ newLogger.warning("WARNING: Running with lazy compilation switched off. This is not a default setting.");
++ }
++ newLogger.warning("Optimistic types are ", optimisticTypes ? "ENABLED." : "DISABLED.");
++ }
++ });
++ }
++
++ ScriptEnvironment getScriptEnvironment() {
++ return env;
++ }
++
++ boolean isOnDemandCompilation() {
++ return onDemand;
++ }
++
++ boolean useOptimisticTypes() {
++ return optimistic;
++ }
++
++ Context getContext() {
++ return context;
++ }
++
++ Type getOptimisticType(final Optimistic node) {
++ return typeEvaluator.getOptimisticType(node);
+ }
+
+ /**
+- * Constructor
+- *
+- * @param installer code installer
+- * @param strict should this compilation use strict mode semantics
++ * Returns true if the expression can be safely evaluated, and its value is an object known to always use
++ * String as the type of its property names retrieved through
++ * {@link ScriptRuntime#toPropertyIterator(Object)}. It is used to avoid optimistic assumptions about its
++ * property name types.
++ * @param expr the expression to test
++ * @return true if the expression can be safely evaluated, and its value is an object known to always use
++ * String as the type of its property iterators.
+ */
+- public Compiler(final CodeInstaller<ScriptEnvironment> installer, final boolean strict) {
+- this(installer.getOwner(), installer, sequence(installer.getOwner()._lazy_compilation), strict);
++ boolean hasStringPropertyIterator(final Expression expr) {
++ return typeEvaluator.hasStringPropertyIterator(expr);
++ }
++
++ void addInvalidatedProgramPoint(final int programPoint, final Type type) {
++ invalidatedProgramPoints.put(programPoint, type);
++ }
++
++
++ /**
++ * Returns a copy of this compiler's current mapping of invalidated optimistic program points to their types. The
++ * copy is not live with regard to changes in state in this compiler instance, and is mutable.
++ * @return a copy of this compiler's current mapping of invalidated optimistic program points to their types.
++ */
++ public Map<Integer, Type> getInvalidatedProgramPoints() {
++ return invalidatedProgramPoints == null ? null : new TreeMap<>(invalidatedProgramPoints);
++ }
++
++ TypeMap getTypeMap() {
++ return types;
++ }
++
++ MethodType getCallSiteType(final FunctionNode fn) {
++ if (types == null || !isOnDemandCompilation()) {
++ return null;
++ }
++ return types.getCallSiteType(fn);
++ }
++
++ Type getParamType(final FunctionNode fn, final int pos) {
++ return types == null ? null : types.get(fn, pos);
+ }
+
+ /**
+- * Constructor - compilation will use the same strict semantics as in script environment
++ * Do a compilation job
+ *
+- * @param installer code installer
++ * @param functionNode function node to compile
++ * @param phases phases of compilation transforms to apply to function
++
++ * @return transformed function
++ *
++ * @throws CompilationException if error occurs during compilation
+ */
+- public Compiler(final CodeInstaller<ScriptEnvironment> installer) {
+- this(installer.getOwner(), installer, sequence(installer.getOwner()._lazy_compilation), installer.getOwner()._strict);
+- }
++ public FunctionNode compile(final FunctionNode functionNode, final CompilationPhases phases) throws CompilationException {
++ if (log.isEnabled()) {
++ log.info(">> Starting compile job for ", DebugLogger.quote(functionNode.getName()), " phases=", quote(phases.getDesc()));
++ log.indent();
++ }
+
+- /**
+- * Constructor - compilation needs no installer, but uses a script environment
+- * Used in "compile only" scenarios
+- * @param env a script environment
+- */
+- public Compiler(final ScriptEnvironment env) {
+- this(env, null, sequence(env._lazy_compilation), env._strict);
+- }
++ final String name = DebugLogger.quote(functionNode.getName());
+
+- private static void printMemoryUsage(final String phaseName, final FunctionNode functionNode) {
+- LOG.info(phaseName + " finished. Doing IR size calculation...");
+-
+- final ObjectSizeCalculator osc = new ObjectSizeCalculator(ObjectSizeCalculator.getEffectiveMemoryLayoutSpecification());
+- osc.calculateObjectSize(functionNode);
+-
+- final List<ClassHistogramElement> list = osc.getClassHistogram();
+-
+- final StringBuilder sb = new StringBuilder();
+- final long totalSize = osc.calculateObjectSize(functionNode);
+- sb.append(phaseName).append(" Total size = ").append(totalSize / 1024 / 1024).append("MB");
+- LOG.info(sb);
+-
+- Collections.sort(list, new Comparator<ClassHistogramElement>() {
+- @Override
+- public int compare(ClassHistogramElement o1, ClassHistogramElement o2) {
+- final long diff = o1.getBytes() - o2.getBytes();
+- if (diff < 0) {
+- return 1;
+- } else if (diff > 0) {
+- return -1;
+- } else {
+- return 0;
+- }
+- }
+- });
+- for (final ClassHistogramElement e : list) {
+- final String line = String.format(" %-48s %10d bytes (%8d instances)", e.getClazz(), e.getBytes(), e.getInstances());
+- LOG.info(line);
+- if (e.getBytes() < totalSize / 200) {
+- LOG.info(" ...");
+- break; // never mind, so little memory anyway
+- }
+- }
+- }
+-
+- /**
+- * Execute the compilation this Compiler was created with
+- * @param functionNode function node to compile from its current state
+- * @throws CompilationException if something goes wrong
+- * @return function node that results from code transforms
+- */
+- public FunctionNode compile(final FunctionNode functionNode) throws CompilationException {
+ FunctionNode newFunctionNode = functionNode;
+
+- initCompiler(newFunctionNode); //TODO move this state into functionnode?
+-
+ for (final String reservedName : RESERVED_NAMES) {
+ newFunctionNode.uniqueName(reservedName);
+ }
+
+- final boolean fine = !LOG.levelAbove(Level.FINE);
+- final boolean info = !LOG.levelAbove(Level.INFO);
++ final boolean info = log.levelFinerThanOrEqual(Level.INFO);
++
++ final DebugLogger timeLogger = env.isTimingEnabled() ? env._timing.getLogger() : null;
+
+ long time = 0L;
+
+- for (final CompilationPhase phase : sequence) {
+- newFunctionNode = phase.apply(this, newFunctionNode);
++ for (final CompilationPhase phase : phases) {
++ log.fine(phase, " starting for ", name);
++
++ try {
++ newFunctionNode = phase.apply(this, phases, newFunctionNode);
++ } catch (final ParserException error) {
++ errors.error(error);
++ if (env._dump_on_error) {
++ error.printStackTrace(env.getErr());
++ }
++ return null;
++ }
++
++ log.fine(phase, " done for function ", quote(name));
+
+ if (env._print_mem_usage) {
+- printMemoryUsage(phase.toString(), newFunctionNode);
++ printMemoryUsage(functionNode, phase.toString());
+ }
+
+- final long duration = Timing.isEnabled() ? (phase.getEndTime() - phase.getStartTime()) : 0L;
+- time += duration;
+-
+- if (fine) {
+- final StringBuilder sb = new StringBuilder();
+-
+- sb.append(phase.toString()).
+- append(" done for function '").
+- append(newFunctionNode.getName()).
+- append('\'');
+-
+- if (duration > 0L) {
+- sb.append(" in ").
+- append(duration).
+- append(" ms ");
+- }
+-
+- LOG.fine(sb);
+- }
++ time += (env.isTimingEnabled() ? phase.getEndTime() - phase.getStartTime() : 0L);
+ }
+
++ if (typeInformationFile != null && !phases.isRestOfCompilation()) {
++ OptimisticTypesPersistence.store(typeInformationFile, invalidatedProgramPoints);
++ }
++
++ log.unindent();
++
+ if (info) {
+- final StringBuilder sb = new StringBuilder();
+- sb.append("Compile job for '").
+- append(newFunctionNode.getSource()).
++ final StringBuilder sb = new StringBuilder("<< Finished compile job for ");
++ sb.append(newFunctionNode.getSource()).
+ append(':').
+- append(newFunctionNode.getName()).
+- append("' finished");
++ append(quote(newFunctionNode.getName()));
+
+- if (time > 0L) {
+- sb.append(" in ").
+- append(time).
+- append(" ms");
++ if (time > 0L && timeLogger != null) {
++ assert env.isTimingEnabled();
++ sb.append(" in ").append(time).append(" ms");
+ }
+-
+- LOG.info(sb);
++ log.info(sb);
+ }
+
+ return newFunctionNode;
+ }
+
+- private Class<?> install(final String className, final byte[] code, final Object[] constants) {
+- return installer.install(className, code, source, constants);
++ Source getSource() {
++ return source;
++ }
++
++ Map<String, byte[]> getBytecode() {
++ return Collections.unmodifiableMap(bytecode);
+ }
+
+ /**
+- * Install compiled classes into a given loader
+- * @param functionNode function node to install - must be in {@link CompilationState#EMITTED} state
+- * @return root script class - if there are several compile units they will also be installed
++ * Reset bytecode cache for compiler reuse.
+ */
+- public Class<?> install(final FunctionNode functionNode) {
+- final long t0 = Timing.isEnabled() ? System.currentTimeMillis() : 0L;
++ void clearBytecode() {
++ bytecode.clear();
++ }
+
+- assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " has no bytecode and cannot be installed";
+-
+- final Map<String, Class<?>> installedClasses = new HashMap<>();
+- final Object[] constants = getConstantData().toArray();
+-
+- final String rootClassName = firstCompileUnitName();
+- final byte[] rootByteCode = bytecode.get(rootClassName);
+- final Class<?> rootClass = install(rootClassName, rootByteCode, constants);
+-
+- if (!isLazy()) {
+- installer.storeCompiledScript(source, rootClassName, bytecode, constants);
+- }
+-
+- int length = rootByteCode.length;
+-
+- installedClasses.put(rootClassName, rootClass);
+-
+- for (final Entry<String, byte[]> entry : bytecode.entrySet()) {
+- final String className = entry.getKey();
+- if (className.equals(rootClassName)) {
+- continue;
+- }
+- final byte[] code = entry.getValue();
+- length += code.length;
+-
+- installedClasses.put(className, install(className, code, constants));
+- }
+-
+- for (final CompileUnit unit : compileUnits) {
+- unit.setCode(installedClasses.get(unit.getUnitClassName()));
+- }
+-
+- final StringBuilder sb;
+- if (LOG.isEnabled()) {
+- sb = new StringBuilder();
+- sb.append("Installed class '").
+- append(rootClass.getSimpleName()).
+- append('\'').
+- append(" bytes=").
+- append(length).
+- append('.');
+- if (bytecode.size() > 1) {
+- sb.append(' ').append(bytecode.size()).append(" compile units.");
+- }
+- } else {
+- sb = null;
+- }
+-
+- if (Timing.isEnabled()) {
+- final long duration = System.currentTimeMillis() - t0;
+- Timing.accumulateTime("[Code Installation]", duration);
+- if (sb != null) {
+- sb.append(" Install time: ").append(duration).append(" ms");
+- }
+- }
+-
+- if (sb != null) {
+- LOG.fine(sb);
+- }
+-
+- return rootClass;
++ CompileUnit getFirstCompileUnit() {
++ assert !compileUnits.isEmpty();
++ return compileUnits.iterator().next();
+ }
+
+ Set<CompileUnit> getCompileUnits() {
+ return compileUnits;
+ }
+
+- boolean getStrictMode() {
+- return strict;
+- }
+-
+- void setStrictMode(final boolean strict) {
+- this.strict = strict;
+- }
+-
+ ConstantData getConstantData() {
+ return constantData;
+ }
+@@ -500,76 +689,102 @@
+ return installer;
+ }
+
+- TemporarySymbols getTemporarySymbols() {
+- return temporarySymbols;
+- }
+-
+ void addClass(final String name, final byte[] code) {
+ bytecode.put(name, code);
+ }
+
+- ScriptEnvironment getEnv() {
+- return this.env;
++ String nextCompileUnitName() {
++ final StringBuilder sb = new StringBuilder(COMPILE_UNIT_NAME_BUFFER_SIZE);
++ sb.append(firstCompileUnitName);
++ final int cuid = nextCompileUnitId.getAndIncrement();
++ if (cuid > 0) {
++ sb.append("$cu").append(cuid);
++ }
++
++ return sb.toString();
+ }
+
+- private String safeSourceName(final Source src) {
+- String baseName = new File(src.getName()).getName();
++ Map<Integer, FunctionInitializer> functionInitializers;
+
+- final int index = baseName.lastIndexOf(".js");
+- if (index != -1) {
+- baseName = baseName.substring(0, index);
++ void addFunctionInitializer(final RecompilableScriptFunctionData functionData, final FunctionNode functionNode) {
++ if (functionInitializers == null) {
++ functionInitializers = new HashMap<>();
+ }
+-
+- baseName = baseName.replace('.', '_').replace('-', '_');
+- if (! env._loader_per_compile) {
+- baseName = baseName + installer.getUniqueScriptId();
++ if (!functionInitializers.containsKey(functionData)) {
++ functionInitializers.put(functionData.getFunctionNodeId(), new FunctionInitializer(functionNode));
+ }
+- final String mangled = NameCodec.encode(baseName);
+-
+- return mangled != null ? mangled : baseName;
+ }
+
+- private int nextCompileUnitIndex() {
+- return compileUnits.size() + 1;
++ Map<Integer, FunctionInitializer> getFunctionInitializers() {
++ return functionInitializers;
+ }
+
+- String firstCompileUnitName() {
+- return SCRIPTS_PACKAGE + '/' + scriptName;
++ /**
++ * Persist current compilation with the given {@code cacheKey}.
++ * @param cacheKey cache key
++ * @param functionNode function node
++ */
++ public void persistClassInfo(final String cacheKey, final FunctionNode functionNode) {
++ if (cacheKey != null && env._persistent_cache) {
++ Map<Integer, FunctionInitializer> initializers;
++ // If this is an on-demand compilation create a function initializer for the function being compiled.
++ // Otherwise use function initializer map generated by codegen.
++ if (functionInitializers == null) {
++ initializers = new HashMap<>();
++ final FunctionInitializer initializer = new FunctionInitializer(functionNode, getInvalidatedProgramPoints());
++ initializers.put(functionNode.getId(), initializer);
++ } else {
++ initializers = functionInitializers;
++ }
++ final String mainClassName = getFirstCompileUnit().getUnitClassName();
++ installer.storeScript(cacheKey, source, mainClassName, bytecode, initializers, constantData.toArray(), compilationId);
++ }
+ }
+
+- private String nextCompileUnitName() {
+- return firstCompileUnitName() + '$' + nextCompileUnitIndex();
++ /**
++ * Make sure the next compilation id is greater than {@code value}.
++ * @param value compilation id value
++ */
++ public static void updateCompilationId(final int value) {
++ if (value >= COMPILATION_ID.get()) {
++ COMPILATION_ID.set(value + 1);
++ }
+ }
+
+ CompileUnit addCompileUnit(final long initialWeight) {
+- return addCompileUnit(nextCompileUnitName(), initialWeight);
+- }
+-
+- CompileUnit addCompileUnit(final String unitClassName) {
+- return addCompileUnit(unitClassName, 0L);
+- }
+-
+- private CompileUnit addCompileUnit(final String unitClassName, final long initialWeight) {
+- final CompileUnit compileUnit = initCompileUnit(unitClassName, initialWeight);
++ final CompileUnit compileUnit = createCompileUnit(initialWeight);
+ compileUnits.add(compileUnit);
+- LOG.fine("Added compile unit ", compileUnit);
++ log.fine("Added compile unit ", compileUnit);
+ return compileUnit;
+ }
+
+- private CompileUnit initCompileUnit(final String unitClassName, final long initialWeight) {
+- final ClassEmitter classEmitter = new ClassEmitter(env, sourceName, unitClassName, strict);
++ CompileUnit createCompileUnit(final String unitClassName, final long initialWeight) {
++ final ClassEmitter classEmitter = new ClassEmitter(context, sourceName, unitClassName, isStrict());
+ final CompileUnit compileUnit = new CompileUnit(unitClassName, classEmitter, initialWeight);
+-
+ classEmitter.begin();
+
+- final MethodEmitter initMethod = classEmitter.init(EnumSet.of(Flag.PRIVATE));
+- initMethod.begin();
+- initMethod.load(Type.OBJECT, 0);
+- initMethod.newInstance(jdk.nashorn.internal.scripts.JS.class);
+- initMethod.returnVoid();
+- initMethod.end();
++ return compileUnit;
++ }
+
+- return compileUnit;
++ private CompileUnit createCompileUnit(final long initialWeight) {
++ return createCompileUnit(nextCompileUnitName(), initialWeight);
++ }
++
++ boolean isStrict() {
++ return strict;
++ }
++
++ void replaceCompileUnits(final Set<CompileUnit> newUnits) {
++ compileUnits.clear();
++ compileUnits.addAll(newUnits);
++ }
++
++ void serializeAst(final FunctionNode fn) {
++ serializedAsts.put(fn.getId(), AstSerializer.serialize(fn));
++ }
++
++ byte[] removeSerializedAst(final int fnId) {
++ return serializedAsts.remove(fnId);
+ }
+
+ CompileUnit findUnit(final long weight) {
+@@ -593,22 +808,65 @@
+ return name.replace('/', '.');
+ }
+
+- /**
+- * Should we use integers for arithmetic operations as well?
+- * TODO: We currently generate no overflow checks so this is
+- * disabled
+- *
+- * @return true if arithmetic operations should not widen integer
+- * operands by default.
+- */
+- static boolean shouldUseIntegerArithmetic() {
+- return USE_INT_ARITH;
++ RecompilableScriptFunctionData getScriptFunctionData(final int functionId) {
++ assert compiledFunction != null;
++ final RecompilableScriptFunctionData fn = compiledFunction.getScriptFunctionData(functionId);
++ assert fn != null : functionId;
++ return fn;
+ }
+
+- private static final boolean USE_INT_ARITH;
++ boolean isGlobalSymbol(final FunctionNode fn, final String name) {
++ return getScriptFunctionData(fn.getId()).isGlobalSymbol(fn, name);
++ }
+
+- static {
+- USE_INT_ARITH = Options.getBooleanProperty("nashorn.compiler.intarithmetic");
+- assert !USE_INT_ARITH : "Integer arithmetic is not enabled";
++ int[] getContinuationEntryPoints() {
++ return continuationEntryPoints;
++ }
++
++ Type getInvalidatedProgramPointType(final int programPoint) {
++ return invalidatedProgramPoints.get(programPoint);
++ }
++
++ private void printMemoryUsage(final FunctionNode functionNode, final String phaseName) {
++ if (!log.isEnabled()) {
++ return;
++ }
++
++ log.info(phaseName, "finished. Doing IR size calculation...");
++
++ final ObjectSizeCalculator osc = new ObjectSizeCalculator(ObjectSizeCalculator.getEffectiveMemoryLayoutSpecification());
++ osc.calculateObjectSize(functionNode);
++
++ final List<ClassHistogramElement> list = osc.getClassHistogram();
++ final StringBuilder sb = new StringBuilder();
++ final long totalSize = osc.calculateObjectSize(functionNode);
++
++ sb.append(phaseName).
++ append(" Total size = ").
++ append(totalSize / 1024 / 1024).
++ append("MB");
++ log.info(sb);
++
++ Collections.sort(list, new Comparator<ClassHistogramElement>() {
++ @Override
++ public int compare(final ClassHistogramElement o1, final ClassHistogramElement o2) {
++ final long diff = o1.getBytes() - o2.getBytes();
++ if (diff < 0) {
++ return 1;
++ } else if (diff > 0) {
++ return -1;
++ } else {
++ return 0;
++ }
++ }
++ });
++ for (final ClassHistogramElement e : list) {
++ final String line = String.format(" %-48s %10d bytes (%8d instances)", e.getClazz(), e.getBytes(), e.getInstances());
++ log.info(line);
++ if (e.getBytes() < totalSize / 200) {
++ log.info(" ...");
++ break; // never mind, so little memory anyway
++ }
++ }
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,7 +29,11 @@
+
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
++import java.util.HashSet;
+ import java.util.Iterator;
++import java.util.Set;
++import jdk.internal.org.objectweb.asm.MethodVisitor;
++import jdk.internal.org.objectweb.asm.Opcodes;
+ import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+@@ -41,7 +45,6 @@
+ */
+
+ public enum CompilerConstants {
+-
+ /** the __FILE__ variable */
+ __FILE__,
+
+@@ -51,9 +54,6 @@
+ /** the __LINE__ variable */
+ __LINE__,
+
+- /** lazy prefix for classes of jitted methods */
+- LAZY("Lazy"),
+-
+ /** constructor name */
+ INIT("<init>"),
+
+@@ -78,15 +78,18 @@
+ /** function prefix for anonymous functions */
+ ANON_FUNCTION_PREFIX("L:"),
+
+- /** method name for Java method that is script entry point */
+- RUN_SCRIPT("runScript"),
++ /** method name for Java method that is the program entry point */
++ PROGRAM(":program"),
++
++ /** method name for Java method that creates the script function for the program */
++ CREATE_PROGRAM_FUNCTION(":createProgramFunction"),
+
+ /**
+ * "this" name symbol for a parameter representing ECMAScript "this" in static methods that are compiled
+ * representations of ECMAScript functions. It is not assigned a slot, as its position in the method signature is
+ * dependent on other factors (most notably, callee can precede it).
+ */
+- THIS("this"),
++ THIS("this", Object.class),
+
+ /** this debugger symbol */
+ THIS_DEBUGGER(":this"),
+@@ -110,13 +113,16 @@
+ /** the internal arguments object, when necessary (not visible to scripts, can't be reassigned). */
+ ARGUMENTS(":arguments", ScriptObject.class),
+
++ /** prefix for apply-to-call exploded arguments */
++ EXPLODED_ARGUMENT_PREFIX(":xarg"),
++
+ /** prefix for iterators for for (x in ...) */
+ ITERATOR_PREFIX(":i", Iterator.class),
+
+ /** prefix for tag variable used for switch evaluation */
+ SWITCH_TAG_PREFIX(":s"),
+
+- /** prefix for all exceptions */
++ /** prefix for JVM exceptions */
+ EXCEPTION_PREFIX(":e", Throwable.class),
+
+ /** prefix for quick slots generated in Store */
+@@ -161,7 +167,7 @@
+ /** get map */
+ GET_MAP(":getMap"),
+
+- /** get map */
++ /** set map */
+ SET_MAP(":setMap"),
+
+ /** get array prefix */
+@@ -170,10 +176,22 @@
+ /** get array suffix */
+ GET_ARRAY_SUFFIX("$array");
+
++ /** To save memory - intern the compiler constant symbol names, as they are frequently reused */
++ static {
++ for (final CompilerConstants c : values()) {
++ final String symbolName = c.symbolName();
++ if (symbolName != null) {
++ symbolName.intern();
++ }
++ }
++ }
++
++ private static Set<String> symbolNames;
++
+ /**
+ * Prefix used for internal methods generated in script clases.
+ */
+- public static final String INTERNAL_METHOD_PREFIX = ":";
++ private static final String INTERNAL_METHOD_PREFIX = ":";
+
+ private final String symbolName;
+ private final Class<?> type;
+@@ -198,9 +216,28 @@
+ }
+
+ private CompilerConstants(final String symbolName, final Class<?> type, final int slot) {
+- this.symbolName = symbolName;
+- this.type = type;
+- this.slot = slot;
++ this.symbolName = symbolName;
++ this.type = type;
++ this.slot = slot;
++ }
++
++ /**
++ * Check whether a name is that of a reserved compiler constnat
++ * @param name name
++ * @return true if compiler constant name
++ */
++ public static boolean isCompilerConstant(final String name) {
++ ensureSymbolNames();
++ return symbolNames.contains(name);
++ }
++
++ private static void ensureSymbolNames() {
++ if(symbolNames == null) {
++ symbolNames = new HashSet<>();
++ for(final CompilerConstants cc: CompilerConstants.values()) {
++ symbolNames.add(cc.symbolName);
++ }
++ }
+ }
+
+ /**
+@@ -327,9 +364,14 @@
+ public static Call specialCallNoLookup(final String className, final String name, final String desc) {
+ return new Call(null, className, name, desc) {
+ @Override
+- public MethodEmitter invoke(final MethodEmitter method) {
++ MethodEmitter invoke(final MethodEmitter method) {
+ return method.invokespecial(className, name, descriptor);
+ }
++
++ @Override
++ public void invoke(final MethodVisitor mv) {
++ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, name, desc, false);
++ }
+ };
+ }
+
+@@ -361,9 +403,14 @@
+ public static Call staticCallNoLookup(final String className, final String name, final String desc) {
+ return new Call(null, className, name, desc) {
+ @Override
+- public MethodEmitter invoke(final MethodEmitter method) {
++ MethodEmitter invoke(final MethodEmitter method) {
+ return method.invokestatic(className, name, descriptor);
+ }
++
++ @Override
++ public void invoke(final MethodVisitor mv) {
++ mv.visitMethodInsn(Opcodes.INVOKESTATIC, className, name, desc, false);
++ }
+ };
+ }
+
+@@ -396,9 +443,14 @@
+ public static Call virtualCallNoLookup(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
+ return new Call(null, className(clazz), name, methodDescriptor(rtype, ptypes)) {
+ @Override
+- public MethodEmitter invoke(final MethodEmitter method) {
++ MethodEmitter invoke(final MethodEmitter method) {
+ return method.invokevirtual(className, name, descriptor);
+ }
++
++ @Override
++ public void invoke(final MethodVisitor mv) {
++ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, name, descriptor, false);
++ }
+ };
+ }
+
+@@ -416,9 +468,14 @@
+ public static Call interfaceCallNoLookup(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
+ return new Call(null, className(clazz), name, methodDescriptor(rtype, ptypes)) {
+ @Override
+- public MethodEmitter invoke(final MethodEmitter method) {
++ MethodEmitter invoke(final MethodEmitter method) {
+ return method.invokeinterface(className, name, descriptor);
+ }
++
++ @Override
++ public void invoke(final MethodVisitor mv) {
++ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, className, name, descriptor, true);
++ }
+ };
+ }
+
+@@ -512,9 +569,14 @@
+ public static Call staticCall(final MethodHandles.Lookup lookup, final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
+ return new Call(MH.findStatic(lookup, clazz, name, MH.type(rtype, ptypes)), className(clazz), name, methodDescriptor(rtype, ptypes)) {
+ @Override
+- public MethodEmitter invoke(final MethodEmitter method) {
++ MethodEmitter invoke(final MethodEmitter method) {
+ return method.invokestatic(className, name, descriptor);
+ }
++
++ @Override
++ public void invoke(final MethodVisitor mv) {
++ mv.visitMethodInsn(Opcodes.INVOKESTATIC, className, name, descriptor, false);
++ }
+ };
+ }
+
+@@ -532,13 +594,56 @@
+ public static Call virtualCall(final MethodHandles.Lookup lookup, final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
+ return new Call(MH.findVirtual(lookup, clazz, name, MH.type(rtype, ptypes)), className(clazz), name, methodDescriptor(rtype, ptypes)) {
+ @Override
+- public MethodEmitter invoke(final MethodEmitter method) {
++ MethodEmitter invoke(final MethodEmitter method) {
+ return method.invokevirtual(className, name, descriptor);
+ }
++
++ @Override
++ public void invoke(final MethodVisitor mv) {
++ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, name, descriptor, false);
++ }
+ };
+ }
+
+ /**
++ * Create a special call, given an explicit lookup, looking up the method handle for it at the same time.
++ * clazz is used as this class
++ *
++ * @param lookup the lookup
++ * @param clazz the class
++ * @param name the name of the method
++ * @param rtype the return type
++ * @param ptypes the parameter types
++ *
++ * @return the call object representing the virtual call
++ */
++ public static Call specialCall(final MethodHandles.Lookup lookup, final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
++ return new Call(MH.findSpecial(lookup, clazz, name, MH.type(rtype, ptypes), clazz), className(clazz), name, methodDescriptor(rtype, ptypes)) {
++ @Override
++ MethodEmitter invoke(final MethodEmitter method) {
++ return method.invokespecial(className, name, descriptor);
++ }
++
++ @Override
++ public void invoke(final MethodVisitor mv) {
++ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, name, descriptor, false);
++ }
++ };
++ }
++
++ /**
++ * Returns true if the passed string looks like a method name of an internally generated Nashorn method. Basically,
++ * if it starts with a colon character {@code :} but is not the name of the program method {@code :program}.
++ * Program function is not considered internal as we want it to show up in exception stack traces.
++ * @param methodName the name of a method
++ * @return true if it looks like an internal Nashorn method name.
++ * @throws NullPointerException if passed null
++ */
++ public static boolean isInternalMethodName(final String methodName) {
++ return methodName.startsWith(INTERNAL_METHOD_PREFIX) && !methodName.equals(PROGRAM.symbolName);
++ }
++
++ /**
+ * Private class representing an access. This can generate code into a method code or
+ * a field access.
+ */
+@@ -668,7 +773,14 @@
+ *
+ * @return the method emitter
+ */
+- protected abstract MethodEmitter invoke(final MethodEmitter emitter);
++ abstract MethodEmitter invoke(final MethodEmitter emitter);
++
++ /**
++ * Generate invocation code for the method
++ *
++ * @param mv a method visitor
++ */
++ public abstract void invoke(final MethodVisitor mv);
+ }
+
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/Condition.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/Condition.java Wed Feb 04 12:14:47 2015 -0800
+@@ -66,8 +66,7 @@
+ case GT:
+ return IFGT;
+ default:
+- assert false;
+- return -1;
++ throw new UnsupportedOperationException("toUnary:" + c.toString());
+ }
+ }
+
+@@ -86,8 +85,7 @@
+ case GT:
+ return IF_ICMPGT;
+ default:
+- assert false;
+- return -1;
++ throw new UnsupportedOperationException("toBinary:" + c.toString());
+ }
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/ConstantData.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/ConstantData.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,20 +25,18 @@
+
+ package jdk.nashorn.internal.codegen;
+
+-import jdk.nashorn.internal.runtime.Property;
+-import jdk.nashorn.internal.runtime.PropertyMap;
+-
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.HashMap;
+ import java.util.List;
+ import java.util.Map;
++import jdk.nashorn.internal.runtime.PropertyMap;
+
+ /**
+ * Manages constants needed by code generation. Objects are maintained in an
+ * interning maps to remove duplicates.
+ */
+-class ConstantData {
++final class ConstantData {
+ /** Constant table. */
+ final List<Object> constants;
+
+@@ -64,7 +62,7 @@
+ private int calcHashCode() {
+ final Class<?> cls = array.getClass();
+
+- if (cls == Object[].class) {
++ if (!cls.getComponentType().isPrimitive()) {
+ return Arrays.hashCode((Object[])array);
+ } else if (cls == double[].class) {
+ return Arrays.hashCode((double[])array);
+@@ -92,7 +90,7 @@
+ final Class<?> cls = array.getClass();
+
+ if (cls == otherArray.getClass()) {
+- if (cls == Object[].class) {
++ if (!cls.getComponentType().isPrimitive()) {
+ return Arrays.equals((Object[])array, (Object[])otherArray);
+ } else if (cls == double[].class) {
+ return Arrays.equals((double[])array, (double[])otherArray);
+@@ -122,12 +120,7 @@
+ private final int hashCode;
+
+ public PropertyMapWrapper(final PropertyMap map) {
+- int hash = 0;
+- for (final Property property : map.getProperties()) {
+- hash = hash << 7 ^ hash >> 7;
+- hash ^= property.hashCode();
+- }
+- this.hashCode = hash;
++ this.hashCode = Arrays.hashCode(map.getProperties());
+ this.propertyMap = map;
+ }
+
+@@ -138,14 +131,8 @@
+
+ @Override
+ public boolean equals(final Object other) {
+- if (!(other instanceof PropertyMapWrapper)) {
+- return false;
+- }
+-
+- final Property[] ownProperties = propertyMap.getProperties();
+- final Property[] otherProperties = ((PropertyMapWrapper) other).propertyMap.getProperties();
+-
+- return Arrays.equals(ownProperties, otherProperties);
++ return other instanceof PropertyMapWrapper &&
++ Arrays.equals(propertyMap.getProperties(), ((PropertyMapWrapper) other).propertyMap.getProperties());
+ }
+ }
+
+@@ -185,6 +172,7 @@
+ * @return the index in the constant pool that the object was given
+ */
+ public int add(final Object object) {
++ assert object != null;
+ final Object entry;
+ if (object.getClass().isArray()) {
+ entry = new ArrayWrapper(object);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/DumpBytecode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,120 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
++
++import java.io.File;
++import java.io.FileOutputStream;
++import java.io.IOException;
++import java.io.PrintWriter;
++import jdk.nashorn.internal.runtime.ECMAErrors;
++import jdk.nashorn.internal.runtime.ScriptEnvironment;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++
++/**
++ * Class that facilitates printing bytecode and dumping it to disk.
++ */
++public final class DumpBytecode {
++ /**
++ * Dump bytecode to console and potentially disk.
++ * @param env the script environment defining options for printing bytecode
++ * @param logger a logger used to write diagnostics about bytecode dumping
++ * @param bytecode the actual code to dump
++ * @param className the name of the class being dumped
++ */
++ public static void dumpBytecode(final ScriptEnvironment env, final DebugLogger logger, final byte[] bytecode, final String className) {
++ File dir = null;
++ try {
++ // should could be printed to stderr for generate class?
++ if (env._print_code) {
++
++ final StringBuilder sb = new StringBuilder();
++ sb.append("class: " + className).
++ append('\n').
++ append(ClassEmitter.disassemble(bytecode)).
++ append("=====");
++
++ if (env._print_code_dir != null) {
++
++ String name = className;
++ final int dollar = name.lastIndexOf('$');
++ if (dollar != -1) {
++ name = name.substring(dollar + 1);
++ }
++
++ dir = new File(env._print_code_dir);
++ if (!dir.exists() && !dir.mkdirs()) {
++ throw new IOException(dir.toString());
++ }
++
++ File file;
++ String fileName;
++ int uniqueId = 0;
++ do {
++ fileName = name + (uniqueId == 0 ? "" : "_" + uniqueId) + ".bytecode";
++ file = new File(env._print_code_dir, fileName);
++ uniqueId++;
++ } while (file.exists());
++
++ try (final PrintWriter pw = new PrintWriter(new FileOutputStream(file))) {
++ pw.print(sb.toString());
++ pw.flush();
++ }
++ } else {
++ env.getErr().println(sb);
++ }
++ }
++
++
++ // should code be dumped to disk - only valid in compile_only mode?
++ if (env._dest_dir != null) {
++ final String fileName = className.replace('.', File.separatorChar) + ".class";
++ final int index = fileName.lastIndexOf(File.separatorChar);
++
++ if (index != -1) {
++ dir = new File(env._dest_dir, fileName.substring(0, index));
++ } else {
++ dir = new File(env._dest_dir);
++ }
++
++ if (!dir.exists() && !dir.mkdirs()) {
++ throw new IOException(dir.toString());
++ }
++ final File file = new File(env._dest_dir, fileName);
++ try (final FileOutputStream fos = new FileOutputStream(file)) {
++ fos.write(bytecode);
++ }
++ logger.info("Wrote class to '" + file.getAbsolutePath() + '\'');
++ }
++ } catch (final IOException e) {
++ logger.warning("Skipping class dump for ",
++ className,
++ ": ",
++ ECMAErrors.getMessage(
++ "io.error.cant.write",
++ dir.toString()));
++ }
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,8 +28,9 @@
+ import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
++import static jdk.nashorn.internal.codegen.ObjectClassGenerator.PRIMITIVE_FIELD_TYPE;
++import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getFieldName;
+ import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getPaddedFieldCount;
+-import static jdk.nashorn.internal.codegen.types.Type.OBJECT;
+ import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex;
+ import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
+
+@@ -51,47 +52,41 @@
+ * @param <T> the value type for the fields being written on object creation, e.g. Node
+ * @see jdk.nashorn.internal.ir.Node
+ */
+-public abstract class FieldObjectCreator<T> extends ObjectCreator {
++public abstract class FieldObjectCreator<T> extends ObjectCreator<T> {
+
+- private String fieldObjectClassName;
+- private Class<?> fieldObjectClass;
+- private int fieldCount;
+- private int paddedFieldCount;
+- private int paramCount;
+-
+- /** array of corresponding values to symbols (null for no values) */
+- private final List<T> values;
++ private String fieldObjectClassName;
++ private Class<? extends ScriptObject> fieldObjectClass;
++ private int fieldCount;
++ private int paddedFieldCount;
++ private int paramCount;
+
+ /** call site flags to be used for invocations */
+- private final int callSiteFlags;
++ private final int callSiteFlags;
++ /** are we creating this field object from 'eval' code? */
++ private final boolean evalCode;
+
+ /**
+ * Constructor
+ *
+ * @param codegen code generator
+- * @param keys keys for fields in object
+- * @param symbols symbols for fields in object
+- * @param values list of values corresponding to keys
++ * @param tuples tuples for fields in object
+ */
+- FieldObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final List<T> values) {
+- this(codegen, keys, symbols, values, false, false);
++ FieldObjectCreator(final CodeGenerator codegen, final List<MapTuple<T>> tuples) {
++ this(codegen, tuples, false, false);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param codegen code generator
+- * @param keys keys for fields in object
+- * @param symbols symbols for fields in object
+- * @param values values (or null where no value) to be written to the fields
++ * @param tuples tuples for fields in object
+ * @param isScope is this a scope object
+ * @param hasArguments does the created object have an "arguments" property
+ */
+- FieldObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final List<T> values, final boolean isScope, final boolean hasArguments) {
+- super(codegen, keys, symbols, isScope, hasArguments);
+- this.values = values;
++ FieldObjectCreator(final CodeGenerator codegen, final List<MapTuple<T>> tuples, final boolean isScope, final boolean hasArguments) {
++ super(codegen, tuples, isScope, hasArguments);
+ this.callSiteFlags = codegen.getCallSiteFlags();
+-
++ this.evalCode = codegen.isEvalCode();
+ countFields();
+ findClass();
+ }
+@@ -104,8 +99,19 @@
+ @Override
+ protected void makeObject(final MethodEmitter method) {
+ makeMap();
+-
+- method._new(getClassName()).dup(); // create instance
++ final String className = getClassName();
++ try {
++ // NOTE: we must load the actual structure class here, because the API operates with Nashorn Type objects,
++ // and Type objects need a loaded class, for better or worse. We also have to be specific and use the type
++ // of the actual structure class, we can't generalize it to e.g. Type.typeFor(ScriptObject.class) as the
++ // exact type information is needed for generating continuations in rest-of methods. If we didn't do this,
++ // object initializers like { x: arr[i] } would fail during deoptimizing compilation on arr[i], as the
++ // values restored from the RewriteException would be cast to "ScriptObject" instead of to e.g. "JO4", and
++ // subsequently the "PUTFIELD J04.L0" instruction in the continuation code would fail bytecode verification.
++ method._new(Context.forStructureClass(className.replace('/', '.'))).dup();
++ } catch (final ClassNotFoundException e) {
++ throw new AssertionError(e);
++ }
+ loadMap(method); //load the map
+
+ if (isScope()) {
+@@ -113,32 +119,31 @@
+
+ if (hasArguments()) {
+ method.loadCompilerConstant(ARGUMENTS);
+- method.invoke(constructorNoLookup(getClassName(), PropertyMap.class, ScriptObject.class, ARGUMENTS.type()));
++ method.invoke(constructorNoLookup(className, PropertyMap.class, ScriptObject.class, ARGUMENTS.type()));
+ } else {
+- method.invoke(constructorNoLookup(getClassName(), PropertyMap.class, ScriptObject.class));
++ method.invoke(constructorNoLookup(className, PropertyMap.class, ScriptObject.class));
+ }
+ } else {
+- method.invoke(constructorNoLookup(getClassName(), PropertyMap.class));
++ method.invoke(constructorNoLookup(className, PropertyMap.class));
+ }
+
+ // Set values.
+- final Iterator<Symbol> symbolIter = symbols.iterator();
+- final Iterator<String> keyIter = keys.iterator();
+- final Iterator<T> valueIter = values.iterator();
++ final Iterator<MapTuple<T>> iter = tuples.iterator();
+
+- while (symbolIter.hasNext()) {
+- final Symbol symbol = symbolIter.next();
+- final String key = keyIter.next();
+- final T value = valueIter.next();
++ while (iter.hasNext()) {
++ final MapTuple<T> tuple = iter.next();
++ //we only load when we have both symbols and values (which can be == the symbol)
++ //if we didn't load, we need an array property
++ if (tuple.symbol != null && tuple.value != null) {
++ final int index = getArrayIndex(tuple.key);
++ if (!isValidArrayIndex(index)) {
++ putField(method, tuple.key, tuple.symbol.getFieldIndex(), tuple);
++ } else {
++ putSlot(method, ArrayIndex.toLongIndex(index), tuple);
++ }
+
+- if (symbol != null && value != null) {
+- final int index = getArrayIndex(key);
+-
+- if (!isValidArrayIndex(index)) {
+- putField(method, key, symbol.getFieldIndex(), value);
+- } else {
+- putSlot(method, ArrayIndex.toLongIndex(index), value);
+- }
++ //this is a nop of tuple.key isn't e.g. "apply" or another special name
++ method.invalidateSpecialName(tuple.key);
+ }
+ }
+ }
+@@ -146,31 +151,32 @@
+ @Override
+ protected PropertyMap makeMap() {
+ assert propertyMap == null : "property map already initialized";
+- propertyMap = newMapCreator(fieldObjectClass).makeFieldMap(hasArguments(), fieldCount, paddedFieldCount);
++ propertyMap = newMapCreator(fieldObjectClass).makeFieldMap(hasArguments(), fieldCount, paddedFieldCount, evalCode);
+ return propertyMap;
+ }
+
+ /**
+- * Technique for loading an initial value. Defined by anonymous subclasses in code gen.
+- *
+- * @param value Value to load.
+- */
+- protected abstract void loadValue(T value);
+-
+- /**
+ * Store a value in a field of the generated class object.
+ *
+ * @param method Script method.
+ * @param key Property key.
+ * @param fieldIndex Field number.
+- * @param value Value to store.
++ * @param tuple Tuple to store.
+ */
+- private void putField(final MethodEmitter method, final String key, final int fieldIndex, final T value) {
++ private void putField(final MethodEmitter method, final String key, final int fieldIndex, final MapTuple<T> tuple) {
+ method.dup();
+
+- loadValue(value);
+- method.convert(OBJECT);
+- method.putField(getClassName(), ObjectClassGenerator.getFieldName(fieldIndex, Type.OBJECT), typeDescriptor(Object.class));
++ final Type fieldType = tuple.isPrimitive() ? PRIMITIVE_FIELD_TYPE : Type.OBJECT;
++ final String fieldClass = getClassName();
++ final String fieldName = getFieldName(fieldIndex, fieldType);
++ final String fieldDesc = typeDescriptor(fieldType.getTypeClass());
++
++ assert fieldName.equals(getFieldName(fieldIndex, PRIMITIVE_FIELD_TYPE)) || fieldType.isObject() : key + " object keys must store to L*-fields";
++ assert fieldName.equals(getFieldName(fieldIndex, Type.OBJECT)) || fieldType.isPrimitive() : key + " primitive keys must store to J*-fields";
++
++ loadTuple(method, tuple);
++
++ method.putField(fieldClass, fieldName, fieldDesc);
+ }
+
+ /**
+@@ -178,16 +184,16 @@
+ *
+ * @param method Script method.
+ * @param index Slot index.
+- * @param value Value to store.
++ * @param tuple Tuple to store.
+ */
+- private void putSlot(final MethodEmitter method, final long index, final T value) {
++ private void putSlot(final MethodEmitter method, final long index, final MapTuple<T> tuple) {
+ method.dup();
+ if (JSType.isRepresentableAsInt(index)) {
+- method.load((int) index);
++ method.load((int)index);
+ } else {
+ method.load(index);
+ }
+- loadValue(value);
++ loadTuple(method, tuple, false); //we don't pack array like objects
+ method.dynamicSetIndex(callSiteFlags);
+ }
+
+@@ -220,11 +226,12 @@
+ * Tally the number of fields and parameters.
+ */
+ private void countFields() {
+- for (final Symbol symbol : this.symbols) {
++ for (final MapTuple<T> tuple : tuples) {
++ final Symbol symbol = tuple.symbol;
+ if (symbol != null) {
+ if (hasArguments() && symbol.isParam()) {
+ symbol.setFieldIndex(paramCount++);
+- } else {
++ } else if (!isValidArrayIndex(getArrayIndex(tuple.key))) {
+ symbol.setFieldIndex(fieldCount++);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,199 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
+-
+-import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
+-
+-import jdk.nashorn.internal.ir.BinaryNode;
+-import jdk.nashorn.internal.ir.Block;
+-import jdk.nashorn.internal.ir.Expression;
+-import jdk.nashorn.internal.ir.ExpressionStatement;
+-import jdk.nashorn.internal.ir.ForNode;
+-import jdk.nashorn.internal.ir.FunctionNode;
+-import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
+-import jdk.nashorn.internal.ir.LexicalContext;
+-import jdk.nashorn.internal.ir.Node;
+-import jdk.nashorn.internal.ir.Symbol;
+-import jdk.nashorn.internal.ir.TemporarySymbols;
+-import jdk.nashorn.internal.ir.UnaryNode;
+-import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
+-import jdk.nashorn.internal.parser.Token;
+-import jdk.nashorn.internal.parser.TokenType;
+-import jdk.nashorn.internal.runtime.DebugLogger;
+-
+-/**
+- * Lower to more primitive operations. After lowering, an AST has symbols and
+- * types. Lowering may also add specialized versions of methods to the script if
+- * the optimizer is turned on.
+- *
+- * Any expression that requires temporary storage as part of computation will
+- * also be detected here and give a temporary symbol
+- *
+- * For any op that we process in FinalizeTypes it is an absolute guarantee
+- * that scope and slot information is correct. This enables e.g. AccessSpecialization
+- * and frame optimizations
+- */
+-
+-final class FinalizeTypes extends NodeOperatorVisitor<LexicalContext> {
+-
+- private static final DebugLogger LOG = new DebugLogger("finalize");
+-
+- private final TemporarySymbols temporarySymbols;
+-
+- FinalizeTypes(final TemporarySymbols temporarySymbols) {
+- super(new LexicalContext());
+- this.temporarySymbols = temporarySymbols;
+- }
+-
+- @Override
+- public Node leaveForNode(final ForNode forNode) {
+- if (forNode.isForIn()) {
+- return forNode;
+- }
+-
+- final Expression init = forNode.getInit();
+- final Expression test = forNode.getTest();
+- final Expression modify = forNode.getModify();
+-
+- assert test != null || forNode.hasGoto() : "forNode " + forNode + " needs goto and is missing it in " + lc.getCurrentFunction();
+-
+- return forNode.
+- setInit(lc, init == null ? null : discard(init)).
+- setModify(lc, modify == null ? null : discard(modify));
+- }
+-
+- @Override
+- public Node leaveCOMMALEFT(final BinaryNode binaryNode) {
+- assert binaryNode.getSymbol() != null;
+- return binaryNode.setRHS(discard(binaryNode.rhs()));
+- }
+-
+- @Override
+- public Node leaveCOMMARIGHT(final BinaryNode binaryNode) {
+- assert binaryNode.getSymbol() != null;
+- return binaryNode.setLHS(discard(binaryNode.lhs()));
+- }
+-
+- @Override
+- public boolean enterBlock(final Block block) {
+- updateSymbols(block);
+- return true;
+- }
+-
+- @Override
+- public Node leaveExpressionStatement(final ExpressionStatement expressionStatement) {
+- temporarySymbols.reuse();
+- return expressionStatement.setExpression(discard(expressionStatement.getExpression()));
+- }
+-
+- @Override
+- public boolean enterFunctionNode(final FunctionNode functionNode) {
+- if (functionNode.isLazy()) {
+- return false;
+- }
+-
+- // If the function doesn't need a callee, we ensure its __callee__ symbol doesn't get a slot. We can't do
+- // this earlier, as access to scoped variables, self symbol, etc. in previous phases can all trigger the
+- // need for the callee.
+- if (!functionNode.needsCallee()) {
+- functionNode.compilerConstant(CALLEE).setNeedsSlot(false);
+- }
+- // Similar reasoning applies to __scope__ symbol: if the function doesn't need either parent scope and none of
+- // its blocks create a scope, we ensure it doesn't get a slot, but we can't determine whether it needs a scope
+- // earlier than this phase.
+- if (!(functionNode.hasScopeBlock() || functionNode.needsParentScope())) {
+- functionNode.compilerConstant(SCOPE).setNeedsSlot(false);
+- }
+-
+- return true;
+- }
+-
+- @Override
+- public Node leaveFunctionNode(final FunctionNode functionNode) {
+- return functionNode.setState(lc, CompilationState.FINALIZED);
+- }
+-
+- private static void updateSymbolsLog(final FunctionNode functionNode, final Symbol symbol, final boolean loseSlot) {
+- if (LOG.isEnabled()) {
+- if (!symbol.isScope()) {
+- LOG.finest("updateSymbols: ", symbol, " => scope, because all vars in ", functionNode.getName(), " are in scope");
+- }
+- if (loseSlot && symbol.hasSlot()) {
+- LOG.finest("updateSymbols: ", symbol, " => no slot, because all vars in ", functionNode.getName(), " are in scope");
+- }
+- }
+- }
+-
+- /**
+- * Called after a block or function node (subclass of block) is finished. Guarantees
+- * that scope and slot information is correct for every symbol
+- * @param block block for which to to finalize type info.
+- */
+- private void updateSymbols(final Block block) {
+- if (!block.needsScope()) {
+- return; // nothing to do
+- }
+-
+- final FunctionNode functionNode = lc.getFunction(block);
+- final boolean allVarsInScope = functionNode.allVarsInScope();
+- final boolean isVarArg = functionNode.isVarArg();
+-
+- for (final Symbol symbol : block.getSymbols()) {
+- if (symbol.isInternal() || symbol.isThis() || symbol.isTemp()) {
+- continue;
+- }
+-
+- if (symbol.isVar()) {
+- if (allVarsInScope || symbol.isScope()) {
+- updateSymbolsLog(functionNode, symbol, true);
+- Symbol.setSymbolIsScope(lc, symbol);
+- symbol.setNeedsSlot(false);
+- } else {
+- assert symbol.hasSlot() : symbol + " should have a slot only, no scope";
+- }
+- } else if (symbol.isParam() && (allVarsInScope || isVarArg || symbol.isScope())) {
+- updateSymbolsLog(functionNode, symbol, isVarArg);
+- Symbol.setSymbolIsScope(lc, symbol);
+- symbol.setNeedsSlot(!isVarArg);
+- }
+- }
+- }
+-
+- private static Expression discard(final Expression node) {
+- if (node.getSymbol() != null) {
+- final UnaryNode discard = new UnaryNode(Token.recast(node.getToken(), TokenType.DISCARD), node);
+- //discard never has a symbol in the discard node - then it would be a nop
+- assert !node.isTerminal();
+- return discard;
+- }
+-
+- // node has no result (symbol) so we can keep it the way it is
+- return node;
+- }
+-
+-
+-}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/FindScopeDepths.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,368 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
++
++import static jdk.nashorn.internal.runtime.logging.DebugLogger.quote;
++
++import java.util.HashMap;
++import java.util.HashSet;
++import java.util.Iterator;
++import java.util.Map;
++import java.util.Set;
++import jdk.nashorn.internal.codegen.ObjectClassGenerator.AllocatorDescriptor;
++import jdk.nashorn.internal.ir.Block;
++import jdk.nashorn.internal.ir.FunctionNode;
++import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
++import jdk.nashorn.internal.ir.IdentNode;
++import jdk.nashorn.internal.ir.LexicalContext;
++import jdk.nashorn.internal.ir.Node;
++import jdk.nashorn.internal.ir.Symbol;
++import jdk.nashorn.internal.ir.WithNode;
++import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
++
++/**
++ * Establishes depth of scope for non local symbols at the start of method.
++ * If this is a recompilation, the previous data from eager compilation is
++ * stored in the RecompilableScriptFunctionData and is transferred to the
++ * FunctionNode being compiled
++ */
++@Logger(name="scopedepths")
++final class FindScopeDepths extends NodeVisitor<LexicalContext> implements Loggable {
++
++ private final Compiler compiler;
++ private final Map<Integer, Map<Integer, RecompilableScriptFunctionData>> fnIdToNestedFunctions = new HashMap<>();
++ private final Map<Integer, Map<String, Integer>> externalSymbolDepths = new HashMap<>();
++ private final Map<Integer, Set<String>> internalSymbols = new HashMap<>();
++ private final Set<Block> withBodies = new HashSet<>();
++
++ private final DebugLogger log;
++
++ private int dynamicScopeCount;
++
++ FindScopeDepths(final Compiler compiler) {
++ super(new LexicalContext());
++ this.compiler = compiler;
++ this.log = initLogger(compiler.getContext());
++ }
++
++ @Override
++ public DebugLogger getLogger() {
++ return log;
++ }
++
++ @Override
++ public DebugLogger initLogger(final Context context) {
++ return context.getLogger(this.getClass());
++ }
++
++ static int findScopesToStart(final LexicalContext lc, final FunctionNode fn, final Block block) {
++ final Block bodyBlock = findBodyBlock(lc, fn, block);
++ final Iterator<Block> iter = lc.getBlocks(block);
++ Block b = iter.next();
++ int scopesToStart = 0;
++ while (true) {
++ if (b.needsScope()) {
++ scopesToStart++;
++ }
++ if (b == bodyBlock) {
++ break;
++ }
++ b = iter.next();
++ }
++ return scopesToStart;
++ }
++
++ static int findInternalDepth(final LexicalContext lc, final FunctionNode fn, final Block block, final Symbol symbol) {
++ final Block bodyBlock = findBodyBlock(lc, fn, block);
++ final Iterator<Block> iter = lc.getBlocks(block);
++ Block b = iter.next();
++ int scopesToStart = 0;
++ while (true) {
++ if (definedInBlock(b, symbol)) {
++ return scopesToStart;
++ }
++ if (b.needsScope()) {
++ scopesToStart++;
++ }
++ if (b == bodyBlock) {
++ break; //don't go past body block, but process it
++ }
++ b = iter.next();
++ }
++ return -1;
++ }
++
++ private static boolean definedInBlock(final Block block, final Symbol symbol) {
++ if (symbol.isGlobal()) {
++ if (block.isGlobalScope()) {
++ return true;
++ }
++ //globals cannot be defined anywhere else
++ return false;
++ }
++ return block.getExistingSymbol(symbol.getName()) == symbol;
++ }
++
++ static Block findBodyBlock(final LexicalContext lc, final FunctionNode fn, final Block block) {
++ final Iterator<Block> iter = lc.getBlocks(block);
++ while (iter.hasNext()) {
++ final Block next = iter.next();
++ if (fn.getBody() == next) {
++ return next;
++ }
++ }
++ return null;
++ }
++
++ private static Block findGlobalBlock(final LexicalContext lc, final Block block) {
++ final Iterator<Block> iter = lc.getBlocks(block);
++ Block globalBlock = null;
++ while (iter.hasNext()) {
++ globalBlock = iter.next();
++ }
++ return globalBlock;
++ }
++
++ private static boolean isDynamicScopeBoundary(final FunctionNode fn) {
++ return fn.needsDynamicScope();
++ }
++
++ private boolean isDynamicScopeBoundary(final Block block) {
++ return withBodies.contains(block);
++ }
++
++ @Override
++ public boolean enterFunctionNode(final FunctionNode functionNode) {
++ if (compiler.isOnDemandCompilation()) {
++ return true;
++ }
++
++ if (isDynamicScopeBoundary(functionNode)) {
++ increaseDynamicScopeCount(functionNode);
++ }
++
++ final int fnId = functionNode.getId();
++ Map<Integer, RecompilableScriptFunctionData> nestedFunctions = fnIdToNestedFunctions.get(fnId);
++ if (nestedFunctions == null) {
++ nestedFunctions = new HashMap<>();
++ fnIdToNestedFunctions.put(fnId, nestedFunctions);
++ }
++
++ return true;
++ }
++
++ //external symbols hold the scope depth of sc11 from global at the start of the method
++ @Override
++ public Node leaveFunctionNode(final FunctionNode functionNode) {
++ final String name = functionNode.getName();
++ FunctionNode newFunctionNode = functionNode.setState(lc, CompilationState.SCOPE_DEPTHS_COMPUTED);
++
++ if (compiler.isOnDemandCompilation()) {
++ final RecompilableScriptFunctionData data = compiler.getScriptFunctionData(newFunctionNode.getId());
++ if (data.inDynamicContext()) {
++ log.fine("Reviving scriptfunction ", quote(name), " as defined in previous (now lost) dynamic scope.");
++ newFunctionNode = newFunctionNode.setInDynamicContext(lc);
++ }
++ return newFunctionNode;
++ }
++
++ if (inDynamicScope()) {
++ log.fine("Tagging ", quote(name), " as defined in dynamic scope");
++ newFunctionNode = newFunctionNode.setInDynamicContext(lc);
++ }
++
++ //create recompilable scriptfunctiondata
++ final int fnId = newFunctionNode.getId();
++ final Map<Integer, RecompilableScriptFunctionData> nestedFunctions = fnIdToNestedFunctions.remove(fnId);
++
++ assert nestedFunctions != null;
++ // Generate the object class and property map in case this function is ever used as constructor
++ final RecompilableScriptFunctionData data = new RecompilableScriptFunctionData(
++ newFunctionNode,
++ compiler.getCodeInstaller(),
++ new AllocatorDescriptor(newFunctionNode.getThisProperties()),
++ nestedFunctions,
++ externalSymbolDepths.get(fnId),
++ internalSymbols.get(fnId),
++ compiler.removeSerializedAst(fnId));
++
++ if (lc.getOutermostFunction() != newFunctionNode) {
++ final FunctionNode parentFn = lc.getParentFunction(newFunctionNode);
++ if (parentFn != null) {
++ fnIdToNestedFunctions.get(parentFn.getId()).put(fnId, data);
++ }
++ } else {
++ compiler.setData(data);
++ }
++
++ if (isDynamicScopeBoundary(functionNode)) {
++ decreaseDynamicScopeCount(functionNode);
++ }
++
++ return newFunctionNode;
++ }
++
++ private boolean inDynamicScope() {
++ return dynamicScopeCount > 0;
++ }
++
++ private void increaseDynamicScopeCount(final Node node) {
++ assert dynamicScopeCount >= 0;
++ ++dynamicScopeCount;
++ if (log.isEnabled()) {
++ log.finest(quote(lc.getCurrentFunction().getName()), " ++dynamicScopeCount = ", dynamicScopeCount, " at: ", node, node.getClass());
++ }
++ }
++
++ private void decreaseDynamicScopeCount(final Node node) {
++ --dynamicScopeCount;
++ assert dynamicScopeCount >= 0;
++ if (log.isEnabled()) {
++ log.finest(quote(lc.getCurrentFunction().getName()), " --dynamicScopeCount = ", dynamicScopeCount, " at: ", node, node.getClass());
++ }
++ }
++
++ @Override
++ public boolean enterWithNode(final WithNode node) {
++ withBodies.add(node.getBody());
++ return true;
++ }
++
++ @Override
++ public boolean enterBlock(final Block block) {
++ if (compiler.isOnDemandCompilation()) {
++ return true;
++ }
++
++ if (isDynamicScopeBoundary(block)) {
++ increaseDynamicScopeCount(block);
++ }
++
++ if (!lc.isFunctionBody()) {
++ return true;
++ }
++
++ //the below part only happens on eager compilation when we have the entire hierarchy
++ //block is a function body
++ final FunctionNode fn = lc.getCurrentFunction();
++
++ //get all symbols that are referenced inside this function body
++ final Set<Symbol> symbols = new HashSet<>();
++ block.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
++ @Override
++ public final boolean enterDefault(final Node node) {
++ if (!compiler.isOnDemandCompilation()) {
++ if (node instanceof IdentNode) {
++ final Symbol symbol = ((IdentNode)node).getSymbol();
++ if (symbol != null && symbol.isScope()) {
++ //if this is an internal symbol, skip it.
++ symbols.add(symbol);
++ }
++ }
++ }
++ return true;
++ }
++ });
++
++ final Map<String, Integer> internals = new HashMap<>();
++
++ final Block globalBlock = findGlobalBlock(lc, block);
++ final Block bodyBlock = findBodyBlock(lc, fn, block);
++
++ assert globalBlock != null;
++ assert bodyBlock != null;
++
++ for (final Symbol symbol : symbols) {
++ Iterator<Block> iter;
++
++ final int internalDepth = findInternalDepth(lc, fn, block, symbol);
++ final boolean internal = internalDepth >= 0;
++ if (internal) {
++ internals.put(symbol.getName(), internalDepth);
++ }
++
++ // if not internal, we have to continue walking until we reach the top. We
++ // start outside the body and each new scope adds a depth count. When we
++ // find the symbol, we store its depth count
++ if (!internal) {
++ int depthAtStart = 0;
++ //not internal - keep looking.
++ iter = lc.getAncestorBlocks(bodyBlock);
++ while (iter.hasNext()) {
++ final Block b2 = iter.next();
++ if (definedInBlock(b2, symbol)) {
++ addExternalSymbol(fn, symbol, depthAtStart);
++ break;
++ }
++ if (b2.needsScope()) {
++ depthAtStart++;
++ }
++ }
++ }
++ }
++
++ addInternalSymbols(fn, internals.keySet());
++
++ if (log.isEnabled()) {
++ log.info(fn.getName() + " internals=" + internals + " externals=" + externalSymbolDepths.get(fn.getId()));
++ }
++
++ return true;
++ }
++
++ @Override
++ public Node leaveBlock(final Block block) {
++ if (compiler.isOnDemandCompilation()) {
++ return block;
++ }
++ if (isDynamicScopeBoundary(block)) {
++ decreaseDynamicScopeCount(block);
++ }
++ return block;
++ }
++
++ private void addInternalSymbols(final FunctionNode functionNode, final Set<String> symbols) {
++ final int fnId = functionNode.getId();
++ assert internalSymbols.get(fnId) == null || internalSymbols.get(fnId).equals(symbols); //e.g. cloned finally block
++ internalSymbols.put(fnId, symbols);
++ }
++
++ private void addExternalSymbol(final FunctionNode functionNode, final Symbol symbol, final int depthAtStart) {
++ final int fnId = functionNode.getId();
++ Map<String, Integer> depths = externalSymbolDepths.get(fnId);
++ if (depths == null) {
++ depths = new HashMap<>();
++ externalSymbolDepths.put(fnId, depths);
++ }
++ depths.put(symbol.getName(), depthAtStart);
++ }
++
++}
+--- ./nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,12 +26,16 @@
+ package jdk.nashorn.internal.codegen;
+
+ import java.util.ArrayList;
++import java.util.HashSet;
+ import java.util.List;
++import java.util.Set;
+ import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.BinaryNode;
+ import jdk.nashorn.internal.ir.Block;
+ import jdk.nashorn.internal.ir.BlockStatement;
++import jdk.nashorn.internal.ir.CaseNode;
+ import jdk.nashorn.internal.ir.EmptyNode;
++import jdk.nashorn.internal.ir.Expression;
+ import jdk.nashorn.internal.ir.FunctionNode;
+ import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
+ import jdk.nashorn.internal.ir.IfNode;
+@@ -40,30 +44,46 @@
+ import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
+ import jdk.nashorn.internal.ir.Node;
+ import jdk.nashorn.internal.ir.Statement;
++import jdk.nashorn.internal.ir.SwitchNode;
+ import jdk.nashorn.internal.ir.TernaryNode;
+ import jdk.nashorn.internal.ir.UnaryNode;
+ import jdk.nashorn.internal.ir.VarNode;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+-import jdk.nashorn.internal.runtime.DebugLogger;
++import jdk.nashorn.internal.runtime.Context;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
+
+ /**
+ * Simple constant folding pass, executed before IR is starting to be lowered.
+ */
+-final class FoldConstants extends NodeVisitor<LexicalContext> {
++@Logger(name="fold")
++final class FoldConstants extends NodeVisitor<LexicalContext> implements Loggable {
+
+- private static final DebugLogger LOG = new DebugLogger("fold");
++ private final DebugLogger log;
+
+- FoldConstants() {
++ FoldConstants(final Compiler compiler) {
+ super(new LexicalContext());
++ this.log = initLogger(compiler.getContext());
++ }
++
++ @Override
++ public DebugLogger getLogger() {
++ return log;
++ }
++
++ @Override
++ public DebugLogger initLogger(final Context context) {
++ return context.getLogger(this.getClass());
+ }
+
+ @Override
+ public Node leaveUnaryNode(final UnaryNode unaryNode) {
+ final LiteralNode<?> literalNode = new UnaryNodeConstantEvaluator(unaryNode).eval();
+ if (literalNode != null) {
+- LOG.info("Unary constant folded ", unaryNode, " to ", literalNode);
++ log.info("Unary constant folded ", unaryNode, " to ", literalNode);
+ return literalNode;
+ }
+ return unaryNode;
+@@ -73,18 +93,13 @@
+ public Node leaveBinaryNode(final BinaryNode binaryNode) {
+ final LiteralNode<?> literalNode = new BinaryNodeConstantEvaluator(binaryNode).eval();
+ if (literalNode != null) {
+- LOG.info("Binary constant folded ", binaryNode, " to ", literalNode);
++ log.info("Binary constant folded ", binaryNode, " to ", literalNode);
+ return literalNode;
+ }
+ return binaryNode;
+ }
+
+ @Override
+- public boolean enterFunctionNode(final FunctionNode functionNode) {
+- return !functionNode.isLazy();
+- }
+-
+- @Override
+ public Node leaveFunctionNode(final FunctionNode functionNode) {
+ return functionNode.setState(lc, CompilationState.CONSTANT_FOLDED);
+ }
+@@ -116,11 +131,37 @@
+ public Node leaveTernaryNode(final TernaryNode ternaryNode) {
+ final Node test = ternaryNode.getTest();
+ if (test instanceof LiteralNode.PrimitiveLiteralNode) {
+- return ((LiteralNode.PrimitiveLiteralNode<?>)test).isTrue() ? ternaryNode.getTrueExpression() : ternaryNode.getFalseExpression();
++ return (((LiteralNode.PrimitiveLiteralNode<?>)test).isTrue() ? ternaryNode.getTrueExpression() : ternaryNode.getFalseExpression()).getExpression();
+ }
+ return ternaryNode;
+ }
+
++ @Override
++ public Node leaveSwitchNode(final SwitchNode switchNode) {
++ return switchNode.setUniqueInteger(lc, isUniqueIntegerSwitchNode(switchNode));
++ }
++
++ private static boolean isUniqueIntegerSwitchNode(final SwitchNode switchNode) {
++ final Set<Integer> alreadySeen = new HashSet<>();
++ for (final CaseNode caseNode : switchNode.getCases()) {
++ final Expression test = caseNode.getTest();
++ if (test != null && !isUniqueIntegerLiteral(test, alreadySeen)) {
++ return false;
++ }
++ }
++ return true;
++ }
++
++ private static boolean isUniqueIntegerLiteral(final Expression expr, final Set<Integer> alreadySeen) {
++ if (expr instanceof LiteralNode) {
++ final Object value = ((LiteralNode<?>)expr).getValue();
++ if (value instanceof Integer) {
++ return alreadySeen.add((Integer)value);
++ }
++ }
++ return false;
++ }
++
+ /**
+ * Helper class to evaluate constant expressions at compile time This is
+ * also a simplifier used by BinaryNode visits, UnaryNode visits and
+@@ -149,7 +190,7 @@
+ final LexicalContext lc = new LexicalContext();
+ block.accept(lc, new NodeVisitor<LexicalContext>(lc) {
+ @Override
+- public boolean enterVarNode(VarNode varNode) {
++ public boolean enterVarNode(final VarNode varNode) {
+ statements.add(varNode.setInit(null));
+ return false;
+ }
+@@ -163,7 +204,7 @@
+
+ @Override
+ protected LiteralNode<?> eval() {
+- final Node rhsNode = parent.rhs();
++ final Node rhsNode = parent.getExpression();
+
+ if (!(rhsNode instanceof LiteralNode)) {
+ return null;
+@@ -174,7 +215,8 @@
+ }
+
+ final LiteralNode<?> rhs = (LiteralNode<?>)rhsNode;
+- final boolean rhsInteger = rhs.getType().isInteger();
++ final Type rhsType = rhs.getType();
++ final boolean rhsInteger = rhsType.isInteger() || rhsType.isBoolean();
+
+ LiteralNode<?> literalNode;
+
+@@ -261,7 +303,7 @@
+ break;
+ case ADD:
+ if ((lhs.isString() || rhs.isNumeric()) && (rhs.isString() || rhs.isNumeric())) {
+- Object res = ScriptRuntime.ADD(lhs.getObject(), rhs.getObject());
++ final Object res = ScriptRuntime.ADD(lhs.getObject(), rhs.getObject());
+ if (res instanceof Number) {
+ value = ((Number)res).doubleValue();
+ break;
+@@ -280,7 +322,7 @@
+ value = lhs.getNumber() - rhs.getNumber();
+ break;
+ case SHR:
+- return LiteralNode.newInstance(token, finish, (lhs.getInt32() >>> rhs.getInt32()) & JSType.MAX_UINT);
++ return LiteralNode.newInstance(token, finish, JSType.toUint32(lhs.getInt32() >>> rhs.getInt32()));
+ case SAR:
+ return LiteralNode.newInstance(token, finish, lhs.getInt32() >> rhs.getInt32());
+ case SHL:
+@@ -311,8 +353,8 @@
+ return null;
+ }
+
+- isInteger &= value != 0.0 && JSType.isRepresentableAsInt(value);
+- isLong &= value != 0.0 && JSType.isRepresentableAsLong(value);
++ isInteger &= JSType.isRepresentableAsInt(value) && !JSType.isNegativeZero(value);
++ isLong &= JSType.isRepresentableAsLong(value) && !JSType.isNegativeZero(value);
+
+ if (isInteger) {
+ return LiteralNode.newInstance(token, finish, (int)value);
+--- ./nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java Wed Feb 04 12:14:47 2015 -0800
+@@ -141,7 +141,7 @@
+ paramTypeList.add(paramType.getTypeClass());
+ }
+
+- this.methodType = MH.type(returnType.getTypeClass(), paramTypeList.toArray(new Class[paramTypes.length]));
++ this.methodType = MH.type(returnType.getTypeClass(), paramTypeList.toArray(new Class<?>[paramTypes.length]));
+ }
+
+ /**
+@@ -195,6 +195,14 @@
+ }
+
+ /**
++ * Get the param types for this function signature
++ * @return cloned vector of param types
++ */
++ public Type[] getParamTypes() {
++ return paramTypes.clone();
++ }
++
++ /**
+ * Return the {@link MethodType} for this function signature
+ * @return the method type
+ */
+--- ./nashorn/src/jdk/nashorn/internal/codegen/Label.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/Label.java Wed Feb 04 12:14:47 2015 -0800
+@@ -24,8 +24,14 @@
+ */
+ package jdk.nashorn.internal.codegen;
+
++import java.io.Serializable;
++import java.util.ArrayList;
++import java.util.Arrays;
++import java.util.BitSet;
++import java.util.Iterator;
++import java.util.List;
++import java.util.ListIterator;
+ import jdk.nashorn.internal.codegen.types.Type;
+-import jdk.nashorn.internal.runtime.Debug;
+
+ /**
+ * Abstraction for labels, separating a label from the underlying
+@@ -34,24 +40,29 @@
+ *
+ * see -Dnashorn.codegen.debug, --log=codegen
+ */
+-public final class Label {
++public final class Label implements Serializable {
++ private static final long serialVersionUID = 1L;
++
+ //byte code generation evaluation type stack for consistency check
+ //and correct opcode selection. one per label as a label may be a
+ //join point
+- static final class Stack {
+- Type[] data = new Type[8];
+- int sp = 0;
++ static final class Stack implements Cloneable {
++ static final int NON_LOAD = -1;
++
++ Type[] data;
++ int[] localLoads;
++ int sp;
++
++ List<Type> localVariableTypes;
++ int firstTemp; // index of the first temporary local variable
++ // Bitmap marking last slot belonging to a single symbol.
++ BitSet symbolBoundary;
+
+ Stack() {
+- }
+-
+- private Stack(final Type[] type, final int sp) {
+- this();
+- this.data = new Type[type.length];
+- this.sp = sp;
+- for (int i = 0; i < sp; i++) {
+- data[i] = type[i];
+- }
++ data = new Type[8];
++ localLoads = new int[8];
++ localVariableTypes = new ArrayList<>(8);
++ symbolBoundary = new BitSet();
+ }
+
+ boolean isEmpty() {
+@@ -62,7 +73,147 @@
+ return sp;
+ }
+
+- boolean isEquivalentTo(final Stack other) {
++ void clear() {
++ sp = 0;
++ }
++
++ void push(final Type type) {
++ if (data.length == sp) {
++ final Type[] newData = new Type[sp * 2];
++ final int[] newLocalLoad = new int[sp * 2];
++ System.arraycopy(data, 0, newData, 0, sp);
++ System.arraycopy(localLoads, 0, newLocalLoad, 0, sp);
++ data = newData;
++ localLoads = newLocalLoad;
++ }
++ data[sp] = type;
++ localLoads[sp] = NON_LOAD;
++ sp++;
++ }
++
++ Type peek() {
++ return peek(0);
++ }
++
++ Type peek(final int n) {
++ final int pos = sp - 1 - n;
++ return pos < 0 ? null : data[pos];
++ }
++
++ /**
++ * Retrieve the top <tt>count</tt> types on the stack without modifying it.
++ *
++ * @param count number of types to return
++ * @return array of Types
++ */
++ Type[] getTopTypes(final int count) {
++ final Type[] topTypes = new Type[count];
++ System.arraycopy(data, sp - count, topTypes, 0, count);
++ return topTypes;
++ }
++
++ int[] getLocalLoads(final int from, final int to) {
++ final int count = to - from;
++ final int[] topLocalLoads = new int[count];
++ System.arraycopy(localLoads, from, topLocalLoads, 0, count);
++ return topLocalLoads;
++ }
++
++ /**
++ * Returns the number of used local variable slots, including all live stack-store temporaries.
++ * @return the number of used local variable slots, including all live stack-store temporaries.
++ */
++ int getUsedSlotsWithLiveTemporaries() {
++ // There are at least as many as are declared by the current blocks.
++ int usedSlots = firstTemp;
++ // Look at every load on the stack, and bump the number of used slots up by the temporaries seen there.
++ for(int i = sp; i-->0;) {
++ final int slot = localLoads[i];
++ if(slot != Label.Stack.NON_LOAD) {
++ final int afterSlot = slot + localVariableTypes.get(slot).getSlots();
++ if(afterSlot > usedSlots) {
++ usedSlots = afterSlot;
++ }
++ }
++ }
++ return usedSlots;
++ }
++
++ /**
++ *
++ * @param joinOrigin the stack from the other branch.
++ */
++ void joinFrom(final Stack joinOrigin, final boolean breakTarget) {
++ assert isStackCompatible(joinOrigin);
++ if(breakTarget) {
++ // As we're joining labels that can jump across block boundaries, the number of local variables can
++ // differ, and we should always respect the one having less variables.
++ firstTemp = Math.min(firstTemp, joinOrigin.firstTemp);
++ } else {
++ assert firstTemp == joinOrigin.firstTemp;
++ }
++ final int[] otherLoads = joinOrigin.localLoads;
++ int firstDeadTemp = firstTemp;
++ for(int i = 0; i < sp; ++i) {
++ final int localLoad = localLoads[i];
++ if(localLoad != otherLoads[i]) {
++ localLoads[i] = NON_LOAD;
++ } else if(localLoad >= firstDeadTemp) {
++ firstDeadTemp = localLoad + localVariableTypes.get(localLoad).getSlots();
++ }
++ }
++ // Eliminate dead temporaries
++ undefineLocalVariables(firstDeadTemp, false);
++ assert isVariablePartitioningEqual(joinOrigin, firstDeadTemp);
++ mergeVariableTypes(joinOrigin, firstDeadTemp);
++ }
++
++ private void mergeVariableTypes(final Stack joinOrigin, final int toSlot) {
++ final ListIterator<Type> it1 = localVariableTypes.listIterator();
++ final Iterator<Type> it2 = joinOrigin.localVariableTypes.iterator();
++
++ for(int i = 0; i < toSlot; ++i) {
++ final Type thisType = it1.next();
++ final Type otherType = it2.next();
++ if(otherType == Type.UNKNOWN) {
++ // Variables that are <unknown> on the other branch will become <unknown> here too.
++ it1.set(Type.UNKNOWN);
++ } else if (thisType != otherType) {
++ if(thisType.isObject() && otherType.isObject()) {
++ // different object types are merged into Object.
++ // TODO: maybe find most common superclass?
++ it1.set(Type.OBJECT);
++ } else {
++ assert thisType == Type.UNKNOWN;
++ }
++ }
++ }
++ }
++
++ void joinFromTry(final Stack joinOrigin) {
++ // As we're joining labels that can jump across block boundaries, the number of local variables can
++ // differ, and we should always respect the one having less variables.
++ firstTemp = Math.min(firstTemp, joinOrigin.firstTemp);
++ assert isVariablePartitioningEqual(joinOrigin, firstTemp);
++ mergeVariableTypes(joinOrigin, firstTemp);
++ }
++
++ private int getFirstDeadLocal(final List<Type> types) {
++ int i = types.size();
++ for(final ListIterator<Type> it = types.listIterator(i);
++ it.hasPrevious() && it.previous() == Type.UNKNOWN;
++ --i) {
++ // no body
++ }
++
++ // Respect symbol boundaries; we never chop off half a symbol's storage
++ while(!symbolBoundary.get(i - 1)) {
++ ++i;
++ }
++ return i;
++ }
++
++ private boolean isStackCompatible(final Stack other) {
+ if (sp != other.sp) {
+ return false;
+ }
+@@ -74,60 +225,288 @@
+ return true;
+ }
+
+- void clear() {
+- sp = 0;
++ private boolean isVariablePartitioningEqual(final Stack other, final int toSlot) {
++ // No difference in the symbol boundaries before the toSlot
++ final BitSet diff = other.getSymbolBoundaryCopy();
++ diff.xor(symbolBoundary);
++ return diff.previousSetBit(toSlot - 1) == -1;
+ }
+
+- void push(final Type type) {
+- if (data.length == sp) {
+- final Type[] newData = new Type[sp * 2];
+- for (int i = 0; i < sp; i++) {
+- newData[i] = data[i];
+- }
+- data = newData;
++ void markDeadLocalVariables(final int fromSlot, final int slotCount) {
++ final int localCount = localVariableTypes.size();
++ if(fromSlot >= localCount) {
++ return;
+ }
+- data[sp++] = type;
++ final int toSlot = Math.min(fromSlot + slotCount, localCount);
++ invalidateLocalLoadsOnStack(fromSlot, toSlot);
++ for(int i = fromSlot; i < toSlot; ++i) {
++ localVariableTypes.set(i, Type.UNKNOWN);
++ }
+ }
+
+- Type peek() {
+- return peek(0);
++ @SuppressWarnings("unchecked")
++ List<Type> getLocalVariableTypesCopy() {
++ return (List<Type>)((ArrayList<Type>)localVariableTypes).clone();
+ }
+
+- Type peek(final int n) {
+- int pos = sp - 1 - n;
+- return pos < 0 ? null : data[pos];
++ BitSet getSymbolBoundaryCopy() {
++ return (BitSet)symbolBoundary.clone();
++ }
++
++ /**
++ * Returns a list of local variable slot types, but for those symbols that have multiple values, only the slot
++ * holding the widest type is marked as live.
++ * @return a list of widest local variable slot types.
++ */
++ List<Type> getWidestLiveLocals(final List<Type> lvarTypes) {
++ final List<Type> widestLiveLocals = new ArrayList<>(lvarTypes);
++ boolean keepNextValue = true;
++ final int size = widestLiveLocals.size();
++ for(int i = size - 1; i-- > 0;) {
++ if(symbolBoundary.get(i)) {
++ keepNextValue = true;
++ }
++ final Type t = widestLiveLocals.get(i);
++ if(t != Type.UNKNOWN) {
++ if(keepNextValue) {
++ if(t != Type.SLOT_2) {
++ keepNextValue = false;
++ }
++ } else {
++ widestLiveLocals.set(i, Type.UNKNOWN);
++ }
++ }
++ }
++ widestLiveLocals.subList(Math.max(getFirstDeadLocal(widestLiveLocals), firstTemp), widestLiveLocals.size()).clear();
++ return widestLiveLocals;
++ }
++
++ String markSymbolBoundariesInLvarTypesDescriptor(final String lvarDescriptor) {
++ final char[] chars = lvarDescriptor.toCharArray();
++ int j = 0;
++ for(int i = 0; i < chars.length; ++i) {
++ final char c = chars[i];
++ final int nextj = j + CodeGeneratorLexicalContext.getTypeForSlotDescriptor(c).getSlots();
++ if(!symbolBoundary.get(nextj - 1)) {
++ chars[i] = Character.toLowerCase(c);
++ }
++ j = nextj;
++ }
++ return new String(chars);
+ }
+
+ Type pop() {
++ assert sp > 0;
+ return data[--sp];
+ }
+
+- Stack copy() {
+- return new Stack(data, sp);
++ @Override
++ public Stack clone() {
++ try {
++ final Stack clone = (Stack)super.clone();
++ clone.data = data.clone();
++ clone.localLoads = localLoads.clone();
++ clone.symbolBoundary = getSymbolBoundaryCopy();
++ clone.localVariableTypes = getLocalVariableTypesCopy();
++ return clone;
++ } catch(final CloneNotSupportedException e) {
++ throw new AssertionError("", e);
++ }
++ }
++
++ private Stack cloneWithEmptyStack() {
++ final Stack stack = clone();
++ stack.sp = 0;
++ return stack;
++ }
++
++ int getTopLocalLoad() {
++ return localLoads[sp - 1];
++ }
++
++ void markLocalLoad(final int slot) {
++ localLoads[sp - 1] = slot;
++ }
++
++ /**
++ * Performs various bookeeping when a value is stored in a local variable slot.
++ * @param slot the slot written to
++ * @param onlySymbolLiveValue if true, this is the symbol's only live value, and other values of the symbol
++ * should be marked dead
++ * @param Type the type written to the slot
++ */
++ void onLocalStore(final Type type, final int slot, final boolean onlySymbolLiveValue) {
++ if(onlySymbolLiveValue) {
++ final int fromSlot = slot == 0 ? 0 : (symbolBoundary.previousSetBit(slot - 1) + 1);
++ final int toSlot = symbolBoundary.nextSetBit(slot) + 1;
++ for(int i = fromSlot; i < toSlot; ++i) {
++ localVariableTypes.set(i, Type.UNKNOWN);
++ }
++ invalidateLocalLoadsOnStack(fromSlot, toSlot);
++ } else {
++ invalidateLocalLoadsOnStack(slot, slot + type.getSlots());
++ }
++
++ localVariableTypes.set(slot, type);
++ if(type.isCategory2()) {
++ localVariableTypes.set(slot + 1, Type.SLOT_2);
++ }
++ }
++
++ /**
++ * Given a slot range, invalidate knowledge about local loads on stack from these slots (because they're being
++ * killed).
++ * @param fromSlot first slot, inclusive.
++ * @param toSlot last slot, exclusive.
++ */
++ private void invalidateLocalLoadsOnStack(final int fromSlot, final int toSlot) {
++ for(int i = 0; i < sp; ++i) {
++ final int localLoad = localLoads[i];
++ if(localLoad >= fromSlot && localLoad < toSlot) {
++ localLoads[i] = NON_LOAD;
++ }
++ }
++ }
++
++ /**
++ * Marks a range of slots as belonging to a defined local variable. The slots will start out with no live value
++ * in them.
++ * @param fromSlot first slot, inclusive.
++ * @param toSlot last slot, exclusive.
++ */
++ void defineBlockLocalVariable(final int fromSlot, final int toSlot) {
++ defineLocalVariable(fromSlot, toSlot);
++ assert firstTemp < toSlot;
++ firstTemp = toSlot;
++ }
++
++ /**
++ * Defines a new temporary local variable and returns its allocated index.
++ * @param width the required width (in slots) for the new variable.
++ * @return the bytecode slot index where the newly allocated local begins.
++ */
++ int defineTemporaryLocalVariable(final int width) {
++ final int fromSlot = getUsedSlotsWithLiveTemporaries();
++ defineLocalVariable(fromSlot, fromSlot + width);
++ return fromSlot;
++ }
++
++ /**
++ * Marks a range of slots as belonging to a defined temporary local variable. The slots will start out with no
++ * live value in them.
++ * @param fromSlot first slot, inclusive.
++ * @param toSlot last slot, exclusive.
++ */
++ void defineTemporaryLocalVariable(final int fromSlot, final int toSlot) {
++ defineLocalVariable(fromSlot, toSlot);
++ }
++
++ private void defineLocalVariable(final int fromSlot, final int toSlot) {
++ assert !hasLoadsOnStack(fromSlot, toSlot);
++ assert fromSlot < toSlot;
++ symbolBoundary.clear(fromSlot, toSlot - 1);
++ symbolBoundary.set(toSlot - 1);
++ final int lastExisting = Math.min(toSlot, localVariableTypes.size());
++ for(int i = fromSlot; i < lastExisting; ++i) {
++ localVariableTypes.set(i, Type.UNKNOWN);
++ }
++ for(int i = lastExisting; i < toSlot; ++i) {
++ localVariableTypes.add(i, Type.UNKNOWN);
++ }
++ }
++
++ /**
++ * Undefines all local variables past the specified slot.
++ * @param fromSlot the first slot to be undefined
++ * @param canTruncateSymbol if false, the fromSlot must be either the first slot of a symbol, or the first slot
++ * after the last symbol. If true, the fromSlot can be in the middle of the storage area for a symbol. This
++ * should be used with care - it is only meant for use in optimism exception handlers.
++ */
++ void undefineLocalVariables(final int fromSlot, final boolean canTruncateSymbol) {
++ final int lvarCount = localVariableTypes.size();
++ assert lvarCount == symbolBoundary.length();
++ assert !hasLoadsOnStack(fromSlot, lvarCount);
++ if(canTruncateSymbol) {
++ if(fromSlot > 0) {
++ symbolBoundary.set(fromSlot - 1);
++ }
++ } else {
++ assert fromSlot == 0 || symbolBoundary.get(fromSlot - 1);
++ }
++ if(fromSlot < lvarCount) {
++ symbolBoundary.clear(fromSlot, lvarCount);
++ localVariableTypes.subList(fromSlot, lvarCount).clear();
++ }
++ firstTemp = Math.min(fromSlot, firstTemp);
++ assert symbolBoundary.length() == localVariableTypes.size();
++ assert symbolBoundary.length() == fromSlot;
++ }
++
++ private void markAsOptimisticCatchHandler(final int liveLocalCount) {
++ // Live temporaries that are no longer on stack are undefined
++ undefineLocalVariables(liveLocalCount, true);
++ // Temporaries are promoted
++ firstTemp = liveLocalCount;
++ // No trailing undefineds
++ localVariableTypes.subList(firstTemp, localVariableTypes.size()).clear();
++ assert symbolBoundary.length() == firstTemp;
++ // Generalize all reference types to Object, and promote boolean to int
++ for(final ListIterator<Type> it = localVariableTypes.listIterator(); it.hasNext();) {
++ final Type type = it.next();
++ if(type == Type.BOOLEAN) {
++ it.set(Type.INT);
++ } else if(type.isObject() && type != Type.OBJECT) {
++ it.set(Type.OBJECT);
++ }
++ }
++ }
++
++ /**
++ * Returns true if any loads on the stack come from the specified slot range.
++ * @param fromSlot start of the range (inclusive)
++ * @param toSlot end of the range (exclusive)
++ * @return true if any loads on the stack come from the specified slot range.
++ */
++ boolean hasLoadsOnStack(final int fromSlot, final int toSlot) {
++ for(int i = 0; i < sp; ++i) {
++ final int load = localLoads[i];
++ if(load >= fromSlot && load < toSlot) {
++ return true;
++ }
++ }
++ return false;
+ }
+
+ @Override
+ public String toString() {
+- final StringBuilder builder = new StringBuilder("[");
+- for (int i = 0; i < sp; i++) {
+- builder.append(data[i]);
+- if (i < sp - 1) {
+- builder.append(", ");
+- }
+- }
+- return builder.append("]").toString();
++ return "stack=" + Arrays.toString(Arrays.copyOf(data, sp))
++ + ", symbolBoundaries=" + String.valueOf(symbolBoundary)
++ + ", firstTemp=" + firstTemp
++ + ", localTypes=" + String.valueOf(localVariableTypes)
++ ;
+ }
+ }
+
++ /** Next id for debugging purposes, remove if footprint becomes unmanageable */
++ private static int nextId = 0;
++
+ /** Name of this label */
+ private final String name;
+
+ /** Type stack at this label */
+- private Label.Stack stack;
++ private transient Label.Stack stack;
+
+ /** ASM representation of this label */
+ private jdk.internal.org.objectweb.asm.Label label;
+
++ /** Id for debugging purposes, remove if footprint becomes unmanageable */
++ private final int id;
++
++ /** Is this label reachable (anything ever jumped to it)? */
++ private transient boolean reachable;
++
++ private transient boolean breakTarget;
++
+ /**
+ * Constructor
+ *
+@@ -136,6 +515,7 @@
+ public Label(final String name) {
+ super();
+ this.name = name;
++ this.id = nextId++;
+ }
+
+ /**
+@@ -146,9 +526,9 @@
+ public Label(final Label label) {
+ super();
+ this.name = label.name;
++ this.id = label.id;
+ }
+
+-
+ jdk.internal.org.objectweb.asm.Label getLabel() {
+ if (this.label == null) {
+ this.label = new jdk.internal.org.objectweb.asm.Label();
+@@ -160,12 +540,66 @@
+ return stack;
+ }
+
+- void setStack(final Label.Stack stack) {
+- this.stack = stack;
++ void joinFrom(final Label.Stack joinOrigin) {
++ this.reachable = true;
++ if(stack == null) {
++ stack = joinOrigin.clone();
++ } else {
++ stack.joinFrom(joinOrigin, breakTarget);
++ }
+ }
+
++ void joinFromTry(final Label.Stack joinOrigin, final boolean isOptimismHandler) {
++ this.reachable = true;
++ if (stack == null) {
++ if(!isOptimismHandler) {
++ stack = joinOrigin.cloneWithEmptyStack();
++ // Optimism handler needs temporaries to remain live, others don't.
++ stack.undefineLocalVariables(stack.firstTemp, false);
++ }
++ } else {
++ assert !isOptimismHandler;
++ stack.joinFromTry(joinOrigin);
++ }
++ }
++
++ void markAsBreakTarget() {
++ breakTarget = true;
++ }
++
++ boolean isBreakTarget() {
++ return breakTarget;
++ }
++
++ void onCatch() {
++ if(stack != null) {
++ stack = stack.cloneWithEmptyStack();
++ }
++ }
++ void markAsOptimisticCatchHandler(final Label.Stack currentStack, final int liveLocalCount) {
++ stack = currentStack.cloneWithEmptyStack();
++ stack.markAsOptimisticCatchHandler(liveLocalCount);
++ }
++
++ void markAsOptimisticContinuationHandlerFor(final Label afterConsumeStackLabel) {
++ stack = afterConsumeStackLabel.stack.cloneWithEmptyStack();
++ }
++
++ boolean isReachable() {
++ return reachable;
++ }
++
++ boolean isAfter(final Label other) {
++ return label.getOffset() > other.label.getOffset();
++ }
++
++ private String str;
++
+ @Override
+ public String toString() {
+- return name + '_' + Debug.id(this);
++ if (str == null) {
++ str = name + '_' + id;
++ }
++ return str;
+ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/LocalStateRestorationInfo.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
++
++import jdk.nashorn.internal.codegen.types.Type;
++
++/**
++ * Encapsulates the information for restoring the local state when continuing execution after a rewrite triggered by
++ * an optimistic assumption failure. An instance of this class is specific to a program point.
++ *
++ */
++public class LocalStateRestorationInfo {
++ private final Type[] localVariableTypes;
++ private final int[] stackLoads;
++
++ LocalStateRestorationInfo(final Type[] localVariableTypes, final int[] stackLoads) {
++ this.localVariableTypes = localVariableTypes;
++ this.stackLoads = stackLoads;
++ }
++
++ /**
++ * Returns the types of the local variables at the continuation of a program point.
++ * @return the types of the local variables at the continuation of a program point.
++ */
++ public Type[] getLocalVariableTypes() {
++ return localVariableTypes.clone();
++ }
++
++ /**
++ * Returns the indices of local variables that need to be loaded on stack before jumping to the continuation of the
++ * program point.
++ * @return the indices of local variables that need to be loaded on stack.
++ */
++ public int[] getStackLoads() {
++ return stackLoads.clone();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1562 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
++
++import static jdk.nashorn.internal.codegen.CompilerConstants.RETURN;
++import static jdk.nashorn.internal.ir.Expression.isAlwaysFalse;
++import static jdk.nashorn.internal.ir.Expression.isAlwaysTrue;
++
++import java.util.ArrayDeque;
++import java.util.ArrayList;
++import java.util.Collections;
++import java.util.Deque;
++import java.util.HashSet;
++import java.util.IdentityHashMap;
++import java.util.Iterator;
++import java.util.LinkedList;
++import java.util.List;
++import java.util.Map;
++import java.util.Set;
++import java.util.function.Function;
++import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.ir.AccessNode;
++import jdk.nashorn.internal.ir.BaseNode;
++import jdk.nashorn.internal.ir.BinaryNode;
++import jdk.nashorn.internal.ir.Block;
++import jdk.nashorn.internal.ir.BreakNode;
++import jdk.nashorn.internal.ir.BreakableNode;
++import jdk.nashorn.internal.ir.CaseNode;
++import jdk.nashorn.internal.ir.CatchNode;
++import jdk.nashorn.internal.ir.ContinueNode;
++import jdk.nashorn.internal.ir.Expression;
++import jdk.nashorn.internal.ir.ForNode;
++import jdk.nashorn.internal.ir.FunctionNode;
++import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
++import jdk.nashorn.internal.ir.IdentNode;
++import jdk.nashorn.internal.ir.IfNode;
++import jdk.nashorn.internal.ir.IndexNode;
++import jdk.nashorn.internal.ir.JoinPredecessor;
++import jdk.nashorn.internal.ir.JoinPredecessorExpression;
++import jdk.nashorn.internal.ir.JumpStatement;
++import jdk.nashorn.internal.ir.LabelNode;
++import jdk.nashorn.internal.ir.LexicalContext;
++import jdk.nashorn.internal.ir.LexicalContextNode;
++import jdk.nashorn.internal.ir.LiteralNode;
++import jdk.nashorn.internal.ir.LocalVariableConversion;
++import jdk.nashorn.internal.ir.LoopNode;
++import jdk.nashorn.internal.ir.Node;
++import jdk.nashorn.internal.ir.PropertyNode;
++import jdk.nashorn.internal.ir.ReturnNode;
++import jdk.nashorn.internal.ir.RuntimeNode;
++import jdk.nashorn.internal.ir.RuntimeNode.Request;
++import jdk.nashorn.internal.ir.SplitReturn;
++import jdk.nashorn.internal.ir.Statement;
++import jdk.nashorn.internal.ir.SwitchNode;
++import jdk.nashorn.internal.ir.Symbol;
++import jdk.nashorn.internal.ir.TernaryNode;
++import jdk.nashorn.internal.ir.ThrowNode;
++import jdk.nashorn.internal.ir.TryNode;
++import jdk.nashorn.internal.ir.UnaryNode;
++import jdk.nashorn.internal.ir.VarNode;
++import jdk.nashorn.internal.ir.WhileNode;
++import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++import jdk.nashorn.internal.parser.TokenType;
++
++/**
++ * Calculates types for local variables. For purposes of local variable type calculation, the only types used are
++ * Undefined, boolean, int, long, double, and Object. The calculation eagerly widens types of local variable to their
++ * widest at control flow join points.
++ * TODO: investigate a more sophisticated solution that uses use/def information to only widens the type of a local
++ * variable to its widest used type after the join point. That would eliminate some widenings of undefined variables to
++ * object, most notably those used only in loops. We need a full liveness analysis for that. Currently, we can establish
++ * per-type liveness, which eliminates most of unwanted dead widenings.
++ * NOTE: the way this class is implemented, it actually processes the AST in two passes. The first pass is top-down and
++ * implemented in {@code enterXxx} methods. This pass does not mutate the AST (except for one occurrence, noted below),
++ * as being able to find relevant labels for control flow joins is sensitive to their reference identity, and mutated
++ * label-carrying nodes will create copies of their labels. A second bottom-up pass applying the changes is implemented
++ * in the separate visitor sitting in {@link #leaveFunctionNode(FunctionNode)}. This visitor will also instantiate new
++ * instances of the calculator to be run on nested functions (when not lazy compiling).
++ *
++ */
++final class LocalVariableTypesCalculator extends NodeVisitor<LexicalContext>{
++
++ private static class JumpOrigin {
++ final JoinPredecessor node;
++ final Map<Symbol, LvarType> types;
++
++ JumpOrigin(final JoinPredecessor node, final Map<Symbol, LvarType> types) {
++ this.node = node;
++ this.types = types;
++ }
++ }
++
++ private static class JumpTarget {
++ private final List<JumpOrigin> origins = new LinkedList<>();
++ private Map<Symbol, LvarType> types = Collections.emptyMap();
++
++ void addOrigin(final JoinPredecessor originNode, final Map<Symbol, LvarType> originTypes) {
++ origins.add(new JumpOrigin(originNode, originTypes));
++ this.types = getUnionTypes(this.types, originTypes);
++ }
++ }
++ private enum LvarType {
++ UNDEFINED(Type.UNDEFINED),
++ BOOLEAN(Type.BOOLEAN),
++ INT(Type.INT),
++ LONG(Type.LONG),
++ DOUBLE(Type.NUMBER),
++ OBJECT(Type.OBJECT);
++
++ private final Type type;
++ private LvarType(final Type type) {
++ this.type = type;
++ }
++ }
++
++ private static final Map<Type, LvarType> TO_LVAR_TYPE = new IdentityHashMap<>();
++
++ static {
++ for(final LvarType lvarType: LvarType.values()) {
++ TO_LVAR_TYPE.put(lvarType.type, lvarType);
++ }
++ }
++
++ @SuppressWarnings("unchecked")
++ private static IdentityHashMap<Symbol, LvarType> cloneMap(final Map<Symbol, LvarType> map) {
++ return (IdentityHashMap<Symbol, LvarType>)((IdentityHashMap<?,?>)map).clone();
++ }
++
++ private LocalVariableConversion createConversion(final Symbol symbol, final LvarType branchLvarType,
++ final Map<Symbol, LvarType> joinLvarTypes, final LocalVariableConversion next) {
++ final LvarType targetType = joinLvarTypes.get(symbol);
++ assert targetType != null;
++ if(targetType == branchLvarType) {
++ return next;
++ }
++ // NOTE: we could naively just use symbolIsUsed(symbol, branchLvarType) here, but that'd be wrong. While
++ // technically a conversion will read the value of the symbol with that type, but it will also write it to a new
++ // type, and that type might be dead (we can't know yet). For this reason, we don't treat conversion reads as
++ // real uses until we know their target type is live. If we didn't do this, and just did a symbolIsUsed here,
++ // we'd introduce false live variables which could nevertheless turn into dead ones in a subsequent
++ // deoptimization, causing a shift in the list of live locals that'd cause erroneous restoration of
++ // continuations (since RewriteException's byteCodeSlots carries an array and not a name-value map).
++
++ symbolIsConverted(symbol, branchLvarType, targetType);
++ //symbolIsUsed(symbol, branchLvarType);
++ return new LocalVariableConversion(symbol, branchLvarType.type, targetType.type, next);
++ }
++
++ private static Map<Symbol, LvarType> getUnionTypes(final Map<Symbol, LvarType> types1, final Map<Symbol, LvarType> types2) {
++ if(types1 == types2 || types1.isEmpty()) {
++ return types2;
++ } else if(types2.isEmpty()) {
++ return types1;
++ }
++ final Set<Symbol> commonSymbols = new HashSet<>(types1.keySet());
++ commonSymbols.retainAll(types2.keySet());
++ // We have a chance of returning an unmodified set if both sets have the same keys and one is strictly wider
++ // than the other.
++ final int commonSize = commonSymbols.size();
++ final int types1Size = types1.size();
++ final int types2Size = types2.size();
++ if(commonSize == types1Size && commonSize == types2Size) {
++ boolean matches1 = true, matches2 = true;
++ Map<Symbol, LvarType> union = null;
++ for(final Symbol symbol: commonSymbols) {
++ final LvarType type1 = types1.get(symbol);
++ final LvarType type2 = types2.get(symbol);
++ final LvarType widest = widestLvarType(type1, type2);
++ if(widest != type1 && matches1) {
++ matches1 = false;
++ if(!matches2) {
++ union = cloneMap(types1);
++ }
++ }
++ if (widest != type2 && matches2) {
++ matches2 = false;
++ if(!matches1) {
++ union = cloneMap(types2);
++ }
++ }
++ if(!(matches1 || matches2) && union != null) { //remove overly enthusiastic "union can be null" warning
++ assert union != null;
++ union.put(symbol, widest);
++ }
++ }
++ return matches1 ? types1 : matches2 ? types2 : union;
++ }
++ // General case
++ final Map<Symbol, LvarType> union;
++ if(types1Size > types2Size) {
++ union = cloneMap(types1);
++ union.putAll(types2);
++ } else {
++ union = cloneMap(types2);
++ union.putAll(types1);
++ }
++ for(final Symbol symbol: commonSymbols) {
++ final LvarType type1 = types1.get(symbol);
++ final LvarType type2 = types2.get(symbol);
++ union.put(symbol, widestLvarType(type1, type2));
++ }
++ return union;
++ }
++
++ private static void symbolIsUsed(final Symbol symbol, final LvarType type) {
++ if(type != LvarType.UNDEFINED) {
++ symbol.setHasSlotFor(type.type);
++ }
++ }
++
++ private static class SymbolConversions {
++ private static byte I2L = 1 << 0;
++ private static byte I2D = 1 << 1;
++ private static byte I2O = 1 << 2;
++ private static byte L2D = 1 << 3;
++ private static byte L2O = 1 << 4;
++ private static byte D2O = 1 << 5;
++
++ private byte conversions;
++
++ void recordConversion(final LvarType from, final LvarType to) {
++ switch (from) {
++ case UNDEFINED:
++ return;
++ case INT:
++ case BOOLEAN:
++ switch (to) {
++ case LONG:
++ recordConversion(I2L);
++ return;
++ case DOUBLE:
++ recordConversion(I2D);
++ return;
++ case OBJECT:
++ recordConversion(I2O);
++ return;
++ default:
++ illegalConversion(from, to);
++ return;
++ }
++ case LONG:
++ switch (to) {
++ case DOUBLE:
++ recordConversion(L2D);
++ return;
++ case OBJECT:
++ recordConversion(L2O);
++ return;
++ default:
++ illegalConversion(from, to);
++ return;
++ }
++ case DOUBLE:
++ if(to == LvarType.OBJECT) {
++ recordConversion(D2O);
++ }
++ return;
++ default:
++ illegalConversion(from, to);
++ }
++ }
++
++ private static void illegalConversion(final LvarType from, final LvarType to) {
++ throw new AssertionError("Invalid conversion from " + from + " to " + to);
++ }
++
++ void recordConversion(final byte convFlag) {
++ conversions = (byte)(conversions | convFlag);
++ }
++
++ boolean hasConversion(final byte convFlag) {
++ return (conversions & convFlag) != 0;
++ }
++
++ void calculateTypeLiveness(final Symbol symbol) {
++ if(symbol.hasSlotFor(Type.OBJECT)) {
++ if(hasConversion(D2O)) {
++ symbol.setHasSlotFor(Type.NUMBER);
++ }
++ if(hasConversion(L2O)) {
++ symbol.setHasSlotFor(Type.LONG);
++ }
++ if(hasConversion(I2O)) {
++ symbol.setHasSlotFor(Type.INT);
++ }
++ }
++ if(symbol.hasSlotFor(Type.NUMBER)) {
++ if(hasConversion(L2D)) {
++ symbol.setHasSlotFor(Type.LONG);
++ }
++ if(hasConversion(I2D)) {
++ symbol.setHasSlotFor(Type.INT);
++ }
++ }
++ if(symbol.hasSlotFor(Type.LONG)) {
++ if(hasConversion(I2L)) {
++ symbol.setHasSlotFor(Type.INT);
++ }
++ }
++ }
++ }
++
++ private void symbolIsConverted(final Symbol symbol, final LvarType from, final LvarType to) {
++ SymbolConversions conversions = symbolConversions.get(symbol);
++ if(conversions == null) {
++ conversions = new SymbolConversions();
++ symbolConversions.put(symbol, conversions);
++ }
++ conversions.recordConversion(from, to);
++ }
++
++ private static LvarType toLvarType(final Type type) {
++ assert type != null;
++ final LvarType lvarType = TO_LVAR_TYPE.get(type);
++ if(lvarType != null) {
++ return lvarType;
++ }
++ assert type.isObject();
++ return LvarType.OBJECT;
++ }
++ private static LvarType widestLvarType(final LvarType t1, final LvarType t2) {
++ if(t1 == t2) {
++ return t1;
++ }
++ // Undefined or boolean to anything always widens to object.
++ if(t1.ordinal() < LvarType.INT.ordinal() || t2.ordinal() < LvarType.INT.ordinal()) {
++ return LvarType.OBJECT;
++ }
++ // NOTE: we allow "widening" of long to double even though it can lose precision. ECMAScript doesn't have an
++ // Int64 type anyway, so this loss of precision is actually more conformant to the specification...
++ return LvarType.values()[Math.max(t1.ordinal(), t2.ordinal())];
++ }
++ private final Compiler compiler;
++ private final Map<Label, JumpTarget> jumpTargets = new IdentityHashMap<>();
++ // Local variable type mapping at the currently evaluated point. No map instance is ever modified; setLvarType() always
++ // allocates a new map. Immutability of maps allows for cheap snapshots by just keeping the reference to the current
++ // value.
++ private Map<Symbol, LvarType> localVariableTypes = new IdentityHashMap<>();
++
++ // Whether the current point in the AST is reachable code
++ private boolean reachable = true;
++ // Return type of the function
++ private Type returnType = Type.UNKNOWN;
++ // Synthetic return node that we must insert at the end of the function if it's end is reachable.
++ private ReturnNode syntheticReturn;
++
++ private boolean alreadyEnteredTopLevelFunction;
++
++ // LvarType and conversion information gathered during the top-down pass; applied to nodes in the bottom-up pass.
++ private final Map<JoinPredecessor, LocalVariableConversion> localVariableConversions = new IdentityHashMap<>();
++
++ private final Map<IdentNode, LvarType> identifierLvarTypes = new IdentityHashMap<>();
++ private final Map<Symbol, SymbolConversions> symbolConversions = new IdentityHashMap<>();
++
++ private SymbolToType symbolToType = new SymbolToType();
++
++ // Stack of open labels for starts of catch blocks, one for every currently traversed try block; for inserting
++ // control flow edges to them. Note that we currently don't insert actual control flow edges, but instead edges that
++ // help us with type calculations. This means that some operations that can result in an exception being thrown
++ // aren't considered (function calls, side effecting property getters and setters etc.), while some operations that
++ // don't result in control flow transfers do originate an edge to the catch blocks (namely, assignments to local
++ // variables).
++ private final Deque<Label> catchLabels = new ArrayDeque<>();
++
++ LocalVariableTypesCalculator(final Compiler compiler) {
++ super(new LexicalContext());
++ this.compiler = compiler;
++ }
++
++ private JumpTarget createJumpTarget(final Label label) {
++ assert !jumpTargets.containsKey(label);
++ final JumpTarget jumpTarget = new JumpTarget();
++ jumpTargets.put(label, jumpTarget);
++ return jumpTarget;
++ }
++
++ private void doesNotContinueSequentially() {
++ reachable = false;
++ localVariableTypes = Collections.emptyMap();
++ }
++
++
++ @Override
++ public boolean enterBinaryNode(final BinaryNode binaryNode) {
++ // NOTE: regardless of operator's lexical associativity, lhs is always evaluated first.
++ final Expression lhs = binaryNode.lhs();
++ final boolean isAssignment = binaryNode.isAssignment();
++ LvarType lhsTypeOnLoad = null;
++ if(isAssignment) {
++ if(lhs instanceof BaseNode) {
++ ((BaseNode)lhs).getBase().accept(this);
++ if(lhs instanceof IndexNode) {
++ ((IndexNode)lhs).getIndex().accept(this);
++ } else {
++ assert lhs instanceof AccessNode;
++ }
++ } else {
++ assert lhs instanceof IdentNode;
++ if(binaryNode.isSelfModifying()) {
++ final IdentNode ident = ((IdentNode)lhs);
++ ident.accept(this);
++ // Self-assignment can cause a change in the type of the variable. For purposes of evaluating
++ // the type of the operation, we must use its type as it was when it was loaded. If we didn't
++ // do this, some awkward expressions would end up being calculated incorrectly, e.g.
++ // "var x; x += x = 0;". In this case we have undefined+int so the result type is double (NaN).
++ // However, if we used the type of "x" on LHS after we evaluated RHS, we'd see int+int, so the
++ // result type would be either optimistic int or pessimistic long, which would be wrong.
++ lhsTypeOnLoad = getLocalVariableTypeIfBytecode(ident.getSymbol());
++ }
++ }
++ } else {
++ lhs.accept(this);
++ }
++
++ final boolean isLogical = binaryNode.isLogical();
++ assert !(isAssignment && isLogical); // there are no logical assignment operators in JS
++ final Label joinLabel = isLogical ? new Label("") : null;
++ if(isLogical) {
++ jumpToLabel((JoinPredecessor)lhs, joinLabel);
++ }
++
++ final Expression rhs = binaryNode.rhs();
++ rhs.accept(this);
++ if(isLogical) {
++ jumpToLabel((JoinPredecessor)rhs, joinLabel);
++ }
++ joinOnLabel(joinLabel);
++
++ if(isAssignment && lhs instanceof IdentNode) {
++ if(binaryNode.isSelfModifying()) {
++ onSelfAssignment((IdentNode)lhs, binaryNode, lhsTypeOnLoad);
++ } else {
++ onAssignment((IdentNode)lhs, rhs);
++ }
++ }
++ return false;
++ }
++
++ @Override
++ public boolean enterBlock(final Block block) {
++ for(final Symbol symbol: block.getSymbols()) {
++ if(symbol.isBytecodeLocal() && getLocalVariableTypeOrNull(symbol) == null) {
++ setType(symbol, LvarType.UNDEFINED);
++ }
++ }
++ return true;
++ }
++
++ @Override
++ public boolean enterBreakNode(final BreakNode breakNode) {
++ return enterJumpStatement(breakNode);
++ }
++
++ @Override
++ public boolean enterContinueNode(final ContinueNode continueNode) {
++ return enterJumpStatement(continueNode);
++ }
++
++ private boolean enterJumpStatement(final JumpStatement jump) {
++ if(!reachable) {
++ return false;
++ }
++ final BreakableNode target = jump.getTarget(lc);
++ jumpToLabel(jump, jump.getTargetLabel(target), getBreakTargetTypes(target));
++ doesNotContinueSequentially();
++ return false;
++ }
++
++ @Override
++ protected boolean enterDefault(final Node node) {
++ return reachable;
++ }
++
++ private void enterDoWhileLoop(final WhileNode loopNode) {
++ final JoinPredecessorExpression test = loopNode.getTest();
++ final Block body = loopNode.getBody();
++ final Label continueLabel = loopNode.getContinueLabel();
++ final Label breakLabel = loopNode.getBreakLabel();
++ final Map<Symbol, LvarType> beforeLoopTypes = localVariableTypes;
++ final Label repeatLabel = new Label("");
++ for(;;) {
++ jumpToLabel(loopNode, repeatLabel, beforeLoopTypes);
++ final Map<Symbol, LvarType> beforeRepeatTypes = localVariableTypes;
++ body.accept(this);
++ if(reachable) {
++ jumpToLabel(body, continueLabel);
++ }
++ joinOnLabel(continueLabel);
++ if(!reachable) {
++ break;
++ }
++ test.accept(this);
++ jumpToLabel(test, breakLabel);
++ if(isAlwaysFalse(test)) {
++ break;
++ }
++ jumpToLabel(test, repeatLabel);
++ joinOnLabel(repeatLabel);
++ if(localVariableTypes.equals(beforeRepeatTypes)) {
++ break;
++ }
++ resetJoinPoint(continueLabel);
++ resetJoinPoint(breakLabel);
++ resetJoinPoint(repeatLabel);
++ }
++
++ if(isAlwaysTrue(test)) {
++ doesNotContinueSequentially();
++ }
++
++ leaveBreakable(loopNode);
++ }
++
++ @Override
++ public boolean enterForNode(final ForNode forNode) {
++ if(!reachable) {
++ return false;
++ }
++
++ final Expression init = forNode.getInit();
++ if(forNode.isForIn()) {
++ final JoinPredecessorExpression iterable = forNode.getModify();
++ iterable.accept(this);
++ enterTestFirstLoop(forNode, null, init,
++ // If we're iterating over property names, and we can discern from the runtime environment
++ // of the compilation that the object being iterated over must use strings for property
++ // names (e.g., it is a native JS object or array), then we'll not bother trying to treat
++ // the property names optimistically.
++ !compiler.useOptimisticTypes() || (!forNode.isForEach() && compiler.hasStringPropertyIterator(iterable.getExpression())));
++ } else {
++ if(init != null) {
++ init.accept(this);
++ }
++ enterTestFirstLoop(forNode, forNode.getModify(), null, false);
++ }
++ return false;
++ }
++
++ @Override
++ public boolean enterFunctionNode(final FunctionNode functionNode) {
++ if(alreadyEnteredTopLevelFunction) {
++ return false;
++ }
++ int pos = 0;
++ if(!functionNode.isVarArg()) {
++ for (final IdentNode param : functionNode.getParameters()) {
++ final Symbol symbol = param.getSymbol();
++ // Parameter is not necessarily bytecode local as it can be scoped due to nested context use, but it
++ // must have a slot if we aren't in a function with vararg signature.
++ assert symbol.hasSlot();
++ final Type callSiteParamType = compiler.getParamType(functionNode, pos);
++ final LvarType paramType = callSiteParamType == null ? LvarType.OBJECT : toLvarType(callSiteParamType);
++ setType(symbol, paramType);
++ // Make sure parameter slot for its incoming value is not marked dead. NOTE: this is a heuristic. Right
++ // now, CodeGenerator.expandParameters() relies on the fact that every parameter's final slot width will
++ // be at least the same as incoming width, therefore even if a parameter is never read, we'll still keep
++ // its slot.
++ symbolIsUsed(symbol);
++ setIdentifierLvarType(param, paramType);
++ pos++;
++ }
++ }
++ setCompilerConstantAsObject(functionNode, CompilerConstants.THIS);
++
++ // TODO: coarse-grained. If we wanted to solve it completely precisely,
++ // we'd also need to push/pop its type when handling WithNode (so that
++ // it can go back to undefined after a 'with' block.
++ if(functionNode.hasScopeBlock() || functionNode.needsParentScope()) {
++ setCompilerConstantAsObject(functionNode, CompilerConstants.SCOPE);
++ }
++ if(functionNode.needsCallee()) {
++ setCompilerConstantAsObject(functionNode, CompilerConstants.CALLEE);
++ }
++ if(functionNode.needsArguments()) {
++ setCompilerConstantAsObject(functionNode, CompilerConstants.ARGUMENTS);
++ }
++
++ alreadyEnteredTopLevelFunction = true;
++ return true;
++ }
++
++ @Override
++ public boolean enterIdentNode(final IdentNode identNode) {
++ final Symbol symbol = identNode.getSymbol();
++ if(symbol.isBytecodeLocal()) {
++ symbolIsUsed(symbol);
++ setIdentifierLvarType(identNode, getLocalVariableType(symbol));
++ }
++ return false;
++ }
++
++ @Override
++ public boolean enterIfNode(final IfNode ifNode) {
++ if(!reachable) {
++ return false;
++ }
++
++ final Expression test = ifNode.getTest();
++ final Block pass = ifNode.getPass();
++ final Block fail = ifNode.getFail();
++
++ test.accept(this);
++
++ final Map<Symbol, LvarType> afterTestLvarTypes = localVariableTypes;
++ if(!isAlwaysFalse(test)) {
++ pass.accept(this);
++ }
++ final Map<Symbol, LvarType> passLvarTypes = localVariableTypes;
++ final boolean reachableFromPass = reachable;
++
++ reachable = true;
++ localVariableTypes = afterTestLvarTypes;
++ if(!isAlwaysTrue(test) && fail != null) {
++ fail.accept(this);
++ final boolean reachableFromFail = reachable;
++ reachable |= reachableFromPass;
++ if(!reachable) {
++ return false;
++ }
++
++ if(reachableFromFail) {
++ if(reachableFromPass) {
++ final Map<Symbol, LvarType> failLvarTypes = localVariableTypes;
++ localVariableTypes = getUnionTypes(passLvarTypes, failLvarTypes);
++ setConversion(pass, passLvarTypes, localVariableTypes);
++ setConversion(fail, failLvarTypes, localVariableTypes);
++ }
++ return false;
++ }
++ }
++
++ if(reachableFromPass) {
++ localVariableTypes = getUnionTypes(afterTestLvarTypes, passLvarTypes);
++ // IfNode itself is associated with conversions that might need to be performed after the test if there's no
++ // else branch. E.g.
++ // if(x = 1, cond) { x = 1.0 } must widen "x = 1" to a double.
++ setConversion(pass, passLvarTypes, localVariableTypes);
++ setConversion(ifNode, afterTestLvarTypes, localVariableTypes);
++ } else {
++ localVariableTypes = afterTestLvarTypes;
++ }
++
++ return false;
++ }
++
++ @Override
++ public boolean enterPropertyNode(final PropertyNode propertyNode) {
++ // Avoid falsely adding property keys to the control flow graph
++ if(propertyNode.getValue() != null) {
++ propertyNode.getValue().accept(this);
++ }
++ return false;
++ }
++
++ @Override
++ public boolean enterReturnNode(final ReturnNode returnNode) {
++ if(!reachable) {
++ return false;
++ }
++
++ final Expression returnExpr = returnNode.getExpression();
++ final Type returnExprType;
++ if(returnExpr != null) {
++ returnExpr.accept(this);
++ returnExprType = getType(returnExpr);
++ } else {
++ returnExprType = Type.UNDEFINED;
++ }
++ returnType = Type.widestReturnType(returnType, returnExprType);
++ doesNotContinueSequentially();
++ return false;
++ }
++
++ @Override
++ public boolean enterSplitReturn(final SplitReturn splitReturn) {
++ doesNotContinueSequentially();
++ return false;
++ }
++
++ @Override
++ public boolean enterSwitchNode(final SwitchNode switchNode) {
++ if(!reachable) {
++ return false;
++ }
++
++ final Expression expr = switchNode.getExpression();
++ expr.accept(this);
++
++ final List<CaseNode> cases = switchNode.getCases();
++ if(cases.isEmpty()) {
++ return false;
++ }
++
++ // Control flow is different for all-integer cases where we dispatch by switch table, and for all other cases
++ // where we do sequential comparison. Note that CaseNode objects act as join points.
++ final boolean isInteger = switchNode.isUniqueInteger();
++ final Label breakLabel = switchNode.getBreakLabel();
++ final boolean hasDefault = switchNode.getDefaultCase() != null;
++
++ boolean tagUsed = false;
++ for(final CaseNode caseNode: cases) {
++ final Expression test = caseNode.getTest();
++ if(!isInteger && test != null) {
++ test.accept(this);
++ if(!tagUsed) {
++ symbolIsUsed(switchNode.getTag(), LvarType.OBJECT);
++ tagUsed = true;
++ }
++ }
++ // CaseNode carries the conversions that need to be performed on its entry from the test.
++ // CodeGenerator ensures these are only emitted when arriving on the branch and not through a
++ // fallthrough.
++ jumpToLabel(caseNode, caseNode.getBody().getEntryLabel());
++ }
++ if(!hasDefault) {
++ // No default case means we can arrive at the break label without entering any cases. In that case
++ // SwitchNode will carry the conversions that need to be performed before it does that jump.
++ jumpToLabel(switchNode, breakLabel);
++ }
++
++ // All cases are arrived at through jumps
++ doesNotContinueSequentially();
++
++ Block previousBlock = null;
++ for(final CaseNode caseNode: cases) {
++ final Block body = caseNode.getBody();
++ final Label entryLabel = body.getEntryLabel();
++ if(previousBlock != null && reachable) {
++ jumpToLabel(previousBlock, entryLabel);
++ }
++ joinOnLabel(entryLabel);
++ assert reachable == true;
++ body.accept(this);
++ previousBlock = body;
++ }
++ if(previousBlock != null && reachable) {
++ jumpToLabel(previousBlock, breakLabel);
++ }
++ leaveBreakable(switchNode);
++ return false;
++ }
++
++ @Override
++ public boolean enterTernaryNode(final TernaryNode ternaryNode) {
++ final Expression test = ternaryNode.getTest();
++ final Expression trueExpr = ternaryNode.getTrueExpression();
++ final Expression falseExpr = ternaryNode.getFalseExpression();
++
++ test.accept(this);
++
++ final Map<Symbol, LvarType> testExitLvarTypes = localVariableTypes;
++ if(!isAlwaysFalse(test)) {
++ trueExpr.accept(this);
++ }
++ final Map<Symbol, LvarType> trueExitLvarTypes = localVariableTypes;
++ localVariableTypes = testExitLvarTypes;
++ if(!isAlwaysTrue(test)) {
++ falseExpr.accept(this);
++ }
++ final Map<Symbol, LvarType> falseExitLvarTypes = localVariableTypes;
++ localVariableTypes = getUnionTypes(trueExitLvarTypes, falseExitLvarTypes);
++ setConversion((JoinPredecessor)trueExpr, trueExitLvarTypes, localVariableTypes);
++ setConversion((JoinPredecessor)falseExpr, falseExitLvarTypes, localVariableTypes);
++ return false;
++ }
++
++ private void enterTestFirstLoop(final LoopNode loopNode, final JoinPredecessorExpression modify,
++ final Expression iteratorValues, final boolean iteratorValuesAreObject) {
++ final JoinPredecessorExpression test = loopNode.getTest();
++ if(isAlwaysFalse(test)) {
++ test.accept(this);
++ return;
++ }
++
++ final Label continueLabel = loopNode.getContinueLabel();
++ final Label breakLabel = loopNode.getBreakLabel();
++
++ final Label repeatLabel = modify == null ? continueLabel : new Label("");
++ final Map<Symbol, LvarType> beforeLoopTypes = localVariableTypes;
++ for(;;) {
++ jumpToLabel(loopNode, repeatLabel, beforeLoopTypes);
++ final Map<Symbol, LvarType> beforeRepeatTypes = localVariableTypes;
++ if(test != null) {
++ test.accept(this);
++ }
++ if(!isAlwaysTrue(test)) {
++ jumpToLabel(test, breakLabel);
++ }
++ if(iteratorValues instanceof IdentNode) {
++ final IdentNode ident = (IdentNode)iteratorValues;
++ // Receives iterator values; the optimistic type of the iterator values is tracked on the
++ // identifier, but we override optimism if it's known that the object being iterated over will
++ // never have primitive property names.
++ onAssignment(ident, iteratorValuesAreObject ? LvarType.OBJECT :
++ toLvarType(compiler.getOptimisticType(ident)));
++ }
++ final Block body = loopNode.getBody();
++ body.accept(this);
++ if(reachable) {
++ jumpToLabel(body, continueLabel);
++ }
++ joinOnLabel(continueLabel);
++ if(!reachable) {
++ break;
++ }
++ if(modify != null) {
++ modify.accept(this);
++ jumpToLabel(modify, repeatLabel);
++ joinOnLabel(repeatLabel);
++ }
++ if(localVariableTypes.equals(beforeRepeatTypes)) {
++ break;
++ }
++ // Reset the join points and repeat the analysis
++ resetJoinPoint(continueLabel);
++ resetJoinPoint(breakLabel);
++ resetJoinPoint(repeatLabel);
++ }
++
++ if(isAlwaysTrue(test) && iteratorValues == null) {
++ doesNotContinueSequentially();
++ }
++
++ leaveBreakable(loopNode);
++ }
++
++ @Override
++ public boolean enterThrowNode(final ThrowNode throwNode) {
++ if(!reachable) {
++ return false;
++ }
++
++ throwNode.getExpression().accept(this);
++ jumpToCatchBlock(throwNode);
++ doesNotContinueSequentially();
++ return false;
++ }
++
++ @Override
++ public boolean enterTryNode(final TryNode tryNode) {
++ if(!reachable) {
++ return false;
++ }
++
++ // This is the label for the join point at the entry of the catch blocks.
++ final Label catchLabel = new Label("");
++ catchLabels.push(catchLabel);
++
++ // Presume that even the start of the try block can immediately go to the catch
++ jumpToLabel(tryNode, catchLabel);
++
++ final Block body = tryNode.getBody();
++ body.accept(this);
++ catchLabels.pop();
++
++ // Final exit label for the whole try/catch construct (after the try block and after all catches).
++ final Label endLabel = new Label("");
++
++ boolean canExit = false;
++ if(reachable) {
++ jumpToLabel(body, endLabel);
++ canExit = true;
++ }
++ doesNotContinueSequentially();
++
++ joinOnLabel(catchLabel);
++ for(final CatchNode catchNode: tryNode.getCatches()) {
++ final IdentNode exception = catchNode.getException();
++ onAssignment(exception, LvarType.OBJECT);
++ final Expression condition = catchNode.getExceptionCondition();
++ if(condition != null) {
++ condition.accept(this);
++ }
++ final Map<Symbol, LvarType> afterConditionTypes = localVariableTypes;
++ final Block catchBody = catchNode.getBody();
++ // TODO: currently, we consider that the catch blocks are always reachable from the try block as currently
++ // we lack enough analysis to prove that no statement before a break/continue/return in the try block can
++ // throw an exception.
++ reachable = true;
++ catchBody.accept(this);
++ final Symbol exceptionSymbol = exception.getSymbol();
++ if(reachable) {
++ localVariableTypes = cloneMap(localVariableTypes);
++ localVariableTypes.remove(exceptionSymbol);
++ jumpToLabel(catchBody, endLabel);
++ canExit = true;
++ }
++ localVariableTypes = cloneMap(afterConditionTypes);
++ localVariableTypes.remove(exceptionSymbol);
++ }
++ // NOTE: if we had one or more conditional catch blocks with no unconditional catch block following them, then
++ // there will be an unconditional rethrow, so the join point can never be reached from the last
++ // conditionExpression.
++ doesNotContinueSequentially();
++
++ if(canExit) {
++ joinOnLabel(endLabel);
++ }
++
++ return false;
++ }
++
++
++ @Override
++ public boolean enterUnaryNode(final UnaryNode unaryNode) {
++ final Expression expr = unaryNode.getExpression();
++ expr.accept(this);
++
++ if(unaryNode.isSelfModifying()) {
++ if(expr instanceof IdentNode) {
++ final IdentNode ident = (IdentNode)expr;
++ onSelfAssignment(ident, unaryNode, getLocalVariableTypeIfBytecode(ident.getSymbol()));
++ }
++ }
++ return false;
++ }
++
++ @Override
++ public boolean enterVarNode(final VarNode varNode) {
++ if (!reachable) {
++ return false;
++ }
++ final Expression init = varNode.getInit();
++ if(init != null) {
++ init.accept(this);
++ onAssignment(varNode.getName(), init);
++ }
++ return false;
++ }
++
++ @Override
++ public boolean enterWhileNode(final WhileNode whileNode) {
++ if(!reachable) {
++ return false;
++ }
++ if(whileNode.isDoWhile()) {
++ enterDoWhileLoop(whileNode);
++ } else {
++ enterTestFirstLoop(whileNode, null, null, false);
++ }
++ return false;
++ }
++
++ private Map<Symbol, LvarType> getBreakTargetTypes(final BreakableNode target) {
++ // Remove symbols defined in the the blocks that are being broken out of.
++ Map<Symbol, LvarType> types = localVariableTypes;
++ for(final Iterator<LexicalContextNode> it = lc.getAllNodes(); it.hasNext();) {
++ final LexicalContextNode node = it.next();
++ if(node instanceof Block) {
++ for(final Symbol symbol: ((Block)node).getSymbols()) {
++ if(localVariableTypes.containsKey(symbol)) {
++ if(types == localVariableTypes) {
++ types = cloneMap(localVariableTypes);
++ }
++ types.remove(symbol);
++ }
++ }
++ }
++ if(node == target) {
++ break;
++ }
++ }
++ return types;
++ }
++
++ /**
++ * Returns the current type of the local variable represented by the symbol. This is the most strict of all
++ * {@code getLocalVariableType*} methods, as it will throw an assertion if the type is null. Therefore, it is only
++ * safe to be invoked on symbols known to be bytecode locals, and only after they have been initialized.
++ * Regardless, it is recommended to use this method in majority of cases, as because of its strictness it is the
++ * best suited for catching missing type calculation bugs early.
++ * @param symbol a symbol representing a bytecode local variable.
++ * @return the current type of the local variable represented by the symbol
++ */
++ private LvarType getLocalVariableType(final Symbol symbol) {
++ final LvarType type = getLocalVariableTypeOrNull(symbol);
++ assert type != null;
++ return type;
++ }
++
++ /**
++ * Gets the type for a local variable if it is a bytecode local, otherwise null. Can be used in circumstances where
++ * the type is irrelevant if the symbol is not a bytecode local. Note that for bytecode locals, it delegates to
++ * {@link #getLocalVariableType(Symbol)}, so it will still assert that the type for such variable is already
++ * defined (that is, not null).
++ * @param symbol the symbol representing the variable.
++ * @return the current variable type, if it is a bytecode local, otherwise null.
++ */
++ private LvarType getLocalVariableTypeIfBytecode(final Symbol symbol) {
++ return symbol.isBytecodeLocal() ? getLocalVariableType(symbol) : null;
++ }
++
++ /**
++ * Gets the type for a variable represented by a symbol, or null if the type is not know. This is the least strict
++ * of all local variable type getters, and as such its use is discouraged except in initialization scenarios (where
++ * a just-defined symbol might still be null).
++ * @param symbol the symbol
++ * @return the current type for the symbol, or null if the type is not known either because the symbol has not been
++ * initialized, or because the symbol does not represent a bytecode local variable.
++ */
++ private LvarType getLocalVariableTypeOrNull(final Symbol symbol) {
++ return localVariableTypes.get(symbol);
++ }
++
++ private JumpTarget getOrCreateJumpTarget(final Label label) {
++ JumpTarget jumpTarget = jumpTargets.get(label);
++ if(jumpTarget == null) {
++ jumpTarget = createJumpTarget(label);
++ }
++ return jumpTarget;
++ }
++
++
++ /**
++ * If there's a join point associated with a label, insert the join point into the flow.
++ * @param label the label to insert a join point for.
++ */
++ private void joinOnLabel(final Label label) {
++ final JumpTarget jumpTarget = jumpTargets.remove(label);
++ if(jumpTarget == null) {
++ return;
++ }
++ assert !jumpTarget.origins.isEmpty();
++ reachable = true;
++ localVariableTypes = getUnionTypes(jumpTarget.types, localVariableTypes);
++ for(final JumpOrigin jumpOrigin: jumpTarget.origins) {
++ setConversion(jumpOrigin.node, jumpOrigin.types, localVariableTypes);
++ }
++ }
++
++ /**
++ * If we're in a try/catch block, add an edge from the specified node to the try node's pre-catch label.
++ */
++ private void jumpToCatchBlock(final JoinPredecessor jumpOrigin) {
++ final Label currentCatchLabel = catchLabels.peek();
++ if(currentCatchLabel != null) {
++ jumpToLabel(jumpOrigin, currentCatchLabel);
++ }
++ }
++
++ private void jumpToLabel(final JoinPredecessor jumpOrigin, final Label label) {
++ jumpToLabel(jumpOrigin, label, localVariableTypes);
++ }
++
++ private void jumpToLabel(final JoinPredecessor jumpOrigin, final Label label, final Map<Symbol, LvarType> types) {
++ getOrCreateJumpTarget(label).addOrigin(jumpOrigin, types);
++ }
++
++ @Override
++ public Node leaveBlock(final Block block) {
++ if(lc.isFunctionBody()) {
++ if(reachable) {
++ // reachable==true means we can reach the end of the function without an explicit return statement. We
++ // need to insert a synthetic one then. This logic used to be in Lower.leaveBlock(), but Lower's
++ // reachability analysis (through Terminal.isTerminal() flags) is not precise enough so
++ // Lower$BlockLexicalContext.afterSetStatements will sometimes think the control flow terminates even
++ // when it didn't. Example: function() { switch((z)) { default: {break; } throw x; } }.
++ createSyntheticReturn(block);
++ assert !reachable;
++ }
++ // We must calculate the return type here (and not in leaveFunctionNode) as it can affect the liveness of
++ // the :return symbol and thus affect conversion type liveness calculations for it.
++ calculateReturnType();
++ }
++
++ boolean cloned = false;
++ for(final Symbol symbol: block.getSymbols()) {
++ // Undefine the symbol outside the block
++ if(localVariableTypes.containsKey(symbol)) {
++ if(!cloned) {
++ localVariableTypes = cloneMap(localVariableTypes);
++ cloned = true;
++ }
++ localVariableTypes.remove(symbol);
++ }
++
++ if(symbol.hasSlot()) {
++ final SymbolConversions conversions = symbolConversions.get(symbol);
++ if(conversions != null) {
++ // Potentially make some currently dead types live if they're needed as a source of a type
++ // conversion at a join.
++ conversions.calculateTypeLiveness(symbol);
++ }
++ if(symbol.slotCount() == 0) {
++ // This is a local variable that is never read. It won't need a slot.
++ symbol.setNeedsSlot(false);
++ }
++ }
++ }
++
++ if(reachable) {
++ // TODO: this is totally backwards. Block should not be breakable, LabelNode should be breakable.
++ final LabelNode labelNode = lc.getCurrentBlockLabelNode();
++ if(labelNode != null) {
++ jumpToLabel(labelNode, block.getBreakLabel());
++ }
++ }
++ leaveBreakable(block);
++ return block;
++ }
++
++ private void calculateReturnType() {
++ // NOTE: if return type is unknown, then the function does not explicitly return a value. Such a function under
++ // ECMAScript rules returns Undefined, which has Type.OBJECT. We might consider an optimization in the future
++ // where we can return void functions.
++ if(returnType.isUnknown()) {
++ returnType = Type.OBJECT;
++ }
++ }
++
++ private void createSyntheticReturn(final Block body) {
++ final FunctionNode functionNode = lc.getCurrentFunction();
++ final long token = functionNode.getToken();
++ final int finish = functionNode.getFinish();
++ final List<Statement> statements = body.getStatements();
++ final int lineNumber = statements.isEmpty() ? functionNode.getLineNumber() : statements.get(statements.size() - 1).getLineNumber();
++ final IdentNode returnExpr;
++ if(functionNode.isProgram()) {
++ returnExpr = new IdentNode(token, finish, RETURN.symbolName()).setSymbol(getCompilerConstantSymbol(functionNode, RETURN));
++ } else {
++ returnExpr = null;
++ }
++ syntheticReturn = new ReturnNode(lineNumber, token, finish, returnExpr);
++ syntheticReturn.accept(this);
++ }
++
++ /**
++ * Leave a breakable node. If there's a join point associated with its break label (meaning there was at least one
++ * break statement to the end of the node), insert the join point into the flow.
++ * @param breakable the breakable node being left.
++ */
++ private void leaveBreakable(final BreakableNode breakable) {
++ joinOnLabel(breakable.getBreakLabel());
++ }
++
++ @Override
++ public Node leaveFunctionNode(final FunctionNode functionNode) {
++ // Sets the return type of the function and also performs the bottom-up pass of applying type and conversion
++ // information to nodes as well as doing the calculation on nested functions as required.
++ FunctionNode newFunction = functionNode;
++ final NodeVisitor<LexicalContext> applyChangesVisitor = new NodeVisitor<LexicalContext>(new LexicalContext()) {
++ private boolean inOuterFunction = true;
++ private final Deque<JoinPredecessor> joinPredecessors = new ArrayDeque<>();
++
++ @Override
++ protected boolean enterDefault(final Node node) {
++ if(!inOuterFunction) {
++ return false;
++ }
++ if(node instanceof JoinPredecessor) {
++ joinPredecessors.push((JoinPredecessor)node);
++ }
++ return inOuterFunction;
++ }
++
++ @Override
++ public boolean enterFunctionNode(final FunctionNode fn) {
++ if(compiler.isOnDemandCompilation()) {
++ // Only calculate nested function local variable types if we're doing eager compilation
++ return false;
++ }
++ inOuterFunction = false;
++ return true;
++ }
++
++ @SuppressWarnings("fallthrough")
++ @Override
++ public Node leaveBinaryNode(final BinaryNode binaryNode) {
++ if(binaryNode.isComparison()) {
++ final Expression lhs = binaryNode.lhs();
++ final Expression rhs = binaryNode.rhs();
++
++ Type cmpWidest = Type.widest(lhs.getType(), rhs.getType());
++ boolean newRuntimeNode = false, finalized = false;
++ final TokenType tt = binaryNode.tokenType();
++ switch (tt) {
++ case EQ_STRICT:
++ case NE_STRICT:
++ // Specialize comparison with undefined
++ final Expression undefinedNode = createIsUndefined(binaryNode, lhs, rhs,
++ tt == TokenType.EQ_STRICT ? Request.IS_UNDEFINED : Request.IS_NOT_UNDEFINED);
++ if(undefinedNode != binaryNode) {
++ return undefinedNode;
++ }
++ // Specialize comparison of boolean with non-boolean
++ if (lhs.getType().isBoolean() != rhs.getType().isBoolean()) {
++ newRuntimeNode = true;
++ cmpWidest = Type.OBJECT;
++ finalized = true;
++ }
++ // fallthrough
++ default:
++ if (newRuntimeNode || cmpWidest.isObject()) {
++ return new RuntimeNode(binaryNode).setIsFinal(finalized);
++ }
++ }
++ } else if(binaryNode.isOptimisticUndecidedType()) {
++ // At this point, we can assign a static type to the optimistic binary ADD operator as now we know
++ // the types of its operands.
++ return binaryNode.decideType();
++ }
++ return binaryNode;
++ }
++
++ @Override
++ protected Node leaveDefault(final Node node) {
++ if(node instanceof JoinPredecessor) {
++ final JoinPredecessor original = joinPredecessors.pop();
++ assert original.getClass() == node.getClass() : original.getClass().getName() + "!=" + node.getClass().getName();
++ return (Node)setLocalVariableConversion(original, (JoinPredecessor)node);
++ }
++ return node;
++ }
++
++ @Override
++ public Node leaveBlock(final Block block) {
++ if(inOuterFunction && syntheticReturn != null && lc.isFunctionBody()) {
++ final ArrayList<Statement> stmts = new ArrayList<>(block.getStatements());
++ stmts.add((ReturnNode)syntheticReturn.accept(this));
++ return block.setStatements(lc, stmts);
++ }
++ return super.leaveBlock(block);
++ }
++
++ @Override
++ public Node leaveFunctionNode(final FunctionNode nestedFunctionNode) {
++ inOuterFunction = true;
++ final FunctionNode newNestedFunction = (FunctionNode)nestedFunctionNode.accept(
++ new LocalVariableTypesCalculator(compiler));
++ lc.replace(nestedFunctionNode, newNestedFunction);
++ return newNestedFunction;
++ }
++
++ @Override
++ public Node leaveIdentNode(final IdentNode identNode) {
++ final IdentNode original = (IdentNode)joinPredecessors.pop();
++ final Symbol symbol = identNode.getSymbol();
++ if(symbol == null) {
++ assert identNode.isPropertyName();
++ return identNode;
++ } else if(symbol.hasSlot()) {
++ assert !symbol.isScope() || symbol.isParam(); // Only params can be slotted and scoped.
++ assert original.getName().equals(identNode.getName());
++ final LvarType lvarType = identifierLvarTypes.remove(original);
++ if(lvarType != null) {
++ return setLocalVariableConversion(original, identNode.setType(lvarType.type));
++ }
++ // If there's no type, then the identifier must've been in unreachable code. In that case, it can't
++ // have assigned conversions either.
++ assert localVariableConversions.get(original) == null;
++ } else {
++ assert identIsDeadAndHasNoLiveConversions(original);
++ }
++ return identNode;
++ }
++
++ @Override
++ public Node leaveLiteralNode(final LiteralNode<?> literalNode) {
++ //for e.g. ArrayLiteralNodes the initial types may have been narrowed due to the
++ //introduction of optimistic behavior - hence ensure that all literal nodes are
++ //reinitialized
++ return literalNode.initialize(lc);
++ }
++
++ @Override
++ public Node leaveRuntimeNode(final RuntimeNode runtimeNode) {
++ final Request request = runtimeNode.getRequest();
++ final boolean isEqStrict = request == Request.EQ_STRICT;
++ if(isEqStrict || request == Request.NE_STRICT) {
++ return createIsUndefined(runtimeNode, runtimeNode.getArgs().get(0), runtimeNode.getArgs().get(1),
++ isEqStrict ? Request.IS_UNDEFINED : Request.IS_NOT_UNDEFINED);
++ }
++ return runtimeNode;
++ }
++
++ @SuppressWarnings("unchecked")
++ private <T extends JoinPredecessor> T setLocalVariableConversion(final JoinPredecessor original, final T jp) {
++ // NOTE: can't use Map.remove() as our copy-on-write AST semantics means some nodes appear twice (in
++ // finally blocks), so we need to be able to access conversions for them multiple times.
++ return (T)jp.setLocalVariableConversion(lc, localVariableConversions.get(original));
++ }
++ };
++
++ newFunction = newFunction.setBody(lc, (Block)newFunction.getBody().accept(applyChangesVisitor));
++ newFunction = newFunction.setReturnType(lc, returnType);
++
++
++ newFunction = newFunction.setState(lc, CompilationState.LOCAL_VARIABLE_TYPES_CALCULATED);
++ newFunction = newFunction.setParameters(lc, newFunction.visitParameters(applyChangesVisitor));
++ return newFunction;
++ }
++
++ private static Expression createIsUndefined(final Expression parent, final Expression lhs, final Expression rhs, final Request request) {
++ if (isUndefinedIdent(lhs) || isUndefinedIdent(rhs)) {
++ return new RuntimeNode(parent, request, lhs, rhs);
++ }
++ return parent;
++ }
++
++ private static boolean isUndefinedIdent(final Expression expr) {
++ return expr instanceof IdentNode && "undefined".equals(((IdentNode)expr).getName());
++ }
++
++ private boolean identIsDeadAndHasNoLiveConversions(final IdentNode identNode) {
++ final LocalVariableConversion conv = localVariableConversions.get(identNode);
++ return conv == null || !conv.isLive();
++ }
++
++ private void onAssignment(final IdentNode identNode, final Expression rhs) {
++ onAssignment(identNode, toLvarType(getType(rhs)));
++ }
++
++ private void onAssignment(final IdentNode identNode, final LvarType type) {
++ final Symbol symbol = identNode.getSymbol();
++ assert symbol != null : identNode.getName();
++ if(!symbol.isBytecodeLocal()) {
++ return;
++ }
++ assert type != null;
++ final LvarType finalType;
++ if(type == LvarType.UNDEFINED && getLocalVariableType(symbol) != LvarType.UNDEFINED) {
++ // Explicit assignment of a known undefined local variable to a local variable that is not undefined will
++ // materialize that undefined in the assignment target. Note that assigning known undefined to known
++ // undefined will *not* initialize the variable, e.g. "var x; var y = x;" compiles to no-op.
++ finalType = LvarType.OBJECT;
++ symbol.setFlag(Symbol.HAS_OBJECT_VALUE);
++ } else {
++ finalType = type;
++ }
++ setType(symbol, finalType);
++ // Explicit assignment of an undefined value. Make sure the variable can store an object
++ // TODO: if we communicated the fact to codegen with a flag on the IdentNode that the value was already
++ // undefined before the assignment, we could just ignore it. In general, we could ignore an assignment if we
++ // know that the value assigned is the same as the current value of the variable, but we'd need constant
++ // propagation for that.
++ setIdentifierLvarType(identNode, finalType);
++ // For purposes of type calculation, we consider an assignment to a local variable to be followed by
++ // the catch nodes of the current (if any) try block. This will effectively enforce that narrower
++ // assignments to a local variable in a try block will also have to store a widened value as well. Code
++ // within the try block will be able to keep loading the narrower value, but after the try block only
++ // the widest value will remain live.
++ // Rationale for this is that if there's an use for that variable in any of the catch blocks, or
++ // following the catch blocks, they must use the widest type.
++ // Example:
++ /*
++ Originally:
++ ===========
++ var x;
++ try {
++ x = 1; <-- stores into int slot for x
++ f(x); <-- loads the int slot for x
++ x = 3.14 <-- stores into the double slot for x
++ f(x); <-- loads the double slot for x
++ x = 1; <-- stores into int slot for x
++ f(x); <-- loads the int slot for x
++ } finally {
++ f(x); <-- loads the double slot for x, but can be reached by a path where x is int, so we need
++ to go back and ensure that double values are also always stored along with int
++ values.
++ }
++
++ After correction:
++ =================
++
++ var x;
++ try {
++ x = 1; <-- stores into both int and double slots for x
++ f(x); <-- loads the int slot for x
++ x = 3.14 <-- stores into the double slot for x
++ f(x); <-- loads the double slot for x
++ x = 1; <-- stores into both int and double slots for x
++ f(x); <-- loads the int slot for x
++ } finally {
++ f(x); <-- loads the double slot for x
++ }
++ */
++ jumpToCatchBlock(identNode);
++ }
++
++ private void onSelfAssignment(final IdentNode identNode, final Expression assignment, final LvarType typeOnLoad) {
++ final Symbol symbol = identNode.getSymbol();
++ assert symbol != null : identNode.getName();
++ if(!symbol.isBytecodeLocal()) {
++ return;
++ }
++ final LvarType type = toLvarType(getType(assignment, symbol, typeOnLoad.type));
++ // Self-assignment never produce either a boolean or undefined
++ assert type != null && type != LvarType.UNDEFINED && type != LvarType.BOOLEAN;
++ setType(symbol, type);
++ jumpToCatchBlock(identNode);
++ }
++
++ private void resetJoinPoint(final Label label) {
++ jumpTargets.remove(label);
++ }
++
++ private void setCompilerConstantAsObject(final FunctionNode functionNode, final CompilerConstants cc) {
++ final Symbol symbol = getCompilerConstantSymbol(functionNode, cc);
++ setType(symbol, LvarType.OBJECT);
++ // never mark compiler constants as dead
++ symbolIsUsed(symbol);
++ }
++
++ private static Symbol getCompilerConstantSymbol(final FunctionNode functionNode, final CompilerConstants cc) {
++ return functionNode.getBody().getExistingSymbol(cc.symbolName());
++ }
++
++ private void setConversion(final JoinPredecessor node, final Map<Symbol, LvarType> branchLvarTypes, final Map<Symbol, LvarType> joinLvarTypes) {
++ if(node == null) {
++ return;
++ }
++ if(branchLvarTypes.isEmpty() || joinLvarTypes.isEmpty()) {
++ localVariableConversions.remove(node);
++ }
++
++ LocalVariableConversion conversion = null;
++ if(node instanceof IdentNode) {
++ // conversions on variable assignment in try block are special cases, as they only apply to the variable
++ // being assigned and all other conversions should be ignored.
++ final Symbol symbol = ((IdentNode)node).getSymbol();
++ conversion = createConversion(symbol, branchLvarTypes.get(symbol), joinLvarTypes, null);
++ } else {
++ for(final Map.Entry<Symbol, LvarType> entry: branchLvarTypes.entrySet()) {
++ final Symbol symbol = entry.getKey();
++ final LvarType branchLvarType = entry.getValue();
++ conversion = createConversion(symbol, branchLvarType, joinLvarTypes, conversion);
++ }
++ }
++ if(conversion != null) {
++ localVariableConversions.put(node, conversion);
++ } else {
++ localVariableConversions.remove(node);
++ }
++ }
++
++ private void setIdentifierLvarType(final IdentNode identNode, final LvarType type) {
++ assert type != null;
++ identifierLvarTypes.put(identNode, type);
++ }
++
++ /**
++ * Marks a local variable as having a specific type from this point onward. Invoked by stores to local variables.
++ * @param symbol the symbol representing the variable
++ * @param type the type
++ */
++ @SuppressWarnings("unused")
++ private void setType(final Symbol symbol, final LvarType type) {
++ if(getLocalVariableTypeOrNull(symbol) == type) {
++ return;
++ }
++ assert symbol.hasSlot();
++ assert !symbol.isGlobal();
++ localVariableTypes = localVariableTypes.isEmpty() ? new IdentityHashMap<Symbol, LvarType>() : cloneMap(localVariableTypes);
++ localVariableTypes.put(symbol, type);
++ }
++
++ /**
++ * Set a flag in the symbol marking it as needing to be able to store a value of a particular type. Every symbol for
++ * a local variable will be assigned between 1 and 6 local variable slots for storing all types it is known to need
++ * to store.
++ * @param symbol the symbol
++ */
++ private void symbolIsUsed(final Symbol symbol) {
++ symbolIsUsed(symbol, getLocalVariableType(symbol));
++ }
++
++ /**
++ * Gets the type of the expression, dependent on the current types of the local variables.
++ *
++ * @param expr the expression
++ * @return the current type of the expression dependent on the current types of the local variables.
++ */
++ private Type getType(final Expression expr) {
++ return expr.getType(getSymbolToType());
++ }
++
++ /**
++ * Returns a function object from symbols to their types, used by the expressions to evaluate their type.
++ * {@link BinaryNode} specifically uses identity of the function to cache type calculations. This method makes
++ * sure to return the same function object while the local variable types don't change, and create a new function
++ * object if the local variable types have been changed.
++ * @return a function object representing a mapping from symbols to their types.
++ */
++ private Function<Symbol, Type> getSymbolToType() {
++ if(symbolToType.isStale()) {
++ symbolToType = new SymbolToType();
++ }
++ return symbolToType;
++ }
++
++ private class SymbolToType implements Function<Symbol, Type> {
++ private final Object boundTypes = localVariableTypes;
++ @Override
++ public Type apply(final Symbol t) {
++ return getLocalVariableType(t).type;
++ }
++
++ boolean isStale() {
++ return boundTypes != localVariableTypes;
++ }
++ }
++
++ /**
++ * Gets the type of the expression, dependent on the current types of the local variables and a single overridden
++ * symbol type. Used by type calculation on compound operators to ensure the type of the LHS at the time it was
++ * loaded (which can potentially be different after RHS evaluation, e.g. "var x; x += x = 0;") is preserved for
++ * the calculation.
++ *
++ * @param expr the expression
++ * @param overriddenSymbol the overridden symbol
++ * @param overriddenType the overridden type
++ * @return the current type of the expression dependent on the current types of the local variables and the single
++ * potentially overridden type.
++ */
++ private Type getType(final Expression expr, final Symbol overriddenSymbol, final Type overriddenType) {
++ return expr.getType(getSymbolToType(overriddenSymbol, overriddenType));
++ }
++
++ private Function<Symbol, Type> getSymbolToType(final Symbol overriddenSymbol, final Type overriddenType) {
++ return getLocalVariableType(overriddenSymbol).type == overriddenType ? getSymbolToType() :
++ new SymbolToTypeOverride(overriddenSymbol, overriddenType);
++ }
++
++ private class SymbolToTypeOverride implements Function<Symbol, Type> {
++ private final Function<Symbol, Type> originalSymbolToType = getSymbolToType();
++ private final Symbol overriddenSymbol;
++ private final Type overriddenType;
++
++ SymbolToTypeOverride(final Symbol overriddenSymbol, final Type overriddenType) {
++ this.overriddenSymbol = overriddenSymbol;
++ this.overriddenType = overriddenType;
++ }
++
++ @Override
++ public Type apply(final Symbol symbol) {
++ return symbol == overriddenSymbol ? overriddenType : originalSymbolToType.apply(symbol);
++ }
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/codegen/Lower.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/Lower.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,12 +27,15 @@
+
+ import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.RETURN;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
++import static jdk.nashorn.internal.ir.Expression.isAlwaysTrue;
+
+ import java.util.ArrayList;
+ import java.util.Arrays;
++import java.util.Collections;
+ import java.util.List;
+ import java.util.ListIterator;
++import java.util.regex.Pattern;
++import jdk.nashorn.internal.ir.AccessNode;
+ import jdk.nashorn.internal.ir.BaseNode;
+ import jdk.nashorn.internal.ir.BinaryNode;
+ import jdk.nashorn.internal.ir.Block;
+@@ -40,6 +43,7 @@
+ import jdk.nashorn.internal.ir.BlockStatement;
+ import jdk.nashorn.internal.ir.BreakNode;
+ import jdk.nashorn.internal.ir.CallNode;
++import jdk.nashorn.internal.ir.CaseNode;
+ import jdk.nashorn.internal.ir.CatchNode;
+ import jdk.nashorn.internal.ir.ContinueNode;
+ import jdk.nashorn.internal.ir.EmptyNode;
+@@ -50,12 +54,15 @@
+ import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
+ import jdk.nashorn.internal.ir.IdentNode;
+ import jdk.nashorn.internal.ir.IfNode;
++import jdk.nashorn.internal.ir.IndexNode;
++import jdk.nashorn.internal.ir.JumpStatement;
+ import jdk.nashorn.internal.ir.LabelNode;
+ import jdk.nashorn.internal.ir.LexicalContext;
+ import jdk.nashorn.internal.ir.LiteralNode;
+ import jdk.nashorn.internal.ir.LoopNode;
+ import jdk.nashorn.internal.ir.Node;
+ import jdk.nashorn.internal.ir.ReturnNode;
++import jdk.nashorn.internal.ir.RuntimeNode;
+ import jdk.nashorn.internal.ir.Statement;
+ import jdk.nashorn.internal.ir.SwitchNode;
+ import jdk.nashorn.internal.ir.Symbol;
+@@ -68,10 +75,12 @@
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+ import jdk.nashorn.internal.parser.Token;
+ import jdk.nashorn.internal.parser.TokenType;
+-import jdk.nashorn.internal.runtime.CodeInstaller;
+-import jdk.nashorn.internal.runtime.DebugLogger;
+-import jdk.nashorn.internal.runtime.ScriptRuntime;
++import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.Source;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
+
+ /**
+ * Lower to more primitive operations. After lowering, an AST still has no symbols
+@@ -82,18 +91,19 @@
+ * harder and context dependent to do any code copying after symbols have been
+ * finalized.
+ */
++@Logger(name="lower")
++final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Loggable {
+
+-final class Lower extends NodeOperatorVisitor<BlockLexicalContext> {
++ private final DebugLogger log;
+
+- private static final DebugLogger LOG = new DebugLogger("lower");
+-
+- // needed only to get unique eval id
+- private final CodeInstaller<?> installer;
++ // Conservative pattern to test if element names consist of characters valid for identifiers.
++ // This matches any non-zero length alphanumeric string including _ and $ and not starting with a digit.
++ private static Pattern SAFE_PROPERTY_NAME = Pattern.compile("[a-zA-Z_$][\\w$]*");
+
+ /**
+ * Constructor.
+ */
+- Lower(final CodeInstaller<?> installer) {
++ Lower(final Compiler compiler) {
+ super(new BlockLexicalContext() {
+
+ @Override
+@@ -136,40 +146,18 @@
+ return block.setIsTerminal(this, false);
+ }
+ });
+- this.installer = installer;
++
++ this.log = initLogger(compiler.getContext());
+ }
+
+ @Override
+- public boolean enterBlock(final Block block) {
+- final FunctionNode function = lc.getCurrentFunction();
+- if (lc.isFunctionBody() && function.isProgram() && !function.hasDeclaredFunctions()) {
+- new ExpressionStatement(function.getLineNumber(), block.getToken(), block.getFinish(), LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED)).accept(this);
+- }
+- return true;
++ public DebugLogger getLogger() {
++ return log;
+ }
+
+ @Override
+- public Node leaveBlock(final Block block) {
+- //now we have committed the entire statement list to the block, but we need to truncate
+- //whatever is after the last terminal. block append won't append past it
+-
+-
+- if (lc.isFunctionBody()) {
+- final FunctionNode currentFunction = lc.getCurrentFunction();
+- final boolean isProgram = currentFunction.isProgram();
+- final Statement last = lc.getLastStatement();
+- final ReturnNode returnNode = new ReturnNode(
+- last == null ? currentFunction.getLineNumber() : last.getLineNumber(), //TODO?
+- currentFunction.getToken(),
+- currentFunction.getFinish(),
+- isProgram ?
+- compilerConstant(RETURN) :
+- LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED));
+-
+- returnNode.accept(this);
+- }
+-
+- return block;
++ public DebugLogger initLogger(final Context context) {
++ return context.getLogger(this.getClass());
+ }
+
+ @Override
+@@ -200,6 +188,28 @@
+ }
+
+ @Override
++ public Node leaveIndexNode(final IndexNode indexNode) {
++ final String name = getConstantPropertyName(indexNode.getIndex());
++ if (name != null) {
++ // If index node is a constant property name convert index node to access node.
++ assert Token.descType(indexNode.getToken()) == TokenType.LBRACKET;
++ return new AccessNode(indexNode.getToken(), indexNode.getFinish(), indexNode.getBase(), name);
++ }
++ return super.leaveIndexNode(indexNode);
++ }
++
++ // If expression is a primitive literal that is not an array index and does return its string value. Else return null.
++ private static String getConstantPropertyName(final Expression expression) {
++ if (expression instanceof LiteralNode.PrimitiveLiteralNode) {
++ final Object value = ((LiteralNode) expression).getValue();
++ if (value instanceof String && SAFE_PROPERTY_NAME.matcher((String) value).matches()) {
++ return (String) value;
++ }
++ }
++ return null;
++ }
++
++ @Override
+ public Node leaveExpressionStatement(final ExpressionStatement expressionStatement) {
+ final Expression expr = expressionStatement.getExpression();
+ ExpressionStatement node = expressionStatement;
+@@ -222,7 +232,7 @@
+ }
+
+ @Override
+- public Node leaveBlockStatement(BlockStatement blockStatement) {
++ public Node leaveBlockStatement(final BlockStatement blockStatement) {
+ return addStatement(blockStatement);
+ }
+
+@@ -230,22 +240,24 @@
+ public Node leaveForNode(final ForNode forNode) {
+ ForNode newForNode = forNode;
+
+- final Node test = forNode.getTest();
+- if (!forNode.isForIn() && conservativeAlwaysTrue(test)) {
++ final Expression test = forNode.getTest();
++ if (!forNode.isForIn() && isAlwaysTrue(test)) {
+ newForNode = forNode.setTest(lc, null);
+ }
+
+- return addStatement(checkEscape(newForNode));
+- }
+-
+- @Override
+- public boolean enterFunctionNode(final FunctionNode functionNode) {
+- return !functionNode.isLazy();
++ newForNode = checkEscape(newForNode);
++ if(newForNode.isForIn()) {
++ // Wrap it in a block so its internally created iterator is restricted in scope
++ addStatementEnclosedInBlock(newForNode);
++ } else {
++ addStatement(newForNode);
++ }
++ return newForNode;
+ }
+
+ @Override
+ public Node leaveFunctionNode(final FunctionNode functionNode) {
+- LOG.info("END FunctionNode: ", functionNode.getName());
++ log.info("END FunctionNode: ", functionNode.getName());
+ return functionNode.setState(lc, CompilationState.LOWERED);
+ }
+
+@@ -255,6 +267,16 @@
+ }
+
+ @Override
++ public Node leaveIN(final BinaryNode binaryNode) {
++ return new RuntimeNode(binaryNode);
++ }
++
++ @Override
++ public Node leaveINSTANCEOF(final BinaryNode binaryNode) {
++ return new RuntimeNode(binaryNode);
++ }
++
++ @Override
+ public Node leaveLabelNode(final LabelNode labelNode) {
+ return addStatement(labelNode);
+ }
+@@ -265,16 +287,35 @@
+ return returnNode;
+ }
+
++ @Override
++ public Node leaveCaseNode(final CaseNode caseNode) {
++ // Try to represent the case test as an integer
++ final Node test = caseNode.getTest();
++ if (test instanceof LiteralNode) {
++ final LiteralNode<?> lit = (LiteralNode<?>)test;
++ if (lit.isNumeric() && !(lit.getValue() instanceof Integer)) {
++ if (JSType.isRepresentableAsInt(lit.getNumber())) {
++ return caseNode.setTest((Expression)LiteralNode.newInstance(lit, lit.getInt32()).accept(this));
++ }
++ }
++ }
++ return caseNode;
++ }
+
+ @Override
+ public Node leaveSwitchNode(final SwitchNode switchNode) {
+- return addStatement(switchNode);
++ if(!switchNode.isUniqueInteger()) {
++ // Wrap it in a block so its internally created tag is restricted in scope
++ addStatementEnclosedInBlock(switchNode);
++ } else {
++ addStatement(switchNode);
++ }
++ return switchNode;
+ }
+
+ @Override
+ public Node leaveThrowNode(final ThrowNode throwNode) {
+- addStatement(throwNode); //ThrowNodes are always terminal, marked as such in constructor
+- return throwNode;
++ return addStatement(throwNode); //ThrowNodes are always terminal, marked as such in constructor
+ }
+
+ private static Node ensureUniqueNamesIn(final Node node) {
+@@ -308,12 +349,12 @@
+ final long token = tryNode.getToken();
+ final int finish = tryNode.getFinish();
+
+- final IdentNode exception = new IdentNode(token, finish, lc.getCurrentFunction().uniqueName("catch_all"));
++ final IdentNode exception = new IdentNode(token, finish, lc.getCurrentFunction().uniqueName(CompilerConstants.EXCEPTION_PREFIX.symbolName()));
+
+- final Block catchBody = new Block(token, finish, new ThrowNode(lineNumber, token, finish, new IdentNode(exception), ThrowNode.IS_SYNTHETIC_RETHROW));
++ final Block catchBody = new Block(token, finish, new ThrowNode(lineNumber, token, finish, new IdentNode(exception), true));
+ assert catchBody.isTerminal(); //ends with throw, so terminal
+
+- final CatchNode catchAllNode = new CatchNode(lineNumber, token, finish, new IdentNode(exception), null, catchBody, CatchNode.IS_SYNTHETIC_RETHROW);
++ final CatchNode catchAllNode = new CatchNode(lineNumber, token, finish, new IdentNode(exception), null, catchBody, true);
+ final Block catchAllBlock = new Block(token, finish, catchAllNode);
+
+ //catchallblock -> catchallnode (catchnode) -> exception -> throw
+@@ -369,12 +410,16 @@
+
+ @Override
+ public Node leaveBreakNode(final BreakNode breakNode) {
+- return copy(breakNode, (Node)Lower.this.lc.getBreakable(breakNode.getLabel()));
++ return leaveJumpStatement(breakNode);
+ }
+
+ @Override
+ public Node leaveContinueNode(final ContinueNode continueNode) {
+- return copy(continueNode, Lower.this.lc.getContinueTo(continueNode.getLabel()));
++ return leaveJumpStatement(continueNode);
++ }
++
++ private Node leaveJumpStatement(final JumpStatement jump) {
++ return copy(jump, (Node)jump.getTarget(Lower.this.lc));
+ }
+
+ @Override
+@@ -425,7 +470,7 @@
+ final Block finallyBody = tryNode.getFinallyBody();
+
+ if (finallyBody == null) {
+- return addStatement(tryNode);
++ return addStatement(ensureUnconditionalCatch(tryNode));
+ }
+
+ /*
+@@ -468,7 +513,7 @@
+ if (tryNode.getCatchBlocks().isEmpty()) {
+ newTryNode = tryNode.setFinallyBody(null);
+ } else {
+- Block outerBody = new Block(tryNode.getToken(), tryNode.getFinish(), tryNode.setFinallyBody(null));
++ final Block outerBody = new Block(tryNode.getToken(), tryNode.getFinish(), ensureUnconditionalCatch(tryNode.setFinallyBody(null)));
+ newTryNode = tryNode.setBody(outerBody).setCatchBlocks(null);
+ }
+
+@@ -481,6 +526,18 @@
+ return spliceFinally(newTryNode, rethrows, finallyBody);
+ }
+
++ private TryNode ensureUnconditionalCatch(final TryNode tryNode) {
++ final List<CatchNode> catches = tryNode.getCatches();
++ if(catches == null || catches.isEmpty() || catches.get(catches.size() - 1).getExceptionCondition() == null) {
++ return tryNode;
++ }
++ // If the last catch block is conditional, add an unconditional rethrow block
++ final List<Block> newCatchBlocks = new ArrayList<>(tryNode.getCatchBlocks());
++
++ newCatchBlocks.add(catchAllBlock(tryNode));
++ return tryNode.setCatchBlocks(newCatchBlocks);
++ }
++
+ @Override
+ public Node leaveVarNode(final VarNode varNode) {
+ addStatement(varNode);
+@@ -492,12 +549,12 @@
+
+ @Override
+ public Node leaveWhileNode(final WhileNode whileNode) {
+- final Node test = whileNode.getTest();
++ final Expression test = whileNode.getTest();
+ final Block body = whileNode.getBody();
+
+- if (conservativeAlwaysTrue(test)) {
++ if (isAlwaysTrue(test)) {
+ //turn it into a for node without a test.
+- final ForNode forNode = (ForNode)new ForNode(whileNode.getLineNumber(), whileNode.getToken(), whileNode.getFinish(), null, null, body, null, ForNode.IS_FOR).accept(this);
++ final ForNode forNode = (ForNode)new ForNode(whileNode.getLineNumber(), whileNode.getToken(), whileNode.getFinish(), body, 0).accept(this);
+ lc.replace(whileNode, forNode);
+ return forNode;
+ }
+@@ -535,16 +592,13 @@
+ private String evalLocation(final IdentNode node) {
+ final Source source = lc.getCurrentFunction().getSource();
+ final int pos = node.position();
+- // Code installer is null when running with --compile-only, use 0 as id in that case
+- final long id = installer == null ? 0 : installer.getUniqueEvalId();
+ return new StringBuilder().
+ append(source.getName()).
+ append('#').
+ append(source.getLine(pos)).
+ append(':').
+ append(source.getColumn(pos)).
+- append("<eval>@").
+- append(id).
++ append("<eval>").
+ toString();
+ }
+
+@@ -571,23 +625,17 @@
+
+ // 'eval' call with at least one argument
+ if (args.size() >= 1 && EVAL.symbolName().equals(callee.getName())) {
+- final FunctionNode currentFunction = lc.getCurrentFunction();
+- return callNode.setEvalArgs(
+- new CallNode.EvalArgs(
+- (Expression)ensureUniqueNamesIn(args.get(0)).accept(this),
+- compilerConstant(THIS),
+- evalLocation(callee),
+- currentFunction.isStrict()));
++ final List<Expression> evalArgs = new ArrayList<>(args.size());
++ for(final Expression arg: args) {
++ evalArgs.add((Expression)ensureUniqueNamesIn(arg).accept(this));
++ }
++ return callNode.setEvalArgs(new CallNode.EvalArgs(evalArgs, evalLocation(callee)));
+ }
+ }
+
+ return callNode;
+ }
+
+- private static boolean conservativeAlwaysTrue(final Node node) {
+- return node == null || ((node instanceof LiteralNode) && Boolean.TRUE.equals(((LiteralNode<?>)node).getValue()));
+- }
+-
+ /**
+ * Helper that given a loop body makes sure that it is not terminal if it
+ * has a continue that leads to the loop header or to outer loops' loop
+@@ -610,7 +658,7 @@
+ @Override
+ public Node leaveContinueNode(final ContinueNode node) {
+ // all inner loops have been popped.
+- if (lex.contains(lex.getContinueTo(node.getLabel()))) {
++ if (lex.contains(node.getTarget(lex))) {
+ escapes.add(node);
+ }
+ return node;
+@@ -620,10 +668,11 @@
+ return !escapes.isEmpty();
+ }
+
+- private LoopNode checkEscape(final LoopNode loopNode) {
++ @SuppressWarnings("unchecked")
++ private <T extends LoopNode> T checkEscape(final T loopNode) {
+ final boolean escapes = controlFlowEscapes(lc, loopNode.getBody());
+ if (escapes) {
+- return loopNode.
++ return (T)loopNode.
+ setBody(lc, loopNode.getBody().setIsTerminal(lc, false)).
+ setControlFlowEscapes(lc, escapes);
+ }
+@@ -636,6 +685,14 @@
+ return statement;
+ }
+
++ private void addStatementEnclosedInBlock(final Statement stmt) {
++ BlockStatement b = BlockStatement.createReplacement(stmt, Collections.<Statement>singletonList(stmt));
++ if(stmt.isTerminal()) {
++ b = b.setBlock(b.getBlock().setIsTerminal(null, true));
++ }
++ addStatement(b);
++ }
++
+ /**
+ * An internal expression has a symbol that is tagged internal. Check if
+ * this is such a node
+@@ -644,7 +701,10 @@
+ * @return true if internal, false otherwise
+ */
+ private static boolean isInternalExpression(final Expression expression) {
+- final Symbol symbol = expression.getSymbol();
++ if (!(expression instanceof IdentNode)) {
++ return false;
++ }
++ final Symbol symbol = ((IdentNode)expression).getSymbol();
+ return symbol != null && symbol.isInternal();
+ }
+
+@@ -656,8 +716,7 @@
+ * @return true if an assignment to eval result, false otherwise
+ */
+ private static boolean isEvalResultAssignment(final Node expression) {
+- Node e = expression;
+- assert e.tokenType() != TokenType.DISCARD; //there are no discards this early anymore
++ final Node e = expression;
+ if (e instanceof BinaryNode) {
+ final Node lhs = ((BinaryNode)e).lhs();
+ if (lhs instanceof IdentNode) {
+@@ -666,5 +725,4 @@
+ }
+ return false;
+ }
+-
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -34,52 +34,58 @@
+ import jdk.nashorn.internal.runtime.AccessorProperty;
+ import jdk.nashorn.internal.runtime.Property;
+ import jdk.nashorn.internal.runtime.PropertyMap;
++import jdk.nashorn.internal.runtime.ScriptObject;
++import jdk.nashorn.internal.runtime.SpillProperty;
+
+ /**
+ * Class that creates PropertyMap sent to script object constructors.
++ * @param <T> value type for tuples, e.g. Symbol
+ */
+-public class MapCreator {
++public class MapCreator<T> {
+ /** Object structure for objects associated with this map */
+ private final Class<?> structure;
+
+ /** key set for object map */
+- final List<String> keys;
+-
+- /** corresponding symbol set for object map */
+- final List<Symbol> symbols;
++ private final List<MapTuple<T>> tuples;
+
+ /**
+ * Constructor
+ *
+ * @param structure structure to generate map for (a JO subclass)
+- * @param keys list of keys for map
+- * @param symbols list of symbols for map
++ * @param tuples list of tuples for map
+ */
+- MapCreator(final Class<?> structure, final List<String> keys, final List<Symbol> symbols) {
++ MapCreator(final Class<? extends ScriptObject> structure, final List<MapTuple<T>> tuples) {
+ this.structure = structure;
+- this.keys = keys;
+- this.symbols = symbols;
++ this.tuples = tuples;
+ }
+
+ /**
+ * Constructs a property map based on a set of fields.
+ *
+- * @param hasArguments does the created object have an "arguments" property
++ * @param hasArguments does the created object have an "arguments" property
+ * @param fieldCount Number of fields in use.
+- * @param fieldMaximum Number of fields available.
+- *
++ * @param fieldMaximum Number of fields available.
++ * @param evalCode is this property map created for 'eval' code?
+ * @return New map populated with accessor properties.
+ */
+- PropertyMap makeFieldMap(final boolean hasArguments, final int fieldCount, final int fieldMaximum) {
++ PropertyMap makeFieldMap(final boolean hasArguments, final int fieldCount, final int fieldMaximum, final boolean evalCode) {
+ final List<Property> properties = new ArrayList<>();
+- assert keys != null;
++ assert tuples != null;
+
+- for (int i = 0, length = keys.size(); i < length; i++) {
+- final String key = keys.get(i);
+- final Symbol symbol = symbols.get(i);
++ for (final MapTuple<T> tuple : tuples) {
++ final String key = tuple.key;
++ final Symbol symbol = tuple.symbol;
++ final Class<?> initialType = tuple.getValueType();
+
+ if (symbol != null && !isValidArrayIndex(getArrayIndex(key))) {
+- properties.add(new AccessorProperty(key, getPropertyFlags(symbol, hasArguments), structure, symbol.getFieldIndex()));
++ final int flags = getPropertyFlags(symbol, hasArguments, evalCode);
++ final Property property = new AccessorProperty(
++ key,
++ flags,
++ structure,
++ symbol.getFieldIndex(),
++ initialType);
++ properties.add(property);
+ }
+ }
+
+@@ -89,14 +95,20 @@
+ PropertyMap makeSpillMap(final boolean hasArguments) {
+ final List<Property> properties = new ArrayList<>();
+ int spillIndex = 0;
+- assert keys != null;
++ assert tuples != null;
+
+- for (int i = 0, length = keys.size(); i < length; i++) {
+- final String key = keys.get(i);
+- final Symbol symbol = symbols.get(i);
++ for (final MapTuple<T> tuple : tuples) {
++ final String key = tuple.key;
++ final Symbol symbol = tuple.symbol;
+
++ //TODO initial type is object here no matter what. Is that right?
+ if (symbol != null && !isValidArrayIndex(getArrayIndex(key))) {
+- properties.add(new AccessorProperty(key, getPropertyFlags(symbol, hasArguments), spillIndex++));
++ final int flags = getPropertyFlags(symbol, hasArguments, false);
++ properties.add(
++ new SpillProperty(
++ key,
++ flags,
++ spillIndex++));
+ }
+ }
+
+@@ -111,34 +123,44 @@
+ *
+ * @return flags to use for fields
+ */
+- protected int getPropertyFlags(final Symbol symbol, final boolean hasArguments) {
++ static int getPropertyFlags(final Symbol symbol, final boolean hasArguments, final boolean evalCode) {
+ int flags = 0;
+
+ if (symbol.isParam()) {
+- flags |= Property.IS_ALWAYS_OBJECT | Property.IS_PARAMETER;
++ flags |= Property.IS_PARAMETER;
+ }
+
+ if (hasArguments) {
+- flags |= Property.IS_ALWAYS_OBJECT | Property.HAS_ARGUMENTS;
++ flags |= Property.HAS_ARGUMENTS;
+ }
+
+- if (symbol.isScope()) {
++ // See ECMA 5.1 10.5 Declaration Binding Instantiation.
++ // Step 2 If code is eval code, then let configurableBindings
++ // be true else let configurableBindings be false.
++ // We have to make vars, functions declared in 'eval' code
++ // configurable. But vars, functions from any other code is
++ // not configurable.
++ if (symbol.isScope() && !evalCode) {
+ flags |= Property.NOT_CONFIGURABLE;
+ }
+
+- if (symbol.canBePrimitive()) {
+- flags |= Property.CAN_BE_PRIMITIVE;
+- }
+-
+- if (symbol.canBeUndefined()) {
+- flags |= Property.CAN_BE_UNDEFINED;
+- }
+-
+ if (symbol.isFunctionDeclaration()) {
+ flags |= Property.IS_FUNCTION_DECLARATION;
+ }
+
++ if (symbol.isConst()) {
++ flags |= Property.NOT_WRITABLE;
++ }
++
++ if (symbol.isBlockScoped()) {
++ flags |= Property.IS_LEXICAL_BINDING;
++ }
++
++ // Mark symbol as needing declaration. Access before declaration will throw a ReferenceError.
++ if (symbol.isBlockScoped() && symbol.isScope()) {
++ flags |= Property.NEEDS_DECLARATION;
++ }
++
+ return flags;
+ }
+-
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/MapTuple.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,66 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
++
++import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
++
++import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.ir.Symbol;
++
++/**
++ * A tuple of values used for map creation
++ * @param <T> value type
++ */
++class MapTuple<T> {
++ final String key;
++ final Symbol symbol;
++ final Type type;
++ final T value;
++
++ MapTuple(final String key, final Symbol symbol, final Type type) {
++ this(key, symbol, type, null);
++ }
++
++ MapTuple(final String key, final Symbol symbol, final Type type, final T value) {
++ this.key = key;
++ this.symbol = symbol;
++ this.type = type;
++ this.value = value;
++ }
++
++ public Class<?> getValueType() {
++ return OBJECT_FIELDS_ONLY ? Object.class : null; //until proven otherwise we are undefined, see NASHORN-592 int.class;
++ }
++
++ boolean isPrimitive() {
++ return !OBJECT_FIELDS_ONLY && getValueType().isPrimitive() && getValueType() != boolean.class;
++ }
++
++ @Override
++ public String toString() {
++ return "[key=" + key + ", symbol=" + symbol + ", value=" + value + " (" + (value == null ? "null" : value.getClass().getSimpleName()) +")]";
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -43,6 +43,10 @@
+ import static jdk.internal.org.objectweb.asm.Opcodes.IF_ACMPEQ;
+ import static jdk.internal.org.objectweb.asm.Opcodes.IF_ACMPNE;
+ import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPEQ;
++import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPGE;
++import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPGT;
++import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPLE;
++import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPLT;
+ import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPNE;
+ import static jdk.internal.org.objectweb.asm.Opcodes.INSTANCEOF;
+ import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEINTERFACE;
+@@ -64,11 +68,17 @@
+ import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.staticField;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
++import static jdk.nashorn.internal.codegen.ObjectClassGenerator.PRIMITIVE_FIELD_TYPE;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_OPTIMISTIC;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_PROGRAM_POINT_SHIFT;
+
+ import java.io.PrintStream;
+ import java.lang.reflect.Array;
++import java.util.Collection;
+ import java.util.EnumSet;
++import java.util.IdentityHashMap;
+ import java.util.List;
++import java.util.Map;
+ import jdk.internal.dynalink.support.NameCodec;
+ import jdk.internal.org.objectweb.asm.Handle;
+ import jdk.internal.org.objectweb.asm.MethodVisitor;
+@@ -81,17 +91,25 @@
+ import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.FunctionNode;
+ import jdk.nashorn.internal.ir.IdentNode;
+-import jdk.nashorn.internal.ir.LexicalContext;
++import jdk.nashorn.internal.ir.JoinPredecessor;
+ import jdk.nashorn.internal.ir.LiteralNode;
++import jdk.nashorn.internal.ir.LocalVariableConversion;
+ import jdk.nashorn.internal.ir.RuntimeNode;
+ import jdk.nashorn.internal.ir.Symbol;
++import jdk.nashorn.internal.ir.TryNode;
++import jdk.nashorn.internal.objects.Global;
++import jdk.nashorn.internal.objects.NativeArray;
+ import jdk.nashorn.internal.runtime.ArgumentSetter;
++import jdk.nashorn.internal.runtime.Context;
+ import jdk.nashorn.internal.runtime.Debug;
+-import jdk.nashorn.internal.runtime.DebugLogger;
+ import jdk.nashorn.internal.runtime.JSType;
+-import jdk.nashorn.internal.runtime.ScriptEnvironment;
++import jdk.nashorn.internal.runtime.RewriteException;
++import jdk.nashorn.internal.runtime.Scope;
+ import jdk.nashorn.internal.runtime.ScriptObject;
++import jdk.nashorn.internal.runtime.ScriptRuntime;
++import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
+ import jdk.nashorn.internal.runtime.linker.Bootstrap;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
+ import jdk.nashorn.internal.runtime.options.Options;
+
+ /**
+@@ -111,27 +129,34 @@
+ /** The ASM MethodVisitor we are plugged into */
+ private final MethodVisitor method;
+
+- /** Current type stack for current evaluation */
+- private Label.Stack stack;
+-
+ /** Parent classEmitter representing the class of this method */
+ private final ClassEmitter classEmitter;
+
+ /** FunctionNode representing this method, or null if none exists */
+ protected FunctionNode functionNode;
+
++ /** Current type stack for current evaluation */
++ private Label.Stack stack;
++
+ /** Check whether this emitter ever has a function return point */
+ private boolean hasReturn;
+
+- /** The script environment */
+- private final ScriptEnvironment env;
++ private boolean preventUndefinedLoad;
++
++ /**
++ * Map of live local variable definitions.
++ */
++ private final Map<Symbol, LocalVariableDef> localVariableDefs = new IdentityHashMap<>();
++
++ /** The context */
++ private final Context context;
+
+ /** Threshold in chars for when string constants should be split */
+ static final int LARGE_STRING_THRESHOLD = 32 * 1024;
+
+ /** Debug flag, should we dump all generated bytecode along with stacks? */
+- private static final DebugLogger LOG = new DebugLogger("codegen", "nashorn.codegen.debug");
+- private static final boolean DEBUG = LOG.isEnabled();
++ private final DebugLogger log;
++ private final boolean debug;
+
+ /** dump stack on a particular line, or -1 if disabled */
+ private static final int DEBUG_TRACE_LINE;
+@@ -153,6 +178,9 @@
+ /** Bootstrap for runtime node indy:s */
+ private static final Handle RUNTIMEBOOTSTRAP = new Handle(H_INVOKESTATIC, RuntimeCallSite.BOOTSTRAP.className(), RuntimeCallSite.BOOTSTRAP.name(), RuntimeCallSite.BOOTSTRAP.descriptor());
+
++ /** Bootstrap for array populators */
++ private static final Handle POPULATE_ARRAY_BOOTSTRAP = new Handle(H_INVOKESTATIC, RewriteException.BOOTSTRAP.className(), RewriteException.BOOTSTRAP.name(), RewriteException.BOOTSTRAP.descriptor());
++
+ /**
+ * Constructor - internal use from ClassEmitter only
+ * @see ClassEmitter#method
+@@ -173,11 +201,13 @@
+ * @param functionNode a function node representing this method
+ */
+ MethodEmitter(final ClassEmitter classEmitter, final MethodVisitor method, final FunctionNode functionNode) {
+- this.env = classEmitter.getEnv();
++ this.context = classEmitter.getContext();
+ this.classEmitter = classEmitter;
+ this.method = method;
+ this.functionNode = functionNode;
+ this.stack = null;
++ this.log = context.getLogger(CodeGenerator.class);
++ this.debug = log.isEnabled();
+ }
+
+ /**
+@@ -203,6 +233,14 @@
+ classEmitter.endMethod(this);
+ }
+
++ boolean isReachable() {
++ return stack != null;
++ }
++
++ private void doesNotContinueSequentially() {
++ stack = null;
++ }
++
+ private void newStack() {
+ stack = new Label.Stack();
+ }
+@@ -216,7 +254,7 @@
+ * Push a type to the existing stack
+ * @param type the type
+ */
+- private void pushType(final Type type) {
++ void pushType(final Type type) {
+ if (type != null) {
+ stack.push(type);
+ }
+@@ -230,7 +268,7 @@
+ * @return the type that was retrieved
+ */
+ private Type popType(final Type expected) {
+- final Type type = stack.pop();
++ final Type type = popType();
+ assert type.isObject() && expected.isObject() ||
+ type.isEquivalentTo(expected) : type + " is not compatible with " + expected;
+ return type;
+@@ -246,26 +284,40 @@
+ }
+
+ /**
+- * Pop a type from the existing stack, ensuring that it is numeric,
+- * assert if not
++ * Pop a type from the existing stack, ensuring that it is numeric. Boolean type is popped as int type.
+ *
+ * @return the type
+ */
+ private NumericType popNumeric() {
+- final Type type = stack.pop();
+- assert type.isNumeric() : type + " is not numeric";
++ final Type type = popType();
++ if(type.isBoolean()) {
++ // Booleans are treated as int for purposes of arithmetic operations
++ return Type.INT;
++ }
++ assert type.isNumeric();
+ return (NumericType)type;
+ }
+
+ /**
+ * Pop a type from the existing stack, ensuring that it is an integer type
+- * (integer or long), assert if not
++ * (integer or long). Boolean type is popped as int type.
+ *
+ * @return the type
+ */
++ private BitwiseType popBitwise() {
++ final Type type = popType();
++ if(type == Type.BOOLEAN) {
++ return Type.INT;
++ }
++ return (BitwiseType)type;
++ }
++
+ private BitwiseType popInteger() {
+- final Type type = stack.pop();
+- assert type.isInteger() || type.isLong() : type + " is not an integer or long";
++ final Type type = popType();
++ if(type == Type.BOOLEAN) {
++ return Type.INT;
++ }
++ assert type == Type.INT;
+ return (BitwiseType)type;
+ }
+
+@@ -276,7 +328,7 @@
+ * @return the type
+ */
+ private ArrayType popArray() {
+- final Type type = stack.pop();
++ final Type type = popType();
+ assert type.isArray() : type;
+ return (ArrayType)type;
+ }
+@@ -307,13 +359,14 @@
+ * object type on the stack
+ *
+ * @param classDescriptor class descriptor for the object type
++ * @param type the type of the new object
+ *
+ * @return the method emitter
+ */
+- MethodEmitter _new(final String classDescriptor) {
++ MethodEmitter _new(final String classDescriptor, final Type type) {
+ debug("new", classDescriptor);
+ method.visitTypeInsn(NEW, classDescriptor);
+- pushType(Type.OBJECT);
++ pushType(type);
+ return this;
+ }
+
+@@ -326,7 +379,7 @@
+ * @return the method emitter
+ */
+ MethodEmitter _new(final Class<?> clazz) {
+- return _new(className(clazz));
++ return _new(className(clazz), Type.typeFor(clazz));
+ }
+
+ /**
+@@ -358,25 +411,40 @@
+ debug("dup", depth);
+
+ switch (depth) {
+- case 0:
++ case 0: {
++ final int l0 = stack.getTopLocalLoad();
+ pushType(peekType());
++ stack.markLocalLoad(l0);
+ break;
++ }
+ case 1: {
++ final int l0 = stack.getTopLocalLoad();
+ final Type p0 = popType();
++ final int l1 = stack.getTopLocalLoad();
+ final Type p1 = popType();
+ pushType(p0);
++ stack.markLocalLoad(l0);
+ pushType(p1);
++ stack.markLocalLoad(l1);
+ pushType(p0);
++ stack.markLocalLoad(l0);
+ break;
+ }
+ case 2: {
++ final int l0 = stack.getTopLocalLoad();
+ final Type p0 = popType();
++ final int l1 = stack.getTopLocalLoad();
+ final Type p1 = popType();
++ final int l2 = stack.getTopLocalLoad();
+ final Type p2 = popType();
+ pushType(p0);
++ stack.markLocalLoad(l0);
+ pushType(p2);
++ stack.markLocalLoad(l2);
+ pushType(p1);
++ stack.markLocalLoad(l1);
+ pushType(p0);
++ stack.markLocalLoad(l0);
+ break;
+ }
+ default:
+@@ -398,13 +466,22 @@
+ debug("dup2");
+
+ if (peekType().isCategory2()) {
++ final int l0 = stack.getTopLocalLoad();
+ pushType(peekType());
++ stack.markLocalLoad(l0);
+ } else {
+- final Type type = get2();
+- pushType(type);
+- pushType(type);
+- pushType(type);
+- pushType(type);
++ final int l0 = stack.getTopLocalLoad();
++ final Type p0 = popType();
++ final int l1 = stack.getTopLocalLoad();
++ final Type p1 = popType();
++ pushType(p0);
++ stack.markLocalLoad(l0);
++ pushType(p1);
++ stack.markLocalLoad(l1);
++ pushType(p0);
++ stack.markLocalLoad(l0);
++ pushType(p1);
++ stack.markLocalLoad(l1);
+ }
+ method.visitInsn(DUP2);
+ return this;
+@@ -454,35 +531,42 @@
+ MethodEmitter swap() {
+ debug("swap");
+
++ final int l0 = stack.getTopLocalLoad();
+ final Type p0 = popType();
++ final int l1 = stack.getTopLocalLoad();
+ final Type p1 = popType();
+ p0.swap(method, p1);
+
+ pushType(p0);
++ stack.markLocalLoad(l0);
+ pushType(p1);
+- debug("after ", p0, p1);
++ stack.markLocalLoad(l1);
+ return this;
+ }
+
++ void pack() {
++ final Type type = peekType();
++ if (type.isInteger()) {
++ convert(PRIMITIVE_FIELD_TYPE);
++ } else if (type.isLong()) {
++ //nop
++ } else if (type.isNumber()) {
++ invokestatic("java/lang/Double", "doubleToRawLongBits", "(D)J");
++ } else {
++ assert false : type + " cannot be packed!";
++ }
++ //all others are nops, objects aren't packed
++ }
++
+ /**
+- * Add a local variable. This is a nop if the symbol has no slot
+- *
+- * @param symbol symbol for the local variable
+- * @param start start of scope
+- * @param end end of scope
++ * Initializes a bytecode method parameter
++ * @param symbol the symbol for the parameter
++ * @param type the type of the parameter
++ * @param start the label for the start of the method
+ */
+- void localVariable(final Symbol symbol, final Label start, final Label end) {
+- if (!symbol.hasSlot()) {
+- return;
+- }
+-
+- String name = symbol.getName();
+-
+- if (name.equals(THIS.symbolName())) {
+- name = THIS_DEBUGGER.symbolName();
+- }
+-
+- method.visitLocalVariable(name, symbol.getSymbolType().getDescriptor(), null, start.getLabel(), end.getLabel(), symbol.getSlot());
++ void initializeMethodParameter(final Symbol symbol, final Type type, final Label start) {
++ assert symbol.isBytecodeLocal();
++ localVariableDefs.put(symbol, new LocalVariableDef(start.getLabel(), type));
+ }
+
+ /**
+@@ -550,8 +634,8 @@
+ */
+ MethodEmitter shr() {
+ debug("shr");
+- popType(Type.INT);
+- pushType(popInteger().shr(method));
++ popInteger();
++ pushType(popBitwise().shr(method));
+ return this;
+ }
+
+@@ -563,21 +647,21 @@
+ */
+ MethodEmitter shl() {
+ debug("shl");
+- popType(Type.INT);
+- pushType(popInteger().shl(method));
++ popInteger();
++ pushType(popBitwise().shl(method));
+ return this;
+ }
+
+ /**
+- * Pops two integer types from the stack, performs a bitwise arithetic shift right and pushes
++ * Pops two integer types from the stack, performs a bitwise arithmetic shift right and pushes
+ * the result. The shift count, the first element, must be INT.
+ *
+ * @return the method emitter
+ */
+ MethodEmitter sar() {
+ debug("sar");
+- popType(Type.INT);
+- pushType(popInteger().sar(method));
++ popInteger();
++ pushType(popBitwise().sar(method));
+ return this;
+ }
+
+@@ -586,9 +670,9 @@
+ *
+ * @return the method emitter
+ */
+- MethodEmitter neg() {
++ MethodEmitter neg(final int programPoint) {
+ debug("neg");
+- pushType(popNumeric().neg(method));
++ pushType(popNumeric().neg(method, programPoint));
+ return this;
+ }
+
+@@ -599,20 +683,49 @@
+ * @param recovery label pointing to start of catch block
+ */
+ void _catch(final Label recovery) {
+- stack.clear();
+- stack.push(Type.OBJECT);
++ // While in JVM a catch block can be reached through normal control flow, our code generator never does this,
++ // so we might as well presume there's no stack on entry.
++ assert stack == null;
++ recovery.onCatch();
+ label(recovery);
++ beginCatchBlock();
+ }
+
+ /**
++ * Add any number of labels for the start of a catch block and push the exception to the
++ * stack
++ *
++ * @param recoveries labels pointing to start of catch block
++ */
++ void _catch(final Collection<Label> recoveries) {
++ assert stack == null;
++ for(final Label l: recoveries) {
++ label(l);
++ }
++ beginCatchBlock();
++ }
++
++ private void beginCatchBlock() {
++ // It can happen that the catch label wasn't marked as reachable. They are marked as reachable if there's an
++ // assignment in the try block, but it's possible that there was none.
++ if(!isReachable()) {
++ newStack();
++ }
++ pushType(Type.typeFor(Throwable.class));
++ }
++ /**
+ * Start a try/catch block.
+ *
+ * @param entry start label for try
+ * @param exit end label for try
+ * @param recovery start label for catch
+ * @param typeDescriptor type descriptor for exception
++ * @param isOptimismHandler true if this is a hander for {@code UnwarrantedOptimismException}. Normally joining on a
++ * catch handler kills temporary variables, but optimism handlers are an exception, as they need to capture
++ * temporaries as well, so they must remain live.
+ */
+- void _try(final Label entry, final Label exit, final Label recovery, final String typeDescriptor) {
++ private void _try(final Label entry, final Label exit, final Label recovery, final String typeDescriptor, final boolean isOptimismHandler) {
++ recovery.joinFromTry(entry.getStack(), isOptimismHandler);
+ method.visitTryCatchBlock(entry.getLabel(), exit.getLabel(), recovery.getLabel(), typeDescriptor);
+ }
+
+@@ -625,7 +738,7 @@
+ * @param clazz exception class
+ */
+ void _try(final Label entry, final Label exit, final Label recovery, final Class<?> clazz) {
+- method.visitTryCatchBlock(entry.getLabel(), exit.getLabel(), recovery.getLabel(), CompilerConstants.className(clazz));
++ _try(entry, exit, recovery, CompilerConstants.className(clazz), clazz == UnwarrantedOptimismException.class);
+ }
+
+ /**
+@@ -636,9 +749,12 @@
+ * @param recovery start label for catch
+ */
+ void _try(final Label entry, final Label exit, final Label recovery) {
+- _try(entry, exit, recovery, (String)null);
++ _try(entry, exit, recovery, (String)null, false);
+ }
+
++ void markLabelAsOptimisticCatchHandler(final Label label, final int liveLocalCount) {
++ label.markAsOptimisticCatchHandler(stack, liveLocalCount);
++ }
+
+ /**
+ * Load the constants array
+@@ -665,6 +781,12 @@
+ return this;
+ }
+
++ MethodEmitter loadForcedInitializer(final Type type) {
++ debug("load forced initializer ", type);
++ pushType(type.loadForcedInitializer(method));
++ return this;
++ }
++
+ /**
+ * Push the empty value for the given type, i.e. EMPTY.
+ *
+@@ -805,22 +927,36 @@
+ }
+
+ /**
+- * Push a local variable to the stack. If the symbol representing
+- * the local variable doesn't have a slot, this is a NOP
++ * Pushes the value of an identifier to the stack. If the identifier does not represent a local variable or a
++ * parameter, this will be a no-op.
+ *
+- * @param symbol the symbol representing the local variable.
++ * @param ident the identifier for the variable being loaded.
+ *
+ * @return the method emitter
+ */
+- MethodEmitter load(final Symbol symbol) {
++ MethodEmitter load(final IdentNode ident) {
++ return load(ident.getSymbol(), ident.getType());
++ }
++
++ /**
++ * Pushes the value of the symbol to the stack with the specified type. No type conversion is being performed, and
++ * the type is only being used if the symbol addresses a local variable slot. The value of the symbol is loaded if
++ * it addresses a local variable slot, or it is a parameter (in which case it can also be loaded from a vararg array
++ * or the arguments object). If it is neither, the operation is a no-op.
++ *
++ * @param symbol the symbol addressing the value being loaded
++ * @param type the presumed type of the value when it is loaded from a local variable slot
++ * @return the method emitter
++ */
++ MethodEmitter load(final Symbol symbol, final Type type) {
+ assert symbol != null;
+ if (symbol.hasSlot()) {
+- final int slot = symbol.getSlot();
+- debug("load symbol", symbol.getName(), " slot=", slot);
+- final Type type = symbol.getSymbolType().load(method, slot);
+- pushType(type == Type.OBJECT && symbol.isThis() ? Type.THIS : type);
++ final int slot = symbol.getSlot(type);
++ debug("load symbol", symbol.getName(), " slot=", slot, "type=", type);
++ load(type, slot);
++ // _try(new Label("dummy"), new Label("dummy2"), recovery);
++ // method.visitTryCatchBlock(new Label(), arg1, arg2, arg3);
+ } else if (symbol.isParam()) {
+- assert !symbol.isScope();
+ assert functionNode.isVarArg() : "Non-vararg functions have slotted parameters";
+ final int index = symbol.getFieldIndex();
+ if (functionNode.needsArguments()) {
+@@ -841,7 +977,7 @@
+ }
+
+ /**
+- * Push a local variable to the stack, given an explicit bytecode slot
++ * Push a local variable to the stack, given an explicit bytecode slot.
+ * This is used e.g. for stub generation where we know where items like
+ * "this" and "scope" reside.
+ *
+@@ -853,7 +989,11 @@
+ MethodEmitter load(final Type type, final int slot) {
+ debug("explicit load", type, slot);
+ final Type loadType = type.load(method, slot);
++ assert loadType != null;
+ pushType(loadType == Type.OBJECT && isThisSlot(slot) ? Type.THIS : loadType);
++ assert !preventUndefinedLoad || (slot < stack.localVariableTypes.size() && stack.localVariableTypes.get(slot) != Type.UNKNOWN)
++ : "Attempted load of uninitialized slot " + slot + " (as type " + type + ")";
++ stack.markLocalLoad(slot);
+ return this;
+ }
+
+@@ -861,7 +1001,7 @@
+ if (functionNode == null) {
+ return slot == CompilerConstants.JAVA_THIS.slot();
+ }
+- final int thisSlot = compilerConstant(THIS).getSlot();
++ final int thisSlot = getCompilerConstantSymbol(THIS).getSlot(Type.OBJECT);
+ assert !functionNode.needsCallee() || thisSlot == 1; // needsCallee -> thisSlot == 1
+ assert functionNode.needsCallee() || thisSlot == 0; // !needsCallee -> thisSlot == 0
+ return slot == thisSlot;
+@@ -883,7 +1023,7 @@
+ return this;
+ }
+
+- private Symbol compilerConstant(final CompilerConstants cc) {
++ private Symbol getCompilerConstantSymbol(final CompilerConstants cc) {
+ return functionNode.getBody().getExistingSymbol(cc.symbolName());
+ }
+
+@@ -893,22 +1033,46 @@
+ * @return if this method has a slot allocated for the scope variable.
+ */
+ boolean hasScope() {
+- return compilerConstant(SCOPE).hasSlot();
++ return getCompilerConstantSymbol(SCOPE).hasSlot();
+ }
+
+ MethodEmitter loadCompilerConstant(final CompilerConstants cc) {
+- final Symbol symbol = compilerConstant(cc);
++ return loadCompilerConstant(cc, null);
++ }
++
++ MethodEmitter loadCompilerConstant(final CompilerConstants cc, final Type type) {
+ if (cc == SCOPE && peekType() == Type.SCOPE) {
+ dup();
+ return this;
+ }
+- return load(symbol);
++ return load(getCompilerConstantSymbol(cc), type != null ? type : getCompilerConstantType(cc));
++ }
++
++ MethodEmitter loadScope() {
++ return loadCompilerConstant(SCOPE).checkcast(Scope.class);
++ }
++
++ MethodEmitter setSplitState(final int state) {
++ return loadScope().load(state).invoke(Scope.SET_SPLIT_STATE);
+ }
+
+ void storeCompilerConstant(final CompilerConstants cc) {
+- final Symbol symbol = compilerConstant(cc);
++ storeCompilerConstant(cc, null);
++ }
++
++ void storeCompilerConstant(final CompilerConstants cc, final Type type) {
++ final Symbol symbol = getCompilerConstantSymbol(cc);
++ if(!symbol.hasSlot()) {
++ return;
++ }
+ debug("store compiler constant ", symbol);
+- store(symbol);
++ store(symbol, type != null ? type : getCompilerConstantType(cc));
++ }
++
++ private static Type getCompilerConstantType(final CompilerConstants cc) {
++ final Class<?> constantType = cc.type();
++ assert constantType != null;
++ return Type.typeFor(constantType);
+ }
+
+ /**
+@@ -940,48 +1104,215 @@
+
+ /**
+ * Pop a value from the stack and store it in a local variable represented
+- * by the given symbol. If the symbol has no slot, this is a NOP
++ * by the given identifier. If the symbol has no slot, this is a NOP
+ *
+- * @param symbol symbol to store stack to
++ * @param ident identifier to store stack to
+ */
+- void store(final Symbol symbol) {
++ void store(final IdentNode ident) {
++ final Type type = ident.getType();
++ final Symbol symbol = ident.getSymbol();
++ if(type == Type.UNDEFINED) {
++ assert peekType() == Type.UNDEFINED;
++ store(symbol, Type.OBJECT);
++ } else {
++ store(symbol, type);
++ }
++ }
++
++ /**
++ * Represents a definition of a local variable with a type. Used for local variable table building.
++ */
++ private static class LocalVariableDef {
++ // The start label from where this definition lives.
++ private final jdk.internal.org.objectweb.asm.Label label;
++ // The currently live type of the local variable.
++ private final Type type;
++
++ LocalVariableDef(final jdk.internal.org.objectweb.asm.Label label, final Type type) {
++ this.label = label;
++ this.type = type;
++ }
++
++ }
++
++ void closeLocalVariable(final Symbol symbol, final Label label) {
++ final LocalVariableDef def = localVariableDefs.get(symbol);
++ if(def != null) {
++ endLocalValueDef(symbol, def, label.getLabel());
++ }
++ if(isReachable()) {
++ markDeadLocalVariable(symbol);
++ }
++ }
++
++ void markDeadLocalVariable(final Symbol symbol) {
++ if(!symbol.isDead()) {
++ markDeadSlots(symbol.getFirstSlot(), symbol.slotCount());
++ }
++ }
++
++ void markDeadSlots(final int firstSlot, final int slotCount) {
++ stack.markDeadLocalVariables(firstSlot, slotCount);
++ }
++
++ private void endLocalValueDef(final Symbol symbol, final LocalVariableDef def, final jdk.internal.org.objectweb.asm.Label label) {
++ String name = symbol.getName();
++ if (name.equals(THIS.symbolName())) {
++ name = THIS_DEBUGGER.symbolName();
++ }
++ method.visitLocalVariable(name, def.type.getDescriptor(), null, def.label, label, symbol.getSlot(def.type));
++ }
++
++ void store(final Symbol symbol, final Type type) {
++ store(symbol, type, true);
++ }
++
++ /**
++ * Pop a value from the stack and store it in a variable denoted by the given symbol. The variable should be either
++ * a local variable, or a function parameter (and not a scoped variable). For local variables, this method will also
++ * do the bookeeping of the local variable table as well as mark values in all alternative slots for the symbol as
++ * dead. In this regard it differs from {@link #storeHidden(Type, int)}.
++ *
++ * @param symbol the symbol to store into.
++ * @param type the type to store
++ * @param onlySymbolLiveValue if true, this is the sole live value for the symbol. If false, currently live values should
++ * be kept live.
++ */
++ void store(final Symbol symbol, final Type type, final boolean onlySymbolLiveValue) {
+ assert symbol != null : "No symbol to store";
+ if (symbol.hasSlot()) {
+- final int slot = symbol.getSlot();
+- debug("store symbol", symbol.getName(), " slot=", slot);
+- popType(symbol.getSymbolType()).store(method, slot);
++ final boolean isLiveType = symbol.hasSlotFor(type);
++ final LocalVariableDef existingDef = localVariableDefs.get(symbol);
++ if(existingDef == null || existingDef.type != type) {
++ final jdk.internal.org.objectweb.asm.Label here = new jdk.internal.org.objectweb.asm.Label();
++ if(isLiveType) {
++ final LocalVariableDef newDef = new LocalVariableDef(here, type);
++ localVariableDefs.put(symbol, newDef);
++ }
++ method.visitLabel(here);
++ if(existingDef != null) {
++ endLocalValueDef(symbol, existingDef, here);
++ }
++ }
++ if(isLiveType) {
++ final int slot = symbol.getSlot(type);
++ debug("store symbol", symbol.getName(), " type=", type, " slot=", slot);
++ storeHidden(type, slot, onlySymbolLiveValue);
++ } else {
++ if(onlySymbolLiveValue) {
++ markDeadLocalVariable(symbol);
++ }
++ debug("dead store symbol ", symbol.getName(), " type=", type);
++ pop();
++ }
+ } else if (symbol.isParam()) {
+ assert !symbol.isScope();
+ assert functionNode.isVarArg() : "Non-vararg functions have slotted parameters";
+ final int index = symbol.getFieldIndex();
+ if (functionNode.needsArguments()) {
++ convert(Type.OBJECT);
+ debug("store symbol", symbol.getName(), " arguments index=", index);
+ loadCompilerConstant(ARGUMENTS);
+ load(index);
+ ArgumentSetter.SET_ARGUMENT.invoke(this);
+ } else {
++ convert(Type.OBJECT);
+ // varargs without arguments object - just do array store to __varargs__
+ debug("store symbol", symbol.getName(), " array index=", index);
+ loadCompilerConstant(VARARGS);
+ load(index);
+ ArgumentSetter.SET_ARRAY_ELEMENT.invoke(this);
+ }
++ } else {
++ debug("dead store symbol ", symbol.getName(), " type=", type);
++ pop();
+ }
+ }
+
+ /**
+- * Pop a value from the stack and store it in a given local variable
+- * slot.
++ * Pop a value from the stack and store it in a local variable slot. Note that in contrast with
++ * {@link #store(Symbol, Type)}, this method does not adjust the local variable table, nor marks slots for
++ * alternative value types for the symbol as being dead. For that reason, this method is usually not called
++ * directly. Notable exceptions are temporary internal locals (e.g. quick store, last-catch-condition, etc.) that
++ * are not desired to show up in the local variable table.
+ *
+ * @param type the type to pop
+ * @param slot the slot
+ */
+- void store(final Type type, final int slot) {
++ void storeHidden(final Type type, final int slot) {
++ storeHidden(type, slot, true);
++ }
++
++ void storeHidden(final Type type, final int slot, final boolean onlyLiveSymbolValue) {
++ explicitStore(type, slot);
++ stack.onLocalStore(type, slot, onlyLiveSymbolValue);
++ }
++
++ void storeTemp(final Type type, final int slot) {
++ explicitStore(type, slot);
++ defineTemporaryLocalVariable(slot, slot + type.getSlots());
++ onLocalStore(type, slot);
++ }
++
++ void onLocalStore(final Type type, final int slot) {
++ stack.onLocalStore(type, slot, true);
++ }
++
++ private void explicitStore(final Type type, final int slot) {
++ assert slot != -1;
++ debug("explicit store", type, slot);
+ popType(type);
+ type.store(method, slot);
+ }
+
+ /**
++ * Marks a range of slots as belonging to a defined local variable. The slots will start out with no live value
++ * in them.
++ * @param fromSlot first slot, inclusive.
++ * @param toSlot last slot, exclusive.
++ */
++ void defineBlockLocalVariable(final int fromSlot, final int toSlot) {
++ stack.defineBlockLocalVariable(fromSlot, toSlot);
++ }
++
++ /**
++ * Marks a range of slots as belonging to a defined temporary local variable. The slots will start out with no
++ * live value in them.
++ * @param fromSlot first slot, inclusive.
++ * @param toSlot last slot, exclusive.
++ */
++ void defineTemporaryLocalVariable(final int fromSlot, final int toSlot) {
++ stack.defineTemporaryLocalVariable(fromSlot, toSlot);
++ }
++
++ /**
++ * Defines a new temporary local variable and returns its allocated index.
++ * @param width the required width (in slots) for the new variable.
++ * @return the bytecode slot index where the newly allocated local begins.
++ */
++ int defineTemporaryLocalVariable(final int width) {
++ return stack.defineTemporaryLocalVariable(width);
++ }
++
++ void undefineLocalVariables(final int fromSlot, final boolean canTruncateSymbol) {
++ if(isReachable()) {
++ stack.undefineLocalVariables(fromSlot, canTruncateSymbol);
++ }
++ }
++
++ List<Type> getLocalVariableTypes() {
++ return stack.localVariableTypes;
++ }
++
++ List<Type> getWidestLiveLocals(final List<Type> localTypes) {
++ return stack.getWidestLiveLocals(localTypes);
++ }
++
++ String markSymbolBoundariesInLvarTypesDescriptor(final String lvarDescriptor) {
++ return stack.markSymbolBoundariesInLvarTypesDescriptor(lvarDescriptor);
++ }
++
++ /**
+ * Increment/Decrement a local integer by the given value.
+ *
+ * @param slot the int slot
+@@ -999,9 +1330,9 @@
+ public void athrow() {
+ debug("athrow");
+ final Type receiver = popType(Type.OBJECT);
+- assert receiver.isObject();
++ assert Throwable.class.isAssignableFrom(receiver.getTypeClass()) : receiver.getTypeClass();
+ method.visitInsn(ATHROW);
+- stack = null;
++ doesNotContinueSequentially();
+ }
+
+ /**
+@@ -1130,11 +1461,7 @@
+ popType(Type.OBJECT);
+ }
+
+- if (opcode == INVOKEINTERFACE) {
+- method.visitMethodInsn(opcode, className, methodName, methodDescriptor, true);
+- } else {
+- method.visitMethodInsn(opcode, className, methodName, methodDescriptor, false);
+- }
++ method.visitMethodInsn(opcode, className, methodName, methodDescriptor, opcode == INVOKEINTERFACE);
+
+ if (returnType != null) {
+ pushType(returnType);
+@@ -1197,7 +1524,7 @@
+ *
+ * @return the method emitter
+ */
+- MethodEmitter invokeStatic(final String className, final String methodName, final String methodDescriptor, final Type returnType) {
++ MethodEmitter invokestatic(final String className, final String methodName, final String methodDescriptor, final Type returnType) {
+ invokestatic(className, methodName, methodDescriptor);
+ popType();
+ pushType(returnType);
+@@ -1235,8 +1562,9 @@
+ */
+ void lookupswitch(final Label defaultLabel, final int[] values, final Label... table) {//Collection<Label> table) {
+ debug("lookupswitch", peekType());
+- popType(Type.INT);
++ adjustStackForSwitch(defaultLabel, table);
+ method.visitLookupSwitchInsn(defaultLabel.getLabel(), values, getLabels(table));
++ doesNotContinueSequentially();
+ }
+
+ /**
+@@ -1248,8 +1576,17 @@
+ */
+ void tableswitch(final int lo, final int hi, final Label defaultLabel, final Label... table) {
+ debug("tableswitch", peekType());
++ adjustStackForSwitch(defaultLabel, table);
++ method.visitTableSwitchInsn(lo, hi, defaultLabel.getLabel(), getLabels(table));
++ doesNotContinueSequentially();
++ }
++
++ private void adjustStackForSwitch(final Label defaultLabel, final Label... table) {
+ popType(Type.INT);
+- method.visitTableSwitchInsn(lo, hi, defaultLabel.getLabel(), getLabels(table));
++ joinTo(defaultLabel);
++ for(final Label label: table) {
++ joinTo(label);
++ }
+ }
+
+ /**
+@@ -1305,7 +1642,7 @@
+ convert(type);
+ }
+ popType(type)._return(method);
+- stack = null;
++ doesNotContinueSequentially();
+ }
+
+ /**
+@@ -1322,18 +1659,7 @@
+ debug("return [void]");
+ assert stack.isEmpty() : stack;
+ method.visitInsn(RETURN);
+- stack = null;
+- }
+-
+- /**
+- * Goto, possibly when splitting is taking place. If
+- * a splitNode exists, we need to handle the case that the
+- * jump target is another method
+- *
+- * @param label destination label
+- */
+- void splitAwareGoto(final LexicalContext lc, final Label label) {
+- _goto(label);
++ doesNotContinueSequentially();
+ }
+
+ /**
+@@ -1359,7 +1685,7 @@
+ assert peekType().isInteger() || peekType().isBoolean() || peekType().isObject() : "expecting integer type or object for jump, but found " + peekType();
+ popType();
+ }
+- mergeStackTo(label);
++ joinTo(label);
+ method.visitJumpInsn(opcode, label.getLabel());
+ }
+
+@@ -1454,6 +1780,16 @@
+ }
+
+ /**
++ * Generate an if_icmplt
++ *
++ * @param label label to true case
++ */
++ void if_icmplt(final Label label) {
++ debug("if_icmplt", label);
++ jump(IF_ICMPLT, label, 2);
++ }
++
++ /**
+ * Generate an ifle
+ *
+ * @param label label to true case
+@@ -1464,6 +1800,16 @@
+ }
+
+ /**
++ * Generate an if_icmple
++ *
++ * @param label label to true case
++ */
++ void if_icmple(final Label label) {
++ debug("if_icmple", label);
++ jump(IF_ICMPLE, label, 2);
++ }
++
++ /**
+ * Generate an ifgt
+ *
+ * @param label label to true case
+@@ -1474,6 +1820,16 @@
+ }
+
+ /**
++ * Generate an if_icmpgt
++ *
++ * @param label label to true case
++ */
++ void if_icmpgt(final Label label) {
++ debug("if_icmpgt", label);
++ jump(IF_ICMPGT, label, 2);
++ }
++
++ /**
+ * Generate an ifge
+ *
+ * @param label label to true case
+@@ -1484,24 +1840,58 @@
+ }
+
+ /**
++ * Generate an if_icmpge
++ *
++ * @param label label to true case
++ */
++ void if_icmpge(final Label label) {
++ debug("if_icmpge", label);
++ jump(IF_ICMPGE, label, 2);
++ }
++
++ /**
+ * Unconditional jump to a label
+ *
+ * @param label destination label
+ */
+ void _goto(final Label label) {
+- //debug("goto", label);
++ debug("goto", label);
+ jump(GOTO, label, 0);
+- stack = null; //whoever reaches the point after us provides the stack, because we don't
++ doesNotContinueSequentially(); //whoever reaches the point after us provides the stack, because we don't
+ }
+
+ /**
+- * Examine two stacks and make sure they are of the same size and their
+- * contents are equivalent to each other
+- * @param s0 first stack
+- * @param s1 second stack
++ * Unconditional jump to the start label of a loop. It differs from ordinary {@link #_goto(Label)} in that it will
++ * preserve the current label stack, as the next instruction after the goto is loop body that the loop will come
++ * back to. Also used to jump at the start label of the continuation handler, as it behaves much like a loop test in
++ * the sense that after it is evaluated, it also jumps backwards.
+ *
+- * @return true if stacks are equivalent, false otherwise
++ * @param loopStart start label of a loop
+ */
++ void gotoLoopStart(final Label loopStart) {
++ debug("goto (loop)", loopStart);
++ jump(GOTO, loopStart, 0);
++ }
++
++ /**
++ * Unconditional jump without any control flow and data flow testing. You should not normally use this method when
++ * generating code, except if you're very sure that you know what you're doing. Normally only used for the
++ * admittedly torturous control flow of continuation handler plumbing.
++ * @param target the target of the jump
++ */
++ void uncheckedGoto(final Label target) {
++ method.visitJumpInsn(GOTO, target.getLabel());
++ }
++
++ /**
++ * Potential transfer of control to a catch block.
++ *
++ * @param catchLabel destination catch label
++ */
++ void canThrow(final Label catchLabel) {
++ catchLabel.joinFromTry(stack, false);
++ }
++
+ /**
+ * A join in control flow - helper function that makes sure all entry stacks
+ * discovered for the join point so far are equivalent
+@@ -1511,45 +1901,46 @@
+ *
+ * @param label label
+ */
+- private void mergeStackTo(final Label label) {
+- //sometimes we can do a merge stack without having a stack - i.e. when jumping ahead to dead code
+- //see NASHORN-73. So far we had been saved by the line number nodes. This should have been fixed
+- //by Lower removing everything after an unconditionally executed terminating statement OR a break
+- //or continue in a block. Previously code left over after breaks and continues was still there
+- //and caused bytecode to be generated - which crashed on stack not being there, as the merge
+- //was not in fact preceeded by a visit. Furthermore, this led to ASM putting out its NOP NOP NOP
+- //ATHROW sequences instead of no code being generated at all. This should now be fixed.
+- assert stack != null : label + " entered with no stack. deadcode that remains?";
+-
+- final Label.Stack labelStack = label.getStack();
+- if (labelStack == null) {
+- label.setStack(stack.copy());
+- return;
+- }
+- assert stack.isEquivalentTo(labelStack) : "stacks " + stack + " is not equivalent with " + labelStack + " at join point";
++ private void joinTo(final Label label) {
++ assert isReachable();
++ label.joinFrom(stack);
+ }
+
+ /**
+ * Register a new label, enter it here.
++ * @param label
++ */
++ void label(final Label label) {
++ breakLabel(label, -1);
++ }
++
++ /**
++ * Register a new break target label, enter it here.
+ *
+ * @param label the label
++ * @param liveLocals the number of live locals at this label
+ */
+- void label(final Label label) {
+- /*
+- * If stack == null, this means that we came here not through a fallthrough.
+- * E.g. a label after an athrow. Then we create a new stack if one doesn't exist
+- * for this location already.
+- */
+- if (stack == null) {
+- stack = label.getStack();
+- if (stack == null) {
+- newStack();
+- }
++ void breakLabel(final Label label, final int liveLocals) {
++ if (!isReachable()) {
++ // If we emit a label, and the label's stack is null, it must not be reachable.
++ assert (label.getStack() == null) != label.isReachable();
++ } else {
++ joinTo(label);
++ }
++ // Use label's stack as we might have no stack.
++ final Label.Stack labelStack = label.getStack();
++ stack = labelStack == null ? null : labelStack.clone();
++ if(stack != null && label.isBreakTarget() && liveLocals != -1) {
++ // This has to be done because we might not have another frame to provide us with its firstTemp if the label
++ // is only reachable through a break or continue statement; also in this case, the frame can actually
++ // give us a higher number of live locals, e.g. if it comes from a catch. Typical example:
++ // for(;;) { try{ throw 0; } catch(e) { break; } }.
++ // Since the for loop can only be exited through the break in the catch block, it'll bring with it the
++ // "e" as a live local, and we need to trim it off here.
++ assert stack.firstTemp >= liveLocals;
++ stack.firstTemp = liveLocals;
+ }
+ debug_label(label);
+-
+- mergeStackTo(label); //we have to merge our stack to whatever is in the label
+-
+ method.visitLabel(label.getLabel());
+ }
+
+@@ -1561,13 +1952,32 @@
+ * @return the method emitter
+ */
+ MethodEmitter convert(final Type to) {
+- final Type type = peekType().convert(method, to);
++ final Type from = peekType();
++ final Type type = from.convert(method, to);
+ if (type != null) {
+- if (!peekType().isEquivalentTo(to)) {
+- debug("convert", peekType(), "->", to);
++ if (!from.isEquivalentTo(to)) {
++ debug("convert", from, "->", to);
+ }
+- popType();
+- pushType(type);
++ if (type != from) {
++ final int l0 = stack.getTopLocalLoad();
++ popType();
++ pushType(type);
++ // NOTE: conversions from a primitive type are considered to preserve the "load" property of the value
++ // on the stack. Otherwise we could introduce temporary locals in a deoptimized rest-of (e.g. doing an
++ // "i < x.length" where "i" is int and ".length" gets deoptimized to long would end up converting i to
++ // long with "ILOAD i; I2L; LSTORE tmp; LLOAD tmp;"). Such additional temporary would cause an error
++ // when restoring the state of the function for rest-of execution, as the not-yet deoptimized variant
++ // would have the (now invalidated) assumption that "x.length" is an int, so it wouldn't have the I2L,
++ // and therefore neither the subsequent LSTORE tmp; LLOAD tmp;. By making sure conversions from a
++ // primitive type don't erase the "load" information, we don't introduce temporaries in the deoptimized
++ // rest-of that didn't exist in the more optimistic version that triggered the deoptimization.
++ // NOTE: as a more general observation, we could theoretically track the operations required to
++ // reproduce any stack value as long as they are all local loads, constant loads, and stack operations.
++ // We won't go there in the current system
++ if(!from.isObject()) {
++ stack.markLocalLoad(l0);
++ }
++ }
+ }
+ return this;
+ }
+@@ -1590,8 +2000,8 @@
+ * @return common type
+ */
+ private BitwiseType get2i() {
+- final BitwiseType p0 = popInteger();
+- final BitwiseType p1 = popInteger();
++ final BitwiseType p0 = popBitwise();
++ final BitwiseType p1 = popBitwise();
+ assert p0.isEquivalentTo(p1) : "expecting equivalent types on stack but got " + p0 + " and " + p1;
+ return p0;
+ }
+@@ -1613,9 +2023,9 @@
+ *
+ * @return the method emitter
+ */
+- MethodEmitter add() {
++ MethodEmitter add(final int programPoint) {
+ debug("add");
+- pushType(get2().add(method));
++ pushType(get2().add(method, programPoint));
+ return this;
+ }
+
+@@ -1624,9 +2034,9 @@
+ *
+ * @return the method emitter
+ */
+- MethodEmitter sub() {
++ MethodEmitter sub(final int programPoint) {
+ debug("sub");
+- pushType(get2n().sub(method));
++ pushType(get2n().sub(method, programPoint));
+ return this;
+ }
+
+@@ -1635,9 +2045,9 @@
+ *
+ * @return the method emitter
+ */
+- MethodEmitter mul() {
++ MethodEmitter mul(final int programPoint) {
+ debug("mul ");
+- pushType(get2n().mul(method));
++ pushType(get2n().mul(method, programPoint));
+ return this;
+ }
+
+@@ -1646,9 +2056,9 @@
+ *
+ * @return the method emitter
+ */
+- MethodEmitter div() {
++ MethodEmitter div(final int programPoint) {
+ debug("div");
+- pushType(get2n().div(method));
++ pushType(get2n().div(method, programPoint));
+ return this;
+ }
+
+@@ -1657,9 +2067,9 @@
+ *
+ * @return the method emitter
+ */
+- MethodEmitter rem() {
++ MethodEmitter rem(final int programPoint) {
+ debug("rem");
+- pushType(get2n().rem(method));
++ pushType(get2n().rem(method, programPoint));
+ return this;
+ }
+
+@@ -1670,13 +2080,23 @@
+ * @return array of Types
+ */
+ protected Type[] getTypesFromStack(final int count) {
+- final Type[] types = new Type[count];
+- int pos = 0;
+- for (int i = count - 1; i >= 0; i--) {
+- types[i] = stack.peek(pos++);
+- }
++ return stack.getTopTypes(count);
++ }
+
+- return types;
++ int[] getLocalLoadsOnStack(final int from, final int to) {
++ return stack.getLocalLoads(from, to);
++ }
++
++ int getStackSize() {
++ return stack.size();
++ }
++
++ int getFirstTemp() {
++ return stack.firstTemp;
++ }
++
++ int getUsedSlotsWithLiveTemporaries() {
++ return stack.getUsedSlotsWithLiveTemporaries();
+ }
+
+ /**
+@@ -1693,7 +2113,14 @@
+
+ int pos = 0;
+ for (int i = argCount - 1; i >= 0; i--) {
+- paramTypes[i] = stack.peek(pos++);
++ Type pt = stack.peek(pos++);
++ // "erase" specific ScriptObject subtype info - except for NativeArray.
++ // NativeArray is used for array/List/Deque conversion for Java calls.
++ if (ScriptObject.class.isAssignableFrom(pt.getTypeClass()) &&
++ !NativeArray.class.isAssignableFrom(pt.getTypeClass())) {
++ pt = Type.SCRIPT_OBJECT;
++ }
++ paramTypes[i] = pt;
+ }
+ final String descriptor = Type.getMethodDescriptor(returnType, paramTypes);
+ for (int i = 0; i < argCount; i++) {
+@@ -1703,6 +2130,20 @@
+ return descriptor;
+ }
+
++ MethodEmitter invalidateSpecialName(final String name) {
++ switch (name) {
++ case "apply":
++ case "call":
++ debug("invalidate_name", "name=", name);
++ load("Function");
++ invoke(ScriptRuntime.INVALIDATE_RESERVED_BUILTIN_NAME);
++ break;
++ default:
++ break;
++ }
++ return this;
++ }
++
+ /**
+ * Generate a dynamic new
+ *
+@@ -1712,6 +2153,7 @@
+ * @return the method emitter
+ */
+ MethodEmitter dynamicNew(final int argCount, final int flags) {
++ assert !isOptimistic(flags);
+ debug("dynamic_new", "argcount=", argCount);
+ final String signature = getDynamicSignature(Type.OBJECT, argCount);
+ method.visitInvokeDynamicInsn("dyn:new", signature, LINKERBOOTSTRAP, flags);
+@@ -1738,6 +2180,14 @@
+ return this;
+ }
+
++ MethodEmitter dynamicArrayPopulatorCall(final int argCount, final int startIndex) {
++ debug("populate_array", "args=", argCount, "startIndex=", startIndex);
++ final String signature = getDynamicSignature(Type.OBJECT_ARRAY, argCount);
++ method.visitInvokeDynamicInsn("populateArray", signature, POPULATE_ARRAY_BOOTSTRAP, startIndex);
++ pushType(Type.OBJECT_ARRAY);
++ return this;
++ }
++
+ /**
+ * Generate a dynamic call for a runtime node
+ *
+@@ -1764,11 +2214,11 @@
+ * @param name name of property
+ * @param flags call site flags
+ * @param isMethod should it prefer retrieving methods
+- *
++ * @param isIndex is this an index operation?
+ * @return the method emitter
+ */
+- MethodEmitter dynamicGet(final Type valueType, final String name, final int flags, final boolean isMethod) {
+- debug("dynamic_get", name, valueType);
++ MethodEmitter dynamicGet(final Type valueType, final String name, final int flags, final boolean isMethod, final boolean isIndex) {
++ debug("dynamic_get", name, valueType, getProgramPoint(flags));
+
+ Type type = valueType;
+ if (type.isObject() || type.isBoolean()) {
+@@ -1776,11 +2226,10 @@
+ }
+
+ popType(Type.SCOPE);
+- method.visitInvokeDynamicInsn((isMethod ? "dyn:getMethod|getProp|getElem:" : "dyn:getProp|getElem|getMethod:") +
+- NameCodec.encode(name), Type.getMethodDescriptor(type, Type.OBJECT), LINKERBOOTSTRAP, flags);
++ method.visitInvokeDynamicInsn(dynGetOperation(isMethod, isIndex) + ':' + NameCodec.encode(name),
++ Type.getMethodDescriptor(type, Type.OBJECT), LINKERBOOTSTRAP, flags);
+
+ pushType(type);
+-
+ convert(valueType); //most probably a nop
+
+ return this;
+@@ -1789,12 +2238,13 @@
+ /**
+ * Generate dynamic setter. Pop receiver and property from stack.
+ *
+- * @param valueType the type of the value to set
+- * @param name name of property
+- * @param flags call site flags
++ * @param name name of property
++ * @param flags call site flags
++ * @param isIndex is this an index operation?
+ */
+- void dynamicSet(final String name, final int flags) {
+- debug("dynamic_set", name, peekType());
++ void dynamicSet(final String name, final int flags, final boolean isIndex) {
++ assert !isOptimistic(flags);
++ debug("dynamic_set", name, peekType());
+
+ Type type = peekType();
+ if (type.isObject() || type.isBoolean()) { //promote strings to objects etc
+@@ -1804,7 +2254,8 @@
+ popType(type);
+ popType(Type.SCOPE);
+
+- method.visitInvokeDynamicInsn("dyn:setProp|setElem:" + NameCodec.encode(name), methodDescriptor(void.class, Object.class, type.getTypeClass()), LINKERBOOTSTRAP, flags);
++ method.visitInvokeDynamicInsn(dynSetOperation(isIndex) + ':' + NameCodec.encode(name),
++ methodDescriptor(void.class, Object.class, type.getTypeClass()), LINKERBOOTSTRAP, flags);
+ }
+
+ /**
+@@ -1818,7 +2269,8 @@
+ * @return the method emitter
+ */
+ MethodEmitter dynamicGetIndex(final Type result, final int flags, final boolean isMethod) {
+- debug("dynamic_get_index", peekType(1), "[", peekType(), "]");
++ assert result.getTypeClass().isPrimitive() || result.getTypeClass() == Object.class;
++ debug("dynamic_get_index", peekType(1), "[", peekType(), "]", getProgramPoint(flags));
+
+ Type resultType = result;
+ if (result.isBoolean()) {
+@@ -1836,8 +2288,7 @@
+
+ final String signature = Type.getMethodDescriptor(resultType, Type.OBJECT /*e.g STRING->OBJECT*/, index);
+
+- method.visitInvokeDynamicInsn(isMethod ? "dyn:getMethod|getElem|getProp" : "dyn:getElem|getProp|getMethod",
+- signature, LINKERBOOTSTRAP, flags);
++ method.visitInvokeDynamicInsn(dynGetOperation(isMethod, true), signature, LINKERBOOTSTRAP, flags);
+ pushType(resultType);
+
+ if (result.isBoolean()) {
+@@ -1847,6 +2298,13 @@
+ return this;
+ }
+
++ private static String getProgramPoint(final int flags) {
++ if((flags & CALLSITE_OPTIMISTIC) == 0) {
++ return "";
++ }
++ return "pp=" + String.valueOf((flags & (-1 << CALLSITE_PROGRAM_POINT_SHIFT)) >> CALLSITE_PROGRAM_POINT_SHIFT);
++ }
++
+ /**
+ * Dynamic setter for indexed structures. Pop value, index and receiver from
+ * stack, generate appropriate signature based on types
+@@ -1854,6 +2312,7 @@
+ * @param flags call site flags for setter
+ */
+ void dynamicSetIndex(final int flags) {
++ assert !isOptimistic(flags);
+ debug("dynamic_set_index", peekType(2), "[", peekType(1), "] =", peekType());
+
+ Type value = peekType();
+@@ -2009,10 +2468,9 @@
+ * Register line number at a label
+ *
+ * @param line line number
+- * @param label label
+ */
+ void lineNumber(final int line) {
+- if (env._debug_lines) {
++ if (context.getEnv()._debug_lines) {
+ debug_label("[LINE]", line);
+ final jdk.internal.org.objectweb.asm.Label l = new jdk.internal.org.objectweb.asm.Label();
+ method.visitLabel(l);
+@@ -2020,6 +2478,56 @@
+ }
+ }
+
++ void beforeJoinPoint(final JoinPredecessor joinPredecessor) {
++ LocalVariableConversion next = joinPredecessor.getLocalVariableConversion();
++ while(next != null) {
++ final Symbol symbol = next.getSymbol();
++ if(next.isLive()) {
++ emitLocalVariableConversion(next, true);
++ } else {
++ markDeadLocalVariable(symbol);
++ }
++ next = next.getNext();
++ }
++ }
++
++ void beforeTry(final TryNode tryNode, final Label recovery) {
++ LocalVariableConversion next = tryNode.getLocalVariableConversion();
++ while(next != null) {
++ if(next.isLive()) {
++ final Type to = emitLocalVariableConversion(next, false);
++ recovery.getStack().onLocalStore(to, next.getSymbol().getSlot(to), true);
++ }
++ next = next.getNext();
++ }
++ }
++
++ private static String dynGetOperation(final boolean isMethod, final boolean isIndex) {
++ if (isMethod) {
++ return isIndex ? "dyn:getMethod|getElem|getProp" : "dyn:getMethod|getProp|getElem";
++ } else {
++ return isIndex ? "dyn:getElem|getProp|getMethod" : "dyn:getProp|getElem|getMethod";
++ }
++ }
++
++ private static String dynSetOperation(final boolean isIndex) {
++ return isIndex ? "dyn:setElem|setProp" : "dyn:setProp|setElem";
++ }
++
++ private Type emitLocalVariableConversion(final LocalVariableConversion conversion, final boolean onlySymbolLiveValue) {
++ final Type from = conversion.getFrom();
++ final Type to = conversion.getTo();
++ final Symbol symbol = conversion.getSymbol();
++ assert symbol.isBytecodeLocal();
++ if(from == Type.UNDEFINED) {
++ loadUndefined(to);
++ } else {
++ load(symbol, from).convert(to);
++ }
++ store(symbol, to, onlySymbolLiveValue);
++ return to;
++ }
++
+ /*
+ * Debugging below
+ */
+@@ -2086,12 +2594,55 @@
+ *
+ * @param args debug information to print
+ */
++ @SuppressWarnings("unused")
+ private void debug(final Object... args) {
+- if (DEBUG) {
++ if (debug) {
+ debug(30, args);
+ }
+ }
+
++ private void debug(final String arg) {
++ if (debug) {
++ debug(30, arg);
++ }
++ }
++
++ private void debug(final Object arg0, final Object arg1) {
++ if (debug) {
++ debug(30, new Object[] { arg0, arg1 });
++ }
++ }
++
++ private void debug(final Object arg0, final Object arg1, final Object arg2) {
++ if (debug) {
++ debug(30, new Object[] { arg0, arg1, arg2 });
++ }
++ }
++
++ private void debug(final Object arg0, final Object arg1, final Object arg2, final Object arg3) {
++ if (debug) {
++ debug(30, new Object[] { arg0, arg1, arg2, arg3 });
++ }
++ }
++
++ private void debug(final Object arg0, final Object arg1, final Object arg2, final Object arg3, final Object arg4) {
++ if (debug) {
++ debug(30, new Object[] { arg0, arg1, arg2, arg3, arg4 });
++ }
++ }
++
++ private void debug(final Object arg0, final Object arg1, final Object arg2, final Object arg3, final Object arg4, final Object arg5) {
++ if (debug) {
++ debug(30, new Object[] { arg0, arg1, arg2, arg3, arg4, arg5 });
++ }
++ }
++
++ private void debug(final Object arg0, final Object arg1, final Object arg2, final Object arg3, final Object arg4, final Object arg5, final Object arg6) {
++ if (debug) {
++ debug(30, new Object[] { arg0, arg1, arg2, arg3, arg4, arg5, arg6 });
++ }
++ }
++
+ /**
+ * Debug function that outputs generated bytecode and stack contents
+ * for a label - indentation is currently the only thing that differs
+@@ -2099,13 +2650,13 @@
+ * @param args debug information to print
+ */
+ private void debug_label(final Object... args) {
+- if (DEBUG) {
++ if (debug) {
+ debug(22, args);
+ }
+ }
+
+ private void debug(final int padConstant, final Object... args) {
+- if (DEBUG) {
++ if (debug) {
+ final StringBuilder sb = new StringBuilder();
+ int pad;
+
+@@ -2118,7 +2669,7 @@
+ pad--;
+ }
+
+- if (stack != null && !stack.isEmpty()) {
++ if (isReachable() && !stack.isEmpty()) {
+ sb.append("{");
+ sb.append(stack.size());
+ sb.append(":");
+@@ -2148,7 +2699,10 @@
+ } else {
+ sb.append(t.getDescriptor());
+ }
+-
++ final int loadIndex = stack.localLoads[stack.sp - 1 - pos];
++ if(loadIndex != Label.Stack.NON_LOAD) {
++ sb.append('(').append(loadIndex).append(')');
++ }
+ if (pos + 1 < stack.size()) {
+ sb.append(' ');
+ }
+@@ -2168,10 +2722,10 @@
+ sb.append(' ');
+ }
+
+- if (env != null) { //early bootstrap code doesn't have inited context yet
+- LOG.info(sb);
++ if (context.getEnv() != null) { //early bootstrap code doesn't have inited context yet
++ log.info(sb);
+ if (DEBUG_TRACE_LINE == linePrefix) {
+- new Throwable().printStackTrace(LOG.getOutputStream());
++ new Throwable().printStackTrace(log.getOutputStream());
+ }
+ }
+ }
+@@ -2189,8 +2743,17 @@
+ return hasReturn;
+ }
+
+- List<Label> getExternalTargets() {
+- return null;
++ /**
++ * Invoke to enforce assertions preventing load from a local variable slot that's known to not have been written to.
++ * Used by CodeGenerator, as it strictly enforces tracking of stores. Simpler uses of MethodEmitter, e.g. those
++ * for creating initializers for structure classes, array getters, etc. don't have strict tracking of stores,
++ * therefore they would fail if they had this assertion turned on.
++ */
++ void setPreventUndefinedLoad() {
++ this.preventUndefinedLoad = true;
+ }
+
++ private static boolean isOptimistic(final int flags) {
++ return (flags & CALLSITE_OPTIMISTIC) != 0;
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/Namespace.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/Namespace.java Wed Feb 04 12:14:47 2015 -0800
+@@ -80,7 +80,6 @@
+ if (counter != null) {
+ final int count = counter + 1;
+ namespaceDirectory.put(base, count);
+-
+ return base + '-' + count;
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -35,12 +35,20 @@
+ import static jdk.nashorn.internal.codegen.CompilerConstants.className;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
+ import static jdk.nashorn.internal.lookup.Lookup.MH;
++import static jdk.nashorn.internal.runtime.JSType.CONVERT_OBJECT;
++import static jdk.nashorn.internal.runtime.JSType.CONVERT_OBJECT_OPTIMISTIC;
++import static jdk.nashorn.internal.runtime.JSType.GET_UNDEFINED;
++import static jdk.nashorn.internal.runtime.JSType.TYPE_DOUBLE_INDEX;
++import static jdk.nashorn.internal.runtime.JSType.TYPE_INT_INDEX;
++import static jdk.nashorn.internal.runtime.JSType.TYPE_LONG_INDEX;
++import static jdk.nashorn.internal.runtime.JSType.TYPE_OBJECT_INDEX;
++import static jdk.nashorn.internal.runtime.JSType.TYPE_UNDEFINED_INDEX;
++import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
+
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+ import java.lang.invoke.MethodType;
+-import java.util.Arrays;
+-import java.util.Collections;
+ import java.util.EnumSet;
+ import java.util.Iterator;
+ import java.util.LinkedList;
+@@ -49,24 +57,35 @@
+ import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.runtime.AccessorProperty;
+ import jdk.nashorn.internal.runtime.Context;
+-import jdk.nashorn.internal.runtime.DebugLogger;
+ import jdk.nashorn.internal.runtime.FunctionScope;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptEnvironment;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+-import jdk.nashorn.internal.runtime.ScriptRuntime;
++import jdk.nashorn.internal.runtime.Undefined;
++import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
+ import jdk.nashorn.internal.runtime.options.Options;
+
+ /**
+ * Generates the ScriptObject subclass structure with fields for a user objects.
+ */
+-public final class ObjectClassGenerator {
++@Logger(name="fields")
++public final class ObjectClassGenerator implements Loggable {
+
+ /**
+- * Marker for scope parameters.
++ * Type guard to make sure we don't unnecessarily explode field storages. Rather unbox e.g.
++ * a java.lang.Number than blow up the field. Gradually, optimistic types should create almost
++ * no boxed types
+ */
+- static final String SCOPE_MARKER = "P";
++ private static final MethodHandle IS_TYPE_GUARD = findOwnMH("isType", boolean.class, Class.class, Object.class);
++
++ /**
++ * Marker for scope parameters
++ */
++ private static final String SCOPE_MARKER = "P";
+
+ /**
+ * Minimum number of extra fields in an object.
+@@ -77,29 +96,26 @@
+ * Debug field logger
+ * Should we print debugging information for fields when they are generated and getters/setters are called?
+ */
+- public static final DebugLogger LOG = new DebugLogger("fields", "nashorn.fields.debug");
+-
+- /**
+- * is field debugging enabled. Several modules in codegen and properties use this, hence
+- * public access.
+- */
+- public static final boolean DEBUG_FIELDS = LOG.isEnabled();
++ private final DebugLogger log;
+
+ /**
+ * Should the runtime only use java.lang.Object slots for fields? If this is false, the representation
+ * will be a primitive 64-bit long value used for all primitives and a java.lang.Object for references.
+ * This introduces a larger number of method handles in the system, as we need to have different getters
+- * and setters for the different fields. Currently this introduces significant overhead in Hotspot.
++ * and setters for the different fields.
+ *
+ * This is engineered to plug into the TaggedArray implementation, when it's done.
+ */
+- public static final boolean OBJECT_FIELDS_ONLY = !Options.getBooleanProperty("nashorn.fields.dual");
++ public static final boolean OBJECT_FIELDS_ONLY = Options.getBooleanProperty("nashorn.fields.objects");
+
+ /** The field types in the system */
+ private static final List<Type> FIELD_TYPES = new LinkedList<>();
+
+ /** What type is the primitive type in dual representation */
+- public static final Type PRIMITIVE_TYPE = Type.LONG;
++ public static final Type PRIMITIVE_FIELD_TYPE = Type.LONG;
++
++ private static final MethodHandle GET_DIFFERENT = findOwnMH("getDifferent", Object.class, Object.class, Class.class, MethodHandle.class, MethodHandle.class, int.class);
++ private static final MethodHandle GET_DIFFERENT_UNDEFINED = findOwnMH("getDifferentUndefined", Object.class, int.class);
+
+ /**
+ * The list of field types that we support - one type creates one field. This is currently either
+@@ -107,33 +123,16 @@
+ */
+ static {
+ if (!OBJECT_FIELDS_ONLY) {
+- System.err.println("WARNING!!! Running with primitive fields - there is untested functionality!");
+- FIELD_TYPES.add(PRIMITIVE_TYPE);
++ FIELD_TYPES.add(PRIMITIVE_FIELD_TYPE);
+ }
+ FIELD_TYPES.add(Type.OBJECT);
+ }
++ private static boolean initialized = false;
+
+ /** The context */
+ private final Context context;
+
+ /**
+- * The list of available accessor types in width order. This order is used for type guesses narrow{@literal ->} wide
+- * in the dual--fields world
+- */
+- public static final List<Type> ACCESSOR_TYPES = Collections.unmodifiableList(
+- Arrays.asList(
+- Type.INT,
+- Type.LONG,
+- Type.NUMBER,
+- Type.OBJECT));
+-
+- //these are hard coded for speed and so that we can switch on them
+- private static final int TYPE_INT_INDEX = 0; //getAccessorTypeIndex(int.class);
+- private static final int TYPE_LONG_INDEX = 1; //getAccessorTypeIndex(long.class);
+- private static final int TYPE_DOUBLE_INDEX = 2; //getAccessorTypeIndex(double.class);
+- private static final int TYPE_OBJECT_INDEX = 3; //getAccessorTypeIndex(Object.class);
+-
+- /**
+ * Constructor
+ *
+ * @param context a context
+@@ -141,64 +140,39 @@
+ public ObjectClassGenerator(final Context context) {
+ this.context = context;
+ assert context != null;
++ this.log = initLogger(context);
++ if (!initialized) {
++ initialized = true;
++ if (OBJECT_FIELDS_ONLY) {
++ log.warning("Running with object fields only - this is a deprecated configuration.");
++ }
++ }
++ }
++
++ @Override
++ public DebugLogger getLogger() {
++ return log;
++ }
++
++ @Override
++ public DebugLogger initLogger(final Context ctxt) {
++ return ctxt.getLogger(this.getClass());
+ }
+
+ /**
+- * Given a type of an accessor, return its index in [0..getNumberOfAccessorTypes())
+- *
+- * @param type the type
+- *
+- * @return the accessor index, or -1 if no accessor of this type exists
++ * Pack a number into a primitive long field
++ * @param n number object
++ * @return primitive long value with all the bits in the number
+ */
+- public static int getAccessorTypeIndex(final Type type) {
+- return getAccessorTypeIndex(type.getTypeClass());
+- }
+-
+- /**
+- * Given a class of an accessor, return its index in [0..getNumberOfAccessorTypes())
+- *
+- * Note that this is hardcoded with respect to the dynamic contents of the accessor
+- * types array for speed. Hotspot got stuck with this as 5% of the runtime in
+- * a benchmark when it looped over values and increased an index counter. :-(
+- *
+- * @param type the type
+- *
+- * @return the accessor index, or -1 if no accessor of this type exists
+- */
+- public static int getAccessorTypeIndex(final Class<?> type) {
+- if (type == int.class) {
+- return 0;
+- } else if (type == long.class) {
+- return 1;
+- } else if (type == double.class) {
+- return 2;
+- } else if (!type.isPrimitive()) {
+- return 3;
++ public static long pack(final Number n) {
++ if (n instanceof Integer) {
++ return n.intValue();
++ } else if (n instanceof Long) {
++ return n.longValue();
++ } else if (n instanceof Double) {
++ return Double.doubleToRawLongBits(n.doubleValue());
+ }
+- return -1;
+- }
+-
+- /**
+- * Return the number of accessor types available.
+- *
+- * @return number of accessor types in system
+- */
+- public static int getNumberOfAccessorTypes() {
+- return ACCESSOR_TYPES.size();
+- }
+-
+- /**
+- * Return the accessor type based on its index in [0..getNumberOfAccessorTypes())
+- * Indexes are ordered narrower{@literal ->}wider / optimistic{@literal ->}pessimistic. Invalidations always
+- * go to a type of higher index
+- *
+- * @param index accessor type index
+- *
+- * @return a type corresponding to the index.
+- */
+-
+- public static Type getAccessorType(final int index) {
+- return ACCESSOR_TYPES.get(index);
++ throw new AssertionError("cannot pack" + n);
+ }
+
+ /**
+@@ -232,10 +206,10 @@
+ * @param clazz the JavaScript scope class.
+ * @return the number of fields in the scope class.
+ */
+- public static int getFieldCount(Class<?> clazz) {
++ public static int getFieldCount(final Class<?> clazz) {
+ final String name = clazz.getSimpleName();
+ final String prefix = JS_OBJECT_PREFIX.symbolName();
+- if(prefix.equals(name)) {
++ if (prefix.equals(name)) {
+ return 0;
+ }
+ final int scopeMarker = name.indexOf(SCOPE_MARKER);
+@@ -264,13 +238,16 @@
+ * @param fieldNames fields to initialize to undefined, where applicable
+ */
+ private static void initializeToUndefined(final MethodEmitter init, final String className, final List<String> fieldNames) {
++ if (!OBJECT_FIELDS_ONLY) {
++ // no need to initialize anything to undefined in the dual field world
++ // - then we have a constant getter for undefined for any unknown type
++ return;
++ }
++
+ if (fieldNames.isEmpty()) {
+ return;
+ }
+
+- // always initialize fields to undefined, even with --dual-fields. Then it's ok to
+- // remember things like "widest set type" in properties, and if it's object, don't
+- // add any special "return undefined" getters, saving an invalidation
+ init.load(Type.OBJECT, JAVA_THIS.slot());
+ init.loadUndefined(Type.OBJECT);
+
+@@ -324,10 +301,14 @@
+ init.returnVoid();
+ init.end();
+
+- newEmptyInit(classEmitter, className);
+- newAllocate(classEmitter, className);
++ final MethodEmitter initWithSpillArrays = newInitWithSpillArraysMethod(classEmitter, ScriptObject.class);
++ initWithSpillArrays.returnVoid();
++ initWithSpillArrays.end();
+
+- return toByteArray(classEmitter);
++ newEmptyInit(className, classEmitter);
++ newAllocate(className, classEmitter);
++
++ return toByteArray(className, classEmitter);
+ }
+
+ /**
+@@ -340,8 +321,8 @@
+ * @return Byte codes for generated class.
+ */
+ public byte[] generate(final int fieldCount, final int paramCount) {
+- final String className = getClassName(fieldCount, paramCount);
+- final String superName = className(FunctionScope.class);
++ final String className = getClassName(fieldCount, paramCount);
++ final String superName = className(FunctionScope.class);
+ final ClassEmitter classEmitter = newClassEmitter(className, superName);
+ final List<String> initFields = addFields(classEmitter, fieldCount);
+
+@@ -350,12 +331,17 @@
+ init.returnVoid();
+ init.end();
+
++ final MethodEmitter initWithSpillArrays = newInitWithSpillArraysMethod(classEmitter, FunctionScope.class);
++ initializeToUndefined(initWithSpillArrays, className, initFields);
++ initWithSpillArrays.returnVoid();
++ initWithSpillArrays.end();
++
+ final MethodEmitter initWithArguments = newInitScopeWithArgumentsMethod(classEmitter);
+ initializeToUndefined(initWithArguments, className, initFields);
+ initWithArguments.returnVoid();
+ initWithArguments.end();
+
+- return toByteArray(classEmitter);
++ return toByteArray(className, classEmitter);
+ }
+
+ /**
+@@ -391,7 +377,7 @@
+ * @return Open class emitter.
+ */
+ private ClassEmitter newClassEmitter(final String className, final String superName) {
+- final ClassEmitter classEmitter = new ClassEmitter(context.getEnv(), className, superName);
++ final ClassEmitter classEmitter = new ClassEmitter(context, className, superName);
+ classEmitter.begin();
+
+ return classEmitter;
+@@ -414,6 +400,18 @@
+ return init;
+ }
+
++ private static MethodEmitter newInitWithSpillArraysMethod(final ClassEmitter classEmitter, final Class<?> superClass) {
++ final MethodEmitter init = classEmitter.init(PropertyMap.class, long[].class, Object[].class);
++ init.begin();
++ init.load(Type.OBJECT, JAVA_THIS.slot());
++ init.load(Type.OBJECT, INIT_MAP.slot());
++ init.load(Type.LONG_ARRAY, 2);
++ init.load(Type.OBJECT_ARRAY, 3);
++ init.invoke(constructorNoLookup(superClass, PropertyMap.class, long[].class, Object[].class));
++
++ return init;
++ }
++
+ /**
+ * Allocate and initialize a new <init> method for scopes.
+ * @param classEmitter Open class emitter.
+@@ -453,7 +451,7 @@
+ * @param classEmitter Open class emitter.
+ * @param className Name of JavaScript class.
+ */
+- private static void newEmptyInit(final ClassEmitter classEmitter, final String className) {
++ private static void newEmptyInit(final String className, final ClassEmitter classEmitter) {
+ final MethodEmitter emptyInit = classEmitter.init();
+ emptyInit.begin();
+ emptyInit.load(Type.OBJECT, JAVA_THIS.slot());
+@@ -469,10 +467,10 @@
+ * @param classEmitter Open class emitter.
+ * @param className Name of JavaScript class.
+ */
+- private static void newAllocate(final ClassEmitter classEmitter, final String className) {
++ private static void newAllocate(final String className, final ClassEmitter classEmitter) {
+ final MethodEmitter allocate = classEmitter.method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), ALLOCATE.symbolName(), ScriptObject.class, PropertyMap.class);
+ allocate.begin();
+- allocate._new(className);
++ allocate._new(className, Type.typeFor(ScriptObject.class));
+ allocate.dup();
+ allocate.load(Type.typeFor(PropertyMap.class), 0);
+ allocate.invoke(constructorNoLookup(className, PropertyMap.class));
+@@ -486,15 +484,13 @@
+ * @param classEmitter Open class emitter.
+ * @return Byte codes for the class.
+ */
+- private byte[] toByteArray(final ClassEmitter classEmitter) {
++ private byte[] toByteArray(final String className, final ClassEmitter classEmitter) {
+ classEmitter.end();
+
+ final byte[] code = classEmitter.toByteArray();
+ final ScriptEnvironment env = context.getEnv();
+
+- if (env._print_code) {
+- env.getErr().println(ClassEmitter.disassemble(code));
+- }
++ DumpBytecode.dumpBytecode(env, log, code, className);
+
+ if (env._verify_code) {
+ context.verify(code);
+@@ -504,20 +500,174 @@
+ }
+
+ /** Double to long bits, used with --dual-fields for primitive double values */
+- private static final MethodHandle PACK_DOUBLE =
++ public static final MethodHandle PACK_DOUBLE =
+ MH.explicitCastArguments(MH.findStatic(MethodHandles.publicLookup(), Double.class, "doubleToRawLongBits", MH.type(long.class, double.class)), MH.type(long.class, double.class));
+
+ /** double bits to long, used with --dual-fields for primitive double values */
+- private static MethodHandle UNPACK_DOUBLE =
++ public static final MethodHandle UNPACK_DOUBLE =
+ MH.findStatic(MethodHandles.publicLookup(), Double.class, "longBitsToDouble", MH.type(double.class, long.class));
+
+- /** object conversion quickies with JS semantics - used for return value and parameter filter */
+- private static MethodHandle[] CONVERT_OBJECT = {
+- JSType.TO_INT32.methodHandle(),
+- JSType.TO_UINT32.methodHandle(),
+- JSType.TO_NUMBER.methodHandle(),
+- null
+- };
++ //type != forType, so use the correct getter for forType, box it and throw
++ @SuppressWarnings("unused")
++ private static Object getDifferent(final Object receiver, final Class<?> forType, final MethodHandle primitiveGetter, final MethodHandle objectGetter, final int programPoint) {
++ //create the sametype getter, and upcast to value. no matter what the store format is,
++ //
++ final MethodHandle sameTypeGetter = getterForType(forType, primitiveGetter, objectGetter);
++ final MethodHandle mh = MH.asType(sameTypeGetter, sameTypeGetter.type().changeReturnType(Object.class));
++ try {
++ final Object value = mh.invokeExact(receiver);
++ throw new UnwarrantedOptimismException(value, programPoint);
++ } catch (final Error | RuntimeException e) {
++ throw e;
++ } catch (final Throwable e) {
++ throw new RuntimeException(e);
++ }
++ }
++
++ @SuppressWarnings("unused")
++ private static Object getDifferentUndefined(final int programPoint) {
++ throw new UnwarrantedOptimismException(Undefined.getUndefined(), programPoint);
++ }
++
++ private static MethodHandle getterForType(final Class<?> forType, final MethodHandle primitiveGetter, final MethodHandle objectGetter) {
++ switch (getAccessorTypeIndex(forType)) {
++ case TYPE_INT_INDEX:
++ assert !OBJECT_FIELDS_ONLY : "this can only happen with dual fields";
++ return MH.explicitCastArguments(primitiveGetter, primitiveGetter.type().changeReturnType(int.class));
++ case TYPE_LONG_INDEX:
++ assert !OBJECT_FIELDS_ONLY : "this can only happen with dual fields";
++ return primitiveGetter;
++ case TYPE_DOUBLE_INDEX:
++ assert !OBJECT_FIELDS_ONLY : "this can only happen with dual fields";
++ return MH.filterReturnValue(primitiveGetter, UNPACK_DOUBLE);
++ case TYPE_OBJECT_INDEX:
++ return objectGetter;
++ default:
++ throw new AssertionError(forType);
++ }
++ }
++
++ //no optimism here. we do unconditional conversion to types
++ private static MethodHandle createGetterInner(final Class<?> forType, final Class<?> type, final MethodHandle primitiveGetter, final MethodHandle objectGetter, final List<MethodHandle> converters, final int programPoint) {
++ final int fti = forType == null ? TYPE_UNDEFINED_INDEX : getAccessorTypeIndex(forType);
++ final int ti = getAccessorTypeIndex(type);
++ //this means fail if forType != type
++ final boolean isOptimistic = converters == CONVERT_OBJECT_OPTIMISTIC;
++ final boolean isPrimitiveStorage = forType != null && forType.isPrimitive();
++
++ //which is the primordial getter
++ final MethodHandle getter = OBJECT_FIELDS_ONLY ? objectGetter : isPrimitiveStorage ? primitiveGetter : objectGetter;
++
++ if (forType == null) {
++ if (isOptimistic) {
++ //return undefined if asking for object. otherwise throw UnwarrantedOptimismException
++ if (ti == TYPE_OBJECT_INDEX) {
++ return MH.dropArguments(GET_UNDEFINED.get(TYPE_OBJECT_INDEX), 0, Object.class);
++ }
++ //throw exception
++ return MH.asType(
++ MH.dropArguments(
++ MH.insertArguments(
++ GET_DIFFERENT_UNDEFINED,
++ 0,
++ programPoint),
++ 0,
++ Object.class),
++ getter.type().changeReturnType(type));
++ }
++ //return an undefined and coerce it to the appropriate type
++ return MH.dropArguments(GET_UNDEFINED.get(ti), 0, Object.class);
++ }
++
++ assert forType != null;
++ assert !OBJECT_FIELDS_ONLY || forType == Object.class : forType;
++
++ if (isOptimistic) {
++ if (fti < ti) {
++ //asking for a wider type than currently stored. then it's OK to coerce.
++ //e.g. stored as int, ask for long or double
++ //e.g. stored as long, ask for double
++ assert fti != TYPE_UNDEFINED_INDEX;
++ final MethodHandle tgetter = getterForType(forType, primitiveGetter, objectGetter);
++ return MH.asType(tgetter, tgetter.type().changeReturnType(type));
++ } else if (fti == ti) {
++ //Fast path, never throw exception - exact getter, just unpack if needed
++ return getterForType(forType, primitiveGetter, objectGetter);
++ } else {
++ assert fti > ti;
++ //if asking for a narrower type than the storage - throw exception
++ //unless FTI is object, in that case we have to go through the converters
++ //there is no
++ if (fti == TYPE_OBJECT_INDEX) {
++ return MH.filterReturnValue(
++ objectGetter,
++ MH.insertArguments(
++ converters.get(ti),
++ 1,
++ programPoint));
++ }
++
++ //asking for narrower primitive than we have stored, that is an
++ //UnwarrantedOptimismException
++ return MH.asType(
++ MH.filterArguments(
++ objectGetter,
++ 0,
++ MH.insertArguments(
++ GET_DIFFERENT,
++ 1,
++ forType,
++ primitiveGetter,
++ objectGetter,
++ programPoint)),
++ objectGetter.type().changeReturnType(type));
++ }
++ }
++
++ assert !isOptimistic;
++ //freely coerce the result to whatever you asked for, this is e.g. Object->int for a & b
++ final MethodHandle tgetter = getterForType(forType, primitiveGetter, objectGetter);
++ if (fti == TYPE_OBJECT_INDEX) {
++ if (fti != ti) {
++ return MH.filterReturnValue(tgetter, CONVERT_OBJECT.get(ti));
++ }
++ return tgetter;
++ }
++
++ assert !OBJECT_FIELDS_ONLY;
++ //final MethodType pmt = primitiveGetter.type();
++ assert primitiveGetter != null;
++ final MethodType tgetterType = tgetter.type();
++ switch (fti) {
++ case TYPE_INT_INDEX: {
++ return MH.asType(tgetter, tgetterType.changeReturnType(type));
++ }
++ case TYPE_LONG_INDEX:
++ switch (ti) {
++ case TYPE_INT_INDEX:
++ //get int while an int, truncating cast of long value
++ return MH.filterReturnValue(tgetter, JSType.TO_INT32_L.methodHandle);
++ case TYPE_LONG_INDEX:
++ return primitiveGetter;
++ default:
++ return MH.asType(tgetter, tgetterType.changeReturnType(type));
++ }
++ case TYPE_DOUBLE_INDEX:
++ switch (ti) {
++ case TYPE_INT_INDEX:
++ return MH.filterReturnValue(tgetter, JSType.TO_INT32_D.methodHandle);
++ case TYPE_LONG_INDEX:
++ return MH.explicitCastArguments(tgetter, tgetterType.changeReturnType(type));
++ case TYPE_DOUBLE_INDEX:
++ assert tgetterType.returnType() == double.class;
++ return tgetter;
++ default:
++ return MH.asType(tgetter, tgetterType.changeReturnType(Object.class));
++ }
++ default:
++ throw new UnsupportedOperationException(forType + "=>" + type);
++ }
++ }
+
+ /**
+ * Given a primitiveGetter (optional for non dual fields) and an objectSetter that retrieve
+@@ -526,7 +676,7 @@
+ * and we want an Object getter, in the dual fields world we'd pick the primitiveGetter,
+ * which reads a long, use longBitsToDouble on the result to unpack it, and then change the
+ * return type to Object, boxing it. In the objects only world there are only object fields,
+- * primtives are boxed when asked for them and we don't need to bother with primitive encoding
++ * primitives are boxed when asked for them and we don't need to bother with primitive encoding
+ * (or even undefined, which if forType==null) representation, so we just return whatever is
+ * in the object field. The object field is always initiated to Undefined, so here, where we have
+ * the representation for Undefined in all our bits, this is not a problem.
+@@ -543,110 +693,18 @@
+ * @param type type to retrieve it as
+ * @param primitiveGetter getter to read the primitive version of this field (null if Objects Only)
+ * @param objectGetter getter to read the object version of this field
++ * @param programPoint program point for getter, if program point is INVALID_PROGRAM_POINT, then this is not an optimistic getter
+ *
+ * @return getter for the given representation that returns the given type
+ */
+- public static MethodHandle createGetter(final Class<?> forType, final Class<?> type, final MethodHandle primitiveGetter, final MethodHandle objectGetter) {
+- final int fti = forType == null ? -1 : getAccessorTypeIndex(forType);
+- final int ti = getAccessorTypeIndex(type);
+-
+- if (fti == TYPE_OBJECT_INDEX || OBJECT_FIELDS_ONLY) {
+- if (ti == TYPE_OBJECT_INDEX) {
+- return objectGetter;
+- }
+-
+- return MH.filterReturnValue(objectGetter, CONVERT_OBJECT[ti]);
+- }
+-
+- assert !OBJECT_FIELDS_ONLY;
+- if (forType == null) {
+- return GET_UNDEFINED[ti];
+- }
+-
+- final MethodType pmt = primitiveGetter.type();
+-
+- switch (fti) {
+- case TYPE_INT_INDEX:
+- case TYPE_LONG_INDEX:
+- switch (ti) {
+- case TYPE_INT_INDEX:
+- //get int while an int, truncating cast of long value
+- return MH.explicitCastArguments(primitiveGetter, pmt.changeReturnType(int.class));
+- case TYPE_LONG_INDEX:
+- return primitiveGetter;
+- default:
+- return MH.asType(primitiveGetter, pmt.changeReturnType(type));
+- }
+- case TYPE_DOUBLE_INDEX:
+- final MethodHandle getPrimitiveAsDouble = MH.filterReturnValue(primitiveGetter, UNPACK_DOUBLE);
+- switch (ti) {
+- case TYPE_INT_INDEX:
+- case TYPE_LONG_INDEX:
+- return MH.explicitCastArguments(getPrimitiveAsDouble, pmt.changeReturnType(type));
+- case TYPE_DOUBLE_INDEX:
+- return getPrimitiveAsDouble;
+- default:
+- return MH.asType(getPrimitiveAsDouble, pmt.changeReturnType(Object.class));
+- }
+- default:
+- assert false;
+- return null;
+- }
+- }
+-
+- private static final MethodHandle IS_TYPE_GUARD = findOwnMH("isType", boolean.class, Class.class, Object.class);
+-
+- @SuppressWarnings("unused")
+- private static boolean isType(final Class<?> boxedForType, final Object x) {
+- return x.getClass() == boxedForType;
+- }
+-
+- private static Class<? extends Number> getBoxedType(final Class<?> forType) {
+- if (forType == int.class) {
+- return Integer.class;
+- }
+-
+- if (forType == long.class) {
+- return Long.class;
+- }
+-
+- if (forType == double.class) {
+- return Double.class;
+- }
+-
+- assert false;
+- return null;
+- }
+-
+- /**
+- * If we are setting boxed types (because the compiler couldn't determine which they were) to
+- * a primitive field, we can reuse the primitive field getter, as long as we are setting an element
+- * of the same boxed type as the primitive type representation
+- *
+- * @param forType the current type
+- * @param primitiveSetter primitive setter for the current type with an element of the current type
+- * @param objectSetter the object setter
+- *
+- * @return method handle that checks if the element to be set is of the currenttype, even though it's boxed
+- * and instead of using the generic object setter, that would blow up the type and invalidate the map,
+- * unbox it and call the primitive setter instead
+- */
+- public static MethodHandle createGuardBoxedPrimitiveSetter(final Class<?> forType, final MethodHandle primitiveSetter, final MethodHandle objectSetter) {
+- final Class<? extends Number> boxedForType = getBoxedType(forType);
+- //object setter that checks for primitive if current type is primitive
+-
+- return MH.guardWithTest(
+- MH.insertArguments(
+- MH.dropArguments(
+- IS_TYPE_GUARD,
+- 1,
+- Object.class),
+- 0,
+- boxedForType),
+- MH.asType(
+- primitiveSetter,
+- objectSetter.type()),
+- objectSetter);
++ public static MethodHandle createGetter(final Class<?> forType, final Class<?> type, final MethodHandle primitiveGetter, final MethodHandle objectGetter, final int programPoint) {
++ return createGetterInner(
++ forType,
++ type,
++ primitiveGetter,
++ objectGetter,
++ isValid(programPoint) ? CONVERT_OBJECT_OPTIMISTIC : CONVERT_OBJECT,
++ programPoint);
+ }
+
+ /**
+@@ -699,11 +757,61 @@
+ }
+ return MH.asType(MH.filterArguments(primitiveSetter, 1, PACK_DOUBLE), pmt.changeParameterType(1, type));
+ default:
+- assert false;
+- return null;
++ throw new UnsupportedOperationException(forType + "=>" + type);
+ }
+ }
+
++ @SuppressWarnings("unused")
++ private static boolean isType(final Class<?> boxedForType, final Object x) {
++ return x != null && x.getClass() == boxedForType;
++ }
++
++ private static Class<? extends Number> getBoxedType(final Class<?> forType) {
++ if (forType == int.class) {
++ return Integer.class;
++ }
++
++ if (forType == long.class) {
++ return Long.class;
++ }
++
++ if (forType == double.class) {
++ return Double.class;
++ }
++
++ assert false;
++ return null;
++ }
++
++ /**
++ * If we are setting boxed types (because the compiler couldn't determine which they were) to
++ * a primitive field, we can reuse the primitive field getter, as long as we are setting an element
++ * of the same boxed type as the primitive type representation
++ *
++ * @param forType the current type
++ * @param primitiveSetter primitive setter for the current type with an element of the current type
++ * @param objectSetter the object setter
++ *
++ * @return method handle that checks if the element to be set is of the currenttype, even though it's boxed
++ * and instead of using the generic object setter, that would blow up the type and invalidate the map,
++ * unbox it and call the primitive setter instead
++ */
++ public static MethodHandle createGuardBoxedPrimitiveSetter(final Class<?> forType, final MethodHandle primitiveSetter, final MethodHandle objectSetter) {
++ final Class<? extends Number> boxedForType = getBoxedType(forType);
++ //object setter that checks for primitive if current type is primitive
++ return MH.guardWithTest(
++ MH.insertArguments(
++ MH.dropArguments(
++ IS_TYPE_GUARD,
++ 1,
++ Object.class),
++ 0,
++ boxedForType),
++ MH.asType(
++ primitiveSetter,
++ objectSetter.type()),
++ objectSetter);
++ }
+ /**
+ * Add padding to field count to avoid creating too many classes and have some spare fields
+ * @param count the field count
+@@ -713,80 +821,49 @@
+ return count / FIELD_PADDING * FIELD_PADDING + FIELD_PADDING;
+ }
+
+- //
+- // Provide generic getters and setters for undefined types. If a type is undefined, all
+- // and marshals the set to the correct setter depending on the type of the value being set.
+- // Note that there are no actual undefined versions of int, long and double in JavaScript,
+- // but executing toInt32, toLong and toNumber always returns a working result, 0, 0L or NaN
+- //
+-
+- /** The value of Undefined cast to an int32 */
+- public static final int UNDEFINED_INT = 0;
+- /** The value of Undefined cast to a long */
+- public static final long UNDEFINED_LONG = 0L;
+- /** The value of Undefined cast to a double */
+- public static final double UNDEFINED_DOUBLE = Double.NaN;
+-
+- /**
+- * Compute type name for correct undefined getter
+- * @param type the type
+- * @return name of getter
+- */
+- private static String typeName(final Type type) {
+- String name = type.getTypeClass().getName();
+- final int dot = name.lastIndexOf('.');
+- if (dot != -1) {
+- name = name.substring(dot + 1);
+- }
+- return Character.toUpperCase(name.charAt(0)) + name.substring(1);
++ private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
++ return MH.findStatic(MethodHandles.lookup(), ObjectClassGenerator.class, name, MH.type(rtype, types));
+ }
+
+ /**
+- * Handles for undefined getters of the different types
++ * Describes the allocator class name and property map for a constructor function with the specified
++ * number of "this" properties that it initializes.
++ *
+ */
+- private static final MethodHandle[] GET_UNDEFINED = new MethodHandle[ObjectClassGenerator.getNumberOfAccessorTypes()];
++ public static class AllocatorDescriptor {
++ private final String allocatorClassName;
++ private final PropertyMap allocatorMap;
+
+- /**
+- * Used to wrap getters for undefined values, where this matters. Currently only in dual fields.
+- * If an object starts out as undefined it needs special getters until it has been assigned
+- * something the first time
+- *
+- * @param returnType type to cast the undefined to
+- *
+- * @return undefined as returnType
+- */
+- public static MethodHandle getUndefined(final Class<?> returnType) {
+- return GET_UNDEFINED[ObjectClassGenerator.getAccessorTypeIndex(returnType)];
+- }
++ /**
++ * Creates a new allocator descriptor
++ * @param thisProperties the number of "this" properties that the function initializes
++ */
++ public AllocatorDescriptor(final int thisProperties) {
++ final int paddedFieldCount = getPaddedFieldCount(thisProperties);
++ this.allocatorClassName = Compiler.binaryName(getClassName(paddedFieldCount));
++ this.allocatorMap = PropertyMap.newMap(null, allocatorClassName, 0, paddedFieldCount, 0);
++ }
+
+- static {
+- int pos = 0;
+- for (final Type type : ACCESSOR_TYPES) {
+- GET_UNDEFINED[pos++] = findOwnMH("getUndefined" + typeName(type), type.getTypeClass(), Object.class);
++ /**
++ * Returns the name of the class that the function allocates
++ * @return the name of the class that the function allocates
++ */
++ public String getAllocatorClassName() {
++ return allocatorClassName;
++ }
++
++ /**
++ * Returns the allocator map for the function.
++ * @return the allocator map for the function.
++ */
++ public PropertyMap getAllocatorMap() {
++ return allocatorMap;
++ }
++
++ @Override
++ public String toString() {
++ return "AllocatorDescriptor[allocatorClassName=" + allocatorClassName + ", allocatorMap.size=" +
++ allocatorMap.size() + "]";
+ }
+ }
+-
+- @SuppressWarnings("unused")
+- private static int getUndefinedInt(final Object obj) {
+- return UNDEFINED_INT;
+- }
+-
+- @SuppressWarnings("unused")
+- private static long getUndefinedLong(final Object obj) {
+- return UNDEFINED_LONG;
+- }
+-
+- @SuppressWarnings("unused")
+- private static double getUndefinedDouble(final Object obj) {
+- return UNDEFINED_DOUBLE;
+- }
+-
+- @SuppressWarnings("unused")
+- private static Object getUndefinedObject(final Object obj) {
+- return ScriptRuntime.UNDEFINED;
+- }
+-
+- private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+- return MH.findStatic(MethodHandles.lookup(), ObjectClassGenerator.class, name, MH.type(rtype, types));
+- }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,22 +28,21 @@
+ import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
+
+ import java.util.List;
+-import jdk.nashorn.internal.ir.Symbol;
++import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.runtime.PropertyMap;
++import jdk.nashorn.internal.runtime.ScriptObject;
+
+ /**
+ * Base class for object creation code generation.
++ * @param <T> value type
+ */
+-public abstract class ObjectCreator {
++public abstract class ObjectCreator<T> {
+
+- /** List of keys to initiate in this ObjectCreator */
+- protected final List<String> keys;
+-
+- /** List of symbols to initiate in this ObjectCreator */
+- protected final List<Symbol> symbols;
++ /** List of keys & symbols to initiate in this ObjectCreator */
++ final List<MapTuple<T>> tuples;
+
+ /** Code generator */
+- protected final CodeGenerator codegen;
++ final CodeGenerator codegen;
+
+ /** Property map */
+ protected PropertyMap propertyMap;
+@@ -55,15 +54,13 @@
+ * Constructor
+ *
+ * @param codegen the code generator
+- * @param keys the keys
+- * @param symbols the symbols corresponding to keys, same index
++ * @param tuples key,symbol,value (optional) tuples
+ * @param isScope is this object scope
+ * @param hasArguments does the created object have an "arguments" property
+ */
+- protected ObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final boolean isScope, final boolean hasArguments) {
++ ObjectCreator(final CodeGenerator codegen, final List<MapTuple<T>> tuples, final boolean isScope, final boolean hasArguments) {
+ this.codegen = codegen;
+- this.keys = keys;
+- this.symbols = symbols;
++ this.tuples = tuples;
+ this.isScope = isScope;
+ this.hasArguments = hasArguments;
+ }
+@@ -85,8 +82,8 @@
+ * @param clazz type of MapCreator
+ * @return map creator instantiated by type
+ */
+- protected MapCreator newMapCreator(final Class<?> clazz) {
+- return new MapCreator(clazz, keys, symbols);
++ protected MapCreator<?> newMapCreator(final Class<? extends ScriptObject> clazz) {
++ return new MapCreator<>(clazz, tuples);
+ }
+
+ /**
+@@ -107,6 +104,10 @@
+ return method;
+ }
+
++ PropertyMap getMap() {
++ return propertyMap;
++ }
++
+ /**
+ * Is this a scope object
+ * @return true if scope
+@@ -122,4 +123,27 @@
+ protected boolean hasArguments() {
+ return hasArguments;
+ }
++
++ /**
++ * Technique for loading an initial value. Defined by anonymous subclasses in code gen.
++ *
++ * @param value Value to load.
++ * @param type the type of the value to load
++ */
++ protected abstract void loadValue(T value, Type type);
++
++ MethodEmitter loadTuple(final MethodEmitter method, final MapTuple<T> tuple, final boolean pack) {
++ loadValue(tuple.value, tuple.type);
++ if (pack && tuple.isPrimitive()) {
++ method.pack();
++ } else {
++ method.convert(Type.OBJECT);
++ }
++ return method;
++ }
++
++ MethodEmitter loadTuple(final MethodEmitter method, final MapTuple<T> tuple) {
++ return loadTuple(method, tuple, true);
++ }
++
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/OptimisticTypesCalculator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,257 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
++
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
++
++import java.util.ArrayDeque;
++import java.util.BitSet;
++import java.util.Deque;
++import jdk.nashorn.internal.ir.AccessNode;
++import jdk.nashorn.internal.ir.BinaryNode;
++import jdk.nashorn.internal.ir.CallNode;
++import jdk.nashorn.internal.ir.CatchNode;
++import jdk.nashorn.internal.ir.Expression;
++import jdk.nashorn.internal.ir.ExpressionStatement;
++import jdk.nashorn.internal.ir.ForNode;
++import jdk.nashorn.internal.ir.FunctionNode;
++import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
++import jdk.nashorn.internal.ir.IdentNode;
++import jdk.nashorn.internal.ir.IfNode;
++import jdk.nashorn.internal.ir.IndexNode;
++import jdk.nashorn.internal.ir.JoinPredecessorExpression;
++import jdk.nashorn.internal.ir.LexicalContext;
++import jdk.nashorn.internal.ir.LoopNode;
++import jdk.nashorn.internal.ir.Node;
++import jdk.nashorn.internal.ir.Optimistic;
++import jdk.nashorn.internal.ir.PropertyNode;
++import jdk.nashorn.internal.ir.Symbol;
++import jdk.nashorn.internal.ir.TernaryNode;
++import jdk.nashorn.internal.ir.UnaryNode;
++import jdk.nashorn.internal.ir.VarNode;
++import jdk.nashorn.internal.ir.WhileNode;
++import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++import jdk.nashorn.internal.parser.TokenType;
++import jdk.nashorn.internal.runtime.ScriptObject;
++
++/**
++ * Assigns optimistic types to expressions that can have them. This class mainly contains logic for which expressions
++ * must not ever be marked as optimistic, assigning narrowest non-invalidated types to program points from the
++ * compilation environment, as well as initializing optimistic types of global properties for scripts.
++ */
++final class OptimisticTypesCalculator extends NodeVisitor<LexicalContext> {
++
++ final Compiler compiler;
++
++ // Per-function bit set of program points that must never be optimistic.
++ final Deque<BitSet> neverOptimistic = new ArrayDeque<>();
++
++ OptimisticTypesCalculator(final Compiler compiler) {
++ super(new LexicalContext());
++ this.compiler = compiler;
++ }
++
++ @Override
++ public boolean enterAccessNode(final AccessNode accessNode) {
++ tagNeverOptimistic(accessNode.getBase());
++ return true;
++ }
++
++ @Override
++ public boolean enterPropertyNode(final PropertyNode propertyNode) {
++ if(propertyNode.getKeyName().equals(ScriptObject.PROTO_PROPERTY_NAME)) {
++ tagNeverOptimistic(propertyNode.getValue());
++ }
++ return super.enterPropertyNode(propertyNode);
++ }
++
++ @Override
++ public boolean enterBinaryNode(final BinaryNode binaryNode) {
++ if(binaryNode.isAssignment()) {
++ final Expression lhs = binaryNode.lhs();
++ if(!binaryNode.isSelfModifying()) {
++ tagNeverOptimistic(lhs);
++ }
++ if(lhs instanceof IdentNode) {
++ final Symbol symbol = ((IdentNode)lhs).getSymbol();
++ // Assignment to internal symbols is never optimistic, except for self-assignment expressions
++ if(symbol.isInternal() && !binaryNode.rhs().isSelfModifying()) {
++ tagNeverOptimistic(binaryNode.rhs());
++ }
++ }
++ } else if(binaryNode.isTokenType(TokenType.INSTANCEOF)) {
++ tagNeverOptimistic(binaryNode.lhs());
++ tagNeverOptimistic(binaryNode.rhs());
++ }
++ return true;
++ }
++
++ @Override
++ public boolean enterCallNode(final CallNode callNode) {
++ tagNeverOptimistic(callNode.getFunction());
++ return true;
++ }
++
++ @Override
++ public boolean enterCatchNode(final CatchNode catchNode) {
++ // Condition is never optimistic (always coerced to boolean).
++ tagNeverOptimistic(catchNode.getExceptionCondition());
++ return true;
++ }
++
++ @Override
++ public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) {
++ final Expression expr = expressionStatement.getExpression();
++ if(!expr.isSelfModifying()) {
++ tagNeverOptimistic(expr);
++ }
++ return true;
++ }
++
++ @Override
++ public boolean enterForNode(final ForNode forNode) {
++ if(forNode.isForIn()) {
++ // for..in has the iterable in its "modify"
++ tagNeverOptimistic(forNode.getModify());
++ } else {
++ // Test is never optimistic (always coerced to boolean).
++ tagNeverOptimisticLoopTest(forNode);
++ }
++ return true;
++ }
++
++ @Override
++ public boolean enterFunctionNode(final FunctionNode functionNode) {
++ if (!neverOptimistic.isEmpty() && compiler.isOnDemandCompilation()) {
++ // This is a nested function, and we're doing on-demand compilation. In these compilations, we never descend
++ // into nested functions.
++ return false;
++ }
++ neverOptimistic.push(new BitSet());
++ return true;
++ }
++
++ @Override
++ public boolean enterIfNode(final IfNode ifNode) {
++ // Test is never optimistic (always coerced to boolean).
++ tagNeverOptimistic(ifNode.getTest());
++ return true;
++ }
++
++ @Override
++ public boolean enterIndexNode(final IndexNode indexNode) {
++ tagNeverOptimistic(indexNode.getBase());
++ return true;
++ }
++
++ @Override
++ public boolean enterTernaryNode(final TernaryNode ternaryNode) {
++ // Test is never optimistic (always coerced to boolean).
++ tagNeverOptimistic(ternaryNode.getTest());
++ return true;
++ }
++
++ @Override
++ public boolean enterUnaryNode(final UnaryNode unaryNode) {
++ if(unaryNode.isTokenType(TokenType.NOT) || unaryNode.isTokenType(TokenType.NEW)) {
++ // Operand of boolean negation is never optimistic (always coerced to boolean).
++ // Operand of "new" is never optimistic (always coerced to Object).
++ tagNeverOptimistic(unaryNode.getExpression());
++ }
++ return true;
++ }
++
++ @Override
++ public boolean enterVarNode(final VarNode varNode) {
++ tagNeverOptimistic(varNode.getName());
++ return true;
++ }
++
++ @Override
++ public boolean enterWhileNode(final WhileNode whileNode) {
++ // Test is never optimistic (always coerced to boolean).
++ tagNeverOptimisticLoopTest(whileNode);
++ return true;
++ }
++
++ @Override
++ protected Node leaveDefault(final Node node) {
++ if(node instanceof Optimistic) {
++ return leaveOptimistic((Optimistic)node);
++ }
++ return node;
++ }
++
++ @Override
++ public Node leaveFunctionNode(final FunctionNode functionNode) {
++ neverOptimistic.pop();
++ return functionNode.setState(lc, CompilationState.OPTIMISTIC_TYPES_ASSIGNED);
++ }
++
++ @Override
++ public Node leaveIdentNode(final IdentNode identNode) {
++ final Symbol symbol = identNode.getSymbol();
++ if(symbol == null) {
++ assert identNode.isPropertyName();
++ return identNode;
++ } else if(symbol.isBytecodeLocal()) {
++ // Identifiers accessing bytecode local variables will never be optimistic, as type calculation phase over
++ // them will always assign them statically provable types. Note that access to function parameters can still
++ // be optimistic if the parameter needs to be in scope as it's used by a nested function.
++ return identNode;
++ } else if(symbol.isParam() && lc.getCurrentFunction().isVarArg()) {
++ // Parameters in vararg methods are not optimistic; we always access them using Object getters.
++ return identNode.setType(identNode.getMostPessimisticType());
++ } else {
++ assert symbol.isScope();
++ return leaveOptimistic(identNode);
++ }
++ }
++
++ private Expression leaveOptimistic(final Optimistic opt) {
++ final int pp = opt.getProgramPoint();
++ if(isValid(pp) && !neverOptimistic.peek().get(pp)) {
++ return (Expression)opt.setType(compiler.getOptimisticType(opt));
++ }
++ return (Expression)opt;
++ }
++
++ private void tagNeverOptimistic(final Expression expr) {
++ if(expr instanceof Optimistic) {
++ final int pp = ((Optimistic)expr).getProgramPoint();
++ if(isValid(pp)) {
++ neverOptimistic.peek().set(pp);
++ }
++ }
++ }
++
++ private void tagNeverOptimisticLoopTest(final LoopNode loopNode) {
++ final JoinPredecessorExpression test = loopNode.getTest();
++ if(test != null) {
++ tagNeverOptimistic(test.getExpression());
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,549 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
++
++import java.io.BufferedInputStream;
++import java.io.BufferedOutputStream;
++import java.io.DataInputStream;
++import java.io.DataOutputStream;
++import java.io.File;
++import java.io.FileInputStream;
++import java.io.FileOutputStream;
++import java.io.IOException;
++import java.io.InputStream;
++import java.io.PrintWriter;
++import java.io.StringWriter;
++import java.net.URL;
++import java.nio.file.Files;
++import java.nio.file.Path;
++import java.security.AccessController;
++import java.security.MessageDigest;
++import java.security.PrivilegedAction;
++import java.text.SimpleDateFormat;
++import java.util.Base64;
++import java.util.Date;
++import java.util.Map;
++import java.util.Timer;
++import java.util.TimerTask;
++import java.util.concurrent.TimeUnit;
++import java.util.concurrent.atomic.AtomicBoolean;
++import java.util.function.Function;
++import java.util.function.IntFunction;
++import java.util.function.Predicate;
++import java.util.stream.Stream;
++import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
++import jdk.nashorn.internal.runtime.Source;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.options.Options;
++
++/**
++ * Static utility that encapsulates persistence of type information for functions compiled with optimistic
++ * typing. With this feature enabled, when a JavaScript function is recompiled because it gets deoptimized,
++ * the type information for deoptimization is stored in a cache file. If the same function is compiled in a
++ * subsequent JVM invocation, the type information is used for initial compilation, thus allowing the system
++ * to skip a lot of intermediate recompilations and immediately emit a version of the code that has its
++ * optimistic types at (or near) the steady state.
++ * </p><p>
++ * Normally, the type info persistence feature is disabled. When the {@code nashorn.typeInfo.maxFiles} system
++ * property is specified with a value greater than 0, it is enabled and operates in an operating-system
++ * specific per-user cache directory. You can override the directory by specifying it in the
++ * {@code nashorn.typeInfo.cacheDir} directory. The maximum number of files is softly enforced by a task that
++ * cleans up the directory periodically on a separate thread. It is run after some delay after a new file is
++ * added to the cache. The default delay is 20 seconds, and can be set using the
++ * {@code nashorn.typeInfo.cleanupDelaySeconds} system property. You can also specify the word
++ * {@code unlimited} as the value for {@code nashorn.typeInfo.maxFiles} in which case the type info cache is
++ * allowed to grow without limits.
++ */
++public final class OptimisticTypesPersistence {
++ // Default is 0, for disabling the feature when not specified. A reasonable default when enabled is
++ // dependent on the application; setting it to e.g. 20000 is probably good enough for most uses and will
++ // usually cap the cache directory to about 80MB presuming a 4kB filesystem allocation unit. There is one
++ // file per JavaScript function.
++ private static final int DEFAULT_MAX_FILES = 0;
++ // Constants for signifying that the cache should not be limited
++ private static final int UNLIMITED_FILES = -1;
++ // Maximum number of files that should be cached on disk. The maximum will be softly enforced.
++ private static final int MAX_FILES = getMaxFiles();
++ // Number of seconds to wait between adding a new file to the cache and running a cleanup process
++ private static final int DEFAULT_CLEANUP_DELAY = 20;
++ private static final int CLEANUP_DELAY = Math.max(0, Options.getIntProperty(
++ "nashorn.typeInfo.cleanupDelaySeconds", DEFAULT_CLEANUP_DELAY));
++ // The name of the default subdirectory within the system cache directory where we store type info.
++ private static final String DEFAULT_CACHE_SUBDIR_NAME = "com.oracle.java.NashornTypeInfo";
++ // The directory where we cache type info
++ private static final File baseCacheDir = createBaseCacheDir();
++ private static final File cacheDir = createCacheDir(baseCacheDir);
++ // In-process locks to make sure we don't have a cross-thread race condition manipulating any file.
++ private static final Object[] locks = cacheDir == null ? null : createLockArray();
++ // Only report one read/write error every minute
++ private static final long ERROR_REPORT_THRESHOLD = 60000L;
++
++ private static volatile long lastReportedError;
++ private static final AtomicBoolean scheduledCleanup;
++ private static final Timer cleanupTimer;
++ static {
++ if (baseCacheDir == null || MAX_FILES == UNLIMITED_FILES) {
++ scheduledCleanup = null;
++ cleanupTimer = null;
++ } else {
++ scheduledCleanup = new AtomicBoolean();
++ cleanupTimer = new Timer(true);
++ }
++ }
++ /**
++ * Retrieves an opaque descriptor for the persistence location for a given function. It should be passed
++ * to {@link #load(Object)} and {@link #store(Object, Map)} methods.
++ * @param source the source where the function comes from
++ * @param functionId the unique ID number of the function within the source
++ * @param paramTypes the types of the function parameters (as persistence is per parameter type
++ * specialization).
++ * @return an opaque descriptor for the persistence location. Can be null if persistence is disabled.
++ */
++ public static Object getLocationDescriptor(final Source source, final int functionId, final Type[] paramTypes) {
++ if(cacheDir == null) {
++ return null;
++ }
++ final StringBuilder b = new StringBuilder(48);
++ // Base64-encode the digest of the source, and append the function id.
++ b.append(source.getDigest()).append('-').append(functionId);
++ // Finally, if this is a parameter-type specialized version of the function, add the parameter types
++ // to the file name.
++ if(paramTypes != null && paramTypes.length > 0) {
++ b.append('-');
++ for(final Type t: paramTypes) {
++ b.append(Type.getShortSignatureDescriptor(t));
++ }
++ }
++ return new LocationDescriptor(new File(cacheDir, b.toString()));
++ }
++
++ private static final class LocationDescriptor {
++ private final File file;
++
++ LocationDescriptor(final File file) {
++ this.file = file;
++ }
++ }
++
++
++ /**
++ * Stores the map of optimistic types for a given function.
++ * @param locationDescriptor the opaque persistence location descriptor, retrieved by calling
++ * {@link #getLocationDescriptor(Source, int, Type[])}.
++ * @param optimisticTypes the map of optimistic types.
++ */
++ @SuppressWarnings("resource")
++ public static void store(final Object locationDescriptor, final Map<Integer, Type> optimisticTypes) {
++ if(locationDescriptor == null || optimisticTypes.isEmpty()) {
++ return;
++ }
++ final File file = ((LocationDescriptor)locationDescriptor).file;
++
++ AccessController.doPrivileged(new PrivilegedAction<Void>() {
++ @Override
++ public Void run() {
++ synchronized(getFileLock(file)) {
++ if (!file.exists()) {
++ // If the file already exists, we aren't increasing the number of cached files, so
++ // don't schedule cleanup.
++ scheduleCleanup();
++ }
++ try (final FileOutputStream out = new FileOutputStream(file)) {
++ out.getChannel().lock(); // lock exclusive
++ final DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(out));
++ Type.writeTypeMap(optimisticTypes, dout);
++ dout.flush();
++ } catch(final Exception e) {
++ reportError("write", file, e);
++ }
++ }
++ return null;
++ }
++ });
++ }
++
++ /**
++ * Loads the map of optimistic types for a given function.
++ * @param locationDescriptor the opaque persistence location descriptor, retrieved by calling
++ * {@link #getLocationDescriptor(Source, int, Type[])}.
++ * @return the map of optimistic types, or null if persisted type information could not be retrieved.
++ */
++ @SuppressWarnings("resource")
++ public static Map<Integer, Type> load(final Object locationDescriptor) {
++ if (locationDescriptor == null) {
++ return null;
++ }
++ final File file = ((LocationDescriptor)locationDescriptor).file;
++ return AccessController.doPrivileged(new PrivilegedAction<Map<Integer, Type>>() {
++ @Override
++ public Map<Integer, Type> run() {
++ try {
++ if(!file.isFile()) {
++ return null;
++ }
++ synchronized(getFileLock(file)) {
++ try (final FileInputStream in = new FileInputStream(file)) {
++ in.getChannel().lock(0, Long.MAX_VALUE, true); // lock shared
++ final DataInputStream din = new DataInputStream(new BufferedInputStream(in));
++ return Type.readTypeMap(din);
++ }
++ }
++ } catch (final Exception e) {
++ reportError("read", file, e);
++ return null;
++ }
++ }
++ });
++ }
++
++ private static void reportError(final String msg, final File file, final Exception e) {
++ final long now = System.currentTimeMillis();
++ if(now - lastReportedError > ERROR_REPORT_THRESHOLD) {
++ reportError(String.format("Failed to %s %s", msg, file), e);
++ lastReportedError = now;
++ }
++ }
++
++ /**
++ * Logs an error message with warning severity (reasoning being that we're reporting an error that'll disable the
++ * type info cache, but it's only logged as a warning because that doesn't prevent Nashorn from running, it just
++ * disables a performance-enhancing cache).
++ * @param msg the message to log
++ * @param e the exception that represents the error.
++ */
++ private static void reportError(final String msg, final Exception e) {
++ getLogger().warning(msg, "\n", exceptionToString(e));
++ }
++
++ /**
++ * A helper that prints an exception stack trace into a string. We have to do this as if we just pass the exception
++ * to {@link DebugLogger#warning(Object...)}, it will only log the exception message and not the stack, making
++ * problems harder to diagnose.
++ * @param e the exception
++ * @return the string representation of {@link Exception#printStackTrace()} output.
++ */
++ private static String exceptionToString(final Exception e) {
++ final StringWriter sw = new StringWriter();
++ final PrintWriter pw = new PrintWriter(sw, false);
++ e.printStackTrace(pw);
++ pw.flush();
++ return sw.toString();
++ }
++
++ private static File createBaseCacheDir() {
++ if(MAX_FILES == 0 || Options.getBooleanProperty("nashorn.typeInfo.disabled")) {
++ return null;
++ }
++ try {
++ return createBaseCacheDirPrivileged();
++ } catch(final Exception e) {
++ reportError("Failed to create cache dir", e);
++ return null;
++ }
++ }
++
++ private static File createBaseCacheDirPrivileged() {
++ return AccessController.doPrivileged(new PrivilegedAction<File>() {
++ @Override
++ public File run() {
++ final String explicitDir = System.getProperty("nashorn.typeInfo.cacheDir");
++ final File dir;
++ if(explicitDir != null) {
++ dir = new File(explicitDir);
++ } else {
++ // When no directory is explicitly specified, get an operating system specific cache
++ // directory, and create "com.oracle.java.NashornTypeInfo" in it.
++ final File systemCacheDir = getSystemCacheDir();
++ dir = new File(systemCacheDir, DEFAULT_CACHE_SUBDIR_NAME);
++ if (isSymbolicLink(dir)) {
++ return null;
++ }
++ }
++ return dir;
++ }
++ });
++ }
++
++ private static File createCacheDir(final File baseDir) {
++ if (baseDir == null) {
++ return null;
++ }
++ try {
++ return createCacheDirPrivileged(baseDir);
++ } catch(final Exception e) {
++ reportError("Failed to create cache dir", e);
++ return null;
++ }
++ }
++
++ private static File createCacheDirPrivileged(final File baseDir) {
++ return AccessController.doPrivileged(new PrivilegedAction<File>() {
++ @Override
++ public File run() {
++ final String versionDirName;
++ try {
++ versionDirName = getVersionDirName();
++ } catch(final Exception e) {
++ reportError("Failed to calculate version dir name", e);
++ return null;
++ }
++ final File versionDir = new File(baseDir, versionDirName);
++ if (isSymbolicLink(versionDir)) {
++ return null;
++ }
++ versionDir.mkdirs();
++ if (versionDir.isDirectory()) {
++ getLogger().info("Optimistic type persistence directory is " + versionDir);
++ return versionDir;
++ }
++ getLogger().warning("Could not create optimistic type persistence directory " + versionDir);
++ return null;
++ }
++ });
++ }
++
++ /**
++ * Returns an operating system specific root directory for cache files.
++ * @return an operating system specific root directory for cache files.
++ */
++ private static File getSystemCacheDir() {
++ final String os = System.getProperty("os.name", "generic");
++ if("Mac OS X".equals(os)) {
++ // Mac OS X stores caches in ~/Library/Caches
++ return new File(new File(System.getProperty("user.home"), "Library"), "Caches");
++ } else if(os.startsWith("Windows")) {
++ // On Windows, temp directory is the best approximation of a cache directory, as its contents
++ // persist across reboots and various cleanup utilities know about it. java.io.tmpdir normally
++ // points to a user-specific temp directory, %HOME%\LocalSettings\Temp.
++ return new File(System.getProperty("java.io.tmpdir"));
++ } else {
++ // In other cases we're presumably dealing with a UNIX flavor (Linux, Solaris, etc.); "~/.cache"
++ return new File(System.getProperty("user.home"), ".cache");
++ }
++ }
++
++ /**
++ * In order to ensure that changes in Nashorn code don't cause corruption in the data, we'll create a
++ * per-code-version directory. Normally, this will create the SHA-1 digest of the nashorn.jar. In case the classpath
++ * for nashorn is local directory (e.g. during development), this will create the string "dev-" followed by the
++ * timestamp of the most recent .class file.
++ *
++ * @return digest of currently running nashorn
++ * @throws Exception if digest could not be created
++ */
++ public static String getVersionDirName() throws Exception {
++ // NOTE: getResource("") won't work if the JAR file doesn't have directory entries (and JAR files in JDK distro
++ // don't, or at least it's a bad idea counting on it). Alternatively, we could've tried
++ // getResource("OptimisticTypesPersistence.class") but behavior of getResource with regard to its willingness
++ // to hand out URLs to .class files is also unspecified. Therefore, the most robust way to obtain an URL to our
++ // package is to have a small non-class anchor file and start out from its URL.
++ final URL url = OptimisticTypesPersistence.class.getResource("anchor.properties");
++ final String protocol = url.getProtocol();
++ if (protocol.equals("jar")) {
++ // Normal deployment: nashorn.jar
++ final String jarUrlFile = url.getFile();
++ final String filePath = jarUrlFile.substring(0, jarUrlFile.indexOf('!'));
++ final URL file = new URL(filePath);
++ try (final InputStream in = file.openStream()) {
++ final byte[] buf = new byte[128*1024];
++ final MessageDigest digest = MessageDigest.getInstance("SHA-1");
++ for(;;) {
++ final int l = in.read(buf);
++ if(l == -1) {
++ return Base64.getUrlEncoder().withoutPadding().encodeToString(digest.digest());
++ }
++ digest.update(buf, 0, l);
++ }
++ }
++ } else if(protocol.equals("file")) {
++ // Development
++ final String fileStr = url.getFile();
++ final String className = OptimisticTypesPersistence.class.getName();
++ final int packageNameLen = className.lastIndexOf('.');
++ final String dirStr = fileStr.substring(0, fileStr.length() - packageNameLen - 1);
++ final File dir = new File(dirStr);
++ return "dev-" + new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(getLastModifiedClassFile(
++ dir, 0L)));
++ } else {
++ throw new AssertionError();
++ }
++ }
++
++ private static long getLastModifiedClassFile(final File dir, final long max) {
++ long currentMax = max;
++ for(final File f: dir.listFiles()) {
++ if(f.getName().endsWith(".class")) {
++ final long lastModified = f.lastModified();
++ if (lastModified > currentMax) {
++ currentMax = lastModified;
++ }
++ } else if (f.isDirectory()) {
++ final long lastModified = getLastModifiedClassFile(f, currentMax);
++ if (lastModified > currentMax) {
++ currentMax = lastModified;
++ }
++ }
++ }
++ return currentMax;
++ }
++
++ /**
++ * Returns true if the specified file is a symbolic link, and also logs a warning if it is.
++ * @param file the file
++ * @return true if file is a symbolic link, false otherwise.
++ */
++ private static boolean isSymbolicLink(final File file) {
++ if (Files.isSymbolicLink(file.toPath())) {
++ getLogger().warning("Directory " + file + " is a symlink");
++ return true;
++ }
++ return false;
++ }
++
++ private static Object[] createLockArray() {
++ final Object[] lockArray = new Object[Runtime.getRuntime().availableProcessors() * 2];
++ for (int i = 0; i < lockArray.length; ++i) {
++ lockArray[i] = new Object();
++ }
++ return lockArray;
++ }
++
++ private static Object getFileLock(final File file) {
++ return locks[(file.hashCode() & Integer.MAX_VALUE) % locks.length];
++ }
++
++ private static DebugLogger getLogger() {
++ try {
++ return Context.getContext().getLogger(RecompilableScriptFunctionData.class);
++ } catch (final Exception e) {
++ e.printStackTrace();
++ return DebugLogger.DISABLED_LOGGER;
++ }
++ }
++
++ private static void scheduleCleanup() {
++ if (MAX_FILES != UNLIMITED_FILES && scheduledCleanup.compareAndSet(false, true)) {
++ cleanupTimer.schedule(new TimerTask() {
++ @Override
++ public void run() {
++ scheduledCleanup.set(false);
++ try {
++ doCleanup();
++ } catch (final IOException e) {
++ // Ignore it. While this is unfortunate, we don't have good facility for reporting
++ // this, as we're running in a thread that has no access to Context, so we can't grab
++ // a DebugLogger.
++ }
++ }
++ }, TimeUnit.SECONDS.toMillis(CLEANUP_DELAY));
++ }
++ }
++
++ private static void doCleanup() throws IOException {
++ final Path[] files = getAllRegularFilesInLastModifiedOrder();
++ final int nFiles = files.length;
++ final int filesToDelete = Math.max(0, nFiles - MAX_FILES);
++ int filesDeleted = 0;
++ for (int i = 0; i < nFiles && filesDeleted < filesToDelete; ++i) {
++ try {
++ Files.deleteIfExists(files[i]);
++ // Even if it didn't exist, we increment filesDeleted; it existed a moment earlier; something
++ // else deleted it for us; that's okay with us.
++ filesDeleted++;
++ } catch (final Exception e) {
++ // does not increase filesDeleted
++ }
++ files[i] = null; // gc eligible
++ }
++ }
++
++ private static Path[] getAllRegularFilesInLastModifiedOrder() throws IOException {
++ try (final Stream<Path> filesStream = Files.walk(baseCacheDir.toPath())) {
++ // TODO: rewrite below once we can use JDK8 syntactic constructs
++ return filesStream
++ .filter(new Predicate<Path>() {
++ @Override
++ public boolean test(final Path path) {
++ return !Files.isDirectory(path);
++ }
++ })
++ .map(new Function<Path, PathAndTime>() {
++ @Override
++ public PathAndTime apply(final Path path) {
++ return new PathAndTime(path);
++ }
++ })
++ .sorted()
++ .map(new Function<PathAndTime, Path>() {
++ @Override
++ public Path apply(final PathAndTime pathAndTime) {
++ return pathAndTime.path;
++ }
++ })
++ .toArray(new IntFunction<Path[]>() { // Replace with Path::new
++ @Override
++ public Path[] apply(final int length) {
++ return new Path[length];
++ }
++ });
++ }
++ }
++
++ private static class PathAndTime implements Comparable<PathAndTime> {
++ private final Path path;
++ private final long time;
++
++ PathAndTime(final Path path) {
++ this.path = path;
++ this.time = getTime(path);
++ }
++
++ @Override
++ public int compareTo(final PathAndTime other) {
++ return Long.compare(time, other.time);
++ }
++
++ private static long getTime(final Path path) {
++ try {
++ return Files.getLastModifiedTime(path).toMillis();
++ } catch (final IOException e) {
++ // All files for which we can't retrieve the last modified date will be considered oldest.
++ return -1L;
++ }
++ }
++ }
++
++ private static int getMaxFiles() {
++ final String str = Options.getStringProperty("nashorn.typeInfo.maxFiles", null);
++ if (str == null) {
++ return DEFAULT_MAX_FILES;
++ } else if ("unlimited".equals(str)) {
++ return UNLIMITED_FILES;
++ }
++ return Math.max(0, Integer.parseInt(str));
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/ProgramPoints.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,132 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
++
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.FIRST_PROGRAM_POINT;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.MAX_PROGRAM_POINT_VALUE;
++
++import java.util.HashSet;
++import java.util.Set;
++import jdk.nashorn.internal.IntDeque;
++import jdk.nashorn.internal.ir.AccessNode;
++import jdk.nashorn.internal.ir.BinaryNode;
++import jdk.nashorn.internal.ir.CallNode;
++import jdk.nashorn.internal.ir.Expression;
++import jdk.nashorn.internal.ir.FunctionNode;
++import jdk.nashorn.internal.ir.IdentNode;
++import jdk.nashorn.internal.ir.IndexNode;
++import jdk.nashorn.internal.ir.LexicalContext;
++import jdk.nashorn.internal.ir.Node;
++import jdk.nashorn.internal.ir.Optimistic;
++import jdk.nashorn.internal.ir.UnaryNode;
++import jdk.nashorn.internal.ir.VarNode;
++import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++
++/**
++ * Find program points in the code that are needed for optimistic assumptions
++ */
++class ProgramPoints extends NodeVisitor<LexicalContext> {
++
++ private final IntDeque nextProgramPoint = new IntDeque();
++ private final Set<Node> noProgramPoint = new HashSet<>();
++
++ ProgramPoints() {
++ super(new LexicalContext());
++ }
++
++ private int next() {
++ final int next = nextProgramPoint.getAndIncrement();
++ if(next > MAX_PROGRAM_POINT_VALUE) {
++ throw new AssertionError("Function has more than " + MAX_PROGRAM_POINT_VALUE + " program points");
++ }
++ return next;
++ }
++
++ @Override
++ public boolean enterFunctionNode(final FunctionNode functionNode) {
++ nextProgramPoint.push(FIRST_PROGRAM_POINT);
++ return true;
++ }
++
++ @Override
++ public Node leaveFunctionNode(final FunctionNode functionNode) {
++ nextProgramPoint.pop();
++ return functionNode;
++ }
++
++ private Expression setProgramPoint(final Optimistic optimistic) {
++ if (noProgramPoint.contains(optimistic)) {
++ return (Expression)optimistic;
++ }
++ return (Expression)(optimistic.canBeOptimistic() ? optimistic.setProgramPoint(next()) : optimistic);
++ }
++
++ @Override
++ public boolean enterVarNode(final VarNode varNode) {
++ noProgramPoint.add(varNode.getName());
++ return true;
++ }
++
++ @Override
++ public boolean enterIdentNode(final IdentNode identNode) {
++ if (identNode.isInternal()) {
++ noProgramPoint.add(identNode);
++ }
++ return true;
++ }
++
++ @Override
++ public Node leaveIdentNode(final IdentNode identNode) {
++ if(identNode.isPropertyName()) {
++ return identNode;
++ }
++ return setProgramPoint(identNode);
++ }
++
++ @Override
++ public Node leaveCallNode(final CallNode callNode) {
++ return setProgramPoint(callNode);
++ }
++
++ @Override
++ public Node leaveAccessNode(final AccessNode accessNode) {
++ return setProgramPoint(accessNode);
++ }
++
++ @Override
++ public Node leaveIndexNode(final IndexNode indexNode) {
++ return setProgramPoint(indexNode);
++ }
++
++ @Override
++ public Node leaveBinaryNode(final BinaryNode binaryNode) {
++ return setProgramPoint(binaryNode);
++ }
++
++ @Override
++ public Node leaveUnaryNode(final UnaryNode unaryNode) {
++ return setProgramPoint(unaryNode);
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/codegen/RangeAnalyzer.java Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,475 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
+-
+-import java.util.HashMap;
+-import java.util.HashSet;
+-import java.util.Map;
+-import jdk.nashorn.internal.codegen.types.Range;
+-import jdk.nashorn.internal.codegen.types.Type;
+-import jdk.nashorn.internal.ir.Assignment;
+-import jdk.nashorn.internal.ir.BinaryNode;
+-import jdk.nashorn.internal.ir.Expression;
+-import jdk.nashorn.internal.ir.ForNode;
+-import jdk.nashorn.internal.ir.IdentNode;
+-import jdk.nashorn.internal.ir.LexicalContext;
+-import jdk.nashorn.internal.ir.LiteralNode;
+-import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
+-import jdk.nashorn.internal.ir.LoopNode;
+-import jdk.nashorn.internal.ir.Node;
+-import jdk.nashorn.internal.ir.RuntimeNode;
+-import jdk.nashorn.internal.ir.Symbol;
+-import jdk.nashorn.internal.ir.UnaryNode;
+-import jdk.nashorn.internal.ir.VarNode;
+-import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
+-import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+-import jdk.nashorn.internal.parser.TokenType;
+-import jdk.nashorn.internal.runtime.DebugLogger;
+-
+-/**
+- * Range analysis and narrowing of type where it can be proven
+- * that there is no spillover, e.g.
+- *
+- * function func(c) {
+- * var v = c & 0xfff;
+- * var w = c & 0xeee;
+- * var x = v * w;
+- * return x;
+- * }
+- *
+- * Proves that the multiplication never exceeds 24 bits and can thus be an int
+- */
+-final class RangeAnalyzer extends NodeOperatorVisitor<LexicalContext> {
+- static final DebugLogger LOG = new DebugLogger("ranges");
+-
+- private static final Range.Functionality RANGE = new Range.Functionality(LOG);
+-
+- private final Map<LoopNode, Symbol> loopCounters = new HashMap<>();
+-
+- RangeAnalyzer() {
+- super(new LexicalContext());
+- }
+-
+- @Override
+- public boolean enterForNode(final ForNode forNode) {
+- //conservatively attempt to identify the loop counter. Null means that it wasn't
+- //properly identified and that no optimizations can be made with it - its range is
+- //simply unknown in that case, if it is assigned in the loop
+- final Symbol counter = findLoopCounter(forNode);
+- LOG.fine("Entering forNode " + forNode + " counter = " + counter);
+- if (counter != null && !assignedInLoop(forNode, counter)) {
+- loopCounters.put(forNode, counter);
+- }
+- return true;
+- }
+-
+- //destination visited
+- private Symbol setRange(final Expression dest, final Range range) {
+- if (range.isUnknown()) {
+- return null;
+- }
+-
+- final Symbol symbol = dest.getSymbol();
+- assert symbol != null : dest + " " + dest.getClass() + " has no symbol";
+- assert symbol.getRange() != null : symbol + " has no range";
+- final Range symRange = RANGE.join(symbol.getRange(), range);
+-
+- //anything assigned in the loop, not being the safe loop counter(s) invalidates its entire range
+- if (lc.inLoop() && !isLoopCounter(lc.getCurrentLoop(), symbol)) {
+- symbol.setRange(Range.createGenericRange());
+- return symbol;
+- }
+-
+- if (!symRange.equals(symbol.getRange())) {
+- LOG.fine("Modify range for " + dest + " " + symbol + " from " + symbol.getRange() + " to " + symRange + " (in node = " + dest + ")" );
+- symbol.setRange(symRange);
+- }
+-
+- return null;
+- }
+-
+- @Override
+- public Node leaveADD(final BinaryNode node) {
+- setRange(node, RANGE.add(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- return node;
+- }
+-
+- @Override
+- public Node leaveSUB(final BinaryNode node) {
+- setRange(node, RANGE.sub(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- return node;
+- }
+-
+- @Override
+- public Node leaveMUL(final BinaryNode node) {
+- setRange(node, RANGE.mul(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- return node;
+- }
+-
+- @Override
+- public Node leaveDIV(final BinaryNode node) {
+- setRange(node, RANGE.div(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- return node;
+- }
+-
+- @Override
+- public Node leaveMOD(final BinaryNode node) {
+- setRange(node, RANGE.mod(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- return node;
+- }
+-
+- @Override
+- public Node leaveBIT_AND(final BinaryNode node) {
+- setRange(node, RANGE.and(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- return node;
+- }
+-
+- @Override
+- public Node leaveBIT_OR(final BinaryNode node) {
+- setRange(node, RANGE.or(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- return node;
+- }
+-
+- @Override
+- public Node leaveBIT_XOR(final BinaryNode node) {
+- setRange(node, RANGE.xor(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- return node;
+- }
+-
+- @Override
+- public Node leaveSAR(final BinaryNode node) {
+- setRange(node, RANGE.sar(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- return node;
+- }
+-
+- @Override
+- public Node leaveSHL(final BinaryNode node) {
+- setRange(node, RANGE.shl(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- return node;
+- }
+-
+- @Override
+- public Node leaveSHR(final BinaryNode node) {
+- setRange(node, RANGE.shr(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- return node;
+- }
+-
+- private Node leaveCmp(final BinaryNode node) {
+- setRange(node, Range.createTypeRange(Type.BOOLEAN));
+- return node;
+- }
+-
+- @Override
+- public Node leaveEQ(final BinaryNode node) {
+- return leaveCmp(node);
+- }
+-
+- @Override
+- public Node leaveEQ_STRICT(final BinaryNode node) {
+- return leaveCmp(node);
+- }
+-
+- @Override
+- public Node leaveNE(final BinaryNode node) {
+- return leaveCmp(node);
+- }
+-
+- @Override
+- public Node leaveNE_STRICT(final BinaryNode node) {
+- return leaveCmp(node);
+- }
+-
+- @Override
+- public Node leaveLT(final BinaryNode node) {
+- return leaveCmp(node);
+- }
+-
+- @Override
+- public Node leaveLE(final BinaryNode node) {
+- return leaveCmp(node);
+- }
+-
+- @Override
+- public Node leaveGT(final BinaryNode node) {
+- return leaveCmp(node);
+- }
+-
+- @Override
+- public Node leaveGE(final BinaryNode node) {
+- return leaveCmp(node);
+- }
+-
+- @Override
+- public Node leaveASSIGN(final BinaryNode node) {
+- Range range = node.rhs().getSymbol().getRange();
+- if (range.isUnknown()) {
+- range = Range.createGenericRange();
+- }
+-
+- setRange(node.lhs(), range);
+- setRange(node, range);
+-
+- return node;
+- }
+-
+- private Node leaveSelfModifyingAssign(final BinaryNode node, final Range range) {
+- setRange(node.lhs(), range);
+- setRange(node, range);
+- return node;
+- }
+-
+- private Node leaveSelfModifyingAssign(final UnaryNode node, final Range range) {
+- setRange(node.rhs(), range);
+- setRange(node, range);
+- return node;
+- }
+-
+- @Override
+- public Node leaveASSIGN_ADD(final BinaryNode node) {
+- return leaveSelfModifyingAssign(node, RANGE.add(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- }
+-
+- @Override
+- public Node leaveASSIGN_SUB(final BinaryNode node) {
+- return leaveSelfModifyingAssign(node, RANGE.sub(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- }
+-
+- @Override
+- public Node leaveASSIGN_MUL(final BinaryNode node) {
+- return leaveSelfModifyingAssign(node, RANGE.mul(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- }
+-
+- @Override
+- public Node leaveASSIGN_DIV(final BinaryNode node) {
+- return leaveSelfModifyingAssign(node, Range.createTypeRange(Type.NUMBER));
+- }
+-
+- @Override
+- public Node leaveASSIGN_MOD(final BinaryNode node) {
+- return leaveSelfModifyingAssign(node, Range.createTypeRange(Type.NUMBER));
+- }
+-
+- @Override
+- public Node leaveASSIGN_BIT_AND(final BinaryNode node) {
+- return leaveSelfModifyingAssign(node, RANGE.and(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- }
+-
+- @Override
+- public Node leaveASSIGN_BIT_OR(final BinaryNode node) {
+- return leaveSelfModifyingAssign(node, RANGE.or(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- }
+-
+- @Override
+- public Node leaveASSIGN_BIT_XOR(final BinaryNode node) {
+- return leaveSelfModifyingAssign(node, RANGE.xor(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- }
+-
+- @Override
+- public Node leaveASSIGN_SAR(final BinaryNode node) {
+- return leaveSelfModifyingAssign(node, RANGE.sar(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- }
+-
+- @Override
+- public Node leaveASSIGN_SHR(final BinaryNode node) {
+- return leaveSelfModifyingAssign(node, RANGE.shr(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- }
+-
+- @Override
+- public Node leaveASSIGN_SHL(final BinaryNode node) {
+- return leaveSelfModifyingAssign(node, RANGE.shl(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+- }
+-
+- @Override
+- public Node leaveDECINC(final UnaryNode node) {
+- switch (node.tokenType()) {
+- case DECPREFIX:
+- case DECPOSTFIX:
+- return leaveSelfModifyingAssign(node, RANGE.sub(node.rhs().getSymbol().getRange(), Range.createRange(1)));
+- case INCPREFIX:
+- case INCPOSTFIX:
+- return leaveSelfModifyingAssign(node, RANGE.add(node.rhs().getSymbol().getRange(), Range.createRange(1)));
+- default:
+- assert false;
+- return node;
+- }
+- }
+-
+- @Override
+- public Node leaveADD(final UnaryNode node) {
+- Range range = node.rhs().getSymbol().getRange();
+- if (!range.getType().isNumeric()) {
+- range = Range.createTypeRange(Type.NUMBER);
+- }
+- setRange(node, range);
+- return node;
+- }
+-
+- @Override
+- public Node leaveBIT_NOT(final UnaryNode node) {
+- setRange(node, Range.createTypeRange(Type.INT));
+- return node;
+- }
+-
+- @Override
+- public Node leaveNOT(final UnaryNode node) {
+- setRange(node, Range.createTypeRange(Type.BOOLEAN));
+- return node;
+- }
+-
+- @Override
+- public Node leaveSUB(final UnaryNode node) {
+- setRange(node, RANGE.neg(node.rhs().getSymbol().getRange()));
+- return node;
+- }
+-
+- @Override
+- public Node leaveVarNode(final VarNode node) {
+- if (node.isAssignment()) {
+- Range range = node.getInit().getSymbol().getRange();
+- range = range.isUnknown() ? Range.createGenericRange() : range;
+-
+- setRange(node.getName(), range);
+- }
+-
+- return node;
+- }
+-
+- @SuppressWarnings("rawtypes")
+- @Override
+- public boolean enterLiteralNode(final LiteralNode node) {
+- // ignore array literals
+- return !(node instanceof ArrayLiteralNode);
+- }
+-
+- @Override
+- public Node leaveLiteralNode(@SuppressWarnings("rawtypes") final LiteralNode node) {
+- if (node.getType().isInteger()) {
+- setRange(node, Range.createRange(node.getInt32()));
+- } else if (node.getType().isNumber()) {
+- setRange(node, Range.createRange(node.getNumber()));
+- } else if (node.getType().isLong()) {
+- setRange(node, Range.createRange(node.getLong()));
+- } else if (node.getType().isBoolean()) {
+- setRange(node, Range.createTypeRange(Type.BOOLEAN));
+- } else {
+- setRange(node, Range.createGenericRange());
+- }
+- return node;
+- }
+-
+- @Override
+- public boolean enterRuntimeNode(final RuntimeNode node) {
+- // a runtime node that cannot be specialized is no point entering
+- return node.getRequest().canSpecialize();
+- }
+-
+- /**
+- * Check whether a symbol is unsafely assigned in a loop - i.e. repeteadly assigned and
+- * not being identified as the loop counter. That means we don't really know anything
+- * about its range.
+- * @param loopNode loop node
+- * @param symbol symbol
+- * @return true if assigned in loop
+- */
+- // TODO - this currently checks for nodes only - needs to be augmented for while nodes
+- // assignment analysis is also very conservative
+- private static boolean assignedInLoop(final LoopNode loopNode, final Symbol symbol) {
+- final HashSet<Node> skip = new HashSet<>();
+- final HashSet<Node> assignmentsInLoop = new HashSet<>();
+-
+- loopNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
+- private boolean assigns(final Node node, final Symbol s) {
+- return node.isAssignment() && ((Assignment<?>)node).getAssignmentDest().getSymbol() == s;
+- }
+-
+- @Override
+- public boolean enterForNode(final ForNode forNode) {
+- if (forNode.getInit() != null) {
+- skip.add(forNode.getInit());
+- }
+- if (forNode.getModify() != null) {
+- skip.add(forNode.getModify());
+- }
+- return true;
+- }
+-
+- @Override
+- public Node leaveDefault(final Node node) {
+- //if this is an assignment to symbol
+- if (!skip.contains(node) && assigns(node, symbol)) {
+- assignmentsInLoop.add(node);
+- }
+- return node;
+- }
+- });
+-
+- return !assignmentsInLoop.isEmpty();
+- }
+-
+- /**
+- * Check for a loop counter. This is currently quite conservative, in that it only handles
+- * x <= counter and x < counter.
+- *
+- * @param node loop node to check
+- * @return
+- */
+- private static Symbol findLoopCounter(final LoopNode node) {
+- final Expression test = node.getTest();
+-
+- if (test != null && test.isComparison()) {
+- final BinaryNode binaryNode = (BinaryNode)test;
+- final Expression lhs = binaryNode.lhs();
+- final Expression rhs = binaryNode.rhs();
+-
+- //detect ident cmp int_literal
+- if (lhs instanceof IdentNode && rhs instanceof LiteralNode && ((LiteralNode<?>)rhs).getType().isInteger()) {
+- final Symbol symbol = lhs.getSymbol();
+- final int margin = ((LiteralNode<?>)rhs).getInt32();
+- final TokenType op = test.tokenType();
+-
+- switch (op) {
+- case LT:
+- case LE:
+- symbol.setRange(RANGE.join(symbol.getRange(), Range.createRange(op == TokenType.LT ? margin - 1 : margin)));
+- return symbol;
+- case GT:
+- case GE:
+- //setRange(lhs, Range.createRange(op == TokenType.GT ? margin + 1 : margin));
+- //return symbol;
+- default:
+- break;
+- }
+- }
+- }
+-
+- return null;
+- }
+-
+- private boolean isLoopCounter(final LoopNode loopNode, final Symbol symbol) {
+- //this only works if loop nodes aren't replaced by other ones during this transform, but they are not
+- return loopCounters.get(loopNode) == symbol;
+- }
+-}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/ReplaceCompileUnits.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,85 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
++
++import java.util.ArrayList;
++import java.util.List;
++import jdk.nashorn.internal.ir.CompileUnitHolder;
++import jdk.nashorn.internal.ir.FunctionNode;
++import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
++import jdk.nashorn.internal.ir.LexicalContext;
++import jdk.nashorn.internal.ir.LiteralNode;
++import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
++import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
++import jdk.nashorn.internal.ir.Node;
++import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++
++/**
++ * Base class for a node visitor that replaces {@link CompileUnit}s in {@link CompileUnitHolder}s.
++ */
++abstract class ReplaceCompileUnits extends NodeVisitor<LexicalContext> {
++ ReplaceCompileUnits() {
++ super(new LexicalContext());
++ }
++
++ /**
++ * Override to provide a replacement for an old compile unit.
++ * @param oldUnit the old compile unit to replace
++ * @return the compile unit's replacement.
++ */
++ abstract CompileUnit getReplacement(final CompileUnit oldUnit);
++
++ CompileUnit getExistingReplacement(final CompileUnitHolder node) {
++ final CompileUnit oldUnit = node.getCompileUnit();
++ assert oldUnit != null;
++
++ final CompileUnit newUnit = getReplacement(oldUnit);
++ assert newUnit != null;
++
++ return newUnit;
++ }
++
++ @Override
++ public Node leaveFunctionNode(final FunctionNode node) {
++ return node.setCompileUnit(lc, getExistingReplacement(node)).setState(lc, CompilationState.COMPILE_UNITS_REUSED);
++ }
++
++ @Override
++ public Node leaveLiteralNode(final LiteralNode<?> node) {
++ if (node instanceof ArrayLiteralNode) {
++ final ArrayLiteralNode aln = (ArrayLiteralNode)node;
++ if (aln.getUnits() == null) {
++ return node;
++ }
++ final List<ArrayUnit> newArrayUnits = new ArrayList<>();
++ for (final ArrayUnit au : aln.getUnits()) {
++ newArrayUnits.add(new ArrayUnit(getExistingReplacement(au), au.getLo(), au.getHi()));
++ }
++ return aln.setUnits(lc, newArrayUnits);
++ }
++ return node;
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java Wed Feb 04 12:14:47 2015 -0800
+@@ -42,7 +42,6 @@
+ import jdk.nashorn.internal.ir.RuntimeNode;
+ import jdk.nashorn.internal.ir.RuntimeNode.Request;
+ import jdk.nashorn.internal.lookup.Lookup;
+-import jdk.nashorn.internal.lookup.MethodHandleFactory;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+ import jdk.nashorn.internal.runtime.linker.Bootstrap;
+
+@@ -59,7 +58,7 @@
+ public final class RuntimeCallSite extends MutableCallSite {
+ static final Call BOOTSTRAP = staticCallNoLookup(Bootstrap.class, "runtimeBootstrap", CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
+
+- private static final MethodHandle NEXT = findOwnMH("next", MethodHandle.class, String.class);
++ private static final MethodHandle NEXT = findOwnMH_V("next", MethodHandle.class, String.class);
+
+ private final RuntimeNode.Request request;
+
+@@ -89,7 +88,7 @@
+ }
+
+ /**
+- * The first type to try to use for this genrated runtime node
++ * The first type to try to use for this generated runtime node
+ *
+ * @return a type
+ */
+@@ -351,19 +350,19 @@
+ /** Unbox cache */
+ private static final Map<Class<?>, MethodHandle> UNBOX;
+
+- private static final MethodHandle CHECKCAST = findOwnMH("checkcast", boolean.class, Class.class, Object.class);
+- private static final MethodHandle CHECKCAST2 = findOwnMH("checkcast", boolean.class, Class.class, Object.class, Object.class);
+- private static final MethodHandle ADDCHECK = findOwnMH("ADDcheck", boolean.class, int.class, int.class);
++ private static final MethodHandle CHECKCAST = findOwnMH_S("checkcast", boolean.class, Class.class, Object.class);
++ private static final MethodHandle CHECKCAST2 = findOwnMH_S("checkcast", boolean.class, Class.class, Object.class, Object.class);
++ private static final MethodHandle ADDCHECK = findOwnMH_S("ADDcheck", boolean.class, int.class, int.class);
+
+ /**
+ * Build maps of correct boxing operations
+ */
+ static {
+ UNBOX = new HashMap<>();
+- UNBOX.put(Boolean.class, findOwnMH("unboxZ", int.class, Object.class));
+- UNBOX.put(Integer.class, findOwnMH("unboxI", int.class, Object.class));
+- UNBOX.put(Long.class, findOwnMH("unboxJ", long.class, Object.class));
+- UNBOX.put(Number.class, findOwnMH("unboxD", double.class, Object.class));
++ UNBOX.put(Boolean.class, findOwnMH_S("unboxZ", int.class, Object.class));
++ UNBOX.put(Integer.class, findOwnMH_S("unboxI", int.class, Object.class));
++ UNBOX.put(Long.class, findOwnMH_S("unboxJ", long.class, Object.class));
++ UNBOX.put(Number.class, findOwnMH_S("unboxD", double.class, Object.class));
+
+ METHODS = new HashMap<>();
+
+@@ -375,9 +374,9 @@
+
+ final boolean isCmp = Request.isComparison(req);
+
+- METHODS.put(req.name() + "int", findOwnMH(req.name(), (isCmp ? boolean.class : int.class), int.class, int.class));
+- METHODS.put(req.name() + "long", findOwnMH(req.name(), (isCmp ? boolean.class : long.class), long.class, long.class));
+- METHODS.put(req.name() + "double", findOwnMH(req.name(), (isCmp ? boolean.class : double.class), double.class, double.class));
++ METHODS.put(req.name() + "int", findOwnMH_S(req.name(), (isCmp ? boolean.class : int.class), int.class, int.class));
++ METHODS.put(req.name() + "long", findOwnMH_S(req.name(), (isCmp ? boolean.class : long.class), long.class, long.class));
++ METHODS.put(req.name() + "double", findOwnMH_S(req.name(), (isCmp ? boolean.class : double.class), double.class, double.class));
+ }
+ }
+
+@@ -674,12 +673,11 @@
+ return ((Number)obj).doubleValue();
+ }
+
+- private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+- try {
+- return MH.findStatic(MethodHandles.lookup(), RuntimeCallSite.class, name, MH.type(rtype, types));
+- } catch (final MethodHandleFactory.LookupException e) {
+- return MH.findVirtual(MethodHandles.lookup(), RuntimeCallSite.class, name, MH.type(rtype, types));
+- }
++ private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
++ return MH.findStatic(MethodHandles.lookup(), RuntimeCallSite.class, name, MH.type(rtype, types));
+ }
+
++ private static MethodHandle findOwnMH_V(final String name, final Class<?> rtype, final Class<?>... types) {
++ return MH.findVirtual(MethodHandles.lookup(), RuntimeCallSite.class, name, MH.type(rtype, types));
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/SharedScopeCall.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/SharedScopeCall.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,8 @@
+
+ package jdk.nashorn.internal.codegen;
+
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_OPTIMISTIC;
++
+ import java.util.Arrays;
+ import java.util.EnumSet;
+ import jdk.nashorn.internal.codegen.types.Type;
+@@ -81,6 +83,7 @@
+ this.valueType = valueType;
+ this.returnType = returnType;
+ this.paramTypes = paramTypes;
++ assert (flags & CALLSITE_OPTIMISTIC) == 0;
+ this.flags = flags;
+ // If paramTypes is not null this is a call, otherwise it's just a get.
+ this.isCall = paramTypes != null;
+@@ -150,7 +153,10 @@
+ method._goto(parentLoopStart);
+ method.label(parentLoopDone);
+
+- method.dynamicGet(valueType, symbol.getName(), flags, isCall);
++ assert !isCall || valueType.isObject(); // Callables are always objects
++ // If flags are optimistic, but we're doing a call, remove optimistic flags from the getter, as they obviously
++ // only apply to the call.
++ method.dynamicGet(valueType, symbol.getName(), isCall ? CodeGenerator.nonOptimisticFlags(flags) : flags, isCall, false);
+
+ // If this is a get we're done, otherwise call the value as function.
+ if (isCall) {
+@@ -159,11 +165,10 @@
+ method.loadUndefined(Type.OBJECT);
+ int slot = 2;
+ for (final Type type : paramTypes) {
+- method.load(type, slot++);
+- if (type == Type.NUMBER || type == Type.LONG) {
+- slot++;
+- }
++ method.load(type, slot);
++ slot += type.getSlots();
+ }
++ // Shared scope calls disabled in optimistic world. TODO is this right?
+ method.dynamicCall(returnType, 2 + paramTypes.length, flags);
+ }
+
+@@ -179,17 +184,16 @@
+ final Type[] params = new Type[paramTypes.length + 2];
+ params[0] = Type.typeFor(ScriptObject.class);
+ params[1] = Type.INT;
+- int i = 2;
+- for (Type type : paramTypes) {
+- if (type.isObject()) {
+- type = Type.OBJECT;
+- }
+- params[i++] = type;
+- }
++ System.arraycopy(paramTypes, 0, params, 2, paramTypes.length);
+ staticSignature = Type.getMethodDescriptor(returnType, params);
+ }
+ }
+ return staticSignature;
+ }
+
++ @Override
++ public String toString() {
++ return methodName + " " + staticSignature;
++ }
++
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,7 +27,7 @@
+
+ import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
+-import static jdk.nashorn.internal.codegen.types.Type.OBJECT;
++import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
+
+ import java.util.LinkedHashSet;
+ import java.util.List;
+@@ -35,10 +35,11 @@
+ import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.Expression;
+ import jdk.nashorn.internal.ir.LiteralNode;
+-import jdk.nashorn.internal.ir.Symbol;
++import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.Property;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptObject;
++import jdk.nashorn.internal.runtime.ScriptRuntime;
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
+ import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
+ import jdk.nashorn.internal.scripts.JO;
+@@ -46,21 +47,16 @@
+ /**
+ * An object creator that uses spill properties.
+ */
+-public class SpillObjectCreator extends ObjectCreator {
+-
+- private final List<Expression> values;
++public final class SpillObjectCreator extends ObjectCreator<Expression> {
+
+ /**
+ * Constructor
+ *
+ * @param codegen code generator
+- * @param keys keys for fields in object
+- * @param symbols symbols for fields in object
+- * @param values list of values corresponding to keys
++ * @param tuples tuples for key, symbol, value
+ */
+- protected SpillObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final List<Expression> values) {
+- super(codegen, keys, symbols, false, false);
+- this.values = values;
++ SpillObjectCreator(final CodeGenerator codegen, final List<MapTuple<Expression>> tuples) {
++ super(codegen, tuples, false, false);
+ makeMap();
+ }
+
+@@ -68,82 +64,123 @@
+ protected void makeObject(final MethodEmitter method) {
+ assert !isScope() : "spill scope objects are not currently supported";
+
+- final int length = keys.size();
+- final Object[] presetValues = new Object[length];
++ final int length = tuples.size();
++ final long[] jpresetValues = new long[ScriptObject.spillAllocationLength(length)];
++ final Object[] opresetValues = new Object[ScriptObject.spillAllocationLength(length)];
+ final Set<Integer> postsetValues = new LinkedHashSet<>();
+ final int callSiteFlags = codegen.getCallSiteFlags();
+- ArrayData arrayData = ArrayData.allocate(new Object[0]);
++ ArrayData arrayData = ArrayData.allocate(ScriptRuntime.EMPTY_ARRAY);
+
+ // Compute constant property values
+- for (int i = 0; i < length; i++) {
+- final String key = keys.get(i);
+- final Expression value = values.get(i);
++ int pos = 0;
++ for (final MapTuple<Expression> tuple : tuples) {
++ final String key = tuple.key;
++ final Expression value = tuple.value;
+
+- if (value == null) {
+- continue; // getter or setter
+- }
++ //this is a nop of tuple.key isn't e.g. "apply" or another special name
++ method.invalidateSpecialName(tuple.key);
+
+- final Object constantValue = LiteralNode.objectAsConstant(value);
+- if (constantValue == LiteralNode.POSTSET_MARKER) {
+- postsetValues.add(i);
+- continue;
+- }
++ if (value != null) {
++ final Object constantValue = LiteralNode.objectAsConstant(value);
++ if (constantValue == LiteralNode.POSTSET_MARKER) {
++ postsetValues.add(pos);
++ } else {
++ final Property property = propertyMap.findProperty(key);
++ if (property != null) {
++ // normal property key
++ property.setType(JSType.unboxedFieldType(constantValue));
++ final int slot = property.getSlot();
++ if (!OBJECT_FIELDS_ONLY && constantValue instanceof Number) {
++ jpresetValues[slot] = ObjectClassGenerator.pack((Number)constantValue);
++ } else {
++ opresetValues[slot] = constantValue;
++ }
++ } else {
++ // array index key
++ final long oldLength = arrayData.length();
++ final int index = ArrayIndex.getArrayIndex(key);
++ final long longIndex = ArrayIndex.toLongIndex(index);
+
+- final Property property = propertyMap.findProperty(key);
+- if (property != null) {
+- // normal property key
+- presetValues[property.getSlot()] = constantValue;
+- } else {
+- // array index key
+- final long oldLength = arrayData.length();
+- final int index = ArrayIndex.getArrayIndex(key);
+- assert ArrayIndex.isValidArrayIndex(index);
+- final long longIndex = ArrayIndex.toLongIndex(index);
+- if (longIndex >= oldLength) {
+- arrayData = arrayData.ensure(longIndex);
+- }
+- arrayData = arrayData.set(index, constantValue, false);
+- if (longIndex > oldLength) {
+- arrayData = arrayData.delete(oldLength, longIndex - 1);
++ assert ArrayIndex.isValidArrayIndex(index);
++
++ if (longIndex >= oldLength) {
++ arrayData = arrayData.ensure(longIndex);
++ }
++
++ //avoid blowing up the array if we can
++ if (constantValue instanceof Integer) {
++ arrayData = arrayData.set(index, ((Integer)constantValue).intValue(), false);
++ } else if (constantValue instanceof Long) {
++ arrayData = arrayData.set(index, ((Long)constantValue).longValue(), false);
++ } else if (constantValue instanceof Double) {
++ arrayData = arrayData.set(index, ((Double)constantValue).doubleValue(), false);
++ } else {
++ arrayData = arrayData.set(index, constantValue, false);
++ }
++
++ if (longIndex > oldLength) {
++ arrayData = arrayData.delete(oldLength, longIndex - 1);
++ }
++ }
+ }
+ }
++ pos++;
+ }
+
++ //assert postsetValues.isEmpty() : "test me " + postsetValues;
++
+ // create object and invoke constructor
+ method._new(JO.class).dup();
+ codegen.loadConstant(propertyMap);
+- method.invoke(constructorNoLookup(JO.class, PropertyMap.class));
+
+- // Set spill array with preset values
+- method.dup();
+- codegen.loadConstant(presetValues);
+- method.putField(Type.getInternalName(ScriptObject.class), "spill", Type.OBJECT_ARRAY.getDescriptor());
++ //load primitive values to j spill array
++ codegen.loadConstant(jpresetValues);
++ for (final int i : postsetValues) {
++ final MapTuple<Expression> tuple = tuples.get(i);
++ final Property property = propertyMap.findProperty(tuple.key);
++ if (property != null && tuple.isPrimitive()) {
++ method.dup();
++ method.load(property.getSlot());
++ loadTuple(method, tuple);
++ method.arraystore();
++ }
++ }
+
+- // Set array data if any
++ //load object values to o spill array
++ codegen.loadConstant(opresetValues);
++ for (final int i : postsetValues) {
++ final MapTuple<Expression> tuple = tuples.get(i);
++ final Property property = propertyMap.findProperty(tuple.key);
++ if (property != null && !tuple.isPrimitive()) {
++ method.dup();
++ method.load(property.getSlot());
++ loadTuple(method, tuple);
++ method.arraystore();
++ }
++ }
++
++ //instantiate the script object with spill objects
++ method.invoke(constructorNoLookup(JO.class, PropertyMap.class, long[].class, Object[].class));
++
++ // Set prefix array data if any
+ if (arrayData.length() > 0) {
+ method.dup();
+ codegen.loadConstant(arrayData);
+- method.invoke(virtualCallNoLookup(ScriptObject.class, "setArray",void.class, ArrayData.class));
++ method.invoke(virtualCallNoLookup(ScriptObject.class, "setArray", void.class, ArrayData.class));
+ }
+
+- // Create properties with non-constant values
+- for (int i : postsetValues) {
+- final String key = keys.get(i);
+- final Property property = propertyMap.findProperty(key);
+-
++ // set postfix
++ for (final int i : postsetValues) {
++ final MapTuple<Expression> tuple = tuples.get(i);
++ final Property property = propertyMap.findProperty(tuple.key);
+ if (property == null) {
+- final int index = ArrayIndex.getArrayIndex(key);
++ final int index = ArrayIndex.getArrayIndex(tuple.key);
+ assert ArrayIndex.isValidArrayIndex(index);
+ method.dup();
+ method.load(ArrayIndex.toLongIndex(index));
+- codegen.load(values.get(i));
++ //method.println("putting " + tuple + " into arraydata");
++ loadTuple(method, tuple);
+ method.dynamicSetIndex(callSiteFlags);
+- } else {
+- method.dup();
+- method.getField(Type.getInternalName(ScriptObject.class), "spill", Type.OBJECT_ARRAY.getDescriptor());
+- method.load(property.getSlot());
+- codegen.load(values.get(i), OBJECT);
+- method.arraystore();
+ }
+ }
+ }
+@@ -151,14 +188,12 @@
+ @Override
+ protected PropertyMap makeMap() {
+ assert propertyMap == null : "property map already initialized";
+-
+- propertyMap = new MapCreator(JO.class, keys, symbols) {
+- @Override
+- protected int getPropertyFlags(Symbol symbol, boolean hasArguments) {
+- return super.getPropertyFlags(symbol, hasArguments) | Property.IS_SPILL | Property.IS_ALWAYS_OBJECT;
+- }
+- }.makeSpillMap(false);
+-
++ propertyMap = new MapCreator<>(JO.class, tuples).makeSpillMap(false);
+ return propertyMap;
+ }
++
++ @Override
++ protected void loadValue(final Expression expr, final Type type) {
++ codegen.loadExpressionAsType(expr, type);
++ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/SplitIntoFunctions.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,446 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
++
++import static jdk.nashorn.internal.ir.Node.NO_FINISH;
++import static jdk.nashorn.internal.ir.Node.NO_LINE_NUMBER;
++import static jdk.nashorn.internal.ir.Node.NO_TOKEN;
++
++import java.util.ArrayDeque;
++import java.util.ArrayList;
++import java.util.Arrays;
++import java.util.Collections;
++import java.util.Deque;
++import java.util.List;
++import java.util.Objects;
++import jdk.nashorn.internal.ir.AccessNode;
++import jdk.nashorn.internal.ir.BinaryNode;
++import jdk.nashorn.internal.ir.Block;
++import jdk.nashorn.internal.ir.BlockLexicalContext;
++import jdk.nashorn.internal.ir.BreakNode;
++import jdk.nashorn.internal.ir.CallNode;
++import jdk.nashorn.internal.ir.CaseNode;
++import jdk.nashorn.internal.ir.ContinueNode;
++import jdk.nashorn.internal.ir.Expression;
++import jdk.nashorn.internal.ir.ExpressionStatement;
++import jdk.nashorn.internal.ir.FunctionNode;
++import jdk.nashorn.internal.ir.GetSplitState;
++import jdk.nashorn.internal.ir.IdentNode;
++import jdk.nashorn.internal.ir.IfNode;
++import jdk.nashorn.internal.ir.JumpStatement;
++import jdk.nashorn.internal.ir.LiteralNode;
++import jdk.nashorn.internal.ir.Node;
++import jdk.nashorn.internal.ir.ReturnNode;
++import jdk.nashorn.internal.ir.SetSplitState;
++import jdk.nashorn.internal.ir.SplitNode;
++import jdk.nashorn.internal.ir.SplitReturn;
++import jdk.nashorn.internal.ir.Statement;
++import jdk.nashorn.internal.ir.SwitchNode;
++import jdk.nashorn.internal.ir.VarNode;
++import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++import jdk.nashorn.internal.parser.Token;
++import jdk.nashorn.internal.parser.TokenType;
++
++/**
++ * A node visitor that replaces {@link SplitNode}s with anonymous function invocations and some additional constructs
++ * to support control flow across splits. By using this transformation, split functions are translated into ordinary
++ * JavaScript functions with nested anonymous functions. The transformations however introduce several AST nodes that
++ * have no JavaScript source representations ({@link GetSplitState}, {@link SetSplitState}, and {@link SplitReturn}),
++ * and therefore such function is no longer reparseable from its source. For that reason, split functions and their
++ * fragments are serialized in-memory and deserialized when they need to be recompiled either for deoptimization or
++ * for type specialization.
++ * NOTE: all {@code leave*()} methods for statements are returning their input nodes. That way, they will not mutate
++ * the original statement list in the block containing the statement, which is fine, as it'll be replaced by the
++ * lexical context when the block is left. If we returned something else (e.g. null), we'd cause a mutation in the
++ * enclosing block's statement list that is otherwise overwritten later anyway.
++ */
++final class SplitIntoFunctions extends NodeVisitor<BlockLexicalContext> {
++ private static final int FALLTHROUGH_STATE = -1;
++ private static final int RETURN_STATE = 0;
++ private static final int BREAK_STATE = 1;
++ private static final int FIRST_JUMP_STATE = 2;
++
++ private static final String THIS_NAME = CompilerConstants.THIS.symbolName();
++ private static final String RETURN_NAME = CompilerConstants.RETURN.symbolName();
++ // Used as the name of the formal parameter for passing the current value of :return symbol into a split fragment.
++ private static final String RETURN_PARAM_NAME = RETURN_NAME + "-in";
++
++ private final Deque<FunctionState> functionStates = new ArrayDeque<>();
++ private final Deque<SplitState> splitStates = new ArrayDeque<>();
++ private final Namespace namespace;
++
++ private boolean artificialBlock = false;
++
++ // -1 is program; we need to use negative ones
++ private int nextFunctionId = -2;
++
++ public SplitIntoFunctions(final Compiler compiler) {
++ super(new BlockLexicalContext() {
++ @Override
++ protected Block afterSetStatements(Block block) {
++ for(Statement stmt: block.getStatements()) {
++ assert !(stmt instanceof SplitNode);
++ }
++ return block;
++ }
++ });
++ namespace = new Namespace(compiler.getScriptEnvironment().getNamespace());
++ }
++
++ @Override
++ public boolean enterFunctionNode(final FunctionNode functionNode) {
++ functionStates.push(new FunctionState(functionNode));
++ return true;
++ }
++
++ @Override
++ public Node leaveFunctionNode(final FunctionNode functionNode) {
++ functionStates.pop();
++ return functionNode;
++ }
++
++ @Override
++ protected Node leaveDefault(final Node node) {
++ if (node instanceof Statement) {
++ appendStatement((Statement)node);
++ }
++ return node;
++ }
++
++ @Override
++ public boolean enterSplitNode(final SplitNode splitNode) {
++ getCurrentFunctionState().splitDepth++;
++ splitStates.push(new SplitState(splitNode));
++ return true;
++ }
++
++ @Override
++ public Node leaveSplitNode(final SplitNode splitNode) {
++ // Replace the split node with an anonymous function expression call.
++
++ final FunctionState fnState = getCurrentFunctionState();
++
++ final String name = splitNode.getName();
++ Block body = splitNode.getBody();
++ final int firstLineNumber = body.getFirstStatementLineNumber();
++ final long token = body.getToken();
++ final int finish = body.getFinish();
++
++ final FunctionNode originalFn = fnState.fn;
++ assert originalFn == lc.getCurrentFunction();
++ final boolean isProgram = originalFn.isProgram();
++
++ // Change SplitNode({...}) into "function () { ... }", or "function (:return-in) () { ... }" (for program)
++ final long newFnToken = Token.toDesc(TokenType.FUNCTION, nextFunctionId--, 0);
++ final FunctionNode fn = new FunctionNode(
++ originalFn.getSource(),
++ body.getFirstStatementLineNumber(),
++ newFnToken,
++ finish,
++ NO_TOKEN,
++ namespace,
++ createIdent(name),
++ originalFn.getName() + "$" + name,
++ isProgram ? Collections.singletonList(createReturnParamIdent()) : Collections.<IdentNode>emptyList(),
++ FunctionNode.Kind.NORMAL,
++ // We only need IS_SPLIT conservatively, in case it contains any array units so that we force
++ // the :callee's existence, to force :scope to never be in a slot lower than 2. This is actually
++ // quite a horrible hack to do with CodeGenerator.fixScopeSlot not trampling other parameters
++ // and should go away once we no longer have array unit handling in codegen. Note however that
++ // we still use IS_SPLIT as the criteria in CompilationPhase.SERIALIZE_SPLIT_PHASE.
++ FunctionNode.IS_ANONYMOUS | FunctionNode.USES_ANCESTOR_SCOPE | FunctionNode.IS_SPLIT
++ )
++ .setBody(lc, body)
++ .setCompileUnit(lc, splitNode.getCompileUnit())
++ .copyCompilationState(lc, originalFn);
++
++ // Call the function:
++ // either "(function () { ... }).call(this)"
++ // or "(function (:return-in) { ... }).call(this, :return)"
++ // NOTE: Function.call() has optimized linking that basically does a pass-through to the function being invoked.
++ // NOTE: CompilationPhase.PROGRAM_POINT_PHASE happens after this, so these calls are subject to optimistic
++ // assumptions on their return value (when they return a value), as they should be.
++ final IdentNode thisIdent = createIdent(THIS_NAME);
++ final CallNode callNode = new CallNode(firstLineNumber, token, finish, new AccessNode(NO_TOKEN, NO_FINISH, fn, "call"),
++ isProgram ? Arrays.<Expression>asList(thisIdent, createReturnIdent())
++ : Collections.<Expression>singletonList(thisIdent),
++ false);
++
++ final SplitState splitState = splitStates.pop();
++ fnState.splitDepth--;
++
++ final Expression callWithReturn;
++ final boolean hasReturn = splitState.hasReturn;
++ if (hasReturn && fnState.splitDepth > 0) {
++ final SplitState parentSplit = splitStates.peek();
++ if (parentSplit != null) {
++ // Propagate hasReturn to parent split
++ parentSplit.hasReturn = true;
++ }
++ }
++ if (hasReturn || isProgram) {
++ // capture return value: ":return = (function () { ... })();"
++ callWithReturn = new BinaryNode(Token.recast(token, TokenType.ASSIGN), createReturnIdent(), callNode);
++ } else {
++ // no return value, just call : "(function () { ... })();"
++ callWithReturn = callNode;
++ }
++ appendStatement(new ExpressionStatement(firstLineNumber, token, finish, callWithReturn));
++
++ Statement splitStateHandler;
++
++ final List<JumpStatement> jumpStatements = splitState.jumpStatements;
++ final int jumpCount = jumpStatements.size();
++ // There are jumps (breaks or continues) that need to be propagated outside the split node. We need to
++ // set up a switch statement for them:
++ // switch(:scope.getScopeState()) { ... }
++ if (jumpCount > 0) {
++ final List<CaseNode> cases = new ArrayList<>(jumpCount + (hasReturn ? 1 : 0));
++ if (hasReturn) {
++ // If the split node also contained a return, we'll slip it as a case in the switch statement
++ addCase(cases, RETURN_STATE, createReturnFromSplit());
++ }
++ int i = FIRST_JUMP_STATE;
++ for (final JumpStatement jump: jumpStatements) {
++ addCase(cases, i++, enblockAndVisit(jump));
++ }
++ splitStateHandler = new SwitchNode(NO_LINE_NUMBER, token, finish, GetSplitState.INSTANCE, cases, null);
++ } else {
++ splitStateHandler = null;
++ }
++
++ // As the switch statement itself is breakable, an unlabelled break can't be in the switch statement,
++ // so we need to test for it separately.
++ if (splitState.hasBreak) {
++ // if(:scope.getScopeState() == Scope.BREAK) { break; }
++ splitStateHandler = makeIfStateEquals(firstLineNumber, token, finish, BREAK_STATE,
++ enblockAndVisit(new BreakNode(NO_LINE_NUMBER, token, finish, null)), splitStateHandler);
++ }
++
++ // Finally, if the split node had a return statement, but there were no external jumps, we didn't have
++ // the switch statement to handle the return, so we need a separate if for it.
++ if (hasReturn && jumpCount == 0) {
++ // if (:scope.getScopeState() == Scope.RETURN) { return :return; }
++ splitStateHandler = makeIfStateEquals(NO_LINE_NUMBER, token, finish, RETURN_STATE,
++ createReturnFromSplit(), splitStateHandler);
++ }
++
++ if (splitStateHandler != null) {
++ appendStatement(splitStateHandler);
++ }
++
++ return splitNode;
++ }
++
++ private static void addCase(final List<CaseNode> cases, final int i, final Block body) {
++ cases.add(new CaseNode(NO_TOKEN, NO_FINISH, intLiteral(i), body));
++ }
++
++ private static LiteralNode<Number> intLiteral(final int i) {
++ return LiteralNode.newInstance(NO_TOKEN, NO_FINISH, i);
++ }
++
++ private static Block createReturnFromSplit() {
++ return new Block(NO_TOKEN, NO_FINISH, createReturnReturn());
++ }
++
++ private static ReturnNode createReturnReturn() {
++ return new ReturnNode(NO_LINE_NUMBER, NO_TOKEN, NO_FINISH, createReturnIdent());
++ }
++
++ private static IdentNode createReturnIdent() {
++ return createIdent(RETURN_NAME);
++ }
++
++ private static IdentNode createReturnParamIdent() {
++ return createIdent(RETURN_PARAM_NAME);
++ }
++
++ private static IdentNode createIdent(final String name) {
++ return new IdentNode(NO_TOKEN, NO_FINISH, name);
++ }
++
++ private Block enblockAndVisit(final JumpStatement jump) {
++ artificialBlock = true;
++ final Block block = (Block)new Block(NO_TOKEN, NO_FINISH, jump).accept(this);
++ artificialBlock = false;
++ return block;
++ }
++
++ private static IfNode makeIfStateEquals(final int lineNumber, final long token, final int finish,
++ final int value, final Block pass, final Statement fail) {
++ return new IfNode(lineNumber, token, finish,
++ new BinaryNode(Token.recast(token, TokenType.EQ_STRICT),
++ GetSplitState.INSTANCE, intLiteral(value)),
++ pass,
++ fail == null ? null : new Block(NO_TOKEN, NO_FINISH, fail));
++ }
++
++ @Override
++ public boolean enterVarNode(VarNode varNode) {
++ if (!inSplitNode()) {
++ return super.enterVarNode(varNode);
++ }
++ assert !varNode.isBlockScoped(); //TODO: we must handle these too, but we currently don't
++
++ final Expression init = varNode.getInit();
++ if (varNode.isAnonymousFunctionDeclaration()) {
++ // We ain't moving anonymous function declarations.
++ return super.enterVarNode(varNode);
++ }
++
++ // Move a declaration-only var statement to the top of the outermost function.
++ getCurrentFunctionState().varStatements.add(varNode.setInit(null));
++ // If it had an initializer, replace it with an assignment expression statement. Note that "var" is a
++ // statement, so it doesn't contribute to :return of the programs, therefore we are _not_ adding a
++ // ":return = ..." assignment around the original assignment.
++ if (init != null) {
++ final long token = Token.recast(varNode.getToken(), TokenType.ASSIGN);
++ new ExpressionStatement(varNode.getLineNumber(), token, varNode.getFinish(),
++ new BinaryNode(token, varNode.getName(), varNode.getInit())).accept(this);
++ }
++
++ return false;
++ }
++
++ @Override
++ public Node leaveBlock(final Block block) {
++ if (!artificialBlock) {
++ if (lc.isFunctionBody()) {
++ // Prepend declaration-only var statements to the top of the statement list.
++ lc.prependStatements(getCurrentFunctionState().varStatements);
++ } else if (lc.isSplitBody()) {
++ appendSplitReturn(FALLTHROUGH_STATE, NO_LINE_NUMBER);
++ if (getCurrentFunctionState().fn.isProgram()) {
++ // If we're splitting the program, make sure every shard ends with "return :return" and
++ // begins with ":return = :return-in;".
++ lc.prependStatement(new ExpressionStatement(NO_LINE_NUMBER, NO_TOKEN, NO_FINISH,
++ new BinaryNode(Token.toDesc(TokenType.ASSIGN, 0, 0), createReturnIdent(), createReturnParamIdent())));
++ }
++ }
++ }
++ return block;
++ }
++
++ @Override
++ public Node leaveBreakNode(final BreakNode breakNode) {
++ return leaveJumpNode(breakNode);
++ }
++
++ @Override
++ public Node leaveContinueNode(final ContinueNode continueNode) {
++ return leaveJumpNode(continueNode);
++ }
++
++ private JumpStatement leaveJumpNode(final JumpStatement jump) {
++ if (inSplitNode()) {
++ final SplitState splitState = getCurrentSplitState();
++ final SplitNode splitNode = splitState.splitNode;
++ if (lc.isExternalTarget(splitNode, jump.getTarget(lc))) {
++ appendSplitReturn(splitState.getSplitStateIndex(jump), jump.getLineNumber());
++ return jump;
++ }
++ }
++ appendStatement(jump);
++ return jump;
++ }
++
++ private void appendSplitReturn(final int splitState, final int lineNumber) {
++ appendStatement(new SetSplitState(splitState, lineNumber));
++ if (getCurrentFunctionState().fn.isProgram()) {
++ // If we're splitting the program, make sure every fragment passes back :return
++ appendStatement(createReturnReturn());
++ } else {
++ appendStatement(SplitReturn.INSTANCE);
++ }
++ }
++
++ @Override
++ public Node leaveReturnNode(final ReturnNode returnNode) {
++ if(inSplitNode()) {
++ appendStatement(new SetSplitState(RETURN_STATE, returnNode.getLineNumber()));
++ getCurrentSplitState().hasReturn = true;
++ }
++ appendStatement(returnNode);
++ return returnNode;
++ }
++
++ private void appendStatement(final Statement statement) {
++ lc.appendStatement(statement);
++ }
++
++ private boolean inSplitNode() {
++ return getCurrentFunctionState().splitDepth > 0;
++ }
++
++ private FunctionState getCurrentFunctionState() {
++ return functionStates.peek();
++ }
++
++ private SplitState getCurrentSplitState() {
++ return splitStates.peek();
++ }
++
++ private static class FunctionState {
++ final FunctionNode fn;
++ final List<Statement> varStatements = new ArrayList<>();
++ int splitDepth;
++
++ FunctionState(final FunctionNode fn) {
++ this.fn = fn;
++ }
++ }
++
++ private static class SplitState {
++ final SplitNode splitNode;
++ boolean hasReturn;
++ boolean hasBreak;
++
++ final List<JumpStatement> jumpStatements = new ArrayList<>();
++
++ int getSplitStateIndex(final JumpStatement jump) {
++ if (jump instanceof BreakNode && jump.getLabelName() == null) {
++ // Unlabelled break is a special case
++ hasBreak = true;
++ return BREAK_STATE;
++ }
++
++ int i = 0;
++ for(final JumpStatement exJump: jumpStatements) {
++ if (jump.getClass() == exJump.getClass() && Objects.equals(jump.getLabelName(), exJump.getLabelName())) {
++ return i + FIRST_JUMP_STATE;
++ }
++ ++i;
++ }
++ jumpStatements.add(jump);
++ return i + FIRST_JUMP_STATE;
++ }
++
++ SplitState(final SplitNode splitNode) {
++ this.splitNode = splitNode;
++ }
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/codegen/SplitMethodEmitter.java Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,100 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
+-
+-import java.util.ArrayList;
+-import java.util.List;
+-
+-import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
+-
+-import jdk.internal.org.objectweb.asm.MethodVisitor;
+-import jdk.nashorn.internal.codegen.types.Type;
+-import jdk.nashorn.internal.ir.LexicalContext;
+-import jdk.nashorn.internal.ir.SplitNode;
+-import jdk.nashorn.internal.runtime.Scope;
+-
+-/**
+- * Emitter used for splitting methods. Needs to keep track of if there are jump targets
+- * outside the current split node. All external jump targets encountered at method
+- * emission are logged, and {@code CodeGenerator#leaveSplitNode(SplitNode)} creates
+- * an appropriate jump table when the SplitNode has been iterated through
+- */
+-public class SplitMethodEmitter extends MethodEmitter {
+-
+- private final SplitNode splitNode;
+-
+- private final List<Label> externalTargets = new ArrayList<>();
+-
+- SplitMethodEmitter(final ClassEmitter classEmitter, final MethodVisitor mv, SplitNode splitNode) {
+- super(classEmitter, mv);
+- this.splitNode = splitNode;
+- }
+-
+- @Override
+- void splitAwareGoto(final LexicalContext lc, final Label label) {
+- assert splitNode != null;
+- final int index = findExternalTarget(lc, label);
+- if (index >= 0) {
+- loadCompilerConstant(SCOPE);
+- checkcast(Scope.class);
+- load(index + 1);
+- invoke(Scope.SET_SPLIT_STATE);
+- loadUndefined(Type.OBJECT);
+- _return(functionNode.getReturnType());
+- return;
+- }
+- super.splitAwareGoto(lc, label);
+- }
+-
+- private int findExternalTarget(final LexicalContext lc, final Label label) {
+- final int index = externalTargets.indexOf(label);
+-
+- if (index >= 0) {
+- return index;
+- }
+-
+- if (lc.isExternalTarget(splitNode, label)) {
+- externalTargets.add(label);
+- return externalTargets.size() - 1;
+- }
+- return -1;
+- }
+-
+- @Override
+- MethodEmitter registerReturn() {
+- setHasReturn();
+- loadCompilerConstant(SCOPE);
+- checkcast(Scope.class);
+- load(0);
+- invoke(Scope.SET_SPLIT_STATE);
+- return this;
+- }
+-
+- @Override
+- final List<Label> getExternalTargets() {
+- return externalTargets;
+- }
+-}
+--- ./nashorn/src/jdk/nashorn/internal/codegen/Splitter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/Splitter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -42,7 +42,7 @@
+ import jdk.nashorn.internal.ir.SplitNode;
+ import jdk.nashorn.internal.ir.Statement;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+-import jdk.nashorn.internal.runtime.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
+ import jdk.nashorn.internal.runtime.options.Options;
+
+ /**
+@@ -64,7 +64,7 @@
+ /** Weight threshold for when to start a split. */
+ public static final long SPLIT_THRESHOLD = Options.getIntProperty("nashorn.compiler.splitter.threshold", 32 * 1024);
+
+- private static final DebugLogger LOG = Compiler.LOG;
++ private final DebugLogger log;
+
+ /**
+ * Constructor.
+@@ -78,30 +78,27 @@
+ this.compiler = compiler;
+ this.outermost = functionNode;
+ this.outermostCompileUnit = outermostCompileUnit;
++ this.log = compiler.getLogger();
+ }
+
+ /**
+- * Execute the split
++ * Execute the split.
++ * @param fn the function to split
++ * @param top whether this is the topmost compiled function (it's either a program, or we're doing a recompilation).
+ */
+- FunctionNode split(final FunctionNode fn) {
++ FunctionNode split(final FunctionNode fn, final boolean top) {
+ FunctionNode functionNode = fn;
+
+- if (functionNode.isLazy()) {
+- LOG.finest("Postponing split of '", functionNode.getName(), "' as it's lazy");
+- return functionNode;
+- }
+-
+- LOG.finest("Initiating split of '", functionNode.getName(), "'");
++ log.finest("Initiating split of '", functionNode.getName(), "'");
+
+ long weight = WeighNodes.weigh(functionNode);
+- final boolean top = fn.isProgram(); //compiler.getFunctionNode() == outermost;
+
+ // We know that our LexicalContext is empty outside the call to functionNode.accept(this) below,
+ // so we can pass null to all methods expecting a LexicalContext parameter.
+ assert lc.isEmpty() : "LexicalContext not empty";
+
+ if (weight >= SPLIT_THRESHOLD) {
+- LOG.finest("Splitting '", functionNode.getName(), "' as its weight ", weight, " exceeds split threshold ", SPLIT_THRESHOLD);
++ log.finest("Splitting '", functionNode.getName(), "' as its weight ", weight, " exceeds split threshold ", SPLIT_THRESHOLD);
+ functionNode = (FunctionNode)functionNode.accept(this);
+
+ if (functionNode.isSplit()) {
+@@ -138,7 +135,7 @@
+
+ @Override
+ public Node leaveFunctionNode(final FunctionNode nestedFunction) {
+- FunctionNode split = new Splitter(compiler, nestedFunction, outermostCompileUnit).split(nestedFunction);
++ final FunctionNode split = new Splitter(compiler, nestedFunction, outermostCompileUnit).split(nestedFunction, false);
+ lc.replace(nestedFunction, split);
+ return split;
+ }
+@@ -310,7 +307,7 @@
+ units.add(new ArrayUnit(unit, lo, postsets.length));
+ }
+
+- arrayLiteralNode.setUnits(units);
++ return arrayLiteralNode.setUnits(lc, units);
+ }
+
+ return literal;
+@@ -319,10 +316,7 @@
+ @Override
+ public boolean enterFunctionNode(final FunctionNode node) {
+ //only go into the function node for this splitter. any subfunctions are rejected
+- if (node == outermost && !node.isLazy()) {
+- return true;
+- }
+- return false;
++ return node == outermost;
+ }
+ }
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/TypeEvaluator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,250 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
++
++import static jdk.nashorn.internal.runtime.Property.NOT_CONFIGURABLE;
++import static jdk.nashorn.internal.runtime.Property.NOT_ENUMERABLE;
++import static jdk.nashorn.internal.runtime.Property.NOT_WRITABLE;
++
++import java.lang.invoke.MethodType;
++import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.ir.AccessNode;
++import jdk.nashorn.internal.ir.CallNode;
++import jdk.nashorn.internal.ir.Expression;
++import jdk.nashorn.internal.ir.FunctionNode;
++import jdk.nashorn.internal.ir.IdentNode;
++import jdk.nashorn.internal.ir.IndexNode;
++import jdk.nashorn.internal.ir.Optimistic;
++import jdk.nashorn.internal.objects.ArrayBufferView;
++import jdk.nashorn.internal.objects.NativeArray;
++import jdk.nashorn.internal.runtime.FindProperty;
++import jdk.nashorn.internal.runtime.JSType;
++import jdk.nashorn.internal.runtime.Property;
++import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
++import jdk.nashorn.internal.runtime.ScriptFunction;
++import jdk.nashorn.internal.runtime.ScriptObject;
++import jdk.nashorn.internal.runtime.ScriptRuntime;
++
++/**
++ * Functionality for using a runtime scope to look up value types.
++ * Used during recompilation.
++ */
++final class TypeEvaluator {
++ /**
++ * Type signature for invocation of functions without parameters: we must pass (callee, this) of type
++ * (ScriptFunction, Object) respectively. We also use Object as the return type (we must pass something,
++ * but it'll be ignored; it can't be void, though).
++ */
++ private static final MethodType EMPTY_INVOCATION_TYPE = MethodType.methodType(Object.class, ScriptFunction.class, Object.class);
++
++ private final Compiler compiler;
++ private final ScriptObject runtimeScope;
++
++ TypeEvaluator(final Compiler compiler, final ScriptObject runtimeScope) {
++ this.compiler = compiler;
++ this.runtimeScope = runtimeScope;
++ }
++
++ /**
++ * Returns true if the expression can be safely evaluated, and its value is an object known to always use
++ * String as the type of its property names retrieved through
++ * {@link ScriptRuntime#toPropertyIterator(Object)}. It is used to avoid optimistic assumptions about its
++ * property name types.
++ * @param expr the expression to test
++ * @return true if the expression can be safely evaluated, and its value is an object known to always use
++ * String as the type of its property iterators.
++ */
++ boolean hasStringPropertyIterator(final Expression expr) {
++ return evaluateSafely(expr) instanceof ScriptObject;
++ }
++
++ Type getOptimisticType(final Optimistic node) {
++ assert compiler.useOptimisticTypes();
++
++ final int programPoint = node.getProgramPoint();
++ final Type validType = compiler.getInvalidatedProgramPointType(programPoint);
++
++ if (validType != null) {
++ return validType;
++ }
++
++ final Type mostOptimisticType = node.getMostOptimisticType();
++ final Type evaluatedType = getEvaluatedType(node);
++
++ if (evaluatedType != null) {
++ if (evaluatedType.widerThan(mostOptimisticType)) {
++ final Type newValidType = evaluatedType.isObject() || evaluatedType.isBoolean() ? Type.OBJECT : evaluatedType;
++ // Update invalidatedProgramPoints so we don't re-evaluate the expression next time. This is a heuristic
++ // as we're doing a tradeoff. Re-evaluating expressions on each recompile takes time, but it might
++ // notice a widening in the type of the expression and thus prevent an unnecessary deoptimization later.
++ // We'll presume though that the types of expressions are mostly stable, so if we evaluated it in one
++ // compilation, we'll keep to that and risk a low-probability deoptimization if its type gets widened
++ // in the future.
++ compiler.addInvalidatedProgramPoint(node.getProgramPoint(), newValidType);
++ }
++ return evaluatedType;
++ }
++ return mostOptimisticType;
++ }
++
++ private static Type getPropertyType(final ScriptObject sobj, final String name) {
++ final FindProperty find = sobj.findProperty(name, true);
++ if (find == null) {
++ return null;
++ }
++
++ final Property property = find.getProperty();
++ final Class<?> propertyClass = property.getType();
++ if (propertyClass == null) {
++ // propertyClass == null means its value is Undefined. It is probably not initialized yet, so we won't make
++ // a type assumption yet.
++ return null;
++ } else if (propertyClass.isPrimitive()) {
++ return Type.typeFor(propertyClass);
++ }
++
++ final ScriptObject owner = find.getOwner();
++ if (property.hasGetterFunction(owner)) {
++ // Can have side effects, so we can't safely evaluate it; since !propertyClass.isPrimitive(), it's Object.
++ return Type.OBJECT;
++ }
++
++ // Safely evaluate the property, and return the narrowest type for the actual value (e.g. Type.INT for a boxed
++ // integer).
++ final Object value = property.needsDeclaration() ? ScriptRuntime.UNDEFINED : property.getObjectValue(owner, owner);
++ if (value == ScriptRuntime.UNDEFINED) {
++ return null;
++ }
++ return Type.typeFor(JSType.unboxedFieldType(value));
++ }
++
++ /**
++ * Declares a symbol name as belonging to a non-scoped local variable during an on-demand compilation of a single
++ * function. This method will add an explicit Undefined binding for the local into the runtime scope if it's
++ * otherwise implicitly undefined so that when an expression is evaluated for the name, it won't accidentally find
++ * an unrelated value higher up the scope chain. It is only required to call this method when doing an optimistic
++ * on-demand compilation.
++ * @param symbolName the name of the symbol that is to be declared as being a non-scoped local variable.
++ */
++ void declareLocalSymbol(final String symbolName) {
++ assert
++ compiler.useOptimisticTypes() &&
++ compiler.isOnDemandCompilation() &&
++ runtimeScope != null :
++ "useOptimistic=" +
++ compiler.useOptimisticTypes() +
++ " isOnDemand=" +
++ compiler.isOnDemandCompilation() +
++ " scope="+runtimeScope;
++
++ if (runtimeScope.findProperty(symbolName, false) == null) {
++ runtimeScope.addOwnProperty(symbolName, NOT_WRITABLE | NOT_ENUMERABLE | NOT_CONFIGURABLE, ScriptRuntime.UNDEFINED);
++ }
++ }
++
++ private Object evaluateSafely(final Expression expr) {
++ if (expr instanceof IdentNode) {
++ return runtimeScope == null ? null : evaluatePropertySafely(runtimeScope, ((IdentNode)expr).getName());
++ }
++
++ if (expr instanceof AccessNode) {
++ final AccessNode accessNode = (AccessNode)expr;
++ final Object base = evaluateSafely(accessNode.getBase());
++ if (!(base instanceof ScriptObject)) {
++ return null;
++ }
++ return evaluatePropertySafely((ScriptObject)base, accessNode.getProperty());
++ }
++
++ return null;
++ }
++
++ private static Object evaluatePropertySafely(final ScriptObject sobj, final String name) {
++ final FindProperty find = sobj.findProperty(name, true);
++ if (find == null) {
++ return null;
++ }
++ final Property property = find.getProperty();
++ final ScriptObject owner = find.getOwner();
++ if (property.hasGetterFunction(owner)) {
++ // Possible side effects; can't evaluate safely
++ return null;
++ }
++ return property.getObjectValue(owner, owner);
++ }
++
++
++ private Type getEvaluatedType(final Optimistic expr) {
++ if (expr instanceof IdentNode) {
++ if (runtimeScope == null) {
++ return null;
++ }
++ return getPropertyType(runtimeScope, ((IdentNode)expr).getName());
++ } else if (expr instanceof AccessNode) {
++ final AccessNode accessNode = (AccessNode)expr;
++ final Object base = evaluateSafely(accessNode.getBase());
++ if (!(base instanceof ScriptObject)) {
++ return null;
++ }
++ return getPropertyType((ScriptObject)base, accessNode.getProperty());
++ } else if (expr instanceof IndexNode) {
++ final IndexNode indexNode = (IndexNode)expr;
++ final Object base = evaluateSafely(indexNode.getBase());
++ if(base instanceof NativeArray || base instanceof ArrayBufferView) {
++ // NOTE: optimistic array getters throw UnwarrantedOptimismException based on the type of their
++ // underlying array storage, not based on values of individual elements. Thus, a LongArrayData will
++ // throw UOE for every optimistic int linkage attempt, even if the long value being returned in the
++ // first invocation would be representable as int. That way, we can presume that the array's optimistic
++ // type is the most optimistic type for which an element getter has a chance of executing successfully.
++ return ((ScriptObject)base).getArray().getOptimisticType();
++ }
++ } else if (expr instanceof CallNode) {
++ // Currently, we'll only try to guess the return type of immediately invoked function expressions with no
++ // parameters, that is (function() { ... })(). We could do better, but these are all heuristics and we can
++ // gradually introduce them as needed. An easy one would be to do the same for .call(this) idiom.
++ final CallNode callExpr = (CallNode)expr;
++ final Expression fnExpr = callExpr.getFunction();
++ if (fnExpr instanceof FunctionNode) {
++ final FunctionNode fn = (FunctionNode)fnExpr;
++ if (callExpr.getArgs().isEmpty()) {
++ final RecompilableScriptFunctionData data = compiler.getScriptFunctionData(fn.getId());
++ if (data != null) {
++ final Type returnType = Type.typeFor(data.getReturnType(EMPTY_INVOCATION_TYPE, runtimeScope));
++ if (returnType == Type.BOOLEAN) {
++ // We don't have optimistic booleans. In fact, optimistic call sites getting back boolean
++ // currently deoptimize all the way to Object.
++ return Type.OBJECT;
++ }
++ assert returnType == Type.INT || returnType == Type.LONG || returnType == Type.NUMBER || returnType == Type.OBJECT;
++ return returnType;
++ }
++ }
++ }
++ }
++
++ return null;
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/TypeMap.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,166 @@
++/*
++ * Copyright (c) 2010-2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen;
++
++import java.lang.invoke.MethodType;
++import java.util.Arrays;
++import java.util.HashMap;
++import java.util.Map;
++import java.util.NoSuchElementException;
++import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.ir.FunctionNode;
++import jdk.nashorn.internal.runtime.ScriptFunction;
++
++/**
++ * A data structure that maps one or several function nodes (by their unique id:s, not by
++ * the FunctionNode object itself, due to copy on write changing it several times through
++ * code generation.
++ */
++public class TypeMap {
++ private final Map<Integer, Type[]> paramTypeMap = new HashMap<>();
++ private final Map<Integer, Type> returnTypeMap = new HashMap<>();
++ private final boolean needsCallee;
++
++ /**
++ * Constructor
++ * @param functionNodeId function node id
++ * @param type method type found at runtime corresponding to parameter guess
++ * @param needsCallee does the function using this type map need a callee
++ */
++ public TypeMap(final int functionNodeId, final MethodType type, final boolean needsCallee) {
++ final Type[] types = new Type[type.parameterCount()];
++ int pos = 0;
++ for (final Class<?> p : type.parameterArray()) {
++ types[pos++] = Type.typeFor(p);
++ }
++ paramTypeMap.put(functionNodeId, types);
++ returnTypeMap.put(functionNodeId, Type.typeFor(type.returnType()));
++
++ this.needsCallee = needsCallee;
++ }
++
++ /**
++ * Returns the array of parameter types for a particular function node
++ * @param functionNodeId the ID of the function node
++ * @return an array of parameter types
++ * @throws NoSuchElementException if the type map has no mapping for the requested function
++ */
++ public Type[] getParameterTypes(final int functionNodeId) {
++ final Type[] paramTypes = paramTypeMap.get(functionNodeId);
++ if (paramTypes == null) {
++ throw new NoSuchElementException(Integer.toString(functionNodeId));
++ }
++ return paramTypes.clone();
++ }
++
++ MethodType getCallSiteType(final FunctionNode functionNode) {
++ final Type[] types = paramTypeMap.get(functionNode.getId());
++ if (types == null) {
++ return null;
++ }
++
++ MethodType mt = MethodType.methodType(returnTypeMap.get(functionNode.getId()).getTypeClass());
++ if (needsCallee) {
++ mt = mt.appendParameterTypes(ScriptFunction.class);
++ }
++
++ mt = mt.appendParameterTypes(Object.class); //this
++
++ for (final Type type : types) {
++ if (type == null) {
++ return null; // not all parameter information is supplied
++ }
++ mt = mt.appendParameterTypes(type.getTypeClass());
++ }
++
++ return mt;
++ }
++
++ /**
++ * Does the function using this TypeMap need a callee argument. This is used
++ * to compute correct param index offsets in {@link jdk.nashorn.internal.codegen.ApplySpecialization}
++ * @return true if a callee is needed, false otherwise
++ */
++ public boolean needsCallee() {
++ return needsCallee;
++ }
++
++ /**
++ * Get the parameter type for this parameter position, or
++ * null if now known
++ * @param functionNode functionNode
++ * @param pos position
++ * @return parameter type for this callsite if known
++ */
++ Type get(final FunctionNode functionNode, final int pos) {
++ final Type[] types = paramTypeMap.get(functionNode.getId());
++ assert types == null || pos < types.length : "fn = " + functionNode.getId() + " " + "types=" + Arrays.toString(types) + " || pos=" + pos + " >= length=" + types.length + " in " + this;
++ if (types != null && pos < types.length) {
++ return types[pos];
++ }
++ return null;
++ }
++
++ boolean has(final FunctionNode functionNode) {
++ final int id = functionNode.getId();
++ final Type[] paramTypes = paramTypeMap.get(id);
++ assert (paramTypes == null) == (returnTypeMap.get(id) == null) : "inconsistent param and return types in param map";
++ return paramTypes != null;
++ }
++
++ @Override
++ public String toString() {
++ return toString("");
++ }
++
++ String toString(final String prefix) {
++ final StringBuilder sb = new StringBuilder();
++
++ if (paramTypeMap.isEmpty()) {
++ sb.append(prefix).append("\t<empty>");
++ return sb.toString();
++ }
++
++ for (final Map.Entry<Integer, Type[]> entry : paramTypeMap.entrySet()) {
++ final int id = entry.getKey();
++ sb.append(prefix).append('\t');
++ sb.append("function ").append(id).append('\n');
++ sb.append(prefix).append("\t\tparamTypes=");
++ if (entry.getValue() == null) {
++ sb.append("[]");
++ } else {
++ sb.append(Arrays.toString(entry.getValue()));
++ }
++ sb.append('\n');
++ sb.append(prefix).append("\t\treturnType=");
++ final Type ret = returnTypeMap.get(id);
++ sb.append(ret == null ? "N/A" : ret);
++ sb.append('\n');
++ }
++
++ return sb.toString();
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,7 +27,6 @@
+
+ import java.util.List;
+ import java.util.Map;
+-import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.AccessNode;
+ import jdk.nashorn.internal.ir.BinaryNode;
+ import jdk.nashorn.internal.ir.Block;
+@@ -69,24 +68,25 @@
+ * Weight constants.
+ */
+ static final long FUNCTION_WEIGHT = 40;
+- static final long AASTORE_WEIGHT = 2;
+- static final long ACCESS_WEIGHT = 4;
++ static final long AASTORE_WEIGHT = 2;
++ static final long ACCESS_WEIGHT = 4;
+ static final long ADD_WEIGHT = 10;
+- static final long BREAK_WEIGHT = 1;
++ static final long BREAK_WEIGHT = 1;
+ static final long CALL_WEIGHT = 10;
+ static final long CATCH_WEIGHT = 10;
+- static final long CONTINUE_WEIGHT = 1;
+- static final long IF_WEIGHT = 2;
++ static final long COMPARE_WEIGHT = 6;
++ static final long CONTINUE_WEIGHT = 1;
++ static final long IF_WEIGHT = 2;
+ static final long LITERAL_WEIGHT = 10;
+- static final long LOOP_WEIGHT = 4;
+- static final long NEW_WEIGHT = 6;
++ static final long LOOP_WEIGHT = 4;
++ static final long NEW_WEIGHT = 6;
+ static final long FUNC_EXPR_WEIGHT = 20;
+- static final long RETURN_WEIGHT = 2;
++ static final long RETURN_WEIGHT = 2;
+ static final long SPLIT_WEIGHT = 40;
+- static final long SWITCH_WEIGHT = 8;
+- static final long THROW_WEIGHT = 2;
++ static final long SWITCH_WEIGHT = 8;
++ static final long THROW_WEIGHT = 2;
+ static final long VAR_WEIGHT = 40;
+- static final long WITH_WEIGHT = 8;
++ static final long WITH_WEIGHT = 8;
+
+ /** Accumulated weight. */
+ private long weight;
+@@ -101,7 +101,7 @@
+ *
+ * @param weightCache cache of already calculated block weights
+ */
+- private WeighNodes(FunctionNode topFunction, final Map<Node, Long> weightCache) {
++ private WeighNodes(final FunctionNode topFunction, final Map<Node, Long> weightCache) {
+ super(new LexicalContext());
+ this.topFunction = topFunction;
+ this.weightCache = weightCache;
+@@ -173,7 +173,6 @@
+ if (functionNode == topFunction) {
+ // the function being weighted; descend into its statements
+ return true;
+-// functionNode.visitStatements(this);
+ }
+ // just a reference to inner function from outer function
+ weight += FUNC_EXPR_WEIGHT;
+@@ -307,11 +306,6 @@
+ }
+
+ @Override
+- public Node leaveDISCARD(final UnaryNode unaryNode) {
+- return unaryNodeWeight(unaryNode);
+- }
+-
+- @Override
+ public Node leaveNEW(final UnaryNode unaryNode) {
+ weight += NEW_WEIGHT;
+ return unaryNode;
+@@ -446,22 +440,22 @@
+
+ @Override
+ public Node leaveEQ(final BinaryNode binaryNode) {
+- return runtimeNodeWeight(binaryNode);
++ return compareWeight(binaryNode);
+ }
+
+ @Override
+ public Node leaveEQ_STRICT(final BinaryNode binaryNode) {
+- return runtimeNodeWeight(binaryNode);
++ return compareWeight(binaryNode);
+ }
+
+ @Override
+ public Node leaveGE(final BinaryNode binaryNode) {
+- return runtimeNodeWeight(binaryNode);
++ return compareWeight(binaryNode);
+ }
+
+ @Override
+ public Node leaveGT(final BinaryNode binaryNode) {
+- return runtimeNodeWeight(binaryNode);
++ return compareWeight(binaryNode);
+ }
+
+ @Override
+@@ -478,12 +472,12 @@
+
+ @Override
+ public Node leaveLE(final BinaryNode binaryNode) {
+- return runtimeNodeWeight(binaryNode);
++ return compareWeight(binaryNode);
+ }
+
+ @Override
+ public Node leaveLT(final BinaryNode binaryNode) {
+- return runtimeNodeWeight(binaryNode);
++ return compareWeight(binaryNode);
+ }
+
+ @Override
+@@ -498,12 +492,12 @@
+
+ @Override
+ public Node leaveNE(final BinaryNode binaryNode) {
+- return runtimeNodeWeight(binaryNode);
++ return compareWeight(binaryNode);
+ }
+
+ @Override
+ public Node leaveNE_STRICT(final BinaryNode binaryNode) {
+- return runtimeNodeWeight(binaryNode);
++ return compareWeight(binaryNode);
+ }
+
+ @Override
+@@ -546,8 +540,8 @@
+ return unaryNode;
+ }
+
+- private Node runtimeNodeWeight(final BinaryNode binaryNode) {
+- weight += Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType()).isObject() ? CALL_WEIGHT : 1;
++ private Node compareWeight(final BinaryNode binaryNode) {
++ weight += COMPARE_WEIGHT;
+ return binaryNode;
+ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/codegen/anchor.properties Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,27 @@
++#
++# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++#
++# This code is free software; you can redistribute it and/or modify it
++# under the terms of the GNU General Public License version 2 only, as
++# published by the Free Software Foundation. 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.
++#
++
++
++# This file exists only so OptimisticTypesPersistence.getVersionDirName() can take its URL.
+--- ./nashorn/src/jdk/nashorn/internal/codegen/types/ArrayType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/types/ArrayType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -37,6 +37,7 @@
+ * This is an array type, i.e. OBJECT_ARRAY, NUMBER_ARRAY.
+ */
+ public class ArrayType extends ObjectType implements BytecodeArrayOps {
++ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor
+--- ./nashorn/src/jdk/nashorn/internal/codegen/types/BitwiseType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/types/BitwiseType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,6 +29,7 @@
+ * This class represents a numeric type that can be used for bit operations.
+ */
+ public abstract class BitwiseType extends NumericType implements BytecodeBitwiseOps {
++ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor
+--- ./nashorn/src/jdk/nashorn/internal/codegen/types/BooleanType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/types/BooleanType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -50,24 +50,29 @@
+
+ package jdk.nashorn.internal.codegen.types;
+
++import static jdk.internal.org.objectweb.asm.Opcodes.I2D;
++import static jdk.internal.org.objectweb.asm.Opcodes.I2L;
++import static jdk.internal.org.objectweb.asm.Opcodes.IADD;
+ import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_0;
+ import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_1;
+ import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD;
+ import static jdk.internal.org.objectweb.asm.Opcodes.IRETURN;
+ import static jdk.internal.org.objectweb.asm.Opcodes.ISTORE;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
++import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_INT;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
+
+ import jdk.internal.org.objectweb.asm.MethodVisitor;
+ import jdk.nashorn.internal.codegen.CompilerConstants;
+-import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+-import jdk.nashorn.internal.runtime.JSType;
+
+ /**
+ * The boolean type class
+ */
+ public final class BooleanType extends Type {
++ private static final long serialVersionUID = 1L;
+
+ private static final CompilerConstants.Call VALUE_OF = staticCallNoLookup(Boolean.class, "valueOf", Boolean.class, boolean.class);
++ private static final CompilerConstants.Call TO_STRING = staticCallNoLookup(Boolean.class, "toString", String.class, boolean.class);
+
+ /**
+ * Constructor
+@@ -87,8 +92,19 @@
+ }
+
+ @Override
++ public char getBytecodeStackType() {
++ return 'I';
++ }
++
++ @Override
+ public Type loadUndefined(final MethodVisitor method) {
+- method.visitLdcInsn(ObjectClassGenerator.UNDEFINED_INT);
++ method.visitLdcInsn(UNDEFINED_INT);
++ return BOOLEAN;
++ }
++
++ @Override
++ public Type loadForcedInitializer(final MethodVisitor method) {
++ method.visitInsn(ICONST_0);
+ return BOOLEAN;
+ }
+
+@@ -124,31 +140,30 @@
+ }
+
+ if (to.isNumber()) {
+- convert(method, OBJECT);
+- invokeStatic(method, JSType.TO_NUMBER);
++ method.visitInsn(I2D);
++ } else if (to.isLong()) {
++ method.visitInsn(I2L);
+ } else if (to.isInteger()) {
+- return to; // do nothing.
+- } else if (to.isLong()) {
+- convert(method, OBJECT);
+- invokeStatic(method, JSType.TO_UINT32);
+- } else if (to.isLong()) {
+- convert(method, OBJECT);
+- invokeStatic(method, JSType.TO_LONG);
++ //nop
+ } else if (to.isString()) {
+- invokeStatic(method, VALUE_OF);
+- invokeStatic(method, JSType.TO_PRIMITIVE_TO_STRING);
++ invokestatic(method, TO_STRING);
+ } else if (to.isObject()) {
+- invokeStatic(method, VALUE_OF);
++ invokestatic(method, VALUE_OF);
+ } else {
+- assert false : "Illegal conversion " + this + " -> " + to;
++ throw new UnsupportedOperationException("Illegal conversion " + this + " -> " + to);
+ }
+
+ return to;
+ }
+
+ @Override
+- public Type add(final MethodVisitor method) {
+- assert false : "unsupported operation";
+- return null;
++ public Type add(final MethodVisitor method, final int programPoint) {
++ // Adding booleans in JavaScript is perfectly valid, they add as if false=0 and true=1
++ if(programPoint == INVALID_PROGRAM_POINT) {
++ method.visitInsn(IADD);
++ } else {
++ method.visitInvokeDynamicInsn("iadd", "(II)I", MATHBOOTSTRAP, programPoint);
++ }
++ return INT;
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeNumericOps.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeNumericOps.java Wed Feb 04 12:14:47 2015 -0800
+@@ -36,50 +36,55 @@
+ * Pop and negate the value on top of the stack and push the result
+ *
+ * @param method method visitor
+- *
++ * @param programPoint program point id
+ * @return result type
+ */
+- Type neg(MethodVisitor method);
++ Type neg(MethodVisitor method, int programPoint);
+
+ /**
+ * Pop two values on top of the stack and subtract the first from the
+ * second, pushing the result on the stack
+ *
+ * @param method method visitor
+- *
++ * @param programPoint program point id
+ * @return result type
+ */
+- Type sub(MethodVisitor method);
++ Type sub(MethodVisitor method, int programPoint);
+
+ /**
+ * Pop and multiply the two values on top of the stack and push the result
+ * on the stack
+ *
+ * @param method method visitor
+- *
++ * @param programPoint program point id
+ * @return result type
+ */
+- Type mul(MethodVisitor method);
++ Type mul(MethodVisitor method, int programPoint);
+
+ /**
+ * Pop two values on top of the stack and divide the first with the second,
+ * pushing the result on the stack
+ *
+ * @param method method visitor
+- *
++ * @param programPoint program point id
+ * @return result type
+ */
+- Type div(MethodVisitor method);
++ Type div(MethodVisitor method, int programPoint);
+
+ /**
+ * Pop two values on top of the stack and compute the modulo of the first
+ * with the second, pushing the result on the stack
+ *
++ * Note that the rem method never takes a program point, because it
++ * can never be more optimistic than its widest operand - an int/int
++ * rem operation or a long/long rem operation can never return a
++ * winder remainder than the int or the long
++ *
+ * @param method method visitor
+- *
++ * @param programPoint program point id
+ * @return result type
+ */
+- Type rem(MethodVisitor method);
++ Type rem(MethodVisitor method, int programPoint);
+
+ /**
+ * Comparison with int return value, e.g. LCMP, DCMP.
+--- ./nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeOps.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeOps.java Wed Feb 04 12:14:47 2015 -0800
+@@ -85,9 +85,10 @@
+ * first to the second, pushing the result on the stack
+ *
+ * @param method method visitor
++ * @param programPoint program point id
+ * @return result type
+ */
+- Type add(MethodVisitor method);
++ Type add(MethodVisitor method, int programPoint);
+
+ /**
+ * Load a variable from a local slot to the stack
+@@ -129,6 +130,17 @@
+ Type loadUndefined(MethodVisitor method);
+
+ /**
++ * Load the "forced initializer" value to the stack, used to ensure that a local variable has a value when it is
++ * read by the unwarranted optimism catch block.
++ *
++ * @param method method visitor.
++ *
++ * @return the forced initialization type at the top of the stack
++ */
++ Type loadForcedInitializer(MethodVisitor method);
++
++
++ /**
+ * Load the "empty" value to the stack.
+ *
+ * @param method method visitor.
+--- ./nashorn/src/jdk/nashorn/internal/codegen/types/IntType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/types/IntType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -37,12 +37,10 @@
+ import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_4;
+ import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_5;
+ import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_M1;
+-import static jdk.internal.org.objectweb.asm.Opcodes.IDIV;
+ import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD;
+ import static jdk.internal.org.objectweb.asm.Opcodes.IMUL;
+ import static jdk.internal.org.objectweb.asm.Opcodes.INEG;
+ import static jdk.internal.org.objectweb.asm.Opcodes.IOR;
+-import static jdk.internal.org.objectweb.asm.Opcodes.IREM;
+ import static jdk.internal.org.objectweb.asm.Opcodes.IRETURN;
+ import static jdk.internal.org.objectweb.asm.Opcodes.ISHL;
+ import static jdk.internal.org.objectweb.asm.Opcodes.ISHR;
+@@ -52,15 +50,18 @@
+ import static jdk.internal.org.objectweb.asm.Opcodes.IXOR;
+ import static jdk.internal.org.objectweb.asm.Opcodes.SIPUSH;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
++import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_INT;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
+
+ import jdk.internal.org.objectweb.asm.MethodVisitor;
+ import jdk.nashorn.internal.codegen.CompilerConstants;
+-import jdk.nashorn.internal.codegen.ObjectClassGenerator;
++import jdk.nashorn.internal.runtime.JSType;
+
+ /**
+ * Type class: INT
+ */
+ class IntType extends BitwiseType {
++ private static final long serialVersionUID = 1L;
+
+ private static final CompilerConstants.Call TO_STRING = staticCallNoLookup(Integer.class, "toString", String.class, int.class);
+ private static final CompilerConstants.Call VALUE_OF = staticCallNoLookup(Integer.class, "valueOf", Integer.class, int.class);
+@@ -80,42 +81,47 @@
+ }
+
+ @Override
++ public char getBytecodeStackType() {
++ return 'I';
++ }
++
++ @Override
+ public Type ldc(final MethodVisitor method, final Object c) {
+ assert c instanceof Integer;
+
+ final int value = ((Integer) c).intValue();
+
+ switch (value) {
+- case -1:
+- method.visitInsn(ICONST_M1);
+- break;
+- case 0:
+- method.visitInsn(ICONST_0);
+- break;
+- case 1:
+- method.visitInsn(ICONST_1);
+- break;
+- case 2:
+- method.visitInsn(ICONST_2);
+- break;
+- case 3:
+- method.visitInsn(ICONST_3);
+- break;
+- case 4:
+- method.visitInsn(ICONST_4);
+- break;
+- case 5:
+- method.visitInsn(ICONST_5);
+- break;
+- default:
+- if (value == (byte) value) {
+- method.visitIntInsn(BIPUSH, value);
+- } else if (value == (short) value) {
+- method.visitIntInsn(SIPUSH, value);
+- } else {
+- method.visitLdcInsn(c);
+- }
+- break;
++ case -1:
++ method.visitInsn(ICONST_M1);
++ break;
++ case 0:
++ method.visitInsn(ICONST_0);
++ break;
++ case 1:
++ method.visitInsn(ICONST_1);
++ break;
++ case 2:
++ method.visitInsn(ICONST_2);
++ break;
++ case 3:
++ method.visitInsn(ICONST_3);
++ break;
++ case 4:
++ method.visitInsn(ICONST_4);
++ break;
++ case 5:
++ method.visitInsn(ICONST_5);
++ break;
++ default:
++ if (value == (byte) value) {
++ method.visitIntInsn(BIPUSH, value);
++ } else if (value == (short) value) {
++ method.visitIntInsn(SIPUSH, value);
++ } else {
++ method.visitLdcInsn(c);
++ }
++ break;
+ }
+
+ return Type.INT;
+@@ -134,19 +140,23 @@
+ } else if (to.isBoolean()) {
+ //nop
+ } else if (to.isString()) {
+- invokeStatic(method, TO_STRING);
++ invokestatic(method, TO_STRING);
+ } else if (to.isObject()) {
+- invokeStatic(method, VALUE_OF);
++ invokestatic(method, VALUE_OF);
+ } else {
+- assert false : "Illegal conversion " + this + " -> " + to;
++ throw new UnsupportedOperationException("Illegal conversion " + this + " -> " + to);
+ }
+
+ return to;
+ }
+
+ @Override
+- public Type add(final MethodVisitor method) {
+- method.visitInsn(IADD);
++ public Type add(final MethodVisitor method, final int programPoint) {
++ if(programPoint == INVALID_PROGRAM_POINT) {
++ method.visitInsn(IADD);
++ } else {
++ method.visitInvokeDynamicInsn("iadd", "(II)I", MATHBOOTSTRAP, programPoint);
++ }
+ return INT;
+ }
+
+@@ -200,32 +210,52 @@
+ }
+
+ @Override
+- public Type sub(final MethodVisitor method) {
+- method.visitInsn(ISUB);
++ public Type sub(final MethodVisitor method, final int programPoint) {
++ if(programPoint == INVALID_PROGRAM_POINT) {
++ method.visitInsn(ISUB);
++ } else {
++ method.visitInvokeDynamicInsn("isub", "(II)I", MATHBOOTSTRAP, programPoint);
++ }
+ return INT;
+ }
+
+ @Override
+- public Type mul(final MethodVisitor method) {
+- method.visitInsn(IMUL);
++ public Type mul(final MethodVisitor method, final int programPoint) {
++ if(programPoint == INVALID_PROGRAM_POINT) {
++ method.visitInsn(IMUL);
++ } else {
++ method.visitInvokeDynamicInsn("imul", "(II)I", MATHBOOTSTRAP, programPoint);
++ }
+ return INT;
+ }
+
+ @Override
+- public Type div(final MethodVisitor method) {
+- method.visitInsn(IDIV);
++ public Type div(final MethodVisitor method, final int programPoint) {
++ if (programPoint == INVALID_PROGRAM_POINT) {
++ JSType.DIV_ZERO.invoke(method);
++ } else {
++ method.visitInvokeDynamicInsn("idiv", "(II)I", MATHBOOTSTRAP, programPoint);
++ }
+ return INT;
+ }
+
+ @Override
+- public Type rem(final MethodVisitor method) {
+- method.visitInsn(IREM);
++ public Type rem(final MethodVisitor method, final int programPoint) {
++ if (programPoint == INVALID_PROGRAM_POINT) {
++ JSType.REM_ZERO.invoke(method);
++ } else {
++ method.visitInvokeDynamicInsn("irem", "(II)I", MATHBOOTSTRAP, programPoint);
++ }
+ return INT;
+ }
+
+ @Override
+- public Type neg(final MethodVisitor method) {
+- method.visitInsn(INEG);
++ public Type neg(final MethodVisitor method, final int programPoint) {
++ if(programPoint == INVALID_PROGRAM_POINT) {
++ method.visitInsn(INEG);
++ } else {
++ method.visitInvokeDynamicInsn("ineg", "(I)I", MATHBOOTSTRAP, programPoint);
++ }
+ return INT;
+ }
+
+@@ -236,19 +266,24 @@
+
+ @Override
+ public Type loadUndefined(final MethodVisitor method) {
+- method.visitLdcInsn(ObjectClassGenerator.UNDEFINED_INT);
++ method.visitLdcInsn(UNDEFINED_INT);
++ return INT;
++ }
++
++ @Override
++ public Type loadForcedInitializer(final MethodVisitor method) {
++ method.visitInsn(ICONST_0);
+ return INT;
+ }
+
+ @Override
+ public Type cmp(final MethodVisitor method, final boolean isCmpG) {
+- assert false : "unsupported operation";
+- return null;
++ throw new UnsupportedOperationException("cmp" + (isCmpG ? 'g' : 'l'));
+ }
+
+ @Override
+ public Type cmp(final MethodVisitor method) {
+- assert false : "unsupported operation";
+- return null;
++ throw new UnsupportedOperationException("cmp");
+ }
++
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/types/LongType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/types/LongType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -32,12 +32,9 @@
+ import static jdk.internal.org.objectweb.asm.Opcodes.LCMP;
+ import static jdk.internal.org.objectweb.asm.Opcodes.LCONST_0;
+ import static jdk.internal.org.objectweb.asm.Opcodes.LCONST_1;
+-import static jdk.internal.org.objectweb.asm.Opcodes.LDIV;
+ import static jdk.internal.org.objectweb.asm.Opcodes.LLOAD;
+ import static jdk.internal.org.objectweb.asm.Opcodes.LMUL;
+-import static jdk.internal.org.objectweb.asm.Opcodes.LNEG;
+ import static jdk.internal.org.objectweb.asm.Opcodes.LOR;
+-import static jdk.internal.org.objectweb.asm.Opcodes.LREM;
+ import static jdk.internal.org.objectweb.asm.Opcodes.LRETURN;
+ import static jdk.internal.org.objectweb.asm.Opcodes.LSHL;
+ import static jdk.internal.org.objectweb.asm.Opcodes.LSHR;
+@@ -46,15 +43,18 @@
+ import static jdk.internal.org.objectweb.asm.Opcodes.LUSHR;
+ import static jdk.internal.org.objectweb.asm.Opcodes.LXOR;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
++import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_LONG;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
+
+ import jdk.internal.org.objectweb.asm.MethodVisitor;
+ import jdk.nashorn.internal.codegen.CompilerConstants;
+-import jdk.nashorn.internal.codegen.ObjectClassGenerator;
++import jdk.nashorn.internal.runtime.JSType;
+
+ /**
+ * Type class: LONG
+ */
+ class LongType extends BitwiseType {
++ private static final long serialVersionUID = 1L;
+
+ private static final CompilerConstants.Call VALUE_OF = staticCallNoLookup(Long.class, "valueOf", Long.class, long.class);
+
+@@ -77,6 +77,11 @@
+ }
+
+ @Override
++ public char getBytecodeStackType() {
++ return 'J';
++ }
++
++ @Override
+ public Type cmp(final MethodVisitor method) {
+ method.visitInsn(LCMP);
+ return INT;
+@@ -121,11 +126,11 @@
+ if (to.isNumber()) {
+ method.visitInsn(L2D);
+ } else if (to.isInteger()) {
+- method.visitInsn(L2I);
++ invokestatic(method, JSType.TO_INT32_L);
+ } else if (to.isBoolean()) {
+ method.visitInsn(L2I);
+ } else if (to.isObject()) {
+- invokeStatic(method, VALUE_OF);
++ invokestatic(method, VALUE_OF);
+ } else {
+ assert false : "Illegal conversion " + this + " -> " + to;
+ }
+@@ -134,32 +139,52 @@
+ }
+
+ @Override
+- public Type add(final MethodVisitor method) {
+- method.visitInsn(LADD);
++ public Type add(final MethodVisitor method, final int programPoint) {
++ if(programPoint == INVALID_PROGRAM_POINT) {
++ method.visitInsn(LADD);
++ } else {
++ method.visitInvokeDynamicInsn("ladd", "(JJ)J", MATHBOOTSTRAP, programPoint);
++ }
+ return LONG;
+ }
+
+ @Override
+- public Type sub(final MethodVisitor method) {
+- method.visitInsn(LSUB);
++ public Type sub(final MethodVisitor method, final int programPoint) {
++ if(programPoint == INVALID_PROGRAM_POINT) {
++ method.visitInsn(LSUB);
++ } else {
++ method.visitInvokeDynamicInsn("lsub", "(JJ)J", MATHBOOTSTRAP, programPoint);
++ }
+ return LONG;
+ }
+
+ @Override
+- public Type mul(final MethodVisitor method) {
+- method.visitInsn(LMUL);
++ public Type mul(final MethodVisitor method, final int programPoint) {
++ if(programPoint == INVALID_PROGRAM_POINT) {
++ method.visitInsn(LMUL);
++ } else {
++ method.visitInvokeDynamicInsn("lmul", "(JJ)J", MATHBOOTSTRAP, programPoint);
++ }
+ return LONG;
+ }
+
+ @Override
+- public Type div(final MethodVisitor method) {
+- method.visitInsn(LDIV);
++ public Type div(final MethodVisitor method, final int programPoint) {
++ if (programPoint == INVALID_PROGRAM_POINT) {
++ JSType.DIV_ZERO_LONG.invoke(method);
++ } else {
++ method.visitInvokeDynamicInsn("ldiv", "(JJ)J", MATHBOOTSTRAP, programPoint);
++ }
+ return LONG;
+ }
+
+ @Override
+- public Type rem(final MethodVisitor method) {
+- method.visitInsn(LREM);
++ public Type rem(final MethodVisitor method, final int programPoint) {
++ if (programPoint == INVALID_PROGRAM_POINT) {
++ JSType.REM_ZERO_LONG.invoke(method);
++ } else {
++ method.visitInvokeDynamicInsn("lrem", "(JJ)J", MATHBOOTSTRAP, programPoint);
++ }
+ return LONG;
+ }
+
+@@ -200,8 +225,8 @@
+ }
+
+ @Override
+- public Type neg(final MethodVisitor method) {
+- method.visitInsn(LNEG);
++ public Type neg(final MethodVisitor method, final int programPoint) {
++ method.visitInvokeDynamicInsn("lneg", "(J)J", MATHBOOTSTRAP, programPoint);
+ return LONG;
+ }
+
+@@ -212,7 +237,13 @@
+
+ @Override
+ public Type loadUndefined(final MethodVisitor method) {
+- method.visitLdcInsn(ObjectClassGenerator.UNDEFINED_LONG);
++ method.visitLdcInsn(UNDEFINED_LONG);
++ return LONG;
++ }
++
++ @Override
++ public Type loadForcedInitializer(final MethodVisitor method) {
++ method.visitInsn(LCONST_0);
+ return LONG;
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/codegen/types/NumberType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/types/NumberType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -39,13 +39,14 @@
+ import static jdk.internal.org.objectweb.asm.Opcodes.DSTORE;
+ import static jdk.internal.org.objectweb.asm.Opcodes.DSUB;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
++import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_DOUBLE;
+
+ import jdk.internal.org.objectweb.asm.MethodVisitor;
+ import jdk.nashorn.internal.codegen.CompilerConstants;
+-import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+ import jdk.nashorn.internal.runtime.JSType;
+
+ class NumberType extends NumericType {
++ private static final long serialVersionUID = 1L;
+
+ private static final CompilerConstants.Call VALUE_OF = staticCallNoLookup(Double.class, "valueOf", Double.class, double.class);
+
+@@ -64,6 +65,11 @@
+ }
+
+ @Override
++ public char getBytecodeStackType() {
++ return 'D';
++ }
++
++ @Override
+ public Type cmp(final MethodVisitor method, final boolean isCmpG) {
+ method.visitInsn(isCmpG ? DCMPG : DCMPL);
+ return INT;
+@@ -84,7 +90,13 @@
+
+ @Override
+ public Type loadUndefined(final MethodVisitor method) {
+- method.visitLdcInsn(ObjectClassGenerator.UNDEFINED_DOUBLE);
++ method.visitLdcInsn(UNDEFINED_DOUBLE);
++ return NUMBER;
++ }
++
++ @Override
++ public Type loadForcedInitializer(final MethodVisitor method) {
++ method.visitInsn(DCONST_0);
+ return NUMBER;
+ }
+
+@@ -112,54 +124,54 @@
+ }
+
+ if (to.isInteger()) {
+- invokeStatic(method, JSType.TO_INT32_D);
++ invokestatic(method, JSType.TO_INT32_D);
+ } else if (to.isLong()) {
+- invokeStatic(method, JSType.TO_INT64_D);
++ invokestatic(method, JSType.TO_LONG_D);
+ } else if (to.isBoolean()) {
+- invokeStatic(method, JSType.TO_BOOLEAN_D);
++ invokestatic(method, JSType.TO_BOOLEAN_D);
+ } else if (to.isString()) {
+- invokeStatic(method, JSType.TO_STRING_D);
++ invokestatic(method, JSType.TO_STRING_D);
+ } else if (to.isObject()) {
+- invokeStatic(method, VALUE_OF);
++ invokestatic(method, VALUE_OF);
+ } else {
+- assert false : "Illegal conversion " + this + " -> " + to;
++ throw new UnsupportedOperationException("Illegal conversion " + this + " -> " + to);
+ }
+
+ return to;
+ }
+
+ @Override
+- public Type add(final MethodVisitor method) {
++ public Type add(final MethodVisitor method, final int programPoint) {
+ method.visitInsn(DADD);
+ return NUMBER;
+ }
+
+ @Override
+- public Type sub(final MethodVisitor method) {
++ public Type sub(final MethodVisitor method, final int programPoint) {
+ method.visitInsn(DSUB);
+ return NUMBER;
+ }
+
+ @Override
+- public Type mul(final MethodVisitor method) {
++ public Type mul(final MethodVisitor method, final int programPoint) {
+ method.visitInsn(DMUL);
+ return NUMBER;
+ }
+
+ @Override
+- public Type div(final MethodVisitor method) {
++ public Type div(final MethodVisitor method, final int programPoint) {
+ method.visitInsn(DDIV);
+ return NUMBER;
+ }
+
+ @Override
+- public Type rem(final MethodVisitor method) {
++ public Type rem(final MethodVisitor method, final int programPoint) {
+ method.visitInsn(DREM);
+ return NUMBER;
+ }
+
+ @Override
+- public Type neg(final MethodVisitor method) {
++ public Type neg(final MethodVisitor method, final int programPoint) {
+ method.visitInsn(DNEG);
+ return NUMBER;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/types/NumericType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/types/NumericType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,6 +29,8 @@
+ * This is a numeric type, i.e. NUMBER, LONG, INT, INT32.
+ */
+ public abstract class NumericType extends Type implements BytecodeNumericOps {
++ private static final long serialVersionUID = 1L;
++
+ /**
+ * Constructor
+ *
+--- ./nashorn/src/jdk/nashorn/internal/codegen/types/ObjectType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/types/ObjectType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -47,6 +47,7 @@
+ * contain a class that is a more specialized object
+ */
+ class ObjectType extends Type {
++ private static final long serialVersionUID = 1L;
+
+ protected ObjectType() {
+ this(Object.class);
+@@ -65,8 +66,13 @@
+ }
+
+ @Override
+- public Type add(final MethodVisitor method) {
+- invokeStatic(method, ScriptRuntime.ADD);
++ public String getShortDescriptor() {
++ return getTypeClass() == Object.class ? "Object" : getTypeClass().getSimpleName();
++ }
++
++ @Override
++ public Type add(final MethodVisitor method, final int programPoint) {
++ invokestatic(method, ScriptRuntime.ADD);
+ return Type.OBJECT;
+ }
+
+@@ -74,7 +80,7 @@
+ public Type load(final MethodVisitor method, final int slot) {
+ assert slot != -1;
+ method.visitVarInsn(ALOAD, slot);
+- return Type.OBJECT;
++ return this;
+ }
+
+ @Override
+@@ -86,13 +92,21 @@
+ @Override
+ public Type loadUndefined(final MethodVisitor method) {
+ method.visitFieldInsn(GETSTATIC, className(ScriptRuntime.class), "UNDEFINED", typeDescriptor(Undefined.class));
++ return UNDEFINED;
++ }
++
++ @Override
++ public Type loadForcedInitializer(final MethodVisitor method) {
++ method.visitInsn(ACONST_NULL);
++ // TODO: do we need a special type for null, e.g. Type.NULL? It should be assignable to any other object type
++ // without a checkast in convert.
+ return OBJECT;
+ }
+
+ @Override
+ public Type loadEmpty(final MethodVisitor method) {
+ method.visitFieldInsn(GETSTATIC, className(ScriptRuntime.class), "EMPTY", typeDescriptor(Undefined.class));
+- return OBJECT;
++ return UNDEFINED;
+ }
+
+ @Override
+@@ -108,10 +122,10 @@
+ method.visitLdcInsn(c);
+ return Type.typeFor(MethodHandle.class);
+ } else {
+- assert false : "implementation missing for class " + c.getClass() + " value=" + c;
++ throw new UnsupportedOperationException("implementation missing for class " + c.getClass() + " value=" + c);
+ }
+
+- return OBJECT;
++ return Type.OBJECT;
+ }
+
+ @Override
+@@ -138,6 +152,10 @@
+ }
+ return to;
+ } else if (to.isObject()) {
++ final Class<?> toClass = to.getTypeClass();
++ if(!toClass.isAssignableFrom(getTypeClass())) {
++ method.visitTypeInsn(CHECKCAST, CompilerConstants.className(toClass));
++ }
+ return to;
+ }
+ } else if (isString()) {
+@@ -145,17 +163,19 @@
+ }
+
+ if (to.isInteger()) {
+- invokeStatic(method, JSType.TO_INT32);
++ invokestatic(method, JSType.TO_INT32);
+ } else if (to.isNumber()) {
+- invokeStatic(method, JSType.TO_NUMBER);
++ invokestatic(method, JSType.TO_NUMBER);
+ } else if (to.isLong()) {
+- invokeStatic(method, JSType.TO_INT64);
++ invokestatic(method, JSType.TO_LONG);
+ } else if (to.isBoolean()) {
+- invokeStatic(method, JSType.TO_BOOLEAN);
++ invokestatic(method, JSType.TO_BOOLEAN);
+ } else if (to.isString()) {
+- invokeStatic(method, JSType.TO_PRIMITIVE_TO_STRING);
++ invokestatic(method, JSType.TO_PRIMITIVE_TO_STRING);
++ } else if (to.isCharSequence()) {
++ invokestatic(method, JSType.TO_PRIMITIVE_TO_CHARSEQUENCE);
+ } else {
+- assert false : "Illegal conversion " + this + " -> " + to + " " + isString() + " " + toString;
++ throw new UnsupportedOperationException("Illegal conversion " + this + " -> " + to + " " + isString() + " " + toString);
+ }
+
+ return to;
+@@ -165,4 +185,9 @@
+ public void _return(final MethodVisitor method) {
+ method.visitInsn(ARETURN);
+ }
++
++ @Override
++ public char getBytecodeStackType() {
++ return 'A';
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/codegen/types/Range.java Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,705 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 jdk.nashorn.internal.codegen.types;
+-
+-import java.util.Arrays;
+-import java.util.Collections;
+-import java.util.List;
+-
+-import jdk.nashorn.internal.runtime.DebugLogger;
+-import jdk.nashorn.internal.runtime.JSType;
+-
+-/**
+- * Represents the value range of a symbol.
+- */
+-public abstract class Range {
+-
+- private static final Range GENERIC_RANGE = new Range() {
+- @Override
+- public Type getType() {
+- return Type.OBJECT;
+- }
+- };
+-
+- private static final Range NUMBER_RANGE = new Range() {
+- @Override
+- public Type getType() {
+- return Type.NUMBER;
+- }
+- };
+-
+- private static final Range UNKNOWN_RANGE = new Range() {
+- @Override
+- public Type getType() {
+- return Type.UNKNOWN;
+- }
+-
+- @Override
+- public boolean isUnknown() {
+- return true;
+- }
+- };
+-
+- private static class IntegerRange extends Range {
+- private final long min;
+- private final long max;
+- private final Type type;
+-
+- private IntegerRange(final long min, final long max) {
+- assert min <= max;
+- this.min = min;
+- this.max = max;
+- this.type = typeFromRange(min, max);
+- }
+-
+- private static Type typeFromRange(final long from, final long to) {
+- if (from >= Integer.MIN_VALUE && to <= Integer.MAX_VALUE) {
+- return Type.INT;
+- }
+- return Type.LONG;
+- }
+-
+- @Override
+- public Type getType() {
+- return type;
+- }
+-
+- public long getMin() {
+- return min;
+- }
+-
+- public long getMax() {
+- return max;
+- }
+-
+- @Override
+- public boolean isIntegerConst() {
+- return getMin() == getMax();
+- }
+-
+- private long getBitMask() {
+- if (min == max) {
+- return min;
+- }
+-
+- if (min < 0) {
+- return ~0L;
+- }
+-
+- long mask = 1;
+- while (mask < max) {
+- mask = (mask << 1) | 1;
+- }
+- return mask;
+- }
+-
+- @Override
+- public boolean equals(final Object obj) {
+- if (obj instanceof IntegerRange) {
+- final IntegerRange other = (IntegerRange)obj;
+- return this.type == other.type && this.min == other.min && this.max == other.max;
+- }
+- return false;
+- }
+-
+- @Override
+- public int hashCode() {
+- return Long.hashCode(min) ^ Long.hashCode(max);
+- }
+-
+- @Override
+- public String toString() {
+- return super.toString() + "[" + min +", " + max + "]";
+- }
+- }
+-
+- /**
+- * Get narrowest type for this range
+- * @return type
+- */
+- public abstract Type getType();
+-
+- /**
+- * Is this range unknown
+- * @return true if unknown
+- */
+- public boolean isUnknown() {
+- return false;
+- }
+-
+- /**
+- * Check if an integer is enough to span this range
+- * @return true if integer is enough
+- */
+- public boolean isIntegerType() {
+- return this instanceof IntegerRange;
+- }
+-
+- /**
+- * Check if an integer is enough to span this range
+- * @return true if integer is enough
+- */
+- public boolean isIntegerConst() {
+- return false;
+- }
+-
+- /**
+- * Create an unknown range - this is most likely a singleton object
+- * and it represents "we have no known range information"
+- * @return the range
+- */
+- public static Range createUnknownRange() {
+- return UNKNOWN_RANGE;
+- }
+-
+- /**
+- * Create a constant range: [value, value]
+- * @param value value
+- * @return the range
+- */
+- public static Range createRange(final int value) {
+- return createIntegerRange(value, value);
+- }
+-
+- /**
+- * Create a constant range: [value, value]
+- * @param value value
+- * @return the range
+- */
+- public static Range createRange(final long value) {
+- return createIntegerRange(value, value);
+- }
+-
+- /**
+- * Create a constant range: [value, value]
+- * @param value value
+- * @return the range
+- */
+- public static Range createRange(final double value) {
+- if (isRepresentableAsLong(value)) {
+- return createIntegerRange((long) value, (long) value);
+- }
+- return createNumberRange();
+- }
+-
+- /**
+- * Create a constant range: [value, value]
+- * @param value value
+- * @return the range
+- */
+- public static Range createRange(final Object value) {
+- if (value instanceof Integer) {
+- return createRange((int)value);
+- } else if (value instanceof Long) {
+- return createRange((long)value);
+- } else if (value instanceof Double) {
+- return createRange((double)value);
+- }
+-
+- return createGenericRange();
+- }
+-
+- /**
+- * Create a generic range - object symbol that carries no range
+- * information
+- * @return the range
+- */
+- public static Range createGenericRange() {
+- return GENERIC_RANGE;
+- }
+-
+- /**
+- * Create a number range - number symbol that carries no range
+- * information
+- * @return the range
+- */
+- public static Range createNumberRange() {
+- return NUMBER_RANGE;
+- }
+-
+- /**
+- * Create an integer range [min, max]
+- * @param min minimum value, inclusive
+- * @param max maximum value, inclusive
+- * @return the range
+- */
+- public static IntegerRange createIntegerRange(final long min, final long max) {
+- return new IntegerRange(min, max);
+- }
+-
+- /**
+- * Create an integer range of maximum type width for the given type
+- * @param type the type
+- * @return the range
+- */
+- public static IntegerRange createIntegerRange(final Type type) {
+- assert type.isNumeric() && !type.isNumber();
+- final long min;
+- final long max;
+- if (type.isInteger()) {
+- min = Integer.MIN_VALUE;
+- max = Integer.MAX_VALUE;
+- } else if (type.isLong()) {
+- min = Long.MIN_VALUE;
+- max = Long.MAX_VALUE;
+- } else {
+- throw new AssertionError(); //type incompatible with integer range
+- }
+- return new IntegerRange(min, max);
+- }
+-
+- /**
+- * Create an range of maximum type width for the given type
+- * @param type the type
+- * @return the range
+- */
+- public static Range createTypeRange(final Type type) {
+- if (type.isNumber()) {
+- return createNumberRange();
+- } else if (type.isNumeric()) {
+- return createIntegerRange(type);
+- } else {
+- return createGenericRange();
+- }
+- }
+-
+- // check that add doesn't overflow
+- private static boolean checkAdd(final long a, final long b) {
+- final long result = a + b;
+- return ((a ^ result) & (b ^ result)) >= 0;
+- }
+-
+- // check that sub doesn't overflow
+- private static boolean checkSub(final long a, final long b) {
+- final long result = a - b;
+- return ((a ^ result) & (b ^ result)) >= 0;
+- }
+-
+- private static boolean checkMul(final long a, final long b) {
+- // TODO correct overflow check
+- return a >= Integer.MIN_VALUE && a <= Integer.MAX_VALUE && b >= Integer.MIN_VALUE && b <= Integer.MAX_VALUE;
+- }
+-
+- /**
+- * The range functionality class responsible for merging ranges and drawing
+- * range conclusions from operations executed
+- */
+- public static class Functionality {
+- /** logger */
+- protected final DebugLogger log;
+-
+- /**
+- * Constructor
+- * @param log logger
+- */
+- public Functionality(final DebugLogger log) {
+- this.log = log;
+- }
+-
+- /**
+- * Join two ranges
+- * @param a first range
+- * @param b second range
+- * @return the joined range
+- */
+- public Range join(final Range a, final Range b) {
+- if (a.equals(b)) {
+- return a;
+- }
+-
+- Type joinedType = a.getType();
+- if (a.getType() != b.getType()) {
+- if (a.isUnknown()) {
+- return b;
+- }
+- if (b.isUnknown()) {
+- return a;
+- }
+-
+- joinedType = Type.widest(a.getType(), b.getType());
+- }
+-
+- if (joinedType.isInteger() || joinedType.isLong()) {
+- return createIntegerRange(
+- Math.min(((IntegerRange) a).getMin(), ((IntegerRange) b).getMin()),
+- Math.max(((IntegerRange) a).getMax(), ((IntegerRange) b).getMax()));
+- }
+-
+- return createTypeRange(joinedType);
+- }
+-
+- /**
+- * Add operation
+- * @param a range of first symbol to be added
+- * @param b range of second symbol to be added
+- * @return resulting range representing the value range after add
+- */
+- public Range add(final Range a, final Range b) {
+- if (a.isIntegerType() && b.isIntegerType()) {
+- final IntegerRange lhs = (IntegerRange)a;
+- final IntegerRange rhs = (IntegerRange)b;
+- if (checkAdd(lhs.getMin(), rhs.getMin()) && checkAdd(lhs.getMax(), rhs.getMax())) {
+- return createIntegerRange(lhs.getMin() + rhs.getMin(), lhs.getMax() + rhs.getMax());
+- }
+- }
+-
+- if (a.getType().isNumeric() && b.getType().isNumeric()) {
+- return createNumberRange();
+- }
+-
+- return createGenericRange();
+- }
+-
+- /**
+- * Sub operation
+- * @param a range of first symbol to be subtracted
+- * @param b range of second symbol to be subtracted
+- * @return resulting range representing the value range after subtraction
+- */
+- public Range sub(final Range a, final Range b) {
+- if (a.isIntegerType() && b.isIntegerType()) {
+- final IntegerRange lhs = (IntegerRange)a;
+- final IntegerRange rhs = (IntegerRange)b;
+- if (checkSub(lhs.getMin(), rhs.getMax()) && checkSub(lhs.getMax(), rhs.getMin())) {
+- return createIntegerRange(lhs.getMin() - rhs.getMax(), lhs.getMax() - rhs.getMin());
+- }
+- }
+-
+- if (a.getType().isNumeric() && b.getType().isNumeric()) {
+- return createNumberRange();
+- }
+-
+- return createGenericRange();
+- }
+-
+- /**
+- * Mul operation
+- * @param a range of first symbol to be multiplied
+- * @param b range of second symbol to be multiplied
+- * @return resulting range representing the value range after multiplication
+- */
+- public Range mul(final Range a, final Range b) {
+- if (a.isIntegerType() && b.isIntegerType()) {
+- final IntegerRange lhs = (IntegerRange)a;
+- final IntegerRange rhs = (IntegerRange)b;
+-
+- //ensure that nothing ever overflows or underflows
+- if (checkMul(lhs.getMin(), rhs.getMin()) &&
+- checkMul(lhs.getMax(), rhs.getMax()) &&
+- checkMul(lhs.getMin(), rhs.getMax()) &&
+- checkMul(lhs.getMax(), rhs.getMin())) {
+-
+- final List<Long> results =
+- Arrays.asList(
+- lhs.getMin() * rhs.getMin(),
+- lhs.getMin() * rhs.getMax(),
+- lhs.getMax() * rhs.getMin(),
+- lhs.getMax() * rhs.getMax());
+- return createIntegerRange(Collections.min(results), Collections.max(results));
+- }
+- }
+-
+- if (a.getType().isNumeric() && b.getType().isNumeric()) {
+- return createNumberRange();
+- }
+-
+- return createGenericRange();
+- }
+-
+- /**
+- * Neg operation
+- * @param a range of value symbol to be negated
+- * @return resulting range representing the value range after neg
+- */
+- public Range neg(final Range a) {
+- if (a.isIntegerType()) {
+- final IntegerRange rhs = (IntegerRange)a;
+- if (rhs.getMin() != Long.MIN_VALUE && rhs.getMax() != Long.MIN_VALUE) {
+- return createIntegerRange(-rhs.getMax(), -rhs.getMin());
+- }
+- }
+-
+- if (a.getType().isNumeric()) {
+- return createNumberRange();
+- }
+-
+- return createGenericRange();
+- }
+-
+- /**
+- * Bitwise and operation
+- * @param a range of first symbol to be and:ed
+- * @param b range of second symbol to be and:ed
+- * @return resulting range representing the value range after and
+- */
+- public Range and(final Range a, final Range b) {
+- if (a.isIntegerType() && b.isIntegerType()) {
+- final int resultMask = (int) (((IntegerRange)a).getBitMask() & ((IntegerRange)b).getBitMask());
+- if (resultMask >= 0) {
+- return createIntegerRange(0, resultMask);
+- }
+- } else if (a.isUnknown() && b.isIntegerType()) {
+- final long operandMask = ((IntegerRange)b).getBitMask();
+- if (operandMask >= 0) {
+- return createIntegerRange(0, operandMask);
+- }
+- } else if (a.isIntegerType() && b.isUnknown()) {
+- final long operandMask = ((IntegerRange)a).getBitMask();
+- if (operandMask >= 0) {
+- return createIntegerRange(0, operandMask);
+- }
+- }
+-
+- return createTypeRange(Type.INT);
+- }
+-
+- /**
+- * Bitwise or operation
+- * @param a range of first symbol to be or:ed
+- * @param b range of second symbol to be or:ed
+- * @return resulting range representing the value range after or
+- */
+- public Range or(final Range a, final Range b) {
+- if (a.isIntegerType() && b.isIntegerType()) {
+- final int resultMask = (int)(((IntegerRange)a).getBitMask() | ((IntegerRange)b).getBitMask());
+- if (resultMask >= 0) {
+- return createIntegerRange(0, resultMask);
+- }
+- }
+-
+- return createTypeRange(Type.INT);
+- }
+-
+- /**
+- * Bitwise xor operation
+- * @param a range of first symbol to be xor:ed
+- * @param b range of second symbol to be xor:ed
+- * @return resulting range representing the value range after and
+- */
+- public Range xor(final Range a, final Range b) {
+- if (a.isIntegerConst() && b.isIntegerConst()) {
+- return createRange(((IntegerRange)a).getMin() ^ ((IntegerRange)b).getMin());
+- }
+-
+- if (a.isIntegerType() && b.isIntegerType()) {
+- final int resultMask = (int)(((IntegerRange)a).getBitMask() | ((IntegerRange)b).getBitMask());
+- if (resultMask >= 0) {
+- return createIntegerRange(0, createIntegerRange(0, resultMask).getBitMask());
+- }
+- }
+- return createTypeRange(Type.INT);
+- }
+-
+- /**
+- * Bitwise shl operation
+- * @param a range of first symbol to be shl:ed
+- * @param b range of second symbol to be shl:ed
+- * @return resulting range representing the value range after shl
+- */
+- public Range shl(final Range a, final Range b) {
+- if (b.isIntegerType() && b.isIntegerConst()) {
+- final IntegerRange left = (IntegerRange)(a.isIntegerType() ? a : createTypeRange(Type.INT));
+- final int shift = (int)((IntegerRange) b).getMin() & 0x1f;
+- final int min = (int)left.getMin() << shift;
+- final int max = (int)left.getMax() << shift;
+- if (min >> shift == left.getMin() && max >> shift == left.getMax()) {
+- return createIntegerRange(min, max);
+- }
+- }
+-
+- return createTypeRange(Type.INT);
+- }
+-
+- /**
+- * Bitwise shr operation
+- * @param a range of first symbol to be shr:ed
+- * @param b range of second symbol to be shr:ed
+- * @return resulting range representing the value range after shr
+- */
+- public Range shr(final Range a, final Range b) {
+- if (b.isIntegerType() && b.isIntegerConst()) {
+- final long shift = ((IntegerRange) b).getMin() & 0x1f;
+- final IntegerRange left = (IntegerRange)(a.isIntegerType() ? a : createTypeRange(Type.INT));
+- if (left.getMin() >= 0) {
+- long min = left.getMin() >>> shift;
+- long max = left.getMax() >>> shift;
+- return createIntegerRange(min, max);
+- } else if (shift >= 1) {
+- return createIntegerRange(0, JSType.MAX_UINT >>> shift);
+- }
+- }
+-
+- return createTypeRange(Type.INT);
+- }
+-
+- /**
+- * Bitwise sar operation
+- * @param a range of first symbol to be sar:ed
+- * @param b range of second symbol to be sar:ed
+- * @return resulting range representing the value range after sar
+- */
+- public Range sar(final Range a, final Range b) {
+- if (b.isIntegerType() && b.isIntegerConst()) {
+- final IntegerRange left = (IntegerRange)(a.isIntegerType() ? a : createTypeRange(Type.INT));
+- final long shift = ((IntegerRange) b).getMin() & 0x1f;
+- final long min = left.getMin() >> shift;
+- final long max = left.getMax() >> shift;
+- return createIntegerRange(min, max);
+- }
+-
+- return createTypeRange(Type.INT);
+- }
+-
+- /**
+- * Modulo operation
+- * @param a range of first symbol to the mod operation
+- * @param b range of second symbol to be mod operation
+- * @return resulting range representing the value range after mod
+- */
+- public Range mod(final Range a, final Range b) {
+- if (a.isIntegerType() && b.isIntegerType()) {
+- final IntegerRange rhs = (IntegerRange) b;
+- if (rhs.getMin() > 0 || rhs.getMax() < 0) { // divisor range must not include 0
+- final long absmax = Math.max(Math.abs(rhs.getMin()), Math.abs(rhs.getMax())) - 1;
+- return createIntegerRange(rhs.getMin() > 0 ? 0 : -absmax, rhs.getMax() < 0 ? 0 : +absmax);
+- }
+- }
+- return createTypeRange(Type.NUMBER);
+- }
+-
+- /**
+- * Division operation
+- * @param a range of first symbol to the division
+- * @param b range of second symbol to be division
+- * @return resulting range representing the value range after division
+- */
+- public Range div(final Range a, final Range b) {
+- // TODO
+- return createTypeRange(Type.NUMBER);
+- }
+- }
+-
+- /**
+- * Simple trace functionality that will log range creation
+- */
+- public static class TraceFunctionality extends Functionality {
+- TraceFunctionality(final DebugLogger log) {
+- super(log);
+- }
+-
+- private Range trace(final Range result, final String operation, final Range... operands) {
+- log.fine("range::" + operation + Arrays.toString(operands) + " => " + result);
+- return result;
+- }
+-
+- @Override
+- public Range join(final Range a, final Range b) {
+- final Range result = super.join(a, b);
+- if (!a.equals(b)) {
+- trace(result, "join", a, b);
+- }
+- return result;
+- }
+-
+- @Override
+- public Range add(final Range a, final Range b) {
+- return trace(super.add(a, b), "add", a, b);
+- }
+-
+- @Override
+- public Range sub(final Range a, final Range b) {
+- return trace(super.sub(a, b), "sub", a, b);
+- }
+-
+- @Override
+- public Range mul(final Range a, final Range b) {
+- return trace(super.mul(a, b), "mul", a, b);
+- }
+-
+- @Override
+- public Range neg(final Range a) {
+- return trace(super.neg(a), "neg", a);
+- }
+-
+- @Override
+- public Range and(final Range a, final Range b) {
+- return trace(super.and(a, b), "and", a, b);
+- }
+-
+- @Override
+- public Range or(final Range a, final Range b) {
+- return trace(super.or(a, b), "or", a, b);
+- }
+-
+- @Override
+- public Range xor(final Range a, final Range b) {
+- return trace(super.xor(a, b), "xor", a, b);
+- }
+-
+- @Override
+- public Range shl(final Range a, final Range b) {
+- return trace(super.shl(a, b), "shl", a, b);
+- }
+-
+- @Override
+- public Range shr(final Range a, final Range b) {
+- return trace(super.shr(a, b), "shr", a, b);
+- }
+-
+- @Override
+- public Range sar(final Range a, final Range b) {
+- return trace(super.sar(a, b), "sar", a, b);
+- }
+-
+- @Override
+- public Range mod(final Range a, final Range b) {
+- return trace(super.mod(a, b), "mod", a, b);
+- }
+-
+- @Override
+- public Range div(final Range a, final Range b) {
+- return trace(super.div(a, b), "div", a, b);
+- }
+- }
+-
+- @Override
+- public String toString() {
+- return String.valueOf(getType());
+- }
+-
+- @SuppressWarnings("unused")
+- private static boolean isRepresentableAsInt(final double number) {
+- return (int)number == number && !isNegativeZero(number);
+- }
+-
+- private static boolean isRepresentableAsLong(final double number) {
+- return (long)number == number && !isNegativeZero(number);
+- }
+-
+- private static boolean isNegativeZero(final double number) {
+- return Double.doubleToLongBits(number) == Double.doubleToLongBits(-0.0);
+- }
+-}
+--- ./nashorn/src/jdk/nashorn/internal/codegen/types/Type.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/codegen/types/Type.java Wed Feb 04 12:14:47 2015 -0800
+@@ -33,6 +33,7 @@
+ import static jdk.internal.org.objectweb.asm.Opcodes.DUP2_X2;
+ import static jdk.internal.org.objectweb.asm.Opcodes.DUP_X1;
+ import static jdk.internal.org.objectweb.asm.Opcodes.DUP_X2;
++import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC;
+ import static jdk.internal.org.objectweb.asm.Opcodes.IALOAD;
+ import static jdk.internal.org.objectweb.asm.Opcodes.IASTORE;
+ import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC;
+@@ -45,13 +46,28 @@
+ import static jdk.internal.org.objectweb.asm.Opcodes.T_DOUBLE;
+ import static jdk.internal.org.objectweb.asm.Opcodes.T_INT;
+ import static jdk.internal.org.objectweb.asm.Opcodes.T_LONG;
++import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
+
++import java.io.DataInput;
++import java.io.DataOutput;
++import java.io.IOException;
++import java.io.Serializable;
++import java.lang.invoke.CallSite;
+ import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.lang.invoke.MethodType;
++import java.util.Collections;
++import java.util.Map;
++import java.util.TreeMap;
++import java.util.WeakHashMap;
+ import java.util.concurrent.ConcurrentHashMap;
+ import java.util.concurrent.ConcurrentMap;
++import jdk.internal.org.objectweb.asm.Handle;
+ import jdk.internal.org.objectweb.asm.MethodVisitor;
+ import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+-
++import jdk.nashorn.internal.runtime.ScriptObject;
++import jdk.nashorn.internal.runtime.Undefined;
++import jdk.nashorn.internal.runtime.linker.Bootstrap;
+
+ /**
+ * This is the representation of a JavaScript type, disassociated from java
+@@ -74,29 +90,44 @@
+ * INTs rather than OBJECTs
+ */
+
+-public abstract class Type implements Comparable<Type>, BytecodeOps {
++public abstract class Type implements Comparable<Type>, BytecodeOps, Serializable {
++ private static final long serialVersionUID = 1L;
+
+ /** Human readable name for type */
+- private final String name;
++ private transient final String name;
+
+ /** Descriptor for type */
+- private final String descriptor;
++ private transient final String descriptor;
+
+ /** The "weight" of the type. Used for picking widest/least specific common type */
+- private final int weight;
++ private transient final int weight;
+
+ /** How many bytecode slots does this type occupy */
+- private final int slots;
++ private transient final int slots;
+
+ /** The class for this type */
+ private final Class<?> clazz;
+
++ /**
++ * Cache for internal types - this is a query that requires complex stringbuilding inside
++ * ASM and it saves startup time to cache the type mappings
++ */
++ private static final Map<Class<?>, jdk.internal.org.objectweb.asm.Type> INTERNAL_TYPE_CACHE =
++ Collections.synchronizedMap(new WeakHashMap<Class<?>, jdk.internal.org.objectweb.asm.Type>());
++
++ /** Internal ASM type for this Type - computed once at construction */
++ private transient final jdk.internal.org.objectweb.asm.Type internalType;
++
+ /** Weights are used to decide which types are "wider" than other types */
+ protected static final int MIN_WEIGHT = -1;
+
+ /** Set way below Integer.MAX_VALUE to prevent overflow when adding weights. Objects are still heaviest. */
+ protected static final int MAX_WEIGHT = 20;
+
++ static final Call BOOTSTRAP = staticCallNoLookup(Bootstrap.class, "mathBootstrap", CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, int.class);
++
++ static final Handle MATHBOOTSTRAP = new Handle(H_INVOKESTATIC, BOOTSTRAP.className(), "mathBootstrap", BOOTSTRAP.descriptor());
++
+ /**
+ * Constructor
+ *
+@@ -105,12 +136,13 @@
+ * @param slots how many bytecode slots the type takes up
+ */
+ Type(final String name, final Class<?> clazz, final int weight, final int slots) {
+- this.name = name;
+- this.clazz = clazz;
+- this.descriptor = jdk.internal.org.objectweb.asm.Type.getDescriptor(clazz);
+- this.weight = weight;
++ this.name = name;
++ this.clazz = clazz;
++ this.descriptor = jdk.internal.org.objectweb.asm.Type.getDescriptor(clazz);
++ this.weight = weight;
+ assert weight >= MIN_WEIGHT && weight <= MAX_WEIGHT : "illegal type weight: " + weight;
+- this.slots = slots;
++ this.slots = slots;
++ this.internalType = getInternalType(clazz);
+ }
+
+ /**
+@@ -149,6 +181,17 @@
+ }
+
+ /**
++ * Returns the character describing the bytecode type for this value on the stack or local variable, identical to
++ * what would be used as the prefix for a bytecode {@code LOAD} or {@code STORE} instruction, therefore it must be
++ * one of {@code A, F, D, I, L}. Also, the special value {@code U} is used for local variable slots that haven't
++ * been initialized yet (it can't appear for a value pushed to the operand stack, those always have known values).
++ * Note that while we allow all JVM internal types, Nashorn doesn't necessarily use them all - currently we don't
++ * have floats, only doubles, but that might change in the future.
++ * @return the character describing the bytecode type for this value on the stack.
++ */
++ public abstract char getBytecodeStackType();
++
++ /**
+ * Generate a method descriptor given a return type and a param array
+ *
+ * @param returnType return type
+@@ -181,6 +224,20 @@
+ }
+
+ /**
++ * Return a character representing {@code type} in a method signature.
++ *
++ * @param type parameter type
++ * @return descriptor character
++ */
++ public static char getShortSignatureDescriptor(final Type type) {
++ // Use 'Z' for boolean parameters as we need to distinguish from int
++ if (type instanceof BooleanType) {
++ return 'Z';
++ }
++ return type.getBytecodeStackType();
++ }
++
++ /**
+ * Return the type for an internal type, package private - do not use
+ * outside code gen
+ *
+@@ -199,7 +256,11 @@
+ case jdk.internal.org.objectweb.asm.Type.DOUBLE:
+ return NUMBER;
+ case jdk.internal.org.objectweb.asm.Type.OBJECT:
+- return OBJECT;
++ try {
++ return Type.typeFor(Class.forName(itype.getClassName()));
++ } catch(final ClassNotFoundException e) {
++ throw new AssertionError(e);
++ }
+ case jdk.internal.org.objectweb.asm.Type.VOID:
+ return null;
+ case jdk.internal.org.objectweb.asm.Type.ARRAY:
+@@ -248,19 +309,88 @@
+ return types;
+ }
+
++ /**
++ * Write a map of {@code int} to {@code Type} to an output stream. This is used to store deoptimization state.
++ *
++ * @param typeMap the type map
++ * @param output data output
++ * @throws IOException if write cannot be completed
++ */
++ public static void writeTypeMap(final Map<Integer, Type> typeMap, final DataOutput output) throws IOException {
++ if (typeMap == null) {
++ output.writeInt(0);
++ } else {
++ output.writeInt(typeMap.size());
++ for(final Map.Entry<Integer, Type> e: typeMap.entrySet()) {
++ output.writeInt(e.getKey());
++ final byte typeChar;
++ final Type type = e.getValue();
++ if(type == Type.OBJECT) {
++ typeChar = 'L';
++ } else if (type == Type.NUMBER) {
++ typeChar = 'D';
++ } else if (type == Type.LONG) {
++ typeChar = 'J';
++ } else {
++ throw new AssertionError();
++ }
++ output.writeByte(typeChar);
++ }
++ }
++ }
++
++ /**
++ * Read a map of {@code int} to {@code Type} from an input stream. This is used to store deoptimization state.
++ *
++ * @param input data input
++ * @return type map
++ * @throws IOException if read cannot be completed
++ */
++ public static Map<Integer, Type> readTypeMap(final DataInput input) throws IOException {
++ final int size = input.readInt();
++ if (size <= 0) {
++ return null;
++ }
++ final Map<Integer, Type> map = new TreeMap<>();
++ for(int i = 0; i < size; ++i) {
++ final int pp = input.readInt();
++ final int typeChar = input.readByte();
++ final Type type;
++ switch (typeChar) {
++ case 'L': type = Type.OBJECT; break;
++ case 'D': type = Type.NUMBER; break;
++ case 'J': type = Type.LONG; break;
++ default: continue;
++ }
++ map.put(pp, type);
++ }
++ return map;
++ }
++
+ static jdk.internal.org.objectweb.asm.Type getInternalType(final String className) {
+ return jdk.internal.org.objectweb.asm.Type.getType(className);
+ }
+
+ private jdk.internal.org.objectweb.asm.Type getInternalType() {
+- return jdk.internal.org.objectweb.asm.Type.getType(getTypeClass());
++ return internalType;
++ }
++
++ private static jdk.internal.org.objectweb.asm.Type lookupInternalType(final Class<?> type) {
++ final Map<Class<?>, jdk.internal.org.objectweb.asm.Type> c = INTERNAL_TYPE_CACHE;
++ jdk.internal.org.objectweb.asm.Type itype = c.get(type);
++ if (itype != null) {
++ return itype;
++ }
++ itype = jdk.internal.org.objectweb.asm.Type.getType(type);
++ c.put(type, itype);
++ return itype;
+ }
+
+ private static jdk.internal.org.objectweb.asm.Type getInternalType(final Class<?> type) {
+- return jdk.internal.org.objectweb.asm.Type.getType(type);
++ return lookupInternalType(type);
+ }
+
+- static void invokeStatic(final MethodVisitor method, final Call call) {
++ static void invokestatic(final MethodVisitor method, final Call call) {
+ method.visitMethodInsn(INVOKESTATIC, call.className(), call.name(), call.descriptor(), false);
+ }
+
+@@ -373,6 +503,14 @@
+ }
+
+ /**
++ * Is this a primitive type (e.g int, long, double, boolean)
++ * @return true if primitive
++ */
++ public boolean isPrimitive() {
++ return !isObject();
++ }
++
++ /**
+ * Determines whether a type is a STRING type
+ *
+ * @return true if object type, false otherwise
+@@ -382,6 +520,15 @@
+ }
+
+ /**
++ * Determines whether a type is a CHARSEQUENCE type used internally strings
++ *
++ * @return true if CharSequence (internal string) type, false otherwise
++ */
++ public boolean isCharSequence() {
++ return this.equals(Type.CHARSEQUENCE);
++ }
++
++ /**
+ * Determine if two types are equivalent, i.e. need no conversion
+ *
+ * @param type the second type to check
+@@ -389,7 +536,7 @@
+ * @return true if types are equivalent, false otherwise
+ */
+ public boolean isEquivalentTo(final Type type) {
+- return this.weight() == type.weight() || (isObject() && type.isObject());
++ return this.weight() == type.weight() || isObject() && type.isObject();
+ }
+
+ /**
+@@ -439,6 +586,7 @@
+ public int getSlots() {
+ return slots;
+ }
++
+ /**
+ * Returns the widest or most common of two types
+ *
+@@ -462,6 +610,49 @@
+ }
+
+ /**
++ * Returns the widest or most common of two types, given as classes
++ *
++ * @param type0 type one
++ * @param type1 type two
++ *
++ * @return the widest type
++ */
++ public static Class<?> widest(final Class<?> type0, final Class<?> type1) {
++ return widest(Type.typeFor(type0), Type.typeFor(type1)).getTypeClass();
++ }
++
++ /**
++ * When doing widening for return types of a function or a ternary operator, it is not valid to widen a boolean to
++ * anything other than object. Note that this wouldn't be necessary if {@code Type.widest} did not allow
++ * boolean-to-number widening. Eventually, we should address it there, but it affects too many other parts of the
++ * system and is sometimes legitimate (e.g. whenever a boolean value would undergo ToNumber conversion anyway).
++ * @param t1 type 1
++ * @param t2 type 2
++ * @return wider of t1 and t2, except if one is boolean and the other is neither boolean nor unknown, in which case
++ * {@code Type.OBJECT} is returned.
++ */
++ public static Type widestReturnType(final Type t1, final Type t2) {
++ if (t1.isUnknown()) {
++ return t2;
++ } else if (t2.isUnknown()) {
++ return t1;
++ } else if(t1.isBoolean() != t2.isBoolean() || t1.isNumeric() != t2.isNumeric()) {
++ return Type.OBJECT;
++ }
++ return Type.widest(t1, t2);
++ }
++
++ /**
++ * Returns a generic version of the type. Basically, if the type {@link #isObject()}, returns {@link #OBJECT},
++ * otherwise returns the type unchanged.
++ * @param type the type to generify
++ * @return the generified type
++ */
++ public static Type generic(final Type type) {
++ return type.isObject() ? Type.OBJECT : type;
++ }
++
++ /**
+ * Returns the narrowest or least common of two types
+ *
+ * @param type0 type one
+@@ -470,7 +661,25 @@
+ * @return the widest type
+ */
+ public static Type narrowest(final Type type0, final Type type1) {
+- return type0.weight() < type1.weight() ? type0 : type1;
++ return type0.narrowerThan(type1) ? type0 : type1;
++ }
++
++ /**
++ * Check whether this type is strictly narrower than another one
++ * @param type type to check against
++ * @return true if this type is strictly narrower
++ */
++ public boolean narrowerThan(final Type type) {
++ return weight() < type.weight();
++ }
++
++ /**
++ * Check whether this type is strictly wider than another one
++ * @param type type to check against
++ * @return true if this type is strictly wider
++ */
++ public boolean widerThan(final Type type) {
++ return weight() > type.weight();
+ }
+
+ /**
+@@ -549,6 +758,16 @@
+ return descriptor;
+ }
+
++ /**
++ * Return the descriptor of a type, short version
++ * Used mainly for debugging purposes
++ *
++ * @return the short descriptor
++ */
++ public String getShortDescriptor() {
++ return descriptor;
++ }
++
+ @Override
+ public String toString() {
+ return name;
+@@ -688,17 +907,17 @@
+ /**
+ * This is an integer type, i.e INT, INT32.
+ */
+- public static final Type INT = putInCache(new IntType());
++ public static final BitwiseType INT = putInCache(new IntType());
+
+ /**
+ * This is the number singleton, used for all number types
+ */
+- public static final Type NUMBER = putInCache(new NumberType());
++ public static final NumericType NUMBER = putInCache(new NumberType());
+
+ /**
+ * This is the long singleton, used for all long types
+ */
+- public static final Type LONG = putInCache(new LongType());
++ public static final BitwiseType LONG = putInCache(new LongType());
+
+ /**
+ * A string singleton
+@@ -706,14 +925,33 @@
+ public static final Type STRING = putInCache(new ObjectType(String.class));
+
+ /**
++ * This is the CharSequence singleton used to represent JS strings internally
++ * (either a {@code java.lang.String} or {@code jdk.nashorn.internal.runtime.ConsString}.
++ */
++ public static final Type CHARSEQUENCE = putInCache(new ObjectType(CharSequence.class));
++
++
++ /**
+ * This is the object singleton, used for all object types
+ */
+ public static final Type OBJECT = putInCache(new ObjectType());
+
+ /**
++ * A undefined singleton
++ */
++ public static final Type UNDEFINED = putInCache(new ObjectType(Undefined.class));
++
++ /**
++ * This is the singleton for ScriptObjects
++ */
++ public static final Type SCRIPT_OBJECT = putInCache(new ObjectType(ScriptObject.class));
++
++ /**
+ * This is the singleton for integer arrays
+ */
+ public static final ArrayType INT_ARRAY = new ArrayType(int[].class) {
++ private static final long serialVersionUID = 1L;
++
+ @Override
+ public void astore(final MethodVisitor method) {
+ method.visitInsn(IASTORE);
+@@ -741,6 +979,8 @@
+ * This is the singleton for long arrays
+ */
+ public static final ArrayType LONG_ARRAY = new ArrayType(long[].class) {
++ private static final long serialVersionUID = 1L;
++
+ @Override
+ public void astore(final MethodVisitor method) {
+ method.visitInsn(LASTORE);
+@@ -768,6 +1008,8 @@
+ * This is the singleton for numeric arrays
+ */
+ public static final ArrayType NUMBER_ARRAY = new ArrayType(double[].class) {
++ private static final long serialVersionUID = 1L;
++
+ @Override
+ public void astore(final MethodVisitor method) {
+ method.visitInsn(DASTORE);
+@@ -802,6 +1044,8 @@
+
+ /** This type, always an object type, just a toString override */
+ public static final Type THIS = new ObjectType() {
++ private static final long serialVersionUID = 1L;
++
+ @Override
+ public String toString() {
+ return "this";
+@@ -810,6 +1054,8 @@
+
+ /** Scope type, always an object type, just a toString override */
+ public static final Type SCOPE = new ObjectType() {
++ private static final long serialVersionUID = 1L;
++
+ @Override
+ public String toString() {
+ return "scope";
+@@ -820,11 +1066,60 @@
+ // EMPTY - used as a class that is absolutely not compatible with a type to represent "unknown"
+ }
+
++ private abstract static class ValueLessType extends Type {
++ private static final long serialVersionUID = 1L;
++
++ ValueLessType(final String name) {
++ super(name, Unknown.class, MIN_WEIGHT, 1);
++ }
++
++ @Override
++ public Type load(final MethodVisitor method, final int slot) {
++ throw new UnsupportedOperationException("load " + slot);
++ }
++
++ @Override
++ public void store(final MethodVisitor method, final int slot) {
++ throw new UnsupportedOperationException("store " + slot);
++ }
++
++ @Override
++ public Type ldc(final MethodVisitor method, final Object c) {
++ throw new UnsupportedOperationException("ldc " + c);
++ }
++
++ @Override
++ public Type loadUndefined(final MethodVisitor method) {
++ throw new UnsupportedOperationException("load undefined");
++ }
++
++ @Override
++ public Type loadForcedInitializer(final MethodVisitor method) {
++ throw new UnsupportedOperationException("load forced initializer");
++ }
++
++ @Override
++ public Type convert(final MethodVisitor method, final Type to) {
++ throw new UnsupportedOperationException("convert => " + to);
++ }
++
++ @Override
++ public void _return(final MethodVisitor method) {
++ throw new UnsupportedOperationException("return");
++ }
++
++ @Override
++ public Type add(final MethodVisitor method, final int programPoint) {
++ throw new UnsupportedOperationException("add");
++ }
++ }
++
+ /**
+ * This is the unknown type which is used as initial type for type
+ * inference. It has the minimum type width
+ */
+- public static final Type UNKNOWN = new Type("<unknown>", Unknown.class, MIN_WEIGHT, 1) {
++ public static final Type UNKNOWN = new ValueLessType("<unknown>") {
++ private static final long serialVersionUID = 1L;
+
+ @Override
+ public String getDescriptor() {
+@@ -832,48 +1127,39 @@
+ }
+
+ @Override
+- public Type load(final MethodVisitor method, final int slot) {
+- assert false : "unsupported operation";
+- return null;
++ public char getBytecodeStackType() {
++ return 'U';
++ }
++ };
++
++ /**
++ * This is the unknown type which is used as initial type for type
++ * inference. It has the minimum type width
++ */
++ public static final Type SLOT_2 = new ValueLessType("<slot_2>") {
++ private static final long serialVersionUID = 1L;
++
++ @Override
++ public String getDescriptor() {
++ return "<slot_2>";
+ }
+
+ @Override
+- public void store(final MethodVisitor method, final int slot) {
+- assert false : "unsupported operation";
+- }
+-
+- @Override
+- public Type ldc(final MethodVisitor method, final Object c) {
+- assert false : "unsupported operation";
+- return null;
+- }
+-
+- @Override
+- public Type loadUndefined(final MethodVisitor method) {
+- assert false : "unsupported operation";
+- return null;
+- }
+-
+- @Override
+- public Type convert(final MethodVisitor method, final Type to) {
+- assert false : "unsupported operation";
+- return null;
+- }
+-
+- @Override
+- public void _return(final MethodVisitor method) {
+- assert false : "unsupported operation";
+- }
+-
+- @Override
+- public Type add(final MethodVisitor method) {
+- assert false : "unsupported operation";
+- return null;
++ public char getBytecodeStackType() {
++ throw new UnsupportedOperationException("getBytecodeStackType");
+ }
+ };
+
+- private static <T extends Type> T putInCache(T type) {
++ private static <T extends Type> T putInCache(final T type) {
+ cache.put(type.getTypeClass(), type);
+ return type;
+ }
++
++ /**
++ * Read resolve
++ * @return resolved type
++ */
++ protected final Object readResolve() {
++ return Type.typeFor(clazz);
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/AccessNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/AccessNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,16 +25,21 @@
+
+ package jdk.nashorn.internal.ir;
+
++import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++import jdk.nashorn.internal.parser.Token;
++import jdk.nashorn.internal.parser.TokenType;
+
+ /**
+ * IR representation of a property access (period operator.)
+ */
+ @Immutable
+ public final class AccessNode extends BaseNode {
+- /** Property ident. */
+- private final IdentNode property;
++ private static final long serialVersionUID = 1L;
++
++ /** Property name. */
++ private final String property;
+
+ /**
+ * Constructor
+@@ -44,13 +49,13 @@
+ * @param base base node
+ * @param property property
+ */
+- public AccessNode(final long token, final int finish, final Expression base, final IdentNode property) {
++ public AccessNode(final long token, final int finish, final Expression base, final String property) {
+ super(token, finish, base, false);
+- this.property = property.setIsPropertyName();
++ this.property = property;
+ }
+
+- private AccessNode(final AccessNode accessNode, final Expression base, final IdentNode property, final boolean isFunction) {
+- super(accessNode, base, isFunction);
++ private AccessNode(final AccessNode accessNode, final Expression base, final String property, final boolean isFunction, final Type type, final int id) {
++ super(accessNode, base, isFunction, type, id);
+ this.property = property;
+ }
+
+@@ -62,59 +67,78 @@
+ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
+ if (visitor.enterAccessNode(this)) {
+ return visitor.leaveAccessNode(
+- setBase((Expression)base.accept(visitor)).
+- setProperty((IdentNode)property.accept(visitor)));
++ setBase((Expression)base.accept(visitor)));
+ }
+ return this;
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ final boolean needsParen = tokenType().needsParens(getBase().tokenType(), true);
+
++ if (printType) {
++ optimisticTypeToString(sb);
++ }
++
+ if (needsParen) {
+ sb.append('(');
+ }
+
+- base.toString(sb);
++ base.toString(sb, printType);
+
+ if (needsParen) {
+ sb.append(')');
+ }
+ sb.append('.');
+
+- sb.append(property.getName());
++ sb.append(property);
+ }
+
+ /**
+- * Get the property
++ * Get the property name
+ *
+- * @return the property IdentNode
++ * @return the property name
+ */
+- public IdentNode getProperty() {
++ public String getProperty() {
+ return property;
+ }
+
++ /**
++ * Return true if this node represents an index operation normally represented as {@link IndexNode}.
++ * @return true if an index access.
++ */
++ public boolean isIndex() {
++ return Token.descType(getToken()) == TokenType.LBRACKET;
++ }
++
+ private AccessNode setBase(final Expression base) {
+ if (this.base == base) {
+ return this;
+ }
+- return new AccessNode(this, base, property, isFunction());
+- }
+-
+- private AccessNode setProperty(final IdentNode property) {
+- if (this.property == property) {
+- return this;
+- }
+- return new AccessNode(this, base, property, isFunction());
++ return new AccessNode(this, base, property, isFunction(), type, programPoint);
+ }
+
+ @Override
+- public BaseNode setIsFunction() {
++ public AccessNode setType(final Type type) {
++ if (this.type == type) {
++ return this;
++ }
++ return new AccessNode(this, base, property, isFunction(), type, programPoint);
++ }
++
++ @Override
++ public AccessNode setProgramPoint(final int programPoint) {
++ if (this.programPoint == programPoint) {
++ return this;
++ }
++ return new AccessNode(this, base, property, isFunction(), type, programPoint);
++ }
++
++ @Override
++ public AccessNode setIsFunction() {
+ if (isFunction()) {
+ return this;
+ }
+- return new AccessNode(this, base, property, true);
++ return new AccessNode(this, base, property, true, type, programPoint);
+ }
+-
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/BaseNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/BaseNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,10 @@
+
+ package jdk.nashorn.internal.ir;
+
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
++
++import java.util.function.Function;
++import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+
+ /**
+@@ -34,13 +38,20 @@
+ * @see IndexNode
+ */
+ @Immutable
+-public abstract class BaseNode extends Expression implements FunctionCall {
++public abstract class BaseNode extends Expression implements FunctionCall, Optimistic {
++ private static final long serialVersionUID = 1L;
+
+ /** Base Node. */
+ protected final Expression base;
+
+ private final boolean isFunction;
+
++ /** Callsite type for this node, if overridden optimistically or conservatively depending on coercion */
++ protected final Type type;
++
++ /** Program point id */
++ protected final int programPoint;
++
+ /**
+ * Constructor
+ *
+@@ -51,8 +62,10 @@
+ */
+ public BaseNode(final long token, final int finish, final Expression base, final boolean isFunction) {
+ super(token, base.getStart(), finish);
+- this.base = base;
+- this.isFunction = isFunction;
++ this.base = base;
++ this.isFunction = isFunction;
++ this.type = null;
++ this.programPoint = INVALID_PROGRAM_POINT;
+ }
+
+ /**
+@@ -60,11 +73,15 @@
+ * @param baseNode node to inherit from
+ * @param base base
+ * @param isFunction is this a function
++ * @param callSiteType the callsite type for this base node, either optimistic or conservative
++ * @param programPoint program point id
+ */
+- protected BaseNode(final BaseNode baseNode, final Expression base, final boolean isFunction) {
++ protected BaseNode(final BaseNode baseNode, final Expression base, final boolean isFunction, final Type callSiteType, final int programPoint) {
+ super(baseNode);
+- this.base = base;
+- this.isFunction = isFunction;
++ this.base = base;
++ this.isFunction = isFunction;
++ this.type = callSiteType;
++ this.programPoint = programPoint;
+ }
+
+ /**
+@@ -80,6 +97,31 @@
+ return isFunction;
+ }
+
++ @Override
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
++ return type == null ? getMostPessimisticType() : type;
++ }
++
++ @Override
++ public int getProgramPoint() {
++ return programPoint;
++ }
++
++ @Override
++ public Type getMostOptimisticType() {
++ return Type.INT;
++ }
++
++ @Override
++ public Type getMostPessimisticType() {
++ return Type.OBJECT;
++ }
++
++ @Override
++ public boolean canBeOptimistic() {
++ return true;
++ }
++
+ /**
+ * Mark this node as being the callee operand of a {@link CallNode}.
+ * @return a base node identical to this one in all aspects except with its function flag set.
+--- ./nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,7 +25,15 @@
+
+ package jdk.nashorn.internal.ir;
+
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
++
++import java.util.Arrays;
++import java.util.Collections;
++import java.util.HashSet;
++import java.util.Set;
++import java.util.function.Function;
+ import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.ir.annotations.Ignore;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+ import jdk.nashorn.internal.parser.TokenType;
+@@ -34,12 +42,40 @@
+ * BinaryNode nodes represent two operand operations.
+ */
+ @Immutable
+-public final class BinaryNode extends Expression implements Assignment<Expression> {
++public final class BinaryNode extends Expression implements Assignment<Expression>, Optimistic {
++ private static final long serialVersionUID = 1L;
++
++ // Placeholder for "undecided optimistic ADD type". Unfortunately, we can't decide the type of ADD during optimistic
++ // type calculation as it can have local variables as its operands that will decide its ultimate type.
++ private static final Type OPTIMISTIC_UNDECIDED_TYPE = Type.typeFor(new Object(){/*empty*/}.getClass());
++
+ /** Left hand side argument. */
+ private final Expression lhs;
+
+ private final Expression rhs;
+
++ private final int programPoint;
++
++ private final Type type;
++
++ private transient Type cachedType;
++ private transient Object cachedTypeFunction;
++
++ @Ignore
++ private static final Set<TokenType> CAN_OVERFLOW =
++ Collections.unmodifiableSet(new HashSet<>(Arrays.asList(new TokenType[] {
++ TokenType.ADD,
++ TokenType.DIV,
++ TokenType.MOD,
++ TokenType.MUL,
++ TokenType.SUB,
++ TokenType.ASSIGN_ADD,
++ TokenType.ASSIGN_DIV,
++ TokenType.ASSIGN_MOD,
++ TokenType.ASSIGN_MUL,
++ TokenType.ASSIGN_SUB
++ })));
++
+ /**
+ * Constructor
+ *
+@@ -49,17 +85,25 @@
+ */
+ public BinaryNode(final long token, final Expression lhs, final Expression rhs) {
+ super(token, lhs.getStart(), rhs.getFinish());
++ assert !(isTokenType(TokenType.AND) || isTokenType(TokenType.OR)) || lhs instanceof JoinPredecessorExpression;
+ this.lhs = lhs;
+ this.rhs = rhs;
++ this.programPoint = INVALID_PROGRAM_POINT;
++ this.type = null;
+ }
+
+- private BinaryNode(final BinaryNode binaryNode, final Expression lhs, final Expression rhs) {
++ private BinaryNode(final BinaryNode binaryNode, final Expression lhs, final Expression rhs, final Type type, final int programPoint) {
+ super(binaryNode);
+ this.lhs = lhs;
+ this.rhs = rhs;
++ this.programPoint = programPoint;
++ this.type = type;
+ }
+
+- @Override
++ /**
++ * Returns true if the node is a comparison operation.
++ * @return true if the node is a comparison operation.
++ */
+ public boolean isComparison() {
+ switch (tokenType()) {
+ case EQ:
+@@ -77,6 +121,36 @@
+ }
+
+ /**
++ * Returns true if the node is a logical operation.
++ * @return true if the node is a logical operation.
++ */
++ public boolean isLogical() {
++ return isLogical(tokenType());
++ }
++
++ /**
++ * Returns true if the token type represents a logical operation.
++ * @param tokenType the token type
++ * @return true if the token type represents a logical operation.
++ */
++ public static boolean isLogical(final TokenType tokenType) {
++ switch (tokenType) {
++ case AND:
++ case OR:
++ return true;
++ default:
++ return false;
++ }
++ }
++
++ private static final Function<Symbol, Type> UNKNOWN_LOCALS = new Function<Symbol, Type>() {
++ @Override
++ public Type apply(final Symbol t) {
++ return null;
++ }
++ };
++
++ /**
+ * Return the widest possible type for this operation. This is used for compile time
+ * static type inference
+ *
+@@ -84,9 +158,62 @@
+ */
+ @Override
+ public Type getWidestOperationType() {
++ return getWidestOperationType(UNKNOWN_LOCALS);
++ }
++
++ /**
++ * Return the widest possible operand type for this operation.
++ *
++ * @return Type
++ */
++ public Type getWidestOperandType() {
+ switch (tokenType()) {
+ case SHR:
+ case ASSIGN_SHR:
++ return Type.INT;
++ case INSTANCEOF:
++ return Type.OBJECT;
++ default:
++ if (isComparison()) {
++ return Type.OBJECT;
++ }
++ return getWidestOperationType();
++ }
++ }
++
++ private Type getWidestOperationType(final Function<Symbol, Type> localVariableTypes) {
++ switch (tokenType()) {
++ case ADD:
++ case ASSIGN_ADD: {
++ // Compare this logic to decideType(Type, Type); it's similar, but it handles the optimistic type
++ // calculation case while this handles the conservative case.
++ final Type lhsType = lhs.getType(localVariableTypes);
++ final Type rhsType = rhs.getType(localVariableTypes);
++ if(lhsType == Type.BOOLEAN && rhsType == Type.BOOLEAN) {
++ // Will always fit in an int, as the value range is [0, 1, 2]. If we didn't treat them specially here,
++ // they'd end up being treated as generic INT operands and their sum would be conservatively considered
++ // to be a LONG in the generic case below; we can do better here.
++ return Type.INT;
++ } else if(isString(lhsType) || isString(rhsType)) {
++ // We can statically figure out that this is a string if either operand is a string. In this case, use
++ // CHARSEQUENCE to prevent it from being proactively flattened.
++ return Type.CHARSEQUENCE;
++ }
++ final Type widestOperandType = Type.widest(undefinedToNumber(booleanToInt(lhsType)), undefinedToNumber(booleanToInt(rhsType)));
++ if(widestOperandType == Type.INT) {
++ return Type.LONG;
++ } else if (widestOperandType.isNumeric()) {
++ return Type.NUMBER;
++ }
++ // We pretty much can't know what it will be statically. Must presume OBJECT conservatively, as we can end
++ // up getting either a string or an object when adding something + object, e.g.:
++ // 1 + {} == "1[object Object]", but
++ // 1 + {valueOf: function() { return 2 }} == 3. Also:
++ // 1 + {valueOf: function() { return "2" }} == "12".
++ return Type.OBJECT;
++ }
++ case SHR:
++ case ASSIGN_SHR:
+ return Type.LONG;
+ case ASSIGN_SAR:
+ case ASSIGN_SHL:
+@@ -101,20 +228,68 @@
+ return Type.INT;
+ case DIV:
+ case MOD:
++ case ASSIGN_DIV:
++ case ASSIGN_MOD: {
++ // Naively, one might think MOD has the same type as the widest of its operands, this is unfortunately not
++ // true when denominator is zero, so even type(int % int) == double.
++ return Type.NUMBER;
++ }
+ case MUL:
+ case SUB:
+- case ASSIGN_DIV:
+- case ASSIGN_MOD:
+ case ASSIGN_MUL:
+- case ASSIGN_SUB:
++ case ASSIGN_SUB: {
++ final Type lhsType = lhs.getType(localVariableTypes);
++ final Type rhsType = rhs.getType(localVariableTypes);
++ if(lhsType == Type.BOOLEAN && rhsType == Type.BOOLEAN) {
++ return Type.INT;
++ }
++ final Type widestOperandType = Type.widest(booleanToInt(lhsType), booleanToInt(rhsType));
++ if(widestOperandType == Type.INT) {
++ return Type.LONG;
++ }
+ return Type.NUMBER;
++ }
++ case VOID: {
++ return Type.UNDEFINED;
++ }
++ case ASSIGN: {
++ return rhs.getType(localVariableTypes);
++ }
++ case INSTANCEOF: {
++ return Type.BOOLEAN;
++ }
++ case COMMALEFT: {
++ return lhs.getType(localVariableTypes);
++ }
++ case COMMARIGHT: {
++ return rhs.getType(localVariableTypes);
++ }
++ case AND:
++ case OR:{
++ return Type.widestReturnType(lhs.getType(localVariableTypes), rhs.getType(localVariableTypes));
++ }
+ default:
++ if (isComparison()) {
++ return Type.BOOLEAN;
++ }
+ return Type.OBJECT;
+ }
+ }
+
++ private static boolean isString(final Type type) {
++ return type == Type.STRING || type == Type.CHARSEQUENCE;
++ }
++
++ private static Type booleanToInt(final Type type) {
++ return type == Type.BOOLEAN ? Type.INT : type;
++ }
++
++ private static Type undefinedToNumber(final Type type) {
++ return type == Type.UNDEFINED ? Type.NUMBER : type;
++ }
++
+ /**
+- * Check if this node is an assigment
++ * Check if this node is an assignment
+ *
+ * @return true if this node assigns a value
+ */
+@@ -150,7 +325,7 @@
+ }
+
+ @Override
+- public BinaryNode setAssignmentDest(Expression n) {
++ public BinaryNode setAssignmentDest(final Expression n) {
+ return setLHS(n);
+ }
+
+@@ -209,17 +384,41 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
+- final TokenType type = tokenType();
++ public boolean isAlwaysFalse() {
++ switch (tokenType()) {
++ case COMMALEFT:
++ return lhs.isAlwaysFalse();
++ case COMMARIGHT:
++ return rhs.isAlwaysFalse();
++ default:
++ return false;
++ }
++ }
+
+- final boolean lhsParen = type.needsParens(lhs().tokenType(), true);
+- final boolean rhsParen = type.needsParens(rhs().tokenType(), false);
++ @Override
++ public boolean isAlwaysTrue() {
++ switch (tokenType()) {
++ case COMMALEFT:
++ return lhs.isAlwaysTrue();
++ case COMMARIGHT:
++ return rhs.isAlwaysTrue();
++ default:
++ return false;
++ }
++ }
++
++ @Override
++ public void toString(final StringBuilder sb, final boolean printType) {
++ final TokenType tokenType = tokenType();
++
++ final boolean lhsParen = tokenType.needsParens(lhs().tokenType(), true);
++ final boolean rhsParen = tokenType.needsParens(rhs().tokenType(), false);
+
+ if (lhsParen) {
+ sb.append('(');
+ }
+
+- lhs().toString(sb);
++ lhs().toString(sb, printType);
+
+ if (lhsParen) {
+ sb.append(')');
+@@ -227,7 +426,7 @@
+
+ sb.append(' ');
+
+- switch (type) {
++ switch (tokenType) {
+ case COMMALEFT:
+ sb.append(",<");
+ break;
+@@ -239,16 +438,20 @@
+ sb.append("++");
+ break;
+ default:
+- sb.append(type.getName());
++ sb.append(tokenType.getName());
+ break;
+ }
+
++ if (isOptimistic()) {
++ sb.append(Expression.OPT_IDENTIFIER);
++ }
++
+ sb.append(' ');
+
+ if (rhsParen) {
+ sb.append('(');
+ }
+- rhs().toString(sb);
++ rhs().toString(sb, printType);
+ if (rhsParen) {
+ sb.append(')');
+ }
+@@ -279,7 +482,7 @@
+ if (this.lhs == lhs) {
+ return this;
+ }
+- return new BinaryNode(this, lhs, rhs);
++ return new BinaryNode(this, lhs, rhs, type, programPoint);
+ }
+
+ /**
+@@ -291,7 +494,104 @@
+ if (this.rhs == rhs) {
+ return this;
+ }
+- return new BinaryNode(this, lhs, rhs);
++ return new BinaryNode(this, lhs, rhs, type, programPoint);
+ }
+
++ @Override
++ public int getProgramPoint() {
++ return programPoint;
++ }
++
++ @Override
++ public boolean canBeOptimistic() {
++ return isTokenType(TokenType.ADD) || (getMostOptimisticType() != getMostPessimisticType());
++ }
++
++ @Override
++ public BinaryNode setProgramPoint(final int programPoint) {
++ if (this.programPoint == programPoint) {
++ return this;
++ }
++ return new BinaryNode(this, lhs, rhs, type, programPoint);
++ }
++
++ @Override
++ public Type getMostOptimisticType() {
++ final TokenType tokenType = tokenType();
++ if(tokenType == TokenType.ADD || tokenType == TokenType.ASSIGN_ADD) {
++ return OPTIMISTIC_UNDECIDED_TYPE;
++ } else if (CAN_OVERFLOW.contains(tokenType())) {
++ return Type.INT;
++ }
++ return getMostPessimisticType();
++ }
++
++ @Override
++ public Type getMostPessimisticType() {
++ return getWidestOperationType();
++ }
++
++ /**
++ * Returns true if the node has the optimistic type of the node is not yet decided. Optimistic ADD nodes start out
++ * as undecided until we can figure out if they're numeric or not.
++ * @return true if the node has the optimistic type of the node is not yet decided.
++ */
++ public boolean isOptimisticUndecidedType() {
++ return type == OPTIMISTIC_UNDECIDED_TYPE;
++ }
++
++ @Override
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
++ if(localVariableTypes == cachedTypeFunction) {
++ return cachedType;
++ }
++ cachedType = getTypeUncached(localVariableTypes);
++ cachedTypeFunction = localVariableTypes;
++ return cachedType;
++ }
++
++ private Type getTypeUncached(final Function<Symbol, Type> localVariableTypes) {
++ if(type == OPTIMISTIC_UNDECIDED_TYPE) {
++ return decideType(lhs.getType(localVariableTypes), rhs.getType(localVariableTypes));
++ }
++ final Type widest = getWidestOperationType(localVariableTypes);
++ if(type == null) {
++ return widest;
++ }
++ return Type.narrowest(widest, Type.widest(type, Type.widest(lhs.getType(localVariableTypes), rhs.getType(localVariableTypes))));
++ }
++
++ private static Type decideType(final Type lhsType, final Type rhsType) {
++ // Compare this to getWidestOperationType() for ADD and ASSIGN_ADD cases. There's some similar logic, but these
++ // are optimistic decisions, meaning that we don't have to treat boolean addition separately (as it'll become
++ // int addition in the general case anyway), and that we also don't conservatively widen sums of ints to
++ // longs, or sums of longs to doubles.
++ if(isString(lhsType) || isString(rhsType)) {
++ return Type.CHARSEQUENCE;
++ }
++ // NOTE: We don't have optimistic object-to-(int, long) conversions. Therefore, if any operand is an Object, we
++ // bail out of optimism here and presume a conservative Object return value, as the object's ToPrimitive() can
++ // end up returning either a number or a string, and their common supertype is Object, for better or worse.
++ final Type widest = Type.widest(undefinedToNumber(booleanToInt(lhsType)), undefinedToNumber(booleanToInt(rhsType)));
++ return widest.isObject() ? Type.OBJECT : widest;
++ }
++
++ /**
++ * If the node is a node representing an add operation and has {@link #isOptimisticUndecidedType() optimistic
++ * undecided type}, decides its type. Should be invoked after its operands types have been finalized.
++ * @return returns a new node similar to this node, but with its type set to the type decided from the type of its
++ * operands.
++ */
++ public BinaryNode decideType() {
++ assert type == OPTIMISTIC_UNDECIDED_TYPE;
++ return setType(decideType(lhs.getType(), rhs.getType()));
++ }
++
++ @Override
++ public BinaryNode setType(final Type type) {
++ if (this.type == type) {
++ return this;
++ }
++ return new BinaryNode(this, lhs, rhs, type, programPoint);
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/Block.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/Block.java Wed Feb 04 12:14:47 2015 -0800
+@@ -33,19 +33,17 @@
+ import java.util.LinkedHashMap;
+ import java.util.List;
+ import java.util.Map;
+-
+ import jdk.nashorn.internal.codegen.Label;
+-import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+
+-import static jdk.nashorn.internal.codegen.CompilerConstants.RETURN;
+-
+ /**
+ * IR representation for a list of statements.
+ */
+ @Immutable
+-public class Block extends Node implements BreakableNode, Flags<Block> {
++public class Block extends Node implements BreakableNode, Terminal, Flags<Block> {
++ private static final long serialVersionUID = 1L;
++
+ /** List of statements */
+ protected final List<Statement> statements;
+
+@@ -53,7 +51,7 @@
+ protected final Map<String, Symbol> symbols;
+
+ /** Entry label. */
+- protected final Label entryLabel;
++ private final Label entryLabel;
+
+ /** Break label. */
+ private final Label breakLabel;
+@@ -61,25 +59,27 @@
+ /** Does the block/function need a new scope? */
+ protected final int flags;
+
++ /**
++ * @see JoinPredecessor
++ */
++ private final LocalVariableConversion conversion;
++
+ /** Flag indicating that this block needs scope */
+ public static final int NEEDS_SCOPE = 1 << 0;
+
+ /**
+- * Flag indicating whether this block needs
+- * self symbol assignment at the start. This is used only for
+- * blocks that are the bodies of function nodes who refer to themselves
+- * by name. It causes codegen to insert a var [fn_name] = __callee__
+- * at the start of the body
+- */
+- public static final int NEEDS_SELF_SYMBOL = 1 << 1;
+-
+- /**
+ * Is this block tagged as terminal based on its contents
+ * (usually the last statement)
+ */
+ public static final int IS_TERMINAL = 1 << 2;
+
+ /**
++ * Is this block the eager global scope - i.e. the original program. This isn't true for the
++ * outermost level of recompiles
++ */
++ public static final int IS_GLOBAL_SCOPE = 1 << 3;
++
++ /**
+ * Constructor
+ *
+ * @param token token
+@@ -94,7 +94,8 @@
+ this.entryLabel = new Label("block_entry");
+ this.breakLabel = new Label("block_break");
+ final int len = statements.length;
+- this.flags = (len > 0 && statements[len - 1].hasTerminalFlags()) ? IS_TERMINAL : 0;
++ this.flags = len > 0 && statements[len - 1].hasTerminalFlags() ? IS_TERMINAL : 0;
++ this.conversion = null;
+ }
+
+ /**
+@@ -108,7 +109,7 @@
+ this(token, finish, statements.toArray(new Statement[statements.size()]));
+ }
+
+- private Block(final Block block, final int finish, final List<Statement> statements, final int flags, final Map<String, Symbol> symbols) {
++ private Block(final Block block, final int finish, final List<Statement> statements, final int flags, final Map<String, Symbol> symbols, final LocalVariableConversion conversion) {
+ super(block);
+ this.statements = statements;
+ this.flags = flags;
+@@ -116,11 +117,21 @@
+ this.entryLabel = new Label(block.entryLabel);
+ this.breakLabel = new Label(block.breakLabel);
+ this.finish = finish;
++ this.conversion = conversion;
+ }
+
+ /**
+- * Clear the symbols in a block
+- * TODO: make this immutable
++ * Is this block the outermost eager global scope - i.e. the primordial program?
++ * Used for global anchor point for scope depth computation for recompilation code
++ * @return true if outermost eager global scope
++ */
++ public boolean isGlobalScope() {
++ return getFlag(IS_GLOBAL_SCOPE);
++ }
++
++ /**
++ * Clear the symbols in the block.
++ * TODO: make this immutable.
+ */
+ public void clearSymbols() {
+ symbols.clear();
+@@ -128,7 +139,7 @@
+
+ @Override
+ public Node ensureUniqueLabels(final LexicalContext lc) {
+- return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, symbols));
++ return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, symbols, conversion));
+ }
+
+ /**
+@@ -140,14 +151,14 @@
+ @Override
+ public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
+ if (visitor.enterBlock(this)) {
+- return visitor.leaveBlock(setStatements(lc, Node.accept(visitor, Statement.class, statements)));
++ return visitor.leaveBlock(setStatements(lc, Node.accept(visitor, statements)));
+ }
+
+ return this;
+ }
+
+ /**
+- * Get an iterator for all the symbols defined in this block
++ * Get a copy of the list for all the symbols defined in this block
+ * @return symbol iterator
+ */
+ public List<Symbol> getSymbols() {
+@@ -175,9 +186,9 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ for (final Node statement : statements) {
+- statement.toString(sb);
++ statement.toString(sb, printType);
+ sb.append(';');
+ }
+ }
+@@ -217,19 +228,16 @@
+ return isTerminal ? setFlag(lc, IS_TERMINAL) : clearFlag(lc, IS_TERMINAL);
+ }
+
+- /**
+- * Set the type of the return symbol in this block if present.
+- * @param returnType the new type
+- * @return this block
+- */
+- public Block setReturnType(final Type returnType) {
+- final Symbol symbol = getExistingSymbol(RETURN.symbolName());
+- if (symbol != null) {
+- symbol.setTypeOverride(returnType);
+- }
+- return this;
++ @Override
++ public int getFlags() {
++ return flags;
+ }
+
++ /**
++ * Is this a terminal block, i.e. does it end control flow like ending with a throw or return?
++ *
++ * @return true if this node statement is terminal
++ */
+ @Override
+ public boolean isTerminal() {
+ return getFlag(IS_TERMINAL);
+@@ -248,6 +256,19 @@
+ return breakLabel;
+ }
+
++ @Override
++ public Block setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) {
++ if(this.conversion == conversion) {
++ return this;
++ }
++ return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, symbols, conversion));
++ }
++
++ @Override
++ public LocalVariableConversion getLocalVariableConversion() {
++ return conversion;
++ }
++
+ /**
+ * Get the list of statements in this block
+ *
+@@ -258,6 +279,25 @@
+ }
+
+ /**
++ * Returns the number of statements in the block.
++ * @return the number of statements in the block.
++ */
++ public int getStatementCount() {
++ return statements.size();
++ }
++
++ /**
++ * Returns the line number of the first statement in the block.
++ * @return the line number of the first statement in the block, or -1 if the block has no statements.
++ */
++ public int getFirstStatementLineNumber() {
++ if(statements == null || statements.isEmpty()) {
++ return -1;
++ }
++ return statements.get(0).getLineNumber();
++ }
++
++ /**
+ * Reset the statement list for this block
+ *
+ * @param lc lexical context
+@@ -272,7 +312,7 @@
+ if (!statements.isEmpty()) {
+ lastFinish = statements.get(statements.size() - 1).getFinish();
+ }
+- return Node.replaceInLexicalContext(lc, this, new Block(this, Math.max(finish, lastFinish), statements, flags, symbols));
++ return Node.replaceInLexicalContext(lc, this, new Block(this, Math.max(finish, lastFinish), statements, flags, symbols, conversion));
+ }
+
+ /**
+@@ -295,20 +335,20 @@
+ }
+
+ @Override
+- public Block setFlags(final LexicalContext lc, int flags) {
++ public Block setFlags(final LexicalContext lc, final int flags) {
+ if (this.flags == flags) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, symbols));
++ return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, symbols, conversion));
+ }
+
+ @Override
+- public Block clearFlag(final LexicalContext lc, int flag) {
++ public Block clearFlag(final LexicalContext lc, final int flag) {
+ return setFlags(lc, flags & ~flag);
+ }
+
+ @Override
+- public Block setFlag(final LexicalContext lc, int flag) {
++ public Block setFlag(final LexicalContext lc, final int flag) {
+ return setFlags(lc, flags | flag);
+ }
+
+@@ -327,7 +367,7 @@
+ return this;
+ }
+
+- return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags | NEEDS_SCOPE, symbols));
++ return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags | NEEDS_SCOPE, symbols, conversion));
+ }
+
+ /**
+@@ -353,11 +393,11 @@
+
+ @Override
+ public List<Label> getLabels() {
+- return Collections.singletonList(breakLabel);
++ return Collections.unmodifiableList(Arrays.asList(entryLabel, breakLabel));
+ }
+
+ @Override
+- public Node accept(NodeVisitor<? extends LexicalContext> visitor) {
++ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
+ return Acceptor.accept(this, visitor);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java Wed Feb 04 12:14:47 2015 -0800
+@@ -40,14 +40,14 @@
+ public class BlockLexicalContext extends LexicalContext {
+ /** statement stack, each block on the lexical context maintains one of these, which is
+ * committed to the block on pop */
+- private Deque<List<Statement>> sstack = new ArrayDeque<>();
++ private final Deque<List<Statement>> sstack = new ArrayDeque<>();
+
+ /** Last non debug statement emitted in this context */
+ protected Statement lastStatement;
+
+ @Override
+ public <T extends LexicalContextNode> T push(final T node) {
+- T pushed = super.push(node);
++ final T pushed = super.push(node);
+ if (node instanceof Block) {
+ sstack.push(new ArrayList<Statement>());
+ }
+@@ -68,7 +68,7 @@
+ * @param block the block to operate on
+ * @return a modified block.
+ */
+- protected Block afterSetStatements(Block block) {
++ protected Block afterSetStatements(final Block block) {
+ return block;
+ }
+
+@@ -109,6 +109,16 @@
+ }
+
+ /**
++ * Prepend a list of statement to the block being generated
++ * @param statements a list of statements to prepend
++ */
++ public void prependStatements(final List<Statement> statements) {
++ assert statements != null;
++ sstack.peek().addAll(0, statements);
++ }
++
++
++ /**
+ * Get the last statement that was emitted into a block
+ * @return the last statement emitted
+ */
+--- ./nashorn/src/jdk/nashorn/internal/ir/BlockStatement.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/BlockStatement.java Wed Feb 04 12:14:47 2015 -0800
+@@ -32,6 +32,8 @@
+ * Represents a block used as a statement.
+ */
+ public class BlockStatement extends Statement {
++ private static final long serialVersionUID = 1L;
++
+ /** Block to execute. */
+ private final Block block;
+
+@@ -58,7 +60,7 @@
+ * @return a block statement with the new statements. It will have the line number, token, and finish of the
+ * original statement.
+ */
+- public static Statement createReplacement(final Statement stmt, final List<Statement> newStmts) {
++ public static BlockStatement createReplacement(final Statement stmt, final List<Statement> newStmts) {
+ return createReplacement(stmt, stmt.getFinish(), newStmts);
+ }
+
+@@ -70,7 +72,7 @@
+ * @return a block statement with the new statements. It will have the line number, and token of the
+ * original statement.
+ */
+- public static Statement createReplacement(final Statement stmt, int finish, final List<Statement> newStmts) {
++ public static BlockStatement createReplacement(final Statement stmt, final int finish, final List<Statement> newStmts) {
+ return new BlockStatement(stmt.getLineNumber(), new Block(stmt.getToken(), finish, newStmts));
+ }
+
+@@ -89,8 +91,8 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
+- block.toString(sb);
++ public void toString(final StringBuilder sb, final boolean printType) {
++ block.toString(sb, printType);
+ }
+
+ /**
+--- ./nashorn/src/jdk/nashorn/internal/ir/BreakNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/BreakNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package jdk.nashorn.internal.ir;
+
++import jdk.nashorn.internal.codegen.Label;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+
+@@ -32,9 +33,8 @@
+ * IR representation for {@code break} statements.
+ */
+ @Immutable
+-public final class BreakNode extends Statement {
+-
+- private final IdentNode label;
++public final class BreakNode extends JumpStatement {
++ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor
+@@ -42,22 +42,16 @@
+ * @param lineNumber line number
+ * @param token token
+ * @param finish finish
+- * @param label label for break or null if none
++ * @param labelName label name for break or null if none
+ */
+- public BreakNode(final int lineNumber, final long token, final int finish, final IdentNode label) {
+- super(lineNumber, token, finish);
+- this.label = label;
++ public BreakNode(final int lineNumber, final long token, final int finish, final String labelName) {
++ super(lineNumber, token, finish, labelName);
+ }
+
+- @Override
+- public boolean hasGoto() {
+- return true;
++ private BreakNode(final BreakNode breakNode, final LocalVariableConversion conversion) {
++ super(breakNode, conversion);
+ }
+
+- /**
+- * Assist in IR navigation.
+- * @param visitor IR navigating visitor.
+- */
+ @Override
+ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
+ if (visitor.enterBreakNode(this)) {
+@@ -67,21 +61,23 @@
+ return this;
+ }
+
+- /**
+- * Get the label for this break node
+- * @return label, or null if none
+- */
+- public IdentNode getLabel() {
+- return label;
++ @Override
++ JumpStatement createNewJumpStatement(final LocalVariableConversion conversion) {
++ return new BreakNode(this, conversion);
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
+- sb.append("break");
++ String getStatementName() {
++ return "break";
++ }
+
+- if (label != null) {
+- sb.append(' ');
+- label.toString(sb);
+- }
++ @Override
++ public BreakableNode getTarget(final LexicalContext lc) {
++ return lc.getBreakable(getLabelName());
++ }
++
++ @Override
++ public Label getTargetLabel(final BreakableNode target) {
++ return target.getBreakLabel();
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/BreakableNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/BreakableNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,14 +25,13 @@
+
+ package jdk.nashorn.internal.ir;
+
+-import java.util.List;
+ import jdk.nashorn.internal.codegen.Label;
+
+ /**
+ * This class represents a node from which control flow can execute
+ * a {@code break} statement
+ */
+-public interface BreakableNode extends LexicalContextNode {
++public interface BreakableNode extends LexicalContextNode, JoinPredecessor, Labels {
+ /**
+ * Ensure that any labels in this breakable node are unique so
+ * that new jumps won't go to old parts of the tree. Used for
+@@ -56,11 +55,4 @@
+ */
+ public Label getBreakLabel();
+
+- /**
+- * Return the labels associated with this node. Breakable nodes that
+- * aren't LoopNodes only have a break label - the location immediately
+- * afterwards the node in code
+- * @return list of labels representing locations around this node
+- */
+- public List<Label> getLabels();
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/BreakableStatement.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/BreakableStatement.java Wed Feb 04 12:14:47 2015 -0800
+@@ -32,10 +32,13 @@
+
+ @Immutable
+ abstract class BreakableStatement extends LexicalContextStatement implements BreakableNode {
++ private static final long serialVersionUID = 1L;
+
+ /** break label. */
+ protected final Label breakLabel;
+
++ final LocalVariableConversion conversion;
++
+ /**
+ * Constructor
+ *
+@@ -47,16 +50,19 @@
+ protected BreakableStatement(final int lineNumber, final long token, final int finish, final Label breakLabel) {
+ super(lineNumber, token, finish);
+ this.breakLabel = breakLabel;
++ this.conversion = null;
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param breakableNode source node
++ * @param conversion the potentially new local variable conversion
+ */
+- protected BreakableStatement(final BreakableStatement breakableNode) {
++ protected BreakableStatement(final BreakableStatement breakableNode, final LocalVariableConversion conversion) {
+ super(breakableNode);
+ this.breakLabel = new Label(breakableNode.getBreakLabel());
++ this.conversion = conversion;
+ }
+
+ /**
+@@ -86,6 +92,21 @@
+ */
+ @Override
+ public List<Label> getLabels() {
+- return Collections.singletonList(breakLabel);
++ return Collections.unmodifiableList(Collections.singletonList(breakLabel));
+ }
++
++ @Override
++ public JoinPredecessor setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) {
++ if(this.conversion == conversion) {
++ return this;
++ }
++ return setLocalVariableConversionChanged(lc, conversion);
++ }
++
++ @Override
++ public LocalVariableConversion getLocalVariableConversion() {
++ return conversion;
++ }
++
++ abstract JoinPredecessor setLocalVariableConversionChanged(LexicalContext lc, LocalVariableConversion conversion);
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/CallNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/CallNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,8 +25,12 @@
+
+ package jdk.nashorn.internal.ir;
+
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
++
++import java.io.Serializable;
+ import java.util.Collections;
+ import java.util.List;
++import java.util.function.Function;
+ import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.annotations.Ignore;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+@@ -36,7 +40,8 @@
+ * IR representation for a function call.
+ */
+ @Immutable
+-public final class CallNode extends LexicalContextExpression {
++public final class CallNode extends LexicalContextExpression implements Optimistic {
++ private static final long serialVersionUID = 1L;
+
+ /** Function identifier or function body. */
+ private final Expression function;
+@@ -45,71 +50,53 @@
+ private final List<Expression> args;
+
+ /** Is this a "new" operation */
+- public static final int IS_NEW = 0x1;
++ private static final int IS_NEW = 1 << 0;
++
++ /** Can this be a Function.call? */
++ private static final int IS_APPLY_TO_CALL = 1 << 1;
+
+ private final int flags;
+
+ private final int lineNumber;
+
++ private final int programPoint;
++
++ private final Type optimisticType;
++
+ /**
+ * Arguments to be passed to builtin {@code eval} function
+ */
+- public static class EvalArgs {
+- /** evaluated code */
+- private final Expression code;
+-
+- /** 'this' passed to evaluated code */
+- private final IdentNode evalThis;
++ public static class EvalArgs implements Serializable {
++ private static final long serialVersionUID = 1L;
++ private final List<Expression> args;
+
+ /** location string for the eval call */
+ private final String location;
+
+- /** is this call from a strict context? */
+- private final boolean strictMode;
+-
+ /**
+ * Constructor
+ *
+- * @param code code to evaluate
+- * @param evalThis this node
+- * @param location location for the eval call
+- * @param strictMode is this a call from a strict context?
++ * @param args arguments to eval
++ * @param location location for the eval call
+ */
+- public EvalArgs(final Expression code, final IdentNode evalThis, final String location, final boolean strictMode) {
+- this.code = code;
+- this.evalThis = evalThis;
++ public EvalArgs(final List<Expression> args, final String location) {
++ this.args = args;
+ this.location = location;
+- this.strictMode = strictMode;
+ }
+
+ /**
+ * Return the code that is to be eval:ed by this eval function
+ * @return code as an AST node
+ */
+- public Expression getCode() {
+- return code;
++ public List<Expression> getArgs() {
++ return Collections.unmodifiableList(args);
+ }
+
+- private EvalArgs setCode(final Expression code) {
+- if (this.code == code) {
++ private EvalArgs setArgs(final List<Expression> args) {
++ if (this.args == args) {
+ return this;
+ }
+- return new EvalArgs(code, evalThis, location, strictMode);
+- }
+-
+- /**
+- * Get the {@code this} symbol used to invoke this eval call
+- * @return the {@code this} symbol
+- */
+- public IdentNode getThis() {
+- return this.evalThis;
+- }
+-
+- private EvalArgs setThis(final IdentNode evalThis) {
+- if (this.evalThis == evalThis) {
+- return this;
+- }
+- return new EvalArgs(code, evalThis, location, strictMode);
++ return new EvalArgs(args, location);
+ }
+
+ /**
+@@ -119,14 +106,6 @@
+ public String getLocation() {
+ return this.location;
+ }
+-
+- /**
+- * Check whether this eval call is executed in strict mode
+- * @return true if executed in strict mode, false otherwise
+- */
+- public boolean getStrictMode() {
+- return this.strictMode;
+- }
+ }
+
+ /** arguments for 'eval' call. Non-null only if this call node is 'eval' */
+@@ -141,24 +120,29 @@
+ * @param finish finish
+ * @param function the function to call
+ * @param args args to the call
++ * @param isNew true if this is a constructor call with the "new" keyword
+ */
+- public CallNode(final int lineNumber, final long token, final int finish, final Expression function, final List<Expression> args) {
++ public CallNode(final int lineNumber, final long token, final int finish, final Expression function, final List<Expression> args, final boolean isNew) {
+ super(token, finish);
+
+- this.function = function;
+- this.args = args;
+- this.flags = 0;
+- this.evalArgs = null;
+- this.lineNumber = lineNumber;
++ this.function = function;
++ this.args = args;
++ this.flags = isNew ? IS_NEW : 0;
++ this.evalArgs = null;
++ this.lineNumber = lineNumber;
++ this.programPoint = INVALID_PROGRAM_POINT;
++ this.optimisticType = null;
+ }
+
+- private CallNode(final CallNode callNode, final Expression function, final List<Expression> args, final int flags, final EvalArgs evalArgs) {
++ private CallNode(final CallNode callNode, final Expression function, final List<Expression> args, final int flags, final Type optimisticType, final EvalArgs evalArgs, final int programPoint) {
+ super(callNode);
+ this.lineNumber = callNode.lineNumber;
+ this.function = function;
+ this.args = args;
+ this.flags = flags;
+ this.evalArgs = evalArgs;
++ this.programPoint = programPoint;
++ this.optimisticType = optimisticType;
+ }
+
+ /**
+@@ -170,8 +154,16 @@
+ }
+
+ @Override
+- public Type getType() {
+- return function instanceof FunctionNode ? ((FunctionNode)function).getReturnType() : Type.OBJECT;
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
++ return optimisticType == null ? Type.OBJECT : optimisticType;
++ }
++
++ @Override
++ public Optimistic setType(final Type optimisticType) {
++ if (this.optimisticType == optimisticType) {
++ return this;
++ }
++ return new CallNode(this, function, args, flags, optimisticType, evalArgs, programPoint);
+ }
+
+ /**
+@@ -186,15 +178,13 @@
+ if (visitor.enterCallNode(this)) {
+ final CallNode newCallNode = (CallNode)visitor.leaveCallNode(
+ setFunction((Expression)function.accept(visitor)).
+- setArgs(Node.accept(visitor, Expression.class, args)).
+- setFlags(flags).
++ setArgs(Node.accept(visitor, args)).
+ setEvalArgs(evalArgs == null ?
+ null :
+- evalArgs.setCode((Expression)evalArgs.getCode().accept(visitor)).
+- setThis((IdentNode)evalArgs.getThis().accept(visitor))));
++ evalArgs.setArgs(Node.accept(visitor, evalArgs.getArgs()))));
+ // Theoretically, we'd need to instead pass lc to every setter and do a replacement on each. In practice,
+ // setType from TypeOverride can't accept a lc, and we don't necessarily want to go there now.
+- if(this != newCallNode) {
++ if (this != newCallNode) {
+ return Node.replaceInLexicalContext(lc, this, newCallNode);
+ }
+ }
+@@ -203,8 +193,19 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
+- function.toString(sb);
++ public void toString(final StringBuilder sb, final boolean printType) {
++ if (printType) {
++ optimisticTypeToString(sb);
++ }
++
++ final StringBuilder fsb = new StringBuilder();
++ function.toString(fsb, printType);
++
++ if (isApplyToCall()) {
++ sb.append(fsb.toString().replace("apply", "[apply => call]"));
++ } else {
++ sb.append(fsb);
++ }
+
+ sb.append('(');
+
+@@ -217,7 +218,7 @@
+ first = false;
+ }
+
+- arg.toString(sb);
++ arg.toString(sb, printType);
+ }
+
+ sb.append(')');
+@@ -234,12 +235,13 @@
+ /**
+ * Reset the arguments for the call
+ * @param args new arguments list
++ * @return new callnode, or same if unchanged
+ */
+- private CallNode setArgs(final List<Expression> args) {
++ public CallNode setArgs(final List<Expression> args) {
+ if (this.args == args) {
+ return this;
+ }
+- return new CallNode(this, function, args, flags, evalArgs);
++ return new CallNode(this, function, args, flags, optimisticType, evalArgs, programPoint);
+ }
+
+ /**
+@@ -261,7 +263,7 @@
+ if (this.evalArgs == evalArgs) {
+ return this;
+ }
+- return new CallNode(this, function, args, flags, evalArgs);
++ return new CallNode(this, function, args, flags, optimisticType, evalArgs, programPoint);
+ }
+
+ /**
+@@ -273,6 +275,23 @@
+ }
+
+ /**
++ * Is this an apply call that we optimistically should try to turn into
++ * a call instead
++ * @return true if apply to call
++ */
++ public boolean isApplyToCall() {
++ return (flags & IS_APPLY_TO_CALL) != 0;
++ }
++
++ /**
++ * Flag this call node as one that tries to call call instead of apply
++ * @return new call node with changed flags, if not already flagged as apply to call, then the same node
++ */
++ public CallNode setIsApplyToCall() {
++ return setFlags(flags | IS_APPLY_TO_CALL);
++ }
++
++ /**
+ * Return the function expression that this call invokes
+ * @return the function
+ */
+@@ -289,7 +308,7 @@
+ if (this.function == function) {
+ return this;
+ }
+- return new CallNode(this, function, args, flags, evalArgs);
++ return new CallNode(this, function, args, flags, optimisticType, evalArgs, programPoint);
+ }
+
+ /**
+@@ -297,21 +316,41 @@
+ * @return true if this a new operation
+ */
+ public boolean isNew() {
+- return (flags & IS_NEW) == IS_NEW;
+- }
+-
+- /**
+- * Flag this call as a new operation
+- * @return same node or new one on state change
+- */
+- public CallNode setIsNew() {
+- return setFlags(IS_NEW);
++ return (flags & IS_NEW) != 0;
+ }
+
+ private CallNode setFlags(final int flags) {
+ if (this.flags == flags) {
+ return this;
+ }
+- return new CallNode(this, function, args, flags, evalArgs);
++ return new CallNode(this, function, args, flags, optimisticType, evalArgs, programPoint);
++ }
++
++ @Override
++ public int getProgramPoint() {
++ return programPoint;
++ }
++
++ @Override
++ public CallNode setProgramPoint(final int programPoint) {
++ if (this.programPoint == programPoint) {
++ return this;
++ }
++ return new CallNode(this, function, args, flags, optimisticType, evalArgs, programPoint);
++ }
++
++ @Override
++ public Type getMostOptimisticType() {
++ return Type.INT;
++ }
++
++ @Override
++ public Type getMostPessimisticType() {
++ return Type.OBJECT;
++ }
++
++ @Override
++ public boolean canBeOptimistic() {
++ return true;
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/CaseNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/CaseNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,8 @@
+
+ package jdk.nashorn.internal.ir;
+
++import java.util.Collections;
++import java.util.List;
+ import jdk.nashorn.internal.codegen.Label;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+@@ -34,7 +36,9 @@
+ * Case nodes are not BreakableNodes, but the SwitchNode is
+ */
+ @Immutable
+-public final class CaseNode extends Node {
++public final class CaseNode extends Node implements JoinPredecessor, Labels, Terminal {
++ private static final long serialVersionUID = 1L;
++
+ /** Test expression. */
+ private final Expression test;
+
+@@ -45,6 +49,11 @@
+ private final Label entry;
+
+ /**
++ * @see JoinPredecessor
++ */
++ private final LocalVariableConversion conversion;
++
++ /**
+ * Constructors
+ *
+ * @param token token
+@@ -58,16 +67,23 @@
+ this.test = test;
+ this.body = body;
+ this.entry = new Label("entry");
++ this.conversion = null;
+ }
+
+- CaseNode(final CaseNode caseNode, final Expression test, final Block body) {
++ CaseNode(final CaseNode caseNode, final Expression test, final Block body, final LocalVariableConversion conversion) {
+ super(caseNode);
+
+ this.test = test;
+ this.body = body;
+ this.entry = new Label(caseNode.entry);
++ this.conversion = conversion;
+ }
+
++ /**
++ * Is this a terminal case node, i.e. does it end control flow like having a throw or return?
++ *
++ * @return true if this node statement is terminal
++ */
+ @Override
+ public boolean isTerminal() {
+ return body.isTerminal();
+@@ -90,10 +106,10 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printTypes) {
+ if (test != null) {
+ sb.append("case ");
+- test.toString(sb);
++ test.toString(sb, printTypes);
+ sb.append(':');
+ } else {
+ sb.append("default:");
+@@ -133,13 +149,31 @@
+ if (this.test == test) {
+ return this;
+ }
+- return new CaseNode(this, test, body);
++ return new CaseNode(this, test, body, conversion);
++ }
++
++ @Override
++ public JoinPredecessor setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) {
++ if(this.conversion == conversion) {
++ return this;
++ }
++ return new CaseNode(this, test, body, conversion);
++ }
++
++ @Override
++ public LocalVariableConversion getLocalVariableConversion() {
++ return conversion;
+ }
+
+ private CaseNode setBody(final Block body) {
+ if (this.body == body) {
+ return this;
+ }
+- return new CaseNode(this, test, body);
++ return new CaseNode(this, test, body, conversion);
++ }
++
++ @Override
++ public List<Label> getLabels() {
++ return Collections.unmodifiableList(Collections.singletonList(entry));
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/CatchNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/CatchNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -33,6 +33,8 @@
+ */
+ @Immutable
+ public final class CatchNode extends Statement {
++ private static final long serialVersionUID = 1L;
++
+ /** Exception identifier. */
+ private final IdentNode exception;
+
+@@ -42,10 +44,7 @@
+ /** Catch body. */
+ private final Block body;
+
+- private final int flags;
+-
+- /** Is this block a synthethic rethrow created by finally inlining? */
+- public static final int IS_SYNTHETIC_RETHROW = 1;
++ private final boolean isSyntheticRethrow;
+
+ /**
+ * Constructors
+@@ -56,22 +55,24 @@
+ * @param exception variable name of exception
+ * @param exceptionCondition exception condition
+ * @param body catch body
+- * @param flags flags
++ * @param isSyntheticRethrow true if this node is a synthetically generated rethrow node.
+ */
+- public CatchNode(final int lineNumber, final long token, final int finish, final IdentNode exception, final Expression exceptionCondition, final Block body, final int flags) {
++ public CatchNode(final int lineNumber, final long token, final int finish, final IdentNode exception,
++ final Expression exceptionCondition, final Block body, final boolean isSyntheticRethrow) {
+ super(lineNumber, token, finish);
+- this.exception = exception;
++ this.exception = exception == null ? null : exception.setIsInitializedHere();
+ this.exceptionCondition = exceptionCondition;
+ this.body = body;
+- this.flags = flags;
++ this.isSyntheticRethrow = isSyntheticRethrow;
+ }
+
+- private CatchNode(final CatchNode catchNode, final IdentNode exception, final Expression exceptionCondition, final Block body, final int flags) {
++ private CatchNode(final CatchNode catchNode, final IdentNode exception, final Expression exceptionCondition,
++ final Block body, final boolean isSyntheticRethrow) {
+ super(catchNode);
+ this.exception = exception;
+ this.exceptionCondition = exceptionCondition;
+ this.body = body;
+- this.flags = flags;
++ this.isSyntheticRethrow = isSyntheticRethrow;
+ }
+
+ /**
+@@ -96,13 +97,13 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printTypes) {
+ sb.append(" catch (");
+- exception.toString(sb);
++ exception.toString(sb, printTypes);
+
+ if (exceptionCondition != null) {
+ sb.append(" if ");
+- exceptionCondition.toString(sb);
++ exceptionCondition.toString(sb, printTypes);
+ }
+ sb.append(')');
+ }
+@@ -132,7 +133,7 @@
+ if (this.exceptionCondition == exceptionCondition) {
+ return this;
+ }
+- return new CatchNode(this, exception, exceptionCondition, body, flags);
++ return new CatchNode(this, exception, exceptionCondition, body, isSyntheticRethrow);
+ }
+
+ /**
+@@ -152,14 +153,14 @@
+ if (this.exception == exception) {
+ return this;
+ }
+- return new CatchNode(this, exception, exceptionCondition, body, flags);
++ return new CatchNode(this, exception, exceptionCondition, body, isSyntheticRethrow);
+ }
+
+ private CatchNode setBody(final Block body) {
+ if (this.body == body) {
+ return this;
+ }
+- return new CatchNode(this, exception, exceptionCondition, body, flags);
++ return new CatchNode(this, exception, exceptionCondition, body, isSyntheticRethrow);
+ }
+
+ /**
+@@ -170,7 +171,6 @@
+ * @return true if a finally synthetic rethrow
+ */
+ public boolean isSyntheticRethrow() {
+- return (flags & IS_SYNTHETIC_RETHROW) == IS_SYNTHETIC_RETHROW;
++ return isSyntheticRethrow;
+ }
+-
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/ir/CompileUnitHolder.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,40 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.ir;
++
++import jdk.nashorn.internal.codegen.CompileUnit;
++
++/**
++ * Marker interface for things in the IR that can hold compile units.
++ * {@link CompileUnit}
++ */
++public interface CompileUnitHolder {
++ /**
++ * Return the compile unit held by this instance
++ * @return compile unit
++ */
++ public CompileUnit getCompileUnit();
++}
+--- ./nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package jdk.nashorn.internal.ir;
+
++import jdk.nashorn.internal.codegen.Label;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+
+@@ -32,9 +33,8 @@
+ * IR representation for CONTINUE statements.
+ */
+ @Immutable
+-public class ContinueNode extends Statement {
+-
+- private IdentNode label;
++public class ContinueNode extends JumpStatement {
++ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor
+@@ -42,16 +42,14 @@
+ * @param lineNumber line number
+ * @param token token
+ * @param finish finish
+- * @param label label for break or null if none
++ * @param labelName label name for continue or null if none
+ */
+- public ContinueNode(final int lineNumber, final long token, final int finish, final IdentNode label) {
+- super(lineNumber, token, finish);
+- this.label = label;
++ public ContinueNode(final int lineNumber, final long token, final int finish, final String labelName) {
++ super(lineNumber, token, finish, labelName);
+ }
+
+- @Override
+- public boolean hasGoto() {
+- return true;
++ private ContinueNode(final ContinueNode continueNode, final LocalVariableConversion conversion) {
++ super(continueNode, conversion);
+ }
+
+ @Override
+@@ -63,22 +61,24 @@
+ return this;
+ }
+
+- /**
+- * Get the label for this break node
+- * @return label, or null if none
+- */
+- public IdentNode getLabel() {
+- return label;
++ @Override
++ JumpStatement createNewJumpStatement(final LocalVariableConversion conversion) {
++ return new ContinueNode(this, conversion);
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
+- sb.append("continue");
++ String getStatementName() {
++ return "continue";
++ }
+
+- if (label != null) {
+- sb.append(' ');
+- label.toString(sb);
+- }
++
++ @Override
++ public BreakableNode getTarget(final LexicalContext lc) {
++ return lc.getContinueTo(getLabelName());
++ }
++
++ @Override
++ public Label getTargetLabel(final BreakableNode target) {
++ return ((LoopNode)target).getContinueLabel();
+ }
+ }
+-
+--- ./nashorn/src/jdk/nashorn/internal/ir/EmptyNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/EmptyNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -33,6 +33,7 @@
+ */
+ @Immutable
+ public final class EmptyNode extends Statement {
++ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor
+@@ -64,7 +65,7 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printTypes) {
+ sb.append(';');
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/ir/Expression.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/Expression.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,7 +25,9 @@
+
+ package jdk.nashorn.internal.ir;
+
++import java.util.function.Function;
+ import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
+
+ /**
+ * Common superclass for all expression nodes. Expression nodes can have
+@@ -33,69 +35,46 @@
+ *
+ */
+ public abstract class Expression extends Node {
+- private Symbol symbol;
++ private static final long serialVersionUID = 1L;
+
+- Expression(long token, int start, int finish) {
++ static final String OPT_IDENTIFIER = "%";
++
++ private static final Function<Symbol, Type> UNKNOWN_LOCALS = new Function<Symbol, Type>() {
++ @Override
++ public Type apply(final Symbol t) {
++ return null;
++ }
++ };
++
++ Expression(final long token, final int start, final int finish) {
+ super(token, start, finish);
+ }
+
+- Expression(long token, int finish) {
++ Expression(final long token, final int finish) {
+ super(token, finish);
+ }
+
+- Expression(Expression expr) {
++ Expression(final Expression expr) {
+ super(expr);
+- this.symbol = expr.symbol;
+ }
+
+ /**
+- * Return the Symbol the compiler has assigned to this Node. The symbol
+- * is the place where it's expression value is stored after evaluation
++ * Returns the type of the expression.
+ *
+- * @return the symbol
++ * @return the type of the expression.
+ */
+- public Symbol getSymbol() {
+- return symbol;
++ public final Type getType() {
++ return getType(UNKNOWN_LOCALS);
+ }
+
+ /**
+- * Assign a symbol to this node. See {@link Expression#getSymbol()} for explanation
+- * of what a symbol is
+- *
+- * @param lc lexical context
+- * @param symbol the symbol
+- * @return new node
++ * Returns the type of the expression under the specified symbol-to-type mapping. By default delegates to
++ * {@link #getType()} but expressions whose type depends on their subexpressions' types and expressions whose type
++ * depends on symbol type ({@link IdentNode}) will have a special implementation.
++ * @param localVariableTypes a mapping from symbols to their types, used for type calculation.
++ * @return the type of the expression under the specified symbol-to-type mapping.
+ */
+- public Expression setSymbol(final LexicalContext lc, final Symbol symbol) {
+- if (this.symbol == symbol) {
+- return this;
+- }
+- final Expression newExpr = (Expression)clone();
+- newExpr.symbol = symbol;
+- return newExpr;
+- }
+-
+- /**
+- * Check if the expression has a type. The default behavior is to go into the symbol
+- * and check the symbol type, but there may be overrides, for example in
+- * getters that require a different type than the internal representation
+- *
+- * @return true if a type exists
+- */
+- public boolean hasType() {
+- return getSymbol() != null;
+- }
+-
+- /**
+- * Returns the type of the expression. Typically this is the symbol type. No types
+- * are stored in the expression itself, unless it implements TypeOverride.
+- *
+- * @return the type of the node.
+- */
+- public Type getType() {
+- assert hasType() : this + " has no type";
+- return symbol.getSymbolType();
+- }
++ public abstract Type getType(final Function<Symbol, Type> localVariableTypes);
+
+ /**
+ * Returns {@code true} if this expression depends exclusively on state that is constant
+@@ -108,4 +87,88 @@
+ public boolean isLocal() {
+ return false;
+ }
++
++ /**
++ * Is this a self modifying assignment?
++ * @return true if self modifying, e.g. a++, or a*= 17
++ */
++ public boolean isSelfModifying() {
++ return false;
++ }
++
++ /**
++ * Returns widest operation type of this operation.
++ *
++ * @return the widest type for this operation
++ */
++ public Type getWidestOperationType() {
++ return Type.OBJECT;
++ }
++
++ /**
++ * Returns true if the type of this expression is narrower than its widest operation type (thus, it is
++ * optimistically typed).
++ * @return true if this expression is optimistically typed.
++ */
++ public final boolean isOptimistic() {
++ return getType().narrowerThan(getWidestOperationType());
++ }
++
++ void optimisticTypeToString(final StringBuilder sb) {
++ optimisticTypeToString(sb, isOptimistic());
++ }
++
++ void optimisticTypeToString(final StringBuilder sb, final boolean optimistic) {
++ sb.append('{');
++ final Type type = getType();
++ final String desc = type == Type.UNDEFINED ? "U" : type.getDescriptor();
++
++ sb.append(desc.charAt(desc.length() - 1) == ';' ? "O" : desc);
++ if (isOptimistic() && optimistic) {
++ sb.append(OPT_IDENTIFIER);
++ final int pp = ((Optimistic)this).getProgramPoint();
++ if (UnwarrantedOptimismException.isValid(pp)) {
++ sb.append('_').append(pp);
++ }
++ }
++ sb.append('}');
++ }
++
++ /**
++ * Returns true if the runtime value of this expression is always false when converted to boolean as per ECMAScript
++ * ToBoolean conversion. Used in control flow calculations.
++ * @return true if this expression's runtime value converted to boolean is always false.
++ */
++ public boolean isAlwaysFalse() {
++ return false;
++ }
++
++ /**
++ * Returns true if the runtime value of this expression is always true when converted to boolean as per ECMAScript
++ * ToBoolean conversion. Used in control flow calculations.
++ * @return true if this expression's runtime value converted to boolean is always true.
++ */
++ public boolean isAlwaysTrue() {
++ return false;
++ }
++
++ /**
++ * Returns true if the expression is not null and {@link #isAlwaysFalse()}.
++ * @param test a test expression used as a predicate of a branch or a loop.
++ * @return true if the expression is not null and {@link #isAlwaysFalse()}.
++ */
++ public static boolean isAlwaysFalse(final Expression test) {
++ return test != null && test.isAlwaysFalse();
++ }
++
++
++ /**
++ * Returns true if the expression is null or {@link #isAlwaysTrue()}. Null is considered to be always true as a
++ * for loop with no test is equivalent to a for loop with always-true test.
++ * @param test a test expression used as a predicate of a branch or a loop.
++ * @return true if the expression is null or {@link #isAlwaysFalse()}.
++ */
++ public static boolean isAlwaysTrue(final Expression test) {
++ return test == null || test.isAlwaysTrue();
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/ExpressionStatement.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/ExpressionStatement.java Wed Feb 04 12:14:47 2015 -0800
+@@ -35,6 +35,8 @@
+ */
+ @Immutable
+ public final class ExpressionStatement extends Statement {
++ private static final long serialVersionUID = 1L;
++
+ /** Expression to execute. */
+ private final Expression expression;
+
+@@ -57,11 +59,6 @@
+ }
+
+ @Override
+- public boolean isTerminal() {
+- return expression.isTerminal();
+- }
+-
+- @Override
+ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
+ if (visitor.enterExpressionStatement(this)) {
+ return visitor.leaveExpressionStatement(setExpression((Expression)expression.accept(visitor)));
+@@ -71,8 +68,8 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
+- expression.toString(sb);
++ public void toString(final StringBuilder sb, final boolean printTypes) {
++ expression.toString(sb, printTypes);
+ }
+
+ /**
+--- ./nashorn/src/jdk/nashorn/internal/ir/Flags.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/Flags.java Wed Feb 04 12:14:47 2015 -0800
+@@ -37,6 +37,12 @@
+ public interface Flags<T extends LexicalContextNode> {
+
+ /**
++ * Get all flags of a LexicalContextNode
++ * @return flags
++ */
++ public int getFlags();
++
++ /**
+ * Check if a flag is set in a lexical context node
+ * @param flag flag to check
+ * @return flags
+--- ./nashorn/src/jdk/nashorn/internal/ir/ForNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/ForNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -33,23 +33,26 @@
+ */
+ @Immutable
+ public final class ForNode extends LoopNode {
+- /** Initialize expression. */
++ private static final long serialVersionUID = 1L;
++
++ /** Initialize expression for an ordinary for statement, or the LHS expression receiving iterated-over values in a
++ * for-in statement. */
+ private final Expression init;
+
+- /** Test expression. */
+- private final Expression modify;
++ /** Modify expression for an ordinary statement, or the source of the iterator in the for-in statement. */
++ private final JoinPredecessorExpression modify;
+
+ /** Iterator symbol. */
+ private Symbol iterator;
+
+- /** Is this a normal for loop? */
+- public static final int IS_FOR = 1 << 0;
+-
+ /** Is this a normal for in loop? */
+- public static final int IS_FOR_IN = 1 << 1;
++ public static final int IS_FOR_IN = 1 << 0;
+
+ /** Is this a normal for each in loop? */
+- public static final int IS_FOR_EACH = 1 << 2;
++ public static final int IS_FOR_EACH = 1 << 1;
++
++ /** Does this loop need a per-iteration scope because its init contain a LET declaration? */
++ public static final int PER_ITERATION_SCOPE = 1 << 2;
+
+ private final int flags;
+
+@@ -59,30 +62,30 @@
+ * @param lineNumber line number
+ * @param token token
+ * @param finish finish
+- * @param init initialization expression
+- * @param test test
+ * @param body body
+- * @param modify modify
+ * @param flags flags
+ */
+- public ForNode(final int lineNumber, final long token, final int finish, final Expression init, final Expression test, final Block body, final Expression modify, final int flags) {
+- super(lineNumber, token, finish, test, body, false);
++ public ForNode(final int lineNumber, final long token, final int finish, final Block body, final int flags) {
++ super(lineNumber, token, finish, body, false);
++ this.flags = flags;
++ this.init = null;
++ this.modify = null;
++ }
++
++ private ForNode(final ForNode forNode, final Expression init, final JoinPredecessorExpression test,
++ final Block body, final JoinPredecessorExpression modify, final int flags, final boolean controlFlowEscapes, final LocalVariableConversion conversion) {
++ super(forNode, test, body, controlFlowEscapes, conversion);
+ this.init = init;
+ this.modify = modify;
+ this.flags = flags;
+- }
+-
+- private ForNode(final ForNode forNode, final Expression init, final Expression test, final Block body, final Expression modify, final int flags, final boolean controlFlowEscapes) {
+- super(forNode, test, body, controlFlowEscapes);
+- this.init = init;
+- this.modify = modify;
+- this.flags = flags;
+- this.iterator = forNode.iterator; //TODO is this acceptable? symbols are never cloned, just copied as references
++ // Even if the for node gets cloned in try/finally, the symbol can be shared as only one branch of the finally
++ // is executed.
++ this.iterator = forNode.iterator;
+ }
+
+ @Override
+- public Node ensureUniqueLabels(LexicalContext lc) {
+- return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes));
++ public Node ensureUniqueLabels(final LexicalContext lc) {
++ return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
+ }
+
+ @Override
+@@ -90,8 +93,8 @@
+ if (visitor.enterForNode(this)) {
+ return visitor.leaveForNode(
+ setInit(lc, init == null ? null : (Expression)init.accept(visitor)).
+- setTest(lc, test == null ? null : (Expression)test.accept(visitor)).
+- setModify(lc, modify == null ? null : (Expression)modify.accept(visitor)).
++ setTest(lc, test == null ? null : (JoinPredecessorExpression)test.accept(visitor)).
++ setModify(lc, modify == null ? null : (JoinPredecessorExpression)modify.accept(visitor)).
+ setBody(lc, (Block)body.accept(visitor)));
+ }
+
+@@ -99,24 +102,25 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
+- sb.append("for (");
++ public void toString(final StringBuilder sb, final boolean printTypes) {
++ sb.append("for");
++ LocalVariableConversion.toString(conversion, sb).append(' ');
+
+ if (isForIn()) {
+- init.toString(sb);
++ init.toString(sb, printTypes);
+ sb.append(" in ");
+- modify.toString(sb);
++ modify.toString(sb, printTypes);
+ } else {
+ if (init != null) {
+- init.toString(sb);
++ init.toString(sb, printTypes);
+ }
+ sb.append("; ");
+ if (test != null) {
+- test.toString(sb);
++ test.toString(sb, printTypes);
+ }
+ sb.append("; ");
+ if (modify != null) {
+- modify.toString(sb);
++ modify.toString(sb, printTypes);
+ }
+ }
+
+@@ -154,7 +158,7 @@
+ if (this.init == init) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes));
++ return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
+ }
+
+ /**
+@@ -212,7 +216,7 @@
+ * Get the modification expression for this ForNode
+ * @return the modification expression
+ */
+- public Expression getModify() {
++ public JoinPredecessorExpression getModify() {
+ return modify;
+ }
+
+@@ -222,24 +226,19 @@
+ * @param modify new modification expression
+ * @return new for node if changed or existing if not
+ */
+- public ForNode setModify(final LexicalContext lc, final Expression modify) {
++ public ForNode setModify(final LexicalContext lc, final JoinPredecessorExpression modify) {
+ if (this.modify == modify) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes));
++ return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
+ }
+
+ @Override
+- public Expression getTest() {
+- return test;
+- }
+-
+- @Override
+- public ForNode setTest(final LexicalContext lc, final Expression test) {
++ public ForNode setTest(final LexicalContext lc, final JoinPredecessorExpression test) {
+ if (this.test == test) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes));
++ return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
+ }
+
+ @Override
+@@ -252,7 +251,7 @@
+ if (this.body == body) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes));
++ return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
+ }
+
+ @Override
+@@ -260,14 +259,32 @@
+ if (this.controlFlowEscapes == controlFlowEscapes) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes));
++ return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
+ }
+
+ private ForNode setFlags(final LexicalContext lc, final int flags) {
+ if (this.flags == flags) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes));
++ return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
+ }
+
++ @Override
++ JoinPredecessor setLocalVariableConversionChanged(final LexicalContext lc, final LocalVariableConversion conversion) {
++ return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion));
++ }
++
++ @Override
++ public boolean hasPerIterationScope() {
++ return (flags & PER_ITERATION_SCOPE) != 0;
++ }
++
++ /**
++ * Set the per-iteration-scope flag on this node.
++ * @param lc lexical context
++ * @return the node with flag set
++ */
++ public ForNode setPerIterationScope(final LexicalContext lc) {
++ return setFlags(lc, flags | PER_ITERATION_SCOPE);
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/FunctionCall.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/FunctionCall.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,14 +26,18 @@
+ package jdk.nashorn.internal.ir;
+
+ /**
+- * Interface used by AccessNodes, IndexNodes and IdentNodes to signal
+- * that they are function calls
++ * Interface used by AccessNodes, IndexNodes and IdentNodes to signal that when evaluated, their value will be treated
++ * as a function and immediately invoked, e.g. {@code foo()}, {@code foo.bar()} or {@code foo[bar]()}. Used to customize
++ * the priority of composite dynamic operations when emitting {@code INVOKEDYNAMIC} instructions that implement them,
++ * namely prioritize {@code getMethod} over {@code getElem} or {@code getProp}. An access or ident node with isFunction
++ * set to true will be emitted as {@code dyn:getMethod|getProp|getElem} while one with it set to false will be emitted
++ * as {@code dyn:getProp|getElem|getMethod}. Similarly, an index node with isFunction set to true will be emitted as
++ * {@code dyn:getMethod|getElem|getProp} while the one set to false will be emitted as {@code dyn:getElem|getProp|getMethod}.
+ */
+ public interface FunctionCall {
+ /**
+- * Return true if this function call implementor is a function
+- *
+- * @return true if implements a function call
++ * Returns true if the value of this expression will be treated as a function and immediately invoked.
++ * @return true if the value of this expression will be treated as a function and immediately invoked.
+ */
+ public boolean isFunction();
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,12 +25,19 @@
+
+ package jdk.nashorn.internal.ir;
+
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_PROFILE;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_TRACE;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_TRACE_ENTEREXIT;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_TRACE_VALUES;
++
+ import java.util.Collections;
+ import java.util.EnumSet;
+-import java.util.HashSet;
++import java.util.Iterator;
+ import java.util.List;
+-import java.util.Objects;
+-import java.util.Set;
++import java.util.function.Function;
++import jdk.nashorn.internal.AssertsEnabled;
+ import jdk.nashorn.internal.codegen.CompileUnit;
+ import jdk.nashorn.internal.codegen.Compiler;
+ import jdk.nashorn.internal.codegen.CompilerConstants;
+@@ -39,6 +46,7 @@
+ import jdk.nashorn.internal.ir.annotations.Ignore;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.Source;
+ import jdk.nashorn.internal.runtime.UserAccessorProperty;
+@@ -48,7 +56,8 @@
+ * IR representation for function (or script.)
+ */
+ @Immutable
+-public final class FunctionNode extends LexicalContextExpression implements Flags<FunctionNode> {
++public final class FunctionNode extends LexicalContextExpression implements Flags<FunctionNode>, CompileUnitHolder {
++ private static final long serialVersionUID = 1L;
+
+ /** Type used for all FunctionNodes */
+ public static final Type FUNCTION_TYPE = Type.typeFor(ScriptFunction.class);
+@@ -77,26 +86,41 @@
+ CONSTANT_FOLDED,
+ /** method has been lowered */
+ LOWERED,
+- /** method hass been attributed */
+- ATTR,
++ /** program points have been assigned to unique locations */
++ PROGRAM_POINTS_ASSIGNED,
++ /** any transformations of builtins have taken place, e.g. apply=&gt;call */
++ BUILTINS_TRANSFORMED,
+ /** method has been split */
+ SPLIT,
+- /** method has had its types finalized */
+- FINALIZED,
++ /** method has had symbols assigned */
++ SYMBOLS_ASSIGNED,
++ /** computed scope depths for symbols */
++ SCOPE_DEPTHS_COMPUTED,
++ /** method has had types calculated*/
++ OPTIMISTIC_TYPES_ASSIGNED,
++ /** method has had types calculated */
++ LOCAL_VARIABLE_TYPES_CALCULATED,
++ /** compile units reused (optional) */
++ COMPILE_UNITS_REUSED,
+ /** method has been emitted to bytecode */
+- EMITTED
++ BYTECODE_GENERATED,
++ /** method has been installed */
++ BYTECODE_INSTALLED
+ }
++
+ /** Source of entity. */
+- private final Source source;
++ private transient final Source source;
++
++ /**
++ * Opaque object representing parser state at the end of the function. Used when reparsing outer functions
++ * to skip parsing inner functions.
++ */
++ private final Object endParserState;
+
+ /** External function identifier. */
+ @Ignore
+ private final IdentNode ident;
+
+- /** Parsed version of functionNode */
+- @Ignore
+- private final FunctionNode snapshot;
+-
+ /** The body of the function node */
+ private final Block body;
+
+@@ -118,31 +142,25 @@
+ /** Last token of function. **/
+ private final long lastToken;
+
+- /** Declared symbols in this function node */
+- @Ignore
+- private final Set<Symbol> declaredSymbols;
+-
+ /** Method's namespace. */
+- private final Namespace namespace;
++ private transient final Namespace namespace;
+
+ /** Current compilation state */
+ @Ignore
+ private final EnumSet<CompilationState> compilationState;
+
++ /** Number of properties of "this" object assigned in this function */
+ @Ignore
+- private final Compiler.Hints hints;
+-
+- /** Properties of this object assigned in this function */
+- @Ignore
+- private HashSet<String> thisProperties;
++ private final int thisProperties;
+
+ /** Function flags. */
+ private final int flags;
+
+- /** //@ sourceURL or //# sourceURL for program function nodes */
+- private final String sourceURL;
++ /** Line number of function start */
++ private final int lineNumber;
+
+- private final int lineNumber;
++ /** Root class for function */
++ private final Class<?> rootClass;
+
+ /** Is anonymous function flag. */
+ public static final int IS_ANONYMOUS = 1 << 0;
+@@ -156,7 +174,7 @@
+ /** Does the function use the "arguments" identifier ? */
+ public static final int USES_ARGUMENTS = 1 << 3;
+
+- /** Has this node been split because it was too large? */
++ /** Has this function been split because it was too large? */
+ public static final int IS_SPLIT = 1 << 4;
+
+ /** Does the function call eval? If it does, then all variables in this function might be get/set by it and it can
+@@ -182,36 +200,87 @@
+ /** Does this function or any of its descendants use variables from an ancestor function's scope (incl. globals)? */
+ public static final int USES_ANCESTOR_SCOPE = 1 << 9;
+
+- /** Is this function lazily compiled? */
+- public static final int IS_LAZY = 1 << 10;
++ /** Does this function have nested declarations? */
++ public static final int HAS_FUNCTION_DECLARATIONS = 1 << 10;
+
+- /** Does this function have lazy, yet uncompiled children */
+- public static final int HAS_LAZY_CHILDREN = 1 << 11;
++ /** Does this function have optimistic expressions? (If it does, it can undergo deoptimizing recompilation.) */
++ public static final int IS_DEOPTIMIZABLE = 1 << 11;
+
+- /** Does this function have lazy, yet uncompiled children */
+- public static final int IS_PROGRAM = 1 << 12;
++ /** Are we vararg, but do we just pass the arguments along to apply or call */
++ public static final int HAS_APPLY_TO_CALL_SPECIALIZATION = 1 << 12;
+
+- /** Does this function have nested declarations? */
+- public static final int HAS_FUNCTION_DECLARATIONS = 1 << 13;
++ /**
++ * Is this function the top-level program?
++ */
++ public static final int IS_PROGRAM = 1 << 13;
+
+- /** Can this function be specialized? */
+- public static final int CAN_SPECIALIZE = 1 << 14;
++ /**
++ * Flag indicating whether this function uses the local variable symbol for itself. Only named function expressions
++ * can have this flag set if they reference themselves (e.g. "(function f() { return f })". Declared functions will
++ * use the symbol in their parent scope instead when they reference themselves by name.
++ */
++ public static final int USES_SELF_SYMBOL = 1 << 14;
+
+ /** Does this function use the "this" keyword? */
+- public static final int USES_THIS = 1 << 15;
++ public static final int USES_THIS = 1 << 15;
++
++ /** Is this declared in a dynamic context */
++ public static final int IN_DYNAMIC_CONTEXT = 1 << 16;
++
++ /**
++ * The following flags are derived from directive comments within this function.
++ * Note that even IS_STRICT is one such flag but that requires special handling.
++ */
++
++ /** parser, print parse tree */
++ public static final int IS_PRINT_PARSE = 1 << 17;
++ /** parser, print lower parse tree */
++ public static final int IS_PRINT_LOWER_PARSE = 1 << 18;
++ /** parser, print AST */
++ public static final int IS_PRINT_AST = 1 << 19;
++ /** parser, print lower AST */
++ public static final int IS_PRINT_LOWER_AST = 1 << 20;
++ /** parser, print symbols */
++ public static final int IS_PRINT_SYMBOLS = 1 << 21;
++
++ // callsite tracing, profiling within this function
++ /** profile callsites in this function? */
++ public static final int IS_PROFILE = 1 << 22;
++
++ /** trace callsite enterexit in this function? */
++ public static final int IS_TRACE_ENTEREXIT = 1 << 23;
++
++ /** trace callsite misses in this function? */
++ public static final int IS_TRACE_MISSES = 1 << 24;
++
++ /** trace callsite values in this function? */
++ public static final int IS_TRACE_VALUES = 1 << 25;
++
++ /**
++ * Whether this function needs the callee {@link ScriptFunction} instance passed to its code as a
++ * parameter on invocation. Note that we aren't, in fact using this flag in function nodes.
++ * Rather, it is always calculated (see {@link #needsCallee()}). {@link RecompilableScriptFunctionData}
++ * will, however, cache the value of this flag.
++ */
++ public static final int NEEDS_CALLEE = 1 << 26;
++
++ /** extension callsite flags mask */
++ public static final int EXTENSION_CALLSITE_FLAGS = IS_PRINT_PARSE |
++ IS_PRINT_LOWER_PARSE | IS_PRINT_AST | IS_PRINT_LOWER_AST |
++ IS_PRINT_SYMBOLS | IS_PROFILE | IS_TRACE_ENTEREXIT |
++ IS_TRACE_MISSES | IS_TRACE_VALUES;
+
+ /** Does this function or any nested functions contain an eval? */
+ private static final int HAS_DEEP_EVAL = HAS_EVAL | HAS_NESTED_EVAL;
+
+ /** Does this function need to store all its variables in scope? */
+- private static final int HAS_ALL_VARS_IN_SCOPE = HAS_DEEP_EVAL | IS_SPLIT | HAS_LAZY_CHILDREN;
++ private static final int HAS_ALL_VARS_IN_SCOPE = HAS_DEEP_EVAL;
+
+ /** Does this function potentially need "arguments"? Note that this is not a full test, as further negative check of REDEFINES_ARGS is needed. */
+ private static final int MAYBE_NEEDS_ARGUMENTS = USES_ARGUMENTS | HAS_EVAL;
+
+- /** Does this function need the parent scope? It needs it if either it or its descendants use variables from it, or have a deep eval.
+- * We also pessimistically need a parent scope if we have lazy children that have not yet been compiled */
+- private static final int NEEDS_PARENT_SCOPE = USES_ANCESTOR_SCOPE | HAS_DEEP_EVAL | HAS_LAZY_CHILDREN;
++ /** Does this function need the parent scope? It needs it if either it or its descendants use variables from it, or have a deep eval, or it's the program. */
++ public static final int NEEDS_PARENT_SCOPE = USES_ANCESTOR_SCOPE | HAS_DEEP_EVAL | IS_PROGRAM;
+
+ /** What is the return type of this function? */
+ private Type returnType = Type.UNKNOWN;
+@@ -223,14 +292,13 @@
+ * @param lineNumber line number
+ * @param token token
+ * @param finish finish
+- * @param firstToken first token of the funtion node (including the function declaration)
++ * @param firstToken first token of the function node (including the function declaration)
+ * @param namespace the namespace
+ * @param ident the identifier
+ * @param name the name of the function
+ * @param parameters parameter list
+ * @param kind kind of function as in {@link FunctionNode.Kind}
+ * @param flags initial flags
+- * @param sourceURL sourceURL specified in script (optional)
+ */
+ public FunctionNode(
+ final Source source,
+@@ -243,8 +311,7 @@
+ final String name,
+ final List<IdentNode> parameters,
+ final FunctionNode.Kind kind,
+- final int flags,
+- final String sourceURL) {
++ final int flags) {
+ super(token, finish);
+
+ this.source = source;
+@@ -257,32 +324,33 @@
+ this.lastToken = token;
+ this.namespace = namespace;
+ this.compilationState = EnumSet.of(CompilationState.INITIALIZED);
+- this.declaredSymbols = new HashSet<>();
+ this.flags = flags;
+- this.sourceURL = sourceURL;
+ this.compileUnit = null;
+ this.body = null;
+- this.snapshot = null;
+- this.hints = null;
++ this.thisProperties = 0;
++ this.rootClass = null;
++ this.endParserState = null;
+ }
+
+ private FunctionNode(
+ final FunctionNode functionNode,
+ final long lastToken,
++ final Object endParserState,
+ final int flags,
+- final String sourceURL,
+ final String name,
+ final Type returnType,
+ final CompileUnit compileUnit,
+ final EnumSet<CompilationState> compilationState,
+ final Block body,
+ final List<IdentNode> parameters,
+- final FunctionNode snapshot,
+- final Compiler.Hints hints) {
++ final int thisProperties,
++ final Class<?> rootClass,
++ final Source source, Namespace namespace) {
+ super(functionNode);
++
++ this.endParserState = endParserState;
+ this.lineNumber = functionNode.lineNumber;
+ this.flags = flags;
+- this.sourceURL = sourceURL;
+ this.name = name;
+ this.returnType = returnType;
+ this.compileUnit = compileUnit;
+@@ -290,17 +358,15 @@
+ this.compilationState = compilationState;
+ this.body = body;
+ this.parameters = parameters;
+- this.snapshot = snapshot;
+- this.hints = hints;
++ this.thisProperties = thisProperties;
++ this.rootClass = rootClass;
++ this.source = source;
++ this.namespace = namespace;
+
+ // the fields below never change - they are final and assigned in constructor
+- this.source = functionNode.source;
+ this.ident = functionNode.ident;
+- this.namespace = functionNode.namespace;
+- this.declaredSymbols = functionNode.declaredSymbols;
+ this.kind = functionNode.kind;
+ this.firstToken = functionNode.firstToken;
+- this.thisProperties = functionNode.thisProperties;
+ }
+
+ @Override
+@@ -312,6 +378,50 @@
+ }
+
+ /**
++ * Visits the parameter nodes of this function. Parameters are normally not visited automatically.
++ * @param visitor the visitor to apply to the nodes.
++ * @return a list of parameter nodes, potentially modified from original ones by the visitor.
++ */
++ public List<IdentNode> visitParameters(final NodeVisitor<? extends LexicalContext> visitor) {
++ return Node.accept(visitor, parameters);
++ }
++
++ /**
++ * Get additional callsite flags to be used specific to this function.
++ *
++ * @return callsite flags
++ */
++ public int getCallSiteFlags() {
++ int callsiteFlags = 0;
++ if (getFlag(IS_STRICT)) {
++ callsiteFlags |= CALLSITE_STRICT;
++ }
++
++ // quick check for extension callsite flags turned on by directives.
++ if ((flags & EXTENSION_CALLSITE_FLAGS) == 0) {
++ return callsiteFlags;
++ }
++
++ if (getFlag(IS_PROFILE)) {
++ callsiteFlags |= CALLSITE_PROFILE;
++ }
++
++ if (getFlag(IS_TRACE_MISSES)) {
++ callsiteFlags |= CALLSITE_TRACE | CALLSITE_TRACE_MISSES;
++ }
++
++ if (getFlag(IS_TRACE_VALUES)) {
++ callsiteFlags |= CALLSITE_TRACE | CALLSITE_TRACE_ENTEREXIT | CALLSITE_TRACE_VALUES;
++ }
++
++ if (getFlag(IS_TRACE_ENTEREXIT)) {
++ callsiteFlags |= CALLSITE_TRACE | CALLSITE_TRACE_ENTEREXIT;
++ }
++
++ return callsiteFlags;
++ }
++
++ /**
+ * Get the source for this function
+ * @return the source
+ */
+@@ -320,35 +430,96 @@
+ }
+
+ /**
++ * Sets the source and namespace for this function. It can only set a non-null source and namespace for a function
++ * that currently has both a null source and a null namespace. This is used to re-set the source and namespace for
++ * a deserialized function node.
++ * @param source the source for the function.
++ * @param namespace the namespace for the function
++ * @return a new function node with the set source and namespace
++ * @throws IllegalArgumentException if the specified source or namespace is null
++ * @throws IllegalStateException if the function already has either a source or namespace set.
++ */
++ public FunctionNode initializeDeserialized(final Source source, final Namespace namespace) {
++ if (source == null || namespace == null) {
++ throw new IllegalArgumentException();
++ } else if (this.source == source && this.namespace == namespace) {
++ return this;
++ } else if (this.source != null || this.namespace != null) {
++ throw new IllegalStateException();
++ }
++ return new FunctionNode(
++ this,
++ lastToken,
++ endParserState,
++ flags,
++ name,
++ returnType,
++ compileUnit,
++ compilationState,
++ body,
++ parameters,
++ thisProperties,
++ rootClass, source, namespace);
++ }
++
++ /**
++ * Get the unique ID for this function within the script file.
++ * @return the id
++ */
++ public int getId() {
++ return position();
++ }
++
++ /**
+ * get source name - sourceURL or name derived from Source.
+ *
+ * @return name for the script source
+ */
+ public String getSourceName() {
+- return (sourceURL != null)? sourceURL : source.getName();
++ return getSourceName(source);
+ }
+
+ /**
+- * get the sourceURL
+- * @return the sourceURL
++ * Static source name getter
++ *
++ * @param source the source
++ * @return source name
+ */
+- public String getSourceURL() {
+- return sourceURL;
++ public static String getSourceName(final Source source) {
++ final String explicitURL = source.getExplicitURL();
++ return explicitURL != null ? explicitURL : source.getName();
+ }
+
+ /**
+- * Set the sourceURL
++ * Function to parse nashorn per-function extension directive comments.
+ *
+- * @param lc lexical context
+- * @param newSourceURL source url string to set
+- * @return function node or a new one if state was changed
++ * @param directive nashorn extension directive string
++ * @return integer flag for the given directive.
+ */
+- public FunctionNode setSourceURL(final LexicalContext lc, final String newSourceURL) {
+- if (Objects.equals(sourceURL, newSourceURL)) {
+- return this;
++ public static int getDirectiveFlag(final String directive) {
++ switch (directive) {
++ case "nashorn callsite trace enterexit":
++ return IS_TRACE_ENTEREXIT;
++ case "nashorn callsite trace misses":
++ return IS_TRACE_MISSES;
++ case "nashorn callsite trace objects":
++ return IS_TRACE_VALUES;
++ case "nashorn callsite profile":
++ return IS_PROFILE;
++ case "nashorn print parse":
++ return IS_PRINT_PARSE;
++ case "nashorn print lower parse":
++ return IS_PRINT_LOWER_PARSE;
++ case "nashorn print ast":
++ return IS_PRINT_AST;
++ case "nashorn print lower ast":
++ return IS_PRINT_LOWER_AST;
++ case "nashorn print symbols":
++ return IS_PRINT_SYMBOLS;
++ default:
++ // unknown/unsupported directive
++ return 0;
+ }
+-
+- return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, newSourceURL, name, returnType, compileUnit, compilationState, body, parameters, null, hints));
+ }
+
+ /**
+@@ -360,53 +531,6 @@
+ }
+
+ /**
+- * Get the version of this function node's code as it looked upon construction
+- * i.e typically parsed and nothing else
+- * @return initial version of function node
+- */
+- public FunctionNode getSnapshot() {
+- return snapshot;
+- }
+-
+- /**
+- * Throw away the snapshot, if any, to save memory. Used when heuristic
+- * determines that a method is not worth specializing
+- *
+- * @param lc lexical context
+- * @return new function node if a snapshot was present, now with snapsnot null
+- */
+- public FunctionNode clearSnapshot(final LexicalContext lc) {
+- if (this.snapshot == null) {
+- return this;
+- }
+- return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, null, hints));
+- }
+-
+- /**
+- * Take a snapshot of this function node at a given point in time
+- * and store it in the function node
+- * @param lc lexical context
+- * @return function node
+- */
+- public FunctionNode snapshot(final LexicalContext lc) {
+- if (this.snapshot == this) {
+- return this;
+- }
+- if (isProgram() || parameters.isEmpty()) {
+- return this; //never specialize anything that won't be recompiled
+- }
+- return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, this, hints));
+- }
+-
+- /**
+- * Can this function node be regenerated with more specific type args?
+- * @return true if specialization is possible
+- */
+- public boolean canSpecialize() {
+- return snapshot != null && getFlag(CAN_SPECIALIZE);
+- }
+-
+- /**
+ * Get the compilation state of this function
+ * @return the compilation state
+ */
+@@ -421,21 +545,7 @@
+ * @return true of the node is in the given state
+ */
+ public boolean hasState(final EnumSet<CompilationState> state) {
+- return compilationState.equals(state);
+- }
+-
+- /**
+- * Check whether the state of this FunctionNode contains a given compilation
+- * state.
+- *
+- * A node can be in many states at once, e.g. both lowered and initialized.
+- * To check for an exact state, use {FunctionNode{@link #hasState(EnumSet)}
+- *
+- * @param state state to check for
+- * @return true if state is present in the total compilation state of this FunctionNode
+- */
+- public boolean hasState(final CompilationState state) {
+- return compilationState.contains(state);
++ return !AssertsEnabled.assertsEnabled() || compilationState.containsAll(state);
+ }
+
+ /**
+@@ -448,35 +558,52 @@
+ * @return function node or a new one if state was changed
+ */
+ public FunctionNode setState(final LexicalContext lc, final CompilationState state) {
+- if (this.compilationState.contains(state)) {
++ if (!AssertsEnabled.assertsEnabled() || this.compilationState.contains(state)) {
+ return this;
+ }
+ final EnumSet<CompilationState> newState = EnumSet.copyOf(this.compilationState);
+ newState.add(state);
+- return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, newState, body, parameters, snapshot, hints));
++ return setCompilationState(lc, newState);
+ }
+
+ /**
+- * Get any compiler hints that may associated with the function
+- * @return compiler hints
++ * Copy a compilation state from an original function to this function. Used when creating synthetic
++ * function nodes by the splitter.
++ *
++ * @param lc lexical context
++ * @param original the original function node to copy compilation state from
++ * @return function node or a new one if state was changed
+ */
+- public Compiler.Hints getHints() {
+- return this.hints == null ? Compiler.Hints.EMPTY : hints;
++ public FunctionNode copyCompilationState(final LexicalContext lc, final FunctionNode original) {
++ final EnumSet<CompilationState> origState = original.compilationState;
++ if (!AssertsEnabled.assertsEnabled() || this.compilationState.containsAll(origState)) {
++ return this;
++ }
++ final EnumSet<CompilationState> newState = EnumSet.copyOf(this.compilationState);
++ newState.addAll(origState);
++ return setCompilationState(lc, newState);
+ }
+
+- /**
+- * Set compiler hints for this function
+- * @param lc lexical context
+- * @param hints compiler hints
+- * @return new function if hints changed
+- */
+- public FunctionNode setHints(final LexicalContext lc, final Compiler.Hints hints) {
+- if (this.hints == hints) {
+- return this;
+- }
+- return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
++ private FunctionNode setCompilationState(final LexicalContext lc, final EnumSet<CompilationState> compilationState) {
++ return Node.replaceInLexicalContext(
++ lc,
++ this,
++ new FunctionNode(
++ this,
++ lastToken,
++ endParserState,
++ flags,
++ name,
++ returnType,
++ compileUnit,
++ compilationState,
++ body,
++ parameters,
++ thisProperties,
++ rootClass, source, namespace));
+ }
+
++
+ /**
+ * Create a unique name in the namespace of this FunctionNode
+ * @param base prefix for name
+@@ -486,48 +613,67 @@
+ return namespace.uniqueName(base);
+ }
+
+-
+ @Override
+- public void toString(final StringBuilder sb) {
+- sb.append('[');
+- sb.append(returnType);
+- sb.append(']');
+- sb.append(' ');
++ public void toString(final StringBuilder sb, final boolean printTypes) {
++ sb.append('[').
++ append(returnType).
++ append(']').
++ append(' ');
+
+ sb.append("function");
+
+ if (ident != null) {
+ sb.append(' ');
+- ident.toString(sb);
++ ident.toString(sb, printTypes);
+ }
+
+ sb.append('(');
+- boolean first = true;
+
+- for (final IdentNode parameter : parameters) {
+- if (!first) {
++ for (final Iterator<IdentNode> iter = parameters.iterator(); iter.hasNext(); ) {
++ final IdentNode parameter = iter.next();
++ if (parameter.getSymbol() != null) {
++ sb.append('[').append(parameter.getType()).append(']').append(' ');
++ }
++ parameter.toString(sb, printTypes);
++ if (iter.hasNext()) {
+ sb.append(", ");
+- } else {
+- first = false;
+ }
+-
+- parameter.toString(sb);
+ }
+
+ sb.append(')');
+ }
+
+ @Override
++ public int getFlags() {
++ return flags;
++ }
++
++ @Override
+ public boolean getFlag(final int flag) {
+ return (flags & flag) != 0;
+ }
+
+ @Override
+- public FunctionNode setFlags(final LexicalContext lc, int flags) {
++ public FunctionNode setFlags(final LexicalContext lc, final int flags) {
+ if (this.flags == flags) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
++ return Node.replaceInLexicalContext(
++ lc,
++ this,
++ new FunctionNode(
++ this,
++ lastToken,
++ endParserState,
++ flags,
++ name,
++ returnType,
++ compileUnit,
++ compilationState,
++ body,
++ parameters,
++ thisProperties,
++ rootClass, source, namespace));
+ }
+
+ @Override
+@@ -549,23 +695,32 @@
+ }
+
+ /**
+- * Should this function node be lazily code generated, i.e. first at link time
+- * @return true if lazy
++ * Returns true if the function contains at least one optimistic operation (and thus can be deoptimized).
++ * @return true if the function contains at least one optimistic operation (and thus can be deoptimized).
+ */
+- public boolean isLazy() {
+- return getFlag(IS_LAZY);
++ public boolean canBeDeoptimized() {
++ return getFlag(IS_DEOPTIMIZABLE);
+ }
+
+ /**
+- * Check if the {@code eval} keyword is used in this function
++ * Check if this function has a call expression for the identifier "eval" (that is, {@code eval(...)}).
+ *
+- * @return true if {@code eval} is used
++ * @return true if {@code eval} is called.
+ */
+ public boolean hasEval() {
+ return getFlag(HAS_EVAL);
+ }
+
+ /**
++ * Returns true if a function nested (directly or transitively) within this function {@link #hasEval()}.
++ *
++ * @return true if a nested function calls {@code eval}.
++ */
++ public boolean hasNestedEval() {
++ return getFlag(HAS_NESTED_EVAL);
++ }
++
++ /**
+ * Get the first token for this function
+ * @return the first token
+ */
+@@ -587,10 +742,14 @@
+ * (since it exposes {@code arguments.callee} property) will need to have a callee parameter. We also return true
+ * for split functions to make sure symbols slots are the same in the main and split methods.
+ *
++ * A function that has had an apply(this,arguments) turned into a call doesn't need arguments anymore, but still
++ * has to fit the old callsite, thus, we require a dummy callee parameter for those functions as well
++ *
+ * @return true if the function's generated Java method needs a {@code callee} parameter.
+ */
+ public boolean needsCallee() {
+- return needsParentScope() || needsSelfSymbol() || isSplit() || (needsArguments() && !isStrict());
++ // NOTE: we only need isSplit() here to ensure that :scope can never drop below slot 2 for splitting array units.
++ return needsParentScope() || usesSelfSymbol() || isSplit() || (needsArguments() && !isStrict()) || hasOptimisticApplyToCall();
+ }
+
+ /**
+@@ -602,6 +761,15 @@
+ return getFlag(USES_THIS);
+ }
+
++
++ /**
++ * Return true if function contains an apply to call transform
++ * @return true if this function has transformed apply to call
++ */
++ public boolean hasOptimisticApplyToCall() {
++ return getFlag(HAS_APPLY_TO_CALL_SPECIALIZATION);
++ }
++
+ /**
+ * Get the identifier for this function, this is its symbol.
+ * @return the identifier as an IdentityNode
+@@ -611,24 +779,6 @@
+ }
+
+ /**
+- * Return a set of symbols declared in this function node. This
+- * is only relevant after Attr, otherwise it will be an empty
+- * set as no symbols have been introduced
+- * @return set of declared symbols in function
+- */
+- public Set<Symbol> getDeclaredSymbols() {
+- return Collections.unmodifiableSet(declaredSymbols);
+- }
+-
+- /**
+- * Add a declared symbol to this function node
+- * @param symbol symbol that is declared
+- */
+- public void addDeclaredSymbol(final Symbol symbol) {
+- declaredSymbols.add(symbol);
+- }
+-
+- /**
+ * Get the function body
+ * @return the function body
+ */
+@@ -643,10 +793,28 @@
+ * @return new function node if body changed, same if not
+ */
+ public FunctionNode setBody(final LexicalContext lc, final Block body) {
+- if(this.body == body) {
++ if (this.body == body) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags | (body.needsScope() ? FunctionNode.HAS_SCOPE_BLOCK : 0), sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
++ return Node.replaceInLexicalContext(
++ lc,
++ this,
++ new FunctionNode(
++ this,
++ lastToken,
++ endParserState,
++ flags |
++ (body.needsScope() ?
++ FunctionNode.HAS_SCOPE_BLOCK :
++ 0),
++ name,
++ returnType,
++ compileUnit,
++ compilationState,
++ body,
++ parameters,
++ thisProperties,
++ rootClass, source, namespace));
+ }
+
+ /**
+@@ -662,6 +830,36 @@
+ }
+
+ /**
++ * Was this function declared in a dynamic context, i.e. in a with or eval style
++ * chain
++ * @return true if in dynamic context
++ */
++ public boolean inDynamicContext() {
++ return getFlag(IN_DYNAMIC_CONTEXT);
++ }
++
++ /**
++ * Check whether a function would need dynamic scope, which is does if it has
++ * evals and isn't strict.
++ * @return true if dynamic scope is needed
++ */
++ public boolean needsDynamicScope() {
++ // Function has a direct eval in it (so a top-level "var ..." in the eval code can introduce a new
++ // variable into the function's scope), and it isn't strict (as evals in strict functions get an
++ // isolated scope).
++ return hasEval() && !isStrict();
++ }
++
++ /**
++ * Flag this function as declared in a dynamic context
++ * @param lc lexical context
++ * @return new function node, or same if unmodified
++ */
++ public FunctionNode setInDynamicContext(final LexicalContext lc) {
++ return setFlag(lc, IN_DYNAMIC_CONTEXT);
++ }
++
++ /**
+ * Returns true if this function needs to have an Arguments object defined as a local variable named "arguments".
+ * Functions that use "arguments" as identifier and don't define it as a name of a parameter or a nested function
+ * (see ECMAScript 5.1 Chapter 10.5), as well as any function that uses eval or with, or has a nested function that
+@@ -684,26 +882,43 @@
+ * @return true if the function needs parent scope.
+ */
+ public boolean needsParentScope() {
+- return getFlag(NEEDS_PARENT_SCOPE) || isProgram();
++ return getFlag(NEEDS_PARENT_SCOPE);
+ }
+
+ /**
+- * Register a property assigned to the this object in this function.
+- * @param key the property name
++ * Set the number of properties assigned to the this object in this function.
++ * @param lc the current lexical context.
++ * @param thisProperties number of properties
++ * @return a potentially modified function node
+ */
+- public void addThisProperty(final String key) {
+- if (thisProperties == null) {
+- thisProperties = new HashSet<>();
++ public FunctionNode setThisProperties(final LexicalContext lc, final int thisProperties) {
++ if (this.thisProperties == thisProperties) {
++ return this;
+ }
+- thisProperties.add(key);
++ return Node.replaceInLexicalContext(
++ lc,
++ this,
++ new FunctionNode(
++ this,
++ lastToken,
++ endParserState,
++ flags,
++ name,
++ returnType,
++ compileUnit,
++ compilationState,
++ body,
++ parameters,
++ thisProperties,
++ rootClass, source, namespace));
+ }
+
+ /**
+ * Get the number of properties assigned to the this object in this function.
+ * @return number of properties
+ */
+- public int countThisProperties() {
+- return thisProperties == null ? 0 : thisProperties.size();
++ public int getThisProperties() {
++ return thisProperties;
+ }
+
+ /**
+@@ -741,7 +956,60 @@
+ if (this.lastToken == lastToken) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
++ return Node.replaceInLexicalContext(
++ lc,
++ this,
++ new FunctionNode(
++ this,
++ lastToken,
++ endParserState,
++ flags,
++ name,
++ returnType,
++ compileUnit,
++ compilationState,
++ body,
++ parameters,
++ thisProperties,
++ rootClass, source, namespace));
++ }
++
++ /**
++ * Returns the end parser state for this function.
++ * @return the end parser state for this function.
++ */
++ public Object getEndParserState() {
++ return endParserState;
++ }
++
++ /**
++ * Set the end parser state for this function.
++ * @param lc lexical context
++ * @param endParserState the parser state to set
++ * @return function node or a new one if state was changed
++ */
++ public FunctionNode setEndParserState(final LexicalContext lc, final Object endParserState) {
++ if (this.endParserState == endParserState) {
++ return this;
++ }
++ return Node.replaceInLexicalContext(
++ lc,
++ this,
++ new FunctionNode(
++ this,
++ lastToken,
++ endParserState,
++ flags,
++ name,
++ returnType,
++ compileUnit,
++ compilationState,
++ body,
++ parameters,
++ thisProperties,
++ rootClass,
++ source,
++ namespace));
+ }
+
+ /**
+@@ -752,7 +1020,6 @@
+ return name;
+ }
+
+-
+ /**
+ * Set the internal name for this function
+ * @param lc lexical context
+@@ -763,38 +1030,46 @@
+ if (this.name.equals(name)) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
++ return Node.replaceInLexicalContext(
++ lc,
++ this,
++ new FunctionNode(
++ this,
++ lastToken,
++ endParserState,
++ flags,
++ name,
++ returnType,
++ compileUnit,
++ compilationState,
++ body,
++ parameters,
++ thisProperties,
++ rootClass,
++ source,
++ namespace));
+ }
+
+ /**
+- * Check if this function should have all its variables in its own scope. Scripts, split sub-functions, and
++ * Check if this function should have all its variables in its own scope. Split sub-functions, and
+ * functions having with and/or eval blocks are such.
+ *
+ * @return true if all variables should be in scope
+ */
+ public boolean allVarsInScope() {
+- return isProgram() || getFlag(HAS_ALL_VARS_IN_SCOPE);
++ return getFlag(HAS_ALL_VARS_IN_SCOPE);
+ }
+
+ /**
+- * Checks if this function is a sub-function generated by splitting a larger one
++ * Checks if this function is split into several smaller fragments.
+ *
+- * @return true if this function is split from a larger one
++ * @return true if this function is split into several smaller fragments.
+ */
+ public boolean isSplit() {
+ return getFlag(IS_SPLIT);
+ }
+
+ /**
+- * Checks if this function has yet-to-be-generated child functions
+- *
+- * @return true if there are lazy child functions
+- */
+- public boolean hasLazyChildren() {
+- return getFlag(HAS_LAZY_CHILDREN);
+- }
+-
+- /**
+ * Get the parameters to this function
+ * @return a list of IdentNodes which represent the function parameters, in order
+ */
+@@ -803,6 +1078,16 @@
+ }
+
+ /**
++ * Returns the identifier for a named parameter at the specified position in this function's parameter list.
++ * @param index the parameter's position.
++ * @return the identifier for the requested named parameter.
++ * @throws IndexOutOfBoundsException if the index is invalid.
++ */
++ public IdentNode getParameter(final int index) {
++ return parameters.get(index);
++ }
++
++ /**
+ * Reset the compile unit used to compile this function
+ * @see Compiler
+ * @param lc lexical context
+@@ -813,7 +1098,22 @@
+ if (this.parameters == parameters) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
++ return Node.replaceInLexicalContext(
++ lc,
++ this,
++ new FunctionNode(
++ this,
++ lastToken,
++ endParserState,
++ flags,
++ name,
++ returnType,
++ compileUnit,
++ compilationState,
++ body,
++ parameters,
++ thisProperties,
++ rootClass, source, namespace));
+ }
+
+ /**
+@@ -833,16 +1133,22 @@
+ }
+
+ /**
+- * Does this function need a self symbol - this is needed only for self
+- * referring functions
+- * @return true if function needs a symbol for self
++ * Does this function use its self symbol - this is needed only for self-referencing named function expressions.
++ * Self-referencing declared functions won't have this flag set, as they can access their own symbol through the
++ * scope (since they're bound to the symbol with their name in their enclosing scope).
++ * @return true if this function node is a named function expression that uses the symbol for itself.
+ */
+- public boolean needsSelfSymbol() {
+- return body.getFlag(Block.NEEDS_SELF_SYMBOL);
++ public boolean usesSelfSymbol() {
++ return getFlag(USES_SELF_SYMBOL);
+ }
+
+ @Override
+- public Type getType() {
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
++ return FUNCTION_TYPE;
++ }
++
++ @Override
++ public Type getWidestOperationType() {
+ return FUNCTION_TYPE;
+ }
+
+@@ -867,27 +1173,28 @@
+ //we never bother with object types narrower than objects, that will lead to byte code verification errors
+ //as for instance even if we know we are returning a string from a method, the code generator will always
+ //treat it as an object, at least for now
+- if (this.returnType == returnType) {
++ final Type type = returnType.isObject() ? Type.OBJECT : returnType;
++ if (this.returnType == type) {
+ return this;
+ }
+- final Type type = Type.widest(this.returnType, returnType.isObject() ? Type.OBJECT : returnType);
+ return Node.replaceInLexicalContext(
+ lc,
+ this,
+ new FunctionNode(
+ this,
+ lastToken,
++ endParserState,
+ flags,
+- sourceURL,
+ name,
+ type,
+ compileUnit,
+ compilationState,
+- body.setReturnType(type),
++ body,
+ parameters,
+- snapshot,
+- hints));
+- }
++ thisProperties,
++ rootClass, source, namespace
++ ));
++ }
+
+ /**
+ * Check if the function is generated in strict mode
+@@ -902,6 +1209,7 @@
+ * @see Compiler
+ * @return the compile unit
+ */
++ @Override
+ public CompileUnit getCompileUnit() {
+ return compileUnit;
+ }
+@@ -917,7 +1225,22 @@
+ if (this.compileUnit == compileUnit) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
++ return Node.replaceInLexicalContext(
++ lc,
++ this,
++ new FunctionNode(
++ this,
++ lastToken,
++ endParserState,
++ flags,
++ name,
++ returnType,
++ compileUnit,
++ compilationState,
++ body,
++ parameters,
++ thisProperties,
++ rootClass, source, namespace));
+ }
+
+ /**
+@@ -938,4 +1261,41 @@
+ public Symbol compilerConstant(final CompilerConstants cc) {
+ return body.getExistingSymbol(cc.symbolName());
+ }
++
++ /**
++ * Get the root class that this function node compiles to
++ * @return root class
++ */
++ public Class<?> getRootClass() {
++ return rootClass;
++ }
++
++ /**
++ * Reset the root class that this function is compiled to
++ * @see Compiler
++ * @param lc lexical context
++ * @param rootClass root class
++ * @return function node or a new one if state was changed
++ */
++ public FunctionNode setRootClass(final LexicalContext lc, final Class<?> rootClass) {
++ if (this.rootClass == rootClass) {
++ return this;
++ }
++ return Node.replaceInLexicalContext(
++ lc,
++ this,
++ new FunctionNode(
++ this,
++ lastToken,
++ endParserState,
++ flags,
++ name,
++ returnType,
++ compileUnit,
++ compilationState,
++ body,
++ parameters,
++ thisProperties,
++ rootClass, source, namespace));
++ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/ir/GetSplitState.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.ir;
++
++import java.util.function.Function;
++import jdk.nashorn.internal.codegen.CompilerConstants;
++import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++import jdk.nashorn.internal.runtime.Scope;
++
++/**
++ * Synthetic AST node that represents loading of the scope object and invocation of the {@link Scope#getSplitState()}
++ * method on it. It has no JavaScript source representation and only occurs in synthetic functions created by
++ * the split-into-functions transformation.
++ */
++public final class GetSplitState extends Expression {
++ private static final long serialVersionUID = 1L;
++
++ /** The sole instance of this AST node. */
++ public final static GetSplitState INSTANCE = new GetSplitState();
++
++ private GetSplitState() {
++ super(NO_TOKEN, NO_FINISH);
++ }
++
++ @Override
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
++ return Type.INT;
++ }
++
++ @Override
++ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
++ return visitor.enterGetSplitState(this) ? visitor.leaveGetSplitState(this) : this;
++ }
++
++ @Override
++ public void toString(final StringBuilder sb, final boolean printType) {
++ if (printType) {
++ sb.append("{I}");
++ }
++ sb.append(CompilerConstants.SCOPE.symbolName()).append('.').append(Scope.GET_SPLIT_STATE.name()).append("()");
++ }
++
++ private Object readResolve() {
++ return INSTANCE;
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/ir/IdentNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/IdentNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,29 +28,44 @@
+ import static jdk.nashorn.internal.codegen.CompilerConstants.__DIR__;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.__FILE__;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.__LINE__;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
+
++import java.util.function.Function;
+ import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++import jdk.nashorn.internal.parser.Token;
++import jdk.nashorn.internal.parser.TokenType;
+
+ /**
+ * IR representation for an identifier.
+ */
+ @Immutable
+-public final class IdentNode extends Expression implements PropertyKey, FunctionCall {
++public final class IdentNode extends Expression implements PropertyKey, FunctionCall, Optimistic, JoinPredecessor {
++ private static final long serialVersionUID = 1L;
++
+ private static final int PROPERTY_NAME = 1 << 0;
+ private static final int INITIALIZED_HERE = 1 << 1;
+ private static final int FUNCTION = 1 << 2;
+ private static final int FUTURESTRICT_NAME = 1 << 3;
++ private static final int IS_DECLARED_HERE = 1 << 4;
++ private static final int IS_DEAD = 1 << 5;
+
+ /** Identifier. */
+ private final String name;
+
+- /** Type for a callsite, e.g. X in a get()X or a set(X)V */
+- private final Type callSiteType;
++ /** Optimistic type */
++ private final Type type;
+
+ private final int flags;
+
++ private final int programPoint;
++
++ private final LocalVariableConversion conversion;
++
++ private Symbol symbol;
++
++
+ /**
+ * Constructor
+ *
+@@ -60,16 +75,21 @@
+ */
+ public IdentNode(final long token, final int finish, final String name) {
+ super(token, finish);
+- this.name = name.intern();
+- this.callSiteType = null;
++ this.name = name;
++ this.type = null;
+ this.flags = 0;
++ this.programPoint = INVALID_PROGRAM_POINT;
++ this.conversion = null;
+ }
+
+- private IdentNode(final IdentNode identNode, final String name, final Type callSiteType, final int flags) {
++ private IdentNode(final IdentNode identNode, final String name, final Type type, final int flags, final int programPoint, final LocalVariableConversion conversion) {
+ super(identNode);
+ this.name = name;
+- this.callSiteType = callSiteType;
++ this.type = type;
+ this.flags = flags;
++ this.programPoint = programPoint;
++ this.conversion = conversion;
++ this.symbol = identNode.symbol;
+ }
+
+ /**
+@@ -79,24 +99,33 @@
+ */
+ public IdentNode(final IdentNode identNode) {
+ super(identNode);
+- this.name = identNode.getName();
+- this.callSiteType = null;
+- this.flags = identNode.flags;
++ this.name = identNode.getName();
++ this.type = identNode.type;
++ this.flags = identNode.flags;
++ this.conversion = identNode.conversion;
++ this.programPoint = INVALID_PROGRAM_POINT;
++ this.symbol = identNode.symbol;
++ }
++
++ /**
++ * Creates an identifier for the symbol. Normally used by code generator for creating temporary storage identifiers
++ * that must contain both a symbol and a type.
++ * @param symbol the symbol to create a temporary identifier for.
++ * @return a temporary identifier for the symbol.
++ */
++ public static IdentNode createInternalIdentifier(final Symbol symbol) {
++ return new IdentNode(Token.toDesc(TokenType.IDENT, 0, 0), 0, symbol.getName()).setSymbol(symbol);
+ }
+
+ @Override
+- public Type getType() {
+- return callSiteType == null ? super.getType() : callSiteType;
+- }
+-
+- @Override
+- public boolean isAtom() {
+- return true;
+- }
+-
+- private boolean hasCallSiteType() {
+- //this is an identity that's part of a getter or setter
+- return callSiteType != null;
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
++ if(type != null) {
++ return type;
++ } else if(symbol != null && symbol.isScope()) {
++ return Type.OBJECT;
++ }
++ final Type symbolType = localVariableTypes.apply(symbol);
++ return symbolType == null ? Type.UNDEFINED : symbolType;
+ }
+
+ /**
+@@ -114,14 +143,10 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
+- if (hasCallSiteType()) {
+- sb.append('{');
+- final String desc = getType().getDescriptor();
+- sb.append(desc.charAt(desc.length() - 1) == ';' ? 'O' : getType().getDescriptor());
+- sb.append('}');
++ public void toString(final StringBuilder sb, final boolean printType) {
++ if (printType) {
++ optimisticTypeToString(sb, symbol == null || !symbol.hasSlot());
+ }
+-
+ sb.append(name);
+ }
+
+@@ -144,11 +169,36 @@
+ }
+
+ /**
++ * Return the Symbol the compiler has assigned to this identifier. The symbol is a description of the storage
++ * location for the identifier.
++ *
++ * @return the symbol
++ */
++ public Symbol getSymbol() {
++ return symbol;
++ }
++
++ /**
++ * Assign a symbol to this identifier. See {@link IdentNode#getSymbol()} for explanation of what a symbol is.
++ *
++ * @param symbol the symbol
++ * @return new node
++ */
++ public IdentNode setSymbol(final Symbol symbol) {
++ if (this.symbol == symbol) {
++ return this;
++ }
++ final IdentNode newIdent = (IdentNode)clone();
++ newIdent.symbol = symbol;
++ return newIdent;
++ }
++
++ /**
+ * Check if this IdentNode is a property name
+ * @return true if this is a property name
+ */
+ public boolean isPropertyName() {
+- return (flags & PROPERTY_NAME) != 0;
++ return (flags & PROPERTY_NAME) == PROPERTY_NAME;
+ }
+
+ /**
+@@ -159,7 +209,7 @@
+ if (isPropertyName()) {
+ return this;
+ }
+- return new IdentNode(this, name, callSiteType, flags | PROPERTY_NAME);
++ return new IdentNode(this, name, type, flags | PROPERTY_NAME, programPoint, conversion);
+ }
+
+ /**
+@@ -167,7 +217,7 @@
+ * @return true if this is a future strict name
+ */
+ public boolean isFutureStrictName() {
+- return (flags & FUTURESTRICT_NAME) != 0;
++ return (flags & FUTURESTRICT_NAME) == FUTURESTRICT_NAME;
+ }
+
+ /**
+@@ -178,7 +228,7 @@
+ if (isFutureStrictName()) {
+ return this;
+ }
+- return new IdentNode(this, name, callSiteType, flags | FUTURESTRICT_NAME);
++ return new IdentNode(this, name, type, flags | FUTURESTRICT_NAME, programPoint, conversion);
+ }
+
+ /**
+@@ -186,7 +236,7 @@
+ * @return true if IdentNode is initialized on creation
+ */
+ public boolean isInitializedHere() {
+- return (flags & INITIALIZED_HERE) != 0;
++ return (flags & INITIALIZED_HERE) == INITIALIZED_HERE;
+ }
+
+ /**
+@@ -197,22 +247,69 @@
+ if (isInitializedHere()) {
+ return this;
+ }
+- return new IdentNode(this, name, callSiteType, flags | INITIALIZED_HERE);
++ return new IdentNode(this, name, type, flags | INITIALIZED_HERE, programPoint, conversion);
+ }
+
+ /**
+- * Check if this IdentNode is a special identity, currently __DIR__, __FILE__
+- * or __LINE__
++ * Is this a LET or CONST identifier used before its declaration?
+ *
+- * @return true if this IdentNode is special
++ * @return true if identifier is dead
+ */
+- public boolean isSpecialIdentity() {
++ public boolean isDead() {
++ return (flags & IS_DEAD) != 0;
++ }
++
++ /**
++ * Flag this IdentNode as a LET or CONST identifier used before its declaration.
++ *
++ * @return a new IdentNode equivalent to this but marked as dead.
++ */
++ public IdentNode markDead() {
++ return new IdentNode(this, name, type, flags | IS_DEAD, programPoint, conversion);
++ }
++
++ /**
++ * Is this IdentNode declared here?
++ *
++ * @return true if identifier is declared here
++ */
++ public boolean isDeclaredHere() {
++ return (flags & IS_DECLARED_HERE) != 0;
++ }
++
++ /**
++ * Flag this IdentNode as being declared here.
++ *
++ * @return a new IdentNode equivalent to this but marked as declared here.
++ */
++ public IdentNode setIsDeclaredHere() {
++ if (isDeclaredHere()) {
++ return this;
++ }
++ return new IdentNode(this, name, type, flags | IS_DECLARED_HERE, programPoint, conversion);
++ }
++
++ /**
++ * Check if the name of this IdentNode is same as that of a compile-time property (currently __DIR__, __FILE__, and
++ * __LINE__).
++ *
++ * @return true if this IdentNode's name is same as that of a compile-time property
++ */
++ public boolean isCompileTimePropertyName() {
+ return name.equals(__DIR__.symbolName()) || name.equals(__FILE__.symbolName()) || name.equals(__LINE__.symbolName());
+ }
+
+ @Override
+ public boolean isFunction() {
+- return (flags & FUNCTION) != 0;
++ return (flags & FUNCTION) == FUNCTION;
++ }
++
++ @Override
++ public IdentNode setType(final Type type) {
++ if (this.type == type) {
++ return this;
++ }
++ return new IdentNode(this, name, type, flags, programPoint, conversion);
+ }
+
+ /**
+@@ -223,6 +320,68 @@
+ if (isFunction()) {
+ return this;
+ }
+- return new IdentNode(this, name, callSiteType, flags | FUNCTION);
++ return new IdentNode(this, name, type, flags | FUNCTION, programPoint, conversion);
++ }
++
++ /**
++ * Mark this node as not being the callee operand of a {@link CallNode}.
++ * @return an ident node identical to this one in all aspects except with its function flag unset.
++ */
++ public IdentNode setIsNotFunction() {
++ if (! isFunction()) {
++ return this;
++ }
++ return new IdentNode(this, name, type, flags & ~FUNCTION, programPoint, conversion);
++ }
++
++ @Override
++ public int getProgramPoint() {
++ return programPoint;
++ }
++
++ @Override
++ public Optimistic setProgramPoint(final int programPoint) {
++ if (this.programPoint == programPoint) {
++ return this;
++ }
++ return new IdentNode(this, name, type, flags, programPoint, conversion);
++ }
++
++ @Override
++ public Type getMostOptimisticType() {
++ return Type.INT;
++ }
++
++ @Override
++ public Type getMostPessimisticType() {
++ return Type.OBJECT;
++ }
++
++ @Override
++ public boolean canBeOptimistic() {
++ return true;
++ }
++
++ @Override
++ public JoinPredecessor setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) {
++ if(this.conversion == conversion) {
++ return this;
++ }
++ return new IdentNode(this, name, type, flags, programPoint, conversion);
++ }
++
++ /**
++ * Is this an internal symbol, i.e. one that starts with ':'. Those can
++ * never be optimistic.
++ * @return true if internal symbol
++ */
++ public boolean isInternal() {
++ assert name != null;
++ return name.charAt(0) == ':';
++ }
++
++ @Override
++ public LocalVariableConversion getLocalVariableConversion() {
++ return conversion;
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/IfNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/IfNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -32,7 +32,9 @@
+ * IR representation for an IF statement.
+ */
+ @Immutable
+-public final class IfNode extends Statement {
++public final class IfNode extends Statement implements JoinPredecessor {
++ private static final long serialVersionUID = 1L;
++
+ /** Test expression. */
+ private final Expression test;
+
+@@ -43,6 +45,12 @@
+ private final Block fail;
+
+ /**
++ * Local variable conversions that need to be performed after test if it evaluates to false, and there's no else
++ * branch.
++ */
++ private final LocalVariableConversion conversion;
++
++ /**
+ * Constructor
+ *
+ * @param lineNumber line number
+@@ -57,13 +65,15 @@
+ this.test = test;
+ this.pass = pass;
+ this.fail = fail;
++ this.conversion = null;
+ }
+
+- private IfNode(final IfNode ifNode, final Expression test, final Block pass, final Block fail) {
++ private IfNode(final IfNode ifNode, final Expression test, final Block pass, final Block fail, final LocalVariableConversion conversion) {
+ super(ifNode);
+ this.test = test;
+ this.pass = pass;
+ this.fail = fail;
++ this.conversion = conversion;
+ }
+
+ @Override
+@@ -84,9 +94,9 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printTypes) {
+ sb.append("if (");
+- test.toString(sb);
++ test.toString(sb, printTypes);
+ sb.append(')');
+ }
+
+@@ -102,7 +112,7 @@
+ if (this.fail == fail) {
+ return this;
+ }
+- return new IfNode(this, test, pass, fail);
++ return new IfNode(this, test, pass, fail, conversion);
+ }
+
+ /**
+@@ -117,7 +127,7 @@
+ if (this.pass == pass) {
+ return this;
+ }
+- return new IfNode(this, test, pass, fail);
++ return new IfNode(this, test, pass, fail, conversion);
+ }
+
+ /**
+@@ -137,6 +147,19 @@
+ if (this.test == test) {
+ return this;
+ }
+- return new IfNode(this, test, pass, fail);
++ return new IfNode(this, test, pass, fail, conversion);
++ }
++
++ @Override
++ public IfNode setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) {
++ if(this.conversion == conversion) {
++ return this;
++ }
++ return new IfNode(this, test, pass, fail, conversion);
++ }
++
++ @Override
++ public LocalVariableConversion getLocalVariableConversion() {
++ return conversion;
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/IndexNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/IndexNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,14 +25,16 @@
+
+ package jdk.nashorn.internal.ir;
+
++import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+-
+ /**
+ * IR representation of an indexed access (brackets operator.)
+ */
+ @Immutable
+ public final class IndexNode extends BaseNode {
++ private static final long serialVersionUID = 1L;
++
+ /** Property index. */
+ private final Expression index;
+
+@@ -49,8 +51,8 @@
+ this.index = index;
+ }
+
+- private IndexNode(final IndexNode indexNode, final Expression base, final Expression index, final boolean isFunction) {
+- super(indexNode, base, isFunction);
++ private IndexNode(final IndexNode indexNode, final Expression base, final Expression index, final boolean isFunction, final Type type, final int programPoint) {
++ super(indexNode, base, isFunction, type, programPoint);
+ this.index = index;
+ }
+
+@@ -65,21 +67,25 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ final boolean needsParen = tokenType().needsParens(base.tokenType(), true);
+
+ if (needsParen) {
+ sb.append('(');
+ }
+
+- base.toString(sb);
++ if (printType) {
++ optimisticTypeToString(sb);
++ }
++
++ base.toString(sb, printType);
+
+ if (needsParen) {
+ sb.append(')');
+ }
+
+ sb.append('[');
+- index.toString(sb);
++ index.toString(sb, printType);
+ sb.append(']');
+ }
+
+@@ -95,7 +101,7 @@
+ if (this.base == base) {
+ return this;
+ }
+- return new IndexNode(this, base, index, isFunction());
++ return new IndexNode(this, base, index, isFunction(), type, programPoint);
+ }
+
+ /**
+@@ -103,19 +109,34 @@
+ * @param index new index expression
+ * @return a node equivalent to this one except for the requested change.
+ */
+- public IndexNode setIndex(Expression index) {
++ public IndexNode setIndex(final Expression index) {
+ if(this.index == index) {
+ return this;
+ }
+- return new IndexNode(this, base, index, isFunction());
++ return new IndexNode(this, base, index, isFunction(), type, programPoint);
+ }
+
+ @Override
+- public BaseNode setIsFunction() {
++ public IndexNode setType(final Type type) {
++ if (this.type == type) {
++ return this;
++ }
++ return new IndexNode(this, base, index, isFunction(), type, programPoint);
++ }
++
++ @Override
++ public IndexNode setIsFunction() {
+ if (isFunction()) {
+ return this;
+ }
+- return new IndexNode(this, base, index, true);
++ return new IndexNode(this, base, index, true, type, programPoint);
+ }
+
++ @Override
++ public IndexNode setProgramPoint(final int programPoint) {
++ if (this.programPoint == programPoint) {
++ return this;
++ }
++ return new IndexNode(this, base, index, isFunction(), type, programPoint);
++ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/ir/JoinPredecessor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.ir;
++
++/**
++ * Interface implemented by AST nodes that either can occur as predecessors of a control flow join, or contain a control
++ * flow join themselves. JoinPredecessor only provides a getter and setter for a {@link LocalVariableConversion}; the
++ * semantics of control flow for a particular node implementing the interface are shared between
++ * {@code LocalVariableTypesCalculator} that creates the conversions, and {@code CodeGenerator} that uses them.
++ */
++public interface JoinPredecessor {
++ /**
++ * Set the local variable conversions needed to unify their types at a control flow join point.
++ * @param lc the current lexical context
++ * @param conversion the conversions.
++ * @return this node or a different node representing the change.
++ */
++ public JoinPredecessor setLocalVariableConversion(LexicalContext lc, LocalVariableConversion conversion);
++
++ /**
++ * Returns the local variable conversions needed to unify their types at a control flow join point.
++ * @return the local variable conversions needed to unify their types at a control flow join point. Can be null.
++ * Can contain {@link LocalVariableConversion#isLive() dead conversions}.
++ */
++ public LocalVariableConversion getLocalVariableConversion();
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/ir/JoinPredecessorExpression.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,132 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.ir;
++
++import java.util.function.Function;
++import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++
++/**
++ * A wrapper for an expression that is in a position to be a join predecessor.
++ */
++public class JoinPredecessorExpression extends Expression implements JoinPredecessor {
++ private static final long serialVersionUID = 1L;
++
++ private final Expression expression;
++ private final LocalVariableConversion conversion;
++
++ /**
++ * A no-arg constructor does not wrap any expression on its own, but can be used as a place to contain a local
++ * variable conversion in a place where an expression can otherwise stand.
++ */
++ public JoinPredecessorExpression() {
++ this(null);
++ }
++
++ /**
++ * A constructor for wrapping an expression and making it a join predecessor. Typically used on true and false
++ * subexpressions of the ternary node as well as on the operands of short-circuiting logical expressions {@code &&}
++ * and {@code ||}.
++ * @param expression the expression to wrap
++ */
++ public JoinPredecessorExpression(final Expression expression) {
++ this(expression, null);
++ }
++
++ private JoinPredecessorExpression(final Expression expression, final LocalVariableConversion conversion) {
++ super(expression == null ? 0L : expression.getToken(), expression == null ? 0 : expression.getStart(), expression == null ? 0 : expression.getFinish());
++ this.expression = expression;
++ this.conversion = conversion;
++ }
++
++ @Override
++ public JoinPredecessor setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) {
++ if(conversion == this.conversion) {
++ return this;
++ }
++ return new JoinPredecessorExpression(expression, conversion);
++ }
++
++ @Override
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
++ return expression.getType(localVariableTypes);
++ }
++
++ @Override
++ public boolean isAlwaysFalse() {
++ return expression != null && expression.isAlwaysFalse();
++ }
++
++ @Override
++ public boolean isAlwaysTrue() {
++ return expression != null && expression.isAlwaysTrue();
++ }
++
++ /**
++ * Returns the underlying expression.
++ * @return the underlying expression.
++ */
++ public Expression getExpression() {
++ return expression;
++ }
++
++ /**
++ * Sets the underlying expression.
++ * @param expression the new underlying expression
++ * @return this or modified join predecessor expression object.
++ */
++ public JoinPredecessorExpression setExpression(final Expression expression) {
++ if(expression == this.expression) {
++ return this;
++ }
++ return new JoinPredecessorExpression(expression, conversion);
++ }
++
++ @Override
++ public LocalVariableConversion getLocalVariableConversion() {
++ return conversion;
++ }
++
++ @Override
++ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
++ if(visitor.enterJoinPredecessorExpression(this)) {
++ final Expression expr = getExpression();
++ return visitor.leaveJoinPredecessorExpression(expr == null ? this : setExpression((Expression)expr.accept(visitor)));
++ }
++ return this;
++ }
++
++ @Override
++ public void toString(final StringBuilder sb, final boolean printType) {
++ if(expression != null) {
++ expression.toString(sb, printType);
++ }
++ if(conversion != null) {
++ conversion.toString(sb);
++ }
++ }
++
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/ir/JumpStatement.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,120 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.ir;
++
++import jdk.nashorn.internal.codegen.Label;
++
++/**
++ * Common base class for jump statements (e.g. {@code break} and {@code continue}).
++ */
++public abstract class JumpStatement extends Statement implements JoinPredecessor {
++ private static final long serialVersionUID = 1L;
++
++ private final String labelName;
++ private final LocalVariableConversion conversion;
++
++ /**
++ * Constructor
++ *
++ * @param lineNumber line number
++ * @param token token
++ * @param finish finish
++ * @param labelName label name for break or null if none
++ */
++ protected JumpStatement(final int lineNumber, final long token, final int finish, final String labelName) {
++ super(lineNumber, token, finish);
++ this.labelName = labelName;
++ this.conversion = null;
++ }
++
++ /**
++ * Copy constructor.
++ * @param jumpStatement the original jump statement.
++ * @param conversion a new local variable conversion.
++ */
++ protected JumpStatement(final JumpStatement jumpStatement, final LocalVariableConversion conversion) {
++ super(jumpStatement);
++ this.labelName = jumpStatement.labelName;
++ this.conversion = conversion;
++ }
++
++ @Override
++ public boolean hasGoto() {
++ return true;
++ }
++
++ /**
++ * Get the label name for this break node
++ * @return label name, or null if none
++ */
++ public String getLabelName() {
++ return labelName;
++ }
++
++ @Override
++ public void toString(final StringBuilder sb, final boolean printType) {
++ sb.append(getStatementName());
++
++ if (labelName != null) {
++ sb.append(' ').append(labelName);
++ }
++ }
++
++ abstract String getStatementName();
++
++ /**
++ * Finds the target for this jump statement in a lexical context.
++ * @param lc the lexical context
++ * @return the target, or null if not found
++ */
++ public abstract BreakableNode getTarget(final LexicalContext lc);
++
++ /**
++ * Returns the label corresponding to this kind of jump statement (either a break or continue label) in the target.
++ * @param target the target. Note that it need not be the target of this jump statement, as the method can retrieve
++ * a label on any passed target as long as the target has a label of the requisite kind. Of course, it is advisable
++ * to invoke the method on a jump statement that targets the breakable.
++ * @return the label of the target corresponding to the kind of jump statement.
++ * @throws ClassCastException if invoked on the kind of breakable node that this jump statement is not prepared to
++ * handle.
++ */
++ public abstract Label getTargetLabel(final BreakableNode target);
++
++ @Override
++ public JumpStatement setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) {
++ if(this.conversion == conversion) {
++ return this;
++ }
++ return createNewJumpStatement(conversion);
++ }
++
++ abstract JumpStatement createNewJumpStatement(LocalVariableConversion newConversion);
++
++ @Override
++ public LocalVariableConversion getLocalVariableConversion() {
++ return conversion;
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/ir/LabelNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/LabelNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,36 +29,44 @@
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+
+ /**
+- * IR representation for a labeled statement.
++ * IR representation for a labeled statement. It implements JoinPredecessor to hold conversions that need to be effected
++ * when the block exits normally, but is also targeted by a break statement that might bring different local variable
++ * types to the join at the break point.
+ */
+ @Immutable
+-public final class LabelNode extends LexicalContextStatement {
++public final class LabelNode extends LexicalContextStatement implements JoinPredecessor {
++ private static final long serialVersionUID = 1L;
++
+ /** Label ident. */
+- private final IdentNode label;
++ private final String labelName;
+
+ /** Statements. */
+ private final Block body;
+
++ private final LocalVariableConversion localVariableConversion;
++
+ /**
+ * Constructor
+ *
+ * @param lineNumber line number
+ * @param token token
+ * @param finish finish
+- * @param label label identifier
++ * @param labelName label name
+ * @param body body of label node
+ */
+- public LabelNode(final int lineNumber, final long token, final int finish, final IdentNode label, final Block body) {
++ public LabelNode(final int lineNumber, final long token, final int finish, final String labelName, final Block body) {
+ super(lineNumber, token, finish);
+
+- this.label = label;
++ this.labelName = labelName;
+ this.body = body;
++ this.localVariableConversion = null;
+ }
+
+- private LabelNode(final LabelNode labelNode, final IdentNode label, final Block body) {
++ private LabelNode(final LabelNode labelNode, final String labelName, final Block body, final LocalVariableConversion localVariableConversion) {
+ super(labelNode);
+- this.label = label;
+- this.body = body;
++ this.labelName = labelName;
++ this.body = body;
++ this.localVariableConversion = localVariableConversion;
+ }
+
+ @Override
+@@ -69,18 +77,15 @@
+ @Override
+ public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
+ if (visitor.enterLabelNode(this)) {
+- return visitor.leaveLabelNode(
+- setLabel(lc, (IdentNode)label.accept(visitor)).
+- setBody(lc, (Block)body.accept(visitor)));
++ return visitor.leaveLabelNode(setBody(lc, (Block)body.accept(visitor)));
+ }
+
+ return this;
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
+- label.toString(sb);
+- sb.append(':');
++ public void toString(final StringBuilder sb, final boolean printType) {
++ sb.append(labelName).append(':');
+ }
+
+ /**
+@@ -101,22 +106,27 @@
+ if (this.body == body) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new LabelNode(this, label, body));
++ return Node.replaceInLexicalContext(lc, this, new LabelNode(this, labelName, body, localVariableConversion));
+ }
+
+ /**
+- * Get the identifier representing the label name
++ * Get the label name
+ * @return the label
+ */
+- public IdentNode getLabel() {
+- return label;
++ public String getLabelName() {
++ return labelName;
+ }
+
+- private LabelNode setLabel(final LexicalContext lc, final IdentNode label) {
+- if (this.label == label) {
++ @Override
++ public LocalVariableConversion getLocalVariableConversion() {
++ return localVariableConversion;
++ }
++
++ @Override
++ public LabelNode setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion localVariableConversion) {
++ if(this.localVariableConversion == localVariableConversion) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new LabelNode(this, label, body));
++ return Node.replaceInLexicalContext(lc, this, new LabelNode(this, labelName, body, localVariableConversion));
+ }
+-
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/ir/Labels.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.ir;
++
++import java.util.List;
++import jdk.nashorn.internal.codegen.Label;
++
++/**
++ * Interface that can be used to get a list of all labels in a node
++ */
++public interface Labels {
++
++ /**
++ * Return the labels associated with this node. Breakable nodes that
++ * aren't LoopNodes only have a break label - the location immediately
++ * afterwards the node in code
++ * @return list of labels representing locations around this node
++ */
++ public List<Label> getLabels();
++}
+--- ./nashorn/src/jdk/nashorn/internal/ir/LexicalContext.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/LexicalContext.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,7 +27,6 @@
+ import java.io.File;
+ import java.util.Iterator;
+ import java.util.NoSuchElementException;
+-import jdk.nashorn.internal.codegen.Label;
+ import jdk.nashorn.internal.runtime.Debug;
+ import jdk.nashorn.internal.runtime.Source;
+
+@@ -148,6 +147,7 @@
+ * @return the node that was pushed
+ */
+ public <T extends LexicalContextNode> T push(final T node) {
++ assert !contains(node);
+ if (sp == stack.length) {
+ final LexicalContextNode[] newStack = new LexicalContextNode[sp * 2];
+ System.arraycopy(stack, 0, newStack, 0, sp);
+@@ -201,6 +201,18 @@
+ return (T)popped;
+ }
+
++ /**
++ * Explicitly apply flags to the topmost element on the stack. This is only valid to use from a
++ * {@code NodeVisitor.leaveXxx()} method and only on the node being exited at the time. It is not mandatory to use,
++ * as {@link #pop(LexicalContextNode)} will apply the flags automatically, but this method can be used to apply them
++ * during the {@code leaveXxx()} method in case its logic depends on the value of the flags.
++ * @param node the node to apply the flags to. Must be the topmost node on the stack.
++ * @return the passed in node, or a modified node (if any flags were modified)
++ */
++ public <T extends LexicalContextNode & Flags<T>> T applyTopFlags(final T node) {
++ assert node == peek();
++ return node.setFlag(this, flags[sp - 1]);
++ }
+
+ /**
+ * Return the top element in the context
+@@ -233,10 +245,9 @@
+ * @return the new node
+ */
+ public LexicalContextNode replace(final LexicalContextNode oldNode, final LexicalContextNode newNode) {
+- //System.err.println("REPLACE old=" + Debug.id(oldNode) + " new=" + Debug.id(newNode));
+ for (int i = sp - 1; i >= 0; i--) {
+ if (stack[i] == oldNode) {
+- assert i == (sp - 1) : "violation of contract - we always expect to find the replacement node on top of the lexical context stack: " + newNode + " has " + stack[i + 1].getClass() + " above it";
++ assert i == sp - 1 : "violation of contract - we always expect to find the replacement node on top of the lexical context stack: " + newNode + " has " + stack[i + 1].getClass() + " above it";
+ stack[i] = newNode;
+ break;
+ }
+@@ -271,6 +282,31 @@
+ }
+
+ /**
++ * Gets the label node of the current block.
++ * @return the label node of the current block, if it is labeled. Otherwise returns null.
++ */
++ public LabelNode getCurrentBlockLabelNode() {
++ assert stack[sp - 1] instanceof Block;
++ if(sp < 2) {
++ return null;
++ }
++ final LexicalContextNode parent = stack[sp - 2];
++ return parent instanceof LabelNode ? (LabelNode)parent : null;
++ }
++
++
++ /*
++ public FunctionNode getProgram() {
++ final Iterator<FunctionNode> iter = getFunctions();
++ FunctionNode last = null;
++ while (iter.hasNext()) {
++ last = iter.next();
++ }
++ assert last != null;
++ return last;
++ }*/
++
++ /**
+ * Returns an iterator over all ancestors block of the given block, with its parent block first.
+ * @param block the block whose ancestors are returned
+ * @return an iterator over all ancestors block of the given block.
+@@ -315,8 +351,7 @@
+ }
+
+ /**
+- * Get the function for this block. If the block is itself a function
+- * this returns identity
++ * Get the function for this block.
+ * @param block block for which to get function
+ * @return function for block
+ */
+@@ -364,9 +399,6 @@
+ * @return block in which the symbol is defined, assert if no such block in context
+ */
+ public Block getDefiningBlock(final Symbol symbol) {
+- if (symbol.isTemp()) {
+- return null;
+- }
+ final String name = symbol.getName();
+ for (final Iterator<Block> it = getBlocks(); it.hasNext();) {
+ final Block next = it.next();
+@@ -382,10 +414,7 @@
+ * @param symbol symbol
+ * @return function node in which this symbol is defined, assert if no such symbol exists in context
+ */
+- public FunctionNode getDefiningFunction(Symbol symbol) {
+- if (symbol.isTemp()) {
+- return null;
+- }
++ public FunctionNode getDefiningFunction(final Symbol symbol) {
+ final String name = symbol.getName();
+ for (final Iterator<LexicalContextNode> iter = new NodeIterator<>(LexicalContextNode.class); iter.hasNext();) {
+ final LexicalContextNode next = iter.next();
+@@ -393,7 +422,7 @@
+ while (iter.hasNext()) {
+ final LexicalContextNode next2 = iter.next();
+ if (next2 instanceof FunctionNode) {
+- return ((FunctionNode)next2);
++ return (FunctionNode)next2;
+ }
+ }
+ throw new AssertionError("Defining block for symbol " + name + " has no function in the context");
+@@ -411,19 +440,11 @@
+ }
+
+ /**
+- * Returns true if the expression defining the function is a callee of a CallNode that should be the second
+- * element on the stack, e.g. <code>(function(){})()</code>. That is, if the stack ends with
+- * {@code [..., CallNode, FunctionNode]} then {@code callNode.getFunction()} should be equal to
+- * {@code functionNode}, and the top of the stack should itself be a variant of {@code functionNode}.
+- * @param functionNode the function node being tested
+- * @return true if the expression defining the current function is a callee of a call expression.
++ * Is the topmost lexical context element body of a SplitNode?
++ * @return true if it's the body of a split node.
+ */
+- public boolean isFunctionDefinedInCurrentCall(FunctionNode functionNode) {
+- final LexicalContextNode parent = stack[sp - 2];
+- if (parent instanceof CallNode && ((CallNode)parent).getFunction() == functionNode) {
+- return true;
+- }
+- return false;
++ public boolean isSplitBody() {
++ return sp >= 2 && stack[sp - 1] instanceof Block && stack[sp - 2] instanceof SplitNode;
+ }
+
+ /**
+@@ -444,15 +465,26 @@
+ }
+
+ /**
+- * Count the number of with scopes until a given node
+- * @param until node to stop counting at, or null if all nodes should be counted
++ * Count the number of scopes until a given node. Note that this method is solely used to figure out the number of
++ * scopes that need to be explicitly popped in order to perform a break or continue jump within the current bytecode
++ * method. For this reason, the method returns 0 if it encounters a {@code SplitNode} between the current location
++ * and the break/continue target.
++ * @param until node to stop counting at. Must be within the current function
+ * @return number of with scopes encountered in the context
+ */
+ public int getScopeNestingLevelTo(final LexicalContextNode until) {
++ assert until != null;
+ //count the number of with nodes until "until" is hit
+ int n = 0;
+- for (final Iterator<WithNode> iter = new NodeIterator<>(WithNode.class, until); iter.hasNext(); iter.next()) {
+- n++;
++ for (final Iterator<LexicalContextNode> iter = getAllNodes(); iter.hasNext();) {
++ final LexicalContextNode node = iter.next();
++ if (node == until) {
++ break;
++ }
++ assert !(node instanceof FunctionNode); // Can't go outside current function
++ if (node instanceof WithNode || node instanceof Block && ((Block)node).needsScope()) {
++ n++;
++ }
+ }
+ return n;
+ }
+@@ -486,12 +518,13 @@
+
+ /**
+ * Find the breakable node corresponding to this label.
+- * @param label label to search for, if null the closest breakable node will be returned unconditionally, e.g. a while loop with no label
++ * @param labelName name of the label to search for. If null, the closest breakable node will be returned
++ * unconditionally, e.g. a while loop with no label
+ * @return closest breakable node
+ */
+- public BreakableNode getBreakable(final IdentNode label) {
+- if (label != null) {
+- final LabelNode foundLabel = findLabel(label.getName());
++ public BreakableNode getBreakable(final String labelName) {
++ if (labelName != null) {
++ final LabelNode foundLabel = findLabel(labelName);
+ if (foundLabel != null) {
+ // iterate to the nearest breakable to the foundLabel
+ BreakableNode breakable = null;
+@@ -511,12 +544,13 @@
+
+ /**
+ * Find the continue target node corresponding to this label.
+- * @param label label to search for, if null the closest loop node will be returned unconditionally, e.g. a while loop with no label
++ * @param labelName label name to search for. If null the closest loop node will be returned unconditionally, e.g. a
++ * while loop with no label
+ * @return closest continue target node
+ */
+- public LoopNode getContinueTo(final IdentNode label) {
+- if (label != null) {
+- final LabelNode foundLabel = findLabel(label.getName());
++ public LoopNode getContinueTo(final String labelName) {
++ if (labelName != null) {
++ final LabelNode foundLabel = findLabel(labelName);
+ if (foundLabel != null) {
+ // iterate to the nearest loop to the foundLabel
+ LoopNode loop = null;
+@@ -538,7 +572,7 @@
+ public LabelNode findLabel(final String name) {
+ for (final Iterator<LabelNode> iter = new NodeIterator<>(LabelNode.class, getCurrentFunction()); iter.hasNext(); ) {
+ final LabelNode next = iter.next();
+- if (next.getLabel().getName().equals(name)) {
++ if (next.getLabelName().equals(name)) {
+ return next;
+ }
+ }
+@@ -546,30 +580,34 @@
+ }
+
+ /**
+- * Checks whether a given label is a jump destination that lies outside a given
+- * split node
++ * Checks whether a given target is a jump destination that lies outside a given split node
+ * @param splitNode the split node
+- * @param label the label
+- * @return true if label resides outside the split node
++ * @param target the target node
++ * @return true if target resides outside the split node
+ */
+- public boolean isExternalTarget(final SplitNode splitNode, final Label label) {
+- boolean targetFound = false;
+- for (int i = sp - 1; i >= 0; i--) {
++ public boolean isExternalTarget(final SplitNode splitNode, final BreakableNode target) {
++ for (int i = sp; i-- > 0;) {
+ final LexicalContextNode next = stack[i];
+ if (next == splitNode) {
+- return !targetFound;
+- }
+-
+- if (next instanceof BreakableNode) {
+- for (final Label l : ((BreakableNode)next).getLabels()) {
+- if (l == label) {
+- targetFound = true;
+- break;
+- }
+- }
++ return true;
++ } else if (next == target) {
++ return false;
+ }
+ }
+- assert false : label + " was expected in lexical context " + LexicalContext.this + " but wasn't";
++ throw new AssertionError(target + " was expected in lexical context " + LexicalContext.this + " but wasn't");
++ }
++
++ /**
++ * Checks whether the current context is inside a switch statement without explicit blocks (curly braces).
++ * @return true if in unprotected switch statement
++ */
++ public boolean inUnprotectedSwitchContext() {
++ for (int i = sp; i > 0; i--) {
++ final LexicalContextNode next = stack[i];
++ if (next instanceof Block) {
++ return stack[i - 1] instanceof SwitchNode;
++ }
++ }
+ return false;
+ }
+
+@@ -627,11 +665,12 @@
+ if (next == null) {
+ throw new NoSuchElementException();
+ }
+- T lnext = next;
++ final T lnext = next;
+ next = findNext();
+ return lnext;
+ }
+
++ @SuppressWarnings("unchecked")
+ private T findNext() {
+ for (int i = index; i >= 0; i--) {
+ final Object node = stack[i];
+@@ -640,7 +679,7 @@
+ }
+ if (clazz.isAssignableFrom(node.getClass())) {
+ index = i - 1;
+- return clazz.cast(node);
++ return (T)node;
+ }
+ }
+ return null;
+--- ./nashorn/src/jdk/nashorn/internal/ir/LexicalContextExpression.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/LexicalContextExpression.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,16 +28,17 @@
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+
+ abstract class LexicalContextExpression extends Expression implements LexicalContextNode {
++ private static final long serialVersionUID = 1L;
+
+- LexicalContextExpression(LexicalContextExpression expr) {
++ LexicalContextExpression(final LexicalContextExpression expr) {
+ super(expr);
+ }
+
+- LexicalContextExpression(long token, int start, int finish) {
++ LexicalContextExpression(final long token, final int start, final int finish) {
+ super(token, start, finish);
+ }
+
+- LexicalContextExpression(long token, int finish) {
++ LexicalContextExpression(final long token, final int finish) {
+ super(token, finish);
+ }
+
+@@ -45,15 +46,4 @@
+ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
+ return Acceptor.accept(this, visitor);
+ }
+-
+- /**
+- * Set the symbol and replace in lexical context if applicable
+- * @param lc lexical context
+- * @param symbol symbol
+- * @return new node if symbol changed
+- */
+- @Override
+- public Expression setSymbol(final LexicalContext lc, final Symbol symbol) {
+- return Node.replaceInLexicalContext(lc, this, (LexicalContextExpression)super.setSymbol(null, symbol));
+- }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/LexicalContextStatement.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/LexicalContextStatement.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,6 +28,8 @@
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+
+ abstract class LexicalContextStatement extends Statement implements LexicalContextNode {
++ private static final long serialVersionUID = 1L;
++
+ /**
+ * Constructor
+ *
+--- ./nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,10 +25,11 @@
+
+ package jdk.nashorn.internal.ir;
+
++import java.io.Serializable;
+ import java.util.Arrays;
+ import java.util.Collections;
+ import java.util.List;
+-
++import java.util.function.Function;
+ import jdk.nashorn.internal.codegen.CompileUnit;
+ import jdk.nashorn.internal.codegen.types.ArrayType;
+ import jdk.nashorn.internal.codegen.types.Type;
+@@ -49,6 +50,8 @@
+ */
+ @Immutable
+ public abstract class LiteralNode<T> extends Expression implements PropertyKey {
++ private static final long serialVersionUID = 1L;
++
+ /** Literal value */
+ protected final T value;
+
+@@ -86,9 +89,15 @@
+ this.value = newValue;
+ }
+
+- @Override
+- public boolean isAtom() {
+- return true;
++ /**
++ * Initialization setter, if required for immutable state. This is used for
++ * things like ArrayLiteralNodes that need to carry state for the splitter.
++ * Default implementation is just a nop.
++ * @param lc lexical context
++ * @return new literal node with initialized state, or same if nothing changed
++ */
++ public LiteralNode<?> initialize(final LexicalContext lc) {
++ return this;
+ }
+
+ /**
+@@ -100,7 +109,7 @@
+ }
+
+ @Override
+- public Type getType() {
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
+ return Type.typeFor(value.getClass());
+ }
+
+@@ -215,7 +224,7 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ if (value == null) {
+ sb.append("null");
+ } else {
+@@ -227,10 +236,14 @@
+ * Get the literal node value
+ * @return the value
+ */
+- public T getValue() {
++ public final T getValue() {
+ return value;
+ }
+
++ private static Expression[] valueToArray(final List<Expression> value) {
++ return value.toArray(new Expression[value.size()]);
++ }
++
+ /**
+ * Create a new null literal
+ *
+@@ -260,6 +273,8 @@
+ * @param <T> the literal type
+ */
+ public static class PrimitiveLiteralNode<T> extends LiteralNode<T> {
++ private static final long serialVersionUID = 1L;
++
+ private PrimitiveLiteralNode(final long token, final int finish, final T value) {
+ super(token, finish, value);
+ }
+@@ -280,10 +295,21 @@
+ public boolean isLocal() {
+ return true;
+ }
++
++ @Override
++ public boolean isAlwaysFalse() {
++ return !isTrue();
++ }
++
++ @Override
++ public boolean isAlwaysTrue() {
++ return isTrue();
++ }
+ }
+
+ @Immutable
+ private static final class BooleanLiteralNode extends PrimitiveLiteralNode<Boolean> {
++ private static final long serialVersionUID = 1L;
+
+ private BooleanLiteralNode(final long token, final int finish, final boolean value) {
+ super(Token.recast(token, value ? TokenType.TRUE : TokenType.FALSE), finish, value);
+@@ -299,7 +325,7 @@
+ }
+
+ @Override
+- public Type getType() {
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
+ return Type.BOOLEAN;
+ }
+
+@@ -336,6 +362,7 @@
+
+ @Immutable
+ private static final class NumberLiteralNode extends PrimitiveLiteralNode<Number> {
++ private static final long serialVersionUID = 1L;
+
+ private final Type type = numberGetType(value);
+
+@@ -362,7 +389,7 @@
+ }
+
+ @Override
+- public Type getType() {
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
+ return type;
+ }
+
+@@ -398,6 +425,8 @@
+ }
+
+ private static class UndefinedLiteralNode extends PrimitiveLiteralNode<Undefined> {
++ private static final long serialVersionUID = 1L;
++
+ private UndefinedLiteralNode(final long token, final int finish) {
+ super(Token.recast(token, TokenType.OBJECT), finish, ScriptRuntime.UNDEFINED);
+ }
+@@ -434,6 +463,8 @@
+
+ @Immutable
+ private static class StringLiteralNode extends PrimitiveLiteralNode<String> {
++ private static final long serialVersionUID = 1L;
++
+ private StringLiteralNode(final long token, final int finish, final String value) {
+ super(Token.recast(token, TokenType.STRING), finish, value);
+ }
+@@ -443,7 +474,7 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ sb.append('\"');
+ sb.append(value);
+ sb.append('\"');
+@@ -477,6 +508,8 @@
+
+ @Immutable
+ private static class LexerTokenLiteralNode extends LiteralNode<LexerToken> {
++ private static final long serialVersionUID = 1L;
++
+ private LexerTokenLiteralNode(final long token, final int finish, final LexerToken value) {
+ super(Token.recast(token, TokenType.STRING), finish, value); //TODO is string the correct token type here?
+ }
+@@ -486,12 +519,12 @@
+ }
+
+ @Override
+- public Type getType() {
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
+ return Type.OBJECT;
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ sb.append(value.toString());
+ }
+ }
+@@ -540,6 +573,7 @@
+ }
+
+ private static final class NullLiteralNode extends PrimitiveLiteralNode<Object> {
++ private static final long serialVersionUID = 1L;
+
+ private NullLiteralNode(final long token, final int finish) {
+ super(Token.recast(token, TokenType.OBJECT), finish, null);
+@@ -555,7 +589,7 @@
+ }
+
+ @Override
+- public Type getType() {
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
+ return Type.OBJECT;
+ }
+
+@@ -568,24 +602,29 @@
+ /**
+ * Array literal node class.
+ */
+- public static final class ArrayLiteralNode extends LiteralNode<Expression[]> {
++ @Immutable
++ public static final class ArrayLiteralNode extends LiteralNode<Expression[]> implements LexicalContextNode {
++ private static final long serialVersionUID = 1L;
+
+ /** Array element type. */
+- private Type elementType;
++ private final Type elementType;
+
+ /** Preset constant array. */
+- private Object presets;
++ private final Object presets;
+
+ /** Indices of array elements requiring computed post sets. */
+- private int[] postsets;
++ private final int[] postsets;
+
+- private List<ArrayUnit> units;
++ /** Sub units with indexes ranges, in which to split up code generation, for large literals */
++ private final List<ArrayUnit> units;
+
+ /**
+ * An ArrayUnit is a range in an ArrayLiteral. ArrayLiterals can
+ * be split if they are too large, for bytecode generation reasons
+ */
+- public static class ArrayUnit {
++ public static final class ArrayUnit implements CompileUnitHolder, Serializable {
++ private static final long serialVersionUID = 1L;
++
+ /** Compile unit associated with the postsets range. */
+ private final CompileUnit compileUnit;
+
+@@ -624,11 +663,156 @@
+ * The array compile unit
+ * @return array compile unit
+ */
++ @Override
+ public CompileUnit getCompileUnit() {
+ return compileUnit;
+ }
+ }
+
++ private static final class ArrayLiteralInitializer {
++
++ static ArrayLiteralNode initialize(final ArrayLiteralNode node) {
++ final Type elementType = computeElementType(node.value);
++ final int[] postsets = computePostsets(node.value);
++ final Object presets = computePresets(node.value, elementType, postsets);
++ return new ArrayLiteralNode(node, node.value, elementType, postsets, presets, node.units);
++ }
++
++ private static Type computeElementType(final Expression[] value) {
++ Type widestElementType = Type.INT;
++
++ for (final Expression elem : value) {
++ if (elem == null) {
++ widestElementType = widestElementType.widest(Type.OBJECT); //no way to represent undefined as number
++ break;
++ }
++
++ final Type type = elem.getType().isUnknown() ? Type.OBJECT : elem.getType();
++ if (type.isBoolean()) {
++ //TODO fix this with explicit boolean types
++ widestElementType = widestElementType.widest(Type.OBJECT);
++ break;
++ }
++
++ widestElementType = widestElementType.widest(type);
++ if (widestElementType.isObject()) {
++ break;
++ }
++ }
++ return widestElementType;
++ }
++
++ private static int[] computePostsets(final Expression[] value) {
++ final int[] computed = new int[value.length];
++ int nComputed = 0;
++
++ for (int i = 0; i < value.length; i++) {
++ final Expression element = value[i];
++ if (element == null || objectAsConstant(element) == POSTSET_MARKER) {
++ computed[nComputed++] = i;
++ }
++ }
++ return Arrays.copyOf(computed, nComputed);
++ }
++
++ private static boolean setArrayElement(final int[] array, final int i, final Object n) {
++ if (n instanceof Number) {
++ array[i] = ((Number)n).intValue();
++ return true;
++ }
++ return false;
++ }
++
++ private static boolean setArrayElement(final long[] array, final int i, final Object n) {
++ if (n instanceof Number) {
++ array[i] = ((Number)n).longValue();
++ return true;
++ }
++ return false;
++ }
++
++ private static boolean setArrayElement(final double[] array, final int i, final Object n) {
++ if (n instanceof Number) {
++ array[i] = ((Number)n).doubleValue();
++ return true;
++ }
++ return false;
++ }
++
++ private static int[] presetIntArray(final Expression[] value, final int[] postsets) {
++ final int[] array = new int[value.length];
++ int nComputed = 0;
++ for (int i = 0; i < value.length; i++) {
++ if (!setArrayElement(array, i, objectAsConstant(value[i]))) {
++ assert postsets[nComputed++] == i;
++ }
++ }
++ assert postsets.length == nComputed;
++ return array;
++ }
++
++ private static long[] presetLongArray(final Expression[] value, final int[] postsets) {
++ final long[] array = new long[value.length];
++ int nComputed = 0;
++ for (int i = 0; i < value.length; i++) {
++ if (!setArrayElement(array, i, objectAsConstant(value[i]))) {
++ assert postsets[nComputed++] == i;
++ }
++ }
++ assert postsets.length == nComputed;
++ return array;
++ }
++
++ private static double[] presetDoubleArray(final Expression[] value, final int[] postsets) {
++ final double[] array = new double[value.length];
++ int nComputed = 0;
++ for (int i = 0; i < value.length; i++) {
++ if (!setArrayElement(array, i, objectAsConstant(value[i]))) {
++ assert postsets[nComputed++] == i;
++ }
++ }
++ assert postsets.length == nComputed;
++ return array;
++ }
++
++ private static Object[] presetObjectArray(final Expression[] value, final int[] postsets) {
++ final Object[] array = new Object[value.length];
++ int nComputed = 0;
++
++ for (int i = 0; i < value.length; i++) {
++ final Node node = value[i];
++
++ if (node == null) {
++ assert postsets[nComputed++] == i;
++ continue;
++ }
++ final Object element = objectAsConstant(node);
++
++ if (element != POSTSET_MARKER) {
++ array[i] = element;
++ } else {
++ assert postsets[nComputed++] == i;
++ }
++ }
++
++ assert postsets.length == nComputed;
++ return array;
++ }
++
++ static Object computePresets(final Expression[] value, final Type elementType, final int[] postsets) {
++ assert !elementType.isUnknown();
++ if (elementType.isInteger()) {
++ return presetIntArray(value, postsets);
++ } else if (elementType.isLong()) {
++ return presetLongArray(value, postsets);
++ } else if (elementType.isNumeric()) {
++ return presetDoubleArray(value, postsets);
++ } else {
++ return presetObjectArray(value, postsets);
++ }
++ }
++ }
++
+ /**
+ * Constructor
+ *
+@@ -639,144 +823,21 @@
+ protected ArrayLiteralNode(final long token, final int finish, final Expression[] value) {
+ super(Token.recast(token, TokenType.ARRAY), finish, value);
+ this.elementType = Type.UNKNOWN;
++ this.presets = null;
++ this.postsets = null;
++ this.units = null;
+ }
+
+ /**
+ * Copy constructor
+ * @param node source array literal node
+ */
+- private ArrayLiteralNode(final ArrayLiteralNode node, final Expression[] value) {
++ private ArrayLiteralNode(final ArrayLiteralNode node, final Expression[] value, final Type elementType, final int[] postsets, final Object presets, final List<ArrayUnit> units) {
+ super(node, value);
+- this.elementType = node.elementType;
+- this.presets = node.presets;
+- this.postsets = node.postsets;
+- this.units = node.units;
+- }
+-
+- /**
+- * Compute things like widest element type needed. Internal use from compiler only
+- */
+- public void analyze() {
+- elementType = Type.INT;
+- analyzeElements();
+-
+- if (elementType.isInteger()) {
+- presetIntArray();
+- } else if (elementType.isLong()) {
+- presetLongArray();
+- } else if (elementType.isNumeric()) {
+- presetNumberArray();
+- } else {
+- presetObjectArray();
+- }
+- }
+-
+- private void presetIntArray() {
+- final int[] array = new int[value.length];
+- final int[] computed = new int[value.length];
+- int nComputed = 0;
+-
+- for (int i = 0; i < value.length; i++) {
+- final Object element = objectAsConstant(value[i]);
+-
+- if (element instanceof Number) {
+- array[i] = ((Number)element).intValue();
+- } else {
+- computed[nComputed++] = i;
+- }
+- }
+-
+- presets = array;
+- postsets = Arrays.copyOf(computed, nComputed);
+- }
+-
+- private void presetLongArray() {
+- final long[] array = new long[value.length];
+- final int[] computed = new int[value.length];
+- int nComputed = 0;
+-
+- for (int i = 0; i < value.length; i++) {
+- final Object element = objectAsConstant(value[i]);
+-
+- if (element instanceof Number) {
+- array[i] = ((Number)element).longValue();
+- } else {
+- computed[nComputed++] = i;
+- }
+- }
+-
+- presets = array;
+- postsets = Arrays.copyOf(computed, nComputed);
+- }
+-
+- private void presetNumberArray() {
+- final double[] array = new double[value.length];
+- final int[] computed = new int[value.length];
+- int nComputed = 0;
+-
+- for (int i = 0; i < value.length; i++) {
+- final Object element = objectAsConstant(value[i]);
+-
+- if (element instanceof Number) {
+- array[i] = ((Number)element).doubleValue();
+- } else {
+- computed[nComputed++] = i;
+- }
+- }
+-
+- presets = array;
+- postsets = Arrays.copyOf(computed, nComputed);
+- }
+-
+- private void presetObjectArray() {
+- final Object[] array = new Object[value.length];
+- final int[] computed = new int[value.length];
+- int nComputed = 0;
+-
+- for (int i = 0; i < value.length; i++) {
+- final Node node = value[i];
+-
+- if (node == null) {
+- computed[nComputed++] = i;
+- } else {
+- final Object element = objectAsConstant(node);
+-
+- if (element != POSTSET_MARKER) {
+- array[i] = element;
+- } else {
+- computed[nComputed++] = i;
+- }
+- }
+- }
+-
+- presets = array;
+- postsets = Arrays.copyOf(computed, nComputed);
+- }
+-
+- private void analyzeElements() {
+- for (final Expression node : value) {
+- if (node == null) {
+- elementType = elementType.widest(Type.OBJECT); //no way to represent undefined as number
+- break;
+- }
+-
+- assert node.getSymbol() != null; //don't run this on unresolved nodes or you are in trouble
+- Type symbolType = node.getSymbol().getSymbolType();
+- if (symbolType.isUnknown()) {
+- symbolType = Type.OBJECT;
+- }
+-
+- if (symbolType.isBoolean()) {
+- elementType = elementType.widest(Type.OBJECT);
+- break;
+- }
+-
+- elementType = elementType.widest(symbolType);
+-
+- if (elementType.isObject()) {
+- break;
+- }
+- }
++ this.elementType = elementType;
++ this.postsets = postsets;
++ this.presets = presets;
++ this.units = units;
+ }
+
+ @Override
+@@ -785,10 +846,27 @@
+ }
+
+ /**
++ * Setter that initializes all code generation meta data for an
++ * ArrayLiteralNode. This acts a setter, so the return value may
++ * return a new node and must be handled
++ *
++ * @param lc lexical context
++ * @return new array literal node with postsets, presets and element types initialized
++ */
++ @Override
++ public ArrayLiteralNode initialize(final LexicalContext lc) {
++ return Node.replaceInLexicalContext(lc, this, ArrayLiteralInitializer.initialize(this));
++ }
++
++ /**
+ * Get the array element type as Java format, e.g. [I
+ * @return array element type
+ */
+ public ArrayType getArrayType() {
++ return getArrayType(getElementType());
++ }
++
++ private static ArrayType getArrayType(final Type elementType) {
+ if (elementType.isInteger()) {
+ return Type.INT_ARRAY;
+ } else if (elementType.isLong()) {
+@@ -801,7 +879,7 @@
+ }
+
+ @Override
+- public Type getType() {
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
+ return Type.typeFor(NativeArray.class);
+ }
+
+@@ -810,6 +888,7 @@
+ * @return element type
+ */
+ public Type getElementType() {
++ assert !elementType.isUnknown() : this + " has elementType=unknown";
+ return elementType;
+ }
+
+@@ -819,14 +898,28 @@
+ * @return post set indices
+ */
+ public int[] getPostsets() {
++ assert postsets != null : this + " elementType=" + elementType + " has no postsets";
+ return postsets;
+ }
+
++ private boolean presetsMatchElementType() {
++ if (elementType == Type.INT) {
++ return presets instanceof int[];
++ } else if (elementType == Type.LONG) {
++ return presets instanceof long[];
++ } else if (elementType == Type.NUMBER) {
++ return presets instanceof double[];
++ } else {
++ return presets instanceof Object[];
++ }
++ }
++
+ /**
+ * Get presets constant array
+ * @return presets array, always returns an array type
+ */
+ public Object getPresets() {
++ assert presets != null && presetsMatchElementType() : this + " doesn't have presets, or invalid preset type: " + presets;
+ return presets;
+ }
+
+@@ -841,29 +934,46 @@
+
+ /**
+ * Set the ArrayUnits that make up this ArrayLiteral
++ * @param lc lexical context
+ * @see ArrayUnit
+ * @param units list of array units
++ * @return new or changed arrayliteralnode
+ */
+- public void setUnits(final List<ArrayUnit> units) {
+- this.units = units;
++ public ArrayLiteralNode setUnits(final LexicalContext lc, final List<ArrayUnit> units) {
++ if (this.units == units) {
++ return this;
++ }
++ return Node.replaceInLexicalContext(lc, this, new ArrayLiteralNode(this, value, elementType, postsets, presets, units));
+ }
+
+ @Override
+ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
++ return Acceptor.accept(this, visitor);
++ }
++
++ @Override
++ public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
+ if (visitor.enterLiteralNode(this)) {
+ final List<Expression> oldValue = Arrays.asList(value);
+- final List<Expression> newValue = Node.accept(visitor, Expression.class, oldValue);
+- return visitor.leaveLiteralNode(oldValue != newValue ? setValue(newValue) : this);
++ final List<Expression> newValue = Node.accept(visitor, oldValue);
++ return visitor.leaveLiteralNode(oldValue != newValue ? setValue(lc, newValue) : this);
+ }
+ return this;
+ }
+
+- private ArrayLiteralNode setValue(final List<Expression> value) {
+- return new ArrayLiteralNode(this, value.toArray(new Expression[value.size()]));
++ private ArrayLiteralNode setValue(final LexicalContext lc, final Expression[] value) {
++ if (this.value == value) {
++ return this;
++ }
++ return Node.replaceInLexicalContext(lc, this, new ArrayLiteralNode(this, value, elementType, postsets, presets, units));
++ }
++
++ private ArrayLiteralNode setValue(final LexicalContext lc, final List<Expression> value) {
++ return setValue(lc, value.toArray(new Expression[value.size()]));
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ sb.append('[');
+ boolean first = true;
+ for (final Node node : value) {
+@@ -874,7 +984,7 @@
+ if (node == null) {
+ sb.append("undefined");
+ } else {
+- node.toString(sb);
++ node.toString(sb, printType);
+ }
+ first = false;
+ }
+@@ -892,10 +1002,9 @@
+ * @return the new literal node
+ */
+ public static LiteralNode<Expression[]> newInstance(final long token, final int finish, final List<Expression> value) {
+- return new ArrayLiteralNode(token, finish, value.toArray(new Expression[value.size()]));
++ return new ArrayLiteralNode(token, finish, valueToArray(value));
+ }
+
+-
+ /**
+ * Create a new array literal based on a parent node (source, token, finish)
+ *
+@@ -905,7 +1014,7 @@
+ * @return the new literal node
+ */
+ public static LiteralNode<?> newInstance(final Node parent, final List<Expression> value) {
+- return new ArrayLiteralNode(parent.getToken(), parent.getFinish(), value.toArray(new Expression[value.size()]));
++ return new ArrayLiteralNode(parent.getToken(), parent.getFinish(), valueToArray(value));
+ }
+
+ /**
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/ir/LocalVariableConversion.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,174 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.ir;
++
++import jdk.nashorn.internal.codegen.types.Type;
++
++/**
++ * Class describing one or more local variable conversions that needs to be performed on entry to a control flow join
++ * point. Note that the class is named as a singular "Conversion" and not a plural "Conversions", but instances of the
++ * class have a reference to the next conversion, so multiple conversions are always represented with a single instance
++ * that is a head of a linked list of instances.
++ * @see JoinPredecessor
++ */
++public final class LocalVariableConversion {
++ private final Symbol symbol;
++ // TODO: maybe introduce a type pair class? These will often be repeated.
++ private final Type from;
++ private final Type to;
++ private final LocalVariableConversion next;
++
++ /**
++ * Creates a new object representing a local variable conversion.
++ * @param symbol the symbol representing the local variable whose value is being converted.
++ * @param from the type value is being converted from.
++ * @param to the type value is being converted to.
++ * @param next next conversion at the same join point, if any (the conversion object implements a singly-linked
++ * list of conversions).
++ */
++ public LocalVariableConversion(final Symbol symbol, final Type from, final Type to, final LocalVariableConversion next) {
++ this.symbol = symbol;
++ this.from = from;
++ this.to = to;
++ this.next = next;
++ }
++
++ /**
++ * Returns the type being converted from.
++ * @return the type being converted from.
++ */
++ public Type getFrom() {
++ return from;
++ }
++
++ /**
++ * Returns the type being converted to.
++ * @return the type being converted to.
++ */
++ public Type getTo() {
++ return to;
++ }
++
++ /**
++ * Returns the next conversion at the same join point, or null if this is the last one.
++ * @return the next conversion at the same join point.
++ */
++ public LocalVariableConversion getNext() {
++ return next;
++ }
++
++ /**
++ * Returns the symbol representing the local variable whose value is being converted.
++ * @return the symbol representing the local variable whose value is being converted.
++ */
++ public Symbol getSymbol() {
++ return symbol;
++ }
++
++ /**
++ * Returns true if this conversion is live. A conversion is live if the symbol has a slot for the conversion's
++ * {@link #getTo() to} type. If a conversion is dead, it can be omitted in code generator.
++ * @return true if this conversion is live.
++ */
++ public boolean isLive() {
++ return symbol.hasSlotFor(to);
++ }
++
++ /**
++ * Returns true if this conversion {@link #isLive()}, or if any of its {@link #getNext()} conversions are live.
++ * @return true if this conversion, or any conversion following it, are live.
++ */
++ public boolean isAnyLive() {
++ return isLive() || isAnyLive(next);
++ }
++
++ /**
++ * Returns true if the passed join predecessor has {@link #isAnyLive()} conversion.
++ * @param jp the join predecessor being examined.
++ * @return true if the join predecessor conversion is not null and {@link #isAnyLive()}.
++ */
++ public static boolean hasLiveConversion(final JoinPredecessor jp) {
++ return isAnyLive(jp.getLocalVariableConversion());
++ }
++
++ /**
++ * Returns true if the passed conversion is not null, and it {@link #isAnyLive()}.
++ * @parameter conv the conversion being tested for liveness.
++ * @return true if the conversion is not null and {@link #isAnyLive()}.
++ */
++ private static boolean isAnyLive(final LocalVariableConversion conv) {
++ return conv != null && conv.isAnyLive();
++ }
++
++ @Override
++ public String toString() {
++ return toString(new StringBuilder()).toString();
++ }
++
++ /**
++ * Generates a string representation of this conversion in the passed string builder.
++ * @param sb the string builder in which to generate a string representation of this conversion.
++ * @return the passed in string builder.
++ */
++ public StringBuilder toString(final StringBuilder sb) {
++ if(isLive()) {
++ return toStringNext(sb.append('\u27e6'), true).append("\u27e7 ");
++ }
++ return next == null ? sb : next.toString(sb);
++ }
++
++ /**
++ * Generates a string representation of the passed conversion in the passed string builder.
++ * @param conv the conversion to render in the string builder.
++ * @param sb the string builder in which to generate a string representation of this conversion.
++ * @return the passed in string builder.
++ */
++ public static StringBuilder toString(final LocalVariableConversion conv, final StringBuilder sb) {
++ return conv == null ? sb : conv.toString(sb);
++ }
++
++ private StringBuilder toStringNext(final StringBuilder sb, final boolean first) {
++ if(isLive()) {
++ if(!first) {
++ sb.append(", ");
++ }
++ sb.append(symbol.getName()).append(':').append(getTypeChar(from)).append('\u2192').append(getTypeChar(to));
++ return next == null ? sb : next.toStringNext(sb, false);
++ }
++ return next == null ? sb : next.toStringNext(sb, first);
++ }
++
++ private static char getTypeChar(final Type type) {
++ if(type == Type.UNDEFINED) {
++ return 'U';
++ } else if(type.isObject()) {
++ return 'O';
++ } else if(type == Type.BOOLEAN) {
++ return 'Z';
++ }
++ return type.getBytecodeStackType();
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/ir/LoopNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/LoopNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,6 +26,7 @@
+ package jdk.nashorn.internal.ir;
+
+ import java.util.Arrays;
++import java.util.Collections;
+ import java.util.List;
+ import jdk.nashorn.internal.codegen.Label;
+
+@@ -33,11 +34,13 @@
+ * A loop node, for example a while node, do while node or for node
+ */
+ public abstract class LoopNode extends BreakableStatement {
++ private static final long serialVersionUID = 1L;
++
+ /** loop continue label. */
+ protected final Label continueLabel;
+
+ /** Loop test node, null if infinite */
+- protected final Expression test;
++ protected final JoinPredecessorExpression test;
+
+ /** Loop body */
+ protected final Block body;
+@@ -51,14 +54,13 @@
+ * @param lineNumber lineNumber
+ * @param token token
+ * @param finish finish
+- * @param test test, or null if infinite loop
+ * @param body loop body
+ * @param controlFlowEscapes controlFlowEscapes
+ */
+- protected LoopNode(final int lineNumber, final long token, final int finish, final Expression test, final Block body, final boolean controlFlowEscapes) {
++ protected LoopNode(final int lineNumber, final long token, final int finish, final Block body, final boolean controlFlowEscapes) {
+ super(lineNumber, token, finish, new Label("while_break"));
+ this.continueLabel = new Label("while_continue");
+- this.test = test;
++ this.test = null;
+ this.body = body;
+ this.controlFlowEscapes = controlFlowEscapes;
+ }
+@@ -70,9 +72,11 @@
+ * @param test new test
+ * @param body new body
+ * @param controlFlowEscapes controlFlowEscapes
++ * @param conversion the local variable conversion carried by this loop node.
+ */
+- protected LoopNode(final LoopNode loopNode, final Expression test, final Block body, final boolean controlFlowEscapes) {
+- super(loopNode);
++ protected LoopNode(final LoopNode loopNode, final JoinPredecessorExpression test, final Block body,
++ final boolean controlFlowEscapes, final LocalVariableConversion conversion) {
++ super(loopNode, conversion);
+ this.continueLabel = new Label(loopNode.continueLabel);
+ this.test = test;
+ this.body = body;
+@@ -125,7 +129,7 @@
+
+ @Override
+ public List<Label> getLabels() {
+- return Arrays.asList(breakLabel, continueLabel);
++ return Collections.unmodifiableList(Arrays.asList(breakLabel, continueLabel));
+ }
+
+ @Override
+@@ -150,7 +154,9 @@
+ * Get the test for this for node
+ * @return the test
+ */
+- public abstract Expression getTest();
++ public final JoinPredecessorExpression getTest() {
++ return test;
++ }
+
+ /**
+ * Set the test for this for node
+@@ -159,7 +165,7 @@
+ * @param test new test
+ * @return same or new node depending on if test was changed
+ */
+- public abstract LoopNode setTest(final LexicalContext lc, final Expression test);
++ public abstract LoopNode setTest(final LexicalContext lc, final JoinPredecessorExpression test);
+
+ /**
+ * Set the control flow escapes flag for this node.
+@@ -171,4 +177,9 @@
+ */
+ public abstract LoopNode setControlFlowEscapes(final LexicalContext lc, final boolean controlFlowEscapes);
+
++ /**
++ * Does this loop have a LET declaration and hence require a per-iteration scope?
++ * @return true if a per-iteration scope is required.
++ */
++ public abstract boolean hasPerIterationScope();
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/Node.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/Node.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,9 +25,9 @@
+
+ package jdk.nashorn.internal.ir;
+
++import java.io.Serializable;
+ import java.util.ArrayList;
+ import java.util.List;
+-import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+ import jdk.nashorn.internal.parser.Token;
+ import jdk.nashorn.internal.parser.TokenType;
+@@ -35,7 +35,18 @@
+ /**
+ * Nodes are used to compose Abstract Syntax Trees.
+ */
+-public abstract class Node implements Cloneable {
++public abstract class Node implements Cloneable, Serializable {
++ private static final long serialVersionUID = 1L;
++
++ /** Constant used for synthetic AST nodes that have no line number. */
++ public static final int NO_LINE_NUMBER = -1;
++
++ /** Constant used for synthetic AST nodes that have no token. */
++ public static final long NO_TOKEN = 0L;
++
++ /** Constant used for synthetic AST nodes that have no finish. */
++ public static final int NO_FINISH = 0;
++
+ /** Start of source range. */
+ protected final int start;
+
+@@ -82,15 +93,6 @@
+ }
+
+ /**
+- * Is this an atom node - for example a literal or an identity
+- *
+- * @return true if atom
+- */
+- public boolean isAtom() {
+- return false;
+- }
+-
+- /**
+ * Is this a loop node?
+ *
+ * @return true if atom
+@@ -110,31 +112,6 @@
+ }
+
+ /**
+- * Is this a self modifying assignment?
+- * @return true if self modifying, e.g. a++, or a*= 17
+- */
+- public boolean isSelfModifying() {
+- return false;
+- }
+-
+- /**
+- * Returns widest operation type of this operation.
+- *
+- * @return the widest type for this operation
+- */
+- public Type getWidestOperationType() {
+- return Type.OBJECT;
+- }
+-
+- /**
+- * Returns true if this node represents a comparison operator
+- * @return true if comparison
+- */
+- public boolean isComparison() {
+- return false;
+- }
+-
+- /**
+ * For reference copies - ensure that labels in the copy node are unique
+ * using an appropriate copy constructor
+ * @param lc lexical context
+@@ -164,16 +141,19 @@
+ *
+ * @param sb a StringBuilder
+ */
+- public abstract void toString(StringBuilder sb);
++ public void toString(final StringBuilder sb) {
++ toString(sb, true);
++ }
+
+ /**
+- * Check if this node has terminal flags, i.e. ends or breaks control flow
+- *
+- * @return true if terminal
++ * Print logic that decides whether to show the optimistic type
++ * or not - for example it should not be printed after just parse,
++ * when it hasn't been computed, or has been set to a trivially provable
++ * value
++ * @param sb string builder
++ * @param printType print type?
+ */
+- public boolean hasTerminalFlags() {
+- return isTerminal() || hasGoto();
+- }
++ public abstract void toString(final StringBuilder sb, final boolean printType);
+
+ /**
+ * Get the finish position for this node in the source string
+@@ -192,15 +172,6 @@
+ }
+
+ /**
+- * Check if this function repositions control flow with goto like
+- * semantics, for example {@link BreakNode} or a {@link ForNode} with no test
+- * @return true if node has goto semantics
+- */
+- public boolean hasGoto() {
+- return false;
+- }
+-
+- /**
+ * Get start position for node
+ * @return start position
+ */
+@@ -219,12 +190,15 @@
+
+ @Override
+ public final boolean equals(final Object other) {
+- return super.equals(other);
++ return this == other;
+ }
+
+ @Override
+ public final int hashCode() {
+- return super.hashCode();
++ // NOTE: we aren't delegating to Object.hashCode as it still requires trip to the VM for initializing,
++ // it touches the object header and/or stores the identity hashcode somewhere, etc. There's several
++ // places in the compiler pipeline that store nodes in maps, so this can get hot.
++ return Long.hashCode(token);
+ }
+
+ /**
+@@ -272,30 +246,35 @@
+ return token;
+ }
+
+- /**
+- * Is this a terminal Node, i.e. does it end control flow like a throw or return
+- * expression does?
+- *
+- * @return true if this node is terminal
+- */
+- public boolean isTerminal() {
+- return false;
+- }
+-
+ //on change, we have to replace the entire list, that's we can't simple do ListIterator.set
+- static <T extends Node> List<T> accept(final NodeVisitor<? extends LexicalContext> visitor, final Class<T> clazz, final List<T> list) {
+- boolean changed = false;
+- final List<T> newList = new ArrayList<>();
+-
+- for (final Node node : list) {
+- final T newNode = node == null ? null : clazz.cast(node.accept(visitor));
+- if (newNode != node) {
+- changed = true;
+- }
+- newList.add(newNode);
++ static <T extends Node> List<T> accept(final NodeVisitor<? extends LexicalContext> visitor, final List<T> list) {
++ final int size = list.size();
++ if (size == 0) {
++ return list;
+ }
+
+- return changed ? newList : list;
++ List<T> newList = null;
++
++ for (int i = 0; i < size; i++) {
++ final T node = list.get(i);
++ @SuppressWarnings("unchecked")
++ final T newNode = node == null ? null : (T)node.accept(visitor);
++ if (newNode != node) {
++ if (newList == null) {
++ newList = new ArrayList<>(size);
++ for (int j = 0; j < i; j++) {
++ newList.add(list.get(j));
++ }
++ }
++ newList.add(newNode);
++ } else {
++ if (newList != null) {
++ newList.add(node);
++ }
++ }
++ }
++
++ return newList == null ? list : newList;
+ }
+
+ static <T extends LexicalContextNode> T replaceInLexicalContext(final LexicalContext lc, final T oldNode, final T newNode) {
+--- ./nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,6 +27,8 @@
+
+ import java.util.Collections;
+ import java.util.List;
++import java.util.function.Function;
++import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+
+@@ -35,6 +37,7 @@
+ */
+ @Immutable
+ public final class ObjectNode extends Expression {
++ private static final long serialVersionUID = 1L;
+
+ /** Literal elements. */
+ private final List<PropertyNode> elements;
+@@ -59,14 +62,19 @@
+ @Override
+ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
+ if (visitor.enterObjectNode(this)) {
+- return visitor.leaveObjectNode(setElements(Node.accept(visitor, PropertyNode.class, elements)));
++ return visitor.leaveObjectNode(setElements(Node.accept(visitor, elements)));
+ }
+
+ return this;
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
++ return Type.OBJECT;
++ }
++
++ @Override
++ public void toString(final StringBuilder sb, final boolean printType) {
+ sb.append('{');
+
+ if (!elements.isEmpty()) {
+@@ -79,7 +87,7 @@
+ }
+ first = false;
+
+- element.toString(sb);
++ element.toString(sb, printType);
+ }
+ sb.append(' ');
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/ir/Optimistic.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,92 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.ir;
++
++import jdk.nashorn.internal.codegen.types.Type;
++
++/**
++ * Is this a node that can be optimistically typed? This means that it
++ * has a probable type but it's not available through static analysis
++ *
++ * The follow nodes are optimistic, with reasons therefore given within
++ * parenthesis
++ *
++ * @see IndexNode (dynamicGetIndex)
++ * @see BinaryNode (local calculations to strongly typed bytecode)
++ * @see UnaryNode (local calculations to strongly typed bytecode)
++ * @see CallNode (dynamicCall)
++ * @see AccessNode (dynamicGet)
++ * @see IdentNode (dynamicGet)
++ */
++public interface Optimistic {
++ /**
++ * Unique node ID that is associated with an invokedynamic call that mail
++ * fail and its callsite. This is so that nodes can be regenerated less
++ * pessimistically the next generation if an assumption failed
++ *
++ * @return unique node id
++ */
++ public int getProgramPoint();
++
++ /**
++ * Set the node number for this node, associating with a unique per-function
++ * program point
++ * @param programPoint the node number
++ * @return new node, or same if unchanged
++ */
++ public Optimistic setProgramPoint(final int programPoint);
++
++ /**
++ * Is it possible for this particular implementor to actually have any optimism?
++ * SHIFT operators for instance are binary nodes, but never optimistic. Multiply
++ * operators are. We might want to refurbish the type hierarchy to fix this.
++ * @return true if theoretically optimistic
++ */
++ public boolean canBeOptimistic();
++
++ /**
++ * Get the most optimistic type for this node. Typically we start out as
++ * an int, and then at runtime we bump this up to number and then Object
++ *
++ * @return optimistic type to be used in code generation
++ */
++ public Type getMostOptimisticType();
++
++ /**
++ * Most pessimistic type that is guaranteed to be safe. Typically this is
++ * number for arithmetic operations that can overflow, or Object for an add
++ *
++ * @return pessimistic type guaranteed to never overflow
++ */
++ public Type getMostPessimisticType();
++
++ /**
++ * Set the override type
++ *
++ * @param type the type
++ * @return a node equivalent to this one except for the requested change.
++ */
++ public Optimistic setType(final Type type);
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/ir/OptimisticLexicalContext.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,128 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.ir;
++
++import java.util.ArrayDeque;
++import java.util.ArrayList;
++import java.util.Collections;
++import java.util.Deque;
++import java.util.List;
++import jdk.nashorn.internal.codegen.types.Type;
++
++/**
++ * Lexical context that keeps track of optimistic assumptions (if any)
++ * made during code generation. Used from Attr and FinalizeTypes
++ */
++public class OptimisticLexicalContext extends LexicalContext {
++
++ private final boolean isEnabled;
++
++ class Assumption {
++ Symbol symbol;
++ Type type;
++
++ Assumption(final Symbol symbol, final Type type) {
++ this.symbol = symbol;
++ this.type = type;
++ }
++ @Override
++ public String toString() {
++ return symbol.getName() + "=" + type;
++ }
++ }
++
++ /** Optimistic assumptions that could be made per function */
++ private final Deque<List<Assumption>> optimisticAssumptions = new ArrayDeque<>();
++
++ /**
++ * Constructor
++ * @param isEnabled are optimistic types enabled?
++ */
++ public OptimisticLexicalContext(final boolean isEnabled) {
++ super();
++ this.isEnabled = isEnabled;
++ }
++
++ /**
++ * Are optimistic types enabled
++ * @return true if optimistic types
++ */
++ public boolean isEnabled() {
++ return isEnabled;
++ }
++
++ /**
++ * Log an optimistic assumption during codegen
++ * TODO : different parameters and more info about the assumption for future profiling
++ * needs
++ * @param symbol symbol
++ * @param type type
++ */
++ public void logOptimisticAssumption(final Symbol symbol, final Type type) {
++ if (isEnabled) {
++ final List<Assumption> peek = optimisticAssumptions.peek();
++ peek.add(new Assumption(symbol, type));
++ }
++ }
++
++ /**
++ * Get the list of optimistic assumptions made
++ * @return optimistic assumptions
++ */
++ public List<Assumption> getOptimisticAssumptions() {
++ return Collections.unmodifiableList(optimisticAssumptions.peek());
++ }
++
++ /**
++ * Does this method have optimistic assumptions made during codegen?
++ * @return true if optimistic assumptions were made
++ */
++ public boolean hasOptimisticAssumptions() {
++ return !optimisticAssumptions.isEmpty() && !getOptimisticAssumptions().isEmpty();
++ }
++
++ @Override
++ public <T extends LexicalContextNode> T push(final T node) {
++ if (isEnabled) {
++ if(node instanceof FunctionNode) {
++ optimisticAssumptions.push(new ArrayList<Assumption>());
++ }
++ }
++
++ return super.push(node);
++ }
++
++ @Override
++ public <T extends LexicalContextNode> T pop(final T node) {
++ final T popped = super.pop(node);
++ if (isEnabled) {
++ if(node instanceof FunctionNode) {
++ optimisticAssumptions.pop();
++ }
++ }
++ return popped;
++ }
++
++}
+--- ./nashorn/src/jdk/nashorn/internal/ir/PropertyNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/PropertyNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -33,6 +33,7 @@
+ */
+ @Immutable
+ public final class PropertyNode extends Node {
++ private static final long serialVersionUID = 1L;
+
+ /** Property key. */
+ private final PropertyKey key;
+@@ -94,25 +95,25 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ if (value instanceof FunctionNode && ((FunctionNode)value).getIdent() != null) {
+ value.toString(sb);
+ }
+
+ if (value != null) {
+- ((Node)key).toString(sb);
++ ((Node)key).toString(sb, printType);
+ sb.append(": ");
+- value.toString(sb);
++ value.toString(sb, printType);
+ }
+
+ if (getter != null) {
+ sb.append(' ');
+- getter.toString(sb);
++ getter.toString(sb, printType);
+ }
+
+ if (setter != null) {
+ sb.append(' ');
+- setter.toString(sb);
++ setter.toString(sb, printType);
+ }
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -36,6 +36,8 @@
+ */
+ @Immutable
+ public class ReturnNode extends Statement {
++ private static final long serialVersionUID = 1L;
++
+ /** Optional expression. */
+ private final Expression expression;
+
+@@ -100,11 +102,11 @@
+
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ sb.append(isYield() ? "yield" : "return");
+ if (expression != null) {
+ sb.append(' ');
+- expression.toString(sb);
++ expression.toString(sb, printType);
+ }
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,10 +25,12 @@
+
+ package jdk.nashorn.internal.ir;
+
+-import java.util.ArrayList;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
++
+ import java.util.Arrays;
+ import java.util.Collections;
+ import java.util.List;
++import java.util.function.Function;
+ import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+@@ -38,7 +40,8 @@
+ * IR representation for a runtime call.
+ */
+ @Immutable
+-public class RuntimeNode extends Expression {
++public class RuntimeNode extends Expression implements Optimistic {
++ private static final long serialVersionUID = 1L;
+
+ /**
+ * Request enum used for meta-information about the runtime request
+@@ -77,7 +80,11 @@
+ /** !== operator with at least one object */
+ NE_STRICT(TokenType.NE_STRICT, Type.BOOLEAN, 2, true),
+ /** != operator with at least one object */
+- NE(TokenType.NE, Type.BOOLEAN, 2, true);
++ NE(TokenType.NE, Type.BOOLEAN, 2, true),
++ /** is undefined */
++ IS_UNDEFINED(TokenType.EQ_STRICT, Type.BOOLEAN, 2),
++ /** is not undefined */
++ IS_NOT_UNDEFINED(TokenType.NE_STRICT, Type.BOOLEAN, 2);
+
+ /** token type */
+ private final TokenType tokenType;
+@@ -163,9 +170,14 @@
+ * @param node the node
+ * @return request type
+ */
+- public static Request requestFor(final Node node) {
+- assert node.isComparison();
++ public static Request requestFor(final Expression node) {
+ switch (node.tokenType()) {
++ case TYPEOF:
++ return Request.TYPEOF;
++ case IN:
++ return Request.IN;
++ case INSTANCEOF:
++ return Request.INSTANCEOF;
+ case EQ_STRICT:
+ return Request.EQ_STRICT;
+ case NE_STRICT:
+@@ -189,6 +201,17 @@
+ }
+
+ /**
++ * Is this an undefined check?
++ *
++ * @param request request
++ *
++ * @return true if undefined check
++ */
++ public static boolean isUndefinedCheck(final Request request) {
++ return request == IS_UNDEFINED || request == IS_NOT_UNDEFINED;
++ }
++
++ /**
+ * Is this an EQ or EQ_STRICT?
+ *
+ * @param request a request
+@@ -211,6 +234,17 @@
+ }
+
+ /**
++ * Is this strict?
++ *
++ * @param request a request
++ *
++ * @return true if script
++ */
++ public static boolean isStrict(final Request request) {
++ return request == EQ_STRICT || request == NE_STRICT;
++ }
++
++ /**
+ * If this request can be reversed, return the reverse request
+ * Eq EQ {@literal ->} NE.
+ *
+@@ -285,6 +319,8 @@
+ case LT:
+ case GE:
+ case GT:
++ case IS_UNDEFINED:
++ case IS_NOT_UNDEFINED:
+ return true;
+ default:
+ return false;
+@@ -301,6 +337,8 @@
+ /** is final - i.e. may not be removed again, lower in the code pipeline */
+ private final boolean isFinal;
+
++ private final int programPoint;
++
+ /**
+ * Constructor
+ *
+@@ -315,14 +353,16 @@
+ this.request = request;
+ this.args = args;
+ this.isFinal = false;
++ this.programPoint = INVALID_PROGRAM_POINT;
+ }
+
+- private RuntimeNode(final RuntimeNode runtimeNode, final Request request, final boolean isFinal, final List<Expression> args) {
++ private RuntimeNode(final RuntimeNode runtimeNode, final Request request, final boolean isFinal, final List<Expression> args, final int programPoint) {
+ super(runtimeNode);
+
+ this.request = request;
+ this.args = args;
+ this.isFinal = isFinal;
++ this.programPoint = programPoint;
+ }
+
+ /**
+@@ -361,6 +401,7 @@
+ this.request = request;
+ this.args = args;
+ this.isFinal = false;
++ this.programPoint = parent instanceof Optimistic ? ((Optimistic)parent).getProgramPoint() : INVALID_PROGRAM_POINT;
+ }
+
+ /**
+@@ -370,20 +411,32 @@
+ * @param request the request
+ */
+ public RuntimeNode(final UnaryNode parent, final Request request) {
+- this(parent, request, parent.rhs());
++ this(parent, request, parent.getExpression());
+ }
+
+ /**
+- * Constructor
++ * Constructor used to replace a binary node with a runtime request.
+ *
+ * @param parent parent node from which to inherit source, token, finish and arguments
+- * @param request the request
+ */
+- public RuntimeNode(final BinaryNode parent, final Request request) {
+- this(parent, request, parent.lhs(), parent.rhs());
++ public RuntimeNode(final BinaryNode parent) {
++ this(parent, Request.requestFor(parent), parent.lhs(), parent.rhs());
+ }
+
+ /**
++ * Reset the request for this runtime node
++ * @param request request
++ * @return new runtime node or same if same request
++ */
++ public RuntimeNode setRequest(final Request request) {
++ if (this.request == request) {
++ return this;
++ }
++ return new RuntimeNode(this, request, isFinal, args, programPoint);
++ }
++
++
++ /**
+ * Is this node final - i.e. it can never be replaced with other nodes again
+ * @return true if final
+ */
+@@ -400,32 +453,28 @@
+ if (this.isFinal == isFinal) {
+ return this;
+ }
+- return new RuntimeNode(this, request, isFinal, args);
++ return new RuntimeNode(this, request, isFinal, args, programPoint);
+ }
+
+ /**
+ * Return type for the ReferenceNode
+ */
+ @Override
+- public Type getType() {
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
+ return request.getReturnType();
+ }
+
+ @Override
+ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
+ if (visitor.enterRuntimeNode(this)) {
+- final List<Expression> newArgs = new ArrayList<>();
+- for (final Node arg : args) {
+- newArgs.add((Expression)arg.accept(visitor));
+- }
+- return visitor.leaveRuntimeNode(setArgs(newArgs));
++ return visitor.leaveRuntimeNode(setArgs(Node.accept(visitor, args)));
+ }
+
+ return this;
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ sb.append("ScriptRuntime.");
+ sb.append(request);
+ sb.append('(');
+@@ -439,7 +488,7 @@
+ first = false;
+ }
+
+- arg.toString(sb);
++ arg.toString(sb, printType);
+ }
+
+ sb.append(')');
+@@ -453,11 +502,16 @@
+ return Collections.unmodifiableList(args);
+ }
+
+- private RuntimeNode setArgs(final List<Expression> args) {
++ /**
++ * Set the arguments of this runtime node
++ * @param args new arguments
++ * @return new runtime node, or identical if no change
++ */
++ public RuntimeNode setArgs(final List<Expression> args) {
+ if (this.args == args) {
+ return this;
+ }
+- return new RuntimeNode(this, request, isFinal, args);
++ return new RuntimeNode(this, request, isFinal, args, programPoint);
+ }
+
+ /**
+@@ -483,4 +537,39 @@
+ }
+ return true;
+ }
++
++//TODO these are blank for now:
++
++ @Override
++ public int getProgramPoint() {
++ return programPoint;
++ }
++
++ @Override
++ public RuntimeNode setProgramPoint(final int programPoint) {
++ if(this.programPoint == programPoint) {
++ return this;
++ }
++ return new RuntimeNode(this, request, isFinal, args, programPoint);
++ }
++
++ @Override
++ public boolean canBeOptimistic() {
++ return false;
++ }
++
++ @Override
++ public Type getMostOptimisticType() {
++ return getType();
++ }
++
++ @Override
++ public Type getMostPessimisticType() {
++ return getType();
++ }
++
++ @Override
++ public RuntimeNode setType(final Type type) {
++ return this;
++ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/ir/SetSplitState.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.ir;
++
++import jdk.nashorn.internal.codegen.CompilerConstants;
++import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++import jdk.nashorn.internal.runtime.Scope;
++
++/**
++ * Synthetic AST node that represents loading of the scope object and invocation of the {@link Scope#setSplitState(int)}
++ * method on it. It has no JavaScript source representation and only occurs in synthetic functions created by
++ * the split-into-functions transformation.
++ */
++public final class SetSplitState extends Statement {
++ private static final long serialVersionUID = 1L;
++
++ private final int state;
++
++ /**
++ * Creates a new split state setter
++ * @param state the state to set
++ * @param lineNumber the line number where it is inserted
++ */
++ public SetSplitState(final int state, final int lineNumber) {
++ super(lineNumber, NO_TOKEN, NO_FINISH);
++ this.state = state;
++ }
++
++ /**
++ * Returns the state this setter sets.
++ * @return the state this setter sets.
++ */
++ public int getState() {
++ return state;
++ }
++
++ @Override
++ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
++ return visitor.enterSetSplitState(this) ? visitor.leaveSetSplitState(this) : this;
++ }
++
++ @Override
++ public void toString(final StringBuilder sb, final boolean printType) {
++ sb.append(CompilerConstants.SCOPE.symbolName()).append('.').append(Scope.SET_SPLIT_STATE.name())
++ .append('(').append(state).append(");");
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/ir/SplitNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/SplitNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,9 @@
+
+ package jdk.nashorn.internal.ir;
+
++import java.io.IOException;
++import java.io.NotSerializableException;
++import java.io.ObjectOutputStream;
+ import jdk.nashorn.internal.codegen.CompileUnit;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+@@ -33,7 +36,9 @@
+ * Node indicating code is split across classes.
+ */
+ @Immutable
+-public class SplitNode extends LexicalContextStatement {
++public class SplitNode extends LexicalContextStatement implements CompileUnitHolder {
++ private static final long serialVersionUID = 1L;
++
+ /** Split node method name. */
+ private final String name;
+
+@@ -41,7 +46,7 @@
+ private final CompileUnit compileUnit;
+
+ /** Body of split code. */
+- private final Node body;
++ private final Block body;
+
+ /**
+ * Constructor
+@@ -50,49 +55,49 @@
+ * @param body body of split code
+ * @param compileUnit compile unit to use for the body
+ */
+- public SplitNode(final String name, final Node body, final CompileUnit compileUnit) {
+- super(-1, body.getToken(), body.getFinish());
++ public SplitNode(final String name, final Block body, final CompileUnit compileUnit) {
++ super(body.getFirstStatementLineNumber(), body.getToken(), body.getFinish());
+ this.name = name;
+ this.body = body;
+ this.compileUnit = compileUnit;
+ }
+
+- private SplitNode(final SplitNode splitNode, final Node body) {
++ private SplitNode(final SplitNode splitNode, final Block body, final CompileUnit compileUnit) {
+ super(splitNode);
+ this.name = splitNode.name;
+ this.body = body;
+- this.compileUnit = splitNode.compileUnit;
++ this.compileUnit = compileUnit;
+ }
+
+ /**
+ * Get the body for this split node - i.e. the actual code it encloses
+ * @return body for split node
+ */
+- public Node getBody() {
++ public Block getBody() {
+ return body;
+ }
+
+- private SplitNode setBody(final LexicalContext lc, final Node body) {
++ private SplitNode setBody(final LexicalContext lc, final Block body) {
+ if (this.body == body) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new SplitNode(this, body));
++ return Node.replaceInLexicalContext(lc, this, new SplitNode(this, body, compileUnit));
+ }
+
+ @Override
+ public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
+ if (visitor.enterSplitNode(this)) {
+- return visitor.leaveSplitNode(setBody(lc, body.accept(visitor)));
++ return visitor.leaveSplitNode(setBody(lc, (Block)body.accept(visitor)));
+ }
+ return this;
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ sb.append("<split>(");
+ sb.append(compileUnit.getClass().getSimpleName());
+ sb.append(") ");
+- body.toString(sb);
++ body.toString(sb, printType);
+ }
+
+ /**
+@@ -107,8 +112,27 @@
+ * Get the compile unit for this split node
+ * @return compile unit
+ */
++ @Override
+ public CompileUnit getCompileUnit() {
+ return compileUnit;
+ }
+
++ /**
++ * Set the compile unit for this split node
++ * @param lc lexical context
++ * @param compileUnit compile unit
++ * @return new node if changed, otherwise same node
++ */
++ public SplitNode setCompileUnit(final LexicalContext lc, final CompileUnit compileUnit) {
++ if (this.compileUnit == compileUnit) {
++ return this;
++ }
++ return Node.replaceInLexicalContext(lc, this, new SplitNode(this, body, compileUnit));
++ }
++
++ private void writeObject(final ObjectOutputStream out) throws IOException {
++ // We are only serializing the AST after we run SplitIntoFunctions; no SplitNodes can remain for the
++ // serialization.
++ throw new NotSerializableException(getClass().getName());
++ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/ir/SplitReturn.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,64 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.ir;
++
++import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++
++/**
++ * Synthetic AST node that represents return from a split fragment of a split function for control flow reasons (break
++ * or continue into a target outside the current fragment). It has no JavaScript source representation and only occurs
++ * in synthetic functions created by the split-into-functions transformation. It is different from a return node in
++ * that the return value is irrelevant, and doesn't affect the function's return type calculation.
++ */
++public final class SplitReturn extends Statement {
++ private static final long serialVersionUID = 1L;
++
++ /** The sole instance of this AST node. */
++ public static final SplitReturn INSTANCE = new SplitReturn();
++
++ private SplitReturn() {
++ super(NO_LINE_NUMBER, NO_TOKEN, NO_FINISH);
++ }
++
++ @Override
++ public boolean isTerminal() {
++ return true;
++ }
++
++ @Override
++ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
++ return visitor.enterSplitReturn(this) ? visitor.leaveSplitReturn(this) : this;
++ }
++
++ @Override
++ public void toString(StringBuilder sb, boolean printType) {
++ sb.append(":splitreturn;");
++ }
++
++ private Object readResolve() {
++ return INSTANCE;
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/ir/Statement.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/Statement.java Wed Feb 04 12:14:47 2015 -0800
+@@ -30,7 +30,8 @@
+ * made up of statements. The only node subclass that needs to keep token and
+ * location information is the Statement
+ */
+-public abstract class Statement extends Node {
++public abstract class Statement extends Node implements Terminal {
++ private static final long serialVersionUID = 1L;
+
+ private final int lineNumber;
+
+@@ -77,4 +78,32 @@
+ return lineNumber;
+ }
+
++ /**
++ * Is this a terminal statement, i.e. does it end control flow like a throw or return?
++ *
++ * @return true if this node statement is terminal
++ */
++ @Override
++ public boolean isTerminal() {
++ return false;
++ }
++
++ /**
++ * Check if this statement repositions control flow with goto like
++ * semantics, for example {@link BreakNode} or a {@link ForNode} with no test
++ * @return true if statement has goto semantics
++ */
++ public boolean hasGoto() {
++ return false;
++ }
++
++ /**
++ * Check if this statement has terminal flags, i.e. ends or breaks control flow
++ *
++ * @return true if has terminal flags
++ */
++ public final boolean hasTerminalFlags() {
++ return isTerminal() || hasGoto();
++ }
+ }
++
+--- ./nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -37,6 +37,8 @@
+ */
+ @Immutable
+ public final class SwitchNode extends BreakableStatement {
++ private static final long serialVersionUID = 1L;
++
+ /** Switch expression. */
+ private final Expression expression;
+
+@@ -46,6 +48,10 @@
+ /** Switch default index. */
+ private final int defaultCaseIndex;
+
++ /** True if all cases are 32-bit signed integer constants, without repetitions. It's a prerequisite for
++ * using a tableswitch/lookupswitch when generating code. */
++ private final boolean uniqueInteger;
++
+ /** Tag symbol. */
+ private Symbol tag;
+
+@@ -64,23 +70,26 @@
+ this.expression = expression;
+ this.cases = cases;
+ this.defaultCaseIndex = defaultCase == null ? -1 : cases.indexOf(defaultCase);
++ this.uniqueInteger = false;
+ }
+
+- private SwitchNode(final SwitchNode switchNode, final Expression expression, final List<CaseNode> cases, final int defaultCase) {
+- super(switchNode);
++ private SwitchNode(final SwitchNode switchNode, final Expression expression, final List<CaseNode> cases,
++ final int defaultCaseIndex, final LocalVariableConversion conversion, final boolean uniqueInteger) {
++ super(switchNode, conversion);
+ this.expression = expression;
+ this.cases = cases;
+- this.defaultCaseIndex = defaultCase;
+- this.tag = switchNode.getTag(); //TODO are symbols inhereted as references?
++ this.defaultCaseIndex = defaultCaseIndex;
++ this.tag = switchNode.getTag(); //TODO are symbols inherited as references?
++ this.uniqueInteger = uniqueInteger;
+ }
+
+ @Override
+ public Node ensureUniqueLabels(final LexicalContext lc) {
+ final List<CaseNode> newCases = new ArrayList<>();
+ for (final CaseNode caseNode : cases) {
+- newCases.add(new CaseNode(caseNode, caseNode.getTest(), caseNode.getBody()));
++ newCases.add(new CaseNode(caseNode, caseNode.getTest(), caseNode.getBody(), caseNode.getLocalVariableConversion()));
+ }
+- return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, newCases, defaultCaseIndex));
++ return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, newCases, defaultCaseIndex, conversion, uniqueInteger));
+ }
+
+ @Override
+@@ -103,16 +112,16 @@
+ if (visitor.enterSwitchNode(this)) {
+ return visitor.leaveSwitchNode(
+ setExpression(lc, (Expression)expression.accept(visitor)).
+- setCases(lc, Node.accept(visitor, CaseNode.class, cases), defaultCaseIndex));
++ setCases(lc, Node.accept(visitor, cases), defaultCaseIndex));
+ }
+
+ return this;
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ sb.append("switch (");
+- expression.toString(sb);
++ expression.toString(sb, printType);
+ sb.append(')');
+ }
+
+@@ -138,7 +147,7 @@
+ * by NodeVisitors who perform operations on every case node
+ * @param lc lexical context
+ * @param cases list of cases
+- * @return new switcy node or same if no state was changed
++ * @return new switch node or same if no state was changed
+ */
+ public SwitchNode setCases(final LexicalContext lc, final List<CaseNode> cases) {
+ return setCases(lc, cases, defaultCaseIndex);
+@@ -148,7 +157,7 @@
+ if (this.cases == cases) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, cases, defaultCaseIndex));
++ return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, cases, defaultCaseIndex, conversion, uniqueInteger));
+ }
+
+ /**
+@@ -180,7 +189,7 @@
+ if (this.expression == expression) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, cases, defaultCaseIndex));
++ return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, cases, defaultCaseIndex, conversion, uniqueInteger));
+ }
+
+ /**
+@@ -200,5 +209,32 @@
+ public void setTag(final Symbol tag) {
+ this.tag = tag;
+ }
++
++ /**
++ * Returns true if all cases of this switch statement are 32-bit signed integer constants, without repetitions.
++ * @return true if all cases of this switch statement are 32-bit signed integer constants, without repetitions.
++ */
++ public boolean isUniqueInteger() {
++ return uniqueInteger;
++ }
++
++ /**
++ * Sets whether all cases of this switch statement are 32-bit signed integer constants, without repetitions.
++ * @param lc lexical context
++ * @param uniqueInteger if true, all cases of this switch statement have been determined to be 32-bit signed
++ * integer constants, without repetitions.
++ * @return this switch node, if the value didn't change, or a new switch node with the changed value
++ */
++ public SwitchNode setUniqueInteger(final LexicalContext lc, final boolean uniqueInteger) {
++ if(this.uniqueInteger == uniqueInteger) {
++ return this;
++ }
++ return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, cases, defaultCaseIndex, conversion, uniqueInteger));
++ }
++
++ @Override
++ JoinPredecessor setLocalVariableConversionChanged(final LexicalContext lc, final LocalVariableConversion conversion) {
++ return Node.replaceInLexicalContext(lc, this, new SwitchNode(this, expression, cases, defaultCaseIndex, conversion, uniqueInteger));
++ }
++
+ }
+-
+--- ./nashorn/src/jdk/nashorn/internal/ir/Symbol.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/Symbol.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,54 +29,62 @@
+ import java.util.HashSet;
+ import java.util.Set;
+ import java.util.StringTokenizer;
+-import jdk.nashorn.internal.codegen.types.Range;
+ import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.runtime.Context;
+ import jdk.nashorn.internal.runtime.Debug;
+ import jdk.nashorn.internal.runtime.options.Options;
+
+-import static jdk.nashorn.internal.codegen.CompilerConstants.RETURN;
+-
+ /**
+- * Maps a name to specific data.
++ * Symbol is a symbolic address for a value ("variable" if you wish). Identifiers in JavaScript source, as well as
++ * certain synthetic variables created by the compiler are represented by Symbol objects. Symbols can address either
++ * local variable slots in bytecode ("slotted symbol"), or properties in scope objects ("scoped symbol"). A symbol can
++ * also end up being defined but then not used during symbol assignment calculations; such symbol will be neither
++ * scoped, nor slotted; it represents a dead variable (it might be written to, but is never read). Finally, a symbol can
++ * be both slotted and in scope. This special case can only occur with bytecode method parameters. They all come in as
++ * slotted, but if they are used by a nested function (or eval) then they will be copied into the scope object, and used
++ * from there onwards. Two further special cases are parameters stored in {@code NativeArguments} objects and parameters
++ * stored in {@code Object[]} parameter to variable-arity functions. Those use the {@code #getFieldIndex()} property to
++ * refer to their location.
+ */
+
+ public final class Symbol implements Comparable<Symbol> {
+- /** Symbol kinds. Kind ordered by precedence. */
+- public static final int IS_TEMP = 1;
+ /** Is this Global */
+- public static final int IS_GLOBAL = 2;
++ public static final int IS_GLOBAL = 1;
+ /** Is this a variable */
+- public static final int IS_VAR = 3;
++ public static final int IS_VAR = 2;
+ /** Is this a parameter */
+- public static final int IS_PARAM = 4;
+- /** Is this a constant */
+- public static final int IS_CONSTANT = 5;
++ public static final int IS_PARAM = 3;
+ /** Mask for kind flags */
+- public static final int KINDMASK = (1 << 3) - 1; // Kinds are represented by lower three bits
++ public static final int KINDMASK = (1 << 2) - 1; // Kinds are represented by lower two bits
+
+- /** Is this scope */
+- public static final int IS_SCOPE = 1 << 4;
++ /** Is this symbol in scope */
++ public static final int IS_SCOPE = 1 << 2;
+ /** Is this a this symbol */
+- public static final int IS_THIS = 1 << 5;
+- /** Can this symbol ever be undefined */
+- public static final int CAN_BE_UNDEFINED = 1 << 6;
+- /** Is this symbol always defined? */
+- public static final int IS_ALWAYS_DEFINED = 1 << 8;
+- /** Can this symbol ever have primitive types */
+- public static final int CAN_BE_PRIMITIVE = 1 << 9;
++ public static final int IS_THIS = 1 << 3;
+ /** Is this a let */
+- public static final int IS_LET = 1 << 10;
++ public static final int IS_LET = 1 << 4;
++ /** Is this a const */
++ public static final int IS_CONST = 1 << 5;
+ /** Is this an internal symbol, never represented explicitly in source code */
+- public static final int IS_INTERNAL = 1 << 11;
++ public static final int IS_INTERNAL = 1 << 6;
+ /** Is this a function self-reference symbol */
+- public static final int IS_FUNCTION_SELF = 1 << 12;
+- /** Is this a specialized param? */
+- public static final int IS_SPECIALIZED_PARAM = 1 << 13;
+- /** Is this symbol a shared temporary? */
+- public static final int IS_SHARED = 1 << 14;
++ public static final int IS_FUNCTION_SELF = 1 << 7;
+ /** Is this a function declaration? */
+- public static final int IS_FUNCTION_DECLARATION = 1 << 15;
++ public static final int IS_FUNCTION_DECLARATION = 1 << 8;
++ /** Is this a program level symbol? */
++ public static final int IS_PROGRAM_LEVEL = 1 << 9;
++ /** Are this symbols' values stored in local variable slots? */
++ public static final int HAS_SLOT = 1 << 10;
++ /** Is this symbol known to store an int value ? */
++ public static final int HAS_INT_VALUE = 1 << 11;
++ /** Is this symbol known to store a long value ? */
++ public static final int HAS_LONG_VALUE = 1 << 12;
++ /** Is this symbol known to store a double value ? */
++ public static final int HAS_DOUBLE_VALUE = 1 << 13;
++ /** Is this symbol known to store an object value ? */
++ public static final int HAS_OBJECT_VALUE = 1 << 14;
++ /** Is this symbol seen a declaration? Used for block scoped LET and CONST symbols only. */
++ public static final int HAS_BEEN_DECLARED = 1 << 15;
+
+ /** Null or name identifying symbol. */
+ private final String name;
+@@ -84,21 +92,16 @@
+ /** Symbol flags. */
+ private int flags;
+
+- /** Type of symbol. */
+- private Type type;
+-
+- /** Local variable slot. -1 indicates external property. */
+- private int slot;
++ /** First bytecode method local variable slot for storing the value(s) of this variable. -1 indicates the variable
++ * is not stored in local variable slots or it is not yet known. */
++ private int firstSlot = -1;
+
+ /** Field number in scope or property; array index in varargs when not using arguments object. */
+- private int fieldIndex;
++ private int fieldIndex = -1;
+
+ /** Number of times this symbol is used in code */
+ private int useCount;
+
+- /** Range for symbol */
+- private Range range;
+-
+ /** Debugging option - dump info and stack trace when symbols with given names are manipulated */
+ private static final Set<String> TRACE_SYMBOLS;
+ private static final Set<String> TRACE_SYMBOLS_STACKTRACE;
+@@ -109,7 +112,7 @@
+ if (stacktrace != null) {
+ trace = stacktrace; //stacktrace always implies trace as well
+ TRACE_SYMBOLS_STACKTRACE = new HashSet<>();
+- for (StringTokenizer st = new StringTokenizer(stacktrace, ","); st.hasMoreTokens(); ) {
++ for (final StringTokenizer st = new StringTokenizer(stacktrace, ","); st.hasMoreTokens(); ) {
+ TRACE_SYMBOLS_STACKTRACE.add(st.nextToken());
+ }
+ } else {
+@@ -119,7 +122,7 @@
+
+ if (trace != null) {
+ TRACE_SYMBOLS = new HashSet<>();
+- for (StringTokenizer st = new StringTokenizer(trace, ","); st.hasMoreTokens(); ) {
++ for (final StringTokenizer st = new StringTokenizer(trace, ","); st.hasMoreTokens(); ) {
+ TRACE_SYMBOLS.add(st.nextToken());
+ }
+ } else {
+@@ -132,49 +135,13 @@
+ *
+ * @param name name of symbol
+ * @param flags symbol flags
+- * @param type type of this symbol
+- * @param slot bytecode slot for this symbol
+ */
+- protected Symbol(final String name, final int flags, final Type type, final int slot) {
++ public Symbol(final String name, final int flags) {
+ this.name = name;
+ this.flags = flags;
+- this.type = type;
+- this.slot = slot;
+- this.fieldIndex = -1;
+- this.range = Range.createUnknownRange();
+- trace("CREATE SYMBOL");
+- }
+-
+- /**
+- * Constructor
+- *
+- * @param name name of symbol
+- * @param flags symbol flags
+- */
+- public Symbol(final String name, final int flags) {
+- this(name, flags, Type.UNKNOWN, -1);
+- }
+-
+- /**
+- * Constructor
+- *
+- * @param name name of symbol
+- * @param flags symbol flags
+- * @param type type of this symbol
+- */
+- public Symbol(final String name, final int flags, final Type type) {
+- this(name, flags, type, -1);
+- }
+-
+- private Symbol(final Symbol base, final String name, final int flags) {
+- this.flags = flags;
+- this.name = name;
+-
+- this.fieldIndex = base.fieldIndex;
+- this.slot = base.slot;
+- this.type = base.type;
+- this.useCount = base.useCount;
+- this.range = base.range;
++ if(shouldTrace()) {
++ trace("CREATE SYMBOL " + name);
++ }
+ }
+
+ private static String align(final String string, final int max) {
+@@ -188,74 +155,58 @@
+ }
+
+ /**
+- * Return the type for this symbol. Normally, if there is no type override,
+- * this is where any type for any node is stored. If the node has a TypeOverride,
+- * it may override this, e.g. when asking for a scoped field as a double
+- *
+- * @return symbol type
+- */
+- public final Type getSymbolType() {
+- return type;
+- }
+-
+- /**
+ * Debugging .
+ *
+ * @param stream Stream to print to.
+ */
+
+ void print(final PrintWriter stream) {
+- final String printName = align(name, 20);
+- final String printType = align(type.toString(), 10);
+- final String printSlot = align(slot == -1 ? "none" : "" + slot, 10);
+- String printFlags = "";
++ final StringBuilder sb = new StringBuilder();
++
++ sb.append(align(name, 20)).
++ append(": ").
++ append(", ").
++ append(align(firstSlot == -1 ? "none" : "" + firstSlot, 10));
+
+ switch (flags & KINDMASK) {
+- case IS_TEMP:
+- printFlags = "temp " + printFlags;
+- break;
+ case IS_GLOBAL:
+- printFlags = "global " + printFlags;
++ sb.append(" global");
+ break;
+ case IS_VAR:
+- printFlags = "var " + printFlags;
++ if (isConst()) {
++ sb.append(" const");
++ } else if (isLet()) {
++ sb.append(" let");
++ } else {
++ sb.append(" var");
++ }
+ break;
+ case IS_PARAM:
+- printFlags = "param " + printFlags;
+- break;
+- case IS_CONSTANT:
+- printFlags = "CONSTANT " + printFlags;
++ sb.append(" param");
+ break;
+ default:
+ break;
+ }
+
+ if (isScope()) {
+- printFlags += "scope ";
++ sb.append(" scope");
+ }
+
+ if (isInternal()) {
+- printFlags += "internal ";
+- }
+-
+- if (isLet()) {
+- printFlags += "let ";
++ sb.append(" internal");
+ }
+
+ if (isThis()) {
+- printFlags += "this ";
++ sb.append(" this");
+ }
+
+- if (!canBeUndefined()) {
+- printFlags += "always_def ";
++ if (isProgramLevel()) {
++ sb.append(" program");
+ }
+
+- if (canBePrimitive()) {
+- printFlags += "can_be_prim ";
+- }
++ sb.append('\n');
+
+- stream.print(printName + ": " + printType + ", " + printSlot + ", " + printFlags);
+- stream.println();
++ stream.print(sb.toString());
+ }
+
+ /**
+@@ -272,9 +223,16 @@
+ * Allocate a slot for this symbol.
+ *
+ * @param needsSlot True if symbol needs a slot.
++ * @return the symbol
+ */
+- public void setNeedsSlot(final boolean needsSlot) {
+- setSlot(needsSlot ? 0 : -1);
++ public Symbol setNeedsSlot(final boolean needsSlot) {
++ if(needsSlot) {
++ assert !isScope();
++ flags |= HAS_SLOT;
++ } else {
++ flags &= ~HAS_SLOT;
++ }
++ return this;
+ }
+
+ /**
+@@ -283,7 +241,14 @@
+ * @return Number of slots.
+ */
+ public int slotCount() {
+- return type.isCategory2() ? 2 : 1;
++ return ((flags & HAS_INT_VALUE) == 0 ? 0 : 1) +
++ ((flags & HAS_LONG_VALUE) == 0 ? 0 : 2) +
++ ((flags & HAS_DOUBLE_VALUE) == 0 ? 0 : 2) +
++ ((flags & HAS_OBJECT_VALUE) == 0 ? 0 : 1);
++ }
++
++ private boolean isSlotted() {
++ return firstSlot != -1 && ((flags & HAS_SLOT) != 0);
+ }
+
+ @Override
+@@ -291,17 +256,18 @@
+ final StringBuilder sb = new StringBuilder();
+
+ sb.append(name).
+- append(' ').
+- append('(').
+- append(getSymbolType().getTypeClass().getSimpleName()).
+- append(')');
++ append(' ');
+
+ if (hasSlot()) {
+ sb.append(' ').
+ append('(').
+ append("slot=").
+- append(slot).
+- append(')');
++ append(firstSlot).append(' ');
++ if((flags & HAS_INT_VALUE) != 0) { sb.append('I'); }
++ if((flags & HAS_LONG_VALUE) != 0) { sb.append('J'); }
++ if((flags & HAS_DOUBLE_VALUE) != 0) { sb.append('D'); }
++ if((flags & HAS_OBJECT_VALUE) != 0) { sb.append('O'); }
++ sb.append(')');
+ }
+
+ if (isScope()) {
+@@ -312,10 +278,6 @@
+ }
+ }
+
+- if (canBePrimitive()) {
+- sb.append(" P?");
+- }
+-
+ return sb.toString();
+ }
+
+@@ -325,21 +287,31 @@
+ }
+
+ /**
+- * Does this symbol have an allocated bytecode slot. If not, it is scope
+- * and must be loaded from memory upon access
++ * Does this symbol have an allocated bytecode slot? Note that having an allocated bytecode slot doesn't necessarily
++ * mean the symbol's value will be stored in it. Namely, a function parameter can have a bytecode slot, but if it is
++ * in scope, then the bytecode slot will not be used. See {@link #isBytecodeLocal()}.
+ *
+ * @return true if this symbol has a local bytecode slot
+ */
+ public boolean hasSlot() {
+- return slot >= 0;
++ return (flags & HAS_SLOT) != 0;
+ }
+
+ /**
+- * Check if this is a temporary symbol
+- * @return true if temporary
++ * Is this symbol a local variable stored in bytecode local variable slots? This is true for a slotted variable that
++ * is not in scope. (E.g. a parameter that is in scope is slotted, but it will not be a local variable).
++ * @return true if this symbol is using bytecode local slots for its storage.
+ */
+- public boolean isTemp() {
+- return (flags & KINDMASK) == IS_TEMP;
++ public boolean isBytecodeLocal() {
++ return hasSlot() && !isScope();
++ }
++
++ /**
++ * Returns true if this symbol is dead (it is a local variable that is statically proven to never be read in any type).
++ * @return true if this symbol is dead
++ */
++ public boolean isDead() {
++ return (flags & (HAS_SLOT | IS_SCOPE)) == 0;
+ }
+
+ /**
+@@ -349,16 +321,8 @@
+ * @return true if this is scoped
+ */
+ public boolean isScope() {
+- assert ((flags & KINDMASK) != IS_GLOBAL) || ((flags & IS_SCOPE) == IS_SCOPE) : "global without scope flag";
+- return (flags & IS_SCOPE) == IS_SCOPE;
+- }
+-
+- /**
+- * Returns true if this symbol is a temporary that is being shared across expressions.
+- * @return true if this symbol is a temporary that is being shared across expressions.
+- */
+- public boolean isShared() {
+- return (flags & IS_SHARED) == IS_SHARED;
++ assert (flags & KINDMASK) != IS_GLOBAL || (flags & IS_SCOPE) == IS_SCOPE : "global without scope flag";
++ return (flags & IS_SCOPE) != 0;
+ }
+
+ /**
+@@ -366,51 +330,34 @@
+ * @return true if a function declaration
+ */
+ public boolean isFunctionDeclaration() {
+- return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION;
+- }
+-
+- /**
+- * Creates an unshared copy of a symbol. The symbol must be currently shared.
+- * @param newName the name for the new symbol.
+- * @return a new, unshared symbol.
+- */
+- public Symbol createUnshared(final String newName) {
+- assert isShared();
+- return new Symbol(this, newName, flags & ~IS_SHARED);
++ return (flags & IS_FUNCTION_DECLARATION) != 0;
+ }
+
+ /**
+ * Flag this symbol as scope as described in {@link Symbol#isScope()}
++ * @return the symbol
+ */
+- /**
+- * Flag this symbol as scope as described in {@link Symbol#isScope()}
+- */
+- public void setIsScope() {
++ public Symbol setIsScope() {
+ if (!isScope()) {
+- trace("SET IS SCOPE");
+- assert !isShared();
++ if(shouldTrace()) {
++ trace("SET IS SCOPE");
++ }
+ flags |= IS_SCOPE;
++ if(!isParam()) {
++ flags &= ~HAS_SLOT;
++ }
+ }
++ return this;
+ }
+
+- /**
+- * Mark this symbol as one being shared by multiple expressions. The symbol must be a temporary.
+- */
+- public void setIsShared() {
+- if (!isShared()) {
+- assert isTemp();
+- trace("SET IS SHARED");
+- flags |= IS_SHARED;
+- }
+- }
+-
+-
+ /**
+ * Mark this symbol as a function declaration.
+ */
+ public void setIsFunctionDeclaration() {
+ if (!isFunctionDeclaration()) {
+- trace("SET IS FUNCTION DECLARATION");
++ if(shouldTrace()) {
++ trace("SET IS FUNCTION DECLARATION");
++ }
+ flags |= IS_FUNCTION_DECLARATION;
+ }
+ }
+@@ -440,92 +387,19 @@
+ }
+
+ /**
+- * Check if this symbol is always defined, which overrides all canBeUndefined tags
+- * @return true if always defined
++ * Check if this is a program (script) level definition
++ * @return true if program level
+ */
+- public boolean isAlwaysDefined() {
+- return isParam() || (flags & IS_ALWAYS_DEFINED) == IS_ALWAYS_DEFINED;
+- }
+-
+- /**
+- * Get the range for this symbol
+- * @return range for symbol
+- */
+- public Range getRange() {
+- return range;
+- }
+-
+- /**
+- * Set the range for this symbol
+- * @param range range
+- */
+- public void setRange(final Range range) {
+- this.range = range;
+- }
+-
+- /**
+- * Check if this symbol represents a return value with a known non-generic type.
+- * @return true if specialized return value
+- */
+- public boolean isNonGenericReturn() {
+- return getName().equals(RETURN.symbolName()) && type != Type.OBJECT;
+- }
+-
+- /**
+- * Check if this symbol is a function parameter of known
+- * narrowest type
+- * @return true if parameter
+- */
+- public boolean isSpecializedParam() {
+- return (flags & IS_SPECIALIZED_PARAM) == IS_SPECIALIZED_PARAM;
+- }
+-
+- /**
+- * Check whether this symbol ever has primitive assignments. Conservative
+- * @return true if primitive assignments exist
+- */
+- public boolean canBePrimitive() {
+- return (flags & CAN_BE_PRIMITIVE) == CAN_BE_PRIMITIVE;
+- }
+-
+- /**
+- * Check if this symbol can ever be undefined
+- * @return true if can be undefined
+- */
+- public boolean canBeUndefined() {
+- return (flags & CAN_BE_UNDEFINED) == CAN_BE_UNDEFINED;
+- }
+-
+- /**
+- * Flag this symbol as potentially undefined in parts of the program
+- */
+- public void setCanBeUndefined() {
+- assert type.isObject() : type;
+- if (isAlwaysDefined()) {
+- return;
+- } else if (!canBeUndefined()) {
+- assert !isShared();
+- flags |= CAN_BE_UNDEFINED;
+- }
+- }
+-
+- /**
+- * Flag this symbol as potentially primitive
+- * @param type the primitive type it occurs with, currently unused but can be used for width guesses
+- */
+- public void setCanBePrimitive(final Type type) {
+- if(!canBePrimitive()) {
+- assert !isShared();
+- flags |= CAN_BE_PRIMITIVE;
+- }
++ public boolean isProgramLevel() {
++ return (flags & IS_PROGRAM_LEVEL) != 0;
+ }
+
+ /**
+ * Check if this symbol is a constant
+ * @return true if a constant
+ */
+- public boolean isConstant() {
+- return (flags & KINDMASK) == IS_CONSTANT;
++ public boolean isConst() {
++ return (flags & IS_CONST) != 0;
+ }
+
+ /**
+@@ -550,17 +424,7 @@
+ * @return true if let
+ */
+ public boolean isLet() {
+- return (flags & IS_LET) == IS_LET;
+- }
+-
+- /**
+- * Flag this symbol as a let
+- */
+- public void setIsLet() {
+- if(!isLet()) {
+- assert !isShared();
+- flags |= IS_LET;
+- }
++ return (flags & IS_LET) != 0;
+ }
+
+ /**
+@@ -568,7 +432,32 @@
+ * @return true if this symbol as a function's self-referencing symbol.
+ */
+ public boolean isFunctionSelf() {
+- return (flags & IS_FUNCTION_SELF) == IS_FUNCTION_SELF;
++ return (flags & IS_FUNCTION_SELF) != 0;
++ }
++
++ /**
++ * Is this a block scoped symbol
++ * @return true if block scoped
++ */
++ public boolean isBlockScoped() {
++ return isLet() || isConst();
++ }
++
++ /**
++ * Has this symbol been declared
++ * @return true if declared
++ */
++ public boolean hasBeenDeclared() {
++ return (flags & HAS_BEEN_DECLARED) != 0;
++ }
++
++ /**
++ * Mark this symbol as declared
++ */
++ public void setHasBeenDeclared() {
++ if (!hasBeenDeclared()) {
++ flags |= HAS_BEEN_DECLARED;
++ }
+ }
+
+ /**
+@@ -587,12 +476,13 @@
+ * and get allocated in a JO-prefixed ScriptObject subclass.
+ *
+ * @param fieldIndex field index - a positive integer
++ * @return the symbol
+ */
+- public void setFieldIndex(final int fieldIndex) {
+- if(this.fieldIndex != fieldIndex) {
+- assert !isShared();
++ public Symbol setFieldIndex(final int fieldIndex) {
++ if (this.fieldIndex != fieldIndex) {
+ this.fieldIndex = fieldIndex;
+ }
++ return this;
+ }
+
+ /**
+@@ -606,12 +496,37 @@
+ /**
+ * Set the symbol flags
+ * @param flags flags
++ * @return the symbol
+ */
+- public void setFlags(final int flags) {
+- if(this.flags != flags) {
+- assert !isShared();
++ public Symbol setFlags(final int flags) {
++ if (this.flags != flags) {
+ this.flags = flags;
+ }
++ return this;
++ }
++
++ /**
++ * Set a single symbol flag
++ * @param flag flag to set
++ * @return the symbol
++ */
++ public Symbol setFlag(final int flag) {
++ if ((this.flags & flag) == 0) {
++ this.flags |= flag;
++ }
++ return this;
++ }
++
++ /**
++ * Clears a single symbol flag
++ * @param flag flag to set
++ * @return the symbol
++ */
++ public Symbol clearFlag(final int flag) {
++ if ((this.flags & flag) != 0) {
++ this.flags &= ~flag;
++ }
++ return this;
+ }
+
+ /**
+@@ -623,18 +538,82 @@
+ }
+
+ /**
+- * Get the byte code slot for this symbol
+- * @return byte code slot, or -1 if no slot allocated/possible
++ * Get the index of the first bytecode slot for this symbol
++ * @return byte code slot
+ */
+- public int getSlot() {
+- return slot;
++ public int getFirstSlot() {
++ assert isSlotted();
++ return firstSlot;
++ }
++
++ /**
++ * Get the index of the bytecode slot for this symbol for storing a value of the specified type.
++ * @param type the requested type
++ * @return byte code slot
++ */
++ public int getSlot(final Type type) {
++ assert isSlotted();
++ int typeSlot = firstSlot;
++ if(type.isBoolean() || type.isInteger()) {
++ assert (flags & HAS_INT_VALUE) != 0;
++ return typeSlot;
++ }
++ typeSlot += ((flags & HAS_INT_VALUE) == 0 ? 0 : 1);
++ if(type.isLong()) {
++ assert (flags & HAS_LONG_VALUE) != 0;
++ return typeSlot;
++ }
++ typeSlot += ((flags & HAS_LONG_VALUE) == 0 ? 0 : 2);
++ if(type.isNumber()) {
++ assert (flags & HAS_DOUBLE_VALUE) != 0;
++ return typeSlot;
++ }
++ assert type.isObject();
++ assert (flags & HAS_OBJECT_VALUE) != 0 : name;
++ return typeSlot + ((flags & HAS_DOUBLE_VALUE) == 0 ? 0 : 2);
++ }
++
++ /**
++ * Returns true if this symbol has a local variable slot for storing a value of specific type.
++ * @param type the type
++ * @return true if this symbol has a local variable slot for storing a value of specific type.
++ */
++ public boolean hasSlotFor(final Type type) {
++ if(type.isBoolean() || type.isInteger()) {
++ return (flags & HAS_INT_VALUE) != 0;
++ } else if(type.isLong()) {
++ return (flags & HAS_LONG_VALUE) != 0;
++ } else if(type.isNumber()) {
++ return (flags & HAS_DOUBLE_VALUE) != 0;
++ }
++ assert type.isObject();
++ return (flags & HAS_OBJECT_VALUE) != 0;
++ }
++
++ /**
++ * Marks this symbol as having a local variable slot for storing a value of specific type.
++ * @param type the type
++ */
++ public void setHasSlotFor(final Type type) {
++ if(type.isBoolean() || type.isInteger()) {
++ setFlag(HAS_INT_VALUE);
++ } else if(type.isLong()) {
++ setFlag(HAS_LONG_VALUE);
++ } else if(type.isNumber()) {
++ setFlag(HAS_DOUBLE_VALUE);
++ } else {
++ assert type.isObject();
++ setFlag(HAS_OBJECT_VALUE);
++ }
+ }
+
+ /**
+ * Increase the symbol's use count by one.
++ * @return the symbol
+ */
+- public void increaseUseCount() {
++ public Symbol increaseUseCount() {
+ useCount++;
++ return this;
+ }
+
+ /**
+@@ -647,76 +626,16 @@
+
+ /**
+ * Set the bytecode slot for this symbol
+- * @param slot valid bytecode slot, or -1 if not available
++ * @param firstSlot valid bytecode slot
++ * @return the symbol
+ */
+- public void setSlot(final int slot) {
+- if (slot != this.slot) {
+- assert !isShared();
+- trace("SET SLOT " + slot);
+- this.slot = slot;
+- }
+- }
+-
+- /**
+- * Assign a specific subclass of Object to the symbol
+- *
+- * @param type the type
+- */
+- public void setType(final Class<?> type) {
+- assert !type.isPrimitive() && !Number.class.isAssignableFrom(type) : "Class<?> types can only be subclasses of object";
+- setType(Type.typeFor(type));
+- }
+-
+- /**
+- * Assign a type to the symbol
+- *
+- * @param type the type
+- */
+- public void setType(final Type type) {
+- setTypeOverride(Type.widest(this.type, type));
+- }
+-
+- /**
+- * Returns true if calling {@link #setType(Type)} on this symbol would effectively change its type.
+- * @param newType the new type to test for
+- * @return true if setting this symbols type to a new value would effectively change its type.
+- */
+- public boolean wouldChangeType(final Type newType) {
+- return Type.widest(this.type, newType) != this.type;
+- }
+-
+- /**
+- * Only use this if you know about an existing type
+- * constraint - otherwise a type can only be
+- * widened
+- *
+- * @param type the type
+- */
+- public void setTypeOverride(final Type type) {
+- final Type old = this.type;
+- if (old != type) {
+- assert !isShared();
+- trace("TYPE CHANGE: " + old + "=>" + type + " == " + type);
+- this.type = type;
+- }
+- }
+-
+- /**
+- * Sets the type of the symbol to the specified type. If the type would be changed, but this symbol is a shared
+- * temporary, it will instead return a different temporary symbol of the requested type from the passed temporary
+- * symbols. That way, it never mutates the type of a shared temporary.
+- * @param type the new type for the symbol
+- * @param ts a holder of temporary symbols
+- * @return either this symbol, or a different symbol if this symbol is a shared temporary and it type would have to
+- * be changed.
+- */
+- public Symbol setTypeOverrideShared(final Type type, final TemporarySymbols ts) {
+- if(getSymbolType() != type) {
+- if(isShared()) {
+- assert !hasSlot();
+- return ts.getTypedTemporarySymbol(type);
++ public Symbol setFirstSlot(final int firstSlot) {
++ assert firstSlot >= 0 && firstSlot <= 65535;
++ if (firstSlot != this.firstSlot) {
++ if(shouldTrace()) {
++ trace("SET SLOT " + firstSlot);
+ }
+- setTypeOverride(type);
++ this.firstSlot = firstSlot;
+ }
+ return this;
+ }
+@@ -728,22 +647,26 @@
+ * when flags need to be tagged, but block is in the
+ * middle of evaluation and cannot be modified.
+ *
+- * @param lc lexical context
+- * @param symbol symbol
++ * @param lc lexical context
++ * @param symbol symbol
++ * @return the symbol
+ */
+- public static void setSymbolIsScope(final LexicalContext lc, final Symbol symbol) {
++ public static Symbol setSymbolIsScope(final LexicalContext lc, final Symbol symbol) {
+ symbol.setIsScope();
+ if (!symbol.isGlobal()) {
+ lc.setBlockNeedsScope(lc.getDefiningBlock(symbol));
+ }
++ return symbol;
++ }
++
++ private boolean shouldTrace() {
++ return TRACE_SYMBOLS != null && (TRACE_SYMBOLS.isEmpty() || TRACE_SYMBOLS.contains(name));
+ }
+
+ private void trace(final String desc) {
+- if (TRACE_SYMBOLS != null && (TRACE_SYMBOLS.isEmpty() || TRACE_SYMBOLS.contains(name))) {
+- Context.err(Debug.id(this) + " SYMBOL: '" + name + "' " + desc);
+- if (TRACE_SYMBOLS_STACKTRACE != null && (TRACE_SYMBOLS_STACKTRACE.isEmpty() || TRACE_SYMBOLS_STACKTRACE.contains(name))) {
+- new Throwable().printStackTrace(Context.getCurrentErr());
+- }
++ Context.err(Debug.id(this) + " SYMBOL: '" + name + "' " + desc);
++ if (TRACE_SYMBOLS_STACKTRACE != null && (TRACE_SYMBOLS_STACKTRACE.isEmpty() || TRACE_SYMBOLS_STACKTRACE.contains(name))) {
++ new Throwable().printStackTrace(Context.getCurrentErr());
+ }
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/TemporarySymbols.java Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,169 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 jdk.nashorn.internal.ir;
+-
+-import static jdk.nashorn.internal.codegen.CompilerConstants.TEMP_PREFIX;
+-import static jdk.nashorn.internal.ir.Symbol.IS_TEMP;
+-
+-import java.util.HashMap;
+-import java.util.Map;
+-import jdk.nashorn.internal.codegen.types.Type;
+-
+-/**
+- * Class that holds reusable temporary symbols by type.
+- *
+- */
+-public class TemporarySymbols {
+- private static final String prefix = TEMP_PREFIX.symbolName() + "$";
+-
+- private int totalSymbolCount;
+- private final Map<Type, TypedTemporarySymbols> temporarySymbolsByType = new HashMap<>();
+-
+- /**
+- * Associates a temporary symbol of a given type with a node, if the node doesn't already have any symbol.
+- * @param lc the current lexical context
+- * @param type the type of the temporary symbol
+- * @param node the node
+- * @return the node that is guaranteed to have a symbol.
+- */
+- public Expression ensureSymbol(final LexicalContext lc, final Type type, final Expression node) {
+- final Symbol symbol = node.getSymbol();
+- if (symbol != null) {
+- return node;
+- }
+- return node.setSymbol(lc, getTypedTemporarySymbol(type));
+- }
+-
+- /**
+- * Given a type, returns a temporary symbol of that type.
+- * @param type the required type of the symbol.
+- * @return a temporary symbol of the required type.
+- */
+- public Symbol getTypedTemporarySymbol(final Type type) {
+- return getTypedTemporarySymbols(type).getTemporarySymbol(type);
+- }
+-
+- private TypedTemporarySymbols getTypedTemporarySymbols(final Type type) {
+- TypedTemporarySymbols temporarySymbols = temporarySymbolsByType.get(type);
+- if(temporarySymbols == null) {
+- temporarySymbols = new TypedTemporarySymbols();
+- temporarySymbolsByType.put(type, temporarySymbols);
+- }
+- return temporarySymbols;
+- }
+-
+- /**
+- * This method is called to signal to this object that all the symbols it holds can be reused now.
+- */
+- public void reuse() {
+- for(TypedTemporarySymbols ts: temporarySymbolsByType.values()) {
+- ts.reuse();
+- }
+- }
+-
+- /**
+- * Given a shared symbol, creates an unshared copy of it with a unique name.
+- * @param symbol the shared symbol
+- * @return the unshared, uniquely named copy of the symbol
+- */
+- public Symbol createUnshared(Symbol symbol) {
+- return symbol.createUnshared(getUniqueName());
+- }
+-
+- private String getUniqueName() {
+- return prefix + (++totalSymbolCount);
+- }
+-
+- /**
+- * Returns the total number of symbols this object created during its lifetime.
+- * @return the total number of symbols this object created during its lifetime.
+- */
+- public int getTotalSymbolCount() {
+- return totalSymbolCount;
+- }
+-
+- private class TypedTemporarySymbols {
+- private Symbol[] symbols = new Symbol[16];
+- private int nextFreeSymbol = 0;
+- private int symbolCount = 0;
+-
+- Symbol getTemporarySymbol(final Type type) {
+- while(nextFreeSymbol < symbolCount) {
+- final Symbol nextSymbol = symbols[nextFreeSymbol];
+- assert nextSymbol != null;
+- // If it has a slot, we can't reuse it.
+- if(!nextSymbol.hasSlot()) {
+- final Type symbolType = nextSymbol.getSymbolType();
+- if(symbolType == type) {
+- assert nextSymbol.isTemp();
+- assert !nextSymbol.isScope();
+- // If types match, we can reuse it.
+- nextSymbol.setIsShared();
+- nextFreeSymbol++;
+- return nextSymbol;
+- }
+- // If its type changed, but it doesn't have a slot then move it to its new home according to its
+- // new type.
+- getTypedTemporarySymbols(symbolType).addSymbol(nextSymbol);
+- }
+- // If we can move another symbol into its place, do that and repeat the analysis for this symbol.
+- --symbolCount;
+- if(symbolCount != nextFreeSymbol) {
+- final Symbol lastFreeSymbol = symbols[symbolCount];
+- symbols[nextFreeSymbol] = lastFreeSymbol;
+- }
+- symbols[symbolCount] = null;
+- }
+- return createNewSymbol(type);
+- }
+-
+- private Symbol createNewSymbol(final Type type) {
+- ensureCapacity();
+- final Symbol symbol = symbols[nextFreeSymbol] = new Symbol(getUniqueName(), IS_TEMP, type);
+- nextFreeSymbol++;
+- symbolCount++;
+- return symbol;
+- }
+-
+- private void addSymbol(Symbol symbol) {
+- ensureCapacity();
+- symbols[symbolCount++] = symbol;
+- }
+-
+- void reuse() {
+- nextFreeSymbol = 0;
+- }
+-
+- private void ensureCapacity() {
+- if(symbolCount == symbols.length) {
+- final Symbol[] newSymbols = new Symbol[symbolCount * 2];
+- System.arraycopy(symbols, 0, newSymbols, 0, symbolCount);
+- symbols = newSymbols;
+- }
+- }
+- }
+-
+-}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/ir/Terminal.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.ir;
++
++/**
++ * Interface for AST nodes that can have a flag determining if they can terminate function control flow.
++ */
++public interface Terminal {
++ /**
++ * Returns true if this AST node is (or contains) a statement that terminates function control flow.
++ * @return true if this AST node is (or contains) a statement that terminates function control flow.
++ */
++ public boolean isTerminal();
++}
+--- ./nashorn/src/jdk/nashorn/internal/ir/TernaryNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/TernaryNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,20 +25,23 @@
+
+ package jdk.nashorn.internal.ir;
+
++import java.util.function.Function;
++import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++import jdk.nashorn.internal.parser.TokenType;
+
+ /**
+- * TernaryNode nodes represent three operand operations (?:).
++ * TernaryNode represent the ternary operator {@code ?:}. Note that for control-flow calculation reasons its branch
++ * expressions (but not its test expression) are always wrapped in instances of {@link JoinPredecessorExpression}.
+ */
+ @Immutable
+ public final class TernaryNode extends Expression {
++ private static final long serialVersionUID = 1L;
++
+ private final Expression test;
+-
+- private final Expression trueExpr;
+-
+- /** Third argument. */
+- private final Expression falseExpr;
++ private final JoinPredecessorExpression trueExpr;
++ private final JoinPredecessorExpression falseExpr;
+
+ /**
+ * Constructor
+@@ -48,14 +51,15 @@
+ * @param trueExpr expression evaluated when test evaluates to true
+ * @param falseExpr expression evaluated when test evaluates to true
+ */
+- public TernaryNode(final long token, final Expression test, final Expression trueExpr, final Expression falseExpr) {
++ public TernaryNode(final long token, final Expression test, final JoinPredecessorExpression trueExpr, final JoinPredecessorExpression falseExpr) {
+ super(token, falseExpr.getFinish());
+ this.test = test;
+ this.trueExpr = trueExpr;
+ this.falseExpr = falseExpr;
+ }
+
+- private TernaryNode(final TernaryNode ternaryNode, final Expression test, final Expression trueExpr, final Expression falseExpr) {
++ private TernaryNode(final TernaryNode ternaryNode, final Expression test, final JoinPredecessorExpression trueExpr,
++ final JoinPredecessorExpression falseExpr) {
+ super(ternaryNode);
+ this.test = test;
+ this.trueExpr = trueExpr;
+@@ -66,24 +70,25 @@
+ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
+ if (visitor.enterTernaryNode(this)) {
+ final Expression newTest = (Expression)getTest().accept(visitor);
+- final Expression newTrueExpr = (Expression)getTrueExpression().accept(visitor);
+- final Expression newFalseExpr = (Expression)falseExpr.accept(visitor);
+- return visitor.leaveTernaryNode(setTest(newTest).setTrueExpression(newTrueExpr).setFalseExpression1(newFalseExpr));
++ final JoinPredecessorExpression newTrueExpr = (JoinPredecessorExpression)trueExpr.accept(visitor);
++ final JoinPredecessorExpression newFalseExpr = (JoinPredecessorExpression)falseExpr.accept(visitor);
++ return visitor.leaveTernaryNode(setTest(newTest).setTrueExpression(newTrueExpr).setFalseExpression(newFalseExpr));
+ }
+
+ return this;
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
+- final boolean testParen = tokenType().needsParens(getTest().tokenType(), true);
+- final boolean trueParen = tokenType().needsParens(getTrueExpression().tokenType(), false);
+- final boolean falseParen = tokenType().needsParens(getFalseExpression().tokenType(), false);
++ public void toString(final StringBuilder sb, final boolean printType) {
++ final TokenType tokenType = tokenType();
++ final boolean testParen = tokenType.needsParens(getTest().tokenType(), true);
++ final boolean trueParen = tokenType.needsParens(getTrueExpression().tokenType(), false);
++ final boolean falseParen = tokenType.needsParens(getFalseExpression().tokenType(), false);
+
+ if (testParen) {
+ sb.append('(');
+ }
+- getTest().toString(sb);
++ getTest().toString(sb, printType);
+ if (testParen) {
+ sb.append(')');
+ }
+@@ -93,7 +98,7 @@
+ if (trueParen) {
+ sb.append('(');
+ }
+- getTrueExpression().toString(sb);
++ getTrueExpression().toString(sb, printType);
+ if (trueParen) {
+ sb.append(')');
+ }
+@@ -103,7 +108,7 @@
+ if (falseParen) {
+ sb.append('(');
+ }
+- getFalseExpression().toString(sb);
++ getFalseExpression().toString(sb, printType);
+ if (falseParen) {
+ sb.append(')');
+ }
+@@ -116,6 +121,12 @@
+ && getFalseExpression().isLocal();
+ }
+
++ @Override
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
++ return Type.widestReturnType(getTrueExpression().getType(localVariableTypes), getFalseExpression().getType(localVariableTypes));
++ }
++
++
+ /**
+ * Get the test expression for this ternary expression, i.e. "x" in x ? y : z
+ * @return the test expression
+@@ -128,7 +139,7 @@
+ * Get the true expression for this ternary expression, i.e. "y" in x ? y : z
+ * @return the true expression
+ */
+- public Expression getTrueExpression() {
++ public JoinPredecessorExpression getTrueExpression() {
+ return trueExpr;
+ }
+
+@@ -136,7 +147,7 @@
+ * Get the false expression for this ternary expression, i.e. "z" in x ? y : z
+ * @return the false expression
+ */
+- public Expression getFalseExpression() {
++ public JoinPredecessorExpression getFalseExpression() {
+ return falseExpr;
+ }
+
+@@ -157,7 +168,7 @@
+ * @param trueExpr new true expression
+ * @return a node equivalent to this one except for the requested change.
+ */
+- public TernaryNode setTrueExpression(final Expression trueExpr) {
++ public TernaryNode setTrueExpression(final JoinPredecessorExpression trueExpr) {
+ if (this.trueExpr == trueExpr) {
+ return this;
+ }
+@@ -169,7 +180,7 @@
+ * @param falseExpr new false expression
+ * @return a node equivalent to this one except for the requested change.
+ */
+- public TernaryNode setFalseExpression1(final Expression falseExpr) {
++ public TernaryNode setFalseExpression(final JoinPredecessorExpression falseExpr) {
+ if (this.falseExpr == falseExpr) {
+ return this;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -32,14 +32,15 @@
+ * IR representation for THROW statements.
+ */
+ @Immutable
+-public final class ThrowNode extends Statement {
++public final class ThrowNode extends Statement implements JoinPredecessor {
++ private static final long serialVersionUID = 1L;
++
+ /** Exception expression. */
+ private final Expression expression;
+
+- private final int flags;
++ private final LocalVariableConversion conversion;
+
+- /** Is this block a synthethic rethrow created by finally inlining? */
+- public static final int IS_SYNTHETIC_RETHROW = 1;
++ private final boolean isSyntheticRethrow;
+
+ /**
+ * Constructor
+@@ -48,18 +49,21 @@
+ * @param token token
+ * @param finish finish
+ * @param expression expression to throw
+- * @param flags flags
++ * @param isSyntheticRethrow true if this throw node is part of a synthetic rethrow.
+ */
+- public ThrowNode(final int lineNumber, final long token, final int finish, final Expression expression, final int flags) {
++ public ThrowNode(final int lineNumber, final long token, final int finish, final Expression expression, final boolean isSyntheticRethrow) {
+ super(lineNumber, token, finish);
+ this.expression = expression;
+- this.flags = flags;
++ this.isSyntheticRethrow = isSyntheticRethrow;
++ this.conversion = null;
+ }
+
+- private ThrowNode(final ThrowNode node, final Expression expression, final int flags) {
++ private ThrowNode(final ThrowNode node, final Expression expression, final boolean isSyntheticRethrow,
++ final LocalVariableConversion conversion) {
+ super(node);
+ this.expression = expression;
+- this.flags = flags;
++ this.isSyntheticRethrow = isSyntheticRethrow;
++ this.conversion = conversion;
+ }
+
+ @Override
+@@ -81,11 +85,14 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ sb.append("throw ");
+
+ if (expression != null) {
+- expression.toString(sb);
++ expression.toString(sb, printType);
++ }
++ if (conversion != null) {
++ conversion.toString(sb);
+ }
+ }
+
+@@ -106,7 +113,7 @@
+ if (this.expression == expression) {
+ return this;
+ }
+- return new ThrowNode(this, expression, flags);
++ return new ThrowNode(this, expression, isSyntheticRethrow, conversion);
+ }
+
+ /**
+@@ -116,7 +123,20 @@
+ * @return true if synthetic throw node
+ */
+ public boolean isSyntheticRethrow() {
+- return (flags & IS_SYNTHETIC_RETHROW) == IS_SYNTHETIC_RETHROW;
++ return isSyntheticRethrow;
++ }
++
++ @Override
++ public JoinPredecessor setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) {
++ if(this.conversion == conversion) {
++ return this;
++ }
++ return new ThrowNode(this, expression, isSyntheticRethrow, conversion);
++ }
++
++ @Override
++ public LocalVariableConversion getLocalVariableConversion() {
++ return conversion;
+ }
+
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/TryNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/TryNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,8 +28,6 @@
+ import java.util.ArrayList;
+ import java.util.Collections;
+ import java.util.List;
+-
+-import jdk.nashorn.internal.codegen.Label;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+
+@@ -37,7 +35,9 @@
+ * IR representation of a TRY statement.
+ */
+ @Immutable
+-public final class TryNode extends Statement {
++public final class TryNode extends Statement implements JoinPredecessor {
++ private static final long serialVersionUID = 1L;
++
+ /** Try statements. */
+ private final Block body;
+
+@@ -47,15 +47,14 @@
+ /** Finally clause. */
+ private final Block finallyBody;
+
+- /** Exit label. */
+- private final Label exit;
+-
+ /** Exception symbol. */
+ private Symbol exception;
+
+ /** Catchall exception for finally expansion, where applicable */
+ private Symbol finallyCatchAll;
+
++ private final LocalVariableConversion conversion;
++
+ /**
+ * Constructor
+ *
+@@ -71,21 +70,22 @@
+ this.body = body;
+ this.catchBlocks = catchBlocks;
+ this.finallyBody = finallyBody;
+- this.exit = new Label("exit");
++ this.conversion = null;
+ }
+
+- private TryNode(final TryNode tryNode, final Block body, final List<Block> catchBlocks, final Block finallyBody) {
++ private TryNode(final TryNode tryNode, final Block body, final List<Block> catchBlocks, final Block finallyBody, final LocalVariableConversion conversion) {
+ super(tryNode);
+ this.body = body;
+ this.catchBlocks = catchBlocks;
+ this.finallyBody = finallyBody;
+- this.exit = new Label(tryNode.exit);
++ this.conversion = conversion;
++ this.exception = tryNode.exception;
+ }
+
+ @Override
+ public Node ensureUniqueLabels(final LexicalContext lc) {
+ //try nodes are never in lex context
+- return new TryNode(this, body, catchBlocks, finallyBody);
++ return new TryNode(this, body, catchBlocks, finallyBody, conversion);
+ }
+
+ @Override
+@@ -114,8 +114,7 @@
+ return visitor.leaveTryNode(
+ setBody(newBody).
+ setFinallyBody(newFinallyBody).
+- setCatchBlocks(Node.accept(visitor, Block.class, catchBlocks)).
+- setException(exception).
++ setCatchBlocks(Node.accept(visitor, catchBlocks)).
+ setFinallyCatchAll(finallyCatchAll));
+ }
+
+@@ -123,7 +122,7 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ sb.append("try ");
+ }
+
+@@ -144,7 +143,7 @@
+ if (this.body == body) {
+ return this;
+ }
+- return new TryNode(this, body, catchBlocks, finallyBody);
++ return new TryNode(this, body, catchBlocks, finallyBody, conversion);
+ }
+
+ /**
+@@ -154,11 +153,15 @@
+ public List<CatchNode> getCatches() {
+ final List<CatchNode> catches = new ArrayList<>(catchBlocks.size());
+ for (final Block catchBlock : catchBlocks) {
+- catches.add((CatchNode)catchBlock.getStatements().get(0));
++ catches.add(getCatchNodeFromBlock(catchBlock));
+ }
+ return Collections.unmodifiableList(catches);
+ }
+
++ private static CatchNode getCatchNodeFromBlock(final Block catchBlock) {
++ return (CatchNode)catchBlock.getStatements().get(0);
++ }
++
+ /**
+ * Get the catch blocks for this try block
+ * @return a list of blocks
+@@ -176,7 +179,7 @@
+ if (this.catchBlocks == catchBlocks) {
+ return this;
+ }
+- return new TryNode(this, body, catchBlocks, finallyBody);
++ return new TryNode(this, body, catchBlocks, finallyBody, conversion);
+ }
+
+ /**
+@@ -186,7 +189,6 @@
+ public Symbol getException() {
+ return exception;
+ }
+-
+ /**
+ * Set the exception symbol for this try block
+ * @param exception a symbol for the compiler to store the exception in
+@@ -219,14 +221,6 @@
+ }
+
+ /**
+- * Get the exit label for this try block
+- * @return exit label
+- */
+- public Label getExit() {
+- return exit;
+- }
+-
+- /**
+ * Get the body of the finally clause for this try
+ * @return finally body, or null if no finally
+ */
+@@ -243,6 +237,19 @@
+ if (this.finallyBody == finallyBody) {
+ return this;
+ }
+- return new TryNode(this, body, catchBlocks, finallyBody);
++ return new TryNode(this, body, catchBlocks, finallyBody, conversion);
++ }
++
++ @Override
++ public JoinPredecessor setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) {
++ if(this.conversion == conversion) {
++ return this;
++ }
++ return new TryNode(this, body, catchBlocks, finallyBody, conversion);
++ }
++
++ @Override
++ public LocalVariableConversion getLocalVariableConversion() {
++ return conversion;
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,8 +28,14 @@
+ import static jdk.nashorn.internal.parser.TokenType.BIT_NOT;
+ import static jdk.nashorn.internal.parser.TokenType.DECPOSTFIX;
+ import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
+
++import java.util.Arrays;
++import java.util.Collections;
++import java.util.List;
++import java.util.function.Function;
+ import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.ir.annotations.Ignore;
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+ import jdk.nashorn.internal.parser.Token;
+@@ -39,9 +45,27 @@
+ * UnaryNode nodes represent single operand operations.
+ */
+ @Immutable
+-public final class UnaryNode extends Expression implements Assignment<Expression> {
++public final class UnaryNode extends Expression implements Assignment<Expression>, Optimistic {
++ private static final long serialVersionUID = 1L;
++
+ /** Right hand side argument. */
+- private final Expression rhs;
++ private final Expression expression;
++
++ private final int programPoint;
++
++ private final Type type;
++
++ @Ignore
++ private static final List<TokenType> CAN_OVERFLOW =
++ Collections.unmodifiableList(
++ Arrays.asList(new TokenType[] {
++ TokenType.ADD,
++ TokenType.SUB, //negate
++ TokenType.DECPREFIX,
++ TokenType.DECPOSTFIX,
++ TokenType.INCPREFIX,
++ TokenType.INCPOSTFIX,
++ }));
+
+ /**
+ * Constructor
+@@ -56,20 +80,24 @@
+ /**
+ * Constructor
+ *
+- * @param token token
+- * @param start start
+- * @param finish finish
+- * @param rhs expression
++ * @param token token
++ * @param start start
++ * @param finish finish
++ * @param expression expression
+ */
+- public UnaryNode(final long token, final int start, final int finish, final Expression rhs) {
++ public UnaryNode(final long token, final int start, final int finish, final Expression expression) {
+ super(token, start, finish);
+- this.rhs = rhs;
++ this.expression = expression;
++ this.programPoint = INVALID_PROGRAM_POINT;
++ this.type = null;
+ }
+
+
+- private UnaryNode(final UnaryNode unaryNode, final Expression rhs) {
++ private UnaryNode(final UnaryNode unaryNode, final Expression expression, final Type type, final int programPoint) {
+ super(unaryNode);
+- this.rhs = rhs;
++ this.expression = expression;
++ this.programPoint = programPoint;
++ this.type = type;
+ }
+
+ /**
+@@ -95,19 +123,53 @@
+ return isAssignment();
+ }
+
++ private static final Function<Symbol, Type> UNKNOWN_LOCALS = new Function<Symbol, Type>() {
++ @Override
++ public Type apply(final Symbol t) {
++ return null;
++ }
++ };
++
++
+ @Override
+ public Type getWidestOperationType() {
+- return isAssignment() ? Type.NUMBER : Type.OBJECT;
++ return getWidestOperationType(UNKNOWN_LOCALS);
++ }
++
++ private Type getWidestOperationType(final Function<Symbol, Type> localVariableTypes) {
++ switch (tokenType()) {
++ case ADD:
++ final Type operandType = getExpression().getType(localVariableTypes);
++ if(operandType == Type.BOOLEAN) {
++ return Type.INT;
++ } else if(operandType.isObject()) {
++ return Type.NUMBER;
++ }
++ assert operandType.isNumeric();
++ return operandType;
++ case SUB:
++ // This might seems overly conservative until you consider that -0 can only be represented as a double.
++ return Type.NUMBER;
++ case NOT:
++ case DELETE:
++ return Type.BOOLEAN;
++ case BIT_NOT:
++ return Type.INT;
++ case VOID:
++ return Type.UNDEFINED;
++ default:
++ return isAssignment() ? Type.NUMBER : Type.OBJECT;
++ }
+ }
+
+ @Override
+ public Expression getAssignmentDest() {
+- return isAssignment() ? rhs() : null;
++ return isAssignment() ? getExpression() : null;
+ }
+
+ @Override
+- public UnaryNode setAssignmentDest(Expression n) {
+- return setRHS(n);
++ public UnaryNode setAssignmentDest(final Expression n) {
++ return setExpression(n);
+ }
+
+ @Override
+@@ -122,7 +184,7 @@
+ @Override
+ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
+ if (visitor.enterUnaryNode(this)) {
+- return visitor.leaveUnaryNode(setRHS((Expression)rhs.accept(visitor)));
++ return visitor.leaveUnaryNode(setExpression((Expression)expression.accept(visitor)));
+ }
+
+ return this;
+@@ -131,31 +193,33 @@
+ @Override
+ public boolean isLocal() {
+ switch (tokenType()) {
+- case NEW:
+- return false;
+- case ADD:
+- case SUB:
+- case NOT:
+- case BIT_NOT:
+- return rhs.isLocal() && rhs.getType().isJSPrimitive();
+- case DECPOSTFIX:
+- case DECPREFIX:
+- case INCPOSTFIX:
+- case INCPREFIX:
+- return rhs instanceof IdentNode && rhs.isLocal() && rhs.getType().isJSPrimitive();
+- default:
+- return rhs.isLocal();
++ case NEW:
++ return false;
++ case ADD:
++ case SUB:
++ case NOT:
++ case BIT_NOT:
++ return expression.isLocal() && expression.getType().isJSPrimitive();
++ case DECPOSTFIX:
++ case DECPREFIX:
++ case INCPOSTFIX:
++ case INCPREFIX:
++ return expression instanceof IdentNode && expression.isLocal() && expression.getType().isJSPrimitive();
++ default:
++ return expression.isLocal();
+ }
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
+- toString(sb, new Runnable() {
+- @Override
+- public void run() {
+- sb.append(rhs().toString());
+- }
+- });
++ public void toString(final StringBuilder sb, final boolean printType) {
++ toString(sb,
++ new Runnable() {
++ @Override
++ public void run() {
++ getExpression().toString(sb, printType);
++ }
++ },
++ printType);
+ }
+
+ /**
+@@ -163,23 +227,27 @@
+ * operand to a specified runnable.
+ * @param sb the string builder to use
+ * @param rhsStringBuilder the runnable that appends the string representation of the operand to the string builder
++ * @param printType should we print type
+ * when invoked.
+ */
+- public void toString(final StringBuilder sb, final Runnable rhsStringBuilder) {
+- final TokenType type = tokenType();
+- final String name = type.getName();
+- final boolean isPostfix = type == DECPOSTFIX || type == INCPOSTFIX;
++ public void toString(final StringBuilder sb, final Runnable rhsStringBuilder, final boolean printType) {
++ final TokenType tokenType = tokenType();
++ final String name = tokenType.getName();
++ final boolean isPostfix = tokenType == DECPOSTFIX || tokenType == INCPOSTFIX;
+
+- boolean rhsParen = type.needsParens(rhs().tokenType(), false);
++ if (isOptimistic()) {
++ sb.append(Expression.OPT_IDENTIFIER);
++ }
++ boolean rhsParen = tokenType.needsParens(getExpression().tokenType(), false);
+
+ if (!isPostfix) {
+ if (name == null) {
+- sb.append(type.name());
++ sb.append(tokenType.name());
+ rhsParen = true;
+ } else {
+ sb.append(name);
+
+- if (type.ordinal() > BIT_NOT.ordinal()) {
++ if (tokenType.ordinal() > BIT_NOT.ordinal()) {
+ sb.append(' ');
+ }
+ }
+@@ -194,7 +262,7 @@
+ }
+
+ if (isPostfix) {
+- sb.append(type == DECPOSTFIX ? "--" : "++");
++ sb.append(tokenType == DECPOSTFIX ? "--" : "++");
+ }
+ }
+
+@@ -206,8 +274,8 @@
+ *
+ * @return right hand side or expression node
+ */
+- public Expression rhs() {
+- return rhs;
++ public Expression getExpression() {
++ return expression;
+ }
+
+ /**
+@@ -216,13 +284,62 @@
+ *
+ * @see BinaryNode
+ *
+- * @param rhs right hand side or expression node
++ * @param expression right hand side or expression node
+ * @return a node equivalent to this one except for the requested change.
+ */
+- public UnaryNode setRHS(final Expression rhs) {
+- if (this.rhs == rhs) {
++ public UnaryNode setExpression(final Expression expression) {
++ if (this.expression == expression) {
+ return this;
+ }
+- return new UnaryNode(this, rhs);
++ return new UnaryNode(this, expression, type, programPoint);
+ }
++
++ @Override
++ public int getProgramPoint() {
++ return programPoint;
++ }
++
++ @Override
++ public UnaryNode setProgramPoint(final int programPoint) {
++ if (this.programPoint == programPoint) {
++ return this;
++ }
++ return new UnaryNode(this, expression, type, programPoint);
++ }
++
++ @Override
++ public boolean canBeOptimistic() {
++ return getMostOptimisticType() != getMostPessimisticType();
++ }
++
++ @Override
++ public Type getMostOptimisticType() {
++ if (CAN_OVERFLOW.contains(tokenType())) {
++ return Type.INT;
++ }
++ return getMostPessimisticType();
++ }
++
++ @Override
++ public Type getMostPessimisticType() {
++ return getWidestOperationType();
++ }
++
++ @Override
++ public Type getType(final Function<Symbol, Type> localVariableTypes) {
++ final Type widest = getWidestOperationType(localVariableTypes);
++ if(type == null) {
++ return widest;
++ }
++ return Type.narrowest(widest, Type.widest(type, expression.getType(localVariableTypes)));
++ }
++
++ @Override
++ public UnaryNode setType(final Type type) {
++ if (this.type == type) {
++ return this;
++ }
++ return new UnaryNode(this, expression, type, programPoint);
++ }
++
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/VarNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/VarNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,12 +27,15 @@
+
+ import jdk.nashorn.internal.ir.annotations.Immutable;
+ import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++import jdk.nashorn.internal.parser.Token;
+
+ /**
+ * Node represents a var/let declaration.
+ */
+ @Immutable
+ public final class VarNode extends Statement implements Assignment<IdentNode> {
++ private static final long serialVersionUID = 1L;
++
+ /** Var name. */
+ private final IdentNode name;
+
+@@ -42,13 +45,16 @@
+ /** Is this a var statement (as opposed to a "var" in a for loop statement) */
+ private final int flags;
+
+- /** Flag that determines if this function node is a statement */
+- public static final int IS_STATEMENT = 1 << 0;
++ /** Flag for ES6 LET declaration */
++ public static final int IS_LET = 1 << 0;
++
++ /** Flag for ES6 CONST declaration */
++ public static final int IS_CONST = 1 << 1;
+
+ /** Flag that determines if this is the last function declaration in a function
+ * This is used to micro optimize the placement of return value assignments for
+ * a program node */
+- public static final int IS_LAST_FUNCTION_DECLARATION = 1 << 1;
++ public static final int IS_LAST_FUNCTION_DECLARATION = 1 << 2;
+
+ /**
+ * Constructor
+@@ -60,7 +66,7 @@
+ * @param init init node or null if just a declaration
+ */
+ public VarNode(final int lineNumber, final long token, final int finish, final IdentNode name, final Expression init) {
+- this(lineNumber, token, finish, name, init, IS_STATEMENT);
++ this(lineNumber, token, finish, name, init, 0);
+ }
+
+ private VarNode(final VarNode varNode, final IdentNode name, final Expression init, final int flags) {
+@@ -99,7 +105,7 @@
+ }
+
+ @Override
+- public VarNode setAssignmentDest(IdentNode n) {
++ public VarNode setAssignmentDest(final IdentNode n) {
+ return setName(n);
+ }
+
+@@ -109,6 +115,43 @@
+ }
+
+ /**
++ * Is this a VAR node block scoped? This returns true for ECMAScript 6 LET and CONST nodes.
++ * @return true if an ES6 LET or CONST node
++ */
++ public boolean isBlockScoped() {
++ return getFlag(IS_LET) || getFlag(IS_CONST);
++ }
++
++ /**
++ * Is this an ECMAScript 6 LET node?
++ * @return true if LET node
++ */
++ public boolean isLet() {
++ return getFlag(IS_LET);
++ }
++
++ /**
++ * Is this an ECMAScript 6 CONST node?
++ * @return true if CONST node
++ */
++ public boolean isConst() {
++ return getFlag(IS_CONST);
++ }
++
++ /**
++ * Return the flags to use for symbols for this declaration.
++ * @return the symbol flags
++ */
++ public int getSymbolFlags() {
++ if (isLet()) {
++ return Symbol.IS_VAR | Symbol.IS_LET;
++ } else if (isConst()) {
++ return Symbol.IS_VAR | Symbol.IS_CONST;
++ }
++ return Symbol.IS_VAR;
++ }
++
++ /**
+ * Does this variable declaration have an init value
+ * @return true if an init exists, false otherwise
+ */
+@@ -123,8 +166,9 @@
+ @Override
+ public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
+ if (visitor.enterVarNode(this)) {
++ // var is right associative, so visit init before name
++ final Expression newInit = init == null ? null : (Expression)init.accept(visitor);
+ final IdentNode newName = (IdentNode)name.accept(visitor);
+- final Expression newInit = init == null ? null : (Expression)init.accept(visitor);
+ final VarNode newThis;
+ if (name != newName || init != newInit) {
+ newThis = new VarNode(this, newName, newInit, flags);
+@@ -137,13 +181,13 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
+- sb.append("var ");
+- name.toString(sb);
++ public void toString(final StringBuilder sb, final boolean printType) {
++ sb.append(Token.descType(getToken()).getName()).append(' ');
++ name.toString(sb, printType);
+
+ if (init != null) {
+ sb.append(" = ");
+- init.toString(sb);
++ init.toString(sb, printType);
+ }
+ }
+
+@@ -213,18 +257,18 @@
+ }
+
+ /**
+- * Returns true if this is a var statement (as opposed to a var initializer in a for loop).
+- * @return true if this is a var statement (as opposed to a var initializer in a for loop).
+- */
+- public boolean isStatement() {
+- return (flags & IS_STATEMENT) != 0;
+- }
+-
+- /**
+ * Returns true if this is a function declaration.
+ * @return true if this is a function declaration.
+ */
+ public boolean isFunctionDeclaration() {
+ return init instanceof FunctionNode && ((FunctionNode)init).isDeclared();
+ }
++
++ /**
++ * Returns true if this is an anonymous function declaration.
++ * @return true if this is an anonymous function declaration.
++ */
++ public boolean isAnonymousFunctionDeclaration() {
++ return isFunctionDeclaration() && ((FunctionNode)init).isAnonymous();
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/WhileNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/WhileNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -34,6 +34,8 @@
+ */
+ @Immutable
+ public final class WhileNode extends LoopNode {
++ private static final long serialVersionUID = 1L;
++
+
+ /** is this a do while node ? */
+ private final boolean isDoWhile;
+@@ -47,7 +49,7 @@
+ * @param isDoWhile is this a do while loop?
+ */
+ public WhileNode(final int lineNumber, final long token, final int finish, final boolean isDoWhile) {
+- super(lineNumber, token, finish, null, null, false);
++ super(lineNumber, token, finish, null, false);
+ this.isDoWhile = isDoWhile;
+ }
+
+@@ -58,15 +60,16 @@
+ * @param test test
+ * @param body body
+ * @param controlFlowEscapes control flow escapes?
++ * @param conversion TODO
+ */
+- protected WhileNode(final WhileNode whileNode, final Expression test, final Block body, final boolean controlFlowEscapes) {
+- super(whileNode, test, body, controlFlowEscapes);
++ private WhileNode(final WhileNode whileNode, final JoinPredecessorExpression test, final Block body, final boolean controlFlowEscapes, final LocalVariableConversion conversion) {
++ super(whileNode, test, body, controlFlowEscapes, conversion);
+ this.isDoWhile = whileNode.isDoWhile;
+ }
+
+ @Override
+ public Node ensureUniqueLabels(final LexicalContext lc) {
+- return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes));
++ return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes, conversion));
+ }
+
+ @Override
+@@ -80,26 +83,21 @@
+ if (isDoWhile()) {
+ return visitor.leaveWhileNode(
+ setBody(lc, (Block)body.accept(visitor)).
+- setTest(lc, (Expression)test.accept(visitor)));
++ setTest(lc, (JoinPredecessorExpression)test.accept(visitor)));
+ }
+ return visitor.leaveWhileNode(
+- setTest(lc, (Expression)test.accept(visitor)).
++ setTest(lc, (JoinPredecessorExpression)test.accept(visitor)).
+ setBody(lc, (Block)body.accept(visitor)));
+ }
+ return this;
+ }
+
+ @Override
+- public Expression getTest() {
+- return test;
+- }
+-
+- @Override
+- public WhileNode setTest(final LexicalContext lc, final Expression test) {
++ public WhileNode setTest(final LexicalContext lc, final JoinPredecessorExpression test) {
+ if (this.test == test) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes));
++ return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes, conversion));
+ }
+
+ @Override
+@@ -112,7 +110,7 @@
+ if (this.body == body) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes));
++ return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes, conversion));
+ }
+
+ @Override
+@@ -120,7 +118,12 @@
+ if (this.controlFlowEscapes == controlFlowEscapes) {
+ return this;
+ }
+- return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes));
++ return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes, conversion));
++ }
++
++ @Override
++ JoinPredecessor setLocalVariableConversionChanged(final LexicalContext lc, final LocalVariableConversion conversion) {
++ return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes, conversion));
+ }
+
+ /**
+@@ -132,9 +135,9 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ sb.append("while (");
+- test.toString(sb);
++ test.toString(sb, printType);
+ sb.append(')');
+ }
+
+@@ -145,4 +148,9 @@
+ }
+ return test == null;
+ }
++
++ @Override
++ public boolean hasPerIterationScope() {
++ return false;
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/ir/WithNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/WithNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -33,6 +33,8 @@
+ */
+ @Immutable
+ public final class WithNode extends LexicalContextStatement {
++ private static final long serialVersionUID = 1L;
++
+ /** This expression. */
+ private final Expression expression;
+
+@@ -79,9 +81,9 @@
+ }
+
+ @Override
+- public void toString(final StringBuilder sb) {
++ public void toString(final StringBuilder sb, final boolean printType) {
+ sb.append("with (");
+- expression.toString(sb);
++ expression.toString(sb, printType);
+ sb.append(')');
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/ir/debug/ASTWriter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/debug/ASTWriter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -36,8 +36,11 @@
+ import jdk.nashorn.internal.ir.BinaryNode;
+ import jdk.nashorn.internal.ir.Block;
+ import jdk.nashorn.internal.ir.Expression;
++import jdk.nashorn.internal.ir.IdentNode;
+ import jdk.nashorn.internal.ir.Node;
++import jdk.nashorn.internal.ir.Statement;
+ import jdk.nashorn.internal.ir.Symbol;
++import jdk.nashorn.internal.ir.Terminal;
+ import jdk.nashorn.internal.ir.TernaryNode;
+ import jdk.nashorn.internal.ir.annotations.Ignore;
+ import jdk.nashorn.internal.ir.annotations.Reference;
+@@ -104,23 +107,31 @@
+
+ final boolean isReference = field != null && field.isAnnotationPresent(Reference.class);
+
+- Class<?> clazz = node.getClass();
++ final Class<?> clazz = node.getClass();
+ String type = clazz.getName();
+
+ type = type.substring(type.lastIndexOf('.') + 1, type.length());
++ int truncate = type.indexOf("Node");
++ if (truncate == -1) {
++ truncate = type.indexOf("Statement");
++ }
++ if (truncate != -1) {
++ type = type.substring(0, truncate);
++ }
++ type = type.toLowerCase();
++
+ if (isReference) {
+ type = "ref: " + type;
+ }
+- type += "@" + Debug.id(node);
+ final Symbol symbol;
+- if(node instanceof Expression) {
+- symbol = ((Expression)node).getSymbol();
++ if (node instanceof IdentNode) {
++ symbol = ((IdentNode)node).getSymbol();
+ } else {
+ symbol = null;
+ }
+
+ if (symbol != null) {
+- type += "#" + symbol;
++ type += ">" + symbol;
+ }
+
+ if (node instanceof Block && ((Block)node).needsScope()) {
+@@ -135,11 +146,11 @@
+
+ String status = "";
+
+- if (node.isTerminal()) {
++ if (node instanceof Terminal && ((Terminal)node).isTerminal()) {
+ status += " Terminal";
+ }
+
+- if (node.hasGoto()) {
++ if (node instanceof Statement && ((Statement)node).hasGoto()) {
+ status += " Goto ";
+ }
+
+@@ -160,6 +171,8 @@
+ status += " (" + tname + ")";
+ }
+
++ status += " @" + Debug.id(node);
++
+ if (children.isEmpty()) {
+ sb.append("[").
+ append(type).
+@@ -200,7 +213,7 @@
+ } else if (value instanceof Collection) {
+ int pos = 0;
+ ASTWriter.indent(sb, indent + 1);
+- sb.append("[Collection ").
++ sb.append('[').
+ append(child.getName()).
+ append("[0..").
+ append(((Collection<Node>)value).size()).
+--- ./nashorn/src/jdk/nashorn/internal/ir/debug/ClassHistogramElement.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/debug/ClassHistogramElement.java Wed Feb 04 12:14:47 2015 -0800
+@@ -30,7 +30,7 @@
+ /**
+ * Class histogram element for IR / Java object instrumentation
+ */
+-public class ClassHistogramElement {
++public final class ClassHistogramElement {
+ /**
+ * Instance comparator
+ */
+--- ./nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,10 +27,9 @@
+
+ import static jdk.nashorn.internal.runtime.Source.sourceFor;
+
++import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.List;
+-import java.util.ArrayList;
+-import jdk.nashorn.internal.codegen.CompilerConstants;
+ import jdk.nashorn.internal.ir.AccessNode;
+ import jdk.nashorn.internal.ir.BinaryNode;
+ import jdk.nashorn.internal.ir.Block;
+@@ -41,12 +40,14 @@
+ import jdk.nashorn.internal.ir.CatchNode;
+ import jdk.nashorn.internal.ir.ContinueNode;
+ import jdk.nashorn.internal.ir.EmptyNode;
++import jdk.nashorn.internal.ir.Expression;
+ import jdk.nashorn.internal.ir.ExpressionStatement;
+ import jdk.nashorn.internal.ir.ForNode;
+ import jdk.nashorn.internal.ir.FunctionNode;
+ import jdk.nashorn.internal.ir.IdentNode;
+ import jdk.nashorn.internal.ir.IfNode;
+ import jdk.nashorn.internal.ir.IndexNode;
++import jdk.nashorn.internal.ir.JoinPredecessorExpression;
+ import jdk.nashorn.internal.ir.LabelNode;
+ import jdk.nashorn.internal.ir.LexicalContext;
+ import jdk.nashorn.internal.ir.LiteralNode;
+@@ -72,7 +73,6 @@
+ import jdk.nashorn.internal.parser.TokenType;
+ import jdk.nashorn.internal.runtime.Context;
+ import jdk.nashorn.internal.runtime.ParserException;
+-import jdk.nashorn.internal.runtime.ScriptEnvironment;
+ import jdk.nashorn.internal.runtime.Source;
+
+ /**
+@@ -83,17 +83,17 @@
+ /**
+ * Returns AST as JSON compatible string.
+ *
+- * @param env script environment to use
++ * @param context context
+ * @param code code to be parsed
+ * @param name name of the code source (used for location)
+ * @param includeLoc tells whether to include location information for nodes or not
+ * @return JSON string representation of AST of the supplied code
+ */
+- public static String parse(final ScriptEnvironment env, final String code, final String name, final boolean includeLoc) {
+- final Parser parser = new Parser(env, sourceFor(name, code), new Context.ThrowErrorManager(), env._strict);
++ public static String parse(final Context context, final String code, final String name, final boolean includeLoc) {
++ final Parser parser = new Parser(context.getEnv(), sourceFor(name, code), new Context.ThrowErrorManager(), context.getEnv()._strict, context.getLogger(Parser.class));
+ final JSONWriter jsonWriter = new JSONWriter(includeLoc);
+ try {
+- final FunctionNode functionNode = parser.parse(CompilerConstants.RUN_SCRIPT.symbolName());
++ final FunctionNode functionNode = parser.parse(); //symbol name is ":program", default
+ functionNode.accept(jsonWriter);
+ return jsonWriter.getString();
+ } catch (final ParserException e) {
+@@ -103,6 +103,17 @@
+ }
+
+ @Override
++ public boolean enterJoinPredecessorExpression(final JoinPredecessorExpression joinPredecessorExpression) {
++ final Expression expr = joinPredecessorExpression.getExpression();
++ if(expr != null) {
++ expr.accept(this);
++ } else {
++ nullValue();
++ }
++ return false;
++ }
++
++ @Override
+ protected boolean enterDefault(final Node node) {
+ objectStart();
+ location(node);
+@@ -132,8 +143,7 @@
+ accessNode.getBase().accept(this);
+ comma();
+
+- property("property");
+- accessNode.getProperty().accept(this);
++ property("property", accessNode.getProperty());
+ comma();
+
+ property("computed", false);
+@@ -153,16 +163,6 @@
+ return leave();
+ }
+
+- private static boolean isLogical(final TokenType tt) {
+- switch (tt) {
+- case AND:
+- case OR:
+- return true;
+- default:
+- return false;
+- }
+- }
+-
+ @Override
+ public boolean enterBinaryNode(final BinaryNode binaryNode) {
+ enterDefault(binaryNode);
+@@ -170,7 +170,7 @@
+ final String name;
+ if (binaryNode.isAssignment()) {
+ name = "AssignmentExpression";
+- } else if (isLogical(binaryNode.tokenType())) {
++ } else if (binaryNode.isLogical()) {
+ name = "LogicalExpression";
+ } else {
+ name = "BinaryExpression";
+@@ -199,11 +199,11 @@
+ type("BreakStatement");
+ comma();
+
+- final IdentNode label = breakNode.getLabel();
+- property("label");
+- if (label != null) {
+- label.accept(this);
++ final String label = breakNode.getLabelName();
++ if(label != null) {
++ property("label", label);
+ } else {
++ property("label");
+ nullValue();
+ }
+
+@@ -278,11 +278,11 @@
+ type("ContinueStatement");
+ comma();
+
+- final IdentNode label = continueNode.getLabel();
+- property("label");
+- if (label != null) {
+- label.accept(this);
++ final String label = continueNode.getLabelName();
++ if(label != null) {
++ property("label", label);
+ } else {
++ property("label");
+ nullValue();
+ }
+
+@@ -319,7 +319,7 @@
+ }
+
+ @Override
+- public boolean enterBlockStatement(BlockStatement blockStatement) {
++ public boolean enterBlockStatement(final BlockStatement blockStatement) {
+ enterDefault(blockStatement);
+
+ type("BlockStatement");
+@@ -339,13 +339,13 @@
+ type("ForInStatement");
+ comma();
+
+- Node init = forNode.getInit();
++ final Node init = forNode.getInit();
+ assert init != null;
+ property("left");
+ init.accept(this);
+ comma();
+
+- Node modify = forNode.getModify();
++ final Node modify = forNode.getModify();
+ assert modify != null;
+ property("right");
+ modify.accept(this);
+@@ -535,8 +535,7 @@
+ type("LabeledStatement");
+ comma();
+
+- property("label");
+- labelNode.getLabel().accept(this);
++ property("label", labelNode.getLabelName());
+ comma();
+
+ property("body");
+@@ -762,8 +761,8 @@
+ final List<CatchNode> guarded = new ArrayList<>();
+ CatchNode unguarded = null;
+ if (catches != null) {
+- for (Node n : catches) {
+- CatchNode cn = (CatchNode)n;
++ for (final Node n : catches) {
++ final CatchNode cn = (CatchNode)n;
+ if (cn.getExceptionCondition() != null) {
+ guarded.add(cn);
+ } else {
+@@ -804,7 +803,7 @@
+ type("NewExpression");
+ comma();
+
+- final CallNode callNode = (CallNode)unaryNode.rhs();
++ final CallNode callNode = (CallNode)unaryNode.getExpression();
+ property("callee");
+ callNode.getFunction().accept(this);
+ comma();
+@@ -846,7 +845,7 @@
+ comma();
+
+ property("argument");
+- unaryNode.rhs().accept(this);
++ unaryNode.getExpression().accept(this);
+ }
+
+ return leave();
+@@ -959,9 +958,13 @@
+ buf.append(key);
+ buf.append("\":");
+ if (value != null) {
+- if (escape) buf.append('"');
++ if (escape) {
++ buf.append('"');
++ }
+ buf.append(value);
+- if (escape) buf.append('"');
++ if (escape) {
++ buf.append('"');
++ }
+ }
+ }
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/ir/debug/NashornClassReader.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,551 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.ir.debug;
++
++import java.util.ArrayList;
++import java.util.HashMap;
++import java.util.List;
++import java.util.Map;
++import jdk.internal.org.objectweb.asm.Attribute;
++import jdk.internal.org.objectweb.asm.ClassReader;
++import jdk.internal.org.objectweb.asm.ClassVisitor;
++import jdk.internal.org.objectweb.asm.Label;
++import jdk.nashorn.internal.ir.debug.NashornTextifier.NashornLabel;
++
++/**
++ * Subclass of the ASM classs reader that retains more info, such
++ * as bytecode offsets
++ */
++public class NashornClassReader extends ClassReader {
++
++ private final Map<String, List<Label>> labelMap = new HashMap<>();
++
++ /**
++ * Constructor
++ * @param bytecode bytecode for class
++ */
++ public NashornClassReader(final byte[] bytecode) {
++ super(bytecode);
++ parse(bytecode);
++ }
++
++ List<Label> getExtraLabels(final String className, final String methodName, final String methodDesc) {
++ final String key = fullyQualifiedName(className, methodName, methodDesc);
++ return labelMap.get(key);
++ }
++
++ private static int readByte(final byte[] bytecode, final int index) {
++ return (byte)(bytecode[index] & 0xff);
++ }
++
++ private static int readShort(final byte[] bytecode, final int index) {
++ return (short)((bytecode[index] & 0xff) << 8) | (bytecode[index + 1] & 0xff);
++ }
++
++ private static int readInt(final byte[] bytecode, final int index) {
++ return ((bytecode[index] & 0xff) << 24) | ((bytecode[index + 1] & 0xff) << 16) | ((bytecode[index + 2] & 0xff) << 8) | (bytecode[index + 3] & 0xff);
++ }
++
++ private static long readLong(final byte[] bytecode, final int index) {
++ final int hi = readInt(bytecode, index);
++ final int lo = readInt(bytecode, index + 4);
++ return ((long)hi << 32) | lo;
++ }
++
++ private static String readUTF(final int index, final int utfLen, final byte[] bytecode) {
++ final int endIndex = index + utfLen;
++ final char buf[] = new char[utfLen * 2];
++ int strLen = 0;
++ int c;
++ int st = 0;
++ char cc = 0;
++ int i = index;
++
++ while (i < endIndex) {
++ c = bytecode[i++];
++ switch (st) {
++ case 0:
++ c = c & 0xFF;
++ if (c < 0x80) { // 0xxxxxxx
++ buf[strLen++] = (char) c;
++ } else if (c < 0xE0 && c > 0xBF) { // 110x xxxx 10xx xxxx
++ cc = (char) (c & 0x1F);
++ st = 1;
++ } else { // 1110 xxxx 10xx xxxx 10xx xxxx
++ cc = (char) (c & 0x0F);
++ st = 2;
++ }
++ break;
++
++ case 1: // byte 2 of 2-byte char or byte 3 of 3-byte char
++ buf[strLen++] = (char) ((cc << 6) | (c & 0x3F));
++ st = 0;
++ break;
++
++ case 2: // byte 2 of 3-byte char
++ cc = (char) ((cc << 6) | (c & 0x3F));
++ st = 1;
++ break;
++
++ default:
++ break;
++ }
++ }
++ return new String(buf, 0, strLen);
++ }
++
++ private String parse(final byte[] bytecode) {
++ String thisClassName;
++
++ int u = 0;
++
++ final int magic = readInt(bytecode, u);
++ u += 4; //magic
++ assert magic == 0xcafebabe : Integer.toHexString(magic);
++ readShort(bytecode, u); //minor
++ u += 2;
++ readShort(bytecode, u); //major
++ u += 2; //minor
++
++ final int cpc = readShort(bytecode, u);
++ u += 2;
++ final ArrayList<Constant> cp = new ArrayList<>(cpc);
++ cp.add(null);
++
++ for (int i = 1; i < cpc; i++) {
++ //constant pool entries
++ final int tag = readByte(bytecode, u);
++ u += 1;
++ switch (tag) {
++ case 7: //class
++ cp.add(new IndexInfo(cp, tag, readShort(bytecode, u)));
++ u += 2;
++ break;
++ case 9: //fieldref
++ case 10: //methodref
++ case 11: //interfacemethodref
++ cp.add(new IndexInfo2(cp, tag, readShort(bytecode, u), readShort(bytecode, u + 2)));
++ u += 4;
++ break;
++ case 8: //string
++ cp.add(new IndexInfo(cp, tag, readShort(bytecode, u))); //string index
++ u += 2;
++ break;
++ case 3: //int
++ cp.add(new DirectInfo<>(cp, tag, readInt(bytecode, u)));
++ u += 4;
++ break;
++ case 4: //float
++ cp.add(new DirectInfo<>(cp, tag, Float.intBitsToFloat(readInt(bytecode, u))));
++ u += 4;
++ break;
++ case 5: //long
++ cp.add(new DirectInfo<>(cp, tag, readLong(bytecode, u)));
++ cp.add(null);
++ i++;
++ u += 8;
++ break;
++ case 6: //double
++ cp.add(new DirectInfo<>(cp, tag, Double.longBitsToDouble(readLong(bytecode, u))));
++ cp.add(null);
++ i++;
++ u += 8;
++ break;
++ case 12: //name and type
++ cp.add(new IndexInfo2(cp, tag, readShort(bytecode, u), readShort(bytecode, u + 2)));
++ u += 4;
++ break;
++ case 1: //utf8
++ final int len = readShort(bytecode, u);
++ u += 2;
++ cp.add(new DirectInfo<>(cp, tag, readUTF(u, len, bytecode)));
++ u += len;
++ break;
++ case 16: //methodtype
++ cp.add(new IndexInfo(cp, tag, readShort(bytecode, u)));
++ u += 2;
++ break;
++ case 18: //indy
++ cp.add(new IndexInfo2(cp, tag, readShort(bytecode, u), readShort(bytecode, u + 2)) {
++ @Override
++ public String toString() {
++ return "#" + index + ' ' + cp.get(index2).toString();
++ }
++
++ });
++ u += 4;
++ break;
++ case 15: //methodhandle
++ final int kind = readByte(bytecode, u);
++ assert kind >= 1 && kind <= 9 : kind;
++ cp.add(new IndexInfo2(cp, tag, kind, readShort(bytecode, u + 1)) {
++ @Override
++ public String toString() {
++ return "#" + index + ' ' + cp.get(index2).toString();
++ }
++ });
++
++ u += 3;
++ break;
++ default:
++ assert false : tag;
++ break;
++ }
++ }
++
++ readShort(bytecode, u); //access flags
++ u += 2; //access
++ final int cls = readShort(bytecode, u);
++ u += 2; //this_class
++ thisClassName = cp.get(cls).toString();
++ u += 2; //super
++
++ final int ifc = readShort(bytecode, u);
++ u += 2;
++ u += ifc * 2;
++
++ final int fc = readShort(bytecode, u);
++ u += 2; //fields
++
++ for (int i = 0 ; i < fc ; i++) {
++ u += 2; //access
++ readShort(bytecode, u); //fieldname
++ u += 2; //name
++ u += 2; //descriptor
++ final int ac = readShort(bytecode, u);
++ u += 2;
++ //field attributes
++ for (int j = 0; j < ac; j++) {
++ u += 2; //attribute name
++ final int len = readInt(bytecode, u);
++ u += 4;
++ u += len;
++ }
++ }
++
++ final int mc = readShort(bytecode, u);
++ u += 2;
++ for (int i = 0 ; i < mc ; i++) {
++ readShort(bytecode, u);
++ u += 2; //access
++
++ final int methodNameIndex = readShort(bytecode, u);
++ u += 2;
++ final String methodName = cp.get(methodNameIndex).toString();
++
++ final int methodDescIndex = readShort(bytecode, u);
++ u += 2;
++ final String methodDesc = cp.get(methodDescIndex).toString();
++
++ final int ac = readShort(bytecode, u);
++ u += 2;
++
++ //method attributes
++ for (int j = 0; j < ac; j++) {
++ final int nameIndex = readShort(bytecode, u);
++ u += 2;
++ final String attrName = cp.get(nameIndex).toString();
++
++ final int attrLen = readInt(bytecode, u);
++ u += 4;
++
++ if ("Code".equals(attrName)) {
++ readShort(bytecode, u);
++ u += 2; //max stack
++ readShort(bytecode, u);
++ u += 2; //max locals
++ final int len = readInt(bytecode, u);
++ u += 4;
++ parseCode(bytecode, u, len, fullyQualifiedName(thisClassName, methodName, methodDesc));
++ u += len;
++ final int elen = readShort(bytecode, u); //exception table length
++ u += 2;
++ u += elen * 8;
++
++ //method attributes
++ final int ac2 = readShort(bytecode, u);
++ u += 2;
++ for (int k = 0; k < ac2; k++) {
++ u += 2; //name;
++ final int aclen = readInt(bytecode, u);
++ u += 4; //length
++ u += aclen; //bytes;
++ }
++ } else {
++ u += attrLen;
++ }
++ }
++ }
++
++ final int ac = readShort(bytecode, u);
++ u += 2;
++ //other attributes
++ for (int i = 0 ; i < ac ; i++) {
++ readShort(bytecode, u); //name index
++ u += 2;
++ final int len = readInt(bytecode, u);
++ u += 4;
++ u += len;
++ //attribute
++ }
++
++ return thisClassName;
++ }
++
++ private static String fullyQualifiedName(final String className, final String methodName, final String methodDesc) {
++ return className + '.' + methodName + methodDesc;
++ }
++
++ private void parseCode(final byte[] bytecode, final int index, final int len, final String desc) {
++ final List<Label> labels = new ArrayList<>();
++ labelMap.put(desc, labels);
++
++ boolean wide = false;
++
++ for (int i = index; i < index + len;) {
++ final int opcode = bytecode[i];
++ labels.add(new NashornLabel(opcode, i - index));
++
++ switch (opcode & 0xff) {
++ case 0xc4: //wide
++ wide = true;
++ i += 1;
++ break;
++ case 0xa9: //ret
++ i += wide ? 4 : 2;
++ break;
++ case 0xab: //lookupswitch
++ i += 1;
++ while (((i - index) & 3) != 0) {
++ i++;
++ }
++ readInt(bytecode, i);
++ i += 4; //defaultbyte
++ final int npairs = readInt(bytecode, i);
++ i += 4;
++ i += 8 * npairs;
++ break;
++ case 0xaa: //tableswitch
++ i += 1;
++ while (((i - index) & 3) != 0) {
++ i++;
++ }
++ readInt(bytecode, i); //default
++ i += 4;
++ final int lo = readInt(bytecode, i);
++ i += 4;
++ final int hi = readInt(bytecode, i);
++ i += 4;
++ i += 4 * (hi - lo + 1);
++ break;
++ case 0xc5: //multianewarray
++ i += 4;
++ break;
++ case 0x19: //aload (wide)
++ case 0x18: //dload
++ case 0x17: //fload
++ case 0x15: //iload
++ case 0x16: //lload
++ case 0x3a: //astore wide
++ case 0x39: //dstore
++ case 0x38: //fstore
++ case 0x36: //istore
++ case 0x37: //lstore
++ i += wide ? 3 : 2;
++ break;
++ case 0x10: //bipush
++ case 0x12: //ldc
++ case 0xbc: //anewarrayu
++ i += 2;
++ break;
++ case 0xb4: //getfield
++ case 0xb2: //getstatic
++ case 0xbd: //anewarray
++ case 0xc0: //checkcast
++ case 0xa5: //ifacmp_eq
++ case 0xa6: //ifacmp_ne
++ case 0x9f: //all ifs and ifcmps
++ case 0xa0:
++ case 0xa1:
++ case 0xa2:
++ case 0xa3:
++ case 0xa4:
++ case 0x99:
++ case 0x9a:
++ case 0x9b:
++ case 0x9c:
++ case 0x9d:
++ case 0x9e:
++ case 0xc7:
++ case 0xc6:
++ case 0xc1: //instanceof
++ case 0xa7: //goto
++ case 0xb7: //special
++ case 0xb8: //static
++ case 0xb6: //virtual
++ case 0xa8: //jsr
++ case 0x13: //ldc_w
++ case 0x14: //ldc2_w
++ case 0xbb: //new
++ case 0xb5: //putfield
++ case 0xb3: //putstatic
++ case 0x11: //sipush
++ i += 3;
++ break;
++ case 0x84: //iinc (wide)
++ i += wide ? 5 : 3;
++ break;
++ case 0xba: //indy
++ case 0xb9: //interface
++ case 0xc8:
++ case 0xc9: //jsr_w
++ i += 5; //goto_w
++ break;
++ default:
++ i++;
++ break;
++ }
++
++ if (wide) {
++ wide = false;
++ }
++ }
++ }
++
++ @Override
++ public void accept(final ClassVisitor classVisitor, final Attribute[] attrs, final int flags) {
++ super.accept(classVisitor, attrs, flags);
++ }
++
++ @Override
++ protected Label readLabel(final int offset, final Label[] labels) {
++ final Label label = super.readLabel(offset, labels);
++ label.info = offset;
++ return label;
++ }
++
++ private abstract static class Constant {
++ protected ArrayList<Constant> cp;
++ protected int tag;
++ protected Constant(final ArrayList<Constant> cp, final int tag) {
++ this.cp = cp;
++ this.tag = tag;
++ }
++
++ @SuppressWarnings("unused")
++ final String getType() {
++ String str = type[tag];
++ while (str.length() < 16) {
++ str += " ";
++ }
++ return str;
++ }
++ }
++
++ private static class IndexInfo extends Constant {
++ protected final int index;
++
++ IndexInfo(final ArrayList<Constant> cp, final int tag, final int index) {
++ super(cp, tag);
++ this.index = index;
++ }
++
++ @Override
++ public String toString() {
++ return cp.get(index).toString();
++ }
++ }
++
++ private static class IndexInfo2 extends IndexInfo {
++ protected final int index2;
++
++ IndexInfo2(final ArrayList<Constant> cp, final int tag, final int index, final int index2) {
++ super(cp, tag, index);
++ this.index2 = index2;
++ }
++
++ @Override
++ public String toString() {
++ return super.toString() + ' ' + cp.get(index2).toString();
++ }
++ }
++
++ private static class DirectInfo<T> extends Constant {
++ protected final T info;
++
++ DirectInfo(final ArrayList<Constant> cp, final int tag, final T info) {
++ super(cp, tag);
++ this.info = info;
++ }
++
++ @Override
++ public String toString() {
++ return info.toString();// + " [class=" + info.getClass().getSimpleName() + ']';
++ }
++ }
++
++ private static String type[] = {
++ //0
++ "<error>",
++ //1
++ "UTF8",
++ //2
++ "<error>",
++ //3
++ "Integer",
++ //4
++ "Float",
++ //5
++ "Long",
++ //6
++ "Double",
++ //7
++ "Class",
++ //8
++ "String",
++ //9
++ "Fieldref",
++ //10
++ "Methodref",
++ //11
++ "InterfaceMethodRef",
++ //12
++ "NameAndType",
++ //13
++ "<error>",
++ //14
++ "<error>",
++ //15
++ "MethodHandle",
++ //16
++ "MethodType",
++ //17
++ "<error>",
++ //18
++ "Invokedynamic"
++ };
++
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/ir/debug/NashornTextifier.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1257 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.ir.debug;
++
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_PROGRAM_POINT_SHIFT;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.FLAGS_MASK;
++
++import java.io.File;
++import java.io.FileNotFoundException;
++import java.io.FileOutputStream;
++import java.io.PrintWriter;
++import java.util.HashMap;
++import java.util.HashSet;
++import java.util.Iterator;
++import java.util.LinkedHashSet;
++import java.util.List;
++import java.util.Map;
++import java.util.Set;
++import jdk.internal.org.objectweb.asm.Attribute;
++import jdk.internal.org.objectweb.asm.Handle;
++import jdk.internal.org.objectweb.asm.Label;
++import jdk.internal.org.objectweb.asm.Opcodes;
++import jdk.internal.org.objectweb.asm.Type;
++import jdk.internal.org.objectweb.asm.signature.SignatureReader;
++import jdk.internal.org.objectweb.asm.util.Printer;
++import jdk.internal.org.objectweb.asm.util.TraceSignatureVisitor;
++import jdk.nashorn.internal.runtime.ScriptEnvironment;
++import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
++
++/**
++ * Pretty printer for --print-code.
++ * Also supports dot formats if --print-code has arguments
++ */
++public final class NashornTextifier extends Printer {
++
++ private String currentClassName;
++ private Iterator<Label> labelIter;
++ private Graph graph;
++ private String currentBlock;
++
++ // Following variables are used to govern the state of collapsing long sequences of NOP.
++ /** True if the last instruction was a NOP. */
++ private boolean lastWasNop = false;
++ /** True if ellipse ("...") was emitted in place of a second NOP. */
++ private boolean lastWasEllipse = false;
++
++ private static final int INTERNAL_NAME = 0;
++ private static final int FIELD_DESCRIPTOR = 1;
++ private static final int FIELD_SIGNATURE = 2;
++ private static final int METHOD_DESCRIPTOR = 3;
++ private static final int METHOD_SIGNATURE = 4;
++ private static final int CLASS_SIGNATURE = 5;
++
++ private final String tab = " ";
++ private final String tab2 = " ";
++ private final String tab3 = " ";
++
++ private Map<Label, String> labelNames;
++
++ private boolean localVarsStarted = false;
++
++ private NashornClassReader cr;
++ private ScriptEnvironment env;
++
++ /**
++ * Constructs a new {@link NashornTextifier}. <i>Subclasses must not use this
++ * constructor</i>. Instead, they must use the {@link #NashornTextifier(int)}
++ * version.
++ * @param env script environment
++ * @param cr a customized classreader for gathering, among other things, label
++ * information
++ */
++ public NashornTextifier(final ScriptEnvironment env, final NashornClassReader cr) {
++ this(Opcodes.ASM5);
++ this.env = env;
++ this.cr = cr;
++ }
++
++ private NashornTextifier(final ScriptEnvironment env, final NashornClassReader cr, final Iterator<Label> labelIter, final Graph graph) {
++ this(env, cr);
++ this.labelIter = labelIter;
++ this.graph = graph;
++ }
++
++ /**
++ * Constructs a new {@link NashornTextifier}.
++ *
++ * @param api
++ * the ASM API version implemented by this visitor. Must be one
++ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
++ */
++ protected NashornTextifier(final int api) {
++ super(api);
++ }
++
++ @Override
++ public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) {
++ final int major = version & 0xFFFF;
++ final int minor = version >>> 16;
++
++ currentClassName = name;
++
++ final StringBuilder sb = new StringBuilder();
++ sb.append("// class version ").
++ append(major).
++ append('.').
++ append(minor).append(" (").
++ append(version).
++ append(")\n");
++
++ if ((access & Opcodes.ACC_DEPRECATED) != 0) {
++ sb.append("// DEPRECATED\n");
++ }
++
++ sb.append("// access flags 0x"). //TODO TRANSLATE TO WHAT THEY MEAN
++ append(Integer.toHexString(access).toUpperCase()).
++ append('\n');
++
++ appendDescriptor(sb, CLASS_SIGNATURE, signature);
++ if (signature != null) {
++ final TraceSignatureVisitor sv = new TraceSignatureVisitor(access);
++ final SignatureReader r = new SignatureReader(signature);
++ r.accept(sv);
++ sb.append("// declaration: ").
++ append(name).
++ append(sv.getDeclaration()).
++ append('\n');
++ }
++
++ appendAccess(sb, access & ~Opcodes.ACC_SUPER);
++ if ((access & Opcodes.ACC_ANNOTATION) != 0) {
++ sb.append("@interface ");
++ } else if ((access & Opcodes.ACC_INTERFACE) != 0) {
++ sb.append("interface ");
++ } else if ((access & Opcodes.ACC_ENUM) == 0) {
++ sb.append("class ");
++ }
++ appendDescriptor(sb, INTERNAL_NAME, name);
++
++ if (superName != null && !"java/lang/Object".equals(superName)) {
++ sb.append(" extends ");
++ appendDescriptor(sb, INTERNAL_NAME, superName);
++ sb.append(' ');
++ }
++ if (interfaces != null && interfaces.length > 0) {
++ sb.append(" implements ");
++ for (final String interface1 : interfaces) {
++ appendDescriptor(sb, INTERNAL_NAME, interface1);
++ sb.append(' ');
++ }
++ }
++ sb.append(" {\n");
++
++ addText(sb);
++ }
++
++ @Override
++ public void visitSource(final String file, final String debug) {
++ final StringBuilder sb = new StringBuilder();
++ if (file != null) {
++ sb.append(tab).
++ append("// compiled from: ").
++ append(file).
++ append('\n');
++ }
++ if (debug != null) {
++ sb.append(tab).
++ append("// debug info: ").
++ append(debug).
++ append('\n');
++ }
++ if (sb.length() > 0) {
++ addText(sb);
++ }
++ }
++
++ @Override
++ public void visitOuterClass(final String owner, final String name, final String desc) {
++ final StringBuilder sb = new StringBuilder();
++ sb.append(tab).append("outer class ");
++ appendDescriptor(sb, INTERNAL_NAME, owner);
++ sb.append(' ');
++ if (name != null) {
++ sb.append(name).append(' ');
++ }
++ appendDescriptor(sb, METHOD_DESCRIPTOR, desc);
++ sb.append('\n');
++ addText(sb);
++ }
++
++ @Override
++ public NashornTextifier visitField(final int access, final String name, final String desc, final String signature, final Object value) {
++ final StringBuilder sb = new StringBuilder();
++// sb.append('\n');
++ if ((access & Opcodes.ACC_DEPRECATED) != 0) {
++ sb.append(tab).append("// DEPRECATED\n");
++ }
++
++/* sb.append(tab).
++ append("// access flags 0x").
++ append(Integer.toHexString(access).toUpperCase()).
++ append('\n');
++*/
++
++ if (signature != null) {
++ sb.append(tab);
++ appendDescriptor(sb, FIELD_SIGNATURE, signature);
++
++ final TraceSignatureVisitor sv = new TraceSignatureVisitor(0);
++ final SignatureReader r = new SignatureReader(signature);
++ r.acceptType(sv);
++ sb.append(tab).
++ append("// declaration: ").
++ append(sv.getDeclaration()).
++ append('\n');
++ }
++
++ sb.append(tab);
++ appendAccess(sb, access);
++
++ final String prunedDesc = desc.endsWith(";") ? desc.substring(0, desc.length() - 1) : desc;
++ appendDescriptor(sb, FIELD_DESCRIPTOR, prunedDesc);
++ sb.append(' ').append(name);
++ if (value != null) {
++ sb.append(" = ");
++ if (value instanceof String) {
++ sb.append('\"').append(value).append('\"');
++ } else {
++ sb.append(value);
++ }
++ }
++
++ sb.append(";\n");
++ addText(sb);
++
++ final NashornTextifier t = createNashornTextifier();
++ addText(t.getText());
++
++ return t;
++ }
++
++ @Override
++ public NashornTextifier visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
++
++ graph = new Graph(name);
++
++ final List<Label> extraLabels = cr.getExtraLabels(currentClassName, name, desc);
++ this.labelIter = extraLabels == null ? null : extraLabels.iterator();
++
++ final StringBuilder sb = new StringBuilder();
++
++ sb.append('\n');
++ if ((access & Opcodes.ACC_DEPRECATED) != 0) {
++ sb.append(tab).
++ append("// DEPRECATED\n");
++ }
++
++ sb.append(tab).
++ append("// access flags 0x").
++ append(Integer.toHexString(access).toUpperCase()).
++ append('\n');
++
++ if (signature != null) {
++ sb.append(tab);
++ appendDescriptor(sb, METHOD_SIGNATURE, signature);
++
++ final TraceSignatureVisitor v = new TraceSignatureVisitor(0);
++ final SignatureReader r = new SignatureReader(signature);
++ r.accept(v);
++ final String genericDecl = v.getDeclaration();
++ final String genericReturn = v.getReturnType();
++ final String genericExceptions = v.getExceptions();
++
++ sb.append(tab).
++ append("// declaration: ").
++ append(genericReturn).
++ append(' ').
++ append(name).
++ append(genericDecl);
++
++ if (genericExceptions != null) {
++ sb.append(" throws ").append(genericExceptions);
++ }
++ sb.append('\n');
++ }
++
++ sb.append(tab);
++ appendAccess(sb, access);
++ if ((access & Opcodes.ACC_NATIVE) != 0) {
++ sb.append("native ");
++ }
++ if ((access & Opcodes.ACC_VARARGS) != 0) {
++ sb.append("varargs ");
++ }
++ if ((access & Opcodes.ACC_BRIDGE) != 0) {
++ sb.append("bridge ");
++ }
++
++ sb.append(name);
++ appendDescriptor(sb, METHOD_DESCRIPTOR, desc);
++ if (exceptions != null && exceptions.length > 0) {
++ sb.append(" throws ");
++ for (final String exception : exceptions) {
++ appendDescriptor(sb, INTERNAL_NAME, exception);
++ sb.append(' ');
++ }
++ }
++
++ sb.append('\n');
++ addText(sb);
++
++ final NashornTextifier t = createNashornTextifier();
++ addText(t.getText());
++ return t;
++ }
++
++ @Override
++ public void visitClassEnd() {
++ addText("}\n");
++ }
++
++ @Override
++ public void visitFieldEnd() {
++ //empty
++ }
++
++ @Override
++ public void visitParameter(final String name, final int access) {
++ final StringBuilder sb = new StringBuilder();
++ sb.append(tab2).append("// parameter ");
++ appendAccess(sb, access);
++ sb.append(' ').append(name == null ? "<no name>" : name)
++ .append('\n');
++ addText(sb);
++ }
++
++ @Override
++ public void visitCode() {
++ //empty
++ }
++
++ @Override
++ public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, final Object[] stack) {
++ final StringBuilder sb = new StringBuilder();
++ sb.append("frame ");
++ switch (type) {
++ case Opcodes.F_NEW:
++ case Opcodes.F_FULL:
++ sb.append("full [");
++ appendFrameTypes(sb, nLocal, local);
++ sb.append("] [");
++ appendFrameTypes(sb, nStack, stack);
++ sb.append(']');
++ break;
++ case Opcodes.F_APPEND:
++ sb.append("append [");
++ appendFrameTypes(sb, nLocal, local);
++ sb.append(']');
++ break;
++ case Opcodes.F_CHOP:
++ sb.append("chop ").append(nLocal);
++ break;
++ case Opcodes.F_SAME:
++ sb.append("same");
++ break;
++ case Opcodes.F_SAME1:
++ sb.append("same1 ");
++ appendFrameTypes(sb, 1, stack);
++ break;
++ default:
++ assert false;
++ break;
++ }
++ sb.append('\n');
++ sb.append('\n');
++ addText(sb);
++ }
++
++ private StringBuilder appendOpcode(final StringBuilder sb, final int opcode) {
++ final Label next = getNextLabel();
++ if (next instanceof NashornLabel) {
++ final int bci = next.getOffset();
++ if (bci != -1) {
++ final String bcis = "" + bci;
++ for (int i = 0; i < 5 - bcis.length(); i++) {
++ sb.append(' ');
++ }
++ sb.append(bcis);
++ sb.append(' ');
++ } else {
++ sb.append(" ");
++ }
++ }
++
++ return sb.append(tab2).append(OPCODES[opcode].toLowerCase());
++ }
++
++ private Label getNextLabel() {
++ return labelIter == null ? null : labelIter.next();
++ }
++
++ @Override
++ public void visitInsn(final int opcode) {
++ if(opcode == Opcodes.NOP) {
++ if(lastWasEllipse) {
++ getNextLabel();
++ return;
++ } else if(lastWasNop) {
++ getNextLabel();
++ addText(" ...\n");
++ lastWasEllipse = true;
++ return;
++ } else {
++ lastWasNop = true;
++ }
++ } else {
++ lastWasNop = lastWasEllipse = false;
++ }
++ final StringBuilder sb = new StringBuilder();
++ appendOpcode(sb, opcode).append('\n');
++ addText(sb);
++ checkNoFallThru(opcode, null);
++ }
++
++ @Override
++ public void visitIntInsn(final int opcode, final int operand) {
++ final StringBuilder sb = new StringBuilder();
++ appendOpcode(sb, opcode)
++ .append(' ')
++ .append(opcode == Opcodes.NEWARRAY ? TYPES[operand] : Integer
++ .toString(operand)).append('\n');
++ addText(sb);
++ }
++
++ @Override
++ public void visitVarInsn(final int opcode, final int var) {
++ final StringBuilder sb = new StringBuilder();
++ appendOpcode(sb, opcode).append(' ').append(var).append('\n');
++ addText(sb);
++ }
++
++ @Override
++ public void visitTypeInsn(final int opcode, final String type) {
++ final StringBuilder sb = new StringBuilder();
++ appendOpcode(sb, opcode).append(' ');
++ appendDescriptor(sb, INTERNAL_NAME, type);
++ sb.append('\n');
++ addText(sb);
++ }
++
++ @Override
++ public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) {
++ final StringBuilder sb = new StringBuilder();
++ appendOpcode(sb, opcode).append(' ');
++ appendDescriptor(sb, INTERNAL_NAME, owner);
++ sb.append('.').append(name).append(" : ");
++ appendDescriptor(sb, FIELD_DESCRIPTOR, desc);
++ sb.append('\n');
++ addText(sb);
++ }
++
++ @Override
++ public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, final boolean itf) {
++ final StringBuilder sb = new StringBuilder();
++ appendOpcode(sb, opcode).append(' ');
++ appendDescriptor(sb, INTERNAL_NAME, owner);
++ sb.append('.').append(name);
++ appendDescriptor(sb, METHOD_DESCRIPTOR, desc);
++ sb.append('\n');
++ addText(sb);
++ }
++
++ @Override
++ public void visitInvokeDynamicInsn(final String name, final String desc, final Handle bsm, final Object... bsmArgs) {
++ final StringBuilder sb = new StringBuilder();
++
++ appendOpcode(sb, Opcodes.INVOKEDYNAMIC).append(' ');
++ sb.append(name);
++ appendDescriptor(sb, METHOD_DESCRIPTOR, desc);
++ final int len = sb.length();
++ for (int i = 0; i < 80 - len ; i++) {
++ sb.append(' ');
++ }
++ sb.append(" [");
++ appendHandle(sb, bsm);
++ if (bsmArgs.length == 0) {
++ sb.append("none");
++ } else {
++ for (final Object cst : bsmArgs) {
++ if (cst instanceof String) {
++ appendStr(sb, (String)cst);
++ } else if (cst instanceof Type) {
++ sb.append(((Type)cst).getDescriptor()).append(".class");
++ } else if (cst instanceof Handle) {
++ appendHandle(sb, (Handle)cst);
++ } else if (cst instanceof Integer) {
++ final int c = (Integer)cst;
++ final int pp = c >> CALLSITE_PROGRAM_POINT_SHIFT;
++ if (pp != 0) {
++ sb.append(" pp=").append(pp);
++ }
++ sb.append(NashornCallSiteDescriptor.toString(c & FLAGS_MASK));
++ } else {
++ sb.append(cst);
++ }
++ sb.append(", ");
++ }
++ sb.setLength(sb.length() - 2);
++ }
++
++ sb.append("]\n");
++ addText(sb);
++ }
++
++ private static final boolean noFallThru(final int opcode) {
++ switch (opcode) {
++ case Opcodes.GOTO:
++ case Opcodes.ATHROW:
++ case Opcodes.ARETURN:
++ case Opcodes.IRETURN:
++ case Opcodes.LRETURN:
++ case Opcodes.FRETURN:
++ case Opcodes.DRETURN:
++ return true;
++ default:
++ return false;
++ }
++ }
++
++ private void checkNoFallThru(final int opcode, final String to) {
++ if (noFallThru(opcode)) {
++ graph.setNoFallThru(currentBlock);
++ }
++
++ if (currentBlock != null && to != null) {
++ graph.addEdge(currentBlock, to);
++ }
++ }
++
++ @Override
++ public void visitJumpInsn(final int opcode, final Label label) {
++ final StringBuilder sb = new StringBuilder();
++ appendOpcode(sb, opcode).append(' ');
++ final String to = appendLabel(sb, label);
++ sb.append('\n');
++ addText(sb);
++ checkNoFallThru(opcode, to);
++ }
++
++ private void addText(final Object t) {
++ text.add(t);
++ if (currentBlock != null) {
++ graph.addText(currentBlock, t.toString());
++ }
++ }
++
++ @Override
++ public void visitLabel(final Label label) {
++ final StringBuilder sb = new StringBuilder();
++ sb.append("\n");
++ final String name = appendLabel(sb, label);
++ sb.append(" [bci=");
++ sb.append(label.info);
++ sb.append("]");
++ sb.append("\n");
++
++ graph.addNode(name);
++ if (currentBlock != null && !graph.isNoFallThru(currentBlock)) {
++ graph.addEdge(currentBlock, name);
++ }
++ currentBlock = name;
++ addText(sb);
++ }
++
++ @Override
++ public void visitLdcInsn(final Object cst) {
++ final StringBuilder sb = new StringBuilder();
++ appendOpcode(sb, Opcodes.LDC).append(' ');
++ if (cst instanceof String) {
++ appendStr(sb, (String) cst);
++ } else if (cst instanceof Type) {
++ sb.append(((Type) cst).getDescriptor()).append(".class");
++ } else {
++ sb.append(cst);
++ }
++ sb.append('\n');
++ addText(sb);
++ }
++
++ @Override
++ public void visitIincInsn(final int var, final int increment) {
++ final StringBuilder sb = new StringBuilder();
++ appendOpcode(sb, Opcodes.IINC).append(' ');
++ sb.append(var).append(' ')
++ .append(increment).append('\n');
++ addText(sb);
++ }
++
++ @Override
++ public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels) {
++ final StringBuilder sb = new StringBuilder();
++ appendOpcode(sb, Opcodes.TABLESWITCH).append(' ');
++ for (int i = 0; i < labels.length; ++i) {
++ sb.append(tab3).append(min + i).append(": ");
++ final String to = appendLabel(sb, labels[i]);
++ graph.addEdge(currentBlock, to);
++ sb.append('\n');
++ }
++ sb.append(tab3).append("default: ");
++ appendLabel(sb, dflt);
++ sb.append('\n');
++ addText(sb);
++ }
++
++ @Override
++ public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
++ final StringBuilder sb = new StringBuilder();
++ appendOpcode(sb, Opcodes.LOOKUPSWITCH).append(' ');
++ for (int i = 0; i < labels.length; ++i) {
++ sb.append(tab3).append(keys[i]).append(": ");
++ final String to = appendLabel(sb, labels[i]);
++ graph.addEdge(currentBlock, to);
++ sb.append('\n');
++ }
++ sb.append(tab3).append("default: ");
++ final String to = appendLabel(sb, dflt);
++ graph.addEdge(currentBlock, to);
++ sb.append('\n');
++ addText(sb.toString());
++ }
++
++ @Override
++ public void visitMultiANewArrayInsn(final String desc, final int dims) {
++ final StringBuilder sb = new StringBuilder();
++ appendOpcode(sb, Opcodes.MULTIANEWARRAY).append(' ');
++ appendDescriptor(sb, FIELD_DESCRIPTOR, desc);
++ sb.append(' ').append(dims).append('\n');
++ addText(sb);
++ }
++
++ @Override
++ public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) {
++ final StringBuilder sb = new StringBuilder();
++ sb.append(tab2).append("try ");
++ final String from = appendLabel(sb, start);
++ sb.append(' ');
++ appendLabel(sb, end);
++ sb.append(' ');
++ final String to = appendLabel(sb, handler);
++ sb.append(' ');
++ appendDescriptor(sb, INTERNAL_NAME, type);
++ sb.append('\n');
++ addText(sb);
++ graph.setIsCatch(to, type);
++ graph.addTryCatch(from, to);
++ }
++
++ @Override
++ public void visitLocalVariable(final String name, final String desc,final String signature, final Label start, final Label end, final int index) {
++
++ final StringBuilder sb = new StringBuilder();
++ if (!localVarsStarted) {
++ text.add("\n");
++ localVarsStarted = true;
++ graph.addNode("vars");
++ currentBlock = "vars";
++ }
++
++ sb.append(tab2).append("local ").append(name).append(' ');
++ final int len = sb.length();
++ for (int i = 0; i < 25 - len; i++) {
++ sb.append(' ');
++ }
++ String label;
++
++ label = appendLabel(sb, start);
++ for (int i = 0; i < 5 - label.length(); i++) {
++ sb.append(' ');
++ }
++ label = appendLabel(sb, end);
++ for (int i = 0; i < 5 - label.length(); i++) {
++ sb.append(' ');
++ }
++
++ sb.append(index).append(tab2);
++
++ appendDescriptor(sb, FIELD_DESCRIPTOR, desc);
++ sb.append('\n');
++
++ if (signature != null) {
++ sb.append(tab2);
++ appendDescriptor(sb, FIELD_SIGNATURE, signature);
++
++ final TraceSignatureVisitor sv = new TraceSignatureVisitor(0);
++ final SignatureReader r = new SignatureReader(signature);
++ r.acceptType(sv);
++ sb.append(tab2).append("// declaration: ")
++ .append(sv.getDeclaration()).append('\n');
++ }
++ addText(sb.toString());
++ }
++
++ @Override
++ public void visitLineNumber(final int line, final Label start) {
++ final StringBuilder sb = new StringBuilder();
++ sb.append("<line ");
++ sb.append(line);
++ sb.append(">\n");
++ addText(sb.toString());
++ }
++
++ @Override
++ public void visitMaxs(final int maxStack, final int maxLocals) {
++ final StringBuilder sb = new StringBuilder();
++ sb.append('\n');
++ sb.append(tab2).append("max stack = ").append(maxStack);
++ sb.append(", max locals = ").append(maxLocals).append('\n');
++ addText(sb.toString());
++ }
++
++ private void printToDir(final Graph g) {
++ if (env._print_code_dir != null) {
++ final File dir = new File(env._print_code_dir);
++ if (!dir.exists() && !dir.mkdirs()) {
++ throw new RuntimeException(dir.toString());
++ }
++
++ File file;
++ int uniqueId = 0;
++ do {
++ final String fileName = g.getName() + (uniqueId == 0 ? "" : "_" + uniqueId) + ".dot";
++ file = new File(dir, fileName);
++ uniqueId++;
++ } while (file.exists());
++
++ try (PrintWriter pw = new PrintWriter(new FileOutputStream(file))) {
++ pw.println(g);
++ } catch (final FileNotFoundException e) {
++ throw new RuntimeException(e);
++ }
++ }
++ }
++
++ @Override
++ public void visitMethodEnd() {
++ //here we need to do several bytecode guesses best upon the ldc instructions.
++ //for each instruction, assign bci. for an ldc/w/2w, guess a byte and keep
++ //iterating. if the next label is wrong, backtrack.
++ if (env._print_code_func == null || env._print_code_func.equals(graph.getName())) {
++ if (env._print_code_dir != null) {
++ printToDir(graph);
++ }
++ }
++ }
++
++ /**
++ * Creates a new TraceVisitor instance.
++ *
++ * @return a new TraceVisitor.
++ */
++ protected NashornTextifier createNashornTextifier() {
++ return new NashornTextifier(env, cr, labelIter, graph);
++ }
++
++ private static void appendDescriptor(final StringBuilder sb, final int type, final String desc) {
++ if (desc != null) {
++ if (type == CLASS_SIGNATURE || type == FIELD_SIGNATURE || type == METHOD_SIGNATURE) {
++ sb.append("// signature ").append(desc).append('\n');
++ } else {
++ appendShortDescriptor(sb, desc);
++ }
++ }
++ }
++
++ private String appendLabel(final StringBuilder sb, final Label l) {
++ if (labelNames == null) {
++ labelNames = new HashMap<>();
++ }
++ String name = labelNames.get(l);
++ if (name == null) {
++ name = "L" + labelNames.size();
++ labelNames.put(l, name);
++ }
++ sb.append(name);
++ return name;
++ }
++
++ private static void appendHandle(final StringBuilder sb, final Handle h) {
++ switch (h.getTag()) {
++ case Opcodes.H_GETFIELD:
++ sb.append("getfield");
++ break;
++ case Opcodes.H_GETSTATIC:
++ sb.append("getstatic");
++ break;
++ case Opcodes.H_PUTFIELD:
++ sb.append("putfield");
++ break;
++ case Opcodes.H_PUTSTATIC:
++ sb.append("putstatic");
++ break;
++ case Opcodes.H_INVOKEINTERFACE:
++ sb.append("interface");
++ break;
++ case Opcodes.H_INVOKESPECIAL:
++ sb.append("special");
++ break;
++ case Opcodes.H_INVOKESTATIC:
++ sb.append("static");
++ break;
++ case Opcodes.H_INVOKEVIRTUAL:
++ sb.append("virtual");
++ break;
++ case Opcodes.H_NEWINVOKESPECIAL:
++ sb.append("new_special");
++ break;
++ default:
++ assert false;
++ break;
++ }
++ sb.append(" '");
++ sb.append(h.getName());
++ sb.append("'");
++ }
++
++ private static void appendAccess(final StringBuilder sb, final int access) {
++ if ((access & Opcodes.ACC_PUBLIC) != 0) {
++ sb.append("public ");
++ }
++ if ((access & Opcodes.ACC_PRIVATE) != 0) {
++ sb.append("private ");
++ }
++ if ((access & Opcodes.ACC_PROTECTED) != 0) {
++ sb.append("protected ");
++ }
++ if ((access & Opcodes.ACC_FINAL) != 0) {
++ sb.append("final ");
++ }
++ if ((access & Opcodes.ACC_STATIC) != 0) {
++ sb.append("static ");
++ }
++ if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) {
++ sb.append("synchronized ");
++ }
++ if ((access & Opcodes.ACC_VOLATILE) != 0) {
++ sb.append("volatile ");
++ }
++ if ((access & Opcodes.ACC_TRANSIENT) != 0) {
++ sb.append("transient ");
++ }
++ if ((access & Opcodes.ACC_ABSTRACT) != 0) {
++ sb.append("abstract ");
++ }
++ if ((access & Opcodes.ACC_STRICT) != 0) {
++ sb.append("strictfp ");
++ }
++ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
++ sb.append("synthetic ");
++ }
++ if ((access & Opcodes.ACC_MANDATED) != 0) {
++ sb.append("mandated ");
++ }
++ if ((access & Opcodes.ACC_ENUM) != 0) {
++ sb.append("enum ");
++ }
++ }
++
++ private void appendFrameTypes(final StringBuilder sb, final int n, final Object[] o) {
++ for (int i = 0; i < n; ++i) {
++ if (i > 0) {
++ sb.append(' ');
++ }
++ if (o[i] instanceof String) {
++ final String desc = (String) o[i];
++ if (desc.startsWith("[")) {
++ appendDescriptor(sb, FIELD_DESCRIPTOR, desc);
++ } else {
++ appendDescriptor(sb, INTERNAL_NAME, desc);
++ }
++ } else if (o[i] instanceof Integer) {
++ switch (((Integer)o[i]).intValue()) {
++ case 0:
++ appendDescriptor(sb, FIELD_DESCRIPTOR, "T");
++ break;
++ case 1:
++ appendDescriptor(sb, FIELD_DESCRIPTOR, "I");
++ break;
++ case 2:
++ appendDescriptor(sb, FIELD_DESCRIPTOR, "F");
++ break;
++ case 3:
++ appendDescriptor(sb, FIELD_DESCRIPTOR, "D");
++ break;
++ case 4:
++ appendDescriptor(sb, FIELD_DESCRIPTOR, "J");
++ break;
++ case 5:
++ appendDescriptor(sb, FIELD_DESCRIPTOR, "N");
++ break;
++ case 6:
++ appendDescriptor(sb, FIELD_DESCRIPTOR, "U");
++ break;
++ default:
++ assert false;
++ break;
++ }
++ } else {
++ appendLabel(sb, (Label) o[i]);
++ }
++ }
++ }
++
++ private static void appendShortDescriptor(final StringBuilder sb, final String desc) {
++ //final StringBuilder buf = new StringBuilder();
++ if (desc.charAt(0) == '(') {
++ for (int i = 0; i < desc.length(); i++) {
++ if (desc.charAt(i) == 'L') {
++ int slash = i;
++ while (desc.charAt(i) != ';') {
++ i++;
++ if (desc.charAt(i) == '/') {
++ slash = i;
++ }
++ }
++ sb.append(desc.substring(slash + 1, i)).append(';');
++ } else {
++ sb.append(desc.charAt(i));
++ }
++ }
++ } else {
++ final int lastSlash = desc.lastIndexOf('/');
++ final int lastBracket = desc.lastIndexOf('[');
++ if(lastBracket != -1) {
++ sb.append(desc, 0, lastBracket + 1);
++ }
++ sb.append(lastSlash == -1 ? desc : desc.substring(lastSlash + 1));
++ }
++ }
++
++ private static void appendStr(final StringBuilder sb, final String s) {
++ sb.append('\"');
++ for (int i = 0; i < s.length(); ++i) {
++ final char c = s.charAt(i);
++ if (c == '\n') {
++ sb.append("\\n");
++ } else if (c == '\r') {
++ sb.append("\\r");
++ } else if (c == '\\') {
++ sb.append("\\\\");
++ } else if (c == '"') {
++ sb.append("\\\"");
++ } else if (c < 0x20 || c > 0x7f) {
++ sb.append("\\u");
++ if (c < 0x10) {
++ sb.append("000");
++ } else if (c < 0x100) {
++ sb.append("00");
++ } else if (c < 0x1000) {
++ sb.append('0');
++ }
++ sb.append(Integer.toString(c, 16));
++ } else {
++ sb.append(c);
++ }
++ }
++ sb.append('\"');
++ }
++
++ private static class Graph {
++ private final LinkedHashSet<String> nodes;
++ private final Map<String, StringBuilder> contents;
++ private final Map<String, Set<String>> edges;
++ private final Set<String> hasPreds;
++ private final Set<String> noFallThru;
++ private final Map<String, String> catches;
++ private final Map<String, Set<String>> exceptionMap; //maps catch nodes to all their trys that can reach them
++ private final String name;
++
++ private static final String LEFT_ALIGN = "\\l";
++ private static final String COLOR_CATCH = "\"#ee9999\"";
++ private static final String COLOR_ORPHAN = "\"#9999bb\"";
++ private static final String COLOR_DEFAULT = "\"#99bb99\"";
++ private static final String COLOR_LOCALVARS = "\"#999999\"";
++
++ Graph(final String name) {
++ this.name = name;
++ this.nodes = new LinkedHashSet<>();
++ this.contents = new HashMap<>();
++ this.edges = new HashMap<>();
++ this.hasPreds = new HashSet<>();
++ this.catches = new HashMap<>();
++ this.noFallThru = new HashSet<>();
++ this.exceptionMap = new HashMap<>();
++ }
++
++ void addEdge(final String from, final String to) {
++ Set<String> edgeSet = edges.get(from);
++ if (edgeSet == null) {
++ edgeSet = new LinkedHashSet<>();
++ edges.put(from, edgeSet);
++ }
++ edgeSet.add(to);
++ hasPreds.add(to);
++ }
++
++ void addTryCatch(final String tryNode, final String catchNode) {
++ Set<String> tryNodes = exceptionMap.get(catchNode);
++ if (tryNodes == null) {
++ tryNodes = new HashSet<>();
++ exceptionMap.put(catchNode, tryNodes);
++ }
++ if (!tryNodes.contains(tryNode)) {
++ addEdge(tryNode, catchNode);
++ }
++ tryNodes.add(tryNode);
++ }
++
++ void addNode(final String node) {
++ assert !nodes.contains(node);
++ nodes.add(node);
++ }
++
++ void setNoFallThru(final String node) {
++ noFallThru.add(node);
++ }
++
++ boolean isNoFallThru(final String node) {
++ return noFallThru.contains(node);
++ }
++
++ void setIsCatch(final String node, final String exception) {
++ catches.put(node, exception);
++ }
++
++ String getName() {
++ return name;
++ }
++
++ void addText(final String node, final String text) {
++ StringBuilder sb = contents.get(node);
++ if (sb == null) {
++ sb = new StringBuilder();
++ }
++
++ for (int i = 0; i < text.length(); i++) {
++ switch (text.charAt(i)) {
++ case '\n':
++ sb.append(LEFT_ALIGN);
++ break;
++ case '"':
++ sb.append("'");
++ break;
++ default:
++ sb.append(text.charAt(i));
++ break;
++ }
++ }
++
++ contents.put(node, sb);
++ }
++
++ private static String dottyFriendly(final String name) {
++ return name.replace(':', '_');
++ }
++
++ @Override
++ public String toString() {
++
++ final StringBuilder sb = new StringBuilder();
++ sb.append("digraph " + dottyFriendly(name) + " {");
++ sb.append("\n");
++ sb.append("\tgraph [fontname=courier]\n");
++ sb.append("\tnode [style=filled,color="+COLOR_DEFAULT+",fontname=courier]\n");
++ sb.append("\tedge [fontname=courier]\n\n");
++
++ for (final String node : nodes) {
++ sb.append("\t");
++ sb.append(node);
++ sb.append(" [");
++ sb.append("id=");
++ sb.append(node);
++ sb.append(", label=\"");
++ String c = contents.get(node).toString();
++ if (c.startsWith(LEFT_ALIGN)) {
++ c = c.substring(LEFT_ALIGN.length());
++ }
++ final String ex = catches.get(node);
++ if (ex != null) {
++ sb.append("*** CATCH: ").append(ex).append(" ***\n");
++ }
++ sb.append(c);
++ sb.append("\"]\n");
++ }
++
++ for (final String from : edges.keySet()) {
++ for (final String to : edges.get(from)) {
++ sb.append("\t");
++ sb.append(from);
++ sb.append(" -> ");
++ sb.append(to);
++ sb.append("[label=\"");
++ sb.append(to);
++ sb.append("\"");
++ if (catches.get(to) != null) {
++ sb.append(", color=red, style=dashed");
++ }
++ sb.append(']');
++ sb.append(";\n");
++ }
++ }
++
++ sb.append("\n");
++ for (final String node : nodes) {
++ sb.append("\t");
++ sb.append(node);
++ sb.append(" [shape=box");
++ if (catches.get(node) != null) {
++ sb.append(", color=" + COLOR_CATCH);
++ } else if ("vars".equals(node)) {
++ sb.append(", shape=hexagon, color=" + COLOR_LOCALVARS);
++ } else if (!hasPreds.contains(node)) {
++ sb.append(", color=" + COLOR_ORPHAN);
++ }
++ sb.append("]\n");
++ }
++
++ sb.append("}\n");
++ return sb.toString();
++ }
++ }
++
++ static class NashornLabel extends Label {
++ final Label label;
++ final int bci;
++ final int opcode;
++
++ NashornLabel(final Label label, final int bci) {
++ this.label = label;
++ this.bci = bci;
++ this.opcode = -1;
++ }
++
++ //not an ASM label
++ NashornLabel(final int opcode, final int bci) {
++ this.opcode = opcode;
++ this.bci = bci;
++ this.label = null;
++ }
++
++ Label getLabel() {
++ return label;
++ }
++
++ @Override
++ public int getOffset() {
++ return bci;
++ }
++
++ @Override
++ public String toString() {
++ return "label " + bci;
++ }
++ }
++
++ @Override
++ public Printer visitAnnotationDefault() {
++ throw new AssertionError();
++ }
++
++ @Override
++ public Printer visitClassAnnotation(final String arg0, final boolean arg1) {
++ return this;
++ }
++
++ @Override
++ public void visitClassAttribute(final Attribute arg0) {
++ throw new AssertionError();
++ }
++
++ @Override
++ public Printer visitFieldAnnotation(final String arg0, final boolean arg1) {
++ throw new AssertionError();
++ }
++
++ @Override
++ public void visitFieldAttribute(final Attribute arg0) {
++ throw new AssertionError();
++ }
++
++ @Override
++ public Printer visitMethodAnnotation(final String arg0, final boolean arg1) {
++ return this;
++ }
++
++ @Override
++ public void visitMethodAttribute(final Attribute arg0) {
++ throw new AssertionError();
++ }
++
++ @Override
++ public Printer visitParameterAnnotation(final int arg0, final String arg1, final boolean arg2) {
++ throw new AssertionError();
++ }
++
++ @Override
++ public void visit(final String arg0, final Object arg1) {
++ throw new AssertionError();
++ }
++
++ @Override
++ public Printer visitAnnotation(final String arg0, final String arg1) {
++ throw new AssertionError();
++ }
++
++ @Override
++ public void visitAnnotationEnd() {
++ //empty
++ }
++
++ @Override
++ public Printer visitArray(final String arg0) {
++ throw new AssertionError();
++ }
++
++ @Override
++ public void visitEnum(final String arg0, final String arg1, final String arg2) {
++ throw new AssertionError();
++ }
++
++ @Override
++ public void visitInnerClass(final String arg0, final String arg1, final String arg2, final int arg3) {
++ throw new AssertionError();
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -52,9 +52,7 @@
+ * this fact and will report incorrect sizes, as it will presume the default JVM
+ * behavior.
+ */
+-
+-@SuppressWarnings("StaticNonFinalUsedInInitialization")
+-public class ObjectSizeCalculator {
++public final class ObjectSizeCalculator {
+
+ /**
+ * Describes constant memory overheads for various constructs in a JVM implementation.
+@@ -307,7 +305,7 @@
+ public ClassSizeInfo(final Class<?> clazz) {
+ long newFieldsSize = 0;
+ final List<Field> newReferenceFields = new LinkedList<>();
+- for (Field f : clazz.getDeclaredFields()) {
++ for (final Field f : clazz.getDeclaredFields()) {
+ if (Modifier.isStatic(f.getModifiers())) {
+ continue;
+ }
+@@ -338,10 +336,10 @@
+ }
+
+ public void enqueueReferencedObjects(final Object obj, final ObjectSizeCalculator calc) {
+- for (Field f : referenceFields) {
++ for (final Field f : referenceFields) {
+ try {
+ calc.enqueue(f.get(obj));
+- } catch (IllegalAccessException e) {
++ } catch (final IllegalAccessException e) {
+ final AssertionError ae = new AssertionError(
+ "Unexpected denial of access to " + f);
+ ae.initCause(e);
+--- ./nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,18 +29,25 @@
+ import jdk.nashorn.internal.ir.BinaryNode;
+ import jdk.nashorn.internal.ir.Block;
+ import jdk.nashorn.internal.ir.BlockStatement;
++import jdk.nashorn.internal.ir.BreakNode;
+ import jdk.nashorn.internal.ir.CaseNode;
+ import jdk.nashorn.internal.ir.CatchNode;
++import jdk.nashorn.internal.ir.ContinueNode;
+ import jdk.nashorn.internal.ir.ExpressionStatement;
+ import jdk.nashorn.internal.ir.ForNode;
+ import jdk.nashorn.internal.ir.FunctionNode;
++import jdk.nashorn.internal.ir.IdentNode;
+ import jdk.nashorn.internal.ir.IfNode;
++import jdk.nashorn.internal.ir.JoinPredecessor;
++import jdk.nashorn.internal.ir.JoinPredecessorExpression;
+ import jdk.nashorn.internal.ir.LabelNode;
+ import jdk.nashorn.internal.ir.LexicalContext;
++import jdk.nashorn.internal.ir.LocalVariableConversion;
+ import jdk.nashorn.internal.ir.Node;
+ import jdk.nashorn.internal.ir.SplitNode;
+ import jdk.nashorn.internal.ir.Statement;
+ import jdk.nashorn.internal.ir.SwitchNode;
++import jdk.nashorn.internal.ir.ThrowNode;
+ import jdk.nashorn.internal.ir.TryNode;
+ import jdk.nashorn.internal.ir.UnaryNode;
+ import jdk.nashorn.internal.ir.VarNode;
+@@ -70,25 +77,30 @@
+ /** Print line numbers */
+ private final boolean printLineNumbers;
+
++ /** Print inferred and optimistic types */
++ private final boolean printTypes;
++
+ private int lastLineNumber = -1;
+
+ /**
+ * Constructor.
+ */
+ public PrintVisitor() {
+- this(true);
++ this(true, true);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param printLineNumbers should line number nodes be included in the output?
++ * @param printTypes should we print optimistic and inferred types?
+ */
+- public PrintVisitor(final boolean printLineNumbers) {
++ public PrintVisitor(final boolean printLineNumbers, final boolean printTypes) {
+ super(new LexicalContext());
+ this.EOLN = System.lineSeparator();
+ this.sb = new StringBuilder();
+ this.printLineNumbers = printLineNumbers;
++ this.printTypes = printTypes;
+ }
+
+ /**
+@@ -97,7 +109,7 @@
+ * @param root a node from which to start printing code
+ */
+ public PrintVisitor(final Node root) {
+- this(root, true);
++ this(root, true, true);
+ }
+
+ /**
+@@ -105,9 +117,10 @@
+ *
+ * @param root a node from which to start printing code
+ * @param printLineNumbers should line numbers nodes be included in the output?
++ * @param printTypes should we print optimistic and inferred types?
+ */
+- public PrintVisitor(final Node root, final boolean printLineNumbers) {
+- this(printLineNumbers);
++ public PrintVisitor(final Node root, final boolean printLineNumbers, final boolean printTypes) {
++ this(printLineNumbers, printTypes);
+ visit(root);
+ }
+
+@@ -135,7 +148,28 @@
+
+ @Override
+ public boolean enterDefault(final Node node) {
+- node.toString(sb);
++ node.toString(sb, printTypes);
++ return false;
++ }
++
++ @Override
++ public boolean enterContinueNode(final ContinueNode node) {
++ node.toString(sb, printTypes);
++ printLocalVariableConversion(node);
++ return false;
++ }
++
++ @Override
++ public boolean enterBreakNode(final BreakNode node) {
++ node.toString(sb, printTypes);
++ printLocalVariableConversion(node);
++ return false;
++ }
++
++ @Override
++ public boolean enterThrowNode(final ThrowNode node) {
++ node.toString(sb, printTypes);
++ printLocalVariableConversion(node);
+ return false;
+ }
+
+@@ -148,9 +182,9 @@
+
+ final List<Statement> statements = block.getStatements();
+
+- for (final Node statement : statements) {
+- if (printLineNumbers && (statement instanceof Statement)) {
+- final int lineNumber = ((Statement)statement).getLineNumber();
++ for (final Statement statement : statements) {
++ if (printLineNumbers) {
++ final int lineNumber = statement.getLineNumber();
+ sb.append('\n');
+ if (lineNumber != lastLineNumber) {
+ indent();
+@@ -162,10 +196,6 @@
+
+ statement.accept(this);
+
+- if (statement instanceof FunctionNode) {
+- continue;
+- }
+-
+ int lastIndex = sb.length() - 1;
+ char lastChar = sb.charAt(lastIndex);
+ while (Character.isWhitespace(lastChar) && lastIndex >= 0) {
+@@ -190,6 +220,7 @@
+ sb.append(EOLN);
+ indent();
+ sb.append('}');
++ printLocalVariableConversion(block);
+
+ return false;
+ }
+@@ -211,13 +242,31 @@
+ }
+
+ @Override
++ public boolean enterJoinPredecessorExpression(final JoinPredecessorExpression expr) {
++ expr.getExpression().accept(this);
++ printLocalVariableConversion(expr);
++ return false;
++ }
++
++ @Override
++ public boolean enterIdentNode(final IdentNode identNode) {
++ identNode.toString(sb, printTypes);
++ printLocalVariableConversion(identNode);
++ return true;
++ }
++
++ private void printLocalVariableConversion(final JoinPredecessor joinPredecessor) {
++ LocalVariableConversion.toString(joinPredecessor.getLocalVariableConversion(), sb);
++ }
++
++ @Override
+ public boolean enterUnaryNode(final UnaryNode unaryNode) {
+ unaryNode.toString(sb, new Runnable() {
+ @Override
+ public void run() {
+- unaryNode.rhs().accept(PrintVisitor.this);
++ unaryNode.getExpression().accept(PrintVisitor.this);
+ }
+- });
++ }, printTypes);
+ return false;
+ }
+
+@@ -229,21 +278,21 @@
+
+ @Override
+ public boolean enterForNode(final ForNode forNode) {
+- forNode.toString(sb);
++ forNode.toString(sb, printTypes);
+ forNode.getBody().accept(this);
+ return false;
+ }
+
+ @Override
+ public boolean enterFunctionNode(final FunctionNode functionNode) {
+- functionNode.toString(sb);
++ functionNode.toString(sb, printTypes);
+ enterBlock(functionNode.getBody());
+ return false;
+ }
+
+ @Override
+ public boolean enterIfNode(final IfNode ifNode) {
+- ifNode.toString(sb);
++ ifNode.toString(sb, printTypes);
+ ifNode.getPass().accept(this);
+
+ final Block fail = ifNode.getFail();
+@@ -252,7 +301,12 @@
+ sb.append(" else ");
+ fail.accept(this);
+ }
+-
++ if(ifNode.getLocalVariableConversion() != null) {
++ assert fail == null;
++ sb.append(" else ");
++ printLocalVariableConversion(ifNode);
++ sb.append(";");
++ }
+ return false;
+ }
+
+@@ -261,15 +315,15 @@
+ indent -= TABWIDTH;
+ indent();
+ indent += TABWIDTH;
+- labeledNode.toString(sb);
++ labeledNode.toString(sb, printTypes);
+ labeledNode.getBody().accept(this);
+-
++ printLocalVariableConversion(labeledNode);
+ return false;
+ }
+
+ @Override
+ public boolean enterSplitNode(final SplitNode splitNode) {
+- splitNode.toString(sb);
++ splitNode.toString(sb, printTypes);
+ sb.append(EOLN);
+ indent += TABWIDTH;
+ indent();
+@@ -287,7 +341,7 @@
+
+ @Override
+ public boolean enterSwitchNode(final SwitchNode switchNode) {
+- switchNode.toString(sb);
++ switchNode.toString(sb, printTypes);
+ sb.append(" {");
+
+ final List<CaseNode> cases = switchNode.getCases();
+@@ -295,13 +349,20 @@
+ for (final CaseNode caseNode : cases) {
+ sb.append(EOLN);
+ indent();
+- caseNode.toString(sb);
++ caseNode.toString(sb, printTypes);
++ printLocalVariableConversion(caseNode);
+ indent += TABWIDTH;
+ caseNode.getBody().accept(this);
+ indent -= TABWIDTH;
+ sb.append(EOLN);
+ }
+-
++ if(switchNode.getLocalVariableConversion() != null) {
++ sb.append(EOLN);
++ indent();
++ sb.append("default: ");
++ printLocalVariableConversion(switchNode);
++ sb.append("{}");
++ }
+ sb.append(EOLN);
+ indent();
+ sb.append("}");
+@@ -311,14 +372,15 @@
+
+ @Override
+ public boolean enterTryNode(final TryNode tryNode) {
+- tryNode.toString(sb);
++ tryNode.toString(sb, printTypes);
++ printLocalVariableConversion(tryNode);
+ tryNode.getBody().accept(this);
+
+ final List<Block> catchBlocks = tryNode.getCatchBlocks();
+
+ for (final Block catchBlock : catchBlocks) {
+ final CatchNode catchNode = (CatchNode)catchBlock.getStatements().get(0);
+- catchNode.toString(sb);
++ catchNode.toString(sb, printTypes);
+ catchNode.getBody().accept(this);
+ }
+
+@@ -335,7 +397,8 @@
+ @Override
+ public boolean enterVarNode(final VarNode varNode) {
+ sb.append("var ");
+- varNode.getName().toString(sb);
++ varNode.getName().toString(sb, printTypes);
++ printLocalVariableConversion(varNode.getName());
+ final Node init = varNode.getInit();
+ if (init != null) {
+ sb.append(" = ");
+@@ -347,13 +410,14 @@
+
+ @Override
+ public boolean enterWhileNode(final WhileNode whileNode) {
++ printLocalVariableConversion(whileNode);
+ if (whileNode.isDoWhile()) {
+ sb.append("do");
+ whileNode.getBody().accept(this);
+ sb.append(' ');
+- whileNode.toString(sb);
++ whileNode.toString(sb, printTypes);
+ } else {
+- whileNode.toString(sb);
++ whileNode.toString(sb, printTypes);
+ whileNode.getBody().accept(this);
+ }
+
+@@ -362,7 +426,7 @@
+
+ @Override
+ public boolean enterWithNode(final WithNode withNode) {
+- withNode.toString(sb);
++ withNode.toString(sb, printTypes);
+ withNode.getBody().accept(this);
+
+ return false;
+--- ./nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -53,8 +53,6 @@
+ return enterBIT_NOT(unaryNode);
+ case DELETE:
+ return enterDELETE(unaryNode);
+- case DISCARD:
+- return enterDISCARD(unaryNode);
+ case NEW:
+ return enterNEW(unaryNode);
+ case NOT:
+@@ -84,8 +82,6 @@
+ return leaveBIT_NOT(unaryNode);
+ case DELETE:
+ return leaveDELETE(unaryNode);
+- case DISCARD:
+- return leaveDISCARD(unaryNode);
+ case NEW:
+ return leaveNEW(unaryNode);
+ case NOT:
+@@ -359,26 +355,6 @@
+ }
+
+ /**
+- * Unary enter - callback for entering a discard operator
+- *
+- * @param unaryNode the node
+- * @return true if traversal should continue and node children be traversed, false otherwise
+- */
+- public boolean enterDISCARD(final UnaryNode unaryNode) {
+- return enterDefault(unaryNode);
+- }
+-
+- /**
+- * Unary leave - callback for leaving a discard operator
+- *
+- * @param unaryNode the node
+- * @return processed node, which will replace the original one, or the original node
+- */
+- public Node leaveDISCARD(final UnaryNode unaryNode) {
+- return leaveDefault(unaryNode);
+- }
+-
+- /**
+ * Unary enter - callback for entering a new operator
+ *
+ * @param unaryNode the node
+--- ./nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -38,9 +38,11 @@
+ import jdk.nashorn.internal.ir.ExpressionStatement;
+ import jdk.nashorn.internal.ir.ForNode;
+ import jdk.nashorn.internal.ir.FunctionNode;
++import jdk.nashorn.internal.ir.GetSplitState;
+ import jdk.nashorn.internal.ir.IdentNode;
+ import jdk.nashorn.internal.ir.IfNode;
+ import jdk.nashorn.internal.ir.IndexNode;
++import jdk.nashorn.internal.ir.JoinPredecessorExpression;
+ import jdk.nashorn.internal.ir.LabelNode;
+ import jdk.nashorn.internal.ir.LexicalContext;
+ import jdk.nashorn.internal.ir.LiteralNode;
+@@ -49,7 +51,9 @@
+ import jdk.nashorn.internal.ir.PropertyNode;
+ import jdk.nashorn.internal.ir.ReturnNode;
+ import jdk.nashorn.internal.ir.RuntimeNode;
++import jdk.nashorn.internal.ir.SetSplitState;
+ import jdk.nashorn.internal.ir.SplitNode;
++import jdk.nashorn.internal.ir.SplitReturn;
+ import jdk.nashorn.internal.ir.SwitchNode;
+ import jdk.nashorn.internal.ir.TernaryNode;
+ import jdk.nashorn.internal.ir.ThrowNode;
+@@ -389,6 +393,26 @@
+ }
+
+ /**
++ * Callback for entering a {@link GetSplitState}.
++ *
++ * @param getSplitState the get split state expression
++ * @return true if traversal should continue and node children be traversed, false otherwise
++ */
++ public boolean enterGetSplitState(final GetSplitState getSplitState) {
++ return enterDefault(getSplitState);
++ }
++
++ /**
++ * Callback for leaving a {@link GetSplitState}.
++ *
++ * @param getSplitState the get split state expression
++ * @return processed node, which will replace the original one, or the original node
++ */
++ public Node leaveGetSplitState(final GetSplitState getSplitState) {
++ return leaveDefault(getSplitState);
++ }
++
++ /**
+ * Callback for entering an IdentNode
+ *
+ * @param identNode the node
+@@ -569,6 +593,26 @@
+ }
+
+ /**
++ * Callback for entering a {@link SetSplitState}.
++ *
++ * @param setSplitState the set split state statement
++ * @return true if traversal should continue and node children be traversed, false otherwise
++ */
++ public boolean enterSetSplitState(final SetSplitState setSplitState) {
++ return enterDefault(setSplitState);
++ }
++
++ /**
++ * Callback for leaving a {@link SetSplitState}.
++ *
++ * @param setSplitState the set split state expression
++ * @return processed node, which will replace the original one, or the original node
++ */
++ public Node leaveSetSplitState(final SetSplitState setSplitState) {
++ return leaveDefault(setSplitState);
++ }
++
++ /**
+ * Callback for entering a SplitNode
+ *
+ * @param splitNode the node
+@@ -589,6 +633,26 @@
+ }
+
+ /**
++ * Callback for entering a SplitReturn
++ *
++ * @param splitReturn the node
++ * @return true if traversal should continue and node children be traversed, false otherwise
++ */
++ public boolean enterSplitReturn(final SplitReturn splitReturn) {
++ return enterDefault(splitReturn);
++ }
++
++ /**
++ * Callback for leaving a SplitReturn
++ *
++ * @param splitReturn the node
++ * @return processed node, which will replace the original one, or the original node
++ */
++ public Node leaveSplitReturn(final SplitReturn splitReturn) {
++ return leaveDefault(splitReturn);
++ }
++
++ /**
+ * Callback for entering a SwitchNode
+ *
+ * @param switchNode the node
+@@ -689,6 +753,27 @@
+ }
+
+ /**
++ * Callback for entering a {@link JoinPredecessorExpression}.
++ *
++ * @param expr the join predecessor expression
++ * @return true if traversal should continue and node children be traversed, false otherwise
++ */
++ public boolean enterJoinPredecessorExpression(final JoinPredecessorExpression expr) {
++ return enterDefault(expr);
++ }
++
++ /**
++ * Callback for leaving a {@link JoinPredecessorExpression}.
++ *
++ * @param expr the join predecessor expression
++ * @return processed node, which will replace the original one, or the original node
++ */
++ public Node leaveJoinPredecessorExpression(final JoinPredecessorExpression expr) {
++ return leaveDefault(expr);
++ }
++
++
++ /**
+ * Callback for entering a VarNode
+ *
+ * @param varNode the node
+--- ./nashorn/src/jdk/nashorn/internal/lookup/Lookup.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/lookup/Lookup.java Wed Feb 04 12:14:47 2015 -0800
+@@ -68,6 +68,12 @@
+ /** Method handle to the most generic of setters, the one that takes an Object */
+ public static final MethodType SET_OBJECT_TYPE = MH.type(void.class, Object.class, Object.class);
+
++ /** Method handle to the primitive getters, the one that returns an long/int/double */
++ public static final MethodType GET_PRIMITIVE_TYPE = MH.type(long.class, Object.class);
++
++ /** Method handle to the primitive getters, the one that returns an long/int/double */
++ public static final MethodType SET_PRIMITIVE_TYPE = MH.type(void.class, Object.class, long.class);
++
+ private Lookup() {
+ }
+
+@@ -123,6 +129,53 @@
+ }
+
+ /**
++ * This method filters primitive argument types using JavaScript semantics. For example,
++ * an (int) cast of a double in Java land is not the same thing as invoking toInt32 on it.
++ * If you are returning values to JavaScript that have to be of a specific type, this is
++ * the correct return value filter to use, as the explicitCastArguments just uses the
++ * Java boxing equivalents
++ *
++ * @param mh method handle for which to filter argument value
++ * @param n argument index
++ * @param from old argument type, the new one is given by the sent method handle
++ * @return method handle for appropriate argument type conversion
++ */
++ public static MethodHandle filterArgumentType(final MethodHandle mh, final int n, final Class<?> from) {
++ final Class<?> to = mh.type().parameterType(n);
++
++ if (from == int.class) {
++ //fallthru
++ } else if (from == long.class) {
++ if (to == int.class) {
++ return MH.filterArguments(mh, n, JSType.TO_INT32_L.methodHandle());
++ }
++ //fallthru
++ } else if (from == double.class) {
++ if (to == int.class) {
++ return MH.filterArguments(mh, n, JSType.TO_INT32_D.methodHandle());
++ } else if (to == long.class) {
++ return MH.filterArguments(mh, n, JSType.TO_UINT32_D.methodHandle());
++ }
++ //fallthru
++ } else if (!from.isPrimitive()) {
++ if (to == int.class) {
++ return MH.filterArguments(mh, n, JSType.TO_INT32.methodHandle());
++ } else if (to == long.class) {
++ return MH.filterArguments(mh, n, JSType.TO_UINT32.methodHandle());
++ } else if (to == double.class) {
++ return MH.filterArguments(mh, n, JSType.TO_NUMBER.methodHandle());
++ } else if (!to.isPrimitive()) {
++ return mh;
++ }
++
++ assert false : "unsupported Lookup.filterReturnType type " + from + " -> " + to;
++ }
++
++ //use a standard cast - we don't need to check JavaScript special cases
++ return MH.explicitCastArguments(mh, mh.type().changeParameterType(n, from));
++ }
++
++ /**
+ * This method filters primitive return types using JavaScript semantics. For example,
+ * an (int) cast of a double in Java land is not the same thing as invoking toInt32 on it.
+ * If you are returning values to JavaScript that have to be of a specific type, this is
+@@ -139,6 +192,9 @@
+ if (retType == int.class) {
+ //fallthru
+ } else if (retType == long.class) {
++ if (type == int.class) {
++ return MH.filterReturnValue(mh, JSType.TO_INT32_L.methodHandle());
++ }
+ //fallthru
+ } else if (retType == double.class) {
+ if (type == int.class) {
+--- ./nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java Wed Feb 04 12:14:47 2015 -0800
+@@ -37,15 +37,18 @@
+ import java.util.List;
+ import java.util.logging.Level;
+ import jdk.nashorn.internal.runtime.ConsString;
++import jdk.nashorn.internal.runtime.Context;
+ import jdk.nashorn.internal.runtime.Debug;
+-import jdk.nashorn.internal.runtime.DebugLogger;
+ import jdk.nashorn.internal.runtime.ScriptObject;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
+ import jdk.nashorn.internal.runtime.options.Options;
+
+ /**
+ * This class is abstraction for all method handle, switchpoint and method type
+ * operations. This enables the functionality interface to be subclassed and
+- * intrumensted, as it has been proven vital to keep the number of method
++ * instrumented, as it has been proven vital to keep the number of method
+ * handles in the system down.
+ *
+ * All operations of the above type should go through this class, and not
+@@ -96,27 +99,9 @@
+ return obj.toString();
+ }
+
+- private static final MethodHandleFunctionality STANDARD = new StandardMethodHandleFunctionality();
+- private static final MethodHandleFunctionality FUNC;
+-
+- private static final String DEBUG_PROPERTY = "nashorn.methodhandles.debug";
+- private static final DebugLogger LOG = new DebugLogger("methodhandles", DEBUG_PROPERTY);
+-
+- static {
+- if (LOG.isEnabled() || Options.getBooleanProperty(DEBUG_PROPERTY)) {
+- if (Options.getStringProperty(DEBUG_PROPERTY, "").equals("create")) {
+- FUNC = new TraceCreateMethodHandleFunctionality();
+- } else {
+- FUNC = new TraceMethodHandleFunctionality();
+- }
+- } else {
+- FUNC = STANDARD;
+- }
+- }
+-
++ private static final MethodHandleFunctionality FUNC = new StandardMethodHandleFunctionality();
+ private static final boolean PRINT_STACKTRACE = Options.getBooleanProperty("nashorn.methodhandles.debug.stacktrace");
+
+-
+ /**
+ * Return the method handle functionality used for all method handle operations
+ * @return a method handle functionality implementation
+@@ -125,8 +110,15 @@
+ return FUNC;
+ }
+
+- private static final MethodHandle TRACE = STANDARD.findStatic(LOOKUP, MethodHandleFactory.class, "traceArgs", MethodType.methodType(void.class, DebugLogger.class, String.class, int.class, Object[].class));
+- private static final MethodHandle TRACE_RETURN = STANDARD.findStatic(LOOKUP, MethodHandleFactory.class, "traceReturn", MethodType.methodType(Object.class, DebugLogger.class, Object.class));
++ private static final MethodHandle TRACE = FUNC.findStatic(LOOKUP, MethodHandleFactory.class, "traceArgs", MethodType.methodType(void.class, DebugLogger.class, String.class, int.class, Object[].class));
++ private static final MethodHandle TRACE_RETURN = FUNC.findStatic(LOOKUP, MethodHandleFactory.class, "traceReturn", MethodType.methodType(Object.class, DebugLogger.class, Object.class));
++ private static final MethodHandle TRACE_RETURN_VOID = FUNC.findStatic(LOOKUP, MethodHandleFactory.class, "traceReturnVoid", MethodType.methodType(void.class, DebugLogger.class));
++
++ private static final String VOID_TAG = "[VOID]";
++
++ private static void err(final String str) {
++ Context.getContext().getErr().println(str);
++ }
+
+ /**
+ * Tracer that is applied before a value is returned from the traced function. It will output the return
+@@ -136,11 +128,23 @@
+ * @return return value unmodified
+ */
+ static Object traceReturn(final DebugLogger logger, final Object value) {
+- final String str = "\treturn: " + stripName(value) + " [type=" + (value == null ? "null" : stripName(value.getClass()) + ']');
+- logger.log(TRACE_LEVEL, str);
++ final String str = " return" +
++ (VOID_TAG.equals(value) ?
++ ";" :
++ " " + stripName(value) + "; // [type=" + (value == null ? "null]" : stripName(value.getClass()) + ']'));
++ if (logger == null) {
++ err(str);
++ } else if (logger.isEnabled()) {
++ logger.log(TRACE_LEVEL, str);
++ }
++
+ return value;
+ }
+
++ static void traceReturnVoid(final DebugLogger logger) {
++ traceReturn(logger, VOID_TAG);
++ }
++
+ /**
+ * Tracer that is applied before a function is called, printing the arguments
+ *
+@@ -172,8 +176,11 @@
+ }
+ }
+
+- assert logger != null;
+- logger.log(TRACE_LEVEL, sb);
++ if (logger == null) {
++ err(sb.toString());
++ } else {
++ logger.log(TRACE_LEVEL, sb);
++ }
+ stacktrace(logger);
+ }
+
+@@ -184,7 +191,12 @@
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final PrintStream ps = new PrintStream(baos);
+ new Throwable().printStackTrace(ps);
+- logger.log(TRACE_LEVEL, baos.toString());
++ final String st = baos.toString();
++ if (logger == null) {
++ err(st);
++ } else {
++ logger.log(TRACE_LEVEL, st);
++ }
+ }
+
+ private static String argString(final Object arg) {
+@@ -203,8 +215,8 @@
+
+ if (arg instanceof ScriptObject) {
+ return arg.toString() +
+- " (map=" + Debug.id((((ScriptObject)arg).getMap())) +
+- ")";
++ " (map=" + Debug.id(((ScriptObject)arg).getMap()) +
++ ')';
+ }
+
+ return arg.toString();
+@@ -212,35 +224,63 @@
+
+ /**
+ * Add a debug printout to a method handle, tracing parameters and return values
++ * Output will be unconditional to stderr
+ *
+- * @param logger a specific logger to which to write the output
+ * @param mh method handle to trace
+ * @param tag start of trace message
+ * @return traced method handle
+ */
+- public static MethodHandle addDebugPrintout(final DebugLogger logger, final MethodHandle mh, final Object tag) {
+- return addDebugPrintout(logger, mh, 0, true, tag);
++ public static MethodHandle addDebugPrintout(final MethodHandle mh, final Object tag) {
++ return addDebugPrintout(null, Level.OFF, mh, 0, true, tag);
+ }
+
+-
+ /**
+ * Add a debug printout to a method handle, tracing parameters and return values
+ *
+ * @param logger a specific logger to which to write the output
++ * @param level level over which to print
++ * @param mh method handle to trace
++ * @param tag start of trace message
++ * @return traced method handle
++ */
++ public static MethodHandle addDebugPrintout(final DebugLogger logger, final Level level, final MethodHandle mh, final Object tag) {
++ return addDebugPrintout(logger, level, mh, 0, true, tag);
++ }
++
++ /**
++ * Add a debug printout to a method handle, tracing parameters and return values
++ * Output will be unconditional to stderr
++ *
+ * @param mh method handle to trace
+ * @param paramStart first param to print/trace
+ * @param printReturnValue should we print/trace return value if available?
+ * @param tag start of trace message
+ * @return traced method handle
+ */
+- public static MethodHandle addDebugPrintout(final DebugLogger logger, final MethodHandle mh, final int paramStart, final boolean printReturnValue, final Object tag) {
++ public static MethodHandle addDebugPrintout(final MethodHandle mh, final int paramStart, final boolean printReturnValue, final Object tag) {
++ return addDebugPrintout(null, Level.OFF, mh, paramStart, printReturnValue, tag);
++ }
++
++ /**
++ * Add a debug printout to a method handle, tracing parameters and return values
++ *
++ * @param logger a specific logger to which to write the output
++ * @param level level over which to print
++ * @param mh method handle to trace
++ * @param paramStart first param to print/trace
++ * @param printReturnValue should we print/trace return value if available?
++ * @param tag start of trace message
++ * @return traced method handle
++ */
++ public static MethodHandle addDebugPrintout(final DebugLogger logger, final Level level, final MethodHandle mh, final int paramStart, final boolean printReturnValue, final Object tag) {
+ final MethodType type = mh.type();
+
+- if (logger != null && logger.levelAbove(TRACE_LEVEL)) {
++ //if there is no logger, or if it's set to log only coarser events
++ //than the trace level, skip and return
++ if (logger != null && logger.levelCoarserThan(level)) {
+ return mh;
+ }
+
+- assert logger != null;
+ assert TRACE != null;
+
+ MethodHandle trace = MethodHandles.insertArguments(TRACE, 0, logger, tag, paramStart);
+@@ -253,191 +293,49 @@
+ asType(type.changeReturnType(void.class)));
+
+ final Class<?> retType = type.returnType();
+- if (retType != void.class && printReturnValue) {
+- final MethodHandle traceReturn = MethodHandles.insertArguments(TRACE_RETURN, 0, logger);
+- trace = MethodHandles.filterReturnValue(trace,
+- traceReturn.asType(
+- traceReturn.type().changeParameterType(0, retType).changeReturnType(retType)));
++ if (printReturnValue) {
++ if (retType != void.class) {
++ final MethodHandle traceReturn = MethodHandles.insertArguments(TRACE_RETURN, 0, logger);
++ trace = MethodHandles.filterReturnValue(trace,
++ traceReturn.asType(
++ traceReturn.type().changeParameterType(0, retType).changeReturnType(retType)));
++ } else {
++ trace = MethodHandles.filterReturnValue(trace, MethodHandles.insertArguments(TRACE_RETURN_VOID, 0, logger));
++ }
+ }
+
+ return trace;
+ }
+
+ /**
+- * The standard class that marshalls all method handle operations to the java.lang.invoke
++ * Class that marshalls all method handle operations to the java.lang.invoke
+ * package. This exists only so that it can be subclassed and method handles created from
+ * Nashorn made possible to instrument.
+ *
+ * All Nashorn classes should use the MethodHandleFactory for their method handle operations
+ */
+- private static class StandardMethodHandleFunctionality implements MethodHandleFunctionality {
++ @Logger(name="methodhandles")
++ private static class StandardMethodHandleFunctionality implements MethodHandleFunctionality, Loggable {
+
+- @Override
+- public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
+- return MethodHandles.filterArguments(target, pos, filters);
++ // for bootstrapping reasons, because a lot of static fields use MH for lookups, we
++ // need to set the logger when the Global object is finished. This means that we don't
++ // get instrumentation for public static final MethodHandle SOMETHING = MH... in the builtin
++ // classes, but that doesn't matter, because this is usually not where we want it
++ private DebugLogger log = DebugLogger.DISABLED_LOGGER;
++
++ public StandardMethodHandleFunctionality() {
+ }
+
+ @Override
+- public MethodHandle filterReturnValue(final MethodHandle target, final MethodHandle filter) {
+- return MethodHandles.filterReturnValue(target, filter);
++ public DebugLogger initLogger(final Context context) {
++ return this.log = context.getLogger(this.getClass());
+ }
+
+ @Override
+- public MethodHandle guardWithTest(final MethodHandle test, final MethodHandle target, final MethodHandle fallback) {
+- return MethodHandles.guardWithTest(test, target, fallback);
++ public DebugLogger getLogger() {
++ return log;
+ }
+
+- @Override
+- public MethodHandle insertArguments(final MethodHandle target, final int pos, final Object... values) {
+- return MethodHandles.insertArguments(target, pos, values);
+- }
+-
+- @Override
+- public MethodHandle dropArguments(final MethodHandle target, final int pos, final Class<?>... valueTypes) {
+- return MethodHandles.dropArguments(target, pos, valueTypes);
+- }
+-
+- @Override
+- public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> valueTypes) {
+- return MethodHandles.dropArguments(target, pos, valueTypes);
+- }
+-
+- @Override
+- public MethodHandle asType(final MethodHandle handle, final MethodType type) {
+- return handle.asType(type);
+- }
+-
+- @Override
+- public MethodHandle bindTo(final MethodHandle handle, final Object x) {
+- return handle.bindTo(x);
+- }
+-
+- @Override
+- public MethodHandle foldArguments(final MethodHandle target, final MethodHandle combiner) {
+- return MethodHandles.foldArguments(target, combiner);
+- }
+-
+- @Override
+- public MethodHandle explicitCastArguments(final MethodHandle target, final MethodType type) {
+- return MethodHandles.explicitCastArguments(target, type);
+- }
+-
+- @Override
+- public MethodHandle arrayElementGetter(final Class<?> type) {
+- return MethodHandles.arrayElementGetter(type);
+- }
+-
+- @Override
+- public MethodHandle arrayElementSetter(final Class<?> type) {
+- return MethodHandles.arrayElementSetter(type);
+- }
+-
+- @Override
+- public MethodHandle throwException(final Class<?> returnType, final Class<? extends Throwable> exType) {
+- return MethodHandles.throwException(returnType, exType);
+- }
+-
+- @Override
+- public MethodHandle constant(final Class<?> type, final Object value) {
+- return MethodHandles.constant(type, value);
+- }
+-
+- @Override
+- public MethodHandle asCollector(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
+- return handle.asCollector(arrayType, arrayLength);
+- }
+-
+- @Override
+- public MethodHandle asSpreader(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
+- return handle.asSpreader(arrayType, arrayLength);
+- }
+-
+- @Override
+- public MethodHandle getter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+- try {
+- return explicitLookup.findGetter(clazz, name, type);
+- } catch (final NoSuchFieldException | IllegalAccessException e) {
+- throw new LookupException(e);
+- }
+- }
+-
+- @Override
+- public MethodHandle staticGetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+- try {
+- return explicitLookup.findStaticGetter(clazz, name, type);
+- } catch (final NoSuchFieldException | IllegalAccessException e) {
+- throw new LookupException(e);
+- }
+- }
+-
+-
+- @Override
+- public MethodHandle setter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+- try {
+- return explicitLookup.findSetter(clazz, name, type);
+- } catch (final NoSuchFieldException | IllegalAccessException e) {
+- throw new LookupException(e);
+- }
+- }
+-
+- @Override
+- public MethodHandle staticSetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+- try {
+- return explicitLookup.findStaticSetter(clazz, name, type);
+- } catch (final NoSuchFieldException | IllegalAccessException e) {
+- throw new LookupException(e);
+- }
+- }
+-
+- @Override
+- public MethodHandle find(final Method method) {
+- try {
+- return PUBLIC_LOOKUP.unreflect(method);
+- } catch (final IllegalAccessException e) {
+- throw new LookupException(e);
+- }
+- }
+-
+- @Override
+- public MethodHandle findStatic(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
+- try {
+- return explicitLookup.findStatic(clazz, name, type);
+- } catch (final NoSuchMethodException | IllegalAccessException e) {
+- throw new LookupException(e);
+- }
+- }
+-
+- @Override
+- public MethodHandle findVirtual(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
+- try {
+- return explicitLookup.findVirtual(clazz, name, type);
+- } catch (final NoSuchMethodException | IllegalAccessException e) {
+- throw new LookupException(e);
+- }
+- }
+-
+- @Override
+- public SwitchPoint createSwitchPoint() {
+- return new SwitchPoint();
+- }
+-
+- @Override
+- public MethodHandle guardWithTest(final SwitchPoint sp, final MethodHandle before, final MethodHandle after) {
+- return sp.guardWithTest(before, after);
+- }
+-
+- @Override
+- public MethodType type(final Class<?> returnType, final Class<?>... paramTypes) {
+- return MethodType.methodType(returnType, paramTypes);
+- }
+-
+- }
+-
+- /**
+- * Class used for instrumenting and debugging Nashorn generated method handles
+- */
+- private static class TraceMethodHandleFunctionality extends StandardMethodHandleFunctionality {
+-
+ protected static String describe(final Object... data) {
+ final StringBuilder sb = new StringBuilder();
+
+@@ -470,177 +368,221 @@
+ }
+
+ public MethodHandle debug(final MethodHandle master, final String str, final Object... args) {
+- return addDebugPrintout(LOG, master, Integer.MAX_VALUE, false, str + ' ' + describe(args));
++ if (log.isEnabled()) {
++ if (PRINT_STACKTRACE) {
++ stacktrace(log);
++ }
++ return addDebugPrintout(log, Level.INFO, master, Integer.MAX_VALUE, false, str + ' ' + describe(args));
++ }
++ return master;
+ }
+
+ @Override
+ public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
+- final MethodHandle mh = super.filterArguments(target, pos, filters);
++ final MethodHandle mh = MethodHandles.filterArguments(target, pos, filters);
+ return debug(mh, "filterArguments", target, pos, filters);
+ }
+
+ @Override
+ public MethodHandle filterReturnValue(final MethodHandle target, final MethodHandle filter) {
+- final MethodHandle mh = super.filterReturnValue(target, filter);
++ final MethodHandle mh = MethodHandles.filterReturnValue(target, filter);
+ return debug(mh, "filterReturnValue", target, filter);
+ }
+
+ @Override
+ public MethodHandle guardWithTest(final MethodHandle test, final MethodHandle target, final MethodHandle fallback) {
+- final MethodHandle mh = super.guardWithTest(test, target, fallback);
++ final MethodHandle mh = MethodHandles.guardWithTest(test, target, fallback);
+ return debug(mh, "guardWithTest", test, target, fallback);
+ }
+
+ @Override
+ public MethodHandle insertArguments(final MethodHandle target, final int pos, final Object... values) {
+- final MethodHandle mh = super.insertArguments(target, pos, values);
++ final MethodHandle mh = MethodHandles.insertArguments(target, pos, values);
+ return debug(mh, "insertArguments", target, pos, values);
+ }
+
+ @Override
+ public MethodHandle dropArguments(final MethodHandle target, final int pos, final Class<?>... values) {
+- final MethodHandle mh = super.dropArguments(target, pos, values);
++ final MethodHandle mh = MethodHandles.dropArguments(target, pos, values);
+ return debug(mh, "dropArguments", target, pos, values);
+ }
+
+ @Override
+ public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> values) {
+- final MethodHandle mh = super.dropArguments(target, pos, values);
++ final MethodHandle mh = MethodHandles.dropArguments(target, pos, values);
+ return debug(mh, "dropArguments", target, pos, values);
+ }
+
+ @Override
+ public MethodHandle asType(final MethodHandle handle, final MethodType type) {
+- final MethodHandle mh = super.asType(handle, type);
++ final MethodHandle mh = handle.asType(type);
+ return debug(mh, "asType", handle, type);
+ }
+
+ @Override
+ public MethodHandle bindTo(final MethodHandle handle, final Object x) {
+- final MethodHandle mh = super.bindTo(handle, x);
++ final MethodHandle mh = handle.bindTo(x);
+ return debug(mh, "bindTo", handle, x);
+ }
+
+ @Override
+ public MethodHandle foldArguments(final MethodHandle target, final MethodHandle combiner) {
+- final MethodHandle mh = super.foldArguments(target, combiner);
++ final MethodHandle mh = MethodHandles.foldArguments(target, combiner);
+ return debug(mh, "foldArguments", target, combiner);
+ }
+
+ @Override
+ public MethodHandle explicitCastArguments(final MethodHandle target, final MethodType type) {
+- final MethodHandle mh = super.explicitCastArguments(target, type);
++ final MethodHandle mh = MethodHandles.explicitCastArguments(target, type);
+ return debug(mh, "explicitCastArguments", target, type);
+ }
+
+ @Override
+ public MethodHandle arrayElementGetter(final Class<?> type) {
+- final MethodHandle mh = super.arrayElementGetter(type);
++ final MethodHandle mh = MethodHandles.arrayElementGetter(type);
+ return debug(mh, "arrayElementGetter", type);
+ }
+
+ @Override
+ public MethodHandle arrayElementSetter(final Class<?> type) {
+- final MethodHandle mh = super.arrayElementSetter(type);
++ final MethodHandle mh = MethodHandles.arrayElementSetter(type);
+ return debug(mh, "arrayElementSetter", type);
+ }
+
+ @Override
+ public MethodHandle throwException(final Class<?> returnType, final Class<? extends Throwable> exType) {
+- final MethodHandle mh = super.throwException(returnType, exType);
++ final MethodHandle mh = MethodHandles.throwException(returnType, exType);
+ return debug(mh, "throwException", returnType, exType);
+ }
+
+ @Override
++ public MethodHandle catchException(final MethodHandle target, final Class<? extends Throwable> exType, final MethodHandle handler) {
++ final MethodHandle mh = MethodHandles.catchException(target, exType, handler);
++ return debug(mh, "catchException", exType);
++ }
++
++ @Override
+ public MethodHandle constant(final Class<?> type, final Object value) {
+- final MethodHandle mh = super.constant(type, value);
++ final MethodHandle mh = MethodHandles.constant(type, value);
+ return debug(mh, "constant", type, value);
+ }
+
+ @Override
++ public MethodHandle identity(final Class<?> type) {
++ final MethodHandle mh = MethodHandles.identity(type);
++ return debug(mh, "identity", type);
++ }
++
++ @Override
+ public MethodHandle asCollector(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
+- final MethodHandle mh = super.asCollector(handle, arrayType, arrayLength);
++ final MethodHandle mh = handle.asCollector(arrayType, arrayLength);
+ return debug(mh, "asCollector", handle, arrayType, arrayLength);
+ }
+
+ @Override
+ public MethodHandle asSpreader(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
+- final MethodHandle mh = super.asSpreader(handle, arrayType, arrayLength);
++ final MethodHandle mh = handle.asSpreader(arrayType, arrayLength);
+ return debug(mh, "asSpreader", handle, arrayType, arrayLength);
+ }
+
+ @Override
+ public MethodHandle getter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+- final MethodHandle mh = super.getter(explicitLookup, clazz, name, type);
+- return debug(mh, "getter", explicitLookup, clazz, name, type);
++ try {
++ final MethodHandle mh = explicitLookup.findGetter(clazz, name, type);
++ return debug(mh, "getter", explicitLookup, clazz, name, type);
++ } catch (final NoSuchFieldException | IllegalAccessException e) {
++ throw new LookupException(e);
++ }
+ }
+
+ @Override
+ public MethodHandle staticGetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+- final MethodHandle mh = super.staticGetter(explicitLookup, clazz, name, type);
+- return debug(mh, "static getter", explicitLookup, clazz, name, type);
++ try {
++ final MethodHandle mh = explicitLookup.findStaticGetter(clazz, name, type);
++ return debug(mh, "static getter", explicitLookup, clazz, name, type);
++ } catch (final NoSuchFieldException | IllegalAccessException e) {
++ throw new LookupException(e);
++ }
+ }
+
+ @Override
+ public MethodHandle setter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+- final MethodHandle mh = super.setter(explicitLookup, clazz, name, type);
+- return debug(mh, "setter", explicitLookup, clazz, name, type);
++ try {
++ final MethodHandle mh = explicitLookup.findSetter(clazz, name, type);
++ return debug(mh, "setter", explicitLookup, clazz, name, type);
++ } catch (final NoSuchFieldException | IllegalAccessException e) {
++ throw new LookupException(e);
++ }
+ }
+
+ @Override
+ public MethodHandle staticSetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+- final MethodHandle mh = super.staticSetter(explicitLookup, clazz, name, type);
+- return debug(mh, "static setter", explicitLookup, clazz, name, type);
++ try {
++ final MethodHandle mh = explicitLookup.findStaticSetter(clazz, name, type);
++ return debug(mh, "static setter", explicitLookup, clazz, name, type);
++ } catch (final NoSuchFieldException | IllegalAccessException e) {
++ throw new LookupException(e);
++ }
+ }
+
+ @Override
+ public MethodHandle find(final Method method) {
+- final MethodHandle mh = super.find(method);
+- return debug(mh, "find", method);
++ try {
++ final MethodHandle mh = PUBLIC_LOOKUP.unreflect(method);
++ return debug(mh, "find", method);
++ } catch (final IllegalAccessException e) {
++ throw new LookupException(e);
++ }
+ }
+
+ @Override
+ public MethodHandle findStatic(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
+- final MethodHandle mh = super.findStatic(explicitLookup, clazz, name, type);
+- return debug(mh, "findStatic", explicitLookup, clazz, name, type);
++ try {
++ final MethodHandle mh = explicitLookup.findStatic(clazz, name, type);
++ return debug(mh, "findStatic", explicitLookup, clazz, name, type);
++ } catch (final NoSuchMethodException | IllegalAccessException e) {
++ throw new LookupException(e);
++ }
++ }
++
++ @Override
++ public MethodHandle findSpecial(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type, final Class<?> thisClass) {
++ try {
++ final MethodHandle mh = explicitLookup.findSpecial(clazz, name, type, thisClass);
++ return debug(mh, "findSpecial", explicitLookup, clazz, name, type);
++ } catch (final NoSuchMethodException | IllegalAccessException e) {
++ throw new LookupException(e);
++ }
+ }
+
+ @Override
+ public MethodHandle findVirtual(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
+- final MethodHandle mh = super.findVirtual(explicitLookup, clazz, name, type);
+- return debug(mh, "findVirtual", explicitLookup, clazz, name, type);
++ try {
++ final MethodHandle mh = explicitLookup.findVirtual(clazz, name, type);
++ return debug(mh, "findVirtual", explicitLookup, clazz, name, type);
++ } catch (final NoSuchMethodException | IllegalAccessException e) {
++ throw new LookupException(e);
++ }
+ }
+
+ @Override
+ public SwitchPoint createSwitchPoint() {
+- final SwitchPoint sp = super.createSwitchPoint();
+- LOG.log(TRACE_LEVEL, "createSwitchPoint ", sp);
++ final SwitchPoint sp = new SwitchPoint();
++ log.log(TRACE_LEVEL, "createSwitchPoint ", sp);
+ return sp;
+ }
+
+ @Override
+ public MethodHandle guardWithTest(final SwitchPoint sp, final MethodHandle before, final MethodHandle after) {
+- final MethodHandle mh = super.guardWithTest(sp, before, after);
++ final MethodHandle mh = sp.guardWithTest(before, after);
+ return debug(mh, "guardWithTest", sp, before, after);
+ }
+
+ @Override
+ public MethodType type(final Class<?> returnType, final Class<?>... paramTypes) {
+- final MethodType mt = super.type(returnType, paramTypes);
+- LOG.log(TRACE_LEVEL, "methodType ", returnType, " ", Arrays.toString(paramTypes), " ", mt);
++ final MethodType mt = MethodType.methodType(returnType, paramTypes);
++ log.log(TRACE_LEVEL, "methodType ", returnType, " ", Arrays.toString(paramTypes), " ", mt);
+ return mt;
+ }
+ }
+-
+- /**
+- * Class used for debugging Nashorn generated method handles
+- */
+- private static class TraceCreateMethodHandleFunctionality extends TraceMethodHandleFunctionality {
+- @Override
+- public MethodHandle debug(final MethodHandle master, final String str, final Object... args) {
+- LOG.log(TRACE_LEVEL, str, " ", describe(args));
+- stacktrace(LOG);
+- return master;
+- }
+- }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java Wed Feb 04 12:14:47 2015 -0800
+@@ -152,6 +152,17 @@
+ public MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType);
+
+ /**
++ * Wrapper for {@link java.lang.invoke.MethodHandles#catchException(MethodHandle, Class, MethodHandle)}
++ *
++ * @param target target method
++ * @param exType exception type
++ * @param handler the method handle to call when exception is thrown
++ *
++ * @return exception thrower method handle
++ */
++ public MethodHandle catchException(final MethodHandle target, final Class<? extends Throwable> exType, final MethodHandle handler);
++
++ /**
+ * Wrapper for {@link java.lang.invoke.MethodHandles#constant(Class, Object)}
+ *
+ * @param type type of constant
+@@ -162,6 +173,15 @@
+ public MethodHandle constant(Class<?> type, Object value);
+
+ /**
++ * Wrapper for {@link java.lang.invoke.MethodHandles#identity(Class)}
++ *
++ * @param type type of value
++ *
++ * @return method handle that returns identity argument
++ */
++ public MethodHandle identity(Class<?> type);
++
++ /**
+ * Wrapper for {@link java.lang.invoke.MethodHandle#asType(MethodType)}
+ *
+ * @param handle method handle for type conversion
+@@ -286,6 +306,19 @@
+ public MethodHandle findVirtual(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type);
+
+ /**
++ * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findSpecial(Class, String, MethodType, Class)}
++ *
++ * @param explicitLookup explicit lookup to be used
++ * @param clazz class to look in
++ * @param name name of method
++ * @param type method type
++ * @param thisClass thisClass
++ *
++ * @return method handle for virtual method
++ */
++ public MethodHandle findSpecial(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type, final Class<?> thisClass);
++
++ /**
+ * Wrapper for SwitchPoint creation. Just like {@code new SwitchPoint()} but potentially
+ * tracked
+ *
+@@ -313,5 +346,6 @@
+ * @return the method type
+ */
+ public MethodType type(Class<?> returnType, Class<?>... paramTypes);
++
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -209,6 +209,11 @@
+ }
+
+ @Override
++ public String toString() {
++ return '[' + getClass().getSimpleName() + " {configurable=" + configurable + " enumerable=" + enumerable + " getter=" + get + " setter=" + set + "}]";
++ }
++
++ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 41 * hash + Objects.hashCode(this.configurable);
+--- ./nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,7 +26,13 @@
+ package jdk.nashorn.internal.objects;
+
+ import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
+-
++import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
++import java.nio.ByteBuffer;
++import java.nio.ByteOrder;
++import jdk.internal.dynalink.CallSiteDescriptor;
++import jdk.internal.dynalink.linker.GuardedInvocation;
++import jdk.internal.dynalink.linker.LinkRequest;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Getter;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+@@ -35,33 +41,56 @@
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
++import jdk.nashorn.internal.runtime.arrays.TypedArrayData;
+
++/**
++ * ArrayBufferView, es6 class or TypedArray implementation
++ */
+ @ScriptClass("ArrayBufferView")
+-abstract class ArrayBufferView extends ScriptObject {
++public abstract class ArrayBufferView extends ScriptObject {
++ private final NativeArrayBuffer buffer;
++ private final int byteOffset;
+
+ // initialized by nasgen
+ private static PropertyMap $nasgenmap$;
+
+ private ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength, final Global global) {
+ super($nasgenmap$);
+- checkConstructorArgs(buffer, byteOffset, elementLength);
+- this.setProto(getPrototype(global));
+- this.setArray(factory().createArrayData(buffer, byteOffset, elementLength));
++
++ final int bytesPerElement = bytesPerElement();
++
++ checkConstructorArgs(buffer.getByteLength(), bytesPerElement, byteOffset, elementLength);
++ setProto(getPrototype(global));
++
++ this.buffer = buffer;
++ this.byteOffset = byteOffset;
++
++ assert byteOffset % bytesPerElement == 0;
++ final int start = byteOffset / bytesPerElement;
++ final ByteBuffer newNioBuffer = buffer.getNioBuffer().duplicate().order(ByteOrder.nativeOrder());
++ final ArrayData data = factory().createArrayData(newNioBuffer, start, start + elementLength);
++
++ setArray(data);
+ }
+
+- ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
++ /**
++ * Constructor
++ *
++ * @param buffer underlying NativeArrayBuffer
++ * @param byteOffset byte offset for buffer
++ * @param elementLength element length in bytes
++ */
++ protected ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+ this(buffer, byteOffset, elementLength, Global.instance());
+ }
+
+- private void checkConstructorArgs(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
++ private static void checkConstructorArgs(final int byteLength, final int bytesPerElement, final int byteOffset, final int elementLength) {
+ if (byteOffset < 0 || elementLength < 0) {
+- throw new RuntimeException("byteOffset or length must not be negative");
+- }
+- if (byteOffset + elementLength * bytesPerElement() > buffer.getByteLength()) {
+- throw new RuntimeException("byteOffset + byteLength out of range");
+- }
+- if (byteOffset % bytesPerElement() != 0) {
+- throw new RuntimeException("byteOffset must be a multiple of the element size");
++ throw new RuntimeException("byteOffset or length must not be negative, byteOffset=" + byteOffset + ", elementLength=" + elementLength + ", bytesPerElement=" + bytesPerElement);
++ } else if (byteOffset + elementLength * bytesPerElement > byteLength) {
++ throw new RuntimeException("byteOffset + byteLength out of range, byteOffset=" + byteOffset + ", elementLength=" + elementLength + ", bytesPerElement=" + bytesPerElement);
++ } else if (byteOffset % bytesPerElement != 0) {
++ throw new RuntimeException("byteOffset must be a multiple of the element size, byteOffset=" + byteOffset + " bytesPerElement=" + bytesPerElement);
+ }
+ }
+
+@@ -69,24 +98,44 @@
+ return factory().bytesPerElement;
+ }
+
++ /**
++ * Buffer getter as per spec
++ * @param self ArrayBufferView instance
++ * @return buffer
++ */
+ @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
+ public static Object buffer(final Object self) {
+- return ((ArrayDataImpl)((ArrayBufferView)self).getArray()).buffer;
++ return ((ArrayBufferView)self).buffer;
+ }
+
++ /**
++ * Buffer offset getter as per spec
++ * @param self ArrayBufferView instance
++ * @return buffer offset
++ */
+ @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
+- public static Object byteOffset(final Object self) {
+- return ((ArrayDataImpl)((ArrayBufferView)self).getArray()).byteOffset;
++ public static int byteOffset(final Object self) {
++ return ((ArrayBufferView)self).byteOffset;
+ }
+
++ /**
++ * Byte length getter as per spec
++ * @param self ArrayBufferView instance
++ * @return array buffer view length in bytes
++ */
+ @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
+- public static Object byteLength(final Object self) {
++ public static int byteLength(final Object self) {
+ final ArrayBufferView view = (ArrayBufferView)self;
+- return ((ArrayDataImpl)view.getArray()).elementLength * view.bytesPerElement();
++ return ((TypedArrayData<?>)view.getArray()).getElementLength() * view.bytesPerElement();
+ }
+
++ /**
++ * Length getter as per spec
++ * @param self ArrayBufferView instance
++ * @return length in elements
++ */
+ @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
+- public static Object length(final Object self) {
++ public static int length(final Object self) {
+ return ((ArrayBufferView)self).elementLength();
+ }
+
+@@ -96,221 +145,119 @@
+ }
+
+ private int elementLength() {
+- return ((ArrayDataImpl)getArray()).elementLength;
++ return ((TypedArrayData<?>)getArray()).getElementLength();
+ }
+
+- protected static abstract class ArrayDataImpl extends ArrayData {
+- protected final NativeArrayBuffer buffer;
+- protected final int byteOffset;
+- private final int elementLength;
+-
+- protected ArrayDataImpl(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+- super(elementLength);
+- this.buffer = buffer;
+- this.byteOffset = byteOffset;
+- this.elementLength = elementLength;
+- }
+-
+- @Override
+- public ArrayData copy() {
+- throw new UnsupportedOperationException(); // Not used for ArrayBuffers
+- }
+-
+- @Override
+- public Object[] asObjectArray() {
+- final Object[] array = new Object[elementLength];
+- for (int i = 0; i < elementLength; i++) {
+- array[i] = getObjectImpl(i);
+- }
+- return array;
+- }
+-
+- @Override
+- public ArrayData ensure(final long safeIndex) {
+- return this;
+- }
+-
+- @Override
+- public void setLength(final long length) {
+- //empty?
+- //TODO is this right?
+- }
+-
+- @Override
+- public ArrayData shrink(final long newLength) {
+- return this;
+- }
+-
+- @Override
+- public ArrayData set(final int index, final Object value, final boolean strict) {
+- if (has(index)) {
+- setImpl(index, value);
+- }
+- return this;
+- }
+-
+- @Override
+- public ArrayData set(final int index, final int value, final boolean strict) {
+- if (has(index)) {
+- setImpl(index, value);
+- }
+- return this;
+- }
+-
+- @Override
+- public ArrayData set(final int index, final long value, final boolean strict) {
+- if (has(index)) {
+- setImpl(index, value);
+- }
+- return this;
+- }
+-
+- @Override
+- public ArrayData set(final int index, final double value, final boolean strict) {
+- if (has(index)) {
+- setImpl(index, value);
+- }
+- return this;
+- }
+-
+- @Override
+- public int getInt(final int index) {
+- return getIntImpl(index);
+- }
+-
+- @Override
+- public long getLong(final int index) {
+- return getLongImpl(index);
+- }
+-
+- @Override
+- public double getDouble(final int index) {
+- return getDoubleImpl(index);
+- }
+-
+- @Override
+- public Object getObject(final int index) {
+- return getObjectImpl(index);
+- }
+-
+- @Override
+- public boolean has(final int index) {
+- return index >= 0 && index < elementLength;
+- }
+-
+- @Override
+- public boolean canDelete(final int index, final boolean strict) {
+- return false;
+- }
+-
+- @Override
+- public boolean canDelete(final long fromIndex, final long toIndex, final boolean strict) {
+- return false;
+- }
+-
+- @Override
+- public ArrayData delete(final int index) {
+- return this;
+- }
+-
+- @Override
+- public ArrayData delete(final long fromIndex, final long toIndex) {
+- return this;
+- }
+-
+- @Override
+- protected ArrayData convert(final Class<?> type) {
+- return this;
+- }
+-
+- @Override
+- public void shiftLeft(final int by) {
+- throw new UnsupportedOperationException();
+- }
+-
+- @Override
+- public ArrayData shiftRight(final int by) {
+- throw new UnsupportedOperationException();
+- }
+-
+- @Override
+- public Object pop() {
+- throw new UnsupportedOperationException();
+- }
+-
+- @Override
+- public ArrayData slice(final long from, final long to) {
+- throw new UnsupportedOperationException();
+- }
+-
+- protected abstract int getIntImpl(int key);
+-
+- protected long getLongImpl(final int key) {
+- return getIntImpl(key);
+- }
+-
+- protected double getDoubleImpl(final int key) {
+- return getIntImpl(key);
+- }
+-
+- protected Object getObjectImpl(final int key) {
+- return getIntImpl(key);
+- }
+-
+- protected abstract void setImpl(int key, int value);
+-
+- protected void setImpl(final int key, final long value) {
+- setImpl(key, (int)value);
+- }
+-
+- protected void setImpl(final int key, final double value) {
+- setImpl(key, JSType.toInt32(value));
+- }
+-
+- protected void setImpl(final int key, final Object value) {
+- setImpl(key, JSType.toInt32(value));
+- }
+-
+- protected abstract int byteIndex(int index);
+- }
+-
++ /**
++ * Factory class for byte ArrayBufferViews
++ */
+ protected static abstract class Factory {
+ final int bytesPerElement;
+ final int maxElementLength;
+
++ /**
++ * Constructor
++ *
++ * @param bytesPerElement number of bytes per element for this buffer
++ */
+ public Factory(final int bytesPerElement) {
+- this.bytesPerElement = bytesPerElement;
++ this.bytesPerElement = bytesPerElement;
+ this.maxElementLength = Integer.MAX_VALUE / bytesPerElement;
+ }
+
++ /**
++ * Factory method
++ *
++ * @param elementLength number of elements
++ * @return new ArrayBufferView
++ */
+ public final ArrayBufferView construct(final int elementLength) {
+- if(elementLength > maxElementLength) {
++ if (elementLength > maxElementLength) {
+ throw rangeError("inappropriate.array.buffer.length", JSType.toString(elementLength));
+ }
+ return construct(new NativeArrayBuffer(elementLength * bytesPerElement), 0, elementLength);
+ }
+
+- public abstract ArrayBufferView construct(NativeArrayBuffer buffer, int byteOffset, int elementLength);
++ /**
++ * Factory method
++ *
++ * @param buffer underlying buffer
++ * @param byteOffset byte offset
++ * @param elementLength number of elements
++ *
++ * @return new ArrayBufferView
++ */
++ public abstract ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength);
+
+- public abstract ArrayData createArrayData(NativeArrayBuffer buffer, int byteOffset, int elementLength);
++ /**
++ * Factory method for array data
++ *
++ * @param nb underlying nativebuffer
++ * @param start start element
++ * @param end end element
++ *
++ * @return new array data
++ */
++ public abstract TypedArrayData<?> createArrayData(final ByteBuffer nb, final int start, final int end);
++
++ /**
++ * Get the class name for this type of buffer
++ *
++ * @return class name
++ */
++ public abstract String getClassName();
+ }
+
++ /**
++ * Get the factor for this kind of buffer
++ * @return Factory
++ */
+ protected abstract Factory factory();
+
++ /**
++ * Get the prototype for this ArrayBufferView
++ * @param global global instance
++ * @return prototype
++ */
+ protected abstract ScriptObject getPrototype(final Global global);
+
++ @Override
++ public final String getClassName() {
++ return factory().getClassName();
++ }
++
++ /**
++ * Check if this array contains floats
++ * @return true if float array (or double)
++ */
+ protected boolean isFloatArray() {
+ return false;
+ }
+
+- protected static ArrayBufferView constructorImpl(final Object[] args, final Factory factory) {
+- final Object arg0 = args.length != 0 ? args[0] : 0;
+- final ArrayBufferView dst;
+- final int length;
++ /**
++ * Inheritable constructor implementation
++ *
++ * @param newObj is this a new constructor
++ * @param args arguments
++ * @param factory factory
++ *
++ * @return new ArrayBufferView
++ */
++ protected static ArrayBufferView constructorImpl(final boolean newObj, final Object[] args, final Factory factory) {
++ final Object arg0 = args.length != 0 ? args[0] : 0;
++ final ArrayBufferView dest;
++ final int length;
++
++ if (!newObj) {
++ throw typeError("constructor.requires.new", factory.getClassName());
++ }
++
++
+ if (arg0 instanceof NativeArrayBuffer) {
+ // Constructor(ArrayBuffer buffer, optional unsigned long byteOffset, optional unsigned long length)
+- final NativeArrayBuffer buffer = (NativeArrayBuffer) arg0;
+- final int byteOffset = args.length > 1 ? JSType.toInt32(args[1]) : 0;
++ final NativeArrayBuffer buffer = (NativeArrayBuffer)arg0;
++ final int byteOffset = args.length > 1 ? JSType.toInt32(args[1]) : 0;
++
+ if (args.length > 2) {
+ length = JSType.toInt32(args[2]);
+ } else {
+@@ -319,27 +266,39 @@
+ }
+ length = (buffer.getByteLength() - byteOffset) / factory.bytesPerElement;
+ }
++
+ return factory.construct(buffer, byteOffset, length);
+ } else if (arg0 instanceof ArrayBufferView) {
+ // Constructor(TypedArray array)
+ length = ((ArrayBufferView)arg0).elementLength();
+- dst = factory.construct(length);
++ dest = factory.construct(length);
+ } else if (arg0 instanceof NativeArray) {
+ // Constructor(type[] array)
+ length = lengthToInt(((NativeArray) arg0).getArray().length());
+- dst = factory.construct(length);
++ dest = factory.construct(length);
+ } else {
+- // Constructor(unsigned long length)
+- length = lengthToInt(JSType.toInt64(arg0));
++ // Constructor(unsigned long length). Treating infinity as 0 is a special case for ArrayBufferView.
++ final double dlen = JSType.toNumber(arg0);
++ length = lengthToInt(Double.isInfinite(dlen) ? 0L : JSType.toLong(dlen));
+ return factory.construct(length);
+ }
+
+- copyElements(dst, length, (ScriptObject)arg0, 0);
+- return dst;
++ copyElements(dest, length, (ScriptObject)arg0, 0);
++
++ return dest;
+ }
+
++ /**
++ * Inheritable implementation of set, if no efficient implementation is available
++ *
++ * @param self ArrayBufferView instance
++ * @param array array
++ * @param offset0 array offset
++ *
++ * @return result of setter
++ */
+ protected static Object setImpl(final Object self, final Object array, final Object offset0) {
+- final ArrayBufferView dest = ((ArrayBufferView)self);
++ final ArrayBufferView dest = (ArrayBufferView)self;
+ final int length;
+ if (array instanceof ArrayBufferView) {
+ // void set(TypedArray array, optional unsigned long offset)
+@@ -351,7 +310,7 @@
+ throw new RuntimeException("argument is not of array type");
+ }
+
+- final ScriptObject source = (ScriptObject) array;
++ final ScriptObject source = (ScriptObject)array;
+ final int offset = JSType.toInt32(offset0); // default=0
+
+ if (dest.elementLength() < length + offset || offset < 0) {
+@@ -366,11 +325,11 @@
+ private static void copyElements(final ArrayBufferView dest, final int length, final ScriptObject source, final int offset) {
+ if (!dest.isFloatArray()) {
+ for (int i = 0, j = offset; i < length; i++, j++) {
+- dest.set(j, source.getInt(i), false);
++ dest.set(j, source.getInt(i, INVALID_PROGRAM_POINT), 0);
+ }
+ } else {
+ for (int i = 0, j = offset; i < length; i++, j++) {
+- dest.set(j, source.getDouble(i), false);
++ dest.set(j, source.getDouble(i, INVALID_PROGRAM_POINT), 0);
+ }
+ }
+ }
+@@ -379,15 +338,48 @@
+ if (length > Integer.MAX_VALUE || length < 0) {
+ throw rangeError("inappropriate.array.buffer.length", JSType.toString(length));
+ }
+- return (int) (length & Integer.MAX_VALUE);
++ return (int)(length & Integer.MAX_VALUE);
+ }
+
++ /**
++ * Implementation of subarray if no efficient override exists
++ *
++ * @param self ArrayBufferView instance
++ * @param begin0 begin index
++ * @param end0 end index
++ *
++ * @return sub array
++ */
+ protected static ScriptObject subarrayImpl(final Object self, final Object begin0, final Object end0) {
+- final ArrayBufferView arrayView = ((ArrayBufferView)self);
+- final int elementLength = arrayView.elementLength();
+- final int begin = NativeArrayBuffer.adjustIndex(JSType.toInt32(begin0), elementLength);
+- final int end = NativeArrayBuffer.adjustIndex(end0 != ScriptRuntime.UNDEFINED ? JSType.toInt32(end0) : elementLength, elementLength);
+- final ArrayDataImpl arrayData = (ArrayDataImpl)arrayView.getArray();
+- return arrayView.factory().construct(arrayData.buffer, arrayData.byteIndex(begin), Math.max(end - begin, 0));
++ final ArrayBufferView arrayView = (ArrayBufferView)self;
++ final int byteOffset = arrayView.byteOffset;
++ final int bytesPerElement = arrayView.bytesPerElement();
++ final int elementLength = arrayView.elementLength();
++ final int begin = NativeArrayBuffer.adjustIndex(JSType.toInt32(begin0), elementLength);
++ final int end = NativeArrayBuffer.adjustIndex(end0 != ScriptRuntime.UNDEFINED ? JSType.toInt32(end0) : elementLength, elementLength);
++ final int length = Math.max(end - begin, 0);
++
++ assert byteOffset % bytesPerElement == 0;
++
++ //second is byteoffset
++ return arrayView.factory().construct(arrayView.buffer, begin * bytesPerElement + byteOffset, length);
++ }
++
++ @Override
++ protected GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) {
++ final GuardedInvocation inv = getArray().findFastGetIndexMethod(getArray().getClass(), desc, request);
++ if (inv != null) {
++ return inv;
++ }
++ return super.findGetIndexMethod(desc, request);
++ }
++
++ @Override
++ protected GuardedInvocation findSetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) {
++ final GuardedInvocation inv = getArray().findFastSetIndexMethod(getArray().getClass(), desc, request);
++ if (inv != null) {
++ return inv;
++ }
++ return super.findSetIndexMethod(desc, request);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/BoundScriptFunctionImpl.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/BoundScriptFunctionImpl.java Wed Feb 04 12:14:47 2015 -0800
+@@ -38,7 +38,7 @@
+ final class BoundScriptFunctionImpl extends ScriptFunctionImpl {
+ private final ScriptFunction targetFunction;
+
+- BoundScriptFunctionImpl(ScriptFunctionData data, ScriptFunction targetFunction) {
++ BoundScriptFunctionImpl(final ScriptFunctionData data, final ScriptFunction targetFunction) {
+ super(data, Global.instance());
+ setPrototype(ScriptRuntime.UNDEFINED);
+ this.targetFunction = targetFunction;
+--- ./nashorn/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -197,6 +197,11 @@
+ }
+
+ @Override
++ public String toString() {
++ return '[' + getClass().getSimpleName() + " {configurable=" + configurable + " enumerable=" + enumerable + " writable=" + writable + " value=" + value + "}]";
++ }
++
++ @Override
+ public int hashCode() {
+ int hash = 5;
+ hash = 43 * hash + Objects.hashCode(this.configurable);
+--- ./nashorn/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -176,6 +176,11 @@
+ }
+
+ @Override
++ public String toString() {
++ return '[' + getClass().getSimpleName() + " {configurable=" + configurable + " enumerable=" + enumerable + "}]";
++ }
++
++ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 97 * hash + Objects.hashCode(this.configurable);
+--- ./nashorn/src/jdk/nashorn/internal/objects/Global.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/Global.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,6 +26,7 @@
+ package jdk.nashorn.internal.objects;
+
+ import static jdk.nashorn.internal.lookup.Lookup.MH;
++import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+@@ -33,20 +34,30 @@
+ import java.io.PrintWriter;
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
++import java.lang.invoke.MethodType;
++import java.lang.invoke.SwitchPoint;
+ import java.lang.reflect.Field;
++import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.concurrent.Callable;
+ import java.util.concurrent.ConcurrentHashMap;
++import javax.script.ScriptContext;
++import javax.script.ScriptEngine;
++import jdk.internal.dynalink.CallSiteDescriptor;
+ import jdk.internal.dynalink.linker.GuardedInvocation;
+ import jdk.internal.dynalink.linker.LinkRequest;
++import jdk.nashorn.api.scripting.ClassFilter;
++import jdk.nashorn.api.scripting.ScriptObjectMirror;
+ import jdk.nashorn.internal.lookup.Lookup;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Property;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+ import jdk.nashorn.internal.runtime.ConsString;
+ import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.ECMAErrors;
++import jdk.nashorn.internal.runtime.GlobalConstants;
+ import jdk.nashorn.internal.runtime.GlobalFunctions;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.NativeJavaPackage;
+@@ -55,13 +66,14 @@
+ import jdk.nashorn.internal.runtime.Scope;
+ import jdk.nashorn.internal.runtime.ScriptEnvironment;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+-import jdk.nashorn.internal.runtime.ScriptFunctionData;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+ import jdk.nashorn.internal.runtime.ScriptingFunctions;
++import jdk.nashorn.internal.runtime.Specialization;
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
+ import jdk.nashorn.internal.runtime.linker.Bootstrap;
+ import jdk.nashorn.internal.runtime.linker.InvokeByName;
++import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+ import jdk.nashorn.internal.runtime.regexp.RegExpResult;
+ import jdk.nashorn.internal.scripts.JO;
+
+@@ -70,9 +82,35 @@
+ */
+ @ScriptClass("Global")
+ public final class Global extends ScriptObject implements Scope {
++ // Placeholder value used in place of a location property (__FILE__, __DIR__, __LINE__)
++ private static final Object LOCATION_PROPERTY_PLACEHOLDER = new Object();
+ private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
+ private final InvokeByName VALUE_OF = new InvokeByName("valueOf", ScriptObject.class);
+
++ /**
++ * Optimistic builtin names that require switchpoint invalidation
++ * upon assignment. Overly conservative, but works for now, to avoid
++ * any complicated scope checks and especially heavy weight guards
++ * like
++ *
++ * <pre>
++ * public boolean setterGuard(final Object receiver) {
++ * final Global global = Global.instance();
++ * final ScriptObject sobj = global.getFunctionPrototype();
++ * final Object apply = sobj.get("apply");
++ * return apply == receiver;
++ * }
++ * </pre>
++ *
++ * Naturally, checking for builtin classes like NativeFunction is cheaper,
++ * it's when you start adding property checks for said builtins you have
++ * problems with guard speed.
++ */
++
++ /** Nashorn extension: arguments array */
++ @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
++ public Object arguments;
++
+ /** ECMA 15.1.2.2 parseInt (string , radix) */
+ @Property(attributes = Attribute.NOT_ENUMERABLE)
+ public Object parseInt;
+@@ -135,11 +173,11 @@
+
+ /** Value property NaN of the Global Object - ECMA 15.1.1.1 NaN */
+ @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+- public final Object NaN = Double.NaN;
++ public final double NaN = Double.NaN;
+
+ /** Value property Infinity of the Global Object - ECMA 15.1.1.2 Infinity */
+ @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+- public final Object Infinity = Double.POSITIVE_INFINITY;
++ public final double Infinity = Double.POSITIVE_INFINITY;
+
+ /** Value property Undefined of the Global Object - ECMA 15.1.1.3 Undefined */
+ @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+@@ -303,15 +341,15 @@
+
+ /** Nashorn extension: current script's file name */
+ @Property(name = "__FILE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+- public Object __FILE__;
++ public final Object __FILE__ = LOCATION_PROPERTY_PLACEHOLDER;
+
+ /** Nashorn extension: current script's directory */
+ @Property(name = "__DIR__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+- public Object __DIR__;
++ public final Object __DIR__ = LOCATION_PROPERTY_PLACEHOLDER;
+
+ /** Nashorn extension: current source line number being executed */
+ @Property(name = "__LINE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+- public Object __LINE__;
++ public final Object __LINE__ = LOCATION_PROPERTY_PLACEHOLDER;
+
+ /** Used as Date.prototype's default value */
+ public NativeDate DEFAULT_DATE;
+@@ -352,19 +390,19 @@
+ private ScriptObject builtinJavafx;
+ private ScriptObject builtinJavax;
+ private ScriptObject builtinOrg;
+- private ScriptObject builtinJavaImporter;
++ private ScriptFunction builtinJavaImporter;
+ private ScriptObject builtinJavaApi;
+- private ScriptObject builtinArrayBuffer;
+- private ScriptObject builtinDataView;
+- private ScriptObject builtinInt8Array;
+- private ScriptObject builtinUint8Array;
+- private ScriptObject builtinUint8ClampedArray;
+- private ScriptObject builtinInt16Array;
+- private ScriptObject builtinUint16Array;
+- private ScriptObject builtinInt32Array;
+- private ScriptObject builtinUint32Array;
+- private ScriptObject builtinFloat32Array;
+- private ScriptObject builtinFloat64Array;
++ private ScriptFunction builtinArrayBuffer;
++ private ScriptFunction builtinDataView;
++ private ScriptFunction builtinInt8Array;
++ private ScriptFunction builtinUint8Array;
++ private ScriptFunction builtinUint8ClampedArray;
++ private ScriptFunction builtinInt16Array;
++ private ScriptFunction builtinUint16Array;
++ private ScriptFunction builtinInt32Array;
++ private ScriptFunction builtinUint32Array;
++ private ScriptFunction builtinFloat32Array;
++ private ScriptFunction builtinFloat64Array;
+
+ /*
+ * ECMA section 13.2.3 The [[ThrowTypeError]] Function Object
+@@ -377,12 +415,14 @@
+ // Used to store the last RegExp result to support deprecated RegExp constructor properties
+ private RegExpResult lastRegExpResult;
+
+- private static final MethodHandle EVAL = findOwnMH("eval", Object.class, Object.class, Object.class);
+- private static final MethodHandle PRINT = findOwnMH("print", Object.class, Object.class, Object[].class);
+- private static final MethodHandle PRINTLN = findOwnMH("println", Object.class, Object.class, Object[].class);
+- private static final MethodHandle LOAD = findOwnMH("load", Object.class, Object.class, Object.class);
+- private static final MethodHandle LOADWITHNEWGLOBAL = findOwnMH("loadWithNewGlobal", Object.class, Object.class, Object[].class);
+- private static final MethodHandle EXIT = findOwnMH("exit", Object.class, Object.class, Object.class);
++ private static final MethodHandle EVAL = findOwnMH_S("eval", Object.class, Object.class, Object.class);
++ private static final MethodHandle NO_SUCH_PROPERTY = findOwnMH_S(NO_SUCH_PROPERTY_NAME, Object.class, Object.class, Object.class);
++ private static final MethodHandle PRINT = findOwnMH_S("print", Object.class, Object.class, Object[].class);
++ private static final MethodHandle PRINTLN = findOwnMH_S("println", Object.class, Object.class, Object[].class);
++ private static final MethodHandle LOAD = findOwnMH_S("load", Object.class, Object.class, Object.class);
++ private static final MethodHandle LOAD_WITH_NEW_GLOBAL = findOwnMH_S("loadWithNewGlobal", Object.class, Object.class, Object[].class);
++ private static final MethodHandle EXIT = findOwnMH_S("exit", Object.class, Object.class, Object.class);
++ private static final MethodHandle LEXICAL_SCOPE_FILTER = findOwnMH_S("lexicalScopeFilter", Object.class, Object.class);
+
+ // initialized by nasgen
+ private static PropertyMap $nasgenmap$;
+@@ -390,6 +430,25 @@
+ // context to which this global belongs to
+ private final Context context;
+
++ // current ScriptContext to use - can be null.
++ private ScriptContext scontext;
++ // current ScriptEngine associated - can be null.
++ private ScriptEngine engine;
++
++ // ES6 global lexical scope.
++ private final LexicalScope lexicalScope;
++
++ // Switchpoint for non-constant global callsites in the presence of ES6 lexical scope.
++ private SwitchPoint lexicalScopeSwitchPoint;
++
++ /**
++ * Set the current script context
++ * @param scontext script context
++ */
++ public void setScriptContext(final ScriptContext scontext) {
++ this.scontext = scontext;
++ }
++
+ @Override
+ protected Context getContext() {
+ return context;
+@@ -407,12 +466,7 @@
+ // null check on context
+ context.getClass();
+
+- /*
+- * Duplicate global's map and use it. This way the initial Map filled
+- * by nasgen (referenced from static field in this class) is retained
+- * 'as is' (as that one is process wide singleton.
+- */
+- return $nasgenmap$.duplicate();
++ return $nasgenmap$;
+ }
+
+ /**
+@@ -424,6 +478,7 @@
+ super(checkAndGetMap(context));
+ this.context = context;
+ this.setIsScope();
++ this.lexicalScope = context.getEnv()._es6 ? new LexicalScope(this) : null;
+ }
+
+ /**
+@@ -432,11 +487,23 @@
+ * @return the global singleton
+ */
+ public static Global instance() {
+- Global global = Context.getGlobal();
++ final Global global = Context.getGlobal();
+ global.getClass(); // null check
+ return global;
+ }
+
++ private static Global instanceFrom(final Object self) {
++ return self instanceof Global? (Global)self : instance();
++ }
++
++ /**
++ * Check if we have a Global instance
++ * @return true if one exists
++ */
++ public static boolean hasInstance() {
++ return Context.getGlobal() != null;
++ }
++
+ /**
+ * Script access to {@link ScriptEnvironment}
+ *
+@@ -458,6 +525,14 @@
+ // Runtime interface to Global
+
+ /**
++ * Is there a class filter in the current Context?
++ * @return class filter
++ */
++ public ClassFilter getClassFilter() {
++ return context.getClassFilter();
++ }
++
++ /**
+ * Is this global of the given Context?
+ * @param ctxt the context
+ * @return true if this global belongs to the given Context
+@@ -478,28 +553,18 @@
+ * Initialize standard builtin objects like "Object", "Array", "Function" etc.
+ * as well as our extension builtin objects like "Java", "JSAdapter" as properties
+ * of the global scope object.
++ *
++ * @param engine ScriptEngine to initialize
+ */
+- public void initBuiltinObjects() {
++ @SuppressWarnings("hiding")
++ public void initBuiltinObjects(final ScriptEngine engine) {
+ if (this.builtinObject != null) {
+ // already initialized, just return
+ return;
+ }
+
+- init();
+- }
+-
+- /**
+- * Create a new ScriptFunction object
+- *
+- * @param name function name
+- * @param handle invocation handle for function
+- * @param scope the scope
+- * @param strict are we in strict mode
+- *
+- * @return new script function
+- */
+- public ScriptFunction newScriptFunction(final String name, final MethodHandle handle, final ScriptObject scope, final boolean strict) {
+- return new ScriptFunctionImpl(name, handle, scope, null, strict ? ScriptFunctionData.IS_STRICT_CONSTRUCTOR : ScriptFunctionData.IS_CONSTRUCTOR);
++ this.engine = engine;
++ init(engine);
+ }
+
+ /**
+@@ -537,7 +602,7 @@
+ *
+ * @return guarded invocation
+ */
+- public GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) {
++ public static GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) {
+ if (self instanceof String || self instanceof ConsString) {
+ return NativeString.lookupPrimitive(request, self);
+ } else if (self instanceof Number) {
+@@ -549,6 +614,24 @@
+ }
+
+ /**
++ * Returns a method handle that creates a wrapper object for a JS primitive value.
++ *
++ * @param self receiver object
++ * @return method handle to create wrapper objects for primitive receiver
++ */
++ public static MethodHandle getPrimitiveWrapFilter(final Object self) {
++ if (self instanceof String || self instanceof ConsString) {
++ return NativeString.WRAPFILTER;
++ } else if (self instanceof Number) {
++ return NativeNumber.WRAPFILTER;
++ } else if (self instanceof Boolean) {
++ return NativeBoolean.WRAPFILTER;
++ }
++ throw new IllegalArgumentException("Unsupported primitive: " + self);
++ }
++
++
++ /**
+ * Create a new empty script object
+ *
+ * @return the new ScriptObject
+@@ -729,6 +812,7 @@
+ * @param value of the data property
+ * @param configurable is the property configurable?
+ * @param enumerable is the property enumerable?
++ * @param writable is the property writable?
+ * @return newly created DataPropertyDescriptor object
+ */
+ public PropertyDescriptor newDataDescriptor(final Object value, final boolean configurable, final boolean enumerable, final boolean writable) {
+@@ -758,7 +842,6 @@
+ return desc;
+ }
+
+-
+ private static <T> T getLazilyCreatedValue(final Object key, final Callable<T> creator, final Map<Object, T> map) {
+ final T obj = map.get(key);
+ if (obj != null) {
+@@ -800,6 +883,41 @@
+ }
+
+ /**
++ * Hook to search missing variables in ScriptContext if available
++ * @param self used to detect if scope call or not (this function is 'strict')
++ * @param name name of the variable missing
++ * @return value of the missing variable or undefined (or TypeError for scope search)
++ */
++ public static Object __noSuchProperty__(final Object self, final Object name) {
++ final Global global = Global.instance();
++ final ScriptContext sctxt = global.scontext;
++ final String nameStr = name.toString();
++
++ if (sctxt != null) {
++ final int scope = sctxt.getAttributesScope(nameStr);
++ if (scope != -1) {
++ return ScriptObjectMirror.unwrap(sctxt.getAttribute(nameStr, scope), global);
++ }
++ }
++
++ switch (nameStr) {
++ case "context":
++ return sctxt;
++ case "engine":
++ return global.engine;
++ default:
++ break;
++ }
++
++ if (self == UNDEFINED) {
++ // scope access and so throw ReferenceError
++ throw referenceError(global, "not.defined", nameStr);
++ }
++
++ return UNDEFINED;
++ }
++
++ /**
+ * This is the eval used when 'indirect' eval call is made.
+ *
+ * var global = this;
+@@ -811,7 +929,7 @@
+ * @return the result of eval
+ */
+ public static Object eval(final Object self, final Object str) {
+- return directEval(self, str, UNDEFINED, UNDEFINED, UNDEFINED);
++ return directEval(self, str, UNDEFINED, UNDEFINED, false);
+ }
+
+ /**
+@@ -827,14 +945,14 @@
+ *
+ * This is directly invoked from generated when eval(code) is called in user code
+ */
+- public static Object directEval(final Object self, final Object str, final Object callThis, final Object location, final Object strict) {
++ public static Object directEval(final Object self, final Object str, final Object callThis, final Object location, final boolean strict) {
+ if (!(str instanceof String || str instanceof ConsString)) {
+ return str;
+ }
+- final Global global = Global.instance();
+- final ScriptObject scope = (self instanceof ScriptObject) ? (ScriptObject)self : global;
++ final Global global = Global.instanceFrom(self);
++ final ScriptObject scope = self instanceof ScriptObject ? (ScriptObject)self : global;
+
+- return global.getContext().eval(scope, str.toString(), callThis, location, Boolean.TRUE.equals(strict));
++ return global.getContext().eval(scope, str.toString(), callThis, location, strict, true);
+ }
+
+ /**
+@@ -846,7 +964,7 @@
+ * @return result of print (undefined)
+ */
+ public static Object print(final Object self, final Object... objects) {
+- return printImpl(false, objects);
++ return Global.instanceFrom(self).printImpl(false, objects);
+ }
+
+ /**
+@@ -858,7 +976,7 @@
+ * @return result of println (undefined)
+ */
+ public static Object println(final Object self, final Object... objects) {
+- return printImpl(true, objects);
++ return Global.instanceFrom(self).printImpl(true, objects);
+ }
+
+ /**
+@@ -872,8 +990,8 @@
+ * @throws IOException if source could not be read
+ */
+ public static Object load(final Object self, final Object source) throws IOException {
+- final Global global = Global.instance();
+- final ScriptObject scope = (self instanceof ScriptObject) ? (ScriptObject)self : global;
++ final Global global = Global.instanceFrom(self);
++ final ScriptObject scope = self instanceof ScriptObject ? (ScriptObject)self : global;
+ return global.getContext().load(scope, source);
+ }
+
+@@ -888,7 +1006,7 @@
+ * @throws IOException if source could not be read
+ */
+ public static Object loadWithNewGlobal(final Object self, final Object...args) throws IOException {
+- final Global global = Global.instance();
++ final Global global = Global.instanceFrom(self);
+ final int length = args.length;
+ final boolean hasArgs = 0 < length;
+ final Object from = hasArgs ? args[0] : UNDEFINED;
+@@ -903,7 +1021,7 @@
+ * @param self self reference
+ * @param code exit code
+ *
+- * @return undefined (will never be reacheD)
++ * @return undefined (will never be reached)
+ */
+ public static Object exit(final Object self, final Object code) {
+ System.exit(JSType.toInt32(code));
+@@ -1111,6 +1229,40 @@
+ return instance.function == instance.getBuiltinFunction();
+ }
+
++ /**
++ * Get the switchpoint used to check property changes for Function.prototype.apply
++ * @return the switchpoint guarding apply (same as guarding call, and everything else in function)
++ */
++ public static SwitchPoint getBuiltinFunctionApplySwitchPoint() {
++ return ScriptFunction.getPrototype(Global.instance().getBuiltinFunction()).getProperty("apply").getBuiltinSwitchPoint();
++ }
++
++ private static boolean isBuiltinFunctionProperty(final String name) {
++ final Global instance = Global.instance();
++ final ScriptFunction builtinFunction = instance.getBuiltinFunction();
++ if (builtinFunction == null) {
++ return false; //conservative for compile-only mode
++ }
++ final boolean isBuiltinFunction = instance.function == builtinFunction;
++ return isBuiltinFunction && ScriptFunction.getPrototype(builtinFunction).getProperty(name).isBuiltin();
++ }
++
++ /**
++ * Check if the Function.prototype.apply has not been replaced
++ * @return true if Function.prototype.apply has been replaced
++ */
++ public static boolean isBuiltinFunctionPrototypeApply() {
++ return isBuiltinFunctionProperty("apply");
++ }
++
++ /**
++ * Check if the Function.prototype.apply has not been replaced
++ * @return true if Function.prototype.call has been replaced
++ */
++ public static boolean isBuiltinFunctionPrototypeCall() {
++ return isBuiltinFunctionProperty("call");
++ }
++
+ private ScriptFunction getBuiltinJSAdapter() {
+ return builtinJSAdapter;
+ }
+@@ -1457,6 +1609,26 @@
+ }
+
+ /**
++ * Called from generated to replace a location property placeholder with the actual location property value.
++ *
++ * @param placeholder the value tested for being a placeholder for a location property
++ * @param locationProperty the actual value for the location property
++ * @return locationProperty if placeholder is indeed a placeholder for a location property, the placeholder otherwise
++ */
++ public static Object replaceLocationPropertyPlaceholder(final Object placeholder, final Object locationProperty) {
++ return isLocationPropertyPlaceholder(placeholder) ? locationProperty : placeholder;
++ }
++
++ /**
++ * Called from runtime internals to check if the passed value is a location property placeholder.
++ * @param placeholder the value tested for being a placeholder for a location property
++ * @return true if the value is a placeholder, false otherwise.
++ */
++ public static boolean isLocationPropertyPlaceholder(final Object placeholder) {
++ return placeholder == LOCATION_PROPERTY_PLACEHOLDER;
++ }
++
++ /**
+ * Create a new RegExp object.
+ *
+ * @param expression Regular expression.
+@@ -1494,11 +1666,13 @@
+ * not the case
+ *
+ * @param obj and object to check
++ * @return the script object
+ */
+- public static void checkObject(final Object obj) {
++ public static ScriptObject checkObject(final Object obj) {
+ if (!(obj instanceof ScriptObject)) {
+ throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
+ }
++ return (ScriptObject)obj;
+ }
+
+ /**
+@@ -1533,7 +1707,141 @@
+ splitState = state;
+ }
+
+- private void init() {
++ /**
++ * Return the ES6 global scope for lexically declared bindings.
++ * @return the ES6 lexical global scope.
++ */
++ public final ScriptObject getLexicalScope() {
++ assert context.getEnv()._es6;
++ return lexicalScope;
++ }
++
++ @Override
++ public void addBoundProperties(final ScriptObject source, final jdk.nashorn.internal.runtime.Property[] properties) {
++ PropertyMap ownMap = getMap();
++ LexicalScope lexicalScope = null;
++ PropertyMap lexicalMap = null;
++ boolean hasLexicalDefinitions = false;
++
++ if (context.getEnv()._es6) {
++ lexicalScope = (LexicalScope) getLexicalScope();
++ lexicalMap = lexicalScope.getMap();
++
++ for (final jdk.nashorn.internal.runtime.Property property : properties) {
++ if (property.isLexicalBinding()) {
++ hasLexicalDefinitions = true;
++ }
++ // ES6 15.1.8 steps 6. and 7.
++ final jdk.nashorn.internal.runtime.Property globalProperty = ownMap.findProperty(property.getKey());
++ if (globalProperty != null && !globalProperty.isConfigurable() && property.isLexicalBinding()) {
++ throw ECMAErrors.syntaxError("redeclare.variable", property.getKey());
++ }
++ final jdk.nashorn.internal.runtime.Property lexicalProperty = lexicalMap.findProperty(property.getKey());
++ if (lexicalProperty != null && !property.isConfigurable()) {
++ throw ECMAErrors.syntaxError("redeclare.variable", property.getKey());
++ }
++ }
++ }
++
++ for (final jdk.nashorn.internal.runtime.Property property : properties) {
++ if (property.isLexicalBinding()) {
++ assert lexicalScope != null;
++ lexicalMap = lexicalScope.addBoundProperty(lexicalMap, source, property);
++
++ if (ownMap.findProperty(property.getKey()) != null) {
++ // If property exists in the global object invalidate any global constant call sites.
++ invalidateGlobalConstant(property.getKey());
++ }
++ } else {
++ ownMap = addBoundProperty(ownMap, source, property);
++ }
++ }
++
++ setMap(ownMap);
++
++ if (hasLexicalDefinitions) {
++ lexicalScope.setMap(lexicalMap);
++ invalidateLexicalSwitchPoint();
++ }
++ }
++
++ @Override
++ public GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
++ final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
++ final boolean isScope = NashornCallSiteDescriptor.isScope(desc);
++
++ if (lexicalScope != null && isScope && !NashornCallSiteDescriptor.isApplyToCall(desc)) {
++ if (lexicalScope.hasOwnProperty(name)) {
++ return lexicalScope.findGetMethod(desc, request, operator);
++ }
++ }
++
++ final GuardedInvocation invocation = super.findGetMethod(desc, request, operator);
++
++ // We want to avoid adding our generic lexical scope switchpoint to global constant invocations,
++ // because those are invalidated per-key in the addBoundProperties method above.
++ // We therefor check if the invocation does already have a switchpoint and the property is non-inherited,
++ // assuming this only applies to global constants. If other non-inherited properties will
++ // start using switchpoints some time in the future we'll have to revisit this.
++ if (isScope && context.getEnv()._es6 && (invocation.getSwitchPoints() == null || !hasOwnProperty(name))) {
++ return invocation.addSwitchPoint(getLexicalScopeSwitchPoint());
++ }
++
++ return invocation;
++ }
++
++ @Override
++ public GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) {
++ final boolean isScope = NashornCallSiteDescriptor.isScope(desc);
++
++ if (lexicalScope != null && isScope) {
++ final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
++ if (lexicalScope.hasOwnProperty(name)) {
++ return lexicalScope.findSetMethod(desc, request);
++ }
++ }
++
++ final GuardedInvocation invocation = super.findSetMethod(desc, request);
++
++ if (isScope && context.getEnv()._es6) {
++ return invocation.addSwitchPoint(getLexicalScopeSwitchPoint());
++ }
++
++ return invocation;
++ }
++
++ private synchronized SwitchPoint getLexicalScopeSwitchPoint() {
++ SwitchPoint switchPoint = lexicalScopeSwitchPoint;
++ if (switchPoint == null || switchPoint.hasBeenInvalidated()) {
++ switchPoint = lexicalScopeSwitchPoint = new SwitchPoint();
++ }
++ return switchPoint;
++ }
++
++ private synchronized void invalidateLexicalSwitchPoint() {
++ if (lexicalScopeSwitchPoint != null) {
++ context.getLogger(GlobalConstants.class).info("Invalidating non-constant globals on lexical scope update");
++ SwitchPoint.invalidateAll(new SwitchPoint[]{ lexicalScopeSwitchPoint });
++ }
++ }
++
++
++ @SuppressWarnings("unused")
++ private static Object lexicalScopeFilter(final Object self) {
++ if (self instanceof Global) {
++ return ((Global) self).getLexicalScope();
++ }
++ return self;
++ }
++
++ private <T extends ScriptObject> T initConstructorAndSwitchPoint(final String name, final Class<T> clazz) {
++ final T func = initConstructor(name, clazz);
++ tagBuiltinProperties(name, func);
++ return func;
++ }
++
++ @SuppressWarnings("hiding")
++ private void init(final ScriptEngine engine) {
+ assert Context.getGlobal() == this : "this global is not set as current";
+
+ final ScriptEnvironment env = getContext().getEnv();
+@@ -1547,7 +1855,19 @@
+ // initialize global function properties
+ this.eval = this.builtinEval = ScriptFunctionImpl.makeFunction("eval", EVAL);
+
+- this.parseInt = ScriptFunctionImpl.makeFunction("parseInt", GlobalFunctions.PARSEINT);
++ this.parseInt = ScriptFunctionImpl.makeFunction("parseInt", GlobalFunctions.PARSEINT,
++ new Specialization[] {
++ new Specialization(GlobalFunctions.PARSEINT_Z),
++ new Specialization(GlobalFunctions.PARSEINT_I),
++ new Specialization(GlobalFunctions.PARSEINT_J),
++ new Specialization(GlobalFunctions.PARSEINT_OI),
++ new Specialization(GlobalFunctions.PARSEINT_O) });
++ this.parseFloat = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
++ this.isNaN = ScriptFunctionImpl.makeFunction("isNaN", GlobalFunctions.IS_NAN,
++ new Specialization[] {
++ new Specialization(GlobalFunctions.IS_NAN_I),
++ new Specialization(GlobalFunctions.IS_NAN_J),
++ new Specialization(GlobalFunctions.IS_NAN_D) });
+ this.parseFloat = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
+ this.isNaN = ScriptFunctionImpl.makeFunction("isNaN", GlobalFunctions.IS_NAN);
+ this.isFinite = ScriptFunctionImpl.makeFunction("isFinite", GlobalFunctions.IS_FINITE);
+@@ -1559,20 +1879,20 @@
+ this.unescape = ScriptFunctionImpl.makeFunction("unescape", GlobalFunctions.UNESCAPE);
+ this.print = ScriptFunctionImpl.makeFunction("print", env._print_no_newline ? PRINT : PRINTLN);
+ this.load = ScriptFunctionImpl.makeFunction("load", LOAD);
+- this.loadWithNewGlobal = ScriptFunctionImpl.makeFunction("loadWithNewGlobal", LOADWITHNEWGLOBAL);
++ this.loadWithNewGlobal = ScriptFunctionImpl.makeFunction("loadWithNewGlobal", LOAD_WITH_NEW_GLOBAL);
+ this.exit = ScriptFunctionImpl.makeFunction("exit", EXIT);
+ this.quit = ScriptFunctionImpl.makeFunction("quit", EXIT);
+
+ // built-in constructors
+- this.builtinArray = (ScriptFunction)initConstructor("Array");
+- this.builtinBoolean = (ScriptFunction)initConstructor("Boolean");
+- this.builtinDate = (ScriptFunction)initConstructor("Date");
+- this.builtinJSON = initConstructor("JSON");
+- this.builtinJSAdapter = (ScriptFunction)initConstructor("JSAdapter");
+- this.builtinMath = initConstructor("Math");
+- this.builtinNumber = (ScriptFunction)initConstructor("Number");
+- this.builtinRegExp = (ScriptFunction)initConstructor("RegExp");
+- this.builtinString = (ScriptFunction)initConstructor("String");
++ this.builtinArray = initConstructorAndSwitchPoint("Array", ScriptFunction.class);
++ this.builtinBoolean = initConstructorAndSwitchPoint("Boolean", ScriptFunction.class);
++ this.builtinDate = initConstructorAndSwitchPoint("Date", ScriptFunction.class);
++ this.builtinJSON = initConstructorAndSwitchPoint("JSON", ScriptObject.class);
++ this.builtinJSAdapter = initConstructorAndSwitchPoint("JSAdapter", ScriptFunction.class);
++ this.builtinMath = initConstructorAndSwitchPoint("Math", ScriptObject.class);
++ this.builtinNumber = initConstructorAndSwitchPoint("Number", ScriptFunction.class);
++ this.builtinRegExp = initConstructorAndSwitchPoint("RegExp", ScriptFunction.class);
++ this.builtinString = initConstructorAndSwitchPoint("String", ScriptFunction.class);
+
+ // initialize String.prototype.length to 0
+ // add String.prototype.length
+@@ -1632,25 +1952,25 @@
+
+ copyBuiltins();
+
+- // initialized with strings so that typeof will work as expected.
+- this.__FILE__ = "";
+- this.__DIR__ = "";
+- this.__LINE__ = 0.0;
+-
+ // expose script (command line) arguments as "arguments" property of global
+- final List<String> arguments = env.getArguments();
+- final Object argsObj = wrapAsObject(arguments.toArray());
+-
+- addOwnProperty("arguments", Attribute.NOT_ENUMERABLE, argsObj);
++ arguments = wrapAsObject(env.getArguments().toArray());
+ if (env._scripting) {
+ // synonym for "arguments" in scripting mode
+- addOwnProperty("$ARG", Attribute.NOT_ENUMERABLE, argsObj);
++ addOwnProperty("$ARG", Attribute.NOT_ENUMERABLE, arguments);
++ }
++
++ if (engine != null) {
++ // default file name
++ addOwnProperty(ScriptEngine.FILENAME, Attribute.NOT_ENUMERABLE, null);
++ // __noSuchProperty__ hook for ScriptContext search of missing variables
++ final ScriptFunction noSuchProp = ScriptFunctionImpl.makeStrictFunction(NO_SUCH_PROPERTY_NAME, NO_SUCH_PROPERTY);
++ addOwnProperty(NO_SUCH_PROPERTY_NAME, Attribute.NOT_ENUMERABLE, noSuchProp);
+ }
+ }
+
+ private void initErrorObjects() {
+ // Error objects
+- this.builtinError = (ScriptFunction)initConstructor("Error");
++ this.builtinError = initConstructor("Error", ScriptFunction.class);
+ final ScriptObject errorProto = getErrorPrototype();
+
+ // Nashorn specific accessors on Error.prototype - stack, lineNumber, columnNumber and fileName
+@@ -1669,10 +1989,12 @@
+
+ // ECMA 15.11.4.2 Error.prototype.name
+ // Error.prototype.name = "Error";
+- errorProto.set(NativeError.NAME, "Error", false);
++ errorProto.set(NativeError.NAME, "Error", 0);
+ // ECMA 15.11.4.3 Error.prototype.message
+ // Error.prototype.message = "";
+- errorProto.set(NativeError.MESSAGE, "", false);
++ errorProto.set(NativeError.MESSAGE, "", 0);
++
++ tagBuiltinProperties("Error", builtinError);
+
+ this.builtinEvalError = initErrorSubtype("EvalError", errorProto);
+ this.builtinRangeError = initErrorSubtype("RangeError", errorProto);
+@@ -1683,12 +2005,13 @@
+ }
+
+ private ScriptFunction initErrorSubtype(final String name, final ScriptObject errorProto) {
+- final ScriptObject cons = initConstructor(name);
++ final ScriptFunction cons = initConstructor(name, ScriptFunction.class);
+ final ScriptObject prototype = ScriptFunction.getPrototype(cons);
+- prototype.set(NativeError.NAME, name, false);
+- prototype.set(NativeError.MESSAGE, "", false);
++ prototype.set(NativeError.NAME, name, 0);
++ prototype.set(NativeError.MESSAGE, "", 0);
+ prototype.setInitialProto(errorProto);
+- return (ScriptFunction)cons;
++ tagBuiltinProperties(name, cons);
++ return cons;
+ }
+
+ private void initJavaAccess() {
+@@ -1700,8 +2023,8 @@
+ this.builtinJavafx = new NativeJavaPackage("javafx", objectProto);
+ this.builtinJavax = new NativeJavaPackage("javax", objectProto);
+ this.builtinOrg = new NativeJavaPackage("org", objectProto);
+- this.builtinJavaImporter = initConstructor("JavaImporter");
+- this.builtinJavaApi = initConstructor("Java");
++ this.builtinJavaImporter = initConstructor("JavaImporter", ScriptFunction.class);
++ this.builtinJavaApi = initConstructor("Java", ScriptObject.class);
+ }
+
+ private void initScripting(final ScriptEnvironment scriptEnv) {
+@@ -1744,9 +2067,9 @@
+ }
+
+ private static void copyOptions(final ScriptObject options, final ScriptEnvironment scriptEnv) {
+- for (Field f : scriptEnv.getClass().getFields()) {
++ for (final Field f : scriptEnv.getClass().getFields()) {
+ try {
+- options.set(f.getName(), f.get(scriptEnv), false);
++ options.set(f.getName(), f.get(scriptEnv), 0);
+ } catch (final IllegalArgumentException | IllegalAccessException exp) {
+ throw new RuntimeException(exp);
+ }
+@@ -1754,17 +2077,18 @@
+ }
+
+ private void initTypedArray() {
+- this.builtinArrayBuffer = initConstructor("ArrayBuffer");
+- this.builtinDataView = initConstructor("DataView");
+- this.builtinInt8Array = initConstructor("Int8Array");
+- this.builtinUint8Array = initConstructor("Uint8Array");
+- this.builtinUint8ClampedArray = initConstructor("Uint8ClampedArray");
+- this.builtinInt16Array = initConstructor("Int16Array");
+- this.builtinUint16Array = initConstructor("Uint16Array");
+- this.builtinInt32Array = initConstructor("Int32Array");
+- this.builtinUint32Array = initConstructor("Uint32Array");
+- this.builtinFloat32Array = initConstructor("Float32Array");
+- this.builtinFloat64Array = initConstructor("Float64Array");
++ this.builtinArrayBuffer = initConstructorAndSwitchPoint("ArrayBuffer", ScriptFunction.class);
++ this.builtinDataView = initConstructorAndSwitchPoint("DataView", ScriptFunction.class);
++ this.builtinInt8Array = initConstructorAndSwitchPoint("Int8Array", ScriptFunction.class);
++ this.builtinUint8Array = initConstructorAndSwitchPoint("Uint8Array", ScriptFunction.class);
++ this.builtinUint8ClampedArray = initConstructorAndSwitchPoint("Uint8ClampedArray", ScriptFunction.class);
++ this.builtinInt16Array = initConstructorAndSwitchPoint("Int16Array", ScriptFunction.class);
++ this.builtinUint16Array = initConstructorAndSwitchPoint("Uint16Array", ScriptFunction.class);
++ this.builtinInt32Array = initConstructorAndSwitchPoint("Int32Array", ScriptFunction.class);
++ this.builtinUint32Array = initConstructorAndSwitchPoint("Uint32Array", ScriptFunction.class);
++ this.builtinFloat32Array = initConstructorAndSwitchPoint("Float32Array", ScriptFunction.class);
++ this.builtinFloat64Array = initConstructorAndSwitchPoint("Float64Array", ScriptFunction.class);
++
+ }
+
+ private void copyBuiltins() {
+@@ -1809,20 +2133,20 @@
+ }
+
+ private void initDebug() {
+- this.addOwnProperty("Debug", Attribute.NOT_ENUMERABLE, initConstructor("Debug"));
++ this.addOwnProperty("Debug", Attribute.NOT_ENUMERABLE, initConstructor("Debug", ScriptObject.class));
+ }
+
+- @SuppressWarnings("resource")
+- private static Object printImpl(final boolean newLine, final Object... objects) {
+- final PrintWriter out = Global.getEnv().getOut();
++ private Object printImpl(final boolean newLine, final Object... objects) {
++ @SuppressWarnings("resource")
++ final PrintWriter out = scontext != null? new PrintWriter(scontext.getWriter()) : getContext().getEnv().getOut();
+ final StringBuilder sb = new StringBuilder();
+
+- for (final Object object : objects) {
++ for (final Object obj : objects) {
+ if (sb.length() != 0) {
+ sb.append(' ');
+ }
+
+- sb.append(JSType.toString(object));
++ sb.append(JSType.toString(obj));
+ }
+
+ // Print all at once to ensure thread friendly result.
+@@ -1837,11 +2161,7 @@
+ return UNDEFINED;
+ }
+
+- /**
+- * These classes are generated by nasgen tool and so we have to use
+- * reflection to load and create new instance of these classes.
+- */
+- private ScriptObject initConstructor(final String name) {
++ private <T extends ScriptObject> T initConstructor(final String name, final Class<T> clazz) {
+ try {
+ // Assuming class name pattern for built-in JS constructors.
+ final StringBuilder sb = new StringBuilder("jdk.nashorn.internal.objects.");
+@@ -1850,8 +2170,8 @@
+ sb.append(name);
+ sb.append("$Constructor");
+
+- final Class<?> funcClass = Class.forName(sb.toString());
+- final ScriptObject res = (ScriptObject)funcClass.newInstance();
++ final Class<?> funcClass = Class.forName(sb.toString());
++ final T res = clazz.cast(funcClass.newInstance());
+
+ if (res instanceof ScriptFunction) {
+ // All global constructor prototypes are not-writable,
+@@ -1864,13 +2184,53 @@
+ res.setInitialProto(getObjectPrototype());
+ }
+
++ res.setIsBuiltin();
++
+ return res;
+-
+ } catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
++ private List<jdk.nashorn.internal.runtime.Property> extractBuiltinProperties(final String name, final ScriptObject func) {
++ final List<jdk.nashorn.internal.runtime.Property> list = new ArrayList<>();
++
++ list.addAll(Arrays.asList(func.getMap().getProperties()));
++
++ if (func instanceof ScriptFunction) {
++ final ScriptObject proto = ScriptFunction.getPrototype((ScriptFunction)func);
++ if (proto != null) {
++ list.addAll(Arrays.asList(proto.getMap().getProperties()));
++ }
++ }
++
++ final jdk.nashorn.internal.runtime.Property prop = getProperty(name);
++ if (prop != null) {
++ list.add(prop);
++ }
++
++ return list;
++ }
++
++ /**
++ * Given a builtin object, traverse its properties recursively and associate them with a name that
++ * will be a key to their invalidation switchpoint.
++ * @param name name for key
++ * @param func builtin script object
++ */
++ private void tagBuiltinProperties(final String name, final ScriptObject func) {
++ SwitchPoint sp = context.getBuiltinSwitchPoint(name);
++ if (sp == null) {
++ sp = context.newBuiltinSwitchPoint(name);
++ }
++
++ //get all builtin properties in this builtin object and register switchpoints keyed on the propery name,
++ //one overwrite destroys all for now, e.g. Function.prototype.apply = 17; also destroys Function.prototype.call etc
++ for (final jdk.nashorn.internal.runtime.Property prop : extractBuiltinProperties(name, func)) {
++ prop.setBuiltinSwitchPoint(sp);
++ }
++ }
++
+ // Function and Object constructors are inter-dependent. Also,
+ // Function.prototype
+ // functions are not properly initialized. We fix the references here.
+@@ -1879,10 +2239,11 @@
+ // to play with object references carefully!!
+ private void initFunctionAndObject() {
+ // First-n-foremost is Function
+- this.builtinFunction = (ScriptFunction)initConstructor("Function");
++
++ this.builtinFunction = initConstructor("Function", ScriptFunction.class);
+
+ // create global anonymous function
+- final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction(this);
++ final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction();
+ // need to copy over members of Function.prototype to anon function
+ anon.addBoundProperties(getFunctionPrototype());
+
+@@ -1890,7 +2251,7 @@
+ // <anon-function>
+ builtinFunction.setInitialProto(anon);
+ builtinFunction.setPrototype(anon);
+- anon.set("constructor", builtinFunction, false);
++ anon.set("constructor", builtinFunction, 0);
+ anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
+
+ // use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3
+@@ -1901,7 +2262,7 @@
+ typeErrorThrower.preventExtensions();
+
+ // now initialize Object
+- this.builtinObject = (ScriptFunction)initConstructor("Object");
++ this.builtinObject = initConstructor("Object", ScriptFunction.class);
+ final ScriptObject ObjectPrototype = getObjectPrototype();
+ // Object.getPrototypeOf(Function.prototype) === Object.prototype
+ anon.setInitialProto(ObjectPrototype);
+@@ -1912,7 +2273,6 @@
+ final ScriptFunction setProto = ScriptFunctionImpl.makeFunction("setProto", NativeObject.SET__PROTO__);
+ ObjectPrototype.addOwnProperty("__proto__", Attribute.NOT_ENUMERABLE, getProto, setProto);
+
+-
+ // Function valued properties of Function.prototype were not properly
+ // initialized. Because, these were created before global.function and
+ // global.object were not initialized.
+@@ -1947,14 +2307,14 @@
+ }
+
+ properties = getObjectPrototype().getMap().getProperties();
++
+ for (final jdk.nashorn.internal.runtime.Property property : properties) {
+ final Object key = property.getKey();
+- final Object value = ObjectPrototype.get(key);
+-
+ if (key.equals("constructor")) {
+ continue;
+ }
+
++ final Object value = ObjectPrototype.get(key);
+ if (value instanceof ScriptFunction) {
+ final ScriptFunction func = (ScriptFunction)value;
+ final ScriptObject prototype = ScriptFunction.getPrototype(func);
+@@ -1963,9 +2323,13 @@
+ }
+ }
+ }
++
++ tagBuiltinProperties("Object", builtinObject);
++ tagBuiltinProperties("Function", builtinFunction);
++ tagBuiltinProperties("Function", anon);
+ }
+
+- private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
++ private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
+ return MH.findStatic(MethodHandles.lookup(), Global.class, name, MH.type(rtype, types));
+ }
+
+@@ -1977,4 +2341,40 @@
+ this.lastRegExpResult = regExpResult;
+ }
+
++ @Override
++ protected boolean isGlobal() {
++ return true;
++ }
++
++ /**
++ * A class representing the ES6 global lexical scope.
++ */
++ private static class LexicalScope extends ScriptObject {
++
++ LexicalScope(final ScriptObject proto) {
++ super(proto, PropertyMap.newMap());
++ }
++
++ @Override
++ protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
++ return filterInvocation(super.findGetMethod(desc, request, operator));
++ }
++
++ @Override
++ protected GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) {
++ return filterInvocation(super.findSetMethod(desc, request));
++ }
++
++ @Override
++ protected PropertyMap addBoundProperty(final PropertyMap propMap, final ScriptObject source, final jdk.nashorn.internal.runtime.Property property) {
++ // We override this method just to make it callable by Global
++ return super.addBoundProperty(propMap, source, property);
++ }
++
++ private static GuardedInvocation filterInvocation(final GuardedInvocation invocation) {
++ final MethodType type = invocation.getInvocation().type();
++ return invocation.asType(type.changeParameterType(0, Object.class)).filterArguments(0, LEXICAL_SCOPE_FILTER);
++ }
++ }
++
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeArray.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeArray.java Wed Feb 04 12:14:47 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -29,9 +29,10 @@
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+ import static jdk.nashorn.internal.runtime.PropertyDescriptor.VALUE;
+ import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE;
++import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
+ import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.arrayLikeIterator;
+ import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.reverseArrayLikeIterator;
+-import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT;
+
+ import java.lang.invoke.MethodHandle;
+ import java.util.ArrayList;
+@@ -41,7 +42,9 @@
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.concurrent.Callable;
+-
++import jdk.internal.dynalink.CallSiteDescriptor;
++import jdk.internal.dynalink.linker.GuardedInvocation;
++import jdk.internal.dynalink.linker.LinkRequest;
+ import jdk.nashorn.api.scripting.JSObject;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+@@ -49,9 +52,13 @@
+ import jdk.nashorn.internal.objects.annotations.Getter;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+ import jdk.nashorn.internal.objects.annotations.Setter;
+-import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
++import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
++import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
+ import jdk.nashorn.internal.objects.annotations.Where;
++import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.Debug;
+ import jdk.nashorn.internal.runtime.JSType;
++import jdk.nashorn.internal.runtime.OptimisticBuiltins;
+ import jdk.nashorn.internal.runtime.PropertyDescriptor;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+@@ -61,7 +68,11 @@
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
+ import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
+ import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
++import jdk.nashorn.internal.runtime.arrays.ContinuousArrayData;
++import jdk.nashorn.internal.runtime.arrays.IntElements;
++import jdk.nashorn.internal.runtime.arrays.IntOrLongElements;
+ import jdk.nashorn.internal.runtime.arrays.IteratorAction;
++import jdk.nashorn.internal.runtime.arrays.NumericElements;
+ import jdk.nashorn.internal.runtime.linker.Bootstrap;
+ import jdk.nashorn.internal.runtime.linker.InvokeByName;
+
+@@ -70,7 +81,7 @@
+ * keyed values. All other values are stored in spill.
+ */
+ @ScriptClass("Array")
+-public final class NativeArray extends ScriptObject {
++public final class NativeArray extends ScriptObject implements OptimisticBuiltins {
+ private static final Object JOIN = new Object();
+ private static final Object EVERY_CALLBACK_INVOKER = new Object();
+ private static final Object SOME_CALLBACK_INVOKER = new Object();
+@@ -81,6 +92,89 @@
+ private static final Object CALL_CMP = new Object();
+ private static final Object TO_LOCALE_STRING = new Object();
+
++ /*
++ * Constructors.
++ */
++ NativeArray() {
++ this(ArrayData.initialArray());
++ }
++
++ NativeArray(final long length) {
++ // TODO assert valid index in long before casting
++ this(ArrayData.allocate((int)length));
++ }
++
++ NativeArray(final int[] array) {
++ this(ArrayData.allocate(array));
++ }
++
++ NativeArray(final long[] array) {
++ this(ArrayData.allocate(array));
++ }
++
++ NativeArray(final double[] array) {
++ this(ArrayData.allocate(array));
++ }
++
++ NativeArray(final Object[] array) {
++ this(ArrayData.allocate(array.length));
++
++ ArrayData arrayData = this.getArray();
++ if (array.length > 0) {
++ arrayData.ensure(array.length - 1);
++ }
++
++ for (int index = 0; index < array.length; index++) {
++ final Object value = array[index];
++
++ if (value == ScriptRuntime.EMPTY) {
++ arrayData = arrayData.delete(index);
++ } else {
++ arrayData = arrayData.set(index, value, false);
++ }
++ }
++
++ this.setArray(arrayData);
++ }
++
++ NativeArray(final ArrayData arrayData) {
++ this(arrayData, Global.instance());
++ }
++
++ NativeArray(final ArrayData arrayData, final Global global) {
++ super(global.getArrayPrototype(), $nasgenmap$);
++ setArray(arrayData);
++ setIsArray();
++ }
++
++ @Override
++ protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
++ final GuardedInvocation inv = getArray().findFastGetMethod(getArray().getClass(), desc, request, operator);
++ if (inv != null) {
++ return inv;
++ }
++ return super.findGetMethod(desc, request, operator);
++ }
++
++ @Override
++ protected GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) {
++ final GuardedInvocation inv = getArray().findFastGetIndexMethod(getArray().getClass(), desc, request);
++ if (inv != null) {
++ return inv;
++ }
++ return super.findGetIndexMethod(desc, request);
++ }
++
++ @Override
++ protected GuardedInvocation findSetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) {
++ final GuardedInvocation inv = getArray().findFastSetIndexMethod(getArray().getClass(), desc, request);
++ if (inv != null) {
++ return inv;
++ }
++
++ return super.findSetIndexMethod(desc, request);
++ }
++
+ private static InvokeByName getJOIN() {
+ return Global.instance().getInvokeByName(JOIN,
+ new Callable<InvokeByName>() {
+@@ -157,59 +251,6 @@
+ // initialized by nasgen
+ private static PropertyMap $nasgenmap$;
+
+- /*
+- * Constructors.
+- */
+- NativeArray() {
+- this(ArrayData.initialArray());
+- }
+-
+- NativeArray(final long length) {
+- // TODO assert valid index in long before casting
+- this(ArrayData.allocate((int) length));
+- }
+-
+- NativeArray(final int[] array) {
+- this(ArrayData.allocate(array));
+- }
+-
+- NativeArray(final long[] array) {
+- this(ArrayData.allocate(array));
+- }
+-
+- NativeArray(final double[] array) {
+- this(ArrayData.allocate(array));
+- }
+-
+- NativeArray(final Object[] array) {
+- this(ArrayData.allocate(array.length));
+-
+- ArrayData arrayData = this.getArray();
+- arrayData.ensure(array.length - 1);
+-
+- for (int index = 0; index < array.length; index++) {
+- final Object value = array[index];
+-
+- if (value == ScriptRuntime.EMPTY) {
+- arrayData = arrayData.delete(index);
+- } else {
+- arrayData = arrayData.set(index, value, false);
+- }
+- }
+-
+- this.setArray(arrayData);
+- }
+-
+- NativeArray(final ArrayData arrayData) {
+- this(arrayData, Global.instance());
+- }
+-
+- NativeArray(final ArrayData arrayData, final Global global) {
+- super(global.getArrayPrototype(), $nasgenmap$);
+- this.setArray(arrayData);
+- this.setIsArray();
+- }
+-
+ @Override
+ public String getClassName() {
+ return "Array";
+@@ -217,7 +258,82 @@
+
+ @Override
+ public Object getLength() {
+- return getArray().length() & JSType.MAX_UINT;
++ final long length = JSType.toUint32(getArray().length());
++ if (length < Integer.MAX_VALUE) {
++ return (int)length;
++ }
++ return length;
++ }
++
++ private boolean defineLength(final long oldLen, final PropertyDescriptor oldLenDesc, final PropertyDescriptor desc, final boolean reject) {
++ // Step 3a
++ if (!desc.has(VALUE)) {
++ return super.defineOwnProperty("length", desc, reject);
++ }
++
++ // Step 3b
++ final PropertyDescriptor newLenDesc = desc;
++
++ // Step 3c and 3d - get new length and convert to long
++ final long newLen = NativeArray.validLength(newLenDesc.getValue(), true);
++
++ // Step 3e
++ newLenDesc.setValue(newLen);
++
++ // Step 3f
++ // increasing array length - just need to set new length value (and attributes if any) and return
++ if (newLen >= oldLen) {
++ return super.defineOwnProperty("length", newLenDesc, reject);
++ }
++
++ // Step 3g
++ if (!oldLenDesc.isWritable()) {
++ if (reject) {
++ throw typeError("property.not.writable", "length", ScriptRuntime.safeToString(this));
++ }
++ return false;
++ }
++
++ // Step 3h and 3i
++ final boolean newWritable = !newLenDesc.has(WRITABLE) || newLenDesc.isWritable();
++ if (!newWritable) {
++ newLenDesc.setWritable(true);
++ }
++
++ // Step 3j and 3k
++ final boolean succeeded = super.defineOwnProperty("length", newLenDesc, reject);
++ if (!succeeded) {
++ return false;
++ }
++
++ // Step 3l
++ // make sure that length is set till the point we can delete the old elements
++ long o = oldLen;
++ while (newLen < o) {
++ o--;
++ final boolean deleteSucceeded = delete(o, false);
++ if (!deleteSucceeded) {
++ newLenDesc.setValue(o + 1);
++ if (!newWritable) {
++ newLenDesc.setWritable(false);
++ }
++ super.defineOwnProperty("length", newLenDesc, false);
++ if (reject) {
++ throw typeError("property.not.writable", "length", ScriptRuntime.safeToString(this));
++ }
++ return false;
++ }
++ }
++
++ // Step 3m
++ if (!newWritable) {
++ // make 'length' property not writable
++ final ScriptObject newDesc = Global.newEmptyInstance();
++ newDesc.set(WRITABLE, false, 0);
++ return super.defineOwnProperty("length", newDesc, false);
++ }
++
++ return true;
+ }
+
+ /**
+@@ -233,82 +349,16 @@
+
+ // Step 2
+ // get old length and convert to long
+- long oldLen = NativeArray.validLength(oldLenDesc.getValue(), true);
++ final long oldLen = NativeArray.validLength(oldLenDesc.getValue(), true);
+
+ // Step 3
+ if ("length".equals(key)) {
+ // check for length being made non-writable
++ final boolean result = defineLength(oldLen, oldLenDesc, desc, reject);
+ if (desc.has(WRITABLE) && !desc.isWritable()) {
+ setIsLengthNotWritable();
+ }
+-
+- // Step 3a
+- if (!desc.has(VALUE)) {
+- return super.defineOwnProperty("length", desc, reject);
+- }
+-
+- // Step 3b
+- final PropertyDescriptor newLenDesc = desc;
+-
+- // Step 3c and 3d - get new length and convert to long
+- final long newLen = NativeArray.validLength(newLenDesc.getValue(), true);
+-
+- // Step 3e
+- newLenDesc.setValue(newLen);
+-
+- // Step 3f
+- // increasing array length - just need to set new length value (and attributes if any) and return
+- if (newLen >= oldLen) {
+- return super.defineOwnProperty("length", newLenDesc, reject);
+- }
+-
+- // Step 3g
+- if (!oldLenDesc.isWritable()) {
+- if (reject) {
+- throw typeError("property.not.writable", "length", ScriptRuntime.safeToString(this));
+- }
+- return false;
+- }
+-
+- // Step 3h and 3i
+- final boolean newWritable = (!newLenDesc.has(WRITABLE) || newLenDesc.isWritable());
+- if (!newWritable) {
+- newLenDesc.setWritable(true);
+- }
+-
+- // Step 3j and 3k
+- final boolean succeeded = super.defineOwnProperty("length", newLenDesc, reject);
+- if (!succeeded) {
+- return false;
+- }
+-
+- // Step 3l
+- // make sure that length is set till the point we can delete the old elements
+- while (newLen < oldLen) {
+- oldLen--;
+- final boolean deleteSucceeded = delete(oldLen, false);
+- if (!deleteSucceeded) {
+- newLenDesc.setValue(oldLen + 1);
+- if (!newWritable) {
+- newLenDesc.setWritable(false);
+- }
+- super.defineOwnProperty("length", newLenDesc, false);
+- if (reject) {
+- throw typeError("property.not.writable", "length", ScriptRuntime.safeToString(this));
+- }
+- return false;
+- }
+- }
+-
+- // Step 3m
+- if (!newWritable) {
+- // make 'length' property not writable
+- final ScriptObject newDesc = Global.newEmptyInstance();
+- newDesc.set(WRITABLE, false, false);
+- return super.defineOwnProperty("length", newDesc, false);
+- }
+-
+- return true;
++ return result;
+ }
+
+ // Step 4a
+@@ -381,6 +431,12 @@
+ return getArray().asObjectArray();
+ }
+
++ @Override
++ public void setIsLengthNotWritable() {
++ super.setIsLengthNotWritable();
++ setArray(ArrayData.setIsLengthNotWritable(getArray()));
++ }
++
+ /**
+ * ECMA 15.4.3.2 Array.isArray ( arg )
+ *
+@@ -401,7 +457,7 @@
+ @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
+ public static Object length(final Object self) {
+ if (isArray(self)) {
+- return ((ScriptObject) self).getArray().length() & JSType.MAX_UINT;
++ return JSType.toUint32(((ScriptObject) self).getArray().length());
+ }
+
+ return 0;
+@@ -415,7 +471,7 @@
+ @Setter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
+ public static void length(final Object self, final Object length) {
+ if (isArray(self)) {
+- ((ScriptObject) self).setLength(validLength(length, true));
++ ((ScriptObject)self).setLength(validLength(length, true));
+ }
+ }
+
+@@ -482,6 +538,19 @@
+ }
+
+ /**
++ * Assert that an array is numeric, if not throw type error
++ * @param self self array to check
++ * @return true if numeric
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE)
++ public static Object assertNumeric(final Object self) {
++ if(!(self instanceof NativeArray && ((NativeArray)self).getArray().getOptimisticType().isNumeric())) {
++ throw typeError("not.a.numeric.array", ScriptRuntime.safeToString(self));
++ }
++ return Boolean.TRUE;
++ }
++
++ /**
+ * ECMA 15.4.4.3 Array.prototype.toLocaleString ( )
+ *
+ * @param self self reference
+@@ -586,7 +655,7 @@
+ * @param self self reference
+ * @return the new NativeArray
+ */
+- @SpecializedConstructor
++ @SpecializedFunction(isConstructor=true)
+ public static NativeArray construct(final boolean newObj, final Object self) {
+ return new NativeArray(0);
+ }
+@@ -594,6 +663,21 @@
+ /**
+ * ECMA 15.4.2.2 new Array (len)
+ *
++ * Specialized constructor for zero arguments - empty array
++ *
++ * @param newObj was the new operator used to instantiate this array
++ * @param self self reference
++ * @param element first element
++ * @return the new NativeArray
++ */
++ @SpecializedFunction(isConstructor=true)
++ public static Object construct(final boolean newObj, final Object self, final boolean element) {
++ return new NativeArray(new Object[] { element });
++ }
++
++ /**
++ * ECMA 15.4.2.2 new Array (len)
++ *
+ * Specialized constructor for one integer argument (length)
+ *
+ * @param newObj was the new operator used to instantiate this array
+@@ -601,7 +685,7 @@
+ * @param length array length
+ * @return the new NativeArray
+ */
+- @SpecializedConstructor
++ @SpecializedFunction(isConstructor=true)
+ public static NativeArray construct(final boolean newObj, final Object self, final int length) {
+ if (length >= 0) {
+ return new NativeArray(length);
+@@ -620,7 +704,7 @@
+ * @param length array length
+ * @return the new NativeArray
+ */
+- @SpecializedConstructor
++ @SpecializedFunction(isConstructor=true)
+ public static NativeArray construct(final boolean newObj, final Object self, final long length) {
+ if (length >= 0L && length <= JSType.MAX_UINT) {
+ return new NativeArray(length);
+@@ -639,7 +723,7 @@
+ * @param length array length
+ * @return the new NativeArray
+ */
+- @SpecializedConstructor
++ @SpecializedFunction(isConstructor=true)
+ public static NativeArray construct(final boolean newObj, final Object self, final double length) {
+ final long uint32length = JSType.toUint32(length);
+
+@@ -654,12 +738,86 @@
+ * ECMA 15.4.4.4 Array.prototype.concat ( [ item1 [ , item2 [ , ... ] ] ] )
+ *
+ * @param self self reference
+- * @param args arguments to concat
++ * @param arg argument
++ * @return resulting NativeArray
++ */
++ @SpecializedFunction(linkLogic=ConcatLinkLogic.class)
++ public static NativeArray concat(final Object self, final int arg) {
++ final ContinuousArrayData newData = getContinuousArrayDataCCE(self, Integer.class).copy(); //get at least an integer data copy of this data
++ newData.fastPush(arg); //add an integer to its end
++ return new NativeArray(newData);
++ }
++
++ /**
++ * ECMA 15.4.4.4 Array.prototype.concat ( [ item1 [ , item2 [ , ... ] ] ] )
++ *
++ * @param self self reference
++ * @param arg argument
++ * @return resulting NativeArray
++ */
++ @SpecializedFunction(linkLogic=ConcatLinkLogic.class)
++ public static NativeArray concat(final Object self, final long arg) {
++ final ContinuousArrayData newData = getContinuousArrayDataCCE(self, Long.class).copy(); //get at least a long array data copy of this data
++ newData.fastPush(arg); //add a long at the end
++ return new NativeArray(newData);
++ }
++
++ /**
++ * ECMA 15.4.4.4 Array.prototype.concat ( [ item1 [ , item2 [ , ... ] ] ] )
++ *
++ * @param self self reference
++ * @param arg argument
++ * @return resulting NativeArray
++ */
++ @SpecializedFunction(linkLogic=ConcatLinkLogic.class)
++ public static NativeArray concat(final Object self, final double arg) {
++ final ContinuousArrayData newData = getContinuousArrayDataCCE(self, Double.class).copy(); //get at least a number array data copy of this data
++ newData.fastPush(arg); //add a double at the end
++ return new NativeArray(newData);
++ }
++
++ /**
++ * ECMA 15.4.4.4 Array.prototype.concat ( [ item1 [ , item2 [ , ... ] ] ] )
++ *
++ * @param self self reference
++ * @param arg argument
++ * @return resulting NativeArray
++ */
++ @SpecializedFunction(linkLogic=ConcatLinkLogic.class)
++ public static NativeArray concat(final Object self, final Object arg) {
++ //arg is [NativeArray] of same type.
++ final ContinuousArrayData selfData = getContinuousArrayDataCCE(self);
++ final ContinuousArrayData newData;
++
++ if (arg instanceof NativeArray) {
++ final ContinuousArrayData argData = (ContinuousArrayData)((NativeArray)arg).getArray();
++ if (argData.isEmpty()) {
++ newData = selfData.copy();
++ } else if (selfData.isEmpty()) {
++ newData = argData.copy();
++ } else {
++ final Class<?> widestElementType = selfData.widest(argData).getBoxedElementType();
++ newData = ((ContinuousArrayData)selfData.convert(widestElementType)).fastConcat((ContinuousArrayData)argData.convert(widestElementType));
++ }
++ } else {
++ newData = getContinuousArrayDataCCE(self, Object.class).copy();
++ newData.fastPush(arg);
++ }
++
++ return new NativeArray(newData);
++ }
++
++ /**
++ * ECMA 15.4.4.4 Array.prototype.concat ( [ item1 [ , item2 [ , ... ] ] ] )
++ *
++ * @param self self reference
++ * @param args arguments
+ * @return resulting NativeArray
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+ public static NativeArray concat(final Object self, final Object... args) {
+ final ArrayList<Object> list = new ArrayList<>();
++
+ concatToList(list, Global.toObject(self));
+
+ for (final Object obj : args) {
+@@ -669,16 +827,16 @@
+ return new NativeArray(list.toArray());
+ }
+
+- @SuppressWarnings("null")
+ private static void concatToList(final ArrayList<Object> list, final Object obj) {
+- final boolean isScriptArray = isArray(obj);
++ final boolean isScriptArray = isArray(obj);
+ final boolean isScriptObject = isScriptArray || obj instanceof ScriptObject;
+ if (isScriptArray || obj instanceof Iterable || (obj != null && obj.getClass().isArray())) {
+ final Iterator<Object> iter = arrayLikeIterator(obj, true);
+ if (iter.hasNext()) {
+ for (int i = 0; iter.hasNext(); ++i) {
+ final Object value = iter.next();
+- if (value == ScriptRuntime.UNDEFINED && isScriptObject && !((ScriptObject)obj).has(i)) {
++ final boolean lacksIndex = obj != null && !((ScriptObject)obj).has(i);
++ if (value == ScriptRuntime.UNDEFINED && isScriptObject && lacksIndex) {
+ // TODO: eventually rewrite arrayLikeIterator to use a three-state enum for handling
+ // UNDEFINED instead of an "includeUndefined" boolean with states SKIP, INCLUDE,
+ // RETURN_EMPTY. Until then, this is how we'll make sure that empty elements don't make it
+@@ -726,6 +884,68 @@
+ }
+
+ /**
++ * Specialization of pop for ContinuousArrayData
++ * The link guard checks that the array is continuous AND not empty.
++ * The runtime guard checks that the guard is continuous (CCE otherwise)
++ *
++ * Primitive specialization, {@link LinkLogic}
++ *
++ * @param self self reference
++ * @return element popped
++ * @throws ClassCastException if array is empty, facilitating Undefined return value
++ */
++ @SpecializedFunction(name="pop", linkLogic=PopLinkLogic.class)
++ public static int popInt(final Object self) {
++ //must be non empty IntArrayData
++ return getContinuousNonEmptyArrayDataCCE(self, IntElements.class).fastPopInt();
++ }
++
++ /**
++ * Specialization of pop for ContinuousArrayData
++ *
++ * Primitive specialization, {@link LinkLogic}
++ *
++ * @param self self reference
++ * @return element popped
++ * @throws ClassCastException if array is empty, facilitating Undefined return value
++ */
++ @SpecializedFunction(name="pop", linkLogic=PopLinkLogic.class)
++ public static long popLong(final Object self) {
++ //must be non empty Int or LongArrayData
++ return getContinuousNonEmptyArrayDataCCE(self, IntOrLongElements.class).fastPopLong();
++ }
++
++ /**
++ * Specialization of pop for ContinuousArrayData
++ *
++ * Primitive specialization, {@link LinkLogic}
++ *
++ * @param self self reference
++ * @return element popped
++ * @throws ClassCastException if array is empty, facilitating Undefined return value
++ */
++ @SpecializedFunction(name="pop", linkLogic=PopLinkLogic.class)
++ public static double popDouble(final Object self) {
++ //must be non empty int long or double array data
++ return getContinuousNonEmptyArrayDataCCE(self, NumericElements.class).fastPopDouble();
++ }
++
++ /**
++ * Specialization of pop for ContinuousArrayData
++ *
++ * Primitive specialization, {@link LinkLogic}
++ *
++ * @param self self reference
++ * @return element popped
++ * @throws ClassCastException if array is empty, facilitating Undefined return value
++ */
++ @SpecializedFunction(name="pop", linkLogic=PopLinkLogic.class)
++ public static Object popObject(final Object self) {
++ //can be any data, because the numeric ones will throw cce and force relink
++ return getContinuousArrayDataCCE(self, null).fastPopObject();
++ }
++
++ /**
+ * ECMA 15.4.4.6 Array.prototype.pop ()
+ *
+ * @param self self reference
+@@ -743,7 +963,7 @@
+ final long len = JSType.toUint32(sobj.getLength());
+
+ if (len == 0) {
+- sobj.set("length", 0, true);
++ sobj.set("length", 0, CALLSITE_STRICT);
+ return ScriptRuntime.UNDEFINED;
+ }
+
+@@ -751,7 +971,7 @@
+ final Object element = sobj.get(index);
+
+ sobj.delete(index, true);
+- sobj.set("length", index, true);
++ sobj.set("length", index, CALLSITE_STRICT);
+
+ return element;
+ } catch (final ClassCastException | NullPointerException e) {
+@@ -762,32 +982,112 @@
+ /**
+ * ECMA 15.4.4.7 Array.prototype.push (args...)
+ *
++ * Primitive specialization, {@link LinkLogic}
++ *
++ * @param self self reference
++ * @param arg a primitive to push
++ * @return array length after push
++ */
++ @SpecializedFunction(linkLogic=PushLinkLogic.class)
++ public static long push(final Object self, final int arg) {
++ return getContinuousArrayDataCCE(self, Integer.class).fastPush(arg);
++ }
++
++ /**
++ * ECMA 15.4.4.7 Array.prototype.push (args...)
++ *
++ * Primitive specialization, {@link LinkLogic}
++ *
++ * @param self self reference
++ * @param arg a primitive to push
++ * @return array length after push
++ */
++ @SpecializedFunction(linkLogic=PushLinkLogic.class)
++ public static long push(final Object self, final long arg) {
++ return getContinuousArrayDataCCE(self, Long.class).fastPush(arg);
++ }
++
++ /**
++ * ECMA 15.4.4.7 Array.prototype.push (args...)
++ *
++ * Primitive specialization, {@link LinkLogic}
++ *
++ * @param self self reference
++ * @param arg a primitive to push
++ * @return array length after push
++ */
++ @SpecializedFunction(linkLogic=PushLinkLogic.class)
++ public static long push(final Object self, final double arg) {
++ return getContinuousArrayDataCCE(self, Double.class).fastPush(arg);
++ }
++
++ /**
++ * ECMA 15.4.4.7 Array.prototype.push (args...)
++ *
++ * Primitive specialization, {@link LinkLogic}
++ *
++ * @param self self reference
++ * @param arg a primitive to push
++ * @return array length after push
++ */
++ @SpecializedFunction(name="push", linkLogic=PushLinkLogic.class)
++ public static long pushObject(final Object self, final Object arg) {
++ return getContinuousArrayDataCCE(self, Object.class).fastPush(arg);
++ }
++
++ /**
++ * ECMA 15.4.4.7 Array.prototype.push (args...)
++ *
+ * @param self self reference
+ * @param args arguments to push
+- * @return array after pushes
++ * @return array length after pushes
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+ public static Object push(final Object self, final Object... args) {
+ try {
+ final ScriptObject sobj = (ScriptObject)self;
+
+- if (bulkable(sobj)) {
+- if (sobj.getArray().length() + args.length <= JSType.MAX_UINT) {
+- final ArrayData newData = sobj.getArray().push(true, args);
+- sobj.setArray(newData);
+- return newData.length();
+- }
+- //fallthru
++ if (bulkable(sobj) && sobj.getArray().length() + args.length <= JSType.MAX_UINT) {
++ final ArrayData newData = sobj.getArray().push(true, args);
++ sobj.setArray(newData);
++ return newData.length();
+ }
+
+ long len = JSType.toUint32(sobj.getLength());
+ for (final Object element : args) {
+- sobj.set(len++, element, true);
++ sobj.set(len++, element, CALLSITE_STRICT);
+ }
+- sobj.set("length", len, true);
++ sobj.set("length", len, CALLSITE_STRICT);
+
+ return len;
+ } catch (final ClassCastException | NullPointerException e) {
++ throw typeError(Context.getGlobal(), e, "not.an.object", ScriptRuntime.safeToString(self));
++ }
++ }
++
++ /**
++ * ECMA 15.4.4.7 Array.prototype.push (args...) specialized for single object argument
++ *
++ * @param self self reference
++ * @param arg argument to push
++ * @return array after pushes
++ */
++ @SpecializedFunction
++ public static long push(final Object self, final Object arg) {
++ try {
++ final ScriptObject sobj = (ScriptObject)self;
++ final ArrayData arrayData = sobj.getArray();
++ final long length = arrayData.length();
++ if (bulkable(sobj) && length < JSType.MAX_UINT) {
++ sobj.setArray(arrayData.push(true, arg));
++ return length + 1;
++ }
++
++ long len = JSType.toUint32(sobj.getLength());
++ sobj.set(len++, arg, CALLSITE_STRICT);
++ sobj.set("length", len, CALLSITE_STRICT);
++ return len;
++ } catch (final ClassCastException | NullPointerException e) {
+ throw typeError("not.an.object", ScriptRuntime.safeToString(self));
+ }
+ }
+@@ -813,14 +1113,14 @@
+ final boolean upperExists = sobj.has(upper);
+
+ if (lowerExists && upperExists) {
+- sobj.set(lower, upperValue, true);
+- sobj.set(upper, lowerValue, true);
++ sobj.set(lower, upperValue, CALLSITE_STRICT);
++ sobj.set(upper, lowerValue, CALLSITE_STRICT);
+ } else if (!lowerExists && upperExists) {
+- sobj.set(lower, upperValue, true);
++ sobj.set(lower, upperValue, CALLSITE_STRICT);
+ sobj.delete(upper, true);
+ } else if (lowerExists && !upperExists) {
+ sobj.delete(lower, true);
+- sobj.set(upper, lowerValue, true);
++ sobj.set(upper, lowerValue, CALLSITE_STRICT);
+ }
+ }
+ return sobj;
+@@ -857,9 +1157,9 @@
+ } else {
+ boolean hasPrevious = true;
+ for (long k = 1; k < len; k++) {
+- boolean hasCurrent = sobj.has(k);
++ final boolean hasCurrent = sobj.has(k);
+ if (hasCurrent) {
+- sobj.set(k - 1, sobj.get(k), true);
++ sobj.set(k - 1, sobj.get(k), CALLSITE_STRICT);
+ } else if (hasPrevious) {
+ sobj.delete(k - 1, true);
+ }
+@@ -871,7 +1171,7 @@
+ len = 0;
+ }
+
+- sobj.set("length", len, true);
++ sobj.set("length", len, CALLSITE_STRICT);
+
+ return first;
+ }
+@@ -894,7 +1194,7 @@
+ final ScriptObject sobj = (ScriptObject)obj;
+ final long len = JSType.toUint32(sobj.getLength());
+ final long relativeStart = JSType.toLong(start);
+- final long relativeEnd = (end == ScriptRuntime.UNDEFINED) ? len : JSType.toLong(end);
++ final long relativeEnd = end == ScriptRuntime.UNDEFINED ? len : JSType.toLong(end);
+
+ long k = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len);
+ final long finale = relativeEnd < 0 ? Math.max(len + relativeEnd, 0) : Math.min(relativeEnd, len);
+@@ -983,10 +1283,13 @@
+ // Get only non-missing elements. Missing elements go at the end
+ // of the sorted array. So, just don't copy these to sort input.
+ final ArrayList<Object> src = new ArrayList<>();
+- for (long i = 0; i < len; i = array.nextIndex(i)) {
+- if (array.has((int) i)) {
+- src.add(array.getObject((int) i));
++
++ for (final Iterator<Long> iter = array.indexIterator(); iter.hasNext(); ) {
++ final long index = iter.next();
++ if (index >= len) {
++ break;
+ }
++ src.add(array.getObject((int)index));
+ }
+
+ final Object[] sorted = sort(src.toArray(), comparefn);
+@@ -1001,7 +1304,7 @@
+ }
+
+ sobj.setArray(array);
+- }
++ }
+
+ return sobj;
+ } catch (final ClassCastException | NullPointerException e) {
+@@ -1024,8 +1327,8 @@
+ return ScriptRuntime.UNDEFINED;
+ }
+
+- final Object start = (args.length > 0) ? args[0] : ScriptRuntime.UNDEFINED;
+- final Object deleteCount = (args.length > 1) ? args[1] : ScriptRuntime.UNDEFINED;
++ final Object start = args.length > 0 ? args[0] : ScriptRuntime.UNDEFINED;
++ final Object deleteCount = args.length > 1 ? args[1] : ScriptRuntime.UNDEFINED;
+
+ Object[] items;
+
+@@ -1054,7 +1357,7 @@
+ for (int i = 0; i < items.length; i++, k++) {
+ sobj.defineOwnProperty(k, items[i]);
+ }
+- } catch (UnsupportedOperationException uoe) {
++ } catch (final UnsupportedOperationException uoe) {
+ returnValue = slowSplice(sobj, actualStart, actualDeleteCount, items, len);
+ }
+ } else {
+@@ -1077,18 +1380,18 @@
+ }
+
+ if (items.length < deleteCount) {
+- for (long k = start; k < (len - deleteCount); k++) {
++ for (long k = start; k < len - deleteCount; k++) {
+ final long from = k + deleteCount;
+ final long to = k + items.length;
+
+ if (sobj.has(from)) {
+- sobj.set(to, sobj.get(from), true);
++ sobj.set(to, sobj.get(from), CALLSITE_STRICT);
+ } else {
+ sobj.delete(to, true);
+ }
+ }
+
+- for (long k = len; k > (len - deleteCount + items.length); k--) {
++ for (long k = len; k > len - deleteCount + items.length; k--) {
+ sobj.delete(k - 1, true);
+ }
+ } else if (items.length > deleteCount) {
+@@ -1098,7 +1401,7 @@
+
+ if (sobj.has(from)) {
+ final Object fromValue = sobj.get(from);
+- sobj.set(to, fromValue, true);
++ sobj.set(to, fromValue, CALLSITE_STRICT);
+ } else {
+ sobj.delete(to, true);
+ }
+@@ -1107,11 +1410,11 @@
+
+ long k = start;
+ for (int i = 0; i < items.length; i++, k++) {
+- sobj.set(k, items[i], true);
++ sobj.set(k, items[i], CALLSITE_STRICT);
+ }
+
+ final long newLength = len - deleteCount + items.length;
+- sobj.set("length", newLength, true);
++ sobj.set("length", newLength, CALLSITE_STRICT);
+
+ return array;
+ }
+@@ -1151,19 +1454,19 @@
+
+ if (sobj.has(from)) {
+ final Object fromValue = sobj.get(from);
+- sobj.set(to, fromValue, true);
++ sobj.set(to, fromValue, CALLSITE_STRICT);
+ } else {
+ sobj.delete(to, true);
+ }
+ }
+
+ for (int j = 0; j < items.length; j++) {
+- sobj.set(j, items[j], true);
++ sobj.set(j, items[j], CALLSITE_STRICT);
+ }
+ }
+
+ final long newLength = len + items.length;
+- sobj.set("length", newLength, true);
++ sobj.set("length", newLength, CALLSITE_STRICT);
+
+ return newLength;
+ }
+@@ -1191,7 +1494,7 @@
+ }
+
+
+- for (long k = Math.max(0, (n < 0) ? (len - Math.abs(n)) : n); k < len; k++) {
++ for (long k = Math.max(0, n < 0 ? len - Math.abs(n) : n); k < len; k++) {
+ if (sobj.has(k)) {
+ if (ScriptRuntime.EQ_STRICT(sobj.get(k), searchElement)) {
+ return k;
+@@ -1222,10 +1525,10 @@
+ return -1;
+ }
+
+- final Object searchElement = (args.length > 0) ? args[0] : ScriptRuntime.UNDEFINED;
+- final long n = (args.length > 1) ? JSType.toLong(args[1]) : (len - 1);
++ final Object searchElement = args.length > 0 ? args[0] : ScriptRuntime.UNDEFINED;
++ final long n = args.length > 1 ? JSType.toLong(args[1]) : len - 1;
+
+- for (long k = (n < 0) ? (len - Math.abs(n)) : Math.min(n, len - 1); k >= 0; k--) {
++ for (long k = n < 0 ? len - Math.abs(n) : Math.min(n, len - 1); k >= 0; k--) {
+ if (sobj.has(k)) {
+ if (ScriptRuntime.EQ_STRICT(sobj.get(k), searchElement)) {
+ return k;
+@@ -1258,7 +1561,7 @@
+
+ @Override
+ protected boolean forEach(final Object val, final long i) throws Throwable {
+- return (result = (boolean)everyInvoker.invokeExact(callbackfn, thisArg, val, i, self));
++ return result = (boolean)everyInvoker.invokeExact(callbackfn, thisArg, val, i, self);
+ }
+ }.apply();
+ }
+@@ -1435,4 +1738,166 @@
+
+ return false;
+ }
++
++ @Override
++ public String toString() {
++ return "NativeArray@" + Debug.id(this) + " [" + getArray().getClass().getSimpleName() + ']';
++ }
++
++ @Override
++ public SpecializedFunction.LinkLogic getLinkLogic(final Class<? extends LinkLogic> clazz) {
++ if (clazz == PushLinkLogic.class) {
++ return PushLinkLogic.INSTANCE;
++ } else if (clazz == PopLinkLogic.class) {
++ return PopLinkLogic.INSTANCE;
++ } else if (clazz == ConcatLinkLogic.class) {
++ return ConcatLinkLogic.INSTANCE;
++ }
++ return null;
++ }
++
++ @Override
++ public boolean hasPerInstanceAssumptions() {
++ return true; //length writable switchpoint
++ }
++
++ /**
++ * This is an abstract super class that contains common functionality for all
++ * specialized optimistic builtins in NativeArray. For example, it handles the
++ * modification switchpoint which is touched when length is written.
++ */
++ private static abstract class ArrayLinkLogic extends SpecializedFunction.LinkLogic {
++ protected ArrayLinkLogic() {
++ }
++
++ protected static ContinuousArrayData getContinuousArrayData(final Object self) {
++ try {
++ //cast to NativeArray, to avoid cases like x = {0:0, 1:1}, x.length = 2, where we can't use the array push/pop
++ return (ContinuousArrayData)((NativeArray)self).getArray();
++ } catch (final Exception e) {
++ return null;
++ }
++ }
++
++ /**
++ * Push and pop callsites can throw ClassCastException as a mechanism to have them
++ * relinked - this enabled fast checks of the kind of ((IntArrayData)arrayData).push(x)
++ * for an IntArrayData only push - if this fails, a CCE will be thrown and we will relink
++ */
++ @Override
++ public Class<? extends Throwable> getRelinkException() {
++ return ClassCastException.class;
++ }
++ }
++
++ /**
++ * This is linker logic for optimistic concatenations
++ */
++ private static final class ConcatLinkLogic extends ArrayLinkLogic {
++ private static final LinkLogic INSTANCE = new ConcatLinkLogic();
++
++ @Override
++ public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
++ final Object[] args = request.getArguments();
++
++ if (args.length != 3) { //single argument check
++ return false;
++ }
++
++ final ContinuousArrayData selfData = getContinuousArrayData(self);
++ if (selfData == null) {
++ return false;
++ }
++
++ final Object arg = args[2];
++ //args[2] continuousarray or non arraydata, let past non array datas
++ if (arg instanceof NativeArray) {
++ final ContinuousArrayData argData = getContinuousArrayData(arg);
++ if (argData == null) {
++ return false;
++ }
++ }
++
++ return true;
++ }
++ }
++
++ /**
++ * This is linker logic for optimistic pushes
++ */
++ private static final class PushLinkLogic extends ArrayLinkLogic {
++ private static final LinkLogic INSTANCE = new PushLinkLogic();
++
++ @Override
++ public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
++ return getContinuousArrayData(self) != null;
++ }
++ }
++
++ /**
++ * This is linker logic for optimistic pops
++ */
++ private static final class PopLinkLogic extends ArrayLinkLogic {
++ private static final LinkLogic INSTANCE = new PopLinkLogic();
++
++ /**
++ * We need to check if we are dealing with a continuous non empty array data here,
++ * as pop with a primitive return value returns undefined for arrays with length 0
++ */
++ @Override
++ public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
++ final ContinuousArrayData data = getContinuousNonEmptyArrayData(self);
++ if (data != null) {
++ final Class<?> elementType = data.getElementType();
++ final Class<?> returnType = desc.getMethodType().returnType();
++ final boolean typeFits = JSType.getAccessorTypeIndex(returnType) >= JSType.getAccessorTypeIndex(elementType);
++ return typeFits;
++ }
++ return false;
++ }
++
++ private static ContinuousArrayData getContinuousNonEmptyArrayData(final Object self) {
++ final ContinuousArrayData data = getContinuousArrayData(self);
++ if (data != null) {
++ return data.length() == 0 ? null : data;
++ }
++ return null;
++ }
++ }
++
++ //runtime calls for push and pops. they could be used as guards, but they also perform the runtime logic,
++ //so rather than synthesizing them into a guard method handle that would also perform the push on the
++ //retrieved receiver, we use this as runtime logic
++
++ //TODO - fold these into the Link logics, but I'll do that as a later step, as I want to do a checkin
++ //where everything works first
++
++ private static final <T> ContinuousArrayData getContinuousNonEmptyArrayDataCCE(final Object self, final Class<T> clazz) {
++ try {
++ @SuppressWarnings("unchecked")
++ final ContinuousArrayData data = (ContinuousArrayData)(T)((NativeArray)self).getArray();
++ if (data.length() != 0L) {
++ return data; //if length is 0 we cannot pop and have to relink, because then we'd have to return an undefined, which is a wider type than e.g. int
++ }
++ } catch (final NullPointerException e) {
++ //fallthru
++ }
++ throw new ClassCastException();
++ }
++
++ private static final ContinuousArrayData getContinuousArrayDataCCE(final Object self) {
++ try {
++ return (ContinuousArrayData)((NativeArray)self).getArray();
++ } catch (final NullPointerException e) {
++ throw new ClassCastException();
++ }
++ }
++
++ private static final ContinuousArrayData getContinuousArrayDataCCE(final Object self, final Class<?> elementType) {
++ try {
++ return (ContinuousArrayData)((NativeArray)self).getArray(elementType); //ensure element type can fit "elementType"
++ } catch (final NullPointerException e) {
++ throw new ClassCastException();
++ }
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,27 +25,81 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+ import java.nio.ByteBuffer;
+-import java.util.Arrays;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+ import jdk.nashorn.internal.objects.annotations.Function;
+ import jdk.nashorn.internal.objects.annotations.Getter;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
++import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
++import jdk.nashorn.internal.objects.annotations.Where;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+
++/**
++ * NativeArrayBuffer - ArrayBuffer as described in the JS typed
++ * array spec
++ */
+ @ScriptClass("ArrayBuffer")
+-final class NativeArrayBuffer extends ScriptObject {
+- private final byte[] buffer;
++public final class NativeArrayBuffer extends ScriptObject {
++ private final ByteBuffer nb;
+
+ // initialized by nasgen
+ private static PropertyMap $nasgenmap$;
+
++ /**
++ * Constructor
++ * @param nb native byte buffer to wrap
++ * @param global global instance
++ */
++ protected NativeArrayBuffer(final ByteBuffer nb, final Global global) {
++ super(global.getArrayBufferPrototype(), $nasgenmap$);
++ this.nb = nb;
++ }
++
++ /**
++ * Constructor
++ * @param nb native byte buffer to wrap
++ */
++ protected NativeArrayBuffer(final ByteBuffer nb) {
++ this(nb, Global.instance());
++ }
++
++ /**
++ * Constructor
++ * @param byteLength byteLength for buffer
++ */
++ protected NativeArrayBuffer(final int byteLength) {
++ this(ByteBuffer.allocateDirect(byteLength));
++ }
++
++ /**
++ * Clone constructor
++ * Used only for slice
++ * @param other original buffer
++ * @param begin begin byte index
++ * @param end end byte index
++ */
++ protected NativeArrayBuffer(final NativeArrayBuffer other, final int begin, final int end) {
++ this(cloneBuffer(other.getNioBuffer(), begin, end));
++ }
++
++ /**
++ * Constructor
++ * @param newObj is this invoked with new
++ * @param self self reference
++ * @param args arguments to constructor
++ * @return new NativeArrayBuffer
++ */
+ @Constructor(arity = 1)
+ public static NativeArrayBuffer constructor(final boolean newObj, final Object self, final Object... args) {
++ if (!newObj) {
++ throw typeError("constructor.requires.new", "ArrayBuffer");
++ }
++
+ if (args.length == 0) {
+ throw new RuntimeException("missing length argument");
+ }
+@@ -53,21 +107,19 @@
+ return new NativeArrayBuffer(JSType.toInt32(args[0]));
+ }
+
+- protected NativeArrayBuffer(final byte[] byteArray, final Global global) {
+- super(global.getArrayBufferPrototype(), $nasgenmap$);
+- this.buffer = byteArray;
++ private static ByteBuffer cloneBuffer(final ByteBuffer original, final int begin, final int end) {
++ final ByteBuffer clone = ByteBuffer.allocateDirect(original.capacity());
++ original.rewind();//copy from the beginning
++ clone.put(original);
++ original.rewind();
++ clone.flip();
++ clone.position(begin);
++ clone.limit(end);
++ return clone.slice();
+ }
+
+- protected NativeArrayBuffer(final byte[] byteArray) {
+- this(byteArray, Global.instance());
+- }
+-
+- protected NativeArrayBuffer(final int byteLength) {
+- this(new byte[byteLength]);
+- }
+-
+- protected NativeArrayBuffer(final NativeArrayBuffer other, final int begin, final int end) {
+- this(Arrays.copyOfRange(other.buffer, begin, end));
++ ByteBuffer getNioBuffer() {
++ return nb;
+ }
+
+ @Override
+@@ -75,19 +127,68 @@
+ return "ArrayBuffer";
+ }
+
++ /**
++ * Byte length for native array buffer
++ * @param self native array buffer
++ * @return byte length
++ */
+ @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
+- public static Object byteLength(final Object self) {
+- return ((NativeArrayBuffer)self).buffer.length;
++ public static int byteLength(final Object self) {
++ return ((NativeArrayBuffer)self).getByteLength();
+ }
+
++ /**
++ * Returns true if an object is an ArrayBufferView
++ *
++ * @param self self
++ * @param obj object to check
++ *
++ * @return true if obj is an ArrayBufferView
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static boolean isView(final Object self, final Object obj) {
++ return obj instanceof ArrayBufferView;
++ }
++
++ /**
++ * Slice function
++ * @param self native array buffer
++ * @param begin0 start byte index
++ * @param end0 end byte index
++ * @return new array buffer, sliced
++ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
+ public static NativeArrayBuffer slice(final Object self, final Object begin0, final Object end0) {
+ final NativeArrayBuffer arrayBuffer = (NativeArrayBuffer)self;
+- int begin = JSType.toInt32(begin0);
+- int end = end0 != ScriptRuntime.UNDEFINED ? JSType.toInt32(end0) : arrayBuffer.getByteLength();
+- begin = adjustIndex(begin, arrayBuffer.getByteLength());
+- end = adjustIndex(end, arrayBuffer.getByteLength());
+- return new NativeArrayBuffer((NativeArrayBuffer) self, begin, Math.max(end, begin));
++ final int byteLength = arrayBuffer.getByteLength();
++ final int begin = adjustIndex(JSType.toInt32(begin0), byteLength);
++ final int end = adjustIndex(end0 != ScriptRuntime.UNDEFINED ? JSType.toInt32(end0) : byteLength, byteLength);
++ return new NativeArrayBuffer(arrayBuffer, begin, Math.max(end, begin));
++ }
++
++ /**
++ * Specialized slice function
++ * @param self native array buffer
++ * @param begin start byte index
++ * @param end end byte index
++ * @return new array buffer, sliced
++ */
++ @SpecializedFunction
++ public static Object slice(final Object self, final int begin, final int end) {
++ final NativeArrayBuffer arrayBuffer = (NativeArrayBuffer)self;
++ final int byteLength = arrayBuffer.getByteLength();
++ return new NativeArrayBuffer(arrayBuffer, adjustIndex(begin, byteLength), Math.max(adjustIndex(end, byteLength), begin));
++ }
++
++ /**
++ * Specialized slice function
++ * @param self native array buffer
++ * @param begin start byte index
++ * @return new array buffer, sliced
++ */
++ @SpecializedFunction
++ public static Object slice(final Object self, final int begin) {
++ return slice(self, begin, ((NativeArrayBuffer)self).getByteLength());
+ }
+
+ /**
+@@ -100,10 +201,7 @@
+ * @return valid index index in the range [0, length).
+ */
+ static int adjustIndex(final int index, final int length) {
+- if (index < 0) {
+- return clamp(index + length, length);
+- }
+- return clamp(index, length);
++ return index < 0 ? clamp(index + length, length) : clamp(index, length);
+ }
+
+ /**
+@@ -118,23 +216,19 @@
+ return index;
+ }
+
+- public byte[] getByteArray() {
+- return buffer;
+- }
+-
+- public int getByteLength() {
+- return buffer.length;
++ int getByteLength() {
++ return nb.limit();
+ }
+
+ ByteBuffer getBuffer() {
+- return ByteBuffer.wrap(buffer);
++ return nb;
+ }
+
+ ByteBuffer getBuffer(final int offset) {
+- return ByteBuffer.wrap(buffer, offset, buffer.length - offset);
++ return (ByteBuffer)nb.duplicate().position(offset);
+ }
+
+ ByteBuffer getBuffer(final int offset, final int length) {
+- return ByteBuffer.wrap(buffer, offset, length);
++ return (ByteBuffer)getBuffer(offset).limit(length);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,8 +25,8 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.lookup.Lookup.MH;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+-import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+@@ -51,9 +51,9 @@
+ public final class NativeBoolean extends ScriptObject {
+ private final boolean value;
+
+- // Method handle to create an object wrapper for a primitive boolean
+- private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeBoolean.class, Object.class));
+- // Method handle to retrieve the Boolean prototype object
++ /** Method handle to create an object wrapper for a primitive boolean. */
++ static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeBoolean.class, Object.class));
++ /** Method handle to retrieve the Boolean prototype object. */
+ private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
+
+ // initialized by nasgen
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeDataView.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeDataView.java Wed Feb 04 12:14:47 2015 -0800
+@@ -24,9 +24,9 @@
+ */
+ package jdk.nashorn.internal.objects;
+
+-import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
++import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+ import java.nio.ByteBuffer;
+ import java.nio.ByteOrder;
+@@ -35,7 +35,6 @@
+ import jdk.nashorn.internal.objects.annotations.Function;
+ import jdk.nashorn.internal.objects.annotations.Property;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+-import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
+ import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+@@ -88,15 +87,15 @@
+ // underlying ByteBuffer
+ private final ByteBuffer buf;
+
+- private NativeDataView(NativeArrayBuffer arrBuf) {
++ private NativeDataView(final NativeArrayBuffer arrBuf) {
+ this(arrBuf, arrBuf.getBuffer(), 0);
+ }
+
+- private NativeDataView(NativeArrayBuffer arrBuf, int offset) {
++ private NativeDataView(final NativeArrayBuffer arrBuf, final int offset) {
+ this(arrBuf, bufferFrom(arrBuf, offset), offset);
+ }
+
+- private NativeDataView(NativeArrayBuffer arrBuf, int offset, int length) {
++ private NativeDataView(final NativeArrayBuffer arrBuf, final int offset, final int length) {
+ this(arrBuf, bufferFrom(arrBuf, offset, length), offset, length);
+ }
+
+@@ -106,10 +105,10 @@
+
+ private NativeDataView(final NativeArrayBuffer arrBuf, final ByteBuffer buf, final int offset, final int length) {
+ super(Global.instance().getDataViewPrototype(), $nasgenmap$);
+- this.buffer = arrBuf;
++ this.buffer = arrBuf;
+ this.byteOffset = offset;
+ this.byteLength = length;
+- this.buf = buf;
++ this.buf = buf;
+ }
+
+ /**
+@@ -136,14 +135,14 @@
+ throw typeError("not.an.arraybuffer.in.dataview");
+ }
+
+- final NativeArrayBuffer arrBuf = (NativeArrayBuffer) args[0];
++ final NativeArrayBuffer arrBuf = (NativeArrayBuffer)args[0];
+ switch (args.length) {
+- case 1:
+- return new NativeDataView(arrBuf);
+- case 2:
+- return new NativeDataView(arrBuf, JSType.toInt32(args[1]));
+- default:
+- return new NativeDataView(arrBuf, JSType.toInt32(args[1]), JSType.toInt32(args[2]));
++ case 1:
++ return new NativeDataView(arrBuf);
++ case 2:
++ return new NativeDataView(arrBuf, JSType.toInt32(args[1]));
++ default:
++ return new NativeDataView(arrBuf, JSType.toInt32(args[1]), JSType.toInt32(args[2]));
+ }
+ }
+
+@@ -156,7 +155,7 @@
+ * @param offset offset in bytes from the start of the ArrayBuffer
+ * @return newly constructed DataView object
+ */
+- @SpecializedConstructor
++ @SpecializedFunction(isConstructor=true)
+ public static NativeDataView constructor(final boolean newObj, final Object self, final Object arrBuf, final int offset) {
+ if (!(arrBuf instanceof NativeArrayBuffer)) {
+ throw typeError("not.an.arraybuffer.in.dataview");
+@@ -174,7 +173,7 @@
+ * @param length is the number of bytes from the offset that this DataView will reference
+ * @return newly constructed DataView object
+ */
+- @SpecializedConstructor
++ @SpecializedFunction(isConstructor=true)
+ public static NativeDataView constructor(final boolean newObj, final Object self, final Object arrBuf, final int offset, final int length) {
+ if (!(arrBuf instanceof NativeArrayBuffer)) {
+ throw typeError("not.an.arraybuffer.in.dataview");
+@@ -204,8 +203,8 @@
+ public static int getInt8(final Object self, final Object byteOffset) {
+ try {
+ return getBuffer(self).get(JSType.toInt32(byteOffset));
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -220,8 +219,8 @@
+ public static int getInt8(final Object self, final int byteOffset) {
+ try {
+ return getBuffer(self).get(byteOffset);
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -235,9 +234,9 @@
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
+ public static int getUint8(final Object self, final Object byteOffset) {
+ try {
+- return (0xFF & getBuffer(self).get(JSType.toInt32(byteOffset)));
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ return 0xFF & getBuffer(self).get(JSType.toInt32(byteOffset));
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -251,9 +250,9 @@
+ @SpecializedFunction
+ public static int getUint8(final Object self, final int byteOffset) {
+ try {
+- return (0xFF & getBuffer(self).get(byteOffset));
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ return 0xFF & getBuffer(self).get(byteOffset);
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -269,8 +268,8 @@
+ public static int getInt16(final Object self, final Object byteOffset, final Object littleEndian) {
+ try {
+ return getBuffer(self, littleEndian).getShort(JSType.toInt32(byteOffset));
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -285,8 +284,8 @@
+ public static int getInt16(final Object self, final int byteOffset) {
+ try {
+ return getBuffer(self, false).getShort(byteOffset);
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -302,8 +301,8 @@
+ public static int getInt16(final Object self, final int byteOffset, final boolean littleEndian) {
+ try {
+ return getBuffer(self, littleEndian).getShort(byteOffset);
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -318,9 +317,9 @@
+ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+ public static int getUint16(final Object self, final Object byteOffset, final Object littleEndian) {
+ try {
+- return (int) (0xFFFF & getBuffer(self, littleEndian).getShort(JSType.toInt32(byteOffset)));
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ return 0xFFFF & getBuffer(self, littleEndian).getShort(JSType.toInt32(byteOffset));
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -334,9 +333,9 @@
+ @SpecializedFunction
+ public static int getUint16(final Object self, final int byteOffset) {
+ try {
+- return (int) (0xFFFF & getBuffer(self, false).getShort(byteOffset));
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ return 0xFFFF & getBuffer(self, false).getShort(byteOffset);
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -351,9 +350,9 @@
+ @SpecializedFunction
+ public static int getUint16(final Object self, final int byteOffset, final boolean littleEndian) {
+ try {
+- return (int) (0xFFFF & getBuffer(self, littleEndian).getShort(byteOffset));
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ return 0xFFFF & getBuffer(self, littleEndian).getShort(byteOffset);
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -369,8 +368,8 @@
+ public static int getInt32(final Object self, final Object byteOffset, final Object littleEndian) {
+ try {
+ return getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset));
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -385,8 +384,8 @@
+ public static int getInt32(final Object self, final int byteOffset) {
+ try {
+ return getBuffer(self, false).getInt(byteOffset);
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -402,8 +401,8 @@
+ public static int getInt32(final Object self, final int byteOffset, final boolean littleEndian) {
+ try {
+ return getBuffer(self, littleEndian).getInt(byteOffset);
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -418,9 +417,9 @@
+ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+ public static long getUint32(final Object self, final Object byteOffset, final Object littleEndian) {
+ try {
+- return (long) (0xFFFFFFFFL & getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset)));
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ return 0xFFFFFFFFL & getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset));
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -434,9 +433,9 @@
+ @SpecializedFunction
+ public static long getUint32(final Object self, final int byteOffset) {
+ try {
+- return (long) (0xFFFFFFFFL & getBuffer(self, false).getInt(JSType.toInt32(byteOffset)));
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ return JSType.toUint32(getBuffer(self, false).getInt(JSType.toInt32(byteOffset)));
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -451,9 +450,9 @@
+ @SpecializedFunction
+ public static long getUint32(final Object self, final int byteOffset, final boolean littleEndian) {
+ try {
+- return (long) (0xFFFFFFFFL & getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset)));
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ return JSType.toUint32(getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset)));
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -469,8 +468,8 @@
+ public static double getFloat32(final Object self, final Object byteOffset, final Object littleEndian) {
+ try {
+ return getBuffer(self, littleEndian).getFloat(JSType.toInt32(byteOffset));
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -485,8 +484,8 @@
+ public static double getFloat32(final Object self, final int byteOffset) {
+ try {
+ return getBuffer(self, false).getFloat(byteOffset);
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -502,8 +501,8 @@
+ public static double getFloat32(final Object self, final int byteOffset, final boolean littleEndian) {
+ try {
+ return getBuffer(self, littleEndian).getFloat(byteOffset);
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -519,8 +518,8 @@
+ public static double getFloat64(final Object self, final Object byteOffset, final Object littleEndian) {
+ try {
+ return getBuffer(self, littleEndian).getDouble(JSType.toInt32(byteOffset));
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -535,8 +534,8 @@
+ public static double getFloat64(final Object self, final int byteOffset) {
+ try {
+ return getBuffer(self, false).getDouble(byteOffset);
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -552,8 +551,8 @@
+ public static double getFloat64(final Object self, final int byteOffset, final boolean littleEndian) {
+ try {
+ return getBuffer(self, littleEndian).getDouble(byteOffset);
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -582,8 +581,8 @@
+ try {
+ getBuffer(self).put(JSType.toInt32(byteOffset), (byte)JSType.toInt32(value));
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -600,8 +599,8 @@
+ try {
+ getBuffer(self).put(byteOffset, (byte)value);
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -618,8 +617,8 @@
+ try {
+ getBuffer(self).put(JSType.toInt32(byteOffset), (byte)JSType.toInt32(value));
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -636,8 +635,8 @@
+ try {
+ getBuffer(self).put(byteOffset, (byte)value);
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -655,8 +654,8 @@
+ try {
+ getBuffer(self, littleEndian).putShort(JSType.toInt32(byteOffset), (short)JSType.toInt32(value));
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -673,8 +672,8 @@
+ try {
+ getBuffer(self, false).putShort(byteOffset, (short)value);
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -692,8 +691,8 @@
+ try {
+ getBuffer(self, littleEndian).putShort(byteOffset, (short)value);
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -711,8 +710,8 @@
+ try {
+ getBuffer(self, littleEndian).putShort(JSType.toInt32(byteOffset), (short)JSType.toInt32(value));
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -729,8 +728,8 @@
+ try {
+ getBuffer(self, false).putShort(byteOffset, (short)value);
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -748,8 +747,8 @@
+ try {
+ getBuffer(self, littleEndian).putShort(byteOffset, (short)value);
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -765,10 +764,10 @@
+ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+ public static Object setInt32(final Object self, final Object byteOffset, final Object value, final Object littleEndian) {
+ try {
+- getBuffer(self, littleEndian).putInt(JSType.toInt32(byteOffset), (int)JSType.toInt32(value));
++ getBuffer(self, littleEndian).putInt(JSType.toInt32(byteOffset), JSType.toInt32(value));
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -785,8 +784,8 @@
+ try {
+ getBuffer(self, false).putInt(byteOffset, value);
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -804,8 +803,8 @@
+ try {
+ getBuffer(self, littleEndian).putInt(byteOffset, value);
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -823,8 +822,8 @@
+ try {
+ getBuffer(self, littleEndian).putInt(JSType.toInt32(byteOffset), (int)JSType.toUint32(value));
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -841,8 +840,8 @@
+ try {
+ getBuffer(self, false).putInt(byteOffset, (int)value);
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -860,8 +859,8 @@
+ try {
+ getBuffer(self, littleEndian).putInt(byteOffset, (int)value);
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -879,8 +878,8 @@
+ try {
+ getBuffer(self, littleEndian).putFloat((int)JSType.toUint32(byteOffset), (float)JSType.toNumber(value));
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -897,8 +896,8 @@
+ try {
+ getBuffer(self, false).putFloat(byteOffset, (float)value);
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -916,8 +915,8 @@
+ try {
+ getBuffer(self, littleEndian).putFloat(byteOffset, (float)value);
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -935,8 +934,8 @@
+ try {
+ getBuffer(self, littleEndian).putDouble((int)JSType.toUint32(byteOffset), JSType.toNumber(value));
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -953,8 +952,8 @@
+ try {
+ getBuffer(self, false).putDouble(byteOffset, value);
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -972,8 +971,8 @@
+ try {
+ getBuffer(self, littleEndian).putDouble(byteOffset, value);
+ return UNDEFINED;
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.offset");
+ }
+ }
+
+@@ -981,22 +980,22 @@
+ private static ByteBuffer bufferFrom(final NativeArrayBuffer nab, final int offset) {
+ try {
+ return nab.getBuffer(offset);
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.constructor.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.constructor.offset");
+ }
+ }
+
+ private static ByteBuffer bufferFrom(final NativeArrayBuffer nab, final int offset, final int length) {
+ try {
+ return nab.getBuffer(offset, length);
+- } catch (final IndexOutOfBoundsException ioe) {
+- throw rangeError(ioe, "dataview.constructor.offset");
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "dataview.constructor.offset");
+ }
+ }
+
+ private static NativeDataView checkSelf(final Object self) {
+ if (!(self instanceof NativeDataView)) {
+- throw typeError("not.an.arraybuffer", ScriptRuntime.safeToString(self));
++ throw typeError("not.an.arraybuffer.in.dataview", ScriptRuntime.safeToString(self));
+ }
+ return (NativeDataView)self;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeDate.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeDate.java Wed Feb 04 12:14:47 2015 -0800
+@@ -30,7 +30,6 @@
+ import static java.lang.Double.isNaN;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+-
+ import java.util.Locale;
+ import java.util.TimeZone;
+ import java.util.concurrent.Callable;
+@@ -38,7 +37,7 @@
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+ import jdk.nashorn.internal.objects.annotations.Function;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+-import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
++import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
+ import jdk.nashorn.internal.objects.annotations.Where;
+ import jdk.nashorn.internal.parser.DateParser;
+ import jdk.nashorn.internal.runtime.ConsString;
+@@ -155,7 +154,7 @@
+ * @param self self references
+ * @return Date representing now
+ */
+- @SpecializedConstructor
++ @SpecializedFunction(isConstructor=true)
+ public static Object construct(final boolean isNew, final Object self) {
+ final NativeDate result = new NativeDate();
+ return isNew ? result : toStringImpl(result, FORMAT_DATE_TIME);
+@@ -909,6 +908,7 @@
+ sb.append(n);
+ }
+
++ @SuppressWarnings("fallthrough")
+ private static String toStringImpl(final Object self, final int format) {
+ final NativeDate nd = getNativeDate(self);
+
+@@ -934,7 +934,6 @@
+ }
+ sb.append(' ');
+
+- //$FALL-THROUGH$
+ case FORMAT_TIME:
+ final TimeZone tz = nd.getTimeZone();
+ final double utcTime = nd.getTime();
+@@ -1046,7 +1045,8 @@
+
+ // ECMA 15.9.1.2 TimeWithinDay (t)
+ private static double timeWithinDay(final double t) {
+- return t % msPerDay;
++ final double val = t % msPerDay;
++ return val < 0? val + msPerDay : val;
+ }
+
+ // ECMA 15.9.1.3 InLeapYear (t)
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,19 +26,23 @@
+ package jdk.nashorn.internal.objects;
+
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+-
+ import java.io.PrintWriter;
++import java.util.LinkedList;
+ import java.util.Objects;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Function;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+ import jdk.nashorn.internal.objects.annotations.Where;
+ import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.PropertyListeners;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptObject;
++import jdk.nashorn.internal.runtime.ScriptRuntime;
++import jdk.nashorn.internal.runtime.events.RuntimeEvent;
+ import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
++import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+
+ /**
+ * Nashorn specific debug utils. This is meant for Nashorn developers.
+@@ -63,6 +67,36 @@
+ }
+
+ /**
++ * Return the ArrayData class for this ScriptObject
++ * @param self self
++ * @param obj script object to check
++ * @return ArrayData class, or undefined if no ArrayData is present
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static Object getArrayDataClass(final Object self, final Object obj) {
++ try {
++ return ((ScriptObject)obj).getArray().getClass();
++ } catch (final ClassCastException e) {
++ return ScriptRuntime.UNDEFINED;
++ }
++ }
++
++ /**
++ * Return the ArrayData for this ScriptObject
++ * @param self self
++ * @param obj script object to check
++ * @return ArrayData, ArrayDatas have toString methods, return Undefined if data missing
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static Object getArrayData(final Object self, final Object obj) {
++ try {
++ return ((ScriptObject)obj).getArray();
++ } catch (final ClassCastException e) {
++ return ScriptRuntime.UNDEFINED;
++ }
++ }
++
++ /**
+ * Nashorn extension: get context, context utility
+ *
+ * @param self self reference
+@@ -93,21 +127,6 @@
+ }
+
+ /**
+- * Nashorn extension: get spill vector from {@link ScriptObject}
+- *
+- * @param self self reference
+- * @param obj script object
+- * @return the spill vector for the given ScriptObject
+- */
+- @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+- public static Object spill(final Object self, final Object obj) {
+- if (obj instanceof ScriptObject) {
+- return ((ScriptObject)obj).spill;
+- }
+- return UNDEFINED;
+- }
+-
+- /**
+ * Check object identity comparison regardless of type
+ *
+ * @param self self reference
+@@ -121,6 +140,31 @@
+ }
+
+ /**
++ * Returns true if if the two objects are both property maps, and they have identical properties in the same order,
++ * but allows the properties to differ in their types.
++ * @param self self
++ * @param m1 first property map
++ * @param m2 second property map
++ * @return true if they have identical properties in same order, with possibly different types.
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static Object equalWithoutType(final Object self, final Object m1, final Object m2) {
++ return ((PropertyMap)m1).equalsWithoutType((PropertyMap)m2);
++ }
++
++ /**
++ * Returns a diagnostic string representing the difference of two property maps.
++ * @param self self
++ * @param m1 first property map
++ * @param m2 second property map
++ * @return a diagnostic string representing the difference of two property maps.
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static Object diffPropertyMaps(final Object self, final Object m1, final Object m2) {
++ return PropertyMap.diff((PropertyMap)m1, (PropertyMap)m2);
++ }
++
++ /**
+ * Object util - getClass
+ *
+ * @param self self reference
+@@ -196,7 +240,6 @@
+ * @param self self reference
+ * @return undefined
+ */
+- @SuppressWarnings("resource")
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+ public static Object dumpCounters(final Object self) {
+ final PrintWriter out = Context.getCurrentErr();
+@@ -210,7 +253,6 @@
+ out.println("ScriptFunction allocations " + ScriptFunction.getAllocations());
+ out.println("PropertyMap count " + PropertyMap.getCount());
+ out.println("PropertyMap cloned " + PropertyMap.getClonedCount());
+- out.println("PropertyMap duplicated " + PropertyMap.getDuplicatedCount());
+ out.println("PropertyMap history hit " + PropertyMap.getHistoryHit());
+ out.println("PropertyMap proto invalidations " + PropertyMap.getProtoInvalidations());
+ out.println("PropertyMap proto history hit " + PropertyMap.getProtoHistoryHit());
+@@ -223,4 +265,133 @@
+
+ return UNDEFINED;
+ }
++
++ /*
++ * Framework for logging runtime events
++ */
++
++ private static final String EVENT_QUEUE = "__eventQueue__";
++ private static final String EVENT_QUEUE_CAPACITY = "__eventQueueCapacity__";
++
++ /**
++ * Get the capacity of the event queue
++ * @param self self reference
++ * @return capacity of event queue as an integer
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static Object getEventQueueCapacity(final Object self) {
++ final ScriptObject sobj = (ScriptObject)self;
++ Integer cap;
++ if (sobj.has(EVENT_QUEUE_CAPACITY)) {
++ cap = JSType.toInt32(sobj.get(EVENT_QUEUE_CAPACITY));
++ } else {
++ setEventQueueCapacity(self, cap = RuntimeEvent.RUNTIME_EVENT_QUEUE_SIZE);
++ }
++ return cap;
++ }
++
++ /**
++ * Set the event queue capacity
++ * @param self an event queue
++ * @param newCapacity new capacity
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static void setEventQueueCapacity(final Object self, final Object newCapacity) {
++ ((ScriptObject)self).set(EVENT_QUEUE_CAPACITY, newCapacity, NashornCallSiteDescriptor.CALLSITE_STRICT);
++ }
++
++ /**
++ * Add a runtime event to the runtime event queue. The queue has a fixed
++ * size {@link RuntimeEvent#RUNTIME_EVENT_QUEUE_SIZE} and the oldest
++ * entry will be thrown out of the queue is about to overflow
++ * @param self self reference
++ * @param event event to add
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static void addRuntimeEvent(final Object self, final Object event) {
++ final LinkedList<RuntimeEvent<?>> q = getEventQueue(self);
++ final int cap = (Integer)getEventQueueCapacity(self);
++ while (q.size() >= cap) {
++ q.removeFirst();
++ }
++ q.addLast(getEvent(event));
++ }
++
++ /**
++ * Expands the event queue capacity, or truncates if capacity is lower than
++ * current capacity. Then only the newest entries are kept
++ * @param self self reference
++ * @param newCapacity new capacity
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static void expandEventQueueCapacity(final Object self, final Object newCapacity) {
++ final LinkedList<RuntimeEvent<?>> q = getEventQueue(self);
++ final int nc = JSType.toInt32(newCapacity);
++ while (q.size() > nc) {
++ q.removeFirst();
++ }
++ setEventQueueCapacity(self, nc);
++ }
++
++ /**
++ * Clear the runtime event queue
++ * @param self self reference
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static void clearRuntimeEvents(final Object self) {
++ final LinkedList<RuntimeEvent<?>> q = getEventQueue(self);
++ q.clear();
++ }
++
++ /**
++ * Remove a specific runtime event from the event queue
++ * @param self self reference
++ * @param event event to remove
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static void removeRuntimeEvent(final Object self, final Object event) {
++ final LinkedList<RuntimeEvent<?>> q = getEventQueue(self);
++ final RuntimeEvent<?> re = getEvent(event);
++ if (!q.remove(re)) {
++ throw new IllegalStateException("runtime event " + re + " was not in event queue");
++ }
++ }
++
++ /**
++ * Return all runtime events in the queue as an array
++ * @param self self reference
++ * @return array of events
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static Object getRuntimeEvents(final Object self) {
++ final LinkedList<RuntimeEvent<?>> q = getEventQueue(self);
++ return q.toArray(new RuntimeEvent<?>[q.size()]);
++ }
++
++ /**
++ * Return the last runtime event in the queue
++ * @param self self reference
++ * @return the freshest event, null if queue is empty
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static Object getLastRuntimeEvent(final Object self) {
++ final LinkedList<RuntimeEvent<?>> q = getEventQueue(self);
++ return q.isEmpty() ? null : q.getLast();
++ }
++
++ @SuppressWarnings("unchecked")
++ private static LinkedList<RuntimeEvent<?>> getEventQueue(final Object self) {
++ final ScriptObject sobj = (ScriptObject)self;
++ LinkedList<RuntimeEvent<?>> q;
++ if (sobj.has(EVENT_QUEUE)) {
++ q = (LinkedList<RuntimeEvent<?>>)((ScriptObject)self).get(EVENT_QUEUE);
++ } else {
++ ((ScriptObject)self).set(EVENT_QUEUE, q = new LinkedList<>(), NashornCallSiteDescriptor.CALLSITE_STRICT);
++ }
++ return q;
++ }
++
++ private static RuntimeEvent<?> getEvent(final Object event) {
++ return (RuntimeEvent<?>)event;
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeError.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeError.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,12 +25,11 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.lookup.Lookup.MH;
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+-import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+-
+ import jdk.nashorn.api.scripting.NashornException;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+@@ -41,8 +40,8 @@
+ import jdk.nashorn.internal.runtime.ECMAException;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.PropertyMap;
++import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+-import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+ /**
+@@ -147,8 +146,7 @@
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+ public static Object captureStackTrace(final Object self, final Object errorObj) {
+- Global.checkObject(errorObj);
+- final ScriptObject sobj = (ScriptObject)errorObj;
++ final ScriptObject sobj = Global.checkObject(errorObj);
+ initException(sobj);
+ sobj.delete(STACK, false);
+ if (! sobj.has("stack")) {
+@@ -184,8 +182,7 @@
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
+ public static Object printStackTrace(final Object self) {
+- Global.checkObject(self);
+- return ECMAException.printStackTrace((ScriptObject)self);
++ return ECMAException.printStackTrace(Global.checkObject(self));
+ }
+
+ /**
+@@ -199,8 +196,7 @@
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
+ public static Object getStackTrace(final Object self) {
+- Global.checkObject(self);
+- final ScriptObject sobj = (ScriptObject)self;
++ final ScriptObject sobj = Global.checkObject(self);
+ final Object exception = ECMAException.getException(sobj);
+ Object[] res;
+ if (exception instanceof Throwable) {
+@@ -220,8 +216,7 @@
+ * @return line number from which error was thrown
+ */
+ public static Object getLineNumber(final Object self) {
+- Global.checkObject(self);
+- final ScriptObject sobj = (ScriptObject)self;
++ final ScriptObject sobj = Global.checkObject(self);
+ return sobj.has(LINENUMBER) ? sobj.get(LINENUMBER) : ECMAException.getLineNumber(sobj);
+ }
+
+@@ -234,8 +229,7 @@
+ * @return value that was set
+ */
+ public static Object setLineNumber(final Object self, final Object value) {
+- Global.checkObject(self);
+- final ScriptObject sobj = (ScriptObject)self;
++ final ScriptObject sobj = Global.checkObject(self);
+ if (sobj.hasOwnProperty(LINENUMBER)) {
+ sobj.put(LINENUMBER, value, false);
+ } else {
+@@ -252,8 +246,7 @@
+ * @return column number from which error was thrown
+ */
+ public static Object getColumnNumber(final Object self) {
+- Global.checkObject(self);
+- final ScriptObject sobj = (ScriptObject)self;
++ final ScriptObject sobj = Global.checkObject(self);
+ return sobj.has(COLUMNNUMBER) ? sobj.get(COLUMNNUMBER) : ECMAException.getColumnNumber((ScriptObject)self);
+ }
+
+@@ -266,8 +259,7 @@
+ * @return value that was set
+ */
+ public static Object setColumnNumber(final Object self, final Object value) {
+- Global.checkObject(self);
+- final ScriptObject sobj = (ScriptObject)self;
++ final ScriptObject sobj = Global.checkObject(self);
+ if (sobj.hasOwnProperty(COLUMNNUMBER)) {
+ sobj.put(COLUMNNUMBER, value, false);
+ } else {
+@@ -284,8 +276,7 @@
+ * @return file name from which error was thrown
+ */
+ public static Object getFileName(final Object self) {
+- Global.checkObject(self);
+- final ScriptObject sobj = (ScriptObject)self;
++ final ScriptObject sobj = Global.checkObject(self);
+ return sobj.has(FILENAME) ? sobj.get(FILENAME) : ECMAException.getFileName((ScriptObject)self);
+ }
+
+@@ -298,8 +289,7 @@
+ * @return value that was set
+ */
+ public static Object setFileName(final Object self, final Object value) {
+- Global.checkObject(self);
+- final ScriptObject sobj = (ScriptObject)self;
++ final ScriptObject sobj = Global.checkObject(self);
+ if (sobj.hasOwnProperty(FILENAME)) {
+ sobj.put(FILENAME, value, false);
+ } else {
+@@ -318,15 +308,14 @@
+ * @return value of "stack" property
+ */
+ public static Object getStack(final Object self) {
+- Global.checkObject(self);
+- final ScriptObject sobj = (ScriptObject)self;
++ final ScriptObject sobj = Global.checkObject(self);
+ if (sobj.has(STACK)) {
+ return sobj.get(STACK);
+ }
+
+ final Object exception = ECMAException.getException(sobj);
+ if (exception instanceof Throwable) {
+- Object value = getScriptStackString(sobj, (Throwable)exception);
++ final Object value = getScriptStackString(sobj, (Throwable)exception);
+ if (sobj.hasOwnProperty(STACK)) {
+ sobj.put(STACK, value, false);
+ } else {
+@@ -349,14 +338,12 @@
+ * @return value that was set
+ */
+ public static Object setStack(final Object self, final Object value) {
+- Global.checkObject(self);
+- final ScriptObject sobj = (ScriptObject)self;
++ final ScriptObject sobj = Global.checkObject(self);
+ if (sobj.hasOwnProperty(STACK)) {
+ sobj.put(STACK, value, false);
+ } else {
+ sobj.addOwnProperty(STACK, Attribute.NOT_ENUMERABLE, value);
+ }
+-
+ return value;
+ }
+
+@@ -370,9 +357,7 @@
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
+ public static Object toString(final Object self) {
+ // Step 1 and 2 : check if 'self' is object it not throw TypeError
+- Global.checkObject(self);
+-
+- final ScriptObject sobj = (ScriptObject)self;
++ final ScriptObject sobj = Global.checkObject(self);
+
+ // Step 3 & 4 : get "name" and convert to String.
+ // But if message is undefined make it "Error".
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,12 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
++
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.nio.ByteBuffer;
++import java.nio.FloatBuffer;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+ import jdk.nashorn.internal.objects.annotations.Function;
+@@ -35,6 +41,7 @@
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
++import jdk.nashorn.internal.runtime.arrays.TypedArrayData;
+
+ /**
+ * Float32 array for the TypedArray extension
+@@ -56,73 +63,118 @@
+ public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+ return new NativeFloat32Array(buffer, byteOffset, length);
+ }
++
+ @Override
+- public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+- return new Float32ArrayData(buffer, byteOffset, length);
++ public Float32ArrayData createArrayData(final ByteBuffer nb, final int start, final int end) {
++ return new Float32ArrayData(nb.asFloatBuffer(), start, end);
++ }
++
++ @Override
++ public String getClassName() {
++ return "Float32Array";
+ }
+ };
+
+- private static final class Float32ArrayData extends ArrayDataImpl {
+- private Float32ArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+- super(buffer, byteOffset, elementLength);
++ private static final class Float32ArrayData extends TypedArrayData<FloatBuffer> {
++
++ private static final MethodHandle GET_ELEM = specialCall(MethodHandles.lookup(), Float32ArrayData.class, "getElem", double.class, int.class).methodHandle();
++ private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Float32ArrayData.class, "setElem", void.class, int.class, double.class).methodHandle();
++
++ private Float32ArrayData(final FloatBuffer nb, final int start, final int end) {
++ super(((FloatBuffer)nb.position(start).limit(end)).slice(), end - start);
+ }
+
+ @Override
+- protected int byteIndex(final int index) {
+- return index * BYTES_PER_ELEMENT + byteOffset;
++ public Class<?> getElementType() {
++ return double.class;
+ }
+
+ @Override
+- protected double getDoubleImpl(final int index) {
+- final int byteIndex = byteIndex(index);
+- final byte[] byteArray = buffer.getByteArray();
+- final int bits = byteArray[byteIndex ] & 0x0000_00ff |
+- byteArray[byteIndex+1] << 8 & 0x0000_ff00 |
+- byteArray[byteIndex+2] << 16 & 0x00ff_0000 |
+- byteArray[byteIndex+3] << 24 & 0xff00_0000 ;
+- return Float.intBitsToFloat(bits);
++ public Class<?> getBoxedElementType() {
++ return Double.class;
+ }
+
+ @Override
+- protected int getIntImpl(final int index) {
+- return (int)getDoubleImpl(index);
++ protected MethodHandle getGetElem() {
++ return GET_ELEM;
+ }
+
+ @Override
+- protected long getLongImpl(final int key) {
+- return (long)getDoubleImpl(key);
++ protected MethodHandle getSetElem() {
++ return SET_ELEM;
++ }
++
++ private double getElem(final int index) {
++ try {
++ return nb.get(index);
++ } catch (final IndexOutOfBoundsException e) {
++ throw new ClassCastException(); //force relink - this works for unoptimistic too
++ }
++ }
++
++ private void setElem(final int index, final double elem) {
++ try {
++ nb.put(index, (float)elem);
++ } catch (final IndexOutOfBoundsException e) {
++ //swallow valid array indexes. it's ok.
++ if (index < 0) {
++ throw new ClassCastException();
++ }
++ }
+ }
+
+ @Override
+- protected Object getObjectImpl(final int key) {
+- return getDoubleImpl(key);
++ public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
++ if (returnType == int.class || returnType == long.class) {
++ return null;
++ }
++ return getContinuousElementGetter(getClass(), GET_ELEM, returnType, programPoint);
+ }
+
+ @Override
+- protected void setImpl(final int index, final double value) {
+- final int bits = Float.floatToRawIntBits((float)value);
+- final int byteIndex = byteIndex(index);
+- @SuppressWarnings("MismatchedReadAndWriteOfArray")
+- final byte[] byteArray = buffer.getByteArray();
+- byteArray[byteIndex ] = (byte)(bits & 0xff);
+- byteArray[byteIndex+1] = (byte)(bits >>> 8 & 0xff);
+- byteArray[byteIndex+2] = (byte)(bits >>> 16 & 0xff);
+- byteArray[byteIndex+3] = (byte)(bits >>> 24 & 0xff);
++ public int getInt(final int index) {
++ return (int)getDouble(index);
+ }
+
+ @Override
+- protected void setImpl(final int key, final int value) {
+- setImpl(key, (double)value);
++ public long getLong(final int index) {
++ return (long)getDouble(index);
+ }
+
+ @Override
+- protected void setImpl(final int key, final long value) {
+- setImpl(key, (double)value);
++ public double getDouble(final int index) {
++ return getElem(index);
+ }
+
+ @Override
+- protected void setImpl(final int key, final Object value) {
+- setImpl(key, JSType.toNumber(value));
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public Object getObject(final int index) {
++ return getDouble(index);
++ }
++
++ @Override
++ public ArrayData set(final int index, final Object value, final boolean strict) {
++ return set(index, JSType.toNumber(value), strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final int value, final boolean strict) {
++ return set(index, (double)value, strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final long value, final boolean strict) {
++ return set(index, (double)value, strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final double value, final boolean strict) {
++ setElem(index, value);
++ return this;
+ }
+ }
+
+@@ -137,7 +189,7 @@
+ */
+ @Constructor(arity = 1)
+ public static NativeFloat32Array constructor(final boolean newObj, final Object self, final Object... args) {
+- return (NativeFloat32Array)constructorImpl(args, FACTORY);
++ return (NativeFloat32Array)constructorImpl(newObj, args, FACTORY);
+ }
+
+ NativeFloat32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+@@ -145,11 +197,6 @@
+ }
+
+ @Override
+- public String getClassName() {
+- return "Float32Array";
+- }
+-
+- @Override
+ protected Factory factory() {
+ return FACTORY;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,12 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
++
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.nio.ByteBuffer;
++import java.nio.DoubleBuffer;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+ import jdk.nashorn.internal.objects.annotations.Function;
+@@ -35,6 +41,7 @@
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
++import jdk.nashorn.internal.runtime.arrays.TypedArrayData;
+
+ /**
+ * Float64 array for the TypedArray extension
+@@ -56,83 +63,118 @@
+ public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+ return new NativeFloat64Array(buffer, byteOffset, length);
+ }
++
+ @Override
+- public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+- return new Float64ArrayData(buffer, byteOffset, length);
++ public Float64ArrayData createArrayData(final ByteBuffer nb, final int start, final int length) {
++ return new Float64ArrayData(nb.asDoubleBuffer(), start, length);
++ }
++
++ @Override
++ public String getClassName() {
++ return "Float64Array";
+ }
+ };
+
+- private static final class Float64ArrayData extends ArrayDataImpl {
+- private Float64ArrayData(final NativeArrayBuffer buffer,
+- final int byteOffset, final int elementLength) {
+- super(buffer, byteOffset, elementLength);
++ private static final class Float64ArrayData extends TypedArrayData<DoubleBuffer> {
++
++ private static final MethodHandle GET_ELEM = specialCall(MethodHandles.lookup(), Float64ArrayData.class, "getElem", double.class, int.class).methodHandle();
++ private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Float64ArrayData.class, "setElem", void.class, int.class, double.class).methodHandle();
++
++ private Float64ArrayData(final DoubleBuffer nb, final int start, final int end) {
++ super(((DoubleBuffer)nb.position(start).limit(end)).slice(), end - start);
+ }
+
+ @Override
+- protected int byteIndex(final int index) {
+- return index * BYTES_PER_ELEMENT + byteOffset;
++ protected MethodHandle getGetElem() {
++ return GET_ELEM;
+ }
+
+ @Override
+- protected double getDoubleImpl(final int index) {
+- final int byteIndex = byteIndex(index);
+- final byte[] byteArray = buffer.getByteArray();
+- final long bits;
+- bits = byteArray[byteIndex ] & 0x0000_0000_0000_00ffL |
+- (long)byteArray[byteIndex+1] << 8 & 0x0000_0000_0000_ff00L |
+- (long)byteArray[byteIndex+2] << 16 & 0x0000_0000_00ff_0000L |
+- (long)byteArray[byteIndex+3] << 24 & 0x0000_0000_ff00_0000L |
+- (long)byteArray[byteIndex+4] << 32 & 0x0000_00ff_0000_0000L |
+- (long)byteArray[byteIndex+5] << 40 & 0x0000_ff00_0000_0000L |
+- (long)byteArray[byteIndex+6] << 48 & 0x00ff_0000_0000_0000L |
+- (long)byteArray[byteIndex+7] << 56 & 0xff00_0000_0000_0000L ;
+- return Double.longBitsToDouble(bits);
++ protected MethodHandle getSetElem() {
++ return SET_ELEM;
+ }
+
+ @Override
+- protected int getIntImpl(final int index) {
+- return (int)getDoubleImpl(index);
++ public Class<?> getElementType() {
++ return double.class;
+ }
+
+ @Override
+- protected long getLongImpl(final int key) {
+- return (long)getDoubleImpl(key);
++ public Class<?> getBoxedElementType() {
++ return Double.class;
++ }
++
++ private double getElem(final int index) {
++ try {
++ return nb.get(index);
++ } catch (final IndexOutOfBoundsException e) {
++ throw new ClassCastException(); //force relink - this works for unoptimistic too
++ }
++ }
++
++ private void setElem(final int index, final double elem) {
++ try {
++ nb.put(index, elem);
++ } catch (final IndexOutOfBoundsException e) {
++ //swallow valid array indexes. it's ok.
++ if (index < 0) {
++ throw new ClassCastException();
++ }
++ }
+ }
+
+ @Override
+- protected Object getObjectImpl(final int key) {
+- return getDoubleImpl(key);
++ public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
++ if (returnType == int.class || returnType == long.class) {
++ return null;
++ }
++ return getContinuousElementGetter(getClass(), GET_ELEM, returnType, programPoint);
+ }
+
+ @Override
+- protected void setImpl(final int index, final double value) {
+- final long bits = Double.doubleToRawLongBits(value);
+- final int byteIndex = byteIndex(index);
+- @SuppressWarnings("MismatchedReadAndWriteOfArray")
+- final byte[] byteArray = buffer.getByteArray();
+- byteArray[byteIndex ] = (byte)(bits & 0xff);
+- byteArray[byteIndex+1] = (byte)(bits >>> 8 & 0xff);
+- byteArray[byteIndex+2] = (byte)(bits >>> 16 & 0xff);
+- byteArray[byteIndex+3] = (byte)(bits >>> 24 & 0xff);
+- byteArray[byteIndex+4] = (byte)(bits >>> 32 & 0xff);
+- byteArray[byteIndex+5] = (byte)(bits >>> 40 & 0xff);
+- byteArray[byteIndex+6] = (byte)(bits >>> 48 & 0xff);
+- byteArray[byteIndex+7] = (byte)(bits >>> 56 & 0xff);
++ public int getInt(final int index) {
++ return (int)getDouble(index);
+ }
+
+ @Override
+- protected void setImpl(final int key, final int value) {
+- setImpl(key, (double)value);
++ public long getLong(final int index) {
++ return (long)getDouble(index);
+ }
+
+ @Override
+- protected void setImpl(final int key, final long value) {
+- setImpl(key, (double)value);
++ public double getDouble(final int index) {
++ return getElem(index);
+ }
+
+ @Override
+- protected void setImpl(final int key, final Object value) {
+- setImpl(key, JSType.toNumber(value));
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public Object getObject(final int index) {
++ return getDouble(index);
++ }
++
++ @Override
++ public ArrayData set(final int index, final Object value, final boolean strict) {
++ return set(index, JSType.toNumber(value), strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final int value, final boolean strict) {
++ return set(index, (double)value, strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final long value, final boolean strict) {
++ return set(index, (double)value, strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final double value, final boolean strict) {
++ setElem(index, value);
++ return this;
+ }
+ }
+
+@@ -147,7 +189,7 @@
+ */
+ @Constructor(arity = 1)
+ public static NativeFloat64Array constructor(final boolean newObj, final Object self, final Object... args) {
+- return (NativeFloat64Array)constructorImpl(args, FACTORY);
++ return (NativeFloat64Array)constructorImpl(newObj, args, FACTORY);
+ }
+
+ NativeFloat64Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+@@ -155,11 +197,6 @@
+ }
+
+ @Override
+- public String getClassName() {
+- return "Float64Array";
+- }
+-
+- @Override
+ protected Factory factory() {
+ return FACTORY;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,12 +25,15 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+ import static jdk.nashorn.internal.runtime.Source.sourceFor;
+
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
+ import java.util.List;
+-
++import jdk.internal.dynalink.support.Lookup;
+ import jdk.nashorn.api.scripting.JSObject;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+@@ -41,10 +44,11 @@
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.ParserException;
+ import jdk.nashorn.internal.runtime.PropertyMap;
++import jdk.nashorn.internal.runtime.ScriptEnvironment;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+-import jdk.nashorn.internal.runtime.Source;
++import jdk.nashorn.internal.runtime.linker.Bootstrap;
+
+ /**
+ * ECMA 15.3 Function Objects
+@@ -56,6 +60,9 @@
+ @ScriptClass("Function")
+ public final class NativeFunction {
+
++ /** apply arg converter handle */
++ public static final MethodHandle TO_APPLY_ARGS = Lookup.findOwnStatic(MethodHandles.lookup(), "toApplyArgs", Object[].class, Object.class);
++
+ // initialized by nasgen
+ @SuppressWarnings("unused")
+ private static PropertyMap $nasgenmap$;
+@@ -89,50 +96,75 @@
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
+ public static Object apply(final Object self, final Object thiz, final Object array) {
+- if (!(self instanceof ScriptFunction) && !(self instanceof JSObject)) {
+- throw typeError("not.a.function", ScriptRuntime.safeToString(self));
+- }
++ checkCallable(self);
+
+- Object[] args = null;
+-
+- if (array instanceof ScriptObject) {
+- // look for array-like object
+- final ScriptObject sobj = (ScriptObject)array;
+- final Object len = sobj.getLength();
+- final int n = (int)JSType.toUint32(len);
+-
+- args = new Object[n];
+- for (int i = 0; i < args.length; i++) {
+- args[i] = sobj.get(i);
+- }
+- } else if (array instanceof Object[]) {
+- args = (Object[])array;
+- } else if (array instanceof List) {
+- final List<?> list = (List<?>)array;
+- list.toArray(args = new Object[list.size()]);
+- } else if (array == null || array == UNDEFINED) {
+- args = ScriptRuntime.EMPTY_ARRAY;
+- } else if (array instanceof JSObject) {
+- // look for array-like JSObject object
+- final JSObject jsObj = (JSObject)array;
+- final Object len = jsObj.hasMember("length")? jsObj.getMember("length") : Integer.valueOf(0);
+- final int n = (int)JSType.toUint32(len);
+-
+- args = new Object[n];
+- for (int i = 0; i < args.length; i++) {
+- args[i] = jsObj.hasSlot(i)? jsObj.getSlot(i) : UNDEFINED;
+- }
+- } else {
+- throw typeError("function.apply.expects.array");
+- }
++ final Object[] args = toApplyArgs(array);
+
+ if (self instanceof ScriptFunction) {
+ return ScriptRuntime.apply((ScriptFunction)self, thiz, args);
+ } else if (self instanceof JSObject) {
+ return ((JSObject)self).call(thiz, args);
+ }
++ throw new AssertionError("Should not reach here");
++ }
+
+- throw new AssertionError("should not reach here");
++ /**
++ * Given an array-like object, converts it into a Java object array suitable for invocation of ScriptRuntime.apply
++ * or for direct invocation of the applied function.
++ * @param array the array-like object. Can be null in which case a zero-length array is created.
++ * @return the Java array
++ */
++ public static Object[] toApplyArgs(final Object array) {
++ if (array instanceof NativeArguments) {
++ return ((NativeArguments)array).getArray().asObjectArray();
++ } else if (array instanceof ScriptObject) {
++ // look for array-like object
++ final ScriptObject sobj = (ScriptObject)array;
++ final int n = lengthToInt(sobj.getLength());
++
++ final Object[] args = new Object[n];
++ for (int i = 0; i < args.length; i++) {
++ args[i] = sobj.get(i);
++ }
++ return args;
++ } else if (array instanceof Object[]) {
++ return (Object[])array;
++ } else if (array instanceof List) {
++ final List<?> list = (List<?>)array;
++ return list.toArray(new Object[list.size()]);
++ } else if (array == null || array == UNDEFINED) {
++ return ScriptRuntime.EMPTY_ARRAY;
++ } else if (array instanceof JSObject) {
++ // look for array-like JSObject object
++ final JSObject jsObj = (JSObject)array;
++ final Object len = jsObj.hasMember("length")? jsObj.getMember("length") : Integer.valueOf(0);
++ final int n = lengthToInt(len);
++
++ final Object[] args = new Object[n];
++ for (int i = 0; i < args.length; i++) {
++ args[i] = jsObj.hasSlot(i)? jsObj.getSlot(i) : UNDEFINED;
++ }
++ return args;
++ } else {
++ throw typeError("function.apply.expects.array");
++ }
++ }
++
++ private static int lengthToInt(final Object len) {
++ final long ln = JSType.toUint32(len);
++ // NOTE: ECMASCript 5.1 section 15.3.4.3 says length should be treated as Uint32, but we wouldn't be able to
++ // allocate a Java array of more than MAX_VALUE elements anyway, so at this point we have to throw an error.
++ // People applying a function to more than 2^31 arguments will unfortunately be out of luck.
++ if (ln > Integer.MAX_VALUE) {
++ throw rangeError("range.error.inappropriate.array.length", JSType.toString(len));
++ }
++ return (int)ln;
++ }
++
++ private static void checkCallable(final Object self) {
++ if (!(self instanceof ScriptFunction || (self instanceof JSObject && ((JSObject)self).isFunction()))) {
++ throw typeError("not.a.function", ScriptRuntime.safeToString(self));
++ }
+ }
+
+ /**
+@@ -144,11 +176,9 @@
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+ public static Object call(final Object self, final Object... args) {
+- if (!(self instanceof ScriptFunction) && !(self instanceof JSObject)) {
+- throw typeError("not.a.function", ScriptRuntime.safeToString(self));
+- }
++ checkCallable(self);
+
+- Object thiz = (args.length == 0) ? UNDEFINED : args[0];
++ final Object thiz = (args.length == 0) ? UNDEFINED : args[0];
+ Object[] arguments;
+
+ if (args.length > 1) {
+@@ -175,11 +205,7 @@
+ * @return function with bound arguments
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+- public static ScriptFunction bind(final Object self, final Object... args) {
+- if (!(self instanceof ScriptFunction)) {
+- throw typeError("not.a.function", ScriptRuntime.safeToString(self));
+- }
+-
++ public static Object bind(final Object self, final Object... args) {
+ final Object thiz = (args.length == 0) ? UNDEFINED : args[0];
+
+ Object[] arguments;
+@@ -190,7 +216,7 @@
+ arguments = ScriptRuntime.EMPTY_ARRAY;
+ }
+
+- return ((ScriptFunctionImpl)self).makeBoundFunction(thiz, arguments);
++ return Bootstrap.bindCallable(self, thiz, arguments);
+ }
+
+ /**
+@@ -236,7 +262,7 @@
+ funcBody = JSType.toString(args[args.length - 1]);
+
+ final String paramList = paramListBuf.toString();
+- if (! paramList.isEmpty()) {
++ if (!paramList.isEmpty()) {
+ checkFunctionParameters(paramList);
+ sb.append(paramList);
+ }
+@@ -258,8 +284,7 @@
+ }
+
+ private static void checkFunctionParameters(final String params) {
+- final Source src = sourceFor("<function>", params);
+- final Parser parser = new Parser(Global.getEnv(), src, new Context.ThrowErrorManager());
++ final Parser parser = getParser(params);
+ try {
+ parser.parseFormalParameterList();
+ } catch (final ParserException pe) {
+@@ -268,12 +293,16 @@
+ }
+
+ private static void checkFunctionBody(final String funcBody) {
+- final Source src = sourceFor("<function>", funcBody);
+- final Parser parser = new Parser(Global.getEnv(), src, new Context.ThrowErrorManager());
++ final Parser parser = getParser(funcBody);
+ try {
+ parser.parseFunctionBody();
+ } catch (final ParserException pe) {
+ pe.throwAsEcmaException();
+ }
+ }
++
++ private static Parser getParser(final String sourceText) {
++ final ScriptEnvironment env = Global.getEnv();
++ return new Parser(env, sourceFor("<function>", sourceText), new Context.ThrowErrorManager(), env._strict, null);
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,15 +25,23 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
++
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.nio.ByteBuffer;
++import java.nio.ShortBuffer;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+ import jdk.nashorn.internal.objects.annotations.Function;
+ import jdk.nashorn.internal.objects.annotations.Property;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+ import jdk.nashorn.internal.objects.annotations.Where;
++import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
++import jdk.nashorn.internal.runtime.arrays.TypedArrayData;
+
+ /**
+ * Int16 array for the TypedArray extension
+@@ -56,37 +64,120 @@
+ public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+ return new NativeInt16Array(buffer, byteOffset, length);
+ }
++
+ @Override
+- public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+- return new Int16ArrayData(buffer, byteOffset, length);
++ public Int16ArrayData createArrayData(final ByteBuffer nb, final int start, final int end) {
++ return new Int16ArrayData(nb.asShortBuffer(), start, end);
++ }
++
++ @Override
++ public String getClassName() {
++ return "Int16Array";
+ }
+ };
+
+- private static final class Int16ArrayData extends ArrayDataImpl {
+- private Int16ArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+- super(buffer, byteOffset, elementLength);
++ private static final class Int16ArrayData extends TypedArrayData<ShortBuffer> {
++
++ private static final MethodHandle GET_ELEM = specialCall(MethodHandles.lookup(), Int16ArrayData.class, "getElem", int.class, int.class).methodHandle();
++ private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Int16ArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
++
++ private Int16ArrayData(final ShortBuffer nb, final int start, final int end) {
++ super(((ShortBuffer)nb.position(start).limit(end)).slice(), end - start);
+ }
+
+ @Override
+- protected int byteIndex(final int index) {
+- return index * BYTES_PER_ELEMENT + byteOffset;
++ protected MethodHandle getGetElem() {
++ return GET_ELEM;
+ }
+
+ @Override
+- protected int getIntImpl(final int index) {
+- final int byteIndex = byteIndex(index);
+- final byte[] byteArray = buffer.getByteArray();
+- return byteArray[byteIndex ] & (short)0x00ff |
+- byteArray[byteIndex+1] << 8 & (short)0xff00 ;
++ protected MethodHandle getSetElem() {
++ return SET_ELEM;
+ }
+
+ @Override
+- protected void setImpl(final int index, final int value) {
+- final int byteIndex = byteIndex(index);
+- @SuppressWarnings("MismatchedReadAndWriteOfArray")
+- final byte[] byteArray = buffer.getByteArray();
+- byteArray[byteIndex ] = (byte)(value & 0xff);
+- byteArray[byteIndex+1] = (byte)(value >>> 8 & 0xff);
++ public Class<?> getElementType() {
++ return int.class;
++ }
++
++ @Override
++ public Class<?> getBoxedElementType() {
++ return Integer.class;
++ }
++
++ private int getElem(final int index) {
++ try {
++ return nb.get(index);
++ } catch (final IndexOutOfBoundsException e) {
++ throw new ClassCastException(); //force relink - this works for unoptimistic too
++ }
++ }
++
++ private void setElem(final int index, final int elem) {
++ try {
++ nb.put(index, (short)elem);
++ } catch (final IndexOutOfBoundsException e) {
++ //swallow valid array indexes. it's ok.
++ if (index < 0) {
++ throw new ClassCastException();
++ }
++ }
++ }
++
++ @Override
++ public int getInt(final int index) {
++ return getElem(index);
++ }
++
++ @Override
++ public int getIntOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public long getLong(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public long getLongOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public double getDouble(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public Object getObject(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public ArrayData set(final int index, final Object value, final boolean strict) {
++ return set(index, JSType.toInt32(value), strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final int value, final boolean strict) {
++ setElem(index, value);
++ return this;
++ }
++
++ @Override
++ public ArrayData set(final int index, final long value, final boolean strict) {
++ return set(index, (int)value, strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final double value, final boolean strict) {
++ return set(index, (int)value, strict);
+ }
+ }
+
+@@ -101,7 +192,7 @@
+ */
+ @Constructor(arity = 1)
+ public static NativeInt16Array constructor(final boolean newObj, final Object self, final Object... args) {
+- return (NativeInt16Array)constructorImpl(args, FACTORY);
++ return (NativeInt16Array)constructorImpl(newObj, args, FACTORY);
+ }
+
+ NativeInt16Array(final NativeArrayBuffer buffer, final int byteOffset, final int byteLength) {
+@@ -109,11 +200,6 @@
+ }
+
+ @Override
+- public String getClassName() {
+- return "Int16Array";
+- }
+-
+- @Override
+ protected Factory factory() {
+ return FACTORY;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,15 +25,23 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
++
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.nio.ByteBuffer;
++import java.nio.IntBuffer;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+ import jdk.nashorn.internal.objects.annotations.Function;
+ import jdk.nashorn.internal.objects.annotations.Property;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+ import jdk.nashorn.internal.objects.annotations.Where;
++import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
++import jdk.nashorn.internal.runtime.arrays.TypedArrayData;
+
+ /**
+ * Int32 array for the TypedArray extension
+@@ -55,41 +63,119 @@
+ public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+ return new NativeInt32Array(buffer, byteOffset, length);
+ }
++
+ @Override
+- public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+- return new Int32ArrayData(buffer, byteOffset, length);
++ public Int32ArrayData createArrayData(final ByteBuffer nb, final int start, final int length) {
++ return new Int32ArrayData(nb.asIntBuffer(), start, length);
++ }
++
++ @Override
++ public String getClassName() {
++ return "Int32Array";
+ }
+ };
+
+- private static final class Int32ArrayData extends ArrayDataImpl {
+- private Int32ArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+- super(buffer, byteOffset, elementLength);
++ private static final class Int32ArrayData extends TypedArrayData<IntBuffer> {
++
++ private static final MethodHandle GET_ELEM = specialCall(MethodHandles.lookup(), Int32ArrayData.class, "getElem", int.class, int.class).methodHandle();
++ private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Int32ArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
++
++ private Int32ArrayData(final IntBuffer nb, final int start, final int end) {
++ super(((IntBuffer)nb.position(start).limit(end)).slice(), end - start);
+ }
+
+ @Override
+- protected int byteIndex(final int index) {
+- return index * BYTES_PER_ELEMENT + byteOffset;
++ protected MethodHandle getGetElem() {
++ return GET_ELEM;
+ }
+
+ @Override
+- protected int getIntImpl(final int index) {
+- final int byteIndex = byteIndex(index);
+- final byte[] byteArray = buffer.getByteArray();
+- return byteArray[byteIndex ] & 0x0000_00ff |
+- byteArray[byteIndex+1] << 8 & 0x0000_ff00 |
+- byteArray[byteIndex+2] << 16 & 0x00ff_0000 |
+- byteArray[byteIndex+3] << 24 & 0xff00_0000 ;
++ protected MethodHandle getSetElem() {
++ return SET_ELEM;
++ }
++
++ private int getElem(final int index) {
++ try {
++ return nb.get(index);
++ } catch (final IndexOutOfBoundsException e) {
++ throw new ClassCastException(); //force relink - this works for unoptimistic too
++ }
++ }
++
++ private void setElem(final int index, final int elem) {
++ try {
++ nb.put(index, elem);
++ } catch (final IndexOutOfBoundsException e) {
++ if (index < 0) {
++ throw new ClassCastException();
++ }
++ }
+ }
+
+ @Override
+- protected void setImpl(final int index, final int value) {
+- final int byteIndex = byteIndex(index);
+- @SuppressWarnings("MismatchedReadAndWriteOfArray")
+- final byte[] byteArray = buffer.getByteArray();
+- byteArray[byteIndex ] = (byte)(value & 0xff);
+- byteArray[byteIndex+1] = (byte)(value >>> 8 & 0xff);
+- byteArray[byteIndex+2] = (byte)(value >>> 16 & 0xff);
+- byteArray[byteIndex+3] = (byte)(value >>> 24 & 0xff);
++ public Class<?> getElementType() {
++ return int.class;
++ }
++
++ @Override
++ public Class<?> getBoxedElementType() {
++ return Integer.class;
++ }
++
++ @Override
++ public int getInt(final int index) {
++ return getElem(index);
++ }
++
++ @Override
++ public int getIntOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public long getLong(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public long getLongOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public double getDouble(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public Object getObject(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public ArrayData set(final int index, final Object value, final boolean strict) {
++ return set(index, JSType.toInt32(value), strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final int value, final boolean strict) {
++ setElem(index, value);
++ return this;
++ }
++
++ @Override
++ public ArrayData set(final int index, final long value, final boolean strict) {
++ return set(index, (int)value, strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final double value, final boolean strict) {
++ return set(index, (int)value, strict);
+ }
+ }
+
+@@ -104,7 +190,7 @@
+ */
+ @Constructor(arity = 1)
+ public static NativeInt32Array constructor(final boolean newObj, final Object self, final Object... args) {
+- return (NativeInt32Array)constructorImpl(args, FACTORY);
++ return (NativeInt32Array)constructorImpl(newObj, args, FACTORY);
+ }
+
+ NativeInt32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+@@ -112,11 +198,6 @@
+ }
+
+ @Override
+- public String getClassName() {
+- return "Int32Array";
+- }
+-
+- @Override
+ protected Factory factory() {
+ return FACTORY;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,15 +25,22 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
++
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.nio.ByteBuffer;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+ import jdk.nashorn.internal.objects.annotations.Function;
+ import jdk.nashorn.internal.objects.annotations.Property;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+ import jdk.nashorn.internal.objects.annotations.Where;
++import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
++import jdk.nashorn.internal.runtime.arrays.TypedArrayData;
+
+ /**
+ * Int8Array for the TypedArray extension
+@@ -57,32 +64,122 @@
+ }
+
+ @Override
+- public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+- return new Int8ArrayData(buffer, byteOffset, length);
++ public Int8ArrayData createArrayData(final ByteBuffer nb, final int start, final int end) {
++ return new Int8ArrayData(nb, start, end);
++ }
++
++ @Override
++ public String getClassName() {
++ return "Int8Array";
+ }
+ };
+
+- private static final class Int8ArrayData extends ArrayDataImpl {
+- private Int8ArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+- super(buffer, byteOffset, elementLength);
++ private static final class Int8ArrayData extends TypedArrayData<ByteBuffer> {
++
++ private static final MethodHandle GET_ELEM = specialCall(MethodHandles.lookup(), Int8ArrayData.class, "getElem", int.class, int.class).methodHandle();
++ private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Int8ArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
++
++ private Int8ArrayData(final ByteBuffer nb, final int start, final int end) {
++ super(((ByteBuffer)nb.position(start).limit(end)).slice(), end - start);
+ }
+
+ @Override
+- protected int byteIndex(final int index) {
+- return index * BYTES_PER_ELEMENT + byteOffset;
++ protected MethodHandle getGetElem() {
++ return GET_ELEM;
+ }
+
+ @Override
+- protected int getIntImpl(final int index) {
+- return buffer.getByteArray()[byteIndex(index)];
++ protected MethodHandle getSetElem() {
++ return SET_ELEM;
+ }
+
+ @Override
+- protected void setImpl(final int index, final int value) {
+- buffer.getByteArray()[byteIndex(index)] = (byte)value;
++ public Class<?> getElementType() {
++ return int.class;
++ }
++
++ @Override
++ public Class<?> getBoxedElementType() {
++ return Integer.class;
++ }
++
++ private int getElem(final int index) {
++ try {
++ return nb.get(index);
++ } catch (final IndexOutOfBoundsException e) {
++ throw new ClassCastException(); //force relink - this works for unoptimistic too
++ }
++ }
++
++ private void setElem(final int index, final int elem) {
++ try {
++ nb.put(index, (byte)elem);
++ } catch (final IndexOutOfBoundsException e) {
++ //swallow valid array indexes. it's ok.
++ if (index < 0) {
++ throw new ClassCastException();
++ }
++ }
++ }
++
++ @Override
++ public int getInt(final int index) {
++ return getElem(index);
++ }
++
++ @Override
++ public int getIntOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public long getLong(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public long getLongOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public double getDouble(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public Object getObject(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public ArrayData set(final int index, final Object value, final boolean strict) {
++ return set(index, JSType.toInt32(value), strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final int value, final boolean strict) {
++ setElem(index, value);
++ return this;
++ }
++
++ @Override
++ public ArrayData set(final int index, final long value, final boolean strict) {
++ return set(index, (int)value, strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final double value, final boolean strict) {
++ return set(index, (int)value, strict);
+ }
+ }
+
++
+ /**
+ * Constructor
+ *
+@@ -94,7 +191,7 @@
+ */
+ @Constructor(arity = 1)
+ public static NativeInt8Array constructor(final boolean newObj, final Object self, final Object... args) {
+- return (NativeInt8Array)constructorImpl(args, FACTORY);
++ return (NativeInt8Array)constructorImpl(newObj, args, FACTORY);
+ }
+
+ NativeInt8Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+@@ -102,11 +199,6 @@
+ }
+
+ @Override
+- public String getClassName() {
+- return "Int8Array";
+- }
+-
+- @Override
+ protected Factory factory() {
+ return FACTORY;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,9 +25,10 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.lookup.Lookup.MH;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+-import static jdk.nashorn.internal.lookup.Lookup.MH;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
+
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+@@ -38,6 +39,7 @@
+ import jdk.internal.dynalink.CallSiteDescriptor;
+ import jdk.internal.dynalink.linker.GuardedInvocation;
+ import jdk.internal.dynalink.linker.LinkRequest;
++import jdk.nashorn.internal.lookup.Lookup;
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+ import jdk.nashorn.internal.runtime.FindProperty;
+@@ -47,7 +49,6 @@
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+ import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
+-import jdk.nashorn.internal.lookup.Lookup;
+ import jdk.nashorn.internal.scripts.JO;
+
+ /**
+@@ -168,63 +169,63 @@
+ }
+
+ @Override
+- public int getInt(final Object key) {
+- return (overrides && super.hasOwnProperty(key)) ? super.getInt(key) : callAdapteeInt(__get__, key);
++ public int getInt(final Object key, final int programPoint) {
++ return (overrides && super.hasOwnProperty(key)) ? super.getInt(key, programPoint) : callAdapteeInt(programPoint, __get__, key);
+ }
+
+ @Override
+- public int getInt(final double key) {
+- return (overrides && super.hasOwnProperty(key)) ? super.getInt(key) : callAdapteeInt(__get__, key);
++ public int getInt(final double key, final int programPoint) {
++ return (overrides && super.hasOwnProperty(key)) ? super.getInt(key, programPoint) : callAdapteeInt(programPoint, __get__, key);
+ }
+
+ @Override
+- public int getInt(final long key) {
+- return (overrides && super.hasOwnProperty(key)) ? super.getInt(key) : callAdapteeInt(__get__, key);
++ public int getInt(final long key, final int programPoint) {
++ return (overrides && super.hasOwnProperty(key)) ? super.getInt(key, programPoint) : callAdapteeInt(programPoint, __get__, key);
+ }
+
+ @Override
+- public int getInt(final int key) {
+- return (overrides && super.hasOwnProperty(key)) ? super.getInt(key) : callAdapteeInt(__get__, key);
++ public int getInt(final int key, final int programPoint) {
++ return (overrides && super.hasOwnProperty(key)) ? super.getInt(key, programPoint) : callAdapteeInt(programPoint, __get__, key);
+ }
+
+ @Override
+- public long getLong(final Object key) {
+- return (overrides && super.hasOwnProperty(key)) ? super.getLong(key) : callAdapteeLong(__get__, key);
++ public long getLong(final Object key, final int programPoint) {
++ return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
+ }
+
+ @Override
+- public long getLong(final double key) {
+- return (overrides && super.hasOwnProperty(key)) ? super.getLong(key) : callAdapteeLong(__get__, key);
++ public long getLong(final double key, final int programPoint) {
++ return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
+ }
+
+ @Override
+- public long getLong(final long key) {
+- return (overrides && super.hasOwnProperty(key)) ? super.getLong(key) : callAdapteeLong(__get__, key);
++ public long getLong(final long key, final int programPoint) {
++ return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
+ }
+
+ @Override
+- public long getLong(final int key) {
+- return (overrides && super.hasOwnProperty(key)) ? super.getLong(key) : callAdapteeLong(__get__, key);
++ public long getLong(final int key, final int programPoint) {
++ return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
+ }
+
+ @Override
+- public double getDouble(final Object key) {
+- return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key) : callAdapteeDouble(__get__, key);
++ public double getDouble(final Object key, final int programPoint) {
++ return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key, programPoint) : callAdapteeDouble(programPoint, __get__, key);
+ }
+
+ @Override
+- public double getDouble(final double key) {
+- return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key) : callAdapteeDouble(__get__, key);
++ public double getDouble(final double key, final int programPoint) {
++ return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key, programPoint) : callAdapteeDouble(programPoint, __get__, key);
+ }
+
+ @Override
+- public double getDouble(final long key) {
+- return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key) : callAdapteeDouble(__get__, key);
++ public double getDouble(final long key, final int programPoint) {
++ return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key, programPoint) : callAdapteeDouble(programPoint, __get__, key);
+ }
+
+ @Override
+- public double getDouble(final int key) {
+- return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key) : callAdapteeDouble(__get__, key);
++ public double getDouble(final int key, final int programPoint) {
++ return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key, programPoint) : callAdapteeDouble(programPoint, __get__, key);
+ }
+
+ @Override
+@@ -248,146 +249,146 @@
+ }
+
+ @Override
+- public void set(final Object key, final int value, final boolean strict) {
++ public void set(final Object key, final int value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+ @Override
+- public void set(final Object key, final long value, final boolean strict) {
++ public void set(final Object key, final long value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+ @Override
+- public void set(final Object key, final double value, final boolean strict) {
++ public void set(final Object key, final double value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+ @Override
+- public void set(final Object key, final Object value, final boolean strict) {
++ public void set(final Object key, final Object value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+ @Override
+- public void set(final double key, final int value, final boolean strict) {
++ public void set(final double key, final int value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+ @Override
+- public void set(final double key, final long value, final boolean strict) {
++ public void set(final double key, final long value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+ @Override
+- public void set(final double key, final double value, final boolean strict) {
++ public void set(final double key, final double value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+ @Override
+- public void set(final double key, final Object value, final boolean strict) {
++ public void set(final double key, final Object value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+ @Override
+- public void set(final long key, final int value, final boolean strict) {
++ public void set(final long key, final int value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+ @Override
+- public void set(final long key, final long value, final boolean strict) {
++ public void set(final long key, final long value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+ @Override
+- public void set(final long key, final double value, final boolean strict) {
++ public void set(final long key, final double value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+ @Override
+- public void set(final long key, final Object value, final boolean strict) {
++ public void set(final long key, final Object value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+ @Override
+- public void set(final int key, final int value, final boolean strict) {
++ public void set(final int key, final int value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+ @Override
+- public void set(final int key, final long value, final boolean strict) {
++ public void set(final int key, final long value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+ @Override
+- public void set(final int key, final double value, final boolean strict) {
++ public void set(final int key, final double value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+ @Override
+- public void set(final int key, final Object value, final boolean strict) {
++ public void set(final int key, final Object value, final int flags) {
+ if (overrides && super.hasOwnProperty(key)) {
+- super.set(key, value, strict);
++ super.set(key, value, flags);
+ } else {
+- callAdaptee(__put__, key, value, strict);
++ callAdaptee(__put__, key, value, flags);
+ }
+ }
+
+@@ -577,7 +578,7 @@
+ }
+
+ @Override
+- protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc) {
++ protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+ return findHook(desc, __new__, false);
+ }
+
+@@ -625,8 +626,8 @@
+ // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice.
+ return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class,
+ func.makeBoundFunction(this, new Object[] { name })), 0, Object.class),
+- adaptee.getProtoSwitchPoint(__call__, find.getOwner()),
+- testJSAdaptor(adaptee, null, null, null));
++ testJSAdaptor(adaptee, null, null, null),
++ adaptee.getProtoSwitchPoint(__call__, find.getOwner()));
+ }
+ }
+ throw typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this));
+@@ -658,16 +659,16 @@
+ return callAdaptee(UNDEFINED, name, args);
+ }
+
+- private double callAdapteeDouble(final String name, final Object... args) {
+- return JSType.toNumber(callAdaptee(name, args));
++ private double callAdapteeDouble(final int programPoint, final String name, final Object... args) {
++ return JSType.toNumberMaybeOptimistic(callAdaptee(name, args), programPoint);
+ }
+
+- private long callAdapteeLong(final String name, final Object... args) {
+- return JSType.toLong(callAdaptee(name, args));
++ private long callAdapteeLong(final int programPoint, final String name, final Object... args) {
++ return JSType.toLongMaybeOptimistic(callAdaptee(name, args), programPoint);
+ }
+
+- private int callAdapteeInt(final String name, final Object... args) {
+- return JSType.toInt32(callAdaptee(name, args));
++ private int callAdapteeInt(final int programPoint, final String name, final Object... args) {
++ return JSType.toInt32MaybeOptimistic(callAdaptee(name, args), programPoint);
+ }
+
+ private Object callAdaptee(final Object retValue, final String name, final Object... args) {
+@@ -696,8 +697,8 @@
+ if (methodHandle != null) {
+ return new GuardedInvocation(
+ methodHandle,
+- adaptee.getProtoSwitchPoint(hook, findData.getOwner()),
+- testJSAdaptor(adaptee, findData.getGetter(Object.class), findData.getOwner(), func));
++ testJSAdaptor(adaptee, findData.getGetter(Object.class, INVALID_PROGRAM_POINT, null), findData.getOwner(), func),
++ adaptee.getProtoSwitchPoint(hook, findData.getOwner()));
+ }
+ }
+ }
+@@ -709,7 +710,7 @@
+ final MethodHandle methodHandle = hook.equals(__put__) ?
+ MH.asType(Lookup.EMPTY_SETTER, type) :
+ Lookup.emptyGetter(type.returnType());
+- return new GuardedInvocation(methodHandle, adaptee.getProtoSwitchPoint(hook, null), testJSAdaptor(adaptee, null, null, null));
++ return new GuardedInvocation(methodHandle, testJSAdaptor(adaptee, null, null, null), adaptee.getProtoSwitchPoint(hook, null));
+ }
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java Wed Feb 04 12:14:47 2015 -0800
+@@ -171,7 +171,7 @@
+ }
+
+ if (modSpace instanceof Number) {
+- int indent = Math.min(10, JSType.toInteger(modSpace));
++ final int indent = Math.min(10, JSType.toInteger(modSpace));
+ if (indent < 1) {
+ gap = "";
+ } else {
+@@ -191,7 +191,7 @@
+ state.gap = gap;
+
+ final ScriptObject wrapper = Global.newEmptyInstance();
+- wrapper.set("", value, false);
++ wrapper.set("", value, 0);
+
+ return str("", wrapper, state);
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeJava.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeJava.java Wed Feb 04 12:14:47 2015 -0800
+@@ -36,6 +36,7 @@
+ import jdk.internal.dynalink.beans.StaticClass;
+ import jdk.internal.dynalink.support.TypeUtilities;
+ import jdk.nashorn.api.scripting.JSObject;
++import jdk.nashorn.api.scripting.ScriptUtils;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Function;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+@@ -44,6 +45,7 @@
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.ListAdapter;
+ import jdk.nashorn.internal.runtime.PropertyMap;
++import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+ import jdk.nashorn.internal.runtime.linker.Bootstrap;
+@@ -80,6 +82,77 @@
+ }
+
+ /**
++ * Returns synchronized wrapper version of the given ECMAScript function.
++ * @param self not used
++ * @param func the ECMAScript function whose synchronized version is returned.
++ * @param obj the object (i.e, lock) on which the function synchronizes.
++ * @return synchronized wrapper version of the given ECMAScript function.
++ */
++ @Function(name="synchronized", attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static Object synchronizedFunc(final Object self, final Object func, final Object obj) {
++ if (func instanceof ScriptFunction) {
++ return ((ScriptFunction)func).makeSynchronizedFunction(obj);
++ }
++
++ throw typeError("not.a.function", ScriptRuntime.safeToString(func));
++ }
++
++ /**
++ * Returns true if the specified object is a Java method.
++ * @param self not used
++ * @param obj the object that is checked if it is a Java method object or not
++ * @return tells whether given object is a Java method object or not.
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static boolean isJavaMethod(final Object self, final Object obj) {
++ return Bootstrap.isDynamicMethod(obj);
++ }
++
++ /**
++ * Returns true if the specified object is a java function (but not script function)
++ * @param self not used
++ * @param obj the object that is checked if it is a Java function or not
++ * @return tells whether given object is a Java function or not
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static boolean isJavaFunction(final Object self, final Object obj) {
++ return Bootstrap.isCallable(obj) && !(obj instanceof ScriptFunction);
++ }
++
++ /**
++ * Returns true if the specified object is a Java object but not a script object
++ * @param self not used
++ * @param obj the object that is checked
++ * @return tells whether given object is a Java object but not a script object
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static boolean isJavaObject(final Object self, final Object obj) {
++ return obj != null && !(obj instanceof ScriptObject);
++ }
++
++ /**
++ * Returns true if the specified object is a ECMAScript object, that is an instance of {@link ScriptObject}.
++ * @param self not used
++ * @param obj the object that is checked if it is a ECMAScript object or not
++ * @return tells whether given object is a ECMAScript object or not.
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static boolean isScriptObject(final Object self, final Object obj) {
++ return obj instanceof ScriptObject;
++ }
++
++ /**
++ * Returns true if the specified object is a ECMAScript function, that is an instance of {@link ScriptFunction}.
++ * @param self not used
++ * @param obj the object that is checked if it is a ECMAScript function or not
++ * @return tells whether given object is a ECMAScript function or not.
++ */
++ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
++ public static boolean isScriptFunction(final Object self, final Object obj) {
++ return obj instanceof ScriptFunction;
++ }
++
++ /**
+ * <p>
+ * Given a name of a Java type, returns an object representing that type in Nashorn. The Java class of the objects
+ * used to represent Java types in Nashorn is not {@link java.lang.Class} but rather {@link StaticClass}. They are
+@@ -414,7 +487,7 @@
+ final Context ctx = Global.getThisContext();
+ try {
+ return ctx.findClass(typeName);
+- } catch(ClassNotFoundException e) {
++ } catch(final ClassNotFoundException e) {
+ // The logic below compensates for a frequent user error - when people use dot notation to separate inner
+ // class names, i.e. "java.lang.Character.UnicodeBlock" vs."java.lang.Character$UnicodeBlock". The logic
+ // below will try alternative class names, replacing dots at the end of the name with dollar signs.
+@@ -429,7 +502,7 @@
+ nextName.setCharAt(lastDot, '$');
+ try {
+ return ctx.findClass(nextName.toString());
+- } catch(ClassNotFoundException cnfe) {
++ } catch(final ClassNotFoundException cnfe) {
+ // Intentionally ignored, so the loop retries with the next name
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,9 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
++
+ import jdk.internal.dynalink.CallSiteDescriptor;
+ import jdk.internal.dynalink.beans.StaticClass;
+ import jdk.internal.dynalink.linker.GuardedInvocation;
+@@ -34,9 +37,12 @@
+ import jdk.nashorn.internal.objects.annotations.Function;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+ import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.NativeJavaPackage;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptObject;
++import jdk.nashorn.internal.runtime.ScriptRuntime;
++import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
+
+ /**
+ * This is "JavaImporter" constructor. This constructor allows you to use Java types omitting explicit package names.
+@@ -91,33 +97,30 @@
+ }
+
+ /**
+- * "No such property" call placeholder.
+- *
+- * This can never be called as we override {@link ScriptObject#noSuchProperty}. We do declare it here as it's a signal
+- * to {@link jdk.nashorn.internal.runtime.WithObject} that it's worth trying doing a {@code noSuchProperty} on this object.
++ * "No such property" handler.
+ *
+ * @param self self reference
+ * @param name property name
+- * @return never returns
++ * @return value of the missing property
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
+ public static Object __noSuchProperty__(final Object self, final Object name) {
+- throw new AssertionError("__noSuchProperty__ placeholder called");
++ if (! (self instanceof NativeJavaImporter)) {
++ throw typeError("not.a.java.importer", ScriptRuntime.safeToString(self));
++ }
++ return ((NativeJavaImporter)self).createProperty(JSType.toString(name));
+ }
+
+ /**
+- * "No such method call" placeholder
+- *
+- * This can never be called as we override {@link ScriptObject#noSuchMethod}. We do declare it here as it's a signal
+- * to {@link jdk.nashorn.internal.runtime.WithObject} that it's worth trying doing a noSuchProperty on this object.
++ * "No such method call" handler
+ *
+ * @param self self reference
+ * @param args arguments to method
+- * @return never returns
++ * @return never returns always throw TypeError
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
+ public static Object __noSuchMethod__(final Object self, final Object... args) {
+- throw new AssertionError("__noSuchMethod__ placeholder called");
++ throw typeError("not.a.function", ScriptRuntime.safeToString(args[0]));
+ }
+
+ @Override
+@@ -131,15 +134,19 @@
+ }
+
+ @Override
+- protected Object invokeNoSuchProperty(final String name) {
+- return createProperty(name);
++ protected Object invokeNoSuchProperty(final String name, final int programPoint) {
++ final Object retval = createProperty(name);
++ if (isValid(programPoint)) {
++ throw new UnwarrantedOptimismException(retval, programPoint);
++ }
++ return retval;
+ }
+
+ private boolean createAndSetProperty(final CallSiteDescriptor desc) {
+ final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
+ final Object value = createProperty(name);
+ if(value != null) {
+- set(name, value, false);
++ set(name, value, 0);
+ return true;
+ }
+ return false;
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeMath.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeMath.java Wed Feb 04 12:14:47 2015 -0800
+@@ -489,6 +489,20 @@
+ }
+
+ /**
++ * ECMA 15.8.2.11 max(x) - specialized version for two Object args
++ *
++ * @param self self reference
++ * @param x first argument
++ * @param y second argument
++ *
++ * @return largest value of x and y
++ */
++ @SpecializedFunction
++ public static double max(final Object self, final Object x, final Object y) {
++ return Math.max(JSType.toNumber(x), JSType.toNumber(y));
++ }
++
++ /**
+ * ECMA 15.8.2.12 min(x)
+ *
+ * @param self self reference
+@@ -567,6 +581,20 @@
+ }
+
+ /**
++ * ECMA 15.8.2.12 min(x) - specialized version for two Object args
++ *
++ * @param self self reference
++ * @param x first argument
++ * @param y second argument
++ *
++ * @return smallest value of x and y
++ */
++ @SpecializedFunction
++ public static double min(final Object self, final Object x, final Object y) {
++ return Math.min(JSType.toNumber(x), JSType.toNumber(y));
++ }
++
++ /**
+ * ECMA 15.8.2.13 pow(x,y)
+ *
+ * @param self self reference
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,12 +25,10 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.lookup.Lookup.MH;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+-import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsInt;
+-import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsLong;
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+-import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+@@ -44,6 +42,7 @@
+ import jdk.nashorn.internal.objects.annotations.Function;
+ import jdk.nashorn.internal.objects.annotations.Property;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
++import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
+ import jdk.nashorn.internal.objects.annotations.Where;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+@@ -58,9 +57,9 @@
+ @ScriptClass("Number")
+ public final class NativeNumber extends ScriptObject {
+
+- // Method handle to create an object wrapper for a primitive number
+- private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeNumber.class, Object.class));
+- // Method handle to retrieve the Number prototype object
++ /** Method handle to create an object wrapper for a primitive number. */
++ static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeNumber.class, Object.class));
++ /** Method handle to retrieve the Number prototype object. */
+ private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
+
+ /** ECMA 15.7.3.2 largest positive finite value */
+@@ -84,8 +83,6 @@
+ public static final double POSITIVE_INFINITY = Double.POSITIVE_INFINITY;
+
+ private final double value;
+- private final boolean isInt;
+- private final boolean isLong;
+
+ // initialized by nasgen
+ private static PropertyMap $nasgenmap$;
+@@ -93,8 +90,6 @@
+ private NativeNumber(final double value, final ScriptObject proto, final PropertyMap map) {
+ super(proto, map);
+ this.value = value;
+- this.isInt = isRepresentableAsInt(value);
+- this.isLong = isRepresentableAsLong(value);
+ }
+
+ NativeNumber(final double value, final Global global) {
+@@ -132,30 +127,6 @@
+ return value;
+ }
+
+- /**
+- * Get the value of this Number as a {@code int}
+- * @return an {@code int} representing the Number value
+- * @throws ClassCastException If number is not representable as an {@code int}
+- */
+- public int intValue() throws ClassCastException {
+- if (isInt) {
+- return (int)value;
+- }
+- throw new ClassCastException();
+- }
+-
+- /**
+- * Get the value of this Number as a {@code long}
+- * @return a {@code long} representing the Number value
+- * @throws ClassCastException If number is not representable as an {@code long}
+- */
+- public long longValue() throws ClassCastException {
+- if (isLong) {
+- return (long)value;
+- }
+- throw new ClassCastException();
+- }
+-
+ @Override
+ public String getClassName() {
+ return "Number";
+@@ -186,8 +157,20 @@
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
+ public static String toFixed(final Object self, final Object fractionDigits) {
+- final int f = JSType.toInteger(fractionDigits);
+- if (f < 0 || f > 20) {
++ return toFixed(self, JSType.toInteger(fractionDigits));
++ }
++
++ /**
++ * ECMA 15.7.4.5 Number.prototype.toFixed (fractionDigits) specialized for int fractionDigits
++ *
++ * @param self self reference
++ * @param fractionDigits how many digits should be after the decimal point, 0 if undefined
++ *
++ * @return number in decimal fixed point notation
++ */
++ @SpecializedFunction
++ public static String toFixed(final Object self, final int fractionDigits) {
++ if (fractionDigits < 0 || fractionDigits > 20) {
+ throw rangeError("invalid.fraction.digits", "toFixed");
+ }
+
+@@ -201,8 +184,8 @@
+ }
+
+ final NumberFormat format = NumberFormat.getNumberInstance(Locale.US);
+- format.setMinimumFractionDigits(f);
+- format.setMaximumFractionDigits(f);
++ format.setMinimumFractionDigits(fractionDigits);
++ format.setMaximumFractionDigits(fractionDigits);
+ format.setGroupingUsed(false);
+
+ return format.format(x);
+@@ -240,7 +223,7 @@
+ * ECMA 15.7.4.7 Number.prototype.toPrecision (precision)
+ *
+ * @param self self reference
+- * @param precision use {@code precision - 1} digits after the significand's decimal point or call {@link NativeDate#toString} if undefined
++ * @param precision use {@code precision - 1} digits after the significand's decimal point or call {@link JSType#toString} if undefined
+ *
+ * @return number in decimal exponentiation notation or decimal fixed notation depending on {@code precision}
+ */
+@@ -250,8 +233,23 @@
+ if (precision == UNDEFINED) {
+ return JSType.toString(x);
+ }
++ return (toPrecision(x, JSType.toInteger(precision)));
++ }
+
+- final int p = JSType.toInteger(precision);
++ /**
++ * ECMA 15.7.4.7 Number.prototype.toPrecision (precision) specialized f
++ *
++ * @param self self reference
++ * @param precision use {@code precision - 1} digits after the significand's decimal point.
++ *
++ * @return number in decimal exponentiation notation or decimal fixed notation depending on {@code precision}
++ */
++ @SpecializedFunction
++ public static String toPrecision(final Object self, final int precision) {
++ return toPrecision(getNumberValue(self), precision);
++ }
++
++ private static String toPrecision(final double x, final int p) {
+ if (Double.isNaN(x)) {
+ return "NaN";
+ } else if (Double.isInfinite(x)) {
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeObject.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeObject.java Wed Feb 04 12:14:47 2015 -0800
+@@ -75,7 +75,10 @@
+ */
+ @ScriptClass("Object")
+ public final class NativeObject {
++ /** Methodhandle to proto getter */
+ public static final MethodHandle GET__PROTO__ = findOwnMH("get__proto__", ScriptObject.class, Object.class);
++
++ /** Methodhandle to proto setter */
+ public static final MethodHandle SET__PROTO__ = findOwnMH("set__proto__", Object.class, Object.class, Object.class);
+
+ private static final Object TO_STRING = new Object();
+@@ -94,9 +97,7 @@
+ private static ScriptObject get__proto__(final Object self) {
+ // See ES6 draft spec: B.2.2.1.1 get Object.prototype.__proto__
+ // Step 1 Let O be the result of calling ToObject passing the this.
+- final Object obj = Global.toObject(self);
+- Global.checkObject(obj);
+- final ScriptObject sobj = (ScriptObject)obj;
++ final ScriptObject sobj = Global.checkObject(Global.toObject(self));
+ return sobj.getProto();
+ }
+
+@@ -282,8 +283,7 @@
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+ public static ScriptObject defineProperty(final Object self, final Object obj, final Object prop, final Object attr) {
+- Global.checkObject(obj);
+- final ScriptObject sobj = (ScriptObject)obj;
++ final ScriptObject sobj = Global.checkObject(obj);
+ sobj.defineOwnProperty(JSType.toString(prop), attr, true);
+ return sobj;
+ }
+@@ -298,9 +298,7 @@
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+ public static ScriptObject defineProperties(final Object self, final Object obj, final Object props) {
+- Global.checkObject(obj);
+-
+- final ScriptObject sobj = (ScriptObject)obj;
++ final ScriptObject sobj = Global.checkObject(obj);
+ final Object propsObj = Global.toObject(props);
+
+ if (propsObj instanceof ScriptObject) {
+@@ -454,18 +452,17 @@
+ */
+ @Constructor
+ public static Object construct(final boolean newObj, final Object self, final Object value) {
+- final JSType type = JSType.of(value);
++ final JSType type = JSType.ofNoFunction(value);
+
+ // Object(null), Object(undefined), Object() are same as "new Object()"
+
+- if (newObj || (type == JSType.NULL || type == JSType.UNDEFINED)) {
++ if (newObj || type == JSType.NULL || type == JSType.UNDEFINED) {
+ switch (type) {
+ case BOOLEAN:
+ case NUMBER:
+ case STRING:
+ return Global.toObject(value);
+ case OBJECT:
+- case FUNCTION:
+ return value;
+ case NULL:
+ case UNDEFINED:
+@@ -546,7 +543,7 @@
+ final Object key = JSType.toPrimitive(v, String.class);
+ final Object obj = Global.toObject(self);
+
+- return (obj instanceof ScriptObject) && ((ScriptObject)obj).hasOwnProperty(key);
++ return obj instanceof ScriptObject && ((ScriptObject)obj).hasOwnProperty(key);
+ }
+
+ /**
+@@ -660,25 +657,29 @@
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+ public static Object bindProperties(final Object self, final Object target, final Object source) {
+ // target object has to be a ScriptObject
+- Global.checkObject(target);
++ final ScriptObject targetObj = Global.checkObject(target);
+ // check null or undefined source object
+ Global.checkObjectCoercible(source);
+
+- final ScriptObject targetObj = (ScriptObject)target;
++ if (source instanceof ScriptObject) {
++ final ScriptObject sourceObj = (ScriptObject)source;
+
+- if (source instanceof ScriptObject) {
+- final ScriptObject sourceObj = (ScriptObject)source;
+- final Property[] properties = sourceObj.getMap().getProperties();
++ final PropertyMap sourceMap = sourceObj.getMap();
++ final Property[] properties = sourceMap.getProperties();
++ //replace the map and blow up everything to objects to work with dual fields :-(
+
+ // filter non-enumerable properties
+ final ArrayList<Property> propList = new ArrayList<>();
+- for (Property prop : properties) {
++ for (final Property prop : properties) {
+ if (prop.isEnumerable()) {
++ final Object value = sourceObj.get(prop.getKey());
++ prop.setType(Object.class);
++ prop.setValue(sourceObj, sourceObj, value, false);
+ propList.add(prop);
+ }
+ }
+
+- if (! propList.isEmpty()) {
++ if (!propList.isEmpty()) {
+ targetObj.addBoundProperties(sourceObj, propList.toArray(new Property[propList.size()]));
+ }
+ } else if (source instanceof ScriptObjectMirror) {
+@@ -696,7 +697,7 @@
+ final String name = keys[idx];
+ final MethodHandle getter = Bootstrap.createDynamicInvoker("dyn:getMethod|getProp|getElem:" + name, MIRROR_GETTER_TYPE);
+ final MethodHandle setter = Bootstrap.createDynamicInvoker("dyn:setProp|setElem:" + name, MIRROR_SETTER_TYPE);
+- props[idx] = (AccessorProperty.create(name, 0, getter, setter));
++ props[idx] = AccessorProperty.create(name, 0, getter, setter);
+ }
+
+ targetObj.addBoundProperties(source, props);
+@@ -715,6 +716,32 @@
+ return target;
+ }
+
++ /**
++ * Binds the source mirror object's properties to the target object. Binding
++ * properties allows two-way read/write for the properties of the source object.
++ * All inherited, enumerable properties are also bound. This method is used to
++ * to make 'with' statement work with ScriptObjectMirror as scope object.
++ *
++ * @param target the target object to which the source object's properties are bound
++ * @param source the source object whose properties are bound to the target
++ * @return the target object after property binding
++ */
++ public static Object bindAllProperties(final ScriptObject target, final ScriptObjectMirror source) {
++ final Set<String> keys = source.keySet();
++ // make accessor properties using dynamic invoker getters and setters
++ final AccessorProperty[] props = new AccessorProperty[keys.size()];
++ int idx = 0;
++ for (final String name : keys) {
++ final MethodHandle getter = Bootstrap.createDynamicInvoker("dyn:getMethod|getProp|getElem:" + name, MIRROR_GETTER_TYPE);
++ final MethodHandle setter = Bootstrap.createDynamicInvoker("dyn:setProp|setElem:" + name, MIRROR_SETTER_TYPE);
++ props[idx] = AccessorProperty.create(name, 0, getter, setter);
++ idx++;
++ }
++
++ target.addBoundProperties(source, props);
++ return target;
++ }
++
+ private static void bindBeanProperties(final ScriptObject targetObj, final Object source,
+ final Collection<String> readablePropertyNames, final Collection<String> writablePropertyNames,
+ final Collection<String> methodNames) {
+@@ -772,16 +799,16 @@
+ targetObj.addBoundProperties(source, properties.toArray(new AccessorProperty[properties.size()]));
+ }
+
+- private static MethodHandle getBoundBeanMethodGetter(Object source, MethodHandle methodGetter) {
++ private static MethodHandle getBoundBeanMethodGetter(final Object source, final MethodHandle methodGetter) {
+ try {
+ // NOTE: we're relying on the fact that "dyn:getMethod:..." return value is constant for any given method
+ // name and object linked with BeansLinker. (Actually, an even stronger assumption is true: return value is
+ // constant for any given method name and object's class.)
+ return MethodHandles.dropArguments(MethodHandles.constant(Object.class,
+- Bootstrap.bindDynamicMethod(methodGetter.invoke(source), source)), 0, Object.class);
++ Bootstrap.bindCallable(methodGetter.invoke(source), source, null)), 0, Object.class);
+ } catch(RuntimeException|Error e) {
+ throw e;
+- } catch(Throwable t) {
++ } catch(final Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+@@ -794,10 +821,10 @@
+ assert passesGuard(source, inv.getGuard());
+ } catch(RuntimeException|Error e) {
+ throw e;
+- } catch(Throwable t) {
++ } catch(final Throwable t) {
+ throw new RuntimeException(t);
+ }
+- assert inv.getSwitchPoint() == null; // Linkers in Dynalink's beans package don't use switchpoints.
++ assert inv.getSwitchPoints() == null; // Linkers in Dynalink's beans package don't use switchpoints.
+ // We discard the guard, as all method handles will be bound to a specific object.
+ return inv.getInvocation();
+ }
+@@ -806,12 +833,12 @@
+ return guard == null || (boolean)guard.invoke(obj);
+ }
+
+- private static LinkRequest createLinkRequest(String operation, MethodType methodType, Object source) {
++ private static LinkRequest createLinkRequest(final String operation, final MethodType methodType, final Object source) {
+ return new LinkRequestImpl(CallSiteDescriptorFactory.create(MethodHandles.publicLookup(), operation,
+- methodType), false, source);
++ methodType), null, 0, false, source);
+ }
+
+ private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+- return MH.findStatic(MethodHandles.lookup(), NativeObject.class, name, MH.type(rtype, types));
++ return MH.findStatic(MethodHandles.lookup(), NativeObject.class, name, MH.type(rtype, types));
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,9 +28,11 @@
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
++import java.lang.invoke.MethodHandle;
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.List;
++import java.util.concurrent.Callable;
+
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+@@ -38,19 +40,20 @@
+ import jdk.nashorn.internal.objects.annotations.Getter;
+ import jdk.nashorn.internal.objects.annotations.Property;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+-import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
++import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
+ import jdk.nashorn.internal.objects.annotations.Where;
+ import jdk.nashorn.internal.runtime.BitVector;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.ParserException;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+-import jdk.nashorn.internal.runtime.regexp.RegExp;
+-import jdk.nashorn.internal.runtime.regexp.RegExpFactory;
+-import jdk.nashorn.internal.runtime.regexp.RegExpResult;
+-import jdk.nashorn.internal.runtime.regexp.RegExpMatcher;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
++import jdk.nashorn.internal.runtime.linker.Bootstrap;
++import jdk.nashorn.internal.runtime.regexp.RegExp;
++import jdk.nashorn.internal.runtime.regexp.RegExpFactory;
++import jdk.nashorn.internal.runtime.regexp.RegExpMatcher;
++import jdk.nashorn.internal.runtime.regexp.RegExpResult;
+
+ /**
+ * ECMA 15.10 RegExp Objects.
+@@ -141,7 +144,7 @@
+ * @param self self reference
+ * @return new NativeRegExp
+ */
+- @SpecializedConstructor
++ @SpecializedFunction(isConstructor=true)
+ public static NativeRegExp constructor(final boolean isNew, final Object self) {
+ return new NativeRegExp("", "");
+ }
+@@ -156,7 +159,7 @@
+ * @param pattern pattern
+ * @return new NativeRegExp
+ */
+- @SpecializedConstructor
++ @SpecializedFunction(isConstructor=true)
+ public static NativeRegExp constructor(final boolean isNew, final Object self, final Object pattern) {
+ return newRegExp(pattern, UNDEFINED);
+ }
+@@ -172,7 +175,7 @@
+ * @param flags flags
+ * @return new NativeRegExp
+ */
+- @SpecializedConstructor
++ @SpecializedFunction(isConstructor=true)
+ public static NativeRegExp constructor(final boolean isNew, final Object self, final Object pattern, final Object flags) {
+ return newRegExp(pattern, flags);
+ }
+@@ -211,7 +214,7 @@
+ * @param string pattern string
+ * @return flat regexp
+ */
+- static NativeRegExp flatRegExp(String string) {
++ static NativeRegExp flatRegExp(final String string) {
+ // escape special characters
+ StringBuilder sb = null;
+ final int length = string.length();
+@@ -379,7 +382,7 @@
+ * @return last regexp input
+ */
+ @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "input")
+- public static Object getLastInput(Object self) {
++ public static Object getLastInput(final Object self) {
+ final RegExpResult match = Global.instance().getLastRegExpResult();
+ return match == null ? "" : match.getInput();
+ }
+@@ -390,7 +393,7 @@
+ * @return last regexp input
+ */
+ @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "multiline")
+- public static Object getLastMultiline(Object self) {
++ public static Object getLastMultiline(final Object self) {
+ return false; // doesn't ever seem to become true and isn't documented anyhwere
+ }
+
+@@ -400,7 +403,7 @@
+ * @return last regexp input
+ */
+ @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "lastMatch")
+- public static Object getLastMatch(Object self) {
++ public static Object getLastMatch(final Object self) {
+ final RegExpResult match = Global.instance().getLastRegExpResult();
+ return match == null ? "" : match.getGroup(0);
+ }
+@@ -411,7 +414,7 @@
+ * @return last regexp input
+ */
+ @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "lastParen")
+- public static Object getLastParen(Object self) {
++ public static Object getLastParen(final Object self) {
+ final RegExpResult match = Global.instance().getLastRegExpResult();
+ return match == null ? "" : match.getLastParen();
+ }
+@@ -422,7 +425,7 @@
+ * @return last regexp input
+ */
+ @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "leftContext")
+- public static Object getLeftContext(Object self) {
++ public static Object getLeftContext(final Object self) {
+ final RegExpResult match = Global.instance().getLastRegExpResult();
+ return match == null ? "" : match.getInput().substring(0, match.getIndex());
+ }
+@@ -433,7 +436,7 @@
+ * @return last regexp input
+ */
+ @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "rightContext")
+- public static Object getRightContext(Object self) {
++ public static Object getRightContext(final Object self) {
+ final RegExpResult match = Global.instance().getLastRegExpResult();
+ return match == null ? "" : match.getInput().substring(match.getIndex() + match.length());
+ }
+@@ -444,7 +447,7 @@
+ * @return last regexp input
+ */
+ @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$1")
+- public static Object getGroup1(Object self) {
++ public static Object getGroup1(final Object self) {
+ final RegExpResult match = Global.instance().getLastRegExpResult();
+ return match == null ? "" : match.getGroup(1);
+ }
+@@ -455,7 +458,7 @@
+ * @return last regexp input
+ */
+ @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$2")
+- public static Object getGroup2(Object self) {
++ public static Object getGroup2(final Object self) {
+ final RegExpResult match = Global.instance().getLastRegExpResult();
+ return match == null ? "" : match.getGroup(2);
+ }
+@@ -466,7 +469,7 @@
+ * @return last regexp input
+ */
+ @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$3")
+- public static Object getGroup3(Object self) {
++ public static Object getGroup3(final Object self) {
+ final RegExpResult match = Global.instance().getLastRegExpResult();
+ return match == null ? "" : match.getGroup(3);
+ }
+@@ -477,7 +480,7 @@
+ * @return last regexp input
+ */
+ @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$4")
+- public static Object getGroup4(Object self) {
++ public static Object getGroup4(final Object self) {
+ final RegExpResult match = Global.instance().getLastRegExpResult();
+ return match == null ? "" : match.getGroup(4);
+ }
+@@ -488,7 +491,7 @@
+ * @return last regexp input
+ */
+ @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$5")
+- public static Object getGroup5(Object self) {
++ public static Object getGroup5(final Object self) {
+ final RegExpResult match = Global.instance().getLastRegExpResult();
+ return match == null ? "" : match.getGroup(5);
+ }
+@@ -499,7 +502,7 @@
+ * @return last regexp input
+ */
+ @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$6")
+- public static Object getGroup6(Object self) {
++ public static Object getGroup6(final Object self) {
+ final RegExpResult match = Global.instance().getLastRegExpResult();
+ return match == null ? "" : match.getGroup(6);
+ }
+@@ -510,7 +513,7 @@
+ * @return last regexp input
+ */
+ @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$7")
+- public static Object getGroup7(Object self) {
++ public static Object getGroup7(final Object self) {
+ final RegExpResult match = Global.instance().getLastRegExpResult();
+ return match == null ? "" : match.getGroup(7);
+ }
+@@ -521,7 +524,7 @@
+ * @return last regexp input
+ */
+ @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$8")
+- public static Object getGroup8(Object self) {
++ public static Object getGroup8(final Object self) {
+ final RegExpResult match = Global.instance().getLastRegExpResult();
+ return match == null ? "" : match.getGroup(8);
+ }
+@@ -532,7 +535,7 @@
+ * @return last regexp input
+ */
+ @Getter(where = Where.CONSTRUCTOR, attributes = Attribute.CONSTANT, name = "$9")
+- public static Object getGroup9(Object self) {
++ public static Object getGroup9(final Object self) {
+ final RegExpResult match = Global.instance().getLastRegExpResult();
+ return match == null ? "" : match.getGroup(9);
+ }
+@@ -569,7 +572,7 @@
+ }
+
+ // String.prototype.split method ignores the global flag and should not update lastIndex property.
+- private RegExpResult execSplit(final String string, int start) {
++ private RegExpResult execSplit(final String string, final int start) {
+ if (start < 0 || start > string.length()) {
+ return null;
+ }
+@@ -596,7 +599,7 @@
+ for (int i = 0, lastGroupStart = matcher.start(); i <= groupCount; i++) {
+ final int groupStart = matcher.start(i);
+ if (lastGroupStart > groupStart
+- || (groupsInNegativeLookahead != null && groupsInNegativeLookahead.isSet(i))) {
++ || groupsInNegativeLookahead != null && groupsInNegativeLookahead.isSet(i)) {
+ // (1) ECMA 15.10.2.5 NOTE 3: need to clear Atom's captures each time Atom is repeated.
+ // (2) ECMA 15.10.2.8 NOTE 3: Backreferences to captures in (?!Disjunction) from elsewhere
+ // in the pattern always return undefined because the negative lookahead must fail.
+@@ -649,7 +652,7 @@
+ * @param replacement Replacement string.
+ * @return String with substitutions.
+ */
+- String replace(final String string, final String replacement, final ScriptFunction function) {
++ String replace(final String string, final String replacement, final ScriptFunction function) throws Throwable {
+ final RegExpMatcher matcher = regexp.match(string);
+
+ if (matcher == null) {
+@@ -665,7 +668,8 @@
+ sb.append(string, 0, matcher.start());
+
+ if (function != null) {
+- sb.append(callReplaceValue(function, matcher, string));
++ final Object self = function.isStrict() ? UNDEFINED : Global.instance();
++ sb.append(callReplaceValue(getReplaceValueInvoker(), function, self, matcher, string));
+ } else {
+ appendReplacement(matcher, string, replacement, sb);
+ }
+@@ -683,10 +687,13 @@
+ int previousLastIndex = 0;
+ final StringBuilder sb = new StringBuilder();
+
++ final MethodHandle invoker = function == null ? null : getReplaceValueInvoker();
++ final Object self = function == null || function.isStrict() ? UNDEFINED : Global.instance();
++
+ do {
+ sb.append(string, thisIndex, matcher.start());
+ if (function != null) {
+- sb.append(callReplaceValue(function, matcher, string));
++ sb.append(callReplaceValue(invoker, function, self, matcher, string));
+ } else {
+ appendReplacement(matcher, string, replacement, sb);
+ }
+@@ -746,8 +753,8 @@
+ cursor++;
+ if (cursor < replacement.length() && firstDigit < matcher.groupCount()) {
+ final int secondDigit = replacement.charAt(cursor) - '0';
+- if ((secondDigit >= 0) && (secondDigit <= 9)) {
+- final int newRefNum = (firstDigit * 10) + secondDigit;
++ if (secondDigit >= 0 && secondDigit <= 9) {
++ final int newRefNum = firstDigit * 10 + secondDigit;
+ if (newRefNum <= matcher.groupCount() && newRefNum > 0) {
+ // $nn ($01-$99)
+ refNum = newRefNum;
+@@ -790,16 +797,26 @@
+ }
+ }
+
+- private String callReplaceValue(final ScriptFunction function, final RegExpMatcher matcher, final String string) {
++ private static final Object REPLACE_VALUE = new Object();
++
++ private static final MethodHandle getReplaceValueInvoker() {
++ return Global.instance().getDynamicInvoker(REPLACE_VALUE,
++ new Callable<MethodHandle>() {
++ @Override
++ public MethodHandle call() {
++ return Bootstrap.createDynamicInvoker("dyn:call", String.class, ScriptFunction.class, Object.class, Object[].class);
++ }
++ });
++ }
++
++ private String callReplaceValue(final MethodHandle invoker, final ScriptFunction function, final Object self, final RegExpMatcher matcher, final String string) throws Throwable {
+ final Object[] groups = groups(matcher);
+ final Object[] args = Arrays.copyOf(groups, groups.length + 2);
+
+ args[groups.length] = matcher.start();
+ args[groups.length + 1] = string;
+
+- final Object self = function.isStrict() ? UNDEFINED : Global.instance();
+-
+- return JSType.toString(ScriptRuntime.apply(function, self, args));
++ return (String)invoker.invokeExact(function, self, args);
+ }
+
+ /**
+@@ -908,7 +925,6 @@
+ }
+
+ private static NativeRegExp checkRegExp(final Object self) {
+- Global.checkObjectCoercible(self);
+ if (self instanceof NativeRegExp) {
+ return (NativeRegExp)self;
+ } else if (self != null && self == Global.instance().getRegExpPrototype()) {
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java Wed Feb 04 12:14:47 2015 -0800
+@@ -32,9 +32,9 @@
+ import jdk.nashorn.internal.objects.annotations.Setter;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+-import jdk.nashorn.internal.runtime.regexp.RegExpResult;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
++import jdk.nashorn.internal.runtime.regexp.RegExpResult;
+
+ /**
+ * Objects of this class are used to represent return values from
+@@ -74,7 +74,7 @@
+ @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
+ public static Object length(final Object self) {
+ if (self instanceof ScriptObject) {
+- return ((ScriptObject)self).getArray().length() & JSType.MAX_UINT;
++ return JSType.toUint32(((ScriptObject)self).getArray().length());
+ }
+
+ return 0;
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,8 +25,8 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.lookup.Lookup.MH;
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+-import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+@@ -79,8 +79,9 @@
+ final ScriptFunction func = Global.instance().getTypeErrorThrower();
+ // We have to fill user accessor functions late as these are stored
+ // in this object rather than in the PropertyMap of this object.
+- setUserAccessors("caller", func, func);
+- setUserAccessors("callee", func, func);
++ final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
++ initUserAccessors("caller", flags, func, func);
++ initUserAccessors("callee", flags, func, func);
+
+ setArray(ArrayData.allocate(values));
+ this.length = values.length;
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeString.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeString.java Wed Feb 04 12:14:47 2015 -0800
+@@ -39,6 +39,7 @@
+ import java.util.LinkedList;
+ import java.util.List;
+ import java.util.Locale;
++import java.util.Set;
+ import jdk.internal.dynalink.CallSiteDescriptor;
+ import jdk.internal.dynalink.linker.GuardedInvocation;
+ import jdk.internal.dynalink.linker.LinkRequest;
+@@ -48,11 +49,12 @@
+ import jdk.nashorn.internal.objects.annotations.Function;
+ import jdk.nashorn.internal.objects.annotations.Getter;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+-import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
+ import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
++import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
+ import jdk.nashorn.internal.objects.annotations.Where;
+ import jdk.nashorn.internal.runtime.ConsString;
+ import jdk.nashorn.internal.runtime.JSType;
++import jdk.nashorn.internal.runtime.OptimisticBuiltins;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+@@ -66,13 +68,13 @@
+ * ECMA 15.5 String Objects.
+ */
+ @ScriptClass("String")
+-public final class NativeString extends ScriptObject {
++public final class NativeString extends ScriptObject implements OptimisticBuiltins {
+
+ private final CharSequence value;
+
+- // Method handle to create an object wrapper for a primitive string
+- private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeString.class, Object.class));
+- // Method handle to retrieve the String prototype object
++ /** Method handle to create an object wrapper for a primitive string */
++ static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeString.class, Object.class));
++ /** Method handle to retrieve the String prototype object */
+ private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
+
+ // initialized by nasgen
+@@ -155,10 +157,9 @@
+
+ if (returnType == Object.class && (self instanceof String || self instanceof ConsString)) {
+ try {
+- MethodHandle mh = MH.findStatic(MethodHandles.lookup(), NativeString.class, "get", desc.getMethodType());
+- return new GuardedInvocation(mh, NashornGuards.getInstanceOf2Guard(String.class, ConsString.class));
++ return new GuardedInvocation(MH.findStatic(MethodHandles.lookup(), NativeString.class, "get", desc.getMethodType()), NashornGuards.getInstanceOf2Guard(String.class, ConsString.class));
+ } catch (final LookupException e) {
+- // Shouldn't happen. Fall back to super
++ //empty. Shouldn't happen. Fall back to super
+ }
+ }
+ return super.findGetIndexMethod(desc, request);
+@@ -236,111 +237,111 @@
+ }
+
+ @Override
+- public int getInt(final Object key) {
+- return JSType.toInt32(get(key));
++ public int getInt(final Object key, final int programPoint) {
++ return JSType.toInt32MaybeOptimistic(get(key), programPoint);
+ }
+
+ @Override
+- public int getInt(final double key) {
+- return JSType.toInt32(get(key));
++ public int getInt(final double key, final int programPoint) {
++ return JSType.toInt32MaybeOptimistic(get(key), programPoint);
+ }
+
+ @Override
+- public int getInt(final long key) {
+- return JSType.toInt32(get(key));
++ public int getInt(final long key, final int programPoint) {
++ return JSType.toInt32MaybeOptimistic(get(key), programPoint);
+ }
+
+ @Override
+- public int getInt(final int key) {
+- return JSType.toInt32(get(key));
++ public int getInt(final int key, final int programPoint) {
++ return JSType.toInt32MaybeOptimistic(get(key), programPoint);
+ }
+
+ @Override
+- public long getLong(final Object key) {
+- return JSType.toUint32(get(key));
++ public long getLong(final Object key, final int programPoint) {
++ return JSType.toLongMaybeOptimistic(get(key), programPoint);
+ }
+
+ @Override
+- public long getLong(final double key) {
+- return JSType.toUint32(get(key));
++ public long getLong(final double key, final int programPoint) {
++ return JSType.toLongMaybeOptimistic(get(key), programPoint);
+ }
+
+ @Override
+- public long getLong(final long key) {
+- return JSType.toUint32(get(key));
++ public long getLong(final long key, final int programPoint) {
++ return JSType.toLongMaybeOptimistic(get(key), programPoint);
+ }
+
+ @Override
+- public long getLong(final int key) {
+- return JSType.toUint32(get(key));
++ public long getLong(final int key, final int programPoint) {
++ return JSType.toLongMaybeOptimistic(get(key), programPoint);
+ }
+
+ @Override
+- public double getDouble(final Object key) {
+- return JSType.toNumber(get(key));
++ public double getDouble(final Object key, final int programPoint) {
++ return JSType.toNumberMaybeOptimistic(get(key), programPoint);
+ }
+
+ @Override
+- public double getDouble(final double key) {
+- return JSType.toNumber(get(key));
++ public double getDouble(final double key, final int programPoint) {
++ return JSType.toNumberMaybeOptimistic(get(key), programPoint);
+ }
+
+ @Override
+- public double getDouble(final long key) {
+- return JSType.toNumber(get(key));
++ public double getDouble(final long key, final int programPoint) {
++ return JSType.toNumberMaybeOptimistic(get(key), programPoint);
+ }
+
+ @Override
+- public double getDouble(final int key) {
+- return JSType.toNumber(get(key));
++ public double getDouble(final int key, final int programPoint) {
++ return JSType.toNumberMaybeOptimistic(get(key), programPoint);
+ }
+
+ @Override
+ public boolean has(final Object key) {
+ final Object primitiveKey = JSType.toPrimitive(key, String.class);
+ final int index = ArrayIndex.getArrayIndex(primitiveKey);
+- return isValid(index) || super.has(primitiveKey);
++ return isValidStringIndex(index) || super.has(primitiveKey);
+ }
+
+ @Override
+ public boolean has(final int key) {
+- return isValid(key) || super.has(key);
++ return isValidStringIndex(key) || super.has(key);
+ }
+
+ @Override
+ public boolean has(final long key) {
+ final int index = ArrayIndex.getArrayIndex(key);
+- return isValid(index) || super.has(key);
++ return isValidStringIndex(index) || super.has(key);
+ }
+
+ @Override
+ public boolean has(final double key) {
+ final int index = ArrayIndex.getArrayIndex(key);
+- return isValid(index) || super.has(key);
++ return isValidStringIndex(index) || super.has(key);
+ }
+
+ @Override
+ public boolean hasOwnProperty(final Object key) {
+ final Object primitiveKey = JSType.toPrimitive(key, String.class);
+ final int index = ArrayIndex.getArrayIndex(primitiveKey);
+- return isValid(index) || super.hasOwnProperty(primitiveKey);
++ return isValidStringIndex(index) || super.hasOwnProperty(primitiveKey);
+ }
+
+ @Override
+ public boolean hasOwnProperty(final int key) {
+- return isValid(key) || super.hasOwnProperty(key);
++ return isValidStringIndex(key) || super.hasOwnProperty(key);
+ }
+
+ @Override
+ public boolean hasOwnProperty(final long key) {
+ final int index = ArrayIndex.getArrayIndex(key);
+- return isValid(index) || super.hasOwnProperty(key);
++ return isValidStringIndex(index) || super.hasOwnProperty(key);
+ }
+
+ @Override
+ public boolean hasOwnProperty(final double key) {
+ final int index = ArrayIndex.getArrayIndex(key);
+- return isValid(index) || super.hasOwnProperty(key);
++ return isValidStringIndex(index) || super.hasOwnProperty(key);
+ }
+
+ @Override
+@@ -368,7 +369,7 @@
+ }
+
+ private boolean checkDeleteIndex(final int index, final boolean strict) {
+- if (isValid(index)) {
++ if (isValidStringIndex(index)) {
+ if (strict) {
+ throw typeError("cant.delete.property", Integer.toString(index), ScriptRuntime.safeToString(this));
+ }
+@@ -392,10 +393,12 @@
+ /**
+ * return a List of own keys associated with the object.
+ * @param all True if to include non-enumerable keys.
++ * @param nonEnumerable set of non-enumerable properties seen already.Used
++ * to filter out shadowed, but enumerable properties from proto children.
+ * @return Array of keys.
+ */
+ @Override
+- public String[] getOwnKeys(final boolean all) {
++ protected String[] getOwnKeys(final boolean all, final Set<String> nonEnumerable) {
+ final List<Object> keys = new ArrayList<>();
+
+ // add string index keys
+@@ -404,7 +407,7 @@
+ }
+
+ // add super class properties
+- keys.addAll(Arrays.asList(super.getOwnKeys(all)));
++ keys.addAll(Arrays.asList(super.getOwnKeys(all, nonEnumerable)));
+ return keys.toArray(new String[keys.size()]);
+ }
+
+@@ -441,12 +444,11 @@
+ * @return string with one charcode
+ */
+ @SpecializedFunction
+- public static String fromCharCode(final Object self, final Object value) {
+- try {
+- return "" + (char)JSType.toUint16(((Number)value).doubleValue());
+- } catch (final ClassCastException e) {
+- return fromCharCode(self, new Object[] { value });
++ public static Object fromCharCode(final Object self, final Object value) {
++ if (value instanceof Integer) {
++ return fromCharCode(self, (int)value);
+ }
++ return Character.toString((char)JSType.toUint16(value));
+ }
+
+ /**
+@@ -457,18 +459,46 @@
+ */
+ @SpecializedFunction
+ public static String fromCharCode(final Object self, final int value) {
+- return "" + (char)(value & 0xffff);
++ return Character.toString((char)(value & 0xffff));
+ }
+
+ /**
+- * ECMA 15.5.3.2 - specialization for one char of long type
++ * ECMA 15.5.3.2 - specialization for two chars of int type
+ * @param self self reference
+- * @param value one argument to be interpreted as char
++ * @param ch1 first char
++ * @param ch2 second char
+ * @return string with one charcode
+ */
+ @SpecializedFunction
+- public static String fromCharCode(final Object self, final long value) {
+- return "" + (char)((int)value & 0xffff);
++ public static Object fromCharCode(final Object self, final int ch1, final int ch2) {
++ return Character.toString((char)(ch1 & 0xffff)) + Character.toString((char)(ch2 & 0xffff));
++ }
++
++ /**
++ * ECMA 15.5.3.2 - specialization for three chars of int type
++ * @param self self reference
++ * @param ch1 first char
++ * @param ch2 second char
++ * @param ch3 third char
++ * @return string with one charcode
++ */
++ @SpecializedFunction
++ public static Object fromCharCode(final Object self, final int ch1, final int ch2, final int ch3) {
++ return Character.toString((char)(ch1 & 0xffff)) + Character.toString((char)(ch2 & 0xffff)) + Character.toString((char)(ch3 & 0xffff));
++ }
++
++ /**
++ * ECMA 15.5.3.2 - specialization for four chars of int type
++ * @param self self reference
++ * @param ch1 first char
++ * @param ch2 second char
++ * @param ch3 third char
++ * @param ch4 fourth char
++ * @return string with one charcode
++ */
++ @SpecializedFunction
++ public static String fromCharCode(final Object self, final int ch1, final int ch2, final int ch3, final int ch4) {
++ return Character.toString((char)(ch1 & 0xffff)) + Character.toString((char)(ch2 & 0xffff)) + Character.toString((char)(ch3 & 0xffff)) + Character.toString((char)(ch4 & 0xffff));
+ }
+
+ /**
+@@ -479,7 +509,7 @@
+ */
+ @SpecializedFunction
+ public static String fromCharCode(final Object self, final double value) {
+- return "" + (char)JSType.toUint16(value);
++ return Character.toString((char)JSType.toUint16(value));
+ }
+
+ /**
+@@ -536,7 +566,15 @@
+ }
+
+ private static String charAtImpl(final String str, final int pos) {
+- return (pos < 0 || pos >= str.length()) ? "" : String.valueOf(str.charAt(pos));
++ return pos < 0 || pos >= str.length() ? "" : String.valueOf(str.charAt(pos));
++ }
++
++ private static int getValidChar(final Object self, final int pos) {
++ try {
++ return ((CharSequence)self).charAt(pos);
++ } catch (final IndexOutOfBoundsException e) {
++ throw new ClassCastException(); //invalid char, out of bounds, force relink
++ }
+ }
+
+ /**
+@@ -547,7 +585,9 @@
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
+ public static double charCodeAt(final Object self, final Object pos) {
+- return charCodeAtImpl(checkObjectToString(self), JSType.toInteger(pos));
++ final String str = checkObjectToString(self);
++ final int idx = JSType.toInteger(pos);
++ return idx < 0 || idx >= str.length() ? Double.NaN : str.charAt(idx);
+ }
+
+ /**
+@@ -556,9 +596,20 @@
+ * @param pos position in string
+ * @return number representing charcode at position
+ */
+- @SpecializedFunction
+- public static double charCodeAt(final Object self, final double pos) {
+- return charCodeAt(self, (int) pos);
++ @SpecializedFunction(linkLogic=CharCodeAtLinkLogic.class)
++ public static int charCodeAt(final Object self, final double pos) {
++ return charCodeAt(self, (int)pos); //toInt pos is ok
++ }
++
++ /**
++ * ECMA 15.5.4.5 String.prototype.charCodeAt (pos) - specialized version for long position
++ * @param self self reference
++ * @param pos position in string
++ * @return number representing charcode at position
++ */
++ @SpecializedFunction(linkLogic=CharCodeAtLinkLogic.class)
++ public static int charCodeAt(final Object self, final long pos) {
++ return charCodeAt(self, (int)pos);
+ }
+
+ /**
+@@ -567,13 +618,10 @@
+ * @param pos position in string
+ * @return number representing charcode at position
+ */
+- @SpecializedFunction
+- public static double charCodeAt(final Object self, final int pos) {
+- return charCodeAtImpl(checkObjectToString(self), pos);
+- }
+
+- private static double charCodeAtImpl(final String str, final int pos) {
+- return (pos < 0 || pos >= str.length()) ? Double.NaN : str.charAt(pos);
++ @SpecializedFunction(linkLogic=CharCodeAtLinkLogic.class)
++ public static int charCodeAt(final Object self, final int pos) {
++ return getValidChar(self, pos);
+ }
+
+ /**
+@@ -688,7 +736,7 @@
+ collator.setStrength(Collator.IDENTICAL);
+ collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
+
+- return (double)collator.compare(str, JSType.toString(that));
++ return collator.compare(str, JSType.toString(that));
+ }
+
+ /**
+@@ -743,9 +791,10 @@
+ * @param string item to replace
+ * @param replacement item to replace it with
+ * @return string after replacement
++ * @throws Throwable if replacement fails
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
+- public static String replace(final Object self, final Object string, final Object replacement) {
++ public static String replace(final Object self, final Object string, final Object replacement) throws Throwable {
+
+ final String str = checkObjectToString(self);
+
+@@ -807,7 +856,7 @@
+ @SpecializedFunction
+ public static String slice(final Object self, final int start) {
+ final String str = checkObjectToString(self);
+- final int from = (start < 0) ? Math.max(str.length() + start, 0) : Math.min(start, str.length());
++ final int from = start < 0 ? Math.max(str.length() + start, 0) : Math.min(start, str.length());
+
+ return str.substring(from);
+ }
+@@ -838,8 +887,8 @@
+ final String str = checkObjectToString(self);
+ final int len = str.length();
+
+- final int from = (start < 0) ? Math.max(len + start, 0) : Math.min(start, len);
+- final int to = (end < 0) ? Math.max(len + end, 0) : Math.min(end, len);
++ final int from = start < 0 ? Math.max(len + start, 0) : Math.min(start, len);
++ final int to = end < 0 ? Math.max(len + end, 0) : Math.min(end, len);
+
+ return str.substring(Math.min(from, to), to);
+ }
+@@ -868,7 +917,7 @@
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
+ public static ScriptObject split(final Object self, final Object separator, final Object limit) {
+ final String str = checkObjectToString(self);
+- final long lim = (limit == UNDEFINED) ? JSType.MAX_UINT : JSType.toUint32(limit);
++ final long lim = limit == UNDEFINED ? JSType.MAX_UINT : JSType.toUint32(limit);
+
+ if (separator == UNDEFINED) {
+ return lim == 0 ? new NativeArray() : new NativeArray(new Object[]{str});
+@@ -882,7 +931,7 @@
+ return splitString(str, JSType.toString(separator), lim);
+ }
+
+- private static ScriptObject splitString(String str, String separator, long limit) {
++ private static ScriptObject splitString(final String str, final String separator, final long limit) {
+ if (separator.isEmpty()) {
+ final int length = (int) Math.min(str.length(), limit);
+ final Object[] array = new Object[length];
+@@ -899,7 +948,7 @@
+ int n = 0;
+
+ while (pos < strLength && n < limit) {
+- int found = str.indexOf(separator, pos);
++ final int found = str.indexOf(separator, pos);
+ if (found == -1) {
+ break;
+ }
+@@ -932,7 +981,7 @@
+ intStart = Math.max(intStart + strLength, 0);
+ }
+
+- final int intLen = Math.min(Math.max((length == UNDEFINED) ? Integer.MAX_VALUE : JSType.toInteger(length), 0), strLength - intStart);
++ final int intLen = Math.min(Math.max(length == UNDEFINED ? Integer.MAX_VALUE : JSType.toInteger(length), 0), strLength - intStart);
+
+ return intLen <= 0 ? "" : str.substring(intStart, intStart + intLen);
+ }
+@@ -998,8 +1047,8 @@
+ public static String substring(final Object self, final int start, final int end) {
+ final String str = checkObjectToString(self);
+ final int len = str.length();
+- final int validStart = start < 0 ? 0 : (start > len ? len : start);
+- final int validEnd = end < 0 ? 0 : (end > len ? len : end);
++ final int validStart = start < 0 ? 0 : start > len ? len : start;
++ final int validEnd = end < 0 ? 0 : end > len ? len : end;
+
+ if (validStart < validEnd) {
+ return str.substring(validStart, validEnd);
+@@ -1067,7 +1116,6 @@
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
+ public static String trim(final Object self) {
+-
+ final String str = checkObjectToString(self);
+ int start = 0;
+ int end = str.length() - 1;
+@@ -1092,7 +1140,7 @@
+
+ final String str = checkObjectToString(self);
+ int start = 0;
+- int end = str.length() - 1;
++ final int end = str.length() - 1;
+
+ while (start <= end && ScriptRuntime.isJSWhitespace(str.charAt(start))) {
+ start++;
+@@ -1110,7 +1158,7 @@
+ public static String trimRight(final Object self) {
+
+ final String str = checkObjectToString(self);
+- int start = 0;
++ final int start = 0;
+ int end = str.length() - 1;
+
+ while (end >= start && ScriptRuntime.isJSWhitespace(str.charAt(end))) {
+@@ -1120,7 +1168,7 @@
+ return str.substring(start, end + 1);
+ }
+
+- private static ScriptObject newObj(final Object self, final CharSequence str) {
++ private static ScriptObject newObj(final CharSequence str) {
+ return new NativeString(str);
+ }
+
+@@ -1137,8 +1185,8 @@
+ */
+ @Constructor(arity = 1)
+ public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+- final CharSequence str = (args.length > 0) ? JSType.toCharSequence(args[0]) : "";
+- return newObj ? newObj(self, str) : str.toString();
++ final CharSequence str = args.length > 0 ? JSType.toCharSequence(args[0]) : "";
++ return newObj ? newObj(str) : str.toString();
+ }
+
+ /**
+@@ -1151,9 +1199,9 @@
+ *
+ * @return new NativeString ("")
+ */
+- @SpecializedConstructor
++ @SpecializedFunction(isConstructor=true)
+ public static Object constructor(final boolean newObj, final Object self) {
+- return newObj ? newObj(self, "") : "";
++ return newObj ? newObj("") : "";
+ }
+
+ /**
+@@ -1167,10 +1215,10 @@
+ *
+ * @return new NativeString (arg)
+ */
+- @SpecializedConstructor
++ @SpecializedFunction(isConstructor=true)
+ public static Object constructor(final boolean newObj, final Object self, final Object arg) {
+ final CharSequence str = JSType.toCharSequence(arg);
+- return newObj ? newObj(self, str) : str.toString();
++ return newObj ? newObj(str) : str.toString();
+ }
+
+ /**
+@@ -1184,10 +1232,61 @@
+ *
+ * @return new NativeString containing the string representation of the arg
+ */
+- @SpecializedConstructor
++ @SpecializedFunction(isConstructor=true)
+ public static Object constructor(final boolean newObj, final Object self, final int arg) {
++ final String str = Integer.toString(arg);
++ return newObj ? newObj(str) : str;
++ }
++
++ /**
++ * ECMA 15.5.2.1 new String ( [ value ] ) - special version with exactly one {@code int} arg
++ *
++ * Constructor
++ *
++ * @param newObj is this constructor invoked with the new operator
++ * @param self self reference
++ * @param arg the arg
++ *
++ * @return new NativeString containing the string representation of the arg
++ */
++ @SpecializedFunction(isConstructor=true)
++ public static Object constructor(final boolean newObj, final Object self, final long arg) {
++ final String str = Long.toString(arg);
++ return newObj ? newObj(str) : str;
++ }
++
++ /**
++ * ECMA 15.5.2.1 new String ( [ value ] ) - special version with exactly one {@code int} arg
++ *
++ * Constructor
++ *
++ * @param newObj is this constructor invoked with the new operator
++ * @param self self reference
++ * @param arg the arg
++ *
++ * @return new NativeString containing the string representation of the arg
++ */
++ @SpecializedFunction(isConstructor=true)
++ public static Object constructor(final boolean newObj, final Object self, final double arg) {
+ final String str = JSType.toString(arg);
+- return newObj ? newObj(self, str) : str;
++ return newObj ? newObj(str) : str;
++ }
++
++ /**
++ * ECMA 15.5.2.1 new String ( [ value ] ) - special version with exactly one {@code boolean} arg
++ *
++ * Constructor
++ *
++ * @param newObj is this constructor invoked with the new operator
++ * @param self self reference
++ * @param arg the arg
++ *
++ * @return new NativeString containing the string representation of the arg
++ */
++ @SpecializedFunction(isConstructor=true)
++ public static Object constructor(final boolean newObj, final Object self, final boolean arg) {
++ final String str = Boolean.toString(arg);
++ return newObj ? newObj(str) : str;
+ }
+
+ /**
+@@ -1234,7 +1333,7 @@
+ } else if (self != null && self == Global.instance().getStringPrototype()) {
+ return "";
+ } else {
+- throw typeError( "not.a.string", ScriptRuntime.safeToString(self));
++ throw typeError("not.a.string", ScriptRuntime.safeToString(self));
+ }
+ }
+
+@@ -1255,11 +1354,57 @@
+ }
+ }
+
+- private boolean isValid(final int key) {
++ private boolean isValidStringIndex(final int key) {
+ return key >= 0 && key < value.length();
+ }
+
+ private static MethodHandle findOwnMH(final String name, final MethodType type) {
+ return MH.findStatic(MethodHandles.lookup(), NativeString.class, name, type);
+ }
++
++ @Override
++ public LinkLogic getLinkLogic(final Class<? extends LinkLogic> clazz) {
++ if (clazz == CharCodeAtLinkLogic.class) {
++ return CharCodeAtLinkLogic.INSTANCE;
++ }
++ return null;
++ }
++
++ @Override
++ public boolean hasPerInstanceAssumptions() {
++ return false;
++ }
++
++ /**
++ * This is linker logic charCodeAt - when we specialize further methods in NativeString
++ * It may be expanded. It's link check makes sure that we are dealing with a char
++ * sequence and that we are in range
++ */
++ private static final class CharCodeAtLinkLogic extends SpecializedFunction.LinkLogic {
++ private static final CharCodeAtLinkLogic INSTANCE = new CharCodeAtLinkLogic();
++
++ @Override
++ public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
++ try {
++ //check that it's a char sequence or throw cce
++ final CharSequence cs = (CharSequence)self;
++ //check that the index, representable as an int, is inside the array
++ final int intIndex = JSType.toInteger(request.getArguments()[2]);
++ return intIndex >= 0 && intIndex < cs.length(); //can link
++ } catch (final ClassCastException | IndexOutOfBoundsException e) {
++ //fallthru
++ }
++ return false;
++ }
++
++ /**
++ * charCodeAt callsites can throw ClassCastException as a mechanism to have them
++ * relinked - this enabled fast checks of the kind of ((IntArrayData)arrayData).push(x)
++ * for an IntArrayData only push - if this fails, a CCE will be thrown and we will relink
++ */
++ @Override
++ public Class<? extends Throwable> getRelinkException() {
++ return ClassCastException.class;
++ }
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,15 +25,23 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
++
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.nio.ByteBuffer;
++import java.nio.CharBuffer;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+ import jdk.nashorn.internal.objects.annotations.Function;
+ import jdk.nashorn.internal.objects.annotations.Property;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+ import jdk.nashorn.internal.objects.annotations.Where;
++import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
++import jdk.nashorn.internal.runtime.arrays.TypedArrayData;
+
+ /**
+ * Uint16 array for TypedArray extension
+@@ -55,37 +63,125 @@
+ public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+ return new NativeUint16Array(buffer, byteOffset, length);
+ }
++
+ @Override
+- public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+- return new Uint16ArrayData(buffer, byteOffset, length);
++ public Uint16ArrayData createArrayData(final ByteBuffer nb, final int start, final int end) {
++ return new Uint16ArrayData(nb.asCharBuffer(), start, end);
++ }
++
++ @Override
++ public String getClassName() {
++ return "Uint16Array";
+ }
+ };
+
+- private static final class Uint16ArrayData extends ArrayDataImpl {
+- private Uint16ArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+- super(buffer, byteOffset, elementLength);
++ private static final class Uint16ArrayData extends TypedArrayData<CharBuffer> {
++
++ private static final MethodHandle GET_ELEM = specialCall(MethodHandles.lookup(), Uint16ArrayData.class, "getElem", int.class, int.class).methodHandle();
++ private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Uint16ArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
++
++ private Uint16ArrayData(final CharBuffer nb, final int start, final int end) {
++ super(((CharBuffer)nb.position(start).limit(end)).slice(), end - start);
+ }
+
+ @Override
+- protected int byteIndex(final int index) {
+- return index * BYTES_PER_ELEMENT + byteOffset;
++ protected MethodHandle getGetElem() {
++ return GET_ELEM;
+ }
+
+ @Override
+- protected int getIntImpl(final int index) {
+- final int byteIndex = byteIndex(index);
+- final byte[] byteArray = buffer.getByteArray();
+- return byteArray[byteIndex ] & 0x0000_00ff |
+- byteArray[byteIndex+1] << 8 & 0x0000_ff00 ;
++ protected MethodHandle getSetElem() {
++ return SET_ELEM;
++ }
++
++ private int getElem(final int index) {
++ try {
++ return nb.get(index);
++ } catch (final IndexOutOfBoundsException e) {
++ throw new ClassCastException(); //force relink - this works for unoptimistic too
++ }
++ }
++
++ private void setElem(final int index, final int elem) {
++ try {
++ nb.put(index, (char)elem);
++ } catch (final IndexOutOfBoundsException e) {
++ //swallow valid array indexes. it's ok.
++ if (index < 0) {
++ throw new ClassCastException();
++ }
++ }
+ }
+
+ @Override
+- protected void setImpl(final int index, final int value) {
+- final int byteIndex = byteIndex(index);
+- @SuppressWarnings("MismatchedReadAndWriteOfArray")
+- final byte[] byteArray = buffer.getByteArray();
+- byteArray[byteIndex ] = (byte)(value & 0xff);
+- byteArray[byteIndex+1] = (byte)(value >>> 8 & 0xff);
++ public boolean isUnsigned() {
++ return true;
++ }
++
++ @Override
++ public Class<?> getElementType() {
++ return int.class;
++ }
++
++ @Override
++ public Class<?> getBoxedElementType() {
++ return Integer.class;
++ }
++
++ @Override
++ public int getInt(final int index) {
++ return getElem(index);
++ }
++
++ @Override
++ public int getIntOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public long getLong(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public long getLongOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public double getDouble(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public Object getObject(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public ArrayData set(final int index, final Object value, final boolean strict) {
++ return set(index, JSType.toInt32(value), strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final int value, final boolean strict) {
++ setElem(index, value);
++ return this;
++ }
++
++ @Override
++ public ArrayData set(final int index, final long value, final boolean strict) {
++ return set(index, (int)value, strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final double value, final boolean strict) {
++ return set(index, (int)value, strict);
+ }
+ }
+
+@@ -100,7 +196,7 @@
+ */
+ @Constructor(arity = 1)
+ public static NativeUint16Array constructor(final boolean newObj, final Object self, final Object... args) {
+- return (NativeUint16Array)constructorImpl(args, FACTORY);
++ return (NativeUint16Array)constructorImpl(newObj, args, FACTORY);
+ }
+
+ NativeUint16Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+@@ -108,11 +204,6 @@
+ }
+
+ @Override
+- public String getClassName() {
+- return "Uint16Array";
+- }
+-
+- @Override
+ protected Factory factory() {
+ return FACTORY;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,13 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
++
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.nio.ByteBuffer;
++import java.nio.ByteOrder;
++import java.nio.IntBuffer;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+ import jdk.nashorn.internal.objects.annotations.Function;
+@@ -35,6 +42,7 @@
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
++import jdk.nashorn.internal.runtime.arrays.TypedArrayData;
+
+ /**
+ * Uint32 array for TypedArray extension
+@@ -56,55 +64,128 @@
+ public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteBegin, final int length) {
+ return new NativeUint32Array(buffer, byteBegin, length);
+ }
++
+ @Override
+- public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+- return new Uint32ArrayData(buffer, byteOffset, length);
++ public Uint32ArrayData createArrayData(final ByteBuffer nb, final int start, final int end) {
++ return new Uint32ArrayData(nb.order(ByteOrder.nativeOrder()).asIntBuffer(), start, end);
++ }
++
++ @Override
++ public String getClassName() {
++ return "Uint32Array";
+ }
+ };
+
+- private static final class Uint32ArrayData extends ArrayDataImpl {
+- private Uint32ArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+- super(buffer, byteOffset, elementLength);
++ private static final class Uint32ArrayData extends TypedArrayData<IntBuffer> {
++
++ private static final MethodHandle GET_ELEM = specialCall(MethodHandles.lookup(), Uint32ArrayData.class, "getElem", long.class, int.class).methodHandle();
++ private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Uint32ArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
++
++ private Uint32ArrayData(final IntBuffer nb, final int start, final int end) {
++ super(((IntBuffer)nb.position(start).limit(end)).slice(), end - start);
+ }
+
+ @Override
+- protected int byteIndex(final int index) {
+- return index * BYTES_PER_ELEMENT + byteOffset;
++ protected MethodHandle getGetElem() {
++ return GET_ELEM;
+ }
+
+ @Override
+- protected int getIntImpl(final int index) {
+- final int byteIndex = byteIndex(index);
+- final byte[] byteArray = buffer.getByteArray();
+- return byteArray[byteIndex ] & 0x0000_00ff |
+- byteArray[byteIndex+1] << 8 & 0x0000_ff00 |
+- byteArray[byteIndex+2] << 16 & 0x00ff_0000 |
+- byteArray[byteIndex+3] << 24 & 0xff00_0000 ;
++ protected MethodHandle getSetElem() {
++ return SET_ELEM;
+ }
+
+ @Override
+- protected long getLongImpl(final int key) {
+- return getIntImpl(key) & JSType.MAX_UINT;
++ public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
++ if (returnType == int.class) {
++ return null;
++ }
++ return getContinuousElementGetter(getClass(), GET_ELEM, returnType, programPoint);
++ }
++
++ private long getElem(final int index) {
++ try {
++ return JSType.toUint32(nb.get(index));
++ } catch (final IndexOutOfBoundsException e) {
++ throw new ClassCastException(); //force relink - this works for unoptimistic too
++ }
++ }
++
++ private void setElem(final int index, final int elem) {
++ try {
++ nb.put(index, elem);
++ } catch (final IndexOutOfBoundsException e) {
++ //swallow valid array indexes. it's ok.
++ if (index < 0) {
++ throw new ClassCastException();
++ }
++ }
+ }
+
+ @Override
+- protected double getDoubleImpl(final int key) {
+- return getIntImpl(key) & JSType.MAX_UINT;
++ public boolean isUnsigned() {
++ return true;
+ }
+
+ @Override
+- protected Object getObjectImpl(final int key) {
+- return getIntImpl(key) & JSType.MAX_UINT;
++ public Class<?> getElementType() {
++ return long.class;
+ }
+
+ @Override
+- protected void setImpl(final int index, final int value) {
+- final int byteIndex = byteIndex(index);
+- final byte[] byteArray = buffer.getByteArray();
+- byteArray[byteIndex ] = (byte)(value & 0xff);
+- byteArray[byteIndex+1] = (byte)(value >>> 8 & 0xff);
+- byteArray[byteIndex+2] = (byte)(value >>> 16 & 0xff);
+- byteArray[byteIndex+3] = (byte)(value >>> 24 & 0xff);
++ public Class<?> getBoxedElementType() {
++ return Integer.class;
++ }
++
++ @Override
++ public int getInt(final int index) {
++ return (int)getLong(index);
++ }
++
++ @Override
++ public long getLong(final int index) {
++ return getElem(index);
++ }
++
++ @Override
++ public long getLongOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public double getDouble(final int index) {
++ return getLong(index);
++ }
++
++ @Override
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ return getLong(index);
++ }
++
++ @Override
++ public Object getObject(final int index) {
++ return getLong(index);
++ }
++
++ @Override
++ public ArrayData set(final int index, final Object value, final boolean strict) {
++ return set(index, JSType.toInt32(value), strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final int value, final boolean strict) {
++ setElem(index, value);
++ return this;
++ }
++
++ @Override
++ public ArrayData set(final int index, final long value, final boolean strict) {
++ return set(index, (int)value, strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final double value, final boolean strict) {
++ return set(index, (int)value, strict);
+ }
+ }
+
+@@ -119,7 +200,7 @@
+ */
+ @Constructor(arity = 1)
+ public static NativeUint32Array constructor(final boolean newObj, final Object self, final Object... args) {
+- return (NativeUint32Array)constructorImpl(args, FACTORY);
++ return (NativeUint32Array)constructorImpl(newObj, args, FACTORY);
+ }
+
+ NativeUint32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+@@ -127,11 +208,6 @@
+ }
+
+ @Override
+- public String getClassName() {
+- return "Uint32Array";
+- }
+-
+- @Override
+ protected Factory factory() {
+ return FACTORY;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,21 +25,29 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
++
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.nio.ByteBuffer;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+ import jdk.nashorn.internal.objects.annotations.Function;
+ import jdk.nashorn.internal.objects.annotations.Property;
+ import jdk.nashorn.internal.objects.annotations.ScriptClass;
+ import jdk.nashorn.internal.objects.annotations.Where;
++import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
++import jdk.nashorn.internal.runtime.arrays.TypedArrayData;
+
+ /**
+ * Uint8 array for TypedArray extension
+ */
+ @ScriptClass("Uint8Array")
+ public final class NativeUint8Array extends ArrayBufferView {
++
+ /**
+ * The size in bytes of each element in the array.
+ */
+@@ -55,31 +63,127 @@
+ public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+ return new NativeUint8Array(buffer, byteOffset, length);
+ }
++
+ @Override
+- public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+- return new Uint8ArrayData(buffer, byteOffset, length);
++ public Uint8ArrayData createArrayData(final ByteBuffer nb, final int start, final int end) {
++ return new Uint8ArrayData(nb, start, end);
++ }
++
++ @Override
++ public String getClassName() {
++ return "Uint8Array";
+ }
+ };
+
+- private static final class Uint8ArrayData extends ArrayDataImpl {
+- private Uint8ArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+- super(buffer, byteOffset, elementLength);
++ private static final class Uint8ArrayData extends TypedArrayData<ByteBuffer> {
++
++ private static final MethodHandle GET_ELEM = specialCall(MethodHandles.lookup(), Uint8ArrayData.class, "getElem", int.class, int.class).methodHandle();
++ private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Uint8ArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
++
++ private Uint8ArrayData(final ByteBuffer nb, final int start, final int end) {
++ super(((ByteBuffer)nb.position(start).limit(end)).slice(), end - start);
+ }
+
+ @Override
+- protected int byteIndex(final int index) {
+- return index * BYTES_PER_ELEMENT + byteOffset;
++ protected MethodHandle getGetElem() {
++ return GET_ELEM;
+ }
+
+ @Override
+- protected int getIntImpl(final int index) {
+- return buffer.getByteArray()[byteIndex(index)] & 0xff;
++ protected MethodHandle getSetElem() {
++ return SET_ELEM;
++ }
++
++ private int getElem(final int index) {
++ try {
++ return nb.get(index) & 0xff;
++ } catch (final IndexOutOfBoundsException e) {
++ throw new ClassCastException(); //force relink - this works for unoptimistic too
++ }
++ }
++
++ private void setElem(final int index, final int elem) {
++ try {
++ nb.put(index, (byte)elem);
++ } catch (final IndexOutOfBoundsException e) {
++ //swallow valid array indexes. it's ok.
++ if (index < 0) {
++ throw new ClassCastException();
++ }
++ }
+ }
+
+ @Override
+- protected void setImpl(final int index, final int value) {
+- buffer.getByteArray()[byteIndex(index)] = (byte)value;
++ public boolean isUnsigned() {
++ return true;
+ }
++
++ @Override
++ public Class<?> getElementType() {
++ return int.class;
++ }
++
++ @Override
++ public Class<?> getBoxedElementType() {
++ return Integer.class;
++ }
++
++ @Override
++ public int getInt(final int index) {
++ return getElem(index);
++ }
++
++ @Override
++ public int getIntOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public long getLong(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public long getLongOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public double getDouble(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public Object getObject(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public ArrayData set(final int index, final Object value, final boolean strict) {
++ return set(index, JSType.toInt32(value), strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final int value, final boolean strict) {
++ setElem(index, value);
++ return this;
++ }
++
++ @Override
++ public ArrayData set(final int index, final long value, final boolean strict) {
++ return set(index, (int)value, strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final double value, final boolean strict) {
++ return set(index, (int)value, strict);
++ }
++
+ }
+
+ /**
+@@ -93,7 +197,7 @@
+ */
+ @Constructor(arity = 1)
+ public static NativeUint8Array constructor(final boolean newObj, final Object self, final Object... args) {
+- return (NativeUint8Array)constructorImpl(args, FACTORY);
++ return (NativeUint8Array)constructorImpl(newObj, args, FACTORY);
+ }
+
+ NativeUint8Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+@@ -101,11 +205,6 @@
+ }
+
+ @Override
+- public String getClassName() {
+- return "Uint8Array";
+- }
+-
+- @Override
+ protected Factory factory() {
+ return FACTORY;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,13 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
++import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
++import static jdk.nashorn.internal.lookup.Lookup.MH;
++
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.nio.ByteBuffer;
+ import jdk.nashorn.internal.objects.annotations.Attribute;
+ import jdk.nashorn.internal.objects.annotations.Constructor;
+ import jdk.nashorn.internal.objects.annotations.Function;
+@@ -35,6 +42,7 @@
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
++import jdk.nashorn.internal.runtime.arrays.TypedArrayData;
+
+ /**
+ * Uint8 clamped array for TypedArray extension
+@@ -56,55 +64,173 @@
+ public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+ return new NativeUint8ClampedArray(buffer, byteOffset, length);
+ }
++
+ @Override
+- public ArrayData createArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+- return new Uint8ClampedArrayData(buffer, byteOffset, length);
++ public Uint8ClampedArrayData createArrayData(final ByteBuffer nb, final int start, final int end) {
++ return new Uint8ClampedArrayData(nb, start, end);
++ }
++
++ @Override
++ public String getClassName() {
++ return "Uint8ClampedArray";
+ }
+ };
+
+- private static final class Uint8ClampedArrayData extends ArrayDataImpl {
+- private Uint8ClampedArrayData(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+- super(buffer, byteOffset, elementLength);
++ private static final class Uint8ClampedArrayData extends TypedArrayData<ByteBuffer> {
++
++ private static final MethodHandle GET_ELEM = specialCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "getElem", int.class, int.class).methodHandle();
++ private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
++ private static final MethodHandle RINT_D = staticCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "rint", double.class, double.class).methodHandle();
++ private static final MethodHandle RINT_O = staticCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "rint", Object.class, Object.class).methodHandle();
++ private static final MethodHandle CLAMP_LONG = staticCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "clampLong", long.class, long.class).methodHandle();
++
++ private Uint8ClampedArrayData(final ByteBuffer nb, final int start, final int end) {
++ super(((ByteBuffer)nb.position(start).limit(end)).slice(), end - start);
+ }
+
+ @Override
+- protected int byteIndex(final int index) {
+- return index * BYTES_PER_ELEMENT + byteOffset;
++ protected MethodHandle getGetElem() {
++ return GET_ELEM;
+ }
+
+ @Override
+- protected int getIntImpl(final int index) {
+- return buffer.getByteArray()[byteIndex(index)] & 0xff;
++ protected MethodHandle getSetElem() {
++ return SET_ELEM;
+ }
+
+ @Override
+- protected void setImpl(final int index, final int value) {
+- final byte clamped;
+- if ((value & 0xffff_ff00) == 0) {
+- clamped = (byte) value;
+- } else {
+- clamped = value < 0 ? 0 : (byte)0xff;
+- }
+- buffer.getByteArray()[byteIndex(index)] = clamped;
++ public Class<?> getElementType() {
++ return int.class;
+ }
+
+ @Override
+- protected void setImpl(final int index, final long value) {
+- if (JSType.isRepresentableAsInt(value)) {
+- setImpl(index, (int)value);
+- } else {
+- buffer.getByteArray()[byteIndex(index)] = value > 0 ? (byte)0xff : 0;
++ public Class<?> getBoxedElementType() {
++ return int.class;
++ }
++
++ private int getElem(final int index) {
++ try {
++ return nb.get(index) & 0xff;
++ } catch (final IndexOutOfBoundsException e) {
++ throw new ClassCastException(); //force relink - this works for unoptimistic too
+ }
+ }
+
+ @Override
+- protected void setImpl(final int key, final double value) {
+- setImpl(key, (int)Math.rint(value));
++ public MethodHandle getElementSetter(final Class<?> elementType) {
++ final MethodHandle setter = super.getElementSetter(elementType); //getContinuousElementSetter(getClass(), setElem(), elementType);
++ if (setter != null) {
++ if (elementType == Object.class) {
++ return MH.filterArguments(setter, 2, RINT_O);
++ } else if (elementType == double.class) {
++ return MH.filterArguments(setter, 2, RINT_D);
++ } else if (elementType == long.class) {
++ return MH.filterArguments(setter, 2, CLAMP_LONG);
++ }
++ }
++ return setter;
++ }
++
++ private void setElem(final int index, final int elem) {
++ try {
++ final byte clamped;
++ if ((elem & 0xffff_ff00) == 0) {
++ clamped = (byte)elem;
++ } else {
++ clamped = elem < 0 ? 0 : (byte)0xff;
++ }
++ nb.put(index, clamped);
++ } catch (final IndexOutOfBoundsException e) {
++ //swallow valid array indexes. it's ok.
++ if (index < 0) {
++ throw new ClassCastException();
++ }
++ }
+ }
+
+ @Override
+- protected void setImpl(final int key, final Object value) {
+- setImpl(key, JSType.toNumber(value));
++ public boolean isClamped() {
++ return true;
++ }
++
++ @Override
++ public boolean isUnsigned() {
++ return true;
++ }
++
++ @Override
++ public int getInt(final int index) {
++ return getElem(index);
++ }
++
++ @Override
++ public int getIntOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public long getLong(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public long getLongOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public double getDouble(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ return getElem(index);
++ }
++
++ @Override
++ public Object getObject(final int index) {
++ return getInt(index);
++ }
++
++ @Override
++ public ArrayData set(final int index, final Object value, final boolean strict) {
++ return set(index, JSType.toNumber(value), strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final int value, final boolean strict) {
++ setElem(index, value);
++ return this;
++ }
++
++ @Override
++ public ArrayData set(final int index, final long value, final boolean strict) {
++ return set(index, (int)value, strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final double value, final boolean strict) {
++ return set(index, rint(value), strict);
++ }
++
++ private static double rint(final double rint) {
++ return (int)Math.rint(rint);
++ }
++
++ @SuppressWarnings("unused")
++ private static Object rint(final Object rint) {
++ return rint(JSType.toNumber(rint));
++ }
++
++ @SuppressWarnings("unused")
++ private static long clampLong(final long l) {
++ if(l < 0L) {
++ return 0L;
++ } else if(l > 0xffL) {
++ return 0xffL;
++ }
++ return l;
+ }
+ }
+
+@@ -119,7 +245,7 @@
+ */
+ @Constructor(arity = 1)
+ public static NativeUint8ClampedArray constructor(final boolean newObj, final Object self, final Object... args) {
+- return (NativeUint8ClampedArray)constructorImpl(args, FACTORY);
++ return (NativeUint8ClampedArray)constructorImpl(newObj, args, FACTORY);
+ }
+
+ NativeUint8ClampedArray(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+@@ -127,11 +253,6 @@
+ }
+
+ @Override
+- public String getClassName() {
+- return "Uint8ClampedArray";
+- }
+-
+- @Override
+ protected Factory factory() {
+ return FACTORY;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,8 +25,8 @@
+
+ package jdk.nashorn.internal.objects;
+
++import static jdk.nashorn.internal.lookup.Lookup.MH;
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+-import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+--- ./nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java Wed Feb 04 12:14:47 2015 -0800
+@@ -30,6 +30,7 @@
+
+ import java.lang.invoke.MethodHandle;
+ import java.util.ArrayList;
++import jdk.nashorn.internal.runtime.AccessorProperty;
+ import jdk.nashorn.internal.runtime.GlobalFunctions;
+ import jdk.nashorn.internal.runtime.Property;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+@@ -37,7 +38,7 @@
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptFunctionData;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+-import jdk.nashorn.internal.runtime.AccessorProperty;
++import jdk.nashorn.internal.runtime.Specialization;
+
+ /**
+ * Concrete implementation of ScriptFunction. This sets correct map for the
+@@ -58,7 +59,7 @@
+ // Marker object for lazily initialized prototype object
+ private static final Object LAZY_PROTOTYPE = new Object();
+
+- private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs, final Global global) {
++ private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final Specialization[] specs, final Global global) {
+ super(name, invokeHandle, map$, null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
+ init(global);
+ }
+@@ -71,11 +72,11 @@
+ * @param invokeHandle handle for invocation
+ * @param specs specialized versions of this method, if available, null otherwise
+ */
+- ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs) {
++ ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final Specialization[] specs) {
+ this(name, invokeHandle, specs, Global.instance());
+ }
+
+- private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final MethodHandle[] specs, final Global global) {
++ private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final Specialization[] specs, final Global global) {
+ super(name, invokeHandle, map.addAll(map$), null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
+ init(global);
+ }
+@@ -89,11 +90,11 @@
+ * @param map initial property map
+ * @param specs specialized versions of this method, if available, null otherwise
+ */
+- ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final MethodHandle[] specs) {
++ ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final Specialization[] specs) {
+ this(name, invokeHandle, map, specs, Global.instance());
+ }
+
+- private ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final int flags, final Global global) {
++ private ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final Specialization[] specs, final int flags, final Global global) {
+ super(name, methodHandle, getMap(isStrict(flags)), scope, specs, flags);
+ init(global);
+ }
+@@ -107,7 +108,7 @@
+ * @param specs specialized versions of this method, if available, null otherwise
+ * @param flags {@link ScriptFunctionData} flags
+ */
+- ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final int flags) {
++ ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final Specialization[] specs, final int flags) {
+ this(name, methodHandle, scope, specs, flags, Global.instance());
+ }
+
+@@ -175,13 +176,22 @@
+ private static class AnonymousFunction extends ScriptFunctionImpl {
+ private static final PropertyMap anonmap$ = PropertyMap.newMap();
+
+- AnonymousFunction(final Global global) {
++ AnonymousFunction() {
+ super("", GlobalFunctions.ANONYMOUS, anonmap$, null);
+ }
+ }
+
+- static ScriptFunctionImpl newAnonymousFunction(final Global global) {
+- return new AnonymousFunction(global);
++ static ScriptFunctionImpl newAnonymousFunction() {
++ return new AnonymousFunction();
++ }
++
++ private static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final Specialization[] specs, final int flags) {
++ final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, flags);
++ func.setPrototype(UNDEFINED);
++ // Non-constructor built-in functions do not have "prototype" property
++ func.deleteOwnProperty(func.getMap().findProperty("prototype"));
++
++ return func;
+ }
+
+ /**
+@@ -192,13 +202,19 @@
+ * @param specs specialized versions of function if available, null otherwise
+ * @return new ScriptFunction
+ */
+- static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final MethodHandle[] specs) {
+- final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, ScriptFunctionData.IS_BUILTIN);
+- func.setPrototype(UNDEFINED);
+- // Non-constructor built-in functions do not have "prototype" property
+- func.deleteOwnProperty(func.getMap().findProperty("prototype"));
++ static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final Specialization[] specs) {
++ return makeFunction(name, methodHandle, specs, ScriptFunctionData.IS_BUILTIN);
++ }
+
+- return func;
++ /**
++ * Factory method for non-constructor built-in, strict functions
++ *
++ * @param name function name
++ * @param methodHandle handle for invocation
++ * @return new ScriptFunction
++ */
++ static ScriptFunction makeStrictFunction(final String name, final MethodHandle methodHandle) {
++ return makeFunction(name, methodHandle, null, ScriptFunctionData.IS_BUILTIN | ScriptFunctionData.IS_STRICT );
+ }
+
+ /**
+@@ -220,13 +236,13 @@
+
+ /**
+ * Same as {@link ScriptFunction#makeBoundFunction(Object, Object[])}. The only reason we override it is so that we
+- * can expose it to methods in this package.
++ * can expose it.
+ * @param self the self to bind to this function. Can be null (in which case, null is bound as this).
+ * @param args additional arguments to bind to this function. Can be null or empty to not bind additional arguments.
+ * @return a function with the specified self and parameters bound.
+ */
+ @Override
+- protected ScriptFunction makeBoundFunction(Object self, Object[] args) {
++ public ScriptFunction makeBoundFunction(final Object self, final Object[] args) {
+ return super.makeBoundFunction(self, args);
+ }
+
+@@ -272,14 +288,13 @@
+
+ // We have to fill user accessor functions late as these are stored
+ // in this object rather than in the PropertyMap of this object.
+-
+- final ScriptFunction errorThrower = global.getTypeErrorThrower();
++ assert objectSpill == null;
++ final ScriptFunction typeErrorThrower = global.getTypeErrorThrower();
+ if (findProperty("arguments", true) != null) {
+- setUserAccessors("arguments", errorThrower, errorThrower);
+- }
+-
++ initUserAccessors("arguments", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
++ }
+ if (findProperty("caller", true) != null) {
+- setUserAccessors("caller", errorThrower, errorThrower);
+- }
++ initUserAccessors("caller", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
++ }
+ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/objects/annotations/Optimistic.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.objects.annotations;
++
++import java.lang.annotation.ElementType;
++import java.lang.annotation.Retention;
++import java.lang.annotation.RetentionPolicy;
++import java.lang.annotation.Target;
++
++/**
++ * The Optimistic annotation is used for builtins that can throw UnwarrantedOptimism
++ * exception if they are wrong, whose callsite is optimistic and contains a program
++ * point. Every optimistic builtin callsite needs to bind its programPoint to an
++ * argument of the implementation at compile time
++ *
++ * Typical use case would be something like: if you want to do an optimistic "push" function
++ * in NativeArray that takes an int, write
++ *
++ * <pre>
++ * {@literal @}SpecializedFunction {@literal @}Optimistic
++ * public static int push(final Object self, final int x, final int programPoint) {
++ * try {
++ * //push code assuming that this is an int array
++ * //return new length of array, assuming it's an int
++ * } catch (ArrayWasWrong e) {
++ * //undo any array modifications
++ * throw new UnwarrantedOptimismExceptionArrayType(x, programPoint);
++ * } catch (LengthOverFlowed e) {
++ * //undo any array modifications
++ * throw new UnwarratnedOptimismExceptionArrayLength(uint32lenThatOverFlowed, programPoint)
++ * }
++ * }
++ * </pre>
++ */
++@Retention(RetentionPolicy.RUNTIME)
++@Target(ElementType.METHOD)
++public @interface Optimistic {
++ //empty
++}
+--- ./nashorn/src/jdk/nashorn/internal/objects/annotations/Property.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/annotations/Property.java Wed Feb 04 12:14:47 2015 -0800
+@@ -40,21 +40,25 @@
+ public @interface Property {
+ /**
+ * Name of the script property. If empty, the name is inferred.
++ * @return name
+ */
+ public String name() default "";
+
+ /**
+ * Attribute flags for this function.
++ * @return attribute
+ */
+ public int attributes() default DEFAULT_ATTRIBUTES;
+
+ /**
+ * Initialize this property with the object of given class.
++ * @return class
+ */
+ public String clazz() default "";
+
+ /**
+ * Where this property lives?
++ * @return location of property
+ */
+ public Where where() default Where.INSTANCE;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedConstructor.java Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,47 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 jdk.nashorn.internal.objects.annotations;
+-
+-import java.lang.annotation.ElementType;
+-import java.lang.annotation.Retention;
+-import java.lang.annotation.RetentionPolicy;
+-import java.lang.annotation.Target;
+-
+-/**
+- * The SpecializedConstructor annotation is used to flag more type specific constructors than the standard one in
+- * Native objects. For example {@link jdk.nashorn.internal.objects.NativeArray#construct} takes an arbitrary number of
+- * Object elements as an array. Call this constructor, including the varargs collector that allocates the array
+- * upon each invocation, is much more expensive than calling a specialized constructor that takes one arguments
+- * of, e.g. int type from the call site, such as
+- * {@link jdk.nashorn.internal.objects.NativeArray#construct(boolean, Object, int)}.
+- * {@link jdk.nashorn.internal.runtime.ScriptFunction} will try to look up the most specific function when
+- * linking the callsite.
+- */
+-@Retention(RetentionPolicy.RUNTIME)
+-@Target(ElementType.METHOD)
+-public @interface SpecializedConstructor {
+- //empty
+-}
+--- ./nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java Wed Feb 04 12:14:47 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -29,18 +29,186 @@
+ import java.lang.annotation.Retention;
+ import java.lang.annotation.RetentionPolicy;
+ import java.lang.annotation.Target;
++import java.lang.invoke.MethodHandle;
++import jdk.internal.dynalink.CallSiteDescriptor;
++import jdk.internal.dynalink.linker.LinkRequest;
++import jdk.nashorn.internal.runtime.ScriptFunction;
+
+ /**
+- * The SpecializedFunction annotation is used to flag more type specific functions than the standard one in
+- * Native objects. For example {@link jdk.nashorn.internal.objects.NativeMath#max} takes an arbitrary number of
+- * Object elements as an array. Call this function, including the varargs collector that allocates the array
+- * upon each invocation, is much more expensive than calling a specialized function that takes two arguments
+- * of, e.g. int type from the call site, such as {@link jdk.nashorn.internal.objects.NativeMath#max(Object, int, int)}.
+- * {@link jdk.nashorn.internal.runtime.ScriptFunction} will try to look up the most specific function when
+- * linking the callsite.
++ * The SpecializedFunction annotation is used to flag more type specific
++ * functions than the standard one in the native objects
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.METHOD)
+ public @interface SpecializedFunction {
+- //empty
++
++ /**
++ * Functionality for testing if we are allowed to link a specialized
++ * function the first time we encounter it. Then the guard will handle the
++ * rest of the invocations
++ *
++ * This is the same for all callsites in Nashorn, the first time callsite is
++ * linked, we have to manually check that the linkage is OK. Even if we add
++ * a guard and it fails upon the first try, this is not good enough.
++ * (Symmetrical to how it works everywhere else in the Nashorn runtime).
++ *
++ * Here we abstract out a few of the most common link guard checks.
++ */
++ public static abstract class LinkLogic {
++ /**
++ * Empty link logic instance - this is the default
++ * "no special linking or runtime guard behavior"
++ */
++ public static final LinkLogic EMPTY_INSTANCE = new Empty();
++
++ /** Empty link logic class - allow all linking, no guards */
++ private static final class Empty extends LinkLogic {
++ @Override
++ public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
++ return true;
++ }
++
++ @Override
++ public boolean isEmpty() {
++ return true;
++ }
++ }
++
++ /**
++ * Get the class representing the empty link logic
++ * @return class representing empty link logic
++ */
++ public static Class<? extends LinkLogic> getEmptyLinkLogicClass() {
++ return Empty.class;
++ }
++
++ /**
++ * Should this callsite relink when an exception is thrown
++ *
++ * @return the relink exception, or null if none
++ */
++ public Class<? extends Throwable> getRelinkException() {
++ return null;
++ }
++
++ /**
++ * Is this link logic class empty - i.e. no special linking logic
++ * supplied
++ *
++ * @param clazz class to check
++ *
++ * @return true if this link logic is empty
++ */
++ public static boolean isEmpty(final Class<? extends LinkLogic> clazz) {
++ return clazz == Empty.class;
++ }
++
++ /**
++ * Is this link logic instance empty - i.e. no special linking logic
++ * supplied
++ *
++ * @return true if this link logic instance is empty
++ */
++ public boolean isEmpty() {
++ return false;
++ }
++
++ /**
++ * Given a callsite, can we link this method based on the receiver and
++ * parameters?
++ *
++ * @param self receiver
++ * @param desc callsite descriptor
++ * @param request link request
++ *
++ * @return true if we can link this callsite at this time
++ */
++ public abstract boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request);
++
++ /**
++ * Given a callsite, do we require an extra guard for specialization to
++ * go through?
++ *
++ * @param self receiver
++ *
++ * @return true if a guard is to be woven into the callsite
++ */
++ public boolean needsGuard(final Object self) {
++ return true;
++ }
++
++ /**
++ * Given a callsite, and optional arguments, do we need an extra guard
++ * for specialization to go through - this guard can be a function of
++ * the arguments too
++ *
++ * @param self receiver
++ * @param args arguments
++ *
++ * @return true if a guard is to be woven into the callsite
++ */
++ public boolean needsGuard(final Object self, final Object... args) {
++ return true;
++ }
++
++ /**
++ * Given a callsite, and optional arguments, return any extra guard we
++ * might need for specialization as a method handle.
++ *
++ * @return methodhandle for guard, or null if no guard is needed
++ */
++ public MethodHandle getGuard() {
++ return null;
++ }
++
++ /**
++ * Check, given a link request and a receiver, if this specialization
++ * fits This is used by the linker in {@link ScriptFunction} to figure
++ * out if an optimistic builtin can be linked when first discovered
++ *
++ * @param self receiver
++ * @param desc callsite descriptor
++ * @param request link request
++
++ * @return true if we can link, false otherwise - that means we have to
++ * pick a non specialized target
++ */
++ public boolean checkLinkable(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
++ // check the link guard, if it says we can link, go ahead
++ return canLink(self, desc, request);
++ }
++ }
++
++ /**
++ * name override for return value polymorphism, for example we can't have
++ * pop(V)I and pop(V)D in the same Java class, so they need to be named,
++ * e.g. popInt(V)I and popDouble(V)D for disambiguation, however, their
++ * names still need to resolve to "pop" to JavaScript so we can still
++ * specialize on return values and so that the linker can find them
++ *
++ * @return name, "" means no override, use the Java function name, e.g.
++ * "push"
++ */
++ String name() default "";
++
++ /**
++ * Return the guard for this specialized function. The default is no guard.
++ *
++ * @return guard
++ */
++ Class<?> linkLogic() default LinkLogic.Empty.class;
++
++ /**
++ * Is this a specialized constructor?
++ */
++ boolean isConstructor() default false;
++
++ /**
++ * Can this function throw UnwarrantedOptimismExceptions? This works just
++ * like the normal functions, but we need the function to be
++ * immutable/non-state modifying, as we can't generate continuations for
++ * native code. Luckily a lot of the methods we want to specialize have this
++ * property
++ */
++ boolean isOptimistic() default false;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java Wed Feb 04 12:14:47 2015 -0800
+@@ -30,7 +30,8 @@
+ import static jdk.nashorn.internal.parser.TokenType.EOF;
+ import static jdk.nashorn.internal.parser.TokenType.EOL;
+ import static jdk.nashorn.internal.parser.TokenType.IDENT;
+-
++import java.util.HashMap;
++import java.util.Map;
+ import jdk.nashorn.internal.ir.IdentNode;
+ import jdk.nashorn.internal.ir.LiteralNode;
+ import jdk.nashorn.internal.parser.Lexer.LexerToken;
+@@ -58,6 +59,9 @@
+ /** Index of current token. */
+ protected int k;
+
++ /** Previous token - accessible to sub classes */
++ protected long previousToken;
++
+ /** Descriptor of current token. */
+ protected long token;
+
+@@ -85,17 +89,20 @@
+ /** Is this parser running under strict mode? */
+ protected boolean isStrictMode;
+
+- /** //@ sourceURL or //# sourceURL */
+- protected String sourceURL;
++ /** What should line numbers be counted from? */
++ protected final int lineOffset;
++
++ private final Map<String, String> canonicalNames = new HashMap<>();
+
+ /**
+ * Construct a parser.
+ *
+- * @param source Source to parse.
+- * @param errors Error reporting manager.
+- * @param strict True if we are in strict mode
++ * @param source Source to parse.
++ * @param errors Error reporting manager.
++ * @param strict True if we are in strict mode
++ * @param lineOffset Offset from which lines should be counted
+ */
+- protected AbstractParser(final Source source, final ErrorManager errors, final boolean strict) {
++ protected AbstractParser(final Source source, final ErrorManager errors, final boolean strict, final int lineOffset) {
+ this.source = source;
+ this.errors = errors;
+ this.k = -1;
+@@ -103,6 +110,7 @@
+ this.type = EOL;
+ this.last = EOL;
+ this.isStrictMode = strict;
++ this.lineOffset = lineOffset;
+ }
+
+ /**
+@@ -174,7 +182,7 @@
+ // currently only @sourceURL=foo supported
+ private void checkDirectiveComment() {
+ // if already set, ignore this one
+- if (sourceURL != null) {
++ if (source.getExplicitURL() != null) {
+ return;
+ }
+
+@@ -182,7 +190,7 @@
+ final int len = comment.length();
+ // 4 characters for directive comment marker //@\s or //#\s
+ if (len > 4 && comment.substring(4).startsWith(SOURCE_URL_PREFIX)) {
+- sourceURL = comment.substring(4 + SOURCE_URL_PREFIX.length());
++ source.setExplicitURL(comment.substring(4 + SOURCE_URL_PREFIX.length()));
+ }
+ }
+
+@@ -199,6 +207,7 @@
+ // Set up next token.
+ k++;
+ final long lastToken = token;
++ previousToken = token;
+ token = getToken(k);
+ type = Token.descType(token);
+
+@@ -208,7 +217,7 @@
+ }
+
+ if (type == EOL) {
+- line = Token.descLength(token);
++ line = Token.descLength(token);
+ linePosition = Token.descPosition(token);
+ } else {
+ start = Token.descPosition(token);
+@@ -316,18 +325,28 @@
+ }
+
+ /**
+- * Check next token and advance.
++ * Check current token and advance to the next token.
+ *
+ * @param expected Expected tokenType.
+ *
+ * @throws ParserException on unexpected token type
+ */
+ protected final void expect(final TokenType expected) throws ParserException {
++ expectDontAdvance(expected);
++ next();
++ }
++
++ /**
++ * Check current token, but don't advance to the next token.
++ *
++ * @param expected Expected tokenType.
++ *
++ * @throws ParserException on unexpected token type
++ */
++ protected final void expectDontAdvance(final TokenType expected) throws ParserException {
+ if (type != expected) {
+ throw error(expectMessage(expected));
+ }
+-
+- next();
+ }
+
+ /**
+@@ -403,7 +422,7 @@
+ next();
+
+ // Create IDENT node.
+- return new IdentNode(identToken, finish, ident).setIsFutureStrictName();
++ return createIdentNode(identToken, finish, ident).setIsFutureStrictName();
+ }
+
+ // Get IDENT.
+@@ -412,7 +431,22 @@
+ return null;
+ }
+ // Create IDENT node.
+- return new IdentNode(identToken, finish, ident);
++ return createIdentNode(identToken, finish, ident);
++ }
++
++ /**
++ * Creates a new {@link IdentNode} as if invoked with a {@link IdentNode#IdentNode(long, int, String)
++ * constructor} but making sure that the {@code name} is deduplicated within this parse job.
++ * @param identToken the token for the new {@code IdentNode}
++ * @param identFinish the finish for the new {@code IdentNode}
++ * @param name the name for the new {@code IdentNode}. It will be de-duplicated.
++ * @return a newly constructed {@code IdentNode} with the specified token, finish, and name; the name will
++ * be deduplicated.
++ */
++ protected IdentNode createIdentNode(final long identToken, final int identFinish, final String name) {
++ final String existingName = canonicalNames.putIfAbsent(name, name);
++ final String canonicalName = existingName != null ? existingName : name;
++ return new IdentNode(identToken, identFinish, canonicalName);
+ }
+
+ /**
+@@ -447,7 +481,7 @@
+ final String ident = (String)getValue(identToken);
+ next();
+ // Create IDENT node.
+- return new IdentNode(identToken, finish, ident);
++ return createIdentNode(identToken, finish, ident);
+ } else {
+ expect(IDENT);
+ return null;
+--- ./nashorn/src/jdk/nashorn/internal/parser/JSONParser.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/parser/JSONParser.java Wed Feb 04 12:14:47 2015 -0800
+@@ -32,7 +32,6 @@
+ import static jdk.nashorn.internal.parser.TokenType.RBRACE;
+ import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
+ import static jdk.nashorn.internal.parser.TokenType.STRING;
+-
+ import java.util.ArrayList;
+ import java.util.List;
+ import jdk.nashorn.internal.ir.Expression;
+@@ -57,7 +56,7 @@
+ * @param errors the error manager
+ */
+ public JSONParser(final Source source, final ErrorManager errors) {
+- super(source, errors, false);
++ super(source, errors, false, 0);
+ }
+
+ /**
+@@ -160,7 +159,7 @@
+ }
+
+ // First digit of number.
+- int digit = convertDigit(ch0, 10);
++ final int digit = convertDigit(ch0, 10);
+
+ // skip first digit
+ skip(1);
+--- ./nashorn/src/jdk/nashorn/internal/parser/Lexer.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/parser/Lexer.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,14 +27,15 @@
+
+ import static jdk.nashorn.internal.parser.TokenType.ADD;
+ import static jdk.nashorn.internal.parser.TokenType.COMMENT;
++import static jdk.nashorn.internal.parser.TokenType.DECIMAL;
+ import static jdk.nashorn.internal.parser.TokenType.DIRECTIVE_COMMENT;
+-import static jdk.nashorn.internal.parser.TokenType.DECIMAL;
+ import static jdk.nashorn.internal.parser.TokenType.EOF;
+ import static jdk.nashorn.internal.parser.TokenType.EOL;
+ import static jdk.nashorn.internal.parser.TokenType.ERROR;
+ import static jdk.nashorn.internal.parser.TokenType.ESCSTRING;
+ import static jdk.nashorn.internal.parser.TokenType.EXECSTRING;
+ import static jdk.nashorn.internal.parser.TokenType.FLOATING;
++import static jdk.nashorn.internal.parser.TokenType.FUNCTION;
+ import static jdk.nashorn.internal.parser.TokenType.HEXADECIMAL;
+ import static jdk.nashorn.internal.parser.TokenType.LBRACE;
+ import static jdk.nashorn.internal.parser.TokenType.LPAREN;
+@@ -45,9 +46,11 @@
+ import static jdk.nashorn.internal.parser.TokenType.STRING;
+ import static jdk.nashorn.internal.parser.TokenType.XML;
+
++import java.io.Serializable;
+ import jdk.nashorn.internal.runtime.ECMAErrors;
+ import jdk.nashorn.internal.runtime.ErrorManager;
+ import jdk.nashorn.internal.runtime.JSErrorType;
++import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.ParserException;
+ import jdk.nashorn.internal.runtime.Source;
+ import jdk.nashorn.internal.runtime.options.Options;
+@@ -76,7 +79,7 @@
+ private final boolean nested;
+
+ /** Pending new line number and position. */
+- private int pendingLine;
++ int pendingLine;
+
+ /** Position of last EOL + 1. */
+ private int linePosition;
+@@ -84,6 +87,9 @@
+ /** Type of last token added. */
+ private TokenType last;
+
++ private final boolean pauseOnFunctionBody;
++ private boolean pauseOnNextLeftBrace;
++
+ private static final String SPACETAB = " \t"; // ASCII space and tab
+ private static final String LFCR = "\n\r"; // line feed and carriage return (ctrl-m)
+
+@@ -181,14 +187,32 @@
+ * @param scripting are we in scripting mode
+ */
+ public Lexer(final Source source, final TokenStream stream, final boolean scripting) {
+- super(source.getContent(), 1, 0, source.getLength());
++ this(source, 0, source.getLength(), stream, scripting, false);
++ }
+
++ /**
++ * Constructor
++ *
++ * @param source the source
++ * @param start start position in source from which to start lexing
++ * @param len length of source segment to lex
++ * @param stream token stream to lex
++ * @param scripting are we in scripting mode
++ * @param pauseOnFunctionBody if true, lexer will return from {@link #lexify()} when it encounters a
++ * function body. This is used with the feature where the parser is skipping nested function bodies to
++ * avoid reading ahead unnecessarily when we skip the function bodies.
++ */
++
++ public Lexer(final Source source, final int start, final int len, final TokenStream stream, final boolean scripting, final boolean pauseOnFunctionBody) {
++ super(source.getContent(), 1, start, len);
+ this.source = source;
+ this.stream = stream;
+ this.scripting = scripting;
+ this.nested = false;
+ this.pendingLine = 1;
+ this.last = EOL;
++
++ this.pauseOnFunctionBody = pauseOnFunctionBody;
+ }
+
+ private Lexer(final Lexer lexer, final State state) {
+@@ -202,6 +226,7 @@
+ pendingLine = state.pendingLine;
+ linePosition = state.linePosition;
+ last = EOL;
++ pauseOnFunctionBody = false;
+ }
+
+ static class State extends Scanner.State {
+@@ -796,6 +821,9 @@
+ final int length = scanIdentifier();
+ // Check to see if it is a keyword.
+ final TokenType type = TokenLookup.lookupKeyword(content, start, length);
++ if (type == FUNCTION && pauseOnFunctionBody) {
++ pauseOnNextLeftBrace = true;
++ }
+ // Add keyword or identifier token.
+ add(type, start);
+ }
+@@ -1583,6 +1611,9 @@
+ // We break to let the parser decide what it is.
+ if (canStartLiteral(type)) {
+ break;
++ } else if (type == LBRACE && pauseOnNextLeftBrace) {
++ pauseOnNextLeftBrace = false;
++ break;
+ }
+ } else if (Character.isJavaIdentifierStart(ch0) || ch0 == '\\' && ch1 == 'u') {
+ // Scan and add identifier or keyword.
+@@ -1609,7 +1640,7 @@
+ */
+ Object getValueOf(final long token, final boolean strict) {
+ final int start = Token.descPosition(token);
+- final int len = Token.descLength(token);
++ final int len = Token.descLength(token);
+
+ switch (Token.descType(token)) {
+ case DECIMAL:
+@@ -1619,7 +1650,23 @@
+ case HEXADECIMAL:
+ return Lexer.valueOf(source.getString(start + 2, len - 2), 16); // number
+ case FLOATING:
+- return Double.valueOf(source.getString(start, len)); // number
++ final String str = source.getString(start, len);
++ final double value = Double.valueOf(str);
++ if (str.indexOf('.') != -1) {
++ return value; //number
++ }
++ //anything without an explicit decimal point is still subject to a
++ //"representable as int or long" check. Then the programmer does not
++ //explicitly code something as a double. For example new Color(int, int, int)
++ //and new Color(float, float, float) will get ambiguous for cases like
++ //new Color(1.0, 1.5, 1.5) if we don't respect the decimal point.
++ //yet we don't want e.g. 1e6 to be a double unnecessarily
++ if (JSType.isRepresentableAsInt(value) && !JSType.isNegativeZero(value)) {
++ return (int)value;
++ } else if (JSType.isRepresentableAsLong(value) && !JSType.isNegativeZero(value)) {
++ return (long)value;
++ }
++ return value;
+ case STRING:
+ return source.getString(start, len); // String
+ case ESCSTRING:
+@@ -1671,7 +1718,9 @@
+ * Helper class for Lexer tokens, e.g XML or RegExp tokens.
+ * This is the abstract superclass
+ */
+- public static abstract class LexerToken {
++ public static abstract class LexerToken implements Serializable {
++ private static final long serialVersionUID = 1L;
++
+ private final String expression;
+
+ /**
+@@ -1695,6 +1744,8 @@
+ * Temporary container for regular expressions.
+ */
+ public static class RegexToken extends LexerToken {
++ private static final long serialVersionUID = 1L;
++
+ /** Options. */
+ private final String options;
+
+@@ -1727,6 +1778,7 @@
+ * Temporary container for XML expression.
+ */
+ public static class XMLToken extends LexerToken {
++ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor.
+--- ./nashorn/src/jdk/nashorn/internal/parser/Parser.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/parser/Parser.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,9 +25,9 @@
+
+ package jdk.nashorn.internal.parser;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.ANON_FUNCTION_PREFIX;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.ANON_FUNCTION_PREFIX;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.RUN_SCRIPT;
++import static jdk.nashorn.internal.codegen.CompilerConstants.PROGRAM;
+ import static jdk.nashorn.internal.parser.TokenType.ASSIGN;
+ import static jdk.nashorn.internal.parser.TokenType.CASE;
+ import static jdk.nashorn.internal.parser.TokenType.CATCH;
+@@ -45,6 +45,7 @@
+ import static jdk.nashorn.internal.parser.TokenType.IF;
+ import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX;
+ import static jdk.nashorn.internal.parser.TokenType.LBRACE;
++import static jdk.nashorn.internal.parser.TokenType.LET;
+ import static jdk.nashorn.internal.parser.TokenType.LPAREN;
+ import static jdk.nashorn.internal.parser.TokenType.RBRACE;
+ import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
+@@ -53,8 +54,11 @@
+ import static jdk.nashorn.internal.parser.TokenType.TERNARY;
+ import static jdk.nashorn.internal.parser.TokenType.WHILE;
+
++import java.io.Serializable;
++import java.util.ArrayDeque;
+ import java.util.ArrayList;
+ import java.util.Collections;
++import java.util.Deque;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.Iterator;
+@@ -84,6 +88,7 @@
+ import jdk.nashorn.internal.ir.IdentNode;
+ import jdk.nashorn.internal.ir.IfNode;
+ import jdk.nashorn.internal.ir.IndexNode;
++import jdk.nashorn.internal.ir.JoinPredecessorExpression;
+ import jdk.nashorn.internal.ir.LabelNode;
+ import jdk.nashorn.internal.ir.LexicalContext;
+ import jdk.nashorn.internal.ir.LiteralNode;
+@@ -103,22 +108,29 @@
+ import jdk.nashorn.internal.ir.VarNode;
+ import jdk.nashorn.internal.ir.WhileNode;
+ import jdk.nashorn.internal.ir.WithNode;
+-import jdk.nashorn.internal.runtime.DebugLogger;
++import jdk.nashorn.internal.ir.debug.ASTWriter;
++import jdk.nashorn.internal.ir.debug.PrintVisitor;
++import jdk.nashorn.internal.runtime.Context;
+ import jdk.nashorn.internal.runtime.ErrorManager;
+ import jdk.nashorn.internal.runtime.JSErrorType;
+ import jdk.nashorn.internal.runtime.ParserException;
++import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
+ import jdk.nashorn.internal.runtime.ScriptEnvironment;
+ import jdk.nashorn.internal.runtime.ScriptingFunctions;
+ import jdk.nashorn.internal.runtime.Source;
+ import jdk.nashorn.internal.runtime.Timing;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
+
+ /**
+ * Builds the IR.
+ */
+-public class Parser extends AbstractParser {
++@Logger(name="parser")
++public class Parser extends AbstractParser implements Loggable {
+ private static final String ARGUMENTS_NAME = CompilerConstants.ARGUMENTS_VAR.symbolName();
+
+- /** Current script environment. */
++ /** Current env. */
+ private final ScriptEnvironment env;
+
+ /** Is scripting mode. */
+@@ -127,15 +139,18 @@
+ private List<Statement> functionDeclarations;
+
+ private final BlockLexicalContext lc = new BlockLexicalContext();
++ private final Deque<Object> defaultNames = new ArrayDeque<>();
+
+ /** Namespace for function names where not explicitly given */
+ private final Namespace namespace;
+
+- private static final DebugLogger LOG = new DebugLogger("parser");
++ private final DebugLogger log;
+
+ /** to receive line information from Lexer when scanning multine literals. */
+ protected final Lexer.LineInfoReceiver lineInfoReceiver;
+
++ private RecompilableScriptFunctionData reparsedFunction;
++
+ /**
+ * Constructor
+ *
+@@ -144,7 +159,20 @@
+ * @param errors error manager
+ */
+ public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors) {
+- this(env, source, errors, env._strict);
++ this(env, source, errors, env._strict, null);
++ }
++
++ /**
++ * Constructor
++ *
++ * @param env script environment
++ * @param source source to parse
++ * @param errors error manager
++ * @param strict strict
++ * @param log debug logger if one is needed
++ */
++ public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final DebugLogger log) {
++ this(env, source, errors, strict, 0, log);
+ }
+
+ /**
+@@ -154,10 +182,12 @@
+ * @param source source to parse
+ * @param errors error manager
+ * @param strict parser created with strict mode enabled.
++ * @param lineOffset line offset to start counting lines from
++ * @param log debug logger if one is needed
+ */
+- public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict) {
+- super(source, errors, strict);
+- this.env = env;
++ public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final int lineOffset, final DebugLogger log) {
++ super(source, errors, strict, lineOffset);
++ this.env = env;
+ this.namespace = new Namespace(env.getNamespace());
+ this.scripting = env._scripting;
+ if (this.scripting) {
+@@ -173,6 +203,37 @@
+ // non-scripting mode script can't have multi-line literals
+ this.lineInfoReceiver = null;
+ }
++
++ this.log = log == null ? DebugLogger.DISABLED_LOGGER : log;
++ }
++
++ @Override
++ public DebugLogger getLogger() {
++ return log;
++ }
++
++ @Override
++ public DebugLogger initLogger(final Context context) {
++ return context.getLogger(this.getClass());
++ }
++
++ /**
++ * Sets the name for the first function. This is only used when reparsing anonymous functions to ensure they can
++ * preserve their already assigned name, as that name doesn't appear in their source text.
++ * @param name the name for the first parsed function.
++ */
++ public void setFunctionName(final String name) {
++ defaultNames.push(createIdentNode(0, 0, name));
++ }
++
++ /**
++ * Sets the {@link RecompilableScriptFunctionData} representing the function being reparsed (when this
++ * parser instance is used to reparse a previously parsed function, as part of its on-demand compilation).
++ * This will trigger various special behaviors, such as skipping nested function bodies.
++ * @param reparsedFunction the function being reparsed.
++ */
++ public void setReparsedFunction(final RecompilableScriptFunctionData reparsedFunction) {
++ this.reparsedFunction = reparsedFunction;
+ }
+
+ /**
+@@ -181,12 +242,12 @@
+ * if parsing should fail
+ *
+ * This is the default parse call, which will name the function node
+- * "runScript" {@link CompilerConstants#RUN_SCRIPT}
++ * {code :program} {@link CompilerConstants#PROGRAM}
+ *
+ * @return function node resulting from successful parse
+ */
+ public FunctionNode parse() {
+- return parse(RUN_SCRIPT.symbolName());
++ return parse(PROGRAM.symbolName(), 0, source.getLength(), false);
+ }
+
+ /**
+@@ -194,35 +255,44 @@
+ * Errors will be thrown and the error manager will contain information
+ * if parsing should fail
+ *
++ * This should be used to create one and only one function node
++ *
+ * @param scriptName name for the script, given to the parsed FunctionNode
++ * @param startPos start position in source
++ * @param len length of parse
++ * @param allowPropertyFunction if true, "get" and "set" are allowed as first tokens of the program, followed by
++ * a property getter or setter function. This is used when reparsing a function that can potentially be defined as a
++ * property getter or setter in an object literal.
+ *
+ * @return function node resulting from successful parse
+ */
+- public FunctionNode parse(final String scriptName) {
+- final long t0 = Timing.isEnabled() ? System.currentTimeMillis() : 0L;
+- LOG.info(this, " begin for '", scriptName, "'");
++ public FunctionNode parse(final String scriptName, final int startPos, final int len, final boolean allowPropertyFunction) {
++ final boolean isTimingEnabled = env.isTimingEnabled();
++ final long t0 = isTimingEnabled ? System.nanoTime() : 0L;
++ log.info(this, " begin for '", scriptName, "'");
+
+ try {
+ stream = new TokenStream();
+- lexer = new Lexer(source, stream, scripting && !env._no_syntax_extensions);
++ lexer = new Lexer(source, startPos, len, stream, scripting && !env._no_syntax_extensions, reparsedFunction != null);
++ lexer.line = lexer.pendingLine = lineOffset + 1;
++ line = lineOffset;
+
+ // Set up first token (skips opening EOL.)
+ k = -1;
+ next();
+-
+ // Begin parse.
+- return program(scriptName);
++ return program(scriptName, allowPropertyFunction);
+ } catch (final Exception e) {
+ handleParseException(e);
+
+ return null;
+ } finally {
+ final String end = this + " end '" + scriptName + "'";
+- if (Timing.isEnabled()) {
+- Timing.accumulateTime(toString(), System.currentTimeMillis() - t0);
+- LOG.info(end, "' in ", (System.currentTimeMillis() - t0), " ms");
++ if (isTimingEnabled) {
++ env._timing.accumulateTime(toString(), System.nanoTime() - t0);
++ log.info(end, "' in ", Timing.toMillisPrint(System.nanoTime() - t0), " ms");
+ } else {
+- LOG.info(end);
++ log.info(end);
+ }
+ }
+ }
+@@ -264,6 +334,7 @@
+ try {
+ stream = new TokenStream();
+ lexer = new Lexer(source, stream, scripting && !env._no_syntax_extensions);
++ final int functionLine = line;
+
+ // Set up first token (skips opening EOL.)
+ k = -1;
+@@ -275,21 +346,23 @@
+
+ FunctionNode function = newFunctionNode(
+ functionToken,
+- new IdentNode(functionToken, Token.descPosition(functionToken), RUN_SCRIPT.symbolName()),
++ new IdentNode(functionToken, Token.descPosition(functionToken), PROGRAM.symbolName()),
+ new ArrayList<IdentNode>(),
+- FunctionNode.Kind.NORMAL);
++ FunctionNode.Kind.NORMAL,
++ functionLine);
+
+ functionDeclarations = new ArrayList<>();
+- sourceElements();
++ sourceElements(false);
+ addFunctionDeclarations(function);
+ functionDeclarations = null;
+
+ expect(EOF);
+
+ function.setFinish(source.getLength() - 1);
+-
+ function = restoreFunctionNode(function, token); //commit code
+ function = function.setBody(lc, function.getBody().setNeedsScope(lc));
++
++ printAST(function);
+ return function;
+ } catch (final Exception e) {
+ handleParseException(e);
+@@ -381,7 +454,7 @@
+ * @param ident Name of function.
+ * @return New block.
+ */
+- private FunctionNode newFunctionNode(final long startToken, final IdentNode ident, final List<IdentNode> parameters, final FunctionNode.Kind kind) {
++ private FunctionNode newFunctionNode(final long startToken, final IdentNode ident, final List<IdentNode> parameters, final FunctionNode.Kind kind, final int functionLine) {
+ // Build function name.
+ final StringBuilder sb = new StringBuilder();
+
+@@ -394,26 +467,21 @@
+ sb.append(ident.getName());
+
+ final String name = namespace.uniqueName(sb.toString());
+- assert parentFunction != null || name.equals(RUN_SCRIPT.symbolName()) : "name = " + name;// must not rename runScript().
++ assert parentFunction != null || name.equals(PROGRAM.symbolName()) || name.startsWith(RecompilableScriptFunctionData.RECOMPILATION_PREFIX) : "name = " + name;
+
+ int flags = 0;
++ if (isStrictMode) {
++ flags |= FunctionNode.IS_STRICT;
++ }
+ if (parentFunction == null) {
+ flags |= FunctionNode.IS_PROGRAM;
+ }
+- if (isStrictMode) {
+- flags |= FunctionNode.IS_STRICT;
+- }
+- if (env._specialize_calls != null) {
+- if (env._specialize_calls.contains(name)) {
+- flags |= FunctionNode.CAN_SPECIALIZE;
+- }
+- }
+
+ // Start new block.
+- FunctionNode functionNode =
++ final FunctionNode functionNode =
+ new FunctionNode(
+ source,
+- line, //TODO?
++ functionLine,
+ token,
+ Token.descPosition(token),
+ startToken,
+@@ -422,8 +490,7 @@
+ name,
+ parameters,
+ kind,
+- flags,
+- sourceURL);
++ flags);
+
+ lc.push(functionNode);
+ // Create new block, and just put it on the context stack, restoreFunctionNode() will associate it with the
+@@ -447,9 +514,8 @@
+ return lc.pop(functionNode).
+ setBody(lc, newBody).
+ setLastToken(lc, lastToken).
+- setState(lc, errors.hasErrors() ? CompilationState.PARSE_ERROR : CompilationState.PARSED).
+- snapshot(lc);
+- }
++ setState(lc, errors.hasErrors() ? CompilationState.PARSE_ERROR : CompilationState.PARSED);
++ }
+
+ /**
+ * Get the statements in a block.
+@@ -493,7 +559,7 @@
+ // Set up new block. Captures first token.
+ Block newBlock = newBlock();
+ try {
+- statement();
++ statement(false, false, true);
+ } finally {
+ newBlock = restoreBlock(newBlock);
+ }
+@@ -522,6 +588,10 @@
+ }
+ }
+
++ private boolean useBlockScope() {
++ return env._es6;
++ }
++
+ private static boolean isArguments(final String name) {
+ return ARGUMENTS_NAME.equals(name);
+ }
+@@ -582,9 +652,13 @@
+ }
+
+ // Build up node.
++ if(BinaryNode.isLogical(opType)) {
++ return new BinaryNode(op, new JoinPredecessorExpression(lhs), new JoinPredecessorExpression(rhs));
++ }
+ return new BinaryNode(op, lhs, rhs);
+ }
+
++
+ /**
+ * Reduce increment/decrement to simpler operations.
+ * @param firstToken First token.
+@@ -620,19 +694,21 @@
+ *
+ * Parse the top level script.
+ */
+- private FunctionNode program(final String scriptName) {
+- // Make a fake token for the script.
+- final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength());
++ private FunctionNode program(final String scriptName, final boolean allowPropertyFunction) {
++ // Make a pseudo-token for the script holding its start and length.
++ final long functionToken = Token.toDesc(FUNCTION, Token.descPosition(Token.withDelimiter(token)), source.getLength());
++ final int functionLine = line;
+ // Set up the script to append elements.
+
+ FunctionNode script = newFunctionNode(
+ functionToken,
+ new IdentNode(functionToken, Token.descPosition(functionToken), scriptName),
+ new ArrayList<IdentNode>(),
+- FunctionNode.Kind.SCRIPT);
++ FunctionNode.Kind.SCRIPT,
++ functionLine);
+
+ functionDeclarations = new ArrayList<>();
+- sourceElements();
++ sourceElements(allowPropertyFunction);
+ addFunctionDeclarations(script);
+ functionDeclarations = null;
+
+@@ -642,10 +718,6 @@
+
+ script = restoreFunctionNode(script, token); //commit code
+ script = script.setBody(lc, script.getBody().setNeedsScope(lc));
+- // user may have directive comment to set sourceURL
+- if (sourceURL != null) {
+- script = script.setSourceURL(lc, sourceURL);
+- }
+
+ return script;
+ }
+@@ -683,10 +755,12 @@
+ *
+ * Parse the elements of the script or function.
+ */
+- private void sourceElements() {
+- List<Node> directiveStmts = null;
+- boolean checkDirective = true;
+- final boolean oldStrictMode = isStrictMode;
++ private void sourceElements(final boolean shouldAllowPropertyFunction) {
++ List<Node> directiveStmts = null;
++ boolean checkDirective = true;
++ boolean allowPropertyFunction = shouldAllowPropertyFunction;
++ final boolean oldStrictMode = isStrictMode;
++
+
+ try {
+ // If is a script, then process until the end of the script.
+@@ -698,7 +772,8 @@
+
+ try {
+ // Get the next element.
+- statement(true);
++ statement(true, allowPropertyFunction, false);
++ allowPropertyFunction = false;
+
+ // check for directive prologues
+ if (checkDirective) {
+@@ -742,6 +817,12 @@
+ verifyStrictIdent(param, "function parameter");
+ }
+ }
++ } else if (Context.DEBUG) {
++ final int flag = FunctionNode.getDirectiveFlag(directive);
++ if (flag != 0) {
++ final FunctionNode function = lc.getCurrentFunction();
++ lc.setFlag(function, flag);
++ }
+ }
+ }
+ }
+@@ -781,13 +862,15 @@
+ * Parse any of the basic statement types.
+ */
+ private void statement() {
+- statement(false);
++ statement(false, false, false);
+ }
+
+ /**
+ * @param topLevel does this statement occur at the "top level" of a script or a function?
++ * @param allowPropertyFunction allow property "get" and "set" functions?
++ * @param singleStatement are we in a single statement context?
+ */
+- private void statement(final boolean topLevel) {
++ private void statement(final boolean topLevel, final boolean allowPropertyFunction, final boolean singleStatement) {
+ if (type == FUNCTION) {
+ // As per spec (ECMA section 12), function declarations as arbitrary statement
+ // is not "portable". Implementation can issue a warning or disallow the same.
+@@ -800,7 +883,7 @@
+ block();
+ break;
+ case VAR:
+- variableStatement(true);
++ variableStatement(type, true);
+ break;
+ case SEMICOLON:
+ emptyStatement();
+@@ -850,8 +933,15 @@
+ expect(SEMICOLON);
+ break;
+ default:
++ if (useBlockScope() && (type == LET || type == CONST)) {
++ if (singleStatement) {
++ throw error(AbstractParser.message("expected.stmt", type.getName() + " declaration"), token);
++ }
++ variableStatement(type, true);
++ break;
++ }
+ if (env._const_as_var && type == CONST) {
+- variableStatement(true);
++ variableStatement(TokenType.VAR, true);
+ break;
+ }
+
+@@ -860,6 +950,20 @@
+ labelStatement();
+ return;
+ }
++ if(allowPropertyFunction) {
++ final String ident = (String)getValue();
++ final long propertyToken = token;
++ final int propertyLine = line;
++ if("get".equals(ident)) {
++ next();
++ addPropertyFunctionStatement(propertyGetterFunction(propertyToken, propertyLine));
++ return;
++ } else if("set".equals(ident)) {
++ next();
++ addPropertyFunctionStatement(propertySetterFunction(propertyToken, propertyLine));
++ return;
++ }
++ }
+ }
+
+ expressionStatement();
+@@ -867,6 +971,11 @@
+ }
+ }
+
++ private void addPropertyFunctionStatement(final PropertyFunction propertyFunction) {
++ final FunctionNode fn = propertyFunction.functionNode;
++ functionDeclarations.add(new ExpressionStatement(fn.getLineNumber(), fn.getToken(), finish, fn));
++ }
++
+ /**
+ * block :
+ * { StatementList? }
+@@ -948,11 +1057,17 @@
+ * Parse a VAR statement.
+ * @param isStatement True if a statement (not used in a FOR.)
+ */
+- private List<VarNode> variableStatement(final boolean isStatement) {
++ private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement) {
+ // VAR tested in caller.
+ next();
+
+ final List<VarNode> vars = new ArrayList<>();
++ int varFlags = 0;
++ if (varType == LET) {
++ varFlags |= VarNode.IS_LET;
++ } else if (varType == CONST) {
++ varFlags |= VarNode.IS_CONST;
++ }
+
+ while (true) {
+ // Get starting token.
+@@ -970,11 +1085,18 @@
+ next();
+
+ // Get initializer expression. Suppress IN if not statement.
+- init = assignmentExpression(!isStatement);
++ defaultNames.push(name);
++ try {
++ init = assignmentExpression(!isStatement);
++ } finally {
++ defaultNames.pop();
++ }
++ } else if (varType == CONST) {
++ throw error(AbstractParser.message("missing.const.assignment", name.getName()));
+ }
+
+ // Allocate var node.
+- final VarNode var = new VarNode(varLine, varToken, finish, name, init);
++ final VarNode var = new VarNode(varLine, varToken, finish, name.setIsDeclaredHere(), init, varFlags);
+ vars.add(var);
+ appendStatement(var);
+
+@@ -986,7 +1108,7 @@
+
+ // If is a statement then handle end of line.
+ if (isStatement) {
+- boolean semicolon = type == SEMICOLON;
++ final boolean semicolon = type == SEMICOLON;
+ endOfLine();
+ if (semicolon) {
+ lc.getCurrentBlock().setFinish(finish);
+@@ -1088,9 +1210,12 @@
+ * Parse a FOR statement.
+ */
+ private void forStatement() {
++ // When ES6 for-let is enabled we create a container block to capture the LET.
++ final int startLine = start;
++ Block outer = useBlockScope() ? newBlock() : null;
++
+ // Create FOR node, capturing FOR token.
+- ForNode forNode = new ForNode(line, token, Token.descPosition(token), null, null, null, null, ForNode.IS_FOR);
+-
++ ForNode forNode = new ForNode(line, token, Token.descPosition(token), null, 0);
+ lc.push(forNode);
+
+ try {
+@@ -1110,15 +1235,23 @@
+
+ switch (type) {
+ case VAR:
+- // Var statements captured in for outer block.
+- vars = variableStatement(false);
++ // Var declaration captured in for outer block.
++ vars = variableStatement(type, false);
+ break;
+ case SEMICOLON:
+ break;
+ default:
++ if (useBlockScope() && (type == LET || type == CONST)) {
++ if (type == LET) {
++ forNode = forNode.setPerIterationScope(lc);
++ }
++ // LET/CONST declaration captured in container block created above.
++ vars = variableStatement(type, false);
++ break;
++ }
+ if (env._const_as_var && type == CONST) {
+- // Var statements captured in for outer block.
+- vars = variableStatement(false);
++ // Var declaration captured in for outer block.
++ vars = variableStatement(TokenType.VAR, false);
+ break;
+ }
+
+@@ -1138,16 +1271,16 @@
+
+ expect(SEMICOLON);
+ if (type != SEMICOLON) {
+- forNode = forNode.setTest(lc, expression());
++ forNode = forNode.setTest(lc, joinPredecessorExpression());
+ }
+ expect(SEMICOLON);
+ if (type != RPAREN) {
+- forNode = forNode.setModify(lc, expression());
++ forNode = forNode.setModify(lc, joinPredecessorExpression());
+ }
+ break;
+
+ case IN:
+- forNode = forNode.setIsForIn(lc);
++ forNode = forNode.setIsForIn(lc).setTest(lc, new JoinPredecessorExpression());
+ if (vars != null) {
+ // for (var i in obj)
+ if (vars.size() == 1) {
+@@ -1180,7 +1313,7 @@
+ next();
+
+ // Get the collection expression.
+- forNode = forNode.setModify(lc, expression());
++ forNode = forNode.setModify(lc, joinPredecessorExpression());
+ break;
+
+ default:
+@@ -1199,7 +1332,13 @@
+ } finally {
+ lc.pop(forNode);
+ }
+- }
++
++ if (outer != null) {
++ outer.setFinish(forNode.getFinish());
++ outer = restoreBlock(outer);
++ appendStatement(new BlockStatement(startLine, outer));
++ }
++ }
+
+ /**
+ * ... IterationStatement :
+@@ -1240,7 +1379,7 @@
+ try {
+ expect(LPAREN);
+ final int whileLine = line;
+- final Expression test = expression();
++ final JoinPredecessorExpression test = joinPredecessorExpression();
+ expect(RPAREN);
+ final Block body = getStatement();
+ appendStatement(whileNode =
+@@ -1278,7 +1417,7 @@
+ expect(WHILE);
+ expect(LPAREN);
+ final int doLine = line;
+- final Expression test = expression();
++ final JoinPredecessorExpression test = joinPredecessorExpression();
+ expect(RPAREN);
+
+ if (type == SEMICOLON) {
+@@ -1332,8 +1471,8 @@
+ break;
+ }
+
+- final IdentNode label = labelNode == null ? null : labelNode.getLabel();
+- final LoopNode targetNode = lc.getContinueTo(label);
++ final String labelName = labelNode == null ? null : labelNode.getLabelName();
++ final LoopNode targetNode = lc.getContinueTo(labelName);
+
+ if (targetNode == null) {
+ throw error(AbstractParser.message("illegal.continue.stmt"), continueToken);
+@@ -1342,7 +1481,7 @@
+ endOfLine();
+
+ // Construct and add CONTINUE node.
+- appendStatement(new ContinueNode(continueLine, continueToken, finish, label == null ? null : new IdentNode(label)));
++ appendStatement(new ContinueNode(continueLine, continueToken, finish, labelName));
+ }
+
+ /**
+@@ -1382,8 +1521,8 @@
+
+ //either an explicit label - then get its node or just a "break" - get first breakable
+ //targetNode is what we are breaking out from.
+- final IdentNode label = labelNode == null ? null : labelNode.getLabel();
+- final BreakableNode targetNode = lc.getBreakable(label);
++ final String labelName = labelNode == null ? null : labelNode.getLabelName();
++ final BreakableNode targetNode = lc.getBreakable(labelName);
+ if (targetNode == null) {
+ throw error(AbstractParser.message("illegal.break.stmt"), breakToken);
+ }
+@@ -1391,7 +1530,7 @@
+ endOfLine();
+
+ // Construct and add BREAK node.
+- appendStatement(new BreakNode(breakLine, breakToken, finish, label == null ? null : new IdentNode(label)));
++ appendStatement(new BreakNode(breakLine, breakToken, finish, labelName));
+ }
+
+ /**
+@@ -1618,7 +1757,7 @@
+ throw error(AbstractParser.message("duplicate.label", ident.getName()), labelToken);
+ }
+
+- LabelNode labelNode = new LabelNode(line, labelToken, finish, ident, null);
++ LabelNode labelNode = new LabelNode(line, labelToken, finish, ident.getName(), null);
+ try {
+ lc.push(labelNode);
+ labelNode = labelNode.setBody(lc, getStatement());
+@@ -1630,7 +1769,7 @@
+ }
+ }
+
+- /**
++ /**
+ * ThrowStatement :
+ * throw Expression ; // [no LineTerminator here]
+ *
+@@ -1665,7 +1804,7 @@
+
+ endOfLine();
+
+- appendStatement(new ThrowNode(throwLine, throwToken, finish, expression, 0));
++ appendStatement(new ThrowNode(throwLine, throwToken, finish, expression, false));
+ }
+
+ /**
+@@ -1730,7 +1869,7 @@
+ try {
+ // Get CATCH body.
+ final Block catchBody = getBlock(true);
+- final CatchNode catchNode = new CatchNode(catchLine, catchToken, finish, exception, ifExpression, catchBody, 0);
++ final CatchNode catchNode = new CatchNode(catchLine, catchToken, finish, exception, ifExpression, catchBody, false);
+ appendStatement(catchNode);
+ } finally {
+ catchBlock = restoreBlock(catchBlock);
+@@ -1892,7 +2031,7 @@
+ // Skip ending of edit string expression.
+ expect(RBRACE);
+
+- return new CallNode(primaryLine, primaryToken, finish, execIdent, arguments);
++ return new CallNode(primaryLine, primaryToken, finish, execIdent, arguments, false);
+ }
+
+ /**
+@@ -2128,8 +2267,8 @@
+ private PropertyNode propertyAssignment() {
+ // Capture firstToken.
+ final long propertyToken = token;
+-
+- FunctionNode functionNode;
++ final int functionLine = line;
++
+ PropertyKey propertyName;
+
+ if (type == IDENT) {
+@@ -2141,49 +2280,75 @@
+
+ switch (ident) {
+ case "get":
+- final PropertyKey getIdent = propertyName();
+- final String getterName = getIdent.getPropertyName();
+- final IdentNode getNameNode = new IdentNode(((Node)getIdent).getToken(), finish, NameCodec.encode("get " + getterName));
+- expect(LPAREN);
+- expect(RPAREN);
+- functionNode = functionBody(getSetToken, getNameNode, new ArrayList<IdentNode>(), FunctionNode.Kind.GETTER);
+- return new PropertyNode(propertyToken, finish, getIdent, null, functionNode, null);
++ final PropertyFunction getter = propertyGetterFunction(getSetToken, functionLine);
++ return new PropertyNode(propertyToken, finish, getter.ident, null, getter.functionNode, null);
+
+ case "set":
+- final PropertyKey setIdent = propertyName();
+- final String setterName = setIdent.getPropertyName();
+- final IdentNode setNameNode = new IdentNode(((Node)setIdent).getToken(), finish, NameCodec.encode("set " + setterName));
+- expect(LPAREN);
+- // be sloppy and allow missing setter parameter even though
+- // spec does not permit it!
+- final IdentNode argIdent;
+- if (type == IDENT || isNonStrictModeIdent()) {
+- argIdent = getIdent();
+- verifyStrictIdent(argIdent, "setter argument");
+- } else {
+- argIdent = null;
+- }
+- expect(RPAREN);
+- List<IdentNode> parameters = new ArrayList<>();
+- if (argIdent != null) {
+- parameters.add(argIdent);
+- }
+- functionNode = functionBody(getSetToken, setNameNode, parameters, FunctionNode.Kind.SETTER);
+- return new PropertyNode(propertyToken, finish, setIdent, null, null, functionNode);
+-
++ final PropertyFunction setter = propertySetterFunction(getSetToken, functionLine);
++ return new PropertyNode(propertyToken, finish, setter.ident, null, null, setter.functionNode);
+ default:
+ break;
+ }
+ }
+
+- propertyName = new IdentNode(propertyToken, finish, ident).setIsPropertyName();
++ propertyName = createIdentNode(propertyToken, finish, ident).setIsPropertyName();
+ } else {
+ propertyName = propertyName();
+ }
+
+ expect(COLON);
+
+- return new PropertyNode(propertyToken, finish, propertyName, assignmentExpression(false), null, null);
++ defaultNames.push(propertyName);
++ try {
++ return new PropertyNode(propertyToken, finish, propertyName, assignmentExpression(false), null, null);
++ } finally {
++ defaultNames.pop();
++ }
++ }
++
++ private PropertyFunction propertyGetterFunction(final long getSetToken, final int functionLine) {
++ final PropertyKey getIdent = propertyName();
++ final String getterName = getIdent.getPropertyName();
++ final IdentNode getNameNode = createIdentNode(((Node)getIdent).getToken(), finish, NameCodec.encode("get " + getterName));
++ expect(LPAREN);
++ expect(RPAREN);
++ final FunctionNode functionNode = functionBody(getSetToken, getNameNode, new ArrayList<IdentNode>(), FunctionNode.Kind.GETTER, functionLine);
++
++ return new PropertyFunction(getIdent, functionNode);
++ }
++
++ private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine) {
++ final PropertyKey setIdent = propertyName();
++ final String setterName = setIdent.getPropertyName();
++ final IdentNode setNameNode = createIdentNode(((Node)setIdent).getToken(), finish, NameCodec.encode("set " + setterName));
++ expect(LPAREN);
++ // be sloppy and allow missing setter parameter even though
++ // spec does not permit it!
++ final IdentNode argIdent;
++ if (type == IDENT || isNonStrictModeIdent()) {
++ argIdent = getIdent();
++ verifyStrictIdent(argIdent, "setter argument");
++ } else {
++ argIdent = null;
++ }
++ expect(RPAREN);
++ final List<IdentNode> parameters = new ArrayList<>();
++ if (argIdent != null) {
++ parameters.add(argIdent);
++ }
++ final FunctionNode functionNode = functionBody(getSetToken, setNameNode, parameters, FunctionNode.Kind.SETTER, functionLine);
++
++ return new PropertyFunction(setIdent, functionNode);
++ }
++
++ private static class PropertyFunction {
++ final PropertyKey ident;
++ final FunctionNode functionNode;
++
++ PropertyFunction(final PropertyKey ident, final FunctionNode function) {
++ this.ident = ident;
++ this.functionNode = function;
++ }
+ }
+
+ /**
+@@ -2216,7 +2381,7 @@
+ detectSpecialFunction((IdentNode)lhs);
+ }
+
+- lhs = new CallNode(callLine, callToken, finish, lhs, arguments);
++ lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
+ }
+
+ loop:
+@@ -2231,7 +2396,7 @@
+ final List<Expression> arguments = optimizeList(argumentList());
+
+ // Create call node.
+- lhs = new CallNode(callLine, callToken, finish, lhs, arguments);
++ lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
+
+ break;
+
+@@ -2254,7 +2419,7 @@
+ final IdentNode property = getIdentifierName();
+
+ // Create property access node.
+- lhs = new AccessNode(callToken, finish, lhs, property);
++ lhs = new AccessNode(callToken, finish, lhs, property.getName());
+
+ break;
+
+@@ -2310,7 +2475,7 @@
+ arguments.add(objectLiteral());
+ }
+
+- final CallNode callNode = new CallNode(callLine, constructor.getToken(), finish, constructor, optimizeList(arguments));
++ final CallNode callNode = new CallNode(callLine, constructor.getToken(), finish, constructor, optimizeList(arguments), true);
+
+ return new UnaryNode(newToken, callNode);
+ }
+@@ -2334,7 +2499,7 @@
+
+ switch (type) {
+ case NEW:
+- // Get new exppression.
++ // Get new expression.
+ lhs = newExpression();
+ break;
+
+@@ -2378,7 +2543,7 @@
+ final IdentNode property = getIdentifierName();
+
+ // Create property access node.
+- lhs = new AccessNode(callToken, finish, lhs, property);
++ lhs = new AccessNode(callToken, finish, lhs, property.getName());
+
+ break;
+
+@@ -2429,7 +2594,7 @@
+ return nodeList;
+ }
+
+- private static <T> List<T> optimizeList(ArrayList<T> list) {
++ private static <T> List<T> optimizeList(final ArrayList<T> list) {
+ switch(list.size()) {
+ case 0: {
+ return Collections.emptyList();
+@@ -2479,7 +2644,7 @@
+ // name is null, generate anonymous name
+ boolean isAnonymous = false;
+ if (name == null) {
+- final String tmpName = ANON_FUNCTION_PREFIX.symbolName() + functionLine;
++ final String tmpName = getDefaultValidFunctionName(functionLine, isStatement);
+ name = new IdentNode(functionToken, Token.descPosition(functionToken), tmpName);
+ isAnonymous = true;
+ }
+@@ -2488,10 +2653,18 @@
+ final List<IdentNode> parameters = formalParameterList();
+ expect(RPAREN);
+
+- FunctionNode functionNode = functionBody(functionToken, name, parameters, FunctionNode.Kind.NORMAL);
++ FunctionNode functionNode;
++ // Hide the current default name across function boundaries. E.g. "x3 = function x1() { function() {}}"
++ // If we didn't hide the current default name, then the innermost anonymous function would receive "x3".
++ hideDefaultName();
++ try {
++ functionNode = functionBody(functionToken, name, parameters, FunctionNode.Kind.NORMAL, functionLine);
++ } finally {
++ defaultNames.pop();
++ }
+
+ if (isStatement) {
+- if (topLevel) {
++ if (topLevel || useBlockScope()) {
+ functionNode = functionNode.setFlag(lc, FunctionNode.IS_DECLARED);
+ } else if (isStrictMode) {
+ throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("strict.no.func.decl.here"), functionToken);
+@@ -2543,9 +2716,12 @@
+ }
+
+ if (isStatement) {
+- final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, VarNode.IS_STATEMENT);
++ final int varFlags = (topLevel || !useBlockScope()) ? 0 : VarNode.IS_LET;
++ final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, varFlags);
+ if (topLevel) {
+ functionDeclarations.add(varNode);
++ } else if (useBlockScope()) {
++ prependStatement(varNode); // Hoist to beginning of current block
+ } else {
+ appendStatement(varNode);
+ }
+@@ -2554,6 +2730,59 @@
+ return functionNode;
+ }
+
++ private String getDefaultValidFunctionName(final int functionLine, final boolean isStatement) {
++ final String defaultFunctionName = getDefaultFunctionName();
++ if (isValidIdentifier(defaultFunctionName)) {
++ if (isStatement) {
++ // The name will be used as the LHS of a symbol assignment. We add the anonymous function
++ // prefix to ensure that it can't clash with another variable.
++ return ANON_FUNCTION_PREFIX.symbolName() + defaultFunctionName;
++ }
++ return defaultFunctionName;
++ }
++ return ANON_FUNCTION_PREFIX.symbolName() + functionLine;
++ }
++
++ private static boolean isValidIdentifier(final String name) {
++ if(name == null || name.isEmpty()) {
++ return false;
++ }
++ if(!Character.isJavaIdentifierStart(name.charAt(0))) {
++ return false;
++ }
++ for(int i = 1; i < name.length(); ++i) {
++ if(!Character.isJavaIdentifierPart(name.charAt(i))) {
++ return false;
++ }
++ }
++ return true;
++ }
++
++ private String getDefaultFunctionName() {
++ if(!defaultNames.isEmpty()) {
++ final Object nameExpr = defaultNames.peek();
++ if(nameExpr instanceof PropertyKey) {
++ markDefaultNameUsed();
++ return ((PropertyKey)nameExpr).getPropertyName();
++ } else if(nameExpr instanceof AccessNode) {
++ markDefaultNameUsed();
++ return ((AccessNode)nameExpr).getProperty();
++ }
++ }
++ return null;
++ }
++
++ private void markDefaultNameUsed() {
++ defaultNames.pop();
++ hideDefaultName();
++ }
++
++ private void hideDefaultName() {
++ // Can be any value as long as getDefaultFunctionName doesn't recognize it as something it can extract a value
++ // from. Can't be null
++ defaultNames.push("");
++ }
++
+ /**
+ * FormalParameterList :
+ * Identifier
+@@ -2583,7 +2812,7 @@
+ */
+ private List<IdentNode> formalParameterList(final TokenType endType) {
+ // Prepare to gather parameters.
+- final List<IdentNode> parameters = new ArrayList<>();
++ final ArrayList<IdentNode> parameters = new ArrayList<>();
+ // Track commas.
+ boolean first = true;
+
+@@ -2604,6 +2833,7 @@
+ parameters.add(ident);
+ }
+
++ parameters.trimToSize();
+ return parameters;
+ }
+
+@@ -2616,14 +2846,18 @@
+ * Parse function body.
+ * @return function node (body.)
+ */
+- private FunctionNode functionBody(final long firstToken, final IdentNode ident, final List<IdentNode> parameters, final FunctionNode.Kind kind) {
++ private FunctionNode functionBody(final long firstToken, final IdentNode ident, final List<IdentNode> parameters, final FunctionNode.Kind kind, final int functionLine) {
+ FunctionNode functionNode = null;
+ long lastToken = 0L;
+
++ final boolean parseBody;
++ Object endParserState = null;
+ try {
+ // Create a new function block.
+- functionNode = newFunctionNode(firstToken, ident, parameters, kind);
+-
++ functionNode = newFunctionNode(firstToken, ident, parameters, kind, functionLine);
++ assert functionNode != null;
++ final int functionId = functionNode.getId();
++ parseBody = reparsedFunction == null || functionId <= reparsedFunction.getFunctionNodeId();
+ // Nashorn extension: expression closures
+ if (!env._no_syntax_extensions && type != LBRACE) {
+ /*
+@@ -2635,38 +2869,160 @@
+
+ // just expression as function body
+ final Expression expr = assignmentExpression(true);
++ lastToken = previousToken;
+ assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode);
+- final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), finish, expr);
+- appendStatement(returnNode);
+- lastToken = token;
+- functionNode.setFinish(Token.descPosition(token) + Token.descLength(token));
+-
++ // EOL uses length field to store the line number
++ final int lastFinish = Token.descPosition(lastToken) + (Token.descType(lastToken) == EOL ? 0 : Token.descLength(lastToken));
++ // Only create the return node if we aren't skipping nested functions. Note that we aren't
++ // skipping parsing of these extended functions; they're considered to be small anyway. Also,
++ // they don't end with a single well known token, so it'd be very hard to get correctly (see
++ // the note below for reasoning on skipping happening before instead of after RBRACE for
++ // details).
++ if (parseBody) {
++ final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), lastFinish, expr);
++ appendStatement(returnNode);
++ }
++ functionNode.setFinish(lastFinish);
+ } else {
+- expect(LBRACE);
+-
+- // Gather the function elements.
+- final List<Statement> prevFunctionDecls = functionDeclarations;
+- functionDeclarations = new ArrayList<>();
+- try {
+- sourceElements();
+- addFunctionDeclarations(functionNode);
+- } finally {
+- functionDeclarations = prevFunctionDecls;
++ expectDontAdvance(LBRACE);
++ if (parseBody || !skipFunctionBody(functionNode)) {
++ next();
++ // Gather the function elements.
++ final List<Statement> prevFunctionDecls = functionDeclarations;
++ functionDeclarations = new ArrayList<>();
++ try {
++ sourceElements(false);
++ addFunctionDeclarations(functionNode);
++ } finally {
++ functionDeclarations = prevFunctionDecls;
++ }
++
++ lastToken = token;
++ if (parseBody) {
++ // Since the lexer can read ahead and lexify some number of tokens in advance and have
++ // them buffered in the TokenStream, we need to produce a lexer state as it was just
++ // before it lexified RBRACE, and not whatever is its current (quite possibly well read
++ // ahead) state.
++ endParserState = new ParserState(Token.descPosition(token), line, linePosition);
++
++ // NOTE: you might wonder why do we capture/restore parser state before RBRACE instead of
++ // after RBRACE; after all, we could skip the below "expect(RBRACE);" if we captured the
++ // state after it. The reason is that RBRACE is a well-known token that we can expect and
++ // will never involve us getting into a weird lexer state, and as such is a great reparse
++ // point. Typical example of a weird lexer state after RBRACE would be:
++ // function this_is_skipped() { ... } "use strict";
++ // because lexer is doing weird off-by-one maneuvers around string literal quotes. Instead
++ // of compensating for the possibility of a string literal (or similar) after RBRACE,
++ // we'll rather just restart parsing from this well-known, friendly token instead.
++ }
+ }
+-
+- lastToken = token;
+ expect(RBRACE);
+ functionNode.setFinish(finish);
+-
+ }
+ } finally {
+ functionNode = restoreFunctionNode(functionNode, lastToken);
+ }
++
++ // NOTE: we can only do alterations to the function node after restoreFunctionNode.
++
++ if (parseBody) {
++ functionNode = functionNode.setEndParserState(lc, endParserState);
++ } else if (functionNode.getBody().getStatementCount() > 0){
++ // This is to ensure the body is empty when !parseBody but we couldn't skip parsing it (see
++ // skipFunctionBody() for possible reasons). While it is not strictly necessary for correctness to
++ // enforce empty bodies in nested functions that were supposed to be skipped, we do assert it as
++ // an invariant in few places in the compiler pipeline, so for consistency's sake we'll throw away
++ // nested bodies early if we were supposed to skip 'em.
++ functionNode = functionNode.setBody(null, functionNode.getBody().setStatements(null,
++ Collections.<Statement>emptyList()));
++ }
++
++ if (reparsedFunction != null) {
++ // We restore the flags stored in the function's ScriptFunctionData that we got when we first
++ // eagerly parsed the code. We're doing it because some flags would be set based on the
++ // content of the function, or even content of its nested functions, most of which are normally
++ // skipped during an on-demand compilation.
++ final RecompilableScriptFunctionData data = reparsedFunction.getScriptFunctionData(functionNode.getId());
++ if (data != null) {
++ // Data can be null if when we originally parsed the file, we removed the function declaration
++ // as it was dead code.
++ functionNode = functionNode.setFlags(lc, data.getFunctionFlags());
++ // This compensates for missing markEval() in case the function contains an inner function
++ // that contains eval(), that now we didn't discover since we skipped the inner function.
++ if (functionNode.hasNestedEval()) {
++ assert functionNode.hasScopeBlock();
++ functionNode = functionNode.setBody(lc, functionNode.getBody().setNeedsScope(null));
++ }
++ }
++ }
++ printAST(functionNode);
+ return functionNode;
+ }
+
++ private boolean skipFunctionBody(final FunctionNode functionNode) {
++ if (reparsedFunction == null) {
++ // Not reparsing, so don't skip any function body.
++ return false;
++ }
++ // Skip to the RBRACE of this function, and continue parsing from there.
++ final RecompilableScriptFunctionData data = reparsedFunction.getScriptFunctionData(functionNode.getId());
++ if (data == null) {
++ // Nested function is not known to the reparsed function. This can happen if the FunctionNode was
++ // in dead code that was removed. Both FoldConstants and Lower prune dead code. In that case, the
++ // FunctionNode was dropped before a RecompilableScriptFunctionData could've been created for it.
++ return false;
++ }
++ final ParserState parserState = (ParserState)data.getEndParserState();
++ assert parserState != null;
++
++ stream.reset();
++ lexer = parserState.createLexer(source, lexer, stream, scripting && !env._no_syntax_extensions);
++ line = parserState.line;
++ linePosition = parserState.linePosition;
++ // Doesn't really matter, but it's safe to treat it as if there were a semicolon before
++ // the RBRACE.
++ type = SEMICOLON;
++ k = -1;
++ next();
++
++ return true;
++ }
++
++ /**
++ * Encapsulates part of the state of the parser, enough to reconstruct the state of both parser and lexer
++ * for resuming parsing after skipping a function body.
++ */
++ private static class ParserState implements Serializable {
++ private final int position;
++ private final int line;
++ private final int linePosition;
++
++ private static final long serialVersionUID = -2382565130754093694L;
++
++ ParserState(final int position, final int line, final int linePosition) {
++ this.position = position;
++ this.line = line;
++ this.linePosition = linePosition;
++ }
++
++ Lexer createLexer(final Source source, final Lexer lexer, final TokenStream stream, final boolean scripting) {
++ final Lexer newLexer = new Lexer(source, position, lexer.limit - position, stream, scripting, true);
++ newLexer.restoreState(new Lexer.State(position, Integer.MAX_VALUE, line, -1, linePosition, SEMICOLON));
++ return newLexer;
++ }
++ }
++
++ private void printAST(final FunctionNode functionNode) {
++ if (functionNode.getFlag(FunctionNode.IS_PRINT_AST)) {
++ env.getErr().println(new ASTWriter(functionNode));
++ }
++
++ if (functionNode.getFlag(FunctionNode.IS_PRINT_PARSE)) {
++ env.getErr().println(new PrintVisitor(functionNode, true, false));
++ }
++ }
++
+ private void addFunctionDeclarations(final FunctionNode functionNode) {
+- assert lc.peek() == lc.getFunctionBody(functionNode);
+ VarNode lastDecl = null;
+ for (int i = functionDeclarations.size() - 1; i >= 0; i--) {
+ Statement decl = functionDeclarations.get(i);
+@@ -2919,6 +3275,10 @@
+ return expression(unaryExpression(), COMMARIGHT.getPrecedence(), false);
+ }
+
++ private JoinPredecessorExpression joinPredecessorExpression() {
++ return new JoinPredecessorExpression(expression());
++ }
++
+ private Expression expression(final Expression exprLhs, final int minPrecedence, final boolean noIn) {
+ // Get the precedence of the next operator.
+ int precedence = type.getPrecedence();
+@@ -2935,33 +3295,42 @@
+
+ // Pass expression. Middle expression of a conditional expression can be a "in"
+ // expression - even in the contexts where "in" is not permitted.
+- final Expression rhs = expression(unaryExpression(), ASSIGN.getPrecedence(), false);
++ final Expression trueExpr = expression(unaryExpression(), ASSIGN.getPrecedence(), false);
+
+ expect(COLON);
+
+ // Fail expression.
+- final Expression third = expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
++ final Expression falseExpr = expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
+
+ // Build up node.
+- lhs = new TernaryNode(op, lhs, rhs, third);
++ lhs = new TernaryNode(op, lhs, new JoinPredecessorExpression(trueExpr), new JoinPredecessorExpression(falseExpr));
+ } else {
+ // Skip operator.
+ next();
+
+ // Get the next primary expression.
+- Expression rhs = unaryExpression();
+-
+- // Get precedence of next operator.
+- int nextPrecedence = type.getPrecedence();
+-
+- // Subtask greater precedence.
+- while (type.isOperator(noIn) &&
+- (nextPrecedence > precedence ||
+- nextPrecedence == precedence && !type.isLeftAssociative())) {
+- rhs = expression(rhs, nextPrecedence, noIn);
+- nextPrecedence = type.getPrecedence();
++ Expression rhs;
++ final boolean isAssign = Token.descType(op) == ASSIGN;
++ if(isAssign) {
++ defaultNames.push(lhs);
+ }
+-
++ try {
++ rhs = unaryExpression();
++ // Get precedence of next operator.
++ int nextPrecedence = type.getPrecedence();
++
++ // Subtask greater precedence.
++ while (type.isOperator(noIn) &&
++ (nextPrecedence > precedence ||
++ nextPrecedence == precedence && !type.isLeftAssociative())) {
++ rhs = expression(rhs, nextPrecedence, noIn);
++ nextPrecedence = type.getPrecedence();
++ }
++ } finally {
++ if(isAssign) {
++ defaultNames.pop();
++ }
++ }
+ lhs = verifyAssignment(op, lhs, rhs);
+ }
+
+@@ -3001,7 +3370,7 @@
+
+ @Override
+ public String toString() {
+- return "[JavaScript Parsing]";
++ return "'JavaScript Parsing'";
+ }
+
+ private static void markEval(final LexicalContext lc) {
+@@ -3015,6 +3384,9 @@
+ } else {
+ lc.setFlag(fn, FunctionNode.HAS_NESTED_EVAL);
+ }
++ // NOTE: it is crucial to mark the body of the outer function as needing scope even when we skip
++ // parsing a nested function. functionBody() contains code to compensate for the lack of invoking
++ // this method when the parser skips a nested function.
+ lc.setBlockNeedsScope(lc.getFunctionBody(fn));
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/parser/Token.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/parser/Token.java Wed Feb 04 12:14:47 2015 -0800
+@@ -61,6 +61,28 @@
+ }
+
+ /**
++ * Normally returns the token itself, except in case of string tokens
++ * which report their position past their opening delimiter and thus
++ * need to have position and length adjusted.
++ *
++ * @param token Token descriptor.
++ * @return same or adjusted token.
++ */
++ public static long withDelimiter(final long token) {
++ final TokenType tokenType = Token.descType(token);
++ switch(tokenType) {
++ case STRING: case ESCSTRING: case EXECSTRING: {
++ final int start = Token.descPosition(token) - 1;
++ final int len = Token.descLength(token) + 2;
++ return toDesc(tokenType, start, len);
++ }
++ default: {
++ return token;
++ }
++ }
++ }
++
++ /**
+ * Extract token length from a token descriptor.
+ * @param token Token descriptor.
+ * @return Length of the token.
+--- ./nashorn/src/jdk/nashorn/internal/parser/TokenStream.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/parser/TokenStream.java Wed Feb 04 12:14:47 2015 -0800
+@@ -209,4 +209,8 @@
+ in = count;
+ buffer = newBuffer;
+ }
++
++ void reset() {
++ in = out = count = base = 0;
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/parser/TokenType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/parser/TokenType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,7 +25,6 @@
+
+ package jdk.nashorn.internal.parser;
+
+-import java.util.Locale;
+ import static jdk.nashorn.internal.parser.TokenKind.BINARY;
+ import static jdk.nashorn.internal.parser.TokenKind.BRACKET;
+ import static jdk.nashorn.internal.parser.TokenKind.FUTURE;
+@@ -36,6 +35,8 @@
+ import static jdk.nashorn.internal.parser.TokenKind.SPECIAL;
+ import static jdk.nashorn.internal.parser.TokenKind.UNARY;
+
++import java.util.Locale;
++
+ /**
+ * Description of all the JavaScript tokens.
+ */
+@@ -182,7 +183,6 @@
+ ARRAY (LITERAL, null),
+
+ COMMALEFT (IR, null),
+- DISCARD (IR, null),
+ DECPOSTFIX (IR, null),
+ INCPOSTFIX (IR, null);
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,38 +25,38 @@
+
+ package jdk.nashorn.internal.runtime;
+
+-import static jdk.nashorn.internal.codegen.ObjectClassGenerator.ACCESSOR_TYPES;
+-import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS;
+-import static jdk.nashorn.internal.codegen.ObjectClassGenerator.LOG;
+ import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
+-import static jdk.nashorn.internal.codegen.ObjectClassGenerator.PRIMITIVE_TYPE;
++import static jdk.nashorn.internal.codegen.ObjectClassGenerator.PRIMITIVE_FIELD_TYPE;
+ import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createGetter;
+-import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createGuardBoxedPrimitiveSetter;
+ import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createSetter;
+-import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getAccessorType;
+-import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getAccessorTypeIndex;
+-import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getNumberOfAccessorTypes;
++import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getFieldCount;
++import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getFieldName;
+ import static jdk.nashorn.internal.lookup.Lookup.MH;
+ import static jdk.nashorn.internal.lookup.MethodHandleFactory.stripName;
+-
++import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex;
++import static jdk.nashorn.internal.runtime.JSType.getNumberOfAccessorTypes;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
+ import java.io.IOException;
+ import java.io.ObjectInputStream;
+-import java.io.Serializable;
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+-import java.lang.invoke.MethodType;
++import java.lang.invoke.SwitchPoint;
++import java.util.function.Supplier;
++import java.util.logging.Level;
+ import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+ import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.lookup.Lookup;
+-import jdk.nashorn.internal.lookup.MethodHandleFactory;
++import jdk.nashorn.internal.objects.Global;
+
+ /**
+ * An AccessorProperty is the most generic property type. An AccessorProperty is
+ * represented as fields in a ScriptObject class.
+ */
+-public final class AccessorProperty extends Property implements Serializable {
+- private static final MethodHandles.Lookup lookup = MethodHandles.lookup();
+- private static final MethodHandle REPLACE_MAP = findOwnMH("replaceMap", Object.class, Object.class, PropertyMap.class, String.class, Class.class, Class.class);
++public class AccessorProperty extends Property {
++ private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
++
++ private static final MethodHandle REPLACE_MAP = findOwnMH_S("replaceMap", Object.class, Object.class, PropertyMap.class);
++ private static final MethodHandle INVALIDATE_SP = findOwnMH_S("invalidateSwitchPoint", Object.class, AccessorProperty.class, Object.class);
+
+ private static final int NOOF_TYPES = getNumberOfAccessorTypes();
+ private static final long serialVersionUID = 3371720170182154920L;
+@@ -67,49 +67,56 @@
+ * these are the most frequently retrieved ones, and lookup of method handle natives only registers in the profiler
+ * for them.
+ */
+- private static ClassValue<GettersSetters> GETTERS_SETTERS = new ClassValue<GettersSetters>() {
++ private static ClassValue<Accessors> GETTERS_SETTERS = new ClassValue<Accessors>() {
+ @Override
+- protected GettersSetters computeValue(Class<?> structure) {
+- return new GettersSetters(structure);
++ protected Accessors computeValue(final Class<?> structure) {
++ return new Accessors(structure);
+ }
+ };
+
+- /** Property getter cache */
+- private transient MethodHandle[] getters = new MethodHandle[NOOF_TYPES];
++ private static class Accessors {
++ final MethodHandle[] objectGetters;
++ final MethodHandle[] objectSetters;
++ final MethodHandle[] primitiveGetters;
++ final MethodHandle[] primitiveSetters;
+
+- private static final MethodType[] ACCESSOR_GETTER_TYPES = new MethodType[NOOF_TYPES];
+- private static final MethodType[] ACCESSOR_SETTER_TYPES = new MethodType[NOOF_TYPES];
+- private static final MethodType ACCESSOR_GETTER_PRIMITIVE_TYPE;
+- private static final MethodType ACCESSOR_SETTER_PRIMITIVE_TYPE;
+- private static final MethodHandle SPILL_ELEMENT_GETTER;
+- private static final MethodHandle SPILL_ELEMENT_SETTER;
++ /**
++ * Normal
++ * @param structure
++ */
++ Accessors(final Class<?> structure) {
++ final int fieldCount = getFieldCount(structure);
++ objectGetters = new MethodHandle[fieldCount];
++ objectSetters = new MethodHandle[fieldCount];
++ primitiveGetters = new MethodHandle[fieldCount];
++ primitiveSetters = new MethodHandle[fieldCount];
+
+- private static final int SPILL_CACHE_SIZE = 8;
+- private static final MethodHandle[] SPILL_ACCESSORS = new MethodHandle[SPILL_CACHE_SIZE * 2];
++ for (int i = 0; i < fieldCount; i++) {
++ final String fieldName = getFieldName(i, Type.OBJECT);
++ final Class<?> typeClass = Type.OBJECT.getTypeClass();
++ objectGetters[i] = MH.asType(MH.getter(LOOKUP, structure, fieldName, typeClass), Lookup.GET_OBJECT_TYPE);
++ objectSetters[i] = MH.asType(MH.setter(LOOKUP, structure, fieldName, typeClass), Lookup.SET_OBJECT_TYPE);
++ }
+
+- static {
+- MethodType getterPrimitiveType = null;
+- MethodType setterPrimitiveType = null;
+-
+- for (int i = 0; i < NOOF_TYPES; i++) {
+- final Type type = ACCESSOR_TYPES.get(i);
+- ACCESSOR_GETTER_TYPES[i] = MH.type(type.getTypeClass(), Object.class);
+- ACCESSOR_SETTER_TYPES[i] = MH.type(void.class, Object.class, type.getTypeClass());
+-
+- if (type == PRIMITIVE_TYPE) {
+- getterPrimitiveType = ACCESSOR_GETTER_TYPES[i];
+- setterPrimitiveType = ACCESSOR_SETTER_TYPES[i];
++ if (!OBJECT_FIELDS_ONLY) {
++ for (int i = 0; i < fieldCount; i++) {
++ final String fieldNamePrimitive = getFieldName(i, PRIMITIVE_FIELD_TYPE);
++ final Class<?> typeClass = PRIMITIVE_FIELD_TYPE.getTypeClass();
++ primitiveGetters[i] = MH.asType(MH.getter(LOOKUP, structure, fieldNamePrimitive, typeClass), Lookup.GET_PRIMITIVE_TYPE);
++ primitiveSetters[i] = MH.asType(MH.setter(LOOKUP, structure, fieldNamePrimitive, typeClass), Lookup.SET_PRIMITIVE_TYPE);
++ }
+ }
+ }
++ }
+
+- ACCESSOR_GETTER_PRIMITIVE_TYPE = getterPrimitiveType;
+- ACCESSOR_SETTER_PRIMITIVE_TYPE = setterPrimitiveType;
+-
+- final MethodType spillGetterType = MethodType.methodType(Object[].class, Object.class);
+- final MethodHandle spillGetter = MH.asType(MH.getter(MethodHandles.lookup(), ScriptObject.class, "spill", Object[].class), spillGetterType);
+- SPILL_ELEMENT_GETTER = MH.filterArguments(MH.arrayElementGetter(Object[].class), 0, spillGetter);
+- SPILL_ELEMENT_SETTER = MH.filterArguments(MH.arrayElementSetter(Object[].class), 0, spillGetter);
+- }
++ /**
++ * Property getter cache
++ * Note that we can't do the same simple caching for optimistic getters,
++ * due to the fact that they are bound to a program point, which will
++ * produce different boun method handles wrapping the same access mechanism
++ * depending on callsite
++ */
++ private transient MethodHandle[] GETTER_CACHE = new MethodHandle[NOOF_TYPES];
+
+ /**
+ * Create a new accessor property. Factory method used by nasgen generated code.
+@@ -126,23 +133,16 @@
+ }
+
+ /** Seed getter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */
+- private transient MethodHandle primitiveGetter;
++ transient MethodHandle primitiveGetter;
+
+ /** Seed setter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */
+- private transient MethodHandle primitiveSetter;
++ transient MethodHandle primitiveSetter;
+
+ /** Seed getter for the Object version of this field */
+- private transient MethodHandle objectGetter;
++ transient MethodHandle objectGetter;
+
+ /** Seed setter for the Object version of this field */
+- private transient MethodHandle objectSetter;
+-
+- /**
+- * Current type of this object, in object only mode, this is an Object.class. In dual-fields mode
+- * null means undefined, and primitive types are allowed. The reason a special type is used for
+- * undefined, is that are no bits left to represent it in primitive types
+- */
+- private Class<?> currentType;
++ transient MethodHandle objectSetter;
+
+ /**
+ * Delegate constructor for bound properties. This is used for properties created by
+@@ -156,33 +156,50 @@
+ * @param delegate delegate object to rebind receiver to
+ */
+ AccessorProperty(final AccessorProperty property, final Object delegate) {
+- super(property);
++ super(property, property.getFlags() | IS_BOUND);
+
+ this.primitiveGetter = bindTo(property.primitiveGetter, delegate);
+ this.primitiveSetter = bindTo(property.primitiveSetter, delegate);
+- this.objectGetter = bindTo(property.ensureObjectGetter(), delegate);
+- this.objectSetter = bindTo(property.ensureObjectSetter(), delegate);
+-
++ this.objectGetter = bindTo(property.objectGetter, delegate);
++ this.objectSetter = bindTo(property.objectSetter, delegate);
++ property.GETTER_CACHE = new MethodHandle[NOOF_TYPES];
+ // Properties created this way are bound to a delegate
+- this.flags |= IS_BOUND;
+- setCurrentType(property.getCurrentType());
++ setType(property.getType());
+ }
+
+ /**
++ * SPILL PROPERTY or USER ACCESSOR PROPERTY abstract constructor
++ *
+ * Constructor for spill properties. Array getters and setters will be created on demand.
+ *
+ * @param key the property key
+ * @param flags the property flags
+ * @param slot spill slot
++ * @param primitiveGetter primitive getter
++ * @param primitiveSetter primitive setter
++ * @param objectGetter object getter
++ * @param objectSetter object setter
+ */
+- public AccessorProperty(final String key, final int flags, final int slot) {
++ protected AccessorProperty(
++ final String key,
++ final int flags,
++ final int slot,
++ final MethodHandle primitiveGetter,
++ final MethodHandle primitiveSetter,
++ final MethodHandle objectGetter,
++ final MethodHandle objectSetter) {
+ super(key, flags, slot);
+- assert (flags & IS_SPILL) == IS_SPILL;
+-
+- setCurrentType(Object.class);
++ assert getClass() != AccessorProperty.class;
++ this.primitiveGetter = primitiveGetter;
++ this.primitiveSetter = primitiveSetter;
++ this.objectGetter = objectGetter;
++ this.objectSetter = objectSetter;
++ initializeType();
+ }
+
+ /**
++ * NASGEN constructor
++ *
+ * Constructor. Similar to the constructor with both primitive getters and setters, the difference
+ * here being that only one getter and setter (setter is optional for non writable fields) is given
+ * to the constructor, and the rest are created from those. Used e.g. by Nasgen classes
+@@ -193,8 +210,9 @@
+ * @param getter the property getter
+ * @param setter the property setter or null if non writable, non configurable
+ */
+- AccessorProperty(final String key, final int flags, final int slot, final MethodHandle getter, final MethodHandle setter) {
+- super(key, flags, slot);
++ private AccessorProperty(final String key, final int flags, final int slot, final MethodHandle getter, final MethodHandle setter) {
++ super(key, flags | IS_BUILTIN | (getter.type().returnType().isPrimitive() ? IS_NASGEN_PRIMITIVE : 0), slot);
++ assert !isSpill();
+
+ // we don't need to prep the setters these will never be invalidated as this is a nasgen
+ // or known type getter/setter. No invalidations will take place
+@@ -203,40 +221,31 @@
+ final Class<?> setterType = setter == null ? null : setter.type().parameterType(1);
+
+ assert setterType == null || setterType == getterType;
+-
+- if (getterType.isPrimitive()) {
+- for (int i = 0; i < NOOF_TYPES; i++) {
+- getters[i] = MH.asType(
+- Lookup.filterReturnType(
+- getter,
+- getAccessorType(i).getTypeClass()),
+- ACCESSOR_GETTER_TYPES[i]);
++ if (OBJECT_FIELDS_ONLY) {
++ primitiveGetter = primitiveSetter = null;
++ } else {
++ if (getterType == int.class || getterType == long.class) {
++ primitiveGetter = MH.asType(getter, Lookup.GET_PRIMITIVE_TYPE);
++ primitiveSetter = setter == null ? null : MH.asType(setter, Lookup.SET_PRIMITIVE_TYPE);
++ } else if (getterType == double.class) {
++ primitiveGetter = MH.asType(MH.filterReturnValue(getter, ObjectClassGenerator.PACK_DOUBLE), Lookup.GET_PRIMITIVE_TYPE);
++ primitiveSetter = setter == null ? null : MH.asType(MH.filterArguments(setter, 1, ObjectClassGenerator.UNPACK_DOUBLE), Lookup.SET_PRIMITIVE_TYPE);
++ } else {
++ primitiveGetter = primitiveSetter = null;
+ }
+- } else {
+- objectGetter = getter.type() != Lookup.GET_OBJECT_TYPE ? MH.asType(getter, Lookup.GET_OBJECT_TYPE) : getter;
+- objectSetter = setter != null && setter.type() != Lookup.SET_OBJECT_TYPE ? MH.asType(setter, Lookup.SET_OBJECT_TYPE) : setter;
+ }
+
+- setCurrentType(getterType);
+- }
++ assert primitiveGetter == null || primitiveGetter.type() == Lookup.GET_PRIMITIVE_TYPE : primitiveGetter + "!=" + Lookup.GET_PRIMITIVE_TYPE;
++ assert primitiveSetter == null || primitiveSetter.type() == Lookup.SET_PRIMITIVE_TYPE : primitiveSetter;
+
+- private static class GettersSetters {
+- final MethodHandle[] getters;
+- final MethodHandle[] setters;
++ objectGetter = getter.type() != Lookup.GET_OBJECT_TYPE ? MH.asType(getter, Lookup.GET_OBJECT_TYPE) : getter;
++ objectSetter = setter != null && setter.type() != Lookup.SET_OBJECT_TYPE ? MH.asType(setter, Lookup.SET_OBJECT_TYPE) : setter;
+
+- public GettersSetters(Class<?> structure) {
+- final int fieldCount = ObjectClassGenerator.getFieldCount(structure);
+- getters = new MethodHandle[fieldCount];
+- setters = new MethodHandle[fieldCount];
+- for(int i = 0; i < fieldCount; ++i) {
+- final String fieldName = ObjectClassGenerator.getFieldName(i, Type.OBJECT);
+- getters[i] = MH.asType(MH.getter(lookup, structure, fieldName, Type.OBJECT.getTypeClass()), Lookup.GET_OBJECT_TYPE);
+- setters[i] = MH.asType(MH.setter(lookup, structure, fieldName, Type.OBJECT.getTypeClass()), Lookup.SET_OBJECT_TYPE);
+- }
+- }
++ setType(OBJECT_FIELDS_ONLY ? Object.class : getterType);
+ }
+
+ /**
++ * Normal ACCESS PROPERTY constructor given a structure class.
+ * Constructor for dual field AccessorPropertys.
+ *
+ * @param key property key
+@@ -248,77 +257,119 @@
+ super(key, flags, slot);
+
+ initGetterSetter(structure);
++ initializeType();
+ }
+
+ private void initGetterSetter(final Class<?> structure) {
+ final int slot = getSlot();
+- final String key = getKey();
+ /*
+ * primitiveGetter and primitiveSetter are only used in dual fields mode. Setting them to null also
+ * works in dual field mode, it only means that the property never has a primitive
+ * representation.
+ */
+- primitiveGetter = null;
+- primitiveSetter = null;
+
+ if (isParameter() && hasArguments()) {
+- final MethodHandle arguments = MH.getter(lookup, structure, "arguments", ScriptObject.class);
+-
++ //parameters are always stored in an object array, which may or may not be a good idea
++ final MethodHandle arguments = MH.getter(LOOKUP, structure, "arguments", ScriptObject.class);
+ objectGetter = MH.asType(MH.insertArguments(MH.filterArguments(ScriptObject.GET_ARGUMENT.methodHandle(), 0, arguments), 1, slot), Lookup.GET_OBJECT_TYPE);
+ objectSetter = MH.asType(MH.insertArguments(MH.filterArguments(ScriptObject.SET_ARGUMENT.methodHandle(), 0, arguments), 1, slot), Lookup.SET_OBJECT_TYPE);
++ primitiveGetter = null;
++ primitiveSetter = null;
+ } else {
+- final GettersSetters gs = GETTERS_SETTERS.get(structure);
+- objectGetter = gs.getters[slot];
+- objectSetter = gs.setters[slot];
+-
+- if (!OBJECT_FIELDS_ONLY) {
+- final String fieldNamePrimitive = ObjectClassGenerator.getFieldName(slot, PRIMITIVE_TYPE);
+- final Class<?> typeClass = PRIMITIVE_TYPE.getTypeClass();
+- primitiveGetter = MH.asType(MH.getter(lookup, structure, fieldNamePrimitive, typeClass), ACCESSOR_GETTER_PRIMITIVE_TYPE);
+- primitiveSetter = MH.asType(MH.setter(lookup, structure, fieldNamePrimitive, typeClass), ACCESSOR_SETTER_PRIMITIVE_TYPE);
+- }
++ final Accessors gs = GETTERS_SETTERS.get(structure);
++ objectGetter = gs.objectGetters[slot];
++ primitiveGetter = gs.primitiveGetters[slot];
++ objectSetter = gs.objectSetters[slot];
++ primitiveSetter = gs.primitiveSetters[slot];
+ }
+-
+- Class<?> initialType = null;
+-
+- if (OBJECT_FIELDS_ONLY || isAlwaysObject()) {
+- initialType = Object.class;
+- } else if (!canBePrimitive()) {
+- info(key + " cannot be primitive");
+- initialType = Object.class;
+- } else {
+- info(key + " CAN be primitive");
+- if (!canBeUndefined()) {
+- info(key + " is always defined");
+- initialType = int.class; //double works too for less type invalidation, but this requires experimentation, e.g. var x = 17; x += 2 will turn it into double now because of lack of range analysis
+- }
+- }
+-
+- // is always object means "is never initialized to undefined, and always of object type
+- setCurrentType(initialType);
+ }
+
+ /**
+- * Copy constructor
++ * Constructor
+ *
+- * @param property source property
++ * @param key key
++ * @param flags flags
++ * @param slot field slot index
++ * @param owner owner of property
++ * @param initialValue initial value to which the property can be set
+ */
+- protected AccessorProperty(final AccessorProperty property) {
+- super(property);
++ protected AccessorProperty(final String key, final int flags, final int slot, final ScriptObject owner, final Object initialValue) {
++ this(key, flags, owner.getClass(), slot);
++ setInitialValue(owner, initialValue);
++ }
+
+- this.getters = property.getters;
++ /**
++ * Normal access property constructor that overrides the type
++ * Override the initial type. Used for Object Literals
++ *
++ * @param key key
++ * @param flags flags
++ * @param structure structure to JO subclass
++ * @param slot field slot index
++ * @param initialType initial type of the property
++ */
++ public AccessorProperty(final String key, final int flags, final Class<?> structure, final int slot, final Class<?> initialType) {
++ this(key, flags, structure, slot);
++ setType(OBJECT_FIELDS_ONLY ? Object.class : initialType);
++ }
++
++ /**
++ * Copy constructor that may change type and in that case clear the cache. Important to do that before
++ * type change or getters will be created already stale.
++ *
++ * @param property property
++ * @param newType new type
++ */
++ protected AccessorProperty(final AccessorProperty property, final Class<?> newType) {
++ super(property, property.getFlags());
++
++ this.GETTER_CACHE = newType != property.getLocalType() ? new MethodHandle[NOOF_TYPES] : property.GETTER_CACHE;
+ this.primitiveGetter = property.primitiveGetter;
+ this.primitiveSetter = property.primitiveSetter;
+ this.objectGetter = property.objectGetter;
+ this.objectSetter = property.objectSetter;
+
+- setCurrentType(property.getCurrentType());
++ setType(newType);
++ }
++
++ /**
++ * COPY constructor
++ *
++ * @param property source property
++ */
++ protected AccessorProperty(final AccessorProperty property) {
++ this(property, property.getLocalType());
++ }
++
++ /**
++ * Set initial value of a script object's property
++ * @param owner owner
++ * @param initialValue initial value
++ */
++ protected final void setInitialValue(final ScriptObject owner, final Object initialValue) {
++ setType(JSType.unboxedFieldType(initialValue));
++ if (initialValue instanceof Integer) {
++ invokeSetter(owner, ((Integer)initialValue).intValue());
++ } else if (initialValue instanceof Long) {
++ invokeSetter(owner, ((Long)initialValue).longValue());
++ } else if (initialValue instanceof Double) {
++ invokeSetter(owner, ((Double)initialValue).doubleValue());
++ } else {
++ invokeSetter(owner, initialValue);
++ }
++ }
++
++ /**
++ * Initialize the type of a property
++ */
++ protected final void initializeType() {
++ setType(OBJECT_FIELDS_ONLY ? Object.class : null);
+ }
+
+ private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException {
+ s.defaultReadObject();
+ // Restore getters array
+- getters = new MethodHandle[NOOF_TYPES];
++ GETTER_CACHE = new MethodHandle[NOOF_TYPES];
+ }
+
+ private static MethodHandle bindTo(final MethodHandle mh, final Object receiver) {
+@@ -330,83 +381,217 @@
+ }
+
+ @Override
+- protected Property copy() {
++ public Property copy() {
+ return new AccessorProperty(this);
+ }
+
+ @Override
+- public void setObjectValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict) {
+- if (isSpill()) {
+- self.spill[getSlot()] = value;
+- } else {
+- try {
+- getSetter(Object.class, self.getMap()).invokeExact((Object)self, value);
+- } catch (final Error|RuntimeException e) {
+- throw e;
+- } catch (final Throwable e) {
+- throw new RuntimeException(e);
+- }
+- }
++ public Property copy(final Class<?> newType) {
++ return new AccessorProperty(this, newType);
+ }
+
+ @Override
+- public Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
+- if (isSpill()) {
+- return self.spill[getSlot()];
++ public int getIntValue(final ScriptObject self, final ScriptObject owner) {
++ try {
++ return (int)getGetter(int.class).invokeExact((Object)self);
++ } catch (final Error | RuntimeException e) {
++ throw e;
++ } catch (final Throwable e) {
++ throw new RuntimeException(e);
+ }
++ }
+
++ @Override
++ public long getLongValue(final ScriptObject self, final ScriptObject owner) {
+ try {
+- return getGetter(Object.class).invokeExact((Object)self);
+- } catch (final Error|RuntimeException e) {
++ return (long)getGetter(long.class).invokeExact((Object)self);
++ } catch (final Error | RuntimeException e) {
+ throw e;
+ } catch (final Throwable e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+- // Spill getters and setters are lazily initialized, see JDK-8011630
+- private MethodHandle ensureObjectGetter() {
+- if (isSpill() && objectGetter == null) {
+- objectGetter = getSpillGetter();
++ @Override
++ public double getDoubleValue(final ScriptObject self, final ScriptObject owner) {
++ try {
++ return (double)getGetter(double.class).invokeExact((Object)self);
++ } catch (final Error | RuntimeException e) {
++ throw e;
++ } catch (final Throwable e) {
++ throw new RuntimeException(e);
+ }
+- return objectGetter;
+ }
+
+- private MethodHandle ensureObjectSetter() {
+- if (isSpill() && objectSetter == null) {
+- objectSetter = getSpillSetter();
++ @Override
++ public Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
++ try {
++ return getGetter(Object.class).invokeExact((Object)self);
++ } catch (final Error | RuntimeException e) {
++ throw e;
++ } catch (final Throwable e) {
++ throw new RuntimeException(e);
+ }
+- return objectSetter;
++ }
++
++ /**
++ * Invoke setter for this property with a value
++ * @param self owner
++ * @param value value
++ */
++ protected final void invokeSetter(final ScriptObject self, final int value) {
++ try {
++ getSetter(int.class, self.getMap()).invokeExact((Object)self, value);
++ } catch (final Error | RuntimeException e) {
++ throw e;
++ } catch (final Throwable e) {
++ throw new RuntimeException(e);
++ }
++ }
++
++ /**
++ * Invoke setter for this property with a value
++ * @param self owner
++ * @param value value
++ */
++ protected final void invokeSetter(final ScriptObject self, final long value) {
++ try {
++ getSetter(long.class, self.getMap()).invokeExact((Object)self, value);
++ } catch (final Error | RuntimeException e) {
++ throw e;
++ } catch (final Throwable e) {
++ throw new RuntimeException(e);
++ }
++ }
++
++ /**
++ * Invoke setter for this property with a value
++ * @param self owner
++ * @param value value
++ */
++ protected final void invokeSetter(final ScriptObject self, final double value) {
++ try {
++ getSetter(double.class, self.getMap()).invokeExact((Object)self, value);
++ } catch (final Error | RuntimeException e) {
++ throw e;
++ } catch (final Throwable e) {
++ throw new RuntimeException(e);
++ }
++ }
++
++ /**
++ * Invoke setter for this property with a value
++ * @param self owner
++ * @param value value
++ */
++ protected final void invokeSetter(final ScriptObject self, final Object value) {
++ try {
++ getSetter(Object.class, self.getMap()).invokeExact((Object)self, value);
++ } catch (final Error | RuntimeException e) {
++ throw e;
++ } catch (final Throwable e) {
++ throw new RuntimeException(e);
++ }
++ }
++
++ @Override
++ public void setValue(final ScriptObject self, final ScriptObject owner, final int value, final boolean strict) {
++ assert isConfigurable() || isWritable() : getKey() + " is not writable or configurable";
++ invokeSetter(self, value);
++ }
++
++ @Override
++ public void setValue(final ScriptObject self, final ScriptObject owner, final long value, final boolean strict) {
++ assert isConfigurable() || isWritable() : getKey() + " is not writable or configurable";
++ invokeSetter(self, value);
++ }
++
++ @Override
++ public void setValue(final ScriptObject self, final ScriptObject owner, final double value, final boolean strict) {
++ assert isConfigurable() || isWritable() : getKey() + " is not writable or configurable";
++ invokeSetter(self, value);
++ }
++
++ @Override
++ public void setValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict) {
++ //this is sometimes used for bootstrapping, hence no assert. ugly.
++ invokeSetter(self, value);
+ }
+
+ @Override
+ void initMethodHandles(final Class<?> structure) {
++ // sanity check for structure class
+ if (!ScriptObject.class.isAssignableFrom(structure) || !StructureLoader.isStructureClass(structure.getName())) {
+ throw new IllegalArgumentException();
+ }
+- if (!isSpill()) {
+- initGetterSetter(structure);
+- }
++ // this method is overridden in SpillProperty
++ assert !isSpill();
++ initGetterSetter(structure);
+ }
+
+ @Override
+ public MethodHandle getGetter(final Class<?> type) {
+ final int i = getAccessorTypeIndex(type);
+- ensureObjectGetter();
+
+- if (getters[i] == null) {
+- getters[i] = debug(
+- createGetter(currentType, type, primitiveGetter, objectGetter),
+- currentType, type, "get");
++ assert type == int.class ||
++ type == long.class ||
++ type == double.class ||
++ type == Object.class :
++ "invalid getter type " + type + " for " + getKey();
++
++ checkUndeclared();
++
++ //all this does is add a return value filter for object fields only
++ final MethodHandle[] getterCache = GETTER_CACHE;
++ final MethodHandle cachedGetter = getterCache[i];
++ final MethodHandle getter;
++ if (cachedGetter != null) {
++ getter = cachedGetter;
++ } else {
++ getter = debug(
++ createGetter(
++ getLocalType(),
++ type,
++ primitiveGetter,
++ objectGetter,
++ INVALID_PROGRAM_POINT),
++ getLocalType(),
++ type,
++ "get");
++ getterCache[i] = getter;
++ }
++ assert getter.type().returnType() == type && getter.type().parameterType(0) == Object.class;
++ return getter;
++ }
++
++ @Override
++ public MethodHandle getOptimisticGetter(final Class<?> type, final int programPoint) {
++ // nasgen generated primitive fields like Math.PI have only one known unchangeable primitive type
++ if (objectGetter == null) {
++ return getOptimisticPrimitiveGetter(type, programPoint);
+ }
+
+- return getters[i];
++ checkUndeclared();
++
++ return debug(
++ createGetter(
++ getLocalType(),
++ type,
++ primitiveGetter,
++ objectGetter,
++ programPoint),
++ getLocalType(),
++ type,
++ "get");
++ }
++
++ private MethodHandle getOptimisticPrimitiveGetter(final Class<?> type, final int programPoint) {
++ final MethodHandle g = getGetter(getLocalType());
++ return MH.asType(OptimisticReturnFilters.filterOptimisticReturnValue(g, type, programPoint), g.type().changeReturnType(type));
+ }
+
+ private Property getWiderProperty(final Class<?> type) {
+- final AccessorProperty newProperty = new AccessorProperty(this);
+- newProperty.invalidate(type);
+- return newProperty;
++ return copy(type); //invalidate cache of new property
+ }
+
+ private PropertyMap getWiderMap(final PropertyMap oldMap, final Property newProperty) {
+@@ -416,126 +601,161 @@
+ return newMap;
+ }
+
++ private void checkUndeclared() {
++ if ((getFlags() & NEEDS_DECLARATION) != 0) {
++ // a lexically defined variable that hasn't seen its declaration - throw ReferenceError
++ throw ECMAErrors.referenceError("not.defined", getKey());
++ }
++ }
++
+ // the final three arguments are for debug printout purposes only
+ @SuppressWarnings("unused")
+- private static Object replaceMap(final Object sobj, final PropertyMap newMap, final String key, final Class<?> oldType, final Class<?> newType) {
+- if (DEBUG_FIELDS) {
+- final PropertyMap oldMap = ((ScriptObject)sobj).getMap();
+- info("Type change for '" + key + "' " + oldType + "=>" + newType);
+- finest("setting map " + sobj + " from " + Debug.id(oldMap) + " to " + Debug.id(newMap) + " " + oldMap + " => " + newMap);
+- }
++ private static Object replaceMap(final Object sobj, final PropertyMap newMap) {
+ ((ScriptObject)sobj).setMap(newMap);
+ return sobj;
+ }
+
++ @SuppressWarnings("unused")
++ private static Object invalidateSwitchPoint(final AccessorProperty property, final Object obj) {
++ if (!property.builtinSwitchPoint.hasBeenInvalidated()) {
++ SwitchPoint.invalidateAll(new SwitchPoint[] { property.builtinSwitchPoint });
++ }
++ return obj;
++ }
++
+ private MethodHandle generateSetter(final Class<?> forType, final Class<?> type) {
+- ensureObjectSetter();
+- MethodHandle mh = createSetter(forType, type, primitiveSetter, objectSetter);
+- mh = debug(mh, currentType, type, "set");
+- return mh;
++ return debug(createSetter(forType, type, primitiveSetter, objectSetter), getLocalType(), type, "set");
++ }
++
++ /**
++ * Is this property of the undefined type?
++ * @return true if undefined
++ */
++ protected final boolean isUndefined() {
++ return getLocalType() == null;
+ }
+
+ @Override
+ public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
+- final int i = getAccessorTypeIndex(type);
+- final int ci = currentType == null ? -1 : getAccessorTypeIndex(currentType);
+- final Class<?> forType = currentType == null ? type : currentType;
++ checkUndeclared();
++
++ final int typeIndex = getAccessorTypeIndex(type);
++ final int currentTypeIndex = getAccessorTypeIndex(getLocalType());
+
+ //if we are asking for an object setter, but are still a primitive type, we might try to box it
+ MethodHandle mh;
+-
+- if (needsInvalidator(i, ci)) {
++ if (needsInvalidator(typeIndex, currentTypeIndex)) {
+ final Property newProperty = getWiderProperty(type);
+ final PropertyMap newMap = getWiderMap(currentMap, newProperty);
++
+ final MethodHandle widerSetter = newProperty.getSetter(type, newMap);
+- final MethodHandle explodeTypeSetter = MH.filterArguments(widerSetter, 0, MH.insertArguments(REPLACE_MAP, 1, newMap, getKey(), currentType, type));
+- if (currentType != null && currentType.isPrimitive() && type == Object.class) {
+- //might try a box check on this to avoid widening field to object storage
+- mh = createGuardBoxedPrimitiveSetter(currentType, generateSetter(currentType, currentType), explodeTypeSetter);
+- } else {
+- mh = explodeTypeSetter;
++ final Class<?> ct = getLocalType();
++ mh = MH.filterArguments(widerSetter, 0, MH.insertArguments(debugReplace(ct, type, currentMap, newMap) , 1, newMap));
++ if (ct != null && ct.isPrimitive() && !type.isPrimitive()) {
++ mh = ObjectClassGenerator.createGuardBoxedPrimitiveSetter(ct, generateSetter(ct, ct), mh);
+ }
+ } else {
+- mh = generateSetter(forType, type);
++ final Class<?> forType = isUndefined() ? type : getLocalType();
++ mh = generateSetter(!forType.isPrimitive() ? Object.class : forType, type);
+ }
+
++ if (isBuiltin()) {
++ mh = MH.filterArguments(mh, 0, debugInvalidate(MH.insertArguments(INVALIDATE_SP, 0, this), getKey()));
++ }
++
++ assert mh.type().returnType() == void.class : mh.type();
++
+ return mh;
+ }
+
+ @Override
+- public boolean canChangeType() {
++ public final boolean canChangeType() {
+ if (OBJECT_FIELDS_ONLY) {
+ return false;
+ }
+- return currentType != Object.class && (isConfigurable() || isWritable());
++ // Return true for currently undefined even if non-writable/configurable to allow initialization of ES6 CONST.
++ return getLocalType() == null || (getLocalType() != Object.class && (isConfigurable() || isWritable()));
+ }
+
+- private boolean needsInvalidator(final int ti, final int fti) {
+- return canChangeType() && ti > fti;
+- }
+-
+- private void invalidate(final Class<?> newType) {
+- getters = new MethodHandle[NOOF_TYPES];
+- setCurrentType(newType);
+- }
+-
+- private MethodHandle getSpillGetter() {
+- final int slot = getSlot();
+- MethodHandle getter = slot < SPILL_CACHE_SIZE ? SPILL_ACCESSORS[slot * 2] : null;
+- if (getter == null) {
+- getter = MH.insertArguments(SPILL_ELEMENT_GETTER, 1, slot);
+- if (slot < SPILL_CACHE_SIZE) {
+- SPILL_ACCESSORS[slot * 2 + 0] = getter;
+- }
+- }
+- return getter;
+- }
+-
+- private MethodHandle getSpillSetter() {
+- final int slot = getSlot();
+- MethodHandle setter = slot < SPILL_CACHE_SIZE ? SPILL_ACCESSORS[slot * 2 + 1] : null;
+- if (setter == null) {
+- setter = MH.insertArguments(SPILL_ELEMENT_SETTER, 1, slot);
+- if (slot < SPILL_CACHE_SIZE) {
+- SPILL_ACCESSORS[slot * 2 + 1] = setter;
+- }
+- }
+- return setter;
+- }
+-
+- private static void finest(final String str) {
+- if (DEBUG_FIELDS) {
+- LOG.finest(str);
+- }
+- }
+-
+- private static void info(final String str) {
+- if (DEBUG_FIELDS) {
+- LOG.info(str);
+- }
++ private boolean needsInvalidator(final int typeIndex, final int currentTypeIndex) {
++ return canChangeType() && typeIndex > currentTypeIndex;
+ }
+
+ private MethodHandle debug(final MethodHandle mh, final Class<?> forType, final Class<?> type, final String tag) {
+- if (DEBUG_FIELDS) {
+- return MethodHandleFactory.addDebugPrintout(
+- LOG,
+- mh,
+- tag + " '" + getKey() + "' (property="+ Debug.id(this) + ", forType=" + stripName(forType) + ", type=" + stripName(type) + ')');
++ if (!Context.DEBUG || !Global.hasInstance()) {
++ return mh;
+ }
++
++ final Context context = Context.getContextTrusted();
++ assert context != null;
++
++ return context.addLoggingToHandle(
++ ObjectClassGenerator.class,
++ Level.INFO,
++ mh,
++ 0,
++ true,
++ new Supplier<String>() {
++ @Override
++ public String get() {
++ return tag + " '" + getKey() + "' (property="+ Debug.id(this) + ", slot=" + getSlot() + " " + getClass().getSimpleName() + " forType=" + stripName(forType) + ", type=" + stripName(type) + ')';
++ }
++ });
++ }
++
++ private MethodHandle debugReplace(final Class<?> oldType, final Class<?> newType, final PropertyMap oldMap, final PropertyMap newMap) {
++ if (!Context.DEBUG || !Global.hasInstance()) {
++ return REPLACE_MAP;
++ }
++
++ final Context context = Context.getContextTrusted();
++ assert context != null;
++
++ MethodHandle mh = context.addLoggingToHandle(
++ ObjectClassGenerator.class,
++ REPLACE_MAP,
++ new Supplier<String>() {
++ @Override
++ public String get() {
++ return "Type change for '" + getKey() + "' " + oldType + "=>" + newType;
++ }
++ });
++
++ mh = context.addLoggingToHandle(
++ ObjectClassGenerator.class,
++ Level.FINEST,
++ mh,
++ Integer.MAX_VALUE,
++ false,
++ new Supplier<String>() {
++ @Override
++ public String get() {
++ return "Setting map " + Debug.id(oldMap) + " => " + Debug.id(newMap) + " " + oldMap + " => " + newMap;
++ }
++ });
+ return mh;
+ }
+
+- private void setCurrentType(final Class<?> currentType) {
+- this.currentType = currentType;
++ private static MethodHandle debugInvalidate(final MethodHandle invalidator, final String key) {
++ if (!Context.DEBUG || !Global.hasInstance()) {
++ return invalidator;
++ }
++
++ final Context context = Context.getContextTrusted();
++ assert context != null;
++
++ return context.addLoggingToHandle(
++ ObjectClassGenerator.class,
++ invalidator,
++ new Supplier<String>() {
++ @Override
++ public String get() {
++ return "Field change callback for " + key + " triggered ";
++ }
++ });
+ }
+
+- @Override
+- public Class<?> getCurrentType() {
+- return currentType;
++ private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
++ return MH.findStatic(LOOKUP, AccessorProperty.class, name, MH.type(rtype, types));
+ }
+-
+- private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+- return MH.findStatic(lookup, AccessorProperty.class, name, MH.type(rtype, types));
+- }
+-
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/AllocationStrategy.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,104 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
++
++import static jdk.nashorn.internal.lookup.Lookup.MH;
++
++import java.io.Serializable;
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import jdk.nashorn.internal.codegen.CompilerConstants;
++import jdk.nashorn.internal.codegen.ObjectClassGenerator.AllocatorDescriptor;
++
++/**
++ * Encapsulates the allocation strategy for a function when used as a constructor. Basically the same as
++ * {@link AllocatorDescriptor}, but with an additionally cached resolved method handle. There is also a
++ * canonical default allocation strategy for functions that don't assign any "this" properties (vast majority
++ * of all functions), therefore saving some storage space in {@link RecompilableScriptFunctionData} that would
++ * otherwise be lost to identical tuples of (map, className, handle) fields.
++ */
++final class AllocationStrategy implements Serializable {
++ private static final long serialVersionUID = 1L;
++
++ private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
++
++ private static final AllocationStrategy DEFAULT_STRATEGY = new AllocationStrategy(new AllocatorDescriptor(0));
++
++ /** Allocator map from allocator descriptor */
++ private final PropertyMap allocatorMap;
++
++ /** Name of class where allocator function resides */
++ private final String allocatorClassName;
++
++ /** lazily generated allocator */
++ private transient MethodHandle allocator;
++
++ private AllocationStrategy(final AllocatorDescriptor desc) {
++ this.allocatorMap = desc.getAllocatorMap();
++ // These classes get loaded, so an interned variant of their name is most likely around anyway.
++ this.allocatorClassName = desc.getAllocatorClassName().intern();
++ }
++
++ private boolean matches(final AllocatorDescriptor desc) {
++ return desc.getAllocatorMap().size() == allocatorMap.size() &&
++ desc.getAllocatorClassName().equals(allocatorClassName);
++ }
++
++ static AllocationStrategy get(final AllocatorDescriptor desc) {
++ return DEFAULT_STRATEGY.matches(desc) ? DEFAULT_STRATEGY : new AllocationStrategy(desc);
++ }
++
++ PropertyMap getAllocatorMap() {
++ return allocatorMap;
++ }
++
++ ScriptObject allocate(final PropertyMap map) {
++ try {
++ if (allocator == null) {
++ allocator = MH.findStatic(LOOKUP, Context.forStructureClass(allocatorClassName),
++ CompilerConstants.ALLOCATE.symbolName(), MH.type(ScriptObject.class, PropertyMap.class));
++ }
++ return (ScriptObject)allocator.invokeExact(map);
++ } catch (final RuntimeException | Error e) {
++ throw e;
++ } catch (final Throwable t) {
++ throw new RuntimeException(t);
++ }
++ }
++
++ private Object readResolve() {
++ if(allocatorMap.size() == DEFAULT_STRATEGY.allocatorMap.size() &&
++ allocatorClassName.equals(DEFAULT_STRATEGY.allocatorClassName)) {
++ return DEFAULT_STRATEGY;
++ }
++ return this;
++ }
++
++ @Override
++ public String toString() {
++ return "AllocationStrategy[allocatorClassName=" + allocatorClassName + ", allocatorMap.size=" +
++ allocatorMap.size() + "]";
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/AstDeserializer.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
++
++import java.io.ByteArrayInputStream;
++import java.io.IOException;
++import java.io.ObjectInputStream;
++import java.util.zip.InflaterInputStream;
++import jdk.nashorn.internal.ir.FunctionNode;
++
++/**
++ * This static utility class performs deserialization of FunctionNode ASTs from a byte array.
++ * The format is a standard Java serialization stream, deflated.
++ */
++final class AstDeserializer {
++ static FunctionNode deserialize(final byte[] serializedAst) {
++ try {
++ return (FunctionNode)new ObjectInputStream(new InflaterInputStream(new ByteArrayInputStream(
++ serializedAst))).readObject();
++ } catch (final ClassNotFoundException | IOException e) {
++ // This is internal, can't happen
++ throw new AssertionError("Unexpected exception deserializing function", e);
++ }
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package jdk.nashorn.internal.runtime;
+
++import java.util.Collection;
+ import java.util.Map;
+ import jdk.nashorn.internal.codegen.ClassEmitter;
+
+@@ -48,12 +49,20 @@
+ public T getOwner();
+
+ /**
+- * Install a class
++ * Install a class.
+ * @param className name of the class with / separation
+ * @param bytecode bytecode
+ * @return the installed class
+ */
+- public Class<?> install(final String className, final byte[] bytecode, final Source source, final Object[] constants);
++ public Class<?> install(final String className, final byte[] bytecode);
++
++ /**
++ * Initialize already installed classes.
++ * @param classes the class to initialize
++ * @param source the source object for the classes
++ * @param constants the runtime constants for the classes
++ */
++ public void initialize(final Collection<Class<?>> classes, final Source source, final Object[] constants);
+
+ /**
+ * Verify generated bytecode before emission. This is called back from the
+@@ -71,17 +80,41 @@
+ public long getUniqueScriptId();
+
+ /**
+- * Get next unique eval id
+- * @return unique eval id
+- */
+- public long getUniqueEvalId();
+-
+- /**
+ * Store a compiled script for later reuse
++ *
++ * @param cacheKey key to use in cache
+ * @param source the script source
+ * @param mainClassName the main class name
+ * @param classBytes map of class names to class bytes
++ * @param initializers compilation id -> FunctionInitializer map
+ * @param constants constants array
++ * @param compilationId compilation id
+ */
+- public void storeCompiledScript(Source source, String mainClassName, Map<String, byte[]> classBytes, Object[] constants);
++ public void storeScript(final String cacheKey, final Source source, final String mainClassName, final Map<String, byte[]> classBytes,
++ final Map<Integer, FunctionInitializer> initializers, final Object[] constants, final int compilationId);
++
++ /**
++ * Load a previously compiled script
++ * @param source the script source
++ * @param functionKey the function id and signature
++ * @return compiled script data
++ */
++ public StoredScript loadScript(Source source, String functionKey);
++
++ /**
++ * Returns a new code installer that shares most of the functionality of this code installer, but uses a
++ * new, independent class loader.
++ * @return a new code installer with a new independent class loader.
++ */
++ public CodeInstaller<T> withNewLoader();
++
++ /**
++ * Returns true if this code installer is compatible with the other code installer. Compatibility is expected to be
++ * an equivalence relation, and installers are supposed to be compatible with those they create using
++ * {@link #withNewLoader()}.
++ * @param other the other code installer tested for compatibility with this code installer.
++ * @return true if this code installer is compatible with the other code installer.
++ */
++ public boolean isCompatibleWith(CodeInstaller<T> other);
++
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/CodeStore.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/CodeStore.java Wed Feb 04 12:14:47 2015 -0800
+@@ -34,145 +34,309 @@
+ import java.io.ObjectInputStream;
+ import java.io.ObjectOutputStream;
+ import java.io.Serializable;
++import java.security.AccessControlException;
+ import java.security.AccessController;
+ import java.security.PrivilegedActionException;
+ import java.security.PrivilegedExceptionAction;
+-import java.util.Base64;
++import java.util.Iterator;
+ import java.util.Map;
++import java.util.ServiceLoader;
++import jdk.nashorn.internal.codegen.OptimisticTypesPersistence;
++import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
++import jdk.nashorn.internal.runtime.options.Options;
+
+ /**
+ * A code cache for persistent caching of compiled scripts.
+ */
+-final class CodeStore {
++@Logger(name="codestore")
++public abstract class CodeStore implements Loggable {
+
+- private final File dir;
+- private final int minSize;
++ /**
++ * Permission needed to provide a CodeStore instance via ServiceLoader.
++ */
++ public final static String NASHORN_PROVIDE_CODE_STORE = "nashorn.provideCodeStore";
+
+- // Message digest to file name encoder
+- private final static Base64.Encoder BASE64 = Base64.getUrlEncoder().withoutPadding();
+-
+- // Default minimum size for storing a compiled script class
+- private final static int DEFAULT_MIN_SIZE = 1000;
++ private DebugLogger log;
+
+ /**
+ * Constructor
+- * @param path directory to store code in
+- * @throws IOException
+ */
+- public CodeStore(final String path) throws IOException {
+- this(path, DEFAULT_MIN_SIZE);
++ protected CodeStore() {
++ }
++
++ @Override
++ public DebugLogger initLogger(final Context context) {
++ log = context.getLogger(getClass());
++ return log;
++ }
++
++ @Override
++ public DebugLogger getLogger() {
++ return log;
+ }
+
+ /**
+- * Constructor
+- * @param path directory to store code in
+- * @param minSize minimum file size for caching scripts
+- * @throws IOException
++ * Returns a new code store instance.
++ *
++ * @param context the current context
++ * @return The instance, or null if code store could not be created
+ */
+- public CodeStore(final String path, final int minSize) throws IOException {
+- this.dir = checkDirectory(path);
+- this.minSize = minSize;
++ public static CodeStore newCodeStore(final Context context) {
++ final Class<CodeStore> baseClass = CodeStore.class;
++ try {
++ // security check first
++ final SecurityManager sm = System.getSecurityManager();
++ if (sm != null) {
++ sm.checkPermission(new RuntimePermission(NASHORN_PROVIDE_CODE_STORE));
++ }
++ final ServiceLoader<CodeStore> services = ServiceLoader.load(baseClass);
++ final Iterator<CodeStore> iterator = services.iterator();
++ if (iterator.hasNext()) {
++ final CodeStore store = iterator.next();
++ store.initLogger(context).info("using code store provider ", store.getClass().getCanonicalName());
++ return store;
++ }
++ } catch (final AccessControlException e) {
++ context.getLogger(CodeStore.class).warning("failed to load code store provider ", e);
++ }
++ try {
++ final CodeStore store = new DirectoryCodeStore(context);
++ store.initLogger(context);
++ return store;
++ } catch (final IOException e) {
++ context.getLogger(CodeStore.class).warning("failed to create cache directory ", e);
++ return null;
++ }
+ }
+
+- private static File checkDirectory(final String path) throws IOException {
+- try {
+- return AccessController.doPrivileged(new PrivilegedExceptionAction<File>() {
+- @Override
+- public File run() throws IOException {
+- final File dir = new File(path).getAbsoluteFile();
+- if (!dir.exists() && !dir.mkdirs()) {
+- throw new IOException("Could not create directory: " + dir);
+- } else if (!dir.isDirectory()) {
+- throw new IOException("Not a directory: " + dir);
+- } else if (!dir.canRead() || !dir.canWrite()) {
+- throw new IOException("Directory not readable or writable: " + dir);
+- }
+- return dir;
+- }
+- });
+- } catch (PrivilegedActionException e) {
+- throw (IOException) e.getException();
+- }
++
++ /**
++ * Store a compiled script in the cache.
++ *
++ * @param functionKey the function key
++ * @param source the source
++ * @param mainClassName the main class name
++ * @param classBytes a map of class bytes
++ * @param initializers the function initializers
++ * @param constants the constants array
++ * @param compilationId the compilation id
++ *
++ * @return stored script
++ */
++ public StoredScript store(final String functionKey,
++ final Source source,
++ final String mainClassName,
++ final Map<String, byte[]> classBytes,
++ final Map<Integer, FunctionInitializer> initializers,
++ final Object[] constants,
++ final int compilationId) {
++ return store(functionKey, source, storedScriptFor(source, mainClassName, classBytes, initializers, constants, compilationId));
+ }
+
+ /**
++ * Stores a compiled script.
++ *
++ * @param functionKey the function key
++ * @param source the source
++ * @param script The compiled script
++ * @return The compiled script or {@code null} if not stored
++ */
++ public abstract StoredScript store(final String functionKey,
++ final Source source,
++ final StoredScript script);
++
++ /**
+ * Return a compiled script from the cache, or null if it isn't found.
+ *
+- * @param source the source
+- * @return the compiled script or null
+- * @throws IOException
+- * @throws ClassNotFoundException
++ * @param source the source
++ * @param functionKey the function key
++ * @return the stored script or null
+ */
+- public CompiledScript getScript(final Source source) throws IOException, ClassNotFoundException {
+- if (source.getLength() < minSize) {
+- return null;
+- }
+-
+- final String digest = BASE64.encodeToString(source.getDigest());
+- final File file = new File(dir, digest);
+-
+- try {
+- return AccessController.doPrivileged(new PrivilegedExceptionAction<CompiledScript>() {
+- @Override
+- public CompiledScript run() throws IOException, ClassNotFoundException {
+- if (!file.exists()) {
+- return null;
+- }
+- try (ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)))) {
+- CompiledScript compiledScript = (CompiledScript) in.readObject();
+- compiledScript.setSource(source);
+- return compiledScript;
+- }
+- }
+- });
+- } catch (PrivilegedActionException e) {
+- final Exception ex = e.getException();
+- if (ex instanceof IOException) {
+- throw (IOException) ex;
+- } else if (ex instanceof ClassNotFoundException) {
+- throw (ClassNotFoundException) ex;
+- }
+- throw (new RuntimeException(ex));
+- }
+- }
++ public abstract StoredScript load(final Source source, final String functionKey);
+
+ /**
+- * Store a compiled script in the cache.
++ * Returns a new StoredScript instance.
+ *
+ * @param source the source
+ * @param mainClassName the main class name
+ * @param classBytes a map of class bytes
++ * @param initializers function initializers
+ * @param constants the constants array
+- * @throws IOException
++ * @param compilationId the compilation id
++ *
++ * @return The compiled script
+ */
+- public void putScript(final Source source, final String mainClassName, final Map<String, byte[]> classBytes, final Object[] constants)
+- throws IOException {
+- if (source.getLength() < minSize) {
+- return;
+- }
++ public StoredScript storedScriptFor(final Source source, final String mainClassName,
++ final Map<String, byte[]> classBytes,
++ final Map<Integer, FunctionInitializer> initializers,
++ final Object[] constants, final int compilationId) {
+ for (final Object constant : constants) {
+ // Make sure all constant data is serializable
+- if (! (constant instanceof Serializable)) {
+- return;
++ if (!(constant instanceof Serializable)) {
++ getLogger().warning("cannot store ", source, " non serializable constant ", constant);
++ return null;
++ }
++ }
++ return new StoredScript(compilationId, mainClassName, classBytes, initializers, constants);
++ }
++
++ /**
++ * Generate a string representing the function with {@code functionId} and {@code paramTypes}.
++ * @param functionId function id
++ * @param paramTypes parameter types
++ * @return a string representing the function
++ */
++ public static String getCacheKey(final int functionId, final Type[] paramTypes) {
++ final StringBuilder b = new StringBuilder().append(functionId);
++ if(paramTypes != null && paramTypes.length > 0) {
++ b.append('-');
++ for(final Type t: paramTypes) {
++ b.append(Type.getShortSignatureDescriptor(t));
++ }
++ }
++ return b.toString();
++ }
++
++ /**
++ * A store using a file system directory.
++ */
++ public static class DirectoryCodeStore extends CodeStore {
++
++ // Default minimum size for storing a compiled script class
++ private final static int DEFAULT_MIN_SIZE = 1000;
++
++ private final File dir;
++ private final boolean readOnly;
++ private final int minSize;
++
++ /**
++ * Constructor
++ *
++ * @param context the current context
++ * @throws IOException if there are read/write problems with the cache and cache directory
++ */
++ public DirectoryCodeStore(final Context context) throws IOException {
++ this(context, Options.getStringProperty("nashorn.persistent.code.cache", "nashorn_code_cache"), false, DEFAULT_MIN_SIZE);
++ }
++
++ /**
++ * Constructor
++ *
++ * @param context the current context
++ * @param path directory to store code in
++ * @param readOnly is this a read only code store
++ * @param minSize minimum file size for caching scripts
++ * @throws IOException if there are read/write problems with the cache and cache directory
++ */
++ public DirectoryCodeStore(final Context context, final String path, final boolean readOnly, final int minSize) throws IOException {
++ this.dir = checkDirectory(path, context.getEnv(), readOnly);
++ this.readOnly = readOnly;
++ this.minSize = minSize;
++ }
++
++ private static File checkDirectory(final String path, final ScriptEnvironment env, final boolean readOnly) throws IOException {
++ try {
++ return AccessController.doPrivileged(new PrivilegedExceptionAction<File>() {
++ @Override
++ public File run() throws IOException {
++ final File dir = new File(path, getVersionDir(env)).getAbsoluteFile();
++ if (readOnly) {
++ if (!dir.exists() || !dir.isDirectory()) {
++ throw new IOException("Not a directory: " + dir.getPath());
++ } else if (!dir.canRead()) {
++ throw new IOException("Directory not readable: " + dir.getPath());
++ }
++ } else if (!dir.exists() && !dir.mkdirs()) {
++ throw new IOException("Could not create directory: " + dir.getPath());
++ } else if (!dir.isDirectory()) {
++ throw new IOException("Not a directory: " + dir.getPath());
++ } else if (!dir.canRead() || !dir.canWrite()) {
++ throw new IOException("Directory not readable or writable: " + dir.getPath());
++ }
++ return dir;
++ }
++ });
++ } catch (final PrivilegedActionException e) {
++ throw (IOException) e.getException();
+ }
+ }
+
+- final String digest = BASE64.encodeToString(source.getDigest());
+- final File file = new File(dir, digest);
+- final CompiledScript script = new CompiledScript(source, mainClassName, classBytes, constants);
++ private static String getVersionDir(final ScriptEnvironment env) throws IOException {
++ try {
++ final String versionDir = OptimisticTypesPersistence.getVersionDirName();
++ return env._optimistic_types ? versionDir + "_opt" : versionDir;
++ } catch (final Exception e) {
++ throw new IOException(e);
++ }
++ }
+
+- try {
+- AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+- @Override
+- public Void run() throws IOException {
+- try (ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) {
+- out.writeObject(script);
++ @Override
++ public StoredScript load(final Source source, final String functionKey) {
++ if (source.getLength() < minSize) {
++ return null;
++ }
++
++ final File file = getCacheFile(source, functionKey);
++
++ try {
++ return AccessController.doPrivileged(new PrivilegedExceptionAction<StoredScript>() {
++ @Override
++ public StoredScript run() throws IOException, ClassNotFoundException {
++ if (!file.exists()) {
++ return null;
++ }
++ try (ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)))) {
++ final StoredScript storedScript = (StoredScript) in.readObject();
++ getLogger().info("loaded ", source, "-", functionKey);
++ return storedScript;
++ }
+ }
+- return null;
+- }
+- });
+- } catch (PrivilegedActionException e) {
+- throw (IOException) e.getException();
++ });
++ } catch (final PrivilegedActionException e) {
++ getLogger().warning("failed to load ", source, "-", functionKey, ": ", e.getException());
++ return null;
++ }
++ }
++
++ @Override
++ public StoredScript store(final String functionKey, final Source source, final StoredScript script) {
++ if (readOnly || script == null || belowThreshold(source)) {
++ return null;
++ }
++
++ final File file = getCacheFile(source, functionKey);
++
++ try {
++ return AccessController.doPrivileged(new PrivilegedExceptionAction<StoredScript>() {
++ @Override
++ public StoredScript run() throws IOException {
++ try (ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) {
++ out.writeObject(script);
++ }
++ getLogger().info("stored ", source, "-", functionKey);
++ return script;
++ }
++ });
++ } catch (final PrivilegedActionException e) {
++ getLogger().warning("failed to store ", script, "-", functionKey, ": ", e.getException());
++ return null;
++ }
++ }
++
++
++ private File getCacheFile(final Source source, final String functionKey) {
++ return new File(dir, source.getDigest() + '-' + functionKey);
++ }
++
++ private boolean belowThreshold(final Source source) {
++ if (source.getLength() < minSize) {
++ getLogger().info("below size threshold ", source);
++ return true;
++ }
++ return false;
+ }
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java Wed Feb 04 12:14:47 2015 -0800
+@@ -24,51 +24,290 @@
+ */
+ package jdk.nashorn.internal.runtime;
+
++import static jdk.nashorn.internal.lookup.Lookup.MH;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
++import java.lang.invoke.CallSite;
+ import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
+ import java.lang.invoke.MethodType;
+-
++import java.lang.invoke.MutableCallSite;
++import java.lang.invoke.SwitchPoint;
++import java.util.ArrayList;
++import java.util.Collection;
++import java.util.Collections;
++import java.util.Iterator;
++import java.util.List;
++import java.util.Map;
++import java.util.TreeMap;
++import java.util.function.Supplier;
++import java.util.logging.Level;
++import jdk.internal.dynalink.linker.GuardedInvocation;
++import jdk.nashorn.internal.codegen.Compiler;
++import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
++import jdk.nashorn.internal.codegen.TypeMap;
++import jdk.nashorn.internal.codegen.types.ArrayType;
+ import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.ir.FunctionNode;
++import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
++import jdk.nashorn.internal.runtime.events.RecompilationEvent;
++import jdk.nashorn.internal.runtime.linker.Bootstrap;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
+
+ /**
+ * An version of a JavaScript function, native or JavaScript.
+ * Supports lazily generating a constructor version of the invocation.
+ */
+-final class CompiledFunction implements Comparable<CompiledFunction> {
++final class CompiledFunction {
+
+- /** The method type may be more specific than the invoker, if. e.g.
+- * the invoker is guarded, and a guard with a generic object only
+- * fallback, while the target is more specific, we still need the
+- * more specific type for sorting */
+- private final MethodType type;
+- private final MethodHandle invoker;
++ private static final MethodHandle NEWFILTER = findOwnMH("newFilter", Object.class, Object.class, Object.class);
++ private static final MethodHandle RELINK_COMPOSABLE_INVOKER = findOwnMH("relinkComposableInvoker", void.class, CallSite.class, CompiledFunction.class, boolean.class);
++ private static final MethodHandle HANDLE_REWRITE_EXCEPTION = findOwnMH("handleRewriteException", MethodHandle.class, CompiledFunction.class, OptimismInfo.class, RewriteException.class);
++ private static final MethodHandle RESTOF_INVOKER = MethodHandles.exactInvoker(MethodType.methodType(Object.class, RewriteException.class));
++
++ private final DebugLogger log;
++
++ static final Collection<CompiledFunction> NO_FUNCTIONS = Collections.emptySet();
++
++ /**
++ * The method type may be more specific than the invoker, if. e.g.
++ * the invoker is guarded, and a guard with a generic object only
++ * fallback, while the target is more specific, we still need the
++ * more specific type for sorting
++ */
++ private MethodHandle invoker;
+ private MethodHandle constructor;
++ private OptimismInfo optimismInfo;
++ private final int flags; // from FunctionNode
++ private final MethodType callSiteType;
+
+- CompiledFunction(final MethodType type, final MethodHandle invoker) {
+- this(type, invoker, null);
++ private final Specialization specialization;
++
++ CompiledFunction(final MethodHandle invoker) {
++ this(invoker, null, null);
+ }
+
+- CompiledFunction(final MethodType type, final MethodHandle invoker, final MethodHandle constructor) {
+- assert type != null;
+- this.type = type;
+- this.invoker = invoker;
++ static CompiledFunction createBuiltInConstructor(final MethodHandle invoker, final Specialization specialization) {
++ return new CompiledFunction(MH.insertArguments(invoker, 0, false), createConstructorFromInvoker(MH.insertArguments(invoker, 0, true)), specialization);
++ }
++
++ CompiledFunction(final MethodHandle invoker, final MethodHandle constructor, final Specialization specialization) {
++ this(invoker, constructor, 0, null, specialization, DebugLogger.DISABLED_LOGGER);
++ }
++
++ CompiledFunction(final MethodHandle invoker, final MethodHandle constructor, final int flags, final MethodType callSiteType, final Specialization specialization, final DebugLogger log) {
++ this.specialization = specialization;
++ if (specialization != null && specialization.isOptimistic()) {
++ /*
++ * An optimistic builtin with isOptimistic=true works like any optimistic generated function, i.e. it
++ * can throw unwarranted optimism exceptions. As native functions trivially can't have parts of them
++ * regenerated as restof methods, this only works if the methods are atomic/functional in their behavior
++ * and doesn't modify state before an UOE can be thrown. If they aren't, we can reexecute a wider version
++ * of the same builtin in a recompilation handler for FinalScriptFunctionData. There are several
++ * candidate methods in Native* that would benefit from this, but I haven't had time to implement any
++ * of them currently. In order to fit in with the relinking framework, the current thinking is
++ * that the methods still take a program point to fit in with other optimistic functions, but
++ * it is set to "first", which is the beginning of the method. The relinker can tell the difference
++ * between builtin and JavaScript functions. This might change. TODO
++ */
++ this.invoker = MH.insertArguments(invoker, invoker.type().parameterCount() - 1, UnwarrantedOptimismException.FIRST_PROGRAM_POINT);
++ throw new AssertionError("Optimistic (UnwarrantedOptimismException throwing) builtin functions are currently not in use");
++ }
++ this.invoker = invoker;
+ this.constructor = constructor;
++ this.flags = flags;
++ this.callSiteType = callSiteType;
++ this.log = log;
++ }
++
++ CompiledFunction(final MethodHandle invoker, final RecompilableScriptFunctionData functionData,
++ final Map<Integer, Type> invalidatedProgramPoints, final MethodType callSiteType, final int flags) {
++ this(invoker, null, flags, callSiteType, null, functionData.getLogger());
++ if ((flags & FunctionNode.IS_DEOPTIMIZABLE) != 0) {
++ optimismInfo = new OptimismInfo(functionData, invalidatedProgramPoints);
++ } else {
++ optimismInfo = null;
++ }
++ }
++
++ static CompiledFunction createBuiltInConstructor(final MethodHandle invoker) {
++ return new CompiledFunction(MH.insertArguments(invoker, 0, false), createConstructorFromInvoker(MH.insertArguments(invoker, 0, true)), null);
++ }
++
++ boolean isSpecialization() {
++ return specialization != null;
++ }
++
++ boolean hasLinkLogic() {
++ return getLinkLogicClass() != null;
++ }
++
++ Class<? extends LinkLogic> getLinkLogicClass() {
++ if (isSpecialization()) {
++ final Class<? extends LinkLogic> linkLogicClass = specialization.getLinkLogicClass();
++ assert !LinkLogic.isEmpty(linkLogicClass) : "empty link logic classes should have been removed by nasgen";
++ return linkLogicClass;
++ }
++ return null;
++ }
++
++ int getFlags() {
++ return flags;
++ }
++
++ /**
++ * An optimistic specialization is one that can throw UnwarrantedOptimismException.
++ * This is allowed for native methods, as long as they are functional, i.e. don't change
++ * any state between entering and throwing the UOE. Then we can re-execute a wider version
++ * of the method in the continuation. Rest-of method generation for optimistic builtins is
++ * of course not possible, but this approach works and fits into the same relinking
++ * framework
++ *
++ * @return true if optimistic builtin
++ */
++ boolean isOptimistic() {
++ return isSpecialization() ? specialization.isOptimistic() : false;
++ }
++
++ boolean isApplyToCall() {
++ return (flags & FunctionNode.HAS_APPLY_TO_CALL_SPECIALIZATION) != 0;
++ }
++
++ boolean isVarArg() {
++ return isVarArgsType(invoker.type());
+ }
+
+ @Override
+ public String toString() {
+- return "<callSiteType= " + type + " invoker=" + invoker + " ctor=" + constructor + ">";
++ final StringBuilder sb = new StringBuilder();
++ final Class<? extends LinkLogic> linkLogicClass = getLinkLogicClass();
++
++ sb.append("[invokerType=").
++ append(invoker.type()).
++ append(" ctor=").
++ append(constructor).
++ append(" weight=").
++ append(weight()).
++ append(" linkLogic=").
++ append(linkLogicClass != null ? linkLogicClass.getSimpleName() : "none");
++
++ return sb.toString();
+ }
+
+- MethodHandle getInvoker() {
+- return invoker;
++ boolean needsCallee() {
++ return ScriptFunctionData.needsCallee(invoker);
+ }
+
+- MethodHandle getConstructor() {
++ /**
++ * Returns an invoker method handle for this function. Note that the handle is safely composable in
++ * the sense that you can compose it with other handles using any combinators even if you can't affect call site
++ * invalidation. If this compiled function is non-optimistic, then it returns the same value as
++ * {@link #getInvokerOrConstructor(boolean)}. However, if the function is optimistic, then this handle will
++ * incur an overhead as it will add an intermediate internal call site that can relink itself when the function
++ * needs to regenerate its code to always point at the latest generated code version.
++ * @return a guaranteed composable invoker method handle for this function.
++ */
++ MethodHandle createComposableInvoker() {
++ return createComposableInvoker(false);
++ }
++
++ /**
++ * Returns an invoker method handle for this function when invoked as a constructor. Note that the handle should be
++ * considered non-composable in the sense that you can only compose it with other handles using any combinators if
++ * you can ensure that the composition is guarded by {@link #getOptimisticAssumptionsSwitchPoint()} if it's
++ * non-null, and that you can relink the call site it is set into as a target if the switch point is invalidated. In
++ * all other cases, use {@link #createComposableConstructor()}.
++ * @return a direct constructor method handle for this function.
++ */
++ private MethodHandle getConstructor() {
++ if (constructor == null) {
++ constructor = createConstructorFromInvoker(createInvokerForPessimisticCaller());
++ }
++
+ return constructor;
+ }
+
+- void setConstructor(final MethodHandle constructor) {
+- this.constructor = constructor;
++ /**
++ * Creates a version of the invoker intended for a pessimistic caller (return type is Object, no caller optimistic
++ * program point available).
++ * @return a version of the invoker intended for a pessimistic caller.
++ */
++ private MethodHandle createInvokerForPessimisticCaller() {
++ return createInvoker(Object.class, INVALID_PROGRAM_POINT);
++ }
++
++ /**
++ * Compose a constructor from an invoker.
++ *
++ * @param invoker invoker
++ * @return the composed constructor
++ */
++ private static MethodHandle createConstructorFromInvoker(final MethodHandle invoker) {
++ final boolean needsCallee = ScriptFunctionData.needsCallee(invoker);
++ // If it was (callee, this, args...), permute it to (this, callee, args...). We're doing this because having
++ // "this" in the first argument position is what allows the elegant folded composition of
++ // (newFilter x constructor x allocator) further down below in the code. Also, ensure the composite constructor
++ // always returns Object.
++ final MethodHandle swapped = needsCallee ? swapCalleeAndThis(invoker) : invoker;
++
++ final MethodHandle returnsObject = MH.asType(swapped, swapped.type().changeReturnType(Object.class));
++
++ final MethodType ctorType = returnsObject.type();
++
++ // Construct a dropping type list for NEWFILTER, but don't include constructor "this" into it, so it's actually
++ // captured as "allocation" parameter of NEWFILTER after we fold the constructor into it.
++ // (this, [callee, ]args...) => ([callee, ]args...)
++ final Class<?>[] ctorArgs = ctorType.dropParameterTypes(0, 1).parameterArray();
++
++ // Fold constructor into newFilter that replaces the return value from the constructor with the originally
++ // allocated value when the originally allocated value is a JS primitive (String, Boolean, Number).
++ // (result, this, [callee, ]args...) x (this, [callee, ]args...) => (this, [callee, ]args...)
++ final MethodHandle filtered = MH.foldArguments(MH.dropArguments(NEWFILTER, 2, ctorArgs), returnsObject);
++
++ // allocate() takes a ScriptFunction and returns a newly allocated ScriptObject...
++ if (needsCallee) {
++ // ...we either fold it into the previous composition, if we need both the ScriptFunction callee object and
++ // the newly allocated object in the arguments, so (this, callee, args...) x (callee) => (callee, args...),
++ // or...
++ return MH.foldArguments(filtered, ScriptFunction.ALLOCATE);
++ }
++
++ // ...replace the ScriptFunction argument with the newly allocated object, if it doesn't need the callee
++ // (this, args...) filter (callee) => (callee, args...)
++ return MH.filterArguments(filtered, 0, ScriptFunction.ALLOCATE);
++ }
++
++ /**
++ * Permutes the parameters in the method handle from {@code (callee, this, ...)} to {@code (this, callee, ...)}.
++ * Used when creating a constructor handle.
++ * @param mh a method handle with order of arguments {@code (callee, this, ...)}
++ * @return a method handle with order of arguments {@code (this, callee, ...)}
++ */
++ private static MethodHandle swapCalleeAndThis(final MethodHandle mh) {
++ final MethodType type = mh.type();
++ assert type.parameterType(0) == ScriptFunction.class : type;
++ assert type.parameterType(1) == Object.class : type;
++ final MethodType newType = type.changeParameterType(0, Object.class).changeParameterType(1, ScriptFunction.class);
++ final int[] reorder = new int[type.parameterCount()];
++ reorder[0] = 1;
++ assert reorder[1] == 0;
++ for (int i = 2; i < reorder.length; ++i) {
++ reorder[i] = i;
++ }
++ return MethodHandles.permuteArguments(mh, newType, reorder);
++ }
++
++ /**
++ * Returns an invoker method handle for this function when invoked as a constructor. Note that the handle is safely
++ * composable in the sense that you can compose it with other handles using any combinators even if you can't affect
++ * call site invalidation. If this compiled function is non-optimistic, then it returns the same value as
++ * {@link #getConstructor()}. However, if the function is optimistic, then this handle will incur an overhead as it
++ * will add an intermediate internal call site that can relink itself when the function needs to regenerate its code
++ * to always point at the latest generated code version.
++ * @return a guaranteed composable constructor method handle for this function.
++ */
++ MethodHandle createComposableConstructor() {
++ return createComposableInvoker(true);
+ }
+
+ boolean hasConstructor() {
+@@ -76,45 +315,10 @@
+ }
+
+ MethodType type() {
+- return type;
++ return invoker.type();
+ }
+
+- @Override
+- public int compareTo(final CompiledFunction o) {
+- return compareMethodTypes(type(), o.type());
+- }
+-
+- private static int compareMethodTypes(final MethodType ownType, final MethodType otherType) {
+- // Comparable interface demands that compareTo() should only return 0 if objects are equal.
+- // Failing to meet this requirement causes same weight functions to replace each other in TreeSet,
+- // so we go some lengths to come up with an ordering between same weight functions,
+- // first falling back to parameter count and then to hash code.
+- if (ownType.equals(otherType)) {
+- return 0;
+- }
+-
+- final int diff = weight(ownType) - weight(otherType);
+- if (diff != 0) {
+- return diff;
+- }
+- if (ownType.parameterCount() != otherType.parameterCount()) {
+- return ownType.parameterCount() - otherType.parameterCount();
+- }
+- // We're just interested in not returning 0 here, not correct ordering
+- return ownType.hashCode() - otherType.hashCode();
+- }
+-
+- @Override
+- public boolean equals(Object obj) {
+- return obj instanceof CompiledFunction && type().equals(((CompiledFunction)obj).type());
+- }
+-
+- @Override
+- public int hashCode() {
+- return type().hashCode();
+- }
+-
+- private int weight() {
++ int weight() {
+ return weight(type());
+ }
+
+@@ -124,76 +328,645 @@
+ }
+
+ int weight = Type.typeFor(type.returnType()).getWeight();
+- for (final Class<?> paramType : type.parameterArray()) {
++ for (int i = 0 ; i < type.parameterCount() ; i++) {
++ final Class<?> paramType = type.parameterType(i);
+ final int pweight = Type.typeFor(paramType).getWeight() * 2; //params are more important than call types as return values are always specialized
+ weight += pweight;
+ }
++
++ weight += type.parameterCount(); //more params outweigh few parameters
++
+ return weight;
+ }
+
+- private static boolean isVarArgsType(final MethodType type) {
++ static boolean isVarArgsType(final MethodType type) {
+ assert type.parameterCount() >= 1 : type;
+ return type.parameterType(type.parameterCount() - 1) == Object[].class;
+ }
+
+- boolean moreGenericThan(final CompiledFunction o) {
+- return weight() > o.weight();
++ static boolean moreGenericThan(final MethodType mt0, final MethodType mt1) {
++ return weight(mt0) > weight(mt1);
+ }
+
+- boolean moreGenericThan(final MethodType mt) {
+- return weight() > weight(mt);
++ boolean betterThanFinal(final CompiledFunction other, final MethodType callSiteMethodType) {
++ // Prefer anything over nothing, as we can't compile new versions.
++ if (other == null) {
++ return true;
++ }
++ return betterThanFinal(this, other, callSiteMethodType);
+ }
+
+- /**
+- * Check whether a given method descriptor is compatible with this invocation.
+- * It is compatible if the types are narrower than the invocation type so that
+- * a semantically equivalent linkage can be performed.
+- *
+- * @param mt type to check against
+- * @return true if types are compatible
+- */
+- boolean typeCompatible(final MethodType mt) {
+- final int wantedParamCount = mt.parameterCount();
+- final int existingParamCount = type.parameterCount();
++ private static boolean betterThanFinal(final CompiledFunction cf, final CompiledFunction other, final MethodType callSiteMethodType) {
++ final MethodType thisMethodType = cf.type();
++ final MethodType otherMethodType = other.type();
++ final int thisParamCount = getParamCount(thisMethodType);
++ final int otherParamCount = getParamCount(otherMethodType);
++ final int callSiteRawParamCount = getParamCount(callSiteMethodType);
++ final boolean csVarArg = callSiteRawParamCount == Integer.MAX_VALUE;
++ // Subtract 1 for callee for non-vararg call sites
++ final int callSiteParamCount = csVarArg ? callSiteRawParamCount : callSiteRawParamCount - 1;
+
+- //if we are not examining a varargs type, the number of parameters must be the same
+- if (wantedParamCount != existingParamCount && !isVarArgsType(mt)) {
++ // Prefer the function that discards less parameters
++ final int thisDiscardsParams = Math.max(callSiteParamCount - thisParamCount, 0);
++ final int otherDiscardsParams = Math.max(callSiteParamCount - otherParamCount, 0);
++ if(thisDiscardsParams < otherDiscardsParams) {
++ return true;
++ }
++ if(thisDiscardsParams > otherDiscardsParams) {
+ return false;
+ }
+
+- //we only go as far as the shortest array. the only chance to make this work if
+- //parameters lengths do not match is if our type ends with a varargs argument.
+- //then every trailing parameter in the given callsite can be folded into it, making
+- //us compatible (albeit slower than a direct specialization)
+- final int lastParamIndex = Math.min(wantedParamCount, existingParamCount);
+- for (int i = 0; i < lastParamIndex; i++) {
+- final Type w = Type.typeFor(mt.parameterType(i));
+- final Type e = Type.typeFor(type.parameterType(i));
++ final boolean thisVarArg = thisParamCount == Integer.MAX_VALUE;
++ final boolean otherVarArg = otherParamCount == Integer.MAX_VALUE;
++ if(!(thisVarArg && otherVarArg && csVarArg)) {
++ // At least one of them isn't vararg
++ final Type[] thisType = toTypeWithoutCallee(thisMethodType, 0); // Never has callee
++ final Type[] otherType = toTypeWithoutCallee(otherMethodType, 0); // Never has callee
++ final Type[] callSiteType = toTypeWithoutCallee(callSiteMethodType, 1); // Always has callee
+
+- //don't specialize on booleans, we have the "true" vs int 1 ambiguity in resolution
+- //we also currently don't support boolean as a javascript function callsite type.
+- //it will always box.
+- if (w.isBoolean()) {
++ int narrowWeightDelta = 0;
++ int widenWeightDelta = 0;
++ final int minParamsCount = Math.min(Math.min(thisParamCount, otherParamCount), callSiteParamCount);
++ for(int i = 0; i < minParamsCount; ++i) {
++ final int callSiteParamWeight = getParamType(i, callSiteType, csVarArg).getWeight();
++ // Delta is negative for narrowing, positive for widening
++ final int thisParamWeightDelta = getParamType(i, thisType, thisVarArg).getWeight() - callSiteParamWeight;
++ final int otherParamWeightDelta = getParamType(i, otherType, otherVarArg).getWeight() - callSiteParamWeight;
++ // Only count absolute values of narrowings
++ narrowWeightDelta += Math.max(-thisParamWeightDelta, 0) - Math.max(-otherParamWeightDelta, 0);
++ // Only count absolute values of widenings
++ widenWeightDelta += Math.max(thisParamWeightDelta, 0) - Math.max(otherParamWeightDelta, 0);
++ }
++
++ // If both functions accept more arguments than what is passed at the call site, account for ability
++ // to receive Undefined un-narrowed in the remaining arguments.
++ if(!thisVarArg) {
++ for(int i = callSiteParamCount; i < thisParamCount; ++i) {
++ narrowWeightDelta += Math.max(Type.OBJECT.getWeight() - thisType[i].getWeight(), 0);
++ }
++ }
++ if(!otherVarArg) {
++ for(int i = callSiteParamCount; i < otherParamCount; ++i) {
++ narrowWeightDelta -= Math.max(Type.OBJECT.getWeight() - otherType[i].getWeight(), 0);
++ }
++ }
++
++ // Prefer function that narrows less
++ if(narrowWeightDelta < 0) {
++ return true;
++ }
++ if(narrowWeightDelta > 0) {
+ return false;
+ }
+
+- //This callsite type has a vararg here. it will swallow all remaining args.
+- //for consistency, check that it's the last argument
+- if (e.isArray()) {
++ // Prefer function that widens less
++ if(widenWeightDelta < 0) {
+ return true;
+ }
+-
+- //Our arguments must be at least as wide as the wanted one, if not wider
+- if (Type.widest(w, e) != e) {
+- //e.g. this invocation takes double and callsite says "object". reject. won't fit
+- //but if invocation takes a double and callsite says "int" or "long" or "double", that's fine
++ if(widenWeightDelta > 0) {
+ return false;
+ }
+ }
+
+- return true; // anything goes for return type, take the convenient one and it will be upcasted thru dynalink magic.
++ // Prefer the function that exactly matches the arity of the call site.
++ if(thisParamCount == callSiteParamCount && otherParamCount != callSiteParamCount) {
++ return true;
++ }
++ if(thisParamCount != callSiteParamCount && otherParamCount == callSiteParamCount) {
++ return false;
++ }
++
++ // Otherwise, neither function matches arity exactly. We also know that at this point, they both can receive
++ // more arguments than call site, otherwise we would've already chosen the one that discards less parameters.
++ // Note that variable arity methods are preferred, as they actually match the call site arity better, since they
++ // really have arbitrary arity.
++ if(thisVarArg) {
++ if(!otherVarArg) {
++ return true; //
++ }
++ } else if(otherVarArg) {
++ return false;
++ }
++
++ // Neither is variable arity; chose the one that has less extra parameters.
++ final int fnParamDelta = thisParamCount - otherParamCount;
++ if(fnParamDelta < 0) {
++ return true;
++ }
++ if(fnParamDelta > 0) {
++ return false;
++ }
++
++ final int callSiteRetWeight = Type.typeFor(callSiteMethodType.returnType()).getWeight();
++ // Delta is negative for narrower return type, positive for wider return type
++ final int thisRetWeightDelta = Type.typeFor(thisMethodType.returnType()).getWeight() - callSiteRetWeight;
++ final int otherRetWeightDelta = Type.typeFor(otherMethodType.returnType()).getWeight() - callSiteRetWeight;
++
++ // Prefer function that returns a less wide return type
++ final int widenRetDelta = Math.max(thisRetWeightDelta, 0) - Math.max(otherRetWeightDelta, 0);
++ if(widenRetDelta < 0) {
++ return true;
++ }
++ if(widenRetDelta > 0) {
++ return false;
++ }
++
++ // Prefer function that returns a less narrow return type
++ final int narrowRetDelta = Math.max(-thisRetWeightDelta, 0) - Math.max(-otherRetWeightDelta, 0);
++ if(narrowRetDelta < 0) {
++ return true;
++ }
++ if(narrowRetDelta > 0) {
++ return false;
++ }
++
++ //if they are equal, pick the specialized one first
++ if (cf.isSpecialization() != other.isSpecialization()) {
++ return cf.isSpecialization(); //always pick the specialized version if we can
++ }
++
++ if (cf.isSpecialization() && other.isSpecialization()) {
++ return cf.getLinkLogicClass() != null; //pick link logic specialization above generic specializations
++ }
++
++ // Signatures are identical
++ throw new AssertionError(thisMethodType + " identically applicable to " + otherMethodType + " for " + callSiteMethodType);
+ }
+
++ private static Type[] toTypeWithoutCallee(final MethodType type, final int thisIndex) {
++ final int paramCount = type.parameterCount();
++ final Type[] t = new Type[paramCount - thisIndex];
++ for(int i = thisIndex; i < paramCount; ++i) {
++ t[i - thisIndex] = Type.typeFor(type.parameterType(i));
++ }
++ return t;
++ }
+
++ private static Type getParamType(final int i, final Type[] paramTypes, final boolean isVarArg) {
++ final int fixParamCount = paramTypes.length - (isVarArg ? 1 : 0);
++ if(i < fixParamCount) {
++ return paramTypes[i];
++ }
++ assert isVarArg;
++ return ((ArrayType)paramTypes[paramTypes.length - 1]).getElementType();
++ }
+
++ boolean matchesCallSite(final MethodType other, final boolean pickVarArg) {
++ if (other.equals(this.callSiteType)) {
++ return true;
++ }
++ final MethodType type = type();
++ final int fnParamCount = getParamCount(type);
++ final boolean isVarArg = fnParamCount == Integer.MAX_VALUE;
++ if (isVarArg) {
++ return pickVarArg;
++ }
++
++ final int csParamCount = getParamCount(other);
++ final boolean csIsVarArg = csParamCount == Integer.MAX_VALUE;
++ final int thisThisIndex = needsCallee() ? 1 : 0; // Index of "this" parameter in this function's type
++
++ final int fnParamCountNoCallee = fnParamCount - thisThisIndex;
++ final int minParams = Math.min(csParamCount - 1, fnParamCountNoCallee); // callSiteType always has callee, so subtract 1
++ // We must match all incoming parameters, except "this". Starting from 1 to skip "this".
++ for(int i = 1; i < minParams; ++i) {
++ final Type fnType = Type.typeFor(type.parameterType(i + thisThisIndex));
++ final Type csType = csIsVarArg ? Type.OBJECT : Type.typeFor(other.parameterType(i + 1));
++ if(!fnType.isEquivalentTo(csType)) {
++ return false;
++ }
++ }
++
++ // Must match any undefined parameters to Object type.
++ for(int i = minParams; i < fnParamCountNoCallee; ++i) {
++ if(!Type.typeFor(type.parameterType(i + thisThisIndex)).isEquivalentTo(Type.OBJECT)) {
++ return false;
++ }
++ }
++
++ return true;
++ }
++
++ private static int getParamCount(final MethodType type) {
++ final int paramCount = type.parameterCount();
++ return type.parameterType(paramCount - 1).isArray() ? Integer.MAX_VALUE : paramCount;
++ }
++
++ private boolean canBeDeoptimized() {
++ return optimismInfo != null;
++ }
++
++ private MethodHandle createComposableInvoker(final boolean isConstructor) {
++ final MethodHandle handle = getInvokerOrConstructor(isConstructor);
++
++ // If compiled function is not optimistic, it can't ever change its invoker/constructor, so just return them
++ // directly.
++ if(!canBeDeoptimized()) {
++ return handle;
++ }
++
++ // Otherwise, we need a new level of indirection; need to introduce a mutable call site that can relink itslef
++ // to the compiled function's changed target whenever the optimistic assumptions are invalidated.
++ final CallSite cs = new MutableCallSite(handle.type());
++ relinkComposableInvoker(cs, this, isConstructor);
++ return cs.dynamicInvoker();
++ }
++
++ private static class HandleAndAssumptions {
++ final MethodHandle handle;
++ final SwitchPoint assumptions;
++
++ HandleAndAssumptions(final MethodHandle handle, final SwitchPoint assumptions) {
++ this.handle = handle;
++ this.assumptions = assumptions;
++ }
++
++ GuardedInvocation createInvocation() {
++ return new GuardedInvocation(handle, assumptions);
++ }
++ }
++
++ /**
++ * Returns a pair of an invocation created with a passed-in supplier and a non-invalidated switch point for
++ * optimistic assumptions (or null for the switch point if the function can not be deoptimized). While the method
++ * makes a best effort to return a non-invalidated switch point (compensating for possible deoptimizing
++ * recompilation happening on another thread) it is still possible that by the time this method returns the
++ * switchpoint has been invalidated by a {@code RewriteException} triggered on another thread for this function.
++ * This is not a problem, though, as these switch points are always used to produce call sites that fall back to
++ * relinking when they are invalidated, and in this case the execution will end up here again. What this method
++ * basically does is minimize such busy-loop relinking while the function is being recompiled on a different thread.
++ * @param invocationSupplier the supplier that constructs the actual invocation method handle; should use the
++ * {@code CompiledFunction} method itself in some capacity.
++ * @return a tuple object containing the method handle as created by the supplier and an optimistic assumptions
++ * switch point that is guaranteed to not have been invalidated before the call to this method (or null if the
++ * function can't be further deoptimized).
++ */
++ private synchronized HandleAndAssumptions getValidOptimisticInvocation(final Supplier<MethodHandle> invocationSupplier) {
++ for(;;) {
++ final MethodHandle handle = invocationSupplier.get();
++ final SwitchPoint assumptions = canBeDeoptimized() ? optimismInfo.optimisticAssumptions : null;
++ if(assumptions != null && assumptions.hasBeenInvalidated()) {
++ // We can be in a situation where one thread is in the middle of a deoptimizing compilation when we hit
++ // this and thus, it has invalidated the old switch point, but hasn't created the new one yet. Note that
++ // the behavior of invalidating the old switch point before recompilation, and only creating the new one
++ // after recompilation is by design. If we didn't wait here for the recompilation to complete, we would
++ // be busy looping through the fallback path of the invalidated switch point, relinking the call site
++ // again with the same invalidated switch point, invoking the fallback, etc. stealing CPU cycles from
++ // the recompilation task we're dependent on. This can still happen if the switch point gets invalidated
++ // after we grabbed it here, in which case we'll indeed do one busy relink immediately.
++ try {
++ wait();
++ } catch (final InterruptedException e) {
++ // Intentionally ignored. There's nothing meaningful we can do if we're interrupted
++ }
++ } else {
++ return new HandleAndAssumptions(handle, assumptions);
++ }
++ }
++ }
++
++ private static void relinkComposableInvoker(final CallSite cs, final CompiledFunction inv, final boolean constructor) {
++ final HandleAndAssumptions handleAndAssumptions = inv.getValidOptimisticInvocation(new Supplier<MethodHandle>() {
++ @Override
++ public MethodHandle get() {
++ return inv.getInvokerOrConstructor(constructor);
++ }
++ });
++ final MethodHandle handle = handleAndAssumptions.handle;
++ final SwitchPoint assumptions = handleAndAssumptions.assumptions;
++ final MethodHandle target;
++ if(assumptions == null) {
++ target = handle;
++ } else {
++ final MethodHandle relink = MethodHandles.insertArguments(RELINK_COMPOSABLE_INVOKER, 0, cs, inv, constructor);
++ target = assumptions.guardWithTest(handle, MethodHandles.foldArguments(cs.dynamicInvoker(), relink));
++ }
++ cs.setTarget(target.asType(cs.type()));
++ }
++
++ private MethodHandle getInvokerOrConstructor(final boolean selectCtor) {
++ return selectCtor ? getConstructor() : createInvokerForPessimisticCaller();
++ }
++
++ /**
++ * Returns a guarded invocation for this function when not invoked as a constructor. The guarded invocation has no
++ * guard but it potentially has an optimistic assumptions switch point. As such, it will probably not be used as a
++ * final guarded invocation, but rather as a holder for an invocation handle and switch point to be decomposed and
++ * reassembled into a different final invocation by the user of this method. Any recompositions should take care to
++ * continue to use the switch point. If that is not possible, use {@link #createComposableInvoker()} instead.
++ * @return a guarded invocation for an ordinary (non-constructor) invocation of this function.
++ */
++ GuardedInvocation createFunctionInvocation(final Class<?> callSiteReturnType, final int callerProgramPoint) {
++ return getValidOptimisticInvocation(new Supplier<MethodHandle>() {
++ @Override
++ public MethodHandle get() {
++ return createInvoker(callSiteReturnType, callerProgramPoint);
++ }
++ }).createInvocation();
++ }
++
++ /**
++ * Returns a guarded invocation for this function when invoked as a constructor. The guarded invocation has no guard
++ * but it potentially has an optimistic assumptions switch point. As such, it will probably not be used as a final
++ * guarded invocation, but rather as a holder for an invocation handle and switch point to be decomposed and
++ * reassembled into a different final invocation by the user of this method. Any recompositions should take care to
++ * continue to use the switch point. If that is not possible, use {@link #createComposableConstructor()} instead.
++ * @return a guarded invocation for invocation of this function as a constructor.
++ */
++ GuardedInvocation createConstructorInvocation() {
++ return getValidOptimisticInvocation(new Supplier<MethodHandle>() {
++ @Override
++ public MethodHandle get() {
++ return getConstructor();
++ }
++ }).createInvocation();
++ }
++
++ private MethodHandle createInvoker(final Class<?> callSiteReturnType, final int callerProgramPoint) {
++ final boolean isOptimistic = canBeDeoptimized();
++ MethodHandle handleRewriteException = isOptimistic ? createRewriteExceptionHandler() : null;
++
++ MethodHandle inv = invoker;
++ if(isValid(callerProgramPoint)) {
++ inv = OptimisticReturnFilters.filterOptimisticReturnValue(inv, callSiteReturnType, callerProgramPoint);
++ inv = changeReturnType(inv, callSiteReturnType);
++ if(callSiteReturnType.isPrimitive() && handleRewriteException != null) {
++ // because handleRewriteException always returns Object
++ handleRewriteException = OptimisticReturnFilters.filterOptimisticReturnValue(handleRewriteException,
++ callSiteReturnType, callerProgramPoint);
++ }
++ } else if(isOptimistic) {
++ // Required so that rewrite exception has the same return type. It'd be okay to do it even if we weren't
++ // optimistic, but it isn't necessary as the linker upstream will eventually convert the return type.
++ inv = changeReturnType(inv, callSiteReturnType);
++ }
++
++ if(isOptimistic) {
++ assert handleRewriteException != null;
++ final MethodHandle typedHandleRewriteException = changeReturnType(handleRewriteException, inv.type().returnType());
++ return MH.catchException(inv, RewriteException.class, typedHandleRewriteException);
++ }
++ return inv;
++ }
++
++ private MethodHandle createRewriteExceptionHandler() {
++ return MH.foldArguments(RESTOF_INVOKER, MH.insertArguments(HANDLE_REWRITE_EXCEPTION, 0, this, optimismInfo));
++ }
++
++ private static MethodHandle changeReturnType(final MethodHandle mh, final Class<?> newReturnType) {
++ return Bootstrap.getLinkerServices().asType(mh, mh.type().changeReturnType(newReturnType));
++ }
++
++ @SuppressWarnings("unused")
++ private static MethodHandle handleRewriteException(final CompiledFunction function, final OptimismInfo oldOptimismInfo, final RewriteException re) {
++ return function.handleRewriteException(oldOptimismInfo, re);
++ }
++
++ /**
++ * Debug function for printing out all invalidated program points and their
++ * invalidation mapping to next type
++ * @param ipp
++ * @return string describing the ipp map
++ */
++ private static List<String> toStringInvalidations(final Map<Integer, Type> ipp) {
++ if (ipp == null) {
++ return Collections.emptyList();
++ }
++
++ final List<String> list = new ArrayList<>();
++
++ for (final Iterator<Map.Entry<Integer, Type>> iter = ipp.entrySet().iterator(); iter.hasNext(); ) {
++ final Map.Entry<Integer, Type> entry = iter.next();
++ final char bct = entry.getValue().getBytecodeStackType();
++ final String type;
++
++ switch (entry.getValue().getBytecodeStackType()) {
++ case 'A':
++ type = "object";
++ break;
++ case 'I':
++ type = "int";
++ break;
++ case 'J':
++ type = "long";
++ break;
++ case 'D':
++ type = "double";
++ break;
++ default:
++ type = String.valueOf(bct);
++ break;
++ }
++
++ final StringBuilder sb = new StringBuilder();
++ sb.append('[').
++ append("program point: ").
++ append(entry.getKey()).
++ append(" -> ").
++ append(type).
++ append(']');
++
++ list.add(sb.toString());
++ }
++
++ return list;
++ }
++
++ private void logRecompile(final String reason, final FunctionNode fn, final MethodType type, final Map<Integer, Type> ipp) {
++ if (log.isEnabled()) {
++ log.info(reason, DebugLogger.quote(fn.getName()), " signature: ", type);
++ log.indent();
++ for (final String str : toStringInvalidations(ipp)) {
++ log.fine(str);
++ }
++ log.unindent();
++ }
++ }
++
++ /**
++ * Handles a {@link RewriteException} raised during the execution of this function by recompiling (if needed) the
++ * function with an optimistic assumption invalidated at the program point indicated by the exception, and then
++ * executing a rest-of method to complete the execution with the deoptimized version.
++ * @param oldOptInfo the optimism info of this function. We must store it explicitly as a bound argument in the
++ * method handle, otherwise it could be null for handling a rewrite exception in an outer invocation of a recursive
++ * function when recursive invocations of the function have completely deoptimized it.
++ * @param re the rewrite exception that was raised
++ * @return the method handle for the rest-of method, for folding composition.
++ */
++ private synchronized MethodHandle handleRewriteException(final OptimismInfo oldOptInfo, final RewriteException re) {
++ if (log.isEnabled()) {
++ log.info(
++ new RecompilationEvent(
++ Level.INFO,
++ re,
++ re.getReturnValueNonDestructive()),
++ "caught RewriteException ",
++ re.getMessageShort());
++ log.indent();
++ }
++
++ final MethodType type = type();
++
++ // Compiler needs a call site type as its input, which always has a callee parameter, so we must add it if
++ // this function doesn't have a callee parameter.
++ final MethodType ct = type.parameterType(0) == ScriptFunction.class ?
++ type :
++ type.insertParameterTypes(0, ScriptFunction.class);
++ final OptimismInfo currentOptInfo = optimismInfo;
++ final boolean shouldRecompile = currentOptInfo != null && currentOptInfo.requestRecompile(re);
++
++ // Effective optimism info, for subsequent use. We'll normally try to use the current (latest) one, but if it
++ // isn't available, we'll use the old one bound into the call site.
++ final OptimismInfo effectiveOptInfo = currentOptInfo != null ? currentOptInfo : oldOptInfo;
++ FunctionNode fn = effectiveOptInfo.reparse();
++ final boolean serialized = effectiveOptInfo.isSerialized();
++ final Compiler compiler = effectiveOptInfo.getCompiler(fn, ct, re); //set to non rest-of
++
++ if (!shouldRecompile) {
++ // It didn't necessarily recompile, e.g. for an outer invocation of a recursive function if we already
++ // recompiled a deoptimized version for an inner invocation.
++ // We still need to do the rest of from the beginning
++ logRecompile("Rest-of compilation [STANDALONE] ", fn, ct, effectiveOptInfo.invalidatedProgramPoints);
++ return restOfHandle(effectiveOptInfo, compiler.compile(fn, serialized ? CompilationPhases.COMPILE_SERIALIZED_RESTOF : CompilationPhases.COMPILE_ALL_RESTOF), currentOptInfo != null);
++ }
++
++ logRecompile("Deoptimizing recompilation (up to bytecode) ", fn, ct, effectiveOptInfo.invalidatedProgramPoints);
++ fn = compiler.compile(fn, serialized ? CompilationPhases.RECOMPILE_SERIALIZED_UPTO_BYTECODE : CompilationPhases.COMPILE_UPTO_BYTECODE);
++ log.fine("Reusable IR generated");
++
++ // compile the rest of the function, and install it
++ log.info("Generating and installing bytecode from reusable IR...");
++ logRecompile("Rest-of compilation [CODE PIPELINE REUSE] ", fn, ct, effectiveOptInfo.invalidatedProgramPoints);
++ final FunctionNode normalFn = compiler.compile(fn, CompilationPhases.GENERATE_BYTECODE_AND_INSTALL);
++
++ if (effectiveOptInfo.data.usePersistentCodeCache()) {
++ final RecompilableScriptFunctionData data = effectiveOptInfo.data;
++ final int functionNodeId = data.getFunctionNodeId();
++ final TypeMap typeMap = data.typeMap(ct);
++ final Type[] paramTypes = typeMap == null ? null : typeMap.getParameterTypes(functionNodeId);
++ final String cacheKey = CodeStore.getCacheKey(functionNodeId, paramTypes);
++ compiler.persistClassInfo(cacheKey, normalFn);
++ }
++
++ final boolean canBeDeoptimized = normalFn.canBeDeoptimized();
++
++ if (log.isEnabled()) {
++ log.unindent();
++ log.info("Done.");
++
++ log.info("Recompiled '", fn.getName(), "' (", Debug.id(this), ") ", canBeDeoptimized ? "can still be deoptimized." : " is completely deoptimized.");
++ log.finest("Looking up invoker...");
++ }
++
++ final MethodHandle newInvoker = effectiveOptInfo.data.lookup(fn);
++ invoker = newInvoker.asType(type.changeReturnType(newInvoker.type().returnType()));
++ constructor = null; // Will be regenerated when needed
++
++ log.info("Done: ", invoker);
++ final MethodHandle restOf = restOfHandle(effectiveOptInfo, compiler.compile(fn, CompilationPhases.GENERATE_BYTECODE_AND_INSTALL_RESTOF), canBeDeoptimized);
++
++ // Note that we only adjust the switch point after we set the invoker/constructor. This is important.
++ if (canBeDeoptimized) {
++ effectiveOptInfo.newOptimisticAssumptions(); // Otherwise, set a new switch point.
++ } else {
++ optimismInfo = null; // If we got to a point where we no longer have optimistic assumptions, let the optimism info go.
++ }
++ notifyAll();
++
++ return restOf;
++ }
++
++ private MethodHandle restOfHandle(final OptimismInfo info, final FunctionNode restOfFunction, final boolean canBeDeoptimized) {
++ assert info != null;
++ assert restOfFunction.getCompileUnit().getUnitClassName().contains("restOf");
++ final MethodHandle restOf =
++ changeReturnType(
++ info.data.lookupCodeMethod(
++ restOfFunction.getCompileUnit().getCode(),
++ MH.type(restOfFunction.getReturnType().getTypeClass(),
++ RewriteException.class)),
++ Object.class);
++
++ if (!canBeDeoptimized) {
++ return restOf;
++ }
++
++ // If rest-of is itself optimistic, we must make sure that we can repeat a deoptimization if it, too hits an exception.
++ return MH.catchException(restOf, RewriteException.class, createRewriteExceptionHandler());
++
++ }
++
++ private static class OptimismInfo {
++ // TODO: this is pointing to its owning ScriptFunctionData. Re-evaluate if that's okay.
++ private final RecompilableScriptFunctionData data;
++ private final Map<Integer, Type> invalidatedProgramPoints;
++ private SwitchPoint optimisticAssumptions;
++ private final DebugLogger log;
++
++ OptimismInfo(final RecompilableScriptFunctionData data, final Map<Integer, Type> invalidatedProgramPoints) {
++ this.data = data;
++ this.log = data.getLogger();
++ this.invalidatedProgramPoints = invalidatedProgramPoints == null ? new TreeMap<Integer, Type>() : invalidatedProgramPoints;
++ newOptimisticAssumptions();
++ }
++
++ private void newOptimisticAssumptions() {
++ optimisticAssumptions = new SwitchPoint();
++ }
++
++ boolean requestRecompile(final RewriteException e) {
++ final Type retType = e.getReturnType();
++ final Type previousFailedType = invalidatedProgramPoints.put(e.getProgramPoint(), retType);
++
++ if (previousFailedType != null && !previousFailedType.narrowerThan(retType)) {
++ final StackTraceElement[] stack = e.getStackTrace();
++ final String functionId = stack.length == 0 ?
++ data.getName() :
++ stack[0].getClassName() + "." + stack[0].getMethodName();
++
++ log.info("RewriteException for an already invalidated program point ", e.getProgramPoint(), " in ", functionId, ". This is okay for a recursive function invocation, but a bug otherwise.");
++
++ return false;
++ }
++
++ SwitchPoint.invalidateAll(new SwitchPoint[] { optimisticAssumptions });
++
++ return true;
++ }
++
++ Compiler getCompiler(final FunctionNode fn, final MethodType actualCallSiteType, final RewriteException e) {
++ return data.getCompiler(fn, actualCallSiteType, e.getRuntimeScope(), invalidatedProgramPoints, getEntryPoints(e));
++ }
++
++ private static int[] getEntryPoints(final RewriteException e) {
++ final int[] prevEntryPoints = e.getPreviousContinuationEntryPoints();
++ final int[] entryPoints;
++ if (prevEntryPoints == null) {
++ entryPoints = new int[1];
++ } else {
++ final int l = prevEntryPoints.length;
++ entryPoints = new int[l + 1];
++ System.arraycopy(prevEntryPoints, 0, entryPoints, 1, l);
++ }
++ entryPoints[0] = e.getProgramPoint();
++ return entryPoints;
++ }
++
++ FunctionNode reparse() {
++ return data.reparse();
++ }
++
++ boolean isSerialized() {
++ return data.isSerialized();
++ }
++ }
++
++ @SuppressWarnings("unused")
++ private static Object newFilter(final Object result, final Object allocation) {
++ return (result instanceof ScriptObject || !JSType.isPrimitive(result))? result : allocation;
++ }
++
++ private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
++ return MH.findStatic(MethodHandles.lookup(), CompiledFunction.class, name, MH.type(rtype, types));
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/CompiledFunctions.java Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,114 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
+-
+-import java.lang.invoke.MethodHandle;
+-import java.lang.invoke.MethodType;
+-import java.util.Iterator;
+-import java.util.TreeSet;
+-
+-/**
+- * This is a list of code versions of a function.
+- * The list is sorted in ascending order of generic descriptors
+- */
+-@SuppressWarnings("serial")
+-final class CompiledFunctions extends TreeSet<CompiledFunction> {
+-
+- private CompiledFunction generic;
+-
+- CompiledFunction best(final MethodType type) {
+- final Iterator<CompiledFunction> iter = iterator();
+- while (iter.hasNext()) {
+- final CompiledFunction next = iter.next();
+- if (next.typeCompatible(type)) {
+- return next;
+- }
+- }
+- return generic();
+- }
+-
+- boolean needsCallee() {
+- return ScriptFunctionData.needsCallee(mostGeneric().getInvoker());
+- }
+-
+- CompiledFunction mostGeneric() {
+- return last();
+- }
+-
+- CompiledFunction generic() {
+- CompiledFunction gen = this.generic;
+- if (gen == null) {
+- gen = this.generic = makeGeneric(mostGeneric());
+- }
+- return gen;
+- }
+-
+- private static CompiledFunction makeGeneric(final CompiledFunction func) {
+- final MethodHandle invoker = composeGenericMethod(func.getInvoker());
+- final MethodHandle constructor = func.hasConstructor() ? composeGenericMethod(func.getConstructor()) : null;
+- return new CompiledFunction(invoker.type(), invoker, constructor);
+- }
+-
+- /**
+- * Takes a method handle, and returns a potentially different method handle that can be used in
+- * {@code ScriptFunction#invoke(Object, Object...)} or {code ScriptFunction#construct(Object, Object...)}.
+- * The returned method handle will be sure to return {@code Object}, and will have all its parameters turned into
+- * {@code Object} as well, except for the following ones:
+- * <ul>
+- * <li>a last parameter of type {@code Object[]} which is used for vararg functions,</li>
+- * <li>the first argument, which is forced to be {@link ScriptFunction}, in case the function receives itself
+- * (callee) as an argument.</li>
+- * </ul>
+- *
+- * @param mh the original method handle
+- *
+- * @return the new handle, conforming to the rules above.
+- */
+- private static MethodHandle composeGenericMethod(final MethodHandle mh) {
+- final MethodType type = mh.type();
+- final boolean isVarArg = ScriptFunctionData.isVarArg(mh);
+- final int paramCount = isVarArg ? type.parameterCount() - 1 : type.parameterCount();
+-
+- MethodType newType = MethodType.genericMethodType(paramCount, isVarArg);
+-
+- if (ScriptFunctionData.needsCallee(mh)) {
+- newType = newType.changeParameterType(0, ScriptFunction.class);
+- }
+- return type.equals(newType) ? mh : mh.asType(newType);
+- }
+-
+- /**
+- * Is the given type even more specific than this entire list? That means
+- * we have an opportunity for more specific versions of the method
+- * through lazy code generation
+- *
+- * @param type type to check against
+- * @return true if the given type is more specific than all invocations available
+- */
+- boolean isLessSpecificThan(final MethodType type) {
+- return best(type).moreGenericThan(type);
+- }
+-
+-}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/CompiledScript.java Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,127 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
+-
+-import java.io.Serializable;
+-import java.util.Arrays;
+-import java.util.Map;
+-
+-/**
+- * Class representing a compiled script.
+- */
+-final class CompiledScript implements Serializable {
+-
+- /** Main class name. */
+- private final String mainClassName;
+-
+- /** Map of class names to class bytes. */
+- private final Map<String, byte[]> classBytes;
+-
+- /** Constants array. */
+- private final Object[] constants;
+-
+- /** The source */
+- private transient Source source;
+-
+- private static final long serialVersionUID = 2958227232195298340L;
+-
+- /**
+- * Constructor.
+- *
+- * @param mainClassName main class name
+- * @param classBytes map of class names to class bytes
+- * @param constants constants array
+- */
+- CompiledScript(final Source source, final String mainClassName, final Map<String, byte[]> classBytes, final Object[] constants) {
+- this.source = source;
+- this.mainClassName = mainClassName;
+- this.classBytes = classBytes;
+- this.constants = constants;
+- }
+-
+- /**
+- * Returns the main class name.
+- * @return the main class name
+- */
+- public String getMainClassName() {
+- return mainClassName;
+- }
+-
+- /**
+- * Returns a map of class names to class bytes.
+- * @return map of class bytes
+- */
+- public Map<String, byte[]> getClassBytes() {
+- return classBytes;
+- }
+-
+- /**
+- * Returns the constants array.
+- * @return constants array
+- */
+- public Object[] getConstants() {
+- return constants;
+- }
+-
+- /**
+- * Returns the source of this cached script.
+- * @return the source
+- */
+- public Source getSource() {
+- return source;
+- }
+-
+- /**
+- * Sets the source of this cached script.
+- * @param source the source
+- */
+- void setSource(final Source source) {
+- this.source = source;
+- }
+-
+- @Override
+- public int hashCode() {
+- int hash = mainClassName.hashCode();
+- hash = 31 * hash + classBytes.hashCode();
+- hash = 31 * hash + Arrays.hashCode(constants);
+- return hash;
+- }
+-
+- @Override
+- public boolean equals(Object obj) {
+- if (obj == this) {
+- return true;
+- }
+- if (!(obj instanceof CompiledScript)) {
+- return false;
+- }
+-
+- final CompiledScript cs = (CompiledScript) obj;
+- return mainClassName.equals(cs.mainClassName)
+- && classBytes.equals(cs.classBytes)
+- && Arrays.equals(constants, cs.constants);
+- }
+-}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/ConsString.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/ConsString.java Wed Feb 04 12:14:47 2015 -0800
+@@ -36,8 +36,12 @@
+ public final class ConsString implements CharSequence {
+
+ private CharSequence left, right;
+- final private int length;
+- private boolean flat = false;
++ private final int length;
++ private volatile int state = STATE_NEW;
++
++ private final static int STATE_NEW = 0;
++ private final static int STATE_THRESHOLD = 2;
++ private final static int STATE_FLATTENED = -1;
+
+ /**
+ * Constructor
+@@ -53,11 +57,14 @@
+ this.left = left;
+ this.right = right;
+ length = left.length() + right.length();
++ if (length < 0) {
++ throw new IllegalArgumentException("too big concatenated String");
++ }
+ }
+
+ @Override
+ public String toString() {
+- return (String) flattened();
++ return (String) flattened(true);
+ }
+
+ @Override
+@@ -67,22 +74,31 @@
+
+ @Override
+ public char charAt(final int index) {
+- return flattened().charAt(index);
++ return flattened(true).charAt(index);
+ }
+
+ @Override
+ public CharSequence subSequence(final int start, final int end) {
+- return flattened().subSequence(start, end);
++ return flattened(true).subSequence(start, end);
+ }
+
+- private CharSequence flattened() {
+- if (!flat) {
+- flatten();
++ /**
++ * Returns the components of this ConsString as a {@code CharSequence} array with two elements.
++ * The elements will be either {@code Strings} or other {@code ConsStrings}.
++ * @return CharSequence array of length 2
++ */
++ public synchronized CharSequence[] getComponents() {
++ return new CharSequence[] { left, right };
++ }
++
++ private CharSequence flattened(final boolean flattenNested) {
++ if (state != STATE_FLATTENED) {
++ flatten(flattenNested);
+ }
+ return left;
+ }
+
+- private void flatten() {
++ private synchronized void flatten(final boolean flattenNested) {
+ // We use iterative traversal as recursion may exceed the stack size limit.
+ final char[] chars = new char[length];
+ int pos = length;
+@@ -97,8 +113,14 @@
+ do {
+ if (cs instanceof ConsString) {
+ final ConsString cons = (ConsString) cs;
+- stack.addFirst(cons.left);
+- cs = cons.right;
++ // Count the times a cons-string is traversed as part of other cons-strings being flattened.
++ // If it crosses a threshold we flatten the nested cons-string internally.
++ if (cons.state == STATE_FLATTENED || (flattenNested && ++cons.state >= STATE_THRESHOLD)) {
++ cs = cons.flattened(false);
++ } else {
++ stack.addFirst(cons.left);
++ cs = cons.right;
++ }
+ } else {
+ final String str = (String) cs;
+ pos -= str.length();
+@@ -109,7 +131,7 @@
+
+ left = new String(chars);
+ right = "";
+- flat = true;
++ state = STATE_FLATTENED;
+ }
+
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/Context.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/Context.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,10 +26,10 @@
+ package jdk.nashorn.internal.runtime;
+
+ import static jdk.nashorn.internal.codegen.CompilerConstants.CONSTANTS;
+-import static jdk.nashorn.internal.codegen.CompilerConstants.RUN_SCRIPT;
++import static jdk.nashorn.internal.codegen.CompilerConstants.CREATE_PROGRAM_FUNCTION;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.STRICT_MODE;
+-import static jdk.nashorn.internal.lookup.Lookup.MH;
++import static jdk.nashorn.internal.runtime.CodeStore.newCodeStore;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+ import static jdk.nashorn.internal.runtime.Source.sourceFor;
+@@ -39,11 +39,12 @@
+ import java.io.PrintWriter;
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
++import java.lang.invoke.MethodType;
++import java.lang.invoke.SwitchPoint;
+ import java.lang.ref.ReferenceQueue;
+ import java.lang.ref.SoftReference;
+ import java.lang.reflect.Field;
+ import java.lang.reflect.Modifier;
+-import java.util.concurrent.atomic.AtomicLong;
+ import java.net.MalformedURLException;
+ import java.net.URL;
+ import java.security.AccessControlContext;
+@@ -55,20 +56,34 @@
+ import java.security.PrivilegedActionException;
+ import java.security.PrivilegedExceptionAction;
+ import java.security.ProtectionDomain;
++import java.util.Collection;
+ import java.util.HashMap;
+ import java.util.LinkedHashMap;
+ import java.util.Map;
+-
++import java.util.concurrent.atomic.AtomicLong;
++import java.util.concurrent.atomic.AtomicReference;
++import java.util.function.Consumer;
++import java.util.function.Supplier;
++import java.util.logging.Level;
++import javax.script.ScriptEngine;
+ import jdk.internal.org.objectweb.asm.ClassReader;
+ import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
++import jdk.nashorn.api.scripting.ClassFilter;
+ import jdk.nashorn.api.scripting.ScriptObjectMirror;
+ import jdk.nashorn.internal.codegen.Compiler;
++import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
+ import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+ import jdk.nashorn.internal.ir.FunctionNode;
+ import jdk.nashorn.internal.ir.debug.ASTWriter;
+ import jdk.nashorn.internal.ir.debug.PrintVisitor;
++import jdk.nashorn.internal.lookup.MethodHandleFactory;
+ import jdk.nashorn.internal.objects.Global;
+ import jdk.nashorn.internal.parser.Parser;
++import jdk.nashorn.internal.runtime.events.RuntimeEvent;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
++import jdk.nashorn.internal.runtime.options.LoggingOption.LoggerInfo;
+ import jdk.nashorn.internal.runtime.options.Options;
+
+ /**
+@@ -111,6 +126,19 @@
+ private static final String LOAD_FX = "fx:";
+ private static final String LOAD_NASHORN = "nashorn:";
+
++ private static MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
++ private static MethodType CREATE_PROGRAM_FUNCTION_TYPE = MethodType.methodType(ScriptFunction.class, ScriptObject.class);
++
++ /**
++ * Keeps track of which builtin prototypes and properties have been relinked
++ * Currently we are conservative and associate the name of a builtin class with all
++ * its properties, so it's enough to invalidate a property to break all assumptions
++ * about a prototype. This can be changed to a more fine grained approach, but no one
++ * ever needs this, given the very rare occurance of swapping out only parts of
++ * a builtin v.s. the entire builtin object
++ */
++ private final Map<String, SwitchPoint> builtinSwitchPoints = new HashMap<>();
++
+ /* Force DebuggerSupport to be loaded. */
+ static {
+ DebuggerSupport.FORCELOAD = true;
+@@ -124,6 +152,13 @@
+ private final Context context;
+ private final ScriptLoader loader;
+ private final CodeSource codeSource;
++ private int usageCount = 0;
++ private int bytesDefined = 0;
++
++ // We reuse this installer for 10 compilations or 200000 defined bytes. Usually the first condition
++ // will occur much earlier, the second is a safety measure for very large scripts/functions.
++ private final static int MAX_USAGES = 10;
++ private final static int MAX_BYTES_DEFINED = 200_000;
+
+ private ContextCodeInstaller(final Context context, final ScriptLoader loader, final CodeSource codeSource) {
+ this.context = context;
+@@ -132,7 +167,7 @@
+ }
+
+ /**
+- * Return the context for this installer
++ * Return the script environment for this installer
+ * @return ScriptEnvironment
+ */
+ @Override
+@@ -141,32 +176,35 @@
+ }
+
+ @Override
+- public Class<?> install(final String className, final byte[] bytecode, final Source source, final Object[] constants) {
+- Compiler.LOG.fine("Installing class ", className);
++ public Class<?> install(final String className, final byte[] bytecode) {
++ usageCount++;
++ bytesDefined += bytecode.length;
++ final String binaryName = Compiler.binaryName(className);
++ return loader.installClass(binaryName, bytecode, codeSource);
++ }
+
+- final String binaryName = Compiler.binaryName(className);
+- final Class<?> clazz = loader.installClass(binaryName, bytecode, codeSource);
+-
++ @Override
++ public void initialize(final Collection<Class<?>> classes, final Source source, final Object[] constants) {
+ try {
+- // Need doPrivileged because these fields are private
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+- //use reflection to write source and constants table to installed classes
+- final Field sourceField = clazz.getDeclaredField(SOURCE.symbolName());
+- final Field constantsField = clazz.getDeclaredField(CONSTANTS.symbolName());
+- sourceField.setAccessible(true);
+- constantsField.setAccessible(true);
+- sourceField.set(null, source);
+- constantsField.set(null, constants);
++ for (final Class<?> clazz : classes) {
++ //use reflection to write source and constants table to installed classes
++ final Field sourceField = clazz.getDeclaredField(SOURCE.symbolName());
++ sourceField.setAccessible(true);
++ sourceField.set(null, source);
++
++ final Field constantsField = clazz.getDeclaredField(CONSTANTS.symbolName());
++ constantsField.setAccessible(true);
++ constantsField.set(null, constants);
++ }
+ return null;
+ }
+ });
+ } catch (final PrivilegedActionException e) {
+ throw new RuntimeException(e);
+ }
+-
+- return clazz;
+ }
+
+ @Override
+@@ -180,20 +218,38 @@
+ }
+
+ @Override
+- public long getUniqueEvalId() {
+- return context.getUniqueEvalId();
++ public void storeScript(final String cacheKey, final Source source, final String mainClassName,
++ final Map<String,byte[]> classBytes, final Map<Integer, FunctionInitializer> initializers,
++ final Object[] constants, final int compilationId) {
++ if (context.codeStore != null) {
++ context.codeStore.store(cacheKey, source, mainClassName, classBytes, initializers, constants, compilationId);
++ }
+ }
+
+ @Override
+- public void storeCompiledScript(final Source source, final String mainClassName,
+- final Map<String, byte[]> classBytes, final Object[] constants) {
++ public StoredScript loadScript(final Source source, final String functionKey) {
+ if (context.codeStore != null) {
+- try {
+- context.codeStore.putScript(source, mainClassName, classBytes, constants);
+- } catch (final IOException e) {
+- throw new RuntimeException(e);
+- }
++ return context.codeStore.load(source, functionKey);
+ }
++ return null;
++ }
++
++ @Override
++ public CodeInstaller<ScriptEnvironment> withNewLoader() {
++ // Reuse this installer if we're within our limits.
++ if (usageCount < MAX_USAGES && bytesDefined < MAX_BYTES_DEFINED) {
++ return this;
++ }
++ return new ContextCodeInstaller(context, context.createNewLoader(), codeSource);
++ }
++
++ @Override
++ public boolean isCompatibleWith(final CodeInstaller<ScriptEnvironment> other) {
++ if (other instanceof ContextCodeInstaller) {
++ final ContextCodeInstaller cci = (ContextCodeInstaller)other;
++ return cci.context == context && cci.codeSource == codeSource;
++ }
++ return false;
+ }
+ }
+
+@@ -208,6 +264,10 @@
+ // persistent code store
+ private CodeStore codeStore;
+
++ // A factory for linking global properties as constant method handles. It is created when the first Global
++ // is created, and invalidated forever once the second global is created.
++ private final AtomicReference<GlobalConstants> globalConstantsRef = new AtomicReference<>();
++
+ /**
+ * Get the current global scope
+ * @return the current global scope
+@@ -236,6 +296,14 @@
+ public static void setGlobal(final Global global) {
+ // This class in a package.access protected package.
+ // Trusted code only can call this method.
++ assert getGlobal() != global;
++ //same code can be cached between globals, then we need to invalidate method handle constants
++ if (global != null) {
++ final GlobalConstants globalConstants = getContext(global).getGlobalConstants();
++ if (globalConstants != null) {
++ globalConstants.invalidateAll();
++ }
++ }
+ currentGlobal.set(global);
+ }
+
+@@ -276,7 +344,6 @@
+ * @param str text to write
+ * @param crlf write a carriage return/new line after text
+ */
+- @SuppressWarnings("resource")
+ public static void err(final String str, final boolean crlf) {
+ final PrintWriter err = Context.getCurrentErr();
+ if (err != null) {
+@@ -309,8 +376,8 @@
+ /** Unique id for script. Used only when --loader-per-compile=false */
+ private final AtomicLong uniqueScriptId;
+
+- /** Unique id for 'eval' */
+- private final AtomicLong uniqueEvalId;
++ /** Optional class filter to use for Java classes. Can be null. */
++ private final ClassFilter classFilter;
+
+ private static final ClassLoader myLoader = Context.class.getClassLoader();
+ private static final StructureLoader sharedLoader;
+@@ -366,7 +433,19 @@
+ * @param appLoader application class loader
+ */
+ public Context(final Options options, final ErrorManager errors, final ClassLoader appLoader) {
+- this(options, errors, new PrintWriter(System.out, true), new PrintWriter(System.err, true), appLoader);
++ this(options, errors, appLoader, (ClassFilter)null);
++ }
++
++ /**
++ * Constructor
++ *
++ * @param options options from command line or Context creator
++ * @param errors error manger
++ * @param appLoader application class loader
++ * @param classFilter class filter to use
++ */
++ public Context(final Options options, final ErrorManager errors, final ClassLoader appLoader, final ClassFilter classFilter) {
++ this(options, errors, new PrintWriter(System.out, true), new PrintWriter(System.err, true), appLoader, classFilter);
+ }
+
+ /**
+@@ -379,11 +458,26 @@
+ * @param appLoader application class loader
+ */
+ public Context(final Options options, final ErrorManager errors, final PrintWriter out, final PrintWriter err, final ClassLoader appLoader) {
++ this(options, errors, out, err, appLoader, (ClassFilter)null);
++ }
++
++ /**
++ * Constructor
++ *
++ * @param options options from command line or Context creator
++ * @param errors error manger
++ * @param out output writer for this Context
++ * @param err error writer for this Context
++ * @param appLoader application class loader
++ * @param classFilter class filter to use
++ */
++ public Context(final Options options, final ErrorManager errors, final PrintWriter out, final PrintWriter err, final ClassLoader appLoader, final ClassFilter classFilter) {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new RuntimePermission(NASHORN_CREATE_CONTEXT));
+ }
+
++ this.classFilter = classFilter;
+ this.env = new ScriptEnvironment(options, out, err);
+ this._strict = env._strict;
+ this.appLoader = appLoader;
+@@ -395,12 +489,11 @@
+ this.uniqueScriptId = new AtomicLong();
+ }
+ this.errors = errors;
+- this.uniqueEvalId = new AtomicLong();
+
+ // if user passed -classpath option, make a class loader with that and set it as
+ // thread context class loader so that script can access classes from that path.
+ final String classPath = options.getString("classpath");
+- if (! env._compile_only && classPath != null && !classPath.isEmpty()) {
++ if (!env._compile_only && classPath != null && !classPath.isEmpty()) {
+ // make sure that caller can create a class loader.
+ if (sm != null) {
+ sm.checkPermission(new RuntimePermission("createClassLoader"));
+@@ -416,16 +509,7 @@
+ }
+
+ if (env._persistent_cache) {
+- if (env._lazy_compilation || env._specialize_calls != null) {
+- getErr().println("Can not use persistent class caching with lazy compilation or call specialization.");
+- } else {
+- try {
+- final String cacheDir = Options.getStringProperty("nashorn.persistent.code.cache", "nashorn_code_cache");
+- codeStore = new CodeStore(cacheDir);
+- } catch (IOException e) {
+- throw new RuntimeException("Error initializing code cache", e);
+- }
+- }
++ codeStore = newCodeStore(this);
+ }
+
+ // print version info if asked.
+@@ -436,6 +520,26 @@
+ if (env._fullversion) {
+ getErr().println("nashorn full version " + Version.fullVersion());
+ }
++
++ initLoggers();
++ }
++
++
++ /**
++ * Get the class filter for this context
++ * @return class filter
++ */
++ public ClassFilter getClassFilter() {
++ return classFilter;
++ }
++
++ /**
++ * Returns the factory for constant method handles for global properties. The returned factory can be
++ * invalidated if this Context has more than one Global.
++ * @return the factory for constant method handles for global properties.
++ */
++ GlobalConstants getGlobalConstants() {
++ return globalConstantsRef.get();
+ }
+
+ /**
+@@ -512,13 +616,12 @@
+ */
+ public MultiGlobalCompiledScript compileScript(final Source source) {
+ final Class<?> clazz = compile(source, this.errors, this._strict);
+- final MethodHandle runMethodHandle = getRunScriptHandle(clazz);
+- final boolean strict = isStrict(clazz);
++ final MethodHandle createProgramFunctionHandle = getCreateProgramFunctionHandle(clazz);
+
+ return new MultiGlobalCompiledScript() {
+ @Override
+ public ScriptFunction getFunction(final Global newGlobal) {
+- return Context.getGlobal().newScriptFunction(RUN_SCRIPT.symbolName(), runMethodHandle, newGlobal, strict);
++ return invokeCreateProgramFunctionHandle(createProgramFunctionHandle, newGlobal);
+ }
+ };
+ }
+@@ -531,15 +634,31 @@
+ * @param callThis "this" to be passed to the evaluated code
+ * @param location location of the eval call
+ * @param strict is this {@code eval} call from a strict mode code?
++ * @return the return value of the {@code eval}
++ */
++ public Object eval(final ScriptObject initialScope, final String string,
++ final Object callThis, final Object location, final boolean strict) {
++ return eval(initialScope, string, callThis, location, strict, false);
++ }
++
++ /**
++ * Entry point for {@code eval}
++ *
++ * @param initialScope The scope of this eval call
++ * @param string Evaluated code as a String
++ * @param callThis "this" to be passed to the evaluated code
++ * @param location location of the eval call
++ * @param strict is this {@code eval} call from a strict mode code?
++ * @param evalCall is this called from "eval" builtin?
+ *
+ * @return the return value of the {@code eval}
+ */
+- public Object eval(final ScriptObject initialScope, final String string, final Object callThis, final Object location, final boolean strict) {
+- final String file = (location == UNDEFINED || location == null) ? "<eval>" : location.toString();
+- final Source source = sourceFor(file, string);
++ public Object eval(final ScriptObject initialScope, final String string,
++ final Object callThis, final Object location, final boolean strict, final boolean evalCall) {
++ final String file = location == UNDEFINED || location == null ? "<eval>" : location.toString();
++ final Source source = sourceFor(file, string, evalCall);
+ final boolean directEval = location != UNDEFINED; // is this direct 'eval' call or indirectly invoked eval?
+ final Global global = Context.getGlobal();
+-
+ ScriptObject scope = initialScope;
+
+ // ECMA section 10.1.1 point 2 says eval code is strict if it begins
+@@ -581,10 +700,10 @@
+ scope = strictEvalScope;
+ }
+
+- ScriptFunction func = getRunScriptFunction(clazz, scope);
++ final ScriptFunction func = getProgramFunction(clazz, scope);
+ Object evalThis;
+ if (directEval) {
+- evalThis = (callThis instanceof ScriptObject || strictFlag) ? callThis : global;
++ evalThis = callThis instanceof ScriptObject || strictFlag ? callThis : global;
+ } else {
+ evalThis = global;
+ }
+@@ -603,7 +722,7 @@
+ public Source run() {
+ try {
+ final URL resURL = Context.class.getResource(resource);
+- return (resURL != null)? sourceFor(srcStr, resURL) : null;
++ return resURL != null ? sourceFor(srcStr, resURL) : null;
+ } catch (final IOException exp) {
+ return null;
+ }
+@@ -626,7 +745,7 @@
+ * @throws IOException if source cannot be found or loaded
+ */
+ public Object load(final ScriptObject scope, final Object from) throws IOException {
+- final Object src = (from instanceof ConsString)? from.toString() : from;
++ final Object src = from instanceof ConsString ? from.toString() : from;
+ Source source = null;
+
+ // load accepts a String (which could be a URL or a file name), a File, a URL
+@@ -634,8 +753,8 @@
+ if (src instanceof String) {
+ final String srcStr = (String)src;
+ if (srcStr.startsWith(LOAD_CLASSPATH)) {
+- URL url = getResourceURL(srcStr.substring(LOAD_CLASSPATH.length()));
+- source = (url != null)? sourceFor(url.toString(), url) : null;
++ final URL url = getResourceURL(srcStr.substring(LOAD_CLASSPATH.length()));
++ source = url != null ? sourceFor(url.toString(), url) : null;
+ } else {
+ final File file = new File(srcStr);
+ if (srcStr.indexOf(':') != -1) {
+@@ -739,11 +858,12 @@
+ *
+ * @throws ClassNotFoundException if structure class cannot be resolved
+ */
+- public static Class<?> forStructureClass(final String fullName) throws ClassNotFoundException {
++ @SuppressWarnings("unchecked")
++ public static Class<? extends ScriptObject> forStructureClass(final String fullName) throws ClassNotFoundException {
+ if (System.getSecurityManager() != null && !StructureLoader.isStructureClass(fullName)) {
+ throw new ClassNotFoundException(fullName);
+ }
+- return Class.forName(fullName, true, sharedLoader);
++ return (Class<? extends ScriptObject>)Class.forName(fullName, true, sharedLoader);
+ }
+
+ /**
+@@ -839,6 +959,11 @@
+ throw new ClassNotFoundException(fullName);
+ }
+
++ // give chance to ClassFilter to filter out, if present
++ if (classFilter != null && !classFilter.exposeToScripts(fullName)) {
++ throw new ClassNotFoundException(fullName);
++ }
++
+ // check package access as soon as possible!
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+@@ -905,9 +1030,55 @@
+ * @return the global script object
+ */
+ public Global newGlobal() {
++ createOrInvalidateGlobalConstants();
+ return new Global(this);
+ }
+
++ private void createOrInvalidateGlobalConstants() {
++ for (;;) {
++ final GlobalConstants currentGlobalConstants = getGlobalConstants();
++ if (currentGlobalConstants != null) {
++ // Subsequent invocation; we're creating our second or later Global. GlobalConstants is not safe to use
++ // with more than one Global, as the constant method handle linkages it creates create a coupling
++ // between the Global and the call sites in the compiled code.
++ currentGlobalConstants.invalidateForever();
++ return;
++ }
++ final GlobalConstants newGlobalConstants = new GlobalConstants(getLogger(GlobalConstants.class));
++ if (globalConstantsRef.compareAndSet(null, newGlobalConstants)) {
++ // First invocation; we're creating the first Global in this Context. Create the GlobalConstants object
++ // for this Context.
++ return;
++ }
++
++ // If we reach here, then we started out as the first invocation, but another concurrent invocation won the
++ // CAS race. We'll just let the loop repeat and invalidate the CAS race winner.
++ }
++ }
++
++ /**
++ * Initialize given global scope object.
++ *
++ * @param global the global
++ * @param engine the associated ScriptEngine instance, can be null
++ * @return the initialized global scope object.
++ */
++ public Global initGlobal(final Global global, final ScriptEngine engine) {
++ // Need only minimal global object, if we are just compiling.
++ if (!env._compile_only) {
++ final Global oldGlobal = Context.getGlobal();
++ try {
++ Context.setGlobal(global);
++ // initialize global scope with builtin global objects
++ global.initBuiltinObjects(engine);
++ } finally {
++ Context.setGlobal(oldGlobal);
++ }
++ }
++
++ return global;
++ }
++
+ /**
+ * Initialize given global scope object.
+ *
+@@ -915,31 +1086,27 @@
+ * @return the initialized global scope object.
+ */
+ public Global initGlobal(final Global global) {
+- // Need only minimal global object, if we are just compiling.
+- if (!env._compile_only) {
+- final Global oldGlobal = Context.getGlobal();
+- try {
+- Context.setGlobal(global);
+- // initialize global scope with builtin global objects
+- global.initBuiltinObjects();
+- } finally {
+- Context.setGlobal(oldGlobal);
+- }
+- }
+-
+- return global;
++ return initGlobal(global, null);
+ }
+
+ /**
+- * Trusted variant - package-private
+- */
+-
+- /**
+ * Return the current global's context
+ * @return current global's context
+ */
+ static Context getContextTrusted() {
+- return ((ScriptObject)Context.getGlobal()).getContext();
++ return getContext(getGlobal());
++ }
++
++ static Context getContextTrustedOrNull() {
++ final Global global = Context.getGlobal();
++ return global == null ? null : getContext(global);
++ }
++
++ private static Context getContext(final Global global) {
++ // We can't invoke Global.getContext() directly, as it's a protected override, and Global isn't in our package.
++ // In order to access the method, we must cast it to ScriptObject first (which is in our package) and then let
++ // virtual invocation do its thing.
++ return ((ScriptObject)global).getContext();
+ }
+
+ /**
+@@ -983,40 +1150,33 @@
+ return ScriptRuntime.apply(script, thiz);
+ }
+
+- private static MethodHandle getRunScriptHandle(final Class<?> script) {
+- return MH.findStatic(
+- MethodHandles.lookup(),
+- script,
+- RUN_SCRIPT.symbolName(),
+- MH.type(
+- Object.class,
+- ScriptFunction.class,
+- Object.class));
++ private static ScriptFunction getProgramFunction(final Class<?> script, final ScriptObject scope) {
++ if (script == null) {
++ return null;
++ }
++ return invokeCreateProgramFunctionHandle(getCreateProgramFunctionHandle(script), scope);
+ }
+
+- private static boolean isStrict(final Class<?> script) {
++ private static MethodHandle getCreateProgramFunctionHandle(final Class<?> script) {
+ try {
+- return script.getField(STRICT_MODE.symbolName()).getBoolean(null);
+- } catch (final NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
+- return false;
++ return LOOKUP.findStatic(script, CREATE_PROGRAM_FUNCTION.symbolName(), CREATE_PROGRAM_FUNCTION_TYPE);
++ } catch (NoSuchMethodException | IllegalAccessException e) {
++ throw new AssertionError("Failed to retrieve a handle for the program function for " + script.getName(), e);
+ }
+ }
+
+- private static ScriptFunction getRunScriptFunction(final Class<?> script, final ScriptObject scope) {
+- if (script == null) {
+- return null;
++ private static ScriptFunction invokeCreateProgramFunctionHandle(final MethodHandle createProgramFunctionHandle, final ScriptObject scope) {
++ try {
++ return (ScriptFunction)createProgramFunctionHandle.invokeExact(scope);
++ } catch (final RuntimeException|Error e) {
++ throw e;
++ } catch (final Throwable t) {
++ throw new AssertionError("Failed to create a program function", t);
+ }
+-
+- // Get run method - the entry point to the script
+- final MethodHandle runMethodHandle = getRunScriptHandle(script);
+- boolean strict = isStrict(script);
+-
+- // Package as a JavaScript function and pass function back to shell.
+- return Context.getGlobal().newScriptFunction(RUN_SCRIPT.symbolName(), runMethodHandle, scope, strict);
+ }
+
+ private ScriptFunction compileScript(final Source source, final ScriptObject scope, final ErrorManager errMan) {
+- return getRunScriptFunction(compile(source, errMan, this._strict), scope);
++ return getProgramFunction(compile(source, errMan, this._strict), scope);
+ }
+
+ private synchronized Class<?> compile(final Source source, final ErrorManager errMan, final boolean strict) {
+@@ -1025,35 +1185,37 @@
+
+ Class<?> script = findCachedClass(source);
+ if (script != null) {
+- Compiler.LOG.fine("Code cache hit for ", source, " avoiding recompile.");
++ final DebugLogger log = getLogger(Compiler.class);
++ if (log.isEnabled()) {
++ log.fine(new RuntimeEvent<>(Level.INFO, source), "Code cache hit for ", source, " avoiding recompile.");
++ }
+ return script;
+ }
+
+- CompiledScript compiledScript = null;
++ StoredScript storedScript = null;
+ FunctionNode functionNode = null;
++ // We only use the code store here if optimistic types are disabled. With optimistic types, initial compilation
++ // just creates a thin wrapper, and actual code is stored per function in RecompilableScriptFunctionData.
++ final boolean useCodeStore = codeStore != null && !env._parse_only && !env._optimistic_types;
++ final String cacheKey = useCodeStore ? CodeStore.getCacheKey(0, null) : null;
+
+- if (!env._parse_only && codeStore != null) {
+- try {
+- compiledScript = codeStore.getScript(source);
+- } catch (IOException | ClassNotFoundException e) {
+- Compiler.LOG.warning("Error loading ", source, " from cache: ", e);
+- // Fall back to normal compilation
+- }
++ if (useCodeStore) {
++ storedScript = codeStore.load(source, cacheKey);
+ }
+
+- if (compiledScript == null) {
+- functionNode = new Parser(env, source, errMan, strict).parse();
++ if (storedScript == null) {
++ functionNode = new Parser(env, source, errMan, strict, getLogger(Parser.class)).parse();
+
+- if (errors.hasErrors()) {
++ if (errMan.hasErrors()) {
+ return null;
+ }
+
+- if (env._print_ast) {
++ if (env._print_ast || functionNode.getFlag(FunctionNode.IS_PRINT_AST)) {
+ getErr().println(new ASTWriter(functionNode));
+ }
+
+- if (env._print_parse) {
+- getErr().println(new PrintVisitor(functionNode));
++ if (env._print_parse || functionNode.getFlag(FunctionNode.IS_PRINT_PARSE)) {
++ getErr().println(new PrintVisitor(functionNode, true, false));
+ }
+ }
+
+@@ -1066,12 +1228,26 @@
+ final CodeSource cs = new CodeSource(url, (CodeSigner[])null);
+ final CodeInstaller<ScriptEnvironment> installer = new ContextCodeInstaller(this, loader, cs);
+
+- if (functionNode != null) {
+- final Compiler compiler = new Compiler(installer, strict);
+- final FunctionNode newFunctionNode = compiler.compile(functionNode);
+- script = compiler.install(newFunctionNode);
++ if (storedScript == null) {
++ final CompilationPhases phases = Compiler.CompilationPhases.COMPILE_ALL;
++
++ final Compiler compiler = new Compiler(
++ this,
++ env,
++ installer,
++ source,
++ errMan,
++ strict | functionNode.isStrict());
++
++ final FunctionNode compiledFunction = compiler.compile(functionNode, phases);
++ if (errMan.hasErrors()) {
++ return null;
++ }
++ script = compiledFunction.getRootClass();
++ compiler.persistClassInfo(cacheKey, compiledFunction);
+ } else {
+- script = install(compiledScript, installer);
++ Compiler.updateCompilationId(storedScript.getCompilationId());
++ script = install(storedScript, source, installer);
+ }
+
+ cacheClass(source, script);
+@@ -1088,48 +1264,53 @@
+ }, CREATE_LOADER_ACC_CTXT);
+ }
+
+- private long getUniqueEvalId() {
+- return uniqueEvalId.getAndIncrement();
+- }
+-
+ private long getUniqueScriptId() {
+ return uniqueScriptId.getAndIncrement();
+ }
+
+-
+ /**
+ * Install a previously compiled class from the code cache.
+ *
+- * @param compiledScript cached script containing class bytes and constants
++ * @param storedScript cached script containing class bytes and constants
+ * @return main script class
+ */
+- private Class<?> install(final CompiledScript compiledScript, final CodeInstaller<ScriptEnvironment> installer) {
++ private static Class<?> install(final StoredScript storedScript, final Source source, final CodeInstaller<ScriptEnvironment> installer) {
+
+ final Map<String, Class<?>> installedClasses = new HashMap<>();
+- final Source source = compiledScript.getSource();
+- final Object[] constants = compiledScript.getConstants();
+- final String rootClassName = compiledScript.getMainClassName();
+- final byte[] rootByteCode = compiledScript.getClassBytes().get(rootClassName);
+- final Class<?> rootClass = installer.install(rootClassName, rootByteCode, source, constants);
++ final Map<String, byte[]> classBytes = storedScript.getClassBytes();
++ final Object[] constants = storedScript.getConstants();
++ final String mainClassName = storedScript.getMainClassName();
++ final byte[] mainClassBytes = classBytes.get(mainClassName);
++ final Class<?> mainClass = installer.install(mainClassName, mainClassBytes);
++ final Map<Integer, FunctionInitializer> initializers = storedScript.getInitializers();
+
+- installedClasses.put(rootClassName, rootClass);
++ installedClasses.put(mainClassName, mainClass);
+
+- for (final Map.Entry<String, byte[]> entry : compiledScript.getClassBytes().entrySet()) {
++ for (final Map.Entry<String, byte[]> entry : classBytes.entrySet()) {
+ final String className = entry.getKey();
+- if (className.equals(rootClassName)) {
++ if (className.equals(mainClassName)) {
+ continue;
+ }
+ final byte[] code = entry.getValue();
+
+- installedClasses.put(className, installer.install(className, code, source, constants));
++ installedClasses.put(className, installer.install(className, code));
+ }
+- for (Object constant : constants) {
++
++ installer.initialize(installedClasses.values(), source, constants);
++
++ for (final Object constant : constants) {
+ if (constant instanceof RecompilableScriptFunctionData) {
+- ((RecompilableScriptFunctionData) constant).setCodeAndSource(installedClasses, source);
++ final RecompilableScriptFunctionData data = (RecompilableScriptFunctionData) constant;
++ data.initTransients(source, installer);
++ final FunctionInitializer initializer = initializers.get(data.getFunctionNodeId());
++ if (initializer != null) {
++ initializer.setCode(installedClasses.get(initializer.getClassName()));
++ data.initializeCode(initializer);
++ }
+ }
+ }
+
+- return rootClass;
++ return mainClass;
+ }
+
+ /**
+@@ -1140,7 +1321,7 @@
+ private final int size;
+ private final ReferenceQueue<Class<?>> queue;
+
+- ClassCache(int size) {
++ ClassCache(final int size) {
+ super(size, 0.75f, true);
+ this.size = size;
+ this.queue = new ReferenceQueue<>();
+@@ -1156,7 +1337,7 @@
+ }
+
+ @Override
+- public ClassReference get(Object key) {
++ public ClassReference get(final Object key) {
+ for (ClassReference ref; (ref = (ClassReference)queue.poll()) != null; ) {
+ remove(ref.source);
+ }
+@@ -1176,7 +1357,7 @@
+
+ // Class cache management
+ private Class<?> findCachedClass(final Source source) {
+- ClassReference ref = classCache == null ? null : classCache.get(source);
++ final ClassReference ref = classCache == null ? null : classCache.get(source);
+ return ref != null ? ref.get() : null;
+ }
+
+@@ -1186,5 +1367,121 @@
+ }
+ }
+
++ // logging
++ private final Map<String, DebugLogger> loggers = new HashMap<>();
++
++ private void initLoggers() {
++ ((Loggable)MethodHandleFactory.getFunctionality()).initLogger(this);
++ }
++
++ /**
++ * Get a logger, given a loggable class
++ * @param clazz a Loggable class
++ * @return debuglogger associated with that class
++ */
++ public DebugLogger getLogger(final Class<? extends Loggable> clazz) {
++ return getLogger(clazz, null);
++ }
++
++ /**
++ * Get a logger, given a loggable class
++ * @param clazz a Loggable class
++ * @param initHook an init hook - if this is the first time the logger is created in the context, run the init hook
++ * @return debuglogger associated with that class
++ */
++ public DebugLogger getLogger(final Class<? extends Loggable> clazz, final Consumer<DebugLogger> initHook) {
++ final String name = getLoggerName(clazz);
++ DebugLogger logger = loggers.get(name);
++ if (logger == null) {
++ if (!env.hasLogger(name)) {
++ return DebugLogger.DISABLED_LOGGER;
++ }
++ final LoggerInfo info = env._loggers.get(name);
++ logger = new DebugLogger(name, info.getLevel(), info.isQuiet());
++ if (initHook != null) {
++ initHook.accept(logger);
++ }
++ loggers.put(name, logger);
++ }
++ return logger;
++ }
++
++ /**
++ * Given a Loggable class, weave debug info info a method handle for that logger.
++ * Level.INFO is used
++ *
++ * @param clazz loggable
++ * @param mh method handle
++ * @param text debug printout to add
++ *
++ * @return instrumented method handle, or null if logger not enabled
++ */
++ public MethodHandle addLoggingToHandle(final Class<? extends Loggable> clazz, final MethodHandle mh, final Supplier<String> text) {
++ return addLoggingToHandle(clazz, Level.INFO, mh, Integer.MAX_VALUE, false, text);
++ }
++
++ /**
++ * Given a Loggable class, weave debug info info a method handle for that logger.
++ *
++ * @param clazz loggable
++ * @param level log level
++ * @param mh method handle
++ * @param paramStart first parameter to print
++ * @param printReturnValue should we print the return vaulue?
++ * @param text debug printout to add
++ *
++ * @return instrumented method handle, or null if logger not enabled
++ */
++ public MethodHandle addLoggingToHandle(final Class<? extends Loggable> clazz, final Level level, final MethodHandle mh, final int paramStart, final boolean printReturnValue, final Supplier<String> text) {
++ final DebugLogger log = getLogger(clazz);
++ if (log.isEnabled()) {
++ return MethodHandleFactory.addDebugPrintout(log, level, mh, paramStart, printReturnValue, text.get());
++ }
++ return mh;
++ }
++
++ private static String getLoggerName(final Class<?> clazz) {
++ Class<?> current = clazz;
++ while (current != null) {
++ final Logger log = current.getAnnotation(Logger.class);
++ if (log != null) {
++ assert !"".equals(log.name());
++ return log.name();
++ }
++ current = current.getSuperclass();
++ }
++ assert false;
++ return null;
++ }
++
++ /**
++ * This is a special kind of switchpoint used to guard builtin
++ * properties and prototypes. In the future it might contain
++ * logic to e.g. multiple switchpoint classes.
++ */
++ public static final class BuiltinSwitchPoint extends SwitchPoint {
++ //empty
++ }
++
++ /**
++ * Create a new builtin switchpoint and return it
++ * @param name key name
++ * @return new builtin switchpoint
++ */
++ public SwitchPoint newBuiltinSwitchPoint(final String name) {
++ assert builtinSwitchPoints.get(name) == null;
++ final SwitchPoint sp = new BuiltinSwitchPoint();
++ builtinSwitchPoints.put(name, sp);
++ return sp;
++ }
++
++ /**
++ * Return the builtin switchpoint for a particular key name
++ * @param name key name
++ * @return builtin switchpoint or null if none
++ */
++ public SwitchPoint getBuiltinSwitchPoint(final String name) {
++ return builtinSwitchPoints.get(name);
++ }
+
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/Debug.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/Debug.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,7 +26,6 @@
+ package jdk.nashorn.internal.runtime;
+
+ import static jdk.nashorn.internal.parser.TokenType.EOF;
+-
+ import jdk.nashorn.internal.parser.Lexer;
+ import jdk.nashorn.internal.parser.Token;
+ import jdk.nashorn.internal.parser.TokenStream;
+@@ -41,6 +40,29 @@
+ }
+
+ /**
++ * Return the topmost JavaScript frame in a stack trace
++ * @param t throwable that contains the stack trace
++ * @return line describing the topmost JavaScript frame
++ */
++ public static String firstJSFrame(final Throwable t) {
++ for (final StackTraceElement ste : t.getStackTrace()) {
++ if (ECMAErrors.isScriptFrame(ste)) {
++ return ste.toString();
++ }
++ }
++ return "<native code>";
++ }
++
++ /**
++ * Return the topmost JavaScript frame from the current
++ * continuation
++ * @return line describing the topmost JavaScript frame
++ */
++ public static String firstJSFrame() {
++ return firstJSFrame(new Throwable());
++ }
++
++ /**
+ * Return the system identity hashcode for an object as a human readable
+ * string
+ *
+@@ -48,7 +70,18 @@
+ * @return system identity hashcode as string
+ */
+ public static String id(final Object x) {
+- return "0x" + Integer.toHexString(System.identityHashCode(x));
++ return String.format("0x%08x", System.identityHashCode(x));
++ }
++
++ /**
++ * Same as {@link Debug#id} but returns the identity hashcode as
++ * an integer
++ *
++ * @param x object
++ * @return system identity hashcode
++ */
++ public static int intId(final Object x) {
++ return System.identityHashCode(x);
+ }
+
+ /**
+--- ./nashorn/src/jdk/nashorn/internal/runtime/DebugLogger.java Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,304 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
+-
+-import java.io.PrintWriter;
+-import java.util.logging.Level;
+-import java.util.logging.Logger;
+-import jdk.nashorn.internal.runtime.options.Options;
+-
+-/**
+- * Wrapper class for Logging system. This is how you are supposed to register a logger and use it
+- */
+-
+-public final class DebugLogger {
+- private final Logger logger;
+- private final boolean isEnabled;
+-
+- private int indent;
+-
+- private static final int INDENT_SPACE = 4;
+-
+- /**
+- * Constructor
+- *
+- * @param loggerName name of logger - this is the unique key with which it can be identified
+- */
+- public DebugLogger(final String loggerName) {
+- this(loggerName, null);
+- }
+-
+- /**
+- * Constructor
+- *
+- * A logger can be paired with a property, e.g. {@code --log:codegen:info} is equivalent to {@code -Dnashorn.codegen.log}
+- *
+- * @param loggerName name of logger - this is the unique key with which it can be identified
+- * @param property system property activating the logger on {@code info} level
+- */
+- public DebugLogger(final String loggerName, final String property) {
+- if (property != null && Options.getBooleanProperty(property)) {
+- this.logger = Logging.getOrCreateLogger(loggerName, Level.INFO);
+- } else {
+- this.logger = Logging.getLogger(loggerName);
+- }
+- assert logger != null;
+- this.isEnabled = getLevel() != Level.OFF;
+- }
+-
+- /**
+- * Do not currently support chaining this with parent logger. Logger level null
+- * means disabled
+- * @return level
+- */
+- private Level getLevel() {
+- return logger.getLevel() == null ? Level.OFF : logger.getLevel();
+- }
+-
+- /**
+- * Get the output writer for the logger. Loggers always default to
+- * stderr for output as they are used mainly to output debug info
+- *
+- * Can be inherited so this should not be static.
+- *
+- * @return print writer for log output.
+- */
+- @SuppressWarnings("static-method")
+- public PrintWriter getOutputStream() {
+- return Context.getCurrentErr();
+- }
+-
+- /**
+- * Check if the logger is enabled
+- * @return true if enabled
+- */
+- public boolean isEnabled() {
+- return isEnabled;
+- }
+-
+- /**
+- * If you want to change the indent level of your logger, call indent with a new position.
+- * Positions start at 0 and are increased by one for a new "tab"
+- *
+- * @param pos indent position
+- */
+- public void indent(final int pos) {
+- if (isEnabled) {
+- indent += pos * INDENT_SPACE;
+- }
+- }
+-
+- /**
+- * Add an indent position
+- */
+- public void indent() {
+- indent += INDENT_SPACE;
+- }
+-
+- /**
+- * Unindent a position
+- */
+- public void unindent() {
+- indent -= INDENT_SPACE;
+- if (indent < 0) {
+- indent = 0;
+- }
+- }
+-
+- /**
+- * Check if the logger is above of the level of detail given
+- * @see java.util.logging.Level
+- *
+- * @param level logging level
+- * @return true if level is above the given one
+- */
+- public boolean levelAbove(final Level level) {
+- return getLevel().intValue() > level.intValue();
+- }
+-
+- /**
+- * Shorthand for outputting a log string as log level {@link java.util.logging.Level#FINEST} on this logger
+- * @param str the string to log
+- */
+- public void finest(final String str) {
+- log(Level.FINEST, str);
+- }
+-
+- /**
+- * Shorthand for outputting a log string as log level
+- * {@link java.util.logging.Level#FINEST} on this logger
+- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+- */
+- public void finest(final Object... objs) {
+- log(Level.FINEST, objs);
+- }
+-
+- /**
+- * Shorthand for outputting a log string as log level
+- * {@link java.util.logging.Level#FINER} on this logger
+- * @param str the string to log
+- */
+- public void finer(final String str) {
+- log(Level.FINER, str);
+- }
+-
+- /**
+- * Shorthand for outputting a log string as log level
+- * {@link java.util.logging.Level#FINER} on this logger
+- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+- */
+- public void finer(final Object... objs) {
+- log(Level.FINER, objs);
+- }
+-
+- /**
+- * Shorthand for outputting a log string as log level
+- * {@link java.util.logging.Level#FINE} on this logger
+- * @param str the string to log
+- */
+- public void fine(final String str) {
+- log(Level.FINE, str);
+- }
+-
+- /**
+- * Shorthand for outputting a log string as log level
+- * {@link java.util.logging.Level#FINE} on this logger
+- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+- */
+- public void fine(final Object... objs) {
+- log(Level.FINE, objs);
+- }
+-
+- /**
+- * Shorthand for outputting a log string as log level
+- * {@link java.util.logging.Level#CONFIG} on this logger
+- * @param str the string to log
+- */
+- public void config(final String str) {
+- log(Level.CONFIG, str);
+- }
+-
+- /**
+- * Shorthand for outputting a log string as log level
+- * {@link java.util.logging.Level#CONFIG} on this logger
+- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+- */
+- public void config(final Object... objs) {
+- log(Level.CONFIG, objs);
+- }
+-
+- /**
+- * Shorthand for outputting a log string as log level
+- * {@link java.util.logging.Level#INFO} on this logger
+- * @param str the string to log
+- */
+- public void info(final String str) {
+- log(Level.INFO, str);
+- }
+-
+- /**
+- * Shorthand for outputting a log string as log level
+- * {@link java.util.logging.Level#FINE} on this logger
+- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+- */
+- public void info(final Object... objs) {
+- log(Level.INFO, objs);
+- }
+-
+- /**
+- * Shorthand for outputting a log string as log level
+- * {@link java.util.logging.Level#WARNING} on this logger
+- * @param str the string to log
+- */
+- public void warning(final String str) {
+- log(Level.WARNING, str);
+- }
+-
+- /**
+- * Shorthand for outputting a log string as log level
+- * {@link java.util.logging.Level#FINE} on this logger
+- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+- */
+- public void warning(final Object... objs) {
+- log(Level.WARNING, objs);
+- }
+-
+- /**
+- * Shorthand for outputting a log string as log level
+- * {@link java.util.logging.Level#SEVERE} on this logger
+- * @param str the string to log
+- */
+- public void severe(final String str) {
+- log(Level.SEVERE, str);
+- }
+-
+- /**
+- * Shorthand for outputting a log string as log level
+- * {@link java.util.logging.Level#FINE} on this logger
+- * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
+- */
+- public void severe(final Object... objs) {
+- log(Level.SEVERE, objs);
+- }
+-
+- /**
+- * Output log line on this logger at a given level of verbosity
+- * @see java.util.logging.Level
+- *
+- * @param level minimum log level required for logging to take place
+- * @param str string to log
+- */
+- public void log(final Level level, final String str) {
+- if (isEnabled) {
+- final StringBuilder sb = new StringBuilder();
+- for (int i = 0 ; i < indent ; i++) {
+- sb.append(' ');
+- }
+- sb.append(str);
+- logger.log(level, sb.toString());
+- }
+- }
+-
+- /**
+- * Output log line on this logger at a given level of verbosity
+- * @see java.util.logging.Level
+- *
+- * @param level minimum log level required for logging to take place
+- * @param objs objects for which to invoke toString and concatenate to log
+- */
+- public void log(final Level level, final Object... objs) {
+- if (isEnabled) {
+- final StringBuilder sb = new StringBuilder();
+- for (int i = 0 ; i < indent ; i++) {
+- sb.append(' ');
+- }
+- for (final Object obj : objs) {
+- sb.append(obj);
+- }
+- logger.log(level, sb.toString());
+- }
+- }
+-}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/DebuggerSupport.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/DebuggerSupport.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,6 +26,7 @@
+ package jdk.nashorn.internal.runtime;
+
+ import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
+
+ import java.lang.invoke.MethodHandle;
+ import java.lang.reflect.Field;
+@@ -53,6 +54,7 @@
+ * available to external debuggers.
+ */
+ @SuppressWarnings("unused")
++ final
+ DebuggerValueDesc forceLoad = new DebuggerValueDesc(null, false, null, null);
+
+ // Hook to force the loading of the SourceInfo class
+@@ -155,7 +157,7 @@
+
+ try {
+ return context.eval(initialScope, string, callThis, ScriptRuntime.UNDEFINED, false);
+- } catch (Throwable ex) {
++ } catch (final Throwable ex) {
+ return returnException ? ex : null;
+ }
+ }
+@@ -237,12 +239,12 @@
+
+ if (ScriptObject.isArray(object)) {
+ sb.append('[');
+- final long length = object.getLong("length");
++ final long length = object.getLong("length", INVALID_PROGRAM_POINT);
+
+ for (long i = 0; i < length; i++) {
+ if (object.has(i)) {
+ final Object valueAsObject = object.get(i);
+- final boolean isUndefined = JSType.of(valueAsObject) == JSType.UNDEFINED;
++ final boolean isUndefined = valueAsObject == ScriptRuntime.UNDEFINED;
+
+ if (isUndefined) {
+ if (i != 0) {
+--- ./nashorn/src/jdk/nashorn/internal/runtime/DefaultPropertyAccess.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/DefaultPropertyAccess.java Wed Feb 04 12:14:47 2015 -0800
+@@ -34,63 +34,63 @@
+ public abstract class DefaultPropertyAccess implements PropertyAccess {
+
+ @Override
+- public int getInt(final Object key) {
++ public int getInt(final Object key, final int programPoint) {
+ return JSType.toInt32(get(key));
+ }
+
+ @Override
+- public int getInt(final double key) {
+- return getInt(JSType.toObject(key));
++ public int getInt(final double key, final int programPoint) {
++ return getInt(JSType.toObject(key), programPoint);
+ }
+
+ @Override
+- public int getInt(final long key) {
+- return getInt(JSType.toObject(key));
++ public int getInt(final long key, final int programPoint) {
++ return getInt(JSType.toObject(key), programPoint);
+ }
+
+ @Override
+- public int getInt(final int key) {
+- return getInt(JSType.toObject(key));
++ public int getInt(final int key, final int programPoint) {
++ return getInt(JSType.toObject(key), programPoint);
+ }
+
+ @Override
+- public long getLong(final Object key) {
++ public long getLong(final Object key, final int programPoint) {
+ return JSType.toLong(get(key));
+ }
+
+ @Override
+- public long getLong(final double key) {
+- return getLong(JSType.toObject(key));
++ public long getLong(final double key, final int programPoint) {
++ return getLong(JSType.toObject(key), programPoint);
+ }
+
+ @Override
+- public long getLong(final long key) {
+- return getLong(JSType.toObject(key));
++ public long getLong(final long key, final int programPoint) {
++ return getLong(JSType.toObject(key), programPoint);
+ }
+
+ @Override
+- public long getLong(final int key) {
+- return getLong(JSType.toObject(key));
++ public long getLong(final int key, final int programPoint) {
++ return getLong(JSType.toObject(key), programPoint);
+ }
+
+ @Override
+- public double getDouble(final Object key) {
++ public double getDouble(final Object key, final int programPoint) {
+ return JSType.toNumber(get(key));
+ }
+
+ @Override
+- public double getDouble(final double key) {
+- return getDouble(JSType.toObject(key));
++ public double getDouble(final double key, final int programPoint) {
++ return getDouble(JSType.toObject(key), programPoint);
+ }
+
+ @Override
+- public double getDouble(final long key) {
+- return getDouble(JSType.toObject(key));
++ public double getDouble(final long key, final int programPoint) {
++ return getDouble(JSType.toObject(key), programPoint);
+ }
+
+ @Override
+- public double getDouble(final int key) {
+- return getDouble(JSType.toObject(key));
++ public double getDouble(final int key, final int programPoint) {
++ return getDouble(JSType.toObject(key), programPoint);
+ }
+
+ @Override
+@@ -112,82 +112,82 @@
+ }
+
+ @Override
+- public void set(final double key, final int value, final boolean strict) {
+- set(JSType.toObject(key), JSType.toObject(value), strict);
++ public void set(final double key, final int value, final int flags) {
++ set(JSType.toObject(key), JSType.toObject(value), flags);
+ }
+
+ @Override
+- public void set(final double key, final long value, final boolean strict) {
+- set(JSType.toObject(key), JSType.toObject(value), strict);
++ public void set(final double key, final long value, final int flags) {
++ set(JSType.toObject(key), JSType.toObject(value), flags);
+ }
+
+ @Override
+- public void set(final double key, final double value, final boolean strict) {
+- set(JSType.toObject(key), JSType.toObject(value), strict);
++ public void set(final double key, final double value, final int flags) {
++ set(JSType.toObject(key), JSType.toObject(value), flags);
+ }
+
+ @Override
+- public void set(final double key, final Object value, final boolean strict) {
+- set(JSType.toObject(key), JSType.toObject(value), strict);
++ public void set(final double key, final Object value, final int flags) {
++ set(JSType.toObject(key), JSType.toObject(value), flags);
+ }
+
+ @Override
+- public void set(final long key, final int value, final boolean strict) {
+- set(JSType.toObject(key), JSType.toObject(value), strict);
++ public void set(final long key, final int value, final int flags) {
++ set(JSType.toObject(key), JSType.toObject(value), flags);
+ }
+
+ @Override
+- public void set(final long key, final long value, final boolean strict) {
+- set(JSType.toObject(key), JSType.toObject(value), strict);
++ public void set(final long key, final long value, final int flags) {
++ set(JSType.toObject(key), JSType.toObject(value), flags);
+ }
+
+ @Override
+- public void set(final long key, final double value, final boolean strict) {
+- set(JSType.toObject(key), JSType.toObject(value), strict);
++ public void set(final long key, final double value, final int flags) {
++ set(JSType.toObject(key), JSType.toObject(value), flags);
+ }
+
+ @Override
+- public void set(final long key, final Object value, final boolean strict) {
+- set(JSType.toObject(key), value, strict);
++ public void set(final long key, final Object value, final int flags) {
++ set(JSType.toObject(key), value, flags);
+ }
+
+ @Override
+- public void set(final int key, final int value, final boolean strict) {
+- set(JSType.toObject(key), JSType.toObject(value), strict);
++ public void set(final int key, final int value, final int flags) {
++ set(JSType.toObject(key), JSType.toObject(value), flags);
+ }
+
+ @Override
+- public void set(final int key, final long value, final boolean strict) {
+- set(JSType.toObject(key), JSType.toObject(value), strict);
++ public void set(final int key, final long value, final int flags) {
++ set(JSType.toObject(key), JSType.toObject(value), flags);
+ }
+
+ @Override
+- public void set(final int key, final double value, final boolean strict) {
+- set(JSType.toObject(key), JSType.toObject(value), strict);
++ public void set(final int key, final double value, final int flags) {
++ set(JSType.toObject(key), JSType.toObject(value), flags);
+ }
+
+ @Override
+- public void set(final int key, final Object value, final boolean strict) {
+- set(JSType.toObject(key), value, strict);
++ public void set(final int key, final Object value, final int flags) {
++ set(JSType.toObject(key), value, flags);
+ }
+
+ @Override
+- public void set(final Object key, final int value, final boolean strict) {
+- set(key, JSType.toObject(value), strict);
++ public void set(final Object key, final int value, final int flags) {
++ set(key, JSType.toObject(value), flags);
+ }
+
+ @Override
+- public void set(final Object key, final long value, final boolean strict) {
+- set(key, JSType.toObject(value), strict);
++ public void set(final Object key, final long value, final int flags) {
++ set(key, JSType.toObject(value), flags);
+ }
+
+ @Override
+- public void set(final Object key, final double value, final boolean strict) {
+- set(key, JSType.toObject(value), strict);
++ public void set(final Object key, final double value, final int flags) {
++ set(key, JSType.toObject(value), flags);
+ }
+
+ @Override
+- public abstract void set(Object key, Object value, boolean strict);
++ public abstract void set(Object key, Object value, int flags);
+
+ @Override
+ public abstract boolean has(Object key);
+--- ./nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,10 +28,9 @@
+ import java.text.MessageFormat;
+ import java.util.Locale;
+ import java.util.ResourceBundle;
+-import jdk.nashorn.api.scripting.NashornException;
+-import jdk.nashorn.internal.scripts.JS;
+ import jdk.nashorn.internal.codegen.CompilerConstants;
+ import jdk.nashorn.internal.objects.Global;
++import jdk.nashorn.internal.scripts.JS;
+
+ /**
+ * Helper class to throw various standard "ECMA error" exceptions such as Error, ReferenceError, TypeError etc.
+@@ -47,7 +46,7 @@
+ /** We assume that compiler generates script classes into the known package. */
+ private static final String scriptPackage;
+ static {
+- String name = JS.class.getName();
++ final String name = JS.class.getName();
+ scriptPackage = name.substring(0, name.lastIndexOf('.'));
+ }
+
+@@ -403,14 +402,10 @@
+ final String className = frame.getClassName();
+
+ // Look for script package in class name (into which compiler puts generated code)
+- if (className.startsWith(scriptPackage) && !frame.getMethodName().startsWith(CompilerConstants.INTERNAL_METHOD_PREFIX)) {
++ if (className.startsWith(scriptPackage) && !CompilerConstants.isInternalMethodName(frame.getMethodName())) {
+ final String source = frame.getFileName();
+- /*
+- * Make sure that it is not some Java code that Nashorn has in that package!
+- * also, we don't want to report JavaScript code that lives in script engine implementation
+- * We want to report only user's own scripts and not any of our own scripts like "engine.js"
+- */
+- return source != null && !source.endsWith(".java") && !source.contains(NashornException.ENGINE_SCRIPT_SOURCE_NAME);
++ // Make sure that it is not some Java code that Nashorn has in that package!
++ return source != null && !source.endsWith(".java");
+ }
+ return false;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/ECMAException.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/ECMAException.java Wed Feb 04 12:14:47 2015 -0800
+@@ -96,15 +96,17 @@
+ // If thrown object is an Error or sub-object like TypeError, then
+ // an ECMAException object has been already initialized at constructor.
+ if (thrown instanceof ScriptObject) {
+- ScriptObject sobj = (ScriptObject)thrown;
+- Object exception = getException(sobj);
++ final Object exception = getException((ScriptObject)thrown);
+ if (exception instanceof ECMAException) {
+- // copy over file name, line number and column number.
+ final ECMAException ee = (ECMAException)exception;
+- ee.setFileName(fileName);
+- ee.setLineNumber(line);
+- ee.setColumnNumber(column);
+- return ee;
++ // Make sure exception has correct thrown reference because that's what will end up getting caught.
++ if (ee.getThrown() == thrown) {
++ // copy over file name, line number and column number.
++ ee.setFileName(fileName);
++ ee.setLineNumber(line);
++ ee.setColumnNumber(column);
++ return ee;
++ }
+ }
+ }
+
+@@ -154,7 +156,11 @@
+ * @return a {@link ECMAException}
+ */
+ public static Object getException(final ScriptObject errObj) {
+- return errObj.get(ECMAException.EXCEPTION_PROPERTY);
++ // Exclude inherited properties that may belong to errors in the prototype chain.
++ if (errObj.hasOwnProperty(ECMAException.EXCEPTION_PROPERTY)) {
++ return errObj.get(ECMAException.EXCEPTION_PROPERTY);
++ }
++ return null;
+ }
+
+ /**
+@@ -285,7 +291,7 @@
+ if (!sobj.has(EXCEPTION_PROPERTY)) {
+ sobj.addOwnProperty(EXCEPTION_PROPERTY, Property.NOT_ENUMERABLE, this);
+ } else {
+- sobj.set(EXCEPTION_PROPERTY, this, false);
++ sobj.set(EXCEPTION_PROPERTY, this, 0);
+ }
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,9 +25,9 @@
+
+ package jdk.nashorn.internal.runtime;
+
+-import static jdk.nashorn.internal.lookup.Lookup.MH;
+-
+ import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodType;
++import java.util.List;
+
+ /**
+ * This is a subclass that represents a script function that may not be regenerated.
+@@ -35,6 +35,8 @@
+ */
+ final class FinalScriptFunctionData extends ScriptFunctionData {
+
++ private static final long serialVersionUID = -930632846167768864L;
++
+ /**
+ * Constructor - used for bind
+ *
+@@ -43,9 +45,10 @@
+ * @param functions precompiled code
+ * @param flags {@link ScriptFunctionData} flags
+ */
+- FinalScriptFunctionData(final String name, final int arity, final CompiledFunctions functions, final int flags) {
++ FinalScriptFunctionData(final String name, final int arity, final List<CompiledFunction> functions, final int flags) {
+ super(name, arity, flags);
+ code.addAll(functions);
++ assert !needsCallee();
+ }
+
+ /**
+@@ -57,33 +60,84 @@
+ * @param specs specializations
+ * @param flags {@link ScriptFunctionData} flags
+ */
+- FinalScriptFunctionData(final String name, final MethodHandle mh, final MethodHandle[] specs, final int flags) {
+- super(name, arity(mh), flags);
++ FinalScriptFunctionData(final String name, final MethodHandle mh, final Specialization[] specs, final int flags) {
++ super(name, methodHandleArity(mh), flags);
+
+ addInvoker(mh);
+ if (specs != null) {
+- for (final MethodHandle spec : specs) {
+- addInvoker(spec);
++ for (final Specialization spec : specs) {
++ addInvoker(spec.getMethodHandle(), spec);
+ }
+ }
+ }
+
+- private void addInvoker(final MethodHandle mh) {
++ @Override
++ boolean isRecompilable() {
++ return false;
++ }
++
++ @Override
++ protected boolean needsCallee() {
++ final boolean needsCallee = code.getFirst().needsCallee();
++ assert allNeedCallee(needsCallee);
++ return needsCallee;
++ }
++
++ private boolean allNeedCallee(final boolean needCallee) {
++ for (final CompiledFunction inv : code) {
++ if(inv.needsCallee() != needCallee) {
++ return false;
++ }
++ }
++ return true;
++ }
++
++ @Override
++ MethodType getGenericType() {
++ // We need to ask the code for its generic type. We can't just rely on this function data's arity, as it's not
++ // actually correct for lots of built-ins. E.g. ECMAScript 5.1 section 15.5.3.2 prescribes that
++ // Script.fromCharCode([char0[, char1[, ...]]]) has a declared arity of 1 even though it's a variable arity
++ // method.
++ int max = 0;
++ for(final CompiledFunction fn: code) {
++ final MethodType t = fn.type();
++ if(ScriptFunctionData.isVarArg(t)) {
++ // 2 for (callee, this, args[])
++ return MethodType.genericMethodType(2, true);
++ }
++ final int paramCount = t.parameterCount() - (ScriptFunctionData.needsCallee(t) ? 1 : 0);
++ if(paramCount > max) {
++ max = paramCount;
++ }
++ }
++ // +1 for callee
++ return MethodType.genericMethodType(max + 1);
++ }
++
++ private CompiledFunction addInvoker(final MethodHandle mh, final Specialization specialization) {
++ assert !needsCallee(mh);
++
++ final CompiledFunction invoker;
+ if (isConstructor(mh)) {
+ // only nasgen constructors: (boolean, self, args) are subject to binding a boolean newObj. isConstructor
+ // is too conservative a check. However, isConstructor(mh) always implies isConstructor param
+ assert isConstructor();
+- final MethodHandle invoker = MH.insertArguments(mh, 0, false);
+- final MethodHandle constructor = composeConstructor(MH.insertArguments(mh, 0, true));
+- code.add(new CompiledFunction(mh.type(), invoker, constructor));
++ invoker = CompiledFunction.createBuiltInConstructor(mh);
+ } else {
+- code.add(new CompiledFunction(mh.type(), mh));
++ invoker = new CompiledFunction(mh, null, specialization);
+ }
++ code.add(invoker);
++
++ return invoker;
+ }
+
+- private static int arity(final MethodHandle mh) {
++ private CompiledFunction addInvoker(final MethodHandle mh) {
++ return addInvoker(mh, null);
++ }
++
++ private static int methodHandleArity(final MethodHandle mh) {
+ if (isVarArg(mh)) {
+- return -1;
++ return MAX_ARITY;
+ }
+
+ //drop self, callee and boolean constructor flag to get real arity
+--- ./nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,9 +26,12 @@
+ package jdk.nashorn.internal.runtime;
+
+ import static jdk.nashorn.internal.lookup.Lookup.MH;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
+
+ import java.lang.invoke.MethodHandle;
++import jdk.internal.dynalink.linker.LinkRequest;
+ import jdk.nashorn.internal.codegen.ObjectClassGenerator;
++import jdk.nashorn.internal.objects.Global;
+
+ /**
+ * This class represents the result from a find property search.
+@@ -57,19 +60,43 @@
+ }
+
+ /**
++ * Return a copy of this FindProperty with a different property.
++ *
++ * @param newProperty the new property
++ * @return the new FindProperty instance
++ */
++ public FindProperty replaceProperty(final Property newProperty) {
++ assert this.property.getKey().equals(newProperty.getKey());
++ assert this.property.getSlot() == newProperty.getSlot();
++ return new FindProperty(self, prototype, newProperty);
++ }
++
++ /**
+ * Ask for a getter that returns the given type. The type has nothing to do with the
+ * internal representation of the property. It may be an Object (boxing primitives) or
+ * a primitive (primitive fields with -Dnashorn.fields.dual=true)
+ * @see ObjectClassGenerator
+ *
+ * @param type type of getter, e.g. int.class if we want a function with {@code get()I} signature
++ * @param programPoint program point, or INVALID_PROGRAM_POINT if pessimistic
++ * @param request link request
++ *
+ * @return method handle for the getter
+ */
+- public MethodHandle getGetter(final Class<?> type) {
+- MethodHandle getter = property.getGetter(type);
++ public MethodHandle getGetter(final Class<?> type, final int programPoint, final LinkRequest request) {
++ MethodHandle getter;
++ if (isValid(programPoint)) {
++ getter = property.getOptimisticGetter(type, programPoint);
++ } else {
++ getter = property.getGetter(type);
++ }
+ if (property instanceof UserAccessorProperty) {
+- final UserAccessorProperty uc = (UserAccessorProperty)property;
+- getter = MH.insertArguments(getter, 0, isInherited() ? getOwner() : null, uc.getGetterSlot());
++ getter = MH.insertArguments(getter, 1, UserAccessorProperty.getINVOKE_UA_GETTER(type, programPoint));
++ if (isValid(programPoint) && type.isPrimitive()) {
++ getter = MH.insertArguments(getter, 1, programPoint);
++ }
++ property.setType(type);
++ return insertAccessorsGetter((UserAccessorProperty) property, request, getter);
+ }
+ return getter;
+ }
+@@ -82,20 +109,36 @@
+ *
+ * @param type type of setter, e.g. int.class if we want a function with {@code set(I)V} signature
+ * @param strict are we in strict mode
++ * @param request link request
+ *
+ * @return method handle for the getter
+ */
+- public MethodHandle getSetter(final Class<?> type, final boolean strict) {
++ public MethodHandle getSetter(final Class<?> type, final boolean strict, final LinkRequest request) {
+ MethodHandle setter = property.getSetter(type, getOwner().getMap());
+ if (property instanceof UserAccessorProperty) {
+- final UserAccessorProperty uc = (UserAccessorProperty) property;
+- setter = MH.insertArguments(setter, 0, isInherited() ? getOwner() : null,
+- uc.getSetterSlot(), strict? property.getKey() : null);
++ setter = MH.insertArguments(setter, 1, UserAccessorProperty.getINVOKE_UA_SETTER(type), strict ? property.getKey() : null);
++ property.setType(type);
++ return insertAccessorsGetter((UserAccessorProperty) property, request, setter);
+ }
+
+ return setter;
+ }
+
++ // Fold an accessor getter into the method handle of a user accessor property.
++ private MethodHandle insertAccessorsGetter(final UserAccessorProperty uap, final LinkRequest request, final MethodHandle mh) {
++ MethodHandle superGetter = uap.getAccessorsGetter();
++ if (isInherited()) {
++ superGetter = ScriptObject.addProtoFilter(superGetter, getProtoChainLength());
++ }
++ if (request != null && !(request.getReceiver() instanceof ScriptObject)) {
++ final MethodHandle wrapFilter = Global.getPrimitiveWrapFilter(request.getReceiver());
++ superGetter = MH.filterArguments(superGetter, 0, wrapFilter.asType(wrapFilter.type().changeReturnType(superGetter.type().parameterType(0))));
++ }
++ superGetter = MH.asType(superGetter, superGetter.type().changeParameterType(0, Object.class));
++
++ return MH.foldArguments(mh, superGetter);
++ }
++
+ /**
+ * Return the {@code ScriptObject} owning of the property: this means the prototype.
+ * @return owner of property
+@@ -105,11 +148,22 @@
+ }
+
+ /**
++ * Return the {@code ScriptObject} where the search started. This is usually the ScriptObject the
++ * operation was started on, except for properties found inside a 'with' statement, where it is the
++ * top-level 'with' expression object.
++ *
++ * @return the start object.
++ */
++ public ScriptObject getSelf() {
++ return self;
++ }
++
++ /**
+ * Return the appropriate receiver for a getter.
+ * @return appropriate receiver
+ */
+ public ScriptObject getGetterReceiver() {
+- return property != null && property.hasGetterFunction(prototype) ? self : prototype;
++ return property != null && property instanceof UserAccessorProperty ? self : prototype;
+ }
+
+ /**
+@@ -155,7 +209,27 @@
+
+ /**
+ * Get the property value from self as object.
+- *
++ * @return the property value
++ */
++ public int getIntValue() {
++ return property.getIntValue(getGetterReceiver(), getOwner());
++ }
++ /**
++ * Get the property value from self as object.
++ * @return the property value
++ */
++ public long getLongValue() {
++ return property.getLongValue(getGetterReceiver(), getOwner());
++ }
++ /**
++ * Get the property value from self as object.
++ * @return the property value
++ */
++ public double getDoubleValue() {
++ return property.getDoubleValue(getGetterReceiver(), getOwner());
++ }
++ /**
++ * Get the property value from self as object.
+ * @return the property value
+ */
+ public Object getObjectValue() {
+@@ -168,8 +242,38 @@
+ * @param value the new value
+ * @param strict strict flag
+ */
+- public void setObjectValue(final Object value, final boolean strict) {
+- property.setObjectValue(getSetterReceiver(), getOwner(), value, strict);
++ public void setValue(final int value, final boolean strict) {
++ property.setValue(getSetterReceiver(), getOwner(), value, strict);
++ }
++
++ /**
++ * Set the property value in self.
++ *
++ * @param value the new value
++ * @param strict strict flag
++ */
++ public void setValue(final long value, final boolean strict) {
++ property.setValue(getSetterReceiver(), getOwner(), value, strict);
++ }
++
++ /**
++ * Set the property value in self.
++ *
++ * @param value the new value
++ * @param strict strict flag
++ */
++ public void setValue(final double value, final boolean strict) {
++ property.setValue(getSetterReceiver(), getOwner(), value, strict);
++ }
++
++ /**
++ * Set the property value in self.
++ *
++ * @param value the new value
++ * @param strict strict flag
++ */
++ public void setValue(final Object value, final boolean strict) {
++ property.setValue(getSetterReceiver(), getOwner(), value, strict);
+ }
+
+ /**
+@@ -187,5 +291,10 @@
+ return length;
+ }
+
++ @Override
++ public String toString() {
++ return "[FindProperty: " + property.getKey() + ']';
++ }
++
+ }
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/FunctionInitializer.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,160 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
++
++import java.io.IOException;
++import java.io.ObjectInputStream;
++import java.io.ObjectOutputStream;
++import java.io.Serializable;
++import java.lang.invoke.MethodType;
++import java.util.Map;
++import jdk.nashorn.internal.codegen.CompileUnit;
++import jdk.nashorn.internal.codegen.FunctionSignature;
++import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.ir.FunctionNode;
++
++/**
++ * Class that contains information allowing us to look up a method handle implementing a JavaScript function
++ * from a generated class. This is used both for code coming from codegen and for persistent serialized code.
++ */
++public final class FunctionInitializer implements Serializable {
++
++ private final String className;
++ private final MethodType methodType;
++ private final int flags;
++ private transient Map<Integer, Type> invalidatedProgramPoints;
++ private transient Class<?> code;
++
++ private static final long serialVersionUID = -5420835725902966692L;
++
++ /**
++ * Constructor.
++ *
++ * @param functionNode the function node
++ */
++ public FunctionInitializer(final FunctionNode functionNode) {
++ this(functionNode, null);
++ }
++
++ /**
++ * Copy constructor.
++ *
++ * @param init original initializer
++ */
++ FunctionInitializer(final FunctionInitializer init) {
++ this.className = init.getClassName();
++ this.methodType = init.getMethodType();
++ this.flags = init.getFlags();
++ }
++
++ /**
++ * Constructor.
++ *
++ * @param functionNode the function node
++ * @param invalidatedProgramPoints invalidated program points
++ */
++ public FunctionInitializer(final FunctionNode functionNode, final Map<Integer, Type> invalidatedProgramPoints) {
++ this.className = functionNode.getCompileUnit().getUnitClassName();
++ this.methodType = new FunctionSignature(functionNode).getMethodType();
++ this.flags = functionNode.getFlags();
++ this.invalidatedProgramPoints = invalidatedProgramPoints;
++
++ final CompileUnit cu = functionNode.getCompileUnit();
++ if (cu != null) {
++ this.code = cu.getCode();
++ }
++
++ assert className != null;
++ }
++
++ /**
++ * Returns the name of the class implementing the function.
++ *
++ * @return the class name
++ */
++ public String getClassName() {
++ return className;
++ }
++
++ /**
++ * Returns the type of the method implementing the function.
++ *
++ * @return the method type
++ */
++ public MethodType getMethodType() {
++ return methodType;
++ }
++
++ /**
++ * Returns the function flags.
++ *
++ * @return function flags
++ */
++ public int getFlags() {
++ return flags;
++ }
++
++ /**
++ * Returns the class implementing the function.
++ *
++ * @return the class
++ */
++ public Class<?> getCode() {
++ return code;
++ }
++
++ /**
++ * Set the class implementing the function
++ * @param code the class
++ */
++ public void setCode(final Class<?> code) {
++ // Make sure code has not been set and has expected class name
++ if (this.code != null) {
++ throw new IllegalStateException("code already set");
++ }
++ assert className.equals(code.getTypeName().replace('.', '/')) : "unexpected class name";
++ this.code = code;
++ }
++
++ /**
++ * Returns the map of invalidated program points.
++ *
++ * @return invalidated program points
++ */
++ public Map<Integer, Type> getInvalidatedProgramPoints() {
++ return invalidatedProgramPoints;
++ }
++
++ private void writeObject(final ObjectOutputStream out) throws IOException {
++ out.defaultWriteObject();
++ Type.writeTypeMap(invalidatedProgramPoints, out);
++ }
++
++ private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
++ in.defaultReadObject();
++ invalidatedProgramPoints = Type.readTypeMap(in);
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java Wed Feb 04 12:14:47 2015 -0800
+@@ -72,6 +72,19 @@
+ }
+
+ /**
++ * Constructor
++ *
++ * @param map property map
++ * @param primitiveSpill primitive spill pool
++ * @param objectSpill reference spill pool
++ */
++ public FunctionScope(final PropertyMap map, final long[] primitiveSpill, final Object[] objectSpill) {
++ super(map, primitiveSpill, objectSpill);
++ this.arguments = null;
++ }
++
++
++ /**
+ * Get the current split state.
+ * @return current split state
+ */
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/GlobalConstants.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,486 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
++
++import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
++import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCall;
++import static jdk.nashorn.internal.lookup.Lookup.MH;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.getProgramPoint;
++import static jdk.nashorn.internal.runtime.logging.DebugLogger.quote;
++
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.lang.invoke.SwitchPoint;
++import java.util.Arrays;
++import java.util.HashMap;
++import java.util.Map;
++import java.util.concurrent.atomic.AtomicBoolean;
++import java.util.logging.Level;
++import jdk.internal.dynalink.CallSiteDescriptor;
++import jdk.internal.dynalink.DynamicLinker;
++import jdk.internal.dynalink.linker.GuardedInvocation;
++import jdk.internal.dynalink.linker.LinkRequest;
++import jdk.nashorn.internal.lookup.Lookup;
++import jdk.nashorn.internal.lookup.MethodHandleFactory;
++import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
++
++/**
++ * Each context owns one of these. This is basically table of accessors
++ * for global properties. A global constant is evaluated to a MethodHandle.constant
++ * for faster access and to avoid walking to proto chain looking for it.
++ *
++ * We put a switchpoint on the global setter, which invalidates the
++ * method handle constant getters, and reverts to the standard access strategy
++ *
++ * However, there is a twist - while certain globals like "undefined" and "Math"
++ * are usually never reassigned, a global value can be reset once, and never again.
++ * This is a rather common pattern, like:
++ *
++ * x = function(something) { ...
++ *
++ * Thus everything registered as a global constant gets an extra chance. Set once,
++ * reregister the switchpoint. Set twice or more - don't try again forever, or we'd
++ * just end up relinking our way into megamorphisism.
++ *
++ * Also it has to be noted that this kind of linking creates a coupling between a Global
++ * and the call sites in compiled code belonging to the Context. For this reason, the
++ * linkage becomes incorrect as soon as the Context has more than one Global. The
++ * {@link #invalidateForever()} is invoked by the Context to invalidate all linkages and
++ * turn off the functionality of this object as soon as the Context's {@link Context#newGlobal()} is invoked
++ * for second time.
++ *
++ * We can extend this to ScriptObjects in general (GLOBAL_ONLY=false), which requires
++ * a receiver guard on the constant getter, but it currently leaks memory and its benefits
++ * have not yet been investigated property.
++ *
++ * As long as all Globals in a Context share the same GlobalConstants instance, we need synchronization
++ * whenever we access it.
++ */
++@Logger(name="const")
++public final class GlobalConstants implements Loggable {
++
++ /**
++ * Should we only try to link globals as constants, and not generic script objects.
++ * Script objects require a receiver guard, which is memory intensive, so this is currently
++ * disabled. We might implement a weak reference based approach to this later.
++ */
++ public static final boolean GLOBAL_ONLY = true;
++
++ private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
++
++ private static final MethodHandle INVALIDATE_SP = virtualCall(LOOKUP, GlobalConstants.class, "invalidateSwitchPoint", Object.class, Object.class, Access.class).methodHandle();
++ private static final MethodHandle RECEIVER_GUARD = staticCall(LOOKUP, GlobalConstants.class, "receiverGuard", boolean.class, Access.class, Object.class, Object.class).methodHandle();
++
++ /** Logger for constant getters */
++ private final DebugLogger log;
++
++ /**
++ * Access map for this global - associates a symbol name with an Access object, with getter
++ * and invalidation information
++ */
++ private final Map<String, Access> map = new HashMap<>();
++
++ private final AtomicBoolean invalidatedForever = new AtomicBoolean(false);
++
++ /**
++ * Constructor - used only by global
++ * @param log logger, or null if none
++ */
++ public GlobalConstants(final DebugLogger log) {
++ this.log = log == null ? DebugLogger.DISABLED_LOGGER : log;
++ }
++
++ @Override
++ public DebugLogger getLogger() {
++ return log;
++ }
++
++ @Override
++ public DebugLogger initLogger(final Context context) {
++ return DebugLogger.DISABLED_LOGGER;
++ }
++
++ /**
++ * Information about a constant access and its potential invalidations
++ */
++ private static class Access {
++ /** name of symbol */
++ private final String name;
++
++ /** switchpoint that invalidates the getters and setters for this access */
++ private SwitchPoint sp;
++
++ /** invalidation count for this access, i.e. how many times has this property been reset */
++ private int invalidations;
++
++ /** has a guard guarding this property getter failed? */
++ private boolean guardFailed;
++
++ private static final int MAX_RETRIES = 2;
++
++ private Access(final String name, final SwitchPoint sp) {
++ this.name = name;
++ this.sp = sp;
++ }
++
++ private boolean hasBeenInvalidated() {
++ return sp.hasBeenInvalidated();
++ }
++
++ private boolean guardFailed() {
++ return guardFailed;
++ }
++
++ private void failGuard() {
++ invalidateOnce();
++ guardFailed = true;
++ }
++
++ private void newSwitchPoint() {
++ assert hasBeenInvalidated();
++ sp = new SwitchPoint();
++ }
++
++ private void invalidate(final int count) {
++ if (!sp.hasBeenInvalidated()) {
++ SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
++ invalidations += count;
++ }
++ }
++
++ /**
++ * Invalidate the access, but do not contribute to the invalidation count
++ */
++ private void invalidateUncounted() {
++ invalidate(0);
++ }
++
++ /**
++ * Invalidate the access, and contribute 1 to the invalidation count
++ */
++ private void invalidateOnce() {
++ invalidate(1);
++ }
++
++ /**
++ * Invalidate the access and make sure that we never try to turn this into
++ * a MethodHandle.constant getter again
++ */
++ private void invalidateForever() {
++ invalidate(MAX_RETRIES);
++ }
++
++ /**
++ * Are we allowed to relink this as constant getter, even though it
++ * it has been reset
++ * @return true if we can relink as constant, one retry is allowed
++ */
++ private boolean mayRetry() {
++ return invalidations < MAX_RETRIES;
++ }
++
++ @Override
++ public String toString() {
++ return "[" + quote(name) + " <id=" + Debug.id(this) + "> inv#=" + invalidations + '/' + MAX_RETRIES + " sp_inv=" + sp.hasBeenInvalidated() + ']';
++ }
++
++ String getName() {
++ return name;
++ }
++
++ SwitchPoint getSwitchPoint() {
++ return sp;
++ }
++ }
++
++ /**
++ * To avoid an expensive global guard "is this the same global", similar to the
++ * receiver guard on the ScriptObject level, we invalidate all getters once
++ * when we switch globals. This is used from the class cache. We _can_ reuse
++ * the same class for a new global, but the builtins and global scoped variables
++ * will have changed.
++ */
++ public void invalidateAll() {
++ if (!invalidatedForever.get()) {
++ log.info("New global created - invalidating all constant callsites without increasing invocation count.");
++ synchronized (this) {
++ for (final Access acc : map.values()) {
++ acc.invalidateUncounted();
++ }
++ }
++ }
++ }
++
++ /**
++ * To avoid an expensive global guard "is this the same global", similar to the
++ * receiver guard on the ScriptObject level, we invalidate all getters when the
++ * second Global is created by the Context owning this instance. After this
++ * method is invoked, this GlobalConstants instance will both invalidate all the
++ * switch points it produced, and it will stop handing out new method handles
++ * altogether.
++ */
++ public void invalidateForever() {
++ if (invalidatedForever.compareAndSet(false, true)) {
++ log.info("New global created - invalidating all constant callsites.");
++ synchronized (this) {
++ for (final Access acc : map.values()) {
++ acc.invalidateForever();
++ }
++ map.clear();
++ }
++ }
++ }
++
++ /**
++ * Invalidate the switchpoint of an access - we have written to
++ * the property
++ *
++ * @param obj receiver
++ * @param acc access
++ *
++ * @return receiver, so this can be used as param filter
++ */
++ @SuppressWarnings("unused")
++ private synchronized Object invalidateSwitchPoint(final Object obj, final Access acc) {
++ if (log.isEnabled()) {
++ log.info("*** Invalidating switchpoint " + acc.getSwitchPoint() + " for receiver=" + obj + " access=" + acc);
++ }
++ acc.invalidateOnce();
++ if (acc.mayRetry()) {
++ if (log.isEnabled()) {
++ log.info("Retry is allowed for " + acc + "... Creating a new switchpoint.");
++ }
++ acc.newSwitchPoint();
++ } else {
++ if (log.isEnabled()) {
++ log.info("This was the last time I allowed " + quote(acc.getName()) + " to relink as constant.");
++ }
++ }
++ return obj;
++ }
++
++ private Access getOrCreateSwitchPoint(final String name) {
++ Access acc = map.get(name);
++ if (acc != null) {
++ return acc;
++ }
++ final SwitchPoint sp = new SwitchPoint();
++ map.put(name, acc = new Access(name, sp));
++ return acc;
++ }
++
++ /**
++ * Called from script object on property deletion to erase a property
++ * that might be linked as MethodHandle.constant and force relink
++ * @param name name of property
++ */
++ void delete(final String name) {
++ if (!invalidatedForever.get()) {
++ synchronized (this) {
++ final Access acc = map.get(name);
++ if (acc != null) {
++ acc.invalidateForever();
++ }
++ }
++ }
++ }
++
++ /**
++ * Receiver guard is used if we extend the global constants to script objects in general.
++ * As the property can have different values in different script objects, while Global is
++ * by definition a singleton, we need this for ScriptObject constants (currently disabled)
++ *
++ * TODO: Note - this seems to cause memory leaks. Use weak references? But what is leaking seems
++ * to be the Access objects, which isn't the case for Globals. Weird.
++ *
++ * @param acc access
++ * @param boundReceiver the receiver bound to the callsite
++ * @param receiver the receiver to check against
++ *
++ * @return true if this receiver is still the one we bound to the callsite
++ */
++ @SuppressWarnings("unused")
++ private static boolean receiverGuard(final Access acc, final Object boundReceiver, final Object receiver) {
++ final boolean id = receiver == boundReceiver;
++ if (!id) {
++ acc.failGuard();
++ }
++ return id;
++ }
++
++ private static boolean isGlobalSetter(final ScriptObject receiver, final FindProperty find) {
++ if (find == null) {
++ return receiver.isScope();
++ }
++ return find.getOwner().isGlobal();
++ }
++
++ /**
++ * Augment a setter with switchpoint for invalidating its getters, should the setter be called
++ *
++ * @param find property lookup
++ * @param inv normal guarded invocation for this setter, as computed by the ScriptObject linker
++ * @param desc callsite descriptor
++ * @param request link request
++ *
++ * @return null if failed to set up constant linkage
++ */
++ GuardedInvocation findSetMethod(final FindProperty find, final ScriptObject receiver, final GuardedInvocation inv, final CallSiteDescriptor desc, final LinkRequest request) {
++ if (invalidatedForever.get() || (GLOBAL_ONLY && !isGlobalSetter(receiver, find))) {
++ return null;
++ }
++
++ final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
++
++ synchronized (this) {
++ final Access acc = getOrCreateSwitchPoint(name);
++
++ if (log.isEnabled()) {
++ log.fine("Trying to link constant SETTER ", acc);
++ }
++
++ if (!acc.mayRetry() || invalidatedForever.get()) {
++ if (log.isEnabled()) {
++ log.fine("*** SET: Giving up on " + quote(name) + " - retry count has exceeded " + DynamicLinker.getLinkedCallSiteLocation());
++ }
++ return null;
++ }
++
++ if (acc.hasBeenInvalidated()) {
++ log.info("New chance for " + acc);
++ acc.newSwitchPoint();
++ }
++
++ assert !acc.hasBeenInvalidated();
++
++ // if we haven't given up on this symbol, add a switchpoint invalidation filter to the receiver parameter
++ final MethodHandle target = inv.getInvocation();
++ final Class<?> receiverType = target.type().parameterType(0);
++ final MethodHandle boundInvalidator = MH.bindTo(INVALIDATE_SP, this);
++ final MethodHandle invalidator = MH.asType(boundInvalidator, boundInvalidator.type().changeParameterType(0, receiverType).changeReturnType(receiverType));
++ final MethodHandle mh = MH.filterArguments(inv.getInvocation(), 0, MH.insertArguments(invalidator, 1, acc));
++
++ assert inv.getSwitchPoints() == null : Arrays.asList(inv.getSwitchPoints());
++ log.info("Linked setter " + quote(name) + " " + acc.getSwitchPoint());
++ return new GuardedInvocation(mh, inv.getGuard(), acc.getSwitchPoint(), inv.getException());
++ }
++ }
++
++ /**
++ * Try to reuse constant method handles for getters
++ * @param c constant value
++ * @return method handle (with dummy receiver) that returns this constant
++ */
++ public static MethodHandle staticConstantGetter(final Object c) {
++ return MH.dropArguments(JSType.unboxConstant(c), 0, Object.class);
++ }
++
++ private MethodHandle constantGetter(final Object c) {
++ final MethodHandle mh = staticConstantGetter(c);
++ if (log.isEnabled()) {
++ return MethodHandleFactory.addDebugPrintout(log, Level.FINEST, mh, "getting as constant");
++ }
++ return mh;
++ }
++
++ /**
++ * Try to turn a getter into a MethodHandle.constant, if possible
++ *
++ * @param find property lookup
++ * @param receiver receiver
++ * @param desc callsite descriptor
++ *
++ * @return resulting getter, or null if failed to create constant
++ */
++ GuardedInvocation findGetMethod(final FindProperty find, final ScriptObject receiver, final CallSiteDescriptor desc) {
++ // Only use constant getter for fast scope access, because the receiver may change between invocations
++ // for slow-scope and non-scope callsites.
++ // Also return null for user accessor properties as they may have side effects.
++ if (invalidatedForever.get() || !NashornCallSiteDescriptor.isFastScope(desc)
++ || (GLOBAL_ONLY && !find.getOwner().isGlobal())
++ || find.getProperty() instanceof UserAccessorProperty) {
++ return null;
++ }
++
++ final boolean isOptimistic = NashornCallSiteDescriptor.isOptimistic(desc);
++ final int programPoint = isOptimistic ? getProgramPoint(desc) : INVALID_PROGRAM_POINT;
++ final Class<?> retType = desc.getMethodType().returnType();
++ final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
++
++ synchronized (this) {
++ final Access acc = getOrCreateSwitchPoint(name);
++
++ log.fine("Starting to look up object value " + name);
++ final Object c = find.getObjectValue();
++
++ if (log.isEnabled()) {
++ log.fine("Trying to link constant GETTER " + acc + " value = " + c);
++ }
++
++ if (acc.hasBeenInvalidated() || acc.guardFailed() || invalidatedForever.get()) {
++ if (log.isEnabled()) {
++ log.info("*** GET: Giving up on " + quote(name) + " - retry count has exceeded " + DynamicLinker.getLinkedCallSiteLocation());
++ }
++ return null;
++ }
++
++ final MethodHandle cmh = constantGetter(c);
++
++ MethodHandle mh;
++ MethodHandle guard;
++
++ if (isOptimistic) {
++ if (JSType.getAccessorTypeIndex(cmh.type().returnType()) <= JSType.getAccessorTypeIndex(retType)) {
++ //widen return type - this is pessimistic, so it will always work
++ mh = MH.asType(cmh, cmh.type().changeReturnType(retType));
++ } else {
++ //immediately invalidate - we asked for a too wide constant as a narrower one
++ mh = MH.dropArguments(MH.insertArguments(JSType.THROW_UNWARRANTED.methodHandle(), 0, c, programPoint), 0, Object.class);
++ }
++ } else {
++ //pessimistic return type filter
++ mh = Lookup.filterReturnType(cmh, retType);
++ }
++
++ if (find.getOwner().isGlobal()) {
++ guard = null;
++ } else {
++ guard = MH.insertArguments(RECEIVER_GUARD, 0, acc, receiver);
++ }
++
++ if (log.isEnabled()) {
++ log.info("Linked getter " + quote(name) + " as MethodHandle.constant() -> " + c + " " + acc.getSwitchPoint());
++ mh = MethodHandleFactory.addDebugPrintout(log, Level.FINE, mh, "get const " + acc);
++ }
++
++ return new GuardedInvocation(mh, guard, acc.getSwitchPoint(), null);
++ }
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,7 +25,6 @@
+
+ package jdk.nashorn.internal.runtime;
+
+-import static jdk.nashorn.internal.runtime.JSType.digit;
+ import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+ import java.lang.invoke.MethodHandle;
+@@ -38,11 +37,35 @@
+ public final class GlobalFunctions {
+
+ /** Methodhandle to implementation of ECMA 15.1.2.2, parseInt */
+- public static final MethodHandle PARSEINT = findOwnMH("parseInt", double.class, Object.class, Object.class, Object.class);
++ public static final MethodHandle PARSEINT = findOwnMH("parseInt", double.class, Object.class, Object.class, Object.class);
++
++ /** Methodhandle (specialized) to implementation of ECMA 15.1.2.2, parseInt */
++ public static final MethodHandle PARSEINT_OI = findOwnMH("parseInt", double.class, Object.class, Object.class, int.class);
++
++ /** ParseInt - NaN for booleans (thru string conversion to number conversion) */
++ public static final MethodHandle PARSEINT_Z = MH.dropArguments(MH.dropArguments(MH.constant(double.class, Double.NaN), 0, boolean.class), 0, Object.class);
++
++ /** ParseInt - identity for ints */
++ public static final MethodHandle PARSEINT_I = MH.dropArguments(MH.identity(int.class), 0, Object.class);
++
++ /** ParseInt - identity for longs */
++ public static final MethodHandle PARSEINT_J = MH.dropArguments(MH.identity(long.class), 0, Object.class);
++
++ /** Methodhandle (specialized) to implementation of ECMA 15.1.2.2, parseInt */
++ public static final MethodHandle PARSEINT_O = findOwnMH("parseInt", double.class, Object.class, Object.class);
+
+ /** Methodhandle to implementation of ECMA 15.1.2.3, parseFloat */
+ public static final MethodHandle PARSEFLOAT = findOwnMH("parseFloat", double.class, Object.class, Object.class);
+
++ /** isNan for integers - always false */
++ public static final MethodHandle IS_NAN_I = MH.dropArguments(MH.constant(boolean.class, false), 0, Object.class);
++
++ /** isNan for longs - always false */
++ public static final MethodHandle IS_NAN_J = MH.dropArguments(MH.constant(boolean.class, false), 0, Object.class);
++
++ /** IsNan for doubles - use Double.isNaN */
++ public static final MethodHandle IS_NAN_D = MH.dropArguments(MH.findStatic(MethodHandles.lookup(), Double.class, "isNaN", MH.type(boolean.class, double.class)), 0, Object.class);
++
+ /** Methodhandle to implementation of ECMA 15.1.2.4, isNaN */
+ public static final MethodHandle IS_NAN = findOwnMH("isNaN", boolean.class, Object.class, Object.class);
+
+@@ -78,19 +101,44 @@
+ /**
+ * ECMA 15.1.2.2 parseInt implementation
+ *
+- * TODO: specialize
++ * @param self self reference
++ * @param string string to parse
++ * @param rad radix
++ *
++ * @return numeric type representing string contents as an int
++ */
++ public static double parseInt(final Object self, final Object string, final Object rad) {
++ return parseIntInternal(JSType.trimLeft(JSType.toString(string)), JSType.toInt32(rad));
++ }
++
++ /**
++ * ECMA 15.1.2.2 parseInt implementation specialized for int radix
+ *
+ * @param self self reference
+ * @param string string to parse
+ * @param rad radix
+ *
+- * @return numeric type representing string contents as an int (TODO: specialize for int case)
++ * @return numeric type representing string contents as an int
+ */
+- //TODO specialize
+- public static double parseInt(final Object self, final Object string, final Object rad) {
+- final String str = JSType.trimLeft(JSType.toString(string));
+- final int length = str.length();
+- int radix = JSType.toInt32(rad);
++ public static double parseInt(final Object self, final Object string, final int rad) {
++ return parseIntInternal(JSType.trimLeft(JSType.toString(string)), rad);
++ }
++
++ /**
++ * ECMA 15.1.2.2 parseInt implementation specialized for no radix argument
++ *
++ * @param self self reference
++ * @param string string to parse
++ *
++ * @return numeric type representing string contents as an int
++ */
++ public static double parseInt(final Object self, final Object string) {
++ return parseIntInternal(JSType.trimLeft(JSType.toString(string)), 0);
++ }
++
++ private static double parseIntInternal(final String str, final int rad) {
++ final int length = str.length();
++ int radix = rad;
+
+ // empty string is not valid
+ if (length == 0) {
+@@ -142,7 +190,7 @@
+ // we should see atleast one valid digit
+ boolean entered = false;
+ while (idx < length) {
+- digit = digit(str.charAt(idx++), radix, true);
++ digit = fastDigit(str.charAt(idx++), radix);
+ if (digit < 0) {
+ break;
+ }
+@@ -456,6 +504,20 @@
+ return ScriptRuntime.UNDEFINED;
+ }
+
++ private static int fastDigit(final int ch, final int radix) {
++ int n = -1;
++ if (ch >= '0' && ch <= '9') {
++ n = ch - '0';
++ } else if (radix > 10) {
++ if (ch >= 'a' && ch <= 'z') {
++ n = ch - 'a' + 10;
++ } else if (ch >= 'A' && ch <= 'Z') {
++ n = ch - 'A' + 10;
++ }
++ }
++ return n < radix ? n : -1;
++ }
++
+ private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+ return MH.findStatic(MethodHandles.lookup(), GlobalFunctions.class, name, MH.type(rtype, types));
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,8 @@
+
+ package jdk.nashorn.internal.runtime;
+
++import static jdk.nashorn.internal.runtime.Source.sourceFor;
++
+ import java.lang.invoke.MethodHandle;
+ import java.util.Iterator;
+ import java.util.concurrent.Callable;
+@@ -39,8 +41,6 @@
+ import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
+ import jdk.nashorn.internal.runtime.linker.Bootstrap;
+
+-import static jdk.nashorn.internal.runtime.Source.sourceFor;
+-
+ /**
+ * Utilities used by "JSON" object implementation.
+ */
+@@ -90,7 +90,7 @@
+ }
+
+ final Global global = Context.getGlobal();
+- Object unfiltered = convertNode(global, node);
++ final Object unfiltered = convertNode(global, node);
+ return applyReviver(global, unfiltered, reviver);
+ }
+
+@@ -122,7 +122,7 @@
+ if (newElement == ScriptRuntime.UNDEFINED) {
+ valueObj.delete(key, false);
+ } else {
+- setPropertyValue(valueObj, key, newElement, false);
++ setPropertyValue(valueObj, key, newElement);
+ }
+ }
+ }
+@@ -139,8 +139,6 @@
+
+ // Converts IR node to runtime value
+ private static Object convertNode(final Global global, final Node node) {
+- assert global instanceof Global;
+-
+ if (node instanceof LiteralNode) {
+ // check for array literal
+ if (node.tokenType() == TokenType.ARRAY) {
+@@ -181,28 +179,28 @@
+
+ final String name = pNode.getKeyName();
+ final Object value = convertNode(global, valueNode);
+- setPropertyValue(object, name, value, false);
++ setPropertyValue(object, name, value);
+ }
+
+ return object;
+ } else if (node instanceof UnaryNode) {
+ // UnaryNode used only to represent negative number JSON value
+ final UnaryNode unaryNode = (UnaryNode)node;
+- return -((LiteralNode<?>)unaryNode.rhs()).getNumber();
++ return -((LiteralNode<?>)unaryNode.getExpression()).getNumber();
+ } else {
+ return null;
+ }
+ }
+
+ // add a new property if does not exist already, or else set old property
+- private static void setPropertyValue(final ScriptObject sobj, final String name, final Object value, final boolean strict) {
++ private static void setPropertyValue(final ScriptObject sobj, final String name, final Object value) {
+ final int index = ArrayIndex.getArrayIndex(name);
+ if (ArrayIndex.isValidArrayIndex(index)) {
+ // array index key
+ sobj.defineOwnProperty(index, value);
+ } else if (sobj.getMap().findProperty(name) != null) {
+ // pre-existing non-inherited property, call set
+- sobj.set(name, value, strict);
++ sobj.set(name, value, 0);
+ } else {
+ // add new property
+ sobj.addOwnProperty(name, Property.WRITABLE_ENUMERABLE_CONFIGURABLE, value);
+--- ./nashorn/src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -45,12 +45,12 @@
+ }
+
+ @Override
+- protected Object getAt(int index) {
++ protected Object getAt(final int index) {
+ return ((JSObject)obj).getSlot(index);
+ }
+
+ @Override
+- protected void setAt(int index, Object element) {
++ protected void setAt(final int index, final Object element) {
+ ((JSObject)obj).setSlot(index, element);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/JSType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/JSType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,16 +26,20 @@
+ package jdk.nashorn.internal.runtime;
+
+ import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
++import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
++import static jdk.nashorn.internal.lookup.Lookup.MH;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+-
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+ import java.lang.reflect.Array;
++import java.util.Arrays;
++import java.util.Collections;
+ import java.util.Deque;
+ import java.util.List;
+ import jdk.internal.dynalink.beans.StaticClass;
+ import jdk.nashorn.api.scripting.JSObject;
+ import jdk.nashorn.internal.codegen.CompilerConstants.Call;
++import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.objects.Global;
+ import jdk.nashorn.internal.parser.Lexer;
+ import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
+@@ -72,58 +76,199 @@
+ /** Max value for an uint32 in JavaScript */
+ public static final long MAX_UINT = 0xFFFF_FFFFL;
+
+- private static final MethodHandles.Lookup myLookup = MethodHandles.lookup();
++ private static final MethodHandles.Lookup JSTYPE_LOOKUP = MethodHandles.lookup();
+
+ /** JavaScript compliant conversion function from Object to boolean */
+- public static final Call TO_BOOLEAN = staticCall(myLookup, JSType.class, "toBoolean", boolean.class, Object.class);
++ public static final Call TO_BOOLEAN = staticCall(JSTYPE_LOOKUP, JSType.class, "toBoolean", boolean.class, Object.class);
+
+ /** JavaScript compliant conversion function from number to boolean */
+- public static final Call TO_BOOLEAN_D = staticCall(myLookup, JSType.class, "toBoolean", boolean.class, double.class);
++ public static final Call TO_BOOLEAN_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toBoolean", boolean.class, double.class);
+
+ /** JavaScript compliant conversion function from Object to integer */
+- public static final Call TO_INTEGER = staticCall(myLookup, JSType.class, "toInteger", int.class, Object.class);
++ public static final Call TO_INTEGER = staticCall(JSTYPE_LOOKUP, JSType.class, "toInteger", int.class, Object.class);
+
+ /** JavaScript compliant conversion function from Object to long */
+- public static final Call TO_LONG = staticCall(myLookup, JSType.class, "toLong", long.class, Object.class);
++ public static final Call TO_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "toLong", long.class, Object.class);
++
++ /** JavaScript compliant conversion function from double to long */
++ public static final Call TO_LONG_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toLong", long.class, double.class);
+
+ /** JavaScript compliant conversion function from Object to number */
+- public static final Call TO_NUMBER = staticCall(myLookup, JSType.class, "toNumber", double.class, Object.class);
++ public static final Call TO_NUMBER = staticCall(JSTYPE_LOOKUP, JSType.class, "toNumber", double.class, Object.class);
++
++ /** JavaScript compliant conversion function from Object to number with type check */
++ public static final Call TO_NUMBER_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toNumberOptimistic", double.class, Object.class, int.class);
+
+ /** JavaScript compliant conversion function from Object to String */
+- public static final Call TO_STRING = staticCall(myLookup, JSType.class, "toString", String.class, Object.class);
++ public static final Call TO_STRING = staticCall(JSTYPE_LOOKUP, JSType.class, "toString", String.class, Object.class);
+
+ /** JavaScript compliant conversion function from Object to int32 */
+- public static final Call TO_INT32 = staticCall(myLookup, JSType.class, "toInt32", int.class, Object.class);
++ public static final Call TO_INT32 = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32", int.class, Object.class);
++
++ /** JavaScript compliant conversion function from Object to int32 */
++ public static final Call TO_INT32_L = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32", int.class, long.class);
++
++ /** JavaScript compliant conversion function from Object to int32 with type check */
++ public static final Call TO_INT32_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32Optimistic", int.class, Object.class, int.class);
+
+ /** JavaScript compliant conversion function from double to int32 */
+- public static final Call TO_INT32_D = staticCall(myLookup, JSType.class, "toInt32", int.class, double.class);
++ public static final Call TO_INT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32", int.class, double.class);
++
++ /** JavaScript compliant conversion function from int to uint32 */
++ public static final Call TO_UINT32_I = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, int.class);
+
+ /** JavaScript compliant conversion function from Object to uint32 */
+- public static final Call TO_UINT32 = staticCall(myLookup, JSType.class, "toUint32", long.class, Object.class);
++ public static final Call TO_UINT32 = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, Object.class);
++
++ /** JavaScript compliant conversion function from Object to long with type check */
++ public static final Call TO_LONG_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toLongOptimistic", long.class, Object.class, int.class);
+
+ /** JavaScript compliant conversion function from number to uint32 */
+- public static final Call TO_UINT32_D = staticCall(myLookup, JSType.class, "toUint32", long.class, double.class);
+-
+- /** JavaScript compliant conversion function from Object to int64 */
+- public static final Call TO_INT64 = staticCall(myLookup, JSType.class, "toInt64", long.class, Object.class);
+-
+- /** JavaScript compliant conversion function from number to int64 */
+- public static final Call TO_INT64_D = staticCall(myLookup, JSType.class, "toInt64", long.class, double.class);
++ public static final Call TO_UINT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, double.class);
+
+ /** JavaScript compliant conversion function from number to String */
+- public static final Call TO_STRING_D = staticCall(myLookup, JSType.class, "toString", String.class, double.class);
++ public static final Call TO_STRING_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toString", String.class, double.class);
+
+ /** Combined call to toPrimitive followed by toString. */
+- public static final Call TO_PRIMITIVE_TO_STRING = staticCall(myLookup, JSType.class, "toPrimitiveToString", String.class, Object.class);
++ public static final Call TO_PRIMITIVE_TO_STRING = staticCall(JSTYPE_LOOKUP, JSType.class, "toPrimitiveToString", String.class, Object.class);
++
++ /** Combined call to toPrimitive followed by toCharSequence. */
++ public static final Call TO_PRIMITIVE_TO_CHARSEQUENCE = staticCall(JSTYPE_LOOKUP, JSType.class, "toPrimitiveToCharSequence", CharSequence.class, Object.class);
++
++ /** Throw an unwarranted optimism exception */
++ public static final Call THROW_UNWARRANTED = staticCall(JSTYPE_LOOKUP, JSType.class, "throwUnwarrantedOptimismException", Object.class, Object.class, int.class);
++
++ /** Add exact wrapper for potentially overflowing integer operations */
++ public static final Call ADD_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "addExact", int.class, int.class, int.class, int.class);
++
++ /** Sub exact wrapper for potentially overflowing integer operations */
++ public static final Call SUB_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "subExact", int.class, int.class, int.class, int.class);
++
++ /** Multiply exact wrapper for potentially overflowing integer operations */
++ public static final Call MUL_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "mulExact", int.class, int.class, int.class, int.class);
++
++ /** Div exact wrapper for potentially integer division that turns into float point */
++ public static final Call DIV_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "divExact", int.class, int.class, int.class, int.class);
++
++ /** Div zero wrapper for integer division that handles (0/0)|0 == 0 */
++ public static final Call DIV_ZERO = staticCall(JSTYPE_LOOKUP, JSType.class, "divZero", int.class, int.class, int.class);
++
++ /** Mod zero wrapper for integer division that handles (0%0)|0 == 0 */
++ public static final Call REM_ZERO = staticCall(JSTYPE_LOOKUP, JSType.class, "remZero", int.class, int.class, int.class);
++
++ /** Mod exact wrapper for potentially integer remainders that turns into float point */
++ public static final Call REM_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "remExact", int.class, int.class, int.class, int.class);
++
++ /** Decrement exact wrapper for potentially overflowing integer operations */
++ public static final Call DECREMENT_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "decrementExact", int.class, int.class, int.class);
++
++ /** Increment exact wrapper for potentially overflowing integer operations */
++ public static final Call INCREMENT_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "incrementExact", int.class, int.class, int.class);
++
++ /** Negate exact exact wrapper for potentially overflowing integer operations */
++ public static final Call NEGATE_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "negateExact", int.class, int.class, int.class);
++
++ /** Add exact wrapper for potentially overflowing long operations */
++ public static final Call ADD_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "addExact", long.class, long.class, long.class, int.class);
++
++ /** Sub exact wrapper for potentially overflowing long operations */
++ public static final Call SUB_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "subExact", long.class, long.class, long.class, int.class);
++
++ /** Multiply exact wrapper for potentially overflowing long operations */
++ public static final Call MUL_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "mulExact", long.class, long.class, long.class, int.class);
++
++ /** Div exact wrapper for potentially integer division that turns into float point */
++ public static final Call DIV_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "divExact", long.class, long.class, long.class, int.class);
++
++ /** Div zero wrapper for long division that handles (0/0) >>> 0 == 0 */
++ public static final Call DIV_ZERO_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "divZero", long.class, long.class, long.class);
++
++ /** Mod zero wrapper for long division that handles (0%0) >>> 0 == 0 */
++ public static final Call REM_ZERO_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "remZero", long.class, long.class, long.class);
++
++ /** Mod exact wrapper for potentially integer remainders that turns into float point */
++ public static final Call REM_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "remExact", long.class, long.class, long.class, int.class);
++
++ /** Decrement exact wrapper for potentially overflowing long operations */
++ public static final Call DECREMENT_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "decrementExact", long.class, long.class, int.class);
++
++ /** Increment exact wrapper for potentially overflowing long operations */
++ public static final Call INCREMENT_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "incrementExact", long.class, long.class, int.class);
++
++ /** Negate exact exact wrapper for potentially overflowing long operations */
++ public static final Call NEGATE_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "negateExact", long.class, long.class, int.class);
+
+ /** Method handle to convert a JS Object to a Java array. */
+- public static final Call TO_JAVA_ARRAY = staticCall(myLookup, JSType.class, "toJavaArray", Object.class, Object.class, Class.class);
++ public static final Call TO_JAVA_ARRAY = staticCall(JSTYPE_LOOKUP, JSType.class, "toJavaArray", Object.class, Object.class, Class.class);
+
+ /** Method handle to convert a JS Object to a Java List. */
+- public static final Call TO_JAVA_LIST = staticCall(myLookup, JSType.class, "toJavaList", List.class, Object.class);
++ public static final Call TO_JAVA_LIST = staticCall(JSTYPE_LOOKUP, JSType.class, "toJavaList", List.class, Object.class);
+
+ /** Method handle to convert a JS Object to a Java deque. */
+- public static final Call TO_JAVA_DEQUE = staticCall(myLookup, JSType.class, "toJavaDeque", Deque.class, Object.class);
++ public static final Call TO_JAVA_DEQUE = staticCall(JSTYPE_LOOKUP, JSType.class, "toJavaDeque", Deque.class, Object.class);
++
++ /** Method handle for void returns. */
++ public static final Call VOID_RETURN = staticCall(JSTYPE_LOOKUP, JSType.class, "voidReturn", void.class);
++
++
++ /**
++ * The list of available accessor types in width order. This order is used for type guesses narrow{@literal ->} wide
++ * in the dual--fields world
++ */
++ private static final List<Type> ACCESSOR_TYPES = Collections.unmodifiableList(
++ Arrays.asList(
++ Type.INT,
++ Type.LONG,
++ Type.NUMBER,
++ Type.OBJECT));
++
++ /** table index for undefined type - hard coded so it can be used in switches at compile time */
++ public static final int TYPE_UNDEFINED_INDEX = -1;
++ /** table index for integer type - hard coded so it can be used in switches at compile time */
++ public static final int TYPE_INT_INDEX = 0; //getAccessorTypeIndex(int.class);
++ /** table index for long type - hard coded so it can be used in switches at compile time */
++ public static final int TYPE_LONG_INDEX = 1; //getAccessorTypeIndex(long.class);
++ /** table index for double type - hard coded so it can be used in switches at compile time */
++ public static final int TYPE_DOUBLE_INDEX = 2; //getAccessorTypeIndex(double.class);
++ /** table index for object type - hard coded so it can be used in switches at compile time */
++ public static final int TYPE_OBJECT_INDEX = 3; //getAccessorTypeIndex(Object.class);
++
++ /** object conversion quickies with JS semantics - used for return value and parameter filter */
++ public static final List<MethodHandle> CONVERT_OBJECT = toUnmodifiableList(
++ JSType.TO_INT32.methodHandle(),
++ JSType.TO_UINT32.methodHandle(),
++ JSType.TO_NUMBER.methodHandle(),
++ null
++ );
++
++ /**
++ * object conversion quickies with JS semantics - used for return value and parameter filter, optimistic
++ * throws exception upon incompatible type (asking for a narrower one than the storage)
++ */
++ public static final List<MethodHandle> CONVERT_OBJECT_OPTIMISTIC = toUnmodifiableList(
++ JSType.TO_INT32_OPTIMISTIC.methodHandle(),
++ JSType.TO_LONG_OPTIMISTIC.methodHandle(),
++ JSType.TO_NUMBER_OPTIMISTIC.methodHandle(),
++ null
++ );
++
++ /** The value of Undefined cast to an int32 */
++ public static final int UNDEFINED_INT = 0;
++ /** The value of Undefined cast to a long */
++ public static final long UNDEFINED_LONG = 0L;
++ /** The value of Undefined cast to a double */
++ public static final double UNDEFINED_DOUBLE = Double.NaN;
++
++ /**
++ * Method handles for getters that return undefined coerced
++ * to the appropriate type
++ */
++ public static final List<MethodHandle> GET_UNDEFINED = toUnmodifiableList(
++ MH.constant(int.class, UNDEFINED_INT),
++ MH.constant(long.class, UNDEFINED_LONG),
++ MH.constant(double.class, UNDEFINED_DOUBLE),
++ MH.constant(Object.class, Undefined.getUndefined())
++ );
+
+ private static final double INT32_LIMIT = 4294967296.0;
+
+@@ -159,7 +304,7 @@
+ }
+
+ if (obj instanceof ScriptObject) {
+- return (obj instanceof ScriptFunction) ? JSType.FUNCTION : JSType.OBJECT;
++ return obj instanceof ScriptFunction ? JSType.FUNCTION : JSType.OBJECT;
+ }
+
+ if (obj instanceof Boolean) {
+@@ -182,6 +327,52 @@
+ }
+
+ /**
++ * Similar to {@link #of(Object)}, but does not distinguish between {@link #FUNCTION} and {@link #OBJECT}, returning
++ * {@link #OBJECT} in both cases. The distinction is costly, and the EQ and STRICT_EQ predicates don't care about it
++ * so we maintain this version for their use.
++ *
++ * @param obj an object
++ *
++ * @return the JSType for the object; returns {@link #OBJECT} instead of {@link #FUNCTION} for functions.
++ */
++ public static JSType ofNoFunction(final Object obj) {
++ // Order of these statements is tuned for performance (see JDK-8024476)
++ if (obj == null) {
++ return JSType.NULL;
++ }
++
++ if (obj instanceof ScriptObject) {
++ return JSType.OBJECT;
++ }
++
++ if (obj instanceof Boolean) {
++ return JSType.BOOLEAN;
++ }
++
++ if (obj instanceof String || obj instanceof ConsString) {
++ return JSType.STRING;
++ }
++
++ if (obj instanceof Number) {
++ return JSType.NUMBER;
++ }
++
++ if (obj == ScriptRuntime.UNDEFINED) {
++ return JSType.UNDEFINED;
++ }
++
++ return JSType.OBJECT;
++ }
++
++ /**
++ * Void return method handle glue
++ */
++ public static void voidReturn() {
++ //empty
++ //TODO: fix up SetMethodCreator better so we don't need this stupid thing
++ }
++
++ /**
+ * Returns true if double number can be represented as an int
+ *
+ * @param number a long to inspect
+@@ -193,7 +384,8 @@
+ }
+
+ /**
+- * Returns true if double number can be represented as an int
++ * Returns true if double number can be represented as an int. Note that it returns true for negative zero. If you
++ * need to exclude negative zero, combine this check with {@link #isNegativeZero(double)}.
+ *
+ * @param number a double to inspect
+ *
+@@ -204,7 +396,22 @@
+ }
+
+ /**
+- * Returns true if double number can be represented as a long
++ * Returns true if Object can be represented as an int
++ *
++ * @param obj an object to inspect
++ *
++ * @return true for int representable objects
++ */
++ public static boolean isRepresentableAsInt(final Object obj) {
++ if (obj instanceof Number) {
++ return isRepresentableAsInt(((Number)obj).doubleValue());
++ }
++ return false;
++ }
++
++ /**
++ * Returns true if double number can be represented as a long. Note that it returns true for negative zero. If you
++ * need to exclude negative zero, combine this check with {@link #isNegativeZero(double)}.
+ *
+ * @param number a double to inspect
+ * @return true for long representable doubles
+@@ -214,13 +421,36 @@
+ }
+
+ /**
++ * Returns true if Object can be represented as a long
++ *
++ * @param obj an object to inspect
++ *
++ * @return true for long representable objects
++ */
++ public static boolean isRepresentableAsLong(final Object obj) {
++ if (obj instanceof Number) {
++ return isRepresentableAsLong(((Number)obj).doubleValue());
++ }
++ return false;
++ }
++
++ /**
++ * Returns true if the number is the negative zero ({@code -0.0d}).
++ * @param number the number to test
++ * @return true if it is the negative zero, false otherwise.
++ */
++ public static boolean isNegativeZero(final double number) {
++ return number == 0.0d && Double.doubleToRawLongBits(number) == 0x8000000000000000L;
++ }
++
++ /**
+ * Check whether an object is primitive
+ *
+ * @param obj an object
+ *
+ * @return true if object is primitive (includes null and undefined)
+ */
+- public static boolean isPrimitive(final Object obj) {
++ public static boolean isPrimitive(final Object obj) {
+ return obj == null ||
+ obj == ScriptRuntime.UNDEFINED ||
+ obj instanceof Boolean ||
+@@ -270,11 +500,21 @@
+ *
+ * @return the string form of the primitive form of the object
+ */
+- public static String toPrimitiveToString(Object obj) {
++ public static String toPrimitiveToString(final Object obj) {
+ return toString(toPrimitive(obj));
+ }
+
+ /**
++ * Like {@link #toPrimitiveToString(Object)}, but avoids conversion of ConsString to String.
++ *
++ * @param obj an object
++ * @return the CharSequence form of the primitive form of the object
++ */
++ public static CharSequence toPrimitiveToCharSequence(final Object obj) {
++ return toCharSequence(toPrimitive(obj));
++ }
++
++ /**
+ * JavaScript compliant conversion of number to boolean
+ *
+ * @param num a number
+@@ -474,6 +714,9 @@
+ * @return a number
+ */
+ public static double toNumber(final Object obj) {
++ if (obj instanceof Double) {
++ return (Double)obj;
++ }
+ if (obj instanceof Number) {
+ return ((Number)obj).doubleValue();
+ }
+@@ -494,6 +737,35 @@
+ }
+
+ /**
++ * Optimistic number conversion - throws UnwarrantedOptimismException if Object
++ *
++ * @param obj object to convert
++ * @param programPoint program point
++ * @return double
++ */
++ public static double toNumberOptimistic(final Object obj, final int programPoint) {
++ if (obj != null) {
++ final Class<?> clz = obj.getClass();
++ if (clz == Double.class || clz == Integer.class || clz == Long.class) {
++ return ((Number)obj).doubleValue();
++ }
++ }
++ throw new UnwarrantedOptimismException(obj, programPoint);
++ }
++
++ /**
++ * Object to number conversion that delegates to either {@link #toNumber(Object)} or to
++ * {@link #toNumberOptimistic(Object, int)} depending on whether the program point is valid or not.
++ * @param obj the object to convert
++ * @param programPoint the program point; can be invalid.
++ * @return the value converted to a number
++ * @throws UnwarrantedOptimismException if the value can't be represented as a number and the program point is valid.
++ */
++ public static double toNumberMaybeOptimistic(final Object obj, final int programPoint) {
++ return UnwarrantedOptimismException.isValid(programPoint) ? toNumberOptimistic(obj, programPoint) : toNumber(obj);
++ }
++
++ /**
+ * Digit representation for a character
+ *
+ * @param ch a character
+@@ -612,7 +884,7 @@
+ }
+
+ /**
+- * JavaScript compliant Object to long conversion. See ECMA 9.4 ToInteger
++ * Converts an Object to long.
+ *
+ * <p>Note that this returns {@link java.lang.Long#MAX_VALUE} or {@link java.lang.Long#MIN_VALUE}
+ * for double values that exceed the long range, including positive and negative Infinity. It is the
+@@ -622,7 +894,46 @@
+ * @return a long
+ */
+ public static long toLong(final Object obj) {
+- return (long)toNumber(obj);
++ return obj instanceof Long ? ((Long)obj).longValue() : toLong(toNumber(obj));
++ }
++
++ /**
++ * Converts a double to long.
++ *
++ * @param num the double to convert
++ * @return the converted long value
++ */
++ public static long toLong(final double num) {
++ return (long)num;
++ }
++
++ /**
++ * Optimistic long conversion - throws UnwarrantedOptimismException if double or Object
++ *
++ * @param obj object to convert
++ * @param programPoint program point
++ * @return long
++ */
++ public static long toLongOptimistic(final Object obj, final int programPoint) {
++ if (obj != null) {
++ final Class<?> clz = obj.getClass();
++ if (clz == Long.class || clz == Integer.class) {
++ return ((Number)obj).longValue();
++ }
++ }
++ throw new UnwarrantedOptimismException(obj, programPoint);
++ }
++
++ /**
++ * Object to int conversion that delegates to either {@link #toLong(Object)} or to
++ * {@link #toLongOptimistic(Object, int)} depending on whether the program point is valid or not.
++ * @param obj the object to convert
++ * @param programPoint the program point; can be invalid.
++ * @return the value converted to long
++ * @throws UnwarrantedOptimismException if the value can't be represented as long and the program point is valid.
++ */
++ public static long toLongMaybeOptimistic(final Object obj, final int programPoint) {
++ return UnwarrantedOptimismException.isValid(programPoint) ? toLongOptimistic(obj, programPoint) : toLong(obj);
+ }
+
+ /**
+@@ -637,15 +948,46 @@
+ }
+
+ /**
++ * Optimistic int conversion - throws UnwarrantedOptimismException if double, long or Object
++ *
++ * @param obj object to convert
++ * @param programPoint program point
++ * @return double
++ */
++ public static int toInt32Optimistic(final Object obj, final int programPoint) {
++ if (obj != null && obj.getClass() == Integer.class) {
++ return ((Integer)obj).intValue();
++ }
++ throw new UnwarrantedOptimismException(obj, programPoint);
++ }
++
++ /**
++ * Object to int conversion that delegates to either {@link #toInt32(Object)} or to
++ * {@link #toInt32Optimistic(Object, int)} depending on whether the program point is valid or not.
++ * @param obj the object to convert
++ * @param programPoint the program point; can be invalid.
++ * @return the value converted to int
++ * @throws UnwarrantedOptimismException if the value can't be represented as int and the program point is valid.
++ */
++ public static int toInt32MaybeOptimistic(final Object obj, final int programPoint) {
++ return UnwarrantedOptimismException.isValid(programPoint) ? toInt32Optimistic(obj, programPoint) : toInt32(obj);
++ }
++
++ // Minimum and maximum range between which every long value can be precisely represented as a double.
++ private static final long MAX_PRECISE_DOUBLE = 1L << 53;
++ private static final long MIN_PRECISE_DOUBLE = -MAX_PRECISE_DOUBLE;
++
++ /**
+ * JavaScript compliant long to int32 conversion
+ *
+ * @param num a long
+ * @return an int32
+ */
+ public static int toInt32(final long num) {
+- return (int)num;
++ return (int)(num >= MIN_PRECISE_DOUBLE && num <= MAX_PRECISE_DOUBLE ? num : (long)(num % INT32_LIMIT));
+ }
+
++
+ /**
+ * JavaScript compliant number to int32 conversion
+ *
+@@ -657,29 +999,6 @@
+ }
+
+ /**
+- * JavaScript compliant Object to int64 conversion
+- *
+- * @param obj an object
+- * @return an int64
+- */
+- public static long toInt64(final Object obj) {
+- return toInt64(toNumber(obj));
+- }
+-
+- /**
+- * JavaScript compliant number to int64 conversion
+- *
+- * @param num a number
+- * @return an int64
+- */
+- public static long toInt64(final double num) {
+- if (Double.isInfinite(num)) {
+- return 0L;
+- }
+- return (long)num;
+- }
+-
+- /**
+ * JavaScript compliant Object to uint32 conversion
+ *
+ * @param obj an object
+@@ -700,6 +1019,16 @@
+ }
+
+ /**
++ * JavaScript compliant int to uint32 conversion
++ *
++ * @param num an int
++ * @return a uint32
++ */
++ public static long toUint32(final int num) {
++ return num & MAX_UINT;
++ }
++
++ /**
+ * JavaScript compliant Object to uint16 conversion
+ * ECMA 9.7 ToUint16: (Unsigned 16 Bit Integer)
+ *
+@@ -727,7 +1056,7 @@
+ * @return a uint16
+ */
+ public static int toUint16(final long num) {
+- return ((int)num) & 0xffff;
++ return (int)num & 0xffff;
+ }
+
+ /**
+@@ -737,7 +1066,7 @@
+ * @return a uint16
+ */
+ public static int toUint16(final double num) {
+- return ((int)doubleToInt32(num)) & 0xffff;
++ return (int)doubleToInt32(num) & 0xffff;
+ }
+
+ private static long doubleToInt32(final double num) {
+@@ -751,7 +1080,7 @@
+ return 0;
+ }
+ // This is rather slow and could probably be sped up using bit-fiddling.
+- final double d = (num >= 0) ? Math.floor(num) : Math.ceil(num);
++ final double d = num >= 0 ? Math.floor(num) : Math.ceil(num);
+ return (long)(d % INT32_LIMIT);
+ }
+
+@@ -1014,6 +1343,448 @@
+ return str.substring(start);
+ }
+
++ /**
++ * Throw an unwarranted optimism exception for a program point
++ * @param value real return value
++ * @param programPoint program point
++ * @return
++ */
++ @SuppressWarnings("unused")
++ private static Object throwUnwarrantedOptimismException(final Object value, final int programPoint) {
++ throw new UnwarrantedOptimismException(value, programPoint);
++ }
++
++ /**
++ * Wrapper for addExact
++ *
++ * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
++ * containing the result and the program point of the failure
++ *
++ * @param x first term
++ * @param y second term
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if overflow occurs
++ */
++ public static int addExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
++ try {
++ return Math.addExact(x, y);
++ } catch (final ArithmeticException e) {
++ throw new UnwarrantedOptimismException((long)x + (long)y, programPoint);
++ }
++ }
++
++ /**
++ * Wrapper for addExact
++ *
++ * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
++ * containing the result and the program point of the failure
++ *
++ * @param x first term
++ * @param y second term
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if overflow occurs
++ */
++ public static long addExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
++ try {
++ return Math.addExact(x, y);
++ } catch (final ArithmeticException e) {
++ throw new UnwarrantedOptimismException((double)x + (double)y, programPoint);
++ }
++ }
++
++ /**
++ * Wrapper for subExact
++ *
++ * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
++ * containing the result and the program point of the failure
++ *
++ * @param x first term
++ * @param y second term
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if overflow occurs
++ */
++ public static int subExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
++ try {
++ return Math.subtractExact(x, y);
++ } catch (final ArithmeticException e) {
++ throw new UnwarrantedOptimismException((long)x - (long)y, programPoint);
++ }
++ }
++
++ /**
++ * Wrapper for subExact
++ *
++ * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
++ * containing the result and the program point of the failure
++ *
++ * @param x first term
++ * @param y second term
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if overflow occurs
++ */
++ public static long subExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
++ try {
++ return Math.subtractExact(x, y);
++ } catch (final ArithmeticException e) {
++ throw new UnwarrantedOptimismException((double)x - (double)y, programPoint);
++ }
++ }
++
++ /**
++ * Wrapper for mulExact
++ *
++ * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
++ * containing the result and the program point of the failure
++ *
++ * @param x first term
++ * @param y second term
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if overflow occurs
++ */
++ public static int mulExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
++ try {
++ return Math.multiplyExact(x, y);
++ } catch (final ArithmeticException e) {
++ throw new UnwarrantedOptimismException((long)x * (long)y, programPoint);
++ }
++ }
++
++ /**
++ * Wrapper for mulExact
++ *
++ * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
++ * containing the result and the program point of the failure
++ *
++ * @param x first term
++ * @param y second term
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if overflow occurs
++ */
++ public static long mulExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
++ try {
++ return Math.multiplyExact(x, y);
++ } catch (final ArithmeticException e) {
++ throw new UnwarrantedOptimismException((double)x * (double)y, programPoint);
++ }
++ }
++
++ /**
++ * Wrapper for divExact. Throws UnwarrantedOptimismException if the result of the division can't be represented as
++ * int.
++ *
++ * @param x first term
++ * @param y second term
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if the result of the division can't be represented as int.
++ */
++ public static int divExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
++ final int res;
++ try {
++ res = x / y;
++ } catch (final ArithmeticException e) {
++ assert y == 0; // Only div by zero anticipated
++ throw new UnwarrantedOptimismException(x > 0 ? Double.POSITIVE_INFINITY : x < 0 ? Double.NEGATIVE_INFINITY : Double.NaN, programPoint);
++ }
++ final int rem = x % y;
++ if (rem == 0) {
++ return res;
++ }
++ // go directly to double here, as anything with non zero remainder is a floating point number in JavaScript
++ throw new UnwarrantedOptimismException((double)x / (double)y, programPoint);
++ }
++
++ /**
++ * Implements int division but allows {@code x / 0} to be represented as 0. Basically equivalent to
++ * {@code (x / y)|0} JavaScript expression (division of two ints coerced to int).
++ * @param x the dividend
++ * @param y the divisor
++ * @return the result
++ */
++ public static int divZero(final int x, final int y) {
++ return y == 0 ? 0 : x / y;
++ }
++
++ /**
++ * Implements int remainder but allows {@code x % 0} to be represented as 0. Basically equivalent to
++ * {@code (x % y)|0} JavaScript expression (remainder of two ints coerced to int).
++ * @param x the dividend
++ * @param y the divisor
++ * @return the remainder
++ */
++ public static int remZero(final int x, final int y) {
++ return y == 0 ? 0 : x % y;
++ }
++
++ /**
++ * Wrapper for modExact. Throws UnwarrantedOptimismException if the modulo can't be represented as int.
++ *
++ * @param x first term
++ * @param y second term
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if the modulo can't be represented as int.
++ */
++ public static int remExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
++ try {
++ return x % y;
++ } catch (final ArithmeticException e) {
++ assert y == 0; // Only mod by zero anticipated
++ throw new UnwarrantedOptimismException(Double.NaN, programPoint);
++ }
++ }
++
++ /**
++ * Wrapper for divExact. Throws UnwarrantedOptimismException if the result of the division can't be represented as
++ * long.
++ *
++ * @param x first term
++ * @param y second term
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if the result of the division can't be represented as long.
++ */
++ public static long divExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
++ final long res;
++ try {
++ res = x / y;
++ } catch (final ArithmeticException e) {
++ assert y == 0L; // Only div by zero anticipated
++ throw new UnwarrantedOptimismException(x > 0L ? Double.POSITIVE_INFINITY : x < 0L ? Double.NEGATIVE_INFINITY : Double.NaN, programPoint);
++ }
++ final long rem = x % y;
++ if (rem == 0L) {
++ return res;
++ }
++ throw new UnwarrantedOptimismException((double)x / (double)y, programPoint);
++ }
++
++ /**
++ * Implements long division but allows {@code x / 0} to be represented as 0. Useful when division of two longs
++ * is coerced to long.
++ * @param x the dividend
++ * @param y the divisor
++ * @return the result
++ */
++ public static long divZero(final long x, final long y) {
++ return y == 0L ? 0L : x / y;
++ }
++
++ /**
++ * Implements long remainder but allows {@code x % 0} to be represented as 0. Useful when remainder of two longs
++ * is coerced to long.
++ * @param x the dividend
++ * @param y the divisor
++ * @return the remainder
++ */
++ public static long remZero(final long x, final long y) {
++ return y == 0L ? 0L : x % y;
++ }
++
++ /**
++ * Wrapper for modExact. Throws UnwarrantedOptimismException if the modulo can't be represented as int.
++ *
++ * @param x first term
++ * @param y second term
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if the modulo can't be represented as int.
++ */
++ public static long remExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
++ try {
++ return x % y;
++ } catch (final ArithmeticException e) {
++ assert y == 0L; // Only mod by zero anticipated
++ throw new UnwarrantedOptimismException(Double.NaN, programPoint);
++ }
++ }
++
++ /**
++ * Wrapper for decrementExact
++ *
++ * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
++ * containing the result and the program point of the failure
++ *
++ * @param x number to negate
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if overflow occurs
++ */
++ public static int decrementExact(final int x, final int programPoint) throws UnwarrantedOptimismException {
++ try {
++ return Math.decrementExact(x);
++ } catch (final ArithmeticException e) {
++ throw new UnwarrantedOptimismException((long)x - 1, programPoint);
++ }
++ }
++
++ /**
++ * Wrapper for decrementExact
++ *
++ * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
++ * containing the result and the program point of the failure
++ *
++ * @param x number to negate
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if overflow occurs
++ */
++ public static long decrementExact(final long x, final int programPoint) throws UnwarrantedOptimismException {
++ try {
++ return Math.decrementExact(x);
++ } catch (final ArithmeticException e) {
++ throw new UnwarrantedOptimismException((double)x - 1L, programPoint);
++ }
++ }
++
++ /**
++ * Wrapper for incrementExact
++ *
++ * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
++ * containing the result and the program point of the failure
++ *
++ * @param x the number to increment
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if overflow occurs
++ */
++ public static int incrementExact(final int x, final int programPoint) throws UnwarrantedOptimismException {
++ try {
++ return Math.incrementExact(x);
++ } catch (final ArithmeticException e) {
++ throw new UnwarrantedOptimismException((long)x + 1, programPoint);
++ }
++ }
++
++ /**
++ * Wrapper for incrementExact
++ *
++ * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
++ * containing the result and the program point of the failure
++ *
++ * @param x the number to increment
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if overflow occurs
++ */
++ public static long incrementExact(final long x, final int programPoint) throws UnwarrantedOptimismException {
++ try {
++ return Math.incrementExact(x);
++ } catch (final ArithmeticException e) {
++ throw new UnwarrantedOptimismException((double)x + 1L, programPoint);
++ }
++ }
++
++ /**
++ * Wrapper for negateExact
++ *
++ * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
++ * containing the result and the program point of the failure
++ *
++ * @param x the number to negate
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if overflow occurs
++ */
++ public static int negateExact(final int x, final int programPoint) throws UnwarrantedOptimismException {
++ try {
++ if (x == 0) {
++ throw new UnwarrantedOptimismException(-0.0, programPoint);
++ }
++ return Math.negateExact(x);
++ } catch (final ArithmeticException e) {
++ throw new UnwarrantedOptimismException(-(long)x, programPoint);
++ }
++ }
++
++ /**
++ * Wrapper for negateExact
++ *
++ * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
++ * containing the result and the program point of the failure
++ *
++ * @param x the number to negate
++ * @param programPoint program point id
++ * @return the result
++ * @throws UnwarrantedOptimismException if overflow occurs
++ */
++ public static long negateExact(final long x, final int programPoint) throws UnwarrantedOptimismException {
++ try {
++ if (x == 0L) {
++ throw new UnwarrantedOptimismException(-0.0, programPoint);
++ }
++ return Math.negateExact(x);
++ } catch (final ArithmeticException e) {
++ throw new UnwarrantedOptimismException(-(double)x, programPoint);
++ }
++ }
++
++ /**
++ * Given a type of an accessor, return its index in [0..getNumberOfAccessorTypes())
++ *
++ * @param type the type
++ *
++ * @return the accessor index, or -1 if no accessor of this type exists
++ */
++ public static int getAccessorTypeIndex(final Type type) {
++ return getAccessorTypeIndex(type.getTypeClass());
++ }
++
++ /**
++ * Given a class of an accessor, return its index in [0..getNumberOfAccessorTypes())
++ *
++ * Note that this is hardcoded with respect to the dynamic contents of the accessor
++ * types array for speed. Hotspot got stuck with this as 5% of the runtime in
++ * a benchmark when it looped over values and increased an index counter. :-(
++ *
++ * @param type the type
++ *
++ * @return the accessor index, or -1 if no accessor of this type exists
++ */
++ public static int getAccessorTypeIndex(final Class<?> type) {
++ if (type == null) {
++ return TYPE_UNDEFINED_INDEX;
++ } else if (type == int.class) {
++ return TYPE_INT_INDEX;
++ } else if (type == long.class) {
++ return TYPE_LONG_INDEX;
++ } else if (type == double.class) {
++ return TYPE_DOUBLE_INDEX;
++ } else if (!type.isPrimitive()) {
++ return TYPE_OBJECT_INDEX;
++ }
++ return -1;
++ }
++
++ /**
++ * Return the accessor type based on its index in [0..getNumberOfAccessorTypes())
++ * Indexes are ordered narrower{@literal ->}wider / optimistic{@literal ->}pessimistic. Invalidations always
++ * go to a type of higher index
++ *
++ * @param index accessor type index
++ *
++ * @return a type corresponding to the index.
++ */
++
++ public static Type getAccessorType(final int index) {
++ return ACCESSOR_TYPES.get(index);
++ }
++
++ /**
++ * Return the number of accessor types available.
++ *
++ * @return number of accessor types in system
++ */
++ public static int getNumberOfAccessorTypes() {
++ return ACCESSOR_TYPES.size();
++ }
++
+ private static double parseRadix(final char chars[], final int start, final int length, final int radix) {
+ int pos = 0;
+
+@@ -1074,4 +1845,67 @@
+ throw new RuntimeException(t);
+ }
+ }
++
++ /**
++ * Returns the boxed version of a primitive class
++ * @param clazz the class
++ * @return the boxed type of clazz, or unchanged if not primitive
++ */
++ public static Class<?> getBoxedClass(final Class<?> clazz) {
++ if (clazz == int.class) {
++ return Integer.class;
++ } else if (clazz == long.class) {
++ return Long.class;
++ } else if (clazz == double.class) {
++ return Double.class;
++ }
++ assert !clazz.isPrimitive();
++ return clazz;
++ }
++
++ /**
++ * Create a method handle constant of the correct primitive type
++ * for a constant object
++ * @param o object
++ * @return constant function that returns object
++ */
++ public static MethodHandle unboxConstant(final Object o) {
++ if (o != null) {
++ if (o.getClass() == Integer.class) {
++ return MH.constant(int.class, ((Integer)o).intValue());
++ } else if (o.getClass() == Long.class) {
++ return MH.constant(long.class, ((Long)o).longValue());
++ } else if (o.getClass() == Double.class) {
++ return MH.constant(double.class, ((Double)o).doubleValue());
++ }
++ }
++ return MH.constant(Object.class, o);
++ }
++
++ /**
++ * Get the unboxed (primitive) type for an object
++ * @param o object
++ * @return primive type or Object.class if not primitive
++ */
++ public static Class<?> unboxedFieldType(final Object o) {
++ if (OBJECT_FIELDS_ONLY) {
++ return Object.class;
++ }
++
++ if (o == null) {
++ return Object.class;
++ } else if (o.getClass() == Integer.class) {
++ return int.class;
++ } else if (o.getClass() == Long.class) {
++ return long.class;
++ } else if (o.getClass() == Double.class) {
++ return double.class;
++ } else {
++ return Object.class;
++ }
++ }
++
++ private static final List<MethodHandle> toUnmodifiableList(final MethodHandle... methodHandles) {
++ return Collections.unmodifiableList(Arrays.asList(methodHandles));
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -34,7 +34,6 @@
+ import java.util.concurrent.Callable;
+ import jdk.nashorn.api.scripting.JSObject;
+ import jdk.nashorn.api.scripting.ScriptObjectMirror;
+-import jdk.nashorn.internal.objects.Global;
+ import jdk.nashorn.internal.runtime.linker.Bootstrap;
+ import jdk.nashorn.internal.runtime.linker.InvokeByName;
+
+@@ -174,7 +173,7 @@
+ */
+ protected abstract void setAt(final int index, final Object element);
+
+- private void checkRange(int index) {
++ private void checkRange(final int index) {
+ if(index < 0 || index >= size()) {
+ throw invalidIndex(index);
+ }
+@@ -200,7 +199,7 @@
+ unshiftInvoker.getInvoker().invokeExact(fn, obj, e);
+ } catch(RuntimeException | Error ex) {
+ throw ex;
+- } catch(Throwable t) {
++ } catch(final Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+@@ -214,7 +213,7 @@
+ pushInvoker.getInvoker().invokeExact(fn, obj, e);
+ } catch(RuntimeException | Error ex) {
+ throw ex;
+- } catch(Throwable t) {
++ } catch(final Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+@@ -328,7 +327,7 @@
+ return shiftInvoker.getInvoker().invokeExact(fn, obj);
+ } catch(RuntimeException | Error ex) {
+ throw ex;
+- } catch(Throwable t) {
++ } catch(final Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+@@ -341,7 +340,7 @@
+ return popInvoker.getInvoker().invokeExact(fn, obj);
+ } catch(RuntimeException | Error ex) {
+ throw ex;
+- } catch(Throwable t) {
++ } catch(final Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+@@ -359,7 +358,7 @@
+ spliceRemoveInvoker.getInvoker().invokeExact(fn, obj, fromIndex, count);
+ } catch(RuntimeException | Error ex) {
+ throw ex;
+- } catch(Throwable t) {
++ } catch(final Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/Logging.java Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,178 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
+-
+-import java.security.AccessControlContext;
+-import java.security.AccessController;
+-import java.security.Permissions;
+-import java.security.PrivilegedAction;
+-import java.security.ProtectionDomain;
+-import java.util.HashMap;
+-import java.util.Locale;
+-import java.util.Map;
+-import java.util.Map.Entry;
+-import java.util.logging.ConsoleHandler;
+-import java.util.logging.Formatter;
+-import java.util.logging.Handler;
+-import java.util.logging.Level;
+-import java.util.logging.LogRecord;
+-import java.util.logging.Logger;
+-import java.util.logging.LoggingPermission;
+-
+-/**
+- * Logging system for getting loggers for arbitrary subsystems as
+- * specified on the command line. Supports all standard log levels
+- *
+- */
+-public final class Logging {
+-
+- private Logging() {
+- }
+-
+- /** Loggers */
+-
+- private static final Logger disabledLogger = Logger.getLogger("disabled");
+-
+- private static AccessControlContext createLoggerControlAccCtxt() {
+- final Permissions perms = new Permissions();
+- perms.add(new LoggingPermission("control", null));
+- return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+- }
+-
+- static {
+- AccessController.doPrivileged(new PrivilegedAction<Void>() {
+- @Override
+- public Void run() {
+- Logging.disabledLogger.setLevel(Level.OFF);
+- return null;
+- }
+- }, createLoggerControlAccCtxt());
+- }
+-
+- /** Maps logger name to loggers. Names are typically per package */
+- private static final Map<String, Logger> loggers = new HashMap<>();
+-
+- private static String lastPart(final String packageName) {
+- final String[] parts = packageName.split("\\.");
+- if (parts.length == 0) {
+- return packageName;
+- }
+- return parts[parts.length - 1];
+- }
+-
+- /**
+- * Get a logger for a given class, generating a logger name based on the
+- * class name
+- *
+- * @param name the name to use as key for the logger
+- * @return the logger
+- */
+- public static Logger getLogger(final String name) {
+- final Logger logger = Logging.loggers.get(name);
+- if (logger != null) {
+- return logger;
+- }
+- return Logging.disabledLogger;
+- }
+-
+- /**
+- * Get a logger for a given name or create it if not already there, typically
+- * used for mapping system properties to loggers
+- *
+- * @param name the name to use as key
+- * @param level log lever to reset existing logger with, or create new logger with
+- * @return the logger
+- */
+- public static Logger getOrCreateLogger(final String name, final Level level) {
+- final Logger logger = Logging.loggers.get(name);
+- if (logger == null) {
+- return instantiateLogger(name, level);
+- }
+- logger.setLevel(level);
+- return logger;
+- }
+-
+- /**
+- * Initialization function that is called to instantiate the logging system. It takes
+- * logger names (keys) and logging labels respectively
+- *
+- * @param map a map where the key is a logger name and the value a logging level
+- * @throws IllegalArgumentException if level or names cannot be parsed
+- */
+- public static void initialize(final Map<String, String> map) throws IllegalArgumentException {
+- try {
+- for (final Entry<String, String> entry : map.entrySet()) {
+- Level level;
+-
+- final String key = entry.getKey();
+- final String value = entry.getValue();
+- if ("".equals(value)) {
+- level = Level.INFO;
+- } else {
+- level = Level.parse(value.toUpperCase(Locale.ENGLISH));
+- }
+-
+- final String name = Logging.lastPart(key);
+- final Logger logger = instantiateLogger(name, level);
+-
+- Logging.loggers.put(name, logger);
+- }
+- } catch (final IllegalArgumentException | SecurityException e) {
+- throw e;
+- }
+- }
+-
+- private static Logger instantiateLogger(final String name, final Level level) {
+- final Logger logger = java.util.logging.Logger.getLogger(name);
+- for (final Handler h : logger.getHandlers()) {
+- logger.removeHandler(h);
+- }
+-
+- logger.setLevel(level);
+- logger.setUseParentHandlers(false);
+- final Handler c = new ConsoleHandler();
+-
+- c.setFormatter(new Formatter() {
+- @Override
+- public String format(final LogRecord record) {
+- final StringBuilder sb = new StringBuilder();
+-
+- sb.append('[')
+- .append(record.getLoggerName())
+- .append("] ")
+- .append(record.getMessage())
+- .append('\n');
+-
+- return sb.toString();
+- }
+- });
+- logger.addHandler(c);
+- c.setLevel(level);
+-
+- return logger;
+- }
+-
+-}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java Wed Feb 04 12:14:47 2015 -0800
+@@ -92,7 +92,7 @@
+ }
+
+ @Override
+- protected PermissionCollection getPermissions(CodeSource codesource) {
++ protected PermissionCollection getPermissions(final CodeSource codesource) {
+ final Permissions permCollection = new Permissions();
+ for (final Permission perm : SCRIPT_PERMISSIONS) {
+ permCollection.add(perm);
+--- ./nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,10 +25,14 @@
+
+ package jdk.nashorn.internal.runtime;
+
++import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
++
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+ import java.lang.invoke.MethodType;
+ import jdk.internal.dynalink.CallSiteDescriptor;
++import jdk.internal.dynalink.beans.BeansLinker;
+ import jdk.internal.dynalink.beans.StaticClass;
+ import jdk.internal.dynalink.linker.GuardedInvocation;
+ import jdk.internal.dynalink.linker.LinkRequest;
+@@ -135,12 +139,12 @@
+ }
+
+ @Override
+- protected GuardedInvocation findNewMethod(CallSiteDescriptor desc) {
++ protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+ return createClassNotFoundInvocation(desc);
+ }
+
+ @Override
+- protected GuardedInvocation findCallMethod(CallSiteDescriptor desc, LinkRequest request) {
++ protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+ return createClassNotFoundInvocation(desc);
+ }
+
+@@ -202,8 +206,12 @@
+ }
+
+ @Override
+- protected Object invokeNoSuchProperty(final String name) {
+- return createProperty(name);
++ protected Object invokeNoSuchProperty(final String key, final int programPoint) {
++ final Object retval = createProperty(key);
++ if (isValid(programPoint)) {
++ throw new UnwarrantedOptimismException(retval, programPoint);
++ }
++ return retval;
+ }
+
+ @Override
+@@ -226,6 +234,35 @@
+ //ignored
+ }
+
++ // Check for explicit constructor signature use
++ // Example: new (java.awt["Color(int, int,int)"])(2, 3, 4);
++ final int openBrace = propertyName.indexOf('(');
++ final int closeBrace = propertyName.lastIndexOf(')');
++ if (openBrace != -1 || closeBrace != -1) {
++ final int lastChar = propertyName.length() - 1;
++ if (openBrace == -1 || closeBrace != lastChar) {
++ throw typeError("improper.constructor.signature", propertyName);
++ }
++
++ // get the class name and try to load it
++ final String className = name + "." + propertyName.substring(0, openBrace);
++ try {
++ javaClass = context.findClass(className);
++ } catch (final NoClassDefFoundError | ClassNotFoundException e) {
++ throw typeError(e, "no.such.java.class", className);
++ }
++
++ // try to find a matching constructor
++ final Object constructor = BeansLinker.getConstructorMethod(
++ javaClass, propertyName.substring(openBrace + 1, lastChar));
++ if (constructor != null) {
++ set(propertyName, constructor, 0);
++ return constructor;
++ }
++ // we didn't find a matching constructor!
++ throw typeError("no.such.java.constructor", propertyName);
++ }
++
+ final Object propertyValue;
+ if (javaClass == null) {
+ propertyValue = new NativeJavaPackage(fullName, getProto());
+@@ -233,7 +270,7 @@
+ propertyValue = StaticClass.forClass(javaClass);
+ }
+
+- set(propertyName, propertyValue, false);
++ set(propertyName, propertyValue, 0);
+ return propertyValue;
+ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/OptimisticBuiltins.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,65 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
++
++import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
++import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
++
++/**
++ * This is an interface for classes that need custom linkage logic. This means Native objects
++ * that contain optimistic native methods, that need special/extra rules for linking, guards and
++ * SwitchPointing, known and internal to the Native object for its linkage
++ */
++public interface OptimisticBuiltins {
++
++ /**
++ * Return an instance of the linking logic we need for a particular LinkLogic
++ * subclass, gotten from the compile time annotation of a specialized builtin method
++ * No assumptions can be made about the lifetime of the instance. The receiver may
++ * keep it as a perpetual final instance field or create new linking logic depending
++ * on its current state for each call, depending on if the global state has changed
++ * or other factors
++ *
++ * @param clazz linking logic class
++ * @return linking logic instance for this class
++ */
++ public SpecializedFunction.LinkLogic getLinkLogic(final Class<? extends LinkLogic> clazz);
++
++ /**
++ * Does this link logic vary depending on which instance we are working with.
++ * Then we have to sort out certain primitives, as they are created as new
++ * objects in the wrapFilter by JavaScript semantics. An example of instance only
++ * assumptions are switchPoints per instance, as in NativeArray. NativeString is
++ * fine, as it's only static.
++ *
++ * TODO: finer granularity on this, on the function level so certain functions
++ * are forbidden only. Currently we don't have enough specialization to bump into this
++ *
++ * @return true if there are per instance assumptions for the optimism
++ */
++ public boolean hasPerInstanceAssumptions();
++
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/OptimisticReturnFilters.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,291 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
++
++import static jdk.nashorn.internal.lookup.Lookup.MH;
++import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
++
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.lang.invoke.MethodType;
++import jdk.internal.dynalink.CallSiteDescriptor;
++import jdk.internal.dynalink.linker.GuardedInvocation;
++import jdk.internal.dynalink.support.TypeUtilities;
++import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
++
++/**
++ * Optimistic return value filters
++ */
++public final class OptimisticReturnFilters {
++ private static final MethodHandle[] ENSURE_INT;
++ private static final MethodHandle[] ENSURE_LONG;
++ private static final MethodHandle[] ENSURE_NUMBER;
++
++ private static final int BOOLEAN_TYPE_INDEX;
++ private static final int CHAR_TYPE_INDEX;
++ private static final int FLOAT_TYPE_INDEX;
++ private static final int VOID_TYPE_INDEX;
++
++ static {
++ final MethodHandle INT_DOUBLE = findOwnMH("ensureInt", int.class, double.class, int.class);
++ ENSURE_INT = new MethodHandle[] {
++ null,
++ findOwnMH("ensureInt", int.class, long.class, int.class),
++ INT_DOUBLE,
++ findOwnMH("ensureInt", int.class, Object.class, int.class),
++ findOwnMH("ensureInt", int.class, int.class),
++ findOwnMH("ensureInt", int.class, boolean.class, int.class),
++ findOwnMH("ensureInt", int.class, char.class, int.class),
++ INT_DOUBLE.asType(INT_DOUBLE.type().changeParameterType(0, float.class)),
++ };
++
++ VOID_TYPE_INDEX = ENSURE_INT.length - 4;
++ BOOLEAN_TYPE_INDEX = ENSURE_INT.length - 3;
++ CHAR_TYPE_INDEX = ENSURE_INT.length - 2;
++ FLOAT_TYPE_INDEX = ENSURE_INT.length - 1;
++
++ final MethodHandle LONG_DOUBLE = findOwnMH("ensureLong", long.class, double.class, int.class);
++ ENSURE_LONG = new MethodHandle[] {
++ null,
++ null,
++ LONG_DOUBLE,
++ findOwnMH("ensureLong", long.class, Object.class, int.class),
++ ENSURE_INT[VOID_TYPE_INDEX].asType(ENSURE_INT[VOID_TYPE_INDEX].type().changeReturnType(long.class)),
++ ENSURE_INT[BOOLEAN_TYPE_INDEX].asType(ENSURE_INT[BOOLEAN_TYPE_INDEX].type().changeReturnType(long.class)),
++ ENSURE_INT[CHAR_TYPE_INDEX].asType(ENSURE_INT[CHAR_TYPE_INDEX].type().changeReturnType(long.class)),
++ LONG_DOUBLE.asType(LONG_DOUBLE.type().changeParameterType(0, float.class)),
++ };
++
++ ENSURE_NUMBER = new MethodHandle[] {
++ null,
++ null,
++ null,
++ findOwnMH("ensureNumber", double.class, Object.class, int.class),
++ ENSURE_INT[VOID_TYPE_INDEX].asType(ENSURE_INT[VOID_TYPE_INDEX].type().changeReturnType(double.class)),
++ ENSURE_INT[BOOLEAN_TYPE_INDEX].asType(ENSURE_INT[BOOLEAN_TYPE_INDEX].type().changeReturnType(double.class)),
++ ENSURE_INT[CHAR_TYPE_INDEX].asType(ENSURE_INT[CHAR_TYPE_INDEX].type().changeReturnType(double.class)),
++ null
++ };
++ }
++
++ /**
++ * Given a method handle and an expected return type, perform return value filtering
++ * according to the optimistic type coercion rules
++ * @param mh method handle
++ * @param expectedReturnType expected return type
++ * @param programPoint program point
++ * @return filtered method
++ */
++ public static MethodHandle filterOptimisticReturnValue(final MethodHandle mh, final Class<?> expectedReturnType, final int programPoint) {
++ if(!isValid(programPoint)) {
++ return mh;
++ }
++
++ final MethodType type = mh.type();
++ final Class<?> actualReturnType = type.returnType();
++ if(TypeUtilities.isConvertibleWithoutLoss(actualReturnType, expectedReturnType)) {
++ return mh;
++ }
++
++ final MethodHandle guard = getOptimisticTypeGuard(expectedReturnType, actualReturnType);
++ return guard == null ? mh : MH.filterReturnValue(mh, MH.insertArguments(guard, guard.type().parameterCount() - 1, programPoint));
++ }
++
++ /**
++ * Given a guarded invocation and a callsite descriptor, perform return value filtering
++ * according to the optimistic type coercion rules, using the return value from the descriptor
++ * @param inv the invocation
++ * @param desc the descriptor
++ * @return filtered invocation
++ */
++ public static GuardedInvocation filterOptimisticReturnValue(final GuardedInvocation inv, final CallSiteDescriptor desc) {
++ if(!NashornCallSiteDescriptor.isOptimistic(desc)) {
++ return inv;
++ }
++ return inv.replaceMethods(filterOptimisticReturnValue(inv.getInvocation(), desc.getMethodType().returnType(),
++ NashornCallSiteDescriptor.getProgramPoint(desc)), inv.getGuard());
++ }
++
++ private static MethodHandle getOptimisticTypeGuard(final Class<?> actual, final Class<?> provable) {
++ final MethodHandle guard;
++ final int provableTypeIndex = getProvableTypeIndex(provable);
++ if (actual == int.class) {
++ guard = ENSURE_INT[provableTypeIndex];
++ } else if (actual == long.class) {
++ guard = ENSURE_LONG[provableTypeIndex];
++ } else if (actual == double.class) {
++ guard = ENSURE_NUMBER[provableTypeIndex];
++ } else {
++ guard = null;
++ assert !actual.isPrimitive() : actual + ", " + provable;
++ }
++ if(guard != null && !(provable.isPrimitive())) {
++ // Make sure filtering a MethodHandle(...)String works with a filter MethodHandle(Object, int)... Note that
++ // if the return type of the method is incompatible with Number, then the guard will always throw an
++ // UnwarrantedOperationException when invoked, but we must link it anyway as we need the guarded function to
++ // successfully execute and return the non-convertible return value that it'll put into the thrown
++ // UnwarrantedOptimismException.
++ return guard.asType(guard.type().changeParameterType(0, provable));
++ }
++ return guard;
++ }
++
++ private static int getProvableTypeIndex(final Class<?> provable) {
++ final int accTypeIndex = getAccessorTypeIndex(provable);
++ if(accTypeIndex != -1) {
++ return accTypeIndex;
++ } else if(provable == boolean.class) {
++ return BOOLEAN_TYPE_INDEX;
++ } else if(provable == void.class) {
++ return VOID_TYPE_INDEX;
++ } else if(provable == byte.class || provable == short.class) {
++ return 0; // never needs a guard, as it's assignable to int
++ } else if(provable == char.class) {
++ return CHAR_TYPE_INDEX;
++ } else if(provable == float.class) {
++ return FLOAT_TYPE_INDEX;
++ }
++ throw new AssertionError(provable.getName());
++ }
++
++ //maps staticallyProvableCallSiteType to actualCallSiteType, throws exception if impossible
++ @SuppressWarnings("unused")
++ private static int ensureInt(final long arg, final int programPoint) {
++ if (JSType.isRepresentableAsInt(arg)) {
++ return (int)arg;
++ }
++ throw new UnwarrantedOptimismException(arg, programPoint);
++ }
++
++ @SuppressWarnings("unused")
++ private static int ensureInt(final double arg, final int programPoint) {
++ if (JSType.isRepresentableAsInt(arg) && !JSType.isNegativeZero(arg)) {
++ return (int)arg;
++ }
++ throw new UnwarrantedOptimismException(arg, programPoint);
++ }
++
++ /**
++ * Returns the argument value as an int. If the argument is not a wrapper for a primitive numeric type
++ * with a value that can be exactly represented as an int, throw an {@link UnwarrantedOptimismException}.
++ * This method is only public so that generated script code can use it. See {code CodeGenerator.ENSURE_INT}.
++ * @param arg the original argument.
++ * @param programPoint the program point used in the exception
++ * @return the value of the argument as an int.
++ * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type with
++ * a value that can be exactly represented as an int.
++ */
++ public static int ensureInt(final Object arg, final int programPoint) {
++ // NOTE: this doesn't delegate to ensureInt(double, int) as in that case if arg were a Long, it would throw a
++ // (potentially imprecise) Double in the UnwarrantedOptimismException. This way, it will put the correct valued
++ // Long into the exception.
++ if (isPrimitiveNumberWrapper(arg)) {
++ final double d = ((Number)arg).doubleValue();
++ if (JSType.isRepresentableAsInt(d) && !JSType.isNegativeZero(d)) {
++ return (int)d;
++ }
++ }
++ throw new UnwarrantedOptimismException(arg, programPoint);
++ }
++
++ private static boolean isPrimitiveNumberWrapper(final Object obj) {
++ if (obj == null) {
++ return false;
++ }
++ final Class<?> c = obj.getClass();
++ return c == Integer.class || c == Double.class || c == Long.class ||
++ c == Float.class || c == Short.class || c == Byte.class;
++ }
++
++ @SuppressWarnings("unused")
++ private static int ensureInt(final boolean arg, final int programPoint) {
++ throw new UnwarrantedOptimismException(arg, programPoint, Type.OBJECT);
++ }
++
++ @SuppressWarnings("unused")
++ private static int ensureInt(final char arg, final int programPoint) {
++ throw new UnwarrantedOptimismException(arg, programPoint, Type.OBJECT);
++ }
++
++ @SuppressWarnings("unused")
++ private static int ensureInt(final int programPoint) {
++ // Turns a void into UNDEFINED
++ throw new UnwarrantedOptimismException(ScriptRuntime.UNDEFINED, programPoint, Type.OBJECT);
++ }
++
++ private static long ensureLong(final double arg, final int programPoint) {
++ if (JSType.isRepresentableAsLong(arg) && !JSType.isNegativeZero(arg)) {
++ return (long)arg;
++ }
++ throw new UnwarrantedOptimismException(arg, programPoint);
++ }
++
++ /**
++ * Returns the argument value as a long. If the argument is not a wrapper for a primitive numeric type
++ * with a value that can be exactly represented as a long, throw an {@link UnwarrantedOptimismException}.
++ * This method is only public so that generated script code can use it. See {code CodeGenerator.ENSURE_LONG}.
++ * @param arg the original argument.
++ * @param programPoint the program point used in the exception
++ * @return the value of the argument as a long.
++ * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type with
++ * a value that can be exactly represented as a long
++ */
++ public static long ensureLong(final Object arg, final int programPoint) {
++ if (arg != null) {
++ final Class<?> c = arg.getClass();
++ if (c == Long.class) {
++ // Must check for Long separately, as Long.doubleValue() isn't precise.
++ return ((Long)arg).longValue();
++ } else if (c == Integer.class || c == Double.class || c == Float.class || c == Short.class ||
++ c == Byte.class) {
++ return ensureLong(((Number)arg).doubleValue(), programPoint);
++ }
++ }
++ throw new UnwarrantedOptimismException(arg, programPoint);
++ }
++
++ /**
++ * Returns the argument value as a double. If the argument is not a a wrapper for a primitive numeric type
++ * throw an {@link UnwarrantedOptimismException}.This method is only public so that generated script code
++ * can use it. See {code CodeGenerator.ENSURE_NUMBER}.
++ * @param arg the original argument.
++ * @param programPoint the program point used in the exception
++ * @return the value of the argument as a double.
++ * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type.
++ */
++ public static double ensureNumber(final Object arg, final int programPoint) {
++ if (isPrimitiveNumberWrapper(arg)) {
++ return ((Number)arg).doubleValue();
++ }
++ throw new UnwarrantedOptimismException(arg, programPoint);
++ }
++
++ private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
++ return MH.findStatic(MethodHandles.lookup(), OptimisticReturnFilters.class, name, MH.type(rtype, types));
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/Property.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/Property.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,12 +28,11 @@
+ import static jdk.nashorn.internal.runtime.PropertyDescriptor.CONFIGURABLE;
+ import static jdk.nashorn.internal.runtime.PropertyDescriptor.ENUMERABLE;
+ import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE;
+-
+ import java.io.Serializable;
+ import java.lang.invoke.MethodHandle;
++import java.lang.invoke.SwitchPoint;
+ import java.util.Objects;
+ import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+-import jdk.nashorn.internal.codegen.types.Type;
+
+ /**
+ * This is the abstract superclass representing a JavaScript Property.
+@@ -65,42 +64,57 @@
+ /** ECMA 8.6.1 - Is this property not configurable? */
+ public static final int NOT_CONFIGURABLE = 1 << 2;
+
+- private static final int MODIFY_MASK = (NOT_WRITABLE | NOT_ENUMERABLE | NOT_CONFIGURABLE);
+-
+- /** Is this a spill property? See {@link AccessorProperty} */
+- public static final int IS_SPILL = 1 << 3;
++ private static final int MODIFY_MASK = NOT_WRITABLE | NOT_ENUMERABLE | NOT_CONFIGURABLE;
+
+ /** Is this a function parameter? */
+- public static final int IS_PARAMETER = 1 << 4;
++ public static final int IS_PARAMETER = 1 << 3;
+
+ /** Is parameter accessed thru arguments? */
+- public static final int HAS_ARGUMENTS = 1 << 5;
+-
+- /** Is this property always represented as an Object? See {@link ObjectClassGenerator} and dual fields flag. */
+- public static final int IS_ALWAYS_OBJECT = 1 << 6;
+-
+- /** Can this property be primitive? */
+- public static final int CAN_BE_PRIMITIVE = 1 << 7;
+-
+- /** Can this property be undefined? */
+- public static final int CAN_BE_UNDEFINED = 1 << 8;
++ public static final int HAS_ARGUMENTS = 1 << 4;
+
+ /** Is this a function declaration property ? */
+- public static final int IS_FUNCTION_DECLARATION = 1 << 9;
++ public static final int IS_FUNCTION_DECLARATION = 1 << 5;
++
++ /**
++ * Is this is a primitive field given to us by Nasgen, i.e.
++ * something we can be sure remains a constant whose type
++ * is narrower than object, e.g. Math.PI which is declared
++ * as a double
++ */
++ public static final int IS_NASGEN_PRIMITIVE = 1 << 6;
++
++ /** Is this a builtin property, e.g. Function.prototype.apply */
++ public static final int IS_BUILTIN = 1 << 7;
+
+ /** Is this property bound to a receiver? This means get/set operations will be delegated to
+ * a statically defined object instead of the object passed as callsite parameter. */
+- public static final int IS_BOUND = 1 << 10;
++ public static final int IS_BOUND = 1 << 8;
++
++ /** Is this a lexically scoped LET or CONST variable that is dead until it is declared. */
++ public static final int NEEDS_DECLARATION = 1 << 9;
++
++ /** Is this property an ES6 lexical binding? */
++ public static final int IS_LEXICAL_BINDING = 1 << 10;
+
+ /** Property key. */
+ private final String key;
+
+ /** Property flags. */
+- protected int flags;
++ private int flags;
+
+ /** Property field number or spill slot. */
+ private final int slot;
+
++ /**
++ * Current type of this object, in object only mode, this is an Object.class. In dual-fields mode
++ * null means undefined, and primitive types are allowed. The reason a special type is used for
++ * undefined, is that are no bits left to represent it in primitive types
++ */
++ private Class<?> type;
++
++ /** SwitchPoint that is invalidated when property is changed, optional */
++ protected transient SwitchPoint builtinSwitchPoint;
++
+ private static final long serialVersionUID = 2099814273074501176L;
+
+ /**
+@@ -122,10 +136,11 @@
+ *
+ * @param property source property
+ */
+- Property(final Property property) {
+- this.key = property.key;
+- this.flags = property.flags;
+- this.slot = property.slot;
++ Property(final Property property, final int flags) {
++ this.key = property.key;
++ this.slot = property.slot;
++ this.builtinSwitchPoint = property.builtinSwitchPoint;
++ this.flags = flags;
+ }
+
+ /**
+@@ -133,7 +148,15 @@
+ *
+ * @return cloned property
+ */
+- abstract Property copy();
++ public abstract Property copy();
++
++ /**
++ * Copy function
++ *
++ * @param newType new type
++ * @return cloned property with new type
++ */
++ public abstract Property copy(final Class<?> newType);
+
+ /**
+ * Property flag utility method for {@link PropertyDescriptor}s. Given two property descriptors,
+@@ -166,6 +189,34 @@
+ }
+
+ /**
++ * Set the change callback for this property, i.e. a SwitchPoint
++ * that will be invalidated when the value of the property is
++ * changed
++ * @param sp SwitchPoint to use for change callback
++ */
++ public final void setBuiltinSwitchPoint(final SwitchPoint sp) {
++ this.builtinSwitchPoint = sp;
++ }
++
++ /**
++ * Builtin properties have an invalidation switchpoint that is
++ * invalidated when they are set, this is a getter for it
++ * @return builtin switchpoint, or null if none
++ */
++ public final SwitchPoint getBuiltinSwitchPoint() {
++ return builtinSwitchPoint;
++ }
++
++ /**
++ * Checks if this is a builtin property, this means that it has
++ * a builtin switchpoint that hasn't been invalidated by a setter
++ * @return true if builtin, untouched (unset) property
++ */
++ public boolean isBuiltin() {
++ return builtinSwitchPoint != null && !builtinSwitchPoint.hasBeenInvalidated();
++ }
++
++ /**
+ * Property flag utility method for {@link PropertyDescriptor}. Get the property flags
+ * conforming to any Property using this PropertyDescriptor
+ *
+@@ -255,7 +306,7 @@
+ * @return true if spill property
+ */
+ public boolean isSpill() {
+- return (flags & IS_SPILL) == IS_SPILL;
++ return false;
+ }
+
+ /**
+@@ -269,15 +320,12 @@
+ }
+
+ /**
+- * Does this property use any slots in the spill array described in
+- * {@link Property#isSpill}? In that case how many. Currently a property
+- * only uses max one spill slot, but this may change in future representations
+- * Only {@link AccessorProperty} instances use spill slots
++ * Is this a LET or CONST property that needs to see its declaration before being usable?
+ *
+- * @return number of spill slots a property is using
++ * @return true if this is a block-scoped variable
+ */
+- public int getSpillCount() {
+- return isSpill() ? 1 : 0;
++ public boolean needsDeclaration() {
++ return (flags & NEEDS_DECLARATION) == NEEDS_DECLARATION;
+ }
+
+ /**
+@@ -298,6 +346,16 @@
+ }
+
+ /**
++ * Check if a flag is set for a property
++ * @param property property
++ * @param flag flag to check
++ * @return true if flag is set
++ */
++ public static boolean checkFlag(final Property property, final int flag) {
++ return (property.getFlags() & flag) == flag;
++ }
++
++ /**
+ * Get the flags for this property
+ * @return property flags
+ */
+@@ -361,6 +419,14 @@
+ public abstract MethodHandle getGetter(final Class<?> type);
+
+ /**
++ * Get an optimistic getter that throws an exception if type is not the known given one
++ * @param type type
++ * @param programPoint program point
++ * @return getter
++ */
++ public abstract MethodHandle getOptimisticGetter(final Class<?> type, final int programPoint);
++
++ /**
+ * Hook to initialize method handles after deserialization.
+ *
+ * @param structure the structure class
+@@ -384,6 +450,46 @@
+ }
+
+ /**
++ * get the Object value of this property from {@code owner}. This allows to bypass creation of the
++ * getter MethodHandle for spill and user accessor properties.
++ *
++ * @param self the this object
++ * @param owner the owner of the property
++ * @return the property value
++ */
++ public abstract int getIntValue(final ScriptObject self, final ScriptObject owner);
++
++ /**
++ * get the Object value of this property from {@code owner}. This allows to bypass creation of the
++ * getter MethodHandle for spill and user accessor properties.
++ *
++ * @param self the this object
++ * @param owner the owner of the property
++ * @return the property value
++ */
++ public abstract long getLongValue(final ScriptObject self, final ScriptObject owner);
++
++ /**
++ * get the Object value of this property from {@code owner}. This allows to bypass creation of the
++ * getter MethodHandle for spill and user accessor properties.
++ *
++ * @param self the this object
++ * @param owner the owner of the property
++ * @return the property value
++ */
++ public abstract double getDoubleValue(final ScriptObject self, final ScriptObject owner);
++
++ /**
++ * get the Object value of this property from {@code owner}. This allows to bypass creation of the
++ * getter MethodHandle for spill and user accessor properties.
++ *
++ * @param self the this object
++ * @param owner the owner of the property
++ * @return the property value
++ */
++ public abstract Object getObjectValue(final ScriptObject self, final ScriptObject owner);
++
++ /**
+ * Set the value of this property in {@code owner}. This allows to bypass creation of the
+ * setter MethodHandle for spill and user accessor properties.
+ *
+@@ -392,17 +498,40 @@
+ * @param value the new property value
+ * @param strict is this a strict setter?
+ */
+- public abstract void setObjectValue(ScriptObject self, ScriptObject owner, Object value, boolean strict);
++ public abstract void setValue(final ScriptObject self, final ScriptObject owner, final int value, final boolean strict);
+
+ /**
+- * Set the Object value of this property from {@code owner}. This allows to bypass creation of the
+- * getter MethodHandle for spill and user accessor properties.
++ * Set the value of this property in {@code owner}. This allows to bypass creation of the
++ * setter MethodHandle for spill and user accessor properties.
+ *
+ * @param self the this object
+ * @param owner the owner object
+- * @return the property value
++ * @param value the new property value
++ * @param strict is this a strict setter?
+ */
+- public abstract Object getObjectValue(ScriptObject self, ScriptObject owner);
++ public abstract void setValue(final ScriptObject self, final ScriptObject owner, final long value, final boolean strict);
++
++ /**
++ * Set the value of this property in {@code owner}. This allows to bypass creation of the
++ * setter MethodHandle for spill and user accessor properties.
++ *
++ * @param self the this object
++ * @param owner the owner object
++ * @param value the new property value
++ * @param strict is this a strict setter?
++ */
++ public abstract void setValue(final ScriptObject self, final ScriptObject owner, final double value, final boolean strict);
++
++ /**
++ * Set the value of this property in {@code owner}. This allows to bypass creation of the
++ * setter MethodHandle for spill and user accessor properties.
++ *
++ * @param self the this object
++ * @param owner the owner object
++ * @param value the new property value
++ * @param strict is this a strict setter?
++ */
++ public abstract void setValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict);
+
+ /**
+ * Abstract method for retrieving the setter for the property. We do not know
+@@ -417,7 +546,7 @@
+ * <p>
+ * see {@link ObjectClassGenerator#createSetter(Class, Class, MethodHandle, MethodHandle)}
+ * if you are interested in the internal details of this. Note that if you
+- * are running in default mode, with {@code -Dnashorn.fields.dual=true}, disabled, the setters
++ * are running with {@code -Dnashorn.fields.objects=true}, the setters
+ * will currently never change, as all properties are represented as Object field,
+ * the Object fields are Initialized to {@code ScriptRuntime.UNDEFINED} and primitives are
+ * boxed/unboxed upon every access, which is not necessarily optimal
+@@ -450,7 +579,7 @@
+
+ @Override
+ public int hashCode() {
+- final Class<?> type = getCurrentType();
++ final Class<?> type = getLocalType();
+ return Objects.hashCode(this.key) ^ flags ^ getSlot() ^ (type == null ? 0 : type.hashCode());
+ }
+
+@@ -466,45 +595,110 @@
+
+ final Property otherProperty = (Property)other;
+
+- return getFlags() == otherProperty.getFlags() &&
+- getSlot() == otherProperty.getSlot() &&
+- getCurrentType() == otherProperty.getCurrentType() &&
+- getKey().equals(otherProperty.getKey());
++ return equalsWithoutType(otherProperty) &&
++ getLocalType() == otherProperty.getLocalType();
+ }
+
++ boolean equalsWithoutType(final Property otherProperty) {
++ return getFlags() == otherProperty.getFlags() &&
++ getSlot() == otherProperty.getSlot() &&
++ getKey().equals(otherProperty.getKey());
++ }
++
++ private static final String type(final Class<?> type) {
++ if (type == null) {
++ return "undef";
++ } else if (type == int.class) {
++ return "i";
++ } else if (type == long.class) {
++ return "j";
++ } else if (type == double.class) {
++ return "d";
++ } else {
++ return "o";
++ }
++ }
++
++ /**
++ * Short toString version
++ * @return short toString
++ */
++ public final String toStringShort() {
++ final StringBuilder sb = new StringBuilder();
++ final Class<?> type = getLocalType();
++ sb.append(getKey()).append(" (").append(type(type)).append(')');
++ return sb.toString();
++ }
++
++ private static String indent(final String str, final int indent) {
++ final StringBuilder sb = new StringBuilder();
++ sb.append(str);
++ for (int i = 0; i < indent - str.length(); i++) {
++ sb.append(' ');
++ }
++ return sb.toString();
++ }
++
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+- final Class<?> type = getCurrentType();
++ final Class<?> type = getLocalType();
+
+- sb.append(getKey()).
+- append("(0x").
+- append(Integer.toHexString(flags)).
++ sb.append(indent(getKey(), 20)).
++ append(" id=").
++ append(Debug.id(this)).
++ append(" (0x").
++ append(indent(Integer.toHexString(flags), 4)).
+ append(") ").
+ append(getClass().getSimpleName()).
+ append(" {").
+- append(type == null ? "UNDEFINED" : Type.typeFor(type).getDescriptor()).
++ append(indent(type(type), 5)).
+ append('}');
+
+ if (slot != -1) {
+- sb.append('[');
+- sb.append(slot);
+- sb.append(']');
++ sb.append(" [").
++ append("slot=").
++ append(slot).
++ append(']');
+ }
+
+ return sb.toString();
+ }
+
+ /**
+- * Get the current type of this field. If you are not running with dual fields enabled,
++ * Get the current type of this property. If you are running with object fields enabled,
+ * this will always be Object.class. See the value representation explanation in
+ * {@link Property#getSetter(Class, PropertyMap)} and {@link ObjectClassGenerator}
+ * for more information.
+ *
++ * <p>Note that for user accessor properties, this returns the type of the last observed
++ * value passed to or returned by a user accessor. Use {@link #getLocalType()} to always get
++ * the type of the actual value stored in the property slot.</p>
++ *
+ * @return current type of property, null means undefined
+ */
+- public Class<?> getCurrentType() {
+- return Object.class;
++ public final Class<?> getType() {
++ return type;
++ }
++
++ /**
++ * Set the type of this property.
++ * @param type new type
++ */
++ public final void setType(final Class<?> type) {
++ assert type != boolean.class : "no boolean storage support yet - fix this";
++ this.type = type == null ? null : type.isPrimitive() ? type : Object.class;
++ }
++
++ /**
++ * Get the type of the value in the local property slot. This returns the same as
++ * {@link #getType()} for normal properties, but always returns {@code Object.class}
++ * for {@link UserAccessorProperty}s as their local type is a pair of accessor references.
++ *
++ * @return the local property type
++ */
++ protected Class<?> getLocalType() {
++ return getType();
+ }
+
+ /**
+@@ -517,44 +711,18 @@
+ }
+
+ /**
+- * Check whether this Property is ever used as anything but an Object. If this is used only
+- * as an object, dual fields mode need not even try to represent it as a primitive at any
+- * callsite, saving map rewrites for performance.
+- *
+- * @return true if representation should always be an object field
+- */
+- public boolean isAlwaysObject() {
+- return (flags & IS_ALWAYS_OBJECT) == IS_ALWAYS_OBJECT;
+- }
+-
+- /**
+- * Check whether this property can be primitive. This is a conservative
+- * analysis result, so {@code false} might mean that it can still be
+- * primitive
+- *
+- * @return can be primitive status
+- */
+- public boolean canBePrimitive() {
+- return (flags & CAN_BE_PRIMITIVE) == CAN_BE_PRIMITIVE;
+- }
+-
+- /**
+- * Check whether this property can be primitive. This is a conservative
+- * analysis result, so {@code true} might mean that it can still be
+- * defined, but it will never say that a property can not be undefined
+- * if it can
+- *
+- * @return can be undefined status
+- */
+- public boolean canBeUndefined() {
+- return (flags & CAN_BE_UNDEFINED) == CAN_BE_UNDEFINED;
+- }
+-
+- /**
+ * Check whether this property represents a function declaration.
+ * @return whether this property is a function declaration or not.
+ */
+ public boolean isFunctionDeclaration() {
+ return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION;
+ }
++
++ /**
++ * Is this a property defined by ES6 let or const?
++ * @return true if this property represents a lexical binding.
++ */
++ public boolean isLexicalBinding() {
++ return (flags & IS_LEXICAL_BINDING) == IS_LEXICAL_BINDING;
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/PropertyAccess.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/PropertyAccess.java Wed Feb 04 12:14:47 2015 -0800
+@@ -38,86 +38,98 @@
+ /**
+ * Get the value for a given key and return it as an int
+ * @param key the key
++ * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
+ * @return the value
+ */
+- public int getInt(Object key);
++ public int getInt(Object key, int programPoint);
+
+ /**
+ * Get the value for a given key and return it as an int
+ * @param key the key
++ * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
+ * @return the value
+ */
+- public int getInt(double key);
++ public int getInt(double key, int programPoint);
+
+ /**
+ * Get the value for a given key and return it as an int
+ * @param key the key
++ * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
+ * @return the value
+ */
+- public int getInt(final long key);
++ public int getInt(long key, int programPoint);
+
+ /**
+ * Get the value for a given key and return it as an int
+ * @param key the key
++ * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
+ * @return the value
+ */
+- public int getInt(int key);
++ public int getInt(int key, int programPoint);
+
+ /**
+ * Get the value for a given key and return it as a long
+ * @param key the key
++ * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
+ * @return the value
+ */
+- public long getLong(Object key);
++ public long getLong(Object key, int programPoint);
+
+ /**
+ * Get the value for a given key and return it as a long
+ * @param key the key
++ * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
+ * @return the value
+ */
+- public long getLong(double key);
++ public long getLong(double key, int programPoint);
+
+ /**
+ * Get the value for a given key and return it as a long
+ * @param key the key
++ * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
+ * @return the value
+ */
+- public long getLong(long key);
++ public long getLong(long key, int programPoint);
+
+ /**
+ * Get the value for a given key and return it as a long
+ * @param key the key
++ * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
+ * @return the value
+ */
+- public long getLong(int key);
++ public long getLong(int key, int programPoint);
+
+ /**
+ * Get the value for a given key and return it as a double
+ * @param key the key
++ * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
+ * @return the value
+ */
+- public double getDouble(Object key);
++ public double getDouble(Object key, int programPoint);
+
+ /**
+ * Get the value for a given key and return it as a double
+ * @param key the key
++ * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
+ * @return the value
+ */
+- public double getDouble(double key);
++ public double getDouble(double key, int programPoint);
+
+ /**
+ * Get the value for a given key and return it as a double
+ * @param key the key
++ * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
+ * @return the value
+ */
+- public double getDouble(long key);
++ public double getDouble(long key, int programPoint);
+
+ /**
+ * Get the value for a given key and return it as a double
+ * @param key the key
++ * @param programPoint or INVALID_PROGRAM_POINT if pessimistic
+ * @return the value
+ */
+- public double getDouble(int key);
++ public double getDouble(int key, int programPoint);
+
+ /**
+ * Get the value for a given key and return it as an Object
+@@ -151,129 +163,129 @@
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(Object key, int value, boolean strict);
++ public void set(Object key, int value, int flags);
+
+ /**
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(Object key, long value, boolean strict);
++ public void set(Object key, long value, int flags);
+
+ /**
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(Object key, double value, boolean strict);
++ public void set(Object key, double value, int flags);
+
+ /**
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(Object key, Object value, boolean strict);
++ public void set(Object key, Object value, int flags);
+
+ /**
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(double key, int value, boolean strict);
++ public void set(double key, int value, int flags);
+
+ /**
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(double key, long value, boolean strict);
++ public void set(double key, long value, int flags);
+
+ /**
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(double key, double value, boolean strict);
++ public void set(double key, double value, int flags);
+
+ /**
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(double key, Object value, boolean strict);
++ public void set(double key, Object value, int flags);
+
+ /**
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(long key, int value, boolean strict);
++ public void set(long key, int value, int flags);
+
+ /**
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(long key, long value, boolean strict);
++ public void set(long key, long value, int flags);
+
+ /**
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(long key, double value, boolean strict);
++ public void set(long key, double value, int flags);
+
+ /**
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(long key, Object value, boolean strict);
++ public void set(long key, Object value, int flags);
+
+ /**
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(int key, int value, boolean strict);
++ public void set(int key, int value, int flags);
+
+ /**
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(int key, long value, boolean strict);
++ public void set(int key, long value, int flags);
+
+ /**
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(int key, double value, boolean strict);
++ public void set(int key, double value, int flags);
+
+ /**
+ * Set the value of a given key
+ * @param key the key
+ * @param value the value
+- * @param strict are we in strict mode
++ * @param flags call site flags
+ */
+- public void set(int key, Object value, boolean strict);
++ public void set(int key, Object value, int flags);
+
+ /**
+ * Check if the given key exists anywhere in the proto chain
+--- ./nashorn/src/jdk/nashorn/internal/runtime/PropertyDescriptor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/PropertyDescriptor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -154,8 +154,8 @@
+
+ /**
+ * Check existence and compare attributes of descriptors.
+- *
+- * @return true if every field of this desc exists in otherDesc and has the same value.
++ * @param otherDesc other descriptor to compare to
++ * @return true if every field of this descriptor exists in otherDesc and has the same value.
+ */
+ public boolean hasAndEquals(PropertyDescriptor otherDesc);
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/PropertyHashMap.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/PropertyHashMap.java Wed Feb 04 12:14:47 2015 -0800
+@@ -164,6 +164,19 @@
+ }
+
+ /**
++ * Clone a property map, replacing a property with a new one in the same place,
++ * which is important for property iterations if a property changes types
++ * @param property old property
++ * @param newProperty new property
++ * @return new property map
++ */
++ public PropertyHashMap immutableReplace(final Property property, final Property newProperty) {
++ assert property.getKey().equals(newProperty.getKey()) : "replacing properties with different keys: '" + property.getKey() + "' != '" + newProperty.getKey() + "'";
++ assert findElement(property.getKey()) != null : "replacing property that doesn't exist in map: '" + property.getKey() + "'";
++ return cloneMap().replaceNoClone(property.getKey(), newProperty);
++ }
++
++ /**
+ * Clone a {@link PropertyHashMap} and add a {@link Property}.
+ *
+ * @param property {@link Property} to add.
+@@ -289,7 +302,7 @@
+ * @return The bin index.
+ */
+ private static int binIndex(final Element[] bins, final String key) {
+- return key.hashCode() & (bins.length - 1);
++ return key.hashCode() & bins.length - 1;
+ }
+
+ /**
+@@ -301,7 +314,7 @@
+ */
+ private static int binsNeeded(final int n) {
+ // 50% padding
+- return 1 << (32 - Integer.numberOfLeadingZeros((n + (n >>> 1)) | (INITIAL_BINS - 1)));
++ return 1 << 32 - Integer.numberOfLeadingZeros(n + (n >>> 1) | INITIAL_BINS - 1);
+ }
+
+ /**
+@@ -327,8 +340,9 @@
+ final Element[] newBins = new Element[binSize];
+ for (Element element = list; element != null; element = element.getLink()) {
+ final Property property = element.getProperty();
+- final String key = property.getKey();
+- final int binIndex = binIndex(newBins, key);
++ final String key = property.getKey();
++ final int binIndex = binIndex(newBins, key);
++
+ newBins[binIndex] = new Element(newBins[binIndex], property);
+ }
+ return newBins;
+@@ -366,6 +380,11 @@
+ return null;
+ }
+
++
++ private PropertyHashMap cloneMap() {
++ return new PropertyHashMap(size, bins == null ? null : bins.clone(), list);
++ }
++
+ /**
+ * Clone {@link PropertyHashMap} to accommodate new size.
+ *
+@@ -385,6 +404,8 @@
+ return new PropertyHashMap(newSize, newBins, list);
+ }
+
++
++
+ /**
+ * Add a {@link Property} to a temporary {@link PropertyHashMap}, that has
+ * been already cloned. Removes duplicates if necessary.
+@@ -416,6 +437,18 @@
+ return new PropertyHashMap(newSize, bins, newList);
+ }
+
++ private PropertyHashMap replaceNoClone(final String key, final Property property) {
++ if (bins != null) {
++ final int binIndex = binIndex(bins, key);
++ Element bin = bins[binIndex];
++ bin = replaceInList(bin, key, property);
++ bins[binIndex] = bin;
++ }
++ Element newList = list;
++ newList = replaceInList(newList, key, property);
++ return new PropertyHashMap(size, bins, newList);
++ }
++
+ /**
+ * Removes an {@link Element} from a specific list, avoiding duplication.
+ *
+@@ -446,6 +479,30 @@
+ return list;
+ }
+
++ // for element x. if x get link matches,
++ private static Element replaceInList(final Element list, final String key, final Property property) {
++ assert list != null;
++ final int hashCode = key.hashCode();
++
++ if (list.match(key, hashCode)) {
++ return new Element(list.getLink(), property);
++ }
++
++ final Element head = new Element(null, list.getProperty());
++ Element previous = head;
++ for (Element element = list.getLink(); element != null; element = element.getLink()) {
++ if (element.match(key, hashCode)) {
++ previous.setLink(new Element(element.getLink(), property));
++ return head;
++ }
++ final Element next = new Element(null, element.getProperty());
++ previous.setLink(next);
++ previous = next;
++ }
++ return list;
++ }
++
++
+ /*
+ * Map implementation
+ */
+@@ -617,6 +674,26 @@
+ throw new UnsupportedOperationException("Immutable map.");
+ }
+
++ @Override
++ public String toString() {
++ final StringBuffer sb = new StringBuffer();
++
++ sb.append('[');
++
++ Element elem = this;
++ do {
++ sb.append(elem.getValue());
++ elem = elem.link;
++ if (elem != null) {
++ sb.append(" -> ");
++ }
++ } while (elem != null);
++
++ sb.append(']');
++
++ return sb.toString();
++ }
++
+ /*
+ * Accessors
+ */
+--- ./nashorn/src/jdk/nashorn/internal/runtime/PropertyListeners.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/PropertyListeners.java Wed Feb 04 12:14:47 2015 -0800
+@@ -111,7 +111,7 @@
+ if (listeners == null) {
+ return false;
+ }
+- WeakPropertyMapSet set = listeners.get(key);
++ final WeakPropertyMapSet set = listeners.get(key);
+ return set != null && set.contains(propertyMap);
+ }
+
+@@ -145,9 +145,9 @@
+ */
+ public synchronized void propertyAdded(final Property prop) {
+ if (listeners != null) {
+- WeakPropertyMapSet set = listeners.get(prop.getKey());
++ final WeakPropertyMapSet set = listeners.get(prop.getKey());
+ if (set != null) {
+- for (PropertyMap propertyMap : set.elements()) {
++ for (final PropertyMap propertyMap : set.elements()) {
+ propertyMap.propertyAdded(prop);
+ }
+ listeners.remove(prop.getKey());
+@@ -162,9 +162,9 @@
+ */
+ public synchronized void propertyDeleted(final Property prop) {
+ if (listeners != null) {
+- WeakPropertyMapSet set = listeners.get(prop.getKey());
++ final WeakPropertyMapSet set = listeners.get(prop.getKey());
+ if (set != null) {
+- for (PropertyMap propertyMap : set.elements()) {
++ for (final PropertyMap propertyMap : set.elements()) {
+ propertyMap.propertyDeleted(prop);
+ }
+ listeners.remove(prop.getKey());
+@@ -181,9 +181,9 @@
+ */
+ public synchronized void propertyModified(final Property oldProp, final Property newProp) {
+ if (listeners != null) {
+- WeakPropertyMapSet set = listeners.get(oldProp.getKey());
++ final WeakPropertyMapSet set = listeners.get(oldProp.getKey());
+ if (set != null) {
+- for (PropertyMap propertyMap : set.elements()) {
++ for (final PropertyMap propertyMap : set.elements()) {
+ propertyMap.propertyModified(oldProp, newProp);
+ }
+ listeners.remove(oldProp.getKey());
+@@ -191,10 +191,13 @@
+ }
+ }
+
++ /**
++ * Callback for when a proto is changed
++ */
+ public synchronized void protoChanged() {
+ if (listeners != null) {
+- for (WeakPropertyMapSet set : listeners.values()) {
+- for (PropertyMap propertyMap : set.elements()) {
++ for (final WeakPropertyMapSet set : listeners.values()) {
++ for (final PropertyMap propertyMap : set.elements()) {
+ propertyMap.protoChanged();
+ }
+ }
+@@ -204,7 +207,7 @@
+
+ private static class WeakPropertyMapSet {
+
+- private WeakHashMap<PropertyMap, Boolean> map = new WeakHashMap<>();
++ private final WeakHashMap<PropertyMap, Boolean> map = new WeakHashMap<>();
+
+ void add(final PropertyMap propertyMap) {
+ map.put(propertyMap, Boolean.TRUE);
+--- ./nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java Wed Feb 04 12:14:47 2015 -0800
+@@ -36,6 +36,7 @@
+ import java.lang.invoke.SwitchPoint;
+ import java.lang.ref.SoftReference;
+ import java.util.Arrays;
++import java.util.BitSet;
+ import java.util.Collection;
+ import java.util.HashMap;
+ import java.util.Iterator;
+@@ -68,7 +69,7 @@
+ private int fieldCount;
+
+ /** Number of fields available. */
+- private int fieldMaximum;
++ private final int fieldMaximum;
+
+ /** Length of spill in use. */
+ private int spillLength;
+@@ -83,11 +84,13 @@
+ private transient WeakHashMap<Property, SoftReference<PropertyMap>> history;
+
+ /** History of prototypes, used to limit map duplication. */
+- private transient WeakHashMap<PropertyMap, SoftReference<PropertyMap>> protoHistory;
++ private transient WeakHashMap<ScriptObject, SoftReference<PropertyMap>> protoHistory;
+
+ /** property listeners */
+ private transient PropertyListeners listeners;
+
++ private transient BitSet freeSlots;
++
+ private static final long serialVersionUID = -7041836752008732533L;
+
+ /**
+@@ -129,6 +132,7 @@
+ this.fieldMaximum = propertyMap.fieldMaximum;
+ // We inherit the parent property listeners instance. It will be cloned when a new listener is added.
+ this.listeners = propertyMap.listeners;
++ this.freeSlots = propertyMap.freeSlots;
+
+ if (Context.DEBUG) {
+ count++;
+@@ -145,21 +149,6 @@
+ this(propertyMap, propertyMap.properties);
+ }
+
+- /**
+- * Duplicates this PropertyMap instance. This is used to duplicate 'shared'
+- * maps {@link PropertyMap} used as process wide singletons. Shared maps are
+- * duplicated for every global scope object. That way listeners, proto and property
+- * histories are scoped within a global scope.
+- *
+- * @return Duplicated {@link PropertyMap}.
+- */
+- public PropertyMap duplicate() {
+- if (Context.DEBUG) {
+- duplicatedCount++;
+- }
+- return new PropertyMap(this.properties, this.className, 0, 0, 0, containsArrayKeys());
+- }
+-
+ private void writeObject(final ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ out.writeObject(properties.getProperties());
+@@ -173,7 +162,7 @@
+
+ assert className != null;
+ final Class<?> structure = Context.forStructureClass(className);
+- for (Property prop : props) {
++ for (final Property prop : props) {
+ prop.initMethodHandles(structure);
+ }
+ }
+@@ -185,13 +174,14 @@
+ * properties with keys that are valid array indices.</p>
+ *
+ * @param properties Collection of initial properties.
++ * @param className class name
+ * @param fieldCount Number of fields in use.
+ * @param fieldMaximum Number of fields available.
+ * @param spillLength Number of used spill slots.
+ * @return New {@link PropertyMap}.
+ */
+ public static PropertyMap newMap(final Collection<Property> properties, final String className, final int fieldCount, final int fieldMaximum, final int spillLength) {
+- PropertyHashMap newProperties = EMPTY_HASHMAP.immutableAdd(properties);
++ final PropertyHashMap newProperties = EMPTY_HASHMAP.immutableAdd(properties);
+ return new PropertyMap(newProperties, className, fieldCount, fieldMaximum, spillLength, false);
+ }
+
+@@ -205,7 +195,7 @@
+ * @return New {@link PropertyMap}.
+ */
+ public static PropertyMap newMap(final Collection<Property> properties) {
+- return (properties == null || properties.isEmpty())? newMap() : newMap(properties, JO.class.getName(), 0, 0, 0);
++ return properties == null || properties.isEmpty()? newMap() : newMap(properties, JO.class.getName(), 0, 0, 0);
+ }
+
+ /**
+@@ -364,6 +354,51 @@
+ return addPropertyNoHistory(new AccessorProperty(property, bindTo));
+ }
+
++ // Get a logical slot index for a property, with spill slot 0 starting at fieldMaximum.
++ private int logicalSlotIndex(final Property property) {
++ final int slot = property.getSlot();
++ if (slot < 0) {
++ return -1;
++ }
++ return property.isSpill() ? slot + fieldMaximum : slot;
++ }
++
++ // Update boundaries and flags after a property has been added
++ private void updateFlagsAndBoundaries(final Property newProperty) {
++ if(newProperty.isSpill()) {
++ spillLength = Math.max(spillLength, newProperty.getSlot() + 1);
++ } else {
++ fieldCount = Math.max(fieldCount, newProperty.getSlot() + 1);
++ }
++ if (isValidArrayIndex(getArrayIndex(newProperty.getKey()))) {
++ setContainsArrayKeys();
++ }
++ }
++
++ // Update the free slots bitmap for a property that has been deleted and/or added.
++ private void updateFreeSlots(final Property oldProperty, final Property newProperty) {
++ // Free slots bitset is possibly shared with parent map, so we must clone it before making modifications.
++ boolean freeSlotsCloned = false;
++ if (oldProperty != null) {
++ final int slotIndex = logicalSlotIndex(oldProperty);
++ if (slotIndex >= 0) {
++ final BitSet newFreeSlots = freeSlots == null ? new BitSet() : (BitSet)freeSlots.clone();
++ assert !newFreeSlots.get(slotIndex);
++ newFreeSlots.set(slotIndex);
++ freeSlots = newFreeSlots;
++ freeSlotsCloned = true;
++ }
++ }
++ if (freeSlots != null && newProperty != null) {
++ final int slotIndex = logicalSlotIndex(newProperty);
++ if (slotIndex > -1 && freeSlots.get(slotIndex)) {
++ final BitSet newFreeSlots = freeSlotsCloned ? freeSlots : ((BitSet)freeSlots.clone());
++ newFreeSlots.clear(slotIndex);
++ freeSlots = newFreeSlots.isEmpty() ? null : newFreeSlots;
++ }
++ }
++ }
++
+ /**
+ * Add a property to the map without adding it to the history. This should be used for properties that
+ * can't be shared such as bound properties, or properties that are expected to be added only once.
+@@ -377,15 +412,9 @@
+ }
+ final PropertyHashMap newProperties = properties.immutableAdd(property);
+ final PropertyMap newMap = new PropertyMap(this, newProperties);
++ newMap.updateFlagsAndBoundaries(property);
++ newMap.updateFreeSlots(null, property);
+
+- if(!property.isSpill()) {
+- newMap.fieldCount = Math.max(newMap.fieldCount, property.getSlot() + 1);
+- }
+- if (isValidArrayIndex(getArrayIndex(property.getKey()))) {
+- newMap.setContainsArrayKeys();
+- }
+-
+- newMap.spillLength += property.getSpillCount();
+ return newMap;
+ }
+
+@@ -406,15 +435,8 @@
+ final PropertyHashMap newProperties = properties.immutableAdd(property);
+ newMap = new PropertyMap(this, newProperties);
+ addToHistory(property, newMap);
+-
+- if(!property.isSpill()) {
+- newMap.fieldCount = Math.max(newMap.fieldCount, property.getSlot() + 1);
+- }
+- if (isValidArrayIndex(getArrayIndex(property.getKey()))) {
+- newMap.setContainsArrayKeys();
+- }
+-
+- newMap.spillLength += property.getSpillCount();
++ newMap.updateFlagsAndBoundaries(property);
++ newMap.updateFreeSlots(null, property);
+ }
+
+ return newMap;
+@@ -436,7 +458,20 @@
+
+ if (newMap == null && properties.containsKey(key)) {
+ final PropertyHashMap newProperties = properties.immutableRemove(key);
+- newMap = new PropertyMap(this, newProperties);
++ final boolean isSpill = property.isSpill();
++ final int slot = property.getSlot();
++ // If deleted property was last field or spill slot we can make it reusable by reducing field/slot count.
++ // Otherwise mark it as free in free slots bitset.
++ if (isSpill && slot >= 0 && slot == spillLength - 1) {
++ newMap = new PropertyMap(newProperties, className, fieldCount, fieldMaximum, spillLength - 1, containsArrayKeys());
++ newMap.freeSlots = freeSlots;
++ } else if (!isSpill && slot >= 0 && slot == fieldCount - 1) {
++ newMap = new PropertyMap(newProperties, className, fieldCount - 1, fieldMaximum, spillLength, containsArrayKeys());
++ newMap.freeSlots = freeSlots;
++ } else {
++ newMap = new PropertyMap(this, newProperties);
++ newMap.updateFreeSlots(property, null);
++ }
+ addToHistory(property, newMap);
+ }
+
+@@ -456,9 +491,8 @@
+ listeners.propertyModified(oldProperty, newProperty);
+ }
+ // Add replaces existing property.
+- final PropertyHashMap newProperties = properties.immutableAdd(newProperty);
++ final PropertyHashMap newProperties = properties.immutableReplace(oldProperty, newProperty);
+ final PropertyMap newMap = new PropertyMap(this, newProperties);
+-
+ /*
+ * See ScriptObject.modifyProperty and ScriptObject.setUserAccessors methods.
+ *
+@@ -474,10 +508,11 @@
+ * the old property is an AccessorProperty and the new one is a UserAccessorProperty property.
+ */
+
+- final boolean sameType = (oldProperty.getClass() == newProperty.getClass());
++ final boolean sameType = oldProperty.getClass() == newProperty.getClass();
+ assert sameType ||
+- (oldProperty instanceof AccessorProperty &&
+- newProperty instanceof UserAccessorProperty) : "arbitrary replaceProperty attempted";
++ oldProperty instanceof AccessorProperty &&
++ newProperty instanceof UserAccessorProperty :
++ "arbitrary replaceProperty attempted " + sameType + " oldProperty=" + oldProperty.getClass() + " newProperty=" + newProperty.getClass() + " [" + oldProperty.getLocalType() + " => " + newProperty.getLocalType() + "]";
+
+ newMap.flags = flags;
+
+@@ -485,7 +520,10 @@
+ * spillLength remains same in case (1) and (2) because of slot reuse. Only for case (3), we need
+ * to add spill count of the newly added UserAccessorProperty property.
+ */
+- newMap.spillLength = spillLength + (sameType? 0 : newProperty.getSpillCount());
++ if (!sameType) {
++ newMap.spillLength = Math.max(spillLength, newProperty.getSlot() + 1);
++ newMap.updateFreeSlots(oldProperty, newProperty);
++ }
+ return newMap;
+ }
+
+@@ -500,12 +538,7 @@
+ * @return the newly created UserAccessorProperty
+ */
+ public UserAccessorProperty newUserAccessors(final String key, final int propertyFlags) {
+- int oldSpillLength = spillLength;
+-
+- final int getterSlot = oldSpillLength++;
+- final int setterSlot = oldSpillLength++;
+-
+- return new UserAccessorProperty(key, propertyFlags, getterSlot, setterSlot);
++ return new UserAccessorProperty(key, propertyFlags, getFreeSpillSlot());
+ }
+
+ /**
+@@ -533,10 +566,9 @@
+
+ final PropertyMap newMap = new PropertyMap(this, newProperties);
+ for (final Property property : otherProperties) {
+- if (isValidArrayIndex(getArrayIndex(property.getKey()))) {
+- newMap.setContainsArrayKeys();
+- }
+- newMap.spillLength += property.getSpillCount();
++ // This method is only safe to use with non-slotted, native getter/setter properties
++ assert property.getSlot() == -1;
++ assert !(isValidArrayIndex(getArrayIndex(property.getKey())));
+ }
+
+ return newMap;
+@@ -590,7 +622,7 @@
+ PropertyMap freeze() {
+ PropertyHashMap newProperties = EMPTY_HASHMAP;
+
+- for (Property oldProperty : properties.getProperties()) {
++ for (final Property oldProperty : properties.getProperties()) {
+ int propertyFlags = Property.NOT_CONFIGURABLE;
+
+ if (!(oldProperty instanceof UserAccessorProperty)) {
+@@ -645,14 +677,14 @@
+ /**
+ * Check prototype history for an existing property map with specified prototype.
+ *
+- * @param parentMap New prototype object.
++ * @param proto New prototype object.
+ *
+ * @return Existing {@link PropertyMap} or {@code null} if not found.
+ */
+- private PropertyMap checkProtoHistory(final PropertyMap parentMap) {
++ private PropertyMap checkProtoHistory(final ScriptObject proto) {
+ final PropertyMap cachedMap;
+ if (protoHistory != null) {
+- final SoftReference<PropertyMap> weakMap = protoHistory.get(parentMap);
++ final SoftReference<PropertyMap> weakMap = protoHistory.get(proto);
+ cachedMap = (weakMap != null ? weakMap.get() : null);
+ } else {
+ cachedMap = null;
+@@ -668,15 +700,15 @@
+ /**
+ * Add a map to the prototype history.
+ *
+- * @param parentMap Prototype to add (key.)
++ * @param newProto Prototype to add (key.)
+ * @param newMap {@link PropertyMap} associated with prototype.
+ */
+- private void addToProtoHistory(final PropertyMap parentMap, final PropertyMap newMap) {
++ private void addToProtoHistory(final ScriptObject newProto, final PropertyMap newMap) {
+ if (protoHistory == null) {
+ protoHistory = new WeakHashMap<>();
+ }
+
+- protoHistory.put(parentMap, new SoftReference<>(newMap));
++ protoHistory.put(newProto, new SoftReference<>(newMap));
+ }
+
+ /**
+@@ -686,13 +718,11 @@
+ * @param newMap Modified {@link PropertyMap}.
+ */
+ private void addToHistory(final Property property, final PropertyMap newMap) {
+- if (!properties.isEmpty()) {
+- if (history == null) {
+- history = new WeakHashMap<>();
+- }
++ if (history == null) {
++ history = new WeakHashMap<>();
++ }
+
+- history.put(property, new SoftReference<>(newMap));
+- }
++ history.put(property, new SoftReference<>(newMap));
+ }
+
+ /**
+@@ -705,7 +735,7 @@
+ private PropertyMap checkHistory(final Property property) {
+
+ if (history != null) {
+- SoftReference<PropertyMap> ref = history.get(property);
++ final SoftReference<PropertyMap> ref = history.get(property);
+ final PropertyMap historicMap = ref == null ? null : ref.get();
+
+ if (historicMap != null) {
+@@ -720,32 +750,44 @@
+ return null;
+ }
+
++ /**
++ * Returns true if the two maps have identical properties in the same order, but allows the properties to differ in
++ * their types. This method is mostly useful for tests.
++ * @param otherMap the other map
++ * @return true if this map has identical properties in the same order as the other map, allowing the properties to
++ * differ in type.
++ */
++ public boolean equalsWithoutType(final PropertyMap otherMap) {
++ if (properties.size() != otherMap.properties.size()) {
++ return false;
++ }
++
++ final Iterator<Property> iter = properties.values().iterator();
++ final Iterator<Property> otherIter = otherMap.properties.values().iterator();
++
++ while (iter.hasNext() && otherIter.hasNext()) {
++ if (!iter.next().equalsWithoutType(otherIter.next())) {
++ return false;
++ }
++ }
++
++ return true;
++ }
++
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+
+- sb.append(" [");
+- boolean isFirst = true;
++ sb.append(Debug.id(this));
++ sb.append(" = {\n");
+
+- for (final Property property : properties.values()) {
+- if (!isFirst) {
+- sb.append(", ");
+- }
+-
+- isFirst = false;
+-
+- sb.append(ScriptRuntime.safeToString(property.getKey()));
+- final Class<?> ctype = property.getCurrentType();
+- sb.append(" <").
+- append(property.getClass().getSimpleName()).
+- append(':').
+- append(ctype == null ?
+- "undefined" :
+- ctype.getSimpleName()).
+- append('>');
++ for (final Property property : getProperties()) {
++ sb.append('\t');
++ sb.append(property);
++ sb.append('\n');
+ }
+
+- sb.append(']');
++ sb.append('}');
+
+ return sb.toString();
+ }
+@@ -799,29 +841,37 @@
+ boolean isFrozen() {
+ return !isExtensible() && allFrozen();
+ }
++
+ /**
+- * Get the number of fields allocated for this {@link PropertyMap}.
++ * Return a free field slot for this map, or {@code -1} if none is available.
+ *
+- * @return Number of fields allocated.
++ * @return free field slot or -1
+ */
+- int getFieldCount() {
+- return fieldCount;
+- }
+- /**
+- * Get maximum number of fields available for this {@link PropertyMap}.
+- *
+- * @return Number of fields available.
+- */
+- int getFieldMaximum() {
+- return fieldMaximum;
++ int getFreeFieldSlot() {
++ if (freeSlots != null) {
++ final int freeSlot = freeSlots.nextSetBit(0);
++ if (freeSlot > -1 && freeSlot < fieldMaximum) {
++ return freeSlot;
++ }
++ }
++ if (fieldCount < fieldMaximum) {
++ return fieldCount;
++ }
++ return -1;
+ }
+
+ /**
+- * Get length of spill area associated with this {@link PropertyMap}.
++ * Get a free spill slot for this map.
+ *
+- * @return Length of spill area.
++ * @return free spill slot
+ */
+- int getSpillLength() {
++ int getFreeSpillSlot() {
++ if (freeSlots != null) {
++ final int freeSlot = freeSlots.nextSetBit(fieldMaximum);
++ if (freeSlot > -1) {
++ return freeSlot - fieldMaximum;
++ }
++ }
+ return spillLength;
+ }
+
+@@ -833,8 +883,7 @@
+ */
+ public PropertyMap changeProto(final ScriptObject newProto) {
+
+- final PropertyMap parentMap = newProto == null ? null : newProto.getMap();
+- final PropertyMap nextMap = checkProtoHistory(parentMap);
++ final PropertyMap nextMap = checkProtoHistory(newProto);
+ if (nextMap != null) {
+ return nextMap;
+ }
+@@ -844,7 +893,7 @@
+ }
+
+ final PropertyMap newMap = new PropertyMap(this);
+- addToProtoHistory(parentMap, newMap);
++ addToProtoHistory(newProto, newMap);
+
+ return newMap;
+ }
+@@ -900,7 +949,7 @@
+
+ @Override
+ public void remove() {
+- throw new UnsupportedOperationException();
++ throw new UnsupportedOperationException("remove");
+ }
+ }
+
+@@ -908,10 +957,60 @@
+ * Debugging and statistics.
+ */
+
++ /**
++ * Debug helper function that returns the diff of two property maps, only
++ * displaying the information that is different and in which map it exists
++ * compared to the other map. Can be used to e.g. debug map guards and
++ * investigate why they fail, causing relink
++ *
++ * @param map0 the first property map
++ * @param map1 the second property map
++ *
++ * @return property map diff as string
++ */
++ public static String diff(final PropertyMap map0, final PropertyMap map1) {
++ final StringBuilder sb = new StringBuilder();
++
++ if (map0 != map1) {
++ sb.append(">>> START: Map diff");
++ boolean found = false;
++
++ for (final Property p : map0.getProperties()) {
++ final Property p2 = map1.findProperty(p.getKey());
++ if (p2 == null) {
++ sb.append("FIRST ONLY : [" + p + "]");
++ found = true;
++ } else if (p2 != p) {
++ sb.append("DIFFERENT : [" + p + "] != [" + p2 + "]");
++ found = true;
++ }
++ }
++
++ for (final Property p2 : map1.getProperties()) {
++ final Property p1 = map0.findProperty(p2.getKey());
++ if (p1 == null) {
++ sb.append("SECOND ONLY: [" + p2 + "]");
++ found = true;
++ }
++ }
++
++ //assert found;
++
++ if (!found) {
++ sb.append(map0).
++ append("!=").
++ append(map1);
++ }
++
++ sb.append("<<< END: Map diff\n");
++ }
++
++ return sb.toString();
++ }
++
+ // counters updated only in debug mode
+ private static int count;
+ private static int clonedCount;
+- private static int duplicatedCount;
+ private static int historyHit;
+ private static int protoInvalidations;
+ private static int protoHistoryHit;
+@@ -932,13 +1031,6 @@
+ }
+
+ /**
+- * @return The number of maps that are duplicated.
+- */
+- public static int getDuplicatedCount() {
+- return duplicatedCount;
+- }
+-
+- /**
+ * @return The number of times history was successfully used.
+ */
+ public static int getHistoryHit() {
+@@ -965,5 +1057,4 @@
+ public static int getSetProtoNewMapCount() {
+ return setProtoNewMapCount;
+ }
+-
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Wed Feb 04 12:14:47 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -26,104 +26,231 @@
+ package jdk.nashorn.internal.runtime;
+
+ import static jdk.nashorn.internal.lookup.Lookup.MH;
+-
+-import java.io.Serializable;
++import java.io.IOException;
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+ import java.lang.invoke.MethodType;
+-import java.util.ArrayList;
+-import java.util.Arrays;
+-import java.util.LinkedList;
++import java.util.Collection;
++import java.util.Collections;
++import java.util.HashMap;
++import java.util.HashSet;
+ import java.util.Map;
++import java.util.Set;
++import java.util.TreeMap;
+ import jdk.internal.dynalink.support.NameCodec;
+ import jdk.nashorn.internal.codegen.Compiler;
++import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
+ import jdk.nashorn.internal.codegen.CompilerConstants;
+ import jdk.nashorn.internal.codegen.FunctionSignature;
++import jdk.nashorn.internal.codegen.Namespace;
++import jdk.nashorn.internal.codegen.ObjectClassGenerator.AllocatorDescriptor;
++import jdk.nashorn.internal.codegen.OptimisticTypesPersistence;
++import jdk.nashorn.internal.codegen.TypeMap;
+ import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.ir.FunctionNode;
+-import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
++import jdk.nashorn.internal.ir.LexicalContext;
++import jdk.nashorn.internal.ir.visitor.NodeVisitor;
++import jdk.nashorn.internal.objects.Global;
++import jdk.nashorn.internal.parser.Parser;
+ import jdk.nashorn.internal.parser.Token;
+ import jdk.nashorn.internal.parser.TokenType;
+-import jdk.nashorn.internal.scripts.JS;
+-
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
+ /**
+ * This is a subclass that represents a script function that may be regenerated,
+ * for example with specialization based on call site types, or lazily generated.
+ * The common denominator is that it can get new invokers during its lifespan,
+ * unlike {@code FinalScriptFunctionData}
+ */
+-public final class RecompilableScriptFunctionData extends ScriptFunctionData implements Serializable {
++@Logger(name="recompile")
++public final class RecompilableScriptFunctionData extends ScriptFunctionData implements Loggable {
++ /** Prefix used for all recompiled script classes */
++ public static final String RECOMPILATION_PREFIX = "Recompilation$";
+
+- /** FunctionNode with the code for this ScriptFunction */
+- private transient FunctionNode functionNode;
++ /** Unique function node id for this function node */
++ private final int functionNodeId;
++
++ private final String functionName;
++
++ /** The line number where this function begins. */
++ private final int lineNumber;
+
+ /** Source from which FunctionNode was parsed. */
+ private transient Source source;
+
+- /** The line number where this function begins. */
+- private final int lineNumber;
+-
+- /** Allows us to retrieve the method handle for this function once the code is compiled */
+- private MethodLocator methodLocator;
++ /** Serialized, compressed form of the AST. Used by split functions as they can't be reparsed from source. */
++ private final byte[] serializedAst;
+
+ /** Token of this function within the source. */
+ private final long token;
+
+- /** Allocator map from makeMap() */
+- private final PropertyMap allocatorMap;
++ /**
++ * Represents the allocation strategy (property map, script object class, and method handle) for when
++ * this function is used as a constructor. Note that majority of functions (those not setting any this.*
++ * properties) will share a single canonical "default strategy" instance.
++ */
++ private final AllocationStrategy allocationStrategy;
++
++ /**
++ * Opaque object representing parser state at the end of the function. Used when reparsing outer function
++ * to help with skipping parsing inner functions.
++ */
++ private final Object endParserState;
+
+ /** Code installer used for all further recompilation/specialization of this ScriptFunction */
+ private transient CodeInstaller<ScriptEnvironment> installer;
+
+- /** Name of class where allocator function resides */
+- private final String allocatorClassName;
++ private final Map<Integer, RecompilableScriptFunctionData> nestedFunctions;
+
+- /** lazily generated allocator */
+- private transient MethodHandle allocator;
++ /** Id to parent function if one exists */
++ private RecompilableScriptFunctionData parent;
++
++ /** Copy of the {@link FunctionNode} flags. */
++ private final int functionFlags;
+
+ private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+
+- /**
+- * Used for specialization based on runtime arguments. Whenever we specialize on
+- * callsite parameter types at runtime, we need to use a parameter type guard to
+- * ensure that the specialized version of the script function continues to be
+- * applicable for a particular callsite.
+- */
+- private static final MethodHandle PARAM_TYPE_GUARD = findOwnMH("paramTypeGuard", boolean.class, Type[].class, Object[].class);
++ private transient DebugLogger log;
+
+- /**
+- * It is usually a good gamble whever we detect a runtime callsite with a double
+- * (or java.lang.Number instance) to specialize the parameter to an integer, if the
+- * parameter in question can be represented as one. The double typically only exists
+- * because the compiler doesn't know any better than "a number type" and conservatively
+- * picks doubles when it can't prove that an integer addition wouldn't overflow.
+- */
+- private static final MethodHandle ENSURE_INT = findOwnMH("ensureInt", int.class, Object.class);
++ private final Map<String, Integer> externalScopeDepths;
++
++ private final Set<String> internalSymbols;
++
++ private static final int GET_SET_PREFIX_LENGTH = "*et ".length();
+
+ private static final long serialVersionUID = 4914839316174633726L;
+
+ /**
+ * Constructor - public as scripts use it
+ *
+- * @param functionNode functionNode that represents this function code
+- * @param installer installer for code regeneration versions of this function
+- * @param allocatorClassName name of our allocator class, will be looked up dynamically if used as a constructor
+- * @param allocatorMap allocator map to seed instances with, when constructing
++ * @param functionNode functionNode that represents this function code
++ * @param installer installer for code regeneration versions of this function
++ * @param allocationDescriptor descriptor for the allocation behavior when this function is used as a constructor
++ * @param nestedFunctions nested function map
++ * @param externalScopeDepths external scope depths
++ * @param internalSymbols internal symbols to method, defined in its scope
++ * @param serializedAst a serialized AST representation. Normally only used for split functions.
+ */
+- public RecompilableScriptFunctionData(final FunctionNode functionNode, final CodeInstaller<ScriptEnvironment> installer, final String allocatorClassName, final PropertyMap allocatorMap) {
++ public RecompilableScriptFunctionData(
++ final FunctionNode functionNode,
++ final CodeInstaller<ScriptEnvironment> installer,
++ final AllocatorDescriptor allocationDescriptor,
++ final Map<Integer, RecompilableScriptFunctionData> nestedFunctions,
++ final Map<String, Integer> externalScopeDepths,
++ final Set<String> internalSymbols,
++ final byte[] serializedAst) {
++
+ super(functionName(functionNode),
+- functionNode.getParameters().size(),
+- getFlags(functionNode));
+- this.functionNode = functionNode;
+- this.source = functionNode.getSource();
+- this.lineNumber = functionNode.getLineNumber();
+- this.token = tokenFor(functionNode);
+- this.installer = installer;
+- this.allocatorClassName = allocatorClassName;
+- this.allocatorMap = allocatorMap;
+- if (!functionNode.isLazy()) {
+- methodLocator = new MethodLocator(functionNode);
++ Math.min(functionNode.getParameters().size(), MAX_ARITY),
++ getDataFlags(functionNode));
++
++ this.functionName = functionNode.getName();
++ this.lineNumber = functionNode.getLineNumber();
++ this.functionFlags = functionNode.getFlags() | (functionNode.needsCallee() ? FunctionNode.NEEDS_CALLEE : 0);
++ this.functionNodeId = functionNode.getId();
++ this.source = functionNode.getSource();
++ this.endParserState = functionNode.getEndParserState();
++ this.token = tokenFor(functionNode);
++ this.installer = installer;
++ this.allocationStrategy = AllocationStrategy.get(allocationDescriptor);
++ this.nestedFunctions = smallMap(nestedFunctions);
++ this.externalScopeDepths = smallMap(externalScopeDepths);
++ this.internalSymbols = smallSet(new HashSet<>(internalSymbols));
++
++ for (final RecompilableScriptFunctionData nfn : nestedFunctions.values()) {
++ assert nfn.getParent() == null;
++ nfn.setParent(this);
+ }
++
++ this.serializedAst = serializedAst;
++ createLogger();
++ }
++
++ private static <K, V> Map<K, V> smallMap(final Map<K, V> map) {
++ if (map == null || map.isEmpty()) {
++ return Collections.emptyMap();
++ } else if (map.size() == 1) {
++ final Map.Entry<K, V> entry = map.entrySet().iterator().next();
++ return Collections.singletonMap(entry.getKey(), entry.getValue());
++ } else {
++ return map;
++ }
++ }
++
++ private static <T> Set<T> smallSet(final Set<T> set) {
++ if (set == null || set.isEmpty()) {
++ return Collections.emptySet();
++ } else if (set.size() == 1) {
++ return Collections.singleton(set.iterator().next());
++ } else {
++ return set;
++ }
++ }
++
++ @Override
++ public DebugLogger getLogger() {
++ return log;
++ }
++
++ @Override
++ public DebugLogger initLogger(final Context ctxt) {
++ return ctxt.getLogger(this.getClass());
++ }
++
++ /**
++ * Check if a symbol is internally defined in a function. For example
++ * if "undefined" is internally defined in the outermost program function,
++ * it has not been reassigned or overridden and can be optimized
++ *
++ * @param symbolName symbol name
++ * @return true if symbol is internal to this ScriptFunction
++ */
++
++ public boolean hasInternalSymbol(final String symbolName) {
++ return internalSymbols.contains(symbolName);
++ }
++
++ /**
++ * Return the external symbol table
++ * @param symbolName symbol name
++ * @return the external symbol table with proto depths
++ */
++ public int getExternalSymbolDepth(final String symbolName) {
++ final Integer depth = externalScopeDepths.get(symbolName);
++ return depth == null ? -1 : depth;
++ }
++
++ /**
++ * Returns the names of all external symbols this function uses.
++ * @return the names of all external symbols this function uses.
++ */
++ public Set<String> getExternalSymbolNames() {
++ return Collections.unmodifiableSet(externalScopeDepths.keySet());
++ }
++
++ /**
++ * Returns the opaque object representing the parser state at the end of this function's body, used to
++ * skip parsing this function when reparsing its containing outer function.
++ * @return the object representing the end parser state
++ */
++ public Object getEndParserState() {
++ return endParserState;
++ }
++
++ /**
++ * Get the parent of this RecompilableScriptFunctionData. If we are
++ * a nested function, we have a parent. Note that "null" return value
++ * can also mean that we have a parent but it is unknown, so this can
++ * only be used for conservative assumptions.
++ * @return parent data, or null if non exists and also null IF UNKNOWN.
++ */
++ public RecompilableScriptFunctionData getParent() {
++ return parent;
++ }
++
++ void setParent(final RecompilableScriptFunctionData parent) {
++ this.parent = parent;
+ }
+
+ @Override
+@@ -135,46 +262,75 @@
+ return "function " + (name == null ? "" : name) + "() { [native code] }";
+ }
+
+- public void setCodeAndSource(final Map<String, Class<?>> code, final Source source) {
+- this.source = source;
+- if (methodLocator != null) {
+- methodLocator.setClass(code.get(methodLocator.getClassName()));
++ /**
++ * Initialize transient fields on deserialized instances
++ *
++ * @param src source
++ * @param inst code installer
++ */
++ public void initTransients(final Source src, final CodeInstaller<ScriptEnvironment> inst) {
++ if (this.source == null && this.installer == null) {
++ this.source = src;
++ this.installer = inst;
++ } else if (this.source != src || !this.installer.isCompatibleWith(inst)) {
++ // Existing values must be same as those passed as parameters
++ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public String toString() {
++ return super.toString() + '@' + functionNodeId;
++ }
++
++ @Override
++ public String toStringVerbose() {
+ final StringBuilder sb = new StringBuilder();
+
++ sb.append("fnId=").append(functionNodeId).append(' ');
++
+ if (source != null) {
+- sb.append(source.getName()).append(':').append(lineNumber).append(' ');
++ sb.append(source.getName())
++ .append(':')
++ .append(lineNumber)
++ .append(' ');
+ }
+
+ return sb.toString() + super.toString();
+ }
+
++ @Override
++ public String getFunctionName() {
++ return functionName;
++ }
++
++ @Override
++ public boolean inDynamicContext() {
++ return getFunctionFlag(FunctionNode.IN_DYNAMIC_CONTEXT);
++ }
++
+ private static String functionName(final FunctionNode fn) {
+ if (fn.isAnonymous()) {
+ return "";
+- } else {
+- final FunctionNode.Kind kind = fn.getKind();
+- if (kind == FunctionNode.Kind.GETTER || kind == FunctionNode.Kind.SETTER) {
+- final String name = NameCodec.decode(fn.getIdent().getName());
+- return name.substring(4); // 4 is "get " or "set "
+- } else {
+- return fn.getIdent().getName();
+- }
+ }
++ final FunctionNode.Kind kind = fn.getKind();
++ if (kind == FunctionNode.Kind.GETTER || kind == FunctionNode.Kind.SETTER) {
++ final String name = NameCodec.decode(fn.getIdent().getName());
++ return name.substring(GET_SET_PREFIX_LENGTH);
++ }
++ return fn.getIdent().getName();
+ }
+
+ private static long tokenFor(final FunctionNode fn) {
+- final int position = Token.descPosition(fn.getFirstToken());
+- final int length = Token.descPosition(fn.getLastToken()) - position + Token.descLength(fn.getLastToken());
++ final int position = Token.descPosition(fn.getFirstToken());
++ final long lastToken = Token.withDelimiter(fn.getLastToken());
++ // EOL uses length field to store the line number
++ final int length = Token.descPosition(lastToken) - position + (Token.descType(lastToken) == TokenType.EOL ? 0 : Token.descLength(lastToken));
+
+ return Token.toDesc(TokenType.FUNCTION, position, length);
+ }
+
+- private static int getFlags(final FunctionNode functionNode) {
++ private static int getDataFlags(final FunctionNode functionNode) {
+ int flags = IS_CONSTRUCTOR;
+ if (functionNode.isStrict()) {
+ flags |= IS_STRICT;
+@@ -185,327 +341,540 @@
+ if (functionNode.usesThis() || functionNode.hasEval()) {
+ flags |= USES_THIS;
+ }
++ if (functionNode.isVarArg()) {
++ flags |= IS_VARIABLE_ARITY;
++ }
+ return flags;
+ }
+
+ @Override
++ PropertyMap getAllocatorMap() {
++ return allocationStrategy.getAllocatorMap();
++ }
++
++ @Override
+ ScriptObject allocate(final PropertyMap map) {
++ return allocationStrategy.allocate(map);
++ }
++
++ boolean isSerialized() {
++ return serializedAst != null;
++ }
++
++ FunctionNode reparse() {
++ if (isSerialized()) {
++ return deserialize();
++ }
++
++ final int descPosition = Token.descPosition(token);
++ final Context context = Context.getContextTrusted();
++ final Parser parser = new Parser(
++ context.getEnv(),
++ source,
++ new Context.ThrowErrorManager(),
++ isStrict(),
++ // source starts at line 0, so even though lineNumber is the correct declaration line, back off
++ // one to make it exclusive
++ lineNumber - 1,
++ context.getLogger(Parser.class));
++
++ if (getFunctionFlag(FunctionNode.IS_ANONYMOUS)) {
++ parser.setFunctionName(functionName);
++ }
++ parser.setReparsedFunction(this);
++
++ final FunctionNode program = parser.parse(CompilerConstants.PROGRAM.symbolName(), descPosition,
++ Token.descLength(token), true);
++ // Parser generates a program AST even if we're recompiling a single function, so when we are only
++ // recompiling a single function, extract it from the program.
++ return (isProgram() ? program : extractFunctionFromScript(program)).setName(null, functionName);
++ }
++
++ private FunctionNode deserialize() {
++ final ScriptEnvironment env = installer.getOwner();
++ final Timing timing = env._timing;
++ final long t1 = System.nanoTime();
+ try {
+- ensureHasAllocator(); //if allocatorClass name is set to null (e.g. for bound functions) we don't even try
+- return allocator == null ? null : (ScriptObject)allocator.invokeExact(map);
+- } catch (final RuntimeException | Error e) {
+- throw e;
+- } catch (final Throwable t) {
+- throw new RuntimeException(t);
++ return AstDeserializer.deserialize(serializedAst).initializeDeserialized(source, new Namespace(env.getNamespace()));
++ } finally {
++ timing.accumulateTime("'Deserialize'", System.nanoTime() - t1);
+ }
+ }
+
+- private void ensureHasAllocator() throws ClassNotFoundException {
+- if (allocator == null && allocatorClassName != null) {
+- this.allocator = MH.findStatic(LOOKUP, Context.forStructureClass(allocatorClassName), CompilerConstants.ALLOCATE.symbolName(), MH.type(ScriptObject.class, PropertyMap.class));
++ private boolean getFunctionFlag(final int flag) {
++ return (functionFlags & flag) != 0;
++ }
++
++ private boolean isProgram() {
++ return getFunctionFlag(FunctionNode.IS_PROGRAM);
++ }
++
++ TypeMap typeMap(final MethodType fnCallSiteType) {
++ if (fnCallSiteType == null) {
++ return null;
++ }
++
++ if (CompiledFunction.isVarArgsType(fnCallSiteType)) {
++ return null;
++ }
++
++ return new TypeMap(functionNodeId, explicitParams(fnCallSiteType), needsCallee());
++ }
++
++ private static ScriptObject newLocals(final ScriptObject runtimeScope) {
++ final ScriptObject locals = Global.newEmptyInstance();
++ locals.setProto(runtimeScope);
++ return locals;
++ }
++
++ private Compiler getCompiler(final FunctionNode fn, final MethodType actualCallSiteType, final ScriptObject runtimeScope) {
++ return getCompiler(fn, actualCallSiteType, newLocals(runtimeScope), null, null);
++ }
++
++ /**
++ * Returns a code installer for installing new code. If we're using either optimistic typing or loader-per-compile,
++ * then asks for a code installer with a new class loader; otherwise just uses the current installer. We use
++ * a new class loader with optimistic typing so that deoptimized code can get reclaimed by GC.
++ * @return a code installer for installing new code.
++ */
++ private CodeInstaller<ScriptEnvironment> getInstallerForNewCode() {
++ final ScriptEnvironment env = installer.getOwner();
++ return env._optimistic_types || env._loader_per_compile ? installer.withNewLoader() : installer;
++ }
++
++ Compiler getCompiler(final FunctionNode functionNode, final MethodType actualCallSiteType,
++ final ScriptObject runtimeScope, final Map<Integer, Type> invalidatedProgramPoints,
++ final int[] continuationEntryPoints) {
++ final TypeMap typeMap = typeMap(actualCallSiteType);
++ final Type[] paramTypes = typeMap == null ? null : typeMap.getParameterTypes(functionNodeId);
++ final Object typeInformationFile = OptimisticTypesPersistence.getLocationDescriptor(source, functionNodeId, paramTypes);
++ final Context context = Context.getContextTrusted();
++ return new Compiler(
++ context,
++ context.getEnv(),
++ getInstallerForNewCode(),
++ functionNode.getSource(), // source
++ context.getErrorManager(),
++ isStrict() | functionNode.isStrict(), // is strict
++ true, // is on demand
++ this, // compiledFunction, i.e. this RecompilableScriptFunctionData
++ typeMap, // type map
++ getEffectiveInvalidatedProgramPoints(invalidatedProgramPoints, typeInformationFile), // invalidated program points
++ typeInformationFile,
++ continuationEntryPoints, // continuation entry points
++ runtimeScope); // runtime scope
++ }
++
++ /**
++ * If the function being compiled already has its own invalidated program points map, use it. Otherwise, attempt to
++ * load invalidated program points map from the persistent type info cache.
++ * @param invalidatedProgramPoints the function's current invalidated program points map. Null if the function
++ * doesn't have it.
++ * @param typeInformationFile the object describing the location of the persisted type information.
++ * @return either the existing map, or a loaded map from the persistent type info cache, or a new empty map if
++ * neither an existing map or a persistent cached type info is available.
++ */
++ @SuppressWarnings("unused")
++ private static Map<Integer, Type> getEffectiveInvalidatedProgramPoints(
++ final Map<Integer, Type> invalidatedProgramPoints, final Object typeInformationFile) {
++ if(invalidatedProgramPoints != null) {
++ return invalidatedProgramPoints;
++ }
++ final Map<Integer, Type> loadedProgramPoints = OptimisticTypesPersistence.load(typeInformationFile);
++ return loadedProgramPoints != null ? loadedProgramPoints : new TreeMap<Integer, Type>();
++ }
++
++ private FunctionInitializer compileTypeSpecialization(final MethodType actualCallSiteType, final ScriptObject runtimeScope, final boolean persist) {
++ // We're creating an empty script object for holding local variables. AssignSymbols will populate it with
++ // explicit Undefined values for undefined local variables (see AssignSymbols#defineSymbol() and
++ // CompilationEnvironment#declareLocalSymbol()).
++
++ if (log.isEnabled()) {
++ log.info("Parameter type specialization of '", functionName, "' signature: ", actualCallSiteType);
++ }
++
++ final boolean persistentCache = usePersistentCodeCache() && persist;
++ String cacheKey = null;
++ if (persistentCache) {
++ final TypeMap typeMap = typeMap(actualCallSiteType);
++ final Type[] paramTypes = typeMap == null ? null : typeMap.getParameterTypes(functionNodeId);
++ cacheKey = CodeStore.getCacheKey(functionNodeId, paramTypes);
++ final CodeInstaller<ScriptEnvironment> newInstaller = getInstallerForNewCode();
++ final StoredScript script = newInstaller.loadScript(source, cacheKey);
++
++ if (script != null) {
++ Compiler.updateCompilationId(script.getCompilationId());
++ return installStoredScript(script, newInstaller);
++ }
++ }
++
++ final FunctionNode fn = reparse();
++ final Compiler compiler = getCompiler(fn, actualCallSiteType, runtimeScope);
++ final FunctionNode compiledFn = compiler.compile(fn,
++ isSerialized() ? CompilationPhases.COMPILE_ALL_SERIALIZED : CompilationPhases.COMPILE_ALL);
++
++ if (persist && !compiledFn.getFlag(FunctionNode.HAS_APPLY_TO_CALL_SPECIALIZATION)) {
++ compiler.persistClassInfo(cacheKey, compiledFn);
++ }
++ return new FunctionInitializer(compiledFn, compiler.getInvalidatedProgramPoints());
++ }
++
++ private static Map<String, Class<?>> installStoredScriptClasses(final StoredScript script, final CodeInstaller<ScriptEnvironment> installer) {
++ final Map<String, Class<?>> installedClasses = new HashMap<>();
++ final Map<String, byte[]> classBytes = script.getClassBytes();
++ final String mainClassName = script.getMainClassName();
++ final byte[] mainClassBytes = classBytes.get(mainClassName);
++
++ final Class<?> mainClass = installer.install(mainClassName, mainClassBytes);
++
++ installedClasses.put(mainClassName, mainClass);
++
++ for (final Map.Entry<String, byte[]> entry : classBytes.entrySet()) {
++ final String className = entry.getKey();
++ final byte[] bytecode = entry.getValue();
++
++ if (className.equals(mainClassName)) {
++ continue;
++ }
++
++ installedClasses.put(className, installer.install(className, bytecode));
++ }
++ return installedClasses;
++ }
++
++ /**
++ * Install this script using the given {@code installer}.
++ *
++ * @param script the compiled script
++ * @return the function initializer
++ */
++ private FunctionInitializer installStoredScript(final StoredScript script, final CodeInstaller<ScriptEnvironment> newInstaller) {
++ final Map<String, Class<?>> installedClasses = installStoredScriptClasses(script, newInstaller);
++
++ final Map<Integer, FunctionInitializer> initializers = script.getInitializers();
++ assert initializers != null;
++ assert initializers.size() == 1;
++ final FunctionInitializer initializer = initializers.values().iterator().next();
++
++ final Object[] constants = script.getConstants();
++ for (int i = 0; i < constants.length; i++) {
++ if (constants[i] instanceof RecompilableScriptFunctionData) {
++ // replace deserialized function data with the ones we already have
++ constants[i] = getScriptFunctionData(((RecompilableScriptFunctionData) constants[i]).getFunctionNodeId());
++ }
++ }
++
++ newInstaller.initialize(installedClasses.values(), source, constants);
++ initializer.setCode(installedClasses.get(initializer.getClassName()));
++ return initializer;
++ }
++
++ boolean usePersistentCodeCache() {
++ final ScriptEnvironment env = installer.getOwner();
++ return env._persistent_cache && env._optimistic_types;
++ }
++
++ private MethodType explicitParams(final MethodType callSiteType) {
++ if (CompiledFunction.isVarArgsType(callSiteType)) {
++ return null;
++ }
++
++ final MethodType noCalleeThisType = callSiteType.dropParameterTypes(0, 2); // (callee, this) is always in call site type
++ final int callSiteParamCount = noCalleeThisType.parameterCount();
++
++ // Widen parameters of reference types to Object as we currently don't care for specialization among reference
++ // types. E.g. call site saying (ScriptFunction, Object, String) should still link to (ScriptFunction, Object, Object)
++ final Class<?>[] paramTypes = noCalleeThisType.parameterArray();
++ boolean changed = false;
++ for (int i = 0; i < paramTypes.length; ++i) {
++ final Class<?> paramType = paramTypes[i];
++ if (!(paramType.isPrimitive() || paramType == Object.class)) {
++ paramTypes[i] = Object.class;
++ changed = true;
++ }
++ }
++ final MethodType generalized = changed ? MethodType.methodType(noCalleeThisType.returnType(), paramTypes) : noCalleeThisType;
++
++ if (callSiteParamCount < getArity()) {
++ return generalized.appendParameterTypes(Collections.<Class<?>>nCopies(getArity() - callSiteParamCount, Object.class));
++ }
++ return generalized;
++ }
++
++ private FunctionNode extractFunctionFromScript(final FunctionNode script) {
++ final Set<FunctionNode> fns = new HashSet<>();
++ script.getBody().accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
++ @Override
++ public boolean enterFunctionNode(final FunctionNode fn) {
++ fns.add(fn);
++ return false;
++ }
++ });
++ assert fns.size() == 1 : "got back more than one method in recompilation";
++ final FunctionNode f = fns.iterator().next();
++ assert f.getId() == functionNodeId;
++ if (!getFunctionFlag(FunctionNode.IS_DECLARED) && f.isDeclared()) {
++ return f.clearFlag(null, FunctionNode.IS_DECLARED);
++ }
++ return f;
++ }
++
++ private void logLookup(final boolean shouldLog, final MethodType targetType) {
++ if (shouldLog && log.isEnabled()) {
++ log.info("Looking up ", DebugLogger.quote(functionName), " type=", targetType);
+ }
+ }
+
+- @Override
+- PropertyMap getAllocatorMap() {
+- return allocatorMap;
++ private MethodHandle lookup(final FunctionInitializer fnInit, final boolean shouldLog) {
++ final MethodType type = fnInit.getMethodType();
++ logLookup(shouldLog, type);
++ return lookupCodeMethod(fnInit.getCode(), type);
+ }
+
++ MethodHandle lookup(final FunctionNode fn) {
++ final MethodType type = new FunctionSignature(fn).getMethodType();
++ logLookup(true, type);
++ return lookupCodeMethod(fn.getCompileUnit().getCode(), type);
++ }
+
+- @Override
+- protected void ensureCompiled() {
+- if (functionNode != null && functionNode.isLazy()) {
+- Compiler.LOG.info("Trampoline hit: need to do lazy compilation of '", functionNode.getName(), "'");
+- final Compiler compiler = new Compiler(installer);
+- functionNode = compiler.compile(functionNode);
+- assert !functionNode.isLazy();
+- compiler.install(functionNode);
+- methodLocator = new MethodLocator(functionNode);
+- flags = getFlags(functionNode);
++ MethodHandle lookupCodeMethod(final Class<?> codeClass, final MethodType targetType) {
++ return MH.findStatic(LOOKUP, codeClass, functionName, targetType);
++ }
++
++ /**
++ * Initializes this function data with the eagerly generated version of the code. This method can only be invoked
++ * by the compiler internals in Nashorn and is public for implementation reasons only. Attempting to invoke it
++ * externally will result in an exception.
++ *
++ * @param initializer FunctionInitializer for this data
++ */
++ public void initializeCode(final FunctionInitializer initializer) {
++ // Since the method is public, we double-check that we aren't invoked with an inappropriate compile unit.
++ if(!code.isEmpty()) {
++ throw new IllegalStateException(name);
++ }
++ addCode(lookup(initializer, true), null, null, initializer.getFlags());
++ }
++
++ private CompiledFunction addCode(final MethodHandle target, final Map<Integer, Type> invalidatedProgramPoints,
++ final MethodType callSiteType, final int fnFlags) {
++ final CompiledFunction cfn = new CompiledFunction(target, this, invalidatedProgramPoints, callSiteType, fnFlags);
++ code.add(cfn);
++ return cfn;
++ }
++
++ /**
++ * Add code with specific call site type. It will adapt the type of the looked up method handle to fit the call site
++ * type. This is necessary because even if we request a specialization that takes an "int" parameter, we might end
++ * up getting one that takes a "double" etc. because of internal function logic causes widening (e.g. assignment of
++ * a wider value to the parameter variable). However, we use the method handle type for matching subsequent lookups
++ * for the same specialization, so we must adapt the handle to the expected type.
++ * @param fnInit the function
++ * @param callSiteType the call site type
++ * @return the compiled function object, with its type matching that of the call site type.
++ */
++ private CompiledFunction addCode(final FunctionInitializer fnInit, final MethodType callSiteType) {
++ if (isVariableArity()) {
++ return addCode(lookup(fnInit, true), fnInit.getInvalidatedProgramPoints(), callSiteType, fnInit.getFlags());
+ }
+
+- if (functionNode != null) {
+- methodLocator.setClass(functionNode.getCompileUnit().getCode());
++ final MethodHandle handle = lookup(fnInit, true);
++ final MethodType fromType = handle.type();
++ MethodType toType = needsCallee(fromType) ? callSiteType.changeParameterType(0, ScriptFunction.class) : callSiteType.dropParameterTypes(0, 1);
++ toType = toType.changeReturnType(fromType.returnType());
++
++ final int toCount = toType.parameterCount();
++ final int fromCount = fromType.parameterCount();
++ final int minCount = Math.min(fromCount, toCount);
++ for(int i = 0; i < minCount; ++i) {
++ final Class<?> fromParam = fromType.parameterType(i);
++ final Class<?> toParam = toType.parameterType(i);
++ // If method has an Object parameter, but call site had String, preserve it as Object. No need to narrow it
++ // artificially. Note that this is related to how CompiledFunction.matchesCallSite() works, specifically
++ // the fact that various reference types compare to equal (see "fnType.isEquivalentTo(csType)" there).
++ if (fromParam != toParam && !fromParam.isPrimitive() && !toParam.isPrimitive()) {
++ assert fromParam.isAssignableFrom(toParam);
++ toType = toType.changeParameterType(i, fromParam);
++ }
+ }
++ if (fromCount > toCount) {
++ toType = toType.appendParameterTypes(fromType.parameterList().subList(toCount, fromCount));
++ } else if (fromCount < toCount) {
++ toType = toType.dropParameterTypes(fromCount, toCount);
++ }
++
++ return addCode(lookup(fnInit, false).asType(toType), fnInit.getInvalidatedProgramPoints(), callSiteType, fnInit.getFlags());
++ }
++
++ /**
++ * Returns the return type of a function specialization for particular parameter types.<br>
++ * <b>Be aware that the way this is implemented, it forces full materialization (compilation and installation) of
++ * code for that specialization.</b>
++ * @param callSiteType the parameter types at the call site. It must include the mandatory {@code callee} and
++ * {@code this} parameters, so it needs to start with at least {@code ScriptFunction.class} and
++ * {@code Object.class} class. Since the return type of the function is calculated from the code itself, it is
++ * irrelevant and should be set to {@code Object.class}.
++ * @param runtimeScope a current runtime scope. Can be null but when it's present it will be used as a source of
++ * current runtime values that can improve the compiler's type speculations (and thus reduce the need for later
++ * recompilations) if the specialization is not already present and thus needs to be freshly compiled.
++ * @return the return type of the function specialization.
++ */
++ public Class<?> getReturnType(final MethodType callSiteType, final ScriptObject runtimeScope) {
++ return getBest(callSiteType, runtimeScope, CompiledFunction.NO_FUNCTIONS).type().returnType();
+ }
+
+ @Override
+- protected synchronized void ensureCodeGenerated() {
+- if (!code.isEmpty()) {
+- return; // nothing to do, we have code, at least some.
++ synchronized CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden) {
++ CompiledFunction existingBest = super.getBest(callSiteType, runtimeScope, forbidden);
++ if (existingBest == null) {
++ existingBest = addCode(compileTypeSpecialization(callSiteType, runtimeScope, true), callSiteType);
+ }
+
+- ensureCompiled();
++ assert existingBest != null;
++ //we are calling a vararg method with real args
++ boolean varArgWithRealArgs = existingBest.isVarArg() && !CompiledFunction.isVarArgsType(callSiteType);
+
+- /*
+- * We can't get to this program point unless we have bytecode, either from
+- * eager compilation or from running a lazy compile on the lines above
+- */
++ //if the best one is an apply to call, it has to match the callsite exactly
++ //or we need to regenerate
++ if (existingBest.isApplyToCall()) {
++ final CompiledFunction best = lookupExactApplyToCall(callSiteType);
++ if (best != null) {
++ return best;
++ }
++ varArgWithRealArgs = true;
++ }
+
+- assert functionNode == null || functionNode.hasState(CompilationState.EMITTED) :
+- functionNode.getName() + " " + functionNode.getState() + " " + Debug.id(functionNode);
++ if (varArgWithRealArgs) {
++ // special case: we had an apply to call, but we failed to make it fit.
++ // Try to generate a specialized one for this callsite. It may
++ // be another apply to call specialization, or it may not, but whatever
++ // it is, it is a specialization that is guaranteed to fit
++ final FunctionInitializer fnInit = compileTypeSpecialization(callSiteType, runtimeScope, false);
++ existingBest = addCode(fnInit, callSiteType);
++ }
+
+- // code exists - look it up and add it into the automatically sorted invoker list
+- addCode(functionNode);
+-
+- if (functionNode != null && !functionNode.canSpecialize()) {
+- // allow GC to claim IR stuff that is not needed anymore
+- functionNode = null;
+- installer = null;
+- }
++ return existingBest;
+ }
+
+- private MethodHandle addCode(final FunctionNode fn) {
+- return addCode(fn, null, null, null);
+- }
+-
+- private MethodHandle addCode(final FunctionNode fn, final MethodType runtimeType, final MethodHandle guard, final MethodHandle fallback) {
+- assert methodLocator != null;
+- MethodHandle target = methodLocator.getMethodHandle();
+- final MethodType targetType = methodLocator.getMethodType();
+-
+- /*
+- * For any integer argument. a double that is representable as an integer is OK.
+- * otherwise the guard would have failed. in that case introduce a filter that
+- * casts the double to an integer, which we know will preserve all precision.
+- */
+- for (int i = 0; i < targetType.parameterCount(); i++) {
+- if (targetType.parameterType(i) == int.class) {
+- //representable as int
+- target = MH.filterArguments(target, i, ENSURE_INT);
+- }
+- }
+-
+- MethodHandle mh = target;
+- if (guard != null) {
+- mh = MH.guardWithTest(MH.asCollector(guard, Object[].class, target.type().parameterCount()), MH.asType(target, fallback.type()), fallback);
+- }
+-
+- final CompiledFunction cf = new CompiledFunction(runtimeType == null ? targetType : runtimeType, mh);
+- code.add(cf);
+-
+- return cf.getInvoker();
+- }
+-
+- private static Type runtimeType(final Object arg) {
+- if (arg == null) {
+- return Type.OBJECT;
+- }
+-
+- final Class<?> clazz = arg.getClass();
+- assert !clazz.isPrimitive() : "always boxed";
+- if (clazz == Double.class) {
+- return JSType.isRepresentableAsInt((double)arg) ? Type.INT : Type.NUMBER;
+- } else if (clazz == Integer.class) {
+- return Type.INT;
+- } else if (clazz == Long.class) {
+- return Type.LONG;
+- } else if (clazz == String.class) {
+- return Type.STRING;
+- }
+- return Type.OBJECT;
+- }
+-
+- private static boolean canCoerce(final Object arg, final Type type) {
+- Type argType = runtimeType(arg);
+- if (Type.widest(argType, type) == type || arg == ScriptRuntime.UNDEFINED) {
+- return true;
+- }
+- System.err.println(arg + " does not fit in "+ argType + " " + type + " " + arg.getClass());
+- new Throwable().printStackTrace();
+- return false;
+- }
+-
+- @SuppressWarnings("unused")
+- private static boolean paramTypeGuard(final Type[] paramTypes, final Object... args) {
+- final int length = args.length;
+- assert args.length >= paramTypes.length;
+-
+- //i==start, skip the this, callee params etc
+- int start = args.length - paramTypes.length;
+- for (int i = start; i < args.length; i++) {
+- final Object arg = args[i];
+- if (!canCoerce(arg, paramTypes[i - start])) {
+- return false;
+- }
+- }
++ @Override
++ boolean isRecompilable() {
+ return true;
+ }
+
+- @SuppressWarnings("unused")
+- private static int ensureInt(final Object arg) {
+- if (arg instanceof Number) {
+- return ((Number)arg).intValue();
+- } else if (arg instanceof Undefined) {
+- return 0;
+- }
+- throw new AssertionError(arg);
++ @Override
++ public boolean needsCallee() {
++ return getFunctionFlag(FunctionNode.NEEDS_CALLEE);
+ }
+
+ /**
+- * Given the runtime callsite args, compute a method type that is equivalent to what
+- * was passed - this is typically a lot more specific that what the compiler has been
+- * able to deduce
+- * @param callSiteType callsite type for the compiled callsite target
+- * @param args runtime arguments to the compiled callsite target
+- * @return adjusted method type, narrowed as to conform to runtime callsite type instead
++ * Returns the {@link FunctionNode} flags associated with this function data.
++ * @return the {@link FunctionNode} flags associated with this function data.
+ */
+- private static MethodType runtimeType(final MethodType callSiteType, final Object[] args) {
+- if (args == null) {
+- //for example bound, or otherwise runtime arguments to callsite unavailable, then
+- //do not change the type
+- return callSiteType;
+- }
+- final Class<?>[] paramTypes = new Class<?>[callSiteType.parameterCount()];
+- final int start = args.length - callSiteType.parameterCount();
+- for (int i = start; i < args.length; i++) {
+- paramTypes[i - start] = runtimeType(args[i]).getTypeClass();
+- }
+- return MH.type(callSiteType.returnType(), paramTypes);
+- }
+-
+- private static ArrayList<Type> runtimeType(final MethodType mt) {
+- final ArrayList<Type> type = new ArrayList<>();
+- for (int i = 0; i < mt.parameterCount(); i++) {
+- type.add(Type.typeFor(mt.parameterType(i)));
+- }
+- return type;
++ public int getFunctionFlags() {
++ return functionFlags;
+ }
+
+ @Override
+- synchronized MethodHandle getBestInvoker(final MethodType callSiteType, final Object[] args) {
+- final MethodType runtimeType = runtimeType(callSiteType, args);
+- assert runtimeType.parameterCount() == callSiteType.parameterCount();
+-
+- final MethodHandle mh = super.getBestInvoker(runtimeType, args);
+-
+- /*
+- * Not all functions can be specialized, for example, if we deemed memory
+- * footprint too large to store a parse snapshot, or if it is meaningless
+- * to do so, such as e.g. for runScript
+- */
+- if (functionNode == null || !functionNode.canSpecialize()) {
+- return mh;
++ MethodType getGenericType() {
++ // 2 is for (callee, this)
++ if (isVariableArity()) {
++ return MethodType.genericMethodType(2, true);
+ }
+-
+- /*
+- * Check if best invoker is equally specific or more specific than runtime
+- * type. In that case, we don't need further specialization, but can use
+- * whatever we have already. We know that it will match callSiteType, or it
+- * would not have been returned from getBestInvoker
+- */
+- if (!code.isLessSpecificThan(runtimeType)) {
+- return mh;
+- }
+-
+- int i;
+- final FunctionNode snapshot = functionNode.getSnapshot();
+- assert snapshot != null;
+-
+- /*
+- * Create a list of the arg types that the compiler knows about
+- * typically, the runtime args are a lot more specific, and we should aggressively
+- * try to use those whenever possible
+- * We WILL try to make an aggressive guess as possible, and add guards if needed.
+- * For example, if the compiler can deduce that we have a number type, but the runtime
+- * passes and int, we might still want to keep it an int, and the gamble to
+- * check that whatever is passed is int representable usually pays off
+- * If the compiler only knows that a parameter is an "Object", it is still worth
+- * it to try to specialize it by looking at the runtime arg.
+- */
+- final LinkedList<Type> compileTimeArgs = new LinkedList<>();
+- for (i = callSiteType.parameterCount() - 1; i >= 0 && compileTimeArgs.size() < snapshot.getParameters().size(); i--) {
+- compileTimeArgs.addFirst(Type.typeFor(callSiteType.parameterType(i)));
+- }
+-
+- /*
+- * The classes known at compile time are a safe to generate as primitives without parameter guards
+- * But the classes known at runtime (if more specific than compile time types) are safe to generate as primitives
+- * IFF there are parameter guards
+- */
+- MethodHandle guard = null;
+- final ArrayList<Type> runtimeParamTypes = runtimeType(runtimeType);
+- while (runtimeParamTypes.size() > functionNode.getParameters().size()) {
+- runtimeParamTypes.remove(0);
+- }
+- for (i = 0; i < compileTimeArgs.size(); i++) {
+- final Type rparam = Type.typeFor(runtimeType.parameterType(i));
+- final Type cparam = compileTimeArgs.get(i);
+-
+- if (cparam.isObject() && !rparam.isObject()) {
+- //check that the runtime object is still coercible to the runtime type, because compiler can't prove it's always primitive
+- if (guard == null) {
+- guard = MH.insertArguments(PARAM_TYPE_GUARD, 0, (Object)runtimeParamTypes.toArray(new Type[runtimeParamTypes.size()]));
+- }
+- }
+- }
+-
+- Compiler.LOG.info("Callsite specialized ", name, " runtimeType=", runtimeType, " parameters=", snapshot.getParameters(), " args=", Arrays.asList(args));
+-
+- assert snapshot != functionNode;
+-
+- final Compiler compiler = new Compiler(installer);
+-
+- final FunctionNode compiledSnapshot = compiler.compile(
+- snapshot.setHints(
+- null,
+- new Compiler.Hints(runtimeParamTypes.toArray(new Type[runtimeParamTypes.size()]))));
+-
+- /*
+- * No matter how narrow your types were, they can never be narrower than Attr during recompile made them. I.e. you
+- * can put an int into the function here, if you see it as a runtime type, but if the function uses a multiplication
+- * on it, it will still need to be a double. At least until we have overflow checks. Similarly, if an int is
+- * passed but it is used as a string, it makes no sense to make the parameter narrower than Object. At least until
+- * the "different types for one symbol in difference places" work is done
+- */
+- compiler.install(compiledSnapshot);
+-
+- return addCode(compiledSnapshot, runtimeType, guard, mh);
+- }
+-
+- private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+- return MH.findStatic(MethodHandles.lookup(), RecompilableScriptFunctionData.class, name, MH.type(rtype, types));
++ return MethodType.genericMethodType(2 + getArity());
+ }
+
+ /**
+- * Helper class that allows us to retrieve the method handle for this function once it has been generated.
++ * Return the function node id.
++ * @return the function node id
+ */
+- private static class MethodLocator implements Serializable {
+- private transient Class<?> clazz;
+- private final String className;
+- private final String methodName;
+- private final MethodType methodType;
+-
+- private static final long serialVersionUID = -5420835725902966692L;
+-
+- MethodLocator(final FunctionNode functionNode) {
+- this.className = functionNode.getCompileUnit().getUnitClassName();
+- this.methodName = functionNode.getName();
+- this.methodType = new FunctionSignature(functionNode).getMethodType();
+-
+- assert className != null;
+- assert methodName != null;
+- }
+-
+- void setClass(final Class<?> clazz) {
+- if (!JS.class.isAssignableFrom(clazz)) {
+- throw new IllegalArgumentException();
+- }
+- this.clazz = clazz;
+- }
+-
+- String getClassName() {
+- return className;
+- }
+-
+- MethodType getMethodType() {
+- return methodType;
+- }
+-
+- MethodHandle getMethodHandle() {
+- return MH.findStatic(LOOKUP, clazz, methodName, methodType);
+- }
++ public int getFunctionNodeId() {
++ return functionNodeId;
+ }
+
++ /**
++ * Get the source for the script
++ * @return source
++ */
++ public Source getSource() {
++ return source;
++ }
++
++ /**
++ * Return a script function data based on a function id, either this function if
++ * the id matches or a nested function based on functionId. This goes down into
++ * nested functions until all leaves are exhausted.
++ *
++ * @param functionId function id
++ * @return script function data or null if invalid id
++ */
++ public RecompilableScriptFunctionData getScriptFunctionData(final int functionId) {
++ if (functionId == functionNodeId) {
++ return this;
++ }
++ RecompilableScriptFunctionData data;
++
++ data = nestedFunctions == null ? null : nestedFunctions.get(functionId);
++ if (data != null) {
++ return data;
++ }
++ for (final RecompilableScriptFunctionData ndata : nestedFunctions.values()) {
++ data = ndata.getScriptFunctionData(functionId);
++ if (data != null) {
++ return data;
++ }
++ }
++ return null;
++ }
++
++ /**
++ * Check whether a certain name is a global symbol, i.e. only exists as defined
++ * in outermost scope and not shadowed by being parameter or assignment in inner
++ * scopes
++ *
++ * @param functionNode function node to check
++ * @param symbolName symbol name
++ * @return true if global symbol
++ */
++ public boolean isGlobalSymbol(final FunctionNode functionNode, final String symbolName) {
++ RecompilableScriptFunctionData data = getScriptFunctionData(functionNode.getId());
++ assert data != null;
++
++ do {
++ if (data.hasInternalSymbol(symbolName)) {
++ return false;
++ }
++ data = data.getParent();
++ } while(data != null);
++
++ return true;
++ }
++
++ /**
++ * Restores the {@link #getFunctionFlags()} flags to a function node. During on-demand compilation, we might need
++ * to restore flags to a function node that was otherwise not subjected to a full compile pipeline (e.g. its parse
++ * was skipped, or it's a nested function of a deserialized function.
++ * @param lc current lexical context
++ * @param fn the function node to restore flags onto
++ * @return the transformed function node
++ */
++ public FunctionNode restoreFlags(final LexicalContext lc, final FunctionNode fn) {
++ assert fn.getId() == functionNodeId;
++ FunctionNode newFn = fn.setFlags(lc, functionFlags);
++ // This compensates for missing markEval() in case the function contains an inner function
++ // that contains eval(), that now we didn't discover since we skipped the inner function.
++ if (newFn.hasNestedEval()) {
++ assert newFn.hasScopeBlock();
++ newFn = newFn.setBody(lc, newFn.getBody().setNeedsScope(null));
++ }
++ return newFn;
++ }
++
++ private void readObject(final java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
++ in.defaultReadObject();
++ createLogger();
++ }
++
++ private void createLogger() {
++ log = initLogger(Context.getContextTrusted());
++ }
+ }
+-
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/RewriteException.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,420 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
++
++import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
++import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
++import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
++
++import java.io.NotSerializableException;
++import java.io.ObjectInputStream;
++import java.io.ObjectOutputStream;
++import java.lang.invoke.CallSite;
++import java.lang.invoke.ConstantCallSite;
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.lang.invoke.MethodHandles.Lookup;
++import java.lang.invoke.MethodType;
++import java.lang.reflect.Array;
++import java.util.Arrays;
++import jdk.nashorn.internal.codegen.CompilerConstants;
++import jdk.nashorn.internal.codegen.CompilerConstants.Call;
++import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.lookup.MethodHandleFactory;
++import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
++import jdk.nashorn.internal.objects.Global;
++import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
++
++/**
++ * Used to signal to the linker to relink the callee
++ */
++@SuppressWarnings("serial")
++public final class RewriteException extends Exception {
++ private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();
++
++ // Runtime scope in effect at the time of the compilation. Used to evaluate types of expressions and prevent overly
++ // optimistic assumptions (which will lead to unnecessary deoptimizing recompilations).
++ private ScriptObject runtimeScope;
++
++ // Contents of bytecode slots
++ private Object[] byteCodeSlots;
++
++ private final int[] previousContinuationEntryPoints;
++
++ /** Call for getting the contents of the bytecode slots in the exception */
++ public static final Call GET_BYTECODE_SLOTS = virtualCallNoLookup(RewriteException.class, "getByteCodeSlots", Object[].class);
++ /** Call for getting the program point in the exception */
++ public static final Call GET_PROGRAM_POINT = virtualCallNoLookup(RewriteException.class, "getProgramPoint", int.class);
++ /** Call for getting the return value for the exception */
++ public static final Call GET_RETURN_VALUE = virtualCallNoLookup(RewriteException.class, "getReturnValueDestructive", Object.class);
++ /** Call for the populate array bootstrap */
++ public static final Call BOOTSTRAP = staticCallNoLookup(RewriteException.class, "populateArrayBootstrap", CallSite.class, Lookup.class, String.class, MethodType.class, int.class);
++
++ /** Call for populating an array with local variable state */
++ private static final Call POPULATE_ARRAY = staticCall(MethodHandles.lookup(), RewriteException.class, "populateArray", Object[].class, Object[].class, int.class, Object[].class);
++
++ /** Call for converting an array to a long array. */
++ public static final Call TO_LONG_ARRAY = staticCallNoLookup(RewriteException.class, "toLongArray", long[].class, Object.class, RewriteException.class);
++ /** Call for converting an array to a double array. */
++ public static final Call TO_DOUBLE_ARRAY = staticCallNoLookup(RewriteException.class, "toDoubleArray", double[].class, Object.class, RewriteException.class);
++ /** Call for converting an array to an object array. */
++ public static final Call TO_OBJECT_ARRAY = staticCallNoLookup(RewriteException.class, "toObjectArray", Object[].class, Object.class, RewriteException.class);
++ /** Call for converting an object to null if it can't be represented as an instance of a class. */
++ public static final Call INSTANCE_OR_NULL = staticCallNoLookup(RewriteException.class, "instanceOrNull", Object.class, Object.class, Class.class);
++ /** Call for asserting the length of an array. */
++ public static final Call ASSERT_ARRAY_LENGTH = staticCallNoLookup(RewriteException.class, "assertArrayLength", void.class, Object[].class, int.class);
++
++ private RewriteException(
++ final UnwarrantedOptimismException e,
++ final Object[] byteCodeSlots,
++ final String[] byteCodeSymbolNames,
++ final int[] previousContinuationEntryPoints) {
++ super("", e, false, Context.DEBUG);
++ this.byteCodeSlots = byteCodeSlots;
++ this.runtimeScope = mergeSlotsWithScope(byteCodeSlots, byteCodeSymbolNames);
++ this.previousContinuationEntryPoints = previousContinuationEntryPoints;
++ }
++
++ /**
++ * Constructor for a rewrite exception thrown from an optimistic function.
++ * @param e the {@link UnwarrantedOptimismException} that triggered this exception.
++ * @param byteCodeSlots contents of local variable slots at the time of rewrite at the program point
++ * @param byteCodeSymbolNames the names of the variables in the {@code byteCodeSlots} parameter. The array might
++ * have less elements, and some elements might be unnamed (the name can be null). The information is provided in an
++ * effort to assist evaluation of expressions for their types by the compiler doing the deoptimizing recompilation,
++ * and can thus be incomplete - the more complete it is, the more expressions can be evaluated by the compiler, and
++ * the more unnecessary deoptimizing compilations can be avoided.
++ * @return a new rewrite exception
++ */
++ public static RewriteException create(final UnwarrantedOptimismException e,
++ final Object[] byteCodeSlots,
++ final String[] byteCodeSymbolNames) {
++ return create(e, byteCodeSlots, byteCodeSymbolNames, null);
++ }
++
++ /**
++ * Constructor for a rewrite exception thrown from a rest-of method.
++ * @param e the {@link UnwarrantedOptimismException} that triggered this exception.
++ * @param byteCodeSlots contents of local variable slots at the time of rewrite at the program point
++ * @param byteCodeSymbolNames the names of the variables in the {@code byteCodeSlots} parameter. The array might
++ * have less elements, and some elements might be unnamed (the name can be null). The information is provided in an
++ * effort to assist evaluation of expressions for their types by the compiler doing the deoptimizing recompilation,
++ * and can thus be incomplete - the more complete it is, the more expressions can be evaluated by the compiler, and
++ * the more unnecessary deoptimizing compilations can be avoided.
++ * @param previousContinuationEntryPoints an array of continuation entry points that were already executed during
++ * one logical invocation of the function (a rest-of triggering a rest-of triggering a...)
++ * @return a new rewrite exception
++ */
++ public static RewriteException create(final UnwarrantedOptimismException e,
++ final Object[] byteCodeSlots,
++ final String[] byteCodeSymbolNames,
++ final int[] previousContinuationEntryPoints) {
++ return new RewriteException(e, byteCodeSlots, byteCodeSymbolNames, previousContinuationEntryPoints);
++ }
++
++ /**
++ * Bootstrap method for populate array
++ * @param lookup lookup
++ * @param name name (ignored)
++ * @param type method type for signature
++ * @param startIndex start index to start writing to
++ * @return callsite to array populator (constant)
++ */
++ public static CallSite populateArrayBootstrap(final MethodHandles.Lookup lookup, final String name, final MethodType type, final int startIndex) {
++ MethodHandle mh = POPULATE_ARRAY.methodHandle();
++ mh = MH.insertArguments(mh, 1, startIndex);
++ mh = MH.asCollector(mh, Object[].class, type.parameterCount() - 1);
++ mh = MH.asType(mh, type);
++ return new ConstantCallSite(mh);
++ }
++
++ private static ScriptObject mergeSlotsWithScope(final Object[] byteCodeSlots, final String[] byteCodeSymbolNames) {
++ final ScriptObject locals = Global.newEmptyInstance();
++ final int l = Math.min(byteCodeSlots.length, byteCodeSymbolNames.length);
++ ScriptObject runtimeScope = null;
++ final String scopeName = CompilerConstants.SCOPE.symbolName();
++ for(int i = 0; i < l; ++i) {
++ final String name = byteCodeSymbolNames[i];
++ final Object value = byteCodeSlots[i];
++ if(scopeName.equals(name)) {
++ assert runtimeScope == null;
++ runtimeScope = (ScriptObject)value;
++ } else if(name != null) {
++ locals.set(name, value, NashornCallSiteDescriptor.CALLSITE_STRICT);
++ }
++ }
++ locals.setProto(runtimeScope);
++ return locals;
++ }
++
++ /**
++ * Array populator used for saving the local variable state into the array contained in the
++ * RewriteException
++ * @param arrayToBePopluated array to be populated
++ * @param startIndex start index to write to
++ * @param items items with which to populate the array
++ * @return the populated array - same array object
++ */
++ public static Object[] populateArray(final Object[] arrayToBePopluated, final int startIndex, final Object[] items) {
++ System.arraycopy(items, 0, arrayToBePopluated, startIndex, items.length);
++ return arrayToBePopluated;
++ }
++
++ /**
++ * Continuation handler calls this method when a local variable carried over into the continuation is expected to be
++ * a long array in the continued method. Normally, it will also be a long array in the original (interrupted by
++ * deoptimization) method, but it can actually be an int array that underwent widening in the new code version.
++ * @param obj the object that has to be converted into a long array
++ * @param e the exception being processed
++ * @return a long array
++ */
++ public static long[] toLongArray(final Object obj, final RewriteException e) {
++ if(obj instanceof long[]) {
++ return (long[])obj;
++ }
++
++ assert obj instanceof int[];
++
++ final int[] in = (int[])obj;
++ final long[] out = new long[in.length];
++ for(int i = 0; i < in.length; ++i) {
++ out[i] = in[i];
++ }
++ return e.replaceByteCodeValue(in, out);
++ }
++
++ /**
++ * Continuation handler calls this method when a local variable carried over into the continuation is expected to be
++ * a double array in the continued method. Normally, it will also be a double array in the original (interrupted by
++ * deoptimization) method, but it can actually be an int or long array that underwent widening in the new code version.
++ * @param obj the object that has to be converted into a double array
++ * @param e the exception being processed
++ * @return a double array
++ */
++ public static double[] toDoubleArray(final Object obj, final RewriteException e) {
++ if(obj instanceof double[]) {
++ return (double[])obj;
++ }
++
++ assert obj instanceof int[] || obj instanceof long[];
++
++ final int l = Array.getLength(obj);
++ final double[] out = new double[l];
++ for(int i = 0; i < l; ++i) {
++ out[i] = Array.getDouble(obj, i);
++ }
++ return e.replaceByteCodeValue(obj, out);
++ }
++
++ /**
++ * Continuation handler calls this method when a local variable carried over into the continuation is expected to be
++ * an Object array in the continued method. Normally, it will also be an Object array in the original (interrupted by
++ * deoptimization) method, but it can actually be an int, long, or double array that underwent widening in the new
++ * code version.
++ * @param obj the object that has to be converted into an Object array
++ * @param e the exception being processed
++ * @return an Object array
++ */
++ public static Object[] toObjectArray(final Object obj, final RewriteException e) {
++ if(obj instanceof Object[]) {
++ return (Object[])obj;
++ }
++
++ assert obj instanceof int[] || obj instanceof long[] || obj instanceof double[] : obj + " is " + obj.getClass().getName();
++
++ final int l = Array.getLength(obj);
++ final Object[] out = new Object[l];
++ for(int i = 0; i < l; ++i) {
++ out[i] = Array.get(obj, i);
++ }
++ return e.replaceByteCodeValue(obj, out);
++ }
++
++ /**
++ * Continuation handler calls this method when a local variable carried over into the continuation is expected to
++ * have a certain type, but the value can have a different type coming from the deoptimized method as it was a dead
++ * store. If we had precise liveness analysis, we wouldn't need this.
++ * @param obj the object inspected for being of a particular type
++ * @param clazz the type the object must belong to
++ * @return the object if it belongs to the type, or null otherwise
++ */
++ public static Object instanceOrNull(final Object obj, final Class<?> clazz) {
++ return clazz.isInstance(obj) ? obj : null;
++ }
++
++ /**
++ * Asserts the length of an array. Invoked from continuation handler only when running with assertions enabled.
++ * The array can, in fact, have more elements than asserted, but they must all have Undefined as their value. The
++ * method does not test for the array having less elements than asserted, as those would already have caused an
++ * {@code ArrayIndexOutOfBoundsException} to be thrown as the continuation handler attempts to access the missing
++ * elements.
++ * @param arr the array
++ * @param length the asserted length
++ */
++ public static void assertArrayLength(final Object[] arr, final int length) {
++ for(int i = arr.length; i-- > length;) {
++ if(arr[i] != ScriptRuntime.UNDEFINED) {
++ throw new AssertionError(String.format("Expected array length %d, but it is %d", length, i + 1));
++ }
++ }
++ }
++
++ private <T> T replaceByteCodeValue(final Object in, final T out) {
++ for(int i = 0; i < byteCodeSlots.length; ++i) {
++ if(byteCodeSlots[i] == in) {
++ byteCodeSlots[i] = out;
++ }
++ }
++ return out;
++ }
++
++ private UnwarrantedOptimismException getUOE() {
++ return (UnwarrantedOptimismException)getCause();
++ }
++ /**
++ * Get return value. This method is destructive, after it is invoked subsequent invocation of either
++ * {@link #getByteCodeSlots()} or this method will return null. This method is invoked from the generated
++ * continuation code as the last step before continuing the execution, and we need to make sure we don't hang on to
++ * either the entry bytecode slot values or the return value and prevent them from being garbage collected.
++ * @return return value
++ */
++ public Object getReturnValueDestructive() {
++ assert byteCodeSlots != null;
++ byteCodeSlots = null;
++ runtimeScope = null;
++ return getUOE().getReturnValueDestructive();
++ }
++
++ Object getReturnValueNonDestructive() {
++ return getUOE().getReturnValueNonDestructive();
++ }
++
++ /**
++ * Get return type
++ * @return return type
++ */
++ public Type getReturnType() {
++ return getUOE().getReturnType();
++ }
++
++ /**
++ * Get the program point.
++ * @return program point.
++ */
++ public int getProgramPoint() {
++ return getUOE().getProgramPoint();
++ }
++
++ /**
++ * Get the bytecode slot contents.
++ * @return bytecode slot contents.
++ */
++ public Object[] getByteCodeSlots() {
++ return byteCodeSlots == null ? null : byteCodeSlots.clone();
++ }
++
++ /**
++ * @return an array of continuation entry points that were already executed during one logical invocation of the
++ * function (a rest-of triggering a rest-of triggering a...)
++ */
++ public int[] getPreviousContinuationEntryPoints() {
++ return previousContinuationEntryPoints == null ? null : previousContinuationEntryPoints.clone();
++ }
++
++ /**
++ * Returns the runtime scope that was in effect when the exception was thrown.
++ * @return the runtime scope.
++ */
++ public ScriptObject getRuntimeScope() {
++ return runtimeScope;
++ }
++
++ private static String stringify(final Object returnValue) {
++ if (returnValue == null) {
++ return "null";
++ }
++ String str = returnValue.toString();
++ if (returnValue instanceof String) {
++ str = '\'' + str + '\'';
++ } else if (returnValue instanceof Double) {
++ str = str + 'd';
++ } else if (returnValue instanceof Long) {
++ str = str + 'l';
++ }
++ return str;
++ }
++
++ @Override
++ public String getMessage() {
++ return getMessage(false);
++ }
++
++ /**
++ * Short toString function for message
++ * @return short message
++ */
++ public String getMessageShort() {
++ return getMessage(true);
++ }
++
++ private String getMessage(final boolean isShort) {
++ final StringBuilder sb = new StringBuilder();
++
++ //program point
++ sb.append("[pp=").
++ append(getProgramPoint()).
++ append(", ");
++
++ //slot contents
++ if (!isShort) {
++ final Object[] slots = byteCodeSlots;
++ if (slots != null) {
++ sb.append("slots=").
++ append(Arrays.asList(slots)).
++ append(", ");
++ }
++ }
++
++ //return type
++ sb.append("type=").
++ append(getReturnType()).
++ append(", ");
++
++ //return value
++ sb.append("value=").
++ append(stringify(getReturnValueNonDestructive())).
++ append(")]");
++
++ return sb.toString();
++ }
++
++ private void writeObject(final ObjectOutputStream out) throws NotSerializableException {
++ throw new NotSerializableException(getClass().getName());
++ }
++
++ private void readObject(final ObjectInputStream in) throws NotSerializableException {
++ throw new NotSerializableException(getClass().getName());
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,16 +26,18 @@
+ package jdk.nashorn.internal.runtime;
+
+ import java.io.PrintWriter;
+-import java.util.HashSet;
++import java.util.HashMap;
+ import java.util.List;
+ import java.util.Locale;
+-import java.util.Set;
++import java.util.Map;
+ import java.util.StringTokenizer;
+ import java.util.TimeZone;
+-
++import java.util.logging.Level;
+ import jdk.nashorn.internal.codegen.Namespace;
+ import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+ import jdk.nashorn.internal.runtime.options.KeyValueOption;
++import jdk.nashorn.internal.runtime.options.LoggingOption;
++import jdk.nashorn.internal.runtime.options.LoggingOption.LoggerInfo;
+ import jdk.nashorn.internal.runtime.options.Option;
+ import jdk.nashorn.internal.runtime.options.Options;
+
+@@ -92,8 +94,14 @@
+ /** Use single Global instance per jsr223 engine instance. */
+ public final boolean _global_per_engine;
+
++ /** Enable experimental ECMAScript 6 features. */
++ public final boolean _es6;
++
++ /** Argument passed to compile only if optimistic compilation should take place */
++ public static final String COMPILE_ONLY_OPTIMISTIC_ARG = "optimistic";
++
+ /**
+- * Behavior when encountering a function declaration in a lexical context where only statements are acceptable
++ * Behavior when encountering a function declaration in a lexical context where only statements are acceptable
+ * (function declarations are source elements, but not statements).
+ */
+ public enum FunctionStatementBehavior {
+@@ -122,6 +130,9 @@
+ /** Should lazy compilation take place */
+ public final boolean _lazy_compilation;
+
++ /** Should optimistic types be used */
++ public final boolean _optimistic_types;
++
+ /** Create a new class loaded for each compilation */
+ public final boolean _loader_per_compile;
+
+@@ -149,6 +160,12 @@
+ /** Print resulting bytecode for script */
+ public final boolean _print_code;
+
++ /** Directory (optional) to print files to */
++ public final String _print_code_dir;
++
++ /** List of functions to write to the print code dir, optional */
++ public final String _print_code_func;
++
+ /** Print memory usage for IR after each phase */
+ public final boolean _print_mem_usage;
+
+@@ -164,15 +181,9 @@
+ /** print symbols and their contents for the script */
+ public final boolean _print_symbols;
+
+- /** range analysis for known types */
+- public final boolean _range_analysis;
+-
+ /** is this environment in scripting mode? */
+ public final boolean _scripting;
+
+- /** is the JIT allowed to specializ calls based on callsite types? */
+- public final Set<String> _specialize_calls;
+-
+ /** is this environment in strict mode? */
+ public final boolean _strict;
+
+@@ -188,6 +199,12 @@
+ /** Local for error messages */
+ public final Locale _locale;
+
++ /** Logging */
++ public final Map<String, LoggerInfo> _loggers;
++
++ /** Timing */
++ public final Timing _timing;
++
+ /**
+ * Constructor
+ *
+@@ -195,6 +212,7 @@
+ * @param out output print writer
+ * @param err error print writer
+ */
++ @SuppressWarnings("unused")
+ public ScriptEnvironment(final Options options, final PrintWriter out, final PrintWriter err) {
+ this.out = out;
+ this.err = err;
+@@ -210,9 +228,9 @@
+ _early_lvalue_error = options.getBoolean("early.lvalue.error");
+ _empty_statements = options.getBoolean("empty.statements");
+ _fullversion = options.getBoolean("fullversion");
+- if(options.getBoolean("function.statement.error")) {
++ if (options.getBoolean("function.statement.error")) {
+ _function_statement = FunctionStatementBehavior.ERROR;
+- } else if(options.getBoolean("function.statement.warning")) {
++ } else if (options.getBoolean("function.statement.warning")) {
+ _function_statement = FunctionStatementBehavior.WARNING;
+ } else {
+ _function_statement = FunctionStatementBehavior.ACCEPT;
+@@ -220,6 +238,7 @@
+ _fx = options.getBoolean("fx");
+ _global_per_engine = options.getBoolean("global.per.engine");
+ _lazy_compilation = options.getBoolean("lazy.compilation");
++ _optimistic_types = options.getBoolean("optimistic.types");
+ _loader_per_compile = options.getBoolean("loader.per.compile");
+ _no_java = options.getBoolean("no.java");
+ _no_syntax_extensions = options.getBoolean("no.syntax.extensions");
+@@ -228,28 +247,45 @@
+ _persistent_cache = options.getBoolean("persistent.code.cache");
+ _print_ast = options.getBoolean("print.ast");
+ _print_lower_ast = options.getBoolean("print.lower.ast");
+- _print_code = options.getBoolean("print.code");
++ _print_code = options.getString("print.code") != null;
+ _print_mem_usage = options.getBoolean("print.mem.usage");
+ _print_no_newline = options.getBoolean("print.no.newline");
+ _print_parse = options.getBoolean("print.parse");
+ _print_lower_parse = options.getBoolean("print.lower.parse");
+ _print_symbols = options.getBoolean("print.symbols");
+- _range_analysis = options.getBoolean("range.analysis");
+ _scripting = options.getBoolean("scripting");
+ _strict = options.getBoolean("strict");
+ _version = options.getBoolean("version");
+ _verify_code = options.getBoolean("verify.code");
+
+- final String specialize = options.getString("specialize.calls");
+- if (specialize == null) {
+- _specialize_calls = null;
++ final String language = options.getString("language");
++ if (language == null || language.equals("es5")) {
++ _es6 = false;
++ } else if (language.equals("es6")) {
++ _es6 = true;
+ } else {
+- _specialize_calls = new HashSet<>();
+- final StringTokenizer st = new StringTokenizer(specialize, ",");
+- while (st.hasMoreElements()) {
+- _specialize_calls.add(st.nextToken());
++ throw new RuntimeException("Unsupported language: " + language);
++ }
++
++ String dir = null;
++ String func = null;
++ final String pc = options.getString("print.code");
++ if (pc != null) {
++ final StringTokenizer st = new StringTokenizer(pc, ",");
++ while (st.hasMoreTokens()) {
++ final StringTokenizer st2 = new StringTokenizer(st.nextToken(), ":");
++ while (st2.hasMoreTokens()) {
++ final String cmd = st2.nextToken();
++ if ("dir".equals(cmd)) {
++ dir = st2.nextToken();
++ } else if ("function".equals(cmd)) {
++ func = st2.nextToken();
++ }
++ }
+ }
+ }
++ _print_code_dir = dir;
++ _print_code_func = func;
+
+ int callSiteFlags = 0;
+ if (options.getBoolean("profile.callsites")) {
+@@ -268,9 +304,6 @@
+ if (kv.hasValue("objects")) {
+ callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_VALUES;
+ }
+- if (kv.hasValue("scope")) {
+- callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_SCOPE;
+- }
+ }
+ this._callsite_flags = callSiteFlags;
+
+@@ -287,18 +320,12 @@
+ } else {
+ this._locale = Locale.getDefault();
+ }
+- }
+
+- /**
+- * Can we specialize a particular method name?
+- * @param functionName method name
+- * @return true if we are allowed to generate versions of this method
+- */
+- public boolean canSpecialize(final String functionName) {
+- if (_specialize_calls == null) {
+- return false;
+- }
+- return _specialize_calls.isEmpty() || _specialize_calls.contains(functionName);
++ final LoggingOption loggingOption = (LoggingOption)options.get("log");
++ this._loggers = loggingOption == null ? new HashMap<String, LoggerInfo>() : loggingOption.getLoggers();
++
++ final LoggerInfo timeLoggerInfo = _loggers.get(Timing.getLoggerName());
++ this._timing = new Timing(timeLoggerInfo != null && timeLoggerInfo.getLevel() != Level.OFF);
+ }
+
+ /**
+@@ -343,4 +370,24 @@
+ public List<String> getArguments() {
+ return options.getArguments();
+ }
++
++ /**
++ * Check if there is a logger registered for a particular name: typically
++ * the "name" attribute of a Loggable annotation on a class
++ *
++ * @param name logger name
++ * @return true, if a logger exists for that name, false otherwise
++ */
++ public boolean hasLogger(final String name) {
++ return _loggers.get(name) != null;
++ }
++
++ /**
++ * Check if compilation/runtime timings are enabled
++ * @return true if enabled
++ */
++ public boolean isTimingEnabled() {
++ return _timing != null ? _timing.isEnabled() : false;
++ }
++
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,18 +29,30 @@
+ import static jdk.nashorn.internal.lookup.Lookup.MH;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+-
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+ import java.lang.invoke.MethodType;
++import java.lang.invoke.SwitchPoint;
++import java.util.ArrayList;
++import java.util.Arrays;
++import java.util.Collection;
++import java.util.Collections;
++import java.util.HashSet;
++import java.util.List;
+ import jdk.internal.dynalink.CallSiteDescriptor;
+ import jdk.internal.dynalink.linker.GuardedInvocation;
+ import jdk.internal.dynalink.linker.LinkRequest;
++import jdk.internal.dynalink.support.Guards;
++import jdk.nashorn.internal.codegen.ApplySpecialization;
++import jdk.nashorn.internal.codegen.Compiler;
+ import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+-import jdk.nashorn.internal.lookup.MethodHandleFactory;
+ import jdk.nashorn.internal.objects.Global;
++import jdk.nashorn.internal.objects.NativeFunction;
++import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
++import jdk.nashorn.internal.runtime.linker.Bootstrap;
+ import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+-import jdk.nashorn.internal.runtime.linker.NashornGuards;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
+
+ /**
+ * Runtime representation of a JavaScript function.
+@@ -48,35 +60,39 @@
+ public abstract class ScriptFunction extends ScriptObject {
+
+ /** Method handle for prototype getter for this ScriptFunction */
+- public static final MethodHandle G$PROTOTYPE = findOwnMH("G$prototype", Object.class, Object.class);
++ public static final MethodHandle G$PROTOTYPE = findOwnMH_S("G$prototype", Object.class, Object.class);
+
+ /** Method handle for prototype setter for this ScriptFunction */
+- public static final MethodHandle S$PROTOTYPE = findOwnMH("S$prototype", void.class, Object.class, Object.class);
++ public static final MethodHandle S$PROTOTYPE = findOwnMH_S("S$prototype", void.class, Object.class, Object.class);
+
+ /** Method handle for length getter for this ScriptFunction */
+- public static final MethodHandle G$LENGTH = findOwnMH("G$length", int.class, Object.class);
++ public static final MethodHandle G$LENGTH = findOwnMH_S("G$length", int.class, Object.class);
+
+ /** Method handle for name getter for this ScriptFunction */
+- public static final MethodHandle G$NAME = findOwnMH("G$name", Object.class, Object.class);
++ public static final MethodHandle G$NAME = findOwnMH_S("G$name", Object.class, Object.class);
+
+ /** Method handle used for implementing sync() in mozilla_compat */
+- public static final MethodHandle INVOKE_SYNC = findOwnMH("invokeSync", Object.class, ScriptFunction.class, Object.class, Object.class, Object[].class);
++ public static final MethodHandle INVOKE_SYNC = findOwnMH_S("invokeSync", Object.class, ScriptFunction.class, Object.class, Object.class, Object[].class);
+
+ /** Method handle for allocate function for this ScriptFunction */
+- static final MethodHandle ALLOCATE = findOwnMH("allocate", Object.class);
++ static final MethodHandle ALLOCATE = findOwnMH_V("allocate", Object.class);
+
+- private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", Object.class, Object.class);
++ private static final MethodHandle WRAPFILTER = findOwnMH_S("wrapFilter", Object.class, Object.class);
+
+- private static final MethodHandle GLOBALFILTER = findOwnMH("globalFilter", Object.class, Object.class);
++ private static final MethodHandle SCRIPTFUNCTION_GLOBALFILTER = findOwnMH_S("globalFilter", Object.class, Object.class);
+
+ /** method handle to scope getter for this ScriptFunction */
+ public static final Call GET_SCOPE = virtualCallNoLookup(ScriptFunction.class, "getScope", ScriptObject.class);
+
+- private static final MethodHandle IS_FUNCTION_MH = findOwnMH("isFunctionMH", boolean.class, Object.class, ScriptFunctionData.class);
++ private static final MethodHandle IS_FUNCTION_MH = findOwnMH_S("isFunctionMH", boolean.class, Object.class, ScriptFunctionData.class);
+
+- private static final MethodHandle IS_NONSTRICT_FUNCTION = findOwnMH("isNonStrictFunction", boolean.class, Object.class, Object.class, ScriptFunctionData.class);
++ private static final MethodHandle IS_APPLY_FUNCTION = findOwnMH_S("isApplyFunction", boolean.class, boolean.class, Object.class, Object.class);
+
+- private static final MethodHandle ADD_ZEROTH_ELEMENT = findOwnMH("addZerothElement", Object[].class, Object[].class, Object.class);
++ private static final MethodHandle IS_NONSTRICT_FUNCTION = findOwnMH_S("isNonStrictFunction", boolean.class, Object.class, Object.class, ScriptFunctionData.class);
++
++ private static final MethodHandle ADD_ZEROTH_ELEMENT = findOwnMH_S("addZerothElement", Object[].class, Object[].class, Object.class);
++
++ private static final MethodHandle WRAP_THIS = MH.findStatic(MethodHandles.lookup(), ScriptFunctionData.class, "wrapThis", MH.type(Object.class, Object.class));
+
+ /** The parent scope. */
+ private final ScriptObject scope;
+@@ -101,7 +117,7 @@
+ final MethodHandle methodHandle,
+ final PropertyMap map,
+ final ScriptObject scope,
+- final MethodHandle[] specs,
++ final Specialization[] specs,
+ final int flags) {
+
+ this(new FinalScriptFunctionData(name, methodHandle, specs, flags), map, scope);
+@@ -195,6 +211,10 @@
+ return data.needsWrappedThis();
+ }
+
++ private static boolean needsWrappedThis(final Object fn) {
++ return fn instanceof ScriptFunction ? ((ScriptFunction)fn).needsWrappedThis() : false;
++ }
++
+ /**
+ * Execute this script function.
+ * @param self Target object.
+@@ -230,12 +250,13 @@
+ if (Context.DEBUG) {
+ allocations++;
+ }
++
+ assert !isBoundFunction(); // allocate never invoked on bound functions
+
+ final ScriptObject object = data.allocate(allocatorMap);
+
+ if (object != null) {
+- Object prototype = getPrototype();
++ final Object prototype = getPrototype();
+ if (prototype instanceof ScriptObject) {
+ object.setInitialProto((ScriptObject)prototype);
+ }
+@@ -311,26 +332,7 @@
+ * @param sync the Object to synchronize on, or undefined
+ * @return synchronized function
+ */
+- public abstract ScriptFunction makeSynchronizedFunction(Object sync);
+-
+- /**
+- * Return the most appropriate invoke handle if there are specializations
+- * @param type most specific method type to look for invocation with
+- * @param args args for trampoline invocation
+- * @return invoke method handle
+- */
+- private MethodHandle getBestInvoker(final MethodType type, final Object[] args) {
+- return data.getBestInvoker(type, args);
+- }
+-
+- /**
+- * Return the most appropriate invoke handle if there are specializations
+- * @param type most specific method type to look for invocation with
+- * @return invoke method handle
+- */
+- public MethodHandle getBestInvoker(final MethodType type) {
+- return getBestInvoker(type, null);
+- }
++ public abstract ScriptFunction makeSynchronizedFunction(Object sync);
+
+ /**
+ * Return the invoke handle bound to a given ScriptObject self reference.
+@@ -340,7 +342,7 @@
+ * @return bound invoke handle
+ */
+ public final MethodHandle getBoundInvokeHandle(final Object self) {
+- return MH.bindTo(bindToCalleeIfNeeded(data.getGenericInvoker()), self);
++ return MH.bindTo(bindToCalleeIfNeeded(data.getGenericInvoker(scope)), self);
+ }
+
+ /**
+@@ -379,7 +381,7 @@
+ * @return self's prototype
+ */
+ public static Object G$prototype(final Object self) {
+- return (self instanceof ScriptFunction) ?
++ return self instanceof ScriptFunction ?
+ ((ScriptFunction)self).getPrototype() :
+ UNDEFINED;
+ }
+@@ -428,9 +430,9 @@
+ * @param constructor constructor
+ * @return prototype, or null if given constructor is not a ScriptFunction
+ */
+- public static ScriptObject getPrototype(final Object constructor) {
+- if (constructor instanceof ScriptFunction) {
+- final Object proto = ((ScriptFunction)constructor).getPrototype();
++ public static ScriptObject getPrototype(final ScriptFunction constructor) {
++ if (constructor != null) {
++ final Object proto = constructor.getPrototype();
+ if (proto instanceof ScriptObject) {
+ return (ScriptObject)proto;
+ }
+@@ -466,12 +468,15 @@
+ }
+
+ @Override
+- protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc) {
++ protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+ final MethodType type = desc.getMethodType();
+- return new GuardedInvocation(pairArguments(data.getBestConstructor(type.changeParameterType(0, ScriptFunction.class), null), type), null, getFunctionGuard(this));
++ assert desc.getMethodType().returnType() == Object.class && !NashornCallSiteDescriptor.isOptimistic(desc);
++ final CompiledFunction cf = data.getBestConstructor(type, scope, CompiledFunction.NO_FUNCTIONS);
++ final GuardedInvocation bestCtorInv = cf.createConstructorInvocation();
++ //TODO - ClassCastException
++ return new GuardedInvocation(pairArguments(bestCtorInv.getInvocation(), type), getFunctionGuard(this, cf.getFlags()), bestCtorInv.getSwitchPoints(), null);
+ }
+
+- @SuppressWarnings("unused")
+ private static Object wrapFilter(final Object obj) {
+ if (obj instanceof ScriptObject || !ScriptFunctionData.isPrimitiveThis(obj)) {
+ return obj;
+@@ -487,6 +492,35 @@
+ }
+
+ /**
++ * Some receivers are primitive, in that case, according to the Spec we create a new
++ * native object per callsite with the wrap filter. We can only apply optimistic builtins
++ * if there is no per instance state saved for these wrapped objects (e.g. currently NativeStrings),
++ * otherwise we can't create optimistic versions
++ *
++ * @param self receiver
++ * @param linkLogicClass linkLogicClass, or null if no link logic exists
++ * @return link logic instance, or null if one could not be constructed for this receiver
++ */
++ private static LinkLogic getLinkLogic(final Object self, final Class<? extends LinkLogic> linkLogicClass) {
++ if (linkLogicClass == null) {
++ return LinkLogic.EMPTY_INSTANCE; //always OK to link this, specialization but without special linking logic
++ }
++
++ if (!Context.getContextTrusted().getEnv()._optimistic_types) {
++ return null; //if optimistic types are off, optimistic builtins are too
++ }
++
++ final Object wrappedSelf = wrapFilter(self);
++ if (wrappedSelf instanceof OptimisticBuiltins) {
++ if (wrappedSelf != self && ((OptimisticBuiltins)wrappedSelf).hasPerInstanceAssumptions()) {
++ return null; //pessimistic - we created a wrapped object different from the primitive, but the assumptions have instance state
++ }
++ return ((OptimisticBuiltins)wrappedSelf).getLinkLogic(linkLogicClass);
++ }
++ return null;
++ }
++
++ /**
+ * dyn:call call site signature: (callee, thiz, [args...])
+ * generated method signature: (callee, thiz, [args...])
+ *
+@@ -497,51 +531,114 @@
+ * (b) method doesn't have callee parameter (builtin functions)
+ * (3) for local/scope calls, bind thiz and drop both callee and thiz.
+ * (4) for normal this-calls, drop callee.
++ *
++ * @return guarded invocation for call
+ */
+ @Override
+ protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+ final MethodType type = desc.getMethodType();
+- final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
+
+- if (request.isCallSiteUnstable()) {
+- // (callee, this, args...) => (callee, this, args[])
+- final MethodHandle collector = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class, type.parameterCount() - 2);
++ final String name = getName();
++ final boolean isUnstable = request.isCallSiteUnstable();
++ final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
++ final boolean isCall = !scopeCall && data.isBuiltin() && "call".equals(name);
++ final boolean isApply = !scopeCall && data.isBuiltin() && "apply".equals(name);
++
++ final boolean isApplyOrCall = isCall | isApply;
++
++ if (isUnstable && !isApplyOrCall) {
++ //megamorphic - replace call with apply
++ final MethodHandle handle;
++ //ensure that the callsite is vararg so apply can consume it
++ if (type.parameterCount() == 3 && type.parameterType(2) == Object[].class) {
++ // Vararg call site
++ handle = ScriptRuntime.APPLY.methodHandle();
++ } else {
++ // (callee, this, args...) => (callee, this, args[])
++ handle = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class, type.parameterCount() - 2);
++ }
+
+ // If call site is statically typed to take a ScriptFunction, we don't need a guard, otherwise we need a
+ // generic "is this a ScriptFunction?" guard.
+- return new GuardedInvocation(collector, ScriptFunction.class.isAssignableFrom(desc.getMethodType().parameterType(0))
+- ? null : NashornGuards.getScriptFunctionGuard());
++ return new GuardedInvocation(
++ handle,
++ null,
++ (SwitchPoint)null,
++ ClassCastException.class);
+ }
+
+ MethodHandle boundHandle;
+ MethodHandle guard = null;
+
++ // Special handling of Function.apply and Function.call. Note we must be invoking
++ if (isApplyOrCall && !isUnstable) {
++ final Object[] args = request.getArguments();
++ if (Bootstrap.isCallable(args[1])) {
++ return createApplyOrCallCall(isApply, desc, request, args);
++ }
++ } //else just fall through and link as ordinary function or unstable apply
++
++ int programPoint = INVALID_PROGRAM_POINT;
++ if (NashornCallSiteDescriptor.isOptimistic(desc)) {
++ programPoint = NashornCallSiteDescriptor.getProgramPoint(desc);
++ }
++
++ CompiledFunction cf = data.getBestInvoker(type, scope, CompiledFunction.NO_FUNCTIONS);
++ final Object self = request.getArguments()[1];
++ final Collection<CompiledFunction> forbidden = new HashSet<>();
++
++ //check for special fast versions of the compiled function
++ final List<SwitchPoint> sps = new ArrayList<>();
++ Class<? extends Throwable> exceptionGuard = null;
++
++ while (cf.isSpecialization()) {
++ final Class<? extends LinkLogic> linkLogicClass = cf.getLinkLogicClass();
++ //if linklogic is null, we can always link with the standard mechanism, it's still a specialization
++ final LinkLogic linkLogic = getLinkLogic(self, linkLogicClass);
++
++ if (linkLogic != null && linkLogic.checkLinkable(self, desc, request)) {
++ final DebugLogger log = Context.getContextTrusted().getLogger(Compiler.class);
++
++ if (log.isEnabled()) {
++ log.info("Linking optimistic builtin function: '", name, "' args=", Arrays.toString(request.getArguments()), " desc=", desc);
++ }
++
++ exceptionGuard = linkLogic.getRelinkException();
++
++ break;
++ }
++
++ //could not link this specialization because link check failed
++ forbidden.add(cf);
++ final CompiledFunction oldCf = cf;
++ cf = data.getBestInvoker(type, scope, forbidden);
++ assert oldCf != cf;
++ }
++
++ final GuardedInvocation bestInvoker = cf.createFunctionInvocation(type.returnType(), programPoint);
++ final MethodHandle callHandle = bestInvoker.getInvocation();
++
+ if (data.needsCallee()) {
+- final MethodHandle callHandle = getBestInvoker(type, request.getArguments());
+ if (scopeCall && needsWrappedThis()) {
+- // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
+ // (callee, this, args...) => (callee, [this], args...)
+- boundHandle = MH.filterArguments(callHandle, 1, GLOBALFILTER);
++ boundHandle = MH.filterArguments(callHandle, 1, SCRIPTFUNCTION_GLOBALFILTER);
+ } else {
+ // It's already (callee, this, args...), just what we need
+ boundHandle = callHandle;
+ }
++ } else if (data.isBuiltin() && "extend".equals(data.getName())) {
++ // NOTE: the only built-in named "extend" is NativeJava.extend. As a special-case we're binding the
++ // current lookup as its "this" so it can do security-sensitive creation of adapter classes.
++ boundHandle = MH.dropArguments(MH.bindTo(callHandle, desc.getLookup()), 0, type.parameterType(0), type.parameterType(1));
++ } else if (scopeCall && needsWrappedThis()) {
++ // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
++ // (this, args...) => ([this], args...)
++ boundHandle = MH.filterArguments(callHandle, 0, SCRIPTFUNCTION_GLOBALFILTER);
++ // ([this], args...) => ([callee], [this], args...)
++ boundHandle = MH.dropArguments(boundHandle, 0, type.parameterType(0));
+ } else {
+- final MethodHandle callHandle = getBestInvoker(type.dropParameterTypes(0, 1), request.getArguments());
+- if (data.isBuiltin() && "extend".equals(data.getName())) {
+- // NOTE: the only built-in named "extend" is NativeJava.extend. As a special-case we're binding the
+- // current lookup as its "this" so it can do security-sensitive creation of adapter classes.
+- boundHandle = MH.dropArguments(MH.bindTo(callHandle, desc.getLookup()), 0, Object.class, Object.class);
+- } else if (scopeCall && needsWrappedThis()) {
+- // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
+- // (this, args...) => ([this], args...)
+- boundHandle = MH.filterArguments(callHandle, 0, GLOBALFILTER);
+- // ([this], args...) => ([callee], [this], args...)
+- boundHandle = MH.dropArguments(boundHandle, 0, Object.class);
+- } else {
+- // (this, args...) => ([callee], this, args...)
+- boundHandle = MH.dropArguments(callHandle, 0, Object.class);
+- }
++ // (this, args...) => ([callee], this, args...)
++ boundHandle = MH.dropArguments(callHandle, 0, type.parameterType(0));
+ }
+
+ // For non-strict functions, check whether this-object is primitive type.
+@@ -557,8 +654,257 @@
+
+ boundHandle = pairArguments(boundHandle, type);
+
+- return new GuardedInvocation(boundHandle, guard == null ? getFunctionGuard(this) : guard);
+- }
++ if (bestInvoker.getSwitchPoints() != null) {
++ sps.addAll(Arrays.asList(bestInvoker.getSwitchPoints()));
++ }
++ final SwitchPoint[] spsArray = sps.isEmpty() ? null : sps.toArray(new SwitchPoint[sps.size()]);
++
++ return new GuardedInvocation(
++ boundHandle,
++ guard == null ?
++ getFunctionGuard(
++ this,
++ cf.getFlags()) :
++ guard,
++ spsArray,
++ exceptionGuard);
++ }
++
++ private GuardedInvocation createApplyOrCallCall(final boolean isApply, final CallSiteDescriptor desc, final LinkRequest request, final Object[] args) {
++ final MethodType descType = desc.getMethodType();
++ final int paramCount = descType.parameterCount();
++ if(descType.parameterType(paramCount - 1).isArray()) {
++ // This is vararg invocation of apply or call. This can normally only happen when we do a recursive
++ // invocation of createApplyOrCallCall (because we're doing apply-of-apply). In this case, create delegate
++ // linkage by unpacking the vararg invocation and use pairArguments to introduce the necessary spreader.
++ return createVarArgApplyOrCallCall(isApply, desc, request, args);
++ }
++
++ final boolean passesThis = paramCount > 2;
++ final boolean passesArgs = paramCount > 3;
++ final int realArgCount = passesArgs ? paramCount - 3 : 0;
++
++ final Object appliedFn = args[1];
++ final boolean appliedFnNeedsWrappedThis = needsWrappedThis(appliedFn);
++
++ //box call back to apply
++ CallSiteDescriptor appliedDesc = desc;
++ final SwitchPoint applyToCallSwitchPoint = Global.getBuiltinFunctionApplySwitchPoint();
++ //enough to change the proto switchPoint here
++
++ final boolean isApplyToCall = NashornCallSiteDescriptor.isApplyToCall(desc);
++ final boolean isFailedApplyToCall = isApplyToCall && applyToCallSwitchPoint.hasBeenInvalidated();
++
++ // R(apply|call, ...) => R(...)
++ MethodType appliedType = descType.dropParameterTypes(0, 1);
++ if (!passesThis) {
++ // R() => R(this)
++ appliedType = appliedType.insertParameterTypes(1, Object.class);
++ } else if (appliedFnNeedsWrappedThis) {
++ appliedType = appliedType.changeParameterType(1, Object.class);
++ }
++
++ /*
++ * dropArgs is a synthetic method handle that contains any args that we need to
++ * get rid of that come after the arguments array in the apply case. We adapt
++ * the callsite to ask for 3 args only and then dropArguments on the method handle
++ * to make it fit the extraneous args.
++ */
++ MethodType dropArgs = MH.type(void.class);
++ if (isApply && !isFailedApplyToCall) {
++ final int pc = appliedType.parameterCount();
++ for (int i = 3; i < pc; i++) {
++ dropArgs = dropArgs.appendParameterTypes(appliedType.parameterType(i));
++ }
++ if (pc > 3) {
++ appliedType = appliedType.dropParameterTypes(3, pc);
++ }
++ }
++
++ if (isApply || isFailedApplyToCall) {
++ if (passesArgs) {
++ // R(this, args) => R(this, Object[])
++ appliedType = appliedType.changeParameterType(2, Object[].class);
++ // drop any extraneous arguments for the apply fail case
++ if (isFailedApplyToCall) {
++ appliedType = appliedType.dropParameterTypes(3, paramCount - 1);
++ }
++ } else {
++ // R(this) => R(this, Object[])
++ appliedType = appliedType.insertParameterTypes(2, Object[].class);
++ }
++ }
++
++ appliedDesc = appliedDesc.changeMethodType(appliedType); //no extra args
++
++ // Create the same arguments for the delegate linking request that would be passed in an actual apply'd invocation
++ final Object[] appliedArgs = new Object[isApply ? 3 : appliedType.parameterCount()];
++ appliedArgs[0] = appliedFn;
++ appliedArgs[1] = passesThis ? appliedFnNeedsWrappedThis ? ScriptFunctionData.wrapThis(args[2]) : args[2] : ScriptRuntime.UNDEFINED;
++ if (isApply && !isFailedApplyToCall) {
++ appliedArgs[2] = passesArgs ? NativeFunction.toApplyArgs(args[3]) : ScriptRuntime.EMPTY_ARRAY;
++ } else {
++ if (passesArgs) {
++ if (isFailedApplyToCall) {
++ final Object[] tmp = new Object[args.length - 3];
++ System.arraycopy(args, 3, tmp, 0, tmp.length);
++ appliedArgs[2] = NativeFunction.toApplyArgs(tmp);
++ } else {
++ assert !isApply;
++ System.arraycopy(args, 3, appliedArgs, 2, args.length - 3);
++ }
++ } else if (isFailedApplyToCall) {
++ appliedArgs[2] = ScriptRuntime.EMPTY_ARRAY;
++ }
++ }
++
++ // Ask the linker machinery for an invocation of the target function
++ final LinkRequest appliedRequest = request.replaceArguments(appliedDesc, appliedArgs);
++
++ GuardedInvocation appliedInvocation;
++ try {
++ appliedInvocation = Bootstrap.getLinkerServices().getGuardedInvocation(appliedRequest);
++ } catch (final RuntimeException | Error e) {
++ throw e;
++ } catch (final Exception e) {
++ throw new RuntimeException(e);
++ }
++ assert appliedRequest != null; // Bootstrap.isCallable() returned true for args[1], so it must produce a linkage.
++
++ final Class<?> applyFnType = descType.parameterType(0);
++ MethodHandle inv = appliedInvocation.getInvocation(); //method handle from apply invocation. the applied function invocation
++
++ if (isApply && !isFailedApplyToCall) {
++ if (passesArgs) {
++ // Make sure that the passed argArray is converted to Object[] the same way NativeFunction.apply() would do it.
++ inv = MH.filterArguments(inv, 2, NativeFunction.TO_APPLY_ARGS);
++ } else {
++ // If the original call site doesn't pass argArray, pass in an empty array
++ inv = MH.insertArguments(inv, 2, (Object)ScriptRuntime.EMPTY_ARRAY);
++ }
++ }
++
++ if (isApplyToCall) {
++ if (isFailedApplyToCall) {
++ //take the real arguments that were passed to a call and force them into the apply instead
++ Context.getContextTrusted().getLogger(ApplySpecialization.class).info("Collection arguments to revert call to apply in " + appliedFn);
++ inv = MH.asCollector(inv, Object[].class, realArgCount);
++ } else {
++ appliedInvocation = appliedInvocation.addSwitchPoint(applyToCallSwitchPoint);
++ }
++ }
++
++ if (!passesThis) {
++ // If the original call site doesn't pass in a thisArg, pass in Global/undefined as needed
++ inv = bindImplicitThis(appliedFn, inv);
++ } else if (appliedFnNeedsWrappedThis) {
++ // target function needs a wrapped this, so make sure we filter for that
++ inv = MH.filterArguments(inv, 1, WRAP_THIS);
++ }
++ inv = MH.dropArguments(inv, 0, applyFnType);
++
++ /*
++ * Dropargs can only be non-()V in the case of isApply && !isFailedApplyToCall, which
++ * is when we need to add arguments to the callsite to catch and ignore the synthetic
++ * extra args that someone has added to the command line.
++ */
++ for (int i = 0; i < dropArgs.parameterCount(); i++) {
++ inv = MH.dropArguments(inv, 4 + i, dropArgs.parameterType(i));
++ }
++
++ MethodHandle guard = appliedInvocation.getGuard();
++ // If the guard checks the value of "this" but we aren't passing thisArg, insert the default one
++ if (!passesThis && guard.type().parameterCount() > 1) {
++ guard = bindImplicitThis(appliedFn, guard);
++ }
++ final MethodType guardType = guard.type();
++
++ // We need to account for the dropped (apply|call) function argument.
++ guard = MH.dropArguments(guard, 0, descType.parameterType(0));
++ // Take the "isApplyFunction" guard, and bind it to this function.
++ MethodHandle applyFnGuard = MH.insertArguments(IS_APPLY_FUNCTION, 2, this); //TODO replace this with switchpoint
++ // Adapt the guard to receive all the arguments that the original guard does.
++ applyFnGuard = MH.dropArguments(applyFnGuard, 2, guardType.parameterArray());
++ // Fold the original function guard into our apply guard.
++ guard = MH.foldArguments(applyFnGuard, guard);
++
++ return appliedInvocation.replaceMethods(inv, guard);
++ }
++
++ /*
++ * This method is used for linking nested apply. Specialized apply and call linking will create a variable arity
++ * call site for an apply call; when createApplyOrCallCall sees a linking request for apply or call with
++ * Nashorn-style variable arity call site (last argument type is Object[]) it'll delegate to this method.
++ * This method converts the link request from a vararg to a non-vararg one (unpacks the array), then delegates back
++ * to createApplyOrCallCall (with which it is thus mutually recursive), and adds appropriate argument spreaders to
++ * invocation and the guard of whatever createApplyOrCallCall returned to adapt it back into a variable arity
++ * invocation. It basically reduces the problem of vararg call site linking of apply and call back to the (already
++ * solved by createApplyOrCallCall) non-vararg call site linking.
++ */
++ private GuardedInvocation createVarArgApplyOrCallCall(final boolean isApply, final CallSiteDescriptor desc,
++ final LinkRequest request, final Object[] args) {
++ final MethodType descType = desc.getMethodType();
++ final int paramCount = descType.parameterCount();
++ final Object[] varArgs = (Object[])args[paramCount - 1];
++ // -1 'cause we're not passing the vararg array itself
++ final int copiedArgCount = args.length - 1;
++ final int varArgCount = varArgs.length;
++
++ // Spread arguments for the delegate createApplyOrCallCall invocation.
++ final Object[] spreadArgs = new Object[copiedArgCount + varArgCount];
++ System.arraycopy(args, 0, spreadArgs, 0, copiedArgCount);
++ System.arraycopy(varArgs, 0, spreadArgs, copiedArgCount, varArgCount);
++
++ // Spread call site descriptor for the delegate createApplyOrCallCall invocation. We drop vararg array and
++ // replace it with a list of Object.class.
++ final MethodType spreadType = descType.dropParameterTypes(paramCount - 1, paramCount).appendParameterTypes(
++ Collections.<Class<?>>nCopies(varArgCount, Object.class));
++ final CallSiteDescriptor spreadDesc = desc.changeMethodType(spreadType);
++
++ // Delegate back to createApplyOrCallCall with the spread (that is, reverted to non-vararg) request/
++ final LinkRequest spreadRequest = request.replaceArguments(spreadDesc, spreadArgs);
++ final GuardedInvocation spreadInvocation = createApplyOrCallCall(isApply, spreadDesc, spreadRequest, spreadArgs);
++
++ // Add spreader combinators to returned invocation and guard.
++ return spreadInvocation.replaceMethods(
++ // Use standard ScriptObject.pairArguments on the invocation
++ pairArguments(spreadInvocation.getInvocation(), descType),
++ // Use our specialized spreadGuardArguments on the guard (see below).
++ spreadGuardArguments(spreadInvocation.getGuard(), descType));
++ }
++
++ private static MethodHandle spreadGuardArguments(final MethodHandle guard, final MethodType descType) {
++ final MethodType guardType = guard.type();
++ final int guardParamCount = guardType.parameterCount();
++ final int descParamCount = descType.parameterCount();
++ final int spreadCount = guardParamCount - descParamCount + 1;
++ if (spreadCount <= 0) {
++ // Guard doesn't dip into the varargs
++ return guard;
++ }
++
++ final MethodHandle arrayConvertingGuard;
++ // If the last parameter type of the guard is an array, then it is already itself a guard for a vararg apply
++ // invocation. We must filter the last argument with toApplyArgs otherwise deeper levels of nesting will fail
++ // with ClassCastException of NativeArray to Object[].
++ if(guardType.parameterType(guardParamCount - 1).isArray()) {
++ arrayConvertingGuard = MH.filterArguments(guard, guardParamCount - 1, NativeFunction.TO_APPLY_ARGS);
++ } else {
++ arrayConvertingGuard = guard;
++ }
++
++ return ScriptObject.adaptHandleToVarArgCallSite(arrayConvertingGuard, descParamCount);
++ }
++
++ private static MethodHandle bindImplicitThis(final Object fn, final MethodHandle mh) {
++ final MethodHandle bound;
++ if(fn instanceof ScriptFunction && ((ScriptFunction)fn).needsWrappedThis()) {
++ bound = MH.filterArguments(mh, 1, SCRIPTFUNCTION_GLOBALFILTER);
++ } else {
++ bound = mh;
++ }
++ return MH.insertArguments(bound, 1, ScriptRuntime.UNDEFINED);
++ }
+
+ /**
+ * Used for noSuchMethod/noSuchProperty and JSAdapter hooks.
+@@ -566,7 +912,7 @@
+ * These don't want a callee parameter, so bind that. Name binding is optional.
+ */
+ MethodHandle getCallMethodHandle(final MethodType type, final String bindName) {
+- return pairArguments(bindToNameIfNeeded(bindToCalleeIfNeeded(getBestInvoker(type, null)), bindName), type);
++ return pairArguments(bindToNameIfNeeded(bindToCalleeIfNeeded(data.getGenericInvoker(scope)), bindName), type);
+ }
+
+ private static MethodHandle bindToNameIfNeeded(final MethodHandle methodHandle, final String bindName) {
+@@ -594,8 +940,13 @@
+ *
+ * @return method handle for guard
+ */
+- private static MethodHandle getFunctionGuard(final ScriptFunction function) {
++ private static MethodHandle getFunctionGuard(final ScriptFunction function, final int flags) {
+ assert function.data != null;
++ // Built-in functions have a 1-1 correspondence to their ScriptFunctionData, so we can use a cheaper identity
++ // comparison for them.
++ if (function.data.isBuiltin()) {
++ return Guards.getIdentityGuard(function);
++ }
+ return MH.insertArguments(IS_FUNCTION_MH, 1, function.data);
+ }
+
+@@ -623,10 +974,17 @@
+ return self instanceof ScriptFunction && ((ScriptFunction)self).data == data && arg instanceof ScriptObject;
+ }
+
++ //TODO this can probably be removed given that we have builtin switchpoints in the context
++ @SuppressWarnings("unused")
++ private static boolean isApplyFunction(final boolean appliedFnCondition, final Object self, final Object expectedSelf) {
++ // NOTE: we're using self == expectedSelf as we're only using this with built-in functions apply() and call()
++ return appliedFnCondition && self == expectedSelf;
++ }
++
+ @SuppressWarnings("unused")
+ private static Object[] addZerothElement(final Object[] args, final Object value) {
+ // extends input array with by adding new zeroth element
+- final Object[] src = (args == null)? ScriptRuntime.EMPTY_ARRAY : args;
++ final Object[] src = args == null? ScriptRuntime.EMPTY_ARRAY : args;
+ final Object[] result = new Object[src.length + 1];
+ System.arraycopy(src, 0, result, 1, src.length);
+ result[0] = value;
+@@ -642,14 +1000,12 @@
+ }
+ }
+
+- private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+- final Class<?> own = ScriptFunction.class;
+- final MethodType mt = MH.type(rtype, types);
+- try {
+- return MH.findStatic(MethodHandles.lookup(), own, name, mt);
+- } catch (final MethodHandleFactory.LookupException e) {
+- return MH.findVirtual(MethodHandles.lookup(), own, name, mt);
+- }
++ private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
++ return MH.findStatic(MethodHandles.lookup(), ScriptFunction.class, name, MH.type(rtype, types));
++ }
++
++ private static MethodHandle findOwnMH_V(final String name, final Class<?> rtype, final Class<?>... types) {
++ return MH.findVirtual(MethodHandles.lookup(), ScriptFunction.class, name, MH.type(rtype, types));
+ }
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,12 +28,17 @@
+ import static jdk.nashorn.internal.lookup.Lookup.MH;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+-
++import java.io.IOException;
++import java.io.ObjectInputStream;
+ import java.io.Serializable;
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+ import java.lang.invoke.MethodType;
+-import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
++import java.util.Collection;
++import java.util.LinkedList;
++import java.util.List;
++import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
++
+
+ /**
+ * A container for data needed to instantiate a specific {@link ScriptFunction} at runtime.
+@@ -41,19 +46,36 @@
+ * constants array to reduce function instantiation overhead during runtime.
+ */
+ public abstract class ScriptFunctionData implements Serializable {
++ static final int MAX_ARITY = LinkerCallSite.ARGLIMIT;
++ static {
++ // Assert it fits in a byte, as that's what we store it in. It's just a size optimization though, so if needed
++ // "byte arity" field can be widened.
++ assert MAX_ARITY < 256;
++ }
+
+- /** Name of the function or "" for anonynous functions */
++ /** Name of the function or "" for anonymous functions */
+ protected final String name;
+
+- /** All versions of this function that have been generated to code */
+- protected final CompiledFunctions code;
++ /**
++ * A list of code versions of a function sorted in ascending order of generic descriptors.
++ */
++ protected transient LinkedList<CompiledFunction> code = new LinkedList<>();
+
+ /** Function flags */
+ protected int flags;
+
++ // Parameter arity of the function, corresponding to "f.length". E.g. "function f(a, b, c) { ... }" arity is 3, and
++ // some built-in ECMAScript functions have their arity declared by the specification. Note that regardless of this
++ // value, the function might still be capable of receiving variable number of arguments, see isVariableArity.
+ private int arity;
+
+- private static final MethodHandle NEWFILTER = findOwnMH("newFilter", Object.class, Object.class, Object.class);
++ /**
++ * A pair of method handles used for generic invoker and constructor. Field is volatile as it can be initialized by
++ * multiple threads concurrently, but we still tolerate a race condition in it as all values stored into it are
++ * idempotent.
++ */
++ private volatile transient GenericInvokers genericInvokers;
++
+ private static final MethodHandle BIND_VAR_ARGS = findOwnMH("bindVarArgs", Object[].class, Object[].class, Object[].class);
+
+ /** Is this a strict mode function? */
+@@ -66,6 +88,8 @@
+ public static final int NEEDS_CALLEE = 1 << 3;
+ /** Does this function make use of the this-object argument? */
+ public static final int USES_THIS = 1 << 4;
++ /** Is this a variable arity function? */
++ public static final int IS_VARIABLE_ARITY = 1 << 5;
+
+ /** Flag for strict or built-in functions */
+ public static final int IS_STRICT_OR_BUILTIN = IS_STRICT | IS_BUILTIN;
+@@ -79,39 +103,43 @@
+ /**
+ * Constructor
+ *
+- * @param name script function name
+- * @param arity arity
+- * @param flags the function flags
++ * @param name script function name
++ * @param arity arity
++ * @param flags the function flags
+ */
+ ScriptFunctionData(final String name, final int arity, final int flags) {
+ this.name = name;
+- this.arity = arity;
+- this.code = new CompiledFunctions();
+ this.flags = flags;
++ setArity(arity);
+ }
+
+ final int getArity() {
+ return arity;
+ }
+
++ final boolean isVariableArity() {
++ return (flags & IS_VARIABLE_ARITY) != 0;
++ }
++
+ /**
+ * Used from e.g. Native*$Constructors as an explicit call. TODO - make arity immutable and final
+ * @param arity new arity
+ */
+ void setArity(final int arity) {
++ if(arity < 0 || arity > MAX_ARITY) {
++ throw new IllegalArgumentException(String.valueOf(arity));
++ }
+ this.arity = arity;
+ }
+
+ CompiledFunction bind(final CompiledFunction originalInv, final ScriptFunction fn, final Object self, final Object[] args) {
+- final MethodHandle boundInvoker = bindInvokeHandle(originalInv.getInvoker(), fn, self, args);
++ final MethodHandle boundInvoker = bindInvokeHandle(originalInv.createComposableInvoker(), fn, self, args);
+
+- //TODO the boundinvoker.type() could actually be more specific here
+ if (isConstructor()) {
+- ensureConstructor(originalInv);
+- return new CompiledFunction(boundInvoker.type(), boundInvoker, bindConstructHandle(originalInv.getConstructor(), fn, args));
++ return new CompiledFunction(boundInvoker, bindConstructHandle(originalInv.createComposableConstructor(), fn, args), null);
+ }
+
+- return new CompiledFunction(boundInvoker.type(), boundInvoker);
++ return new CompiledFunction(boundInvoker);
+ }
+
+ /**
+@@ -122,6 +150,15 @@
+ return (flags & IS_STRICT) != 0;
+ }
+
++ /**
++ * Return the complete internal function name for this
++ * data, not anonymous or similar. May be identical
++ * @return internal function name
++ */
++ protected String getFunctionName() {
++ return getName();
++ }
++
+ boolean isBuiltin() {
+ return (flags & IS_BUILTIN) != 0;
+ }
+@@ -130,11 +167,7 @@
+ return (flags & IS_CONSTRUCTOR) != 0;
+ }
+
+- boolean needsCallee() {
+- // we don't know if we need a callee or not unless code has been compiled
+- ensureCompiled();
+- return (flags & NEEDS_CALLEE) != 0;
+- }
++ abstract boolean needsCallee();
+
+ /**
+ * Returns true if this is a non-strict, non-built-in function that requires non-primitive this argument
+@@ -161,6 +194,14 @@
+ */
+ @Override
+ public String toString() {
++ return name.isEmpty() ? "<anonymous>" : name;
++ }
++
++ /**
++ * Verbose description of data
++ * @return verbose description
++ */
++ public String toStringVerbose() {
+ final StringBuilder sb = new StringBuilder();
+
+ sb.append("name='").
+@@ -181,44 +222,30 @@
+ * and not suddenly a "real" object
+ *
+ * @param callSiteType callsite type
+- * @param args arguments at callsite on first trampoline invocation
+- * @return method handle to best invoker
++ * @return compiled function object representing the best invoker.
+ */
+- MethodHandle getBestInvoker(final MethodType callSiteType, final Object[] args) {
+- return getBest(callSiteType).getInvoker();
++ final CompiledFunction getBestInvoker(final MethodType callSiteType, final ScriptObject runtimeScope) {
++ return getBestInvoker(callSiteType, runtimeScope, CompiledFunction.NO_FUNCTIONS);
+ }
+
+- MethodHandle getBestInvoker(final MethodType callSiteType) {
+- return getBestInvoker(callSiteType, null);
++ final CompiledFunction getBestInvoker(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden) {
++ final CompiledFunction cf = getBest(callSiteType, runtimeScope, forbidden);
++ assert cf != null;
++ return cf;
+ }
+
+- MethodHandle getBestConstructor(final MethodType callSiteType, final Object[] args) {
++ final CompiledFunction getBestConstructor(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden) {
+ if (!isConstructor()) {
+ throw typeError("not.a.constructor", toSource());
+ }
+- ensureCodeGenerated();
+-
+- final CompiledFunction best = getBest(callSiteType);
+- ensureConstructor(best);
+- return best.getConstructor();
+- }
+-
+- MethodHandle getBestConstructor(final MethodType callSiteType) {
+- return getBestConstructor(callSiteType, null);
+- }
+-
+- /**
+- * Subclass responsibility. If we can have lazy code generation, this is a hook to ensure that
+- * code exists before performing an operation.
+- */
+- protected void ensureCodeGenerated() {
+- //empty
++ // Constructor call sites don't have a "this", but getBest is meant to operate on "callee, this, ..." style
++ final CompiledFunction cf = getBest(callSiteType.insertParameterTypes(1, Object.class), runtimeScope, forbidden);
++ return cf;
+ }
+
+ /**
+ * If we can have lazy code generation, this is a hook to ensure that the code has been compiled.
+- * This does not guarantee the code been installed in this {@code ScriptFunctionData} instance;
+- * use {@link #ensureCodeGenerated()} to install the actual method handles.
++ * This does not guarantee the code been installed in this {@code ScriptFunctionData} instance
+ */
+ protected void ensureCompiled() {
+ //empty
+@@ -229,27 +256,139 @@
+ * is generated, get the most generic of all versions of this function and adapt it
+ * to Objects.
+ *
+- * TODO this is only public because {@link JavaAdapterFactory} can't supply us with
+- * a MethodType that we can use for lookup due to boostrapping problems. Can be fixed
+- *
++ * @param runtimeScope the runtime scope. It can be used to evaluate types of scoped variables to guide the
++ * optimistic compilation, should the call to this method trigger code compilation. Can be null if current runtime
++ * scope is not known, but that might cause compilation of code that will need more deoptimization passes.
+ * @return generic invoker of this script function
+ */
+- public final MethodHandle getGenericInvoker() {
+- ensureCodeGenerated();
+- return code.generic().getInvoker();
++ final MethodHandle getGenericInvoker(final ScriptObject runtimeScope) {
++ // This method has race conditions both on genericsInvoker and genericsInvoker.invoker, but even if invoked
++ // concurrently, they'll create idempotent results, so it doesn't matter. We could alternatively implement this
++ // using java.util.concurrent.AtomicReferenceFieldUpdater, but it's hardly worth it.
++ final GenericInvokers lgenericInvokers = ensureGenericInvokers();
++ MethodHandle invoker = lgenericInvokers.invoker;
++ if(invoker == null) {
++ lgenericInvokers.invoker = invoker = createGenericInvoker(runtimeScope);
++ }
++ return invoker;
+ }
+
+- final MethodHandle getGenericConstructor() {
+- ensureCodeGenerated();
+- ensureConstructor(code.generic());
+- return code.generic().getConstructor();
++ private MethodHandle createGenericInvoker(final ScriptObject runtimeScope) {
++ return makeGenericMethod(getGeneric(runtimeScope).createComposableInvoker());
+ }
+
+- private CompiledFunction getBest(final MethodType callSiteType) {
+- ensureCodeGenerated();
+- return code.best(callSiteType);
++ final MethodHandle getGenericConstructor(final ScriptObject runtimeScope) {
++ // This method has race conditions both on genericsInvoker and genericsInvoker.constructor, but even if invoked
++ // concurrently, they'll create idempotent results, so it doesn't matter. We could alternatively implement this
++ // using java.util.concurrent.AtomicReferenceFieldUpdater, but it's hardly worth it.
++ final GenericInvokers lgenericInvokers = ensureGenericInvokers();
++ MethodHandle constructor = lgenericInvokers.constructor;
++ if(constructor == null) {
++ lgenericInvokers.constructor = constructor = createGenericConstructor(runtimeScope);
++ }
++ return constructor;
+ }
+
++ private MethodHandle createGenericConstructor(final ScriptObject runtimeScope) {
++ return makeGenericMethod(getGeneric(runtimeScope).createComposableConstructor());
++ }
++
++ private GenericInvokers ensureGenericInvokers() {
++ GenericInvokers lgenericInvokers = genericInvokers;
++ if(lgenericInvokers == null) {
++ genericInvokers = lgenericInvokers = new GenericInvokers();
++ }
++ return lgenericInvokers;
++ }
++
++ private static MethodType widen(final MethodType cftype) {
++ final Class<?>[] paramTypes = new Class<?>[cftype.parameterCount()];
++ for (int i = 0; i < cftype.parameterCount(); i++) {
++ paramTypes[i] = cftype.parameterType(i).isPrimitive() ? cftype.parameterType(i) : Object.class;
++ }
++ return MH.type(cftype.returnType(), paramTypes);
++ }
++
++ /**
++ * Used to find an apply to call version that fits this callsite.
++ * We cannot just, as in the normal matcher case, return e.g. (Object, Object, int)
++ * for (Object, Object, int, int, int) or we will destroy the semantics and get
++ * a function that, when padded with undefineds, behaves differently
++ * @param type actual call site type
++ * @return apply to call that perfectly fits this callsite or null if none found
++ */
++ CompiledFunction lookupExactApplyToCall(final MethodType type) {
++ for (final CompiledFunction cf : code) {
++ if (!cf.isApplyToCall()) {
++ continue;
++ }
++
++ final MethodType cftype = cf.type();
++ if (cftype.parameterCount() != type.parameterCount()) {
++ continue;
++ }
++
++ if (widen(cftype).equals(widen(type))) {
++ return cf;
++ }
++ }
++
++ return null;
++ }
++
++ CompiledFunction pickFunction(final MethodType callSiteType, final boolean canPickVarArg) {
++ for (final CompiledFunction candidate : code) {
++ if (candidate.matchesCallSite(callSiteType, canPickVarArg)) {
++ return candidate;
++ }
++ }
++ return null;
++ }
++
++ /**
++ * Returns the best function for the specified call site type.
++ * @param callSiteType The call site type. Call site types are expected to have the form
++ * {@code (callee, this[, args...])}.
++ * @param runtimeScope the runtime scope. It can be used to evaluate types of scoped variables to guide the
++ * optimistic compilation, should the call to this method trigger code compilation. Can be null if current runtime
++ * scope is not known, but that might cause compilation of code that will need more deoptimization passes.
++ * @return the best function for the specified call site type.
++ */
++ CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden) {
++ assert callSiteType.parameterCount() >= 2 : callSiteType; // Must have at least (callee, this)
++ assert callSiteType.parameterType(0).isAssignableFrom(ScriptFunction.class) : callSiteType; // Callee must be assignable from script function
++
++ if (isRecompilable()) {
++ final CompiledFunction candidate = pickFunction(callSiteType, false);
++ if (candidate != null) {
++ return candidate;
++ }
++ return pickFunction(callSiteType, true); //try vararg last
++ }
++
++ CompiledFunction best = null;
++ for (final CompiledFunction candidate: code) {
++ if (!forbidden.contains(candidate) && candidate.betterThanFinal(best, callSiteType)) {
++ best = candidate;
++ }
++ }
++
++ return best;
++ }
++
++
++ abstract boolean isRecompilable();
++
++ CompiledFunction getGeneric(final ScriptObject runtimeScope) {
++ return getBest(getGenericType(), runtimeScope, CompiledFunction.NO_FUNCTIONS);
++ }
++
++ /**
++ * Get a method type for a generic invoker.
++ * @return the method type for the generic invoker
++ */
++ abstract MethodType getGenericType();
++
+ /**
+ * Allocates an object using this function's allocator.
+ *
+@@ -278,91 +417,17 @@
+ * @param args additional arguments to bind. Can be null.
+ */
+ ScriptFunctionData makeBoundFunctionData(final ScriptFunction fn, final Object self, final Object[] args) {
+- ensureCodeGenerated();
+-
+ final Object[] allArgs = args == null ? ScriptRuntime.EMPTY_ARRAY : args;
+ final int length = args == null ? 0 : args.length;
+ // Clear the callee and this flags
+ final int boundFlags = flags & ~NEEDS_CALLEE & ~USES_THIS;
+
+- CompiledFunctions boundList = new CompiledFunctions();
+- if (code.size() == 1) {
+- // only one variant - bind that
+- boundList.add(bind(code.first(), fn, self, allArgs));
+- } else {
+- // There are specialized versions. Get the most generic one.
+- // This is to avoid ambiguous overloaded versions of bound and
+- // specialized variants and choosing wrong overload.
+- final MethodHandle genInvoker = getGenericInvoker();
+- final CompiledFunction inv = new CompiledFunction(genInvoker.type(), genInvoker, getGenericConstructor());
+- boundList.add(bind(inv, fn, self, allArgs));
+- }
++ final List<CompiledFunction> boundList = new LinkedList<>();
++ final ScriptObject runtimeScope = fn.getScope();
++ final CompiledFunction bindTarget = new CompiledFunction(getGenericInvoker(runtimeScope), getGenericConstructor(runtimeScope), null);
++ boundList.add(bind(bindTarget, fn, self, allArgs));
+
+- return new FinalScriptFunctionData(name, arity == -1 ? -1 : Math.max(0, arity - length), boundList, boundFlags);
+- }
+-
+- /**
+- * Compose a constructor given a primordial constructor handle.
+- *
+- * @param ctor primordial constructor handle
+- * @return the composed constructor
+- */
+- protected MethodHandle composeConstructor(final MethodHandle ctor) {
+- // If it was (callee, this, args...), permute it to (this, callee, args...). We're doing this because having
+- // "this" in the first argument position is what allows the elegant folded composition of
+- // (newFilter x constructor x allocator) further down below in the code. Also, ensure the composite constructor
+- // always returns Object.
+- final boolean needsCallee = needsCallee(ctor);
+- MethodHandle composedCtor = needsCallee ? swapCalleeAndThis(ctor) : ctor;
+-
+- composedCtor = changeReturnTypeToObject(composedCtor);
+-
+- final MethodType ctorType = composedCtor.type();
+-
+- // Construct a dropping type list for NEWFILTER, but don't include constructor "this" into it, so it's actually
+- // captured as "allocation" parameter of NEWFILTER after we fold the constructor into it.
+- // (this, [callee, ]args...) => ([callee, ]args...)
+- final Class<?>[] ctorArgs = ctorType.dropParameterTypes(0, 1).parameterArray();
+-
+- // Fold constructor into newFilter that replaces the return value from the constructor with the originally
+- // allocated value when the originally allocated value is a primitive.
+- // (result, this, [callee, ]args...) x (this, [callee, ]args...) => (this, [callee, ]args...)
+- composedCtor = MH.foldArguments(MH.dropArguments(NEWFILTER, 2, ctorArgs), composedCtor);
+-
+- // allocate() takes a ScriptFunction and returns a newly allocated ScriptObject...
+- if (needsCallee) {
+- // ...we either fold it into the previous composition, if we need both the ScriptFunction callee object and
+- // the newly allocated object in the arguments, so (this, callee, args...) x (callee) => (callee, args...),
+- // or...
+- return MH.foldArguments(composedCtor, ScriptFunction.ALLOCATE);
+- }
+-
+- // ...replace the ScriptFunction argument with the newly allocated object, if it doesn't need the callee
+- // (this, args...) filter (callee) => (callee, args...)
+- return MH.filterArguments(composedCtor, 0, ScriptFunction.ALLOCATE);
+- }
+-
+- /**
+- * If this function's method handles need a callee parameter, swap the order of first two arguments for the passed
+- * method handle. If this function's method handles don't need a callee parameter, returns the original method
+- * handle unchanged.
+- *
+- * @param mh a method handle with order of arguments {@code (callee, this, args...)}
+- *
+- * @return a method handle with order of arguments {@code (this, callee, args...)}
+- */
+- private static MethodHandle swapCalleeAndThis(final MethodHandle mh) {
+- final MethodType type = mh.type();
+- assert type.parameterType(0) == ScriptFunction.class : type;
+- assert type.parameterType(1) == Object.class : type;
+- final MethodType newType = type.changeParameterType(0, Object.class).changeParameterType(1, ScriptFunction.class);
+- final int[] reorder = new int[type.parameterCount()];
+- reorder[0] = 1;
+- assert reorder[1] == 0;
+- for (int i = 2; i < reorder.length; ++i) {
+- reorder[i] = i;
+- }
+- return MethodHandles.permuteArguments(mh, newType, reorder);
++ return new FinalScriptFunctionData(name, Math.max(0, getArity() - length), boundList, boundFlags);
+ }
+
+ /**
+@@ -373,7 +438,11 @@
+ * @return the converted this object
+ */
+ private Object convertThisObject(final Object thiz) {
+- if (!(thiz instanceof ScriptObject) && needsWrappedThis()) {
++ return needsWrappedThis() ? wrapThis(thiz) : thiz;
++ }
++
++ static Object wrapThis(final Object thiz) {
++ if (!(thiz instanceof ScriptObject)) {
+ if (JSType.nullOrUndefined(thiz)) {
+ return Context.getGlobal();
+ }
+@@ -440,7 +509,7 @@
+ } else {
+ // If target is already bound, insert additional bound arguments after "this" argument, at position 1.
+ final int argInsertPos = isTargetBound ? 1 : 0;
+- final Object[] boundArgs = new Object[Math.min(originalInvoker.type().parameterCount() - argInsertPos, args.length + (isTargetBound ? 0 : (needsCallee ? 2 : 1)))];
++ final Object[] boundArgs = new Object[Math.min(originalInvoker.type().parameterCount() - argInsertPos, args.length + (isTargetBound ? 0 : needsCallee ? 2 : 1))];
+ int next = 0;
+ if (!isTargetBound) {
+ if (needsCallee) {
+@@ -506,6 +575,38 @@
+ }
+
+ /**
++ * Takes a method handle, and returns a potentially different method handle that can be used in
++ * {@code ScriptFunction#invoke(Object, Object...)} or {code ScriptFunction#construct(Object, Object...)}.
++ * The returned method handle will be sure to return {@code Object}, and will have all its parameters turned into
++ * {@code Object} as well, except for the following ones:
++ * <ul>
++ * <li>a last parameter of type {@code Object[]} which is used for vararg functions,</li>
++ * <li>the first argument, which is forced to be {@link ScriptFunction}, in case the function receives itself
++ * (callee) as an argument.</li>
++ * </ul>
++ *
++ * @param mh the original method handle
++ *
++ * @return the new handle, conforming to the rules above.
++ */
++ private static MethodHandle makeGenericMethod(final MethodHandle mh) {
++ final MethodType type = mh.type();
++ final MethodType newType = makeGenericType(type);
++ return type.equals(newType) ? mh : mh.asType(newType);
++ }
++
++ private static MethodType makeGenericType(final MethodType type) {
++ MethodType newType = type.generic();
++ if (isVarArg(type)) {
++ newType = newType.changeParameterType(type.parameterCount() - 1, Object[].class);
++ }
++ if (needsCallee(type)) {
++ newType = newType.changeParameterType(0, ScriptFunction.class);
++ }
++ return newType;
++ }
++
++ /**
+ * Execute this script function.
+ *
+ * @param self Target object.
+@@ -515,9 +616,9 @@
+ * @throws Throwable if there is an exception/error with the invocation or thrown from it
+ */
+ Object invoke(final ScriptFunction fn, final Object self, final Object... arguments) throws Throwable {
+- final MethodHandle mh = getGenericInvoker();
+- final Object selfObj = convertThisObject(self);
+- final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments;
++ final MethodHandle mh = getGenericInvoker(fn.getScope());
++ final Object selfObj = convertThisObject(self);
++ final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments;
+
+ DebuggerSupport.notifyInvoke(mh);
+
+@@ -571,7 +672,7 @@
+ }
+
+ Object construct(final ScriptFunction fn, final Object... arguments) throws Throwable {
+- final MethodHandle mh = getGenericConstructor();
++ final MethodHandle mh = getGenericConstructor(fn.getScope());
+ final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments;
+
+ DebuggerSupport.notifyInvoke(mh);
+@@ -690,24 +791,6 @@
+ }
+
+ /**
+- * Adapts the method handle so its return type is {@code Object}. If the handle's return type is already
+- * {@code Object}, the handle is returned unchanged.
+- *
+- * @param mh the handle to adapt
+- * @return the adapted handle
+- */
+- private static MethodHandle changeReturnTypeToObject(final MethodHandle mh) {
+- final MethodType type = mh.type();
+- return (type.returnType() == Object.class) ? mh : MH.asType(mh, type.changeReturnType(Object.class));
+- }
+-
+- private void ensureConstructor(final CompiledFunction inv) {
+- if (!inv.hasConstructor()) {
+- inv.setConstructor(composeConstructor(inv.getInvoker()));
+- }
+- }
+-
+- /**
+ * Heuristic to figure out if the method handle has a callee argument. If it's type is
+ * {@code (ScriptFunction, ...)}, then we'll assume it has a callee argument. We need this as
+ * the constructor above is not passed this information, and can't just blindly assume it's false
+@@ -719,8 +802,18 @@
+ * @return true if the method handle expects a callee, false otherwise
+ */
+ protected static boolean needsCallee(final MethodHandle mh) {
+- final MethodType type = mh.type();
+- return (type.parameterCount() > 0 && type.parameterType(0) == ScriptFunction.class);
++ return needsCallee(mh.type());
++ }
++
++ static boolean needsCallee(final MethodType type) {
++ final int length = type.parameterCount();
++
++ if (length == 0) {
++ return false;
++ }
++
++ final Class<?> param0 = type.parameterType(0);
++ return param0 == ScriptFunction.class || param0 == boolean.class && length > 1 && type.parameterType(1) == ScriptFunction.class;
+ }
+
+ /**
+@@ -731,10 +824,21 @@
+ * @return true if vararg
+ */
+ protected static boolean isVarArg(final MethodHandle mh) {
+- final MethodType type = mh.type();
++ return isVarArg(mh.type());
++ }
++
++ static boolean isVarArg(final MethodType type) {
+ return type.parameterType(type.parameterCount() - 1).isArray();
+ }
+
++ /**
++ * Is this ScriptFunction declared in a dynamic context
++ * @return true if in dynamic context, false if not or irrelevant
++ */
++ public boolean inDynamicContext() {
++ return false;
++ }
++
+ @SuppressWarnings("unused")
+ private static Object[] bindVarArgs(final Object[] array1, final Object[] array2) {
+ if (array2 == null) {
+@@ -755,12 +859,22 @@
+ return concat;
+ }
+
+- @SuppressWarnings("unused")
+- private static Object newFilter(final Object result, final Object allocation) {
+- return (result instanceof ScriptObject || !JSType.isPrimitive(result))? result : allocation;
+- }
+-
+ private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+ return MH.findStatic(MethodHandles.lookup(), ScriptFunctionData.class, name, MH.type(rtype, types));
+ }
++
++ /**
++ * This class is used to hold the generic invoker and generic constructor pair. It is structured in this way since
++ * most functions will never use them, so this way ScriptFunctionData only pays storage cost for one null reference
++ * to the GenericInvokers object, instead of two null references for the two method handles.
++ */
++ private static final class GenericInvokers {
++ volatile MethodHandle invoker;
++ volatile MethodHandle constructor;
++ }
++
++ private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
++ in.defaultReadObject();
++ code = new LinkedList<>();
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,7 +26,6 @@
+ package jdk.nashorn.internal.runtime;
+
+ import java.security.CodeSource;
+-import java.security.ProtectionDomain;
+
+ /**
+ * Responsible for loading script generated classes.
+@@ -50,7 +49,7 @@
+ }
+
+ @Override
+- protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
++ protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
+ checkPackageAccess(name);
+ if (name.startsWith(NASHORN_PKG_PREFIX)) {
+ return context.getSharedLoader().loadClass(name);
+--- ./nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,11 +25,16 @@
+
+ package jdk.nashorn.internal.runtime;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCall;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
++import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
+ import static jdk.nashorn.internal.lookup.Lookup.MH;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
++import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_DOUBLE;
++import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_INT;
++import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_LONG;
+ import static jdk.nashorn.internal.runtime.PropertyDescriptor.CONFIGURABLE;
+ import static jdk.nashorn.internal.runtime.PropertyDescriptor.ENUMERABLE;
+ import static jdk.nashorn.internal.runtime.PropertyDescriptor.GET;
+@@ -37,8 +42,13 @@
+ import static jdk.nashorn.internal.runtime.PropertyDescriptor.VALUE;
+ import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE;
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
+ import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex;
+ import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.isScopeFlag;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.isStrictFlag;
++import static jdk.nashorn.internal.runtime.linker.NashornGuards.explicitInstanceOfCheck;
+
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+@@ -55,18 +65,18 @@
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+-
+ import jdk.internal.dynalink.CallSiteDescriptor;
+ import jdk.internal.dynalink.linker.GuardedInvocation;
+ import jdk.internal.dynalink.linker.LinkRequest;
+ import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+ import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+ import jdk.nashorn.internal.codegen.ObjectClassGenerator;
++import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.lookup.Lookup;
+-import jdk.nashorn.internal.lookup.MethodHandleFactory;
+ import jdk.nashorn.internal.objects.AccessorPropertyDescriptor;
+ import jdk.nashorn.internal.objects.DataPropertyDescriptor;
+ import jdk.nashorn.internal.objects.Global;
++import jdk.nashorn.internal.objects.NativeArray;
+ import jdk.nashorn.internal.runtime.arrays.ArrayData;
+ import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
+ import jdk.nashorn.internal.runtime.linker.Bootstrap;
+@@ -90,29 +100,35 @@
+ * </ul>
+ */
+
+-public abstract class ScriptObject implements PropertyAccess {
++public abstract class ScriptObject implements PropertyAccess, Cloneable {
+ /** __proto__ special property name inside object literals. ES6 draft. */
+ public static final String PROTO_PROPERTY_NAME = "__proto__";
+
+ /** Search fall back routine name for "no such method" */
+- static final String NO_SUCH_METHOD_NAME = "__noSuchMethod__";
++ public static final String NO_SUCH_METHOD_NAME = "__noSuchMethod__";
+
+ /** Search fall back routine name for "no such property" */
+- static final String NO_SUCH_PROPERTY_NAME = "__noSuchProperty__";
++ public static final String NO_SUCH_PROPERTY_NAME = "__noSuchProperty__";
+
+ /** Per ScriptObject flag - is this a scope object? */
+- public static final int IS_SCOPE = 0b0000_0001;
++ public static final int IS_SCOPE = 1 << 0;
+
+ /** Per ScriptObject flag - is this an array object? */
+- public static final int IS_ARRAY = 0b0000_0010;
++ public static final int IS_ARRAY = 1 << 1;
+
+ /** Per ScriptObject flag - is this an arguments object? */
+- public static final int IS_ARGUMENTS = 0b0000_0100;
++ public static final int IS_ARGUMENTS = 1 << 2;
+
+ /** Is length property not-writable? */
+- public static final int IS_LENGTH_NOT_WRITABLE = 0b0001_0000;
+-
+- /** Spill growth rate - by how many elements does {@link ScriptObject#spill} when full */
++ public static final int IS_LENGTH_NOT_WRITABLE = 1 << 3;
++
++ /** Is this a builtin object? */
++ public static final int IS_BUILTIN = 1 << 4;
++
++ /**
++ * Spill growth rate - by how many elements does {@link ScriptObject#primitiveSpill} and
++ * {@link ScriptObject#objectSpill} when full
++ */
+ public static final int SPILL_RATE = 8;
+
+ /** Map to property information and accessor functions. Ordered by insertion. */
+@@ -124,26 +140,42 @@
+ /** Object flags. */
+ private int flags;
+
+- /** Area for properties added to object after instantiation, see {@link AccessorProperty} */
+- public Object[] spill;
++ /** Area for primitive properties added to object after instantiation, see {@link AccessorProperty} */
++ protected long[] primitiveSpill;
++
++ /** Area for reference properties added to object after instantiation, see {@link AccessorProperty} */
++ protected Object[] objectSpill;
++
++ /**
++ * Number of elements in the spill. This may be less than the spill array lengths, if not all of
++ * the allocated memory is in use
++ */
++ private int spillLength;
+
+ /** Indexed array data. */
+ private ArrayData arrayData;
+
+- /** Method handle to retrive prototype of this object */
+- public static final MethodHandle GETPROTO = findOwnMH("getProto", ScriptObject.class);
+- static final MethodHandle MEGAMORPHIC_GET = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class);
+- static final MethodHandle GLOBALFILTER = findOwnMH("globalFilter", Object.class, Object.class);
+-
+- static final MethodHandle SETFIELD = findOwnMH("setField", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class);
+- static final MethodHandle SETSPILL = findOwnMH("setSpill", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
+- static final MethodHandle SETSPILLWITHNEW = findOwnMH("setSpillWithNew", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
+- static final MethodHandle SETSPILLWITHGROW = findOwnMH("setSpillWithGrow", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, int.class, Object.class, Object.class);
+-
+- private static final MethodHandle TRUNCATINGFILTER = findOwnMH("truncatingFilter", Object[].class, int.class, Object[].class);
+- private static final MethodHandle KNOWNFUNCPROPGUARD = findOwnMH("knownFunctionPropertyGuard", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, Object.class, ScriptFunction.class);
+-
+- private static final ArrayList<MethodHandle> protoFilters = new ArrayList<>();
++ /** Method handle to retrieve prototype of this object */
++ public static final MethodHandle GETPROTO = findOwnMH_V("getProto", ScriptObject.class);
++
++ static final MethodHandle MEGAMORPHIC_GET = findOwnMH_V("megamorphicGet", Object.class, String.class, boolean.class);
++ static final MethodHandle GLOBALFILTER = findOwnMH_S("globalFilter", Object.class, Object.class);
++ static final MethodHandle DECLARE_AND_SET = findOwnMH_V("declareAndSet", void.class, String.class, Object.class);
++
++ private static final MethodHandle TRUNCATINGFILTER = findOwnMH_S("truncatingFilter", Object[].class, int.class, Object[].class);
++ private static final MethodHandle KNOWNFUNCPROPGUARDSELF = findOwnMH_S("knownFunctionPropertyGuardSelf", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, ScriptFunction.class);
++ private static final MethodHandle KNOWNFUNCPROPGUARDPROTO = findOwnMH_S("knownFunctionPropertyGuardProto", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, int.class, ScriptFunction.class);
++
++ private static final ArrayList<MethodHandle> PROTO_FILTERS = new ArrayList<>();
++
++ /** Method handle for getting the array data */
++ public static final Call GET_ARRAY = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getArray", ArrayData.class);
++
++ /** Method handle for getting the property map - debugging purposes */
++ public static final Call GET_MAP = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getMap", PropertyMap.class);
++
++ /** Method handle for setting the array data */
++ public static final Call SET_ARRAY = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setArray", void.class, ArrayData.class);
+
+ /** Method handle for getting a function argument at a given index. Used from MapCreator */
+ public static final Call GET_ARGUMENT = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getArgument", Object.class, int.class);
+@@ -154,15 +186,33 @@
+ /** Method handle for getting the proto of a ScriptObject */
+ public static final Call GET_PROTO = virtualCallNoLookup(ScriptObject.class, "getProto", ScriptObject.class);
+
++ /** Method handle for getting the proto of a ScriptObject */
++ public static final Call GET_PROTO_DEPTH = virtualCallNoLookup(ScriptObject.class, "getProto", ScriptObject.class, int.class);
++
+ /** Method handle for setting the proto of a ScriptObject */
+- public static final Call SET_PROTO = virtualCallNoLookup(ScriptObject.class, "setInitialProto", void.class, ScriptObject.class);
++ public static final Call SET_GLOBAL_OBJECT_PROTO = staticCallNoLookup(ScriptObject.class, "setGlobalObjectProto", void.class, ScriptObject.class);
+
+ /** Method handle for setting the proto of a ScriptObject after checking argument */
+ public static final Call SET_PROTO_FROM_LITERAL = virtualCallNoLookup(ScriptObject.class, "setProtoFromLiteral", void.class, Object.class);
+
+ /** Method handle for setting the user accessors of a ScriptObject */
++ //TODO fastpath this
+ public static final Call SET_USER_ACCESSORS = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class);
+
++ static final MethodHandle[] SET_SLOW = new MethodHandle[] {
++ findOwnMH_V("set", void.class, Object.class, int.class, int.class),
++ findOwnMH_V("set", void.class, Object.class, long.class, int.class),
++ findOwnMH_V("set", void.class, Object.class, double.class, int.class),
++ findOwnMH_V("set", void.class, Object.class, Object.class, int.class)
++ };
++
++ /** Method handle to reset the map of this ScriptObject */
++ public static final Call SET_MAP = virtualCallNoLookup(ScriptObject.class, "setMap", void.class, PropertyMap.class);
++
++ static final MethodHandle CAS_MAP = findOwnMH_V("compareAndSetMap", boolean.class, PropertyMap.class, PropertyMap.class);
++ static final MethodHandle EXTENSION_CHECK = findOwnMH_V("extensionCheck", boolean.class, boolean.class, String.class);
++ static final MethodHandle ENSURE_SPILL_SIZE = findOwnMH_V("ensureSpillSize", Object.class, int.class);
++
+ /**
+ * Constructor
+ */
+@@ -179,7 +229,6 @@
+ if (Context.DEBUG) {
+ ScriptObject.count++;
+ }
+-
+ this.arrayData = ArrayData.EMPTY_ARRAY;
+ this.setMap(map == null ? PropertyMap.newMap() : map);
+ }
+@@ -194,16 +243,50 @@
+ * @param map intial {@link PropertyMap}
+ */
+ protected ScriptObject(final ScriptObject proto, final PropertyMap map) {
+- if (Context.DEBUG) {
+- ScriptObject.count++;
+- }
+-
+- this.arrayData = ArrayData.EMPTY_ARRAY;
+- this.setMap(map == null ? PropertyMap.newMap() : map);
++ this(map);
+ this.proto = proto;
+ }
+
+ /**
++ * Constructor used to instantiate spill properties directly. Used from
++ * SpillObjectCreator.
++ *
++ * @param map property maps
++ * @param primitiveSpill primitive spills
++ * @param objectSpill reference spills
++ */
++ public ScriptObject(final PropertyMap map, final long[] primitiveSpill, final Object[] objectSpill) {
++ this(map);
++ this.primitiveSpill = primitiveSpill;
++ this.objectSpill = objectSpill;
++ assert primitiveSpill.length == objectSpill.length : " primitive spill pool size is not the same length as object spill pool size";
++ this.spillLength = spillAllocationLength(primitiveSpill.length);
++ }
++
++ /**
++ * Check whether this is a global object
++ * @return true if global
++ */
++ protected boolean isGlobal() {
++ return false;
++ }
++
++ private static int alignUp(final int size, final int alignment) {
++ return size + alignment - 1 & ~(alignment - 1);
++ }
++
++ /**
++ * Given a number of properties, return the aligned to SPILL_RATE
++ * buffer size required for the smallest spill pool needed to
++ * house them
++ * @param nProperties number of properties
++ * @return property buffer length, a multiple of SPILL_RATE
++ */
++ public static int spillAllocationLength(final int nProperties) {
++ return alignUp(nProperties, SPILL_RATE);
++ }
++
++ /**
+ * Copy all properties from the source object with their receiver bound to the source.
+ * This function was known as mergeMap
+ *
+@@ -223,29 +306,44 @@
+ PropertyMap newMap = this.getMap();
+
+ for (final Property property : properties) {
+- final String key = property.getKey();
+- final Property oldProp = newMap.findProperty(key);
+- if (oldProp == null) {
+- if (property instanceof UserAccessorProperty) {
+- // Note: we copy accessor functions to this object which is semantically different from binding.
+- final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
+- newMap = newMap.addPropertyNoHistory(prop);
+- } else {
+- newMap = newMap.addPropertyBind((AccessorProperty)property, source);
+- }
++ newMap = addBoundProperty(newMap, source, property);
++ }
++
++ this.setMap(newMap);
++ }
++
++ /**
++ * Add a bound property from {@code source}, using the interim property map {@code propMap}, and return the
++ * new interim property map.
++ *
++ * @param propMap the property map
++ * @param source the source object
++ * @param property the property to be added
++ * @return the new property map
++ */
++ protected PropertyMap addBoundProperty(final PropertyMap propMap, final ScriptObject source, final Property property) {
++ PropertyMap newMap = propMap;
++ final String key = property.getKey();
++ final Property oldProp = newMap.findProperty(key);
++ if (oldProp == null) {
++ if (property instanceof UserAccessorProperty) {
++ // Note: we copy accessor functions to this object which is semantically different from binding.
++ final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
++ newMap = newMap.addPropertyNoHistory(prop);
+ } else {
+- // See ECMA section 10.5 Declaration Binding Instantiation
+- // step 5 processing each function declaration.
+- if (property.isFunctionDeclaration() && !oldProp.isConfigurable()) {
+- if (oldProp instanceof UserAccessorProperty ||
+- !(oldProp.isWritable() && oldProp.isEnumerable())) {
+- throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this));
+- }
++ newMap = newMap.addPropertyBind((AccessorProperty)property, source);
++ }
++ } else {
++ // See ECMA section 10.5 Declaration Binding Instantiation
++ // step 5 processing each function declaration.
++ if (property.isFunctionDeclaration() && !oldProp.isConfigurable()) {
++ if (oldProp instanceof UserAccessorProperty ||
++ !(oldProp.isWritable() && oldProp.isEnumerable())) {
++ throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this));
+ }
+ }
+ }
+-
+- this.setMap(newMap);
++ return newMap;
+ }
+
+ /**
+@@ -386,10 +484,10 @@
+
+ if (property instanceof UserAccessorProperty) {
+ return global.newAccessorDescriptor(
+- (get != null) ?
++ get != null ?
+ get :
+ UNDEFINED,
+- (set != null) ?
++ set != null ?
+ set :
+ UNDEFINED,
+ configurable,
+@@ -430,6 +528,17 @@
+ }
+
+ /**
++ * Invalidate any existing global constant method handles that may exist for {@code key}.
++ * @param key the property name
++ */
++ protected void invalidateGlobalConstant(final String key) {
++ final GlobalConstants globalConstants = getGlobalConstants();
++ if (globalConstants != null) {
++ globalConstants.delete(key);
++ }
++ }
++
++ /**
+ * ECMA 8.12.9 [[DefineOwnProperty]] (P, Desc, Throw)
+ *
+ * @param key the property key
+@@ -444,6 +553,8 @@
+ final Object current = getOwnPropertyDescriptor(key);
+ final String name = JSType.toString(key);
+
++ invalidateGlobalConstant(key);
++
+ if (current == UNDEFINED) {
+ if (isExtensible()) {
+ // add a new own property
+@@ -456,12 +567,12 @@
+ }
+ return false;
+ }
++
+ // modifying an existing property
+- final PropertyDescriptor currentDesc = (PropertyDescriptor) current;
++ final PropertyDescriptor currentDesc = (PropertyDescriptor)current;
+ final PropertyDescriptor newDesc = desc;
+
+- if (newDesc.type() == PropertyDescriptor.GENERIC &&
+- ! newDesc.has(CONFIGURABLE) && ! newDesc.has(ENUMERABLE)) {
++ if (newDesc.type() == PropertyDescriptor.GENERIC && !newDesc.has(CONFIGURABLE) && !newDesc.has(ENUMERABLE)) {
+ // every descriptor field is absent
+ return true;
+ }
+@@ -471,7 +582,7 @@
+ return true;
+ }
+
+- if (! currentDesc.isConfigurable()) {
++ if (!currentDesc.isConfigurable()) {
+ if (newDesc.has(CONFIGURABLE) && newDesc.isConfigurable()) {
+ // not configurable can not be made configurable
+ if (reject) {
+@@ -494,10 +605,11 @@
+ Property property = getMap().findProperty(key);
+
+ if (currentDesc.type() == PropertyDescriptor.DATA &&
+- (newDesc.type() == PropertyDescriptor.DATA || newDesc.type() == PropertyDescriptor.GENERIC)) {
+- if (! currentDesc.isConfigurable() && ! currentDesc.isWritable()) {
++ (newDesc.type() == PropertyDescriptor.DATA ||
++ newDesc.type() == PropertyDescriptor.GENERIC)) {
++ if (!currentDesc.isConfigurable() && !currentDesc.isWritable()) {
+ if (newDesc.has(WRITABLE) && newDesc.isWritable() ||
+- newDesc.has(VALUE) && ! ScriptRuntime.sameValue(currentDesc.getValue(), newDesc.getValue())) {
++ newDesc.has(VALUE) && !ScriptRuntime.sameValue(currentDesc.getValue(), newDesc.getValue())) {
+ if (reject) {
+ throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
+ }
+@@ -506,11 +618,20 @@
+ }
+
+ final boolean newValue = newDesc.has(VALUE);
+- final Object value = newValue? newDesc.getValue() : currentDesc.getValue();
++ final Object value = newValue ? newDesc.getValue() : currentDesc.getValue();
++
+ if (newValue && property != null) {
+ // Temporarily clear flags.
+ property = modifyOwnProperty(property, 0);
+- set(key, value, false);
++ set(key, value, 0);
++ //this might change the map if we change types of the property
++ //hence we need to read it again. note that we should probably
++ //have the setter return the new property throughout and in
++ //general respect Property return values from modify and add
++ //functions - which we don't seem to do at all here :-(
++ //There is already a bug filed to generify PropertyAccess so we
++ //can have the setter return e.g. a Property
++ property = getMap().findProperty(key);
+ }
+
+ if (property == null) {
+@@ -524,23 +645,22 @@
+ } else if (currentDesc.type() == PropertyDescriptor.ACCESSOR &&
+ (newDesc.type() == PropertyDescriptor.ACCESSOR ||
+ newDesc.type() == PropertyDescriptor.GENERIC)) {
+- if (! currentDesc.isConfigurable()) {
+- if (newDesc.has(PropertyDescriptor.GET) && ! ScriptRuntime.sameValue(currentDesc.getGetter(), newDesc.getGetter()) ||
+- newDesc.has(PropertyDescriptor.SET) && ! ScriptRuntime.sameValue(currentDesc.getSetter(), newDesc.getSetter())) {
++ if (!currentDesc.isConfigurable()) {
++ if (newDesc.has(PropertyDescriptor.GET) && !ScriptRuntime.sameValue(currentDesc.getGetter(), newDesc.getGetter()) ||
++ newDesc.has(PropertyDescriptor.SET) && !ScriptRuntime.sameValue(currentDesc.getSetter(), newDesc.getSetter())) {
+ if (reject) {
+ throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
+ }
+ return false;
+ }
+ }
+-
+ // New set the new features.
+ modifyOwnProperty(property, propFlags,
+ newDesc.has(GET) ? newDesc.getGetter() : currentDesc.getGetter(),
+ newDesc.has(SET) ? newDesc.getSetter() : currentDesc.getSetter());
+ } else {
+ // changing descriptor type
+- if (! currentDesc.isConfigurable()) {
++ if (!currentDesc.isConfigurable()) {
+ // not configurable can not be made configurable
+ if (reject) {
+ throw typeError(global, "cant.redefine.property", name, ScriptRuntime.safeToString(this));
+@@ -552,7 +672,7 @@
+
+ // Preserve only configurable and enumerable from current desc
+ // if those are not overridden in the new property descriptor.
+- boolean value = newDesc.has(CONFIGURABLE)? newDesc.isConfigurable() : currentDesc.isConfigurable();
++ boolean value = newDesc.has(CONFIGURABLE) ? newDesc.isConfigurable() : currentDesc.isConfigurable();
+ if (!value) {
+ propFlags |= Property.NOT_CONFIGURABLE;
+ }
+@@ -565,7 +685,7 @@
+ if (type == PropertyDescriptor.DATA) {
+ // get writable from the new descriptor
+ value = newDesc.has(WRITABLE) && newDesc.isWritable();
+- if (! value) {
++ if (!value) {
+ propFlags |= Property.NOT_WRITABLE;
+ }
+
+@@ -602,7 +722,8 @@
+ public void defineOwnProperty(final int index, final Object value) {
+ assert isValidArrayIndex(index) : "invalid array index";
+ final long longIndex = ArrayIndex.toLongIndex(index);
+- setValueAtArrayIndex(longIndex, index, value, false);
++ doesNotHaveEnsureDelete(longIndex, getArray().length(), false);
++ setArray(getArray().ensure(longIndex).set(index,value, false));
+ }
+
+ private void checkIntegerKey(final String key) {
+@@ -666,7 +787,7 @@
+ * @return FindPropertyData or null if not found.
+ */
+ public final FindProperty findProperty(final String key, final boolean deep) {
+- return findProperty(key, deep, false, this);
++ return findProperty(key, deep, this);
+ }
+
+ /**
+@@ -683,16 +804,11 @@
+ *
+ * @param key Property key.
+ * @param deep Whether the search should look up proto chain.
+- * @param stopOnNonScope should a deep search stop on the first non-scope object?
+ * @param start the object on which the lookup was originally initiated
+ *
+ * @return FindPropertyData or null if not found.
+ */
+- FindProperty findProperty(final String key, final boolean deep, final boolean stopOnNonScope, final ScriptObject start) {
+- // if doing deep search, stop search on the first non-scope object if asked to do so
+- if (stopOnNonScope && start != this && !isScope()) {
+- return null;
+- }
++ FindProperty findProperty(final String key, final boolean deep, final ScriptObject start) {
+
+ final PropertyMap selfMap = getMap();
+ final Property property = selfMap.findProperty(key);
+@@ -704,7 +820,7 @@
+ if (deep) {
+ final ScriptObject myProto = getProto();
+ if (myProto != null) {
+- return myProto.findProperty(key, deep, stopOnNonScope, start);
++ return myProto.findProperty(key, deep, start);
+ }
+ }
+
+@@ -733,6 +849,19 @@
+ return false;
+ }
+
++ private SwitchPoint findBuiltinSwitchPoint(final String key) {
++ for (ScriptObject myProto = getProto(); myProto != null; myProto = myProto.getProto()) {
++ final Property prop = myProto.getMap().findProperty(key);
++ if (prop != null) {
++ final SwitchPoint sp = prop.getBuiltinSwitchPoint();
++ if (sp != null && !sp.hasBeenInvalidated()) {
++ return sp;
++ }
++ }
++ }
++ return null;
++ }
++
+ /**
+ * Add a new property to the object.
+ * <p>
+@@ -761,9 +890,7 @@
+ * @return New property.
+ */
+ public final Property addOwnProperty(final String key, final int propertyFlags, final Object value) {
+- final Property property = addSpillProperty(key, propertyFlags);
+- property.setObjectValue(this, this, value, false);
+- return property;
++ return addSpillProperty(key, propertyFlags, value, true);
+ }
+
+ /**
+@@ -777,10 +904,8 @@
+ */
+ public final Property addOwnProperty(final Property newProperty) {
+ PropertyMap oldMap = getMap();
+-
+ while (true) {
+ final PropertyMap newMap = oldMap.addProperty(newProperty);
+-
+ if (!compareAndSetMap(oldMap, newMap)) {
+ oldMap = getMap();
+ final Property oldProperty = oldMap.findProperty(newProperty.getKey());
+@@ -798,7 +923,8 @@
+ // Erase the property field value with undefined. If the property is defined
+ // by user-defined accessors, we don't want to call the setter!!
+ if (!(property instanceof UserAccessorProperty)) {
+- property.setObjectValue(this, this, UNDEFINED, false);
++ assert property != null;
++ property.setValue(this, this, UNDEFINED, false);
+ }
+ }
+
+@@ -825,13 +951,37 @@
+ } else {
+ // delete getter and setter function references so that we don't leak
+ if (property instanceof UserAccessorProperty) {
+- final UserAccessorProperty uc = (UserAccessorProperty) property;
+- setSpill(uc.getGetterSlot(), null);
+- setSpill(uc.getSetterSlot(), null);
++ ((UserAccessorProperty)property).setAccessors(this, getMap(), null);
+ }
++
++ invalidateGlobalConstant(property.getKey());
+ return true;
+ }
+ }
++
++ }
++
++ /**
++ * Fast initialization functions for ScriptFunctions that are strict, to avoid
++ * creating setters that probably aren't used. Inject directly into the spill pool
++ * the defaults for "arguments" and "caller"
++ *
++ * @param key property key
++ * @param propertyFlags flags
++ * @param getter getter for {@link UserAccessorProperty}, null if not present or N/A
++ * @param setter setter for {@link UserAccessorProperty}, null if not present or N/A
++ */
++ protected final void initUserAccessors(final String key, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) {
++ final int slot = spillLength;
++ ensureSpillSize(spillLength); //arguments=slot0, caller=slot0
++ objectSpill[slot] = new UserAccessorProperty.Accessors(getter, setter);
++ final PropertyMap oldMap = getMap();
++ Property newProperty;
++ PropertyMap newMap;
++ do {
++ newProperty = new UserAccessorProperty(key, propertyFlags, slot);
++ newMap = oldMap.addProperty(newProperty);
++ } while (!compareAndSetMap(oldMap, newMap));
+ }
+
+ /**
+@@ -846,19 +996,27 @@
+ */
+ public final Property modifyOwnProperty(final Property oldProperty, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) {
+ Property newProperty;
++
+ if (oldProperty instanceof UserAccessorProperty) {
+- final UserAccessorProperty uc = (UserAccessorProperty) oldProperty;
+- final int getterSlot = uc.getGetterSlot();
+- final int setterSlot = uc.getSetterSlot();
+- setSpill(getterSlot, getter);
+- setSpill(setterSlot, setter);
+-
+- // if just flipping getter and setter with new functions, no need to change property or map
+- if (uc.flags == propertyFlags) {
+- return oldProperty;
++ final UserAccessorProperty uc = (UserAccessorProperty)oldProperty;
++ final int slot = uc.getSlot();
++
++ assert uc.getLocalType() == Object.class;
++ if (slot >= spillLength) {
++ uc.setAccessors(this, getMap(), new UserAccessorProperty.Accessors(getter, setter));
++ } else {
++ final UserAccessorProperty.Accessors gs = uc.getAccessors(this); //this crashes
++ if (gs == null) {
++ uc.setAccessors(this, getMap(), new UserAccessorProperty.Accessors(getter, setter));
++ } else {
++ //reuse existing getter setter for speed
++ gs.set(getter, setter);
++ if (uc.getFlags() == propertyFlags) {
++ return oldProperty;
++ }
++ }
+ }
+-
+- newProperty = new UserAccessorProperty(oldProperty.getKey(), propertyFlags, getterSlot, setterSlot);
++ newProperty = new UserAccessorProperty(uc.getKey(), propertyFlags, slot);
+ } else {
+ // erase old property value and create new user accessor property
+ erasePropertyValue(oldProperty);
+@@ -889,6 +1047,10 @@
+ * @return new property
+ */
+ private Property modifyOwnProperty(final Property oldProperty, final Property newProperty) {
++ if (oldProperty == newProperty) {
++ return newProperty; //nop
++ }
++
+ assert newProperty.getKey().equals(oldProperty.getKey()) : "replacing property with different key";
+
+ PropertyMap oldMap = getMap();
+@@ -925,8 +1087,8 @@
+ }
+ }
+
+- private static int getIntValue(final FindProperty find) {
+- final MethodHandle getter = find.getGetter(int.class);
++ private static int getIntValue(final FindProperty find, final int programPoint) {
++ final MethodHandle getter = find.getGetter(int.class, programPoint, null);
+ if (getter != null) {
+ try {
+ return (int)getter.invokeExact((Object)find.getGetterReceiver());
+@@ -937,11 +1099,11 @@
+ }
+ }
+
+- return ObjectClassGenerator.UNDEFINED_INT;
++ return UNDEFINED_INT;
+ }
+
+- private static long getLongValue(final FindProperty find) {
+- final MethodHandle getter = find.getGetter(long.class);
++ private static long getLongValue(final FindProperty find, final int programPoint) {
++ final MethodHandle getter = find.getGetter(long.class, programPoint, null);
+ if (getter != null) {
+ try {
+ return (long)getter.invokeExact((Object)find.getGetterReceiver());
+@@ -952,11 +1114,11 @@
+ }
+ }
+
+- return ObjectClassGenerator.UNDEFINED_LONG;
++ return UNDEFINED_LONG;
+ }
+
+- private static double getDoubleValue(final FindProperty find) {
+- final MethodHandle getter = find.getGetter(double.class);
++ private static double getDoubleValue(final FindProperty find, final int programPoint) {
++ final MethodHandle getter = find.getGetter(double.class, programPoint, null);
+ if (getter != null) {
+ try {
+ return (double)getter.invokeExact((Object)find.getGetterReceiver());
+@@ -967,7 +1129,7 @@
+ }
+ }
+
+- return ObjectClassGenerator.UNDEFINED_DOUBLE;
++ return UNDEFINED_DOUBLE;
+ }
+
+ /**
+@@ -1040,7 +1202,7 @@
+ * @param value the value to write at the given index
+ */
+ public void setArgument(final int key, final Object value) {
+- set(key, value, false);
++ set(key, value, 0);
+ }
+
+ /**
+@@ -1073,14 +1235,12 @@
+ * @param newMap Replacement map.
+ * @return true if the operation succeeded.
+ */
+- protected synchronized final boolean compareAndSetMap(final PropertyMap oldMap, final PropertyMap newMap) {
+- final boolean update = oldMap == this.map;
+-
+- if (update) {
++ protected final boolean compareAndSetMap(final PropertyMap oldMap, final PropertyMap newMap) {
++ if (oldMap == this.map) {
+ this.map = newMap;
++ return true;
+ }
+-
+- return update;
++ return false;
+ }
+
+ /**
+@@ -1092,10 +1252,24 @@
+ }
+
+ /**
++ * Get the proto of a specific depth
++ * @param n depth
++ * @return proto at given depth
++ */
++ public final ScriptObject getProto(final int n) {
++ assert n > 0;
++ ScriptObject p = getProto();
++ for (int i = n; i-- > 0;) {
++ p = p.getProto();
++ }
++ return p;
++ }
++
++ /**
+ * Set the __proto__ of an object.
+ * @param newProto new __proto__ to set.
+ */
+- public synchronized final void setProto(final ScriptObject newProto) {
++ public final void setProto(final ScriptObject newProto) {
+ final ScriptObject oldProto = proto;
+
+ if (oldProto != newProto) {
+@@ -1124,6 +1298,14 @@
+ }
+
+ /**
++ * Invoked from generated bytecode to initialize the prototype of object literals to the global Object prototype.
++ * @param obj the object literal that needs to have its prototype initialized to the global Object prototype.
++ */
++ public static void setGlobalObjectProto(final ScriptObject obj) {
++ obj.setInitialProto(Global.objectPrototype());
++ }
++
++ /**
+ * Set the __proto__ of an object with checks.
+ * This is the built-in operation [[SetPrototypeOf]]
+ * See ES6 draft spec: 9.1.2 [[SetPrototypeOf]] (V)
+@@ -1132,8 +1314,9 @@
+ */
+ public final void setPrototypeOf(final Object newProto) {
+ if (newProto == null || newProto instanceof ScriptObject) {
+- if (!isExtensible()) {
++ if (! isExtensible()) {
+ // okay to set same proto again - even if non-extensible
++
+ if (newProto == getProto()) {
+ return;
+ }
+@@ -1180,22 +1363,44 @@
+ * @param all True if to include non-enumerable keys.
+ * @return Array of keys.
+ */
+- public String[] getOwnKeys(final boolean all) {
++ public final String[] getOwnKeys(final boolean all) {
++ return getOwnKeys(all, null);
++ }
++
++ /**
++ * return an array of own property keys associated with the object.
++ *
++ * @param all True if to include non-enumerable keys.
++ * @param nonEnumerable set of non-enumerable properties seen already.Used
++ to filter out shadowed, but enumerable properties from proto children.
++ * @return Array of keys.
++ */
++ protected String[] getOwnKeys(final boolean all, final Set<String> nonEnumerable) {
+ final List<Object> keys = new ArrayList<>();
+ final PropertyMap selfMap = this.getMap();
+
+ final ArrayData array = getArray();
+- final long length = array.length();
+-
+- for (long i = 0; i < length; i = array.nextIndex(i)) {
+- if (array.has((int)i)) {
+- keys.add(JSType.toString(i));
+- }
++
++ for (final Iterator<Long> iter = array.indexIterator(); iter.hasNext(); ) {
++ keys.add(JSType.toString(iter.next().longValue()));
+ }
+
+ for (final Property property : selfMap.getProperties()) {
+- if (all || property.isEnumerable()) {
+- keys.add(property.getKey());
++ final boolean enumerable = property.isEnumerable();
++ final String key = property.getKey();
++ if (all) {
++ keys.add(key);
++ } else if (enumerable) {
++ // either we don't have non-enumerable filter set or filter set
++ // does not contain the current property.
++ if (nonEnumerable == null || !nonEnumerable.contains(key)) {
++ keys.add(key);
++ }
++ } else {
++ // store this non-enumerable property for later proto walk
++ if (nonEnumerable != null) {
++ nonEnumerable.add(key);
++ }
+ }
+ }
+
+@@ -1279,16 +1484,15 @@
+ */
+ public ScriptObject preventExtensions() {
+ PropertyMap oldMap = getMap();
+-
+- while (true) {
+- final PropertyMap newMap = getMap().preventExtensions();
+-
+- if (!compareAndSetMap(oldMap, newMap)) {
+- oldMap = getMap();
+- } else {
+- return this;
+- }
++ while (!compareAndSetMap(oldMap, getMap().preventExtensions())) {
++ oldMap = getMap();
+ }
++
++ //invalidate any fast array setters
++ final ArrayData array = getArray();
++ assert array != null;
++ setArray(ArrayData.preventExtension(array));
++ return this;
+ }
+
+ /**
+@@ -1299,7 +1503,7 @@
+ * @return true if array
+ */
+ public static boolean isArray(final Object obj) {
+- return (obj instanceof ScriptObject) && ((ScriptObject)obj).isArray();
++ return obj instanceof ScriptObject && ((ScriptObject)obj).isArray();
+ }
+
+ /**
+@@ -1337,18 +1541,35 @@
+ *
+ * @return {@code true} if 'length' property is non-writable
+ */
+- public final boolean isLengthNotWritable() {
++ public boolean isLengthNotWritable() {
+ return (flags & IS_LENGTH_NOT_WRITABLE) != 0;
+ }
+
+ /**
+- * Flag this object as having non-writable length property
++ * Flag this object as having non-writable length property.
+ */
+ public void setIsLengthNotWritable() {
+ flags |= IS_LENGTH_NOT_WRITABLE;
+ }
+
+ /**
++ * Get the {@link ArrayData}, for this ScriptObject, ensuring it is of a type
++ * that can handle elementType
++ * @param elementType elementType
++ * @return array data
++ */
++ public final ArrayData getArray(final Class<?> elementType) {
++ if (elementType == null) {
++ return arrayData;
++ }
++ final ArrayData newArrayData = arrayData.convert(elementType);
++ if (newArrayData != arrayData) {
++ arrayData = newArrayData;
++ }
++ return newArrayData;
++ }
++
++ /**
+ * Get the {@link ArrayData} for this ScriptObject if it is an array
+ * @return array data
+ */
+@@ -1446,6 +1667,21 @@
+ }
+
+ /**
++ * Tag this script object as built in
++ */
++ public final void setIsBuiltin() {
++ flags |= IS_BUILTIN;
++ }
++
++ /**
++ * Check if this script object is built in
++ * @return true if build in
++ */
++ public final boolean isBuiltin() {
++ return (flags & IS_BUILTIN) != 0;
++ }
++
++ /**
+ * Clears the properties from a ScriptObject
+ * (java.util.Map-like method to help ScriptObjectMirror implementation)
+ *
+@@ -1540,7 +1776,8 @@
+ */
+ public Object put(final Object key, final Object value, final boolean strict) {
+ final Object oldValue = get(key);
+- set(key, value, strict);
++ final int scriptObjectFlags = strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0;
++ set(key, value, scriptObjectFlags);
+ return oldValue;
+ }
+
+@@ -1553,8 +1790,9 @@
+ * @param strict strict mode or not
+ */
+ public void putAll(final Map<?, ?> otherMap, final boolean strict) {
++ final int scriptObjectFlags = strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0;
+ for (final Map.Entry<?, ?> entry : otherMap.entrySet()) {
+- set(entry.getKey(), entry.getValue(), strict);
++ set(entry.getKey(), entry.getValue(), scriptObjectFlags);
+ }
+ }
+
+@@ -1629,11 +1867,11 @@
+ return c > 2 ? findGetMethod(desc, request, operator) : findGetIndexMethod(desc, request);
+ case "setProp":
+ case "setElem":
+- return c > 2 ? findSetMethod(desc, request) : findSetIndexMethod(desc);
++ return c > 2 ? findSetMethod(desc, request) : findSetIndexMethod(desc, request);
+ case "call":
+ return findCallMethod(desc, request);
+ case "new":
+- return findNewMethod(desc);
++ return findNewMethod(desc, request);
+ case "callMethod":
+ return findCallMethodMethod(desc, request);
+ default:
+@@ -1645,10 +1883,11 @@
+ * Find the appropriate New method for an invoke dynamic call.
+ *
+ * @param desc The invoke dynamic call site descriptor.
++ * @param request The link request
+ *
+ * @return GuardedInvocation to be invoked at call site.
+ */
+- protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc) {
++ protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+ return notAFunction();
+ }
+
+@@ -1722,12 +1961,12 @@
+ return methodHandle;
+ }
+ final int listIndex = depth - 1; // We don't need 0-deep walker
+- MethodHandle filter = listIndex < protoFilters.size() ? protoFilters.get(listIndex) : null;
+-
+- if(filter == null) {
++ MethodHandle filter = listIndex < PROTO_FILTERS.size() ? PROTO_FILTERS.get(listIndex) : null;
++
++ if (filter == null) {
+ filter = addProtoFilter(GETPROTO, depth - 1);
+- protoFilters.add(null);
+- protoFilters.set(listIndex, filter);
++ PROTO_FILTERS.add(null);
++ PROTO_FILTERS.set(listIndex, filter);
+ }
+
+ return MH.filterArguments(methodHandle, 0, filter.asType(filter.type().changeReturnType(methodHandle.type().parameterType(0))));
+@@ -1743,66 +1982,110 @@
+ * @return GuardedInvocation to be invoked at call site.
+ */
+ protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
+- final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
++ final boolean explicitInstanceOfCheck = explicitInstanceOfCheck(desc, request);
++
++ String name;
++ name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
++ if (NashornCallSiteDescriptor.isApplyToCall(desc)) {
++ if (Global.isBuiltinFunctionPrototypeApply()) {
++ name = "call";
++ }
++ }
++
+ if (request.isCallSiteUnstable() || hasWithScope()) {
+ return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator));
+ }
+
+ final FindProperty find = findProperty(name, true);
+- MethodHandle methodHandle;
++ MethodHandle mh;
+
+ if (find == null) {
+- if ("getProp".equals(operator)) {
++ switch (operator) {
++ case "getElem": // getElem only gets here if element name is constant, so treat it like a property access
++ case "getProp":
+ return noSuchProperty(desc, request);
+- } else if ("getMethod".equals(operator)) {
++ case "getMethod":
+ return noSuchMethod(desc, request);
+- } else if ("getElem".equals(operator)) {
+- return createEmptyGetter(desc, name);
++ default:
++ throw new AssertionError(operator); // never invoked with any other operation
+ }
+- throw new AssertionError(); // never invoked with any other operation
+ }
+
++ final GlobalConstants globalConstants = getGlobalConstants();
++ if (globalConstants != null) {
++ final GuardedInvocation cinv = globalConstants.findGetMethod(find, this, desc);
++ if (cinv != null) {
++ return cinv;
++ }
++ }
++
+ final Class<?> returnType = desc.getMethodType().returnType();
+- final Property property = find.getProperty();
+- methodHandle = find.getGetter(returnType);
+-
++ final Property property = find.getProperty();
++
++ final int programPoint = NashornCallSiteDescriptor.isOptimistic(desc) ?
++ NashornCallSiteDescriptor.getProgramPoint(desc) :
++ UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
++
++ mh = find.getGetter(returnType, programPoint, request);
+ // Get the appropriate guard for this callsite and property.
+- final MethodHandle guard = NashornGuards.getGuard(this, property, desc);
++ final MethodHandle guard = NashornGuards.getGuard(this, property, desc, explicitInstanceOfCheck);
+ final ScriptObject owner = find.getOwner();
+-
+- if (methodHandle != null) {
+- assert methodHandle.type().returnType().equals(returnType);
+- if (find.isSelf()) {
+- return new GuardedInvocation(methodHandle, guard);
++ final Class<ClassCastException> exception = explicitInstanceOfCheck ? null : ClassCastException.class;
++
++ final SwitchPoint protoSwitchPoint;
++
++ if (mh == null) {
++ mh = Lookup.emptyGetter(returnType);
++ protoSwitchPoint = getProtoSwitchPoint(name, owner);
++ } else if (!find.isSelf()) {
++ assert mh.type().returnType().equals(returnType) :
++ "return type mismatch for getter " + mh.type().returnType() + " != " + returnType;
++ if (!(property instanceof UserAccessorProperty)) {
++ // Add a filter that replaces the self object with the prototype owning the property.
++ mh = addProtoFilter(mh, find.getProtoChainLength());
+ }
+-
+- if (!property.hasGetterFunction(owner)) {
+- // Add a filter that replaces the self object with the prototype owning the property.
+- methodHandle = addProtoFilter(methodHandle, find.getProtoChainLength());
+- }
+- return new GuardedInvocation(methodHandle, guard == null ? null : getProtoSwitchPoint(name, owner), guard);
++ protoSwitchPoint = getProtoSwitchPoint(name, owner);
++ } else {
++ protoSwitchPoint = null;
+ }
+
+- assert !NashornCallSiteDescriptor.isFastScope(desc);
+- return new GuardedInvocation(Lookup.emptyGetter(returnType), getProtoSwitchPoint(name, owner), guard);
++ assert OBJECT_FIELDS_ONLY || guard != null : "we always need a map guard here";
++
++ final GuardedInvocation inv = new GuardedInvocation(mh, guard, protoSwitchPoint, exception);
++ return inv.addSwitchPoint(findBuiltinSwitchPoint(name));
+ }
+
+- private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name,
+- final boolean isMethod) {
++ private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod) {
++ Context.getContextTrusted().getLogger(ObjectClassGenerator.class).warning("Megamorphic getter: " + desc + " " + name + " " +isMethod);
+ final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod);
+- final MethodHandle guard = getScriptObjectGuard(desc.getMethodType());
++ final MethodHandle guard = getScriptObjectGuard(desc.getMethodType(), true);
+ return new GuardedInvocation(invoker, guard);
+ }
+
+ @SuppressWarnings("unused")
+ private Object megamorphicGet(final String key, final boolean isMethod) {
+ final FindProperty find = findProperty(key, true);
+-
+ if (find != null) {
+ return find.getObjectValue();
+ }
+
+- return isMethod ? getNoSuchMethod(key) : invokeNoSuchProperty(key);
++ return isMethod ? getNoSuchMethod(key, INVALID_PROGRAM_POINT) : invokeNoSuchProperty(key, INVALID_PROGRAM_POINT);
++ }
++
++ // Marks a property as declared and sets its value. Used as slow path for block-scoped LET and CONST
++ @SuppressWarnings("unused")
++ private void declareAndSet(final String key, final Object value) {
++ final PropertyMap oldMap = getMap();
++ final FindProperty find = findProperty(key, false);
++ assert find != null;
++
++ final Property property = find.getProperty();
++ assert property != null;
++ assert property.needsDeclaration();
++
++ final PropertyMap newMap = oldMap.replaceProperty(property, property.removeFlags(Property.NEEDS_DECLARATION));
++ setMap(newMap);
++ set(key, value, 0);
+ }
+
+ /**
+@@ -1814,31 +2097,48 @@
+ * @return GuardedInvocation to be invoked at call site.
+ */
+ protected GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+- return findGetIndexMethod(desc.getMethodType());
+- }
+-
+- /**
+- * Find the appropriate GETINDEX method for an invoke dynamic call.
+- *
+- * @param callType the call site method type
+- * @return GuardedInvocation to be invoked at call site.
+- */
+- private static GuardedInvocation findGetIndexMethod(final MethodType callType) {
+- final Class<?> returnClass = callType.returnType();
+- final Class<?> keyClass = callType.parameterType(1);
+-
+- String name = "get";
++ final MethodType callType = desc.getMethodType();
++ final Class<?> returnType = callType.returnType();
++ final Class<?> returnClass = returnType.isPrimitive() ? returnType : Object.class;
++ final Class<?> keyClass = callType.parameterType(1);
++ final boolean explicitInstanceOfCheck = explicitInstanceOfCheck(desc, request);
++
++ final String name;
+ if (returnClass.isPrimitive()) {
+ //turn e.g. get with a double into getDouble
+ final String returnTypeName = returnClass.getName();
+- name += Character.toUpperCase(returnTypeName.charAt(0)) + returnTypeName.substring(1, returnTypeName.length());
++ name = "get" + Character.toUpperCase(returnTypeName.charAt(0)) + returnTypeName.substring(1, returnTypeName.length());
++ } else {
++ name = "get";
+ }
+
+- return new GuardedInvocation(findOwnMH(name, returnClass, keyClass), getScriptObjectGuard(callType));
++ final MethodHandle mh = findGetIndexMethodHandle(returnClass, name, keyClass, desc);
++ return new GuardedInvocation(mh, getScriptObjectGuard(callType, explicitInstanceOfCheck), (SwitchPoint)null, explicitInstanceOfCheck ? null : ClassCastException.class);
+ }
+
+- private static MethodHandle getScriptObjectGuard(final MethodType type) {
+- return ScriptObject.class.isAssignableFrom(type.parameterType(0)) ? null : NashornGuards.getScriptObjectGuard();
++ private static MethodHandle getScriptObjectGuard(final MethodType type, final boolean explicitInstanceOfCheck) {
++ return ScriptObject.class.isAssignableFrom(type.parameterType(0)) ? null : NashornGuards.getScriptObjectGuard(explicitInstanceOfCheck);
++ }
++
++ /**
++ * Find a handle for a getIndex method
++ * @param returnType return type for getter
++ * @param name name
++ * @param elementType index type for getter
++ * @param desc call site descriptor
++ * @return method handle for getter
++ */
++ protected MethodHandle findGetIndexMethodHandle(final Class<?> returnType, final String name, final Class<?> elementType, final CallSiteDescriptor desc) {
++ if (!returnType.isPrimitive()) {
++ return findOwnMH_V(getClass(), name, returnType, elementType);
++ }
++
++ return MH.insertArguments(
++ findOwnMH_V(getClass(), name, returnType, elementType, int.class),
++ 2,
++ NashornCallSiteDescriptor.isOptimistic(desc) ?
++ NashornCallSiteDescriptor.getProgramPoint(desc) :
++ INVALID_PROGRAM_POINT);
+ }
+
+ /**
+@@ -1856,7 +2156,7 @@
+ }
+
+ for (ScriptObject obj = this; obj != owner && obj.getProto() != null; obj = obj.getProto()) {
+- ScriptObject parent = obj.getProto();
++ final ScriptObject parent = obj.getProto();
+ parent.getMap().addListener(name, obj.getMap());
+ }
+
+@@ -1873,11 +2173,13 @@
+ */
+ protected GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) {
+ final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
++
+ if (request.isCallSiteUnstable() || hasWithScope()) {
+ return findMegaMorphicSetMethod(desc, name);
+ }
+
+- final boolean scope = isScope();
++ final boolean explicitInstanceOfCheck = explicitInstanceOfCheck(desc, request);
++
+ /*
+ * If doing property set on a scope object, we should stop proto search on the first
+ * non-scope object. Without this, for example, when assigning "toString" on global scope,
+@@ -1885,111 +2187,83 @@
+ *
+ * toString = function() { print("global toString"); } // don't affect Object.prototype.toString
+ */
+- FindProperty find = findProperty(name, true, scope, this);
++ FindProperty find = findProperty(name, true, this);
+
+ // If it's not a scope search, then we don't want any inherited properties except those with user defined accessors.
+- if (!scope && find != null && find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) {
++ if (find != null && find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) {
+ // We should still check if inherited data property is not writable
+ if (isExtensible() && !find.getProperty().isWritable()) {
+- return createEmptySetMethod(desc, "property.not.writable", false);
++ return createEmptySetMethod(desc, explicitInstanceOfCheck, "property.not.writable", true);
+ }
+- // Otherwise, forget the found property
+- find = null;
++ // Otherwise, forget the found property unless this is a scope callsite and the owner is a scope object as well.
++ if (!NashornCallSiteDescriptor.isScope(desc) || !find.getOwner().isScope()) {
++ find = null;
++ }
+ }
+
+ if (find != null) {
+- if(!find.getProperty().isWritable()) {
++ if (!find.getProperty().isWritable() && !NashornCallSiteDescriptor.isDeclaration(desc)) {
++ if (NashornCallSiteDescriptor.isScope(desc) && find.getProperty().isLexicalBinding()) {
++ throw typeError("assign.constant", name); // Overwriting ES6 const should throw also in non-strict mode.
++ }
+ // Existing, non-writable property
+- return createEmptySetMethod(desc, "property.not.writable", true);
++ return createEmptySetMethod(desc, explicitInstanceOfCheck, "property.not.writable", true);
+ }
+ } else {
+- if (! isExtensible()) {
+- return createEmptySetMethod(desc, "object.non.extensible", false);
++ if (!isExtensible()) {
++ return createEmptySetMethod(desc, explicitInstanceOfCheck, "object.non.extensible", false);
+ }
+ }
+
+- return new SetMethodCreator(this, find, desc).createGuardedInvocation();
++ final GuardedInvocation inv = new SetMethodCreator(this, find, desc, request).createGuardedInvocation(findBuiltinSwitchPoint(name));
++
++ final GlobalConstants globalConstants = getGlobalConstants();
++ if (globalConstants != null) {
++ final GuardedInvocation cinv = globalConstants.findSetMethod(find, this, inv, desc, request);
++ if (cinv != null) {
++ return cinv;
++ }
++ }
++
++ return inv;
+ }
+
+- private GuardedInvocation createEmptySetMethod(final CallSiteDescriptor desc, String strictErrorMessage, boolean canBeFastScope) {
+- final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
++ private GlobalConstants getGlobalConstants() {
++ // Avoid hitting getContext() which might be costly for a non-Global unless needed.
++ return GlobalConstants.GLOBAL_ONLY && !isGlobal() ? null : getContext().getGlobalConstants();
++ }
++
++ private GuardedInvocation createEmptySetMethod(final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final String strictErrorMessage, final boolean canBeFastScope) {
++ final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
+ if (NashornCallSiteDescriptor.isStrict(desc)) {
+- throw typeError(strictErrorMessage, name, ScriptRuntime.safeToString((this)));
+- }
+- assert canBeFastScope || !NashornCallSiteDescriptor.isFastScope(desc);
+- return new GuardedInvocation(Lookup.EMPTY_SETTER, getProtoSwitchPoint(name, null), NashornGuards.getMapGuard(getMap()));
++ throw typeError(strictErrorMessage, name, ScriptRuntime.safeToString(this));
++ }
++ assert canBeFastScope || !NashornCallSiteDescriptor.isFastScope(desc);
++ return new GuardedInvocation(
++ Lookup.EMPTY_SETTER,
++ NashornGuards.getMapGuard(getMap(), explicitInstanceOfCheck),
++ getProtoSwitchPoint(name, null),
++ explicitInstanceOfCheck ? null : ClassCastException.class);
+ }
+
+ @SuppressWarnings("unused")
+- private static void setField(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final MethodHandle setter, final Object self, final Object value) throws Throwable {
+- final ScriptObject obj = (ScriptObject)self;
+- final boolean isStrict = NashornCallSiteDescriptor.isStrict(desc);
+- if (!obj.isExtensible()) {
+- if (isStrict) {
+- throw typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(obj));
+- }
+- } else if (obj.compareAndSetMap(oldMap, newMap)) {
+- setter.invokeExact(self, value);
++ private boolean extensionCheck(final boolean isStrict, final String name) {
++ if (isExtensible()) {
++ return true; //go on and do the set. this is our guard
++ } else if (isStrict) {
++ //throw an error for attempting to do the set in strict mode
++ throw typeError("object.non.extensible", name, ScriptRuntime.safeToString(this));
+ } else {
+- obj.set(desc.getNameToken(CallSiteDescriptor.NAME_OPERAND), value, isStrict);
+- }
+- }
+-
+- @SuppressWarnings("unused")
+- private static void setSpill(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final int index, final Object self, final Object value) {
+- final ScriptObject obj = (ScriptObject)self;
+- if (obj.trySetSpill(desc, oldMap, newMap, value)) {
+- obj.spill[index] = value;
+- }
+- }
+-
+- private boolean trySetSpill(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final Object value) {
+- final boolean isStrict = NashornCallSiteDescriptor.isStrict(desc);
+- if (!isExtensible() && isStrict) {
+- throw typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(this));
+- } else if (compareAndSetMap(oldMap, newMap)) {
+- return true;
+- } else {
+- set(desc.getNameToken(CallSiteDescriptor.NAME_OPERAND), value, isStrict);
++ //not extensible, non strict - this is a nop
+ return false;
+ }
+ }
+
+- @SuppressWarnings("unused")
+- private static void setSpillWithNew(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final int index, final Object self, final Object value) {
+- final ScriptObject obj = (ScriptObject)self;
+- final boolean isStrict = NashornCallSiteDescriptor.isStrict(desc);
+-
+- if (!obj.isExtensible()) {
+- if (isStrict) {
+- throw typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(obj));
+- }
+- } else if (obj.compareAndSetMap(oldMap, newMap)) {
+- obj.spill = new Object[SPILL_RATE];
+- obj.spill[index] = value;
+- } else {
+- obj.set(desc.getNameToken(2), value, isStrict);
+- }
+- }
+-
+- @SuppressWarnings("unused")
+- private static void setSpillWithGrow(final CallSiteDescriptor desc, final PropertyMap oldMap, final PropertyMap newMap, final int index, final int newLength, final Object self, final Object value) {
+- final ScriptObject obj = (ScriptObject)self;
+- final boolean isStrict = NashornCallSiteDescriptor.isStrict(desc);
+-
+- if (!obj.isExtensible()) {
+- if (isStrict) {
+- throw typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(obj));
+- }
+- } else if (obj.compareAndSetMap(oldMap, newMap)) {
+- final int oldLength = obj.spill.length;
+- final Object[] newSpill = new Object[newLength];
+- System.arraycopy(obj.spill, 0, newSpill, 0, oldLength);
+- obj.spill = newSpill;
+- obj.spill[index] = value;
+- } else {
+- obj.set(desc.getNameToken(2), value, isStrict);
+- }
++ private GuardedInvocation findMegaMorphicSetMethod(final CallSiteDescriptor desc, final String name) {
++ final MethodType type = desc.getMethodType().insertParameterTypes(1, Object.class);
++ //never bother with ClassCastExceptionGuard for megamorphic callsites
++ final GuardedInvocation inv = findSetIndexMethod(getClass(), desc, false, type);
++ return inv.replaceMethods(MH.insertArguments(inv.getInvocation(), 1, name), inv.getGuard());
+ }
+
+ @SuppressWarnings("unused")
+@@ -2001,34 +2275,38 @@
+ return sobj;
+ }
+
+- private static GuardedInvocation findMegaMorphicSetMethod(final CallSiteDescriptor desc, final String name) {
+- final MethodType type = desc.getMethodType().insertParameterTypes(1, Object.class);
+- final GuardedInvocation inv = findSetIndexMethod(type, NashornCallSiteDescriptor.isStrict(desc));
+- return inv.replaceMethods(MH.insertArguments(inv.getInvocation(), 1, name), inv.getGuard());
+- }
+-
+- private static GuardedInvocation findSetIndexMethod(final CallSiteDescriptor desc) { // array, index, value
+- return findSetIndexMethod(desc.getMethodType(), NashornCallSiteDescriptor.isStrict(desc));
++ /**
++ * Lookup function for the set index method, available for subclasses as well, e.g. {@link NativeArray}
++ * provides special quick accessor linkage for continuous arrays that are represented as Java arrays
++ *
++ * @param desc call site descriptor
++ * @param request link request
++ *
++ * @return GuardedInvocation to be invoked at call site.
++ */
++ protected GuardedInvocation findSetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) { // array, index, value
++ return findSetIndexMethod(getClass(), desc, explicitInstanceOfCheck(desc, request), desc.getMethodType());
+ }
+
+ /**
+ * Find the appropriate SETINDEX method for an invoke dynamic call.
+ *
++ * @param clazz the receiver class
++ * @param desc the call site descriptor
++ * @param explicitInstanceOfCheck add an explicit instanceof check?
+ * @param callType the method type at the call site
+- * @param isStrict are we in strict mode?
+ *
+ * @return GuardedInvocation to be invoked at call site.
+ */
+- private static GuardedInvocation findSetIndexMethod(final MethodType callType, final boolean isStrict) {
++ private static GuardedInvocation findSetIndexMethod(final Class<? extends ScriptObject> clazz, final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final MethodType callType) {
+ assert callType.parameterCount() == 3;
+-
+- final Class<?> keyClass = callType.parameterType(1);
+- final Class<?> valueClass = callType.parameterType(2);
+-
+- MethodHandle methodHandle = findOwnMH("set", void.class, keyClass, valueClass, boolean.class);
+- methodHandle = MH.insertArguments(methodHandle, 3, isStrict);
+-
+- return new GuardedInvocation(methodHandle, getScriptObjectGuard(callType));
++ final Class<?> keyClass = callType.parameterType(1);
++ final Class<?> valueClass = callType.parameterType(2);
++
++ MethodHandle methodHandle = findOwnMH_V(clazz, "set", void.class, keyClass, valueClass, int.class);
++ methodHandle = MH.insertArguments(methodHandle, 3, NashornCallSiteDescriptor.getFlags(desc));
++
++ return new GuardedInvocation(methodHandle, getScriptObjectGuard(callType, explicitInstanceOfCheck), (SwitchPoint)null, explicitInstanceOfCheck ? null : ClassCastException.class);
+ }
+
+ /**
+@@ -2046,17 +2324,27 @@
+ return noSuchProperty(desc, request);
+ }
+
++ final boolean explicitInstanceOfCheck = explicitInstanceOfCheck(desc, request);
++
+ final Object value = find.getObjectValue();
+- if (! (value instanceof ScriptFunction)) {
+- return createEmptyGetter(desc, name);
++ if (!(value instanceof ScriptFunction)) {
++ return createEmptyGetter(desc, explicitInstanceOfCheck, name);
+ }
+
+ final ScriptFunction func = (ScriptFunction)value;
+- final Object thiz = scopeCall && func.isStrict() ? ScriptRuntime.UNDEFINED : this;
++ final Object thiz = scopeCall && func.isStrict() ? UNDEFINED : this;
+ // TODO: It'd be awesome if we could bind "name" without binding "this".
+- return new GuardedInvocation(MH.dropArguments(MH.constant(ScriptFunction.class,
+- func.makeBoundFunction(thiz, new Object[] { name })), 0, Object.class),
+- null, NashornGuards.getMapGuard(getMap()));
++ // Since we're binding this we must use an identity guard here.
++ return new GuardedInvocation(
++ MH.dropArguments(
++ MH.constant(
++ ScriptFunction.class,
++ func.makeBoundFunction(thiz, new Object[] { name })),
++ 0,
++ Object.class),
++ NashornGuards.combineGuards(
++ NashornGuards.getIdentityGuard(this),
++ NashornGuards.getMapGuard(getMap(), true)));
+ }
+
+ /**
+@@ -2065,29 +2353,44 @@
+ * @param request the link request
+ * @return GuardedInvocation to be invoked at call site.
+ */
+- @SuppressWarnings("null")
+ public GuardedInvocation noSuchProperty(final CallSiteDescriptor desc, final LinkRequest request) {
+- final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
+- final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);
+- final boolean scopeAccess = isScope() && NashornCallSiteDescriptor.isScope(desc);
++ final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
++ final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);
++ final boolean scopeAccess = isScope() && NashornCallSiteDescriptor.isScope(desc);
+
+ if (find != null) {
+- final Object value = find.getObjectValue();
+- ScriptFunction func = null;
+- MethodHandle methodHandle = null;
++ final Object value = find.getObjectValue();
++ ScriptFunction func = null;
++ MethodHandle mh = null;
+
+ if (value instanceof ScriptFunction) {
+ func = (ScriptFunction)value;
+- methodHandle = getCallMethodHandle(func, desc.getMethodType(), name);
++ mh = getCallMethodHandle(func, desc.getMethodType(), name);
+ }
+
+- if (methodHandle != null) {
++ if (mh != null) {
++ assert func != null;
+ if (scopeAccess && func.isStrict()) {
+- methodHandle = bindTo(methodHandle, UNDEFINED);
++ mh = bindTo(mh, UNDEFINED);
+ }
+- return new GuardedInvocation(methodHandle,
++
++ return new GuardedInvocation(
++ mh,
++ find.isSelf()?
++ getKnownFunctionPropertyGuardSelf(
++ getMap(),
++ find.getGetter(Object.class, INVALID_PROGRAM_POINT, request),
++ func)
++ :
++ //TODO this always does a scriptobject check
++ getKnownFunctionPropertyGuardProto(
++ getMap(),
++ find.getGetter(Object.class, INVALID_PROGRAM_POINT, request),
++ find.getProtoChainLength(),
++ func),
+ getProtoSwitchPoint(NO_SUCH_PROPERTY_NAME, find.getOwner()),
+- getKnownFunctionPropertyGuard(getMap(), find.getGetter(Object.class), find.getOwner(), func));
++ //TODO this doesn't need a ClassCastException as guard always checks script object
++ null);
+ }
+ }
+
+@@ -2095,51 +2398,64 @@
+ throw referenceError("not.defined", name);
+ }
+
+- return createEmptyGetter(desc, name);
++ return createEmptyGetter(desc, explicitInstanceOfCheck(desc, request), name);
+ }
+
+ /**
+ * Invoke fall back if a property is not found.
+ * @param name Name of property.
++ * @param programPoint program point
+ * @return Result from call.
+ */
+- protected Object invokeNoSuchProperty(final String name) {
++ protected Object invokeNoSuchProperty(final String name, final int programPoint) {
+ final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);
+
++ Object ret = UNDEFINED;
++
+ if (find != null) {
+ final Object func = find.getObjectValue();
+
+ if (func instanceof ScriptFunction) {
+- return ScriptRuntime.apply((ScriptFunction)func, this, name);
++ ret = ScriptRuntime.apply((ScriptFunction)func, this, name);
+ }
+ }
+
+- return UNDEFINED;
++ if (isValid(programPoint)) {
++ throw new UnwarrantedOptimismException(ret, programPoint);
++ }
++
++ return ret;
+ }
+
++
+ /**
+ * Get __noSuchMethod__ as a function bound to this object and {@code name} if it is defined.
+ * @param name the method name
+ * @return the bound function, or undefined
+ */
+- private Object getNoSuchMethod(final String name) {
++ private Object getNoSuchMethod(final String name, final int programPoint) {
+ final FindProperty find = findProperty(NO_SUCH_METHOD_NAME, true);
+
+ if (find == null) {
+- return invokeNoSuchProperty(name);
++ return invokeNoSuchProperty(name, programPoint);
+ }
+
+ final Object value = find.getObjectValue();
+- if (! (value instanceof ScriptFunction)) {
++ if (!(value instanceof ScriptFunction)) {
+ return UNDEFINED;
+ }
+
+ return ((ScriptFunction)value).makeBoundFunction(this, new Object[] {name});
+ }
+
+- private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final String name) {
++ private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final String name) {
++ if (NashornCallSiteDescriptor.isOptimistic(desc)) {
++ throw new UnwarrantedOptimismException(UNDEFINED, NashornCallSiteDescriptor.getProgramPoint(desc), Type.OBJECT);
++ }
++
+ return new GuardedInvocation(Lookup.emptyGetter(desc.getMethodType().returnType()),
+- getProtoSwitchPoint(name, null), NashornGuards.getMapGuard(getMap()));
++ NashornGuards.getMapGuard(getMap(), explicitInstanceOfCheck), getProtoSwitchPoint(name, null),
++ explicitInstanceOfCheck ? null : ClassCastException.class);
+ }
+
+ private abstract static class ScriptObjectIterator <T extends Object> implements Iterator<T> {
+@@ -2171,7 +2487,7 @@
+
+ @Override
+ public void remove() {
+- throw new UnsupportedOperationException();
++ throw new UnsupportedOperationException("remove");
+ }
+ }
+
+@@ -2183,8 +2499,9 @@
+ @Override
+ protected void init() {
+ final Set<String> keys = new LinkedHashSet<>();
++ final Set<String> nonEnumerable = new HashSet<>();
+ for (ScriptObject self = object; self != null; self = self.getProto()) {
+- keys.addAll(Arrays.asList(self.getOwnKeys(false)));
++ keys.addAll(Arrays.asList(self.getOwnKeys(false, nonEnumerable)));
+ }
+ this.values = keys.toArray(new String[keys.size()]);
+ }
+@@ -2198,8 +2515,9 @@
+ @Override
+ protected void init() {
+ final ArrayList<Object> valueList = new ArrayList<>();
++ final Set<String> nonEnumerable = new HashSet<>();
+ for (ScriptObject self = object; self != null; self = self.getProto()) {
+- for (final String key : self.getOwnKeys(false)) {
++ for (final String key : self.getOwnKeys(false, nonEnumerable)) {
+ valueList.add(self.get(key));
+ }
+ }
+@@ -2213,46 +2531,34 @@
+ * @param propertyFlags Property flags.
+ * @return Added property.
+ */
+- private Property addSpillProperty(final String key, final int propertyFlags) {
+- int fieldCount = getMap().getFieldCount();
+- int fieldMaximum = getMap().getFieldMaximum();
++ private Property addSpillProperty(final String key, final int propertyFlags, final Object value, final boolean hasInitialValue) {
++ final PropertyMap propertyMap = getMap();
++ final int fieldSlot = propertyMap.getFreeFieldSlot();
++
+ Property property;
+-
+- if (fieldCount < fieldMaximum) {
+- property = new AccessorProperty(key, propertyFlags & ~Property.IS_SPILL, getClass(), fieldCount);
++ if (fieldSlot > -1) {
++ property = hasInitialValue ?
++ new AccessorProperty(key, propertyFlags, fieldSlot, this, value) :
++ new AccessorProperty(key, propertyFlags, getClass(), fieldSlot);
+ property = addOwnProperty(property);
+ } else {
+- int i = getMap().getSpillLength();
+- property = new AccessorProperty(key, propertyFlags | Property.IS_SPILL, i);
++ final int spillSlot = propertyMap.getFreeSpillSlot();
++ property = hasInitialValue ?
++ new SpillProperty(key, propertyFlags, spillSlot, this, value) :
++ new SpillProperty(key, propertyFlags, spillSlot);
+ property = addOwnProperty(property);
+- i = property.getSlot();
+-
+- final int newLength = (i + SPILL_RATE) / SPILL_RATE * SPILL_RATE;
+-
+- if (spill == null || newLength > spill.length) {
+- final Object[] newSpill = new Object[newLength];
+-
+- if (spill != null) {
+- System.arraycopy(spill, 0, newSpill, 0, spill.length);
+- }
+-
+- spill = newSpill;
+- }
++ ensureSpillSize(property.getSlot());
+ }
+-
+ return property;
+ }
+
+-
+ /**
+ * Add a spill entry for the given key.
+ * @param key Property key.
+ * @return Setter method handle.
+ */
+- MethodHandle addSpill(final String key) {
+- final Property spillProperty = addSpillProperty(key, 0);
+- final Class<?> type = Object.class;
+- return spillProperty.getSetter(type, getMap()); //TODO specfields
++ MethodHandle addSpill(final Class<?> type, final String key) {
++ return addSpillProperty(key, 0, null, false).getSetter(OBJECT_FIELDS_ONLY ? Object.class : type, getMap());
+ }
+
+ /**
+@@ -2285,9 +2591,8 @@
+ * @return method handle with adjusted arguments
+ */
+ public static MethodHandle pairArguments(final MethodHandle methodHandle, final MethodType callType, final Boolean callerVarArg) {
+-
+ final MethodType methodType = methodHandle.type();
+- if (methodType.equals(callType)) {
++ if (methodType.equals(callType.changeReturnType(methodType.returnType()))) {
+ return methodHandle;
+ }
+
+@@ -2295,8 +2600,18 @@
+ final int callCount = callType.parameterCount();
+
+ final boolean isCalleeVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray();
+- final boolean isCallerVarArg = callerVarArg != null ? callerVarArg.booleanValue() : (callCount > 0 &&
+- callType.parameterType(callCount - 1).isArray());
++ final boolean isCallerVarArg = callerVarArg != null ? callerVarArg.booleanValue() : callCount > 0 &&
++ callType.parameterType(callCount - 1).isArray();
++
++ if (isCalleeVarArg) {
++ return isCallerVarArg ?
++ methodHandle :
++ MH.asCollector(methodHandle, Object[].class, callCount - parameterCount + 1);
++ }
++
++ if (isCallerVarArg) {
++ return adaptHandleToVarArgCallSite(methodHandle, callCount);
++ }
+
+ if (callCount < parameterCount) {
+ final int missingArgs = parameterCount - callCount;
+@@ -2305,7 +2620,7 @@
+ Arrays.fill(fillers, UNDEFINED);
+
+ if (isCalleeVarArg) {
+- fillers[missingArgs - 1] = new Object[0];
++ fillers[missingArgs - 1] = ScriptRuntime.EMPTY_ARRAY;
+ }
+
+ return MH.insertArguments(
+@@ -2314,27 +2629,6 @@
+ fillers);
+ }
+
+- if (isCalleeVarArg) {
+- return isCallerVarArg ?
+- methodHandle :
+- MH.asCollector(methodHandle, Object[].class, callCount - parameterCount + 1);
+- }
+-
+- if (isCallerVarArg) {
+- final int spreadArgs = parameterCount - callCount + 1;
+- return MH.filterArguments(
+- MH.asSpreader(
+- methodHandle,
+- Object[].class,
+- spreadArgs),
+- callCount - 1,
+- MH.insertArguments(
+- TRUNCATINGFILTER,
+- 0,
+- spreadArgs)
+- );
+- }
+-
+ if (callCount > parameterCount) {
+ final int discardedArgs = callCount - parameterCount;
+
+@@ -2347,19 +2641,32 @@
+ return methodHandle;
+ }
+
++ static MethodHandle adaptHandleToVarArgCallSite(final MethodHandle mh, final int callSiteParamCount) {
++ final int spreadArgs = mh.type().parameterCount() - callSiteParamCount + 1;
++ return MH.filterArguments(
++ MH.asSpreader(
++ mh,
++ Object[].class,
++ spreadArgs),
++ callSiteParamCount - 1,
++ MH.insertArguments(
++ TRUNCATINGFILTER,
++ 0,
++ spreadArgs)
++ );
++ }
++
+ @SuppressWarnings("unused")
+ private static Object[] truncatingFilter(final int n, final Object[] array) {
+ final int length = array == null ? 0 : array.length;
+ if (n == length) {
+- return array == null ? new Object[0] : array;
++ return array == null ? ScriptRuntime.EMPTY_ARRAY : array;
+ }
+
+ final Object[] newArray = new Object[n];
+
+ if (array != null) {
+- for (int i = 0; i < n && i < length; i++) {
+- newArray[i] = array[i];
+- }
++ System.arraycopy(array, 0, newArray, 0, Math.min(n, length));
+ }
+
+ if (length < n) {
+@@ -2379,20 +2686,22 @@
+ * @param newLength new length to set
+ */
+ public final void setLength(final long newLength) {
+- final long arrayLength = getArray().length();
+- if (newLength == arrayLength) {
+- return;
+- }
+-
+- if (newLength > arrayLength) {
+- setArray(getArray().ensure(newLength - 1));
+- if (getArray().canDelete(arrayLength, (newLength - 1), false)) {
+- setArray(getArray().delete(arrayLength, (newLength - 1)));
+- }
+- return;
+- }
+-
+- if (newLength < arrayLength) {
++ ArrayData data = getArray();
++ final long arrayLength = data.length();
++ if (newLength == arrayLength) {
++ return;
++ }
++
++ if (newLength > arrayLength) {
++ data = data.ensure(newLength - 1);
++ if (data.canDelete(arrayLength, newLength - 1, false)) {
++ data = data.delete(arrayLength, newLength - 1);
++ }
++ setArray(data);
++ return;
++ }
++
++ if (newLength < arrayLength) {
+ long actualLength = newLength;
+
+ // Check for numeric keys in property map and delete them or adjust length, depending on whether
+@@ -2414,19 +2723,19 @@
+ }
+ }
+
+- setArray(getArray().shrink(actualLength));
+- getArray().setLength(actualLength);
++ setArray(data.shrink(actualLength));
++ data.setLength(actualLength);
+ }
+ }
+
+- private int getInt(final int index, final String key) {
++ private int getInt(final int index, final String key, final int programPoint) {
+ if (isValidArrayIndex(index)) {
+ for (ScriptObject object = this; ; ) {
+ if (object.getMap().containsArrayKeys()) {
+- final FindProperty find = object.findProperty(key, false, false, this);
++ final FindProperty find = object.findProperty(key, false, this);
+
+ if (find != null) {
+- return getIntValue(find);
++ return getIntValue(find, programPoint);
+ }
+ }
+
+@@ -2437,77 +2746,78 @@
+ final ArrayData array = object.getArray();
+
+ if (array.has(index)) {
+- return array.getInt(index);
++ return isValid(programPoint) ?
++ array.getIntOptimistic(index, programPoint) :
++ array.getInt(index);
+ }
+ }
+ } else {
+ final FindProperty find = findProperty(key, true);
+
+ if (find != null) {
+- return getIntValue(find);
++ return getIntValue(find, programPoint);
+ }
+ }
+
+- return JSType.toInt32(invokeNoSuchProperty(key));
++ return JSType.toInt32(invokeNoSuchProperty(key, programPoint));
+ }
+
+ @Override
+- public int getInt(final Object key) {
+- final Object primitiveKey = JSType.toPrimitive(key, String.class);
+- final int index = getArrayIndex(primitiveKey);
++ public int getInt(final Object key, final int programPoint) {
++ final Object primitiveKey = JSType.toPrimitive(key, String.class);
++ final int index = getArrayIndex(primitiveKey);
++ final ArrayData array = getArray();
++
++ if (array.has(index)) {
++ return isValid(programPoint) ? array.getIntOptimistic(index, programPoint) : array.getInt(index);
++ }
++
++ return getInt(index, JSType.toString(primitiveKey), programPoint);
++ }
++
++ @Override
++ public int getInt(final double key, final int programPoint) {
++ final int index = getArrayIndex(key);
+ final ArrayData array = getArray();
+
+ if (array.has(index)) {
+- return array.getInt(index);
++ return isValid(programPoint) ? array.getIntOptimistic(index, programPoint) : array.getInt(index);
+ }
+
+- return getInt(index, JSType.toString(primitiveKey));
++ return getInt(index, JSType.toString(key), programPoint);
+ }
+
+ @Override
+- public int getInt(final double key) {
+- final int index = getArrayIndex(key);
++ public int getInt(final long key, final int programPoint) {
++ final int index = getArrayIndex(key);
+ final ArrayData array = getArray();
+
+ if (array.has(index)) {
+- return array.getInt(index);
++ return isValid(programPoint) ? array.getIntOptimistic(index, programPoint) : array.getInt(index);
+ }
+
+- return getInt(index, JSType.toString(key));
++ return getInt(index, JSType.toString(key), programPoint);
+ }
+
+ @Override
+- public int getInt(final long key) {
+- final int index = getArrayIndex(key);
++ public int getInt(final int key, final int programPoint) {
++ final int index = getArrayIndex(key);
+ final ArrayData array = getArray();
+
+ if (array.has(index)) {
+- return array.getInt(index);
++ return isValid(programPoint) ? array.getIntOptimistic(key, programPoint) : array.getInt(key);
+ }
+
+- return getInt(index, JSType.toString(key));
++ return getInt(index, JSType.toString(key), programPoint);
+ }
+
+- @Override
+- public int getInt(final int key) {
+- final int index = getArrayIndex(key);
+- final ArrayData array = getArray();
+-
+- if (array.has(index)) {
+- return array.getInt(index);
+- }
+-
+- return getInt(index, JSType.toString(key));
+- }
+-
+- private long getLong(final int index, final String key) {
++ private long getLong(final int index, final String key, final int programPoint) {
+ if (isValidArrayIndex(index)) {
+ for (ScriptObject object = this; ; ) {
+ if (object.getMap().containsArrayKeys()) {
+- final FindProperty find = object.findProperty(key, false, false, this);
+-
++ final FindProperty find = object.findProperty(key, false, this);
+ if (find != null) {
+- return getLongValue(find);
++ return getLongValue(find, programPoint);
+ }
+ }
+
+@@ -2518,77 +2828,78 @@
+ final ArrayData array = object.getArray();
+
+ if (array.has(index)) {
+- return array.getLong(index);
++ return isValid(programPoint) ?
++ array.getLongOptimistic(index, programPoint) :
++ array.getLong(index);
+ }
+ }
+ } else {
+ final FindProperty find = findProperty(key, true);
+
+ if (find != null) {
+- return getLongValue(find);
++ return getLongValue(find, programPoint);
+ }
+ }
+
+- return JSType.toLong(invokeNoSuchProperty(key));
++ return JSType.toLong(invokeNoSuchProperty(key, programPoint));
+ }
+
+ @Override
+- public long getLong(final Object key) {
+- final Object primitiveKey = JSType.toPrimitive(key, String.class);
+- final int index = getArrayIndex(primitiveKey);
++ public long getLong(final Object key, final int programPoint) {
++ final Object primitiveKey = JSType.toPrimitive(key, String.class);
++ final int index = getArrayIndex(primitiveKey);
++ final ArrayData array = getArray();
++
++ if (array.has(index)) {
++ return isValid(programPoint) ? array.getLongOptimistic(index, programPoint) : array.getLong(index);
++ }
++
++ return getLong(index, JSType.toString(primitiveKey), programPoint);
++ }
++
++ @Override
++ public long getLong(final double key, final int programPoint) {
++ final int index = getArrayIndex(key);
+ final ArrayData array = getArray();
+
+ if (array.has(index)) {
+- return array.getLong(index);
++ return isValid(programPoint) ? array.getLongOptimistic(index, programPoint) : array.getLong(index);
+ }
+
+- return getLong(index, JSType.toString(primitiveKey));
++ return getLong(index, JSType.toString(key), programPoint);
+ }
+
+ @Override
+- public long getLong(final double key) {
+- final int index = getArrayIndex(key);
++ public long getLong(final long key, final int programPoint) {
++ final int index = getArrayIndex(key);
+ final ArrayData array = getArray();
+
+ if (array.has(index)) {
+- return array.getLong(index);
++ return isValid(programPoint) ? array.getLongOptimistic(index, programPoint) : array.getLong(index);
+ }
+
+- return getLong(index, JSType.toString(key));
++ return getLong(index, JSType.toString(key), programPoint);
+ }
+
+ @Override
+- public long getLong(final long key) {
+- final int index = getArrayIndex(key);
++ public long getLong(final int key, final int programPoint) {
++ final int index = getArrayIndex(key);
+ final ArrayData array = getArray();
+
+ if (array.has(index)) {
+- return array.getLong(index);
++ return isValid(programPoint) ? array.getLongOptimistic(key, programPoint) : array.getLong(key);
+ }
+
+- return getLong(index, JSType.toString(key));
++ return getLong(index, JSType.toString(key), programPoint);
+ }
+
+- @Override
+- public long getLong(final int key) {
+- final int index = getArrayIndex(key);
+- final ArrayData array = getArray();
+-
+- if (array.has(index)) {
+- return array.getLong(index);
+- }
+-
+- return getLong(index, JSType.toString(key));
+- }
+-
+- private double getDouble(final int index, final String key) {
++ private double getDouble(final int index, final String key, final int programPoint) {
+ if (isValidArrayIndex(index)) {
+ for (ScriptObject object = this; ; ) {
+ if (object.getMap().containsArrayKeys()) {
+- final FindProperty find = object.findProperty(key, false, false, this);
+-
++ final FindProperty find = object.findProperty(key, false, this);
+ if (find != null) {
+- return getDoubleValue(find);
++ return getDoubleValue(find, programPoint);
+ }
+ }
+
+@@ -2599,74 +2910,76 @@
+ final ArrayData array = object.getArray();
+
+ if (array.has(index)) {
+- return array.getDouble(index);
++ return isValid(programPoint) ?
++ array.getDoubleOptimistic(index, programPoint) :
++ array.getDouble(index);
+ }
+ }
+ } else {
+ final FindProperty find = findProperty(key, true);
+
+ if (find != null) {
+- return getDoubleValue(find);
++ return getDoubleValue(find, programPoint);
+ }
+ }
+
+- return JSType.toNumber(invokeNoSuchProperty(key));
++ return JSType.toNumber(invokeNoSuchProperty(key, INVALID_PROGRAM_POINT));
+ }
+
+ @Override
+- public double getDouble(final Object key) {
+- final Object primitiveKey = JSType.toPrimitive(key, String.class);
+- final int index = getArrayIndex(primitiveKey);
++ public double getDouble(final Object key, final int programPoint) {
++ final Object primitiveKey = JSType.toPrimitive(key, String.class);
++ final int index = getArrayIndex(primitiveKey);
++ final ArrayData array = getArray();
++
++ if (array.has(index)) {
++ return isValid(programPoint) ? array.getDoubleOptimistic(index, programPoint) : array.getDouble(index);
++ }
++
++ return getDouble(index, JSType.toString(primitiveKey), programPoint);
++ }
++
++ @Override
++ public double getDouble(final double key, final int programPoint) {
++ final int index = getArrayIndex(key);
+ final ArrayData array = getArray();
+
+ if (array.has(index)) {
+- return array.getDouble(index);
++ return isValid(programPoint) ? array.getDoubleOptimistic(index, programPoint) : array.getDouble(index);
+ }
+
+- return getDouble(index, JSType.toString(primitiveKey));
++ return getDouble(index, JSType.toString(key), programPoint);
+ }
+
+ @Override
+- public double getDouble(final double key) {
+- final int index = getArrayIndex(key);
++ public double getDouble(final long key, final int programPoint) {
++ final int index = getArrayIndex(key);
+ final ArrayData array = getArray();
+
+ if (array.has(index)) {
+- return array.getDouble(index);
++ return isValid(programPoint) ? array.getDoubleOptimistic(index, programPoint) : array.getDouble(index);
+ }
+
+- return getDouble(index, JSType.toString(key));
++ return getDouble(index, JSType.toString(key), programPoint);
+ }
+
+ @Override
+- public double getDouble(final long key) {
+- final int index = getArrayIndex(key);
++ public double getDouble(final int key, final int programPoint) {
++ final int index = getArrayIndex(key);
+ final ArrayData array = getArray();
+
+ if (array.has(index)) {
+- return array.getDouble(index);
++ return isValid(programPoint) ? array.getDoubleOptimistic(key, programPoint) : array.getDouble(key);
+ }
+
+- return getDouble(index, JSType.toString(key));
+- }
+-
+- @Override
+- public double getDouble(final int key) {
+- final int index = getArrayIndex(key);
+- final ArrayData array = getArray();
+-
+- if (array.has(index)) {
+- return array.getDouble(index);
+- }
+-
+- return getDouble(index, JSType.toString(key));
++ return getDouble(index, JSType.toString(key), programPoint);
+ }
+
+ private Object get(final int index, final String key) {
+ if (isValidArrayIndex(index)) {
+ for (ScriptObject object = this; ; ) {
+ if (object.getMap().containsArrayKeys()) {
+- final FindProperty find = object.findProperty(key, false, false, this);
++ final FindProperty find = object.findProperty(key, false, this);
+
+ if (find != null) {
+ return find.getObjectValue();
+@@ -2691,14 +3004,14 @@
+ }
+ }
+
+- return invokeNoSuchProperty(key);
++ return invokeNoSuchProperty(key, INVALID_PROGRAM_POINT);
+ }
+
+ @Override
+ public Object get(final Object key) {
+- final Object primitiveKey = JSType.toPrimitive(key, String.class);
+- final int index = getArrayIndex(primitiveKey);
+- final ArrayData array = getArray();
++ final Object primitiveKey = JSType.toPrimitive(key, String.class);
++ final int index = getArrayIndex(primitiveKey);
++ final ArrayData array = getArray();
+
+ if (array.has(index)) {
+ return array.getObject(index);
+@@ -2743,98 +3056,167 @@
+ return get(index, JSType.toString(key));
+ }
+
+- /**
+- * Handle when an array doesn't have a slot - possibly grow and/or convert array.
+- *
+- * @param index key as index
+- * @param value element value
+- * @param strict are we in strict mode
+- */
+- private void doesNotHave(final int index, final Object value, final boolean strict) {
+- final long longIndex = ArrayIndex.toLongIndex(index);
++ private boolean doesNotHaveCheckArrayKeys(final long longIndex, final int value, final int callSiteFlags) {
+ if (getMap().containsArrayKeys()) {
+- final String key = JSType.toString(longIndex);
++ final String key = JSType.toString(longIndex);
+ final FindProperty find = findProperty(key, true);
+-
+ if (find != null) {
+- setObject(find, strict, key, value);
+- return;
++ setObject(find, callSiteFlags, key, value);
++ return true;
+ }
+ }
+-
+- setValueAtArrayIndex(longIndex, index, value, strict);
++ return false;
+ }
+
+- /**
+- * Handle when an array doesn't have a slot - possibly grow and/or convert array.
+- *
+- * @param index key as index
+- * @param value element value
+- * @param strict are we in strict mode
+- */
+- private void setValueAtArrayIndex(final long longIndex, final int index, final Object value, final boolean strict) {
+- final long oldLength = getArray().length();
++ private boolean doesNotHaveCheckArrayKeys(final long longIndex, final long value, final int callSiteFlags) {
++ if (getMap().containsArrayKeys()) {
++ final String key = JSType.toString(longIndex);
++ final FindProperty find = findProperty(key, true);
++ if (find != null) {
++ setObject(find, callSiteFlags, key, value);
++ return true;
++ }
++ }
++ return false;
++ }
++
++ private boolean doesNotHaveCheckArrayKeys(final long longIndex, final double value, final int callSiteFlags) {
++ if (getMap().containsArrayKeys()) {
++ final String key = JSType.toString(longIndex);
++ final FindProperty find = findProperty(key, true);
++ if (find != null) {
++ setObject(find, callSiteFlags, key, value);
++ return true;
++ }
++ }
++ return false;
++ }
++
++ private boolean doesNotHaveCheckArrayKeys(final long longIndex, final Object value, final int callSiteFlags) {
++ if (getMap().containsArrayKeys()) {
++ final String key = JSType.toString(longIndex);
++ final FindProperty find = findProperty(key, true);
++ if (find != null) {
++ setObject(find, callSiteFlags, key, value);
++ return true;
++ }
++ }
++ return false;
++ }
++
++ //value agnostic
++ private boolean doesNotHaveEnsureLength(final long longIndex, final long oldLength, final int callSiteFlags) {
+ if (longIndex >= oldLength) {
+ if (!isExtensible()) {
+- if (strict) {
+- throw typeError("object.non.extensible", JSType.toString(index), ScriptRuntime.safeToString(this));
++ if (isStrictFlag(callSiteFlags)) {
++ throw typeError("object.non.extensible", JSType.toString(longIndex), ScriptRuntime.safeToString(this));
+ }
+- return;
++ return true;
+ }
+ setArray(getArray().ensure(longIndex));
+ }
+-
+- if (value instanceof Integer) {
+- setArray(getArray().set(index, (int)value, strict));
+- } else if (value instanceof Long) {
+- setArray(getArray().set(index, (long)value, strict));
+- } else if (value instanceof Double) {
+- setArray(getArray().set(index, (double)value, strict));
+- } else {
+- setArray(getArray().set(index, value, strict));
+- }
+-
++ return false;
++ }
++
++ private void doesNotHaveEnsureDelete(final long longIndex, final long oldLength, final boolean strict) {
+ if (longIndex > oldLength) {
+ ArrayData array = getArray();
+-
+- if (array.canDelete(oldLength, (longIndex - 1), strict)) {
+- array = array.delete(oldLength, (longIndex - 1));
++ if (array.canDelete(oldLength, longIndex - 1, strict)) {
++ array = array.delete(oldLength, longIndex - 1);
+ }
+-
+ setArray(array);
+ }
+ }
+
++ private void doesNotHave(final int index, final int value, final int callSiteFlags) {
++ final long oldLength = getArray().length();
++ final long longIndex = ArrayIndex.toLongIndex(index);
++ if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) {
++ final boolean strict = isStrictFlag(callSiteFlags);
++ setArray(getArray().set(index, value, strict));
++ doesNotHaveEnsureDelete(longIndex, oldLength, strict);
++ }
++ }
++
++ private void doesNotHave(final int index, final long value, final int callSiteFlags) {
++ final long oldLength = getArray().length();
++ final long longIndex = ArrayIndex.toLongIndex(index);
++ if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) {
++ final boolean strict = isStrictFlag(callSiteFlags);
++ setArray(getArray().set(index, value, strict));
++ doesNotHaveEnsureDelete(longIndex, oldLength, strict);
++ }
++ }
++
++ private void doesNotHave(final int index, final double value, final int callSiteFlags) {
++ final long oldLength = getArray().length();
++ final long longIndex = ArrayIndex.toLongIndex(index);
++ if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) {
++ final boolean strict = isStrictFlag(callSiteFlags);
++ setArray(getArray().set(index, value, strict));
++ doesNotHaveEnsureDelete(longIndex, oldLength, strict);
++ }
++ }
++
++ private void doesNotHave(final int index, final Object value, final int callSiteFlags) {
++ final long oldLength = getArray().length();
++ final long longIndex = ArrayIndex.toLongIndex(index);
++ if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) {
++ final boolean strict = isStrictFlag(callSiteFlags);
++ setArray(getArray().set(index, value, strict));
++ doesNotHaveEnsureDelete(longIndex, oldLength, strict);
++ }
++ }
++
+ /**
+ * This is the most generic of all Object setters. Most of the others use this in some form.
+ * TODO: should be further specialized
+ *
+- * @param find found property
+- * @param strict are we in strict mode
+- * @param key property key
+- * @param value property value
++ * @param find found property
++ * @param callSiteFlags callsite flags
++ * @param key property key
++ * @param value property value
+ */
+- public final void setObject(final FindProperty find, final boolean strict, final String key, final Object value) {
++ public final void setObject(final FindProperty find, final int callSiteFlags, final String key, final Object value) {
+ FindProperty f = find;
+
+- if (f != null && f.isInherited() && !(f.getProperty() instanceof UserAccessorProperty) && !isScope()) {
+- // Setting a property should not modify the property in prototype unless this is a scope object.
+- f = null;
++ invalidateGlobalConstant(key);
++
++ if (f != null && f.isInherited() && !(f.getProperty() instanceof UserAccessorProperty)) {
++ final boolean isScope = isScopeFlag(callSiteFlags);
++ // If the start object of the find is not this object it means the property was found inside a
++ // 'with' statement expression (see WithObject.findProperty()). In this case we forward the 'set'
++ // to the 'with' object.
++ // Note that although a 'set' operation involving a with statement follows scope rules outside
++ // the 'with' expression (the 'set' operation is performed on the owning prototype if it exists),
++ // it follows non-scope rules inside the 'with' expression (set is performed on the top level object).
++ // This is why we clear the callsite flags and FindProperty in the forward call to the 'with' object.
++ if (isScope && f.getSelf() != this) {
++ f.getSelf().setObject(null, 0, key, value);
++ return;
++ }
++ // Setting a property should not modify the property in prototype unless this is a scope callsite
++ // and the owner is a scope object as well (with the exception of 'with' statement handled above).
++ if (!isScope || !f.getOwner().isScope()) {
++ f = null;
++ }
+ }
+
+ if (f != null) {
+ if (!f.getProperty().isWritable()) {
+- if (strict) {
++ if (isScopeFlag(callSiteFlags) && f.getProperty().isLexicalBinding()) {
++ throw typeError("assign.constant", key); // Overwriting ES6 const should throw also in non-strict mode.
++ }
++ if (isStrictFlag(callSiteFlags)) {
+ throw typeError("property.not.writable", key, ScriptRuntime.safeToString(this));
+ }
+-
+ return;
+ }
+
+- f.setObjectValue(value, strict);
++ f.setValue(value, isStrictFlag(callSiteFlags));
+
+ } else if (!isExtensible()) {
+- if (strict) {
++ if (isStrictFlag(callSiteFlags)) {
+ throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this));
+ }
+ } else {
+@@ -2846,311 +3228,323 @@
+ }
+ assert sobj != null : "no parent global object in scope";
+ }
+- sobj.spill(key, value);
++ //this will unbox any Number object to its primitive type in case the
++ //property supports primitive types, so it doesn't matter that it comes
++ //in as an Object.
++ sobj.addSpillProperty(key, 0, value, true);
+ }
+ }
+
+- private void spill(final String key, final Object value) {
+- addSpillProperty(key, 0).setObjectValue(this, this, value, false);
++ @Override
++ public void set(final Object key, final int value, final int callSiteFlags) {
++ final Object primitiveKey = JSType.toPrimitive(key, String.class);
++ final int index = getArrayIndex(primitiveKey);
++
++ if (isValidArrayIndex(index)) {
++ final ArrayData data = getArray();
++ if (data.has(index)) {
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
++ } else {
++ doesNotHave(index, value, callSiteFlags);
++ }
++
++ return;
++ }
++
++ final String propName = JSType.toString(primitiveKey);
++ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
+ }
+
+-
+ @Override
+- public void set(final Object key, final int value, final boolean strict) {
++ public void set(final Object key, final long value, final int callSiteFlags) {
+ final Object primitiveKey = JSType.toPrimitive(key, String.class);
+- final int index = getArrayIndex(primitiveKey);
+-
++ final int index = getArrayIndex(primitiveKey);
++
++ if (isValidArrayIndex(index)) {
++ final ArrayData data = getArray();
++ if (data.has(index)) {
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
++ } else {
++ doesNotHave(index, value, callSiteFlags);
++ }
++
++ return;
++ }
++
++ final String propName = JSType.toString(primitiveKey);
++ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
++ }
++
++ @Override
++ public void set(final Object key, final double value, final int callSiteFlags) {
++ final Object primitiveKey = JSType.toPrimitive(key, String.class);
++ final int index = getArrayIndex(primitiveKey);
++
++ if (isValidArrayIndex(index)) {
++ final ArrayData data = getArray();
++ if (data.has(index)) {
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
++ } else {
++ doesNotHave(index, value, callSiteFlags);
++ }
++
++ return;
++ }
++
++ final String propName = JSType.toString(primitiveKey);
++ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
++ }
++
++ @Override
++ public void set(final Object key, final Object value, final int callSiteFlags) {
++ final Object primitiveKey = JSType.toPrimitive(key, String.class);
++ final int index = getArrayIndex(primitiveKey);
++
++ if (isValidArrayIndex(index)) {
++ final ArrayData data = getArray();
++ if (data.has(index)) {
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
++ } else {
++ doesNotHave(index, value, callSiteFlags);
++ }
++
++ return;
++ }
++
++ final String propName = JSType.toString(primitiveKey);
++ setObject(findProperty(propName, true), callSiteFlags, propName, value);
++ }
++
++ @Override
++ public void set(final double key, final int value, final int callSiteFlags) {
++ final int index = getArrayIndex(key);
++
++ if (isValidArrayIndex(index)) {
++ final ArrayData data = getArray();
++ if (data.has(index)) {
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
++ } else {
++ doesNotHave(index, value, callSiteFlags);
++ }
++
++ return;
++ }
++
++ final String propName = JSType.toString(key);
++ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
++ }
++
++ @Override
++ public void set(final double key, final long value, final int callSiteFlags) {
++ final int index = getArrayIndex(key);
++
++ if (isValidArrayIndex(index)) {
++ final ArrayData data = getArray();
++ if (data.has(index)) {
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
++ } else {
++ doesNotHave(index, value, callSiteFlags);
++ }
++
++ return;
++ }
++
++ final String propName = JSType.toString(key);
++ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
++ }
++
++ @Override
++ public void set(final double key, final double value, final int callSiteFlags) {
++ final int index = getArrayIndex(key);
++
++ if (isValidArrayIndex(index)) {
++ final ArrayData data = getArray();
++ if (data.has(index)) {
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
++ } else {
++ doesNotHave(index, value, callSiteFlags);
++ }
++
++ return;
++ }
++
++ final String propName = JSType.toString(key);
++ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
++ }
++
++ @Override
++ public void set(final double key, final Object value, final int callSiteFlags) {
++ final int index = getArrayIndex(key);
++
++ if (isValidArrayIndex(index)) {
++ final ArrayData data = getArray();
++ if (data.has(index)) {
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
++ } else {
++ doesNotHave(index, value, callSiteFlags);
++ }
++
++ return;
++ }
++
++ final String propName = JSType.toString(key);
++ setObject(findProperty(propName, true), callSiteFlags, propName, value);
++ }
++
++ @Override
++ public void set(final long key, final int value, final int callSiteFlags) {
++ final int index = getArrayIndex(key);
++
++ if (isValidArrayIndex(index)) {
++ final ArrayData data = getArray();
++ if (data.has(index)) {
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
++ } else {
++ doesNotHave(index, value, callSiteFlags);
++ }
++
++ return;
++ }
++
++ final String propName = JSType.toString(key);
++ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
++ }
++
++ @Override
++ public void set(final long key, final long value, final int callSiteFlags) {
++ final int index = getArrayIndex(key);
++
++ if (isValidArrayIndex(index)) {
++ final ArrayData data = getArray();
++ if (data.has(index)) {
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
++ } else {
++ doesNotHave(index, value, callSiteFlags);
++ }
++
++ return;
++ }
++
++ final String propName = JSType.toString(key);
++ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
++ }
++
++ @Override
++ public void set(final long key, final double value, final int callSiteFlags) {
++ final int index = getArrayIndex(key);
++
++ if (isValidArrayIndex(index)) {
++ final ArrayData data = getArray();
++ if (data.has(index)) {
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
++ } else {
++ doesNotHave(index, value, callSiteFlags);
++ }
++
++ return;
++ }
++
++ final String propName = JSType.toString(key);
++ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
++ }
++
++ @Override
++ public void set(final long key, final Object value, final int callSiteFlags) {
++ final int index = getArrayIndex(key);
++
++ if (isValidArrayIndex(index)) {
++ final ArrayData data = getArray();
++ if (data.has(index)) {
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
++ } else {
++ doesNotHave(index, value, callSiteFlags);
++ }
++
++ return;
++ }
++
++ final String propName = JSType.toString(key);
++ setObject(findProperty(propName, true), callSiteFlags, propName, value);
++ }
++
++ @Override
++ public void set(final int key, final int value, final int callSiteFlags) {
++ final int index = getArrayIndex(key);
+ if (isValidArrayIndex(index)) {
+ if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
++ final ArrayData data = getArray();
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
+ } else {
+- doesNotHave(index, value, strict);
++ doesNotHave(index, value, callSiteFlags);
+ }
+-
+ return;
+ }
+
+- final String propName = JSType.toString(primitiveKey);
+- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
++ final String propName = JSType.toString(key);
++ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
+ }
+
+ @Override
+- public void set(final Object key, final long value, final boolean strict) {
+- final Object primitiveKey = JSType.toPrimitive(key, String.class);
+- final int index = getArrayIndex(primitiveKey);
++ public void set(final int key, final long value, final int callSiteFlags) {
++ final int index = getArrayIndex(key);
+
+ if (isValidArrayIndex(index)) {
+- if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
++ final ArrayData data = getArray();
++ if (data.has(index)) {
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
+ } else {
+- doesNotHave(index, value, strict);
++ doesNotHave(index, value, callSiteFlags);
+ }
+
+ return;
+ }
+
+- final String propName = JSType.toString(primitiveKey);
+- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
++ final String propName = JSType.toString(key);
++ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
+ }
+
+ @Override
+- public void set(final Object key, final double value, final boolean strict) {
+- final Object primitiveKey = JSType.toPrimitive(key, String.class);
+- final int index = getArrayIndex(primitiveKey);
++ public void set(final int key, final double value, final int callSiteFlags) {
++ final int index = getArrayIndex(key);
+
+ if (isValidArrayIndex(index)) {
+- if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
++ final ArrayData data = getArray();
++ if (data.has(index)) {
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
+ } else {
+- doesNotHave(index, value, strict);
++ doesNotHave(index, value, callSiteFlags);
+ }
+
+ return;
+ }
+
+- final String propName = JSType.toString(primitiveKey);
+- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
++ final String propName = JSType.toString(key);
++ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
+ }
+
+ @Override
+- public void set(final Object key, final Object value, final boolean strict) {
+- final Object primitiveKey = JSType.toPrimitive(key, String.class);
+- final int index = getArrayIndex(primitiveKey);
++ public void set(final int key, final Object value, final int callSiteFlags) {
++ final int index = getArrayIndex(key);
+
+ if (isValidArrayIndex(index)) {
+- if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
++ final ArrayData data = getArray();
++ if (data.has(index)) {
++ setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
+ } else {
+- doesNotHave(index, value, strict);
++ doesNotHave(index, value, callSiteFlags);
+ }
+
+ return;
+ }
+
+- final String propName = JSType.toString(primitiveKey);
+- setObject(findProperty(propName, true), strict, propName, value);
+- }
+-
+- @Override
+- public void set(final double key, final int value, final boolean strict) {
+- final int index = getArrayIndex(key);
+-
+- if (isValidArrayIndex(index)) {
+- if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
+- } else {
+- doesNotHave(index, value, strict);
+- }
+-
+- return;
+- }
+-
+ final String propName = JSType.toString(key);
+- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+- }
+-
+- @Override
+- public void set(final double key, final long value, final boolean strict) {
+- final int index = getArrayIndex(key);
+-
+- if (isValidArrayIndex(index)) {
+- if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
+- } else {
+- doesNotHave(index, value, strict);
+- }
+-
+- return;
+- }
+-
+- final String propName = JSType.toString(key);
+- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+- }
+-
+- @Override
+- public void set(final double key, final double value, final boolean strict) {
+- final int index = getArrayIndex(key);
+-
+- if (isValidArrayIndex(index)) {
+- if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
+- } else {
+- doesNotHave(index, value, strict);
+- }
+-
+- return;
+- }
+-
+- final String propName = JSType.toString(key);
+- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+- }
+-
+- @Override
+- public void set(final double key, final Object value, final boolean strict) {
+- final int index = getArrayIndex(key);
+-
+- if (isValidArrayIndex(index)) {
+- if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
+- } else {
+- doesNotHave(index, value, strict);
+- }
+-
+- return;
+- }
+-
+- final String propName = JSType.toString(key);
+- setObject(findProperty(propName, true), strict, propName, value);
+- }
+-
+- @Override
+- public void set(final long key, final int value, final boolean strict) {
+- final int index = getArrayIndex(key);
+-
+- if (isValidArrayIndex(index)) {
+- if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
+- } else {
+- doesNotHave(index, value, strict);
+- }
+-
+- return;
+- }
+-
+- final String propName = JSType.toString(key);
+- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+- }
+-
+- @Override
+- public void set(final long key, final long value, final boolean strict) {
+- final int index = getArrayIndex(key);
+-
+- if (isValidArrayIndex(index)) {
+- if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
+- } else {
+- doesNotHave(index, value, strict);
+- }
+-
+- return;
+- }
+-
+- final String propName = JSType.toString(key);
+- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+- }
+-
+- @Override
+- public void set(final long key, final double value, final boolean strict) {
+- final int index = getArrayIndex(key);
+-
+- if (isValidArrayIndex(index)) {
+- if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
+- } else {
+- doesNotHave(index, value, strict);
+- }
+-
+- return;
+- }
+-
+- final String propName = JSType.toString(key);
+- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+- }
+-
+- @Override
+- public void set(final long key, final Object value, final boolean strict) {
+- final int index = getArrayIndex(key);
+-
+- if (isValidArrayIndex(index)) {
+- if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
+- } else {
+- doesNotHave(index, value, strict);
+- }
+-
+- return;
+- }
+-
+- final String propName = JSType.toString(key);
+- setObject(findProperty(propName, true), strict, propName, value);
+- }
+-
+- @Override
+- public void set(final int key, final int value, final boolean strict) {
+- final int index = getArrayIndex(key);
+-
+- if (isValidArrayIndex(index)) {
+- if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
+- } else {
+- doesNotHave(index, value, strict);
+- }
+-
+- return;
+- }
+-
+- final String propName = JSType.toString(key);
+- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+- }
+-
+- @Override
+- public void set(final int key, final long value, final boolean strict) {
+- final int index = getArrayIndex(key);
+-
+- if (isValidArrayIndex(index)) {
+- if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
+- } else {
+- doesNotHave(index, value, strict);
+- }
+-
+- return;
+- }
+-
+- final String propName = JSType.toString(key);
+- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+- }
+-
+- @Override
+- public void set(final int key, final double value, final boolean strict) {
+- final int index = getArrayIndex(key);
+-
+- if (isValidArrayIndex(index)) {
+- if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
+- } else {
+- doesNotHave(index, value, strict);
+- }
+-
+- return;
+- }
+-
+- final String propName = JSType.toString(key);
+- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+- }
+-
+- @Override
+- public void set(final int key, final Object value, final boolean strict) {
+- final int index = getArrayIndex(key);
+-
+- if (isValidArrayIndex(index)) {
+- if (getArray().has(index)) {
+- setArray(getArray().set(index, value, strict));
+- } else {
+- doesNotHave(index, value, strict);
+- }
+-
+- return;
+- }
+-
+- final String propName = JSType.toString(key);
+- setObject(findProperty(propName, true), strict, propName, value);
++ setObject(findProperty(propName, true), callSiteFlags, propName, value);
+ }
+
+ @Override
+ public boolean has(final Object key) {
+ final Object primitiveKey = JSType.toPrimitive(key);
+- final int index = getArrayIndex(primitiveKey);
++ final int index = getArrayIndex(primitiveKey);
+ return isValidArrayIndex(index) ? hasArrayProperty(index) : hasProperty(JSType.toString(primitiveKey), true);
+ }
+
+@@ -3188,7 +3582,7 @@
+ @Override
+ public boolean hasOwnProperty(final Object key) {
+ final Object primitiveKey = JSType.toPrimitive(key, String.class);
+- final int index = getArrayIndex(primitiveKey);
++ final int index = getArrayIndex(primitiveKey);
+ return isValidArrayIndex(index) ? hasOwnArrayProperty(index) : hasProperty(JSType.toString(primitiveKey), false);
+ }
+
+@@ -3211,7 +3605,7 @@
+ }
+
+ private boolean hasOwnArrayProperty(final int index) {
+- return getArray().has(index) || (getMap().containsArrayKeys() && hasProperty(ArrayIndex.toKey(index), false));
++ return getArray().has(index) || getMap().containsArrayKeys() && hasProperty(ArrayIndex.toKey(index), false);
+ }
+
+ @Override
+@@ -3226,7 +3620,6 @@
+ }
+ return false;
+ }
+-
+ return deleteObject(JSType.toObject(key), strict);
+ }
+
+@@ -3264,9 +3657,9 @@
+
+ @Override
+ public boolean delete(final Object key, final boolean strict) {
+- final Object primitiveKey = JSType.toPrimitive(key, String.class);
+- final int index = getArrayIndex(primitiveKey);
+- final ArrayData array = getArray();
++ final Object primitiveKey = JSType.toPrimitive(key, String.class);
++ final int index = getArrayIndex(primitiveKey);
++ final ArrayData array = getArray();
+
+ if (array.has(index)) {
+ if (array.canDelete(index, strict)) {
+@@ -3301,6 +3694,31 @@
+ }
+
+ /**
++ * Return a shallow copy of this ScriptObject.
++ * @return a shallow copy.
++ */
++ public final ScriptObject copy() {
++ try {
++ return clone();
++ } catch (final CloneNotSupportedException e) {
++ throw new RuntimeException(e);
++ }
++ }
++
++ @Override
++ protected ScriptObject clone() throws CloneNotSupportedException {
++ final ScriptObject clone = (ScriptObject) super.clone();
++ if (objectSpill != null) {
++ clone.objectSpill = objectSpill.clone();
++ if (primitiveSpill != null) {
++ clone.primitiveSpill = primitiveSpill.clone();
++ }
++ }
++ clone.arrayData = arrayData.copy();
++ return clone;
++ }
++
++ /**
+ * Make a new UserAccessorProperty property. getter and setter functions are stored in
+ * this ScriptObject and slot values are used in property object.
+ *
+@@ -3311,60 +3729,91 @@
+ * @return the newly created UserAccessorProperty
+ */
+ protected final UserAccessorProperty newUserAccessors(final String key, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) {
+- final UserAccessorProperty property = getMap().newUserAccessors(key, propertyFlags);
+- setSpill(property.getGetterSlot(), getter);
+- setSpill(property.getSetterSlot(), setter);
+-
+- return property;
++ final UserAccessorProperty uc = getMap().newUserAccessors(key, propertyFlags);
++ //property.getSetter(Object.class, getMap());
++ uc.setAccessors(this, getMap(), new UserAccessorProperty.Accessors(getter, setter));
++ return uc;
+ }
+
+- /**
+- * Write a value to a spill slot
+- * @param slot the slot index
+- * @param value the value
+- */
+- protected final void setSpill(final int slot, final Object value) {
+- if (spill == null) {
+- // create new spill.
+- spill = new Object[Math.max(slot + 1, SPILL_RATE)];
+- } else if (slot >= spill.length) {
+- // grow spill as needed
+- final Object[] newSpill = new Object[slot + 1];
+- System.arraycopy(spill, 0, newSpill, 0, spill.length);
+- spill = newSpill;
++ Object ensureSpillSize(final int slot) {
++ if (slot < spillLength) {
++ return this;
+ }
+-
+- spill[slot] = value;
++ final int newLength = alignUp(slot + 1, SPILL_RATE);
++ final Object[] newObjectSpill = new Object[newLength];
++ final long[] newPrimitiveSpill = OBJECT_FIELDS_ONLY ? null : new long[newLength];
++
++ if (objectSpill != null) {
++ System.arraycopy(objectSpill, 0, newObjectSpill, 0, spillLength);
++ if (!OBJECT_FIELDS_ONLY) {
++ System.arraycopy(primitiveSpill, 0, newPrimitiveSpill, 0, spillLength);
++ }
++ }
++
++ this.primitiveSpill = newPrimitiveSpill;
++ this.objectSpill = newObjectSpill;
++ this.spillLength = newLength;
++
++ return this;
+ }
+
+- /**
+- * Get a value from a spill slot
+- * @param slot the slot index
+- * @return the value in the spill slot with the given index
+- */
+- protected Object getSpill(final int slot) {
+- return spill != null && slot < spill.length ? spill[slot] : null;
++ private static MethodHandle findOwnMH_V(final Class<? extends ScriptObject> clazz, final String name, final Class<?> rtype, final Class<?>... types) {
++ // TODO: figure out how can it work for NativeArray$Prototype etc.
++ return MH.findVirtual(MethodHandles.lookup(), ScriptObject.class, name, MH.type(rtype, types));
+ }
+
+- private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+- final Class<?> own = ScriptObject.class;
+- final MethodType mt = MH.type(rtype, types);
+- try {
+- return MH.findStatic(MethodHandles.lookup(), own, name, mt);
+- } catch (final MethodHandleFactory.LookupException e) {
+- return MH.findVirtual(MethodHandles.lookup(), own, name, mt);
+- }
++ private static MethodHandle findOwnMH_V(final String name, final Class<?> rtype, final Class<?>... types) {
++ return findOwnMH_V(ScriptObject.class, name, rtype, types);
+ }
+
+- private static MethodHandle getKnownFunctionPropertyGuard(final PropertyMap map, final MethodHandle getter, final Object where, final ScriptFunction func) {
+- return MH.insertArguments(KNOWNFUNCPROPGUARD, 1, map, getter, where, func);
++ private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
++ return MH.findStatic(MethodHandles.lookup(), ScriptObject.class, name, MH.type(rtype, types));
+ }
+
++ private static MethodHandle getKnownFunctionPropertyGuardSelf(final PropertyMap map, final MethodHandle getter, final ScriptFunction func) {
++ return MH.insertArguments(KNOWNFUNCPROPGUARDSELF, 1, map, getter, func);
++ }
++
+ @SuppressWarnings("unused")
+- private static boolean knownFunctionPropertyGuard(final Object self, final PropertyMap map, final MethodHandle getter, final Object where, final ScriptFunction func) {
++ private static boolean knownFunctionPropertyGuardSelf(final Object self, final PropertyMap map, final MethodHandle getter, final ScriptFunction func) {
+ if (self instanceof ScriptObject && ((ScriptObject)self).getMap() == map) {
+ try {
+- return getter.invokeExact(where) == func;
++ return getter.invokeExact(self) == func;
++ } catch (final RuntimeException | Error e) {
++ throw e;
++ } catch (final Throwable t) {
++ throw new RuntimeException(t);
++ }
++ }
++
++ return false;
++ }
++
++ private static MethodHandle getKnownFunctionPropertyGuardProto(final PropertyMap map, final MethodHandle getter, final int depth, final ScriptFunction func) {
++ return MH.insertArguments(KNOWNFUNCPROPGUARDPROTO, 1, map, getter, depth, func);
++ }
++
++ private static ScriptObject getProto(final ScriptObject self, final int depth) {
++ ScriptObject proto = self;
++ for (int d = 0; d < depth; d++) {
++ proto = proto.getProto();
++ if (proto == null) {
++ return null;
++ }
++ }
++
++ return proto;
++ }
++
++ @SuppressWarnings("unused")
++ private static boolean knownFunctionPropertyGuardProto(final Object self, final PropertyMap map, final MethodHandle getter, final int depth, final ScriptFunction func) {
++ if (self instanceof ScriptObject && ((ScriptObject)self).getMap() == map) {
++ final ScriptObject proto = getProto((ScriptObject)self, depth);
++ if (proto == null) {
++ return false;
++ }
++ try {
++ return getter.invokeExact((Object)proto) == func;
+ } catch (final RuntimeException | Error e) {
+ throw e;
+ } catch (final Throwable t) {
+--- ./nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,13 +27,14 @@
+
+ import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
+ import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
++import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.syntaxError;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+ import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsInt;
+-
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
++import java.lang.invoke.SwitchPoint;
+ import java.lang.reflect.Array;
+ import java.util.Collections;
+ import java.util.Iterator;
+@@ -45,9 +46,12 @@
+ import jdk.internal.dynalink.beans.StaticClass;
+ import jdk.nashorn.api.scripting.JSObject;
+ import jdk.nashorn.api.scripting.ScriptObjectMirror;
++import jdk.nashorn.internal.codegen.ApplySpecialization;
++import jdk.nashorn.internal.codegen.CompilerConstants;
+ import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+ import jdk.nashorn.internal.ir.debug.JSONWriter;
+ import jdk.nashorn.internal.objects.Global;
++import jdk.nashorn.internal.objects.NativeObject;
+ import jdk.nashorn.internal.parser.Lexer;
+ import jdk.nashorn.internal.runtime.linker.Bootstrap;
+
+@@ -81,9 +85,6 @@
+ /** Method handle used to enter a {@code with} scope at runtime. */
+ public static final Call OPEN_WITH = staticCallNoLookup(ScriptRuntime.class, "openWith", ScriptObject.class, ScriptObject.class, Object.class);
+
+- /** Method handle used to exit a {@code with} scope at runtime. */
+- public static final Call CLOSE_WITH = staticCallNoLookup(ScriptRuntime.class, "closeWith", ScriptObject.class, ScriptObject.class);
+-
+ /**
+ * Method used to place a scope's variable into the Global scope, which has to be done for the
+ * properties declared at outermost script level.
+@@ -108,6 +109,16 @@
+ public static final Call APPLY = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "apply", Object.class, ScriptFunction.class, Object.class, Object[].class);
+
+ /**
++ * Throws a reference error for an undefined variable.
++ */
++ public static final Call THROW_REFERENCE_ERROR = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "throwReferenceError", void.class, String.class);
++
++ /**
++ * Used to invalidate builtin names, e.g "Function" mapping to all properties in Function.prototype and Function.prototype itself.
++ */
++ public static final Call INVALIDATE_RESERVED_BUILTIN_NAME = staticCallNoLookup(ScriptRuntime.class, "invalidateReservedBuiltinName", void.class, String.class);
++
++ /**
+ * Converts a switch tag value to a simple integer. deflt value if it can't.
+ *
+ * @param tag Switch statement tag value.
+@@ -121,7 +132,6 @@
+ return (int)d;
+ }
+ }
+-
+ return deflt;
+ }
+
+@@ -169,7 +179,7 @@
+ // But we don't need to -- all we need is the right class name
+ // of the corresponding primitive wrapper type.
+
+- final JSType type = JSType.of(self);
++ final JSType type = JSType.ofNoFunction(self);
+
+ switch (type) {
+ case BOOLEAN:
+@@ -189,7 +199,6 @@
+ className = "Undefined";
+ break;
+ case OBJECT:
+- case FUNCTION:
+ if (self instanceof ScriptObject) {
+ className = ((ScriptObject)self).getClassName();
+ } else if (self instanceof JSObject) {
+@@ -271,7 +280,7 @@
+ private final int length;
+ private int index;
+
+- RangeIterator(int length) {
++ RangeIterator(final int length) {
+ this.length = length;
+ }
+
+@@ -287,7 +296,7 @@
+
+ @Override
+ public void remove() {
+- throw new UnsupportedOperationException();
++ throw new UnsupportedOperationException("remove");
+ }
+ }
+
+@@ -325,7 +334,7 @@
+
+ @Override
+ public void remove() {
+- throw new UnsupportedOperationException();
++ throw new UnsupportedOperationException("remove");
+ }
+ };
+ }
+@@ -384,6 +393,15 @@
+ }
+
+ /**
++ * Throws a reference error for an undefined variable.
++ *
++ * @param name the variable name
++ */
++ public static void throwReferenceError(final String name) {
++ throw referenceError("not.defined", name);
++ }
++
++ /**
+ * Call a script function as a constructor with given args.
+ *
+ * @param target ScriptFunction object.
+@@ -409,8 +427,8 @@
+ * @return true if both objects have the same value
+ */
+ public static boolean sameValue(final Object x, final Object y) {
+- final JSType xType = JSType.of(x);
+- final JSType yType = JSType.of(y);
++ final JSType xType = JSType.ofNoFunction(x);
++ final JSType yType = JSType.ofNoFunction(y);
+
+ if (xType != yType) {
+ return false;
+@@ -429,7 +447,7 @@
+ }
+
+ // checking for xVal == -0.0 and yVal == +0.0 or vice versa
+- if (xVal == 0.0 && (Double.doubleToLongBits(xVal) != Double.doubleToLongBits(yVal))) {
++ if (xVal == 0.0 && Double.doubleToLongBits(xVal) != Double.doubleToLongBits(yVal)) {
+ return false;
+ }
+
+@@ -440,7 +458,7 @@
+ return x.equals(y);
+ }
+
+- return (x == y);
++ return x == y;
+ }
+
+ /**
+@@ -453,7 +471,7 @@
+ * @return JSON string representation of AST of the supplied code
+ */
+ public static String parse(final String code, final String name, final boolean includeLoc) {
+- return JSONWriter.parse(Context.getContextTrusted().getEnv(), code, name, includeLoc);
++ return JSONWriter.parse(Context.getContextTrusted(), code, name, includeLoc);
+ }
+
+ /**
+@@ -466,7 +484,8 @@
+ }
+
+ /**
+- * Entering a {@code with} node requires new scope. This is the implementation
++ * Entering a {@code with} node requires new scope. This is the implementation. When exiting the with statement,
++ * use {@link ScriptObject#getProto()} on the scope.
+ *
+ * @param scope existing scope
+ * @param expression expression in with
+@@ -481,6 +500,17 @@
+ throw typeError(global, "cant.apply.with.to.null");
+ }
+
++ if (expression instanceof ScriptObjectMirror) {
++ final Object unwrapped = ScriptObjectMirror.unwrap(expression, global);
++ if (unwrapped instanceof ScriptObject) {
++ return new WithObject(scope, (ScriptObject)unwrapped);
++ }
++ // foreign ScriptObjectMirror
++ final ScriptObject exprObj = global.newObject();
++ NativeObject.bindAllProperties(exprObj, (ScriptObjectMirror)expression);
++ return new WithObject(scope, exprObj);
++ }
++
+ final Object wrappedExpr = JSType.toScriptObject(global, expression);
+ if (wrappedExpr instanceof ScriptObject) {
+ return new WithObject(scope, (ScriptObject)wrappedExpr);
+@@ -490,20 +520,6 @@
+ }
+
+ /**
+- * Exiting a {@code with} node requires restoring scope. This is the implementation
+- *
+- * @param scope existing scope
+- *
+- * @return restored scope
+- */
+- public static ScriptObject closeWith(final ScriptObject scope) {
+- if (scope instanceof WithObject) {
+- return ((WithObject)scope).getParentScope();
+- }
+- return scope;
+- }
+-
+- /**
+ * ECMA 11.6.1 - The addition operator (+) - generic implementation
+ * Compiler specializes using {@link jdk.nashorn.internal.codegen.RuntimeCallSite}
+ * if any type information is available for any of the operands
+@@ -525,7 +541,7 @@
+ final boolean xIsUndefined = x == UNDEFINED;
+ final boolean yIsUndefined = y == UNDEFINED;
+
+- if ((xIsNumber && yIsUndefined) || (xIsUndefined && yIsNumber) || (xIsUndefined && yIsUndefined)) {
++ if (xIsNumber && yIsUndefined || xIsUndefined && yIsNumber || xIsUndefined && yIsUndefined) {
+ return Double.NaN;
+ }
+
+@@ -535,7 +551,11 @@
+
+ if (xPrim instanceof String || yPrim instanceof String
+ || xPrim instanceof ConsString || yPrim instanceof ConsString) {
+- return new ConsString(JSType.toCharSequence(xPrim), JSType.toCharSequence(yPrim));
++ try {
++ return new ConsString(JSType.toCharSequence(xPrim), JSType.toCharSequence(yPrim));
++ } catch (final IllegalArgumentException iae) {
++ throw rangeError(iae, "concat.string.too.big");
++ }
+ }
+
+ return JSType.toNumber(xPrim) + JSType.toNumber(yPrim);
+@@ -577,6 +597,13 @@
+ if (property != null) {
+ if (obj instanceof ScriptObject) {
+ obj = ((ScriptObject)obj).get(property);
++ if(Global.isLocationPropertyPlaceholder(obj)) {
++ if(CompilerConstants.__LINE__.name().equals(property)) {
++ obj = Integer.valueOf(0);
++ } else {
++ obj = "";
++ }
++ }
+ } else if (object instanceof Undefined) {
+ obj = ((Undefined)obj).get(property);
+ } else if (object == null) {
+@@ -689,67 +716,100 @@
+
+ /** ECMA 11.9.3 The Abstract Equality Comparison Algorithm */
+ private static boolean equals(final Object x, final Object y) {
+- final JSType xType = JSType.of(x);
+- final JSType yType = JSType.of(y);
++ if (x == y) {
++ return true;
++ }
++ if (x instanceof ScriptObject && y instanceof ScriptObject) {
++ return x == y;
++ }
++ if (x instanceof ScriptObjectMirror || y instanceof ScriptObjectMirror) {
++ return ScriptObjectMirror.identical(x, y);
++ }
++ return equalValues(x, y);
++ }
++
++ /**
++ * Extracted portion of {@code equals()} that compares objects by value (or by reference, if no known value
++ * comparison applies).
++ * @param x one value
++ * @param y another value
++ * @return true if they're equal according to 11.9.3
++ */
++ private static boolean equalValues(final Object x, final Object y) {
++ final JSType xType = JSType.ofNoFunction(x);
++ final JSType yType = JSType.ofNoFunction(y);
+
+ if (xType == yType) {
+-
+- if (xType == JSType.UNDEFINED || xType == JSType.NULL) {
+- return true;
+- }
+-
+- if (xType == JSType.NUMBER) {
+- final double xVal = ((Number)x).doubleValue();
+- final double yVal = ((Number)y).doubleValue();
+- if (Double.isNaN(xVal) || Double.isNaN(yVal)) {
+- return false;
+- }
+-
+- return xVal == yVal;
+- }
+-
+- if (xType == JSType.STRING) {
+- // String may be represented by ConsString
+- return x.toString().equals(y.toString());
+- }
+-
+- if (xType == JSType.BOOLEAN) {
+- // Boolean comparison
+- return x.equals(y);
+- }
+-
+- return x == y;
++ return equalSameTypeValues(x, y, xType);
+ }
+
+- if ((xType == JSType.UNDEFINED && yType == JSType.NULL) ||
+- (xType == JSType.NULL && yType == JSType.UNDEFINED)) {
++ return equalDifferentTypeValues(x, y, xType, yType);
++ }
++
++ /**
++ * Extracted portion of {@link #equals(Object, Object)} and {@link #strictEquals(Object, Object)} that compares
++ * values belonging to the same JSType.
++ * @param x one value
++ * @param y another value
++ * @param type the common type for the values
++ * @return true if they're equal
++ */
++ private static boolean equalSameTypeValues(final Object x, final Object y, final JSType type) {
++ if (type == JSType.UNDEFINED || type == JSType.NULL) {
++ return true;
++ }
++
++ if (type == JSType.NUMBER) {
++ return ((Number)x).doubleValue() == ((Number)y).doubleValue();
++ }
++
++ if (type == JSType.STRING) {
++ // String may be represented by ConsString
++ return x.toString().equals(y.toString());
++ }
++
++ if (type == JSType.BOOLEAN) {
++ return ((Boolean)x).booleanValue() == ((Boolean)y).booleanValue();
++ }
++
++ return x == y;
++ }
++
++ /**
++ * Extracted portion of {@link #equals(Object, Object)} that compares values belonging to different JSTypes.
++ * @param x one value
++ * @param y another value
++ * @param xType the type for the value x
++ * @param yType the type for the value y
++ * @return true if they're equal
++ */
++ private static boolean equalDifferentTypeValues(final Object x, final Object y, final JSType xType, final JSType yType) {
++ if (xType == JSType.UNDEFINED && yType == JSType.NULL || xType == JSType.NULL && yType == JSType.UNDEFINED) {
+ return true;
+ }
+
+ if (xType == JSType.NUMBER && yType == JSType.STRING) {
+- return EQ(x, JSType.toNumber(y));
++ return equals(x, JSType.toNumber(y));
+ }
+
+ if (xType == JSType.STRING && yType == JSType.NUMBER) {
+- return EQ(JSType.toNumber(x), y);
++ return equals(JSType.toNumber(x), y);
+ }
+
+ if (xType == JSType.BOOLEAN) {
+- return EQ(JSType.toNumber(x), y);
++ return equals(JSType.toNumber(x), y);
+ }
+
+ if (yType == JSType.BOOLEAN) {
+- return EQ(x, JSType.toNumber(y));
++ return equals(x, JSType.toNumber(y));
+ }
+
+- if ((xType == JSType.STRING || xType == JSType.NUMBER) &&
+- (y instanceof ScriptObject)) {
+- return EQ(x, JSType.toPrimitive(y));
++ if ((xType == JSType.STRING || xType == JSType.NUMBER) && y instanceof ScriptObject) {
++ return equals(x, JSType.toPrimitive(y));
+ }
+
+- if ((x instanceof ScriptObject) &&
+- (yType == JSType.STRING || yType == JSType.NUMBER)) {
+- return EQ(JSType.toPrimitive(x), y);
++ if (x instanceof ScriptObject && (yType == JSType.STRING || yType == JSType.NUMBER)) {
++ return equals(JSType.toPrimitive(x), y);
+ }
+
+ return false;
+@@ -781,39 +841,17 @@
+
+ /** ECMA 11.9.6 The Strict Equality Comparison Algorithm */
+ private static boolean strictEquals(final Object x, final Object y) {
+- final JSType xType = JSType.of(x);
+- final JSType yType = JSType.of(y);
++ // NOTE: you might be tempted to do a quick x == y comparison. Remember, though, that any Double object having
++ // NaN value is not equal to itself by value even though it is referentially.
++
++ final JSType xType = JSType.ofNoFunction(x);
++ final JSType yType = JSType.ofNoFunction(y);
+
+ if (xType != yType) {
+ return false;
+ }
+
+- if (xType == JSType.UNDEFINED || xType == JSType.NULL) {
+- return true;
+- }
+-
+- if (xType == JSType.NUMBER) {
+- final double xVal = ((Number)x).doubleValue();
+- final double yVal = ((Number)y).doubleValue();
+-
+- if (Double.isNaN(xVal) || Double.isNaN(yVal)) {
+- return false;
+- }
+-
+- return xVal == yVal;
+- }
+-
+- if (xType == JSType.STRING) {
+- // String may be represented by ConsString
+- return x.toString().equals(y.toString());
+- }
+-
+- if (xType == JSType.BOOLEAN) {
+- return x.equals(y);
+- }
+-
+- // finally, the object identity comparison
+- return x == y;
++ return equalSameTypeValues(x, y, xType);
+ }
+
+ /**
+@@ -825,9 +863,9 @@
+ * @return true if objects are equal
+ */
+ public static boolean IN(final Object property, final Object obj) {
+- final JSType rvalType = JSType.of(obj);
++ final JSType rvalType = JSType.ofNoFunction(obj);
+
+- if (rvalType == JSType.OBJECT || rvalType == JSType.FUNCTION) {
++ if (rvalType == JSType.OBJECT) {
+ if (obj instanceof ScriptObject) {
+ return ((ScriptObject)obj).has(property);
+ }
+@@ -884,7 +922,7 @@
+ */
+ public static boolean LT(final Object x, final Object y) {
+ final Object value = lessThan(x, y, true);
+- return (value == UNDEFINED) ? false : (Boolean)value;
++ return value == UNDEFINED ? false : (Boolean)value;
+ }
+
+ /**
+@@ -897,7 +935,7 @@
+ */
+ public static boolean GT(final Object x, final Object y) {
+ final Object value = lessThan(y, x, false);
+- return (value == UNDEFINED) ? false : (Boolean)value;
++ return value == UNDEFINED ? false : (Boolean)value;
+ }
+
+ /**
+@@ -910,7 +948,7 @@
+ */
+ public static boolean LE(final Object x, final Object y) {
+ final Object value = lessThan(y, x, false);
+- return (!(Boolean.TRUE.equals(value) || value == UNDEFINED));
++ return !(Boolean.TRUE.equals(value) || value == UNDEFINED);
+ }
+
+ /**
+@@ -923,7 +961,7 @@
+ */
+ public static boolean GE(final Object x, final Object y) {
+ final Object value = lessThan(x, y, true);
+- return (!(Boolean.TRUE.equals(value) || value == UNDEFINED));
++ return !(Boolean.TRUE.equals(value) || value == UNDEFINED);
+ }
+
+ /** ECMA 11.8.5 The Abstract Relational Comparison Algorithm */
+@@ -939,9 +977,9 @@
+ px = JSType.toPrimitive(x, Number.class);
+ }
+
+- if (JSType.of(px) == JSType.STRING && JSType.of(py) == JSType.STRING) {
++ if (JSType.ofNoFunction(px) == JSType.STRING && JSType.ofNoFunction(py) == JSType.STRING) {
+ // May be String or ConsString
+- return (px.toString()).compareTo(py.toString()) < 0;
++ return px.toString().compareTo(py.toString()) < 0;
+ }
+
+ final double nx = JSType.toNumber(px);
+@@ -966,4 +1004,19 @@
+ return nx < ny;
+ }
+
++ /**
++ * Tag a reserved name as invalidated - used when someone writes
++ * to a property with this name - overly conservative, but link time
++ * is too late to apply e.g. apply-&gt;call specialization
++ * @param name property name
++ */
++ public static void invalidateReservedBuiltinName(final String name) {
++ final Context context = Context.getContextTrusted();
++ final SwitchPoint sp = context.getBuiltinSwitchPoint(name);
++ assert sp != null;
++ if (sp != null) {
++ context.getLogger(ApplySpecialization.class).info("Overwrote special name '" + name +"' - invalidating switchpoint");
++ SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
++ }
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,9 +25,9 @@
+
+ package jdk.nashorn.internal.runtime;
+
++import static jdk.nashorn.internal.lookup.Lookup.MH;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+-import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+ import java.io.BufferedReader;
+ import java.io.File;
+@@ -107,8 +107,8 @@
+
+ if (file instanceof File) {
+ f = (File)file;
+- } else if (file instanceof String) {
+- f = new java.io.File((String)file);
++ } else if (file instanceof String || file instanceof ConsString) {
++ f = new java.io.File(((CharSequence)file).toString());
+ }
+
+ if (f == null || !f.isFile()) {
+@@ -157,7 +157,7 @@
+ // Set up ENV variables.
+ final Map<String, String> environment = processBuilder.environment();
+ environment.clear();
+- for (Map.Entry<Object, Object> entry : envProperties.entrySet()) {
++ for (final Map.Entry<Object, Object> entry : envProperties.entrySet()) {
+ environment.put(JSType.toString(entry.getKey()), JSType.toString(entry.getValue()));
+ }
+ }
+@@ -168,15 +168,15 @@
+
+ // Collect output.
+ final StringBuilder outBuffer = new StringBuilder();
+- Thread outThread = new Thread(new Runnable() {
++ final Thread outThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+- char buffer[] = new char[1024];
++ final char buffer[] = new char[1024];
+ try (final InputStreamReader inputStream = new InputStreamReader(process.getInputStream())) {
+ for (int length; (length = inputStream.read(buffer, 0, buffer.length)) != -1; ) {
+ outBuffer.append(buffer, 0, length);
+ }
+- } catch (IOException ex) {
++ } catch (final IOException ex) {
+ exception[0] = ex;
+ }
+ }
+@@ -184,15 +184,15 @@
+
+ // Collect errors.
+ final StringBuilder errBuffer = new StringBuilder();
+- Thread errThread = new Thread(new Runnable() {
++ final Thread errThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+- char buffer[] = new char[1024];
++ final char buffer[] = new char[1024];
+ try (final InputStreamReader inputStream = new InputStreamReader(process.getErrorStream())) {
+ for (int length; (length = inputStream.read(buffer, 0, buffer.length)) != -1; ) {
+ errBuffer.append(buffer, 0, length);
+ }
+- } catch (IOException ex) {
++ } catch (final IOException ex) {
+ exception[1] = ex;
+ }
+ }
+@@ -205,10 +205,10 @@
+ // If input is present, pass on to process.
+ try (OutputStreamWriter outputStream = new OutputStreamWriter(process.getOutputStream())) {
+ if (input != UNDEFINED) {
+- String in = JSType.toString(input);
++ final String in = JSType.toString(input);
+ outputStream.write(in, 0, in.length());
+ }
+- } catch (IOException ex) {
++ } catch (final IOException ex) {
+ // Process was not expecting input. May be normal state of affairs.
+ }
+
+@@ -221,14 +221,14 @@
+ final String err = errBuffer.toString();
+
+ // Set globals for secondary results.
+- global.set(OUT_NAME, out, false);
+- global.set(ERR_NAME, err, false);
+- global.set(EXIT_NAME, exit, false);
++ global.set(OUT_NAME, out, 0);
++ global.set(ERR_NAME, err, 0);
++ global.set(EXIT_NAME, exit, 0);
+
+ // Propagate exception if present.
+- for (int i = 0; i < exception.length; i++) {
+- if (exception[i] != null) {
+- throw exception[i];
++ for (final IOException element : exception) {
++ if (element != null) {
++ throw element;
+ }
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,17 +25,17 @@
+
+ package jdk.nashorn.internal.runtime;
+
++import static jdk.nashorn.internal.lookup.Lookup.MH;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
+-import static jdk.nashorn.internal.lookup.Lookup.MH;
+-
++import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex;
+ import java.lang.invoke.MethodHandle;
++import java.lang.invoke.SwitchPoint;
+ import jdk.internal.dynalink.CallSiteDescriptor;
+ import jdk.internal.dynalink.linker.GuardedInvocation;
+-import jdk.nashorn.internal.lookup.Lookup;
++import jdk.internal.dynalink.linker.LinkRequest;
+ import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+ import jdk.nashorn.internal.runtime.linker.NashornGuards;
+
+-
+ /**
+ * Instances of this class are quite ephemeral; they only exist for the duration of an invocation of
+ * {@link ScriptObject#findSetMethod(CallSiteDescriptor, jdk.internal.dynalink.linker.LinkRequest)} and
+@@ -43,10 +43,12 @@
+ */
+ final class SetMethodCreator {
+ // See constructor parameters for description of fields
+- private final ScriptObject sobj;
+- private final PropertyMap map;
+- private final FindProperty find;
++ private final ScriptObject sobj;
++ private final PropertyMap map;
++ private final FindProperty find;
+ private final CallSiteDescriptor desc;
++ private final Class<?> type;
++ private final LinkRequest request;
+
+ /**
+ * Creates a new property setter method creator.
+@@ -54,12 +56,16 @@
+ * @param find a result of a {@link ScriptObject#findProperty(String, boolean)} on the object for the property we
+ * want to create a setter for. Can be null if the property does not yet exist on the object.
+ * @param desc the descriptor of the call site that triggered the property setter lookup
++ * @param request the link request
+ */
+- SetMethodCreator(final ScriptObject sobj, final FindProperty find, final CallSiteDescriptor desc) {
+- this.sobj = sobj;
+- this.map = sobj.getMap();
+- this.find = find;
+- this.desc = desc;
++ SetMethodCreator(final ScriptObject sobj, final FindProperty find, final CallSiteDescriptor desc, final LinkRequest request) {
++ this.sobj = sobj;
++ this.map = sobj.getMap();
++ this.find = find;
++ this.desc = desc;
++ this.type = desc.getMethodType().parameterType(1);
++ this.request = request;
++
+ }
+
+ private String getName() {
+@@ -74,8 +80,8 @@
+ * Creates the actual guarded invocation that represents the dynamic setter method for the property.
+ * @return the actual guarded invocation that represents the dynamic setter method for the property.
+ */
+- GuardedInvocation createGuardedInvocation() {
+- return createSetMethod().createGuardedInvocation();
++ GuardedInvocation createGuardedInvocation(final SwitchPoint builtinSwitchPoint) {
++ return createSetMethod(builtinSwitchPoint).createGuardedInvocation();
+ }
+
+ /**
+@@ -95,7 +101,7 @@
+ SetMethod(final MethodHandle methodHandle, final Property property) {
+ assert methodHandle != null;
+ this.methodHandle = methodHandle;
+- this.property = property;
++ this.property = property;
+ }
+
+ /**
+@@ -103,12 +109,16 @@
+ * @return the composed guarded invocation that represents the dynamic setter method for the property.
+ */
+ GuardedInvocation createGuardedInvocation() {
+- return new GuardedInvocation(methodHandle, NashornGuards.getGuard(sobj, property, desc));
++ // getGuard() and getException() either both return null, or neither does. The reason for that is that now
++ // getGuard returns a map guard that casts its argument to ScriptObject, and if that fails, we need to
++ // relink on ClassCastException.
++ final boolean explicitInstanceOfCheck = NashornGuards.explicitInstanceOfCheck(desc, request);
++ return new GuardedInvocation(methodHandle, NashornGuards.getGuard(sobj, property, desc, explicitInstanceOfCheck),
++ (SwitchPoint)null, explicitInstanceOfCheck ? null : ClassCastException.class);
+ }
+-
+ }
+
+- private SetMethod createSetMethod() {
++ private SetMethod createSetMethod(final SwitchPoint builtinSwitchPoint) {
+ if (find != null) {
+ return createExistingPropertySetter();
+ }
+@@ -119,7 +129,7 @@
+ return createGlobalPropertySetter();
+ }
+
+- return createNewPropertySetter();
++ return createNewPropertySetter(builtinSwitchPoint);
+ }
+
+ private void checkStrictCreateNewVariable() {
+@@ -132,14 +142,36 @@
+
+ private SetMethod createExistingPropertySetter() {
+ final Property property = find.getProperty();
+- final Class<?> type = desc.getMethodType().parameterType(1);
+- final MethodHandle methodHandle = find.getSetter(type, NashornCallSiteDescriptor.isStrict(desc));
++ final boolean isStrict = NashornCallSiteDescriptor.isStrict(desc);
++ final MethodHandle methodHandle;
++
++ if (NashornCallSiteDescriptor.isDeclaration(desc)) {
++ assert property.needsDeclaration();
++ // This is a LET or CONST being declared. The property is already there but flagged as needing declaration.
++ // We create a new PropertyMap with the flag removed. The map is installed with a fast compare-and-set
++ // method if the pre-callsite map is stable (which should be the case for function scopes except for
++ // non-strict functions containing eval() with var). Otherwise we have to use a slow setter that creates
++ // a new PropertyMap on the fly.
++ final PropertyMap oldMap = getMap();
++ final Property newProperty = property.removeFlags(Property.NEEDS_DECLARATION);
++ final PropertyMap newMap = oldMap.replaceProperty(property, newProperty);
++ final MethodHandle fastSetter = find.replaceProperty(newProperty).getSetter(type, isStrict, request);
++ final MethodHandle slowSetter = MH.insertArguments(ScriptObject.DECLARE_AND_SET, 1, getName()).asType(fastSetter.type());
++
++ // cas map used as guard, if true that means we can do the set fast
++ MethodHandle casMap = MH.insertArguments(ScriptObject.CAS_MAP, 1, oldMap, newMap);
++ casMap = MH.dropArguments(casMap, 1, type);
++ casMap = MH.asType(casMap, casMap.type().changeParameterType(0, Object.class));
++ methodHandle = MH.guardWithTest(casMap, fastSetter, slowSetter);
++ } else {
++ methodHandle = find.getSetter(type, isStrict, request);
++ }
+
+ assert methodHandle != null;
+ assert property != null;
+
+ final MethodHandle boundHandle;
+- if (!property.hasSetterFunction(find.getOwner()) && find.isInherited()) {
++ if (!(property instanceof UserAccessorProperty) && find.isInherited()) {
+ boundHandle = ScriptObject.addProtoFilter(methodHandle, find.getProtoChainLength());
+ } else {
+ boundHandle = methodHandle;
+@@ -149,11 +181,11 @@
+
+ private SetMethod createGlobalPropertySetter() {
+ final ScriptObject global = Context.getGlobal();
+- return new SetMethod(MH.filterArguments(global.addSpill(getName()), 0, ScriptObject.GLOBALFILTER), null);
++ return new SetMethod(MH.filterArguments(global.addSpill(type, getName()), 0, ScriptObject.GLOBALFILTER), null);
+ }
+
+- private SetMethod createNewPropertySetter() {
+- final SetMethod sm = map.getFieldCount() < map.getFieldMaximum() ? createNewFieldSetter() : createNewSpillPropertySetter();
++ private SetMethod createNewPropertySetter(final SwitchPoint builtinSwitchPoint) {
++ final SetMethod sm = map.getFreeFieldSlot() > -1 ? createNewFieldSetter(builtinSwitchPoint) : createNewSpillPropertySetter(builtinSwitchPoint);
+ final PropertyListeners listeners = map.getListeners();
+ if (listeners != null) {
+ listeners.propertyAdded(sm.property);
+@@ -161,38 +193,53 @@
+ return sm;
+ }
+
+- private SetMethod createNewFieldSetter() {
+- final PropertyMap oldMap = getMap();
+- final Property property = new AccessorProperty(getName(), 0, sobj.getClass(), oldMap.getFieldCount());
+- final PropertyMap newMap = oldMap.addProperty(property);
+- MethodHandle setter = MH.insertArguments(ScriptObject.SETFIELD, 0, desc, oldMap, newMap, property.getSetter(Object.class, newMap));
++ private SetMethod createNewSetter(final Property property, final SwitchPoint builtinSwitchPoint) {
++ property.setBuiltinSwitchPoint(builtinSwitchPoint);
+
+- return new SetMethod(MH.asType(setter, Lookup.SET_OBJECT_TYPE), property);
++ final PropertyMap oldMap = getMap();
++ final PropertyMap newMap = getNewMap(property);
++ final boolean isStrict = NashornCallSiteDescriptor.isStrict(desc);
++ final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
++
++ //fast type specific setter
++ final MethodHandle fastSetter = property.getSetter(type, newMap); //0 sobj, 1 value, slot folded for spill property already
++
++ //slow setter, that calls ScriptObject.set with appropraite type and key name
++ MethodHandle slowSetter = ScriptObject.SET_SLOW[getAccessorTypeIndex(type)];
++ slowSetter = MH.insertArguments(slowSetter, 3, NashornCallSiteDescriptor.getFlags(desc));
++ slowSetter = MH.insertArguments(slowSetter, 1, name);
++ slowSetter = MH.asType(slowSetter, slowSetter.type().changeParameterType(0, Object.class));
++
++ assert slowSetter.type().equals(fastSetter.type()) : "slow=" + slowSetter + " != fast=" + fastSetter;
++
++ //cas map used as guard, if true that means we can do the set fast
++ MethodHandle casMap = MH.insertArguments(ScriptObject.CAS_MAP, 1, oldMap, newMap);
++ casMap = MH.dropArguments(casMap, 1, type);
++ casMap = MH.asType(casMap, casMap.type().changeParameterType(0, Object.class));
++ final MethodHandle casGuard = MH.guardWithTest(casMap, fastSetter, slowSetter);
++
++ //outermost level needs an extendable check. if object can be extended, guard is true and
++ //we can run the cas setter. The setter goes to "nop" VOID_RETURN if false or throws an
++ //exception if we are in strict mode and object is not extensible
++ MethodHandle extCheck = MH.insertArguments(ScriptObject.EXTENSION_CHECK, 1, isStrict, name);
++ extCheck = MH.asType(extCheck, extCheck.type().changeParameterType(0, Object.class));
++ extCheck = MH.dropArguments(extCheck, 1, type);
++
++ MethodHandle nop = JSType.VOID_RETURN.methodHandle();
++ nop = MH.dropArguments(nop, 0, Object.class, type);
++
++ return new SetMethod(MH.asType(MH.guardWithTest(extCheck, casGuard, nop), fastSetter.type()), property);
+ }
+
+- private SetMethod createNewSpillPropertySetter() {
+- final int nextSpill = getMap().getSpillLength();
+-
+- final Property property = new AccessorProperty(getName(), Property.IS_SPILL, nextSpill);
+- return new SetMethod(createSpillMethodHandle(nextSpill, property), property);
++ private SetMethod createNewFieldSetter(final SwitchPoint builtinSwitchPoint) {
++ return createNewSetter(new AccessorProperty(getName(), 0, sobj.getClass(), getMap().getFreeFieldSlot(), type), builtinSwitchPoint);
+ }
+
+- private MethodHandle createSpillMethodHandle(final int nextSpill, Property property) {
+- final PropertyMap oldMap = getMap();
+- final PropertyMap newMap = getNewMap(property);
+-
+- final Object[] spill = sobj.spill;
+- if (spill == null) {
+- return MH.insertArguments(ScriptObject.SETSPILLWITHNEW, 0, desc, oldMap, newMap, nextSpill);
+- } else if (nextSpill < spill.length) {
+- return MH.insertArguments(ScriptObject.SETSPILL, 0, desc, oldMap, newMap, nextSpill);
+- } else {
+- final int newLength = (nextSpill + ScriptObject.SPILL_RATE) / ScriptObject.SPILL_RATE * ScriptObject.SPILL_RATE;
+- return MH.insertArguments(ScriptObject.SETSPILLWITHGROW, 0, desc, oldMap, newMap, nextSpill, newLength);
+- }
++ private SetMethod createNewSpillPropertySetter(final SwitchPoint builtinSwitchPoint) {
++ return createNewSetter(new SpillProperty(getName(), 0, getMap().getFreeSpillSlot(), type), builtinSwitchPoint);
+ }
+
+- private PropertyMap getNewMap(Property property) {
++ private PropertyMap getNewMap(final Property property) {
+ return getMap().addProperty(property);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/Source.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/Source.java Wed Feb 04 12:14:47 2015 -0800
+@@ -45,20 +45,25 @@
+ import java.security.MessageDigest;
+ import java.security.NoSuchAlgorithmException;
+ import java.util.Arrays;
++import java.util.Base64;
+ import java.util.Objects;
+ import java.util.WeakHashMap;
+ import jdk.nashorn.api.scripting.URLReader;
+ import jdk.nashorn.internal.parser.Token;
+-
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
+ /**
+ * Source objects track the origin of JavaScript entities.
+ */
+-public final class Source {
+-
+- private static final DebugLogger DEBUG = new DebugLogger("source");
++@Logger(name="source")
++public final class Source implements Loggable {
+ private static final int BUF_SIZE = 8 * 1024;
+ private static final Cache CACHE = new Cache();
+
++ // Message digest to file name encoder
++ private final static Base64.Encoder BASE64 = Base64.getUrlEncoder().withoutPadding();
++
+ /**
+ * Descriptive name of the source as supplied by the user. Used for error
+ * reporting to the user. For example, SyntaxError will use this to print message.
+@@ -79,8 +84,11 @@
+ /** Cached hash code */
+ private int hash;
+
+- /** Message digest */
+- private byte[] digest;
++ /** Base64-encoded SHA1 digest of this source object */
++ private volatile byte[] digest;
++
++ /** source URL set via //@ sourceURL or //# sourceURL directive */
++ private String explicitURL;
+
+ // Do *not* make this public, ever! Trusts the URL and content.
+ private Source(final String name, final String base, final Data data) {
+@@ -97,13 +105,14 @@
+ // Force any access errors
+ data.checkPermissionAndClose();
+ return existingSource;
+- } else {
+- // All sources in cache must be fully loaded
+- data.load();
+- CACHE.put(newSource, newSource);
+- return newSource;
+ }
+- } catch (RuntimeException e) {
++
++ // All sources in cache must be fully loaded
++ data.load();
++ CACHE.put(newSource, newSource);
++
++ return newSource;
++ } catch (final RuntimeException e) {
+ final Throwable cause = e.getCause();
+ if (cause instanceof IOException) {
+ throw (IOException) cause;
+@@ -139,40 +148,46 @@
+ long lastModified();
+
+ char[] array();
++
++ boolean isEvalCode();
+ }
+
+ private static class RawData implements Data {
+ private final char[] array;
++ private final boolean evalCode;
+ private int hash;
+
+- private RawData(final char[] array) {
++ private RawData(final char[] array, final boolean evalCode) {
+ this.array = Objects.requireNonNull(array);
++ this.evalCode = evalCode;
+ }
+
+- private RawData(final String source) {
++ private RawData(final String source, final boolean evalCode) {
+ this.array = Objects.requireNonNull(source).toCharArray();
++ this.evalCode = evalCode;
+ }
+
+ private RawData(final Reader reader) throws IOException {
+- this(readFully(reader));
++ this(readFully(reader), false);
+ }
+
+ @Override
+ public int hashCode() {
+ int h = hash;
+ if (h == 0) {
+- h = hash = Arrays.hashCode(array);
++ h = hash = Arrays.hashCode(array) ^ (evalCode? 1 : 0);
+ }
+ return h;
+ }
+
+ @Override
+- public boolean equals(Object obj) {
++ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof RawData) {
+- return Arrays.equals(array, ((RawData)obj).array);
++ final RawData other = (RawData)obj;
++ return Arrays.equals(array, other.array) && evalCode == other.evalCode;
+ }
+ return false;
+ }
+@@ -203,6 +218,10 @@
+ }
+
+
++ @Override
++ public boolean isEvalCode() {
++ return evalCode;
++ }
+ }
+
+ private static class URLData implements Data {
+@@ -228,7 +247,7 @@
+ }
+
+ @Override
+- public boolean equals(Object other) {
++ public boolean equals(final Object other) {
+ if (this == other) {
+ return true;
+ }
+@@ -236,7 +255,7 @@
+ return false;
+ }
+
+- URLData otherData = (URLData) other;
++ final URLData otherData = (URLData) other;
+
+ if (url.equals(otherData.url)) {
+ // Make sure both have meta data loaded
+@@ -248,7 +267,7 @@
+ } else if (otherData.isDeferred()) {
+ otherData.loadMeta();
+ }
+- } catch (IOException e) {
++ } catch (final IOException e) {
+ throw new RuntimeException(e);
+ }
+
+@@ -284,12 +303,20 @@
+ return array;
+ }
+
++ @Override
++ public boolean isEvalCode() {
++ return false;
++ }
++
+ boolean isDeferred() {
+ return array == null;
+ }
+
++ @SuppressWarnings("try")
+ protected void checkPermissionAndClose() throws IOException {
+- try (InputStream in = url.openStream()) {}
++ try (InputStream in = url.openStream()) {
++ // empty
++ }
+ debug("permission checked for ", url);
+ }
+
+@@ -353,7 +380,10 @@
+ }
+
+ private static void debug(final Object... msg) {
+- DEBUG.info(msg);
++ final DebugLogger logger = getLoggerStatic();
++ if (logger != null) {
++ logger.info(msg);
++ }
+ }
+
+ private char[] data() {
+@@ -361,23 +391,50 @@
+ }
+
+ /**
+- * Returns an instance
++ * Returns a Source instance
+ *
+ * @param name source name
+ * @param content contents as char array
++ * @param isEval does this represent code from 'eval' call?
++ * @return source instance
+ */
+- public static Source sourceFor(final String name, final char[] content) {
+- return new Source(name, baseName(name), new RawData(content));
++ public static Source sourceFor(final String name, final char[] content, final boolean isEval) {
++ return new Source(name, baseName(name), new RawData(content, isEval));
+ }
+
+ /**
+- * Returns an instance
++ * Returns a Source instance
++ *
++ * @param name source name
++ * @param content contents as char array
++ *
++ * @return source instance
++ */
++ public static Source sourceFor(final String name, final char[] content) {
++ return sourceFor(name, content, false);
++ }
++
++ /**
++ * Returns a Source instance
+ *
+ * @param name source name
+ * @param content contents as string
++ * @param isEval does this represent code from 'eval' call?
++ * @return source instance
++ */
++ public static Source sourceFor(final String name, final String content, final boolean isEval) {
++ return new Source(name, baseName(name), new RawData(content, isEval));
++ }
++
++ /**
++ * Returns a Source instance
++ *
++ * @param name source name
++ * @param content contents as string
++ * @return source instance
+ */
+ public static Source sourceFor(final String name, final String content) {
+- return new Source(name, baseName(name), new RawData(content));
++ return sourceFor(name, content, false);
+ }
+
+ /**
+@@ -386,6 +443,8 @@
+ * @param name source name
+ * @param url url from which source can be loaded
+ *
++ * @return source instance
++ *
+ * @throws IOException if source cannot be loaded
+ */
+ public static Source sourceFor(final String name, final URL url) throws IOException {
+@@ -399,6 +458,8 @@
+ * @param url url from which source can be loaded
+ * @param cs Charset used to convert bytes to chars
+ *
++ * @return source instance
++ *
+ * @throws IOException if source cannot be loaded
+ */
+ public static Source sourceFor(final String name, final URL url, final Charset cs) throws IOException {
+@@ -411,6 +472,8 @@
+ * @param name source name
+ * @param file file from which source can be loaded
+ *
++ * @return source instance
++ *
+ * @throws IOException if source cannot be loaded
+ */
+ public static Source sourceFor(final String name, final File file) throws IOException {
+@@ -424,6 +487,8 @@
+ * @param file file from which source can be loaded
+ * @param cs Charset used to convert bytes to chars
+ *
++ * @return source instance
++ *
+ * @throws IOException if source cannot be loaded
+ */
+ public static Source sourceFor(final String name, final File file, final Charset cs) throws IOException {
+@@ -436,6 +501,9 @@
+ *
+ * @param name source name
+ * @param reader reader from which source can be loaded
++ *
++ * @return source instance
++ *
+ * @throws IOException if source cannot be loaded
+ */
+ public static Source sourceFor(final String name, final Reader reader) throws IOException {
+@@ -532,14 +600,39 @@
+ }
+
+ /**
++ * Get explicit source URL.
++ * @return URL set vial sourceURL directive
++ */
++ public String getExplicitURL() {
++ return explicitURL;
++ }
++
++ /**
++ * Set explicit source URL.
++ * @param explicitURL URL set via sourceURL directive
++ */
++ public void setExplicitURL(final String explicitURL) {
++ this.explicitURL = explicitURL;
++ }
++
++ /**
++ * Returns whether this source was submitted via 'eval' call or not.
++ *
++ * @return true if this source represents code submitted via 'eval'
++ */
++ public boolean isEvalCode() {
++ return data.isEvalCode();
++ }
++
++ /**
+ * Find the beginning of the line containing position.
+ * @param position Index to offending token.
+ * @return Index of first character of line.
+ */
+ private int findBOLN(final int position) {
+- final char[] data = data();
++ final char[] d = data();
+ for (int i = position - 1; i > 0; i--) {
+- final char ch = data[i];
++ final char ch = d[i];
+
+ if (ch == '\n' || ch == '\r') {
+ return i + 1;
+@@ -555,10 +648,10 @@
+ * @return Index of last character of line.
+ */
+ private int findEOLN(final int position) {
+- final char[] data = data();
+- final int length = data.length;
++ final char[] d = data();
++ final int length = d.length;
+ for (int i = position; i < length; i++) {
+- final char ch = data[i];
++ final char ch = d[i];
+
+ if (ch == '\n' || ch == '\r') {
+ return i - 1;
+@@ -578,12 +671,12 @@
+ * @return Line number.
+ */
+ public int getLine(final int position) {
+- final char[] data = data();
++ final char[] d = data();
+ // Line count starts at 1.
+ int line = 1;
+
+ for (int i = 0; i < position; i++) {
+- final char ch = data[i];
++ final char ch = d[i];
+ // Works for both \n and \r\n.
+ if (ch == '\n') {
+ line++;
+@@ -618,11 +711,16 @@
+ }
+
+ /**
+- * Get the content of this source as a char array
+- * @return content
++ * Get the content of this source as a char array. Note that the underlying array is returned instead of a
++ * clone; modifying the char array will cause modification to the source; this should not be done. While
++ * there is an apparent danger that we allow unfettered access to an underlying mutable array, the
++ * {@code Source} class is in a restricted {@code jdk.nashorn.internal.*} package and as such it is
++ * inaccessible by external actors in an environment with a security manager. Returning a clone would be
++ * detrimental to performance.
++ * @return content the content of this source as a char array
+ */
+ public char[] getContent() {
+- return data().clone();
++ return data();
+ }
+
+ /**
+@@ -711,12 +809,17 @@
+ }
+
+ /**
+- * Get a message digest for this source.
++ * Get a Base64-encoded SHA1 digest for this source.
+ *
+- * @return a message digest for this source
++ * @return a Base64-encoded SHA1 digest for this source
+ */
+- public synchronized byte[] getDigest() {
+- if (digest == null) {
++ public String getDigest() {
++ return new String(getDigestBytes(), StandardCharsets.US_ASCII);
++ }
++
++ private byte[] getDigestBytes() {
++ byte[] ldigest = digest;
++ if (ldigest == null) {
+ final char[] content = data();
+ final byte[] bytes = new byte[content.length * 2];
+
+@@ -736,12 +839,12 @@
+ if (getURL() != null) {
+ md.update(getURL().toString().getBytes(StandardCharsets.UTF_8));
+ }
+- digest = md.digest(bytes);
+- } catch (NoSuchAlgorithmException e) {
++ digest = ldigest = BASE64.encode(md.digest(bytes));
++ } catch (final NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ }
+- return digest;
++ return ldigest;
+ }
+
+ /**
+@@ -847,4 +950,19 @@
+ return null;
+ }
+ }
++
++ private static DebugLogger getLoggerStatic() {
++ final Context context = Context.getContextTrustedOrNull();
++ return context == null ? null : context.getLogger(Source.class);
++ }
++
++ @Override
++ public DebugLogger initLogger(final Context context) {
++ return context.getLogger(this.getClass());
++ }
++
++ @Override
++ public DebugLogger getLogger() {
++ return initLogger(Context.getContextTrusted());
++ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/Specialization.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,114 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
++
++import java.lang.invoke.MethodHandle;
++import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
++import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
++
++/**
++ * Specialization info for a {@link SpecializedFunction}
++ */
++public final class Specialization {
++ private final MethodHandle mh;
++ private final Class<? extends LinkLogic> linkLogicClass;
++ private final boolean isOptimistic;
++
++ /**
++ * Constructor
++ *
++ * @param mh invoker method handler
++ */
++ public Specialization(final MethodHandle mh) {
++ this(mh, false);
++ }
++
++ /**
++ * Constructor
++ *
++ * @param mh invoker method handler
++ * @param isOptimistic is this an optimistic native method, i.e. can it throw {@link UnwarrantedOptimismException}
++ * which would have to lead to a relink and return value processing
++ */
++ public Specialization(final MethodHandle mh, final boolean isOptimistic) {
++ this(mh, null, isOptimistic);
++ }
++
++ /**
++ * Constructor
++ *
++ * @param mh invoker method handler
++ * @param linkLogicClass extra link logic needed for this function. Instances of this class also contains logic for checking
++ * if this can be linked on its first encounter, which is needed as per our standard linker semantics
++ * @param isOptimistic is this an optimistic native method, i.e. can it throw {@link UnwarrantedOptimismException}
++ * which would have to lead to a relink and return value processing
++ */
++ public Specialization(final MethodHandle mh, final Class<? extends LinkLogic> linkLogicClass, final boolean isOptimistic) {
++ this.mh = mh;
++ this.isOptimistic = isOptimistic;
++ if (linkLogicClass != null) {
++ //null out the "empty" link logic class for optimization purposes
++ //we only use the empty instance because we can't default class annotations
++ //to null
++ this.linkLogicClass = LinkLogic.isEmpty(linkLogicClass) ? null : linkLogicClass;
++ } else {
++ this.linkLogicClass = null;
++ }
++ }
++
++ /**
++ * Get the method handle for the invoker of this ScriptFunction
++ * @return the method handle
++ */
++ public MethodHandle getMethodHandle() {
++ return mh;
++ }
++
++ /**
++ * Get the link logic class for this ScriptFunction
++ * @return link logic class info, i.e. one whose instance contains stuff like
++ * "do we need exception check for every call", and logic to check if we may link
++ */
++ public Class<? extends LinkLogic> getLinkLogicClass() {
++ return linkLogicClass;
++ }
++
++ /**
++ * An optimistic specialization is one that can throw UnwarrantedOptimismException.
++ * This is allowed for native methods, as long as they are functional, i.e. don't change
++ * any state between entering and throwing the UOE. Then we can re-execute a wider version
++ * of the method in the continuation. Rest-of method generation for optimistic builtins is
++ * of course not possible, but this approach works and fits into the same relinking
++ * framework
++ *
++ * @return true if optimistic
++ */
++ public boolean isOptimistic() {
++ return isOptimistic;
++ }
++
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/SpillProperty.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,217 @@
++/*
++ * Copyright (c) 2010-2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
++
++import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
++import static jdk.nashorn.internal.lookup.Lookup.MH;
++
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++
++/**
++ * Spill property
++ */
++public class SpillProperty extends AccessorProperty {
++ private static final long serialVersionUID = 3028496245198669460L;
++
++ private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
++
++ private static final MethodHandle PARRAY_GETTER = MH.asType(MH.getter(LOOKUP, ScriptObject.class, "primitiveSpill", long[].class), MH.type(long[].class, Object.class));
++ private static final MethodHandle OARRAY_GETTER = MH.asType(MH.getter(LOOKUP, ScriptObject.class, "objectSpill", Object[].class), MH.type(Object[].class, Object.class));
++
++ private static final MethodHandle OBJECT_GETTER = MH.filterArguments(MH.arrayElementGetter(Object[].class), 0, OARRAY_GETTER);
++ private static final MethodHandle PRIMITIVE_GETTER = MH.filterArguments(MH.arrayElementGetter(long[].class), 0, PARRAY_GETTER);
++ private static final MethodHandle OBJECT_SETTER = MH.filterArguments(MH.arrayElementSetter(Object[].class), 0, OARRAY_GETTER);
++ private static final MethodHandle PRIMITIVE_SETTER = MH.filterArguments(MH.arrayElementSetter(long[].class), 0, PARRAY_GETTER);
++
++ private static class Accessors {
++ private MethodHandle objectGetter;
++ private MethodHandle objectSetter;
++ private MethodHandle primitiveGetter;
++ private MethodHandle primitiveSetter;
++
++ private final int slot;
++ private final MethodHandle ensureSpillSize;
++
++ private static Accessors ACCESSOR_CACHE[] = new Accessors[512];
++
++ //private static final Map<Integer, Reference<Accessors>> ACCESSOR_CACHE = Collections.synchronizedMap(new WeakHashMap<Integer, Reference<Accessors>>());
++
++ Accessors(final int slot) {
++ assert slot >= 0;
++ this.slot = slot;
++ this.ensureSpillSize = MH.asType(MH.insertArguments(ScriptObject.ENSURE_SPILL_SIZE, 1, slot), MH.type(Object.class, Object.class));
++ }
++
++ private static void ensure(final int slot) {
++ int len = ACCESSOR_CACHE.length;
++ if (slot >= len) {
++ do {
++ len *= 2;
++ } while (slot >= len);
++ final Accessors newCache[] = new Accessors[len];
++ System.arraycopy(ACCESSOR_CACHE, 0, newCache, 0, ACCESSOR_CACHE.length);
++ ACCESSOR_CACHE = newCache;
++ }
++ }
++
++ static MethodHandle getCached(final int slot, final boolean isPrimitive, final boolean isGetter) {
++ //Reference<Accessors> ref = ACCESSOR_CACHE.get(slot);
++ ensure(slot);
++ Accessors acc = ACCESSOR_CACHE[slot];
++ if (acc == null) {
++ acc = new Accessors(slot);
++ ACCESSOR_CACHE[slot] = acc;
++ }
++
++ return acc.getOrCreate(isPrimitive, isGetter);
++ }
++
++ private static MethodHandle primordial(final boolean isPrimitive, final boolean isGetter) {
++ if (isPrimitive) {
++ return isGetter ? PRIMITIVE_GETTER : PRIMITIVE_SETTER;
++ }
++ return isGetter ? OBJECT_GETTER : OBJECT_SETTER;
++ }
++
++ MethodHandle getOrCreate(final boolean isPrimitive, final boolean isGetter) {
++ MethodHandle accessor;
++
++ accessor = getInner(isPrimitive, isGetter);
++ if (accessor != null) {
++ return accessor;
++ }
++
++ accessor = primordial(isPrimitive, isGetter);
++ accessor = MH.insertArguments(accessor, 1, slot);
++ if (!isGetter) {
++ accessor = MH.filterArguments(accessor, 0, ensureSpillSize);
++ }
++ setInner(isPrimitive, isGetter, accessor);
++
++ return accessor;
++ }
++
++ void setInner(final boolean isPrimitive, final boolean isGetter, final MethodHandle mh) {
++ if (isPrimitive) {
++ if (isGetter) {
++ primitiveGetter = mh;
++ } else {
++ primitiveSetter = mh;
++ }
++ } else {
++ if (isGetter) {
++ objectGetter = mh;
++ } else {
++ objectSetter = mh;
++ }
++ }
++ }
++
++ MethodHandle getInner(final boolean isPrimitive, final boolean isGetter) {
++ if (isPrimitive) {
++ return isGetter ? primitiveGetter : primitiveSetter;
++ }
++ return isGetter ? objectGetter : objectSetter;
++ }
++ }
++
++ private static MethodHandle primitiveGetter(final int slot) {
++ return OBJECT_FIELDS_ONLY ? null : Accessors.getCached(slot, true, true);
++ }
++ private static MethodHandle primitiveSetter(final int slot) {
++ return OBJECT_FIELDS_ONLY ? null : Accessors.getCached(slot, true, false);
++ }
++ private static MethodHandle objectGetter(final int slot) {
++ return Accessors.getCached(slot, false, true);
++ }
++ private static MethodHandle objectSetter(final int slot) {
++ return Accessors.getCached(slot, false, false);
++ }
++
++ /**
++ * Constructor for spill properties. Array getters and setters will be created on demand.
++ *
++ * @param key the property key
++ * @param flags the property flags
++ * @param slot spill slot
++ */
++ public SpillProperty(final String key, final int flags, final int slot) {
++ super(key, flags, slot, primitiveGetter(slot), primitiveSetter(slot), objectGetter(slot), objectSetter(slot));
++ assert !OBJECT_FIELDS_ONLY || getLocalType() == Object.class;
++ }
++
++ SpillProperty(final String key, final int flags, final int slot, final Class<?> initialType) {
++ this(key, flags, slot);
++ setType(OBJECT_FIELDS_ONLY ? Object.class : initialType);
++ }
++
++ SpillProperty(final String key, final int flags, final int slot, final ScriptObject owner, final Object initialValue) {
++ this(key, flags, slot);
++ setInitialValue(owner, initialValue);
++ }
++
++ /**
++ * Copy constructor
++ * @param property other property
++ */
++ protected SpillProperty(final SpillProperty property) {
++ super(property);
++ }
++
++ /**
++ * Copy constructor
++ * @param newType new type
++ * @param property other property
++ */
++ protected SpillProperty(final SpillProperty property, final Class<?> newType) {
++ super(property, newType);
++ }
++
++ @Override
++ public Property copy() {
++ return new SpillProperty(this);
++ }
++
++ @Override
++ public Property copy(final Class<?> newType) {
++ return new SpillProperty(this, newType);
++ }
++
++ @Override
++ public boolean isSpill() {
++ return true;
++ }
++
++ @Override
++ void initMethodHandles(final Class<?> structure) {
++ final int slot = getSlot();
++ primitiveGetter = primitiveGetter(slot);
++ primitiveSetter = primitiveSetter(slot);
++ objectGetter = objectGetter(slot);
++ objectSetter = objectSetter(slot);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/StoredScript.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,142 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
++
++import java.io.Serializable;
++import java.util.Arrays;
++import java.util.LinkedHashMap;
++import java.util.Map;
++
++/**
++ * Class representing a persistent compiled script.
++ */
++public final class StoredScript implements Serializable {
++
++ /** Compilation id */
++ private final int compilationId;
++
++ /** Main class name. */
++ private final String mainClassName;
++
++ /** Map of class names to class bytes. */
++ private final Map<String, byte[]> classBytes;
++
++ /** Constants array. */
++ private final Object[] constants;
++
++ /** Function initializers */
++ private final Map<Integer, FunctionInitializer> initializers;
++
++ private static final long serialVersionUID = 2958227232195298340L;
++
++ /**
++ * Constructor.
++ *
++ * @param compilationId compilation id
++ * @param mainClassName main class name
++ * @param classBytes map of class names to class bytes
++ * @param initializers initializer map, id -> FunctionInitializer
++ * @param constants constants array
++ */
++ public StoredScript(final int compilationId, final String mainClassName, final Map<String, byte[]> classBytes, final Map<Integer, FunctionInitializer> initializers, final Object[] constants) {
++ this.compilationId = compilationId;
++ this.mainClassName = mainClassName;
++ this.classBytes = classBytes;
++ this.constants = constants;
++ this.initializers = initializers;
++ }
++
++ /**
++ * Get the compilation id for this StoredScript
++ * @return compilation id
++ */
++ public int getCompilationId() {
++ return compilationId;
++ }
++
++ /**
++ * Returns the main class name.
++ * @return the main class name
++ */
++ public String getMainClassName() {
++ return mainClassName;
++ }
++
++ /**
++ * Returns a map of class names to class bytes.
++ * @return map of class bytes
++ */
++ public Map<String, byte[]> getClassBytes() {
++ final Map<String, byte[]> clonedMap = new LinkedHashMap<>();
++ for (final Map.Entry<String, byte[]> entry : classBytes.entrySet()) {
++ clonedMap.put(entry.getKey(), entry.getValue().clone());
++ }
++ return clonedMap;
++ }
++
++ /**
++ * Returns the constants array.
++ * @return constants array
++ */
++ public Object[] getConstants() {
++ return constants.clone();
++ }
++
++ /**
++ * Returns the function initializers map.
++ * @return The initializers map.
++ */
++ public Map<Integer, FunctionInitializer> getInitializers() {
++ final Map<Integer, FunctionInitializer> clonedMap = new LinkedHashMap<>();
++ for (final Map.Entry<Integer, FunctionInitializer> entry : initializers.entrySet()) {
++ clonedMap.put(entry.getKey(), new FunctionInitializer(entry.getValue()));
++ }
++ return clonedMap;
++ }
++
++ @Override
++ public int hashCode() {
++ int hash = mainClassName.hashCode();
++ hash = 31 * hash + classBytes.hashCode();
++ hash = 31 * hash + Arrays.hashCode(constants);
++ return hash;
++ }
++
++ @Override
++ public boolean equals(final Object obj) {
++ if (obj == this) {
++ return true;
++ }
++ if (!(obj instanceof StoredScript)) {
++ return false;
++ }
++
++ final StoredScript cs = (StoredScript) obj;
++ return mainClassName.equals(cs.mainClassName)
++ && classBytes.equals(cs.classBytes)
++ && Arrays.equals(constants, cs.constants);
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/Timing.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/Timing.java Wed Feb 04 12:14:47 2015 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,69 +24,69 @@
+ */
+ package jdk.nashorn.internal.runtime;
+
++import java.io.BufferedReader;
++import java.io.IOException;
++import java.io.StringReader;
++import java.util.ArrayList;
+ import java.util.LinkedHashMap;
++import java.util.List;
+ import java.util.Map;
++import java.util.concurrent.TimeUnit;
++import java.util.function.Supplier;
+
+-import jdk.nashorn.internal.runtime.options.Options;
++import jdk.nashorn.internal.codegen.CompileUnit;
++import jdk.nashorn.internal.runtime.logging.DebugLogger;
++import jdk.nashorn.internal.runtime.logging.Loggable;
++import jdk.nashorn.internal.runtime.logging.Logger;
+
+ /**
+ * Simple wallclock timing framework
+ */
+-public final class Timing {
+- private static final boolean ENABLED = Options.getBooleanProperty("nashorn.time");
+- private static final Map<String, Long> TIMINGS;
+- private static final long START_TIME;
++@Logger(name="time")
++public final class Timing implements Loggable {
+
+- static {
+- if (ENABLED) {
+- TIMINGS = new LinkedHashMap<>();
+- START_TIME = System.currentTimeMillis();
+- Runtime.getRuntime().addShutdownHook(new Thread() {
+- @Override
+- public void run() {
+- final long t = System.currentTimeMillis();
+- long knownTime = 0L;
+- int maxLength = 0;
++ private DebugLogger log;
++ private TimeSupplier timeSupplier;
++ private final boolean isEnabled;
++ private final long startTime;
+
+- for (final Map.Entry<String, Long> entry : TIMINGS.entrySet()) {
+- maxLength = Math.max(maxLength, entry.getKey().length());
+- }
+- maxLength++;
++ private static final String LOGGER_NAME = Timing.class.getAnnotation(Logger.class).name();
+
+- for (final Map.Entry<String, Long> entry : TIMINGS.entrySet()) {
+- final StringBuilder sb = new StringBuilder();
+-
+- sb.append(entry.getKey());
+- while (sb.length() < maxLength) {
+- sb.append(' ');
+- }
+-
+- final long duration = entry.getValue();
+- sb.append(duration);
+- sb.append(' ');
+- sb.append(" ms");
+-
+- knownTime += duration;
+-
+- System.err.println(sb.toString()); //Context err is gone by shutdown TODO
+- }
+-
+- final long total = t - START_TIME;
+- System.err.println("Total runtime: " + total + " ms (Non-runtime: " + knownTime + " ms [" + (int)(knownTime * 100.0 / total) + "%])");
+- }
+- });
+- } else {
+- TIMINGS = null;
+- START_TIME = 0L;
+- }
++ /**
++ * Instantiate singleton timer for ScriptEnvironment
++ * @param isEnabled true if enabled, otherwise we keep the instance around
++ * for code brevity and "isEnabled" checks, but never instantiate anything
++ * inside it
++ */
++ public Timing(final boolean isEnabled) {
++ this.isEnabled = isEnabled;
++ this.startTime = System.nanoTime();
+ }
+
+ /**
+- * Check if timing is inabled
++ * Get the log info accumulated by this Timing instance
++ * @return log info as one string
++ */
++ public String getLogInfo() {
++ assert isEnabled();
++ return timeSupplier.get();
++ }
++
++ /**
++ * Get the log info accumulated by this Timing instance
++ * @return log info as and array of strings, one per line
++ */
++ public String[] getLogInfoLines() {
++ assert isEnabled();
++ return timeSupplier.getStrings();
++ }
++
++ /**
++ * Check if timing is enabled
+ * @return true if timing is enabled
+ */
+- public static boolean isEnabled() {
+- return ENABLED;
++ boolean isEnabled() {
++ return isEnabled;
+ }
+
+ /**
+@@ -94,16 +94,150 @@
+ * or add to its accumulated time
+ *
+ * @param module module name
+- * @param duration duration to add to accumulated time for module
++ * @param durationNano duration to add to accumulated time for module, in nanoseconds.
+ */
+- public static void accumulateTime(final String module, final long duration) {
+- if (Timing.isEnabled()) {
+- Long accumulatedTime = TIMINGS.get(module);
++ public void accumulateTime(final String module, final long durationNano) {
++ if (isEnabled()) {
++ ensureInitialized(Context.getContextTrusted());
++ timeSupplier.accumulateTime(module, durationNano);
++ }
++ }
++
++ private DebugLogger ensureInitialized(final Context context) {
++ //lazy init, as there is not necessarily a context available when
++ //a ScriptEnvironment gets initialize
++ if (isEnabled() && log == null) {
++ log = initLogger(context);
++ if (log.isEnabled()) {
++ this.timeSupplier = new TimeSupplier();
++ Runtime.getRuntime().addShutdownHook(
++ new Thread() {
++ @Override
++ public void run() {
++ //System.err.println because the context and the output streams may be gone
++ //when the shutdown hook executes
++ final StringBuilder sb = new StringBuilder();
++ for (final String str : timeSupplier.getStrings()) {
++ sb.append('[').
++ append(Timing.getLoggerName()).
++ append("] ").
++ append(str).
++ append('\n');
++ }
++ System.err.print(sb);
++ }
++ });
++ }
++ }
++ return log;
++ }
++
++ static String getLoggerName() {
++ return LOGGER_NAME;
++ }
++
++ @Override
++ public DebugLogger initLogger(final Context context) {
++ return context.getLogger(this.getClass());
++ }
++
++ @Override
++ public DebugLogger getLogger() {
++ return log;
++ }
++
++ /**
++ * Takes a duration in nanoseconds, and returns a string representation of it rounded to milliseconds.
++ * @param durationNano duration in nanoseconds
++ * @return the string representing the duration in milliseconds.
++ */
++ public static String toMillisPrint(final long durationNano) {
++ return Long.toString(TimeUnit.NANOSECONDS.toMillis(durationNano));
++ }
++
++ final class TimeSupplier implements Supplier<String> {
++ private final Map<String, Long> timings;
++
++ TimeSupplier() {
++ timings = new LinkedHashMap<>();
++ }
++
++ String[] getStrings() {
++ final List<String> strs = new ArrayList<>();
++ final BufferedReader br = new BufferedReader(new StringReader(get()));
++ String line;
++ try {
++ while ((line = br.readLine()) != null) {
++ strs.add(line);
++ }
++ } catch (final IOException e) {
++ throw new RuntimeException(e);
++ }
++ return strs.toArray(new String[strs.size()]);
++ }
++
++ @Override
++ public String get() {
++ final long t = System.nanoTime();
++
++ long knownTime = 0L;
++ int maxKeyLength = 0;
++ int maxValueLength = 0;
++
++ for (final Map.Entry<String, Long> entry : timings.entrySet()) {
++ maxKeyLength = Math.max(maxKeyLength, entry.getKey().length());
++ maxValueLength = Math.max(maxValueLength, toMillisPrint(entry.getValue()).length());
++ }
++ maxKeyLength++;
++
++ final StringBuilder sb = new StringBuilder();
++ sb.append("Accumulated compilation phase timings:\n\n");
++ for (final Map.Entry<String, Long> entry : timings.entrySet()) {
++ int len;
++
++ len = sb.length();
++ sb.append(entry.getKey());
++ len = sb.length() - len;
++
++ while (len++ < maxKeyLength) {
++ sb.append(' ');
++ }
++
++ final Long duration = entry.getValue();
++ final String strDuration = toMillisPrint(duration);
++ len = strDuration.length();
++ for (int i = 0; i < maxValueLength - len; i++) {
++ sb.append(' ');
++ }
++
++ sb.append(strDuration).
++ append(" ms\n");
++
++ knownTime += duration;
++ }
++
++ final long total = t - startTime;
++ sb.append('\n');
++ sb.append("Total runtime: ").
++ append(toMillisPrint(total)).
++ append(" ms (Non-runtime: ").
++ append(toMillisPrint(knownTime)).
++ append(" ms [").
++ append((int)(knownTime * 100.0 / total)).
++ append("%])");
++
++ sb.append("\n\nEmitted compile units: ").
++ append(CompileUnit.getEmittedUnitCount());
++
++ return sb.toString();
++ }
++
++ private void accumulateTime(final String module, final long duration) {
++ Long accumulatedTime = timings.get(module);
+ if (accumulatedTime == null) {
+ accumulatedTime = 0L;
+ }
+- TIMINGS.put(module, accumulatedTime + duration);
++ timings.put(module, accumulatedTime + duration);
+ }
+ }
+-
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/Undefined.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/Undefined.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,16 +25,16 @@
+
+ package jdk.nashorn.internal.runtime;
+
++import static jdk.nashorn.internal.lookup.Lookup.MH;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+-import static jdk.nashorn.internal.lookup.Lookup.MH;
+
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+-import java.lang.invoke.MethodType;
+ import jdk.internal.dynalink.CallSiteDescriptor;
+ import jdk.internal.dynalink.linker.GuardedInvocation;
+ import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+ import jdk.internal.dynalink.support.Guards;
++import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+
+ /**
+ * Unique instance of this class is used to represent JavaScript undefined.
+@@ -110,13 +110,13 @@
+ if (desc.getNameTokenCount() < 3) {
+ return findGetIndexMethod(desc);
+ }
+- throw lookupTypeError("cant.read.property.of.undefined", desc);
++ return findGetMethod(desc);
+ case "setProp":
+ case "setElem":
+ if (desc.getNameTokenCount() < 3) {
+ return findSetIndexMethod(desc);
+ }
+- throw lookupTypeError("cant.set.property.of.undefined", desc);
++ return findSetMethod(desc);
+ default:
+ break;
+ }
+@@ -128,44 +128,23 @@
+ return typeError(msg, desc.getNameTokenCount() > 2 ? desc.getNameToken(2) : null);
+ }
+
+- /**
+- * Find the appropriate GETINDEX method for an invoke dynamic call.
+- * @param desc The invoke dynamic callsite descriptor
+- * @param args arguments
+- * @return GuardedInvocation to be invoked at call site.
+- */
+- private static GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc, final Object... args) {
+- final MethodType callType = desc.getMethodType();
+- final Class<?> returnClass = callType.returnType();
+- final Class<?> keyClass = callType.parameterType(1);
++ private static final MethodHandle GET_METHOD = findOwnMH("get", Object.class, Object.class);
++ private static final MethodHandle SET_METHOD = MH.insertArguments(findOwnMH("set", void.class, Object.class, Object.class, int.class), 3, NashornCallSiteDescriptor.CALLSITE_STRICT);
+
+- String name = "get";
+- if (returnClass.isPrimitive()) {
+- //turn e.g. get with a double into getDouble
+- final String returnTypeName = returnClass.getName();
+- name += Character.toUpperCase(returnTypeName.charAt(0)) + returnTypeName.substring(1, returnTypeName.length());
+- }
+- MethodHandle methodHandle = findOwnMH(name, returnClass, keyClass);
+- methodHandle = MH.asType(methodHandle, methodHandle.type().changeParameterType(0, Object.class));
+-
+- return new GuardedInvocation(methodHandle, UNDEFINED_GUARD);
++ private static GuardedInvocation findGetMethod(final CallSiteDescriptor desc) {
++ return new GuardedInvocation(MH.insertArguments(GET_METHOD, 1, desc.getNameToken(2)), UNDEFINED_GUARD).asType(desc);
+ }
+
+- /**
+- * Find the appropriate SETINDEX method for an invoke dynamic call.
+- * @param desc The invoke dynamic callsite descriptor
+- * @return GuardedInvocation to be invoked at call site.
+- */
++ private static GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc) {
++ return new GuardedInvocation(GET_METHOD, UNDEFINED_GUARD).asType(desc);
++ }
++
++ private static GuardedInvocation findSetMethod(final CallSiteDescriptor desc) {
++ return new GuardedInvocation(MH.insertArguments(SET_METHOD, 1, desc.getNameToken(2)), UNDEFINED_GUARD).asType(desc);
++ }
++
+ private static GuardedInvocation findSetIndexMethod(final CallSiteDescriptor desc) {
+- final MethodType callType = desc.getMethodType();
+- final Class<?> keyClass = callType.parameterType(1);
+- final Class<?> valueClass = callType.parameterType(2);
+-
+- MethodHandle methodHandle = findOwnMH("set", void.class, keyClass, valueClass, boolean.class);
+- methodHandle = MH.asType(methodHandle, methodHandle.type().changeParameterType(0, Object.class));
+- methodHandle = MH.insertArguments(methodHandle, 3, false);
+-
+- return new GuardedInvocation(methodHandle, UNDEFINED_GUARD);
++ return new GuardedInvocation(SET_METHOD, UNDEFINED_GUARD).asType(desc);
+ }
+
+ @Override
+@@ -174,7 +153,7 @@
+ }
+
+ @Override
+- public void set(final Object key, final Object value, final boolean strict) {
++ public void set(final Object key, final Object value, final int flags) {
+ throw typeError("cant.set.property.of.undefined", ScriptRuntime.safeToString(key));
+ }
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/UnwarrantedOptimismException.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,167 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
++
++import java.io.NotSerializableException;
++import java.io.ObjectInputStream;
++import java.io.ObjectOutputStream;
++import jdk.nashorn.internal.codegen.types.Type;
++
++/**
++ * This exception is thrown from an optimistic operation, e.g. an integer add,
++ * that was to optimistic for what really took place. Typically things like
++ * trying to get an array element that we want to be an int, and it was a double,
++ * and an int add that actually overflows and needs a double for the representation
++ */
++
++@SuppressWarnings("serial")
++public final class UnwarrantedOptimismException extends RuntimeException {
++ /** Denotes an invalid program point */
++ public static final int INVALID_PROGRAM_POINT = -1;
++
++ /** The value for the first ordinary program point */
++ public static final int FIRST_PROGRAM_POINT = 1;
++
++ private Object returnValue;
++ private final int programPoint;
++ private final Type returnType;
++
++ /**
++ * Constructor
++ * @param returnValue actual return value from the too narrow operation
++ * @param programPoint program point where unwarranted optimism was detected
++ */
++ public UnwarrantedOptimismException(final Object returnValue, final int programPoint) {
++ this(returnValue, programPoint, getReturnType(returnValue));
++ }
++
++ /**
++ * Check if a program point is valid
++ * @param programPoint the program point
++ * @return true if valid
++ */
++ public static boolean isValid(final int programPoint) {
++ assert programPoint >= INVALID_PROGRAM_POINT;
++ return programPoint != INVALID_PROGRAM_POINT;
++ }
++
++ private static Type getReturnType(final Object v) {
++ if (v instanceof Double) {
++ return Type.NUMBER;
++ } else if (v instanceof Long) {
++ return Type.LONG;
++ }
++ assert !(v instanceof Integer) : v + " is an int"; // Can't have an unwarranted optimism exception with int
++ return Type.OBJECT;
++ }
++
++ /**
++ * Constructor with explicit return value type.
++ * @param returnValue actual return value from the too narrow operation
++ * @param programPoint program point where unwarranted optimism was detected
++ * @param returnType type of the returned value. Used to disambiguate the return type. E.g. an {@code ObjectArrayData}
++ * might return a {@link Double} for a particular element getter, but still throw this exception even if the call
++ * site can accept a double, since the array's type is actually {@code Type#OBJECT}. In this case, it must
++ * explicitly use this constructor to indicate its values are to be considered {@code Type#OBJECT} and not
++ * {@code Type#NUMBER}.
++ */
++ public UnwarrantedOptimismException(final Object returnValue, final int programPoint, final Type returnType) {
++ super("", null, false, Context.DEBUG);
++ assert returnType != Type.OBJECT || returnValue == null || !Type.typeFor(returnValue.getClass()).isNumeric();
++ assert returnType != Type.INT;
++ this.returnValue = returnValue;
++ this.programPoint = programPoint;
++ this.returnType = returnType;
++ }
++
++ /**
++ * Get the return value. This is a destructive readout, after the method is invoked the return value is null'd out.
++ * @return return value
++ */
++ public Object getReturnValueDestructive() {
++ final Object retval = returnValue;
++ returnValue = null;
++ return retval;
++ }
++
++ Object getReturnValueNonDestructive() {
++ return returnValue;
++ }
++
++ /**
++ * Get the return type
++ * @return return type
++ */
++ public Type getReturnType() {
++ return returnType;
++ }
++
++ /**
++ * Does this exception refer to an invalid program point? This might be OK if
++ * we throw it, e.g. from a parameter guard
++ * @return true if invalid program point specified
++ */
++ public boolean hasInvalidProgramPoint() {
++ return programPoint == INVALID_PROGRAM_POINT;
++ }
++
++ /**
++ * Get the program point
++ * @return the program point
++ */
++ public int getProgramPoint() {
++ return programPoint;
++ }
++
++ /**
++ * Check if we ended up with a primitive return value (even though it may be
++ * too wide for what we tried to do, e.g. double instead of int)
++ * @return true if return value is primitive
++ */
++ public boolean hasPrimitiveReturnValue() {
++ return returnValue instanceof Number || returnValue instanceof Boolean;
++ }
++
++ @Override
++ public String getMessage() {
++ return "UNWARRANTED OPTIMISM: [returnValue=" +
++ returnValue +
++ " (class=" +
++ (returnValue == null ? "null" : returnValue.getClass().getSimpleName()) +
++ (hasInvalidProgramPoint() ?
++ " <invalid program point>" :
++ (" @ program point #" + programPoint)) +
++ ")]";
++ }
++
++
++ private void writeObject(final ObjectOutputStream out) throws NotSerializableException {
++ throw new NotSerializableException(getClass().getName());
++ }
++
++ private void readObject(final ObjectInputStream in) throws NotSerializableException {
++ throw new NotSerializableException(getClass().getName());
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,165 +25,214 @@
+
+ package jdk.nashorn.internal.runtime;
+
++import static jdk.nashorn.internal.lookup.Lookup.MH;
++import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
++import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
++import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_PROGRAM_POINT_SHIFT;
++
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+-import java.util.concurrent.Callable;
+-
+-import jdk.nashorn.internal.codegen.CompilerConstants;
++import java.lang.invoke.MethodType;
+ import jdk.nashorn.internal.lookup.Lookup;
+ import jdk.nashorn.internal.runtime.linker.Bootstrap;
+-
+-import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
+-import jdk.nashorn.internal.objects.Global;
+-import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+-import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
++import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+
+ /**
+ * Property with user defined getters/setters. Actual getter and setter
+ * functions are stored in underlying ScriptObject. Only the 'slot' info is
+ * stored in the property.
+- *
+- * The slots here denote either ScriptObject embed field number or spill
+- * array index. For spill array index, we use slot value of
+- * (index + ScriptObject.embedSize). See also ScriptObject.getEmbedOrSpill
+- * method. Negative slot value means that the corresponding getter or setter
+- * is null. Note that always two slots are allocated in ScriptObject - but
+- * negative (less by 1) slot number is stored for null getter or setter.
+- * This is done so that when the property is redefined with a different
+- * getter and setter (say, both non-null), we'll have spill slots to store
+- * those. When a slot is negative, (-slot - 1) is the embed/spill index.
+ */
+-public final class UserAccessorProperty extends Property {
++public final class UserAccessorProperty extends SpillProperty {
+
+- /** User defined getter function slot. */
+- private final int getterSlot;
++ private static final long serialVersionUID = -5928687246526840321L;
+
+- /** User defined setter function slot. */
+- private final int setterSlot;
++ static final class Accessors {
++ Object getter;
++ Object setter;
++
++ Accessors(final Object getter, final Object setter) {
++ set(getter, setter);
++ }
++
++ final void set(final Object getter, final Object setter) {
++ this.getter = getter;
++ this.setter = setter;
++ }
++
++ @Override
++ public String toString() {
++ return "[getter=" + getter + " setter=" + setter + ']';
++ }
++ }
++
++ private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+
+ /** Getter method handle */
+- private final static CompilerConstants.Call USER_ACCESSOR_GETTER = staticCall(MethodHandles.lookup(), UserAccessorProperty.class,
+- "userAccessorGetter", Object.class, ScriptObject.class, int.class, Object.class);
++ private final static MethodHandle INVOKE_OBJECT_GETTER = findOwnMH_S("invokeObjectGetter", Object.class, Accessors.class, MethodHandle.class, Object.class);
++ private final static MethodHandle INVOKE_INT_GETTER = findOwnMH_S("invokeIntGetter", int.class, Accessors.class, MethodHandle.class, int.class, Object.class);
++ private final static MethodHandle INVOKE_LONG_GETTER = findOwnMH_S("invokeLongGetter", long.class, Accessors.class, MethodHandle.class, int.class, Object.class);
++ private final static MethodHandle INVOKE_NUMBER_GETTER = findOwnMH_S("invokeNumberGetter", double.class, Accessors.class, MethodHandle.class, int.class, Object.class);
+
+ /** Setter method handle */
+- private final static CompilerConstants.Call USER_ACCESSOR_SETTER = staticCall(MethodHandles.lookup(), UserAccessorProperty.class,
+- "userAccessorSetter", void.class, ScriptObject.class, int.class, String.class, Object.class, Object.class);
++ private final static MethodHandle INVOKE_OBJECT_SETTER = findOwnMH_S("invokeObjectSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, Object.class);
++ private final static MethodHandle INVOKE_INT_SETTER = findOwnMH_S("invokeIntSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, int.class);
++ private final static MethodHandle INVOKE_LONG_SETTER = findOwnMH_S("invokeLongSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, long.class);
++ private final static MethodHandle INVOKE_NUMBER_SETTER = findOwnMH_S("invokeNumberSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, double.class);
+
+- /** Dynamic invoker for getter */
+- private static final Object INVOKE_UA_GETTER = new Object();
+
+- private static MethodHandle getINVOKE_UA_GETTER() {
+-
+- return Context.getGlobal().getDynamicInvoker(INVOKE_UA_GETTER,
+- new Callable<MethodHandle>() {
+- @Override
+- public MethodHandle call() {
+- return Bootstrap.createDynamicInvoker("dyn:call", Object.class,
+- Object.class, Object.class);
+- }
+- });
++ static MethodHandle getINVOKE_UA_GETTER(final Class<?> returnType, final int programPoint) {
++ if (UnwarrantedOptimismException.isValid(programPoint)) {
++ final int flags = NashornCallSiteDescriptor.CALLSITE_OPTIMISTIC | programPoint << CALLSITE_PROGRAM_POINT_SHIFT;
++ return Bootstrap.createDynamicInvoker("dyn:call", flags, returnType, Object.class, Object.class);
++ } else {
++ return Bootstrap.createDynamicInvoker("dyn:call", Object.class, Object.class, Object.class);
++ }
+ }
+
+- /** Dynamic invoker for setter */
+- private static Object INVOKE_UA_SETTER = new Object();
+- private static MethodHandle getINVOKE_UA_SETTER() {
+- return Context.getGlobal().getDynamicInvoker(INVOKE_UA_SETTER,
+- new Callable<MethodHandle>() {
+- @Override
+- public MethodHandle call() {
+- return Bootstrap.createDynamicInvoker("dyn:call", void.class,
+- Object.class, Object.class, Object.class);
+- }
+- });
++ static MethodHandle getINVOKE_UA_SETTER(final Class<?> valueType) {
++ return Bootstrap.createDynamicInvoker("dyn:call", void.class, Object.class, Object.class, valueType);
+ }
+
+ /**
+ * Constructor
+ *
+- * @param key property key
+- * @param flags property flags
+- * @param getterSlot getter slot, starting at first embed
+- * @param setterSlot setter slot, starting at first embed
++ * @param key property key
++ * @param flags property flags
++ * @param slot spill slot
+ */
+- UserAccessorProperty(final String key, final int flags, final int getterSlot, final int setterSlot) {
+- super(key, flags, -1);
+- this.getterSlot = getterSlot;
+- this.setterSlot = setterSlot;
++ UserAccessorProperty(final String key, final int flags, final int slot) {
++ super(key, flags, slot);
+ }
+
+ private UserAccessorProperty(final UserAccessorProperty property) {
+ super(property);
+- this.getterSlot = property.getterSlot;
+- this.setterSlot = property.setterSlot;
+ }
+
+- /**
+- * Return getter spill slot for this UserAccessorProperty.
+- * @return getter slot
+- */
+- public int getGetterSlot() {
+- return getterSlot;
+- }
+-
+- /**
+- * Return setter spill slot for this UserAccessorProperty.
+- * @return setter slot
+- */
+- public int getSetterSlot() {
+- return setterSlot;
++ private UserAccessorProperty(final UserAccessorProperty property, final Class<?> newType) {
++ super(property, newType);
+ }
+
+ @Override
+- protected Property copy() {
++ public Property copy() {
+ return new UserAccessorProperty(this);
+ }
+
+ @Override
+- public boolean equals(final Object other) {
+- if (!super.equals(other)) {
+- return false;
++ public Property copy(final Class<?> newType) {
++ return new UserAccessorProperty(this, newType);
++ }
++
++ void setAccessors(final ScriptObject sobj, final PropertyMap map, final Accessors gs) {
++ try {
++ //invoke the getter and find out
++ super.getSetter(Object.class, map).invokeExact((Object)sobj, (Object)gs);
++ } catch (final Error | RuntimeException t) {
++ throw t;
++ } catch (final Throwable t) {
++ throw new RuntimeException(t);
+ }
++ }
+
+- final UserAccessorProperty uc = (UserAccessorProperty) other;
+- return getterSlot == uc.getterSlot && setterSlot == uc.setterSlot;
++ //pick the getter setter out of the correct spill slot in sobj
++ Accessors getAccessors(final ScriptObject sobj) {
++ try {
++ //invoke the super getter with this spill slot
++ //get the getter setter from the correct spill slot
++ final Object gs = super.getGetter(Object.class).invokeExact((Object)sobj);
++ return (Accessors)gs;
++ } catch (final Error | RuntimeException t) {
++ throw t;
++ } catch (final Throwable t) {
++ throw new RuntimeException(t);
++ }
+ }
+
+ @Override
+- public int hashCode() {
+- return super.hashCode() ^ getterSlot ^ setterSlot;
+- }
+-
+- /*
+- * Accessors.
+- */
+- @Override
+- public int getSpillCount() {
+- return 2;
++ protected Class<?> getLocalType() {
++ return Object.class;
+ }
+
+ @Override
+- public boolean hasGetterFunction(final ScriptObject obj) {
+- return obj.getSpill(getterSlot) != null;
++ public boolean hasGetterFunction(final ScriptObject sobj) {
++ return getAccessors(sobj).getter != null;
+ }
+
+ @Override
+- public boolean hasSetterFunction(final ScriptObject obj) {
+- return obj.getSpill(setterSlot) != null;
++ public boolean hasSetterFunction(final ScriptObject sobj) {
++ return getAccessors(sobj).setter != null;
++ }
++
++ @Override
++ public int getIntValue(final ScriptObject self, final ScriptObject owner) {
++ return (int)getObjectValue(self, owner);
++ }
++
++ @Override
++ public long getLongValue(final ScriptObject self, final ScriptObject owner) {
++ return (long)getObjectValue(self, owner);
++ }
++
++ @Override
++ public double getDoubleValue(final ScriptObject self, final ScriptObject owner) {
++ return (double)getObjectValue(self, owner);
+ }
+
+ @Override
+ public Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
+- return userAccessorGetter(owner, getGetterSlot(), self);
++ try {
++ return invokeObjectGetter(getAccessors((owner != null) ? owner : self), getINVOKE_UA_GETTER(Object.class, INVALID_PROGRAM_POINT), self);
++ } catch (final Error | RuntimeException t) {
++ throw t;
++ } catch (final Throwable t) {
++ throw new RuntimeException(t);
++ }
+ }
+
+ @Override
+- public void setObjectValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict) {
+- userAccessorSetter(owner, getSetterSlot(), strict ? getKey() : null, self, value);
++ public void setValue(final ScriptObject self, final ScriptObject owner, final int value, final boolean strict) {
++ setValue(self, owner, (Object) value, strict);
++ }
++
++ @Override
++ public void setValue(final ScriptObject self, final ScriptObject owner, final long value, final boolean strict) {
++ setValue(self, owner, (Object) value, strict);
++ }
++
++ @Override
++ public void setValue(final ScriptObject self, final ScriptObject owner, final double value, final boolean strict) {
++ setValue(self, owner, (Object) value, strict);
++ }
++
++ @Override
++ public void setValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict) {
++ try {
++ invokeObjectSetter(getAccessors((owner != null) ? owner : self), getINVOKE_UA_SETTER(Object.class), strict ? getKey() : null, self, value);
++ } catch (final Error | RuntimeException t) {
++ throw t;
++ } catch (final Throwable t) {
++ throw new RuntimeException(t);
++ }
+ }
+
+ @Override
+ public MethodHandle getGetter(final Class<?> type) {
+- return Lookup.filterReturnType(USER_ACCESSOR_GETTER.methodHandle(), type);
++ //this returns a getter on the format (Accessors, Object receiver)
++ return Lookup.filterReturnType(INVOKE_OBJECT_GETTER, type);
++ }
++
++ @Override
++ public MethodHandle getOptimisticGetter(final Class<?> type, final int programPoint) {
++ if (type == int.class) {
++ return INVOKE_INT_GETTER;
++ } else if (type == long.class) {
++ return INVOKE_LONG_GETTER;
++ } else if (type == double.class) {
++ return INVOKE_NUMBER_GETTER;
++ } else {
++ assert type == Object.class;
++ return INVOKE_OBJECT_GETTER;
++ }
+ }
+
+ @Override
+@@ -192,58 +241,127 @@
+ }
+
+ @Override
+- public ScriptFunction getGetterFunction(final ScriptObject obj) {
+- final Object value = obj.getSpill(getterSlot);
+- return (value instanceof ScriptFunction) ? (ScriptFunction) value : null;
++ public ScriptFunction getGetterFunction(final ScriptObject sobj) {
++ final Object value = getAccessors(sobj).getter;
++ return (value instanceof ScriptFunction) ? (ScriptFunction)value : null;
+ }
+
+ @Override
+ public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
+- return USER_ACCESSOR_SETTER.methodHandle();
++ if (type == int.class) {
++ return INVOKE_INT_SETTER;
++ } else if (type == long.class) {
++ return INVOKE_LONG_SETTER;
++ } else if (type == double.class) {
++ return INVOKE_NUMBER_SETTER;
++ } else {
++ assert type == Object.class;
++ return INVOKE_OBJECT_SETTER;
++ }
+ }
+
+ @Override
+- public ScriptFunction getSetterFunction(final ScriptObject obj) {
+- final Object value = obj.getSpill(setterSlot);
+- return (value instanceof ScriptFunction) ? (ScriptFunction) value : null;
++ public ScriptFunction getSetterFunction(final ScriptObject sobj) {
++ final Object value = getAccessors(sobj).setter;
++ return (value instanceof ScriptFunction) ? (ScriptFunction)value : null;
++ }
++
++ /**
++ * Get the getter for the {@code Accessors} object.
++ * This is the the super {@code Object} type getter with {@code Accessors} return type.
++ *
++ * @return The getter handle for the Accessors
++ */
++ MethodHandle getAccessorsGetter() {
++ return super.getGetter(Object.class).asType(MethodType.methodType(Accessors.class, Object.class));
+ }
+
+ // User defined getter and setter are always called by "dyn:call". Note that the user
+ // getter/setter may be inherited. If so, proto is bound during lookup. In either
+ // inherited or self case, slot is also bound during lookup. Actual ScriptFunction
+ // to be called is retrieved everytime and applied.
+- static Object userAccessorGetter(final ScriptObject proto, final int slot, final Object self) {
+- final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
+- final Object func = container.getSpill(slot);
+-
++ @SuppressWarnings("unused")
++ private static Object invokeObjectGetter(final Accessors gs, final MethodHandle invoker, final Object self) throws Throwable {
++ final Object func = gs.getter;
+ if (func instanceof ScriptFunction) {
+- try {
+- return getINVOKE_UA_GETTER().invokeExact(func, self);
+- } catch(final Error|RuntimeException t) {
+- throw t;
+- } catch(final Throwable t) {
+- throw new RuntimeException(t);
+- }
++ return invoker.invokeExact(func, self);
+ }
+
+ return UNDEFINED;
+ }
+
+- static void userAccessorSetter(final ScriptObject proto, final int slot, final String name, final Object self, final Object value) {
+- final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
+- final Object func = container.getSpill(slot);
++ @SuppressWarnings("unused")
++ private static int invokeIntGetter(final Accessors gs, final MethodHandle invoker, final int programPoint, final Object self) throws Throwable {
++ final Object func = gs.getter;
++ if (func instanceof ScriptFunction) {
++ return (int) invoker.invokeExact(func, self);
++ }
+
++ throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
++ }
++
++ @SuppressWarnings("unused")
++ private static long invokeLongGetter(final Accessors gs, final MethodHandle invoker, final int programPoint, final Object self) throws Throwable {
++ final Object func = gs.getter;
+ if (func instanceof ScriptFunction) {
+- try {
+- getINVOKE_UA_SETTER().invokeExact(func, self, value);
+- } catch(final Error|RuntimeException t) {
+- throw t;
+- } catch(final Throwable t) {
+- throw new RuntimeException(t);
+- }
+- } else if (name != null) {
++ return (long) invoker.invokeExact(func, self);
++ }
++
++ throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
++ }
++
++ @SuppressWarnings("unused")
++ private static double invokeNumberGetter(final Accessors gs, final MethodHandle invoker, final int programPoint, final Object self) throws Throwable {
++ final Object func = gs.getter;
++ if (func instanceof ScriptFunction) {
++ return (double) invoker.invokeExact(func, self);
++ }
++
++ throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
++ }
++
++ @SuppressWarnings("unused")
++ private static void invokeObjectSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final Object value) throws Throwable {
++ final Object func = gs.setter;
++ if (func instanceof ScriptFunction) {
++ invoker.invokeExact(func, self, value);
++ } else if (name != null) {
+ throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
+ }
+ }
+
++ @SuppressWarnings("unused")
++ private static void invokeIntSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final int value) throws Throwable {
++ final Object func = gs.setter;
++ if (func instanceof ScriptFunction) {
++ invoker.invokeExact(func, self, value);
++ } else if (name != null) {
++ throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
++ }
++ }
++
++ @SuppressWarnings("unused")
++ private static void invokeLongSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final long value) throws Throwable {
++ final Object func = gs.setter;
++ if (func instanceof ScriptFunction) {
++ invoker.invokeExact(func, self, value);
++ } else if (name != null) {
++ throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
++ }
++ }
++
++ @SuppressWarnings("unused")
++ private static void invokeNumberSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final double value) throws Throwable {
++ final Object func = gs.setter;
++ if (func instanceof ScriptFunction) {
++ invoker.invokeExact(func, self, value);
++ } else if (name != null) {
++ throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
++ }
++ }
++
++ private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
++ return MH.findStatic(LOOKUP, UserAccessorProperty.class, name, MH.type(rtype, types));
++ }
++
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/WithObject.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/WithObject.java Wed Feb 04 12:14:47 2015 -0800
+@@ -35,6 +35,8 @@
+ import jdk.internal.dynalink.linker.GuardedInvocation;
+ import jdk.internal.dynalink.linker.LinkRequest;
+ import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
++import jdk.nashorn.api.scripting.AbstractJSObject;
++import jdk.nashorn.api.scripting.ScriptObjectMirror;
+ import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+ import jdk.nashorn.internal.runtime.linker.NashornGuards;
+
+@@ -64,7 +66,6 @@
+ this.expression = expression;
+ }
+
+-
+ /**
+ * Delete a property based on a key.
+ * @param key Any valid JavaScript value.
+@@ -98,11 +99,11 @@
+ final NashornCallSiteDescriptor ndesc = (NashornCallSiteDescriptor)desc;
+ FindProperty find = null;
+ GuardedInvocation link = null;
+- ScriptObject self = null;
++ ScriptObject self;
+
+ final boolean isNamedOperation;
+ final String name;
+- if(desc.getNameTokenCount() > 2) {
++ if (desc.getNameTokenCount() > 2) {
+ isNamedOperation = true;
+ name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
+ } else {
+@@ -117,7 +118,6 @@
+
+ if (find != null) {
+ link = self.lookup(desc, request);
+-
+ if (link != null) {
+ return fixExpressionCallSite(ndesc, link);
+ }
+@@ -193,18 +193,33 @@
+ *
+ * @param key Property key.
+ * @param deep Whether the search should look up proto chain.
+- * @param stopOnNonScope should a deep search stop on the first non-scope object?
+ * @param start the object on which the lookup was originally initiated
+ *
+ * @return FindPropertyData or null if not found.
+ */
+ @Override
+- FindProperty findProperty(final String key, final boolean deep, final boolean stopOnNonScope, final ScriptObject start) {
+- final FindProperty exprProperty = expression.findProperty(key, deep, stopOnNonScope, start);
++ FindProperty findProperty(final String key, final boolean deep, final ScriptObject start) {
++ // We call findProperty on 'expression' with 'expression' itself as start parameter.
++ // This way in ScriptObject.setObject we can tell the property is from a 'with' expression
++ // (as opposed from another non-scope object in the proto chain such as Object.prototype).
++ final FindProperty exprProperty = expression.findProperty(key, true, expression);
+ if (exprProperty != null) {
+ return exprProperty;
+ }
+- return super.findProperty(key, deep, stopOnNonScope, start);
++ return super.findProperty(key, deep, start);
++ }
++
++ @Override
++ protected Object invokeNoSuchProperty(final String name, final int programPoint) {
++ FindProperty find = expression.findProperty(NO_SUCH_PROPERTY_NAME, true);
++ if (find != null) {
++ final Object func = find.getObjectValue();
++ if (func instanceof ScriptFunction) {
++ return ScriptRuntime.apply((ScriptFunction)func, expression, name);
++ }
++ }
++
++ return getProto().invokeNoSuchProperty(name, programPoint);
+ }
+
+ @Override
+@@ -242,35 +257,65 @@
+ private static GuardedInvocation fixExpressionCallSite(final NashornCallSiteDescriptor desc, final GuardedInvocation link) {
+ // If it's not a getMethod, just add an expression filter that converts WithObject in "this" position to its
+ // expression.
+- if(!"getMethod".equals(desc.getFirstOperator())) {
++ if (!"getMethod".equals(desc.getFirstOperator())) {
+ return fixReceiverType(link, WITHEXPRESSIONFILTER).filterArguments(0, WITHEXPRESSIONFILTER);
+ }
+
+- final MethodHandle linkInvocation = link.getInvocation();
+- final MethodType linkType = linkInvocation.type();
+- final boolean linkReturnsFunction = ScriptFunction.class.isAssignableFrom(linkType.returnType());
++ final MethodHandle linkInvocation = link.getInvocation();
++ final MethodType linkType = linkInvocation.type();
++ final boolean linkReturnsFunction = ScriptFunction.class.isAssignableFrom(linkType.returnType());
++
+ return link.replaceMethods(
+ // Make sure getMethod will bind the script functions it receives to WithObject.expression
+- MH.foldArguments(linkReturnsFunction ? BIND_TO_EXPRESSION_FN : BIND_TO_EXPRESSION_OBJ,
+- filter(linkInvocation.asType(linkType.changeReturnType(
+- linkReturnsFunction ? ScriptFunction.class : Object.class)), WITHEXPRESSIONFILTER)),
+- // No clever things for the guard -- it is still identically filtered.
+- filterGuard(link, WITHEXPRESSIONFILTER));
++ MH.foldArguments(
++ linkReturnsFunction ?
++ BIND_TO_EXPRESSION_FN :
++ BIND_TO_EXPRESSION_OBJ,
++ filterReceiver(
++ linkInvocation.asType(
++ linkType.changeReturnType(
++ linkReturnsFunction ?
++ ScriptFunction.class :
++ Object.class).
++ changeParameterType(
++ 0,
++ Object.class)),
++ WITHEXPRESSIONFILTER)),
++ filterGuardReceiver(link, WITHEXPRESSIONFILTER));
++ // No clever things for the guard -- it is still identically filtered.
++
+ }
+
+ private GuardedInvocation fixScopeCallSite(final GuardedInvocation link, final String name, final ScriptObject owner) {
+- final GuardedInvocation newLink = fixReceiverType(link, WITHSCOPEFILTER);
+- return link.replaceMethods(filter(newLink.getInvocation(), WITHSCOPEFILTER),
+- NashornGuards.combineGuards(expressionGuard(name, owner), filterGuard(newLink, WITHSCOPEFILTER)));
++ final GuardedInvocation newLink = fixReceiverType(link, WITHSCOPEFILTER);
++ final MethodHandle expressionGuard = expressionGuard(name, owner);
++ final MethodHandle filterGuardReceiver = filterGuardReceiver(newLink, WITHSCOPEFILTER);
++ return link.replaceMethods(
++ filterReceiver(
++ newLink.getInvocation(),
++ WITHSCOPEFILTER),
++ NashornGuards.combineGuards(
++ expressionGuard,
++ filterGuardReceiver));
+ }
+
+- private static MethodHandle filterGuard(final GuardedInvocation link, final MethodHandle filter) {
++ private static MethodHandle filterGuardReceiver(final GuardedInvocation link, final MethodHandle receiverFilter) {
+ final MethodHandle test = link.getGuard();
+- return test == null ? null : filter(test, filter);
++ if (test == null) {
++ return null;
++ }
++
++ final Class<?> receiverType = test.type().parameterType(0);
++ final MethodHandle filter = MH.asType(receiverFilter,
++ receiverFilter.type().changeParameterType(0, receiverType).
++ changeReturnType(receiverType));
++
++ return filterReceiver(test, filter);
+ }
+
+- private static MethodHandle filter(final MethodHandle mh, final MethodHandle filter) {
+- return MH.filterArguments(mh, 0, filter.asType(filter.type().changeReturnType(mh.type().parameterType(0))));
++ private static MethodHandle filterReceiver(final MethodHandle mh, final MethodHandle receiverFilter) {
++ //With expression filter == receiverFilter, i.e. receiver is cast to withobject and its expression returned
++ return MH.filterArguments(mh, 0, receiverFilter.asType(receiverFilter.type().changeReturnType(mh.type().parameterType(0))));
+ }
+
+ /**
+@@ -284,11 +329,27 @@
+
+ @SuppressWarnings("unused")
+ private static Object bindToExpression(final Object fn, final Object receiver) {
+- return fn instanceof ScriptFunction ? bindToExpression((ScriptFunction) fn, receiver) : fn;
++ if (fn instanceof ScriptFunction) {
++ return bindToExpression((ScriptFunction) fn, receiver);
++ } else if (fn instanceof ScriptObjectMirror) {
++ final ScriptObjectMirror mirror = (ScriptObjectMirror)fn;
++ if (mirror.isFunction()) {
++ // We need to make sure correct 'this' is used for calls with Ident call
++ // expressions. We do so here using an AbstractJSObject instance.
++ return new AbstractJSObject() {
++ @Override
++ public Object call(final Object thiz, final Object... args) {
++ return mirror.call(withFilterExpression(receiver), args);
++ }
++ };
++ }
++ }
++
++ return fn;
+ }
+
+ private static Object bindToExpression(final ScriptFunction fn, final Object receiver) {
+- return fn.makeBoundFunction(withFilterExpression(receiver), new Object[0]);
++ return fn.makeBoundFunction(withFilterExpression(receiver), ScriptRuntime.EMPTY_ARRAY);
+ }
+
+ private MethodHandle expressionGuard(final String name, final ScriptObject owner) {
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/AnyElements.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.arrays;
++
++/**
++ * Marker interface for any ContinuousArray with any elements
++ * Used for type checks that throw ClassCastExceptions and force relinks
++ * for fast NativeArray specializations of builtin methods
++ */
++public interface AnyElements {
++ /**
++ * Return a numeric weight of the element type - wider is higher
++ * @return element type weight
++ */
++ public int getElementWeight();
++}
+\ No newline at end of file
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,34 +25,227 @@
+
+ package jdk.nashorn.internal.runtime.arrays;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
+ import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.lang.reflect.Array;
+ import java.nio.ByteBuffer;
++import java.util.ArrayList;
++import java.util.Iterator;
++import java.util.List;
++import jdk.internal.dynalink.CallSiteDescriptor;
++import jdk.internal.dynalink.linker.GuardedInvocation;
++import jdk.internal.dynalink.linker.LinkRequest;
++import jdk.nashorn.internal.codegen.CompilerConstants;
++import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.objects.Global;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.PropertyDescriptor;
++import jdk.nashorn.internal.runtime.ScriptRuntime;
++import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
+
+ /**
+ * ArrayData - abstraction for wrapping array elements
+ */
+ public abstract class ArrayData {
+-
+ /** Minimum chunk size for underlying arrays */
+- protected static final int CHUNK_SIZE = 16;
++ protected static final int CHUNK_SIZE = 32;
+
+ /** Mask for getting a chunk */
+ protected static final int CHUNK_MASK = CHUNK_SIZE - 1;
+
+- /**
+- * Immutable empty array to get ScriptObjects started.
+- */
+- public static final ArrayData EMPTY_ARRAY = new NoTypeArrayData();
++ /** Untouched data - still link callsites as IntArrayData, but expands to
++ * a proper ArrayData when we try to write to it */
++ public static final ArrayData EMPTY_ARRAY = new UntouchedArrayData();
+
+ /**
+ * Length of the array data. Not necessarily length of the wrapped array.
++ * This is private to ensure that no one in a subclass is able to touch the length
++ * without going through {@link #setLength}. This is used to implement
++ * {@link LengthNotWritableFilter}s, ensuring that there are no ways past
++ * a {@link #setLength} function replaced by a nop
+ */
+ private long length;
+
+ /**
++ * Method handle to throw an {@link UnwarrantedOptimismException} when getting an element
++ * of the wrong type
++ */
++ protected static final CompilerConstants.Call THROW_UNWARRANTED = staticCall(MethodHandles.lookup(), ArrayData.class, "throwUnwarranted", void.class, ArrayData.class, int.class, int.class);
++
++ /**
++ * Immutable empty array to get ScriptObjects started.
++ * Use the same array and convert it to mutable as soon as it is modified
++ */
++ private static class UntouchedArrayData extends ContinuousArrayData {
++ private UntouchedArrayData() {
++ super(0);
++ }
++
++ private ArrayData toRealArrayData() {
++ return toRealArrayData(0);
++ }
++
++ private ArrayData toRealArrayData(final int index) {
++ final IntArrayData newData = new IntArrayData(index + 1);
++ if (index == 0) {
++ return newData;
++ }
++ return new DeletedRangeArrayFilter(newData, 0, index);
++ }
++
++ @Override
++ public ContinuousArrayData copy() {
++ assert length() == 0;
++ return this;
++ }
++
++ @Override
++ public Object asArrayOfType(final Class<?> componentType) {
++ return Array.newInstance(componentType, 0);
++ }
++
++ @Override
++ public Object[] asObjectArray() {
++ return ScriptRuntime.EMPTY_ARRAY;
++ }
++
++ @Override
++ public ArrayData ensure(final long safeIndex) {
++ if (safeIndex > 0L) {
++ if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH) {
++ return new SparseArrayData(this, safeIndex + 1);
++ }
++ //known to fit in int
++ return toRealArrayData((int)safeIndex).ensure(safeIndex);
++ }
++ return this;
++ }
++
++ @Override
++ public ArrayData convert(final Class<?> type) {
++ return toRealArrayData(0).convert(type);
++ }
++
++ @Override
++ public ArrayData delete(final int index) {
++ return new DeletedRangeArrayFilter(this, index, index);
++ }
++
++ @Override
++ public ArrayData delete(final long fromIndex, final long toIndex) {
++ return new DeletedRangeArrayFilter(this, fromIndex, toIndex);
++ }
++
++ @Override
++ public void shiftLeft(final int by) {
++ //nop, always empty or we wouldn't be of this class
++ }
++
++ @Override
++ public ArrayData shiftRight(final int by) {
++ return this; //always empty or we wouldn't be of this class
++ }
++
++ @Override
++ public ArrayData shrink(final long newLength) {
++ return this;
++ }
++
++ @Override
++ public ArrayData set(final int index, final Object value, final boolean strict) {
++ return toRealArrayData(index).set(index, value, strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final int value, final boolean strict) {
++ return toRealArrayData(index).set(index, value, strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final long value, final boolean strict) {
++ return toRealArrayData(index).set(index, value, strict);
++ }
++
++ @Override
++ public ArrayData set(final int index, final double value, final boolean strict) {
++ return toRealArrayData(index).set(index, value, strict);
++ }
++
++ @Override
++ public int getInt(final int index) {
++ throw new ArrayIndexOutOfBoundsException(index); //empty
++ }
++
++ @Override
++ public long getLong(final int index) {
++ throw new ArrayIndexOutOfBoundsException(index); //empty
++ }
++
++ @Override
++ public double getDouble(final int index) {
++ throw new ArrayIndexOutOfBoundsException(index); //empty
++ }
++
++ @Override
++ public Object getObject(final int index) {
++ throw new ArrayIndexOutOfBoundsException(index); //empty
++ }
++
++ @Override
++ public boolean has(final int index) {
++ return false; //empty
++ }
++
++ @Override
++ public Object pop() {
++ return ScriptRuntime.UNDEFINED;
++ }
++
++ @Override
++ public ArrayData push(final boolean strict, final Object item) {
++ return toRealArrayData().push(strict, item);
++ }
++
++ @Override
++ public ArrayData slice(final long from, final long to) {
++ return this; //empty
++ }
++
++ @Override
++ public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
++ return otherData.copy();
++ }
++
++ //no need to override fastPopInt, as the default behavior is to throw classcast exception so we
++ //can relink and return an undefined, this is the IntArrayData default behavior
++ @Override
++ public String toString() {
++ return getClass().getSimpleName();
++ }
++
++ @Override
++ public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
++ return null;
++ }
++
++ @Override
++ public MethodHandle getElementSetter(final Class<?> elementType) {
++ return null;
++ }
++
++ @Override
++ public Class<?> getElementType() {
++ return int.class;
++ }
++
++ @Override
++ public Class<?> getBoxedElementType() {
++ return Integer.class;
++ }
++ }
++
++ /**
+ * Constructor
+ * @param length Virtual length of the array.
+ */
+@@ -64,17 +257,37 @@
+ * Factory method for unspecified array - start as int
+ * @return ArrayData
+ */
+- public static ArrayData initialArray() {
++ public final static ArrayData initialArray() {
+ return new IntArrayData();
+ }
+
+ /**
++ * Unwarranted thrower
++ *
++ * @param data array data
++ * @param programPoint program point
++ * @param index array index
++ */
++ protected static void throwUnwarranted(final ArrayData data, final int programPoint, final int index) {
++ throw new UnwarrantedOptimismException(data.getObject(index), programPoint);
++ }
++
++ /**
++ * Align an array size up to the nearest array chunk size
++ * @param size size required
++ * @return size given, always >= size
++ */
++ protected final static int alignUp(final int size) {
++ return size + CHUNK_SIZE - 1 & ~(CHUNK_SIZE - 1);
++ }
++
++ /**
+ * Factory method for unspecified array with given length - start as int array data
+ *
+ * @param length the initial length
+ * @return ArrayData
+ */
+- public static ArrayData allocate(final int length) {
++ public static final ArrayData allocate(final int length) {
+ if (length == 0) {
+ return new IntArrayData();
+ } else if (length >= SparseArrayData.MAX_DENSE_LENGTH) {
+@@ -90,7 +303,7 @@
+ * @param array the array
+ * @return ArrayData wrapping this array
+ */
+- public static ArrayData allocate(final Object array) {
++ public static final ArrayData allocate(final Object array) {
+ final Class<?> clazz = array.getClass();
+
+ if (clazz == int[].class) {
+@@ -110,7 +323,7 @@
+ * @param array the array to use for initial elements
+ * @return the ArrayData
+ */
+- public static ArrayData allocate(final int[] array) {
++ public static final ArrayData allocate(final int[] array) {
+ return new IntArrayData(array, array.length);
+ }
+
+@@ -120,7 +333,7 @@
+ * @param array the array to use for initial elements
+ * @return the ArrayData
+ */
+- public static ArrayData allocate(final long[] array) {
++ public static final ArrayData allocate(final long[] array) {
+ return new LongArrayData(array, array.length);
+ }
+
+@@ -130,7 +343,7 @@
+ * @param array the array to use for initial elements
+ * @return the ArrayData
+ */
+- public static ArrayData allocate(final double[] array) {
++ public static final ArrayData allocate(final double[] array) {
+ return new NumberArrayData(array, array.length);
+ }
+
+@@ -140,7 +353,7 @@
+ * @param array the array to use for initial elements
+ * @return the ArrayData
+ */
+- public static ArrayData allocate(final Object[] array) {
++ public static final ArrayData allocate(final Object[] array) {
+ return new ObjectArrayData(array, array.length);
+ }
+
+@@ -150,8 +363,8 @@
+ * @param buf the nio ByteBuffer to wrap
+ * @return the ArrayData
+ */
+- public static ArrayData allocate(final ByteBuffer buf) {
+- return new ByteBufferArrayData((ByteBuffer)buf);
++ public static final ArrayData allocate(final ByteBuffer buf) {
++ return new ByteBufferArrayData(buf);
+ }
+
+ /**
+@@ -160,7 +373,7 @@
+ * @param underlying the underlying ArrayData to wrap in the freeze filter
+ * @return the frozen ArrayData
+ */
+- public static ArrayData freeze(final ArrayData underlying) {
++ public static final ArrayData freeze(final ArrayData underlying) {
+ return new FrozenArrayFilter(underlying);
+ }
+
+@@ -170,11 +383,31 @@
+ * @param underlying the underlying ArrayData to wrap in the seal filter
+ * @return the sealed ArrayData
+ */
+- public static ArrayData seal(final ArrayData underlying) {
++ public static final ArrayData seal(final ArrayData underlying) {
+ return new SealedArrayFilter(underlying);
+ }
+
+ /**
++ * Prevent this array from being extended
++ *
++ * @param underlying the underlying ArrayData to wrap in the non extensible filter
++ * @return new array data, filtered
++ */
++ public static final ArrayData preventExtension(final ArrayData underlying) {
++ return new NonExtensibleArrayFilter(underlying);
++ }
++
++ /**
++ * Prevent this array from having its length reset
++ *
++ * @param underlying the underlying ArrayDAta to wrap in the non extensible filter
++ * @return new array data, filtered
++ */
++ public static final ArrayData setIsLengthNotWritable(final ArrayData underlying) {
++ return new LengthNotWritableFilter(underlying);
++ }
++
++ /**
+ * Return the length of the array data. This may differ from the actual
+ * length of the array this wraps as length may be set or gotten as any
+ * other JavaScript Property
+@@ -227,6 +460,22 @@
+ }
+
+ /**
++ * Increase length by 1
++ * @return the new length, not the old one (i.e. pre-increment)
++ */
++ protected final long increaseLength() {
++ return ++this.length;
++ }
++
++ /**
++ * Decrease length by 1.
++ * @return the new length, not the old one (i.e. pre-decrement)
++ */
++ protected final long decreaseLength() {
++ return --this.length;
++ }
++
++ /**
+ * Shift the array data left
+ *
+ * TODO: explore start at an index and not at zero, to make these operations
+@@ -235,7 +484,7 @@
+ *
+ * @param by offset to shift
+ */
+- public abstract void shiftLeft(int by);
++ public abstract void shiftLeft(final int by);
+
+ /**
+ * Shift the array right
+@@ -244,7 +493,7 @@
+
+ * @return New arraydata (or same)
+ */
+- public abstract ArrayData shiftRight(int by);
++ public abstract ArrayData shiftRight(final int by);
+
+ /**
+ * Ensure that the given index exists and won't fail subsequent
+@@ -252,7 +501,7 @@
+ * @param safeIndex the index to ensure wont go out of bounds
+ * @return new array data (or same)
+ */
+- public abstract ArrayData ensure(long safeIndex);
++ public abstract ArrayData ensure(final long safeIndex);
+
+ /**
+ * Shrink the array to a new length, may or may not retain the
+@@ -262,7 +511,7 @@
+ *
+ * @return new array data (or same)
+ */
+- public abstract ArrayData shrink(long newLength);
++ public abstract ArrayData shrink(final long newLength);
+
+ /**
+ * Set an object value at a given index
+@@ -272,7 +521,7 @@
+ * @param strict are we in strict mode
+ * @return new array data (or same)
+ */
+- public abstract ArrayData set(int index, Object value, boolean strict);
++ public abstract ArrayData set(final int index, final Object value, final boolean strict);
+
+ /**
+ * Set an int value at a given index
+@@ -282,7 +531,7 @@
+ * @param strict are we in strict mode
+ * @return new array data (or same)
+ */
+- public abstract ArrayData set(int index, int value, boolean strict);
++ public abstract ArrayData set(final int index, final int value, final boolean strict);
+
+ /**
+ * Set a long value at a given index
+@@ -292,7 +541,7 @@
+ * @param strict are we in strict mode
+ * @return new array data (or same)
+ */
+- public abstract ArrayData set(int index, long value, boolean strict);
++ public abstract ArrayData set(final int index, final long value, final boolean strict);
+
+ /**
+ * Set an double value at a given index
+@@ -302,7 +551,7 @@
+ * @param strict are we in strict mode
+ * @return new array data (or same)
+ */
+- public abstract ArrayData set(int index, double value, boolean strict);
++ public abstract ArrayData set(final int index, final double value, final boolean strict);
+
+ /**
+ * Set an empty value at a given index. Should only affect Object array.
+@@ -333,7 +582,28 @@
+ * @param index the index
+ * @return the value
+ */
+- public abstract int getInt(int index);
++ public abstract int getInt(final int index);
++
++ /**
++ * Returns the optimistic type of this array data. Basically, when an array data object needs to throw an
++ * {@link UnwarrantedOptimismException}, this type is used as the actual type of the return value.
++ * @return the optimistic type of this array data.
++ */
++ public Type getOptimisticType() {
++ return Type.OBJECT;
++ }
++
++ /**
++ * Get optimistic int - default is that it's impossible. Overridden
++ * by arrays that actually represents ints
++ *
++ * @param index the index
++ * @param programPoint program point
++ * @return the value
++ */
++ public int getIntOptimistic(final int index, final int programPoint) {
++ throw new UnwarrantedOptimismException(getObject(index), programPoint, getOptimisticType());
++ }
+
+ /**
+ * Get a long value from a given index
+@@ -341,7 +611,19 @@
+ * @param index the index
+ * @return the value
+ */
+- public abstract long getLong(int index);
++ public abstract long getLong(final int index);
++
++ /**
++ * Get optimistic long - default is that it's impossible. Overridden
++ * by arrays that actually represents longs or narrower
++ *
++ * @param index the index
++ * @param programPoint program point
++ * @return the value
++ */
++ public long getLongOptimistic(final int index, final int programPoint) {
++ throw new UnwarrantedOptimismException(getObject(index), programPoint, getOptimisticType());
++ }
+
+ /**
+ * Get a double value from a given index
+@@ -349,7 +631,19 @@
+ * @param index the index
+ * @return the value
+ */
+- public abstract double getDouble(int index);
++ public abstract double getDouble(final int index);
++
++ /**
++ * Get optimistic double - default is that it's impossible. Overridden
++ * by arrays that actually represents doubles or narrower
++ *
++ * @param index the index
++ * @param programPoint program point
++ * @return the value
++ */
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ throw new UnwarrantedOptimismException(getObject(index), programPoint, getOptimisticType());
++ }
+
+ /**
+ * Get an Object value from a given index
+@@ -357,14 +651,14 @@
+ * @param index the index
+ * @return the value
+ */
+- public abstract Object getObject(int index);
++ public abstract Object getObject(final int index);
+
+ /**
+ * Tests to see if an entry exists (avoids boxing.)
+ * @param index the index
+ * @return true if entry exists
+ */
+- public abstract boolean has(int index);
++ public abstract boolean has(final int index);
+
+ /**
+ * Returns if element at specific index can be deleted or not.
+@@ -410,7 +704,7 @@
+ * @param index the index
+ * @return new array data (or same)
+ */
+- public abstract ArrayData delete(int index);
++ public abstract ArrayData delete(final int index);
+
+ /**
+ * Delete a given range from this array;
+@@ -420,7 +714,7 @@
+ *
+ * @return new ArrayData after deletion
+ */
+- public abstract ArrayData delete(long fromIndex, long toIndex);
++ public abstract ArrayData delete(final long fromIndex, final long toIndex);
+
+ /**
+ * Convert the ArrayData to one with a different element type
+@@ -430,7 +724,7 @@
+ * @param type new element type
+ * @return new array data
+ */
+- protected abstract ArrayData convert(Class<?> type);
++ public abstract ArrayData convert(final Class<?> type);
+
+ /**
+ * Push an array of items to the end of the array
+@@ -447,7 +741,7 @@
+ final Class<?> widest = widestType(items);
+
+ ArrayData newData = convert(widest);
+- long pos = newData.length();
++ long pos = newData.length;
+ for (final Object item : items) {
+ newData = newData.ensure(pos); //avoid sparse array
+ newData.set((int)pos++, item, strict);
+@@ -456,6 +750,50 @@
+ }
+
+ /**
++ * Push an array of items to the end of the array
++ *
++ * @param strict are we in strict mode
++ * @param item the item
++ * @return new array data (or same)
++ */
++ public ArrayData push(final boolean strict, final Object item) {
++ return push(strict, new Object[] { item });
++ }
++
++ /**
++ * Push an array of items to the end of the array
++ *
++ * @param strict are we in strict mode
++ * @param item the item
++ * @return new array data (or same)
++ */
++ public ArrayData push(final boolean strict, final double item) {
++ return push(strict, item);
++ }
++
++ /**
++ * Push an array of items to the end of the array
++ *
++ * @param strict are we in strict mode
++ * @param item the item
++ * @return new array data (or same)
++ */
++ public ArrayData push(final boolean strict, final long item) {
++ return push(strict, item);
++ }
++
++ /**
++ * Push an array of items to the end of the array
++ *
++ * @param strict are we in strict mode
++ * @param item the item
++ * @return new array data (or same)
++ */
++ public ArrayData push(final boolean strict, final int item) {
++ return push(strict, item);
++ }
++
++ /**
+ * Pop an element from the end of the array
+ *
+ * @return the popped element
+@@ -470,7 +808,7 @@
+ * @param to end index + 1
+ * @return new array data
+ */
+- public abstract ArrayData slice(long from, long to);
++ public abstract ArrayData slice(final long from, final long to);
+
+ /**
+ * Fast splice operation. This just modifies the array according to the number of
+@@ -482,30 +820,32 @@
+ * @param removed number of removed elements
+ * @param added number of added elements
+ * @throws UnsupportedOperationException if fast splice is not supported for the class or arguments.
++ * @return new arraydata, but this never happens because we always throw an exception
+ */
+ public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
+ throw new UnsupportedOperationException();
+ }
+
+-
+ static Class<?> widestType(final Object... items) {
+ assert items.length > 0;
+
+ Class<?> widest = Integer.class;
+
+ for (final Object item : items) {
+- final Class<?> itemClass = item == null ? null : item.getClass();
++ if (item == null) {
++ return Object.class;
++ }
++ final Class<?> itemClass = item.getClass();
+ if (itemClass == Long.class) {
+ if (widest == Integer.class) {
+ widest = Long.class;
+ }
+- } else if (itemClass == Double.class) {
++ } else if (itemClass == Double.class || itemClass == Float.class) {
+ if (widest == Integer.class || widest == Long.class) {
+ widest = Double.class;
+ }
+- } else if (!(item instanceof Number)) {
+- widest = Object.class;
+- break;
++ } else if (itemClass != Integer.class && itemClass != Short.class && itemClass != Byte.class) {
++ return Object.class;
+ }
+ }
+
+@@ -513,23 +853,42 @@
+ }
+
+ /**
++ * Return a list of keys in the array for the iterators
++ * @return iterator key list
++ */
++ protected List<Long> computeIteratorKeys() {
++ final List<Long> keys = new ArrayList<>();
++
++ final long len = length();
++ for (long i = 0L; i < len; i = nextIndex(i)) {
++ if (has((int)i)) {
++ keys.add(i);
++ }
++ }
++
++ return keys;
++ }
++
++ /**
++ * Return an iterator that goes through all indexes of elements
++ * in this array. This includes those after array.length if
++ * they exist
++ *
++ * @return iterator
++ */
++ public Iterator<Long> indexIterator() {
++ return computeIteratorKeys().iterator();
++ }
++
++ /**
+ * Exponential growth function for array size when in
+ * need of resizing.
+ *
+ * @param size current size
+ * @return next size to allocate for internal array
+ */
+- protected static int nextSize(final int size) {
+- if (size == 0) {
+- return CHUNK_SIZE;
+- }
+-
+- int i = size;
+- while ((i & CHUNK_MASK) != 0) {
+- i++;
+- }
+-
+- return i << 1;
++ public static int nextSize(final int size) {
++ return alignUp(size + 1) * 2;
+ }
+
+ /**
+@@ -540,7 +899,7 @@
+ *
+ * @return the next index
+ */
+- public long nextIndex(final long index) {
++ long nextIndex(final long index) {
+ return index + 1;
+ }
+
+@@ -553,4 +912,53 @@
+ throw new RuntimeException(t);
+ }
+ }
++
++ /**
++ * Find a fast call if one exists
++ *
++ * @param clazz array data class
++ * @param desc callsite descriptor
++ * @param request link request
++ * @return fast property getter if one is found
++ */
++ public GuardedInvocation findFastCallMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) {
++ return null;
++ }
++
++ /**
++ * Find a fast property getter if one exists
++ *
++ * @param clazz array data class
++ * @param desc callsite descriptor
++ * @param request link request
++ * @param operator operator
++ * @return fast property getter if one is found
++ */
++ public GuardedInvocation findFastGetMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
++ return null;
++ }
++
++ /**
++ * Find a fast element getter if one exists
++ *
++ * @param clazz array data class
++ * @param desc callsite descriptor
++ * @param request link request
++ * @return fast index getter if one is found
++ */
++ public GuardedInvocation findFastGetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) { // array, index, value
++ return null;
++ }
++
++ /**
++ * Find a fast element setter if one exists
++ *
++ * @param clazz array data class
++ * @param desc callsite descriptor
++ * @param request link request
++ * @return fast index getter if one is found
++ */
++ public GuardedInvocation findFastSetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) { // array, index, value
++ return null;
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package jdk.nashorn.internal.runtime.arrays;
+
++import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+ import jdk.nashorn.internal.runtime.Undefined;
+ import jdk.nashorn.internal.runtime.linker.Bootstrap;
+@@ -76,7 +77,6 @@
+ public ArrayData shiftRight(final int by) {
+ underlying = underlying.shiftRight(by);
+ setLength(underlying.length());
+-
+ return this;
+ }
+
+@@ -84,7 +84,6 @@
+ public ArrayData ensure(final long safeIndex) {
+ underlying = underlying.ensure(safeIndex);
+ setLength(underlying.length());
+-
+ return this;
+ }
+
+@@ -92,7 +91,6 @@
+ public ArrayData shrink(final long newLength) {
+ underlying = underlying.shrink(newLength);
+ setLength(underlying.length());
+-
+ return this;
+ }
+
+@@ -100,7 +98,6 @@
+ public ArrayData set(final int index, final Object value, final boolean strict) {
+ underlying = underlying.set(index, value, strict);
+ setLength(underlying.length());
+-
+ return this;
+ }
+
+@@ -108,7 +105,6 @@
+ public ArrayData set(final int index, final int value, final boolean strict) {
+ underlying = underlying.set(index, value, strict);
+ setLength(underlying.length());
+-
+ return this;
+ }
+
+@@ -116,7 +112,6 @@
+ public ArrayData set(final int index, final long value, final boolean strict) {
+ underlying = underlying.set(index, value, strict);
+ setLength(underlying.length());
+-
+ return this;
+ }
+
+@@ -124,7 +119,6 @@
+ public ArrayData set(final int index, final double value, final boolean strict) {
+ underlying = underlying.set(index, value, strict);
+ setLength(underlying.length());
+-
+ return this;
+ }
+
+@@ -141,21 +135,41 @@
+ }
+
+ @Override
++ public Type getOptimisticType() {
++ return underlying.getOptimisticType();
++ }
++
++ @Override
+ public int getInt(final int index) {
+ return underlying.getInt(index);
+ }
+
+ @Override
++ public int getIntOptimistic(final int index, final int programPoint) {
++ return underlying.getIntOptimistic(index, programPoint);
++ }
++
++ @Override
+ public long getLong(final int index) {
+ return underlying.getLong(index);
+ }
+
+ @Override
++ public long getLongOptimistic(final int index, final int programPoint) {
++ return underlying.getLongOptimistic(index, programPoint);
++ }
++
++ @Override
+ public double getDouble(final int index) {
+ return underlying.getDouble(index);
+ }
+
+ @Override
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ return underlying.getDoubleOptimistic(index, programPoint);
++ }
++
++ @Override
+ public Object getObject(final int index) {
+ return underlying.getObject(index);
+ }
+@@ -180,7 +194,7 @@
+ }
+
+ @Override
+- protected ArrayData convert(final Class<?> type) {
++ public ArrayData convert(final Class<?> type) {
+ underlying = underlying.convert(type);
+ setLength(underlying.length());
+ return this;
+@@ -190,7 +204,6 @@
+ public Object pop() {
+ final Object value = underlying.pop();
+ setLength(underlying.length());
+-
+ return value;
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java Wed Feb 04 12:14:47 2015 -0800
+@@ -182,15 +182,15 @@
+ }
+
+ /**
+- * Convert an index to a long value. This basically amounts to ANDing it
+- * with {@link JSType#MAX_UINT}, as the maximum array index in JavaScript
++ * Convert an index to a long value. This basically amounts to converting it into a
++ * {@link JSType#toUint32(int)} uint32} as the maximum array index in JavaScript
+ * is 0xfffffffe
+ *
+ * @param index index to convert to long form
+ * @return index as uint32 in a long
+ */
+ public static long toLongIndex(final int index) {
+- return index & JSType.MAX_UINT;
++ return JSType.toUint32(index);
+ }
+
+ /**
+@@ -201,7 +201,7 @@
+ * @return index as string
+ */
+ public static String toKey(final int index) {
+- return Long.toString(index & JSType.MAX_UINT);
++ return Long.toString(JSType.toUint32(index));
+ }
+
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/ByteBufferArrayData.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/ByteBufferArrayData.java Wed Feb 04 12:14:47 2015 -0800
+@@ -82,17 +82,17 @@
+ }
+
+ @Override
+- public void shiftLeft(int by) {
++ public void shiftLeft(final int by) {
+ throw unsupported("shiftLeft");
+ }
+
+ @Override
+- public ArrayData shiftRight(int by) {
++ public ArrayData shiftRight(final int by) {
+ throw unsupported("shiftRight");
+ }
+
+ @Override
+- public ArrayData ensure(long safeIndex) {
++ public ArrayData ensure(final long safeIndex) {
+ if (safeIndex < buf.capacity()) {
+ return this;
+ }
+@@ -101,12 +101,12 @@
+ }
+
+ @Override
+- public ArrayData shrink(long newLength) {
++ public ArrayData shrink(final long newLength) {
+ throw unsupported("shrink");
+ }
+
+ @Override
+- public ArrayData set(int index, Object value, boolean strict) {
++ public ArrayData set(final int index, final Object value, final boolean strict) {
+ if (value instanceof Number) {
+ buf.put(index, ((Number)value).byteValue());
+ return this;
+@@ -116,45 +116,45 @@
+ }
+
+ @Override
+- public ArrayData set(int index, int value, boolean strict) {
++ public ArrayData set(final int index, final int value, final boolean strict) {
+ buf.put(index, (byte)value);
+ return this;
+ }
+
+ @Override
+- public ArrayData set(int index, long value, boolean strict) {
++ public ArrayData set(final int index, final long value, final boolean strict) {
+ buf.put(index, (byte)value);
+ return this;
+ }
+
+ @Override
+- public ArrayData set(int index, double value, boolean strict) {
++ public ArrayData set(final int index, final double value, final boolean strict) {
+ buf.put(index, (byte)value);
+ return this;
+ }
+
+ @Override
+- public int getInt(int index) {
++ public int getInt(final int index) {
+ return 0x0ff & buf.get(index);
+ }
+
+ @Override
+- public long getLong(int index) {
++ public long getLong(final int index) {
+ return 0x0ff & buf.get(index);
+ }
+
+ @Override
+- public double getDouble(int index) {
++ public double getDouble(final int index) {
+ return 0x0ff & buf.get(index);
+ }
+
+ @Override
+- public Object getObject(int index) {
+- return (int)(0x0ff & buf.get(index));
++ public Object getObject(final int index) {
++ return 0x0ff & buf.get(index);
+ }
+
+ @Override
+- public boolean has(int index) {
++ public boolean has(final int index) {
+ return index > -1 && index < buf.capacity();
+ }
+
+@@ -169,12 +169,12 @@
+ }
+
+ @Override
+- public ArrayData delete(int index) {
++ public ArrayData delete(final int index) {
+ throw unsupported("delete");
+ }
+
+ @Override
+- public ArrayData delete(long fromIndex, long toIndex) {
++ public ArrayData delete(final long fromIndex, final long toIndex) {
+ throw unsupported("delete");
+ }
+
+@@ -189,7 +189,7 @@
+ }
+
+ @Override
+- public ArrayData slice(long from, long to) {
++ public ArrayData slice(final long from, final long to) {
+ throw unsupported("slice");
+ }
+
+@@ -198,7 +198,7 @@
+ throw unsupported("convert");
+ }
+
+- private UnsupportedOperationException unsupported(final String method) {
++ private static UnsupportedOperationException unsupported(final String method) {
+ return new UnsupportedOperationException(method);
+ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,364 @@
++/*
++ * 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 jdk.nashorn.internal.runtime.arrays;
++
++import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
++import static jdk.nashorn.internal.lookup.Lookup.MH;
++import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
++import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.lang.invoke.MethodType;
++import java.lang.invoke.SwitchPoint;
++import jdk.internal.dynalink.CallSiteDescriptor;
++import jdk.internal.dynalink.linker.GuardedInvocation;
++import jdk.internal.dynalink.linker.LinkRequest;
++import jdk.nashorn.internal.codegen.types.Type;
++import jdk.nashorn.internal.lookup.Lookup;
++import jdk.nashorn.internal.runtime.ScriptObject;
++import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
++import jdk.nashorn.internal.runtime.logging.Logger;
++
++/**
++ * Interface implemented by all arrays that are directly accessible as underlying
++ * native arrays
++ */
++@Logger(name="arrays")
++public abstract class ContinuousArrayData extends ArrayData {
++ /**
++ * Constructor
++ * @param length length (elementLength)
++ */
++ protected ContinuousArrayData(final long length) {
++ super(length);
++ }
++
++ /**
++ * Check if we can put one more element at the end of this continous
++ * array without reallocating, or if we are overwriting an already
++ * allocated element
++ *
++ * @param index index to check
++ * @return true if we don't need to do any array reallocation to fit an element at index
++ */
++ public final boolean hasRoomFor(final int index) {
++ return has(index) || (index == length() && ensure(index) == this);
++ }
++
++ /**
++ * Check if an arraydata is empty
++ * @return true if empty
++ */
++ public boolean isEmpty() {
++ return length() == 0L;
++ }
++
++ /**
++ * Return element getter for a certain type at a certain program point
++ * @param returnType return type
++ * @param programPoint program point
++ * @return element getter or null if not supported (used to implement slow linkage instead
++ * as fast isn't possible)
++ */
++ public abstract MethodHandle getElementGetter(final Class<?> returnType, final int programPoint);
++
++ /**
++ * Return element getter for a certain type at a certain program point
++ * @param elementType element type
++ * @return element setter or null if not supported (used to implement slow linkage instead
++ * as fast isn't possible)
++ */
++ public abstract MethodHandle getElementSetter(final Class<?> elementType);
++
++ /**
++ * Version of has that throws a class cast exception if element does not exist
++ * used for relinking
++ *
++ * @param index index to check - currently only int indexes
++ * @return index
++ */
++ protected final int throwHas(final int index) {
++ if (!has(index)) {
++ throw new ClassCastException();
++ }
++ return index;
++ }
++
++ @Override
++ public abstract ContinuousArrayData copy();
++
++ /**
++ * Returns the type used to store an element in this array
++ * @return element type
++ */
++ public abstract Class<?> getElementType();
++
++ @Override
++ public Type getOptimisticType() {
++ return Type.typeFor(getElementType());
++ }
++
++ /**
++ * Returns the boxed type of the type used to store an element in this array
++ * @return element type
++ */
++ public abstract Class<?> getBoxedElementType();
++
++ /**
++ * Get the widest element type of two arrays. This can be done faster in subclasses, but
++ * this works for all ContinuousArrayDatas and for where more optimal checks haven't been
++ * implemented.
++ *
++ * @param otherData another ContinuousArrayData
++ * @return the widest boxed element type
++ */
++ public ContinuousArrayData widest(final ContinuousArrayData otherData) {
++ final Class<?> elementType = getElementType();
++ return Type.widest(elementType, otherData.getElementType()) == elementType ? this : otherData;
++ }
++
++ /**
++ * Look up a continuous array element getter
++ * @param get getter, sometimes combined with a has check that throws CCE on failure for relink
++ * @param returnType return type
++ * @param programPoint program point
++ * @return array getter
++ */
++ protected final MethodHandle getContinuousElementGetter(final MethodHandle get, final Class<?> returnType, final int programPoint) {
++ return getContinuousElementGetter(getClass(), get, returnType, programPoint);
++ }
++
++ /**
++ * Look up a continuous array element setter
++ * @param set setter, sometimes combined with a has check that throws CCE on failure for relink
++ * @param returnType return type
++ * @return array setter
++ */
++ protected final MethodHandle getContinuousElementSetter(final MethodHandle set, final Class<?> returnType) {
++ return getContinuousElementSetter(getClass(), set, returnType);
++ }
++
++ /**
++ * Return element getter for a {@link ContinuousArrayData}
++ * @param clazz clazz for exact type guard
++ * @param getHas has getter
++ * @param returnType return type
++ * @param programPoint program point
++ * @return method handle for element setter
++ */
++ protected MethodHandle getContinuousElementGetter(final Class<? extends ContinuousArrayData> clazz, final MethodHandle getHas, final Class<?> returnType, final int programPoint) {
++ final boolean isOptimistic = isValid(programPoint);
++ final int fti = getAccessorTypeIndex(getHas.type().returnType());
++ final int ti = getAccessorTypeIndex(returnType);
++ MethodHandle mh = getHas;
++
++ if (isOptimistic) {
++ if (ti < fti) {
++ mh = MH.insertArguments(ArrayData.THROW_UNWARRANTED.methodHandle(), 1, programPoint);
++ }
++ }
++ mh = MH.asType(mh, mh.type().changeReturnType(returnType).changeParameterType(0, clazz));
++
++ if (!isOptimistic) {
++ //for example a & array[17];
++ return Lookup.filterReturnType(mh, returnType);
++ }
++ return mh;
++ }
++
++ /**
++ * Return element setter for a {@link ContinuousArrayData}
++ * @param clazz clazz for exact type guard
++ * @param setHas set has guard
++ * @param elementType element type
++ * @return method handle for element setter
++ */
++ protected MethodHandle getContinuousElementSetter(final Class<? extends ContinuousArrayData> clazz, final MethodHandle setHas, final Class<?> elementType) {
++ return MH.asType(setHas, setHas.type().changeParameterType(2, elementType).changeParameterType(0, clazz));
++ }
++
++ /** Fast access guard - it is impractical for JIT performance reasons to use only CCE asType as guard :-(, also we need
++ the null case explicitly, which is the one that CCE doesn't handle */
++ protected static final MethodHandle FAST_ACCESS_GUARD =
++ MH.dropArguments(
++ staticCall(
++ MethodHandles.lookup(),
++ ContinuousArrayData.class,
++ "guard",
++ boolean.class,
++ Class.class,
++ ScriptObject.class).methodHandle(),
++ 2,
++ int.class);
++
++ @SuppressWarnings("unused")
++ private static final boolean guard(final Class<? extends ContinuousArrayData> clazz, final ScriptObject sobj) {
++ if (sobj != null && sobj.getArray().getClass() == clazz) {
++ return true;
++ }
++ return false;
++ }
++
++ /**
++ * Return a fast linked array getter, or null if we have to dispatch to super class
++ * @param desc descriptor
++ * @param request link request
++ * @return invocation or null if needs to be sent to slow relink
++ */
++ @Override
++ public GuardedInvocation findFastGetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) {
++ final MethodType callType = desc.getMethodType();
++ final Class<?> indexType = callType.parameterType(1);
++ final Class<?> returnType = callType.returnType();
++
++ if (ContinuousArrayData.class.isAssignableFrom(clazz) && indexType == int.class) {
++ final Object[] args = request.getArguments();
++ final int index = (int)args[args.length - 1];
++
++ if (has(index)) {
++ final MethodHandle getArray = ScriptObject.GET_ARRAY.methodHandle();
++ final int programPoint = NashornCallSiteDescriptor.isOptimistic(desc) ? NashornCallSiteDescriptor.getProgramPoint(desc) : INVALID_PROGRAM_POINT;
++ MethodHandle getElement = getElementGetter(returnType, programPoint);
++ if (getElement != null) {
++ getElement = MH.filterArguments(getElement, 0, MH.asType(getArray, getArray.type().changeReturnType(clazz)));
++ final MethodHandle guard = MH.insertArguments(FAST_ACCESS_GUARD, 0, clazz);
++ return new GuardedInvocation(getElement, guard, (SwitchPoint)null, ClassCastException.class);
++ }
++ }
++ }
++
++ return null;
++ }
++
++ /**
++ * Return a fast linked array setter, or null if we have to dispatch to super class
++ * @param desc descriptor
++ * @param request link request
++ * @return invocation or null if needs to be sent to slow relink
++ */
++ @Override
++ public GuardedInvocation findFastSetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) { // array, index, value
++ final MethodType callType = desc.getMethodType();
++ final Class<?> indexType = callType.parameterType(1);
++ final Class<?> elementType = callType.parameterType(2);
++
++ if (ContinuousArrayData.class.isAssignableFrom(clazz) && indexType == int.class) {
++ final Object[] args = request.getArguments();
++ final int index = (int)args[args.length - 2];
++
++ if (hasRoomFor(index)) {
++ MethodHandle setElement = getElementSetter(elementType); //Z(continuousarraydata, int, int), return true if successful
++ if (setElement != null) {
++ //else we are dealing with a wider type than supported by this callsite
++ MethodHandle getArray = ScriptObject.GET_ARRAY.methodHandle();
++ getArray = MH.asType(getArray, getArray.type().changeReturnType(getClass()));
++ setElement = MH.filterArguments(setElement, 0, getArray);
++ final MethodHandle guard = MH.insertArguments(FAST_ACCESS_GUARD, 0, clazz);
++ return new GuardedInvocation(setElement, guard, (SwitchPoint)null, ClassCastException.class); //CCE if not a scriptObject anymore
++ }
++ }
++ }
++
++ return null;
++ }
++
++ /**
++ * Specialization - fast push implementation
++ * @param arg argument
++ * @return new array length
++ */
++ public long fastPush(final int arg) {
++ throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
++ }
++
++ /**
++ * Specialization - fast push implementation
++ * @param arg argument
++ * @return new array length
++ */
++ public long fastPush(final long arg) {
++ throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
++ }
++
++ /**
++ * Specialization - fast push implementation
++ * @param arg argument
++ * @return new array length
++ */
++ public long fastPush(final double arg) {
++ throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
++ }
++
++ /**
++ * Specialization - fast push implementation
++ * @param arg argument
++ * @return new array length
++ */
++ public long fastPush(final Object arg) {
++ throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
++ }
++
++ /**
++ * Specialization - fast pop implementation
++ * @return element value
++ */
++ public int fastPopInt() {
++ throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
++ }
++
++ /**
++ * Specialization - fast pop implementation
++ * @return element value
++ */
++ public long fastPopLong() {
++ throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
++ }
++
++ /**
++ * Specialization - fast pop implementation
++ * @return element value
++ */
++ public double fastPopDouble() {
++ throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
++ }
++
++ /**
++ * Specialization - fast pop implementation
++ * @return element value
++ */
++ public Object fastPopObject() {
++ throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
++ }
++
++ /**
++ * Specialization - fast concat implementation
++ * @param otherData data to concat
++ * @return new arraydata
++ */
++ public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
++ throw new ClassCastException(String.valueOf(getClass()) + " != " + String.valueOf(otherData.getClass()));
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,7 +26,6 @@
+ package jdk.nashorn.internal.runtime.arrays;
+
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+-
+ import java.lang.reflect.Array;
+ import jdk.nashorn.internal.runtime.BitVector;
+
+@@ -39,13 +38,12 @@
+
+ DeletedArrayFilter(final ArrayData underlying) {
+ super(underlying);
+-
+ this.deleted = new BitVector(underlying.length());
+ }
+
+ @Override
+ public ArrayData copy() {
+- DeletedArrayFilter copy = new DeletedArrayFilter(underlying.copy());
++ final DeletedArrayFilter copy = new DeletedArrayFilter(underlying.copy());
+ copy.getDeleted().copy(deleted);
+ return copy;
+ }
+@@ -87,7 +85,6 @@
+ public ArrayData shiftRight(final int by) {
+ super.shiftRight(by);
+ deleted.shiftRight(by, length());
+-
+ return this;
+ }
+
+@@ -107,35 +104,30 @@
+ public ArrayData shrink(final long newLength) {
+ super.shrink(newLength);
+ deleted.resize(length());
+-
+ return this;
+ }
+
+ @Override
+ public ArrayData set(final int index, final Object value, final boolean strict) {
+ deleted.clear(ArrayIndex.toLongIndex(index));
+-
+ return super.set(index, value, strict);
+ }
+
+ @Override
+ public ArrayData set(final int index, final int value, final boolean strict) {
+ deleted.clear(ArrayIndex.toLongIndex(index));
+-
+ return super.set(index, value, strict);
+ }
+
+ @Override
+ public ArrayData set(final int index, final long value, final boolean strict) {
+ deleted.clear(ArrayIndex.toLongIndex(index));
+-
+ return super.set(index, value, strict);
+ }
+
+ @Override
+ public ArrayData set(final int index, final double value, final boolean strict) {
+ deleted.clear(ArrayIndex.toLongIndex(index));
+-
+ return super.set(index, value, strict);
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -36,17 +36,25 @@
+ private long lo, hi;
+
+ DeletedRangeArrayFilter(final ArrayData underlying, final long lo, final long hi) {
+- super(underlying);
++ super(maybeSparse(underlying, hi));
+ this.lo = lo;
+ this.hi = hi;
+ }
+
++ private static ArrayData maybeSparse(final ArrayData underlying, final long hi) {
++ if (hi < SparseArrayData.MAX_DENSE_LENGTH || underlying instanceof SparseArrayData) {
++ return underlying;
++ }
++ return new SparseArrayData(underlying, underlying.length());
++ }
++
+ private boolean isEmpty() {
+ return lo > hi;
+ }
+
+ private boolean isDeleted(final int index) {
+- return lo <= index && index <= hi;
++ final long longIndex = ArrayIndex.toLongIndex(index);
++ return lo <= longIndex && longIndex <= hi;
+ }
+
+ @Override
+@@ -58,9 +66,9 @@
+ public Object[] asObjectArray() {
+ final Object[] value = super.asObjectArray();
+
+- if (lo <= Integer.MAX_VALUE) {
+- final int intHi = (int)Math.min(hi, Integer.MAX_VALUE);
+- for (int i = (int)lo; i <= intHi; i++) {
++ if (lo < Integer.MAX_VALUE) {
++ final int end = (int)Math.min(hi + 1, Integer.MAX_VALUE);
++ for (int i = (int)lo; i < end; i++) {
+ value[i] = ScriptRuntime.UNDEFINED;
+ }
+ }
+@@ -73,9 +81,9 @@
+ final Object value = super.asArrayOfType(componentType);
+ final Object undefValue = convertUndefinedValue(componentType);
+
+- if (lo <= Integer.MAX_VALUE) {
+- final int intHi = (int)Math.min(hi, Integer.MAX_VALUE);
+- for (int i = (int)lo; i <= intHi; i++) {
++ if (lo < Integer.MAX_VALUE) {
++ final int end = (int)Math.min(hi + 1, Integer.MAX_VALUE);
++ for (int i = (int)lo; i < end; i++) {
+ Array.set(value, i, undefValue);
+ }
+ }
+@@ -102,8 +110,9 @@
+ @Override
+ public ArrayData shiftRight(final int by) {
+ super.shiftRight(by);
+- lo = Math.min(length(), lo + by);
+- hi = Math.min(length() - 1, hi + by);
++ final long len = length();
++ lo = Math.min(len, lo + by);
++ hi = Math.min(len - 1, hi + by);
+
+ return isEmpty() ? getUnderlying() : this;
+ }
+@@ -229,7 +238,7 @@
+
+ @Override
+ public Object pop() {
+- final int index = (int)(length() - 1);
++ final int index = (int)length() - 1;
+ if (super.has(index)) {
+ final boolean isDeleted = isDeleted(index);
+ final Object value = super.pop();
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/FrozenArrayFilter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/FrozenArrayFilter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,10 +25,10 @@
+
+ package jdk.nashorn.internal.runtime.arrays;
+
++import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+ import jdk.nashorn.internal.objects.Global;
+-import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+-
+ import jdk.nashorn.internal.runtime.PropertyDescriptor;
++import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+ /**
+ * ArrayData after the array has been frozen by Object.freeze call.
+@@ -79,4 +79,15 @@
+ }
+ return this;
+ }
++
++ @Override
++ public ArrayData push(final boolean strict, final Object... items) {
++ return this; //nop
++ }
++
++ @Override
++ public Object pop() {
++ final int len = (int)underlying.length();
++ return len == 0 ? ScriptRuntime.UNDEFINED : underlying.getObject(len - 1);
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,9 @@
+
+ package jdk.nashorn.internal.runtime.arrays;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
+ import java.util.Arrays;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+@@ -33,7 +36,7 @@
+ * Implementation of {@link ArrayData} as soon as an int has been
+ * written to the array. This is the default data for new arrays
+ */
+-final class IntArrayData extends ArrayData {
++final class IntArrayData extends ContinuousArrayData implements IntElements {
+ /**
+ * The wrapped array
+ */
+@@ -53,75 +56,140 @@
+ * @param array an int array
+ * @param length a length, not necessarily array.length
+ */
+- IntArrayData(final int array[], final int length) {
++ IntArrayData(final int[] array, final int length) {
+ super(length);
+- assert array.length >= length;
++ assert array == null || array.length >= length;
+ this.array = array;
+ }
+
+ @Override
+- public ArrayData copy() {
+- return new IntArrayData(array.clone(), (int) length());
++ public final Class<?> getElementType() {
++ return int.class;
+ }
+
+ @Override
++ public final Class<?> getBoxedElementType() {
++ return Integer.class;
++ }
++
++ @Override
++ public final int getElementWeight() {
++ return 1;
++ }
++
++ @Override
++ public final ContinuousArrayData widest(final ContinuousArrayData otherData) {
++ return otherData;
++ }
++
++ private static final MethodHandle HAS_GET_ELEM = specialCall(MethodHandles.lookup(), IntArrayData.class, "getElem", int.class, int.class).methodHandle();
++ private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), IntArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
++
++ @Override
+ public Object[] asObjectArray() {
+- return toObjectArray(array, (int) length());
++ return toObjectArray(true);
++ }
++
++ @SuppressWarnings("unused")
++ private int getElem(final int index) {
++ if (has(index)) {
++ return array[index];
++ }
++ throw new ClassCastException();
++ }
++
++ @SuppressWarnings("unused")
++ private void setElem(final int index, final int elem) {
++ if (hasRoomFor(index)) {
++ array[index] = elem;
++ return;
++ }
++ throw new ClassCastException();
++ }
++
++ @Override
++ public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
++ return getContinuousElementGetter(HAS_GET_ELEM, returnType, programPoint);
++ }
++
++ @Override
++ public MethodHandle getElementSetter(final Class<?> elementType) {
++ return elementType == int.class ? getContinuousElementSetter(SET_ELEM, elementType) : null;
++ }
++
++ @Override
++ public IntArrayData copy() {
++ return new IntArrayData(array.clone(), (int)length());
+ }
+
+ @Override
+ public Object asArrayOfType(final Class<?> componentType) {
+- if(componentType == int.class) {
+- return array.length == length() ? array.clone() : Arrays.copyOf(array, (int) length());
++ if (componentType == int.class) {
++ final int len = (int)length();
++ return array.length == len ? array.clone() : Arrays.copyOf(array, len);
+ }
+ return super.asArrayOfType(componentType);
+ }
+
+- private static Object[] toObjectArray(final int[] array, final int length) {
+- assert length <= array.length : "length exceeds internal array size";
+- final Object[] oarray = new Object[array.length];
++ private Object[] toObjectArray(final boolean trim) {
++ assert length() <= array.length : "length exceeds internal array size";
++ final int len = (int)length();
++ final Object[] oarray = new Object[trim ? len : array.length];
+
+- for (int index = 0; index < length; index++) {
++ for (int index = 0; index < len; index++) {
+ oarray[index] = Integer.valueOf(array[index]);
+ }
+
+ return oarray;
+ }
+
+- private static double[] toDoubleArray(final int[] array, final int length) {
+- assert length <= array.length : "length exceeds internal array size";
++ private double[] toDoubleArray() {
++ assert length() <= array.length : "length exceeds internal array size";
++ final int len = (int)length();
+ final double[] darray = new double[array.length];
+
+- for (int index = 0; index < length; index++) {
++ for (int index = 0; index < len; index++) {
+ darray[index] = array[index];
+ }
+
+ return darray;
+ }
+
+- private static long[] toLongArray(final int[] array, final int length) {
+- assert length <= array.length : "length exceeds internal array size";
++ private long[] toLongArray() {
++ assert length() <= array.length : "length exceeds internal array size";
++ final int len = (int)length();
+ final long[] larray = new long[array.length];
+
+- for (int index = 0; index < length; index++) {
++ for (int index = 0; index < len; index++) {
+ larray[index] = array[index];
+ }
+
+ return larray;
+ }
+
++ private LongArrayData convertToLong() {
++ return new LongArrayData(toLongArray(), (int)length());
++ }
++
++ private NumberArrayData convertToDouble() {
++ return new NumberArrayData(toDoubleArray(), (int)length());
++ }
++
++ private ObjectArrayData convertToObject() {
++ return new ObjectArrayData(toObjectArray(false), (int)length());
++ }
++
+ @Override
+ public ArrayData convert(final Class<?> type) {
+ if (type == Integer.class) {
+ return this;
+- }
+- final int length = (int) length();
+- if (type == Long.class) {
+- return new LongArrayData(IntArrayData.toLongArray(array, length), length);
++ } else if (type == Long.class) {
++ return convertToLong();
+ } else if (type == Double.class) {
+- return new NumberArrayData(IntArrayData.toDoubleArray(array, length), length);
++ return convertToDouble();
+ } else {
+- return new ObjectArrayData(IntArrayData.toObjectArray(array, length), length);
++ assert type == null || (!Number.class.isAssignableFrom(type) && !type.isPrimitive());
++ return convertToObject();
+ }
+ }
+
+@@ -144,36 +212,28 @@
+
+ @Override
+ public ArrayData ensure(final long safeIndex) {
+- if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= array.length) {
++ if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH) {
+ return new SparseArrayData(this, safeIndex + 1);
+ }
+-
+- int newLength = array.length;
+-
+- while (newLength <= safeIndex) {
+- newLength = ArrayData.nextSize(newLength);
+- }
+-
+- if (array.length <= safeIndex) {
++ final int alen = array.length;
++ if (safeIndex >= alen) {
++ final int newLength = ArrayData.nextSize((int)safeIndex);
+ array = Arrays.copyOf(array, newLength);
+ }
+-
+ setLength(safeIndex + 1);
+-
+ return this;
+ }
+
+ @Override
+ public ArrayData shrink(final long newLength) {
+- Arrays.fill(array, (int) newLength, array.length, 0);
+-
++ Arrays.fill(array, (int)newLength, array.length, 0);
+ return this;
+ }
+
+ @Override
+ public ArrayData set(final int index, final Object value, final boolean strict) {
+- if (value instanceof Integer) {
+- return set(index, ((Number)value).intValue(), strict);
++ if (JSType.isRepresentableAsInt(value)) {
++ return set(index, JSType.toInt32(value), strict);
+ } else if (value == ScriptRuntime.UNDEFINED) {
+ return new UndefinedArrayFilter(this).set(index, value, strict);
+ }
+@@ -192,9 +252,8 @@
+
+ @Override
+ public ArrayData set(final int index, final long value, final boolean strict) {
+- final int intValue = (int)value;
+- if (intValue == value) {
+- array[index] = intValue;
++ if (JSType.isRepresentableAsInt(value)) {
++ array[index] = JSType.toInt32(value);
+ setLength(Math.max(index + 1, length()));
+ return this;
+ }
+@@ -219,16 +278,31 @@
+ }
+
+ @Override
++ public int getIntOptimistic(final int index, final int programPoint) {
++ return array[index];
++ }
++
++ @Override
+ public long getLong(final int index) {
+ return array[index];
+ }
+
+ @Override
++ public long getLongOptimistic(final int index, final int programPoint) {
++ return array[index];
++ }
++
++ @Override
+ public double getDouble(final int index) {
+ return array[index];
+ }
+
+ @Override
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ return array[index];
++ }
++
++ @Override
+ public Object getObject(final int index) {
+ return array[index];
+ }
+@@ -250,11 +324,12 @@
+
+ @Override
+ public Object pop() {
+- if (length() == 0) {
++ final int len = (int)length();
++ if (len == 0) {
+ return ScriptRuntime.UNDEFINED;
+ }
+
+- final int newLength = (int) length() - 1;
++ final int newLength = len - 1;
+ final int elem = array[newLength];
+ array[newLength] = 0;
+ setLength(newLength);
+@@ -264,10 +339,18 @@
+
+ @Override
+ public ArrayData slice(final long from, final long to) {
+- final long start = from < 0 ? (from + length()) : from;
+- final long newLength = to - start;
++ return new IntArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)(to - (from < 0 ? from + length() : from)));
++ }
+
+- return new IntArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
++ @Override
++ public final ArrayData push(final boolean strict, final int item) {
++ final long len = length();
++ final ArrayData newData = ensure(len);
++ if (newData == this) {
++ array[(int)len] = item;
++ return this;
++ }
++ return newData.set((int)len, item, strict);
+ }
+
+ @Override
+@@ -277,8 +360,14 @@
+ if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
+ throw new UnsupportedOperationException();
+ }
+- final ArrayData returnValue = (removed == 0) ?
+- EMPTY_ARRAY : new IntArrayData(Arrays.copyOfRange(array, start, start + removed), removed);
++ final ArrayData returnValue = removed == 0 ?
++ EMPTY_ARRAY :
++ new IntArrayData(
++ Arrays.copyOfRange(
++ array,
++ start,
++ start + removed),
++ removed);
+
+ if (newLength != oldLength) {
+ final int[] newArray;
+@@ -297,4 +386,63 @@
+
+ return returnValue;
+ }
++
++ @Override
++ public long fastPush(final int arg) {
++ final int len = (int)length();
++ if (len == array.length) {
++ array = Arrays.copyOf(array, nextSize(len));
++ }
++ array[len] = arg;
++ return increaseLength();
++ }
++
++ //length must not be zero
++ @Override
++ public int fastPopInt() {
++ if (length() == 0) {
++ throw new ClassCastException(); //relink
++ }
++ final int newLength = (int)decreaseLength();
++ final int elem = array[newLength];
++ array[newLength] = 0;
++ return elem;
++ }
++
++ @Override
++ public long fastPopLong() {
++ return fastPopInt();
++ }
++
++ @Override
++ public double fastPopDouble() {
++ return fastPopInt();
++ }
++
++ @Override
++ public Object fastPopObject() {
++ return fastPopInt();
++ }
++
++ @Override
++ public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
++ final int otherLength = (int)otherData.length();
++ final int thisLength = (int)length();
++ assert otherLength > 0 && thisLength > 0;
++
++ final int[] otherArray = ((IntArrayData)otherData).array;
++ final int newLength = otherLength + thisLength;
++ final int[] newArray = new int[ArrayData.alignUp(newLength)];
++
++ System.arraycopy(array, 0, newArray, 0, thisLength);
++ System.arraycopy(otherArray, 0, newArray, thisLength, otherLength);
++
++ return new IntArrayData(newArray, newLength);
++ }
++
++ @Override
++ public String toString() {
++ assert length() <= array.length : length() + " > " + array.length;
++ return getClass().getSimpleName() + ':' + Arrays.toString(Arrays.copyOf(array, (int)length()));
++ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/IntElements.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.arrays;
++
++/**
++ * Marker interface for any ContinuousArray with int elements
++ * Used for type checks that throw ClassCastExceptions and force relinks
++ * for fast NativeArray specializations of builtin methods
++ */
++public interface IntElements extends IntOrLongElements {
++ //empty
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/IntOrLongElements.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.arrays;
++
++/**
++ * Marker interface for any ContinuousArray with int or long elements
++ * Used for type checks that throw ClassCastExceptions and force relinks
++ * for fast NativeArray specializations of builtin methods
++ */
++public interface IntOrLongElements extends NumericElements {
++ //empty
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,11 +25,7 @@
+
+ package jdk.nashorn.internal.runtime.arrays;
+
+-import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+-
+-import jdk.nashorn.api.scripting.JSObject;
+ import jdk.nashorn.internal.runtime.Context;
+-import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+ import jdk.nashorn.internal.runtime.linker.Bootstrap;
+
+@@ -98,17 +94,7 @@
+ * @return result of apply
+ */
+ public final T apply() {
+- final boolean strict;
+- if (callbackfn instanceof ScriptFunction) {
+- strict = ((ScriptFunction)callbackfn).isStrict();
+- } else if (callbackfn instanceof JSObject &&
+- ((JSObject)callbackfn).isFunction()) {
+- strict = ((JSObject)callbackfn).isStrictFunction();
+- } else if (Bootstrap.isDynamicMethod(callbackfn) || Bootstrap.isFunctionalInterfaceObject(callbackfn)) {
+- strict = false;
+- } else {
+- throw typeError("not.a.function", ScriptRuntime.safeToString(callbackfn));
+- }
++ final boolean strict = Bootstrap.isStrictCallable(callbackfn);
+
+ // for non-strict callback, need to translate undefined thisArg to be global object
+ thisArg = (thisArg == ScriptRuntime.UNDEFINED && !strict)? Context.getGlobal() : thisArg;
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/LengthNotWritableFilter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,198 @@
++package jdk.nashorn.internal.runtime.arrays;
++
++import java.util.Iterator;
++import java.util.List;
++import java.util.SortedMap;
++import java.util.TreeMap;
++import jdk.nashorn.internal.runtime.JSType;
++import jdk.nashorn.internal.runtime.ScriptRuntime;
++
++/**
++ * Filter to use for ArrayData where the length is not writable.
++ * The default behavior is just to ignore {@link ArrayData#setLength}
++ */
++final class LengthNotWritableFilter extends ArrayFilter {
++ private final SortedMap<Long, Object> extraElements; //elements with index >= length
++
++ /**
++ * Constructor
++ * @param underlying array
++ */
++ LengthNotWritableFilter(final ArrayData underlying) {
++ this(underlying, new TreeMap<Long, Object>());
++ }
++
++ private LengthNotWritableFilter(final ArrayData underlying, final SortedMap<Long, Object> extraElements) {
++ super(underlying);
++ this.extraElements = extraElements;
++ }
++
++ @Override
++ public ArrayData copy() {
++ return new LengthNotWritableFilter(underlying.copy(), new TreeMap<>(extraElements));
++ }
++
++ @Override
++ public boolean has(final int index) {
++ return super.has(index) || extraElements.containsKey((long)index);
++ }
++
++ /**
++ * Set the length of the data array
++ *
++ * @param length the new length for the data array
++ */
++ @Override
++ public void setLength(final long length) {
++ //empty - setting length for a LengthNotWritableFilter is always a nop
++ }
++
++ @Override
++ public ArrayData ensure(final long index) {
++ return this;
++ }
++
++ @Override
++ public ArrayData slice(final long from, final long to) {
++ //return array[from...to), or array[from...length] if undefined, in this case not as we are an ArrayData
++ return new LengthNotWritableFilter(underlying.slice(from, to), extraElements.subMap(from, to));
++ }
++
++ private boolean checkAdd(final long index, final Object value) {
++ if (index >= length()) {
++ extraElements.put(index, value);
++ return true;
++ }
++ return false;
++ }
++
++ private Object get(final long index) {
++ final Object obj = extraElements.get(index);
++ if (obj == null) {
++ return ScriptRuntime.UNDEFINED;
++ }
++ return obj;
++ }
++
++ @Override
++ public int getInt(final int index) {
++ if (index >= length()) {
++ return JSType.toInt32(get(index));
++ }
++ return underlying.getInt(index);
++ }
++
++ @Override
++ public int getIntOptimistic(final int index, final int programPoint) {
++ if (index >= length()) {
++ return JSType.toInt32Optimistic(get(index), programPoint);
++ }
++ return underlying.getIntOptimistic(index, programPoint);
++ }
++
++ @Override
++ public long getLong(final int index) {
++ if (index >= length()) {
++ return JSType.toLong(get(index));
++ }
++ return underlying.getLong(index);
++ }
++
++ @Override
++ public long getLongOptimistic(final int index, final int programPoint) {
++ if (index >= length()) {
++ return JSType.toLongOptimistic(get(index), programPoint);
++ }
++ return underlying.getLongOptimistic(index, programPoint);
++ }
++
++ @Override
++ public double getDouble(final int index) {
++ if (index >= length()) {
++ return JSType.toNumber(get(index));
++ }
++ return underlying.getDouble(index);
++ }
++
++ @Override
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ if (index >= length()) {
++ return JSType.toNumberOptimistic(get(index), programPoint);
++ }
++ return underlying.getDoubleOptimistic(index, programPoint);
++ }
++
++ @Override
++ public Object getObject(final int index) {
++ if (index >= length()) {
++ return get(index);
++ }
++ return underlying.getObject(index);
++ }
++
++ @Override
++ public ArrayData set(final int index, final Object value, final boolean strict) {
++ if (checkAdd(index, value)) {
++ return this;
++ }
++ underlying = underlying.set(index, value, strict);
++ return this;
++ }
++
++ @Override
++ public ArrayData set(final int index, final int value, final boolean strict) {
++ if (checkAdd(index, value)) {
++ return this;
++ }
++ underlying = underlying.set(index, value, strict);
++ return this;
++ }
++
++ @Override
++ public ArrayData set(final int index, final long value, final boolean strict) {
++ if (checkAdd(index, value)) {
++ return this;
++ }
++ underlying = underlying.set(index, value, strict);
++ return this;
++ }
++
++ @Override
++ public ArrayData set(final int index, final double value, final boolean strict) {
++ if (checkAdd(index, value)) {
++ return this;
++ }
++ underlying = underlying.set(index, value, strict);
++ return this;
++ }
++
++ @Override
++ public ArrayData delete(final int index) {
++ extraElements.remove(index);
++ underlying = underlying.delete(index);
++ return this;
++ }
++
++ @Override
++ public ArrayData delete(final long fromIndex, final long toIndex) {
++ for (final Iterator<Long> iter = extraElements.keySet().iterator(); iter.hasNext();) {
++ final long next = iter.next();
++ if (next >= fromIndex && next <= toIndex) {
++ iter.remove();
++ }
++ if (next > toIndex) { //ordering guaranteed because TreeSet
++ break;
++ }
++ }
++ underlying = underlying.delete(fromIndex, toIndex);
++ return this;
++ }
++
++ @Override
++ public Iterator<Long> indexIterator() {
++ final List<Long> keys = computeIteratorKeys();
++ keys.addAll(extraElements.keySet()); //even if they are outside length this is fine
++ return keys.iterator();
++ }
++
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,10 @@
+
+ package jdk.nashorn.internal.runtime.arrays;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
++import static jdk.nashorn.internal.lookup.Lookup.MH;
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
+ import java.util.Arrays;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+@@ -33,7 +37,7 @@
+ * Implementation of {@link ArrayData} as soon as a long has been
+ * written to the array
+ */
+-final class LongArrayData extends ArrayData {
++final class LongArrayData extends ContinuousArrayData implements IntOrLongElements {
+ /**
+ * The wrapped array
+ */
+@@ -47,24 +51,45 @@
+ LongArrayData(final long array[], final int length) {
+ super(length);
+ assert array.length >= length;
+- this.array = array;
++ this.array = array;
+ }
+
+ @Override
+- public ArrayData copy() {
+- return new LongArrayData(array.clone(), (int) length());
++ public final Class<?> getElementType() {
++ return long.class;
++ }
++
++ @Override
++ public final Class<?> getBoxedElementType() {
++ return Long.class;
++ }
++
++ @Override
++ public final ContinuousArrayData widest(final ContinuousArrayData otherData) {
++ return otherData instanceof IntElements ? this : otherData;
++ }
++
++ @Override
++ public final int getElementWeight() {
++ return 2;
++ }
++
++ @Override
++ public LongArrayData copy() {
++ return new LongArrayData(array.clone(), (int)length());
+ }
+
+ @Override
+ public Object[] asObjectArray() {
+- return toObjectArray(array, (int) length());
++ return toObjectArray(true);
+ }
+
+- private static Object[] toObjectArray(final long[] array, final int length) {
+- assert length <= array.length : "length exceeds internal array size";
+- final Object[] oarray = new Object[array.length];
++ private Object[] toObjectArray(final boolean trim) {
++ assert length() <= array.length : "length exceeds internal array size";
++ final int len = (int)length();
++ final Object[] oarray = new Object[trim ? len : array.length];
+
+- for (int index = 0; index < length; index++) {
++ for (int index = 0; index < len; index++) {
+ oarray[index] = Long.valueOf(array[index]);
+ }
+
+@@ -73,17 +98,19 @@
+
+ @Override
+ public Object asArrayOfType(final Class<?> componentType) {
+- if(componentType == long.class) {
+- return array.length == length() ? array.clone() : Arrays.copyOf(array, (int) length());
++ if (componentType == long.class) {
++ final int len = (int)length();
++ return array.length == len ? array.clone() : Arrays.copyOf(array, len);
+ }
+ return super.asArrayOfType(componentType);
+ }
+
+- private static double[] toDoubleArray(final long[] array, final int length) {
+- assert length <= array.length : "length exceeds internal array size";
++ private double[] toDoubleArray() {
++ assert length() <= array.length : "length exceeds internal array size";
++ final int len = (int)length();
+ final double[] darray = new double[array.length];
+
+- for (int index = 0; index < length; index++) {
++ for (int index = 0; index < len; index++) {
+ darray[index] = array[index];
+ }
+
+@@ -91,15 +118,15 @@
+ }
+
+ @Override
+- public ArrayData convert(final Class<?> type) {
++ public ContinuousArrayData convert(final Class<?> type) {
+ if (type == Integer.class || type == Long.class) {
+ return this;
+ }
+- final int length = (int) length();
++ final int len = (int)length();
+ if (type == Double.class) {
+- return new NumberArrayData(LongArrayData.toDoubleArray(array, length), length);
++ return new NumberArrayData(toDoubleArray(), len);
+ }
+- return new ObjectArrayData(LongArrayData.toObjectArray(array, length), length);
++ return new ObjectArrayData(toObjectArray(false), len);
+ }
+
+ @Override
+@@ -121,29 +148,21 @@
+
+ @Override
+ public ArrayData ensure(final long safeIndex) {
+- if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= array.length) {
++ if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH) {
+ return new SparseArrayData(this, safeIndex + 1);
+ }
+-
+- int newLength = array.length;
+-
+- while (newLength <= safeIndex) {
+- newLength = ArrayData.nextSize(newLength);
+- }
+-
+- if (array.length <= safeIndex) {
++ final int alen = array.length;
++ if (safeIndex >= alen) {
++ final int newLength = ArrayData.nextSize((int)safeIndex);
+ array = Arrays.copyOf(array, newLength);
+ }
+-
+ setLength(safeIndex + 1);
+-
+ return this;
+ }
+
+ @Override
+ public ArrayData shrink(final long newLength) {
+- Arrays.fill(array, (int) newLength, array.length, 0);
+-
++ Arrays.fill(array, (int)newLength, array.length, 0L);
+ return this;
+ }
+
+@@ -183,6 +202,39 @@
+ return convert(Double.class).set(index, value, strict);
+ }
+
++ private static final MethodHandle HAS_GET_ELEM = specialCall(MethodHandles.lookup(), LongArrayData.class, "getElem", long.class, int.class).methodHandle();
++ private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), LongArrayData.class, "setElem", void.class, int.class, long.class).methodHandle();
++
++ @SuppressWarnings("unused")
++ private long getElem(final int index) {
++ if (has(index)) {
++ return array[index];
++ }
++ throw new ClassCastException();
++ }
++
++ @SuppressWarnings("unused")
++ private void setElem(final int index, final long elem) {
++ if (hasRoomFor(index)) {
++ array[index] = elem;
++ return;
++ }
++ throw new ClassCastException();
++ }
++
++ @Override
++ public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
++ if (returnType == int.class) {
++ return null;
++ }
++ return getContinuousElementGetter(HAS_GET_ELEM, returnType, programPoint);
++ }
++
++ @Override
++ public MethodHandle getElementSetter(final Class<?> elementType) {
++ return elementType == int.class || elementType == long.class ? getContinuousElementSetter(MH.asType(SET_ELEM, SET_ELEM.type().changeParameterType(2, elementType)), elementType) : null;
++ }
++
+ @Override
+ public int getInt(final int index) {
+ return (int)array[index];
+@@ -194,11 +246,21 @@
+ }
+
+ @Override
++ public long getLongOptimistic(final int index, final int programPoint) {
++ return array[index];
++ }
++
++ @Override
+ public double getDouble(final int index) {
+ return array[index];
+ }
+
+ @Override
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ return array[index];
++ }
++
++ @Override
+ public Object getObject(final int index) {
+ return array[index];
+ }
+@@ -220,11 +282,12 @@
+
+ @Override
+ public Object pop() {
+- if (length() == 0) {
++ final int len = (int)length();
++ if (len == 0) {
+ return ScriptRuntime.UNDEFINED;
+ }
+
+- final int newLength = (int) (length() - 1);
++ final int newLength = len - 1;
+ final long elem = array[newLength];
+ array[newLength] = 0;
+ setLength(newLength);
+@@ -234,19 +297,30 @@
+
+ @Override
+ public ArrayData slice(final long from, final long to) {
+- final long start = from < 0 ? (from + length()) : from;
++ final long start = from < 0 ? from + length() : from;
+ final long newLength = to - start;
+ return new LongArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
+ }
+
+ @Override
++ public final ArrayData push(final boolean strict, final long item) {
++ final long len = length();
++ final ArrayData newData = ensure(len);
++ if (newData == this) {
++ array[(int)len] = item;
++ return this;
++ }
++ return newData.set((int)len, item, strict);
++ }
++
++ @Override
+ public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
+ final long oldLength = length();
+ final long newLength = oldLength - removed + added;
+ if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
+ throw new UnsupportedOperationException();
+ }
+- final ArrayData returnValue = (removed == 0) ?
++ final ArrayData returnValue = removed == 0 ?
+ EMPTY_ARRAY : new LongArrayData(Arrays.copyOfRange(array, start, start + removed), removed);
+
+ if (newLength != oldLength) {
+@@ -266,4 +340,74 @@
+
+ return returnValue;
+ }
++
++ @Override
++ public long fastPush(final int arg) {
++ return fastPush((long)arg);
++ }
++
++ @Override
++ public long fastPush(final long arg) {
++ final int len = (int)length();
++ if (len == array.length) {
++ array = Arrays.copyOf(array, nextSize(len));
++ }
++ array[len] = arg;
++ return increaseLength();
++ }
++
++ @Override
++ public long fastPopLong() {
++ if (length() == 0) {
++ throw new ClassCastException(); //undefined result
++ }
++ final int newLength = (int)decreaseLength();
++ final long elem = array[newLength];
++ array[newLength] = 0;
++ return elem;
++ }
++
++ @Override
++ public double fastPopDouble() {
++ return fastPopLong();
++ }
++
++ @Override
++ public Object fastPopObject() {
++ return fastPopLong();
++ }
++
++ @Override
++ public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
++ final int otherLength = (int)otherData.length();
++ final int thisLength = (int)length();
++ assert otherLength > 0 && thisLength > 0;
++
++ final long[] otherArray = ((LongArrayData)otherData).array;
++ final int newLength = otherLength + thisLength;
++ final long[] newArray = new long[ArrayData.alignUp(newLength)];
++
++ System.arraycopy(array, 0, newArray, 0, thisLength);
++ System.arraycopy(otherArray, 0, newArray, thisLength, otherLength);
++
++ return new LongArrayData(newArray, newLength);
++ }
++
++ @Override
++ public String toString() {
++ assert length() <= array.length : length() + " > " + array.length;
++
++ final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).
++ append(": [");
++ final int len = (int)length();
++ for (int i = 0; i < len; i++) {
++ sb.append(array[i]).append('L'); //make sure L suffix is on elements, to discriminate this from IntArrayData.toString()
++ if (i + 1 < len) {
++ sb.append(", ");
++ }
++ }
++ sb.append(']');
++
++ return sb.toString();
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/NoTypeArrayData.java Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,186 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.arrays;
+-
+-import java.lang.reflect.Array;
+-import jdk.nashorn.internal.runtime.ScriptRuntime;
+-
+-/**
+- * Place holding array data for non-array objects. Activates a true array when
+- * accessed. Should only exist as a singleton defined in ArrayData.
+- */
+-final class NoTypeArrayData extends ArrayData {
+- NoTypeArrayData() {
+- super(0);
+- }
+-
+- NoTypeArrayData(final long length) {
+- super(length);
+- }
+-
+- @Override
+- public Object[] asObjectArray() {
+- return new Object[0];
+- }
+-
+- @Override
+- public ArrayData copy() {
+- return new NoTypeArrayData();
+- }
+-
+- @Override
+- public Object asArrayOfType(final Class<?> componentType) {
+- return Array.newInstance(componentType, 0);
+- }
+-
+- @Override
+- public ArrayData convert(final Class<?> type) {
+- final long length = length();
+- final ArrayData arrayData;
+- if (type == Long.class) {
+- arrayData = new LongArrayData(new long[ArrayData.nextSize((int)length)], (int)length);
+- } else if (type == Double.class) {
+- arrayData = new NumberArrayData(new double[ArrayData.nextSize((int)length)], (int)length);
+- } else if (type == Integer.class) {
+- arrayData = new IntArrayData(new int[ArrayData.nextSize((int)length)], (int)length);
+- } else {
+- assert !type.isPrimitive();
+- arrayData = new ObjectArrayData(new Object[ArrayData.nextSize((int)length)], (int)length);
+- }
+- return length == 0 ? arrayData : new DeletedRangeArrayFilter(arrayData, 0, length - 1);
+- }
+-
+- @Override
+- public void shiftLeft(final int by) {
+- //empty
+- }
+-
+- @Override
+- public ArrayData shiftRight(final int by) {
+- return this;
+- }
+-
+- @Override
+- public ArrayData ensure(final long safeIndex) {
+- if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH) {
+- return new SparseArrayData(this, safeIndex + 1);
+- }
+-
+- // Don't trample the shared EMPTY_ARRAY.
+- if (length() == 0) {
+- return new NoTypeArrayData(Math.max(safeIndex + 1, length()));
+- }
+-
+- setLength(Math.max(safeIndex + 1, length()));
+- return this;
+- }
+-
+- @Override
+- public ArrayData shrink(final long newLength) {
+- return this;
+- }
+-
+- @Override
+- public ArrayData set(final int index, final Object value, final boolean strict) {
+- ArrayData newData;
+-
+- if (value instanceof Double) {
+- newData = convert(Double.class);
+- } else if (value instanceof Long) {
+- newData = convert(Long.class);
+- } else if (value instanceof Integer) {
+- newData = convert(Integer.class);
+- } else {
+- assert !(value instanceof Number);
+- newData = convert(value == null ? Object.class : value.getClass());
+- }
+-
+- return newData.set(index, value, strict);
+- }
+-
+- @Override
+- public ArrayData set(final int index, final int value, final boolean strict) {
+- final ArrayData newData = convert(Integer.class);
+- return newData.set(index, value, strict);
+- }
+-
+- @Override
+- public ArrayData set(final int index, final long value, final boolean strict) {
+- final ArrayData newData = convert(Long.class);
+- return newData.set(index, value, strict);
+- }
+-
+- @Override
+- public ArrayData set(final int index, final double value, final boolean strict) {
+- final ArrayData newData = convert(Double.class);
+- return newData.set(index, value, strict);
+- }
+-
+- @Override
+- public int getInt(final int index) {
+- throw new ArrayIndexOutOfBoundsException(index);
+- }
+-
+- @Override
+- public long getLong(final int index) {
+- throw new ArrayIndexOutOfBoundsException(index);
+- }
+-
+- @Override
+- public double getDouble(final int index) {
+- throw new ArrayIndexOutOfBoundsException(index);
+- }
+-
+- @Override
+- public Object getObject(final int index) {
+- throw new ArrayIndexOutOfBoundsException(index);
+- }
+-
+- @Override
+- public boolean has(final int index) {
+- return false;
+- }
+-
+- @Override
+- public ArrayData delete(final int index) {
+- return new DeletedRangeArrayFilter(this, index, index);
+- }
+-
+- @Override
+- public ArrayData delete(final long fromIndex, final long toIndex) {
+- return new DeletedRangeArrayFilter(this, fromIndex, toIndex);
+- }
+-
+- @Override
+- public Object pop() {
+- return ScriptRuntime.UNDEFINED;
+- }
+-
+- @Override
+- public ArrayData slice(final long from, final long to) {
+- return this;
+- }
+-}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/NonExtensibleArrayFilter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,68 @@
++package jdk.nashorn.internal.runtime.arrays;
++
++import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
++import jdk.nashorn.internal.objects.Global;
++import jdk.nashorn.internal.runtime.ScriptRuntime;
++
++/**
++ * Filter class that wrap arrays that have been tagged non extensible
++ */
++final class NonExtensibleArrayFilter extends ArrayFilter {
++
++ /**
++ * Constructor
++ * @param underlying array
++ */
++ NonExtensibleArrayFilter(final ArrayData underlying) {
++ super(underlying);
++ }
++
++ @Override
++ public ArrayData copy() {
++ return new NonExtensibleArrayFilter(underlying.copy());
++ }
++
++ @Override
++ public ArrayData slice(final long from, final long to) {
++ return new NonExtensibleArrayFilter(underlying.slice(from, to));
++ }
++
++ private ArrayData extensionCheck(final boolean strict, final int index) {
++ if (!strict) {
++ return this;
++ }
++ throw typeError(Global.instance(), "object.non.extensible", String.valueOf(index), ScriptRuntime.safeToString(this));
++ }
++
++ @Override
++ public ArrayData set(final int index, final Object value, final boolean strict) {
++ if (has(index)) {
++ return underlying.set(index, value, strict);
++ }
++ return extensionCheck(strict, index);
++ }
++
++ @Override
++ public ArrayData set(final int index, final int value, final boolean strict) {
++ if (has(index)) {
++ return underlying.set(index, value, strict);
++ }
++ return extensionCheck(strict, index);
++ }
++
++ @Override
++ public ArrayData set(final int index, final long value, final boolean strict) {
++ if (has(index)) {
++ return underlying.set(index, value, strict);
++ }
++ return extensionCheck(strict, index);
++ }
++
++ @Override
++ public ArrayData set(final int index, final double value, final boolean strict) {
++ if (has(index)) {
++ return underlying.set(index, value, strict);
++ }
++ return extensionCheck(strict, index);
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,15 +25,18 @@
+
+ package jdk.nashorn.internal.runtime.arrays;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
++import static jdk.nashorn.internal.lookup.Lookup.MH;
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+-
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
+ import java.util.Arrays;
+
+ /**
+ * Implementation of {@link ArrayData} as soon as a double has been
+ * written to the array
+ */
+-final class NumberArrayData extends ArrayData {
++final class NumberArrayData extends ContinuousArrayData implements NumericElements {
+ /**
+ * The wrapped array
+ */
+@@ -44,27 +47,48 @@
+ * @param array an int array
+ * @param length a length, not necessarily array.length
+ */
+- NumberArrayData(final double array[], final int length) {
++ NumberArrayData(final double[] array, final int length) {
+ super(length);
+ assert array.length >= length;
+- this.array = array;
++ this.array = array;
+ }
+
+ @Override
+- public ArrayData copy() {
+- return new NumberArrayData(array.clone(), (int) length());
++ public final Class<?> getElementType() {
++ return double.class;
++ }
++
++ @Override
++ public final Class<?> getBoxedElementType() {
++ return Double.class;
++ }
++
++ @Override
++ public final int getElementWeight() {
++ return 3;
++ }
++
++ @Override
++ public final ContinuousArrayData widest(final ContinuousArrayData otherData) {
++ return otherData instanceof IntOrLongElements ? this : otherData;
++ }
++
++ @Override
++ public NumberArrayData copy() {
++ return new NumberArrayData(array.clone(), (int)length());
+ }
+
+ @Override
+ public Object[] asObjectArray() {
+- return toObjectArray(array, (int) length());
++ return toObjectArray(true);
+ }
+
+- private static Object[] toObjectArray(final double[] array, final int length) {
+- assert length <= array.length : "length exceeds internal array size";
+- final Object[] oarray = new Object[array.length];
++ private Object[] toObjectArray(final boolean trim) {
++ assert length() <= array.length : "length exceeds internal array size";
++ final int len = (int)length();
++ final Object[] oarray = new Object[trim ? len : array.length];
+
+- for (int index = 0; index < length; index++) {
++ for (int index = 0; index < len; index++) {
+ oarray[index] = Double.valueOf(array[index]);
+ }
+ return oarray;
+@@ -72,17 +96,18 @@
+
+ @Override
+ public Object asArrayOfType(final Class<?> componentType) {
+- if(componentType == double.class) {
+- return array.length == length() ? array.clone() : Arrays.copyOf(array, (int) length());
++ if (componentType == double.class) {
++ final int len = (int)length();
++ return array.length == len ? array.clone() : Arrays.copyOf(array, len);
+ }
+ return super.asArrayOfType(componentType);
+ }
+
+ @Override
+- public ArrayData convert(final Class<?> type) {
++ public ContinuousArrayData convert(final Class<?> type) {
+ if (type != Double.class && type != Integer.class && type != Long.class) {
+- final int length = (int) length();
+- return new ObjectArrayData(NumberArrayData.toObjectArray(array, length), length);
++ final int len = (int)length();
++ return new ObjectArrayData(toObjectArray(false), len);
+ }
+ return this;
+ }
+@@ -105,29 +130,22 @@
+
+ @Override
+ public ArrayData ensure(final long safeIndex) {
+- if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= array.length) {
++ if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH) {
+ return new SparseArrayData(this, safeIndex + 1);
+ }
++ final int alen = array.length;
++ if (safeIndex >= alen) {
++ final int newLength = ArrayData.nextSize((int)safeIndex);
++ array = Arrays.copyOf(array, newLength); //todo fill with nan or never accessed?
++ }
++ setLength(safeIndex + 1);
++ return this;
+
+- int newLength = array.length;
+-
+- while (newLength <= safeIndex) {
+- newLength = ArrayData.nextSize(newLength);
+- }
+-
+- if (array.length <= safeIndex) {
+- array = Arrays.copyOf(array, newLength);
+- Arrays.fill(array, (int) length(), newLength, Double.NaN);
+- }
+-
+- setLength(safeIndex + 1);
+-
+- return this;
+ }
+
+ @Override
+ public ArrayData shrink(final long newLength) {
+- Arrays.fill(array, (int) newLength, array.length, 0.0);
++ Arrays.fill(array, (int)newLength, array.length, 0.0);
+ return this;
+ }
+
+@@ -164,6 +182,39 @@
+ return this;
+ }
+
++ private static final MethodHandle HAS_GET_ELEM = specialCall(MethodHandles.lookup(), NumberArrayData.class, "getElem", double.class, int.class).methodHandle();
++ private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), NumberArrayData.class, "setElem", void.class, int.class, double.class).methodHandle();
++
++ @SuppressWarnings("unused")
++ private double getElem(final int index) {
++ if (has(index)) {
++ return array[index];
++ }
++ throw new ClassCastException();
++ }
++
++ @SuppressWarnings("unused")
++ private void setElem(final int index, final double elem) {
++ if (hasRoomFor(index)) {
++ array[index] = elem;
++ return;
++ }
++ throw new ClassCastException();
++ }
++
++ @Override
++ public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
++ if (returnType == int.class || returnType == long.class) {
++ return null;
++ }
++ return getContinuousElementGetter(HAS_GET_ELEM, returnType, programPoint);
++ }
++
++ @Override
++ public MethodHandle getElementSetter(final Class<?> elementType) {
++ return elementType.isPrimitive() ? getContinuousElementSetter(MH.asType(SET_ELEM, SET_ELEM.type().changeParameterType(2, elementType)), elementType) : null;
++ }
++
+ @Override
+ public int getInt(final int index) {
+ return (int)array[index];
+@@ -180,6 +231,11 @@
+ }
+
+ @Override
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ return array[index];
++ }
++
++ @Override
+ public Object getObject(final int index) {
+ return array[index];
+ }
+@@ -201,11 +257,12 @@
+
+ @Override
+ public Object pop() {
+- if (length() == 0) {
++ final int len = (int)length();
++ if (len == 0) {
+ return UNDEFINED;
+ }
+
+- final int newLength = (int) (length() - 1);
++ final int newLength = len - 1;
+ final double elem = array[newLength];
+ array[newLength] = 0;
+ setLength(newLength);
+@@ -214,19 +271,30 @@
+
+ @Override
+ public ArrayData slice(final long from, final long to) {
+- final long start = from < 0 ? (from + length()) : from;
++ final long start = from < 0 ? from + length() : from;
+ final long newLength = to - start;
+ return new NumberArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
+ }
+
+ @Override
++ public final ArrayData push(final boolean strict, final double item) {
++ final long len = length();
++ final ArrayData newData = ensure(len);
++ if (newData == this) {
++ array[(int)len] = item;
++ return this;
++ }
++ return newData.set((int)len, item, strict);
++ }
++
++ @Override
+ public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
+ final long oldLength = length();
+ final long newLength = oldLength - removed + added;
+ if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
+ throw new UnsupportedOperationException();
+ }
+- final ArrayData returnValue = (removed == 0) ?
++ final ArrayData returnValue = removed == 0 ?
+ EMPTY_ARRAY : new NumberArrayData(Arrays.copyOfRange(array, start, start + removed), removed);
+
+ if (newLength != oldLength) {
+@@ -246,4 +314,63 @@
+
+ return returnValue;
+ }
++
++ @Override
++ public long fastPush(final int arg) {
++ return fastPush((double)arg);
++ }
++
++ @Override
++ public long fastPush(final long arg) {
++ return fastPush((double)arg);
++ }
++
++ @Override
++ public long fastPush(final double arg) {
++ final int len = (int)length();
++ if (len == array.length) {
++ //note that fastpush never creates spares arrays, there is nothing to gain by that - it will just use even more memory
++ array = Arrays.copyOf(array, nextSize(len));
++ }
++ array[len] = arg;
++ return increaseLength();
++ }
++
++ @Override
++ public double fastPopDouble() {
++ if (length() == 0) {
++ throw new ClassCastException();
++ }
++ final int newLength = (int)decreaseLength();
++ final double elem = array[newLength];
++ array[newLength] = 0;
++ return elem;
++ }
++
++ @Override
++ public Object fastPopObject() {
++ return fastPopDouble();
++ }
++
++ @Override
++ public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
++ final int otherLength = (int)otherData.length();
++ final int thisLength = (int)length();
++ assert otherLength > 0 && thisLength > 0;
++
++ final double[] otherArray = ((NumberArrayData)otherData).array;
++ final int newLength = otherLength + thisLength;
++ final double[] newArray = new double[ArrayData.alignUp(newLength)];
++
++ System.arraycopy(array, 0, newArray, 0, thisLength);
++ System.arraycopy(otherArray, 0, newArray, thisLength, otherLength);
++
++ return new NumberArrayData(newArray, newLength);
++ }
++
++ @Override
++ public String toString() {
++ assert length() <= array.length : length() + " > " + array.length;
++ return getClass().getSimpleName() + ':' + Arrays.toString(Arrays.copyOf(array, (int)length()));
++ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/NumericElements.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.arrays;
++
++/**
++ * Marker interface for any ContinuousArray with numeric elements
++ * (int, long or double)
++ * Used for type checks that throw ClassCastExceptions and force relinks
++ * for fast NativeArray specializations of builtin methods
++ */
++public interface NumericElements extends AnyElements {
++ //empty
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,9 @@
+
+ package jdk.nashorn.internal.runtime.arrays;
+
++import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
+ import java.util.Arrays;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+@@ -33,7 +36,7 @@
+ * Implementation of {@link ArrayData} as soon as an Object has been
+ * written to the array
+ */
+-final class ObjectArrayData extends ArrayData {
++final class ObjectArrayData extends ContinuousArrayData implements AnyElements {
+
+ /**
+ * The wrapped array
+@@ -45,24 +48,52 @@
+ * @param array an int array
+ * @param length a length, not necessarily array.length
+ */
+- ObjectArrayData(final Object array[], final int length) {
++ ObjectArrayData(final Object[] array, final int length) {
+ super(length);
+ assert array.length >= length;
+ this.array = array;
+ }
+
+ @Override
+- public ArrayData copy() {
+- return new ObjectArrayData(array.clone(), (int) length());
++ public final Class<?> getElementType() {
++ return Object.class;
++ }
++
++ @Override
++ public final Class<?> getBoxedElementType() {
++ return getElementType();
++ }
++
++ @Override
++ public final int getElementWeight() {
++ return 4;
++ }
++
++ @Override
++ public final ContinuousArrayData widest(final ContinuousArrayData otherData) {
++ return otherData instanceof NumericElements ? this : otherData;
++ }
++
++ @Override
++ public ObjectArrayData copy() {
++ return new ObjectArrayData(array.clone(), (int)length());
+ }
+
+ @Override
+ public Object[] asObjectArray() {
+- return Arrays.copyOf(array, (int) length());
++ return array.length == length() ? array.clone() : asObjectArrayCopy();
++ }
++
++ private Object[] asObjectArrayCopy() {
++ final long len = length();
++ assert len <= Integer.MAX_VALUE;
++ final Object[] copy = new Object[(int)len];
++ System.arraycopy(array, 0, copy, 0, (int)len);
++ return copy;
+ }
+
+ @Override
+- public ArrayData convert(final Class<?> type) {
++ public ObjectArrayData convert(final Class<?> type) {
+ return this;
+ }
+
+@@ -84,23 +115,15 @@
+
+ @Override
+ public ArrayData ensure(final long safeIndex) {
+- if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= array.length) {
++ if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH) {
+ return new SparseArrayData(this, safeIndex + 1);
+ }
+-
+- int newLength = array.length;
+-
+- while (newLength <= safeIndex) {
+- newLength = ArrayData.nextSize(newLength);
++ final int alen = array.length;
++ if (safeIndex >= alen) {
++ final int newLength = ArrayData.nextSize((int)safeIndex);
++ array = Arrays.copyOf(array, newLength); //fill with undefined or OK? TODO
+ }
+-
+- if (array.length <= safeIndex) {
+- array = Arrays.copyOf(array, newLength);
+- Arrays.fill(array, (int) length(), newLength, ScriptRuntime.UNDEFINED);
+- }
+-
+ setLength(safeIndex + 1);
+-
+ return this;
+ }
+
+@@ -146,10 +169,45 @@
+
+ @Override
+ public ArrayData setEmpty(final long lo, final long hi) {
+- Arrays.fill(array, (int)Math.max(lo, 0L), (int)Math.min(hi, Integer.MAX_VALUE), ScriptRuntime.EMPTY);
++ // hi parameter is inclusive, but Arrays.fill toIndex parameter is exclusive
++ Arrays.fill(array, (int)Math.max(lo, 0L), (int)Math.min(hi + 1, Integer.MAX_VALUE), ScriptRuntime.EMPTY);
+ return this;
+ }
+
++ private static final MethodHandle HAS_GET_ELEM = specialCall(MethodHandles.lookup(), ObjectArrayData.class, "getElem", Object.class, int.class).methodHandle();
++ private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), ObjectArrayData.class, "setElem", void.class, int.class, Object.class).methodHandle();
++
++ @SuppressWarnings("unused")
++ private Object getElem(final int index) {
++ if (has(index)) {
++ return array[index];
++ }
++ throw new ClassCastException();
++ }
++
++ @SuppressWarnings("unused")
++ private void setElem(final int index, final Object elem) {
++ if (hasRoomFor(index)) {
++ array[index] = elem;
++ return;
++ }
++ throw new ClassCastException();
++ }
++
++ @Override
++ public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
++ if (returnType.isPrimitive()) {
++ return null;
++ }
++ return getContinuousElementGetter(HAS_GET_ELEM, returnType, programPoint);
++ }
++
++ @Override
++ public MethodHandle getElementSetter(final Class<?> elementType) {
++ return getContinuousElementSetter(SET_ELEM, Object.class);
++ }
++
++
+ @Override
+ public int getInt(final int index) {
+ return JSType.toInt32(array[index]);
+@@ -188,12 +246,48 @@
+ }
+
+ @Override
++ public long fastPush(final int arg) {
++ return fastPush((Object)arg);
++ }
++
++ @Override
++ public long fastPush(final long arg) {
++ return fastPush((Object)arg);
++ }
++
++ @Override
++ public long fastPush(final double arg) {
++ return fastPush((Object)arg);
++ }
++
++ @Override
++ public long fastPush(final Object arg) {
++ final int len = (int)length();
++ if (len == array.length) {
++ array = Arrays.copyOf(array, nextSize(len));
++ }
++ array[len] = arg;
++ return increaseLength();
++ }
++
++ @Override
++ public Object fastPopObject() {
++ if (length() == 0) {
++ return ScriptRuntime.UNDEFINED;
++ }
++ final int newLength = (int)decreaseLength();
++ final Object elem = array[newLength];
++ array[newLength] = ScriptRuntime.EMPTY;
++ return elem;
++ }
++
++ @Override
+ public Object pop() {
+ if (length() == 0) {
+ return ScriptRuntime.UNDEFINED;
+ }
+
+- final int newLength = (int) (length() - 1);
++ final int newLength = (int)length() - 1;
+ final Object elem = array[newLength];
+ setEmpty(newLength);
+ setLength(newLength);
+@@ -202,19 +296,30 @@
+
+ @Override
+ public ArrayData slice(final long from, final long to) {
+- final long start = from < 0 ? (from + length()) : from;
++ final long start = from < 0 ? from + length() : from;
+ final long newLength = to - start;
+ return new ObjectArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
+ }
+
+ @Override
++ public ArrayData push(final boolean strict, final Object item) {
++ final long len = length();
++ final ArrayData newData = ensure(len);
++ if (newData == this) {
++ array[(int)len] = item;
++ return this;
++ }
++ return newData.set((int)len, item, strict);
++ }
++
++ @Override
+ public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
+ final long oldLength = length();
+ final long newLength = oldLength - removed + added;
+ if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
+ throw new UnsupportedOperationException();
+ }
+- final ArrayData returnValue = (removed == 0) ?
++ final ArrayData returnValue = removed == 0 ?
+ EMPTY_ARRAY : new ObjectArrayData(Arrays.copyOfRange(array, start, start + removed), removed);
+
+ if (newLength != oldLength) {
+@@ -234,4 +339,26 @@
+
+ return returnValue;
+ }
++
++ @Override
++ public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
++ final int otherLength = (int)otherData.length();
++ final int thisLength = (int)length();
++ assert otherLength > 0 && thisLength > 0;
++
++ final Object[] otherArray = ((ObjectArrayData)otherData).array;
++ final int newLength = otherLength + thisLength;
++ final Object[] newArray = new Object[ArrayData.alignUp(newLength)];
++
++ System.arraycopy(array, 0, newArray, 0, thisLength);
++ System.arraycopy(otherArray, 0, newArray, thisLength, otherLength);
++
++ return new ObjectArrayData(newArray, newLength);
++ }
++
++ @Override
++ public String toString() {
++ assert length() <= array.length : length() + " > " + array.length;
++ return getClass().getSimpleName() + ':' + Arrays.toString(Arrays.copyOf(array, (int)length()));
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/SealedArrayFilter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/SealedArrayFilter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,9 +25,9 @@
+
+ package jdk.nashorn.internal.runtime.arrays;
+
+-import jdk.nashorn.internal.objects.Global;
+ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+
++import jdk.nashorn.internal.objects.Global;
+ import jdk.nashorn.internal.runtime.PropertyDescriptor;
+
+ /**
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,6 +28,7 @@
+ import java.util.Arrays;
+ import java.util.Map;
+ import java.util.TreeMap;
++import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+@@ -35,7 +36,7 @@
+ * Handle arrays where the index is very large.
+ */
+ class SparseArrayData extends ArrayData {
+- static final long MAX_DENSE_LENGTH = 512 * 1024;
++ static final int MAX_DENSE_LENGTH = 8 * 1024 * 1024;
+
+ /** Underlying array. */
+ private ArrayData underlying;
+@@ -65,19 +66,19 @@
+
+ @Override
+ public Object[] asObjectArray() {
+- final int length = (int) Math.min(length(), Integer.MAX_VALUE);
+- final int underlyingLength = (int) Math.min(length, underlying.length());
+- final Object[] objArray = new Object[length];
++ final int len = (int)Math.min(length(), Integer.MAX_VALUE);
++ final int underlyingLength = (int)Math.min(len, underlying.length());
++ final Object[] objArray = new Object[len];
+
+ for (int i = 0; i < underlyingLength; i++) {
+ objArray[i] = underlying.getObject(i);
+ }
+
+- Arrays.fill(objArray, underlyingLength, length, ScriptRuntime.UNDEFINED);
++ Arrays.fill(objArray, underlyingLength, len, ScriptRuntime.UNDEFINED);
+
+ for (final Map.Entry<Long, Object> entry : sparseMap.entrySet()) {
+ final long key = entry.getKey();
+- if (key <= Integer.MAX_VALUE) {
++ if (key < Integer.MAX_VALUE) {
+ objArray[(int)key] = entry.getValue();
+ } else {
+ break; // ascending key order
+@@ -109,8 +110,9 @@
+ @Override
+ public ArrayData shiftRight(final int by) {
+ final TreeMap<Long, Object> newSparseMap = new TreeMap<>();
+- if (underlying.length() + by > maxDenseLength) {
+- for (long i = maxDenseLength - by; i < underlying.length(); i++) {
++ final long len = underlying.length();
++ if (len + by > maxDenseLength) {
++ for (long i = maxDenseLength - by; i < len; i++) {
+ if (underlying.has((int) i)) {
+ newSparseMap.put(Long.valueOf(i + by), underlying.getObject((int) i));
+ }
+@@ -161,8 +163,9 @@
+ underlying = underlying.set(index, value, strict);
+ setLength(Math.max(underlying.length(), length()));
+ } else {
+- sparseMap.put(indexToKey(index), value);
+- setLength(Math.max(index + 1, length()));
++ final Long longIndex = indexToKey(index);
++ sparseMap.put(longIndex, value);
++ setLength(Math.max(longIndex + 1, length()));
+ }
+
+ return this;
+@@ -175,8 +178,9 @@
+ underlying = underlying.set(index, value, strict);
+ setLength(Math.max(underlying.length(), length()));
+ } else {
+- sparseMap.put(indexToKey(index), value);
+- setLength(Math.max(index + 1, length()));
++ final Long longIndex = indexToKey(index);
++ sparseMap.put(longIndex, value);
++ setLength(Math.max(longIndex + 1, length()));
+ }
+ return this;
+ }
+@@ -188,8 +192,9 @@
+ underlying = underlying.set(index, value, strict);
+ setLength(Math.max(underlying.length(), length()));
+ } else {
+- sparseMap.put(indexToKey(index), value);
+- setLength(Math.max(index + 1, length()));
++ final Long longIndex = indexToKey(index);
++ sparseMap.put(longIndex, value);
++ setLength(Math.max(longIndex + 1, length()));
+ }
+ return this;
+ }
+@@ -201,8 +206,9 @@
+ underlying = underlying.set(index, value, strict);
+ setLength(Math.max(underlying.length(), length()));
+ } else {
+- sparseMap.put(indexToKey(index), value);
+- setLength(Math.max(index + 1, length()));
++ final Long longIndex = indexToKey(index);
++ sparseMap.put(longIndex, value);
++ setLength(Math.max(longIndex + 1, length()));
+ }
+ return this;
+ }
+@@ -220,6 +226,11 @@
+ }
+
+ @Override
++ public Type getOptimisticType() {
++ return underlying.getOptimisticType();
++ }
++
++ @Override
+ public int getInt(final int index) {
+ if (index >= 0 && index < maxDenseLength) {
+ return underlying.getInt(index);
+@@ -228,6 +239,14 @@
+ }
+
+ @Override
++ public int getIntOptimistic(final int index, final int programPoint) {
++ if (index >= 0 && index < maxDenseLength) {
++ return underlying.getIntOptimistic(index, programPoint);
++ }
++ return JSType.toInt32Optimistic(sparseMap.get(indexToKey(index)), programPoint);
++ }
++
++ @Override
+ public long getLong(final int index) {
+ if (index >= 0 && index < maxDenseLength) {
+ return underlying.getLong(index);
+@@ -236,6 +255,14 @@
+ }
+
+ @Override
++ public long getLongOptimistic(final int index, final int programPoint) {
++ if (index >= 0 && index < maxDenseLength) {
++ return underlying.getLongOptimistic(index, programPoint);
++ }
++ return JSType.toLongOptimistic(sparseMap.get(indexToKey(index)), programPoint);
++ }
++
++ @Override
+ public double getDouble(final int index) {
+ if (index >= 0 && index < maxDenseLength) {
+ return underlying.getDouble(index);
+@@ -244,6 +271,14 @@
+ }
+
+ @Override
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ if (index >= 0 && index < maxDenseLength) {
++ return underlying.getDouble(index);
++ }
++ return JSType.toNumberOptimistic(sparseMap.get(indexToKey(index)), programPoint);
++ }
++
++ @Override
+ public Object getObject(final int index) {
+ if (index >= 0 && index < maxDenseLength) {
+ return underlying.getObject(index);
+@@ -291,27 +326,29 @@
+ }
+
+ private static Long indexToKey(final int index) {
+- return Long.valueOf(index & JSType.MAX_UINT);
++ return Long.valueOf(ArrayIndex.toLongIndex(index));
+ }
+
+ @Override
+- protected ArrayData convert(final Class<?> type) {
++ public ArrayData convert(final Class<?> type) {
+ underlying = underlying.convert(type);
+ return this;
+ }
+
+ @Override
+ public Object pop() {
+- if (length() == 0) {
++ final long len = length();
++ final long underlyingLen = underlying.length();
++ if (len == 0) {
+ return ScriptRuntime.UNDEFINED;
+ }
+- if (length() == underlying.length()) {
++ if (len == underlyingLen) {
+ final Object result = underlying.pop();
+ setLength(underlying.length());
+ return result;
+ }
+- setLength(length() - 1);
+- final Long key = Long.valueOf(length());
++ setLength(len - 1);
++ final Long key = Long.valueOf(len - 1);
+ return sparseMap.containsKey(key) ? sparseMap.remove(key) : ScriptRuntime.UNDEFINED;
+ }
+
+@@ -321,11 +358,13 @@
+ final long start = from < 0 ? (from + length()) : from;
+ final long newLength = to - start;
+
++ final long underlyingLength = underlying.length();
++
+ if (start >= 0 && to <= maxDenseLength) {
+- if (newLength <= underlying.length()) {
++ if (newLength <= underlyingLength) {
+ return underlying.slice(from, to);
+ }
+- return underlying.slice(from, to).ensure(newLength - 1).delete(underlying.length(), newLength);
++ return underlying.slice(from, to).ensure(newLength - 1).delete(underlyingLength, newLength);
+ }
+
+ ArrayData sliced = EMPTY_ARRAY;
+@@ -349,6 +388,7 @@
+ if (nextKey != null) {
+ return nextKey;
+ }
++
+ return length();
+ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/TypedArrayData.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,204 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.arrays;
++
++import static jdk.nashorn.internal.lookup.Lookup.MH;
++import java.lang.invoke.MethodHandle;
++import java.nio.Buffer;
++import jdk.internal.dynalink.CallSiteDescriptor;
++import jdk.internal.dynalink.linker.GuardedInvocation;
++import jdk.internal.dynalink.linker.LinkRequest;
++import jdk.nashorn.internal.lookup.Lookup;
++
++/**
++ * The superclass of all ArrayData used by TypedArrays
++ *
++ * @param <T> buffer implementation
++ */
++public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayData {
++
++ /** wrapped native buffer */
++ protected final T nb;
++
++ /**
++ * Constructor
++ * @param nb wrapped native buffer
++ * @param elementLength length in elements
++ */
++ protected TypedArrayData(final T nb, final int elementLength) {
++ super(elementLength); //TODO is this right?
++ this.nb = nb;
++ }
++
++ /**
++ * Length in number of elements. Accessed from {@code ArrayBufferView}
++ * @return element length
++ */
++ public final int getElementLength() {
++ return (int)length();
++ }
++
++ /**
++ * Is this an unsigned array data?
++ * @return true if unsigned
++ */
++ public boolean isUnsigned() {
++ return false;
++ }
++
++ /**
++ * Is this a clamped array data?
++ * @return true if clamped
++ */
++ public boolean isClamped() {
++ return false;
++ }
++
++ @Override
++ public boolean canDelete(final int index, final boolean strict) {
++ return false;
++ }
++
++ @Override
++ public boolean canDelete(final long fromIndex, final long toIndex, final boolean strict) {
++ return false;
++ }
++
++ @Override
++ public TypedArrayData<T> copy() {
++ throw new UnsupportedOperationException();
++ }
++
++ @Override
++ public Object[] asObjectArray() {
++ throw new UnsupportedOperationException();
++ }
++
++ @Override
++ public void shiftLeft(final int by) {
++ throw new UnsupportedOperationException();
++ }
++
++ @Override
++ public ArrayData shiftRight(final int by) {
++ throw new UnsupportedOperationException();
++ }
++
++ @Override
++ public ArrayData ensure(final long safeIndex) {
++ return this;
++ }
++
++ @Override
++ public ArrayData shrink(final long newLength) {
++ throw new UnsupportedOperationException();
++ }
++
++ @Override
++ public final boolean has(final int index) {
++ return 0 <= index && index < length();
++ }
++
++ @Override
++ public ArrayData delete(final int index) {
++ return this;
++ }
++
++ @Override
++ public ArrayData delete(final long fromIndex, final long toIndex) {
++ return this;
++ }
++
++ @Override
++ public TypedArrayData<T> convert(final Class<?> type) {
++ throw new UnsupportedOperationException();
++ }
++
++ @Override
++ public Object pop() {
++ throw new UnsupportedOperationException();
++ }
++
++ @Override
++ public ArrayData slice(final long from, final long to) {
++ throw new UnsupportedOperationException();
++ }
++
++ /**
++ * Element getter method handle
++ * @return getter
++ */
++ protected abstract MethodHandle getGetElem();
++
++ /**
++ * Element setter method handle
++ * @return setter
++ */
++ protected abstract MethodHandle getSetElem();
++
++ @Override
++ public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
++ final MethodHandle getter = getContinuousElementGetter(getClass(), getGetElem(), returnType, programPoint);
++ if (getter != null) {
++ return Lookup.filterReturnType(getter, returnType);
++ }
++ return getter;
++ }
++
++ @Override
++ public MethodHandle getElementSetter(final Class<?> elementType) {
++ return getContinuousElementSetter(getClass(), Lookup.filterArgumentType(getSetElem(), 2, elementType), elementType);
++ }
++
++ @Override
++ protected MethodHandle getContinuousElementSetter(final Class<? extends ContinuousArrayData> clazz, final MethodHandle setHas, final Class<?> elementType) {
++ final MethodHandle mh = Lookup.filterArgumentType(setHas, 2, elementType);
++ return MH.asType(mh, mh.type().changeParameterType(0, clazz));
++ }
++
++ @Override
++ public GuardedInvocation findFastGetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) {
++ final GuardedInvocation inv = super.findFastGetIndexMethod(clazz, desc, request);
++
++ if (inv != null) {
++ return inv;
++ }
++
++ return null;
++ }
++
++ @Override
++ public GuardedInvocation findFastSetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) { // array, index, value
++ final GuardedInvocation inv = super.findFastSetIndexMethod(clazz, desc, request);
++
++ if (inv != null) {
++ return inv;
++ }
++
++ return null;
++ }
++
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,9 +26,9 @@
+ package jdk.nashorn.internal.runtime.arrays;
+
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+-
+ import java.lang.reflect.Array;
+ import jdk.nashorn.internal.runtime.BitVector;
++import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
+
+ /**
+ * This filter handles the presence of undefined array elements.
+@@ -39,13 +39,12 @@
+
+ UndefinedArrayFilter(final ArrayData underlying) {
+ super(underlying);
+-
+ this.undefined = new BitVector(underlying.length());
+ }
+
+ @Override
+ public ArrayData copy() {
+- UndefinedArrayFilter copy = new UndefinedArrayFilter(underlying.copy());
++ final UndefinedArrayFilter copy = new UndefinedArrayFilter(underlying.copy());
+ copy.getUndefined().copy(undefined);
+ return copy;
+ }
+@@ -87,7 +86,6 @@
+ public ArrayData shiftRight(final int by) {
+ super.shiftRight(by);
+ undefined.shiftRight(by, length());
+-
+ return this;
+ }
+
+@@ -107,7 +105,6 @@
+ public ArrayData shrink(final long newLength) {
+ super.shrink(newLength);
+ undefined.resize(length());
+-
+ return this;
+ }
+
+@@ -154,6 +151,15 @@
+ }
+
+ @Override
++ public int getIntOptimistic(final int index, final int programPoint) {
++ if (undefined.isSet(index)) {
++ throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
++ }
++
++ return super.getIntOptimistic(index, programPoint);
++ }
++
++ @Override
+ public long getLong(final int index) {
+ if (undefined.isSet(index)) {
+ return 0L;
+@@ -163,6 +169,15 @@
+ }
+
+ @Override
++ public long getLongOptimistic(final int index, final int programPoint) {
++ if (undefined.isSet(index)) {
++ throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
++ }
++
++ return super.getLongOptimistic(index, programPoint);
++ }
++
++ @Override
+ public double getDouble(final int index) {
+ if (undefined.isSet(index)) {
+ return Double.NaN;
+@@ -172,6 +187,15 @@
+ }
+
+ @Override
++ public double getDoubleOptimistic(final int index, final int programPoint) {
++ if (undefined.isSet(index)) {
++ throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
++ }
++
++ return super.getDoubleOptimistic(index, programPoint);
++ }
++
++ @Override
+ public Object getObject(final int index) {
+ if (undefined.isSet(index)) {
+ return UNDEFINED;
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/events/RecompilationEvent.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,67 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.events;
++
++import java.util.logging.Level;
++import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
++import jdk.nashorn.internal.runtime.RewriteException;
++
++/**
++ * Subclass of runtime event for {@link RewriteException}. In order not
++ * to leak memory, RewriteExceptions get their return value destroyed
++ * and nulled out during recompilation. If we are running with event
++ * logging enabled, we need to retain the returnValue, hence the extra
++ * field
++ */
++public final class RecompilationEvent extends RuntimeEvent<RewriteException> {
++
++ private final Object returnValue;
++
++ /**
++ * Constructor
++ *
++ * @param level logging level
++ * @param rewriteException rewriteException wrapped by this RuntimEvent
++ * @param returnValue rewriteException return value - as we don't want to make
++ * {@code RewriteException.getReturnValueNonDestructive()} public, we pass it as
++ * an extra parameter, rather than querying the getter from another package.
++ */
++ public RecompilationEvent(final Level level, final RewriteException rewriteException, final Object returnValue) {
++ super(level, rewriteException);
++ assert Context.getContext().getLogger(RecompilableScriptFunctionData.class).isEnabled() :
++ "Unit test/instrumentation purpose only: RecompilationEvent instances should not be created without '--log=recompile', or we will leak memory in the general case";
++ this.returnValue = returnValue;
++ }
++
++ /**
++ * Get the preserved return value for the RewriteException
++ * @return return value
++ */
++ public Object getReturnValue() {
++ return returnValue;
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/events/RuntimeEvent.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,87 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.events;
++
++import java.util.logging.Level;
++import jdk.nashorn.internal.objects.NativeDebug;
++import jdk.nashorn.internal.runtime.options.Options;
++
++/**
++ * Class for representing a runtime event, giving less global dependencies than logger.
++ * Every {@link NativeDebug} object keeps a queue of RuntimeEvents that can be explored
++ * through the debug API.
++ *
++ * @param <T> class of the value this event wraps
++ */
++public class RuntimeEvent<T> {
++ /** Queue size for the runtime event buffer */
++ public static final int RUNTIME_EVENT_QUEUE_SIZE = Options.getIntProperty("nashorn.runtime.event.queue.size", 1024);
++
++ private final Level level;
++ private final T value;
++
++ /**
++ * Constructor
++ *
++ * @param level log level for runtime event to create
++ * @param object object to wrap
++ */
++ public RuntimeEvent(final Level level, final T object) {
++ this.level = level;
++ this.value = object;
++ }
++
++ /**
++ * Return the value wrapped in this runtime event
++ * @return value
++ */
++ public final T getValue() {
++ return value;
++ }
++
++ @Override
++ public String toString() {
++ final StringBuilder sb = new StringBuilder();
++
++ sb.append('[').
++ append(level).
++ append("] ").
++ append(value == null ? "null" : getValueClass().getSimpleName()).
++ append(" value=").
++ append(value);
++
++ return sb.toString();
++ }
++
++ /**
++ * Descriptor for this runtime event, must be overridden and
++ * implemented, e.g. "RewriteException"
++ * @return event name
++ */
++ public final Class<?> getValueClass() {
++ return value.getClass();
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,8 +26,10 @@
+ package jdk.nashorn.internal.runtime.linker;
+
+ import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
++import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+
+ import java.lang.invoke.CallSite;
++import java.lang.invoke.ConstantCallSite;
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+ import java.lang.invoke.MethodHandles.Lookup;
+@@ -35,14 +37,24 @@
+ import jdk.internal.dynalink.CallSiteDescriptor;
+ import jdk.internal.dynalink.DynamicLinker;
+ import jdk.internal.dynalink.DynamicLinkerFactory;
++import jdk.internal.dynalink.GuardedInvocationFilter;
+ import jdk.internal.dynalink.beans.BeansLinker;
+ import jdk.internal.dynalink.beans.StaticClass;
+ import jdk.internal.dynalink.linker.GuardedInvocation;
++import jdk.internal.dynalink.linker.LinkRequest;
+ import jdk.internal.dynalink.linker.LinkerServices;
++import jdk.internal.dynalink.linker.MethodTypeConversionStrategy;
++import jdk.internal.dynalink.support.TypeUtilities;
+ import jdk.nashorn.api.scripting.JSObject;
+ import jdk.nashorn.internal.codegen.CompilerConstants.Call;
++import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+ import jdk.nashorn.internal.codegen.RuntimeCallSite;
++import jdk.nashorn.internal.lookup.MethodHandleFactory;
++import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
++import jdk.nashorn.internal.objects.ScriptFunctionImpl;
++import jdk.nashorn.internal.runtime.ECMAException;
+ import jdk.nashorn.internal.runtime.JSType;
++import jdk.nashorn.internal.runtime.OptimisticReturnFilters;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+ import jdk.nashorn.internal.runtime.options.Options;
+@@ -54,6 +66,27 @@
+ /** Reference to the seed boostrap function */
+ public static final Call BOOTSTRAP = staticCallNoLookup(Bootstrap.class, "bootstrap", CallSite.class, Lookup.class, String.class, MethodType.class, int.class);
+
++ private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();
++
++ private static final MethodHandle VOID_TO_OBJECT = MH.constant(Object.class, ScriptRuntime.UNDEFINED);
++
++ /**
++ * The default dynalink relink threshold for megamorphisism is 8. In the case
++ * of object fields only, it is fine. However, with dual fields, in order to get
++ * performance on benchmarks with a lot of object instantiation and then field
++ * reassignment, it can take slightly more relinks to become stable with type
++ * changes swapping out an entire proprety map and making a map guard fail.
++ * Therefore the relink threshold is set to 16 for dual fields (now the default).
++ * This doesn't seem to have any other negative performance implication.
++ *
++ * See for example octane.gbemu, run with --log=fields:warning to study
++ * megamorphic behavior
++ */
++ private static final int NASHORN_DEFAULT_UNSTABLE_RELINK_THRESHOLD =
++ ObjectClassGenerator.OBJECT_FIELDS_ONLY ?
++ 8 :
++ 16;
++
+ // do not create me!!
+ private Bootstrap() {
+ }
+@@ -62,18 +95,31 @@
+ static {
+ final DynamicLinkerFactory factory = new DynamicLinkerFactory();
+ final NashornBeansLinker nashornBeansLinker = new NashornBeansLinker();
+- final JSObjectLinker jsObjectLinker = new JSObjectLinker(nashornBeansLinker);
+ factory.setPrioritizedLinkers(
+ new NashornLinker(),
+ new NashornPrimitiveLinker(),
+ new NashornStaticClassLinker(),
+- new BoundDynamicMethodLinker(),
++ new BoundCallableLinker(),
+ new JavaSuperAdapterLinker(),
+- jsObjectLinker,
++ new JSObjectLinker(nashornBeansLinker),
++ new BrowserJSObjectLinker(nashornBeansLinker),
+ new ReflectionCheckLinker());
+ factory.setFallbackLinkers(nashornBeansLinker, new NashornBottomLinker());
+ factory.setSyncOnRelink(true);
+- final int relinkThreshold = Options.getIntProperty("nashorn.unstable.relink.threshold", -1);
++ factory.setPrelinkFilter(new GuardedInvocationFilter() {
++ @Override
++ public GuardedInvocation filter(final GuardedInvocation inv, final LinkRequest request, final LinkerServices linkerServices) {
++ final CallSiteDescriptor desc = request.getCallSiteDescriptor();
++ return OptimisticReturnFilters.filterOptimisticReturnValue(inv, desc).asType(linkerServices, desc.getMethodType());
++ }
++ });
++ factory.setAutoConversionStrategy(new MethodTypeConversionStrategy() {
++ @Override
++ public MethodHandle asType(final MethodHandle target, final MethodType newType) {
++ return unboxReturnType(target, newType);
++ }
++ });
++ final int relinkThreshold = Options.getIntProperty("nashorn.unstable.relink.threshold", NASHORN_DEFAULT_UNSTABLE_RELINK_THRESHOLD);
+ if (relinkThreshold > -1) {
+ factory.setUnstableRelinkThreshold(relinkThreshold);
+ }
+@@ -95,19 +141,47 @@
+ }
+
+ return obj instanceof ScriptFunction ||
+- ((obj instanceof JSObject) && ((JSObject)obj).isFunction()) ||
+- isDynamicMethod(obj) ||
++ isJSObjectFunction(obj) ||
++ BeansLinker.isDynamicMethod(obj) ||
++ obj instanceof BoundCallable ||
+ isFunctionalInterfaceObject(obj) ||
+ obj instanceof StaticClass;
+ }
+
+ /**
++ * Returns true if the given object is a strict callable
++ * @param callable the callable object to be checked for strictness
++ * @return true if the obj is a strict callable, false if it is a non-strict callable.
++ * @throws ECMAException with {@code TypeError} if the object is not a callable.
++ */
++ public static boolean isStrictCallable(final Object callable) {
++ if (callable instanceof ScriptFunction) {
++ return ((ScriptFunction)callable).isStrict();
++ } else if (isJSObjectFunction(callable)) {
++ return ((JSObject)callable).isStrictFunction();
++ } else if (callable instanceof BoundCallable) {
++ return isStrictCallable(((BoundCallable)callable).getCallable());
++ } else if (BeansLinker.isDynamicMethod(callable) || callable instanceof StaticClass) {
++ return false;
++ }
++ throw notFunction(callable);
++ }
++
++ private static ECMAException notFunction(final Object obj) {
++ return typeError("not.a.function", ScriptRuntime.safeToString(obj));
++ }
++
++ private static boolean isJSObjectFunction(final Object obj) {
++ return obj instanceof JSObject && ((JSObject)obj).isFunction();
++ }
++
++ /**
+ * Returns if the given object is a dynalink Dynamic method
+ * @param obj object to be checked
+ * @return true if the obj is a dynamic method
+ */
+ public static boolean isDynamicMethod(final Object obj) {
+- return obj instanceof BoundDynamicMethod || BeansLinker.isDynamicMethod(obj);
++ return BeansLinker.isDynamicMethod(obj instanceof BoundCallable ? ((BoundCallable)obj).getCallable() : obj);
+ }
+
+ /**
+@@ -117,7 +191,7 @@
+ * @return true if the obj is an instance of @FunctionalInterface interface
+ */
+ public static boolean isFunctionalInterfaceObject(final Object obj) {
+- return !JSType.isPrimitive(obj) && (NashornBottomLinker.getFunctionalInterfaceMethod(obj.getClass()) != null);
++ return !JSType.isPrimitive(obj) && (NashornBeansLinker.getFunctionalInterfaceMethod(obj.getClass()) != null);
+ }
+
+ /**
+@@ -148,6 +222,60 @@
+ }
+
+ /**
++ * Boostrapper for math calls that may overflow
++ * @param lookup lookup
++ * @param name name of operation
++ * @param type method type
++ * @param programPoint program point to bind to callsite
++ *
++ * @return callsite for a math instrinic node
++ */
++ public static CallSite mathBootstrap(final MethodHandles.Lookup lookup, final String name, final MethodType type, final int programPoint) {
++ final MethodHandle mh;
++ switch (name) {
++ case "iadd":
++ mh = JSType.ADD_EXACT.methodHandle();
++ break;
++ case "isub":
++ mh = JSType.SUB_EXACT.methodHandle();
++ break;
++ case "imul":
++ mh = JSType.MUL_EXACT.methodHandle();
++ break;
++ case "idiv":
++ mh = JSType.DIV_EXACT.methodHandle();
++ break;
++ case "irem":
++ mh = JSType.REM_EXACT.methodHandle();
++ break;
++ case "ineg":
++ mh = JSType.NEGATE_EXACT.methodHandle();
++ break;
++ case "ladd":
++ mh = JSType.ADD_EXACT_LONG.methodHandle();
++ break;
++ case "lsub":
++ mh = JSType.SUB_EXACT_LONG.methodHandle();
++ break;
++ case "lmul":
++ mh = JSType.MUL_EXACT_LONG.methodHandle();
++ break;
++ case "ldiv":
++ mh = JSType.DIV_EXACT_LONG.methodHandle();
++ break;
++ case "lrem":
++ mh = JSType.REM_EXACT_LONG.methodHandle();
++ break;
++ case "lneg":
++ mh = JSType.NEGATE_EXACT_LONG.methodHandle();
++ break;
++ default:
++ throw new AssertionError("unsupported math intrinsic");
++ }
++ return new ConstantCallSite(MH.insertArguments(mh, mh.type().parameterCount() - 1, programPoint));
++ }
++
++ /**
+ * Returns a dynamic invoker for a specified dynamic operation using the public lookup. You can use this method to
+ * create a method handle that when invoked acts completely as if it were a Nashorn-linked call site. An overview of
+ * available dynamic operations can be found in the
+@@ -250,6 +378,20 @@
+
+ /**
+ * Returns a dynamic invoker for a specified dynamic operation using the public lookup. Similar to
++ * {@link #createDynamicInvoker(String, Class, Class...)} but with an additional parameter to
++ * set the call site flags of the dynamic invoker.
++ * @param opDesc Dynalink dynamic operation descriptor.
++ * @param flags the call site flags for the operation
++ * @param rtype the return type for the operation
++ * @param ptypes the parameter types for the operation
++ * @return MethodHandle for invoking the operation.
++ */
++ public static MethodHandle createDynamicInvoker(final String opDesc, final int flags, final Class<?> rtype, final Class<?>... ptypes) {
++ return bootstrap(MethodHandles.publicLookup(), opDesc, MethodType.methodType(rtype, ptypes), flags).dynamicInvoker();
++ }
++
++ /**
++ * Returns a dynamic invoker for a specified dynamic operation using the public lookup. Similar to
+ * {@link #createDynamicInvoker(String, Class, Class...)} but with return and parameter types composed into a
+ * method type in the signature. See the discussion of that method for details.
+ * @param opDesc Dynalink dynamic operation descriptor.
+@@ -261,14 +403,22 @@
+ }
+
+ /**
+- * Binds a bean dynamic method (returned by invoking {@code dyn:getMethod} on an object linked with
+- * {@code BeansLinker} to a receiver.
+- * @param dynamicMethod the dynamic method to bind
++ * Binds any object Nashorn can use as a [[Callable]] to a receiver and optionally arguments.
++ * @param callable the callable to bind
+ * @param boundThis the bound "this" value.
+- * @return a bound dynamic method.
++ * @param boundArgs the bound arguments. Can be either null or empty array to signify no arguments are bound.
++ * @return a bound callable.
++ * @throws ECMAException with {@code TypeError} if the object is not a callable.
+ */
+- public static Object bindDynamicMethod(Object dynamicMethod, Object boundThis) {
+- return new BoundDynamicMethod(dynamicMethod, boundThis);
++ public static Object bindCallable(final Object callable, final Object boundThis, final Object[] boundArgs) {
++ if (callable instanceof ScriptFunctionImpl) {
++ return ((ScriptFunctionImpl)callable).makeBoundFunction(boundThis, boundArgs);
++ } else if (callable instanceof BoundCallable) {
++ return ((BoundCallable)callable).bind(boundArgs);
++ } else if (isCallable(callable)) {
++ return new BoundCallable(callable, boundThis, boundArgs);
++ }
++ throw notFunction(callable);
+ }
+
+ /**
+@@ -288,7 +438,7 @@
+ * @param clazz the class being tested
+ * @param isStatic is access checked for static members (or instance members)
+ */
+- public static void checkReflectionAccess(Class<?> clazz, boolean isStatic) {
++ public static void checkReflectionAccess(final Class<?> clazz, final boolean isStatic) {
+ ReflectionCheckLinker.checkReflectionAccess(clazz, isStatic);
+ }
+
+@@ -307,16 +457,43 @@
+ /**
+ * Takes a guarded invocation, and ensures its method and guard conform to the type of the call descriptor, using
+ * all type conversions allowed by the linker's services. This method is used by Nashorn's linkers as a last step
+- * before returning guarded invocations to the callers. Most of the code used to produce the guarded invocations
+- * does not make an effort to coordinate types of the methods, and so a final type adjustment before a guarded
+- * invocation is returned is the responsibility of the linkers themselves.
++ * before returning guarded invocations. Most of the code used to produce the guarded invocations does not make an
++ * effort to coordinate types of the methods, and so a final type adjustment before a guarded invocation is returned
++ * to the aggregating linker is the responsibility of the linkers themselves.
+ * @param inv the guarded invocation that needs to be type-converted. Can be null.
+ * @param linkerServices the linker services object providing the type conversions.
+ * @param desc the call site descriptor to whose method type the invocation needs to conform.
+ * @return the type-converted guarded invocation. If input is null, null is returned. If the input invocation
+ * already conforms to the requested type, it is returned unchanged.
+ */
+- static GuardedInvocation asType(final GuardedInvocation inv, final LinkerServices linkerServices, final CallSiteDescriptor desc) {
+- return inv == null ? null : inv.asType(linkerServices, desc.getMethodType());
++ static GuardedInvocation asTypeSafeReturn(final GuardedInvocation inv, final LinkerServices linkerServices, final CallSiteDescriptor desc) {
++ return inv == null ? null : inv.asTypeSafeReturn(linkerServices, desc.getMethodType());
++ }
++
++ /**
++ * Adapts the return type of the method handle with {@code explicitCastArguments} when it is an unboxing
++ * conversion. This will ensure that nulls are unwrapped to false or 0.
++ * @param target the target method handle
++ * @param newType the desired new type. Note that this method does not adapt the method handle completely to the
++ * new type, it only adapts the return type; this is allowed as per
++ * {@link DynamicLinkerFactory#setAutoConversionStrategy(MethodTypeConversionStrategy)}, which is what this method
++ * is used for.
++ * @return the method handle with adapted return type, if it required an unboxing conversion.
++ */
++ private static MethodHandle unboxReturnType(final MethodHandle target, final MethodType newType) {
++ final MethodType targetType = target.type();
++ final Class<?> oldReturnType = targetType.returnType();
++ final Class<?> newReturnType = newType.returnType();
++ if (TypeUtilities.isWrapperType(oldReturnType)) {
++ if (newReturnType.isPrimitive()) {
++ // The contract of setAutoConversionStrategy is such that the difference between newType and targetType
++ // can only be JLS method invocation conversions.
++ assert TypeUtilities.isMethodInvocationConvertible(oldReturnType, newReturnType);
++ return MethodHandles.explicitCastArguments(target, targetType.changeReturnType(newReturnType));
++ }
++ } else if (oldReturnType == void.class && newReturnType == Object.class) {
++ return MethodHandles.filterReturnValue(target, VOID_TO_OBJECT);
++ }
++ return target;
+ }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/BoundCallable.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,96 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.linker;
++
++import java.util.Arrays;
++import jdk.nashorn.internal.runtime.ScriptRuntime;
++
++/**
++ * Represents a Nashorn callable bound to a receiver and optionally arguments. Note that objects of this class
++ * are just the tuples of a callable and a bound this and arguments, without any behavior. All the behavior is
++ * defined in the {@code BoundCallableLinker}.
++ */
++public final class BoundCallable {
++ private final Object callable;
++ private final Object boundThis;
++ private final Object[] boundArgs;
++
++ BoundCallable(final Object callable, final Object boundThis, final Object[] boundArgs) {
++ this.callable = callable;
++ this.boundThis = boundThis;
++ this.boundArgs = isEmptyArray(boundArgs) ? ScriptRuntime.EMPTY_ARRAY : boundArgs.clone();
++ }
++
++ private BoundCallable(final BoundCallable original, final Object[] extraBoundArgs) {
++ this.callable = original.callable;
++ this.boundThis = original.boundThis;
++ this.boundArgs = original.concatenateBoundArgs(extraBoundArgs);
++ }
++
++ Object getCallable() {
++ return callable;
++ }
++
++ Object getBoundThis() {
++ return boundThis;
++ }
++
++ Object[] getBoundArgs() {
++ return boundArgs;
++ }
++
++ BoundCallable bind(final Object[] extraBoundArgs) {
++ if (isEmptyArray(extraBoundArgs)) {
++ return this;
++ }
++ return new BoundCallable(this, extraBoundArgs);
++ }
++
++ private Object[] concatenateBoundArgs(final Object[] extraBoundArgs) {
++ if (boundArgs.length == 0) {
++ return extraBoundArgs.clone();
++ }
++ final int origBoundArgsLen = boundArgs.length;
++ final int extraBoundArgsLen = extraBoundArgs.length;
++ final Object[] newBoundArgs = new Object[origBoundArgsLen + extraBoundArgsLen];
++ System.arraycopy(boundArgs, 0, newBoundArgs, 0, origBoundArgsLen);
++ System.arraycopy(extraBoundArgs, 0, newBoundArgs, origBoundArgsLen, extraBoundArgsLen);
++ return newBoundArgs;
++ }
++
++ private static boolean isEmptyArray(final Object[] a) {
++ return a == null || a.length == 0;
++ }
++
++ @Override
++ public String toString() {
++ final StringBuilder b = new StringBuilder(callable.toString()).append(" on ").append(boundThis);
++ if (boundArgs.length != 0) {
++ b.append(" with ").append(Arrays.toString(boundArgs));
++ }
++ return b.toString();
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/BoundCallableLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,132 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.linker;
++
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.lang.invoke.MethodType;
++import java.util.Arrays;
++import jdk.internal.dynalink.CallSiteDescriptor;
++import jdk.internal.dynalink.linker.GuardedInvocation;
++import jdk.internal.dynalink.linker.LinkRequest;
++import jdk.internal.dynalink.linker.LinkerServices;
++import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
++import jdk.internal.dynalink.support.Guards;
++
++/**
++ * Links {@link BoundCallable} objects. Passes through to linker services for linking a callable (for either
++ * "dyn:call" or "dyn:new"), and modifies the returned invocation to deal with the receiver and argument binding.
++ */
++final class BoundCallableLinker implements TypeBasedGuardingDynamicLinker {
++ @Override
++ public boolean canLinkType(final Class<?> type) {
++ return type == BoundCallable.class;
++ }
++
++ @Override
++ public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
++ final Object objBoundCallable = linkRequest.getReceiver();
++ if(!(objBoundCallable instanceof BoundCallable)) {
++ return null;
++ }
++
++ final CallSiteDescriptor descriptor = linkRequest.getCallSiteDescriptor();
++ if (descriptor.getNameTokenCount() < 2 || !"dyn".equals(descriptor.getNameToken(CallSiteDescriptor.SCHEME))) {
++ return null;
++ }
++ final String operation = descriptor.getNameToken(CallSiteDescriptor.OPERATOR);
++ // We need to distinguish "dyn:new" from "dyn:call" because "dyn:call" sites have parameter list of the form
++ // "callee, this, args", while "dyn:call" sites have "callee, args" -- they lack the "this" parameter.
++ final boolean isCall;
++ if ("new".equals(operation)) {
++ isCall = false;
++ } else if ("call".equals(operation)) {
++ isCall = true;
++ } else {
++ // Only dyn:call and dyn:new are supported.
++ return null;
++ }
++ final BoundCallable boundCallable = (BoundCallable)objBoundCallable;
++ final Object callable = boundCallable.getCallable();
++ final Object boundThis = boundCallable.getBoundThis();
++
++ // We need to ask the linker services for a delegate invocation on the target callable.
++
++ // Replace arguments (boundCallable[, this], args) => (callable[, boundThis], boundArgs, args) when delegating
++ final Object[] args = linkRequest.getArguments();
++ final Object[] boundArgs = boundCallable.getBoundArgs();
++ final int argsLen = args.length;
++ final int boundArgsLen = boundArgs.length;
++ final Object[] newArgs = new Object[argsLen + boundArgsLen];
++ newArgs[0] = callable;
++ final int firstArgIndex;
++ if (isCall) {
++ newArgs[1] = boundThis;
++ firstArgIndex = 2;
++ } else {
++ firstArgIndex = 1;
++ }
++ System.arraycopy(boundArgs, 0, newArgs, firstArgIndex, boundArgsLen);
++ System.arraycopy(args, firstArgIndex, newArgs, firstArgIndex + boundArgsLen, argsLen - firstArgIndex);
++
++ // Use R(T0, T1, T2, ...) => R(callable.class, boundThis.class, boundArg0.class, ..., boundArgn.class, T2, ...)
++ // call site type when delegating to underlying linker (for dyn:new, there's no this).
++ final MethodType type = descriptor.getMethodType();
++ // Use R(T0, ...) => R(callable.class, ...)
++ MethodType newMethodType = descriptor.getMethodType().changeParameterType(0, callable.getClass());
++ if (isCall) {
++ // R(callable.class, T1, ...) => R(callable.class, boundThis.class, ...)
++ newMethodType = newMethodType.changeParameterType(1, boundThis.getClass());
++ }
++ // R(callable.class[, boundThis.class], T2, ...) => R(callable.class[, boundThis.class], boundArg0.class, ..., boundArgn.class, T2, ...)
++ for(int i = boundArgs.length; i-- > 0;) {
++ newMethodType = newMethodType.insertParameterTypes(firstArgIndex, boundArgs[i] == null ? Object.class : boundArgs[i].getClass());
++ }
++ final CallSiteDescriptor newDescriptor = descriptor.changeMethodType(newMethodType);
++
++ // Delegate to target's linker
++ final GuardedInvocation inv = linkerServices.getGuardedInvocation(linkRequest.replaceArguments(newDescriptor, newArgs));
++ if(inv == null) {
++ return null;
++ }
++
++ // Bind (callable[, boundThis], boundArgs) to the delegate handle
++ final MethodHandle boundHandle = MethodHandles.insertArguments(inv.getInvocation(), 0,
++ Arrays.copyOf(newArgs, firstArgIndex + boundArgs.length));
++ final Class<?> p0Type = type.parameterType(0);
++ final MethodHandle droppingHandle;
++ if (isCall) {
++ // Ignore incoming boundCallable and this
++ droppingHandle = MethodHandles.dropArguments(boundHandle, 0, p0Type, type.parameterType(1));
++ } else {
++ // Ignore incoming boundCallable
++ droppingHandle = MethodHandles.dropArguments(boundHandle, 0, p0Type);
++ }
++ // Identity guard on boundCallable object
++ final MethodHandle newGuard = Guards.getIdentityGuard(boundCallable);
++ return inv.replaceMethods(droppingHandle, newGuard.asType(newGuard.type().changeParameterType(0, p0Type)));
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethod.java Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,51 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.linker;
+-
+-import jdk.internal.dynalink.beans.BeansLinker;
+-
+-/**
+- * Represents a Dynalink dynamic method bound to a receiver. Note that objects of this class are just the tuples of
+- * a method and a bound this, without any behavior. All the behavior is defined in the {@code BoundDynamicMethodLinker}.
+- */
+-final class BoundDynamicMethod {
+- private final Object dynamicMethod;
+- private final Object boundThis;
+-
+- BoundDynamicMethod(final Object dynamicMethod, final Object boundThis) {
+- assert BeansLinker.isDynamicMethod(dynamicMethod);
+- this.dynamicMethod = dynamicMethod;
+- this.boundThis = boundThis;
+- }
+-
+- Object getDynamicMethod() {
+- return dynamicMethod;
+- }
+-
+- Object getBoundThis() {
+- return boundThis;
+- }
+-}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,91 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.linker;
+-
+-import java.lang.invoke.MethodHandle;
+-import java.lang.invoke.MethodHandles;
+-import java.lang.invoke.MethodType;
+-import jdk.internal.dynalink.CallSiteDescriptor;
+-import jdk.internal.dynalink.beans.BeansLinker;
+-import jdk.internal.dynalink.linker.GuardedInvocation;
+-import jdk.internal.dynalink.linker.LinkRequest;
+-import jdk.internal.dynalink.linker.LinkerServices;
+-import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+-import jdk.internal.dynalink.support.Guards;
+-
+-/**
+- * Links {@code BoundDynamicMethod} objects. Passes through to Dynalink's BeansLinker for linking a dynamic method
+- * (they only respond to "dyn:call"), and modifies the returned invocation to deal with the receiver binding.
+- */
+-final class BoundDynamicMethodLinker implements TypeBasedGuardingDynamicLinker {
+- @Override
+- public boolean canLinkType(Class<?> type) {
+- return type == BoundDynamicMethod.class;
+- }
+-
+- @Override
+- public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) throws Exception {
+- final Object objBoundDynamicMethod = linkRequest.getReceiver();
+- if(!(objBoundDynamicMethod instanceof BoundDynamicMethod)) {
+- return null;
+- }
+-
+- final BoundDynamicMethod boundDynamicMethod = (BoundDynamicMethod)objBoundDynamicMethod;
+- final Object dynamicMethod = boundDynamicMethod.getDynamicMethod();
+- final Object boundThis = boundDynamicMethod.getBoundThis();
+-
+- // Replace arguments (boundDynamicMethod, this, ...) => (dynamicMethod, boundThis, ...) when delegating to
+- // BeansLinker
+- final Object[] args = linkRequest.getArguments();
+- args[0] = dynamicMethod;
+- args[1] = boundThis;
+-
+- // Use R(T0, T1, ...) => R(dynamicMethod.class, boundThis.class, ...) call site type when delegating to
+- // BeansLinker.
+- final CallSiteDescriptor descriptor = linkRequest.getCallSiteDescriptor();
+- final MethodType type = descriptor.getMethodType();
+- final Class<?> dynamicMethodClass = dynamicMethod.getClass();
+- final CallSiteDescriptor newDescriptor = descriptor.changeMethodType(
+- type.changeParameterType(0, dynamicMethodClass).changeParameterType(1, boundThis.getClass()));
+-
+- // Delegate to BeansLinker
+- final GuardedInvocation inv = NashornBeansLinker.getGuardedInvocation(BeansLinker.getLinkerForClass(dynamicMethodClass),
+- linkRequest.replaceArguments(newDescriptor, args), linkerServices);
+- if(inv == null) {
+- return null;
+- }
+-
+- // Bind (dynamicMethod, boundThis) to the handle
+- final MethodHandle boundHandle = MethodHandles.insertArguments(inv.getInvocation(), 0, dynamicMethod, boundThis);
+- final Class<?> p0Type = type.parameterType(0);
+- // Ignore incoming (boundDynamicMethod, this)
+- final MethodHandle droppingHandle = MethodHandles.dropArguments(boundHandle, 0, p0Type, type.parameterType(1));
+- // Identity guard on boundDynamicMethod object
+- final MethodHandle newGuard = Guards.getIdentityGuard(boundDynamicMethod);
+-
+- return inv.replaceMethods(droppingHandle, newGuard.asType(newGuard.type().changeParameterType(0, p0Type)));
+- }
+-}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/BrowserJSObjectLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,225 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.linker;
++
++import static jdk.nashorn.internal.runtime.linker.BrowserJSObjectLinker.JSObjectHandles.JSOBJECT_GETMEMBER;
++import static jdk.nashorn.internal.runtime.linker.BrowserJSObjectLinker.JSObjectHandles.JSOBJECT_GETSLOT;
++import static jdk.nashorn.internal.runtime.linker.BrowserJSObjectLinker.JSObjectHandles.JSOBJECT_SETMEMBER;
++import static jdk.nashorn.internal.runtime.linker.BrowserJSObjectLinker.JSObjectHandles.JSOBJECT_SETSLOT;
++import static jdk.nashorn.internal.runtime.linker.BrowserJSObjectLinker.JSObjectHandles.JSOBJECT_CALL;
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import jdk.internal.dynalink.CallSiteDescriptor;
++import jdk.internal.dynalink.linker.GuardedInvocation;
++import jdk.internal.dynalink.linker.LinkRequest;
++import jdk.internal.dynalink.linker.LinkerServices;
++import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
++import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
++import jdk.nashorn.internal.lookup.MethodHandleFactory;
++import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
++import jdk.nashorn.internal.runtime.JSType;
++
++/**
++ * A Dynalink linker to handle web browser built-in JS (DOM etc.) objects.
++ */
++final class BrowserJSObjectLinker implements TypeBasedGuardingDynamicLinker {
++ private static final ClassLoader myLoader = BrowserJSObjectLinker.class.getClassLoader();
++ private static final String JSOBJECT_CLASS = "netscape.javascript.JSObject";
++ // not final because this is lazily initialized
++ // when we hit a subclass for the first time.
++ private static volatile Class<?> jsObjectClass;
++ private final NashornBeansLinker nashornBeansLinker;
++
++ BrowserJSObjectLinker(final NashornBeansLinker nashornBeansLinker) {
++ this.nashornBeansLinker = nashornBeansLinker;
++ }
++
++ @Override
++ public boolean canLinkType(final Class<?> type) {
++ return canLinkTypeStatic(type);
++ }
++
++ static boolean canLinkTypeStatic(final Class<?> type) {
++ if (jsObjectClass != null && jsObjectClass.isAssignableFrom(type)) {
++ return true;
++ }
++
++ // check if this class is a subclass of JSObject
++ Class<?> clazz = type;
++ while (clazz != null) {
++ if (clazz.getClassLoader() == myLoader &&
++ clazz.getName().equals(JSOBJECT_CLASS)) {
++ jsObjectClass = clazz;
++ return true;
++ }
++ clazz = clazz.getSuperclass();
++ }
++
++ return false;
++ }
++
++ private static void checkJSObjectClass() {
++ assert jsObjectClass != null : JSOBJECT_CLASS + " not found!";
++ }
++
++ @Override
++ public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception {
++ final LinkRequest requestWithoutContext = request.withoutRuntimeContext(); // Nashorn has no runtime context
++ final Object self = requestWithoutContext.getReceiver();
++ final CallSiteDescriptor desc = requestWithoutContext.getCallSiteDescriptor();
++ checkJSObjectClass();
++
++ if (desc.getNameTokenCount() < 2 || !"dyn".equals(desc.getNameToken(CallSiteDescriptor.SCHEME))) {
++ // We only support standard "dyn:*[:*]" operations
++ return null;
++ }
++
++ final GuardedInvocation inv;
++ if (jsObjectClass.isInstance(self)) {
++ inv = lookup(desc, request, linkerServices);
++ } else {
++ throw new AssertionError(); // Should never reach here.
++ }
++
++ return Bootstrap.asTypeSafeReturn(inv, linkerServices, desc);
++ }
++
++ private GuardedInvocation lookup(final CallSiteDescriptor desc, final LinkRequest request, final LinkerServices linkerServices) throws Exception {
++ final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
++ final int c = desc.getNameTokenCount();
++
++ switch (operator) {
++ case "getProp":
++ case "getElem":
++ case "getMethod":
++ if (c > 2) {
++ return findGetMethod(desc);
++ }
++ // For indexed get, we want GuardedInvocation from beans linker and pass it.
++ // BrowserJSObjectLinker.get uses this fallback getter for explicit signature method access.
++ return findGetIndexMethod(nashornBeansLinker.getGuardedInvocation(request, linkerServices));
++ case "setProp":
++ case "setElem":
++ return c > 2 ? findSetMethod(desc) : findSetIndexMethod();
++ case "call":
++ return findCallMethod(desc);
++ default:
++ return null;
++ }
++ }
++
++ private static GuardedInvocation findGetMethod(final CallSiteDescriptor desc) {
++ final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
++ final MethodHandle getter = MH.insertArguments(JSOBJECT_GETMEMBER, 1, name);
++ return new GuardedInvocation(getter, IS_JSOBJECT_GUARD);
++ }
++
++ private static GuardedInvocation findGetIndexMethod(final GuardedInvocation inv) {
++ final MethodHandle getter = MH.insertArguments(JSOBJECTLINKER_GET, 0, inv.getInvocation());
++ return inv.replaceMethods(getter, inv.getGuard());
++ }
++
++ private static GuardedInvocation findSetMethod(final CallSiteDescriptor desc) {
++ final MethodHandle getter = MH.insertArguments(JSOBJECT_SETMEMBER, 1, desc.getNameToken(2));
++ return new GuardedInvocation(getter, IS_JSOBJECT_GUARD);
++ }
++
++ private static GuardedInvocation findSetIndexMethod() {
++ return new GuardedInvocation(JSOBJECTLINKER_PUT, IS_JSOBJECT_GUARD);
++ }
++
++ private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc) {
++ final MethodHandle call = MH.insertArguments(JSOBJECT_CALL, 1, "call");
++ return new GuardedInvocation(MH.asCollector(call, Object[].class, desc.getMethodType().parameterCount() - 1), IS_JSOBJECT_GUARD);
++ }
++
++ @SuppressWarnings("unused")
++ private static boolean isJSObject(final Object self) {
++ return jsObjectClass.isInstance(self);
++ }
++
++ @SuppressWarnings("unused")
++ private static Object get(final MethodHandle fallback, final Object jsobj, final Object key) throws Throwable {
++ if (key instanceof Integer) {
++ return JSOBJECT_GETSLOT.invokeExact(jsobj, (int)key);
++ } else if (key instanceof Number) {
++ final int index = getIndex((Number)key);
++ if (index > -1) {
++ return JSOBJECT_GETSLOT.invokeExact(jsobj, index);
++ }
++ } else if (key instanceof String) {
++ final String name = (String)key;
++ if (name.indexOf('(') != -1) {
++ return fallback.invokeExact(jsobj, key);
++ }
++ return JSOBJECT_GETMEMBER.invokeExact(jsobj, (String)key);
++ }
++ return null;
++ }
++
++ @SuppressWarnings("unused")
++ private static void put(final Object jsobj, final Object key, final Object value) throws Throwable {
++ if (key instanceof Integer) {
++ JSOBJECT_SETSLOT.invokeExact(jsobj, (int)key, value);
++ } else if (key instanceof Number) {
++ JSOBJECT_SETSLOT.invokeExact(jsobj, getIndex((Number)key), value);
++ } else if (key instanceof String) {
++ JSOBJECT_SETMEMBER.invokeExact(jsobj, (String)key, value);
++ }
++ }
++
++ private static int getIndex(final Number n) {
++ final double value = n.doubleValue();
++ return JSType.isRepresentableAsInt(value) ? (int)value : -1;
++ }
++
++ private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();
++ // method handles of the current class
++ private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH_S("isJSObject", boolean.class, Object.class);
++ private static final MethodHandle JSOBJECTLINKER_GET = findOwnMH_S("get", Object.class, MethodHandle.class, Object.class, Object.class);
++ private static final MethodHandle JSOBJECTLINKER_PUT = findOwnMH_S("put", Void.TYPE, Object.class, Object.class, Object.class);
++
++ private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
++ return MH.findStatic(MethodHandles.lookup(), BrowserJSObjectLinker.class, name, MH.type(rtype, types));
++ }
++
++ // method handles of netscape.javascript.JSObject class
++ // These are in separate class as we lazily initialize these
++ // method handles when we hit a subclass of JSObject first time.
++ static class JSObjectHandles {
++ // method handles of JSObject class
++ static final MethodHandle JSOBJECT_GETMEMBER = findJSObjectMH_V("getMember", Object.class, String.class).asType(MH.type(Object.class, Object.class, String.class));
++ static final MethodHandle JSOBJECT_GETSLOT = findJSObjectMH_V("getSlot", Object.class, int.class).asType(MH.type(Object.class, Object.class, int.class));
++ static final MethodHandle JSOBJECT_SETMEMBER = findJSObjectMH_V("setMember", Void.TYPE, String.class, Object.class).asType(MH.type(Void.TYPE, Object.class, String.class, Object.class));
++ static final MethodHandle JSOBJECT_SETSLOT = findJSObjectMH_V("setSlot", Void.TYPE, int.class, Object.class).asType(MH.type(Void.TYPE, Object.class, int.class, Object.class));
++ static final MethodHandle JSOBJECT_CALL = findJSObjectMH_V("call", Object.class, String.class, Object[].class).asType(MH.type(Object.class, Object.class, String.class, Object[].class));
++
++ private static MethodHandle findJSObjectMH_V(final String name, final Class<?> rtype, final Class<?>... types) {
++ checkJSObjectClass();
++ return MH.findVirtual(MethodHandles.publicLookup(), jsObjectClass, name, MH.type(rtype, types));
++ }
++ }
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/ClassAndLoader.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/ClassAndLoader.java Wed Feb 04 12:14:47 2015 -0800
+@@ -75,7 +75,7 @@
+ return representativeClass;
+ }
+
+- boolean canSee(ClassAndLoader other) {
++ boolean canSee(final ClassAndLoader other) {
+ try {
+ final Class<?> otherClass = other.getRepresentativeClass();
+ return Class.forName(otherClass.getName(), false, getLoader()) == otherClass;
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java Wed Feb 04 12:14:47 2015 -0800
+@@ -90,7 +90,7 @@
+ if(plength == 0) {
+ finalPtypes = new Class<?>[] { Object.class, targetClass };
+ } else {
+- finalPtypes = new Class[plength + 2];
++ finalPtypes = new Class<?>[plength + 2];
+ finalPtypes[0] = Object.class;
+ finalPtypes[1] = targetClass;
+ System.arraycopy(ptypes, 0, finalPtypes, 2, plength);
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -81,7 +81,7 @@
+
+ final GuardedInvocation inv;
+ if (self instanceof JSObject) {
+- inv = lookup(desc);
++ inv = lookup(desc, request, linkerServices);
+ } else if (self instanceof Map || self instanceof Bindings) {
+ // guard to make sure the Map or Bindings does not turn into JSObject later!
+ final GuardedInvocation beanInv = nashornBeansLinker.getGuardedInvocation(request, linkerServices);
+@@ -91,7 +91,7 @@
+ throw new AssertionError(); // Should never reach here.
+ }
+
+- return Bootstrap.asType(inv, linkerServices, desc);
++ return Bootstrap.asTypeSafeReturn(inv, linkerServices, desc);
+ }
+
+ @Override
+@@ -110,14 +110,20 @@
+ }
+
+
+- private static GuardedInvocation lookup(final CallSiteDescriptor desc) {
++ private GuardedInvocation lookup(final CallSiteDescriptor desc, final LinkRequest request, final LinkerServices linkerServices) throws Exception {
+ final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
+ final int c = desc.getNameTokenCount();
++
+ switch (operator) {
+ case "getProp":
+ case "getElem":
+ case "getMethod":
+- return c > 2 ? findGetMethod(desc) : findGetIndexMethod();
++ if (c > 2) {
++ return findGetMethod(desc);
++ }
++ // For indexed get, we want get GuardedInvocation beans linker and pass it.
++ // JSObjectLinker.get uses this fallback getter for explicit signature method access.
++ return findGetIndexMethod(nashornBeansLinker.getGuardedInvocation(request, linkerServices));
+ case "setProp":
+ case "setElem":
+ return c > 2 ? findSetMethod(desc) : findSetIndexMethod();
+@@ -131,31 +137,37 @@
+ }
+
+ private static GuardedInvocation findGetMethod(final CallSiteDescriptor desc) {
+- final MethodHandle getter = MH.insertArguments(JSOBJECT_GETMEMBER, 1, desc.getNameToken(2));
+- return new GuardedInvocation(getter, null, IS_JSOBJECT_GUARD);
++ final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
++ final MethodHandle getter = MH.insertArguments(JSOBJECT_GETMEMBER, 1, name);
++ return new GuardedInvocation(getter, IS_JSOBJECT_GUARD);
+ }
+
+- private static GuardedInvocation findGetIndexMethod() {
+- return new GuardedInvocation(JSOBJECTLINKER_GET, null, IS_JSOBJECT_GUARD);
++ private static GuardedInvocation findGetIndexMethod(final GuardedInvocation inv) {
++ final MethodHandle getter = MH.insertArguments(JSOBJECTLINKER_GET, 0, inv.getInvocation());
++ return inv.replaceMethods(getter, inv.getGuard());
+ }
+
+ private static GuardedInvocation findSetMethod(final CallSiteDescriptor desc) {
+ final MethodHandle getter = MH.insertArguments(JSOBJECT_SETMEMBER, 1, desc.getNameToken(2));
+- return new GuardedInvocation(getter, null, IS_JSOBJECT_GUARD);
++ return new GuardedInvocation(getter, IS_JSOBJECT_GUARD);
+ }
+
+ private static GuardedInvocation findSetIndexMethod() {
+- return new GuardedInvocation(JSOBJECTLINKER_PUT, null, IS_JSOBJECT_GUARD);
++ return new GuardedInvocation(JSOBJECTLINKER_PUT, IS_JSOBJECT_GUARD);
+ }
+
+ private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc) {
+- final MethodHandle func = MH.asCollector(JSOBJECT_CALL, Object[].class, desc.getMethodType().parameterCount() - 2);
+- return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD);
++ // TODO: if call site is already a vararg, don't do asCollector
++ MethodHandle mh = JSOBJECT_CALL;
++ if (NashornCallSiteDescriptor.isApplyToCall(desc)) {
++ mh = MH.insertArguments(JSOBJECT_CALL_TO_APPLY, 0, JSOBJECT_CALL);
++ }
++ return new GuardedInvocation(MH.asCollector(mh, Object[].class, desc.getMethodType().parameterCount() - 2), IS_JSOBJECT_GUARD);
+ }
+
+ private static GuardedInvocation findNewMethod(final CallSiteDescriptor desc) {
+ final MethodHandle func = MH.asCollector(JSOBJECT_NEW, Object[].class, desc.getMethodType().parameterCount() - 1);
+- return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD);
++ return new GuardedInvocation(func, IS_JSOBJECT_GUARD);
+ }
+
+ @SuppressWarnings("unused")
+@@ -164,7 +176,8 @@
+ }
+
+ @SuppressWarnings("unused")
+- private static Object get(final Object jsobj, final Object key) {
++ private static Object get(final MethodHandle fallback, final Object jsobj, final Object key)
++ throws Throwable {
+ if (key instanceof Integer) {
+ return ((JSObject)jsobj).getSlot((Integer)key);
+ } else if (key instanceof Number) {
+@@ -173,7 +186,12 @@
+ return ((JSObject)jsobj).getSlot(index);
+ }
+ } else if (key instanceof String) {
+- return ((JSObject)jsobj).getMember((String)key);
++ final String name = (String)key;
++ // get with method name and signature. delegate it to beans linker!
++ if (name.indexOf('(') != -1) {
++ return fallback.invokeExact(jsobj, key);
++ }
++ return ((JSObject)jsobj).getMember(name);
+ }
+ return null;
+ }
+@@ -195,8 +213,8 @@
+ }
+
+ @SuppressWarnings("unused")
+- private static long toInt64(final JSObject obj) {
+- return JSType.toInt64(toNumber(obj));
++ private static long toLong(final JSObject obj) {
++ return JSType.toLong(toNumber(obj));
+ }
+
+ private static double toNumber(final JSObject obj) {
+@@ -213,41 +231,48 @@
+ return JSType.isRepresentableAsInt(value) ? (int)value : -1;
+ }
+
++ @SuppressWarnings("unused")
++ private static Object callToApply(final MethodHandle mh, final JSObject obj, final Object thiz, final Object... args) {
++ assert args.length >= 2;
++ final Object receiver = args[0];
++ final Object[] arguments = new Object[args.length - 1];
++ System.arraycopy(args, 1, arguments, 0, arguments.length);
++ try {
++ return mh.invokeExact(obj, thiz, new Object[] { receiver, arguments });
++ } catch (final RuntimeException | Error e) {
++ throw e;
++ } catch (final Throwable e) {
++ throw new RuntimeException(e);
++ }
++ }
++
+ private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();
+
+ // method handles of the current class
+- private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH("isJSObject", boolean.class, Object.class);
+- private static final MethodHandle JSOBJECTLINKER_GET = findOwnMH("get", Object.class, Object.class, Object.class);
+- private static final MethodHandle JSOBJECTLINKER_PUT = findOwnMH("put", Void.TYPE, Object.class, Object.class, Object.class);
++ private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH_S("isJSObject", boolean.class, Object.class);
++ private static final MethodHandle JSOBJECTLINKER_GET = findOwnMH_S("get", Object.class, MethodHandle.class, Object.class, Object.class);
++ private static final MethodHandle JSOBJECTLINKER_PUT = findOwnMH_S("put", Void.TYPE, Object.class, Object.class, Object.class);
+
+ // method handles of JSObject class
+- private static final MethodHandle JSOBJECT_GETMEMBER = findJSObjectMH("getMember", Object.class, String.class);
+- private static final MethodHandle JSOBJECT_SETMEMBER = findJSObjectMH("setMember", Void.TYPE, String.class, Object.class);
+- private static final MethodHandle JSOBJECT_CALL = findJSObjectMH("call", Object.class, Object.class, Object[].class);
+- private static final MethodHandle JSOBJECT_NEW = findJSObjectMH("newObject", Object.class, Object[].class);
++ private static final MethodHandle JSOBJECT_GETMEMBER = findJSObjectMH_V("getMember", Object.class, String.class);
++ private static final MethodHandle JSOBJECT_SETMEMBER = findJSObjectMH_V("setMember", Void.TYPE, String.class, Object.class);
++ private static final MethodHandle JSOBJECT_CALL = findJSObjectMH_V("call", Object.class, Object.class, Object[].class);
++ private static final MethodHandle JSOBJECT_CALL_TO_APPLY = findOwnMH_S("callToApply", Object.class, MethodHandle.class, JSObject.class, Object.class, Object[].class);
++ private static final MethodHandle JSOBJECT_NEW = findJSObjectMH_V("newObject", Object.class, Object[].class);
+
+ private static final Map<Class<?>, MethodHandle> CONVERTERS = new HashMap<>();
+ static {
+- CONVERTERS.put(boolean.class, findOwnMH("toBoolean", boolean.class, JSObject.class));
+- CONVERTERS.put(int.class, findOwnMH("toInt32", int.class, JSObject.class));
+- CONVERTERS.put(long.class, findOwnMH("toInt64", long.class, JSObject.class));
+- CONVERTERS.put(double.class, findOwnMH("toNumber", double.class, JSObject.class));
++ CONVERTERS.put(boolean.class, findOwnMH_S("toBoolean", boolean.class, JSObject.class));
++ CONVERTERS.put(int.class, findOwnMH_S("toInt32", int.class, JSObject.class));
++ CONVERTERS.put(long.class, findOwnMH_S("toLong", long.class, JSObject.class));
++ CONVERTERS.put(double.class, findOwnMH_S("toNumber", double.class, JSObject.class));
+ }
+
+- private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+- return findMH(name, JSObjectLinker.class, rtype, types);
++ private static MethodHandle findJSObjectMH_V(final String name, final Class<?> rtype, final Class<?>... types) {
++ return MH.findVirtual(MethodHandles.lookup(), JSObject.class, name, MH.type(rtype, types));
+ }
+
+- private static MethodHandle findJSObjectMH(final String name, final Class<?> rtype, final Class<?>... types) {
+- return findMH(name, JSObject.class, rtype, types);
+- }
+-
+- private static MethodHandle findMH(final String name, final Class<?> target, final Class<?> rtype, final Class<?>... types) {
+- final MethodType mt = MH.type(rtype, types);
+- try {
+- return MH.findStatic(MethodHandles.lookup(), target, name, mt);
+- } catch (final MethodHandleFactory.LookupException e) {
+- return MH.findVirtual(MethodHandles.lookup(), target, name, mt);
+- }
++ private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
++ return MH.findStatic(MethodHandles.lookup(), JSObjectLinker.class, name, MH.type(rtype, types));
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -56,7 +56,9 @@
+ import java.util.Collection;
+ import java.util.HashSet;
+ import java.util.Iterator;
++import java.util.LinkedHashMap;
+ import java.util.List;
++import java.util.Map;
+ import java.util.Set;
+ import jdk.internal.org.objectweb.asm.ClassWriter;
+ import jdk.internal.org.objectweb.asm.Handle;
+@@ -64,7 +66,9 @@
+ import jdk.internal.org.objectweb.asm.Opcodes;
+ import jdk.internal.org.objectweb.asm.Type;
+ import jdk.internal.org.objectweb.asm.commons.InstructionAdapter;
++import jdk.nashorn.api.scripting.ScriptUtils;
+ import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+ import jdk.nashorn.internal.runtime.linker.AdaptationResult.Outcome;
+@@ -131,9 +135,12 @@
+ * implemented securely.
+ */
+ final class JavaAdapterBytecodeGenerator {
+- static final Type OBJECT_TYPE = Type.getType(Object.class);
++ private static final Type SCRIPTUTILS_TYPE = Type.getType(ScriptUtils.class);
++ private static final Type OBJECT_TYPE = Type.getType(Object.class);
++ private static final Type CLASS_TYPE = Type.getType(Class.class);
+
+ static final String OBJECT_TYPE_NAME = OBJECT_TYPE.getInternalName();
++ static final String SCRIPTUTILS_TYPE_NAME = SCRIPTUTILS_TYPE.getInternalName();
+
+ static final String INIT = "<init>";
+
+@@ -145,6 +152,7 @@
+ static final String SET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, OBJECT_TYPE);
+ static final String VOID_NOARG_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE);
+
++ private static final Type SCRIPT_OBJECT_TYPE = Type.getType(ScriptObject.class);
+ private static final Type SCRIPT_FUNCTION_TYPE = Type.getType(ScriptFunction.class);
+ private static final Type STRING_TYPE = Type.getType(String.class);
+ private static final Type METHOD_TYPE_TYPE = Type.getType(MethodType.class);
+@@ -166,7 +174,12 @@
+
+ private static final String METHOD_HANDLE_TYPE_DESCRIPTOR = METHOD_HANDLE_TYPE.getDescriptor();
+ private static final String GET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(OBJECT_TYPE);
+- private static final String GET_CLASS_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.getType(Class.class));
++ private static final String GET_CLASS_METHOD_DESCRIPTOR = Type.getMethodDescriptor(CLASS_TYPE);
++ private static final String EXPORT_RETURN_VALUE_METHOD_DESCRIPTOR = Type.getMethodDescriptor(OBJECT_TYPE, OBJECT_TYPE);
++ private static final String UNWRAP_METHOD_DESCRIPTOR = Type.getMethodDescriptor(OBJECT_TYPE, OBJECT_TYPE);
++ private static final String GET_CONVERTER_METHOD_DESCRIPTOR = Type.getMethodDescriptor(METHOD_HANDLE_TYPE, CLASS_TYPE);
++ private static final String TO_CHAR_PRIMITIVE_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.CHAR_TYPE, OBJECT_TYPE);
++ private static final String TO_STRING_METHOD_DESCRIPTOR = Type.getMethodDescriptor(STRING_TYPE, OBJECT_TYPE);
+
+ // Package used when the adapter can't be defined in the adaptee's package (either because it's sealed, or because
+ // it's a java.* package.
+@@ -177,6 +190,7 @@
+ private static final int MAX_GENERATED_TYPE_NAME_LENGTH = 255;
+
+ private static final String CLASS_INIT = "<clinit>";
++ static final String CONVERTER_INIT = "<converter-init>";
+
+ // Method name prefix for invoking super-methods
+ static final String SUPER_PREFIX = "super$";
+@@ -206,6 +220,22 @@
+ private boolean autoConvertibleFromFunction = false;
+ private boolean hasExplicitFinalizer = false;
+
++ /**
++ * Names of static fields holding type converter method handles for return value conversion. We are emitting code
++ * for invoking these explicitly after the delegate handle is invoked, instead of doing an asType or
++ * filterReturnValue on the delegate handle, as that would create a new converter handle wrapping the function's
++ * handle for every instance of the adapter, causing the handle.invokeExact() call sites to become megamorphic.
++ */
++ private final Map<Class<?>, String> converterFields = new LinkedHashMap<>();
++
++ /**
++ * Subset of possible return types for all methods; namely, all possible return types of the SAM methods (we
++ * identify SAM types by having all of their abstract methods share a single name, so there can be multiple
++ * overloads with multiple return types. We use this set when emitting the constructor taking a ScriptFunction (the
++ * SAM initializer) to avoid populating converter fields that will never be used by SAM methods.
++ */
++ private final Set<Class<?>> samReturnTypes = new HashSet<>();
++
+ private final ClassWriter cw;
+
+ /**
+@@ -243,6 +273,7 @@
+ gatherMethods(interfaces);
+ samName = abstractMethodNames.size() == 1 ? abstractMethodNames.iterator().next() : null;
+ generateHandleFields();
++ generateConverterFields();
+ if(classOverride) {
+ generateClassInit();
+ }
+@@ -315,6 +346,24 @@
+ }
+ }
+
++ private void generateConverterFields() {
++ final int flags = ACC_PRIVATE | ACC_FINAL | (classOverride ? ACC_STATIC : 0);
++ for (final MethodInfo mi: methodInfos) {
++ final Class<?> returnType = mi.type.returnType();
++ // Handle primitive types, Object, and String specially
++ if(!returnType.isPrimitive() && returnType != Object.class && returnType != String.class) {
++ if(!converterFields.containsKey(returnType)) {
++ final String name = nextName("convert");
++ converterFields.put(returnType, name);
++ if(mi.getName().equals(samName)) {
++ samReturnTypes.add(returnType);
++ }
++ cw.visitField(flags, name, METHOD_HANDLE_TYPE_DESCRIPTOR, null, null).visitEnd();
++ }
++ }
++ }
++ }
++
+ private void generateClassInit() {
+ final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_STATIC, CLASS_INIT,
+ Type.getMethodDescriptor(Type.VOID_TYPE), null, null));
+@@ -334,8 +383,7 @@
+ for (final MethodInfo mi : methodInfos) {
+ if(mi.getName().equals(samName)) {
+ mv.dup();
+- mv.aconst(Type.getMethodType(mi.type.toMethodDescriptorString()));
+- mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", GET_HANDLE_FUNCTION_DESCRIPTOR, false);
++ loadMethodTypeAndGetHandle(mv, mi, GET_HANDLE_FUNCTION_DESCRIPTOR);
+ } else {
+ mv.visitInsn(ACONST_NULL);
+ }
+@@ -351,8 +399,7 @@
+ for (final MethodInfo mi : methodInfos) {
+ mv.dup();
+ mv.aconst(mi.getName());
+- mv.aconst(Type.getMethodType(mi.type.toMethodDescriptorString()));
+- mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", GET_HANDLE_OBJECT_DESCRIPTOR, false);
++ loadMethodTypeAndGetHandle(mv, mi, GET_HANDLE_OBJECT_DESCRIPTOR);
+ mv.putstatic(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
+ }
+
+@@ -363,9 +410,41 @@
+ invokeGetGlobalWithNullCheck(mv);
+ mv.putstatic(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR);
+
++ generateConverterInit(mv, false);
+ endInitMethod(mv);
+ }
+
++ private void generateConverterInit(final InstructionAdapter mv, final boolean samOnly) {
++ assert !samOnly || !classOverride;
++ for(final Map.Entry<Class<?>, String> converterField: converterFields.entrySet()) {
++ final Class<?> returnType = converterField.getKey();
++ if(!classOverride) {
++ mv.visitVarInsn(ALOAD, 0);
++ }
++
++ if(samOnly && !samReturnTypes.contains(returnType)) {
++ mv.visitInsn(ACONST_NULL);
++ } else {
++ mv.aconst(Type.getType(converterField.getKey()));
++ mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getObjectConverter", GET_CONVERTER_METHOD_DESCRIPTOR, false);
++ }
++
++ if(classOverride) {
++ mv.putstatic(generatedClassName, converterField.getValue(), METHOD_HANDLE_TYPE_DESCRIPTOR);
++ } else {
++ mv.putfield(generatedClassName, converterField.getValue(), METHOD_HANDLE_TYPE_DESCRIPTOR);
++ }
++ }
++ }
++
++ private static void loadMethodTypeAndGetHandle(final InstructionAdapter mv, final MethodInfo mi, final String getHandleDescriptor) {
++ // NOTE: we're using generic() here because we'll be linking to the "generic" invoker version of
++ // the functions anyway, so we cut down on megamorphism in the invokeExact() calls in adapter
++ // bodies. Once we start linking to type-specializing invokers, this should be changed.
++ mv.aconst(Type.getMethodType(mi.type.generic().toMethodDescriptorString()));
++ mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", getHandleDescriptor, false);
++ }
++
+ private static void invokeGetGlobalWithNullCheck(final InstructionAdapter mv) {
+ invokeGetGlobal(mv);
+ mv.dup();
+@@ -422,7 +501,7 @@
+ // Invoke super constructor with the same arguments.
+ mv.visitVarInsn(ALOAD, 0);
+ int offset = 1; // First arg is at position 1, after this.
+- for (Type argType: argTypes) {
++ for (final Type argType: argTypes) {
+ mv.load(offset, argType);
+ offset += argType.getSize();
+ }
+@@ -458,8 +537,8 @@
+ final int argLen = originalArgTypes.length;
+ final Type[] newArgTypes = new Type[argLen + 1];
+
+- // Insert ScriptFunction|Object as the last argument to the constructor
+- final Type extraArgumentType = fromFunction ? SCRIPT_FUNCTION_TYPE : OBJECT_TYPE;
++ // Insert ScriptFunction|ScriptObject as the last argument to the constructor
++ final Type extraArgumentType = fromFunction ? SCRIPT_FUNCTION_TYPE : SCRIPT_OBJECT_TYPE;
+ newArgTypes[argLen] = extraArgumentType;
+ System.arraycopy(originalArgTypes, 0, newArgTypes, 0, argLen);
+
+@@ -497,8 +576,7 @@
+ if(!fromFunction) {
+ mv.aconst(mi.getName());
+ }
+- mv.aconst(Type.getMethodType(mi.type.toMethodDescriptorString()));
+- mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", getHandleDescriptor, false);
++ loadMethodTypeAndGetHandle(mv, mi, getHandleDescriptor);
+ }
+ mv.putfield(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
+ }
+@@ -508,6 +586,36 @@
+ invokeGetGlobalWithNullCheck(mv);
+ mv.putfield(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR);
+
++ // Initialize converters
++ generateConverterInit(mv, fromFunction);
++ endInitMethod(mv);
++
++ if (! fromFunction) {
++ newArgTypes[argLen] = OBJECT_TYPE;
++ final InstructionAdapter mv2 = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT,
++ Type.getMethodDescriptor(originalCtorType.getReturnType(), newArgTypes), null, null));
++ generateOverridingConstructorWithObjectParam(mv2, ctor, originalCtorType.getDescriptor());
++ }
++ }
++
++ // Object additional param accepting constructor - generated to handle null and undefined value
++ // for script adapters. This is effectively to throw TypeError on such script adapters. See
++ // JavaAdapterServices.getHandle as well.
++ private void generateOverridingConstructorWithObjectParam(final InstructionAdapter mv, final Constructor<?> ctor, final String ctorDescriptor) {
++ mv.visitCode();
++ mv.visitVarInsn(ALOAD, 0);
++ final Class<?>[] argTypes = ctor.getParameterTypes();
++ int offset = 1; // First arg is at position 1, after this.
++ for (int i = 0; i < argTypes.length; ++i) {
++ final Type argType = Type.getType(argTypes[i]);
++ mv.load(offset, argType);
++ offset += argType.getSize();
++ }
++ mv.invokespecial(superClassName, INIT, ctorDescriptor, false);
++ mv.visitVarInsn(ALOAD, offset);
++ mv.visitInsn(ACONST_NULL);
++ mv.visitInsn(ACONST_NULL);
++ mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", GET_HANDLE_OBJECT_DESCRIPTOR, false);
+ endInitMethod(mv);
+ }
+
+@@ -622,7 +730,8 @@
+
+ final Label handleDefined = new Label();
+
+- final Type asmReturnType = Type.getType(type.returnType());
++ final Class<?> returnType = type.returnType();
++ final Type asmReturnType = Type.getType(returnType);
+
+ // See if we have overriding method handle defined
+ if(classOverride) {
+@@ -632,7 +741,8 @@
+ mv.getfield(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
+ }
+ // stack: [handle]
+- jumpIfNonNullKeepOperand(mv, handleDefined);
++ mv.visitInsn(DUP);
++ mv.visitJumpInsn(IFNONNULL, handleDefined);
+
+ // No handle is available, fall back to default behavior
+ if(Modifier.isAbstract(method.getModifiers())) {
+@@ -642,6 +752,7 @@
+ mv.invokespecial(UNSUPPORTED_OPERATION_TYPE_NAME, INIT, VOID_NOARG_METHOD_DESCRIPTOR, false);
+ mv.athrow();
+ } else {
++ mv.visitInsn(POP);
+ // If the super method is not abstract, delegate to it.
+ emitSuperCall(mv, method.getDeclaringClass(), name, methodDesc);
+ }
+@@ -703,17 +814,20 @@
+ mv.visitVarInsn(ISTORE, globalsDifferVar);
+ // stack: [handle]
+
+- // Load all parameters back on stack for dynamic invocation.
++ // Load all parameters back on stack for dynamic invocation. NOTE: since we're using a generic
++ // Object(Object, Object, ...) type signature for the method, we must box all arguments here.
+ int varOffset = 1;
+ for (final Type t : asmArgTypes) {
+ mv.load(varOffset, t);
++ boxStackTop(mv, t);
+ varOffset += t.getSize();
+ }
+
+ // Invoke the target method handle
+ final Label tryBlockStart = new Label();
+ mv.visitLabel(tryBlockStart);
+- mv.invokevirtual(METHOD_HANDLE_TYPE.getInternalName(), "invokeExact", type.toMethodDescriptorString(), false);
++ emitInvokeExact(mv, type.generic());
++ convertReturnValue(mv, returnType, asmReturnType);
+ final Label tryBlockEnd = new Label();
+ mv.visitLabel(tryBlockEnd);
+ emitFinally(mv, currentGlobalVar, globalsDifferVar);
+@@ -743,7 +857,7 @@
+ mv.visitLabel(methodEnd);
+
+ mv.visitLocalVariable("currentGlobal", GLOBAL_TYPE_DESCRIPTOR, null, setupGlobal, methodEnd, currentGlobalVar);
+- mv.visitLocalVariable("globalsDiffer", Type.INT_TYPE.getDescriptor(), null, setupGlobal, methodEnd, globalsDifferVar);
++ mv.visitLocalVariable("globalsDiffer", Type.BOOLEAN_TYPE.getDescriptor(), null, setupGlobal, methodEnd, globalsDifferVar);
+
+ if(throwableDeclared) {
+ mv.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrowHandler, THROWABLE_TYPE_NAME);
+@@ -759,16 +873,110 @@
+ endMethod(mv);
+ }
+
+- /**
+- * Emits code for jumping to a label if the top stack operand is not null. The operand is kept on the stack if it
+- * is not null (so is available to code at the jump address) and is popped if it is null.
+- * @param mv the instruction adapter being used to emit code
+- * @param label the label to jump to
+- */
+- private static void jumpIfNonNullKeepOperand(final InstructionAdapter mv, final Label label) {
+- mv.visitInsn(DUP);
+- mv.visitJumpInsn(IFNONNULL, label);
+- mv.visitInsn(POP);
++ private void convertReturnValue(final InstructionAdapter mv, final Class<?> returnType, final Type asmReturnType) {
++ switch(asmReturnType.getSort()) {
++ case Type.VOID:
++ mv.pop();
++ break;
++ case Type.BOOLEAN:
++ JSType.TO_BOOLEAN.invoke(mv);
++ break;
++ case Type.BYTE:
++ JSType.TO_INT32.invoke(mv);
++ mv.visitInsn(Opcodes.I2B);
++ break;
++ case Type.SHORT:
++ JSType.TO_INT32.invoke(mv);
++ mv.visitInsn(Opcodes.I2S);
++ break;
++ case Type.CHAR:
++ // JSType doesn't have a TO_CHAR, so we have services supply us one.
++ mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "toCharPrimitive", TO_CHAR_PRIMITIVE_METHOD_DESCRIPTOR, false);
++ break;
++ case Type.INT:
++ JSType.TO_INT32.invoke(mv);
++ break;
++ case Type.LONG:
++ JSType.TO_LONG.invoke(mv);
++ break;
++ case Type.FLOAT:
++ JSType.TO_NUMBER.invoke(mv);
++ mv.visitInsn(Opcodes.D2F);
++ break;
++ case Type.DOUBLE:
++ JSType.TO_NUMBER.invoke(mv);
++ break;
++ default:
++ if(asmReturnType.equals(OBJECT_TYPE)) {
++ // Must hide ConsString (and potentially other internal Nashorn types) from callers
++ mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "exportReturnValue", EXPORT_RETURN_VALUE_METHOD_DESCRIPTOR, false);
++ } else if(asmReturnType.equals(STRING_TYPE)){
++ // Well-known conversion to String. Not using the JSType one as we want to preserve null as null instead
++ // of the string "n,u,l,l".
++ mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "toString", TO_STRING_METHOD_DESCRIPTOR, false);
++ } else {
++ // Invoke converter method handle for everything else. Note that we could have just added an asType or
++ // filterReturnValue to the invoked handle instead, but then every instance would have the function
++ // method handle wrapped in a separate converter method handle, making handle.invokeExact() megamorphic.
++ if(classOverride) {
++ mv.getstatic(generatedClassName, converterFields.get(returnType), METHOD_HANDLE_TYPE_DESCRIPTOR);
++ } else {
++ mv.visitVarInsn(ALOAD, 0);
++ mv.getfield(generatedClassName, converterFields.get(returnType), METHOD_HANDLE_TYPE_DESCRIPTOR);
++ }
++ mv.swap();
++ emitInvokeExact(mv, MethodType.methodType(returnType, Object.class));
++ }
++ }
++ }
++
++ private static void emitInvokeExact(final InstructionAdapter mv, final MethodType type) {
++ mv.invokevirtual(METHOD_HANDLE_TYPE.getInternalName(), "invokeExact", type.toMethodDescriptorString(), false);
++ }
++
++ private static void boxStackTop(final InstructionAdapter mv, final Type t) {
++ switch(t.getSort()) {
++ case Type.BOOLEAN:
++ invokeValueOf(mv, "Boolean", 'Z');
++ break;
++ case Type.BYTE:
++ case Type.SHORT:
++ case Type.INT:
++ // bytes and shorts get boxed as integers
++ invokeValueOf(mv, "Integer", 'I');
++ break;
++ case Type.CHAR:
++ invokeValueOf(mv, "Character", 'C');
++ break;
++ case Type.FLOAT:
++ // floats get boxed as doubles
++ mv.visitInsn(Opcodes.F2D);
++ invokeValueOf(mv, "Double", 'D');
++ break;
++ case Type.LONG:
++ invokeValueOf(mv, "Long", 'J');
++ break;
++ case Type.DOUBLE:
++ invokeValueOf(mv, "Double", 'D');
++ break;
++ case Type.ARRAY:
++ case Type.METHOD:
++ // Already boxed
++ break;
++ case Type.OBJECT:
++ if(t.equals(OBJECT_TYPE)) {
++ mv.invokestatic(SCRIPTUTILS_TYPE_NAME, "unwrap", UNWRAP_METHOD_DESCRIPTOR, false);
++ }
++ break;
++ default:
++ // Not expecting anything else (e.g. VOID)
++ assert false;
++ break;
++ }
++ }
++
++ private static void invokeValueOf(final InstructionAdapter mv, final String boxedType, final char unboxedType) {
++ mv.invokestatic("java/lang/" + boxedType, "valueOf", "(" + unboxedType + ")Ljava/lang/" + boxedType + ";", false);
+ }
+
+ /**
+@@ -805,7 +1013,7 @@
+ }
+ }
+
+- private void generateSuperMethod(MethodInfo mi) {
++ private void generateSuperMethod(final MethodInfo mi) {
+ final Method method = mi.method;
+
+ final String methodDesc = mi.type.toMethodDescriptorString();
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java Wed Feb 04 12:14:47 2015 -0800
+@@ -30,25 +30,34 @@
+ import java.security.PrivilegedAction;
+ import java.security.ProtectionDomain;
+ import java.security.SecureClassLoader;
++import java.util.Arrays;
++import java.util.Collection;
++import java.util.Collections;
++import java.util.HashSet;
+ import jdk.internal.dynalink.beans.StaticClass;
++import jdk.nashorn.internal.codegen.DumpBytecode;
+ import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
++import jdk.nashorn.internal.runtime.ScriptObject;
+
+ /**
+ * This class encapsulates the bytecode of the adapter class and can be used to load it into the JVM as an actual Class.
+ * It can be invoked repeatedly to create multiple adapter classes from the same bytecode; adapter classes that have
+ * class-level overrides must be re-created for every set of such overrides. Note that while this class is named
+ * "class loader", it does not, in fact, extend {@code ClassLoader}, but rather uses them internally. Instances of this
+- * class are normally created by {@link JavaAdapterBytecodeGenerator}.
++ * class are normally created by {@code JavaAdapterBytecodeGenerator}.
+ */
+-@SuppressWarnings("javadoc")
+ final class JavaAdapterClassLoader {
+ private static final AccessControlContext CREATE_LOADER_ACC_CTXT = ClassAndLoader.createPermAccCtxt("createClassLoader");
++ private static final AccessControlContext GET_CONTEXT_ACC_CTXT = ClassAndLoader.createPermAccCtxt(Context.NASHORN_GET_CONTEXT);
++ private static final Collection<String> VISIBLE_INTERNAL_CLASS_NAMES = Collections.unmodifiableCollection(new HashSet<>(
++ Arrays.asList(JavaAdapterServices.class.getName(), ScriptObject.class.getName(), ScriptFunction.class.getName(), JSType.class.getName())));
+
+ private final String className;
+ private final byte[] classBytes;
+
+- JavaAdapterClassLoader(String className, byte[] classBytes) {
++ JavaAdapterClassLoader(final String className, final byte[] classBytes) {
+ this.className = className.replace('/', '.');
+ this.classBytes = classBytes;
+ }
+@@ -94,7 +103,7 @@
+ // loaded by a loader that prevents package.access. If so, it'd throw
+ // SecurityException for nashorn's classes!. For adapter's to work, we
+ // should be able to refer to the few classes it needs in its implementation.
+- if(ScriptFunction.class.getName().equals(name) || JavaAdapterServices.class.getName().equals(name)) {
++ if(VISIBLE_INTERNAL_CLASS_NAMES.contains(name)) {
+ return myLoader.loadClass(name);
+ }
+ throw se;
+@@ -105,6 +114,14 @@
+ protected Class<?> findClass(final String name) throws ClassNotFoundException {
+ if(name.equals(className)) {
+ assert classBytes != null : "what? already cleared .class bytes!!";
++
++ final Context ctx = AccessController.doPrivileged(new PrivilegedAction<Context>() {
++ @Override
++ public Context run() {
++ return Context.getContext();
++ }
++ }, GET_CONTEXT_ACC_CTXT);
++ DumpBytecode.dumpBytecode(ctx.getEnv(), ctx.getLogger(jdk.nashorn.internal.codegen.Compiler.class), classBytes, name);
+ return defineClass(name, classBytes, 0, classBytes.length, protectionDomain);
+ }
+ throw new ClassNotFoundException(name);
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java Wed Feb 04 12:14:47 2015 -0800
+@@ -113,15 +113,15 @@
+ * @throws ECMAException with a TypeError if the adapter class can not be generated because the original class is
+ * final, non-public, or has no public or protected constructors.
+ */
+- public static StaticClass getAdapterClassFor(final Class<?>[] types, ScriptObject classOverrides, final MethodHandles.Lookup lookup) {
++ public static StaticClass getAdapterClassFor(final Class<?>[] types, final ScriptObject classOverrides, final MethodHandles.Lookup lookup) {
+ return getAdapterClassFor(types, classOverrides, getProtectionDomain(lookup));
+ }
+
+- private static StaticClass getAdapterClassFor(final Class<?>[] types, ScriptObject classOverrides, final ProtectionDomain protectionDomain) {
++ private static StaticClass getAdapterClassFor(final Class<?>[] types, final ScriptObject classOverrides, final ProtectionDomain protectionDomain) {
+ assert types != null && types.length > 0;
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+- for (Class<?> type : types) {
++ for (final Class<?> type : types) {
+ // check for restricted package access
+ Context.checkPackageAccess(type);
+ // check for classes, interfaces in reflection
+@@ -163,7 +163,7 @@
+ final StaticClass adapterClass = getAdapterClassFor(new Class<?>[] { targetType }, null, lookup);
+ return MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(
+ NashornCallSiteDescriptor.get(lookup, "dyn:new",
+- MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false,
++ MethodType.methodType(targetType, StaticClass.class, sourceType), 0), null, 0, false,
+ adapterClass, null)).getInvocation(), adapterClass);
+ }
+
+@@ -257,7 +257,7 @@
+ final boolean autoConvertibleFromFunction;
+ final AdaptationResult adaptationResult;
+
+- AdapterInfo(Class<?> superClass, List<Class<?>> interfaces, ClassAndLoader definingLoader) throws AdaptationException {
++ AdapterInfo(final Class<?> superClass, final List<Class<?>> interfaces, final ClassAndLoader definingLoader) throws AdaptationException {
+ this.commonLoader = findCommonLoader(definingLoader);
+ final JavaAdapterBytecodeGenerator gen = new JavaAdapterBytecodeGenerator(superClass, interfaces, commonLoader, false);
+ this.autoConvertibleFromFunction = gen.isAutoConvertibleFromFunction();
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java Wed Feb 04 12:14:47 2015 -0800
+@@ -150,7 +150,7 @@
+ return Context.getGlobal();
+ }
+
+- static void setClassOverrides(ScriptObject overrides) {
++ static void setClassOverrides(final ScriptObject overrides) {
+ classOverrides.set(overrides);
+ }
+
+@@ -183,7 +183,7 @@
+ public ClassLoader run() {
+ return new SecureClassLoader(null) {
+ @Override
+- protected Class<?> findClass(String name) throws ClassNotFoundException {
++ protected Class<?> findClass(final String name) throws ClassNotFoundException {
+ if(name.equals(className)) {
+ return defineClass(name, bytes, 0, bytes.length, new ProtectionDomain(
+ new CodeSource(null, (CodeSigner[])null), new Permissions()));
+@@ -197,8 +197,49 @@
+ try {
+ return MethodHandles.lookup().findStatic(Class.forName(className, true, loader), "invoke",
+ MethodType.methodType(void.class, MethodHandle.class, Object.class));
+- } catch(ReflectiveOperationException e) {
++ } catch(final ReflectiveOperationException e) {
+ throw new AssertionError(e.getMessage(), e);
+ }
+ }
++
++ /**
++ * Returns a method handle used to convert a return value from a delegate method (always Object) to the expected
++ * Java return type.
++ * @param returnType the return type
++ * @return the converter for the expected return type
++ */
++ public static MethodHandle getObjectConverter(final Class<?> returnType) {
++ return Bootstrap.getLinkerServices().getTypeConverter(Object.class, returnType);
++ }
++
++ /**
++ * Invoked when returning Object from an adapted method to filter out internal Nashorn objects that must not be seen
++ * by the callers. Currently only transforms {@code ConsString} into {@code String} and transforms {@code ScriptObject} into {@code ScriptObjectMirror}.
++ * @param obj the return value
++ * @return the filtered return value.
++ */
++ public static Object exportReturnValue(final Object obj) {
++ return NashornBeansLinker.exportArgument(obj, true);
++ }
++
++ /**
++ * Invoked to convert a return value of a delegate function to primitive char. There's no suitable conversion in
++ * {@code JSType}, so we provide our own to adapters.
++ * @param obj the return value.
++ * @return the character value of the return value
++ */
++ public static char toCharPrimitive(final Object obj) {
++ return JavaArgumentConverters.toCharPrimitive(obj);
++ }
++
++ /**
++ * Invoked to convert a return value of a delegate function to String. It is similar to
++ * {@code JSType.toString(Object)}, except it doesn't handle StaticClass specially, and it returns null for null
++ * input instead of the string "null".
++ * @param obj the return value.
++ * @return the String value of the return value
++ */
++ public static String toString(final Object obj) {
++ return JavaArgumentConverters.toString(obj);
++ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java Wed Feb 04 12:14:47 2015 -0800
+@@ -124,34 +124,14 @@
+ return s.charAt(0);
+ }
+
+- @SuppressWarnings("unused")
+- private static char toCharPrimitive(final Object obj0) {
++ static char toCharPrimitive(final Object obj0) {
+ final Character c = toChar(obj0);
+ return c == null ? (char)0 : c;
+ }
+
+- // Almost identical to ScriptRuntime.toString, but doesn't handle StaticClass specially, and it returns null for
+- // null instead of the string "null".
+- private static String toString(final Object obj0) {
+- for (Object obj = obj0; ;) {
+- if (obj == null) {
+- return null;
+- } else if (obj instanceof String) {
+- return (String) obj;
+- } else if (obj instanceof ConsString) {
+- return obj.toString();
+- } else if (obj instanceof Number) {
+- return JSType.toString(((Number)obj).doubleValue());
+- } else if (obj instanceof Boolean) {
+- return ((Boolean) obj).toString();
+- } else if (obj == UNDEFINED) {
+- return "undefined";
+- } else if (obj instanceof ScriptObject) {
+- obj = JSType.toPrimitive(obj, String.class);
+- continue;
+- }
+- throw assertUnexpectedType(obj);
+- }
++ // Almost identical to ScriptRuntime.toString, but returns null for null instead of the string "null".
++ static String toString(final Object obj) {
++ return obj == null ? null : JSType.toString(obj);
+ }
+
+ @SuppressWarnings("unused")
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,7 +27,7 @@
+
+ /**
+ * Represents a an adapter for invoking superclass methods on an adapter instance generated by
+- * {@link JavaAdapterBytecodeGenerator}. Note that objects of this class are just wrappers around the adapter instances,
++ * {@code JavaAdapterBytecodeGenerator}. Note that objects of this class are just wrappers around the adapter instances,
+ * without any behavior. All the behavior is defined in the {@code JavaSuperAdapterLinker}.
+ */
+ class JavaSuperAdapter {
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -42,7 +42,7 @@
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+ /**
+- * A linker for instances of {@link JavaSuperAdapter}. Only links {@code getMethod} calls, by forwarding them to the
++ * A linker for instances of {@code JavaSuperAdapter}. Only links {@code getMethod} calls, by forwarding them to the
+ * bean linker for the adapter class and prepending {@code super$} to method names.
+ *
+ */
+@@ -115,15 +115,15 @@
+
+ final MethodHandle invocation = guardedInv.getInvocation();
+ final MethodType invType = invocation.type();
+- // For invocation typed R(T0, ...) create a dynamic method binder of type R(R, T0)
+- final MethodHandle typedBinder = BIND_DYNAMIC_METHOD.asType(MethodType.methodType(invType.returnType(),
++ // For invocation typed R(T0, ...) create a dynamic method binder of type Object(R, T0)
++ final MethodHandle typedBinder = BIND_DYNAMIC_METHOD.asType(MethodType.methodType(Object.class,
+ invType.returnType(), invType.parameterType(0)));
+- // For invocation typed R(T0, T1, ...) create a dynamic method binder of type R(R, T0, T1, ...)
++ // For invocation typed R(T0, T1, ...) create a dynamic method binder of type Object(R, T0, T1, ...)
+ final MethodHandle droppingBinder = MethodHandles.dropArguments(typedBinder, 2,
+ invType.parameterList().subList(1, invType.parameterCount()));
+ // Finally, fold the invocation into the binder to produce a method handle that will bind every returned
+ // DynamicMethod object from dyn:getMethod calls to the actual receiver
+- // R(R(T0, T1, ...), T0, T1, ...)
++ // Object(R(T0, T1, ...), T0, T1, ...)
+ final MethodHandle bindingInvocation = MethodHandles.foldArguments(droppingBinder, invocation);
+
+ final MethodHandle typedGetAdapter = asFilterType(GET_ADAPTER, 0, invType, type);
+@@ -147,7 +147,7 @@
+ * @param sourceType the source method type for filtering
+ * @return a type adapted filter
+ */
+- private static MethodHandle asFilterType(final MethodHandle filter, int pos, MethodType targetType, MethodType sourceType) {
++ private static MethodHandle asFilterType(final MethodHandle filter, final int pos, final MethodType targetType, final MethodType sourceType) {
+ return filter.asType(MethodType.methodType(targetType.parameterType(pos), sourceType.parameterType(pos)));
+ }
+
+@@ -165,7 +165,7 @@
+ */
+ @SuppressWarnings("unused")
+ private static Object bindDynamicMethod(final Object dynamicMethod, final Object boundThis) {
+- return dynamicMethod == null ? ScriptRuntime.UNDEFINED : Bootstrap.bindDynamicMethod(dynamicMethod, boundThis);
++ return dynamicMethod == null ? ScriptRuntime.UNDEFINED : Bootstrap.bindCallable(dynamicMethod, boundThis, null);
+ }
+
+ /**
+@@ -175,7 +175,7 @@
+ * @return true if the receiver is a super adapter, and its underlying adapter is of the specified class
+ */
+ @SuppressWarnings("unused")
+- private static boolean isAdapterOfClass(Class<?> clazz, Object obj) {
++ private static boolean isAdapterOfClass(final Class<?> clazz, final Object obj) {
+ return obj instanceof JavaSuperAdapter && clazz == (((JavaSuperAdapter)obj).getAdapter()).getClass();
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java Wed Feb 04 12:14:47 2015 -0800
+@@ -46,7 +46,6 @@
+ import jdk.internal.dynalink.ChainedCallSite;
+ import jdk.internal.dynalink.DynamicLinker;
+ import jdk.internal.dynalink.linker.GuardedInvocation;
+-import jdk.nashorn.internal.lookup.MethodHandleFactory;
+ import jdk.nashorn.internal.runtime.Context;
+ import jdk.nashorn.internal.runtime.Debug;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+@@ -63,7 +62,10 @@
+
+ private static final String PROFILEFILE = Options.getStringProperty("nashorn.profilefile", "NashornProfile.txt");
+
+- private static final MethodHandle INCREASE_MISS_COUNTER = findOwnMH("increaseMissCount", Object.class, String.class, Object.class);
++ private static final MethodHandle INCREASE_MISS_COUNTER = MH.findStatic(MethodHandles.lookup(), LinkerCallSite.class, "increaseMissCount", MH.type(Object.class, String.class, Object.class));
++ private static final MethodHandle ON_CATCH_INVALIDATION = MH.findStatic(MethodHandles.lookup(), LinkerCallSite.class, "onCatchInvalidation", MH.type(ChainedCallSite.class, LinkerCallSite.class));
++
++ private int catchInvalidations;
+
+ LinkerCallSite(final NashornCallSiteDescriptor descriptor) {
+ super(descriptor);
+@@ -72,6 +74,34 @@
+ }
+ }
+
++ @Override
++ protected MethodHandle getPruneCatches() {
++ return MH.filterArguments(super.getPruneCatches(), 0, ON_CATCH_INVALIDATION);
++ }
++
++ /**
++ * Action to perform when a catch guard around a callsite triggers. Increases
++ * catch invalidation counter
++ * @param callSite callsite
++ * @return the callsite, so this can be used as argument filter
++ */
++ @SuppressWarnings("unused")
++ private static ChainedCallSite onCatchInvalidation(final LinkerCallSite callSite) {
++ ++callSite.catchInvalidations;
++ return callSite;
++ }
++
++ /**
++ * Get the number of catch invalidations that have happened at this call site so far
++ * @param callSiteToken call site token, unique to the callsite.
++ * @return number of catch invalidations, i.e. thrown exceptions caught by the linker
++ */
++ public static int getCatchInvalidationCount(final Object callSiteToken) {
++ if (callSiteToken instanceof LinkerCallSite) {
++ return ((LinkerCallSite)callSiteToken).catchInvalidations;
++ }
++ return 0;
++ }
+ /**
+ * Construct a new linker call site.
+ * @param name Name of method.
+@@ -79,8 +109,7 @@
+ * @param flags Call site specific flags.
+ * @return New LinkerCallSite.
+ */
+- static LinkerCallSite newLinkerCallSite(final MethodHandles.Lookup lookup, final String name, final MethodType type,
+- final int flags) {
++ static LinkerCallSite newLinkerCallSite(final MethodHandles.Lookup lookup, final String name, final MethodType type, final int flags) {
+ final NashornCallSiteDescriptor desc = NashornCallSiteDescriptor.get(lookup, name, type, flags);
+
+ if (desc.isProfile()) {
+@@ -145,11 +174,10 @@
+ */
+ public static Object increaseMissCount(final String desc, final Object self) {
+ ++missCount;
+- if(r.nextInt(100) < missSamplingPercentage) {
+- AtomicInteger i = missCounts.get(desc);
+- if(i == null) {
+- i = new AtomicInteger(1);
+- missCounts.put(desc, i);
++ if (r.nextInt(100) < missSamplingPercentage) {
++ final AtomicInteger i = missCounts.get(desc);
++ if (i == null) {
++ missCounts.put(desc, new AtomicInteger(1));
+ } else {
+ i.incrementAndGet();
+ }
+@@ -157,14 +185,6 @@
+ return self;
+ }
+
+- private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+- try {
+- return MH.findStatic(MethodHandles.lookup(), LinkerCallSite.class, name, MH.type(rtype, types));
+- } catch (final MethodHandleFactory.LookupException e) {
+- return MH.findVirtual(MethodHandles.lookup(), LinkerCallSite.class, name, MH.type(rtype, types));
+- }
+- }
+-
+ /*
+ * Debugging call sites.
+ */
+@@ -276,7 +296,6 @@
+ }
+
+ static class ProfileDumper implements Runnable {
+- @SuppressWarnings("resource")
+ @Override
+ public void run() {
+ PrintWriter out = null;
+@@ -314,10 +333,11 @@
+ * Debug subclass for LinkerCallSite that allows tracing
+ */
+ private static class TracingLinkerCallSite extends LinkerCallSite {
++ private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+
+- private static final MethodHandle TRACEOBJECT = findOwnMH("traceObject", Object.class, MethodHandle.class, Object[].class);
+- private static final MethodHandle TRACEVOID = findOwnMH("traceVoid", void.class, MethodHandle.class, Object[].class);
+- private static final MethodHandle TRACEMISS = findOwnMH("traceMiss", void.class, String.class, Object[].class);
++ private static final MethodHandle TRACEOBJECT = MH.findVirtual(LOOKUP, TracingLinkerCallSite.class, "traceObject", MH.type(Object.class, MethodHandle.class, Object[].class));
++ private static final MethodHandle TRACEVOID = MH.findVirtual(LOOKUP, TracingLinkerCallSite.class, "traceVoid", MH.type(void.class, MethodHandle.class, Object[].class));
++ private static final MethodHandle TRACEMISS = MH.findVirtual(LOOKUP, TracingLinkerCallSite.class, "traceMiss", MH.type(void.class, String.class, Object[].class));
+
+ TracingLinkerCallSite(final NashornCallSiteDescriptor desc) {
+ super(desc);
+@@ -420,7 +440,7 @@
+ final Object arg = args[i];
+ out.print(", ");
+
+- if (getNashornDescriptor().isTraceScope() || !(arg instanceof ScriptObject && ((ScriptObject)arg).isScope())) {
++ if (!(arg instanceof ScriptObject && ((ScriptObject)arg).isScope())) {
+ printObject(out, arg);
+ } else {
+ out.print("SCOPE");
+@@ -448,7 +468,7 @@
+ *
+ * @throws Throwable if invocation fails or throws exception/error
+ */
+- @SuppressWarnings({"unused", "resource"})
++ @SuppressWarnings("unused")
+ public Object traceObject(final MethodHandle mh, final Object... args) throws Throwable {
+ final PrintWriter out = Context.getCurrentErr();
+ tracePrint(out, "ENTER ", args, null);
+@@ -466,7 +486,7 @@
+ *
+ * @throws Throwable if invocation fails or throws exception/error
+ */
+- @SuppressWarnings({"unused", "resource"})
++ @SuppressWarnings("unused")
+ public void traceVoid(final MethodHandle mh, final Object... args) throws Throwable {
+ final PrintWriter out = Context.getCurrentErr();
+ tracePrint(out, "ENTER ", args, null);
+@@ -486,14 +506,6 @@
+ public void traceMiss(final String desc, final Object... args) throws Throwable {
+ tracePrint(Context.getCurrentErr(), desc, args, null);
+ }
+-
+- private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+- try {
+- return MH.findStatic(MethodHandles.lookup(), TracingLinkerCallSite.class, name, MH.type(rtype, types));
+- } catch (final MethodHandleFactory.LookupException e) {
+- return MH.findVirtual(MethodHandles.lookup(), TracingLinkerCallSite.class, name, MH.type(rtype, types));
+- }
+- }
+ }
+
+ // counters updated in debug mode
+@@ -503,6 +515,11 @@
+ private static final Random r = new Random();
+ private static final int missSamplingPercentage = Options.getIntProperty("nashorn.tcs.miss.samplePercent", 1);
+
++ @Override
++ protected int getMaxChainLength() {
++ return 8;
++ }
++
+ /**
+ * Get the callsite count
+ * @return the count
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,32 +25,101 @@
+
+ package jdk.nashorn.internal.runtime.linker;
+
++import static jdk.nashorn.internal.lookup.Lookup.MH;
++import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
++
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
+ import java.lang.invoke.MethodType;
++import java.lang.reflect.Method;
++import java.lang.reflect.Modifier;
++import jdk.internal.dynalink.CallSiteDescriptor;
+ import jdk.internal.dynalink.beans.BeansLinker;
+ import jdk.internal.dynalink.linker.ConversionComparator.Comparison;
+ import jdk.internal.dynalink.linker.GuardedInvocation;
+ import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+ import jdk.internal.dynalink.linker.LinkRequest;
+ import jdk.internal.dynalink.linker.LinkerServices;
++import jdk.internal.dynalink.support.Guards;
+ import jdk.internal.dynalink.support.Lookup;
++import jdk.nashorn.api.scripting.ScriptUtils;
++import jdk.nashorn.internal.objects.NativeArray;
+ import jdk.nashorn.internal.runtime.ConsString;
++import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.ScriptObject;
++import jdk.nashorn.internal.runtime.ScriptRuntime;
++import jdk.nashorn.internal.runtime.options.Options;
+
+ /**
+ * This linker delegates to a {@code BeansLinker} but passes it a special linker services object that has a modified
+ * {@code asType} method that will ensure that we never pass internal engine objects that should not be externally
+- * observable (currently only ConsString) to Java APIs, but rather that we flatten it into a String. We can't just add
++ * observable (currently ConsString and ScriptObject) to Java APIs, but rather that we flatten it into a String. We can't just add
+ * this functionality as custom converters via {@code GuaardingTypeConverterFactory}, since they are not consulted when
+ * the target method handle parameter signature is {@code Object}.
+ */
+ public class NashornBeansLinker implements GuardingDynamicLinker {
+- private static final MethodHandle EXPORT_ARGUMENT = new Lookup(MethodHandles.lookup()).findOwnStatic("exportArgument", Object.class, Object.class);
++ // System property to control whether to wrap ScriptObject->ScriptObjectMirror for
++ // Object type arguments of Java method calls, field set and array set.
++ private static final boolean MIRROR_ALWAYS = Options.getBooleanProperty("nashorn.mirror.always", true);
++
++ private static final MethodHandle EXPORT_ARGUMENT;
++ private static final MethodHandle EXPORT_NATIVE_ARRAY;
++ private static final MethodHandle EXPORT_SCRIPT_OBJECT;
++ private static final MethodHandle IMPORT_RESULT;
++ private static final MethodHandle FILTER_CONSSTRING;
++
++ static {
++ final Lookup lookup = new Lookup(MethodHandles.lookup());
++ EXPORT_ARGUMENT = lookup.findOwnStatic("exportArgument", Object.class, Object.class);
++ EXPORT_NATIVE_ARRAY = lookup.findOwnStatic("exportNativeArray", Object.class, NativeArray.class);
++ EXPORT_SCRIPT_OBJECT = lookup.findOwnStatic("exportScriptObject", Object.class, ScriptObject.class);
++ IMPORT_RESULT = lookup.findOwnStatic("importResult", Object.class, Object.class);
++ FILTER_CONSSTRING = lookup.findOwnStatic("consStringFilter", Object.class, Object.class);
++ }
++
++ // cache of @FunctionalInterface method of implementor classes
++ private static final ClassValue<Method> FUNCTIONAL_IFACE_METHOD = new ClassValue<Method>() {
++ @Override
++ protected Method computeValue(final Class<?> type) {
++ return findFunctionalInterfaceMethod(type);
++ }
++ };
+
+ private final BeansLinker beansLinker = new BeansLinker();
+
+ @Override
+ public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
++ final Object self = linkRequest.getReceiver();
++ final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
++ if (self instanceof ConsString) {
++ // In order to treat ConsString like a java.lang.String we need a link request with a string receiver.
++ final Object[] arguments = linkRequest.getArguments();
++ arguments[0] = "";
++ final LinkRequest forgedLinkRequest = linkRequest.replaceArguments(desc, arguments);
++ final GuardedInvocation invocation = getGuardedInvocation(beansLinker, forgedLinkRequest, linkerServices);
++ // If an invocation is found we add a filter that makes it work for both Strings and ConsStrings.
++ return invocation == null ? null : invocation.filterArguments(0, FILTER_CONSSTRING);
++ }
++
++ if (self != null && "call".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) {
++ // Support dyn:call on any object that supports some @FunctionalInterface
++ // annotated interface. This way Java method, constructor references or
++ // implementations of java.util.function.* interfaces can be called as though
++ // those are script functions.
++ final Method m = getFunctionalInterfaceMethod(self.getClass());
++ if (m != null) {
++ final MethodType callType = desc.getMethodType();
++ // 'callee' and 'thiz' passed from script + actual arguments
++ if (callType.parameterCount() != m.getParameterCount() + 2) {
++ throw typeError("no.method.matches.args", ScriptRuntime.safeToString(self));
++ }
++ return new GuardedInvocation(
++ // drop 'thiz' passed from the script.
++ MH.dropArguments(desc.getLookup().unreflect(m), 1, callType.parameterType(1)),
++ Guards.getInstanceOfGuard(m.getDeclaringClass())).asTypeSafeReturn(
++ new NashornBeansLinkerServices(linkerServices), callType);
++ }
++ }
+ return getGuardedInvocation(beansLinker, linkRequest, linkerServices);
+ }
+
+@@ -69,9 +138,76 @@
+
+ @SuppressWarnings("unused")
+ private static Object exportArgument(final Object arg) {
++ return exportArgument(arg, MIRROR_ALWAYS);
++ }
++
++ @SuppressWarnings("unused")
++ private static Object exportNativeArray(final NativeArray arg) {
++ return exportArgument(arg, MIRROR_ALWAYS);
++ }
++
++ @SuppressWarnings("unused")
++ private static Object exportScriptObject(final ScriptObject arg) {
++ return exportArgument(arg, MIRROR_ALWAYS);
++ }
++
++ @SuppressWarnings("unused")
++ private static Object exportScriptArray(final NativeArray arg) {
++ return exportArgument(arg, MIRROR_ALWAYS);
++ }
++
++ static Object exportArgument(final Object arg, final boolean mirrorAlways) {
++ if (arg instanceof ConsString) {
++ return arg.toString();
++ } else if (mirrorAlways && arg instanceof ScriptObject) {
++ return ScriptUtils.wrap((ScriptObject)arg);
++ } else {
++ return arg;
++ }
++ }
++
++ @SuppressWarnings("unused")
++ private static Object importResult(final Object arg) {
++ return ScriptUtils.unwrap(arg);
++ }
++
++ @SuppressWarnings("unused")
++ private static Object consStringFilter(final Object arg) {
+ return arg instanceof ConsString ? arg.toString() : arg;
+ }
+
++ private static Method findFunctionalInterfaceMethod(final Class<?> clazz) {
++ if (clazz == null) {
++ return null;
++ }
++
++ for (final Class<?> iface : clazz.getInterfaces()) {
++ // check accessiblity up-front
++ if (! Context.isAccessibleClass(iface)) {
++ continue;
++ }
++
++ // check for @FunctionalInterface
++ if (iface.isAnnotationPresent(FunctionalInterface.class)) {
++ // return the first abstract method
++ for (final Method m : iface.getMethods()) {
++ if (Modifier.isAbstract(m.getModifiers())) {
++ return m;
++ }
++ }
++ }
++ }
++
++ // did not find here, try super class
++ return findFunctionalInterfaceMethod(clazz.getSuperclass());
++ }
++
++ // Returns @FunctionalInterface annotated interface's single abstract
++ // method. If not found, returns null.
++ static Method getFunctionalInterfaceMethod(final Class<?> clazz) {
++ return FUNCTIONAL_IFACE_METHOD.get(clazz);
++ }
++
+ private static class NashornBeansLinkerServices implements LinkerServices {
+ private final LinkerServices linkerServices;
+
+@@ -81,30 +217,58 @@
+
+ @Override
+ public MethodHandle asType(final MethodHandle handle, final MethodType fromType) {
+- final MethodHandle typed = linkerServices.asType(handle, fromType);
+-
+ final MethodType handleType = handle.type();
+ final int paramCount = handleType.parameterCount();
+ assert fromType.parameterCount() == handleType.parameterCount();
+
++ MethodType newFromType = fromType;
+ MethodHandle[] filters = null;
+ for(int i = 0; i < paramCount; ++i) {
+- if(shouldConvert(handleType.parameterType(i), fromType.parameterType(i))) {
+- if(filters == null) {
++ final MethodHandle filter = argConversionFilter(handleType.parameterType(i), fromType.parameterType(i));
++ if (filter != null) {
++ if (filters == null) {
+ filters = new MethodHandle[paramCount];
+ }
+- filters[i] = EXPORT_ARGUMENT;
++ // "erase" specific type with Object type or else we'll get filter mismatch
++ newFromType = newFromType.changeParameterType(i, Object.class);
++ filters[i] = filter;
+ }
+ }
+
+- return filters != null ? MethodHandles.filterArguments(typed, 0, filters) : typed;
++ final MethodHandle typed = linkerServices.asType(handle, newFromType);
++ MethodHandle result = filters != null ? MethodHandles.filterArguments(typed, 0, filters) : typed;
++ // Filter Object typed return value for possible ScriptObjectMirror. We convert
++ // ScriptObjectMirror as ScriptObject (if it is mirror from current global).
++ if (MIRROR_ALWAYS && areBothObjects(handleType.returnType(), fromType.returnType())) {
++ result = MethodHandles.filterReturnValue(result, IMPORT_RESULT);
++ }
++
++ return result;
+ }
+
+- private static boolean shouldConvert(final Class<?> handleType, final Class<?> fromType) {
++ private static MethodHandle argConversionFilter(final Class<?> handleType, final Class<?> fromType) {
++ if (handleType == Object.class) {
++ if (fromType == Object.class) {
++ return EXPORT_ARGUMENT;
++ } else if (fromType == NativeArray.class) {
++ return EXPORT_NATIVE_ARRAY;
++ } else if (fromType == ScriptObject.class) {
++ return EXPORT_SCRIPT_OBJECT;
++ }
++ }
++ return null;
++ }
++
++ private static boolean areBothObjects(final Class<?> handleType, final Class<?> fromType) {
+ return handleType == Object.class && fromType == Object.class;
+ }
+
+ @Override
++ public MethodHandle asTypeLosslessReturn(final MethodHandle handle, final MethodType fromType) {
++ return Implementation.asTypeLosslessReturn(this, handle, fromType);
++ }
++
++ @Override
+ public MethodHandle getTypeConverter(final Class<?> sourceType, final Class<?> targetType) {
+ return linkerServices.getTypeConverter(sourceType, targetType);
+ }
+@@ -121,6 +285,15 @@
+
+ @Override
+ public Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) {
++ if (sourceType == ConsString.class) {
++ if (String.class == targetType1 || CharSequence.class == targetType1) {
++ return Comparison.TYPE_1_BETTER;
++ }
++
++ if (String.class == targetType2 || CharSequence.class == targetType2) {
++ return Comparison.TYPE_2_BETTER;
++ }
++ }
+ return linkerServices.compareConversion(sourceType, targetType1, targetType2);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -30,9 +30,6 @@
+ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+ import java.lang.invoke.MethodHandle;
+-import java.lang.invoke.MethodType;
+-import java.lang.reflect.Method;
+-import java.lang.reflect.Modifier;
+ import java.util.HashMap;
+ import java.util.Map;
+ import jdk.internal.dynalink.CallSiteDescriptor;
+@@ -44,9 +41,10 @@
+ import jdk.internal.dynalink.linker.LinkRequest;
+ import jdk.internal.dynalink.linker.LinkerServices;
+ import jdk.internal.dynalink.support.Guards;
+-import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.codegen.types.Type;
+ import jdk.nashorn.internal.runtime.JSType;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
++import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
+
+ /**
+ * Nashorn bottom linker; used as a last-resort catch-all linker for all linking requests that fall through all other
+@@ -93,21 +91,8 @@
+ }
+ throw typeError("not.a.function", ScriptRuntime.safeToString(self));
+ case "call":
+- // Support dyn:call on any object that supports some @FunctionalInterface
+- // annotated interface. This way Java method, constructor references or
+- // implementations of java.util.function.* interfaces can be called as though
+- // those are script functions.
+- final Method m = getFunctionalInterfaceMethod(self.getClass());
+- if (m != null) {
+- final MethodType callType = desc.getMethodType();
+- // 'callee' and 'thiz' passed from script + actual arguments
+- if (callType.parameterCount() != m.getParameterCount() + 2) {
+- throw typeError("no.method.matches.args", ScriptRuntime.safeToString(self));
+- }
+- return new GuardedInvocation(
+- // drop 'thiz' passed from the script.
+- MH.dropArguments(desc.getLookup().unreflect(m), 1, callType.parameterType(1)),
+- Guards.getInstanceOfGuard(m.getDeclaringClass())).asType(callType);
++ if(BeansLinker.isDynamicConstructor(self)) {
++ throw typeError("constructor.requires.new", ScriptRuntime.safeToString(self));
+ }
+ if(BeansLinker.isDynamicMethod(self)) {
+ throw typeError("no.method.matches.args", ScriptRuntime.safeToString(self));
+@@ -118,16 +103,24 @@
+ throw typeError("no.such.function", getArgument(linkRequest), ScriptRuntime.safeToString(self));
+ case "getProp":
+ case "getElem":
++ if(NashornCallSiteDescriptor.isOptimistic(desc)) {
++ throw new UnwarrantedOptimismException(UNDEFINED, NashornCallSiteDescriptor.getProgramPoint(desc), Type.OBJECT);
++ }
+ if (desc.getOperand() != null) {
+ return getInvocation(EMPTY_PROP_GETTER, self, linkerServices, desc);
+ }
+ return getInvocation(EMPTY_ELEM_GETTER, self, linkerServices, desc);
+ case "setProp":
+- case "setElem":
++ case "setElem": {
++ final boolean strict = NashornCallSiteDescriptor.isStrict(desc);
++ if (strict) {
++ throw typeError("cant.set.property", getArgument(linkRequest), ScriptRuntime.safeToString(self));
++ }
+ if (desc.getOperand() != null) {
+ return getInvocation(EMPTY_PROP_SETTER, self, linkerServices, desc);
+ }
+ return getInvocation(EMPTY_ELEM_SETTER, self, linkerServices, desc);
++ }
+ default:
+ break;
+ }
+@@ -151,14 +144,14 @@
+ private static GuardedInvocation convertToTypeNoCast(final Class<?> sourceType, final Class<?> targetType) throws Exception {
+ final MethodHandle mh = CONVERTERS.get(targetType);
+ if (mh != null) {
+- return new GuardedInvocation(mh, null);
++ return new GuardedInvocation(mh);
+ }
+
+ return null;
+ }
+
+ private static GuardedInvocation getInvocation(final MethodHandle handle, final Object self, final LinkerServices linkerServices, final CallSiteDescriptor desc) {
+- return Bootstrap.asType(new GuardedInvocation(handle, Guards.getClassGuard(self.getClass())), linkerServices, desc);
++ return Bootstrap.asTypeSafeReturn(new GuardedInvocation(handle, Guards.getClassGuard(self.getClass())), linkerServices, desc);
+ }
+
+ // Used solely in an assertion to figure out if the object we get here is something we in fact expect. Objects
+@@ -205,44 +198,4 @@
+ }
+ return ScriptRuntime.safeToString(linkRequest.getArguments()[1]);
+ }
+-
+- // cache of @FunctionalInterface method of implementor classes
+- private static final ClassValue<Method> FUNCTIONAL_IFACE_METHOD = new ClassValue<Method>() {
+- @Override
+- protected Method computeValue(final Class<?> type) {
+- return findFunctionalInterfaceMethod(type);
+- }
+-
+- private Method findFunctionalInterfaceMethod(final Class<?> clazz) {
+- if (clazz == null) {
+- return null;
+- }
+-
+- for (Class<?> iface : clazz.getInterfaces()) {
+- // check accessiblity up-front
+- if (! Context.isAccessibleClass(iface)) {
+- continue;
+- }
+-
+- // check for @FunctionalInterface
+- if (iface.isAnnotationPresent(FunctionalInterface.class)) {
+- // return the first abstract method
+- for (final Method m : iface.getMethods()) {
+- if (Modifier.isAbstract(m.getModifiers())) {
+- return m;
+- }
+- }
+- }
+- }
+-
+- // did not find here, try super class
+- return findFunctionalInterfaceMethod(clazz.getSuperclass());
+- }
+- };
+-
+- // Returns @FunctionalInterface annotated interface's single abstract
+- // method. If not found, returns null.
+- static Method getFunctionalInterfaceMethod(final Class<?> clazz) {
+- return FUNCTIONAL_IFACE_METHOD.get(clazz);
+- }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -33,6 +33,7 @@
+ import jdk.internal.dynalink.CallSiteDescriptor;
+ import jdk.internal.dynalink.support.AbstractCallSiteDescriptor;
+ import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
++import jdk.nashorn.internal.ir.debug.NashornTextifier;
+
+ /**
+ * Nashorn-specific implementation of Dynalink's {@link CallSiteDescriptor}. The reason we have our own subclass is that
+@@ -42,40 +43,63 @@
+ public final class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor {
+ /** Flags that the call site references a scope variable (it's an identifier reference or a var declaration, not a
+ * property access expression. */
+- public static final int CALLSITE_SCOPE = 0x01;
++ public static final int CALLSITE_SCOPE = 1 << 0;
+ /** Flags that the call site is in code that uses ECMAScript strict mode. */
+- public static final int CALLSITE_STRICT = 0x02;
++ public static final int CALLSITE_STRICT = 1 << 1;
+ /** Flags that a property getter or setter call site references a scope variable that is located at a known distance
+ * in the scope chain. Such getters and setters can often be linked more optimally using these assumptions. */
+- public static final int CALLSITE_FAST_SCOPE = 0x400;
++ public static final int CALLSITE_FAST_SCOPE = 1 << 2;
++ /** Flags that a callsite type is optimistic, i.e. we might get back a wider return value than encoded in the
++ * descriptor, and in that case we have to throw an UnwarrantedOptimismException */
++ public static final int CALLSITE_OPTIMISTIC = 1 << 3;
++ /** Is this really an apply that we try to call as a call? */
++ public static final int CALLSITE_APPLY_TO_CALL = 1 << 4;
++ /** Does this a callsite for a variable declaration? */
++ public static final int CALLSITE_DECLARE = 1 << 5;
+
+ /** Flags that the call site is profiled; Contexts that have {@code "profile.callsites"} boolean property set emit
+ * code where call sites have this flag set. */
+- public static final int CALLSITE_PROFILE = 0x10;
++ public static final int CALLSITE_PROFILE = 1 << 6;
+ /** Flags that the call site is traced; Contexts that have {@code "trace.callsites"} property set emit code where
+ * call sites have this flag set. */
+- public static final int CALLSITE_TRACE = 0x20;
++ public static final int CALLSITE_TRACE = 1 << 7;
+ /** Flags that the call site linkage miss (and thus, relinking) is traced; Contexts that have the keyword
+ * {@code "miss"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */
+- public static final int CALLSITE_TRACE_MISSES = 0x40;
++ public static final int CALLSITE_TRACE_MISSES = 1 << 8;
+ /** Flags that entry/exit to/from the method linked at call site are traced; Contexts that have the keyword
+- * {@code "enterexit"} in their {@code "trace.callsites"} property emit code where call sites have this flag
+- * set. */
+- public static final int CALLSITE_TRACE_ENTEREXIT = 0x80;
++ * {@code "enterexit"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */
++ public static final int CALLSITE_TRACE_ENTEREXIT = 1 << 9;
+ /** Flags that values passed as arguments to and returned from the method linked at call site are traced; Contexts
+ * that have the keyword {@code "values"} in their {@code "trace.callsites"} property emit code where call sites
+ * have this flag set. */
+- public static final int CALLSITE_TRACE_VALUES = 0x100;
+- /** Ordinarily, when {@link #CALLSITE_TRACE_VALUES} is set, scope objects are not printed in the trace but instead
+- * the word {@code "SCOPE"} is printed instead With this flag, scope objects are also printed. Contexts that have
+- * the keyword {@code "scope"} in their {@code "trace.callsites"} property emit code where call sites have this flag
+- * set. */
+- public static final int CALLSITE_TRACE_SCOPE = 0x200;
++ public static final int CALLSITE_TRACE_VALUES = 1 << 10;
++
++ //we could have more tracing flags here, for example CALLSITE_TRACE_SCOPE, but bits are a bit precious
++ //right now given the program points
++
++ /**
++ * Number of bits the program point is shifted to the left in the flags (lowest bit containing a program point).
++ * Always one larger than the largest flag shift. Note that introducing a new flag halves the number of program
++ * points we can have.
++ * TODO: rethink if we need the various profile/trace flags or the linker can use the Context instead to query its
++ * trace/profile settings.
++ */
++ public static final int CALLSITE_PROGRAM_POINT_SHIFT = 11;
++
++ /**
++ * Maximum program point value. 21 bits should be enough for anyone
++ */
++ public static final int MAX_PROGRAM_POINT_VALUE = (1 << 32 - CALLSITE_PROGRAM_POINT_SHIFT) - 1;
++
++ /**
++ * Flag mask to get the program point flags
++ */
++ public static final int FLAGS_MASK = (1 << CALLSITE_PROGRAM_POINT_SHIFT) - 1;
+
+ private static final ClassValue<ConcurrentMap<NashornCallSiteDescriptor, NashornCallSiteDescriptor>> canonicals =
+ new ClassValue<ConcurrentMap<NashornCallSiteDescriptor,NashornCallSiteDescriptor>>() {
+ @Override
+- protected ConcurrentMap<NashornCallSiteDescriptor, NashornCallSiteDescriptor> computeValue(Class<?> type) {
++ protected ConcurrentMap<NashornCallSiteDescriptor, NashornCallSiteDescriptor> computeValue(final Class<?> type) {
+ return new ConcurrentHashMap<>();
+ }
+ };
+@@ -87,6 +111,34 @@
+ private final int flags;
+
+ /**
++ * Function used by {@link NashornTextifier} to represent call site flags in
++ * human readable form
++ * @param flags call site flags
++ * @return human readable form of this callsite descriptor
++ */
++ public static String toString(final int flags) {
++ final StringBuilder sb = new StringBuilder();
++ if ((flags & CALLSITE_SCOPE) != 0) {
++ if ((flags & CALLSITE_FAST_SCOPE) != 0) {
++ sb.append("fastscope ");
++ } else {
++ assert (flags & CALLSITE_FAST_SCOPE) == 0 : "can't be fastscope without scope";
++ sb.append("scope ");
++ }
++ if ((flags & CALLSITE_DECLARE) != 0) {
++ sb.append("declare ");
++ }
++ }
++ if ((flags & CALLSITE_APPLY_TO_CALL) != 0) {
++ sb.append("apply2call ");
++ }
++ if ((flags & CALLSITE_STRICT) != 0) {
++ sb.append("strict ");
++ }
++ return sb.length() == 0 ? "" : " " + sb.toString().trim();
++ }
++
++ /**
+ * Retrieves a Nashorn call site descriptor with the specified values. Since call site descriptors are immutable
+ * this method is at liberty to retrieve canonicalized instances (although it is not guaranteed it will do so).
+ * @param lookup the lookup describing the script
+@@ -203,7 +255,7 @@
+ * @return the Nashorn-specific flags for the call site, or 0 if the passed descriptor is not a Nashorn call site
+ * descriptor.
+ */
+- private static int getFlags(final CallSiteDescriptor desc) {
++ public static int getFlags(final CallSiteDescriptor desc) {
+ return desc instanceof NashornCallSiteDescriptor ? ((NashornCallSiteDescriptor)desc).flags : 0;
+ }
+
+@@ -262,6 +314,62 @@
+ return isFlag(desc, CALLSITE_STRICT);
+ }
+
++ /**
++ * Returns true if this is an apply call that we try to call as
++ * a "call"
++ * @param desc descriptor
++ * @return true if apply to call
++ */
++ public static boolean isApplyToCall(final CallSiteDescriptor desc) {
++ return isFlag(desc, CALLSITE_APPLY_TO_CALL);
++ }
++
++ /**
++ * Is this an optimistic call site
++ * @param desc descriptor
++ * @return true if optimistic
++ */
++ public static boolean isOptimistic(final CallSiteDescriptor desc) {
++ return isFlag(desc, CALLSITE_OPTIMISTIC);
++ }
++
++ /**
++ * Does this callsite contain a declaration for its target?
++ * @param desc descriptor
++ * @return true if contains declaration
++ */
++ public static boolean isDeclaration(final CallSiteDescriptor desc) {
++ return isFlag(desc, CALLSITE_DECLARE);
++ }
++
++ /**
++ * Returns true if {@code flags} has the {@link #CALLSITE_STRICT} bit set.
++ * @param flags the flags
++ * @return true if the flag is set, false otherwise.
++ */
++ public static boolean isStrictFlag(final int flags) {
++ return (flags & CALLSITE_STRICT) != 0;
++ }
++
++ /**
++ * Returns true if {@code flags} has the {@link #CALLSITE_SCOPE} bit set.
++ * @param flags the flags
++ * @return true if the flag is set, false otherwise.
++ */
++ public static boolean isScopeFlag(final int flags) {
++ return (flags & CALLSITE_SCOPE) != 0;
++ }
++
++ /**
++ * Get a program point from a descriptor (must be optimistic)
++ * @param desc descriptor
++ * @return program point
++ */
++ public static int getProgramPoint(final CallSiteDescriptor desc) {
++ assert isOptimistic(desc) : "program point requested from non-optimistic descriptor " + desc;
++ return getFlags(desc) >> CALLSITE_PROGRAM_POINT_SHIFT;
++ }
++
+ boolean isProfile() {
+ return isFlag(CALLSITE_PROFILE);
+ }
+@@ -282,12 +390,13 @@
+ return isFlag(CALLSITE_TRACE_VALUES);
+ }
+
+- boolean isTraceScope() {
+- return isFlag(CALLSITE_TRACE_SCOPE);
++ boolean isOptimistic() {
++ return isFlag(CALLSITE_OPTIMISTIC);
+ }
+
+ @Override
+ public CallSiteDescriptor changeMethodType(final MethodType newMethodType) {
+ return get(getLookup(), operator, operand, newMethodType, flags);
+ }
++
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java Wed Feb 04 12:14:47 2015 -0800
+@@ -31,6 +31,7 @@
+ import java.lang.invoke.MethodHandles;
+ import java.lang.ref.WeakReference;
+ import jdk.internal.dynalink.CallSiteDescriptor;
++import jdk.internal.dynalink.linker.LinkRequest;
+ import jdk.nashorn.api.scripting.JSObject;
+ import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+ import jdk.nashorn.internal.objects.Global;
+@@ -38,56 +39,80 @@
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptObject;
++import jdk.nashorn.internal.runtime.options.Options;
+
+ /**
+ * Constructor of method handles used to guard call sites.
+ */
+ public final class NashornGuards {
+- private static final MethodHandle IS_SCRIPTOBJECT = findOwnMH("isScriptObject", boolean.class, Object.class);
+- private static final MethodHandle IS_NOT_JSOBJECT = findOwnMH("isNotJSObject", boolean.class, Object.class);
+- private static final MethodHandle IS_SCRIPTFUNCTION = findOwnMH("isScriptFunction", boolean.class, Object.class);
+- private static final MethodHandle IS_MAP = findOwnMH("isMap", boolean.class, Object.class, PropertyMap.class);
++ private static final MethodHandle IS_MAP = findOwnMH("isMap", boolean.class, ScriptObject.class, PropertyMap.class);
++ private static final MethodHandle IS_MAP_SCRIPTOBJECT = findOwnMH("isMap", boolean.class, Object.class, PropertyMap.class);
++ private static final MethodHandle IS_INSTANCEOF_2 = findOwnMH("isInstanceOf2", boolean.class, Object.class, Class.class, Class.class);
++ private static final MethodHandle IS_SCRIPTOBJECT = findOwnMH("isScriptObject", boolean.class, Object.class);
++ private static final MethodHandle IS_NOT_JSOBJECT = findOwnMH("isNotJSObject", boolean.class, Object.class);
+ private static final MethodHandle SAME_OBJECT = findOwnMH("sameObject", boolean.class, Object.class, WeakReference.class);
+- private static final MethodHandle IS_INSTANCEOF_2 = findOwnMH("isInstanceOf2", boolean.class, Object.class, Class.class, Class.class);
++ //TODO - maybe put this back in ScriptFunction instead of the ClassCastException.class relinkage
++ //private static final MethodHandle IS_SCRIPTFUNCTION = findOwnMH("isScriptFunction", boolean.class, Object.class);
++
++ private static final boolean CCE_ONLY = Options.getBooleanProperty("nashorn.cce");
+
+ // don't create me!
+ private NashornGuards() {
+ }
+
+ /**
+- * Get the guard that checks if an item is a {@code ScriptObject}
+- * @return method handle for guard
++ * Given a callsite descriptor and a link request, determine whether we should use an instanceof
++ * check explicitly for the guard if needed, or if we should link it with a try/catch ClassCastException
++ * combinator as its relink criteria - i.e. relink when CCE is thrown.
++ *
++ * @param desc callsite descriptor
++ * @param request link request
++ * @return true of explicit instanceof check is needed
++ */
++ public static boolean explicitInstanceOfCheck(final CallSiteDescriptor desc, final LinkRequest request) {
++ //THIS is currently true, as the inliner encounters several problems with sun.misc.ValueConversions.castReference
++ //otherwise. We should only use the exception based relink where we have no choice, and the result is faster code,
++ //for example in the NativeArray, TypedArray, ContinuousArray getters. For the standard callsite, it appears that
++ //we lose performance rather than gain it, due to JVM issues. :-(
++ return !CCE_ONLY;
++ }
++
++ /**
++ * Returns a guard that does an instanceof ScriptObject check on the receiver
++ * @return guard
+ */
+ public static MethodHandle getScriptObjectGuard() {
+ return IS_SCRIPTOBJECT;
+ }
+
+- /**
+- * Get the guard that checks if an item is not a {@code JSObject}
+- * @return method handle for guard
+- */
+- public static MethodHandle getNotJSObjectGuard() {
+- return IS_NOT_JSOBJECT;
+- }
++ /**
++ * Get the guard that checks if an item is not a {@code JSObject}
++ * @return method handle for guard
++ */
++ public static MethodHandle getNotJSObjectGuard() {
++ return IS_NOT_JSOBJECT;
++ }
+
+ /**
+- * Get the guard that checks if an item is a {@code ScriptFunction}
+- * @return method handle for guard
++ * Returns a guard that does an instanceof ScriptObject check on the receiver
++ * @param explicitInstanceOfCheck - if false, then this is a nop, because it's all the guard does
++ * @return guard
+ */
+- public static MethodHandle getScriptFunctionGuard() {
+- return IS_SCRIPTFUNCTION;
++ public static MethodHandle getScriptObjectGuard(final boolean explicitInstanceOfCheck) {
++ return explicitInstanceOfCheck ? IS_SCRIPTOBJECT : null;
+ }
+
+ /**
+ * Get the guard that checks if a {@link PropertyMap} is equal to
+ * a known map, using reference comparison
+ *
++ * @param explicitInstanceOfCheck true if we should do an explicit script object instanceof check instead of just casting
+ * @param map The map to check against. This will be bound to the guard method handle
+ *
+ * @return method handle for guard
+ */
+- public static MethodHandle getMapGuard(final PropertyMap map) {
+- return MH.insertArguments(IS_MAP, 1, map);
++ public static MethodHandle getMapGuard(final PropertyMap map, final boolean explicitInstanceOfCheck) {
++ return MH.insertArguments(explicitInstanceOfCheck ? IS_MAP_SCRIPTOBJECT : IS_MAP, 1, map);
+ }
+
+ /**
+@@ -109,23 +134,24 @@
+ * @param sobj the first object in the prototype chain
+ * @param property the property
+ * @param desc the callsite descriptor
++ * @param explicitInstanceOfCheck true if we should do an explicit script object instanceof check instead of just casting
+ * @return method handle for guard
+ */
+- public static MethodHandle getGuard(final ScriptObject sobj, final Property property, final CallSiteDescriptor desc) {
++ public static MethodHandle getGuard(final ScriptObject sobj, final Property property, final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck) {
+ if (!needsGuard(property, desc)) {
+ return null;
+ }
+ if (NashornCallSiteDescriptor.isScope(desc)) {
+- if (property != null && property.isBound()) {
++ if (property != null && property.isBound() && !property.canChangeType()) {
+ // This is a declared top level variables in main script or eval, use identity guard.
+ return getIdentityGuard(sobj);
+ }
+ if (!(sobj instanceof Global) && (property == null || property.isConfigurable())) {
+ // Undeclared variables in nested evals need stronger guards
+- return combineGuards(getIdentityGuard(sobj), getMapGuard(sobj.getMap()));
++ return combineGuards(getIdentityGuard(sobj), getMapGuard(sobj.getMap(), explicitInstanceOfCheck));
+ }
+ }
+- return getMapGuard(sobj.getMap());
++ return getMapGuard(sobj.getMap(), explicitInstanceOfCheck);
+ }
+
+
+@@ -158,7 +184,13 @@
+ * @return true if both guard1 and guard2 returned true
+ */
+ public static MethodHandle combineGuards(final MethodHandle guard1, final MethodHandle guard2) {
+- return MH.guardWithTest(guard1, guard2, MH.dropArguments(MH.constant(boolean.class, false), 0, Object.class));
++ if (guard1 == null) {
++ return guard2;
++ } else if (guard2 == null) {
++ return guard1;
++ } else {
++ return MH.guardWithTest(guard1, guard2, MH.dropArguments(MH.constant(boolean.class, false), 0, Object.class));
++ }
+ }
+
+ @SuppressWarnings("unused")
+@@ -167,13 +199,18 @@
+ }
+
+ @SuppressWarnings("unused")
+- private static boolean isNotJSObject(final Object self) {
+- return !(self instanceof JSObject);
++ private static boolean isScriptObject(final Class<? extends ScriptObject> clazz, final Object self) {
++ return clazz.isInstance(self);
+ }
+
+ @SuppressWarnings("unused")
+- private static boolean isScriptFunction(final Object self) {
+- return self instanceof ScriptFunction;
++ private static boolean isMap(final ScriptObject self, final PropertyMap map) {
++ return self.getMap() == map;
++ }
++
++ @SuppressWarnings("unused")
++ private static boolean isNotJSObject(final Object self) {
++ return !(self instanceof JSObject);
+ }
+
+ @SuppressWarnings("unused")
+@@ -181,6 +218,7 @@
+ return self instanceof ScriptObject && ((ScriptObject)self).getMap() == map;
+ }
+
++
+ @SuppressWarnings("unused")
+ private static boolean sameObject(final Object self, final WeakReference<ScriptObject> ref) {
+ return self == ref.get();
+@@ -191,8 +229,12 @@
+ return class1.isInstance(self) || class2.isInstance(self);
+ }
+
++ @SuppressWarnings("unused")
++ private static boolean isScriptFunction(final Object self) {
++ return self instanceof ScriptFunction;
++ }
++
+ private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+ return MH.findStatic(MethodHandles.lookup(), NashornGuards.class, name, MH.type(rtype, types));
+ }
+-
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -63,7 +63,7 @@
+ final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator {
+ private static final ClassValue<MethodHandle> ARRAY_CONVERTERS = new ClassValue<MethodHandle>() {
+ @Override
+- protected MethodHandle computeValue(Class<?> type) {
++ protected MethodHandle computeValue(final Class<?> type) {
+ return createArrayConverter(type);
+ }
+ };
+@@ -91,16 +91,20 @@
+ return null;
+ }
+
++ return Bootstrap.asTypeSafeReturn(getGuardedInvocation(self, request, desc), linkerServices, desc);
++ }
++
++ private static GuardedInvocation getGuardedInvocation(final Object self, final LinkRequest request, final CallSiteDescriptor desc) {
+ final GuardedInvocation inv;
+ if (self instanceof ScriptObject) {
+ inv = ((ScriptObject)self).lookup(desc, request);
+ } else if (self instanceof Undefined) {
+ inv = Undefined.lookup(desc);
+ } else {
+- throw new AssertionError(); // Should never reach here.
++ throw new AssertionError(self.getClass().getName()); // Should never reach here.
+ }
+
+- return Bootstrap.asType(inv, linkerServices, desc);
++ return inv;
+ }
+
+ @Override
+@@ -184,7 +188,7 @@
+ */
+ private static GuardedInvocation getArrayConverter(final Class<?> sourceType, final Class<?> targetType) {
+ final boolean isSourceTypeNativeArray = sourceType == NativeArray.class;
+- // If source type is more generic than ScriptFunction class, we'll need to use a guard
++ // If source type is more generic than NativeArray class, we'll need to use a guard
+ final boolean isSourceTypeGeneric = !isSourceTypeNativeArray && sourceType.isAssignableFrom(NativeArray.class);
+
+ if (isSourceTypeNativeArray || isSourceTypeGeneric) {
+@@ -208,12 +212,12 @@
+ return MH.asType(converter, converter.type().changeReturnType(type));
+ }
+
+- private static GuardedInvocation getMirrorConverter(Class<?> sourceType, Class<?> targetType) {
++ private static GuardedInvocation getMirrorConverter(final Class<?> sourceType, final Class<?> targetType) {
+ // Could've also used (targetType.isAssignableFrom(ScriptObjectMirror.class) && targetType != Object.class) but
+ // it's probably better to explicitly spell out the supported target types
+ if (targetType == Map.class || targetType == Bindings.class || targetType == JSObject.class || targetType == ScriptObjectMirror.class) {
+ if(ScriptObject.class.isAssignableFrom(sourceType)) {
+- return new GuardedInvocation(CREATE_MIRROR, null);
++ return new GuardedInvocation(CREATE_MIRROR);
+ }
+ return new GuardedInvocation(CREATE_MIRROR, IS_SCRIPT_OBJECT);
+ }
+@@ -270,7 +274,7 @@
+ return Comparison.INDETERMINATE;
+ }
+
+- private static boolean isList(Class<?> clazz) {
++ private static boolean isList(final Class<?> clazz) {
+ return clazz == List.class || clazz == Deque.class;
+ }
+
+@@ -288,7 +292,7 @@
+
+ @SuppressWarnings("unused")
+ private static Object createMirror(final Object obj) {
+- return ScriptUtils.wrap(obj);
++ return obj instanceof ScriptObject? ScriptUtils.wrap((ScriptObject)obj) : obj;
+ }
+
+ private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -39,7 +39,7 @@
+ import jdk.internal.dynalink.support.TypeUtilities;
+ import jdk.nashorn.internal.objects.Global;
+ import jdk.nashorn.internal.runtime.ConsString;
+-import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+ /**
+ * Internal linker for String, Boolean, and Number objects, only ever used by Nashorn engine and not exposed to other
+@@ -47,6 +47,9 @@
+ * primitive type conversions for these types when linking to Java methods.
+ */
+ final class NashornPrimitiveLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator {
++ private static final GuardedTypeConversion VOID_TO_OBJECT = new GuardedTypeConversion(
++ new GuardedInvocation(MethodHandles.constant(Object.class, ScriptRuntime.UNDEFINED)), true);
++
+ @Override
+ public boolean canLinkType(final Class<?> type) {
+ return canLinkTypeStatic(type);
+@@ -62,10 +65,9 @@
+ final LinkRequest request = origRequest.withoutRuntimeContext(); // Nashorn has no runtime context
+
+ final Object self = request.getReceiver();
+- final Global global = Context.getGlobal();
+ final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor) request.getCallSiteDescriptor();
+
+- return Bootstrap.asType(global.primitiveLookup(request, self), linkerServices, desc);
++ return Bootstrap.asTypeSafeReturn(Global.primitiveLookup(request, self), linkerServices, desc);
+ }
+
+ /**
+@@ -79,6 +81,9 @@
+ public GuardedTypeConversion convertToType(final Class<?> sourceType, final Class<?> targetType) {
+ final MethodHandle mh = JavaArgumentConverters.getConverter(targetType);
+ if (mh == null) {
++ if(targetType == Object.class && sourceType == void.class) {
++ return VOID_TO_OBJECT;
++ }
+ return null;
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -54,12 +54,12 @@
+ private static final GuardingDynamicLinker staticClassLinker = BeansLinker.getLinkerForClass(StaticClass.class);
+
+ @Override
+- public boolean canLinkType(Class<?> type) {
++ public boolean canLinkType(final Class<?> type) {
+ return type == StaticClass.class;
+ }
+
+ @Override
+- public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) throws Exception {
++ public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
+ final LinkRequest request = linkRequest.withoutRuntimeContext(); // Nashorn has no runtime context
+ final Object self = request.getReceiver();
+ if (self.getClass() != StaticClass.class) {
+@@ -99,7 +99,7 @@
+ return delegate(linkerServices, request);
+ }
+
+- private static GuardedInvocation delegate(LinkerServices linkerServices, final LinkRequest request) throws Exception {
++ private static GuardedInvocation delegate(final LinkerServices linkerServices, final LinkRequest request) throws Exception {
+ return NashornBeansLinker.getGuardedInvocation(staticClassLinker, request, linkerServices);
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,17 +26,18 @@
+ package jdk.nashorn.internal.runtime.linker;
+
+ import static jdk.nashorn.internal.lookup.Lookup.MH;
+-
+ import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodType;
++import java.lang.invoke.SwitchPoint;
+ import jdk.internal.dynalink.CallSiteDescriptor;
+ import jdk.internal.dynalink.linker.GuardedInvocation;
+ import jdk.internal.dynalink.linker.LinkRequest;
+-import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+ import jdk.internal.dynalink.support.Guards;
+-import jdk.nashorn.internal.lookup.Lookup;
++import jdk.nashorn.internal.runtime.Context;
+ import jdk.nashorn.internal.runtime.FindProperty;
++import jdk.nashorn.internal.runtime.GlobalConstants;
+ import jdk.nashorn.internal.runtime.ScriptObject;
++import jdk.nashorn.internal.runtime.UserAccessorProperty;
+
+ /**
+ * Implements lookup of methods to link for dynamic operations on JavaScript primitive values (booleans, strings, and
+@@ -59,6 +60,7 @@
+ * creates a transient native wrapper of the same type as {@code wrappedReceiver} for subsequent invocations of the
+ * method - it will be combined into the returned invocation as an argument filter on the receiver.
+ * @return a guarded invocation representing the operation at the call site when performed on a JavaScript primitive
++ * @param protoFilter A method handle that walks up the proto chain of this receiver object
+ * type {@code receiverClass}.
+ */
+ public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Class<?> receiverClass,
+@@ -77,6 +79,7 @@
+ * @param wrapFilter A method handle that takes a primitive value of type guarded by the {@code guard} and
+ * creates a transient native wrapper of the same type as {@code wrappedReceiver} for subsequent invocations of the
+ * method - it will be combined into the returned invocation as an argument filter on the receiver.
++ * @param protoFilter A method handle that walks up the proto chain of this receiver object
+ * @return a guarded invocation representing the operation at the call site when performed on a JavaScript primitive
+ * type (that is implied by both {@code guard} and {@code wrappedReceiver}).
+ */
+@@ -84,37 +87,42 @@
+ final ScriptObject wrappedReceiver, final MethodHandle wrapFilter,
+ final MethodHandle protoFilter) {
+ final CallSiteDescriptor desc = request.getCallSiteDescriptor();
+- final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
+- if ("setProp".equals(operator) || "setElem".equals(operator)) {
+- MethodType type = desc.getMethodType();
+- MethodHandle method = MH.asType(Lookup.EMPTY_SETTER, MH.type(void.class, Object.class, type.parameterType(1)));
+- if (type.parameterCount() == 3) {
+- method = MH.dropArguments(method, 2, type.parameterType(2));
+- }
+- return new GuardedInvocation(method, guard);
+- }
+
+- if(desc.getNameTokenCount() > 2) {
++ //checks whether the property name is hard-coded in the call-site (i.e. a getProp vs a getElem, or setProp vs setElem)
++ //if it is we can make assumptions on the property: that if it is not defined on primitive wrapper itself it never will be.
++ //so in that case we can skip creation of primitive wrapper and start our search with the prototype.
++ if (desc.getNameTokenCount() > 2) {
+ final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
+ final FindProperty find = wrappedReceiver.findProperty(name, true);
+- if(find == null) {
++
++ if (find == null) {
+ // Give up early, give chance to BeanLinker and NashornBottomLinker to deal with it.
+ return null;
+- } else if (find.isInherited() && !find.getProperty().hasGetterFunction(find.getOwner())) {
++ }
++
++ final SwitchPoint sp = find.getProperty().getBuiltinSwitchPoint(); //can use this instead of proto filter
++ if (sp instanceof Context.BuiltinSwitchPoint && !sp.hasBeenInvalidated()) {
++ return new GuardedInvocation(GlobalConstants.staticConstantGetter(find.getObjectValue()), guard, sp, null);
++ }
++
++ if (find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) {
+ // If property is found in the prototype object bind the method handle directly to
+ // the proto filter instead of going through wrapper instantiation below.
+ final ScriptObject proto = wrappedReceiver.getProto();
+ final GuardedInvocation link = proto.lookup(desc, request);
+
+ if (link != null) {
+- final MethodHandle invocation = link.getInvocation();
++ final MethodHandle invocation = link.getInvocation(); //this contains the builtin switchpoint
++
+ final MethodHandle adaptedInvocation = MH.asType(invocation, invocation.type().changeParameterType(0, Object.class));
+ final MethodHandle method = MH.filterArguments(adaptedInvocation, 0, protoFilter);
+ final MethodHandle protoGuard = MH.filterArguments(link.getGuard(), 0, protoFilter);
++
+ return new GuardedInvocation(method, NashornGuards.combineGuards(guard, protoGuard));
+ }
+ }
+ }
++
+ final GuardedInvocation link = wrappedReceiver.lookup(desc, request);
+ if (link != null) {
+ MethodHandle method = link.getInvocation();
+@@ -124,8 +132,10 @@
+ assert receiverType.isAssignableFrom(wrapType.returnType());
+ method = MH.filterArguments(method, 0, MH.asType(wrapFilter, wrapType.changeReturnType(receiverType)));
+ }
+- return new GuardedInvocation(method, guard, link.getSwitchPoint());
++
++ return new GuardedInvocation(method, guard, link.getSwitchPoints(), null);
+ }
++
+ return null;
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,8 @@
+
+ package jdk.nashorn.internal.runtime.linker;
+
++import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
++
+ import java.lang.reflect.Modifier;
+ import java.lang.reflect.Proxy;
+ import jdk.internal.dynalink.CallSiteDescriptor;
+@@ -33,7 +35,9 @@
+ import jdk.internal.dynalink.linker.LinkerServices;
+ import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+ import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
++import jdk.nashorn.api.scripting.ClassFilter;
+ import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.objects.Global;
+
+ /**
+ * Check java reflection permission for java reflective and java.lang.invoke access from scripts
+@@ -100,6 +104,12 @@
+ }
+
+ static void checkReflectionAccess(final Class<?> clazz, final boolean isStatic) {
++ final Global global = Context.getGlobal();
++ final ClassFilter cf = global.getClassFilter();
++ if (cf != null && isReflectiveCheckNeeded(clazz, isStatic)) {
++ throw typeError("no.reflection.with.classfilter");
++ }
++
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null && isReflectiveCheckNeeded(clazz, isStatic)) {
+ checkReflectionPermission(sm);
+@@ -107,6 +117,12 @@
+ }
+
+ private static void checkLinkRequest(final LinkRequest origRequest) {
++ final Global global = Context.getGlobal();
++ final ClassFilter cf = global.getClassFilter();
++ if (cf != null) {
++ throw typeError("no.reflection.with.classfilter");
++ }
++
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ final LinkRequest requestWithoutContext = origRequest.withoutRuntimeContext(); // Nashorn has no runtime context
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/logging/DebugLogger.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,606 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.logging;
++
++import java.io.PrintWriter;
++import java.security.AccessControlContext;
++import java.security.AccessController;
++import java.security.Permissions;
++import java.security.PrivilegedAction;
++import java.security.ProtectionDomain;
++import java.util.logging.ConsoleHandler;
++import java.util.logging.Formatter;
++import java.util.logging.Handler;
++import java.util.logging.Level;
++import java.util.logging.LogRecord;
++import java.util.logging.Logger;
++import java.util.logging.LoggingPermission;
++import jdk.nashorn.internal.objects.Global;
++import jdk.nashorn.internal.runtime.Context;
++import jdk.nashorn.internal.runtime.ScriptFunction;
++import jdk.nashorn.internal.runtime.ScriptObject;
++import jdk.nashorn.internal.runtime.ScriptRuntime;
++import jdk.nashorn.internal.runtime.events.RuntimeEvent;
++
++/**
++ * Wrapper class for Logging system. This is how you are supposed to register a logger and use it
++ */
++
++public final class DebugLogger {
++
++ /** Disabled logger used for all loggers that need an instance, but shouldn't output anything */
++ public static final DebugLogger DISABLED_LOGGER = new DebugLogger("disabled", Level.OFF, false);
++
++ private final Logger logger;
++ private final boolean isEnabled;
++
++ private int indent;
++
++ private static final int INDENT_SPACE = 4;
++
++ /** A quiet logger only logs {@link RuntimeEvent}s and does't output any text, regardless of level */
++ private final boolean isQuiet;
++
++ /**
++ * Constructor
++ *
++ * A logger can be paired with a property, e.g. {@code --log:codegen:info} is equivalent to {@code -Dnashorn.codegen.log}
++ *
++ * @param loggerName name of logger - this is the unique key with which it can be identified
++ * @param loggerLevel level of the logger
++ * @param isQuiet is this a quiet logger, i.e. enabled for things like e.g. RuntimeEvent:s, but quiet otherwise
++ */
++ public DebugLogger(final String loggerName, final Level loggerLevel, final boolean isQuiet) {
++ this.logger = instantiateLogger(loggerName, loggerLevel);
++ this.isQuiet = isQuiet;
++ assert logger != null;
++ this.isEnabled = getLevel() != Level.OFF;
++ }
++
++ private static Logger instantiateLogger(final String name, final Level level) {
++ final Logger logger = java.util.logging.Logger.getLogger(name);
++ AccessController.doPrivileged(new PrivilegedAction<Void>() {
++ @Override
++ public Void run() {
++ for (final Handler h : logger.getHandlers()) {
++ logger.removeHandler(h);
++ }
++
++ logger.setLevel(level);
++ logger.setUseParentHandlers(false);
++ final Handler c = new ConsoleHandler();
++
++ c.setFormatter(new Formatter() {
++ @Override
++ public String format(final LogRecord record) {
++ final StringBuilder sb = new StringBuilder();
++
++ sb.append('[')
++ .append(record.getLoggerName())
++ .append("] ")
++ .append(record.getMessage())
++ .append('\n');
++
++ return sb.toString();
++ }
++ });
++ logger.addHandler(c);
++ c.setLevel(level);
++ return null;
++ }
++ }, createLoggerControlAccCtxt());
++
++ return logger;
++ }
++
++ /**
++ * Do not currently support chaining this with parent logger. Logger level null
++ * means disabled
++ * @return level
++ */
++ public Level getLevel() {
++ return logger.getLevel() == null ? Level.OFF : logger.getLevel();
++ }
++
++ /**
++ * Get the output writer for the logger. Loggers always default to
++ * stderr for output as they are used mainly to output debug info
++ *
++ * Can be inherited so this should not be static.
++ *
++ * @return print writer for log output.
++ */
++ @SuppressWarnings("static-method")
++ public PrintWriter getOutputStream() {
++ return Context.getCurrentErr();
++ }
++
++ /**
++ * Add quotes around a string
++ * @param str string
++ * @return quoted string
++ */
++ public static String quote(final String str) {
++ if (str.isEmpty()) {
++ return "''";
++ }
++
++ char startQuote = '\0';
++ char endQuote = '\0';
++ char quote = '\0';
++
++ if (str.startsWith("\\") || str.startsWith("\"")) {
++ startQuote = str.charAt(0);
++ }
++ if (str.endsWith("\\") || str.endsWith("\"")) {
++ endQuote = str.charAt(str.length() - 1);
++ }
++
++ if (startQuote == '\0' || endQuote == '\0') {
++ quote = startQuote == '\0' ? endQuote : startQuote;
++ }
++ if (quote == '\0') {
++ quote = '\'';
++ }
++
++ return (startQuote == '\0' ? quote : startQuote) + str + (endQuote == '\0' ? quote : endQuote);
++ }
++
++ /**
++ * Check if the logger is enabled
++ * @return true if enabled
++ */
++ public boolean isEnabled() {
++ return isEnabled;
++ }
++
++ /**
++ * Check if the logger is enabled
++ * @param logger logger to check, null will return false
++ * @return true if enabled
++ */
++ public static boolean isEnabled(final DebugLogger logger) {
++ return logger != null && logger.isEnabled();
++ }
++
++ /**
++ * If you want to change the indent level of your logger, call indent with a new position.
++ * Positions start at 0 and are increased by one for a new "tab"
++ *
++ * @param pos indent position
++ */
++ public void indent(final int pos) {
++ if (isEnabled) {
++ indent += pos * INDENT_SPACE;
++ }
++ }
++
++ /**
++ * Add an indent position
++ */
++ public void indent() {
++ indent += INDENT_SPACE;
++ }
++
++ /**
++ * Unindent a position
++ */
++ public void unindent() {
++ indent -= INDENT_SPACE;
++ if (indent < 0) {
++ indent = 0;
++ }
++ }
++
++ private static void logEvent(final RuntimeEvent<?> event) {
++ if (event != null) {
++ final Global global = Context.getGlobal();
++ if (global.has("Debug")) {
++ final ScriptObject debug = (ScriptObject)global.get("Debug");
++ final ScriptFunction addRuntimeEvent = (ScriptFunction)debug.get("addRuntimeEvent");
++ ScriptRuntime.apply(addRuntimeEvent, debug, event);
++ }
++ }
++ }
++
++ /**
++ * Check if the logger is above the level of detail given
++ * @see java.util.logging.Level
++ *
++ * The higher the level, the more severe the warning
++ *
++ * @param level logging level
++ * @return true if level is above the given one
++ */
++ public boolean levelCoarserThan(final Level level) {
++ return getLevel().intValue() > level.intValue();
++ }
++
++ /**
++ * Check if the logger is above or equal to the level
++ * of detail given
++ * @see java.util.logging.Level
++ *
++ * The higher the level, the more severe the warning
++ *
++ * @param level logging level
++ * @return true if level is above the given one
++ */
++ public boolean levelCoarserThanOrEqual(final Level level) {
++ return getLevel().intValue() >= level.intValue();
++ }
++
++ /**
++ * Check if the logger is below the level of detail given
++ * @see java.util.logging.Level
++ *
++ * The higher the level, the more severe the warning
++ *
++ * @param level logging level
++ * @return true if level is above the given one
++ */
++ public boolean levelFinerThan(final Level level) {
++ return getLevel().intValue() < level.intValue();
++ }
++
++ /**
++ * Check if the logger is below or equal to the level
++ * of detail given
++ * @see java.util.logging.Level
++ *
++ * The higher the level, the more severe the warning
++ *
++ * @param level logging level
++ * @return true if level is above the given one
++ */
++ public boolean levelFinerThanOrEqual(final Level level) {
++ return getLevel().intValue() <= level.intValue();
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level {@link java.util.logging.Level#FINEST} on this logger
++ * @param str the string to log
++ */
++ public void finest(final String str) {
++ log(Level.FINEST, str);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level {@link java.util.logging.Level#FINEST} on this logger
++ * @param event optional runtime event to log
++ * @param str the string to log
++ */
++ public void finest(final RuntimeEvent<?> event, final String str) {
++ finest(str);
++ logEvent(event);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#FINEST} on this logger
++ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
++ */
++ public void finest(final Object... objs) {
++ log(Level.FINEST, objs);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#FINEST} on this logger
++ * @param event optional runtime event to log
++ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
++ */
++ public void finest(final RuntimeEvent<?> event, final Object... objs) {
++ finest(objs);
++ logEvent(event);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#FINER} on this logger
++ * @param str the string to log
++ */
++ public void finer(final String str) {
++ log(Level.FINER, str);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#FINER} on this logger
++ * @param event optional runtime event to log
++ * @param str the string to log
++ */
++ public void finer(final RuntimeEvent<?> event, final String str) {
++ finer(str);
++ logEvent(event);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#FINER} on this logger
++ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
++ */
++ public void finer(final Object... objs) {
++ log(Level.FINER, objs);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#FINER} on this logger
++ * @param event optional runtime event to log
++ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
++ */
++ public void finer(final RuntimeEvent<?> event, final Object... objs) {
++ finer(objs);
++ logEvent(event);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#FINE} on this logger
++ * @param str the string to log
++ */
++ public void fine(final String str) {
++ log(Level.FINE, str);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#FINE} on this logger
++ * @param event optional runtime event to log
++ * @param str the string to log
++ */
++ public void fine(final RuntimeEvent<?> event, final String str) {
++ fine(str);
++ logEvent(event);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#FINE} on this logger
++ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
++ */
++ public void fine(final Object... objs) {
++ log(Level.FINE, objs);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#FINE} on this logger
++ * @param event optional runtime event to log
++ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
++ */
++ public void fine(final RuntimeEvent<?> event, final Object... objs) {
++ fine(objs);
++ logEvent(event);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#CONFIG} on this logger
++ * @param str the string to log
++ */
++ public void config(final String str) {
++ log(Level.CONFIG, str);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#CONFIG} on this logger
++ * @param event optional runtime event to log
++ * @param str the string to log
++ */
++ public void config(final RuntimeEvent<?> event, final String str) {
++ config(str);
++ logEvent(event);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#CONFIG} on this logger
++ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
++ */
++ public void config(final Object... objs) {
++ log(Level.CONFIG, objs);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#CONFIG} on this logger
++ * @param event optional runtime event to log
++ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
++ */
++ public void config(final RuntimeEvent<?> event, final Object... objs) {
++ config(objs);
++ logEvent(event);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#INFO} on this logger
++ * @param str the string to log
++ */
++ public void info(final String str) {
++ log(Level.INFO, str);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#INFO} on this logger
++ * @param event optional runtime event to log
++ * @param str the string to log
++ */
++ public void info(final RuntimeEvent<?> event, final String str) {
++ info(str);
++ logEvent(event);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#FINE} on this logger
++ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
++ */
++ public void info(final Object... objs) {
++ log(Level.INFO, objs);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#FINE} on this logger
++ * @param event optional runtime event to log
++ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
++ */
++ public void info(final RuntimeEvent<?> event, final Object... objs) {
++ info(objs);
++ logEvent(event);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#WARNING} on this logger
++ * @param str the string to log
++ */
++ public void warning(final String str) {
++ log(Level.WARNING, str);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#WARNING} on this logger
++ * @param event optional runtime event to log
++ * @param str the string to log
++ */
++ public void warning(final RuntimeEvent<?> event, final String str) {
++ warning(str);
++ logEvent(event);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#FINE} on this logger
++ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
++ */
++ public void warning(final Object... objs) {
++ log(Level.WARNING, objs);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#FINE} on this logger
++ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
++ * @param event optional runtime event to log
++ */
++ public void warning(final RuntimeEvent<?> event, final Object... objs) {
++ warning(objs);
++ logEvent(event);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#SEVERE} on this logger
++ * @param str the string to log
++ */
++ public void severe(final String str) {
++ log(Level.SEVERE, str);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#SEVERE} on this logger
++ * @param str the string to log
++ * @param event optional runtime event to log
++ */
++ public void severe(final RuntimeEvent<?> event, final String str) {
++ severe(str);
++ logEvent(event);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#SEVERE} on this logger
++ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
++ */
++ public void severe(final Object... objs) {
++ log(Level.SEVERE, objs);
++ }
++
++ /**
++ * Shorthand for outputting a log string as log level
++ * {@link java.util.logging.Level#FINE} on this logger
++ * @param event optional runtime event to log
++ * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
++ */
++ public void severe(final RuntimeEvent<?> event, final Object... objs) {
++ severe(objs);
++ logEvent(event);
++ }
++
++ /**
++ * Output log line on this logger at a given level of verbosity
++ * @see java.util.logging.Level
++ *
++ * @param level minimum log level required for logging to take place
++ * @param str string to log
++ */
++ public void log(final Level level, final String str) {
++ if (isEnabled && !isQuiet) {
++ final StringBuilder sb = new StringBuilder();
++ for (int i = 0 ; i < indent ; i++) {
++ sb.append(' ');
++ }
++ sb.append(str);
++ logger.log(level, sb.toString());
++ }
++ }
++
++ /**
++ * Output log line on this logger at a given level of verbosity
++ * @see java.util.logging.Level
++ *
++ * @param level minimum log level required for logging to take place
++ * @param objs objects for which to invoke toString and concatenate to log
++ */
++ public void log(final Level level, final Object... objs) {
++ if (isEnabled && !isQuiet) {
++ final StringBuilder sb = new StringBuilder();
++ for (final Object obj : objs) {
++ sb.append(obj);
++ }
++ log(level, sb.toString());
++ }
++ }
++
++ /**
++ * Access control context for logger level and instantiation permissions
++ * @return access control context
++ */
++ private static AccessControlContext createLoggerControlAccCtxt() {
++ final Permissions perms = new Permissions();
++ perms.add(new LoggingPermission("control", null));
++ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
++ }
++
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/logging/Loggable.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,56 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.logging;
++
++import jdk.nashorn.internal.runtime.Context;
++
++/**
++ * Interface implemented by classes that are loggable.
++ * Their instances will provide functionality for initializing
++ * a logger (usually by asking Global for it, with a reference
++ * to this.getClass()) and a method to return the logger in
++ * use
++ *
++ * Typically a class implementing this interface also has the
++ * Logger annotation
++ *
++ * @see Logger
++ */
++public interface Loggable {
++ /**
++ * Initialize a logger, by asking Context to get or create it
++ * and then keep it in a table by name
++ *
++ * @param context context
++ * @return the initialized logger
++ */
++ public DebugLogger initLogger(final Context context);
++
++ /**
++ * Return the logger in use
++ * @return logger
++ */
++ public DebugLogger getLogger();
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/logging/Logger.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.logging;
++
++import java.lang.annotation.Retention;
++import java.lang.annotation.RetentionPolicy;
++
++/**
++ * This annotation is associated with a class that has a logger.
++ * It contains a name property of the logger name. e.g. a class
++ * whose logger can be initialized by --log:fields, should be
++ * annotated @Logger(name="fields"). Multiple classes can have
++ * the same annotation, which will make them use the same logger
++ * object. Usually a class with this annotation is also a Loggable,
++ * but it is not a hard demand
++ *
++ * @see Loggable
++ */
++@Retention(RetentionPolicy.RUNTIME)
++public @interface Logger {
++ /**
++ * Get the name of the logger
++ * @return logger name
++ */
++ public String name() default "";
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/options/KeyValueOption.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/options/KeyValueOption.java Wed Feb 04 12:14:47 2015 -0800
+@@ -36,7 +36,7 @@
+ *
+ * {@code --log=module1:level1,module2:level2... }
+ */
+-public final class KeyValueOption extends Option<String> {
++public class KeyValueOption extends Option<String> {
+ /**
+ * Map of keys given
+ */
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/src/jdk/nashorn/internal/runtime/options/LoggingOption.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,133 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime.options;
++
++import java.util.Collections;
++import java.util.HashMap;
++import java.util.Locale;
++import java.util.Map;
++import java.util.Map.Entry;
++import java.util.logging.Level;
++
++/**
++ * Class that collects logging options like --log=compiler:finest,fields,recompile:fine into
++ * a map form that can be used to instantiate loggers in the Global object on demand
++ */
++public class LoggingOption extends KeyValueOption {
++
++ /**
++ * Logging info. Basically a logger name maps to this,
++ * which is a tuple of log level and the "is quiet" flag,
++ * which is a special log level used to collect RuntimeEvents
++ * only, but not output anything
++ */
++ public static class LoggerInfo {
++ private final Level level;
++ private final boolean isQuiet;
++
++ LoggerInfo(final Level level, final boolean isQuiet) {
++ this.level = level;
++ this.isQuiet = isQuiet;
++ }
++
++ /**
++ * Get the log level
++ * @return log level
++ */
++ public Level getLevel() {
++ return level;
++ }
++
++ /**
++ * Get the quiet flag
++ * @return true if quiet flag is set
++ */
++ public boolean isQuiet() {
++ return isQuiet;
++ }
++ }
++
++ private final Map<String, LoggerInfo> loggers = new HashMap<>();
++
++ LoggingOption(final String value) {
++ super(value);
++ initialize(getValues());
++ }
++
++ /**
++ * Return the logger info collected from this command line option
++ *
++ * @return map of logger name to logger info
++ */
++ public Map<String, LoggerInfo> getLoggers() {
++ return Collections.unmodifiableMap(loggers);
++ }
++
++ /**
++ * Initialization function that is called to instantiate the logging system. It takes
++ * logger names (keys) and logging labels respectively
++ *
++ * @param map a map where the key is a logger name and the value a logging level
++ * @throws IllegalArgumentException if level or names cannot be parsed
++ */
++ private void initialize(final Map<String, String> logMap) throws IllegalArgumentException {
++ try {
++ for (final Entry<String, String> entry : logMap.entrySet()) {
++ Level level;
++ final String name = lastPart(entry.getKey());
++ final String levelString = entry.getValue().toUpperCase(Locale.ENGLISH);
++ final boolean isQuiet;
++
++ if ("".equals(levelString)) {
++ level = Level.INFO;
++ isQuiet = false;
++ } else if ("QUIET".equals(levelString)) {
++ level = Level.INFO;
++ isQuiet = true;
++ } else {
++ level = Level.parse(levelString);
++ isQuiet = false;
++ }
++
++ loggers.put(name, new LoggerInfo(level, isQuiet));
++ }
++ } catch (final IllegalArgumentException | SecurityException e) {
++ throw e;
++ }
++ }
++
++
++
++ private static String lastPart(final String packageName) {
++ final String[] parts = packageName.split("\\.");
++ if (parts.length == 0) {
++ return packageName;
++ }
++ return parts[parts.length - 1];
++ }
++
++
++}
+--- ./nashorn/src/jdk/nashorn/internal/runtime/options/Options.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/options/Options.java Wed Feb 04 12:14:47 2015 -0800
+@@ -48,7 +48,6 @@
+ import java.util.TimeZone;
+ import java.util.TreeMap;
+ import java.util.TreeSet;
+-import jdk.nashorn.internal.runtime.Logging;
+ import jdk.nashorn.internal.runtime.QuotedStringTokenizer;
+
+ /**
+@@ -79,7 +78,10 @@
+ /** The options map of enabled options */
+ private final TreeMap<String, Option<?>> options;
+
+- /** System property that can be used for command line option propagation */
++ /** System property that can be used to prepend options to the explicitly specified command line. */
++ private static final String NASHORN_ARGS_PREPEND_PROPERTY = "nashorn.args.prepend";
++
++ /** System property that can be used to append options to the explicitly specified command line. */
+ private static final String NASHORN_ARGS_PROPERTY = "nashorn.args";
+
+ /**
+@@ -137,9 +139,10 @@
+ * Convenience function for getting system properties in a safe way
+
+ * @param name of boolean property
+- * @return true if set to true, false if unset or set to false
++ * @param defValue default value of boolean property
++ * @return true if set to true, default value if unset or set to false
+ */
+- public static boolean getBooleanProperty(final String name) {
++ public static boolean getBooleanProperty(final String name, final Boolean defValue) {
+ name.getClass(); // null check
+ if (!name.startsWith("nashorn.")) {
+ throw new IllegalArgumentException(name);
+@@ -151,6 +154,9 @@
+ public Boolean run() {
+ try {
+ final String property = System.getProperty(name);
++ if (property == null && defValue != null) {
++ return defValue;
++ }
+ return property != null && !"false".equalsIgnoreCase(property);
+ } catch (final SecurityException e) {
+ // if no permission to read, assume false
+@@ -162,6 +168,16 @@
+
+ /**
+ * Convenience function for getting system properties in a safe way
++
++ * @param name of boolean property
++ * @return true if set to true, false if unset or set to false
++ */
++ public static boolean getBooleanProperty(final String name) {
++ return getBooleanProperty(name, null);
++ }
++
++ /**
++ * Convenience function for getting system properties in a safe way
+ *
+ * @param name of string property
+ * @param defValue the default value if unset
+@@ -406,15 +422,9 @@
+ */
+ public void process(final String[] args) {
+ final LinkedList<String> argList = new LinkedList<>();
++ addSystemProperties(NASHORN_ARGS_PREPEND_PROPERTY, argList);
+ Collections.addAll(argList, args);
+-
+- final String extra = getStringProperty(NASHORN_ARGS_PROPERTY, null);
+- if (extra != null) {
+- final StringTokenizer st = new StringTokenizer(extra);
+- while (st.hasMoreTokens()) {
+- argList.add(st.nextToken());
+- }
+- }
++ addSystemProperties(NASHORN_ARGS_PROPERTY, argList);
+
+ while (!argList.isEmpty()) {
+ final String arg = argList.remove(0);
+@@ -496,6 +506,16 @@
+ }
+ }
+
++ private static void addSystemProperties(final String sysPropName, final List<String> argList) {
++ final String sysArgs = getStringProperty(sysPropName, null);
++ if (sysArgs != null) {
++ final StringTokenizer st = new StringTokenizer(sysArgs);
++ while (st.hasMoreTokens()) {
++ argList.add(st.nextToken());
++ }
++ }
++ }
++
+ private static OptionTemplate getOptionTemplate(final String key) {
+ for (final OptionTemplate t : Options.validOptions) {
+ if (t.matches(key)) {
+@@ -518,14 +538,12 @@
+ case "keyvalues":
+ return new KeyValueOption(value);
+ case "log":
+- final KeyValueOption kv = new KeyValueOption(value);
+- Logging.initialize(kv.getValues());
+- return kv;
++ return new LoggingOption(value);
+ case "boolean":
+ return new Option<>(value != null && Boolean.parseBoolean(value));
+ case "integer":
+ try {
+- return new Option<>((value == null) ? 0 : Integer.parseInt(value));
++ return new Option<>(value == null ? 0 : Integer.parseInt(value));
+ } catch (final NumberFormatException nfe) {
+ throw new IllegalOptionException(t);
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/JdkRegExp.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/JdkRegExp.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,8 +25,6 @@
+
+ package jdk.nashorn.internal.runtime.regexp;
+
+-import jdk.nashorn.internal.runtime.ParserException;
+-
+ import static java.util.regex.Pattern.CASE_INSENSITIVE;
+ import static java.util.regex.Pattern.MULTILINE;
+ import static java.util.regex.Pattern.UNICODE_CASE;
+@@ -34,6 +32,7 @@
+ import java.util.regex.Matcher;
+ import java.util.regex.Pattern;
+ import java.util.regex.PatternSyntaxException;
++import jdk.nashorn.internal.runtime.ParserException;
+
+ /**
+ * Default regular expression implementation based on java.util.regex package.
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,8 @@
+
+ package jdk.nashorn.internal.runtime.regexp;
+
++import java.util.regex.Pattern;
++import java.util.regex.PatternSyntaxException;
+ import jdk.nashorn.internal.runtime.ParserException;
+ import jdk.nashorn.internal.runtime.regexp.joni.Matcher;
+ import jdk.nashorn.internal.runtime.regexp.joni.Option;
+@@ -33,9 +35,6 @@
+ import jdk.nashorn.internal.runtime.regexp.joni.Syntax;
+ import jdk.nashorn.internal.runtime.regexp.joni.exception.JOniException;
+
+-import java.util.regex.Pattern;
+-import java.util.regex.PatternSyntaxException;
+-
+ /**
+ * Regular expression implementation based on the Joni engine from the JRuby project.
+ */
+@@ -77,7 +76,7 @@
+ }
+
+ if (parsed != null) {
+- char[] javaPattern = parsed.getJavaPattern().toCharArray();
++ final char[] javaPattern = parsed.getJavaPattern().toCharArray();
+ this.regex = new Regex(javaPattern, 0, javaPattern.length, option, Syntax.JAVASCRIPT);
+ this.groupsInNegativeLookahead = parsed.getGroupsInNegativeLookahead();
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExp.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExp.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,12 +25,11 @@
+
+ package jdk.nashorn.internal.runtime.regexp;
+
++import java.util.regex.MatchResult;
+ import jdk.nashorn.internal.runtime.BitVector;
+ import jdk.nashorn.internal.runtime.ECMAErrors;
+ import jdk.nashorn.internal.runtime.ParserException;
+
+-import java.util.regex.MatchResult;
+-
+ /**
+ * This is the base class for representing a parsed regular expression.
+ *
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,9 @@
+
+ package jdk.nashorn.internal.runtime.regexp;
+
++import java.util.Collections;
++import java.util.Set;
++import java.util.WeakHashMap;
+ import jdk.nashorn.internal.runtime.ParserException;
+ import jdk.nashorn.internal.runtime.options.Options;
+
+@@ -39,6 +42,15 @@
+ private final static String JDK = "jdk";
+ private final static String JONI = "joni";
+
++ /** Weak cache of already validated regexps - when reparsing, we don't, for example
++ * need to recompile (reverify) all regexps that have previously been parsed by this
++ * RegExpFactory in a previous compilation. This saves significant time in e.g. avatar
++ * startup */
++ private static final Set<String> VALID_CACHE_SET =
++ Collections.newSetFromMap(
++ Collections.synchronizedMap(
++ new WeakHashMap<String, Boolean>()));
++
+ static {
+ final String impl = Options.getStringProperty("nashorn.regexp.impl", JONI);
+ switch (impl) {
+@@ -88,7 +100,9 @@
+ */
+ // @SuppressWarnings({"unused"})
+ public static void validate(final String pattern, final String flags) throws ParserException {
+- instance.compile(pattern, flags);
++ if (VALID_CACHE_SET.add(pattern + flags)) {
++ instance.compile(pattern, flags);
++ }
+ }
+
+ /**
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java Wed Feb 04 12:14:47 2015 -0800
+@@ -31,7 +31,6 @@
+ import java.util.List;
+ import java.util.Map;
+ import java.util.regex.PatternSyntaxException;
+-
+ import jdk.nashorn.internal.parser.Lexer;
+ import jdk.nashorn.internal.parser.Scanner;
+ import jdk.nashorn.internal.runtime.BitVector;
+@@ -101,7 +100,7 @@
+
+ private void processForwardReferences() {
+
+- Iterator<Integer> iterator = forwardReferences.descendingIterator();
++ final Iterator<Integer> iterator = forwardReferences.descendingIterator();
+ while (iterator.hasNext()) {
+ final int pos = iterator.next();
+ final int num = iterator.next();
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,9 +27,7 @@
+ import static jdk.nashorn.internal.runtime.regexp.joni.Option.isMultiline;
+ import static jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode.newAltNode;
+ import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.isRepeatInfinite;
+-
+ import java.util.HashSet;
+-
+ import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
+ import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
+ import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
+@@ -50,10 +48,11 @@
+
+ final class Analyser extends Parser {
+
+- protected Analyser(ScanEnvironment env, char[] chars, int p, int end) {
++ protected Analyser(final ScanEnvironment env, final char[] chars, final int p, final int end) {
+ super(env, chars, p, end);
+ }
+
++ @SuppressWarnings("unused")
+ protected final void compile() {
+ if (Config.DEBUG) {
+ Config.log.println(new String(chars, getBegin(), getEnd()));
+@@ -77,7 +76,9 @@
+
+ root = setupTree(root, 0);
+ if (Config.DEBUG_PARSE_TREE) {
+- if (Config.DEBUG_PARSE_TREE_RAW) Config.log.println("<TREE>");
++ if (Config.DEBUG_PARSE_TREE_RAW) {
++ Config.log.println("<TREE>");
++ }
+ root.verifyTree(new HashSet<Node>(), env.reg.warnings);
+ Config.log.println(root + "\n");
+ }
+@@ -95,7 +96,9 @@
+
+ regex.clearOptimizeInfo();
+
+- if (!Config.DONT_OPTIMIZE) setOptimizedInfoFromTree(root);
++ if (!Config.DONT_OPTIMIZE) {
++ setOptimizedInfoFromTree(root);
++ }
+
+ env.memNodes = null;
+
+@@ -111,13 +114,15 @@
+
+ if (Config.DEBUG_COMPILE) {
+ Config.log.println("stack used: " + regex.stackNeeded);
+- if (Config.USE_STRING_TEMPLATES) Config.log.print("templates: " + regex.templateNum + "\n");
++ if (Config.USE_STRING_TEMPLATES) {
++ Config.log.print("templates: " + regex.templateNum + "\n");
++ }
+ Config.log.println(new ByteCodePrinter(regex).byteCodeListToString());
+
+ } // DEBUG_COMPILE
+ }
+
+- private void swap(Node a, Node b) {
++ private void swap(final Node a, final Node b) {
+ a.swap(b);
+
+ if (root == b) {
+@@ -128,7 +133,7 @@
+ }
+
+ // USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK
+- private int quantifiersMemoryInfo(Node node) {
++ private int quantifiersMemoryInfo(final Node node) {
+ int info = 0;
+
+ switch(node.getType()) {
+@@ -136,20 +141,22 @@
+ case NodeType.ALT:
+ ConsAltNode can = (ConsAltNode)node;
+ do {
+- int v = quantifiersMemoryInfo(can.car);
+- if (v > info) info = v;
++ final int v = quantifiersMemoryInfo(can.car);
++ if (v > info) {
++ info = v;
++ }
+ } while ((can = can.cdr) != null);
+ break;
+
+ case NodeType.QTFR:
+- QuantifierNode qn = (QuantifierNode)node;
++ final QuantifierNode qn = (QuantifierNode)node;
+ if (qn.upper != 0) {
+ info = quantifiersMemoryInfo(qn.target);
+ }
+ break;
+
+ case NodeType.ENCLOSE:
+- EncloseNode en = (EncloseNode)node;
++ final EncloseNode en = (EncloseNode)node;
+ switch (en.type) {
+ case EncloseType.MEMORY:
+ return TargetInfo.IS_EMPTY_MEM;
+@@ -177,13 +184,15 @@
+ return info;
+ }
+
+- private int getMinMatchLength(Node node) {
++ private int getMinMatchLength(final Node node) {
+ int min = 0;
+
+ switch (node.getType()) {
+ case NodeType.BREF:
+- BackRefNode br = (BackRefNode)node;
+- if (br.isRecursion()) break;
++ final BackRefNode br = (BackRefNode)node;
++ if (br.isRecursion()) {
++ break;
++ }
+
+ if (br.backRef > env.numMem) {
+ throw new ValueException(ERR_INVALID_BACKREF);
+@@ -202,8 +211,8 @@
+ case NodeType.ALT:
+ ConsAltNode y = (ConsAltNode)node;
+ do {
+- Node x = y.car;
+- int tmin = getMinMatchLength(x);
++ final Node x = y.car;
++ final int tmin = getMinMatchLength(x);
+ if (y == node) {
+ min = tmin;
+ } else if (min > tmin) {
+@@ -226,7 +235,7 @@
+ break;
+
+ case NodeType.QTFR:
+- QuantifierNode qn = (QuantifierNode)node;
++ final QuantifierNode qn = (QuantifierNode)node;
+ if (qn.lower > 0) {
+ min = getMinMatchLength(qn.target);
+ min = MinMaxLen.distanceMultiply(min, qn.lower);
+@@ -234,7 +243,7 @@
+ break;
+
+ case NodeType.ENCLOSE:
+- EncloseNode en = (EncloseNode)node;
++ final EncloseNode en = (EncloseNode)node;
+ switch (en.type) {
+ case EncloseType.MEMORY:
+ if (en.isMinFixed()) {
+@@ -250,6 +259,9 @@
+ case EncloseType.STOP_BACKTRACK:
+ min = getMinMatchLength(en.target);
+ break;
++
++ default:
++ break;
+ } // inner switch
+ break;
+
+@@ -261,14 +273,14 @@
+ return min;
+ }
+
+- private int getMaxMatchLength(Node node) {
++ private int getMaxMatchLength(final Node node) {
+ int max = 0;
+
+ switch (node.getType()) {
+ case NodeType.LIST:
+ ConsAltNode ln = (ConsAltNode)node;
+ do {
+- int tmax = getMaxMatchLength(ln.car);
++ final int tmax = getMaxMatchLength(ln.car);
+ max = MinMaxLen.distanceAdd(max, tmax);
+ } while ((ln = ln.cdr) != null);
+ break;
+@@ -276,8 +288,10 @@
+ case NodeType.ALT:
+ ConsAltNode an = (ConsAltNode)node;
+ do {
+- int tmax = getMaxMatchLength(an.car);
+- if (max < tmax) max = tmax;
++ final int tmax = getMaxMatchLength(an.car);
++ if (max < tmax) {
++ max = tmax;
++ }
+ } while ((an = an.cdr) != null);
+ break;
+
+@@ -295,7 +309,7 @@
+ break;
+
+ case NodeType.BREF:
+- BackRefNode br = (BackRefNode)node;
++ final BackRefNode br = (BackRefNode)node;
+ if (br.isRecursion()) {
+ max = MinMaxLen.INFINITE_DISTANCE;
+ break;
+@@ -304,12 +318,14 @@
+ if (br.backRef > env.numMem) {
+ throw new ValueException(ERR_INVALID_BACKREF);
+ }
+- int tmax = getMaxMatchLength(env.memNodes[br.backRef]);
+- if (max < tmax) max = tmax;
++ final int tmax = getMaxMatchLength(env.memNodes[br.backRef]);
++ if (max < tmax) {
++ max = tmax;
++ }
+ break;
+
+ case NodeType.QTFR:
+- QuantifierNode qn = (QuantifierNode)node;
++ final QuantifierNode qn = (QuantifierNode)node;
+ if (qn.upper != 0) {
+ max = getMaxMatchLength(qn.target);
+ if (max != 0) {
+@@ -323,7 +339,7 @@
+ break;
+
+ case NodeType.ENCLOSE:
+- EncloseNode en = (EncloseNode)node;
++ final EncloseNode en = (EncloseNode)node;
+ switch (en.type) {
+ case EncloseType.MEMORY:
+ if (en.isMaxFixed()) {
+@@ -339,6 +355,9 @@
+ case EncloseType.STOP_BACKTRACK:
+ max = getMaxMatchLength(en.target);
+ break;
++
++ default:
++ break;
+ } // inner switch
+ break;
+
+@@ -352,12 +371,12 @@
+
+ private static final int GET_CHAR_LEN_VARLEN = -1;
+ private static final int GET_CHAR_LEN_TOP_ALT_VARLEN = -2;
+- protected final int getCharLengthTree(Node node) {
++ protected final int getCharLengthTree(final Node node) {
+ return getCharLengthTree(node, 0);
+ }
+
+- private int getCharLengthTree(Node node, int level) {
+- level++;
++ private int getCharLengthTree(final Node node, final int levelp) {
++ final int level = levelp + 1;
+
+ int len = 0;
+ returnCode = 0;
+@@ -366,8 +385,10 @@
+ case NodeType.LIST:
+ ConsAltNode ln = (ConsAltNode)node;
+ do {
+- int tlen = getCharLengthTree(ln.car, level);
+- if (returnCode == 0) len = MinMaxLen.distanceAdd(len, tlen);
++ final int tlen = getCharLengthTree(ln.car, level);
++ if (returnCode == 0) {
++ len = MinMaxLen.distanceAdd(len, tlen);
++ }
+ } while (returnCode == 0 && (ln = ln.cdr) != null);
+ break;
+
+@@ -377,9 +398,11 @@
+
+ int tlen = getCharLengthTree(an.car, level);
+ while (returnCode == 0 && (an = an.cdr) != null) {
+- int tlen2 = getCharLengthTree(an.car, level);
++ final int tlen2 = getCharLengthTree(an.car, level);
+ if (returnCode == 0) {
+- if (tlen != tlen2) varLen = true;
++ if (tlen != tlen2) {
++ varLen = true;
++ }
+ }
+ }
+
+@@ -397,15 +420,17 @@
+ break;
+
+ case NodeType.STR:
+- StringNode sn = (StringNode)node;
++ final StringNode sn = (StringNode)node;
+ len = sn.length();
+ break;
+
+ case NodeType.QTFR:
+- QuantifierNode qn = (QuantifierNode)node;
++ final QuantifierNode qn = (QuantifierNode)node;
+ if (qn.lower == qn.upper) {
+ tlen = getCharLengthTree(qn.target, level);
+- if (returnCode == 0) len = MinMaxLen.distanceMultiply(tlen, qn.lower);
++ if (returnCode == 0) {
++ len = MinMaxLen.distanceMultiply(tlen, qn.lower);
++ }
+ } else {
+ returnCode = GET_CHAR_LEN_VARLEN;
+ }
+@@ -418,7 +443,7 @@
+ break;
+
+ case NodeType.ENCLOSE:
+- EncloseNode en = (EncloseNode)node;
++ final EncloseNode en = (EncloseNode)node;
+ switch(en.type) {
+ case EncloseType.MEMORY:
+ if (en.isCLenFixed()) {
+@@ -436,6 +461,9 @@
+ case EncloseType.STOP_BACKTRACK:
+ len = getCharLengthTree(en.target, level);
+ break;
++
++ default:
++ break;
+ } // inner switch
+ break;
+
+@@ -449,13 +477,15 @@
+ }
+
+ /* x is not included y ==> 1 : 0 */
+- private boolean isNotIncluded(Node x, Node y) {
++ private static boolean isNotIncluded(final Node xn, final Node yn) {
++ Node x = xn;
++ Node y = yn;
+ Node tmp;
+
+ // !retry:!
+ retry: while(true) {
+
+- int yType = y.getType();
++ final int yType = y.getType();
+
+ switch(x.getType()) {
+ case NodeType.CTYPE:
+@@ -482,21 +512,25 @@
+ break;
+
+ case NodeType.CCLASS:
+- CClassNode xc = (CClassNode)x;
++ final CClassNode xc = (CClassNode)x;
+
+ switch(yType) {
+
+ case NodeType.CCLASS:
+- CClassNode yc = (CClassNode)y;
++ final CClassNode yc = (CClassNode)y;
+
+ for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
+ boolean v = xc.bs.at(i);
+ if ((v && !xc.isNot()) || (!v && xc.isNot())) {
+ v = yc.bs.at(i);
+- if ((v && !yc.isNot()) || (!v && yc.isNot())) return false;
++ if ((v && !yc.isNot()) || (!v && yc.isNot())) {
++ return false;
++ }
+ }
+ }
+- if ((xc.mbuf == null && !xc.isNot()) || yc.mbuf == null && !yc.isNot()) return true;
++ if ((xc.mbuf == null && !xc.isNot()) || yc.mbuf == null && !yc.isNot()) {
++ return true;
++ }
+ return false;
+ // break; not reached
+
+@@ -514,26 +548,31 @@
+ break; // case NodeType.CCLASS
+
+ case NodeType.STR:
+- StringNode xs = (StringNode)x;
+- if (xs.length() == 0) break;
++ final StringNode xs = (StringNode)x;
++ if (xs.length() == 0) {
++ break;
++ }
+
+ switch (yType) {
+
+ case NodeType.CCLASS:
+- CClassNode cc = (CClassNode)y;
+- int code = xs.chars[xs.p];
++ final CClassNode cc = (CClassNode)y;
++ final int code = xs.chars[xs.p];
+ return !cc.isCodeInCC(code);
+
+ case NodeType.STR:
+- StringNode ys = (StringNode)y;
++ final StringNode ys = (StringNode)y;
+ int len = xs.length();
+- if (len > ys.length()) len = ys.length();
++ if (len > ys.length()) {
++ len = ys.length();
++ }
+ if (xs.isAmbig() || ys.isAmbig()) {
+ /* tiny version */
+ return false;
+- } else {
+- for (int i=0, p=ys.p, q=xs.p; i<len; i++, p++, q++) {
+- if (ys.chars[p] != xs.chars[q]) return true;
++ }
++ for (int i=0, pt=ys.p, q=xs.p; i<len; i++, pt++, q++) {
++ if (ys.chars[pt] != xs.chars[q]) {
++ return true;
+ }
+ }
+ break;
+@@ -543,6 +582,8 @@
+ } // inner switch
+
+ break; // case NodeType.STR
++ default:
++ break;
+
+ } // switch
+
+@@ -551,7 +592,7 @@
+ return false;
+ }
+
+- private Node getHeadValueNode(Node node, boolean exact) {
++ private Node getHeadValueNode(final Node node, final boolean exact) {
+ Node n = null;
+
+ switch(node.getType()) {
+@@ -562,7 +603,9 @@
+
+ case NodeType.CTYPE:
+ case NodeType.CCLASS:
+- if (!exact) n = node;
++ if (!exact) {
++ n = node;
++ }
+ break;
+
+ case NodeType.LIST:
+@@ -570,8 +613,11 @@
+ break;
+
+ case NodeType.STR:
+- StringNode sn = (StringNode)node;
+- if (sn.end <= sn.p) break; // ???
++ final StringNode sn = (StringNode)node;
++ if (sn.end <= sn.p)
++ {
++ break; // ???
++ }
+
+ if (exact && !sn.isRaw() && isIgnoreCase(regex.options)){
+ // nothing
+@@ -581,7 +627,7 @@
+ break;
+
+ case NodeType.QTFR:
+- QuantifierNode qn = (QuantifierNode)node;
++ final QuantifierNode qn = (QuantifierNode)node;
+ if (qn.lower > 0) {
+ if (qn.headExact != null) {
+ n = qn.headExact;
+@@ -592,11 +638,11 @@
+ break;
+
+ case NodeType.ENCLOSE:
+- EncloseNode en = (EncloseNode)node;
++ final EncloseNode en = (EncloseNode)node;
+
+ switch (en.type) {
+ case EncloseType.OPTION:
+- int options = regex.options;
++ final int options = regex.options;
+ regex.options = en.option;
+ n = getHeadValueNode(en.target, exact);
+ regex.options = options;
+@@ -606,12 +652,17 @@
+ case EncloseType.STOP_BACKTRACK:
+ n = getHeadValueNode(en.target, exact);
+ break;
++
++ default:
++ break;
+ } // inner switch
+ break;
+
+ case NodeType.ANCHOR:
+- AnchorNode an = (AnchorNode)node;
+- if (an.type == AnchorType.PREC_READ) n = getHeadValueNode(an.target, exact);
++ final AnchorNode an = (AnchorNode)node;
++ if (an.type == AnchorType.PREC_READ) {
++ n = getHeadValueNode(an.target, exact);
++ }
+ break;
+
+ default:
+@@ -622,8 +673,10 @@
+ }
+
+ // true: invalid
+- private boolean checkTypeTree(Node node, int typeMask, int encloseMask, int anchorMask) {
+- if ((node.getType2Bit() & typeMask) == 0) return true;
++ private boolean checkTypeTree(final Node node, final int typeMask, final int encloseMask, final int anchorMask) {
++ if ((node.getType2Bit() & typeMask) == 0) {
++ return true;
++ }
+
+ boolean invalid = false;
+
+@@ -641,16 +694,22 @@
+ break;
+
+ case NodeType.ENCLOSE:
+- EncloseNode en = (EncloseNode)node;
+- if ((en.type & encloseMask) == 0) return true;
++ final EncloseNode en = (EncloseNode)node;
++ if ((en.type & encloseMask) == 0) {
++ return true;
++ }
+ invalid = checkTypeTree(en.target, typeMask, encloseMask, anchorMask);
+ break;
+
+ case NodeType.ANCHOR:
+- AnchorNode an = (AnchorNode)node;
+- if ((an.type & anchorMask) == 0) return true;
++ final AnchorNode an = (AnchorNode)node;
++ if ((an.type & anchorMask) == 0) {
++ return true;
++ }
+
+- if (an.target != null) invalid = checkTypeTree(an.target, typeMask, encloseMask, anchorMask);
++ if (an.target != null) {
++ invalid = checkTypeTree(an.target, typeMask, encloseMask, anchorMask);
++ }
+ break;
+
+ default:
+@@ -665,15 +724,16 @@
+ (?<=A|B) ==> (?<=A)|(?<=B)
+ (?<!A|B) ==> (?<!A)(?<!B)
+ */
+- private Node divideLookBehindAlternatives(Node node) {
+- AnchorNode an = (AnchorNode)node;
+- int anchorType = an.type;
++ private Node divideLookBehindAlternatives(final Node nodep) {
++ Node node = nodep;
++ final AnchorNode an = (AnchorNode)node;
++ final int anchorType = an.type;
+ Node head = an.target;
+ Node np = ((ConsAltNode)head).car;
+
+ swap(node, head);
+
+- Node tmp = node;
++ final Node tmp = node;
+ node = head;
+ head = tmp;
+
+@@ -682,7 +742,7 @@
+ np = node;
+
+ while ((np = ((ConsAltNode)np).cdr) != null) {
+- AnchorNode insert = new AnchorNode(anchorType);
++ final AnchorNode insert = new AnchorNode(anchorType);
+ insert.setTarget(((ConsAltNode)np).car);
+ ((ConsAltNode)np).setCar(insert);
+ }
+@@ -697,10 +757,10 @@
+ return node;
+ }
+
+- private Node setupLookBehind(Node node) {
+- AnchorNode an = (AnchorNode)node;
+- int len = getCharLengthTree(an.target);
+- switch(returnCode) {
++ private Node setupLookBehind(final Node node) {
++ final AnchorNode an = (AnchorNode)node;
++ final int len = getCharLengthTree(an.target);
++ switch (returnCode) {
+ case 0:
+ an.charLength = len;
+ break;
+@@ -709,23 +769,26 @@
+ case GET_CHAR_LEN_TOP_ALT_VARLEN:
+ if (syntax.differentLengthAltLookBehind()) {
+ return divideLookBehindAlternatives(node);
+- } else {
+- throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
+ }
++ throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
++ default:
++ break;
+ }
+ return node;
+ }
+
+- private void nextSetup(Node node, Node nextNode) {
++ private void nextSetup(final Node nodep, final Node nextNode) {
++ Node node = nodep;
++
+ // retry:
+ retry: while(true) {
+
+- int type = node.getType();
++ final int type = node.getType();
+ if (type == NodeType.QTFR) {
+- QuantifierNode qn = (QuantifierNode)node;
++ final QuantifierNode qn = (QuantifierNode)node;
+ if (qn.greedy && isRepeatInfinite(qn.upper)) {
+ if (Config.USE_QTFR_PEEK_NEXT) {
+- StringNode n = (StringNode)getHeadValueNode(nextNode, true);
++ final StringNode n = (StringNode)getHeadValueNode(nextNode, true);
+ /* '\0': for UTF-16BE etc... */
+ if (n != null && n.chars[n.p] != 0) { // ?????????
+ qn.nextHeadExact = n;
+@@ -734,11 +797,11 @@
+ /* automatic posseivation a*b ==> (?>a*)b */
+ if (qn.lower <= 1) {
+ if (qn.target.isSimple()) {
+- Node x = getHeadValueNode(qn.target, false);
++ final Node x = getHeadValueNode(qn.target, false);
+ if (x != null) {
+- Node y = getHeadValueNode(nextNode, false);
++ final Node y = getHeadValueNode(nextNode, false);
+ if (y != null && isNotIncluded(x, y)) {
+- EncloseNode en = new EncloseNode(EncloseType.STOP_BACKTRACK); //onig_node_new_enclose
++ final EncloseNode en = new EncloseNode(EncloseType.STOP_BACKTRACK); //onig_node_new_enclose
+ en.setStopBtSimpleRepeat();
+ //en.setTarget(qn.target); // optimize it ??
+ swap(node, en);
+@@ -750,7 +813,7 @@
+ }
+ }
+ } else if (type == NodeType.ENCLOSE) {
+- EncloseNode en = (EncloseNode)node;
++ final EncloseNode en = (EncloseNode)node;
+ if (en.isMemory()) {
+ node = en.target;
+ // !goto retry;!
+@@ -762,26 +825,26 @@
+ } // while
+ }
+
+- private void updateStringNodeCaseFoldMultiByte(StringNode sn) {
+- char[] chars = sn.chars;
+- int end = sn.end;
++ private void updateStringNodeCaseFoldMultiByte(final StringNode sn) {
++ final char[] ch = sn.chars;
++ final int end = sn.end;
+ value = sn.p;
+ int sp = 0;
+ char buf;
+
+ while (value < end) {
+- int ovalue = value;
+- buf = EncodingHelper.toLowerCase(chars[value++]);
++ final int ovalue = value;
++ buf = EncodingHelper.toLowerCase(ch[value++]);
+
+- if (chars[ovalue] != buf) {
++ if (ch[ovalue] != buf) {
+
+ char[] sbuf = new char[sn.length() << 1];
+- System.arraycopy(chars, sn.p, sbuf, 0, ovalue - sn.p);
++ System.arraycopy(ch, sn.p, sbuf, 0, ovalue - sn.p);
+ value = ovalue;
+ while (value < end) {
+- buf = EncodingHelper.toLowerCase(chars[value++]);
++ buf = EncodingHelper.toLowerCase(ch[value++]);
+ if (sp >= sbuf.length) {
+- char[]tmp = new char[sbuf.length << 1];
++ final char[]tmp = new char[sbuf.length << 1];
+ System.arraycopy(sbuf, 0, tmp, 0, sbuf.length);
+ sbuf = tmp;
+ }
+@@ -794,13 +857,13 @@
+ }
+ }
+
+- private void updateStringNodeCaseFold(Node node) {
+- StringNode sn = (StringNode)node;
++ private void updateStringNodeCaseFold(final Node node) {
++ final StringNode sn = (StringNode)node;
+ updateStringNodeCaseFoldMultiByte(sn);
+ }
+
+- private Node expandCaseFoldMakeRemString(char[] chars, int p, int end) {
+- StringNode node = new StringNode(chars, p, end);
++ private Node expandCaseFoldMakeRemString(final char[] ch, final int pp, final int end) {
++ final StringNode node = new StringNode(ch, pp, end);
+
+ updateStringNodeCaseFold(node);
+ node.setAmbig();
+@@ -808,8 +871,8 @@
+ return node;
+ }
+
+- private boolean expandCaseFoldStringAlt(int itemNum, char[] items,
+- char[] chars, int p, int slen, int end, ObjPtr<Node> node) {
++ private static boolean expandCaseFoldStringAlt(final int itemNum, final char[] items,
++ final char[] chars, final int p, final int slen, final int end, final ObjPtr<Node> node) {
+
+ ConsAltNode altNode;
+ node.p = altNode = newAltNode(null, null);
+@@ -822,7 +885,7 @@
+
+ snode.catCode(items[i]);
+
+- ConsAltNode an = newAltNode(null, null);
++ final ConsAltNode an = newAltNode(null, null);
+ an.setCar(snode);
+ altNode.setCdr(an);
+ altNode = an;
+@@ -831,66 +894,75 @@
+ }
+
+ private static final int THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION = 8;
+- private Node expandCaseFoldString(Node node) {
+- StringNode sn = (StringNode)node;
++ private Node expandCaseFoldString(final Node node) {
++ final StringNode sn = (StringNode)node;
+
+- if (sn.isAmbig() || sn.length() <= 0) return node;
++ if (sn.isAmbig() || sn.length() <= 0) {
++ return node;
++ }
+
+- char[] chars = sn.chars;
+- int p = sn.p;
+- int end = sn.end;
++ final char[] chars1 = sn.chars;
++ int pt = sn.p;
++ final int end = sn.end;
+ int altNum = 1;
+
+- ConsAltNode topRoot = null, root = null;
+- ObjPtr<Node> prevNode = new ObjPtr<Node>();
++ ConsAltNode topRoot = null, r = null;
++ @SuppressWarnings("unused")
++ final ObjPtr<Node> prevNode = new ObjPtr<Node>();
+ StringNode stringNode = null;
+
+- while (p < end) {
+- char[] items = EncodingHelper.caseFoldCodesByString(regex.caseFoldFlag, chars[p]);
++ while (pt < end) {
++ final char[] items = EncodingHelper.caseFoldCodesByString(regex.caseFoldFlag, chars1[pt]);
+
+ if (items.length == 0) {
+ if (stringNode == null) {
+- if (root == null && prevNode.p != null) {
+- topRoot = root = ConsAltNode.listAdd(null, prevNode.p);
++ if (r == null && prevNode.p != null) {
++ topRoot = r = ConsAltNode.listAdd(null, prevNode.p);
+ }
+
+ prevNode.p = stringNode = new StringNode(); // onig_node_new_str(NULL, NULL);
+
+- if (root != null) ConsAltNode.listAdd(root, stringNode);
++ if (r != null) {
++ ConsAltNode.listAdd(r, stringNode);
++ }
+
+ }
+
+- stringNode.cat(chars, p, p + 1);
++ stringNode.cat(chars1, pt, pt + 1);
+ } else {
+ altNum *= (items.length + 1);
+- if (altNum > THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION) break;
+-
+- if (root == null && prevNode.p != null) {
+- topRoot = root = ConsAltNode.listAdd(null, prevNode.p);
++ if (altNum > THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION) {
++ break;
+ }
+
+- expandCaseFoldStringAlt(items.length, items, chars, p, 1, end, prevNode);
+- if (root != null) ConsAltNode.listAdd(root, prevNode.p);
++ if (r == null && prevNode.p != null) {
++ topRoot = r = ConsAltNode.listAdd(null, prevNode.p);
++ }
++
++ expandCaseFoldStringAlt(items.length, items, chars1, pt, 1, end, prevNode);
++ if (r != null) {
++ ConsAltNode.listAdd(r, prevNode.p);
++ }
+ stringNode = null;
+ }
+- p++;
++ pt++;
+ }
+
+- if (p < end) {
+- Node srem = expandCaseFoldMakeRemString(chars, p, end);
++ if (pt < end) {
++ final Node srem = expandCaseFoldMakeRemString(chars1, pt, end);
+
+- if (prevNode.p != null && root == null) {
+- topRoot = root = ConsAltNode.listAdd(null, prevNode.p);
++ if (prevNode.p != null && r == null) {
++ topRoot = r = ConsAltNode.listAdd(null, prevNode.p);
+ }
+
+- if (root == null) {
++ if (r == null) {
+ prevNode.p = srem;
+ } else {
+- ConsAltNode.listAdd(root, srem);
++ ConsAltNode.listAdd(r, srem);
+ }
+ }
+ /* ending */
+- Node xnode = topRoot != null ? topRoot : prevNode.p;
++ final Node xnode = topRoot != null ? topRoot : prevNode.p;
+
+ swap(node, xnode);
+ return xnode;
+@@ -910,7 +982,10 @@
+ 5. find invalid patterns in look-behind.
+ 6. expand repeated string.
+ */
+- protected final Node setupTree(Node node, int state) {
++ protected final Node setupTree(final Node nodep, final int statep) {
++ Node node = nodep;
++ int state = statep;
++
+ restart: while (true) {
+ switch (node.getType()) {
+ case NodeType.LIST:
+@@ -946,7 +1021,7 @@
+ break;
+
+ case NodeType.BREF:
+- BackRefNode br = (BackRefNode)node;
++ final BackRefNode br = (BackRefNode)node;
+ if (br.backRef > env.numMem) {
+ throw new ValueException(ERR_INVALID_BACKREF);
+ }
+@@ -956,25 +1031,31 @@
+ break;
+
+ case NodeType.QTFR:
+- QuantifierNode qn = (QuantifierNode)node;
++ final QuantifierNode qn = (QuantifierNode)node;
+ Node target = qn.target;
+
+- if ((state & IN_REPEAT) != 0) qn.setInRepeat();
++ if ((state & IN_REPEAT) != 0) {
++ qn.setInRepeat();
++ }
+
+ if (isRepeatInfinite(qn.upper) || qn.lower >= 1) {
+- int d = getMinMatchLength(target);
++ final int d = getMinMatchLength(target);
+ if (d == 0) {
+ qn.targetEmptyInfo = TargetInfo.IS_EMPTY;
+ if (Config.USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT) {
+- int info = quantifiersMemoryInfo(target);
+- if (info > 0) qn.targetEmptyInfo = info;
++ final int info = quantifiersMemoryInfo(target);
++ if (info > 0) {
++ qn.targetEmptyInfo = info;
++ }
+ } // USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK
+ // strange stuff here (turned off)
+ }
+ }
+
+ state |= IN_REPEAT;
+- if (qn.lower != qn.upper) state |= IN_VAR_REPEAT;
++ if (qn.lower != qn.upper) {
++ state |= IN_VAR_REPEAT;
++ }
+
+ target = setupTree(target, state);
+
+@@ -982,12 +1063,12 @@
+ if (target.getType() == NodeType.STR) {
+ if (!isRepeatInfinite(qn.lower) && qn.lower == qn.upper &&
+ qn.lower > 1 && qn.lower <= EXPAND_STRING_MAX_LENGTH) {
+- StringNode sn = (StringNode)target;
+- int len = sn.length();
++ final StringNode sn = (StringNode)target;
++ final int len = sn.length();
+
+ if (len * qn.lower <= EXPAND_STRING_MAX_LENGTH) {
+- StringNode str = qn.convertToString(sn.flag);
+- int n = qn.lower;
++ final StringNode str = qn.convertToString(sn.flag);
++ final int n = qn.lower;
+ for (int i = 0; i < n; i++) {
+ str.cat(sn.chars, sn.p, sn.end);
+ }
+@@ -999,7 +1080,7 @@
+ if (Config.USE_OP_PUSH_OR_JUMP_EXACT) {
+ if (qn.greedy && qn.targetEmptyInfo != 0) {
+ if (target.getType() == NodeType.QTFR) {
+- QuantifierNode tqn = (QuantifierNode)target;
++ final QuantifierNode tqn = (QuantifierNode)target;
+ if (tqn.headExact != null) {
+ qn.headExact = tqn.headExact;
+ tqn.headExact = null;
+@@ -1012,10 +1093,10 @@
+ break;
+
+ case NodeType.ENCLOSE:
+- EncloseNode en = (EncloseNode)node;
++ final EncloseNode en = (EncloseNode)node;
+ switch (en.type) {
+ case EncloseType.OPTION:
+- int options = regex.options;
++ final int options = regex.options;
+ regex.options = en.option;
+ setupTree(en.target, state);
+ regex.options = options;
+@@ -1033,19 +1114,24 @@
+ case EncloseType.STOP_BACKTRACK:
+ setupTree(en.target, state);
+ if (en.target.getType() == NodeType.QTFR) {
+- QuantifierNode tqn = (QuantifierNode)en.target;
++ final QuantifierNode tqn = (QuantifierNode)en.target;
+ if (isRepeatInfinite(tqn.upper) && tqn.lower <= 1 && tqn.greedy) {
+ /* (?>a*), a*+ etc... */
+- if (tqn.target.isSimple()) en.setStopBtSimpleRepeat();
++ if (tqn.target.isSimple()) {
++ en.setStopBtSimpleRepeat();
++ }
+ }
+ }
+ break;
+
++ default:
++ break;
++
+ } // inner switch
+ break;
+
+ case NodeType.ANCHOR:
+- AnchorNode an = (AnchorNode)node;
++ final AnchorNode an = (AnchorNode)node;
+ switch (an.type) {
+ case AnchorType.PREC_READ:
+ setupTree(an.target, state);
+@@ -1060,7 +1146,9 @@
+ throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
+ }
+ node = setupLookBehind(node);
+- if (node.getType() != NodeType.ANCHOR) continue restart;
++ if (node.getType() != NodeType.ANCHOR) {
++ continue restart;
++ }
+ setupTree(((AnchorNode)node).target, state);
+ break;
+
+@@ -1069,26 +1157,33 @@
+ throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
+ }
+ node = setupLookBehind(node);
+- if (node.getType() != NodeType.ANCHOR) continue restart;
++ if (node.getType() != NodeType.ANCHOR) {
++ continue restart;
++ }
+ setupTree(((AnchorNode)node).target, (state | IN_NOT));
+ break;
+
++ default:
++ break;
++
+ } // inner switch
+ break;
++ default:
++ break;
+ } // switch
+ return node;
+ } // restart: while
+ }
+
+ private static final int MAX_NODE_OPT_INFO_REF_COUNT = 5;
+- private void optimizeNodeLeft(Node node, NodeOptInfo opt, OptEnvironment oenv) { // oenv remove, pass mmd
++ private void optimizeNodeLeft(final Node node, final NodeOptInfo opt, final OptEnvironment oenv) { // oenv remove, pass mmd
+ opt.clear();
+ opt.setBoundNode(oenv.mmd);
+
+ switch (node.getType()) {
+ case NodeType.LIST: {
+- OptEnvironment nenv = new OptEnvironment();
+- NodeOptInfo nopt = new NodeOptInfo();
++ final OptEnvironment nenv = new OptEnvironment();
++ final NodeOptInfo nopt = new NodeOptInfo();
+ nenv.copy(oenv);
+ ConsAltNode lin = (ConsAltNode)node;
+ do {
+@@ -1100,7 +1195,7 @@
+ }
+
+ case NodeType.ALT: {
+- NodeOptInfo nopt = new NodeOptInfo();
++ final NodeOptInfo nopt = new NodeOptInfo();
+ ConsAltNode aln = (ConsAltNode)node;
+ do {
+ optimizeNodeLeft(aln.car, nopt, oenv);
+@@ -1114,9 +1209,9 @@
+ }
+
+ case NodeType.STR: {
+- StringNode sn = (StringNode)node;
++ final StringNode sn = (StringNode)node;
+
+- int slen = sn.length();
++ final int slen = sn.length();
+
+ if (!sn.isAmbig()) {
+ opt.exb.concatStr(sn.chars, sn.p, sn.end, sn.isRaw());
+@@ -1150,13 +1245,13 @@
+ }
+
+ case NodeType.CCLASS: {
+- CClassNode cc = (CClassNode)node;
++ final CClassNode cc = (CClassNode)node;
+ /* no need to check ignore case. (setted in setup_tree()) */
+ if (cc.mbuf != null || cc.isNot()) {
+ opt.length.set(1, 1);
+ } else {
+ for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
+- boolean z = cc.bs.at(i);
++ final boolean z = cc.bs.at(i);
+ if ((z && !cc.isNot()) || (!z && cc.isNot())) {
+ opt.map.addChar(i);
+ }
+@@ -1172,7 +1267,7 @@
+ }
+
+ case NodeType.ANCHOR: {
+- AnchorNode an = (AnchorNode)node;
++ final AnchorNode an = (AnchorNode)node;
+ switch (an.type) {
+ case AnchorType.BEGIN_BUF:
+ case AnchorType.BEGIN_POSITION:
+@@ -1184,7 +1279,7 @@
+ break;
+
+ case AnchorType.PREC_READ:
+- NodeOptInfo nopt = new NodeOptInfo();
++ final NodeOptInfo nopt = new NodeOptInfo();
+ optimizeNodeLeft(an.target, nopt, oenv);
+ if (nopt.exb.length > 0) {
+ opt.expr.copy(nopt.exb);
+@@ -1192,7 +1287,9 @@
+ opt.expr.copy(nopt.exm);
+ }
+ opt.expr.reachEnd = false;
+- if (nopt.map.value > 0) opt.map.copy(nopt.map);
++ if (nopt.map.value > 0) {
++ opt.map.copy(nopt.map);
++ }
+ break;
+
+ case AnchorType.PREC_READ_NOT:
+@@ -1200,22 +1297,25 @@
+ case AnchorType.LOOK_BEHIND_NOT:
+ break;
+
++ default:
++ break;
++
+ } // inner switch
+ break;
+ }
+
+ case NodeType.BREF: {
+- BackRefNode br = (BackRefNode)node;
++ final BackRefNode br = (BackRefNode)node;
+
+ if (br.isRecursion()) {
+ opt.length.set(0, MinMaxLen.INFINITE_DISTANCE);
+ break;
+ }
+
+- Node[]nodes = oenv.scanEnv.memNodes;
++ final Node[]nodes = oenv.scanEnv.memNodes;
+
+- int min = getMinMatchLength(nodes[br.backRef]);
+- int max = getMaxMatchLength(nodes[br.backRef]);
++ final int min = getMinMatchLength(nodes[br.backRef]);
++ final int max = getMaxMatchLength(nodes[br.backRef]);
+
+ opt.length.set(min, max);
+ break;
+@@ -1223,8 +1323,8 @@
+
+
+ case NodeType.QTFR: {
+- NodeOptInfo nopt = new NodeOptInfo();
+- QuantifierNode qn = (QuantifierNode)node;
++ final NodeOptInfo nopt = new NodeOptInfo();
++ final QuantifierNode qn = (QuantifierNode)node;
+ optimizeNodeLeft(qn.target, nopt, oenv);
+ if (qn.lower == 0 && isRepeatInfinite(qn.upper)) {
+ if (oenv.mmd.max == 0 && qn.target.getType() == NodeType.CANY && qn.greedy) {
+@@ -1258,7 +1358,7 @@
+
+ }
+ }
+- int min = MinMaxLen.distanceMultiply(nopt.length.min, qn.lower);
++ final int min = MinMaxLen.distanceMultiply(nopt.length.min, qn.lower);
+ int max;
+ if (isRepeatInfinite(qn.upper)) {
+ max = nopt.length.max > 0 ? MinMaxLen.INFINITE_DISTANCE : 0;
+@@ -1270,10 +1370,10 @@
+ }
+
+ case NodeType.ENCLOSE: {
+- EncloseNode en = (EncloseNode)node;
++ final EncloseNode en = (EncloseNode)node;
+ switch (en.type) {
+ case EncloseType.OPTION:
+- int save = oenv.options;
++ final int save = oenv.options;
+ oenv.options = en.option;
+ optimizeNodeLeft(en.target, opt, oenv);
+ oenv.options = save;
+@@ -1283,8 +1383,12 @@
+ if (++en.optCount > MAX_NODE_OPT_INFO_REF_COUNT) {
+ int min = 0;
+ int max = MinMaxLen.INFINITE_DISTANCE;
+- if (en.isMinFixed()) min = en.minLength;
+- if (en.isMaxFixed()) max = en.maxLength;
++ if (en.isMinFixed()) {
++ min = en.minLength;
++ }
++ if (en.isMaxFixed()) {
++ max = en.maxLength;
++ }
+ opt.length.set(min, max);
+ } else { // USE_SUBEXP_CALL
+ optimizeNodeLeft(en.target, opt, oenv);
+@@ -1299,6 +1403,9 @@
+ case EncloseType.STOP_BACKTRACK:
+ optimizeNodeLeft(en.target, opt, oenv);
+ break;
++
++ default:
++ break;
+ } // inner switch
+ break;
+ }
+@@ -1308,9 +1415,10 @@
+ } // switch
+ }
+
+- protected final void setOptimizedInfoFromTree(Node node) {
+- NodeOptInfo opt = new NodeOptInfo();
+- OptEnvironment oenv = new OptEnvironment();
++ @SuppressWarnings("unused")
++ protected final void setOptimizedInfoFromTree(final Node node) {
++ final NodeOptInfo opt = new NodeOptInfo();
++ final OptEnvironment oenv = new OptEnvironment();
+
+ oenv.options = regex.options;
+ oenv.caseFoldFlag = regex.caseFoldFlag;
+@@ -1348,7 +1456,9 @@
+ regex.setSubAnchor(opt.map.anchor);
+ } else {
+ regex.subAnchor |= opt.anchor.leftAnchor & AnchorType.BEGIN_LINE;
+- if (opt.length.max == 0) regex.subAnchor |= opt.anchor.rightAnchor & AnchorType.END_LINE;
++ if (opt.length.max == 0) {
++ regex.subAnchor |= opt.anchor.rightAnchor & AnchorType.END_LINE;
++ }
+ }
+
+ if (Config.DEBUG_COMPILE || Config.DEBUG_MATCH) {
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java Wed Feb 04 12:14:47 2015 -0800
+@@ -24,14 +24,14 @@
+ final class ApplyCaseFold {
+
+ // i_apply_case_fold
+- public void apply(int from, int to, Object o) {
+- ApplyCaseFoldArg arg = (ApplyCaseFoldArg)o;
++ public static void apply(final int from, final int to, final Object o) {
++ final ApplyCaseFoldArg arg = (ApplyCaseFoldArg)o;
+
+- ScanEnvironment env = arg.env;
+- CClassNode cc = arg.cc;
+- BitSet bs = cc.bs;
++ final ScanEnvironment env = arg.env;
++ final CClassNode cc = arg.cc;
++ final BitSet bs = cc.bs;
+
+- boolean inCC = cc.isCodeInCC(from);
++ final boolean inCC = cc.isCodeInCC(from);
+
+ if (Config.CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS) {
+ if ((inCC && !cc.isNot()) || (!inCC && cc.isNot())) {
+@@ -45,7 +45,9 @@
+ } else {
+ if (inCC) {
+ if (to >= BitSet.SINGLE_BYTE_SIZE) {
+- if (cc.isNot()) cc.clearNotFlag();
++ if (cc.isNot()) {
++ cc.clearNotFlag();
++ }
+ cc.addCodeRange(env, to, to);
+ } else {
+ if (cc.isNot()) {
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFoldArg.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFoldArg.java Wed Feb 04 12:14:47 2015 -0800
+@@ -22,13 +22,14 @@
+ import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
+ import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
+
++@SuppressWarnings("javadoc")
+ public final class ApplyCaseFoldArg {
+ final ScanEnvironment env;
+ final CClassNode cc;
+ ConsAltNode altRoot;
+ ConsAltNode tail;
+
+- public ApplyCaseFoldArg(ScanEnvironment env, CClassNode cc) {
++ public ApplyCaseFoldArg(final ScanEnvironment env, final CClassNode cc) {
+ this.env = env;
+ this.cc = cc;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ArrayCompiler.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ArrayCompiler.java Wed Feb 04 12:14:47 2015 -0800
+@@ -24,7 +24,6 @@
+ import static jdk.nashorn.internal.runtime.regexp.joni.Option.isIgnoreCase;
+ import static jdk.nashorn.internal.runtime.regexp.joni.Option.isMultiline;
+ import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.isRepeatInfinite;
+-
+ import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
+ import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
+ import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
+@@ -47,13 +46,13 @@
+ private char[][] templates;
+ private int templateNum;
+
+- ArrayCompiler(Analyser analyser) {
++ ArrayCompiler(final Analyser analyser) {
+ super(analyser);
+ }
+
+ @Override
+ protected final void prepare() {
+- int codeSize = Config.USE_STRING_TEMPLATES ? 8 : ((analyser.getEnd() - analyser.getBegin()) * 2 + 2);
++ final int codeSize = Config.USE_STRING_TEMPLATES ? 8 : ((analyser.getEnd() - analyser.getBegin()) * 2 + 2);
+ code = new int[codeSize];
+ codeLength = 0;
+ }
+@@ -71,7 +70,7 @@
+ }
+
+ @Override
+- protected void compileAltNode(ConsAltNode node) {
++ protected void compileAltNode(final ConsAltNode node) {
+ ConsAltNode aln = node;
+ int len = 0;
+
+@@ -82,7 +81,7 @@
+ }
+ } while ((aln = aln.cdr) != null);
+
+- int pos = codeLength + len; /* goal position */
++ final int pos = codeLength + len; /* goal position */
+
+ aln = node;
+ do {
+@@ -98,15 +97,15 @@
+ } while ((aln = aln.cdr) != null);
+ }
+
+- private boolean isNeedStrLenOpExact(int op) {
++ private static boolean isNeedStrLenOpExact(final int op) {
+ return op == OPCode.EXACTN || op == OPCode.EXACTN_IC;
+ }
+
+- private boolean opTemplated(int op) {
++ private static boolean opTemplated(final int op) {
+ return isNeedStrLenOpExact(op);
+ }
+
+- private int selectStrOpcode(int strLength, boolean ignoreCase) {
++ private static int selectStrOpcode(final int strLength, final boolean ignoreCase) {
+ int op;
+
+ if (ignoreCase) {
+@@ -127,8 +126,8 @@
+ return op;
+ }
+
+- private void compileTreeEmptyCheck(Node node, int emptyInfo) {
+- int savedNumNullCheck = regex.numNullCheck;
++ private void compileTreeEmptyCheck(final Node node, final int emptyInfo) {
++ final int savedNumNullCheck = regex.numNullCheck;
+
+ if (emptyInfo != 0) {
+ addOpcode(OPCode.NULL_CHECK_START);
+@@ -139,7 +138,7 @@
+ compileTree(node);
+
+ if (emptyInfo != 0) {
+- switch(emptyInfo) {
++ switch (emptyInfo) {
+ case TargetInfo.IS_EMPTY:
+ addOpcode(OPCode.NULL_CHECK_END);
+ break;
+@@ -149,29 +148,33 @@
+ case TargetInfo.IS_EMPTY_REC:
+ addOpcode(OPCode.NULL_CHECK_END_MEMST_PUSH);
+ break;
++ default:
++ break;
+ } // switch
+
+ addMemNum(savedNumNullCheck); /* NULL CHECK ID */
+ }
+ }
+
+- private int addCompileStringlength(char[] chars, int p, int strLength, boolean ignoreCase) {
+- int op = selectStrOpcode(strLength, ignoreCase);
++ private static int addCompileStringlength(final char[] chars, final int p, final int strLength, final boolean ignoreCase) {
++ final int op = selectStrOpcode(strLength, ignoreCase);
+ int len = OPSize.OPCODE;
+
+ if (Config.USE_STRING_TEMPLATES && opTemplated(op)) {
+ // string length, template index, template string pointer
+ len += OPSize.LENGTH + OPSize.INDEX + OPSize.INDEX;
+ } else {
+- if (isNeedStrLenOpExact(op)) len += OPSize.LENGTH;
++ if (isNeedStrLenOpExact(op)) {
++ len += OPSize.LENGTH;
++ }
+ len += strLength;
+ }
+ return len;
+ }
+
+ @Override
+- protected final void addCompileString(char[] chars, int p, int strLength, boolean ignoreCase) {
+- int op = selectStrOpcode(strLength, ignoreCase);
++ protected final void addCompileString(final char[] chars, final int p, final int strLength, final boolean ignoreCase) {
++ final int op = selectStrOpcode(strLength, ignoreCase);
+ addOpcode(op);
+
+ if (isNeedStrLenOpExact(op)) {
+@@ -187,15 +190,17 @@
+ }
+ }
+
+- private int compileLengthStringNode(Node node) {
+- StringNode sn = (StringNode)node;
+- if (sn.length() <= 0) return 0;
+- boolean ambig = sn.isAmbig();
++ private static int compileLengthStringNode(final Node node) {
++ final StringNode sn = (StringNode)node;
++ if (sn.length() <= 0) {
++ return 0;
++ }
++ final boolean ambig = sn.isAmbig();
+
+ int p, prev;
+ p = prev = sn.p;
+- int end = sn.end;
+- char[] chars = sn.chars;
++ final int end = sn.end;
++ final char[] chars = sn.chars;
+ p++;
+
+ int slen = 1;
+@@ -205,23 +210,27 @@
+ slen++;
+ p++;
+ }
+- int r = addCompileStringlength(chars, prev, slen, ambig);
++ final int r = addCompileStringlength(chars, prev, slen, ambig);
+ rlen += r;
+ return rlen;
+ }
+
+- private int compileLengthStringRawNode(StringNode sn) {
+- if (sn.length() <= 0) return 0;
++ private static int compileLengthStringRawNode(final StringNode sn) {
++ if (sn.length() <= 0) {
++ return 0;
++ }
+ return addCompileStringlength(sn.chars, sn.p, sn.length(), false);
+ }
+
+- private void addMultiByteCClass(CodeRangeBuffer mbuf) {
++ private void addMultiByteCClass(final CodeRangeBuffer mbuf) {
+ addLength(mbuf.used);
+ addInts(mbuf.p, mbuf.used);
+ }
+
+- private int compileLengthCClassNode(CClassNode cc) {
+- if (cc.isShare()) return OPSize.OPCODE + OPSize.POINTER;
++ private static int compileLengthCClassNode(final CClassNode cc) {
++ if (cc.isShare()) {
++ return OPSize.OPCODE + OPSize.POINTER;
++ }
+
+ int len;
+ if (cc.mbuf == null) {
+@@ -239,7 +248,7 @@
+ }
+
+ @Override
+- protected void compileCClassNode(CClassNode cc) {
++ protected void compileCClassNode(final CClassNode cc) {
+ if (cc.isShare()) { // shared char class
+ addOpcode(OPCode.CCLASS_NODE);
+ addPointer(cc);
+@@ -284,7 +293,7 @@
+ }
+
+ @Override
+- protected void compileBackrefNode(BackRefNode node) {
++ protected void compileBackrefNode(final BackRefNode node) {
+ if (isIgnoreCase(regex.options)) {
+ addOpcode(OPCode.BACKREFN_IC);
+ addMemNum(node.backRef);
+@@ -305,7 +314,7 @@
+ }
+
+ private static final int REPEAT_RANGE_ALLOC = 8;
+- private void entryRepeatRange(int id, int lower, int upper) {
++ private void entryRepeatRange(final int id, final int lower, final int upper) {
+ if (regex.repeatRangeLo == null) {
+ regex.repeatRangeLo = new int[REPEAT_RANGE_ALLOC];
+ regex.repeatRangeHi = new int[REPEAT_RANGE_ALLOC];
+@@ -322,8 +331,8 @@
+ regex.repeatRangeHi[id] = isRepeatInfinite(upper) ? 0x7fffffff : upper;
+ }
+
+- private void compileRangeRepeatNode(QuantifierNode qn, int targetLen, int emptyInfo) {
+- int numRepeat = regex.numRepeat;
++ private void compileRangeRepeatNode(final QuantifierNode qn, final int targetLen, final int emptyInfo) {
++ final int numRepeat = regex.numRepeat;
+ addOpcode(qn.greedy ? OPCode.REPEAT : OPCode.REPEAT_NG);
+ addMemNum(numRepeat); /* OP_REPEAT ID */
+ regex.numRepeat++;
+@@ -345,24 +354,23 @@
+ private static final int QUANTIFIER_EXPAND_LIMIT_SIZE = 50; // was 50
+
+ @SuppressWarnings("unused")
+- private static boolean cknOn(int ckn) {
++ private static boolean cknOn(final int ckn) {
+ return ckn > 0;
+ }
+
+- private int compileNonCECLengthQuantifierNode(QuantifierNode qn) {
+- boolean infinite = isRepeatInfinite(qn.upper);
+- int emptyInfo = qn.targetEmptyInfo;
++ private int compileNonCECLengthQuantifierNode(final QuantifierNode qn) {
++ final boolean infinite = isRepeatInfinite(qn.upper);
++ final int emptyInfo = qn.targetEmptyInfo;
+
+- int tlen = compileLengthTree(qn.target);
++ final int tlen = compileLengthTree(qn.target);
+
+ /* anychar repeat */
+ if (qn.target.getType() == NodeType.CANY) {
+ if (qn.greedy && infinite) {
+ if (qn.nextHeadExact != null) {
+ return OPSize.ANYCHAR_STAR_PEEK_NEXT + tlen * qn.lower;
+- } else {
+- return OPSize.ANYCHAR_STAR + tlen * qn.lower;
+ }
++ return OPSize.ANYCHAR_STAR + tlen * qn.lower;
+ }
+ }
+
+@@ -408,11 +416,11 @@
+ }
+
+ @Override
+- protected void compileNonCECQuantifierNode(QuantifierNode qn) {
+- boolean infinite = isRepeatInfinite(qn.upper);
+- int emptyInfo = qn.targetEmptyInfo;
++ protected void compileNonCECQuantifierNode(final QuantifierNode qn) {
++ final boolean infinite = isRepeatInfinite(qn.upper);
++ final int emptyInfo = qn.targetEmptyInfo;
+
+- int tlen = compileLengthTree(qn.target);
++ final int tlen = compileLengthTree(qn.target);
+
+ if (qn.isAnyCharStar()) {
+ compileTreeNTimes(qn.target, qn.lower);
+@@ -422,17 +430,16 @@
+ } else {
+ addOpcode(OPCode.ANYCHAR_STAR_PEEK_NEXT);
+ }
+- StringNode sn = (StringNode)qn.nextHeadExact;
++ final StringNode sn = (StringNode)qn.nextHeadExact;
+ addChars(sn.chars, sn.p, 1);
+ return;
++ }
++ if (isMultiline(regex.options)) {
++ addOpcode(OPCode.ANYCHAR_ML_STAR);
+ } else {
+- if (isMultiline(regex.options)) {
+- addOpcode(OPCode.ANYCHAR_ML_STAR);
+- } else {
+- addOpcode(OPCode.ANYCHAR_STAR);
+- }
+- return;
++ addOpcode(OPCode.ANYCHAR_STAR);
+ }
++ return;
+ }
+
+ int modTLen;
+@@ -461,13 +468,13 @@
+ if (qn.greedy) {
+ if (qn.headExact != null) {
+ addOpcodeRelAddr(OPCode.PUSH_OR_JUMP_EXACT1, modTLen + OPSize.JUMP);
+- StringNode sn = (StringNode)qn.headExact;
++ final StringNode sn = (StringNode)qn.headExact;
+ addChars(sn.chars, sn.p, 1);
+ compileTreeEmptyCheck(qn.target, emptyInfo);
+ addOpcodeRelAddr(OPCode.JUMP, -(modTLen + OPSize.JUMP + OPSize.PUSH_OR_JUMP_EXACT1));
+ } else if (qn.nextHeadExact != null) {
+ addOpcodeRelAddr(OPCode.PUSH_IF_PEEK_NEXT, modTLen + OPSize.JUMP);
+- StringNode sn = (StringNode)qn.nextHeadExact;
++ final StringNode sn = (StringNode)qn.nextHeadExact;
+ addChars(sn.chars, sn.p, 1);
+ compileTreeEmptyCheck(qn.target, emptyInfo);
+ addOpcodeRelAddr(OPCode.JUMP, -(modTLen + OPSize.JUMP + OPSize.PUSH_IF_PEEK_NEXT));
+@@ -486,7 +493,7 @@
+ compileTree(qn.target);
+ } else if (!infinite && qn.greedy &&
+ (qn.upper == 1 || (tlen + OPSize.PUSH) * qn.upper <= QUANTIFIER_EXPAND_LIMIT_SIZE)) {
+- int n = qn.upper - qn.lower;
++ final int n = qn.upper - qn.lower;
+ compileTreeNTimes(qn.target, qn.lower);
+
+ for (int i=0; i<n; i++) {
+@@ -502,22 +509,21 @@
+ }
+ }
+
+- private int compileLengthOptionNode(EncloseNode node) {
+- int prev = regex.options;
++ private int compileLengthOptionNode(final EncloseNode node) {
++ final int prev = regex.options;
+ regex.options = node.option;
+- int tlen = compileLengthTree(node.target);
++ final int tlen = compileLengthTree(node.target);
+ regex.options = prev;
+
+ if (isDynamic(prev ^ node.option)) {
+ return OPSize.SET_OPTION_PUSH + OPSize.SET_OPTION + OPSize.FAIL + tlen + OPSize.SET_OPTION;
+- } else {
+- return tlen;
+ }
++ return tlen;
+ }
+
+ @Override
+- protected void compileOptionNode(EncloseNode node) {
+- int prev = regex.options;
++ protected void compileOptionNode(final EncloseNode node) {
++ final int prev = regex.options;
+
+ if (isDynamic(prev ^ node.option)) {
+ addOpcodeOption(OPCode.SET_OPTION_PUSH, node.option);
+@@ -534,7 +540,7 @@
+ }
+ }
+
+- private int compileLengthEncloseNode(EncloseNode node) {
++ private int compileLengthEncloseNode(final EncloseNode node) {
+ if (node.isOption()) {
+ return compileLengthOptionNode(node);
+ }
+@@ -559,7 +565,7 @@
+
+ case EncloseType.STOP_BACKTRACK:
+ if (node.isStopBtSimpleRepeat()) {
+- QuantifierNode qn = (QuantifierNode)node.target;
++ final QuantifierNode qn = (QuantifierNode)node.target;
+ tlen = compileLengthTree(qn.target);
+ len = tlen * qn.lower + OPSize.PUSH + tlen + OPSize.POP + OPSize.JUMP;
+ } else {
+@@ -575,7 +581,7 @@
+ }
+
+ @Override
+- protected void compileEncloseNode(EncloseNode node) {
++ protected void compileEncloseNode(final EncloseNode node) {
+ int len;
+ switch (node.type) {
+ case EncloseType.MEMORY:
+@@ -598,7 +604,7 @@
+
+ case EncloseType.STOP_BACKTRACK:
+ if (node.isStopBtSimpleRepeat()) {
+- QuantifierNode qn = (QuantifierNode)node.target;
++ final QuantifierNode qn = (QuantifierNode)node.target;
+
+ compileTreeNTimes(qn.target, qn.lower);
+
+@@ -620,7 +626,7 @@
+ } // switch
+ }
+
+- private int compileLengthAnchorNode(AnchorNode node) {
++ private int compileLengthAnchorNode(final AnchorNode node) {
+ int tlen;
+ if (node.target != null) {
+ tlen = compileLengthTree(node.target);
+@@ -654,7 +660,7 @@
+ }
+
+ @Override
+- protected void compileAnchorNode(AnchorNode node) {
++ protected void compileAnchorNode(final AnchorNode node) {
+ int len;
+ int n;
+
+@@ -675,13 +681,15 @@
+ break;
+
+ case AnchorType.WORD_BEGIN:
+- if (Config.USE_WORD_BEGIN_END)
++ if (Config.USE_WORD_BEGIN_END) {
+ addOpcode(OPCode.WORD_BEGIN);
++ }
+ break;
+
+ case AnchorType.WORD_END:
+- if (Config.USE_WORD_BEGIN_END)
++ if (Config.USE_WORD_BEGIN_END) {
+ addOpcode(OPCode.WORD_END);
++ }
+ break;
+
+ case AnchorType.PREC_READ:
+@@ -701,7 +709,9 @@
+ addOpcode(OPCode.LOOK_BEHIND);
+ if (node.charLength < 0) {
+ n = analyser.getCharLengthTree(node.target);
+- if (analyser.returnCode != 0) newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
++ if (analyser.returnCode != 0) {
++ newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
++ }
+ } else {
+ n = node.charLength;
+ }
+@@ -714,7 +724,9 @@
+ addOpcodeRelAddr(OPCode.PUSH_LOOK_BEHIND_NOT, len + OPSize.FAIL_LOOK_BEHIND_NOT);
+ if (node.charLength < 0) {
+ n = analyser.getCharLengthTree(node.target);
+- if (analyser.returnCode != 0) newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
++ if (analyser.returnCode != 0) {
++ newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
++ }
+ } else {
+ n = node.charLength;
+ }
+@@ -728,7 +740,7 @@
+ } // switch
+ }
+
+- private int compileLengthTree(Node node) {
++ private int compileLengthTree(final Node node) {
+ int len = 0;
+
+ switch (node.getType()) {
+@@ -750,7 +762,7 @@
+ break;
+
+ case NodeType.STR:
+- StringNode sn = (StringNode)node;
++ final StringNode sn = (StringNode)node;
+ if (sn.isRaw()) {
+ len = compileLengthStringRawNode(sn);
+ } else {
+@@ -768,7 +780,7 @@
+ break;
+
+ case NodeType.BREF:
+- BackRefNode br = (BackRefNode)node;
++ final BackRefNode br = (BackRefNode)node;
+
+ len = ((!isIgnoreCase(regex.options) && br.backRef <= 2)
+ ? OPSize.OPCODE : (OPSize.OPCODE + OPSize.MEMNUM));
+@@ -793,35 +805,37 @@
+ return len;
+ }
+
+- private void ensure(int size) {
++ private void ensure(final int size) {
+ if (size >= code.length) {
+ int length = code.length << 1;
+- while (length <= size) length <<= 1;
+- int[]tmp = new int[length];
++ while (length <= size) {
++ length <<= 1;
++ }
++ final int[]tmp = new int[length];
+ System.arraycopy(code, 0, tmp, 0, code.length);
+ code = tmp;
+ }
+ }
+
+- private void addInt(int i) {
++ private void addInt(final int i) {
+ if (codeLength >= code.length) {
+- int[]tmp = new int[code.length << 1];
++ final int[]tmp = new int[code.length << 1];
+ System.arraycopy(code, 0, tmp, 0, code.length);
+ code = tmp;
+ }
+ code[codeLength++] = i;
+ }
+
+- void setInt(int i, int offset) {
++ void setInt(final int i, final int offset) {
+ ensure(offset);
+ regex.code[offset] = i;
+ }
+
+- private void addObject(Object o) {
++ private void addObject(final Object o) {
+ if (regex.operands == null) {
+ regex.operands = new Object[4];
+ } else if (regex.operandLength >= regex.operands.length) {
+- Object[]tmp = new Object[regex.operands.length << 1];
++ final Object[]tmp = new Object[regex.operands.length << 1];
+ System.arraycopy(regex.operands, 0, tmp, 0, regex.operands.length);
+ regex.operands = tmp;
+ }
+@@ -829,20 +843,23 @@
+ regex.operands[regex.operandLength++] = o;
+ }
+
+- private void addChars(char[] chars, int p ,int length) {
++ private void addChars(final char[] chars, final int pp ,final int length) {
+ ensure(codeLength + length);
+- int end = p + length;
++ int p = pp;
++ final int end = p + length;
+
+- while (p < end) code[codeLength++] = chars[p++];
++ while (p < end) {
++ code[codeLength++] = chars[p++];
++ }
+ }
+
+- private void addInts(int[]ints, int length) {
++ private void addInts(final int[]ints, final int length) {
+ ensure(codeLength + length);
+ System.arraycopy(ints, 0, code, codeLength, length);
+ codeLength += length;
+ }
+
+- private void addOpcode(int opcode) {
++ private void addOpcode(final int opcode) {
+ addInt(opcode);
+
+ switch(opcode) {
+@@ -876,54 +893,57 @@
+ case OPCode.CALL:
+ case OPCode.RETURN: // it will appear only with CALL though
+ regex.stackNeeded = true;
++ break;
++ default:
++ break;
+ }
+ }
+
+ @SuppressWarnings("unused")
+- private void addStateCheckNum(int num) {
++ private void addStateCheckNum(final int num) {
+ addInt(num);
+ }
+
+- private void addRelAddr(int addr) {
++ private void addRelAddr(final int addr) {
+ addInt(addr);
+ }
+
+ @SuppressWarnings("unused")
+- private void addAbsAddr(int addr) {
++ private void addAbsAddr(final int addr) {
+ addInt(addr);
+ }
+
+- private void addLength(int length) {
++ private void addLength(final int length) {
+ addInt(length);
+ }
+
+- private void addMemNum(int num) {
++ private void addMemNum(final int num) {
+ addInt(num);
+ }
+
+- private void addPointer(Object o) {
++ private void addPointer(final Object o) {
+ addObject(o);
+ }
+
+- private void addOption(int option) {
++ private void addOption(final int option) {
+ addInt(option);
+ }
+
+- private void addOpcodeRelAddr(int opcode, int addr) {
++ private void addOpcodeRelAddr(final int opcode, final int addr) {
+ addOpcode(opcode);
+ addRelAddr(addr);
+ }
+
+- private void addOpcodeOption(int opcode, int option) {
++ private void addOpcodeOption(final int opcode, final int option) {
+ addOpcode(opcode);
+ addOption(option);
+ }
+
+- private void addTemplate(char[] chars) {
++ private void addTemplate(final char[] chars) {
+ if (templateNum == 0) {
+ templates = new char[2][];
+ } else if (templateNum == templates.length) {
+- char[][] tmp = new char[templateNum * 2][];
++ final char[][] tmp = new char[templateNum * 2][];
+ System.arraycopy(templates, 0, tmp, 0, templateNum);
+ templates = tmp;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitSet.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitSet.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni;
+
++@SuppressWarnings("javadoc")
+ public final class BitSet {
+ static final int BITS_PER_BYTE = 8;
+ public static final int SINGLE_BYTE_SIZE = (1 << BITS_PER_BYTE);
+@@ -31,77 +32,100 @@
+ private static final int BITS_TO_STRING_WRAP = 4;
+ @Override
+ public String toString() {
+- StringBuilder buffer = new StringBuilder();
++ final StringBuilder buffer = new StringBuilder();
+ buffer.append("BitSet");
+ for (int i=0; i<SINGLE_BYTE_SIZE; i++) {
+- if ((i % (SINGLE_BYTE_SIZE / BITS_TO_STRING_WRAP)) == 0) buffer.append("\n ");
++ if ((i % (SINGLE_BYTE_SIZE / BITS_TO_STRING_WRAP)) == 0) {
++ buffer.append("\n ");
++ }
+ buffer.append(at(i) ? "1" : "0");
+ }
+ return buffer.toString();
+ }
+
+- public boolean at(int pos) {
++ public boolean at(final int pos) {
+ return (bits[pos >>> ROOM_SHIFT] & bit(pos)) != 0;
+ }
+
+- public void set(int pos) {
++ public void set(final int pos) {
+ bits[pos >>> ROOM_SHIFT] |= bit(pos);
+ }
+
+- public void clear(int pos) {
++ public void clear(final int pos) {
+ bits[pos >>> ROOM_SHIFT] &= ~bit(pos);
+ }
+
+ public void clear() {
+- for (int i=0; i<BITSET_SIZE; i++) bits[i]=0;
++ for (int i=0; i<BITSET_SIZE; i++) {
++ bits[i]=0;
++ }
+ }
+
+ public boolean isEmpty() {
+ for (int i=0; i<BITSET_SIZE; i++) {
+- if (bits[i] != 0) return false;
++ if (bits[i] != 0) {
++ return false;
++ }
+ }
+ return true;
+ }
+
+- public void setRange(int from, int to) {
+- for (int i=from; i<=to && i < SINGLE_BYTE_SIZE; i++) set(i);
++ public void setRange(final int from, final int to) {
++ for (int i=from; i<=to && i < SINGLE_BYTE_SIZE; i++) {
++ set(i);
++ }
+ }
+
+ public void invert() {
+- for (int i=0; i<BITSET_SIZE; i++) bits[i] = ~bits[i];
++ for (int i=0; i<BITSET_SIZE; i++) {
++ bits[i] = ~bits[i];
++ }
+ }
+
+- public void invertTo(BitSet to) {
+- for (int i=0; i<BITSET_SIZE; i++) to.bits[i] = ~bits[i];
++ public void invertTo(final BitSet to) {
++ for (int i=0; i<BITSET_SIZE; i++) {
++ to.bits[i] = ~bits[i];
++ }
+ }
+
+- public void and(BitSet other) {
+- for (int i=0; i<BITSET_SIZE; i++) bits[i] &= other.bits[i];
++ public void and(final BitSet other) {
++ for (int i=0; i<BITSET_SIZE; i++) {
++ bits[i] &= other.bits[i];
++ }
+ }
+
+- public void or(BitSet other) {
+- for (int i=0; i<BITSET_SIZE; i++) bits[i] |= other.bits[i];
++ public void or(final BitSet other) {
++ for (int i=0; i<BITSET_SIZE; i++) {
++ bits[i] |= other.bits[i];
++ }
+ }
+
+- public void copy(BitSet other) {
+- for (int i=0; i<BITSET_SIZE; i++) bits[i] = other.bits[i];
++ public void copy(final BitSet other) {
++ for (int i=0; i<BITSET_SIZE; i++) {
++ bits[i] = other.bits[i];
++ }
+ }
+
+ public int numOn() {
+ int num = 0;
+ for (int i=0; i<SINGLE_BYTE_SIZE; i++) {
+- if (at(i)) num++;
++ if (at(i)) {
++ num++;
++ }
+ }
+ return num;
+ }
+
+- static int bit(int pos){
++ static int bit(final int pos){
+ return 1 << (pos % SINGLE_BYTE_SIZE);
+ }
+
+- private static int log2(int n){
++ private static int log2(final int np) {
+ int log = 0;
+- while ((n >>>= 1) != 0) log++;
++ int n = np;
++ while ((n >>>= 1) != 0) {
++ log++;
++ }
+ return log;
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitStatus.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitStatus.java Wed Feb 04 12:14:47 2015 -0800
+@@ -30,11 +30,12 @@
+ return -1;
+ }
+
+- public static boolean bsAt(int stats, int n) {
++ public static boolean bsAt(final int stats, final int n) {
+ return (n < BIT_STATUS_BITS_NUM ? stats & (1 << n) : (stats & 1)) != 0;
+ }
+
+- public static int bsOnAt(int stats, int n) {
++ public static int bsOnAt(final int statsp, final int n) {
++ int stats = statsp;
+ if (n < BIT_STATUS_BITS_NUM) {
+ stats |= (1 << n);
+ } else {
+@@ -43,12 +44,7 @@
+ return stats;
+ }
+
+- public static int bsOnOff(int v, int f, boolean negative) {
+- if (negative) {
+- v &= ~f;
+- } else {
+- v |= f;
+- }
+- return v;
++ public static int bsOnOff(final int v, final int f, final boolean negative) {
++ return negative ? (v & ~f) : (v | f);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java Wed Feb 04 12:14:47 2015 -0800
+@@ -20,17 +20,15 @@
+ package jdk.nashorn.internal.runtime.regexp.joni;
+
+ import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
++import static jdk.nashorn.internal.runtime.regexp.joni.EncodingHelper.isNewLine;
+ import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindCondition;
+ import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindLongest;
+ import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindNotEmpty;
+ import static jdk.nashorn.internal.runtime.regexp.joni.Option.isNotBol;
+ import static jdk.nashorn.internal.runtime.regexp.joni.Option.isNotEol;
+ import static jdk.nashorn.internal.runtime.regexp.joni.Option.isPosixRegion;
+-import static jdk.nashorn.internal.runtime.regexp.joni.EncodingHelper.isNewLine;
+-
+ import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
+ import jdk.nashorn.internal.runtime.regexp.joni.constants.OPCode;
+-import jdk.nashorn.internal.runtime.regexp.joni.constants.OPSize;
+ import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
+ import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+ import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
+@@ -47,19 +45,19 @@
+ private final int[] code; // byte code
+ private int ip; // instruction pointer
+
+- ByteCodeMachine(Regex regex, char[] chars, int p, int end) {
++ ByteCodeMachine(final Regex regex, final char[] chars, final int p, final int end) {
+ super(regex, chars, p, end);
+ this.code = regex.code;
+ }
+
+- private boolean stringCmpIC(int caseFlodFlag, int s1, IntHolder ps2, int mbLen, int textEnd) {
+-
++ private boolean stringCmpIC(final int caseFlodFlag, final int s1p, final IntHolder ps2, final int mbLen, final int textEnd) {
++ int s1 = s1p;
+ int s2 = ps2.value;
+- int end1 = s1 + mbLen;
++ final int end1 = s1 + mbLen;
+
+ while (s1 < end1) {
+- char c1 = EncodingHelper.toLowerCase(chars[s1++]);
+- char c2 = EncodingHelper.toLowerCase(chars[s2++]);
++ final char c1 = EncodingHelper.toLowerCase(chars[s1++]);
++ final char c2 = EncodingHelper.toLowerCase(chars[s2++]);
+
+ if (c1 != c2) {
+ return false;
+@@ -83,41 +81,51 @@
+ Config.log.printf("%4d", (s - str)).print("> \"");
+ int q, i;
+ for (i=0, q=s; i<7 && q<end && s>=0; i++) {
+- if (q < end) Config.log.print(new String(new char[]{chars[q++]}));
++ if (q < end) {
++ Config.log.print(new String(new char[]{chars[q++]}));
++ }
+ }
+- String str = q < end ? "...\"" : "\"";
+- q += str.length();
+- Config.log.print(str);
+- for (i=0; i<20-(q-s);i++) Config.log.print(" ");
+- StringBuilder sb = new StringBuilder();
++ final String string = q < end ? "...\"" : "\"";
++ q += string.length();
++ Config.log.print(string);
++ for (i=0; i<20-(q-s);i++) {
++ Config.log.print(" ");
++ }
++ final StringBuilder sb = new StringBuilder();
+ new ByteCodePrinter(regex).compiledByteCodeToString(sb, ip);
+ Config.log.println(sb.toString());
+ }
+ }
+
+ @Override
+- protected final int matchAt(int range, int sstart, int sprev) {
+- this.range = range;
+- this.sstart = sstart;
+- this.sprev = sprev;
++ protected final int matchAt(final int r, final int ss, final int sp) {
++ this.range = r;
++ this.sstart = ss;
++ this.sprev = sp;
+
+ stk = 0;
+ ip = 0;
+
+- if (Config.DEBUG_MATCH) debugMatchBegin();
++ if (Config.DEBUG_MATCH) {
++ debugMatchBegin();
++ }
+
+ init();
+
+ bestLen = -1;
+- s = sstart;
++ s = ss;
+
+- final int[]code = this.code;
++ final int[] c = this.code;
+ while (true) {
+- if (Config.DEBUG_MATCH) debugMatchLoop();
++ if (Config.DEBUG_MATCH) {
++ debugMatchLoop();
++ }
+
+ sbegin = s;
+- switch (code[ip++]) {
+- case OPCode.END: if (opEnd()) return finish(); break;
++ switch (c[ip++]) {
++ case OPCode.END: if (opEnd()) {
++ return finish();
++ } break;
+ case OPCode.EXACT1: opExact1(); break;
+ case OPCode.EXACT2: opExact2(); continue;
+ case OPCode.EXACT3: opExact3(); continue;
+@@ -215,7 +223,7 @@
+ }
+
+ private boolean opEnd() {
+- int n = s - sstart;
++ final int n = s - sstart;
+
+ if (n > bestLen) {
+ if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) {
+@@ -259,7 +267,7 @@
+ msaEnd = s - str;
+ }
+ } else {
+- Region region = msaRegion;
++ final Region region = msaRegion;
+ if (Config.USE_POSIX_API_REGION_OPTION) {
+ if (!isPosixRegion(regex.options)) {
+ if (region != null) {
+@@ -355,13 +363,17 @@
+ if (s + tlen > range) {opFail(); return;}
+
+ if (Config.USE_STRING_TEMPLATES) {
+- char[] bs = regex.templates[code[ip++]];
++ final char[] bs = regex.templates[code[ip++]];
+ int ps = code[ip++];
+
+- while (tlen-- > 0) if (bs[ps++] != chars[s++]) {opFail(); return;}
++ while (tlen-- > 0) {
++ if (bs[ps++] != chars[s++]) {opFail(); return;}
++ }
+
+ } else {
+- while (tlen-- > 0) if (code[ip++] != chars[s++]) {opFail(); return;}
++ while (tlen-- > 0) {
++ if (code[ip++] != chars[s++]) {opFail(); return;}
++ }
+ }
+ sprev = s - 1;
+ }
+@@ -377,19 +389,23 @@
+ if (s + tlen > range) {opFail(); return;}
+
+ if (Config.USE_STRING_TEMPLATES) {
+- char[] bs = regex.templates[code[ip++]];
++ final char[] bs = regex.templates[code[ip++]];
+ int ps = code[ip++];
+
+- while (tlen-- > 0) if (bs[ps++] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;}
++ while (tlen-- > 0) {
++ if (bs[ps++] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;}
++ }
+ } else {
+
+- while (tlen-- > 0) if (code[ip++] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;}
++ while (tlen-- > 0) {
++ if (code[ip++] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;}
++ }
+ }
+ sprev = s - 1;
+ }
+
+ private boolean isInBitSet() {
+- int c = chars[s];
++ final int c = chars[s];
+ return (c <= 0xff && (code[ip + (c >>> BitSet.ROOM_SHIFT)] & (1 << c)) != 0);
+ }
+
+@@ -401,12 +417,16 @@
+ }
+
+ private boolean isInClassMB() {
+- int tlen = code[ip++];
+- if (s >= range) return false;
+- int ss = s;
++ final int tlen = code[ip++];
++ if (s >= range) {
++ return false;
++ }
++ final int ss = s;
+ s++;
+- int c = chars[ss];
+- if (!EncodingHelper.isInCodeRange(code, ip, c)) return false;
++ final int c = chars[ss];
++ if (!EncodingHelper.isInCodeRange(code, ip, c)) {
++ return false;
++ }
+ ip += tlen;
+ return true;
+ }
+@@ -426,7 +446,7 @@
+ } else {
+ if (!isInBitSet()) {opFail(); return;}
+ ip += BitSet.BITSET_SIZE;
+- int tlen = code[ip++]; // by code range length
++ final int tlen = code[ip++]; // by code range length
+ ip += tlen;
+ s++;
+ }
+@@ -441,20 +461,24 @@
+ }
+
+ private boolean isNotInClassMB() {
+- int tlen = code[ip++];
++ final int tlen = code[ip++];
+
+ if (!(s + 1 <= range)) {
+- if (s >= range) return false;
++ if (s >= range) {
++ return false;
++ }
+ s = end;
+ ip += tlen;
+ return true;
+ }
+
+- int ss = s;
++ final int ss = s;
+ s++;
+- int c = chars[ss];
++ final int c = chars[ss];
+
+- if (EncodingHelper.isInCodeRange(code, ip, c)) return false;
++ if (EncodingHelper.isInCodeRange(code, ip, c)) {
++ return false;
++ }
+ ip += tlen;
+ return true;
+ }
+@@ -463,7 +487,7 @@
+ if (s >= range) {opFail(); return;}
+ if (chars[s] <= 0xff) {
+ s++;
+- int tlen = code[ip++];
++ final int tlen = code[ip++];
+ ip += tlen;
+ sprev = sbegin; // break;
+ return;
+@@ -480,7 +504,7 @@
+ } else {
+ if (isInBitSet()) {opFail(); return;}
+ ip += BitSet.BITSET_SIZE;
+- int tlen = code[ip++];
++ final int tlen = code[ip++];
+ ip += tlen;
+ s++;
+ }
+@@ -489,10 +513,10 @@
+
+ private void opCClassNode() {
+ if (s >= range) {opFail(); return;}
+- CClassNode cc = (CClassNode)regex.operands[code[ip++]];
+- int ss = s;
++ final CClassNode cc = (CClassNode)regex.operands[code[ip++]];
++ final int ss = s;
+ s++;
+- int c = chars[ss];
++ final int c = chars[ss];
+ if (!cc.isCodeInCCLength(c)) {opFail(); return;}
+ sprev = sbegin; // break;
+ }
+@@ -511,10 +535,10 @@
+ }
+
+ private void opAnyCharStar() {
+- final char[] chars = this.chars;
++ final char[] ch = this.chars;
+ while (s < range) {
+ pushAlt(ip, s, sprev);
+- if (isNewLine(chars, s, end)) {opFail(); return;}
++ if (isNewLine(ch, s, end)) {opFail(); return;}
+ sprev = s;
+ s++;
+ }
+@@ -532,11 +556,13 @@
+
+ private void opAnyCharStarPeekNext() {
+ final char c = (char)code[ip];
+- final char[] chars = this.chars;
++ final char[] ch = this.chars;
+
+ while (s < range) {
+- char b = chars[s];
+- if (c == b) pushAlt(ip + 1, s, sprev);
++ final char b = ch[s];
++ if (c == b) {
++ pushAlt(ip + 1, s, sprev);
++ }
+ if (isNewLine(b)) {opFail(); return;}
+ sprev = s;
+ s++;
+@@ -547,10 +573,12 @@
+
+ private void opAnyCharMLStarPeekNext() {
+ final char c = (char)code[ip];
+- final char[] chars = this.chars;
++ final char[] ch = this.chars;
+
+ while (s < range) {
+- if (c == chars[s]) pushAlt(ip + 1, s, sprev);
++ if (c == ch[s]) {
++ pushAlt(ip + 1, s, sprev);
++ }
+ sprev = s;
+ s++;
+ }
+@@ -592,29 +620,39 @@
+
+ private void opWordBegin() {
+ if (s < range && EncodingHelper.isWord(chars[s])) {
+- if (s == str || !EncodingHelper.isWord(chars[sprev])) return;
++ if (s == str || !EncodingHelper.isWord(chars[sprev])) {
++ return;
++ }
+ }
+ opFail();
+ }
+
+ private void opWordEnd() {
+ if (s != str && EncodingHelper.isWord(chars[sprev])) {
+- if (s == end || !EncodingHelper.isWord(chars[s])) return;
++ if (s == end || !EncodingHelper.isWord(chars[s])) {
++ return;
++ }
+ }
+ opFail();
+ }
+
+ private void opBeginBuf() {
+- if (s != str) opFail();
++ if (s != str) {
++ opFail();
++ }
+ }
+
+ private void opEndBuf() {
+- if (s != end) opFail();
++ if (s != end) {
++ opFail();
++ }
+ }
+
+ private void opBeginLine() {
+ if (s == str) {
+- if (isNotBol(msaOptions)) opFail();
++ if (isNotBol(msaOptions)) {
++ opFail();
++ }
+ return;
+ } else if (isNewLine(chars, sprev, end) && s != end) {
+ return;
+@@ -626,13 +664,16 @@
+ if (s == end) {
+ if (Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
+ if (str == end || !isNewLine(chars, sprev, end)) {
+- if (isNotEol(msaOptions)) opFail();
++ if (isNotEol(msaOptions)) {
++ opFail();
++ }
+ }
+ return;
+- } else {
+- if (isNotEol(msaOptions)) opFail();
+- return;
+ }
++ if (isNotEol(msaOptions)) {
++ opFail();
++ }
++ return;
+ } else if (isNewLine(chars, s, end)) {
+ return;
+ }
+@@ -643,13 +684,16 @@
+ if (s == end) {
+ if (Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
+ if (str == end || !isNewLine(chars, sprev, end)) {
+- if (isNotEol(msaOptions)) opFail();
++ if (isNotEol(msaOptions)) {
++ opFail();
++ }
+ }
+ return;
+- } else {
+- if (isNotEol(msaOptions)) opFail();
+- return;
+ }
++ if (isNotEol(msaOptions)) {
++ opFail();
++ }
++ return;
+ } else if (isNewLine(chars, s, end) && s + 1 == end) {
+ return;
+ }
+@@ -657,40 +701,42 @@
+ }
+
+ private void opBeginPosition() {
+- if (s != msaStart) opFail();
++ if (s != msaStart) {
++ opFail();
++ }
+ }
+
+ private void opMemoryStartPush() {
+- int mem = code[ip++];
++ final int mem = code[ip++];
+ pushMemStart(mem, s);
+ }
+
+ private void opMemoryStart() {
+- int mem = code[ip++];
++ final int mem = code[ip++];
+ repeatStk[memStartStk + mem] = s;
+ }
+
+ private void opMemoryEndPush() {
+- int mem = code[ip++];
++ final int mem = code[ip++];
+ pushMemEnd(mem, s);
+ }
+
+ private void opMemoryEnd() {
+- int mem = code[ip++];
++ final int mem = code[ip++];
+ repeatStk[memEndStk + mem] = s;
+ }
+
+ private void opMemoryEndPushRec() {
+- int mem = code[ip++];
+- int stkp = getMemStart(mem); /* should be before push mem-end. */
++ final int mem = code[ip++];
++ final int stkp = getMemStart(mem); /* should be before push mem-end. */
+ pushMemEnd(mem, s);
+ repeatStk[memStartStk + mem] = stkp;
+ }
+
+ private void opMemoryEndRec() {
+- int mem = code[ip++];
++ final int mem = code[ip++];
+ repeatStk[memEndStk + mem] = s;
+- int stkp = getMemStart(mem);
++ final int stkp = getMemStart(mem);
+
+ if (BitStatus.bsAt(regex.btMemStart, mem)) {
+ repeatStk[memStartStk + mem] = stkp;
+@@ -701,36 +747,40 @@
+ pushMemEndMark(mem);
+ }
+
+- private boolean backrefInvalid(int mem) {
++ private boolean backrefInvalid(final int mem) {
+ return repeatStk[memEndStk + mem] == INVALID_INDEX || repeatStk[memStartStk + mem] == INVALID_INDEX;
+ }
+
+- private int backrefStart(int mem) {
++ private int backrefStart(final int mem) {
+ return bsAt(regex.btMemStart, mem) ? stack[repeatStk[memStartStk + mem]].getMemPStr() : repeatStk[memStartStk + mem];
+ }
+
+- private int backrefEnd(int mem) {
++ private int backrefEnd(final int mem) {
+ return bsAt(regex.btMemEnd, mem) ? stack[repeatStk[memEndStk + mem]].getMemPStr() : repeatStk[memEndStk + mem];
+ }
+
+- private void backref(int mem) {
++ private void backref(final int mem) {
+ /* if you want to remove following line,
+ you should check in parse and compile time. (numMem) */
+ if (mem > regex.numMem || backrefInvalid(mem)) {opFail(); return;}
+
+ int pstart = backrefStart(mem);
+- int pend = backrefEnd(mem);
++ final int pend = backrefEnd(mem);
+
+ int n = pend - pstart;
+ if (s + n > range) {opFail(); return;}
+ sprev = s;
+
+ // STRING_CMP
+- while(n-- > 0) if (chars[pstart++] != chars[s++]) {opFail(); return;}
++ while(n-- > 0) {
++ if (chars[pstart++] != chars[s++]) {opFail(); return;}
++ }
+
+ // beyond string check
+ if (sprev < range) {
+- while (sprev + 1 < s) sprev++;
++ while (sprev + 1 < s) {
++ sprev++;
++ }
+ }
+ }
+
+@@ -747,15 +797,15 @@
+ }
+
+ private void opBackRefNIC() {
+- int mem = code[ip++];
++ final int mem = code[ip++];
+ /* if you want to remove following line,
+ you should check in parse and compile time. (numMem) */
+ if (mem > regex.numMem || backrefInvalid(mem)) {opFail(); return;}
+
+- int pstart = backrefStart(mem);
+- int pend = backrefEnd(mem);
++ final int pstart = backrefStart(mem);
++ final int pend = backrefEnd(mem);
+
+- int n = pend - pstart;
++ final int n = pend - pstart;
+ if (s + n > range) {opFail(); return;}
+ sprev = s;
+
+@@ -764,19 +814,23 @@
+ s = value;
+
+ // if (sprev < chars.length)
+- while (sprev + 1 < s) sprev++;
++ while (sprev + 1 < s) {
++ sprev++;
++ }
+ }
+
+ private void opBackRefMulti() {
+- int tlen = code[ip++];
++ final int tlen = code[ip++];
+
+ int i;
+ loop:for (i=0; i<tlen; i++) {
+- int mem = code[ip++];
+- if (backrefInvalid(mem)) continue;
++ final int mem = code[ip++];
++ if (backrefInvalid(mem)) {
++ continue;
++ }
+
+ int pstart = backrefStart(mem);
+- int pend = backrefEnd(mem);
++ final int pend = backrefEnd(mem);
+
+ int n = pend - pstart;
+ if (s + n > range) {opFail(); return;}
+@@ -785,14 +839,18 @@
+ int swork = s;
+
+ while (n-- > 0) {
+- if (chars[pstart++] != chars[swork++]) continue loop;
++ if (chars[pstart++] != chars[swork++]) {
++ continue loop;
++ }
+ }
+
+ s = swork;
+
+ // beyond string check
+ if (sprev < range) {
+- while (sprev + 1 < s) sprev++;
++ while (sprev + 1 < s) {
++ sprev++;
++ }
+ }
+
+ ip += tlen - i - 1; // * SIZE_MEMNUM (1)
+@@ -802,27 +860,34 @@
+ }
+
+ private void opBackRefMultiIC() {
+- int tlen = code[ip++];
++ final int tlen = code[ip++];
+
+ int i;
+ loop:for (i=0; i<tlen; i++) {
+- int mem = code[ip++];
+- if (backrefInvalid(mem)) continue;
++ final int mem = code[ip++];
++ if (backrefInvalid(mem)) {
++ continue;
++ }
+
+- int pstart = backrefStart(mem);
+- int pend = backrefEnd(mem);
++ final int pstart = backrefStart(mem);
++ final int pend = backrefEnd(mem);
+
+- int n = pend - pstart;
++ final int n = pend - pstart;
+ if (s + n > range) {opFail(); return;}
+
+ sprev = s;
+
+ value = s;
+- if (!stringCmpIC(regex.caseFoldFlag, pstart, this, n, end)) continue loop; // STRING_CMP_VALUE_IC
++ if (!stringCmpIC(regex.caseFoldFlag, pstart, this, n, end))
++ {
++ continue loop; // STRING_CMP_VALUE_IC
++ }
+ s = value;
+
+ // if (sprev < chars.length)
+- while (sprev + 1 < s) sprev++;
++ while (sprev + 1 < s) {
++ sprev++;
++ }
+
+ ip += tlen - i - 1; // * SIZE_MEMNUM (1)
+ break; /* success */
+@@ -830,23 +895,25 @@
+ if (i == tlen) {opFail(); return;}
+ }
+
+- private boolean memIsInMemp(int mem, int num, int memp) {
+- for (int i=0; i<num; i++) {
+- int m = code[memp++];
+- if (mem == m) return true;
++ private boolean memIsInMemp(final int mem, final int num, final int mempp) {
++ for (int i=0, memp = mempp; i<num; i++) {
++ final int m = code[memp++];
++ if (mem == m) {
++ return true;
++ }
+ }
+ return false;
+ }
+
+ // USE_BACKREF_AT_LEVEL // (s) and (end) implicit
+- private boolean backrefMatchAtNestedLevel(boolean ignoreCase, int caseFoldFlag,
+- int nest, int memNum, int memp) {
++ private boolean backrefMatchAtNestedLevel(final boolean ignoreCase, final int caseFoldFlag,
++ final int nest, final int memNum, final int memp) {
+ int pend = -1;
+ int level = 0;
+ int k = stk - 1;
+
+ while (k >= 0) {
+- StackEntry e = stack[k];
++ final StackEntry e = stack[k];
+
+ if (e.type == CALL_FRAME) {
+ level--;
+@@ -855,9 +922,11 @@
+ } else if (level == nest) {
+ if (e.type == MEM_START) {
+ if (memIsInMemp(e.getMemNum(), memNum, memp)) {
+- int pstart = e.getMemPStr();
++ final int pstart = e.getMemPStr();
+ if (pend != -1) {
+- if (pend - pstart > end - s) return false; /* or goto next_mem; */
++ if (pend - pstart > end - s) {
++ return false; /* or goto next_mem; */
++ }
+ int p = pstart;
+
+ value = s;
+@@ -867,7 +936,9 @@
+ }
+ } else {
+ while (p < pend) {
+- if (chars[p++] != chars[value++]) return false; /* or goto next_mem; */
++ if (chars[p++] != chars[value++]) {
++ return false; /* or goto next_mem; */
++ }
+ }
+ }
+ s = value;
+@@ -887,32 +958,23 @@
+ }
+
+ private void opBackRefAtLevel() {
+- int ic = code[ip++];
+- int level = code[ip++];
+- int tlen = code[ip++];
++ final int ic = code[ip++];
++ final int level = code[ip++];
++ final int tlen = code[ip++];
+
+ sprev = s;
+ if (backrefMatchAtNestedLevel(ic != 0, regex.caseFoldFlag, level, tlen, ip)) { // (s) and (end) implicit
+- while (sprev + 1 < s) sprev++;
++ while (sprev + 1 < s) {
++ sprev++;
++ }
+ ip += tlen; // * SIZE_MEMNUM
+ } else {
+ {opFail(); return;}
+ }
+ }
+
+- /* no need: IS_DYNAMIC_OPTION() == 0 */
+- private void opSetOptionPush() {
+- // option = code[ip++]; // final for now
+- pushAlt(ip, s, sprev);
+- ip += OPSize.SET_OPTION + OPSize.FAIL;
+- }
+-
+- private void opSetOption() {
+- // option = code[ip++]; // final for now
+- }
+-
+ private void opNullCheckStart() {
+- int mem = code[ip++];
++ final int mem = code[ip++];
+ pushNullCheckStart(mem, s);
+ }
+
+@@ -936,8 +998,8 @@
+ }
+
+ private void opNullCheckEnd() {
+- int mem = code[ip++];
+- int isNull = nullCheck(mem, s); /* mem: null check id */
++ final int mem = code[ip++];
++ final int isNull = nullCheck(mem, s); /* mem: null check id */
+
+ if (isNull != 0) {
+ if (Config.DEBUG_MATCH) {
+@@ -950,8 +1012,8 @@
+
+ // USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK
+ private void opNullCheckEndMemST() {
+- int mem = code[ip++]; /* mem: null check id */
+- int isNull = nullCheckMemSt(mem, s);
++ final int mem = code[ip++]; /* mem: null check id */
++ final int isNull = nullCheckMemSt(mem, s);
+
+ if (isNull != 0) {
+ if (Config.DEBUG_MATCH) {
+@@ -965,7 +1027,7 @@
+
+ // USE_SUBEXP_CALL
+ private void opNullCheckEndMemSTPush() {
+- int mem = code[ip++]; /* mem: null check id */
++ final int mem = code[ip++]; /* mem: null check id */
+
+ int isNull;
+ if (Config.USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT) {
+@@ -991,7 +1053,7 @@
+ }
+
+ private void opPush() {
+- int addr = code[ip++];
++ final int addr = code[ip++];
+ pushAlt(ip + addr, s, sprev);
+ }
+
+@@ -1000,7 +1062,7 @@
+ }
+
+ private void opPushOrJumpExact1() {
+- int addr = code[ip++];
++ final int addr = code[ip++];
+ // beyond string check
+ if (s < range && code[ip] == chars[s]) {
+ ip++;
+@@ -1011,7 +1073,7 @@
+ }
+
+ private void opPushIfPeekNext() {
+- int addr = code[ip++];
++ final int addr = code[ip++];
+ // beyond string check
+ if (s < range && code[ip] == chars[s]) {
+ ip++;
+@@ -1022,8 +1084,8 @@
+ }
+
+ private void opRepeat() {
+- int mem = code[ip++]; /* mem: OP_REPEAT ID */
+- int addr= code[ip++];
++ final int mem = code[ip++]; /* mem: OP_REPEAT ID */
++ final int addr= code[ip++];
+
+ // ensure1();
+ repeatStk[mem] = stk;
+@@ -1035,8 +1097,8 @@
+ }
+
+ private void opRepeatNG() {
+- int mem = code[ip++]; /* mem: OP_REPEAT ID */
+- int addr= code[ip++];
++ final int mem = code[ip++]; /* mem: OP_REPEAT ID */
++ final int addr= code[ip++];
+
+ // ensure1();
+ repeatStk[mem] = stk;
+@@ -1048,8 +1110,8 @@
+ }
+ }
+
+- private void repeatInc(int mem, int si) {
+- StackEntry e = stack[si];
++ private void repeatInc(final int mem, final int si) {
++ final StackEntry e = stack[si];
+
+ e.increaseRepeatCount();
+
+@@ -1065,25 +1127,25 @@
+ }
+
+ private void opRepeatInc() {
+- int mem = code[ip++]; /* mem: OP_REPEAT ID */
+- int si = repeatStk[mem];
++ final int mem = code[ip++]; /* mem: OP_REPEAT ID */
++ final int si = repeatStk[mem];
+ repeatInc(mem, si);
+ }
+
+ private void opRepeatIncSG() {
+- int mem = code[ip++]; /* mem: OP_REPEAT ID */
+- int si = getRepeat(mem);
++ final int mem = code[ip++]; /* mem: OP_REPEAT ID */
++ final int si = getRepeat(mem);
+ repeatInc(mem, si);
+ }
+
+- private void repeatIncNG(int mem, int si) {
+- StackEntry e = stack[si];
++ private void repeatIncNG(final int mem, final int si) {
++ final StackEntry e = stack[si];
+
+ e.increaseRepeatCount();
+
+ if (e.getRepeatCount() < regex.repeatRangeHi[mem]) {
+ if (e.getRepeatCount() >= regex.repeatRangeLo[mem]) {
+- int pcode = e.getRepeatPCode();
++ final int pcode = e.getRepeatPCode();
+ pushRepeatInc(si);
+ pushAlt(pcode, s, sprev);
+ } else {
+@@ -1096,14 +1158,14 @@
+ }
+
+ private void opRepeatIncNG() {
+- int mem = code[ip++];
+- int si = repeatStk[mem];
++ final int mem = code[ip++];
++ final int si = repeatStk[mem];
+ repeatIncNG(mem, si);
+ }
+
+ private void opRepeatIncNGSG() {
+- int mem = code[ip++];
+- int si = getRepeat(mem);
++ final int mem = code[ip++];
++ final int si = getRepeat(mem);
+ repeatIncNG(mem, si);
+ }
+
+@@ -1112,13 +1174,13 @@
+ }
+
+ private void opPopPos() {
+- StackEntry e = stack[posEnd()];
++ final StackEntry e = stack[posEnd()];
+ s = e.getStatePStr();
+ sprev= e.getStatePStrPrev();
+ }
+
+ private void opPushPosNot() {
+- int addr = code[ip++];
++ final int addr = code[ip++];
+ pushPosNot(ip + addr, s, sprev);
+ }
+
+@@ -1136,23 +1198,16 @@
+ }
+
+ private void opLookBehind() {
+- int tlen = code[ip++];
++ final int tlen = code[ip++];
+ s = EncodingHelper.stepBack(str, s, tlen);
+ if (s == -1) {opFail(); return;}
+ sprev = EncodingHelper.prevCharHead(str, s);
+ }
+
+- private void opLookBehindSb() {
+- int tlen = code[ip++];
+- s -= tlen;
+- if (s < str) {opFail(); return;}
+- sprev = s == str ? -1 : s - 1;
+- }
+-
+ private void opPushLookBehindNot() {
+- int addr = code[ip++];
+- int tlen = code[ip++];
+- int q = EncodingHelper.stepBack(str, s, tlen);
++ final int addr = code[ip++];
++ final int tlen = code[ip++];
++ final int q = EncodingHelper.stepBack(str, s, tlen);
+ if (q == -1) {
+ /* too short case -> success. ex. /(?<!XXX)a/.match("a")
+ If you want to change to fail, replace following line. */
+@@ -1177,7 +1232,7 @@
+ }
+
+
+- StackEntry e = pop();
++ final StackEntry e = pop();
+ ip = e.getStatePCode();
+ s = e.getStatePStr();
+ sprev = e.getStatePStrPrev();
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodePrinter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodePrinter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -214,7 +214,7 @@
+ Arguments.OPTION, /*OP_SET_OPTION*/
+ };
+
+- public ByteCodePrinter(Regex regex) {
++ public ByteCodePrinter(final Regex regex) {
+ code = regex.code;
+ codeLength = regex.codeLength;
+ operands = regex.operands;
+@@ -226,33 +226,35 @@
+ return compiledByteCodeListToString();
+ }
+
+- private void pString(StringBuilder sb, int len, int s) {
++ private void pString(final StringBuilder sb, final int len, final int s) {
+ sb.append(":");
+ sb.append(new String(code, s, len));
+ }
+
+- private void pLenString(StringBuilder sb, int len, int s) {
++ private void pLenString(final StringBuilder sb, final int len, final int s) {
+ sb.append(":").append(len).append(":");
+ sb.append(new String(code, s, len));
+ }
+
+- private void pLenStringFromTemplate(StringBuilder sb, int len, char[] tm, int idx) {
++ private static void pLenStringFromTemplate(final StringBuilder sb, final int len, final char[] tm, final int idx) {
+ sb.append(":T:").append(len).append(":");
+ sb.append(tm, idx, len);
+ }
+
+- public int compiledByteCodeToString(StringBuilder sb, int bp) {
++ public int compiledByteCodeToString(final StringBuilder sb, final int bptr) {
+ int len, n, mem, addr, scn, cod;
+ BitSet bs;
+ CClassNode cc;
+ int tm, idx;
++ int bp = bptr;
+
+ sb.append("[").append(OpCodeNames[code[bp]]);
+- int argType = OpCodeArgTypes[code[bp]];
+- int ip = bp;
++ final int argType = OpCodeArgTypes[code[bp]];
++ final int ip = bp;
+ if (argType != Arguments.SPECIAL) {
+ bp++;
+ switch (argType) {
++ default:
+ case Arguments.NON:
+ break;
+
+@@ -410,16 +412,18 @@
+ for (int i=0; i<len; i++) {
+ mem = code[bp];
+ bp += OPSize.MEMNUM;
+- if (i > 0) sb.append(", ");
++ if (i > 0) {
++ sb.append(", ");
++ }
+ sb.append(mem);
+ }
+ break;
+
+ case OPCode.BACKREF_WITH_LEVEL: {
+- int option = code[bp];
++ final int option = code[bp];
+ bp += OPSize.OPTION;
+ sb.append(":").append(option);
+- int level = code[bp];
++ final int level = code[bp];
+ bp += OPSize.LENGTH;
+ sb.append(":").append(level);
+ sb.append(" ");
+@@ -428,7 +432,9 @@
+ for (int i=0; i<len; i++) {
+ mem = code[bp];
+ bp += OPSize.MEMNUM;
+- if (i > 0) sb.append(", ");
++ if (i > 0) {
++ sb.append(", ");
++ }
+ sb.append(mem);
+ }
+ break;
+@@ -491,17 +497,19 @@
+ }
+
+ private String compiledByteCodeListToString() {
+- StringBuilder sb = new StringBuilder();
++ final StringBuilder sb = new StringBuilder();
+ sb.append("code length: ").append(codeLength).append("\n");
+
+ int ncode = 0;
+ int bp = 0;
+- int end = codeLength;
++ final int end = codeLength;
+
+ while (bp < end) {
+ ncode++;
+
+- if (bp > 0) sb.append(ncode % 5 == 0 ? "\n" : " ");
++ if (bp > 0) {
++ sb.append(ncode % 5 == 0 ? "\n" : " ");
++ }
+
+ bp = compiledByteCodeToString(sb, bp);
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CodeRangeBuffer.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CodeRangeBuffer.java Wed Feb 04 12:14:47 2015 -0800
+@@ -22,6 +22,7 @@
+ import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+ import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
+
++@SuppressWarnings("javadoc")
+ public final class CodeRangeBuffer implements Cloneable {
+ private static final int INIT_MULTI_BYTE_RANGE_SIZE = 5;
+ private static final int ALL_MULTI_BYTE_RANGE = 0x7fffffff;
+@@ -36,13 +37,13 @@
+ }
+
+ // CodeRange.isInCodeRange
+- public boolean isInCodeRange(int code) {
++ public boolean isInCodeRange(final int code) {
+ int low = 0;
+- int n = p[0];
++ final int n = p[0];
+ int high = n;
+
+ while (low < high) {
+- int x = (low + high) >> 1;
++ final int x = (low + high) >> 1;
+ if (code > p[(x << 1) + 2]) {
+ low = x + 1;
+ } else {
+@@ -52,7 +53,7 @@
+ return low < n && code >= p[(low << 1) + 1];
+ }
+
+- private CodeRangeBuffer(CodeRangeBuffer orig) {
++ private CodeRangeBuffer(final CodeRangeBuffer orig) {
+ p = new int[orig.p.length];
+ System.arraycopy(orig.p, 0, p, 0, p.length);
+ used = orig.used;
+@@ -60,7 +61,7 @@
+
+ @Override
+ public String toString() {
+- StringBuilder buf = new StringBuilder();
++ final StringBuilder buf = new StringBuilder();
+ buf.append("CodeRange");
+ buf.append("\n used: ").append(used);
+ buf.append("\n code point: ").append(p[0]);
+@@ -68,54 +69,64 @@
+
+ for (int i=0; i<p[0]; i++) {
+ buf.append("[").append(rangeNumToString(p[i * 2 + 1])).append("..").append(rangeNumToString(p[i * 2 + 2])).append("]");
+- if (i > 0 && i % 6 == 0) buf.append("\n ");
++ if (i > 0 && i % 6 == 0) {
++ buf.append("\n ");
++ }
+ }
+
+ return buf.toString();
+ }
+
+- private static String rangeNumToString(int num){
++ private static String rangeNumToString(final int num){
+ return "0x" + Integer.toString(num, 16);
+ }
+
+- public void expand(int low) {
++ public void expand(final int low) {
+ int length = p.length;
+ do { length <<= 1; } while (length < low);
+- int[]tmp = new int[length];
++ final int[]tmp = new int[length];
+ System.arraycopy(p, 0, tmp, 0, used);
+ p = tmp;
+ }
+
+- public void ensureSize(int size) {
++ public void ensureSize(final int size) {
+ int length = p.length;
+ while (length < size ) { length <<= 1; }
+ if (p.length != length) {
+- int[]tmp = new int[length];
++ final int[]tmp = new int[length];
+ System.arraycopy(p, 0, tmp, 0, used);
+ p = tmp;
+ }
+ }
+
+- private void moveRight(int from, int to, int n) {
+- if (to + n > p.length) expand(to + n);
++ private void moveRight(final int from, final int to, final int n) {
++ if (to + n > p.length) {
++ expand(to + n);
++ }
+ System.arraycopy(p, from, p, to, n);
+- if (to + n > used) used = to + n;
++ if (to + n > used) {
++ used = to + n;
++ }
+ }
+
+- protected void moveLeft(int from, int to, int n) {
++ protected void moveLeft(final int from, final int to, final int n) {
+ System.arraycopy(p, from, p, to, n);
+ }
+
+- private void moveLeftAndReduce(int from, int to) {
++ private void moveLeftAndReduce(final int from, final int to) {
+ System.arraycopy(p, from, p, to, used - from);
+ used -= from - to;
+ }
+
+- public void writeCodePoint(int pos, int b) {
+- int u = pos + 1;
+- if (p.length < u) expand(u);
++ public void writeCodePoint(final int pos, final int b) {
++ final int u = pos + 1;
++ if (p.length < u) {
++ expand(u);
++ }
+ p[pos] = b;
+- if (used < u) used = u;
++ if (used < u) {
++ used = u;
++ }
+ }
+
+ @Override
+@@ -125,23 +136,28 @@
+
+ // ugly part: these methods should be made OO
+ // add_code_range_to_buf
+- public static CodeRangeBuffer addCodeRangeToBuff(CodeRangeBuffer pbuf, int from, int to) {
++ public static CodeRangeBuffer addCodeRangeToBuff(final CodeRangeBuffer pbufp, final int fromp, final int top) {
++ int from = fromp, to = top;
++ CodeRangeBuffer pbuf = pbufp;
++
+ if (from > to) {
+- int n = from;
++ final int n = from;
+ from = to;
+ to = n;
+ }
+
+- if (pbuf == null) pbuf = new CodeRangeBuffer(); // move to CClassNode
++ if (pbuf == null) {
++ pbuf = new CodeRangeBuffer(); // move to CClassNode
++ }
+
+- int[]p = pbuf.p;
++ final int[]p = pbuf.p;
+ int n = p[0];
+
+ int low = 0;
+ int bound = n;
+
+ while (low < bound) {
+- int x = (low + bound) >>> 1;
++ final int x = (low + bound) >>> 1;
+ if (from > p[x * 2 + 2]) {
+ low = x + 1;
+ } else {
+@@ -153,7 +169,7 @@
+ bound = n;
+
+ while (high < bound) {
+- int x = (high + bound) >>> 1;
++ final int x = (high + bound) >>> 1;
+ if (to >= p[x * 2 + 1] - 1) {
+ high = x + 1;
+ } else {
+@@ -161,19 +177,25 @@
+ }
+ }
+
+- int incN = low + 1 - high;
++ final int incN = low + 1 - high;
+
+- if (n + incN > Config.MAX_MULTI_BYTE_RANGES_NUM) throw new ValueException(ErrorMessages.ERR_TOO_MANY_MULTI_BYTE_RANGES);
++ if (n + incN > Config.MAX_MULTI_BYTE_RANGES_NUM) {
++ throw new ValueException(ErrorMessages.ERR_TOO_MANY_MULTI_BYTE_RANGES);
++ }
+
+ if (incN != 1) {
+- if (from > p[low * 2 + 1]) from = p[low * 2 + 1];
+- if (to < p[(high - 1) * 2 + 2]) to = p[(high - 1) * 2 + 2];
++ if (from > p[low * 2 + 1]) {
++ from = p[low * 2 + 1];
++ }
++ if (to < p[(high - 1) * 2 + 2]) {
++ to = p[(high - 1) * 2 + 2];
++ }
+ }
+
+ if (incN != 0 && high < n) {
+- int fromPos = 1 + high * 2;
+- int toPos = 1 + (low + 1) * 2;
+- int size = (n - high) * 2;
++ final int fromPos = 1 + high * 2;
++ final int toPos = 1 + (low + 1) * 2;
++ final int size = (n - high) * 2;
+
+ if (incN > 0) {
+ pbuf.moveRight(fromPos, toPos, size);
+@@ -182,7 +204,7 @@
+ }
+ }
+
+- int pos = 1 + low * 2;
++ final int pos = 1 + low * 2;
+ // pbuf.ensureSize(pos + 2);
+ pbuf.writeCodePoint(pos, from);
+ pbuf.writeCodePoint(pos + 1, to);
+@@ -193,37 +215,40 @@
+ }
+
+ // add_code_range, be aware of it returning null!
+- public static CodeRangeBuffer addCodeRange(CodeRangeBuffer pbuf, ScanEnvironment env, int from, int to) {
++ public static CodeRangeBuffer addCodeRange(final CodeRangeBuffer pbuf, final ScanEnvironment env, final int from, final int to) {
+ if (from > to) {
+ if (env.syntax.allowEmptyRangeInCC()) {
+ return pbuf;
+- } else {
+- throw new ValueException(ErrorMessages.ERR_EMPTY_RANGE_IN_CHAR_CLASS);
+ }
++ throw new ValueException(ErrorMessages.ERR_EMPTY_RANGE_IN_CHAR_CLASS);
+ }
+ return addCodeRangeToBuff(pbuf, from, to);
+ }
+
+ // SET_ALL_MULTI_BYTE_RANGE
+- protected static CodeRangeBuffer setAllMultiByteRange(CodeRangeBuffer pbuf) {
++ protected static CodeRangeBuffer setAllMultiByteRange(final CodeRangeBuffer pbuf) {
+ return addCodeRangeToBuff(pbuf, EncodingHelper.mbcodeStartPosition(), ALL_MULTI_BYTE_RANGE);
+ }
+
+ // ADD_ALL_MULTI_BYTE_RANGE
+- public static CodeRangeBuffer addAllMultiByteRange(CodeRangeBuffer pbuf) {
++ public static CodeRangeBuffer addAllMultiByteRange(final CodeRangeBuffer pbuf) {
+ return setAllMultiByteRange(pbuf);
+ }
+
+ // not_code_range_buf
+- public static CodeRangeBuffer notCodeRangeBuff(CodeRangeBuffer bbuf) {
++ public static CodeRangeBuffer notCodeRangeBuff(final CodeRangeBuffer bbuf) {
+ CodeRangeBuffer pbuf = null;
+
+- if (bbuf == null) return setAllMultiByteRange(pbuf);
++ if (bbuf == null) {
++ return setAllMultiByteRange(pbuf);
++ }
+
+- int[]p = bbuf.p;
+- int n = p[0];
++ final int[]p = bbuf.p;
++ final int n = p[0];
+
+- if (n <= 0) return setAllMultiByteRange(pbuf);
++ if (n <= 0) {
++ return setAllMultiByteRange(pbuf);
++ }
+
+ int pre = EncodingHelper.mbcodeStartPosition();
+
+@@ -235,18 +260,26 @@
+ if (pre <= from - 1) {
+ pbuf = addCodeRangeToBuff(pbuf, pre, from - 1);
+ }
+- if (to == ALL_MULTI_BYTE_RANGE) break;
++ if (to == ALL_MULTI_BYTE_RANGE) {
++ break;
++ }
+ pre = to + 1;
+ }
+
+- if (to < ALL_MULTI_BYTE_RANGE) pbuf = addCodeRangeToBuff(pbuf, to + 1, ALL_MULTI_BYTE_RANGE);
++ if (to < ALL_MULTI_BYTE_RANGE) {
++ pbuf = addCodeRangeToBuff(pbuf, to + 1, ALL_MULTI_BYTE_RANGE);
++ }
+ return pbuf;
+ }
+
+ // or_code_range_buf
+- public static CodeRangeBuffer orCodeRangeBuff(CodeRangeBuffer bbuf1, boolean not1,
+- CodeRangeBuffer bbuf2, boolean not2) {
++ public static CodeRangeBuffer orCodeRangeBuff(final CodeRangeBuffer bbuf1p, final boolean not1p,
++ final CodeRangeBuffer bbuf2p, final boolean not2p) {
+ CodeRangeBuffer pbuf = null;
++ CodeRangeBuffer bbuf1 = bbuf1p;
++ CodeRangeBuffer bbuf2 = bbuf2p;
++ boolean not1 = not1p;
++ boolean not2 = not2p;
+
+ if (bbuf1 == null && bbuf2 == null) {
+ if (not1 || not2) {
+@@ -266,13 +299,11 @@
+ if (bbuf1 == null) {
+ if (not1) {
+ return setAllMultiByteRange(pbuf);
+- } else {
+- if (!not2) {
+- return bbuf2.clone();
+- } else {
+- return notCodeRangeBuff(bbuf2);
+- }
+ }
++ if (!not2) {
++ return bbuf2.clone();
++ }
++ return notCodeRangeBuff(bbuf2);
+ }
+
+ if (not1) {
+@@ -289,12 +320,12 @@
+ pbuf = notCodeRangeBuff(bbuf2);
+ }
+
+- int[]p1 = bbuf1.p;
+- int n1 = p1[0];
++ final int[]p1 = bbuf1.p;
++ final int n1 = p1[0];
+
+ for (int i=0; i<n1; i++) {
+- int from = p1[i * 2 + 1];
+- int to = p1[i * 2 + 2];
++ final int from = p1[i * 2 + 1];
++ final int to = p1[i * 2 + 2];
+ pbuf = addCodeRangeToBuff(pbuf, from, to);
+ }
+
+@@ -302,16 +333,18 @@
+ }
+
+ // and_code_range1
+- public static CodeRangeBuffer andCodeRange1(CodeRangeBuffer pbuf, int from1, int to1, int[]data, int n) {
++ public static CodeRangeBuffer andCodeRange1(final CodeRangeBuffer pbufp, final int from1p, final int to1p, final int[]data, final int n) {
++ CodeRangeBuffer pbuf = pbufp;
++ int from1 = from1p, to1 = to1p;
++
+ for (int i=0; i<n; i++) {
+- int from2 = data[i * 2 + 1];
+- int to2 = data[i * 2 + 2];
++ final int from2 = data[i * 2 + 1];
++ final int to2 = data[i * 2 + 2];
+ if (from2 < from1) {
+ if (to2 < from1) {
+ continue;
+- } else {
+- from1 = to2 + 1;
+ }
++ from1 = to2 + 1;
+ } else if (from2 <= to1) {
+ if (to2 < to1) {
+ if (from1 <= from2 - 1) {
+@@ -324,7 +357,9 @@
+ } else {
+ from1 = from2;
+ }
+- if (from1 > to1) break;
++ if (from1 > to1) {
++ break;
++ }
+ }
+
+ if (from1 <= to1) {
+@@ -335,15 +370,22 @@
+ }
+
+ // and_code_range_buf
+- public static CodeRangeBuffer andCodeRangeBuff(CodeRangeBuffer bbuf1, boolean not1,
+- CodeRangeBuffer bbuf2, boolean not2) {
++ public static CodeRangeBuffer andCodeRangeBuff(final CodeRangeBuffer bbuf1p, final boolean not1p,
++ final CodeRangeBuffer bbuf2p, final boolean not2p) {
+ CodeRangeBuffer pbuf = null;
++ CodeRangeBuffer bbuf1 = bbuf1p;
++ CodeRangeBuffer bbuf2 = bbuf2p;
++ boolean not1 = not1p, not2 = not2p;
+
+ if (bbuf1 == null) {
+- if (not1 && bbuf2 != null) return bbuf2.clone(); /* not1 != 0 -> not2 == 0 */
++ if (not1 && bbuf2 != null) {
++ return bbuf2.clone(); /* not1 != 0 -> not2 == 0 */
++ }
+ return null;
+ } else if (bbuf2 == null) {
+- if (not2) return bbuf1.clone();
++ if (not2) {
++ return bbuf1.clone();
++ }
+ return null;
+ }
+
+@@ -355,31 +397,35 @@
+ tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf;
+ }
+
+- int[]p1 = bbuf1.p;
+- int n1 = p1[0];
+- int[]p2 = bbuf2.p;
+- int n2 = p2[0];
++ final int[]p1 = bbuf1.p;
++ final int n1 = p1[0];
++ final int[]p2 = bbuf2.p;
++ final int n2 = p2[0];
+
+ if (!not2 && !not1) { /* 1 AND 2 */
+ for (int i=0; i<n1; i++) {
+- int from1 = p1[i * 2 + 1];
+- int to1 = p1[i * 2 + 2];
++ final int from1 = p1[i * 2 + 1];
++ final int to1 = p1[i * 2 + 2];
+
+ for (int j=0; j<n2; j++) {
+- int from2 = p2[j * 2 + 1];
+- int to2 = p2[j * 2 + 2];
++ final int from2 = p2[j * 2 + 1];
++ final int to2 = p2[j * 2 + 2];
+
+- if (from2 > to1) break;
+- if (to2 < from1) continue;
+- int from = from1 > from2 ? from1 : from2;
+- int to = to1 < to2 ? to1 : to2;
++ if (from2 > to1) {
++ break;
++ }
++ if (to2 < from1) {
++ continue;
++ }
++ final int from = from1 > from2 ? from1 : from2;
++ final int to = to1 < to2 ? to1 : to2;
+ pbuf = addCodeRangeToBuff(pbuf, from, to);
+ }
+ }
+ } else if (!not1) { /* 1 AND (not 2) */
+ for (int i=0; i<n1; i++) {
+- int from1 = p1[i * 2 + 1];
+- int to1 = p1[i * 2 + 2];
++ final int from1 = p1[i * 2 + 1];
++ final int to1 = p1[i * 2 + 2];
+ pbuf = andCodeRange1(pbuf, from1, to1, p2, n2);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Compiler.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Compiler.java Wed Feb 04 12:14:47 2015 -0800
+@@ -36,7 +36,7 @@
+ protected final Analyser analyser;
+ protected final Regex regex;
+
+- protected Compiler(Analyser analyser) {
++ protected Compiler(final Analyser analyser) {
+ this.analyser = analyser;
+ this.regex = analyser.regex;
+ }
+@@ -52,21 +52,25 @@
+
+ protected abstract void compileAltNode(ConsAltNode node);
+
+- private void compileStringRawNode(StringNode sn) {
+- if (sn.length() <= 0) return;
++ private void compileStringRawNode(final StringNode sn) {
++ if (sn.length() <= 0) {
++ return;
++ }
+ addCompileString(sn.chars, sn.p, sn.length(), false);
+ }
+
+- private void compileStringNode(StringNode node) {
+- StringNode sn = node;
+- if (sn.length() <= 0) return;
++ private void compileStringNode(final StringNode node) {
++ final StringNode sn = node;
++ if (sn.length() <= 0) {
++ return;
++ }
+
+- boolean ambig = sn.isAmbig();
++ final boolean ambig = sn.isAmbig();
+
+ int p, prev;
+ p = prev = sn.p;
+- int end = sn.end;
+- char[] chars = sn.chars;
++ final int end = sn.end;
++ final char[] chars = sn.chars;
+ p++;
+ int slen = 1;
+
+@@ -87,7 +91,7 @@
+ protected abstract void compileEncloseNode(EncloseNode node);
+ protected abstract void compileAnchorNode(AnchorNode node);
+
+- protected final void compileTree(Node node) {
++ protected final void compileTree(final Node node) {
+ switch (node.getType()) {
+ case NodeType.LIST:
+ ConsAltNode lin = (ConsAltNode)node;
+@@ -101,7 +105,7 @@
+ break;
+
+ case NodeType.STR:
+- StringNode sn = (StringNode)node;
++ final StringNode sn = (StringNode)node;
+ if (sn.isRaw()) {
+ compileStringRawNode(sn);
+ } else {
+@@ -126,7 +130,7 @@
+ break;
+
+ case NodeType.ENCLOSE:
+- EncloseNode enode = (EncloseNode)node;
++ final EncloseNode enode = (EncloseNode)node;
+ if (enode.isOption()) {
+ compileOptionNode(enode);
+ } else {
+@@ -144,15 +148,17 @@
+ } // switch
+ }
+
+- protected final void compileTreeNTimes(Node node, int n) {
+- for (int i=0; i<n; i++) compileTree(node);
++ protected final void compileTreeNTimes(final Node node, final int n) {
++ for (int i=0; i<n; i++) {
++ compileTree(node);
++ }
+ }
+
+- protected void newSyntaxException(String message) {
++ protected void newSyntaxException(final String message) {
+ throw new SyntaxException(message);
+ }
+
+- protected void newInternalException(String message) {
++ protected void newInternalException(final String message) {
+ throw new InternalException(message);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Config.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Config.java Wed Feb 04 12:14:47 2015 -0800
+@@ -21,6 +21,7 @@
+
+ import java.io.PrintStream;
+
++@SuppressWarnings("javadoc")
+ public interface Config {
+ final int CHAR_TABLE_SIZE = 256;
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,11 +19,11 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni;
+
++import java.util.Arrays;
+ import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
+ import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
+
+-import java.util.Arrays;
+-
++@SuppressWarnings("javadoc")
+ public final class EncodingHelper {
+
+ final static int NEW_LINE = 0x000a;
+@@ -34,19 +34,19 @@
+ final static char[] EMPTYCHARS = new char[0];
+ final static int[][] codeRanges = new int[15][];
+
+- public static int digitVal(int code) {
++ public static int digitVal(final int code) {
+ return code - '0';
+ }
+
+- public static int odigitVal(int code) {
++ public static int odigitVal(final int code) {
+ return digitVal(code);
+ }
+
+- public static boolean isXDigit(int code) {
++ public static boolean isXDigit(final int code) {
+ return Character.isDigit(code) || (code >= 'a' && code <= 'f') || (code >= 'A' && code <= 'F');
+ }
+
+- public static int xdigitVal(int code) {
++ public static int xdigitVal(final int code) {
+ if (Character.isDigit(code)) {
+ return code - '0';
+ } else if (code >= 'a' && code <= 'f') {
+@@ -56,38 +56,43 @@
+ }
+ }
+
+- public static boolean isDigit(int code) {
++ public static boolean isDigit(final int code) {
+ return code >= '0' && code <= '9';
+ }
+
+- public static boolean isWord(int code) {
++ public static boolean isWord(final int code) {
+ // letter, digit, or '_'
+ return (1 << Character.getType(code) & CharacterType.WORD_MASK) != 0;
+ }
+
+- public static boolean isNewLine(int code) {
++ public static boolean isNewLine(final int code) {
+ return code == NEW_LINE || code == RETURN || code == LINE_SEPARATOR || code == PARAGRAPH_SEPARATOR;
+ }
+
+- public static boolean isNewLine(char[] chars, int p, int end) {
++ public static boolean isNewLine(final char[] chars, final int p, final int end) {
+ return p < end && isNewLine(chars[p]);
+ }
+
+ // Encoding.prevCharHead
+- public static int prevCharHead(int p, int s) {
++ public static int prevCharHead(final int p, final int s) {
+ return s <= p ? -1 : s - 1;
+ }
+
+ /* onigenc_get_right_adjust_char_head_with_prev */
+- public static int rightAdjustCharHeadWithPrev(int s, IntHolder prev) {
+- if (prev != null) prev.value = -1; /* Sorry */
++ public static int rightAdjustCharHeadWithPrev(final int s, final IntHolder prev) {
++ if (prev != null) {
++ prev.value = -1; /* Sorry */
++ }
+ return s;
+ }
+
+ // Encoding.stepBack
+- public static int stepBack(int p, int s, int n) {
+- while (s != -1 && n-- > 0) {
+- if (s <= p) return -1;
++ public static int stepBack(final int p, final int sp, final int np) {
++ int s = sp, n = np;
++ while (s != -1 && n-- > 0) {
++ if (s <= p) {
++ return -1;
++ }
+ s--;
+ }
+ return s;
+@@ -97,7 +102,7 @@
+ return 0x80;
+ }
+
+- public static char[] caseFoldCodesByString(int flag, char c) {
++ public static char[] caseFoldCodesByString(final int flag, final char c) {
+ char[] codes = EMPTYCHARS;
+ final char upper = toUpperCase(c);
+
+@@ -117,13 +122,13 @@
+ return codes;
+ }
+
+- public static void applyAllCaseFold(int flag, ApplyCaseFold fun, Object arg) {
++ public static void applyAllCaseFold(final int flag, final ApplyCaseFold fun, final Object arg) {
+ for (int c = 0; c < 0xffff; c++) {
+ if (Character.isLowerCase(c)) {
+ final int upper = toUpperCase(c);
+
+ if (upper != c) {
+- fun.apply(c, upper, arg);
++ ApplyCaseFold.apply(c, upper, arg);
+ }
+ }
+ }
+@@ -134,40 +139,40 @@
+ final int upper = toUpperCase(c);
+
+ if (upper != c) {
+- fun.apply(upper, c, arg);
++ ApplyCaseFold.apply(upper, c, arg);
+ }
+ }
+ }
+ }
+
+- public static char toLowerCase(char c) {
++ public static char toLowerCase(final char c) {
+ return (char)toLowerCase((int)c);
+ }
+
+- public static int toLowerCase(int c) {
++ public static int toLowerCase(final int c) {
+ if (c < 128) {
+ return ('A' <= c && c <= 'Z') ? (c + ('a' - 'A')) : c;
+ }
+ // Do not convert non-ASCII upper case character to ASCII lower case.
+- int lower = Character.toLowerCase(c);
++ final int lower = Character.toLowerCase(c);
+ return (lower < 128) ? c : lower;
+
+ }
+
+- public static char toUpperCase(char c) {
++ public static char toUpperCase(final char c) {
+ return (char)toUpperCase((int)c);
+ }
+
+- public static int toUpperCase(int c) {
++ public static int toUpperCase(final int c) {
+ if (c < 128) {
+ return ('a' <= c && c <= 'z') ? c + ('A' - 'a') : c;
+ }
+ // Do not convert non-ASCII lower case character to ASCII upper case.
+- int upper = Character.toUpperCase(c);
++ final int upper = Character.toUpperCase(c);
+ return (upper < 128) ? c : upper;
+ }
+
+- public static int[] ctypeCodeRange(int ctype, IntHolder sbOut) {
++ public static int[] ctypeCodeRange(final int ctype, final IntHolder sbOut) {
+ sbOut.value = 0x100; // use bitset for codes smaller than 256
+ int[] range = null;
+
+@@ -206,13 +211,13 @@
+ }
+
+ // CodeRange.isInCodeRange
+- public static boolean isInCodeRange(int[] p, int offset, int code) {
++ public static boolean isInCodeRange(final int[] p, final int offset, final int code) {
+ int low = 0;
+- int n = p[offset];
++ final int n = p[offset];
+ int high = n ;
+
+ while (low < high) {
+- int x = (low + high) >> 1;
++ final int x = (low + high) >> 1;
+ if (code > p[(x << 1) + 2 + offset]) {
+ low = x + 1;
+ } else {
+@@ -225,7 +230,7 @@
+ /**
+ * @see <a href="http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt">http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt</a>
+ */
+- public static boolean isCodeCType(int code, int ctype) {
++ public static boolean isCodeCType(final int code, final int ctype) {
+ int type;
+ switch (ctype) {
+ case CharacterType.NEWLINE:
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Lexer.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Lexer.java Wed Feb 04 12:14:47 2015 -0800
+@@ -21,7 +21,6 @@
+
+ import static jdk.nashorn.internal.runtime.regexp.joni.Option.isSingleline;
+ import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.isRepeatInfinite;
+-
+ import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode;
+ import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
+ import jdk.nashorn.internal.runtime.regexp.joni.constants.MetaChar;
+@@ -36,7 +35,7 @@
+ protected final Syntax syntax; // fast access to syntax
+ protected final Token token = new Token(); // current token
+
+- protected Lexer(ScanEnvironment env, char[] chars, int p, int end) {
++ protected Lexer(final ScanEnvironment env, final char[] chars, final int p, final int end) {
+ super(chars, p, end);
+ this.env = env;
+ this.syntax = env.syntax;
+@@ -48,14 +47,13 @@
+ */
+ private int fetchRangeQuantifier() {
+ mark();
+- boolean synAllow = syntax.allowInvalidInterval();
++ final boolean synAllow = syntax.allowInvalidInterval();
+
+ if (!left()) {
+ if (synAllow) {
+ return 1; /* "....{" : OK! */
+- } else {
+- throw new SyntaxException(ERR_END_PATTERN_AT_LEFT_BRACE);
+ }
++ throw new SyntaxException(ERR_END_PATTERN_AT_LEFT_BRACE);
+ }
+
+ if (!synAllow) {
+@@ -83,13 +81,15 @@
+ }
+ }
+
+- if (!left()) return invalidRangeQuantifier(synAllow);
++ if (!left()) {
++ return invalidRangeQuantifier(synAllow);
++ }
+
+ fetch();
+ int up;
+ int ret = 0;
+ if (c == ',') {
+- int prev = p; // ??? last
++ final int prev = p; // ??? last
+ up = scanUnsignedNumber();
+ if (up < 0) {
+ throw new ValueException(ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE);
+@@ -99,25 +99,35 @@
+ }
+
+ if (p == prev) {
+- if (nonLow) return invalidRangeQuantifier(synAllow);
++ if (nonLow) {
++ return invalidRangeQuantifier(synAllow);
++ }
+ up = QuantifierNode.REPEAT_INFINITE; /* {n,} : {n,infinite} */
+ }
+ } else {
+- if (nonLow) return invalidRangeQuantifier(synAllow);
++ if (nonLow) {
++ return invalidRangeQuantifier(synAllow);
++ }
+ unfetch();
+ up = low; /* {n} : exact n times */
+ ret = 2; /* fixed */
+ }
+
+- if (!left()) return invalidRangeQuantifier(synAllow);
++ if (!left()) {
++ return invalidRangeQuantifier(synAllow);
++ }
+ fetch();
+
+ if (syntax.opEscBraceInterval()) {
+- if (c != syntax.metaCharTable.esc) return invalidRangeQuantifier(synAllow);
++ if (c != syntax.metaCharTable.esc) {
++ return invalidRangeQuantifier(synAllow);
++ }
+ fetch();
+ }
+
+- if (c != '}') return invalidRangeQuantifier(synAllow);
++ if (c != '}') {
++ return invalidRangeQuantifier(synAllow);
++ }
+
+ if (!isRepeatInfinite(up) && low > up) {
+ throw new ValueException(ERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE);
+@@ -130,13 +140,12 @@
+ return ret; /* 0: normal {n,m}, 2: fixed {n} */
+ }
+
+- private int invalidRangeQuantifier(boolean synAllow) {
++ private int invalidRangeQuantifier(final boolean synAllow) {
+ if (synAllow) {
+ restore();
+ return 1;
+- } else {
+- throw new SyntaxException(ERR_INVALID_REPEAT_RANGE_PATTERN);
+ }
++ throw new SyntaxException(ERR_INVALID_REPEAT_RANGE_PATTERN);
+ }
+
+ @SuppressWarnings("fallthrough")
+@@ -218,35 +227,26 @@
+ }
+ }
+
+- private int nameEndCodePoint(int start) {
+- switch(start) {
+- case '<':
+- return '>';
+- case '\'':
+- return '\'';
+- default:
+- return 0;
+- }
+- }
+-
+- private void fetchTokenInCCFor_charType(boolean flag, int type) {
++ private void fetchTokenInCCFor_charType(final boolean flag, final int type) {
+ token.type = TokenType.CHAR_TYPE;
+ token.setPropCType(type);
+ token.setPropNot(flag);
+ }
+
+ private void fetchTokenInCCFor_x() {
+- if (!left()) return;
+- int last = p;
++ if (!left()) {
++ return;
++ }
++ final int last = p;
+
+ if (peekIs('{') && syntax.opEscXBraceHex8()) {
+ inc();
+- int num = scanUnsignedHexadecimalNumber(8);
++ final int num = scanUnsignedHexadecimalNumber(8);
+ if (num < 0) {
+ throw new ValueException(ERR_TOO_BIG_WIDE_CHAR_VALUE);
+ }
+ if (left()) {
+- int c2 = peek();
++ final int c2 = peek();
+ if (EncodingHelper.isXDigit(c2)) {
+ throw new ValueException(ERR_TOO_LONG_WIDE_CHAR_VALUE);
+ }
+@@ -274,8 +274,10 @@
+ }
+
+ private void fetchTokenInCCFor_u() {
+- if (!left()) return;
+- int last = p;
++ if (!left()) {
++ return;
++ }
++ final int last = p;
+
+ if (syntax.op2EscUHex4()) {
+ int num = scanUnsignedHexadecimalNumber(4);
+@@ -293,7 +295,7 @@
+ private void fetchTokenInCCFor_digit() {
+ if (syntax.opEscOctal3()) {
+ unfetch();
+- int last = p;
++ final int last = p;
+ int num = scanUnsignedOctalNumber(3);
+ if (num < 0) {
+ throw new ValueException(ERR_TOO_BIG_NUMBER);
+@@ -329,7 +331,9 @@
+ } else if (c == '-') {
+ token.type = TokenType.CC_RANGE;
+ } else if (c == syntax.metaCharTable.esc) {
+- if (!syntax.backSlashEscapeInCC()) return token.type;
++ if (!syntax.backSlashEscapeInCC()) {
++ return token.type;
++ }
+ if (!left()) {
+ throw new SyntaxException(ERR_END_PATTERN_AT_ESCAPE);
+ }
+@@ -357,10 +361,14 @@
+ fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.S : CharacterType.SPACE);
+ break;
+ case 'h':
+- if (syntax.op2EscHXDigit()) fetchTokenInCCFor_charType(false, CharacterType.XDIGIT);
++ if (syntax.op2EscHXDigit()) {
++ fetchTokenInCCFor_charType(false, CharacterType.XDIGIT);
++ }
+ break;
+ case 'H':
+- if (syntax.op2EscHXDigit()) fetchTokenInCCFor_charType(true, CharacterType.XDIGIT);
++ if (syntax.op2EscHXDigit()) {
++ fetchTokenInCCFor_charType(true, CharacterType.XDIGIT);
++ }
+ break;
+ case 'x':
+ fetchTokenInCCFor_x();
+@@ -381,7 +389,7 @@
+
+ default:
+ unfetch();
+- int num = fetchEscapedValue();
++ final int num = fetchEscapedValue();
+ if (token.getC() != num) {
+ token.setCode(num);
+ token.type = TokenType.CODE_POINT;
+@@ -395,7 +403,7 @@
+ return token.type;
+ }
+
+- private void fetchTokenFor_repeat(int lower, int upper) {
++ private void fetchTokenFor_repeat(final int lower, final int upper) {
+ token.type = TokenType.OP_REPEAT;
+ token.setRepeatLower(lower);
+ token.setRepeatUpper(upper);
+@@ -418,18 +426,20 @@
+ } // inner switch
+ }
+
+- private void fetchTokenFor_anchor(int subType) {
++ private void fetchTokenFor_anchor(final int subType) {
+ token.type = TokenType.ANCHOR;
+ token.setAnchor(subType);
+ }
+
+ private void fetchTokenFor_xBrace() {
+- if (!left()) return;
++ if (!left()) {
++ return;
++ }
+
+- int last = p;
++ final int last = p;
+ if (peekIs('{') && syntax.opEscXBraceHex8()) {
+ inc();
+- int num = scanUnsignedHexadecimalNumber(8);
++ final int num = scanUnsignedHexadecimalNumber(8);
+ if (num < 0) {
+ throw new ValueException(ERR_TOO_BIG_WIDE_CHAR_VALUE);
+ }
+@@ -461,8 +471,10 @@
+ }
+
+ private void fetchTokenFor_uHex() {
+- if (!left()) return;
+- int last = p;
++ if (!left()) {
++ return;
++ }
++ final int last = p;
+
+ if (syntax.op2EscUHex4()) {
+ int num = scanUnsignedHexadecimalNumber(4);
+@@ -479,8 +491,8 @@
+
+ private void fetchTokenFor_digit() {
+ unfetch();
+- int last = p;
+- int num = scanUnsignedNumber();
++ final int last = p;
++ final int num = scanUnsignedNumber();
+ if (num < 0 || num > Config.MAX_BACKREF_NUM) { // goto skip_backref
+ } else if (syntax.opDecimalBackref() && (num <= env.numMem || num <= 9)) { /* This spec. from GNU regex */
+ if (syntax.strictCheckBackref()) {
+@@ -505,7 +517,7 @@
+
+ private void fetchTokenFor_zero() {
+ if (syntax.opEscOctal3()) {
+- int last = p;
++ final int last = p;
+ int num = scanUnsignedOctalNumber(c == '0' ? 2 : 3);
+ if (num < 0) {
+ throw new ValueException(ERR_TOO_BIG_NUMBER);
+@@ -562,79 +574,129 @@
+ switch(c) {
+
+ case '*':
+- if (syntax.opEscAsteriskZeroInf()) fetchTokenFor_repeat(0, QuantifierNode.REPEAT_INFINITE);
++ if (syntax.opEscAsteriskZeroInf()) {
++ fetchTokenFor_repeat(0, QuantifierNode.REPEAT_INFINITE);
++ }
+ break;
+ case '+':
+- if (syntax.opEscPlusOneInf()) fetchTokenFor_repeat(1, QuantifierNode.REPEAT_INFINITE);
++ if (syntax.opEscPlusOneInf()) {
++ fetchTokenFor_repeat(1, QuantifierNode.REPEAT_INFINITE);
++ }
+ break;
+ case '?':
+- if (syntax.opEscQMarkZeroOne()) fetchTokenFor_repeat(0, 1);
++ if (syntax.opEscQMarkZeroOne()) {
++ fetchTokenFor_repeat(0, 1);
++ }
+ break;
+ case '{':
+- if (syntax.opEscBraceInterval()) fetchTokenFor_openBrace();
++ if (syntax.opEscBraceInterval()) {
++ fetchTokenFor_openBrace();
++ }
+ break;
+ case '|':
+- if (syntax.opEscVBarAlt()) token.type = TokenType.ALT;
++ if (syntax.opEscVBarAlt()) {
++ token.type = TokenType.ALT;
++ }
+ break;
+ case '(':
+- if (syntax.opEscLParenSubexp()) token.type = TokenType.SUBEXP_OPEN;
++ if (syntax.opEscLParenSubexp()) {
++ token.type = TokenType.SUBEXP_OPEN;
++ }
+ break;
+ case ')':
+- if (syntax.opEscLParenSubexp()) token.type = TokenType.SUBEXP_CLOSE;
++ if (syntax.opEscLParenSubexp()) {
++ token.type = TokenType.SUBEXP_CLOSE;
++ }
+ break;
+ case 'w':
+- if (syntax.opEscWWord()) fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.W : CharacterType.WORD);
++ if (syntax.opEscWWord()) {
++ fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.W : CharacterType.WORD);
++ }
+ break;
+ case 'W':
+- if (syntax.opEscWWord()) fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.W : CharacterType.WORD);
++ if (syntax.opEscWWord()) {
++ fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.W : CharacterType.WORD);
++ }
+ break;
+ case 'b':
+- if (syntax.opEscBWordBound()) fetchTokenFor_anchor(AnchorType.WORD_BOUND);
++ if (syntax.opEscBWordBound()) {
++ fetchTokenFor_anchor(AnchorType.WORD_BOUND);
++ }
+ break;
+ case 'B':
+- if (syntax.opEscBWordBound()) fetchTokenFor_anchor(AnchorType.NOT_WORD_BOUND);
++ if (syntax.opEscBWordBound()) {
++ fetchTokenFor_anchor(AnchorType.NOT_WORD_BOUND);
++ }
+ break;
+ case '<':
+- if (Config.USE_WORD_BEGIN_END && syntax.opEscLtGtWordBeginEnd()) fetchTokenFor_anchor(AnchorType.WORD_BEGIN);
++ if (Config.USE_WORD_BEGIN_END && syntax.opEscLtGtWordBeginEnd()) {
++ fetchTokenFor_anchor(AnchorType.WORD_BEGIN);
++ }
+ break;
+ case '>':
+- if (Config.USE_WORD_BEGIN_END && syntax.opEscLtGtWordBeginEnd()) fetchTokenFor_anchor(AnchorType.WORD_END);
++ if (Config.USE_WORD_BEGIN_END && syntax.opEscLtGtWordBeginEnd()) {
++ fetchTokenFor_anchor(AnchorType.WORD_END);
++ }
+ break;
+ case 's':
+- if (syntax.opEscSWhiteSpace()) fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.S : CharacterType.SPACE);
++ if (syntax.opEscSWhiteSpace()) {
++ fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.S : CharacterType.SPACE);
++ }
+ break;
+ case 'S':
+- if (syntax.opEscSWhiteSpace()) fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.S : CharacterType.SPACE);
++ if (syntax.opEscSWhiteSpace()) {
++ fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.S : CharacterType.SPACE);
++ }
+ break;
+ case 'd':
+- if (syntax.opEscDDigit()) fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.D : CharacterType.DIGIT);
++ if (syntax.opEscDDigit()) {
++ fetchTokenInCCFor_charType(false, Config.NON_UNICODE_SDW ? CharacterType.D : CharacterType.DIGIT);
++ }
+ break;
+ case 'D':
+- if (syntax.opEscDDigit()) fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.D : CharacterType.DIGIT);
++ if (syntax.opEscDDigit()) {
++ fetchTokenInCCFor_charType(true, Config.NON_UNICODE_SDW ? CharacterType.D : CharacterType.DIGIT);
++ }
+ break;
+ case 'h':
+- if (syntax.op2EscHXDigit()) fetchTokenInCCFor_charType(false, CharacterType.XDIGIT);
++ if (syntax.op2EscHXDigit()) {
++ fetchTokenInCCFor_charType(false, CharacterType.XDIGIT);
++ }
+ break;
+ case 'H':
+- if (syntax.op2EscHXDigit()) fetchTokenInCCFor_charType(true, CharacterType.XDIGIT);
++ if (syntax.op2EscHXDigit()) {
++ fetchTokenInCCFor_charType(true, CharacterType.XDIGIT);
++ }
+ break;
+ case 'A':
+- if (syntax.opEscAZBufAnchor()) fetchTokenFor_anchor(AnchorType.BEGIN_BUF);
++ if (syntax.opEscAZBufAnchor()) {
++ fetchTokenFor_anchor(AnchorType.BEGIN_BUF);
++ }
+ break;
+ case 'Z':
+- if (syntax.opEscAZBufAnchor()) fetchTokenFor_anchor(AnchorType.SEMI_END_BUF);
++ if (syntax.opEscAZBufAnchor()) {
++ fetchTokenFor_anchor(AnchorType.SEMI_END_BUF);
++ }
+ break;
+ case 'z':
+- if (syntax.opEscAZBufAnchor()) fetchTokenFor_anchor(AnchorType.END_BUF);
++ if (syntax.opEscAZBufAnchor()) {
++ fetchTokenFor_anchor(AnchorType.END_BUF);
++ }
+ break;
+ case 'G':
+- if (syntax.opEscCapitalGBeginAnchor()) fetchTokenFor_anchor(AnchorType.BEGIN_POSITION);
++ if (syntax.opEscCapitalGBeginAnchor()) {
++ fetchTokenFor_anchor(AnchorType.BEGIN_POSITION);
++ }
+ break;
+ case '`':
+- if (syntax.op2EscGnuBufAnchor()) fetchTokenFor_anchor(AnchorType.BEGIN_BUF);
++ if (syntax.op2EscGnuBufAnchor()) {
++ fetchTokenFor_anchor(AnchorType.BEGIN_BUF);
++ }
+ break;
+ case '\'':
+- if (syntax.op2EscGnuBufAnchor()) fetchTokenFor_anchor(AnchorType.END_BUF);
++ if (syntax.op2EscGnuBufAnchor()) {
++ fetchTokenFor_anchor(AnchorType.END_BUF);
++ }
+ break;
+ case 'x':
+ fetchTokenFor_xBrace();
+@@ -659,7 +721,7 @@
+
+ default:
+ unfetch();
+- int num = fetchEscapedValue();
++ final int num = fetchEscapedValue();
+
+ /* set_raw: */
+ if (token.getC() != num) {
+@@ -684,22 +746,34 @@
+ {
+ switch(c) {
+ case '.':
+- if (syntax.opDotAnyChar()) token.type = TokenType.ANYCHAR;
++ if (syntax.opDotAnyChar()) {
++ token.type = TokenType.ANYCHAR;
++ }
+ break;
+ case '*':
+- if (syntax.opAsteriskZeroInf()) fetchTokenFor_repeat(0, QuantifierNode.REPEAT_INFINITE);
++ if (syntax.opAsteriskZeroInf()) {
++ fetchTokenFor_repeat(0, QuantifierNode.REPEAT_INFINITE);
++ }
+ break;
+ case '+':
+- if (syntax.opPlusOneInf()) fetchTokenFor_repeat(1, QuantifierNode.REPEAT_INFINITE);
++ if (syntax.opPlusOneInf()) {
++ fetchTokenFor_repeat(1, QuantifierNode.REPEAT_INFINITE);
++ }
+ break;
+ case '?':
+- if (syntax.opQMarkZeroOne()) fetchTokenFor_repeat(0, 1);
++ if (syntax.opQMarkZeroOne()) {
++ fetchTokenFor_repeat(0, 1);
++ }
+ break;
+ case '{':
+- if (syntax.opBraceInterval()) fetchTokenFor_openBrace();
++ if (syntax.opBraceInterval()) {
++ fetchTokenFor_openBrace();
++ }
+ break;
+ case '|':
+- if (syntax.opVBarAlt()) token.type = TokenType.ALT;
++ if (syntax.opVBarAlt()) {
++ token.type = TokenType.ALT;
++ }
+ break;
+
+ case '(':
+@@ -713,9 +787,13 @@
+ }
+ fetch();
+ if (c == syntax.metaCharTable.esc) {
+- if (left()) fetch();
++ if (left()) {
++ fetch();
++ }
+ } else {
+- if (c == ')') break;
++ if (c == ')') {
++ break;
++ }
+ }
+ }
+ continue start; // goto start
+@@ -723,19 +801,29 @@
+ unfetch();
+ }
+
+- if (syntax.opLParenSubexp()) token.type = TokenType.SUBEXP_OPEN;
++ if (syntax.opLParenSubexp()) {
++ token.type = TokenType.SUBEXP_OPEN;
++ }
+ break;
+ case ')':
+- if (syntax.opLParenSubexp()) token.type = TokenType.SUBEXP_CLOSE;
++ if (syntax.opLParenSubexp()) {
++ token.type = TokenType.SUBEXP_CLOSE;
++ }
+ break;
+ case '^':
+- if (syntax.opLineAnchor()) fetchTokenFor_anchor(isSingleline(env.option) ? AnchorType.BEGIN_BUF : AnchorType.BEGIN_LINE);
++ if (syntax.opLineAnchor()) {
++ fetchTokenFor_anchor(isSingleline(env.option) ? AnchorType.BEGIN_BUF : AnchorType.BEGIN_LINE);
++ }
+ break;
+ case '$':
+- if (syntax.opLineAnchor()) fetchTokenFor_anchor(isSingleline(env.option) ? AnchorType.END_BUF : AnchorType.END_LINE);
++ if (syntax.opLineAnchor()) {
++ fetchTokenFor_anchor(isSingleline(env.option) ? AnchorType.END_BUF : AnchorType.END_LINE);
++ }
+ break;
+ case '[':
+- if (syntax.opBracketCC()) token.type = TokenType.CC_CC_OPEN;
++ if (syntax.opBracketCC()) {
++ token.type = TokenType.CC_CC_OPEN;
++ }
+ break;
+ case ']':
+ //if (*src > env->pattern) /* /].../ is allowed. */
+@@ -745,7 +833,9 @@
+ if (Option.isExtend(env.option)) {
+ while (left()) {
+ fetch();
+- if (EncodingHelper.isNewLine(c)) break;
++ if (EncodingHelper.isNewLine(c)) {
++ break;
++ }
+ }
+ continue start; // goto start
+ }
+@@ -756,7 +846,10 @@
+ case '\n':
+ case '\r':
+ case '\f':
+- if (Option.isExtend(env.option)) continue start; // goto start
++ if (Option.isExtend(env.option))
++ {
++ continue start; // goto start
++ }
+ break;
+
+ default: // string
+@@ -798,11 +891,11 @@
+ }
+ }
+
+- protected final void syntaxWarn(String message, char c) {
+- syntaxWarn(message.replace("<%n>", Character.toString(c)));
++ protected final void syntaxWarn(final String message, final char ch) {
++ syntaxWarn(message.replace("<%n>", Character.toString(ch)));
+ }
+
+- protected final void syntaxWarn(String message) {
++ protected final void syntaxWarn(final String message) {
+ if (Config.USE_WARN) {
+ env.reg.warnings.warn(message + ": /" + new String(chars, getBegin(), getEnd()) + "/");
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Matcher.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Matcher.java Wed Feb 04 12:14:47 2015 -0800
+@@ -21,10 +21,10 @@
+ package jdk.nashorn.internal.runtime.regexp.joni;
+
+ import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindLongest;
+-
+ import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
+ import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
+
++@SuppressWarnings("javadoc")
+ public abstract class Matcher extends IntHolder {
+ protected final Regex regex;
+
+@@ -41,11 +41,11 @@
+ protected int msaBegin;
+ protected int msaEnd;
+
+- public Matcher(Regex regex, char[] chars) {
++ public Matcher(final Regex regex, final char[] chars) {
+ this(regex, chars, 0, chars.length);
+ }
+
+- public Matcher(Regex regex, char[] chars, int p, int end) {
++ public Matcher(final Regex regex, final char[] chars, final int p, final int end) {
+ this.regex = regex;
+
+ this.chars = chars;
+@@ -70,33 +70,34 @@
+ return msaEnd;
+ }
+
+- protected final void msaInit(int option, int start) {
++ protected final void msaInit(final int option, final int start) {
+ msaOptions = option;
+ msaStart = start;
+- if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) msaBestLen = -1;
++ if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) {
++ msaBestLen = -1;
++ }
+ }
+
+- public final int match(int at, int range, int option) {
++ public final int match(final int at, final int range, final int option) {
+ msaInit(option, at);
+
+- int prev = EncodingHelper.prevCharHead(str, at);
++ final int prev = EncodingHelper.prevCharHead(str, at);
+
+ if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
+ return matchAt(end /*range*/, at, prev);
+- } else {
+- return matchAt(range /*range*/, at, prev);
+ }
++ return matchAt(range /*range*/, at, prev);
+ }
+
+ int low, high; // these are the return values
+- private boolean forwardSearchRange(char[] chars, int str, int end, int s, int range, IntHolder lowPrev) {
++ private boolean forwardSearchRange(final char[] ch, final int string, final int e, final int s, final int range, final IntHolder lowPrev) {
+ int pprev = -1;
+ int p = s;
+
+ if (Config.DEBUG_SEARCH) {
+ Config.log.println("forward_search_range: "+
+- "str: " + str +
+- ", end: " + end +
++ "str: " + string +
++ ", end: " + e +
+ ", s: " + s +
+ ", range: " + range);
+ }
+@@ -106,7 +107,7 @@
+ }
+
+ retry:while (true) {
+- p = regex.searchAlgorithm.search(regex, chars, p, end, range);
++ p = regex.searchAlgorithm.search(regex, ch, p, e, range);
+
+ if (p != -1 && p < range) {
+ if (p - regex.dMin < s) {
+@@ -119,9 +120,9 @@
+ if (regex.subAnchor != 0) {
+ switch (regex.subAnchor) {
+ case AnchorType.BEGIN_LINE:
+- if (p != str) {
+- int prev = EncodingHelper.prevCharHead((pprev != -1) ? pprev : str, p);
+- if (!EncodingHelper.isNewLine(chars, prev, end)) {
++ if (p != string) {
++ final int prev = EncodingHelper.prevCharHead((pprev != -1) ? pprev : string, p);
++ if (!EncodingHelper.isNewLine(ch, prev, e)) {
+ // goto retry_gate;
+ pprev = p;
+ p++;
+@@ -131,17 +132,17 @@
+ break;
+
+ case AnchorType.END_LINE:
+- if (p == end) {
++ if (p == e) {
+ if (!Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
+- int prev = EncodingHelper.prevCharHead((pprev != -1) ? pprev : str, p);
+- if (prev != -1 && EncodingHelper.isNewLine(chars, prev, end)) {
++ final int prev = EncodingHelper.prevCharHead((pprev != -1) ? pprev : string, p);
++ if (prev != -1 && EncodingHelper.isNewLine(ch, prev, e)) {
+ // goto retry_gate;
+ pprev = p;
+ p++;
+ continue retry;
+ }
+ }
+- } else if (!EncodingHelper.isNewLine(chars, p, end)) {
++ } else if (!EncodingHelper.isNewLine(ch, p, e)) {
+ //if () break;
+ // goto retry_gate;
+ pprev = p;
+@@ -149,6 +150,9 @@
+ continue retry;
+ }
+ break;
++
++ default:
++ break;
+ } // switch
+ }
+
+@@ -158,7 +162,7 @@
+ if (low > s) {
+ lowPrev.value = EncodingHelper.prevCharHead(s, p);
+ } else {
+- lowPrev.value = EncodingHelper.prevCharHead((pprev != -1) ? pprev : str, p);
++ lowPrev.value = EncodingHelper.prevCharHead((pprev != -1) ? pprev : string, p);
+ }
+ }
+ } else {
+@@ -172,7 +176,7 @@
+ }
+ } else {
+ if (lowPrev != null) {
+- lowPrev.value = EncodingHelper.prevCharHead((pprev != -1) ? pprev : str, low);
++ lowPrev.value = EncodingHelper.prevCharHead((pprev != -1) ? pprev : string, low);
+ }
+ }
+ }
+@@ -182,8 +186,8 @@
+
+ if (Config.DEBUG_SEARCH) {
+ Config.log.println("forward_search_range success: "+
+- "low: " + (low - str) +
+- ", high: " + (high - str) +
++ "low: " + (low - string) +
++ ", high: " + (high - string) +
+ ", dmin: " + regex.dMin +
+ ", dmax: " + regex.dMax);
+ }
+@@ -196,20 +200,21 @@
+ }
+
+ // low, high
+- private boolean backwardSearchRange(char[] chars, int str, int end, int s, int range, int adjrange) {
+- range += regex.dMin;
++ private boolean backwardSearchRange(final char[] ch, final int string, final int e, final int s, final int range, final int adjrange) {
++ int r = range;
++ r += regex.dMin;
+ int p = s;
+
+ retry:while (true) {
+- p = regex.searchAlgorithm.searchBackward(regex, chars, range, adjrange, end, p, s, range);
++ p = regex.searchAlgorithm.searchBackward(regex, ch, r, adjrange, e, p, s, r);
+
+ if (p != -1) {
+ if (regex.subAnchor != 0) {
+ switch (regex.subAnchor) {
+ case AnchorType.BEGIN_LINE:
+- if (p != str) {
+- int prev = EncodingHelper.prevCharHead(str, p);
+- if (!EncodingHelper.isNewLine(chars, prev, end)) {
++ if (p != string) {
++ final int prev = EncodingHelper.prevCharHead(string, p);
++ if (!EncodingHelper.isNewLine(ch, prev, e)) {
+ p = prev;
+ continue retry;
+ }
+@@ -217,21 +222,28 @@
+ break;
+
+ case AnchorType.END_LINE:
+- if (p == end) {
++ if (p == e) {
+ if (!Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
+- int prev = EncodingHelper.prevCharHead(adjrange, p);
+- if (prev == -1) return false;
+- if (EncodingHelper.isNewLine(chars, prev, end)) {
++ final int prev = EncodingHelper.prevCharHead(adjrange, p);
++ if (prev == -1) {
++ return false;
++ }
++ if (EncodingHelper.isNewLine(ch, prev, e)) {
+ p = prev;
+ continue retry;
+ }
+ }
+- } else if (!EncodingHelper.isNewLine(chars, p, end)) {
++ } else if (!EncodingHelper.isNewLine(ch, p, e)) {
+ p = EncodingHelper.prevCharHead(adjrange, p);
+- if (p == -1) return false;
++ if (p == -1) {
++ return false;
++ }
+ continue retry;
+ }
+ break;
++
++ default:
++ break;
+ } // switch
+ }
+
+@@ -243,48 +255,59 @@
+
+ if (Config.DEBUG_SEARCH) {
+ Config.log.println("backward_search_range: "+
+- "low: " + (low - str) +
+- ", high: " + (high - str));
++ "low: " + (low - string) +
++ ", high: " + (high - string));
+ }
+
+ return true;
+ }
+
+- if (Config.DEBUG_SEARCH) Config.log.println("backward_search_range: fail.");
++ if (Config.DEBUG_SEARCH) {
++ Config.log.println("backward_search_range: fail.");
++ }
+ return false;
+ } // while
+ }
+
+ // MATCH_AND_RETURN_CHECK
+- private boolean matchCheck(int upperRange, int s, int prev) {
++ private boolean matchCheck(final int upperRange, final int s, final int prev) {
+ if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
+ if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) {
+ //range = upperRange;
+ if (matchAt(upperRange, s, prev) != -1) {
+- if (!isFindLongest(regex.options)) return true;
++ if (!isFindLongest(regex.options)) {
++ return true;
++ }
+ }
+ } else {
+ //range = upperRange;
+- if (matchAt(upperRange, s, prev) != -1) return true;
++ if (matchAt(upperRange, s, prev) != -1) {
++ return true;
++ }
+ }
+ } else {
+ if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) {
+ if (matchAt(end, s, prev) != -1) {
+ //range = upperRange;
+- if (!isFindLongest(regex.options)) return true;
++ if (!isFindLongest(regex.options)) {
++ return true;
++ }
+ }
+ } else {
+ //range = upperRange;
+- if (matchAt(end, s, prev) != -1) return true;
++ if (matchAt(end, s, prev) != -1) {
++ return true;
++ }
+ }
+ }
+ return false;
+ }
+
+- public final int search(int start, int range, int option) {
++ public final int search(final int startp, final int rangep, final int option) {
++ int start = startp, range = rangep;
+ int s, prev;
+ int origStart = start;
+- int origRange = range;
++ final int origRange = range;
+
+ if (Config.DEBUG_SEARCH) {
+ Config.log.println("onig_search (entry point): "+
+@@ -294,7 +317,9 @@
+ ", range " + (range - str));
+ }
+
+- if (start > end || start < str) return -1;
++ if (start > end || start < str) {
++ return -1;
++ }
+
+ /* anchor optimize: resume search range */
+ if (regex.anchor != 0 && str < end) {
+@@ -311,7 +336,10 @@
+ } else if ((regex.anchor & AnchorType.BEGIN_BUF) != 0) {
+ /* search str-position only */
+ if (range > start) {
+- if (start != str) return -1; // mismatch_no_msa;
++ if (start != str)
++ {
++ return -1; // mismatch_no_msa;
++ }
+ range = str + 1;
+ } else {
+ if (range <= str) {
+@@ -324,20 +352,29 @@
+ } else if ((regex.anchor & AnchorType.END_BUF) != 0) {
+ minSemiEnd = maxSemiEnd = end;
+ // !end_buf:!
+- if (endBuf(start, range, minSemiEnd, maxSemiEnd)) return -1; // mismatch_no_msa;
++ if (endBuf(start, range, minSemiEnd, maxSemiEnd))
++ {
++ return -1; // mismatch_no_msa;
++ }
+ } else if ((regex.anchor & AnchorType.SEMI_END_BUF) != 0) {
+- int preEnd = EncodingHelper.stepBack(str, end, 1);
++ final int preEnd = EncodingHelper.stepBack(str, end, 1);
+ maxSemiEnd = end;
+ if (EncodingHelper.isNewLine(chars, preEnd, end)) {
+ minSemiEnd = preEnd;
+ if (minSemiEnd > str && start <= minSemiEnd) {
+ // !goto end_buf;!
+- if (endBuf(start, range, minSemiEnd, maxSemiEnd)) return -1; // mismatch_no_msa;
++ if (endBuf(start, range, minSemiEnd, maxSemiEnd))
++ {
++ return -1; // mismatch_no_msa;
++ }
+ }
+ } else {
+ minSemiEnd = end;
+ // !goto end_buf;!
+- if (endBuf(start, range, minSemiEnd, maxSemiEnd)) return -1; // mismatch_no_msa;
++ if (endBuf(start, range, minSemiEnd, maxSemiEnd))
++ {
++ return -1; // mismatch_no_msa;
++ }
+ }
+ } else if ((regex.anchor & AnchorType.ANYCHAR_STAR_ML) != 0) {
+ // goto !begin_position;!
+@@ -359,7 +396,9 @@
+ prev = -1;
+ msaInit(option, start);
+
+- if (matchCheck(end, s, prev)) return match(s);
++ if (matchCheck(end, s, prev)) {
++ return match(s);
++ }
+ return mismatch();
+ }
+ return -1; // goto mismatch_no_msa;
+@@ -389,49 +428,62 @@
+ schRange = end;
+ } else {
+ schRange += regex.dMax;
+- if (schRange > end) schRange = end;
++ if (schRange > end) {
++ schRange = end;
++ }
+ }
+ }
+- if ((end - start) < regex.thresholdLength) return mismatch();
++ if ((end - start) < regex.thresholdLength) {
++ return mismatch();
++ }
+
+ if (regex.dMax != MinMaxLen.INFINITE_DISTANCE) {
+ do {
+- if (!forwardSearchRange(chars, str, end, s, schRange, this)) return mismatch(); // low, high, lowPrev
++ if (!forwardSearchRange(chars, str, end, s, schRange, this)) {
++ return mismatch(); // low, high, lowPrev
++ }
+ if (s < low) {
+ s = low;
+ prev = value;
+ }
+ while (s <= high) {
+- if (matchCheck(origRange, s, prev)) return match(s); // ???
++ if (matchCheck(origRange, s, prev)) {
++ return match(s); // ???
++ }
+ prev = s;
+ s++;
+ }
+ } while (s < range);
++ }
++ /* check only. */
++ if (!forwardSearchRange(chars, str, end, s, schRange, null)) {
+ return mismatch();
++ }
+
+- } else { /* check only. */
+- if (!forwardSearchRange(chars, str, end, s, schRange, null)) return mismatch();
+-
+- if ((regex.anchor & AnchorType.ANYCHAR_STAR) != 0) {
+- do {
+- if (matchCheck(origRange, s, prev)) return match(s);
+- prev = s;
+- s++;
+- } while (s < range);
+- return mismatch();
+- }
+-
++ if ((regex.anchor & AnchorType.ANYCHAR_STAR) != 0) {
++ do {
++ if (matchCheck(origRange, s, prev)) {
++ return match(s);
++ }
++ prev = s;
++ s++;
++ } while (s < range);
++ return mismatch();
+ }
+ }
+
+ do {
+- if (matchCheck(origRange, s, prev)) return match(s);
++ if (matchCheck(origRange, s, prev)) {
++ return match(s);
++ }
+ prev = s;
+ s++;
+ } while (s < range);
+
+ if (s == range) { /* because empty match with /$/. */
+- if (matchCheck(origRange, s, prev)) return match(s);
++ if (matchCheck(origRange, s, prev)) {
++ return match(s);
++ }
+ }
+ } else { /* backward search */
+ if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
+@@ -450,37 +502,51 @@
+ if (regex.dMax != MinMaxLen.INFINITE_DISTANCE && (end - range) >= regex.thresholdLength) {
+ do {
+ int schStart = s + regex.dMax;
+- if (schStart > end) schStart = end;
+- if (!backwardSearchRange(chars, str, end, schStart, range, adjrange)) return mismatch(); // low, high
+- if (s > high) s = high;
++ if (schStart > end) {
++ schStart = end;
++ }
++ if (!backwardSearchRange(chars, str, end, schStart, range, adjrange))
++ {
++ return mismatch(); // low, high
++ }
++ if (s > high) {
++ s = high;
++ }
+ while (s != -1 && s >= low) {
+ prev = EncodingHelper.prevCharHead(str, s);
+- if (matchCheck(origStart, s, prev)) return match(s);
++ if (matchCheck(origStart, s, prev)) {
++ return match(s);
++ }
+ s = prev;
+ }
+ } while (s >= range);
+ return mismatch();
+- } else { /* check only. */
+- if ((end - range) < regex.thresholdLength) return mismatch();
++ }
++ if ((end - range) < regex.thresholdLength) {
++ return mismatch();
++ }
+
+- int schStart = s;
+- if (regex.dMax != 0) {
+- if (regex.dMax == MinMaxLen.INFINITE_DISTANCE) {
++ int schStart = s;
++ if (regex.dMax != 0) {
++ if (regex.dMax == MinMaxLen.INFINITE_DISTANCE) {
++ schStart = end;
++ } else {
++ schStart += regex.dMax;
++ if (schStart > end) {
+ schStart = end;
+- } else {
+- schStart += regex.dMax;
+- if (schStart > end) {
+- schStart = end;
+- }
+ }
+ }
+- if (!backwardSearchRange(chars, str, end, schStart, range, adjrange)) return mismatch();
++ }
++ if (!backwardSearchRange(chars, str, end, schStart, range, adjrange)) {
++ return mismatch();
+ }
+ }
+
+ do {
+ prev = EncodingHelper.prevCharHead(str, s);
+- if (matchCheck(origStart, s, prev)) return match(s);
++ if (matchCheck(origStart, s, prev)) {
++ return match(s);
++ }
+ s = prev;
+ } while (s >= range);
+
+@@ -488,8 +554,13 @@
+ return mismatch();
+ }
+
+- private boolean endBuf(int start, int range, int minSemiEnd, int maxSemiEnd) {
+- if ((maxSemiEnd - str) < regex.anchorDmin) return true; // mismatch_no_msa;
++ private boolean endBuf(final int startp, final int rangep, final int minSemiEnd, final int maxSemiEnd) {
++ int start = startp;
++ int range = rangep;
++
++ if ((maxSemiEnd - str) < regex.anchorDmin) {
++ return true; // mismatch_no_msa;
++ }
+
+ if (range > start) {
+ if ((minSemiEnd - start) > regex.anchorDmax) {
+@@ -502,7 +573,10 @@
+ if ((maxSemiEnd - (range - 1)) < regex.anchorDmin) {
+ range = maxSemiEnd - regex.anchorDmin + 1;
+ }
+- if (start >= range) return true; // mismatch_no_msa;
++ if (start >= range)
++ {
++ return true; // mismatch_no_msa;
++ }
+ } else {
+ if ((minSemiEnd - range) > regex.anchorDmax) {
+ range = minSemiEnd - regex.anchorDmax;
+@@ -510,19 +584,22 @@
+ if ((maxSemiEnd - start) < regex.anchorDmin) {
+ start = maxSemiEnd - regex.anchorDmin;
+ }
+- if (range > start) return true; // mismatch_no_msa;
++ if (range > start)
++ {
++ return true; // mismatch_no_msa;
++ }
+ }
+ return false;
+ }
+
+- private int match(int s) {
++ private int match(final int s) {
+ return s - str; // sstart ???
+ }
+
+ private int mismatch() {
+ if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) {
+ if (msaBestLen >= 0) {
+- int s = msaBestS;
++ final int s = msaBestS;
+ return match(s);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,12 +19,13 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni;
+
++@SuppressWarnings("javadoc")
+ public abstract class MatcherFactory {
+ public abstract Matcher create(Regex regex, char[] chars, int p, int end);
+
+ static final MatcherFactory DEFAULT = new MatcherFactory() {
+ @Override
+- public Matcher create(Regex regex, char[] chars, int p, int end) {
++ public Matcher create(final Regex regex, final char[] chars, final int p, final int end) {
+ return new ByteCodeMachine(regex, chars, p, end);
+ }
+ };
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/MinMaxLen.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/MinMaxLen.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,7 +26,7 @@
+ MinMaxLen() {
+ }
+
+- MinMaxLen(int min, int max) {
++ MinMaxLen(final int min, final int max) {
+ this.min = min;
+ this.max = max;
+ }
+@@ -46,32 +46,48 @@
+ };
+
+ int distanceValue() {
+- if (max == INFINITE_DISTANCE) return 0;
+- int d = max - min;
++ if (max == INFINITE_DISTANCE) {
++ return 0;
++ }
++ final int d = max - min;
+ /* return dist_vals[d] * 16 / (mm->min + 12); */
+ return d < distValues.length ? distValues[d] : 1;
+ }
+
+- int compareDistanceValue(MinMaxLen other, int v1, int v2) {
+- if (v2 <= 0) return -1;
+- if (v1 <= 0) return 1;
++ int compareDistanceValue(final MinMaxLen other, final int v1p, final int v2p) {
++ int v1 = v1p, v2 = v2p;
++
++ if (v2 <= 0) {
++ return -1;
++ }
++ if (v1 <= 0) {
++ return 1;
++ }
+
+ v1 *= distanceValue();
+ v2 *= other.distanceValue();
+
+- if (v2 > v1) return 1;
+- if (v2 < v1) return -1;
++ if (v2 > v1) {
++ return 1;
++ }
++ if (v2 < v1) {
++ return -1;
++ }
+
+- if (other.min < min) return 1;
+- if (other.min > min) return -1;
++ if (other.min < min) {
++ return 1;
++ }
++ if (other.min > min) {
++ return -1;
++ }
+ return 0;
+ }
+
+- boolean equal(MinMaxLen other) {
++ boolean equal(final MinMaxLen other) {
+ return min == other.min && max == other.max;
+ }
+
+- void set(int min, int max) {
++ void set(final int min, final int max) {
+ this.min = min;
+ this.max = max;
+ }
+@@ -80,46 +96,52 @@
+ min = max = 0;
+ }
+
+- void copy(MinMaxLen other) {
++ void copy(final MinMaxLen other) {
+ min = other.min;
+ max = other.max;
+ }
+
+- void add(MinMaxLen other) {
++ void add(final MinMaxLen other) {
+ min = distanceAdd(min, other.min);
+ max = distanceAdd(max, other.max);
+ }
+
+- void addLength(int len) {
++ void addLength(final int len) {
+ min = distanceAdd(min, len);
+ max = distanceAdd(max, len);
+ }
+
+- void altMerge(MinMaxLen other) {
+- if (min > other.min) min = other.min;
+- if (max < other.max) max = other.max;
++ void altMerge(final MinMaxLen other) {
++ if (min > other.min) {
++ min = other.min;
++ }
++ if (max < other.max) {
++ max = other.max;
++ }
+ }
+
+ static final int INFINITE_DISTANCE = 0x7FFFFFFF;
+- static int distanceAdd(int d1, int d2) {
++ static int distanceAdd(final int d1, final int d2) {
+ if (d1 == INFINITE_DISTANCE || d2 == INFINITE_DISTANCE) {
+ return INFINITE_DISTANCE;
+- } else {
+- if (d1 <= INFINITE_DISTANCE - d2) return d1 + d2;
+- else return INFINITE_DISTANCE;
+ }
++ if (d1 <= INFINITE_DISTANCE - d2) {
++ return d1 + d2;
++ }
++ return INFINITE_DISTANCE;
+ }
+
+- static int distanceMultiply(int d, int m) {
+- if (m == 0) return 0;
++ static int distanceMultiply(final int d, final int m) {
++ if (m == 0) {
++ return 0;
++ }
+ if (d < INFINITE_DISTANCE / m) {
+ return d * m;
+- } else {
+- return INFINITE_DISTANCE;
+ }
++ return INFINITE_DISTANCE;
+ }
+
+- static String distanceRangeToString(int a, int b) {
++ static String distanceRangeToString(final int a, final int b) {
+ String s = "";
+ if (a == INFINITE_DISTANCE) {
+ s += "inf";
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NodeOptInfo.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NodeOptInfo.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni;
+
++@SuppressWarnings("javadoc")
+ public final class NodeOptInfo {
+ final MinMaxLen length = new MinMaxLen();
+ final OptAnchorInfo anchor = new OptAnchorInfo();
+@@ -27,7 +28,7 @@
+ final OptExactInfo expr = new OptExactInfo(); /* prec read (?=...) */
+ final OptMapInfo map = new OptMapInfo(); /* boundary */
+
+- public void setBoundNode(MinMaxLen mmd) {
++ public void setBoundNode(final MinMaxLen mmd) {
+ exb.mmd.copy(mmd);
+ expr.mmd.copy(mmd);
+ map.mmd.copy(mmd);
+@@ -42,7 +43,7 @@
+ map.clear();
+ }
+
+- public void copy(NodeOptInfo other) {
++ public void copy(final NodeOptInfo other) {
+ length.copy(other.length);
+ anchor.copy(other.anchor);
+ exb.copy(other.exb);
+@@ -51,8 +52,8 @@
+ map.copy(other.map);
+ }
+
+- public void concatLeftNode(NodeOptInfo other) {
+- OptAnchorInfo tanchor = new OptAnchorInfo(); // remove it somehow ?
++ public void concatLeftNode(final NodeOptInfo other) {
++ final OptAnchorInfo tanchor = new OptAnchorInfo(); // remove it somehow ?
+ tanchor.concat(anchor, other.anchor, length.max, other.length.max);
+ anchor.copy(tanchor);
+
+@@ -67,8 +68,8 @@
+ }
+ }
+
+- boolean exbReach = exb.reachEnd;
+- boolean exmReach = exm.reachEnd;
++ final boolean exbReach = exb.reachEnd;
++ final boolean exmReach = exm.reachEnd;
+
+ if (other.length.max != 0) {
+ exb.reachEnd = exm.reachEnd = false;
+@@ -91,8 +92,12 @@
+ if (other.length.max > 0) {
+ // TODO: make sure it is not an Oniguruma bug (casting unsigned int to int for arithmetic comparison)
+ int otherLengthMax = other.length.max;
+- if (otherLengthMax == MinMaxLen.INFINITE_DISTANCE) otherLengthMax = -1;
+- if (expr.length > otherLengthMax) expr.length = otherLengthMax;
++ if (otherLengthMax == MinMaxLen.INFINITE_DISTANCE) {
++ otherLengthMax = -1;
++ }
++ if (expr.length > otherLengthMax) {
++ expr.length = otherLengthMax;
++ }
+ if (expr.mmd.max == 0) {
+ exb.select(expr);
+ } else {
+@@ -107,7 +112,7 @@
+ length.add(other.length);
+ }
+
+- public void altMerge(NodeOptInfo other, OptEnvironment env) {
++ public void altMerge(final NodeOptInfo other, final OptEnvironment env) {
+ anchor.altMerge(other.anchor);
+ exb.altMerge(other.exb, env);
+ exm.altMerge(other.exm, env);
+@@ -116,7 +121,7 @@
+ length.altMerge(other.length);
+ }
+
+- public void setBound(MinMaxLen mmd) {
++ public void setBound(final MinMaxLen mmd) {
+ exb.mmd.copy(mmd);
+ expr.mmd.copy(mmd);
+ map.mmd.copy(mmd);
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptAnchorInfo.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptAnchorInfo.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,25 +29,31 @@
+ leftAnchor = rightAnchor = 0;
+ }
+
+- void copy(OptAnchorInfo other) {
++ void copy(final OptAnchorInfo other) {
+ leftAnchor = other.leftAnchor;
+ rightAnchor = other.rightAnchor;
+ }
+
+- void concat(OptAnchorInfo left, OptAnchorInfo right, int leftLength, int rightLength) {
++ void concat(final OptAnchorInfo left, final OptAnchorInfo right, final int leftLength, final int rightLength) {
+ leftAnchor = left.leftAnchor;
+- if (leftLength == 0) leftAnchor |= right.leftAnchor;
++ if (leftLength == 0) {
++ leftAnchor |= right.leftAnchor;
++ }
+
+ rightAnchor = right.rightAnchor;
+- if (rightLength == 0) rightAnchor |= left.rightAnchor;
++ if (rightLength == 0) {
++ rightAnchor |= left.rightAnchor;
++ }
+ }
+
+- boolean isSet(int anchor) {
+- if ((leftAnchor & anchor) != 0) return true;
++ boolean isSet(final int anchor) {
++ if ((leftAnchor & anchor) != 0) {
++ return true;
++ }
+ return (rightAnchor & anchor) != 0;
+ }
+
+- void add(int anchor) {
++ void add(final int anchor) {
+ if (isLeftAnchor(anchor)) {
+ leftAnchor |= anchor;
+ } else {
+@@ -55,7 +61,7 @@
+ }
+ }
+
+- void remove(int anchor) {
++ void remove(final int anchor) {
+ if (isLeftAnchor(anchor)) {
+ leftAnchor &= ~anchor;
+ } else {
+@@ -63,28 +69,44 @@
+ }
+ }
+
+- void altMerge(OptAnchorInfo other) {
++ void altMerge(final OptAnchorInfo other) {
+ leftAnchor &= other.leftAnchor;
+ rightAnchor &= other.rightAnchor;
+ }
+
+- static boolean isLeftAnchor(int anchor) { // make a mask for it ?
++ static boolean isLeftAnchor(final int anchor) { // make a mask for it ?
+ return !(anchor == END_BUF || anchor == SEMI_END_BUF ||
+ anchor == END_LINE || anchor == PREC_READ ||
+ anchor == PREC_READ_NOT);
+ }
+
+- static String anchorToString(int anchor) {
+- StringBuffer s = new StringBuffer("[");
++ static String anchorToString(final int anchor) {
++ final StringBuffer s = new StringBuffer("[");
+
+- if ((anchor & AnchorType.BEGIN_BUF) !=0 ) s.append("begin-buf ");
+- if ((anchor & AnchorType.BEGIN_LINE) !=0 ) s.append("begin-line ");
+- if ((anchor & AnchorType.BEGIN_POSITION) !=0 ) s.append("begin-pos ");
+- if ((anchor & AnchorType.END_BUF) !=0 ) s.append("end-buf ");
+- if ((anchor & AnchorType.SEMI_END_BUF) !=0 ) s.append("semi-end-buf ");
+- if ((anchor & AnchorType.END_LINE) !=0 ) s.append("end-line ");
+- if ((anchor & AnchorType.ANYCHAR_STAR) !=0 ) s.append("anychar-star ");
+- if ((anchor & AnchorType.ANYCHAR_STAR_ML) !=0 ) s.append("anychar-star-pl ");
++ if ((anchor & AnchorType.BEGIN_BUF) !=0 ) {
++ s.append("begin-buf ");
++ }
++ if ((anchor & AnchorType.BEGIN_LINE) !=0 ) {
++ s.append("begin-line ");
++ }
++ if ((anchor & AnchorType.BEGIN_POSITION) !=0 ) {
++ s.append("begin-pos ");
++ }
++ if ((anchor & AnchorType.END_BUF) !=0 ) {
++ s.append("end-buf ");
++ }
++ if ((anchor & AnchorType.SEMI_END_BUF) !=0 ) {
++ s.append("semi-end-buf ");
++ }
++ if ((anchor & AnchorType.END_LINE) !=0 ) {
++ s.append("end-line ");
++ }
++ if ((anchor & AnchorType.ANYCHAR_STAR) !=0 ) {
++ s.append("anychar-star ");
++ }
++ if ((anchor & AnchorType.ANYCHAR_STAR_ML) !=0 ) {
++ s.append("anychar-star-pl ");
++ }
+ s.append("]");
+
+ return s.toString();
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptEnvironment.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptEnvironment.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,7 +26,7 @@
+ int caseFoldFlag;
+ ScanEnvironment scanEnv;
+
+- void copy(OptEnvironment other) {
++ void copy(final OptEnvironment other) {
+ mmd.copy(other.mmd);
+ options = other.options;
+ caseFoldFlag = other.caseFoldFlag;
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptExactInfo.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptExactInfo.java Wed Feb 04 12:14:47 2015 -0800
+@@ -44,7 +44,7 @@
+ length = 0;
+ }
+
+- void copy(OptExactInfo other) {
++ void copy(final OptExactInfo other) {
+ mmd.copy(other.mmd);
+ anchor.copy(other.anchor);
+ reachEnd = other.reachEnd;
+@@ -54,42 +54,51 @@
+ System.arraycopy(other.chars, 0, chars, 0, OPT_EXACT_MAXLEN);
+ }
+
+- void concat(OptExactInfo other) {
++ void concat(final OptExactInfo other) {
+ if (!ignoreCase && other.ignoreCase) {
+- if (length >= other.length) return; /* avoid */
++ if (length >= other.length) {
++ return; /* avoid */
++ }
+ ignoreCase = true;
+ }
+
+ int p = 0; // add->s;
+- int end = p + other.length;
++ final int end = p + other.length;
+
+ int i;
+ for (i = length; p < end;) {
+- if (i + 1 > OPT_EXACT_MAXLEN) break;
++ if (i + 1 > OPT_EXACT_MAXLEN) {
++ break;
++ }
+ chars[i++] = other.chars[p++];
+ }
+
+ length = i;
+ reachEnd = (p == end ? other.reachEnd : false);
+
+- OptAnchorInfo tmp = new OptAnchorInfo();
++ final OptAnchorInfo tmp = new OptAnchorInfo();
+ tmp.concat(anchor, other.anchor, 1, 1);
+- if (!other.reachEnd) tmp.rightAnchor = 0;
++ if (!other.reachEnd) {
++ tmp.rightAnchor = 0;
++ }
+ anchor.copy(tmp);
+ }
+
+ // ?? raw is not used here
+- void concatStr(char[] lchars, int p, int end, boolean raw) {
++ void concatStr(final char[] lchars, final int pp, final int end, final boolean raw) {
+ int i;
++ int p = pp;
+ for (i = length; p < end && i < OPT_EXACT_MAXLEN;) {
+- if (i + 1 > OPT_EXACT_MAXLEN) break;
++ if (i + 1 > OPT_EXACT_MAXLEN) {
++ break;
++ }
+ chars[i++] = lchars[p++];
+ }
+
+ length = i;
+ }
+
+- void altMerge(OptExactInfo other, OptEnvironment env) {
++ void altMerge(final OptExactInfo other, final OptEnvironment env) {
+ if (other.length == 0 || length == 0) {
+ clear();
+ return;
+@@ -102,21 +111,27 @@
+
+ int i;
+ for (i = 0; i < length && i < other.length; i++) {
+- if (chars[i] != other.chars[i]) break;
++ if (chars[i] != other.chars[i]) {
++ break;
++ }
+ }
+
+- if (!other.reachEnd || i<other.length || i<length) reachEnd = false;
++ if (!other.reachEnd || i<other.length || i<length) {
++ reachEnd = false;
++ }
+
+ length = i;
+ ignoreCase |= other.ignoreCase;
+
+ anchor.altMerge(other.anchor);
+
+- if (!reachEnd) anchor.rightAnchor = 0;
++ if (!reachEnd) {
++ anchor.rightAnchor = 0;
++ }
+ }
+
+
+- void select(OptExactInfo alt) {
++ void select(final OptExactInfo alt) {
+ int v1 = length;
+ int v2 = alt.length;
+
+@@ -130,23 +145,35 @@
+ v2 = OptMapInfo.positionValue(chars[0] & 0xff);
+ v1 = OptMapInfo.positionValue(alt.chars[0] & 0xff);
+
+- if (length > 1) v1 += 5;
+- if (alt.length > 1) v2 += 5;
++ if (length > 1) {
++ v1 += 5;
++ }
++ if (alt.length > 1) {
++ v2 += 5;
++ }
+ }
+
+- if (!ignoreCase) v1 *= 2;
+- if (!alt.ignoreCase) v2 *= 2;
++ if (!ignoreCase) {
++ v1 *= 2;
++ }
++ if (!alt.ignoreCase) {
++ v2 *= 2;
++ }
+
+- if (mmd.compareDistanceValue(alt.mmd, v1, v2) > 0) copy(alt);
++ if (mmd.compareDistanceValue(alt.mmd, v1, v2) > 0) {
++ copy(alt);
++ }
+ }
+
+ // comp_opt_exact_or_map_info
+ private static final int COMP_EM_BASE = 20;
+- int compare(OptMapInfo m) {
+- if (m.value <= 0) return -1;
++ int compare(final OptMapInfo m) {
++ if (m.value <= 0) {
++ return -1;
++ }
+
+- int ve = COMP_EM_BASE * length * (ignoreCase ? 1 : 2);
+- int vm = COMP_EM_BASE * 5 * 2 / m.value;
++ final int ve = COMP_EM_BASE * length * (ignoreCase ? 1 : 2);
++ final int vm = COMP_EM_BASE * 5 * 2 / m.value;
+
+ return mmd.compareDistanceValue(m.mmd, ve, vm);
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptMapInfo.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/OptMapInfo.java Wed Feb 04 12:14:47 2015 -0800
+@@ -31,10 +31,12 @@
+ mmd.clear();
+ anchor.clear();
+ value = 0;
+- for (int i=0; i<map.length; i++) map[i] = 0;
++ for (int i=0; i<map.length; i++) {
++ map[i] = 0;
++ }
+ }
+
+- void copy(OptMapInfo other) {
++ void copy(final OptMapInfo other) {
+ mmd.copy(other.mmd);
+ anchor.copy(other.anchor);
+ value = other.value;
+@@ -42,19 +44,18 @@
+ System.arraycopy(other.map, 0, map, 0, other.map.length);
+ }
+
+- void addChar(int c) {
+- int c_ = c & 0xff;
++ void addChar(final int c) {
++ final int c_ = c & 0xff;
+ if (map[c_] == 0) {
+ map[c_] = 1;
+ value += positionValue(c_);
+ }
+ }
+
+- void addCharAmb(char[] chars, int p, int end, int caseFoldFlag) {
++ void addCharAmb(final char[] chars, final int p, final int end, final int caseFoldFlag) {
+ addChar(chars[p]);
+
+- caseFoldFlag &= ~Config.INTERNAL_ENC_CASE_FOLD_MULTI_CHAR;
+- char[]items = EncodingHelper.caseFoldCodesByString(caseFoldFlag, chars[p]);
++ final char[]items = EncodingHelper.caseFoldCodesByString(caseFoldFlag & ~Config.INTERNAL_ENC_CASE_FOLD_MULTI_CHAR, chars[p]);
+
+ for (int i=0; i<items.length; i++) {
+ addChar(items[i]);
+@@ -63,23 +64,29 @@
+
+ // select_opt_map_info
+ private static final int z = 1<<15; /* 32768: something big value */
+- void select(OptMapInfo alt) {
+- if (alt.value == 0) return;
++ void select(final OptMapInfo alt) {
++ if (alt.value == 0) {
++ return;
++ }
+ if (value == 0) {
+ copy(alt);
+ return;
+ }
+
+- int v1 = z / value;
+- int v2 = z /alt.value;
++ final int v1 = z / value;
++ final int v2 = z /alt.value;
+
+- if (mmd.compareDistanceValue(alt.mmd, v1, v2) > 0) copy(alt);
++ if (mmd.compareDistanceValue(alt.mmd, v1, v2) > 0) {
++ copy(alt);
++ }
+ }
+
+ // alt_merge_opt_map_info
+- void altMerge(OptMapInfo other) {
++ void altMerge(final OptMapInfo other) {
+ /* if (! is_equal_mml(&to->mmd, &add->mmd)) return ; */
+- if (value == 0) return;
++ if (value == 0) {
++ return;
++ }
+ if (other.value == 0 || mmd.max < other.mmd.max) {
+ clear();
+ return;
+@@ -89,8 +96,12 @@
+
+ int val = 0;
+ for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) {
+- if (other.map[i] != 0) map[i] = 1;
+- if (map[i] != 0) val += positionValue(i);
++ if (other.map[i] != 0) {
++ map[i] = 1;
++ }
++ if (map[i] != 0) {
++ val += positionValue(i);
++ }
+ }
+
+ value = val;
+@@ -109,12 +120,11 @@
+ };
+
+ // map_position_value
+- static int positionValue(int i) {
++ static int positionValue(final int i) {
+ if (i < ByteValTable.length) {
+ return ByteValTable[i];
+- } else {
+- return 4; /* Take it easy. */
+ }
++ return 4; /* Take it easy. */
+ }
+
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Option.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Option.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni;
+
++@SuppressWarnings("javadoc")
+ public class Option {
+
+ /* options */
+@@ -41,74 +42,98 @@
+
+ public static final int DEFAULT = NONE;
+
+- public static String toString(int option) {
++ public static String toString(final int option) {
+ String options = "";
+- if (isIgnoreCase(option)) options += "IGNORECASE ";
+- if (isExtend(option)) options += "EXTEND ";
+- if (isMultiline(option)) options += "MULTILINE ";
+- if (isSingleline(option)) options += "SINGLELINE ";
+- if (isFindLongest(option)) options += "FIND_LONGEST ";
+- if (isFindNotEmpty(option)) options += "FIND_NOT_EMPTY ";
+- if (isNegateSingleline(option)) options += "NEGATE_SINGLELINE ";
+- if (isDontCaptureGroup(option)) options += "DONT_CAPTURE_GROUP ";
+- if (isCaptureGroup(option)) options += "CAPTURE_GROUP ";
++ if (isIgnoreCase(option)) {
++ options += "IGNORECASE ";
++ }
++ if (isExtend(option)) {
++ options += "EXTEND ";
++ }
++ if (isMultiline(option)) {
++ options += "MULTILINE ";
++ }
++ if (isSingleline(option)) {
++ options += "SINGLELINE ";
++ }
++ if (isFindLongest(option)) {
++ options += "FIND_LONGEST ";
++ }
++ if (isFindNotEmpty(option)) {
++ options += "FIND_NOT_EMPTY ";
++ }
++ if (isNegateSingleline(option)) {
++ options += "NEGATE_SINGLELINE ";
++ }
++ if (isDontCaptureGroup(option)) {
++ options += "DONT_CAPTURE_GROUP ";
++ }
++ if (isCaptureGroup(option)) {
++ options += "CAPTURE_GROUP ";
++ }
+
+- if (isNotBol(option)) options += "NOTBOL ";
+- if (isNotEol(option)) options += "NOTEOL ";
+- if (isPosixRegion(option)) options += "POSIX_REGION ";
++ if (isNotBol(option)) {
++ options += "NOTBOL ";
++ }
++ if (isNotEol(option)) {
++ options += "NOTEOL ";
++ }
++ if (isPosixRegion(option)) {
++ options += "POSIX_REGION ";
++ }
+
+ return options;
+ }
+
+- public static boolean isIgnoreCase(int option) {
++ public static boolean isIgnoreCase(final int option) {
+ return (option & IGNORECASE) != 0;
+ }
+
+- public static boolean isExtend(int option) {
++ public static boolean isExtend(final int option) {
+ return (option & EXTEND) != 0;
+ }
+
+- public static boolean isSingleline(int option) {
++ public static boolean isSingleline(final int option) {
+ return (option & SINGLELINE) != 0;
+ }
+
+- public static boolean isMultiline(int option) {
++ public static boolean isMultiline(final int option) {
+ return (option & MULTILINE) != 0;
+ }
+
+- public static boolean isFindLongest(int option) {
++ public static boolean isFindLongest(final int option) {
+ return (option & FIND_LONGEST) != 0;
+ }
+
+- public static boolean isFindNotEmpty(int option) {
++ public static boolean isFindNotEmpty(final int option) {
+ return (option & FIND_NOT_EMPTY) != 0;
+ }
+
+- public static boolean isFindCondition(int option) {
++ public static boolean isFindCondition(final int option) {
+ return (option & (FIND_LONGEST | FIND_NOT_EMPTY)) != 0;
+ }
+
+- public static boolean isNegateSingleline(int option) {
++ public static boolean isNegateSingleline(final int option) {
+ return (option & NEGATE_SINGLELINE) != 0;
+ }
+
+- public static boolean isDontCaptureGroup(int option) {
++ public static boolean isDontCaptureGroup(final int option) {
+ return (option & DONT_CAPTURE_GROUP) != 0;
+ }
+
+- public static boolean isCaptureGroup(int option) {
++ public static boolean isCaptureGroup(final int option) {
+ return (option & CAPTURE_GROUP) != 0;
+ }
+
+- public static boolean isNotBol(int option) {
++ public static boolean isNotBol(final int option) {
+ return (option & NOTBOL) != 0;
+ }
+
+- public static boolean isNotEol(int option) {
++ public static boolean isNotEol(final int option) {
+ return (option & NOTEOL) != 0;
+ }
+
+- public static boolean isPosixRegion(int option) {
++ public static boolean isPosixRegion(final int option) {
+ return (option & POSIX_REGION) != 0;
+ }
+
+@@ -116,7 +141,7 @@
+ // public static boolean isDynamic(int option) {
+ // return (option & (MULTILINE | IGNORECASE)) != 0;
+ // }
+- public static boolean isDynamic(int option) {
++ public static boolean isDynamic(final int option) {
+ return false;
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java Wed Feb 04 12:14:47 2015 -0800
+@@ -22,7 +22,6 @@
+ import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnOff;
+ import static jdk.nashorn.internal.runtime.regexp.joni.Option.isDontCaptureGroup;
+ import static jdk.nashorn.internal.runtime.regexp.joni.Option.isIgnoreCase;
+-
+ import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
+ import jdk.nashorn.internal.runtime.regexp.joni.ast.AnyCharNode;
+ import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
+@@ -52,7 +51,7 @@
+ protected int returnCode; // return code used by parser methods (they itself return parsed nodes)
+ // this approach will not affect recursive calls
+
+- protected Parser(ScanEnvironment env, char[] chars, int p, int end) {
++ protected Parser(final ScanEnvironment env, final char[] chars, final int p, final int end) {
+ super(env, chars, p, end);
+ regex = env.reg;
+ }
+@@ -64,7 +63,7 @@
+ return root;
+ }
+
+- private boolean codeExistCheck(int code, boolean ignoreEscaped) {
++ private boolean codeExistCheck(final int code, final boolean ignoreEscaped) {
+ mark();
+
+ boolean inEsc = false;
+@@ -77,7 +76,9 @@
+ restore();
+ return true;
+ }
+- if (c == syntax.metaCharTable.esc) inEsc = true;
++ if (c == syntax.metaCharTable.esc) {
++ inEsc = true;
++ }
+ }
+ }
+
+@@ -108,7 +109,7 @@
+ CClassNode prevCC = null;
+ CClassNode workCC = null;
+
+- CCStateArg arg = new CCStateArg();
++ final CCStateArg arg = new CCStateArg();
+
+ boolean andStart = false;
+ arg.state = CCSTATE.START;
+@@ -165,7 +166,9 @@
+ arg.vIsRaw = false;
+ fetchTokenInCC();
+ fetched = true;
+- if (token.type == TokenType.CC_RANGE || andStart) env.ccEscWarn("-"); /* [--x] or [a&&-x] is warned. */
++ if (token.type == TokenType.CC_RANGE || andStart) {
++ env.ccEscWarn("-"); /* [--x] or [a&&-x] is warned. */
++ }
+ parseCharClassValEntry(cc, arg); // goto val_entry
+ break;
+ } else if (arg.state == CCSTATE.RANGE) {
+@@ -197,7 +200,7 @@
+ break;
+
+ case CC_CC_OPEN: /* [ */
+- CClassNode acc = parseCharClass();
++ final CClassNode acc = parseCharClass();
+ cc.or(acc);
+ break;
+
+@@ -214,7 +217,9 @@
+ prevCC.and(cc);
+ } else {
+ prevCC = cc;
+- if (workCC == null) workCC = new CClassNode();
++ if (workCC == null) {
++ workCC = new CClassNode();
++ }
+ cc = workCC;
+ }
+ cc.clear();
+@@ -227,7 +232,9 @@
+ throw new InternalException(ERR_PARSER_BUG);
+ } // switch
+
+- if (!fetched) fetchTokenInCC();
++ if (!fetched) {
++ fetchTokenInCC();
++ }
+
+ } // while
+
+@@ -260,29 +267,29 @@
+ return cc;
+ }
+
+- private void parseCharClassSbChar(CClassNode cc, CCStateArg arg) {
++ private void parseCharClassSbChar(final CClassNode cc, final CCStateArg arg) {
+ arg.inType = CCVALTYPE.SB;
+ arg.v = token.getC();
+ arg.vIsRaw = false;
+ parseCharClassValEntry2(cc, arg); // goto val_entry2
+ }
+
+- private void parseCharClassRangeEndVal(CClassNode cc, CCStateArg arg) {
++ private void parseCharClassRangeEndVal(final CClassNode cc, final CCStateArg arg) {
+ arg.v = '-';
+ arg.vIsRaw = false;
+ parseCharClassValEntry(cc, arg); // goto val_entry
+ }
+
+- private void parseCharClassValEntry(CClassNode cc, CCStateArg arg) {
++ private void parseCharClassValEntry(final CClassNode cc, final CCStateArg arg) {
+ arg.inType = arg.v <= 0xff ? CCVALTYPE.SB : CCVALTYPE.CODE_POINT;
+ parseCharClassValEntry2(cc, arg); // val_entry2:
+ }
+
+- private void parseCharClassValEntry2(CClassNode cc, CCStateArg arg) {
++ private void parseCharClassValEntry2(final CClassNode cc, final CCStateArg arg) {
+ cc.nextStateValue(arg, env);
+ }
+
+- private Node parseEnclose(TokenType term) {
++ private Node parseEnclose(final TokenType term) {
+ Node node = null;
+
+ if (!left()) {
+@@ -327,8 +334,8 @@
+ break;
+ case '@':
+ if (syntax.op2AtMarkCaptureHistory()) {
+- EncloseNode en = new EncloseNode(); // node_new_enclose_memory
+- int num = env.addMemEntry();
++ final EncloseNode en = new EncloseNode(); // node_new_enclose_memory
++ final int num = env.addMemEntry();
+ if (num >= BitStatus.BIT_STATUS_BITS_NUM) {
+ throw new ValueException(ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY);
+ }
+@@ -385,17 +392,17 @@
+ } // switch
+
+ if (c == ')') {
+- EncloseNode en = new EncloseNode(option, 0); // node_new_option
++ final EncloseNode en = new EncloseNode(option, 0); // node_new_option
+ node = en;
+ returnCode = 2; /* option only */
+ return node;
+ } else if (c == ':') {
+- int prev = env.option;
++ final int prev = env.option;
+ env.option = option;
+ fetchToken();
+- Node target = parseSubExp(term);
++ final Node target = parseSubExp(term);
+ env.option = prev;
+- EncloseNode en = new EncloseNode(option, 0); // node_new_option
++ final EncloseNode en = new EncloseNode(option, 0); // node_new_option
+ en.setTarget(target);
+ node = en;
+ returnCode = 0;
+@@ -418,20 +425,20 @@
+ returnCode = 1; /* group */
+ return node;
+ }
+- EncloseNode en = new EncloseNode(); // node_new_enclose_memory
+- int num = env.addMemEntry();
++ final EncloseNode en = new EncloseNode(); // node_new_enclose_memory
++ final int num = env.addMemEntry();
+ en.regNum = num;
+ node = en;
+ }
+
+ fetchToken();
+- Node target = parseSubExp(term);
++ final Node target = parseSubExp(term);
+
+ if (node.getType() == NodeType.ANCHOR) {
+- AnchorNode an = (AnchorNode) node;
++ final AnchorNode an = (AnchorNode) node;
+ an.setTarget(target);
+ } else {
+- EncloseNode en = (EncloseNode)node;
++ final EncloseNode en = (EncloseNode)node;
+ en.setTarget(target);
+ if (en.type == EncloseType.MEMORY) {
+ /* Don't move this to previous of parse_subexp() */
+@@ -442,8 +449,11 @@
+ return node; // ??
+ }
+
+- private Node parseExp(TokenType term) {
+- if (token.type == term) return StringNode.EMPTY; // goto end_of_token
++ private Node parseExp(final TokenType term) {
++ if (token.type == term)
++ {
++ return StringNode.EMPTY; // goto end_of_token
++ }
+
+ Node node = null;
+ boolean group = false;
+@@ -458,11 +468,11 @@
+ if (returnCode == 1) {
+ group = true;
+ } else if (returnCode == 2) { /* option only */
+- int prev = env.option;
+- EncloseNode en = (EncloseNode)node;
++ final int prev = env.option;
++ final EncloseNode en = (EncloseNode)node;
+ env.option = en.option;
+ fetchToken();
+- Node target = parseSubExp(term);
++ final Node target = parseSubExp(term);
+ env.option = prev;
+ en.setTarget(target);
+ return node;
+@@ -474,16 +484,15 @@
+ }
+ if (token.escaped) {
+ return parseExpTkRawByte(group); // goto tk_raw_byte
+- } else {
+- return parseExpTkByte(group); // goto tk_byte
+ }
++ return parseExpTkByte(group); // goto tk_byte
+ case STRING:
+ return parseExpTkByte(group); // tk_byte:
+
+ case RAW_BYTE:
+ return parseExpTkRawByte(group); // tk_raw_byte:
+ case CODE_POINT:
+- char[] buf = new char[] {(char)token.getCode()};
++ final char[] buf = new char[] {(char)token.getCode()};
+ // #ifdef NUMBERED_CHAR_IS_NOT_CASE_AMBIG ... // setRaw() #else
+ node = new StringNode(buf, 0, 1);
+ break;
+@@ -494,9 +503,11 @@
+ case CharacterType.S:
+ case CharacterType.W:
+ if (Config.NON_UNICODE_SDW) {
+- CClassNode cc = new CClassNode();
++ final CClassNode cc = new CClassNode();
+ cc.addCType(token.getPropCType(), false, env, this);
+- if (token.getPropNot()) cc.setNot();
++ if (token.getPropNot()) {
++ cc.setNot();
++ }
+ node = cc;
+ }
+ break;
+@@ -505,9 +516,11 @@
+ case CharacterType.DIGIT:
+ case CharacterType.XDIGIT:
+ // #ifdef USE_SHARED_CCLASS_TABLE ... #endif
+- CClassNode ccn = new CClassNode();
++ final CClassNode ccn = new CClassNode();
+ ccn.addCType(token.getPropCType(), false, env, this);
+- if (token.getPropNot()) ccn.setNot();
++ if (token.getPropNot()) {
++ ccn.setNot();
++ }
+ node = ccn;
+ break;
+
+@@ -518,10 +531,10 @@
+ break;
+
+ case CC_CC_OPEN:
+- CClassNode cc = parseCharClass();
++ final CClassNode cc = parseCharClass();
+ node = cc;
+ if (isIgnoreCase(env.option)) {
+- ApplyCaseFoldArg arg = new ApplyCaseFoldArg(env, cc);
++ final ApplyCaseFoldArg arg = new ApplyCaseFoldArg(env, cc);
+ EncodingHelper.applyAllCaseFold(env.caseFoldFlag, ApplyCaseFold.INSTANCE, arg);
+
+ if (arg.altRoot != null) {
+@@ -536,13 +549,13 @@
+
+ case ANYCHAR_ANYTIME:
+ node = new AnyCharNode();
+- QuantifierNode qn = new QuantifierNode(0, QuantifierNode.REPEAT_INFINITE, false);
++ final QuantifierNode qn = new QuantifierNode(0, QuantifierNode.REPEAT_INFINITE, false);
+ qn.setTarget(node);
+ node = qn;
+ break;
+
+ case BACKREF:
+- int backRef = token.getBackrefRef();
++ final int backRef = token.getBackrefRef();
+ node = new BackRefNode(backRef, env);
+ break;
+
+@@ -555,9 +568,8 @@
+ if (syntax.contextIndepRepeatOps()) {
+ if (syntax.contextInvalidRepeatOps()) {
+ throw new SyntaxException(ERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED);
+- } else {
+- node = StringNode.EMPTY; // node_new_empty
+ }
++ node = StringNode.EMPTY; // node_new_empty
+ } else {
+ return parseExpTkByte(group); // goto tk_byte
+ }
+@@ -574,11 +586,13 @@
+ return parseExpRepeat(node, group); // repeat:
+ }
+
+- private Node parseExpTkByte(boolean group) {
+- StringNode node = new StringNode(chars, token.backP, p); // tk_byte:
++ private Node parseExpTkByte(final boolean group) {
++ final StringNode node = new StringNode(chars, token.backP, p); // tk_byte:
+ while (true) {
+ fetchToken();
+- if (token.type != TokenType.STRING) break;
++ if (token.type != TokenType.STRING) {
++ break;
++ }
+
+ if (token.backP == node.end) {
+ node.end = p; // non escaped character, remain shared, just increase shared range
+@@ -590,13 +604,13 @@
+ return parseExpRepeat(node, group); // string_end:, goto repeat
+ }
+
+- private Node parseExpTkRawByte(boolean group) {
++ private Node parseExpTkRawByte(final boolean group) {
+ // tk_raw_byte:
+
+ // important: we don't use 0xff mask here neither in the compiler
+ // (in the template string) so we won't have to mask target
+ // strings when comparing against them in the matcher
+- StringNode node = new StringNode((char)token.getC());
++ final StringNode node = new StringNode((char)token.getC());
+ node.setRaw();
+
+ fetchToken();
+@@ -605,22 +619,23 @@
+ return parseExpRepeat(node, group);
+ }
+
+- private Node parseExpRepeat(Node target, boolean group) {
++ private Node parseExpRepeat(final Node targetp, final boolean group) {
++ Node target = targetp;
+ while (token.type == TokenType.OP_REPEAT || token.type == TokenType.INTERVAL) { // repeat:
+ if (target.isInvalidQuantifier()) {
+ throw new SyntaxException(ERR_TARGET_OF_REPEAT_OPERATOR_INVALID);
+ }
+
+- QuantifierNode qtfr = new QuantifierNode(token.getRepeatLower(),
++ final QuantifierNode qtfr = new QuantifierNode(token.getRepeatLower(),
+ token.getRepeatUpper(),
+ token.type == TokenType.INTERVAL);
+
+ qtfr.greedy = token.getRepeatGreedy();
+- int ret = qtfr.setQuantifier(target, group, env, chars, getBegin(), getEnd());
++ final int ret = qtfr.setQuantifier(target, group, env, chars, getBegin(), getEnd());
+ Node qn = qtfr;
+
+ if (token.getRepeatPossessive()) {
+- EncloseNode en = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
++ final EncloseNode en = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
+ en.setTarget(qn);
+ qn = en;
+ }
+@@ -629,7 +644,7 @@
+ target = qn;
+ } else if (ret == 2) { /* split case: /abc+/ */
+ target = ConsAltNode.newListNode(target, null);
+- ConsAltNode tmp = ((ConsAltNode)target).setCdr(ConsAltNode.newListNode(qn, null));
++ final ConsAltNode tmp = ((ConsAltNode)target).setCdr(ConsAltNode.newListNode(qn, null));
+
+ fetchToken();
+ return parseExpRepeatForCar(target, tmp, group);
+@@ -639,22 +654,22 @@
+ return target;
+ }
+
+- private Node parseExpRepeatForCar(Node top, ConsAltNode target, boolean group) {
++ private Node parseExpRepeatForCar(final Node top, final ConsAltNode target, final boolean group) {
+ while (token.type == TokenType.OP_REPEAT || token.type == TokenType.INTERVAL) { // repeat:
+ if (target.car.isInvalidQuantifier()) {
+ throw new SyntaxException(ERR_TARGET_OF_REPEAT_OPERATOR_INVALID);
+ }
+
+- QuantifierNode qtfr = new QuantifierNode(token.getRepeatLower(),
++ final QuantifierNode qtfr = new QuantifierNode(token.getRepeatLower(),
+ token.getRepeatUpper(),
+ token.type == TokenType.INTERVAL);
+
+ qtfr.greedy = token.getRepeatGreedy();
+- int ret = qtfr.setQuantifier(target.car, group, env, chars, getBegin(), getEnd());
++ final int ret = qtfr.setQuantifier(target.car, group, env, chars, getBegin(), getEnd());
+ Node qn = qtfr;
+
+ if (token.getRepeatPossessive()) {
+- EncloseNode en = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
++ final EncloseNode en = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
+ en.setTarget(qn);
+ qn = en;
+ }
+@@ -669,39 +684,40 @@
+ return top;
+ }
+
+- private Node parseBranch(TokenType term) {
++ private Node parseBranch(final TokenType term) {
+ Node node = parseExp(term);
+
+ if (token.type == TokenType.EOT || token.type == term || token.type == TokenType.ALT) {
+ return node;
+- } else {
+- ConsAltNode top = ConsAltNode.newListNode(node, null);
+- ConsAltNode t = top;
++ }
++ final ConsAltNode top = ConsAltNode.newListNode(node, null);
++ ConsAltNode t = top;
+
+- while (token.type != TokenType.EOT && token.type != term && token.type != TokenType.ALT) {
+- node = parseExp(term);
+- if (node.getType() == NodeType.LIST) {
+- t.setCdr((ConsAltNode)node);
+- while (((ConsAltNode)node).cdr != null ) node = ((ConsAltNode)node).cdr;
++ while (token.type != TokenType.EOT && token.type != term && token.type != TokenType.ALT) {
++ node = parseExp(term);
++ if (node.getType() == NodeType.LIST) {
++ t.setCdr((ConsAltNode)node);
++ while (((ConsAltNode)node).cdr != null ) {
++ node = ((ConsAltNode)node).cdr;
++ }
+
+- t = ((ConsAltNode)node);
+- } else {
+- t.setCdr(ConsAltNode.newListNode(node, null));
+- t = t.cdr;
+- }
++ t = ((ConsAltNode)node);
++ } else {
++ t.setCdr(ConsAltNode.newListNode(node, null));
++ t = t.cdr;
+ }
+- return top;
+ }
++ return top;
+ }
+
+ /* term_tok: TK_EOT or TK_SUBEXP_CLOSE */
+- private Node parseSubExp(TokenType term) {
++ private Node parseSubExp(final TokenType term) {
+ Node node = parseBranch(term);
+
+ if (token.type == term) {
+ return node;
+ } else if (token.type == TokenType.ALT) {
+- ConsAltNode top = ConsAltNode.newAltNode(node, null);
++ final ConsAltNode top = ConsAltNode.newAltNode(node, null);
+ ConsAltNode t = top;
+ while (token.type == TokenType.ALT) {
+ fetchToken();
+@@ -711,7 +727,9 @@
+ t = t.cdr;
+ }
+
+- if (token.type != term) parseSubExpError(term);
++ if (token.type != term) {
++ parseSubExpError(term);
++ }
+ return top;
+ } else {
+ parseSubExpError(term);
+@@ -719,12 +737,11 @@
+ }
+ }
+
+- private void parseSubExpError(TokenType term) {
++ private static void parseSubExpError(final TokenType term) {
+ if (term == TokenType.SUBEXP_CLOSE) {
+ throw new SyntaxException(ERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS);
+- } else {
+- throw new InternalException(ERR_PARSER_BUG);
+ }
++ throw new InternalException(ERR_PARSER_BUG);
+ }
+
+ private Node parseRegexp() {
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Regex.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Regex.java Wed Feb 04 12:14:47 2015 -0800
+@@ -24,6 +24,7 @@
+ import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+ import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
+
++@SuppressWarnings("javadoc")
+ public final class Regex implements RegexState {
+
+ int[] code; /* compiled pattern */
+@@ -72,42 +73,43 @@
+ char[][] templates;
+ int templateNum;
+
+- public Regex(CharSequence cs) {
++ public Regex(final CharSequence cs) {
+ this(cs.toString());
+ }
+
+- public Regex(String str) {
++ public Regex(final String str) {
+ this(str.toCharArray(), 0, str.length(), 0);
+ }
+
+- public Regex(char[] chars) {
++ public Regex(final char[] chars) {
+ this(chars, 0, chars.length, 0);
+ }
+
+- public Regex(char[] chars, int p, int end) {
++ public Regex(final char[] chars, final int p, final int end) {
+ this(chars, p, end, 0);
+ }
+
+- public Regex(char[] chars, int p, int end, int option) {
++ public Regex(final char[] chars, final int p, final int end, final int option) {
+ this(chars, p, end, option, Syntax.RUBY, WarnCallback.DEFAULT);
+ }
+
+ // onig_new
+- public Regex(char[] chars, int p, int end, int option, Syntax syntax) {
++ public Regex(final char[] chars, final int p, final int end, final int option, final Syntax syntax) {
+ this(chars, p, end, option, Config.ENC_CASE_FOLD_DEFAULT, syntax, WarnCallback.DEFAULT);
+ }
+
+- public Regex(char[]chars, int p, int end, int option, WarnCallback warnings) {
++ public Regex(final char[]chars, final int p, final int end, final int option, final WarnCallback warnings) {
+ this(chars, p, end, option, Syntax.RUBY, warnings);
+ }
+
+ // onig_new
+- public Regex(char[] chars, int p, int end, int option, Syntax syntax, WarnCallback warnings) {
++ public Regex(final char[] chars, final int p, final int end, final int option, final Syntax syntax, final WarnCallback warnings) {
+ this(chars, p, end, option, Config.ENC_CASE_FOLD_DEFAULT, syntax, warnings);
+ }
+
+ // onig_alloc_init
+- public Regex(char[] chars, int p, int end, int option, int caseFoldFlag, Syntax syntax, WarnCallback warnings) {
++ public Regex(final char[] chars, final int p, final int end, final int optionp, final int caseFoldFlag, final Syntax syntax, final WarnCallback warnings) {
++ int option = optionp;
+
+ if ((option & (Option.DONT_CAPTURE_GROUP | Option.CAPTURE_GROUP)) ==
+ (Option.DONT_CAPTURE_GROUP | Option.CAPTURE_GROUP)) {
+@@ -140,11 +142,11 @@
+ return factory;
+ }
+
+- public Matcher matcher(char[] chars) {
++ public Matcher matcher(final char[] chars) {
+ return matcher(chars, 0, chars.length);
+ }
+
+- public Matcher matcher(char[] chars, int p, int end) {
++ public Matcher matcher(final char[] chars, final int p, final int end) {
+ MatcherFactory matcherFactory = factory;
+ if (matcherFactory == null) {
+ matcherFactory = compile();
+@@ -162,26 +164,40 @@
+
+ /* set skip map for Boyer-Moor search */
+ void setupBMSkipMap() {
+- char[] chars = exact;
+- int p = exactP;
+- int end = exactEnd;
+- int len = end - p;
++ final char[] chars = exact;
++ final int p = exactP;
++ final int end = exactEnd;
++ final int len = end - p;
+
+ if (len < Config.CHAR_TABLE_SIZE) {
+ // map/skip
+- if (map == null) map = new byte[Config.CHAR_TABLE_SIZE];
++ if (map == null) {
++ map = new byte[Config.CHAR_TABLE_SIZE];
++ }
+
+- for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) map[i] = (byte)len;
+- for (int i=0; i<len-1; i++) map[chars[p + i] & 0xff] = (byte)(len - 1 -i); // oxff ??
++ for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) {
++ map[i] = (byte)len;
++ }
++ for (int i=0; i<len-1; i++)
++ {
++ map[chars[p + i] & 0xff] = (byte)(len - 1 -i); // oxff ??
++ }
+ } else {
+- if (intMap == null) intMap = new int[Config.CHAR_TABLE_SIZE];
++ if (intMap == null) {
++ intMap = new int[Config.CHAR_TABLE_SIZE];
++ }
+
+- for (int i=0; i<len-1; i++) intMap[chars[p + i] & 0xff] = len - 1 - i; // oxff ??
++ for (int i=0; i<len-1; i++)
++ {
++ intMap[chars[p + i] & 0xff] = len - 1 - i; // oxff ??
++ }
+ }
+ }
+
+- void setExactInfo(OptExactInfo e) {
+- if (e.length == 0) return;
++ void setExactInfo(final OptExactInfo e) {
++ if (e.length == 0) {
++ return;
++ }
+
+ // shall we copy that ?
+ exact = e.chars;
+@@ -207,7 +223,7 @@
+ }
+ }
+
+- void setOptimizeMapInfo(OptMapInfo m) {
++ void setOptimizeMapInfo(final OptMapInfo m) {
+ map = m.map;
+
+ searchAlgorithm = SearchAlgorithm.MAP;
+@@ -219,7 +235,7 @@
+ }
+ }
+
+- void setSubAnchor(OptAnchorInfo anc) {
++ void setSubAnchor(final OptAnchorInfo anc) {
+ subAnchor |= anc.leftAnchor & AnchorType.BEGIN_LINE;
+ subAnchor |= anc.rightAnchor & AnchorType.END_LINE;
+ }
+@@ -236,7 +252,7 @@
+ }
+
+ public String optimizeInfoToString() {
+- StringBuilder s = new StringBuilder();
++ final StringBuilder s = new StringBuilder();
+ s.append("optimize: ").append(searchAlgorithm.getName()).append("\n");
+ s.append(" anchor: ").append(OptAnchorInfo.anchorToString(anchor));
+
+@@ -257,7 +273,11 @@
+ s.append("exact: [").append(exact, exactP, exactEnd - exactP).append("]: length: ").append(exactEnd - exactP).append("\n");
+ } else if (searchAlgorithm == SearchAlgorithm.MAP) {
+ int n=0;
+- for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) if (map[i] != 0) n++;
++ for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) {
++ if (map[i] != 0) {
++ n++;
++ }
++ }
+
+ s.append("map: n = ").append(n).append("\n");
+ if (n > 0) {
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Region.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Region.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni;
+
++@SuppressWarnings("javadoc")
+ public final class Region {
+ static final int REGION_NOTPOS = -1;
+
+@@ -26,7 +27,7 @@
+ public final int[]beg;
+ public final int[]end;
+
+- public Region(int num) {
++ public Region(final int num) {
+ this.numRegs = num;
+ this.beg = new int[num];
+ this.end = new int[num];
+@@ -34,9 +35,11 @@
+
+ @Override
+ public String toString() {
+- StringBuilder sb = new StringBuilder();
++ final StringBuilder sb = new StringBuilder();
+ sb.append("Region: \n");
+- for (int i=0; i<beg.length; i++) sb.append(" " + i + ": (" + beg[i] + "-" + end[i] + ")");
++ for (int i=0; i<beg.length; i++) {
++ sb.append(" " + i + ": (" + beg[i] + "-" + end[i] + ")");
++ }
+ return sb.toString();
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ScanEnvironment.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ScanEnvironment.java Wed Feb 04 12:14:47 2015 -0800
+@@ -20,11 +20,11 @@
+ package jdk.nashorn.internal.runtime.regexp.joni;
+
+ import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsClear;
+-
+ import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
+ import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+ import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
+
++@SuppressWarnings("javadoc")
+ public final class ScanEnvironment {
+
+ private static final int SCANENV_MEMNODES_SIZE = 8;
+@@ -44,7 +44,7 @@
+ public Node memNodes[];
+
+
+- public ScanEnvironment(Regex regex, Syntax syntax) {
++ public ScanEnvironment(final Regex regex, final Syntax syntax) {
+ this.reg = regex;
+ option = regex.options;
+ caseFoldFlag = regex.caseFoldFlag;
+@@ -65,7 +65,7 @@
+ if (numMem++ == 0) {
+ memNodes = new Node[SCANENV_MEMNODES_SIZE];
+ } else if (numMem >= memNodes.length) {
+- Node[]tmp = new Node[memNodes.length << 1];
++ final Node[]tmp = new Node[memNodes.length << 1];
+ System.arraycopy(memNodes, 0, tmp, 0, memNodes.length);
+ memNodes = tmp;
+ }
+@@ -73,7 +73,7 @@
+ return numMem;
+ }
+
+- public void setMemNode(int num, Node node) {
++ public void setMemNode(final int num, final Node node) {
+ if (numMem >= num) {
+ memNodes[num] = node;
+ } else {
+@@ -81,7 +81,7 @@
+ }
+ }
+
+- public int convertBackslashValue(int c) {
++ public int convertBackslashValue(final int c) {
+ if (syntax.opEscControlChars()) {
+ switch (c) {
+ case 'n': return '\n';
+@@ -92,7 +92,10 @@
+ case 'b': return '\010';
+ case 'e': return '\033';
+ case 'v':
+- if (syntax.op2EscVVtab()) return 11; // ???
++ if (syntax.op2EscVVtab())
++ {
++ return 11; // ???
++ }
+ break;
+ default:
+ break;
+@@ -101,7 +104,7 @@
+ return c;
+ }
+
+- void ccEscWarn(String s) {
++ void ccEscWarn(final String s) {
+ if (Config.USE_WARN) {
+ if (syntax.warnCCOpNotEscaped() && syntax.backSlashEscapeInCC()) {
+ reg.warnings.warn("character class has '" + s + "' without escape");
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ScannerSupport.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ScannerSupport.java Wed Feb 04 12:14:47 2015 -0800
+@@ -36,7 +36,7 @@
+
+ private final static int INT_SIGN_BIT = 1 << 31;
+
+- protected ScannerSupport(char[] chars, int p, int end) {
++ protected ScannerSupport(final char[] chars, final int p, final int end) {
+ this.chars = chars;
+ this.begin = p;
+ this.end = end;
+@@ -53,14 +53,16 @@
+ }
+
+ protected final int scanUnsignedNumber() {
+- int last = c;
++ final int last = c;
+ int num = 0; // long ???
+ while(left()) {
+ fetch();
+ if (Character.isDigit(c)) {
+- int onum = num;
++ final int onum = num;
+ num = num * 10 + EncodingHelper.digitVal(c);
+- if (((onum ^ num) & INT_SIGN_BIT) != 0) return -1;
++ if (((onum ^ num) & INT_SIGN_BIT) != 0) {
++ return -1;
++ }
+ } else {
+ unfetch();
+ break;
+@@ -70,16 +72,19 @@
+ return num;
+ }
+
+- protected final int scanUnsignedHexadecimalNumber(int maxLength) {
+- int last = c;
++ protected final int scanUnsignedHexadecimalNumber(final int maxLength) {
++ final int last = c;
+ int num = 0;
+- while(left() && maxLength-- != 0) {
++ int ml = maxLength;
++ while(left() && ml-- != 0) {
+ fetch();
+ if (EncodingHelper.isXDigit(c)) {
+- int onum = num;
+- int val = EncodingHelper.xdigitVal(c);
++ final int onum = num;
++ final int val = EncodingHelper.xdigitVal(c);
+ num = (num << 4) + val;
+- if (((onum ^ num) & INT_SIGN_BIT) != 0) return -1;
++ if (((onum ^ num) & INT_SIGN_BIT) != 0) {
++ return -1;
++ }
+ } else {
+ unfetch();
+ break;
+@@ -89,16 +94,19 @@
+ return num;
+ }
+
+- protected final int scanUnsignedOctalNumber(int maxLength) {
+- int last = c;
++ protected final int scanUnsignedOctalNumber(final int maxLength) {
++ final int last = c;
+ int num = 0;
+- while(left() && maxLength-- != 0) {
++ int ml = maxLength;
++ while(left() && ml-- != 0) {
+ fetch();
+ if (Character.isDigit(c) && c < '8') {
+- int onum = num;
+- int val = EncodingHelper.odigitVal(c);
++ final int onum = num;
++ final int val = EncodingHelper.odigitVal(c);
+ num = (num << 3) + val;
+- if (((onum ^ num) & INT_SIGN_BIT) != 0) return -1;
++ if (((onum ^ num) & INT_SIGN_BIT) != 0) {
++ return -1;
++ }
+ } else {
+ unfetch();
+ break;
+@@ -144,8 +152,8 @@
+ return p < stop ? chars[p] : 0;
+ }
+
+- protected final boolean peekIs(int c) {
+- return peek() == c;
++ protected final boolean peekIs(final int ch) {
++ return peek() == ch;
+ }
+
+ protected final boolean left() {
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni;
+
++@SuppressWarnings("javadoc")
+ public abstract class SearchAlgorithm {
+
+ public abstract String getName();
+@@ -34,12 +35,12 @@
+ }
+
+ @Override
+- public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
++ public final int search(final Regex regex, final char[] text, final int textP, final int textEnd, final int textRange) {
+ return textP;
+ }
+
+ @Override
+- public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
++ public final int searchBackward(final Regex regex, final char[] text, final int textP, final int adjustText, final int textEnd, final int textStart, final int s_, final int range_) {
+ return textP;
+ }
+
+@@ -53,16 +54,18 @@
+ }
+
+ @Override
+- public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
+- char[] target = regex.exact;
+- int targetP = regex.exactP;
+- int targetEnd = regex.exactEnd;
++ public final int search(final Regex regex, final char[] text, final int textP, final int textEnd, final int textRange) {
++ final char[] target = regex.exact;
++ final int targetP = regex.exactP;
++ final int targetEnd = regex.exactEnd;
+
+
+ int end = textEnd;
+ end -= targetEnd - targetP - 1;
+
+- if (end > textRange) end = textRange;
++ if (end > textRange) {
++ end = textRange;
++ }
+
+ int s = textP;
+
+@@ -71,11 +74,15 @@
+ int p = s + 1;
+ int t = targetP + 1;
+ while (t < targetEnd) {
+- if (target[t] != text[p++]) break;
++ if (target[t] != text[p++]) {
++ break;
++ }
+ t++;
+ }
+
+- if (t == targetEnd) return s;
++ if (t == targetEnd) {
++ return s;
++ }
+ }
+ s++;
+ }
+@@ -84,10 +91,10 @@
+ }
+
+ @Override
+- public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
+- char[] target = regex.exact;
+- int targetP = regex.exactP;
+- int targetEnd = regex.exactEnd;
++ public final int searchBackward(final Regex regex, final char[] text, final int textP, final int adjustText, final int textEnd, final int textStart, final int s_, final int range_) {
++ final char[] target = regex.exact;
++ final int targetP = regex.exactP;
++ final int targetEnd = regex.exactEnd;
+
+ int s = textEnd;
+ s -= targetEnd - targetP;
+@@ -101,10 +108,14 @@
+ int p = s + 1;
+ int t = targetP + 1;
+ while (t < targetEnd) {
+- if (target[t] != text[p++]) break;
++ if (target[t] != text[p++]) {
++ break;
++ }
+ t++;
+ }
+- if (t == targetEnd) return s;
++ if (t == targetEnd) {
++ return s;
++ }
+ }
+ // s = enc.prevCharHead or s = s <= adjustText ? -1 : s - 1;
+ s--;
+@@ -114,10 +125,8 @@
+ };
+
+ public static final class SLOW_IC extends SearchAlgorithm {
+- private final int caseFoldFlag;
+-
+- public SLOW_IC(Regex regex) {
+- this.caseFoldFlag = regex.caseFoldFlag;
++ public SLOW_IC(final Regex regex) {
++ //empty
+ }
+
+ @Override
+@@ -126,29 +135,33 @@
+ }
+
+ @Override
+- public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
+- char[] target = regex.exact;
+- int targetP = regex.exactP;
+- int targetEnd = regex.exactEnd;
++ public final int search(final Regex regex, final char[] text, final int textP, final int textEnd, final int textRange) {
++ final char[] target = regex.exact;
++ final int targetP = regex.exactP;
++ final int targetEnd = regex.exactEnd;
+
+ int end = textEnd;
+ end -= targetEnd - targetP - 1;
+
+- if (end > textRange) end = textRange;
++ if (end > textRange) {
++ end = textRange;
++ }
+ int s = textP;
+
+ while (s < end) {
+- if (lowerCaseMatch(target, targetP, targetEnd, text, s, textEnd)) return s;
++ if (lowerCaseMatch(target, targetP, targetEnd, text, s, textEnd)) {
++ return s;
++ }
+ s++;
+ }
+ return -1;
+ }
+
+ @Override
+- public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
+- char[] target = regex.exact;
+- int targetP = regex.exactP;
+- int targetEnd = regex.exactEnd;
++ public final int searchBackward(final Regex regex, final char[] text, final int textP, final int adjustText, final int textEnd, final int textStart, final int s_, final int range_) {
++ final char[] target = regex.exact;
++ final int targetP = regex.exactP;
++ final int targetEnd = regex.exactEnd;
+
+ int s = textEnd;
+ s -= targetEnd - targetP;
+@@ -158,17 +171,21 @@
+ }
+
+ while (s >= textP) {
+- if (lowerCaseMatch(target, targetP, targetEnd, text, s, textEnd)) return s;
++ if (lowerCaseMatch(target, targetP, targetEnd, text, s, textEnd)) {
++ return s;
++ }
+ s = EncodingHelper.prevCharHead(adjustText, s);
+ }
+ return -1;
+ }
+
+- private boolean lowerCaseMatch(char[] t, int tP, int tEnd,
+- char[] chars, int p, int end) {
++ private static boolean lowerCaseMatch(final char[] t, final int tPp, final int tEnd,
++ final char[] chars, final int pp, final int end) {
+
+- while (tP < tEnd) {
+- if (t[tP++] != EncodingHelper.toLowerCase(chars[p++])) return false;
++ for (int tP = tPp, p = pp; tP < tEnd; ) {
++ if (t[tP++] != EncodingHelper.toLowerCase(chars[p++])) {
++ return false;
++ }
+ }
+ return true;
+ }
+@@ -182,15 +199,17 @@
+ }
+
+ @Override
+- public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
+- char[] target = regex.exact;
+- int targetP = regex.exactP;
+- int targetEnd = regex.exactEnd;
++ public final int search(final Regex regex, final char[] text, final int textP, final int textEnd, final int textRange) {
++ final char[] target = regex.exact;
++ final int targetP = regex.exactP;
++ final int targetEnd = regex.exactEnd;
+
+ int end = textRange + (targetEnd - targetP) - 1;
+- if (end > textEnd) end = textEnd;
++ if (end > textEnd) {
++ end = textEnd;
++ }
+
+- int tail = targetEnd - 1;
++ final int tail = targetEnd - 1;
+ int s = textP + (targetEnd - targetP) - 1;
+
+ if (regex.intMap == null) {
+@@ -199,7 +218,9 @@
+ int t = tail;
+
+ while (text[p] == target[t]) {
+- if (t == targetP) return p;
++ if (t == targetP) {
++ return p;
++ }
+ p--; t--;
+ }
+
+@@ -211,7 +232,9 @@
+ int t = tail;
+
+ while (text[p] == target[t]) {
+- if (t == targetP) return p;
++ if (t == targetP) {
++ return p;
++ }
+ p--; t--;
+ }
+
+@@ -224,10 +247,10 @@
+ private static final int BM_BACKWARD_SEARCH_LENGTH_THRESHOLD = 100;
+
+ @Override
+- public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
+- char[] target = regex.exact;
+- int targetP = regex.exactP;
+- int targetEnd = regex.exactEnd;
++ public final int searchBackward(final Regex regex, final char[] text, final int textP, final int adjustText, final int textEnd, final int textStart, final int s_, final int range_) {
++ final char[] target = regex.exact;
++ final int targetP = regex.exactP;
++ final int targetEnd = regex.exactEnd;
+
+ if (regex.intMapBackward == null) {
+ if (s_ - range_ < BM_BACKWARD_SEARCH_LENGTH_THRESHOLD) {
+@@ -249,7 +272,9 @@
+ while (t < targetEnd && text[p] == target[t]) {
+ p++; t++;
+ }
+- if (t == targetEnd) return s;
++ if (t == targetEnd) {
++ return s;
++ }
+
+ s -= regex.intMapBackward[text[s] & 0xff];
+ }
+@@ -257,7 +282,7 @@
+ }
+
+
+- private void setBmBackwardSkip(Regex regex, char[] chars, int p, int end) {
++ private void setBmBackwardSkip(final Regex regex, final char[] chars, final int p, final int end) {
+ int[] skip;
+ if (regex.intMapBackward == null) {
+ skip = new int[Config.CHAR_TABLE_SIZE];
+@@ -266,10 +291,14 @@
+ skip = regex.intMapBackward;
+ }
+
+- int len = end - p;
++ final int len = end - p;
+
+- for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) skip[i] = len;
+- for (int i=len-1; i>0; i--) skip[chars[i] & 0xff] = i;
++ for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) {
++ skip[i] = len;
++ }
++ for (int i=len-1; i>0; i--) {
++ skip[chars[i] & 0xff] = i;
++ }
+ }
+ };
+
+@@ -281,25 +310,31 @@
+ }
+
+ @Override
+- public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
+- byte[] map = regex.map;
++ public final int search(final Regex regex, final char[] text, final int textP, final int textEnd, final int textRange) {
++ final byte[] map = regex.map;
+ int s = textP;
+
+ while (s < textRange) {
+- if (text[s] > 0xff || map[text[s]] != 0) return s;
++ if (text[s] > 0xff || map[text[s]] != 0) {
++ return s;
++ }
+ s++;
+ }
+ return -1;
+ }
+
+ @Override
+- public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
+- byte[] map = regex.map;
++ public final int searchBackward(final Regex regex, final char[] text, final int textP, final int adjustText, final int textEnd, final int textStart, final int s_, final int range_) {
++ final byte[] map = regex.map;
+ int s = textStart;
+
+- if (s >= textEnd) s = textEnd - 1;
++ if (s >= textEnd) {
++ s = textEnd - 1;
++ }
+ while (s >= textP) {
+- if (text[s] > 0xff || map[text[s]] != 0) return s;
++ if (text[s] > 0xff || map[text[s]] != 0) {
++ return s;
++ }
+ s--;
+ }
+ return -1;
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/StackEntry.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/StackEntry.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,28 +25,28 @@
+
+ // first union member
+ /* byte code position */
+- void setStatePCode(int pcode) {
++ void setStatePCode(final int pcode) {
+ E1 = pcode;
+ }
+ int getStatePCode() {
+ return E1;
+ }
+ /* string position */
+- void setStatePStr(int pstr) {
++ void setStatePStr(final int pstr) {
+ E2 = pstr;
+ }
+ int getStatePStr() {
+ return E2;
+ }
+ /* previous char position of pstr */
+- void setStatePStrPrev(int pstrPrev) {
++ void setStatePStrPrev(final int pstrPrev) {
+ E3 = pstrPrev;
+ }
+ int getStatePStrPrev() {
+ return E3;
+ }
+
+- void setStateCheck(int check) {
++ void setStateCheck(final int check) {
+ E4 = check;
+ }
+ int getStateCheck() {
+@@ -55,7 +55,7 @@
+
+ // second union member
+ /* for OP_REPEAT_INC, OP_REPEAT_INC_NG */
+- void setRepeatCount(int count) {
++ void setRepeatCount(final int count) {
+ E1 = count;
+ }
+ int getRepeatCount() {
+@@ -68,14 +68,14 @@
+ E1++;
+ }
+ /* byte code position (head of repeated target) */
+- void setRepeatPCode(int pcode) {
++ void setRepeatPCode(final int pcode) {
+ E2 = pcode;
+ }
+ int getRepeatPCode() {
+ return E2;
+ }
+ /* repeat id */
+- void setRepeatNum(int num) {
++ void setRepeatNum(final int num) {
+ E3 = num;
+ }
+ int getRepeatNum() {
+@@ -84,7 +84,7 @@
+
+ // third union member
+ /* index of stack */ /*int repeat_inc struct*/
+- void setSi(int si) {
++ void setSi(final int si) {
+ E1 = si;
+ }
+ int getSi() {
+@@ -93,14 +93,14 @@
+
+ // fourth union member
+ /* memory num */
+- void setMemNum(int num) {
++ void setMemNum(final int num) {
+ E1 = num;
+ }
+ int getMemNum() {
+ return E1;
+ }
+ /* start/end position */
+- void setMemPstr(int pstr) {
++ void setMemPstr(final int pstr) {
+ E2 = pstr;
+ }
+ int getMemPStr() {
+@@ -109,14 +109,14 @@
+
+ /* Following information is set, if this stack type is MEM-START */
+ /* prev. info (for backtrack "(...)*" ) */
+- void setMemStart(int start) {
++ void setMemStart(final int start) {
+ E3 = start;
+ }
+ int getMemStart() {
+ return E3;
+ }
+ /* prev. info (for backtrack "(...)*" ) */
+- void setMemEnd(int end) {
++ void setMemEnd(final int end) {
+ E4 = end;
+ }
+ int getMemEnd() {
+@@ -125,14 +125,14 @@
+
+ // fifth union member
+ /* null check id */
+- void setNullCheckNum(int num) {
++ void setNullCheckNum(final int num) {
+ E1 = num;
+ }
+ int getNullCheckNum() {
+ return E1;
+ }
+ /* start position */
+- void setNullCheckPStr(int pstr) {
++ void setNullCheckPStr(final int pstr) {
+ E2 = pstr;
+ }
+ int getNullCheckPStr() {
+@@ -141,21 +141,21 @@
+
+ // sixth union member
+ /* byte code position */
+- void setCallFrameRetAddr(int addr) {
++ void setCallFrameRetAddr(final int addr) {
+ E1 = addr;
+ }
+ int getCallFrameRetAddr() {
+ return E1;
+ }
+ /* null check id */
+- void setCallFrameNum(int num) {
++ void setCallFrameNum(final int num) {
+ E2 = num;
+ }
+ int getCallFrameNum() {
+ return E2;
+ }
+ /* string position */
+- void setCallFramePStr(int pstr) {
++ void setCallFramePStr(final int pstr) {
+ E3 = pstr;
+ }
+ int getCallFramePStr() {
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/StackMachine.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/StackMachine.java Wed Feb 04 12:14:47 2015 -0800
+@@ -20,9 +20,7 @@
+ package jdk.nashorn.internal.runtime.regexp.joni;
+
+ import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
+-
+ import java.lang.ref.WeakReference;
+-
+ import jdk.nashorn.internal.runtime.regexp.joni.constants.StackPopLevel;
+ import jdk.nashorn.internal.runtime.regexp.joni.constants.StackType;
+
+@@ -35,11 +33,11 @@
+ protected final int[]repeatStk;
+ protected final int memStartStk, memEndStk;
+
+- protected StackMachine(Regex regex, char[] chars, int p , int end) {
++ protected StackMachine(final Regex regex, final char[] chars, final int p , final int end) {
+ super(regex, chars, p, end);
+
+ this.stack = regex.stackNeeded ? fetchStack() : null;
+- int n = regex.numRepeat + (regex.numMem << 1);
++ final int n = regex.numRepeat + (regex.numMem << 1);
+ this.repeatStk = n > 0 ? new int[n] : null;
+
+ memStartStk = regex.numRepeat - 1;
+@@ -49,25 +47,27 @@
+ }
+
+ private static StackEntry[] allocateStack() {
+- StackEntry[]stack = new StackEntry[Config.INIT_MATCH_STACK_SIZE];
++ final StackEntry[]stack = new StackEntry[Config.INIT_MATCH_STACK_SIZE];
+ stack[0] = new StackEntry();
+ return stack;
+ }
+
+ private void doubleStack() {
+- StackEntry[] newStack = new StackEntry[stack.length << 1];
++ final StackEntry[] newStack = new StackEntry[stack.length << 1];
+ System.arraycopy(stack, 0, newStack, 0, stack.length);
+ stack = newStack;
+ }
+
+ static final ThreadLocal<WeakReference<StackEntry[]>> stacks
+ = new ThreadLocal<WeakReference<StackEntry[]>>() {
++ @SuppressWarnings("unused")
+ @Override
+ protected WeakReference<StackEntry[]> initialValue() {
+ return new WeakReference<StackEntry[]>(allocateStack());
+ }
+ };
+
++ @SuppressWarnings("unused")
+ private static StackEntry[] fetchStack() {
+ WeakReference<StackEntry[]> ref = stacks.get();
+ StackEntry[] stack = ref.get();
+@@ -79,7 +79,9 @@
+ }
+
+ protected final void init() {
+- if (stack != null) pushEnsured(ALT, regex.codeLength - 1); /* bottom stack */
++ if (stack != null) {
++ pushEnsured(ALT, regex.codeLength - 1); /* bottom stack */
++ }
+ if (repeatStk != null) {
+ for (int i=1; i<=regex.numMem; i++) {
+ repeatStk[i + memStartStk] = repeatStk[i + memEndStk] = INVALID_INDEX;
+@@ -88,19 +90,23 @@
+ }
+
+ protected final StackEntry ensure1() {
+- if (stk >= stack.length) doubleStack();
++ if (stk >= stack.length) {
++ doubleStack();
++ }
+ StackEntry e = stack[stk];
+- if (e == null) stack[stk] = e = new StackEntry();
++ if (e == null) {
++ stack[stk] = e = new StackEntry();
++ }
+ return e;
+ }
+
+- protected final void pushType(int type) {
++ protected final void pushType(final int type) {
+ ensure1().type = type;
+ stk++;
+ }
+
+- private void push(int type, int pat, int s, int prev) {
+- StackEntry e = ensure1();
++ private void push(final int type, final int pat, final int s, final int prev) {
++ final StackEntry e = ensure1();
+ e.type = type;
+ e.setStatePCode(pat);
+ e.setStatePStr(s);
+@@ -108,22 +114,22 @@
+ stk++;
+ }
+
+- protected final void pushEnsured(int type, int pat) {
+- StackEntry e = stack[stk];
++ protected final void pushEnsured(final int type, final int pat) {
++ final StackEntry e = stack[stk];
+ e.type = type;
+ e.setStatePCode(pat);
+ stk++;
+ }
+
+- protected final void pushAlt(int pat, int s, int prev) {
++ protected final void pushAlt(final int pat, final int s, final int prev) {
+ push(ALT, pat, s, prev);
+ }
+
+- protected final void pushPos(int s, int prev) {
++ protected final void pushPos(final int s, final int prev) {
+ push(POS, -1 /*NULL_UCHARP*/, s, prev);
+ }
+
+- protected final void pushPosNot(int pat, int s, int prev) {
++ protected final void pushPosNot(final int pat, final int s, final int prev) {
+ push(POS_NOT, pat, s, prev);
+ }
+
+@@ -131,12 +137,12 @@
+ pushType(STOP_BT);
+ }
+
+- protected final void pushLookBehindNot(int pat, int s, int sprev) {
++ protected final void pushLookBehindNot(final int pat, final int s, final int sprev) {
+ push(LOOK_BEHIND_NOT, pat, s, sprev);
+ }
+
+- protected final void pushRepeat(int id, int pat) {
+- StackEntry e = ensure1();
++ protected final void pushRepeat(final int id, final int pat) {
++ final StackEntry e = ensure1();
+ e.type = REPEAT;
+ e.setRepeatNum(id);
+ e.setRepeatPCode(pat);
+@@ -144,15 +150,15 @@
+ stk++;
+ }
+
+- protected final void pushRepeatInc(int sindex) {
+- StackEntry e = ensure1();
++ protected final void pushRepeatInc(final int sindex) {
++ final StackEntry e = ensure1();
+ e.type = REPEAT_INC;
+ e.setSi(sindex);
+ stk++;
+ }
+
+- protected final void pushMemStart(int mnum, int s) {
+- StackEntry e = ensure1();
++ protected final void pushMemStart(final int mnum, final int s) {
++ final StackEntry e = ensure1();
+ e.type = MEM_START;
+ e.setMemNum(mnum);
+ e.setMemPstr(s);
+@@ -163,8 +169,8 @@
+ stk++;
+ }
+
+- protected final void pushMemEnd(int mnum, int s) {
+- StackEntry e = ensure1();
++ protected final void pushMemEnd(final int mnum, final int s) {
++ final StackEntry e = ensure1();
+ e.type = MEM_END;
+ e.setMemNum(mnum);
+ e.setMemPstr(s);
+@@ -174,40 +180,42 @@
+ stk++;
+ }
+
+- protected final void pushMemEndMark(int mnum) {
+- StackEntry e = ensure1();
++ protected final void pushMemEndMark(final int mnum) {
++ final StackEntry e = ensure1();
+ e.type = MEM_END_MARK;
+ e.setMemNum(mnum);
+ stk++;
+ }
+
+- protected final int getMemStart(int mnum) {
++ protected final int getMemStart(final int mnum) {
+ int level = 0;
+ int stkp = stk;
+
+ while (stkp > 0) {
+ stkp--;
+- StackEntry e = stack[stkp];
++ final StackEntry e = stack[stkp];
+ if ((e.type & MASK_MEM_END_OR_MARK) != 0 && e.getMemNum() == mnum) {
+ level++;
+ } else if (e.type == MEM_START && e.getMemNum() == mnum) {
+- if (level == 0) break;
++ if (level == 0) {
++ break;
++ }
+ level--;
+ }
+ }
+ return stkp;
+ }
+
+- protected final void pushNullCheckStart(int cnum, int s) {
+- StackEntry e = ensure1();
++ protected final void pushNullCheckStart(final int cnum, final int s) {
++ final StackEntry e = ensure1();
+ e.type = NULL_CHECK_START;
+ e.setNullCheckNum(cnum);
+ e.setNullCheckPStr(s);
+ stk++;
+ }
+
+- protected final void pushNullCheckEnd(int cnum) {
+- StackEntry e = ensure1();
++ protected final void pushNullCheckEnd(final int cnum) {
++ final StackEntry e = ensure1();
+ e.type = NULL_CHECK_END;
+ e.setNullCheckNum(cnum);
+ stk++;
+@@ -233,7 +241,7 @@
+
+ private StackEntry popFree() {
+ while (true) {
+- StackEntry e = stack[--stk];
++ final StackEntry e = stack[--stk];
+
+ if ((e.type & MASK_POP_USED) != 0) {
+ return e;
+@@ -243,7 +251,7 @@
+
+ private StackEntry popMemStart() {
+ while (true) {
+- StackEntry e = stack[--stk];
++ final StackEntry e = stack[--stk];
+
+ if ((e.type & MASK_POP_USED) != 0) {
+ return e;
+@@ -256,7 +264,7 @@
+
+ private StackEntry popDefault() {
+ while (true) {
+- StackEntry e = stack[--stk];
++ final StackEntry e = stack[--stk];
+
+ if ((e.type & MASK_POP_USED) != 0) {
+ return e;
+@@ -277,7 +285,7 @@
+ protected final void popTilPosNot() {
+ while (true) {
+ stk--;
+- StackEntry e = stack[stk];
++ final StackEntry e = stack[stk];
+
+ if (e.type == POS_NOT) {
+ break;
+@@ -298,7 +306,7 @@
+ protected final void popTilLookBehindNot() {
+ while (true) {
+ stk--;
+- StackEntry e = stack[stk];
++ final StackEntry e = stack[stk];
+
+ if (e.type == LOOK_BEHIND_NOT) {
+ break;
+@@ -320,7 +328,7 @@
+ int k = stk;
+ while (true) {
+ k--;
+- StackEntry e = stack[k];
++ final StackEntry e = stack[k];
+ if ((e.type & MASK_TO_VOID_TARGET) != 0) {
+ e.type = VOID;
+ } else if (e.type == POS) {
+@@ -335,7 +343,7 @@
+ int k = stk;
+ while (true) {
+ k--;
+- StackEntry e = stack[k];
++ final StackEntry e = stack[k];
+
+ if ((e.type & MASK_TO_VOID_TARGET) != 0) {
+ e.type = VOID;
+@@ -347,11 +355,11 @@
+ }
+
+ // int for consistency with other null check routines
+- protected final int nullCheck(int id, int s) {
++ protected final int nullCheck(final int id, final int s) {
+ int k = stk;
+ while (true) {
+ k--;
+- StackEntry e = stack[k];
++ final StackEntry e = stack[k];
+
+ if (e.type == NULL_CHECK_START) {
+ if (e.getNullCheckNum() == id) {
+@@ -361,20 +369,19 @@
+ }
+ }
+
+- protected final int nullCheckRec(int id, int s) {
++ protected final int nullCheckRec(final int id, final int s) {
+ int level = 0;
+ int k = stk;
+ while (true) {
+ k--;
+- StackEntry e = stack[k];
++ final StackEntry e = stack[k];
+
+ if (e.type == NULL_CHECK_START) {
+ if (e.getNullCheckNum() == id) {
+ if (level == 0) {
+ return e.getNullCheckPStr() == s ? 1 : 0;
+- } else {
+- level--;
+ }
++ level--;
+ }
+ } else if (e.type == NULL_CHECK_END) {
+ level++;
+@@ -382,7 +389,7 @@
+ }
+ }
+
+- protected final int nullCheckMemSt(int id, int s) {
++ protected final int nullCheckMemSt(final int id, final int s) {
+ int k = stk;
+ int isNull;
+ while (true) {
+@@ -394,7 +401,52 @@
+ if (e.getNullCheckPStr() != s) {
+ isNull = 0;
+ break;
+- } else {
++ }
++ int endp;
++ isNull = 1;
++ while (k < stk) {
++ if (e.type == MEM_START) {
++ if (e.getMemEnd() == INVALID_INDEX) {
++ isNull = 0;
++ break;
++ }
++ if (bsAt(regex.btMemEnd, e.getMemNum())) {
++ endp = stack[e.getMemEnd()].getMemPStr();
++ } else {
++ endp = e.getMemEnd();
++ }
++ if (stack[e.getMemStart()].getMemPStr() != endp) {
++ isNull = 0;
++ break;
++ } else if (endp != s) {
++ isNull = -1; /* empty, but position changed */
++ }
++ }
++ k++;
++ e = stack[k]; // !!
++ }
++ break;
++ }
++ }
++ }
++ return isNull;
++ }
++
++ protected final int nullCheckMemStRec(final int id, final int s) {
++ int level = 0;
++ int k = stk;
++ int isNull;
++ while (true) {
++ k--;
++ StackEntry e = stack[k];
++
++ if (e.type == NULL_CHECK_START) {
++ if (e.getNullCheckNum() == id) {
++ if (level == 0) {
++ if (e.getNullCheckPStr() != s) {
++ isNull = 0;
++ break;
++ }
+ int endp;
+ isNull = 1;
+ while (k < stk) {
+@@ -416,77 +468,33 @@
+ }
+ }
+ k++;
+- e = stack[k]; // !!
++ e = stack[k];
+ }
+ break;
+ }
++ level--;
++ }
++ } else if (e.type == NULL_CHECK_END) {
++ if (e.getNullCheckNum() == id) {
++ level++;
+ }
+ }
+ }
+ return isNull;
+ }
+
+- protected final int nullCheckMemStRec(int id, int s) {
+- int level = 0;
+- int k = stk;
+- int isNull;
+- while (true) {
+- k--;
+- StackEntry e = stack[k];
+-
+- if (e.type == NULL_CHECK_START) {
+- if (e.getNullCheckNum() == id) {
+- if (level == 0) {
+- if (e.getNullCheckPStr() != s) {
+- isNull = 0;
+- break;
+- } else {
+- int endp;
+- isNull = 1;
+- while (k < stk) {
+- if (e.type == MEM_START) {
+- if (e.getMemEnd() == INVALID_INDEX) {
+- isNull = 0;
+- break;
+- }
+- if (bsAt(regex.btMemEnd, e.getMemNum())) {
+- endp = stack[e.getMemEnd()].getMemPStr();
+- } else {
+- endp = e.getMemEnd();
+- }
+- if (stack[e.getMemStart()].getMemPStr() != endp) {
+- isNull = 0;
+- break;
+- } else if (endp != s) {
+- isNull = -1; /* empty, but position changed */
+- }
+- }
+- k++;
+- e = stack[k];
+- }
+- break;
+- }
+- } else {
+- level--;
+- }
+- }
+- } else if (e.type == NULL_CHECK_END) {
+- if (e.getNullCheckNum() == id) level++;
+- }
+- }
+- return isNull;
+- }
+-
+- protected final int getRepeat(int id) {
++ protected final int getRepeat(final int id) {
+ int level = 0;
+ int k = stk;
+ while (true) {
+ k--;
+- StackEntry e = stack[k];
++ final StackEntry e = stack[k];
+
+ if (e.type == REPEAT) {
+ if (level == 0) {
+- if (e.getRepeatNum() == id) return k;
++ if (e.getRepeatNum() == id) {
++ return k;
++ }
+ }
+ } else if (e.type == CALL_FRAME) {
+ level--;
+@@ -501,14 +509,13 @@
+ int k = stk;
+ while (true) {
+ k--;
+- StackEntry e = stack[k];
++ final StackEntry e = stack[k];
+
+ if (e.type == CALL_FRAME) {
+ if (level == 0) {
+ return e.getCallFrameRetAddr();
+- } else {
+- level--;
+ }
++ level--;
+ } else if (e.type == RETURN) {
+ level++;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Syntax.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Syntax.java Wed Feb 04 12:14:47 2015 -0800
+@@ -20,17 +20,17 @@
+ package jdk.nashorn.internal.runtime.regexp.joni;
+
+ import static jdk.nashorn.internal.runtime.regexp.joni.constants.MetaChar.INEFFECTIVE_META_CHAR;
+-
+ import jdk.nashorn.internal.runtime.regexp.joni.constants.SyntaxProperties;
+
+-public final class Syntax implements SyntaxProperties{
++@SuppressWarnings("javadoc")
++public final class Syntax implements SyntaxProperties {
+ private final int op;
+ private final int op2;
+ private final int behavior;
+ public final int options;
+ public final MetaCharTable metaCharTable;
+
+- public Syntax(int op, int op2, int behavior, int options, MetaCharTable metaCharTable) {
++ public Syntax(final int op, final int op2, final int behavior, final int options, final MetaCharTable metaCharTable) {
+ this.op = op;
+ this.op2 = op2;
+ this.behavior = behavior;
+@@ -46,8 +46,8 @@
+ public final int oneOrMoreTime;
+ public final int anyCharAnyTime;
+
+- public MetaCharTable(int esc, int anyChar, int anyTime,
+- int zeroOrOneTime, int oneOrMoreTime, int anyCharAnyTime) {
++ public MetaCharTable(final int esc, final int anyChar, final int anyTime,
++ final int zeroOrOneTime, final int oneOrMoreTime, final int anyCharAnyTime) {
+ this.esc = esc;
+ this.anyChar = anyChar;
+ this.anyTime = anyTime;
+@@ -61,7 +61,7 @@
+ * OP
+ *
+ */
+- protected boolean isOp(int opm) {
++ protected boolean isOp(final int opm) {
+ return (op & opm) != 0;
+ }
+
+@@ -194,7 +194,7 @@
+ * OP
+ *
+ */
+- protected boolean isOp2(int opm) {
++ protected boolean isOp2(final int opm) {
+ return (op2 & opm) != 0;
+ }
+
+@@ -282,7 +282,7 @@
+ * BEHAVIOR
+ *
+ */
+- protected boolean isBehavior(int bvm) {
++ protected boolean isBehavior(final int bvm) {
+ return (behavior & bvm) != 0;
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Token.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Token.java Wed Feb 04 12:14:47 2015 -0800
+@@ -33,21 +33,21 @@
+ int getC() {
+ return INT1;
+ }
+- void setC(int c) {
++ void setC(final int c) {
+ INT1 = c;
+ }
+
+ int getCode() {
+ return INT1;
+ }
+- void setCode(int code) {
++ void setCode(final int code) {
+ INT1 = code;
+ }
+
+ int getAnchor() {
+ return INT1;
+ }
+- void setAnchor(int anchor) {
++ void setAnchor(final int anchor) {
+ INT1 = anchor;
+ }
+
+@@ -55,35 +55,35 @@
+ int getRepeatLower() {
+ return INT1;
+ }
+- void setRepeatLower(int lower) {
++ void setRepeatLower(final int lower) {
+ INT1 = lower;
+ }
+
+ int getRepeatUpper() {
+ return INT2;
+ }
+- void setRepeatUpper(int upper) {
++ void setRepeatUpper(final int upper) {
+ INT2 = upper;
+ }
+
+ boolean getRepeatGreedy() {
+ return INT3 != 0;
+ }
+- void setRepeatGreedy(boolean greedy) {
++ void setRepeatGreedy(final boolean greedy) {
+ INT3 = greedy ? 1 : 0;
+ }
+
+ boolean getRepeatPossessive() {
+ return INT4 != 0;
+ }
+- void setRepeatPossessive(boolean possessive) {
++ void setRepeatPossessive(final boolean possessive) {
+ INT4 = possessive ? 1 : 0;
+ }
+
+ int getBackrefRef() {
+ return INT2;
+ }
+- void setBackrefRef(int ref1) {
++ void setBackrefRef(final int ref1) {
+ INT2 = ref1;
+ }
+
+@@ -91,14 +91,14 @@
+ int getPropCType() {
+ return INT1;
+ }
+- void setPropCType(int ctype) {
++ void setPropCType(final int ctype) {
+ INT1 = ctype;
+ }
+
+ boolean getPropNot() {
+ return INT2 != 0;
+ }
+- void setPropNot(boolean not) {
++ void setPropNot(final boolean not) {
+ INT2 = not ? 1 : 0;
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/WarnCallback.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/WarnCallback.java Wed Feb 04 12:14:47 2015 -0800
+@@ -22,10 +22,11 @@
+ /**
+ * @author <a href="mailto:ola.bini@gmail.com">Ola Bini</a>
+ */
++@SuppressWarnings("javadoc")
+ public interface WarnCallback {
+ WarnCallback DEFAULT = new WarnCallback() {
+ @Override
+- public void warn(String message) {
++ public void warn(final String message) {
+ System.err.println(message);
+ }
+ };
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Warnings.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Warnings.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni;
+
++@SuppressWarnings("javadoc")
+ public interface Warnings {
+ final String INVALID_BACKREFERENCE = "invalid back reference";
+ final String INVALID_SUBEXP_CALL = "invalid subexp call";
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/AnchorNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/AnchorNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -21,12 +21,13 @@
+
+ import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
+
++@SuppressWarnings("javadoc")
+ public final class AnchorNode extends Node implements AnchorType {
+ public int type;
+ public Node target;
+ public int charLength;
+
+- public AnchorNode(int type) {
++ public AnchorNode(final int type) {
+ this.type = type;
+ charLength = -1;
+ }
+@@ -37,7 +38,7 @@
+ }
+
+ @Override
+- protected void setChild(Node newChild) {
++ protected void setChild(final Node newChild) {
+ target = newChild;
+ }
+
+@@ -46,7 +47,7 @@
+ return target;
+ }
+
+- public void setTarget(Node tgt) {
++ public void setTarget(final Node tgt) {
+ target = tgt;
+ tgt.parent = this;
+ }
+@@ -57,36 +58,68 @@
+ }
+
+ @Override
+- public String toString(int level) {
+- StringBuilder value = new StringBuilder();
++ public String toString(final int level) {
++ final StringBuilder value = new StringBuilder();
+ value.append("\n type: " + typeToString());
+ value.append("\n target: " + pad(target, level + 1));
+ return value.toString();
+ }
+
+ public String typeToString() {
+- StringBuilder type = new StringBuilder();
+- if (isType(BEGIN_BUF)) type.append("BEGIN_BUF ");
+- if (isType(BEGIN_LINE)) type.append("BEGIN_LINE ");
+- if (isType(BEGIN_POSITION)) type.append("BEGIN_POSITION ");
+- if (isType(END_BUF)) type.append("END_BUF ");
+- if (isType(SEMI_END_BUF)) type.append("SEMI_END_BUF ");
+- if (isType(END_LINE)) type.append("END_LINE ");
+- if (isType(WORD_BOUND)) type.append("WORD_BOUND ");
+- if (isType(NOT_WORD_BOUND)) type.append("NOT_WORD_BOUND ");
+- if (isType(WORD_BEGIN)) type.append("WORD_BEGIN ");
+- if (isType(WORD_END)) type.append("WORD_END ");
+- if (isType(PREC_READ)) type.append("PREC_READ ");
+- if (isType(PREC_READ_NOT)) type.append("PREC_READ_NOT ");
+- if (isType(LOOK_BEHIND)) type.append("LOOK_BEHIND ");
+- if (isType(LOOK_BEHIND_NOT)) type.append("LOOK_BEHIND_NOT ");
+- if (isType(ANYCHAR_STAR)) type.append("ANYCHAR_STAR ");
+- if (isType(ANYCHAR_STAR_ML)) type.append("ANYCHAR_STAR_ML ");
+- return type.toString();
++ final StringBuilder sb = new StringBuilder();
++ if (isType(BEGIN_BUF)) {
++ sb.append("BEGIN_BUF ");
++ }
++ if (isType(BEGIN_LINE)) {
++ sb.append("BEGIN_LINE ");
++ }
++ if (isType(BEGIN_POSITION)) {
++ sb.append("BEGIN_POSITION ");
++ }
++ if (isType(END_BUF)) {
++ sb.append("END_BUF ");
++ }
++ if (isType(SEMI_END_BUF)) {
++ sb.append("SEMI_END_BUF ");
++ }
++ if (isType(END_LINE)) {
++ sb.append("END_LINE ");
++ }
++ if (isType(WORD_BOUND)) {
++ sb.append("WORD_BOUND ");
++ }
++ if (isType(NOT_WORD_BOUND)) {
++ sb.append("NOT_WORD_BOUND ");
++ }
++ if (isType(WORD_BEGIN)) {
++ sb.append("WORD_BEGIN ");
++ }
++ if (isType(WORD_END)) {
++ sb.append("WORD_END ");
++ }
++ if (isType(PREC_READ)) {
++ sb.append("PREC_READ ");
++ }
++ if (isType(PREC_READ_NOT)) {
++ sb.append("PREC_READ_NOT ");
++ }
++ if (isType(LOOK_BEHIND)) {
++ sb.append("LOOK_BEHIND ");
++ }
++ if (isType(LOOK_BEHIND_NOT)) {
++ sb.append("LOOK_BEHIND_NOT ");
++ }
++ if (isType(ANYCHAR_STAR)) {
++ sb.append("ANYCHAR_STAR ");
++ }
++ if (isType(ANYCHAR_STAR_ML)) {
++ sb.append("ANYCHAR_STAR_ML ");
++ }
++ return sb.toString();
+ }
+
+- private boolean isType(int type) {
+- return (this.type & type) != 0;
++ private boolean isType(final int t) {
++ return (this.type & t) != 0;
+ }
+
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/AnyCharNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/AnyCharNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
++@SuppressWarnings("javadoc")
+ public final class AnyCharNode extends Node {
+ public AnyCharNode(){}
+
+@@ -33,8 +34,8 @@
+ }
+
+ @Override
+- public String toString(int level) {
+- String value = "";
++ public String toString(final int level) {
++ final String value = "";
+ return value;
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/BackRefNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/BackRefNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -21,10 +21,11 @@
+
+ import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
+
++@SuppressWarnings("javadoc")
+ public final class BackRefNode extends StateNode {
+ public final int backRef;
+
+- public BackRefNode(int backRef, ScanEnvironment env) {
++ public BackRefNode(final int backRef, final ScanEnvironment env) {
+ this.backRef = backRef;
+
+ if (backRef <= env.numMem && env.memNodes[backRef] == null) {
+@@ -43,8 +44,8 @@
+ }
+
+ @Override
+- public String toString(int level) {
+- StringBuilder value = new StringBuilder(super.toString(level));
++ public String toString(final int level) {
++ final StringBuilder value = new StringBuilder(super.toString(level));
+ value.append("\n back: ").append(backRef);
+ return value.toString();
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CClassNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CClassNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,7 +19,12 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
+-import jdk.nashorn.internal.runtime.regexp.joni.*;
++import jdk.nashorn.internal.runtime.regexp.joni.BitSet;
++import jdk.nashorn.internal.runtime.regexp.joni.CodeRangeBuffer;
++import jdk.nashorn.internal.runtime.regexp.joni.Config;
++import jdk.nashorn.internal.runtime.regexp.joni.EncodingHelper;
++import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
++import jdk.nashorn.internal.runtime.regexp.joni.Syntax;
+ import jdk.nashorn.internal.runtime.regexp.joni.constants.CCSTATE;
+ import jdk.nashorn.internal.runtime.regexp.joni.constants.CCVALTYPE;
+ import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
+@@ -29,6 +34,7 @@
+ import jdk.nashorn.internal.runtime.regexp.joni.exception.SyntaxException;
+ import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
+
++@SuppressWarnings("javadoc")
+ public final class CClassNode extends Node {
+ private static final int FLAG_NCCLASS_NOT = 1<<0;
+ private static final int FLAG_NCCLASS_SHARE = 1<<1;
+@@ -94,9 +100,11 @@
+ }
+
+ @Override
+- public boolean equals(Object other) {
+- if (!(other instanceof CClassNode)) return false;
+- CClassNode cc = (CClassNode)other;
++ public boolean equals(final Object other) {
++ if (!(other instanceof CClassNode)) {
++ return false;
++ }
++ final CClassNode cc = (CClassNode)other;
+ return ctype == cc.ctype && isNot() == cc.isNot();
+ }
+
+@@ -105,16 +113,17 @@
+ if (Config.USE_SHARED_CCLASS_TABLE) {
+ int hash = 0;
+ hash += ctype;
+- if (isNot()) hash++;
++ if (isNot()) {
++ hash++;
++ }
+ return hash + (hash >> 5);
+- } else {
+- return super.hashCode();
+ }
++ return super.hashCode();
+ }
+
+ @Override
+- public String toString(int level) {
+- StringBuilder value = new StringBuilder();
++ public String toString(final int level) {
++ final StringBuilder value = new StringBuilder();
+ value.append("\n flags: " + flagsToString());
+ value.append("\n bs: " + pad(bs, level + 1));
+ value.append("\n mbuf: " + pad(mbuf, level + 1));
+@@ -123,21 +132,25 @@
+ }
+
+ public String flagsToString() {
+- StringBuilder flags = new StringBuilder();
+- if (isNot()) flags.append("NOT ");
+- if (isShare()) flags.append("SHARE ");
+- return flags.toString();
++ final StringBuilder f = new StringBuilder();
++ if (isNot()) {
++ f.append("NOT ");
++ }
++ if (isShare()) {
++ f.append("SHARE ");
++ }
++ return f.toString();
+ }
+
+ public boolean isEmpty() {
+ return mbuf == null && bs.isEmpty();
+ }
+
+- public void addCodeRangeToBuf(int from, int to) {
++ public void addCodeRangeToBuf(final int from, final int to) {
+ mbuf = CodeRangeBuffer.addCodeRangeToBuff(mbuf, from, to);
+ }
+
+- public void addCodeRange(ScanEnvironment env, int from, int to) {
++ public void addCodeRange(final ScanEnvironment env, final int from, final int to) {
+ mbuf = CodeRangeBuffer.addCodeRange(mbuf, env, from, to);
+ }
+
+@@ -155,22 +168,22 @@
+ }
+
+ // and_cclass
+- public void and(CClassNode other) {
+- boolean not1 = isNot();
++ public void and(final CClassNode other) {
++ final boolean not1 = isNot();
+ BitSet bsr1 = bs;
+- CodeRangeBuffer buf1 = mbuf;
+- boolean not2 = other.isNot();
++ final CodeRangeBuffer buf1 = mbuf;
++ final boolean not2 = other.isNot();
+ BitSet bsr2 = other.bs;
+- CodeRangeBuffer buf2 = other.mbuf;
++ final CodeRangeBuffer buf2 = other.mbuf;
+
+ if (not1) {
+- BitSet bs1 = new BitSet();
++ final BitSet bs1 = new BitSet();
+ bsr1.invertTo(bs1);
+ bsr1 = bs1;
+ }
+
+ if (not2) {
+- BitSet bs2 = new BitSet();
++ final BitSet bs2 = new BitSet();
+ bsr2.invertTo(bs2);
+ bsr2 = bs2;
+ }
+@@ -202,22 +215,22 @@
+ }
+
+ // or_cclass
+- public void or(CClassNode other) {
+- boolean not1 = isNot();
++ public void or(final CClassNode other) {
++ final boolean not1 = isNot();
+ BitSet bsr1 = bs;
+- CodeRangeBuffer buf1 = mbuf;
+- boolean not2 = other.isNot();
++ final CodeRangeBuffer buf1 = mbuf;
++ final boolean not2 = other.isNot();
+ BitSet bsr2 = other.bs;
+- CodeRangeBuffer buf2 = other.mbuf;
++ final CodeRangeBuffer buf2 = other.mbuf;
+
+ if (not1) {
+- BitSet bs1 = new BitSet();
++ final BitSet bs1 = new BitSet();
+ bsr1.invertTo(bs1);
+ bsr1 = bs1;
+ }
+
+ if (not2) {
+- BitSet bs2 = new BitSet();
++ final BitSet bs2 = new BitSet();
+ bsr2.invertTo(bs2);
+ bsr2 = bs2;
+ }
+@@ -246,8 +259,8 @@
+ }
+
+ // add_ctype_to_cc_by_range // Encoding out!
+- public void addCTypeByRange(int ctype, boolean not, int sbOut, int mbr[]) {
+- int n = mbr[0];
++ public void addCTypeByRange(final int ct, final boolean not, final int sbOut, final int mbr[]) {
++ final int n = mbr[0];
+
+ if (!not) {
+ for (int i=0; i<n; i++) {
+@@ -289,10 +302,14 @@
+ // !goto sb_end2!, remove duplication
+ prev = sbOut;
+ for (i=0; i<n; i++) {
+- if (prev < mbr[2 * i + 1]) addCodeRangeToBuf(prev, mbr[i * 2 + 1] - 1);
++ if (prev < mbr[2 * i + 1]) {
++ addCodeRangeToBuf(prev, mbr[i * 2 + 1] - 1);
++ }
+ prev = mbr[i * 2 + 2] + 1;
+ }
+- if (prev < 0x7fffffff/*!!!*/) addCodeRangeToBuf(prev, 0x7fffffff);
++ if (prev < 0x7fffffff/*!!!*/) {
++ addCodeRangeToBuf(prev, 0x7fffffff);
++ }
+ return;
+ }
+ bs.set(j);
+@@ -307,22 +324,27 @@
+ // !sb_end2:!
+ prev = sbOut;
+ for (int i=0; i<n; i++) {
+- if (prev < mbr[2 * i + 1]) addCodeRangeToBuf(prev, mbr[i * 2 + 1] - 1);
++ if (prev < mbr[2 * i + 1]) {
++ addCodeRangeToBuf(prev, mbr[i * 2 + 1] - 1);
++ }
+ prev = mbr[i * 2 + 2] + 1;
+ }
+- if (prev < 0x7fffffff/*!!!*/) addCodeRangeToBuf(prev, 0x7fffffff);
++ if (prev < 0x7fffffff/*!!!*/) {
++ addCodeRangeToBuf(prev, 0x7fffffff);
++ }
+ }
+ }
+
+- public void addCType(int ctype, boolean not, ScanEnvironment env, IntHolder sbOut) {
++ public void addCType(final int ctp, final boolean not, final ScanEnvironment env, final IntHolder sbOut) {
++ int ct = ctp;
+ if (Config.NON_UNICODE_SDW) {
+- switch(ctype) {
++ switch (ct) {
+ case CharacterType.D:
+ case CharacterType.S:
+ case CharacterType.W:
+- ctype ^= CharacterType.SPECIAL_MASK;
++ ct ^= CharacterType.SPECIAL_MASK;
+
+- if (env.syntax == Syntax.JAVASCRIPT && ctype == CharacterType.SPACE) {
++ if (env.syntax == Syntax.JAVASCRIPT && ct == CharacterType.SPACE) {
+ // \s in JavaScript includes unicode characters.
+ break;
+ }
+@@ -330,26 +352,32 @@
+ if (not) {
+ for (int c = 0; c < BitSet.SINGLE_BYTE_SIZE; c++) {
+ // if (!ASCIIEncoding.INSTANCE.isCodeCType(c, ctype)) bs.set(c);
+- if ((AsciiCtypeTable[c] & (1 << ctype)) == 0) bs.set(c);
++ if ((AsciiCtypeTable[c] & (1 << ct)) == 0) {
++ bs.set(c);
++ }
+ }
+ addAllMultiByteRange();
+ } else {
+ for (int c = 0; c < BitSet.SINGLE_BYTE_SIZE; c++) {
+ // if (ASCIIEncoding.INSTANCE.isCodeCType(c, ctype)) bs.set(c);
+- if ((AsciiCtypeTable[c] & (1 << ctype)) != 0) bs.set(c);
++ if ((AsciiCtypeTable[c] & (1 << ct)) != 0) {
++ bs.set(c);
++ }
+ }
+ }
+ return;
++ default:
++ break;
+ }
+ }
+
+- int[] ranges = EncodingHelper.ctypeCodeRange(ctype, sbOut);
++ final int[] ranges = EncodingHelper.ctypeCodeRange(ct, sbOut);
+ if (ranges != null) {
+- addCTypeByRange(ctype, not, sbOut.value, ranges);
++ addCTypeByRange(ct, not, sbOut.value, ranges);
+ return;
+ }
+
+- switch(ctype) {
++ switch(ct) {
+ case CharacterType.ALPHA:
+ case CharacterType.BLANK:
+ case CharacterType.CNTRL:
+@@ -363,12 +391,16 @@
+ case CharacterType.ALNUM:
+ if (not) {
+ for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
+- if (!EncodingHelper.isCodeCType(c, ctype)) bs.set(c);
++ if (!EncodingHelper.isCodeCType(c, ct)) {
++ bs.set(c);
++ }
+ }
+ addAllMultiByteRange();
+ } else {
+ for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
+- if (EncodingHelper.isCodeCType(c, ctype)) bs.set(c);
++ if (EncodingHelper.isCodeCType(c, ct)) {
++ bs.set(c);
++ }
+ }
+ }
+ break;
+@@ -377,11 +409,15 @@
+ case CharacterType.PRINT:
+ if (not) {
+ for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
+- if (!EncodingHelper.isCodeCType(c, ctype)) bs.set(c);
++ if (!EncodingHelper.isCodeCType(c, ct)) {
++ bs.set(c);
++ }
+ }
+ } else {
+ for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
+- if (EncodingHelper.isCodeCType(c, ctype)) bs.set(c);
++ if (EncodingHelper.isCodeCType(c, ct)) {
++ bs.set(c);
++ }
+ }
+ addAllMultiByteRange();
+ }
+@@ -390,13 +426,17 @@
+ case CharacterType.WORD:
+ if (!not) {
+ for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
+- if (EncodingHelper.isWord(c)) bs.set(c);
++ if (EncodingHelper.isWord(c)) {
++ bs.set(c);
++ }
+ }
+
+ addAllMultiByteRange();
+ } else {
+ for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
+- if (!EncodingHelper.isWord(c)) bs.set(c);
++ if (!EncodingHelper.isWord(c)) {
++ bs.set(c);
++ }
+ }
+ }
+ break;
+@@ -416,8 +456,10 @@
+ public CCSTATE state;
+ }
+
+- public void nextStateClass(CCStateArg arg, ScanEnvironment env) {
+- if (arg.state == CCSTATE.RANGE) throw new SyntaxException(ErrorMessages.ERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE);
++ public void nextStateClass(final CCStateArg arg, final ScanEnvironment env) {
++ if (arg.state == CCSTATE.RANGE) {
++ throw new SyntaxException(ErrorMessages.ERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE);
++ }
+
+ if (arg.state == CCSTATE.VALUE && arg.type != CCVALTYPE.CLASS) {
+ if (arg.type == CCVALTYPE.SB) {
+@@ -430,12 +472,14 @@
+ arg.type = CCVALTYPE.CLASS;
+ }
+
+- public void nextStateValue(CCStateArg arg, ScanEnvironment env) {
++ public void nextStateValue(final CCStateArg arg, final ScanEnvironment env) {
+
+ switch(arg.state) {
+ case VALUE:
+ if (arg.type == CCVALTYPE.SB) {
+- if (arg.vs > 0xff) throw new ValueException(ErrorMessages.ERR_INVALID_CODE_POINT_VALUE);
++ if (arg.vs > 0xff) {
++ throw new ValueException(ErrorMessages.ERR_INVALID_CODE_POINT_VALUE);
++ }
+ bs.set(arg.vs);
+ } else if (arg.type == CCVALTYPE.CODE_POINT) {
+ addCodeRange(env, arg.vs, arg.vs);
+@@ -445,16 +489,17 @@
+ case RANGE:
+ if (arg.inType == arg.type) {
+ if (arg.inType == CCVALTYPE.SB) {
+- if (arg.vs > 0xff || arg.v > 0xff) throw new ValueException(ErrorMessages.ERR_INVALID_CODE_POINT_VALUE);
++ if (arg.vs > 0xff || arg.v > 0xff) {
++ throw new ValueException(ErrorMessages.ERR_INVALID_CODE_POINT_VALUE);
++ }
+
+ if (arg.vs > arg.v) {
+ if (env.syntax.allowEmptyRangeInCC()) {
+ // goto ccs_range_end
+ arg.state = CCSTATE.COMPLETE;
+ break;
+- } else {
+- throw new ValueException(ErrorMessages.ERR_EMPTY_RANGE_IN_CHAR_CLASS);
+ }
++ throw new ValueException(ErrorMessages.ERR_EMPTY_RANGE_IN_CHAR_CLASS);
+ }
+ bs.setRange(arg.vs, arg.v);
+ } else {
+@@ -466,9 +511,8 @@
+ // goto ccs_range_end
+ arg.state = CCSTATE.COMPLETE;
+ break;
+- } else {
+- throw new ValueException(ErrorMessages.ERR_EMPTY_RANGE_IN_CHAR_CLASS);
+ }
++ throw new ValueException(ErrorMessages.ERR_EMPTY_RANGE_IN_CHAR_CLASS);
+ }
+ bs.setRange(arg.vs, arg.v < 0xff ? arg.v : 0xff);
+ addCodeRange(env, arg.vs, arg.v);
+@@ -493,7 +537,7 @@
+ }
+
+ // onig_is_code_in_cc_len
+- public boolean isCodeInCCLength(int code) {
++ public boolean isCodeInCCLength(final int code) {
+ boolean found;
+
+ if (code > 0xff) {
+@@ -504,13 +548,12 @@
+
+ if (isNot()) {
+ return !found;
+- } else {
+- return found;
+ }
++ return found;
+ }
+
+ // onig_is_code_in_cc
+- public boolean isCodeInCC(int code) {
++ public boolean isCodeInCC(final int code) {
+ return isCodeInCCLength(code);
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/ConsAltNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/ConsAltNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -20,35 +20,40 @@
+ package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
+ import java.util.Set;
+-
+ import jdk.nashorn.internal.runtime.regexp.joni.WarnCallback;
+ import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
+ import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
+
++@SuppressWarnings("javadoc")
+ public final class ConsAltNode extends Node {
+ public Node car;
+ public ConsAltNode cdr;
+ private int type; // List or Alt
+
+- private ConsAltNode(Node car, ConsAltNode cdr, int type) {
++ private ConsAltNode(final Node car, final ConsAltNode cdr, final int type) {
+ this.car = car;
+- if (car != null) car.parent = this;
++ if (car != null) {
++ car.parent = this;
++ }
+ this.cdr = cdr;
+- if (cdr != null) cdr.parent = this;
++ if (cdr != null) {
++ cdr.parent = this;
++ }
+
+ this.type = type;
+ }
+
+- public static ConsAltNode newAltNode(Node left, ConsAltNode right) {
++ public static ConsAltNode newAltNode(final Node left, final ConsAltNode right) {
+ return new ConsAltNode(left, right, ALT);
+ }
+
+- public static ConsAltNode newListNode(Node left, ConsAltNode right) {
++ public static ConsAltNode newListNode(final Node left, final ConsAltNode right) {
+ return new ConsAltNode(left, right, LIST);
+ }
+
+- public static ConsAltNode listAdd(ConsAltNode list, Node x) {
+- ConsAltNode n = newListNode(x, null);
++ public static ConsAltNode listAdd(final ConsAltNode listp, final Node x) {
++ final ConsAltNode n = newListNode(x, null);
++ ConsAltNode list = listp;
+
+ if (list != null) {
+ while (list.cdr != null) {
+@@ -73,7 +78,7 @@
+ }
+
+ @Override
+- protected void setChild(Node newChild) {
++ protected void setChild(final Node newChild) {
+ car = newChild;
+ }
+
+@@ -83,13 +88,13 @@
+ }
+
+ @Override
+- public void swap(Node with) {
++ public void swap(final Node with) {
+ if (cdr != null) {
+ cdr.parent = with;
+ if (with instanceof ConsAltNode) {
+- ConsAltNode withCan = (ConsAltNode)with;
++ final ConsAltNode withCan = (ConsAltNode)with;
+ withCan.cdr.parent = this;
+- ConsAltNode tmp = cdr;
++ final ConsAltNode tmp = cdr;
+ cdr = withCan.cdr;
+ withCan.cdr = tmp;
+ }
+@@ -98,7 +103,7 @@
+ }
+
+ @Override
+- public void verifyTree(Set<Node> set, WarnCallback warnings) {
++ public void verifyTree(final Set<Node> set, final WarnCallback warnings) {
+ if (!set.contains(this)) {
+ set.add(this);
+ if (car != null) {
+@@ -116,13 +121,13 @@
+ }
+ }
+
+- public Node setCar(Node ca) {
++ public Node setCar(final Node ca) {
+ car = ca;
+ ca.parent = this;
+ return car;
+ }
+
+- public ConsAltNode setCdr(ConsAltNode cd) {
++ public ConsAltNode setCdr(final ConsAltNode cd) {
+ cdr = cd;
+ cd.parent = this;
+ return cdr;
+@@ -141,8 +146,8 @@
+ }
+
+ @Override
+- public String toString(int level) {
+- StringBuilder value = new StringBuilder();
++ public String toString(final int level) {
++ final StringBuilder value = new StringBuilder();
+ value.append("\n car: " + pad(car, level + 1));
+ value.append("\n cdr: " + (cdr == null ? "NULL" : cdr.toString()));
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/EncloseNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/EncloseNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -22,6 +22,7 @@
+ import jdk.nashorn.internal.runtime.regexp.joni.Option;
+ import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType;
+
++@SuppressWarnings("javadoc")
+ public final class EncloseNode extends StateNode implements EncloseType {
+
+ public final int type; // enclose type
+@@ -35,7 +36,7 @@
+ public int optCount; // referenced count in optimize_node_left()
+
+ // node_new_enclose / onig_node_new_enclose
+- public EncloseNode(int type) {
++ public EncloseNode(final int type) {
+ this.type = type;
+ callAddr = -1;
+ }
+@@ -46,7 +47,7 @@
+ }
+
+ // node_new_option
+- public EncloseNode(int option, int i) {
++ public EncloseNode(final int option, final int i) {
+ this(OPTION);
+ this.option = option;
+ }
+@@ -57,7 +58,7 @@
+ }
+
+ @Override
+- protected void setChild(Node newChild) {
++ protected void setChild(final Node newChild) {
+ target = newChild;
+ }
+
+@@ -66,7 +67,7 @@
+ return target;
+ }
+
+- public void setTarget(Node tgt) {
++ public void setTarget(final Node tgt) {
+ target = tgt;
+ tgt.parent = this;
+ }
+@@ -77,8 +78,8 @@
+ }
+
+ @Override
+- public String toString(int level) {
+- StringBuilder value = new StringBuilder(super.toString(level));
++ public String toString(final int level) {
++ final StringBuilder value = new StringBuilder(super.toString(level));
+ value.append("\n type: " + typeToString());
+ value.append("\n regNum: " + regNum);
+ value.append("\n option: " + Option.toString(option));
+@@ -93,7 +94,7 @@
+ }
+
+ public String typeToString() {
+- StringBuilder types = new StringBuilder();
++ final StringBuilder types = new StringBuilder();
+ if (isStopBacktrack()) types.append("STOP_BACKTRACK ");
+ if (isMemory()) types.append("MEMORY ");
+ if (isOption()) types.append("OPTION ");
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/Node.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/Node.java Wed Feb 04 12:14:47 2015 -0800
+@@ -20,11 +20,11 @@
+ package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
+ import java.util.Set;
+-
+ import jdk.nashorn.internal.runtime.regexp.joni.Config;
+ import jdk.nashorn.internal.runtime.regexp.joni.WarnCallback;
+ import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType;
+
++@SuppressWarnings("javadoc")
+ public abstract class Node implements NodeType {
+ public Node parent;
+
+@@ -34,10 +34,14 @@
+ return 1 << getType();
+ }
+
+- protected void setChild(Node tgt){} // default definition
+- protected Node getChild(){return null;} // default definition
++ protected void setChild(final Node tgt) {
++ //empty, default definition
++ }
++ protected Node getChild() {
++ return null; // default definition
++ }
+
+- public void swap(Node with) {
++ public void swap(final Node with) {
+ Node tmp;
+
+ //if (getChild() != null) getChild().parent = with;
+@@ -47,9 +51,13 @@
+ //setChild(with.getChild());
+ //with.setChild(tmp);
+
+- if (parent != null) parent.setChild(with);
++ if (parent != null) {
++ parent.setChild(with);
++ }
+
+- if (with.parent != null) with.parent.setChild(this);
++ if (with.parent != null) {
++ with.parent.setChild(this);
++ }
+
+ tmp = parent;
+ parent = with.parent;
+@@ -57,7 +65,7 @@
+ }
+
+ // overridden by ConsAltNode and CallNode
+- public void verifyTree(Set<Node> set, WarnCallback warnings) {
++ public void verifyTree(final Set<Node> set, final WarnCallback warnings) {
+ if (!set.contains(this) && getChild() != null) {
+ set.add(this);
+ if (getChild().parent != this) {
+@@ -76,22 +84,28 @@
+
+ @Override
+ public final String toString() {
+- StringBuilder s = new StringBuilder();
++ final StringBuilder s = new StringBuilder();
+ s.append("<" + getAddressName() + " (" + (parent == null ? "NULL" : parent.getAddressName()) + ")>");
+ return s + toString(0);
+ }
+
+- protected static String pad(Object value, int level) {
+- if (value == null) return "NULL";
++ protected static String pad(final Object value, final int level) {
++ if (value == null) {
++ return "NULL";
++ }
+
+- StringBuilder pad = new StringBuilder(" ");
+- for (int i=0; i<level; i++) pad.append(pad);
++ final StringBuilder pad = new StringBuilder(" ");
++ for (int i=0; i<level; i++) {
++ pad.append(pad);
++ }
+
+ return value.toString().replace("\n", "\n" + pad);
+ }
+
+ public final boolean isInvalidQuantifier() {
+- if (!Config.VANILLA) return false;
++ if (!Config.VANILLA) {
++ return false;
++ }
+
+ ConsAltNode node;
+
+@@ -108,14 +122,18 @@
+ case LIST:
+ node = (ConsAltNode)this;
+ do {
+- if (!node.car.isInvalidQuantifier()) return false;
++ if (!node.car.isInvalidQuantifier()) {
++ return false;
++ }
+ } while ((node = node.cdr) != null);
+ return false;
+
+ case ALT:
+ node = (ConsAltNode)this;
+ do {
+- if (node.car.isInvalidQuantifier()) return true;
++ if (node.car.isInvalidQuantifier()) {
++ return true;
++ }
+ } while ((node = node.cdr) != null);
+ break;
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/QuantifierNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/QuantifierNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,12 +19,18 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.ast;
+
++import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.ReduceType.A;
++import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.ReduceType.AQ;
++import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.ReduceType.ASIS;
++import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.ReduceType.DEL;
++import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.ReduceType.PQ_Q;
++import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.ReduceType.P_QQ;
++import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.ReduceType.QQ;
+ import jdk.nashorn.internal.runtime.regexp.joni.Config;
+ import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
+ import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo;
+
+-import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.ReduceType.*;
+-
++@SuppressWarnings("javadoc")
+ public final class QuantifierNode extends StateNode {
+
+ public Node target;
+@@ -66,13 +72,15 @@
+ };
+
+
+- public QuantifierNode(int lower, int upper, boolean byNumber) {
++ public QuantifierNode(final int lower, final int upper, final boolean byNumber) {
+ this.lower = lower;
+ this.upper = upper;
+ greedy = true;
+ targetEmptyInfo = TargetInfo.ISNOT_EMPTY;
+
+- if (byNumber) setByNumber();
++ if (byNumber) {
++ setByNumber();
++ }
+ }
+
+ @Override
+@@ -81,7 +89,7 @@
+ }
+
+ @Override
+- protected void setChild(Node newChild) {
++ protected void setChild(final Node newChild) {
+ target = newChild;
+ }
+
+@@ -90,13 +98,13 @@
+ return target;
+ }
+
+- public void setTarget(Node tgt) {
++ public void setTarget(final Node tgt) {
+ target = tgt;
+ tgt.parent = this;
+ }
+
+- public StringNode convertToString(int flag) {
+- StringNode sn = new StringNode();
++ public StringNode convertToString(final int flag) {
++ final StringNode sn = new StringNode();
+ sn.flag = flag;
+ sn.swap(this);
+ return sn;
+@@ -108,8 +116,8 @@
+ }
+
+ @Override
+- public String toString(int level) {
+- StringBuilder value = new StringBuilder(super.toString(level));
++ public String toString(final int level) {
++ final StringBuilder value = new StringBuilder(super.toString(level));
+ value.append("\n target: " + pad(target, level + 1));
+ value.append("\n lower: " + lower);
+ value.append("\n upper: " + upper);
+@@ -130,23 +138,33 @@
+ protected int popularNum() {
+ if (greedy) {
+ if (lower == 0) {
+- if (upper == 1) return 0;
+- else if (isRepeatInfinite(upper)) return 1;
++ if (upper == 1) {
++ return 0;
++ } else if (isRepeatInfinite(upper)) {
++ return 1;
++ }
+ } else if (lower == 1) {
+- if (isRepeatInfinite(upper)) return 2;
++ if (isRepeatInfinite(upper)) {
++ return 2;
++ }
+ }
+ } else {
+ if (lower == 0) {
+- if (upper == 1) return 3;
+- else if (isRepeatInfinite(upper)) return 4;
++ if (upper == 1) {
++ return 3;
++ } else if (isRepeatInfinite(upper)) {
++ return 4;
++ }
+ } else if (lower == 1) {
+- if (isRepeatInfinite(upper)) return 5;
++ if (isRepeatInfinite(upper)) {
++ return 5;
++ }
+ }
+ }
+ return -1;
+ }
+
+- protected void set(QuantifierNode other) {
++ protected void set(final QuantifierNode other) {
+ setTarget(other.target);
+ other.target = null;
+ lower = other.lower;
+@@ -161,11 +179,13 @@
+ isRefered = other.isRefered;
+ }
+
+- public void reduceNestedQuantifier(QuantifierNode other) {
+- int pnum = popularNum();
+- int cnum = other.popularNum();
++ public void reduceNestedQuantifier(final QuantifierNode other) {
++ final int pnum = popularNum();
++ final int cnum = other.popularNum();
+
+- if (pnum < 0 || cnum < 0) return;
++ if (pnum < 0 || cnum < 0) {
++ return;
++ }
+
+ switch(REDUCE_TABLE[cnum][pnum]) {
+ case DEL:
+@@ -218,22 +238,27 @@
+ case ASIS:
+ setTarget(other);
+ return;
++
++ default:
++ break;
+ }
+ // ??? remove the parent from target ???
+ other.target = null; // remove target from reduced quantifier
+ }
+
+ @SuppressWarnings("fallthrough")
+- public int setQuantifier(Node tgt, boolean group, ScanEnvironment env, char[] chars, int p, int end) {
+- if (lower == 1 && upper == 1) return 1;
++ public int setQuantifier(final Node tgt, final boolean group, final ScanEnvironment env, final char[] chars, final int p, final int end) {
++ if (lower == 1 && upper == 1) {
++ return 1;
++ }
+
+ switch(tgt.getType()) {
+
+ case STR:
+ if (!group) {
+- StringNode sn = (StringNode)tgt;
++ final StringNode sn = (StringNode)tgt;
+ if (sn.canBeSplit()) {
+- StringNode n = sn.splitLastChar();
++ final StringNode n = sn.splitLastChar();
+ if (n != null) {
+ setTarget(n);
+ return 2;
+@@ -245,9 +270,9 @@
+ case QTFR:
+ /* check redundant double repeat. */
+ /* verbose warn (?:.?)? etc... but not warn (.?)? etc... */
+- QuantifierNode qnt = (QuantifierNode)tgt;
+- int nestQNum = popularNum();
+- int targetQNum = qnt.popularNum();
++ final QuantifierNode qnt = (QuantifierNode)tgt;
++ final int nestQNum = popularNum();
++ final int targetQNum = qnt.popularNum();
+
+ if (Config.USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR) {
+ if (!isByNumber() && !qnt.isByNumber() && env.syntax.warnReduntantNestedRepeat()) {
+@@ -290,7 +315,7 @@
+ }
+
+ public static final int REPEAT_INFINITE = -1;
+- public static boolean isRepeatInfinite(int n) {
++ public static boolean isRepeatInfinite(final int n) {
+ return n == REPEAT_INFINITE;
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StateNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StateNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -21,16 +21,17 @@
+
+ import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeStatus;
+
++@SuppressWarnings("javadoc")
+ public abstract class StateNode extends Node implements NodeStatus {
+ protected int state;
+
+ @Override
+- public String toString(int level) {
++ public String toString(final int level) {
+ return "\n state: " + stateToString();
+ }
+
+ public String stateToString() {
+- StringBuilder states = new StringBuilder();
++ final StringBuilder states = new StringBuilder();
+ if (isMinFixed()) states.append("MIN_FIXED ");
+ if (isMaxFixed()) states.append("MAX_FIXED ");
+ if (isMark1()) states.append("MARK1 ");
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StringNode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StringNode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -22,6 +22,7 @@
+ import jdk.nashorn.internal.runtime.regexp.joni.EncodingHelper;
+ import jdk.nashorn.internal.runtime.regexp.joni.constants.StringType;
+
++@SuppressWarnings("javadoc")
+ public final class StringNode extends Node implements StringType {
+
+ private static final int NODE_STR_MARGIN = 16;
+@@ -38,14 +39,14 @@
+ this.chars = new char[NODE_STR_BUF_SIZE];
+ }
+
+- public StringNode(char[] chars, int p, int end) {
++ public StringNode(final char[] chars, final int p, final int end) {
+ this.chars = chars;
+ this.p = p;
+ this.end = end;
+ setShared();
+ }
+
+- public StringNode(char c) {
++ public StringNode(final char c) {
+ this();
+ chars[end++] = c;
+ }
+@@ -53,10 +54,10 @@
+ /* Ensure there is ahead bytes available in node's buffer
+ * (assumes that the node is not shared)
+ */
+- public void ensure(int ahead) {
+- int len = (end - p) + ahead;
++ public void ensure(final int ahead) {
++ final int len = (end - p) + ahead;
+ if (len >= chars.length) {
+- char[] tmp = new char[len + NODE_STR_MARGIN];
++ final char[] tmp = new char[len + NODE_STR_MARGIN];
+ System.arraycopy(chars, p, tmp, 0, end - p);
+ chars = tmp;
+ }
+@@ -64,10 +65,10 @@
+
+ /* COW and/or ensure there is ahead bytes available in node's buffer
+ */
+- private void modifyEnsure(int ahead) {
++ private void modifyEnsure(final int ahead) {
+ if (isShared()) {
+- int len = (end - p) + ahead;
+- char[] tmp = new char[len + NODE_STR_MARGIN];
++ final int len = (end - p) + ahead;
++ final char[] tmp = new char[len + NODE_STR_MARGIN];
+ System.arraycopy(chars, p, tmp, 0, end - p);
+ chars = tmp;
+ end = end - p;
+@@ -89,8 +90,8 @@
+ }
+
+ @Override
+- public String toString(int level) {
+- StringBuilder value = new StringBuilder();
++ public String toString(final int level) {
++ final StringBuilder value = new StringBuilder();
+ value.append("\n bytes: '");
+ for (int i=p; i<end; i++) {
+ if (chars[i] >= 0x20 && chars[i] < 0x7f) {
+@@ -111,7 +112,7 @@
+ StringNode n = null;
+
+ if (end > p) {
+- int prev = EncodingHelper.prevCharHead(p, end);
++ final int prev = EncodingHelper.prevCharHead(p, end);
+ if (prev != -1 && prev > p) { /* can be splitted. */
+ n = new StringNode(chars, prev, end);
+ if (isRaw()) n.setRaw();
+@@ -125,26 +126,26 @@
+ return end > p && 1 < (end - p);
+ }
+
+- public void set(char[] chars, int p, int end) {
++ public void set(final char[] chars, final int p, final int end) {
+ this.chars = chars;
+ this.p = p;
+ this.end = end;
+ setShared();
+ }
+
+- public void cat(char[] cat, int catP, int catEnd) {
+- int len = catEnd - catP;
++ public void cat(final char[] cat, final int catP, final int catEnd) {
++ final int len = catEnd - catP;
+ modifyEnsure(len);
+ System.arraycopy(cat, catP, chars, end, len);
+ end += len;
+ }
+
+- public void cat(char c) {
++ public void cat(final char c) {
+ modifyEnsure(1);
+ chars[end++] = c;
+ }
+
+- public void catCode(int code) {
++ public void catCode(final int code) {
+ cat((char)code);
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/AnchorType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/AnchorType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public interface AnchorType {
+ final int BEGIN_BUF = (1<<0);
+ final int BEGIN_LINE = (1<<1);
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/Arguments.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/Arguments.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public interface Arguments {
+ final int SPECIAL = -1;
+ final int NON = 0;
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/AsmConstants.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/AsmConstants.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public interface AsmConstants {
+ final int THIS = 0;
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/CCSTATE.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/CCSTATE.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public enum CCSTATE {
+ VALUE,
+ RANGE,
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/CCVALTYPE.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/CCVALTYPE.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public enum CCVALTYPE {
+ SB,
+ CODE_POINT,
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/EncloseType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/EncloseType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public interface EncloseType {
+ final int MEMORY = 1<<0;
+ final int OPTION = 1<<1;
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/MetaChar.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/MetaChar.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public interface MetaChar {
+ final int ESCAPE = 0;
+ final int ANYCHAR = 1;
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/NodeStatus.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/NodeStatus.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public interface NodeStatus {
+ /* status bits */
+ final int NST_MIN_FIXED = (1<<0);
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/NodeType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/NodeType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public interface NodeType {
+ /* node type */
+ final int STR = 0;
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/OPCode.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/OPCode.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public interface OPCode {
+ final int FINISH = 0; /* matching process terminator (no more alternative) */
+ final int END = 1; /* pattern code terminator (success end) */
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/OPSize.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/OPSize.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public interface OPSize {
+
+ // this might be helpful for potential byte[] migration
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/RegexState.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/RegexState.java Wed Feb 04 12:14:47 2015 -0800
+@@ -20,6 +20,7 @@
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
+ // we dont need this ATM
++@SuppressWarnings("javadoc")
+ public interface RegexState {
+ final int NORMAL = 0;
+ final int SEARCHING = 1;
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/StackPopLevel.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/StackPopLevel.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public interface StackPopLevel {
+ final int FREE = 0;
+ final int MEM_START = 1;
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/StackType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/StackType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public interface StackType {
+ /** stack **/
+ final int INVALID_STACK_INDEX = -1;
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/StringType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/StringType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public interface StringType {
+ final int NSTR_RAW = 1<<0;
+ final int NSTR_AMBIG = 1<<1;
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/SyntaxProperties.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/SyntaxProperties.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public interface SyntaxProperties {
+ /* syntax (operators); */
+ final int OP_VARIABLE_META_CHARACTERS = (1<<0);
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/TargetInfo.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/TargetInfo.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public interface TargetInfo {
+ final int ISNOT_EMPTY = 0;
+ final int IS_EMPTY = 1;
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/TokenType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/TokenType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public enum TokenType {
+ EOT, /* end of token */
+ RAW_BYTE,
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/Traverse.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/Traverse.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.constants;
+
++@SuppressWarnings("javadoc")
+ public interface Traverse {
+ final int TRAVERSE_CALLBACK_AT_FIRST = 1;
+ final int TRAVERSE_CALLBACK_AT_LAST = 2;
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/CharacterType.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/CharacterType.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.encoding;
+
++@SuppressWarnings("javadoc")
+ public interface CharacterType {
+
+ final int NEWLINE = 0;
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/IntHolder.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/IntHolder.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.encoding;
+
++@SuppressWarnings("javadoc")
+ public class IntHolder {
+ public int value;
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/ObjPtr.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/ObjPtr.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,12 +19,13 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.encoding;
+
++@SuppressWarnings("javadoc")
+ public final class ObjPtr<T> {
+ public ObjPtr() {
+ this(null);
+ }
+
+- public ObjPtr(T p) {
++ public ObjPtr(final T p) {
+ this.p = p;
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ErrorMessages.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ErrorMessages.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,6 +19,7 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.exception;
+
++@SuppressWarnings("javadoc")
+ public interface ErrorMessages {
+
+ /* from jcodings */
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/InternalException.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/InternalException.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,10 +19,11 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.exception;
+
++@SuppressWarnings("javadoc")
+ public class InternalException extends JOniException{
+ private static final long serialVersionUID = -3871816465397927992L;
+
+- public InternalException(String message) {
++ public InternalException(final String message) {
+ super(message);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/JOniException.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/JOniException.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,10 +19,11 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.exception;
+
++@SuppressWarnings("javadoc")
+ public class JOniException extends RuntimeException{
+ private static final long serialVersionUID = -6027192180014164667L;
+
+- public JOniException(String message) {
++ public JOniException(final String message) {
+ super(message);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/SyntaxException.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/SyntaxException.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,10 +19,11 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.exception;
+
++@SuppressWarnings("javadoc")
+ public class SyntaxException extends JOniException{
+ private static final long serialVersionUID = 7862720128961874288L;
+
+- public SyntaxException(String message) {
++ public SyntaxException(final String message) {
+ super(message);
+ }
+ }
+--- ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ValueException.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ValueException.java Wed Feb 04 12:14:47 2015 -0800
+@@ -19,14 +19,15 @@
+ */
+ package jdk.nashorn.internal.runtime.regexp.joni.exception;
+
+-public class ValueException extends SyntaxException{
++@SuppressWarnings("javadoc")
++public class ValueException extends SyntaxException {
+ private static final long serialVersionUID = -196013852479929134L;
+
+- public ValueException(String message) {
++ public ValueException(final String message) {
+ super(message);
+ }
+
+- public ValueException(String message, String str) {
++ public ValueException(final String message, final String str) {
+ super(message.replaceAll("%n", str));
+ }
+
+--- ./nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties Wed Feb 04 12:14:47 2015 -0800
+@@ -58,6 +58,7 @@
+ parser.error.regex.repeated.flag=Repeated RegExp flag: {0}
+ parser.error.regex.syntax={0}
+ parser.error.trailing.comma.in.json=Trailing comma is not allowed in JSON
++parser.error.missing.const.assignment=Missing assignment to constant "{0}"
+
+ # strict mode error messages
+ parser.error.strict.no.with="with" statement cannot be used in strict mode
+@@ -72,14 +73,17 @@
+ type.error.not.an.object={0} is not an Object
+ type.error.not.a.boolean={0} is not a Boolean
+ type.error.not.a.date={0} is not a Date
++type.error.not.a.java.importer={0} is not a JavaImporter object
+ type.error.not.a.number={0} is not a Number
+ type.error.not.a.regexp={0} is not a RegExp
+ type.error.not.a.string={0} is not a String
+ type.error.not.a.function={0} is not a function
+ type.error.not.a.constructor={0} is not a constructor function
+ type.error.not.a.file={0} is not a File
++type.error.not.a.numeric.array={0} is not a numeric array
+ type.error.not.a.bytebuffer={0} is not a java.nio.ByteBuffer
+-type.error.not.an.arraybuffer.in.dataview=First arg to DataView constructor must be an ArrayBuffer
++type.error.not.an.arraybuffer.in.dataview=First argument to DataView constructor must be an ArrayBuffer
++type.error.no.reflection.with.classfilter=Java reflection not supported when class filter is present
+
+ # operations not permitted on undefined
+ type.error.cant.call.undefined=Cannot call undefined
+@@ -89,8 +93,11 @@
+
+ # other wrong usages of property
+ type.error.property.has.no.setter=Cannot set property "{0}" of {1} that has only a getter
+-type.error.cant.set.proto.to.non.object=Cannot set Object {0}'s __proto__ to be a non-object like {1}
++type.error.cant.set.proto.to.non.object=Cannot set Object {0}''s __proto__ to be a non-object like {1}
+ type.error.no.such.function={1} has no such function "{0}"
++type.error.no.such.java.class=No such Java class: {0}
++type.error.no.such.java.constructor=No such Java constructor: {0}
++type.error.improper.constructor.signature=Java constructor signature invalid: {0}
+ type.error.cant.get.property=Cannot get property "{0}" of {1}
+ type.error.cant.set.property=Cannot set property "{0}" of {1}
+ type.error.cant.delete.property=Cannot delete property "{0}" of {1}
+@@ -109,6 +116,7 @@
+ type.error.cannot.convert.to.interface=object {0} cannot be converted to {1} due to "{2}"
+ type.error.array.reduce.invalid.init=invalid initialValue for Array.prototype.reduce
+ type.error.array.reduceright.invalid.init=invalid initialValue for Array.prototype.reduceRight
++type.error.assign.constant=Assignment to constant "{0}"
+ type.error.cannot.get.default.string=Cannot get default string value
+ type.error.cannot.get.default.number=Cannot get default number value
+ type.error.cant.apply.with.to.null=Cannot apply "with" to null
+@@ -119,10 +127,10 @@
+ type.error.cant.load.script=Cannot load script from {0}
+ type.error.JSON.stringify.cyclic=JSON.stringify got a cyclic data structure
+ type.error.cant.convert.string.to.char=Cannot convert string to character; its length must be exactly 1
+-type.error.cant.convert.number.to.char=Cannot convert number to character; it's out of 0-65535 range
++type.error.cant.convert.number.to.char=Cannot convert number to character; it is out of 0-65535 range
+ type.error.cant.convert.to.java.string=Cannot convert object of type {0} to a Java argument of string type
+ type.error.cant.convert.to.java.number=Cannot convert object of type {0} to a Java argument of number type
+-type.error.cant.convert.to.javascript.array=Can only convert Java arrays and lists to JavaScript arrays. Can't convert object of type {0}.
++type.error.cant.convert.to.javascript.array=Can only convert Java arrays and lists to JavaScript arrays. Cannot convert object of type {0}.
+ type.error.extend.expects.at.least.one.argument=Java.extend needs at least one argument.
+ type.error.extend.expects.at.least.one.type.argument=Java.extend needs at least one type argument.
+ type.error.extend.expects.java.types=Java.extend needs Java types as its arguments.
+@@ -135,9 +143,10 @@
+ type.error.extend.ERROR_FINAL_FINALIZER=Can not extend class because {0} has a final finalize method.
+ type.error.no.constructor.matches.args=Can not construct {0} with the passed arguments; they do not match any of its constructor signatures.
+ type.error.no.method.matches.args=Can not invoke method {0} with the passed arguments; they do not match any of its method signatures.
+-type.error.method.not.constructor=Java method {0} can't be used as a constructor.
++type.error.method.not.constructor=Java method {0} cannot be used as a constructor.
+ type.error.env.not.object=$ENV must be an Object.
+ type.error.unsupported.java.to.type=Unsupported Java.to target type {0}.
++type.error.constructor.requires.new=Constructor {0} requires "new".
+ type.error.new.on.nonpublic.javatype=new cannot be used with non-public java type {0}.
+
+ range.error.dataview.constructor.offset=Wrong offset or length in DataView constructor
+@@ -149,12 +158,16 @@
+ range.error.invalid.radix=radix argument must be in [2, 36]
+ range.error.invalid.date=Invalid Date
+ range.error.too.many.errors=Script contains too many errors: {0} errors
++range.error.concat.string.too.big=Concatenated String is too big
+
+ reference.error.not.defined="{0}" is not defined
+ reference.error.cant.be.used.as.lhs="{0}" can not be used as the left-hand side of assignment
+
+ syntax.error.invalid.json=Invalid JSON: {0}
+ syntax.error.strict.cant.delete=cannot delete "{0}" in strict mode
++syntax.error.redeclare.variable=Variable "{0}" has already been declared
++syntax.error.assign.constant=Assignment to constant "{0}"
++syntax.error.unprotected.switch.declaration=Unsupported {0} declaration in unprotected switch statement
+
+ io.error.cant.write=cannot write "{0}"
+ config.error.no.dest=no destination directory supplied
+--- ./nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties Wed Feb 04 12:14:47 2015 -0800
+@@ -177,7 +177,7 @@
+ is_undocumented=true, \
+ params="<module:level>,*", \
+ desc="Enable logging of a given level for a given number of sub systems. \
+- [for example: --log=fields:finest,codegen:info]", \
++ [for example: --log=fields:finest,codegen:info].", \
+ type=Log \
+ }
+
+@@ -197,7 +197,15 @@
+ nashorn.option.lazy.compilation = { \
+ name="--lazy-compilation", \
+ is_undocumented=true, \
+- desc="EXPERIMENTAL: Use lazy code generation strategies - do not compile the entire script at once." \
++ desc="Use lazy code generation strategies - do not compile the entire script at once.", \
++ default=true \
++}
++
++nashorn.option.optimistic.types = { \
++ name="--optimistic-types", \
++ short_name="-ot", \
++ desc="Use optimistic type assumptions with deoptimizing recompilation. This makes the compiler try, for any program symbol whose type cannot be proven at compile time, to type it as narrow and primitive as possible. If the runtime encounters an error because symbol type is too narrow, a wider method will be generated until steady stage is reached. While this produces as optimal Java Bytecode as possible, erroneous type guesses will lead to longer warmup. Optimistic typing is currently disabled by default, but can be enabled for significantly better peak performance.", \
++ default=false \
+ }
+
+ nashorn.option.loader.per.compile = { \
+@@ -211,23 +219,23 @@
+ name="--no-java", \
+ short_name="-nj", \
+ is_undocumented=true, \
+- desc="No Java support", \
++ desc="Disable Java support.", \
+ default=false \
+ }
+
+-nashorn.option.no.syntax.extensions = { \
+- name="--no-syntax-extensions", \
+- short_name="-nse", \
+- is_undocumented=true, \
+- desc="No non-standard syntax extensions", \
+- default=false \
++nashorn.option.no.syntax.extensions = { \
++ name="--no-syntax-extensions", \
++ short_name="-nse", \
++ is_undocumented=true, \
++ desc="Disallow non-standard syntax extensions.", \
++ default=false \
+ }
+
+ nashorn.option.no.typed.arrays = { \
+ name="--no-typed-arrays", \
+ short_name="-nta", \
+ is_undocumented=true, \
+- desc="No Typed arrays support", \
++ desc="Disable typed arrays support.", \
+ default=false \
+ }
+
+@@ -266,8 +274,11 @@
+
+ nashorn.option.print.code = { \
+ name="--print-code", \
++ short_name="-pc", \
+ is_undocumented=true, \
+- desc="Print bytecode." \
++ params="[dir:<output-dir>,function:<name>]", \
++ type=keyvalues, \
++ desc="Print generated bytecode. If a directory is specified, nothing will be dumped to stderr. Also, in that case, .dot files will be generated for all functions or for the function with the specified name only." \
+ }
+
+ nashorn.option.print.mem.usage = { \
+@@ -284,12 +295,14 @@
+
+ nashorn.option.print.parse = { \
+ name="--print-parse", \
++ short_name="-pp", \
+ is_undocumented=true, \
+ desc="Print the parse tree." \
+ }
+
+ nashorn.option.print.lower.parse = { \
+ name="--print-lower-parse", \
++ short_name="-plp", \
+ is_undocumented=true, \
+ desc="Print the parse tree after lowering." \
+ }
+@@ -300,12 +313,6 @@
+ desc="Print the symbol table." \
+ }
+
+-nashorn.option.range.analysis = { \
+- name="--range-analysis", \
+- is_undocumented=true, \
+- desc="EXPERIMENTAL: Do range analysis using known compile time types, and try to narrow number types" \
+-}
+-
+ nashorn.option.D = { \
+ name="-D", \
+ desc="-Dname=value. Set a system property. This option can be repeated.", \
+@@ -322,28 +329,28 @@
+ desc="Enable scripting features." \
+ }
+
+-nashorn.option.specialize.calls = { \
+- name="--specialize-calls", \
+- is_undocumented=true, \
+- type=String, \
+- params="[=function_1,...,function_n]", \
+- desc="EXPERIMENTAL: Specialize all or a set of method according to callsite parameter types" \
++nashorn.option.language = { \
++ name="--language", \
++ type=String, \
++ params=[es5|es6], \
++ default=es5, \
++ desc="Specify ECMAScript language version." \
+ }
+
+-nashorn.option.stdout = { \
+- name="--stdout", \
+- is_undocumented=true, \
+- type=String, \
+- params="<output console>", \
+- desc="Redirect stdout to a filename or to another tty, e.g. stderr" \
++nashorn.option.stdout = { \
++ name="--stdout", \
++ is_undocumented=true, \
++ type=String, \
++ params="<output console>", \
++ desc="Redirect stdout to a filename or to another tty, e.g. stderr." \
+ }
+
+-nashorn.option.stderr = { \
+- name="--stderr", \
+- is_undocumented=true, \
+- type=String, \
+- params="<output console>", \
+- desc="Redirect stderr to a filename or to another tty, e.g. stdout" \
++nashorn.option.stderr = { \
++ name="--stderr", \
++ is_undocumented=true, \
++ type=String, \
++ params="<output console>", \
++ desc="Redirect stderr to a filename or to another tty, e.g. stdout." \
+ }
+
+ nashorn.option.timezone = { \
+@@ -363,14 +370,14 @@
+ type=Locale \
+ }
+
+-nashorn.option.trace.callsites = { \
+- name="--trace-callsites", \
+- short_name="-tcs", \
+- is_undocumented=true, \
+- type=keyvalues, \
+- params="[=[option,]*]", \
+- desc="Enable callsite trace mode. Options are: miss [trace callsite misses] \
+- enterexit [trace callsite enter/exit], objects [print object properties]" \
++nashorn.option.trace.callsites = { \
++ name="--trace-callsites", \
++ short_name="-tcs", \
++ is_undocumented=true, \
++ type=keyvalues, \
++ params="[=[option,]*]", \
++ desc="Enable callsite trace mode. Options are: miss [trace callsite misses] \
++ enterexit [trace callsite enter/exit], objects [print object properties]." \
+ }
+
+ nashorn.option.verify.code = { \
+--- ./nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js Wed Feb 04 12:14:47 2015 -0800
+@@ -105,7 +105,7 @@
+ if (arguments.length < 1 || arguments.length > 2 ) {
+ throw "sync(function [,object]) parameter count mismatch";
+ }
+- return Packages.jdk.nashorn.api.scripting.ScriptUtils.makeSynchronizedFunction(func, syncobj);
++ return Java.synchronized(func, syncobj);
+ }
+ });
+
+@@ -160,7 +160,7 @@
+ configurable: true, enumerable: false, writable: true,
+ value: function(state) {
+ if (! state) {
+- state = java.util.Collections.newSetFromMap(new java.util.IdentityHashMap());
++ state = java.util.Collections.newSetFromMap(new java.util.HashMap());
+ }
+ if (state.contains(this)) {
+ return "{}";
+--- ./nashorn/src/jdk/nashorn/internal/scripts/JO.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/internal/scripts/JO.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package jdk.nashorn.internal.scripts;
+
++import jdk.nashorn.internal.codegen.SpillObjectCreator;
+ import jdk.nashorn.internal.runtime.PropertyMap;
+ import jdk.nashorn.internal.runtime.ScriptObject;
+
+@@ -63,6 +64,18 @@
+ }
+
+ /**
++ * Constructor that takes a pre-initialized spill pool. Used for
++ * by {@link SpillObjectCreator} for intializing object literals
++ *
++ * @param map property map
++ * @param primitiveSpill primitive spill pool
++ * @param objectSpill reference spill pool
++ */
++ public JO(final PropertyMap map, final long[] primitiveSpill, final Object[] objectSpill) {
++ super(map, primitiveSpill, objectSpill);
++ }
++
++ /**
+ * A method handle of this method is passed to the ScriptFunction constructor.
+ *
+ * @param map the property map to use for allocatorMap
+--- ./nashorn/src/jdk/nashorn/tools/Shell.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/src/jdk/nashorn/tools/Shell.java Wed Feb 04 12:14:47 2015 -0800
+@@ -41,6 +41,7 @@
+ import java.util.ResourceBundle;
+ import jdk.nashorn.api.scripting.NashornException;
+ import jdk.nashorn.internal.codegen.Compiler;
++import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
+ import jdk.nashorn.internal.ir.FunctionNode;
+ import jdk.nashorn.internal.ir.debug.ASTWriter;
+ import jdk.nashorn.internal.ir.debug.PrintVisitor;
+@@ -178,7 +179,6 @@
+ *
+ * @return null if there are problems with option parsing.
+ */
+- @SuppressWarnings("resource")
+ private static Context makeContext(final InputStream in, final OutputStream out, final OutputStream err, final String[] args) {
+ final PrintStream pout = out instanceof PrintStream ? (PrintStream) out : new PrintStream(out);
+ final PrintStream perr = err instanceof PrintStream ? (PrintStream) err : new PrintStream(err);
+@@ -225,6 +225,7 @@
+
+ /**
+ * Compiles the given script files in the command line
++ * This is called only when using the --compile-only flag
+ *
+ * @param context the nashorn context
+ * @param global the global scope
+@@ -245,12 +246,21 @@
+
+ // For each file on the command line.
+ for (final String fileName : files) {
+- final FunctionNode functionNode = new Parser(env, sourceFor(fileName, new File(fileName)), errors).parse();
++ final FunctionNode functionNode = new Parser(env, sourceFor(fileName, new File(fileName)), errors, env._strict, 0, context.getLogger(Parser.class)).parse();
+
+ if (errors.getNumberOfErrors() != 0) {
+ return COMPILATION_ERROR;
+ }
+
++ new Compiler(
++ context,
++ env,
++ null, //null - pass no code installer - this is compile only
++ functionNode.getSource(),
++ context.getErrorManager(),
++ env._strict | functionNode.isStrict()).
++ compile(functionNode, CompilationPhases.COMPILE_ALL_NO_INSTALL);
++
+ if (env._print_ast) {
+ context.getErr().println(new ASTWriter(functionNode));
+ }
+@@ -259,8 +269,9 @@
+ context.getErr().println(new PrintVisitor(functionNode));
+ }
+
+- //null - pass no code installer - this is compile only
+- new Compiler(env).compile(functionNode);
++ if (errors.getNumberOfErrors() != 0) {
++ return COMPILATION_ERROR;
++ }
+ }
+ } finally {
+ env.getOut().flush();
+@@ -390,7 +401,6 @@
+ * @param global global scope object to use
+ * @return return code
+ */
+- @SuppressWarnings("resource")
+ private static int readEvalPrint(final Context context, final Global global) {
+ final String prompt = bundle.getString("shell.prompt");
+ final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+@@ -436,19 +446,16 @@
+ continue;
+ }
+
+- Object res;
+ try {
+- res = context.eval(global, source, global, "<shell>", env._strict);
++ final Object res = context.eval(global, source, global, "<shell>", env._strict);
++ if (res != ScriptRuntime.UNDEFINED) {
++ err.println(JSType.toString(res));
++ }
+ } catch (final Exception e) {
+ err.println(e);
+ if (env._dump_on_error) {
+ e.printStackTrace(err);
+ }
+- continue;
+- }
+-
+- if (res != ScriptRuntime.UNDEFINED) {
+- err.println(JSType.toString(res));
+ }
+ }
+ } finally {
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/examples/apply_to_call_benchmark.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,68 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * - Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * - Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * - Neither the name of Oracle nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++var Class = {
++ create: function() {
++ return function() { //vararg
++ this.initialize.apply(this, arguments);
++ }
++ }
++};
++
++Color = Class.create();
++Color.prototype = {
++ red: 0, green: 0, blue: 0,
++ initialize: function(r,g,b) {
++ this.red = r;
++ this.green = g;
++ this.blue = b;
++ }
++}
++
++function bench(x) {
++ var d = new Date;
++ var colors = new Array(16);
++ for (var i=0;i<1e8;i++) {
++ colors[i&0xf] = (new Color(1,2,3));
++ }
++ print(new Date - d);
++ return colors;
++}
++bench(17);
++
++print("Swapping out call");
++Function.prototype.call = function() {
++ throw "This should not happen, apply should be called instead";
++};
++
++bench(17);
++
++print("All done!");
+--- ./nashorn/test/examples/array-micro.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/examples/array-micro.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/examples/charcodeat-benchmark.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,63 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Simple benchmark to measure charCodeAt specialized method performance
++ */
++
++var str = "sghjkdsfkjghsdfjkfkjdfkjdfjkdfjkfdjkfdkfldjfhdfpkjdhafgksdjfgldfgjldfkjgdlfjgldkfjgkldfj";
++var RESULT1 = 9187;
++var RESULT2 = 1496;
++
++function f() {
++ var len = str.length;
++ var c = 0;
++ for (var i = 0; i < len; i++) {
++ c += str.charCodeAt(i);
++ }
++ return c;
++}
++
++function bench(res) {
++ var d = new Date;
++ var sum = 0;
++ for (var i = 0; i < 1e6; i++) {
++ sum |= f();
++ }
++ if (sum == res) {
++ print("Verified OK");
++ } else {
++ print("Verification failed " + sum + " should be " + res);
++ }
++ print((new Date - d) + " ms");
++}
++
++bench(RESULT1);
++
++print("Replacing charCodeAt... ");
++
++String.prototype.charCodeAt = function() { return 17; }
++
++bench(RESULT2);
++
++print("Done");
+--- ./nashorn/test/examples/dual-fields-micro.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/examples/dual-fields-micro.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -34,15 +34,15 @@
+ }
+
+ var sum = 1;
+-function bench() {
++function bench() {
+ var d = new Date;
+
+ for (var iter = 0; iter <4*50e6; iter++) {
+- sum *= 20 * b(21,22);
++ sum *= 20 * b(21,22);
+ }
+
+ print("time = " +(new Date-d));
+- print(sum);
++ print(sum);
+ }
+
+ bench();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/examples/getter-setter-micro.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,81 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * - Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * - Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * - Neither the name of Oracle nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/*
++ * A micro-benchmark for getters and setters with primitive values,
++ * alternating between ints and doubles. Introduction of primitive
++ * and optimistic user accessors in JDK-8062401 make this faster by
++ * 10x or more by allowing inlining and other optimizations to take place.
++ */
++
++var x = {
++ get m() {
++ return this._m;
++ },
++ set m(v) {
++ this._m = v;
++ },
++ get n() {
++ return this._n;
++ },
++ set n(v) {
++ this._n = v;
++ }
++};
++
++
++function bench(v1, v2, result) {
++ var start = Date.now();
++ x.n = v1;
++ for (var i = 0; i < 1e8; i++) {
++ x.m = v2;
++ if (x.m + x.n !== result) {
++ throw "wrong result";
++ }
++ }
++ print("done in", Date.now() - start, "millis");
++}
++
++for (var i = 0; i < 10; i++) {
++ bench(i, 4, 4 + i);
++}
++
++for (var i = 0; i < 10; i++) {
++ bench(i, 4.5, 4.5 + i);
++}
++
++for (var i = 0; i < 10; i++) {
++ bench(i, 5, 5 + i);
++}
++
++for (var i = 0; i < 10; i++) {
++ bench(i, 5.5, 5.5 + i);
++}
+--- ./nashorn/test/examples/innerbench.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/examples/innerbench.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/test/examples/int-micro.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/examples/int-micro.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/examples/push-pop-benchmark.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Simple benchmark to measure push/pop specialized method performance
++ */
++
++var a = [];
++
++var RESULT = 15;
++
++function bench() {
++ var sum = 0;
++ for (var i=0;i<10;i++) {
++ a.push(i);
++ }
++ for (var i=0;i<10;i++) {
++ sum |= a.pop();
++ }
++ return sum;
++}
++
++function runbench() {
++ var sum = 0;
++ for (var iters = 0; iters<1e8; iters++) {
++ sum |= bench();
++ }
++ return sum;
++}
++
++var d = new Date;
++var res = runbench();
++print((new Date - d) + " ms");
++print();
++if (res != RESULT) {
++ print("ERROR: Wrong result - should be " + RESULT);
++} else {
++ print("Verified OK - result is correct");
++}
+--- ./nashorn/test/examples/string-micro.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/examples/string-micro.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -46,12 +46,18 @@
+ str[2];
+ });
+
+-bench("fromCharCode", function() {
++bench("fromCharCode 1", function() {
+ String.fromCharCode(97);
+ String.fromCharCode(98);
+ String.fromCharCode(99);
+ });
+
++bench("fromCharCode 2", function() {
++ String.fromCharCode(97, 98);
++ String.fromCharCode(97, 98, 99);
++ String.fromCharCode(97, 98, 99, 100);
++});
++
+ bench("charAt 1", function() {
+ str.charAt(0);
+ str.charAt(1);
+--- ./nashorn/test/examples/typechain.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/examples/typechain.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+--- ./nashorn/test/lib/benchmark.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/lib/benchmark.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -33,14 +33,14 @@
+ startTime = new Date,
+ runs = 0;
+ do {
+- method.apply(args);
+- runs++;
+- totalTime = new Date - startTime;
++ method.apply(args);
++ runs++;
++ totalTime = new Date - startTime;
+ } while (totalTime < timeInMillis);
+-
++
+ // convert ms to seconds
+ totalTime /= 1000;
+-
++
+ // period → how long per operation
+ period = totalTime / runs;
+
+--- ./nashorn/test/opt/add.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/opt/add.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * Example of an add function that gets specialized to doubles
+- * if run with --optimize flag set
++ * if run with --optimize flag set
+ */
+
+ function add(a,b) {
+@@ -34,7 +34,7 @@
+ function bench() {
+ var sum = 1;
+ for (var x = 0 ; x < 10e8/2 ; x ++) {
+- sum *= add(x,x + 1);
++ sum *= add(x,x + 1);
+ }
+ return sum;
+ }
+--- ./nashorn/test/opt/add_constant.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/opt/add_constant.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * Example of an add function that gets specialized to doubles
+- * if run with --optimize flag set
++ * if run with --optimize flag set
+ */
+
+ function add(a,b) {
+@@ -34,7 +34,7 @@
+ function bench() {
+ var sum = 1;
+ for (var x = 0 ; x < 5e7 ; x++) {
+- sum *= add(x, 17);
++ sum *= add(x, 17);
+ }
+ return sum;
+ }
+--- ./nashorn/test/opt/add_reuse_callsite.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/opt/add_reuse_callsite.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * Example of an add function that gets specialized to doubles
+- * if run with --optimize flag set
++ * if run with --optimize flag set
+ */
+
+ function add(a,b) {
+@@ -34,10 +34,10 @@
+ function bench() {
+ var sum = 1;
+ for (var x = 0 ; x < 5e7 ; x++) {
+- sum *= add(x,x + 1);
++ sum *= add(x,x + 1);
+ }
+ for (var x = 0; x < 5e7 ; x++) {
+- sum *= add(x + 2, x + 3);
++ sum *= add(x + 2, x + 3);
+ }
+ return sum;
+ }
+--- ./nashorn/test/opt/add_revert2.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/opt/add_revert2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * Example of an add function that gets specialized to doubles
+- * if run with --optimize flag set
++ * if run with --optimize flag set
+ */
+
+ function add(a,b) {
+@@ -34,8 +34,8 @@
+ function bench() {
+ var sum = 1;
+ for (var x = 0 ; x < 5e7 ; x++) {
+- sum *= add(x, 17);
+- sum *= add(x, x); //can use same revert as 17?
++ sum *= add(x, 17);
++ sum *= add(x, x); //can use same revert as 17?
+ }
+ return sum;
+ }
+--- ./nashorn/test/opt/cascade_specialize.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/opt/cascade_specialize.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -37,4 +37,4 @@
+ }
+
+ test();
+-
++
+--- ./nashorn/test/script/assert.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/assert.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,8 +28,8 @@
+ */
+
+ // Assert is TestNG's Assert class
+-Object.defineProperty(this, "Assert", {
+- configuable: true,
++Object.defineProperty(this, "Assert", {
++ configurable: true,
+ enumerable: false,
+ writable: true,
+ value: Packages.org.testng.Assert
+@@ -37,10 +37,10 @@
+
+ // fail function to call TestNG Assert.fail
+ Object.defineProperty(this, "fail", {
+- configuable: true,
++ configurable: true,
+ enumerable: false,
+ writable: true,
+- // 'error' is optional. if present it has to be
++ // 'error' is optional. if present it has to be
+ // an ECMAScript Error object or java Throwable object
+ value: function (message, error) {
+ var throwable = null;
+@@ -63,7 +63,7 @@
+ });
+
+ Object.defineProperty(this, "printError", {
+- configuable: true,
++ configurable: true,
+ enumerable: false,
+ writable: true,
+ value: function (e) {
+--- ./nashorn/test/script/basic/8024180/global_var_delete.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/8024180/global_var_delete.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/8024180/global_var_shadow.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/8024180/global_var_shadow.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/8024180/scope_no_such_prop.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/8024180/scope_no_such_prop.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/8024180/with_expr_prop_add.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/8024180/with_expr_prop_add.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -42,7 +42,7 @@
+ if (i == 0) {
+ p.x = "p.x";
+ }
+- }
++ }
+ }
+ }
+
+--- ./nashorn/test/script/basic/8024180/with_java_object.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/8024180/with_java_object.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8005958.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8005958.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * JDK-8005958 : invoking a function through INVOKESTATIC with more
++ * JDK-8005958 : invoking a function through INVOKESTATIC with more
+ * arguments than it declares resulted in malformed bytecode being
+ * generated.
+ *
+--- ./nashorn/test/script/basic/JDK-8006304.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8006304.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,26 +1,26 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+-
++
+ /**
+ * JDK-8006304 : Remove pre-population of maps for constructor produced maps.
+ *
+--- ./nashorn/test/script/basic/JDK-8006337.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8006337.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * JDK-8006337 : Discarded arguments for INVOKESTATIC must still be
++ * JDK-8006337 : Discarded arguments for INVOKESTATIC must still be
+ * evaluated for side effects.
+ *
+ * @test
+--- ./nashorn/test/script/basic/JDK-8006529-b.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8006529-b.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -62,4 +62,4 @@
+ for(var i in x) {
+ print("Doing " + i)
+ new x[i]()
+-}
+\ No newline at end of file
++}
+--- ./nashorn/test/script/basic/JDK-8006570.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8006570.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -57,4 +57,4 @@
+ strict.call(null);
+ strict.call("foo");
+ strict.call(1);
+-strict.call(true);
+\ No newline at end of file
++strict.call(true);
+--- ./nashorn/test/script/basic/JDK-8006852a.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8006852a.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -27,24 +27,24 @@
+ * @test
+ * @run
+ */
+-
+-function Field(val){
+- this.value = val;
+-}
+-var times = 0;
+-
+-Field.prototype = {
+- get value(){
+- print("GETTER!");
+- return this._value;
+- },
+- set value(val){
+- print("SETTER!");
+- this._value = val + (++times);
+- }
+-};
+-
+-var f = new Field("test");
+-print(f.value);
+-f.value = "test2";
++
++function Field(val){
++ this.value = val;
++}
++var times = 0;
++
++Field.prototype = {
++ get value(){
++ print("GETTER!");
++ return this._value;
++ },
++ set value(val){
++ print("SETTER!");
++ this._value = val + (++times);
++ }
++};
++
++var f = new Field("test");
+ print(f.value);
++f.value = "test2";
++print(f.value);
+--- ./nashorn/test/script/basic/JDK-8006852b.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8006852b.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -27,7 +27,7 @@
+ * @test
+ * @run
+ */
+-
++
+ function MyCons(arg) {
+ if (arg == 2) {
+ this.foo = 3;
+--- ./nashorn/test/script/basic/JDK-8006857.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8006857.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8006983.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8006983.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8006984.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8006984.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,22 +23,22 @@
+
+ /**
+ * findProperty on WithObject was not considering its object argument
+- *
++ *
+ * @test
+ * @run
+ */
+
+-var guiPkgs = { JFrame: function() { print("created"); } };
++var guiPkgs = { JFrame: function() { print("created"); } };
+
+-with (guiPkgs) {
+- var main = function() {
++with (guiPkgs) {
++ var main = function() {
+ var frame; // <---- this local variable caused scope to be not set properly prior to fix
+
+- function createFrame() {
+- frame = new JFrame();
+- }
++ function createFrame() {
++ frame = new JFrame();
++ }
+
+- createFrame();
+- }
+-}
++ createFrame();
++ }
++}
+ main();
+--- ./nashorn/test/script/basic/JDK-8007060.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8007060.js Wed Feb 04 12:14:47 2015 -0800
+@@ -91,4 +91,4 @@
+ [1, 2, 3].filter(F, "hello");
+ [1, 2, 3].filter(F, 1);
+ [1, 2, 3].filter(F, {});
+-[1, 2, 3].filter(F, "hello");
+\ No newline at end of file
++[1, 2, 3].filter(F, "hello");
+--- ./nashorn/test/script/basic/JDK-8007140.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8007140.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8007215.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8007215.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * Varargs based on too many parameters broke. Regression test.
+- *
++ *
+ * @test
+ * @run
+ */
+@@ -31,11 +31,11 @@
+ function f() {
+ var sum = 0;
+ for (var i = 0; i < arguments.length; i++) {
+- var a = arguments[i];
+- sum += a;
++ var a = arguments[i];
++ sum += a;
+ }
+ return sum;
+-}
++}
+
+ var res;
+
+--- ./nashorn/test/script/basic/JDK-8007460.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8007460.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -37,4 +37,4 @@
+ print(y)
+ print(arguments[0])
+ }
+-f(2)
+\ No newline at end of file
++f(2)
+--- ./nashorn/test/script/basic/JDK-8007522.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8007522.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8007523.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8007523.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * JDK-8007523: VerifyError on script that uses regular expression literals with ternary operator
++ * JDK-8007523: VerifyError on script that uses regular expression literals with ternary operator
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/JDK-8007619.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8007619.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -37,11 +37,11 @@
+ while (match != null) {
+ print("Match = " + match);
+ print("RegExp.lastMatch = " + RegExp.lastMatch);
+-
++
+ print("RegExp.$1 = " + RegExp.$1);
+ print("RegExp.$2 = " + RegExp.$2);
+ print("RegExp.$3 = " + RegExp.$3);
+-
++
+ print("RegExp.lastParen = " + RegExp.lastParen)
+ print("RegExp.input = " + RegExp.input);
+
+--- ./nashorn/test/script/basic/JDK-8007990.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8007990.js Wed Feb 04 12:14:47 2015 -0800
+@@ -22,15 +22,15 @@
+ */
+
+ /**
+- * JDK-8007990: Access methods declared on public interfaces implemented by
++ * JDK-8007990: Access methods declared on public interfaces implemented by
+ * non-public classes
+ *
+ * @test
+ * @run
+ */
+
+-var p = new Packages.java.io.File("test/script/basic/JDK-8007990.js");
+-var path = p.toPath();
+-var basicView = Packages.java.nio.file.Files.getFileAttributeView(path, Packages.java.nio.file.attribute.BasicFileAttributeView.class);
++var p = new Packages.java.io.File("test/script/basic/JDK-8007990.js");
++var path = p.toPath();
++var basicView = Packages.java.nio.file.Files.getFileAttributeView(path, Packages.java.nio.file.attribute.BasicFileAttributeView.class);
+ // We just want to confirm we can access the readAttributes() function
+ print(basicView.readAttributes().directory);
+--- ./nashorn/test/script/basic/JDK-8008197.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8008197.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -33,7 +33,7 @@
+ var e = m.getEngineByName("nashorn");
+
+ var obj = {
+- func: function(str) {
++ func: function(str) {
+ return /hello/.exec(str);
+ }
+ };
+--- ./nashorn/test/script/basic/JDK-8008206.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8008206.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,9 +28,9 @@
+ * @run
+ */
+
+-var x = 1;
++var x = 1;
+
+-switch (x) {
+- case foo = false, 1:
+- print("ok");
+-}
++switch (x) {
++ case foo = false, 1:
++ print("ok");
++}
+--- ./nashorn/test/script/basic/JDK-8008238.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8008238.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8008554.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8008554.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8008814-3.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8008814-3.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8008814-4.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8008814-4.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8009553.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8009553.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8009868.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8009868.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8010697.js Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,59 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-/**
+- * JDK-8010697: DeletedArrayFilter seems to leak memory
+- *
+- * @test
+- * @run
+- */
+-
+-var N = 1000;
+-
+-var array = new Array(N);
+-var WeakReferenceArray = Java.type("java.lang.ref.WeakReference[]");
+-var refArray = new WeakReferenceArray(N);
+-
+-for (var i = 0; i < N; i ++) {
+- var object = new java.lang.Object();
+- array[i] = object;
+- refArray[i] = new java.lang.ref.WeakReference(object);
+-}
+-
+-object = null;
+-
+-for (var i = 0; i < N; i ++) {
+- delete array[i];
+-}
+-
+-java.lang.System.gc();
+-java.lang.System.gc();
+-
+-for (var i = 0; i < N; i ++) {
+- if (refArray[i].get() != null) {
+- print("Reference found at " + i);
+- exit(0);
+- }
+-}
+-
+-print("All references gone");
+--- ./nashorn/test/script/basic/JDK-8010697.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,1 +0,0 @@
+-All references gone
+--- ./nashorn/test/script/basic/JDK-8010709.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8010709.js Wed Feb 04 12:14:47 2015 -0800
+@@ -22,7 +22,7 @@
+ */
+
+ /**
+- * JDK-8010709 org on the top level doesn't resolve
++ * JDK-8010709 org on the top level doesn't resolve
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/JDK-8010710.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8010710.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -26,7 +26,7 @@
+ * as array index in self modifying assigns
+ *
+ * @test
+- * @run
++ * @run
+ */
+ function zero() {
+ return 0;
+@@ -38,9 +38,9 @@
+ print(b[zero() + 1][2 + a[0]] += 10);
+
+ //repro for NASHORN-258 that never made it
+-function AddRoundKey() {
+- var r=0;
+- state[r][1] &= 17;
++function AddRoundKey() {
++ var r=0;
++ state[r][1] &= 17;
+ }
+
+ var srcFiles = [];
+@@ -52,7 +52,7 @@
+ //this broke the javafx build system. verify it works
+ function bouncingBall() {
+ for (j=0; j<100; j++) {
+- added += srcFiles[j];
++ added += srcFiles[j];
+ }
+ }
+ bouncingBall();
+@@ -61,7 +61,7 @@
+ //this is how they should have done it for speed, that works always, verify this too
+ function bouncingBall2() {
+ for (var k=0; k<100; k++) {
+- added += srcFiles[k];
++ added += srcFiles[k];
+ }
+ }
+ bouncingBall2();
+--- ./nashorn/test/script/basic/JDK-8010720.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8010720.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8010731.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,64 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8010731: Nashorn exposes internal symbols such as __callee__, __scope__ to scripts
++ *
++ * @test
++ * @run
++ */
++
++function checkCallee() {
++ var x = arguments[0]; // force __callee__ (renamed as :callee)
++
++ print(__callee__);
++}
++
++try {
++ checkCallee();
++ fail("Should have thrown ReferenceError for __callee__");
++} catch (e) {
++ if (! (e instanceof ReferenceError)) {
++ fail("ReferenceError expected, got " + e);
++ }
++}
++
++function checkScope() {
++ var x = 334;
++
++ function inner() {
++ var y = x * x; // force __scope__ (renamed as :scope")
++ print(__scope__);
++ }
++
++ inner();
++}
++
++try {
++ checkScope();
++ fail("Should have thrown ReferenceError for __scope__");
++} catch (e) {
++ if (! (e instanceof ReferenceError)) {
++ fail("ReferenceError expected, got " + e);
++ }
++}
+--- ./nashorn/test/script/basic/JDK-8010804.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8010804.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -83,4 +83,4 @@
+
+ var d = new Date();
+ d.setYear(Infinity);
+-print(d);
+\ No newline at end of file
++print(d);
+--- ./nashorn/test/script/basic/JDK-8010946-privileged.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8010946-privileged.js Wed Feb 04 12:14:47 2015 -0800
+@@ -25,7 +25,7 @@
+ * JDK-8010946: AccessController.doPrivileged() doesn't work as expected.
+ * This is actually a broader issue of having Dynalink correctly handle
+ * caller-sensitive methods.
+- *
++ *
+ * NOTE: This is not a standalone test file, it is loaded by JDK-801946.js
+ * @subtest
+ */
+--- ./nashorn/test/script/basic/JDK-8010946.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8010946.js Wed Feb 04 12:14:47 2015 -0800
+@@ -34,7 +34,7 @@
+ load(__DIR__ + "JDK-8010946-privileged.js")
+
+ try {
+- // This should fail, even though the code itself resides in the
++ // This should fail, even though the code itself resides in the
+ // privileged script, as we're invoking it without going through
+ // doPrivileged()
+ print("Attempting unprivileged execution...")
+--- ./nashorn/test/script/basic/JDK-8011023.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011023.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * Round should be ecma compliant
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ print(1/Math.round(-0.5));
+--- ./nashorn/test/script/basic/JDK-8011209.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011209.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8011237.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011237.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8011274.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011274.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8011357.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011357.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8011362.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011362.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8011365.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011365.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,7 +30,7 @@
+
+ try {
+ Array.prototype.join.call(null, { toString:function() { throw 2 } });
+- fail("should have thrown TypeError");
++ fail("should have thrown TypeError");
+ } catch (e) {
+ if (! (e instanceof TypeError)) {
+ fail("TypeError expected, got " + e);
+@@ -46,7 +46,7 @@
+ if (funcName == "constructor") {
+ continue;
+ }
+-
++
+ var prop = Array.prototype[funcName];
+ if (prop instanceof Function) {
+ // try 'null' this
+--- ./nashorn/test/script/basic/JDK-8011382.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011382.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * JDK-8011382: Data prototype methods and constructor do not call user defined toISOString, valueOf methods per spec.
++ * JDK-8011382: Data prototype methods and constructor do not call user defined toISOString, valueOf methods per spec.
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/JDK-8011394.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011394.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8011552.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011552.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8011555.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011555.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -35,7 +35,7 @@
+ } catch(e) {
+ // We expect to get a TypeError for trying to use __noSuchMethod__ as
+ // a constructor. Before we fixed this bug, we were getting a runtime
+- // exception with MH type mismatch on a MH.foldArguments within the
++ // exception with MH type mismatch on a MH.foldArguments within the
+ // WithObject code instead.
+ print(e)
+ }
+--- ./nashorn/test/script/basic/JDK-8011578.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011578.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8011718.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011718.js Wed Feb 04 12:14:47 2015 -0800
+@@ -28,19 +28,19 @@
+ * @run
+ */
+
+-var obj = {
+- hello:"From obj",
+-};
+-var obj2 = {
+- hello:"From obj2",
+-};
++var obj = {
++ hello:"From obj",
++};
++var obj2 = {
++ hello:"From obj2",
++};
+
+-function doit(cb){
+- cb();
+- var cb2 = cb.bind(obj2, "This one is not acccepted");
+- cb2();
+-}
++function doit(cb){
++ cb();
++ var cb2 = cb.bind(obj2, "This one is not acccepted");
++ cb2();
++}
+
+-doit(function(){
+- print(this.hello);
++doit(function(){
++ print(this.hello);
+ }.bind(obj));
+--- ./nashorn/test/script/basic/JDK-8011756.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011756.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8011893.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011893.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8011960.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011960.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8011964.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011964.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8011974.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8011974.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8012083.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8012083.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * JDK-8012093 - array literals can only be subject to constant evaluation under very special
++ * JDK-8012083 - array literals can only be subject to constant evaluation under very special
+ * circumstances.
+ *
+ * @test
+--- ./nashorn/test/script/basic/JDK-8012164.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8012164.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -46,11 +46,11 @@
+
+ func();
+
+-// See JDK-8015855: test/script/basic/JDK-8012164.js fails on Windows
++// See JDK-8015855: test/script/basic/JDK-8012164.js fails on Windows
+ // Replace '\' to '/' in class and file names of StackFrameElement objects
+ function printFrame(stack) {
+ var fileName = stack.fileName.replace(/\\/g, '/');
+ var className = stack.className.replace(/\\/g, '/');
+ print(className + '.' + stack.methodName + '(' +
+- fileName + ':' + stack.lineNumber + ')');
++ fileName + ':' + stack.lineNumber + ')');
+ }
+--- ./nashorn/test/script/basic/JDK-8012191.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8012191.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,7 +28,7 @@
+ * @run
+ */
+
+-// ClassCastException: Cannot cast java.lang.String to [Ljava.lang.Object;
++// ClassCastException: Cannot cast java.lang.String to [Ljava.lang.Object;
+ __noSuchProperty__ = function() {
+ print("obj.__noSuchProperty__ invoked for " + arguments[0]);
+ }
+--- ./nashorn/test/script/basic/JDK-8012240.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8012240.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -33,15 +33,15 @@
+ try {
+ Array.prototype.map.call(
+ {
+- length: -1,
++ length: -1,
+ get 0() {
+ in_getter_for_0 = true;
+ throw 0;
+ }
+- },
++ },
+ function(){}).length;
+ } catch (e) {
+ if (e !== 0 || !in_getter_for_0) {
+ fail("should have thrown error from getter for '0'th element");
+ }
+-}
++}
+--- ./nashorn/test/script/basic/JDK-8012291.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8012291.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8012305.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8012305.js Wed Feb 04 12:14:47 2015 -0800
+@@ -22,7 +22,7 @@
+ */
+
+ /**
+- * JDK-8012305: Function.bind can't be called on prototype function inside constructor
++ * JDK-8012305: Function.bind can't be called on prototype function inside constructor
+ *
+ * @test
+ * @run
+@@ -36,4 +36,4 @@
+
+ MyObject.prototype._process = function() { print("Message "); }
+
+-var s = new MyObject();
++var s = new MyObject();
+--- ./nashorn/test/script/basic/JDK-8012457.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8012457.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -35,7 +35,7 @@
+ // getter should be called
+ var getter_0_called = false;
+
+-Function().apply(null,
++Function().apply(null,
+ Object.defineProperty([],"0",
+ { get: function(){ getter_0_called = true; return 0 }
+ })
+--- ./nashorn/test/script/basic/JDK-8012462.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8012462.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8013131.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8013131.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8013167.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8013167.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,4 +29,4 @@
+ */
+
+ var x = new Packages.jdk.nashorn.test.models.VarArgConstructor(1, false, "a", "b", "c")
+-print(x.indicator)
+\ No newline at end of file
++print(x.indicator)
+--- ./nashorn/test/script/basic/JDK-8013325.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8013325.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -33,9 +33,9 @@
+ // x doesn't see an arguments object as it has a nested function with that name
+ // so it'll invoke the function.
+ arguments("a", "b", "c");
+-
++
+ function arguments(x, y, z) {
+- // The function 'arguments' OTOH can't see itself; if it uses the
++ // The function 'arguments' OTOH can't see itself; if it uses the
+ // identifier 'arguments', it'll see its own arguments object.
+ print(arguments)
+ print(x + " " + y + " " + z)
+--- ./nashorn/test/script/basic/JDK-8013337.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8013337.js Wed Feb 04 12:14:47 2015 -0800
+@@ -22,7 +22,7 @@
+ */
+
+ /**
+- * JDK-8013337: Issues with Date.prototype's get, set functions
++ * JDK-8013337: Issues with Date.prototype's get, set functions
+ *
+ * @test
+ * @option -timezone=Asia/Calcutta
+@@ -63,7 +63,7 @@
+ checkGetterCalled("setUTCMonth");
+
+ try {
+- Date.prototype.setTime.call({}, { valueOf: function() { throw "err" } })
++ Date.prototype.setTime.call({}, { valueOf: function() { throw "err" } })
+ } catch (e) {
+ if (! (e instanceof TypeError)) {
+ fail("TypeError expected, got " + e);
+--- ./nashorn/test/script/basic/JDK-8013444.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8013444.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -32,14 +32,14 @@
+ var type = typeof JSON.parse('{}',function(){})
+ print("type is " + type);
+
+-var obj = JSON.parse('{"name": "nashorn"}',
++var obj = JSON.parse('{"name": "nashorn"}',
+ function(k, v) {
+ if (k === "") return v;
+ return v.toUpperCase();
+ });
+ print(JSON.stringify(obj))
+
+-var array =
++var array =
+ JSON.parse("[1, 3, 5, 7, 9, 11]",
+ function(k, v) {
+ if (k === "") return v;
+--- ./nashorn/test/script/basic/JDK-8013729.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8013729.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8013873.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8013873.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8013874.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8013874.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8013878.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8013878.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8013919.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8013919.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -33,7 +33,7 @@
+ print("a");
+ } finally {
+ var b = function() {
+- print("b");
++ print("b");
+ }
+ b();
+ }
+--- ./nashorn/test/script/basic/JDK-8014426.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8014426.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8014647.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8014647.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8014781.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8014781.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8014785.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8014785.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -40,7 +40,7 @@
+ // update obj.x via foo.x
+ foo.x = "hello";
+ print("obj.x = " + obj.x); // prints "hello" now
+-
++
+ obj.x = 42; // foo.x also becomes 42
+ print("obj.x = " + obj.x); // prints 42
+ print("foo.x = " + foo.x); // prints 42
+--- ./nashorn/test/script/basic/JDK-8014953.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8014953.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -27,7 +27,7 @@
+ * @test
+ * @run
+ */
+-
++
+ try {
+ new java.util.ArrrayList(16)
+ } catch(e) {
+--- ./nashorn/test/script/basic/JDK-8015267.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015267.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -27,7 +27,7 @@
+ * @test
+ * @run
+ */
+-
++
+ var a = ['a', 'b', 'c', 'd']
+
+ var l = Java.to(a, java.util.List)
+@@ -64,10 +64,10 @@
+ l[7] = 'g'
+ print(a)
+
+-try { l.add(15, '') } catch(e) { print(e.class) }
+-try { l.remove(15) } catch(e) { print(e.class) }
+-try { l.add(-1, '') } catch(e) { print(e.class) }
+-try { l.remove(-1) } catch(e) { print(e.class) }
++try { l.add(15, '') } catch(e) { print(e.class) }
++try { l.remove(15) } catch(e) { print(e.class) }
++try { l.add(-1, '') } catch(e) { print(e.class) }
++try { l.remove(-1) } catch(e) { print(e.class) }
+
+ l.remove(7)
+ l.remove(2)
+--- ./nashorn/test/script/basic/JDK-8015345.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015345.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8015346.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015346.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8015347.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015347.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8015348.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015348.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8015349.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015349.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -32,7 +32,7 @@
+ print(code + " = " + eval(code));
+ }
+
+-printEval("'abc'.lastIndexOf('a', 4)");
++printEval("'abc'.lastIndexOf('a', 4)");
+ printEval("'abc'.lastIndexOf('b', Infinity)");
+ printEval("'abc'.lastIndexOf('a', -1)");
+ printEval("'abc'.lastIndexOf('a', -Infinity)");
+--- ./nashorn/test/script/basic/JDK-8015350.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015350.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8015352.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015352.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8015353.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015353.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8015354.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015354.js Wed Feb 04 12:14:47 2015 -0800
+@@ -22,7 +22,7 @@
+ */
+
+ /**
+- * JDK-8015354: JSON.parse should not use [[Put]] but use [[DefineOwnProperty]] instead
++ * JDK-8015354: JSON.parse should not use [[Put]] but use [[DefineOwnProperty]] instead
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/JDK-8015355.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015355.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * JDK-8015355: Array.prototype functions don't honour non-writable length and / or index properties
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/JDK-8015356.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015356.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * JDK-8015355: Array concatenation should ignore empty array elements.
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/JDK-8015357.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015357.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,8 +28,8 @@
+ * @run
+ */
+
+-var a = [];
+-a[0x7fffffff]=1;
++var a = [];
++a[0x7fffffff]=1;
+
+ if (a.sort()[0] != 1) {
+ fail("a.sort()[0] != 1");
+--- ./nashorn/test/script/basic/JDK-8015741.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015741.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8015830.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015830.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8015892.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015892.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,10 +29,10 @@
+ * @run
+ */
+
+-function doIt() {
+- if (something) {
+- x = x.obj;
+- } else {
+- var x = "x";
+- }
+-}
++function doIt() {
++ if (something) {
++ x = x.obj;
++ } else {
++ var x = "x";
++ }
++}
+--- ./nashorn/test/script/basic/JDK-8015945.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015945.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8015959.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015959.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8015969.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8015969.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -32,43 +32,26 @@
+ var m = new javax.script.ScriptEngineManager();
+ var e = m.getEngineByName("nashorn");
+
++e.put("fail", fail);
+ e.eval(<<EOF
+
+ 'use strict';
+
+ try {
+- context = 444;
+- print("FAILED!! context write should have thrown error");
+-} catch (e) {
+- if (! (e instanceof TypeError)) {
+- print("TypeError expected but got " + e);
+- }
+-}
+-
+-try {
+- engine = "hello";
+- print("FAILED!! engine write should have thrown error");
+-} catch (e) {
+- if (! (e instanceof TypeError)) {
+- print("TypeError expected but got " + e);
+- }
+-}
+-
+-try {
+ delete context;
+- print("FAILED!! context delete should have thrown error");
++ fail("FAILED!! context delete should have thrown error");
+ } catch (e) {
+ if (! (e instanceof SyntaxError)) {
+- print("SyntaxError expected but got " + e);
++ fail("SyntaxError expected but got " + e);
+ }
+ }
+
+ try {
+ delete engine;
+- print("FAILED!! engine delete should have thrown error");
++ fail("FAILED!! engine delete should have thrown error");
+ } catch (e) {
+ if (! (e instanceof SyntaxError)) {
+- print("SyntaxError expected but got " + e);
++ fail("SyntaxError expected but got " + e);
+ }
+ }
+
+--- ./nashorn/test/script/basic/JDK-8016235.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8016235.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,27 +23,27 @@
+
+ /**
+ * JDK-8016235 : use before definition in catch block generated erroneous bytecode
+- * as there is no guarantee anything in the try block has executed.
++ * as there is no guarantee anything in the try block has executed.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ function f() {
+ try {
+- var parser = {};
++ var parser = {};
+ } catch (e) {
+- parser = parser.context();
++ parser = parser.context();
+ }
+ }
+
+-function g() {
++function g() {
+ try {
+ return "apa";
+ } catch (tmp) {
+- //for now, too conservative as var ex declaration exists on the function
+- //level, but at least the code does not break, and the analysis is driven
+- //from the catch block (the rare case), not the try block (the common case)
++ //for now, too conservative as var ex declaration exists on the function
++ //level, but at least the code does not break, and the analysis is driven
++ //from the catch block (the rare case), not the try block (the common case)
+ var ex = new Error("DOM Exception 5");
+ ex.code = ex.number = 5;
+ return ex;
+--- ./nashorn/test/script/basic/JDK-8016239.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8016239.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8016518.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8016518.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8016542.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8016542.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8016618.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8016618.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -38,7 +38,7 @@
+ function func(x, y) {
+ print('func.x = ' + x);
+ print('func.x = ' + y)
+-};
++};
+
+ var obj = {
+ foo: 'hello',
+@@ -54,18 +54,30 @@
+ });
+
+ // load on mirror with local object as argument
+-global.load({
++global.load({
+ name: "code",
+ script: "print('x = ' + x)"
+ });
+
+ function f() {
+ // mirror function called with local arguments
++ // global.func.apply(obj, arguments);
+ global.func.apply(obj, arguments);
+ }
+
+ f(23, "hello");
+
++f(24, "hello2");
++
++var oldCall = Function.prototype.call;
++Function.prototype.call = function() {
++ throw "this should never happen! go back to apply!";
++};
++
++f(25, "hello3");
++
++Function.prototype.call = oldCall;
++
+ var fObject = global.eval("Object");
+
+ // instanceof on mirrors
+--- ./nashorn/test/script/basic/JDK-8016618.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8016618.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -1,6 +1,10 @@
+ x = 33
+ func.x = 23
+ func.x = hello
++func.x = 24
++func.x = hello2
++func.x = 25
++func.x = hello3
+ global instanceof fObject? true
+ x is wriable ? true
+ x value = 33
+--- ./nashorn/test/script/basic/JDK-8016667.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8016667.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -31,22 +31,22 @@
+ function toto() {
+ var friends = 1;
+ (joe = friends) == null;
+-}
++}
+
+ //JDK-8019476 duplicate case of this
+-Function("with(\nnull == (this % {}))( /x/g );");
++Function("with(\nnull == (this % {}))( /x/g );");
+
+ function f() {
+ with(null == (this % {}))(/x/g);
+ }
+
+-Function("return (null != [,,] <= this);");
++Function("return (null != [,,] <= this);");
+
+ function f2() {
+ return (null != [,,] <= this);
+ }
+
+-Function("/*infloop*/L:for(var x; ([+(function (window)[,,])(function(q) { return q; }, -0)].some(new Function)); [11,12,13,14].some) {/*infloop*/do {;return this; } while(x); }");
++Function("/*infloop*/L:for(var x; ([+(function (window)[,,])(function(q) { return q; }, -0)].some(new Function)); [11,12,13,14].some) {/*infloop*/do {;return this; } while(x); }");
+
+ function f3() {
+ /*infloop*/L:for(var x; ([+(function (window)[,,])(function(q) { return q; }, -0)].some(new Function)); [11,12,13,14].some) {/*infloop*/do {;return this; } while(x); }
+--- ./nashorn/test/script/basic/JDK-8016681.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8016681.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8017046.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8017046.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8017082.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8017082.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8017084.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8017084.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8017768.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8017768.js Wed Feb 04 12:14:47 2015 -0800
+@@ -23,7 +23,7 @@
+
+ /**
+ * JDK-8017768: Allow use of dot notation for inner class names.
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/JDK-8017950.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8017950.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -36,7 +36,7 @@
+ }
+ }
+
+-function f() {
++function f() {
+ func()
+ }
+
+--- ./nashorn/test/script/basic/JDK-8019226.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019226.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * JDK-8019226: line number not generated for first statement if it is on the same function declaration line
++ * JDK-8019226: line number not generated for first statement if it is on the same function declaration line
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/JDK-8019473.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019473.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8019478.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019478.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8019482.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019482.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8019488.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019488.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8019508.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019508.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8019553.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019553.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8019585.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019585.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,5 +30,5 @@
+ */
+
+ function f() {
+- var a = b == 17 && (a = toto(b)) && toto2(a);
++ var a = b == 17 && (a = toto(b)) && toto2(a);
+ }
+--- ./nashorn/test/script/basic/JDK-8019629.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019629.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * JDK-8019629: void operator should always evaluate to undefined
++ * JDK-8019629: void operator should always evaluate to undefined
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/JDK-8019783.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019783.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8019791.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019791.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8019805.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019805.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8019808.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019808.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,7 +28,7 @@
+ * @run
+ */
+
+-Function("switch([]) { case 7: }");
++Function("switch([]) { case 7: }");
+
+ function f() {
+ switch([]) {
+--- ./nashorn/test/script/basic/JDK-8019809.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019809.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,7 +28,7 @@
+ * @run
+ */
+
+-//Function("L: {break L;return; }");
++//Function("L: {break L;return; }");
+
+ function f() {
+ L: { break L; return; }
+--- ./nashorn/test/script/basic/JDK-8019810.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019810.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8019811.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019811.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,18 +30,18 @@
+
+ function f(x) {
+ var window = 17;
+- return function (x) {
+- return true
++ return function (x) {
++ return true
+ } (x) >> window;
+ }
+
+-Function("L:if((function x ()3)() + arguments++) {return; } else if (new gc()) while(((x2.prop = functional)) && 0){ }");
++Function("L:if((function x ()3)() + arguments++) {return; } else if (new gc()) while(((x2.prop = functional)) && 0){ }");
+
+-Function("var x = x -= '' ");
++Function("var x = x -= '' ");
+
+-Function("switch((Math.pow ? x = 1.2e3 : 3)) { default: return; }")
++Function("switch((Math.pow ? x = 1.2e3 : 3)) { default: return; }")
+
+ Function("x = 0.1, x\ntrue\n~this");
+
+ Function("with((function (x)x2)() ^ this){return; }");
+-
+\ No newline at end of file
++
+--- ./nashorn/test/script/basic/JDK-8019814.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019814.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -34,7 +34,7 @@
+ // java.lang.AssertionError: expecting integer type or object for jump, but found double
+ Function("with(\nnull == (this % {}))( /x/g );");
+
+-// java.lang.AssertionError: expecting equivalent types on stack but got double and int
++// java.lang.AssertionError: expecting equivalent types on stack but got double and int
+ try {
+ eval('Function("/*infloop*/while(((function ()4.)([z1,,], [,,]) - true++))switch(1e+81.x) { default: break; \u0009 }")');
+ } catch (e) {
+@@ -48,11 +48,11 @@
+ Function("return (null != [,,] <= this);");
+
+ // java.lang.AssertionError: Only return value on stack allowed at return point
+-// - depth=2 stack = jdk.nashorn.internal.codegen.Label$Stack@4bd0d62f
++// - depth=2 stack = jdk.nashorn.internal.codegen.Label$Stack@4bd0d62f
+ Function("x = 0.1, x\ntrue\n~this");
+
+ // java.lang.AssertionError: node NaN ~ window class jdk.nashorn.internal.ir.BinaryNode
+-// has no symbol! [object] function _L1()
++// has no symbol! [object] function _L1()
+ Function("throw NaN\n~window;");
+
+ // java.lang.AssertionError: array element type doesn't match array type
+@@ -65,9 +65,9 @@
+ }
+
+ // java.lang.AssertionError: stacks jdk.nashorn.internal.codegen.Label$Stack@4918f90f
+-// is not equivalent with jdk.nashorn.internal.codegen.Label$Stack@5f9b21a1 at join point
++// is not equivalent with jdk.nashorn.internal.codegen.Label$Stack@5f9b21a1 at join point
+ Function("if((null ^ [1]) !== (this.yoyo(false))) {var NaN, x;x\n~[,,z1] }");
+
+ // java.lang.AssertionError
+-// at jdk.nashorn.internal.codegen.Attr.enterFunctionBody(Attr.java:276)
+-Function("return (void ({ set each (x2)y }));");
++// at jdk.nashorn.internal.codegen.Attr.enterFunctionBody(Attr.java:276)
++Function("return (void ({ set each (x2)y }));");
+--- ./nashorn/test/script/basic/JDK-8019817.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019817.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,7 +29,7 @@
+ */
+ var y = 17.17;
+
+-Function("return y % function(q) { return q; }();");
++Function("return y % function(q) { return q; }();");
+
+ function f() {
+ return y % function(q) { return q; }();
+--- ./nashorn/test/script/basic/JDK-8019819.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019819.js Wed Feb 04 12:14:47 2015 -0800
+@@ -23,14 +23,14 @@
+
+ /**
+ * JDK-8019819: scope symbol didn't get a slot in certain cases
+- *
++ *
+ * @test
+ * @run
+ */
+ function f() {
+ try {
+- } catch(e if [].g(e)) {
+- with({}) {
++ } catch(e if [].g(e)) {
++ with({}) {
+ throw e;
+ }
+ }
+@@ -38,8 +38,8 @@
+
+ function g() {
+ try {
+- } catch(e) {
+- with({}) {
++ } catch(e) {
++ with({}) {
+ throw e;
+ }
+ }
+--- ./nashorn/test/script/basic/JDK-8019821.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019821.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,37 +1,37 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * JDK-8019821: boolean switch value accidentally triggered "allInts" case
++ * JDK-8019821: boolean switch value accidentally triggered "allInts" case
+ * as boolean is considered narrower than int. This caused a ClassCastException
+ *
+ * @test
+ * @run
+ */
+
+-function f() {
+- switch(gc()) {
+- case true:
+- case 1:
++function f() {
++ switch(gc()) {
++ case true:
++ case 1:
+ }
+ }
+--- ./nashorn/test/script/basic/JDK-8019822.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019822.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8019947.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019947.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8019963.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019963.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8019983.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019983.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -24,18 +24,18 @@
+ /**
+ * JDK-8019983.js return without expression combined with return with expression should produce object
+ * return type (undefined)
+- *
++ *
+ * @test
+ * @run
+ */
+
+
+-function g() {
+- switch(1) {
+- case 0:
+- case '':
++function g() {
++ switch(1) {
++ case 0:
++ case '':
+ default:
+- return;
++ return;
+ }
+ return 10;
+ }
+--- ./nashorn/test/script/basic/JDK-8019985.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8019985.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8020124.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8020124.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8020132.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8020132.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8020223.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8020223.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8020324.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8020324.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8020324.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8020324.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -17,7 +17,7 @@
+ bean.readWrite = 18: 18
+ obj1.readWrite: 18
+ obj1.getReadWrite(): 18
+-obj1.setReadWrite(19): null
++obj1.setReadWrite(19): undefined
+ obj1.readWrite: 19
+ bean.readWrite: 19
+
+@@ -52,7 +52,7 @@
+ PropertyBind.staticReadWrite = 26: 26
+ obj2.staticReadWrite: 26
+ obj2.getStaticReadWrite(): 26
+-obj2.setStaticReadWrite(27): null
++obj2.setStaticReadWrite(27): undefined
+ obj2.staticReadWrite: 27
+ PropertyBind.staticReadWrite: 27
+
+--- ./nashorn/test/script/basic/JDK-8020325.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8020325.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8020354.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8020354.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8020355.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8020355.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8020356.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8020356.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8020357.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8020357.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -35,7 +35,7 @@
+
+ // A value over the limit should throw a RangeError.
+ try {
+- Int32Array(limit)
++ new Int32Array(limit)
+ } catch(e) {
+ print(e)
+ }
+--- ./nashorn/test/script/basic/JDK-8020358.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8020358.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8020380.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8020380.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8020437.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8020437.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8020463.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8020463.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8020508.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8020508.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * JDK-8020508: Enforce reflection check on
++ * JDK-8020508: Enforce reflection check on
+ * Object.bindProperties(target, source) for beans
+ *
+ * @test
+--- ./nashorn/test/script/basic/JDK-8021122.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8021122.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8022598.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8022598.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8022731.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8022731.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8022903.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8022903.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -43,7 +43,7 @@
+
+ var capitals = new java.util.LinkedHashMap()
+ capitals.Sweden = "Stockholm"
+-capitals.Hungary = "Budapet"
++capitals.Hungary = "Budapest"
+ capitals.Croatia = "Zagreb"
+
+ for(var key in capitals) {
+--- ./nashorn/test/script/basic/JDK-8022903.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8022903.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -5,8 +5,8 @@
+ purple
+ pink
+ capital of Sweden is Stockholm
+-capital of Hungary is Budapet
++capital of Hungary is Budapest
+ capital of Croatia is Zagreb
+ Stockholm
+-Budapet
++Budapest
+ Zagreb
+--- ./nashorn/test/script/basic/JDK-8023026.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8023026.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8023373.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8023373.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -50,7 +50,7 @@
+ write: function(s, off, len) {
+ s = capitalize(s)
+ // Must handle overloads by arity
+- if(off === undefined) {
++ if(off === undefined) {
+ cw.super$write(s, 0, s.length())
+ } else if (typeof s === "string") {
+ cw.super$write(s, off, len)
+--- ./nashorn/test/script/basic/JDK-8023531.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8023531.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8023551.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8023551.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8023630.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8023630.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -50,7 +50,7 @@
+ write: function(s, off, len) {
+ s = capitalize(s)
+ // Must handle overloads by arity
+- if(off === undefined) {
++ if(off === undefined) {
+ cw_super.write(s, 0, s.length())
+ } else if (typeof s === "string") {
+ cw_super.write(s, off, len)
+--- ./nashorn/test/script/basic/JDK-8023650.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8023650.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8023780.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8023780.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8023784.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8023784.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8024120.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8024120.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8024174.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8024174.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8024255.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8024255.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -39,9 +39,9 @@
+ }
+ }
+
+-var obj = {
++var obj = {
+ default: 344,
+- in: 'hello',
++ in: 'hello',
+ if: false,
+ class: 4.223
+ }
+--- ./nashorn/test/script/basic/JDK-8024512.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8024512.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8024619.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8024619.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8024846.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8024846.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8024847.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8024847.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -79,7 +79,7 @@
+ var __array__ = [ "nashorn", "js" ];
+
+ var obj = new JSObject() {
+-
++
+ hasMember: function(name) {
+ return name in __array__;
+ },
+--- ./nashorn/test/script/basic/JDK-8024972.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8024972.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8025048-2.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025048-2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,7 +29,7 @@
+ */
+
+ function func(x) {
+- switch(x) {
++ switch(x) {
+ case 8: break; case false:
+ }
+ }
+--- ./nashorn/test/script/basic/JDK-8025048.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025048.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,7 +29,7 @@
+ */
+
+ function func(x) {
+- switch(x) {
++ switch(x) {
+ case 8: break; case true:
+ }
+ }
+--- ./nashorn/test/script/basic/JDK-8025080.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025080.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8025090.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025090.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8025111.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025111.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8025147.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025147.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8025149.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025149.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8025163.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025163.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8025197.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025197.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8025213.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025213.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8025312.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025312.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8025325.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025325.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8025434.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025434.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8025486.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025486.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8025488.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025488.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -39,5 +39,5 @@
+ return this.arr.toString();
+ }
+
+-var e = new MyError();
++var e = new MyError();
+ print(e.stack.replace(/\\/g, '/'));
+--- ./nashorn/test/script/basic/JDK-8025515.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025515.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -47,7 +47,7 @@
+ var stack = e.nashornException.getStackTrace();
+ var name = getFirstScriptFrame(stack).methodName;
+ if (name !== expected) {
+- fail("got " + stack[0].methodName + ", expected " + expected);
++ fail("got " + name + ", expected " + expected);
+ }
+ }
+ }
+@@ -61,7 +61,7 @@
+ var f = (function() {
+ return function() { a.b.c; };
+ })();
+-testMethodName(f, "L:61$L:62");
++testMethodName(f, "f$L:62");
+
+ testMethodName((function() {
+ return function() { return a.b.c; };
+--- ./nashorn/test/script/basic/JDK-8025520.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025520.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8025589.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8025589.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026008.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026008.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026016.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026016.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026033.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026033.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026042.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026042.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026048.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026048.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026112.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026112.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026125.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026125.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026137.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026137.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * JDK-8026137: Binary evaluation order in JavaScript is load load
++ * JDK-8026137: Binary evaluation order in JavaScript is load load
+ * convert convert, not load convert load convert.
+ *
+ * @test
+@@ -30,14 +30,16 @@
+ */
+
+ try {
+- (function f() { Object.defineProperty({},"x",{get: function(){return {valueOf:function(){throw 0}}}}).x - Object.defineProperty({},"x",{get: function(){throw 1}}).x })()
+-}
++ (function f() {
++ Object.defineProperty({},"x",{get: function(){return {valueOf:function(){throw 0}}}}).x -
++ Object.defineProperty({},"x",{get: function(){throw 1}}).x })()
++}
+ catch (e) {
+ print(e);
+ }
+
+ try {
+- ({valueOf: function(){throw 0}}) - ({valueOf: function(){throw 1}} - 1)
++ ({valueOf: function(){throw 0}}) - ({valueOf: function(){throw 1}} - 1)
+ } catch (e) {
+ print(e);
+ }
+--- ./nashorn/test/script/basic/JDK-8026161.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026161.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026162.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026162.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026167.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026167.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -37,7 +37,7 @@
+ e.eval('function f() { var e = 33; eval("e") } f()');
+
+ function f() {
+- Function.call.call(function x() { eval("x") }); eval("x")
++ Function.call.call(function x() { eval("x") }); eval("x")
+ }
+
+ try {
+--- ./nashorn/test/script/basic/JDK-8026248.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026248.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,7 +30,7 @@
+
+ load('nashorn:mozilla_compat.js')
+
+-importClass(java.io.File, java.io.InputStream)
++importClass(java.io.File, java.io.InputStream)
+
+ print(File)
+ print(InputStream)
+--- ./nashorn/test/script/basic/JDK-8026264.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026264.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026292.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026292.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026302.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026302.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -45,4 +45,4 @@
+ var desc = Object.getOwnPropertyDescriptor(obj, prop);
+ print(desc.get);
+ print(desc.set);
+-}
++}
+--- ./nashorn/test/script/basic/JDK-8026317.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026317.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026367.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026367.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026692.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026692.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026693.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026693.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026701.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026701.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026805.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026805.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026858.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026858.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8026955.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8026955.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8027016.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8027016.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8027024.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8027024.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * JDK-8027024: String.prototype.charAt and charCodeAt do not evaluate 'self' and 'pos' arguments in right order
++ * JDK-8027024: String.prototype.charAt and charCodeAt do not evaluate 'self' and 'pos' arguments in right order
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/JDK-8027042.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8027042.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -26,33 +26,35 @@
+ *
+ * @test
+ * @run
++ * @fork
+ */
+
+ // var with getter side effect
+-Object.defineProperty(this, "a", { get: function() {print("get a"); return 1; }});
++Object.defineProperty(this, "a1", { get: function() {print("get a"); return 1; }});
+
+ // var with both getter and conversion side effect
+-Object.defineProperty(this, "b", { get: function() {print("get b"); return {valueOf: function() { print("conv b"); return 10; }}; }});
++Object.defineProperty(this, "b1", { get: function() {print("get b"); return {valueOf: function() { print("conv b"); return 10; }}; }});
+
+ (function() {
+ // var with toPrimitive conversion side effect
+- var c = {valueOf: function() { print("conv c"); return 100; }};
+-
+- print(b + (c + a));
+- print(b + (c + b));
+- print(b + (a + b));
+- print(b + (b + c));
+- print(b + (b + c));
+- print(b + (c + (a - b)));
+- print(b + (c + (c - b)));
+- print(b + (c + (b - c)));
+- print(b + (b + (a ? 2 : 3)));
+- print(b + (b + (b ? 2 : 3)));
+- print(b + (b + (c ? 2 : 3)));
+- print(b + ((-c) + (-a)));
+- print(b + ((-c) + (-b)));
+- print(b + ((-c) + (-c)));
+- try { print(b + new a); } catch (e) {}
+- try { print(b + new b); } catch (e) {}
+- try { print(b + new c); } catch (e) {}
++ var c1 = {valueOf: function() { print("conv c"); return 100; }};
++ print("start");
++ print(b1 + (c1 + a1));
++ print("done with first");
++ print(b1 + (c1 + b1));
++ print(b1 + (a1 + b1));
++ print(b1 + (b1 + c1));
++ print(b1 + (b1 + c1));
++ print(b1 + (c1 + (a1 - b1)));
++ print(b1 + (c1 + (c1 - b1)));
++ print(b1 + (c1 + (b1 - c1)));
++ print(b1 + (b1 + (a1 ? 2 : 3)));
++ print(b1 + (b1 + (b1 ? 2 : 3)));
++ print(b1 + (b1 + (c1 ? 2 : 3)));
++ print(b1 + ((-c1) + (-a1)));
++ print(b1 + ((-c1) + (-b1)));
++ print(b1 + ((-c1) + (-c1)));
++ try { print(b1 + new a1); } catch (e) {}
++ try { print(b1 + new b1); } catch (e) {}
++ try { print(b1 + new c1); } catch (e) {}
+ })();
+--- ./nashorn/test/script/basic/JDK-8027042.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8027042.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -1,8 +1,10 @@
++start
+ get b
+ get a
+ conv c
+ conv b
+ 111
++done with first
+ get b
+ get b
+ conv c
+--- ./nashorn/test/script/basic/JDK-8027236.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8027236.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8027562.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8027562.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8027700.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8027700.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -43,7 +43,7 @@
+ }
+ }
+
+-Object.defineProperty(this, "foo", { value:0 })
++Object.defineProperty(this, "foo", { value:0 })
+ try {
+ eval("function foo() {}");
+ fail("should have thrown TypeError");
+--- ./nashorn/test/script/basic/JDK-8027753.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8027753.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8027828.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8027828.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8027933.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8027933.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8028020.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8028020.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8028210.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8028210.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8028434.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8028434.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -31,28 +31,28 @@
+
+ try {
+ while (test.apa < 0) {
+- print("x");
++ print("x");
+ }
+ } catch (e) {
+ var st = e.getStackTrace();
+ if (st.length != 1) {
+- print("erroneous stacktrace length " + s.length);
++ print("erroneous stacktrace length " + s.length);
+ }
+ if (st[0].lineNumber !== 33) {
+- print("erroneous stacktrace element, lineNumber=" + st[0].lineNumber + " elem=" + st);
++ print("erroneous stacktrace element, lineNumber=" + st[0].lineNumber + " elem=" + st);
+ }
+ }
+
+ try {
+ do {
+- print("x");
++ print("x");
+ } while (test.apa < 0);
+ } catch (e) {
+ var st = e.getStackTrace();
+ if (st.length != 1) {
+- print("erroneous stacktrace length " + s.length);
++ print("erroneous stacktrace length " + s.length);
+ }
+ if (st[0].lineNumber !== 49) {
+- print("erroneous stacktrace element, lineNumber= " + st[0].lineNumber + " elem=" + st);
++ print("erroneous stacktrace element, lineNumber= " + st[0].lineNumber + " elem=" + st);
+ }
+ }
+--- ./nashorn/test/script/basic/JDK-8029364.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8029364.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8029384.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8029384: Function expression self-symbol not available for eval
++ *
++ * @test
++ * @run
++ */
++
++var g = function f() { print(eval("f.x")) }
++g.x = "tada!"
++g()
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8029384.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++tada!
+--- ./nashorn/test/script/basic/JDK-8029467.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8029467.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -32,3 +32,4 @@
+ print((function (x) { if(x) { return true } else { return 0 } })(true))
+ print(typeof (function (x) { return x ? 1 : "123" })(true) === "number")
+ print(typeof (function (x) { if(x) { return 1 } else { return "123" } })(true) === "number")
++
+--- ./nashorn/test/script/basic/JDK-8029667.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8029667.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,7 +29,7 @@
+ */
+
+ function f(x) {
+- return (function inner() {
++ return (function inner() {
+ var y; (function dummy() { return y })() // force own scope for the inner function
+ with({}) { // 'with' block turns off fast scopes
+ return x
+@@ -39,8 +39,8 @@
+ print(f(1));
+ print(f(2));
+
+-function g(x) {
+- (function inner() {
++function g(x) {
++ (function inner() {
+ var y; (function dummy() { return y })() // force own scope for the inner function
+ with({}) { // 'with' block turns off fast scopes
+ // Test setter as well as getter
+@@ -83,9 +83,7 @@
+ }
+ }
+ main();
+-}
++}
+
+ print(withScopes[0].func);
+ print(withScopes[1].func);
+-
+-
+--- ./nashorn/test/script/basic/JDK-8030182.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8030182.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8030182_2.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8030182_2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,13 +28,13 @@
+ * @run
+ */
+
+-var str = "";
++var str = "";
+
+ // large code to force splitting
+-for (i = 0; i < 1000; ++i)
++for (i = 0; i < 1000; ++i)
+ str +="o = new Object()\n";
+
+-str +="g()";
++str +="g()";
+
+ // check that "$split" or some such internal method
+ // does not appear in script stack trace!!
+--- ./nashorn/test/script/basic/JDK-8030182_2.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8030182_2.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -1,3 +1,3 @@
+ ReferenceError: "g" is not defined
+- at <program> (test/script/basic/JDK-8030182_2.js#42:4<eval>@0:-1)
++ at <program> (test/script/basic/JDK-8030182_2.js#42:4<eval>:-1)
+ at <program> (test/script/basic/JDK-8030182_2.js:42)
+--- ./nashorn/test/script/basic/JDK-8030197.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8030197.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8030199.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8030199.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8030200.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8030200.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8030202.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8030202.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8030809.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8030809.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,7 +29,7 @@
+ */
+
+ function func() {
+- (function() {
++ (function() {
+ throw new Error();
+ })();
+ }
+--- ./nashorn/test/script/basic/JDK-8031317.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8031317.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8031359.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8031359.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8031983.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8031983.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * JDK-8031983: Error objects should capture stack at the constructor
++ * JDK-8031983: Error objects should capture stack at the constructor
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/JDK-8032004.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8032004.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * JDK-8032004: instance property "message" of Error objects should be non-enumerable
++ * JDK-8032004: instance property "message" of Error objects should be non-enumerable
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/JDK-8032068.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8032068.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8034055.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8034055.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8035312.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,225 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8035312 push to frozen array must not increase length property
++ *
++ * @test
++ * @run
++ * @fork
++ * @option -Dnashorn.debug=true
++ */
++
++function printArrayDataClass(x) {
++ if (typeof Debug !== 'undefined') {
++ print(Debug.getArrayDataClass(x));
++ }
++}
++
++function gpush(x, elem) {
++ try {
++ print("Pushing " + elem + " to " + x);
++ x.push(elem);
++ } catch (e) {
++ print("caught error" + e);
++ }
++ print("\tarray is now [" + x + "] length is = " + x.length);
++ print();
++ printArrayDataClass(x);
++}
++
++function gpop(x) {
++ try {
++ print("Popping from " + x);
++ x.pop();
++ } catch (e) {
++ if (!(e instanceof TypeError)) {
++ print("e of wrong type " + e);
++ }
++ }
++ print("\tarray is now [" + x + "] length is = " + x.length);
++ print();
++ printArrayDataClass(x);
++}
++
++function checkArray(x) {
++ print();
++ print(">>> Push test");
++
++ var olen = x.length;
++ gpush(x, 0);
++
++ print("x.length === " + x.length + " (should be " + olen + ")");
++ print("x[3] === " + x[3] + " (should be 0)");
++ print("x[4] === " + x[4] + " (should be undefined)");
++
++ print();
++ print(">>> Pop test");
++ gpop(x);
++ gpop(x);
++ print("x.length === " + x.length + " (should be " + olen + ")");
++ print("x === " + x);
++
++ for (var i = 0 ; i < 5; i++) {
++ gpop(x);
++ }
++
++ print("x.length === " + x.length + " (should be " + olen + ")");
++ print("x === " + x);
++}
++
++print("*** Freezing");
++var frozen = [1,2,3];
++Object.freeze(frozen);
++checkArray(frozen);
++printArrayDataClass(frozen);
++
++//so far so good
++
++print();
++print("*** Other length not writable issues");
++var lengthNotWritable = [1,2,3];
++Object.defineProperty(lengthNotWritable, "length", { writable: false });
++checkArray(lengthNotWritable);
++printArrayDataClass(lengthNotWritable);
++
++function set(array, from, to, stride) {
++ //add three elements
++ for (var i = from; i < to; i+=stride) {
++ try {
++ print("Writing " + i);
++ array[i] = i;
++ printArrayDataClass(array);
++ } catch (e) {
++ print(e instanceof TypeError);
++ }
++ }
++}
++
++//define empty array with non writable length
++var arr = [1];
++Object.defineProperty(arr, "length", { writable: false });
++
++var olen2 = arr.length;
++
++set(arr, 0, 3, 1);
++
++if (arr.length != olen2) {
++ throw new ("error: " + arr.length + " != " + olen2);
++}
++
++print();
++print("array writing 0-3, with 1 stride, array = " + arr);
++print("length = " + arr.length + ", but elements are: " + arr[0] + " " + arr[1] + " " + arr[2]);
++print();
++
++//do the same but sparse/deleted range
++var arr2 = [1];
++Object.defineProperty(arr2, "length", { writable: false });
++
++print("initial length = " + arr2.length);
++var olen3 = arr2.length;
++
++set(arr2, 0, 30, 3);
++
++if (arr2.length != olen3) {
++ throw new ("error: " + arr2.length + " != " + olen3);
++}
++
++print();
++var larger = 20;
++print("array writing 0-" + larger + ", with 3 stride, array = " + arr2);
++print("length = " + arr2.length + ", but elements are: " + arr2[0] + " " + arr2[1] + " " + arr2[2]);
++
++for (var i = 0; i < larger; i++) {
++ if (arr2[i] === undefined) {
++ continue;
++ }
++ print(arr2[i] + " has length " + arr2.length);
++}
++
++print();
++var elem = 0x7fffffff - 10;
++printArrayDataClass(arr2);
++print("adding a new element high up in the array");
++print("length before element was added " + arr2.length);
++print("putting sparse at " + elem);
++arr2[elem] = "sparse";
++print("length after element was added " + arr2.length + " should be the same");
++printArrayDataClass(arr2);
++
++print();
++print("Printing arr2 - this will fail if length is > 28 and it is " + arr2.length);
++print("arr2 = [" + arr2 + "]");
++print("new length that should not be writable = " + arr2.length);
++print(arr2[elem] === "sparse");
++print(arr2[elem]);
++for (var i = 0; i < larger; i++) {
++ print(arr2[i]);
++}
++for (var key in arr2) {
++ print(key + ":" + arr2[key]);
++}
++
++//issues reported by sundar - generic setter doesn't go through push/pop bulkable
++
++function sundarExample2(arr, _writable) {
++ print("Checking if push works for bulkable non bulkable arrays - Setting length property not allowed");
++ arr[0] = "bar";
++ print(arr.length + " should be 1"); // should be 1
++ print(arr[0] + " should be bar");
++ print("["+ arr + "] should be [bar]");
++
++ // Object.defineProperty(arr, "length", { configurable: _writable });
++ Object.defineProperty(arr, "length", { writable: _writable });
++ arr[1] = "baz";
++
++ if (_writable) {
++ print(arr.length + " should be 2");
++ print(arr[0] + " should be bar");
++ print(arr[1] + " should be baz");
++ print("["+ arr + "] should be [bar,baz]");
++ } else {
++ print(arr.length + " should STILL be 1");
++ print(arr[0] + " should be bar");
++ print(arr[1] + " should be baz");
++ print("["+ arr + "] should be [bar]");
++ }
++}
++
++var newArr1 = [];
++sundarExample2(newArr1, false);
++print();
++try {
++ sundarExample2(newArr1, true);
++ print("should not get here");
++} catch (e) {
++ if (!(e instanceof TypeError)) {
++ print("Wrong exception");
++ }
++ print("got TypeError when redefining length, as expected")
++}
++print();
++
++sundarExample2([], true);
++print("Done");
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8035312.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,186 @@
++*** Freezing
++
++>>> Push test
++Pushing 0 to 1,2,3
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
++x.length === 3 (should be 3)
++x[3] === undefined (should be 0)
++x[4] === undefined (should be undefined)
++
++>>> Pop test
++Popping from 1,2,3
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
++Popping from 1,2,3
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
++x.length === 3 (should be 3)
++x === 1,2,3
++Popping from 1,2,3
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
++Popping from 1,2,3
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
++Popping from 1,2,3
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
++Popping from 1,2,3
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
++Popping from 1,2,3
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
++x.length === 3 (should be 3)
++x === 1,2,3
++class jdk.nashorn.internal.runtime.arrays.FrozenArrayFilter
++
++*** Other length not writable issues
++
++>>> Push test
++Pushing 0 to 1,2,3
++caught errorTypeError: "length" is not a writable property of [object Array]
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++x.length === 3 (should be 3)
++x[3] === 0 (should be 0)
++x[4] === undefined (should be undefined)
++
++>>> Pop test
++Popping from 1,2,3
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Popping from 1,2,3
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++x.length === 3 (should be 3)
++x === 1,2,3
++Popping from 1,2,3
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Popping from 1,2,3
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Popping from 1,2,3
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Popping from 1,2,3
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Popping from 1,2,3
++ array is now [1,2,3] length is = 3
++
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++x.length === 3 (should be 3)
++x === 1,2,3
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Writing 0
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Writing 1
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Writing 2
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++
++array writing 0-3, with 1 stride, array = 0
++length = 1, but elements are: 0 undefined 2
++
++initial length = 1
++Writing 0
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Writing 3
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Writing 6
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Writing 9
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Writing 12
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Writing 15
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Writing 18
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Writing 21
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Writing 24
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++Writing 27
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++
++array writing 0-20, with 3 stride, array = 0
++length = 1, but elements are: 0 undefined undefined
++0 has length 1
++
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++adding a new element high up in the array
++length before element was added 1
++putting sparse at 2147483637
++length after element was added 1 should be the same
++class jdk.nashorn.internal.runtime.arrays.LengthNotWritableFilter
++
++Printing arr2 - this will fail if length is > 28 and it is 1
++arr2 = [0]
++new length that should not be writable = 1
++true
++sparse
++0
++undefined
++undefined
++undefined
++undefined
++undefined
++undefined
++undefined
++undefined
++undefined
++undefined
++undefined
++undefined
++undefined
++undefined
++undefined
++undefined
++undefined
++undefined
++undefined
++0:0
++2147483637:sparse
++Checking if push works for bulkable non bulkable arrays - Setting length property not allowed
++1 should be 1
++bar should be bar
++[bar] should be [bar]
++1 should STILL be 1
++bar should be bar
++baz should be baz
++[bar] should be [bar]
++
++Checking if push works for bulkable non bulkable arrays - Setting length property not allowed
++1 should be 1
++bar should be bar
++[bar] should be [bar]
++got TypeError when redefining length, as expected
++
++Checking if push works for bulkable non bulkable arrays - Setting length property not allowed
++1 should be 1
++bar should be bar
++[bar] should be [bar]
++2 should be 2
++bar should be bar
++baz should be baz
++[bar,baz] should be [bar,baz]
++Done
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8035312_2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,65 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8035312_2 - length setter and iterators
++ *
++ * @test
++ * @run
++ */
++
++"use strict"
++
++function printArray(a,n) {
++ print("PRINT_ARRAY CALLED: length = " + a.length);
++ print();
++
++ print("INDEXED");
++ for (var x = 0; x<n; x++) {
++ print("\t" + x + ":"+a[x]);
++ }
++ print("KEYS");
++ for (var key in a) {
++ print("\t" + key + ";" + a[key]);
++ }
++}
++
++var b = [1,2,3];
++
++Object.defineProperty(b, "length", { writable: false });
++var high = 8;
++b[high] = high;
++
++printArray(b, high + 5);
++
++var c = [1,2,3];
++c[high] = high;
++print();
++print("element[" + high + "]: " + c.length + " " + c[high]);
++print("Resetting length");
++c.length = 3;
++print("element[" + high + "]: " + c.length + " " + c[high]);
++print();
++
++printArray(c, high + 5);
++print();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8035312_2.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,47 @@
++PRINT_ARRAY CALLED: length = 3
++
++INDEXED
++ 0:1
++ 1:2
++ 2:3
++ 3:undefined
++ 4:undefined
++ 5:undefined
++ 6:undefined
++ 7:undefined
++ 8:8
++ 9:undefined
++ 10:undefined
++ 11:undefined
++ 12:undefined
++KEYS
++ 0;1
++ 1;2
++ 2;3
++ 8;8
++
++element[8]: 9 8
++Resetting length
++element[8]: 3 undefined
++
++PRINT_ARRAY CALLED: length = 3
++
++INDEXED
++ 0:1
++ 1:2
++ 2:3
++ 3:undefined
++ 4:undefined
++ 5:undefined
++ 6:undefined
++ 7:undefined
++ 8:undefined
++ 9:undefined
++ 10:undefined
++ 11:undefined
++ 12:undefined
++KEYS
++ 0;1
++ 1;2
++ 2;3
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8035312_3.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8035312_3 - sparse array, non writable length
++ *
++ * @test
++ * @run
++ */
++
++var b = [1,2,3];
++
++Object.defineProperty(b, "length", { writable: false });
++var high = 23534343;
++b[high-10] = high-10;
++
++print(b[high-10]);
++
++var c = [1,2,3];
++c[high-10] = high-10;
++c.length = 3;
++print(c);
++print(c[high-10]);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8035312_3.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,3 @@
++23534333
++1,2,3
++undefined
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8035312_4.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8035312_4 - pushes and pops for non writable length
++ *
++ * @test
++ * @run
++ */
++
++var b = [1,2,3];
++Object.defineProperty(b, "length", { writable: false });
++
++try {
++ b.push(4);
++} catch (e) {
++ print("length = " + b.length);
++ print("i caught an error");
++}
++print(b);
++print(b[3]);
++print("length = " + b.length);
++
++var c = [1,2,3];
++Object.defineProperty(c, "length", { writable: false });
++
++for (var i = 0; i < 5; i++) {
++ try {
++ c.pop();
++ } catch (e) {
++ print("length = " + c.length);
++ print("I caught an error");
++ print(c);
++ }
++}
++
++print(c);
++print(c[3]);
++print("length = " + b.length);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8035312_4.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,23 @@
++length = 3
++i caught an error
++1,2,3
++4
++length = 3
++length = 3
++I caught an error
++1,2,
++length = 3
++I caught an error
++1,2,
++length = 3
++I caught an error
++1,2,
++length = 3
++I caught an error
++1,2,
++length = 3
++I caught an error
++1,2,
++1,2,
++undefined
++length = 3
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8035312_5.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,60 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8035312_5 - pushes and pops for frozen array
++ *
++ * @test
++ * @run
++ */
++
++var b = [1,2,3];
++Object.freeze(b);
++
++try {
++ b.push(4);
++} catch (e) {
++ print("length = " + b.length);
++ print("i caught an error");
++}
++print(b);
++print(b[3]);
++print("length = " + b.length);
++
++var c = [1,2,3];
++Object.freeze(c);
++
++for (var i = 0; i < 5; i++) {
++ try {
++ c.pop();
++ } catch (e) {
++ print("length = " + c.length);
++ print("I caught an error");
++ print(c);
++ }
++}
++
++print(c);
++print(c[3]);
++print("length = " + b.length);
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8035312_5.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,6 @@
++1,2,3
++undefined
++length = 3
++1,2,3
++undefined
++length = 3
+--- ./nashorn/test/script/basic/JDK-8037562.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8037562.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8038413.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8038413: NPE in unboxInteger
++ *
++ * @test
++ * @run
++ */
++
++// When adapting a method returning Integer to an optimistic call site
++// expecting int, can't forego filters because of null. That is, the
++// Integer->int conversion can't be left to the automatisms present in
++// java.lang.invoke.MethodHandle.asType() because of potential null
++// values.
++var IntegerArray = Java.type("java.lang.Integer[]");
++var arr = new IntegerArray(1);
++print(arr[0]);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8038413.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++null
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8038945.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,240 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8038945.js : test various undefined strict intrinsics and that they
++ * aren't erroneously applied when undefined is in any scope but global
++ *
++ * @test
++ * @run
++ */
++
++//:program internals={print=0, f1=0, f2=0, f3=0, f4=0, undefined=0, f5=0} externals=null
++
++//f1 internals={} externals={undefined=0}
++function f1(x) {
++ return x === undefined;
++}
++
++//f2 internals={} externals=null
++function f2(x, undefined) {
++ return x === undefined;
++}
++
++//f3 internals={x=0} externals=null
++function f3(x) {
++ //f3$f3_2 internals={} externals={x=0}
++ function f3_2(undefined) {
++ return x === undefined;
++ }
++ return f3_2(17);
++}
++
++//f4 internals={x=0} externals=null
++function f4(x) {
++ //f4$f4_2 internals={} externals={x=0}
++ function f4_2() {
++ var undefined = 17;
++ return x === undefined;
++ }
++ return f4_2();
++}
++
++//f5 internals={x=0, undefined=0} externals=null
++function f5(x) {
++ var undefined = 17;
++ //f5$f5_2 internals={} externals={x=0, undefined=0}
++ function f5_2() {
++ return x === undefined;
++ }
++ return f5_2();
++}
++
++print(" 1: " + f1(17) + " === false");
++print(" 2: " + f2(17) + " === false");
++print(" 3: " + f3(17) + " === true");
++print(" 4: " + f4(17) + " === true");
++print(" 5: " + f5(17) + " === true");
++
++//recompile
++print(" 6: " + f1("17") + " === false");
++print(" 7: " + f2("17") + " === false");
++print(" 8: " + f3("17") + " === false");
++print(" 9: " + f4("17") + " === false");
++print("10: " + f5("17") + " === false");
++
++//g1 internals={} externals={undefined=0}
++function g1(x) {
++ return x !== undefined;
++}
++
++//g2 internals={} externals=null
++function g2(x, undefined) {
++ return x !== undefined;
++}
++
++//g3 internals={x=0} externals=null
++function g3(x) {
++ //g3$g3_2 internals={} externals={x=0}
++ function g3_2(undefined) {
++ return x !== undefined;
++ }
++ return g3_2(17);
++}
++
++//g4 internals={x=0} externals=null
++function g4(x) {
++ //f4$f4_2 internals={} externals={x=0}
++ function g4_2() {
++ var undefined = 17;
++ return x !== undefined;
++ }
++ return g4_2();
++}
++
++//g5 internals={x=0, undefined=0} externals=null
++function g5(x) {
++ var undefined = 17;
++ //g5$g5_2 internals={} externals={x=0, undefined=0}
++ function g5_2() {
++ return x !== undefined;
++ }
++ return g5_2();
++}
++
++print("11: " + g1(17) + " === true");
++print("12: " + g2(17) + " === true");
++print("13: " + g3(17) + " === false");
++print("14: " + g4(17) + " === false");
++print("15: " + g5(17) + " === false");
++
++//recompile
++print("16: " + g1("17") + " === true");
++print("17: " + g2("17") + " === true");
++print("18: " + g3("17") + " === true");
++print("19: " + g4("17") + " === true");
++print("20: " + g5("17") + " === true");
++
++//h1 internals={} externals={undefined=0}
++function h1(x) {
++ return undefined === x;
++}
++
++//h2 internals={} externals=null
++function h2(x, undefined) {
++ return undefined === x;
++}
++
++//h3 internals={x=0} externals=null
++function h3(x) {
++ //h3$f3_2 internals={} externals={x=0}
++ function h3_2(undefined) {
++ return undefined === x;
++ }
++ return h3_2(17);
++}
++
++//h4 internals={x=0} externals=null
++function h4(x) {
++ //h4$h4_2 internals={} externals={x=0}
++ function h4_2() {
++ var undefined = 17;
++ return undefined === x;
++ }
++ return h4_2();
++}
++
++//h5 internals={x=0, undefined=0} externals=null
++function h5(x) {
++ var undefined = 17;
++ //h5$h5_2 internals={} externals={x=0, undefined=0}
++ function h5_2() {
++ return undefined === x;
++ }
++ return h5_2();
++}
++
++print("21: " + h1(17) + " === false");
++print("22: " + h2(17) + " === false");
++print("23: " + h3(17) + " === true");
++print("24: " + h4(17) + " === true");
++print("25: " + h5(17) + " === true");
++
++//recompile
++print("26: " + h1("17") + " === false");
++print("27: " + h2("17") + " === false");
++print("28: " + h3("17") + " === false");
++print("29: " + h4("17") + " === false");
++print("30: " + h5("17") + " === false");
++
++//i1 internals={} externals={undefined=0}
++function i1(x) {
++ return undefined !== x;
++}
++
++//i2 internals={} externals=null
++function i2(x, undefined) {
++ return undefined !== x;
++}
++
++//i3 internals={x=0} externals=null
++function i3(x) {
++ //i3$f3_2 internals={} externals={x=0}
++ function i3_2(undefined) {
++ return undefined !== x;
++ }
++ return i3_2(17);
++}
++
++//i4 internals={x=0} externals=null
++function i4(x) {
++ //i4$i4_2 internals={} externals={x=0}
++ function i4_2() {
++ var undefined = 17;
++ return undefined !== x;
++ }
++ return i4_2();
++}
++
++//h5 internals={x=0, undefined=0} externals=null
++function i5(x) {
++ var undefined = 17;
++ //i5$i5_2 internals={} externals={x=0, undefined=0}
++ function i5_2() {
++ return undefined !== x;
++ }
++ return i5_2();
++}
++
++print("31: " + i1(17) + " === true");
++print("32: " + i2(17) + " === true");
++print("33: " + i3(17) + " === false");
++print("34: " + i4(17) + " === false");
++print("35: " + i5(17) + " === false");
++
++//recompile
++print("36: " + i1("17") + " === true");
++print("37: " + i2("17") + " === true");
++print("38: " + i3("17") + " === true");
++print("39: " + i4("17") + " === true");
++print("40: " + i5("17") + " === true");
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8038945.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,40 @@
++ 1: false === false
++ 2: false === false
++ 3: true === true
++ 4: true === true
++ 5: true === true
++ 6: false === false
++ 7: false === false
++ 8: false === false
++ 9: false === false
++10: false === false
++11: true === true
++12: true === true
++13: false === false
++14: false === false
++15: false === false
++16: true === true
++17: true === true
++18: true === true
++19: true === true
++20: true === true
++21: false === false
++22: false === false
++23: true === true
++24: true === true
++25: true === true
++26: false === false
++27: false === false
++28: false === false
++29: false === false
++30: false === false
++31: true === true
++32: true === true
++33: false === false
++34: false === false
++35: false === false
++36: true === true
++37: true === true
++38: true === true
++39: true === true
++40: true === true
+--- ./nashorn/test/script/basic/JDK-8039387.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8039387.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8040024.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,100 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8040024: NaN comparisons were failing
++ *
++ * @test
++ * @run
++ */
++
++function f(x) {
++ if((x - '0') <= 9) {
++ print("FAIL if <=");
++ } else {
++ print("OK");
++ }
++
++ if((x - '0') < 9) {
++ print("FAIL if <");
++ } else {
++ print("OK");
++ }
++
++ if((x - '0') >= 9) {
++ print("FAIL if >=");
++ } else {
++ print("OK");
++ }
++
++ if((x - '0') > 9) {
++ print("FAIL if >");
++ } else {
++ print("OK");
++ }
++
++ while((x - '0') <= 9) {
++ print("FAIL while <=");
++ break;
++ }
++
++ while((x - '0') < 9) {
++ print("FAIL while <");
++ break;
++ }
++
++ while((x - '0') > 9) {
++ print("FAIL while >");
++ break;
++ }
++
++ while((x - '0') >= 9) {
++ print("FAIL while >=");
++ break;
++ }
++
++ var i = 0;
++ do {
++ print("do-while <= only once");
++ if(++i == 2) { break; }
++ } while((x - '0') <= 9);
++
++ var i = 0;
++ do {
++ print("do-while < only once");
++ if(++i == 2) { break; }
++ } while((x - '0') < 9);
++
++ var i = 0;
++ do {
++ print("do-while >= only once");
++ if(++i == 2) { break; }
++ } while((x - '0') >= 9);
++
++ var i = 0;
++ do {
++ print("do-while > only once");
++ if(++i == 2) { break; }
++ } while((x - '0') > 9);
++}
++f('%')
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8040024.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,8 @@
++OK
++OK
++OK
++OK
++do-while <= only once
++do-while < only once
++do-while >= only once
++do-while > only once
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8041995.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8041995: optimistic object property maps were only updated if the outermost program
++ * point in a property setter failed, not an inner one, which is wrong.
++ *
++ * @test
++ * @run
++ */
++
++function xyzzy() {
++ return 17.4711;
++}
++var obj = {
++ z: -xyzzy()
++};
++print(obj.z);
++
++function phlug() {
++ var obj = {
++ 4: -Infinity,
++ 5: Infinity,
++ length: 5 - Math.pow(2, 32)
++ };
++
++ return Array.prototype.lastIndexOf.call(obj, -Infinity) === 4;
++}
++
++var d = new Date;
++print(phlug());
++var d2 = new Date - d;
++print(d2 < 5000); // if this takes more than five seconds we have read the double length as an int
++
++function wrong() {
++ var obj = {
++ length1: 5 - Math.pow(2, 32),
++ length2: 4 - Math.pow(2, 32),
++ length3: 3 - Math.pow(2, 32),
++ length4: 2 - Math.pow(2, 32),
++ length5: 1 - Math.pow(2, 32),
++ length6: Math.pow(2, 32)
++ };
++ for (var i in obj) {
++ print(obj[i]);
++ }
++}
++
++wrong();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8041995.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,9 @@
++-17.4711
++true
++true
++-4294967291
++-4294967292
++-4294967293
++-4294967294
++-4294967295
++4294967296
+--- ./nashorn/test/script/basic/JDK-8041998.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8041998.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8042364.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8042364.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * JDK-8042364: Make __proto__ ES6 draft compliant
+- *
++ *
+ * @test
+ * @run
+ */
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8043133.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8043133: Fix corner cases of JDK-8041995
++ *
++ * @test
++ * @run
++ */
++
++var x = {}
++var b = false;
++// Ternary expression is not optimistic, yet the analyzer must still
++// find the optimistic subexpression f() that triggered deoptimizing
++// recompilation.
++Object.defineProperty(x, 'foo', { value: b ? b : f() });
++print(x.foo); // Must print "Hello world" instead of 0
++
++function f() {
++ return "Hello World!"
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8043133.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++Hello World!
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8043232.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,92 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8043232: Index selection of overloaded java new constructors
++ *
++ * @test
++ * @run
++ */
++
++// call explicit constructor
++print(new (java.awt["Color(int,int,int)"])(255,0,255));
++// print the constructor itself
++print(java.awt["Color(int,int,int)"]);
++
++// store constructor to call later
++var Color = java.awt["Color(int,int,int)"];
++// call stored constructor
++print(new Color(33, 233, 2))
++
++// check if default constructor works
++var obj = new (java.lang["Object()"])();
++if (obj.class != java.lang.Object.class) {
++ fail("obj is a java.lang.Object");
++}
++
++// expected failure cases.
++function checkIt(func) {
++ try {
++ func();
++ throw new Error("should have thrown TypeError");
++ } catch(e) {
++ if (! (e instanceof TypeError)) {
++ fail("Expected TypeError, got " + e);
++ }
++ print(e);
++ }
++}
++
++// constructor of a non-existent class
++checkIt(function() new (java.lang["NonExistent(String)"])());
++
++// non-existent constructor of an existing class
++checkIt(function() new (java.lang["Object(String)"])());
++
++// garbage signature string
++checkIt(function() new (java.lang["Object()xxxxx"])());
++checkIt(function() new (java.lang["Object("])());
++checkIt(function() new (java.lang["Object)"])());
++
++var System = Java.type("java.lang.System");
++// try to do 'new' on static method
++checkIt(function() new (System.getProperty)("java.version"));
++
++// try to do 'new' on an instance method
++var println = System.out.println;
++checkIt(function() new println("hello"));
++
++// call constructor as normal method (without 'new')
++checkIt(function() Color());
++
++// try constructor on interface
++checkIt(function() new java.lang["Runnable()"]);
++checkIt(function() new java.lang["Runnable(int)"]);
++
++// try constructor on abstrace class
++try {
++ new java.io["InputStream()"];
++ throw new Error("should have thrown exception!");
++} catch (e) {
++ print(e);
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8043232.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,14 @@
++java.awt.Color[r=255,g=0,b=255]
++[jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)]
++java.awt.Color[r=33,g=233,b=2]
++TypeError: No such Java class: java.lang.NonExistent
++TypeError: No such Java constructor: Object(String)
++TypeError: Java constructor signature invalid: Object()xxxxx
++TypeError: Java constructor signature invalid: Object(
++TypeError: Java constructor signature invalid: Object)
++TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.lang.System.getProperty] cannot be used as a constructor.
++TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println] cannot be used as a constructor.
++TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] requires "new".
++TypeError: No such Java constructor: Runnable()
++TypeError: No such Java constructor: Runnable(int)
++java.lang.InstantiationException: java.io.InputStream
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8043235.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,58 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8043235: Type-based optimizations interfere with continuation methods
++ *
++ * @test
++ * @run
++ */
++
++function g() {
++ return "Hello World!"
++}
++
++function f1() {
++ var c;
++ var paused = false;
++ // If we didn't disable nullCheck specialization for expressions
++ // containing a deoptimization site, we'd get an AssertionError
++ while (!paused && (null !== (c = g()))) {
++ print(c);
++ paused = true;
++ }
++}
++
++function f2() {
++ var c;
++ var paused = false;
++ // If we didn't disable undefinedCheck specialization for expressions
++ // containing a deoptimization site, we'd get an AssertionError
++ while (!paused && (undefined !== (c = g()))) {
++ print(c);
++ paused = true;
++ }
++}
++
++f1();
++f2();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8043235.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,2 @@
++Hello World!
++Hello World!
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8043431.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8043431: Fix yet another corner case of JDK-8041995
++ *
++ * @test
++ * @run
++ */
++
++var a = "Hello World!";
++
++// Without the fix, evaluating "a" optimistically will start a
++// deoptimizing recompilation in a nested object literal, and trigger an
++// assertion in code generator.
++var x = {
++ foo: {
++ value: a
++ }
++};
++
++print(x.foo.value);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8043431.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++Hello World!
+--- ./nashorn/test/script/basic/JDK-8043930.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8043930.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * JDK-8043930: TypeError when attemping to create an instance of non-public class could be better
++ * JDK-8043930: TypeError when attemping to create an instance of non-public class could be better
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/JDK-8044520.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8044520.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8044533.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8044533: Deoptimizing negation produces wrong result for zero
++ *
++ * @test
++ * @run
++ */
++
++print(1/(function() { var f = 0; return -f; })())
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8044533.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++-Infinity
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8044534.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8044534: Constant folding for unary + should produce int for boolean literals
++ *
++ * @test
++ * @run
++ */
++
++var inspect = Java.type("jdk.nashorn.test.tools.StaticTypeInspector").inspect;
++
++print(inspect(+true, "+true "));
++print(inspect(+false, "+false"));
++print(inspect(-true, "-true "));
++print(inspect(-false, "-false"));
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8044534.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,4 @@
+++true : int
+++false: int
++-true : int
++-false: double
+--- ./nashorn/test/script/basic/JDK-8044612.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8044612.js Wed Feb 04 12:14:47 2015 -0800
+@@ -34,4 +34,4 @@
+
+ if ("hello".replace("o", "$x") != "hell$x") {
+ fail("String.prototype.replace failed to handle '$x' as replacement");
+-}
++}
+--- ./nashorn/test/script/basic/JDK-8044695.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8044695.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/JDK-8044750.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK-8044750.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8046013.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,57 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8046013: TypeError: Cannot apply "with" to non script object
++ *
++ * @test
++ * @run
++ */
++
++var obj = loadWithNewGlobal({
++ script: "({ f: 33 })",
++ name: "test"
++});
++
++with (obj) {
++ print("f = " + f);
++}
++
++var obj2 = loadWithNewGlobal({
++ script: "var obj = Object.create({ foo: 42 }); obj.bar = 'hello'; obj",
++ name: "test2"
++});
++
++with (obj2) {
++ print("foo = " + foo);
++ print("bar = " + bar);
++}
++
++var obj3 = loadWithNewGlobal({
++ script: "({ f: 33, func: function() { print('this.f =', this.f); } })",
++ name: "test"
++});
++
++with(obj3) {
++ func();
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8046013.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,4 @@
++f = 33
++foo = 42
++bar = hello
++this.f = 33
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8046026.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8046026: CompiledFunction.relinkComposableInvoker assert is being hit
++ * JDK-8044770: crash with jdk9-dev/nashorn during global object initialization from MT test
++ * JDK-8047770: NPE in deoptimizing recompilation in multithreaded
++ *
++ * @test
++ * @run
++ */
++
++(function() {
++var n = 1 << 25;
++var ThreadLocalRandom = java.util.concurrent.ThreadLocalRandom;
++var m = java.util.stream.IntStream.range(0, n)
++ .parallel() // this is the essence of this test. We must trigger parallel execution
++ .filter(function() {
++ var tlr = ThreadLocalRandom.current();
++
++ var x = tlr.nextDouble(-1.0, 1.0);
++ var y = tlr.nextDouble(-1.0, 1.0);
++
++ return x * x + y * y <= 1.0;
++ })
++ .count();
++var pi = (4.0 * m) / n;
++print(pi.toFixed(2));
++})()
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8046026.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++3.14
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8046905.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,91 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8046905: apply on apply is broken
++ *
++ * @test
++ * @run
++ */
++
++var apply = Function.prototype.apply;
++var call = Function.prototype.call;
++var sort = Array.prototype.sort;
++var join = Array.prototype.join;
++
++// Running three times so that we test an already linked call site too:
++// i==0: linking initially with assumed optimistic returned type int.
++// i==1: linking after deoptimization with returned type Object.
++// i==2: re-running code linked in previous iteration. This will
++// properly exercise the guards too.
++print("1 level of apply")
++for(i = 0; i < 3; ++i) {
++ print(sort.apply([4,3,2,1]))
++}
++print("2 levels of apply")
++for(i = 0; i < 3; ++i) {
++ print(apply.apply(sort,[[4,3,2,1]]))
++}
++print("3 levels of apply")
++for(i = 0; i < 3; ++i) {
++ print(apply.apply(apply,[sort,[[4,3,2,1]]]))
++}
++print("4 levels of apply")
++for(i = 0; i < 3; ++i) {
++ print(apply.apply(apply,[apply,[sort,[[4,3,2,1]]]]))
++}
++print("5 levels of apply")
++for(i = 0; i < 3; ++i) {
++ print(apply.apply(apply,[apply,[apply,[sort,[[4,3,2,1]]]]]))
++}
++print("Many levels of apply!")
++for(i = 0; i < 3; ++i) {
++ print(apply.apply(apply,[apply,[apply,[apply,[apply,[apply,[apply,[apply,[apply,[apply,[apply,[apply,[apply,[apply,[apply,[apply,[apply,[apply,[apply,[apply,[sort,[[4,3,2,1]]]]]]]]]]]]]]]]]]]]]]))
++}
++
++print("different invocations that'll trigger relinking")
++var invocation = [sort,[[4,3,2,1]]];
++for(i = 0; i < 4; ++i) {
++ print(apply.apply(apply,[apply,invocation]))
++ // First change after i==1, so it relinks an otherwise stable linkage
++ if(i == 1) {
++ invocation = [sort,[[8,7,6,5]]];
++ } else if(i == 2) {
++ invocation = [join,[[8,7,6,5],["-"]]];
++ }
++}
++
++print("Many levels of call!")
++for(i = 0; i < 3; ++i) {
++ print(call.call(call,call,call,call,call,call,call,call,call,call,call,call,call,call,call,call,call,call,call,call,sort,[4,3,2,1]))
++}
++
++print("call apply call apply call... a lot");
++for(i = 0; i < 3; ++i) {
++ print(apply.call(call, apply, [call, apply, [call, apply, [call, apply, [call, apply, [call, apply, [sort, [4,3,2,1]]]]]]]))
++}
++
++print("apply call apply call apply... a lot");
++for(i = 0; i < 3; ++i) {
++ print(call.apply(apply, [call, apply, [call, apply, [call, apply, [call, apply, [call, apply, [call, apply, [call, sort, [[4,3,2,1]]]]]]]]]))
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8046905.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,41 @@
++1 level of apply
++1,2,3,4
++1,2,3,4
++1,2,3,4
++2 levels of apply
++1,2,3,4
++1,2,3,4
++1,2,3,4
++3 levels of apply
++1,2,3,4
++1,2,3,4
++1,2,3,4
++4 levels of apply
++1,2,3,4
++1,2,3,4
++1,2,3,4
++5 levels of apply
++1,2,3,4
++1,2,3,4
++1,2,3,4
++Many levels of apply!
++1,2,3,4
++1,2,3,4
++1,2,3,4
++different invocations that'll trigger relinking
++1,2,3,4
++1,2,3,4
++5,6,7,8
++8-7-6-5
++Many levels of call!
++1,2,3,4
++1,2,3,4
++1,2,3,4
++call apply call apply call... a lot
++1,2,3,4
++1,2,3,4
++1,2,3,4
++apply call apply call apply... a lot
++1,2,3,4
++1,2,3,4
++1,2,3,4
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047035.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8047035: (function() "hello")() crashes in Lexer with jdk9
++ *
++ * @test
++ * @run
++ */
++
++// should not print ")" at the end
++print(function() "hello");
++print(function() '');
++
++// The following should not crash inside lexer
++print((function() '')());
++print((function() "hello")());
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047035.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,4 @@
++function() "hello"
++function() ''
++
++hello
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047057.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,75 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8047057: Add a regression test for the passing test cases from JDK-8042304
++ *
++ * @test
++ * @run
++ */
++
++// commented out makeFuncAndCall calls are still result in crash
++// Tests commented with //** fail only when assertions are turned on
++
++function makeFuncAndCall(code) {
++ Function(code)();
++}
++
++function makeFuncExpectError(code, ErrorType) {
++ try {
++ makeFuncAndCall(code);
++ } catch (e) {
++ if (! (e instanceof ErrorType)) {
++ fail(ErrorType.name + " expected, got " + e);
++ }
++ }
++}
++
++makeFuncAndCall("switch(0) { default: {break;} return }");
++makeFuncAndCall("L: { { break L; } return; }");
++makeFuncAndCall("L: { while(0) break L; return; }");
++makeFuncExpectError("L: {while(0) break L; return [](); }", TypeError);
++makeFuncAndCall("do with({}) break ; while(0);");
++makeFuncAndCall("while(0) with({}) continue ;");
++makeFuncAndCall("eval([]);");
++makeFuncAndCall("try{} finally{[]}");
++makeFuncAndCall("try { } catch(x if 1) { try { } catch(x2) { } }");
++makeFuncAndCall("try { } catch(x if 1) { try { return; } catch(x2) { { } } }");
++makeFuncAndCall("Error() * (false)[-0]--");
++makeFuncAndCall("try { var x = 1, x = null; } finally { }");
++makeFuncAndCall("try { var x = {}, x = []; } catch(x3) { }");
++makeFuncAndCall("[delete this]");
++makeFuncAndCall("if(eval('', eval('', function() {}))) { }");
++makeFuncAndCall("if(eval('', eval('', function() {}))) { }");
++makeFuncAndCall("eval(\"[,,];\", [11,12,13,14].some)");
++makeFuncAndCall("eval(\"1.2e3\", ({})[ /x/ ])");
++makeFuncExpectError("eval(\"x4\", x3);", ReferenceError);
++makeFuncAndCall("with({5.0000000000000000000000: String()}){(false); }");
++makeFuncAndCall("try { var x = undefined, x = 5.0000000000000000000000; } catch(x) { x = undefined; }");
++makeFuncAndCall("(function (x){ x %= this}(false))");
++makeFuncAndCall("eval.apply.apply(function(){ eval('') })");
++makeFuncAndCall("(false % !this) && 0");
++makeFuncAndCall("with({8: 'fafafa'.replace()}){ }");
++makeFuncAndCall("(function (x) '' )(true)");
++makeFuncExpectError("new eval(function(){})", TypeError);
++makeFuncAndCall('eval("23", ({})[/x/])');
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047067.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8047067: all eval arguments need to be copied in Lower
++ *
++ * @test
++ * @run
++ */
++
++// The second expression triggers optimistic deoptimization, and if not
++// all eval arguments were copied in Lower, we'd end up with duplicate
++// program points that'd cause incorrect continuation program point in
++// the rest-of, and therefore a bad stack, and therefore an AIOOBE in
++// the continuation setup code.
++eval("23", ({})[/x/])
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047078.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8047078: ArrayLiteral mutability caused trouble in optimistic types
++ *
++ * @test
++ * @run
++ */
++
++function makeFuncAndCall(code) {
++ Function(code)();
++}
++
++makeFuncAndCall("eval([]);");
++makeFuncAndCall("eval([1]);");
++makeFuncAndCall("eval([1,2,3,,4]);");
++makeFuncAndCall("try{} finally{[]}");
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047166.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8047166: 'do with({}) break ; while(0);' crashes in CodeGenerator
++ *
++ * @test
++ * @run
++ */
++
++(function(){do with({}) break ; while(0);})();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047357.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8047357: More precise synthetic return + unreachable throw
++ *
++ * @test
++ * @run
++ */
++
++print((function() { switch(0) { default: {var x; break ; } throw x; } })());
++print((function() { switch(0) { default: {break;} return; } })());
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047357.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,2 @@
++undefined
++undefined
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047359.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8047359: large string size RangeError should be thrown rather than reporting negative length
++ *
++ * @test
++ * @run
++ */
++
++try {
++ var s = " "; for (var i=0;i<31;++i) s+=s; s.length;
++ throw new Error("should have thrown RangeError!");
++} catch (e) {
++ if (! (e instanceof RangeError)) {
++ fail("RangeError expected, got " + e);
++ }
++}
++
++try {
++ var s = " "; for (var i=0;i<31;++i) s+=s;
++ throw new Error("should have thrown RangeError!");
++} catch (e) {
++ if (! (e instanceof RangeError)) {
++ fail("RangeError expected, got " + e);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047369.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,186 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8047369: Add regression tests for passing test cases of JDK-8024971
++ *
++ * @test
++ * @run
++ * @option -scripting
++ */
++
++function makeFuncAndCall(code) {
++ Function(code)();
++}
++
++function makeFuncExpectError(code, ErrorType) {
++ try {
++ makeFuncAndCall(code);
++ } catch (e) {
++ if (! (e instanceof ErrorType)) {
++ fail(ErrorType.name + " expected, got " + e);
++ }
++ }
++}
++
++function evalExpectError(code, ErrorType) {
++ try {
++ eval(code)();
++ } catch (e) {
++ if (! (e instanceof ErrorType)) {
++ fail(ErrorType.name + " expected, got " + e);
++ }
++ }
++}
++
++function evalExpectValue(code, value) {
++ if (eval(code) != value) {
++ fail("Expected " + value + " with eval of " + code);
++ }
++}
++
++makeFuncAndCall("for(x.x in 0) {}");
++// bug JDK-8047357
++// makeFuncAndCall("switch((null >> x3)) { default: {var x; break ; }\nthrow x; }");
++makeFuncExpectError("switch(x) { case 8: break; case false: }", ReferenceError);
++makeFuncAndCall("try { return true; } finally { return false; } ");
++makeFuncAndCall("({ get 1e81(){} })");
++makeFuncAndCall("{var x, x3;try { return 0; } finally { return 3/0; } }");
++makeFuncExpectError("with(x ? 1e81 : (x2.constructor = 0.1)) {}", ReferenceError);
++makeFuncAndCall("while(x-=1) {var x=0; }");
++makeFuncAndCall("while((x-=false) && 0) { var x = this; }");
++makeFuncAndCall("/*infloop*/while(x4-=x) var x, x4 = x1;");
++makeFuncAndCall("/*infloop*/L:while(x+=null) { this;var x = /x/g ; }");
++makeFuncAndCall("while((x1|=0.1) && 0) { var x1 = -0, functional; }");
++makeFuncAndCall("with({}) return (eval(\"arguments\"));");
++
++evalExpectValue(<<CODE
++ var s = "(function() { return y })()";
++ (function() {
++ with({ y:1 })
++ eval(s)
++ })();
++ (function() {
++ with({
++ get y() { return "get"; }
++ })
++ return eval(s)
++ })();
++CODE, "get");
++
++// bug JDK-8047359
++// evalExpectValue("s = ' '; for (var i=0;i<31;++i) s+=s; s.length", RangeError);
++
++evalExpectValue(<<CODE
++ function f(o) {
++ var eval=0;
++ with({
++ get eval() { return o.eval }
++ })
++ return eval("1+2");
++ }
++ f(this);
++CODE, 3)
++
++evalExpectValue(<<CODE
++ function f() {
++ var a=1,e=2;
++ try {
++ throw 3
++ } catch(e) {
++ return + function g(){return eval('a+e')}()
++ }
++ }
++ f();
++CODE, 4);
++
++//evalExpectValue(
++// "function f(){var a=1; with({get a(){return false}}) return a}; f()", false);
++
++evalExpectError("function public() {\"use strict\"}", SyntaxError);
++evalExpectError("function f(public) {\"use strict\"}", SyntaxError);
++evalExpectError("function f() { switch(x) {} } f()", ReferenceError);
++
++// bug JDK-8047364
++// makeFuncAndCall("L1:try { return } finally { break L1 }");
++
++evalExpectValue(<<CODE
++ function f() {
++ function g() { return 0 }
++ function g() { return 1 }
++ function g$1() { return 2 }
++ return g$1()
++ }
++
++ f();
++CODE, 2);
++
++evalExpectValue(<<CODE
++ function f() {
++ function g() {return 0 }
++ var h = function g() { return 1 };
++ function g$1() { return 2 };
++ return h()
++ }
++
++ f()
++CODE, 1);
++
++evalExpectValue(<<CODE
++ function f() {
++ var obj = { get ":"() {} }
++ var desc = Object.getOwnPropertyDescriptor(obj, ":")
++ return desc.get.name
++ }
++
++ f()
++CODE, ":");
++
++evalExpectValue(<<CODE
++ function f() {
++ var obj = { set ":"(a) {} };
++ var desc = Object.getOwnPropertyDescriptor(obj, ":");
++ return desc.set;
++ }
++
++ f()
++CODE, "set \":\"(a) {}");
++
++// bug JDK-8047366
++// evalExpectValue("(1000000000000000128).toString()", "1000000000000000100");
++// evalExpectValue("(1000000000000000128).toFixed().toString()", "1000000000000000128");
++
++try {
++ Function("-", {
++ toString: function() {
++ throw "err"
++ }
++ })();
++} catch (e) {
++ if (e != "err") {
++ fail("Expected 'err' here, got " + e);
++ }
++}
++evalExpectError("function f() { switch(x) {} } f()", ReferenceError);
++Array.prototype.splice.call(Java.type("java.util.HashMap"))
++Array.prototype.slice.call(Java.type("java.util.HashMap"))
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047371.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8047371: local variable declaration in TypeEvaluator should use ScriptObject.addOwnProperty instead of .set
++ *
++ * @test
++ * @run
++ */
++
++print((function(){ var a=1; with({ get a() { return false } }) return a })());
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047371.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++false
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047728.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8047728: (function(x){var o={x:0}; with(o){delete x} return o.x})() evaluates to 0 instead of undefined
++ *
++ * @test
++ * @run
++ */
++
++function func(x) {
++ var o = {x:0};
++ with(o){
++ delete x;
++ }
++ return o.x
++}
++
++if (typeof func() != 'undefined') {
++ fail("expected undefined from 'func' call");
++}
++
++function func2() {
++ var x;
++ var o = {x:0};
++ with(o){
++ delete x;
++ }
++ return o.x
++}
++
++if (typeof func2() != 'undefined') {
++ fail("expected undefined from 'func2' call");
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047764-strict.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8047764: Indexed or polymorphic set on global affects Object.prototype
++ *
++ * @test
++ * @run
++ */
++
++// Same as JDK-8047764.js but running in strict mode
++"use strict";
++
++// Test global set operation on properties defined in Object.prototype
++
++Object.defineProperty(Object.prototype, "prop1", { get: function() { return 1; }, set: function(v) { print("setting prop1: " + v); }});
++Object.defineProperty(Object.prototype, "prop2", { value: 1, writable: false, configurable: false });
++
++try {
++ prop1 = 1;
++ print("prop 1: " + prop2);
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ prop2 = 2;
++ print("prop 2: " + prop2);
++} catch (e) {
++ print(e.name);
++}
++
++// Make sure various ways of setting global toString don't affect Object.prototype.toString
++
++function checkToString() {
++ print(global);
++ print(Object.prototype);
++ print(global.toString === Object.prototype.toString);
++ print(objProtoToString === Object.prototype.toString);
++}
++
++var global = this;
++var objProtoToString = Object.prototype.toString;
++global["toString"] = function() { return "global toString 1"; };
++checkToString();
++global.toString = function() { return "global toString 2"; };
++checkToString();
++toString = function() { return "global toString 3"; };
++checkToString();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047764-strict.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,15 @@
++setting prop1: 1
++prop 1: 1
++TypeError
++global toString 1
++[object Object]
++false
++true
++global toString 2
++[object Object]
++false
++true
++global toString 3
++[object Object]
++false
++true
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047764.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,94 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8047764: Indexed or polymorphic set on global affects Object.prototype
++ *
++ * @test
++ * @run
++ */
++
++// Test global set operation on properties defined in Object.prototype
++
++Object.defineProperty(Object.prototype, "prop1", { get: function() { return 1; }, set: function(v) { print("setting prop1: " + v); }});
++Object.defineProperty(Object.prototype, "prop2", { value: 1, writable: false, configurable: false });
++
++try {
++ prop1 = 1;
++ print("prop 1: " + prop2);
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ prop2 = 2;
++ print("prop 2: " + prop2);
++} catch (e) {
++ print(e.name);
++}
++
++// Make sure various ways of setting global toString don't affect Object.prototype.toString
++
++function checkToString() {
++ print(global);
++ print(Object.prototype);
++ print(global.toString === Object.prototype.toString);
++ print(objProtoToString === Object.prototype.toString);
++}
++
++var global = this;
++var objProtoToString = Object.prototype.toString;
++global["toString"] = function() { return "global toString 1"; };
++checkToString();
++global.toString = function() { return "global toString 2"; };
++checkToString();
++toString = function() { return "global toString 3"; };
++checkToString();
++
++// Test setters on 'with' object
++
++var p = { prop3: 3, toString: function() { return "[object p]"; }};
++Object.defineProperty(p, "prop4", { get: function() { print("get", this); return 4; }, set: function(v) { print("set", this, v); }});
++var o = Object.create(p);
++o.toString = function() { return "[object o]"; };
++
++with(o) {
++ (function() {
++ var m = 5;
++ (function() {
++ print(prop3);
++ prop3 = m;
++ print(prop3);
++ print(prop4);
++ prop4 = m;
++ print(prop4);
++ })();
++ })();
++}
++
++print(o.hasOwnProperty("prop3"));
++print(o.prop3);
++print(p.prop3);
++print(o.hasOwnProperty("prop4"));
++print(o.prop4);
++print(p.prop4);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047764.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,30 @@
++setting prop1: 1
++prop 1: 1
++prop 2: 1
++global toString 1
++[object Object]
++false
++true
++global toString 2
++[object Object]
++false
++true
++global toString 3
++[object Object]
++false
++true
++3
++5
++get [object o]
++4
++set [object o] 5
++get [object o]
++4
++true
++5
++3
++false
++get [object o]
++4
++get [object p]
++4
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047959.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8047959: bindings created for declarations in eval code are not mutable
++ *
++ * @test
++ * @run
++ */
++
++eval("var x=10;");
++print('delete x? ' + delete x);
++print('typeof x = ' + typeof x);
++
++eval("function f() {}");
++print('delete f? ' + delete f);
++print('typeof f = ' + typeof f);
++
++var foo = 223;
++print('delete foo? ' + delete foo);
++print('typeof foo = ' + typeof foo);
++
++function func() {}
++print('delete func? ' + delete func);
++print('typeof func = ' + typeof func);
++
++eval("var foo = 33;");
++print("delete foo? " + delete foo);
++print("typeof foo? " + typeof foo);
++print("foo = " + foo);
++
++var x = "global";
++(function(){
++ eval("var x='local'");
++ print("x in function = "+ x);
++ print("delete x? = " + delete x);
++ print("x after delete = " + x);
++})();
++print("x = " + x);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8047959.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,15 @@
++delete x? false
++typeof x = number
++delete f? true
++typeof f = undefined
++delete foo? false
++typeof foo = number
++delete func? false
++typeof func = function
++delete foo? false
++typeof foo? number
++foo = 33
++x in function = local
++delete x? = true
++x after delete = global
++x = global
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8048071.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,85 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8048071: eval within 'with' statement does not use correct scope if with scope expression has a copy of eval
++ *
++ * @test
++ * @run
++ */
++
++function func() {
++ var x = 1;
++ with ({ eval: this.eval }) {
++ eval("var x = 23");
++ }
++
++ return x;
++}
++
++print(func());
++print("typeof x? " + typeof x);
++
++print((function(global){
++ var x = 1;
++ with(global) {
++ eval("eval('var x=0')");
++ }
++ return x;
++})(this));
++print("typeof x? " + typeof x);
++
++print((function(global){
++ var x = 1;
++ with({eval: global.eval}) {
++ eval("eval('var x=0')");
++ }
++ return x;
++})(this));
++print("typeof x? " + typeof x);
++
++// not-builtin eval cases
++
++(function () {
++ function eval(str) {
++ print("local eval called: " + str);
++ print(this);
++ }
++
++ with({}) {
++ eval("hello");
++ }
++})();
++
++(function () {
++ with({
++ eval:function(str) {
++ print("with's eval called: " + str);
++ print("this = " + this);
++ print("this.foo = " + this.foo);
++ },
++ foo: 42
++ }) {
++ eval("hello")
++ }
++})();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8048071.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,11 @@
++23
++typeof x? undefined
++0
++typeof x? undefined
++0
++typeof x? undefined
++local eval called: hello
++[object global]
++with's eval called: hello
++this = [object Object]
++this.foo = 42
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8048079_1a.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8048079: Persistent code store is broken after optimistic types merge
++ *
++ * @test
++ * @runif external.prototype
++ * @option -pcc
++ * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache
++ * @fork
++ */
++
++load(__DIR__ + 'prototype.js');
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8048079_1a.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++parsed and compiled ok prototype.js
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8048079_1b.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8048079: Persistent code store is broken after optimistic types merge
++ *
++ * @test
++ * @runif external.yui
++ * @option -pcc
++ * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache
++ * @fork
++ */
++
++load(__DIR__ + 'yui.js');
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8048079_1b.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,2 @@
++parsed and compiled ok yui-min.js
++parsed and compiled ok yui.js
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8048079_2a.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8048079: Persistent code store is broken after optimistic types merge.
++ * Same script as JDK-8048079_1a.js to exercise code cache.
++ * @test
++ * @runif external.prototype
++ * @option -pcc
++ * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache
++ * @fork
++ */
++
++load(__DIR__ + 'prototype.js');
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8048079_2a.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++parsed and compiled ok prototype.js
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8048079_2b.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8048079: Persistent code store is broken after optimistic types merge
++ * Same script as JDK-8048079_1b.js to exercise code cache again.
++ * @test
++ * @runif external.yui
++ * @option -pcc
++ * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache
++ * @fork
++ */
++
++load(__DIR__ + 'yui.js');
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8048079_2b.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,2 @@
++parsed and compiled ok yui-min.js
++parsed and compiled ok yui.js
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8048505.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Read fully parameter test
++ *
++ * @test
++ * @option -scripting
++ * @run
++ */
++
++var str = __FILE__;
++var first = readFully(str);
++print(typeof str);
++
++var str2 = __FILE__.substring(0,5);
++var str3 = __FILE__.substring(5);
++print(typeof str2);
++print(typeof str3);
++
++var cons = str2 + str3;
++print(typeof cons);
++
++var second = readFully(cons);
++
++var f = new java.io.File(str);
++print(typeof f);
++var third = readFully(f);
++
++print(first.length() == second.length());
++print(first.length() == third.length());
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8048505.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,7 @@
++string
++string
++string
++string
++object
++true
++true
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8048586.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8048586: String concatenation with optimistic types is slow
++ *
++ * @test
++ * @run
++ */
++
++var body = '';
++
++for (var i = 0; i < 1024 * 1024; i++) {
++ body += 'hello world\n';
++}
++
++body = '';
++
++for (var i = 0; i < 1024 * 1024; i++) {
++ body = body + 'hello world\n';
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8048718.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8048718: JSON.parse('{"0":0, "64":0}') throws ArrayindexOutOfBoundsException
++ *
++ * @test
++ * @run
++ */
++
++var obj = JSON.parse('{"0":0, "64":0}');
++if ("1" in obj) {
++ fail("found element at index 1");
++}
++
++if ("63" in obj) {
++ fail("found element at index 63");
++}
++
++if (obj[0] != 0) {
++ fail("expected obj[0] to be 0");
++}
++
++if (obj[64] != 0) {
++ fail("expected obj[64] to be 0");
++}
++
++for (var i in obj) {
++ if (i != "0" && i != "64") {
++ fail("invalid property " + i);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8049086.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,144 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8049086: Minor API convenience functions on "Java" object
++ *
++ * @test
++ * @run
++ */
++
++var System = Java.type("java.lang.System");
++var out = System.out;
++var println = out.println;
++var getProperty = System.getProperty;
++var File = Java.type("java.io.File")["(String)"];
++
++print("println is java method? " + Java.isJavaMethod(println));
++print("println is script function? " + Java.isScriptFunction(println));
++print("getProperty is java method? " + Java.isJavaMethod(getProperty));
++print("getProperty is script function? " + Java.isScriptFunction(getProperty));
++print("File is java method? " + Java.isJavaMethod(File));
++print("File is script function? " + Java.isScriptFunction(File));
++
++print("eval is script function? " + Java.isScriptFunction(eval));
++print("eval is java method? " + Java.isJavaMethod(eval));
++function hello() {}
++print("hello is script function? " + Java.isScriptFunction(hello));
++print("hello is java method? " + Java.isJavaMethod(hello));
++
++print("out is script object? " + Java.isScriptObject(out));
++print("System is script object? " + Java.isScriptObject(System));
++print("Object is script object? " + Java.isScriptObject(Object));
++print("{} is script object? " + Java.isScriptObject({}));
++print("/foo/ is script object? " + Java.isScriptObject(/foo/));
++
++// Java function is anything whose 'typeof' is 'function' but it is not
++// a script function! This includes:
++// (a) Java methods (b) Java classes (as these respond to new)
++// (c) FunctionalInterface objects (d) JSObjects that are 'functions'
++
++print("java.awt.Color is java function? " + Java.isJavaFunction(java.awt.Color));
++print("java.lang.Runnable instance is java function? "
++ + Java.isJavaFunction(new java.lang.Runnable(function() {})));
++print("eval is java function? " + Java.isJavaFunction(eval));
++print("println is java function? " + Java.isJavaFunction(println));
++print("getProperty is java function? " + Java.isJavaFunction(getProperty));
++
++var JSObject = Java.type("jdk.nashorn.api.scripting.JSObject");
++print("callable JSObject is function? " +
++ Java.isJavaFunction(new JSObject() {
++ isFunction: function() true,
++ call: function() {}
++ })
++);
++
++print("Non callable JSObject is function? " +
++ Java.isJavaFunction(new JSObject() {
++ isFunction: function() false,
++ })
++);
++
++// synchronized function
++var lock = new java.lang.Object();
++
++print("lock is java object? " + Java.isJavaObject(lock));
++print("eval is java object? " + Java.isJavaObject(eval));
++print("{} is java object? " + Java.isJavaObject({}));
++print("/foo/ is java object? " + Java.isJavaObject(/foo/));
++print("[] is java object? " + Java.isJavaObject([]));
++print("java.io.File is java object? " + Java.isJavaObject(java.io.File));
++
++// synchornized function checks
++Java.synchronized(function() {
++ var th = new java.lang.Thread(Java.synchronized(function() {
++ print("new thread");
++ print("notifying..");
++ lock.notifyAll();
++ }, lock));
++ th.start();
++ print("about to wait..");
++ lock.wait();
++ th.join();
++ print("done waiting!");
++}, lock)();
++
++// try Mozilla "sync" as well
++load("nashorn:mozilla_compat.js");
++sync(function() {
++ var th = new java.lang.Thread(sync(function() {
++ print("new thread");
++ print("notifying..");
++ lock.notifyAll();
++ }, lock));
++ th.start();
++ print("about to wait..");
++ lock.wait();
++ th.join();
++ print("done waiting!");
++}, lock)();
++
++function expectTypeError(func) {
++ try {
++ func();
++ throw new Error("should have thrown TypeError");
++ } catch (e) {
++ if (! (e instanceof TypeError)) {
++ fail("Expected TypeError, got " +e);
++ }
++ print(e);
++ }
++}
++
++expectTypeError(function() Java.synchronized(232));
++expectTypeError(function() sync(232));
++expectTypeError(function() Java.synchronized({}));
++expectTypeError(function() sync({}));
++expectTypeError(function() Java.synchronized([]));
++expectTypeError(function() sync([]));
++expectTypeError(function() Java.synchronized("hello"));
++expectTypeError(function() sync("hello"));
++expectTypeError(function() Java.synchronized(null));
++expectTypeError(function() sync(null));
++expectTypeError(function() Java.synchronized(undefined));
++expectTypeError(function() sync(undefined));
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8049086.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,48 @@
++println is java method? true
++println is script function? false
++getProperty is java method? true
++getProperty is script function? false
++File is java method? true
++File is script function? false
++eval is script function? true
++eval is java method? false
++hello is script function? true
++hello is java method? false
++out is script object? false
++System is script object? false
++Object is script object? true
++{} is script object? true
++/foo/ is script object? true
++java.awt.Color is java function? true
++java.lang.Runnable instance is java function? true
++eval is java function? false
++println is java function? true
++getProperty is java function? true
++callable JSObject is function? true
++Non callable JSObject is function? false
++lock is java object? true
++eval is java object? false
++{} is java object? false
++/foo/ is java object? false
++[] is java object? false
++java.io.File is java object? true
++about to wait..
++new thread
++notifying..
++done waiting!
++about to wait..
++new thread
++notifying..
++done waiting!
++TypeError: 232 is not a function
++TypeError: 232 is not a function
++TypeError: [object Object] is not a function
++TypeError: [object Object] is not a function
++TypeError: [object Array] is not a function
++TypeError: [object Array] is not a function
++TypeError: hello is not a function
++TypeError: hello is not a function
++TypeError: null is not a function
++TypeError: null is not a function
++TypeError: undefined is not a function
++TypeError: undefined is not a function
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8049242.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,78 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8049242: Explicit constructor overload selection should work with StaticClass as well
++ *
++ * @test
++ * @run
++ */
++
++// call explicit constructor
++print(new (Java.type("java.awt.Color")["(int,int,int)"])(255,0,255));
++// print the constructor itself
++print(Java.type("java.awt.Color")["(int,int,int)"]);
++
++// store constructor to call later
++var Color = Java.type("java.awt.Color")["(int,int,int)"];
++// call stored constructor
++print(new Color(33, 233, 2))
++
++// check if default constructor works
++var obj = new (Java.type("java.lang.Object")["()"])();
++if (obj.class != Java.type("java.lang.Object").class) {
++ fail("obj is a java.lang.Object");
++}
++
++// expected failure cases.
++function checkIt(func) {
++ try {
++ func();
++ throw new Error("should have thrown TypeError");
++ } catch(e) {
++ if (! (e instanceof TypeError)) {
++ fail("Expected TypeError, got " + e);
++ }
++ print(e);
++ }
++}
++
++// garbage signature string
++checkIt(function() new (Java.type("java.lang.Object")["()xxxxx"])());
++checkIt(function() new (Java.type("java.lang.Object")["("])());
++checkIt(function() new (Java.type("java.lang.Object")[")"])());
++
++// call constructor as normal method (without 'new')
++checkIt(function() Color());
++
++// try constructor on interface
++checkIt(function() new (Java.type("java.lang.Runnable"))["()"]);
++checkIt(function() new (Java.type("java.lang.Runnable"))["(int)"]);
++
++// try constructor on abstrace class
++try {
++ new (Java.type("java.io.InputStream"))["()"];
++ throw new Error("should have thrown exception!");
++} catch (e) {
++ print(e);
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8049242.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,10 @@
++java.awt.Color[r=255,g=0,b=255]
++[jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)]
++java.awt.Color[r=33,g=233,b=2]
++TypeError: null is not a function
++TypeError: null is not a function
++TypeError: null is not a function
++TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] requires "new".
++TypeError: null is not a function
++TypeError: null is not a function
++java.lang.InstantiationException: java.io.InputStream
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8049407-big-endian.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Verify DataView behavior with little/big endian
++ *
++ * @test
++ * @run
++ * @bigendian
++ */
++
++var dir = typeof(__DIR__) == 'undefined' ? "test/script/basic/" : __DIR__;
++load(dir + "JDK-8049407-payload.js");
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8049407-big-endian.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++false
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8049407-payload.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Verify DataView behavior with little/big endian
++ *
++ * @subtest
++ * @run
++ */
++
++var littleEndian = (function() {
++ var buffer = new ArrayBuffer(2);
++ new DataView(buffer).setInt16(0, 256, true);
++ return new Int16Array(buffer)[0] === 256;
++ })();
++
++print(littleEndian);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8049407.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Verify DataView behavior with little/big endian
++ *
++ * @test
++ * @run
++ * @littleendian
++ */
++
++var dir = typeof(__DIR__) == 'undefined' ? "test/script/basic/" : __DIR__;
++load(dir + "JDK-8049407-payload.js");
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8049407.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++true
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8050432.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,40 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8050432: javax.script.filename variable should not be enumerable with nashorn engine's ENGINE_SCOPE bindings
++ *
++ * @test
++ * @run
++ */
++
++var ScriptEngine = javax.script.ScriptEngine;
++var m = new javax.script.ScriptEngineManager();
++var engine = m.getEngineByName("nashorn");
++
++engine.put(ScriptEngine.FILENAME, "foo");
++var desc = engine.eval("Object.getOwnPropertyDescriptor(this, '"
++ + ScriptEngine.FILENAME + "')");
++if (desc.enumerable) {
++ fail(ScriptEngine.FILENAME + " is enumerable");
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8051439.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051439: Wrong type calculated for ADD operator with undefined operand
++ *
++ * @test
++ * @run
++ */
++
++// Test + operator
++function f1() {
++ var x;
++ for (var i = 0;i < 3; i++) {
++ x = x + i;
++ }
++ x = x + "test";
++ return x;
++}
++
++// Test += operator
++function f2() {
++ var x;
++ for (var i = 0;i < 3; i++) {
++ x += i;
++ }
++ x += "test";
++ return x;
++}
++
++print(f1());
++print(f2());
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8051439.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,2 @@
++NaNtest
++NaNtest
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8051778.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,83 @@
++/*
++ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051778: support bind on all Nashorn callables
++ *
++ * @test
++ * @run
++ */
++
++var bind = Function.prototype.bind;
++
++// Bind a POJO method
++var l = new java.util.ArrayList();
++var l_add_foo = bind.call(l.add, l, "foo");
++l_add_foo();
++print("l=" + l);
++
++// Bind a BoundCallable
++var l_add = bind.call(l.add, l);
++var l_add_foo2 = bind.call(l_add, null, "foo2");
++l_add_foo2();
++print("l=" + l);
++
++// Bind a POJO method retrieved from one instance to a different but
++// compatible instance.
++var l2 = new java.util.ArrayList();
++var l2_size = bind.call(l.size, l2);
++print("l2_size()=" + l2_size());
++
++// Bind a Java type object (used as a constructor).
++var construct_two = bind.call(java.lang.Integer, null, 2);
++print("Bound Integer(2) constructor: " + new construct_two())
++
++// Bind a @FunctionalInterface proxying to an object literal. NOTE: the
++// expected value of this.a is always "original" and never "bound". This
++// might seem counterintuitive, but we are not binding the apply()
++// function of the object literal that defines the BiFunction behaviour,
++// we are binding the SAM proxy object instead, and it is always
++// forwarding to the apply() function with "this" set to the object
++// literal. Basically, binding "this" for SAM proxies is useless; only
++// binding arguments makes sense.
++var f1 = new java.util.function.BiFunction() {
++ apply: function(x, y) {
++ return "BiFunction with literal: " + this.a + ", " + x + ", " + y;
++ },
++ a: "unbound"
++};
++print((bind.call(f1, {a: "bound"}))(1, 2))
++print((bind.call(f1, {a: "bound"}, 3))(4))
++print((bind.call(f1, {a: "bound"}, 5, 6))())
++
++// Bind a @FunctionalInterface proxying to a function. With the same
++// reasoning as above (binding the proxy vs. binding the JS function),
++// the value of this.a will always be undefined, and never "bound".
++var f2 = new java.util.function.BiFunction(
++ function(x, y) {
++ return "BiFunction with function: " + this.a + ", " + x + ", " + y;
++ }
++);
++print((bind.call(f2, {a: "bound"}))(7, 8))
++print((bind.call(f2, {a: "bound"}, 9))(10))
++print((bind.call(f2, {a: "bound"}, 11, 12))())
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8051778.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,10 @@
++l=[foo]
++l=[foo, foo2]
++l2_size()=0
++Bound Integer(2) constructor: 2
++BiFunction with literal: unbound, 1, 2
++BiFunction with literal: unbound, 3, 4
++BiFunction with literal: unbound, 5, 6
++BiFunction with function: undefined, 7, 8
++BiFunction with function: undefined, 9, 10
++BiFunction with function: undefined, 11, 12
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8054503.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,50 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * 8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
++ *
++ * @test
++ * @run
++ */
++
++function MyFunc() {}
++
++MyFunc.prototype.foo = 42;
++var obj = new MyFunc();
++Object.defineProperty(obj, "foo", {
++ value: "hello",
++ enumerable: false
++});
++
++for (var p in obj) {
++ if (p == "foo") {
++ fail("'foo' is not expected here!");
++ }
++}
++
++for each (var p in obj) {
++ if (p == "hello" || p == 42) {
++ fail("'foo' value is not expected here");
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8055762.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,84 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8055762: Nashorn misses linker for netscape.javascript.JSObject instances
++ *
++ * @test
++ * @option -scripting
++ * @run
++ */
++
++// basic checks for special linkage for netscape.javascript.JSObject
++// instances. For this test, we just subclass that class rather than
++// involve actual browser script engine or javafx webkit objects.
++
++function main() {
++ var JSObject;
++ try {
++ JSObject = Java.type("netscape.javascript.JSObject");
++ } catch (e) {
++ if (e instanceof java.lang.ClassNotFoundException) {
++ // pass vacuously by emitting the .EXPECTED file content
++ var str = readFully(__DIR__ + "JDK-8055762.js.EXPECTED");
++ print(str.substring(0, str.length - 1));
++ return;
++ } else{
++ fail("unexpected exception for JSObject", e);
++ }
++ }
++ test(JSObject);
++}
++
++function test(JSObject) {
++ var obj = new (Java.extend(JSObject))() {
++ getMember: function(name) {
++ if (name == "func") {
++ return function(arg) {
++ print("func called with " + arg);
++ }
++ }
++ return name.toUpperCase();
++ },
++
++ getSlot: function(index) {
++ return index^2;
++ },
++
++ setMember: function(name, value) {
++ print(name + " set to " + value);
++ },
++
++ setSlot: function(index, value) {
++ print("[" + index + "] set to " + value);
++ }
++ };
++
++ print(obj["foo"]);
++ print(obj[2]);
++ obj.bar = 23;
++ obj[3] = 23;
++ obj.func("hello");
++}
++
++main();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8055762.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,5 @@
++FOO
++0
++bar set to 23
++[3] set to 23
++func called with hello
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8055796.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8055796: JSObject and browser JSObject linkers should provide fallback to call underlying Java methods directly
++ *
++ * @test
++ * @run
++ */
++
++var m = new javax.script.ScriptEngineManager();
++var e = m.getEngineByName("nashorn");
++var jsobj = e.eval("({ foo: 33, valueOf: function() 42 })");
++
++print("foo =", jsobj['getMember(java.lang.String)']("foo"));
++print("eval =", jsobj['eval(String)']("this + 44"));
++print("valueOf function? =", (jsobj.valueOf)['isFunction()']());
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8055796.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,3 @@
++foo = 33
++eval = 86
++valueOf function? = true
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8055796_2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,79 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8055796: JSObject and browser JSObject linkers should provide fallback to call underlying Java methods directly
++ *
++ * @test
++ * @option -scripting
++ * @run
++ */
++
++function main() {
++ var JSObject;
++ try {
++ JSObject = Java.type("netscape.javascript.JSObject");
++ } catch (e) {
++ if (e instanceof java.lang.ClassNotFoundException) {
++ // pass vacuously by emitting the .EXPECTED file content
++ var str = readFully(__DIR__ + "JDK-8055796_2.js.EXPECTED");
++ print(str.substring(0, str.length - 1));
++ return;
++ } else {
++ fail("unexpected exception on JSObject", e);
++ }
++ }
++ test(JSObject);
++}
++
++function test(JSObject) {
++ var bjsobj = new (Java.extend(JSObject))() {
++ getMember: function(name) {
++ if (name == "func") {
++ return function(arg) {
++ print("func called with " + arg);
++ }
++ }
++ return name.toUpperCase();
++ },
++
++ getSlot: function(index) {
++ return index*index;
++ },
++
++ setMember: function(name, value) {
++ print(name + " set to " + value);
++ },
++
++ setSlot: function(index, value) {
++ print("[" + index + "] set to " + value);
++ }
++ };
++
++ print("getMember('foo') =", bjsobj['getMember(String)']('foo'));
++ print("getSlot(6) =", bjsobj['getSlot(int)'](6));
++ bjsobj['setMember(String, Object)']('bar', 'hello');
++ bjsobj['setSlot(int, Object)'](10, 42);
++}
++
++main();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8055796_2.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,4 @@
++getMember('foo') = FOO
++getSlot(6) = 36
++bar set to hello
++[10] set to 42
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8055870.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8055870: iteration fails if index var is not used
++ *
++ * @test
++ * @run
++ */
++
++function isEmpty2(v) {
++ for (var k in v) {
++ return false;
++ }
++ return true;
++}
++
++x = {test: 'test'}
++
++print(isEmpty2(x))
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8055870.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++false
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8056123.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8056123: Anonymous function statements leak internal function names into global scope
++ *
++ * @test
++ * @run
++ */
++
++// do *not* introduce newlines before this line!
++function () { // line 32
++ print("hello function!");
++}
++
++if (typeof this["L:32"] != 'undefined') {
++ fail("anonymous function statement leaks name in global");
++}
++
++var keys = Object.keys(this);
++for (var i in keys) {
++ if (keys[i].contains("L:")) {
++ fail("found " + keys[i] + " in global scope");
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8056129.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8056129: AtomicInteger is treated as primitive number with optimistic compilation
++ *
++ * @test
++ * @run
++ */
++
++var AtomicInteger = java.util.concurrent.atomic.AtomicInteger;
++
++function getAtomic() {
++ return new AtomicInteger()
++}
++var x = getAtomic()
++print(x instanceof AtomicInteger)
++
++var a = []
++a.push(x)
++var y = a[0]
++print(y instanceof AtomicInteger)
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8056129.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,2 @@
++true
++true
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8056978.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,46 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8056978: ClassCastException: cannot cast jdk.nashorn.internal.scripts.JO*
++ *
++ * @test
++ * @run
++ */
++
++var obj1 = {
++ 'name': 'test name',
++ '1': '1',
++ '2': '2',
++ '3': '3',
++ '4': '4',
++ '5': '5'
++};
++
++var obj2 = {
++ 'name': 'hello'
++};
++
++print(obj2['name']);
++print(obj2.name);
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8056978.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,2 @@
++hello
++hello
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8057019-2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * this apply with extra arguments
++ * (with apply to call enabled)
++ *
++ * @test
++ * @run
++ */
++
++load(__DIR__ + 'JDK-8057019-payload.js');
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8057019-2.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,24 @@
++1 2 undefined
++1 2 3
++1 2 3
++1 2 undefined
++1 2 3
++1 2 3
++1 2 undefined
++1 2 3
++1 2 3
++1 2 undefined
++1 2 3
++1 2 3
++1 2 undefined
++1 2 3
++1 2 3
++23 apa gorilla
++23 apa gorilla
++23 apa gorilla
++23 apa gorilla
++23 apa gorilla
++23 apa gorilla
++TypeError: Function.prototype.apply expects an Array for second argument
++TypeError: Function.prototype.apply expects an Array for second argument
++TypeError: Function.prototype.apply expects an Array for second argument
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8057019-payload.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,102 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * this apply with extra arguments
++ *
++ * @subtest
++ */
++
++function func(x, y, z) {
++ print(x, y, z);
++}
++
++function g() {
++ func.apply(this, arguments);
++}
++function h() {
++ func.apply(this, arguments, 23);
++}
++function i() {
++ func.apply(this, arguments, 23, 4711);
++}
++function j() {
++ func.apply(this, arguments, 23, 4711, "apa", "dingo", "gorilla");
++}
++function k() {
++ func.apply(this, arguments, 23);
++}
++function l() {
++ func.apply(this, [23, "apa", "gorilla", "dingo"], 17);
++}
++function m() {
++ func.apply(this, [23, "apa", "gorilla", "dingo"]);
++}
++function n() {
++ func.apply(this, "significant");
++}
++
++g(1,2);
++g(1,2,3);
++g(1,2,3,4);
++
++h(1,2);
++h(1,2,3);
++h(1,2,3,4);
++
++i(1,2);
++i(1,2,3);
++i(1,2,3,4);
++
++j(1,2);
++j(1,2,3);
++j(1,2,3,4);
++
++k(1,2);
++k(1,2,3);
++k(1,2,3,4);
++
++l(1,2);
++l(1,2,3);
++l(1,2,3,4);
++
++m(1,2);
++m(1,2,3);
++m(1,2,3,4);
++
++try {
++ n(1,2);
++} catch (e) {
++ print(e);
++}
++try {
++ n(1,2,3);
++} catch (e) {
++ print(e);
++}
++
++try {
++ n(1,2,3,4);
++} catch (e) {
++ print(e);
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8057019.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * this apply with extra arguments
++ * (turning off apply to call)
++ *
++ * @fork
++ * @option -Dnashorn.apply2call=false
++ * @test
++ * @run
++ */
++
++load(__DIR__ + 'JDK-8057019-payload.js');
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8057019.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,24 @@
++1 2 undefined
++1 2 3
++1 2 3
++1 2 undefined
++1 2 3
++1 2 3
++1 2 undefined
++1 2 3
++1 2 3
++1 2 undefined
++1 2 3
++1 2 3
++1 2 undefined
++1 2 3
++1 2 3
++23 apa gorilla
++23 apa gorilla
++23 apa gorilla
++23 apa gorilla
++23 apa gorilla
++23 apa gorilla
++TypeError: Function.prototype.apply expects an Array for second argument
++TypeError: Function.prototype.apply expects an Array for second argument
++TypeError: Function.prototype.apply expects an Array for second argument
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8057825.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057825 : A failed apply to call generation should NOT reuse the
++ * best apply to call generation so far - because it may not fit!!!
++ *
++ * @test
++ * @run
++ */
++
++function createApplier(f) {
++ function applier() {
++ f.apply(this, arguments); // no transform applied here
++ }
++ return applier;
++}
++
++function printer(x,y) {
++ print(x + " and " + y);
++}
++
++var printerApplier = createApplier(printer);
++printerApplier();
++printerApplier.apply(this, ["foo", "bar"]);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8057825.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,2 @@
++undefined and undefined
++foo and bar
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8058179.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8058179: Global constants get in the way of self-modifying properties
++ *
++ * @test
++ * @run
++ */
++
++var global = this;
++
++Object.defineProperty(global, "value", {
++ get: function() {
++ print("getting value");
++ global["value"] = "value 2";
++ return "value 1";
++ },
++ set: function(value) {
++ print("setting value: " + value);
++ delete global["value"];
++ global["value"] = value;
++ },
++ configurable: true
++});
++
++print(value);
++print(value);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8058179.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,4 @@
++getting value
++setting value: value 2
++value 1
++value 2
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8058422.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8058422: Users should be able to overwrite "context" and "engine" variables
++ *
++ * @test
++ * @run
++ */
++
++var m = new javax.script.ScriptEngineManager();
++var e = m.getEngineByName("nashorn");
++e.put("foo", "hello");
++var obj = e.eval("context.getAttribute('foo')");
++if (obj != "hello") {
++ fail("Expected 'obj' to be 'hello'");
++}
++
++e.put("context", "bar");
++if (e.eval("context") != "bar") {
++ fail("Expected 'context' to be 'bar'");
++}
++
++if (e.eval("foo") != "hello") {
++ fail("Expected 'foo' to be 'hello'");
++}
++
++if (e.eval("engine") != e) {
++ fail("'engine' is not evaluaed to current engine");
++}
++
++e.put("engine", "foobar");
++if (e.eval("engine") != "foobar") {
++ fail("'engine' is not evalued to 'foobar'");
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8058545.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8058545: With strict mode, bean property assignment of a non-existent property should result in TypeError
++ *
++ * @test
++ * @run
++ */
++
++'use strict';
++var File = Java.type("java.io.File");
++var f = new File(".");
++try {
++ f.foo = 33;
++ fail("Should have thrown TypeError");
++} catch (e) {
++ if (! (e instanceof TypeError)) {
++ fail("Expected TypeError, got " + e);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8058561.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8058561: NPE in LocalVariableTypesCalculator
++ *
++ * @test
++ * @run
++ * @option --lazy-compilation=false
++ */
++
++// Just attempting to compile this caused the NPE
++function func(x, y) {
++ while(true) {
++ switch (y[0]) {
++ case "bar":
++ x = 'xxx';
++ break;
++ }
++ }
++ return x;
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8058610.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,77 @@
++/*
++ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8058610: must not let long operations overflow
++ *
++ * @test
++ * @run
++ */
++
++function mul(x) {
++ return x.foo * x.bar;
++}
++print("=== mul ===")
++print(mul({foo: 2147483647, bar: 2147483647})); // 2^31
++print(mul({foo: 17179869184, bar: 2147483647})); // 2^34
++
++function self_mul(x) {
++ return x.foo *= x.bar;
++}
++print("=== self_mul ===")
++print(self_mul({foo: 2147483647, bar: 2147483647})); // 2^31
++print(self_mul({foo: 17179869184, bar: 2147483647})); // 2^34
++
++// We'll need to use this function to obtain long values larger in
++// magnitude than those precisely representable in a double (2^53),
++// as Nashorn's parser will reify such literals as a double. For
++// overflow on add and sub we need (2^63)-1.
++var parseLong = Java.type("java.lang.Long").parseLong;
++
++function sub(x) {
++ return x.foo - x.bar;
++}
++print("=== sub ===")
++print(sub({foo: 2147483647, bar: -2147483647})); // 2^31
++print(sub({foo: parseLong("9223372036854775807"), bar: parseLong("-9223372036854775807")})); // 2^63-1
++
++function self_sub(x) {
++ return x.foo -= x.bar;
++}
++print("=== self_sub ===")
++print(self_sub({foo: 2147483647, bar: -2147483647})); // 2^31
++print(self_sub({foo: parseLong("9223372036854775807"), bar: parseLong("-9223372036854775807")})); // 2^63-1
++
++function add(x) {
++ return x.foo + x.bar;
++}
++print("=== add ===")
++print(add({foo: 2147483647, bar: 2147483647})); // 2^31
++print(add({foo: parseLong("9223372036854775807"), bar: parseLong("9223372036854775807")})); // 2^63-1
++
++function self_add(x) {
++ return x.foo += x.bar;
++}
++print("=== self_add ===")
++print(self_add({foo: 2147483647, bar: 2147483647})); // 2^31
++print(self_add({foo: parseLong("9223372036854775807"), bar: parseLong("9223372036854775807")})); // 2^63-1
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8058610.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,18 @@
++=== mul ===
++4611686014132420600
++36893488130239234000
++=== self_mul ===
++4611686014132420600
++36893488130239234000
++=== sub ===
++4294967294
++18446744073709552000
++=== self_sub ===
++4294967294
++18446744073709552000
++=== add ===
++4294967294
++18446744073709552000
++=== self_add ===
++4294967294
++18446744073709552000
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8058615.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8058615: Overload resolution ambiguity involving ConsString
++ *
++ * @test
++ * @run
++ */
++
++var strw = new java.io.StringWriter();
++var bufw = new java.io.BufferedWriter(strw);
++var s = "hello ";
++bufw.write(s + "world");
++bufw.close();
++print(strw.toString());
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8058615.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++hello world
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8059443.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,39 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8059443: NPE when unboxing return values
++ *
++ * NOTE: this test can only pass when running with a JDK where
++ * JDK-8060483 is also fixed (9b37 or later).
++ *
++ * @test
++ * @run
++ */
++
++var NullProvider = Java.type("jdk.nashorn.test.models.NullProvider");
++
++if (!NullProvider.getBoolean()) { print("yay"); }
++print(NullProvider.getLong() * (1 << 33));
++print(NullProvider.getDouble() / 2.5);
++print(NullProvider.getInteger() << 1);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8059443.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,4 @@
++yay
++0
++0
++0
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8060011.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,58 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8060011: Concatenating an array and converting it to Java gives wrong result
++ *
++ * @test
++ * @run
++ */
++
++
++function compareAsJavaArrays(a1, a2) {
++ var ja1 = Java.to(a1);
++ var ja2 = Java.to(a2);
++ if (ja1.length !== ja2.length) {
++ throw "different length";
++ }
++ for (var i = 0; i < ja1.length; i++) {
++ if (ja1[i] !== ja2[i]) {
++ throw "different element at " + i;
++ }
++ }
++ if (java.util.Arrays.toString(ja1) !== java.util.Arrays.toString(ja2)) {
++ throw "different string representation";
++ }
++}
++
++compareAsJavaArrays([0, 1, 2, 3],
++ [0].concat([1, 2, 3]));
++compareAsJavaArrays([1000000000, 2000000000, 3000000000, 4000000000],
++ [1000000000].concat([2000000000, 3000000000, 4000000000]));
++compareAsJavaArrays([0.5, 1.5, 2.5, 3.5],
++ [0.5].concat([1.5, 2.5, 3.5]));
++compareAsJavaArrays(["0", "1", "2", "3"],
++ ["0"].concat(["1", "2", "3"]));
++
++
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8060101.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8060101: AssertionError: __noSuchProperty__ placeholder called from NativeJavaImporter
++ *
++ * @test
++ * @run
++ */
++
++var constant = 0.50;
++var ind = 0.0;
++
++// make sure callsites are exercised quite a few times
++// to induce megamorphic callsite for with/JavaImporter
++// combo - which triggered that AssertionError.
++for (var i = 0; i < 50; i++) {
++ var math = new JavaImporter(java.lang.StrictMath);
++ ind += 10.0;
++ with (math) {
++ StrictMath.exp(-constant*ind);
++ }
++}
++
++for (var i = 0; i < 50; i++) {
++ var math = new JavaImporter(java.lang.StrictMath);
++ try {
++ math.Foo();
++ } catch (e) {
++ if (! (e instanceof TypeError)) {
++ throw e;
++ }
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8061113.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8061113: Boolean used as optimistic call return type
++ *
++ * @test
++ * @run
++ */
++
++function testcase() {
++ var a = {x:0};
++ return (function () {return a.x === 0})();
++}
++print(testcase());
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8061113.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++true
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8061391.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,151 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8061391 - Checks that the optimistic builtin for concat is semantically
++ * correct.
++ *
++ * @test
++ * @run
++ */
++
++var maxJavaInt = 0x7fffffff;
++
++var ia = [1, 2, 3, 4];
++var la = [maxJavaInt + 1000, maxJavaInt + 2000, maxJavaInt + 3000, maxJavaInt + 4000];
++var da = [1.1, 2.2, 3.3, 4.4];
++var oa = ["one", "two", "three", "four"];
++
++var aa = [ia, la, da, oa];
++
++function concats() {
++ print("shared callsite");
++
++ print(ia);
++ print(la);
++ print(da);
++ print(oa);
++ print(aa);
++
++ for (var i = 0; i < aa.length; i++) {
++ print(aa[i].concat(aa[i][0]));
++ for (var j = 0; j < aa.length ; j++) {
++ print(aa[i].concat(aa[j]));
++ }
++ }
++}
++
++function concats_inline() {
++ print("separate callsites");
++
++ print(ia);
++ print(la);
++ print(da);
++ print(oa);
++ print(aa);
++
++ print(aa[0].concat(aa[0]));
++ print(aa[0].concat(aa[1]));
++ print(aa[0].concat(aa[2]));
++ print(aa[0].concat(aa[3]));
++ print(aa[0].concat(aa[0][0]));
++
++ print(aa[1].concat(aa[0]));
++ print(aa[1].concat(aa[1]));
++ print(aa[1].concat(aa[2]));
++ print(aa[1].concat(aa[3]));
++ print(aa[1].concat(aa[1][0]));
++
++ print(aa[2].concat(aa[0]));
++ print(aa[2].concat(aa[1]));
++ print(aa[2].concat(aa[2]));
++ print(aa[2].concat(aa[3]));
++ print(aa[2].concat(aa[2][0]));
++
++ print(aa[3].concat(aa[0]));
++ print(aa[3].concat(aa[1]));
++ print(aa[3].concat(aa[2]));
++ print(aa[3].concat(aa[3]));
++ print(aa[3].concat(aa[3][0]));
++}
++
++concats();
++concats_inline();
++
++print();
++var oldia = ia.slice(0); //clone ia
++print("oldia = " + oldia);
++ia[10] = "sparse";
++print("oldia = " + oldia);
++
++print();
++print("Redoing with sparse arrays");
++
++concats();
++concats_inline();
++
++ia = oldia;
++print("Restored ia = " + ia);
++
++function concat_expand() {
++ print("concat type expansion");
++ print(ia.concat(la));
++ print(ia.concat(da));
++ print(ia.concat(oa));
++ print(la.concat(ia));
++ print(la.concat(da));
++ print(la.concat(oa));
++ print(da.concat(ia));
++ print(da.concat(la));
++ print(da.concat(oa));
++}
++
++print();
++concat_expand();
++
++print();
++
++function concat_varargs() {
++ print("concat varargs");
++ print(ia.concat(la)); //fast
++ print(ia.concat(la, da, oa)); //slow
++ var slow = ia.concat(1, maxJavaInt * 2, 4711.17, function() { print("hello, world") }); //slow
++ print(slow);
++ return slow;
++}
++
++var slow = concat_varargs();
++
++print();
++print("sanity checks");
++slow.map(
++ function(elem) {
++ if (elem instanceof Function) {
++ elem();
++ } else {
++ print((typeof elem) + " = " + elem);
++ }
++ });
++
++print(ia.concat({key: "value"}));
++print(ia.concat({key: "value"}, {key2: "value2"}));
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8061391.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,138 @@
++shared callsite
++1,2,3,4
++2147484647,2147485647,2147486647,2147487647
++1.1,2.2,3.3,4.4
++one,two,three,four
++1,2,3,4,2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4,one,two,three,four
++1,2,3,4,1
++1,2,3,4,1,2,3,4
++1,2,3,4,2147484647,2147485647,2147486647,2147487647
++1,2,3,4,1.1,2.2,3.3,4.4
++1,2,3,4,one,two,three,four
++2147484647,2147485647,2147486647,2147487647,2147484647
++2147484647,2147485647,2147486647,2147487647,1,2,3,4
++2147484647,2147485647,2147486647,2147487647,2147484647,2147485647,2147486647,2147487647
++2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4
++2147484647,2147485647,2147486647,2147487647,one,two,three,four
++1.1,2.2,3.3,4.4,1.1
++1.1,2.2,3.3,4.4,1,2,3,4
++1.1,2.2,3.3,4.4,2147484647,2147485647,2147486647,2147487647
++1.1,2.2,3.3,4.4,1.1,2.2,3.3,4.4
++1.1,2.2,3.3,4.4,one,two,three,four
++one,two,three,four,one
++one,two,three,four,1,2,3,4
++one,two,three,four,2147484647,2147485647,2147486647,2147487647
++one,two,three,four,1.1,2.2,3.3,4.4
++one,two,three,four,one,two,three,four
++separate callsites
++1,2,3,4
++2147484647,2147485647,2147486647,2147487647
++1.1,2.2,3.3,4.4
++one,two,three,four
++1,2,3,4,2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4,one,two,three,four
++1,2,3,4,1,2,3,4
++1,2,3,4,2147484647,2147485647,2147486647,2147487647
++1,2,3,4,1.1,2.2,3.3,4.4
++1,2,3,4,one,two,three,four
++1,2,3,4,1
++2147484647,2147485647,2147486647,2147487647,1,2,3,4
++2147484647,2147485647,2147486647,2147487647,2147484647,2147485647,2147486647,2147487647
++2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4
++2147484647,2147485647,2147486647,2147487647,one,two,three,four
++2147484647,2147485647,2147486647,2147487647,2147484647
++1.1,2.2,3.3,4.4,1,2,3,4
++1.1,2.2,3.3,4.4,2147484647,2147485647,2147486647,2147487647
++1.1,2.2,3.3,4.4,1.1,2.2,3.3,4.4
++1.1,2.2,3.3,4.4,one,two,three,four
++1.1,2.2,3.3,4.4,1.1
++one,two,three,four,1,2,3,4
++one,two,three,four,2147484647,2147485647,2147486647,2147487647
++one,two,three,four,1.1,2.2,3.3,4.4
++one,two,three,four,one,two,three,four
++one,two,three,four,one
++
++oldia = 1,2,3,4
++oldia = 1,2,3,4
++
++Redoing with sparse arrays
++shared callsite
++1,2,3,4,,,,,,,sparse
++2147484647,2147485647,2147486647,2147487647
++1.1,2.2,3.3,4.4
++one,two,three,four
++1,2,3,4,,,,,,,sparse,2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4,one,two,three,four
++1,2,3,4,,,,,,,sparse,1
++1,2,3,4,,,,,,,sparse,1,2,3,4,,,,,,,sparse
++1,2,3,4,,,,,,,sparse,2147484647,2147485647,2147486647,2147487647
++1,2,3,4,,,,,,,sparse,1.1,2.2,3.3,4.4
++1,2,3,4,,,,,,,sparse,one,two,three,four
++2147484647,2147485647,2147486647,2147487647,2147484647
++2147484647,2147485647,2147486647,2147487647,1,2,3,4,,,,,,,sparse
++2147484647,2147485647,2147486647,2147487647,2147484647,2147485647,2147486647,2147487647
++2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4
++2147484647,2147485647,2147486647,2147487647,one,two,three,four
++1.1,2.2,3.3,4.4,1.1
++1.1,2.2,3.3,4.4,1,2,3,4,,,,,,,sparse
++1.1,2.2,3.3,4.4,2147484647,2147485647,2147486647,2147487647
++1.1,2.2,3.3,4.4,1.1,2.2,3.3,4.4
++1.1,2.2,3.3,4.4,one,two,three,four
++one,two,three,four,one
++one,two,three,four,1,2,3,4,,,,,,,sparse
++one,two,three,four,2147484647,2147485647,2147486647,2147487647
++one,two,three,four,1.1,2.2,3.3,4.4
++one,two,three,four,one,two,three,four
++separate callsites
++1,2,3,4,,,,,,,sparse
++2147484647,2147485647,2147486647,2147487647
++1.1,2.2,3.3,4.4
++one,two,three,four
++1,2,3,4,,,,,,,sparse,2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4,one,two,three,four
++1,2,3,4,,,,,,,sparse,1,2,3,4,,,,,,,sparse
++1,2,3,4,,,,,,,sparse,2147484647,2147485647,2147486647,2147487647
++1,2,3,4,,,,,,,sparse,1.1,2.2,3.3,4.4
++1,2,3,4,,,,,,,sparse,one,two,three,four
++1,2,3,4,,,,,,,sparse,1
++2147484647,2147485647,2147486647,2147487647,1,2,3,4,,,,,,,sparse
++2147484647,2147485647,2147486647,2147487647,2147484647,2147485647,2147486647,2147487647
++2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4
++2147484647,2147485647,2147486647,2147487647,one,two,three,four
++2147484647,2147485647,2147486647,2147487647,2147484647
++1.1,2.2,3.3,4.4,1,2,3,4,,,,,,,sparse
++1.1,2.2,3.3,4.4,2147484647,2147485647,2147486647,2147487647
++1.1,2.2,3.3,4.4,1.1,2.2,3.3,4.4
++1.1,2.2,3.3,4.4,one,two,three,four
++1.1,2.2,3.3,4.4,1.1
++one,two,three,four,1,2,3,4,,,,,,,sparse
++one,two,three,four,2147484647,2147485647,2147486647,2147487647
++one,two,three,four,1.1,2.2,3.3,4.4
++one,two,three,four,one,two,three,four
++one,two,three,four,one
++Restored ia = 1,2,3,4
++
++concat type expansion
++1,2,3,4,2147484647,2147485647,2147486647,2147487647
++1,2,3,4,1.1,2.2,3.3,4.4
++1,2,3,4,one,two,three,four
++2147484647,2147485647,2147486647,2147487647,1,2,3,4
++2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4
++2147484647,2147485647,2147486647,2147487647,one,two,three,four
++1.1,2.2,3.3,4.4,1,2,3,4
++1.1,2.2,3.3,4.4,2147484647,2147485647,2147486647,2147487647
++1.1,2.2,3.3,4.4,one,two,three,four
++
++concat varargs
++1,2,3,4,2147484647,2147485647,2147486647,2147487647
++1,2,3,4,2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4,one,two,three,four
++1,2,3,4,1,4294967294,4711.17,function() { print("hello, world") }
++
++sanity checks
++number = 1
++number = 2
++number = 3
++number = 4
++number = 1
++number = 4294967294
++number = 4711.17
++hello, world
++1,2,3,4,[object Object]
++1,2,3,4,[object Object],[object Object]
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8061391_2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Array extension check
++ *
++ * @test
++ * @run
++ */
++
++"use strict";
++var a = [1,2,3];
++Object.preventExtensions(a);
++try {
++ a[4] = 4;
++ print(a);
++} catch (e) {
++ if (!(e instanceof TypeError)) {
++ print("TypeError expected but got e");
++ }
++}
++
++if (a[0] != 1) {
++ throw "element 0 is wrong";
++}
++if (a[1] != 2) {
++ throw "element 1 is wrong";
++}
++if (a[2] != 3) {
++ throw "element 2 is wrong";
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8061391_3.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,44 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Array extension check
++ *
++ * @test
++ * @run
++ */
++
++var a = [1,2,3];
++Object.preventExtensions(a);
++a[4] = 4;
++print(a);
++if (a[0] != 1) {
++ throw "element 0 is wrong";
++}
++if (a[1] != 2) {
++ throw "element 1 is wrong";
++}
++if (a[2] != 3) {
++ throw "element 2 is wrong";
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8061391_3.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++1,2,3
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8061959.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8061959 - Checks for the existence of ArrayBufferView
++ *
++ * @test
++ * @run
++ */
++
++print(ArrayBuffer.isView(new Int8Array(4)));
++print(ArrayBuffer.isView("gorilla"));
++print(ArrayBuffer.isView());
++
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8061959.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,3 @@
++true
++false
++false
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8062024.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,40 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8062024: Issue with date.setFullYear when time other than midnight
++ *
++ * @test
++ * @option -timezone=Asia/Calcutta
++ * @run
++ */
++
++var date1 = new Date("January 01, 1950 00:00:00");
++print("Before:", date1);
++date1.setFullYear(1960);
++print("After:", date1);
++
++var date2 = new Date("January 01, 1950 00:00:01");
++print("Before:", date2);
++date2.setFullYear(1960);
++print("After:", date2);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8062024.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,4 @@
++Before: Sun Jan 01 1950 00:00:00 GMT+0530 (IST)
++After: Fri Jan 01 1960 00:00:00 GMT+0530 (IST)
++Before: Sun Jan 01 1950 00:00:01 GMT+0530 (IST)
++After: Fri Jan 01 1960 00:00:01 GMT+0530 (IST)
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8062132.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,80 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * 8062132: Nashorn incorrectly binds "this" for constructor created by another function
++ *
++ * @test
++ * @run
++ */
++
++function subclass(parentCtor, proto) {
++ function C() {
++ parentCtor.call(this);
++ }
++
++ C.prototype = Object.create(parentCtor.prototype);
++
++ for (var prop in proto) {
++ if (proto.hasOwnProperty(prop)) {
++ C.prototype[prop] = proto[prop];
++ }
++ }
++
++ return C;
++}
++
++var Parent = function() {
++ this.init();
++};
++
++Parent.prototype = {
++ init: null
++};
++
++var Child1 = subclass(Parent, {
++ prop1: 1,
++ init: function() {
++ print('child 1');
++ }
++});
++
++var Child2 = subclass(Parent, {
++ init: function() {
++ print('child 2');
++ }
++});
++
++var Child3 = subclass(Parent, {
++ prop1: 1,
++ init: function() {
++ print('child 3');
++ }
++});
++
++new Child1();
++new Child2();
++new Child3();
++new Child1();
++new Child2();
++new Child3();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8062132.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,6 @@
++child 1
++child 2
++child 3
++child 1
++child 2
++child 3
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8062381.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,53 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8062381 wrong argument chosen for charCodeAt in linker logic
++ *
++ * @test
++ * @run
++ */
++
++var s = "abcdef";
++var len = s.length + 1;
++
++function f1() {
++ for (var i = 0; i < len; i++) {
++ print(s.charCodeAt(i));
++ }
++ print(s.charCodeAt());
++}
++
++function f2() {
++ for (var i = 0; i < len; i++) {
++ print(s.charCodeAt("" + i));
++ }
++ print(s.charCodeAt());
++}
++
++f1();
++f2();
++f1();
++f2();
++
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8062381.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,32 @@
++97
++98
++99
++100
++101
++102
++NaN
++97
++97
++98
++99
++100
++101
++102
++NaN
++97
++97
++98
++99
++100
++101
++102
++NaN
++97
++97
++98
++99
++100
++101
++102
++NaN
++97
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8062583.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,51 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8062583: Throwing object with error prototype causes error proto to be caught
++ *
++ * @test
++ * @run
++ */
++
++function CustomError() {
++ this.name = "CustomError";
++}
++
++CustomError.prototype = new Error();
++
++var c1 = new CustomError();
++
++try {
++ throw c1;
++} catch (e) {
++ print(e === c1);
++ print(e === CustomError.prototype);
++ print(e.stack.replace(/\\/g, '/'));
++ print(e.nashornException.toString().replace(/\\/g, '/'));
++}
++
++var c2 = new CustomError();
++Error.captureStackTrace(c2);
++print(c2.stack.replace(/\\/g, '/'));
++print(c2.nashornException.toString().replace(/\\/g, '/'));
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8062583.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,8 @@
++true
++false
++CustomError
++ at <program> (test/script/basic/JDK-8062583.js:40)
++test/script/basic/JDK-8062583.js:40:4 CustomError
++CustomError
++ at <program> (test/script/basic/JDK-8062583.js:49)
++test/script/basic/JDK-8062583.js:49 CustomError
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8062624.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8062624: java.lang.String methods not available on concatenated strings
++ *
++ * @test
++ * @run
++ */
++
++function testStringMethods(s) {
++ print(s.startsWith("f"));
++ print(s.endsWith("r"));
++ print(Java.from(s.getBytes()));
++ print(Java.from(s.bytes));
++}
++
++var s = "f";
++testStringMethods(s);
++s = s + "oo";
++testStringMethods(s);
++testStringMethods("abc");
++s += "bar";
++s = "baz" + s;
++testStringMethods(s);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8062624.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,16 @@
++true
++false
++102
++102
++true
++false
++102,111,111
++102,111,111
++false
++false
++97,98,99
++97,98,99
++false
++true
++98,97,122,102,111,111,98,97,114
++98,97,122,102,111,111,98,97,114
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8062799.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,103 @@
++/*
++ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8062799: Binary logical expressions can have numeric types
++ *
++ * @test
++ * @run
++ */
++
++(function() {
++ var inspect = Java.type("jdk.nashorn.test.tools.StaticTypeInspector").inspect;
++
++ var b = true;
++ var i = 1;
++ var l = 4294967296;
++ var d = 2.1;
++ var o = "foo";
++
++ print(inspect(b || b, "b || b"));
++ print(inspect(b || i, "b || i"));
++ print(inspect(b || l, "b || l"));
++ print(inspect(b || d, "b || d"));
++ print(inspect(b || o, "b || o"));
++
++ print(inspect(i || b, "i || b"));
++ print(inspect(i || i, "i || i"));
++ print(inspect(i || l, "i || l"));
++ print(inspect(i || d, "i || d"));
++ print(inspect(i || o, "i || o"));
++
++ print(inspect(l || b, "l || b"));
++ print(inspect(l || i, "l || i"));
++ print(inspect(l || l, "l || l"));
++ print(inspect(l || d, "l || d"));
++ print(inspect(l || o, "l || o"));
++
++ print(inspect(d || b, "d || b"));
++ print(inspect(d || i, "d || i"));
++ print(inspect(d || l, "d || l"));
++ print(inspect(d || d, "d || d"));
++ print(inspect(d || o, "d || o"));
++
++ print(inspect(o || b, "o || b"));
++ print(inspect(o || i, "o || i"));
++ print(inspect(o || l, "o || l"));
++ print(inspect(o || d, "o || d"));
++ print(inspect(o || o, "o || o"));
++
++ print(inspect(b && b, "b && b"));
++ print(inspect(b && i, "b && i"));
++ print(inspect(b && l, "b && l"));
++ print(inspect(b && d, "b && d"));
++ print(inspect(b && o, "b && o"));
++
++ print(inspect(i && b, "i && b"));
++ print(inspect(i && i, "i && i"));
++ print(inspect(i && l, "i && l"));
++ print(inspect(i && d, "i && d"));
++ print(inspect(i && o, "i && o"));
++
++ print(inspect(l && b, "l && b"));
++ print(inspect(l && i, "l && i"));
++ print(inspect(l && l, "l && l"));
++ print(inspect(l && d, "l && d"));
++ print(inspect(l && o, "l && o"));
++
++ print(inspect(d && b, "d && b"));
++ print(inspect(d && i, "d && i"));
++ print(inspect(d && l, "d && l"));
++ print(inspect(d && d, "d && d"));
++ print(inspect(d && o, "d && o"));
++
++ print(inspect(o && b, "o && b"));
++ print(inspect(o && i, "o && i"));
++ print(inspect(o && l, "o && l"));
++ print(inspect(o && d, "o && d"));
++ print(inspect(o && o, "o && o"));
++})();
++
++
++
++
+\ No newline at end of file
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8062799.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,50 @@
++b || b: boolean
++b || i: boolean
++b || l: boolean
++b || d: boolean
++b || o: boolean
++i || b: int
++i || i: int
++i || l: long
++i || d: double
++i || o: int
++l || b: long
++l || i: long
++l || l: long
++l || d: double
++l || o: long
++d || b: double
++d || i: double
++d || l: double
++d || d: double
++d || o: double
++o || b: object
++o || i: object
++o || l: object
++o || d: object
++o || o: object
++b && b: boolean
++b && i: int
++b && l: long
++b && d: double
++b && o: object
++i && b: boolean
++i && i: int
++i && l: long
++i && d: double
++i && o: object
++l && b: boolean
++l && i: long
++l && l: long
++l && d: double
++l && o: object
++d && b: boolean
++d && i: double
++d && l: double
++d && d: double
++d && o: object
++o && b: boolean
++o && i: int
++o && l: long
++o && d: double
++o && o: object
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8062937.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,46 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8062937 - GlobalConstants produces wrong result with defineProperty and index setters
++ *
++ * @test
++ * @run
++ */
++
++var x = 1;
++for (var i = 2; i < 5; i++) {
++ print(x);
++ Object.defineProperty(this, "x", {value: i});
++}
++print(x);
++
++print();
++
++var name = "y";
++var y = 1;
++for (var i = 2; i < 5; i++) {
++ print(y);
++ this[name] = i;
++}
++print(y);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8062937.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,9 @@
++1
++2
++3
++4
++
++1
++2
++3
++4
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8066221.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8066221: anonymous function statement name clashes with another symbol
++ * (compile-only test)
++ *
++ * @test
++ */
++
++x3 = function x1(x3) { function (){} };
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8066224.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8066224: fixes for folding a constant-test ternary operator
++ *
++ * @test
++ * @run
++ */
++
++print((function(){
++ if(false ? 0 : '') {
++ throw false;
++ } else if (x = this) {
++ var x = x;
++ }
++ return x === this;
++})())
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8066224.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++true
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8066225.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8066225: NPE in MethodEmitter with duplicate integer switch cases
++ *
++ * @test
++ * @run
++ */
++
++(function (x){
++ switch(x) {
++ case 44: for (var x in {}) {x}; print("1");
++ case 44: print("2");
++ }
++})(44);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8066225.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,2 @@
++1
++2
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8066227.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,40 @@
++/*
++ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8066227: CodeGenerator load unitialized slot
++ *
++ * @test
++ * @run
++ */
++
++print((function () { var x; (x += x = 0); return x; })());
++print((function () { var x; (x -= x = 0); return x; })());
++print((function () { var x; (x *= x = 0); return x; })());
++print((function () { var x; (x /= x = 0); return x; })());
++print((function () { var x; (x %= x = 0); return x; })());
++print((function () { var x; (x <<= x = 0); return x; })());
++print((function () { var x; (x >>= x = 0); return x; })());
++print((function () { var x; (x >>>= x = 0); return x; })());
++print((function () { var x; (x |= x = 0); return x; })());
++print((function () { var x; (x &= x = 0); return x; })());
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8066227.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,10 @@
++NaN
++NaN
++NaN
++NaN
++NaN
++0
++0
++0
++0
++0
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8066230.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8066230: Undefined object type assertion when computing TypeBounds
++ *
++ * @test
++ * @run
++ */
++
++(function() { void null + 0; })();
++(function() { var x; x += void x; })();
++(function() { var a = true + x, x; })();
++print("SUCCESS");
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8066230.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++SUCCESS
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8066236.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,46 @@
++/*
++ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8066236: RuntimeNode forces copy creation on visitation
++ *
++ * @test
++ * @run
++ */
++
++// Note: we're using Function("code") instead of (function(){ code }) so that
++// we don't trigger parser API validation in JDK-8008448 tests. The test code
++// encapsulated in functions below can't be correctly handled by the parser API
++// currently, as it contains parser-generated REFERENCE_ERROR runtime nodes.
++try {
++ Function("L: {this = x;break L}")();
++} catch (e) {
++ print("threw ReferenceError: " + (e instanceof ReferenceError));
++}
++try {
++ Function("L:with(this--)break L;")();
++} catch (e) {
++ print("threw ReferenceError: " + (e instanceof ReferenceError));
++}
++Function("L:with(Object in Object)break L;")();
++print("SUCCESS");
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8066236.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,3 @@
++threw ReferenceError: true
++threw ReferenceError: true
++SUCCESS
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8066669.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,58 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8066669: dust.js performance regression caused by primitive field conversion
++ *
++ * @test
++ * @run
++ */
++
++// Make sure index access on Java objects is working as expected.
++var map = new java.util.HashMap();
++
++map["foo"] = "bar";
++map[1] = 2;
++map[false] = true;
++map[null] = 0;
++
++print(map);
++
++var keys = map.keySet().iterator();
++
++while(keys.hasNext()) {
++ var key = keys.next();
++ print(typeof key, key);
++}
++
++print(typeof map["foo"], map["foo"]);
++print(typeof map[1], map[1]);
++print(typeof map[false], map[false]);
++print(typeof map[null], map[null]);
++
++print(map.foo);
++print(map.false);
++print(map.null);
++
++map.foo = "baz";
++print(map);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8066669.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,13 @@
++{null=0, 1=2, false=true, foo=bar}
++object null
++number 1
++boolean false
++string foo
++string bar
++number 2
++boolean true
++number 0
++bar
++null
++null
++{null=0, 1=2, false=true, foo=baz}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8066932.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8066932: __noSuchMethod__ binds to this-object without proper guard
++ *
++ * @test
++ * @run
++ */
++
++function C(id) {
++ this.id = id;
++}
++
++C.prototype.__noSuchMethod__ = function(name, args) {
++ return this.id;
++};
++
++function test(id) {
++ var c = new C(id);
++ return c.nonExistingMethod();
++}
++
++for (var i = 0; i < 30; i++) {
++ if (test(i) !== i) {
++ throw new Error("Wrong result from noSuchMethod in iteration " + i);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8067136.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8067136: BrowserJSObjectLinker does not handle call on JSObjects
++ *
++ * @test
++ * @option -scripting
++ * @run
++ */
++
++// call on netscape.javascript.JSObject
++
++function main() {
++ var JSObject;
++ try {
++ JSObject = Java.type("netscape.javascript.JSObject");
++ } catch (e) {
++ if (e instanceof java.lang.ClassNotFoundException) {
++ // pass vacuously by emitting the .EXPECTED file content
++ var str = readFully(__DIR__ + "JDK-8067136.js.EXPECTED");
++ print(str.substring(0, str.length - 1));
++ return;
++ } else{
++ fail("unexpected exception for JSObject", e);
++ }
++ }
++ test(JSObject);
++}
++
++function test(JSObject) {
++ var obj = new (Java.extend(JSObject))() {
++ getMember: function(name) {
++ if (name == "func") {
++ return new (Java.extend(JSObject)) {
++ call: function(n) {
++ print("func called");
++ }
++ }
++ }
++ return name.toUpperCase();
++ },
++
++ };
++
++ obj.func();
++}
++
++main();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8067136.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++func called
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8068573.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,57 @@
++/*
++ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8068573: POJO setter using [] syntax throws an exception
++ *
++ * @test
++ * @run
++ */
++
++// Invoke a setter using []. It's important that the setter returns void.
++var pb = new (Java.type("jdk.nashorn.test.models.PropertyBind"))
++var n = "writeOnly";
++pb[n] = 2;
++Assert.assertEquals(pb.peekWriteOnly(), 2);
++
++// Invoke an overloaded setter using []. It's important that one of the
++// overloads returns void.
++var os = new (Java.type("jdk.nashorn.test.models.OverloadedSetter"))
++var n2 = "color";
++os[n2] = 3; // exercise int overload
++Assert.assertEquals(os.peekColor(), "3");
++os[n2] = "blue"; // exercise string overload
++Assert.assertEquals(os.peekColor(), "blue");
++for each(var x in [42, "42"]) {
++ os[n2] = x; // exercise both overloads in the same call site
++ Assert.assertEquals(os.peekColor(), "42");
++}
++
++// Invoke an overloaded method using [], repeatedly in the same call
++// site. It's important that one of the overloads returns void.
++var n3="foo";
++var param=["xyz", 1, "zyx", 2];
++var expected=["boo", void 0, "boo", void 0];
++for(var i in param) {
++ Assert.assertEquals(os[n3](param[i]), expected[i]);
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/JDK-8069002.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8069002: NPE on invoking null (8068889 regression)
++ *
++ * @test
++ * @run
++ */
++
++try {
++ null();
++} catch (e) {
++ Assert.assertTrue(e instanceof TypeError);
++}
+--- ./nashorn/test/script/basic/JDK_8005848.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/JDK_8005848.js Wed Feb 04 12:14:47 2015 -0800
+@@ -22,7 +22,7 @@
+ */
+
+ /**
+- * JDK-8005848 : assigning to global toString variable affects Object.prototype.toString
++ * JDK-8005848 : assigning to global toString variable affects Object.prototype.toString
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/NASHORN-100.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-100.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-101.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-101.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-102.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-102.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-103.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-103.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-104.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-104.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-105.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-105.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * NASHORN-105 : parseFloat function is not spec. compliant.
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/NASHORN-106.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-106.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-107.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-107.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-108.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-108.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-109.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-109.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-11.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-11.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-111.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-111.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -31,7 +31,7 @@
+ try {
+ throw new TypeError("type error");
+ } catch (e) {
+- // This used to throw ClassCastException
++ // This used to throw ClassCastException
+ // ThrowException cannot be cast to ScriptObject
+ print(JSON.stringify(e));
+ }
+--- ./nashorn/test/script/basic/NASHORN-113.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-113.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-114.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-114.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-115.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-115.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-117.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-117.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,7 +28,7 @@
+ * @run
+ */
+
+-// The following code results in StackOverflowError
++// The following code results in StackOverflowError
+
+ var i0 = "";
+ var o0 = "";
+--- ./nashorn/test/script/basic/NASHORN-118.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-118.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * NASHORN-118 : Function.prototype.apply should accept "arguments" object
++ * NASHORN-118 : Function.prototype.apply should accept "arguments" object
+ * of another function as second argument.
+ *
+ * @test
+--- ./nashorn/test/script/basic/NASHORN-119.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-119.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-12.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-12.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-120.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-120.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-122.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-122.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-126.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-126.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -26,9 +26,9 @@
+ *
+ * @test
+ * @run
+- */
++ */
+
+ print(String(1000000000000000000000) === "1e+21");
+ print(String(0.000000000100000000000) === "1e-10");
+
+-
++
+--- ./nashorn/test/script/basic/NASHORN-127.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-127.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,11 +29,11 @@
+ */
+
+ try {
+- try {
++ try {
+ throw ReferenceError(17);
+- } catch (e) {
+- print(e);
+- throw TypeError(4711);
++ } catch (e) {
++ print(e);
++ throw TypeError(4711);
+ }
+-} catch (e) { print(e);
++} catch (e) { print(e);
+ }
+--- ./nashorn/test/script/basic/NASHORN-130.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-130.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-132.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-132.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-133.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-133.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-135.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-135.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-136.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-136.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -32,7 +32,7 @@
+ valueOf: function() {
+ print("obj1.valueOf");
+ return 1;
+- },
++ },
+
+ toString: function() {
+ print("obj1.toString");
+--- ./nashorn/test/script/basic/NASHORN-14.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-14.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,7 +30,7 @@
+ */
+
+
+-function callback() {
++function callback() {
+ print('callback with args ' + Array.prototype.join.apply(arguments))
+ }
+
+--- ./nashorn/test/script/basic/NASHORN-148.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-148.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,13 +23,13 @@
+
+ /**
+ * NASHORN-148 : arguments element deletion/resurrection does not work as expected
+- *
++ *
+ * @test
+ * @run
+ */
+
+
+-function func(x) {
++function func(x) {
+ print("func.x = " + x);
+ print("func.arguments[0] = " + arguments[0]);
+
+@@ -43,7 +43,7 @@
+ print("func.arguments[0] = " + arguments[0]);
+
+ // delete arguments[0]
+- delete arguments[0];
++ delete arguments[0];
+ print("func.x = " + x);
+ print("func.arguments[0] = " + arguments[0]);
+
+--- ./nashorn/test/script/basic/NASHORN-15.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-15.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-153.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-153.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-156.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-156.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,8 +29,8 @@
+ * @run
+ */
+
+-var obj = {
+- get foo() { return 3; }
++var obj = {
++ get foo() { return 3; }
+ };
+
+ if (obj.foo != 3) {
+--- ./nashorn/test/script/basic/NASHORN-157.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-157.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,7 +28,7 @@
+ * @run
+ */
+
+-try {
++try {
+ print((x, 1));
+ fail("#1 ReferenceError should have been thrown");
+ } catch (e) {
+--- ./nashorn/test/script/basic/NASHORN-163.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-163.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * NASHORN-163 : Object.keys(o) should only enumerate o's own properties
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/NASHORN-164.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-164.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,7 +30,7 @@
+
+ var obj2 = { bar: 'hello' };
+ var obj = Object.create(obj2);
+-obj.foo = 22;
++obj.foo = 22;
+
+ if (JSON.stringify(obj) != '{"foo":22}') {
+ throw Error("expected '{\"foo\":22}' got " + JSON.stringify(obj));
+--- ./nashorn/test/script/basic/NASHORN-165.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-165.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-166.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-166.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-168.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-168.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-169.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-169.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-172.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-172.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,12 +28,12 @@
+ * @run
+ */
+
+-if (delete x !== true) {
++if (delete x !== true) {
+ fail('#1: delete x === true');
+ }
+
+-if (delete this.x !== true) {
+- fail('#2: delete this.x === true');
++if (delete this.x !== true) {
++ fail('#2: delete this.x === true');
+ }
+
+ var y = 23;
+--- ./nashorn/test/script/basic/NASHORN-173.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-173.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-174.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-174.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -33,7 +33,7 @@
+ if (nums.length != 4) {
+ fail("#1: split result expected to be of length 4");
+ }
+-
++
+ function check(index, value) {
+ if (nums[index] != value) {
+ fail("expected value @ " + index + " is " + value);
+--- ./nashorn/test/script/basic/NASHORN-175.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-175.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-176.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-176.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-177.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-177.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * NASHORN-177 : null array elements become undefined on assignment
++ * NASHORN-177 : null array elements become undefined on assignment
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/NASHORN-178.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-178.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-179.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-179.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-18.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-18.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-181.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-181.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -32,7 +32,7 @@
+
+ try {
+ var obj = Object.create({}, props);
+- if (! obj.hasOwnProperty("foo")) {
++ if (! obj.hasOwnProperty("foo")) {
+ fail("obj does not have 'foo' property");
+ }
+ } catch (e) {
+--- ./nashorn/test/script/basic/NASHORN-182.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-182.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,7 +30,7 @@
+
+ function callback(prev, cur, idx, obj) {
+ fail("callback with " + idx);
+-}
++}
+
+ // array-like object
+ var obj = { 1: 1, 2: 2, length: 3 };
+--- ./nashorn/test/script/basic/NASHORN-183.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-183.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-184.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-184.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-185.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-185.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-187.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-187.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -31,16 +31,16 @@
+ var obj = {};
+
+ try {
+- Object.defineProperty(obj, "foo", {
+- get: function() { return 22; },
+- set: undefined
++ Object.defineProperty(obj, "foo", {
++ get: function() { return 22; },
++ set: undefined
+ });
+ } catch (e) {
+ fail("failed", e);
+ }
+
+ try {
+- Object.defineProperty(obj, "bar", {
++ Object.defineProperty(obj, "bar", {
+ get: undefined
+ });
+ } catch (e) {
+--- ./nashorn/test/script/basic/NASHORN-188.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-188.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-19.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-19.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -38,8 +38,8 @@
+
+ do {
+ with(myscope) {
+- myvalue = 12;
+- break;
++ myvalue = 12;
++ break;
+ }
+ } while (false);
+
+@@ -62,15 +62,15 @@
+ var scope2 = {value:20};
+ while (true) {
+ with (scope) {
+- print(value);
+- value = 11;
+- print(value);
+- with (scope2) {
+- print(value);
+- value = 21;
+- print(value);
+- break;
+- }
++ print(value);
++ value = 11;
++ print(value);
++ with (scope2) {
++ print(value);
++ value = 21;
++ print(value);
++ break;
++ }
+ }
+ }
+
+@@ -83,19 +83,19 @@
+ var scope = {value:10};
+ var scope2 = {value:20};
+ while (true) {
+- with (scope) {
+- print(value);
+- value = 11;
+- print(value);
+- with (scope2) {
+- print(value);
+- value = 21;
+- print(value);
+- break;
+- }
+- }
++ with (scope) {
++ print(value);
++ value = 11;
++ print(value);
++ with (scope2) {
++ print(value);
++ value = 21;
++ print(value);
++ break;
++ }
+ }
+-
++ }
++
+ print(value);
+ }
+
+@@ -104,14 +104,14 @@
+ var value = "hello";
+ var scope = {value:10};
+ while (true) {
+- with (scope) {
+- print(value);
+- value = 11;
+- print(value);
+- if (value > ten()) {
+- break;
+- }
+- }
++ with (scope) {
++ print(value);
++ value = 11;
++ print(value);
++ if (value > ten()) {
++ break;
++ }
++ }
+ }
+ print(value);
+ }
+@@ -123,24 +123,24 @@
+ var scope2 = {value:20};
+ var outer = 0;
+ while (outer < 5) {
+- var i=0;
+- while (i < 10) {
+- with(scope) {
+- print("loop header "+i);
+- with (scope2) {
+- value = 11;
+- i++;
+- if ((i & 1) != 0) {
+- print("continue");
+- continue;
+- }
+- }
+- }
+- print(value);
+- }
+- outer++;
++ var i=0;
++ while (i < 10) {
++ with(scope) {
++ print("loop header "+i);
++ with (scope2) {
++ value = 11;
++ i++;
++ if ((i & 1) != 0) {
++ print("continue");
++ continue;
++ }
++ }
++ }
++ print(value);
+ }
+-}
++ outer++;
++ }
++}
+
+ //continue one level
+ function test4() {
+@@ -148,15 +148,15 @@
+ var scope = {value:10};
+ var i=0;
+ while (i < 10) {
+- print("loop header "+i);
+- with (scope) {
+- value = 11;
+- i++;
+- if ((i & 1) != 0) {
+- print("continue");
+- continue;
+- }
+- }
++ print("loop header "+i);
++ with (scope) {
++ value = 11;
++ i++;
++ if ((i & 1) != 0) {
++ print("continue");
++ continue;
++ }
++ }
+ }
+ print(value);
+ }
+@@ -170,24 +170,24 @@
+ var outer = 0;
+ outer_label:
+ while (outer < 5) {
+- var i=0;
+- while (i < 10) {
+- with(scope) {
+- print("loop header "+i);
+- with (scope2) {
+- value = 11;
+- i++;
+- if ((i & 1) != 0) {
+- print("continue");
+- outer++;
+- continue outer_label;
+- }
+- }
+- }
+- print(value);
+- }
++ var i=0;
++ while (i < 10) {
++ with(scope) {
++ print("loop header "+i);
++ with (scope2) {
++ value = 11;
++ i++;
++ if ((i & 1) != 0) {
++ print("continue");
++ outer++;
++ continue outer_label;
++ }
++ }
++ }
++ print(value);
+ }
+-}
++ }
++}
+
+ //labelled break
+ function test6() {
+@@ -196,21 +196,21 @@
+ var scope2 = {value:20};
+ outer:
+ {
+- var i=0;
+- while (i < 10) {
+- with(scope) {
+- print("loop header "+i);
+- with (scope2) {
+- value = 11;
+- i++;
+- if ((i & 1) != 0) {
+- print("break");
+- break outer;
+- }
+- }
+- }
+- print(value);
+- }
++ var i=0;
++ while (i < 10) {
++ with(scope) {
++ print("loop header "+i);
++ with (scope2) {
++ value = 11;
++ i++;
++ if ((i & 1) != 0) {
++ print("break");
++ break outer;
++ }
++ }
++ }
++ print(value);
++ }
+ }
+ }
+
+@@ -218,32 +218,32 @@
+ function test7() {
+ var value = "hello";
+ var scope = {value:10};
+- var scope2 = {value:20};
++ var scope2 = {value:20};
+ var global = false;
+ try {
+- with(scope) {
+- try {
+- print(value);
+- value = 4711;
+- print(value);
+- with(scope2) {
+- print(value);
+- value = 17;
+- print(value);
+- global = true;
+- throw "inner";
+- }
+- } catch (ei) {
+- print(ei);
+- print(value);
+- if (global) {
+- throw "outer";
+- }
+- }
+- }
++ with(scope) {
++ try {
++ print(value);
++ value = 4711;
++ print(value);
++ with(scope2) {
++ print(value);
++ value = 17;
++ print(value);
++ global = true;
++ throw "inner";
++ }
++ } catch (ei) {
++ print(ei);
++ print(value);
++ if (global) {
++ throw "outer";
++ }
++ }
++ }
+ } catch (eo) {
+- print(eo);
+- print(value);
++ print(eo);
++ print(value);
+ }
+ print(value);
+ }
+--- ./nashorn/test/script/basic/NASHORN-190.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-190.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,7 +28,7 @@
+ * @run
+ */
+
+-var obj = {
++var obj = {
+ 20: 'world', "2.3": 'hello'
+ };
+
+--- ./nashorn/test/script/basic/NASHORN-192.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-192.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * NASHORN-192 : User defined property setter or getter with extra arguments or lesser argument fails by throwing exception
+- *
++ *
+ * @test
+ * @run
+ */
+@@ -59,7 +59,7 @@
+ set: function(obj1, obj2, obj3) {
+ this.val = obj1;
+ }
+-});
++});
+
+ try {
+ obj.prop = 33;
+--- ./nashorn/test/script/basic/NASHORN-194.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-194.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-196.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-196.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -33,7 +33,7 @@
+ Object.defineProperty(arr, "length", {
+ value: -0
+ });
+-
++
+ if (arr.length !== 0) {
+ fail("array length is not zero!");
+ }
+--- ./nashorn/test/script/basic/NASHORN-198.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-198.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-20.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-20.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-201.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-201.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-202.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-202.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-203.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-203.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-204.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-204.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-205.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-205.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -54,7 +54,7 @@
+ } catch (e) {
+ fail("failed", e);
+ }
+-
++
+ var newDesc = Object.getOwnPropertyDescriptor(obj, "foo");
+ if (! newDesc.hasOwnProperty("value")) {
+ fail("'value' missing!!");
+--- ./nashorn/test/script/basic/NASHORN-206.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-206.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-207.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-207.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -37,7 +37,7 @@
+ } catch (e) {
+ if (! (e instanceof SyntaxError)) {
+ fail("#2 SyntaxError expected but got " + e);
+- }
++ }
+ }
+
+ // cannot delete function parameter variable
+@@ -47,7 +47,7 @@
+ } catch(e) {
+ if (! (e instanceof SyntaxError)) {
+ fail("#4 SyntaxError expected but got " + e);
+- }
++ }
+ }
+
+ // assignment can't be used to define as new variable
+--- ./nashorn/test/script/basic/NASHORN-207_2.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-207_2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-208.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-208.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * NASHORN-208
++ * NASHORN-208
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/NASHORN-209.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-209.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,8 +28,8 @@
+ * @run
+ */
+
+-var obj = {
+- in: 11, class: 'hello', try: false,
++var obj = {
++ in: 11, class: 'hello', try: false,
+ typeof: 456, instanceof: 'world',
+ catch: function() { print("catch called"); }
+ };
+--- ./nashorn/test/script/basic/NASHORN-21.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-21.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-211.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-211.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-212.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-212.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-213.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-213.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-215.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-215.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-216.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-216.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-217.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-217.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-219.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-219.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-22.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-22.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-221.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-221.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-222.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-222.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-223.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-223.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-225.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-225.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-226.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-226.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-227.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-227.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-228.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-228.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -51,4 +51,4 @@
+ fail("typeof key of a string is not 'string'");
+ }
+ }
+-
++
+--- ./nashorn/test/script/basic/NASHORN-229.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-229.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -39,4 +39,4 @@
+ }
+
+ load(__DIR__ + 'NASHORN-229_subtest.js');
+-
++
+--- ./nashorn/test/script/basic/NASHORN-229_subtest.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-229_subtest.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,7 +30,7 @@
+ function func2() {
+ var obj2 = {
+ get bar() { return 343; }
+- };
++ };
+
+ return (obj2.bar === 343);
+ }
+--- ./nashorn/test/script/basic/NASHORN-23.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-23.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * NASHORN-23: calling function valued global variable before it is initialized should fail.
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/NASHORN-232.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-232.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-234.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-234.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-235.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-235.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-236.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-236.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-237.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-237.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-239.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-239.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-24.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-24.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * NASHORN-24: function local var assignments should resolve to 'with' scope if found in scope.
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/NASHORN-241.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-241.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,7 +30,7 @@
+
+ try {
+ new 1;
+- fail('new "1" should have thrown TypeError');
++ fail('new "1" should have thrown TypeError');
+ } catch (e) {
+ if (! (e instanceof TypeError)) {
+ fail('expected TypeError, got ' + e, e);
+@@ -40,7 +40,7 @@
+ try {
+ var x = "1";
+ new x;
+- fail('var x = "1"; new x should have thrown TypeError');
++ fail('var x = "1"; new x should have thrown TypeError');
+ } catch (e) {
+ if (! (e instanceof TypeError)) {
+ fail('var x = "1"; new x - expected TypeError, got ' + e, e);
+@@ -50,10 +50,10 @@
+ try {
+ var x = "1";
+ new x();
+- fail('var x = "1"; new x() should have thrown TypeError');
++ fail('var x = "1"; new x() should have thrown TypeError');
+ } catch (e) {
+ if (! (e instanceof TypeError)) {
+- fail('var x = "1"; new x() - expected TypeError, got ' + e);
++ fail('var x = "1"; new x() - expected TypeError, got ' + e);
+ }
+ }
+
+--- ./nashorn/test/script/basic/NASHORN-242.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-242.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-245.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-245.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-247.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-247.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-25.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-25.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-251.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-251.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-252.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-252.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-253.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-253.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-256.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-256.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-258.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-258.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,28 +30,28 @@
+
+ function test3(a) {
+ for (i = 0; i < a.length ; i++) {
+- for (j = 0; j < a[i].length ; j++) {
+- for (k = 0; k < a[i][j].length ; k++) {
+- a[i][j][k] *= 8;
+- }
+- }
++ for (j = 0; j < a[i].length ; j++) {
++ for (k = 0; k < a[i][j].length ; k++) {
++ a[i][j][k] *= 8;
++ }
++ }
+ }
+ }
+
+ function test3local(a) {
+ for (var i = 0; i < a.length ; i++) {
+- for (var j = 0; j < a[i].length ; j++) {
+- for (var k = 0; k < a[i][j].length ; k++) {
+- a[i][j][k] *= 8;
+- }
+- }
++ for (var j = 0; j < a[i].length ; j++) {
++ for (var k = 0; k < a[i][j].length ; k++) {
++ a[i][j][k] *= 8;
++ }
++ }
+ }
+ }
+
+ var array = [ [[1,1,1],[1,1,1],[1,1,1]],
+- [[1,1,1],[1,1,1],[1,1,1]],
+- [[1,1,1],[1,1,1],[1,1,1]] ];
+-
++ [[1,1,1],[1,1,1],[1,1,1]],
++ [[1,1,1],[1,1,1],[1,1,1]] ];
++
+ test3(array);
+ print(array);
+
+@@ -59,17 +59,17 @@
+ print(array);
+
+ function outer() {
+-
++
+ var array2 = [ [[1,1,1],[1,1,1],[1,1,1]],
+- [[1,1,1],[1,1,1],[1,1,1]],
+- [[1,1,1],[1,1,1],[1,1,1]] ];
+-
++ [[1,1,1],[1,1,1],[1,1,1]],
++ [[1,1,1],[1,1,1],[1,1,1]] ];
++
+ var f = function inner() {
+- for (var i = 0; i < array2.length ; i++) {
+- for (var j = 0; j < array2[i].length ; j++) {
+- array2[i][j][2] *= 8;
+- }
+- }
++ for (var i = 0; i < array2.length ; i++) {
++ for (var j = 0; j < array2[i].length ; j++) {
++ array2[i][j][2] *= 8;
++ }
++ }
+ };
+
+ f();
+--- ./nashorn/test/script/basic/NASHORN-26.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-26.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-260.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-260.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-261.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-261.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -75,7 +75,7 @@
+ }
+ }
+
+-// pass no args to our overwritten eval
++// pass no args to our overwritten eval
+ // the new eval should not print anything (no hidden args passed)
+ eval();
+
+--- ./nashorn/test/script/basic/NASHORN-262.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-262.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * NASHORN-262 : for statement iterator variable is not checked in strict mode
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/NASHORN-263.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-263.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-264.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-264.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-265.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-265.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,27 +1,27 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+-/**
++/**
+ * NASHORN-265 with scope access within a nested function can't access global var
+ *
+ * @test
+--- ./nashorn/test/script/basic/NASHORN-266.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-266.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-269.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-269.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-27.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-27.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-270.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-270.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-271.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-271.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,7 +28,7 @@
+ * @run
+ */
+
+-var res = JSON.stringify(23, function(k,v) {
++var res = JSON.stringify(23, function(k,v) {
+ return (v == 23)? [1, 2] : v;
+ });
+
+@@ -36,8 +36,8 @@
+ fail("#1 expected '[1,2]' got " + res);
+ }
+
+-var res = JSON.stringify(23, function(k,v) {
+- return (v == 23)? { x: 1, y: 'hello' } : v;
++var res = JSON.stringify(23, function(k,v) {
++ return (v == 23)? { x: 1, y: 'hello' } : v;
+ });
+
+ if (res !== '{"x":1,"y":"hello"}') {
+--- ./nashorn/test/script/basic/NASHORN-275.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-275.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-276.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-276.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-277.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-277.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-278.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-278.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-28.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-28.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-281.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-281.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-284.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-284.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-285.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-285.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,31 +28,31 @@
+ * @run
+ */
+
+-function do_not_loop_forever() {
++function do_not_loop_forever() {
+ var sum = 0;
+- for (var i = 0; i < 4711; i++) {
+- sum += i;
+- if (i >= 0) {
+- continue;
+- }
+- return sum;
+- }
++ for (var i = 0; i < 4711; i++) {
++ sum += i;
++ if (i >= 0) {
++ continue;
++ }
++ return sum;
++ }
+ return sum;
+ }
+
+
+ function still_tag_terminal() {
+ var sum = 0;
+- for (var i = 0; i < 4711; i++) {
+- sum += i;
+- for (var j = 0; j < 4712; j++) {
+- sum += j;
+- if (j & 1) {
+- continue;
+- }
+- }
+- return sum;
+- }
++ for (var i = 0; i < 4711; i++) {
++ sum += i;
++ for (var j = 0; j < 4712; j++) {
++ sum += j;
++ if (j & 1) {
++ continue;
++ }
++ }
++ return sum;
++ }
+ return sum;
+ }
+
+--- ./nashorn/test/script/basic/NASHORN-288.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-288.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-29.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-29.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-293.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-293.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-294.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-294.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-296.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-296.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-297.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-297.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-30.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-30.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,11 +30,11 @@
+
+ var obj = {
+ valueOf: function() {
+- print("valueOf call");
+- return -2
++ print("valueOf call");
++ return -2
+ },
+
+- toString: function() {
++ toString: function() {
+ print("toString call");
+ return "-2";
+ }
+--- ./nashorn/test/script/basic/NASHORN-300.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-300.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,9 +29,9 @@
+ */
+
+ function func1(foo) {
+- if (foo) {
++ if (foo) {
+ var encoding = arguments[3];
+- }
++ }
+
+ var s = encoding;
+ }
+--- ./nashorn/test/script/basic/NASHORN-301.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-301.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-304.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-304.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-310.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-310.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-318.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-318.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-32.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-32.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-321.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-321.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-323.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-323.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-324.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-324.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-33.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-33.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-331.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-331.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * NASHORN-331 : Nan compares
++ * NASHORN-331 : Nan compares
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/NASHORN-337.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-337.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * NASHORN-337 - Erroneous DCMPL/DCMPG instructions were generated
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/NASHORN-34.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-34.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-340.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-340.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-349.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-349.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-354.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-354.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-355.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-355.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-36.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-36.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-365.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-365.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-366.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-366.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-368.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-368.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-37.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-37.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * NASHORN-37 : object and array properties defined with special keys can be accessed be by special or string keys
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/NASHORN-375.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-375.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-376.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-376.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/NASHORN-377-big-endian.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * NASHORN-377: Typed arrays.
++ *
++ * @test
++ * @run
++ * @bigendian
++ */
++
++var dir = typeof(__DIR__) == 'undefined' ? "test/script/basic/" : __DIR__;
++load(dir + "NASHORN-377-payload.js");
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/NASHORN-377-big-endian.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,34 @@
++8 8 true undefined
++[object ArrayBuffer] [object ArrayBuffer] [object Int8Array]
++0 8 8 1
++0 8 8 1
++0 8 8 1
++0 8 4 2
++0 8 4 2
++0 8 2 4
++0 8 2 4
++0 8 2 4
++0 8 1 8
++7071727374-807677 7071727374807677
++727374-807677 2 6
++72737480 2 4
++71727374 1 4
++717273748076
++7071727374807677 1886483059 1954575991
++70717273-1020305 1886483059 -16909061
++70717273fefdfcfb 1886483059 4278058235
++40490fdafefdfcfb 2
++400921fb4d12d84a 1
++400921fb4d12d84a 1074340347 1293080650
++00000000400921fb4d12d84a
++400921fb4d12-27b6 400921fb4d12d84a
++00-100804d12-27b6 ffff00804d12d84a
++0 1 2 3 4 5 6 7
++0102030405060708
++subarray(2,4)=0304 subarray(-6,-4)=0304
++010203040506
++03040506 0405
++0102030405060708090a0b0c0d0e0f10
++slice(4,8)=05060708 slice(-8,-4)=090a0b0c
++0102030405060708090a0b0c
++060708090a0b
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/NASHORN-377-payload.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,226 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * NASHORN-377: Typed arrays. Payload for litte and big endian platforms.
++ *
++ * @subtest
++ * @run
++ */
++
++var types = [Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];
++
++//---------------------------------------------------------------------------
++// utility functions
++//---------------------------------------------------------------------------
++function tohex(d, w) {
++ var hex = Number(d).toString(16);
++ var pad = (w ? w : 8) - hex.length;
++ hex = "00000000".substr(0, pad) + hex;
++ return hex;
++}
++
++function arrstr(a, n, w) {
++ var s = "";
++ if (typeof n == "undefined") n = a.length;
++ if (typeof w == "undefined") w = a.constructor.BYTES_PER_ELEMENT * 2;
++ for (var i = 0; i < n; i++) {
++ s += tohex(a[i], w);
++ }
++ return s;
++}
++function bufstr(b) {
++ if (b.buffer !== undefined) {
++ b = b.buffer;
++ }
++ return arrstr(new Uint8Array(b));
++}
++
++function assertFail(f) {
++ try {
++ f();
++ } catch (e) {
++ //print(e);
++ return;
++ }
++ throw "assertion failed: expected exception";
++}
++
++function assertTrue(f) {
++ if (f() !== true) throw "assertion failed: " + f;
++}
++
++function isUndefined(x) {
++ return typeof x === "undefined";
++}
++
++function fillArray(a, start) {
++ if (typeof start == "undefined") start = 1;
++ for (var i = 0; i < a.length; i++) {
++ a[i] = i + start;
++ }
++ return a;
++}
++
++//---------------------------------------------------------------------------
++// tests
++//---------------------------------------------------------------------------
++(function() {
++ var b = new ArrayBuffer(8);
++ var i8 = new Int8Array(b);
++ print(i8.buffer.byteLength, b.byteLength, i8.buffer === b, b.length);
++ print(b, i8.buffer, i8);
++})();
++
++(function test_attributes() {
++ var b = new ArrayBuffer(8);
++ for (var i in types) {
++ var x = new types[i](b);
++ print(x.byteOffset, x.byteLength, x.length, x.constructor.BYTES_PER_ELEMENT);
++ assertTrue(function(){ return x.constructor === types[i] });
++ }
++})();
++
++(function() {
++ var b = new ArrayBuffer(8);
++ var i8 = new Int8Array(b);
++ fillArray(i8, 0x70);
++
++ var i8_2 = new Int8Array(b, 2);
++ var i8_2_4 = new Uint8Array(b, 2, 4);
++
++ i8_2_4[3] = 0x80;
++
++ print(arrstr(i8, 8, 2) + " " + bufstr(i8));
++ print(arrstr(i8_2, 6) + " " + i8_2.byteOffset + " " + i8_2.byteLength);
++ print(arrstr(i8_2_4, 4) + " " + i8_2_4.byteOffset + " " + i8_2_4.byteLength);
++
++ var i8_1_5 = i8.subarray(1, 5);
++ i8_2_4.subarray(1, 5);
++ print(arrstr(i8_1_5, 4) + " " + i8_1_5.byteOffset + " " + i8_1_5.byteLength);
++
++ print(bufstr(b.slice(1,7)));
++})();
++
++(function() {
++ var b = new ArrayBuffer(8);
++ fillArray(new Int8Array(b), 0x70);
++ new Int8Array(b)[5] = 0x80;
++
++ var i32 = new Int32Array(b);
++ var u32 = new Uint32Array(b);
++ print(arrstr(i32), i32[0], i32[1]);
++ i32[1] = 0xfefdfcfb;
++ print(arrstr(i32), i32[0], i32[1]);
++ print(arrstr(u32), u32[0], u32[1]);
++
++ var pi = 3.1415926;
++ var f32 = new Float32Array(b);
++ var f64 = new Float64Array(b);
++ f32[0] = pi;
++ print(bufstr(b), f32.length);
++ f64[0] = pi;
++ print(bufstr(b), f64.length);
++ print(arrstr(u32), u32[0], u32[1]);
++
++ var d = new Int32Array(3);
++ d.set(i32,1);
++ print(bufstr(d));
++
++ var s = new Int16Array(b);
++ var t = new Uint16Array(b);
++ print(arrstr(s), arrstr(t));
++ s[0] = -1; s[1] = 0x80;
++ print(arrstr(s), arrstr(t));
++})();
++
++(function enumerate_properties() {
++ var i8 = new Int8Array(new ArrayBuffer(8));
++ var s = ""; for (var i in i8) { s += i + " "; } print(s.trim());
++})();
++
++// check that ScriptObject fallback is still working
++// DISABLED because correct behavior is unclear
++(function() {
++ // NB: firefox will never set any out-of-bounds or non-array values although it does get both from prototype.
++ var z = new Uint8Array(4);
++ z["asdf"] = "asdf"; print(z["asdf"]);
++ z[0x100000000] = "asdf"; print(z[0x100000000]);
++ z[-1] = "asdf"; print(z[-1]);
++
++ // v8 and nashorn disagree on out-of-bounds uint32 indices: v8 won't go to the prototype.
++ z[0xf0000000] = "asdf"; print(z[0xf0000000]);
++ z[0xffffffff] = "asdf"; print(z[0xffffffff]);
++ z[0x70000000] = "asdf"; print(z[0x70000000]);
++
++ // this will work in firefox and nashorn (not in v8).
++ Uint8Array.prototype[4] = "asdf"; print(z[4]);
++});
++
++(function test_exceptions() {
++ assertFail(function() { new Int32Array(new ArrayBuffer(7)); });
++ assertFail(function() { new Int32Array(new ArrayBuffer(8), 0, 4); });
++ assertFail(function() { new Int32Array(new ArrayBuffer(8),-1, 2); });
++ assertFail(function() { new Int32Array(new ArrayBuffer(8), 0,-1); });
++})();
++
++(function test_subarray() {
++ var x = fillArray(new Int8Array(8));
++ print(arrstr(x));
++ print("subarray(2,4)=" + arrstr(x.subarray(2, 4)), "subarray(-6,-4)=" + arrstr(x.subarray(-6, -4))); // negative index refers from the end of the array
++ print(arrstr(x.subarray(-10, -2))); // negative index clamped to 0
++ assertTrue(function(){ return arrstr(x.subarray(6, 4)) === ""; }); // negative length clamped to 0
++ print(arrstr(x.subarray(1,-1).subarray(1,-1)), arrstr(x.subarray(1,-1).subarray(1,-1).subarray(1,-1))); // subarray of subarray
++})();
++
++(function test_slice() {
++ var b = new ArrayBuffer(16);
++ fillArray(new Int8Array(b));
++ print(bufstr(b));
++ print("slice(4,8)=" + bufstr(b.slice(4, 8)), "slice(-8,-4)=" + bufstr(b.slice(-8, -4))); // negative index refers from the end of the array
++ print(bufstr(b.slice(-20, -4))); // negative index clamped to 0
++ assertTrue(function(){ return bufstr(b.slice(8, 4)) === ""; }); // negative length clamped to 0
++ print(arrstr(new Int16Array(b.slice(1,-1).slice(2,-1).slice(1,-2).slice(1,-1)))); // slice of slice
++})();
++
++(function test_clamped() {
++ var a = new Uint8ClampedArray(10);
++ a[0] = -17; // clamped to 0
++ a[1] = 4711; // clamped to 255
++ a[2] = 17.5; // clamped to 18
++ a[3] = 16.5; // clamped to 16
++ a[4] = 255.9; // clamped to 255
++ a[5] = Infinity; // clamped to 255
++ a[6] = -Infinity; // clamped to 0
++ a[7] = NaN; // 0
++ assertTrue(function(){ return a[0] === 0 && a[1] === 255 && a[2] === 18 && a[3] === 16 && a[4] === 255 && a[5] === 255 && a[6] === 0 && a[7] === 0; });
++})();
++
++(function test_out_of_bounds() {
++ var a = new Int32Array(10);
++ a[10] = 10;
++ a[100] = 100;
++ a[1000] = 1000;
++ assertTrue(function(){ return isUndefined(a[10]) && isUndefined(a[11]) && isUndefined(a[100]) && isUndefined(a[123]) && isUndefined(a[1000]); });
++})();
++
+--- ./nashorn/test/script/basic/NASHORN-377.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-377.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -26,201 +26,8 @@
+ *
+ * @test
+ * @run
++ * @littleendian
+ */
+
+-var types = [Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];
+-
+-//---------------------------------------------------------------------------
+-// utility functions
+-//---------------------------------------------------------------------------
+-function tohex(d, w) {
+- var hex = Number(d).toString(16);
+- var pad = (w ? w : 8) - hex.length;
+- hex = "00000000".substr(0, pad) + hex;
+- return hex;
+-}
+-
+-function arrstr(a, n, w) {
+- var s = "";
+- if (typeof n == "undefined") n = a.length;
+- if (typeof w == "undefined") w = a.constructor.BYTES_PER_ELEMENT * 2;
+- for (var i = 0; i < n; i++) {
+- s += tohex(a[i], w);
+- }
+- return s;
+-}
+-function bufstr(b) {
+- if (b.buffer !== undefined) {
+- b = b.buffer;
+- }
+- return arrstr(new Uint8Array(b));
+-}
+-
+-function assertFail(f) {
+- try {
+- f();
+- } catch (e) {
+- //print(e);
+- return;
+- }
+- throw "assertion failed: expected exception";
+-}
+-
+-function assertTrue(f) {
+- if (f() !== true) throw "assertion failed: " + f;
+-}
+-
+-function isUndefined(x) {
+- return typeof x === "undefined";
+-}
+-
+-function fillArray(a, start) {
+- if (typeof start == "undefined") start = 1;
+- for (var i = 0; i < a.length; i++) {
+- a[i] = i + start;
+- }
+- return a;
+-}
+-
+-//---------------------------------------------------------------------------
+-// tests
+-//---------------------------------------------------------------------------
+-(function() {
+- var b = new ArrayBuffer(8);
+- var i8 = new Int8Array(b);
+- print(i8.buffer.byteLength, b.byteLength, i8.buffer === b, b.length);
+- print(b, i8.buffer, i8);
+-})();
+-
+-(function test_attributes() {
+- var b = new ArrayBuffer(8);
+- for (var i in types) {
+- var x = new types[i](b);
+- print(x.byteOffset, x.byteLength, x.length, x.constructor.BYTES_PER_ELEMENT);
+- assertTrue(function(){ return x.constructor === types[i] });
+- }
+-})();
+-
+-(function() {
+- var b = new ArrayBuffer(8);
+- var i8 = new Int8Array(b);
+- fillArray(i8, 0x70);
+-
+- var i8_2 = new Int8Array(b, 2);
+- var i8_2_4 = new Uint8Array(b, 2, 4);
+-
+- i8_2_4[3] = 0x80;
+-
+- print(arrstr(i8, 8, 2) + " " + bufstr(i8));
+- print(arrstr(i8_2, 6) + " " + i8_2.byteOffset + " " + i8_2.byteLength);
+- print(arrstr(i8_2_4, 4) + " " + i8_2_4.byteOffset + " " + i8_2_4.byteLength);
+-
+- var i8_1_5 = i8.subarray(1, 5);
+- i8_2_4.subarray(1, 5);
+- print(arrstr(i8_1_5, 4) + " " + i8_1_5.byteOffset + " " + i8_1_5.byteLength);
+-
+- print(bufstr(b.slice(1,7)));
+-})();
+-
+-(function() {
+- var b = new ArrayBuffer(8);
+- fillArray(new Int8Array(b), 0x70);
+- new Int8Array(b)[5] = 0x80;
+-
+- var i32 = new Int32Array(b);
+- var u32 = new Uint32Array(b);
+- print(arrstr(i32), i32[0], i32[1]);
+- i32[1] = 0xfefdfcfb;
+- print(arrstr(i32), i32[0], i32[1]);
+- print(arrstr(u32), u32[0], u32[1]);
+-
+- var pi = 3.1415926;
+- var f32 = new Float32Array(b);
+- var f64 = new Float64Array(b);
+- f32[0] = pi;
+- print(bufstr(b), f32.length);
+- f64[0] = pi;
+- print(bufstr(b), f64.length);
+- print(arrstr(u32), u32[0], u32[1]);
+-
+- var d = new Int32Array(3);
+- d.set(i32,1);
+- print(bufstr(d));
+-
+- var s = new Int16Array(b);
+- var t = new Uint16Array(b);
+- print(arrstr(s), arrstr(t));
+- s[0] = -1; s[1] = 0x80;
+- print(arrstr(s), arrstr(t));
+-})();
+-
+-(function enumerate_properties() {
+- var i8 = new Int8Array(new ArrayBuffer(8));
+- var s = ""; for (var i in i8) { s += i + " "; } print(s.trim());
+-})();
+-
+-// check that ScriptObject fallback is still working
+-// DISABLED because correct behavior is unclear
+-(function() {
+- // NB: firefox will never set any out-of-bounds or non-array values although it does get both from prototype.
+- var z = new Uint8Array(4);
+- z["asdf"] = "asdf"; print(z["asdf"]);
+- z[0x100000000] = "asdf"; print(z[0x100000000]);
+- z[-1] = "asdf"; print(z[-1]);
+-
+- // v8 and nashorn disagree on out-of-bounds uint32 indices: v8 won't go to the prototype.
+- z[0xf0000000] = "asdf"; print(z[0xf0000000]);
+- z[0xffffffff] = "asdf"; print(z[0xffffffff]);
+- z[0x70000000] = "asdf"; print(z[0x70000000]);
+-
+- // this will work in firefox and nashorn (not in v8).
+- Uint8Array.prototype[4] = "asdf"; print(z[4]);
+-});
+-
+-(function test_exceptions() {
+- assertFail(function() { new Int32Array(new ArrayBuffer(7)); });
+- assertFail(function() { new Int32Array(new ArrayBuffer(8), 0, 4); });
+- assertFail(function() { new Int32Array(new ArrayBuffer(8),-1, 2); });
+- assertFail(function() { new Int32Array(new ArrayBuffer(8), 0,-1); });
+-})();
+-
+-(function test_subarray() {
+- var x = fillArray(new Int8Array(8));
+- print(arrstr(x));
+- print("subarray(2,4)=" + arrstr(x.subarray(2, 4)), "subarray(-6,-4)=" + arrstr(x.subarray(-6, -4))); // negative index refers from the end of the array
+- print(arrstr(x.subarray(-10, -2))); // negative index clamped to 0
+- assertTrue(function(){ return arrstr(x.subarray(6, 4)) === ""; }); // negative length clamped to 0
+- print(arrstr(x.subarray(1,-1).subarray(1,-1)), arrstr(x.subarray(1,-1).subarray(1,-1).subarray(1,-1))); // subarray of subarray
+-})();
+-
+-(function test_slice() {
+- var b = ArrayBuffer(16);
+- fillArray(new Int8Array(b));
+- print(bufstr(b));
+- print("slice(4,8)=" + bufstr(b.slice(4, 8)), "slice(-8,-4)=" + bufstr(b.slice(-8, -4))); // negative index refers from the end of the array
+- print(bufstr(b.slice(-20, -4))); // negative index clamped to 0
+- assertTrue(function(){ return bufstr(b.slice(8, 4)) === ""; }); // negative length clamped to 0
+- print(arrstr(new Int16Array(b.slice(1,-1).slice(2,-1).slice(1,-2).slice(1,-1)))); // slice of slice
+-})();
+-
+-(function test_clamped() {
+- var a = new Uint8ClampedArray(10);
+- a[0] = -17; // clamped to 0
+- a[1] = 4711; // clamped to 255
+- a[2] = 17.5; // clamped to 18
+- a[3] = 16.5; // clamped to 16
+- a[4] = 255.9; // clamped to 255
+- a[5] = Infinity; // clamped to 255
+- a[6] = -Infinity; // clamped to 0
+- a[7] = NaN; // 0
+- assertTrue(function(){ return a[0] === 0 && a[1] === 255 && a[2] === 18 && a[3] === 16 && a[4] === 255 && a[5] === 255 && a[6] === 0 && a[7] === 0; });
+-})();
+-
+-(function test_out_of_bounds() {
+- var a = new Int32Array(10);
+- a[10] = 10;
+- a[100] = 100;
+- a[1000] = 1000;
+- assertTrue(function(){ return isUndefined(a[10]) && isUndefined(a[11]) && isUndefined(a[100]) && isUndefined(a[123]) && isUndefined(a[1000]); });
+-})();
+-
++var dir = typeof(__DIR__) == 'undefined' ? "test/script/basic/" : __DIR__;
++load(dir + "NASHORN-377-payload.js");
+--- ./nashorn/test/script/basic/NASHORN-378.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-378.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,7 +29,7 @@
+ */
+
+ var obj = {};
+-Object.defineProperty(obj, "foo",
++Object.defineProperty(obj, "foo",
+ { get: function() { return 42; },
+ configurable: true});
+
+--- ./nashorn/test/script/basic/NASHORN-38.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-38.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -33,7 +33,7 @@
+ // defined later in lexical order (see below)
+ print(typeof f);
+ return f;
+-
++
+ function f(){
+ print("inside function 'f'");
+ }
+--- ./nashorn/test/script/basic/NASHORN-380.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-380.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-381.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-381.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-382.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-382.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-383.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-383.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-384.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-384.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-385.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-385.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -37,7 +37,7 @@
+
+ function checkSetter() {
+ o.bar = 44;
+-}
++}
+
+ function checkCall() {
+ try {
+@@ -51,8 +51,8 @@
+ checkSetter();
+ checkCall();
+
+-proto.__get__ = function(name) {
+- print("in __get__: " + name);
++proto.__get__ = function(name) {
++ print("in __get__: " + name);
+ return name;
+ };
+
+--- ./nashorn/test/script/basic/NASHORN-389.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-389.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-393.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-393.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-394.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-394.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-396.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-396.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -27,17 +27,17 @@
+ * @test
+ * @run
+ */
+-
+-Object.defineProperty(Number.prototype,
+- "foo",
++
++Object.defineProperty(Number.prototype,
++ "foo",
+ { get: function () { 'use strict'; return this; }
+-});
++});
+
+ if(!((5).foo === 5)) {
+ fail("#1 ToObject conversion on 'thisArg' for strict getter");
+ }
+
+-Number.prototype.func = function() {
++Number.prototype.func = function() {
+ 'use strict';
+ return this;
+ };
+--- ./nashorn/test/script/basic/NASHORN-397.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-397.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-398.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-398.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-40.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-40.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-400.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-400.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-401.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-401.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-402.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-402.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-404.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-404.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-405.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-405.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,13 +23,13 @@
+
+ /**
+ * NASHORN-405 make sure slice does not modify arrays
+- *
++ *
+ * @test
+ * @run
+ */
+
+ var x = ['foo', '%zx'];
+-var s = x.slice(1);
++var s = x.slice(1);
+ print(s);
+ print(x);
+
+--- ./nashorn/test/script/basic/NASHORN-406.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-406.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * NASHORN-406 : Property descriptor properties should be enumerable
++ * NASHORN-406 : Property descriptor properties should be enumerable
+ *
+ * @test
+ * @run
+@@ -36,7 +36,7 @@
+
+ function checkData() {
+ var desc = Object.getOwnPropertyDescriptor(obj, "foo");
+- var enumSeen = false, writeSeen = false,
++ var enumSeen = false, writeSeen = false,
+ configSeen = false, valueSeen = false;
+ for (i in desc) {
+ switch(i) {
+@@ -50,7 +50,7 @@
+ valueSeen = true; break;
+ }
+ }
+-
++
+ return enumSeen && writeSeen && configSeen && valueSeen;
+ }
+
+@@ -60,7 +60,7 @@
+
+ function checkAccessor() {
+ var desc = Object.getOwnPropertyDescriptor(obj, "bar");
+- var enumSeen = false, getterSeen = false,
++ var enumSeen = false, getterSeen = false,
+ configSeen = false, setterSeen = false;
+ for (i in desc) {
+ switch(i) {
+--- ./nashorn/test/script/basic/NASHORN-408.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-408.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-415.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-415.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-416.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-416.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -32,7 +32,7 @@
+
+ function getter() { return 32; }
+
+-Object.defineProperty(obj, "foo",
++Object.defineProperty(obj, "foo",
+ { get: getter, configurable: true });
+
+ function setter(x) { print(x); }
+--- ./nashorn/test/script/basic/NASHORN-417.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-417.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-418.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-418.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-420.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-420.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-421.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-421.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -52,9 +52,9 @@
+ }
+ }
+
+-var methods = [ "concat", "join", "pop", "push", "reverse",
++var methods = [ "concat", "join", "pop", "push", "reverse",
+ "shift", "unshift", "slice", "sort", "splice",
+- "indexOf", "lastIndexOf", "every", "some", "forEach",
++ "indexOf", "lastIndexOf", "every", "some", "forEach",
+ "map", "filter", "reduce", "reduceRight" ];
+
+ for (var m in methods) {
+--- ./nashorn/test/script/basic/NASHORN-423.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-423.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-423a.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-423a.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-424.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-424.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-425.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-425.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-426.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-426.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-427.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-427.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-428.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-428.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-429.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-429.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-432.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-432.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-433.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-433.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-434.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-434.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -34,7 +34,7 @@
+ if (this !== global) {
+ fail("#1 callback got 'this' different from global");
+ }
+-}
++}
+
+ function strictFunc(val, idx, obj) {
+ 'use strict';
+@@ -49,7 +49,7 @@
+ }
+
+ var arr = [1];
+-arr.forEach(func);
++arr.forEach(func);
+ arr.forEach(strictFunc);
+
+ var callbackThis = {};
+--- ./nashorn/test/script/basic/NASHORN-435.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-435.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-437.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-437.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-44.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-44.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,9 +29,9 @@
+ */
+ function loop1() {
+ print("loop1");
+- for (var i = 0; i < 5; i++) {
+- print(i);
+- continue;
++ for (var i = 0; i < 5; i++) {
++ print(i);
++ continue;
+ }
+ print(i);
+ print("done1");
+@@ -40,8 +40,8 @@
+ function loop2() {
+ print("loop2");
+ for (var i = 0; i < 5; i++) {
+- print(i);
+- break;
++ print(i);
++ break;
+ }
+ print(i);
+ print("done2");
+--- ./nashorn/test/script/basic/NASHORN-441.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-441.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-442.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-442.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-443.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-443.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-444.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-444.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-445.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-445.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-446.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-446.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-447.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-447.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-448.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-448.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-449.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-449.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * NASHORN-449 : defineProperty on arguments object does not work element in question was deleted earlier
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/NASHORN-45.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-45.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-450.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-450.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-452.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-452.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-459.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-459.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-46.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-46.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-462.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-462.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -31,8 +31,8 @@
+ function Foo() {};
+ Object.defineProperty(Foo.prototype, "bar", { value: 19 });
+
+-var fooObj = new Foo();
+-fooObj.bar = "overridden";
++var fooObj = new Foo();
++fooObj.bar = "overridden";
+ if (fooObj.hasOwnProperty("bar")) {
+ fail("inherited non-writable property can be overridden");
+ }
+--- ./nashorn/test/script/basic/NASHORN-463.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-463.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-468.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-468.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-47.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-47.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-473.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-473.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-474.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-474.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-478.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-478.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-48.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-48.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,9 +29,9 @@
+ */
+
+ function loop3() {
+- for (var i = 0; i < 5; i++) {
+- print(i);
+- throw "ERROR";
++ for (var i = 0; i < 5; i++) {
++ print(i);
++ throw "ERROR";
+ }
+ print("dead");
+ }
+@@ -41,17 +41,17 @@
+ } catch (e) {
+ print(e);
+ }
+-
++
+ function loop4() {
+ var i = 0;
+ while (i++ < 5) {
+- print(i);
+- throw "ERROR";
++ print(i);
++ throw "ERROR";
+ }
+ print("dead");
+ }
+
+-try {
++try {
+ loop4();
+ } catch (e) {
+ print(e);
+@@ -60,13 +60,13 @@
+ function loop5() {
+ var i = 0;
+ do {
+- print(i);
+- throw "ERROR";
++ print(i);
++ throw "ERROR";
+ } while (i++ < 5);
+ print("dead");
+ }
+
+-try {
++try {
+ loop5();
+ } catch (e) {
+ print(e);
+--- ./nashorn/test/script/basic/NASHORN-481.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-481.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -10029,7 +10029,7 @@
+ "tag": "mesoventral",
+ "popularity": 4096
+ }];
+-
++
+ var entry = largeTable[1000];
+ print(entry.tag, entry.popularity);
+
+--- ./nashorn/test/script/basic/NASHORN-482.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-482.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-484.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-484.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-486.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-486.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -32,7 +32,7 @@
+
+ try {
+ // save line number and force ReferenceError for 'foo'
+- var lineNumber = __LINE__; print(foo);
++ var lineNumber = __LINE__; print(foo);
+ fail("#1 should have thrown ReferenceError");
+ } catch (e) {
+ if (! (e instanceof ReferenceError)) {
+--- ./nashorn/test/script/basic/NASHORN-487.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-487.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-488.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-488.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -34,7 +34,7 @@
+ }
+
+ Object.defineProperty(Function.prototype, "prototype", {
+- set: undefined, get: function() { return 32; },
++ set: undefined, get: function() { return 32; },
+ configurable: true
+ });
+
+--- ./nashorn/test/script/basic/NASHORN-49.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-49.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-490.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-490.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-494.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-494.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-497.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-497.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-498.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-498.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,13 +30,13 @@
+
+ // no syntax error expected for the following functions
+ function func() {
+- // Parser thinks it is a for-in statement! But 'in' used in
++ // Parser thinks it is a for-in statement! But 'in' used in
+ // cond. expression. This is a normal for statement
+ for (var x = a ? b in c : 3;;) {}
+ }
+
+ function func2() {
+- // for-in statement but init is cond. expression with 'in'
++ // for-in statement but init is cond. expression with 'in'
+ // This is same as "for (var x = (a? b in c : e) in {} )"
+ for (var x = a ? b in c : e in {}) {}
+ }
+--- ./nashorn/test/script/basic/NASHORN-499.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-499.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-50.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-50.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,7 +30,7 @@
+
+ try {
+ for (var y in null) {
+- y = 2;
++ y = 2;
+ }
+ } catch (e) {
+ print(e);
+@@ -38,7 +38,7 @@
+
+ try {
+ for (var y in undefined) {
+- y = 2;
++ y = 2;
+ }
+ } catch (e) {
+ print(e);
+--- ./nashorn/test/script/basic/NASHORN-500.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-500.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,7 +29,7 @@
+ */
+
+ var origToString = Object.prototype.toString;
+-Object.prototype.toString = function () {
++Object.prototype.toString = function () {
+ return this.myStr();
+ }
+
+--- ./nashorn/test/script/basic/NASHORN-503.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-503.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-51.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-51.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-511.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-511.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-515.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-515.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,17 +30,17 @@
+
+ function a() {
+ var x = (3.14-2.14);
+-
++
+ switch (x) {
+ case 1:
+- print("--1");
+- break;
++ print("--1");
++ break;
+ case 2:
+- print("--2");
+- break;
++ print("--2");
++ break;
+ default:
+- print("default");
+- break;
++ print("default");
++ break;
+ }
+ }
+
+@@ -50,11 +50,11 @@
+ switch (index) {
+ case 0x00:
+ case 0x01:
+- print("one zero");
+- break;
++ print("one zero");
++ break;
+ default:
+- print("default");
+- break;
++ print("default");
++ break;
+ }
+ }
+
+@@ -64,76 +64,76 @@
+ switch (index) {
+ case 0x00:
+ case 0x01:
+- print("one zero");
+- break;
++ print("one zero");
++ break;
+ default:
+- print("default");
++ print("default");
+ }
+ --index;
+ }
+
+ function d() {
+ var x = (3.14-1.14);
+-
++
+ switch(x) {
+ case 1:
+- print("--1"); break;
++ print("--1"); break;
+ case 2:
+- print("--2"); break;
++ print("--2"); break;
+ case 3:
+- print("--3"); break;
++ print("--3"); break;
+ case 4:
+- print("--4"); break;
++ print("--4"); break;
+ default:
+- print("default");
++ print("default");
+ }
+ }
+
+ function e() {
+ var y = 2147483647;
+-
++
+ switch(y) {
+ case -2147483648:
+- print("MIN_INT"); break;
++ print("MIN_INT"); break;
+ case -2147483647:
+- print("MIN_INT+1"); break;
++ print("MIN_INT+1"); break;
+ case 2147483647:
+- print("MAX_INT"); break;
++ print("MAX_INT"); break;
+ case 1:
+- print("--1"); break;
++ print("--1"); break;
+ case 2:
+- print("--2"); break;
++ print("--2"); break;
+ case 3:
+- print("--3"); break;
++ print("--3"); break;
+ case 4:
+- print("--4"); break;
++ print("--4"); break;
+ default:
+- print("default");
++ print("default");
+ }
+ }
+
+ function f() {
+ var z = 2;
+-
++
+ switch(z) {
+ case -2147483648:
+- print("MIN_INT"); break;
++ print("MIN_INT"); break;
+ case -2147483647:
+- print("MIN_INT+1"); break;
++ print("MIN_INT+1"); break;
+ case 2147483647:
+- print("MAX_INT"); break;
++ print("MAX_INT"); break;
+ case 1:
+- print("--1"); break;
++ print("--1"); break;
+ case 2:
+- print("--2 first"); break;
++ print("--2 first"); break;
+ case 2:
+- print("--2 second"); break;
++ print("--2 second"); break;
+ case 3:
+- print("--3"); break;
++ print("--3"); break;
+ case 4:
+- print("--4"); break;
++ print("--4"); break;
+ default:
+- print("default");
++ print("default");
+ }
+ }
+
+--- ./nashorn/test/script/basic/NASHORN-516.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-516.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-52.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-52.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-534.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-534.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-535.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-535.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-544.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-544.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-55.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-55.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-554.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-554.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-556.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-556.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-56.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-56.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-562.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-562.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-565.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-565.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-575.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-575.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-58.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-58.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,14 +30,14 @@
+
+ function test1() {
+ var x = 1;
+- try {
+- print('try');
+- x = 2;
++ try {
++ print('try');
++ x = 2;
+ } catch(e) {
+- print('catch');
+- } finally {
+- print('finally');
+- x = 3;
++ print('catch');
++ } finally {
++ print('finally');
++ x = 3;
+ }
+ print(x);
+ }
+@@ -45,81 +45,81 @@
+ function test2() {
+ var x = 1;
+ try {
+- print('try');
++ print('try');
+ } finally {
+- print('finally');
+- x = 2;
++ print('finally');
++ x = 2;
+ }
+ print(x);
+ }
+
+ function test3() {
+ try {
+- return 2;
++ return 2;
+ } finally {
+- return 3;
++ return 3;
+ }
+ }
+
+ function test4() {
+ try {
+- x = 1;
+- print(x);
+- try {
+- x = 2;
+- print(x);
+- } finally {
+- x = 3;
+- print(x)
+- try {
+- x = 4;
+- print(x);
+- } finally {
+- x = 5;
+- print(x);
+- }
+- }
+- print(x)
++ x = 1;
++ print(x);
++ try {
++ x = 2;
++ print(x);
+ } finally {
+- x = 6;
+- print(x);
++ x = 3;
++ print(x)
++ try {
++ x = 4;
++ print(x);
++ } finally {
++ x = 5;
++ print(x);
++ }
++ }
++ print(x)
++ } finally {
++ x = 6;
++ print(x);
+ }
+ print(x);
+ }
+
+ function test5() {
+ try {
+- x = 1;
+- print(x);
+- try {
+- x = 2;
+- print(x);
+- } finally {
+- x = 3;
+- print(x)
+- try {
+- x = 4;
+- print(x);
+- } finally {
+- x = 5;
+- return x;
+- }
+- }
+- print(x)
++ x = 1;
++ print(x);
++ try {
++ x = 2;
++ print(x);
+ } finally {
+- x = 6;
+- return x;
++ x = 3;
++ print(x)
++ try {
++ x = 4;
++ print(x);
++ } finally {
++ x = 5;
++ return x;
++ }
++ }
++ print(x)
++ } finally {
++ x = 6;
++ return x;
+ }
+ }
+
+ function test6() {
+ try {
+- throw new Error("testing");
++ throw new Error("testing");
+ } catch (ex) {
+- print(ex);
+- return;
++ print(ex);
++ return;
+ } finally {
+- print("finally");
++ print("finally");
+ }
+ }
+
+@@ -133,7 +133,7 @@
+ i++;
+ }
+ if (i != 4) {
+- print("FAIL");
++ print("FAIL");
+ }
+ print("SUCCESS");
+ }
+--- ./nashorn/test/script/basic/NASHORN-59.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-59.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-592-dual.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-592-dual.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-592.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-592.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-597.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-597.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-60.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-60.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-609.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-609.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-61.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-61.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-62.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-62.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-620.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-620.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-623.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-623.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-627.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-627.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-63.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-63.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -64,7 +64,7 @@
+ error('Different Objects are equal');
+ }
+
+-var obj1 = {};
++var obj1 = {};
+ var obj2 = obj1;
+ if (obj1 != obj2) {
+ error(' Same object literals are not equal');
+--- ./nashorn/test/script/basic/NASHORN-637.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-637.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-639.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-639.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-64.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-64.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-642.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-642.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-646.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-646.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-658.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-658.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-659.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-659.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-66.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-66.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-664.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-664.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -34,11 +34,11 @@
+ e.fileName = "foo";
+ if (e.fileName !== 'foo') {
+ fail("can not set e.fileName");
+- }
++ }
+ e.lineNumber = 100;
+ if (e.lineNumber !== 100) {
+ fail("can not set e.lineNumber");
+- }
++ }
+ e.columnNumber = 33;
+ if (e.columnNumber !== 33) {
+ fail("can not set e.columnNumber");
+--- ./nashorn/test/script/basic/NASHORN-665.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-665.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-67.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-67.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,15 +30,15 @@
+
+ function test_nested() {
+ try {
+- try {
+- throw new Error("bam!");
+- } catch (e) {
+- print("SUCCESS")
+- }
++ try {
++ throw new Error("bam!");
++ } catch (e) {
++ print("SUCCESS")
++ }
+ } catch (e2) {
+- fail("inner catch should have caught the exception");
+- }
+-
++ fail("inner catch should have caught the exception");
++ }
++
+ }
+
+ test_nested()
+--- ./nashorn/test/script/basic/NASHORN-678.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-678.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -41,7 +41,7 @@
+
+ try {
+ 33();
+- fail("should have thrown error");
++ fail("should have thrown error");
+ } catch (e) {
+ if (! (e instanceof TypeError)) {
+ fail("expected TypeError, got " + e);
+--- ./nashorn/test/script/basic/NASHORN-68.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-68.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-689.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-689.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-69.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-69.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-691.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-691.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-694.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-694.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-697.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-697.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-703.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-703.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -32,7 +32,7 @@
+ * This file is split into two tests as the presence of eval affects the whole script
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ function template() {
+--- ./nashorn/test/script/basic/NASHORN-703a.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-703a.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -32,7 +32,7 @@
+ * This file is split into two tests as the presence of eval affects the whole script
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ function template() {
+--- ./nashorn/test/script/basic/NASHORN-705.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-705.js Wed Feb 04 12:14:47 2015 -0800
+@@ -2,21 +2,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-71.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-71.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-710.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-710.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-711.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-711.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-72.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-72.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-722.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-722.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-73.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-73.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -50,8 +50,8 @@
+
+ while (true) {
+ break;
+- if (true) {
+- var s;
++ if (true) {
++ var s;
+ }
+ }
+
+@@ -61,20 +61,20 @@
+ for ( ; ; ) {
+ break;
+ while (true) {
+- do {
+- var u;
+- } while (true);
+- }
++ do {
++ var u;
++ } while (true);
++ }
+ }
+
+ function terminal() {
+ print("r = "+r);
+ print("t = "+t);
+ for (;;) {
+- var r;
+- return;
+- var t;
+- print("THIS SHOULD NEVER BE PRINTED!");
++ var r;
++ return;
++ var t;
++ print("THIS SHOULD NEVER BE PRINTED!");
+ }
+ print("NEITHER SHOULD THIS");
+ }
+@@ -84,13 +84,13 @@
+ function terminal2() {
+ print("q = "+q);
+ for (;;) {
+- return;
+- print("THIS SHOULD NEVER BE PRINTED!");
++ return;
++ print("THIS SHOULD NEVER BE PRINTED!");
+ }
+ print("NEITHER SHOULD THIS");
+ }
+
+-try {
++try {
+ terminal2();
+ } catch (e) {
+ print(e);
+@@ -108,13 +108,13 @@
+ } catch (e) {
+ print(e);
+ }
+-
++
+
+ function disp_a() {
+ var a = 20;
+ print("Value of 'a' inside the function " + a);
+ }
+-
++
+ var a = 10;
+
+ disp_a();
+--- ./nashorn/test/script/basic/NASHORN-737.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-737.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-737.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-737.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -3,10 +3,7 @@
+ "body": [
+ {
+ "type": "LabeledStatement",
+- "label": {
+- "type": "Identifier",
+- "name": "label"
+- },
++ "label": "label",
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+@@ -21,10 +18,7 @@
+ "body": [
+ {
+ "type": "BreakStatement",
+- "label": {
+- "type": "Identifier",
+- "name": "label"
+- }
++ "label": "label"
+ }
+ ]
+ }
+--- ./nashorn/test/script/basic/NASHORN-74.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-74.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-740.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-740.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-75.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-75.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-758.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-758.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-759.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-759.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-760.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-760.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,8 +29,8 @@
+ */
+ // problem 1
+ // the conversions in TernaryNode are not necessary, but they should not cause problems. They did
+-// this was because the result of Global.allocate(Object[])Object which returns a NativeObject.
+-// was tracked as an object type on our stack. The type system did not recognize this as an array.
++// this was because the result of Global.allocate(Object[])Object which returns a NativeObject.
++// was tracked as an object type on our stack. The type system did not recognize this as an array.
+ // Then the explicit conversions became "convert NativeArray->Object[]" which is a checkccast Object[]
+ // which naturally failed.
+
+--- ./nashorn/test/script/basic/NASHORN-768.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-768.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -46,7 +46,7 @@
+ // global object
+ var obj = {
+ foo: 42,
+- bar: function(x) {
++ bar: function(x) {
+ if (id != "engine-global-id") {
+ throw "id != 'engine-global-id'";
+ }
+--- ./nashorn/test/script/basic/NASHORN-778.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-778.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-78.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-78.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-79.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-79.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -32,8 +32,8 @@
+ print((function f(a) {
+ return a == 0? 1 : a*f(a-1);
+ })(4));
+-
+-
++
++
+ print((function g(a) {
+ function g(a) { return 1000; }
+ return a == 0? 1 : a*g(a-1);
+--- ./nashorn/test/script/basic/NASHORN-792.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-792.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-80.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-80.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-81.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-81.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-833.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-833.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-837.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-837.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-85.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-85.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-86.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-86.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-87.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-87.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-89.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-89.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-90.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-90.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-91.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-91.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-92.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-92.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-93.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-93.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-95.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-95.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-96.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-96.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-97.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-97.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/NASHORN-98.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-98.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -35,7 +35,7 @@
+ fail("syntax error expected here got " + e);
+ }
+ printError(e);
+-}
++}
+
+ try {
+ eval("var x = { foo: 33 bar: 'hello' }");
+@@ -44,4 +44,4 @@
+ fail("syntax error expected here got " + e);
+ }
+ printError(e);
+-}
++}
+--- ./nashorn/test/script/basic/NASHORN-99.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/NASHORN-99.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/access-specializer.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/access-specializer.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -24,9 +24,9 @@
+ /**
+ * This is a simple test that checks that access specialization in FinalizeTypes is consistent.
+ * Here, a2 = 0 will be turned int {I}a2 = 0, and all would be fine and well, only we can't change
+- * the symbol type for a2 from double, and we can't as it's not a temporary. Either we have to put
++ * the symbol type for a2 from double, and we can't as it's not a temporary. Either we have to put
+ * a temporary in at the late finalize stage and add another assignment, or we genericize the check
+- * in CodeGenerator#Store so we detect whether a target is of the wrong type before storing. It
++ * in CodeGenerator#Store so we detect whether a target is of the wrong type before storing. It
+ * is hopefully very rare, and will only be a problem when assignment results that have been
+ * specialized live on the stack
+ *
+--- ./nashorn/test/script/basic/addition.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/addition.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/allgettersetters.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/allgettersetters.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/andor.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/andor.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * and or test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ print("a" && "b");
+--- ./nashorn/test/script/basic/anonrecur.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/anonrecur.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/apply_to_call/apply_to_call1.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,66 @@
++/*
++* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * apply_to_call1.js - do one apply to call specialization, then override, apply and make sure it reverts (i.e. stops
++ * calling call)
++ *
++ * @test
++ * @run
++ */
++
++print("start");
++
++var x = {
++ a : 0,
++ b : 0,
++ c : 0,
++ initialize : function(x,y,z) {
++ this.a = x;
++ this.b = y;
++ this.c = z;
++ }
++};
++
++function test() {
++ x.initialize.apply(x, arguments);
++}
++
++test(4711,23,17);
++print(x.a);
++print(x.b);
++print(x.c);
++
++print("Overwriting apply now");
++
++x.initialize = {
++ apply : function() {
++ for (var i=0;i<arguments.length;i++) {
++ print("I am not who you think " + arguments[i]);
++ }
++ x.a = arguments[1][0];
++ }
++};
++
++test(4712);
++print(x.a);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/apply_to_call/apply_to_call1.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,8 @@
++start
++4711
++23
++17
++Overwriting apply now
++I am not who you think [object Object]
++I am not who you think [object Arguments]
++4712
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/apply_to_call/apply_to_call2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,63 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * apply_to_call2.js - do one apply to call specialization, then override call and make sure it reverts (i.e. stops
++ * calling call)
++ *
++ * @test
++ * @run
++ */
++
++print("start");
++
++var x = {
++ a : 0,
++ b : 0,
++ c : 0,
++ initialize : function(x,y,z) {
++ this.a = x;
++ this.b = y;
++ this.c = z;
++ }
++};
++
++function test() {
++ x.initialize.apply(x, arguments);
++}
++
++test(4711,23,17);
++print(x.a);
++print(x.b);
++print(x.c);
++
++print("Overwriting call now");
++
++Function.prototype.call = function() {
++ throw "this should never be thrown - test should revert to builtin apply";
++};
++
++test(1,2,3);
++print(x.a);
++print(x.b);
++print(x.c);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/apply_to_call/apply_to_call2.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,8 @@
++start
++4711
++23
++17
++Overwriting call now
++1
++2
++3
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/apply_to_call/apply_to_call3.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,67 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * apply_to_call3.js - do one apply to call specialization, then override, apply and make sure it reverts (i.e. stops
++ * calling call). Then apply should break and throw exception
++ *
++ * @test
++ * @run
++ */
++
++print("start");
++
++var x = {
++ a : 0,
++ b : 0,
++ c : 0,
++ initialize : function(x,y,z) {
++ this.a = x;
++ this.b = y;
++ this.c = z;
++ }
++};
++
++function test() {
++ x.initialize.apply(x, arguments);
++}
++
++test(4711,23,17);
++print(x.a);
++print(x.b);
++print(x.c);
++
++print("Overwriting apply now");
++
++Function.prototype.apply = function() {
++ throw "This should be thrown, as the test call transform is no longer valid";
++};
++
++try {
++ test(1,2,3);
++} catch (e) {
++ print(e);
++}
++print(x.a);
++print(x.b);
++print(x.c);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/apply_to_call/apply_to_call3.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,9 @@
++start
++4711
++23
++17
++Overwriting apply now
++This should be thrown, as the test call transform is no longer valid
++4711
++23
++17
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/apply_to_call/apply_to_call4.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,131 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * apply_to_call4.js - various escaping args patterns that prevent the optimization from being applied
++ * calling call)
++ *
++ * @test
++ * @run
++ */
++
++print("start");
++
++var x = {
++ a : 0,
++ b : 0,
++ c : 0,
++ initialize : function(x,y,z) {
++ this.a = x;
++ this.b = y;
++ this.c = z;
++ }
++};
++
++function f(x) {
++ print("this is a black hole - arguments escape");
++}
++
++function test() {
++ f(arguments);
++ x.initialize.apply(x, arguments);
++}
++
++test(4711,23,17);
++print(x.a);
++print(x.b);
++print(x.c);
++
++function test2() {
++ arguments[0] = 17;
++ x.initialize.apply(x, arguments);
++}
++
++test2(1,2,3);
++print(x.a);
++print(x.b);
++print(x.c);
++
++function test3() {
++ var escape = arguments[0];
++ f(escape);
++ x.initialize.apply(x, arguments);
++}
++
++test3("alpha", "beta", "gamma");
++print(x.a);
++print(x.b);
++print(x.c);
++
++function test4() {
++ var escape = arguments.length;
++ f(escape);
++ x.initialize.apply(x, arguments);
++}
++
++test4(1.2, 2.3, 3.4);
++print(x.a);
++print(x.b);
++print(x.c);
++
++function test5() {
++ x.initialize.apply(x, arguments, 17);
++}
++
++print("test 5 done");
++test5(11, 22);
++print("a="+typeof(x.a));
++print(x.b);
++print(x.c);
++
++print("Now it's time for transforms");
++
++function test6() {
++ x.initialize.apply(x, arguments);
++}
++
++test6(19, 20, 21);
++print(x.a);
++print(x.b);
++print(x.c);
++
++function test7() {
++ x.initialize.apply(x, arguments);
++}
++
++test7(1, 2.2, 17, 18);
++print(x.a);
++print(x.b);
++print(x.c);
++
++print("Should have transformed");
++
++function test8() {
++ var apply = f;
++ x.initialize.apply(x, arguments);
++}
++
++test8(7,8,9);
++print(x.a);
++print(x.b);
++print(x.c);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/apply_to_call/apply_to_call4.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,31 @@
++start
++this is a black hole - arguments escape
++4711
++23
++17
++17
++2
++3
++this is a black hole - arguments escape
++alpha
++beta
++gamma
++this is a black hole - arguments escape
++1.2
++2.3
++3.4
++test 5 done
++a=number
++22
++undefined
++Now it's time for transforms
++19
++20
++21
++1
++2.2
++17
++Should have transformed
++7
++8
++9
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/apply_to_call/apply_to_call5.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,111 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * apply_to_call5.js - do one apply to call specialization, then override, apply and make sure it reverts (i.e. stops
++ * calling call)
++ *
++ * @test
++ * @run
++ */
++
++print("start");
++
++var x = {
++ a : 0,
++ b : 0,
++ c : 0,
++ initialize : function(x,y,z) {
++ this.a = x;
++ this.b = y;
++ this.c = z;
++ }
++};
++
++function test() {
++ x.initialize.apply(x, arguments);
++}
++
++test(4711,23,17);
++print(x.a);
++print(x.b);
++print(x.c);
++
++print("Overwriting apply now");
++x.initialize.apply = function() { print("New function for apply - not a property"); }
++
++test(4712);
++print(x.a);
++
++
++var x2 = {
++ a : 0,
++ b : 0,
++ c : 0,
++ initialize : function(x,y,z) {
++ this.a = x;
++ this.b = y;
++ this.c = z;
++ }
++};
++
++function test2() {
++ x2.initialize.apply(x2, arguments);
++}
++
++test2(4711,23,17);
++print(x2.a);
++print(x2.b);
++print(x2.c);
++
++print("Overwriting apply now");
++x2.initialize['apply'] = function() { print("New function for apply - not a property"); }
++
++test(4712);
++print(x2.a);
++
++var x3 = {
++ a : 0,
++ b : 0,
++ c : 0,
++ initialize : function(x,y,z) {
++ this.a = x;
++ this.b = y;
++ this.c = z;
++ }
++};
++
++function test3() {
++ x3.initialize.apply(x3, arguments);
++}
++
++test3(4711,23,17);
++print(x3.a);
++print(x3.b);
++print(x3.c);
++
++print("Overwriting apply now");
++eval("x3.initialize['apply'] = function() { print('New function for apply - not a property'); }");
++
++test(4712);
++print(x3.a);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/apply_to_call/apply_to_call5.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,19 @@
++start
++4711
++23
++17
++Overwriting apply now
++New function for apply - not a property
++4711
++4711
++23
++17
++Overwriting apply now
++New function for apply - not a property
++4711
++4711
++23
++17
++Overwriting apply now
++New function for apply - not a property
++4711
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/apply_to_call/apply_to_call_recompile.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,44 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * apply_to_recompile.js - make sure that recompilations of methods are
++ * transform equivalent when it comes to apply2call, or we will have
++ * erroneous contiunation info generation
++ *
++ * @test
++ * @run
++ */
++
++function K() {
++ K.b2BoundValues.apply(this, arguments);
++ this.constructor === K && K.b2BoundValues.apply(this, arguments)
++}
++
++K.b2BoundValues = function(a,b,c) {
++ print(a);
++ print(b);
++ print(c);
++};
++
++new K(11,12,13,14,15,16);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/apply_to_call/apply_to_call_recompile.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,6 @@
++11
++12
++13
++11
++12
++13
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/apply_to_call/apply_to_call_varargs.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,75 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * apply_to_call_varars - make sure that apply to call transform works
++ * even when supplying too few arguments
++ *
++ * @test
++ * @run
++ */
++
++var Class = {
++ create: function() {
++ return function() { //vararg
++ this.initialize.apply(this, arguments);
++ }
++ }
++};
++
++Color = Class.create();
++Color.prototype = {
++ red: 0, green: 0, blue: 0,
++ initialize: function(r) {
++ this.red = r;
++ this.green = 255;
++ this.blue = 255;
++ },
++ toString: function() {
++ print("[red=" + this.red + ", green=" + this.green + ", blue=" + this.blue + "]");
++ }
++};
++
++var colors = new Array(16);
++function run() {
++ for (var i = 0; i < colors.length; i++) {
++ colors[i&0xf] = (new Color(i));
++ }
++}
++
++run();
++for (var i = 0; i < colors.length; i++) {
++ print(colors[i]);
++}
++
++print("Swapping out call");
++Function.prototype.call = function() {
++ throw "This should not happen, apply should be called instead";
++};
++
++run();
++for (var i = 0; i < colors.length; i++) {
++ print(colors[i]);
++}
++
++print("All done!");
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/apply_to_call/apply_to_call_varargs.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,66 @@
++[red=0, green=255, blue=255]
++undefined
++[red=1, green=255, blue=255]
++undefined
++[red=2, green=255, blue=255]
++undefined
++[red=3, green=255, blue=255]
++undefined
++[red=4, green=255, blue=255]
++undefined
++[red=5, green=255, blue=255]
++undefined
++[red=6, green=255, blue=255]
++undefined
++[red=7, green=255, blue=255]
++undefined
++[red=8, green=255, blue=255]
++undefined
++[red=9, green=255, blue=255]
++undefined
++[red=10, green=255, blue=255]
++undefined
++[red=11, green=255, blue=255]
++undefined
++[red=12, green=255, blue=255]
++undefined
++[red=13, green=255, blue=255]
++undefined
++[red=14, green=255, blue=255]
++undefined
++[red=15, green=255, blue=255]
++undefined
++Swapping out call
++[red=0, green=255, blue=255]
++undefined
++[red=1, green=255, blue=255]
++undefined
++[red=2, green=255, blue=255]
++undefined
++[red=3, green=255, blue=255]
++undefined
++[red=4, green=255, blue=255]
++undefined
++[red=5, green=255, blue=255]
++undefined
++[red=6, green=255, blue=255]
++undefined
++[red=7, green=255, blue=255]
++undefined
++[red=8, green=255, blue=255]
++undefined
++[red=9, green=255, blue=255]
++undefined
++[red=10, green=255, blue=255]
++undefined
++[red=11, green=255, blue=255]
++undefined
++[red=12, green=255, blue=255]
++undefined
++[red=13, green=255, blue=255]
++undefined
++[red=14, green=255, blue=255]
++undefined
++[red=15, green=255, blue=255]
++undefined
++All done!
+--- ./nashorn/test/script/basic/applycall.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/applycall.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/args.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/args.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/arity.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/arity.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * arity test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ function func1(a) { print(a); }
+--- ./nashorn/test/script/basic/arrayprotoclass.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/arrayprotoclass.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/arrays.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/arrays.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -155,6 +155,6 @@
+ print(Array.prototype.reduce.call("hello", function() {}));
+ print(Array.prototype.toString.call(new java.lang.Object()));
+ print(Array.prototype.toLocaleString.call(new java.lang.Object()));
+-print(Array.prototype.reduceRight.call(new java.lang.Object(),
++print(Array.prototype.reduceRight.call(new java.lang.Object(),
+ function() {}, 33));
+
+--- ./nashorn/test/script/basic/arrays2.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/arrays2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/arraysIntKey.js Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,35 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-/**
+- * Checks that we override array entries with defineProperty.
+- *
+- * @test
+- * @run
+- */
+-
+-var o = [0];
+-Object.defineProperty(o, "0", { get: function() { return "zero"; }, set: function(v) { print(v); }, configurable: true });
+-
+-print(o[0]);
+-o[0] = "one";
+--- ./nashorn/test/script/basic/arraysIntKey.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,2 +0,0 @@
+-zero
+-one
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/arrays_int_key.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Checks that we override array entries with defineProperty.
++ *
++ * @test
++ * @run
++ */
++
++var o = [0];
++Object.defineProperty(o, "0", { get: function() { return "zero"; }, set: function(v) { print(v); }, configurable: true });
++
++print(o[0]);
++o[0] = "one";
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/arrays_int_key.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,2 @@
++zero
++one
+--- ./nashorn/test/script/basic/arrayset.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/arrayset.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,7 +28,7 @@
+ * @run
+ */
+
+-var arr = [];
++var arr = [];
+ print(arr.length);
+ print(arr.hasOwnProperty(10000));
+ print(arr.hasOwnProperty(10));
+--- ./nashorn/test/script/basic/arrayundefined.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/arrayundefined.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/assign.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/assign.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * Assign test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ var x = 10;
+--- ./nashorn/test/script/basic/bitwise_and.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/bitwise_and.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/boolean_arithmetic.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,113 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * test arithmetic operations on boolean variables
++ *
++ * @test
++ * @run
++ */
++
++function printOp(text, value) {
++ print(text + value);
++}
++
++(function () {
++var t = true;
++var f = false;
++
++print("+")
++printOp("f, f: ", (f + f))
++printOp("f, t: ", (f + t))
++printOp("t, f: ", (t + f))
++printOp("t, t: ", (t + t))
++
++print("-")
++printOp("f, f: ", (f - f))
++printOp("f, t: ", (f - t))
++printOp("t, f: ", (t - f))
++printOp("t, t: ", (t - t))
++
++print("*")
++printOp("f, f: ", (f * f))
++printOp("f, t: ", (f * t))
++printOp("t, f: ", (t * f))
++printOp("t, t: ", (t * t))
++
++print("/")
++printOp("f, f: ", (f / f))
++printOp("f, t: ", (f / t))
++printOp("t, f: ", (t / f))
++printOp("t, t: ", (t / t))
++
++print("<<")
++printOp("f, f: ", (f << f))
++printOp("f, t: ", (f << t))
++printOp("t, f: ", (t << f))
++printOp("t, t: ", (t << t))
++
++print(">>")
++printOp("f, f: ", (f >> f))
++printOp("f, t: ", (f >> t))
++printOp("t, f: ", (t >> f))
++printOp("t, t: ", (t >> t))
++
++print(">>>")
++printOp("f, f: ", (f >>> f))
++printOp("f, t: ", (f >>> t))
++printOp("t, f: ", (t >>> f))
++printOp("t, t: ", (t >>> t))
++
++print("|")
++printOp("f, f: ", (f | f))
++printOp("f, t: ", (f | t))
++printOp("t, f: ", (t | f))
++printOp("t, t: ", (t | t))
++
++print("&")
++printOp("f, f: ", (f & f))
++printOp("f, t: ", (f & t))
++printOp("t, f: ", (t & f))
++printOp("t, t: ", (t & t))
++
++print("^")
++printOp("f, f: ", (f ^ f))
++printOp("f, t: ", (f ^ t))
++printOp("t, f: ", (t ^ f))
++printOp("t, t: ", (t ^ t))
++
++print("~")
++printOp("f: ", (~f))
++printOp("t: ", (~t))
++
++print("+")
++printOp("f: ", (+f))
++printOp("t: ", (+t))
++
++print("-")
++printOp("f: ", (-f))
++printOp("t: ", (-t))
++
++printOp("1/-f: ", (1/-f))
++
++})();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/boolean_arithmetic.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,60 @@
+++
++f, f: 0
++f, t: 1
++t, f: 1
++t, t: 2
++-
++f, f: 0
++f, t: -1
++t, f: 1
++t, t: 0
++*
++f, f: 0
++f, t: 0
++t, f: 0
++t, t: 1
++/
++f, f: NaN
++f, t: 0
++t, f: Infinity
++t, t: 1
++<<
++f, f: 0
++f, t: 0
++t, f: 1
++t, t: 2
++>>
++f, f: 0
++f, t: 0
++t, f: 1
++t, t: 0
++>>>
++f, f: 0
++f, t: 0
++t, f: 1
++t, t: 0
++|
++f, f: 0
++f, t: 1
++t, f: 1
++t, t: 1
++&
++f, f: 0
++f, t: 0
++t, f: 0
++t, t: 1
++^
++f, f: 0
++f, t: 1
++t, f: 1
++t, t: 0
++~
++f: -1
++t: -2
+++
++f: 0
++t: 1
++-
++f: 0
++t: -1
++1/-f: -Infinity
+--- ./nashorn/test/script/basic/booleangetter.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/booleangetter.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/builtin.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/builtin.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/builtin_assign.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/builtin_assign.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/builtinchain.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/builtinchain.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/calllink.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/calllink.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -60,7 +60,7 @@
+ var obj5 = new MyConstructor();
+ var obj6 = new MyConstructor();
+
+-var arr = [ obj1, obj2, obj3, obj4, obj5, obj6,
++var arr = [ obj1, obj2, obj3, obj4, obj5, obj6,
+ obj1, obj2, obj3, obj4, obj5, obj6 ];
+
+ var myObj;
+@@ -69,8 +69,8 @@
+ obj3.func = function() {
+ print("new obj3.func called");
+ }
+- obj4.func = function() {
+- print("new obj4.func called");
++ obj4.func = function() {
++ print("new obj4.func called");
+ }
+ MyConstructor.prototype.func = function() {
+ print("all new MyConstructor.prototype.func");
+--- ./nashorn/test/script/basic/classloader.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/classloader.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/closure.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/closure.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,14 +25,14 @@
+ * Closure test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+-
++
+ (function test1(a, b){ print(a, b); })(10, 20);
+ (function test2(a, b){ print(a, b); })(10);
+ (function test3(a, b){ print(a, b); })(10, 20, 30);
+-(function test4(a, b){
+- print(arguments[0] + "," + arguments[1]);
++(function test4(a, b){
++ print(arguments[0] + "," + arguments[1]);
+ print(arguments.callee);
+ })(10, 20);
+
+--- ./nashorn/test/script/basic/closure.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/closure.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -2,7 +2,7 @@
+ 10 undefined
+ 10 20
+ 10,20
+-function test4(a, b){
+- print(arguments[0] + "," + arguments[1]);
++function test4(a, b){
++ print(arguments[0] + "," + arguments[1]);
+ print(arguments.callee);
+ }
+--- ./nashorn/test/script/basic/commandargs.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/commandargs.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * Simple test to check command line arguments for scripts.
+ *
+ * @test
+- * @argument hello
++ * @argument hello
+ * @argument world
+ * @run
+ */
+@@ -33,4 +33,4 @@
+ for (i in arguments) {
+ print(arguments[i]);
+ }
+-
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/compile-octane-normal.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Make sure that we run with the class cache off to so that every
++ * run produces compile time and with optimistic type info caching
++ * and persistent code store off, for the same reasons. These last two
++ * are currently default, but this is not guaranteed to be the case
++ * forever, so make this test future safe, we specify them explicitly
++ *
++ * @test
++ * @fork
++ * @runif external.octane
++ * @option -scripting
++ * @option -Dnashorn.typeInfo.disabled=true
++ * @option --class-cache-size=0
++ * @option --persistent-code-cache=false
++ */
++
++var fn = __DIR__ + 'compile-octane.js';
++var url = new java.io.File(fn).toURL();
++loadWithNewGlobal(url);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/compile-octane-normal.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,30 @@
++Compiling 'box2d'...
++Done.
++Compiling 'code-load'...
++Done.
++Compiling 'crypto'...
++Done.
++Compiling 'deltablue'...
++Done.
++Compiling 'earley-boyer'...
++Done.
++Compiling 'gbemu'... (2 files)
++Done.
++Compiling 'mandreel'...
++Done.
++Compiling 'navier-stokes'...
++Done.
++Compiling 'pdfjs'...
++Done.
++Compiling 'raytrace'...
++Done.
++Compiling 'regexp'...
++Done.
++Compiling 'richards'...
++Done.
++Compiling 'splay'...
++Done.
++Compiling 'typescript'... (3 files)
++Done.
++Compiling 'zlib'... (2 files)
++Done.
+--- ./nashorn/test/script/basic/compile-octane-splitter.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/compile-octane-splitter.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,32 +1,44 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
++ * Make sure that we run with the class cache off to so that every
++ * run produces compile time and with optimistic type info caching
++ * and persistent code store off, for the same reasons. These last two
++ * are currently default, but this is not guaranteed to be the case
++ * forever, so make this test future safe, we specify them explicitly
++ *
+ * @test
++ * @fork
+ * @option -Dnashorn.compiler.splitter.threshold=1000
+ * @fork
+ * @runif external.octane
+- */
++ * @option -scripting
++ * @option -Dnashorn.typeInfo.disabled=true
++ * @option --class-cache-size=0
++ * @option --persistent-code-cache=false
++ */
+
+-compile_only = true;
+-load(__DIR__ + 'run-octane.js');
++var fn = __DIR__ + 'compile-octane.js';
++var url = new java.io.File(fn).toURL();
++loadWithNewGlobal(url);
+--- ./nashorn/test/script/basic/compile-octane-splitter.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/compile-octane-splitter.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -1,14 +1,30 @@
+-[box2d] Compiled OK
+-[code-load] Compiled OK
+-[crypto] Compiled OK
+-[deltablue] Compiled OK
+-[earley-boyer] Compiled OK
+-[gbemu] Compiled OK
+-[mandreel] Compiled OK
+-[navier-stokes] Compiled OK
+-[pdfjs] Compiled OK
+-[raytrace] Compiled OK
+-[regexp] Compiled OK
+-[richards] Compiled OK
+-[splay] Compiled OK
+-[typescript] Compiled OK
++Compiling 'box2d'...
++Done.
++Compiling 'code-load'...
++Done.
++Compiling 'crypto'...
++Done.
++Compiling 'deltablue'...
++Done.
++Compiling 'earley-boyer'...
++Done.
++Compiling 'gbemu'... (2 files)
++Done.
++Compiling 'mandreel'...
++Done.
++Compiling 'navier-stokes'...
++Done.
++Compiling 'pdfjs'...
++Done.
++Compiling 'raytrace'...
++Done.
++Compiling 'regexp'...
++Done.
++Compiling 'richards'...
++Done.
++Compiling 'splay'...
++Done.
++Compiling 'typescript'... (3 files)
++Done.
++Compiling 'zlib'... (2 files)
++Done.
+--- ./nashorn/test/script/basic/compile-octane.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/compile-octane.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,30 +1,143 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * @test
+- * @runif external.octane
+- */
++ * Make sure that we run with the class cache off to so that every
++ * run produces compile time and with optimistic type info caching
++ * and persistent code store off, for the same reasons. These last two
++ * are currently default, but this is not guaranteed to be the case
++ * forever, so make this test future safe, we specify them explicitly
++ *
++ * This means that if you use this subtest as a compilation test
++ * harness, pass the arguments:
++ *
++ * -scripting -Dnashorn.typeInfo.disabled=true --class-cache-size=0
++ * --persistent-code-cache=false
++ *
++ * @subtest
++ */
+
+-compile_only = true;
+-load(__DIR__ + 'run-octane.js');
++load(__DIR__ + 'octane-payload.js');
++
++var DEFAULT_ITERS = 1; //default is one iteration through each benchmark
++var iters = DEFAULT_ITERS;
++var args = [];
++
++if (typeof $ARGS !== 'undefined') {
++ args = $ARGS;
++} else if (typeof arguments !== 'undefined' && arguments.length != 0) {
++ args = arguments;
++}
++
++var onlyTheseTests = [];
++var verbose = false;
++
++for (var i = 0; i < args.length; ) {
++ var arg = args[i];
++ if (arg === '--iterations') {
++ iters = +args[++i];
++ } else if (arg === '--verbose') {
++ verbose = true;
++ } else {
++ onlyTheseTests.push(arg);
++ }
++ i++;
++}
++
++if (isNaN(iters)) {
++ iters = DEFAULT_ITERS;
++}
++
++if (iters != DEFAULT_ITERS) {
++ print("Running " + iters + " iterations of each compilation.");
++}
++
++function print_if_verbose(x) {
++ if (verbose) {
++ print(x);
++ }
++}
++
++function contains(a, obj) {
++ for (var i = 0; i < a.length; i++) {
++ if (a[i] === obj) {
++ return true;
++ }
++ }
++ return false;
++}
++
++var testsCompiled = [];
++
++for (var j in tests) {
++ var test_name = tests[j].name;
++ var files = tests[j].files;
++
++ if (onlyTheseTests.length > 0 && !contains(onlyTheseTests, test_name)) {
++ print_if_verbose("Skipping " + test_name);
++ continue;
++ }
++
++ if (!contains(testsCompiled, test_name)) {
++ testsCompiled.push(test_name);
++ }
++
++ var str = "Compiling '" + test_name + "'...";
++ if (files.length > 1) {
++ str += " (" + files.length + " files)";
++ }
++ if (iters != 1) {
++ str += " (" + iters + " times)";
++ }
++ str + "...";
++ print(str);
++
++ for (var iteration = 0; iteration < iters; iteration++) {
++
++ //get a new global to avoid symbol pollution and reloads of base
++ //in the same namespace
++ var newGlobal = loadWithNewGlobal({script:'this', name:'test'});
++
++ //load base into the new global so we get BenchmarkSuite etc
++ newGlobal.load(base);
++
++ //load all files in the single benchmark
++ for (var k in files) {
++ var file = files[k];
++ if (iteration >= 0) { //only display message on first iteration
++ var str2 = "\t";
++ if (iters > 1) {
++ str2 += " [iteration " + (iteration + 1) + "]";
++ }
++ str2 += " processing file: " + file + "...";
++ print_if_verbose(str2);
++ }
++ newGlobal.load(new java.io.File(path + file).toURL());
++ }
++ }
++ print("Done.");
++}
++
++if (testsCompiled.length == 0) {
++ print("Error: no tests given to compile");
++}
+--- ./nashorn/test/script/basic/compile-octane.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,14 +0,0 @@
+-[box2d] Compiled OK
+-[code-load] Compiled OK
+-[crypto] Compiled OK
+-[deltablue] Compiled OK
+-[earley-boyer] Compiled OK
+-[gbemu] Compiled OK
+-[mandreel] Compiled OK
+-[navier-stokes] Compiled OK
+-[pdfjs] Compiled OK
+-[raytrace] Compiled OK
+-[regexp] Compiled OK
+-[richards] Compiled OK
+-[splay] Compiled OK
+-[typescript] Compiled OK
+--- ./nashorn/test/script/basic/condassign.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/condassign.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/construct.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/construct.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,19 +25,19 @@
+ * Constructor test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ function Test() {
+ this.A = "A big fat string";
+ this.B = 123;
+-
++
+ this.F = function(x) { return x; }
+-
+- var proto = Object.getPrototypeOf(this);
++
++ var proto = Object.getPrototypeOf(this);
+ proto.R = "A big fat string";
+ proto.S = 123;
+-
++
+ proto.T = function(x) { return x; }
+
+ return "monkey";
+--- ./nashorn/test/script/basic/constructorname.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/constructorname.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/convert.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/convert.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -42,7 +42,7 @@
+
+ // object to Map
+ obj = { foo: 333, bar: 'hello'};
+-var map = ScriptUtils.convert(obj, java.util.Map.class);
++var map = ScriptUtils.wrap(obj);
+ print(map instanceof java.util.Map);
+ for (m in map) {
+ print(m + " " + map[m]);
+--- ./nashorn/test/script/basic/dataview_endian.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/dataview_endian.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/dataview_getset.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/dataview_getset.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/dataview_new.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/dataview_new.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -57,7 +57,8 @@
+ fail("Should have thrown " + ErrorType.name);
+ } catch (e) {
+ if (! (e instanceof ErrorType)) {
+- fail("Expected " + ErrorType.name + " got " + e);
++ print("Expected " + ErrorType.name + " got " + e);
++ e.printStackTrace()
+ }
+ }
+ }
+--- ./nashorn/test/script/basic/date.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/date.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/dateparse.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/dateparse.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/decinc.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/decinc.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/delete.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/delete.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/delete2.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/delete2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -26,7 +26,7 @@
+ * throws VerifyError!!
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ var a = 10;
+@@ -39,7 +39,7 @@
+
+ function e(g) {
+ var f = 10;
+-
++
+ print(delete f);
+ print(f);
+ print(delete g);
+--- ./nashorn/test/script/basic/dotpropname.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/dotpropname.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/doublecache.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/doublecache.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -39,7 +39,7 @@
+ 0.5,
+ 100,
+ 200,
+-
++
+ -200,
+ -100,
+ -0.5,
+@@ -50,5 +50,5 @@
+ 100,
+ 200
+ ];
+-
++
+ for (i in x) print(x[i]);
+--- ./nashorn/test/script/basic/enumeration.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/enumeration.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * Make sure that there are no-enumerable items on standard objects.
++ * Make sure that there are no-enumerable items on standard objects.
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/errors.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/errors.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * Basic checks for Error constructors.
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/errorstack.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/errorstack.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -26,7 +26,7 @@
+ *
+ * @test
+ * @run
+- */
++ */
+
+ function func1() {
+ func2();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/block-function-decl.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,51 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ */
++
++"use strict";
++
++{
++ // f is defined on block level
++ print(f);
++ f();
++ function f() {
++ print("in f");
++ }
++ print(f);
++ f();
++}
++
++try {
++ print(typeof f);
++ f();
++} catch (e) {
++ print(e);
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/block-function-decl.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,10 @@
++function f() {
++ print("in f");
++ }
++in f
++function f() {
++ print("in f");
++ }
++in f
++undefined
++ReferenceError: "f" is not defined
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/const-empty.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ */
++
++try {
++ eval('"use strict";\n' +
++ 'const x;\n');
++} catch (e) {
++ print(String(e).replace(/\\/g, "/"));
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/const-empty.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,3 @@
++SyntaxError: test/script/basic/es6/const-empty.js#33:4<eval>:2:7 Missing assignment to constant "x"
++const x;
++ ^
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/const-reassign.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,174 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
++ *
++ * @test
++ * @run
++ * @option --language=es6 */
++
++"use strict";
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ 'x = 1;\n');
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ 'x++;\n');
++ fail("const assignment didn't throw");
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ 'x--;\n');
++ fail("const assignment didn't throw");
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ '++x;\n');
++ fail("const assignment didn't throw");
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ '--x;\n');
++ fail("const assignment didn't throw");
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ 'x += 1;\n');
++ fail("const assignment didn't throw");
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ 'x *= 1;\n');
++ fail("const assignment didn't throw");
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ 'x /= 1;\n');
++ fail("const assignment didn't throw");
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ 'x %= 1;\n');
++ fail("const assignment didn't throw");
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ 'x |= 1;\n');
++ fail("const assignment didn't throw");
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ 'x &= 1;\n');
++ fail("const assignment didn't throw");
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ 'x ^= 1;\n');
++ fail("const assignment didn't throw");
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ 'x <<= 1;\n');
++ fail("const assignment didn't throw");
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ 'x >>= 1;\n');
++ fail("const assignment didn't throw");
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ 'x >>>= 1;\n');
++ fail("const assignment didn't throw");
++} catch (e) {
++ print(e.name);
++}
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ 'delete x;\n');
++ fail("const assignment didn't throw");
++} catch (e) {
++ print(e.name);
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/const-reassign.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,16 @@
++SyntaxError
++SyntaxError
++SyntaxError
++SyntaxError
++SyntaxError
++SyntaxError
++SyntaxError
++SyntaxError
++SyntaxError
++SyntaxError
++SyntaxError
++SyntaxError
++SyntaxError
++SyntaxError
++SyntaxError
++SyntaxError
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/const-redeclare-extra.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057678: Tests for let&const keywords in Nashorn
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ * @option -scripting
++ */
++
++
++function tryIt (code) {
++ try {
++ eval(code)
++ } catch (e) {
++ print(String(e).replace(/\\/g, "/"))
++ }
++}
++
++tryIt(<<CODE
++ "use strict";
++ const x = 2;
++ var x = {};
++CODE)
++
++tryIt(<<CODE
++ "use strict";
++ var x = 2;
++ const x = {};
++CODE)
++
++tryIt(<<CODE
++ "use strict";
++ function x () {}
++ const x = 5;
++CODE)
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/const-redeclare-extra.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,9 @@
++SyntaxError: test/script/basic/es6/const-redeclare-extra.js#36:8<eval>:3:8 Variable "x" has already been declared
++ var x = {};
++ ^
++SyntaxError: test/script/basic/es6/const-redeclare-extra.js#36:8<eval>:3:10 Variable "x" has already been declared
++ const x = {};
++ ^
++SyntaxError: test/script/basic/es6/const-redeclare-extra.js#36:8<eval>:3:10 Variable "x" has already been declared
++ const x = 5;
++ ^
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/const-redeclare.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ */
++
++try {
++ eval('"use strict";\n' +
++ 'const x = 2;\n' +
++ 'const x = 2;\n');
++} catch (e) {
++ print(String(e).replace(/\\/g, "/"));
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/const-redeclare.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,3 @@
++SyntaxError: test/script/basic/es6/const-redeclare.js#33:4<eval>:2:6 Variable "x" has already been declared
++const x = 2;
++ ^
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/const-self.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
++ *
++ * @test
++ * @run
++ * @option --language=es6 */
++
++"use strict";
++
++const a = 1, b = a;
++
++print(a, b);
++
++try {
++ eval('"use strict";\n' +
++ 'const a = a;\n');
++} catch (e) {
++ print(e);
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/const-self.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,2 @@
++1 1
++ReferenceError: "a" is not defined
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/const-tdz.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,81 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
++ *
++ * @test
++ * @run
++ * @option --language=es6 */
++
++"use strict";
++
++{
++ print("test 1");
++
++ function f() {
++ try {
++ print(a);
++ } catch (a) {
++ print(a);
++ }
++ }
++
++ f();
++ const a = 1;
++ f();
++}
++
++{
++ print("test 2");
++
++ function f() {
++ try {
++ print(a);
++ } catch (a) {
++ print(a);
++ }
++ }
++
++ f();
++ const a = 2;
++ f();
++}
++
++{
++ print("test 3");
++ {
++ try {
++ print(a);
++ } catch (a) {
++ print(a);
++ }
++ }
++
++ const a = 3;
++
++ {
++ print(a);
++ }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/const-tdz.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,9 @@
++test 1
++ReferenceError: "a" is not defined
++1
++test 2
++ReferenceError: "a" is not defined
++2
++test 3
++ReferenceError: "a" is not defined
++3
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/const.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ */
++
++"use strict";
++
++const a = 2;
++const c = 2;
++print(a, c);
++
++function f(x) {
++ const a = 5;
++ const c = 10;
++ print(a, c);
++ if (x) {
++ const a = 42;
++ const c = 43;
++ print(a, c);
++ }
++ print(a, c);
++
++ function inner() {
++ (function() {
++ print(a, c);
++ })();
++ }
++ inner();
++}
++
++f(true);
++f(false);
++
++(function() {
++ (function() {
++ print(a, c);
++ })();
++})();
++
++function outer() {
++ print(a, c);
++}
++outer();
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/const.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,10 @@
++2 2
++5 10
++42 43
++5 10
++5 10
++5 10
++5 10
++5 10
++2 2
++2 2
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/for-let-object-fields.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,81 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8067219: NPE in ScriptObject.clone() when running with object fields
++ *
++ * @test
++ * @run
++ * @fork
++ * @option -Dnashorn.fields.objects=true
++ * @option --language=es6
++ */
++
++"use strict";
++
++for (let i = 0; i < 10; i++) {
++ print(i);
++}
++
++try {
++ print(i);
++} catch (e) {
++ print(e);
++}
++
++let a = [];
++
++for (let i = 0; i < 10; i++) {
++ a.push(function() { print(i); });
++}
++
++a.forEach(function(f) { f(); });
++
++a = [];
++
++for (let i = 0; i < 10; i++) {
++ if (i == 5) {
++ i = "foo";
++ }
++ a.push(function() { print(i); });
++}
++
++a.forEach(function(f) { f(); });
++
++try {
++ print(i);
++} catch (e) {
++ print(e);
++}
++
++a = [];
++
++for (let i = 0; i < 20; i++) {
++ if (i % 2 == 1) {
++ i += 2;
++ continue;
++ }
++ a.push(function() { print(i); });
++}
++
++a.forEach(function(f) { f(); });
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/for-let-object-fields.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++0
++1
++2
++3
++4
++5
++6
++7
++8
++9
++ReferenceError: "i" is not defined
++0
++1
++2
++3
++4
++5
++6
++7
++8
++9
++0
++1
++2
++3
++4
++foo
++ReferenceError: "i" is not defined
++0
++4
++8
++12
++16
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/for-let.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,79 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ */
++
++"use strict";
++
++for (let i = 0; i < 10; i++) {
++ print(i);
++}
++
++try {
++ print(i);
++} catch (e) {
++ print(e);
++}
++
++let a = [];
++
++for (let i = 0; i < 10; i++) {
++ a.push(function() { print(i); });
++}
++
++a.forEach(function(f) { f(); });
++
++a = [];
++
++for (let i = 0; i < 10; i++) {
++ if (i == 5) {
++ i = "foo";
++ }
++ a.push(function() { print(i); });
++}
++
++a.forEach(function(f) { f(); });
++
++try {
++ print(i);
++} catch (e) {
++ print(e);
++}
++
++a = [];
++
++for (let i = 0; i < 20; i++) {
++ if (i % 2 == 1) {
++ i += 2;
++ continue;
++ }
++ a.push(function() { print(i); });
++}
++
++a.forEach(function(f) { f(); });
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/for-let.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++0
++1
++2
++3
++4
++5
++6
++7
++8
++9
++ReferenceError: "i" is not defined
++0
++1
++2
++3
++4
++5
++6
++7
++8
++9
++0
++1
++2
++3
++4
++foo
++ReferenceError: "i" is not defined
++0
++4
++8
++12
++16
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-const-statement-context.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057980: let & const: remaining issues with lexical scoping
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ */
++
++function tryEval(s) {
++ try {
++ eval(s);
++ } catch (e) {
++ print(String(e).replace(/\\/g, "/"));
++ }
++}
++
++tryEval('if (true) let x = 1;');
++tryEval('if (true) const x = 1;');
++tryEval('while (true) let x = 1;');
++tryEval('while (true) const x = 1;');
++tryEval('for (;;) let x = 1;');
++tryEval('for (;;) const x = 1;');
++tryEval('do let x = 1; while (true);');
++tryEval('do const x = 1; while (true);');
++tryEval('with (y) const x = 1;');
++tryEval('with (y) let x = 1;');
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-const-statement-context.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,30 @@
++SyntaxError: test/script/basic/es6/let-const-statement-context.js#34:8<eval>:1:10 Expected statement but found let declaration
++if (true) let x = 1;
++ ^
++SyntaxError: test/script/basic/es6/let-const-statement-context.js#34:8<eval>:1:10 Expected statement but found const declaration
++if (true) const x = 1;
++ ^
++SyntaxError: test/script/basic/es6/let-const-statement-context.js#34:8<eval>:1:13 Expected statement but found let declaration
++while (true) let x = 1;
++ ^
++SyntaxError: test/script/basic/es6/let-const-statement-context.js#34:8<eval>:1:13 Expected statement but found const declaration
++while (true) const x = 1;
++ ^
++SyntaxError: test/script/basic/es6/let-const-statement-context.js#34:8<eval>:1:9 Expected statement but found let declaration
++for (;;) let x = 1;
++ ^
++SyntaxError: test/script/basic/es6/let-const-statement-context.js#34:8<eval>:1:9 Expected statement but found const declaration
++for (;;) const x = 1;
++ ^
++SyntaxError: test/script/basic/es6/let-const-statement-context.js#34:8<eval>:1:3 Expected statement but found let declaration
++do let x = 1; while (true);
++ ^
++SyntaxError: test/script/basic/es6/let-const-statement-context.js#34:8<eval>:1:3 Expected statement but found const declaration
++do const x = 1; while (true);
++ ^
++SyntaxError: test/script/basic/es6/let-const-statement-context.js#34:8<eval>:1:9 Expected statement but found const declaration
++with (y) const x = 1;
++ ^
++SyntaxError: test/script/basic/es6/let-const-statement-context.js#34:8<eval>:1:9 Expected statement but found let declaration
++with (y) let x = 1;
++ ^
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-const-switch.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057980: let & const: remaining issues with lexical scoping
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ */
++
++function tryEval(s) {
++ try {
++ eval(s);
++ } catch (e) {
++ print(String(e).replace(/\\/g, "/"));
++ }
++}
++
++tryEval('var x = 0; switch (x) { case 0: { let x = 1; print(x); } case 1: { let x = 2; print(x); }} print(x);');
++tryEval('var x = 0; switch (x) { case 0: { const x = 1; print(x); } case 1: { const x = 2; print(x); }} print(x);');
++
++// TODO: the following should not throw
++tryEval('switch (x) { case 0: let x = 1; }');
++tryEval('switch (x) { case 0: const x = 1; }');
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-const-switch.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,12 @@
++1
++2
++0
++1
++2
++0
++SyntaxError: test/script/basic/es6/let-const-switch.js#34:8<eval>:1:25 Unsupported let declaration in unprotected switch statement
++switch (x) { case 0: let x = 1; }
++ ^
++SyntaxError: test/script/basic/es6/let-const-switch.js#34:8<eval>:1:27 Unsupported const declaration in unprotected switch statement
++switch (x) { case 0: const x = 1; }
++ ^
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-eval.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,98 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
++ *
++ * @test
++ * @run
++ * @option --language=es6 */
++
++"use strict";
++
++function f() {
++ var a;
++ let b;
++ const c = 0;
++
++ print(a, b, c);
++
++ try {
++ eval("x = 1; print('x: ' + x);");
++ print("assignment to x succeeded");
++ } catch (e) {
++ print(e);
++ }
++ try {
++ eval("'use strict'; let z = 1; print('z: ' + z);");
++ print("assignment to z succeeded");
++ eval("print('z: ' + z);");
++ } catch (e) {
++ print(e);
++ }
++
++ try {
++ eval("a = 1; print(a);");
++ print("assignment to a succeeded");
++ } catch (e) {
++ print(e);
++ }
++ print("a: " + a);
++
++ try {
++ eval("b = 1; print('b: ' + b);");
++ print("assignment to b succeeded");
++ } catch (e) {
++ print(e);
++ }
++ print("b: " + b);
++
++ try {
++ eval("c = 1; print('c: ' + c);");
++ print("assignment to c succeeded");
++ } catch (e) {
++ print(e);
++ }
++ print("c: " + c);
++
++ eval("a = 2; let b = 3;");
++
++ try {
++ print(a, b, c);
++ } catch (e) {
++ print(e);
++ }
++
++ let x;
++
++ try {
++ print(a, b, c, x);
++ } catch (e) {
++ print(e);
++ }
++
++}
++
++f();
++
++print(typeof a, typeof b, typeof c, typeof x, typeof z);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-eval.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,16 @@
++undefined undefined 0
++ReferenceError: "x" is not defined
++z: 1
++assignment to z succeeded
++ReferenceError: "z" is not defined
++1
++assignment to a succeeded
++a: 1
++b: 1
++assignment to b succeeded
++b: 1
++TypeError: "c" is not a writable property of [object Object]
++c: 0
++2 1 0
++2 1 0 undefined
++undefined undefined undefined undefined undefined
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-load-lib.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @subtest
++ */
++
++"use strict";
++
++// var should be visible in other script, let and const not
++var a = 1;
++let b = 2;
++const c = 3;
++
++// top level function should be visible
++function top() {
++ print("top level function");
++}
++
++// block level function not visible outside script
++{
++ function block() {
++ print("block function");
++ }
++
++ top();
++ block();
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-load.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,60 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ */
++
++"use strict";
++
++load(__DIR__ + "let-load-lib.js");
++
++{
++ let a = 20;
++ const c = 30;
++ print("print local defs: " + a, c);
++}
++
++print("imported var: " + a);
++print("imported let: " + b);
++print("imported const: " + c);
++
++top();
++
++try {
++ block();
++} catch (e) {
++ print(e);
++}
++
++try {
++ c = "foo";
++} catch (e) {
++ print(e);
++}
++
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-load.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,9 @@
++top level function
++block function
++print local defs: 20 30
++imported var: 1
++imported let: 2
++imported const: 3
++top level function
++ReferenceError: "block" is not defined
++TypeError: Assignment to constant "c"
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-nodeclare.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
++ *
++ * @test
++ * @run
++ * @option --language=es6 */
++
++"use strict";
++
++try {
++ if (true) {
++ let x = 2;
++ print(x);
++ }
++ print(x);
++} catch (e) {
++ print(e);
++}
++
++
++try {
++ if (true) {
++ const x = 2;
++ print(x);
++ }
++ print(x);
++} catch (e) {
++ print(e);
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-nodeclare.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,4 @@
++2
++ReferenceError: "x" is not defined
++2
++ReferenceError: "x" is not defined
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-redeclare-extra.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057678: Tests for let&const keywords in Nashorn
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ * @option -scripting
++ */
++
++function tryIt (code) {
++ try {
++ eval(code)
++ } catch (e) {
++ print(String(e).replace(/\\/g, "/"))
++ }
++}
++
++tryIt(<<CODE
++ "use strict";
++ let x = 2;
++ const x = function (a,b,c) {};
++CODE)
++
++tryIt(<<CODE
++ "use strict";
++ let x = {};
++ var x = 2;
++CODE)
++
++tryIt(<<CODE
++ "use strict";
++ var x = 2;
++ let x = undefined;
++CODE)
++
++tryIt(<<CODE
++ "use strict";
++ const x = function (){};
++ let x = {};
++CODE)
++
++
++tryIt(<<CODE
++ "use strict";
++ let a = 2;
++ function a () {};
++CODE)
+\ No newline at end of file
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-redeclare-extra.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,15 @@
++SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:2:8 Variable "x" has already been declared
++ let x = 2;
++ ^
++SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:3:8 Variable "x" has already been declared
++ var x = 2;
++ ^
++SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:3:8 Variable "x" has already been declared
++ let x = undefined;
++ ^
++SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:2:10 Variable "x" has already been declared
++ const x = function (){};
++ ^
++SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:2:8 Variable "a" has already been declared
++ let a = 2;
++ ^
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-redeclare.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ */
++
++try {
++ eval('"use strict";\n' +
++ 'let x = 2;\n' +
++ 'let x = 2;\n');
++} catch (e) {
++ print(String(e).replace(/\\/g, "/"));
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-redeclare.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,3 @@
++SyntaxError: test/script/basic/es6/let-redeclare.js#33:4<eval>:2:4 Variable "x" has already been declared
++let x = 2;
++ ^
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-self.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
++ *
++ * @test
++ * @run
++ * @option --language=es6 */
++
++"use strict";
++
++let a, b = a;
++
++print(a, b);
++
++try {
++ eval('"use strict";\n' +
++ 'let a = a;\n');
++} catch (e) {
++ print(e);
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-self.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,2 @@
++undefined undefined
++ReferenceError: "a" is not defined
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-tdz.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,97 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
++ *
++ * @test
++ * @run
++ * @option --language=es6 */
++
++"use strict";
++
++{
++ print("test 1");
++
++ function f() {
++ try {
++ print(a);
++ } catch (a) {
++ print(a);
++ }
++ }
++
++ f();
++ let a = 1;
++ f();
++}
++
++{
++ print("test 2");
++
++ function f() {
++ try {
++ print(a);
++ } catch (a) {
++ print(a);
++ }
++ }
++
++ f();
++ let a = 2;
++ f();
++}
++
++{
++ print("test 3");
++
++ {
++ try {
++ print(a);
++ } catch (a) {
++ print(a);
++ }
++ }
++
++ let a = 3;
++
++ {
++ print(a);
++ }
++}
++
++{
++ print("test 4");
++ let a;
++
++ {
++ print(a);
++ }
++
++ a = 4;
++
++ {
++ print(a);
++ }
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let-tdz.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,12 @@
++test 1
++ReferenceError: "a" is not defined
++1
++test 2
++ReferenceError: "a" is not defined
++2
++test 3
++ReferenceError: "a" is not defined
++3
++test 4
++undefined
++4
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
++ *
++ * @test
++ * @run
++ * @option --language=es6 */
++
++"use strict";
++
++let a = 2;
++let c = 2;
++print(a, c);
++
++function f(x) {
++ let a = 5;
++ const c = 10;
++ print(a, c);
++ if (x) {
++ let a = 42;
++ const c = 43;
++ print(a, c);
++ }
++ print(a, c);
++
++ function inner() {
++ (function() {
++ print(a, c);
++ })();
++ }
++ inner();
++}
++
++f(true);
++f(false);
++
++(function() {
++ (function() {
++ print(a, c);
++ })();
++})();
++
++function outer() {
++ print(a, c);
++}
++outer();
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,10 @@
++2 2
++5 10
++42 43
++5 10
++5 10
++5 10
++5 10
++5 10
++2 2
++2 2
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let_const_closure.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,123 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057678: Tests for let&const keywords in Nashorn
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ * @option -scripting
++ */
++
++function tryIt(code) {
++ try {
++ eval(code)
++ } catch (e) {
++ print(e)
++ }
++}
++
++
++tryIt(<<CODE
++ function a () {
++ this.val = 41
++ let self = this
++ this.b = function () {
++ return self.val;
++ }
++ }
++ c = new a()
++ print(c.b.call(null))
++CODE)
++
++
++tryIt(<<CODE
++ function a () {
++ this.val = 42
++ let self = this
++ this.b = function () {
++ return this.val;
++ }.bind(self)
++ }
++ c = new a()
++ print(c.b.call(null))
++CODE)
++
++tryIt(<<CODE
++ function a () {
++ this.val = 43
++ const self = this
++ this.b = function () {
++ return self.val;
++ }
++ }
++ c = new a()
++ print(c.b.call(null))
++CODE)
++
++tryIt(<<CODE
++ function a () {
++ this.val = 44
++ const self = this
++ this.b = function () {
++ return this.val;
++ }.bind(self)
++ }
++ c = new a()
++ print(c.b.call(null))
++CODE)
++
++tryIt(<<CODE
++ let a = {name : 'test'}
++ let f = function () {
++ print(this.name)
++ }
++ let nf = f.bind(a)
++ nf()
++ if (true) {
++ let a = null
++ nf()
++ }
++ nf()
++CODE)
++
++
++tryIt(<<CODE
++ let arr = []
++ for (let i = 0; i < 3; i++) {
++ arr[i] = function(){return i;}
++ }
++ for (let i in arr) {
++ print(arr[i]())
++ }
++ arr = []
++ for (var i = 0; i < 3; i++) {
++ (function(i){
++ arr[i] = function(){return i;}
++ })(i)
++ }
++ for (let i in arr) {
++ print(arr[i]())
++ }
++CODE)
+\ No newline at end of file
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let_const_closure.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,13 @@
++41
++42
++43
++44
++test
++test
++test
++0
++1
++2
++0
++1
++2
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let_const_reuse.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,71 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057678: Tests for let&const keywords in Nashorn
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ * @option -scripting
++ */
++
++function tryIt (code) {
++ try {
++ eval(code)
++ } catch (e) {
++ print(String(e).replace(/\\/g, "/"))
++ }
++}
++
++tryIt(<<CODE
++ let a = 23
++ if (true) {
++ a--
++ let a = 43;
++ }
++CODE)
++
++tryIt(<<CODE
++ const a = 23
++ if (true) {
++ a--
++ const a = 43;
++ }
++CODE)
++
++tryIt(<<CODE
++ let a = 23
++ if (true) {
++ a--
++ const a = 43;
++ }
++CODE)
++
++tryIt(<<CODE
++ const a = 23
++ if (true) {
++ a--
++ let a = 43;
++ }
++CODE)
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let_const_reuse.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,8 @@
++ReferenceError: "a" is not defined
++SyntaxError: test/script/basic/es6/let_const_reuse.js#35:9<eval>:3:8 Assignment to constant "a"
++ a--
++ ^
++SyntaxError: test/script/basic/es6/let_const_reuse.js#35:9<eval>:3:8 Assignment to constant "a"
++ a--
++ ^
++ReferenceError: "a" is not defined
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let_different_types.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,73 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057678: Tests for let&const keywords in Nashorn
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ * @option -scripting
++ */
++
++function tryIt (code) {
++ try {
++ eval(code)
++ } catch (e) {
++ print(e)
++ }
++}
++
++tryIt(<<CODE
++ let a = function () { var a = "Hello World!"; return a; }
++ print(typeof a)
++ {
++ let a = 34;
++ print(typeof a)
++ if (true) {
++ let c = 54.7
++ var d = c
++ print(typeof c)
++ print(typeof d)
++ }
++ }
++ print(typeof a)
++ print(typeof a())
++ print(typeof c)
++ print(typeof d)
++ print(d)
++CODE)
++
++tryIt(<<CODE
++ let a = {}
++ if (true) {
++ function a () {
++ print (typeof a)
++ return 'Hello World!'
++ }
++ print(typeof a)
++ print(a())
++ }
++ print(typeof a)
++CODE)
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let_different_types.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,13 @@
++function
++number
++number
++number
++function
++string
++undefined
++number
++54.7
++function
++function
++Hello World!
++object
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let_loops.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,80 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057678: Tests for let&const keywords in Nashorn
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ * @option -scripting
++ */
++
++
++function tryIt (code) {
++ try {
++ eval(code)
++ } catch (e) {
++ print(e)
++ }
++}
++
++tryIt(<<CODE
++ let a = 2;
++ do {
++ a--;
++ let b = a;
++ } while (a > 0);
++ print(a)
++ print(b)
++CODE)
++
++tryIt(<<CODE
++ let a = 2
++ while(a > 0) {
++ a--
++ let b = a
++ }
++ print(a)
++ print(b)
++CODE)
++
++tryIt(<<CODE
++ let a = 2
++ while(a > 0) {
++ a--
++ const b = a
++ }
++ print(a)
++ print(b)
++CODE)
++
++tryIt(<<CODE
++ let a = 2;
++ do {
++ a--;
++ const b = a;
++ } while (a > 0);
++ print(a)
++ print(b)
++CODE)
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/let_loops.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,8 @@
++0
++ReferenceError: "b" is not defined
++0
++ReferenceError: "b" is not defined
++0
++ReferenceError: "b" is not defined
++0
++ReferenceError: "b" is not defined
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/lexical-toplevel-def.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057691: Nashorn: let & const declarations are not shared between scripts
++ *
++ * @subtest
++ */
++
++var VAR = "VAR";
++let LET = "LET";
++const CONST = "CONST";
++function FUNC() {}
++this.GLOBAL = "GLOBAL";
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/lexical-toplevel-print.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,51 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057691: Nashorn: let & const declarations are not shared between scripts
++ *
++ * @subtest
++ */
++
++print(VAR);
++print(LET);
++print(CONST);
++print(FUNC);
++print(GLOBAL);
++print(this.VAR);
++print(this.LET); // undefined
++print(this.CONST); // undefined
++print(this.FUNC);
++print(this.GLOBAL);
++print("VAR" in this);
++print("LET" in this); // false
++print("CONST" in this); // false
++print("FUNC" in this);
++print("GLOBAL" in this);
++
++try {
++ LET = LET + "LET";
++ CONST = CONST + "CONST";
++} catch (e) {
++ print(String(e).replace(/\\/g, "/"));
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/lexical-toplevel-redeclare-func-on-let.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057691: Nashorn: let & const declarations are not shared between scripts
++ *
++ * @subtest
++ */
++
++function LET() {}
++var SHOULD_NOT_EXIST = 10;
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/lexical-toplevel-redeclare-let-on-builtin.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057691: Nashorn: let & const declarations are not shared between scripts
++ *
++ * @subtest
++ */
++
++let Object = "LEXICAL BUILTIN";
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/lexical-toplevel-redeclare-let-on-func.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057691: Nashorn: let & const declarations are not shared between scripts
++ *
++ * @subtest
++ */
++
++let FUNC = 10;
++var SHOULD_NOT_EXIST = 10;
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/lexical-toplevel-redeclare-let-on-global.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057691: Nashorn: let & const declarations are not shared between scripts
++ *
++ * @subtest
++ */
++
++let GLOBAL = "LEXICAL GLOBAL";
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/lexical-toplevel-redeclare-let-on-var.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057691: Nashorn: let & const declarations are not shared between scripts
++ *
++ * @subtest
++ */
++
++let VAR = 10;
++var SHOULD_NOT_EXIST = 10;
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/lexical-toplevel-redeclare-var-on-let.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057691: Nashorn: let & const declarations are not shared between scripts
++ *
++ * @subtest
++ */
++
++var LET = 10;
++var SHOULD_NOT_EXIST = 10;
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/lexical-toplevel-redeclare.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,78 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057691: Nashorn: let & const declarations are not shared between scripts
++ *
++ * @test
++ * @run
++ * @option -scripting
++ * @option --language=es6
++ */
++
++load(__DIR__ + "lexical-toplevel-def.js");
++
++var global = this;
++
++function tryIt (code) {
++ try {
++ eval(code)
++ } catch (e) {
++ print(String(e).replace(/\\/g, "/"))
++ }
++}
++
++function loadScript(script) {
++ print(script);
++ try {
++ load(__DIR__ + script);
++ } catch (e) {
++ print(String(e).replace(/\\/g, "/"));
++ }
++ print(VAR);
++ print(LET);
++ print(CONST);
++ print(FUNC);
++ print(GLOBAL);
++ print(global.VAR);
++ print(global.LET);
++ print(global.CONST);
++ print(global.FUNC);
++ print(global.GLOBAL);
++ try {
++ print(SHOULD_NOT_EXIST);
++ } catch (e) {
++ print(String(e).replace(/\\/g, "/"));
++ }
++ print(global.SHOULD_NOT_EXIST);
++ print(Object);
++ print(global.Object);
++ print();
++}
++
++loadScript("lexical-toplevel-redeclare-var-on-let.js");
++loadScript("lexical-toplevel-redeclare-func-on-let.js");
++loadScript("lexical-toplevel-redeclare-let-on-var.js");
++loadScript("lexical-toplevel-redeclare-let-on-func.js");
++loadScript("lexical-toplevel-redeclare-let-on-builtin.js");
++loadScript("lexical-toplevel-redeclare-let-on-global.js");
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/lexical-toplevel-redeclare.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,100 @@
++lexical-toplevel-redeclare-var-on-let.js
++SyntaxError: Variable "LET" has already been declared
++VAR
++LET
++CONST
++function FUNC() {}
++GLOBAL
++VAR
++undefined
++undefined
++function FUNC() {}
++GLOBAL
++ReferenceError: "SHOULD_NOT_EXIST" is not defined
++undefined
++function Object() { [native code] }
++function Object() { [native code] }
++
++lexical-toplevel-redeclare-func-on-let.js
++SyntaxError: Variable "LET" has already been declared
++VAR
++LET
++CONST
++function FUNC() {}
++GLOBAL
++VAR
++undefined
++undefined
++function FUNC() {}
++GLOBAL
++ReferenceError: "SHOULD_NOT_EXIST" is not defined
++undefined
++function Object() { [native code] }
++function Object() { [native code] }
++
++lexical-toplevel-redeclare-let-on-var.js
++SyntaxError: Variable "VAR" has already been declared
++VAR
++LET
++CONST
++function FUNC() {}
++GLOBAL
++VAR
++undefined
++undefined
++function FUNC() {}
++GLOBAL
++ReferenceError: "SHOULD_NOT_EXIST" is not defined
++undefined
++function Object() { [native code] }
++function Object() { [native code] }
++
++lexical-toplevel-redeclare-let-on-func.js
++SyntaxError: Variable "FUNC" has already been declared
++VAR
++LET
++CONST
++function FUNC() {}
++GLOBAL
++VAR
++undefined
++undefined
++function FUNC() {}
++GLOBAL
++ReferenceError: "SHOULD_NOT_EXIST" is not defined
++undefined
++function Object() { [native code] }
++function Object() { [native code] }
++
++lexical-toplevel-redeclare-let-on-builtin.js
++VAR
++LET
++CONST
++function FUNC() {}
++GLOBAL
++VAR
++undefined
++undefined
++function FUNC() {}
++GLOBAL
++ReferenceError: "SHOULD_NOT_EXIST" is not defined
++undefined
++LEXICAL BUILTIN
++function Object() { [native code] }
++
++lexical-toplevel-redeclare-let-on-global.js
++VAR
++LET
++CONST
++function FUNC() {}
++LEXICAL GLOBAL
++VAR
++undefined
++undefined
++function FUNC() {}
++GLOBAL
++ReferenceError: "SHOULD_NOT_EXIST" is not defined
++undefined
++LEXICAL BUILTIN
++function Object() { [native code] }
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/lexical-toplevel.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8057691: Nashorn: let & const declarations are not shared between scripts
++ *
++ * @test
++ * @run
++ * @option --language=es6
++ */
++
++load(__DIR__ + "lexical-toplevel-def.js");
++
++load(__DIR__ + "lexical-toplevel-print.js");
++load(__DIR__ + "lexical-toplevel-print.js");
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/es6/lexical-toplevel.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,32 @@
++VAR
++LET
++CONST
++function FUNC() {}
++GLOBAL
++VAR
++undefined
++undefined
++function FUNC() {}
++GLOBAL
++true
++false
++false
++true
++true
++TypeError: Assignment to constant "CONST"
++VAR
++LETLET
++CONST
++function FUNC() {}
++GLOBAL
++VAR
++undefined
++undefined
++function FUNC() {}
++GLOBAL
++true
++false
++false
++true
++true
++TypeError: Assignment to constant "CONST"
+--- ./nashorn/test/script/basic/eval.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/eval.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * eval test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ print("eval.length " + eval.length);
+@@ -33,7 +33,7 @@
+ function test1() {
+ var x = 200;
+ y = x + 2000;
+-
++
+ print(x);
+ print(y);
+ }
+@@ -41,7 +41,7 @@
+ function test2() {
+ eval("var x = 300;");
+ eval("y = x + 3000;");
+-
++
+ print(x);
+ print(y);
+ }
+--- ./nashorn/test/script/basic/evalreturn.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/evalreturn.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * eval return values test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ var x = 0;
+@@ -65,7 +65,7 @@
+ var g = eval("function cake() { print('moist and delicious!'); } function cookie() { print('sweet and crunchy!'); }");
+ print(g);
+ g();
+-
+
+
+
++
+--- ./nashorn/test/script/basic/exprclosure.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/exprclosure.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/exprclosure.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/exprclosure.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -1,4 +1,4 @@
+-function(x) x*x;
++function(x) x*x
+ 625
+-function fun(x) x * (x + 1) / 2;
++function fun(x) x * (x + 1) / 2
+ 55
+--- ./nashorn/test/script/basic/extensibility.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/extensibility.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/fastpushpop.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,61 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * fastpushpop.js: make sure guards work for fast push implementation
++ * and normal one
++ *
++ * @test
++ * @run
++ */
++
++var a = [1,2,3];
++a.push(4);
++a.push(5);
++a.push(6);
++print(a);
++
++var a2 = Object.defineProperty(a,"length", { writable: false });
++try {
++ a2.push(7);
++} catch (e) {
++ print("first: " + (e instanceof TypeError));
++}
++
++print(a2);
++
++var b = [1,2,3,,,,4711.17,"dingo!"];
++b.push(4);
++b.push(5);
++b.push(6);
++print(b);
++
++var b2 = Object.defineProperty(b,"length", { writable: false });
++try {
++ b2.push(7);
++} catch (e) {
++ print("second: " + (e instanceof TypeError));
++}
++
++print(b2);
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/fastpushpop.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,6 @@
++1,2,3,4,5,6
++first: true
++1,2,3,4,5,6
++1,2,3,,,,4711.17,dingo!,4,5,6
++second: true
++1,2,3,,,,4711.17,dingo!,4,5,6
+--- ./nashorn/test/script/basic/fileline.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/fileline.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/finally-catchalls.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/finally-catchalls.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,75 +30,75 @@
+
+ function test1() {
+ try {
+- print("try");
+- throw "ex";
++ print("try");
++ throw "ex";
+ } finally {
+- print("finally");
++ print("finally");
+ }
+ }
+
+-function test2() {
++function test2() {
+ try {
+- print("try");
++ print("try");
+ } finally {
+- print("finally");
++ print("finally");
+ }
+ }
+
+-function test3() {
++function test3() {
+ try {
+- print("try");
+- return;
++ print("try");
++ return;
+ } finally {
+- print("finally");
++ print("finally");
+ }
+ }
+
+-function test4() {
++function test4() {
+ var i = 0;
+ while (i<10) {
+- try {
+- print("try "+i);
+- i++;
+- continue;
+- } finally {
+- print("finally "+i);
+- }
++ try {
++ print("try "+i);
++ i++;
++ continue;
++ } finally {
++ print("finally "+i);
++ }
+ }
+ print(i);
+ }
+
+-function test5() {
++function test5() {
+ var i = 0;
+ while (i<10) {
+- try {
+- print("try "+i);
+- i++;
+- break;
+- } finally {
+- print("finally "+i);
+- }
++ try {
++ print("try "+i);
++ i++;
++ break;
++ } finally {
++ print("finally "+i);
++ }
+ }
+ print(i);
+ }
+
+-function test6() {
++function test6() {
+ var i = 0;
+ while (i<10) {
+- try {
+- print("try "+i);
+- if (i == 5)
+- break;
+- i++;
+- } finally {
+- print("finally "+i);
+- }
++ try {
++ print("try "+i);
++ if (i == 5)
++ break;
++ i++;
++ } finally {
++ print("finally "+i);
++ }
+ }
+ print(i);
+ }
+
+ print("\ntest 1\n");
+-try {
++try {
+ test1();
+ } catch (e) {
+ print("got e");
+--- ./nashorn/test/script/basic/finallyreturn.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/finallyreturn.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/forin.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/forin.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/forin2.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/forin2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -37,7 +37,7 @@
+ print("error 1");
+ } catch(e) {
+ if ((e instanceof TypeError) !== true) {
+- print(e);
++ print(e);
+ }
+ }
+
+@@ -46,30 +46,30 @@
+ print("error 2");
+ } catch(e) {
+ if((e instanceof TypeError) !== true) {
+- print(e);
++ print(e);
+ }
+ }
+
+-try {
+- for (var y in null) {
+- y = 2;
++try {
++ for (var y in null) {
++ y = 2;
+ }
+ print("this is ok 1");
+ } catch(e) {
+ if ((e instanceof TypeError) !== true) {
+- print(e);
++ print(e);
+ }
+ }
+
+ // CHECK#4
+ try {
+- for (var z in 'bbb'.match(/aaa/)) {
+- z = 2;
++ for (var z in 'bbb'.match(/aaa/)) {
++ z = 2;
+ }
+ print("this is ok 2");
+ } catch(e) {
+ if((e instanceof TypeError) !== true) {
+- print(e);
++ print(e);
+ }
+ }
+
+@@ -79,7 +79,7 @@
+ print("error 5");
+ } catch(e) {
+ if ((e instanceof TypeError) !== true) {
+- print(e);
++ print(e);
+ }
+ }
+
+@@ -88,29 +88,29 @@
+ print("error 6");
+ } catch (e) {
+ if ((e instanceof TypeError) !== true) {
+- print(e);
++ print(e);
+ }
+ }
+
+ // CHECK#3
+ try {
+- for (var y in undefined) {
+- y = 2;
++ for (var y in undefined) {
++ y = 2;
+ }
+ print("this is ok 3");
+-} catch (e) {
++} catch (e) {
+ if ((e instanceof TypeError) !== true) {
+- print(e);
++ print(e);
+ }
+ }
+
+ try {
+- for (var z in this.foo) {
+- z = 2;
++ for (var z in this.foo) {
++ z = 2;
+ }
+ print("this is ok 4");
+ } catch (e) {
+ if ((e instanceof TypeError) !== true) {
+- print(e);
++ print(e);
+ }
+ }
+--- ./nashorn/test/script/basic/funcarray.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/funcarray.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,9 +25,9 @@
+ * Function array test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+-
++
+
+ var funcs = [
+ function() { print("first"); },
+@@ -35,7 +35,7 @@
+ function() { print("third"); },
+ function() { print("fourth"); }
+ ];
+-
++
+ funcs[0]();
+ funcs[1]();
+ funcs[2]();
+--- ./nashorn/test/script/basic/funcbind.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/funcbind.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -34,10 +34,10 @@
+ print("global foo");
+ }
+
+-function func(x, y) {
++function func(x, y) {
+ print(this == global);
+- print(x);
+- print(y);
++ print(x);
++ print(y);
+ this.foo();
+ }
+
+--- ./nashorn/test/script/basic/funcbind2.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/funcbind2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/funcbind3.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/funcbind3.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/funcconstructor.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/funcconstructor.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/getclassname.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/getclassname.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/getter_callsite.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/getter_callsite.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * Check that getter property is properly invoked by a callsite
+- *
++ *
+ * @test
+ * @run
+ */
+@@ -32,7 +32,7 @@
+ return { get foo() { return a }};
+ }
+
+-function printFoo(obj) {
++function printFoo(obj) {
+ print("obj.foo is " + obj.foo);
+ }
+
+--- ./nashorn/test/script/basic/gettercalls.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/gettercalls.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/getterfunc.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/getterfunc.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/gettersetter.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/gettersetter.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * Getter/Setter test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ 'use strict';
+@@ -39,7 +39,7 @@
+ this._x = x;
+ }
+ };
+-
++
+ var b = {
+ _x : "default",
+ get x() {
+@@ -47,7 +47,7 @@
+ }
+ };
+
+-
++
+ var c = {
+ _x : "default",
+ set x(x) {
+--- ./nashorn/test/script/basic/globalaccess.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/globalaccess.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/globals.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/globals.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/globalscope.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/globalscope.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * Global scope test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ var g = this;
+--- ./nashorn/test/script/basic/hello.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/hello.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * Simple "hello world" test
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ print("hello world");
+--- ./nashorn/test/script/basic/herestr_operator.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/herestr_operator.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/hideLocationProperties.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,57 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Tests the hiding of location properties by local variables etc.
++ *
++ * @test
++ * @run
++ */
++
++function x(__FILE__) {
++ print(__FILE__);
++}
++
++function y(__FILE__) {
++ print(__FILE__);
++ function y1() { __FILE__ }
++}
++
++function w(__FILE__) {
++ print(__FILE__);
++ return arguments;
++}
++
++function z(__FILE__) {
++ (function() { print(__FILE__) })()
++}
++
++print(__FILE__.replace(/\\/g, "/"))
++
++var o = { __FILE__: "woot" }
++with(o) { print(__FILE__) }
++
++x("foo")
++y("bar")
++w("boo")
++z("baz")
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/hideLocationProperties.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,6 @@
++test/script/basic/hideLocationProperties.js
++woot
++foo
++bar
++boo
++baz
+--- ./nashorn/test/script/basic/illegaljavaname.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/illegaljavaname.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/importpackage.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/importpackage.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/incheck.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/incheck.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,30 +1,30 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * Check that the expression ("property" in obj) works for own property as
++ * Check that the expression ("property" in obj) works for own property as
+ * well as properties 'inherited' from proto chain.
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/indexedcall.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/indexedcall.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/info.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/info.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/inherited_nonwritable.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/inherited_nonwritable.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/instanceof.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/instanceof.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/instanceof2.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/instanceof2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * Instanceof test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ var x = { a: 1, b: "string", c: [1, 2, 3], d: function() {} };
+--- ./nashorn/test/script/basic/interfaces.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/interfaces.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -28,7 +28,7 @@
+ * @run
+ */
+
+-// implement java.lang.Runnable interface
++// implement java.lang.Runnable interface
+ var runnable = new java.lang.Runnable({
+ run: function() {
+ print("Inside run function");
+--- ./nashorn/test/script/basic/iterator.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/iterator.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * Verify that basic for..in works for objects, arrays.
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/java.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/java.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/javaadapter.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/javaadapter.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/javaarray.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/javaarray.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/javaarrayconversion.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/javaarrayconversion.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * Tests for conversion of JavaScript arrays to Java arrays and the other
+- * way round. Also generally useful as a JavaScript-to-Java type conversion
++ * way round. Also generally useful as a JavaScript-to-Java type conversion
+ * test.
+ *
+ * @test
+@@ -49,9 +49,9 @@
+ testF(inputValue, type, isNaN)
+ }
+
+-// Those labeled "Correct?" are not clearly correct conversions. Those
+-// labeled "TypeError maybe?" could actually throw a TypeError, or only
+-// throw a TypeError when in strict mode.
++// Those labeled "Correct?" are not clearly correct conversions. Those
++// labeled "TypeError maybe?" could actually throw a TypeError, or only
++// throw a TypeError when in strict mode.
+ // The case of ("false", "boolean") => true is particularly amusing.
+
+ test(x, "int", 0) // Correct? TypeError maybe?
+--- ./nashorn/test/script/basic/javaclassoverrides.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/javaclassoverrides.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/javaexceptions.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/javaexceptions.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * Basic checks for throwing and catching java exceptions from script.
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/javaimporter.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/javaimporter.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -42,7 +42,7 @@
+ print("java=" + map.get("java"));
+ print("cpp=" + map.get("cpp"));
+
+-var imports2 = new JavaImporter(java.io, java.util);
++var imports2 = new JavaImporter(java.io, java.util);
+ with (imports2) {
+ print(File);
+ }
+--- ./nashorn/test/script/basic/javainnerclasses.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/javainnerclasses.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -27,7 +27,7 @@
+ * @test
+ * @run
+ */
+-
++
+ // Do it with Java.type()
+ var outer = new (Java.type("jdk.nashorn.test.models.OuterClass"))("apple")
+ print(outer)
+--- ./nashorn/test/script/basic/javasigcall.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/javasigcall.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/jquery.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/jquery.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,49 +29,49 @@
+ */
+
+ var urls = [
+- 'http://code.jquery.com/jquery-1.7.2.min.js',
+- 'http://code.jquery.com/jquery-1.7.2.js'
+- ];
+-
++ 'http://code.jquery.com/jquery-1.7.2.min.js',
++ 'http://code.jquery.com/jquery-1.7.2.js'
++ ];
++
+ function test_jquery(url) {
+-
++
+ //bug one repro - this should compile
+ function a() {
+- var c;
+- if (func1(zz) || (c = func2(zz)) ) {
+- if (c) {
+- }
+- }
+- return target;
++ var c;
++ if (func1(zz) || (c = func2(zz)) ) {
++ if (c) {
++ }
+ }
+-
++ return target;
++ }
++
+ //bug two repro - this should compile
+ function b() {
+- return ((v ? i : "") + "str");
++ return ((v ? i : "") + "str");
+ }
+-
++
+ function checkWindow(e) {
+- if (e instanceof ReferenceError && e.toString().indexOf('window') != -1) {
+- return;
+- }
+- throw e;
++ if (e instanceof ReferenceError && e.toString().indexOf('window') != -1) {
++ return;
+ }
+-
++ throw e;
++ }
++
+ var name;
+-
+- try {
+- var split = url.split('/');
+- name = split[split.length - 1];
+- var path = __DIR__ + "../external/jquery/" + name;
+- try {
+- load(path);
+- } catch (e) {
+- checkWindow(e);
+- }
++
++ try {
++ var split = url.split('/');
++ name = split[split.length - 1];
++ var path = __DIR__ + "../external/jquery/" + name;
++ try {
++ load(path);
+ } catch (e) {
+- print("Unexpected exception " + e);
++ checkWindow(e);
+ }
+-
++ } catch (e) {
++ print("Unexpected exception " + e);
++ }
++
+ print("done " + name);
+ }
+
+--- ./nashorn/test/script/basic/jsadapter.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/jsadapter.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/jsadapterlink.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/jsadapterlink.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/json.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/json.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -51,12 +51,12 @@
+ print(JSON.stringify(obj));
+ print(JSON.stringify(obj2));
+
+-try {
++try {
+ JSON.parse('{ "foo" /*comment */ : 44, "bar" : "hello" }', reviver);
+ print("Fail!");
+ } catch (e) {
+ if (!(e instanceof SyntaxError)) {
+- print("Comments are illegal in JSON. Should throw SyntaxError, not " + e);
++ print("Comments are illegal in JSON. Should throw SyntaxError, not " + e);
+ }
+ }
+ print("Success!");
+--- ./nashorn/test/script/basic/list.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/list.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/list.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/list.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -10,7 +10,7 @@
+ l[0]=foo
+ l[1]=a
+ l[0.9]=null
+-l['blah']=null
++l['blah']=undefined
+ l[size_name]()=2
+ java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
+ java.lang.IndexOutOfBoundsException: Index: Infinity, Size: 2
+--- ./nashorn/test/script/basic/literal.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/literal.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * Object literal test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+
+--- ./nashorn/test/script/basic/load.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/load.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/loadedfile.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/loadedfile.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/localundef.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/localundef.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -32,7 +32,7 @@
+ function func(arg){
+ // initializing "x" with something removes VerifyError!
+ var x;
+- if (arg == 1) {
++ if (arg == 1) {
+ return x;
+ } else {
+ x = 0;
+--- ./nashorn/test/script/basic/map.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/map.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -41,7 +41,7 @@
+
+ print("m = " + m)
+ print("m.empty = " + m.empty) // prints "false"
+-print("m['empty'] = " + m['empty'])
++print("m['empty'] = " + m['empty'])
+ print("m[empty_key] = " + m[empty_key]) // prints "foo"
+
+ print("m.bwah = " + m.bwah) // prints "null"
+--- ./nashorn/test/script/basic/math.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/math.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/minuszero.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/minuszero.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/module.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/module.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -31,4 +31,4 @@
+ exports.func = function() {
+ print("module.func called");
+ }
+-}
++}
+--- ./nashorn/test/script/basic/moduleload.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/moduleload.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/nashorn2.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/nashorn2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,9 +25,9 @@
+ * Regression: NAS2 - lhs of index has no symbol.
+ *
+ * @test
+- * @run
++ * @run
+ */
+-
++
+
+ var obj = { prop: [3, 4] };
+ print(obj.prop[0]);
+--- ./nashorn/test/script/basic/natives.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/natives.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -27,7 +27,7 @@
+ * @test
+ * @run
+ */
+-
++
+ var s = "abcded";
+ var n = 1289.90;
+ var b = true;
+--- ./nashorn/test/script/basic/new.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/new.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * new Function test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ function MyObject() {
+--- ./nashorn/test/script/basic/newexpr.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/newexpr.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -44,8 +44,8 @@
+ }
+
+ print(new func().foo);
+-
+-print ((new function() { this.x = "hello" }).x);
++
++print ((new function() { this.x = "hello" }).x);
+
+ var abc = {
+ bar: function() {
+@@ -56,10 +56,10 @@
+ print(new abc.bar().x);
+
+ function func2() {
+- return {
++ return {
+ foo: function() {
+ print("foo");
+- }
++ }
+ };
+ };
+
+--- ./nashorn/test/script/basic/newnew.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/newnew.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -27,7 +27,7 @@
+ * @test
+ * @run
+ */
+-
++
+ function myObject() {
+ this.x = 10;
+ this.y = 20;
+--- ./nashorn/test/script/basic/no_line_numbers.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/no_line_numbers.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -53,8 +53,8 @@
+
+ while (true) {
+ break;
+- if (true) {
+- var s;
++ if (true) {
++ var s;
+ }
+ }
+
+@@ -64,20 +64,20 @@
+ for ( ; ; ) {
+ break;
+ while (true) {
+- do {
+- var u;
+- } while (true);
+- }
++ do {
++ var u;
++ } while (true);
++ }
+ }
+
+ function terminal() {
+ print("r = "+r);
+ print("t = "+t);
+ for (;;) {
+- var r;
+- return;
+- var t;
+- print("THIS SHOULD NEVER BE PRINTED!");
++ var r;
++ return;
++ var t;
++ print("THIS SHOULD NEVER BE PRINTED!");
+ }
+ print("NEITHER SHOULD THIS");
+ }
+@@ -87,13 +87,13 @@
+ function terminal2() {
+ print("q = "+q);
+ for (;;) {
+- return;
+- print("THIS SHOULD NEVER BE PRINTED!");
++ return;
++ print("THIS SHOULD NEVER BE PRINTED!");
+ }
+ print("NEITHER SHOULD THIS");
+ }
+
+-try {
++try {
+ terminal2();
+ } catch (e) {
+ print(e);
+@@ -111,13 +111,13 @@
+ } catch (e) {
+ print(e);
+ }
+-
++
+
+ function disp_a() {
+ var a = 20;
+ print("Value of 'a' inside the function " + a);
+ }
+-
++
+ var a = 10;
+
+ disp_a();
+--- ./nashorn/test/script/basic/nonconstructors.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/nonconstructors.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/nosuchmethod.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/nosuchmethod.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * Test noSuchMethod feature.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ __noSuchProperty__ = function(a) { this[a] = "xxx"; return this[a]; }
+--- ./nashorn/test/script/basic/nosuchproperty.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/nosuchproperty.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/number.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/number.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/numberstring.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/numberstring.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/objectprops.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/objectprops.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -45,7 +45,7 @@
+ xyz: { value: 44 },
+ abc: { get: function() { print("get abc"); return "abc"; } }
+ }
+-);
++);
+
+ print("obj.xyz = " + obj.xyz);
+ print("obj.abc = " + obj.abc);
+@@ -54,7 +54,7 @@
+ var obj2 = Object.create(MyConstructor.prototype);
+ print("obj2 in MyConstructor instance? " + (obj2 instanceof MyConstructor));
+
+-var obj3 = Object.create(Object.prototype,
++var obj3 = Object.create(Object.prototype,
+ {
+ xyz: { value: 44 }
+ }
+--- ./nashorn/test/script/basic/objects.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/objects.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/octane-payload.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,58 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @subtest
++ */
++
++function initZlib() {
++ zlib = new BenchmarkSuite('zlib', [152815148], [
++ new Benchmark('zlib', false, true, 10,
++ runZlib, undefined, tearDownZlib, null, 3)]);
++}
++
++var tests = [
++ {name:"box2d", files:["box2d.js"], suite:"Box2DBenchmark"},
++ {name:"code-load", files:["code-load.js"], suite:"CodeLoad"},
++ {name:"crypto", files:["crypto.js"], suite:"Crypto"},
++ {name:"deltablue", files:["deltablue.js"], suite:"DeltaBlue"},
++ {name:"earley-boyer", files:["earley-boyer.js"], suite:"EarleyBoyer"},
++ {name:"gbemu", files:["gbemu-part1.js", "gbemu-part2.js"], suite:"GameboyBenchmark"},
++ {name:"mandreel", files:["mandreel.js"], suite:"MandreelBenchmark"},
++ {name:"navier-stokes", files:["navier-stokes.js"], suite:"NavierStokes"},
++ {name:"pdfjs", files:["pdfjs.js"], suite:"PdfJS", cleanUpIteration: function() { canvas_logs = []; }},
++ {name:"raytrace", files:["raytrace.js"], suite:"RayTrace"},
++ {name:"regexp", files:["regexp.js"], suite:"RegExpSuite"},
++ {name:"richards", files:["richards.js"], suite:"Richards"},
++ {name:"splay", files:["splay.js"], suite:"Splay"},
++ {name:"typescript", files:["typescript.js", "typescript-input.js", "typescript-compiler.js"], suite:"typescript"},
++ //zlib currently disabled - requires read
++ {name:"zlib", files:["zlib.js", "zlib-data.js"], suite:"zlib", before:initZlib}
++];
++
++var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__;
++
++// TODO: why is this path hard coded when it's defined in project properties?
++var path = dir + "../external/octane/";
++var base = path + "base.js";
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/optimistic_arithmetic_check_type.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,77 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8036987, 8037572
++ * @summary Implement tests that checks static types in the compiled code
++ * @option --optimistic-types=true
++ * @run
++ */
++
++var inspect = Java.type("jdk.nashorn.test.tools.StaticTypeInspector").inspect
++var a = 3, b, c;
++var x = { a: 2, b:1, c: 7, d: -1}
++var y = { a: Number.MAX_VALUE, b: Number.POSITIVE_INFINITY, c: "Hello", d: undefined}
++
++// Testing arithmetic operators
++//-- Local variable
++print(inspect(x.a*x.b, "local int multiplication by local int"))
++print(inspect(x.a/x.b, "local int division by local int without remainder"))
++print(inspect(x.c/x.a, "local int division by local int with remainder"))
++print(inspect(x.c%x.a, "local int modulo by local int"))
++print(inspect(x.a+x.b, "local int addition local int"))
++print(inspect(x.a-x.b, "local int substraction local int"))
++print(inspect(y.a*y.a, "max value multiplication by max value"))
++print(inspect(y.b*y.b, "infinity multiplication by infinity"))
++print(inspect(x.d/y.b, "-1 division by infinity"))
++print(inspect(y.b/x.e, "infinity division by zero"))
++print(inspect(y.b/y.c, "infinity division by String"))
++print(inspect(y.d/y.d, "local undefined division by local undefined"))
++print(inspect(y.d*y.d, "local undefined multiplication by local undefined"))
++print(inspect(y.d+x.a, "local undefined addition local int"))
++print(inspect(y.d--, "local undefined decrement postfix"))
++print(inspect(--y.d, "local undefined decrement prefix"))
++print(inspect(x.a++, "local int increment postfix"))
++print(inspect(++x.a, "local int increment prefix"))
++print(inspect(x.a--, "local int decrement postfix"))
++print(inspect(--x.a, "local int decrement prefix"))
++print(inspect(+x.a, "local int unary plus"))
++print(inspect(-x.a, "local int unary minus"))
++//-- Global variable
++print(inspect(b*c, "undefined multiplication by undefined"))
++print(inspect(b/c, "undefined division by undefined"))
++print(inspect(a+a, "global int addition global int"))
++print(inspect(a-a, "global int substraction global int"))
++print(inspect(a*a, "global int multiplication by global int"))
++print(inspect(a++, "global int increment postfix"))
++print(inspect(++a, "global int increment prefix"))
++print(inspect(a--, "global int decrement postfix"))
++print(inspect(--a, "global int decrement prefix"))
++print(inspect(+a, "global int unary plus"))
++print(inspect(-a, "global int unary minus"))
++print(inspect(b--, "global undefined decrement postfix"))
++print(inspect(--b, "global undefined decrement prefix"))
++print(inspect(x, "object"))
++print(inspect(x/x, "object division by object"))
++print(inspect(x/y, "object division by object"))
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/optimistic_arithmetic_check_type.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,38 @@
++local int multiplication by local int: int
++local int division by local int without remainder: int
++local int division by local int with remainder: double
++local int modulo by local int: int
++local int addition local int: int
++local int substraction local int: int
++max value multiplication by max value: double
++infinity multiplication by infinity: double
++-1 division by infinity: double
++infinity division by zero: double
++infinity division by String: double
++local undefined division by local undefined: double
++local undefined multiplication by local undefined: double
++local undefined addition local int: double
++local undefined decrement postfix: double
++local undefined decrement prefix: double
++local int increment postfix: int
++local int increment prefix: int
++local int decrement postfix: int
++local int decrement prefix: int
++local int unary plus: int
++local int unary minus: int
++undefined multiplication by undefined: double
++undefined division by undefined: double
++global int addition global int: int
++global int substraction global int: int
++global int multiplication by global int: int
++global int increment postfix: int
++global int increment prefix: int
++global int decrement postfix: int
++global int decrement prefix: int
++global int unary plus: int
++global int unary minus: int
++global undefined decrement postfix: double
++global undefined decrement prefix: double
++object: object
++object division by object: double
++object division by object: double
+\ No newline at end of file
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/optimistic_assignment_check_type.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8036987, 8037572
++ * @summary Implement tests that checks static types in the compiled code
++ * @option --optimistic-types=true
++ * @run
++ */
++
++var inspect = Java.type("jdk.nashorn.test.tools.StaticTypeInspector").inspect
++var a = b = 3;
++var c;
++var x = { a: 2, b:1, c: 7, d: -1, e: 1}
++var y = { a: undefined, b: undefined}
++
++// Testing assignment operators
++//-- Global variable
++print(inspect(a=c, "global int assignment to global variable"))
++print(inspect(a=b, "undefined assignment to global int"))
++print(inspect(a=y.a, "global int assignment to undefined"))
++print(inspect(a+=b, "undefined addition assignment to global int"))
++print(inspect(b=b+b, "global int addition global int"))
++print(inspect(b+= y.a, "global int addition assignment undefined"))
++//--Local variable
++print(inspect(x.a+= y.a, "local int addition assignment local undefined"))
++print(inspect(x.b=y.a, "local int assignment to undefined"))
++print(inspect(y.a+=y.a, "local undefined addition assignment local undefined"))
++print(inspect(x.c-=x.d, "local int substraction assignment local int"))
++print(inspect(x.c*=x.d, "local int multiplication assignment local int"))
++print(inspect(x.c/=x.d, "local int division assignment local int"))
++print(inspect(y.b=x.c, "local undefined assignment to local int"))
++print(inspect(y.c=x.c, "local boolean assignment to local int"))
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/optimistic_assignment_check_type.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,14 @@
++global int assignment to global variable: undefined
++undefined assignment to global int: int
++global int assignment to undefined: undefined
++undefined addition assignment to global int: double
++global int addition global int: int
++global int addition assignment undefined: double
++local int addition assignment local undefined: double
++local int assignment to undefined: undefined
++local undefined addition assignment local undefined: double
++local int substraction assignment local int: int
++local int multiplication assignment local int: int
++local int division assignment local int: int
++local undefined assignment to local int: int
++local boolean assignment to local int: int
+\ No newline at end of file
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/optimistic_check_type.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,108 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8036987, 8037572
++ * @summary Implement tests that checks static types in the compiled code
++ * @option --optimistic-types=true
++ * @run
++ */
++
++var inspect = Java.type("jdk.nashorn.test.tools.StaticTypeInspector").inspect
++var a=3, b=2.3, c=true, d;
++var x = { a: 2, b:0, c:undefined}
++var trees = new Array("redwood", "bay", "cedar", "oak");
++
++// Testing conditional operator
++print(inspect("" ? b : x.a, "ternary operator"))
++var b1 = b;
++print(inspect(x.b ? b1 : x.a, "ternary operator"))
++var b2 = b;
++print(inspect(c ? b2 : a, "ternary operator"))
++var b3 = b;
++print(inspect(!c ? b3 : a, "ternary operator"))
++var b4 = b;
++print(inspect(d ? b4 : x.c, "ternary operator"))
++print(inspect(x.c ? a : c, "ternary operator"))
++print(inspect(c ? d : a, "ternary operator"))
++var b5 = b;
++print(inspect(c ? +a : b5, "ternary operator"))
++
++// Testing format methods
++print(inspect(b.toFixed(2), "global double toFixed()"))
++print(inspect(b.toPrecision(2)/1, "global double toPrecision() divided by 1"))
++print(inspect(b.toExponential(2), "global double toExponential()"))
++
++// Testing arrays
++print(inspect(trees[1], "member object"))
++trees[1] = undefined;
++print(inspect(trees[1], "member undefined"))
++var b6=b;
++print(inspect(1 in trees ? b6 : a, "conditional on array member"))
++delete trees[2]
++var b7=b;
++print(inspect(2 in trees ? b7 : a, "conditional on array member"))
++print(inspect(3 in trees ? trees[2]="bay" : a, "conditional on array member"))
++var b8=b;
++print(inspect("oak" in trees ? b8 : a, "conditional on array member"))
++
++// Testing nested functions and return value
++function f1() {
++ var x = 2, y = 1;
++ function g() {
++ print(inspect(x, "outer local variable"));
++ print(inspect(a, "global variable"));
++ print(inspect(x*y, "outer local int multiplication by outer local int"));
++ print(inspect(a*d, "global int multiplication by global undefined"));
++ }
++ g()
++}
++f1()
++
++function f2(a,b,c) {
++ g = (a+b) * c;
++ print(inspect(c, "local undefined"));
++ print(inspect(a+b, "local undefined addition local undefined"));
++ print(inspect(g, "local undefined multiplication by undefined"));
++}
++f2()
++
++function f3(a,b) {
++ g = a && b;
++ print(inspect(g, "local undefined AND local undefined"));
++ print(inspect(c||g, "global true OR local undefined"));
++}
++f3()
++
++function f4() {
++ var x = true, y = 0;
++ function g() {
++ print(inspect(x+y, "outer local true addition local int"));
++ print(inspect(a+x, "global int addition outer local true"));
++ print(inspect(x*y, "outer local true multiplication by outer local int"));
++ print(inspect(y*d, "outer local int multiplication by global undefined"));
++ }
++ g()
++}
++f4()
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/optimistic_check_type.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,30 @@
++ternary operator: int
++ternary operator: int
++ternary operator: double
++ternary operator: int
++ternary operator: undefined
++ternary operator: boolean
++ternary operator: undefined
++ternary operator: int
++global double toFixed(): object
++global double toPrecision() divided by 1: double
++global double toExponential(): object
++member object: object
++member undefined: undefined
++conditional on array member: double
++conditional on array member: int
++conditional on array member: object
++conditional on array member: int
++outer local variable: int
++global variable: int
++outer local int multiplication by outer local int: int
++global int multiplication by global undefined: double
++local undefined: undefined
++local undefined addition local undefined: double
++local undefined multiplication by undefined: double
++local undefined AND local undefined: undefined
++global true OR local undefined: boolean
++outer local true addition local int: double
++global int addition outer local true: double
++outer local true multiplication by outer local int: double
++outer local int multiplication by global undefined: double
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/optimistic_logical_check_type.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,65 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8036987, 8037572
++ * @summary Implement tests that checks static types in the compiled code
++ * @run
++ */
++
++var inspect = Java.type("jdk.nashorn.test.tools.StaticTypeInspector").inspect
++var a = 3, b = true, c = 0;
++var x = { a: 2, b: undefined, c: true}
++
++// Testing logical operators
++//-- Global variable
++print(inspect("cat" && "dog", "object AND object"))
++print(inspect(b && a, "true AND non-falsey global int"))
++print(inspect(a && b, "non-falsey global int AND true"))
++print(inspect(x && b, "non-falsey object AND true"))
++print(inspect(b && x, "true AND non-falsey object"))
++print(inspect("cat" || "dog", "object OR object"))
++print(inspect(b || a, "true OR non-falsey global int"))
++print(inspect(a || b, "non-falsey global int OR true"))
++print(inspect(x || b, "non-falsey object OR true"))
++print(inspect(b || x, "true OR non-falsey object"))
++print(inspect(!x.c || b, "false OR true"))
++print(inspect(c && b, "falsey global int AND true"))
++print(inspect(c || x.b, "falsey global int OR undefined"))
++print(inspect(!c || x.b, "logical not falsey global int OR undefined"))
++print(inspect(!b || x.b, "false OR undefined"))
++print(inspect(!b || c, "false OR falsey global int"))
++print(inspect(!c || c, "logical not falsey global int OR falsey global int"))
++ //--Local variable
++print(inspect(x.b && a, "local undefined AND non-falsey global int"))
++print(inspect(b && x.b, "true AND local undefined"))
++print(inspect(x.b && x.a, "local undefined AND non-falsey local int"))
++print(inspect(x.b || b, "local undefined OR true"))
++print(inspect(b || x.b, "true OR local undefined"))
++print(inspect(x.a && x.c, "non-falsey local int AND true"))
++print(inspect(x.c && x.a, "true AND non-falsey local int"))
++print(inspect(x.c && !!x.a, "true AND double logical not non-falsey local int "))
++print(inspect(!x.c && x.a, "false AND non-falsey local int"))
++print(inspect(x.a || x.c, "non-falsey local int OR true"))
++print(inspect(!x.c || x.c, "false OR true"))
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/optimistic_logical_check_type.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,28 @@
++object AND object: object
++true AND non-falsey global int: int
++non-falsey global int AND true: boolean
++non-falsey object AND true: boolean
++true AND non-falsey object: object
++object OR object: object
++true OR non-falsey global int: boolean
++non-falsey global int OR true: int
++non-falsey object OR true: object
++true OR non-falsey object: boolean
++false OR true: boolean
++falsey global int AND true: int
++falsey global int OR undefined: undefined
++logical not falsey global int OR undefined: boolean
++false OR undefined: undefined
++false OR falsey global int: int
++logical not falsey global int OR falsey global int: boolean
++local undefined AND non-falsey global int: undefined
++true AND local undefined: undefined
++local undefined AND non-falsey local int: undefined
++local undefined OR true: boolean
++true OR local undefined: boolean
++non-falsey local int AND true: boolean
++true AND non-falsey local int: int
++true AND double logical not non-falsey local int : boolean
++false AND non-falsey local int: boolean
++non-falsey local int OR true: int
++false OR true: boolean
+--- ./nashorn/test/script/basic/options.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/options.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/paramspec.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/paramspec.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/assignmentExpr.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/assignmentExpr.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/binaryExpr.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/binaryExpr.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/breakStat.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/breakStat.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/breakStat.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/breakStat.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -24,10 +24,7 @@
+ "body": [
+ {
+ "type": "LabeledStatement",
+- "label": {
+- "type": "Identifier",
+- "name": "loop"
+- },
++ "label": "loop",
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+@@ -42,10 +39,7 @@
+ "body": [
+ {
+ "type": "BreakStatement",
+- "label": {
+- "type": "Identifier",
+- "name": "loop"
+- }
++ "label": "loop"
+ }
+ ]
+ }
+@@ -60,10 +54,7 @@
+ "body": [
+ {
+ "type": "LabeledStatement",
+- "label": {
+- "type": "Identifier",
+- "name": "loop"
+- },
++ "label": "loop",
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+@@ -77,10 +68,7 @@
+ "body": [
+ {
+ "type": "BreakStatement",
+- "label": {
+- "type": "Identifier",
+- "name": "loop"
+- }
++ "label": "loop"
+ }
+ ]
+ }
+--- ./nashorn/test/script/basic/parser/condExpr.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/condExpr.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/continueStat.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/continueStat.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/continueStat.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/continueStat.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -24,10 +24,7 @@
+ "body": [
+ {
+ "type": "LabeledStatement",
+- "label": {
+- "type": "Identifier",
+- "name": "begin"
+- },
++ "label": "begin",
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+@@ -42,10 +39,7 @@
+ "body": [
+ {
+ "type": "ContinueStatement",
+- "label": {
+- "type": "Identifier",
+- "name": "begin"
+- }
++ "label": "begin"
+ }
+ ]
+ }
+@@ -60,10 +54,7 @@
+ "body": [
+ {
+ "type": "LabeledStatement",
+- "label": {
+- "type": "Identifier",
+- "name": "start"
+- },
++ "label": "start",
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+@@ -77,10 +68,7 @@
+ "body": [
+ {
+ "type": "ContinueStatement",
+- "label": {
+- "type": "Identifier",
+- "name": "start"
+- }
++ "label": "start"
+ }
+ ]
+ }
+--- ./nashorn/test/script/basic/parser/debuggerStat.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/debuggerStat.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/functions.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/functions.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/ifStat.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/ifStat.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/labelledStat.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/labelledStat.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/labelledStat.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/labelledStat.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -3,10 +3,7 @@
+ "body": [
+ {
+ "type": "LabeledStatement",
+- "label": {
+- "type": "Identifier",
+- "name": "begin"
+- },
++ "label": "begin",
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+@@ -20,10 +17,7 @@
+ "body": [
+ {
+ "type": "BreakStatement",
+- "label": {
+- "type": "Identifier",
+- "name": "begin"
+- }
++ "label": "begin"
+ }
+ ]
+ }
+@@ -38,10 +32,7 @@
+ "body": [
+ {
+ "type": "LabeledStatement",
+- "label": {
+- "type": "Identifier",
+- "name": "begin"
+- },
++ "label": "begin",
+ "body": {
+ "type": "BlockStatement",
+ "body": [
+@@ -56,10 +47,7 @@
+ "body": [
+ {
+ "type": "BreakStatement",
+- "label": {
+- "type": "Identifier",
+- "name": "begin"
+- }
++ "label": "begin"
+ }
+ ]
+ }
+--- ./nashorn/test/script/basic/parser/lhsExpr.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/lhsExpr.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/lhsExpr.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/lhsExpr.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -69,10 +69,7 @@
+ "type": "Identifier",
+ "name": "obj"
+ },
+- "property": {
+- "type": "Identifier",
+- "name": "foo"
+- },
++ "property": "foo",
+ "computed": false
+ }
+ }
+@@ -91,16 +88,10 @@
+ "type": "Identifier",
+ "name": "obj"
+ },
+- "property": {
+- "type": "Identifier",
+- "name": "foo"
+- },
++ "property": "foo",
+ "computed": false
+ },
+- "property": {
+- "type": "Identifier",
+- "name": "bar"
+- },
++ "property": "bar",
+ "computed": false
+ }
+ }
+@@ -176,10 +167,7 @@
+ "type": "Identifier",
+ "name": "obj"
+ },
+- "property": {
+- "type": "Identifier",
+- "name": "Type"
+- },
++ "property": "Type",
+ "computed": false
+ },
+ "arguments": []
+@@ -200,10 +188,7 @@
+ "type": "Identifier",
+ "name": "obj"
+ },
+- "property": {
+- "type": "Identifier",
+- "name": "Type"
+- },
++ "property": "Type",
+ "computed": false
+ },
+ "arguments": []
+@@ -224,10 +209,7 @@
+ "type": "Identifier",
+ "name": "obj"
+ },
+- "property": {
+- "type": "Identifier",
+- "name": "Type"
+- },
++ "property": "Type",
+ "computed": false
+ },
+ "arguments": [
+@@ -273,10 +255,7 @@
+ "type": "Identifier",
+ "name": "obj"
+ },
+- "property": {
+- "type": "Identifier",
+- "name": "foo"
+- },
++ "property": "foo",
+ "computed": false
+ },
+ "arguments": []
+@@ -322,10 +301,7 @@
+ "type": "Identifier",
+ "name": "obj"
+ },
+- "property": {
+- "type": "Identifier",
+- "name": "foo"
+- },
++ "property": "foo",
+ "computed": false
+ },
+ "arguments": [
+--- ./nashorn/test/script/basic/parser/loopStat.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/loopStat.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/objectLitExpr.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/objectLitExpr.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/parenExpr.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/parenExpr.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/primaryExpr.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/primaryExpr.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/returnStat.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/returnStat.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/switchStat.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/switchStat.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/throwStat.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/throwStat.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/tryCatchStat.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/tryCatchStat.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/unaryExpr.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/unaryExpr.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/useStrict.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/useStrict.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/util.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/util.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/varDecl.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/varDecl.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/parser/withStat.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/parser/withStat.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/propchange.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/propchange.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -26,7 +26,7 @@
+ *
+ * @test
+ * @run
+- */
++ */
+
+ var obj = { x: 343 };
+
+--- ./nashorn/test/script/basic/propertycheck.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/propertycheck.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/prototype.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/prototype.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,12 +30,12 @@
+
+ function check(url_) {
+ try {
+- load(url_);
++ load(url_);
+ } catch (e) {
+- if (e instanceof ReferenceError && e.toString().indexOf('navigator') != -1) {
+- return;
+- }
+- throw e;
++ if (e instanceof ReferenceError && e.toString().indexOf('navigator') != -1) {
++ return;
++ }
++ throw e;
+ }
+ }
+
+@@ -43,7 +43,7 @@
+ try {
+ try {
+ check(file);
+- } catch (e) {
++ } catch (e) {
+ print(e);
+ }
+ } catch (e) {
+--- ./nashorn/test/script/basic/pushpull.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/pushpull.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/ranges_disabled.js Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,32 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-/**
+- * range analysis test. check that computation return values are correct
+- * both with and without range analysis
+- *
+- * @test
+- * @run
+- */
+-
+-load(__DIR__ + "ranges_payload.js");
+--- ./nashorn/test/script/basic/ranges_disabled.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,4 +0,0 @@
+-289
+-11094405
+-4294967293
+--4722
+--- ./nashorn/test/script/basic/ranges_enabled.js Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,33 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-/**
+- * range analysis test. check that computation return values are correct
+- * both with and without range analysis
+- *
+- * @test
+- * @option --range-analysis
+- * @run
+- */
+-
+-load(__DIR__ + "ranges_payload.js");
+--- ./nashorn/test/script/basic/ranges_enabled.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,4 +0,0 @@
+-289
+-11094405
+-4294967293
+--4722
+--- ./nashorn/test/script/basic/ranges_payload.js Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,74 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-/**
+- * range analysis test. check that computation return values are correct
+- * both with and without range analysis
+- *
+- * @subtest
+- */
+-
+-function f(c) {
+- var v = c & 0xffff;
+- var w = v & 0xfff;
+- var x = v * w;
+- return x;
+-}
+-
+-function g() {
+- var sum = 0;
+- for (var x = 0; x < 4711; x++) {
+- sum += x;
+- }
+- return sum;
+-}
+-
+-function g2() {
+- var sum = 0;
+- //make sure we overflow
+- var displacement = 0x7ffffffe;
+- for (var x = displacement; x < (displacement + 2); x++) {
+- sum += x;
+- }
+- return sum;
+-}
+-
+-//mostly provide code coverage for all the range operations
+-function h() {
+- var sum = 0;
+- sum += 4711;
+- sum &= 0xffff;
+- sum /= 2;
+- sum *= 2;
+- sum -= 4;
+- sum |= 2;
+- sum ^= 17;
+- sum = sum % 10000;
+- sum = -sum;
+- return sum
+-}
+-
+-print(f(17));
+-print(g());
+-print(g2());
+-print(h());
+--- ./nashorn/test/script/basic/regex.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/regex.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,9 +25,9 @@
+ * RegExp test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+-
++
+ var regexp;
+
+ regexp = new RegExp("dog");
+--- ./nashorn/test/script/basic/regexp_flags.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/regexp_flags.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -24,7 +24,7 @@
+ /**
+ * NASHORN-154: Early error reporting.
+ *
+- * Errors in regular expression literals that are not implementation-defined
++ * Errors in regular expression literals that are not implementation-defined
+ * syntax extensions.
+ *
+ * @test
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/relink_index_getter.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * relink_index_getter: after call site was linked for array, make sure it
++ * gets correctly relinked for boolean.
++ *
++ * @test
++ * @run
++ */
++
++var x = [[], false]
++for(var i in x) { print(x[i][0]) }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/relink_index_getter.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,2 @@
++undefined
++undefined
+--- ./nashorn/test/script/basic/run-octane.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/run-octane.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -24,31 +24,10 @@
+ /**
+ * @subtest
+ */
++var dir = typeof(__DIR__) == 'undefined' ? "test/script/basic/" : __DIR__;
++load(dir + "octane-payload.js");
+
+-var tests = [
+- {name:"box2d", files:["box2d.js"], suite:"Box2DBenchmark"},
+- {name:"code-load", files:["code-load.js"], suite:"CodeLoad"},
+- {name:"crypto", files:["crypto.js"], suite:"Crypto"},
+- {name:"deltablue", files:["deltablue.js"], suite:"DeltaBlue"},
+- {name:"earley-boyer", files:["earley-boyer.js"], suite:"EarleyBoyer"},
+- {name:"gbemu", files:["gbemu-part1.js", "gbemu-part2.js"], suite:"GameboyBenchmark"},
+- {name:"mandreel", files:["mandreel.js"], suite:"MandreelBenchmark"},
+- {name:"navier-stokes", files:["navier-stokes.js"], suite:"NavierStokes"},
+- {name:"pdfjs", files:["pdfjs.js"], suite:"PdfJS"},
+- {name:"raytrace", files:["raytrace.js"], suite:"RayTrace"},
+- {name:"regexp", files:["regexp.js"], suite:"RegExpSuite"},
+- {name:"richards", files:["richards.js"], suite:"Richards"},
+- {name:"splay", files:["splay.js"], suite:"Splay"},
+- {name:"typescript", files:["typescript.js", "typescript-input.js", "typescript-compiler.js"], suite:"typescript"}
+- //zlib currently disabled - requires read
+- // {name:"zlib", files:["zlib.js", "zlib-data.js"], suite:"zlib"},
+-];
+-var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__;
+-
+-// TODO: why is this path hard coded when it's defined in project properties?
+-var path = dir + "../external/octane/";
+-
+-var runtime = "";
++var runtime = undefined;
+ var verbose = false;
+
+ var numberOfIterations = 5;
+@@ -64,145 +43,159 @@
+ function load_bench(arg) {
+
+ for (var idx = 0; idx < arg.files.length; idx++) {
+- var f = arg.files[idx];
+- var file = f.split('/');
+- var file_name = path + file[file.length - 1];
+-
+- var compile_and_return = should_compile_only(file_name);
+- if (compile_and_return) {
+- if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them
+- return true;
+- }
+- }
+-
+- print_verbose(arg, "loading '" + arg.name + "' [" + f + "]...");
+- load(file_name);
++ var f = arg.files[idx];
++ var file = f.split('/');
++ var file_name = path + file[file.length - 1];
++
++ var compile_and_return = should_compile_only(file_name);
++ if (compile_and_return) {
++ if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them
++ return true;
++ }
++ }
++
++ print_verbose(arg, "loading '" + arg.name + "' [" + f + "]... " + file_name);
++ load(file_name);
++ }
++
++ if (typeof arg.before !== 'undefined') {
++ arg.before();
+ }
+
+ if (compile_and_return) {
+- print_always(arg, "Compiled OK");
++ print_always(arg, "Compiled OK");
+ }
+ return !compile_and_return;
+
+ }
+
++
+ function run_one_benchmark(arg, iters) {
+
+ if (!load_bench(arg)) {
+- return;
+- }
+-
++ return;
++ }
++
+ var success = true;
+ var current_name;
+-
++
+ if (iters == undefined) {
+- iters = numberOfIterations;
++ iters = numberOfIterations;
+ } else {
+- numberOfIterations = iters;
++ numberOfIterations = iters;
+ }
+-
++
+ var benchmarks = eval(arg.suite + ".benchmarks");
+ var min_score = 1e9;
+ var max_score = 0;
+ var mean_score = 0;
+
+ try {
+- for (var x = 0; x < benchmarks.length ; x++) {
+- //do warmup run
+- //reset random number generator needed as of octane 9 before each run
+- BenchmarkSuite.ResetRNG();
+- benchmarks[x].Setup();
+- }
+- BenchmarkSuite.ResetRNG();
+- print_verbose(arg, "running '" + arg.name + "' for " + iters + " iterations of no less than " + min_time + " seconds (" + runtime + ")");
+-
+- var scores = [];
+-
+- var min_time_ms = min_time * 1000;
+- var len = benchmarks.length;
+-
+- for (var it = 0; it < iters + 1; it++) {
+- //every iteration must take a minimum of 10 secs
+- var ops = 0;
+- var elapsed = 0;
+- var start = new Date;
+- do {
+- for (var i = 0; i < len; i++) {
+- benchmarks[i].run();
+- //important - no timing here like elapsed = new Date() - start, as in the
+- //original harness. This will make timing very non-deterministic.
+- //NOTHING else must live in this loop
+- }
+- ops += len;
+- elapsed = new Date - start;
+- } while (elapsed < min_time * 1000);
+-
+- var score = ops / elapsed * 1000 * 60;
+- scores.push(score);
+- var name = it == 0 ? "warmup" : "iteration " + it;
+- print_verbose(arg, name + " finished " + score.toFixed(0) + " ops/minute");
+- }
++ for (var x = 0; x < benchmarks.length ; x++) {
++ //do warmup run
++ //reset random number generator needed as of octane 9 before each run
++ BenchmarkSuite.ResetRNG();
++ benchmarks[x].Setup();
++ }
++ BenchmarkSuite.ResetRNG();
++ print_verbose(arg, "running '" + arg.name + "' for " + iters + " iterations of no less than " + min_time + " seconds");
+
+- for (var x = 0; x < benchmarks.length ; x++) {
+- benchmarks[x].TearDown();
+- }
++ var scores = [];
+
+- for (var x = 1; x < iters + 1 ; x++) {
+- mean_score += scores[x];
+- min_score = Math.min(min_score, scores[x]);
+- max_score = Math.max(max_score, scores[x]);
+- }
+- mean_score /= iters;
++ var min_time_ms = min_time * 1000;
++ var len = benchmarks.length;
+
++ for (var it = 0; it < iters + 1; it++) {
++ //every iteration must take a minimum of 10 secs
++ var ops = 0;
++ var elapsed = 0;
++ var start = new Date;
++ do {
++ for (var i = 0; i < len; i++) {
++ benchmarks[i].run();
++ //important - no timing here like elapsed = new Date() - start, as in the
++ //original harness. This will make timing very non-deterministic.
++ //NOTHING else must live in this loop
++ }
++ ops += len;
++ elapsed = new Date - start;
++ } while (elapsed < min_time * 1000);
++
++ var score = ops / elapsed * 1000 * 60;
++ scores.push(score);
++ var name = it == 0 ? "warmup" : "iteration " + it;
++ print_verbose(arg, name + " finished " + score.toFixed(0) + " ops/minute");
++
++ // optional per-iteration cleanup hook
++ if (typeof arg.cleanUpIteration == "function") {
++ arg.cleanUpIteration();
++ }
++ }
++
++ for (var x = 0; x < benchmarks.length ; x++) {
++ benchmarks[x].TearDown();
++ }
++
++ for (var x = 1; x < iters + 1 ; x++) {
++ mean_score += scores[x];
++ min_score = Math.min(min_score, scores[x]);
++ max_score = Math.max(max_score, scores[x]);
++ }
++ mean_score /= iters;
+ } catch (e) {
+- print_always("*** Aborted and setting score to zero. Reason: " + e);
+- mean_score = min_score = max_score = 0;
+- scores = [0];
++ print_always(arg, "*** Aborted and setting score to zero. Reason: " + e);
++ if (is_this_nashorn() && e instanceof java.lang.Throwable) {
++ e.printStackTrace();
++ }
++ mean_score = min_score = max_score = 0;
++ scores = [0];
+ }
+
+ var res = mean_score.toFixed(0);
+ if (verbose) {
+- res += " ops/minute (" + min_score.toFixed(0) + "-" + max_score.toFixed(0) + "), warmup=" + scores[0].toFixed(0);
++ res += " ops/minute (" + min_score.toFixed(0) + "-" + max_score.toFixed(0) + "), warmup=" + scores[0].toFixed(0);
+ }
+ print_always(arg, res);
+ }
+
++function runtime_string() {
++ return runtime == undefined ? "" : ("[" + runtime + "] ");
++}
++
+ function print_always(arg, x) {
+- print("[" + arg.name + "] " + x);
++ print(runtime_string() + "[" + arg.name + "] " + x);
+ }
+
+ function print_verbose(arg, x) {
+ if (verbose) {
+- print_always(arg, x)
++ print_always(arg, x)
+ }
+ }
+
+ function run_suite(tests, iters) {
+ for (var idx = 0; idx < tests.length; idx++) {
+- run_one_benchmark(tests[idx], iters);
++ run_one_benchmark(tests[idx], iters);
+ }
+ }
+
+-runtime = "command line";
+-
+ var args = [];
+
+ if (typeof $ARGS !== 'undefined') {
+ args = $ARGS;
+ } else if (typeof arguments !== 'undefined' && arguments.length != 0) {
+ args = arguments;
+-}
++}
+
+ var new_args = [];
+ for (i in args) {
+ if (args[i].toString().indexOf(' ') != -1) {
+- args[i] = args[i].replace(/\/$/, '');
+- var s = args[i].split(' ');
+- for (j in s) {
+- new_args.push(s[j]);
+- }
++ args[i] = args[i].replace(/\/$/, '');
++ var s = args[i].split(' ');
++ for (j in s) {
++ new_args.push(s[j]);
++ }
+ } else {
+- new_args.push(args[i]);
++ new_args.push(args[i]);
+ }
+ }
+
+@@ -214,50 +207,76 @@
+ var iters = undefined;
+ var min_time = 5;
+
+-for (var i = 0; i < args.length; i++) {
++for (var i = 0; i < args.length; i++) {
+ arg = args[i];
+ if (arg == "--iterations") {
+- iters = +args[++i];
++ iters = +args[++i];
++ if (isNaN(iters)) {
++ throw "'--iterations' must be followed by integer";
++ }
+ } else if (arg == "--runtime") {
+- runtime = args[++i];
++ runtime = args[++i];
+ } else if (arg == "--verbose") {
+- verbose = true;
++ verbose = true;
+ } else if (arg == "--min-time") {
+- min_time = +args[++i];
++ min_time = +args[++i];
++ if (isNaN(iters)) {
++ throw "'--min-time' must be followed by integer";
++ }
+ } else if (arg == "") {
+- continue; //skip
++ continue; //skip
+ } else {
+- var found = false;
+- for (j in tests) {
+- if (tests[j].name === arg) {
+- tests_found.push(tests[j]);
+- found = true;
+- break;
+- }
+- }
+- if (!found) {
+- var str = "unknown test name: '" + arg + "' -- valid names are: ";
+- for (j in tests) {
+- if (j != 0) {
+- str += ", ";
+- }
+- str += "'" + tests[j].name + "'";
+- }
+- throw str;
+- }
++ var found = false;
++ for (j in tests) {
++ if (tests[j].name === arg) {
++ tests_found.push(tests[j]);
++ found = true;
++ break;
++ }
++ }
++ if (!found) {
++ var str = "unknown test name: '" + arg + "' -- valid names are: ";
++ for (j in tests) {
++ if (j != 0) {
++ str += ", ";
++ }
++ str += "'" + tests[j].name + "'";
++ }
++ throw str;
++ }
+ }
+ }
+
+-if (tests_found.length == 0) {
++if (tests_found.length == 0) {
+ for (i in tests) {
+- tests_found.push(tests[i]);
++ tests_found.push(tests[i]);
+ }
+-}
++}
+
+-tests_found.sort();
++// returns false for rhino, v8 and all other javascript runtimes, true for Nashorn
++function is_this_nashorn() {
++ return typeof Error.dumpStack == 'function'
++}
++
++if (is_this_nashorn()) {
++ try {
++ read = readFully;
++ } catch (e) {
++ print("ABORTING: Cannot find 'readFully'. You must have scripting enabled to use this test harness. (-scripting)");
++ throw e;
++ }
++}
++
++// run tests in alphabetical order by name
++tests_found.sort(function(a, b) {
++ if (a.name < b.name) {
++ return -1;
++ } else if (a.name > b.name) {
++ return 1;
++ } else {
++ return 0;
++ }
++});
+
+ load(path + 'base.js');
+ run_suite(tests_found, iters);
+-
+-
+-
+--- ./nashorn/test/script/basic/runsunspider-eager.js Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,33 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-/**
+- * runsunspider : runs the sunspider tests and checks for compliance
+- *
+- * @test
+- * @option -timezone=PST
+- * @runif external.sunspider
+- */
+-
+-load(__DIR__ + "runsunspider.js");
+-
+--- ./nashorn/test/script/basic/runsunspider-lazy.js Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,34 +0,0 @@
+-/*
+- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-/**
+- * runsunspider : runs the sunspider tests and checks for compliance
+- *
+- * @test
+- * @option -timezone=PST
+- * @option --lazy-compilation
+- * @runif external.sunspider
+- */
+-
+-load(__DIR__ + "runsunspider.js");
+-
+--- ./nashorn/test/script/basic/runsunspider-lazy.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,1 +0,0 @@
+-Sunspider finished!
+--- ./nashorn/test/script/basic/runsunspider.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/runsunspider.js Wed Feb 04 12:14:47 2015 -0800
+@@ -24,7 +24,9 @@
+ /**
+ * runsunspider : runs the sunspider tests and checks for compliance
+ *
+- * @subtest
++ * @test
++ * @option -timezone=PST
++ * @runif external.sunspider
+ */
+
+ /**
+@@ -37,32 +39,32 @@
+ }
+ }
+
++function pprint(x) {
++ if (verbose_run) {
++ print(x);
++ }
++}
++
+ var runs = 0;
+-var iterations__ = 1;
+ var total_time = 0;
+
+ function runbench(name) {
+ var filename = name.split("/").pop();
+- if (verbose_run) {
+- print("Running " + filename);
+- }
++ pprint("Running (warmup/sanity) " + filename);
+
+ var start = new Date;
+- for (var i = 0; i < iterations__; i++) {
+- load(name);
+- }
++ load(name);
++
+ var stop = new Date - start;
+ total_time += stop;
+
+- if (verbose_run) {
+- print(filename + " done in " + stop + " ms");
+- }
++ pprint(filename + " done in " + stop + " ms");
+ runs++;
+ }
+
+-var m_w = 4711;
+-var m_z = 17;
+-var MAXINT = 0x7fffffff;
++var m_w;
++var m_z;
++var MAXINT;
+
+ //produce deterministic random numbers for test suite
+ function pseudorandom() {
+@@ -71,25 +73,133 @@
+ return (Math.abs((m_z << 16) + m_w) & MAXINT) / MAXINT;
+ }
+
++function initrandom() {
++ m_w = 4711;
++ m_z = 17;
++ MAXINT = 0x7fffffff;
++ Math.random = pseudorandom;
++}
++
++var rtimes = 0;
++var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__;
++var single;
++var verbose_run = false;
++var runall = false;
++
++var args = [];
++if (typeof $ARGS !== 'undefined') {
++ args = $ARGS;
++} else if (typeof arguments !== 'undefined' && arguments.length != 0) {
++ args = arguments;
++}
++
++for (var i = 0; i < args.length; i++) {
++ if (args[i] === '--verbose') {
++ verbose_run = true;
++ } else if (args[i] === '--times') {
++ i++;
++ rtimes = +args[i];
++ } else if (args[i] === '--single') {
++ i++;
++ single = args[i];
++ } else if (args[i] === '--runall') {
++ i++;
++ runall = true;
++ }
++}
++
+ function runsuite(tests) {
+- var changed = false;
+-
++ var changed = false;
++ var res = [];
+ var oldRandom = Math.random;
+- Math.random = pseudorandom;
+
+ try {
+- for (var n = 0; n < tests.length; n++) {
+- path = dir + '../external/sunspider/tests/sunspider-1.0/' + tests[n].name
+- runbench(path);
+- if (typeof tests[n].actual !== 'undefined') {
+- assertEq(tests[n].actual(), tests[n].expected());
++ for (var n = 0; n < tests.length; n++) {
++ try {
++ path = dir + '../external/sunspider/tests/sunspider-1.0.2/' + tests[n].name
++
++ initrandom();
++
++ var dd = new Date;
++
++ runbench(path);
++ if (typeof tests[n].actual !== 'undefined') {
++ assertEq(tests[n].actual(), tests[n].expected());
++ }
++
++ var times = 0;
++ if (typeof tests[n].rerun !== 'undefined' && tests[n].times > 0) {
++ pprint("rerunning " + tests[n].name + " " + tests[n].times + " times...");
++ var to = tests[n].times;
++
++ var elemsPerPercent = to / 100;
++ var po = 0|(to / 10);
++
++ pprint("Doing warmup.");
++ for (times = 0; times < to; times++) {
++ initrandom();
++ tests[n].rerun();
++ }
++
++ pprint("Doing hot runs.");
++ for (times = 0; times < to; times++) {
++ initrandom();
++ tests[n].rerun();
++ if ((times % (po|0)) == 0) {
++ pprint("\t" + times/to * 100 + "%");
++ }
++ }
++ }
++
++ var t = Math.round(((new Date - dd) / (times == 0 ? 1 : times)) * 100 / 100);
++ pprint("time per iteration: " + t + " ms");
++ if (typeof tests[n].actual !== 'undefined') {
++ assertEq(tests[n].actual(), tests[n].expected());
++ }
++ res.push(t);
++
++ pprint("");
++
++ changed = true;
++ } catch(e) {
++ if (runall) {
++ print("FAIL!");
++ } else {
++ throw e;
++ }
+ }
+- changed = true;
+ }
++ } catch (e) {
++ print("FAIL!");
++ throw e;
+ // no scripting or something, silently fail
+ } finally {
++ Math.random = oldRandom;
+ }
+- Math.random = oldRandom;
++
++ for (var n = 0; n < tests.length; n++) {
++
++ var time = "" + res[n];
++ while (time.length < 6) {
++ time = " " + time;
++ }
++ time += " ms";
++ if (res[n] == -1) {
++ time = "<couldn't be rerun>";
++ }
++ var str = tests[n].name;
++ for (var spaces = str.length; spaces < 32; spaces++) {
++ str += " ";
++ }
++ str += " ";
++ str += time;
++
++ if (tests[n].times > 0) {
++ str += " [";
++ str += tests[n].times + " reruns]";
++ }
++ pprint(str);
++ }
+
+ return changed;
+ }
+@@ -106,20 +216,47 @@
+ }
+
+ var tests = [
++
++ { name: 'regexp-dna.js',
++ actual: function() {
++ return dnaOutputString + dnaInput;
++ },
++ expected: function() {
++ return expectedDNAOutputString + expectedDNAInput;
++ },
++ },
++
+ { name: 'string-base64.js',
+ actual: function() {
+ return hash(str);
+ },
+ expected: function() {
+ return 1544571068;
++ },
++ times: rtimes,
++ rerun: function() {
++ toBinaryTable = [
++ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
++ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
++ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
++ 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1,
++ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
++ 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
++ -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
++ 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
++ ];
++ var str = "";
++ for (var i = 0; i < 8192; i++)
++ str += String.fromCharCode((25 * Math.random()) + 97);
++
++ for (var i = 8192; i <= 16384; i *= 2) {
++ var base64;
++ base64 = toBase64(str);
++ var encoded = base64ToString(base64);
++
++ str += str;
+ }
+- },
+- { name: 'string-validate-input.js',
+- actual: function() {
+- return hash(endResult);
+- },
+- expected: function() {
+- return 2016572373;
++ toBinaryTable = null;
+ }
+ },
+ { name: 'date-format-xparb.js',
+@@ -128,7 +265,29 @@
+ },
+ expected: function() {
+ return "2017-09-05Tuesday, September 05, 2017 8:43:48 AM";
++ },
++ times: rtimes,
++ rerun: function() {
++ date = new Date("1/1/2007 1:11:11");
++ for (i = 0; i < 4000; ++i) {
++ var shortFormat = date.dateFormat("Y-m-d");
++ var longFormat = date.dateFormat("l, F d, Y g:i:s A");
++ date.setTime(date.getTime() + 84266956);
+ }
++ }
++
++ },
++ { name: 'string-validate-input.js',
++ actual: function() {
++ return hash(endResult);
++ },
++ expected: function() {
++ return 726038055;
++ },
++ times: rtimes,
++ rerun: function() {
++ doTest();
++ },
+ },
+ { name: '3d-morph.js',
+ actual: function() {
+@@ -137,6 +296,20 @@
+ },
+ expected: function() {
+ return true;
++ },
++ times: rtimes,
++ rerun: function() {
++ a = Array()
++ for (var i=0; i < nx*nz*3; ++i)
++ a[i] = 0
++ for (var i = 0; i < loops; ++i) {
++ morph(a, i/loops)
++ }
++ testOutput = 0;
++ for (var i = 0; i < nx; i++)
++ testOutput += a[3*(i*nx+i)+1];
++ a = null;
++
+ }
+ },
+ { name: 'crypto-aes.js',
+@@ -145,6 +318,12 @@
+ },
+ expected: function() {
+ return decryptedText;
++ },
++ times: rtimes,
++ rerun: function() {
++ cipherText = AESEncryptCtr(plainText, password, 256);
++ decryptedText = AESDecryptCtr(cipherText, password, 256);
++
+ }
+ },
+ { name: 'crypto-md5.js',
+@@ -153,32 +332,56 @@
+ },
+ expected: function() {
+ return "a831e91e0f70eddcb70dc61c6f82f6cd";
++ },
++ times: rtimes,
++ rerun: function() {
++ md5Output = hex_md5(plainText);
+ }
+ },
++
+ { name: 'crypto-sha1.js',
+ actual: function() {
+ return sha1Output;
+ },
+ expected: function() {
+ return "2524d264def74cce2498bf112bedf00e6c0b796d";
++ },
++ times: rtimes,
++ rerun: function() {
++ sha1Output = hex_sha1(plainText);
+ }
+ },
++
+ { name: 'bitops-bitwise-and.js',
+ actual: function() {
+ return result;
+ },
+ expected: function() {
+ return 0;
++ },
++ times: rtimes,
++ rerun: function() {
++ bitwiseAndValue = 4294967296;
++ for (var i = 0; i < 600000; i++) {
++ bitwiseAndValue = bitwiseAndValue & i;
++ }
++ result = bitwiseAndValue;
+ }
+ },
++
+ { name: 'bitops-bits-in-byte.js',
+ actual: function() {
+ return result;
+ },
+ expected: function() {
+ return 358400;
++ },
++ times: rtimes,
++ rerun: function() {
++ result = TimeFunc(bitsinbyte);
+ }
+ },
++
+ { name: 'bitops-nsieve-bits.js',
+ actual: function() {
+ var ret = 0;
+@@ -190,40 +393,101 @@
+ },
+ expected: function() {
+ return -1286749539853;
++ },
++ times: rtimes,
++ rerun: function() {
++ result = sieve();
+ }
+ },
++
+ { name: 'bitops-3bit-bits-in-byte.js',
+ actual: function() {
+ return sum;
+ },
+ expected: function() {
+ return 512000;
++ },
++ times: rtimes,
++ rerun: function() {
++ sum = TimeFunc(fast3bitlookup);
+ }
+ },
++
+ { name: 'access-nbody.js',
+ actual: function() {
+ return ret;
+ },
+ expected: function() {
+ return -1.3524862408537381;
++ },
++ times: rtimes,
++ rerun: function() {
++ var ret = 0;
++ for (var n = 3; n <= 24; n *= 2) {
++ (function(){
++ var bodies = new NBodySystem( Array(
++ Sun(),Jupiter(),Saturn(),Uranus(),Neptune()
++ ));
++ var max = n * 100;
++
++ ret += bodies.energy();
++ for (var i=0; i<max; i++){
++ bodies.advance(0.01);
++ }
++ ret += bodies.energy();
++ })();
++ }
+ }
+ },
++
+ { name: 'access-binary-trees.js',
+ actual: function() {
+ return ret;
+ },
+ expected: function() {
+ return -4;
++ },
++ times: rtimes,
++ rerun: function() {
++ ret = 0;
++
++ for (var n = 4; n <= 7; n += 1) {
++ var minDepth = 4;
++ var maxDepth = Math.max(minDepth + 2, n);
++ var stretchDepth = maxDepth + 1;
++
++ var check = bottomUpTree(0,stretchDepth).itemCheck();
++
++ var longLivedTree = bottomUpTree(0,maxDepth);
++ for (var depth=minDepth; depth<=maxDepth; depth+=2){
++ var iterations = 1 << (maxDepth - depth + minDepth);
++
++ check = 0;
++ for (var i=1; i<=iterations; i++){
++ check += bottomUpTree(i,depth).itemCheck();
++ check += bottomUpTree(-i,depth).itemCheck();
++ }
++ }
++
++ ret += longLivedTree.itemCheck();
++ }
+ }
+ },
++
+ { name: 'access-fannkuch.js',
+ actual: function() {
+ return ret;
+ },
+ expected: function() {
+ return 22;
++ },
++ times: rtimes,
++ rerun: function() {
++ n = 8;
++ ret = fannkuch(n);
+ }
+ },
++
+ { name: 'math-spectral-norm.js',
+ actual: function() {
+ var ret = '';
+@@ -234,32 +498,43 @@
+ },
+ expected: function() {
+ return "1.2657786149754053,1.2727355112619148,1.273989979775574,1.274190125290389,";
++ },
++ times: rtimes,
++ rerun: function() {
++ total = 0;
++ for (var i = 6; i <= 48; i *= 2) {
++ total += spectralnorm(i);
++ }
+ }
+ },
++
+ { name: '3d-raytrace.js',
+ actual: function() {
+ return hash(testOutput);
+ },
+ expected: function() {
+ return 230692593;
++ },
++ times: rtimes,
++ rerun: function() {
++ testOutput = arrayToCanvasCommands(raytraceScene());
+ }
+ },
+- { name: 'regexp-dna.js',
+- actual: function() {
+- return dnaOutputString;
+- },
+- expected: function() {
+- return "agggtaaa|tttaccct 0\n[cgt]gggtaaa|tttaccc[acg] 9\na[act]ggtaaa|tttacc[agt]t 27\nag[act]gtaaa|tttac[agt]ct 24\nagg[act]taaa|ttta[agt]cct 30\naggg[acg]aaa|ttt[cgt]ccct 9\nagggt[cgt]aa|tt[acg]accct 12\nagggta[cgt]a|t[acg]taccct 9\nagggtaa[cgt]|[acg]ttaccct 15\n";
+- }
+- },
++
+ { name: 'math-cordic.js',
+ actual: function() {
+ return total;
+ },
+ expected: function() {
+ return 10362.570468755888;
++ },
++ times: rtimes,
++ rerun: function() {
++ total = 0;
++ cordic(25000);
+ }
+ },
++
+ { name: 'controlflow-recursive.js',
+ actual: function() {
+ var ret = 0;
+@@ -272,16 +547,36 @@
+ },
+ expected: function() {
+ return 57775;
++ },
++ times: rtimes,
++ rerun: function() {
++ result = 0;
++ for (var i = 3; i <= 5; i++) {
++ result += ack(3,i);
++ result += fib(17.0+i);
++ result += tak(3*i+3,2*i+2,i+1);
++ }
+ }
+ },
++
+ { name: 'date-format-tofte.js',
+ actual: function() {
+ return shortFormat + longFormat;
+ },
+ expected: function() {
+ return "2008-05-01Thursday, May 01, 2008 6:31:22 PM";
++ },
++ times: rtimes,
++ rerun: function() {
++ date = new Date("1/1/2007 1:11:11");
++ for (i = 0; i < 500; ++i) {
++ var shortFormat = date.formatDate("Y-m-d");
++ var longFormat = date.formatDate("l, F d, Y g:i:s A");
++ date.setTime(date.getTime() + 84266956);
++ }
+ }
+ },
++
+ { name: 'string-tagcloud.js',
+ actual: function() {
+ // The result string embeds floating-point numbers, which can vary a bit on different platforms,
+@@ -291,8 +586,71 @@
+ },
+ expected: function() {
+ return 295906;
++ },
++ times: rtimes,
++ rerun: function() {
++ tagInfo = tagInfoJSON.parseJSON(function(a, b) { if (a == "popularity") { return Math.log(b) / log2; } else {return b; } });
++ tagcloud = makeTagCloud(tagInfo);
+ }
+ },
++
++ { name: 'math-partial-sums.js',
++ actual: function() {
++ return total;
++ },
++ expected: function() {
++ return 60.08994194659945;
++ },
++ times: rtimes,
++ rerun: function() {
++ total = 0;
++ for (var i = 1024; i <= 16384; i *= 2) {
++ total += partial(i);
++ }
++ }
++ },
++
++ { name: 'access-nsieve.js',
++ actual: function() {
++ return result;
++ },
++ expected: function() {
++ return 14302;
++ },
++ times: rtimes,
++ rerun: function() {
++ result = sieve();
++ }
++ },
++
++ { name: '3d-cube.js',
++ times: rtimes,
++ rerun: function() {
++ Q = new Array();
++ MTrans = new Array(); // transformation matrix
++ MQube = new Array(); // position information of qube
++ I = new Array(); // entity matrix
++ Origin = new Object();
++ Testing = new Object();
++ for ( var i = 20; i <= 160; i *= 2 ) {
++ Init(i);
++ }
++ }
++ },
++
++ //TODO no easy way to sanity check result
++ { name: 'string-fasta.js',
++ times: rtimes,
++ rerun: function() {
++ ret = 0;
++ count = 7;
++ fastaRepeat(2*count*100000, ALU);
++ fastaRandom(3*count*1000, IUB);
++ fastaRandom(5*count*1000, HomoSap);
++ }
++ },
++
++ //TODO no easy way to sanity check result
+ { name: 'string-unpack-code.js',
+ actual: function() {
+ return decompressedMochiKit.length == 106415 &&
+@@ -301,43 +659,32 @@
+ decompressedMochiKit[82556] == '>';
+ },
+ expected: function() {
+- return true;
+- }
++ return true;
++ },
+ },
+- //TODO no easy way to sanity check result
+- { name: 'string-fasta.js' },
+- //TODO no easy way to sanity check result
+- { name: 'math-partial-sums.js' },
+- //TODO no easy way to sanity check result
+- { name: 'access-nsieve.js' },
+- //TODO no easy way to sanity check result
+- { name: '3d-cube.js' },
++
+ ];
+
++tests.sort(function(a,b) { return a.name.localeCompare(b.name); });
++if (typeof single !== 'undefined') {
++ for (i in tests) {
++ if (tests[i].name === single) {
++ singleTest = tests[i];
++ tests = [singleTest];
++ break;
++ }
++ }
++ if (tests.length != 1) {
++ throw "unknown single test '" + single + "'";
++ }
++}
++
++
+ // handle the case this script may be run by a JS engine that doesn't
+ // support __DIR__ global variable.
+-var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__;
+-
+-var verbose_run = false;
+-
+-var args = [];
+-if (typeof $ARGS !== 'undefined') {
+- args = $ARGS;
+-} else if (typeof arguments !== 'undefined' && arguments.length != 0) {
+- args = arguments;
+-}
+-
+-for (i in args) {
+- if (args[i] === '--verbose') {
+- verbose_run = true;
+- break;
+- }
+-}
+
+ runsuite(tests);
+
+-if (verbose_run) {
+- print('\n' + runs + "/" + tests.length + " tests were successfully run in " + total_time + " ms ");
+-}
++pprint('\n' + runs + "/" + tests.length + " tests were successfully run in " + total_time + " ms ");
+
+ print("Sunspider finished!");
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/runsunspider.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++Sunspider finished!
+--- ./nashorn/test/script/basic/samfunc.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/samfunc.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -34,7 +34,7 @@
+
+ var t1 = new java.lang.Thread(function() {
+ print("thread t1.run");
+-});
++});
+
+ // make sure that we can pass interface implementation as well.
+ var t2 = new java.lang.Thread(new java.lang.Runnable() {
+--- ./nashorn/test/script/basic/scripting.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/scripting.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/scripting.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/scripting.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -22,21 +22,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/sealfreeze.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/sealfreeze.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/setlength.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/setlength.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -27,7 +27,7 @@
+ * @test
+ * @run
+ */
+-
++
+ var a = ["a", "b", "c", "d", "e"];
+ print(a.length);
+ print(a);
+--- ./nashorn/test/script/basic/splitter.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/splitter.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,7 +30,5 @@
+ * @fork
+ */
+
+-load(__DIR__ + 'prototype.js');
+-load(__DIR__ + 'yui.js');
+ load(__DIR__ + 'NASHORN-689.js');
+ load(__DIR__ + 'NASHORN-58.js');
+--- ./nashorn/test/script/basic/splitter.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/splitter.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -1,6 +1,3 @@
+-parsed and compiled ok prototype.js
+-parsed and compiled ok yui-min.js
+-parsed and compiled ok yui.js
+ a=10
+ a=9
+ a=8
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/splitter_prototype.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test various scripts with low splitter threshold
++ *
++ * @test
++ * @option -Dnashorn.compiler.splitter.threshold=200
++ * @runif external.prototype
++ * @fork
++ */
++
++load(__DIR__ + 'prototype.js');
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/splitter_prototype.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++parsed and compiled ok prototype.js
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/splitter_yui.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test various scripts with low splitter threshold
++ *
++ * @test
++ * @option -Dnashorn.compiler.splitter.threshold=200
++ * @runif external.yui
++ * @fork
++ */
++
++load(__DIR__ + 'yui.js');
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/splitter_yui.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,2 @@
++parsed and compiled ok yui-min.js
++parsed and compiled ok yui.js
+--- ./nashorn/test/script/basic/stdin.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/stdin.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/strings.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/strings.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/throws.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/throws.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/tosource.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/tosource.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/tostring.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/tostring.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/try.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/try.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,12 +25,12 @@
+ * Try throw test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ function A() {
+ print("before try");
+-
++
+ try {
+ print("before throw");
+ throw "a string";
+@@ -41,7 +41,7 @@
+ } finally {
+ print("finally");
+ }
+-
++
+ return "incorrect";
+ }
+
+--- ./nashorn/test/script/basic/try2.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/try2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,21 +25,21 @@
+ * Try throw test - nest finally
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ function f() {
+ print("a");
+ try {
+- print("b");
++ print("b");
+ } finally {
+- print("c");
+- try {
+- print("d");
+- } finally {
+- print("e");
+- }
+- print("f");
++ print("c");
++ try {
++ print("d");
++ } finally {
++ print("e");
++ }
++ print("f");
+ }
+ print("g");
+ }
+--- ./nashorn/test/script/basic/trybreakcont.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/trybreakcont.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/trycatch.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/trycatch.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * try catch test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ var actual = '';
+@@ -35,13 +35,13 @@
+
+ function test() {
+ expect = true;
+-
++
+ try {
+ actual = true;
+ }
+ catch(ex) {
+ actual = ex + '';
+ }
+-
++
+ print(actual);
+ }
+--- ./nashorn/test/script/basic/trycatchfor.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/trycatchfor.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,7 +30,7 @@
+
+ try {
+ for(var i =0; i < 10; i++) {
+- }
++ }
+ } catch (e) {
+ }
+
+--- ./nashorn/test/script/basic/tryfinallyreturn.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/tryfinallyreturn.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/tryforbreak.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/tryforbreak.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -31,8 +31,8 @@
+ try {
+ for(i = 0; i < 3; i++) {
+ break;
+- };
+-} catch (e) {
++ };
++} catch (e) {
+ }
+
+ print("done");
+--- ./nashorn/test/script/basic/typechange.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/typechange.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * This test crashes with VerifyError (bad type on stack).
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/typecoerce.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/typecoerce.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -24,9 +24,9 @@
+ /**
+ * There was a bug in the old Lower that didn't fully propagate type information
+ * by way of assignment. 'q' in the example below would have finished a double
+- * even though it can get an object value through the assignment 'q = l'
+- *
+- * Furthermore, this caused type coercion to be done at q = l, and not a q = q * 2,
++ * even though it can get an object value through the assignment 'q = l'
++ *
++ * Furthermore, this caused type coercion to be done at q = l, and not a q = q * 2,
+ * which is a bug. This test ensures it happens in the correct order
+ *
+ * @test
+@@ -42,11 +42,11 @@
+ var l = 1.2; //number
+ var q = 2.3; //number
+ for (var i = 0; i < 2; i++) {
+- q = l; // q = toNumber(l), no coercion here
+- print("assignment done");
+- q = q * 2; // q = q * 2, coercion here
+- print("multiplication done");
+- l = createObject();
++ q = l; // q = toNumber(l), no coercion here
++ print("assignment done");
++ q = q * 2; // q = q * 2, coercion here
++ print("multiplication done");
++ l = createObject();
+ }
+ }
+
+--- ./nashorn/test/script/basic/typedarrays.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/typedarrays.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,20 +25,20 @@
+ * typedarray test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+
+ var typeDefinitions = [
+-Int8Array,
+-Uint8Array,
+-Uint8ClampedArray,
+-Int16Array,
+-Uint16Array,
+-Int32Array,
+-Uint32Array,
+-Float32Array,
+-Float64Array,
++Int8Array,
++Uint8Array,
++Uint8ClampedArray,
++Int16Array,
++Uint16Array,
++Int32Array,
++Uint32Array,
++Float32Array,
++Float64Array,
+ ];
+
+ var mem1 = new ArrayBuffer(1024);
+@@ -55,17 +55,17 @@
+ typeDefinitions.forEach(function(arrayDef) {
+ var p = arrayDef.prototype;
+ var sub = [];
+- sub.push(new arrayDef(mem1, arrayDef.BYTES_PER_ELEMENT, 3));
++ sub.push(new arrayDef(mem1, arrayDef.BYTES_PER_ELEMENT, 3));
+ sub.push(new arrayDef(size));
+ sub.push(new arrayDef(arr));
+ //push the instances, they will be reused to do instance based construction
+ partial.push({
+- instances:sub,
++ instances:sub,
+ type:arrayDef
+ });
+-
++
+ all.concat(all, sub);
+-
++
+ });
+
+ partial.forEach(function(inst) {
+@@ -83,11 +83,11 @@
+ var arr = Object.getOwnPropertyNames(instance);
+ arr.forEach(function(p) {
+ var val = instance[p];
+- if(!isNaN(p)){
++ if(!isNaN(p)) {
+ val[p] = 99;
+- }
++ }
+ });
+-
++
+ instance.set(instance, 0);
+ instance.set(instance);
+ instance.set(arr2);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/typedarrays2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,56 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Typed array test 2
++ *
++ * @test
++ * @run
++ */
++
++var b = new ArrayBuffer(8);
++
++var v1 = new Int32Array(b);
++var v2 = new Uint8Array(b, 2);
++var v3 = new Int16Array(b, 2, 2);
++
++v3[1000] = 17;
++v3.apa = 17;
++print(v3[1000]);
++var arr = [1,2,3];
++arr.gegg = 17;
++print(arr.gegg);
++var v4 = new Int32Array(arr);
++print(v4.gegg);
++
++v2[0] = 0xff;
++v2[1] = 0xff;
++if (v2[1] != 0xff) {
++ print("Error 1: " + v2[1]);
++}
++if (v3[0] != -1) {
++ print("Error 2: " + v3[0]);
++}
++
++print("Done");
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/basic/typedarrays2.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,4 @@
++undefined
++17
++undefined
++Done
+--- ./nashorn/test/script/basic/typeof.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/typeof.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * Typeof test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ var x = { a: 1, b: "string", c: [1, 2, 3], d: function() {} };
+--- ./nashorn/test/script/basic/typeof2.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/typeof2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/undefined.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/undefined.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/underscore.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/underscore.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * NASHORN-466 : corpus parse test for underscore
+- *
++ *
+ * @test
+ * @runif external.underscore
+ */
+--- ./nashorn/test/script/basic/varargs.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/varargs.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * Var args test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+ function varFunc(a, b, c) {
+ print(a, b, c);
+--- ./nashorn/test/script/basic/void.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/void.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/with.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/with.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * With test.
+ *
+ * @test
+- * @run
++ * @run
+ */
+
+ var x = {a: 10, b: 20, c: 30};
+@@ -38,12 +38,12 @@
+ with (x) {
+ print(b);
+ print(x.b);
+-
++
+ b = false;
+-
++
+ print(b);
+ print(x.b);
+-
++
+ y = 200;
+ }
+
+@@ -52,10 +52,10 @@
+
+ for (i in x) print(i, x[i]);
+
+-var obj = {
++var obj = {
+ __noSuchProperty__: function(name) {
+ return name.toUpperCase();
+- }
++ }
+ };
+
+ with(obj) {
+--- ./nashorn/test/script/basic/withprimitive.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/withprimitive.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -24,7 +24,7 @@
+ /**
+ * Using "with" statement with primitive typed value as scope object.
+ * Results in VerifyError: Bad type on operand stack.
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/basic/writable_relink.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/writable_relink.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/basic/xorassign.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/xorassign.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * The following crashes with VerifyError.
++ * The following crashes with VerifyError.
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/basic/yui.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/basic/yui.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,23 +23,23 @@
+
+ /**
+ * NASHORN-469 : corpus parse test for yahoo ui library / yahoo ui library min
+- *
++ *
+ * @test
+ * @runif external.yui
+ */
+
+ var names = [ "yui-min.js", "yui.js" ];
+
+-for each (name in names) {
++for each (name in names) {
+ try {
+- try {
++ try {
+ var file = __DIR__ + "../external/yui/" + name;
+- load(__DIR__ + "../external/yui/" + name);
+- } catch (e) {
+- print(e);
+- }
++ load(__DIR__ + "../external/yui/" + name);
+ } catch (e) {
+- print("error: " + e);
++ print(e);
++ }
++ } catch (e) {
++ print("error: " + e);
+ }
+ print("parsed and compiled ok " + name);
+ }
+--- ./nashorn/test/script/currently-failing/JDK-8006191.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/currently-failing/JDK-8006191.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+- *
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+- *
++ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+- *
++ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+- *
++ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+- *
++ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+@@ -28,14 +28,14 @@
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+-
++
+ /**
+ * JDK-8006191 - `cmd` -> exec("cmd") in script mode
+ *
+ * @test
+ * @option -scripting
+ * @argument ArgumentFromCommandLine
+- * @run
++ * @run
+ */
+
+ #!/usr/bin/jjs
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/currently-failing/JDK-8010697.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8010697: DeletedArrayFilter seems to leak memory
++ *
++ * @test
++ * @run
++ */
++
++var N = 1000;
++
++var array = new Array(N);
++var WeakReferenceArray = Java.type("java.lang.ref.WeakReference[]");
++var refArray = new WeakReferenceArray(N);
++
++for (var i = 0; i < N; i ++) {
++ var object = new java.awt.Color(0,0,0);//lang.Object();
++ array[i] = object;
++ refArray[i] = new java.lang.ref.WeakReference(object);
++}
++
++object = null;
++
++for (var i = 0; i < N; i ++) {
++ delete array[i];
++}
++
++java.lang.System.gc();
++java.lang.System.gc();
++java.lang.System.gc();
++
++for (var i = 0; i < N; i ++) {
++ if (refArray[i].get() != null) {
++ print("Reference found at " + i + " " + refArray + " " + refArray[i].get());
++ }
++}
++
++print("All references gone");
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/currently-failing/JDK-8010697.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++All references gone
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/currently-failing/apply_to_call_bench.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,93 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * sanity check that apply to call specialization is faster than apply.
++ *
++ * @test
++ * @run
++ */
++
++var Class = {
++ create: function() {
++ return function() { //vararg
++ this.initialize.apply(this, arguments);
++ }
++ }
++};
++
++Color = Class.create();
++Color.prototype = {
++ red: 0, green: 0, blue: 0,
++ initialize: function(r,g,b) {
++ this.red = r;
++ this.green = g;
++ this.blue = b;
++ }
++};
++
++var time1 = 0;
++var time2 = 0;
++
++function set_time1(t) {
++ time1 = t;
++}
++
++function set_time2(t) {
++ time2 = t;
++}
++
++function bench(x, set_time) {
++ var d = new Date;
++ var colors = new Array(16);
++ for (var i=0;i<1e8;i++) {
++ colors[i & 0xf] = new Color(1,2,3);
++ }
++ var t = new Date - d;
++ set_time(t);
++ return colors;
++}
++
++//warmup
++print("Running warmup");
++bench(17, set_time1);
++
++print("Running sharp run");
++bench(17, set_time1);
++
++print("Swapping out call");
++Function.prototype.call = function() {
++ throw "This should not happen, apply should be called instead";
++};
++
++print("Rerunning invalidated");
++bench(17, set_time2);
++
++print("All done!");
++
++if (time1 > time2) {
++ print("ERROR: time1 > time2 (" + time1 + " > " + time2 + ")");
++} else {
++ print("Times OK");
++}
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/currently-failing/apply_to_call_bench.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,6 @@
++Running warmup
++Running sharp run
++Swapping out call
++Rerunning invalidated
++All done!
++Times OK
+--- ./nashorn/test/script/currently-failing/clone_ir.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/currently-failing/clone_ir.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -41,12 +41,12 @@
+ var System = Java.type("java.lang.System");
+
+ var toArrayMethod = ASTWriter.class.getMethod("toArray");
+-var parseMethod = Parser.class.getMethod("parse");
++var parseMethod = Parser.class.getMethod("parse");
+
+ function toString(obj) {
+ var output = "{ ";
+ for (property in obj) {
+- output += property + ': ' + obj[property]+'; ';
++ output += property + ': ' + obj[property]+'; ';
+ }
+ return output + '}'
+ }
+@@ -54,11 +54,11 @@
+ function flatten(func) {
+ var writer = new ASTWriter(func);
+ var funcList = toArrayMethod.invoke(writer);
+-
++
+ var res = [];
+ for each (x in funcList) {
+- res.push({ name: x.getClass().getName(), id: System.identityHashCode(x) });
+- }
++ res.push({ name: x.getClass().getName(), id: System.identityHashCode(x) });
++ }
+ return res;
+ }
+
+@@ -80,20 +80,20 @@
+ print(f2.map(toString));
+
+ if (f1.length != f2.length) {
+- print("length difference between original and clone " + f1.length + " != " + f2.length);
+- return false;
++ print("length difference between original and clone " + f1.length + " != " + f2.length);
++ return false;
+ }
+
+ for (var i = 0; i < f1.length; i++) {
+- if (f1[i].name !== f2[i].name) {
+- print("name conflict at " + i + " " + f1[i].name + " != " + f2[i].name);
+- return false;
+- } else if (f1[i].id === f2[i].id) {
+- print("id problem at " + i + " " + toString(f1[i]) + " was not deep copied to " + toString(f2[i]) + " became " + f1[i].id + " != " + f2[i].id);
+- return false;
+- }
++ if (f1[i].name !== f2[i].name) {
++ print("name conflict at " + i + " " + f1[i].name + " != " + f2[i].name);
++ return false;
++ } else if (f1[i].id === f2[i].id) {
++ print("id problem at " + i + " " + toString(f1[i]) + " was not deep copied to " + toString(f2[i]) + " became " + f1[i].id + " != " + f2[i].id);
++ return false;
+ }
+-
++ }
++
+ return true;
+ }
+
+--- ./nashorn/test/script/currently-failing/gettersetter.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/currently-failing/gettersetter.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/currently-failing/logcoverage.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/currently-failing/logcoverage.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * mh_coverage.js
+- * Screen scrape various logs to ensure that we cover enough functionality,
++ * Screen scrape various logs to ensure that we cover enough functionality,
+ * e.g. method handle instrumentation
+ *
+ * @test
+@@ -44,25 +44,25 @@
+ var fac = new NashornScriptEngineFactory();
+ // get current System.err
+ var oldErr = System.err;
+- var oldOut = System.out;
++ var oldOut = System.out;
+ var baosErr = new ByteArrayOutputStream();
+ var newErr = new PrintStream(baosErr);
+ var baosOut = new ByteArrayOutputStream();
+- var newOut = new PrintStream(baosOut);
++ var newOut = new PrintStream(baosOut);
+ try {
+ // set new standard err
+ System.setErr(newErr);
+ System.setOut(newOut);
+ var engine = fac.getScriptEngine(Java.to(opts, "java.lang.String[]"));
+- var reader = new java.io.FileReader(name);
++ var reader = new java.io.FileReader(name);
+ engine.eval(reader);
+ newErr.flush();
+- newOut.flush();
++ newOut.flush();
+ return new java.lang.String(baosErr.toByteArray());
+ } finally {
+ // restore System.err to old value
+ System.setErr(oldErr);
+- System.setOut(oldOut);
++ System.setOut(oldOut);
+ }
+ }
+ }
+@@ -70,27 +70,27 @@
+ var str;
+
+ var methodsCalled = [
+- 'asCollector',
+- 'asType',
+- 'bindTo',
+- 'dropArguments',
+- 'explicitCastArguments',
+- 'filterArguments',
+- 'filterReturnValue',
+- 'findStatic',
+- 'findVirtual',
+- 'foldArguments',
+- 'getter',
+- 'guardWithTest',
+- 'insertArguments',
+- 'methodType',
++ 'asCollector',
++ 'asType',
++ 'bindTo',
++ 'dropArguments',
++ 'explicitCastArguments',
++ 'filterArguments',
++ 'filterReturnValue',
++ 'findStatic',
++ 'findVirtual',
++ 'foldArguments',
++ 'getter',
++ 'guardWithTest',
++ 'insertArguments',
++ 'methodType',
+ 'setter'
+ ];
+
+ function check(str, strs) {
+ for each (s in strs) {
+ if (str.indexOf(s) !== -1) {
+- continue;
++ continue;
+ }
+ print(s + " not found");
+ return;
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/currently-failing/optimistic_check_type_cases.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8035652,8037858
++ * @summary Implement tests that checks static types in the compiled code
++ * @run
++ */
++
++var inspect = Java.type("jdk.nashorn.test.tools.StaticTypeInspector").inspect
++var a = b = c = 3;
++
++//JDK-8035652
++print(inspect(a/a, "global int division by global int"))
++print(inspect(a%a, "global int modulus by global int"))
++print(inspect(b+=b, "global int addition assignment global int"))
++//JDK-8037858
++print(inspect(b-=b, "global int substraction assignment global int"))
++print(inspect(c*=a, "global int multiplication assignment global int"))
++print(inspect(a/=a, "global int division assignment global int"))
++print(inspect(c%=c, "global int modulo assignment global int"))
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/currently-failing/optimistic_check_type_cases.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,7 @@
++global int division by global int: int
++global int modulus by global int: int
++global int addition assignment global int: int
++global int substraction assignment global int: int
++global int multiplication assignment global int: int
++global int division assignment global int: int
++global int modulo assignment global int: int
+\ No newline at end of file
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/currently-failing/property_delete.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @option -Dnashorn.debug=true
++ * @fork
++ */
++
++load(__DIR__ + "maputil.js");
++
++function Foo() {
++ this.x = 33;
++}
++
++var obj1 = new Foo();
++var obj2 = new Foo();
++
++assertSameMap(obj1, obj2);
++
++// property deletion at same callsite
++function deleteX(obj) {
++ delete obj.x;
++}
++deleteX(obj1);
++deleteX(obj2);
++
++assertSameMap(obj1, obj2);
+--- ./nashorn/test/script/error/JDK-8008814-1.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/JDK-8008814-1.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/JDK-8008814-2.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/JDK-8008814-2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/JDK-8016522.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/JDK-8016522.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/JDK-8020437-2.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/JDK-8020437-2.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/JDK-8020437.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/JDK-8020437.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/JDK-8026039.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/JDK-8026039.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,4 +29,4 @@
+
+ function public() {"use strict"}
+
+-function f(public) {"use strict"}
++function f(public) {"use strict"}
+--- ./nashorn/test/script/error/JDK-8026039.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/JDK-8026039.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -2,7 +2,7 @@
+ function public() {"use strict"}
+ ^
+ test/script/error/JDK-8026039.js:32:11 Expected ident but found public
+-function f(public) {"use strict"}
++function f(public) {"use strict"}
+ ^
+ test/script/error/JDK-8026039.js:33:0 Expected } but found eof
+
+--- ./nashorn/test/script/error/JDK-8027933.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/JDK-8027933.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/JDK-8039047.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/JDK-8039047.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/NASHORN-154/function_mult_params_in_strict.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/NASHORN-154/function_mult_params_in_strict.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -24,8 +24,8 @@
+ /**
+ * Early error reporting.
+ *
+- * The occurrence of an Identifier value appearing more than once within a
+- * FormalParameterList of an individual strict mode FunctionDeclaration or
++ * The occurrence of an Identifier value appearing more than once within a
++ * FormalParameterList of an individual strict mode FunctionDeclaration or
+ * FunctionExpression
+ *
+ * @test/compile-error
+--- ./nashorn/test/script/error/NASHORN-154/improper_return_break_continue.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/NASHORN-154/improper_return_break_continue.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/NASHORN-154/invalid_lvalue.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/NASHORN-154/invalid_lvalue.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -24,8 +24,8 @@
+ /**
+ * Early error reporting.
+ *
+- * Attempts to call PutValue on any value for which an early determination can
+- * be made that the value is not a Reference (for example, executing the
++ * Attempts to call PutValue on any value for which an early determination can
++ * be made that the value is not a Reference (for example, executing the
+ * assignment statement 3=4).
+ *
+ * @test/compile-error
+--- ./nashorn/test/script/error/NASHORN-154/literal_data_and_accessor.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/NASHORN-154/literal_data_and_accessor.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/NASHORN-154/literal_mult_getters.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/NASHORN-154/literal_mult_getters.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -24,8 +24,8 @@
+ /**
+ * Early error reporting.
+ *
+- * Attempts to define an ObjectLiteral that has multiple get property
+- * assignments with the same name or multiple set property assignments with
++ * Attempts to define an ObjectLiteral that has multiple get property
++ * assignments with the same name or multiple set property assignments with
+ * the same name.
+ *
+ * @test/compile-error
+--- ./nashorn/test/script/error/NASHORN-154/literal_mult_prop_in_strict.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/NASHORN-154/literal_mult_prop_in_strict.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -24,7 +24,7 @@
+ /**
+ * Early error reporting.
+ *
+- * Attempts in strict mode code to define an ObjectLiteral that has multiple
++ * Attempts in strict mode code to define an ObjectLiteral that has multiple
+ * data property assignments with the same name.
+ *
+ * @test/compile-error
+--- ./nashorn/test/script/error/NASHORN-154/with_in_strict.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/NASHORN-154/with_in_strict.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/NASHORN-214.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/NASHORN-214.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/NASHORN-35.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/NASHORN-35.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/NASHORN-39.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/NASHORN-39.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -29,5 +29,5 @@
+
+ // line terminator here should result in compiler error.
+
+-throw
++throw
+ 1;
+--- ./nashorn/test/script/error/NASHORN-568.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/NASHORN-568.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/NASHORN-57.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/NASHORN-57.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/NASHORN-668.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/NASHORN-668.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/quotemissing.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/quotemissing.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/error/strictmode.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/error/strictmode.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/jfx/kaleidoscope.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/jfx/kaleidoscope.js Wed Feb 04 12:14:47 2015 -0800
+@@ -52,99 +52,99 @@
+ var isFrameRendered = false;
+
+ function renderFrame() {
+- if (!isFrameRendered) {
++ if (!isFrameRendered) {
+ a=0.2*angle;
+- b=0.7*angle;
+- r=0;
+- fade=32;
+- for(var i=0;i<6;i++)
+- {
+- c[i]=1.0/(i+1)/2;
+- d[i]=1.0/(i+1)/2;
+- }
+- radius=Math.round((WIDTH+HEIGHT)/8);
+- e=radius*0.2;
+- p_x=Math.round(WIDTH/2);
+- p_y=Math.round(HEIGHT/2);
+- x=(radius*c[0])*Math.cos(a*d[1])+(radius*c[2])*Math.sin(a*d[3])+(radius*c[4])*Math.sin(a*d[5]);
+- y=(radius*c[5])*Math.sin(a*d[4])+(radius*c[3])*Math.cos(a*d[2])+(radius*c[1])*Math.cos(a*d[0]);
++ b=0.7*angle;
++ r=0;
++ fade=32;
++ for(var i=0;i<6;i++)
++ {
++ c[i]=1.0/(i+1)/2;
++ d[i]=1.0/(i+1)/2;
++ }
++ radius=Math.round((WIDTH+HEIGHT)/8);
++ e=radius*0.2;
++ p_x=Math.round(WIDTH/2);
++ p_y=Math.round(HEIGHT/2);
++ x=(radius*c[0])*Math.cos(a*d[1])+(radius*c[2])*Math.sin(a*d[3])+(radius*c[4])*Math.sin(a*d[5]);
++ y=(radius*c[5])*Math.sin(a*d[4])+(radius*c[3])*Math.cos(a*d[2])+(radius*c[1])*Math.cos(a*d[0]);
+ isFrameRendered = true;
+ }
+ anim();
+ }
+
+ function anim() {
+- var a1=Math.cos(a*2);
+- var a2=Math.cos(a*4);
+- var a3=Math.cos(a);
+- var a4=Math.sin(a);
+- if(b>limit1&&b<limit2) {
+- r+=radius*0.02*a1;
+- prv_x=x;
+- prv_y=y;
+- x=prv_x2+r*a3;
+- y=prv_y2+r*a4;
+- } else {
+- prv_x=x;
+- prv_y=y;
+- prv_x2=x;
+- prv_y2=y;
+- x=(radius*c[0])*Math.cos(a*d[1])+(radius*c[2])*Math.sin(a*d[3])+(radius*c[4])*Math.sin(a*d[5]);
+- y=(radius*c[5])*Math.sin(a*d[4])+(radius*c[3])*Math.cos(a*d[2])+(radius*c[1])*Math.cos(a*d[0]);
+- }
+- var c3=16*Math.cos(a*10);
+- var c1=Math.floor(56*Math.cos(a*angle*4)+c3);
+- var c2=Math.floor(56*Math.sin(a*angle*4)-c3);
+- context.lineCap=StrokeLineCap.ROUND;
+- context.setStroke(Paint.valueOf('rgba('+(192+c1)+','+(192+c2)+','+(192-c1)+','+(0.01-0.005*-a1)+')'));
+- context.lineWidth=e*1.4+e*0.8*a3;
+- draw_line(p_x,p_y,prv_x,prv_y,x,y);
+- context.lineWidth=e+e*0.8*a3;
+- draw_line(p_x,p_y,prv_x,prv_y,x,y);
+- context.setStroke(Paint.valueOf('rgba('+(192+c1)+','+(192+c2)+','+(192-c1)+','+(0.06-0.03*-a1)+')'));
+- context.lineWidth=e*0.6+e*0.35*a3;
+- draw_line(p_x,p_y,prv_x,prv_y,x,y);
+- context.setStroke(Paint.valueOf('rgba(0,0,0,0.06)'));
+- context.lineWidth=e*0.4+e*0.225*a3;
+- draw_line(p_x,p_y,prv_x,prv_y,x,y);
+- context.setStroke(Paint.valueOf('rgba('+(192+c1)+','+(192+c2)+','+(192-c1)+','+(0.1-0.075*-a1)+')'));
+- context.lineWidth=e*0.2+e*0.1*a3;
+- draw_line(p_x,p_y,prv_x,prv_y,x,y);
+- context.setStroke(Paint.valueOf('rgba(255,255,255,0.4)'));
+- context.lineWidth=e*(0.1-0.05*-a2);
+- draw_line(p_x,p_y,prv_x,prv_y,x,y);
+- a+=angle*Math.cos(b);
+- b+=angle*0.1;
++ var a1=Math.cos(a*2);
++ var a2=Math.cos(a*4);
++ var a3=Math.cos(a);
++ var a4=Math.sin(a);
++ if(b>limit1&&b<limit2) {
++ r+=radius*0.02*a1;
++ prv_x=x;
++ prv_y=y;
++ x=prv_x2+r*a3;
++ y=prv_y2+r*a4;
++ } else {
++ prv_x=x;
++ prv_y=y;
++ prv_x2=x;
++ prv_y2=y;
++ x=(radius*c[0])*Math.cos(a*d[1])+(radius*c[2])*Math.sin(a*d[3])+(radius*c[4])*Math.sin(a*d[5]);
++ y=(radius*c[5])*Math.sin(a*d[4])+(radius*c[3])*Math.cos(a*d[2])+(radius*c[1])*Math.cos(a*d[0]);
++ }
++ var c3=16*Math.cos(a*10);
++ var c1=Math.floor(56*Math.cos(a*angle*4)+c3);
++ var c2=Math.floor(56*Math.sin(a*angle*4)-c3);
++ context.lineCap=StrokeLineCap.ROUND;
++ context.setStroke(Paint.valueOf('rgba('+(192+c1)+','+(192+c2)+','+(192-c1)+','+(0.01-0.005*-a1)+')'));
++ context.lineWidth=e*1.4+e*0.8*a3;
++ draw_line(p_x,p_y,prv_x,prv_y,x,y);
++ context.lineWidth=e+e*0.8*a3;
++ draw_line(p_x,p_y,prv_x,prv_y,x,y);
++ context.setStroke(Paint.valueOf('rgba('+(192+c1)+','+(192+c2)+','+(192-c1)+','+(0.06-0.03*-a1)+')'));
++ context.lineWidth=e*0.6+e*0.35*a3;
++ draw_line(p_x,p_y,prv_x,prv_y,x,y);
++ context.setStroke(Paint.valueOf('rgba(0,0,0,0.06)'));
++ context.lineWidth=e*0.4+e*0.225*a3;
++ draw_line(p_x,p_y,prv_x,prv_y,x,y);
++ context.setStroke(Paint.valueOf('rgba('+(192+c1)+','+(192+c2)+','+(192-c1)+','+(0.1-0.075*-a1)+')'));
++ context.lineWidth=e*0.2+e*0.1*a3;
++ draw_line(p_x,p_y,prv_x,prv_y,x,y);
++ context.setStroke(Paint.valueOf('rgba(255,255,255,0.4)'));
++ context.lineWidth=e*(0.1-0.05*-a2);
++ draw_line(p_x,p_y,prv_x,prv_y,x,y);
++ a+=angle*Math.cos(b);
++ b+=angle*0.1;
+ }
+
+ function draw_line(x,y,x1,y1,x2,y2) {
+- context.beginPath();
+- context.moveTo(x+x1,y+y1);
+- context.lineTo(x+x2,y+y2);
+- context.moveTo(x-x1,y+y1);
+- context.lineTo(x-x2,y+y2);
+- context.moveTo(x-x1,y-y1);
+- context.lineTo(x-x2,y-y2);
+- context.moveTo(x+x1,y-y1);
+- context.lineTo(x+x2,y-y2);
+- context.moveTo(x+y1,y+x1);
+- context.lineTo(x+y2,y+x2);
+- context.moveTo(x-y1,y+x1);
+- context.lineTo(x-y2,y+x2);
+- context.moveTo(x-y1,y-x1);
+- context.lineTo(x-y2,y-x2);
+- context.moveTo(x+y1,y-x1);
+- context.lineTo(x+y2,y-x2);
+- context.moveTo(x,y+x2);
+- context.lineTo(x,y+x1);
+- context.moveTo(x,y-x2);
+- context.lineTo(x,y-x1);
+- context.moveTo(x+x2,y);
+- context.lineTo(x+x1,y);
+- context.moveTo(x-x2,y);
+- context.lineTo(x-x1,y);
+- context.stroke();
+- context.closePath();
++ context.beginPath();
++ context.moveTo(x+x1,y+y1);
++ context.lineTo(x+x2,y+y2);
++ context.moveTo(x-x1,y+y1);
++ context.lineTo(x-x2,y+y2);
++ context.moveTo(x-x1,y-y1);
++ context.lineTo(x-x2,y-y2);
++ context.moveTo(x+x1,y-y1);
++ context.lineTo(x+x2,y-y2);
++ context.moveTo(x+y1,y+x1);
++ context.lineTo(x+y2,y+x2);
++ context.moveTo(x-y1,y+x1);
++ context.lineTo(x-y2,y+x2);
++ context.moveTo(x-y1,y-x1);
++ context.lineTo(x-y2,y-x2);
++ context.moveTo(x+y1,y-x1);
++ context.lineTo(x+y2,y-x2);
++ context.moveTo(x,y+x2);
++ context.lineTo(x,y+x1);
++ context.moveTo(x,y-x2);
++ context.lineTo(x,y-x1);
++ context.moveTo(x+x2,y);
++ context.lineTo(x+x1,y);
++ context.moveTo(x-x2,y);
++ context.lineTo(x-x1,y);
++ context.stroke();
++ context.closePath();
+ }
+
+ var stack = new StackPane();
+--- ./nashorn/test/script/jfx/spread.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/jfx/spread.js Wed Feb 04 12:14:47 2015 -0800
+@@ -211,7 +211,7 @@
+ var timer = new AnimationTimerExtend() {
+ handle: function handle(now) {
+ if (frame < 200) {
+- draw_frame();
++ draw_frame();
+ } else {
+ checkImageAndExit();
+ timer.stop();
+--- ./nashorn/test/script/maptests/builtins.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/maptests/builtins.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/maptests/constructor.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/maptests/constructor.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -33,4 +33,4 @@
+ // These objects should share the map
+ assertSameMap(new Point(2, 3), new Point(43, 23));
+ assertSameMap(new Point(), new Point());
+-assertSameMap(new Point(), new Point(3, 1));
++assertEqualWithoutTypeMap(new Point(), new Point(3, 1));
+--- ./nashorn/test/script/maptests/maputil.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/maptests/maputil.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -27,7 +27,7 @@
+
+ function assertSameMap(obj1, obj2, msg) {
+ if (! Debug.identical(Debug.map(obj1), Debug.map(obj2))) {
+- fail(obj1.constructor + " instances don't share map");
++ fail(obj1.constructor + " instances don't share map " + Debug.diffPropertyMaps(Debug.map(obj1), Debug.map(obj2)));
+ }
+ }
+
+@@ -36,3 +36,9 @@
+ fail(obj1.constructor + " and " + obj2.constructor + " instances share map");
+ }
+ }
++
++function assertEqualWithoutTypeMap(obj1, obj2, msg) {
++ if (!Debug.equalWithoutType(Debug.map(obj1), Debug.map(obj2))) {
++ fail(obj1.constructor + " and " + obj2.constructor + " instances don't have identical (without considering property types) maps");
++ }
++}
+--- ./nashorn/test/script/maptests/object_create.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/maptests/object_create.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/maptests/object_literals.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/maptests/object_literals.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -42,5 +42,5 @@
+
+ // Object literals created at different callsites
+ assertSameMap({}, {});
+-assertSameMap({foo: 4}, {foo: 'hello'});
+-assertSameMap({foo: 34, bar: 'fdgd'}, {foo: 'world', bar: 54});
++assertEqualWithoutTypeMap({foo: 4}, {foo: 'hello'});
++assertEqualWithoutTypeMap({foo: 34, bar: 'fdgd'}, {foo: 'world', bar: 54});
+--- ./nashorn/test/script/maptests/point.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/maptests/point.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -46,4 +46,4 @@
+
+ assertSameMap(new Point(2, 3), new Point(43, 23));
+ assertSameMap(new Point(), new Point());
+-assertSameMap(new Point(), new Point(3, 1));
++assertEqualWithoutTypeMap(new Point(), new Point(3, 1));
+--- ./nashorn/test/script/maptests/property_add.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/maptests/property_add.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -43,4 +43,4 @@
+ addX(obj1, 3);
+ addX(obj2, 'hello');
+
+-assertSameMap(obj1, obj2);
++assertEqualWithoutTypeMap(obj1, obj2);
+--- ./nashorn/test/script/maptests/property_delete.js Mon Dec 08 12:30:54 2014 -0800
++++ /dev/null Thu Jan 01 00:00:00 1970 +0000
+@@ -1,48 +0,0 @@
+-/*
+- * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.
+- *
+- * This code is distributed in the hope that it will be useful, but WITHOUT
+- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-/**
+- * @test
+- * @option -Dnashorn.debug=true
+- * @fork
+- */
+-
+-load(__DIR__ + "maputil.js");
+-
+-function Foo() {
+- this.x = 33;
+-}
+-
+-var obj1 = new Foo();
+-var obj2 = new Foo();
+-
+-assertSameMap(obj1, obj2);
+-
+-// property deletion at same callsite
+-function deleteX(obj) {
+- delete obj.x;
+-}
+-deleteX(obj1);
+-deleteX(obj2);
+-
+-assertSameMap(obj1, obj2);
+--- ./nashorn/test/script/maptests/proto.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/maptests/proto.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Base library for Showdown markdown engine Nashorn testing.
++ * @subtest
++ *
++ *
++ */
++
++load(__DIR__ + "external/showdown/showdown.js");
++var shdwn = Showdown;
++var window = {
++ Showdown: shdwn
++}
++load(__DIR__ + "external/showdown/table.js");
++var converter = new Showdown.converter({extensions: ['table']});
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/anchors-by-reference.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\nThis is [an example][id] reference-style link.\nThis is [another] [foo] reference-style link.\nThis is [a third][bar] reference-style link.\nThis is [a fourth][4] reference-style link.\n\n [id]: http://example.com/ \"Optional Title Here\"\n [foo]: http://example.com/ (Optional Title Here)\n [bar]: http://example.com/ (Optional Title Here)\n [4]: <http://example.com/>\n \"Optional Title Here\"";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/anchors-by-reference.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,4 @@
++<p>This is <a href="http://example.com/" title="Optional Title Here">an example</a> reference-style link.
++This is <a href="http://example.com/" title="Optional Title Here">another</a> reference-style link.
++This is <a href="http://example.com/" title="Optional Title Here">a third</a> reference-style link.
++This is <a href="http://example.com/" title="Optional Title Here">a fourth</a> reference-style link.</p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/automatic-anchors.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n<http://example.com/>";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/automatic-anchors.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<p><a href="http://example.com/">http://example.com/</a></p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/blockquote-nested-markdown.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "> ## This is a header.\n>\n> 1. This is the first list item.\n> 2. This is the second list item.\n>\n> Here's some example code:\n>\n> return shell_exec(\"echo $input | $markdown_script\");";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/blockquote-nested-markdown.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,13 @@
++<blockquote>
++ <h2 id="thisisaheader">This is a header.</h2>
++
++ <ol>
++ <li>This is the first list item.</li>
++ <li>This is the second list item.</li>
++ </ol>
++
++ <p>Here's some example code:</p>
++
++<pre><code>return shell_exec("echo $input | $markdown_script");
++</code></pre>
++</blockquote>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/blockquote.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = " \n > This is a multi line blockquote test\n >\n > With more than one line.";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/blockquote.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,5 @@
++<blockquote>
++ <p>This is a multi line blockquote test</p>
++
++ <p>With more than one line.</p>
++</blockquote>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/code-block-html-escape.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\nThis is some HTML:\n\n <h1>Heading</h1>";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/code-block-html-escape.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,4 @@
++<p>This is some HTML:</p>
++
++<pre><code>&lt;h1&gt;Heading&lt;/h1&gt;
++</code></pre>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/code-block.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\nThis is a normal paragraph:\n\n This is a code block.";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/code-block.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,4 @@
++<p>This is a normal paragraph:</p>
++
++<pre><code>This is a code block.
++</code></pre>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/doubline-list.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n * Bird\n\n * Magic";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/doubline-list.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,4 @@
++<ul>
++<li><p>Bird</p></li>
++<li><p>Magic</p></li>
++</ul>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/emphasis.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n*important*\n\n_important_\n\nthis mid*important*sentence";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/emphasis.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,5 @@
++<p><em>important</em></p>
++
++<p><em>important</em></p>
++
++<p>this mid<em>important</em>sentence</p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/escaped-number-period.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "It happened in 1986\. What a great season.";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/escaped-number-period.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<p>It happened in 1986. What a great season.</p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/escaping.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\nThese should all be escaped:\n\n\\\n\n\`\n\n\*\n\n\_\n\n\{\n\n\}\n\n\[\n\n\]\n\n\(\n\n\)\n\n\#\n\n\+\n\n\-\n\n\.\n\n\!";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/escaping.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,31 @@
++<p>These should all be escaped:</p>
++
++<p>\</p>
++
++<p>`</p>
++
++<p>*</p>
++
++<p>_</p>
++
++<p>{</p>
++
++<p>}</p>
++
++<p>[</p>
++
++<p>]</p>
++
++<p>(</p>
++
++<p>)</p>
++
++<p>#</p>
++
++<p>+</p>
++
++<p>-</p>
++
++<p>.</p>
++
++<p>!</p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/github-style-at-start.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "```\nfunction MyFunc(a) {\n // ...\n}\n```\n\nThat is some code!";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/github-style-at-start.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,6 @@
++<pre><code>function MyFunc(a) {
++ // ...
++}
++</code></pre>
++
++<p>That is some code!</p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/github-style-codeblock.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\nDefine a function in javascript:\n\n```\nfunction MyFunc(a) {\n var s = '`';\n}\n```\n\nAnd some HTML\n\n```html\n<div>HTML!</div>\n```";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/github-style-codeblock.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,11 @@
++<p>Define a function in javascript:</p>
++
++<pre><code>function MyFunc(a) {
++ var s = '`';
++}
++</code></pre>
++
++<p>And some HTML</p>
++
++<pre><code class="html">&lt;div&gt;HTML!&lt;/div&gt;
++</code></pre>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/github-style-linebreaks.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "```\ncode can go here\nthis is rendered on a second line\n```";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/github-style-linebreaks.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,3 @@
++<pre><code>code can go here
++this is rendered on a second line
++</code></pre>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h1-with-double-hash.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "# This is an H1 #";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h1-with-double-hash.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<h1 id="thisisanh1">This is an H1</h1>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h1-with-equals.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "This is an H1\n=============";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h1-with-equals.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<h1 id="thisisanh1">This is an H1</h1>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h1-with-single-hash.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "# This is an H1";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h1-with-single-hash.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<h1 id="thisisanh1">This is an H1</h1>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h2-with-dashes.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "This is an H2\n-------------";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h2-with-dashes.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<h2 id="thisisanh2">This is an H2</h2>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h2-with-double-hash.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "## This is an H2 ##";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h2-with-double-hash.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<h2 id="thisisanh2">This is an H2</h2>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h2-with-single-hash.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "## This is an H2";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h2-with-single-hash.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<h2 id="thisisanh2">This is an H2</h2>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h3-with-double-hash.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "### This is an H3 ###";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h3-with-double-hash.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<h3 id="thisisanh3">This is an H3</h3>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h3-with-single-hash.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "### This is an H3";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h3-with-single-hash.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<h3 id="thisisanh3">This is an H3</h3>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h4-with-single-hash.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "#### This is an H4";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h4-with-single-hash.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<h4 id="thisisanh4">This is an H4</h4>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h5-with-single-hash.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "##### This is an H5";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h5-with-single-hash.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<h5 id="thisisanh5">This is an H5</h5>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h6-with-single-hash.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "###### This is an H6";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/h6-with-single-hash.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<h6 id="thisisanh6">This is an H6</h6>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/horizontal-rules.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n* * *\n\n***\n\n*****\n\n- - -\n\n---------------------------------------\n";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/horizontal-rules.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,9 @@
++<hr />
++
++<hr />
++
++<hr />
++
++<hr />
++
++<hr />
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/html5-strutural-tags.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\nThese HTML5 tags should pass through just fine.\n\n<section>hello</section>\n<header>head</header>\n<footer>footsies</footer>\n<nav>navigation</nav>\n<article>read me</article>\n<aside>ignore me</aside>\n<article>read\nme</article>\n<aside>\nignore me\n</aside>\n\nthe end";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/html5-strutural-tags.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,22 @@
++<p>These HTML5 tags should pass through just fine.</p>
++
++<section>hello</section>
++
++<header>head</header>
++
++<footer>footsies</footer>
++
++<nav>navigation</nav>
++
++<article>read me</article>
++
++<aside>ignore me</aside>
++
++<article>read
++me</article>
++
++<aside>
++ignore me
++</aside>
++
++<p>the end</p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/images.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n![Alt text](/path/to/img.jpg)\n\n![Alt text](/path/to/img.jpg \"Optional title\")\n\n![Alt text][id]\n\n [id]: url/to/image \"Optional title attribute\"";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/images.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,5 @@
++<p><img src="/path/to/img.jpg" alt="Alt text" title="" /></p>
++
++<p><img src="/path/to/img.jpg" alt="Alt text" title="Optional title" /></p>
++
++<p><img src="url/to/image" alt="Alt text" title="Optional title attribute" /></p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/implicit-anchors.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\nSearch the web at [Google][] or [Daring Fireball][].\n\n [Google]: http://google.com/\n [Daring Fireball]: http://daringfireball.net/";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/implicit-anchors.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<p>Search the web at <a href="http://google.com/">Google</a> or <a href="http://daringfireball.net/">Daring Fireball</a>.</p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/inline-anchors.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\nThis is [an example](http://example.com/ \"Title\") inline link.\n\n[This link](http://example.net/) has no title attribute.";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/inline-anchors.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,3 @@
++<p>This is <a href="http://example.com/" title="Title">an example</a> inline link.</p>
++
++<p><a href="http://example.net/">This link</a> has no title attribute.</p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/inline-code.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\nCreate a new `function`.\n\nUse the backtick in MySQL syntax ``SELECT `column` FROM whatever``.\n\nA single backtick in a code span: `` ` ``\n\nA backtick-delimited string in a code span: `` `foo` ``\n\nPlease don't use any `<blink>` tags.\n\n`&#8212;` is the decimal-encoded equivalent of `&mdash;`.";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/inline-code.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,11 @@
++<p>Create a new <code>function</code>.</p>
++
++<p>Use the backtick in MySQL syntax <code>SELECT `column` FROM whatever</code>.</p>
++
++<p>A single backtick in a code span: <code>`</code></p>
++
++<p>A backtick-delimited string in a code span: <code>`foo`</code></p>
++
++<p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>
++
++<p><code>&amp;#8212;</code> is the decimal-encoded equivalent of <code>&amp;mdash;</code>.</p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/inline-style-tag.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n<style>\n p { line-height: 20px; }\n</style>\n\nAn exciting sentence.";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/inline-style-tag.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,5 @@
++<style>
++ p { line-height: 20px; }
++</style>
++
++<p>An exciting sentence.</p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/lazy-blockquote.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n > This is a multi line blockquote test\n\n > With more than one line.";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/lazy-blockquote.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,5 @@
++<blockquote>
++ <p>This is a multi line blockquote test</p>
++
++ <p>With more than one line.</p>
++</blockquote>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/list-with-blockquote.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "* A list item with a blockquote:\n\n > This is a blockquote\n > inside a list item.";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/list-with-blockquote.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,8 @@
++<ul>
++<li><p>A list item with a blockquote:</p>
++
++<blockquote>
++ <p>This is a blockquote
++ inside a list item.</p>
++</blockquote></li>
++</ul>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/list-with-code.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "* A list item with code:\n\n alert('Hello world!');";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/list-with-code.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,6 @@
++<ul>
++<li><p>A list item with code:</p>
++
++<pre><code>alert('Hello world!');
++</code></pre></li>
++</ul>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/multi-paragraph-list.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n 1. This is a major bullet point.\n\n That contains multiple paragraphs.\n\n 2. And another line";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/multi-paragraph-list.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,6 @@
++<ol>
++<li><p>This is a major bullet point.</p>
++
++<p>That contains multiple paragraphs.</p></li>
++<li><p>And another line</p></li>
++</ol>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/multiline-unordered-list.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n - This line spans\n more than one line and is lazy\n - Similar to this line";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/multiline-unordered-list.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,5 @@
++<ul>
++<li>This line spans
++more than one line and is lazy</li>
++<li>Similar to this line</li>
++</ul>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/nested-blockquote.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n > This is a multi line blockquote test\n >\n > > And nesting!\n >\n > With more than one line.";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/nested-blockquote.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,9 @@
++<blockquote>
++ <p>This is a multi line blockquote test</p>
++
++ <blockquote>
++ <p>And nesting!</p>
++ </blockquote>
++
++ <p>With more than one line.</p>
++</blockquote>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/ordered-list-same-number.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n 1. Red\n 1. Green\n 1. Blue";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/ordered-list-same-number.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,5 @@
++<ol>
++<li>Red</li>
++<li>Green</li>
++<li>Blue</li>
++</ol>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/ordered-list-wrong-numbers.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n 8. Red\n 1. Green\n 3. Blue";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/ordered-list-wrong-numbers.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,5 @@
++<ol>
++<li>Red</li>
++<li>Green</li>
++<li>Blue</li>
++</ol>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/ordered-list.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n 1. Red\n 2. Green\n 3. Blue";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/ordered-list.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,5 @@
++<ol>
++<li>Red</li>
++<li>Green</li>
++<li>Blue</li>
++</ol>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/relative-anchors.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\nSee my [About](/about/) page for details.";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/relative-anchors.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<p>See my <a href="/about/">About</a> page for details.</p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/simple-paragraph.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\nHello, world!";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/simple-paragraph.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<p>Hello, world!</p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/strong.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n**important**\n\n__important__\n\nreally **freaking**strong";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/strong.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,5 @@
++<p><strong>important</strong></p>
++
++<p><strong>important</strong></p>
++
++<p>really <strong>freaking</strong>strong</p>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/table-basic.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "| First Header | Second Header |\n| ------------- | ------------- |\n| Row 1 Cell 1 | Row 1 Cell 2 |\n| Row 2 Cell 1 | Row 2 Cell 2 |\n";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/table-basic.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,21 @@
++<table>
++<thead>
++<tr>
++<th id="first_header" style="text-align:left;"> First Header </th>
++<th id="second_header" style="text-align:left;"> Second Header </th>
++</tr>
++</thead>
++
++<tbody>
++<tr>
++<td style="text-align:left;"><p>Row 1 Cell 1 </p></td>
++<td style="text-align:left;"><p>Row 1 Cell 2 </p></td>
++</tr>
++
++<tr>
++<td style="text-align:left;"><p>Row 2 Cell 1 </p></td>
++<td style="text-align:left;"><p>Row 2 Cell 2 </p></td>
++</tr>
++
++</tbody>
++</table>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/table-large.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "| First Header | Second Header | Third Header | Fourth Header |\n| ------------- | ------------- | ------------ | ------------- |\n| Row 1 Cell 1 | Row 1 Cell 2 | Row 1 Cell 3 | Row 1 Cell 4 |\n| Row 2 Cell 1 | Row 2 Cell 2 | Row 2 Cell 3 | Row 2 Cell 4 |\n| Row 3 Cell 1 | Row 3 Cell 2 | Row 3 Cell 3 | Row 3 Cell 4 |\n| Row 4 Cell 1 | Row 4 Cell 2 | Row 4 Cell 3 | Row 4 Cell 4 |\n| Row 5 Cell 1 | Row 5 Cell 2 | Row 5 Cell 3 | Row 5 Cell 4 |\n";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/table-large.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,48 @@
++<table>
++<thead>
++<tr>
++<th id="first_header" style="text-align:left;"> First Header </th>
++<th id="second_header" style="text-align:left;"> Second Header </th>
++<th id="third_header" style="text-align:left;"> Third Header </th>
++<th id="fourth_header" style="text-align:left;"> Fourth Header </th>
++</tr>
++</thead>
++
++<tbody>
++<tr>
++<td style="text-align:left;"><p>Row 1 Cell 1 </p></td>
++<td style="text-align:left;"><p>Row 1 Cell 2 </p></td>
++<td style="text-align:left;"><p>Row 1 Cell 3 </p></td>
++<td style="text-align:left;"><p>Row 1 Cell 4 </p></td>
++</tr>
++
++<tr>
++<td style="text-align:left;"><p>Row 2 Cell 1 </p></td>
++<td style="text-align:left;"><p>Row 2 Cell 2 </p></td>
++<td style="text-align:left;"><p>Row 2 Cell 3 </p></td>
++<td style="text-align:left;"><p>Row 2 Cell 4 </p></td>
++</tr>
++
++<tr>
++<td style="text-align:left;"><p>Row 3 Cell 1 </p></td>
++<td style="text-align:left;"><p>Row 3 Cell 2 </p></td>
++<td style="text-align:left;"><p>Row 3 Cell 3 </p></td>
++<td style="text-align:left;"><p>Row 3 Cell 4 </p></td>
++</tr>
++
++<tr>
++<td style="text-align:left;"><p>Row 4 Cell 1 </p></td>
++<td style="text-align:left;"><p>Row 4 Cell 2 </p></td>
++<td style="text-align:left;"><p>Row 4 Cell 3 </p></td>
++<td style="text-align:left;"><p>Row 4 Cell 4 </p></td>
++</tr>
++
++<tr>
++<td style="text-align:left;"><p>Row 5 Cell 1 </p></td>
++<td style="text-align:left;"><p>Row 5 Cell 2 </p></td>
++<td style="text-align:left;"><p>Row 5 Cell 3 </p></td>
++<td style="text-align:left;"><p>Row 5 Cell 4 </p></td>
++</tr>
++
++</tbody>
++</table>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/table-with-equals.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "| First Header | Second Header |\n| ============= | ============= |\n| Row 1 Cell 1 | Row 1 Cell 2 |\n| Row 2 Cell 1 | Row 2 Cell 2 |\n";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/table-with-equals.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,21 @@
++<table>
++<thead>
++<tr>
++<th id="first_header" style="text-align:left;"> First Header </th>
++<th id="second_header" style="text-align:left;"> Second Header </th>
++</tr>
++</thead>
++
++<tbody>
++<tr>
++<td style="text-align:left;"><p>Row 1 Cell 1 </p></td>
++<td style="text-align:left;"><p>Row 1 Cell 2 </p></td>
++</tr>
++
++<tr>
++<td style="text-align:left;"><p>Row 2 Cell 1 </p></td>
++<td style="text-align:left;"><p>Row 2 Cell 2 </p></td>
++</tr>
++
++</tbody>
++</table>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/unordered-list-asterisk.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n * Red\n * Green\n * Blue";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/unordered-list-asterisk.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,5 @@
++<ul>
++<li>Red</li>
++<li>Green</li>
++<li>Blue</li>
++</ul>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/unordered-list-minus.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n - Red\n - Green\n - Blue";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/unordered-list-minus.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,5 @@
++<ul>
++<li>Red</li>
++<li>Green</li>
++<li>Blue</li>
++</ul>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/unordered-list-plus.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\n + Red\n + Green\n + Blue";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/unordered-list-plus.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,5 @@
++<ul>
++<li>Red</li>
++<li>Green</li>
++<li>Blue</li>
++</ul>
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/url-with-parenthesis.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Test for Showdown markdown parser work with Nashorn.
++ *
++ * @test
++ * @run
++ */
++
++var input = "\nThere's an [episode](http://en.memory-alpha.org/wiki/Darmok_(episode)) of Star Trek: The Next Generation";
++var output = converter.makeHtml(input);
++print(output);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/markdown/url-with-parenthesis.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,1 @@
++<p>There's an <a href="http://en.memory-alpha.org/wiki/Darmok_(episode)">episode</a> of Star Trek: The Next Generation</p>
+--- ./nashorn/test/script/nosecurity/JDK-8044798.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/nosecurity/JDK-8044798.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,6 +25,8 @@
+ * JDK-8044798: API for debugging Nashorn
+ *
+ * @test
++ * @option -Dnashorn.mirror.always=false
++ * @fork
+ * @run
+ */
+
+@@ -37,11 +39,7 @@
+
+ var valueDescFields = DebuggerValueDesc.class.declaredFields;
+ Arrays.sort(valueDescFields, function(f1, f2) f1.name.compareTo(f2.name));
+-var keyField;
+ for each (var f in valueDescFields) {
+- if (f.name == "key") {
+- keyField = f;
+- }
+ f.accessible = true;
+ }
+
+@@ -92,22 +90,18 @@
+
+ // valueInfos
+ var infos = valueInfosMethod.invoke(null, Object, true);
+-Arrays.sort(infos, function (i1, i2) keyField.get(i1).compareTo(keyField.get(i2)));
+-
+ for each (var info in infos) {
+ for each (var f in valueDescFields) {
+ print(f.name, "=", f.get(info));
+- }
++ }
+ }
+
+ // valueInfos - user defined object
+ var infos = valueInfosMethod.invoke(null, { foo: 34, bar: "hello" }, true);
+-Arrays.sort(infos, function (i1, i2) keyField.get(i1).compareTo(keyField.get(i2)));
+-
+ for each (var info in infos) {
+ for each (var f in valueDescFields) {
+ print(f.name, "=", f.get(info));
+- }
++ }
+ }
+
+ // valueAsString
+--- ./nashorn/test/script/nosecurity/JDK-8044798.js.EXPECTED Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/nosecurity/JDK-8044798.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -8,25 +8,17 @@
+ valueAsObject = [object Object]
+ valueAsString = {foo: 343}
+ expandable = false
+-key = bindProperties
+-valueAsObject = function bindProperties() { [native code] }
+-valueAsString = function bindProperties() { [native code] }
++key = setIndexedPropertiesToExternalArrayData
++valueAsObject = function setIndexedPropertiesToExternalArrayData() { [native code] }
++valueAsString = function setIndexedPropertiesToExternalArrayData() { [native code] }
+ expandable = false
+-key = create
+-valueAsObject = function create() { [native code] }
+-valueAsString = function create() { [native code] }
++key = getPrototypeOf
++valueAsObject = function getPrototypeOf() { [native code] }
++valueAsString = function getPrototypeOf() { [native code] }
+ expandable = false
+-key = defineProperties
+-valueAsObject = function defineProperties() { [native code] }
+-valueAsString = function defineProperties() { [native code] }
+-expandable = false
+-key = defineProperty
+-valueAsObject = function defineProperty() { [native code] }
+-valueAsString = function defineProperty() { [native code] }
+-expandable = false
+-key = freeze
+-valueAsObject = function freeze() { [native code] }
+-valueAsString = function freeze() { [native code] }
++key = setPrototypeOf
++valueAsObject = function setPrototypeOf() { [native code] }
++valueAsString = function setPrototypeOf() { [native code] }
+ expandable = false
+ key = getOwnPropertyDescriptor
+ valueAsObject = function getOwnPropertyDescriptor() { [native code] }
+@@ -36,26 +28,54 @@
+ valueAsObject = function getOwnPropertyNames() { [native code] }
+ valueAsString = function getOwnPropertyNames() { [native code] }
+ expandable = false
+-key = getPrototypeOf
+-valueAsObject = function getPrototypeOf() { [native code] }
+-valueAsString = function getPrototypeOf() { [native code] }
++key = create
++valueAsObject = function create() { [native code] }
++valueAsString = function create() { [native code] }
++expandable = false
++key = defineProperty
++valueAsObject = function defineProperty() { [native code] }
++valueAsString = function defineProperty() { [native code] }
++expandable = false
++key = defineProperties
++valueAsObject = function defineProperties() { [native code] }
++valueAsString = function defineProperties() { [native code] }
++expandable = false
++key = seal
++valueAsObject = function seal() { [native code] }
++valueAsString = function seal() { [native code] }
++expandable = false
++key = freeze
++valueAsObject = function freeze() { [native code] }
++valueAsString = function freeze() { [native code] }
++expandable = false
++key = preventExtensions
++valueAsObject = function preventExtensions() { [native code] }
++valueAsString = function preventExtensions() { [native code] }
++expandable = false
++key = isSealed
++valueAsObject = function isSealed() { [native code] }
++valueAsString = function isSealed() { [native code] }
++expandable = false
++key = isFrozen
++valueAsObject = function isFrozen() { [native code] }
++valueAsString = function isFrozen() { [native code] }
+ expandable = false
+ key = isExtensible
+ valueAsObject = function isExtensible() { [native code] }
+ valueAsString = function isExtensible() { [native code] }
+ expandable = false
+-key = isFrozen
+-valueAsObject = function isFrozen() { [native code] }
+-valueAsString = function isFrozen() { [native code] }
+-expandable = false
+-key = isSealed
+-valueAsObject = function isSealed() { [native code] }
+-valueAsString = function isSealed() { [native code] }
+-expandable = false
+ key = keys
+ valueAsObject = function keys() { [native code] }
+ valueAsString = function keys() { [native code] }
+ expandable = false
++key = bindProperties
++valueAsObject = function bindProperties() { [native code] }
++valueAsString = function bindProperties() { [native code] }
++expandable = false
++key = prototype
++valueAsObject = [object Object]
++valueAsString = {toString: function toString() { [native code] }, toLocaleString: function toLocaleString() { [native code] }, valueOf: function valueOf() { [native code] }, hasOwnProperty: function hasOwnProperty() { [native code] }, isPrototypeOf: function isPrototypeOf() { [native code] }, propertyIsEnumerable: function propertyIsEnumerable() { [native code] }, constructor: function Object() { [native code] }, __proto__: null}
++expandable = false
+ key = length
+ valueAsObject = 1
+ valueAsString = 1
+@@ -64,33 +84,13 @@
+ valueAsObject = Object
+ valueAsString = "Object"
+ expandable = false
+-key = preventExtensions
+-valueAsObject = function preventExtensions() { [native code] }
+-valueAsString = function preventExtensions() { [native code] }
+-expandable = false
+-key = prototype
+-valueAsObject = [object Object]
+-valueAsString = {toString: function toString() { [native code] }, toLocaleString: function toLocaleString() { [native code] }, valueOf: function valueOf() { [native code] }, hasOwnProperty: function hasOwnProperty() { [native code] }, isPrototypeOf: function isPrototypeOf() { [native code] }, propertyIsEnumerable: function propertyIsEnumerable() { [native code] }, constructor: function Object() { [native code] }, __proto__: null}
+-expandable = false
+-key = seal
+-valueAsObject = function seal() { [native code] }
+-valueAsString = function seal() { [native code] }
+-expandable = false
+-key = setIndexedPropertiesToExternalArrayData
+-valueAsObject = function setIndexedPropertiesToExternalArrayData() { [native code] }
+-valueAsString = function setIndexedPropertiesToExternalArrayData() { [native code] }
+-expandable = false
+-key = setPrototypeOf
+-valueAsObject = function setPrototypeOf() { [native code] }
+-valueAsString = function setPrototypeOf() { [native code] }
++key = foo
++valueAsObject = 34
++valueAsString = 34
+ expandable = false
+ key = bar
+ valueAsObject = hello
+ valueAsString = "hello"
+-expandable = false
+-key = foo
+-valueAsObject = 34
+-valueAsString = 34
+ undefined
+ null
+ "hello"
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/nosecurity/JDK-8044851.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,93 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8044851: nashorn properties leak memory
++ *
++ * @test
++ * @run
++ * @option -Dnashorn.debug=true
++ * @fork
++ */
++
++function printProperty(value, property) {
++ print(value, property.getKey(), property.isSpill() ? "spill" : "field", property.getSlot());
++}
++
++var obj = {}, i, name;
++
++for (i = 0; i < 8; ++i) {
++ name = 'property' + i;
++ obj[name] = 'a' + i;
++ printProperty(obj[name], Debug.map(obj).findProperty(name));
++}
++print();
++
++for (i = 0; i < 8; ++i) {
++ name = 'property' + i;
++ delete obj[name];
++}
++
++for (i = 0; i < 8; ++i) {
++ name = 'property' + i;
++ obj[name] = 'b' + i;
++ printProperty(obj[name], Debug.map(obj).findProperty(name));
++}
++print();
++
++for (i = 0; i < 8; ++i) {
++ name = 'property' + i;
++ Object.defineProperty(obj, name, {get: function() {return i;}, set: function(v) {}, configurable: true});
++ printProperty(obj[name], Debug.map(obj).findProperty(name));
++}
++print();
++
++for (i = 0; i < 8; ++i) {
++ name = 'property' + i;
++ delete obj[name];
++}
++
++for (i = 0; i < 8; ++i) {
++ name = 'property' + i;
++ obj[name] = 'c' + i;
++ printProperty(obj[name], Debug.map(obj).findProperty(name));
++}
++print();
++
++for (i = 7; i > -1; --i) {
++ name = 'property' + i;
++ delete obj[name];
++}
++
++for (i = 0; i < 8; ++i) {
++ name = 'property' + i;
++ obj[name] = 'd' + i;
++ printProperty(obj[name], Debug.map(obj).findProperty(name));
++}
++print();
++
++for (i = 0; i < 8; ++i) {
++ name = 'property' + i;
++ Object.defineProperty(obj, name, {get: function() {return i;}, set: function(v) {}});
++ printProperty(obj[name], Debug.map(obj).findProperty(name));
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/nosecurity/JDK-8044851.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,53 @@
++a0 property0 field 0
++a1 property1 field 1
++a2 property2 field 2
++a3 property3 field 3
++a4 property4 spill 0
++a5 property5 spill 1
++a6 property6 spill 2
++a7 property7 spill 3
++
++b0 property0 field 0
++b1 property1 field 1
++b2 property2 field 2
++b3 property3 field 3
++b4 property4 spill 0
++b5 property5 spill 1
++b6 property6 spill 2
++b7 property7 spill 3
++
++0 property0 spill 4
++1 property1 spill 5
++2 property2 spill 6
++3 property3 spill 7
++4 property4 spill 8
++5 property5 spill 0
++6 property6 spill 1
++7 property7 spill 2
++
++c0 property0 field 0
++c1 property1 field 1
++c2 property2 field 2
++c3 property3 field 3
++c4 property4 spill 0
++c5 property5 spill 1
++c6 property6 spill 2
++c7 property7 spill 3
++
++d0 property0 field 0
++d1 property1 field 1
++d2 property2 field 2
++d3 property3 field 3
++d4 property4 spill 0
++d5 property5 spill 1
++d6 property6 spill 2
++d7 property7 spill 3
++
++0 property0 spill 4
++1 property1 spill 5
++2 property2 spill 6
++3 property3 spill 7
++4 property4 spill 8
++5 property5 spill 0
++6 property6 spill 1
++7 property7 spill 2
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/nosecurity/JDK-8050964.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8050964: OptimisticTypesPersistence.java should use java.util.Date instead of java.sql.Date
++ *
++ * Make sure that nashorn.jar has only 'compact1' dependency.
++ *
++ * @test
++ * @option -scripting
++ * @run
++ */
++
++// assume that this script is run with "nashorn.jar" System
++// property set to relative path of nashorn.jar from the current
++// directory of test execution.
++
++if (typeof fail != 'function') {
++ fail = print;
++}
++
++var System = java.lang.System;
++var File = java.io.File;
++var nashornJar = new File(System.getProperty("nashorn.jar"));
++if (! nashornJar.isAbsolute()) {
++ nashornJar = new File(".", nashornJar);
++}
++
++var javahome = System.getProperty("java.home");
++var jdepsPath = javahome + "/../bin/jdeps".replaceAll(/\//g, File.separater);
++
++// run jdep on nashorn.jar - only summary but print profile info
++$ENV.PWD=System.getProperty("user.dir") // to avoid RE on Cygwin
++`${jdepsPath} -s -P ${nashornJar.absolutePath}`
++
++// check for "(compact1)" in output from jdep tool
++if (! /(compact1)/.test($OUT)) {
++ fail("non-compact1 dependency: " + $OUT);
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/nosecurity/JDK-8055034.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,64 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8055034: jjs exits interactive mode if exception was thrown when trying to print value of last evaluated expression
++ *
++ * @test
++ * @option -scripting
++ * @run
++ */
++
++// assume that this script is run with "nashorn.jar" System
++// property set to relative or absolute path of nashorn.jar
++
++if (typeof fail != 'function') {
++ fail = print;
++}
++
++var System = java.lang.System;
++var File = java.io.File;
++var javahome = System.getProperty("java.home");
++var nashornJar = new File(System.getProperty("nashorn.jar"));
++if (! nashornJar.isAbsolute()) {
++ nashornJar = new File(".", nashornJar);
++}
++var nashornJarDir = nashornJar.parentFile.absolutePath;
++
++// we want to use nashorn.jar passed and not the one that comes with JRE
++var jjsCmd = javahome + "/../bin/jjs";
++jjsCmd += " -J-Djava.ext.dirs=" + nashornJarDir;
++jjsCmd = jjsCmd.toString().replaceAll(/\//g, File.separater);
++$ENV.PWD=System.getProperty("user.dir") // to avoid RE on Cygwin
++$EXEC(jjsCmd, "var x = Object.create(null);\nx;\nprint('PASSED');\nexit(0)");
++
++// $ERR has all interactions including prompts! Just check for error substring.
++var err = $ERR.trim();
++if (! err.contains("TypeError: Cannot get default string value")) {
++ fail("Error stream does not contain expected error message");
++}
++
++// should print "PASSED"
++print($OUT.trim());
++// exit code should be 0
++print("exit code = " + $EXIT);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/nosecurity/JDK-8055034.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,2 @@
++PASSED
++exit code = 0
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/nosecurity/JDK-8055107.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,179 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
++ *
++ * @test
++ * @option -Dnashorn.debug=true
++ * @option -scripting
++ * @run
++ * @fork
++ */
++
++function runScriptEngine(code) {
++ var imports = new JavaImporter(
++ java.io, java.lang, java.util, javax.script);
++
++ with(imports) {
++ var m = new ScriptEngineManager();
++ // get current System.err
++ var oldErr = System.err;
++ var baos = new ByteArrayOutputStream();
++ var newErr = new PrintStream(baos);
++ try {
++ // set new standard err
++ System.setErr(newErr);
++ var engine = m.getEngineByName("nashorn");
++ engine.eval(code);
++ newErr.flush();
++ return new java.lang.String(baos.toByteArray());
++ } finally {
++ // restore System.err to old value
++ System.setErr(oldErr);
++ }
++ }
++}
++
++// nashorn callsite trace enterexit
++var str = runScriptEngine(<<CODE
++function func() {
++ "nashorn callsite trace enterexit";
++ k();
++}
++
++function k() {
++ var x = "hello";
++}
++
++func();
++CODE);
++
++if (!str.contains(" ENTER ")) {
++ fail("expected 'ENTER' in trace mode output");
++}
++
++if (!str.contains(" EXIT ")) {
++ fail("expected 'EXIT' in trace mode output");
++}
++
++// nashorn callsite trace objects
++var str = runScriptEngine(<<CODE
++"nashorn callsite trace objects";
++function func(x) {
++}
++
++func("hello");
++CODE);
++
++if (!str.contains(" ENTER ")) {
++ fail("expected 'ENTER' in trace mode output");
++}
++
++if (!str.contains(" EXIT ")) {
++ fail("expected 'EXIT' in trace mode output");
++}
++
++if (!str.contains("hello")) {
++ fail("expected argument to be traced in trace objects mode");
++}
++
++// nashorn callsite trace misses
++str = runScriptEngine(<<CODE
++function f() {
++ "nashorn callsite trace misses";
++ k();
++}
++
++function k() {}
++f();
++CODE);
++
++if (!str.contains(" MISS ")) {
++ fail("expected callsite MISS trace messages");
++}
++
++// nashorn print lower ast
++str = runScriptEngine(<<CODE
++function foo() {
++ "nashorn print lower ast";
++ var x = 'hello';
++}
++foo();
++CODE);
++
++if (!str.contains("Lower AST for: 'foo'") ||
++ !str.contains("nashorn print lower ast")) {
++ fail("expected Lower AST to be printed for 'foo'");
++}
++
++// nashorn print ast
++str = runScriptEngine(<<CODE
++function foo() {
++ "nashorn print ast";
++}
++CODE);
++if (!str.contains("[function ") ||
++ !str.contains("nashorn print ast")) {
++ fail("expected AST to be printed");
++}
++
++// nashorn print symbols
++str = runScriptEngine(<<CODE
++function bar(a) {
++ "nashorn print symbols";
++ if (a) print(a);
++}
++
++bar();
++CODE)
++
++if (!str.contains("[BLOCK in 'Function bar']")) {
++ fail("expected symbols to be printed for 'bar'");
++}
++
++// nashorn print parse
++str = runScriptEngine(<<CODE
++"nashorn print parse";
++
++function func() {}
++CODE);
++
++if (!str.contains("function func") ||
++ !str.contains("nashorn print parse")) {
++ fail("expected nashorn print parse output");
++}
++
++// nashorn print lower parse
++str = runScriptEngine(<<CODE
++"nashorn print lower parse";
++
++function func() {}
++
++func()
++CODE);
++
++if (!str.contains("function {U%}func") ||
++ !str.contains("nashorn print lower parse")) {
++ fail("expected nashorn print lower parse output");
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/nosecurity/JDK-8060688.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,56 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * JDK-8060688: Nashorn: Generated script class name fails --verify-code for names with special chars
++ *
++ * @test
++ * @run
++ */
++
++var NashornEngineFactory = Java.type("jdk.nashorn.api.scripting.NashornScriptEngineFactory");
++var ScriptEngine = Java.type("javax.script.ScriptEngine");
++var ScriptContext = Java.type("javax.script.ScriptContext");
++
++var factory = new NashornEngineFactory();
++
++var e = factory.getScriptEngine("--verify-code");
++
++function evalAndCheck(code) {
++ try {
++ e.eval(code);
++ } catch (exp) {
++ exp.printStackTrace();
++ }
++}
++
++// check default name
++evalAndCheck("var a = 3");
++// check few names with special chars
++var scontext = e.context;
++scontext.setAttribute(ScriptEngine.FILENAME, "<myscript>", ScriptContext.ENGINE_SCOPE);
++evalAndCheck("var h = 'hello'");
++scontext.setAttribute(ScriptEngine.FILENAME, "[myscript]", ScriptContext.ENGINE_SCOPE);
++evalAndCheck("var foo = 'world'");
++scontext.setAttribute(ScriptEngine.FILENAME, ";/\\$.", ScriptContext.ENGINE_SCOPE);
++evalAndCheck("var foo = 'helloworld'");
+--- ./nashorn/test/script/nosecurity/debuggersupportapi.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/nosecurity/debuggersupportapi.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/nosecurity/nosecurity.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/nosecurity/nosecurity.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * 8043443: Test framework changes to run script tests without security manager
++ * 8043443: Test framework changes to run script tests without security manager
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/sandbox/JDK-8031106.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/JDK-8031106.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/NASHORN-525.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/NASHORN-525.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,28 +1,28 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /**
+- * NASHORN-525 : nashorn misses security access checks
++ * NASHORN-525 : nashorn misses security access checks
+ *
+ * @test
+ * @run
+--- ./nashorn/test/script/sandbox/arrayclass.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/arrayclass.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/classbind.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/classbind.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/classloader.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/classloader.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/doprivileged.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/doprivileged.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -48,11 +48,11 @@
+ check(e);
+ }
+
+- try {
+- var prop = java.lang.System.getProperty("user.dir");
++ try {
++ var prop = java.lang.System.getProperty("user.dir");
+ fail("can get user.dir " + prop);
+- } catch(e) {
++ } catch(e) {
+ print(e);
+- }
++ }
+ }
+ });
+--- ./nashorn/test/script/sandbox/engine.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/engine.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/env.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/env.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/exec.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/exec.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/exit.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/exit.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/file.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/file.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/interfaceimpl.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/interfaceimpl.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/javaextend.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/javaextend.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -30,7 +30,7 @@
+ return Java.type("jdk.nashorn.test.models." + n)
+ }
+
+-// Can't extend a final class
++// Can't extend a final class
+ try {
+ Java.extend(model("FinalClass"))
+ } catch(e) {
+--- ./nashorn/test/script/sandbox/jsadapter.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/jsadapter.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/loadLibrary.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/loadLibrary.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/loadcompat.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/loadcompat.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/nashorninternals.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/nashorninternals.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+
+ /**
+- * Test to check that nashorn "internal" classes in codegen, parser, ir
++ * Test to check that nashorn "internal" classes in codegen, parser, ir
+ * packages cannot * be accessed from sandbox scripts.
+ *
+ * @test
+--- ./nashorn/test/script/sandbox/net.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/net.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/property.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/property.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/reflection.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/reflection.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -38,5 +38,5 @@
+ try {
+ var cl = java.lang.Class.class;
+ } catch(e) {
+- check(e);
++ check(e);
+ }
+--- ./nashorn/test/script/sandbox/runnable.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/runnable.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/sandbox/unsafe.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/sandbox/unsafe.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -43,7 +43,7 @@
+ }
+
+ try {
+- var unsafe = Java.type("sun.misc.Unsafe");
++ var unsafe = Java.type("sun.misc.Unsafe");
+ fail("No SecurityException for Java.type sun.misc.Unsafe");
+ } catch (e) {
+ check(e);
+--- ./nashorn/test/script/test262.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/test262.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/test262_single.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/test262_single.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/trusted/JDK-8006424.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/trusted/JDK-8006424.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/trusted/JDK-8006529.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/trusted/JDK-8006529.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -33,16 +33,18 @@
+ * This test script depends on nashorn Compiler internals. It uses reflection
+ * to get access to private field and many public methods of Compiler and
+ * FunctionNode classes. Note that this is trusted code and access to such
+- * internal package classes and methods is okay. But, if you modify any
++ * internal package classes and methods is okay. But, if you modify any
+ * Compiler or FunctionNode class, you may have to revisit this script.
+ * We cannot use direct Java class (via dynalink bean linker) to Compiler
+ * and FunctionNode because of package-access check and so reflective calls.
+ */
+
+-var forName = java.lang.Class["forName(String)"];
++var forName = java.lang.Class["forName(String)"];
+ var Parser = forName("jdk.nashorn.internal.parser.Parser").static
+ var Compiler = forName("jdk.nashorn.internal.codegen.Compiler").static
++var CompilationPhases = forName("jdk.nashorn.internal.codegen.Compiler$CompilationPhases").static;
+ var Context = forName("jdk.nashorn.internal.runtime.Context").static
++var CodeInstaller = forName("jdk.nashorn.internal.runtime.CodeInstaller").static
+ var ScriptEnvironment = forName("jdk.nashorn.internal.runtime.ScriptEnvironment").static
+ var Source = forName("jdk.nashorn.internal.runtime.Source").static
+ var FunctionNode = forName("jdk.nashorn.internal.ir.FunctionNode").static
+@@ -54,20 +56,23 @@
+ var ThrowErrorManager = forName("jdk.nashorn.internal.runtime.Context$ThrowErrorManager").static
+ var ErrorManager = forName("jdk.nashorn.internal.runtime.ErrorManager").static
+ var Debug = forName("jdk.nashorn.internal.runtime.Debug").static
++var String = forName("java.lang.String").static
++var boolean = Java.type("boolean");
+
+ var parseMethod = Parser.class.getMethod("parse");
+-var compileMethod = Compiler.class.getMethod("compile", FunctionNode.class);
++var compileMethod = Compiler.class.getMethod("compile", FunctionNode.class, CompilationPhases.class);
+ var getBodyMethod = FunctionNode.class.getMethod("getBody");
+ var getStatementsMethod = Block.class.getMethod("getStatements");
+ var getInitMethod = VarNode.class.getMethod("getInit");
+ var getExpressionMethod = ExpressionStatement.class.getMethod("getExpression")
+-var rhsMethod = UnaryNode.class.getMethod("rhs")
++var rhsMethod = UnaryNode.class.getMethod("getExpression")
+ var lhsMethod = BinaryNode.class.getMethod("lhs")
+ var binaryRhsMethod = BinaryNode.class.getMethod("rhs")
+ var debugIdMethod = Debug.class.getMethod("id", java.lang.Object.class)
++var compilePhases = CompilationPhases.class.getField("COMPILE_UPTO_BYTECODE").get(null);
+
+ // These are method names of methods in FunctionNode class
+-var allAssertionList = ['isVarArg', 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'needsSelfSymbol', 'isSplit', 'hasEval', 'allVarsInScope', 'isStrict']
++var allAssertionList = ['isVarArg', 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'usesSelfSymbol', 'isSplit', 'hasEval', 'allVarsInScope', 'isStrict']
+
+ // corresponding Method objects of FunctionNode class
+ var functionNodeMethods = {};
+@@ -103,8 +108,8 @@
+ return findFunction(rhsMethod.invoke(node))
+ } else if(node instanceof BinaryNode) {
+ return findFunction(lhsMethod.invoke(node)) || findFunction(binaryRhsMethod.invoke(node))
+- } else if(node instanceof ExpressionStatement) {
+- return findFunction(getExpressionMethod.invoke(node))
++ } else if(node instanceof ExpressionStatement) {
++ return findFunction(getExpressionMethod.invoke(node))
+ } else if(node instanceof FunctionNode) {
+ return node
+ }
+@@ -115,22 +120,23 @@
+
+ var sourceForMethod = Source.class.getMethod("sourceFor", java.lang.String.class, java.lang.String.class)
+ var ParserConstructor = Parser.class.getConstructor(ScriptEnvironment.class, Source.class, ErrorManager.class)
+-var CompilerConstructor = Compiler.class.getConstructor(ScriptEnvironment.class)
++var CompilerConstructor = Compiler.class.getConstructor(Context.class, ScriptEnvironment.class, CodeInstaller.class, Source.class, ErrorManager.class, boolean.class);
+
+-// compile(script) -- compiles a script specified as a string with its
+-// source code, returns a jdk.nashorn.internal.ir.FunctionNode object
++// compile(script) -- compiles a script specified as a string with its
++// source code, returns a jdk.nashorn.internal.ir.FunctionNode object
+ // representing it.
+-function compile(source) {
++function compile(source, phases) {
+ var source = sourceForMethod.invoke(null, "<no name>", source);
+
+- var env = getEnvMethod.invoke(getContextMethod.invoke(null))
++ var ctxt = getContextMethod.invoke(null);
++ var env = getEnvMethod.invoke(ctxt);
+
+ var parser = ParserConstructor.newInstance(env, source, ThrowErrorManager.class.newInstance());
+ var func = parseMethod.invoke(parser);
+
+- var compiler = CompilerConstructor.newInstance(env);
++ var compiler = CompilerConstructor.newInstance(ctxt, env, null, source, null, false);
+
+- return compileMethod.invoke(compiler, func);
++ return compileMethod.invoke(compiler, func, phases);
+ };
+
+ var allAssertions = (function() {
+@@ -166,8 +172,8 @@
+ // assertions are true in the first function in the given script; "script"
+ // is a string with the source text of the script.
+ function testFirstFn(script) {
+- arguments[0] = getFirstFunction(compile(script))
+- test.apply(null, arguments)
++ arguments[0] = getFirstFunction(compile(script, compilePhases));
++ test.apply(null, arguments);
+ }
+
+ // ---------------------------------- ACTUAL TESTS START HERE --------------
+@@ -197,13 +203,13 @@
+ // A function defining "arguments" as a local variable will be vararg.
+ testFirstFn("function f() { var arguments; arguments; }", 'isVarArg', 'needsCallee')
+
+-// A self-referencing function defined as a statement doesn't need a self
++// A self-referencing function defined as a statement doesn't need a self
+ // symbol, as it'll rather obtain itself from the parent scope.
+ testFirstFn("function f() { f() }", 'needsCallee', 'needsParentScope')
+
+ // A self-referencing function defined as an expression needs a self symbol,
+ // as it can't obtain itself from the parent scope.
+-testFirstFn("(function f() { f() })", 'needsCallee', 'needsSelfSymbol')
++testFirstFn("(function f() { f() })", 'needsCallee', 'usesSelfSymbol')
+
+ // A child function accessing parent's variable triggers the need for scope
+ // in parent
+@@ -217,7 +223,7 @@
+ // scope in parent
+ testFirstFn("(function f() { function g() { x } })", 'needsParentScope', 'needsCallee')
+
+-// A child function redefining a local variable from its parent should not
++// A child function redefining a local variable from its parent should not
+ // affect the parent function in any way
+ testFirstFn("(function f() { var x; function g() { var x; x } })")
+
+@@ -239,14 +245,15 @@
+
+ // Using "eval" triggers pretty much everything. The function even needs to be
+ // vararg, 'cause we don't know if eval will be using "arguments".
+-testFirstFn("(function f() { eval() })", 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'hasEval', 'isVarArg', 'allVarsInScope')
++testFirstFn("(function f() { eval() })", 'usesSelfSymbol', 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'hasEval', 'isVarArg', 'allVarsInScope')
+
+ // Nested function using "eval" is almost the same as parent function using
+ // eval, but at least the parent doesn't have to be vararg.
+-testFirstFn("(function f() { function g() { eval() } })", 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'allVarsInScope')
++testFirstFn("(function f() { function g() { eval() } })", 'usesSelfSymbol', 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'allVarsInScope')
+
+ // Function with 250 named parameters is ordinary
+ testFirstFn("function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54, p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81, p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98, p99, p100, p101, p102, p103, p104, p105, p106, p107, p108, p109, p110, p111, p112, p113, p114, p115, p116, p117, p118, p119, p120, p121, p122, p123, p124, p125, p126, p127, p128, p129, p130, p131, p132, p133, p134, p135, p136, p137, p138, p139, p140, p141, p142, p143, p144, p145, p146, p147, p148, p149, p150, p151, p152, p153, p154, p155, p156, p157, p158, p159, p160, p161, p162, p163, p164, p165, p166, p167, p168, p169, p170, p171, p172, p173, p174, p175, p176, p177, p178, p179, p180, p181, p182, p183, p184, p185, p186, p187, p188, p189, p190, p191, p192, p193, p194, p195, p196, p197, p198, p199, p200, p201, p202, p203, p204, p205, p206, p207, p208, p209, p210, p211, p212, p213, p214, p215, p216, p217, p218, p219, p220, p221, p222, p223, p224, p225, p226, p227, p228, p229, p230, p231, p232, p233, p234, p235, p236, p237, p238, p239, p240, p241, p242, p243, p244, p245, p246, p247, p248, p249, p250) { p250 = p249 }")
+
+ // Function with 251 named parameters is variable arguments
+-testFirstFn("function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54, p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81, p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98, p99, p100, p101, p102, p103, p104, p105, p106, p107, p108, p109, p110, p111, p112, p113, p114, p115, p116, p117, p118, p119, p120, p121, p122, p123, p124, p125, p126, p127, p128, p129, p130, p131, p132, p133, p134, p135, p136, p137, p138, p139, p140, p141, p142, p143, p144, p145, p146, p147, p148, p149, p150, p151, p152, p153, p154, p155, p156, p157, p158, p159, p160, p161, p162, p163, p164, p165, p166, p167, p168, p169, p170, p171, p172, p173, p174, p175, p176, p177, p178, p179, p180, p181, p182, p183, p184, p185, p186, p187, p188, p189, p190, p191, p192, p193, p194, p195, p196, p197, p198, p199, p200, p201, p202, p203, p204, p205, p206, p207, p208, p209, p210, p211, p212, p213, p214, p215, p216, p217, p218, p219, p220, p221, p222, p223, p224, p225, p226, p227, p228, p229, p230, p231, p232, p233, p234, p235, p236, p237, p238, p239, p240, p241, p242, p243, p244, p245, p246, p247, p248, p249, p250, p251) { p250 = p251 }", 'isVarArg')
++// NOTE: hasScopeBlock should be optimized away. Implementation of JDK-8038942 should take care of it.
++testFirstFn("function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54, p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81, p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98, p99, p100, p101, p102, p103, p104, p105, p106, p107, p108, p109, p110, p111, p112, p113, p114, p115, p116, p117, p118, p119, p120, p121, p122, p123, p124, p125, p126, p127, p128, p129, p130, p131, p132, p133, p134, p135, p136, p137, p138, p139, p140, p141, p142, p143, p144, p145, p146, p147, p148, p149, p150, p151, p152, p153, p154, p155, p156, p157, p158, p159, p160, p161, p162, p163, p164, p165, p166, p167, p168, p169, p170, p171, p172, p173, p174, p175, p176, p177, p178, p179, p180, p181, p182, p183, p184, p185, p186, p187, p188, p189, p190, p191, p192, p193, p194, p195, p196, p197, p198, p199, p200, p201, p202, p203, p204, p205, p206, p207, p208, p209, p210, p211, p212, p213, p214, p215, p216, p217, p218, p219, p220, p221, p222, p223, p224, p225, p226, p227, p228, p229, p230, p231, p232, p233, p234, p235, p236, p237, p238, p239, p240, p241, p242, p243, p244, p245, p246, p247, p248, p249, p250, p251) { p250 = p251 }", 'isVarArg', 'hasScopeBlock')
+--- ./nashorn/test/script/trusted/JDK-8008305.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/trusted/JDK-8008305.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/trusted/JDK-8008305_subtest.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/trusted/JDK-8008305_subtest.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/trusted/JDK-8020809.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/trusted/JDK-8020809.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * JDK-8020809: Java adapter should not allow overriding of caller sensitive methods
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/trusted/JDK-8021129.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/trusted/JDK-8021129.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -25,7 +25,7 @@
+ * JDK-8021129: Test prevention of access to members of restricted classes.
+ * Note that even though the script runs as trusted, we still don't allow
+ * access to non-public portions of restricted classes.
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/trusted/JDK-8021189.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/trusted/JDK-8021189.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -23,7 +23,7 @@
+
+ /**
+ * JDK-8021189: Prevent access to constructors of restricted classes
+- *
++ *
+ * @test
+ * @run
+ */
+--- ./nashorn/test/script/trusted/JDK-8025629.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/trusted/JDK-8025629.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/trusted/JDK-8032060.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/trusted/JDK-8032060.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/trusted/NASHORN-638.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/trusted/NASHORN-638.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- ./nashorn/test/script/trusted/NASHORN-653.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/trusted/NASHORN-653.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+@@ -35,37 +35,37 @@
+ \
+ function b() { \
+ while (x) { \
+- return true; \
++ return true; \
+ } \
+ } \
+ \
+ function c() { \
+ while (true) { \
+- return true; \
++ return true; \
+ } \
+ } \
+ \
+ function d() { \
+ do { \
+- return true; \
++ return true; \
+ } while (x); \
+ } \
+ \
+ function f() { \
+ for (;;) { \
+- return true; \
++ return true; \
+ } \
+ } \
+ \
+ function e() { \
+ for (;;) { \
+- return true; \
++ return true; \
+ } \
+ } \
+ \
+ function g() { \
+ for(;;) { \
+- print('goes on and on and on ... '); \
++ print('goes on and on and on ... '); \
+ } \
+ print('x'); \
+ } \
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/trusted/classfilter.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,72 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * ClassFilter to filter out java classes in a script engine.
++ *
++ * @test
++ * @run
++ */
++
++var NashornScriptEngineFactory = Java.type("jdk.nashorn.api.scripting.NashornScriptEngineFactory");
++
++var fac = new NashornScriptEngineFactory();
++// allow only "java.*" classes to be accessed
++var e = fac.getScriptEngine(
++ function(name) name.startsWith("java."));
++
++function evalIt(str) {
++ print(str + " evalutes to " + e.eval(str));
++}
++
++function evalExpectError(str) {
++ try {
++ print(e.eval(str));
++ fail("expected error for: " + str);
++ } catch(exp) {
++ print(str + " throws " + exp);
++ }
++}
++
++evalIt("typeof javax.script.ScriptContext");
++evalIt("typeof javax.script.ScriptEngine");
++evalIt("typeof java.util.Vector");
++evalIt("typeof java.util.Map");
++evalIt("typeof java.util.HashMap");
++// should be able to call methods, create objects of java.* classes
++evalIt("var m = new java.util.HashMap(); m.put('foo', 42); m");
++evalIt("java.lang.System.out.println");
++evalIt("java.lang.System.exit");
++
++evalExpectError("new javax.script.SimpleBindings");
++evalExpectError("Java.type('javax.script.ScriptContext')");
++evalExpectError("java.lang.Class.forName('javax.script.ScriptContext')");
++
++try {
++ fac["getScriptEngine(ClassFilter)"](null);
++ fail("should have thrown NPE");
++} catch (e) {
++ if (! (e instanceof java.lang.NullPointerException)) {
++ fail("NPE expected, got " + e);
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/trusted/classfilter.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,11 @@
++typeof javax.script.ScriptContext evalutes to object
++typeof javax.script.ScriptEngine evalutes to object
++typeof java.util.Vector evalutes to function
++typeof java.util.Map evalutes to function
++typeof java.util.HashMap evalutes to function
++var m = new java.util.HashMap(); m.put('foo', 42); m evalutes to {foo=42}
++java.lang.System.out.println evalutes to [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println]
++java.lang.System.exit evalutes to [jdk.internal.dynalink.beans.SimpleDynamicMethod void java.lang.System.exit(int)]
++new javax.script.SimpleBindings throws java.lang.RuntimeException: java.lang.ClassNotFoundException: javax.script.SimpleBindings
++Java.type('javax.script.ScriptContext') throws java.lang.RuntimeException: java.lang.ClassNotFoundException: javax.script.ScriptContext
++java.lang.Class.forName('javax.script.ScriptContext') throws javax.script.ScriptException: TypeError: Java reflection not supported when class filter is present in <eval> at line number 1
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/trusted/classfilter_extends.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,53 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8036987
++ * @run
++ */
++
++var factory = Java.type('jdk.nashorn.api.scripting.NashornScriptEngineFactory')
++var engine = new factory().getScriptEngine(function(str){
++ return str.indexOf('java.lang.Class') != -1
++ || str == 'java.lang.System'
++ || str.indexOf('java.util') != -1;
++})
++
++function tryEval (str) {
++ try {
++ print(eval(str))
++ print(engine.eval(str))
++ } catch (exc) {
++ print(exc.message)
++ }
++}
++
++tryEval("Java.type('java.util.ArrayList')")
++tryEval("Java.type('java.lang.String')")
++tryEval("java.util.ArrayList")
++tryEval("java.lang.String")
++tryEval("Java.extend(java.util.ArrayList, {})")
++tryEval("Java.extend(java.io.File, {})")
++tryEval("new java.lang.NullPointerException();")
++tryEval("try { java.lang.System.load(null) } catch (e) { e }")
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/trusted/classfilter_extends.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,16 @@
++[JavaClass java.util.ArrayList]
++[JavaClass java.util.ArrayList]
++[JavaClass java.lang.String]
++java.lang.ClassNotFoundException: java.lang.String
++[JavaClass java.util.ArrayList]
++[JavaClass java.util.ArrayList]
++[JavaClass java.lang.String]
++[JavaPackage java.lang.String]
++[JavaClass jdk.nashorn.javaadapters.java.util.ArrayList]
++[JavaClass jdk.nashorn.javaadapters.java.util.ArrayList]
++[JavaClass jdk.nashorn.javaadapters.java.io.File]
++TypeError: Java.extend needs Java types as its arguments. in <eval> at line number 1
++java.lang.NullPointerException
++java.lang.ClassNotFoundException: java.lang.NullPointerException
++java.lang.NullPointerException: library can't be null
++java.lang.NullPointerException: library can't be null
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/trusted/classfilter_mozilla_compat.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * @test
++ * @bug 8036987
++ * @run
++ */
++
++var factory = Java.type('jdk.nashorn.api.scripting.NashornScriptEngineFactory')
++var engine = new factory().getScriptEngine(function(str){
++ return str.indexOf('java.util') != -1;
++})
++
++load("nashorn:mozilla_compat.js");
++engine.eval("load('nashorn:mozilla_compat.js');")
++
++function tryEval (str) {
++ try {
++ print(eval(str))
++ print(engine.eval(str))
++ } catch (exc) {
++ print(exc.message)
++ }
++}
++
++tryEval("new JavaAdapter(javax.script.ScriptContext){}.class")
++tryEval("new JavaAdapter(java.util.ArrayList){}.class")
++tryEval("importClass(java.lang.Integer); Integer")
++tryEval("importClass(java.util.HashSet); HashSet")
++tryEval("importPackage(java.lang); Integer")
++tryEval("importPackage(java.util); HashMap")
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/trusted/classfilter_mozilla_compat.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,12 @@
++class javax.script.ScriptContext$$NashornJavaAdapter
++TypeError: Java.extend needs at least one type argument. in nashorn:mozilla_compat.js at line number 39
++class jdk.nashorn.javaadapters.java.util.ArrayList
++class jdk.nashorn.javaadapters.java.util.ArrayList
++[JavaClass java.lang.Integer]
++TypeError: [object JavaPackage] is not a Java class in nashorn:mozilla_compat.js at line number 373 at column number 16
++[JavaClass java.util.HashSet]
++[JavaClass java.util.HashSet]
++[JavaClass java.lang.Integer]
++ReferenceError: "Integer" is not defined in nashorn:mozilla_compat.js at line number 67
++[JavaClass java.util.HashMap]
++[JavaClass java.util.HashMap]
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/trusted/event_queue.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,123 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Debug.eventqueue test - instead of screen scraping, test the concept of asking Debug for
++ * an event log of favourable events.
++ *
++ * @test
++ * @fork
++ * @option -Dnashorn.debug=true
++ * @option --log=recompile:quiet
++ * @option --optimistic-types=true
++ */
++
++print(Debug);
++print();
++
++var forName = java.lang.Class["forName(String)"];
++var RuntimeEvent = forName("jdk.nashorn.internal.runtime.events.RuntimeEvent").static;
++var getValue = RuntimeEvent.class.getMethod("getValue");
++var getValueClass = RuntimeEvent.class.getMethod("getValueClass");
++
++print(RuntimeEvent);
++
++var RewriteException = forName("jdk.nashorn.internal.runtime.RewriteException").static;
++var getReturnType = RewriteException.class.getMethod("getReturnType");
++
++print(RewriteException);
++
++var a = [1.1, 2.2];
++function f() {
++ var sum = 2;
++ for (var i = 0; i < a.length; i++) {
++ sum *= a[i];
++ }
++ return sum;
++}
++
++function g() {
++ var diff = 17;
++ for (var i = 0; i < a.length; i++) {
++ diff -= a[i];
++ }
++ return diff;
++}
++
++//kill anything that may already be in the event queue from earlier debug runs
++Debug.clearRuntimeEvents();
++
++print();
++print(f());
++print(g());
++
++print();
++events = Debug.getRuntimeEvents();
++print("Done with " + events.length + " in the event queue");
++//make sure we got runtime events
++print("events = " + (events.toString().indexOf("RuntimeEvent") != -1));
++print("events.length = " + events.length);
++
++var lastInLoop = undefined;
++for (var i = 0; i < events.length; i++) {
++ var e = events[i];
++ print("event #" + i);
++ print("\tevent class=" + e.getClass());
++ print("\tvalueClass in event=" + getValueClass.invoke(e));
++ var v = getValue.invoke(e);
++ print("\tclass of value=" + v.getClass());
++ print("\treturn type=" + getReturnType.invoke(v));
++ lastInLoop = events[i];
++}
++
++print();
++print("in loop last class = " + lastInLoop.getClass());
++print("in loop last value class = " + getValueClass.invoke(lastInLoop));
++var rexInLoop = getValue.invoke(lastInLoop);
++print("in loop rex class = " + rexInLoop.getClass());
++print("in loop rex return type = " + getReturnType.invoke(rexInLoop));
++
++//try last runtime events
++var last = Debug.getLastRuntimeEvent();
++//the code after the loop creates additional rewrite exceptions
++print();
++print(last !== lastInLoop);
++print();
++
++print("last class = " + last.getClass());
++print("last value class = " + getValueClass.invoke(last));
++var rex = getValue.invoke(last);
++print("rex class = " + rex.getClass());
++print("rex return type = " + getReturnType.invoke(rex));
++
++//try the capacity setter
++print();
++print(Debug.getEventQueueCapacity());
++Debug.setEventQueueCapacity(2048);
++print(Debug.getEventQueueCapacity());
++
++//try clear events
++print();
++Debug.clearRuntimeEvents();
++print(Debug.getRuntimeEvents().length);
++
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/trusted/event_queue.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,38 @@
++[object Debug]
++
++[JavaClass jdk.nashorn.internal.runtime.events.RuntimeEvent]
++[JavaClass jdk.nashorn.internal.runtime.RewriteException]
++
++4.840000000000001
++13.7
++
++Done with 2 in the event queue
++events = true
++events.length = 2
++event #0
++ event class=class jdk.nashorn.internal.runtime.events.RecompilationEvent
++ valueClass in event=class jdk.nashorn.internal.runtime.RewriteException
++ class of value=class jdk.nashorn.internal.runtime.RewriteException
++ return type=double
++event #1
++ event class=class jdk.nashorn.internal.runtime.events.RecompilationEvent
++ valueClass in event=class jdk.nashorn.internal.runtime.RewriteException
++ class of value=class jdk.nashorn.internal.runtime.RewriteException
++ return type=double
++
++in loop last class = class jdk.nashorn.internal.runtime.events.RecompilationEvent
++in loop last value class = class jdk.nashorn.internal.runtime.RewriteException
++in loop rex class = class jdk.nashorn.internal.runtime.RewriteException
++in loop rex return type = double
++
++true
++
++last class = class jdk.nashorn.internal.runtime.events.RecompilationEvent
++last value class = class jdk.nashorn.internal.runtime.RewriteException
++rex class = class jdk.nashorn.internal.runtime.RewriteException
++rex return type = object
++
++1024
++2048
++
++0
+--- ./nashorn/test/script/trusted/getenv.js Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/script/trusted/getenv.js Wed Feb 04 12:14:47 2015 -0800
+@@ -1,21 +1,21 @@
+ /*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
++ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+- *
++ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+- *
++ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
++ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/trusted/optimistic_recompilation.js Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,83 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/**
++ * Ask Debug for an event log of favourable events instead of using --log flags printing to screen
++ * @test
++ * @bug 8037086,8038398
++ * @fork
++ * @option -Dnashorn.debug=true
++ * @option --log=recompile:quiet
++ * @option --optimistic-types=true
++ */
++
++var forName = java.lang.Class["forName(String)"];
++var RuntimeEvent = forName("jdk.nashorn.internal.runtime.events.RuntimeEvent").static;
++var getValue = RuntimeEvent.class.getMethod("getValue");
++var RewriteException = forName("jdk.nashorn.internal.runtime.RewriteException").static;
++var getReturnType = RewriteException.class.getMethod("getReturnType");
++var RecompilationEvent = forName("jdk.nashorn.internal.runtime.events.RecompilationEvent").static;
++var getReturnValue = RecompilationEvent.class.getMethod("getReturnValue");
++var setReturnTypeAndValue = [];
++var expectedValues = [];
++
++function checkExpectedRecompilation(f, expectedValues, testCase) {
++ Debug.clearRuntimeEvents();
++ print(f());
++ events = Debug.getRuntimeEvents();
++ //make sure we got runtime events
++ print("events = " + (events.toString().indexOf("RuntimeEvent") != -1));
++ if (events.length == expectedValues.length) {
++ for (var i in events) {
++ var e = events[i];
++ var returnValue = getReturnValue.invoke(e);
++ if (typeof returnValue != 'undefined') {
++ setReturnTypeAndValue[i] = [getReturnType.invoke(getValue.invoke(e)), returnValue];
++ } else {
++ returnValue = "undefined";
++ setReturnTypeAndValue[i] = [getReturnType.invoke(getValue.invoke(e)), returnValue];
++ }
++ if (!setReturnTypeAndValue[i].toString().equals(expectedValues[i].toString())) {
++ fail("The return values are not as expected. Expected value: " + expectedValues[i] + " and got: " + setReturnTypeAndValue[i] + " in test case: " + f);
++ }
++ }
++ } else {
++ fail("Number of Deoptimizing recompilation is not correct, expected: " + expectedValues.length + " and found: " + events.length + " in test case: " + f);
++ }
++}
++
++checkExpectedRecompilation(function divisionByZeroTest() {var x = { a: 2, b:1 }; x.a = Number.POSITIVE_INFINITY; x.b = 0; print(x.a/x.b); return 1;},
++ expectedValues =[['double', 'Infinity']]);
++checkExpectedRecompilation(function divisionWithRemainderTest() {var x = { a: 7, b:2 }; print(x.a/x.b); return 1;}, expectedValues =[['double', '3.5']]);
++checkExpectedRecompilation(function infinityMultiplicationTest() {var x = { a: Number.POSITIVE_INFINITY, b: Number.POSITIVE_INFINITY}; print(x.a*x.b); return 1;},
++ expectedValues =[['double', 'Infinity']]);
++checkExpectedRecompilation(function maxValueMultiplicationTest() {var x = { a: Number.MAX_VALUE, b: Number.MAX_VALUE}; print(x.a*x.b); return 1;},
++ expectedValues =[['double', '1.7976931348623157e+308']]);
++checkExpectedRecompilation(function divisionByInfinityTest() {var x = { a: -1, b: Number.POSITIVE_INFINITY}; print(x.a/x.b); return 1;},
++ expectedValues =[['double', 'Infinity']]);
++checkExpectedRecompilation(function divisionByStringTest() {var x = { a: Number.POSITIVE_INFINITY, b: 'Hello'}; print(x.a/x.b); return 1;},
++ expectedValues =[['double', 'Infinity']]);
++checkExpectedRecompilation(function nestedFunctionTest() {var a=3,b,c; function f() {var x = 2, y =1; function g(){var y = x; var z = a; z = x*y; print(a*b)} g()}f(); return 1;},
++ expectedValues =[['object', 'undefined']]);
++checkExpectedRecompilation(function functionTest(a,b,c) { d = (a + b) * c; print(d); return 1;}, expectedValues =[['double', 'NaN']]);
++checkExpectedRecompilation(function andTest(a,b) { d = a && b; print(d); return 1;}, expectedValues =[['object', 'undefined']]);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/script/trusted/optimistic_recompilation.js.EXPECTED Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,27 @@
++Infinity
++1
++events = true
++3.5
++1
++events = true
++Infinity
++1
++events = true
++Infinity
++1
++events = true
++0
++1
++events = true
++NaN
++1
++events = true
++NaN
++1
++events = true
++NaN
++1
++events = true
++undefined
++1
++events = true
+--- ./nashorn/test/src/UnnamedPackageTestCallback.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/UnnamedPackageTestCallback.java Wed Feb 04 12:14:47 2015 -0800
+@@ -23,6 +23,14 @@
+ * questions.
+ */
+
++/**
++ * Interface for callbacks used by the test suite.
++ */
+ public interface UnnamedPackageTestCallback {
++ /**
++ * Call function
++ * @param s string argument
++ * @return string
++ */
+ String call(String s);
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/src/jdk/internal/dynalink/beans/CallerSensitiveTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.internal.dynalink.beans;
++
++import jdk.nashorn.test.models.ClassLoaderAware;
++import org.testng.annotations.Test;
++
++@SuppressWarnings("javadoc")
++public class CallerSensitiveTest {
++ @Test
++ public void testCallerSensitive() {
++ BeansLinker.getLinkerForClass(ClassLoaderAware.class);
++ }
++}
+--- ./nashorn/test/src/jdk/nashorn/api/NashornSQLDriver.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/NashornSQLDriver.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,7 +25,12 @@
+
+ package jdk.nashorn.api;
+
+-import java.sql.*;
++import java.sql.Connection;
++import java.sql.Driver;
++import java.sql.DriverManager;
++import java.sql.DriverPropertyInfo;
++import java.sql.SQLException;
++import java.sql.SQLFeatureNotSupportedException;
+ import java.util.Properties;
+ import java.util.logging.Logger;
+
+@@ -36,18 +41,18 @@
+ static {
+ try {
+ DriverManager.registerDriver(new NashornSQLDriver(), null);
+- } catch (SQLException se) {
++ } catch (final SQLException se) {
+ throw new RuntimeException(se);
+ }
+ }
+
+ @Override
+- public boolean acceptsURL(String url) {
++ public boolean acceptsURL(final String url) {
+ return url.startsWith("jdbc:nashorn:");
+ }
+
+ @Override
+- public Connection connect(String url, Properties info) {
++ public Connection connect(final String url, final Properties info) {
+ throw new UnsupportedOperationException("I am a dummy!!");
+ }
+
+@@ -62,7 +67,7 @@
+ }
+
+ @Override
+- public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) {
++ public DriverPropertyInfo[] getPropertyInfo(final String url, final Properties info) {
+ return new DriverPropertyInfo[0];
+ }
+
+--- ./nashorn/test/src/jdk/nashorn/api/javaaccess/ArrayConversionTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/javaaccess/ArrayConversionTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,7 +29,6 @@
+ import static org.testng.AssertJUnit.assertFalse;
+ import static org.testng.AssertJUnit.assertNull;
+ import static org.testng.AssertJUnit.assertTrue;
+-
+ import java.util.Arrays;
+ import java.util.List;
+ import javax.script.ScriptContext;
+@@ -41,6 +40,7 @@
+ import org.testng.annotations.BeforeClass;
+ import org.testng.annotations.Test;
+
++@SuppressWarnings("javadoc")
+ public class ArrayConversionTest {
+ private static ScriptEngine e = null;
+
+@@ -49,7 +49,7 @@
+ }
+
+ @BeforeClass
+- public static void setUpClass() throws ScriptException {
++ public static void setUpClass() {
+ e = new ScriptEngineManager().getEngineByName("nashorn");
+ }
+
+@@ -111,25 +111,25 @@
+ e.eval("Java.type('" + ArrayConversionTest.class.getName() + "')." + testMethodName + "(" + argument + ")");
+ }
+
+- public static void assertNullIntArray(int[] array) {
++ public static void assertNullIntArray(final int[] array) {
+ assertNull(array);
+ }
+
+- public static void assertNullIntIntArray(int[][] array) {
++ public static void assertNullIntIntArray(final int[][] array) {
+ assertNull(array);
+ }
+
+- public static void assertEmptyIntArray(int[] array) {
++ public static void assertEmptyIntArray(final int[] array) {
+ assertEquals(0, array.length);
+ }
+
+- public static void assertSingle42IntArray(int[] array) {
++ public static void assertSingle42IntArray(final int[] array) {
+ assertEquals(1, array.length);
+ assertEquals(42, array[0]);
+ }
+
+
+- public static void assertIntArrayConversions(int[] array) {
++ public static void assertIntArrayConversions(final int[] array) {
+ assertEquals(13, array.length);
+ assertEquals(0, array[0]); // false
+ assertEquals(1, array[1]); // true
+@@ -146,21 +146,21 @@
+ assertEquals(0, array[12]); // [1, 2]
+ }
+
+- public static void assertEmptyIntIntArray(int[][] array) {
++ public static void assertEmptyIntIntArray(final int[][] array) {
+ assertEquals(0, array.length);
+ }
+
+- public static void assertSingleEmptyIntIntArray(int[][] array) {
++ public static void assertSingleEmptyIntIntArray(final int[][] array) {
+ assertEquals(1, array.length);
+ assertTrue(Arrays.equals(new int[0], array[0]));
+ }
+
+- public static void assertSingleNullIntIntArray(int[][] array) {
++ public static void assertSingleNullIntIntArray(final int[][] array) {
+ assertEquals(1, array.length);
+ assertNull(null, array[0]);
+ }
+
+- public static void assertLargeIntIntArray(int[][] array) {
++ public static void assertLargeIntIntArray(final int[][] array) {
+ assertEquals(5, array.length);
+ assertTrue(Arrays.equals(new int[] { 0 }, array[0]));
+ assertTrue(Arrays.equals(new int[] { 1 }, array[1]));
+@@ -169,7 +169,7 @@
+ assertTrue(Arrays.equals(new int[] { 7, 8 }, array[4]));
+ }
+
+- public static void assertLargeObjectObjectArray(Object[][] array) throws ScriptException {
++ public static void assertLargeObjectObjectArray(final Object[][] array) throws ScriptException {
+ assertEquals(4, array.length);
+ assertTrue(Arrays.equals(new Object[] { Boolean.FALSE }, array[0]));
+ assertTrue(Arrays.equals(new Object[] { 1 }, array[1]));
+@@ -179,7 +179,7 @@
+ assertEquals(17, e.eval("obj.x"));
+ }
+
+- public static void assertBooleanArrayConversions(boolean[] array) {
++ public static void assertBooleanArrayConversions(final boolean[] array) {
+ assertEquals(16, array.length);
+ assertFalse(array[0]); // false
+ assertTrue(array[1]); // true
+@@ -199,26 +199,26 @@
+ assertFalse(array[15]); // undefined
+ }
+
+- public static void assertListArray(List<?>[] array) {
++ public static void assertListArray(final List<?>[] array) {
+ assertEquals(2, array.length);
+ assertEquals(Arrays.asList("foo", "bar"), array[0]);
+ assertEquals(Arrays.asList("apple", "orange"), array[1]);
+ }
+
+- public static void assertVarArg_42_17(Object... args) throws ScriptException {
++ public static void assertVarArg_42_17(final Object... args) {
+ assertEquals(2, args.length);
+ assertEquals(42, ((Number)args[0]).intValue());
+ assertEquals(17, ((Number)args[1]).intValue());
+ }
+
+- public static void assertVarArg_array_17(Object... args) throws ScriptException {
++ public static void assertVarArg_array_17(final Object... args) throws ScriptException {
+ assertEquals(2, args.length);
+ e.getBindings(ScriptContext.ENGINE_SCOPE).put("arr", args[0]);
+ assertTrue((Boolean)e.eval("arr instanceof Array && arr.length == 1 && arr[0] == 42"));
+ assertEquals(18, ((Number)args[1]).intValue());
+ }
+
+- public static void assertVarArg_function(Object... args) throws ScriptException {
++ public static void assertVarArg_function(final Object... args) throws ScriptException {
+ assertEquals(1, args.length);
+ e.getBindings(ScriptContext.ENGINE_SCOPE).put("fn", args[0]);
+ assertEquals("Hello", e.eval("fn()"));
+@@ -226,10 +226,10 @@
+
+
+
+- public static void x(String y) {
++ public static void x(final String y) {
+ assertEquals("abc", y);
+ }
+- public static void x(String[] y) {
++ public static void x(final String[] y) {
+ assertTrue(Arrays.equals(new String[] { "foo", "bar"}, y));
+ }
+ }
+--- ./nashorn/test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,7 +27,6 @@
+
+ import static org.testng.AssertJUnit.assertEquals;
+ import static org.testng.AssertJUnit.assertTrue;
+-
+ import java.util.Arrays;
+ import javax.script.ScriptEngine;
+ import javax.script.ScriptEngineManager;
+@@ -42,6 +41,7 @@
+ * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.BooleanAccessTest
+ * @run testng/othervm jdk.nashorn.api.javaaccess.BooleanAccessTest
+ */
++@SuppressWarnings("javadoc")
+ public class BooleanAccessTest {
+
+ private static ScriptEngine e = null;
+--- ./nashorn/test/src/jdk/nashorn/api/javaaccess/ConsStringTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/javaaccess/ConsStringTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,7 +26,6 @@
+ package jdk.nashorn.api.javaaccess;
+
+ import static org.testng.AssertJUnit.assertEquals;
+-
+ import java.util.HashMap;
+ import java.util.Map;
+ import javax.script.Bindings;
+@@ -40,6 +39,7 @@
+ import org.testng.annotations.BeforeClass;
+ import org.testng.annotations.Test;
+
++@SuppressWarnings("javadoc")
+ public class ConsStringTest {
+ private static ScriptEngine e = null;
+
+@@ -48,7 +48,7 @@
+ }
+
+ @BeforeClass
+- public static void setUpClass() throws ScriptException {
++ public static void setUpClass() {
+ e = new ScriptEngineManager().getEngineByName("nashorn");
+ }
+
+@@ -69,7 +69,7 @@
+ @Test
+ public void testConsStringFromMirror() throws ScriptException {
+ final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE);
+- final Map<Object, Object> m = new HashMap<>();
++ //final Map<Object, Object> m = new HashMap<>();
+ e.eval("var x = 'f'; x += 'oo'; var obj = {x: x};");
+ assertEquals("foo", ((JSObject)b.get("obj")).getMember("x"));
+ }
+@@ -88,7 +88,7 @@
+ public static class ArrayHolder {
+ private Object[] array;
+
+- public void setArray(Object[] array) {
++ public void setArray(final Object[] array) {
+ this.array = array;
+ }
+
+--- ./nashorn/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,7 +28,6 @@
+ import static org.testng.AssertJUnit.assertEquals;
+ import static org.testng.AssertJUnit.assertTrue;
+ import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
+-
+ import java.util.Arrays;
+ import java.util.Calendar;
+ import java.util.Locale;
+@@ -45,6 +44,7 @@
+ * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.MethodAccessTest
+ * @run testng/othervm jdk.nashorn.api.javaaccess.MethodAccessTest
+ */
++@SuppressWarnings("javadoc")
+ public class MethodAccessTest {
+
+ private static ScriptEngine e = null;
+--- ./nashorn/test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,7 +28,6 @@
+ import static org.testng.AssertJUnit.assertEquals;
+ import static org.testng.AssertJUnit.assertTrue;
+ import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
+-
+ import javax.script.ScriptEngine;
+ import javax.script.ScriptEngineManager;
+ import javax.script.ScriptException;
+@@ -42,10 +41,11 @@
+ * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.NumberAccessTest
+ * @run testng/othervm jdk.nashorn.api.javaaccess.NumberAccessTest
+ */
++@SuppressWarnings("javadoc")
+ public class NumberAccessTest {
+
+- private static ScriptEngine e = null;
+- private static SharedObject o = null;
++ private static ScriptEngine e;
++ private static SharedObject o;
+
+ public static void main(final String[] args) {
+ TestNG.main(args);
+@@ -264,7 +264,7 @@
+ @Test
+ public void accessFieldByte() throws ScriptException {
+ e.eval("var p_byte = o.publicByte;");
+- assertEquals(o.publicByte, e.get("p_byte"));
++ assertEquals((double)o.publicByte, ((Number)e.get("p_byte")).doubleValue());
+ e.eval("o.publicByte = 16;");
+ assertEquals(16, o.publicByte);
+ }
+@@ -287,7 +287,7 @@
+ @Test
+ public void accessStaticFieldByte() throws ScriptException {
+ e.eval("var ps_byte = SharedObject.publicStaticByte;");
+- assertEquals(SharedObject.publicStaticByte, e.get("ps_byte"));
++ assertEquals((double)SharedObject.publicStaticByte, ((Number)e.get("ps_byte")).doubleValue());
+ e.eval("SharedObject.publicStaticByte = 16;");
+ assertEquals(16, SharedObject.publicStaticByte);
+ }
+@@ -310,7 +310,7 @@
+ @Test
+ public void accessFinalFieldByte() throws ScriptException {
+ e.eval("var pf_byte = o.publicFinalByte;");
+- assertEquals(o.publicFinalByte, e.get("pf_byte"));
++ assertEquals((double)o.publicFinalByte, ((Number)e.get("pf_byte")).doubleValue());
+ e.eval("o.publicFinalByte = 16;");
+ assertEquals(-7, o.publicFinalByte);
+ }
+@@ -333,7 +333,7 @@
+ @Test
+ public void accessStaticFinalFieldByte() throws ScriptException {
+ e.eval("var psf_byte = SharedObject.publicStaticFinalByte;");
+- assertEquals(SharedObject.publicStaticFinalByte, e.get("psf_byte"));
++ assertEquals((double)SharedObject.publicStaticFinalByte, ((Number)e.get("psf_byte")).doubleValue());
+ e.eval("SharedObject.publicStaticFinalByte = 16;");
+ assertEquals(-70, SharedObject.publicStaticFinalByte);
+ }
+@@ -358,7 +358,7 @@
+ @Test
+ public void accessFieldShort() throws ScriptException {
+ e.eval("var p_short = o.publicShort;");
+- assertEquals(o.publicShort, e.get("p_short"));
++ assertEquals((double)o.publicShort, ((Number)e.get("p_short")).doubleValue());
+ e.eval("o.publicShort = 18;");
+ assertEquals(18, o.publicShort);
+ }
+@@ -381,7 +381,7 @@
+ @Test
+ public void accessStaticFieldShort() throws ScriptException {
+ e.eval("var ps_short = SharedObject.publicStaticShort;");
+- assertEquals(SharedObject.publicStaticShort, e.get("ps_short"));
++ assertEquals((double)SharedObject.publicStaticShort, ((Number)e.get("ps_short")).doubleValue());
+ e.eval("SharedObject.publicStaticShort = 180;");
+ assertEquals(180, SharedObject.publicStaticShort);
+ }
+@@ -404,7 +404,7 @@
+ @Test
+ public void accessFinalFieldShort() throws ScriptException {
+ e.eval("var pf_short = o.publicFinalShort;");
+- assertEquals(o.publicFinalShort, e.get("pf_short"));
++ assertEquals((double)o.publicFinalShort, ((Number)e.get("pf_short")).doubleValue());
+ e.eval("o.publicFinalShort = 180;");
+ assertEquals(31220, o.publicFinalShort);
+ }
+@@ -427,7 +427,7 @@
+ @Test
+ public void accessStaticFinalFieldShort() throws ScriptException {
+ e.eval("var psf_short = SharedObject.publicStaticFinalShort;");
+- assertEquals(SharedObject.publicStaticFinalShort, e.get("psf_short"));
++ assertEquals((double)SharedObject.publicStaticFinalShort, ((Number)e.get("psf_short")).doubleValue());
+ e.eval("SharedObject.publicStaticFinalShort = 180;");
+ assertEquals(8888, SharedObject.publicStaticFinalShort);
+ }
+@@ -555,7 +555,7 @@
+ @Test
+ public void accessFieldFloat() throws ScriptException {
+ e.eval("var p_float = o.publicFloat;");
+- assertEquals(o.publicFloat, e.get("p_float"));
++ assertEquals((double)o.publicFloat, ((Number)e.get("p_float")).doubleValue());
+ o.publicFloat = 0.0f / 0.0f;
+ assertEquals(true, e.eval("isNaN(o.publicFloat)"));
+ o.publicFloat = 1.0f / 0.0f;
+@@ -590,7 +590,7 @@
+ @Test
+ public void accessStaticFieldFloat() throws ScriptException {
+ e.eval("var ps_float = SharedObject.publicStaticFloat;");
+- assertEquals(SharedObject.publicStaticFloat, e.get("ps_float"));
++ assertEquals((double)SharedObject.publicStaticFloat, ((Number)e.get("ps_float")).doubleValue());
+ SharedObject.publicStaticFloat = 0.0f / 0.0f;
+ assertEquals(true, e.eval("isNaN(SharedObject.publicStaticFloat)"));
+ SharedObject.publicStaticFloat = 1.0f / 0.0f;
+@@ -625,7 +625,7 @@
+ @Test
+ public void accessFinalFloat() throws ScriptException {
+ e.eval("var pf_float = o.publicFinalFloat;");
+- assertEquals(o.publicFinalFloat, e.get("pf_float"));
++ assertEquals((double)o.publicFinalFloat, ((Number)e.get("pf_float")).doubleValue());
+ e.eval("o.publicFinalFloat = 20.0;");
+ assertEquals(7.72e8f, o.publicFinalFloat, 1e-10);
+ }
+@@ -648,7 +648,7 @@
+ @Test
+ public void accessStaticFinalFieldFloat() throws ScriptException {
+ e.eval("var psf_float = SharedObject.publicStaticFinalFloat;");
+- assertEquals(SharedObject.publicStaticFinalFloat, e.get("psf_float"));
++ assertEquals((double)SharedObject.publicStaticFinalFloat, ((Number)e.get("psf_float")).doubleValue());
+ e.eval("SharedObject.publicStaticFinalFloat = 20.0;");
+ assertEquals(0.72e8f, SharedObject.publicStaticFinalFloat, 1e-10);
+ }
+--- ./nashorn/test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,7 +27,6 @@
+
+ import static org.testng.AssertJUnit.assertEquals;
+ import static org.testng.AssertJUnit.assertTrue;
+-
+ import javax.script.ScriptEngine;
+ import javax.script.ScriptEngineManager;
+ import javax.script.ScriptException;
+@@ -41,10 +40,11 @@
+ * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.NumberBoxingTest
+ * @run testng/othervm jdk.nashorn.api.javaaccess.NumberBoxingTest
+ */
++@SuppressWarnings("javadoc")
+ public class NumberBoxingTest {
+
+- private static ScriptEngine e = null;
+- private static SharedObject o = null;
++ private static ScriptEngine e;
++ private static SharedObject o;
+
+ public static void main(final String[] args) {
+ TestNG.main(args);
+@@ -77,10 +77,10 @@
+
+ @Test
+ public void accessStaticFieldLongBoxing() throws ScriptException {
+- e.eval("var ps_long = SharedObject.publicStaticLong;");
+- assertEquals(SharedObject.publicStaticLong, e.get("ps_long"));
+- e.eval("SharedObject.publicStaticLong = 120;");
+- assertEquals(120, SharedObject.publicStaticLong);
++ e.eval("var ps_long = SharedObject.publicStaticLongBox;");
++ assertEquals(SharedObject.publicStaticLongBox, e.get("ps_long"));
++ e.eval("SharedObject.publicStaticLongBox = 120;");
++ assertEquals(120L, SharedObject.publicStaticLongBox.longValue());
+ }
+
+ @Test
+@@ -138,7 +138,7 @@
+ @Test
+ public void accessFieldByteBoxing() throws ScriptException {
+ e.eval("var p_byte = o.publicByteBox;");
+- assertEquals(o.publicByteBox, e.get("p_byte"));
++ assertEqualsDouble(o.publicByteBox, "p_byte");
+ e.eval("o.publicByteBox = 16;");
+ assertEquals(Byte.valueOf((byte)16), o.publicByteBox);
+ }
+@@ -146,7 +146,7 @@
+ @Test
+ public void accessStaticFieldByteBoxing() throws ScriptException {
+ e.eval("var ps_byte = SharedObject.publicStaticByte;");
+- assertEquals(SharedObject.publicStaticByte, e.get("ps_byte"));
++ assertEqualsDouble(SharedObject.publicStaticByte, "ps_byte");
+ e.eval("SharedObject.publicStaticByte = 16;");
+ assertEquals(16, SharedObject.publicStaticByte);
+ }
+@@ -154,7 +154,7 @@
+ @Test
+ public void accessFinalFieldByteBoxing() throws ScriptException {
+ e.eval("var pf_byte = o.publicFinalByteBox;");
+- assertEquals(o.publicFinalByteBox, e.get("pf_byte"));
++ assertEqualsDouble(o.publicFinalByteBox, "pf_byte");
+ e.eval("o.publicFinalByteBox = 16;");
+ assertEquals(Byte.valueOf((byte)19), o.publicFinalByteBox);
+ }
+@@ -162,7 +162,7 @@
+ @Test
+ public void accessStaticFinalFieldByteBoxing() throws ScriptException {
+ e.eval("var psf_byte = SharedObject.publicStaticFinalByte;");
+- assertEquals(SharedObject.publicStaticFinalByte, e.get("psf_byte"));
++ assertEqualsDouble(SharedObject.publicStaticFinalByte, "psf_byte");
+ e.eval("SharedObject.publicStaticFinalByte = 16;");
+ assertEquals(-70, SharedObject.publicStaticFinalByte);
+ }
+@@ -172,15 +172,19 @@
+ @Test
+ public void accessFieldShortBoxing() throws ScriptException {
+ e.eval("var p_short = o.publicShortBox;");
+- assertEquals(o.publicShortBox, e.get("p_short"));
++ assertEqualsDouble(o.publicShortBox, "p_short");
+ e.eval("o.publicShortBox = 18;");
+ assertEquals(Short.valueOf((short)18), o.publicShortBox);
+ }
+
++ private static void assertEqualsDouble(final Number n, final String name) {
++ assertEquals(n.doubleValue(), ((Number)e.get(name)).doubleValue());
++ }
++
+ @Test
+ public void accessStaticFieldShortBoxing() throws ScriptException {
+ e.eval("var ps_short = SharedObject.publicStaticShort;");
+- assertEquals(SharedObject.publicStaticShort, e.get("ps_short"));
++ assertEqualsDouble(SharedObject.publicStaticShort, "ps_short");
+ e.eval("SharedObject.publicStaticShort = 180;");
+ assertEquals(180, SharedObject.publicStaticShort);
+ }
+@@ -188,7 +192,7 @@
+ @Test
+ public void accessFinalFieldShortBoxing() throws ScriptException {
+ e.eval("var pf_short = o.publicFinalShortBox;");
+- assertEquals(o.publicFinalShortBox, e.get("pf_short"));
++ assertEqualsDouble(o.publicFinalShortBox, "pf_short");
+ e.eval("o.publicFinalShortBox = 180;");
+ assertEquals(Short.valueOf((short)-26777), o.publicFinalShortBox);
+ }
+@@ -196,7 +200,7 @@
+ @Test
+ public void accessStaticFinalFieldShortBoxing() throws ScriptException {
+ e.eval("var psf_short = SharedObject.publicStaticFinalShort;");
+- assertEquals(SharedObject.publicStaticFinalShort, e.get("psf_short"));
++ assertEqualsDouble(SharedObject.publicStaticFinalShort, "psf_short");
+ e.eval("SharedObject.publicStaticFinalShort = 180;");
+ assertEquals(8888, SharedObject.publicStaticFinalShort);
+ }
+@@ -247,7 +251,7 @@
+ @Test
+ public void accessFieldFloatBoxing() throws ScriptException {
+ e.eval("var p_float = o.publicFloatBox;");
+- assertEquals(o.publicFloatBox, e.get("p_float"));
++ assertEqualsDouble(o.publicFloatBox, "p_float");
+ o.publicFloatBox = 0.0f / 0.0f;
+ assertEquals(true, e.eval("isNaN(o.publicFloatBox)"));
+ o.publicFloatBox = 1.0f / 0.0f;
+@@ -267,7 +271,7 @@
+ @Test
+ public void accessStaticFieldFloatBoxing() throws ScriptException {
+ e.eval("var ps_float = SharedObject.publicStaticFloat;");
+- assertEquals(SharedObject.publicStaticFloat, e.get("ps_float"));
++ assertEqualsDouble(SharedObject.publicStaticFloat, "ps_float");
+ SharedObject.publicStaticFloat = 0.0f / 0.0f;
+ assertEquals(true, e.eval("isNaN(SharedObject.publicStaticFloat)"));
+ SharedObject.publicStaticFloat = 1.0f / 0.0f;
+@@ -287,7 +291,7 @@
+ @Test
+ public void accessFinalFloatBoxing() throws ScriptException {
+ e.eval("var pf_float = o.publicFinalFloatBox;");
+- assertEquals(o.publicFinalFloatBox, e.get("pf_float"));
++ assertEqualsDouble(o.publicFinalFloatBox, "pf_float");
+ e.eval("o.publicFinalFloatBox = 20.0;");
+ assertEquals(1.372e4f, o.publicFinalFloatBox, 1e-10);
+ }
+@@ -295,7 +299,7 @@
+ @Test
+ public void accessStaticFinalFieldFloatBoxing() throws ScriptException {
+ e.eval("var psf_float = SharedObject.publicStaticFinalFloat;");
+- assertEquals(SharedObject.publicStaticFinalFloat, e.get("psf_float"));
++ assertEqualsDouble(SharedObject.publicStaticFinalFloat, "psf_float");
+ e.eval("SharedObject.publicStaticFinalFloat = 20.0;");
+ assertEquals(0.72e8f, SharedObject.publicStaticFinalFloat, 1e-10);
+ }
+--- ./nashorn/test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,7 +27,6 @@
+
+ import static org.testng.AssertJUnit.assertEquals;
+ import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
+-
+ import javax.script.ScriptEngine;
+ import javax.script.ScriptEngineManager;
+ import javax.script.ScriptException;
+@@ -41,6 +40,7 @@
+ * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.ObjectAccessTest
+ * @run testng/othervm jdk.nashorn.api.javaaccess.ObjectAccessTest
+ */
++@SuppressWarnings("javadoc")
+ public class ObjectAccessTest {
+
+ private static ScriptEngine e = null;
+--- ./nashorn/test/src/jdk/nashorn/api/javaaccess/Person.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/javaaccess/Person.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package jdk.nashorn.api.javaaccess;
+
++@SuppressWarnings("javadoc")
+ public class Person {
+
+ public int id = 0;
+--- ./nashorn/test/src/jdk/nashorn/api/javaaccess/SharedObject.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/javaaccess/SharedObject.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,6 +29,7 @@
+ import javax.script.ScriptEngine;
+ import javax.script.ScriptException;
+
++@SuppressWarnings("javadoc")
+ public class SharedObject {
+
+ // Public fields
+@@ -51,7 +52,7 @@
+ public short publicShort = 32000;
+ public short[] publicShortArray = { 3240, 8900, -16789, 1, 12 };
+ public Short publicShortBox = Short.MIN_VALUE;
+- public float publicFloat = 0.7e6f;
++ public float publicFloat = 0.7f;
+ public float[] publicFloatArray = { -32.01f, 89.3f, -1.3e8f, 3.1f };
+ public Float publicFloatBox = 1.377e4f;
+ public double publicDouble = 1.34e20;
+@@ -162,7 +163,7 @@
+ return engine;
+ }
+
+- public void setEngine(ScriptEngine engine) {
++ public void setEngine(final ScriptEngine engine) {
+ this.engine = engine;
+ }
+
+@@ -414,51 +415,51 @@
+ t.start();
+ }
+
+- public String overloadedMethodDoubleVSint(int arg) {
++ public String overloadedMethodDoubleVSint(final int arg) {
+ return "int";
+ }
+
+- public String overloadedMethodDoubleVSint(double arg) {
++ public String overloadedMethodDoubleVSint(final double arg) {
+ return "double";
+ }
+
+- public int overloadedMethod(int arg) {
++ public int overloadedMethod(final int arg) {
+ return arg*2;
+ }
+
+- public int overloadedMethod(String arg) {
++ public int overloadedMethod(final String arg) {
+ return arg.length();
+ }
+
+- public int overloadedMethod(boolean arg) {
++ public int overloadedMethod(final boolean arg) {
+ return (arg) ? 1 : 0;
+ }
+
+- public int overloadedMethod(Person arg) {
++ public int overloadedMethod(final Person arg) {
+ return arg.id*2;
+ }
+
+- public int firstLevelMethodInt(int arg) throws ScriptException, NoSuchMethodException {
++ public int firstLevelMethodInt(final int arg) throws ScriptException, NoSuchMethodException {
+ return (int) ((Invocable)engine).invokeFunction("secondLevelMethodInt", arg);
+ }
+
+- public int thirdLevelMethodInt(int arg) {
++ public int thirdLevelMethodInt(final int arg) {
+ return arg*5;
+ }
+
+- public int firstLevelMethodInteger(Integer arg) throws ScriptException, NoSuchMethodException {
++ public int firstLevelMethodInteger(final Integer arg) throws ScriptException, NoSuchMethodException {
+ return (int) ((Invocable)engine).invokeFunction("secondLevelMethodInteger", arg);
+ }
+
+- public int thirdLevelMethodInteger(Integer arg) {
++ public int thirdLevelMethodInteger(final Integer arg) {
+ return arg*10;
+ }
+
+- public Person firstLevelMethodObject(Person p) throws ScriptException, NoSuchMethodException {
++ public Person firstLevelMethodObject(final Person p) throws ScriptException, NoSuchMethodException {
+ return (Person) ((Invocable)engine).invokeFunction("secondLevelMethodObject", p);
+ }
+
+- public Person thirdLevelMethodObject(Person p) {
++ public Person thirdLevelMethodObject(final Person p) {
+ p.id *= 10;
+ return p;
+ }
+--- ./nashorn/test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,7 +27,6 @@
+
+ import static org.testng.AssertJUnit.assertEquals;
+ import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
+-
+ import javax.script.ScriptEngine;
+ import javax.script.ScriptEngineManager;
+ import javax.script.ScriptException;
+@@ -41,6 +40,7 @@
+ * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.StringAccessTest
+ * @run testng/othervm jdk.nashorn.api.javaaccess.StringAccessTest
+ */
++@SuppressWarnings("javadoc")
+ public class StringAccessTest {
+
+ private static ScriptEngine e = null;
+--- ./nashorn/test/src/jdk/nashorn/api/scripting/InvocableTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/scripting/InvocableTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,8 @@
+
+ package jdk.nashorn.api.scripting;
+
++import static org.testng.Assert.assertEquals;
++import static org.testng.Assert.fail;
+ import java.util.Objects;
+ import java.util.function.Function;
+ import javax.script.Invocable;
+@@ -34,16 +36,15 @@
+ import javax.script.ScriptException;
+ import javax.script.SimpleScriptContext;
+ import org.testng.Assert;
+-import static org.testng.Assert.assertEquals;
+-import static org.testng.Assert.fail;
+ import org.testng.annotations.Test;
+
+ /**
+ * Tests for javax.script.Invocable implementation of nashorn.
+ */
++@SuppressWarnings("javadoc")
+ public class InvocableTest {
+
+- private void log(String msg) {
++ private static void log(final String msg) {
+ org.testng.Reporter.log(msg, true);
+ }
+
+@@ -69,12 +70,12 @@
+ * evaluating script with different Context set.
+ */
+ public void invokeMethodDifferentContextTest() {
+- ScriptEngineManager m = new ScriptEngineManager();
+- ScriptEngine e = m.getEngineByName("nashorn");
++ final ScriptEngineManager m = new ScriptEngineManager();
++ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ try {
+ // define an object with method on it
+- Object obj = e.eval("({ hello: function() { return 'Hello World!'; } })");
++ final Object obj = e.eval("({ hello: function() { return 'Hello World!'; } })");
+
+ final ScriptContext ctxt = new SimpleScriptContext();
+ ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE);
+@@ -99,7 +100,7 @@
+
+ try {
+ final Object obj = e.eval("({})");
+- final Object res = ((Invocable) e).invokeMethod(obj, null);
++ ((Invocable) e).invokeMethod(obj, null);
+ fail("should have thrown NPE");
+ } catch (final Exception exp) {
+ if (!(exp instanceof NullPointerException)) {
+@@ -119,7 +120,7 @@
+
+ try {
+ final Object obj = e.eval("({})");
+- final Object res = ((Invocable) e).invokeMethod(obj, "nonExistentMethod");
++ ((Invocable) e).invokeMethod(obj, "nonExistentMethod");
+ fail("should have thrown NoSuchMethodException");
+ } catch (final Exception exp) {
+ if (!(exp instanceof NoSuchMethodException)) {
+@@ -180,7 +181,7 @@
+ final ScriptEngine engine2 = m.getEngineByName("nashorn");
+
+ try {
+- Object obj = engine1.eval("({ run: function() {} })");
++ final Object obj = engine1.eval("({ run: function() {} })");
+ // pass object from engine1 to engine2 as 'thiz' for invokeMethod
+ ((Invocable) engine2).invokeMethod(obj, "run");
+ fail("should have thrown IllegalArgumentException");
+@@ -211,7 +212,7 @@
+ // try interface on specific script object
+ try {
+ e.eval("var obj = { run: function() { print('run from obj'); } };");
+- Object obj = e.get("obj");
++ final Object obj = e.get("obj");
+ final Runnable runnable = inv.getInterface(obj, Runnable.class);
+ runnable.run();
+ } catch (final Exception exp) {
+@@ -307,17 +308,17 @@
+ * switching to use different ScriptContext.
+ */
+ public void getInterfaceDifferentContext() {
+- ScriptEngineManager m = new ScriptEngineManager();
+- ScriptEngine e = m.getEngineByName("nashorn");
++ final ScriptEngineManager m = new ScriptEngineManager();
++ final ScriptEngine e = m.getEngineByName("nashorn");
+ try {
+- Object obj = e.eval("({ run: function() { } })");
++ final Object obj = e.eval("({ run: function() { } })");
+
+ // change script context
+- ScriptContext ctxt = new SimpleScriptContext();
++ final ScriptContext ctxt = new SimpleScriptContext();
+ ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE);
+ e.setContext(ctxt);
+
+- Runnable r = ((Invocable) e).getInterface(obj, Runnable.class);
++ final Runnable r = ((Invocable) e).getInterface(obj, Runnable.class);
+ r.run();
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+@@ -376,7 +377,7 @@
+ final ScriptEngine engine2 = m.getEngineByName("nashorn");
+
+ try {
+- Object obj = engine1.eval("({ run: function() {} })");
++ final Object obj = engine1.eval("({ run: function() {} })");
+ // pass object from engine1 to engine2 as 'thiz' for getInterface
+ ((Invocable) engine2).getInterface(obj, Runnable.class);
+ fail("should have thrown IllegalArgumentException");
+@@ -397,7 +398,7 @@
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ try {
+- final Object res = ((Invocable) e).invokeFunction(null);
++ ((Invocable)e).invokeFunction(null);
+ fail("should have thrown NPE");
+ } catch (final Exception exp) {
+ if (!(exp instanceof NullPointerException)) {
+@@ -417,7 +418,7 @@
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ try {
+- final Object res = ((Invocable) e).invokeFunction("NonExistentFunc");
++ ((Invocable)e).invokeFunction("NonExistentFunc");
+ fail("should have thrown NoSuchMethodException");
+ } catch (final Exception exp) {
+ if (!(exp instanceof NoSuchMethodException)) {
+@@ -433,12 +434,12 @@
+ * Bindings.
+ */
+ public void invokeFunctionDifferentContextTest() {
+- ScriptEngineManager m = new ScriptEngineManager();
+- ScriptEngine e = m.getEngineByName("nashorn");
++ final ScriptEngineManager m = new ScriptEngineManager();
++ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ try {
+ // define an object with method on it
+- Object obj = e.eval("function hello() { return 'Hello World!'; }");
++ e.eval("function hello() { return 'Hello World!'; }");
+ final ScriptContext ctxt = new SimpleScriptContext();
+ ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE);
+ // change engine's current context
+@@ -525,14 +526,14 @@
+ }
+
+ @Test
+- @SuppressWarnings("unchecked")
+ public void defaultMethodTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Invocable inv = (Invocable) e;
+
+- Object obj = e.eval("({ apply: function(arg) { return arg.toUpperCase(); }})");
+- Function<String, String> func = inv.getInterface(obj, Function.class);
++ final Object obj = e.eval("({ apply: function(arg) { return arg.toUpperCase(); }})");
++ @SuppressWarnings("unchecked")
++ final Function<String, String> func = inv.getInterface(obj, Function.class);
+ assertEquals(func.apply("hello"), "HELLO");
+ }
+ }
+--- ./nashorn/test/src/jdk/nashorn/api/scripting/MultipleEngineTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/scripting/MultipleEngineTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -37,7 +37,7 @@
+ * @test
+ * @run testng jdk.nashorn.api.scripting.MultipleEngineTest
+ */
+-
++@SuppressWarnings("javadoc")
+ public class MultipleEngineTest {
+ @Test
+ public void createAndUseManyEngine() throws ScriptException {
+--- ./nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,10 @@
+
+ package jdk.nashorn.api.scripting;
+
++import static org.testng.Assert.assertEquals;
++import static org.testng.Assert.assertFalse;
++import static org.testng.Assert.fail;
++
+ import java.nio.IntBuffer;
+ import java.util.Collection;
+ import java.util.HashMap;
+@@ -32,11 +36,6 @@
+ import java.util.Set;
+ import javax.script.ScriptEngine;
+ import javax.script.ScriptEngineManager;
+-import javax.script.ScriptException;
+-import static org.testng.Assert.assertEquals;
+-import static org.testng.Assert.assertTrue;
+-import static org.testng.Assert.assertFalse;
+-import static org.testng.Assert.fail;
+ import org.testng.annotations.Test;
+
+ /**
+@@ -45,6 +44,7 @@
+ * JDK-8024615: Refactor ScriptObjectMirror and JSObject to support external
+ * JSObject implementations.
+ */
++@SuppressWarnings("javadoc")
+ public class PluggableJSObjectTest {
+ public static class MapWrapperObject extends AbstractJSObject {
+ private final HashMap<String, Object> map = new LinkedHashMap<>();
+@@ -54,22 +54,22 @@
+ }
+
+ @Override
+- public Object getMember(String name) {
++ public Object getMember(final String name) {
+ return map.get(name);
+ }
+
+ @Override
+- public void setMember(String name, Object value) {
++ public void setMember(final String name, final Object value) {
+ map.put(name, value);
+ }
+
+ @Override
+- public boolean hasMember(String name) {
++ public boolean hasMember(final String name) {
+ return map.containsKey(name);
+ }
+
+ @Override
+- public void removeMember(String name) {
++ public void removeMember(final String name) {
+ map.remove(name);
+ }
+
+@@ -112,7 +112,7 @@
+ public static class BufferObject extends AbstractJSObject {
+ private final IntBuffer buf;
+
+- public BufferObject(int size) {
++ public BufferObject(final int size) {
+ buf = IntBuffer.allocate(size);
+ }
+
+@@ -121,22 +121,22 @@
+ }
+
+ @Override
+- public Object getMember(String name) {
++ public Object getMember(final String name) {
+ return name.equals("length")? buf.capacity() : null;
+ }
+
+ @Override
+- public boolean hasSlot(int i) {
++ public boolean hasSlot(final int i) {
+ return i > -1 && i < buf.capacity();
+ }
+
+ @Override
+- public Object getSlot(int i) {
++ public Object getSlot(final int i) {
+ return buf.get(i);
+ }
+
+ @Override
+- public void setSlot(int i, Object value) {
++ public void setSlot(final int i, final Object value) {
+ buf.put(i, ((Number)value).intValue());
+ }
+
+@@ -172,9 +172,9 @@
+
+ public static class Adder extends AbstractJSObject {
+ @Override
+- public Object call(Object thiz, Object... args) {
++ public Object call(final Object thiz, final Object... args) {
+ double res = 0.0;
+- for (Object arg : args) {
++ for (final Object arg : args) {
+ res += ((Number)arg).doubleValue();
+ }
+ return res;
+@@ -203,8 +203,9 @@
+ }
+
+ public static class Factory extends AbstractJSObject {
++ @SuppressWarnings("unused")
+ @Override
+- public Object newObject(Object... args) {
++ public Object newObject(final Object... args) {
+ return new HashMap<Object, Object>();
+ }
+
+--- ./nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -24,6 +24,10 @@
+ */
+ package jdk.nashorn.api.scripting;
+
++import static org.testng.Assert.assertEquals;
++import static org.testng.Assert.assertNotNull;
++import static org.testng.Assert.assertTrue;
++import static org.testng.Assert.fail;
+ import javax.script.Bindings;
+ import javax.script.ScriptContext;
+ import javax.script.ScriptEngine;
+@@ -32,22 +36,19 @@
+ import javax.script.SimpleBindings;
+ import javax.script.SimpleScriptContext;
+ import org.testng.Assert;
+-import static org.testng.Assert.assertEquals;
+-import static org.testng.Assert.assertNotNull;
+-import static org.testng.Assert.assertTrue;
+-import static org.testng.Assert.fail;
+ import org.testng.annotations.Test;
+
+ /**
+ * Tests for jsr223 Bindings "scope" (engine, global scopes)
+ */
++@SuppressWarnings("javadoc")
+ public class ScopeTest {
+
+ @Test
+ public void createBindingsTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+- Bindings b = e.createBindings();
++ final Bindings b = e.createBindings();
+ b.put("foo", 42.0);
+ Object res = null;
+ try {
+@@ -64,7 +65,7 @@
+ public void engineScopeTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+- Bindings engineScope = e.getBindings(ScriptContext.ENGINE_SCOPE);
++ final Bindings engineScope = e.getBindings(ScriptContext.ENGINE_SCOPE);
+
+ // check few ECMA standard built-in global properties
+ assertNotNull(engineScope.get("Object"));
+@@ -112,8 +113,8 @@
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+ try {
+- Object obj1 = e.eval("Object");
+- Object obj2 = e.eval("Object", newCtxt);
++ final Object obj1 = e.eval("Object");
++ final Object obj2 = e.eval("Object", newCtxt);
+ Assert.assertNotEquals(obj1, obj2);
+ Assert.assertNotNull(obj1);
+ Assert.assertNotNull(obj2);
+@@ -138,10 +139,12 @@
+ e.eval("y = new Object()");
+ e.eval("y = new Object()", origCtxt);
+
+- Object y1 = origCtxt.getAttribute("y");
+- Object y2 = newCtxt.getAttribute("y");
++ final Object y1 = origCtxt.getAttribute("y");
++ final Object y2 = newCtxt.getAttribute("y");
+ Assert.assertNotEquals(y1, y2);
+- Assert.assertNotEquals(e.eval("y"), e.eval("y", origCtxt));
++ final Object yeval1 = e.eval("y");
++ final Object yeval2 = e.eval("y", origCtxt);
++ Assert.assertNotEquals(yeval1, yeval2);
+ Assert.assertEquals("[object Object]", y1.toString());
+ Assert.assertEquals("[object Object]", y2.toString());
+ } catch (final ScriptException se) {
+@@ -159,7 +162,7 @@
+ final ScriptContext newContext = new SimpleScriptContext();
+ newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
+ // we are using a new bindings - so it should have 'func' defined
+- Object value = e.eval("typeof func", newContext);
++ final Object value = e.eval("typeof func", newContext);
+ assertTrue(value.equals("undefined"));
+ }
+
+@@ -210,7 +213,7 @@
+ assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction());
+
+ // check new global instance created has engine.js definitions
+- Bindings b = e.createBindings();
++ final Bindings b = e.createBindings();
+ value = b.get("__noSuchProperty__");
+ assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction());
+ value = b.get("print");
+@@ -231,7 +234,7 @@
+ assertTrue(e.eval("x", ctx).equals("hello"));
+
+ // try some arbitray Bindings for ENGINE_SCOPE
+- Bindings sb = new SimpleBindings();
++ final Bindings sb = new SimpleBindings();
+ ctx.setBindings(sb, ScriptContext.ENGINE_SCOPE);
+
+ // GLOBAL_SCOPE mapping should be visible from non-default ScriptContext eval
+@@ -305,7 +308,7 @@
+ t1.join();
+ t2.join();
+
+- Object obj3 = e.eval("delete foo; foo = 'newer context';", newCtxt);
++ final Object obj3 = e.eval("delete foo; foo = 'newer context';", newCtxt);
+ assertEquals(obj3, "newer context");
+ final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+ final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
+@@ -342,7 +345,7 @@
+ for (int i = 0; i < 1000; i++) {
+ assertEquals(e.eval(sharedScript, origContext), (double)i);
+ }
+- } catch (ScriptException se) {
++ } catch (final ScriptException se) {
+ fail(se.toString());
+ }
+ }
+@@ -354,7 +357,7 @@
+ for (int i = 2; i < 1000; i++) {
+ assertEquals(e.eval(sharedScript, newCtxt), (double)i);
+ }
+- } catch (ScriptException se) {
++ } catch (final ScriptException se) {
+ fail(se.toString());
+ }
+ }
+@@ -377,8 +380,8 @@
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+- Object obj1 = e.eval("String.prototype.foo = 'original context';", origContext);
+- Object obj2 = e.eval("String.prototype.foo = 'new context';", newCtxt);
++ final Object obj1 = e.eval("String.prototype.foo = 'original context';", origContext);
++ final Object obj2 = e.eval("String.prototype.foo = 'new context';", newCtxt);
+ assertEquals(obj1, "original context");
+ assertEquals(obj2, "new context");
+ final String sharedScript = "''.foo";
+@@ -390,7 +393,7 @@
+ t1.join();
+ t2.join();
+
+- Object obj3 = e.eval("delete String.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt);
++ final Object obj3 = e.eval("delete String.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt);
+ assertEquals(obj3, "newer context");
+ final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+ final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
+@@ -404,6 +407,75 @@
+ Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context");
+ }
+
++
++ /**
++ * Test multi-threaded access to prototype user accessor properties for shared script classes with multiple globals.
++ */
++ @Test
++ public static void multiThreadedAccessorTest() throws ScriptException, InterruptedException {
++ final ScriptEngineManager m = new ScriptEngineManager();
++ final ScriptEngine e = m.getEngineByName("nashorn");
++ final Bindings b = e.createBindings();
++ final ScriptContext origContext = e.getContext();
++ final ScriptContext newCtxt = new SimpleScriptContext();
++ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
++
++ e.eval("Object.defineProperty(Object.prototype, 'foo', { get: function() 'original context' })", origContext);
++ e.eval("Object.defineProperty(Object.prototype, 'foo', { get: function() 'new context', configurable: true })", newCtxt);
++ final String sharedScript = "({}).foo";
++
++ final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
++ final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
++ t1.start();
++ t2.start();
++ t1.join();
++ t2.join();
++
++ final Object obj3 = e.eval("delete Object.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt);
++ assertEquals(obj3, "newer context");
++ final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
++ final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
++
++ t3.start();
++ t4.start();
++ t3.join();
++ t4.join();
++ }
++
++ /**
++ * Test multi-threaded access to primitive prototype user accessor properties for shared script classes with multiple globals.
++ */
++ @Test
++ public static void multiThreadedPrimitiveAccessorTest() throws ScriptException, InterruptedException {
++ final ScriptEngineManager m = new ScriptEngineManager();
++ final ScriptEngine e = m.getEngineByName("nashorn");
++ final Bindings b = e.createBindings();
++ final ScriptContext origContext = e.getContext();
++ final ScriptContext newCtxt = new SimpleScriptContext();
++ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
++
++ e.eval("Object.defineProperty(String.prototype, 'foo', { get: function() 'original context' })", origContext);
++ e.eval("Object.defineProperty(String.prototype, 'foo', { get: function() 'new context' })", newCtxt);
++ final String sharedScript = "''.foo";
++
++ final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
++ final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
++ t1.start();
++ t2.start();
++ t1.join();
++ t2.join();
++
++ final Object obj3 = e.eval("delete String.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt);
++ assertEquals(obj3, "newer context");
++ final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
++ final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
++
++ t3.start();
++ t4.start();
++ t3.join();
++ t4.join();
++ }
++
+ /**
+ * Test multi-threaded scope function invocation for shared script classes with multiple globals.
+ */
+@@ -510,6 +582,60 @@
+ assertEquals(e.eval("x", newCtxt), 2);
+ }
+
++ // @bug 8058422: Users should be able to overwrite "context" and "engine" variables
++ @Test
++ public static void contextOverwriteTest() throws ScriptException {
++ final ScriptEngineManager m = new ScriptEngineManager();
++ final ScriptEngine e = m.getEngineByName("nashorn");
++ final Bindings b = new SimpleBindings();
++ b.put("context", "hello");
++ b.put("foo", 32);
++ final ScriptContext newCtxt = new SimpleScriptContext();
++ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
++ e.setContext(newCtxt);
++ assertEquals(e.eval("context"), "hello");
++ assertEquals(((Number)e.eval("foo")).intValue(), 32);
++ }
++
++ // @bug 8058422: Users should be able to overwrite "context" and "engine" variables
++ @Test
++ public static void contextOverwriteInScriptTest() throws ScriptException {
++ final ScriptEngineManager m = new ScriptEngineManager();
++ final ScriptEngine e = m.getEngineByName("nashorn");
++ e.put("foo", 32);
++
++ assertEquals(((Number)e.eval("foo")).intValue(), 32);
++ assertEquals(e.eval("context = 'bar'"), "bar");
++ assertEquals(((Number)e.eval("foo")).intValue(), 32);
++ }
++
++ // @bug 8058422: Users should be able to overwrite "context" and "engine" variables
++ @Test
++ public static void engineOverwriteTest() throws ScriptException {
++ final ScriptEngineManager m = new ScriptEngineManager();
++ final ScriptEngine e = m.getEngineByName("nashorn");
++ final Bindings b = new SimpleBindings();
++ b.put("engine", "hello");
++ b.put("foo", 32);
++ final ScriptContext newCtxt = new SimpleScriptContext();
++ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
++ e.setContext(newCtxt);
++ assertEquals(e.eval("engine"), "hello");
++ assertEquals(((Number)e.eval("foo")).intValue(), 32);
++ }
++
++ // @bug 8058422: Users should be able to overwrite "context" and "engine" variables
++ @Test
++ public static void engineOverwriteInScriptTest() throws ScriptException {
++ final ScriptEngineManager m = new ScriptEngineManager();
++ final ScriptEngine e = m.getEngineByName("nashorn");
++ e.put("foo", 32);
++
++ assertEquals(((Number)e.eval("foo")).intValue(), 32);
++ assertEquals(e.eval("engine = 'bar'"), "bar");
++ assertEquals(((Number)e.eval("foo")).intValue(), 32);
++ }
++
+ // @bug 8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
+ @Test
+ public static void testMegamorphicGetInGlobal() throws Exception {
+@@ -529,6 +655,8 @@
+
+ /**
+ * Test "slow" scopes involving {@code with} and {@code eval} statements for shared script classes with multiple globals.
++ * @throws ScriptException
++ * @throws InterruptedException
+ */
+ @Test
+ public static void testSlowScope() throws ScriptException, InterruptedException {
+@@ -572,7 +700,7 @@
+ for (int i = 0; i < iterations; i++) {
+ assertEquals(engine.eval(source, context), expected);
+ }
+- } catch (ScriptException se) {
++ } catch (final ScriptException se) {
+ throw new RuntimeException(se);
+ }
+ }
+--- ./nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineSecurityTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineSecurityTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,12 +26,9 @@
+ package jdk.nashorn.api.scripting;
+
+ import static org.testng.Assert.fail;
+-
++import java.lang.reflect.InvocationHandler;
+ import java.lang.reflect.Method;
+-import java.lang.reflect.InvocationHandler;
+ import java.lang.reflect.Proxy;
+-import java.util.Objects;
+-import javax.script.Invocable;
+ import javax.script.ScriptEngine;
+ import javax.script.ScriptEngineManager;
+ import javax.script.ScriptException;
+@@ -40,9 +37,10 @@
+ /**
+ * jsr223 tests for security access checks.
+ */
++@SuppressWarnings("javadoc")
+ public class ScriptEngineSecurityTest {
+
+- private void log(String msg) {
++ private static void log(final String msg) {
+ org.testng.Reporter.log(msg, true);
+ }
+
+@@ -168,55 +166,20 @@
+ }
+ }
+
+- @Test
+- /**
+- * Check that script can't implement sensitive package interfaces.
+- */
+- public void checkSensitiveInterfaceImplTest() throws ScriptException {
+- if (System.getSecurityManager() == null) {
+- // pass vacuously
+- return;
+- }
+-
+- final ScriptEngineManager m = new ScriptEngineManager();
+- final ScriptEngine e = m.getEngineByName("nashorn");
+- final Object[] holder = new Object[1];
+- e.put("holder", holder);
+- // put an empty script object into array
+- e.eval("holder[0] = {}");
+- // holder[0] is an object of some subclass of ScriptObject
+- Class ScriptObjectClass = holder[0].getClass().getSuperclass();
+- Class PropertyAccessClass = ScriptObjectClass.getInterfaces()[0];
+- // implementation methods for PropertyAccess class
+- e.eval("function set() {}; function get() {}; function getInt(){} " +
+- "function getDouble(){}; function getLong() {}; " +
+- "this.delete = function () {}; function has() {}; " +
+- "function hasOwnProperty() {}");
+-
+- // get implementation of a restricted package interface
+- try {
+- log(Objects.toString(((Invocable)e).getInterface((Class<?>)PropertyAccessClass)));
+- fail("should have thrown SecurityException");
+- } catch (final Exception exp) {
+- if (! (exp instanceof SecurityException)) {
+- fail("SecurityException expected, got " + exp);
+- }
+- }
+- }
+-
+ // @bug 8032948: Nashorn linkages awry
++ @SuppressWarnings("serial")
+ public static class FakeProxy extends Proxy {
+- public FakeProxy(InvocationHandler ih) {
++ public FakeProxy(final InvocationHandler ih) {
+ super(ih);
+ }
+
+- public static Class<?> makeProxyClass(ClassLoader cl, Class<?>... ifaces) {
++ public static Class<?> makeProxyClass(final ClassLoader cl, final Class<?>... ifaces) {
+ return Proxy.getProxyClass(cl, ifaces);
+ }
+ }
+
+ @Test
+- public void fakeProxySubclassAccessCheckTest() throws ScriptException {
++ public void fakeProxySubclassAccessCheckTest() {
+ if (System.getSecurityManager() == null) {
+ // pass vacuously
+ return;
+@@ -229,11 +192,11 @@
+ e.put("cl", ScriptEngineSecurityTest.class.getClassLoader());
+ e.put("intfs", new Class[] { Runnable.class });
+
+- String getClass = "Java.type(name + '$FakeProxy').getProxyClass(cl, intfs);";
++ final String getClass = "Java.type(name + '$FakeProxy').getProxyClass(cl, intfs);";
+
+ // Should not be able to call static methods of Proxy via fake subclass
+ try {
+- Class c = (Class)e.eval(getClass);
++ e.eval(getClass);
+ fail("should have thrown SecurityException");
+ } catch (final Exception exp) {
+ if (! (exp instanceof SecurityException)) {
+@@ -243,7 +206,7 @@
+ }
+
+ @Test
+- public void fakeProxySubclassAccessCheckTest2() throws ScriptException {
++ public void fakeProxySubclassAccessCheckTest2() {
+ if (System.getSecurityManager() == null) {
+ // pass vacuously
+ return;
+@@ -256,11 +219,11 @@
+ e.put("cl", ScriptEngineSecurityTest.class.getClassLoader());
+ e.put("intfs", new Class[] { Runnable.class });
+
+- String getClass = "Java.type(name + '$FakeProxy').makeProxyClass(cl, intfs);";
++ final String getClass = "Java.type(name + '$FakeProxy').makeProxyClass(cl, intfs);";
+
+ // Should not be able to call static methods of Proxy via fake subclass
+ try {
+- Class c = (Class)e.eval(getClass);
++ e.eval(getClass);
+ fail("should have thrown SecurityException");
+ } catch (final Exception exp) {
+ if (! (exp instanceof SecurityException)) {
+@@ -270,7 +233,12 @@
+ }
+
+ @Test
+- public static void proxyStaticAccessCheckTest() throws ScriptException {
++ public static void proxyStaticAccessCheckTest() {
++ if (System.getSecurityManager() == null) {
++ // pass vacuously
++ return;
++ }
++
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Runnable r = (Runnable)Proxy.newProxyInstance(
+@@ -278,7 +246,7 @@
+ new Class[] { Runnable.class },
+ new InvocationHandler() {
+ @Override
+- public Object invoke(Object p, Method m, Object[] a) {
++ public Object invoke(final Object p, final Method mtd, final Object[] a) {
+ return null;
+ }
+ });
+@@ -297,4 +265,47 @@
+ }
+ }
+ }
++
++
++ @Test
++ public void nashornConfigSecurityTest() {
++ if (System.getSecurityManager() == null) {
++ // pass vacuously
++ return;
++ }
++
++ final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
++ try {
++ fac.getScriptEngine(new ClassFilter() {
++ @Override
++ public boolean exposeToScripts(final String name) {
++ return true;
++ }
++ });
++ fail("SecurityException should have been thrown");
++ } catch (final SecurityException e) {
++ //empty
++ }
++ }
++
++ @Test
++ public void nashornConfigSecurityTest2() {
++ if (System.getSecurityManager() == null) {
++ // pass vacuously
++ return;
++ }
++
++ final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
++ try {
++ fac.getScriptEngine(new String[0], null, new ClassFilter() {
++ @Override
++ public boolean exposeToScripts(final String name) {
++ return true;
++ }
++ });
++ fail("SecurityException should have been thrown");
++ } catch (final SecurityException e) {
++ //empty
++ }
++ }
+ }
+--- ./nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -30,15 +30,18 @@
+ import static org.testng.Assert.assertTrue;
+ import static org.testng.Assert.fail;
+
+-import java.io.PrintWriter;
+ import java.io.StringReader;
+ import java.io.StringWriter;
+ import java.lang.reflect.InvocationHandler;
+ import java.lang.reflect.Method;
+ import java.lang.reflect.Proxy;
+ import java.util.concurrent.Callable;
++import java.util.concurrent.atomic.AtomicBoolean;
++import java.util.function.Consumer;
++import java.util.function.Function;
+ import javax.script.Compilable;
+ import javax.script.CompiledScript;
++import javax.script.Invocable;
+ import javax.script.ScriptContext;
+ import javax.script.ScriptEngine;
+ import javax.script.ScriptEngineFactory;
+@@ -54,9 +57,10 @@
+ * @build jdk.nashorn.api.scripting.Window jdk.nashorn.api.scripting.WindowEventHandler jdk.nashorn.api.scripting.VariableArityTestInterface jdk.nashorn.api.scripting.ScriptEngineTest
+ * @run testng/othervm jdk.nashorn.api.scripting.ScriptEngineTest
+ */
++@SuppressWarnings("javadoc")
+ public class ScriptEngineTest {
+
+- private void log(String msg) {
++ private static void log(final String msg) {
+ org.testng.Reporter.log(msg, true);
+ }
+
+@@ -65,11 +69,11 @@
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+- String[] args = new String[] { "hello", "world" };
++ final String[] args = new String[] { "hello", "world" };
+ try {
+ e.put("arguments", args);
+- Object arg0 = e.eval("arguments[0]");
+- Object arg1 = e.eval("arguments[1]");
++ final Object arg0 = e.eval("arguments[0]");
++ final Object arg1 = e.eval("arguments[1]");
+ assertEquals(args[0], arg0);
+ assertEquals(args[1], arg1);
+ } catch (final Exception exp) {
+@@ -83,12 +87,12 @@
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+- String[] args = new String[] { "hello", "world" };
++ final String[] args = new String[] { "hello", "world" };
+ try {
+ e.put("arguments", args);
+- Object arg0 = e.eval("var imports = new JavaImporter(java.io); " +
++ final Object arg0 = e.eval("var imports = new JavaImporter(java.io); " +
+ " with(imports) { arguments[0] }");
+- Object arg1 = e.eval("var imports = new JavaImporter(java.util, java.io); " +
++ final Object arg1 = e.eval("var imports = new JavaImporter(java.util, java.io); " +
+ " with(imports) { arguments[1] }");
+ assertEquals(args[0], arg0);
+ assertEquals(args[1], arg1);
+@@ -129,22 +133,24 @@
+ assertEquals(fac.getParameter(ScriptEngine.NAME), "javascript");
+
+ boolean seenJS = false;
+- for (String ext : fac.getExtensions()) {
++ for (final String ext : fac.getExtensions()) {
+ if (ext.equals("js")) {
+ seenJS = true;
+ }
+ }
+
+ assertEquals(seenJS, true);
+- String str = fac.getMethodCallSyntax("obj", "foo", "x");
++ final String str = fac.getMethodCallSyntax("obj", "foo", "x");
+ assertEquals(str, "obj.foo(x)");
+
+ boolean seenNashorn = false, seenJavaScript = false, seenECMAScript = false;
+- for (String name : fac.getNames()) {
++ for (final String name : fac.getNames()) {
+ switch (name) {
+ case "nashorn": seenNashorn = true; break;
+ case "javascript": seenJavaScript = true; break;
+ case "ECMAScript": seenECMAScript = true; break;
++ default:
++ break;
+ }
+ }
+
+@@ -153,12 +159,14 @@
+ assertTrue(seenECMAScript);
+
+ boolean seenAppJS = false, seenAppECMA = false, seenTextJS = false, seenTextECMA = false;
+- for (String mime : fac.getMimeTypes()) {
++ for (final String mime : fac.getMimeTypes()) {
+ switch (mime) {
+ case "application/javascript": seenAppJS = true; break;
+ case "application/ecmascript": seenAppECMA = true; break;
+ case "text/javascript": seenTextJS = true; break;
+ case "text/ecmascript": seenTextECMA = true; break;
++ default:
++ break;
+ }
+ }
+
+@@ -548,7 +556,7 @@
+ new Class[] { Runnable.class },
+ new InvocationHandler() {
+ @Override
+- public Object invoke(Object p, Method m, Object[] a) {
++ public Object invoke(final Object p, final Method mtd, final Object[] a) {
+ reached[0] = true;
+ return null;
+ }
+@@ -594,9 +602,114 @@
+ }
+ }
+
++ // @bug 8046013: TypeError: Cannot apply "with" to non script object
++ @Test
++ public void withOnMirrorTest() throws ScriptException {
++ final ScriptEngineManager m = new ScriptEngineManager();
++ final ScriptEngine e = m.getEngineByName("nashorn");
++
++ final Object obj = e.eval("({ foo: 'hello'})");
++ final Object[] arr = new Object[1];
++ arr[0] = obj;
++ e.put("arr", arr);
++ final Object res = e.eval("var res; with(arr[0]) { res = foo; }; res");
++ assertEquals(res, "hello");
++ }
++
++ // @bug 8054223: Nashorn: AssertionError when use __DIR__ and ScriptEngine.eval()
++ @Test
++ public void check__DIR__Test() throws ScriptException {
++ final ScriptEngineManager m = new ScriptEngineManager();
++ final ScriptEngine e = m.getEngineByName("nashorn");
++ e.eval("__DIR__");
++ }
++
++ // @bug 8050432:javax.script.filename variable should not be enumerable
++ // with nashorn engine's ENGINE_SCOPE bindings
++ @Test
++ public void enumerableGlobalsTest() throws ScriptException {
++ final ScriptEngineManager m = new ScriptEngineManager();
++ final ScriptEngine e = m.getEngineByName("nashorn");
++
++ e.put(ScriptEngine.FILENAME, "test");
++ final Object enumerable = e.eval(
++ "Object.getOwnPropertyDescriptor(this, " +
++ " 'javax.script.filename').enumerable");
++ assertEquals(enumerable, Boolean.FALSE);
++ }
++
++ public static class Context {
++ private Object myobj;
++
++ public void set(final Object o) {
++ myobj = o;
++ }
++
++ public Object get() {
++ return myobj;
++ }
++ }
++
++ // @bug 8050977: Java8 Javascript Nashorn exception:
++ // no current Global instance for nashorn
++ @Test
++ public void currentGlobalMissingTest() throws Exception {
++ final ScriptEngineManager manager = new ScriptEngineManager();
++ final ScriptEngine e = manager.getEngineByName("nashorn");
++
++ final Context ctx = new Context();
++ e.put("ctx", ctx);
++ e.eval("var obj = { foo: function(str) { return str.toUpperCase() } }");
++ e.eval("ctx.set(obj)");
++ final Invocable inv = (Invocable)e;
++ assertEquals("HELLO", inv.invokeMethod(ctx.get(), "foo", "hello"));
++ // try object literal
++ e.eval("ctx.set({ bar: function(str) { return str.toLowerCase() } })");
++ assertEquals("hello", inv.invokeMethod(ctx.get(), "bar", "HELLO"));
++ // try array literal
++ e.eval("var arr = [ 'hello', 'world' ]");
++ e.eval("ctx.set(arr)");
++ assertEquals("helloworld", inv.invokeMethod(ctx.get(), "join", ""));
++ }
++
++ // @bug JDK-8068889: ConsString arguments to a functional interface wasn't converted to string.
++ @Test
++ public void functionalInterfaceStringTest() throws Exception {
++ final ScriptEngineManager manager = new ScriptEngineManager();
++ final ScriptEngine e = manager.getEngineByName("nashorn");
++ final AtomicBoolean invoked = new AtomicBoolean(false);
++ e.put("f", new Function<String, String>() {
++ @Override
++ public String apply(String t) {
++ invoked.set(true);
++ return t;
++ }
++ });
++ assertEquals(e.eval("var x = 'a'; x += 'b'; f(x)"), "ab");
++ assertTrue(invoked.get());
++ }
++
++ // @bug JDK-8068889: ScriptObject arguments to a functional interface wasn't converted to a mirror.
++ @Test
++ public void functionalInterfaceObjectTest() throws Exception {
++ final ScriptEngineManager manager = new ScriptEngineManager();
++ final ScriptEngine e = manager.getEngineByName("nashorn");
++ final AtomicBoolean invoked = new AtomicBoolean(false);
++ e.put("c", new Consumer<Object>() {
++ @Override
++ public void accept(Object t) {
++ assertTrue(t instanceof ScriptObjectMirror);
++ assertEquals(((ScriptObjectMirror)t).get("a"), "xyz");
++ invoked.set(true);
++ }
++ });
++ e.eval("var x = 'xy'; x += 'z';c({a:x})");
++ assertTrue(invoked.get());
++ }
++
+ private static void checkProperty(final ScriptEngine e, final String name)
+ throws ScriptException {
+- String value = System.getProperty(name);
++ final String value = System.getProperty(name);
+ e.put("name", name);
+ assertEquals(value, e.eval("java.lang.System.getProperty(name)"));
+ }
+--- ./nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,24 +25,28 @@
+
+ package jdk.nashorn.api.scripting;
+
++import static org.testng.Assert.assertEquals;
++import static org.testng.Assert.assertFalse;
++import static org.testng.Assert.assertTrue;
++import static org.testng.Assert.fail;
++
+ import java.nio.ByteBuffer;
+ import java.util.HashMap;
+ import java.util.List;
+ import java.util.Map;
++import java.util.function.Function;
+ import javax.script.Bindings;
++import javax.script.Invocable;
+ import javax.script.ScriptContext;
+ import javax.script.ScriptEngine;
+ import javax.script.ScriptEngineManager;
+ import javax.script.ScriptException;
+-import static org.testng.Assert.assertEquals;
+-import static org.testng.Assert.assertFalse;
+-import static org.testng.Assert.assertTrue;
+-import static org.testng.Assert.fail;
+ import org.testng.annotations.Test;
+
+ /**
+ * Tests to check jdk.nashorn.api.scripting.ScriptObjectMirror API.
+ */
++@SuppressWarnings("javadoc")
+ public class ScriptObjectMirrorTest {
+
+ @SuppressWarnings("unchecked")
+@@ -133,7 +137,7 @@
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ try {
+ e.eval("var obj = { '1': 'world', func: function() { return this.bar; }, bar: 'hello' }");
+- ScriptObjectMirror obj = (ScriptObjectMirror) e.get("obj");
++ final ScriptObjectMirror obj = (ScriptObjectMirror) e.get("obj");
+
+ // try basic get on existing properties
+ if (!obj.getMember("bar").equals("hello")) {
+@@ -190,7 +194,7 @@
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ try {
+- Object obj = e.eval("new TypeError('wrong type')");
++ final Object obj = e.eval("new TypeError('wrong type')");
+ assertEquals(obj.toString(), "TypeError: wrong type", "toString returns wrong value");
+ } catch (final Throwable t) {
+ t.printStackTrace();
+@@ -198,7 +202,7 @@
+ }
+
+ try {
+- Object obj = e.eval("function func() { print('hello'); }");
++ final Object obj = e.eval("function func() { print('hello'); }");
+ assertEquals(obj.toString(), "function func() { print('hello'); }", "toString returns wrong value");
+ } catch (final Throwable t) {
+ t.printStackTrace();
+@@ -305,4 +309,79 @@
+ // getMember("obj.foo") - thereby getting null instead of undefined
+ assertEquals("undefined", engine.eval(TEST_SCRIPT, newGlobal));
+ }
++
++ public interface MirrorCheckExample {
++ Object test1(Object arg);
++ Object test2(Object arg);
++ boolean compare(Object o1, Object o2);
++ }
++
++ // @bug 8053910: ScriptObjectMirror causing havoc with Invocation interface
++ @Test
++ public void checkMirrorToObject() throws Exception {
++ final ScriptEngineManager engineManager = new ScriptEngineManager();
++ final ScriptEngine engine = engineManager.getEngineByName("nashorn");
++ final Invocable invocable = (Invocable)engine;
++
++ engine.eval("function test1(arg) { return { arg: arg }; }");
++ engine.eval("function test2(arg) { return arg; }");
++ engine.eval("function compare(arg1, arg2) { return arg1 == arg2; }");
++
++ final Map<String, Object> map = new HashMap<>();
++ map.put("option", true);
++
++ final MirrorCheckExample example = invocable.getInterface(MirrorCheckExample.class);
++
++ final Object value1 = invocable.invokeFunction("test1", map);
++ final Object value2 = example.test1(map);
++ final Object value3 = invocable.invokeFunction("test2", value2);
++ final Object value4 = example.test2(value2);
++
++ // check that Object type argument receives a ScriptObjectMirror
++ // when ScriptObject is passed
++ assertEquals(ScriptObjectMirror.class, value1.getClass());
++ assertEquals(ScriptObjectMirror.class, value2.getClass());
++ assertEquals(ScriptObjectMirror.class, value3.getClass());
++ assertEquals(ScriptObjectMirror.class, value4.getClass());
++ assertTrue((boolean)invocable.invokeFunction("compare", value1, value1));
++ assertTrue(example.compare(value1, value1));
++ assertTrue((boolean)invocable.invokeFunction("compare", value3, value4));
++ assertTrue(example.compare(value3, value4));
++ }
++
++ // @bug 8053910: ScriptObjectMirror causing havoc with Invocation interface
++ @Test
++ public void mirrorUnwrapInterfaceMethod() throws Exception {
++ final ScriptEngineManager engineManager = new ScriptEngineManager();
++ final ScriptEngine engine = engineManager.getEngineByName("nashorn");
++ final Invocable invocable = (Invocable)engine;
++ engine.eval("function apply(obj) { " +
++ " return obj instanceof Packages.jdk.nashorn.api.scripting.ScriptObjectMirror; " +
++ "}");
++ @SuppressWarnings("unchecked")
++ final Function<Object,Object> func = invocable.getInterface(Function.class);
++ assertFalse((boolean)func.apply(engine.eval("({ x: 2 })")));
++ }
++
++ // @bug 8055687: Wrong "this" passed to JSObject.eval call
++ @Test
++ public void checkThisForJSObjectEval() throws Exception {
++ final ScriptEngineManager engineManager = new ScriptEngineManager();
++ final ScriptEngine e = engineManager.getEngineByName("nashorn");
++ final JSObject jsobj = (JSObject)e.eval("({foo: 23, bar: 'hello' })");
++ assertEquals(((Number)jsobj.eval("this.foo")).intValue(), 23);
++ assertEquals(jsobj.eval("this.bar"), "hello");
++ assertEquals(jsobj.eval("String(this)"), "[object Object]");
++ final Object global = e.eval("this");
++ assertFalse(global.equals(jsobj.eval("this")));
++ }
++
++ @Test
++ public void topLevelAnonFuncStatement() throws Exception {
++ final ScriptEngineManager engineManager = new ScriptEngineManager();
++ final ScriptEngine e = engineManager.getEngineByName("nashorn");
++ final JSObject func = (JSObject)e.eval("function(x) { return x + ' world' }");
++ assertTrue(func.isFunction());
++ assertEquals(func.call(e.eval("this"), "hello"), "hello world");
++ }
+ }
+--- ./nashorn/test/src/jdk/nashorn/api/scripting/VariableArityTestInterface.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/scripting/VariableArityTestInterface.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package jdk.nashorn.api.scripting;
+
++@SuppressWarnings("javadoc")
+ public interface VariableArityTestInterface {
+ public String test1(int i, String... strings);
+ public String test2(int i, String... strings);
+--- ./nashorn/test/src/jdk/nashorn/api/scripting/Window.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/scripting/Window.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,6 +28,7 @@
+ import java.util.Map;
+ import javax.script.Bindings;
+
++@SuppressWarnings("javadoc")
+ public class Window {
+
+ private String location = "http://localhost:8080/window";
+--- ./nashorn/test/src/jdk/nashorn/api/scripting/WindowEventHandler.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/api/scripting/WindowEventHandler.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,8 +25,7 @@
+
+ package jdk.nashorn.api.scripting;
+
++@SuppressWarnings("javadoc")
+ public interface WindowEventHandler {
+-
+ public boolean loaded();
+-
+ }
+--- ./nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,9 +25,8 @@
+
+ package jdk.nashorn.internal.codegen;
+
++import static jdk.nashorn.internal.runtime.Source.readFully;
+ import static jdk.nashorn.internal.runtime.Source.sourceFor;
+-import static jdk.nashorn.internal.runtime.Source.readFully;
+-
+ import java.io.File;
+ import java.io.PrintWriter;
+ import java.io.StringWriter;
+@@ -45,6 +44,7 @@
+ /**
+ * Tests to check Nashorn JS compiler - just compiler and not execution of scripts.
+ */
++@SuppressWarnings("javadoc")
+ public class CompilerTest {
+ private static final boolean VERBOSE = Boolean.valueOf(System.getProperty("compilertest.verbose"));
+ private static final boolean TEST262 = Boolean.valueOf(System.getProperty("compilertest.test262"));
+@@ -56,7 +56,7 @@
+ public boolean exclude(File file, String content);
+ }
+
+- private void log(String msg) {
++ private static void log(final String msg) {
+ org.testng.Reporter.log(msg, true);
+ }
+
+@@ -72,6 +72,7 @@
+ options.set("print.parse", true);
+ options.set("scripting", true);
+ options.set("const.as.var", true);
++ options.set("verify.code", true);
+
+ final ErrorManager errors = new ErrorManager() {
+ @Override
+@@ -98,11 +99,16 @@
+ compileTestSet(new File(TEST262_SUITE_DIR), new TestFilter() {
+ @Override
+ public boolean exclude(final File file, final String content) {
+- return content.indexOf("@negative") != -1;
++ return content != null && content.contains("@negative");
+ }
+ });
+ }
+- compileTestSet(new File(TEST_BASIC_DIR), null);
++ compileTestSet(new File(TEST_BASIC_DIR), new TestFilter() {
++ @Override
++ public boolean exclude(final File file, final String content) {
++ return file.getName().equals("es6");
++ }
++ });
+ compileTestSet(new File(TEST_NODE_DIR, "node"), null);
+ compileTestSet(new File(TEST_NODE_DIR, "src"), null);
+ }
+@@ -136,6 +142,9 @@
+ private int skipped;
+
+ private void compileJSDirectory(final File dir, final TestFilter filter) {
++ if (filter != null && filter.exclude(dir, null)) {
++ return;
++ }
+ for (final File f : dir.listFiles()) {
+ if (f.isDirectory()) {
+ compileJSDirectory(f, filter);
+--- ./nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,9 +25,8 @@
+
+ package jdk.nashorn.internal.parser;
+
++import static jdk.nashorn.internal.runtime.Source.readFully;
+ import static jdk.nashorn.internal.runtime.Source.sourceFor;
+-import static jdk.nashorn.internal.runtime.Source.readFully;
+-
+ import java.io.File;
+ import jdk.nashorn.internal.runtime.Context;
+ import jdk.nashorn.internal.runtime.ErrorManager;
+@@ -41,6 +40,7 @@
+ /**
+ * Run tests to check Nashorn's parser.
+ */
++@SuppressWarnings("javadoc")
+ public class ParserTest {
+ private static final boolean VERBOSE = Boolean.valueOf(System.getProperty("parsertest.verbose"));
+ private static final boolean TEST262 = Boolean.valueOf(System.getProperty("parsertest.test262"));
+@@ -53,7 +53,7 @@
+ public boolean exclude(File file, String content);
+ }
+
+- private void log(String msg) {
++ private static void log(final String msg) {
+ org.testng.Reporter.log(msg, true);
+ }
+
+@@ -67,7 +67,7 @@
+ options.set("scripting", true);
+ options.set("const.as.var", true);
+
+- ErrorManager errors = new ErrorManager();
++ final ErrorManager errors = new ErrorManager();
+ this.context = new Context(options, errors, Thread.currentThread().getContextClassLoader());
+ }
+
+@@ -82,11 +82,16 @@
+ parseTestSet(TEST262_SUITE_DIR, new TestFilter() {
+ @Override
+ public boolean exclude(final File file, final String content) {
+- return content.indexOf("@negative") != -1;
++ return content != null && content.contains("@negative");
+ }
+ });
+ }
+- parseTestSet(TEST_BASIC_DIR, null);
++ parseTestSet(TEST_BASIC_DIR, new TestFilter() {
++ @Override
++ public boolean exclude(final File file, final String content) {
++ return file.getName().equals("es6");
++ }
++ });
+ }
+
+ private void parseTestSet(final String testSet, final TestFilter filter) {
+@@ -120,6 +125,9 @@
+ private int skipped;
+
+ private void parseJSDirectory(final File dir, final TestFilter filter) {
++ if (filter != null && filter.exclude(dir, null)) {
++ return;
++ }
+ for (final File f : dir.listFiles()) {
+ if (f.isDirectory()) {
+ parseJSDirectory(f, filter);
+@@ -157,8 +165,8 @@
+ }
+ };
+ errors.setLimit(0);
+- final Source source = sourceFor(file.getAbsolutePath(), buffer);
+- new Parser(context.getEnv(), source, errors).parse();
++ final Source source = sourceFor(file.getAbsolutePath(), buffer);
++ new Parser(context.getEnv(), source, errors, context.getEnv()._strict, null).parse();
+ if (errors.getNumberOfErrors() > 0) {
+ log("Parse failed: " + file.getAbsolutePath());
+ failed++;
+@@ -166,6 +174,7 @@
+ passed++;
+ }
+ } catch (final Throwable exp) {
++ exp.printStackTrace();
+ log("Parse failed: " + file.getAbsolutePath() + " : " + exp);
+ if (VERBOSE) {
+ exp.printStackTrace(System.out);
+--- ./nashorn/test/src/jdk/nashorn/internal/performance/AuroraWrapper.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/performance/AuroraWrapper.java Wed Feb 04 12:14:47 2015 -0800
+@@ -43,6 +43,7 @@
+ import org.w3c.dom.NodeList;
+ import org.xml.sax.SAXException;
+
++@SuppressWarnings("javadoc")
+ public class AuroraWrapper {
+
+ public static String fileName = "report.xml";
+--- ./nashorn/test/src/jdk/nashorn/internal/performance/OctaneTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/performance/OctaneTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -40,6 +40,7 @@
+ import java.util.List;
+ import org.testng.annotations.Test;
+
++@SuppressWarnings("javadoc")
+ public class OctaneTest {
+
+ @Test
+@@ -72,7 +73,7 @@
+ genericTest("GBEMU");
+ }
+
+- /* @Test
++/* @Test
+ public void mandreelTest() {
+ genericTest("Mandreel");
+ }*/
+@@ -107,11 +108,21 @@
+ genericTest("Splay");
+ }
+
++ @Test
++/* public void typeScriptTest() {
++ genericTest("TypeScript");
++ }
++
++ @Test
++ public void zlibTest() {
++ genericTest("zlib");
++ }/*/
++
+ public void genericTest(final String benchmark) {
+ try {
+ final String mainScript = "test/script/basic/run-octane.js";
+- final String benchmarkScript = "test/script/external/octane/benchmarks/"+benchmark.toLowerCase() + ".js";
+- String[] args = {
++ final String benchmarkScript = "test/script/external/octane/benchmarks/" + benchmark.toLowerCase() + ".js";
++ final String[] args = {
+ "--",
+ benchmarkScript,
+ "--verbose"
+@@ -136,16 +147,17 @@
+ }
+ }
+
+- public Double genericNashornTest(final String benchmark, final String testPath, String[] args) throws Throwable {
++ public Double genericNashornTest(final String benchmark, final String testPath, final String[] args) throws Throwable {
+ try {
+ final PerformanceWrapper wrapper = new PerformanceWrapper();
+
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final PrintStream ps = new PrintStream(baos);
+
+- java.io.File test=new java.io.File(testPath);
+- File absoluteFile=test.getAbsoluteFile();
++ final java.io.File test=new java.io.File(testPath);
++ final File absoluteFile=test.getAbsoluteFile();
+ @SuppressWarnings("deprecation")
++ final
+ URL testURL=absoluteFile.toURL();
+
+ wrapper.runExecuteOnlyTest(testPath, 0, 0, testURL.toString(), ps, System.err, args);
+@@ -153,7 +165,7 @@
+ final byte[] output = baos.toByteArray();
+ final List<String> result = outputToStrings(output);
+
+- Double _result = filterBenchmark(result, benchmark);
++ final Double _result = filterBenchmark(result, benchmark);
+
+ return _result;
+ } catch (final Throwable e) {
+@@ -265,7 +277,7 @@
+ if (v8 != null && rhino != 0) {
+ nashornToV8 = nashorn.doubleValue() / v8.doubleValue();
+ }
+- String normalizedBenchmark=benchmark.replace("-", "");
++ final String normalizedBenchmark=benchmark.replace("-", "");
+ System.out.println("benchmark-" + normalizedBenchmark + "-nashorn=" + nashorn);
+ AuroraWrapper.addResults(AuroraWrapper.createOrOpenDocument(), "benchmark-" + normalizedBenchmark + "-nashorn", nashorn.toString());
+
+--- ./nashorn/test/src/jdk/nashorn/internal/performance/PerformanceWrapper.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/performance/PerformanceWrapper.java Wed Feb 04 12:14:47 2015 -0800
+@@ -36,10 +36,7 @@
+ import jdk.nashorn.internal.runtime.ScriptFunction;
+ import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+-/**
+- *
+- * @author Pavel Stepanov
+- */
++@SuppressWarnings("javadoc")
+ public class PerformanceWrapper extends jdk.nashorn.tools.Shell {
+
+ int _numberOfIterations;
+@@ -72,8 +69,8 @@
+ }
+
+
+- protected void runExecuteOnlyTest(final String name, final int numberOfIterations, final int runsPerIteration, final String testURL, final OutputStream out, final OutputStream err, String[] newargs) throws Throwable {
+- String[] args=new String[newargs.length+1];
++ protected void runExecuteOnlyTest(final String name, final int numberOfIterations, final int runsPerIteration, final String testURL, final OutputStream out, final OutputStream err, final String[] newargs) throws Throwable {
++ final String[] args=new String[newargs.length+1];
+ System.arraycopy(newargs, 0, args, 1, newargs.length);
+ args[0]=name;
+
+--- ./nashorn/test/src/jdk/nashorn/internal/performance/SplayTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/performance/SplayTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,10 +27,7 @@
+
+ import org.testng.annotations.Test;
+
+-/**
+- *
+- * @author Pavel Stepanov
+- */
++@SuppressWarnings("javadoc")
+ public class SplayTest {
+
+ @Test
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/src/jdk/nashorn/internal/runtime/ClassFilterTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,185 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
++
++import static org.testng.Assert.fail;
++import java.io.File;
++import javax.script.ScriptEngine;
++import javax.script.ScriptException;
++import jdk.nashorn.api.scripting.ClassFilter;
++import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
++import jdk.nashorn.api.scripting.URLReader;
++import jdk.nashorn.internal.test.framework.TestFinder;
++import org.testng.annotations.Test;
++
++@SuppressWarnings("javadoc")
++public class ClassFilterTest {
++ private static final String NASHORN_CODE_CACHE = "nashorn.persistent.code.cache";
++ private static final String CLASSFILTER_CODE_CACHE = "build/classfilter_nashorn_code_cache";
++
++ // @Test
++ // This test takes too much time for basic "ant clean test" run.
++ // Given that "allow-all-java-classes" is equivalent to no java class
++ // filter and external tests don't access any java, not sure if this
++ // test contributes much. We need faster "ant clean test" cycle for
++ // developers.
++ public void runExternalJsTest() {
++ final String[] paths = new String[]{
++ "test/script/basic/compile-octane.js",
++ "test/script/basic/jquery.js",
++ "test/script/basic/prototype.js",
++ "test/script/basic/runsunspider.js",
++ "test/script/basic/underscore.js",
++ "test/script/basic/yui.js",
++ "test/script/basic/run-octane.js"
++ };
++ final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
++ for (final String path : paths) {
++ final ScriptEngine engine = factory.getScriptEngine(new String[]{"-scripting"}, getClass().getClassLoader(), getClassFilter());
++ try {
++ engine.eval(new URLReader(new File(path).toURI().toURL()));
++ } catch (final Exception e) {
++ fail("Script " + path + " fails with exception :" + e.getMessage());
++ }
++ }
++ }
++
++ @Test
++ public void noJavaOptionTest() {
++ final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
++ final ScriptEngine engine = factory.getScriptEngine(new String[]{"--no-java"}, getClass().getClassLoader(), getClassFilter());
++ try {
++ engine.eval("var str = Java.type('java.lang.String');");
++ fail("TypeError should have been thrown");
++ } catch (final ScriptException e) {
++ //emtpy
++ }
++ }
++
++ @Test
++ public void securityTest() {
++ if (System.getSecurityManager() == null) {
++ return;
++ }
++
++ final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
++ final ScriptEngine engine = factory.getScriptEngine(getClassFilter());
++ try {
++ engine.eval("var thread = Java.type('sun.misc.Unsafe')");
++ fail("SecurityException should have been thrown");
++ } catch (final Exception e) {
++ //empty
++ }
++ try {
++ engine.eval("var thread = new sun.misc.Unsafe()");
++ fail("SecurityException should have been thrown");
++ } catch (final Exception e) {
++ //empty
++ }
++ try {
++ engine.eval("var thread = Java.extend(sun.misc.Unsafe, {})");
++ fail("TypeError should have been thrown");
++ } catch (final Exception e) {
++ //empty
++ }
++ try {
++ engine.eval("java.lang.System.exit(0)");
++ fail("SecurityException should have been thrown");
++ } catch (final Exception e) {
++ //empty
++ }
++
++ }
++
++ @Test
++ public void persistentCacheTest() {
++ final String oldCodeCache = System.getProperty(NASHORN_CODE_CACHE);
++ System.setProperty(NASHORN_CODE_CACHE, CLASSFILTER_CODE_CACHE);
++ try {
++ persistentCacheTestImpl();
++ } finally {
++ if (oldCodeCache != null) {
++ System.setProperty(NASHORN_CODE_CACHE, oldCodeCache);
++ }
++ }
++ }
++
++ private void persistentCacheTestImpl() {
++ final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
++ final ScriptEngine engine = factory.getScriptEngine(
++ TestFinder.addExplicitOptimisticTypes(new String[]{"--persistent-code-cache", "--optimistic-types=true"}),
++ getClass().getClassLoader(),
++ getClassFilter()
++ );
++ final String testScript = "var a = Java.type('java.lang.String');" + generateCodeForPersistentStore();
++ try {
++ engine.eval(testScript);
++ } catch (final ScriptException exc) {
++ fail(exc.getMessage());
++ }
++ final ScriptEngine engineSafe = factory.getScriptEngine(
++ TestFinder.addExplicitOptimisticTypes(new String[]{"--persistent-code-cache", "--optimistic-types=true"}),
++ getClass().getClassLoader(),
++ new ClassFilter() {
++ @Override
++ public boolean exposeToScripts(final String s) {
++ return false;
++ }
++ }
++ );
++ try {
++ engineSafe.eval(testScript);
++ fail("ClassNotFoundException should have been thrown");
++ } catch (final Exception exc) {
++ if (!(exc.getCause() instanceof ClassNotFoundException)) {
++ fail("ClassNotFoundException expected, got " + exc.getClass());
++ }
++ }
++ }
++
++ private static String generateCodeForPersistentStore() {
++ final StringBuilder stringBuilder = new StringBuilder();
++ for (int i=0; i < 100; i++) {
++ stringBuilder.append("function i")
++ .append(i)
++ .append("(y, z) { var x")
++ .append(i)
++ .append(" = ")
++ .append(i)
++ .append(";}");
++ }
++ return stringBuilder.toString();
++ }
++
++ private static ClassFilter getClassFilter() {
++ return new ClassFilter() {
++ @Override
++ public boolean exposeToScripts(final String s) {
++ return true;
++ }
++ };
++ }
++}
+--- ./nashorn/test/src/jdk/nashorn/internal/runtime/CodeStoreAndPathTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/runtime/CodeStoreAndPathTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -24,18 +24,18 @@
+ */
+ package jdk.nashorn.internal.runtime;
+
++import static org.testng.Assert.assertEquals;
++import static org.testng.Assert.assertFalse;
+ import java.io.File;
+ import java.io.IOException;
++import java.nio.file.DirectoryStream;
++import java.nio.file.FileSystems;
+ import java.nio.file.Files;
+-import java.nio.file.DirectoryStream;
+ import java.nio.file.Path;
+-import java.nio.file.FileSystems;
++import javax.script.ScriptEngine;
+ import javax.script.ScriptException;
++import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+ import org.testng.annotations.Test;
+-import javax.script.ScriptEngine;
+-import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+-import static org.testng.Assert.assertFalse;
+-import static org.testng.Assert.assertEquals;
+
+ /**
+ * @test
+@@ -43,7 +43,7 @@
+ * @summary Test for persistent code cache and path handling
+ * @run testng jdk.nashorn.internal.runtime.CodeStoreAndPathTest
+ */
+-
++@SuppressWarnings("javadoc")
+ public class CodeStoreAndPathTest {
+
+ final String code1 = "var code1; var x = 'Hello Script'; var x1 = 'Hello Script'; "
+@@ -95,27 +95,23 @@
+ final String codeCache = "build/nashorn_code_cache";
+ final String oldUserDir = System.getProperty("user.dir");
+
+- public void checkCompiledScripts(DirectoryStream<Path> stream, int numberOfScripts) throws IOException {
+- for (Path file : stream) {
+- numberOfScripts--;
+- }
+- stream.close();
+- assertEquals(numberOfScripts,0);
+- }
++ private static final String[] ENGINE_OPTIONS_OPT = new String[]{"--persistent-code-cache", "--optimistic-types=true"};
++ private static final String[] ENGINE_OPTIONS_NOOPT = new String[]{"--persistent-code-cache", "--optimistic-types=false"};
+
+ @Test
+- public void pathHandlingTest() throws ScriptException, IOException {
++ public void pathHandlingTest() {
+ System.setProperty("nashorn.persistent.code.cache", codeCache);
+- String[] options = new String[]{"--persistent-code-cache"};
+- NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
+- ScriptEngine e = fac.getScriptEngine(options);
+- Path expectedCodeCachePath = FileSystems.getDefault().getPath(oldUserDir + File.separator + codeCache);
+- Path actualCodeCachePath = FileSystems.getDefault().getPath(System.getProperty(
++ final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
++
++ fac.getScriptEngine(ENGINE_OPTIONS_NOOPT);
++
++ final Path expectedCodeCachePath = FileSystems.getDefault().getPath(oldUserDir + File.separator + codeCache);
++ final Path actualCodeCachePath = FileSystems.getDefault().getPath(System.getProperty(
+ "nashorn.persistent.code.cache")).toAbsolutePath();
+ // Check that nashorn code cache is created in current working directory
+ assertEquals(actualCodeCachePath, expectedCodeCachePath);
+ // Check that code cache dir exists and it's not empty
+- File file = new File(actualCodeCachePath.toUri());
++ final File file = new File(actualCodeCachePath.toUri());
+ assertFalse(!file.isDirectory(), "No code cache directory was created!");
+ assertFalse(file.list().length == 0, "Code cache directory is empty!");
+ }
+@@ -123,37 +119,70 @@
+ @Test
+ public void changeUserDirTest() throws ScriptException, IOException {
+ System.setProperty("nashorn.persistent.code.cache", codeCache);
+- String[] options = new String[]{"--persistent-code-cache"};
+- NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
+- ScriptEngine e = fac.getScriptEngine(options);
+- Path codeCachePath = FileSystems.getDefault().getPath(System.getProperty(
+- "nashorn.persistent.code.cache")).toAbsolutePath();
+- String newUserDir = "build/newUserDir";
++ final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
++ final ScriptEngine e = fac.getScriptEngine(ENGINE_OPTIONS_NOOPT);
++ final Path codeCachePath = getCodeCachePath(false);
++ final String newUserDir = "build/newUserDir";
+ // Now changing current working directory
+ System.setProperty("user.dir", System.getProperty("user.dir") + File.separator + newUserDir);
+- // Check that a new compiled script is stored in exisitng code cache
+- e.eval(code1);
+- DirectoryStream<Path> stream = Files.newDirectoryStream(codeCachePath);
+- // Already one compiled script has been stored in the cache during initialization
+- checkCompiledScripts(stream, 2);
+- // Setting to default current working dir
+- System.setProperty("user.dir", oldUserDir);
++ try {
++ // Check that a new compiled script is stored in existing code cache
++ e.eval(code1);
++ final DirectoryStream<Path> stream = Files.newDirectoryStream(codeCachePath);
++ checkCompiledScripts(stream, 1);
++ // Setting to default current working dir
++ } finally {
++ System.setProperty("user.dir", oldUserDir);
++ }
+ }
+
+ @Test
+ public void codeCacheTest() throws ScriptException, IOException {
+ System.setProperty("nashorn.persistent.code.cache", codeCache);
+- String[] options = new String[]{"--persistent-code-cache"};
+- NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
+- ScriptEngine e = fac.getScriptEngine(options);
+- Path codeCachePath = FileSystems.getDefault().getPath(System.getProperty(
+- "nashorn.persistent.code.cache")).toAbsolutePath();
++ final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
++ final ScriptEngine e = fac.getScriptEngine(ENGINE_OPTIONS_NOOPT);
++ final Path codeCachePath = getCodeCachePath(false);
+ e.eval(code1);
+ e.eval(code2);
+ e.eval(code3);// less than minimum size for storing
+- // Already one compiled script has been stored in the cache during initialization
+ // adding code1 and code2.
+- DirectoryStream<Path> stream = Files.newDirectoryStream(codeCachePath);
+- checkCompiledScripts(stream, 3);
++ final DirectoryStream<Path> stream = Files.newDirectoryStream(codeCachePath);
++ checkCompiledScripts(stream, 2);
+ }
++
++ @Test
++ public void codeCacheTestOpt() throws ScriptException, IOException {
++ System.setProperty("nashorn.persistent.code.cache", codeCache);
++ final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
++ final ScriptEngine e = fac.getScriptEngine(ENGINE_OPTIONS_OPT);
++ final Path codeCachePath = getCodeCachePath(true);
++ e.eval(code1);
++ e.eval(code2);
++ e.eval(code3);// less than minimum size for storing
++ // adding code1 and code2.
++ final DirectoryStream<Path> stream = Files.newDirectoryStream(codeCachePath);
++ checkCompiledScripts(stream, 2);
++ }
++
++ private static Path getCodeCachePath(final boolean optimistic) {
++ final String codeCache = System.getProperty("nashorn.persistent.code.cache");
++ final Path codeCachePath = FileSystems.getDefault().getPath(codeCache).toAbsolutePath();
++ final String[] files = codeCachePath.toFile().list();
++ for (final String file : files) {
++ if (file.endsWith("_opt") == optimistic) {
++ return codeCachePath.resolve(file);
++ }
++ }
++ throw new AssertionError("Code cache path not found");
++ }
++
++ private static void checkCompiledScripts(final DirectoryStream<Path> stream, final int numberOfScripts) throws IOException {
++ int n = numberOfScripts;
++ for (@SuppressWarnings("unused") final Path file : stream) {
++ n--;
++ }
++ stream.close();
++ assertEquals(n, 0);
++ }
++
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/src/jdk/nashorn/internal/runtime/ConsStringTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,131 @@
++/*
++ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
++
++import static org.testng.Assert.assertEquals;
++
++import org.testng.annotations.Test;
++
++/**
++ * Tests for JSType methods.
++ *
++ * @test
++ * @run testng jdk.nashorn.internal.runtime.ConsStringTest
++ */
++public class ConsStringTest {
++
++ /**
++ * Test toString conversion
++ */
++ @Test
++ public void testConsStringToString() {
++ final ConsString cs1 = new ConsString("b", "c");
++ final ConsString cs2 = new ConsString("d", "e");
++ final ConsString cs3 = new ConsString(cs1, cs2);
++ final ConsString cs4 = new ConsString(cs3, "f");
++ final ConsString cs5 = new ConsString("a", cs4);
++ assertEquals(cs5.toString(), "abcdef");
++ assertEquals(cs4.toString(), "bcdef");
++ assertEquals(cs3.toString(), "bcde");
++ assertEquals(cs2.toString(), "de");
++ assertEquals(cs1.toString(), "bc");
++ // ConsStrings should be flattened now
++ assertEquals(cs1.getComponents()[0], "bc");
++ assertEquals(cs1.getComponents()[1], "");
++ assertEquals(cs2.getComponents()[0], "de");
++ assertEquals(cs2.getComponents()[1], "");
++ assertEquals(cs3.getComponents()[0], "bcde");
++ assertEquals(cs3.getComponents()[1], "");
++ assertEquals(cs4.getComponents()[0], "bcdef");
++ assertEquals(cs4.getComponents()[1], "");
++ assertEquals(cs5.getComponents()[0], "abcdef");
++ assertEquals(cs5.getComponents()[1], "");
++ }
++
++ /**
++ * Test charAt
++ */
++ @Test
++ public void testConsStringCharAt() {
++ final ConsString cs1 = new ConsString("b", "c");
++ final ConsString cs2 = new ConsString("d", "e");
++ final ConsString cs3 = new ConsString(cs1, cs2);
++ final ConsString cs4 = new ConsString(cs3, "f");
++ final ConsString cs5 = new ConsString("a", cs4);
++ assertEquals(cs1.charAt(1), 'c');
++ assertEquals(cs2.charAt(0), 'd');
++ assertEquals(cs3.charAt(3), 'e');
++ assertEquals(cs4.charAt(1), 'c');
++ assertEquals(cs5.charAt(2), 'c');
++ // ConsStrings should be flattened now
++ assertEquals(cs1.getComponents()[0], "bc");
++ assertEquals(cs1.getComponents()[1], "");
++ assertEquals(cs2.getComponents()[0], "de");
++ assertEquals(cs2.getComponents()[1], "");
++ assertEquals(cs3.getComponents()[0], "bcde");
++ assertEquals(cs3.getComponents()[1], "");
++ assertEquals(cs4.getComponents()[0], "bcdef");
++ assertEquals(cs4.getComponents()[1], "");
++ assertEquals(cs5.getComponents()[0], "abcdef");
++ assertEquals(cs5.getComponents()[1], "");
++ }
++
++
++ /**
++ * Test flattening of top-level and internal ConsStrings
++ */
++ @Test
++ public void testConsStringFlattening() {
++ final ConsString cs1 = new ConsString("b", "c");
++ final ConsString cs2 = new ConsString("d", "e");
++ final ConsString cs3 = new ConsString(cs1, cs2);
++ final ConsString cs4 = new ConsString(cs3, "f");
++
++ final ConsString cs5 = new ConsString("a", cs4);
++ // top-level ConsString should not yet be flattened
++ assert(cs5.getComponents()[0] == "a");
++ assert(cs5.getComponents()[1] == cs4);
++ assertEquals(cs5.toString(), "abcdef");
++ // top-level ConsString should be flattened
++ assertEquals(cs5.getComponents()[0], "abcdef");
++ assertEquals(cs5.getComponents()[1], "");
++ // internal ConsString should not yet be flattened after first traversal
++ assertEquals(cs4.getComponents()[0], cs3);
++ assertEquals(cs4.getComponents()[1], "f");
++
++ final ConsString cs6 = new ConsString("a", cs4);
++ // top-level ConsString should not yet be flattened
++ assertEquals(cs6.getComponents()[0], "a");
++ assertEquals(cs6.getComponents()[1], cs4);
++ assertEquals(cs6.toString(), "abcdef");
++ // top-level ConsString should be flattened
++ assertEquals(cs6.getComponents()[0], "abcdef");
++ assertEquals(cs6.getComponents()[1], "");
++ // internal ConsString should have been flattened after second traversal
++ assertEquals(cs4.getComponents()[0], "bcdef");
++ assertEquals(cs4.getComponents()[1], "");
++ }
++}
+--- ./nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,7 +28,7 @@
+ import static jdk.nashorn.internal.runtime.Source.sourceFor;
+ import static org.testng.Assert.assertEquals;
+ import static org.testng.Assert.assertTrue;
+-
++import static org.testng.Assert.fail;
+ import java.util.Map;
+ import jdk.nashorn.internal.objects.Global;
+ import jdk.nashorn.internal.runtime.options.Options;
+@@ -40,6 +40,7 @@
+ * @test
+ * @run testng jdk.nashorn.internal.runtime.ContextTest
+ */
++@SuppressWarnings("javadoc")
+ public class ContextTest {
+ // basic context eval test
+ @Test
+@@ -60,6 +61,27 @@
+ }
+ }
+
++ // Make sure trying to compile an invalid script returns null - see JDK-8046215.
++ @Test
++ public void compileErrorTest() {
++ final Options options = new Options("");
++ final ErrorManager errors = new ErrorManager();
++ final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
++ final Global oldGlobal = Context.getGlobal();
++ Context.setGlobal(cx.createGlobal());
++ try {
++ final ScriptFunction script = cx.compileScript(sourceFor("<evalCompileErrorTest>", "*/"), Context.getGlobal());
++ if (script != null) {
++ fail("Invalid script compiled without errors");
++ }
++ if (errors.getNumberOfErrors() != 1) {
++ fail("Wrong number of errors: " + errors.getNumberOfErrors());
++ }
++ } finally {
++ Context.setGlobal(oldGlobal);
++ }
++ }
++
+ // basic check for JS reflection access - java.util.Map-like access on ScriptObject
+ @Test
+ public void reflectionTest() {
+@@ -74,7 +96,7 @@
+ final String code = "var obj = { x: 344, y: 42 }";
+ eval(cx, "<reflectionTest>", code);
+
+- final Object obj = cx.getGlobal().get("obj");
++ final Object obj = Context.getGlobal().get("obj");
+
+ assertTrue(obj instanceof ScriptObject);
+
+@@ -107,7 +129,7 @@
+ }
+ }
+
+- private Object eval(final Context cx, final String name, final String code) {
++ private static Object eval(final Context cx, final String name, final String code) {
+ final Source source = sourceFor(name, code);
+ final ScriptObject global = Context.getGlobal();
+ final ScriptFunction func = cx.compileScript(source, global);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/src/jdk/nashorn/internal/runtime/ExceptionsNotSerializable.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,77 @@
++/*
++ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
++
++import static org.testng.Assert.assertEquals;
++import static org.testng.Assert.fail;
++import java.io.ByteArrayOutputStream;
++import java.io.IOException;
++import java.io.NotSerializableException;
++import java.io.ObjectOutputStream;
++import javax.script.ScriptEngine;
++import javax.script.ScriptException;
++import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
++import org.testng.annotations.Test;
++
++/**
++ * JDK-8044518: Ensure exceptions related to optimistic recompilation are not serializable
++ *
++ * @test
++ * @run testng jdk.nashorn.internal.runtime.ExceptionsNotSerializable
++ */
++@SuppressWarnings("javadoc")
++public class ExceptionsNotSerializable {
++ @Test
++ public void rewriteExceptionNotSerializable() throws ScriptException {
++ // NOTE: we must create a RewriteException in a context of a Nashorn engine, as it uses Global.newIntance()
++ // internally.
++ final ScriptEngine e = new NashornScriptEngineFactory().getScriptEngine();
++ e.put("f", new Runnable() {
++ @Override
++ public void run() {
++ tryToSerialize(RewriteException.create(null, new Object[0], new String[0]));
++ }
++ });
++ e.eval("f()");
++ }
++
++ @Test
++ public void unwarrantedOptimismExceptionNotSerializable() {
++ tryToSerialize(new UnwarrantedOptimismException(new Double(1.0), 128));
++ }
++
++ private static void tryToSerialize(final Object obj) {
++ try {
++ new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(obj);
++ fail();
++ } catch (final NotSerializableException e) {
++ assertEquals(e.getMessage(), obj.getClass().getName());
++ } catch (final IOException e) {
++ fail("", e);
++ }
++
++ }
++}
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/src/jdk/nashorn/internal/runtime/LexicalBindingTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,212 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.internal.runtime;
++
++import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
++import org.testng.annotations.Test;
++
++import javax.script.Bindings;
++import javax.script.ScriptContext;
++import javax.script.ScriptEngine;
++import javax.script.ScriptException;
++import javax.script.SimpleScriptContext;
++
++import static org.testng.Assert.assertEquals;
++
++/**
++ * Top-level lexical binding tests.
++ *
++ * @test
++ * @run testng jdk.nashorn.internal.runtime.LexicalBindingTest
++ */
++@SuppressWarnings("javadoc")
++public class LexicalBindingTest {
++
++ final static String LANGUAGE_ES6 = "--language=es6";
++ final static int NUMBER_OF_CONTEXTS = 20;
++ final static int MEGAMORPHIC_LOOP_COUNT = 20;
++
++ /**
++ * Test access to global var-declared variables for shared script classes with multiple globals.
++ */
++ @Test
++ public static void megamorphicVarTest() throws ScriptException, InterruptedException {
++ final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
++ final ScriptEngine e = factory.getScriptEngine();
++ final ScriptContext[] contexts = new ScriptContext[NUMBER_OF_CONTEXTS];
++ final String sharedScript = "foo";
++
++
++ for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) {
++ final ScriptContext context = contexts[i] = new SimpleScriptContext();
++ final Bindings b = e.createBindings();
++ context.setBindings(b, ScriptContext.ENGINE_SCOPE);
++ assertEquals(e.eval("var foo = '" + i + "';", context), null);
++ }
++
++ for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) {
++ final ScriptContext context = contexts[i];
++ assertEquals(e.eval(sharedScript, context), String.valueOf(i));
++ }
++ }
++
++ /**
++ * Test access to global lexically declared variables for shared script classes with multiple globals.
++ */
++ @Test
++ public static void megamorphicMultiGlobalLetTest() throws ScriptException, InterruptedException {
++ final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
++ final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6);
++ final ScriptContext[] contexts = new ScriptContext[NUMBER_OF_CONTEXTS];
++ final String sharedScript = "foo";
++
++
++ for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) {
++ final ScriptContext context = contexts[i] = new SimpleScriptContext();
++ final Bindings b = e.createBindings();
++ context.setBindings(b, ScriptContext.ENGINE_SCOPE);
++ assertEquals(e.eval("let foo = '" + i + "';", context), null);
++ }
++
++ for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) {
++ final ScriptContext context = contexts[i];
++ assertEquals(e.eval(sharedScript, context), String.valueOf(i));
++ }
++ }
++
++
++ /**
++ * Test access to global lexically declared variables for shared script classes with single global.
++ */
++ @Test
++ public static void megamorphicSingleGlobalLetTest() throws ScriptException, InterruptedException {
++ final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
++ final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6);
++ final String sharedGetterScript = "foo";
++ final String sharedSetterScript = "foo = 1";
++
++ for (int i = 0; i < MEGAMORPHIC_LOOP_COUNT; i++) {
++ assertEquals(e.eval(sharedSetterScript), 1);
++ assertEquals(e.eval(sharedGetterScript), 1);
++ assertEquals(e.eval("delete foo; a" + i + " = 1; foo = " + i + ";"), i);
++ assertEquals(e.eval(sharedGetterScript), i);
++ }
++
++ assertEquals(e.eval("let foo = 'foo';"), null);
++ assertEquals(e.eval(sharedGetterScript), "foo");
++ assertEquals(e.eval(sharedSetterScript), 1);
++ assertEquals(e.eval(sharedGetterScript), 1);
++ assertEquals(e.eval("this.foo"), MEGAMORPHIC_LOOP_COUNT - 1);
++ }
++
++ /**
++ * Test access to global lexically declared variables for shared script classes with single global.
++ */
++ @Test
++ public static void megamorphicInheritedGlobalLetTest() throws ScriptException, InterruptedException {
++ final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
++ final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6);
++ final String sharedGetterScript = "foo";
++ final String sharedSetterScript = "foo = 1";
++
++ for (int i = 0; i < MEGAMORPHIC_LOOP_COUNT; i++) {
++ assertEquals(e.eval(sharedSetterScript), 1);
++ assertEquals(e.eval(sharedGetterScript), 1);
++ assertEquals(e.eval("delete foo; a" + i + " = 1; Object.prototype.foo = " + i + ";"), i);
++ assertEquals(e.eval(sharedGetterScript), i);
++ }
++
++ assertEquals(e.eval("let foo = 'foo';"), null);
++ assertEquals(e.eval(sharedGetterScript), "foo");
++ assertEquals(e.eval(sharedSetterScript), 1);
++ assertEquals(e.eval(sharedGetterScript), 1);
++ assertEquals(e.eval("this.foo"), MEGAMORPHIC_LOOP_COUNT - 1);
++ }
++
++ /**
++ * Test multi-threaded access to global lexically declared variables for shared script classes with multiple globals.
++ */
++ @Test
++ public static void multiThreadedLetTest() throws ScriptException, InterruptedException {
++ final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
++ final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6);
++ final Bindings b = e.createBindings();
++ final ScriptContext origContext = e.getContext();
++ final ScriptContext newCtxt = new SimpleScriptContext();
++ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
++ final String sharedScript = "foo";
++
++ assertEquals(e.eval("let foo = 'original context';", origContext), null);
++ assertEquals(e.eval("let foo = 'new context';", newCtxt), null);
++
++ final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
++ final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
++ t1.start();
++ t2.start();
++ t1.join();
++ t2.join();
++
++ assertEquals(e.eval("foo = 'newer context';", newCtxt), "newer context");
++ final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
++ final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
++
++ t3.start();
++ t4.start();
++ t3.join();
++ t4.join();
++
++ assertEquals(e.eval(sharedScript), "original context");
++ assertEquals(e.eval(sharedScript, newCtxt), "newer context");
++ }
++
++ private static class ScriptRunner implements Runnable {
++
++ final ScriptEngine engine;
++ final ScriptContext context;
++ final String source;
++ final Object expected;
++ final int iterations;
++
++ ScriptRunner(final ScriptEngine engine, final ScriptContext context, final String source, final Object expected, final int iterations) {
++ this.engine = engine;
++ this.context = context;
++ this.source = source;
++ this.expected = expected;
++ this.iterations = iterations;
++ }
++
++ @Override
++ public void run() {
++ try {
++ for (int i = 0; i < iterations; i++) {
++ assertEquals(engine.eval(source, context), expected);
++ }
++ } catch (final ScriptException se) {
++ throw new RuntimeException(se);
++ }
++ }
++ }
++}
+--- ./nashorn/test/src/jdk/nashorn/internal/runtime/NoPersistenceCachingTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/runtime/NoPersistenceCachingTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -24,13 +24,11 @@
+ */
+ package jdk.nashorn.internal.runtime;
+
++import static org.testng.Assert.fail;
+ import java.io.ByteArrayOutputStream;
+ import java.io.PrintStream;
+ import java.util.regex.Matcher;
+ import java.util.regex.Pattern;
+-import static org.testng.Assert.fail;
+-import org.testng.annotations.Test;
+-
+ import javax.script.ScriptContext;
+ import javax.script.ScriptEngine;
+ import javax.script.ScriptEngineFactory;
+@@ -39,6 +37,7 @@
+ import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+ import org.testng.annotations.AfterTest;
+ import org.testng.annotations.BeforeTest;
++import org.testng.annotations.Test;
+
+ /**
+ * @test
+@@ -46,6 +45,7 @@
+ * @summary Sanity tests for no persistence caching
+ * @run testng/othervm jdk.nashorn.internal.runtime.NoPersistenceCachingTest
+ */
++@SuppressWarnings("javadoc")
+ public class NoPersistenceCachingTest {
+
+ private ScriptEngine engine;
+@@ -59,8 +59,8 @@
+ prevStderr = System.err;
+ System.setErr(new PrintStream(stderr));
+ NashornScriptEngineFactory nashornFactory = null;
+- ScriptEngineManager sm = new ScriptEngineManager();
+- for (ScriptEngineFactory fac : sm.getEngineFactories()) {
++ final ScriptEngineManager sm = new ScriptEngineManager();
++ for (final ScriptEngineFactory fac : sm.getEngineFactories()) {
+ if (fac instanceof NashornScriptEngineFactory) {
+ nashornFactory = (NashornScriptEngineFactory) fac;
+ break;
+@@ -69,7 +69,10 @@
+ if (nashornFactory == null) {
+ fail("Cannot find nashorn factory!");
+ }
+- String[] options = new String[]{"--log=compiler:finest"};
++ // fine is enough for cache hits, finest produces way too much information
++ // TODO this should be ported to use the RuntimeEvents instead of screen scraping
++ // logs, as obviously this is very brittle
++ final String[] options = new String[]{"--log=compiler:fine"};
+ engine = nashornFactory.getScriptEngine(options);
+ context1 = engine.getContext();
+ context2 = new SimpleScriptContext();
+@@ -83,29 +86,31 @@
+ System.setErr(prevStderr);
+ }
+
+- public void runTest(int numberOfContext, String expectedOutputPattern,
+- int expectedPatternOccurrence) {
++ public void runTest(final int numberOfContext, final String expectedOutputPattern,
++ final int expectedPatternOccurrence) {
+
+ try {
+ switch (numberOfContext) {
+ case 2:
+- String scriptTwoContexts = "print('HelloTwoContexts')";
++ final String scriptTwoContexts = "print('HelloTwoContexts')";
+ engine.eval(scriptTwoContexts, context1);
+ engine.eval(scriptTwoContexts, context2);
+ break;
+ case 3:
+- String scriptThreeContexts = "print('HelloThreeContexts')";
++ final String scriptThreeContexts = "print('HelloThreeContexts')";
+ engine.eval(scriptThreeContexts, context1);
+ engine.eval(scriptThreeContexts, context2);
+ engine.eval(scriptThreeContexts, context3);
+ break;
++ default:
++ break;
+ }
+ } catch (final Exception se) {
+ se.printStackTrace();
+ fail(se.getMessage());
+ }
+- Pattern deoptimizing = Pattern.compile(expectedOutputPattern);
+- Matcher matcher = deoptimizing.matcher(stderr.toString());
++ final Pattern deoptimizing = Pattern.compile(expectedOutputPattern);
++ final Matcher matcher = deoptimizing.matcher(stderr.toString());
+ int matches = 0;
+ while (matcher.find()) {
+ matches++;
+--- ./nashorn/test/src/jdk/nashorn/internal/runtime/SourceTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/runtime/SourceTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,24 +25,23 @@
+
+ package jdk.nashorn.internal.runtime;
+
+-import jdk.nashorn.api.scripting.URLReader;
+-import org.testng.annotations.Test;
+-
++import static jdk.nashorn.internal.runtime.Source.sourceFor;
++import static org.testng.Assert.assertEquals;
++import static org.testng.Assert.assertTrue;
++import static org.testng.Assert.fail;
+ import java.io.File;
+ import java.io.IOException;
+ import java.io.InputStreamReader;
+ import java.io.Reader;
+ import java.net.URL;
+ import java.util.Arrays;
+-
+-import static jdk.nashorn.internal.runtime.Source.sourceFor;
+-import static org.testng.Assert.assertEquals;
+-import static org.testng.Assert.assertTrue;
+-import static org.testng.Assert.fail;
++import jdk.nashorn.api.scripting.URLReader;
++import org.testng.annotations.Test;
+
+ /**
+ * Tests different Source representations.
+ */
++@SuppressWarnings("javadoc")
+ public class SourceTest {
+
+ final private static String SOURCE_NAME = "source.js";
+@@ -105,11 +104,11 @@
+ }
+ }
+
+- private Reader getReader(final String path) {
++ private static Reader getReader(final String path) {
+ return new InputStreamReader(SourceTest.class.getResourceAsStream(path));
+ }
+
+- private void testSources(final Source source1, final Source source2) {
++ private static void testSources(final Source source1, final Source source2) {
+ final char[] chars1 = source1.getContent();
+ final char[] chars2 = source2.getContent();
+ final String str1 = source1.getString();
+@@ -118,9 +117,6 @@
+ assertEquals(str1, str2);
+ assertEquals(source1.hashCode(), source2.hashCode());
+ assertTrue(source1.equals(source2));
+- // Test for immutability
+- Arrays.fill(source1.getContent(), (char)0);
+- Arrays.fill(source2.getContent(), (char)1);
+ assertTrue(Arrays.equals(source1.getContent(), str1.toCharArray()));
+ assertTrue(Arrays.equals(source1.getContent(), chars1));
+ assertTrue(Arrays.equals(source1.getContent(), source2.getContent()));
+--- ./nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,20 +28,20 @@
+ import static org.testng.Assert.assertEquals;
+ import static org.testng.Assert.assertTrue;
+ import static org.testng.Assert.fail;
+-
++import javax.script.ScriptContext;
+ import javax.script.ScriptEngine;
+ import javax.script.ScriptEngineFactory;
+ import javax.script.ScriptEngineManager;
+-import javax.script.ScriptContext;
+ import javax.script.ScriptException;
+-import javax.script.SimpleBindings;
+ import javax.script.SimpleScriptContext;
++import jdk.nashorn.api.scripting.ClassFilter;
+ import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+ import org.testng.annotations.Test;
+
+ /**
+ * Tests for trusted client usage of nashorn script engine factory extension API
+ */
++@SuppressWarnings("javadoc")
+ public class TrustedScriptEngineTest {
+ @Test
+ public void versionTest() {
+@@ -55,7 +55,7 @@
+ private final boolean[] reached = new boolean[1];
+
+ @Override
+- protected Class findClass(final String name) throws ClassNotFoundException {
++ protected Class<?> findClass(final String name) throws ClassNotFoundException {
+ // flag that it reached here
+ reached[0] = true;
+ return super.findClass(name);
+@@ -64,7 +64,7 @@
+ public boolean reached() {
+ return reached[0];
+ }
+- };
++ }
+
+ // These are for "private" extension API of NashornScriptEngineFactory that
+ // accepts a ClassLoader and/or command line options.
+@@ -72,7 +72,7 @@
+ @Test
+ public void factoryClassLoaderTest() {
+ final ScriptEngineManager sm = new ScriptEngineManager();
+- for (ScriptEngineFactory fac : sm.getEngineFactories()) {
++ for (final ScriptEngineFactory fac : sm.getEngineFactories()) {
+ if (fac instanceof NashornScriptEngineFactory) {
+ final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac;
+ final MyClassLoader loader = new MyClassLoader();
+@@ -96,7 +96,7 @@
+ @Test
+ public void factoryClassLoaderAndOptionsTest() {
+ final ScriptEngineManager sm = new ScriptEngineManager();
+- for (ScriptEngineFactory fac : sm.getEngineFactories()) {
++ for (final ScriptEngineFactory fac : sm.getEngineFactories()) {
+ if (fac instanceof NashornScriptEngineFactory) {
+ final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac;
+ final String[] options = new String[] { "-strict" };
+@@ -130,7 +130,7 @@
+ @Test
+ public void factoryOptionsTest() {
+ final ScriptEngineManager sm = new ScriptEngineManager();
+- for (ScriptEngineFactory fac : sm.getEngineFactories()) {
++ for (final ScriptEngineFactory fac : sm.getEngineFactories()) {
+ if (fac instanceof NashornScriptEngineFactory) {
+ final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac;
+ // specify --no-syntax-extensions flag
+@@ -140,7 +140,8 @@
+ // try nashorn specific extension
+ e.eval("var f = funtion(x) 2*x;");
+ fail("should have thrown exception!");
+- } catch (final ScriptException se) {
++ } catch (final Exception ex) {
++ //empty
+ }
+ return;
+ }
+@@ -156,7 +157,7 @@
+ */
+ public void noLoaderPerCompilerTest() {
+ final ScriptEngineManager sm = new ScriptEngineManager();
+- for (ScriptEngineFactory fac : sm.getEngineFactories()) {
++ for (final ScriptEngineFactory fac : sm.getEngineFactories()) {
+ if (fac instanceof NashornScriptEngineFactory) {
+ final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac;
+ final String[] options = new String[] { "--loader-per-compile=false" };
+@@ -181,7 +182,7 @@
+ */
+ public void noLoaderPerCompilerWithSameNameTest() {
+ final ScriptEngineManager sm = new ScriptEngineManager();
+- for (ScriptEngineFactory fac : sm.getEngineFactories()) {
++ for (final ScriptEngineFactory fac : sm.getEngineFactories()) {
+ if (fac instanceof NashornScriptEngineFactory) {
+ final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac;
+ final String[] options = new String[] { "--loader-per-compile=false" };
+@@ -221,8 +222,106 @@
+ assertTrue(e.eval("typeof bar").equals("function"));
+ }
+
++ @Test
++ public void classFilterTest() throws ScriptException {
++ final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
++ final ScriptEngine e = fac.getScriptEngine(new ClassFilter() {
++ @Override
++ public boolean exposeToScripts(final String fullName) {
++ // don't allow anything that is not "java."
++ return fullName.startsWith("java.");
++ }
++ });
+
+- @Test public void nashornSwallowsConstKeyword() throws Exception {
++ assertEquals(e.eval("typeof javax.script.ScriptEngine"), "object");
++ assertEquals(e.eval("typeof java.util.Vector"), "function");
++
++ try {
++ e.eval("Java.type('javax.script.ScriptContext')");
++ fail("should not reach here");
++ } catch (final ScriptException | RuntimeException se) {
++ if (! (se.getCause() instanceof ClassNotFoundException)) {
++ fail("ClassNotFoundException expected");
++ }
++ }
++ }
++
++ @Test
++ public void classFilterTest2() throws ScriptException {
++ final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
++ final ScriptEngine e = fac.getScriptEngine(new String[0], Thread.currentThread().getContextClassLoader(),
++ new ClassFilter() {
++ @Override
++ public boolean exposeToScripts(final String fullName) {
++ // don't allow anything that is not "java."
++ return fullName.startsWith("java.");
++ }
++ });
++
++ assertEquals(e.eval("typeof javax.script.ScriptEngine"), "object");
++ assertEquals(e.eval("typeof java.util.Vector"), "function");
++
++ try {
++ e.eval("Java.type('javax.script.ScriptContext')");
++ fail("should not reach here");
++ } catch (final ScriptException | RuntimeException se) {
++ if (! (se.getCause() instanceof ClassNotFoundException)) {
++ fail("ClassNotFoundException expected");
++ }
++ }
++ }
++
++ @Test
++ public void nullClassFilterTest() {
++ final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
++ try {
++ fac.getScriptEngine((ClassFilter)null);
++ fail("should have thrown NPE");
++ } catch (final NullPointerException e) {
++ //empty
++ }
++ }
++
++ @Test
++ public void nullClassFilterTest2() {
++ final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
++ try {
++ fac.getScriptEngine(new String[0], null, null);
++ fail("should have thrown NPE");
++ } catch (final NullPointerException e) {
++ //empty
++ }
++ }
++
++ @Test
++ public void nullArgsTest() {
++ final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
++ try {
++ fac.getScriptEngine((String[])null);
++ fail("should have thrown NPE");
++ } catch (final NullPointerException e) {
++ //empty
++ }
++ }
++
++ @Test
++ public void nullArgsTest2() {
++ final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
++ try {
++ fac.getScriptEngine(null, null, new ClassFilter() {
++ @Override
++ public boolean exposeToScripts(final String name) {
++ return true;
++ }
++ });
++ fail("should have thrown NPE");
++ } catch (final NullPointerException e) {
++ //empty
++ }
++ }
++
++ @Test
++ public void nashornSwallowsConstKeyword() throws Exception {
+ final NashornScriptEngineFactory f = new NashornScriptEngineFactory();
+ final String[] args = new String[] { "--const-as-var" };
+ final ScriptEngine engine = f.getScriptEngine(args);
+@@ -235,4 +334,29 @@
+ );
+ assertEquals(ret, 10, "Parsed and executed OK");
+ }
++
++ @Test
++ public void evalDefaultFileNameTest() throws ScriptException {
++ final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
++ final ScriptEngine engine = fac.getScriptEngine(new String[] { "--verify-code=true" });
++ // default FILENAME being "<eval>" make sure generated code bytecode verifies.
++ engine.eval("var a = 3;");
++ }
++
++ @Test
++ public void evalFileNameWithSpecialCharsTest() throws ScriptException {
++ final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
++ final ScriptEngine engine = fac.getScriptEngine(new String[] { "--verify-code=true" });
++ final ScriptContext ctxt = new SimpleScriptContext();
++ // use file name with "dangerous" chars.
++ ctxt.setAttribute(ScriptEngine.FILENAME, "<myscript>", ScriptContext.ENGINE_SCOPE);
++ engine.eval("var a = 3;");
++ ctxt.setAttribute(ScriptEngine.FILENAME, "[myscript]", ScriptContext.ENGINE_SCOPE);
++ engine.eval("var h = 'hello';");
++ ctxt.setAttribute(ScriptEngine.FILENAME, ";/\\$.", ScriptContext.ENGINE_SCOPE);
++ engine.eval("var foo = 'world';");
++ // name used by jjs shell tool for the interactive mode
++ ctxt.setAttribute(ScriptEngine.FILENAME, "<shell>", ScriptContext.ENGINE_SCOPE);
++ engine.eval("var foo = 'world';");
++ }
+ }
+--- ./nashorn/test/src/jdk/nashorn/internal/runtime/regexp/JdkRegExpTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/runtime/regexp/JdkRegExpTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -29,7 +29,6 @@
+ import static org.testng.Assert.assertNotNull;
+ import static org.testng.Assert.assertTrue;
+
+-import jdk.nashorn.internal.runtime.ParserException;
+ import org.testng.annotations.Test;
+
+ /**
+@@ -45,8 +44,8 @@
+ */
+ @Test
+ public void testMatcher() {
+- RegExp regexp = new RegExpFactory().compile("f(o)o", "");
+- RegExpMatcher matcher = regexp.match("foo");
++ final RegExp regexp = new RegExpFactory().compile("f(o)o", "");
++ final RegExpMatcher matcher = regexp.match("foo");
+ assertNotNull(matcher);
+ assertTrue(matcher.search(0));
+ assertEquals(matcher.getInput(), "foo");
+--- ./nashorn/test/src/jdk/nashorn/internal/runtime/regexp/joni/JoniTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/runtime/regexp/joni/JoniTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,9 +25,6 @@
+
+ package jdk.nashorn.internal.runtime.regexp.joni;
+
+-import static org.testng.Assert.assertEquals;
+-import static org.testng.Assert.assertTrue;
+-
+ import org.testng.annotations.Test;
+
+ /**
+@@ -36,6 +33,7 @@
+ * @test
+ * @run testng jdk.nashorn.internal.runtime.regexp.joni.JoniTest
+ */
++@SuppressWarnings("javadoc")
+ public class JoniTest {
+
+ @Test
+--- ./nashorn/test/src/jdk/nashorn/internal/test/framework/AbstractScriptRunnable.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/test/framework/AbstractScriptRunnable.java Wed Feb 04 12:14:47 2015 -0800
+@@ -34,7 +34,6 @@
+ import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_RUN;
+ import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_FAIL_LIST;
+ import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_SHARED_CONTEXT;
+-
+ import java.io.BufferedReader;
+ import java.io.File;
+ import java.io.IOException;
+@@ -50,6 +49,7 @@
+ /**
+ * Abstract class to compile and run one .js script file.
+ */
++@SuppressWarnings("javadoc")
+ public abstract class AbstractScriptRunnable {
+ // some test scripts need a "framework" script - whose features are used
+ // in the test script. This optional framework script can be null.
+@@ -155,7 +155,7 @@
+ // VM options when a @fork test is executed by a separate process
+ protected static final String[] forkJVMOptions;
+ static {
+- String vmOptions = System.getProperty(TestConfig.TEST_FORK_JVM_OPTIONS);
++ final String vmOptions = System.getProperty(TestConfig.TEST_FORK_JVM_OPTIONS);
+ forkJVMOptions = (vmOptions != null)? vmOptions.split(" ") : new String[0];
+ }
+
+@@ -274,14 +274,14 @@
+ // compile and run this script
+ protected abstract void execute();
+
+- private boolean equalsCompilerMsgs(final String es, final String as) {
++ private static boolean equalsCompilerMsgs(final String es, final String as) {
+ final int split = es.indexOf(':');
+ // Replace both types of separators ('/' and '\') with the one from
+ // current environment
+ return (split >= 0) && as.equals(es.substring(0, split).replaceAll("[/\\\\]", Matcher.quoteReplacement(File.separator)) + es.substring(split));
+ }
+
+- private void escape(final String value, final StringBuilder out) {
++ private static void escape(final String value, final StringBuilder out) {
+ final int len = value.length();
+ for (int i = 0; i < len; i++) {
+ final char ch = value.charAt(i);
+@@ -297,7 +297,7 @@
+ }
+ }
+
+- private String escape(final String value) {
++ private static String escape(final String value) {
+ final StringBuilder sb = new StringBuilder();
+ escape(value, sb);
+ return sb.toString();
+--- ./nashorn/test/src/jdk/nashorn/internal/test/framework/JSJUnitReportReporter.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/test/framework/JSJUnitReportReporter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -34,7 +34,7 @@
+ */
+ public class JSJUnitReportReporter extends JUnitReportReporter {
+ @Override
+- protected String getTestName(ITestResult tr) {
++ protected String getTestName(final ITestResult tr) {
+ final String testName = tr.getTestName();
+ return (testName != null && testName.endsWith(".js"))? testName : super.getTestName(tr);
+ }
+--- ./nashorn/test/src/jdk/nashorn/internal/test/framework/OrphanTestFinder.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/test/framework/OrphanTestFinder.java Wed Feb 04 12:14:47 2015 -0800
+@@ -34,6 +34,7 @@
+ * Test case used by JSCompilerTest to complain if test files are marked as
+ * neither test nor subtest.
+ */
++@SuppressWarnings("javadoc")
+ public final class OrphanTestFinder implements ITest {
+ private final Set<String> orphanFiles;
+
+--- ./nashorn/test/src/jdk/nashorn/internal/test/framework/ParallelTestRunner.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/test/framework/ParallelTestRunner.java Wed Feb 04 12:14:47 2015 -0800
+@@ -31,7 +31,6 @@
+ import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_EXCLUDE_LIST;
+ import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_FRAMEWORK;
+ import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_ROOTS;
+-
+ import java.io.BufferedReader;
+ import java.io.ByteArrayOutputStream;
+ import java.io.File;
+@@ -73,12 +72,14 @@
+ * Parallel test runner runs tests in multiple threads - but avoids any dependency
+ * on third-party test framework library such as TestNG.
+ */
++@SuppressWarnings("javadoc")
+ public class ParallelTestRunner {
+
+ // ParallelTestRunner-specific
+ private static final String TEST_JS_THREADS = "test.js.threads";
+ private static final String TEST_JS_REPORT_FILE = "test.js.report.file";
+- private static final int THREADS = Integer.getInteger(TEST_JS_THREADS, Runtime.getRuntime().availableProcessors());
++ // test262 does a lot of eval's and the JVM hates multithreaded class definition, so lower thread count is usually faster.
++ private static final int THREADS = Integer.getInteger(TEST_JS_THREADS, Runtime.getRuntime().availableProcessors() > 4 ? 4 : 2);
+
+ private final List<ScriptRunnable> tests = new ArrayList<>();
+ private final Set<String> orphans = new TreeSet<>();
+@@ -149,7 +150,7 @@
+ }
+
+ @Override
+- protected void log(String msg) {
++ protected void log(final String msg) {
+ System.err.println(msg);
+ }
+
+@@ -235,6 +236,7 @@
+ outputFile.write(out.toByteArray());
+ errorFile.write(err.toByteArray());
+ }
++ ex.printStackTrace();
+ throw ex;
+ }
+ }
+@@ -245,7 +247,7 @@
+ }
+ }
+
+- private void compare(final String outputFileName, final String expected, final boolean compareCompilerMsg) throws IOException {
++ private void compare(final String fileName, final String expected, final boolean compareCompilerMsg) throws IOException {
+ final File expectedFile = new File(expected);
+
+ BufferedReader expectedReader;
+@@ -255,7 +257,7 @@
+ expectedReader = new BufferedReader(new StringReader(""));
+ }
+
+- final BufferedReader actual = new BufferedReader(new InputStreamReader(new FileInputStream(outputFileName)));
++ final BufferedReader actual = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));
+
+ compare(actual, expectedReader, compareCompilerMsg);
+ }
+@@ -280,6 +282,7 @@
+ } catch (final Throwable ex) {
+ result.exception = ex;
+ result.passed = false;
++ ex.printStackTrace();
+ }
+ return result;
+ }
+@@ -306,12 +309,12 @@
+
+ final TestFactory<ScriptRunnable> testFactory = new TestFactory<ScriptRunnable>() {
+ @Override
+- public ScriptRunnable createTest(String framework, File testFile, List<String> engineOptions, Map<String, String> testOptions, List<String> arguments) {
++ public ScriptRunnable createTest(final String framework, final File testFile, final List<String> engineOptions, final Map<String, String> testOptions, final List<String> arguments) {
+ return new ScriptRunnable(framework, testFile, engineOptions, testOptions, arguments);
+ }
+
+ @Override
+- public void log(String msg) {
++ public void log(final String msg) {
+ System.err.println(msg);
+ }
+ };
+@@ -431,7 +434,9 @@
+ public static void main(final String[] args) throws Exception {
+ parseArgs(args);
+
+- while(new ParallelTestRunner().run());
++ while (new ParallelTestRunner().run()) {
++ //empty
++ }
+ }
+
+ private static void parseArgs(final String[] args) {
+--- ./nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptRunnable.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptRunnable.java Wed Feb 04 12:14:47 2015 -0800
+@@ -40,10 +40,8 @@
+ import java.nio.file.Files;
+ import java.nio.file.StandardCopyOption;
+ import java.util.ArrayList;
+-import java.util.Arrays;
+ import java.util.List;
+ import java.util.Map;
+-
+ import jdk.nashorn.tools.Shell;
+ import org.testng.Assert;
+ import org.testng.ITest;
+@@ -54,6 +52,7 @@
+ * class. Optionally, output from running the script is compared against the
+ * corresponding .EXPECTED file.
+ */
++@SuppressWarnings("javadoc")
+ public final class ScriptRunnable extends AbstractScriptRunnable implements ITest {
+ public ScriptRunnable(final String framework, final File testFile, final List<String> engineOptions, final Map<String, String> testOptions, final List<String> scriptArguments) {
+ super(framework, testFile, engineOptions, testOptions, scriptArguments);
+@@ -72,7 +71,11 @@
+ @Test
+ @Override
+ public void runTest() throws IOException {
+- super.runTest();
++ try {
++ super.runTest();
++ } catch(final AssertionError e) {
++ throw new AssertionError("Failed executing test " + testFile, e);
++ }
+ }
+
+ @Override
+@@ -86,7 +89,7 @@
+
+ // avoid direct System.out.println - use reporter to capture
+ @Override
+- protected void log(String msg) {
++ protected void log(final String msg) {
+ org.testng.Reporter.log(msg, true);
+ }
+
+@@ -174,8 +177,10 @@
+
+ cmd.add(System.getProperty("java.home") + separator + "bin" + separator + "java");
+ cmd.add("-Djava.ext.dirs=dist");
+- for (String str : forkJVMOptions) {
+- cmd.add(str);
++ for (final String str : forkJVMOptions) {
++ if(!str.isEmpty()) {
++ cmd.add(str);
++ }
+ }
+ cmd.add(Shell.class.getName());
+ // now add the rest of the "in process" runtime arguments
+--- ./nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptTest.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptTest.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,7 +26,6 @@
+ package jdk.nashorn.internal.test.framework;
+
+ import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_INCLUDES;
+-
+ import java.io.File;
+ import java.util.ArrayList;
+ import java.util.List;
+@@ -48,7 +47,9 @@
+ * Creates a test factory for the set of .js source tests.
+ *
+ * @return a Object[] of test objects.
++ * @throws Exception upon failure
+ */
++ @SuppressWarnings("static-method")
+ @Factory
+ public Object[] suite() throws Exception {
+ Locale.setDefault(new Locale(""));
+@@ -63,7 +64,7 @@
+ }
+
+ @Override
+- public void log(String msg) {
++ public void log(final String msg) {
+ org.testng.Reporter.log(msg, true);
+ }
+ };
+--- ./nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java Wed Feb 04 12:14:47 2015 -0800
+@@ -74,21 +74,21 @@
+ }
+
+ @Override
+- public void write(byte[] b) throws IOException {
++ public void write(final byte[] b) throws IOException {
+ underlying.write(b);
+ }
+
+ @Override
+- public void write(byte[] b, int off, int len) throws IOException {
++ public void write(final byte[] b, final int off, final int len) throws IOException {
+ underlying.write(b, off, len);
+ }
+
+ @Override
+- public void write(int b) throws IOException {
++ public void write(final int b) throws IOException {
+ underlying.write(b);
+ }
+
+- void setDelegatee(OutputStream stream) {
++ void setDelegatee(final OutputStream stream) {
+ this.underlying = stream;
+ }
+ }
+@@ -100,11 +100,11 @@
+ public SharedContextEvaluator(final String[] args) {
+ this.ctxOut = new DelegatingOutputStream(System.out);
+ this.ctxErr = new DelegatingOutputStream(System.err);
+- PrintWriter wout = new PrintWriter(ctxOut, true);
+- PrintWriter werr = new PrintWriter(ctxErr, true);
+- Options options = new Options("nashorn", werr);
++ final PrintWriter wout = new PrintWriter(ctxOut, true);
++ final PrintWriter werr = new PrintWriter(ctxErr, true);
++ final Options options = new Options("nashorn", werr);
+ options.process(args);
+- ErrorManager errors = new ErrorManager(werr);
++ final ErrorManager errors = new ErrorManager(werr);
+ this.context = new Context(options, errors, wout, werr, Thread.currentThread().getContextClassLoader());
+ }
+
+@@ -125,7 +125,7 @@
+ continue;
+ }
+ final File file = new File(fileName);
+- ScriptFunction script = context.compileScript(sourceFor(fileName, file.toURI().toURL()), global);
++ final ScriptFunction script = context.compileScript(sourceFor(fileName, file.toURI().toURL()), global);
+
+ if (script == null || errors.getNumberOfErrors() != 0) {
+ return COMPILATION_ERROR;
+--- ./nashorn/test/src/jdk/nashorn/internal/test/framework/TestConfig.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/test/framework/TestConfig.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,6 +28,7 @@
+ /**
+ * Configuration info for script tests.
+ */
++@SuppressWarnings("javadoc")
+ public interface TestConfig {
+ // Test options inferred from various test @foo tags and passed to test factory.
+ public static final String OPTIONS_RUN = "run";
+--- ./nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java Wed Feb 04 12:14:47 2015 -0800
+@@ -42,11 +42,11 @@
+ import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_LIST;
+ import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_ROOTS;
+ import static jdk.nashorn.internal.test.framework.TestConfig.TEST_JS_UNCHECKED_DIR;
+-
+ import java.io.BufferedReader;
+ import java.io.File;
+ import java.io.FileReader;
+ import java.io.IOException;
++import java.nio.ByteOrder;
+ import java.nio.file.FileSystem;
+ import java.nio.file.FileSystems;
+ import java.nio.file.FileVisitOption;
+@@ -56,6 +56,7 @@
+ import java.nio.file.SimpleFileVisitor;
+ import java.nio.file.attribute.BasicFileAttributes;
+ import java.util.ArrayList;
++import java.util.Arrays;
+ import java.util.Collections;
+ import java.util.EnumSet;
+ import java.util.HashMap;
+@@ -75,7 +76,8 @@
+ * Utility class to find/parse script test files and to create 'test' instances.
+ * Actual 'test' object type is decided by clients of this class.
+ */
+-final class TestFinder {
++@SuppressWarnings("javadoc")
++public final class TestFinder {
+ private TestFinder() {}
+
+ interface TestFactory<T> {
+@@ -92,7 +94,7 @@
+ final String testList = System.getProperty(TEST_JS_LIST);
+ final String failedTestFileName = System.getProperty(TEST_FAILED_LIST_FILE);
+ if(failedTestFileName != null) {
+- File failedTestFile = new File(failedTestFileName);
++ final File failedTestFile = new File(failedTestFileName);
+ if(failedTestFile.exists() && failedTestFile.length() > 0L) {
+ try(final BufferedReader r = new BufferedReader(new FileReader(failedTestFile))) {
+ for(;;) {
+@@ -195,7 +197,7 @@
+ return false;
+ }
+
+- private static <T> void handleOneTest(final String framework, final Path testFile, final List<T> tests, final Set<String> orphans, TestFactory<T> factory) throws Exception {
++ private static <T> void handleOneTest(final String framework, final Path testFile, final List<T> tests, final Set<String> orphans, final TestFactory<T> factory) throws Exception {
+ final String name = testFile.getFileName().toString();
+
+ assert name.lastIndexOf(".js") > 0 : "not a JavaScript: " + name;
+@@ -215,6 +217,8 @@
+ final List<String> scriptArguments = new ArrayList<>();
+ boolean inComment = false;
+
++ boolean explicitOptimistic = false;
++
+ try (Scanner scanner = new Scanner(testFile)) {
+ while (scanner.hasNext()) {
+ // TODO: Scan for /ref=file qualifiers, etc, to determine run
+@@ -261,14 +265,23 @@
+ isTest = false;
+ isNotTest = true;
+ break;
+- case "@runif":
+- if (System.getProperty(scanner.next()) != null) {
++ case "@bigendian":
++ shouldRun = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
++ break;
++ case "@littleendian":
++ shouldRun = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN;
++ break;
++ case "@runif": {
++ final String prop = scanner.next();
++ if (System.getProperty(prop) != null) {
+ shouldRun = true;
+ } else {
++ factory.log("WARNING: (" + prop + ") skipping " + testFile);
+ isTest = false;
+ isNotTest = true;
+ }
+ break;
++ }
+ case "@run":
+ shouldRun = true;
+ break;
+@@ -284,11 +297,17 @@
+ scriptArguments.add(scanner.next());
+ break;
+ case "@option":
+- engineOptions.add(scanner.next());
++ final String next = scanner.next();
++ engineOptions.add(next);
++ if (next.startsWith("--optimistic-types")) {
++ explicitOptimistic = true;
++ }
+ break;
+ case "@fork":
+ fork = true;
+ break;
++ default:
++ break;
+ }
+
+ // negative tests are expected to fail at runtime only
+@@ -333,12 +352,61 @@
+ testOptions.put(OPTIONS_FORK, "true");
+ }
+
++ //if there are explicit optimistic type settings, use those - do not override
++ //the test might only work with optimistic types on or off.
++ if (!explicitOptimistic) {
++ addExplicitOptimisticTypes(engineOptions);
++ }
++
+ tests.add(factory.createTest(framework, testFile.toFile(), engineOptions, testOptions, scriptArguments));
+ } else if (!isNotTest) {
+ orphans.add(name);
+ }
+ }
+
++ //the reverse of the default setting for optimistic types, if enabled, false, otherwise true
++ //thus, true for 8u40, false for 9
++ private static final boolean OPTIMISTIC_OVERRIDE = true;
++
++ /**
++ * Check if there is an optimistic override, that disables the default
++ * false optimistic types and sets them to true, for testing purposes
++ *
++ * @return true if optimistic type override has been set by test suite
++ */
++ public static boolean hasOptimisticOverride() {
++ return Boolean.valueOf(OPTIMISTIC_OVERRIDE).toString().equals(System.getProperty("optimistic.override"));
++ }
++
++ /**
++ * Add an optimistic-types=true option to an argument list if this
++ * is set to override the default false. Add an optimistic-types=true
++ * options to an argument list if this is set to override the default
++ * true
++ *
++ * @args new argument list array
++ */
++ public static String[] addExplicitOptimisticTypes(final String[] args) {
++ if (hasOptimisticOverride()) {
++ final List<String> newList = new ArrayList<>(Arrays.asList(args));
++ newList.add("--optimistic-types=" + Boolean.valueOf(OPTIMISTIC_OVERRIDE));
++ return newList.toArray(new String[0]);
++ }
++ return args;
++ }
++
++ /**
++ * Add an optimistic-types=true option to an argument list if this
++ * is set to override the default false
++ *
++ * @args argument list
++ */
++ public static void addExplicitOptimisticTypes(final List<String> args) {
++ if (hasOptimisticOverride()) {
++ args.add("--optimistic-types=" + Boolean.valueOf(OPTIMISTIC_OVERRIDE));
++ }
++ }
++
+ private static boolean strictModeEnabled() {
+ return Boolean.getBoolean(TEST_JS_ENABLE_STRICT_MODE);
+ }
+--- ./nashorn/test/src/jdk/nashorn/internal/test/framework/TestHelper.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/test/framework/TestHelper.java Wed Feb 04 12:14:47 2015 -0800
+@@ -36,10 +36,12 @@
+ /**
+ * Simple utilities to deal with build-dir, read/dump files etc.
+ */
++@SuppressWarnings("javadoc")
+ public abstract class TestHelper {
+
+ public static final String TEST_ROOT = "test";
+- public static final String BUILD_ROOT = "build/test";
++ public static final String BUILD_ROOT =
++ System.getProperty("build.dir", "build") + File.separator + "test";
+ public static final String TEST_PREFIX = TEST_ROOT + File.separator;
+
+ private TestHelper() {
+--- ./nashorn/test/src/jdk/nashorn/internal/test/framework/TestReorderInterceptor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/test/framework/TestReorderInterceptor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -38,7 +38,7 @@
+ */
+ public final class TestReorderInterceptor implements IMethodInterceptor {
+ @Override
+- public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
++ public List<IMethodInstance> intercept(final List<IMethodInstance> methods, final ITestContext context) {
+ Collections.sort(methods, new Comparator<IMethodInstance>() {
+ @Override
+ public int compare(final IMethodInstance mi1, final IMethodInstance mi2) {
+@@ -47,10 +47,9 @@
+ final Object o2 = mi2.getInstance();
+ if (o1 instanceof ITest && o2 instanceof ITest) {
+ return ((ITest)o1).getTestName().compareTo(((ITest)o2).getTestName());
+- } else {
+- // something else, don't care about the order
+- return 0;
+ }
++ // something else, don't care about the order
++ return 0;
+ }
+ });
+
+--- ./nashorn/test/src/jdk/nashorn/internal/test/models/InternalRunnable.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/test/models/InternalRunnable.java Wed Feb 04 12:14:47 2015 -0800
+@@ -28,6 +28,7 @@
+ import java.io.PrintWriter;
+ import java.io.StringWriter;
+
++@SuppressWarnings("javadoc")
+ public class InternalRunnable implements Runnable, RestrictedRunnable {
+
+ // This is a public field in a restricted class; scripts should not see it.
+--- ./nashorn/test/src/jdk/nashorn/internal/test/models/RestrictedRunnable.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/internal/test/models/RestrictedRunnable.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,8 +27,8 @@
+
+ /**
+ * Acts as a restricted interface implemented by a restricted class.
+- *
+ */
++@SuppressWarnings("javadoc")
+ public interface RestrictedRunnable {
+ public void restrictedRun();
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/src/jdk/nashorn/test/models/ClassLoaderAware.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.test.models;
++
++@SuppressWarnings("javadoc")
++public interface ClassLoaderAware {
++ public ClassLoader getContextClassLoader();
++ public void checkMemberAccess(Class<?> clazz, int which);
++}
+--- ./nashorn/test/src/jdk/nashorn/test/models/ClassWithFinalFinalizer.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/ClassWithFinalFinalizer.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,7 +25,10 @@
+
+ package jdk.nashorn.test.models;
+
++@SuppressWarnings("javadoc")
+ public class ClassWithFinalFinalizer {
++ @Override
+ protected final void finalize() {
++ //empty
+ }
+ }
+--- ./nashorn/test/src/jdk/nashorn/test/models/ClassWithInheritedFinalFinalizer.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/ClassWithInheritedFinalFinalizer.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,5 +25,7 @@
+
+ package jdk.nashorn.test.models;
+
++@SuppressWarnings("javadoc")
+ public class ClassWithInheritedFinalFinalizer extends ClassWithFinalFinalizer {
++ //empty
+ }
+--- ./nashorn/test/src/jdk/nashorn/test/models/ConstructorWithArgument.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/ConstructorWithArgument.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,10 +25,11 @@
+
+ package jdk.nashorn.test.models;
+
++@SuppressWarnings("javadoc")
+ public abstract class ConstructorWithArgument {
+ private final String token;
+
+- protected ConstructorWithArgument(String token) {
++ protected ConstructorWithArgument(final String token) {
+ this.token = token;
+ }
+
+--- ./nashorn/test/src/jdk/nashorn/test/models/DessertTopping.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/DessertTopping.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package jdk.nashorn.test.models;
+
++@SuppressWarnings("javadoc")
+ public interface DessertTopping {
+ public String pourOnDessert();
+ }
+--- ./nashorn/test/src/jdk/nashorn/test/models/DessertToppingFloorWaxDriver.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/DessertToppingFloorWaxDriver.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,12 +25,13 @@
+
+ package jdk.nashorn.test.models;
+
++@SuppressWarnings("javadoc")
+ public class DessertToppingFloorWaxDriver {
+- public void decorateDessert(DessertTopping dt) {
++ public void decorateDessert(final DessertTopping dt) {
+ dt.pourOnDessert();
+ }
+
+- public void waxFloor(FloorWax fw) {
++ public void waxFloor(final FloorWax fw) {
+ fw.shineUpTheFloor();
+ }
+ }
+--- ./nashorn/test/src/jdk/nashorn/test/models/FinalClass.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/FinalClass.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package jdk.nashorn.test.models;
+
++@SuppressWarnings("javadoc")
+ public final class FinalClass {
+ //empty
+ }
+--- ./nashorn/test/src/jdk/nashorn/test/models/FloorWax.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/FloorWax.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package jdk.nashorn.test.models;
+
++@SuppressWarnings("javadoc")
+ public interface FloorWax {
+ public String shineUpTheFloor();
+ }
+--- ./nashorn/test/src/jdk/nashorn/test/models/IntFloatOverloadSelection.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/IntFloatOverloadSelection.java Wed Feb 04 12:14:47 2015 -0800
+@@ -24,13 +24,14 @@
+ */
+ package jdk.nashorn.test.models;
+
++@SuppressWarnings("javadoc")
+ public class IntFloatOverloadSelection {
+
+- public static String overloadedMethod(int i) {
++ public static String overloadedMethod(final int i) {
+ return "int";
+ }
+
+- public static String overloadedMethod(float f) {
++ public static String overloadedMethod(final float f) {
+ return "float";
+ }
+ }
+--- ./nashorn/test/src/jdk/nashorn/test/models/InternalRunnableSuperclass.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/InternalRunnableSuperclass.java Wed Feb 04 12:14:47 2015 -0800
+@@ -30,8 +30,9 @@
+
+ /**
+ * Acts as a non-restricted superclass for a restricted class.
+- *
+ */
++
++@SuppressWarnings("javadoc")
+ public class InternalRunnableSuperclass {
+ public final int canSeeThisField = 19;
+
+--- ./nashorn/test/src/jdk/nashorn/test/models/Jdk8011362TestSubject.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/Jdk8011362TestSubject.java Wed Feb 04 12:14:47 2015 -0800
+@@ -26,22 +26,23 @@
+ package jdk.nashorn.test.models;
+
+ /**
+- * Test class used by JDK-8011362.js.
++ * Test class used by JDK-8011362.js
+ */
++@SuppressWarnings("javadoc")
+ public class Jdk8011362TestSubject {
+ // This is selected for overloaded("", null)
+- public String overloaded(String a, String b) {
++ public String overloaded(final String a, final String b) {
+ return "overloaded(String, String)";
+ }
+
+ // This is selected for overloaded(0, null)
+- public String overloaded(Double a, Double b) {
++ public String overloaded(final Double a, final Double b) {
+ return "overloaded(Double, Double)";
+ }
+
+ // This method is added to test that null will not match a primitive type, that is overloaded(0, null) will always
+ // select the (Double, Double) over (Double, double).
+- public String overloaded(Double a, double b) {
++ public String overloaded(final Double a, final double b) {
+ return "overloaded(Double, double)";
+ }
+ }
+--- ./nashorn/test/src/jdk/nashorn/test/models/Nashorn401TestSubject.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/Nashorn401TestSubject.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,32 +25,33 @@
+
+ package jdk.nashorn.test.models;
+
++@SuppressWarnings("javadoc")
+ public class Nashorn401TestSubject {
+- public String method2(int arg) {
++ public String method2(final int arg) {
+ return "int method 2";
+ }
+
+- public String method2(double arg) {
++ public String method2(final double arg) {
+ return "double method 2";
+ }
+
+- public String method2(String arg) {
++ public String method2(final String arg) {
+ return "string method 2";
+ }
+
+- public String method3(double arg) {
++ public String method3(final double arg) {
+ return "double method 3: " + arg;
+ }
+
+- public String method3(int arg) {
++ public String method3(final int arg) {
+ return "int method 3: " + arg;
+ }
+
+- public String method4(Double arg) {
++ public String method4(final Double arg) {
+ return "double method 4: " + arg;
+ }
+
+- public String method4(int arg) {
++ public String method4(final int arg) {
+ return "int method 4: " + arg;
+ }
+
+--- ./nashorn/test/src/jdk/nashorn/test/models/NoAccessibleConstructorClass.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/NoAccessibleConstructorClass.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package jdk.nashorn.test.models;
+
++@SuppressWarnings("javadoc")
+ public class NoAccessibleConstructorClass {
+ NoAccessibleConstructorClass() { }
+ }
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/src/jdk/nashorn/test/models/NullProvider.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.test.models;
++
++
++public class NullProvider {
++ public static Integer getInteger() { return null; }
++ public static Long getLong() { return null; }
++ public static Double getDouble() { return null; }
++ public static Boolean getBoolean() { return null; }
++}
+--- ./nashorn/test/src/jdk/nashorn/test/models/OuterClass.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/OuterClass.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,21 +25,23 @@
+
+ package jdk.nashorn.test.models;
+
++@SuppressWarnings("javadoc")
+ public class OuterClass {
+ private final String value;
+
+- public OuterClass(String value) {
++ public OuterClass(final String value) {
+ this.value = value;
+ }
+
+ public static class InnerStaticClass {
+
+ public static class InnerInnerStaticClass {
++ //empty
+ }
+
+ private final String value;
+
+- public InnerStaticClass(String value) {
++ public InnerStaticClass(final String value) {
+ this.value = value;
+ }
+
+@@ -50,15 +52,15 @@
+ }
+
+ public class InnerNonStaticClass {
+- private final String value;
++ private final String val;
+
+- public InnerNonStaticClass(String value) {
+- this.value = value;
++ public InnerNonStaticClass(final String value) {
++ this.val = value;
+ }
+
+ @Override
+ public String toString() {
+- return "InnerNonStaticClass[value=" + value + ", outer=" + OuterClass.this + "]";
++ return "InnerNonStaticClass[value=" + val + ", outer=" + OuterClass.this + "]";
+ }
+ }
+
+--- ./nashorn/test/src/jdk/nashorn/test/models/OverloadedSam.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/OverloadedSam.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package jdk.nashorn.test.models;
+
++@SuppressWarnings("javadoc")
+ public interface OverloadedSam {
+ public void sam(String s);
+ public void sam(String s1, String s2);
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/src/jdk/nashorn/test/models/OverloadedSetter.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,48 @@
++/*
++ * 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 jdk.nashorn.test.models;
++
++public class OverloadedSetter {
++ private String color;
++
++ public void setColor(final int x) {
++ this.color = Integer.toString(x);
++ }
++
++ public void setColor(final String x) {
++ this.color = x;
++ }
++
++ public String peekColor() {
++ return color;
++ }
++
++ public void foo(final int x) {
++ }
++
++ public String foo(final String x) {
++ return "boo";
++ }
++}
+--- ./nashorn/test/src/jdk/nashorn/test/models/OverrideObject.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/OverrideObject.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package jdk.nashorn.test.models;
+
++@SuppressWarnings("javadoc")
+ public class OverrideObject {
+ @Override
+ public int hashCode() {
+@@ -37,7 +38,7 @@
+ }
+
+ @Override
+- public boolean equals(Object o) {
++ public boolean equals(final Object o) {
+ // TODO: add a FindBugs annotation to ignore EQ_ALWAYS_FALSE here. This is just a test.
+ return false;
+ }
+--- ./nashorn/test/src/jdk/nashorn/test/models/PropertyBind.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/PropertyBind.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package jdk.nashorn.test.models;
+
++@SuppressWarnings("javadoc")
+ public class PropertyBind {
+ public static int publicStaticInt;
+ public static final int publicStaticFinalInt = 2112;
+@@ -37,14 +38,14 @@
+ public final int publicFinalInt = 42;
+
+ private int readWrite;
+- private int readOnly = 123;
++ private final int readOnly = 123;
+ private int writeOnly;
+
+ public int getReadWrite() {
+ return readWrite;
+ }
+
+- public void setReadWrite(int readWrite) {
++ public void setReadWrite(final int readWrite) {
+ this.readWrite = readWrite;
+ }
+
+@@ -52,7 +53,7 @@
+ return readOnly;
+ }
+
+- public void setWriteOnly(int writeOnly) {
++ public void setWriteOnly(final int writeOnly) {
+ this.writeOnly = writeOnly;
+ }
+
+@@ -64,7 +65,7 @@
+ return staticReadWrite;
+ }
+
+- public static void setStaticReadWrite(int staticReadWrite) {
++ public static void setStaticReadWrite(final int staticReadWrite) {
+ PropertyBind.staticReadWrite = staticReadWrite;
+ }
+
+@@ -72,7 +73,7 @@
+ return staticReadOnly;
+ }
+
+- public static void setStaticWriteOnly(int staticWriteOnly) {
++ public static void setStaticWriteOnly(final int staticWriteOnly) {
+ PropertyBind.staticWriteOnly = staticWriteOnly;
+ }
+
+--- ./nashorn/test/src/jdk/nashorn/test/models/SourceHelper.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/SourceHelper.java Wed Feb 04 12:14:47 2015 -0800
+@@ -34,6 +34,7 @@
+ /**
+ * Helper class to facilitate script access of nashorn Source class.
+ */
++@SuppressWarnings("javadoc")
+ public final class SourceHelper {
+ private SourceHelper() {}
+
+--- ./nashorn/test/src/jdk/nashorn/test/models/StringArgs.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/StringArgs.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,10 +27,11 @@
+
+ import java.util.List;
+
++@SuppressWarnings("javadoc")
+ public class StringArgs {
+
+- public static void checkString(List<?> list) {
+- for (Object s : list) {
++ public static void checkString(final List<?> list) {
++ for (final Object s : list) {
+ if (!(s instanceof String)) {
+ throw new AssertionError("Not a String: " + s);
+ }
+--- ./nashorn/test/src/jdk/nashorn/test/models/Toothpaste.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/Toothpaste.java Wed Feb 04 12:14:47 2015 -0800
+@@ -25,6 +25,7 @@
+
+ package jdk.nashorn.test.models;
+
++@SuppressWarnings("javadoc")
+ public abstract class Toothpaste {
+ public void applyToBrush() {
+ applyToBrushImpl();
+--- ./nashorn/test/src/jdk/nashorn/test/models/VarArgConstructor.java Mon Dec 08 12:30:54 2014 -0800
++++ ./nashorn/test/src/jdk/nashorn/test/models/VarArgConstructor.java Wed Feb 04 12:14:47 2015 -0800
+@@ -27,14 +27,15 @@
+
+ import java.util.List;
+
++@SuppressWarnings("javadoc")
+ public class VarArgConstructor {
+ private final String indicator;
+
+- public VarArgConstructor(int x, boolean y, List<String> z) {
++ public VarArgConstructor(final int x, final boolean y, final List<String> z) {
+ indicator = "non-vararg";
+ }
+
+- public VarArgConstructor(int x, boolean y, String... z) {
++ public VarArgConstructor(final int x, final boolean y, final String... z) {
+ indicator = "vararg";
+ }
+
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ ./nashorn/test/src/jdk/nashorn/test/tools/StaticTypeInspector.java Wed Feb 04 12:14:47 2015 -0800
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. 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 jdk.nashorn.test.tools;
++
++import jdk.nashorn.internal.runtime.Undefined;
++
++@SuppressWarnings("javadoc")
++public class StaticTypeInspector {
++
++ public static String inspect(final boolean x, final String w) {
++ return w + ": boolean";
++ }
++
++ public static String inspect(final int x, final String w) {
++ return w + ": int";
++ }
++
++ public static String inspect(final long x, final String w) {
++ return w + ": long";
++ }
++
++ public static String inspect(final double x, final String w) {
++ return w + ": double";
++ }
++
++ public static String inspect(final Undefined x, final String w) {
++ return w + ": undefined";
++ }
++
++ public static String inspect(final Object x, final String w) {
++ return w + ": object";
++ }
++}
diff --git a/java/openjdk8/files/patch-bsd b/java/openjdk8/files/patch-bsd
index 9dbd221dc3d5..e26bd615dea2 100644
--- a/java/openjdk8/files/patch-bsd
+++ b/java/openjdk8/files/patch-bsd
@@ -1,5 +1,12 @@
---- ./common/autoconf/build-performance.m4 Tue Dec 02 11:10:25 2014 -0800
-+++ ./common/autoconf/build-performance.m4 Sun Feb 01 21:04:41 2015 -0800
+--- ./.hgtags Wed Jan 28 12:08:30 2015 -0800
++++ ./.hgtags Sat Mar 14 10:28:41 2015 -0700
+@@ -374,3 +374,4 @@
+ 765a17e75fd622f7b892381e23c9b2c531d416f0 jdk8u40-b21
+ b6d03a810a61116268fea08517a9632bd66a7363 jdk8u40-b22
+ 5dd2ad6c7911a1e21f15a28f13ffad662378a3be jdk8u40-b23
++5b37e6757d7c95c9c58b07fb3c9eba234567385a jdk8u40-b24
+--- ./common/autoconf/build-performance.m4 Wed Jan 28 12:08:30 2015 -0800
++++ ./common/autoconf/build-performance.m4 Sat Mar 14 10:28:41 2015 -0700
@@ -41,6 +41,10 @@
# Looks like a MacOSX system
NUM_CORES=`/usr/sbin/system_profiler -detailLevel full SPHardwareDataType | grep 'Cores' | awk '{print [$]5}'`
@@ -23,9 +30,20 @@
elif test "x$OPENJDK_BUILD_OS" = xwindows; then
# Windows, but without cygwin
MEMORY_SIZE=`wmic computersystem get totalphysicalmemory -value | grep = | cut -d "=" -f 2-`
---- ./common/autoconf/generated-configure.sh Tue Dec 02 11:10:25 2014 -0800
-+++ ./common/autoconf/generated-configure.sh Sun Feb 01 21:04:41 2015 -0800
-@@ -1046,6 +1046,7 @@
+@@ -199,8 +208,8 @@
+ # Only use ccache if it is 3.1.4 or later, which supports
+ # precompiled headers.
+ AC_MSG_CHECKING([if ccache supports precompiled headers])
+- HAS_GOOD_CCACHE=`($CCACHE --version | head -n 1 | grep -E 3.1.@<:@456789@:>@) 2> /dev/null`
+- if test "x$HAS_GOOD_CCACHE" = x; then
++ HAS_GOOD_CCACHE=`($CCACHE --version | head -n 1 | awk '{ split($3, a, "."); if (a@<:@1@:>@ >= 3 && (a@<:@2@:>@ > 1 || (a@<:@2@:>@ == 1 && a@<:@3@:>@ >= 4))) print "yes"; else print "no"; }') 2> /dev/null`
++ if test "x$HAS_GOOD_CCACHE" = xyes; then
+ AC_MSG_RESULT([no, disabling ccache])
+ CCACHE=
+ else
+--- ./common/autoconf/generated-configure.sh Wed Jan 28 12:08:30 2015 -0800
++++ ./common/autoconf/generated-configure.sh Sat Mar 14 10:28:41 2015 -0700
+@@ -1048,6 +1048,7 @@
with_extra_cflags
with_extra_cxxflags
with_extra_ldflags
@@ -33,7 +51,7 @@
enable_debug_symbols
enable_zip_debug_info
enable_macosx_runtime_support
-@@ -1816,6 +1817,8 @@
+@@ -1818,6 +1819,8 @@
--with-extra-cflags extra flags to be used when compiling jdk c-files
--with-extra-cxxflags extra flags to be used when compiling jdk c++-files
--with-extra-ldflags extra flags to be used when linking jdk
@@ -42,7 +60,7 @@
--with-x use the X Window System
--with-cups specify prefix directory for the cups package
(expecting the headers under PATH/include)
-@@ -6802,7 +6805,7 @@
+@@ -6804,7 +6807,7 @@
# First argument is the cpu name from the trip/quad
case "$build_cpu" in
@@ -51,7 +69,7 @@
VAR_CPU=x86_64
VAR_CPU_ARCH=x86
VAR_CPU_BITS=64
-@@ -6933,7 +6936,7 @@
+@@ -6935,7 +6938,7 @@
# First argument is the cpu name from the trip/quad
case "$host_cpu" in
@@ -60,7 +78,7 @@
VAR_CPU=x86_64
VAR_CPU_ARCH=x86
VAR_CPU_BITS=64
-@@ -20150,7 +20153,7 @@
+@@ -20223,7 +20226,7 @@
else
COMPILER_VERSION_TEST=`$COMPILER --version 2>&1 | $HEAD -n 1`
# Check that this is likely to be GCC.
@@ -69,7 +87,7 @@
if test $? -ne 0; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required GCC compiler." >&5
$as_echo "$as_me: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required GCC compiler." >&6;}
-@@ -21751,7 +21754,7 @@
+@@ -21824,7 +21827,7 @@
else
COMPILER_VERSION_TEST=`$COMPILER --version 2>&1 | $HEAD -n 1`
# Check that this is likely to be GCC.
@@ -78,7 +96,7 @@
if test $? -ne 0; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required GCC compiler." >&5
$as_echo "$as_me: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required GCC compiler." >&6;}
-@@ -27715,7 +27718,7 @@
+@@ -27788,7 +27791,7 @@
# objcopy is used for moving debug symbols to separate files when
# full debug symbols are enabled.
@@ -87,7 +105,7 @@
if test -n "$ac_tool_prefix"; then
for ac_prog in gobjcopy objcopy
do
-@@ -29381,8 +29384,10 @@
+@@ -29454,8 +29457,10 @@
SET_SHARED_LIBRARY_NAME='-Xlinker -install_name -Xlinker @rpath/$1'
SET_SHARED_LIBRARY_MAPFILE=''
SET_SHARED_LIBRARY_ORIGIN='-Xlinker -rpath -Xlinker @loader_path/.'
@@ -99,7 +117,7 @@
fi
else
if test "x$OPENJDK_TARGET_OS" = xsolaris; then
-@@ -29808,22 +29813,37 @@
+@@ -29881,22 +29886,37 @@
CCXXFLAGS_JDK="$CCXXFLAGS_JDK $ADD_LP64"
# The package path is used only on macosx?
@@ -150,7 +168,7 @@
fi
if test "x$OPENJDK_TARGET_OS" = xlinux; then
CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DLINUX"
-@@ -30322,11 +30342,11 @@
+@@ -30395,11 +30415,11 @@
fi
if test "x$OPENJDK_TARGET_OS" = xbsd; then
@@ -167,7 +185,7 @@
fi
if test "x$OPENJDK" = "xfalse"; then
-@@ -34595,7 +34615,7 @@
+@@ -34668,7 +34688,7 @@
###############################################################################
#
@@ -176,7 +194,7 @@
#
# Check whether --with-alsa was given.
-@@ -34643,6 +34663,11 @@
+@@ -34716,6 +34736,11 @@
ALSA_LIBS="-L${with_alsa_lib} -lasound"
ALSA_FOUND=yes
fi
@@ -188,7 +206,7 @@
if test "x$ALSA_FOUND" = xno; then
-@@ -35633,6 +35658,11 @@
+@@ -35706,6 +35731,11 @@
LIBCXX="-lstdc++"
fi
@@ -200,7 +218,7 @@
-@@ -35706,6 +35736,10 @@
+@@ -35779,6 +35809,10 @@
# Looks like a MacOSX system
NUM_CORES=`/usr/sbin/system_profiler -detailLevel full SPHardwareDataType | grep 'Cores' | awk '{print $5}'`
FOUND_CORES=yes
@@ -211,7 +229,7 @@
elif test "x$OPENJDK_BUILD_OS" = xaix ; then
NUM_CORES=`/usr/sbin/prtconf | grep "^Number Of Processors" | awk '{ print $4 }'`
FOUND_CORES=yes
-@@ -35761,6 +35795,11 @@
+@@ -35834,6 +35868,11 @@
MEMORY_SIZE=`/usr/sbin/system_profiler -detailLevel full SPHardwareDataType | grep 'Memory' | awk '{print $2}'`
MEMORY_SIZE=`expr $MEMORY_SIZE \* 1024`
FOUND_MEM=yes
@@ -223,8 +241,8 @@
elif test "x$OPENJDK_BUILD_OS" = xwindows; then
# Windows, but without cygwin
MEMORY_SIZE=`wmic computersystem get totalphysicalmemory -value | grep = | cut -d "=" -f 2-`
---- ./common/autoconf/libraries.m4 Tue Dec 02 11:10:25 2014 -0800
-+++ ./common/autoconf/libraries.m4 Sun Feb 01 21:04:41 2015 -0800
+--- ./common/autoconf/libraries.m4 Wed Jan 28 12:08:30 2015 -0800
++++ ./common/autoconf/libraries.m4 Sat Mar 14 10:28:41 2015 -0700
@@ -71,9 +71,9 @@
fi
@@ -238,7 +256,28 @@
fi
if test "x$OPENJDK" = "xfalse"; then
-@@ -538,7 +538,7 @@
+@@ -112,14 +112,18 @@
+ # --x-libraries for the sysroot, if that seems to be correct.
+ if test "x$SYS_ROOT" != "x/"; then
+ if test "x$x_includes" = xNONE; then
+- if test -f "$SYS_ROOT/usr/X11R6/include/X11/Xlib.h"; then
++ if test -f "$SYS_ROOT/usr/X11R7/include/X11/Xlib.h"; then
++ x_includes="$SYS_ROOT/usr/X11R7/include"
++ elif test -f "$SYS_ROOT/usr/X11R6/include/X11/Xlib.h"; then
+ x_includes="$SYS_ROOT/usr/X11R6/include"
+ elif test -f "$SYS_ROOT/usr/include/X11/Xlib.h"; then
+ x_includes="$SYS_ROOT/usr/include"
+ fi
+ fi
+ if test "x$x_libraries" = xNONE; then
+- if test -f "$SYS_ROOT/usr/X11R6/lib/libX11.so"; then
++ if test -f "$SYS_ROOT/usr/X11R7/lib/libX11.so"; then
++ x_libraries="$SYS_ROOT/usr/X11R7/lib"
++ elif test -f "$SYS_ROOT/usr/X11R6/lib/libX11.so"; then
+ x_libraries="$SYS_ROOT/usr/X11R6/lib"
+ elif test "$SYS_ROOT/usr/lib64/libX11.so" && test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+ x_libraries="$SYS_ROOT/usr/lib64"
+@@ -538,7 +542,7 @@
###############################################################################
#
@@ -247,7 +286,7 @@
#
AC_ARG_WITH(alsa, [AS_HELP_STRING([--with-alsa],
[specify prefix directory for the alsa package
-@@ -885,5 +885,10 @@
+@@ -885,5 +889,10 @@
LIBCXX="-lstdc++"
fi
@@ -258,8 +297,8 @@
+
AC_SUBST(LIBCXX)
])
---- ./common/autoconf/platform.m4 Tue Dec 02 11:10:25 2014 -0800
-+++ ./common/autoconf/platform.m4 Sun Feb 01 21:04:41 2015 -0800
+--- ./common/autoconf/platform.m4 Wed Jan 28 12:08:30 2015 -0800
++++ ./common/autoconf/platform.m4 Sat Mar 14 10:28:41 2015 -0700
@@ -30,7 +30,7 @@
[
# First argument is the cpu name from the trip/quad
@@ -280,9 +319,9 @@
OPENJDK_TARGET_CPU_OSARCH="i386"
elif test "x$OPENJDK_TARGET_OS" != xmacosx && test "x$OPENJDK_TARGET_CPU" = xx86_64; then
# On all platforms except macosx, we replace x86_64 with amd64.
---- ./common/autoconf/spec.gmk.in Tue Dec 02 11:10:25 2014 -0800
-+++ ./common/autoconf/spec.gmk.in Sun Feb 01 21:04:41 2015 -0800
-@@ -276,7 +276,7 @@
+--- ./common/autoconf/spec.gmk.in Wed Jan 28 12:08:30 2015 -0800
++++ ./common/autoconf/spec.gmk.in Sat Mar 14 10:28:41 2015 -0700
+@@ -275,7 +275,7 @@
ALSA_LIBS:=@ALSA_LIBS@
ALSA_CFLAGS:=@ALSA_CFLAGS@
@@ -291,8 +330,8 @@
# Source file for cacerts
CACERTS_FILE=@CACERTS_FILE@
---- ./common/autoconf/toolchain.m4 Tue Dec 02 11:10:25 2014 -0800
-+++ ./common/autoconf/toolchain.m4 Sun Feb 01 21:04:41 2015 -0800
+--- ./common/autoconf/toolchain.m4 Wed Jan 28 12:08:30 2015 -0800
++++ ./common/autoconf/toolchain.m4 Sat Mar 14 10:28:41 2015 -0700
@@ -72,7 +72,7 @@
else
COMPILER_VERSION_TEST=`$COMPILER --version 2>&1 | $HEAD -n 1`
@@ -369,16 +408,16 @@
fi
if test "x$OPENJDK_TARGET_OS" = xlinux; then
CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DLINUX"
---- ./configure Tue Dec 02 11:10:25 2014 -0800
-+++ ./configure Sun Feb 01 21:04:41 2015 -0800
+--- ./configure Wed Jan 28 12:08:30 2015 -0800
++++ ./configure Sat Mar 14 10:28:41 2015 -0700
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
---- ./make/Main.gmk Tue Dec 02 11:10:25 2014 -0800
-+++ ./make/Main.gmk Sun Feb 01 21:04:41 2015 -0800
+--- ./make/Main.gmk Wed Jan 28 12:08:30 2015 -0800
++++ ./make/Main.gmk Sat Mar 14 10:28:41 2015 -0700
@@ -58,7 +58,11 @@
# Setup number of jobs to use. -jN is unfortunately not available for us to parse from the command line,
@@ -391,8 +430,8 @@
### Main targets
---- ./make/common/MakeBase.gmk Tue Dec 02 11:10:25 2014 -0800
-+++ ./make/common/MakeBase.gmk Sun Feb 01 21:04:41 2015 -0800
+--- ./make/common/MakeBase.gmk Wed Jan 28 12:08:30 2015 -0800
++++ ./make/common/MakeBase.gmk Sat Mar 14 10:28:41 2015 -0700
@@ -338,7 +338,7 @@
# (and causing a crash on Cygwin).
# Default shell seems to always be /bin/sh. Must override with bash to get this to work on Solaris.
@@ -413,8 +452,8 @@
endef
# Make directory without forking mkdir if not needed
---- ./make/common/NativeCompilation.gmk Tue Dec 02 11:10:25 2014 -0800
-+++ ./make/common/NativeCompilation.gmk Sun Feb 01 21:04:41 2015 -0800
+--- ./make/common/NativeCompilation.gmk Wed Jan 28 12:08:30 2015 -0800
++++ ./make/common/NativeCompilation.gmk Sat Mar 14 10:28:41 2015 -0700
@@ -151,9 +151,9 @@
# CC the compiler to use, default is $(CC)
# LDEXE the linker to use for linking executables, default is $(LDEXE)
@@ -428,18 +467,22 @@
ifneq (,$$($1_BIN))
$$(error BIN has been replaced with OBJECT_DIR)
---- ./hotspot/make/bsd/makefiles/adjust-mflags.sh Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/make/bsd/makefiles/adjust-mflags.sh Sun Feb 01 21:04:50 2015 -0800
-@@ -64,7 +64,6 @@
- echo "$MFLAGS" \
- | sed '
- s/^-/ -/
-- s/ -\([^ ][^ ]*\)j/ -\1 -j/
- s/ -j[0-9][0-9]*/ -j/
- s/ -j\([^ ]\)/ -j -\1/
- s/ -j/ -j'${HOTSPOT_BUILD_JOBS:-${default_build_jobs}}'/
---- ./hotspot/make/bsd/makefiles/build_vm_def.sh Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/make/bsd/makefiles/build_vm_def.sh Sun Feb 01 21:04:50 2015 -0800
+--- ./corba/.hgtags Wed Jan 28 12:08:31 2015 -0800
++++ ./corba/.hgtags Wed Feb 04 12:14:39 2015 -0800
+@@ -372,3 +372,4 @@
+ 9c54cc92c0beb29179abbce272d3f5c8ba4ffd0e jdk8u40-b21
+ 4c7421f74674ebefb8e91eba59ab2a2db8c1abd7 jdk8u40-b22
+ 62f7faef5ed956cd481cae6216b22fdb4b6e3e46 jdk8u40-b23
++472aa5bae0e78614e873d56bcc31e7caba49963c jdk8u40-b24
+--- ./hotspot/.hgtags Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/.hgtags Sat Mar 14 16:41:08 2015 -0700
+@@ -586,3 +586,4 @@
+ 0f0cb4eeab2d871274f4ffdcd6017d2fdfa89238 hs25.40-b25
+ 0ee548a1cda08c884eccd563e2d5fdb6ee769b5a jdk8u40-b22
+ 0e67683b700174eab71ea205d1cfa4f1cf4523ba jdk8u40-b23
++fa4e797f61e6dda1a60e06944018213bff2a1b76 jdk8u40-b24
+--- ./hotspot/make/bsd/makefiles/build_vm_def.sh Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/make/bsd/makefiles/build_vm_def.sh Sat Mar 14 16:41:08 2015 -0700
@@ -1,12 +1,28 @@
#!/bin/sh
@@ -475,8 +518,8 @@
+ if ($3 ~ /^_ZN9Arguments17SharedArchivePathE$/) print "\t" $3 ";"
+ }' | sort -u ;;
+esac
---- ./hotspot/make/bsd/makefiles/debug.make Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/make/bsd/makefiles/debug.make Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/make/bsd/makefiles/debug.make Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/make/bsd/makefiles/debug.make Sat Mar 14 16:41:08 2015 -0700
@@ -35,7 +35,10 @@
# to inhibit the effect of the previous line on CFLAGS.
@@ -489,8 +532,8 @@
VERSION = debug
SYSDEFS += -DASSERT
---- ./hotspot/make/bsd/makefiles/fastdebug.make Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/make/bsd/makefiles/fastdebug.make Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/make/bsd/makefiles/fastdebug.make Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/make/bsd/makefiles/fastdebug.make Sat Mar 14 16:41:08 2015 -0700
@@ -56,7 +56,10 @@
# to inhibit the effect of the previous line on CFLAGS.
@@ -503,8 +546,8 @@
VERSION = fastdebug
SYSDEFS += -DASSERT -DCHECK_UNHANDLED_OOPS
---- ./hotspot/make/bsd/makefiles/gcc.make Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/make/bsd/makefiles/gcc.make Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/make/bsd/makefiles/gcc.make Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/make/bsd/makefiles/gcc.make Sat Mar 14 16:41:08 2015 -0700
@@ -168,6 +168,9 @@
CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
endif
@@ -547,7 +590,7 @@
WARNING_FLAGS += -Wconversion
endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./hotspot/make/bsd/makefiles/launcher.make Sun Feb 01 21:04:50 2015 -0800
++++ ./hotspot/make/bsd/makefiles/launcher.make Sat Mar 14 16:41:08 2015 -0700
@@ -0,0 +1,117 @@
+#
+# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
@@ -666,9 +709,9 @@
+ $(QUIETLY) sed -e 's/@@LIBARCH@@/$(LIBARCH)/g' $< > $@
+ $(QUIETLY) chmod +x $@
+
---- ./hotspot/make/bsd/makefiles/mapfile-vers-debug Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/make/bsd/makefiles/mapfile-vers-debug Sun Feb 01 21:04:50 2015 -0800
-@@ -21,243 +21,251 @@
+--- ./hotspot/make/bsd/makefiles/mapfile-vers-debug Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/make/bsd/makefiles/mapfile-vers-debug Sat Mar 14 16:41:08 2015 -0700
+@@ -21,246 +21,254 @@
# questions.
#
#
@@ -844,6 +887,9 @@
- _JVM_IsSupportedJNIVersion
- _JVM_IsThreadAlive
- _JVM_IsVMGeneratedMethodIx
+- _JVM_KnownToNotExist
+- _JVM_GetResourceLookupCacheURLs
+- _JVM_GetResourceLookupCache
- _JVM_LatestUserDefinedLoader
- _JVM_Listen
- _JVM_LoadClass0
@@ -1058,6 +1104,9 @@
+ JVM_IsSupportedJNIVersion;
+ JVM_IsThreadAlive;
+ JVM_IsVMGeneratedMethodIx;
++ JVM_KnownToNotExist;
++ JVM_GetResourceLookupCacheURLs;
++ JVM_GetResourceLookupCache;
+ JVM_LatestUserDefinedLoader;
+ JVM_Listen;
+ JVM_LoadClass0;
@@ -1149,10 +1198,10 @@
+ *;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./hotspot/make/bsd/makefiles/mapfile-vers-debug.macosx Sun Feb 01 21:04:50 2015 -0800
-@@ -0,0 +1,263 @@
++++ ./hotspot/make/bsd/makefiles/mapfile-vers-debug.macosx Sat Mar 14 16:41:08 2015 -0700
+@@ -0,0 +1,266 @@
+#
-+# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
@@ -1340,6 +1389,9 @@
+ _JVM_IsSupportedJNIVersion
+ _JVM_IsThreadAlive
+ _JVM_IsVMGeneratedMethodIx
++ _JVM_KnownToNotExist
++ _JVM_GetResourceLookupCacheURLs
++ _JVM_GetResourceLookupCache
+ _JVM_LatestUserDefinedLoader
+ _JVM_Listen
+ _JVM_LoadClass0
@@ -1414,9 +1466,9 @@
+
+ # INSERT VTABLE SYMBOLS HERE
+
---- ./hotspot/make/bsd/makefiles/mapfile-vers-product Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/make/bsd/makefiles/mapfile-vers-product Sun Feb 01 21:04:50 2015 -0800
-@@ -21,238 +21,246 @@
+--- ./hotspot/make/bsd/makefiles/mapfile-vers-product Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/make/bsd/makefiles/mapfile-vers-product Sat Mar 14 16:41:08 2015 -0700
+@@ -21,241 +21,249 @@
# questions.
#
#
@@ -1592,6 +1644,9 @@
- _JVM_IsSupportedJNIVersion
- _JVM_IsThreadAlive
- _JVM_IsVMGeneratedMethodIx
+- _JVM_KnownToNotExist
+- _JVM_GetResourceLookupCacheURLs
+- _JVM_GetResourceLookupCache
- _JVM_LatestUserDefinedLoader
- _JVM_Listen
- _JVM_LoadClass0
@@ -1806,6 +1861,9 @@
+ JVM_IsSupportedJNIVersion;
+ JVM_IsThreadAlive;
+ JVM_IsVMGeneratedMethodIx;
++ JVM_KnownToNotExist;
++ JVM_GetResourceLookupCacheURLs;
++ JVM_GetResourceLookupCache;
+ JVM_LatestUserDefinedLoader;
+ JVM_Listen;
+ JVM_LoadClass0;
@@ -1888,10 +1946,10 @@
+ *;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./hotspot/make/bsd/makefiles/mapfile-vers-product.macosx Sun Feb 01 21:04:50 2015 -0800
-@@ -0,0 +1,258 @@
++++ ./hotspot/make/bsd/makefiles/mapfile-vers-product.macosx Sat Mar 14 16:41:08 2015 -0700
+@@ -0,0 +1,261 @@
+#
-+# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
@@ -2079,6 +2137,9 @@
+ _JVM_IsSupportedJNIVersion
+ _JVM_IsThreadAlive
+ _JVM_IsVMGeneratedMethodIx
++ _JVM_KnownToNotExist
++ _JVM_GetResourceLookupCacheURLs
++ _JVM_GetResourceLookupCache
+ _JVM_LatestUserDefinedLoader
+ _JVM_Listen
+ _JVM_LoadClass0
@@ -2148,8 +2209,8 @@
+
+ # INSERT VTABLE SYMBOLS HERE
+
---- ./hotspot/make/bsd/makefiles/optimized.make Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/make/bsd/makefiles/optimized.make Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/make/bsd/makefiles/optimized.make Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/make/bsd/makefiles/optimized.make Sat Mar 14 16:41:08 2015 -0700
@@ -38,6 +38,9 @@
# to inhibit the effect of the previous line on CFLAGS.
@@ -2161,8 +2222,8 @@
+MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug$(MAPSUFX)
VERSION = optimized
---- ./hotspot/make/bsd/makefiles/product.make Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/make/bsd/makefiles/product.make Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/make/bsd/makefiles/product.make Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/make/bsd/makefiles/product.make Sat Mar 14 16:41:08 2015 -0700
@@ -38,7 +38,10 @@
# to inhibit the effect of the previous line on CFLAGS.
@@ -2175,8 +2236,8 @@
SYSDEFS += -DPRODUCT
VERSION = optimized
---- ./hotspot/make/bsd/makefiles/rules.make Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/make/bsd/makefiles/rules.make Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/make/bsd/makefiles/rules.make Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/make/bsd/makefiles/rules.make Sat Mar 14 16:41:08 2015 -0700
@@ -34,7 +34,7 @@
CC_COMPILE = $(CC) $(CXXFLAGS) $(CFLAGS)
CXX_COMPILE = $(CXX) $(CXXFLAGS) $(CFLAGS)
@@ -2186,8 +2247,8 @@
COMPILE.CC = $(CC_COMPILE) -c
GENASM.CC = $(CC_COMPILE) -S
---- ./hotspot/src/cpu/x86/vm/jni_x86.h Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/src/cpu/x86/vm/jni_x86.h Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/src/cpu/x86/vm/jni_x86.h Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/src/cpu/x86/vm/jni_x86.h Sat Mar 14 16:41:08 2015 -0700
@@ -34,7 +34,7 @@
#ifndef __has_attribute
#define __has_attribute(x) 0
@@ -2197,8 +2258,8 @@
#define JNIEXPORT __attribute__((visibility("default")))
#define JNIIMPORT __attribute__((visibility("default")))
#else
---- ./hotspot/src/cpu/x86/vm/x86_32.ad Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/src/cpu/x86/vm/x86_32.ad Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/src/cpu/x86/vm/x86_32.ad Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/src/cpu/x86/vm/x86_32.ad Sat Mar 14 16:41:08 2015 -0700
@@ -1210,6 +1210,7 @@
@@ -2208,7 +2269,7 @@
#ifndef PRODUCT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./hotspot/src/os/bsd/vm/decoder_bsd.cpp Sun Feb 01 21:04:50 2015 -0800
++++ ./hotspot/src/os/bsd/vm/decoder_bsd.cpp Sat Mar 14 16:41:08 2015 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
@@ -2257,8 +2318,8 @@
+ return false;
+}
+#endif
---- ./hotspot/src/os/bsd/vm/jsig.c Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/src/os/bsd/vm/jsig.c Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/src/os/bsd/vm/jsig.c Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/src/os/bsd/vm/jsig.c Sat Mar 14 16:41:08 2015 -0700
@@ -140,9 +140,8 @@
}
@@ -2271,8 +2332,8 @@
static int call_os_sigaction(int sig, const struct sigaction *act,
struct sigaction *oact) {
---- ./hotspot/src/os/bsd/vm/jvm_bsd.cpp Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/src/os/bsd/vm/jvm_bsd.cpp Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/src/os/bsd/vm/jvm_bsd.cpp Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/src/os/bsd/vm/jvm_bsd.cpp Sat Mar 14 16:41:08 2015 -0700
@@ -50,6 +50,7 @@
case INTERRUPT_SIGNAL:
case SIGFPE:
@@ -2382,8 +2443,8 @@
+ jio_snprintf(buf, len, "SIG%s", signame);
+ return true;
}
---- ./hotspot/src/os/bsd/vm/jvm_bsd.h Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/src/os/bsd/vm/jvm_bsd.h Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/src/os/bsd/vm/jvm_bsd.h Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/src/os/bsd/vm/jvm_bsd.h Sat Mar 14 16:41:08 2015 -0700
@@ -112,20 +112,6 @@
#define SHUTDOWN2_SIGNAL SIGINT
#define SHUTDOWN3_SIGNAL SIGTERM
@@ -2405,20 +2466,20 @@
#endif /* JVM_MD_H */
#endif // OS_BSD_VM_JVM_BSD_H
---- ./hotspot/src/os/bsd/vm/osThread_bsd.cpp Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/src/os/bsd/vm/osThread_bsd.cpp Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/src/os/bsd/vm/osThread_bsd.cpp Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/src/os/bsd/vm/osThread_bsd.cpp Sat Mar 14 16:41:08 2015 -0700
@@ -30,7 +30,7 @@
void OSThread::pd_initialize() {
assert(this != NULL, "check");
-#ifdef __APPLE__
-+#if defined(__APPLE__) || defined(__FreeBSD__)
++#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
_thread_id = 0;
#else
_thread_id = NULL;
---- ./hotspot/src/os/bsd/vm/os_bsd.cpp Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/src/os/bsd/vm/os_bsd.cpp Sun Feb 01 21:04:50 2015 -0800
-@@ -102,6 +102,16 @@
+--- ./hotspot/src/os/bsd/vm/os_bsd.cpp Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/src/os/bsd/vm/os_bsd.cpp Sat Mar 14 16:41:08 2015 -0700
+@@ -103,10 +103,24 @@
# include <sys/ioctl.h>
# include <sys/syscall.h>
@@ -2435,7 +2496,15 @@
#if defined(__FreeBSD__) || defined(__NetBSD__)
# include <elf.h>
#endif
-@@ -168,6 +178,27 @@
+
++#ifdef __NetBSD__
++#include <lwp.h>
++#endif
++
+ #ifdef __APPLE__
+ # include <mach/mach.h> // semaphore_* API
+ # include <mach-o/dyld.h>
+@@ -169,6 +183,27 @@
// available here means free
julong os::Bsd::available_memory() {
@@ -2463,7 +2532,7 @@
uint64_t available = physical_memory() >> 2;
#ifdef __APPLE__
mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
-@@ -207,7 +238,7 @@
+@@ -208,7 +243,7 @@
static bool init = false;
static bool privileges = false;
if (!init) {
@@ -2472,7 +2541,7 @@
init = true;
}
return privileges;
-@@ -410,12 +441,21 @@
+@@ -411,12 +446,21 @@
const char *v = ::getenv("LD_LIBRARY_PATH");
const char *v_colon = ":";
if (v == NULL) { v = ""; v_colon = ""; }
@@ -2494,11 +2563,14 @@
Arguments::set_library_path(ld_library_path);
FREE_C_HEAP_ARRAY(char, ld_library_path, mtInternal);
}
-@@ -1197,7 +1237,13 @@
+@@ -1197,22 +1241,31 @@
+ guarantee(retval != 0, "just checking");
return retval;
- #elif __FreeBSD__
+-#elif __FreeBSD__
- retval = syscall(SYS_thr_self);
+-#elif __OpenBSD__
++#elifdef __FreeBSD__
+#if __FreeBSD_version > 900030
+ return ::pthread_getthreadid_np();
+#else
@@ -2506,10 +2578,14 @@
+ thr_self(&tid);
+ return (pid_t)tid;
+#endif
- #elif __OpenBSD__
++#elifdef __OpenBSD__
retval = syscall(SYS_getthrid);
- #elif __NetBSD__
-@@ -1207,11 +1253,14 @@
+-#elif __NetBSD__
+- retval = (pid_t) syscall(SYS__lwp_self);
++#elifdef __NetBSD__
++ retval = (pid_t) _lwp_self();
+ #endif
+
if (retval == -1) {
return getpid();
}
@@ -2525,7 +2601,7 @@
#else
return (intx)::pthread_self();
#endif
-@@ -1689,14 +1738,14 @@
+@@ -1690,14 +1743,14 @@
}
void os::print_os_info_brief(outputStream* st) {
@@ -2542,7 +2618,7 @@
os::Posix::print_uname_info(st);
-@@ -1709,6 +1758,29 @@
+@@ -1710,6 +1763,29 @@
// Nothing to do for now.
}
@@ -2572,7 +2648,7 @@
void os::print_memory_info(outputStream* st) {
st->print("Memory:");
-@@ -1718,11 +1790,14 @@
+@@ -1719,11 +1795,14 @@
os::physical_memory() >> 10);
st->print("(" UINT64_FORMAT "k free)",
os::available_memory() >> 10);
@@ -2592,7 +2668,7 @@
st->cr();
}
-@@ -1958,7 +2033,7 @@
+@@ -1959,7 +2038,7 @@
os_semaphore_t _semaphore;
};
@@ -2601,7 +2677,7 @@
SEM_INIT(_semaphore, 0);
}
-@@ -2146,7 +2221,7 @@
+@@ -2147,7 +2226,7 @@
if (::write(fd, "", 1) == 1) {
mmap(base, size,
PROT_READ|PROT_WRITE|PROT_EXEC,
@@ -2610,7 +2686,7 @@
}
}
::close(fd);
-@@ -2256,7 +2331,7 @@
+@@ -2257,7 +2336,7 @@
return ::mprotect(addr, size, PROT_NONE) == 0;
#else
uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,
@@ -2619,7 +2695,7 @@
return res != (uintptr_t) MAP_FAILED;
#endif
}
-@@ -2283,7 +2358,7 @@
+@@ -2284,7 +2363,7 @@
char * addr;
int flags;
@@ -2628,7 +2704,7 @@
if (fixed) {
assert((uintptr_t)requested_addr % os::Bsd::page_size() == 0, "unaligned address");
flags |= MAP_FIXED;
-@@ -2770,6 +2845,7 @@
+@@ -2773,6 +2852,7 @@
return OS_OK;
#elif defined(__FreeBSD__)
int ret = pthread_setprio(thread->osthread()->pthread_id(), newpri);
@@ -2636,7 +2712,7 @@
#elif defined(__APPLE__) || defined(__NetBSD__)
struct sched_param sp;
int policy;
-@@ -3364,18 +3440,6 @@
+@@ -3367,18 +3447,6 @@
}
}
@@ -2655,7 +2731,7 @@
static const char* get_signal_handler_name(address handler,
char* buf, int buflen) {
int offset;
-@@ -3399,9 +3463,6 @@
+@@ -3402,9 +3470,6 @@
sigaction(sig, NULL, &sa);
@@ -2665,7 +2741,7 @@
st->print("%s: ", os::exception_name(sig, buf, buflen));
address handler = (sa.sa_flags & SA_SIGINFO)
-@@ -3423,7 +3484,7 @@
+@@ -3426,7 +3491,7 @@
// May be, handler was resetted by VMError?
if(rh != NULL) {
handler = rh;
@@ -2674,7 +2750,7 @@
}
st->print(", sa_flags=");
-@@ -3499,8 +3560,6 @@
+@@ -3502,8 +3567,6 @@
os_sigaction(sig, (struct sigaction*)NULL, &act);
@@ -2683,7 +2759,7 @@
address thisHandler = (act.sa_flags & SA_SIGINFO)
? CAST_FROM_FN_PTR(address, act.sa_sigaction)
: CAST_FROM_FN_PTR(address, act.sa_handler) ;
-@@ -3560,6 +3619,14 @@
+@@ -3563,6 +3626,14 @@
extern bool signal_name(int signo, char* buf, size_t len);
@@ -2698,7 +2774,7 @@
const char* os::exception_name(int exception_code, char* buf, size_t size) {
if (0 < exception_code && exception_code <= SIGRTMAX) {
// signal
-@@ -3759,6 +3826,19 @@
+@@ -3762,6 +3833,19 @@
};
int os::active_processor_count() {
@@ -2718,7 +2794,7 @@
return _processor_count;
}
-@@ -3970,7 +4050,10 @@
+@@ -3973,7 +4057,10 @@
}
int fd;
int o_delete = (oflag & O_DELETE);
@@ -2730,7 +2806,7 @@
fd = ::open(path, oflag, mode);
if (fd == -1) return -1;
-@@ -4015,7 +4098,7 @@
+@@ -4018,7 +4105,7 @@
* 4843136: (process) pipe file descriptor from Runtime.exec not being closed
* 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
*/
@@ -2739,8 +2815,8 @@
{
int flags = ::fcntl(fd, F_GETFD);
if (flags != -1)
---- ./hotspot/src/os/bsd/vm/vmError_bsd.cpp Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/src/os/bsd/vm/vmError_bsd.cpp Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/src/os/bsd/vm/vmError_bsd.cpp Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/src/os/bsd/vm/vmError_bsd.cpp Sat Mar 14 16:41:08 2015 -0700
@@ -44,7 +44,7 @@
jio_snprintf(p, buflen - len,
"\n\n"
@@ -2759,8 +2835,8 @@
os::current_process_id(), os::current_process_id());
os::fork_and_exec(buf);
---- ./hotspot/src/share/vm/opto/node.cpp Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/src/share/vm/opto/node.cpp Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/src/share/vm/opto/node.cpp Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/src/share/vm/opto/node.cpp Sat Mar 14 16:41:08 2015 -0700
@@ -286,6 +286,10 @@
#ifdef _MSC_VER // the IDX_INIT hack falls foul of warning C4355
#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
@@ -2783,9 +2859,9 @@
//------------------------------clone------------------------------------------
// Clone a Node.
---- ./hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp Sun Feb 01 21:04:50 2015 -0800
-@@ -261,7 +261,7 @@
+--- ./hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp Sat Mar 14 16:41:08 2015 -0700
+@@ -250,7 +250,7 @@
#endif
// GCC 4.3 does not allow 0.0/0.0 to produce a NAN value
@@ -2794,8 +2870,29 @@
#define CAN_USE_NAN_DEFINE 1
#endif
---- ./jdk/make/CompileDemos.gmk Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/CompileDemos.gmk Sun Feb 01 21:05:04 2015 -0800
+--- ./jaxp/.hgtags Wed Jan 28 12:08:37 2015 -0800
++++ ./jaxp/.hgtags Wed Feb 04 12:14:41 2015 -0800
+@@ -374,3 +374,4 @@
+ 78d90db9de2801eec010ccb9f0db3caf969dfc3b jdk8u40-b21
+ 54a13451ce243f2159ed3996e6efcf374a5750ca jdk8u40-b22
+ e07fbae1efeac4e50514384caa7d226af7414114 jdk8u40-b23
++048cebd17f73f23ce2295e360f31c1b6788195aa jdk8u40-b24
+--- ./jaxws/.hgtags Wed Jan 28 12:08:39 2015 -0800
++++ ./jaxws/.hgtags Wed Feb 04 12:14:42 2015 -0800
+@@ -372,3 +372,4 @@
+ 16485a38b6bc762b363f4e439047486742fbcfcb jdk8u40-b21
+ 6e928fd9152541eddf25694be89eb881434a5c5f jdk8u40-b22
+ b6755a463ccf6a79b1e1a43ed7bdb1c5cb1ac17d jdk8u40-b23
++5fbbfd66643edb81cfa0688825d698dcc5f2eb11 jdk8u40-b24
+--- ./jdk/.hgtags Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/.hgtags Sat Mar 14 22:56:25 2015 -0700
+@@ -375,3 +375,4 @@
+ 564bca490631e4ed4f7993e6633ed9ee62067624 jdk8u40-b21
+ d168113f9841a77b3cee3a6a45fcd85b7351ac90 jdk8u40-b22
+ 41fe61722ce96b75dd3a1ba5072473122e21e5a0 jdk8u40-b23
++9d903721276c8684706db7ecfb6cda568e9f4f69 jdk8u40-b24
+--- ./jdk/make/CompileDemos.gmk Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/CompileDemos.gmk Sat Mar 14 22:56:25 2015 -0700
@@ -323,7 +323,7 @@
$(eval $(call SetupJVMTIDemo,hprof, java_crw_demo, \
-I$(JDK_TOPDIR)/src/share/npt -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/npt \
@@ -2805,9 +2902,9 @@
$(eval $(call SetupJVMTIDemo,minst, agent_util java_crw_demo))
$(eval $(call SetupJVMTIDemo,mtrace, agent_util java_crw_demo))
---- ./jdk/make/CompileJavaClasses.gmk Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/CompileJavaClasses.gmk Sun Feb 01 21:05:04 2015 -0800
-@@ -125,23 +125,32 @@
+--- ./jdk/make/CompileJavaClasses.gmk Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/CompileJavaClasses.gmk Sat Mar 14 22:56:25 2015 -0700
+@@ -130,23 +130,32 @@
sun/nio/fs/LinuxFileStore.java \
sun/nio/fs/LinuxFileSystem.java \
sun/nio/fs/LinuxFileSystemProvider.java \
@@ -2844,7 +2941,7 @@
sun/tools/attach/BsdAttachProvider.java \
sun/tools/attach/BsdVirtualMachine.java
endif
-@@ -228,9 +237,9 @@
+@@ -233,9 +242,9 @@
# Exclude another implicitly not included file.
EXFILES += sun/util/locale/AsciiUtil.java
@@ -2856,7 +2953,7 @@
#
EXFILES += sun/nio/fs/PollingWatchService.java
endif
-@@ -270,21 +279,26 @@
+@@ -275,21 +284,26 @@
$(JDK_TOPDIR)/src/closed/$(OPENJDK_TARGET_OS_API_DIR)/classes
endif
@@ -2890,7 +2987,7 @@
endif
# The security classes should not end up in the classes directory as that will prevent them
-@@ -334,6 +348,7 @@
+@@ -339,6 +353,7 @@
SRC:=$(JDK_TOPDIR)/src/share/classes \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/classes \
$(MACOSX_SRC_DIRS) \
@@ -2898,7 +2995,7 @@
$(AIX_SRC_DIRS) \
$(JDK_OUTPUTDIR)/gensrc \
$(JDK_OUTPUTDIR)/gensrc_no_srczip \
-@@ -353,7 +368,7 @@
+@@ -358,7 +373,7 @@
SETUP := GENERATE_JDKBYTECODE, \
SRC := $(JDK_TOPDIR)/src/share/classes \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/classes \
@@ -2907,8 +3004,8 @@
$(CLOSED_SRC_DIRS), \
INCLUDES := $(SECURITY_PKGS), \
EXCLUDES := $(EXCLUDES), \
---- ./jdk/make/CompileLaunchers.gmk Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/CompileLaunchers.gmk Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/CompileLaunchers.gmk Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/CompileLaunchers.gmk Sat Mar 14 22:56:25 2015 -0700
@@ -49,7 +49,7 @@
ORIGIN_ROOT := /..
endif
@@ -3007,8 +3104,8 @@
BUILD_JSPAWNHELPER := 1
endif
---- ./jdk/make/CopyFiles.gmk Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/CopyFiles.gmk Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/CopyFiles.gmk Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/CopyFiles.gmk Sat Mar 14 22:56:25 2015 -0700
@@ -29,6 +29,8 @@
ifeq ($(OPENJDK_TARGET_OS), windows)
@@ -3051,8 +3148,8 @@
endif
endif
endif
---- ./jdk/make/Images.gmk Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/Images.gmk Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/Images.gmk Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/Images.gmk Sat Mar 14 22:56:25 2015 -0700
@@ -234,11 +234,11 @@
endif
@@ -3123,7 +3220,7 @@
################################################################################
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/make/data/classlist/classlist.bsd Sun Feb 01 21:05:04 2015 -0800
++++ ./jdk/make/data/classlist/classlist.bsd Sat Mar 14 22:56:25 2015 -0700
@@ -0,0 +1,2803 @@
+com/sun/java/swing/SwingUtilities3
+com/sun/java/swing/plaf/windows/WindowsTabbedPaneUI
@@ -5928,8 +6025,8 @@
+sun/util/resources/en/TimeZoneNames_en
+sun/util/spi/CalendarProvider
+# ca392e7ee7285d72
---- ./jdk/make/gendata/GendataFontConfig.gmk Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/gendata/GendataFontConfig.gmk Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/gendata/GendataFontConfig.gmk Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/gendata/GendataFontConfig.gmk Sat Mar 14 22:56:25 2015 -0700
@@ -73,6 +73,13 @@
GENDATA_FONT_CONFIG_SRC_PREFIX := aix.
endif
@@ -5944,20 +6041,8 @@
###
$(GENDATA_FONT_CONFIG_DST)/%.src: \
---- ./jdk/make/gensrc/GensrcMisc.gmk Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/gensrc/GensrcMisc.gmk Sun Feb 01 21:05:04 2015 -0800
-@@ -64,9 +64,6 @@
-
- ifeq ($(OPENJDK_TARGET_OS_API), posix)
- UPSUFFIX := $(OPENJDK_TARGET_OS)
-- ifeq ($(OPENJDK_TARGET_OS), macosx)
-- UPSUFFIX := bsd
-- endif
- # UNIXProcess.java is different for solaris and linux. We need to copy
- # the correct UNIXProcess.java over to $(JDK_OUTPUTDIR)/gensrc/java/lang/.
-
---- ./jdk/make/lib/Awt2dLibraries.gmk Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/lib/Awt2dLibraries.gmk Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/lib/Awt2dLibraries.gmk Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/lib/Awt2dLibraries.gmk Sat Mar 14 22:56:25 2015 -0700
@@ -309,7 +309,7 @@
debug_trace.c \
debug_util.c
@@ -5992,7 +6077,7 @@
ifeq ($(MILESTONE), internal)
LIBAWT_XAWT_CFLAGS += -DINTERNAL_BUILD
endif
-@@ -628,6 +639,11 @@
+@@ -627,6 +638,11 @@
LIBAWT_XAWT_LDFLAGS += -lpthread
endif
@@ -6004,7 +6089,7 @@
$(eval $(call SetupNativeCompilation,BUILD_LIBAWT_XAWT, \
LIBRARY := awt_xawt, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
-@@ -691,6 +707,7 @@
+@@ -690,6 +706,7 @@
LDFLAGS_SUFFIX_macosx := $(LIBM) -lawt -ljava -ljvm, \
LDFLAGS_SUFFIX_linux := -lm -lawt -ljava -ljvm, \
LDFLAGS_SUFFIX_aix := -lm -lawt -ljava -ljvm,\
@@ -6012,7 +6097,7 @@
VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \
RC_FLAGS := $(RC_FLAGS) \
-D "JDK_FNAME=lcms.dll" \
-@@ -830,6 +847,7 @@
+@@ -829,6 +846,7 @@
LDFLAGS_SUFFIX_linux := -lawt $(LIBM) $(LIBCXX) -ljava -ljvm -lc, \
LDFLAGS_SUFFIX_solaris := -lawt -lawt_xawt -lc $(LIBM) $(LIBCXX) -ljava -ljvm, \
LDFLAGS_SUFFIX_aix := -lawt -lawt_xawt $(LIBM) $(LIBCXX) -ljava -ljvm,\
@@ -6020,7 +6105,7 @@
LDFLAGS_SUFFIX_macosx := -lawt $(LIBM) $(LIBCXX) -undefined dynamic_lookup \
-ljava -ljvm, \
LDFLAGS_SUFFIX_windows := $(WIN_JAVA_LIB) advapi32.lib user32.lib gdi32.lib \
-@@ -973,6 +991,7 @@
+@@ -972,6 +990,7 @@
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB), \
CFLAGS_linux := $(HEADLESS_CFLAG), \
@@ -6028,7 +6113,7 @@
CFLAGS_macosx := -I$(JDK_TOPDIR)/src/solaris/native/sun/awt, \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjawt/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
-@@ -981,6 +1000,7 @@
+@@ -980,6 +999,7 @@
LDFLAGS_SUFFIX_linux := $(JAWT_LIBS) $(LDFLAGS_JDKLIB_SUFFIX), \
LDFLAGS_SUFFIX_aix := $(JAWT_LIBS) $(LDFLAGS_JDKLIB_SUFFIX),\
LDFLAGS_SUFFIX_solaris := $(JAWT_LIBS) $(LDFLAGS_JDKLIB_SUFFIX) -lXrender, \
@@ -6036,7 +6121,7 @@
LDFLAGS_SUFFIX_macosx := -Xlinker -rpath -Xlinker @loader_path $(JAWT_LIBS) \
-framework Cocoa $(LDFLAGS_JDKLIB_SUFFIX), \
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjawt, \
-@@ -1182,6 +1202,7 @@
+@@ -1181,6 +1201,7 @@
LDFLAGS_SUFFIX_linux := -ljvm -lawt -lm $(LIBDL) -ljava, \
LDFLAGS_SUFFIX_aix := -ljvm -lawt -ljava,\
LDFLAGS_SUFFIX_solaris := $(LIBDL) -ljvm -lawt -lm -ljava $(LIBCXX) -lc, \
@@ -6044,7 +6129,7 @@
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libawt_headless, \
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
-@@ -1235,6 +1256,8 @@
+@@ -1234,6 +1255,8 @@
LIBSPLASHSCREEN_CFLAGS += -DWITH_WIN32
else ifeq ($(OPENJDK_TARGET_OS), solaris)
LIBSPLASHSCREEN_CFLAGS += -DWITH_X11 -I$(OPENWIN_HOME)/include -I$(OPENWIN_HOME)/include/X11/extensions
@@ -6053,7 +6138,7 @@
else
LIBSPLASHSCREEN_CFLAGS += -DWITH_X11 $(X_CFLAGS)
endif
-@@ -1258,6 +1281,8 @@
+@@ -1257,6 +1280,8 @@
else ifeq ($(OPENJDK_TARGET_OS), solaris)
# Solaris still uses OPENWIN_LIB ..
LIBSPLASHSCREEN_LDFLAGS_SUFFIX += -L$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) -lX11 -lXext $(LIBM) -lpthread
@@ -6062,8 +6147,8 @@
else # .. all other Unixes can use X_LIBS
LIBSPLASHSCREEN_LDFLAGS_SUFFIX += $(X_LIBS) -lX11 -lXext $(LIBM) -lpthread
endif
---- ./jdk/make/lib/CoreLibraries.gmk Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/lib/CoreLibraries.gmk Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/lib/CoreLibraries.gmk Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/lib/CoreLibraries.gmk Sat Mar 14 22:56:25 2015 -0700
@@ -82,7 +82,7 @@
endif
@@ -6136,8 +6221,8 @@
LDFLAGS_macosx := -liconv, \
LDFLAGS_SUFFIX_windows := -export:nptInitialize -export:nptTerminate, \
LDFLAGS_SUFFIX_solaris := -lc, \
---- ./jdk/make/lib/NetworkingLibraries.gmk Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/lib/NetworkingLibraries.gmk Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/lib/NetworkingLibraries.gmk Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/lib/NetworkingLibraries.gmk Sat Mar 14 22:56:25 2015 -0700
@@ -42,7 +42,7 @@
LIBNET_EXCLUDE_FILES += linux_close.c
endif
@@ -6155,8 +6240,8 @@
LDFLAGS_SUFFIX_windows := ws2_32.lib jvm.lib secur32.lib iphlpapi.lib \
delayimp.lib $(WIN_JAVA_LIB) advapi32.lib \
-DELAYLOAD:secur32.dll -DELAYLOAD:iphlpapi.dll, \
---- ./jdk/make/lib/NioLibraries.gmk Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/lib/NioLibraries.gmk Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/lib/NioLibraries.gmk Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/lib/NioLibraries.gmk Sat Mar 14 22:56:25 2015 -0700
@@ -77,9 +77,28 @@
UnixNativeDispatcher.c
endif
@@ -6195,7 +6280,15 @@
LDFLAGS_SUFFIX_macosx := -ljava -lnet -pthread -framework CoreFoundation, \
LDFLAGS_SUFFIX :=, \
VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \
-@@ -194,6 +214,7 @@
+@@ -168,6 +188,7 @@
+ ifeq ($(OPENJDK_TARGET_OS_API), posix)
+
+ ifeq (, $(filter $(OPENJDK_TARGET_OS), macosx aix))
++ ifneq ($(shell uname -s), NetBSD) # Not for NetBSD
+
+ # Suppress unused parameters required by exported JNI functions.
+ SCTP_WERROR := -Werror -Wno-error=unused-parameter
+@@ -194,6 +215,7 @@
LDFLAGS_SUFFIX_linux := -lpthread $(LIBDL) -ljava -ljvm, \
LDFLAGS_SUFFIX_posix := -lnio -lnet, \
LDFLAGS_SUFFIX_solaris := -lsocket -ljava -ljvm -lc, \
@@ -6203,9 +6296,15 @@
LDFLAGS_SUFFIX_macosx := -ljava -ljvm, \
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libsctp, \
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
---- ./jdk/make/lib/ServiceabilityLibraries.gmk Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/lib/ServiceabilityLibraries.gmk Sun Feb 01 21:05:04 2015 -0800
-@@ -30,7 +30,7 @@
+@@ -202,4 +224,5 @@
+
+ $(BUILD_LIBSCTP): $(BUILD_LIBNIO)
+ endif
++ endif
+ endif
+--- ./jdk/make/lib/ServiceabilityLibraries.gmk Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/lib/ServiceabilityLibraries.gmk Sat Mar 14 22:56:25 2015 -0700
+@@ -34,7 +34,7 @@
ifneq ($(OPENJDK_TARGET_OS), linux)
LIBATTACH_EXCLUDE_FILES += LinuxVirtualMachine.c
endif
@@ -6214,7 +6313,7 @@
LIBATTACH_EXCLUDE_FILES += BsdVirtualMachine.c
endif
ifneq ($(OPENJDK_TARGET_OS),aix)
-@@ -90,6 +90,7 @@
+@@ -94,6 +94,7 @@
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_SUFFIX_linux := -lpthread, \
LDFLAGS_SUFFIX_solaris := -lnsl -lsocket -lc, \
@@ -6222,7 +6321,7 @@
LDFLAGS_SUFFIX_windows := $(LDFLAGS_JDKLIB_SUFFIX) -export:jdwpTransport_OnLoad ws2_32.lib, \
VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \
RC_FLAGS := $(RC_FLAGS) \
-@@ -251,12 +252,15 @@
+@@ -255,12 +256,15 @@
CFLAGS := $(LIBINSTRUMENT_CFLAGS), \
CFLAGS_debug := -DJPLIS_LOGGING, \
CFLAGS_release := -DNO_JPLIS_LOGGING, \
@@ -6238,7 +6337,7 @@
LDFLAGS_macosx := -Xlinker -all_load $(JDK_OUTPUTDIR)/objs/libjli_static.a \
-framework Cocoa -framework Security -framework ApplicationServices, \
LDFLAGS_SUFFIX := $(LIBINSTRUMENT_LDFLAGS_SUFFIX), \
-@@ -264,6 +268,7 @@
+@@ -268,6 +272,7 @@
LDFLAGS_SUFFIX_solaris := $(LIBZ) -L $(INSTALL_LIBRARIES_HERE)/jli -ljli $(LIBDL) -lc, \
LDFLAGS_SUFFIX_linux := $(LIBZ) -L $(INSTALL_LIBRARIES_HERE)/jli -ljli $(LIBDL), \
LDFLAGS_SUFFIX_aix := $(LIBZ) -L$(JDK_OUTPUTDIR)/objs -ljli_static $(LIBDL),\
@@ -6246,7 +6345,7 @@
VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \
RC_FLAGS := $(RC_FLAGS) \
-D "JDK_FNAME=instrument.dll" \
-@@ -272,7 +277,7 @@
+@@ -276,7 +281,7 @@
OBJECT_DIR := $(LIBINSTRUMENT_DIR), \
DEBUG_SYMBOLS := true))
@@ -6255,7 +6354,7 @@
$(BUILD_LIBINSTRUMENT): $(JDK_OUTPUTDIR)/objs/$(LIBRARY_PREFIX)jli_static$(STATIC_LIBRARY_SUFFIX)
else
$(BUILD_LIBINSTRUMENT): $(INSTALL_LIBRARIES_HERE)/jli/$(LIBRARY_PREFIX)jli$(SHARED_LIBRARY_SUFFIX)
-@@ -298,12 +303,16 @@
+@@ -302,12 +307,16 @@
BUILD_LIBMANAGEMENT_EXCLUDES += LinuxOperatingSystem.c
endif
@@ -6273,7 +6372,7 @@
ifeq ($(ENABLE_DEBUG_SYMBOLS), true)
LIBMANAGEMENT_OPTIMIZATION := LOW
endif
-@@ -352,7 +361,7 @@
+@@ -359,7 +368,7 @@
BUILD_LIBHPROF_LDFLAGS :=
LIBHPROF_OPTIMIZATION := HIGHEST
@@ -6282,8 +6381,8 @@
ifeq ($(ENABLE_DEBUG_SYMBOLS), true)
LIBHPROF_OPTIMIZATION := LOW
endif
---- ./jdk/make/lib/SoundLibraries.gmk Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/lib/SoundLibraries.gmk Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/lib/SoundLibraries.gmk Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/lib/SoundLibraries.gmk Sat Mar 14 22:56:25 2015 -0700
@@ -75,6 +75,11 @@
LIBJSOUND_CFLAGS += -DX_PLATFORM=X_AIX
endif # OPENJDK_TARGET_OS aix
@@ -6313,8 +6412,8 @@
LDFLAGS_SUFFIX := $(ALSA_LIBS) -ljava -ljvm, \
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjsoundalsa, \
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
---- ./jdk/make/mapfiles/launchers/mapfile-x86 Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/mapfiles/launchers/mapfile-x86 Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/mapfiles/launchers/mapfile-x86 Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/mapfiles/launchers/mapfile-x86 Sat Mar 14 22:56:25 2015 -0700
@@ -33,6 +33,7 @@
environ; # Public symbols and required by Java run time
_environ;
@@ -6323,8 +6422,8 @@
___Argv; # The following are private, but as they are
_start; # exported from ctr1/crtn, the clever hacker
_init; # might know about them. However note, that
---- ./jdk/make/mapfiles/launchers/mapfile-x86_64 Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/mapfiles/launchers/mapfile-x86_64 Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/mapfiles/launchers/mapfile-x86_64 Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/mapfiles/launchers/mapfile-x86_64 Sat Mar 14 22:56:25 2015 -0700
@@ -33,6 +33,7 @@
environ; # Public symbols and required by Java run time
_environ;
@@ -6334,7 +6433,7 @@
local:
*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/make/mapfiles/libattach/mapfile-bsd Sun Feb 01 21:05:04 2015 -0800
++++ ./jdk/make/mapfiles/libattach/mapfile-bsd Sat Mar 14 22:56:25 2015 -0700
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
@@ -6379,7 +6478,7 @@
+ *;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/make/mapfiles/libnio/mapfile-bsd Sun Feb 01 21:05:04 2015 -0800
++++ ./jdk/make/mapfiles/libnio/mapfile-bsd Sat Mar 14 22:56:25 2015 -0700
@@ -0,0 +1,195 @@
+#
+# Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
@@ -6576,8 +6675,8 @@
+ local:
+ *;
+};
---- ./jdk/make/mapfiles/libunpack/mapfile-vers-unpack200 Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/mapfiles/libunpack/mapfile-vers-unpack200 Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/mapfiles/libunpack/mapfile-vers-unpack200 Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/mapfiles/libunpack/mapfile-vers-unpack200 Sat Mar 14 22:56:25 2015 -0700
@@ -26,6 +26,9 @@
# Define library interface.
@@ -6589,7 +6688,7 @@
*;
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/make/netbeans/common/bsd-sources.ent Sun Feb 01 21:05:04 2015 -0800
++++ ./jdk/make/netbeans/common/bsd-sources.ent Sat Mar 14 22:56:25 2015 -0700
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
@@ -6637,7 +6736,7 @@
+ <location>${root}/src/bsd/classes</location>
+</source-folder>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/make/netbeans/common/bsd-view.ent Sun Feb 01 21:05:04 2015 -0800
++++ ./jdk/make/netbeans/common/bsd-view.ent Sat Mar 14 22:56:25 2015 -0700
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
@@ -6678,8 +6777,8 @@
+ <includes>${includes}</includes>
+ <excludes>${excludes}</excludes>
+</source-folder>
---- ./jdk/make/netbeans/common/java-data-native.ent Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/netbeans/common/java-data-native.ent Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/netbeans/common/java-data-native.ent Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/netbeans/common/java-data-native.ent Sat Mar 14 22:56:25 2015 -0700
@@ -34,6 +34,7 @@
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/4">
<compilation-unit>
@@ -6688,8 +6787,8 @@
<package-root>${root}/src/macosx/classes</package-root>
<package-root>${root}/src/solaris/classes</package-root>
<package-root>${root}/src/windows/classes</package-root>
---- ./jdk/make/netbeans/common/make.xml Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/netbeans/common/make.xml Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/netbeans/common/make.xml Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/netbeans/common/make.xml Sat Mar 14 22:56:25 2015 -0700
@@ -32,16 +32,21 @@
-->
@@ -6724,8 +6823,8 @@
<macrodef name="make-run">
<attribute name="target"/>
<attribute name="dir"/>
---- ./jdk/make/netbeans/j2se/nbproject/project.xml Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/netbeans/j2se/nbproject/project.xml Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/netbeans/j2se/nbproject/project.xml Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/netbeans/j2se/nbproject/project.xml Sat Mar 14 22:56:25 2015 -0700
@@ -34,6 +34,7 @@
<!DOCTYPE project [
<!ENTITY properties SYSTEM "../../common/properties.ent">
@@ -6758,8 +6857,8 @@
&macosx-view;
&unix-view;
&windows-view;
---- ./jdk/make/netbeans/world/nbproject/project.xml Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/make/netbeans/world/nbproject/project.xml Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/make/netbeans/world/nbproject/project.xml Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/make/netbeans/world/nbproject/project.xml Sat Mar 14 22:56:25 2015 -0700
@@ -34,12 +34,14 @@
<!DOCTYPE project [
<!ENTITY properties SYSTEM "../../common/properties.ent">
@@ -6792,7 +6891,7 @@
&unix-view;
&windows-view;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/src/bsd/classes/java/net/DefaultInterface.java Sun Feb 01 21:05:04 2015 -0800
++++ ./jdk/src/bsd/classes/java/net/DefaultInterface.java Sat Mar 14 22:56:25 2015 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
@@ -6892,7 +6991,7 @@
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/src/bsd/classes/sun/nio/ch/DefaultSelectorProvider.java Sun Feb 01 21:05:04 2015 -0800
++++ ./jdk/src/bsd/classes/sun/nio/ch/DefaultSelectorProvider.java Sat Mar 14 22:56:25 2015 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
@@ -6943,7 +7042,7 @@
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/src/bsd/classes/sun/nio/ch/KQueueArrayWrapper.java Sun Feb 01 21:05:04 2015 -0800
++++ ./jdk/src/bsd/classes/sun/nio/ch/KQueueArrayWrapper.java Sat Mar 14 22:56:25 2015 -0700
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
@@ -7159,7 +7258,7 @@
+ private static native void interrupt(int fd);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/src/bsd/classes/sun/nio/ch/KQueueSelectorImpl.java Sun Feb 01 21:05:04 2015 -0800
++++ ./jdk/src/bsd/classes/sun/nio/ch/KQueueSelectorImpl.java Sat Mar 14 22:56:25 2015 -0700
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
@@ -7411,7 +7510,7 @@
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/src/bsd/classes/sun/nio/ch/KQueueSelectorProvider.java Sun Feb 01 21:05:04 2015 -0800
++++ ./jdk/src/bsd/classes/sun/nio/ch/KQueueSelectorProvider.java Sat Mar 14 22:56:25 2015 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
@@ -7457,8 +7556,50 @@
+ return new KQueueSelectorImpl(this);
+ }
+}
+--- ./jdk/src/bsd/doc/man/javah.1 Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/bsd/doc/man/javah.1 Sat Mar 14 22:56:25 2015 -0700
+@@ -110,7 +110,7 @@
+
+ \&.:\fIyour-path\fR
+
+-Example: \f3\&.:/home/avh/classes:/usr/local/java/classes\fR
++Example: \f3\&.:/home/avh/classes:/usr/local/share/java/classes\fR
+
+ \fIWindows\fR:
+
+--- ./jdk/src/bsd/doc/man/rmic.1 Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/bsd/doc/man/rmic.1 Sat Mar 14 22:56:25 2015 -0700
+@@ -93,7 +93,7 @@
+ .TP
+ -classpath path
+ .br
+-Specifies the path the \f3rmic\fR command uses to look up classes\&. This option overrides the default or the \f3CLASSPATH\fR environment variable when it is set\&. Directories are separated by colons\&. The general format for path is: \f3\&.:<your_path>\fR, for example: \f3\&.:/usr/local/java/classes\fR\&.
++Specifies the path the \f3rmic\fR command uses to look up classes\&. This option overrides the default or the \f3CLASSPATH\fR environment variable when it is set\&. Directories are separated by colons\&. The general format for path is: \f3\&.:<your_path>\fR, for example: \f3\&.:/usr/local/share/java/classes\fR\&.
+ .TP
+ -d \fIdirectory\fR
+ .br
+@@ -207,7 +207,7 @@
+ .SH ENVIRONMENT\ VARIABLES
+ .TP
+ CLASSPATH
+-Used to provide the system a path to user-defined classes\&. Directories are separated by colons, for example: \f3\&.:/usr/local/java/classes\fR\&.
++Used to provide the system a path to user-defined classes\&. Directories are separated by colons, for example: \f3\&.:/usr/local/share/java/classes\fR\&.
+ .SH SEE\ ALSO
+ .TP 0.2i
+ \(bu
+--- ./jdk/src/bsd/doc/man/rmid.1 Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/bsd/doc/man/rmid.1 Sat Mar 14 22:56:25 2015 -0700
+@@ -301,7 +301,7 @@
+ .SH ENVIRONMENT\ VARIABLES
+ .TP
+ CLASSPATH
+-Used to provide the system a path to user-defined classes\&. Directories are separated by colons, for example: \f3\&.:/usr/local/java/classes\fR\&.
++Used to provide the system a path to user-defined classes\&. Directories are separated by colons, for example: \f3\&.:/usr/local/share/java/classes\fR\&.
+ .SH SEE\ ALSO
+ .TP 0.2i
+ \(bu
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/src/bsd/native/sun/nio/ch/KQueueArrayWrapper.c Sun Feb 01 21:05:04 2015 -0800
++++ ./jdk/src/bsd/native/sun/nio/ch/KQueueArrayWrapper.c Sat Mar 14 22:56:25 2015 -0700
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
@@ -7631,7 +7772,7 @@
+ }
+}
+
---- ./jdk/src/macosx/classes/java/net/DefaultInterface.java Mon Dec 08 08:53:26 2014 -0800
+--- ./jdk/src/macosx/classes/java/net/DefaultInterface.java Mon Feb 02 10:12:21 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
@@ -7731,7 +7872,7 @@
- return (ppp != null) ? ppp : loopback;
- }
-}
---- ./jdk/src/macosx/classes/sun/nio/ch/DefaultSelectorProvider.java Mon Dec 08 08:53:26 2014 -0800
+--- ./jdk/src/macosx/classes/sun/nio/ch/DefaultSelectorProvider.java Mon Feb 02 10:12:21 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
@@ -7782,7 +7923,7 @@
- }
-
-}
---- ./jdk/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java Mon Dec 08 08:53:26 2014 -0800
+--- ./jdk/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java Mon Feb 02 10:12:21 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,213 +0,0 @@
-/*
@@ -7998,7 +8139,7 @@
- long timeout);
- private static native void interrupt(int fd);
-}
---- ./jdk/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Mon Dec 08 08:53:26 2014 -0800
+--- ./jdk/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Mon Feb 02 10:12:21 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,249 +0,0 @@
-/*
@@ -8250,7 +8391,7 @@
- return this;
- }
-}
---- ./jdk/src/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java Mon Dec 08 08:53:26 2014 -0800
+--- ./jdk/src/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java Mon Feb 02 10:12:21 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
@@ -8297,7 +8438,7 @@
- return new KQueueSelectorImpl(this);
- }
-}
---- ./jdk/src/macosx/native/sun/nio/ch/KQueueArrayWrapper.c Mon Dec 08 08:53:26 2014 -0800
+--- ./jdk/src/macosx/native/sun/nio/ch/KQueueArrayWrapper.c Mon Feb 02 10:12:21 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
-/*
@@ -8471,9 +8612,9 @@
- }
-}
-
---- ./jdk/src/share/bin/jli_util.h Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/bin/jli_util.h Sun Feb 01 21:05:04 2015 -0800
-@@ -82,7 +82,7 @@
+--- ./jdk/src/share/bin/jli_util.h Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/bin/jli_util.h Sat Mar 14 22:56:25 2015 -0700
+@@ -87,7 +87,7 @@
#define _LARGFILE64_SOURCE
#define JLI_Lseek lseek64
#endif
@@ -8482,8 +8623,8 @@
#define JLI_Lseek lseek
#endif
#ifdef _AIX
---- ./jdk/src/share/classes/sun/awt/FontConfiguration.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/classes/sun/awt/FontConfiguration.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/classes/sun/awt/FontConfiguration.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/classes/sun/awt/FontConfiguration.java Sat Mar 14 22:56:25 2015 -0700
@@ -1146,7 +1146,7 @@
*/
HashMap<String, Boolean> existsMap;
@@ -8493,8 +8634,8 @@
return false;
} else if (existsMap == null) {
existsMap = new HashMap<String, Boolean>();
---- ./jdk/src/share/classes/sun/awt/OSInfo.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/classes/sun/awt/OSInfo.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/classes/sun/awt/OSInfo.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/classes/sun/awt/OSInfo.java Sat Mar 14 22:56:25 2015 -0700
@@ -39,6 +39,7 @@
WINDOWS,
LINUX,
@@ -8514,8 +8655,8 @@
if (osName.contains("OS X")) {
return MACOSX;
}
---- ./jdk/src/share/classes/sun/font/FontUtilities.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/classes/sun/font/FontUtilities.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/classes/sun/font/FontUtilities.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/classes/sun/font/FontUtilities.java Sat Mar 14 22:56:25 2015 -0700
@@ -48,6 +48,8 @@
public static boolean isLinux;
@@ -8534,8 +8675,8 @@
isMacOSX = osName.contains("OS X"); // TODO: MacOSX
String t2kStr = System.getProperty("sun.java2d.font.scaler");
---- ./jdk/src/share/classes/sun/font/SunFontManager.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/classes/sun/font/SunFontManager.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/classes/sun/font/SunFontManager.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/classes/sun/font/SunFontManager.java Sat Mar 14 22:56:25 2015 -0700
@@ -418,7 +418,7 @@
* registerFonts method as on-screen these JRE fonts
* always go through the T2K rasteriser.
@@ -8545,8 +8686,8 @@
/* Linux font configuration uses these fonts */
registerFontDir(jreFontDirName);
}
---- ./jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java Sat Mar 14 22:56:25 2015 -0700
@@ -1298,7 +1298,7 @@
String osName = AccessController.doPrivileged(
new GetPropertyAction("os.name"));
@@ -8556,8 +8697,8 @@
charset("x-COMPOUND_TEXT", "COMPOUND_TEXT",
new String[] {
"COMPOUND_TEXT", // JDK historical
---- ./jdk/src/share/classes/sun/print/PSPrinterJob.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/classes/sun/print/PSPrinterJob.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/classes/sun/print/PSPrinterJob.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/classes/sun/print/PSPrinterJob.java Sat Mar 14 22:56:25 2015 -0700
@@ -1587,7 +1587,7 @@
}
@@ -8567,8 +8708,8 @@
execCmd = new String[ncomps];
execCmd[n++] = "/usr/bin/lpr";
if ((pFlags & PRINTER) != 0) {
---- ./jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java Sat Mar 14 22:56:25 2015 -0700
@@ -48,6 +48,7 @@
public Boolean run() {
String osname = System.getProperty("os.name");
@@ -8577,8 +8718,8 @@
osname.contains("OS X") ||
osname.startsWith("Linux")) {
return new Boolean(System.getProperty
---- ./jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java Sat Mar 14 22:56:25 2015 -0700
@@ -90,6 +90,12 @@
"libgssapi_krb5.so",
"libgssapi_krb5.so.2",
@@ -8592,20 +8733,8 @@
} else if (osname.contains("OS X")) {
gssLibs = new String[]{
"libgssapi_krb5.dylib",
---- ./jdk/src/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java Sun Feb 01 21:05:04 2015 -0800
-@@ -403,7 +403,8 @@
- long uid = 0;
-
- if (osname.startsWith("SunOS") ||
-- (osname.startsWith("Linux"))) {
-+ osname.startsWith("Linux") ||
-+ osname.endsWith("BSD")) {
- try {
- Class<?> c = Class.forName
- ("com.sun.security.auth.module.UnixSystem");
---- ./jdk/src/share/classes/sun/tools/attach/META-INF/services/com.sun.tools.attach.spi.AttachProvider Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/classes/sun/tools/attach/META-INF/services/com.sun.tools.attach.spi.AttachProvider Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/classes/sun/tools/attach/META-INF/services/com.sun.tools.attach.spi.AttachProvider Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/classes/sun/tools/attach/META-INF/services/com.sun.tools.attach.spi.AttachProvider Sat Mar 14 22:56:25 2015 -0700
@@ -31,4 +31,5 @@
#[windows]sun.tools.attach.WindowsAttachProvider
#[linux]sun.tools.attach.LinuxAttachProvider
@@ -8613,7 +8742,7 @@
+#[bsd]sun.tools.attach.BsdAttachProvider
#[aix]sun.tools.attach.AixAttachProvider
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/src/share/lib/security/java.security-bsd Sun Feb 01 21:05:04 2015 -0800
++++ ./jdk/src/share/lib/security/java.security-bsd Sat Mar 14 22:56:25 2015 -0700
@@ -0,0 +1,498 @@
+#
+# This is the "master security properties file".
@@ -9113,8 +9242,8 @@
+#
+# Example:
+# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
---- ./jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp Sat Mar 14 22:56:25 2015 -0700
@@ -62,7 +62,7 @@
#endif // End of ZLIB
@@ -9124,8 +9253,8 @@
#define SWAP_BYTES(a) \
((((a) << 8) & 0xff00) | 0x00ff) & (((a) >> 8) | 0xff00)
#else
---- ./jdk/src/share/native/com/sun/media/sound/DirectAudioDevice.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/com/sun/media/sound/DirectAudioDevice.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/com/sun/media/sound/DirectAudioDevice.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/com/sun/media/sound/DirectAudioDevice.c Sat Mar 14 22:56:25 2015 -0700
@@ -121,7 +121,7 @@
}
@@ -9153,8 +9282,8 @@
#define MAP_NATIVE2LE16(a) (a)
#define MAP_NATIVE2BE16(a) MAP_SWAP16_impl(a)
#define MAP_NATIVE2LE32(a) (a)
---- ./jdk/src/share/native/com/sun/media/sound/Utilities.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/com/sun/media/sound/Utilities.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/com/sun/media/sound/Utilities.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/com/sun/media/sound/Utilities.c Sat Mar 14 22:56:25 2015 -0700
@@ -28,7 +28,7 @@
@@ -9164,8 +9293,8 @@
return 0;
#else
return 1;
---- ./jdk/src/share/native/java/lang/fdlibm/include/fdlibm.h Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/java/lang/fdlibm/include/fdlibm.h Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/java/lang/fdlibm/include/fdlibm.h Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/java/lang/fdlibm/include/fdlibm.h Sat Mar 14 22:56:25 2015 -0700
@@ -40,7 +40,7 @@
#endif
#endif
@@ -9175,9 +9304,9 @@
#define __HI(x) *(1+(int*)&x)
#define __LO(x) *(int*)&x
#define __HIp(x) *(1+(int*)x)
---- ./jdk/src/share/native/sun/awt/image/awt_parseImage.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/image/awt_parseImage.c Sun Feb 01 21:05:04 2015 -0800
-@@ -623,7 +623,7 @@
+--- ./jdk/src/share/native/sun/awt/image/awt_parseImage.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/image/awt_parseImage.c Sat Mar 14 22:56:25 2015 -0700
+@@ -624,7 +624,7 @@
switch(type) {
case java_awt_image_BufferedImage_TYPE_INT_ARGB:
case java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE:
@@ -9186,7 +9315,7 @@
colorOrder[0] = 2;
colorOrder[1] = 1;
colorOrder[2] = 0;
-@@ -636,7 +636,7 @@
+@@ -637,7 +637,7 @@
#endif
break;
case java_awt_image_BufferedImage_TYPE_INT_BGR:
@@ -9195,7 +9324,7 @@
colorOrder[0] = 0;
colorOrder[1] = 1;
colorOrder[2] = 2;
-@@ -647,7 +647,7 @@
+@@ -648,7 +648,7 @@
#endif
break;
case java_awt_image_BufferedImage_TYPE_INT_RGB:
@@ -9204,8 +9333,8 @@
colorOrder[0] = 2;
colorOrder[1] = 1;
colorOrder[2] = 0;
---- ./jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Sat Mar 14 22:56:25 2015 -0700
@@ -1176,7 +1176,7 @@
#define NLUT 8
@@ -9215,8 +9344,8 @@
#define INDEXES { 3, 2, 1, 0, 7, 6, 5, 4 }
#else
#define INDEXES { 0, 1, 2, 3, 4, 5, 6, 7 }
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv2x2_f.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv2x2_f.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv2x2_f.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv2x2_f.c Sat Mar 14 22:56:25 2015 -0700
@@ -86,7 +86,7 @@
#endif /* MLIB_USE_FTOI_CLAMPING */
@@ -9256,8 +9385,8 @@
#endif /* _NO_LONGLONG */
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16ext.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16ext.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16ext.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16ext.c Sat Mar 14 22:56:25 2015 -0700
@@ -126,7 +126,7 @@
#define D2I(x) CLAMP_S32((x) SAT_OFF)
@@ -9297,8 +9426,8 @@
#endif /* _NO_LONGLONG */
/***************************************************************/
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16nw.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16nw.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16nw.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16nw.c Sat Mar 14 22:56:25 2015 -0700
@@ -94,7 +94,7 @@
#define D2I(x) CLAMP_S32((x) SAT_OFF)
@@ -9338,8 +9467,8 @@
#endif /* _NO_LONGLONG */
/***************************************************************/
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8ext.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8ext.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8ext.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8ext.c Sat Mar 14 22:56:25 2015 -0700
@@ -126,7 +126,7 @@
#define D2I(x) CLAMP_S32((x) SAT_OFF)
@@ -9379,8 +9508,8 @@
#endif /* _NO_LONGLONG */
/***************************************************************/
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8nw.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8nw.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8nw.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8nw.c Sat Mar 14 22:56:25 2015 -0700
@@ -95,7 +95,7 @@
#define D2I(x) CLAMP_S32((x) SAT_OFF)
@@ -9420,8 +9549,8 @@
#endif /* _NO_LONGLONG */
/***************************************************************/
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16ext.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16ext.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16ext.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16ext.c Sat Mar 14 22:56:25 2015 -0700
@@ -126,7 +126,7 @@
#define D2I(x) CLAMP_S32((x) SAT_OFF)
@@ -9461,8 +9590,8 @@
#endif /* _NO_LONGLONG */
/***************************************************************/
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16nw.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16nw.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16nw.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16nw.c Sat Mar 14 22:56:25 2015 -0700
@@ -94,7 +94,7 @@
#define D2I(x) CLAMP_S32((x) SAT_OFF)
@@ -9502,8 +9631,8 @@
#endif /* _NO_LONGLONG */
/***************************************************************/
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageCopy_Bit.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageCopy_Bit.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageCopy_Bit.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageCopy_Bit.c Sat Mar 14 22:56:25 2015 -0700
@@ -95,7 +95,7 @@
dst = dp[0];
if (ld_offset + size < 32) {
@@ -9723,8 +9852,8 @@
}
#else /* _LONGLONG */
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_64.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_64.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_64.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_64.c Sat Mar 14 22:56:25 2015 -0700
@@ -168,7 +168,7 @@
}
@@ -10005,8 +10134,8 @@
dp[12] = t0;
dp[13] = t1;
dp[14] = t2;
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_Bit.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_Bit.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_Bit.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_Bit.c Sat Mar 14 22:56:25 2015 -0700
@@ -88,7 +88,7 @@
} d64_2_f32;
@@ -10158,8 +10287,8 @@
((mlib_u32*)lh)[0] = l; ((mlib_u32*)lh)[1] = l;
((mlib_u32*)lh)[2] = l; ((mlib_u32*)lh)[3] = h;
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageUtils.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageUtils.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageUtils.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageUtils.c Sat Mar 14 22:56:25 2015 -0700
@@ -30,7 +30,7 @@
typedef union {
mlib_d64 db;
@@ -10169,8 +10298,8 @@
mlib_s32 int1, int0;
#else
mlib_s32 int0, int1;
---- ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageCopy.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageCopy.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageCopy.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageCopy.c Sat Mar 14 22:56:25 2015 -0700
@@ -275,11 +275,11 @@
for (i = 0; j <= (b_size - 4); j += 4, i++) {
src0 = src1;
@@ -10269,8 +10398,8 @@
s0 = s1;
dp += SIZE;
sp += SIZE;
---- ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageLookUp_f.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageLookUp_f.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageLookUp_f.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageLookUp_f.c Sat Mar 14 22:56:25 2015 -0700
@@ -120,7 +120,7 @@
} \
}
@@ -11503,8 +11632,8 @@
dp[12] = t0;
dp[13] = t1;
dp[14] = t2;
---- ./jdk/src/share/native/sun/awt/medialib/mlib_image.h Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_image.h Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_image.h Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_image.h Sat Mar 14 22:56:25 2015 -0700
@@ -27,9 +27,6 @@
#ifndef MLIB_IMAGE_H
#define MLIB_IMAGE_H
@@ -11515,8 +11644,8 @@
#include <mlib_types.h>
#include <mlib_status.h>
#include <mlib_sys.h>
---- ./jdk/src/share/native/sun/awt/medialib/mlib_sys.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_sys.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_sys.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_sys.c Sat Mar 14 22:56:25 2015 -0700
@@ -29,7 +29,7 @@
#ifdef MACOSX
#include <unistd.h>
@@ -11536,8 +11665,8 @@
#else
return (void *) memalign(8, size);
#endif /* _MSC_VER */
---- ./jdk/src/share/native/sun/font/layout/LEStandalone.h Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/font/layout/LEStandalone.h Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/font/layout/LEStandalone.h Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/font/layout/LEStandalone.h Sat Mar 14 22:56:25 2015 -0700
@@ -136,7 +136,7 @@
#define U_CAPI extern "C"
@@ -11547,8 +11676,8 @@
#define U_IS_BIG_ENDIAN 0
#endif
#endif
---- ./jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Sat Mar 14 22:56:25 2015 -0700
@@ -182,7 +182,7 @@
return 0L;
}
@@ -11558,19 +11687,8 @@
/* Reversing data packed into int for LE archs */
if (isInIntPacked) {
inFormatter ^= DOSWAP_SH(1);
---- ./jdk/src/share/native/sun/java2d/cmm/lcms/lcms2.h Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/java2d/cmm/lcms/lcms2.h Sun Feb 01 21:05:04 2015 -0800
-@@ -202,7 +202,7 @@
- // Try to detect big endian platforms. This list can be endless, so only some checks are performed over here.
- // you can pass this toggle to the compiler by using -DCMS_USE_BIG_ENDIAN or something similar
-
--#if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN)
-+#if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN) || defined(VM_BIG_ENDIAN)
- # define CMS_USE_BIG_ENDIAN 1
- #endif
-
---- ./jdk/src/share/native/sun/management/DiagnosticCommandImpl.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/share/native/sun/management/DiagnosticCommandImpl.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/share/native/sun/management/DiagnosticCommandImpl.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/share/native/sun/management/DiagnosticCommandImpl.c Sat Mar 14 22:56:25 2015 -0700
@@ -27,6 +27,7 @@
#include <jni.h>
#include "management.h"
@@ -11579,8 +11697,8 @@
JNIEXPORT void JNICALL Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled
(JNIEnv *env, jobject dummy, jboolean enabled) {
---- ./jdk/src/solaris/back/util_md.h Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/back/util_md.h Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/back/util_md.h Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/back/util_md.h Sat Mar 14 22:56:25 2015 -0700
@@ -51,7 +51,7 @@
/* On little endian machines, convert java big endian numbers. */
@@ -11590,8 +11708,8 @@
#define HOST_TO_JAVA_CHAR(x) (((x & 0xff) << 8) | ((x >> 8) & (0xff)))
#define HOST_TO_JAVA_SHORT(x) (((x & 0xff) << 8) | ((x >> 8) & (0xff)))
---- ./jdk/src/solaris/bin/ergo_i586.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/bin/ergo_i586.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/bin/ergo_i586.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/bin/ergo_i586.c Sat Mar 14 22:56:25 2015 -0700
@@ -106,7 +106,7 @@
#endif /* __solaris__ */
@@ -11610,8 +11728,8 @@
/*
* Routines shared by solaris-i586 and linux-i586.
---- ./jdk/src/solaris/bin/java_md_solinux.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/bin/java_md_solinux.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/bin/java_md_solinux.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/bin/java_md_solinux.c Sat Mar 14 22:56:25 2015 -0700
@@ -306,9 +306,9 @@
if (llp == NULL && dmllp == NULL) {
return JNI_FALSE;
@@ -11698,8 +11816,8 @@
}
int
---- ./jdk/src/solaris/bin/java_md_solinux.h Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/bin/java_md_solinux.h Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/bin/java_md_solinux.h Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/bin/java_md_solinux.h Sat Mar 14 22:56:25 2015 -0700
@@ -26,17 +26,26 @@
#ifndef JAVA_MD_SOLINUX_H
#define JAVA_MD_SOLINUX_H
@@ -11740,433 +11858,58 @@
#else /* !__solaris__, i.e. Linux, AIX,.. */
static const char *system_dir = "/usr/java";
static const char *user_dir = "/java";
---- ./jdk/src/solaris/classes/java/lang/UNIXProcess.java.bsd Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/classes/java/lang/UNIXProcess.java.bsd Sun Feb 01 21:05:04 2015 -0800
-@@ -94,8 +94,9 @@
- {
- public LaunchMechanism run() {
- String javahome = System.getProperty("java.home");
-+ String osArch = System.getProperty("os.arch");
-
-- helperpath = toCString(javahome + "/lib/jspawnhelper");
-+ helperpath = toCString(javahome + "/lib/" + osArch + "/jspawnhelper");
- String s = System.getProperty(
- "jdk.lang.Process.launchMechanism", "posix_spawn");
-
---- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/src/solaris/classes/java/lang/UNIXProcess.java.macosx Sun Feb 01 21:05:04 2015 -0800
-@@ -0,0 +1,408 @@
-+/*
-+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
-+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-+ *
-+ * This code is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 only, as
-+ * published by the Free Software Foundation. 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 java.lang;
-+
-+import java.io.BufferedInputStream;
-+import java.io.BufferedOutputStream;
-+import java.io.ByteArrayInputStream;
-+import java.io.FileDescriptor;
-+import java.io.FileInputStream;
-+import java.io.FileOutputStream;
-+import java.io.IOException;
-+import java.io.InputStream;
-+import java.io.OutputStream;
-+import java.util.Arrays;
-+import java.util.concurrent.Executors;
-+import java.util.concurrent.Executor;
-+import java.util.concurrent.ThreadFactory;
-+import java.util.concurrent.TimeUnit;
-+import java.security.AccessController;
-+import static java.security.AccessController.doPrivileged;
-+import java.security.PrivilegedAction;
-+import java.security.PrivilegedActionException;
-+import java.security.PrivilegedExceptionAction;
-+
-+/**
-+ * java.lang.Process subclass in the UNIX environment.
-+ *
-+ * @author Mario Wolczko and Ross Knippel.
-+ * @author Konstantin Kladko (ported to Bsd)
-+ * @author Martin Buchholz
-+ */
-+final class UNIXProcess extends Process {
-+ private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
-+ = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
-+
-+ private final int pid;
-+ private int exitcode;
-+ private boolean hasExited;
-+
-+ private /* final */ OutputStream stdin;
-+ private /* final */ InputStream stdout;
-+ private /* final */ InputStream stderr;
-+
-+ private static enum LaunchMechanism {
-+ FORK(1),
-+ POSIX_SPAWN(2);
-+
-+ private int value;
-+ LaunchMechanism(int x) {value = x;}
-+ };
-+
-+ /* On BSD, the default is to spawn */
-+ private static final LaunchMechanism launchMechanism;
-+ private static byte[] helperpath;
-+
-+ private static byte[] toCString(String s) {
-+ if (s == null)
-+ return null;
-+ byte[] bytes = s.getBytes();
-+ byte[] result = new byte[bytes.length + 1];
-+ System.arraycopy(bytes, 0,
-+ result, 0,
-+ bytes.length);
-+ result[result.length-1] = (byte)0;
-+ return result;
-+ }
-+
-+ static {
-+ launchMechanism = AccessController.doPrivileged(
-+ new PrivilegedAction<LaunchMechanism>()
-+ {
-+ public LaunchMechanism run() {
-+ String javahome = System.getProperty("java.home");
-+
-+ helperpath = toCString(javahome + "/lib/jspawnhelper");
-+ String s = System.getProperty(
-+ "jdk.lang.Process.launchMechanism", "posix_spawn");
-+
-+ try {
-+ return LaunchMechanism.valueOf(s.toUpperCase());
-+ } catch (IllegalArgumentException e) {
-+ throw new Error(s + " is not a supported " +
-+ "process launch mechanism on this platform.");
-+ }
-+ }
-+ });
-+ }
-+
-+ /* this is for the reaping thread */
-+ private native int waitForProcessExit(int pid);
-+
-+ /**
-+ * Create a process. Depending on the mode flag, this is done by
-+ * one of the following mechanisms.
-+ * - fork(2) and exec(2)
-+ * - posix_spawn(2)
-+ *
-+ * @param fds an array of three file descriptors.
-+ * Indexes 0, 1, and 2 correspond to standard input,
-+ * standard output and standard error, respectively. On
-+ * input, a value of -1 means to create a pipe to connect
-+ * child and parent processes. On output, a value which
-+ * is not -1 is the parent pipe fd corresponding to the
-+ * pipe which has been created. An element of this array
-+ * is -1 on input if and only if it is <em>not</em> -1 on
-+ * output.
-+ * @return the pid of the subprocess
-+ */
-+ private native int forkAndExec(int mode, byte[] helperpath,
-+ byte[] prog,
-+ byte[] argBlock, int argc,
-+ byte[] envBlock, int envc,
-+ byte[] dir,
-+ int[] fds,
-+ boolean redirectErrorStream)
-+ throws IOException;
-+
-+ /**
-+ * The thread factory used to create "process reaper" daemon threads.
-+ */
-+ private static class ProcessReaperThreadFactory implements ThreadFactory {
-+ private final static ThreadGroup group = getRootThreadGroup();
-+
-+ private static ThreadGroup getRootThreadGroup() {
-+ return doPrivileged(new PrivilegedAction<ThreadGroup> () {
-+ public ThreadGroup run() {
-+ ThreadGroup root = Thread.currentThread().getThreadGroup();
-+ while (root.getParent() != null)
-+ root = root.getParent();
-+ return root;
-+ }});
-+ }
-+
-+ public Thread newThread(Runnable grimReaper) {
-+ // Our thread stack requirement is quite modest.
-+ Thread t = new Thread(group, grimReaper, "process reaper", 32768);
-+ t.setDaemon(true);
-+ // A small attempt (probably futile) to avoid priority inversion
-+ t.setPriority(Thread.MAX_PRIORITY);
-+ return t;
-+ }
-+ }
-+
-+ /**
-+ * The thread pool of "process reaper" daemon threads.
-+ */
-+ private static final Executor processReaperExecutor =
-+ doPrivileged(new PrivilegedAction<Executor>() {
-+ public Executor run() {
-+ return Executors.newCachedThreadPool
-+ (new ProcessReaperThreadFactory());
-+ }});
-+
-+ UNIXProcess(final byte[] prog,
-+ final byte[] argBlock, final int argc,
-+ final byte[] envBlock, final int envc,
-+ final byte[] dir,
-+ final int[] fds,
-+ final boolean redirectErrorStream)
-+ throws IOException {
-+
-+ pid = forkAndExec(launchMechanism.value,
-+ helperpath,
-+ prog,
-+ argBlock, argc,
-+ envBlock, envc,
-+ dir,
-+ fds,
-+ redirectErrorStream);
-+
-+ try {
-+ doPrivileged(new PrivilegedExceptionAction<Void>() {
-+ public Void run() throws IOException {
-+ initStreams(fds);
-+ return null;
-+ }});
-+ } catch (PrivilegedActionException ex) {
-+ throw (IOException) ex.getException();
-+ }
-+ }
-+
-+ static FileDescriptor newFileDescriptor(int fd) {
-+ FileDescriptor fileDescriptor = new FileDescriptor();
-+ fdAccess.set(fileDescriptor, fd);
-+ return fileDescriptor;
-+ }
-+
-+ void initStreams(int[] fds) throws IOException {
-+ stdin = (fds[0] == -1) ?
-+ ProcessBuilder.NullOutputStream.INSTANCE :
-+ new ProcessPipeOutputStream(fds[0]);
-+
-+ stdout = (fds[1] == -1) ?
-+ ProcessBuilder.NullInputStream.INSTANCE :
-+ new ProcessPipeInputStream(fds[1]);
-+
-+ stderr = (fds[2] == -1) ?
-+ ProcessBuilder.NullInputStream.INSTANCE :
-+ new ProcessPipeInputStream(fds[2]);
-+
-+ processReaperExecutor.execute(new Runnable() {
-+ public void run() {
-+ int exitcode = waitForProcessExit(pid);
-+ UNIXProcess.this.processExited(exitcode);
-+ }});
-+ }
-+
-+ void processExited(int exitcode) {
-+ synchronized (this) {
-+ this.exitcode = exitcode;
-+ hasExited = true;
-+ notifyAll();
-+ }
-+
-+ if (stdout instanceof ProcessPipeInputStream)
-+ ((ProcessPipeInputStream) stdout).processExited();
-+
-+ if (stderr instanceof ProcessPipeInputStream)
-+ ((ProcessPipeInputStream) stderr).processExited();
-+
-+ if (stdin instanceof ProcessPipeOutputStream)
-+ ((ProcessPipeOutputStream) stdin).processExited();
-+ }
-+
-+ public OutputStream getOutputStream() {
-+ return stdin;
-+ }
-+
-+ public InputStream getInputStream() {
-+ return stdout;
-+ }
-+
-+ public InputStream getErrorStream() {
-+ return stderr;
-+ }
-+
-+ public synchronized int waitFor() throws InterruptedException {
-+ while (!hasExited) {
-+ wait();
-+ }
-+ return exitcode;
-+ }
-+
-+ @Override
-+ public synchronized boolean waitFor(long timeout, TimeUnit unit)
-+ throws InterruptedException
-+ {
-+ if (hasExited) return true;
-+ if (timeout <= 0) return false;
-+
-+ long timeoutAsNanos = unit.toNanos(timeout);
-+ long startTime = System.nanoTime();
-+ long rem = timeoutAsNanos;
-+
-+ while (!hasExited && (rem > 0)) {
-+ wait(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
-+ rem = timeoutAsNanos - (System.nanoTime() - startTime);
-+ }
-+ return hasExited;
-+ }
-+
-+ public synchronized int exitValue() {
-+ if (!hasExited) {
-+ throw new IllegalThreadStateException("process hasn't exited");
-+ }
-+ return exitcode;
-+ }
-+
-+ private static native void destroyProcess(int pid, boolean force);
-+ private void destroy(boolean force) {
-+ // There is a risk that pid will be recycled, causing us to
-+ // kill the wrong process! So we only terminate processes
-+ // that appear to still be running. Even with this check,
-+ // there is an unavoidable race condition here, but the window
-+ // is very small, and OSes try hard to not recycle pids too
-+ // soon, so this is quite safe.
-+ synchronized (this) {
-+ if (!hasExited)
-+ destroyProcess(pid, force);
-+ }
-+ try { stdin.close(); } catch (IOException ignored) {}
-+ try { stdout.close(); } catch (IOException ignored) {}
-+ try { stderr.close(); } catch (IOException ignored) {}
-+ }
-+
-+ public void destroy() {
-+ destroy(false);
-+ }
-+
-+ @Override
-+ public Process destroyForcibly() {
-+ destroy(true);
-+ return this;
-+ }
-+
-+ @Override
-+ public synchronized boolean isAlive() {
-+ return !hasExited;
-+ }
-+
-+ private static native void init();
-+
-+ static {
-+ init();
-+ }
-+
-+ /**
-+ * A buffered input stream for a subprocess pipe file descriptor
-+ * that allows the underlying file descriptor to be reclaimed when
-+ * the process exits, via the processExited hook.
-+ *
-+ * This is tricky because we do not want the user-level InputStream to be
-+ * closed until the user invokes close(), and we need to continue to be
-+ * able to read any buffered data lingering in the OS pipe buffer.
-+ */
-+ static class ProcessPipeInputStream extends BufferedInputStream {
-+ private final Object closeLock = new Object();
-+
-+ ProcessPipeInputStream(int fd) {
-+ super(new FileInputStream(newFileDescriptor(fd)));
-+ }
-+ private static byte[] drainInputStream(InputStream in)
-+ throws IOException {
-+ int n = 0;
-+ int j;
-+ byte[] a = null;
-+ while ((j = in.available()) > 0) {
-+ a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
-+ n += in.read(a, n, j);
-+ }
-+ return (a == null || n == a.length) ? a : Arrays.copyOf(a, n);
-+ }
-+
-+ /** Called by the process reaper thread when the process exits. */
-+ synchronized void processExited() {
-+ synchronized (closeLock) {
-+ try {
-+ InputStream in = this.in;
-+ // this stream is closed if and only if: in == null
-+ if (in != null) {
-+ byte[] stragglers = drainInputStream(in);
-+ in.close();
-+ this.in = (stragglers == null) ?
-+ ProcessBuilder.NullInputStream.INSTANCE :
-+ new ByteArrayInputStream(stragglers);
-+ }
-+ } catch (IOException ignored) {}
-+ }
-+ }
-+
-+ @Override
-+ public void close() throws IOException {
-+ // BufferedInputStream#close() is not synchronized unlike most other methods.
-+ // Synchronizing helps avoid race with processExited().
-+ synchronized (closeLock) {
-+ super.close();
-+ }
-+ }
-+ }
-+
-+ /**
-+ * A buffered output stream for a subprocess pipe file descriptor
-+ * that allows the underlying file descriptor to be reclaimed when
-+ * the process exits, via the processExited hook.
-+ */
-+ static class ProcessPipeOutputStream extends BufferedOutputStream {
-+ ProcessPipeOutputStream(int fd) {
-+ super(new FileOutputStream(newFileDescriptor(fd)));
-+ }
-+
-+ /** Called by the process reaper thread when the process exits. */
-+ synchronized void processExited() {
-+ OutputStream out = this.out;
-+ if (out != null) {
-+ try {
-+ out.close();
-+ } catch (IOException ignored) {
-+ // We know of no reason to get an IOException, but if
-+ // we do, there's nothing else to do but carry on.
-+ }
-+ this.out = ProcessBuilder.NullOutputStream.INSTANCE;
-+ }
-+ }
-+ }
-+}
---- ./jdk/src/solaris/classes/sun/awt/X11FontManager.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/classes/sun/awt/X11FontManager.java Sun Feb 01 21:05:04 2015 -0800
-@@ -213,7 +213,7 @@
+--- ./jdk/src/solaris/classes/java/lang/UNIXProcess.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/classes/java/lang/UNIXProcess.java Sat Mar 14 22:56:25 2015 -0700
+@@ -82,6 +82,8 @@
+
+ LINUX(LaunchMechanism.VFORK, LaunchMechanism.FORK),
+
++ MACOS(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK),
++
+ BSD(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK),
+
+ SOLARIS(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK),
+@@ -105,9 +107,10 @@
+ // fall through...
+ case LINUX:
+ case AIX:
++ case BSD:
+ return javahome + "/lib/" + osArch + "/jspawnhelper";
+
+- case BSD:
++ case MACOS:
+ return javahome + "/lib/jspawnhelper";
+
+ default:
+@@ -157,7 +160,8 @@
+ );
+
+ if (osName.equals("Linux")) { return LINUX; }
+- if (osName.contains("OS X")) { return BSD; }
++ if (osName.contains("OS X")) { return MACOS; }
++ if (osName.endsWith("BSD")) { return BSD; }
+ if (osName.equals("SunOS")) { return SOLARIS; }
+ if (osName.equals("AIX")) { return AIX; }
+
+@@ -273,6 +277,7 @@
+ void initStreams(int[] fds) throws IOException {
+ switch (platform) {
+ case LINUX:
++ case MACOS:
+ case BSD:
+ stdin = (fds[0] == -1) ?
+ ProcessBuilder.NullOutputStream.INSTANCE :
+@@ -428,6 +433,7 @@
+ private void destroy(boolean force) {
+ switch (platform) {
+ case LINUX:
++ case MACOS:
+ case BSD:
+ case AIX:
+ // There is a risk that pid will be recycled, causing us to
+--- ./jdk/src/solaris/classes/sun/awt/X11FontManager.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/classes/sun/awt/X11FontManager.java Sat Mar 14 22:56:25 2015 -0700
+@@ -236,7 +236,7 @@
if (fontID != null) {
fileName = (String)fontNameMap.get(fontID);
/* On Linux check for the Lucida Oblique fonts */
@@ -12175,7 +11918,7 @@
if (oblmap == null) {
initObliqueLucidaFontMap();
}
-@@ -712,7 +712,7 @@
+@@ -735,7 +735,7 @@
if (fontConfigDirs == null) {
return;
}
@@ -12184,7 +11927,7 @@
fontConfigDirs.add(jreLibDirName+File.separator+"oblique-fonts");
}
fontdirs = (String[])fontConfigDirs.toArray(new String[0]);
-@@ -740,7 +740,7 @@
+@@ -763,7 +763,7 @@
*/
FontConfiguration mFontConfig = new MFontConfiguration(this);
if (FontUtilities.isOpenSolaris ||
@@ -12193,8 +11936,8 @@
(!mFontConfig.foundOsSpecificFile() ||
!mFontConfig.fontFilesArePresent()) ||
(FontUtilities.isSolaris && !mFontConfig.fontFilesArePresent()))) {
---- ./jdk/src/solaris/classes/sun/awt/fontconfigs/bsd.fontconfig.properties Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/classes/sun/awt/fontconfigs/bsd.fontconfig.properties Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/classes/sun/awt/fontconfigs/bsd.fontconfig.properties Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/classes/sun/awt/fontconfigs/bsd.fontconfig.properties Sat Mar 14 22:56:25 2015 -0700
@@ -26,134 +26,134 @@
# Version
@@ -12457,8 +12200,8 @@
+filename.NanumGothic_Bold=/usr/local/lib/X11/fonts/nanum-ttf/NanumGothicBold.ttf
+filename.NanumMyeongjo=/usr/local/lib/X11/fonts/nanum-ttf/NanumMyeongjo.ttf
+filename.NanumMyeongjo_Bold=/usr/local/lib/X11/fonts/nanum-ttf/NanumMyeongjoBold.ttf
---- ./jdk/src/solaris/classes/sun/net/PortConfig.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/classes/sun/net/PortConfig.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/classes/sun/net/PortConfig.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/classes/sun/net/PortConfig.java Sat Mar 14 22:56:25 2015 -0700
@@ -52,7 +52,7 @@
} else if (os.startsWith("SunOS")) {
defaultLower = 32768;
@@ -12468,8 +12211,8 @@
defaultLower = 49152;
defaultUpper = 65535;
} else if (os.startsWith("AIX")) {
---- ./jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java Sat Mar 14 22:56:25 2015 -0700
@@ -66,7 +66,7 @@
return createProvider("sun.nio.ch.SolarisAsynchronousChannelProvider");
if (osname.equals("Linux"))
@@ -12479,8 +12222,8 @@
return createProvider("sun.nio.ch.BsdAsynchronousChannelProvider");
if (osname.equals("AIX"))
return createProvider("sun.nio.ch.AixAsynchronousChannelProvider");
---- ./jdk/src/solaris/classes/sun/nio/fs/BsdFileSystemProvider.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/classes/sun/nio/fs/BsdFileSystemProvider.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/classes/sun/nio/fs/BsdFileSystemProvider.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/classes/sun/nio/fs/BsdFileSystemProvider.java Sat Mar 14 22:56:25 2015 -0700
@@ -25,10 +25,14 @@
package sun.nio.fs;
@@ -12514,8 +12257,8 @@
+ new MagicFileTypeDetector());
+ }
}
---- ./jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java Sat Mar 14 22:56:25 2015 -0700
@@ -61,6 +61,8 @@
return createProvider("sun.nio.fs.SolarisFileSystemProvider");
if (osname.equals("Linux"))
@@ -12525,8 +12268,8 @@
if (osname.contains("OS X"))
return createProvider("sun.nio.fs.MacOSXFileSystemProvider");
if (osname.equals("AIX"))
---- ./jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Sat Mar 14 22:56:25 2015 -0700
@@ -161,6 +161,7 @@
static boolean isBSD() {
@@ -12550,9 +12293,9 @@
"/usr/sbin/lpc status all | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}' | sort"
};
---- ./jdk/src/solaris/classes/sun/tools/attach/BsdVirtualMachine.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/classes/sun/tools/attach/BsdVirtualMachine.java Sun Feb 01 21:05:04 2015 -0800
-@@ -266,7 +266,7 @@
+--- ./jdk/src/solaris/classes/sun/tools/attach/BsdVirtualMachine.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/classes/sun/tools/attach/BsdVirtualMachine.java Sat Mar 14 22:56:25 2015 -0700
+@@ -273,7 +273,7 @@
try {
b = s.getBytes("UTF-8");
} catch (java.io.UnsupportedEncodingException x) {
@@ -12561,8 +12304,8 @@
}
BsdVirtualMachine.write(fd, b, 0, b.length);
}
---- ./jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_SolarisOS_PCM.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_SolarisOS_PCM.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_SolarisOS_PCM.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_SolarisOS_PCM.c Sat Mar 14 22:56:25 2015 -0700
@@ -140,7 +140,7 @@
(float) ((int) sr->samp_rates[s]),
DAUDIO_PCM, /* encoding - let's only do PCM */
@@ -12572,8 +12315,8 @@
FALSE /* little endian */
#else
(bits[b] > 8)?TRUE:FALSE /* big endian */
---- ./jdk/src/solaris/native/common/jni_util_md.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/common/jni_util_md.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/common/jni_util_md.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/common/jni_util_md.c Sat Mar 14 22:56:25 2015 -0700
@@ -28,6 +28,7 @@
#include "jni.h"
#include "jni_util.h"
@@ -12582,8 +12325,8 @@
jstring nativeNewStringPlatform(JNIEnv *env, const char *str) {
return NULL;
---- ./jdk/src/solaris/native/java/lang/java_props_md.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/java/lang/java_props_md.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/java/lang/java_props_md.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/java/lang/java_props_md.c Sat Mar 14 22:56:25 2015 -0700
@@ -151,7 +151,7 @@
lc = setlocale(cat, NULL);
#endif
@@ -12618,8 +12361,8 @@
/* user properties */
{
---- ./jdk/src/solaris/native/java/net/Inet4AddressImpl.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/java/net/Inet4AddressImpl.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/java/net/Inet4AddressImpl.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/java/net/Inet4AddressImpl.c Sat Mar 14 22:56:25 2015 -0700
@@ -36,20 +36,13 @@
#include <stdlib.h>
#include <ctype.h>
@@ -12938,8 +12681,8 @@
#define SET_NONBLOCKING(fd) { \
int flags = fcntl(fd, F_GETFL); \
flags |= O_NONBLOCK; \
---- ./jdk/src/solaris/native/java/net/Inet6AddressImpl.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/java/net/Inet6AddressImpl.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/java/net/Inet6AddressImpl.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/java/net/Inet6AddressImpl.c Sat Mar 14 22:56:25 2015 -0700
@@ -33,7 +33,7 @@
#include <strings.h>
#include <stdlib.h>
@@ -12970,8 +12713,8 @@
/*
* If we're looking up the local machine, attempt to get the address
* from getifaddrs. This ensures we get an IPv6 address for the local
---- ./jdk/src/solaris/native/java/net/NetworkInterface.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/java/net/NetworkInterface.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/java/net/NetworkInterface.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/java/net/NetworkInterface.c Sat Mar 14 22:56:25 2015 -0700
@@ -67,14 +67,18 @@
#include <sys/param.h>
#include <sys/ioctl.h>
@@ -12993,8 +12736,8 @@
#include "jvm.h"
#include "jni_util.h"
---- ./jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c Sat Mar 14 22:56:25 2015 -0700
@@ -2200,7 +2200,7 @@
}
}
@@ -13004,8 +12747,24 @@
if (family == AF_INET6 && index == 0) {
index = getDefaultScopeID(env);
}
---- ./jdk/src/solaris/native/java/net/net_util_md.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/java/net/net_util_md.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/java/net/bsd_close.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/java/net/bsd_close.c Sat Mar 14 22:56:25 2015 -0700
+@@ -316,11 +316,8 @@
+ }
+
+ int NET_Accept(int s, struct sockaddr *addr, int *addrlen) {
+- socklen_t len = *addrlen;
+- int error = accept(s, addr, &len);
+- if (error != -1)
+- *addrlen = (int)len;
+- BLOCKING_IO_RETURN_INT( s, error );
++ /* See NET_RecvFrom() */
++ BLOCKING_IO_RETURN_INT( s, accept(s, addr, (socklen_t *)addrlen) );
+ }
+
+ int NET_Connect(int s, struct sockaddr *addr, int addrlen) {
+--- ./jdk/src/solaris/native/java/net/net_util_md.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/java/net/net_util_md.c Sat Mar 14 22:56:25 2015 -0700
@@ -87,7 +87,7 @@
void setDefaultScopeID(JNIEnv *env, struct sockaddr *him)
@@ -13015,8 +12774,8 @@
static jclass ni_class = NULL;
static jfieldID ni_defaultIndexID;
if (ni_class == NULL) {
---- ./jdk/src/solaris/native/java/net/net_util_md.h Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/java/net/net_util_md.h Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/java/net/net_util_md.h Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/java/net/net_util_md.h Sat Mar 14 22:56:25 2015 -0700
@@ -47,7 +47,7 @@
close subroutine does not return until the select call returns.
...
@@ -13026,8 +12785,8 @@
extern int NET_Timeout(int s, long timeout);
extern int NET_Read(int s, void* buf, size_t len);
extern int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
---- ./jdk/src/solaris/native/java/util/TimeZone_md.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/java/util/TimeZone_md.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/java/util/TimeZone_md.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/java/util/TimeZone_md.c Sat Mar 14 22:56:25 2015 -0700
@@ -52,7 +52,11 @@
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
@@ -13112,8 +12871,8 @@
}
#endif
-
---- ./jdk/src/solaris/native/sun/awt/awt_Font.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/sun/awt/awt_Font.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/sun/awt/awt_Font.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/sun/awt/awt_Font.c Sat Mar 14 22:56:25 2015 -0700
@@ -255,7 +255,7 @@
if (strcmp(style, "regular") == 0) {
altstyle = "roman";
@@ -13123,8 +12882,8 @@
if (!strcmp(family, "lucidasans")) {
family = "lucida";
}
---- ./jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c Sat Mar 14 22:56:25 2015 -0700
@@ -120,7 +120,7 @@
*/
@@ -13191,7 +12950,7 @@
}
#endif /* HEADLESS */
-@@ -1592,7 +1587,7 @@
+@@ -1594,7 +1589,7 @@
{
jobject point = NULL;
#ifndef HEADLESS /* return NULL in HEADLESS, Linux */
@@ -13200,7 +12959,7 @@
int x,y;
AWT_LOCK();
-@@ -1605,7 +1600,7 @@
+@@ -1607,7 +1602,7 @@
DTRACE_PRINTLN("unable to call XineramaSolarisCenterFunc: symbol is null");
}
AWT_FLUSH_UNLOCK();
@@ -13209,8 +12968,8 @@
#endif /* HEADLESS */
return point;
}
---- ./jdk/src/solaris/native/sun/awt/awt_InputMethod.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/sun/awt/awt_InputMethod.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/sun/awt/awt_InputMethod.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/sun/awt/awt_InputMethod.c Sat Mar 14 22:56:25 2015 -0700
@@ -52,7 +52,7 @@
XIMPreeditDrawCallbackStruct *);
static void PreeditCaretCallback(XIC, XPointer,
@@ -13430,8 +13189,8 @@
AWT_LOCK();
adjustStatusWindow(window);
AWT_UNLOCK();
---- ./jdk/src/solaris/native/sun/awt/awt_Robot.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/sun/awt/awt_Robot.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/sun/awt/awt_Robot.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/sun/awt/awt_Robot.c Sat Mar 14 22:56:25 2015 -0700
@@ -45,7 +45,7 @@
#include "wsutils.h"
#include "list.h"
@@ -13441,8 +13200,8 @@
#include <sys/socket.h>
#endif
---- ./jdk/src/solaris/native/sun/awt/extutil.h Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/sun/awt/extutil.h Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/sun/awt/extutil.h Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/sun/awt/extutil.h Sat Mar 14 22:56:25 2015 -0700
@@ -58,7 +58,7 @@
*/
/* $XFree86: xc/include/extensions/extutil.h,v 1.5 2001/01/17 17:53:20 dawes Exp $ */
@@ -13458,8 +13217,8 @@
-#endif /* __linux__ || MACOSX */
+#endif /* __linux__ || _ALLBSD_SOURCE */
---- ./jdk/src/solaris/native/sun/awt/fontpath.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/sun/awt/fontpath.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/sun/awt/fontpath.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/sun/awt/fontpath.c Sat Mar 14 22:56:25 2015 -0700
@@ -23,9 +23,9 @@
* questions.
*/
@@ -13548,8 +13307,8 @@
&& (strcmp((char*)fontformat, "Type 1") != 0)
#endif
) {
---- ./jdk/src/solaris/native/sun/java2d/j2d_md.h Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/sun/java2d/j2d_md.h Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/sun/java2d/j2d_md.h Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/sun/java2d/j2d_md.h Sat Mar 14 22:56:25 2015 -0700
@@ -28,11 +28,11 @@
#include <sys/types.h>
@@ -13565,8 +13324,8 @@
typedef unsigned char jubyte;
typedef unsigned short jushort;
---- ./jdk/src/solaris/native/sun/java2d/loops/mlib_ImageZoom_NN.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/sun/java2d/loops/mlib_ImageZoom_NN.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/sun/java2d/loops/mlib_ImageZoom_NN.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/sun/java2d/loops/mlib_ImageZoom_NN.c Sat Mar 14 22:56:25 2015 -0700
@@ -63,9 +63,6 @@
* MLIB_EDGE_SRC_PADDED
*/
@@ -13671,8 +13430,8 @@
LOGIC(da[0], dtmp, dtmp1, |);
}
else { /* aligned */
---- ./jdk/src/solaris/native/sun/java2d/loops/vis_FuncArray.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/sun/java2d/loops/vis_FuncArray.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/sun/java2d/loops/vis_FuncArray.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/sun/java2d/loops/vis_FuncArray.c Sat Mar 14 22:56:25 2015 -0700
@@ -804,7 +804,7 @@
static int initialized;
static int usevis = JNI_TRUE;
@@ -13682,8 +13441,8 @@
# define ULTRA_CHIP "sparc64"
#else
# define ULTRA_CHIP "sun4u"
---- ./jdk/src/solaris/native/sun/management/OperatingSystemImpl.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/sun/management/OperatingSystemImpl.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/sun/management/OperatingSystemImpl.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/sun/management/OperatingSystemImpl.c Sat Mar 14 22:56:25 2015 -0700
@@ -56,6 +56,9 @@
#include <limits.h>
#include <stdlib.h>
@@ -13838,8 +13597,8 @@
return -1;
}
---- ./jdk/src/solaris/native/sun/nio/ch/sctp/Sctp.h Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/sun/nio/ch/sctp/Sctp.h Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/sun/nio/ch/sctp/Sctp.h Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/sun/nio/ch/sctp/Sctp.h Sat Mar 14 22:56:25 2015 -0700
@@ -67,7 +67,7 @@
@@ -13888,8 +13647,8 @@
jboolean loadSocketExtensionFuncs(JNIEnv* env);
#endif /* !SUN_NIO_CH_SCTP_H */
---- ./jdk/src/solaris/native/sun/nio/ch/sctp/SctpNet.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/sun/nio/ch/sctp/SctpNet.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/sun/nio/ch/sctp/SctpNet.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/sun/nio/ch/sctp/SctpNet.c Sat Mar 14 22:56:25 2015 -0700
@@ -58,6 +58,7 @@
*/
jboolean loadSocketExtensionFuncs
@@ -13906,8 +13665,8 @@
funcsLoaded = JNI_TRUE;
return JNI_TRUE;
---- ./jdk/src/solaris/native/sun/nio/fs/MagicFileTypeDetector.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/sun/nio/fs/MagicFileTypeDetector.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/sun/nio/fs/MagicFileTypeDetector.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/sun/nio/fs/MagicFileTypeDetector.c Sat Mar 14 22:56:25 2015 -0700
@@ -31,6 +31,12 @@
#include <dlfcn.h>
#include <string.h>
@@ -13930,8 +13689,8 @@
if (magic_handle == NULL) {
return JNI_FALSE;
}
---- ./jdk/src/solaris/native/sun/tools/attach/BsdVirtualMachine.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/sun/tools/attach/BsdVirtualMachine.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/sun/tools/attach/BsdVirtualMachine.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/sun/tools/attach/BsdVirtualMachine.c Sat Mar 14 22:56:25 2015 -0700
@@ -37,7 +37,9 @@
#include <sys/types.h>
#include <sys/socket.h>
@@ -13942,8 +13701,8 @@
#include <sys/un.h>
#include <fcntl.h>
---- ./jdk/src/solaris/native/sun/xawt/XWindow.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/solaris/native/sun/xawt/XWindow.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/solaris/native/sun/xawt/XWindow.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/solaris/native/sun/xawt/XWindow.c Sat Mar 14 22:56:25 2015 -0700
@@ -886,7 +886,7 @@
{
KeySym originalKeysym = *keysym;
@@ -13953,8 +13712,8 @@
/* The following code on Linux will cause the keypad keys
* not to echo on JTextField when the NumLock is on. The
* keysyms will be 0, because the last parameter 2 is not defined.
---- ./jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_DirectSound.cpp Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_DirectSound.cpp Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_DirectSound.cpp Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_DirectSound.cpp Sat Mar 14 22:56:25 2015 -0700
@@ -308,7 +308,7 @@
DAUDIO_PCM,
(bitsArray[bitIndex]==8)?FALSE:TRUE, /* signed */
diff --git a/java/openjdk8/files/patch-bsd-test b/java/openjdk8/files/patch-bsd-test
index afd2c3f26238..b973833664b6 100644
--- a/java/openjdk8/files/patch-bsd-test
+++ b/java/openjdk8/files/patch-bsd-test
@@ -1,5 +1,5 @@
---- ./hotspot/test/compiler/5091921/Test7005594.sh Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/test/compiler/5091921/Test7005594.sh Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/test/compiler/5091921/Test7005594.sh Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/test/compiler/5091921/Test7005594.sh Sat Mar 14 16:41:08 2015 -0700
@@ -60,6 +60,15 @@
# Windows/MKS
MEM=`"$ROOTDIR/mksnt/sysinf" memory -v | grep "Total Physical Memory: " | sed 's/Total Physical Memory: *//g'`
@@ -16,8 +16,8 @@
else
echo "Unable to determine amount of physical memory on the machine"
fi
---- ./hotspot/test/compiler/6894807/Test6894807.sh Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/test/compiler/6894807/Test6894807.sh Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/test/compiler/6894807/Test6894807.sh Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/test/compiler/6894807/Test6894807.sh Sat Mar 14 16:41:08 2015 -0700
@@ -21,7 +21,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -27,8 +27,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./hotspot/test/runtime/7110720/Test7110720.sh Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/test/runtime/7110720/Test7110720.sh Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/test/runtime/7110720/Test7110720.sh Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/test/runtime/7110720/Test7110720.sh Sat Mar 14 16:41:08 2015 -0700
@@ -28,7 +28,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -38,8 +38,8 @@
FS="/"
RM=/bin/rm
CP=/bin/cp
---- ./hotspot/test/runtime/XCheckJniJsig/XCheckJSig.java Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/test/runtime/XCheckJniJsig/XCheckJSig.java Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/test/runtime/XCheckJniJsig/XCheckJSig.java Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/test/runtime/XCheckJniJsig/XCheckJSig.java Sat Mar 14 16:41:08 2015 -0700
@@ -37,8 +37,8 @@
public static void main(String args[]) throws Throwable {
@@ -51,8 +51,8 @@
return;
}
---- ./hotspot/test/test_env.sh Tue Dec 02 11:10:51 2014 -0800
-+++ ./hotspot/test/test_env.sh Sun Feb 01 21:04:50 2015 -0800
+--- ./hotspot/test/test_env.sh Fri Jan 30 15:14:31 2015 -0800
++++ ./hotspot/test/test_env.sh Sat Mar 14 16:41:08 2015 -0700
@@ -53,7 +53,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -62,8 +62,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/com/sun/corba/5036554/TestCorbaBug.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/com/sun/corba/5036554/TestCorbaBug.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/com/sun/corba/5036554/TestCorbaBug.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/com/sun/corba/5036554/TestCorbaBug.sh Sat Mar 14 22:56:25 2015 -0700
@@ -48,7 +48,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -73,8 +73,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/com/sun/corba/cachedSocket/7056731.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/com/sun/corba/cachedSocket/7056731.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/com/sun/corba/cachedSocket/7056731.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/com/sun/corba/cachedSocket/7056731.sh Sat Mar 14 22:56:25 2015 -0700
@@ -31,7 +31,7 @@
OS=`uname -s`
@@ -84,8 +84,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/com/sun/jdi/ImmutableResourceTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/com/sun/jdi/ImmutableResourceTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/com/sun/jdi/ImmutableResourceTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/com/sun/jdi/ImmutableResourceTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -56,7 +56,7 @@
OS=`uname -s`
@@ -95,8 +95,8 @@
PATHSEP=":"
;;
---- ./jdk/test/com/sun/jdi/JITDebug.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/com/sun/jdi/JITDebug.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/com/sun/jdi/JITDebug.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/com/sun/jdi/JITDebug.sh Sat Mar 14 22:56:25 2015 -0700
@@ -63,7 +63,7 @@
OS=`uname -s`
export TRANSPORT_METHOD
@@ -106,8 +106,8 @@
PATHSEP=":"
TRANSPORT_METHOD=dt_socket
;;
---- ./jdk/test/com/sun/jdi/PrivateTransportTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/com/sun/jdi/PrivateTransportTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/com/sun/jdi/PrivateTransportTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/com/sun/jdi/PrivateTransportTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -106,7 +106,7 @@
xx=`find ${jreloc}/lib -name libdt_socket.so`
libloc=`dirname ${xx}`
@@ -117,8 +117,8 @@
libloc=${jreloc}/lib
;;
Windows*)
---- ./jdk/test/com/sun/jdi/ShellScaffold.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/com/sun/jdi/ShellScaffold.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/com/sun/jdi/ShellScaffold.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/com/sun/jdi/ShellScaffold.sh Sat Mar 14 22:56:25 2015 -0700
@@ -295,7 +295,7 @@
psCmd=ps
jstack=jstack.exe
@@ -128,8 +128,8 @@
transport=dt_socket
address=
devnull=/dev/null
---- ./jdk/test/com/sun/jdi/connect/spi/JdiLoadedByCustomLoader.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/com/sun/jdi/connect/spi/JdiLoadedByCustomLoader.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/com/sun/jdi/connect/spi/JdiLoadedByCustomLoader.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/com/sun/jdi/connect/spi/JdiLoadedByCustomLoader.sh Sat Mar 14 22:56:25 2015 -0700
@@ -45,7 +45,7 @@
OS=`uname -s`
@@ -139,8 +139,8 @@
PS=":"
;;
Windows* | CYGWIN*)
---- ./jdk/test/java/awt/JAWT/JAWT.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/awt/JAWT/JAWT.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/awt/JAWT/JAWT.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/awt/JAWT/JAWT.sh Sat Mar 14 22:56:25 2015 -0700
@@ -62,6 +62,23 @@
MAKE="make"
LD_LIBRARY_PATH="."
@@ -174,8 +174,8 @@
exit 0;
;;
* )
---- ./jdk/test/java/awt/Toolkit/AutoShutdown/ShowExitTest/ShowExitTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/awt/Toolkit/AutoShutdown/ShowExitTest/ShowExitTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/awt/Toolkit/AutoShutdown/ShowExitTest/ShowExitTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/awt/Toolkit/AutoShutdown/ShowExitTest/ShowExitTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -86,6 +86,14 @@
TMP="/tmp"
;;
@@ -191,8 +191,8 @@
Windows* )
VAR="A different value for Win32"
DEFAULT_JDK="C:/Program Files/Java/jdk1.8.0"
---- ./jdk/test/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -59,7 +59,7 @@
# Checking for proper OS
OS=`uname -s`
@@ -202,8 +202,8 @@
FILESEP="/"
;;
---- ./jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -119,6 +119,14 @@
TMP="/tmp"
;;
@@ -219,8 +219,8 @@
Windows* )
VAR="A different value for Win32"
DEFAULT_JDK="C:/Program Files/Java/jdk1.8.0"
---- ./jdk/test/java/io/File/GetXSpace.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/io/File/GetXSpace.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/io/File/GetXSpace.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/io/File/GetXSpace.java Sat Mar 14 22:56:25 2015 -0700
@@ -51,7 +51,7 @@
private static final String dfFormat;
static {
@@ -230,8 +230,8 @@
// FileSystem Total Used Available Use% MountedOn
dfFormat = "([^\\s]+)\\s+(\\d+)\\s+\\d+\\s+(\\d+)\\s+\\d+%\\s+([^\\s]+)";
} else if (name.startsWith("Windows")) {
---- ./jdk/test/java/io/File/GetXSpace.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/io/File/GetXSpace.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/io/File/GetXSpace.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/io/File/GetXSpace.sh Sat Mar 14 22:56:25 2015 -0700
@@ -26,7 +26,7 @@
# set platform-dependent variable
OS=`uname -s`
@@ -241,8 +241,8 @@
Windows_98 ) return ;;
Windows* ) SID=`sid`; TMP="c:/temp" ;;
* )
---- ./jdk/test/java/io/Serializable/evolution/RenamePackage/run.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/io/Serializable/evolution/RenamePackage/run.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/io/Serializable/evolution/RenamePackage/run.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/io/Serializable/evolution/RenamePackage/run.sh Sat Mar 14 22:56:25 2015 -0700
@@ -45,7 +45,7 @@
# Need to determine the classpath separator and filepath separator based on the
# operating system.
@@ -252,8 +252,8 @@
PS=":" ;;
Windows* | CYGWIN* )
PS=";" ;;
---- ./jdk/test/java/io/Serializable/serialver/classpath/run.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/io/Serializable/serialver/classpath/run.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/io/Serializable/serialver/classpath/run.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/io/Serializable/serialver/classpath/run.sh Sat Mar 14 22:56:25 2015 -0700
@@ -47,7 +47,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -263,8 +263,8 @@
PS=":" ;;
Windows* | CYGWIN* )
PS=";" ;;
---- ./jdk/test/java/io/Serializable/serialver/nested/run.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/io/Serializable/serialver/nested/run.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/io/Serializable/serialver/nested/run.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/io/Serializable/serialver/nested/run.sh Sat Mar 14 22:56:25 2015 -0700
@@ -47,7 +47,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -274,8 +274,8 @@
PS=":" ;;
Windows* | CYGWIN* )
PS=";" ;;
---- ./jdk/test/java/lang/ClassLoader/Assert.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/lang/ClassLoader/Assert.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/lang/ClassLoader/Assert.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/lang/ClassLoader/Assert.sh Sat Mar 14 22:56:25 2015 -0700
@@ -25,7 +25,7 @@
OS=`uname -s`
@@ -285,8 +285,8 @@
FS="/"
CHMOD="${FS}bin${FS}chmod"
;;
---- ./jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh Sat Mar 14 22:56:25 2015 -0700
@@ -55,7 +55,7 @@
Linux )
FS="/"
@@ -296,8 +296,8 @@
FS="/"
;;
AIX )
---- ./jdk/test/java/lang/ClassLoader/deadlock/TestOneWayDelegate.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/lang/ClassLoader/deadlock/TestOneWayDelegate.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/lang/ClassLoader/deadlock/TestOneWayDelegate.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/lang/ClassLoader/deadlock/TestOneWayDelegate.sh Sat Mar 14 22:56:25 2015 -0700
@@ -60,7 +60,7 @@
Linux )
FS="/"
@@ -307,8 +307,8 @@
FS="/"
;;
AIX )
---- ./jdk/test/java/lang/ProcessBuilder/DestroyTest.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/lang/ProcessBuilder/DestroyTest.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/lang/ProcessBuilder/DestroyTest.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/lang/ProcessBuilder/DestroyTest.java Sat Mar 14 22:56:25 2015 -0700
@@ -148,6 +148,9 @@
} else if (osName.startsWith("Linux") == true) {
return new UnixTest(
@@ -319,8 +319,8 @@
} else if (osName.startsWith("Mac OS")) {
return new MacTest(
File.createTempFile("ProcessTrap-", ".sh",null));
---- ./jdk/test/java/lang/ProcessBuilder/Zombies.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/lang/ProcessBuilder/Zombies.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/lang/ProcessBuilder/Zombies.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/lang/ProcessBuilder/Zombies.java Sat Mar 14 22:56:25 2015 -0700
@@ -34,7 +34,7 @@
static final String os = System.getProperty("os.name");
@@ -330,8 +330,8 @@
"/usr/bin/true" : "/bin/true";
public static void main(String[] args) throws Throwable {
---- ./jdk/test/java/lang/StringCoding/CheckEncodings.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/lang/StringCoding/CheckEncodings.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/lang/StringCoding/CheckEncodings.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/lang/StringCoding/CheckEncodings.sh Sat Mar 14 22:56:25 2015 -0700
@@ -30,7 +30,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -341,8 +341,8 @@
Windows* | CYGWIN* )
echo "Passed"; exit 0 ;;
* ) echo "Unrecognized system!" ; exit 1 ;;
---- ./jdk/test/java/lang/annotation/loaderLeak/LoaderLeak.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/lang/annotation/loaderLeak/LoaderLeak.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/lang/annotation/loaderLeak/LoaderLeak.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/lang/annotation/loaderLeak/LoaderLeak.sh Sat Mar 14 22:56:25 2015 -0700
@@ -48,7 +48,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -352,8 +352,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/java/lang/instrument/MakeJAR2.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/lang/instrument/MakeJAR2.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/lang/instrument/MakeJAR2.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/lang/instrument/MakeJAR2.sh Sat Mar 14 22:56:25 2015 -0700
@@ -55,7 +55,7 @@
OS=`uname -s`
@@ -363,8 +363,8 @@
PATHSEP=":"
;;
---- ./jdk/test/java/lang/instrument/appendToClassLoaderSearch/CommonSetup.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/lang/instrument/appendToClassLoaderSearch/CommonSetup.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/lang/instrument/appendToClassLoaderSearch/CommonSetup.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/lang/instrument/appendToClassLoaderSearch/CommonSetup.sh Sat Mar 14 22:56:25 2015 -0700
@@ -43,7 +43,7 @@
PS=":"
FS="/"
@@ -374,8 +374,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/lang/management/OperatingSystemMXBean/GetSystemLoadAverage.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/lang/management/OperatingSystemMXBean/GetSystemLoadAverage.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/lang/management/OperatingSystemMXBean/GetSystemLoadAverage.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/lang/management/OperatingSystemMXBean/GetSystemLoadAverage.java Sat Mar 14 22:56:25 2015 -0700
@@ -79,8 +79,10 @@
System.out.println("Test passed.");
}
@@ -397,8 +397,8 @@
? output.split(" ")
: output.split(",");
double expected = Double.parseDouble(lavg[0]);
---- ./jdk/test/java/lang/management/OperatingSystemMXBean/TestSystemLoadAvg.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/lang/management/OperatingSystemMXBean/TestSystemLoadAvg.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/lang/management/OperatingSystemMXBean/TestSystemLoadAvg.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/lang/management/OperatingSystemMXBean/TestSystemLoadAvg.sh Sat Mar 14 22:56:25 2015 -0700
@@ -61,7 +61,7 @@
while true; do
echo "Run $i: TestSystemLoadAvg"
@@ -408,8 +408,8 @@
runOne GetSystemLoadAverage
;;
* )
---- ./jdk/test/java/net/Authenticator/B4933582.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/net/Authenticator/B4933582.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/net/Authenticator/B4933582.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/net/Authenticator/B4933582.sh Sat Mar 14 22:56:25 2015 -0700
@@ -26,7 +26,7 @@
OS=`uname -s`
@@ -419,8 +419,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/net/DatagramSocket/Send12k.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/net/DatagramSocket/Send12k.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/net/DatagramSocket/Send12k.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/net/DatagramSocket/Send12k.java Sat Mar 14 22:56:25 2015 -0700
@@ -36,9 +36,10 @@
public static void main(String args[]) throws Exception {
@@ -434,8 +434,8 @@
SEND_SIZE = 16 * 576;
} else {
SEND_SIZE = 16 * 1024;
---- ./jdk/test/java/net/DatagramSocket/SendDatagramToBadAddress.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/net/DatagramSocket/SendDatagramToBadAddress.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/net/DatagramSocket/SendDatagramToBadAddress.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/net/DatagramSocket/SendDatagramToBadAddress.java Sat Mar 14 22:56:25 2015 -0700
@@ -45,6 +45,8 @@
return (true);
if (p.getProperty ("os.name").equals ("Linux"))
@@ -445,8 +445,8 @@
if (p.getProperty ("os.name").startsWith ("Mac OS"))
return (true);
// Check for specific Solaris version from here
---- ./jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh Sat Mar 14 22:56:25 2015 -0700
@@ -27,11 +27,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -460,8 +460,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/java/net/Socket/OldSocketImpl.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/net/Socket/OldSocketImpl.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/net/Socket/OldSocketImpl.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/net/Socket/OldSocketImpl.sh Sat Mar 14 22:56:25 2015 -0700
@@ -28,7 +28,7 @@
OS=`uname -s`
@@ -471,8 +471,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/net/URL/B5086147.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/net/URL/B5086147.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/net/URL/B5086147.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/net/URL/B5086147.sh Sat Mar 14 22:56:25 2015 -0700
@@ -26,7 +26,7 @@
OS=`uname -s`
@@ -482,8 +482,8 @@
exit 0
;;
CYGWIN* )
---- ./jdk/test/java/net/URLClassLoader/B5077773.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/net/URLClassLoader/B5077773.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/net/URLClassLoader/B5077773.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/net/URLClassLoader/B5077773.sh Sat Mar 14 22:56:25 2015 -0700
@@ -34,11 +34,7 @@
OS=`uname -s`
@@ -497,8 +497,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/net/URLClassLoader/sealing/checksealed.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/net/URLClassLoader/sealing/checksealed.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/net/URLClassLoader/sealing/checksealed.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/net/URLClassLoader/sealing/checksealed.sh Sat Mar 14 22:56:25 2015 -0700
@@ -27,11 +27,7 @@
OS=`uname -s`
@@ -512,8 +512,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/net/URLConnection/6212146/test.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/net/URLConnection/6212146/test.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/net/URLConnection/6212146/test.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/net/URLConnection/6212146/test.sh Sat Mar 14 22:56:25 2015 -0700
@@ -33,11 +33,7 @@
OS=`uname -s`
@@ -527,8 +527,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/nio/channels/FileChannel/Transfer.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/nio/channels/FileChannel/Transfer.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/nio/channels/FileChannel/Transfer.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/nio/channels/FileChannel/Transfer.java Sat Mar 14 22:56:25 2015 -0700
@@ -228,7 +228,7 @@
// Windows and Linux can't handle the really large file sizes for a
// truncate or a positional write required by the test for 4563125
@@ -538,8 +538,8 @@
return;
File source = File.createTempFile("blah", null);
source.deleteOnExit();
---- ./jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.c Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.c Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.c Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.c Sat Mar 14 22:56:25 2015 -0700
@@ -17,6 +17,12 @@
#include "Launcher.h"
@@ -562,8 +562,8 @@
_exit(-1);
}
---- ./jdk/test/java/nio/charset/coders/CheckSJISMappingProp.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/nio/charset/coders/CheckSJISMappingProp.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/nio/charset/coders/CheckSJISMappingProp.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/nio/charset/coders/CheckSJISMappingProp.sh Sat Mar 14 22:56:25 2015 -0700
@@ -34,7 +34,7 @@
OS=`uname -s`
@@ -573,8 +573,8 @@
# Skip locale test for Windows
Windows* | CYGWIN* )
echo "Passed"; exit 0 ;;
---- ./jdk/test/java/nio/charset/spi/basic.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/nio/charset/spi/basic.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/nio/charset/spi/basic.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/nio/charset/spi/basic.sh Sat Mar 14 22:56:25 2015 -0700
@@ -48,7 +48,7 @@
DIR=`pwd`
@@ -584,8 +584,8 @@
Windows* ) CPS=';' ;;
CYGWIN* )
DIR=`/usr/bin/cygpath -a -s -m $DIR`
---- ./jdk/test/java/nio/file/FileSystem/Basic.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/nio/file/FileSystem/Basic.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/nio/file/FileSystem/Basic.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/nio/file/FileSystem/Basic.java Sat Mar 14 22:56:25 2015 -0700
@@ -76,7 +76,7 @@
checkSupported(fs, "posix", "unix", "owner", "acl", "user");
if (os.equals("Linux"))
@@ -595,8 +595,8 @@
checkSupported(fs, "posix", "unix", "owner");
if (os.equals("Windows"))
checkSupported(fs, "owner", "dos", "acl", "user");
---- ./jdk/test/java/nio/file/Files/CopyAndMove.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/nio/file/Files/CopyAndMove.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/nio/file/Files/CopyAndMove.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/nio/file/Files/CopyAndMove.java Sat Mar 14 22:56:25 2015 -0700
@@ -651,7 +651,7 @@
// check POSIX attributes are copied
@@ -615,8 +615,8 @@
boolean isDirectory = isDirectory(file, NOFOLLOW_LINKS);
if (isUnix) {
---- ./jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh Sat Mar 14 22:56:25 2015 -0700
@@ -33,7 +33,7 @@
OS=`uname -s`
@@ -626,8 +626,8 @@
PS=":"
;;
Windows* | CYGWIN* )
---- ./jdk/test/java/rmi/registry/readTest/readTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/rmi/registry/readTest/readTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/rmi/registry/readTest/readTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/rmi/registry/readTest/readTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -34,7 +34,7 @@
REGARGS=""
@@ -637,8 +637,8 @@
PS=":"
FS="/"
CHMOD="${FS}bin${FS}chmod"
---- ./jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh Sat Mar 14 22:56:25 2015 -0700
@@ -58,7 +58,7 @@
PATHSEP=":"
FILESEP="/"
@@ -648,8 +648,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh Sat Mar 14 22:56:25 2015 -0700
@@ -42,7 +42,7 @@
PATHSEP=":"
FILESEP="/"
@@ -659,8 +659,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock2.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock2.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock2.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock2.sh Sat Mar 14 22:56:25 2015 -0700
@@ -66,7 +66,7 @@
PATHSEP=";"
FILESEP="/"
@@ -670,8 +670,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/java/security/Security/signedfirst/Dyn.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/security/Security/signedfirst/Dyn.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/security/Security/signedfirst/Dyn.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/security/Security/signedfirst/Dyn.sh Sat Mar 14 22:56:25 2015 -0700
@@ -58,7 +58,7 @@
PATHSEP=":"
FILESEP="/"
@@ -681,8 +681,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/java/security/Security/signedfirst/Static.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/security/Security/signedfirst/Static.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/security/Security/signedfirst/Static.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/security/Security/signedfirst/Static.sh Sat Mar 14 22:56:25 2015 -0700
@@ -58,7 +58,7 @@
PATHSEP=":"
FILESEP="/"
@@ -692,8 +692,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/java/util/Currency/PropertiesTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/util/Currency/PropertiesTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/util/Currency/PropertiesTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/util/Currency/PropertiesTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -52,7 +52,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -703,8 +703,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/util/PluggableLocale/ExecTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/util/PluggableLocale/ExecTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/util/PluggableLocale/ExecTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/util/PluggableLocale/ExecTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -62,7 +62,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -714,8 +714,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/util/ResourceBundle/Bug6299235Test.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/util/ResourceBundle/Bug6299235Test.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/util/ResourceBundle/Bug6299235Test.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/util/ResourceBundle/Bug6299235Test.sh Sat Mar 14 22:56:25 2015 -0700
@@ -31,7 +31,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -725,8 +725,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/java/util/ServiceLoader/basic.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/util/ServiceLoader/basic.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/util/ServiceLoader/basic.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/util/ServiceLoader/basic.sh Sat Mar 14 22:56:25 2015 -0700
@@ -43,9 +43,7 @@
OS=`uname -s`
@@ -738,8 +738,8 @@
SEP=':' ;;
* )
SEP='\;' ;;
---- ./jdk/test/java/util/prefs/CheckUserPrefsStorage.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/java/util/prefs/CheckUserPrefsStorage.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/java/util/prefs/CheckUserPrefsStorage.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/java/util/prefs/CheckUserPrefsStorage.sh Sat Mar 14 22:56:25 2015 -0700
@@ -31,7 +31,7 @@
OS=`uname -s`
@@ -749,8 +749,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -56,7 +56,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -760,8 +760,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -89,7 +89,7 @@
FILESEP="/"
;;
@@ -771,8 +771,8 @@
VAR="A different value for Linux"
DEFAULT_JDK=/none
#DEFAULT_JDK=/usr/local/java/jdk1.4/linux-i386
---- ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatThreadTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatThreadTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatThreadTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatThreadTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -90,7 +90,7 @@
FILESEP="/"
;;
@@ -782,8 +782,8 @@
VAR="A different value for Linux"
DEFAULT_JDK=/none
#DEFAULT_JDK=/usr/local/java/jdk1.4/linux-i386
---- ./jdk/test/javax/imageio/stream/StreamCloserLeak/run_test.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/javax/imageio/stream/StreamCloserLeak/run_test.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/javax/imageio/stream/StreamCloserLeak/run_test.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/javax/imageio/stream/StreamCloserLeak/run_test.sh Sat Mar 14 22:56:25 2015 -0700
@@ -108,6 +108,14 @@
TMP="/tmp"
;;
@@ -799,8 +799,8 @@
Windows* )
VAR="A different value for Win32"
DEFAULT_JDK="C:/Program Files/Java/jdk1.8.0"
---- ./jdk/test/javax/script/CommonSetup.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/javax/script/CommonSetup.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/javax/script/CommonSetup.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/javax/script/CommonSetup.sh Sat Mar 14 22:56:25 2015 -0700
@@ -36,7 +36,7 @@
OS=`uname -s`
@@ -810,8 +810,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/javax/security/auth/Subject/doAs/Test.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/javax/security/auth/Subject/doAs/Test.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/javax/security/auth/Subject/doAs/Test.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/javax/security/auth/Subject/doAs/Test.sh Sat Mar 14 22:56:25 2015 -0700
@@ -43,7 +43,7 @@
FS="/"
RM="/bin/rm -f"
@@ -821,8 +821,8 @@
PS=":"
FS="/"
RM="/bin/rm -f"
---- ./jdk/test/lib/security/java.policy/Ext_AllPolicy.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/lib/security/java.policy/Ext_AllPolicy.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/lib/security/java.policy/Ext_AllPolicy.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/lib/security/java.policy/Ext_AllPolicy.sh Sat Mar 14 22:56:25 2015 -0700
@@ -53,7 +53,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -832,8 +832,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java Sat Mar 14 22:56:25 2015 -0700
@@ -53,8 +53,13 @@
return isOs("linux");
}
@@ -849,8 +849,8 @@
}
public static String getOsName() {
---- ./jdk/test/sun/awt/dnd/8024061/bug8024061.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/awt/dnd/8024061/bug8024061.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/awt/dnd/8024061/bug8024061.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/awt/dnd/8024061/bug8024061.java Sat Mar 14 22:56:25 2015 -0700
@@ -107,8 +107,8 @@
public static void main(String[] args) throws AWTException, InvocationTargetException, InterruptedException {
@@ -862,8 +862,8 @@
"skipping!");
return;
}
---- ./jdk/test/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh Sat Mar 14 22:56:25 2015 -0700
@@ -42,7 +42,7 @@
fi
@@ -873,8 +873,8 @@
PATHSEP=":"
FILESEP="/"
DFILESEP=$FILESEP
---- ./jdk/test/sun/net/ftp/MarkResetTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/net/ftp/MarkResetTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/net/ftp/MarkResetTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/net/ftp/MarkResetTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -28,7 +28,7 @@
OS=`uname -s`
@@ -884,8 +884,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/net/www/http/HttpClient/RetryPost.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/net/www/http/HttpClient/RetryPost.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/net/www/http/HttpClient/RetryPost.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/net/www/http/HttpClient/RetryPost.sh Sat Mar 14 22:56:25 2015 -0700
@@ -28,7 +28,7 @@
OS=`uname -s`
@@ -895,8 +895,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/net/www/protocol/jar/B5105410.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/net/www/protocol/jar/B5105410.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/net/www/protocol/jar/B5105410.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/net/www/protocol/jar/B5105410.sh Sat Mar 14 22:56:25 2015 -0700
@@ -31,7 +31,7 @@
OS=`uname -s`
@@ -906,8 +906,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/net/www/protocol/jar/jarbug/run.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/net/www/protocol/jar/jarbug/run.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/net/www/protocol/jar/jarbug/run.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/net/www/protocol/jar/jarbug/run.sh Sat Mar 14 22:56:25 2015 -0700
@@ -31,7 +31,7 @@
OS=`uname -s`
@@ -917,8 +917,8 @@
PS=":"
FS="/"
CHMOD="${FS}bin${FS}chmod"
---- ./jdk/test/sun/nio/ch/SelProvider.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/nio/ch/SelProvider.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/nio/ch/SelProvider.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/nio/ch/SelProvider.java Sat Mar 14 22:56:25 2015 -0700
@@ -39,7 +39,7 @@
expected = "sun.nio.ch.DevPollSelectorProvider";
} else if ("Linux".equals(osname)) {
@@ -928,8 +928,8 @@
expected = "sun.nio.ch.KQueueSelectorProvider";
} else {
return;
---- ./jdk/test/sun/security/krb5/runNameEquals.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/krb5/runNameEquals.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/krb5/runNameEquals.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/krb5/runNameEquals.sh Sat Mar 14 22:56:25 2015 -0700
@@ -52,7 +52,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -939,8 +939,8 @@
PATHSEP=":"
FILESEP="/"
NATIVE=true
---- ./jdk/test/sun/security/mscapi/ShortRSAKey1024.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/mscapi/ShortRSAKey1024.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/mscapi/ShortRSAKey1024.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/mscapi/ShortRSAKey1024.sh Sat Mar 14 22:56:25 2015 -0700
@@ -49,7 +49,7 @@
OS=`uname -s`
@@ -950,8 +950,8 @@
FS="/"
;;
Windows_* )
---- ./jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh Sat Mar 14 22:56:25 2015 -0700
@@ -66,7 +66,7 @@
CP="${FS}bin${FS}cp"
CHMOD="${FS}bin${FS}chmod"
@@ -961,8 +961,8 @@
FS="/"
PS=":"
CP="${FS}bin${FS}cp"
---- ./jdk/test/sun/security/pkcs11/Provider/Login.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/pkcs11/Provider/Login.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/pkcs11/Provider/Login.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/pkcs11/Provider/Login.sh Sat Mar 14 22:56:25 2015 -0700
@@ -67,7 +67,7 @@
CP="${FS}bin${FS}cp"
CHMOD="${FS}bin${FS}chmod"
@@ -972,8 +972,8 @@
FS="/"
PS=":"
CP="${FS}bin${FS}cp"
---- ./jdk/test/sun/security/provider/KeyStore/DKSTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/provider/KeyStore/DKSTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/provider/KeyStore/DKSTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/provider/KeyStore/DKSTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -50,7 +50,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -983,8 +983,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/security/provider/PolicyFile/GrantAllPermToExtWhenNoPolicy.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/provider/PolicyFile/GrantAllPermToExtWhenNoPolicy.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/provider/PolicyFile/GrantAllPermToExtWhenNoPolicy.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/provider/PolicyFile/GrantAllPermToExtWhenNoPolicy.sh Sat Mar 14 22:56:25 2015 -0700
@@ -52,7 +52,7 @@
PATHSEP=":"
FILESEP="/"
@@ -994,8 +994,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh Sat Mar 14 22:56:25 2015 -0700
@@ -59,7 +59,7 @@
PS=":"
FS="/"
@@ -1005,8 +1005,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.sh Sat Mar 14 22:56:25 2015 -0700
@@ -33,7 +33,7 @@
OS=`uname -s`
@@ -1016,8 +1016,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -46,7 +46,7 @@
OS=`uname -s`
@@ -1027,8 +1027,8 @@
FILESEP="/"
PATHSEP=":"
;;
---- ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh Sat Mar 14 22:56:25 2015 -0700
@@ -32,7 +32,7 @@
HOSTNAME=`uname -n`
OS=`uname -s`
@@ -1038,8 +1038,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Sat Mar 14 22:56:25 2015 -0700
@@ -32,7 +32,7 @@
HOSTNAME=`uname -n`
OS=`uname -s`
@@ -1049,8 +1049,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/security/tools/jarsigner/AlgOptions.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/jarsigner/AlgOptions.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/jarsigner/AlgOptions.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/jarsigner/AlgOptions.sh Sat Mar 14 22:56:25 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1060,8 +1060,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/jarsigner/PercentSign.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/jarsigner/PercentSign.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/jarsigner/PercentSign.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/jarsigner/PercentSign.sh Sat Mar 14 22:56:25 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1071,8 +1071,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/jarsigner/diffend.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/jarsigner/diffend.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/jarsigner/diffend.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/jarsigner/diffend.sh Sat Mar 14 22:56:25 2015 -0700
@@ -47,6 +47,13 @@
FS="/"
CP="${FS}bin${FS}cp -f"
@@ -1087,8 +1087,8 @@
CYGWIN* )
NULL=/dev/null
PS=";"
---- ./jdk/test/sun/security/tools/jarsigner/emptymanifest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/jarsigner/emptymanifest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/jarsigner/emptymanifest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/jarsigner/emptymanifest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -39,6 +39,11 @@
Windows_* )
FS="\\"
@@ -1101,8 +1101,8 @@
* )
FS="/"
;;
---- ./jdk/test/sun/security/tools/jarsigner/oldsig.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/jarsigner/oldsig.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/jarsigner/oldsig.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/jarsigner/oldsig.sh Sat Mar 14 22:56:25 2015 -0700
@@ -42,7 +42,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1112,8 +1112,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/keytool/AltProviderPath.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/keytool/AltProviderPath.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/keytool/AltProviderPath.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/keytool/AltProviderPath.sh Sat Mar 14 22:56:25 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1123,8 +1123,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh Sat Mar 14 22:56:25 2015 -0700
@@ -55,7 +55,7 @@
PATHSEP=":"
FILESEP="/"
@@ -1134,8 +1134,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/sun/security/tools/keytool/NoExtNPE.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/keytool/NoExtNPE.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/keytool/NoExtNPE.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/keytool/NoExtNPE.sh Sat Mar 14 22:56:25 2015 -0700
@@ -48,7 +48,7 @@
Linux )
FILESEP="/"
@@ -1145,8 +1145,8 @@
FILESEP="/"
;;
AIX )
---- ./jdk/test/sun/security/tools/keytool/SecretKeyKS.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/keytool/SecretKeyKS.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/keytool/SecretKeyKS.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/keytool/SecretKeyKS.sh Sat Mar 14 22:56:25 2015 -0700
@@ -45,7 +45,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1156,8 +1156,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/keytool/StandardAlgName.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/keytool/StandardAlgName.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/keytool/StandardAlgName.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/keytool/StandardAlgName.sh Sat Mar 14 22:56:25 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1167,8 +1167,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh Sat Mar 14 22:56:25 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1178,8 +1178,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/sun/security/tools/keytool/i18n.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/keytool/i18n.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/keytool/i18n.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/keytool/i18n.sh Sat Mar 14 22:56:25 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1189,8 +1189,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/keytool/printssl.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/keytool/printssl.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/keytool/printssl.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/keytool/printssl.sh Sat Mar 14 22:56:25 2015 -0700
@@ -40,7 +40,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1200,8 +1200,8 @@
FS="/"
;;
CYGWIN* )
---- ./jdk/test/sun/security/tools/keytool/resource.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/keytool/resource.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/keytool/resource.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/keytool/resource.sh Sat Mar 14 22:56:25 2015 -0700
@@ -43,7 +43,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1211,8 +1211,8 @@
NULL=/dev/null
FS="/"
;;
---- ./jdk/test/sun/security/tools/keytool/standard.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/keytool/standard.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/keytool/standard.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/keytool/standard.sh Sat Mar 14 22:56:25 2015 -0700
@@ -45,7 +45,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1222,8 +1222,8 @@
FS="/"
;;
Windows_* )
---- ./jdk/test/sun/security/tools/policytool/Alias.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/policytool/Alias.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/policytool/Alias.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/policytool/Alias.sh Sat Mar 14 22:56:25 2015 -0700
@@ -47,7 +47,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1233,8 +1233,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/policytool/ChangeUI.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/policytool/ChangeUI.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/policytool/ChangeUI.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/policytool/ChangeUI.sh Sat Mar 14 22:56:25 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1244,8 +1244,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/policytool/OpenPolicy.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/policytool/OpenPolicy.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/policytool/OpenPolicy.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/policytool/OpenPolicy.sh Sat Mar 14 22:56:25 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1255,8 +1255,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/policytool/SaveAs.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/policytool/SaveAs.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/policytool/SaveAs.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/policytool/SaveAs.sh Sat Mar 14 22:56:25 2015 -0700
@@ -47,7 +47,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1266,8 +1266,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/policytool/UpdatePermissions.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/policytool/UpdatePermissions.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/policytool/UpdatePermissions.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/policytool/UpdatePermissions.sh Sat Mar 14 22:56:25 2015 -0700
@@ -47,7 +47,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1277,8 +1277,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/policytool/UsePolicy.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/policytool/UsePolicy.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/policytool/UsePolicy.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/policytool/UsePolicy.sh Sat Mar 14 22:56:25 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1288,8 +1288,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/policytool/i18n.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/security/tools/policytool/i18n.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/security/tools/policytool/i18n.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/security/tools/policytool/i18n.sh Sat Mar 14 22:56:25 2015 -0700
@@ -49,7 +49,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1299,8 +1299,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/tools/common/CommonSetup.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/tools/common/CommonSetup.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/tools/common/CommonSetup.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/tools/common/CommonSetup.sh Sat Mar 14 22:56:25 2015 -0700
@@ -47,6 +47,7 @@
# isLinux - true if OS is Linux
# isSolaris - true if OS is Solaris
@@ -1328,8 +1328,8 @@
Darwin )
OS="Mac OS X"
isMacos=true
---- ./jdk/test/sun/tools/jconsole/ResourceCheckTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/tools/jconsole/ResourceCheckTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/tools/jconsole/ResourceCheckTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/tools/jconsole/ResourceCheckTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -54,7 +54,7 @@
OS=`uname -s`
@@ -1339,8 +1339,8 @@
PATHSEP=":"
;;
---- ./jdk/test/sun/tools/native2ascii/resources/ImmutableResourceTest.sh Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/sun/tools/native2ascii/resources/ImmutableResourceTest.sh Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/sun/tools/native2ascii/resources/ImmutableResourceTest.sh Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/sun/tools/native2ascii/resources/ImmutableResourceTest.sh Sat Mar 14 22:56:25 2015 -0700
@@ -56,7 +56,7 @@
OS=`uname -s`
@@ -1350,8 +1350,8 @@
PATHSEP=":"
;;
---- ./jdk/test/tools/launcher/ExecutionEnvironment.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/tools/launcher/ExecutionEnvironment.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/tools/launcher/ExecutionEnvironment.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/tools/launcher/ExecutionEnvironment.java Sat Mar 14 22:56:25 2015 -0700
@@ -194,7 +194,7 @@
Map<String, String> env = new HashMap<>();
@@ -1361,8 +1361,8 @@
for (String x : LD_PATH_STRINGS) {
String pairs[] = x.split("=");
env.put(pairs[0], pairs[1]);
---- ./jdk/test/tools/launcher/RunpathTest.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/tools/launcher/RunpathTest.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/tools/launcher/RunpathTest.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/tools/launcher/RunpathTest.java Sat Mar 14 22:56:25 2015 -0700
@@ -69,7 +69,7 @@
}
@@ -1372,8 +1372,8 @@
RunpathTest rp = new RunpathTest();
rp.testRpath();
}
---- ./jdk/test/tools/launcher/Test7029048.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/tools/launcher/Test7029048.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/tools/launcher/Test7029048.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/tools/launcher/Test7029048.java Sat Mar 14 22:56:25 2015 -0700
@@ -223,7 +223,7 @@
} else if (isSolaris && passes < 9) {
throw new Exception("Test7029048: FAIL: " +
@@ -1383,8 +1383,8 @@
throw new Exception("Test7029048: FAIL: " +
"all tests did not run, expected " + 6 + " got " + passes);
} else {
---- ./jdk/test/tools/launcher/TestHelper.java Mon Dec 08 08:53:26 2014 -0800
-+++ ./jdk/test/tools/launcher/TestHelper.java Sun Feb 01 21:05:04 2015 -0800
+--- ./jdk/test/tools/launcher/TestHelper.java Mon Feb 02 10:12:21 2015 -0800
++++ ./jdk/test/tools/launcher/TestHelper.java Sat Mar 14 22:56:25 2015 -0700
@@ -94,6 +94,8 @@
System.getProperty("os.name", "unknown").startsWith("Linux");
static final boolean isAIX =
@@ -1394,8 +1394,8 @@
static final String LIBJVM = isWindows
? "jvm.dll"
: "libjvm" + (isMacOSX ? ".dylib" : ".so");
---- ./langtools/test/Makefile Tue Dec 02 11:13:06 2014 -0800
-+++ ./langtools/test/Makefile Sun Feb 01 21:04:46 2015 -0800
+--- ./langtools/test/Makefile Wed Jan 28 12:08:47 2015 -0800
++++ ./langtools/test/Makefile Sat Mar 14 10:28:47 2015 -0700
@@ -36,6 +36,14 @@
ARCH=i586
endif
@@ -1411,8 +1411,8 @@
ifeq ($(OSNAME), Darwin)
PLATFORM = bsd
JT_PLATFORM = linux
---- ./langtools/test/tools/javah/ReadOldClass.sh Tue Dec 02 11:13:06 2014 -0800
-+++ ./langtools/test/tools/javah/ReadOldClass.sh Sun Feb 01 21:04:46 2015 -0800
+--- ./langtools/test/tools/javah/ReadOldClass.sh Wed Jan 28 12:08:47 2015 -0800
++++ ./langtools/test/tools/javah/ReadOldClass.sh Sat Mar 14 10:28:47 2015 -0700
@@ -43,7 +43,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1422,8 +1422,8 @@
PS=":"
FS="/"
;;
---- ./nashorn/test/script/jfx.js Tue Dec 02 11:13:14 2014 -0800
-+++ ./nashorn/test/script/jfx.js Sun Feb 01 21:04:47 2015 -0800
+--- ./nashorn/test/script/jfx.js Wed Jan 28 12:08:49 2015 -0800
++++ ./nashorn/test/script/jfx.js Sat Mar 14 10:28:56 2015 -0700
@@ -93,6 +93,8 @@
f2 = new File(sb.append(fsep + "linux.png").toString());
} else if (OSInfo.getOSType() == OSType.MACOSX) {
diff --git a/java/openjdk8/files/patch-jdk-src-solaris-native-java-net-bsd_close.c b/java/openjdk8/files/patch-jdk-src-solaris-native-java-net-bsd_close.c
deleted file mode 100644
index f097e9e16289..000000000000
--- a/java/openjdk8/files/patch-jdk-src-solaris-native-java-net-bsd_close.c
+++ /dev/null
@@ -1,16 +0,0 @@
---- jdk/src/solaris/native/java/net/bsd_close.c
-+++ jdk/src/solaris/native/java/net/bsd_close.c
-@@ -316,11 +316,8 @@
- }
-
- int NET_Accept(int s, struct sockaddr *addr, int *addrlen) {
-- socklen_t len = *addrlen;
-- int error = accept(s, addr, &len);
-- if (error != -1)
-- *addrlen = (int)len;
-- BLOCKING_IO_RETURN_INT( s, error );
-+ /* See NET_RecvFrom() */
-+ BLOCKING_IO_RETURN_INT( s, accept(s, addr, (socklen_t *)addrlen) );
- }
-
- int NET_Connect(int s, struct sockaddr *addr, int addrlen) {